aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml40
-rw-r--r--EPLICENCE286
-rw-r--r--HOWTO/INSTALL-CROSS.md21
-rw-r--r--HOWTO/INSTALL-WIN32.md1009
-rw-r--r--HOWTO/INSTALL.md100
-rw-r--r--HOWTO/MARKDOWN.md21
-rw-r--r--LICENSE.txt178
-rw-r--r--Makefile.in19
-rw-r--r--OTP_VERSION2
-rw-r--r--README.md26
-rw-r--r--bootstrap/bin/start.bootbin5259 -> 5287 bytes
-rw-r--r--bootstrap/bin/start_clean.bootbin5259 -> 5287 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_a.beambin2500 -> 2700 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_asm.beambin11676 -> 11540 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_block.beambin15284 -> 14828 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bool.beambin16308 -> 15732 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bsm.beambin12580 -> 12756 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_clean.beambin11256 -> 9416 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dead.beambin10212 -> 12156 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dict.beambin5364 -> 5300 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_disasm.beambin26320 -> 26320 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_except.beambin3564 -> 3564 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_flatten.beambin3108 -> 3020 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_jump.beambin8700 -> 9448 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_listing.beambin2904 -> 2992 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_peep.beambin2428 -> 2780 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_receive.beambin6480 -> 6444 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_split.beambin2392 -> 2416 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_trim.beambin7672 -> 7928 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_type.beambin14488 -> 14692 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin13476 -> 13620 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_validator.beambin36240 -> 30304 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_z.beambin2748 -> 2652 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl.beambin32416 -> 32376 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_inline.beambin39100 -> 38940 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_sets.beambin0 -> 2868 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_trees.beambin20368 -> 20368 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin39832 -> 39368 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app27
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.appup21
-rw-r--r--bootstrap/lib/compiler/ebin/core_lib.beambin6120 -> 5240 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_lint.beambin12820 -> 13656 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_parse.beambin42968 -> 50920 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin13196 -> 13252 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_scan.beambin6672 -> 6692 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/erl_bifs.beambin2180 -> 2188 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/rec_env.beambin4772 -> 4772 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_dsetel.beambin7332 -> 7340 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold.beambin50468 -> 50072 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold_lists.beambin0 -> 4596 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_inline.beambin4272 -> 4276 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_pre_attributes.beambin3348 -> 3348 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_pre_expand.beambin14244 -> 14940 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin54516 -> 56616 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin54712 -> 53748 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin47460 -> 47352 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel_pp.beambin12644 -> 12556 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_life.beambin20696 -> 19172 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application.beambin4524 -> 4620 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_controller.beambin32180 -> 32152 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_master.beambin6744 -> 6696 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/auth.beambin6496 -> 6552 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin7020 -> 7196 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin28572 -> 28824 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin36596 -> 36492 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin25048 -> 25252 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_ac.beambin26652 -> 26656 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin10512 -> 10568 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_boot_server.beambin6016 -> 6012 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_epmd.beambin7096 -> 7200 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erts_debug.beambin4312 -> 5460 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin14692 -> 14556 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_io_server.beambin14400 -> 15728 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin32688 -> 32764 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_group.beambin17740 -> 17740 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin13540 -> 14160 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/heart.beambin4072 -> 5580 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/hipe_unified_loader.beambin13516 -> 13768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin23068 -> 23420 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp.beambin2680 -> 3044 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp_dist.beambin6240 -> 768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_config.beambin7812 -> 7796 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin26708 -> 27156 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_dns.beambin19812 -> 19764 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin12944 -> 12940 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin15080 -> 14976 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_sctp.beambin2312 -> 2324 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp.beambin2488 -> 2756 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp_dist.beambin6524 -> 7224 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app27
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.appup31
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.beambin3852 -> 3796 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel_config.beambin2760 -> 2768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin22752 -> 22760 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/os.beambin5716 -> 5848 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/pg2.beambin7900 -> 7916 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/ram_file.beambin7032 -> 7044 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/seq_trace.beambin1336 -> 1444 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user.beambin11588 -> 11588 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_drv.beambin10356 -> 11488 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/wrap_log_reader.beambin3380 -> 3372 bytes
-rw-r--r--bootstrap/lib/kernel/include/dist.hrl21
-rw-r--r--bootstrap/lib/kernel/include/dist_util.hrl21
-rw-r--r--bootstrap/lib/kernel/include/file.hrl19
-rw-r--r--bootstrap/lib/kernel/include/inet.hrl21
-rw-r--r--bootstrap/lib/kernel/include/inet_sctp.hrl21
-rw-r--r--bootstrap/lib/kernel/include/net_address.hrl21
-rw-r--r--bootstrap/lib/stdlib/ebin/array.beambin12032 -> 12032 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/beam_lib.beambin18188 -> 18644 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/binary.beambin3644 -> 3812 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin13956 -> 14660 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/calendar.beambin5176 -> 5172 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin53736 -> 54048 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_server.beambin7024 -> 7028 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_utils.beambin28880 -> 28836 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v8.beambin27616 -> 27632 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin51024 -> 50240 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dict.beambin9216 -> 9392 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph.beambin8308 -> 8428 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6852 -> 6844 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin.beambin9968 -> 10248 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin_expand.beambin3168 -> 3164 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin28540 -> 28220 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_anno.beambin0 -> 4900 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin30744 -> 31000 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin22712 -> 22536 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_internal.beambin5236 -> 5824 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin89824 -> 90024 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin75628 -> 84208 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin26984 -> 26912 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin30044 -> 31380 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_tar.beambin17264 -> 17256 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_file_h.beambin5128 -> 4708 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_tty_h.beambin5056 -> 4976 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/escript.beambin17412 -> 17676 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin22292 -> 22720 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin30804 -> 30708 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin8072 -> 8088 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin12436 -> 12512 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_sets.beambin8284 -> 8432 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_trees.beambin4992 -> 5176 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen.beambin4048 -> 4296 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin18144 -> 19624 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_fsm.beambin15724 -> 17412 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin18184 -> 19596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib.beambin9856 -> 10008 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_format.beambin12424 -> 13404 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_fread.beambin7404 -> 7384 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_pretty.beambin15248 -> 15224 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin9652 -> 9660 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lists.beambin29712 -> 29768 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/maps.beambin2016 -> 2408 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/math.beambin1136 -> 1176 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ms_transform.beambin20388 -> 20632 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/orddict.beambin2812 -> 2792 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/otp_internal.beambin10136 -> 11724 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pg.beambin2096 -> 0 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proc_lib.beambin9812 -> 10692 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin70184 -> 70684 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin73720 -> 76684 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/queue.beambin6184 -> 6184 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/rand.beambin0 -> 13568 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/random.beambin1568 -> 1712 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/re.beambin13876 -> 13672 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin30252 -> 30364 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell_default.beambin3884 -> 3932 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin40820 -> 40816 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app28
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.appup33
-rw-r--r--bootstrap/lib/stdlib/ebin/string.beambin4928 -> 5176 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor.beambin23432 -> 24100 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor_bridge.beambin2824 -> 2908 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin8372 -> 8620 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/timer.beambin5476 -> 5488 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/unicode.beambin11608 -> 11676 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/win32reg.beambin5652 -> 5632 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/zip.beambin26848 -> 26904 bytes
-rw-r--r--bootstrap/lib/stdlib/include/assert.hrl261
-rw-r--r--bootstrap/lib/stdlib/include/erl_bits.hrl21
-rw-r--r--bootstrap/lib/stdlib/include/erl_compile.hrl21
-rw-r--r--bootstrap/lib/stdlib/include/ms_transform.hrl21
-rw-r--r--bootstrap/lib/stdlib/include/qlc.hrl21
-rw-r--r--bootstrap/lib/stdlib/include/zip.hrl21
-rw-r--r--configure.in21
-rw-r--r--erl-build-tool-vars.sh21
-rw-r--r--erts/AUTHORS19
-rw-r--r--erts/Makefile.in19
-rw-r--r--erts/aclocal.m41200
-rwxr-xr-xerts/autoconf/config.guess342
-rwxr-xr-xerts/autoconf/config.sub69
-rwxr-xr-xerts/autoconf/configure.vxworks21
-rw-r--r--erts/autoconf/vxworks/sed.general23
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_cpu3221
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc3221
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc60321
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall21
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc86021
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_simlinux19
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_simso19
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_sparc21
-rwxr-xr-xerts/autoconf/win32.config.cache.static1
-rwxr-xr-xerts/autoconf/win64.config.cache.static1
-rw-r--r--erts/configure.in162
-rw-r--r--erts/doc/Makefile21
-rw-r--r--erts/doc/src/Makefile21
-rw-r--r--erts/doc/src/absform.xml793
-rw-r--r--erts/doc/src/alt_dist.xml19
-rw-r--r--erts/doc/src/book.xml21
-rw-r--r--erts/doc/src/communication.xml19
-rw-r--r--erts/doc/src/crash_dump.xml138
-rw-r--r--erts/doc/src/driver.xml21
-rw-r--r--erts/doc/src/driver_entry.xml26
-rw-r--r--erts/doc/src/epmd.xml23
-rw-r--r--erts/doc/src/erl.xml203
-rw-r--r--erts/doc/src/erl_dist_protocol.xml25
-rw-r--r--erts/doc/src/erl_driver.xml152
-rw-r--r--erts/doc/src/erl_ext_dist.xml25
-rw-r--r--erts/doc/src/erl_nif.xml441
-rw-r--r--erts/doc/src/erl_prim_loader.xml56
-rw-r--r--erts/doc/src/erlang.xml8340
-rw-r--r--erts/doc/src/erlc.xml19
-rw-r--r--erts/doc/src/erlsrv.xml19
-rw-r--r--erts/doc/src/erts_alloc.xml93
-rw-r--r--erts/doc/src/escript.xml27
-rw-r--r--erts/doc/src/inet_cfg.xml19
-rw-r--r--erts/doc/src/init.xml23
-rw-r--r--erts/doc/src/match_spec.xml76
-rw-r--r--erts/doc/src/notes.xml1424
-rw-r--r--erts/doc/src/notes_history.xml21
-rw-r--r--erts/doc/src/part.xml21
-rw-r--r--erts/doc/src/part_notes.xml21
-rw-r--r--erts/doc/src/part_notes_history.xml21
-rw-r--r--erts/doc/src/ref_man.xml21
-rw-r--r--erts/doc/src/run_erl.xml21
-rw-r--r--erts/doc/src/start.xml21
-rw-r--r--erts/doc/src/start_erl.xml21
-rw-r--r--erts/doc/src/time_correction.xml1082
-rw-r--r--erts/doc/src/tty.xml19
-rw-r--r--erts/doc/src/werl.xml21
-rw-r--r--erts/doc/src/zlib.xml72
-rw-r--r--erts/emulator/Makefile21
-rw-r--r--erts/emulator/Makefile.in60
-rw-r--r--erts/emulator/beam/atom.c19
-rw-r--r--erts/emulator/beam/atom.h19
-rw-r--r--erts/emulator/beam/atom.names51
-rw-r--r--erts/emulator/beam/beam_bif_load.c63
-rw-r--r--erts/emulator/beam/beam_bp.c118
-rw-r--r--erts/emulator/beam/beam_bp.h26
-rw-r--r--erts/emulator/beam/beam_catches.c25
-rw-r--r--erts/emulator/beam/beam_catches.h19
-rw-r--r--erts/emulator/beam/beam_debug.c115
-rw-r--r--erts/emulator/beam/beam_emu.c935
-rw-r--r--erts/emulator/beam/beam_load.c842
-rw-r--r--erts/emulator/beam/beam_load.h29
-rw-r--r--erts/emulator/beam/beam_ranges.c19
-rw-r--r--erts/emulator/beam/benchmark.c86
-rw-r--r--erts/emulator/beam/benchmark.h66
-rw-r--r--erts/emulator/beam/bif.c584
-rw-r--r--erts/emulator/beam/bif.h26
-rw-r--r--erts/emulator/beam/bif.tab58
-rw-r--r--erts/emulator/beam/big.c88
-rw-r--r--erts/emulator/beam/big.h28
-rw-r--r--erts/emulator/beam/binary.c28
-rw-r--r--erts/emulator/beam/break.c177
-rw-r--r--erts/emulator/beam/code_ix.c23
-rw-r--r--erts/emulator/beam/code_ix.h19
-rw-r--r--erts/emulator/beam/copy.c155
-rw-r--r--erts/emulator/beam/dist.c579
-rw-r--r--erts/emulator/beam/dist.h116
-rw-r--r--erts/emulator/beam/dtrace-wrapper.h19
-rw-r--r--erts/emulator/beam/elib_memmove.c21
-rw-r--r--erts/emulator/beam/erl_afit_alloc.c23
-rw-r--r--erts/emulator/beam/erl_afit_alloc.h21
-rw-r--r--erts/emulator/beam/erl_alloc.c188
-rw-r--r--erts/emulator/beam/erl_alloc.h19
-rw-r--r--erts/emulator/beam/erl_alloc.types47
-rw-r--r--erts/emulator/beam/erl_alloc_util.c152
-rw-r--r--erts/emulator/beam/erl_alloc_util.h21
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.c45
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.h21
-rw-r--r--erts/emulator/beam/erl_arith.c24
-rw-r--r--erts/emulator/beam/erl_async.c32
-rw-r--r--erts/emulator/beam/erl_async.h19
-rw-r--r--erts/emulator/beam/erl_bestfit_alloc.c23
-rw-r--r--erts/emulator/beam/erl_bestfit_alloc.h21
-rw-r--r--erts/emulator/beam/erl_bif_binary.c24
-rw-r--r--erts/emulator/beam/erl_bif_chksum.c19
-rw-r--r--erts/emulator/beam/erl_bif_ddll.c30
-rw-r--r--erts/emulator/beam/erl_bif_guard.c55
-rw-r--r--erts/emulator/beam/erl_bif_info.c458
-rw-r--r--erts/emulator/beam/erl_bif_lists.c21
-rw-r--r--erts/emulator/beam/erl_bif_op.c19
-rw-r--r--erts/emulator/beam/erl_bif_os.c21
-rw-r--r--erts/emulator/beam/erl_bif_port.c33
-rw-r--r--erts/emulator/beam/erl_bif_re.c19
-rw-r--r--erts/emulator/beam/erl_bif_timer.c705
-rw-r--r--erts/emulator/beam/erl_bif_timer.h36
-rw-r--r--erts/emulator/beam/erl_bif_trace.c69
-rw-r--r--erts/emulator/beam/erl_bif_unique.c557
-rw-r--r--erts/emulator/beam/erl_bif_unique.h132
-rw-r--r--erts/emulator/beam/erl_binary.h71
-rw-r--r--erts/emulator/beam/erl_bits.c66
-rw-r--r--erts/emulator/beam/erl_bits.h19
-rw-r--r--erts/emulator/beam/erl_cpu_topology.c29
-rw-r--r--erts/emulator/beam/erl_cpu_topology.h19
-rw-r--r--erts/emulator/beam/erl_db.c249
-rw-r--r--erts/emulator/beam/erl_db.h34
-rw-r--r--erts/emulator/beam/erl_db_hash.c391
-rw-r--r--erts/emulator/beam/erl_db_hash.h26
-rw-r--r--erts/emulator/beam/erl_db_tree.c113
-rw-r--r--erts/emulator/beam/erl_db_tree.h21
-rw-r--r--erts/emulator/beam/erl_db_util.c648
-rw-r--r--erts/emulator/beam/erl_db_util.h46
-rw-r--r--erts/emulator/beam/erl_debug.c36
-rw-r--r--erts/emulator/beam/erl_debug.h19
-rw-r--r--erts/emulator/beam/erl_driver.h113
-rw-r--r--erts/emulator/beam/erl_drv_nif.h103
-rw-r--r--erts/emulator/beam/erl_drv_thread.c34
-rw-r--r--erts/emulator/beam/erl_fun.c21
-rw-r--r--erts/emulator/beam/erl_fun.h19
-rw-r--r--erts/emulator/beam/erl_gc.c256
-rw-r--r--erts/emulator/beam/erl_gc.h60
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.c23
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.h19
-rw-r--r--erts/emulator/beam/erl_hl_timer.c3179
-rw-r--r--erts/emulator/beam/erl_hl_timer.h88
-rw-r--r--erts/emulator/beam/erl_init.c293
-rw-r--r--erts/emulator/beam/erl_instrument.c21
-rw-r--r--erts/emulator/beam/erl_instrument.h21
-rw-r--r--erts/emulator/beam/erl_lock_check.c27
-rw-r--r--erts/emulator/beam/erl_lock_check.h21
-rw-r--r--erts/emulator/beam/erl_lock_count.c385
-rw-r--r--erts/emulator/beam/erl_lock_count.h63
-rw-r--r--erts/emulator/beam/erl_map.c2967
-rw-r--r--erts/emulator/beam/erl_map.h209
-rw-r--r--erts/emulator/beam/erl_math.c39
-rw-r--r--erts/emulator/beam/erl_message.c413
-rw-r--r--erts/emulator/beam/erl_message.h104
-rw-r--r--erts/emulator/beam/erl_monitors.c23
-rw-r--r--erts/emulator/beam/erl_monitors.h24
-rw-r--r--erts/emulator/beam/erl_mtrace.c21
-rw-r--r--erts/emulator/beam/erl_mtrace.h21
-rw-r--r--erts/emulator/beam/erl_nif.c367
-rw-r--r--erts/emulator/beam/erl_nif.h106
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h33
-rw-r--r--erts/emulator/beam/erl_node_container_utils.h19
-rw-r--r--erts/emulator/beam/erl_node_tables.c391
-rw-r--r--erts/emulator/beam/erl_node_tables.h35
-rw-r--r--erts/emulator/beam/erl_port.h50
-rw-r--r--erts/emulator/beam/erl_port_task.c42
-rw-r--r--erts/emulator/beam/erl_port_task.h21
-rw-r--r--erts/emulator/beam/erl_printf_term.c240
-rw-r--r--erts/emulator/beam/erl_printf_term.h21
-rw-r--r--erts/emulator/beam/erl_process.c1544
-rw-r--r--erts/emulator/beam/erl_process.h398
-rw-r--r--erts/emulator/beam/erl_process_dict.c81
-rw-r--r--erts/emulator/beam/erl_process_dict.h21
-rw-r--r--erts/emulator/beam/erl_process_dump.c193
-rw-r--r--erts/emulator/beam/erl_process_lock.c321
-rw-r--r--erts/emulator/beam/erl_process_lock.h114
-rw-r--r--erts/emulator/beam/erl_ptab.c40
-rw-r--r--erts/emulator/beam/erl_ptab.h121
-rw-r--r--erts/emulator/beam/erl_rbtree.h1741
-rw-r--r--erts/emulator/beam/erl_sched_spec_pre_alloc.c19
-rw-r--r--erts/emulator/beam/erl_sched_spec_pre_alloc.h19
-rw-r--r--erts/emulator/beam/erl_smp.h19
-rw-r--r--erts/emulator/beam/erl_sock.h21
-rw-r--r--erts/emulator/beam/erl_sys_driver.h21
-rw-r--r--erts/emulator/beam/erl_term.c29
-rw-r--r--erts/emulator/beam/erl_term.h98
-rw-r--r--erts/emulator/beam/erl_thr_progress.c82
-rw-r--r--erts/emulator/beam/erl_thr_progress.h23
-rw-r--r--erts/emulator/beam/erl_thr_queue.c25
-rw-r--r--erts/emulator/beam/erl_thr_queue.h19
-rw-r--r--erts/emulator/beam/erl_threads.h78
-rw-r--r--erts/emulator/beam/erl_time.h518
-rw-r--r--erts/emulator/beam/erl_time_sup.c2329
-rw-r--r--erts/emulator/beam/erl_trace.c785
-rw-r--r--erts/emulator/beam/erl_trace.h51
-rw-r--r--erts/emulator/beam/erl_unicode.c21
-rw-r--r--erts/emulator/beam/erl_unicode.h21
-rw-r--r--erts/emulator/beam/erl_unicode_normalize.h35
-rw-r--r--erts/emulator/beam/erl_utils.h49
-rw-r--r--erts/emulator/beam/erl_vm.h25
-rw-r--r--erts/emulator/beam/erl_zlib.c21
-rw-r--r--erts/emulator/beam/erl_zlib.h21
-rw-r--r--erts/emulator/beam/erlang_dtrace.d19
-rw-r--r--erts/emulator/beam/error.h29
-rw-r--r--erts/emulator/beam/export.c19
-rw-r--r--erts/emulator/beam/export.h19
-rw-r--r--erts/emulator/beam/external.c865
-rw-r--r--erts/emulator/beam/external.h39
-rw-r--r--erts/emulator/beam/global.h415
-rw-r--r--erts/emulator/beam/hash.c23
-rw-r--r--erts/emulator/beam/hash.h21
-rw-r--r--erts/emulator/beam/index.c25
-rw-r--r--erts/emulator/beam/index.h21
-rw-r--r--erts/emulator/beam/io.c740
-rw-r--r--erts/emulator/beam/module.c19
-rw-r--r--erts/emulator/beam/module.h19
-rw-r--r--erts/emulator/beam/ops.tab237
-rw-r--r--erts/emulator/beam/packet_parser.c26
-rw-r--r--erts/emulator/beam/packet_parser.h24
-rw-r--r--erts/emulator/beam/register.c30
-rw-r--r--erts/emulator/beam/register.h21
-rw-r--r--erts/emulator/beam/safe_hash.c21
-rw-r--r--erts/emulator/beam/safe_hash.h21
-rw-r--r--erts/emulator/beam/sys.h230
-rw-r--r--erts/emulator/beam/time.c847
-rw-r--r--erts/emulator/beam/utils.c1483
-rw-r--r--erts/emulator/beam/version.h21
-rw-r--r--erts/emulator/drivers/common/efile_drv.c61
-rw-r--r--erts/emulator/drivers/common/erl_efile.h19
-rw-r--r--erts/emulator/drivers/common/gzio.h21
-rw-r--r--erts/emulator/drivers/common/gzio_zutil.h21
-rw-r--r--erts/emulator/drivers/common/inet_drv.c405
-rw-r--r--erts/emulator/drivers/common/ram_file_drv.c19
-rw-r--r--erts/emulator/drivers/common/zlib_drv.c92
-rw-r--r--erts/emulator/drivers/ose/ose_efile.c19
-rw-r--r--erts/emulator/drivers/ose/ose_signal_drv.c19
-rw-r--r--erts/emulator/drivers/ose/ttsl_drv.c19
-rw-r--r--erts/emulator/drivers/unix/bin_drv.c21
-rw-r--r--erts/emulator/drivers/unix/multi_drv.c21
-rw-r--r--erts/emulator/drivers/unix/sig_drv.c21
-rw-r--r--erts/emulator/drivers/unix/ttsl_drv.c200
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c34
-rw-r--r--erts/emulator/drivers/vxworks/vxworks_resolv.c21
-rw-r--r--erts/emulator/drivers/win32/registry_drv.c21
-rw-r--r--erts/emulator/drivers/win32/ttsl_drv.c37
-rw-r--r--erts/emulator/drivers/win32/win_con.c25
-rw-r--r--erts/emulator/drivers/win32/win_con.h21
-rw-r--r--erts/emulator/drivers/win32/win_efile.c19
-rw-r--r--erts/emulator/hipe/TODO19
-rw-r--r--erts/emulator/hipe/elf64ppc.x21
-rw-r--r--erts/emulator/hipe/hipe_amd64.c94
-rw-r--r--erts/emulator/hipe/hipe_amd64.h19
-rw-r--r--erts/emulator/hipe/hipe_amd64.tab19
-rw-r--r--erts/emulator/hipe/hipe_amd64_abi.txt2
-rw-r--r--erts/emulator/hipe/hipe_amd64_asm.m474
-rw-r--r--erts/emulator/hipe/hipe_amd64_bifs.m460
-rw-r--r--erts/emulator/hipe/hipe_amd64_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_amd64_glue.S36
-rw-r--r--erts/emulator/hipe/hipe_amd64_glue.h19
-rw-r--r--erts/emulator/hipe/hipe_amd64_primops.h19
-rw-r--r--erts/emulator/hipe/hipe_arch.h20
-rw-r--r--erts/emulator/hipe/hipe_arm.c37
-rw-r--r--erts/emulator/hipe/hipe_arm.h23
-rw-r--r--erts/emulator/hipe/hipe_arm.tab19
-rw-r--r--erts/emulator/hipe/hipe_arm_asm.m436
-rw-r--r--erts/emulator/hipe/hipe_arm_bifs.m456
-rw-r--r--erts/emulator/hipe/hipe_arm_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_arm_glue.S40
-rw-r--r--erts/emulator/hipe/hipe_arm_glue.h19
-rw-r--r--erts/emulator/hipe/hipe_arm_primops.h19
-rw-r--r--erts/emulator/hipe/hipe_bif0.c274
-rw-r--r--erts/emulator/hipe/hipe_bif0.h19
-rw-r--r--erts/emulator/hipe/hipe_bif0.tab26
-rw-r--r--erts/emulator/hipe/hipe_bif1.c72
-rw-r--r--erts/emulator/hipe/hipe_bif1.h19
-rw-r--r--erts/emulator/hipe/hipe_bif1.tab21
-rw-r--r--erts/emulator/hipe/hipe_bif2.c19
-rw-r--r--erts/emulator/hipe/hipe_bif2.tab21
-rw-r--r--erts/emulator/hipe/hipe_bif64.c19
-rw-r--r--erts/emulator/hipe/hipe_bif64.h19
-rw-r--r--erts/emulator/hipe/hipe_bif64.tab19
-rw-r--r--erts/emulator/hipe/hipe_bif_list.m451
-rw-r--r--erts/emulator/hipe/hipe_debug.c29
-rw-r--r--erts/emulator/hipe/hipe_debug.h19
-rw-r--r--erts/emulator/hipe/hipe_gbif_list.h19
-rw-r--r--erts/emulator/hipe/hipe_gc.c22
-rw-r--r--erts/emulator/hipe/hipe_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_mkliterals.c37
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c91
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.h72
-rw-r--r--erts/emulator/hipe/hipe_native_bif.c75
-rw-r--r--erts/emulator/hipe/hipe_native_bif.h24
-rw-r--r--erts/emulator/hipe/hipe_ops.tab19
-rw-r--r--erts/emulator/hipe/hipe_perfctr.c229
-rw-r--r--erts/emulator/hipe/hipe_perfctr.h23
-rw-r--r--erts/emulator/hipe/hipe_perfctr.tab25
-rw-r--r--erts/emulator/hipe/hipe_ppc.c57
-rw-r--r--erts/emulator/hipe/hipe_ppc.h23
-rw-r--r--erts/emulator/hipe/hipe_ppc.tab19
-rw-r--r--erts/emulator/hipe/hipe_ppc64.tab21
-rw-r--r--erts/emulator/hipe/hipe_ppc_asm.m451
-rw-r--r--erts/emulator/hipe/hipe_ppc_bifs.m458
-rw-r--r--erts/emulator/hipe/hipe_ppc_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_ppc_glue.S42
-rw-r--r--erts/emulator/hipe/hipe_ppc_glue.h19
-rw-r--r--erts/emulator/hipe/hipe_ppc_primops.h19
-rw-r--r--erts/emulator/hipe/hipe_primops.h22
-rw-r--r--erts/emulator/hipe/hipe_process.h28
-rw-r--r--erts/emulator/hipe/hipe_risc_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_risc_glue.h19
-rw-r--r--erts/emulator/hipe/hipe_risc_stack.c23
-rw-r--r--erts/emulator/hipe/hipe_signal.h19
-rw-r--r--erts/emulator/hipe/hipe_sparc.c44
-rw-r--r--erts/emulator/hipe/hipe_sparc.h23
-rw-r--r--erts/emulator/hipe/hipe_sparc.tab19
-rw-r--r--erts/emulator/hipe/hipe_sparc_asm.m437
-rw-r--r--erts/emulator/hipe/hipe_sparc_bifs.m456
-rw-r--r--erts/emulator/hipe/hipe_sparc_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_sparc_glue.S42
-rw-r--r--erts/emulator/hipe/hipe_sparc_glue.h19
-rw-r--r--erts/emulator/hipe/hipe_sparc_primops.h19
-rw-r--r--erts/emulator/hipe/hipe_stack.c19
-rw-r--r--erts/emulator/hipe/hipe_stack.h30
-rw-r--r--erts/emulator/hipe/hipe_x86.c68
-rw-r--r--erts/emulator/hipe/hipe_x86.h23
-rw-r--r--erts/emulator/hipe/hipe_x86.tab19
-rw-r--r--erts/emulator/hipe/hipe_x86_abi.txt19
-rw-r--r--erts/emulator/hipe/hipe_x86_asm.m445
-rw-r--r--erts/emulator/hipe/hipe_x86_bifs.m460
-rw-r--r--erts/emulator/hipe/hipe_x86_gc.h19
-rw-r--r--erts/emulator/hipe/hipe_x86_glue.S36
-rw-r--r--erts/emulator/hipe/hipe_x86_glue.h19
-rw-r--r--erts/emulator/hipe/hipe_x86_primops.h19
-rw-r--r--erts/emulator/hipe/hipe_x86_signal.c74
-rw-r--r--erts/emulator/hipe/hipe_x86_stack.c23
-rw-r--r--erts/emulator/internal_doc/dec.erl40
-rw-r--r--erts/emulator/internal_doc/erl_ext_dist.txt19
-rw-r--r--erts/emulator/pcre/pcre.mk19
-rw-r--r--erts/emulator/sys/common/erl_check_io.c62
-rw-r--r--erts/emulator/sys/common/erl_check_io.h27
-rw-r--r--erts/emulator/sys/common/erl_mmap.c33
-rw-r--r--erts/emulator/sys/common/erl_mmap.h19
-rw-r--r--erts/emulator/sys/common/erl_mseg.c23
-rw-r--r--erts/emulator/sys/common/erl_mseg.h19
-rw-r--r--erts/emulator/sys/common/erl_mtrace_sys_wrap.c21
-rw-r--r--erts/emulator/sys/common/erl_os_monotonic_time_extender.c89
-rw-r--r--erts/emulator/sys/common/erl_os_monotonic_time_extender.h66
-rw-r--r--erts/emulator/sys/common/erl_poll.c464
-rw-r--r--erts/emulator/sys/common/erl_poll.h39
-rw-r--r--erts/emulator/sys/common/erl_sys_common_misc.c21
-rw-r--r--erts/emulator/sys/common/erl_util_queue.h19
-rw-r--r--erts/emulator/sys/ose/driver_int.h19
-rw-r--r--erts/emulator/sys/ose/erl_main.c19
-rw-r--r--erts/emulator/sys/ose/erl_ose_sys.h21
-rw-r--r--erts/emulator/sys/ose/erl_ose_sys_ddll.c19
-rw-r--r--erts/emulator/sys/ose/erl_poll.c90
-rw-r--r--erts/emulator/sys/ose/sys.c25
-rw-r--r--erts/emulator/sys/ose/sys_float.c21
-rw-r--r--erts/emulator/sys/ose/sys_time.c19
-rw-r--r--erts/emulator/sys/unix/driver_int.h21
-rw-r--r--erts/emulator/sys/unix/erl_child_setup.c45
-rw-r--r--erts/emulator/sys/unix/erl_main.c21
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h202
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys_ddll.c21
-rw-r--r--erts/emulator/sys/unix/sys.c541
-rw-r--r--erts/emulator/sys/unix/sys_float.c27
-rw-r--r--erts/emulator/sys/unix/sys_time.c881
-rw-r--r--erts/emulator/sys/win32/dosmap.c21
-rw-r--r--erts/emulator/sys/win32/driver_int.h21
-rw-r--r--erts/emulator/sys/win32/erl_main.c21
-rw-r--r--erts/emulator/sys/win32/erl_poll.c90
-rw-r--r--erts/emulator/sys/win32/erl_win32_sys_ddll.c24
-rw-r--r--erts/emulator/sys/win32/erl_win_dyn_driver.h39
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h111
-rw-r--r--erts/emulator/sys/win32/sys.c194
-rw-r--r--erts/emulator/sys/win32/sys_env.c19
-rw-r--r--erts/emulator/sys/win32/sys_float.c21
-rw-r--r--erts/emulator/sys/win32/sys_interrupt.c27
-rw-r--r--erts/emulator/sys/win32/sys_time.c418
-rw-r--r--erts/emulator/test/Makefile23
-rw-r--r--erts/emulator/test/a_SUITE.erl21
-rw-r--r--erts/emulator/test/after_SUITE.erl79
-rw-r--r--erts/emulator/test/alloc_SUITE.erl292
-rw-r--r--erts/emulator/test/alloc_SUITE_data/Makefile.src24
-rw-r--r--erts/emulator/test/alloc_SUITE_data/allocator_test.h41
-rw-r--r--erts/emulator/test/alloc_SUITE_data/basic.c24
-rw-r--r--erts/emulator/test/alloc_SUITE_data/basic.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_index.c23
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_index.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_mask.c25
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_mask.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/coalesce.c24
-rw-r--r--erts/emulator/test/alloc_SUITE_data/coalesce.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/cpool.c28
-rw-r--r--erts/emulator/test/alloc_SUITE_data/cpool.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/migration.c343
-rw-r--r--erts/emulator/test/alloc_SUITE_data/migration.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c24
-rw-r--r--erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/rbtree.c35
-rw-r--r--erts/emulator/test/alloc_SUITE_data/rbtree.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/realloc_copy.c23
-rw-r--r--erts/emulator/test/alloc_SUITE_data/realloc_copy.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.c276
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.h36
-rw-r--r--erts/emulator/test/alloc_SUITE_data/threads.c31
-rw-r--r--erts/emulator/test/alloc_SUITE_data/threads.erl10
-rw-r--r--erts/emulator/test/beam_SUITE.erl19
-rw-r--r--erts/emulator/test/beam_literals_SUITE.erl38
-rw-r--r--erts/emulator/test/bif_SUITE.erl52
-rw-r--r--erts/emulator/test/big_SUITE.erl21
-rw-r--r--erts/emulator/test/big_SUITE_data/literal_test.erl21
-rw-r--r--erts/emulator/test/binary_SUITE.erl23
-rw-r--r--erts/emulator/test/bs_bincomp_SUITE.erl21
-rw-r--r--erts/emulator/test/bs_bit_binaries_SUITE.erl21
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl61
-rw-r--r--erts/emulator/test/bs_match_bin_SUITE.erl21
-rw-r--r--erts/emulator/test/bs_match_int_SUITE.erl21
-rw-r--r--erts/emulator/test/bs_match_misc_SUITE.erl21
-rw-r--r--erts/emulator/test/bs_match_tail_SUITE.erl21
-rw-r--r--erts/emulator/test/bs_utf_SUITE.erl21
-rw-r--r--erts/emulator/test/busy_port_SUITE.erl27
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/Makefile.src21
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c21
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c21
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c21
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c21
-rw-r--r--erts/emulator/test/call_trace_SUITE.erl21
-rw-r--r--erts/emulator/test/code_SUITE.erl43
-rw-r--r--erts/emulator/test/code_SUITE_data/another_code_test.erl21
-rw-r--r--erts/emulator/test/code_SUITE_data/cpbugx.erl21
-rw-r--r--erts/emulator/test/code_SUITE_data/fun_confusion.erl21
-rw-r--r--erts/emulator/test/code_SUITE_data/literals.erl21
-rw-r--r--erts/emulator/test/code_SUITE_data/many_funs.erl21
-rw-r--r--erts/emulator/test/code_SUITE_data/my_code_test.erl21
-rw-r--r--erts/emulator/test/code_SUITE_data/versions.erl19
-rw-r--r--erts/emulator/test/code_parallel_load_SUITE.erl29
-rw-r--r--erts/emulator/test/crypto_SUITE.erl21
-rw-r--r--erts/emulator/test/crypto_reference.erl21
-rw-r--r--erts/emulator/test/ddll_SUITE.erl21
-rw-r--r--erts/emulator/test/decode_packet_SUITE.erl23
-rw-r--r--erts/emulator/test/dgawd_handler.erl21
-rw-r--r--erts/emulator/test/distribution_SUITE.erl44
-rw-r--r--erts/emulator/test/distribution_SUITE_data/run.erl68
-rw-r--r--erts/emulator/test/driver_SUITE.erl58
-rw-r--r--erts/emulator/test/driver_SUITE_data/async_blast_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/caller_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/chkio_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/invalid_extended_marker_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/io_ready_exit_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/larger_major_vsn_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/larger_minor_vsn_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/missing_callback_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/monitor_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/otp_6879_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/otp_9302_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/smaller_major_vsn_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/smaller_minor_vsn_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/sys_info_base_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/sys_info_curr_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.h21
-rw-r--r--erts/emulator/test/driver_SUITE_data/sys_info_prev_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/thr_alloc_drv.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/thr_free_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c19
-rw-r--r--erts/emulator/test/driver_SUITE_data/vsn_mismatch_drv_impl.c21
-rw-r--r--erts/emulator/test/driver_SUITE_data/zero_extended_marker_garb_drv.c21
-rw-r--r--erts/emulator/test/efile_SUITE.erl21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE.erl21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/Makefile.src21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/basic.c21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/rwlock.c21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.h21
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c21
-rw-r--r--erts/emulator/test/erl_link_SUITE.erl28
-rw-r--r--erts/emulator/test/erts_debug_SUITE.erl92
-rw-r--r--erts/emulator/test/estone_SUITE.erl50
-rw-r--r--erts/emulator/test/evil_SUITE.erl21
-rw-r--r--erts/emulator/test/exception_SUITE.erl21
-rw-r--r--erts/emulator/test/float_SUITE.erl28
-rw-r--r--erts/emulator/test/float_SUITE_data/fp_drv.c21
-rw-r--r--erts/emulator/test/float_SUITE_data/has_fpe_bug.erl21
-rw-r--r--erts/emulator/test/fun_SUITE.erl19
-rw-r--r--erts/emulator/test/fun_r13_SUITE.erl19
-rw-r--r--erts/emulator/test/gc_SUITE.erl31
-rw-r--r--erts/emulator/test/guard_SUITE.erl19
-rw-r--r--erts/emulator/test/hash_SUITE.erl48
-rw-r--r--erts/emulator/test/hibernate_SUITE.erl21
-rw-r--r--erts/emulator/test/ignore_cores.erl19
-rw-r--r--erts/emulator/test/list_bif_SUITE.erl21
-rw-r--r--erts/emulator/test/long_timers_test.erl117
-rw-r--r--erts/emulator/test/map_SUITE.erl2416
-rw-r--r--erts/emulator/test/map_SUITE_data/badmap_17.beambin0 -> 592 bytes
-rw-r--r--erts/emulator/test/map_SUITE_data/badmap_17.erl26
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl153
-rw-r--r--erts/emulator/test/module_info_SUITE.erl122
-rw-r--r--erts/emulator/test/module_info_SUITE_data/module_info_test.erl24
-rw-r--r--erts/emulator/test/monitor_SUITE.erl312
-rw-r--r--erts/emulator/test/mtx_SUITE.erl25
-rw-r--r--erts/emulator/test/mtx_SUITE_data/Makefile.src21
-rw-r--r--erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c19
-rw-r--r--erts/emulator/test/nested_SUITE.erl21
-rw-r--r--erts/emulator/test/nif_SUITE.erl289
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c279
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.c21
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.erl21
-rw-r--r--erts/emulator/test/nif_SUITE_data/testcase_driver.h21
-rw-r--r--erts/emulator/test/node_container_SUITE.erl89
-rw-r--r--erts/emulator/test/nofrag_SUITE.erl21
-rw-r--r--erts/emulator/test/num_bif_SUITE.erl23
-rw-r--r--erts/emulator/test/old_mod.erl21
-rw-r--r--erts/emulator/test/old_scheduler_SUITE.erl45
-rw-r--r--erts/emulator/test/op_SUITE.erl33
-rw-r--r--erts/emulator/test/port_SUITE.erl31
-rw-r--r--erts/emulator/test/port_SUITE_data/dead_port.c19
-rw-r--r--erts/emulator/test/port_SUITE_data/port_test.erl21
-rw-r--r--erts/emulator/test/port_bif_SUITE.erl21
-rw-r--r--erts/emulator/test/process_SUITE.erl49
-rw-r--r--erts/emulator/test/pseudoknot_SUITE.erl21
-rw-r--r--erts/emulator/test/random_iolist.erl21
-rw-r--r--erts/emulator/test/receive_SUITE.erl19
-rw-r--r--erts/emulator/test/ref_SUITE.erl21
-rw-r--r--erts/emulator/test/register_SUITE.erl21
-rw-r--r--erts/emulator/test/save_calls_SUITE.erl32
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl44
-rw-r--r--erts/emulator/test/send_term_SUITE.erl47
-rw-r--r--erts/emulator/test/send_term_SUITE_data/ext_terms.binbin476 -> 914 bytes
-rw-r--r--erts/emulator/test/send_term_SUITE_data/ext_terms.h147
-rw-r--r--erts/emulator/test/send_term_SUITE_data/send_term_drv.c21
-rw-r--r--erts/emulator/test/sensitive_SUITE.erl21
-rw-r--r--erts/emulator/test/signal_SUITE.erl27
-rw-r--r--erts/emulator/test/smoke_test_SUITE.erl26
-rw-r--r--erts/emulator/test/statistics_SUITE.erl90
-rw-r--r--erts/emulator/test/system_info_SUITE.erl57
-rw-r--r--erts/emulator/test/system_profile_SUITE.erl176
-rw-r--r--erts/emulator/test/time_SUITE.erl549
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl358
-rw-r--r--erts/emulator/test/trace_SUITE.erl19
-rw-r--r--erts/emulator/test/trace_bif_SUITE.erl287
-rw-r--r--erts/emulator/test/trace_call_count_SUITE.erl21
-rw-r--r--erts/emulator/test/trace_call_time_SUITE.erl37
-rw-r--r--erts/emulator/test/trace_local_SUITE.erl21
-rw-r--r--erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl21
-rw-r--r--erts/emulator/test/trace_meta_SUITE.erl631
-rw-r--r--erts/emulator/test/trace_nif_SUITE.erl21
-rw-r--r--erts/emulator/test/trace_port_SUITE.erl66
-rw-r--r--erts/emulator/test/trace_port_SUITE_data/echo_drv.c12
-rw-r--r--erts/emulator/test/tuple_SUITE.erl21
-rw-r--r--erts/emulator/test/unique_SUITE.erl391
-rw-r--r--erts/emulator/test/z_SUITE.erl21
-rwxr-xr-xerts/emulator/utils/beam_makeops19
-rwxr-xr-xerts/emulator/utils/beam_strip21
-rwxr-xr-xerts/emulator/utils/count19
-rw-r--r--erts/emulator/utils/loaded19
-rwxr-xr-xerts/emulator/utils/make_alloc_types44
-rwxr-xr-xerts/emulator/utils/make_compiler_flags19
-rwxr-xr-xerts/emulator/utils/make_driver_tab21
-rwxr-xr-xerts/emulator/utils/make_preload21
-rwxr-xr-xerts/emulator/utils/make_tables19
-rwxr-xr-xerts/emulator/utils/make_version27
-rw-r--r--erts/emulator/utils/mkver.c27
-rw-r--r--erts/emulator/valgrind/suppress.patched.3.6.017
-rw-r--r--erts/emulator/valgrind/suppress.standard17
-rw-r--r--erts/emulator/zlib/zlib.mk19
-rw-r--r--erts/epmd/Makefile21
-rw-r--r--erts/epmd/epmd.mk21
-rw-r--r--erts/epmd/src/Makefile21
-rw-r--r--erts/epmd/src/Makefile.in21
-rw-r--r--erts/epmd/src/epmd.c33
-rw-r--r--erts/epmd/src/epmd.h21
-rw-r--r--erts/epmd/src/epmd_cli.c51
-rw-r--r--erts/epmd/src/epmd_int.h82
-rw-r--r--erts/epmd/src/epmd_srv.c227
-rw-r--r--erts/epmd/test/Makefile19
-rw-r--r--erts/epmd/test/epmd_SUITE.erl110
-rw-r--r--erts/etc/Makefile21
-rw-r--r--erts/etc/common/Makefile21
-rw-r--r--erts/etc/common/Makefile.in19
-rw-r--r--erts/etc/common/ct_run.c19
-rw-r--r--erts/etc/common/dialyzer.c21
-rw-r--r--erts/etc/common/erlc.c19
-rw-r--r--erts/etc/common/erlexec.c44
-rw-r--r--erts/etc/common/escript.c19
-rw-r--r--erts/etc/common/heart.c62
-rw-r--r--erts/etc/common/inet_gethost.c19
-rw-r--r--erts/etc/common/run_erl_common.c23
-rw-r--r--erts/etc/common/run_erl_common.h19
-rw-r--r--erts/etc/common/run_erl_vsn.h19
-rw-r--r--erts/etc/common/safe_string.c19
-rw-r--r--erts/etc/common/safe_string.h19
-rw-r--r--erts/etc/common/to_erl_common.c19
-rw-r--r--erts/etc/common/to_erl_common.h19
-rw-r--r--erts/etc/common/typer.c21
-rw-r--r--erts/etc/ose/run_erl.c21
-rw-r--r--erts/etc/ose/run_erl.h19
-rw-r--r--erts/etc/ose/run_erl_main.c19
-rw-r--r--erts/etc/unix/Install.src19
-rw-r--r--erts/etc/unix/Makefile19
-rw-r--r--erts/etc/unix/README19
-rw-r--r--erts/etc/unix/RELNOTES19
-rw-r--r--erts/etc/unix/cerl.src29
-rw-r--r--erts/etc/unix/dyn_erl.c21
-rw-r--r--erts/etc/unix/erl.src.src21
-rw-r--r--erts/etc/unix/etp-commands.in111
-rw-r--r--erts/etc/unix/etp-thr.py19
-rw-r--r--erts/etc/unix/etp_commands.erl21
-rw-r--r--erts/etc/unix/etp_commands.mk21
-rw-r--r--erts/etc/unix/format_man_pages21
-rw-r--r--erts/etc/unix/run_erl.c21
-rw-r--r--erts/etc/unix/setuid_socket_wrap.c21
-rw-r--r--erts/etc/unix/start.src21
-rw-r--r--erts/etc/unix/start_erl.src21
-rw-r--r--erts/etc/unix/to_erl.c21
-rw-r--r--erts/etc/win32/Install.c19
-rw-r--r--erts/etc/win32/Makefile21
-rw-r--r--erts/etc/win32/Nmakefile.start_erl21
-rw-r--r--erts/etc/win32/beam.rc21
-rwxr-xr-xerts/etc/win32/cygwin_tools/erl21
-rwxr-xr-xerts/etc/win32/cygwin_tools/erlc21
-rwxr-xr-xerts/etc/win32/cygwin_tools/javac.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/make_bootstrap_ini.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/make_local_ini.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/mingw/ar.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/mingw/cc.sh21
-rw-r--r--erts/etc/win32/cygwin_tools/mingw/coffix.c21
-rwxr-xr-xerts/etc/win32/cygwin_tools/mingw/emu_cc.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/mingw/ld.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/mingw/mc.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/mingw/rc.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/ar.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/cc.sh23
-rw-r--r--erts/etc/win32/cygwin_tools/vc/cc_wrap.c21
-rw-r--r--erts/etc/win32/cygwin_tools/vc/coffix.c21
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/emu_cc.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/ld.sh21
-rw-r--r--erts/etc/win32/cygwin_tools/vc/ld_wrap.c21
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/mc.sh21
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/rc.sh19
-rw-r--r--erts/etc/win32/erl.c21
-rw-r--r--erts/etc/win32/erl.rc21
-rw-r--r--erts/etc/win32/erl_log.c21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_global.h21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_interactive.c21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_interactive.h21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_main.c21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_registry.c21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_registry.h21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_service.c21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_service.h21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_util.c21
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_util.h21
-rw-r--r--erts/etc/win32/init_file.c21
-rw-r--r--erts/etc/win32/init_file.h21
-rw-r--r--erts/etc/win32/msys_tools/erl21
-rw-r--r--erts/etc/win32/msys_tools/erlc21
-rw-r--r--erts/etc/win32/msys_tools/javac.sh21
-rw-r--r--erts/etc/win32/msys_tools/make_bootstrap_ini.sh21
-rw-r--r--erts/etc/win32/msys_tools/make_local_ini.sh21
-rw-r--r--erts/etc/win32/msys_tools/vc/ar.sh21
-rw-r--r--erts/etc/win32/msys_tools/vc/cc.sh33
-rw-r--r--erts/etc/win32/msys_tools/vc/coffix.c21
-rw-r--r--erts/etc/win32/msys_tools/vc/emu_cc.sh22
-rw-r--r--erts/etc/win32/msys_tools/vc/ld.sh21
-rw-r--r--erts/etc/win32/msys_tools/vc/mc.sh28
-rw-r--r--erts/etc/win32/msys_tools/vc/rc.sh28
-rw-r--r--erts/etc/win32/nsis/Makefile31
-rwxr-xr-xerts/etc/win32/nsis/dll_version_helper.sh21
-rw-r--r--erts/etc/win32/nsis/erlang20.nsi19
-rwxr-xr-xerts/etc/win32/nsis/find_redist.sh23
-rw-r--r--erts/etc/win32/port_entry.c21
-rw-r--r--erts/etc/win32/resource.h21
-rw-r--r--erts/etc/win32/start_erl.c21
-rw-r--r--erts/etc/win32/win_erlexec.c21
-rw-r--r--erts/example/Makefile23
-rw-r--r--erts/example/matrix_nif.c19
-rw-r--r--erts/example/matrix_nif.erl21
-rw-r--r--erts/example/next_perm.cc21
-rw-r--r--erts/example/next_perm.erl21
-rw-r--r--erts/example/pg_async.c21
-rw-r--r--erts/example/pg_async.erl21
-rw-r--r--erts/example/pg_async2.c21
-rw-r--r--erts/example/pg_async2.erl21
-rw-r--r--erts/example/pg_encode.c21
-rw-r--r--erts/example/pg_encode.h21
-rw-r--r--erts/example/pg_encode2.c21
-rw-r--r--erts/example/pg_encode2.h21
-rw-r--r--erts/example/pg_sync.c21
-rw-r--r--erts/example/pg_sync.erl21
-rw-r--r--erts/example/time_compat.erl305
-rw-r--r--erts/include/erl_fixed_size_int_types.h21
-rw-r--r--erts/include/erl_int_sizes_config.h.in19
-rw-r--r--erts/include/erl_memory_trace_parser.h21
-rw-r--r--erts/include/erl_native_features_config.h.in19
-rw-r--r--erts/include/internal/README19
-rw-r--r--erts/include/internal/erl_errno.h21
-rw-r--r--erts/include/internal/erl_memory_trace_protocol.h21
-rw-r--r--erts/include/internal/erl_misc_utils.h21
-rw-r--r--erts/include/internal/erl_printf.h21
-rw-r--r--erts/include/internal/erl_printf_format.h21
-rw-r--r--erts/include/internal/erts_internal.mk.in21
-rw-r--r--erts/include/internal/ethr_atomics.h19
-rw-r--r--erts/include/internal/ethr_internal.h46
-rw-r--r--erts/include/internal/ethr_mutex.h19
-rw-r--r--erts/include/internal/ethr_optimized_fallbacks.h19
-rw-r--r--erts/include/internal/ethread.h41
-rw-r--r--erts/include/internal/ethread.mk.in21
-rw-r--r--erts/include/internal/ethread_header_config.h.in106
-rw-r--r--erts/include/internal/ethread_inline.h42
-rw-r--r--erts/include/internal/gcc/ethr_atomic.h496
-rw-r--r--erts/include/internal/gcc/ethr_dw_atomic.h197
-rw-r--r--erts/include/internal/gcc/ethr_membar.h227
-rw-r--r--erts/include/internal/gcc/ethread.h348
-rw-r--r--erts/include/internal/i386/atomic.h19
-rw-r--r--erts/include/internal/i386/ethr_dw_atomic.h92
-rw-r--r--erts/include/internal/i386/ethr_membar.h19
-rw-r--r--erts/include/internal/i386/ethread.h21
-rw-r--r--erts/include/internal/i386/rwlock.h19
-rw-r--r--erts/include/internal/i386/spinlock.h19
-rw-r--r--erts/include/internal/libatomic_ops/ethr_atomic.h19
-rw-r--r--erts/include/internal/libatomic_ops/ethr_dw_atomic.h19
-rw-r--r--erts/include/internal/libatomic_ops/ethr_membar.h19
-rw-r--r--erts/include/internal/libatomic_ops/ethread.h19
-rw-r--r--erts/include/internal/ose/ethr_event.h19
-rw-r--r--erts/include/internal/ppc32/atomic.h19
-rw-r--r--erts/include/internal/ppc32/ethr_membar.h19
-rw-r--r--erts/include/internal/ppc32/ethread.h21
-rw-r--r--erts/include/internal/ppc32/rwlock.h19
-rw-r--r--erts/include/internal/ppc32/spinlock.h19
-rw-r--r--erts/include/internal/pthread/ethr_event.h89
-rw-r--r--erts/include/internal/sparc32/atomic.h19
-rw-r--r--erts/include/internal/sparc32/ethr_membar.h19
-rw-r--r--erts/include/internal/sparc32/ethread.h21
-rw-r--r--erts/include/internal/sparc32/rwlock.h19
-rw-r--r--erts/include/internal/sparc32/spinlock.h19
-rw-r--r--erts/include/internal/sparc64/ethread.h21
-rw-r--r--erts/include/internal/tile/atomic.h19
-rw-r--r--erts/include/internal/tile/ethr_membar.h19
-rw-r--r--erts/include/internal/tile/ethread.h21
-rw-r--r--erts/include/internal/win/ethr_atomic.h19
-rw-r--r--erts/include/internal/win/ethr_dw_atomic.h19
-rw-r--r--erts/include/internal/win/ethr_event.h22
-rw-r--r--erts/include/internal/win/ethr_membar.h19
-rw-r--r--erts/include/internal/win/ethread.h19
-rw-r--r--erts/include/internal/x86_64/ethread.h21
-rw-r--r--erts/lib/internal/README19
-rw-r--r--erts/lib_src/Makefile21
-rw-r--r--erts/lib_src/Makefile.in25
-rw-r--r--erts/lib_src/common/erl_memory_trace_parser.c21
-rw-r--r--erts/lib_src/common/erl_misc_utils.c19
-rw-r--r--erts/lib_src/common/erl_printf.c68
-rw-r--r--erts/lib_src/common/erl_printf_format.c21
-rw-r--r--erts/lib_src/common/ethr_atomics.c19
-rw-r--r--erts/lib_src/common/ethr_aux.c25
-rw-r--r--erts/lib_src/common/ethr_cbf.c19
-rw-r--r--erts/lib_src/common/ethr_mutex.c19
-rw-r--r--erts/lib_src/ose/ethr_event.c19
-rw-r--r--erts/lib_src/ose/ethread.c19
-rw-r--r--erts/lib_src/pthread/ethr_event.c485
-rw-r--r--erts/lib_src/pthread/ethr_x86_sse2_asm.c19
-rw-r--r--erts/lib_src/pthread/ethread.c213
-rwxr-xr-xerts/lib_src/utils/make_atomics_api38
-rw-r--r--erts/lib_src/win/ethr_event.c78
-rw-r--r--erts/lib_src/win/ethread.c32
-rw-r--r--erts/preloaded/Makefile21
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin56292 -> 56336 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin97956 -> 102112 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin4164 -> 6500 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin48808 -> 48764 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1468 -> 1468 bytes
-rw-r--r--erts/preloaded/ebin/prim_eval.beambin1340 -> 1340 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin44904 -> 45004 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin73128 -> 72716 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin23440 -> 23424 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin13188 -> 14176 bytes
-rw-r--r--erts/preloaded/src/Makefile21
-rw-r--r--erts/preloaded/src/add_abstract_code19
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl19
-rw-r--r--erts/preloaded/src/erlang.erl274
-rw-r--r--erts/preloaded/src/erts.app.src23
-rw-r--r--erts/preloaded/src/erts_internal.erl125
-rw-r--r--erts/preloaded/src/init.erl28
-rw-r--r--erts/preloaded/src/otp_ring0.erl19
-rw-r--r--erts/preloaded/src/prim_eval.S19
-rw-r--r--erts/preloaded/src/prim_eval.erl19
-rw-r--r--erts/preloaded/src/prim_file.erl22
-rw-r--r--erts/preloaded/src/prim_inet.erl65
-rw-r--r--erts/preloaded/src/prim_zip.erl19
-rw-r--r--erts/preloaded/src/zip_internal.hrl21
-rw-r--r--erts/preloaded/src/zlib.erl66
-rw-r--r--erts/start_scripts/Makefile19
-rw-r--r--erts/start_scripts/no_dot_erlang.rel.src19
-rw-r--r--erts/start_scripts/start_all_example.rel.src21
-rw-r--r--erts/start_scripts/start_clean.rel.src21
-rw-r--r--erts/start_scripts/start_sasl.rel.src21
-rw-r--r--erts/test/Makefile19
-rw-r--r--erts/test/erl_print_SUITE.erl19
-rw-r--r--erts/test/erl_print_SUITE_data/Makefile.src21
-rw-r--r--erts/test/erl_print_SUITE_data/character_test.h21
-rw-r--r--erts/test/erl_print_SUITE_data/erl_print_tests.c42
-rw-r--r--erts/test/erl_print_SUITE_data/integer_64_test.h21
-rw-r--r--erts/test/erl_print_SUITE_data/integer_test.h21
-rw-r--r--erts/test/erl_print_SUITE_data/snprintf_test.h21
-rw-r--r--erts/test/erl_print_SUITE_data/string_test.h21
-rw-r--r--erts/test/erlc_SUITE.erl19
-rw-r--r--erts/test/erlc_SUITE_data/include/erl_test.hrl21
-rw-r--r--erts/test/erlc_SUITE_data/src/erl_test_bad.erl21
-rw-r--r--erts/test/erlc_SUITE_data/src/erl_test_missing_header.erl19
-rw-r--r--erts/test/erlc_SUITE_data/src/erl_test_ok.erl21
-rw-r--r--erts/test/erlc_SUITE_data/src/start_ok.script2
-rw-r--r--erts/test/erlc_SUITE_data/src/yecc_test_bad.yrl21
-rw-r--r--erts/test/erlc_SUITE_data/src/yecc_test_ok.yrl21
-rw-r--r--erts/test/erlexec_SUITE.erl26
-rw-r--r--erts/test/erlexec_SUITE_data/Makefile.src21
-rw-r--r--erts/test/erlexec_SUITE_data/erlexec_tests.c19
-rw-r--r--erts/test/ethread_SUITE.erl19
-rw-r--r--erts/test/ethread_SUITE_data/Makefile.src21
-rw-r--r--erts/test/ethread_SUITE_data/ethread_tests.c25
-rw-r--r--erts/test/ignore_cores.erl19
-rw-r--r--erts/test/install_SUITE.erl19
-rw-r--r--erts/test/nt_SUITE.erl19
-rw-r--r--erts/test/nt_SUITE_data/Makefile.src21
-rw-r--r--erts/test/nt_SUITE_data/nt_info.c21
-rw-r--r--erts/test/otp_SUITE.erl65
-rw-r--r--erts/test/run_erl_SUITE.erl19
-rw-r--r--erts/test/run_erl_SUITE_data/defuncter.pl21
-rw-r--r--erts/test/run_erl_SUITE_data/run_erl_test.pl21
-rw-r--r--erts/test/upgrade_SUITE.erl26
-rw-r--r--erts/test/upgrade_SUITE_data/start.src21
-rw-r--r--erts/test/utils/gccifier.c21
-rwxr-xr-xerts/test/utils/gccifier.sh19
-rw-r--r--erts/test/z_SUITE.erl19
-rw-r--r--erts/vsn.mk21
-rw-r--r--lib/.gitignore4
-rw-r--r--lib/Makefile19
-rw-r--r--lib/asn1/Makefile21
-rw-r--r--lib/asn1/c_src/Makefile19
-rw-r--r--lib/asn1/c_src/asn1_erl_nif.c19
-rw-r--r--lib/asn1/doc/src/Makefile25
-rw-r--r--lib/asn1/doc/src/asn1_getting_started.xml1291
-rw-r--r--lib/asn1/doc/src/asn1_introduction.xml100
-rw-r--r--lib/asn1/doc/src/asn1_overview.xml50
-rw-r--r--lib/asn1/doc/src/asn1_spec.xmlsrc543
-rw-r--r--lib/asn1/doc/src/asn1_ug.xml1417
-rw-r--r--lib/asn1/doc/src/asn1ct.xml353
-rw-r--r--lib/asn1/doc/src/asn1rt.xml47
-rw-r--r--lib/asn1/doc/src/book.xml21
-rw-r--r--lib/asn1/doc/src/notes.xml93
-rw-r--r--lib/asn1/doc/src/part.xml30
-rw-r--r--lib/asn1/doc/src/ref_man.xml27
-rw-r--r--lib/asn1/doc/users_guide/Makefile21
-rw-r--r--lib/asn1/doc/users_guide/users_guide.sgml21
-rw-r--r--lib/asn1/src/Makefile22
-rw-r--r--lib/asn1/src/asn1.app.src2
-rw-r--r--lib/asn1/src/asn1.appup.src19
-rw-r--r--lib/asn1/src/asn1_app.erl21
-rw-r--r--lib/asn1/src/asn1_db.erl27
-rw-r--r--lib/asn1/src/asn1_records.hrl35
-rw-r--r--lib/asn1/src/asn1ct.erl90
-rw-r--r--lib/asn1/src/asn1ct_check.erl5295
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl21
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl174
-rw-r--r--lib/asn1/src/asn1ct_func.erl19
-rw-r--r--lib/asn1/src/asn1ct_gen.erl95
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl128
-rw-r--r--lib/asn1/src/asn1ct_gen_check.erl19
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl19
-rw-r--r--lib/asn1/src/asn1ct_imm.erl99
-rw-r--r--lib/asn1/src/asn1ct_name.erl21
-rw-r--r--lib/asn1/src/asn1ct_parser.yrl1177
-rw-r--r--lib/asn1/src/asn1ct_parser2.erl2536
-rw-r--r--lib/asn1/src/asn1ct_pretty_format.erl21
-rw-r--r--lib/asn1/src/asn1ct_table.erl19
-rw-r--r--lib/asn1/src/asn1ct_tok.erl351
-rw-r--r--lib/asn1/src/asn1ct_value.erl26
-rw-r--r--lib/asn1/src/asn1rt.erl21
-rw-r--r--lib/asn1/src/asn1rt_nif.erl19
-rw-r--r--lib/asn1/src/asn1rtt_ber.erl23
-rw-r--r--lib/asn1/src/asn1rtt_check.erl19
-rw-r--r--lib/asn1/src/asn1rtt_ext.erl19
-rw-r--r--lib/asn1/src/asn1rtt_per.erl19
-rw-r--r--lib/asn1/src/asn1rtt_per_common.erl19
-rw-r--r--lib/asn1/src/asn1rtt_real_common.erl19
-rw-r--r--lib/asn1/src/asn1rtt_uper.erl19
-rw-r--r--lib/asn1/src/notes_history.sgml21
-rw-r--r--lib/asn1/src/notes_latest.sgml21
-rw-r--r--lib/asn1/src/prepare_templates.erl19
-rw-r--r--lib/asn1/test/External.hrl21
-rw-r--r--lib/asn1/test/Makefile29
-rw-r--r--lib/asn1/test/asn1_SUITE.erl161
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn6
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadValueSet.asn19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoExtension.asn16
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn127
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn160
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constraints.py44
-rw-r--r--lib/asn1/test/asn1_SUITE_data/CoverParser.asn157
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EnumExt.asn12
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Example.asn120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Export1.asn7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Exporting.asn118
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ExtensibilityImplied.asn130
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/IllegalExport.asn17
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Importing.asn120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfObj.asn188
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1136
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MissingEnd.asn15
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn11
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ParamBasic.asn133
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Prim.asn19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SelectionType.asn8
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Seq.py5
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn6
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn110
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn110
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Syntax.py10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl21
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ValueTest.asn96
-rw-r--r--lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl21
-rw-r--r--lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl21
-rw-r--r--lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/ACSE-1.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/AlgorithmInformation-2009.asn1466
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/AttributeCertificateVersion1-2009.asn159
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/AuthenticationFramework.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/BasicAccessControl.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/CertificateExtensions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Character-Coding-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Character-Presentation-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Character-Profile-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Colour-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntax-2009.asn1463
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntaxAlgorithms-2009.asn1248
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DOR-definition.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DSAOperationalAttributeTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Default-Value-Lists.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryAbstractService.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryAccessProtocol.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryInformationShadowProtocol.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryOperationalBindingManagementProtocol.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryOperationalBindingTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryProtectionMappings.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryShadowAbstractService.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DirectorySystemProtocol.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/DistributedOperations.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Document-Profile-Descriptor.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/EnhancedSecurity.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/EnrollmentMessageSyntax-2009.asn1543
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/External-References.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/External-References.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/GULSProtectionMappings.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/GenericProtectingTransferSyntax.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Coding-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Presentation-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Profile-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/GulsSecurityExchanges.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/GulsSecurityTransformations.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/HierarchicalOperationalBindings.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSAbstractService.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSAutoActionTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedBodyPartTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedBodyPartTypes2.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedVoiceBodyPartType.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSFileTransferBodyPartType.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSForwardedContentBodyPartType.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSForwardedReportBodyPartType.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSFunctionalObjects.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSHeadingExtensions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSInformationObjects.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSMessageStoreAttributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSObjectIdentifiers2.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSSecurityExtensions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/IPMSUpperBounds.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/ISO8571-FTAM.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/ISO9541-SN.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Identifiers-and-Expressions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/InformationFramework.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Interchange-Data-Elements.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Layout-Descriptors.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Link-Descriptors.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Location-Expressions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Logical-Descriptors.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MHSObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MHSProtocolObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSAbstractService.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSAccessProtocol.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSGeneralAttributeTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSGeneralAutoActionTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSMatchingRules.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MSUpperBounds.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MTAAbstractService.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MTSAbstractService.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MTSAbstractService88.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MTSAccessProtocol.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MTSObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/MTSUpperBounds.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Notation.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Notation.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/OCSP-2009.asn1183
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/OLD-PKCS7.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn)2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/ObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/OperationalBindingManagement.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-10.asn156
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-12.asn1174
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-5.asn1202
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-7.asn1326
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-8.asn161
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-9.asn1391
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKCS7BodyPartType.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn)2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-CommonTypes-2009.asn1166
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-X400Address-2009.asn1300
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1-PSS-OAEP-Algorithms-2009.asn1308
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Explicit-2009.asn1415
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Implicit-2009.asn1447
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAlgs-2009.asn1528
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAttributeCertificate-2009.asn1292
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCMP-2009.asn1495
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCRMF-2009.asn1409
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Protected-Part-Descriptors.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/ProtocolObjectIdentifiers.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Coding-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Presentation-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Profile-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Reliable-Transfer-APDU.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Abstract-Syntaxes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Generic-ROS-PDUs.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Information-Objects-extensions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Information-Objects.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Realizations.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Useful-Definitions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/SCVP-2009.asn1608
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/SecureMimeMessageV3dot1-2009.asn1122
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/SelectedAttributeTypes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/SeseAPDUs.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/SpkmGssTokens.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Style-Descriptors.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Subprofiles.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Temporal-Relationships.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Text-Units.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/UpperBounds.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/UsefulDefinitions.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/rfcs/Videotex-Coding-Attributes.asn1 (renamed from lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/test_records.erl21
-rw-r--r--lib/asn1/test/asn1_SUITE_data/testobj.erl19
-rw-r--r--lib/asn1/test/asn1_app_test.erl19
-rw-r--r--lib/asn1/test/asn1_appup_test.erl21
-rw-r--r--lib/asn1/test/asn1_test_lib.erl46
-rw-r--r--lib/asn1/test/ber_decode_error.erl19
-rw-r--r--lib/asn1/test/error_SUITE.erl744
-rw-r--r--lib/asn1/test/h323test.erl19
-rw-r--r--lib/asn1/test/syntax_SUITE.erl341
-rw-r--r--lib/asn1/test/testChoExtension.erl24
-rw-r--r--lib/asn1/test/testChoExternal.erl21
-rw-r--r--lib/asn1/test/testChoOptional.erl21
-rw-r--r--lib/asn1/test/testChoPrim.erl19
-rw-r--r--lib/asn1/test/testChoRecursive.erl21
-rw-r--r--lib/asn1/test/testChoTypeRefCho.erl21
-rw-r--r--lib/asn1/test/testChoTypeRefPrim.erl21
-rw-r--r--lib/asn1/test/testChoTypeRefSeq.erl21
-rw-r--r--lib/asn1/test/testChoTypeRefSet.erl21
-rw-r--r--lib/asn1/test/testChoiceIndefinite.erl21
-rw-r--r--lib/asn1/test/testCompactBitString.erl19
-rw-r--r--lib/asn1/test/testConstraints.erl41
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl19
-rw-r--r--lib/asn1/test/testDER.erl21
-rw-r--r--lib/asn1/test/testDeepTConstr.erl19
-rw-r--r--lib/asn1/test/testDef.erl19
-rw-r--r--lib/asn1/test/testDoubleEllipses.erl19
-rw-r--r--lib/asn1/test/testEnumExt.erl47
-rw-r--r--lib/asn1/test/testExtensibilityImplied.erl30
-rw-r--r--lib/asn1/test/testFragmented.erl21
-rw-r--r--lib/asn1/test/testINSTANCE_OF.erl21
-rw-r--r--lib/asn1/test/testImporting.erl35
-rw-r--r--lib/asn1/test/testInfObj.erl58
-rw-r--r--lib/asn1/test/testInfObjExtract.erl73
-rw-r--r--lib/asn1/test/testInfObjectClass.erl21
-rw-r--r--lib/asn1/test/testMegaco.erl21
-rw-r--r--lib/asn1/test/testMergeCompile.erl19
-rw-r--r--lib/asn1/test/testMultipleLevels.erl21
-rw-r--r--lib/asn1/test/testNBAPsystem.erl19
-rw-r--r--lib/asn1/test/testOpenTypeImplicitTag.erl21
-rw-r--r--lib/asn1/test/testOpt.erl19
-rw-r--r--lib/asn1/test/testParamBasic.erl27
-rw-r--r--lib/asn1/test/testParameterizedInfObj.erl19
-rw-r--r--lib/asn1/test/testPrim.erl53
-rw-r--r--lib/asn1/test/testPrimExternal.erl21
-rw-r--r--lib/asn1/test/testPrimStrings.erl31
-rw-r--r--lib/asn1/test/testRfcs.erl76
-rw-r--r--lib/asn1/test/testSSLspecs.erl19
-rw-r--r--lib/asn1/test/testSelectionTypes.erl47
-rw-r--r--lib/asn1/test/testSeq2738.erl21
-rw-r--r--lib/asn1/test/testSeqDefault.erl19
-rw-r--r--lib/asn1/test/testSeqExtension.erl19
-rw-r--r--lib/asn1/test/testSeqExternal.erl21
-rw-r--r--lib/asn1/test/testSeqOf.erl19
-rw-r--r--lib/asn1/test/testSeqOfCho.erl19
-rw-r--r--lib/asn1/test/testSeqOfExternal.erl19
-rw-r--r--lib/asn1/test/testSeqOfIndefinite.erl19
-rw-r--r--lib/asn1/test/testSeqOfTag.erl19
-rw-r--r--lib/asn1/test/testSeqOptional.erl19
-rw-r--r--lib/asn1/test/testSeqPrim.erl21
-rw-r--r--lib/asn1/test/testSeqSetDefaultVal.erl19
-rw-r--r--lib/asn1/test/testSeqSetIndefinite.erl21
-rw-r--r--lib/asn1/test/testSeqTag.erl21
-rw-r--r--lib/asn1/test/testSeqTypeRefCho.erl21
-rw-r--r--lib/asn1/test/testSeqTypeRefPrim.erl21
-rw-r--r--lib/asn1/test/testSeqTypeRefSeq.erl19
-rw-r--r--lib/asn1/test/testSeqTypeRefSet.erl21
-rw-r--r--lib/asn1/test/testSetDefault.erl21
-rw-r--r--lib/asn1/test/testSetExtension.erl21
-rw-r--r--lib/asn1/test/testSetExternal.erl21
-rw-r--r--lib/asn1/test/testSetOf.erl19
-rw-r--r--lib/asn1/test/testSetOfCho.erl19
-rw-r--r--lib/asn1/test/testSetOfExternal.erl19
-rw-r--r--lib/asn1/test/testSetOfTag.erl19
-rw-r--r--lib/asn1/test/testSetOptional.erl19
-rw-r--r--lib/asn1/test/testSetPrim.erl21
-rw-r--r--lib/asn1/test/testSetTag.erl21
-rw-r--r--lib/asn1/test/testSetTypeRefCho.erl21
-rw-r--r--lib/asn1/test/testSetTypeRefPrim.erl21
-rw-r--r--lib/asn1/test/testSetTypeRefSeq.erl21
-rw-r--r--lib/asn1/test/testSetTypeRefSet.erl19
-rw-r--r--lib/asn1/test/testTCAP.erl19
-rw-r--r--lib/asn1/test/testTcapsystem.erl21
-rw-r--r--lib/asn1/test/testTimer.erl19
-rw-r--r--lib/asn1/test/testTypeValueNotation.erl21
-rw-r--r--lib/asn1/test/testUniqueObjectSets.erl176
-rw-r--r--lib/asn1/test/testValueTest.erl115
-rw-r--r--lib/asn1/test/testX420.erl93
-rw-r--r--lib/asn1/test/test_compile_options.erl58
-rw-r--r--lib/asn1/test/test_modified_x420.erl21
-rw-r--r--lib/asn1/test/test_partial_incomplete_decode.erl19
-rw-r--r--lib/asn1/test/test_selective_decode.erl19
-rw-r--r--lib/asn1/test/test_special_decode_performance.erl19
-rw-r--r--lib/asn1/test/test_undecoded_rest.erl19
-rw-r--r--lib/asn1/test/test_x691.erl19
-rw-r--r--lib/asn1/vsn.mk3
-rw-r--r--lib/common_test/Makefile21
-rw-r--r--lib/common_test/doc/src/Makefile62
-rw-r--r--lib/common_test/doc/src/basics_chapter.xml251
-rw-r--r--lib/common_test/doc/src/book.xml21
-rw-r--r--lib/common_test/doc/src/common_test_app.xml805
-rw-r--r--lib/common_test/doc/src/config_file_chapter.xml579
-rw-r--r--lib/common_test/doc/src/cover_chapter.xml370
-rw-r--r--lib/common_test/doc/src/ct.xml1415
-rw-r--r--lib/common_test/doc/src/ct_cover.xml106
-rw-r--r--lib/common_test/doc/src/ct_ftp.xml277
-rw-r--r--lib/common_test/doc/src/ct_hooks.xml877
-rw-r--r--lib/common_test/doc/src/ct_hooks_chapter.xml722
-rw-r--r--lib/common_test/doc/src/ct_master.xml220
-rw-r--r--lib/common_test/doc/src/ct_master_chapter.xml312
-rw-r--r--lib/common_test/doc/src/ct_netconfc.xml1039
-rw-r--r--lib/common_test/doc/src/ct_property_test.xml116
-rw-r--r--lib/common_test/doc/src/ct_rpc.xml220
-rw-r--r--lib/common_test/doc/src/ct_run.xml318
-rw-r--r--lib/common_test/doc/src/ct_slave.xml221
-rw-r--r--lib/common_test/doc/src/ct_snmp.xml523
-rw-r--r--lib/common_test/doc/src/ct_ssh.xml1150
-rw-r--r--lib/common_test/doc/src/ct_telnet.xml604
-rw-r--r--lib/common_test/doc/src/dependencies_chapter.xml403
-rw-r--r--lib/common_test/doc/src/event_handler_chapter.xml406
-rw-r--r--lib/common_test/doc/src/example_chapter.xml929
-rw-r--r--lib/common_test/doc/src/getting_started_chapter.xml305
-rw-r--r--lib/common_test/doc/src/install_chapter.xml103
-rw-r--r--lib/common_test/doc/src/introduction.xml75
-rw-r--r--lib/common_test/doc/src/notes.xml370
-rw-r--r--lib/common_test/doc/src/notes_history.xml21
-rw-r--r--lib/common_test/doc/src/part.xml54
-rw-r--r--lib/common_test/doc/src/part_notes.xml21
-rw-r--r--lib/common_test/doc/src/part_notes_history.xml21
-rw-r--r--lib/common_test/doc/src/ref_man.xml59
-rw-r--r--lib/common_test/doc/src/run_test_chapter.xml2241
-rw-r--r--lib/common_test/doc/src/test_structure_chapter.xml167
-rw-r--r--lib/common_test/doc/src/unix_telnet.xml135
-rw-r--r--lib/common_test/doc/src/why_test_chapter.xml64
-rw-r--r--lib/common_test/doc/src/write_test_chapter.xml1390
-rw-r--r--lib/common_test/include/ct.hrl19
-rw-r--r--lib/common_test/include/ct_event.hrl21
-rw-r--r--lib/common_test/install.sh.in53
-rw-r--r--lib/common_test/priv/Makefile21
-rw-r--r--lib/common_test/priv/Makefile.in30
-rw-r--r--lib/common_test/priv/run_test.in63
-rw-r--r--lib/common_test/src/Makefile24
-rw-r--r--lib/common_test/src/common_test.app.src30
-rw-r--r--lib/common_test/src/common_test.appup.src19
-rw-r--r--lib/common_test/src/ct.erl153
-rw-r--r--lib/common_test/src/ct_config.erl22
-rw-r--r--lib/common_test/src/ct_config_plain.erl19
-rw-r--r--lib/common_test/src/ct_config_xml.erl19
-rw-r--r--lib/common_test/src/ct_conn_log_h.erl82
-rw-r--r--lib/common_test/src/ct_cover.erl21
-rw-r--r--lib/common_test/src/ct_event.erl25
-rw-r--r--lib/common_test/src/ct_framework.erl195
-rw-r--r--lib/common_test/src/ct_ftp.erl21
-rw-r--r--lib/common_test/src/ct_gen_conn.erl24
-rw-r--r--lib/common_test/src/ct_groups.erl140
-rw-r--r--lib/common_test/src/ct_hooks.erl49
-rw-r--r--lib/common_test/src/ct_hooks_lock.erl19
-rw-r--r--lib/common_test/src/ct_logs.erl345
-rw-r--r--lib/common_test/src/ct_make.erl21
-rw-r--r--lib/common_test/src/ct_master.erl31
-rw-r--r--lib/common_test/src/ct_master_event.erl23
-rw-r--r--lib/common_test/src/ct_master_logs.erl40
-rw-r--r--lib/common_test/src/ct_master_status.erl25
-rw-r--r--lib/common_test/src/ct_netconfc.erl184
-rw-r--r--lib/common_test/src/ct_netconfc.hrl21
-rw-r--r--lib/common_test/src/ct_property_test.erl21
-rw-r--r--lib/common_test/src/ct_release_test.erl950
-rw-r--r--lib/common_test/src/ct_repeat.erl19
-rw-r--r--lib/common_test/src/ct_rpc.erl21
-rw-r--r--lib/common_test/src/ct_run.erl325
-rw-r--r--lib/common_test/src/ct_slave.erl67
-rw-r--r--lib/common_test/src/ct_snmp.erl37
-rw-r--r--lib/common_test/src/ct_ssh.erl19
-rw-r--r--lib/common_test/src/ct_telnet.erl81
-rw-r--r--lib/common_test/src/ct_telnet_client.erl40
-rw-r--r--lib/common_test/src/ct_testspec.erl169
-rw-r--r--lib/common_test/src/ct_util.erl26
-rw-r--r--lib/common_test/src/ct_util.hrl21
-rw-r--r--lib/common_test/src/ct_webtool.erl19
-rw-r--r--lib/common_test/src/ct_webtool_sup.erl21
-rw-r--r--lib/common_test/src/cth_conn_log.erl21
-rw-r--r--lib/common_test/src/cth_log_redirect.erl46
-rw-r--r--lib/common_test/src/cth_surefire.erl38
-rw-r--r--lib/common_test/src/unix_telnet.erl35
-rw-r--r--lib/common_test/src/vts.erl19
-rw-r--r--lib/common_test/test/Makefile22
-rw-r--r--lib/common_test/test/ct_auto_compile_SUITE.erl67
-rw-r--r--lib/common_test/test/ct_auto_compile_SUITE_data/bad_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_auto_compile_SUITE_data/dummy_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_basic_html_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_basic_html_SUITE_data/babbling_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_config_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl19
-rw-r--r--lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl21
-rw-r--r--lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_config_info_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_config_info_SUITE_data/config_info_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_cover_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE.erl45
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/config_func_error_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl40
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/misc_error_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl24
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_4_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_5_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_6_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_7_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_8_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_utils.erl19
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl21
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl19
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_gen_conn_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE_data/group_require_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE_data/group_require_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE_data/group_require_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_leader_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_group_leader_SUITE_data/group_leader_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_search_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_spec_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_spec_SUITE_data/groups_spec_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_hooks_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl69
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl96
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_prio_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_data_dir_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl115
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl57
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl151
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl21
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl67
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl85
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl155
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl155
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl157
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl151
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl155
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl153
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl175
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl149
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl174
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl269
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl199
-rw-r--r--lib/common_test/test/ct_master_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_misc_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE.erl50
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl461
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl148
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl166
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.hrl14
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/ns.erl73
-rw-r--r--lib/common_test/test/ct_pre_post_test_io_SUITE.erl145
-rw-r--r--lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl27
-rw-r--r--lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_priv_dir_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_priv_dir_SUITE_data/priv_dir_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_release_test_SUITE.erl190
-rw-r--r--lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl118
-rw-r--r--lib/common_test/test/ct_repeat_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_repeat_testrun_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_sequence_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_shell_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_12_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_6_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_7_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_snmp_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_surefire_SUITE.erl128
-rw-r--r--lib/common_test/test/ct_surefire_SUITE_data/fail_SUITE.erl28
-rw-r--r--lib/common_test/test/ct_surefire_SUITE_data/fail_pre_init_per_suite.erl47
-rw-r--r--lib/common_test/test/ct_surefire_SUITE_data/pass_SUITE.erl28
-rw-r--r--lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_system_error_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_system_error_SUITE_data/a_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_telnet_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE.erl44
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_test_support.erl66
-rw-r--r--lib/common_test/test/ct_test_support_eh.erl19
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_testspec_2_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl47
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl46
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_userconfig_callback.erl19
-rw-r--r--lib/common_test/test/ct_verbosity_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_verbosity_SUITE_data/io_test_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl21
-rw-r--r--lib/common_test/test/telnet_server.erl6
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/Makefile21
-rw-r--r--lib/compiler/doc/src/Makefile21
-rw-r--r--lib/compiler/doc/src/book.xml21
-rw-r--r--lib/compiler/doc/src/compile.xml527
-rw-r--r--lib/compiler/doc/src/notes.xml252
-rw-r--r--lib/compiler/doc/src/notes_history.xml21
-rw-r--r--lib/compiler/doc/src/part_notes.xml21
-rw-r--r--lib/compiler/doc/src/part_notes_history.xml19
-rw-r--r--lib/compiler/doc/src/ref_man.xml23
-rw-r--r--lib/compiler/src/Makefile26
-rw-r--r--lib/compiler/src/beam_a.erl26
-rw-r--r--lib/compiler/src/beam_asm.erl71
-rw-r--r--lib/compiler/src/beam_block.erl58
-rw-r--r--lib/compiler/src/beam_bool.erl72
-rw-r--r--lib/compiler/src/beam_bsm.erl48
-rw-r--r--lib/compiler/src/beam_clean.erl54
-rw-r--r--lib/compiler/src/beam_dead.erl748
-rw-r--r--lib/compiler/src/beam_dict.erl101
-rw-r--r--lib/compiler/src/beam_disasm.erl19
-rw-r--r--lib/compiler/src/beam_disasm.hrl21
-rw-r--r--lib/compiler/src/beam_except.erl19
-rw-r--r--lib/compiler/src/beam_flatten.erl22
-rw-r--r--lib/compiler/src/beam_jump.erl150
-rw-r--r--lib/compiler/src/beam_listing.erl34
-rw-r--r--lib/compiler/src/beam_peep.erl34
-rw-r--r--lib/compiler/src/beam_receive.erl19
-rw-r--r--lib/compiler/src/beam_split.erl23
-rw-r--r--lib/compiler/src/beam_trim.erl27
-rw-r--r--lib/compiler/src/beam_type.erl93
-rw-r--r--lib/compiler/src/beam_utils.erl95
-rw-r--r--lib/compiler/src/beam_validator.erl570
-rw-r--r--lib/compiler/src/beam_z.erl40
-rw-r--r--lib/compiler/src/cerl.erl122
-rw-r--r--lib/compiler/src/cerl_clauses.erl65
-rw-r--r--lib/compiler/src/cerl_inline.erl116
-rw-r--r--lib/compiler/src/cerl_sets.erl207
-rw-r--r--lib/compiler/src/cerl_trees.erl29
-rw-r--r--lib/compiler/src/compile.erl154
-rw-r--r--lib/compiler/src/compiler.app.src25
-rw-r--r--lib/compiler/src/compiler.appup.src19
-rw-r--r--lib/compiler/src/core_lib.erl84
-rw-r--r--lib/compiler/src/core_lint.erl125
-rw-r--r--lib/compiler/src/core_parse.hrl24
-rw-r--r--lib/compiler/src/core_parse.yrl119
-rw-r--r--lib/compiler/src/core_pp.erl47
-rw-r--r--lib/compiler/src/core_scan.erl27
-rw-r--r--lib/compiler/src/erl_bifs.erl20
-rwxr-xr-xlib/compiler/src/genop.tab29
-rw-r--r--lib/compiler/src/rec_env.erl21
-rw-r--r--lib/compiler/src/sys_core_dsetel.erl19
-rw-r--r--lib/compiler/src/sys_core_fold.erl1599
-rw-r--r--lib/compiler/src/sys_core_fold_lists.erl387
-rw-r--r--lib/compiler/src/sys_core_inline.erl27
-rw-r--r--lib/compiler/src/sys_pre_attributes.erl21
-rw-r--r--lib/compiler/src/sys_pre_expand.erl89
-rw-r--r--lib/compiler/src/v3_codegen.erl329
-rw-r--r--lib/compiler/src/v3_core.erl795
-rw-r--r--lib/compiler/src/v3_kernel.erl267
-rw-r--r--lib/compiler/src/v3_kernel.hrl23
-rw-r--r--lib/compiler/src/v3_kernel_pp.erl19
-rw-r--r--lib/compiler/src/v3_life.erl205
-rw-r--r--lib/compiler/src/v3_life.hrl21
-rw-r--r--lib/compiler/test/Makefile17
-rw-r--r--lib/compiler/test/andor_SUITE.erl41
-rw-r--r--lib/compiler/test/apply_SUITE.erl21
-rw-r--r--lib/compiler/test/beam_disasm_SUITE.erl19
-rw-r--r--lib/compiler/test/beam_except_SUITE.erl19
-rw-r--r--lib/compiler/test/beam_utils_SUITE.erl237
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl275
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/bad_catch_try.S8
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/bad_dsetel.S6
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/bin_aligned.S47
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/bin_match.S64
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/compiler_bug.S38
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/dead_code.S25
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/erl_prim_loader.beambin17460 -> 0 bytes
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/freg_range.S4
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/freg_state.S2
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S14
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/illegal_instruction.S26
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/map_field_lists.S29
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S3
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/no_exception_in_catch.S4
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/stack.S4
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/state_after_fault_in_catch.S2
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/undef_label.S22
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/uninit.S16
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/unsafe_catch.S8
-rw-r--r--lib/compiler/test/beam_validator_SUITE_data/xrange.S4
-rw-r--r--lib/compiler/test/bs_bincomp_SUITE.erl21
-rw-r--r--lib/compiler/test/bs_bit_binaries_SUITE.erl23
-rw-r--r--lib/compiler/test/bs_construct_SUITE.erl23
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl121
-rw-r--r--lib/compiler/test/bs_shadowed_size_var.core25
-rw-r--r--lib/compiler/test/bs_utf_SUITE.erl19
-rw-r--r--lib/compiler/test/compilation_SUITE.erl89
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_1.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_10.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_11.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_12.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_2.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_3.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_4.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_5.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_6.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_8.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/beam_compiler_9.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/bin_syntax_1.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/bin_syntax_2.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/bin_syntax_3.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/bin_syntax_4.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/bin_syntax_6.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/catch_in_catch.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/compiler_1.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/compiler_3.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/compiler_5.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/complex_guard.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/const_list_256.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/convopts.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/guards.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/live_var.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/long_string.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/nested_tuples_in_case_expr.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/opt_crash.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/other/vsn_1.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/other/vsn_3.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_2141.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_2173.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_2330.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_2380.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_4790.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5076.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5092.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5151.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5235.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5244.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5404.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5436.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5481.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5553.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5632.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5714.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_5872.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_6121.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_6121a.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_6121b.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/otp_7202.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/pattern_expr.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/trycatch_4.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/vsn_1.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/vsn_2.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE_data/vsn_3.erl21
-rw-r--r--lib/compiler/test/compile_SUITE.erl157
-rw-r--r--lib/compiler/test/compile_SUITE_data/attributes.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/bad_record_use.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/bad_record_use2.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/big.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/dialyzer_test.erl40
-rw-r--r--lib/compiler/test/compile_SUITE_data/include/simple.hrl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/missing_testheap1.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/missing_testheap2.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/record_access.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple.erl21
-rw-r--r--lib/compiler/test/compile_SUITE_data/wrong_module_name.erl21
-rw-r--r--lib/compiler/test/core_SUITE.erl35
-rw-r--r--lib/compiler/test/core_SUITE_data/bs_shadowed_size_var.core66
-rw-r--r--lib/compiler/test/core_SUITE_data/map_core_test.core12
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl102
-rw-r--r--lib/compiler/test/core_fold_SUITE_data/nested_call_in_case.core (renamed from lib/compiler/test/nested_call_in_case.core)3
-rw-r--r--lib/compiler/test/core_fold_SUITE_data/unused_multiple_values_error.core (renamed from lib/compiler/test/unused_multiple_values_error.core)0
-rw-r--r--lib/compiler/test/error_SUITE.erl57
-rw-r--r--lib/compiler/test/error_SUITE_data/head_mismatch_line.erl22
-rw-r--r--lib/compiler/test/float_SUITE.erl21
-rw-r--r--lib/compiler/test/fun_SUITE.erl21
-rw-r--r--lib/compiler/test/guard_SUITE.erl374
-rw-r--r--lib/compiler/test/inline_SUITE.erl21
-rw-r--r--lib/compiler/test/inline_SUITE_data/attribute.erl21
-rw-r--r--lib/compiler/test/inline_SUITE_data/bsdecode.erl21
-rw-r--r--lib/compiler/test/inline_SUITE_data/bsdes.erl21
-rw-r--r--lib/compiler/test/inline_SUITE_data/decode1.erl19
-rw-r--r--lib/compiler/test/inline_SUITE_data/fname.erl19
-rw-r--r--lib/compiler/test/inline_SUITE_data/itracer.erl21
-rw-r--r--lib/compiler/test/inline_SUITE_data/maps_inline_test.erl21
-rw-r--r--lib/compiler/test/lc_SUITE.erl121
-rw-r--r--lib/compiler/test/map_SUITE.erl1471
-rw-r--r--lib/compiler/test/match_SUITE.erl51
-rw-r--r--lib/compiler/test/misc_SUITE.erl56
-rw-r--r--lib/compiler/test/num_bif_SUITE.erl19
-rw-r--r--lib/compiler/test/receive_SUITE.erl57
-rw-r--r--lib/compiler/test/record_SUITE.erl27
-rw-r--r--lib/compiler/test/record_SUITE_data/record_access_in_guards.erl21
-rw-r--r--lib/compiler/test/regressions_SUITE.erl98
-rw-r--r--lib/compiler/test/test_lib.erl48
-rw-r--r--lib/compiler/test/trycatch_SUITE.erl41
-rw-r--r--lib/compiler/test/warnings_SUITE.erl151
-rw-r--r--lib/compiler/test/z_SUITE.erl63
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/configure.in.src21
-rw-r--r--lib/cosEvent/Makefile21
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml19
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml19
-rw-r--r--lib/cosEvent/doc/src/Makefile21
-rw-r--r--lib/cosEvent/doc/src/book.xml21
-rw-r--r--lib/cosEvent/doc/src/ch_contents.xml19
-rw-r--r--lib/cosEvent/doc/src/ch_event_service.xml21
-rw-r--r--lib/cosEvent/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosEvent/doc/src/cosEventApp.xml19
-rw-r--r--lib/cosEvent/doc/src/notes.xml39
-rw-r--r--lib/cosEvent/doc/src/part.xml21
-rw-r--r--lib/cosEvent/doc/src/part_notes.xml21
-rw-r--r--lib/cosEvent/doc/src/ref_man.xml21
-rw-r--r--lib/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer_impl.erl21
-rw-r--r--lib/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer_impl.erl21
-rw-r--r--lib/cosEvent/src/CosEventChannelAdmin_SupplierAdmin_impl.erl21
-rw-r--r--lib/cosEvent/src/Makefile21
-rw-r--r--lib/cosEvent/src/cosEvent.app.src2
-rw-r--r--lib/cosEvent/src/cosEventApp.erl21
-rw-r--r--lib/cosEvent/src/cosEventApp.hrl21
-rw-r--r--lib/cosEvent/src/oe_CosEventComm_CAdmin_impl.erl21
-rw-r--r--lib/cosEvent/src/oe_CosEventComm_Channel_impl.erl21
-rw-r--r--lib/cosEvent/src/oe_CosEventComm_PullerS_impl.erl26
-rw-r--r--lib/cosEvent/src/oe_CosEventComm_PusherS_impl.erl21
-rw-r--r--lib/cosEvent/test/Makefile21
-rw-r--r--lib/cosEvent/test/event_channel_SUITE.erl21
-rw-r--r--lib/cosEvent/test/event_test_PullC_impl.erl21
-rw-r--r--lib/cosEvent/test/event_test_PullS_impl.erl21
-rw-r--r--lib/cosEvent/test/event_test_PushC_impl.erl21
-rw-r--r--lib/cosEvent/test/event_test_PushS_impl.erl21
-rw-r--r--lib/cosEvent/test/event_test_server.idl19
-rw-r--r--lib/cosEvent/test/generated_SUITE.erl21
-rw-r--r--lib/cosEvent/vsn.mk3
-rw-r--r--lib/cosEventDomain/Makefile21
-rw-r--r--lib/cosEventDomain/doc/src/CosEventDomainAdmin.xml19
-rw-r--r--lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml21
-rw-r--r--lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml19
-rw-r--r--lib/cosEventDomain/doc/src/Makefile21
-rw-r--r--lib/cosEventDomain/doc/src/book.xml21
-rw-r--r--lib/cosEventDomain/doc/src/ch_QoS.xml21
-rw-r--r--lib/cosEventDomain/doc/src/ch_contents.xml21
-rw-r--r--lib/cosEventDomain/doc/src/ch_event_domain_service.xml21
-rw-r--r--lib/cosEventDomain/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosEventDomain/doc/src/cosEventDomainApp.xml19
-rw-r--r--lib/cosEventDomain/doc/src/notes.xml39
-rw-r--r--lib/cosEventDomain/doc/src/part.xml21
-rw-r--r--lib/cosEventDomain/doc/src/part_notes.xml21
-rw-r--r--lib/cosEventDomain/doc/src/ref_man.xml21
-rw-r--r--lib/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory_impl.erl21
-rw-r--r--lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl21
-rw-r--r--lib/cosEventDomain/src/Makefile21
-rw-r--r--lib/cosEventDomain/src/cosEventDomain.app.src2
-rw-r--r--lib/cosEventDomain/src/cosEventDomainApp.erl55
-rw-r--r--lib/cosEventDomain/src/cosEventDomainApp.hrl21
-rw-r--r--lib/cosEventDomain/test/Makefile21
-rw-r--r--lib/cosEventDomain/test/event_domain_SUITE.erl21
-rw-r--r--lib/cosEventDomain/test/generated_SUITE.erl21
-rw-r--r--lib/cosEventDomain/vsn.mk3
-rw-r--r--lib/cosFileTransfer/Makefile21
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml19
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml19
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml19
-rw-r--r--lib/cosFileTransfer/doc/src/Makefile21
-rw-r--r--lib/cosFileTransfer/doc/src/book.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/ch_contents.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/ch_example.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/ch_install.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/ch_system.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/cosFileTransferApp.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/notes.xml39
-rw-r--r--lib/cosFileTransfer/doc/src/part.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/part_notes.xml21
-rw-r--r--lib/cosFileTransfer/doc/src/ref_man.xml21
-rw-r--r--lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl21
-rw-r--r--lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl21
-rw-r--r--lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl21
-rw-r--r--lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl21
-rw-r--r--lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl21
-rw-r--r--lib/cosFileTransfer/src/Makefile21
-rw-r--r--lib/cosFileTransfer/src/cosFileTransfer.app.src2
-rw-r--r--lib/cosFileTransfer/src/cosFileTransferApp.erl28
-rw-r--r--lib/cosFileTransfer/src/cosFileTransferApp.hrl21
-rw-r--r--lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl21
-rw-r--r--lib/cosFileTransfer/test/Makefile21
-rw-r--r--lib/cosFileTransfer/test/fileTransfer_SUITE.erl26
-rw-r--r--lib/cosFileTransfer/vsn.mk2
-rw-r--r--lib/cosNotification/Makefile21
-rw-r--r--lib/cosNotification/doc/src/CosNotification.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml21
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml21
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml21
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml21
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml21
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml19
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml21
-rw-r--r--lib/cosNotification/doc/src/Makefile21
-rw-r--r--lib/cosNotification/doc/src/book.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_BNF.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_QoS.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_contents.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_example.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_install.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosNotification/doc/src/ch_system.xml21
-rw-r--r--lib/cosNotification/doc/src/cosNotificationApp.xml21
-rw-r--r--lib/cosNotification/doc/src/notes.xml53
-rw-r--r--lib/cosNotification/doc/src/part.xml21
-rw-r--r--lib/cosNotification/doc/src/part_notes.xml21
-rw-r--r--lib/cosNotification/doc/src/ref_man.xml21
-rw-r--r--lib/cosNotification/src/CosNotification_Common.erl68
-rw-r--r--lib/cosNotification/src/CosNotification_Definitions.hrl25
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl21
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl21
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl21
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl21
-rw-r--r--lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl21
-rw-r--r--lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl24
-rw-r--r--lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl24
-rw-r--r--lib/cosNotification/src/Makefile21
-rw-r--r--lib/cosNotification/src/PullerConsumer_impl.erl21
-rw-r--r--lib/cosNotification/src/PullerSupplier_impl.erl25
-rw-r--r--lib/cosNotification/src/PusherConsumer_impl.erl21
-rw-r--r--lib/cosNotification/src/PusherSupplier_impl.erl21
-rw-r--r--lib/cosNotification/src/cosNotification.app.src2
-rw-r--r--lib/cosNotification/src/cosNotificationApp.erl37
-rw-r--r--lib/cosNotification/src/cosNotification_Filter.erl21
-rw-r--r--lib/cosNotification/src/cosNotification_Grammar.yrl42
-rw-r--r--lib/cosNotification/src/cosNotification_Scanner.erl21
-rw-r--r--lib/cosNotification/src/cosNotification_eventDB.erl53
-rw-r--r--lib/cosNotification/test/Makefile21
-rw-r--r--lib/cosNotification/test/eventDB_SUITE.erl21
-rw-r--r--lib/cosNotification/test/generated_SUITE.erl21
-rw-r--r--lib/cosNotification/test/grammar_SUITE.erl21
-rw-r--r--lib/cosNotification/test/notification_SUITE.erl21
-rw-r--r--lib/cosNotification/test/notify_test_impl.erl25
-rw-r--r--lib/cosNotification/test/notify_test_server.cfg19
-rw-r--r--lib/cosNotification/test/notify_test_server.idl19
-rw-r--r--lib/cosNotification/vsn.mk2
-rw-r--r--lib/cosProperty/Makefile21
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml21
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml19
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml19
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml21
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml19
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml19
-rw-r--r--lib/cosProperty/doc/src/Makefile21
-rw-r--r--lib/cosProperty/doc/src/book.xml21
-rw-r--r--lib/cosProperty/doc/src/ch_contents.xml21
-rw-r--r--lib/cosProperty/doc/src/ch_example.xml21
-rw-r--r--lib/cosProperty/doc/src/ch_install.xml21
-rw-r--r--lib/cosProperty/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosProperty/doc/src/cosProperty.xml21
-rw-r--r--lib/cosProperty/doc/src/notes.xml39
-rw-r--r--lib/cosProperty/doc/src/part.xml21
-rw-r--r--lib/cosProperty/doc/src/part_notes.xml21
-rw-r--r--lib/cosProperty/doc/src/ref_man.xml21
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl21
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl21
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl21
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl27
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl21
-rw-r--r--lib/cosProperty/src/Makefile21
-rw-r--r--lib/cosProperty/src/cosProperty.app.src2
-rw-r--r--lib/cosProperty/src/cosProperty.erl28
-rw-r--r--lib/cosProperty/src/cosProperty.hrl21
-rw-r--r--lib/cosProperty/test/Makefile21
-rw-r--r--lib/cosProperty/test/generated_SUITE.erl21
-rw-r--r--lib/cosProperty/test/property_SUITE.erl21
-rw-r--r--lib/cosProperty/vsn.mk2
-rw-r--r--lib/cosTime/Makefile21
-rw-r--r--lib/cosTime/doc/src/CosTime_TIO.xml19
-rw-r--r--lib/cosTime/doc/src/CosTime_TimeService.xml19
-rw-r--r--lib/cosTime/doc/src/CosTime_UTO.xml19
-rw-r--r--lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml19
-rw-r--r--lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml19
-rw-r--r--lib/cosTime/doc/src/Makefile21
-rw-r--r--lib/cosTime/doc/src/book.xml21
-rw-r--r--lib/cosTime/doc/src/ch_contents.xml21
-rw-r--r--lib/cosTime/doc/src/ch_example.xml21
-rw-r--r--lib/cosTime/doc/src/ch_install.xml21
-rw-r--r--lib/cosTime/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosTime/doc/src/cosTime.xml19
-rw-r--r--lib/cosTime/doc/src/notes.xml53
-rw-r--r--lib/cosTime/doc/src/part.xml21
-rw-r--r--lib/cosTime/doc/src/part_notes.xml21
-rw-r--r--lib/cosTime/doc/src/ref_man.xml21
-rw-r--r--lib/cosTime/src/CosTime_TIO_impl.erl21
-rw-r--r--lib/cosTime/src/CosTime_TimeService_impl.erl26
-rw-r--r--lib/cosTime/src/CosTime_UTO_impl.erl21
-rw-r--r--lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl21
-rw-r--r--lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl21
-rw-r--r--lib/cosTime/src/Makefile21
-rw-r--r--lib/cosTime/src/cosTime.app.src2
-rw-r--r--lib/cosTime/src/cosTime.erl26
-rw-r--r--lib/cosTime/src/cosTimeApp.hrl23
-rw-r--r--lib/cosTime/test/Makefile21
-rw-r--r--lib/cosTime/test/generated_SUITE.erl21
-rw-r--r--lib/cosTime/test/time_SUITE.erl21
-rw-r--r--lib/cosTime/vsn.mk3
-rw-r--r--lib/cosTransactions/Makefile21
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_Control.xml19
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_Coordinator.xml21
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml21
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_Resource.xml21
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml21
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_Synchronization.xml19
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_Terminator.xml19
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml19
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_TransactionalObject.xml21
-rw-r--r--lib/cosTransactions/doc/src/Makefile21
-rw-r--r--lib/cosTransactions/doc/src/book.xml21
-rw-r--r--lib/cosTransactions/doc/src/ch_contents.xml21
-rw-r--r--lib/cosTransactions/doc/src/ch_example.xml21
-rw-r--r--lib/cosTransactions/doc/src/ch_install.xml21
-rw-r--r--lib/cosTransactions/doc/src/ch_introduction.xml21
-rw-r--r--lib/cosTransactions/doc/src/ch_skeletons.xml21
-rw-r--r--lib/cosTransactions/doc/src/cosTransactions.xml19
-rw-r--r--lib/cosTransactions/doc/src/notes.xml53
-rw-r--r--lib/cosTransactions/doc/src/part.xml21
-rw-r--r--lib/cosTransactions/doc/src/part_notes.xml21
-rw-r--r--lib/cosTransactions/doc/src/ref_man.xml21
-rw-r--r--lib/cosTransactions/examples/Makefile21
-rw-r--r--lib/cosTransactions/src/CosTransactions_Terminator_impl.erl21
-rw-r--r--lib/cosTransactions/src/CosTransactions_TransactionFactory_impl.erl28
-rw-r--r--lib/cosTransactions/src/ETraP_Common.erl38
-rw-r--r--lib/cosTransactions/src/ETraP_Common.hrl19
-rw-r--r--lib/cosTransactions/src/ETraP_Server_impl.erl30
-rw-r--r--lib/cosTransactions/src/Makefile21
-rw-r--r--lib/cosTransactions/src/cosTransactions.app.src2
-rw-r--r--lib/cosTransactions/src/cosTransactions.erl21
-rw-r--r--lib/cosTransactions/src/etrap_logmgr.erl21
-rw-r--r--lib/cosTransactions/test/Makefile21
-rw-r--r--lib/cosTransactions/test/etrap_test.cfg19
-rw-r--r--lib/cosTransactions/test/etrap_test.idl19
-rw-r--r--lib/cosTransactions/test/etrap_test_lib.erl21
-rw-r--r--lib/cosTransactions/test/etrap_test_lib.hrl21
-rw-r--r--lib/cosTransactions/test/etrap_test_server_impl.erl19
-rw-r--r--lib/cosTransactions/test/generated_SUITE.erl21
-rw-r--r--lib/cosTransactions/test/transactions_SUITE.erl21
-rw-r--r--lib/cosTransactions/vsn.mk2
-rw-r--r--lib/crypto/Makefile21
-rw-r--r--lib/crypto/c_src/Makefile.in19
-rw-r--r--lib/crypto/c_src/crypto.c436
-rw-r--r--lib/crypto/c_src/crypto_callback.c19
-rw-r--r--lib/crypto/c_src/crypto_callback.h19
-rw-r--r--lib/crypto/doc/src/Makefile21
-rw-r--r--lib/crypto/doc/src/book.xml21
-rw-r--r--lib/crypto/doc/src/crypto.xml181
-rw-r--r--lib/crypto/doc/src/crypto_app.xml21
-rw-r--r--lib/crypto/doc/src/licenses.xml21
-rw-r--r--lib/crypto/doc/src/notes.xml118
-rw-r--r--lib/crypto/doc/src/ref_man.xml21
-rw-r--r--lib/crypto/doc/src/release_notes.xml19
-rw-r--r--lib/crypto/doc/src/usersguide.xml21
-rw-r--r--lib/crypto/priv/Makefile21
-rw-r--r--lib/crypto/src/Makefile19
-rw-r--r--lib/crypto/src/crypto.app.src19
-rw-r--r--lib/crypto/src/crypto.appup.src21
-rw-r--r--lib/crypto/src/crypto.erl95
-rw-r--r--lib/crypto/src/crypto_ec_curves.erl12
-rw-r--r--lib/crypto/test/blowfish_SUITE.erl19
-rw-r--r--lib/crypto/test/crypto_SUITE.erl661
-rw-r--r--lib/crypto/test/old_crypto_SUITE.erl63
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/Makefile21
-rw-r--r--lib/debugger/doc/src/Makefile21
-rw-r--r--lib/debugger/doc/src/book.xml22
-rw-r--r--lib/debugger/doc/src/debugger.xml47
-rw-r--r--lib/debugger/doc/src/debugger_chapter.xml879
-rw-r--r--lib/debugger/doc/src/i.xml159
-rw-r--r--lib/debugger/doc/src/int.xml355
-rw-r--r--lib/debugger/doc/src/introduction.xml63
-rw-r--r--lib/debugger/doc/src/notes.xml70
-rw-r--r--lib/debugger/doc/src/part.xml33
-rw-r--r--lib/debugger/doc/src/ref_man.xml28
-rw-r--r--lib/debugger/priv/Makefile21
-rw-r--r--lib/debugger/src/Makefile21
-rw-r--r--lib/debugger/src/dbg_debugged.erl22
-rw-r--r--lib/debugger/src/dbg_icmd.erl27
-rw-r--r--lib/debugger/src/dbg_idb.erl21
-rw-r--r--lib/debugger/src/dbg_ieval.erl75
-rw-r--r--lib/debugger/src/dbg_ieval.hrl25
-rw-r--r--lib/debugger/src/dbg_iload.erl400
-rw-r--r--lib/debugger/src/dbg_iserver.erl21
-rw-r--r--lib/debugger/src/dbg_istk.erl19
-rw-r--r--lib/debugger/src/dbg_wx_break.erl21
-rw-r--r--lib/debugger/src/dbg_wx_break_win.erl21
-rw-r--r--lib/debugger/src/dbg_wx_code.erl21
-rw-r--r--lib/debugger/src/dbg_wx_filedialog_win.erl19
-rw-r--r--lib/debugger/src/dbg_wx_filedialog_win.hrl21
-rw-r--r--lib/debugger/src/dbg_wx_interpret.erl21
-rw-r--r--lib/debugger/src/dbg_wx_mon.erl19
-rw-r--r--lib/debugger/src/dbg_wx_mon_win.erl19
-rw-r--r--lib/debugger/src/dbg_wx_settings.erl21
-rw-r--r--lib/debugger/src/dbg_wx_src_view.erl21
-rw-r--r--lib/debugger/src/dbg_wx_trace.erl31
-rw-r--r--lib/debugger/src/dbg_wx_trace_win.erl19
-rw-r--r--lib/debugger/src/dbg_wx_view.erl21
-rw-r--r--lib/debugger/src/dbg_wx_win.erl19
-rw-r--r--lib/debugger/src/dbg_wx_winman.erl21
-rw-r--r--lib/debugger/src/debugger.app.src25
-rw-r--r--lib/debugger/src/debugger.appup.src21
-rw-r--r--lib/debugger/src/debugger.erl21
-rw-r--r--lib/debugger/src/i.erl21
-rw-r--r--lib/debugger/src/int.erl25
-rw-r--r--lib/debugger/test/Makefile19
-rw-r--r--lib/debugger/test/andor_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_bincomp_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_construct_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_match_bin_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_match_int_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_match_misc_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_match_tail_SUITE.erl19
-rw-r--r--lib/debugger/test/bs_utf_SUITE.erl19
-rw-r--r--lib/debugger/test/bug_SUITE.erl19
-rw-r--r--lib/debugger/test/bug_SUITE_data/Makefile.src19
-rw-r--r--lib/debugger/test/bug_SUITE_data/otp2163.erl21
-rw-r--r--lib/debugger/test/bug_SUITE_data/otp4845.erl21
-rw-r--r--lib/debugger/test/cleanup.erl21
-rw-r--r--lib/debugger/test/dbg_ui_SUITE.erl19
-rw-r--r--lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl19
-rw-r--r--lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl20
-rw-r--r--lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl19
-rw-r--r--lib/debugger/test/debugger_SUITE.erl19
-rw-r--r--lib/debugger/test/debugger_test.erl19
-rw-r--r--lib/debugger/test/erl_eval_SUITE.erl19
-rw-r--r--lib/debugger/test/exception_SUITE.erl20
-rw-r--r--lib/debugger/test/fun_SUITE.erl19
-rw-r--r--lib/debugger/test/guard_SUITE.erl19
-rw-r--r--lib/debugger/test/int_SUITE.erl19
-rw-r--r--lib/debugger/test/int_SUITE_data/Makefile.src19
-rw-r--r--lib/debugger/test/int_SUITE_data/guards.erl19
-rw-r--r--lib/debugger/test/int_SUITE_data/lists1.erl19
-rw-r--r--lib/debugger/test/int_SUITE_data/my_lists.erl19
-rw-r--r--lib/debugger/test/int_SUITE_data/ordsets1.erl20
-rw-r--r--lib/debugger/test/int_SUITE_data/test.erl19
-rw-r--r--lib/debugger/test/int_SUITE_data/test1.erl21
-rw-r--r--lib/debugger/test/int_break_SUITE.erl20
-rw-r--r--lib/debugger/test/int_break_SUITE_data/Makefile.src19
-rw-r--r--lib/debugger/test/int_break_SUITE_data/ordsets1.erl20
-rw-r--r--lib/debugger/test/int_eval_SUITE.erl21
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/Makefile.src19
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl19
-rw-r--r--lib/debugger/test/lc_SUITE.erl19
-rw-r--r--lib/debugger/test/line_number_SUITE.erl20
-rw-r--r--lib/debugger/test/map_SUITE.erl1787
-rw-r--r--lib/debugger/test/record_SUITE.erl19
-rw-r--r--lib/debugger/test/test_lib.erl19
-rw-r--r--lib/debugger/test/trycatch_SUITE.erl19
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/Makefile21
-rw-r--r--lib/dialyzer/doc/src/Makefile21
-rw-r--r--lib/dialyzer/doc/src/book.xml21
-rw-r--r--lib/dialyzer/doc/src/dialyzer.xml117
-rw-r--r--lib/dialyzer/doc/src/dialyzer_chapter.xml21
-rw-r--r--lib/dialyzer/doc/src/notes.xml294
-rw-r--r--lib/dialyzer/doc/src/part.xml21
-rw-r--r--lib/dialyzer/doc/src/part_notes.xml21
-rw-r--r--lib/dialyzer/doc/src/ref_man.xml21
-rw-r--r--lib/dialyzer/src/Makefile19
-rw-r--r--lib/dialyzer/src/dialyzer.app.src25
-rw-r--r--lib/dialyzer/src/dialyzer.appup.src21
-rw-r--r--lib/dialyzer/src/dialyzer.erl66
-rw-r--r--lib/dialyzer/src/dialyzer.hrl31
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl229
-rw-r--r--lib/dialyzer/src/dialyzer_behaviours.erl47
-rw-r--r--lib/dialyzer/src/dialyzer_callgraph.erl46
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl195
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl40
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl55
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl189
-rw-r--r--lib/dialyzer/src/dialyzer_coordinator.erl19
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl179
-rw-r--r--lib/dialyzer/src/dialyzer_dep.erl19
-rw-r--r--lib/dialyzer/src/dialyzer_explanation.erl21
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.erl19
-rw-r--r--lib/dialyzer/src/dialyzer_options.erl71
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl29
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl36
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl72
-rw-r--r--lib/dialyzer/src/dialyzer_timing.erl29
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl33
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl486
-rw-r--r--lib/dialyzer/src/dialyzer_worker.erl19
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return2
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/src/custom_sup.erl2
-rw-r--r--lib/dialyzer/test/dialyzer_SUITE.erl60
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/para16
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/simple8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/big_external_type.erl526
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/big_local_type.erl523
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_macros.hrl215
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.erl607
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.hrl26
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_digraph.erl20
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_erl_scan.erl19
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue.erl17
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue_params.erl15
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para4.erl134
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para4_adt.erl108
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para5.erl33
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para5_adt.erl36
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_common.hrl55
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_gen.erl624
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_internal.hrl92
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_types.erl1349
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl2401
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl8
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/my_include/erl_bits.hrl18
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/my_include/erl_compile.hrl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_asm.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_block.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_bool.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_dict.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_flatten.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_jump.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_listing.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl.erl21
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_clauses.erl21
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_trees.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lib.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lint.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.hrl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/core_pp.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/erl_bifs.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_expand_pmod.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_attributes.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl20
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.hrl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel_pp.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.erl19
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.hrl19
-rw-r--r--lib/dialyzer/test/options2_SUITE_data/src/kernel/global.erl19
-rw-r--r--lib/dialyzer/test/plt_SUITE.erl250
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_db.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_records.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_per.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber_bin_v2.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per_rt2ct.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_name.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser.yrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_pretty_format.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_tok.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_value.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_check.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_driver_handler.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_v1.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_history.sgml19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_latest.sgml19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/Makefile19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/http.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_handler.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_conf.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_example.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_misc_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_request_handler.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_socket.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_sup.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_util.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/inets_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_actions.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_alias.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_dets.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_plain.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_server.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_browser.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_dir.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_disk_log.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_get.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_head.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_include.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_log.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security_server.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_trace.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/uri.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/Makefile19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.hrl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_backup.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_controller.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_dumper.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_event.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_hash.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_old_hash.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_index.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_kernel_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_late_loader.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_lib.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_log.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_recover.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_registry.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_hook.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sp.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_subscr.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl19
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_text.erl20
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1_suppressed.erl19
-rw-r--r--lib/dialyzer/test/small_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/abs9
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/behaviour_info2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/comparisons228
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes36
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_arity37
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/maps14
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/maps_sum4
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/non_existing1
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/request12
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/suppress_request6
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/abs.erl71
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_bad_format_status.erl12
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_format_status.erl13
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/big_external_type.erl529
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/big_local_type.erl526
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/blame_contract_range_suppressed.erl15
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comparisons.erl56
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl12
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/ditrap.erl47
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl127
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/gs_make.erl19
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/inv_mult.erl15
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/keydel.erl29
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/maps1.erl46
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/maps_sum.erl31
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/predef2.erl56
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/remote_field.erl2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/request1.erl12
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/suppress_request.erl50
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/suppression1.erl33
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/suppression2.erl32
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/suppression3.erl17
-rw-r--r--lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/user_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/diameter/Makefile19
-rwxr-xr-xlib/diameter/bin/diameterc19
-rw-r--r--lib/diameter/doc/src/Makefile19
-rw-r--r--lib/diameter/doc/src/book.xml21
-rw-r--r--lib/diameter/doc/src/depend.sed21
-rw-r--r--lib/diameter/doc/src/diameter.xml98
-rw-r--r--lib/diameter/doc/src/diameter_app.xml21
-rw-r--r--lib/diameter/doc/src/diameter_codec.xml21
-rw-r--r--lib/diameter/doc/src/diameter_dict.xml21
-rw-r--r--lib/diameter/doc/src/diameter_examples.xml21
-rw-r--r--lib/diameter/doc/src/diameter_intro.xml19
-rw-r--r--lib/diameter/doc/src/diameter_make.xml21
-rw-r--r--lib/diameter/doc/src/diameter_sctp.xml21
-rw-r--r--lib/diameter/doc/src/diameter_soc.xml21
-rw-r--r--lib/diameter/doc/src/diameter_soc_rfc6733.xml21
-rw-r--r--lib/diameter/doc/src/diameter_tcp.xml21
-rw-r--r--lib/diameter/doc/src/diameter_transport.xml21
-rw-r--r--lib/diameter/doc/src/diameter_using.xml21
-rw-r--r--lib/diameter/doc/src/files.mk19
-rw-r--r--lib/diameter/doc/src/notes.xml266
-rw-r--r--lib/diameter/doc/src/ref_man.xml21
-rw-r--r--lib/diameter/doc/src/seealso.ent21
-rw-r--r--lib/diameter/doc/src/seehere.sed21
-rw-r--r--lib/diameter/doc/src/user_man.xml21
-rw-r--r--lib/diameter/examples/code/GNUmakefile19
-rw-r--r--lib/diameter/examples/code/client.erl19
-rw-r--r--lib/diameter/examples/code/client_cb.erl19
-rw-r--r--lib/diameter/examples/code/node.erl19
-rw-r--r--lib/diameter/examples/code/redirect.erl19
-rw-r--r--lib/diameter/examples/code/redirect_cb.erl19
-rw-r--r--lib/diameter/examples/code/relay.erl19
-rw-r--r--lib/diameter/examples/code/relay_cb.erl19
-rw-r--r--lib/diameter/examples/code/sctp.erl19
-rw-r--r--lib/diameter/examples/code/server.erl19
-rw-r--r--lib/diameter/examples/code/server_cb.erl19
-rw-r--r--lib/diameter/examples/dict/GNUmakefile21
-rw-r--r--lib/diameter/examples/dict/depend.sed21
-rw-r--r--lib/diameter/examples/dict/rfc4004_mip.dia19
-rw-r--r--lib/diameter/examples/dict/rfc4005_nas.dia19
-rw-r--r--lib/diameter/examples/dict/rfc4006_cc.dia19
-rw-r--r--lib/diameter/examples/dict/rfc4072_eap.dia19
-rw-r--r--lib/diameter/examples/dict/rfc4590_digest.dia21
-rw-r--r--lib/diameter/examples/dict/rfc4740_sip.dia19
-rw-r--r--lib/diameter/include/diameter.hrl21
-rw-r--r--lib/diameter/include/diameter_gen.hrl175
-rw-r--r--lib/diameter/src/Makefile19
-rw-r--r--lib/diameter/src/app.sed21
-rw-r--r--lib/diameter/src/base/diameter.erl20
-rw-r--r--lib/diameter/src/base/diameter_app.erl19
-rw-r--r--lib/diameter/src/base/diameter_callback.erl21
-rw-r--r--lib/diameter/src/base/diameter_capx.erl19
-rw-r--r--lib/diameter/src/base/diameter_codec.erl53
-rw-r--r--lib/diameter/src/base/diameter_config.erl27
-rw-r--r--lib/diameter/src/base/diameter_dict.erl19
-rw-r--r--lib/diameter/src/base/diameter_internal.hrl19
-rw-r--r--lib/diameter/src/base/diameter_lib.erl82
-rw-r--r--lib/diameter/src/base/diameter_misc_sup.erl21
-rw-r--r--lib/diameter/src/base/diameter_peer.erl37
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl57
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm_sup.erl21
-rw-r--r--lib/diameter/src/base/diameter_reg.erl24
-rw-r--r--lib/diameter/src/base/diameter_service.erl552
-rw-r--r--lib/diameter/src/base/diameter_service_sup.erl19
-rw-r--r--lib/diameter/src/base/diameter_session.erl21
-rw-r--r--lib/diameter/src/base/diameter_stats.erl37
-rw-r--r--lib/diameter/src/base/diameter_sup.erl19
-rw-r--r--lib/diameter/src/base/diameter_sync.erl24
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl124
-rw-r--r--lib/diameter/src/base/diameter_types.erl21
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl79
-rw-r--r--lib/diameter/src/base/diameter_watchdog_sup.erl21
-rw-r--r--lib/diameter/src/compiler/diameter_codegen.erl23
-rw-r--r--lib/diameter/src/compiler/diameter_dict_parser.yrl19
-rw-r--r--lib/diameter/src/compiler/diameter_dict_scanner.erl19
-rw-r--r--lib/diameter/src/compiler/diameter_dict_util.erl19
-rw-r--r--lib/diameter/src/compiler/diameter_exprecs.erl19
-rw-r--r--lib/diameter/src/compiler/diameter_forms.hrl33
-rw-r--r--lib/diameter/src/compiler/diameter_make.erl19
-rw-r--r--lib/diameter/src/compiler/diameter_vsn.hrl19
-rw-r--r--lib/diameter/src/depend.sed21
-rw-r--r--lib/diameter/src/diameter.app.src19
-rw-r--r--lib/diameter/src/diameter.appup.src115
-rw-r--r--lib/diameter/src/dict/acct_rfc6733.dia19
-rw-r--r--lib/diameter/src/dict/base_accounting.dia19
-rw-r--r--lib/diameter/src/dict/base_rfc3588.dia19
-rw-r--r--lib/diameter/src/dict/base_rfc6733.dia19
-rw-r--r--lib/diameter/src/dict/capup_rfc6737.dia19
-rw-r--r--lib/diameter/src/dict/relay.dia19
-rw-r--r--lib/diameter/src/info/diameter_dbg.erl19
-rw-r--r--lib/diameter/src/info/diameter_info.erl26
-rw-r--r--lib/diameter/src/modules.mk19
-rw-r--r--lib/diameter/src/transport/diameter_etcp.erl19
-rw-r--r--lib/diameter/src/transport/diameter_etcp_sup.erl19
-rw-r--r--lib/diameter/src/transport/diameter_sctp.erl353
-rw-r--r--lib/diameter/src/transport/diameter_sctp_sup.erl19
-rw-r--r--lib/diameter/src/transport/diameter_tcp.erl19
-rw-r--r--lib/diameter/src/transport/diameter_tcp_sup.erl19
-rw-r--r--lib/diameter/src/transport/diameter_transport.erl21
-rw-r--r--lib/diameter/src/transport/diameter_transport_sup.erl19
-rw-r--r--lib/diameter/subdirs.mk19
-rw-r--r--lib/diameter/test/Makefile19
-rw-r--r--lib/diameter/test/coverspec.sed21
-rw-r--r--lib/diameter/test/depend.sed21
-rw-r--r--lib/diameter/test/diameter_3xxx_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_app_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_capx_SUITE.erl31
-rw-r--r--lib/diameter/test/diameter_codec_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_codec_SUITE_data/avps.dia19
-rw-r--r--lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl19
-rw-r--r--lib/diameter/test/diameter_codec_SUITE_data/recv.dia19
-rw-r--r--lib/diameter/test/diameter_codec_SUITE_data/send.dia19
-rw-r--r--lib/diameter/test/diameter_codec_test.erl19
-rw-r--r--lib/diameter/test/diameter_compiler_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_config_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_ct.erl21
-rw-r--r--lib/diameter/test/diameter_ct.hrl19
-rw-r--r--lib/diameter/test/diameter_dict_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_distribution_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_dpr_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_enum.erl21
-rw-r--r--lib/diameter/test/diameter_event_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_examples_SUITE.erl21
-rw-r--r--lib/diameter/test/diameter_failover_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_gen_sctp_SUITE.erl34
-rw-r--r--lib/diameter/test/diameter_gen_tcp_SUITE.erl21
-rw-r--r--lib/diameter/test/diameter_length_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_pool_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_reg_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_relay_SUITE.erl63
-rw-r--r--lib/diameter/test/diameter_stats_SUITE.erl25
-rw-r--r--lib/diameter/test/diameter_sync_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_tls_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_tls_SUITE_data/Makefile.ca19
-rw-r--r--lib/diameter/test/diameter_traffic_SUITE.erl97
-rw-r--r--lib/diameter/test/diameter_transport_SUITE.erl24
-rw-r--r--lib/diameter/test/diameter_util.erl71
-rw-r--r--lib/diameter/test/diameter_watchdog_SUITE.erl26
-rw-r--r--lib/diameter/test/modules.mk19
-rw-r--r--lib/diameter/test/release.sed21
-rw-r--r--lib/diameter/vsn.mk21
-rw-r--r--lib/edoc/Makefile21
-rw-r--r--lib/edoc/doc/Makefile21
-rw-r--r--lib/edoc/doc/overview.edoc32
-rw-r--r--lib/edoc/doc/src/Makefile21
-rw-r--r--lib/edoc/doc/src/book.xml21
-rw-r--r--lib/edoc/doc/src/notes.xml63
-rw-r--r--lib/edoc/doc/src/part.xml21
-rw-r--r--lib/edoc/doc/src/part_notes.xml21
-rw-r--r--lib/edoc/doc/src/ref_man.xml21
-rw-r--r--lib/edoc/include/Makefile21
-rw-r--r--lib/edoc/include/edoc_doclet.hrl11
-rw-r--r--lib/edoc/priv/edoc.dtd9
-rw-r--r--lib/edoc/priv/edoc_generate.src21
-rw-r--r--lib/edoc/priv/stylesheet.css4
-rw-r--r--lib/edoc/src/edoc.app.src2
-rw-r--r--lib/edoc/src/edoc.appup.src19
-rw-r--r--lib/edoc/src/edoc.erl195
-rw-r--r--lib/edoc/src/edoc.hrl7
-rw-r--r--lib/edoc/src/edoc_data.erl70
-rw-r--r--lib/edoc/src/edoc_doclet.erl106
-rw-r--r--lib/edoc/src/edoc_extract.erl25
-rw-r--r--lib/edoc/src/edoc_layout.erl71
-rw-r--r--lib/edoc/src/edoc_lib.erl171
-rw-r--r--lib/edoc/src/edoc_macros.erl6
-rw-r--r--lib/edoc/src/edoc_parser.yrl14
-rw-r--r--lib/edoc/src/edoc_refs.erl72
-rw-r--r--lib/edoc/src/edoc_run.erl30
-rw-r--r--lib/edoc/src/edoc_scanner.erl17
-rw-r--r--lib/edoc/src/edoc_specs.erl211
-rw-r--r--lib/edoc/src/edoc_tags.erl30
-rw-r--r--lib/edoc/src/edoc_types.erl61
-rw-r--r--lib/edoc/src/otpsgml_layout.erl24
-rw-r--r--lib/edoc/test/edoc_SUITE.erl42
-rw-r--r--lib/edoc/test/edoc_SUITE_data/myapp/doc/.dummy (renamed from lib/common_test/priv/bin/.gitignore)0
-rw-r--r--lib/edoc/test/edoc_SUITE_data/myapp/src/a.erl1
-rw-r--r--lib/edoc/test/edoc_SUITE_data/myapp/src/src_1/b.erl1
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/eldap/Makefile21
-rw-r--r--lib/eldap/asn1/ELDAPv3.asn112
-rw-r--r--lib/eldap/doc/src/Makefile21
-rw-r--r--lib/eldap/doc/src/book.xml21
-rw-r--r--lib/eldap/doc/src/eldap.xml165
-rw-r--r--lib/eldap/doc/src/notes.xml68
-rw-r--r--lib/eldap/doc/src/ref_man.xml21
-rw-r--r--lib/eldap/doc/src/release_notes.xml19
-rw-r--r--lib/eldap/doc/src/usersguide.xml19
-rw-r--r--lib/eldap/src/Makefile19
-rw-r--r--lib/eldap/src/eldap.appup.src19
-rw-r--r--lib/eldap/src/eldap.erl314
-rw-r--r--lib/eldap/test/Makefile19
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl121
-rw-r--r--lib/eldap/test/make_certs.erl21
-rw-r--r--lib/eldap/vsn.mk2
-rw-r--r--lib/erl_docgen/Makefile21
-rw-r--r--lib/erl_docgen/doc/src/Makefile19
-rw-r--r--lib/erl_docgen/doc/src/block_tags.xml21
-rw-r--r--lib/erl_docgen/doc/src/book.xml21
-rw-r--r--lib/erl_docgen/doc/src/character_entities.xml21
-rw-r--r--lib/erl_docgen/doc/src/doc-build.xml21
-rw-r--r--lib/erl_docgen/doc/src/docgen_xml_check.xml21
-rw-r--r--lib/erl_docgen/doc/src/erl_docgen_app.xml22
-rw-r--r--lib/erl_docgen/doc/src/fasc_dtds.xml21
-rw-r--r--lib/erl_docgen/doc/src/header_tags.xml21
-rw-r--r--lib/erl_docgen/doc/src/inline_tags.xml21
-rw-r--r--lib/erl_docgen/doc/src/notes.xml70
-rw-r--r--lib/erl_docgen/doc/src/overview.xml21
-rw-r--r--lib/erl_docgen/doc/src/part.xml21
-rw-r--r--lib/erl_docgen/doc/src/ref_man.xml21
-rw-r--r--lib/erl_docgen/doc/src/refman_dtds.xml21
-rw-r--r--lib/erl_docgen/doc/src/user_guide_dtds.xml21
-rw-r--r--lib/erl_docgen/priv/Makefile21
-rw-r--r--lib/erl_docgen/priv/bin/Makefile19
-rwxr-xr-xlib/erl_docgen/priv/bin/codeline_preprocessing.escript19
-rw-r--r--lib/erl_docgen/priv/bin/specs_gen.escript21
-rwxr-xr-xlib/erl_docgen/priv/bin/xml_from_edoc.escript21
-rwxr-xr-xlib/erl_docgen/priv/bin/xref_mod_app.escript19
-rw-r--r--lib/erl_docgen/priv/css/Makefile21
-rw-r--r--lib/erl_docgen/priv/css/otp_doc.css33
-rw-r--r--lib/erl_docgen/priv/dtd/Makefile21
-rw-r--r--lib/erl_docgen/priv/dtd/application.dtd23
-rw-r--r--lib/erl_docgen/priv/dtd/appref.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/book.dtd25
-rw-r--r--lib/erl_docgen/priv/dtd/bookinsidecover.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/chapter.dtd25
-rw-r--r--lib/erl_docgen/priv/dtd/cites.dtd23
-rw-r--r--lib/erl_docgen/priv/dtd/common.dtd47
-rw-r--r--lib/erl_docgen/priv/dtd/common.entities.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/common.header.dtd25
-rw-r--r--lib/erl_docgen/priv/dtd/common.image.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/common.refs.dtd41
-rw-r--r--lib/erl_docgen/priv/dtd/common.table.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/comref.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/cref.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/erlref.dtd24
-rw-r--r--lib/erl_docgen/priv/dtd/fascicules.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/fileref.dtd21
-rw-r--r--lib/erl_docgen/priv/dtd/part.dtd23
-rw-r--r--lib/erl_docgen/priv/dtd/report.dtd25
-rw-r--r--lib/erl_docgen/priv/dtd/terms.dtd23
-rw-r--r--lib/erl_docgen/priv/dtd_html_entities/Makefile21
-rw-r--r--lib/erl_docgen/priv/dtd_man_entities/Makefile21
-rw-r--r--lib/erl_docgen/priv/fop.xconf19
-rw-r--r--lib/erl_docgen/priv/images/Makefile21
-rw-r--r--lib/erl_docgen/priv/js/flipmenu/Makefile21
-rw-r--r--lib/erl_docgen/priv/xsl/Makefile21
-rw-r--r--lib/erl_docgen/priv/xsl/db_eix.xsl21
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl63
-rw-r--r--lib/erl_docgen/priv/xsl/db_html_params.xsl21
-rw-r--r--lib/erl_docgen/priv/xsl/db_man.xsl49
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl74
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf_params.xsl54
-rw-r--r--lib/erl_docgen/src/Makefile19
-rw-r--r--lib/erl_docgen/src/docgen_edoc_xml_cb.erl43
-rw-r--r--lib/erl_docgen/src/docgen_otp_specs.erl37
-rw-r--r--lib/erl_docgen/src/docgen_xmerl_xml_cb.erl19
-rw-r--r--lib/erl_docgen/src/docgen_xml_check.erl21
-rw-r--r--lib/erl_docgen/src/erl_docgen.app.src2
-rw-r--r--lib/erl_docgen/src/erl_docgen.appup.src19
-rw-r--r--lib/erl_docgen/test/erl_docgen_SUITE.erl19
-rw-r--r--lib/erl_docgen/vsn.mk2
-rw-r--r--lib/erl_interface/Makefile21
-rw-r--r--lib/erl_interface/configure.in21
-rw-r--r--lib/erl_interface/doc/src/Makefile21
-rw-r--r--lib/erl_interface/doc/src/book.xml21
-rw-r--r--lib/erl_interface/doc/src/ei.xml30
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml21
-rw-r--r--lib/erl_interface/doc/src/ei_users_guide.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_call.xml23
-rw-r--r--lib/erl_interface/doc/src/erl_connect.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_error.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml31
-rw-r--r--lib/erl_interface/doc/src/erl_format.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_global.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_interface.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_malloc.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_marshal.xml21
-rw-r--r--lib/erl_interface/doc/src/notes.xml87
-rw-r--r--lib/erl_interface/doc/src/notes_history.xml21
-rw-r--r--lib/erl_interface/doc/src/part.xml21
-rw-r--r--lib/erl_interface/doc/src/part_erl_interface.xml21
-rw-r--r--lib/erl_interface/doc/src/part_notes.xml21
-rw-r--r--lib/erl_interface/doc/src/part_notes_history.xml21
-rw-r--r--lib/erl_interface/doc/src/ref_man.xml21
-rw-r--r--lib/erl_interface/doc/src/ref_man_ei.xml21
-rw-r--r--lib/erl_interface/doc/src/ref_man_erl_interface.xml21
-rw-r--r--lib/erl_interface/doc/src/registry.xml21
-rw-r--r--lib/erl_interface/include/ei.h19
-rw-r--r--lib/erl_interface/include/ei_connect.h21
-rw-r--r--lib/erl_interface/include/eicode.h21
-rw-r--r--lib/erl_interface/include/erl_interface.h21
-rw-r--r--lib/erl_interface/src/Makefile21
-rw-r--r--lib/erl_interface/src/Makefile.in19
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c19
-rw-r--r--lib/erl_interface/src/connect/ei_connect_int.h19
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.c25
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.h21
-rw-r--r--lib/erl_interface/src/connect/eirecv.c21
-rw-r--r--lib/erl_interface/src/connect/eirecv.h21
-rw-r--r--lib/erl_interface/src/connect/eisend.h21
-rw-r--r--lib/erl_interface/src/connect/send.c21
-rw-r--r--lib/erl_interface/src/connect/send_exit.c21
-rw-r--r--lib/erl_interface/src/connect/send_reg.c21
-rw-r--r--lib/erl_interface/src/decode/decode_atom.c21
-rw-r--r--lib/erl_interface/src/decode/decode_big.c42
-rw-r--r--lib/erl_interface/src/decode/decode_bignum.c21
-rw-r--r--lib/erl_interface/src/decode/decode_binary.c21
-rw-r--r--lib/erl_interface/src/decode/decode_boolean.c21
-rw-r--r--lib/erl_interface/src/decode/decode_char.c21
-rw-r--r--lib/erl_interface/src/decode/decode_double.c19
-rw-r--r--lib/erl_interface/src/decode/decode_fun.c21
-rw-r--r--lib/erl_interface/src/decode/decode_intlist.c21
-rw-r--r--lib/erl_interface/src/decode/decode_list_header.c21
-rw-r--r--lib/erl_interface/src/decode/decode_long.c21
-rw-r--r--lib/erl_interface/src/decode/decode_longlong.c21
-rw-r--r--lib/erl_interface/src/decode/decode_pid.c21
-rw-r--r--lib/erl_interface/src/decode/decode_port.c21
-rw-r--r--lib/erl_interface/src/decode/decode_ref.c21
-rw-r--r--lib/erl_interface/src/decode/decode_skip.c19
-rw-r--r--lib/erl_interface/src/decode/decode_skip.h21
-rw-r--r--lib/erl_interface/src/decode/decode_string.c21
-rw-r--r--lib/erl_interface/src/decode/decode_trace.c21
-rw-r--r--lib/erl_interface/src/decode/decode_tuple_header.c21
-rw-r--r--lib/erl_interface/src/decode/decode_ulong.c21
-rw-r--r--lib/erl_interface/src/decode/decode_ulonglong.c21
-rw-r--r--lib/erl_interface/src/decode/decode_version.c21
-rw-r--r--lib/erl_interface/src/eidefs.mk.in21
-rw-r--r--lib/erl_interface/src/encode/eicode.h21
-rw-r--r--lib/erl_interface/src/encode/encode_atom.c21
-rw-r--r--lib/erl_interface/src/encode/encode_big.c21
-rw-r--r--lib/erl_interface/src/encode/encode_bignum.c21
-rw-r--r--lib/erl_interface/src/encode/encode_binary.c21
-rw-r--r--lib/erl_interface/src/encode/encode_boolean.c21
-rw-r--r--lib/erl_interface/src/encode/encode_char.c21
-rw-r--r--lib/erl_interface/src/encode/encode_double.c31
-rw-r--r--lib/erl_interface/src/encode/encode_fun.c21
-rw-r--r--lib/erl_interface/src/encode/encode_list_header.c21
-rw-r--r--lib/erl_interface/src/encode/encode_long.c21
-rw-r--r--lib/erl_interface/src/encode/encode_longlong.c21
-rw-r--r--lib/erl_interface/src/encode/encode_pid.c21
-rw-r--r--lib/erl_interface/src/encode/encode_port.c21
-rw-r--r--lib/erl_interface/src/encode/encode_ref.c21
-rw-r--r--lib/erl_interface/src/encode/encode_string.c21
-rw-r--r--lib/erl_interface/src/encode/encode_trace.c21
-rw-r--r--lib/erl_interface/src/encode/encode_tuple_header.c21
-rw-r--r--lib/erl_interface/src/encode/encode_ulong.c21
-rw-r--r--lib/erl_interface/src/encode/encode_ulonglong.c21
-rw-r--r--lib/erl_interface/src/encode/encode_version.c21
-rw-r--r--lib/erl_interface/src/epmd/ei_epmd.h21
-rw-r--r--lib/erl_interface/src/epmd/epmd_port.c21
-rw-r--r--lib/erl_interface/src/epmd/epmd_publish.c21
-rw-r--r--lib/erl_interface/src/epmd/epmd_unpublish.c21
-rw-r--r--lib/erl_interface/src/erl_interface.app.src21
-rw-r--r--lib/erl_interface/src/erl_interface.appup.src21
-rw-r--r--lib/erl_interface/src/legacy/decode_term.c19
-rw-r--r--lib/erl_interface/src/legacy/encode_term.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_config.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_error.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_error.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.c31
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_fix_alloc.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_fix_alloc.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_format.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_format.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_global.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_internal.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_malloc.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_malloc.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c19
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.h21
-rw-r--r--lib/erl_interface/src/legacy/erl_resolve.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_timeout.c21
-rw-r--r--lib/erl_interface/src/legacy/erl_timeout.h21
-rw-r--r--lib/erl_interface/src/legacy/global_names.c21
-rw-r--r--lib/erl_interface/src/legacy/global_register.c21
-rw-r--r--lib/erl_interface/src/legacy/global_unregister.c21
-rw-r--r--lib/erl_interface/src/legacy/global_whereis.c21
-rw-r--r--lib/erl_interface/src/legacy/portability.h21
-rw-r--r--lib/erl_interface/src/misc/ei_compat.c21
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.c19
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.h21
-rw-r--r--lib/erl_interface/src/misc/ei_format.c21
-rw-r--r--lib/erl_interface/src/misc/ei_format.h21
-rw-r--r--lib/erl_interface/src/misc/ei_internal.h21
-rw-r--r--lib/erl_interface/src/misc/ei_locking.c21
-rw-r--r--lib/erl_interface/src/misc/ei_locking.h21
-rw-r--r--lib/erl_interface/src/misc/ei_malloc.c21
-rw-r--r--lib/erl_interface/src/misc/ei_malloc.h21
-rw-r--r--lib/erl_interface/src/misc/ei_portio.c21
-rw-r--r--lib/erl_interface/src/misc/ei_portio.h21
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c19
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.h21
-rw-r--r--lib/erl_interface/src/misc/ei_pthreads.c21
-rw-r--r--lib/erl_interface/src/misc/ei_trace.c21
-rw-r--r--lib/erl_interface/src/misc/ei_trace.h21
-rw-r--r--lib/erl_interface/src/misc/ei_x_encode.c21
-rw-r--r--lib/erl_interface/src/misc/ei_x_encode.h21
-rw-r--r--lib/erl_interface/src/misc/eidef.h42
-rw-r--r--lib/erl_interface/src/misc/eiext.h21
-rw-r--r--lib/erl_interface/src/misc/get_type.c19
-rw-r--r--lib/erl_interface/src/misc/putget.h19
-rw-r--r--lib/erl_interface/src/misc/show_msg.c19
-rw-r--r--lib/erl_interface/src/misc/show_msg.h21
-rw-r--r--lib/erl_interface/src/not_used/ei_send.c21
-rw-r--r--lib/erl_interface/src/not_used/ei_send_reg.c21
-rw-r--r--lib/erl_interface/src/not_used/send_link.c21
-rw-r--r--lib/erl_interface/src/not_used/whereis.c21
-rw-r--r--lib/erl_interface/src/prog/ei_fake_prog.c21
-rw-r--r--lib/erl_interface/src/prog/erl_call.c21
-rw-r--r--lib/erl_interface/src/prog/erl_fake_prog.c21
-rw-r--r--lib/erl_interface/src/prog/erl_start.c21
-rw-r--r--lib/erl_interface/src/prog/erl_start.h21
-rw-r--r--lib/erl_interface/src/registry/hash.h21
-rw-r--r--lib/erl_interface/src/registry/hash_dohash.c21
-rw-r--r--lib/erl_interface/src/registry/hash_foreach.c21
-rw-r--r--lib/erl_interface/src/registry/hash_freetab.c21
-rw-r--r--lib/erl_interface/src/registry/hash_insert.c21
-rw-r--r--lib/erl_interface/src/registry/hash_isprime.c21
-rw-r--r--lib/erl_interface/src/registry/hash_lookup.c21
-rw-r--r--lib/erl_interface/src/registry/hash_newtab.c21
-rw-r--r--lib/erl_interface/src/registry/hash_remove.c21
-rw-r--r--lib/erl_interface/src/registry/hash_resize.c21
-rw-r--r--lib/erl_interface/src/registry/hash_rlookup.c21
-rw-r--r--lib/erl_interface/src/registry/reg.h21
-rw-r--r--lib/erl_interface/src/registry/reg_close.c21
-rw-r--r--lib/erl_interface/src/registry/reg_delete.c21
-rw-r--r--lib/erl_interface/src/registry/reg_dirty.c21
-rw-r--r--lib/erl_interface/src/registry/reg_dump.c21
-rw-r--r--lib/erl_interface/src/registry/reg_free.c21
-rw-r--r--lib/erl_interface/src/registry/reg_get.c21
-rw-r--r--lib/erl_interface/src/registry/reg_getf.c21
-rw-r--r--lib/erl_interface/src/registry/reg_geti.c21
-rw-r--r--lib/erl_interface/src/registry/reg_getp.c21
-rw-r--r--lib/erl_interface/src/registry/reg_gets.c21
-rw-r--r--lib/erl_interface/src/registry/reg_make.c21
-rw-r--r--lib/erl_interface/src/registry/reg_open.c21
-rw-r--r--lib/erl_interface/src/registry/reg_purge.c21
-rw-r--r--lib/erl_interface/src/registry/reg_resize.c21
-rw-r--r--lib/erl_interface/src/registry/reg_restore.c21
-rw-r--r--lib/erl_interface/src/registry/reg_set.c21
-rw-r--r--lib/erl_interface/src/registry/reg_setf.c21
-rw-r--r--lib/erl_interface/src/registry/reg_seti.c21
-rw-r--r--lib/erl_interface/src/registry/reg_setp.c21
-rw-r--r--lib/erl_interface/src/registry/reg_sets.c21
-rw-r--r--lib/erl_interface/src/registry/reg_stat.c21
-rw-r--r--lib/erl_interface/src/registry/reg_tabstat.c21
-rw-r--r--lib/erl_interface/test/Makefile21
-rw-r--r--lib/erl_interface/test/Makefile.src21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/ei_runner.c21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/ei_runner.h21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/gccifier.c21
-rwxr-xr-xlib/erl_interface/test/all_SUITE_data/gccifier.sh21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/init_tc.erl21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/reclaim.h21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/runner.c21
-rw-r--r--lib/erl_interface/test/all_SUITE_data/runner.h21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE.erl21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c21
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE.erl21
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c21
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/einode.c21
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl19
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c19
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE.erl21
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c21
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl21
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c19
-rw-r--r--lib/erl_interface/test/ei_format_SUITE.erl21
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c21
-rw-r--r--lib/erl_interface/test/ei_print_SUITE.erl21
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c21
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE.erl19
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c19
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE.erl21
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE.erl21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c21
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE.erl21
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c21
-rw-r--r--lib/erl_interface/test/erl_format_SUITE.erl21
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/format_test.c21
-rw-r--r--lib/erl_interface/test/erl_global_SUITE.erl19
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/Makefile.first19
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/Makefile.src19
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c19
-rw-r--r--lib/erl_interface/test/erl_match_SUITE.erl21
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/match_test.c21
-rw-r--r--lib/erl_interface/test/port_call_SUITE.erl21
-rw-r--r--lib/erl_interface/test/port_call_SUITE_data/Makefile.src21
-rw-r--r--lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c21
-rw-r--r--lib/erl_interface/test/runner.erl21
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/et/Makefile21
-rw-r--r--lib/et/doc/src/Makefile19
-rw-r--r--lib/et/doc/src/book.xml21
-rw-r--r--lib/et/doc/src/et.xml19
-rw-r--r--lib/et/doc/src/et_collector.xml19
-rw-r--r--lib/et/doc/src/et_desc.xmlsrc21
-rw-r--r--lib/et/doc/src/et_examples.xmlsrc21
-rw-r--r--lib/et/doc/src/et_intro.xml21
-rw-r--r--lib/et/doc/src/et_selector.xml21
-rw-r--r--lib/et/doc/src/et_tutorial.xmlsrc21
-rw-r--r--lib/et/doc/src/et_viewer.xml19
-rw-r--r--lib/et/doc/src/files.mk19
-rw-r--r--lib/et/doc/src/notes.xml39
-rw-r--r--lib/et/doc/src/part.xml19
-rw-r--r--lib/et/doc/src/ref_man.xml21
-rw-r--r--lib/et/examples/Makefile19
-rw-r--r--lib/et/examples/et_demo.erl19
-rw-r--r--lib/et/include/et.hrl21
-rw-r--r--lib/et/src/Makefile21
-rw-r--r--lib/et/src/et.app.src19
-rw-r--r--lib/et/src/et.appup.src21
-rw-r--r--lib/et/src/et.erl21
-rw-r--r--lib/et/src/et_collector.erl21
-rw-r--r--lib/et/src/et_internal.hrl19
-rw-r--r--lib/et/src/et_selector.erl21
-rw-r--r--lib/et/src/et_viewer.erl19
-rw-r--r--lib/et/src/et_wx_contents_viewer.erl21
-rw-r--r--lib/et/src/et_wx_viewer.erl21
-rw-r--r--lib/et/src/modules.mk19
-rw-r--r--lib/et/subdirs.mk21
-rw-r--r--lib/et/test/Makefile19
-rw-r--r--lib/et/test/et_SUITE.erl19
-rw-r--r--lib/et/test/et_test_lib.erl19
-rw-r--r--lib/et/test/et_test_lib.hrl19
-rw-r--r--lib/et/test/et_wx_SUITE.erl19
-rwxr-xr-xlib/et/test/ett19
-rw-r--r--lib/et/test/ett.erl19
-rw-r--r--lib/et/vsn.mk2
-rw-r--r--lib/eunit/Makefile21
-rw-r--r--lib/eunit/doc/overview.edoc10
-rw-r--r--lib/eunit/doc/src/Makefile19
-rw-r--r--lib/eunit/doc/src/book.xml19
-rw-r--r--lib/eunit/doc/src/notes.xml79
-rw-r--r--lib/eunit/doc/src/part.xml19
-rw-r--r--lib/eunit/doc/src/part_notes.xml19
-rw-r--r--lib/eunit/doc/src/ref_man.xml19
-rw-r--r--lib/eunit/examples/Makefile21
-rw-r--r--lib/eunit/include/eunit.hrl269
-rw-r--r--lib/eunit/src/Makefile2
-rw-r--r--lib/eunit/src/eunit.app.src2
-rw-r--r--lib/eunit/src/eunit.appup.src19
-rw-r--r--lib/eunit/src/eunit.erl2
-rw-r--r--lib/eunit/src/eunit_autoexport.erl11
-rw-r--r--lib/eunit/src/eunit_data.erl3
-rw-r--r--lib/eunit/src/eunit_internal.hrl4
-rw-r--r--lib/eunit/src/eunit_lib.erl48
-rw-r--r--lib/eunit/src/eunit_listener.erl37
-rw-r--r--lib/eunit/src/eunit_proc.erl9
-rw-r--r--lib/eunit/src/eunit_serial.erl18
-rw-r--r--lib/eunit/src/eunit_server.erl2
-rw-r--r--lib/eunit/src/eunit_surefire.erl37
-rw-r--r--lib/eunit/src/eunit_test.erl3
-rw-r--r--lib/eunit/src/eunit_tests.erl2
-rw-r--r--lib/eunit/src/eunit_tty.erl26
-rw-r--r--lib/eunit/test/Makefile23
-rw-r--r--lib/eunit/test/eunit_SUITE.erl57
-rw-r--r--lib/eunit/test/tlatin.erl15
-rw-r--r--lib/eunit/test/tutf8.erl15
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/gs/Makefile21
-rw-r--r--lib/gs/contribs/Makefile21
-rw-r--r--lib/gs/contribs/bonk/Makefile21
-rw-r--r--lib/gs/contribs/bonk/bonk.erl19
-rw-r--r--lib/gs/contribs/bonk/bonk_sound.erl21
-rw-r--r--lib/gs/contribs/bonk/bonk_square.erl21
-rw-r--r--lib/gs/contribs/bonk/sounder.erl21
-rw-r--r--lib/gs/contribs/cols/Makefile21
-rw-r--r--lib/gs/contribs/cols/cols.erl21
-rw-r--r--lib/gs/contribs/cols/highscore.erl21
-rw-r--r--lib/gs/contribs/mandel/Makefile21
-rw-r--r--lib/gs/contribs/mandel/mandel.erl21
-rw-r--r--lib/gs/contribs/mandel/mandel.html21
-rw-r--r--lib/gs/contribs/othello/Makefile21
-rw-r--r--lib/gs/contribs/othello/othello.erl21
-rw-r--r--lib/gs/contribs/othello/othello_adt.erl19
-rw-r--r--lib/gs/contribs/othello/othello_board.erl21
-rw-r--r--lib/gs/doc/src/Makefile21
-rw-r--r--lib/gs/doc/src/book.xml21
-rw-r--r--lib/gs/doc/src/gs.xml19
-rw-r--r--lib/gs/doc/src/gs_chapter1.xml21
-rw-r--r--lib/gs/doc/src/gs_chapter2.xmlsrc21
-rw-r--r--lib/gs/doc/src/gs_chapter3.xml21
-rw-r--r--lib/gs/doc/src/gs_chapter4.xmlsrc21
-rw-r--r--lib/gs/doc/src/gs_chapter5.xmlsrc21
-rw-r--r--lib/gs/doc/src/gs_chapter6.xmlsrc21
-rw-r--r--lib/gs/doc/src/gs_chapter7.xmlsrc21
-rw-r--r--lib/gs/doc/src/gs_chapter8.xmlsrc21
-rw-r--r--lib/gs/doc/src/notes.xml39
-rw-r--r--lib/gs/doc/src/part.xml21
-rw-r--r--lib/gs/doc/src/part_notes.xml21
-rw-r--r--lib/gs/doc/src/ref_man.xml21
-rw-r--r--lib/gs/examples/Makefile21
-rw-r--r--lib/gs/examples/ball.erl21
-rw-r--r--lib/gs/examples/browser.erl21
-rw-r--r--lib/gs/examples/calc.erl21
-rw-r--r--lib/gs/examples/calc2.erl21
-rw-r--r--lib/gs/examples/color_demo.erl21
-rw-r--r--lib/gs/examples/color_demo2.erl21
-rw-r--r--lib/gs/examples/distrib_draw.erl21
-rw-r--r--lib/gs/examples/entry_demo.erl21
-rw-r--r--lib/gs/examples/event_test.erl21
-rw-r--r--lib/gs/examples/file_dialog.erl21
-rw-r--r--lib/gs/examples/focus_demo.erl21
-rw-r--r--lib/gs/examples/frac.erl21
-rw-r--r--lib/gs/examples/line_demo.erl21
-rw-r--r--lib/gs/examples/man.erl21
-rw-r--r--lib/gs/examples/menu_demo.erl21
-rw-r--r--lib/gs/examples/rubber.erl21
-rw-r--r--lib/gs/src/Makefile21
-rw-r--r--lib/gs/src/gs.appup.src19
-rw-r--r--lib/gs/src/gs.erl21
-rw-r--r--lib/gs/src/gs_frontend.erl21
-rw-r--r--lib/gs/src/gs_make.erl21
-rw-r--r--lib/gs/src/gs_packer.erl21
-rw-r--r--lib/gs/src/gs_widgets.erl21
-rw-r--r--lib/gs/src/gse.erl21
-rw-r--r--lib/gs/src/gstk.erl21
-rw-r--r--lib/gs/src/gstk.hrl21
-rw-r--r--lib/gs/src/gstk_arc.erl21
-rw-r--r--lib/gs/src/gstk_button.erl21
-rw-r--r--lib/gs/src/gstk_canvas.erl21
-rw-r--r--lib/gs/src/gstk_checkbutton.erl21
-rw-r--r--lib/gs/src/gstk_db.erl21
-rw-r--r--lib/gs/src/gstk_editor.erl21
-rw-r--r--lib/gs/src/gstk_entry.erl21
-rw-r--r--lib/gs/src/gstk_font.erl21
-rw-r--r--lib/gs/src/gstk_frame.erl21
-rw-r--r--lib/gs/src/gstk_generic.erl21
-rw-r--r--lib/gs/src/gstk_grid.erl21
-rw-r--r--lib/gs/src/gstk_gridline.erl21
-rw-r--r--lib/gs/src/gstk_gs.erl21
-rw-r--r--lib/gs/src/gstk_image.erl21
-rw-r--r--lib/gs/src/gstk_label.erl21
-rw-r--r--lib/gs/src/gstk_line.erl21
-rw-r--r--lib/gs/src/gstk_listbox.erl21
-rw-r--r--lib/gs/src/gstk_menu.erl21
-rw-r--r--lib/gs/src/gstk_menubar.erl21
-rw-r--r--lib/gs/src/gstk_menubutton.erl21
-rw-r--r--lib/gs/src/gstk_menuitem.erl21
-rw-r--r--lib/gs/src/gstk_oval.erl21
-rw-r--r--lib/gs/src/gstk_polygon.erl21
-rw-r--r--lib/gs/src/gstk_port_handler.erl21
-rw-r--r--lib/gs/src/gstk_radiobutton.erl21
-rw-r--r--lib/gs/src/gstk_rectangle.erl21
-rw-r--r--lib/gs/src/gstk_scale.erl21
-rw-r--r--lib/gs/src/gstk_text.erl21
-rw-r--r--lib/gs/src/gstk_widgets.erl21
-rw-r--r--lib/gs/src/gstk_window.erl21
-rw-r--r--lib/gs/src/tcl2erl.erl21
-rw-r--r--lib/gs/src/tool_file_dialog.erl21
-rw-r--r--lib/gs/src/tool_utils.erl19
-rw-r--r--lib/gs/tcl/Makefile21
-rw-r--r--lib/gs/tcl/Makefile.in21
-rw-r--r--lib/gs/test/gs_SUITE.erl19
-rw-r--r--lib/gs/vsn.mk2
-rw-r--r--lib/hipe/Makefile19
-rw-r--r--lib/hipe/amd64/Makefile19
-rw-r--r--lib/hipe/amd64/hipe_amd64_assemble.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_defuse.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_encode.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_frame.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_liveness.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_main.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_pp.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_finalise.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_ls.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_naive.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_postconditions.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_registers.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_spill_restore.erl21
-rw-r--r--lib/hipe/amd64/hipe_amd64_x87.erl21
-rw-r--r--lib/hipe/amd64/hipe_rtl_to_amd64.erl21
-rw-r--r--lib/hipe/arm/Makefile19
-rw-r--r--lib/hipe/arm/hipe_arm.erl21
-rw-r--r--lib/hipe/arm/hipe_arm.hrl21
-rw-r--r--lib/hipe/arm/hipe_arm_assemble.erl23
-rw-r--r--lib/hipe/arm/hipe_arm_cfg.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_defuse.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_encode.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_finalise.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_frame.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_liveness_gpr.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_main.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_pp.erl19
-rw-r--r--lib/hipe/arm/hipe_arm_ra.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_ra_finalise.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_ra_ls.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_ra_naive.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_ra_postconditions.erl21
-rw-r--r--lib/hipe/arm/hipe_arm_registers.erl21
-rw-r--r--lib/hipe/arm/hipe_rtl_to_arm.erl21
-rw-r--r--lib/hipe/cerl/Makefile19
-rw-r--r--lib/hipe/cerl/cerl_cconv.erl21
-rw-r--r--lib/hipe/cerl/cerl_closurean.erl19
-rw-r--r--lib/hipe/cerl/cerl_hipe_primops.hrl21
-rw-r--r--lib/hipe/cerl/cerl_hipeify.erl21
-rw-r--r--lib/hipe/cerl/cerl_lib.erl21
-rw-r--r--lib/hipe/cerl/cerl_messagean.erl19
-rw-r--r--lib/hipe/cerl/cerl_pmatch.erl31
-rw-r--r--lib/hipe/cerl/cerl_prettypr.erl39
-rw-r--r--lib/hipe/cerl/cerl_to_icode.erl33
-rw-r--r--lib/hipe/cerl/cerl_typean.erl21
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl92
-rw-r--r--lib/hipe/cerl/erl_types.erl1358
-rw-r--r--lib/hipe/doc/Makefile19
-rw-r--r--lib/hipe/doc/src/Makefile19
-rw-r--r--lib/hipe/doc/src/book.xml19
-rw-r--r--lib/hipe/doc/src/hipe_app.xml36
-rw-r--r--lib/hipe/doc/src/notes.xml254
-rw-r--r--lib/hipe/doc/src/part_notes.xml21
-rw-r--r--lib/hipe/doc/src/ref_man.xml21
-rw-r--r--lib/hipe/flow/Makefile19
-rw-r--r--lib/hipe/flow/cfg.hrl21
-rw-r--r--lib/hipe/flow/cfg.inc21
-rw-r--r--lib/hipe/flow/ebb.inc21
-rw-r--r--lib/hipe/flow/hipe_bb.erl21
-rw-r--r--lib/hipe/flow/hipe_bb.hrl21
-rw-r--r--lib/hipe/flow/hipe_dominators.erl19
-rw-r--r--lib/hipe/flow/hipe_gen_cfg.erl21
-rw-r--r--lib/hipe/flow/liveness.inc21
-rw-r--r--lib/hipe/icode/Makefile19
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl85
-rw-r--r--lib/hipe/icode/hipe_icode.erl21
-rw-r--r--lib/hipe/icode/hipe_icode.hrl21
-rw-r--r--lib/hipe/icode/hipe_icode_bincomp.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_callgraph.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_cfg.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_coordinator.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_ebb.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_exceptions.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_fp.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_heap_test.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_inline_bifs.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_instruction_counter.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_liveness.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_mulret.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_pp.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl67
-rw-r--r--lib/hipe/icode/hipe_icode_primops.hrl21
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl25
-rw-r--r--lib/hipe/icode/hipe_icode_split_arith.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_ssa.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_const_prop.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_copy_prop.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl21
-rw-r--r--lib/hipe/icode/hipe_icode_type.erl19
-rw-r--r--lib/hipe/icode/hipe_icode_type.hrl21
-rw-r--r--lib/hipe/llvm/Makefile19
-rw-r--r--lib/hipe/llvm/hipe_llvm_main.erl2
-rw-r--r--lib/hipe/llvm/hipe_llvm_merge.erl2
-rw-r--r--lib/hipe/main/Makefile19
-rw-r--r--lib/hipe/main/hipe.app.src27
-rw-r--r--lib/hipe/main/hipe.appup.src21
-rw-r--r--lib/hipe/main/hipe.erl139
-rw-r--r--lib/hipe/main/hipe.hrl.src21
-rw-r--r--lib/hipe/main/hipe_main.erl21
-rw-r--r--lib/hipe/misc/Makefile19
-rw-r--r--lib/hipe/misc/hipe_consttab.erl21
-rw-r--r--lib/hipe/misc/hipe_consttab.hrl21
-rw-r--r--lib/hipe/misc/hipe_data_pp.erl21
-rw-r--r--lib/hipe/misc/hipe_gensym.erl21
-rw-r--r--lib/hipe/misc/hipe_pack_constants.erl21
-rw-r--r--lib/hipe/misc/hipe_sdi.erl21
-rw-r--r--lib/hipe/misc/hipe_sdi.hrl21
-rw-r--r--lib/hipe/opt/Makefile19
-rw-r--r--lib/hipe/opt/hipe_schedule.erl21
-rw-r--r--lib/hipe/opt/hipe_schedule_prio.erl21
-rw-r--r--lib/hipe/opt/hipe_spillmin.erl21
-rw-r--r--lib/hipe/opt/hipe_spillmin_color.erl21
-rw-r--r--lib/hipe/opt/hipe_spillmin_scan.erl21
-rw-r--r--lib/hipe/opt/hipe_target_machine.erl21
-rw-r--r--lib/hipe/opt/hipe_ultra_mod2.erl21
-rw-r--r--lib/hipe/opt/hipe_ultra_prio.erl21
-rw-r--r--lib/hipe/ppc/Makefile19
-rw-r--r--lib/hipe/ppc/hipe_ppc.erl19
-rw-r--r--lib/hipe/ppc/hipe_ppc.hrl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_assemble.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_cfg.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_defuse.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_encode.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_finalise.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_frame.erl19
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_all.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_fpr.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_gpr.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_main.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_pp.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_finalise.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_ls.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_naive.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_postconditions.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl21
-rw-r--r--lib/hipe/ppc/hipe_ppc_registers.erl21
-rw-r--r--lib/hipe/ppc/hipe_rtl_to_ppc.erl19
-rw-r--r--lib/hipe/regalloc/Makefile19
-rw-r--r--lib/hipe/regalloc/hipe_adj_list.erl21
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific.erl21
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_sse2.erl21
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_x87.erl21
-rw-r--r--lib/hipe/regalloc/hipe_arm_specific.erl21
-rw-r--r--lib/hipe/regalloc/hipe_coalescing_regalloc.erl21
-rw-r--r--lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl21
-rw-r--r--lib/hipe/regalloc/hipe_ig.erl21
-rw-r--r--lib/hipe/regalloc/hipe_ig_moves.erl21
-rw-r--r--lib/hipe/regalloc/hipe_ls_regalloc.erl21
-rw-r--r--lib/hipe/regalloc/hipe_moves.erl21
-rw-r--r--lib/hipe/regalloc/hipe_node_sets.erl21
-rw-r--r--lib/hipe/regalloc/hipe_optimistic_regalloc.erl21
-rw-r--r--lib/hipe/regalloc/hipe_ppc_specific.erl21
-rw-r--r--lib/hipe/regalloc/hipe_ppc_specific_fp.erl21
-rw-r--r--lib/hipe/regalloc/hipe_reg_worklists.erl21
-rw-r--r--lib/hipe/regalloc/hipe_regalloc_loop.erl21
-rw-r--r--lib/hipe/regalloc/hipe_sparc_specific.erl21
-rw-r--r--lib/hipe/regalloc/hipe_sparc_specific_fp.erl21
-rw-r--r--lib/hipe/regalloc/hipe_spillcost.erl21
-rw-r--r--lib/hipe/regalloc/hipe_spillcost.hrl21
-rw-r--r--lib/hipe/regalloc/hipe_temp_map.erl21
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific.erl21
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific_x87.erl21
-rw-r--r--lib/hipe/rtl/Makefile21
-rw-r--r--lib/hipe/rtl/hipe_icode2rtl.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl.hrl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_arch.erl19
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith.inc36
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_32.erl24
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_64.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary.erl165
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_construct.erl226
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_match.erl207
-rw-r--r--lib/hipe/rtl/hipe_rtl_cfg.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_cleanup_const.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_exceptions.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_lcm.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_liveness.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_mk_switch.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_primops.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssapre.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_symbolic.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl_varmap.erl21
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl75
-rw-r--r--lib/hipe/sparc/Makefile19
-rw-r--r--lib/hipe/sparc/hipe_rtl_to_sparc.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc.hrl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_assemble.erl23
-rw-r--r--lib/hipe/sparc/hipe_sparc_cfg.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_defuse.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_encode.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_finalise.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_frame.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_all.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_fpr.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_gpr.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_main.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_pp.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_finalise.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_ls.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_naive.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_registers.erl21
-rw-r--r--lib/hipe/ssa/hipe_ssa.inc21
-rw-r--r--lib/hipe/ssa/hipe_ssa_const_prop.inc21
-rw-r--r--lib/hipe/ssa/hipe_ssa_copy_prop.inc21
-rw-r--r--lib/hipe/ssa/hipe_ssa_liveness.inc21
-rw-r--r--lib/hipe/test/Makefile4
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_arith.erl72
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_beam_instrs.erl102
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_bifs.erl257
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_bignums.erl143
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_boolean.erl47
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_bugs_beam.erl138
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl463
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_comparisons.erl157
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_exceptions.erl465
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_floats.erl180
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_fun.erl124
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_guards.erl164
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_inline_function.erl73
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_inline_module.erl31
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_issues_beam.erl326
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl153
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_lists.erl61
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_module_info.erl32
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_pattern_match.erl46
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_random.erl238
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_receive.erl56
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_records.erl28
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_strength_reduce.erl65
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_switches.erl52
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_tail_rec.erl39
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_tuples.erl177
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_add.erl10
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_construct.erl177
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_match.erl120
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_split.erl10
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_utf.erl344
-rw-r--r--lib/hipe/test/hipe_SUITE.erl19
-rw-r--r--lib/hipe/test/hipe_testsuite_driver.erl16
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_map_size.erl6
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_map_sort_literals.erl31
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_put_map_assoc.erl2
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_put_map_exact.erl4
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_update_assoc.erl2
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_update_exact.erl10
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_update_map_expressions.erl6
-rw-r--r--lib/hipe/test/sanity_SUITE_data/sanity_comp_timeout.erl28
-rw-r--r--lib/hipe/test/sanity_SUITE_data/sanity_no_zombies.erl21
-rw-r--r--lib/hipe/tools/Makefile19
-rw-r--r--lib/hipe/tools/hipe_jit.erl21
-rw-r--r--lib/hipe/tools/hipe_profile.erl21
-rw-r--r--lib/hipe/tools/hipe_timer.erl39
-rw-r--r--lib/hipe/util/Makefile19
-rw-r--r--lib/hipe/util/hipe_digraph.erl19
-rw-r--r--lib/hipe/util/hipe_dot.erl21
-rw-r--r--lib/hipe/util/hipe_timing.erl21
-rw-r--r--lib/hipe/util/hipe_vectors.erl21
-rw-r--r--lib/hipe/util/hipe_vectors.hrl21
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/hipe/x86/Makefile19
-rw-r--r--lib/hipe/x86/hipe_rtl_to_x86.erl21
-rw-r--r--lib/hipe/x86/hipe_x86.erl21
-rw-r--r--lib/hipe/x86/hipe_x86.hrl21
-rw-r--r--lib/hipe/x86/hipe_x86_assemble.erl23
-rw-r--r--lib/hipe/x86/hipe_x86_cfg.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_defuse.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_encode.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_frame.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_liveness.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_main.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_postpass.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_pp.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_ra.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_ra_finalise.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_ra_ls.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_ra_naive.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_ra_postconditions.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_ra_x87_ls.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_registers.erl21
-rw-r--r--lib/hipe/x86/hipe_x86_spill_restore.erl19
-rw-r--r--lib/hipe/x86/hipe_x86_x87.erl21
-rw-r--r--lib/ic/Makefile21
-rw-r--r--lib/ic/c_src/Makefile21
-rw-r--r--lib/ic/c_src/Makefile.in21
-rw-r--r--lib/ic/c_src/Makefile.win3221
-rw-r--r--lib/ic/c_src/ic.c21
-rw-r--r--lib/ic/c_src/ic_tmo.c21
-rw-r--r--lib/ic/c_src/oe_ei_code_erlang_binary.c21
-rw-r--r--lib/ic/c_src/oe_ei_decode_longlong.c21
-rw-r--r--lib/ic/c_src/oe_ei_decode_ulonglong.c21
-rw-r--r--lib/ic/c_src/oe_ei_decode_wchar.c21
-rw-r--r--lib/ic/c_src/oe_ei_decode_wstring.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_atom.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_char.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_double.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_list_header.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_long.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_longlong.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_pid.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_port.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_ref.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_string.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_term.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_tuple_header.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_ulong.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_ulonglong.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_version.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_wchar.c21
-rw-r--r--lib/ic/c_src/oe_ei_encode_wstring.c21
-rw-r--r--lib/ic/doc/src/CORBA_Environment_alloc.xml21
-rw-r--r--lib/ic/doc/src/Makefile19
-rw-r--r--lib/ic/doc/src/book.xml21
-rw-r--r--lib/ic/doc/src/c-part.xml21
-rw-r--r--lib/ic/doc/src/ch_basic_idl.xml21
-rw-r--r--lib/ic/doc/src/ch_c_client.xml21
-rw-r--r--lib/ic/doc/src/ch_c_corba_env.xml21
-rw-r--r--lib/ic/doc/src/ch_c_mapping.xml21
-rw-r--r--lib/ic/doc/src/ch_c_server.xml21
-rw-r--r--lib/ic/doc/src/ch_erl_genserv.xml21
-rw-r--r--lib/ic/doc/src/ch_erl_plain.xml21
-rw-r--r--lib/ic/doc/src/ch_ic_protocol.xml21
-rw-r--r--lib/ic/doc/src/ch_introduction.xml21
-rw-r--r--lib/ic/doc/src/ch_java.xml21
-rw-r--r--lib/ic/doc/src/erl-part.xml21
-rw-r--r--lib/ic/doc/src/ic.xml21
-rw-r--r--lib/ic/doc/src/ic_c_protocol.xml21
-rw-r--r--lib/ic/doc/src/ic_clib.xml21
-rw-r--r--lib/ic/doc/src/java-part.xml21
-rw-r--r--lib/ic/doc/src/notes.xml39
-rw-r--r--lib/ic/doc/src/part.xml21
-rw-r--r--lib/ic/doc/src/part_notes.xml21
-rw-r--r--lib/ic/doc/src/ref_man.xml21
-rw-r--r--lib/ic/examples/all-against-all/Makefile21
-rw-r--r--lib/ic/examples/all-against-all/Makefile.win3221
-rw-r--r--lib/ic/examples/all-against-all/callbacks.c21
-rw-r--r--lib/ic/examples/all-against-all/client.c21
-rw-r--r--lib/ic/examples/all-against-all/client.erl21
-rw-r--r--lib/ic/examples/all-against-all/client.java21
-rw-r--r--lib/ic/examples/all-against-all/random.idl21
-rw-r--r--lib/ic/examples/all-against-all/rmod_random_impl.erl21
-rw-r--r--lib/ic/examples/all-against-all/server.c21
-rw-r--r--lib/ic/examples/all-against-all/server.erl21
-rw-r--r--lib/ic/examples/all-against-all/server.java21
-rw-r--r--lib/ic/examples/all-against-all/serverImpl.java21
-rw-r--r--lib/ic/examples/c-client/Makefile21
-rw-r--r--lib/ic/examples/c-client/client.c21
-rw-r--r--lib/ic/examples/c-client/random.idl21
-rw-r--r--lib/ic/examples/c-client/rmod_random_impl.erl21
-rw-r--r--lib/ic/examples/c-client/test.erl21
-rw-r--r--lib/ic/examples/c-server/Makefile21
-rw-r--r--lib/ic/examples/c-server/callbacks.c21
-rw-r--r--lib/ic/examples/c-server/client.c21
-rw-r--r--lib/ic/examples/c-server/client.erl21
-rw-r--r--lib/ic/examples/c-server/random.idl21
-rw-r--r--lib/ic/examples/c-server/server.c21
-rw-r--r--lib/ic/examples/erl-genserv/random.idl21
-rw-r--r--lib/ic/examples/erl-genserv/rmod_random_impl.erl21
-rw-r--r--lib/ic/examples/erl-plain/random.idl21
-rw-r--r--lib/ic/examples/erl-plain/rmod_random_impl.erl21
-rw-r--r--lib/ic/examples/java-client-server/client.java21
-rw-r--r--lib/ic/examples/java-client-server/random.idl21
-rw-r--r--lib/ic/examples/java-client-server/server.java21
-rw-r--r--lib/ic/examples/java-client-server/serverImpl.java21
-rw-r--r--lib/ic/examples/pre_post_condition/Makefile42
-rw-r--r--lib/ic/examples/pre_post_condition/ReadMe.txt29
-rw-r--r--lib/ic/examples/pre_post_condition/ex.idl21
-rw-r--r--lib/ic/examples/pre_post_condition/m_i_impl.erl21
-rw-r--r--lib/ic/examples/pre_post_condition/tracer.erl21
-rw-r--r--lib/ic/include/erlang.idl21
-rw-r--r--lib/ic/include/ic.h21
-rw-r--r--lib/ic/java_src/Makefile21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Any.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/AnyHelper.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/AnyHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/BooleanHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/ByteHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/CharHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/DoubleHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Environment.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/FloatHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Holder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/IntHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/LongHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Makefile21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Pid.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/PidHelper.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/PidHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Port.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/PortHelper.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/PortHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Ref.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/RefHelper.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/RefHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/ShortHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/StringHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/TCKind.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Term.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/TermHolder.java21
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java21
-rw-r--r--lib/ic/src/Makefile21
-rw-r--r--lib/ic/src/ic.erl21
-rw-r--r--lib/ic/src/ic.hrl21
-rw-r--r--lib/ic/src/ic_array_java.erl21
-rw-r--r--lib/ic/src/ic_attribute_java.erl21
-rw-r--r--lib/ic/src/ic_cbe.erl21
-rw-r--r--lib/ic/src/ic_cclient.erl21
-rw-r--r--lib/ic/src/ic_code.erl21
-rw-r--r--lib/ic/src/ic_codegen.erl21
-rw-r--r--lib/ic/src/ic_constant_java.erl21
-rw-r--r--lib/ic/src/ic_cserver.erl21
-rw-r--r--lib/ic/src/ic_debug.hrl21
-rw-r--r--lib/ic/src/ic_enum_java.erl21
-rw-r--r--lib/ic/src/ic_erl_template.erl21
-rw-r--r--lib/ic/src/ic_erlbe.erl21
-rw-r--r--lib/ic/src/ic_error.erl21
-rw-r--r--lib/ic/src/ic_fetch.erl21
-rw-r--r--lib/ic/src/ic_file.erl21
-rw-r--r--lib/ic/src/ic_forms.erl21
-rw-r--r--lib/ic/src/ic_genobj.erl21
-rw-r--r--lib/ic/src/ic_java_type.erl21
-rw-r--r--lib/ic/src/ic_jbe.erl21
-rw-r--r--lib/ic/src/ic_noc.erl21
-rw-r--r--lib/ic/src/ic_options.erl21
-rw-r--r--lib/ic/src/ic_plainbe.erl21
-rw-r--r--lib/ic/src/ic_pp.erl21
-rw-r--r--lib/ic/src/ic_pragma.erl21
-rw-r--r--lib/ic/src/ic_sequence_java.erl21
-rw-r--r--lib/ic/src/ic_struct_java.erl21
-rw-r--r--lib/ic/src/ic_symtab.erl21
-rw-r--r--lib/ic/src/ic_union_java.erl21
-rw-r--r--lib/ic/src/ic_util.erl21
-rw-r--r--lib/ic/src/icenum.erl21
-rw-r--r--lib/ic/src/iceval.erl21
-rw-r--r--lib/ic/src/icforms.hrl21
-rw-r--r--lib/ic/src/icparse.yrl21
-rw-r--r--lib/ic/src/icpreproc.erl21
-rw-r--r--lib/ic/src/icscan.erl21
-rw-r--r--lib/ic/src/icstruct.erl21
-rw-r--r--lib/ic/src/ictk.erl21
-rw-r--r--lib/ic/src/ictype.erl21
-rw-r--r--lib/ic/src/icunion.erl21
-rw-r--r--lib/ic/src/icyeccpre.hrl21
-rw-r--r--lib/ic/test/Makefile21
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src21
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_client.c21
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl21
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl21
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c21
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE.erl21
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src21
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/c_server.c21
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c21
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl21
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE.erl21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl21
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c21
-rw-r--r--lib/ic/test/ic_SUITE.erl21
-rw-r--r--lib/ic/test/ic_SUITE_data/attr.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/c_err1.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/c_err2.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/c_err3.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/c_norm.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/enum.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/forward.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/include.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/include2.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/include3.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/inherit.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/inherit_err.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/inherit_warn.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/mult_ids.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/nasty.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/one.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/one_followed.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/one_out.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/one_raises.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/one_void.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/raises_reg.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/struct.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax1.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax2.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax3.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax4.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax5.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax6.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/type.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/typeid.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/u_case_mult.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/u_default.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/u_mult.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/u_norm.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/u_type.idl21
-rw-r--r--lib/ic/test/ic_SUITE_data/undef_id.idl21
-rw-r--r--lib/ic/test/ic_be_SUITE.erl21
-rw-r--r--lib/ic/test/ic_be_SUITE_data/plain.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE.erl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/arg.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/cascade.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/comment.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/concat.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/define.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/if.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/if_zero.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/inc.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/included1.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/included2.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/includer.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/line.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/misc.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/nopara.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/predef.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/predef_time.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/self_ref.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/separate.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl21
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE.erl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl21
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/uggly.idl21
-rw-r--r--lib/ic/test/ic_register_SUITE.erl21
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m10.idl21
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m11.idl21
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m12.idl21
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m8.idl21
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m9.idl21
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE.erl27
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java21
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src21
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl21
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl21
-rw-r--r--lib/ic/vsn.mk2
-rw-r--r--lib/inets/Makefile19
-rw-r--r--lib/inets/doc/archive/rfc1945.html21
-rw-r--r--lib/inets/doc/src/Makefile20
-rw-r--r--lib/inets/doc/src/book.xml21
-rw-r--r--lib/inets/doc/src/ftp.xml492
-rw-r--r--lib/inets/doc/src/ftp_client.xml71
-rw-r--r--lib/inets/doc/src/http_client.xml117
-rw-r--r--lib/inets/doc/src/http_server.xml1076
-rw-r--r--lib/inets/doc/src/http_uri.xml171
-rw-r--r--lib/inets/doc/src/httpc.xml864
-rw-r--r--lib/inets/doc/src/httpd.xml1260
-rw-r--r--lib/inets/doc/src/httpd_conf.xml162
-rw-r--r--lib/inets/doc/src/httpd_custom_api.xml37
-rw-r--r--lib/inets/doc/src/httpd_socket.xml45
-rw-r--r--lib/inets/doc/src/httpd_util.xml281
-rw-r--r--lib/inets/doc/src/inets.xml130
-rw-r--r--lib/inets/doc/src/inets_services.xml80
-rw-r--r--lib/inets/doc/src/introduction.xml (renamed from lib/mnesia/doc/src/Mnesia_App_D.xmlsrc)36
-rw-r--r--lib/inets/doc/src/mod_alias.xml81
-rw-r--r--lib/inets/doc/src/mod_auth.xml405
-rw-r--r--lib/inets/doc/src/mod_esi.xml154
-rw-r--r--lib/inets/doc/src/mod_security.xml159
-rw-r--r--lib/inets/doc/src/notes.xml514
-rw-r--r--lib/inets/doc/src/notes_history.xml21
-rw-r--r--lib/inets/doc/src/part.xml35
-rw-r--r--lib/inets/doc/src/part_notes.xml21
-rw-r--r--lib/inets/doc/src/part_notes_history.xml21
-rw-r--r--lib/inets/doc/src/ref_man.xml28
-rw-r--r--lib/inets/doc/src/tftp.xml581
-rw-r--r--lib/inets/examples/Makefile21
-rw-r--r--lib/inets/examples/httpd_load_test/Makefile19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt.erl19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt.sh.skel19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_client.erl19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_ctrl.erl19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_logger.erl19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_logger.hrl21
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_random_html.erl26
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_server.erl19
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_slave.erl19
-rw-r--r--lib/inets/examples/httpd_load_test/modules.mk19
-rw-r--r--lib/inets/examples/server_root/Makefile19
-rw-r--r--lib/inets/examples/server_root/conf/httpd.conf21
-rw-r--r--lib/inets/include/httpd.hrl21
-rw-r--r--lib/inets/include/mod_auth.hrl21
-rw-r--r--lib/inets/priv/Makefile21
-rw-r--r--lib/inets/src/Makefile21
-rw-r--r--lib/inets/src/ftp/Makefile19
-rw-r--r--lib/inets/src/ftp/ftp.erl31
-rw-r--r--lib/inets/src/ftp/ftp_internal.hrl21
-rw-r--r--lib/inets/src/ftp/ftp_progress.erl21
-rw-r--r--lib/inets/src/ftp/ftp_response.erl21
-rw-r--r--lib/inets/src/ftp/ftp_sup.erl21
-rw-r--r--lib/inets/src/http_client/Makefile19
-rw-r--r--lib/inets/src/http_client/httpc.erl32
-rw-r--r--lib/inets/src/http_client/httpc_cookie.erl19
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl160
-rw-r--r--lib/inets/src/http_client/httpc_handler_sup.erl19
-rw-r--r--lib/inets/src/http_client/httpc_internal.hrl19
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl21
-rw-r--r--lib/inets/src/http_client/httpc_profile_sup.erl19
-rw-r--r--lib/inets/src/http_client/httpc_request.erl22
-rw-r--r--lib/inets/src/http_client/httpc_response.erl21
-rw-r--r--lib/inets/src/http_client/httpc_sup.erl21
-rw-r--r--lib/inets/src/http_lib/Makefile19
-rw-r--r--lib/inets/src/http_lib/http_chunk.erl203
-rw-r--r--lib/inets/src/http_lib/http_internal.hrl19
-rw-r--r--lib/inets/src/http_lib/http_request.erl21
-rw-r--r--lib/inets/src/http_lib/http_response.erl53
-rw-r--r--lib/inets/src/http_lib/http_transport.erl227
-rw-r--r--lib/inets/src/http_lib/http_uri.erl58
-rw-r--r--lib/inets/src/http_lib/http_util.erl88
-rw-r--r--lib/inets/src/http_server/Makefile34
-rw-r--r--lib/inets/src/http_server/httpd.erl151
-rw-r--r--lib/inets/src/http_server/httpd.hrl19
-rw-r--r--lib/inets/src/http_server/httpd_acceptor.erl19
-rw-r--r--lib/inets/src/http_server/httpd_acceptor_sup.erl57
-rw-r--r--lib/inets/src/http_server/httpd_cgi.erl19
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl449
-rw-r--r--lib/inets/src/http_server/httpd_connection_sup.erl21
-rw-r--r--lib/inets/src/http_server/httpd_custom.erl52
-rw-r--r--lib/inets/src/http_server/httpd_custom_api.erl32
-rw-r--r--lib/inets/src/http_server/httpd_esi.erl19
-rw-r--r--lib/inets/src/http_server/httpd_example.erl53
-rw-r--r--lib/inets/src/http_server/httpd_file.erl21
-rw-r--r--lib/inets/src/http_server/httpd_instance_sup.erl79
-rw-r--r--lib/inets/src/http_server/httpd_internal.hrl21
-rw-r--r--lib/inets/src/http_server/httpd_log.erl21
-rw-r--r--lib/inets/src/http_server/httpd_manager.erl42
-rw-r--r--lib/inets/src/http_server/httpd_misc_sup.erl59
-rw-r--r--lib/inets/src/http_server/httpd_request.erl24
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl67
-rw-r--r--lib/inets/src/http_server/httpd_response.erl69
-rw-r--r--lib/inets/src/http_server/httpd_script_env.erl37
-rw-r--r--lib/inets/src/http_server/httpd_socket.erl21
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl121
-rw-r--r--lib/inets/src/http_server/httpd_util.erl91
-rw-r--r--lib/inets/src/http_server/mod_actions.erl41
-rw-r--r--lib/inets/src/http_server/mod_alias.erl95
-rw-r--r--lib/inets/src/http_server/mod_auth.erl703
-rw-r--r--lib/inets/src/http_server/mod_auth.hrl19
-rw-r--r--lib/inets/src/http_server/mod_auth_dets.erl67
-rw-r--r--lib/inets/src/http_server/mod_auth_mnesia.erl21
-rw-r--r--lib/inets/src/http_server/mod_auth_plain.erl219
-rw-r--r--lib/inets/src/http_server/mod_auth_server.erl261
-rw-r--r--lib/inets/src/http_server/mod_browser.erl42
-rw-r--r--lib/inets/src/http_server/mod_cgi.erl29
-rw-r--r--lib/inets/src/http_server/mod_dir.erl32
-rw-r--r--lib/inets/src/http_server/mod_disk_log.erl88
-rw-r--r--lib/inets/src/http_server/mod_esi.erl122
-rw-r--r--lib/inets/src/http_server/mod_get.erl21
-rw-r--r--lib/inets/src/http_server/mod_head.erl21
-rw-r--r--lib/inets/src/http_server/mod_htaccess.erl58
-rw-r--r--lib/inets/src/http_server/mod_include.erl598
-rw-r--r--lib/inets/src/http_server/mod_log.erl29
-rw-r--r--lib/inets/src/http_server/mod_range.erl21
-rw-r--r--lib/inets/src/http_server/mod_responsecontrol.erl21
-rw-r--r--lib/inets/src/http_server/mod_security.erl255
-rw-r--r--lib/inets/src/http_server/mod_security_server.erl380
-rw-r--r--lib/inets/src/http_server/mod_trace.erl21
-rw-r--r--lib/inets/src/inets_app/Makefile27
-rw-r--r--lib/inets/src/inets_app/inets.app.src27
-rw-r--r--lib/inets/src/inets_app/inets.appup.src21
-rw-r--r--lib/inets/src/inets_app/inets.erl21
-rw-r--r--lib/inets/src/inets_app/inets.mk19
-rw-r--r--lib/inets/src/inets_app/inets_app.erl21
-rw-r--r--lib/inets/src/inets_app/inets_internal.hrl21
-rw-r--r--lib/inets/src/inets_app/inets_lib.erl50
-rw-r--r--lib/inets/src/inets_app/inets_regexp.erl21
-rw-r--r--lib/inets/src/inets_app/inets_service.erl19
-rw-r--r--lib/inets/src/inets_app/inets_sup.erl21
-rw-r--r--lib/inets/src/inets_app/inets_time_compat.erl72
-rw-r--r--lib/inets/src/inets_app/inets_trace.erl53
-rw-r--r--lib/inets/src/tftp/Makefile19
-rw-r--r--lib/inets/src/tftp/tftp.erl21
-rw-r--r--lib/inets/src/tftp/tftp.hrl21
-rw-r--r--lib/inets/src/tftp/tftp_binary.erl21
-rw-r--r--lib/inets/src/tftp/tftp_engine.erl71
-rw-r--r--lib/inets/src/tftp/tftp_file.erl21
-rw-r--r--lib/inets/src/tftp/tftp_lib.erl25
-rw-r--r--lib/inets/src/tftp/tftp_logger.erl27
-rw-r--r--lib/inets/src/tftp/tftp_sup.erl25
-rw-r--r--lib/inets/test/Makefile26
-rw-r--r--lib/inets/test/erl_make_certs.erl29
-rw-r--r--lib/inets/test/ftp_SUITE.erl21
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl21
-rw-r--r--lib/inets/test/ftp_property_test_SUITE.erl21
-rw-r--r--lib/inets/test/ftp_suite_lib.erl29
-rw-r--r--lib/inets/test/http_format_SUITE.erl257
-rw-r--r--lib/inets/test/httpc_SUITE.erl179
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl19
-rw-r--r--lib/inets/test/httpc_proxy_SUITE.erl45
-rw-r--r--lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf19
-rwxr-xr-xlib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh21
-rw-r--r--lib/inets/test/httpd_1_0.erl21
-rw-r--r--lib/inets/test/httpd_1_1.erl74
-rw-r--r--lib/inets/test/httpd_SUITE.erl276
-rw-r--r--lib/inets/test/httpd_SUITE_data/Makefile.src5
-rw-r--r--lib/inets/test/httpd_SUITE_data/mime_types.txt100
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/config/mime.types4
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl21
-rw-r--r--lib/inets/test/httpd_block.erl21
-rw-r--r--lib/inets/test/httpd_load.erl21
-rw-r--r--lib/inets/test/httpd_mod.erl19
-rw-r--r--lib/inets/test/httpd_mod_SUITE.erl21
-rw-r--r--lib/inets/test/httpd_poll.erl25
-rw-r--r--lib/inets/test/httpd_test_data/server_root/Makefile19
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/httpd.conf21
-rw-r--r--lib/inets/test/httpd_test_lib.erl49
-rw-r--r--lib/inets/test/httpd_time_test.erl90
-rw-r--r--lib/inets/test/inets_SUITE.erl201
-rw-r--r--lib/inets/test/inets_app_test.erl88
-rw-r--r--lib/inets/test/inets_appup_test.erl21
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE.erl154
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src39
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c259
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl245
-rw-r--r--lib/inets/test/inets_test_lib.erl51
-rw-r--r--lib/inets/test/inets_test_lib.hrl19
-rw-r--r--lib/inets/test/old_httpd_SUITE.erl25
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/Makefile19
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf21
-rw-r--r--lib/inets/test/property_test/ftp_simple_client_server.erl21
-rw-r--r--lib/inets/test/tftp_SUITE.erl58
-rw-r--r--lib/inets/test/tftp_test_lib.erl21
-rw-r--r--lib/inets/test/tftp_test_lib.hrl21
-rw-r--r--lib/inets/test/uri_SUITE.erl42
-rw-r--r--lib/inets/vsn.mk23
-rw-r--r--lib/jinterface/.classpath6
-rw-r--r--lib/jinterface/.gitignore2
-rw-r--r--lib/jinterface/.project17
-rw-r--r--lib/jinterface/.settings/org.eclipse.jdt.core.prefs296
-rw-r--r--lib/jinterface/.settings/org.eclipse.jdt.ui.prefs121
-rw-r--r--lib/jinterface/Makefile21
-rw-r--r--lib/jinterface/doc/src/Makefile19
-rw-r--r--lib/jinterface/doc/src/book.xml21
-rw-r--r--lib/jinterface/doc/src/index.html.src21
-rw-r--r--lib/jinterface/doc/src/jinterface.xml21
-rw-r--r--lib/jinterface/doc/src/jinterface_users_guide.xml29
-rw-r--r--lib/jinterface/doc/src/notes.xml103
-rw-r--r--lib/jinterface/doc/src/notes_history.xml21
-rw-r--r--lib/jinterface/doc/src/part.xml21
-rw-r--r--lib/jinterface/doc/src/part_notes.xml21
-rw-r--r--lib/jinterface/doc/src/part_notes_history.xml21
-rw-r--r--lib/jinterface/doc/src/ref_man.xml21
-rw-r--r--lib/jinterface/java_src/Makefile21
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java2037
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java245
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/GenericQueue.java209
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java55
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/Links.java147
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile21
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpAuthException.java31
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java568
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java212
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java640
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java316
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java70
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java283
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java44
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java54
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java54
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java31
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java97
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangException.java31
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExit.java83
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExternalFun.java75
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java50
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java171
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java54
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java639
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java420
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java372
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java287
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java184
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java132
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRangeException.java31
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java222
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java55
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java148
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java294
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java62
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java62
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java31
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java27
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java1564
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpLocalNode.java155
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java451
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java665
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java226
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java1026
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNodeStatus.java91
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java1003
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpPeer.java86
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSelf.java302
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServer.java102
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerSocketTransport.java69
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerTransport.java47
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransport.java90
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransportFactory.java57
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSystem.java69
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransport.java50
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransportFactory.java125
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/java_files29
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src21
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src21
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/package.html21
-rw-r--r--lib/jinterface/priv/.gitignore0
-rw-r--r--lib/jinterface/test/.classpath8
-rw-r--r--lib/jinterface/test/.project17
-rw-r--r--lib/jinterface/test/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--lib/jinterface/test/Makefile19
-rw-r--r--lib/jinterface/test/jinterface.spec19
-rw-r--r--lib/jinterface/test/jinterface_SUITE.erl51
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/.gitignore1
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/CoreMatchBind.java585
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/FunEquals.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/GetNames.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Makefile.src23
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Maps.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxPing.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/NodePing.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Nodename.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java19
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/TransportFactoryTest.java91
-rw-r--r--lib/jinterface/test/jitu.erl24
-rw-r--r--lib/jinterface/test/nc_SUITE.erl21
-rw-r--r--lib/jinterface/test/nc_SUITE_data/.gitignore1
-rw-r--r--lib/jinterface/test/nc_SUITE_data/Makefile.src21
-rw-r--r--lib/jinterface/test/nc_SUITE_data/connection_server.java19
-rw-r--r--lib/jinterface/test/nc_SUITE_data/echo_server.java19
-rw-r--r--lib/jinterface/vsn.mk2
-rw-r--r--lib/kernel/Makefile21
-rw-r--r--lib/kernel/doc/src/Makefile19
-rw-r--r--lib/kernel/doc/src/app.xml25
-rw-r--r--lib/kernel/doc/src/application.xml24
-rw-r--r--lib/kernel/doc/src/auth.xml29
-rw-r--r--lib/kernel/doc/src/book.xml21
-rw-r--r--lib/kernel/doc/src/code.xml92
-rw-r--r--lib/kernel/doc/src/config.xml21
-rw-r--r--lib/kernel/doc/src/disk_log.xml31
-rw-r--r--lib/kernel/doc/src/erl_boot_server.xml21
-rw-r--r--lib/kernel/doc/src/erl_ddll.xml41
-rw-r--r--lib/kernel/doc/src/erl_prim_loader_stub.xml19
-rw-r--r--lib/kernel/doc/src/erlang_stub.xml19
-rw-r--r--lib/kernel/doc/src/error_handler.xml19
-rw-r--r--lib/kernel/doc/src/error_logger.xml54
-rw-r--r--lib/kernel/doc/src/file.xml62
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml33
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml41
-rw-r--r--lib/kernel/doc/src/gen_udp.xml25
-rw-r--r--lib/kernel/doc/src/global.xml21
-rw-r--r--lib/kernel/doc/src/global_group.xml21
-rw-r--r--lib/kernel/doc/src/heart.xml94
-rw-r--r--lib/kernel/doc/src/inet.xml84
-rw-r--r--lib/kernel/doc/src/inet_res.xml52
-rw-r--r--lib/kernel/doc/src/init_stub.xml19
-rw-r--r--lib/kernel/doc/src/kernel_app.xml58
-rw-r--r--lib/kernel/doc/src/net_adm.xml25
-rw-r--r--lib/kernel/doc/src/net_kernel.xml34
-rw-r--r--lib/kernel/doc/src/notes.xml356
-rw-r--r--lib/kernel/doc/src/notes_history.xml21
-rw-r--r--lib/kernel/doc/src/os.xml82
-rw-r--r--lib/kernel/doc/src/part_notes.xml21
-rw-r--r--lib/kernel/doc/src/part_notes_history.xml19
-rw-r--r--lib/kernel/doc/src/pg2.xml31
-rw-r--r--lib/kernel/doc/src/ref_man.xml19
-rw-r--r--lib/kernel/doc/src/ref_man.xml.src19
-rw-r--r--lib/kernel/doc/src/rpc.xml21
-rw-r--r--lib/kernel/doc/src/seq_trace.xml50
-rw-r--r--lib/kernel/doc/src/user.xml19
-rw-r--r--lib/kernel/doc/src/wrap_log_reader.xml21
-rw-r--r--lib/kernel/doc/src/zlib_stub.xml19
-rw-r--r--lib/kernel/examples/Makefile21
-rw-r--r--lib/kernel/examples/uds_dist/c_src/uds_drv.c33
-rw-r--r--lib/kernel/examples/uds_dist/src/uds_dist.erl21
-rw-r--r--lib/kernel/include/dist.hrl21
-rw-r--r--lib/kernel/include/dist_util.hrl21
-rw-r--r--lib/kernel/include/file.hrl19
-rw-r--r--lib/kernel/include/inet.hrl21
-rw-r--r--lib/kernel/include/inet_sctp.hrl21
-rw-r--r--lib/kernel/include/net_address.hrl21
-rw-r--r--lib/kernel/src/Makefile19
-rw-r--r--lib/kernel/src/application.erl21
-rw-r--r--lib/kernel/src/application_controller.erl22
-rw-r--r--lib/kernel/src/application_master.erl21
-rw-r--r--lib/kernel/src/application_master.hrl21
-rw-r--r--lib/kernel/src/application_starter.erl19
-rw-r--r--lib/kernel/src/auth.erl23
-rw-r--r--lib/kernel/src/code.erl88
-rw-r--r--lib/kernel/src/code_server.erl100
-rw-r--r--lib/kernel/src/disk_log.erl21
-rw-r--r--lib/kernel/src/disk_log.hrl19
-rw-r--r--lib/kernel/src/disk_log_1.erl25
-rw-r--r--lib/kernel/src/disk_log_server.erl21
-rw-r--r--lib/kernel/src/disk_log_sup.erl21
-rw-r--r--lib/kernel/src/dist_ac.erl21
-rw-r--r--lib/kernel/src/dist_util.erl25
-rw-r--r--lib/kernel/src/erl_boot_server.erl19
-rw-r--r--lib/kernel/src/erl_ddll.erl19
-rw-r--r--lib/kernel/src/erl_distribution.erl21
-rw-r--r--lib/kernel/src/erl_epmd.erl37
-rw-r--r--lib/kernel/src/erl_epmd.hrl21
-rw-r--r--lib/kernel/src/erl_reply.erl21
-rw-r--r--lib/kernel/src/error_handler.erl19
-rw-r--r--lib/kernel/src/error_logger.erl21
-rw-r--r--lib/kernel/src/erts_debug.erl85
-rw-r--r--lib/kernel/src/file.erl43
-rw-r--r--lib/kernel/src/file_io_server.erl255
-rw-r--r--lib/kernel/src/file_server.erl19
-rw-r--r--lib/kernel/src/gen_sctp.erl19
-rw-r--r--lib/kernel/src/gen_tcp.erl26
-rw-r--r--lib/kernel/src/gen_udp.erl21
-rw-r--r--lib/kernel/src/global.erl37
-rw-r--r--lib/kernel/src/global_group.erl21
-rw-r--r--lib/kernel/src/global_search.erl21
-rw-r--r--lib/kernel/src/group.erl167
-rw-r--r--lib/kernel/src/heart.erl206
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl256
-rw-r--r--lib/kernel/src/inet.erl72
-rw-r--r--lib/kernel/src/inet6_sctp.erl21
-rw-r--r--lib/kernel/src/inet6_tcp.erl40
-rw-r--r--lib/kernel/src/inet6_tcp_dist.erl384
-rw-r--r--lib/kernel/src/inet6_udp.erl21
-rw-r--r--lib/kernel/src/inet_boot.hrl21
-rw-r--r--lib/kernel/src/inet_config.erl38
-rw-r--r--lib/kernel/src/inet_config.hrl21
-rw-r--r--lib/kernel/src/inet_db.erl60
-rw-r--r--lib/kernel/src/inet_dns.erl21
-rw-r--r--lib/kernel/src/inet_dns.hrl21
-rw-r--r--lib/kernel/src/inet_dns_record_adts.pl27
-rw-r--r--lib/kernel/src/inet_gethost_native.erl19
-rw-r--r--lib/kernel/src/inet_hosts.erl21
-rw-r--r--lib/kernel/src/inet_int.hrl23
-rw-r--r--lib/kernel/src/inet_parse.erl47
-rw-r--r--lib/kernel/src/inet_res.erl33
-rw-r--r--lib/kernel/src/inet_res.hrl21
-rw-r--r--lib/kernel/src/inet_sctp.erl38
-rw-r--r--lib/kernel/src/inet_tcp.erl37
-rw-r--r--lib/kernel/src/inet_tcp_dist.erl180
-rw-r--r--lib/kernel/src/inet_udp.erl21
-rw-r--r--lib/kernel/src/kernel.app.src25
-rw-r--r--lib/kernel/src/kernel.appup.src29
-rw-r--r--lib/kernel/src/kernel.erl27
-rw-r--r--lib/kernel/src/kernel_config.erl19
-rw-r--r--lib/kernel/src/net.erl21
-rw-r--r--lib/kernel/src/net_adm.erl21
-rw-r--r--lib/kernel/src/net_kernel.erl19
-rw-r--r--lib/kernel/src/os.erl51
-rw-r--r--lib/kernel/src/pg2.erl30
-rw-r--r--lib/kernel/src/ram_file.erl19
-rw-r--r--lib/kernel/src/rpc.erl21
-rw-r--r--lib/kernel/src/seq_trace.erl35
-rw-r--r--lib/kernel/src/standard_error.erl19
-rw-r--r--lib/kernel/src/user.erl19
-rw-r--r--lib/kernel/src/user_drv.erl161
-rw-r--r--lib/kernel/src/user_sup.erl21
-rw-r--r--lib/kernel/src/wrap_log_reader.erl19
-rw-r--r--lib/kernel/test/Makefile19
-rw-r--r--lib/kernel/test/appinc1.erl21
-rw-r--r--lib/kernel/test/appinc1x.erl21
-rw-r--r--lib/kernel/test/appinc2.erl21
-rw-r--r--lib/kernel/test/appinc2A.erl21
-rw-r--r--lib/kernel/test/appinc2B.erl21
-rw-r--r--lib/kernel/test/appinc2top.erl21
-rw-r--r--lib/kernel/test/application_SUITE.erl26
-rw-r--r--lib/kernel/test/application_SUITE_data/app_start_error.erl21
-rw-r--r--lib/kernel/test/application_SUITE_data/group_leader.erl21
-rw-r--r--lib/kernel/test/application_SUITE_data/group_leader_sup.erl21
-rw-r--r--lib/kernel/test/application_SUITE_data/trans_abnormal_sup.erl21
-rw-r--r--lib/kernel/test/application_SUITE_data/trans_normal_sup.erl21
-rw-r--r--lib/kernel/test/application_SUITE_data/transient.erl21
-rw-r--r--lib/kernel/test/bif_SUITE.erl29
-rw-r--r--lib/kernel/test/ch.erl21
-rw-r--r--lib/kernel/test/ch_sup.erl21
-rw-r--r--lib/kernel/test/cleanup.erl19
-rw-r--r--lib/kernel/test/code_SUITE.erl74
-rw-r--r--lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict.erl21
-rw-r--r--lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_app.erl21
-rw-r--r--lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_sup.erl21
-rw-r--r--lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-b/ebin/lists.erl21
-rw-r--r--lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-c/ebin/code_SUITE_mult_root_module.erl21
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load_errors/simple_on_load_error.erl5
-rw-r--r--lib/kernel/test/code_a_test.erl21
-rw-r--r--lib/kernel/test/code_b_test.erl21
-rw-r--r--lib/kernel/test/disk_log_SUITE.erl19
-rw-r--r--lib/kernel/test/disk_log_SUITE_data/wrap_log_test.erl21
-rw-r--r--lib/kernel/test/erl_boot_server_SUITE.erl21
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl67
-rw-r--r--lib/kernel/test/erl_distribution_wb_SUITE.erl36
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl19
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict.erl21
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_app.erl21
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_sup.erl21
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy.erl21
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_app.erl21
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_sup.erl21
-rw-r--r--lib/kernel/test/error_handler_SUITE.erl19
-rw-r--r--lib/kernel/test/error_logger_SUITE.erl41
-rw-r--r--lib/kernel/test/error_logger_warn_SUITE.erl502
-rw-r--r--lib/kernel/test/file_SUITE.erl250
-rw-r--r--lib/kernel/test/file_name_SUITE.erl19
-rw-r--r--lib/kernel/test/gen_sctp_SUITE.erl19
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE.erl72
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c19
-rw-r--r--lib/kernel/test/gen_tcp_echo_SUITE.erl21
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl2037
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl21
-rw-r--r--lib/kernel/test/global_SUITE.erl19
-rw-r--r--lib/kernel/test/global_SUITE_data/global_trace.erl21
-rw-r--r--lib/kernel/test/global_group_SUITE.erl19
-rw-r--r--lib/kernel/test/heart_SUITE.erl94
-rw-r--r--lib/kernel/test/ignore_cores.erl19
-rw-r--r--lib/kernel/test/inet_SUITE.erl77
-rw-r--r--lib/kernel/test/inet_res_SUITE.erl19
-rwxr-xr-xlib/kernel/test/inet_res_SUITE_data/run-named21
-rw-r--r--lib/kernel/test/inet_sockopt_SUITE.erl103
-rw-r--r--lib/kernel/test/init_SUITE.erl19
-rw-r--r--lib/kernel/test/interactive_shell_SUITE.erl31
-rw-r--r--lib/kernel/test/kernel_SUITE.erl19
-rw-r--r--lib/kernel/test/kernel_config_SUITE.erl19
-rw-r--r--lib/kernel/test/loose_node.erl21
-rw-r--r--lib/kernel/test/myApp.erl21
-rw-r--r--lib/kernel/test/os_SUITE.erl19
-rw-r--r--lib/kernel/test/pdict_SUITE.erl52
-rw-r--r--lib/kernel/test/pg2_SUITE.erl19
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl19
-rw-r--r--lib/kernel/test/ram_file_SUITE.erl19
-rw-r--r--lib/kernel/test/rpc_SUITE.erl60
-rw-r--r--lib/kernel/test/sendfile_SUITE.erl19
-rw-r--r--lib/kernel/test/seq_trace_SUITE.erl185
-rw-r--r--lib/kernel/test/standard_error_SUITE.erl50
-rw-r--r--lib/kernel/test/topApp.erl21
-rw-r--r--lib/kernel/test/topApp2.erl21
-rw-r--r--lib/kernel/test/topApp3.erl21
-rw-r--r--lib/kernel/test/wrap_log_reader_SUITE.erl19
-rw-r--r--lib/kernel/test/wrap_log_reader_SUITE_data/wrap_log_test.erl21
-rw-r--r--lib/kernel/test/zlib_SUITE.erl62
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/Makefile21
-rw-r--r--lib/megaco/configure.in19
-rw-r--r--lib/megaco/doc/src/Makefile19
-rw-r--r--lib/megaco/doc/src/book.xml21
-rw-r--r--lib/megaco/doc/src/files.mk19
-rw-r--r--lib/megaco/doc/src/index.html.src21
-rw-r--r--lib/megaco/doc/src/megaco.xml25
-rw-r--r--lib/megaco/doc/src/megaco_architecture.xml21
-rw-r--r--lib/megaco/doc/src/megaco_codec_meas.xml21
-rw-r--r--lib/megaco/doc/src/megaco_codec_mstone1.xml21
-rw-r--r--lib/megaco/doc/src/megaco_codec_mstone2.xml21
-rw-r--r--lib/megaco/doc/src/megaco_codec_transform.xml19
-rw-r--r--lib/megaco/doc/src/megaco_debug.xml19
-rw-r--r--lib/megaco/doc/src/megaco_edist_compress.xml21
-rw-r--r--lib/megaco/doc/src/megaco_encode.xml21
-rw-r--r--lib/megaco/doc/src/megaco_encoder.xml21
-rw-r--r--lib/megaco/doc/src/megaco_examples.xml21
-rw-r--r--lib/megaco/doc/src/megaco_flex_scanner.xml21
-rw-r--r--lib/megaco/doc/src/megaco_intro.xml21
-rw-r--r--lib/megaco/doc/src/megaco_mib.xml19
-rw-r--r--lib/megaco/doc/src/megaco_performance.xml19
-rw-r--r--lib/megaco/doc/src/megaco_run.xml19
-rw-r--r--lib/megaco/doc/src/megaco_tcp.xml21
-rw-r--r--lib/megaco/doc/src/megaco_transport.xml21
-rw-r--r--lib/megaco/doc/src/megaco_transport_mechanisms.xml21
-rw-r--r--lib/megaco/doc/src/megaco_udp.xml21
-rw-r--r--lib/megaco/doc/src/megaco_user.xml21
-rw-r--r--lib/megaco/doc/src/notes.xml38
-rw-r--r--lib/megaco/doc/src/notes_history.xml21
-rw-r--r--lib/megaco/doc/src/part.xml21
-rw-r--r--lib/megaco/doc/src/part_notes.xml21
-rw-r--r--lib/megaco/doc/src/part_notes_history.xml21
-rw-r--r--lib/megaco/doc/src/ref_man.xml21
-rw-r--r--lib/megaco/examples/meas/Makefile.in21
-rw-r--r--lib/megaco/examples/meas/meas.sh.skel.src19
-rw-r--r--lib/megaco/examples/meas/megaco_codec_meas.erl21
-rw-r--r--lib/megaco/examples/meas/megaco_codec_mstone1.erl21
-rw-r--r--lib/megaco/examples/meas/megaco_codec_mstone2.erl21
-rw-r--r--lib/megaco/examples/meas/megaco_codec_mstone_lib.erl21
-rw-r--r--lib/megaco/examples/meas/megaco_codec_transform.erl21
-rw-r--r--lib/megaco/examples/meas/modules.mk21
-rw-r--r--lib/megaco/examples/meas/mstone1.sh.skel.src21
-rw-r--r--lib/megaco/examples/simple/Makefile21
-rw-r--r--lib/megaco/examples/simple/megaco_simple_mg.erl21
-rw-r--r--lib/megaco/examples/simple/megaco_simple_mgc.erl21
-rw-r--r--lib/megaco/examples/simple/modules.mk21
-rw-r--r--lib/megaco/include/megaco.hrl19
-rw-r--r--lib/megaco/include/megaco_message_prev3a.hrl19
-rw-r--r--lib/megaco/include/megaco_message_prev3b.hrl19
-rw-r--r--lib/megaco/include/megaco_message_prev3c.hrl19
-rw-r--r--lib/megaco/include/megaco_message_v1.hrl19
-rw-r--r--lib/megaco/include/megaco_message_v2.hrl19
-rw-r--r--lib/megaco/include/megaco_message_v3.hrl19
-rw-r--r--lib/megaco/include/megaco_sdp.hrl21
-rw-r--r--lib/megaco/src/Makefile21
-rw-r--r--lib/megaco/src/app/Makefile21
-rw-r--r--lib/megaco/src/app/depend.mk21
-rw-r--r--lib/megaco/src/app/megaco.app.src27
-rw-r--r--lib/megaco/src/app/megaco.appup.src26
-rw-r--r--lib/megaco/src/app/megaco.erl21
-rw-r--r--lib/megaco/src/app/megaco.mk21
-rw-r--r--lib/megaco/src/app/megaco_internal.hrl19
-rw-r--r--lib/megaco/src/app/modules.mk21
-rw-r--r--lib/megaco/src/binary/Makefile21
-rw-r--r--lib/megaco/src/binary/depend.mk21
-rw-r--r--lib/megaco/src/binary/megaco_ber_encoder.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder_lib.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_term_id.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_term_id_gen.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_v1.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_v2.erl21
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_v3.erl21
-rw-r--r--lib/megaco/src/binary/megaco_per_encoder.erl21
-rw-r--r--lib/megaco/src/binary/modules.mk21
-rw-r--r--lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl21
-rw-r--r--lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl21
-rw-r--r--lib/megaco/src/engine/Makefile21
-rw-r--r--lib/megaco/src/engine/depend.mk21
-rw-r--r--lib/megaco/src/engine/megaco_config.erl19
-rw-r--r--lib/megaco/src/engine/megaco_config_misc.erl19
-rw-r--r--lib/megaco/src/engine/megaco_digit_map.erl21
-rw-r--r--lib/megaco/src/engine/megaco_edist_compress.erl21
-rw-r--r--lib/megaco/src/engine/megaco_encoder.erl21
-rw-r--r--lib/megaco/src/engine/megaco_erl_dist_encoder.erl21
-rw-r--r--lib/megaco/src/engine/megaco_erl_dist_encoder_mc.erl21
-rw-r--r--lib/megaco/src/engine/megaco_filter.erl19
-rw-r--r--lib/megaco/src/engine/megaco_message_internal.hrl21
-rw-r--r--lib/megaco/src/engine/megaco_messenger.erl19
-rw-r--r--lib/megaco/src/engine/megaco_messenger_misc.erl21
-rw-r--r--lib/megaco/src/engine/megaco_misc_sup.erl21
-rw-r--r--lib/megaco/src/engine/megaco_monitor.erl19
-rw-r--r--lib/megaco/src/engine/megaco_sdp.erl21
-rw-r--r--lib/megaco/src/engine/megaco_stats.erl21
-rw-r--r--lib/megaco/src/engine/megaco_sup.erl21
-rw-r--r--lib/megaco/src/engine/megaco_timer.erl21
-rw-r--r--lib/megaco/src/engine/megaco_trans_sender.erl24
-rw-r--r--lib/megaco/src/engine/megaco_trans_sup.erl21
-rw-r--r--lib/megaco/src/engine/megaco_transport.erl21
-rw-r--r--lib/megaco/src/engine/megaco_user_default.erl21
-rw-r--r--lib/megaco/src/engine/modules.mk21
-rw-r--r--lib/megaco/src/flex/Makefile21
-rw-r--r--lib/megaco/src/flex/Makefile.in19
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner.erl21
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src51
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_handler.erl19
-rw-r--r--lib/megaco/src/flex/modules.mk21
-rw-r--r--lib/megaco/src/rules.mk21
-rw-r--r--lib/megaco/src/subdirs.mk21
-rw-r--r--lib/megaco/src/tcp/Makefile21
-rw-r--r--lib/megaco/src/tcp/depend.mk21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp.erl21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp.hrl21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp_accept.erl21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp_accept_sup.erl21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp_connection.erl21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp_connection_sup.erl21
-rw-r--r--lib/megaco/src/tcp/megaco_tcp_sup.erl21
-rw-r--r--lib/megaco/src/tcp/modules.mk21
-rw-r--r--lib/megaco/src/text/Makefile21
-rw-r--r--lib/megaco/src/text/depend.mk21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder.erl21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder_prev3a.erl21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder_prev3b.erl21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder_prev3c.erl21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder_v1.erl21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder_v2.erl21
-rw-r--r--lib/megaco/src/text/megaco_compact_text_encoder_v3.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder_prev3a.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder_prev3b.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder_prev3c.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder_v1.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder_v2.erl21
-rw-r--r--lib/megaco/src/text/megaco_pretty_text_encoder_v3.erl21
-rw-r--r--lib/megaco/src/text/megaco_text_gen_prev3a.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_gen_prev3b.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_gen_prev3c.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_gen_v1.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_gen_v2.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_gen_v3.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_mini_decoder.erl21
-rw-r--r--lib/megaco/src/text/megaco_text_mini_parser.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_mini_parser.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_prev3a.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_prev3a.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_prev3b.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_prev3b.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_prev3c.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_prev3c.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_v1.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_v1.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_v2.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_v2.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_v3.hrl21
-rw-r--r--lib/megaco/src/text/megaco_text_parser_v3.yrl21
-rw-r--r--lib/megaco/src/text/megaco_text_scanner.erl21
-rw-r--r--lib/megaco/src/text/megaco_text_tokens.hrl21
-rw-r--r--lib/megaco/src/text/modules.mk21
-rw-r--r--lib/megaco/src/udp/Makefile21
-rw-r--r--lib/megaco/src/udp/megaco_udp.erl21
-rw-r--r--lib/megaco/src/udp/megaco_udp.hrl21
-rw-r--r--lib/megaco/src/udp/megaco_udp_server.erl21
-rw-r--r--lib/megaco/src/udp/megaco_udp_sup.erl21
-rw-r--r--lib/megaco/src/udp/modules.mk21
-rw-r--r--lib/megaco/subdirs.mk21
-rw-r--r--lib/megaco/test/Makefile19
-rw-r--r--lib/megaco/test/megaco_SUITE.erl21
-rw-r--r--lib/megaco/test/megaco_actions_test.erl21
-rw-r--r--lib/megaco/test/megaco_app_test.erl19
-rw-r--r--lib/megaco/test/megaco_appup_mg.erl21
-rw-r--r--lib/megaco/test/megaco_appup_mgc.erl21
-rw-r--r--lib/megaco/test/megaco_appup_test.erl21
-rw-r--r--lib/megaco/test/megaco_binary_term_id_test.erl21
-rw-r--r--lib/megaco/test/megaco_call_flow_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_flex_lib.erl21
-rw-r--r--lib/megaco/test/megaco_codec_mini_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_prev3a_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_prev3b_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_prev3c_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_test_lib.erl21
-rw-r--r--lib/megaco/test/megaco_codec_v1_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_v2_test.erl21
-rw-r--r--lib/megaco/test/megaco_codec_v3_test.erl21
-rw-r--r--lib/megaco/test/megaco_config_test.erl19
-rw-r--r--lib/megaco/test/megaco_digit_map_test.erl21
-rw-r--r--lib/megaco/test/megaco_examples_test.erl21
-rw-r--r--lib/megaco/test/megaco_flex_test.erl21
-rw-r--r--lib/megaco/test/megaco_load_test.erl21
-rw-r--r--lib/megaco/test/megaco_mess_otp8212_test.erl21
-rw-r--r--lib/megaco/test/megaco_mess_test.erl21
-rw-r--r--lib/megaco/test/megaco_mess_user_test.erl21
-rw-r--r--lib/megaco/test/megaco_mib_test.erl21
-rw-r--r--lib/megaco/test/megaco_mreq_test.erl21
-rw-r--r--lib/megaco/test/megaco_pending_limit_test.erl21
-rw-r--r--lib/megaco/test/megaco_profile.erl21
-rw-r--r--lib/megaco/test/megaco_sdp_test.erl21
-rw-r--r--lib/megaco/test/megaco_segment_test.erl21
-rw-r--r--lib/megaco/test/megaco_tc_controller.erl21
-rw-r--r--lib/megaco/test/megaco_tcp_test.erl21
-rw-r--r--lib/megaco/test/megaco_test_deliver.erl21
-rw-r--r--lib/megaco/test/megaco_test_generator.erl21
-rw-r--r--lib/megaco/test/megaco_test_generator_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_generic_transport.erl21
-rw-r--r--lib/megaco/test/megaco_test_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_lib.hrl21
-rw-r--r--lib/megaco/test/megaco_test_megaco_generator.erl21
-rw-r--r--lib/megaco/test/megaco_test_mg.erl21
-rw-r--r--lib/megaco/test/megaco_test_mgc.erl21
-rw-r--r--lib/megaco/test/megaco_test_msg_prev3a_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_msg_prev3b_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_msg_prev3c_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_msg_v1_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_msg_v2_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_msg_v3_lib.erl21
-rw-r--r--lib/megaco/test/megaco_test_tcp_generator.erl21
-rw-r--r--lib/megaco/test/megaco_timer_test.erl21
-rw-r--r--lib/megaco/test/megaco_trans_test.erl21
-rw-r--r--lib/megaco/test/megaco_udp_test.erl21
-rw-r--r--lib/megaco/test/modules.mk19
-rw-r--r--lib/megaco/vsn.mk23
-rw-r--r--lib/mnesia/Makefile21
-rw-r--r--lib/mnesia/doc/misc/Makefile21
-rw-r--r--lib/mnesia/doc/src/Makefile22
-rw-r--r--lib/mnesia/doc/src/Mnesia_App_A.xml87
-rw-r--r--lib/mnesia/doc/src/Mnesia_App_A.xmlsrc41
-rw-r--r--lib/mnesia/doc/src/Mnesia_App_B.xmlsrc43
-rw-r--r--lib/mnesia/doc/src/Mnesia_App_C.xmlsrc31
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap1.xml296
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap2.xmlsrc580
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap3.xml556
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap3.xmlsrc521
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap4.xmlsrc1478
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap5.xmlsrc1672
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap7.xmlsrc1311
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap8.xml52
-rw-r--r--lib/mnesia/doc/src/Mnesia_overview.xml193
-rw-r--r--lib/mnesia/doc/src/book.xml21
-rw-r--r--lib/mnesia/doc/src/bup.erl21
-rw-r--r--lib/mnesia/doc/src/company.erl19
-rw-r--r--lib/mnesia/doc/src/company.hrl21
-rw-r--r--lib/mnesia/doc/src/company_o.erl19
-rw-r--r--lib/mnesia/doc/src/company_o.hrl21
-rw-r--r--lib/mnesia/doc/src/mnesia.xml3572
-rw-r--r--lib/mnesia/doc/src/mnesia_frag_hash.xml110
-rw-r--r--lib/mnesia/doc/src/mnesia_registry.xml104
-rw-r--r--lib/mnesia/doc/src/notes.xml126
-rw-r--r--lib/mnesia/doc/src/notes_history.xml21
-rw-r--r--lib/mnesia/doc/src/part.xml29
-rw-r--r--lib/mnesia/doc/src/part_notes.xml21
-rw-r--r--lib/mnesia/doc/src/part_notes_history.xml19
-rw-r--r--lib/mnesia/doc/src/ref_man.xml27
-rw-r--r--lib/mnesia/examples/Makefile21
-rw-r--r--lib/mnesia/examples/bench/bench.erl21
-rw-r--r--lib/mnesia/examples/bench/bench.hrl21
-rw-r--r--lib/mnesia/examples/bench/bench_generate.erl61
-rw-r--r--lib/mnesia/examples/bench/bench_populate.erl21
-rw-r--r--lib/mnesia/examples/bench/bench_trans.erl21
-rw-r--r--lib/mnesia/examples/mnesia_meter.erl19
-rw-r--r--lib/mnesia/examples/mnesia_tpcb.erl60
-rw-r--r--lib/mnesia/include/Makefile21
-rw-r--r--lib/mnesia/src/Makefile21
-rw-r--r--lib/mnesia/src/mnesia.app.src2
-rw-r--r--lib/mnesia/src/mnesia.erl81
-rw-r--r--lib/mnesia/src/mnesia.hrl32
-rw-r--r--lib/mnesia/src/mnesia_backup.erl21
-rw-r--r--lib/mnesia/src/mnesia_bup.erl264
-rw-r--r--lib/mnesia/src/mnesia_checkpoint.erl61
-rw-r--r--lib/mnesia/src/mnesia_checkpoint_sup.erl21
-rw-r--r--lib/mnesia/src/mnesia_controller.erl114
-rw-r--r--lib/mnesia/src/mnesia_dumper.erl176
-rw-r--r--lib/mnesia/src/mnesia_event.erl24
-rw-r--r--lib/mnesia/src/mnesia_frag.erl80
-rw-r--r--lib/mnesia/src/mnesia_frag_hash.erl21
-rw-r--r--lib/mnesia/src/mnesia_frag_old_hash.erl21
-rw-r--r--lib/mnesia/src/mnesia_index.erl60
-rw-r--r--lib/mnesia/src/mnesia_kernel_sup.erl21
-rw-r--r--lib/mnesia/src/mnesia_late_loader.erl27
-rw-r--r--lib/mnesia/src/mnesia_lib.erl158
-rw-r--r--lib/mnesia/src/mnesia_loader.erl125
-rw-r--r--lib/mnesia/src/mnesia_locker.erl58
-rw-r--r--lib/mnesia/src/mnesia_log.erl75
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl69
-rw-r--r--lib/mnesia/src/mnesia_recover.erl55
-rw-r--r--lib/mnesia/src/mnesia_registry.erl21
-rw-r--r--lib/mnesia/src/mnesia_schema.erl253
-rw-r--r--lib/mnesia/src/mnesia_snmp_hook.erl38
-rw-r--r--lib/mnesia/src/mnesia_snmp_sup.erl21
-rw-r--r--lib/mnesia/src/mnesia_sp.erl21
-rw-r--r--lib/mnesia/src/mnesia_subscr.erl52
-rw-r--r--lib/mnesia/src/mnesia_sup.erl21
-rw-r--r--lib/mnesia/src/mnesia_text.erl43
-rw-r--r--lib/mnesia/src/mnesia_tm.erl226
-rw-r--r--lib/mnesia/test/Makefile21
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl19
-rw-r--r--lib/mnesia/test/mnesia_atomicity_test.erl23
-rw-r--r--lib/mnesia/test/mnesia_bench_SUITE.erl19
-rw-r--r--lib/mnesia/test/mnesia_config_backup.erl24
-rw-r--r--lib/mnesia/test/mnesia_config_event.erl21
-rw-r--r--lib/mnesia/test/mnesia_config_test.erl45
-rw-r--r--lib/mnesia/test/mnesia_consistency_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_cost.erl31
-rw-r--r--lib/mnesia/test/mnesia_dbn_meters.erl74
-rw-r--r--lib/mnesia/test/mnesia_dirty_access_test.erl38
-rw-r--r--lib/mnesia/test/mnesia_durability_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_evil_backup.erl50
-rw-r--r--lib/mnesia/test/mnesia_evil_coverage_test.erl25
-rw-r--r--lib/mnesia/test/mnesia_examples_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_frag_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_inconsistent_database_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_install_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl96
-rw-r--r--lib/mnesia/test/mnesia_majority_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_meter.erl19
-rw-r--r--lib/mnesia/test/mnesia_nice_coverage_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_qlc_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_recovery_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_registry_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_schema_recovery_test.erl19
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl23
-rw-r--r--lib/mnesia/test/mnesia_test_lib.hrl19
-rw-r--r--lib/mnesia/test/mnesia_tpcb.erl92
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl25
-rwxr-xr-xlib/mnesia/test/mt21
-rw-r--r--lib/mnesia/test/mt.erl19
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/Makefile21
-rw-r--r--lib/observer/doc/src/Makefile21
-rw-r--r--lib/observer/doc/src/book.xml21
-rw-r--r--lib/observer/doc/src/cdv.xml33
-rw-r--r--lib/observer/doc/src/crashdump.xml40
-rw-r--r--lib/observer/doc/src/crashdump_ug.xml469
-rw-r--r--lib/observer/doc/src/etop.xml156
-rw-r--r--lib/observer/doc/src/etop_ug.xml139
-rw-r--r--lib/observer/doc/src/introduction_ug.xml49
-rw-r--r--lib/observer/doc/src/notes.xml125
-rw-r--r--lib/observer/doc/src/notes_history.xml21
-rw-r--r--lib/observer/doc/src/observer.xml42
-rw-r--r--lib/observer/doc/src/observer_app.xml39
-rw-r--r--lib/observer/doc/src/observer_ug.xml321
-rw-r--r--lib/observer/doc/src/part.xml24
-rw-r--r--lib/observer/doc/src/part_notes.xml21
-rw-r--r--lib/observer/doc/src/part_notes_history.xml19
-rw-r--r--lib/observer/doc/src/ref_man.xml26
-rw-r--r--lib/observer/doc/src/ttb.xml535
-rw-r--r--lib/observer/doc/src/ttb_ug.xml1054
-rw-r--r--lib/observer/include/etop.hrl21
-rw-r--r--lib/observer/src/Makefile21
-rw-r--r--lib/observer/src/cdv_atom_cb.erl19
-rw-r--r--lib/observer/src/cdv_bin_cb.erl25
-rw-r--r--lib/observer/src/cdv_detail_wx.erl29
-rw-r--r--lib/observer/src/cdv_dist_cb.erl25
-rw-r--r--lib/observer/src/cdv_ets_cb.erl92
-rw-r--r--lib/observer/src/cdv_fun_cb.erl21
-rw-r--r--lib/observer/src/cdv_gen_cb.erl23
-rw-r--r--lib/observer/src/cdv_html_wx.erl21
-rw-r--r--lib/observer/src/cdv_info_wx.erl19
-rw-r--r--lib/observer/src/cdv_int_tab_cb.erl19
-rw-r--r--lib/observer/src/cdv_mem_cb.erl19
-rw-r--r--lib/observer/src/cdv_mod_cb.erl25
-rw-r--r--lib/observer/src/cdv_multi_wx.erl19
-rw-r--r--lib/observer/src/cdv_port_cb.erl27
-rw-r--r--lib/observer/src/cdv_proc_cb.erl30
-rw-r--r--lib/observer/src/cdv_sched_cb.erl118
-rw-r--r--lib/observer/src/cdv_table_wx.erl19
-rw-r--r--lib/observer/src/cdv_term_cb.erl23
-rw-r--r--lib/observer/src/cdv_timer_cb.erl21
-rw-r--r--lib/observer/src/cdv_virtual_list_wx.erl116
-rw-r--r--lib/observer/src/cdv_wx.erl29
-rw-r--r--lib/observer/src/crashdump_viewer.erl226
-rw-r--r--lib/observer/src/crashdump_viewer.hrl49
-rw-r--r--lib/observer/src/etop.erl21
-rw-r--r--lib/observer/src/etop_defs.hrl21
-rw-r--r--lib/observer/src/etop_tr.erl21
-rw-r--r--lib/observer/src/etop_txt.erl21
-rw-r--r--lib/observer/src/multitrace.erl21
-rw-r--r--lib/observer/src/observer.app.src25
-rw-r--r--lib/observer/src/observer.appup.src21
-rw-r--r--lib/observer/src/observer.erl19
-rw-r--r--lib/observer/src/observer_alloc_wx.erl257
-rw-r--r--lib/observer/src/observer_app_wx.erl19
-rw-r--r--lib/observer/src/observer_defs.hrl19
-rw-r--r--lib/observer/src/observer_html_lib.erl35
-rw-r--r--lib/observer/src/observer_lib.erl32
-rw-r--r--lib/observer/src/observer_perf_wx.erl292
-rw-r--r--lib/observer/src/observer_pro_wx.erl21
-rw-r--r--lib/observer/src/observer_procinfo.erl97
-rw-r--r--lib/observer/src/observer_sys_wx.erl112
-rw-r--r--lib/observer/src/observer_trace_wx.erl19
-rw-r--r--lib/observer/src/observer_traceoptions_wx.erl23
-rw-r--r--lib/observer/src/observer_tv.hrl19
-rw-r--r--lib/observer/src/observer_tv_table.erl22
-rw-r--r--lib/observer/src/observer_tv_wx.erl33
-rw-r--r--lib/observer/src/observer_wx.erl154
-rw-r--r--lib/observer/src/ttb.erl23
-rw-r--r--lib/observer/src/ttb_et.erl21
-rw-r--r--lib/observer/test/Makefile21
-rw-r--r--lib/observer/test/crashdump_helper.erl19
-rw-r--r--lib/observer/test/crashdump_viewer_SUITE.erl75
-rw-r--r--lib/observer/test/etop_SUITE.erl19
-rw-r--r--lib/observer/test/observer_SUITE.erl54
-rw-r--r--lib/observer/test/ttb_SUITE.erl19
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/odbc/Makefile21
-rw-r--r--lib/odbc/c_src/Makefile21
-rw-r--r--lib/odbc/c_src/Makefile.in19
-rw-r--r--lib/odbc/c_src/odbcserver.c19
-rw-r--r--lib/odbc/c_src/odbcserver.h19
-rw-r--r--lib/odbc/configure.in19
-rw-r--r--lib/odbc/doc/src/Makefile19
-rw-r--r--lib/odbc/doc/src/book.xml21
-rw-r--r--lib/odbc/doc/src/databases.xml19
-rw-r--r--lib/odbc/doc/src/error_handling.xml19
-rw-r--r--lib/odbc/doc/src/getting_started.xml19
-rw-r--r--lib/odbc/doc/src/introduction.xml21
-rw-r--r--lib/odbc/doc/src/notes.xml63
-rw-r--r--lib/odbc/doc/src/notes_history.xml21
-rw-r--r--lib/odbc/doc/src/odbc.xml31
-rw-r--r--lib/odbc/doc/src/part.xml21
-rw-r--r--lib/odbc/doc/src/part_notes.xml21
-rw-r--r--lib/odbc/doc/src/part_notes_history.xml21
-rw-r--r--lib/odbc/doc/src/ref_man.xml21
-rw-r--r--lib/odbc/include/odbc.hrl21
-rw-r--r--lib/odbc/src/Makefile21
-rw-r--r--lib/odbc/src/odbc.appup.src19
-rw-r--r--lib/odbc/src/odbc.erl28
-rw-r--r--lib/odbc/src/odbc_app.erl21
-rw-r--r--lib/odbc/src/odbc_internal.hrl19
-rw-r--r--lib/odbc/src/odbc_sup.erl21
-rw-r--r--lib/odbc/test/Makefile21
-rw-r--r--lib/odbc/test/README19
-rw-r--r--lib/odbc/test/mysql.erl19
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl49
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl19
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl19
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl19
-rw-r--r--lib/odbc/test/odbc_test.hrl19
-rw-r--r--lib/odbc/test/odbc_test_lib.erl19
-rw-r--r--lib/odbc/test/oracle.erl19
-rw-r--r--lib/odbc/test/postgres.erl19
-rw-r--r--lib/odbc/test/sqlserver.erl19
-rw-r--r--lib/odbc/vsn.mk2
-rw-r--r--lib/orber/COSS/CosNaming/CosNaming_BindingIterator_impl.erl21
-rw-r--r--lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl31
-rw-r--r--lib/orber/COSS/CosNaming/Makefile21
-rw-r--r--lib/orber/COSS/CosNaming/lname.erl21
-rw-r--r--lib/orber/COSS/CosNaming/lname.hrl21
-rw-r--r--lib/orber/COSS/CosNaming/lname_component.erl21
-rw-r--r--lib/orber/COSS/CosNaming/orber_cosnaming.hrl21
-rw-r--r--lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl21
-rw-r--r--lib/orber/Makefile21
-rw-r--r--lib/orber/c_src/InitialReference.cc19
-rw-r--r--lib/orber/c_src/InitialReference.hh19
-rw-r--r--lib/orber/c_src/Makefile21
-rw-r--r--lib/orber/c_src/Makefile.in21
-rw-r--r--lib/orber/c_src/main.cc19
-rw-r--r--lib/orber/doc/src/CosNaming.xml19
-rw-r--r--lib/orber/doc/src/CosNaming_BindingIterator.xml19
-rw-r--r--lib/orber/doc/src/CosNaming_NamingContext.xml21
-rw-r--r--lib/orber/doc/src/CosNaming_NamingContextExt.xml19
-rw-r--r--lib/orber/doc/src/Makefile19
-rw-r--r--lib/orber/doc/src/Module_Interface.xml19
-rw-r--r--lib/orber/doc/src/Orber/InitialReference.java21
-rw-r--r--lib/orber/doc/src/Orber/Makefile21
-rw-r--r--lib/orber/doc/src/any.xml19
-rw-r--r--lib/orber/doc/src/book.xml21
-rw-r--r--lib/orber/doc/src/ch_contents.xml21
-rw-r--r--lib/orber/doc/src/ch_debugging.xml21
-rw-r--r--lib/orber/doc/src/ch_exceptions.xml21
-rw-r--r--lib/orber/doc/src/ch_idl_to_erlang_mapping.xml21
-rw-r--r--lib/orber/doc/src/ch_ifr.xml21
-rw-r--r--lib/orber/doc/src/ch_install.xml19
-rw-r--r--lib/orber/doc/src/ch_interceptors.xml21
-rw-r--r--lib/orber/doc/src/ch_introduction.xml21
-rw-r--r--lib/orber/doc/src/ch_naming_service.xml21
-rw-r--r--lib/orber/doc/src/ch_orber_kernel.xml21
-rw-r--r--lib/orber/doc/src/ch_orberweb.xml21
-rw-r--r--lib/orber/doc/src/ch_security.xml21
-rw-r--r--lib/orber/doc/src/ch_stubs.xml21
-rw-r--r--lib/orber/doc/src/corba.xml21
-rw-r--r--lib/orber/doc/src/corba_object.xml19
-rw-r--r--lib/orber/doc/src/example_part.xml19
-rw-r--r--lib/orber/doc/src/fixed.xml19
-rw-r--r--lib/orber/doc/src/interceptors.xml21
-rw-r--r--lib/orber/doc/src/intro_part.xml19
-rw-r--r--lib/orber/doc/src/lname.xml21
-rw-r--r--lib/orber/doc/src/lname_component.xml21
-rw-r--r--lib/orber/doc/src/notes.xml59
-rw-r--r--lib/orber/doc/src/orber.xml19
-rw-r--r--lib/orber/doc/src/orber_acl.xml19
-rw-r--r--lib/orber/doc/src/orber_diagnostics.xml21
-rw-r--r--lib/orber/doc/src/orber_ifr.xml21
-rw-r--r--lib/orber/doc/src/orber_tc.xml19
-rw-r--r--lib/orber/doc/src/part.xml19
-rw-r--r--lib/orber/doc/src/part_notes.xml21
-rw-r--r--lib/orber/doc/src/ref_man.xml21
-rw-r--r--lib/orber/doc/src/tools_debugging_part.xml19
-rw-r--r--lib/orber/examples/Makefile21
-rw-r--r--lib/orber/examples/Stack/Makefile21
-rw-r--r--lib/orber/examples/Stack/StackClient.cc19
-rw-r--r--lib/orber/examples/Stack/StackClient.java21
-rw-r--r--lib/orber/examples/Stack/StackModule_StackFactory_impl.erl21
-rw-r--r--lib/orber/examples/Stack/StackModule_Stack_impl.erl21
-rw-r--r--lib/orber/examples/Stack/stack_client.erl21
-rw-r--r--lib/orber/examples/Stack/stack_factory.erl21
-rw-r--r--lib/orber/include/corba.hrl21
-rw-r--r--lib/orber/include/ifr_types.hrl19
-rw-r--r--lib/orber/include/orber_pi.hrl21
-rw-r--r--lib/orber/java_src/Makefile21
-rw-r--r--lib/orber/java_src/Orber/InitialReference.java21
-rw-r--r--lib/orber/java_src/Orber/Makefile21
-rw-r--r--lib/orber/priv/Makefile21
-rw-r--r--lib/orber/src/Makefile21
-rw-r--r--lib/orber/src/OrberApp_IFR_impl.erl21
-rw-r--r--lib/orber/src/any.erl21
-rw-r--r--lib/orber/src/cdr_decode.erl33
-rw-r--r--lib/orber/src/cdr_encode.erl21
-rw-r--r--lib/orber/src/cdrlib.erl21
-rw-r--r--lib/orber/src/corba.erl27
-rw-r--r--lib/orber/src/corba_boa.erl21
-rw-r--r--lib/orber/src/corba_nvlist.erl21
-rw-r--r--lib/orber/src/corba_object.erl21
-rw-r--r--lib/orber/src/fixed.erl21
-rw-r--r--lib/orber/src/ifr_objects.hrl21
-rw-r--r--lib/orber/src/iop_ior.erl21
-rw-r--r--lib/orber/src/orber.app.src4
-rw-r--r--lib/orber/src/orber.erl19
-rw-r--r--lib/orber/src/orber_acl.erl21
-rw-r--r--lib/orber/src/orber_diagnostics.erl21
-rw-r--r--lib/orber/src/orber_env.erl19
-rw-r--r--lib/orber/src/orber_exceptions.erl21
-rw-r--r--lib/orber/src/orber_ifr.erl25
-rw-r--r--lib/orber/src/orber_ifr.hrl21
-rw-r--r--lib/orber/src/orber_ifr_aliasdef.erl21
-rw-r--r--lib/orber/src/orber_ifr_arraydef.erl21
-rw-r--r--lib/orber/src/orber_ifr_attributedef.erl21
-rw-r--r--lib/orber/src/orber_ifr_constantdef.erl21
-rw-r--r--lib/orber/src/orber_ifr_contained.erl21
-rw-r--r--lib/orber/src/orber_ifr_container.erl21
-rw-r--r--lib/orber/src/orber_ifr_enumdef.erl21
-rw-r--r--lib/orber/src/orber_ifr_exceptiondef.erl21
-rw-r--r--lib/orber/src/orber_ifr_fixeddef.erl21
-rw-r--r--lib/orber/src/orber_ifr_idltype.erl21
-rw-r--r--lib/orber/src/orber_ifr_interfacedef.erl21
-rw-r--r--lib/orber/src/orber_ifr_irobject.erl21
-rw-r--r--lib/orber/src/orber_ifr_moduledef.erl21
-rw-r--r--lib/orber/src/orber_ifr_operationdef.erl21
-rw-r--r--lib/orber/src/orber_ifr_orb.erl24
-rw-r--r--lib/orber/src/orber_ifr_primitivedef.erl21
-rw-r--r--lib/orber/src/orber_ifr_repository.erl24
-rw-r--r--lib/orber/src/orber_ifr_sequencedef.erl21
-rw-r--r--lib/orber/src/orber_ifr_stringdef.erl21
-rw-r--r--lib/orber/src/orber_ifr_structdef.erl21
-rw-r--r--lib/orber/src/orber_ifr_typecode.erl21
-rw-r--r--lib/orber/src/orber_ifr_typedef.erl21
-rw-r--r--lib/orber/src/orber_ifr_uniondef.erl21
-rw-r--r--lib/orber/src/orber_ifr_utils.erl28
-rw-r--r--lib/orber/src/orber_ifr_wstringdef.erl21
-rw-r--r--lib/orber/src/orber_iiop.erl25
-rw-r--r--lib/orber/src/orber_iiop.hrl21
-rw-r--r--lib/orber/src/orber_iiop_inproxy.erl21
-rw-r--r--lib/orber/src/orber_iiop_inrequest.erl25
-rw-r--r--lib/orber/src/orber_iiop_insup.erl21
-rw-r--r--lib/orber/src/orber_iiop_net.erl21
-rw-r--r--lib/orber/src/orber_iiop_net_accept.erl21
-rw-r--r--lib/orber/src/orber_iiop_outproxy.erl21
-rw-r--r--lib/orber/src/orber_iiop_outsup.erl21
-rw-r--r--lib/orber/src/orber_iiop_pm.erl21
-rw-r--r--lib/orber/src/orber_iiop_socketsup.erl21
-rw-r--r--lib/orber/src/orber_iiop_tracer.erl21
-rw-r--r--lib/orber/src/orber_iiop_tracer_silent.erl21
-rw-r--r--lib/orber/src/orber_iiop_tracer_stealth.erl21
-rw-r--r--lib/orber/src/orber_initial_references.erl21
-rw-r--r--lib/orber/src/orber_interceptors.erl21
-rw-r--r--lib/orber/src/orber_objectkeys.erl33
-rw-r--r--lib/orber/src/orber_pi.erl25
-rw-r--r--lib/orber/src/orber_request_number.erl21
-rw-r--r--lib/orber/src/orber_socket.erl25
-rw-r--r--lib/orber/src/orber_tb.erl21
-rw-r--r--lib/orber/src/orber_tc.erl21
-rw-r--r--lib/orber/src/orber_typedefs.erl21
-rw-r--r--lib/orber/src/orber_web.erl21
-rw-r--r--lib/orber/src/orber_web_server.erl29
-rw-r--r--lib/orber/test/Makefile19
-rw-r--r--lib/orber/test/cdrcoding_10_SUITE.erl23
-rw-r--r--lib/orber/test/cdrcoding_11_SUITE.erl23
-rw-r--r--lib/orber/test/cdrcoding_12_SUITE.erl23
-rw-r--r--lib/orber/test/cdrlib_SUITE.erl21
-rw-r--r--lib/orber/test/corba_SUITE.erl19
-rw-r--r--lib/orber/test/csiv2_SUITE.erl19
-rw-r--r--lib/orber/test/data_types_SUITE.erl21
-rw-r--r--lib/orber/test/generated_SUITE.erl21
-rw-r--r--lib/orber/test/iiop_module_do_test_impl.erl21
-rw-r--r--lib/orber/test/iiop_module_test_impl.erl21
-rw-r--r--lib/orber/test/iiop_test.idl19
-rw-r--r--lib/orber/test/iiop_test_impl.erl21
-rw-r--r--lib/orber/test/interceptors_SUITE.erl21
-rw-r--r--lib/orber/test/iop_ior_10_SUITE.erl23
-rw-r--r--lib/orber/test/iop_ior_11_SUITE.erl23
-rw-r--r--lib/orber/test/iop_ior_12_SUITE.erl23
-rw-r--r--lib/orber/test/ip_v4v6_interop_SUITE.erl19
-rw-r--r--lib/orber/test/lname_SUITE.erl21
-rw-r--r--lib/orber/test/multi_ORB_SUITE.erl23
-rw-r--r--lib/orber/test/naming_context_SUITE.erl21
-rw-r--r--lib/orber/test/orber_SUITE.erl21
-rw-r--r--lib/orber/test/orber_acl_SUITE.erl31
-rw-r--r--lib/orber/test/orber_firewall_ipv4_in_SUITE.erl21
-rw-r--r--lib/orber/test/orber_firewall_ipv4_out_SUITE.erl21
-rw-r--r--lib/orber/test/orber_firewall_ipv6_in_SUITE.erl19
-rw-r--r--lib/orber/test/orber_firewall_ipv6_out_SUITE.erl21
-rw-r--r--lib/orber/test/orber_nat_SUITE.erl19
-rw-r--r--lib/orber/test/orber_test.idl19
-rw-r--r--lib/orber/test/orber_test_lib.erl21
-rw-r--r--lib/orber/test/orber_test_server.cfg19
-rw-r--r--lib/orber/test/orber_test_server.idl19
-rw-r--r--lib/orber/test/orber_test_server_impl.erl33
-rw-r--r--lib/orber/test/orber_test_timeout_server_impl.erl21
-rw-r--r--lib/orber/test/orber_web_SUITE.erl21
-rw-r--r--lib/orber/test/tc_SUITE.erl21
-rw-r--r--lib/orber/vsn.mk2
-rw-r--r--lib/os_mon/Makefile21
-rw-r--r--lib/os_mon/c_src/Makefile.in21
-rw-r--r--lib/os_mon/c_src/cpu_sup.c235
-rw-r--r--lib/os_mon/c_src/ferrule.c21
-rw-r--r--lib/os_mon/c_src/memsup.c21
-rw-r--r--lib/os_mon/c_src/memsup.h21
-rw-r--r--lib/os_mon/c_src/mod_syslog.c21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_format.c21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_format.h21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_global.h21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_main.c21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_pipe_stdin.h21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_registry.c21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_registry.h21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_util.c21
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_util.h21
-rw-r--r--lib/os_mon/c_src/win32sysinfo.c21
-rw-r--r--lib/os_mon/doc/src/Makefile21
-rw-r--r--lib/os_mon/doc/src/book.xml21
-rw-r--r--lib/os_mon/doc/src/cpu_sup.xml25
-rw-r--r--lib/os_mon/doc/src/disksup.xml21
-rw-r--r--lib/os_mon/doc/src/memsup.xml21
-rw-r--r--lib/os_mon/doc/src/notes.xml46
-rw-r--r--lib/os_mon/doc/src/nteventlog.xml21
-rw-r--r--lib/os_mon/doc/src/os_mon_app.xml21
-rw-r--r--lib/os_mon/doc/src/os_mon_mib.xml21
-rw-r--r--lib/os_mon/doc/src/os_sup.xml21
-rw-r--r--lib/os_mon/doc/src/part_notes.xml21
-rw-r--r--lib/os_mon/doc/src/ref_man.xml21
-rw-r--r--lib/os_mon/include/memsup.hrl21
-rw-r--r--lib/os_mon/mibs/Makefile21
-rw-r--r--lib/os_mon/mibs/OTP-OS-MON-MIB.mib19
-rw-r--r--lib/os_mon/src/Makefile21
-rw-r--r--lib/os_mon/src/cpu_sup.erl108
-rw-r--r--lib/os_mon/src/disksup.erl21
-rw-r--r--lib/os_mon/src/memsup.erl21
-rw-r--r--lib/os_mon/src/nteventlog.erl21
-rw-r--r--lib/os_mon/src/os_mon.app.src21
-rw-r--r--lib/os_mon/src/os_mon.appup.src21
-rw-r--r--lib/os_mon/src/os_mon.erl21
-rw-r--r--lib/os_mon/src/os_mon_mib.erl21
-rw-r--r--lib/os_mon/src/os_mon_sysinfo.erl21
-rw-r--r--lib/os_mon/src/os_sup.erl21
-rw-r--r--lib/os_mon/test/Makefile19
-rw-r--r--lib/os_mon/test/cpu_sup_SUITE.erl21
-rw-r--r--lib/os_mon/test/disksup_SUITE.erl19
-rw-r--r--lib/os_mon/test/memsup_SUITE.erl19
-rw-r--r--lib/os_mon/test/os_mon_SUITE.erl19
-rw-r--r--lib/os_mon/test/os_mon_conf.erl19
-rw-r--r--lib/os_mon/test/os_mon_mib_SUITE.erl19
-rw-r--r--lib/os_mon/test/os_sup_SUITE.erl19
-rw-r--r--lib/os_mon/vsn.mk2
-rw-r--r--lib/ose/Makefile21
-rw-r--r--lib/ose/doc/src/Makefile19
-rw-r--r--lib/ose/doc/src/book.xml19
-rw-r--r--lib/ose/doc/src/notes.xml35
-rw-r--r--lib/ose/doc/src/ose_app.xml19
-rw-r--r--lib/ose/doc/src/ose_erl_driver.xml19
-rw-r--r--lib/ose/doc/src/ose_intro.xml19
-rw-r--r--lib/ose/doc/src/ose_signals_chapter.xml21
-rw-r--r--lib/ose/doc/src/part.xml19
-rw-r--r--lib/ose/doc/src/ref_man.xml19
-rw-r--r--lib/ose/src/Makefile19
-rw-r--r--lib/ose/src/ose.app.src19
-rw-r--r--lib/ose/src/ose.appup.src19
-rw-r--r--lib/ose/src/ose.erl21
-rw-r--r--lib/ose/test/ose_SUITE.erl19
-rw-r--r--lib/ose/vsn.mk2
-rw-r--r--lib/otp_mibs/Makefile21
-rw-r--r--lib/otp_mibs/doc/src/Makefile21
-rw-r--r--lib/otp_mibs/doc/src/book.xml21
-rw-r--r--lib/otp_mibs/doc/src/introduction.xml21
-rw-r--r--lib/otp_mibs/doc/src/mibs.xml21
-rw-r--r--lib/otp_mibs/doc/src/notes.xml37
-rw-r--r--lib/otp_mibs/doc/src/otp_mib.xml21
-rw-r--r--lib/otp_mibs/doc/src/part.xml21
-rw-r--r--lib/otp_mibs/doc/src/part_notes.xml21
-rw-r--r--lib/otp_mibs/doc/src/ref_man.xml21
-rw-r--r--lib/otp_mibs/mibs/Makefile21
-rw-r--r--lib/otp_mibs/mibs/OTP-EVA-MIB.mib19
-rw-r--r--lib/otp_mibs/mibs/OTP-MIB.mib19
-rw-r--r--lib/otp_mibs/mibs/OTP-REG.mib19
-rw-r--r--lib/otp_mibs/mibs/OTP-TC.mib19
-rw-r--r--lib/otp_mibs/src/Makefile21
-rw-r--r--lib/otp_mibs/src/otp_mib.erl19
-rw-r--r--lib/otp_mibs/src/otp_mibs.app.src21
-rw-r--r--lib/otp_mibs/src/otp_mibs.appup.src21
-rw-r--r--lib/otp_mibs/test/Makefile19
-rw-r--r--lib/otp_mibs/test/otp_mibs_SUITE.erl19
-rw-r--r--lib/otp_mibs/vsn.mk2
-rw-r--r--lib/parsetools/Makefile21
-rw-r--r--lib/parsetools/doc/src/Makefile21
-rw-r--r--lib/parsetools/doc/src/book.xml21
-rw-r--r--lib/parsetools/doc/src/leex.xml2
-rw-r--r--lib/parsetools/doc/src/notes.xml52
-rw-r--r--lib/parsetools/doc/src/notes_history.xml21
-rw-r--r--lib/parsetools/doc/src/part_notes.xml21
-rw-r--r--lib/parsetools/doc/src/ref_man.xml21
-rw-r--r--lib/parsetools/doc/src/yecc.xml23
-rw-r--r--lib/parsetools/include/leexinc.hrl8
-rw-r--r--lib/parsetools/include/yeccpre.hrl52
-rw-r--r--lib/parsetools/src/Makefile21
-rw-r--r--lib/parsetools/src/leex.erl4
-rw-r--r--lib/parsetools/src/parsetools.app.src2
-rw-r--r--lib/parsetools/src/parsetools.appup.src19
-rw-r--r--lib/parsetools/src/yecc.erl37
-rw-r--r--lib/parsetools/src/yeccgramm.yrl47
-rw-r--r--lib/parsetools/src/yeccparser.erl133
-rw-r--r--lib/parsetools/src/yeccscan.erl21
-rw-r--r--lib/parsetools/test/Makefile21
-rw-r--r--lib/parsetools/test/app_SUITE.erl19
-rw-r--r--lib/parsetools/test/leex_SUITE.erl21
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl49
-rw-r--r--lib/parsetools/vsn.mk2
-rw-r--r--lib/percept/Makefile21
-rw-r--r--lib/percept/doc/src/Makefile19
-rw-r--r--lib/percept/doc/src/book.xml19
-rw-r--r--lib/percept/doc/src/egd_ug.xmlsrc19
-rw-r--r--lib/percept/doc/src/notes.xml36
-rw-r--r--lib/percept/doc/src/part.xml19
-rw-r--r--lib/percept/doc/src/part_notes.xml19
-rw-r--r--lib/percept/doc/src/percept_ug.xmlsrc19
-rw-r--r--lib/percept/doc/src/ref_man.xml19
-rw-r--r--lib/percept/doc/stylesheet.css21
-rw-r--r--lib/percept/priv/Makefile21
-rw-r--r--lib/percept/priv/server_root/css/percept.css21
-rw-r--r--lib/percept/priv/server_root/htdocs/index.html21
-rw-r--r--lib/percept/priv/server_root/scripts/percept_area_select.js21
-rw-r--r--lib/percept/priv/server_root/scripts/percept_error_handler.js21
-rw-r--r--lib/percept/priv/server_root/scripts/percept_select_all.js21
-rw-r--r--lib/percept/src/Makefile21
-rw-r--r--lib/percept/src/egd.erl19
-rw-r--r--lib/percept/src/egd.hrl19
-rw-r--r--lib/percept/src/egd_font.erl21
-rw-r--r--lib/percept/src/egd_png.erl21
-rw-r--r--lib/percept/src/egd_primitives.erl21
-rw-r--r--lib/percept/src/egd_render.erl19
-rw-r--r--lib/percept/src/percept.app.src21
-rw-r--r--lib/percept/src/percept.appup.src21
-rw-r--r--lib/percept/src/percept.erl26
-rw-r--r--lib/percept/src/percept.hrl19
-rw-r--r--lib/percept/src/percept_analyzer.erl21
-rw-r--r--lib/percept/src/percept_db.erl19
-rw-r--r--lib/percept/src/percept_graph.erl21
-rw-r--r--lib/percept/src/percept_html.erl19
-rw-r--r--lib/percept/src/percept_image.erl21
-rw-r--r--lib/percept/test/Makefile21
-rw-r--r--lib/percept/test/egd_SUITE.erl19
-rw-r--r--lib/percept/test/ipc_tree.erl21
-rw-r--r--lib/percept/test/percept_SUITE.erl21
-rw-r--r--lib/percept/test/percept_db_SUITE.erl19
-rw-r--r--lib/percept/vsn.mk2
-rw-r--r--lib/public_key/Makefile21
-rw-r--r--lib/public_key/asn1/Makefile21
-rw-r--r--lib/public_key/asn1/PKIX1Explicit88.asn1109
-rw-r--r--lib/public_key/doc/src/Makefile22
-rw-r--r--lib/public_key/doc/src/book.xml19
-rw-r--r--lib/public_key/doc/src/cert_records.xml690
-rw-r--r--lib/public_key/doc/src/introduction.xml44
-rw-r--r--lib/public_key/doc/src/notes.xml123
-rw-r--r--lib/public_key/doc/src/part.xml26
-rw-r--r--lib/public_key/doc/src/part_notes.xml19
-rw-r--r--lib/public_key/doc/src/public_key.xml586
-rw-r--r--lib/public_key/doc/src/public_key_records.xml773
-rw-r--r--lib/public_key/doc/src/ref_man.xml25
-rw-r--r--lib/public_key/doc/src/using_public_key.xml263
-rw-r--r--lib/public_key/include/public_key.hrl21
-rwxr-xr-xlib/public_key/priv/convert.escript50
-rwxr-xr-xlib/public_key/priv/generate25
-rw-r--r--lib/public_key/priv/moduli193
-rw-r--r--lib/public_key/src/Makefile28
-rw-r--r--lib/public_key/src/pubkey_cert.erl21
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl25
-rw-r--r--lib/public_key/src/pubkey_crl.erl23
-rw-r--r--lib/public_key/src/pubkey_moduli.hrl395
-rw-r--r--lib/public_key/src/pubkey_pbe.erl47
-rw-r--r--lib/public_key/src/pubkey_pem.erl24
-rw-r--r--lib/public_key/src/pubkey_ssh.erl213
-rw-r--r--lib/public_key/src/public_key.appup.src19
-rw-r--r--lib/public_key/src/public_key.erl127
-rw-r--r--lib/public_key/test/Makefile19
-rw-r--r--lib/public_key/test/erl_make_certs.erl50
-rw-r--r--lib/public_key/test/pbe_SUITE.erl19
-rw-r--r--lib/public_key/test/pkits_SUITE.erl21
-rw-r--r--lib/public_key/test/public_key_SUITE.erl62
-rw-r--r--lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub1
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub6
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/Makefile21
-rwxr-xr-xlib/reltool/bin/reltool.escript19
-rw-r--r--lib/reltool/doc/src/Makefile19
-rw-r--r--lib/reltool/doc/src/book.xml19
-rw-r--r--lib/reltool/doc/src/files.mk19
-rw-r--r--lib/reltool/doc/src/notes.xml39
-rw-r--r--lib/reltool/doc/src/part.xml19
-rw-r--r--lib/reltool/doc/src/ref_man.xml19
-rw-r--r--lib/reltool/doc/src/reltool.xml21
-rw-r--r--lib/reltool/doc/src/reltool_examples.xml21
-rw-r--r--lib/reltool/doc/src/reltool_intro.xml19
-rw-r--r--lib/reltool/doc/src/reltool_usage.xml21
-rw-r--r--lib/reltool/examples/Makefile21
-rw-r--r--lib/reltool/src/Makefile19
-rw-r--r--lib/reltool/src/files.mk19
-rw-r--r--lib/reltool/src/reltool.app.src21
-rw-r--r--lib/reltool/src/reltool.appup.src19
-rw-r--r--lib/reltool/src/reltool.erl19
-rw-r--r--lib/reltool/src/reltool.hrl19
-rw-r--r--lib/reltool/src/reltool_app_win.erl19
-rw-r--r--lib/reltool/src/reltool_fgraph.erl19
-rw-r--r--lib/reltool/src/reltool_fgraph.hrl21
-rw-r--r--lib/reltool/src/reltool_fgraph_win.erl25
-rw-r--r--lib/reltool/src/reltool_mod_win.erl19
-rw-r--r--lib/reltool/src/reltool_server.erl19
-rw-r--r--lib/reltool/src/reltool_sys_win.erl19
-rw-r--r--lib/reltool/src/reltool_target.erl19
-rw-r--r--lib/reltool/src/reltool_utils.erl26
-rw-r--r--lib/reltool/test/Makefile19
-rw-r--r--lib/reltool/test/reltool_app_SUITE.erl19
-rw-r--r--lib/reltool/test/reltool_manual_gui_SUITE.erl19
-rw-r--r--lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a.erl19
-rw-r--r--lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl19
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl31
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl19
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl19
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl19
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl19
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl19
-rw-r--r--lib/reltool/test/reltool_test_lib.erl19
-rw-r--r--lib/reltool/test/reltool_test_lib.hrl19
-rw-r--r--lib/reltool/test/reltool_wx_SUITE.erl21
-rwxr-xr-xlib/reltool/test/rtt19
-rw-r--r--lib/reltool/test/rtt.erl21
-rw-r--r--lib/reltool/vsn.mk2
-rw-r--r--lib/runtime_tools/Makefile21
-rw-r--r--lib/runtime_tools/c_src/Makefile.in19
-rw-r--r--lib/runtime_tools/c_src/dtrace_user.d19
-rw-r--r--lib/runtime_tools/c_src/dyntrace.c19
-rw-r--r--lib/runtime_tools/c_src/trace_file_drv.c49
-rw-r--r--lib/runtime_tools/c_src/trace_ip_drv.c36
-rw-r--r--lib/runtime_tools/doc/src/Makefile21
-rw-r--r--lib/runtime_tools/doc/src/book.xml21
-rw-r--r--lib/runtime_tools/doc/src/dbg.xml35
-rw-r--r--lib/runtime_tools/doc/src/dyntrace.xml21
-rw-r--r--lib/runtime_tools/doc/src/erts_alloc_config.xml19
-rw-r--r--lib/runtime_tools/doc/src/notes.xml84
-rw-r--r--lib/runtime_tools/doc/src/notes_history.xml19
-rw-r--r--lib/runtime_tools/doc/src/part.xml21
-rw-r--r--lib/runtime_tools/doc/src/part_notes.xml21
-rw-r--r--lib/runtime_tools/doc/src/part_notes_history.xml19
-rw-r--r--lib/runtime_tools/doc/src/ref_man.xml21
-rw-r--r--lib/runtime_tools/doc/src/runtime_tools_app.xml19
-rw-r--r--lib/runtime_tools/doc/src/system_information.xml21
-rw-r--r--lib/runtime_tools/examples/dist.d19
-rw-r--r--lib/runtime_tools/examples/dist.systemtap19
-rw-r--r--lib/runtime_tools/examples/driver1.d19
-rw-r--r--lib/runtime_tools/examples/driver1.systemtap19
-rw-r--r--lib/runtime_tools/examples/efile_drv.d19
-rw-r--r--lib/runtime_tools/examples/efile_drv.systemtap19
-rw-r--r--lib/runtime_tools/examples/function-calls.d19
-rw-r--r--lib/runtime_tools/examples/function-calls.systemtap19
-rw-r--r--lib/runtime_tools/examples/garbage-collection.d19
-rw-r--r--lib/runtime_tools/examples/garbage-collection.systemtap19
-rw-r--r--lib/runtime_tools/examples/memory1.d19
-rw-r--r--lib/runtime_tools/examples/memory1.systemtap19
-rw-r--r--lib/runtime_tools/examples/messages.d19
-rw-r--r--lib/runtime_tools/examples/messages.systemtap19
-rw-r--r--lib/runtime_tools/examples/port1.d19
-rw-r--r--lib/runtime_tools/examples/port1.systemtap19
-rw-r--r--lib/runtime_tools/examples/process-scheduling.d19
-rw-r--r--lib/runtime_tools/examples/process-scheduling.systemtap19
-rw-r--r--lib/runtime_tools/examples/spawn-exit.d19
-rw-r--r--lib/runtime_tools/examples/spawn-exit.systemtap19
-rw-r--r--lib/runtime_tools/examples/user-probe-n.d19
-rw-r--r--lib/runtime_tools/examples/user-probe-n.systemtap19
-rw-r--r--lib/runtime_tools/examples/user-probe.d19
-rw-r--r--lib/runtime_tools/examples/user-probe.systemtap19
-rw-r--r--lib/runtime_tools/include/observer_backend.hrl19
-rw-r--r--lib/runtime_tools/src/Makefile21
-rw-r--r--lib/runtime_tools/src/appmon_info.erl21
-rw-r--r--lib/runtime_tools/src/dbg.erl29
-rw-r--r--lib/runtime_tools/src/erts_alloc_config.erl21
-rw-r--r--lib/runtime_tools/src/observer_backend.erl23
-rw-r--r--lib/runtime_tools/src/percept_profile.erl23
-rw-r--r--lib/runtime_tools/src/runtime_tools.app.src23
-rw-r--r--lib/runtime_tools/src/runtime_tools.appup.src21
-rw-r--r--lib/runtime_tools/src/runtime_tools.erl21
-rw-r--r--lib/runtime_tools/src/runtime_tools_sup.erl21
-rw-r--r--lib/runtime_tools/src/system_information.erl26
-rw-r--r--lib/runtime_tools/test/dbg_SUITE.erl19
-rw-r--r--lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl19
-rw-r--r--lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl19
-rw-r--r--lib/runtime_tools/test/dyntrace_SUITE.erl19
-rw-r--r--lib/runtime_tools/test/erts_alloc_config_SUITE.erl26
-rw-r--r--lib/runtime_tools/test/runtime_tools_SUITE.erl19
-rw-r--r--lib/runtime_tools/test/system_information_SUITE.erl21
-rw-r--r--lib/runtime_tools/vsn.mk2
-rw-r--r--lib/sasl/Makefile21
-rw-r--r--lib/sasl/doc/src/Makefile21
-rw-r--r--lib/sasl/doc/src/alarm_handler.xml103
-rw-r--r--lib/sasl/doc/src/appup.xml465
-rw-r--r--lib/sasl/doc/src/book.xml25
-rw-r--r--lib/sasl/doc/src/error_logging.xml236
-rw-r--r--lib/sasl/doc/src/notes.xml142
-rw-r--r--lib/sasl/doc/src/notes_history.xml21
-rw-r--r--lib/sasl/doc/src/overload.xml151
-rw-r--r--lib/sasl/doc/src/part.xml26
-rw-r--r--lib/sasl/doc/src/part_notes.xml21
-rw-r--r--lib/sasl/doc/src/part_notes_history.xml19
-rw-r--r--lib/sasl/doc/src/rb.xml304
-rw-r--r--lib/sasl/doc/src/ref_man.xml25
-rw-r--r--lib/sasl/doc/src/rel.xml110
-rw-r--r--lib/sasl/doc/src/release_handler.xml764
-rw-r--r--lib/sasl/doc/src/relup.xml89
-rw-r--r--lib/sasl/doc/src/sasl_app.xml196
-rw-r--r--lib/sasl/doc/src/sasl_intro.xml59
-rw-r--r--lib/sasl/doc/src/script.xml176
-rw-r--r--lib/sasl/doc/src/systools.xml366
-rw-r--r--lib/sasl/examples/src/Makefile21
-rw-r--r--lib/sasl/examples/src/target_system.erl19
-rw-r--r--lib/sasl/src/Makefile21
-rw-r--r--lib/sasl/src/alarm_handler.erl21
-rw-r--r--lib/sasl/src/erlsrv.erl21
-rw-r--r--lib/sasl/src/format_lib_supp.erl21
-rw-r--r--lib/sasl/src/misc_supp.erl21
-rw-r--r--lib/sasl/src/overload.erl21
-rw-r--r--lib/sasl/src/rb.erl19
-rw-r--r--lib/sasl/src/rb_format_supp.erl21
-rw-r--r--lib/sasl/src/release_handler.erl19
-rw-r--r--lib/sasl/src/release_handler_1.erl119
-rw-r--r--lib/sasl/src/sasl.app.src23
-rw-r--r--lib/sasl/src/sasl.appup.src27
-rw-r--r--lib/sasl/src/sasl.erl27
-rw-r--r--lib/sasl/src/sasl_report.erl67
-rw-r--r--lib/sasl/src/sasl_report_file_h.erl25
-rw-r--r--lib/sasl/src/sasl_report_tty_h.erl21
-rw-r--r--lib/sasl/src/si.erl21
-rw-r--r--lib/sasl/src/si_sasl_supp.erl19
-rw-r--r--lib/sasl/src/systools.erl21
-rw-r--r--lib/sasl/src/systools.hrl21
-rw-r--r--lib/sasl/src/systools_lib.erl21
-rw-r--r--lib/sasl/src/systools_make.erl21
-rw-r--r--lib/sasl/src/systools_rc.erl49
-rw-r--r--lib/sasl/src/systools_relup.erl21
-rw-r--r--lib/sasl/test/Makefile25
-rw-r--r--lib/sasl/test/alarm_handler_SUITE.erl19
-rw-r--r--lib/sasl/test/installer.erl19
-rw-r--r--lib/sasl/test/overload_SUITE.erl19
-rw-r--r--lib/sasl/test/rb_SUITE.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl21
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/c/aa.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/c/b.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/c/c_sup.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/README2
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a_sup.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a_sup.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup6
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_atom.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_list.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_numeric.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_string.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_tuple.erl19
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app21
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup19
-rw-r--r--lib/sasl/test/sasl_SUITE.erl135
-rw-r--r--lib/sasl/test/sasl_report_SUITE.erl141
-rw-r--r--lib/sasl/test/sasl_report_suite_supervisor.erl77
-rw-r--r--lib/sasl/test/systools_SUITE.erl19
-rw-r--r--lib/sasl/test/systools_rc_SUITE.erl81
-rw-r--r--lib/sasl/test/test_lib.hrl4
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/snmp/Makefile21
-rw-r--r--lib/snmp/doc/src/Makefile21
-rw-r--r--lib/snmp/doc/src/book.xml21
-rw-r--r--lib/snmp/doc/src/files.mk21
-rw-r--r--lib/snmp/doc/src/index.html.src21
-rw-r--r--lib/snmp/doc/src/notes.xml82
-rw-r--r--lib/snmp/doc/src/notes_history.xml21
-rw-r--r--lib/snmp/doc/src/part.xml21
-rw-r--r--lib/snmp/doc/src/part_notes.xml21
-rw-r--r--lib/snmp/doc/src/part_notes_history.xml21
-rw-r--r--lib/snmp/doc/src/ref_man.xml21
-rw-r--r--lib/snmp/doc/src/snmp.xml21
-rw-r--r--lib/snmp/doc/src/snmp_advanced_agent.xml23
-rw-r--r--lib/snmp/doc/src/snmp_agent_config_files.xml21
-rw-r--r--lib/snmp/doc/src/snmp_agent_funct_descr.xml21
-rw-r--r--lib/snmp/doc/src/snmp_agent_netif.xml24
-rw-r--r--lib/snmp/doc/src/snmp_app.xml299
-rw-r--r--lib/snmp/doc/src/snmp_app_a.xml21
-rw-r--r--lib/snmp/doc/src/snmp_app_b.xml21
-rw-r--r--lib/snmp/doc/src/snmp_audit_trail_log.xml21
-rw-r--r--lib/snmp/doc/src/snmp_community_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmp_config.xml303
-rw-r--r--lib/snmp/doc/src/snmp_def_instr_functions.xml21
-rw-r--r--lib/snmp/doc/src/snmp_framework_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmp_generic.xml21
-rw-r--r--lib/snmp/doc/src/snmp_impl_example_agent.xml21
-rw-r--r--lib/snmp/doc/src/snmp_impl_example_manager.xml21
-rw-r--r--lib/snmp/doc/src/snmp_index.xml21
-rw-r--r--lib/snmp/doc/src/snmp_instr_functions.xml21
-rw-r--r--lib/snmp/doc/src/snmp_intro.xml21
-rw-r--r--lib/snmp/doc/src/snmp_manager_config_files.xml21
-rw-r--r--lib/snmp/doc/src/snmp_manager_funct_descr.xml21
-rw-r--r--lib/snmp/doc/src/snmp_manager_netif.xml24
-rw-r--r--lib/snmp/doc/src/snmp_mib_compiler.xml21
-rw-r--r--lib/snmp/doc/src/snmp_notification_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmp_pdus.xml21
-rw-r--r--lib/snmp/doc/src/snmp_standard_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmp_target_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmp_user_based_sm_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmp_view_based_acm_mib.xml21
-rw-r--r--lib/snmp/doc/src/snmpa.xml25
-rw-r--r--lib/snmp/doc/src/snmpa_conf.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_discovery_handler.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_error.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_error_io.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_error_logger.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_error_report.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_local_db.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_mib_data.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_mib_storage.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_mpd.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_network_interface.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_network_interface_filter.xml19
-rw-r--r--lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml19
-rw-r--r--lib/snmp/doc/src/snmpa_notification_filter.xml21
-rw-r--r--lib/snmp/doc/src/snmpa_supervisor.xml21
-rw-r--r--lib/snmp/doc/src/snmpc.xml19
-rw-r--r--lib/snmp/doc/src/snmpc_cmd.xml21
-rw-r--r--lib/snmp/doc/src/snmpm.xml29
-rw-r--r--lib/snmp/doc/src/snmpm_conf.xml21
-rw-r--r--lib/snmp/doc/src/snmpm_mpd.xml21
-rw-r--r--lib/snmp/doc/src/snmpm_network_interface.xml21
-rw-r--r--lib/snmp/doc/src/snmpm_network_interface_filter.xml21
-rw-r--r--lib/snmp/doc/src/snmpm_user.xml21
-rw-r--r--lib/snmp/examples/Makefile21
-rw-r--r--lib/snmp/examples/ex1/Makefile21
-rw-r--r--lib/snmp/examples/ex1/ex1.erl19
-rw-r--r--lib/snmp/examples/ex2/Makefile21
-rw-r--r--lib/snmp/examples/ex2/snmp_ex2_manager.erl21
-rw-r--r--lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl21
-rw-r--r--lib/snmp/examples/subdirs.mk21
-rw-r--r--lib/snmp/include/SNMPv2-TC.hrl21
-rw-r--r--lib/snmp/include/snmp_tables.hrl21
-rw-r--r--lib/snmp/include/snmp_types.hrl21
-rw-r--r--lib/snmp/mibs/Makefile.in21
-rw-r--r--lib/snmp/priv/conf/Makefile21
-rw-r--r--lib/snmp/priv/conf/agent/Makefile21
-rw-r--r--lib/snmp/priv/conf/agent/files.mk21
-rw-r--r--lib/snmp/priv/conf/manager/Makefile21
-rw-r--r--lib/snmp/priv/conf/manager/files.mk21
-rw-r--r--lib/snmp/priv/conf/subdirs.mk21
-rw-r--r--lib/snmp/src/Makefile21
-rw-r--r--lib/snmp/src/agent/Makefile21
-rw-r--r--lib/snmp/src/agent/depend.mk21
-rw-r--r--lib/snmp/src/agent/modules.mk21
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl21
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl21
-rw-r--r--lib/snmp/src/agent/snmp_generic.erl21
-rw-r--r--lib/snmp/src/agent/snmp_generic_mnesia.erl21
-rw-r--r--lib/snmp/src/agent/snmp_index.erl21
-rw-r--r--lib/snmp/src/agent/snmp_notification_mib.erl21
-rw-r--r--lib/snmp/src/agent/snmp_shadow_table.erl30
-rw-r--r--lib/snmp/src/agent/snmp_standard_mib.erl28
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl37
-rw-r--r--lib/snmp/src/agent/snmp_user_based_sm_mib.erl52
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl31
-rw-r--r--lib/snmp/src/agent/snmpa.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_acm.erl25
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_agent_sup.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_app.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_atl.hrl21
-rw-r--r--lib/snmp/src/agent/snmpa_authentication_service.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_discovery_handler.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_discovery_handler_default.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_error.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_error_io.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_error_logger.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_error_report.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_general_db.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_internal.hrl19
-rw-r--r--lib/snmp/src/agent/snmpa_local_db.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_mib.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_mib_data.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_mib_data_ttln.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_mib_data_tttn.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_mib_lib.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage_dets.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage_ets.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_misc_sup.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl40
-rw-r--r--lib/snmp/src/agent/snmpa_net_if.erl40
-rw-r--r--lib/snmp/src/agent/snmpa_net_if_filter.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_network_interface.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_network_interface_filter.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_notification_delivery_info_receiver.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_notification_filter.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_set.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_set_lib.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_set_mechanism.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_supervisor.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_svbl.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_symbolic_store.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_target_cache.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_usm.erl31
-rw-r--r--lib/snmp/src/agent/snmpa_vacm.erl30
-rw-r--r--lib/snmp/src/agent/snmpa_vacm.hrl21
-rw-r--r--lib/snmp/src/app/Makefile21
-rw-r--r--lib/snmp/src/app/depend.mk21
-rw-r--r--lib/snmp/src/app/modules.mk21
-rw-r--r--lib/snmp/src/app/snmp.app.src25
-rw-r--r--lib/snmp/src/app/snmp.appup.src60
-rw-r--r--lib/snmp/src/app/snmp.erl21
-rw-r--r--lib/snmp/src/app/snmp_app.erl21
-rw-r--r--lib/snmp/src/app/snmp_app_sup.erl21
-rw-r--r--lib/snmp/src/app/snmp_internal.hrl21
-rw-r--r--lib/snmp/src/compile/Makefile21
-rw-r--r--lib/snmp/src/compile/depend.mk21
-rw-r--r--lib/snmp/src/compile/modules.mk21
-rw-r--r--lib/snmp/src/compile/snmpc.erl26
-rw-r--r--lib/snmp/src/compile/snmpc.hrl21
-rw-r--r--lib/snmp/src/compile/snmpc.src21
-rw-r--r--lib/snmp/src/compile/snmpc_lib.erl19
-rw-r--r--lib/snmp/src/compile/snmpc_lib.hrl21
-rw-r--r--lib/snmp/src/compile/snmpc_mib_gram.yrl21
-rw-r--r--lib/snmp/src/compile/snmpc_mib_to_hrl.erl21
-rw-r--r--lib/snmp/src/compile/snmpc_misc.erl21
-rw-r--r--lib/snmp/src/compile/snmpc_misc.hrl21
-rw-r--r--lib/snmp/src/compile/snmpc_tok.erl21
-rw-r--r--lib/snmp/src/manager/Makefile21
-rw-r--r--lib/snmp/src/manager/depend.mk21
-rw-r--r--lib/snmp/src/manager/modules.mk21
-rw-r--r--lib/snmp/src/manager/snmpm.erl29
-rw-r--r--lib/snmp/src/manager/snmpm_atl.hrl21
-rw-r--r--lib/snmp/src/manager/snmpm_conf.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl19
-rw-r--r--lib/snmp/src/manager/snmpm_internal.hrl21
-rw-r--r--lib/snmp/src/manager/snmpm_misc_sup.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl37
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl155
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_filter.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_mt.erl19
-rw-r--r--lib/snmp/src/manager/snmpm_network_interface.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_network_interface_filter.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl169
-rw-r--r--lib/snmp/src/manager/snmpm_server_sup.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_supervisor.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_user.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_user_default.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_user_old.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_usm.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_usm.hrl21
-rw-r--r--lib/snmp/src/misc/Makefile21
-rw-r--r--lib/snmp/src/misc/depend.mk21
-rw-r--r--lib/snmp/src/misc/modules.mk21
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl23
-rw-r--r--lib/snmp/src/misc/snmp_config.erl19
-rw-r--r--lib/snmp/src/misc/snmp_debug.hrl21
-rw-r--r--lib/snmp/src/misc/snmp_log.erl19
-rw-r--r--lib/snmp/src/misc/snmp_mini_mib.erl21
-rw-r--r--lib/snmp/src/misc/snmp_misc.erl44
-rw-r--r--lib/snmp/src/misc/snmp_note_store.erl21
-rw-r--r--lib/snmp/src/misc/snmp_pdus.erl19
-rw-r--r--lib/snmp/src/misc/snmp_usm.erl19
-rw-r--r--lib/snmp/src/misc/snmp_verbosity.erl26
-rw-r--r--lib/snmp/src/misc/snmp_verbosity.hrl21
-rw-r--r--lib/snmp/src/subdirs.mk21
-rw-r--r--lib/snmp/subdirs.mk21
-rw-r--r--lib/snmp/test/Makefile21
-rw-r--r--lib/snmp/test/exp/snmp_agent_bl_test.erl21
-rw-r--r--lib/snmp/test/exp/snmp_agent_ms_test.erl21
-rw-r--r--lib/snmp/test/exp/snmp_agent_mt_test.erl21
-rw-r--r--lib/snmp/test/exp/snmp_agent_v1_test.erl21
-rw-r--r--lib/snmp/test/exp/snmp_agent_v2_test.erl21
-rw-r--r--lib/snmp/test/exp/snmp_agent_v3_test.erl21
-rw-r--r--lib/snmp/test/klas3.erl21
-rw-r--r--lib/snmp/test/modules.mk19
-rw-r--r--lib/snmp/test/sa.erl21
-rw-r--r--lib/snmp/test/snmp_SUITE.erl21
-rw-r--r--lib/snmp/test/snmp_agent_mibs_test.erl21
-rw-r--r--lib/snmp/test/snmp_agent_nfilter_test.erl21
-rw-r--r--lib/snmp/test/snmp_agent_test.erl105
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl19
-rw-r--r--lib/snmp/test/snmp_app_test.erl111
-rw-r--r--lib/snmp/test/snmp_appup_mgr.erl29
-rw-r--r--lib/snmp/test/snmp_appup_test.erl21
-rw-r--r--lib/snmp/test/snmp_compiler_test.erl19
-rw-r--r--lib/snmp/test/snmp_conf_test.erl25
-rw-r--r--lib/snmp/test/snmp_log_test.erl48
-rw-r--r--lib/snmp/test/snmp_manager_config_test.erl27
-rw-r--r--lib/snmp/test/snmp_manager_test.erl19
-rw-r--r--lib/snmp/test/snmp_manager_user.erl21
-rw-r--r--lib/snmp/test/snmp_manager_user_old.erl21
-rw-r--r--lib/snmp/test/snmp_manager_user_test.erl19
-rw-r--r--lib/snmp/test/snmp_manager_user_test_lib.erl21
-rw-r--r--lib/snmp/test/snmp_note_store_test.erl21
-rw-r--r--lib/snmp/test/snmp_pdus_test.erl19
-rw-r--r--lib/snmp/test/snmp_test_lib.erl32
-rw-r--r--lib/snmp/test/snmp_test_lib.hrl34
-rw-r--r--lib/snmp/test/snmp_test_manager.erl21
-rw-r--r--lib/snmp/test/snmp_test_mgr.erl27
-rw-r--r--lib/snmp/test/snmp_test_mgr_counter_server.erl19
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl19
-rw-r--r--lib/snmp/test/snmp_test_server.erl21
-rw-r--r--lib/snmp/test/snmp_test_suite.erl21
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE.erl19
-rwxr-xr-xlib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper19
-rw-r--r--lib/snmp/test/test1.erl21
-rw-r--r--lib/snmp/test/test2.erl21
-rw-r--r--lib/snmp/test/test_config/Makefile21
-rw-r--r--lib/snmp/test/test_config/modules.mk19
-rw-r--r--lib/snmp/test/test_config/snmp_test_config.erl19
-rw-r--r--lib/snmp/vsn.mk21
-rw-r--r--lib/ssh/Makefile21
-rw-r--r--lib/ssh/doc/src/Makefile19
-rw-r--r--lib/ssh/doc/src/book.xml19
-rw-r--r--lib/ssh/doc/src/introduction.xml201
-rw-r--r--lib/ssh/doc/src/notes.xml605
-rw-r--r--lib/ssh/doc/src/part_notes.xml19
-rw-r--r--lib/ssh/doc/src/ref_man.xml23
-rw-r--r--lib/ssh/doc/src/ssh.xml629
-rw-r--r--lib/ssh/doc/src/ssh_app.xml343
-rw-r--r--lib/ssh/doc/src/ssh_channel.xml315
-rw-r--r--lib/ssh/doc/src/ssh_client_key_api.xml117
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml527
-rw-r--r--lib/ssh/doc/src/ssh_server_key_api.xml98
-rw-r--r--lib/ssh/doc/src/ssh_sftp.xml736
-rw-r--r--lib/ssh/doc/src/ssh_sftpd.xml75
-rw-r--r--lib/ssh/doc/src/usersguide.xml26
-rw-r--r--lib/ssh/doc/src/using_ssh.xml227
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps3315
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt1624
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps2557
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt1232
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps2853
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt1627
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps3511
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt1962
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt2130
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps3205
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt1624
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps1881
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt896
-rw-r--r--lib/ssh/examples/Makefile19
-rw-r--r--lib/ssh/examples/ssh_device.erl19
-rw-r--r--lib/ssh/examples/ssh_sample_cli.erl19
-rw-r--r--lib/ssh/src/Makefile101
-rw-r--r--lib/ssh/src/ssh.app.src1
-rw-r--r--lib/ssh/src/ssh.appup.src19
-rw-r--r--lib/ssh/src/ssh.erl398
-rw-r--r--lib/ssh/src/ssh.hrl44
-rw-r--r--lib/ssh/src/ssh_acceptor.erl32
-rw-r--r--lib/ssh/src/ssh_acceptor_sup.erl43
-rw-r--r--lib/ssh/src/ssh_app.erl21
-rw-r--r--lib/ssh/src/ssh_auth.erl369
-rw-r--r--lib/ssh/src/ssh_auth.hrl22
-rw-r--r--lib/ssh/src/ssh_bits.erl27
-rw-r--r--lib/ssh/src/ssh_channel.erl19
-rw-r--r--lib/ssh/src/ssh_channel_sup.erl21
-rw-r--r--lib/ssh/src/ssh_cli.erl70
-rw-r--r--lib/ssh/src/ssh_client_key.erl19
-rw-r--r--lib/ssh/src/ssh_client_key_api.erl19
-rw-r--r--lib/ssh/src/ssh_connect.hrl22
-rw-r--r--lib/ssh/src/ssh_connection.erl76
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl868
-rw-r--r--lib/ssh/src/ssh_connection_sup.erl21
-rw-r--r--lib/ssh/src/ssh_daemon_channel.erl19
-rw-r--r--lib/ssh/src/ssh_file.erl113
-rw-r--r--lib/ssh/src/ssh_info.erl30
-rw-r--r--lib/ssh/src/ssh_io.erl19
-rw-r--r--lib/ssh/src/ssh_math.erl41
-rw-r--r--lib/ssh/src/ssh_message.erl198
-rw-r--r--lib/ssh/src/ssh_no_io.erl21
-rw-r--r--lib/ssh/src/ssh_server_key.erl19
-rw-r--r--lib/ssh/src/ssh_server_key_api.erl19
-rw-r--r--lib/ssh/src/ssh_sftp.erl50
-rw-r--r--lib/ssh/src/ssh_sftpd.erl41
-rw-r--r--lib/ssh/src/ssh_sftpd_file.erl19
-rw-r--r--lib/ssh/src/ssh_sftpd_file_api.erl21
-rw-r--r--lib/ssh/src/ssh_shell.erl19
-rw-r--r--lib/ssh/src/ssh_subsystem_sup.erl19
-rw-r--r--lib/ssh/src/ssh_sup.erl19
-rw-r--r--lib/ssh/src/ssh_system_sup.erl83
-rw-r--r--lib/ssh/src/ssh_transport.erl1352
-rw-r--r--lib/ssh/src/ssh_transport.hrl122
-rw-r--r--lib/ssh/src/ssh_userauth.hrl19
-rw-r--r--lib/ssh/src/ssh_xfer.erl19
-rw-r--r--lib/ssh/src/ssh_xfer.hrl19
-rw-r--r--lib/ssh/src/sshc_sup.erl19
-rw-r--r--lib/ssh/src/sshd_sup.erl46
-rw-r--r--lib/ssh/test/Makefile40
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server.erl21
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_encode_decode.erl21
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_subsys.erl21
-rw-r--r--lib/ssh/test/ssh.spec11
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE.erl376
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa5
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key (renamed from lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key)0
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key.pub (renamed from lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key.pub)0
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl1369
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_bench.spec1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE.erl536
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl190
-rw-r--r--lib/ssh/test/ssh_echo_server.erl19
-rw-r--r--lib/ssh/test/ssh_key_cb.erl45
-rw-r--r--lib/ssh/test/ssh_key_cb_options.erl44
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl1187
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_peername_sockname_server.erl21
-rw-r--r--lib/ssh/test/ssh_property_test_SUITE.erl21
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl705
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test3
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli3
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_relay.erl407
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl250
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl437
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt16384
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f11
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f21
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt1
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl62
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl55
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl19
-rw-r--r--lib/ssh/test/ssh_sup_SUITE.erl197
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_test_cli.erl15
-rw-r--r--lib/ssh/test/ssh_test_lib.erl382
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl453
-rw-r--r--lib/ssh/test/ssh_trpt_test_lib.erl772
-rw-r--r--lib/ssh/test/ssh_unicode_SUITE.erl587
-rw-r--r--lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt1
-rw-r--r--lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt1
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE.erl200
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts1
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/vsn.mk3
-rw-r--r--lib/ssl/Makefile21
-rw-r--r--lib/ssl/doc/src/Makefile23
-rw-r--r--lib/ssl/doc/src/book.xml21
-rw-r--r--lib/ssl/doc/src/notes.xml467
-rw-r--r--lib/ssl/doc/src/pkix_certs.xml21
-rw-r--r--lib/ssl/doc/src/refman.xml38
-rw-r--r--lib/ssl/doc/src/release_notes.xml21
-rw-r--r--lib/ssl/doc/src/ssl.xml1234
-rw-r--r--lib/ssl/doc/src/ssl_app.xml155
-rw-r--r--lib/ssl/doc/src/ssl_crl_cache.xml66
-rw-r--r--lib/ssl/doc/src/ssl_crl_cache_api.xml106
-rw-r--r--lib/ssl/doc/src/ssl_distribution.xml285
-rw-r--r--lib/ssl/doc/src/ssl_introduction.xml54
-rw-r--r--lib/ssl/doc/src/ssl_protocol.xml151
-rw-r--r--lib/ssl/doc/src/ssl_session_cache_api.xml142
-rw-r--r--lib/ssl/doc/src/usersguide.xml24
-rw-r--r--lib/ssl/doc/src/using_ssl.xml124
-rw-r--r--lib/ssl/examples/certs/Makefile21
-rw-r--r--lib/ssl/examples/src/Makefile21
-rw-r--r--lib/ssl/examples/src/client_server.erl28
-rw-r--r--lib/ssl/src/Makefile29
-rw-r--r--lib/ssl/src/dtls.erl19
-rw-r--r--lib/ssl/src/dtls_connection.erl38
-rw-r--r--lib/ssl/src/dtls_connection.hrl21
-rw-r--r--lib/ssl/src/dtls_connection_sup.erl21
-rw-r--r--lib/ssl/src/dtls_handshake.erl28
-rw-r--r--lib/ssl/src/dtls_handshake.hrl21
-rw-r--r--lib/ssl/src/dtls_record.erl81
-rw-r--r--lib/ssl/src/dtls_record.hrl21
-rw-r--r--lib/ssl/src/dtls_v1.erl19
-rw-r--r--lib/ssl/src/inet6_tls_dist.erl46
-rw-r--r--lib/ssl/src/inet_tls_dist.erl128
-rw-r--r--lib/ssl/src/ssl.app.src9
-rw-r--r--lib/ssl/src/ssl.appup.src12
-rw-r--r--lib/ssl/src/ssl.erl357
-rw-r--r--lib/ssl/src/ssl_alert.erl21
-rw-r--r--lib/ssl/src/ssl_alert.hrl24
-rw-r--r--lib/ssl/src/ssl_api.hrl21
-rw-r--r--lib/ssl/src/ssl_app.erl21
-rw-r--r--lib/ssl/src/ssl_certificate.erl97
-rw-r--r--lib/ssl/src/ssl_cipher.erl557
-rw-r--r--lib/ssl/src/ssl_cipher.hrl115
-rw-r--r--lib/ssl/src/ssl_config.erl56
-rw-r--r--lib/ssl/src/ssl_connection.erl302
-rw-r--r--lib/ssl/src/ssl_connection.hrl28
-rw-r--r--lib/ssl/src/ssl_crl.erl81
-rw-r--r--lib/ssl/src/ssl_crl_cache.erl180
-rw-r--r--lib/ssl/src/ssl_crl_cache_api.erl31
-rw-r--r--lib/ssl/src/ssl_dist_sup.erl21
-rw-r--r--lib/ssl/src/ssl_handshake.erl528
-rw-r--r--lib/ssl/src/ssl_handshake.hrl30
-rw-r--r--lib/ssl/src/ssl_internal.hrl47
-rw-r--r--lib/ssl/src/ssl_listen_tracker_sup.erl21
-rw-r--r--lib/ssl/src/ssl_manager.erl396
-rw-r--r--lib/ssl/src/ssl_pkix_db.erl95
-rw-r--r--lib/ssl/src/ssl_record.erl74
-rw-r--r--lib/ssl/src/ssl_record.hrl24
-rw-r--r--lib/ssl/src/ssl_session.erl36
-rw-r--r--lib/ssl/src/ssl_session_cache.erl39
-rw-r--r--lib/ssl/src/ssl_session_cache_api.erl20
-rw-r--r--lib/ssl/src/ssl_socket.erl19
-rw-r--r--lib/ssl/src/ssl_srp.hrl21
-rw-r--r--lib/ssl/src/ssl_sup.erl19
-rw-r--r--lib/ssl/src/ssl_tls_dist_proxy.erl194
-rw-r--r--lib/ssl/src/ssl_v2.erl21
-rw-r--r--lib/ssl/src/ssl_v3.erl25
-rw-r--r--lib/ssl/src/tls.erl19
-rw-r--r--lib/ssl/src/tls_connection.erl171
-rw-r--r--lib/ssl/src/tls_connection.hrl21
-rw-r--r--lib/ssl/src/tls_connection_sup.erl21
-rw-r--r--lib/ssl/src/tls_handshake.erl85
-rw-r--r--lib/ssl/src/tls_handshake.hrl21
-rw-r--r--lib/ssl/src/tls_record.erl144
-rw-r--r--lib/ssl/src/tls_record.hrl21
-rw-r--r--lib/ssl/src/tls_v1.erl116
-rw-r--r--lib/ssl/test/Makefile25
-rw-r--r--lib/ssl/test/erl_make_certs.erl41
-rw-r--r--lib/ssl/test/make_certs.erl128
-rw-r--r--lib/ssl/test/ssl.spec3
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE.erl93
-rw-r--r--lib/ssl/test/ssl_alpn_handshake_SUITE.erl419
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl661
-rw-r--r--lib/ssl/test/ssl_bench.spec1
-rw-r--r--lib/ssl/test/ssl_bench_SUITE.erl367
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl227
-rw-r--r--lib/ssl/test/ssl_cipher_SUITE.erl56
-rw-r--r--lib/ssl/test/ssl_crl_SUITE.erl675
-rw-r--r--lib/ssl/test/ssl_dist_SUITE.erl239
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl80
-rw-r--r--lib/ssl/test/ssl_npn_handshake_SUITE.erl50
-rw-r--r--lib/ssl/test/ssl_npn_hello_SUITE.erl30
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl36
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl48
-rw-r--r--lib/ssl/test/ssl_pem_cache_SUITE.erl39
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl311
-rw-r--r--lib/ssl/test/ssl_sni_SUITE.erl190
-rw-r--r--lib/ssl/test/ssl_test_lib.erl274
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl833
-rw-r--r--lib/ssl/test/ssl_upgrade_SUITE.erl278
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/Makefile21
-rw-r--r--lib/stdlib/doc/src/Makefile26
-rw-r--r--lib/stdlib/doc/src/array.xml28
-rw-r--r--lib/stdlib/doc/src/assert_hrl.xml158
-rw-r--r--lib/stdlib/doc/src/base64.xml21
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml37
-rw-r--r--lib/stdlib/doc/src/binary.xml33
-rw-r--r--lib/stdlib/doc/src/book.xml21
-rw-r--r--lib/stdlib/doc/src/c.xml31
-rw-r--r--lib/stdlib/doc/src/calendar.xml31
-rw-r--r--lib/stdlib/doc/src/dets.xml108
-rw-r--r--lib/stdlib/doc/src/dict.xml24
-rw-r--r--lib/stdlib/doc/src/digraph.xml27
-rw-r--r--lib/stdlib/doc/src/digraph_utils.xml26
-rw-r--r--lib/stdlib/doc/src/epp.xml21
-rw-r--r--lib/stdlib/doc/src/erl_anno.xml309
-rw-r--r--lib/stdlib/doc/src/erl_eval.xml21
-rw-r--r--lib/stdlib/doc/src/erl_expand_records.xml19
-rw-r--r--lib/stdlib/doc/src/erl_id_trans.xml19
-rw-r--r--lib/stdlib/doc/src/erl_internal.xml19
-rw-r--r--lib/stdlib/doc/src/erl_lint.xml19
-rw-r--r--lib/stdlib/doc/src/erl_parse.xml119
-rw-r--r--lib/stdlib/doc/src/erl_pp.xml23
-rw-r--r--lib/stdlib/doc/src/erl_scan.xml134
-rw-r--r--lib/stdlib/doc/src/erl_tar.xml24
-rw-r--r--lib/stdlib/doc/src/ets.xml118
-rw-r--r--lib/stdlib/doc/src/file_sorter.xml77
-rw-r--r--lib/stdlib/doc/src/filelib.xml21
-rw-r--r--lib/stdlib/doc/src/filename.xml23
-rw-r--r--lib/stdlib/doc/src/gb_sets.xml38
-rw-r--r--lib/stdlib/doc/src/gb_trees.xml38
-rw-r--r--lib/stdlib/doc/src/gen_event.xml58
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml70
-rw-r--r--lib/stdlib/doc/src/gen_server.xml62
-rw-r--r--lib/stdlib/doc/src/io.xml40
-rw-r--r--lib/stdlib/doc/src/io_lib.xml91
-rw-r--r--lib/stdlib/doc/src/io_protocol.xml21
-rw-r--r--lib/stdlib/doc/src/lib.xml21
-rw-r--r--lib/stdlib/doc/src/lists.xml27
-rw-r--r--lib/stdlib/doc/src/log_mf_h.xml19
-rw-r--r--lib/stdlib/doc/src/maps.xml87
-rw-r--r--lib/stdlib/doc/src/math.xml22
-rw-r--r--lib/stdlib/doc/src/ms_transform.xml19
-rw-r--r--lib/stdlib/doc/src/notes.xml602
-rw-r--r--lib/stdlib/doc/src/notes_history.xml21
-rw-r--r--lib/stdlib/doc/src/orddict.xml36
-rw-r--r--lib/stdlib/doc/src/ordsets.xml21
-rw-r--r--lib/stdlib/doc/src/part.xml19
-rw-r--r--lib/stdlib/doc/src/part_notes.xml21
-rw-r--r--lib/stdlib/doc/src/part_notes_history.xml19
-rw-r--r--lib/stdlib/doc/src/pg.xml114
-rw-r--r--lib/stdlib/doc/src/pool.xml21
-rw-r--r--lib/stdlib/doc/src/proc_lib.xml68
-rw-r--r--lib/stdlib/doc/src/proplists.xml19
-rw-r--r--lib/stdlib/doc/src/qlc.xml21
-rw-r--r--lib/stdlib/doc/src/queue.xml24
-rw-r--r--lib/stdlib/doc/src/rand.xml247
-rw-r--r--lib/stdlib/doc/src/random.xml43
-rw-r--r--lib/stdlib/doc/src/re.xml35
-rw-r--r--lib/stdlib/doc/src/ref_man.xml25
-rw-r--r--lib/stdlib/doc/src/sets.xml46
-rw-r--r--lib/stdlib/doc/src/shell.xml19
-rw-r--r--lib/stdlib/doc/src/shell_default.xml19
-rw-r--r--lib/stdlib/doc/src/slave.xml21
-rw-r--r--lib/stdlib/doc/src/sofs.xml24
-rw-r--r--lib/stdlib/doc/src/specs.xml3
-rw-r--r--lib/stdlib/doc/src/stdlib_app.xml19
-rw-r--r--lib/stdlib/doc/src/string.xml21
-rw-r--r--lib/stdlib/doc/src/supervisor.xml291
-rw-r--r--lib/stdlib/doc/src/supervisor_bridge.xml19
-rw-r--r--lib/stdlib/doc/src/sys.xml36
-rw-r--r--lib/stdlib/doc/src/timer.xml39
-rw-r--r--lib/stdlib/doc/src/unicode.xml21
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml26
-rw-r--r--lib/stdlib/doc/src/win32reg.xml21
-rw-r--r--lib/stdlib/doc/src/zip.xml29
-rw-r--r--lib/stdlib/examples/Makefile21
-rw-r--r--lib/stdlib/examples/erl_id_trans.erl21
-rw-r--r--lib/stdlib/include/assert.hrl261
-rw-r--r--lib/stdlib/include/erl_bits.hrl21
-rw-r--r--lib/stdlib/include/erl_compile.hrl21
-rw-r--r--lib/stdlib/include/ms_transform.hrl21
-rw-r--r--lib/stdlib/include/qlc.hrl21
-rw-r--r--lib/stdlib/include/zip.hrl21
-rw-r--r--lib/stdlib/src/Makefile26
-rw-r--r--lib/stdlib/src/array.erl23
-rw-r--r--lib/stdlib/src/base64.erl21
-rw-r--r--lib/stdlib/src/beam_lib.erl68
-rw-r--r--lib/stdlib/src/binary.erl58
-rw-r--r--lib/stdlib/src/c.erl42
-rw-r--r--lib/stdlib/src/calendar.erl23
-rw-r--r--lib/stdlib/src/dets.erl65
-rw-r--r--lib/stdlib/src/dets.hrl21
-rw-r--r--lib/stdlib/src/dets_server.erl21
-rw-r--r--lib/stdlib/src/dets_sup.erl19
-rw-r--r--lib/stdlib/src/dets_utils.erl27
-rw-r--r--lib/stdlib/src/dets_v8.erl23
-rw-r--r--lib/stdlib/src/dets_v9.erl25
-rw-r--r--lib/stdlib/src/dict.erl33
-rw-r--r--lib/stdlib/src/digraph.erl27
-rw-r--r--lib/stdlib/src/digraph_utils.erl21
-rw-r--r--lib/stdlib/src/edlin.erl40
-rw-r--r--lib/stdlib/src/edlin_expand.erl19
-rw-r--r--lib/stdlib/src/epp.erl190
-rw-r--r--lib/stdlib/src/erl_anno.erl459
-rw-r--r--lib/stdlib/src/erl_bits.erl21
-rw-r--r--lib/stdlib/src/erl_compile.erl19
-rw-r--r--lib/stdlib/src/erl_eval.erl107
-rw-r--r--lib/stdlib/src/erl_expand_records.erl84
-rw-r--r--lib/stdlib/src/erl_internal.erl74
-rw-r--r--lib/stdlib/src/erl_lint.erl900
-rw-r--r--lib/stdlib/src/erl_parse.yrl841
-rw-r--r--lib/stdlib/src/erl_posix_msg.erl21
-rw-r--r--lib/stdlib/src/erl_pp.erl240
-rw-r--r--lib/stdlib/src/erl_scan.erl249
-rw-r--r--lib/stdlib/src/erl_tar.erl23
-rw-r--r--lib/stdlib/src/error_logger_file_h.erl249
-rw-r--r--lib/stdlib/src/error_logger_tty_h.erl258
-rw-r--r--lib/stdlib/src/escript.erl55
-rw-r--r--lib/stdlib/src/ets.erl140
-rw-r--r--lib/stdlib/src/eval_bits.erl21
-rw-r--r--lib/stdlib/src/file_sorter.erl27
-rw-r--r--lib/stdlib/src/filelib.erl19
-rw-r--r--lib/stdlib/src/filename.erl27
-rw-r--r--lib/stdlib/src/gb_sets.erl62
-rw-r--r--lib/stdlib/src/gb_trees.erl57
-rw-r--r--lib/stdlib/src/gen.erl132
-rw-r--r--lib/stdlib/src/gen_event.erl37
-rw-r--r--lib/stdlib/src/gen_fsm.erl33
-rw-r--r--lib/stdlib/src/gen_server.erl56
-rw-r--r--lib/stdlib/src/io.erl23
-rw-r--r--lib/stdlib/src/io_lib.erl67
-rw-r--r--lib/stdlib/src/io_lib_format.erl133
-rw-r--r--lib/stdlib/src/io_lib_fread.erl19
-rw-r--r--lib/stdlib/src/io_lib_pretty.erl21
-rw-r--r--lib/stdlib/src/lib.erl21
-rw-r--r--lib/stdlib/src/lists.erl23
-rw-r--r--lib/stdlib/src/log_mf_h.erl21
-rw-r--r--lib/stdlib/src/maps.erl110
-rw-r--r--lib/stdlib/src/math.erl28
-rw-r--r--lib/stdlib/src/ms_transform.erl32
-rw-r--r--lib/stdlib/src/orddict.erl151
-rw-r--r--lib/stdlib/src/ordsets.erl22
-rw-r--r--lib/stdlib/src/otp_internal.erl130
-rw-r--r--lib/stdlib/src/pg.erl187
-rw-r--r--lib/stdlib/src/pool.erl21
-rw-r--r--lib/stdlib/src/proc_lib.erl136
-rw-r--r--lib/stdlib/src/proplists.erl21
-rw-r--r--lib/stdlib/src/qlc.erl121
-rw-r--r--lib/stdlib/src/qlc_pt.erl687
-rw-r--r--lib/stdlib/src/queue.erl23
-rw-r--r--lib/stdlib/src/rand.erl596
-rw-r--r--lib/stdlib/src/random.erl29
-rw-r--r--lib/stdlib/src/re.erl120
-rw-r--r--lib/stdlib/src/sets.erl23
-rw-r--r--lib/stdlib/src/shell.erl71
-rw-r--r--lib/stdlib/src/shell_default.erl22
-rw-r--r--lib/stdlib/src/slave.erl43
-rw-r--r--lib/stdlib/src/sofs.erl19
-rw-r--r--lib/stdlib/src/stdlib.app.src26
-rw-r--r--lib/stdlib/src/stdlib.appup.src31
-rw-r--r--lib/stdlib/src/string.erl67
-rw-r--r--lib/stdlib/src/supervisor.erl314
-rw-r--r--lib/stdlib/src/supervisor_bridge.erl21
-rw-r--r--lib/stdlib/src/sys.erl46
-rw-r--r--lib/stdlib/src/timer.erl46
-rw-r--r--lib/stdlib/src/unicode.erl25
-rw-r--r--lib/stdlib/src/win32reg.erl28
-rw-r--r--lib/stdlib/src/zip.erl137
-rw-r--r--lib/stdlib/test/ExpandTestCaps.erl19
-rw-r--r--lib/stdlib/test/ExpandTestCaps1.erl19
-rw-r--r--lib/stdlib/test/Makefile6
-rw-r--r--lib/stdlib/test/array_SUITE.erl21
-rw-r--r--lib/stdlib/test/base64_SUITE.erl59
-rw-r--r--lib/stdlib/test/beam_lib_SUITE.erl19
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl142
-rw-r--r--lib/stdlib/test/binref.erl37
-rw-r--r--lib/stdlib/test/c_SUITE.erl21
-rw-r--r--lib/stdlib/test/c_SUITE_data/m.erl21
-rw-r--r--lib/stdlib/test/calendar_SUITE.erl19
-rw-r--r--lib/stdlib/test/dets_SUITE.erl45
-rw-r--r--lib/stdlib/test/dict_SUITE.erl71
-rw-r--r--lib/stdlib/test/dict_test_lib.erl26
-rw-r--r--lib/stdlib/test/digraph_SUITE.erl21
-rw-r--r--lib/stdlib/test/digraph_utils_SUITE.erl21
-rw-r--r--lib/stdlib/test/dummy1_h.erl19
-rw-r--r--lib/stdlib/test/dummy_h.erl21
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl19
-rw-r--r--lib/stdlib/test/epp_SUITE.erl71
-rw-r--r--lib/stdlib/test/epp_SUITE_data/mac.erl21
-rw-r--r--lib/stdlib/test/epp_SUITE_data/mac2.erl21
-rw-r--r--lib/stdlib/test/epp_SUITE_data/mac3.erl21
-rw-r--r--lib/stdlib/test/epp_SUITE_data/pmod.erl21
-rw-r--r--lib/stdlib/test/epp_SUITE_data/variable_1.erl21
-rw-r--r--lib/stdlib/test/epp_SUITE_data/variable_1_include.hrl21
-rw-r--r--lib/stdlib/test/epp_SUITE_data/variable_1_include_dir.hrl21
-rw-r--r--lib/stdlib/test/erl_anno_SUITE.erl569
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl73
-rw-r--r--lib/stdlib/test/erl_expand_records_SUITE.erl21
-rw-r--r--lib/stdlib/test/erl_internal_SUITE.erl86
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl578
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour1.erl6
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour2.erl6
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/callback1.erl6
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/callback2.erl6
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/callback3.erl8
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/format.erl21
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/predef.erl4
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl182
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl306
-rw-r--r--lib/stdlib/test/error_logger_forwarder.erl21
-rw-r--r--lib/stdlib/test/error_logger_h_SUITE.erl406
-rw-r--r--lib/stdlib/test/escript_SUITE.erl19
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_app.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_sup.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_app.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_sup.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main2.erl21
-rw-r--r--lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl19
-rw-r--r--lib/stdlib/test/ets_SUITE.erl505
-rw-r--r--lib/stdlib/test/ets_tough_SUITE.erl19
-rw-r--r--lib/stdlib/test/expand_test.erl19
-rw-r--r--lib/stdlib/test/expand_test1.erl19
-rw-r--r--lib/stdlib/test/file_sorter_SUITE.erl21
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl22
-rw-r--r--lib/stdlib/test/filename_SUITE.erl139
-rw-r--r--lib/stdlib/test/fixtable_SUITE.erl19
-rw-r--r--lib/stdlib/test/format_SUITE.erl19
-rw-r--r--lib/stdlib/test/gen_event_SUITE.erl207
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl343
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl265
-rw-r--r--lib/stdlib/test/id_transform_SUITE.erl74
-rw-r--r--lib/stdlib/test/id_transform_SUITE_data/External.hrl21
-rw-r--r--lib/stdlib/test/id_transform_SUITE_data/m.hrl21
-rw-r--r--lib/stdlib/test/id_transform_SUITE_data/m_i.hrl21
-rw-r--r--lib/stdlib/test/id_transform_SUITE_data/oe_ex.hrl21
-rw-r--r--lib/stdlib/test/io_SUITE.erl302
-rw-r--r--lib/stdlib/test/io_proto_SUITE.erl482
-rw-r--r--lib/stdlib/test/lists_SUITE.erl186
-rw-r--r--lib/stdlib/test/log_mf_h_SUITE.erl21
-rw-r--r--lib/stdlib/test/maps_SUITE.erl100
-rw-r--r--lib/stdlib/test/ms_transform_SUITE.erl19
-rw-r--r--lib/stdlib/test/naughty_child.erl21
-rw-r--r--lib/stdlib/test/proc_lib_SUITE.erl336
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl255
-rw-r--r--lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl19
-rw-r--r--lib/stdlib/test/queue_SUITE.erl19
-rw-r--r--lib/stdlib/test/rand_SUITE.erl540
-rw-r--r--lib/stdlib/test/random_SUITE.erl23
-rw-r--r--lib/stdlib/test/random_iolist.erl21
-rw-r--r--lib/stdlib/test/random_unicode_list.erl21
-rw-r--r--lib/stdlib/test/re_SUITE.erl148
-rw-r--r--lib/stdlib/test/re_testoutput1_replacement_test.erl19
-rw-r--r--lib/stdlib/test/re_testoutput1_split_test.erl19
-rw-r--r--lib/stdlib/test/run_pcre_tests.erl19
-rw-r--r--lib/stdlib/test/select_SUITE.erl21
-rw-r--r--lib/stdlib/test/sets_SUITE.erl65
-rw-r--r--lib/stdlib/test/sets_test_lib.erl26
-rw-r--r--lib/stdlib/test/shell_SUITE.erl30
-rw-r--r--lib/stdlib/test/slave_SUITE.erl19
-rw-r--r--lib/stdlib/test/sofs_SUITE.erl19
-rw-r--r--lib/stdlib/test/stdlib_SUITE.erl102
-rw-r--r--lib/stdlib/test/string_SUITE.erl65
-rw-r--r--lib/stdlib/test/supervisor_1.erl21
-rw-r--r--lib/stdlib/test/supervisor_2.erl19
-rw-r--r--lib/stdlib/test/supervisor_3.erl19
-rw-r--r--lib/stdlib/test/supervisor_SUITE.erl461
-rw-r--r--lib/stdlib/test/supervisor_bridge_SUITE.erl21
-rw-r--r--lib/stdlib/test/supervisor_deadlock.erl14
-rw-r--r--lib/stdlib/test/sys_SUITE.erl37
-rw-r--r--lib/stdlib/test/sys_sp1.erl33
-rw-r--r--lib/stdlib/test/sys_sp2.erl52
-rw-r--r--lib/stdlib/test/tar_SUITE.erl21
-rw-r--r--lib/stdlib/test/timer_SUITE.erl62
-rw-r--r--lib/stdlib/test/timer_simple_SUITE.erl25
-rw-r--r--lib/stdlib/test/unicode_SUITE.erl194
-rw-r--r--lib/stdlib/test/win32reg_SUITE.erl68
-rw-r--r--lib/stdlib/test/y2k_SUITE.erl21
-rw-r--r--lib/stdlib/test/zip_SUITE.erl85
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/Makefile21
-rw-r--r--lib/syntax_tools/doc/Makefile21
-rw-r--r--lib/syntax_tools/doc/overview.edoc83
-rw-r--r--lib/syntax_tools/doc/src/Makefile21
-rw-r--r--lib/syntax_tools/doc/src/book.xml21
-rw-r--r--lib/syntax_tools/doc/src/notes.xml42
-rw-r--r--lib/syntax_tools/doc/src/part.xml21
-rw-r--r--lib/syntax_tools/doc/src/part_notes.xml21
-rw-r--r--lib/syntax_tools/doc/src/ref_man.xml34
-rw-r--r--lib/syntax_tools/examples/Makefile21
-rw-r--r--lib/syntax_tools/examples/merl/Makefile22
-rw-r--r--lib/syntax_tools/examples/merl/basic.erl77
-rw-r--r--lib/syntax_tools/examples/merl/basic_test.erl77
-rw-r--r--lib/syntax_tools/examples/merl/basicc.erl149
-rw-r--r--lib/syntax_tools/examples/merl/lisp.erl160
-rw-r--r--lib/syntax_tools/examples/merl/lisp_test.erl98
-rw-r--r--lib/syntax_tools/examples/merl/lispc.erl102
-rw-r--r--lib/syntax_tools/examples/merl/merl_build.erl104
-rw-r--r--lib/syntax_tools/include/merl.hrl29
-rw-r--r--lib/syntax_tools/src/Makefile22
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl2
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl33
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl9
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl234
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl106
-rw-r--r--lib/syntax_tools/src/erl_tidy.erl30
-rw-r--r--lib/syntax_tools/src/igor.erl23
-rw-r--r--lib/syntax_tools/src/merl.erl1230
-rw-r--r--lib/syntax_tools/src/merl_tests.erl539
-rw-r--r--lib/syntax_tools/src/merl_transform.erl262
-rw-r--r--lib/syntax_tools/src/syntax_tools.app.src5
-rw-r--r--lib/syntax_tools/src/syntax_tools.appup.src19
-rw-r--r--lib/syntax_tools/test/Makefile3
-rw-r--r--lib/syntax_tools/test/merl_SUITE.erl92
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl21
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/test_server/Makefile21
-rw-r--r--lib/test_server/doc/src/Makefile23
-rw-r--r--lib/test_server/doc/src/basics_chapter.xml21
-rw-r--r--lib/test_server/doc/src/book.xml21
-rw-r--r--lib/test_server/doc/src/example_chapter.xml49
-rw-r--r--lib/test_server/doc/src/notes.xml140
-rw-r--r--lib/test_server/doc/src/notes_history.xml21
-rw-r--r--lib/test_server/doc/src/part.xml21
-rw-r--r--lib/test_server/doc/src/part_notes.xml21
-rw-r--r--lib/test_server/doc/src/part_notes_history.xml21
-rw-r--r--lib/test_server/doc/src/ref_man.xml21
-rw-r--r--lib/test_server/doc/src/run_test_chapter.xml21
-rw-r--r--lib/test_server/doc/src/test_server.xml85
-rw-r--r--lib/test_server/doc/src/test_server_app.xml21
-rw-r--r--lib/test_server/doc/src/test_server_ctrl.xml19
-rw-r--r--lib/test_server/doc/src/test_spec_chapter.xml21
-rw-r--r--lib/test_server/doc/src/ts.xml19
-rw-r--r--lib/test_server/doc/src/why_test_chapter.xml21
-rw-r--r--lib/test_server/doc/src/write_framework_chapter.xml21
-rw-r--r--lib/test_server/doc/src/write_test_chapter.xml21
-rw-r--r--lib/test_server/include/test_server.hrl23
-rw-r--r--lib/test_server/include/test_server_line.hrl21
-rw-r--r--lib/test_server/src/Makefile19
-rw-r--r--lib/test_server/src/configure.in21
-rw-r--r--lib/test_server/src/erl2html2.erl78
-rw-r--r--lib/test_server/src/test_server.app.src27
-rw-r--r--lib/test_server/src/test_server.appup.src19
-rw-r--r--lib/test_server/src/test_server.erl546
-rw-r--r--lib/test_server/src/test_server_ctrl.erl218
-rw-r--r--lib/test_server/src/test_server_gl.erl104
-rw-r--r--lib/test_server/src/test_server_internal.hrl20
-rw-r--r--lib/test_server/src/test_server_io.erl19
-rw-r--r--lib/test_server/src/test_server_node.erl76
-rw-r--r--lib/test_server/src/test_server_sup.erl40
-rw-r--r--lib/test_server/src/things/distr_startup_SUITE.erl21
-rw-r--r--lib/test_server/src/things/mnesia_power_SUITE.erl21
-rw-r--r--lib/test_server/src/things/random_kill_SUITE.erl21
-rw-r--r--lib/test_server/src/things/verify.erl21
-rw-r--r--lib/test_server/src/ts.erl623
-rw-r--r--lib/test_server/src/ts.hrl21
-rw-r--r--lib/test_server/src/ts_autoconf_win32.erl21
-rw-r--r--lib/test_server/src/ts_benchmark.erl19
-rw-r--r--lib/test_server/src/ts_erl_config.erl19
-rw-r--r--lib/test_server/src/ts_install.erl19
-rw-r--r--lib/test_server/src/ts_install_cth.erl53
-rw-r--r--lib/test_server/src/ts_lib.erl76
-rw-r--r--lib/test_server/src/ts_make.erl21
-rw-r--r--lib/test_server/src/ts_run.erl19
-rw-r--r--lib/test_server/test/Makefile21
-rw-r--r--lib/test_server/test/erl2html2_SUITE.erl87
-rw-r--r--lib/test_server/test/erl2html2_SUITE_data/include/header3.hrl1
-rw-r--r--lib/test_server/test/erl2html2_SUITE_data/m1.erl6
-rw-r--r--lib/test_server/test/test_server_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_break_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_cover_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_test_lib.erl19
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/Makefile21
-rw-r--r--lib/tools/c_src/Makefile.in21
-rw-r--r--lib/tools/c_src/erl_memory.c19
-rw-r--r--lib/tools/c_src/erl_memory_trace_block_table.c21
-rw-r--r--lib/tools/c_src/erl_memory_trace_block_table.h21
-rw-r--r--lib/tools/doc/src/Makefile19
-rw-r--r--lib/tools/doc/src/book.xml21
-rw-r--r--lib/tools/doc/src/cover.xml128
-rw-r--r--lib/tools/doc/src/cover_chapter.xml21
-rw-r--r--lib/tools/doc/src/cprof.xml21
-rw-r--r--lib/tools/doc/src/cprof_chapter.xml21
-rw-r--r--lib/tools/doc/src/eprof.xml21
-rw-r--r--lib/tools/doc/src/erlang_mode.xml21
-rw-r--r--lib/tools/doc/src/erlang_mode_chapter.xml21
-rw-r--r--lib/tools/doc/src/fprof.xml21
-rw-r--r--lib/tools/doc/src/fprof_chapter.xml21
-rw-r--r--lib/tools/doc/src/instrument.xml21
-rw-r--r--lib/tools/doc/src/lcnt.xml25
-rw-r--r--lib/tools/doc/src/lcnt_chapter.xml19
-rw-r--r--lib/tools/doc/src/make.xml21
-rw-r--r--lib/tools/doc/src/notes.xml149
-rw-r--r--lib/tools/doc/src/notes_history.xml21
-rw-r--r--lib/tools/doc/src/part.xml19
-rw-r--r--lib/tools/doc/src/part_notes.xml21
-rw-r--r--lib/tools/doc/src/part_notes_history.xml19
-rw-r--r--lib/tools/doc/src/ref_man.xml19
-rw-r--r--lib/tools/doc/src/tags.xml19
-rw-r--r--lib/tools/doc/src/xref.xml19
-rw-r--r--lib/tools/doc/src/xref_chapter.xml21
-rw-r--r--lib/tools/emacs/Makefile21
-rw-r--r--lib/tools/emacs/erlang-eunit.el19
-rw-r--r--lib/tools/emacs/erlang-skels-old.el35
-rw-r--r--lib/tools/emacs/erlang-skels.el58
-rw-r--r--lib/tools/emacs/erlang.el59
-rw-r--r--lib/tools/emacs/internal_doc/emacs.sgml21
-rw-r--r--lib/tools/emacs/test.erl.indented27
-rw-r--r--lib/tools/emacs/test.erl.orig27
-rw-r--r--lib/tools/examples/Makefile21
-rw-r--r--lib/tools/priv/Makefile21
-rw-r--r--lib/tools/src/Makefile19
-rw-r--r--lib/tools/src/cover.erl1018
-rw-r--r--lib/tools/src/cover_web.erl23
-rw-r--r--lib/tools/src/cprof.erl24
-rw-r--r--lib/tools/src/eprof.erl47
-rw-r--r--lib/tools/src/fprof.erl29
-rw-r--r--lib/tools/src/instrument.erl21
-rw-r--r--lib/tools/src/lcnt.erl20
-rw-r--r--lib/tools/src/make.erl31
-rw-r--r--lib/tools/src/tags.erl21
-rw-r--r--lib/tools/src/tools.app.src27
-rw-r--r--lib/tools/src/tools.appup.src19
-rw-r--r--lib/tools/src/xref.erl21
-rw-r--r--lib/tools/src/xref.hrl25
-rw-r--r--lib/tools/src/xref_base.erl19
-rw-r--r--lib/tools/src/xref_compiler.erl23
-rw-r--r--lib/tools/src/xref_parser.yrl19
-rw-r--r--lib/tools/src/xref_reader.erl45
-rw-r--r--lib/tools/src/xref_scanner.erl27
-rw-r--r--lib/tools/src/xref_utils.erl42
-rw-r--r--lib/tools/test/Makefile19
-rw-r--r--lib/tools/test/cover_SUITE.erl457
-rw-r--r--lib/tools/test/cover_SUITE_data/cc.erl95
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/t.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/include_eunit_hrl/cover_inc_eunit.erl6
-rw-r--r--lib/tools/test/cprof_SUITE.erl19
-rw-r--r--lib/tools/test/emacs_SUITE.erl19
-rw-r--r--lib/tools/test/emem_SUITE.erl19
-rw-r--r--lib/tools/test/eprof_SUITE.erl19
-rw-r--r--lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl21
-rw-r--r--lib/tools/test/fprof_SUITE.erl19
-rw-r--r--lib/tools/test/fprof_SUITE_data/foo.erl21
-rw-r--r--lib/tools/test/ignore_cores.erl19
-rw-r--r--lib/tools/test/instrument_SUITE.erl19
-rw-r--r--lib/tools/test/lcnt_SUITE.erl29
-rw-r--r--lib/tools/test/make_SUITE.erl19
-rw-r--r--lib/tools/test/make_SUITE_data/Emakefile21
-rw-r--r--lib/tools/test/tools_SUITE.erl19
-rw-r--r--lib/tools/test/xref_SUITE.erl19
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/typer/Makefile21
-rw-r--r--lib/typer/doc/Makefile19
-rw-r--r--lib/typer/doc/src/Makefile19
-rw-r--r--lib/typer/doc/src/book.xml19
-rw-r--r--lib/typer/doc/src/notes.xml48
-rw-r--r--lib/typer/doc/src/part_notes.xml21
-rw-r--r--lib/typer/doc/src/ref_man.xml21
-rw-r--r--lib/typer/doc/src/typer_app.xml19
-rw-r--r--lib/typer/src/Makefile21
-rw-r--r--lib/typer/src/typer.appup.src19
-rw-r--r--lib/typer/src/typer.erl45
-rw-r--r--lib/typer/test/typer_SUITE.erl19
-rw-r--r--lib/typer/vsn.mk2
-rw-r--r--lib/webtool/Makefile21
-rw-r--r--lib/webtool/doc/src/Makefile25
-rw-r--r--lib/webtool/doc/src/book.xml21
-rw-r--r--lib/webtool/doc/src/notes.xml54
-rw-r--r--lib/webtool/doc/src/notes_history.xml19
-rw-r--r--lib/webtool/doc/src/part.xml21
-rw-r--r--lib/webtool/doc/src/part_notes.xml21
-rw-r--r--lib/webtool/doc/src/part_notes_history.xml19
-rw-r--r--lib/webtool/doc/src/ref_man.xml21
-rw-r--r--lib/webtool/doc/src/start_webtool.xml19
-rw-r--r--lib/webtool/doc/src/webtool.xml19
-rw-r--r--lib/webtool/doc/src/webtool_chapter.xml21
-rw-r--r--lib/webtool/priv/Makefile21
-rw-r--r--lib/webtool/src/Makefile21
-rw-r--r--lib/webtool/src/webtool.app.src21
-rw-r--r--lib/webtool/src/webtool.appup.src21
-rw-r--r--lib/webtool/src/webtool.erl20
-rw-r--r--lib/webtool/src/webtool_sup.erl21
-rw-r--r--lib/webtool/test/webtool_SUITE.erl19
-rw-r--r--lib/webtool/vsn.mk2
-rw-r--r--lib/wx/LICENSE.txt178
-rw-r--r--lib/wx/Makefile19
-rw-r--r--lib/wx/api_gen/Makefile23
-rw-r--r--lib/wx/api_gen/gen_util.erl57
-rw-r--r--lib/wx/api_gen/gl_gen.erl21
-rw-r--r--lib/wx/api_gen/gl_gen_c.erl19
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl31
-rw-r--r--lib/wx/api_gen/gl_scan_doc.erl19
-rw-r--r--lib/wx/api_gen/wx_extra/added_func.h41
-rw-r--r--lib/wx/api_gen/wx_extra/wxEvtHandler.c_src6
-rw-r--r--lib/wx/api_gen/wx_extra/wxEvtHandler.erl2
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.c_src19
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.erl19
-rw-r--r--lib/wx/api_gen/wx_extra/wxPrintout.erl21
-rw-r--r--lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src19
-rw-r--r--lib/wx/api_gen/wx_extra/wxXmlResource.erl21
-rw-r--r--lib/wx/api_gen/wx_gen.erl46
-rw-r--r--lib/wx/api_gen/wx_gen.hrl19
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl150
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl21
-rw-r--r--lib/wx/api_gen/wxapi.conf175
-rw-r--r--lib/wx/c_src/Makefile.in19
-rw-r--r--lib/wx/c_src/egl_impl.cpp19
-rw-r--r--lib/wx/c_src/egl_impl.h21
-rw-r--r--lib/wx/c_src/gen/gl_fdefs.h19
-rw-r--r--lib/wx/c_src/gen/gl_finit.h19
-rw-r--r--lib/wx/c_src/gen/gl_funcs.cpp19
-rw-r--r--lib/wx/c_src/gen/glu_finit.h19
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h33
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp672
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp565
-rw-r--r--lib/wx/c_src/gen/wxe_init.cpp495
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h6355
-rw-r--r--lib/wx/c_src/wxe_callback_impl.cpp19
-rw-r--r--lib/wx/c_src/wxe_callback_impl.h19
-rw-r--r--lib/wx/c_src/wxe_driver.c66
-rw-r--r--lib/wx/c_src/wxe_driver.h26
-rw-r--r--lib/wx/c_src/wxe_events.h19
-rw-r--r--lib/wx/c_src/wxe_gl.cpp67
-rw-r--r--lib/wx/c_src/wxe_gl.h23
-rw-r--r--lib/wx/c_src/wxe_helpers.cpp253
-rw-r--r--lib/wx/c_src/wxe_helpers.h55
-rw-r--r--lib/wx/c_src/wxe_impl.cpp353
-rw-r--r--lib/wx/c_src/wxe_impl.h33
-rw-r--r--lib/wx/c_src/wxe_main.cpp19
-rw-r--r--lib/wx/c_src/wxe_memory.h19
-rw-r--r--lib/wx/c_src/wxe_ps_init.c21
-rw-r--r--lib/wx/c_src/wxe_return.cpp151
-rw-r--r--lib/wx/c_src/wxe_return.h45
-rw-r--r--lib/wx/config.mk.in21
-rw-r--r--lib/wx/configure.in48
-rw-r--r--lib/wx/doc/src/Makefile19
-rw-r--r--lib/wx/doc/src/book.xml21
-rw-r--r--lib/wx/doc/src/notes.xml117
-rw-r--r--lib/wx/doc/src/part.xml21
-rw-r--r--lib/wx/doc/src/part_notes.xml21
-rw-r--r--lib/wx/doc/src/ref_man.xml.src21
-rw-r--r--lib/wx/examples/Makefile19
-rw-r--r--lib/wx/examples/demo/Makefile19
-rw-r--r--lib/wx/examples/demo/demo.erl31
-rw-r--r--lib/wx/examples/demo/demo_html_tagger.erl27
-rw-r--r--lib/wx/examples/demo/ex_aui.erl102
-rw-r--r--lib/wx/examples/demo/ex_button.erl21
-rw-r--r--lib/wx/examples/demo/ex_canvas.erl68
-rw-r--r--lib/wx/examples/demo/ex_canvas_paint.erl21
-rw-r--r--lib/wx/examples/demo/ex_choices.erl21
-rw-r--r--lib/wx/examples/demo/ex_cursor.erl21
-rw-r--r--lib/wx/examples/demo/ex_dialogs.erl21
-rw-r--r--lib/wx/examples/demo/ex_frame_utils.erl21
-rw-r--r--lib/wx/examples/demo/ex_gauge.erl21
-rw-r--r--lib/wx/examples/demo/ex_gl.erl21
-rw-r--r--lib/wx/examples/demo/ex_graphicsContext.erl21
-rw-r--r--lib/wx/examples/demo/ex_grid.erl21
-rw-r--r--lib/wx/examples/demo/ex_htmlWindow.erl21
-rw-r--r--lib/wx/examples/demo/ex_listCtrl.erl19
-rw-r--r--lib/wx/examples/demo/ex_notebook.erl21
-rw-r--r--lib/wx/examples/demo/ex_pickers.erl21
-rw-r--r--lib/wx/examples/demo/ex_popupMenu.erl21
-rw-r--r--lib/wx/examples/demo/ex_radioBox.erl21
-rw-r--r--lib/wx/examples/demo/ex_sashWindow.erl21
-rw-r--r--lib/wx/examples/demo/ex_sizers.erl21
-rw-r--r--lib/wx/examples/demo/ex_slider.erl21
-rw-r--r--lib/wx/examples/demo/ex_splitterWindow.erl21
-rw-r--r--lib/wx/examples/demo/ex_static.erl21
-rw-r--r--lib/wx/examples/demo/ex_textCtrl.erl21
-rw-r--r--lib/wx/examples/demo/ex_treeCtrl.erl21
-rw-r--r--lib/wx/examples/simple/Makefile19
-rw-r--r--lib/wx/examples/simple/hello.erl21
-rw-r--r--lib/wx/examples/simple/hello2.erl21
-rw-r--r--lib/wx/examples/simple/menu.erl21
-rw-r--r--lib/wx/examples/simple/minimal.erl21
-rw-r--r--lib/wx/examples/sudoku/Makefile19
-rw-r--r--lib/wx/examples/sudoku/sudoku.erl21
-rw-r--r--lib/wx/examples/sudoku/sudoku.hrl21
-rw-r--r--lib/wx/examples/sudoku/sudoku_board.erl21
-rw-r--r--lib/wx/examples/sudoku/sudoku_game.erl21
-rw-r--r--lib/wx/examples/sudoku/sudoku_gui.erl21
-rw-r--r--lib/wx/examples/xrc/Makefile21
-rw-r--r--lib/wx/examples/xrc/xrc.erl21
-rw-r--r--lib/wx/include/gl.hrl19
-rw-r--r--lib/wx/include/glu.hrl19
-rw-r--r--lib/wx/include/wx.hrl551
-rw-r--r--lib/wx/license.terms286
-rw-r--r--lib/wx/src/Makefile19
-rw-r--r--lib/wx/src/gen/gl.erl91
-rw-r--r--lib/wx/src/gen/glu.erl27
-rw-r--r--lib/wx/src/gen/wxAcceleratorEntry.erl19
-rw-r--r--lib/wx/src/gen/wxAcceleratorTable.erl19
-rw-r--r--lib/wx/src/gen/wxActivateEvent.erl19
-rw-r--r--lib/wx/src/gen/wxArtProvider.erl19
-rw-r--r--lib/wx/src/gen/wxAuiDockArt.erl78
-rw-r--r--lib/wx/src/gen/wxAuiManager.erl23
-rw-r--r--lib/wx/src/gen/wxAuiManagerEvent.erl23
-rw-r--r--lib/wx/src/gen/wxAuiNotebook.erl60
-rw-r--r--lib/wx/src/gen/wxAuiNotebookEvent.erl19
-rw-r--r--lib/wx/src/gen/wxAuiPaneInfo.erl109
-rw-r--r--lib/wx/src/gen/wxAuiSimpleTabArt.erl67
-rw-r--r--lib/wx/src/gen/wxAuiTabArt.erl78
-rw-r--r--lib/wx/src/gen/wxBitmap.erl19
-rw-r--r--lib/wx/src/gen/wxBitmapButton.erl66
-rw-r--r--lib/wx/src/gen/wxBitmapDataObject.erl19
-rw-r--r--lib/wx/src/gen/wxBoxSizer.erl19
-rw-r--r--lib/wx/src/gen/wxBrush.erl19
-rw-r--r--lib/wx/src/gen/wxBufferedDC.erl19
-rw-r--r--lib/wx/src/gen/wxBufferedPaintDC.erl19
-rw-r--r--lib/wx/src/gen/wxButton.erl62
-rw-r--r--lib/wx/src/gen/wxCalendarCtrl.erl62
-rw-r--r--lib/wx/src/gen/wxCalendarDateAttr.erl19
-rw-r--r--lib/wx/src/gen/wxCalendarEvent.erl19
-rw-r--r--lib/wx/src/gen/wxCaret.erl19
-rw-r--r--lib/wx/src/gen/wxCheckBox.erl62
-rw-r--r--lib/wx/src/gen/wxCheckListBox.erl111
-rw-r--r--lib/wx/src/gen/wxChildFocusEvent.erl19
-rw-r--r--lib/wx/src/gen/wxChoice.erl99
-rw-r--r--lib/wx/src/gen/wxChoicebook.erl62
-rw-r--r--lib/wx/src/gen/wxClientDC.erl19
-rw-r--r--lib/wx/src/gen/wxClipboard.erl19
-rw-r--r--lib/wx/src/gen/wxClipboardTextEvent.erl19
-rw-r--r--lib/wx/src/gen/wxCloseEvent.erl19
-rw-r--r--lib/wx/src/gen/wxColourData.erl19
-rw-r--r--lib/wx/src/gen/wxColourDialog.erl78
-rw-r--r--lib/wx/src/gen/wxColourPickerCtrl.erl86
-rw-r--r--lib/wx/src/gen/wxColourPickerEvent.erl19
-rw-r--r--lib/wx/src/gen/wxComboBox.erl99
-rw-r--r--lib/wx/src/gen/wxCommandEvent.erl19
-rw-r--r--lib/wx/src/gen/wxContextMenuEvent.erl19
-rw-r--r--lib/wx/src/gen/wxControl.erl62
-rw-r--r--lib/wx/src/gen/wxControlWithItems.erl62
-rw-r--r--lib/wx/src/gen/wxCursor.erl19
-rw-r--r--lib/wx/src/gen/wxDC.erl19
-rw-r--r--lib/wx/src/gen/wxDCOverlay.erl70
-rw-r--r--lib/wx/src/gen/wxDataObject.erl19
-rw-r--r--lib/wx/src/gen/wxDateEvent.erl19
-rw-r--r--lib/wx/src/gen/wxDatePickerCtrl.erl86
-rw-r--r--lib/wx/src/gen/wxDialog.erl86
-rw-r--r--lib/wx/src/gen/wxDirDialog.erl78
-rw-r--r--lib/wx/src/gen/wxDirPickerCtrl.erl86
-rw-r--r--lib/wx/src/gen/wxDisplayChangedEvent.erl19
-rw-r--r--lib/wx/src/gen/wxEraseEvent.erl19
-rw-r--r--lib/wx/src/gen/wxEvent.erl19
-rw-r--r--lib/wx/src/gen/wxEvtHandler.erl21
-rw-r--r--lib/wx/src/gen/wxFileDataObject.erl19
-rw-r--r--lib/wx/src/gen/wxFileDialog.erl78
-rw-r--r--lib/wx/src/gen/wxFileDirPickerEvent.erl19
-rw-r--r--lib/wx/src/gen/wxFilePickerCtrl.erl86
-rw-r--r--lib/wx/src/gen/wxFindReplaceData.erl19
-rw-r--r--lib/wx/src/gen/wxFindReplaceDialog.erl78
-rw-r--r--lib/wx/src/gen/wxFlexGridSizer.erl19
-rw-r--r--lib/wx/src/gen/wxFocusEvent.erl19
-rw-r--r--lib/wx/src/gen/wxFont.erl19
-rw-r--r--lib/wx/src/gen/wxFontData.erl19
-rw-r--r--lib/wx/src/gen/wxFontDialog.erl78
-rw-r--r--lib/wx/src/gen/wxFontPickerCtrl.erl86
-rw-r--r--lib/wx/src/gen/wxFontPickerEvent.erl19
-rw-r--r--lib/wx/src/gen/wxFrame.erl86
-rw-r--r--lib/wx/src/gen/wxGBSizerItem.erl19
-rw-r--r--lib/wx/src/gen/wxGLCanvas.erl62
-rw-r--r--lib/wx/src/gen/wxGauge.erl62
-rw-r--r--lib/wx/src/gen/wxGenericDirCtrl.erl62
-rw-r--r--lib/wx/src/gen/wxGraphicsBrush.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsContext.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsFont.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsMatrix.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsObject.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsPath.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsPen.erl19
-rw-r--r--lib/wx/src/gen/wxGraphicsRenderer.erl19
-rw-r--r--lib/wx/src/gen/wxGrid.erl76
-rw-r--r--lib/wx/src/gen/wxGridBagSizer.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellAttr.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellBoolEditor.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellBoolRenderer.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellChoiceEditor.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellEditor.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellFloatEditor.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellFloatRenderer.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellNumberEditor.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellNumberRenderer.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellRenderer.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellStringRenderer.erl19
-rw-r--r--lib/wx/src/gen/wxGridCellTextEditor.erl19
-rw-r--r--lib/wx/src/gen/wxGridEvent.erl19
-rw-r--r--lib/wx/src/gen/wxGridSizer.erl19
-rw-r--r--lib/wx/src/gen/wxHelpEvent.erl19
-rw-r--r--lib/wx/src/gen/wxHtmlEasyPrinting.erl19
-rw-r--r--lib/wx/src/gen/wxHtmlLinkEvent.erl19
-rw-r--r--lib/wx/src/gen/wxHtmlWindow.erl76
-rw-r--r--lib/wx/src/gen/wxIcon.erl19
-rw-r--r--lib/wx/src/gen/wxIconBundle.erl19
-rw-r--r--lib/wx/src/gen/wxIconizeEvent.erl19
-rw-r--r--lib/wx/src/gen/wxIdleEvent.erl19
-rw-r--r--lib/wx/src/gen/wxImage.erl19
-rw-r--r--lib/wx/src/gen/wxImageList.erl19
-rw-r--r--lib/wx/src/gen/wxInitDialogEvent.erl19
-rw-r--r--lib/wx/src/gen/wxJoystickEvent.erl19
-rw-r--r--lib/wx/src/gen/wxKeyEvent.erl19
-rw-r--r--lib/wx/src/gen/wxLayoutAlgorithm.erl19
-rw-r--r--lib/wx/src/gen/wxListBox.erl99
-rw-r--r--lib/wx/src/gen/wxListCtrl.erl80
-rw-r--r--lib/wx/src/gen/wxListEvent.erl19
-rw-r--r--lib/wx/src/gen/wxListItem.erl19
-rw-r--r--lib/wx/src/gen/wxListItemAttr.erl19
-rw-r--r--lib/wx/src/gen/wxListView.erl62
-rw-r--r--lib/wx/src/gen/wxListbook.erl62
-rw-r--r--lib/wx/src/gen/wxLocale.erl19
-rw-r--r--lib/wx/src/gen/wxLogNull.erl19
-rw-r--r--lib/wx/src/gen/wxMDIChildFrame.erl80
-rw-r--r--lib/wx/src/gen/wxMDIClientWindow.erl62
-rw-r--r--lib/wx/src/gen/wxMDIParentFrame.erl85
-rw-r--r--lib/wx/src/gen/wxMask.erl19
-rw-r--r--lib/wx/src/gen/wxMaximizeEvent.erl19
-rw-r--r--lib/wx/src/gen/wxMemoryDC.erl19
-rw-r--r--lib/wx/src/gen/wxMenu.erl19
-rw-r--r--lib/wx/src/gen/wxMenuBar.erl67
-rw-r--r--lib/wx/src/gen/wxMenuEvent.erl19
-rw-r--r--lib/wx/src/gen/wxMenuItem.erl19
-rw-r--r--lib/wx/src/gen/wxMessageDialog.erl78
-rw-r--r--lib/wx/src/gen/wxMiniFrame.erl85
-rw-r--r--lib/wx/src/gen/wxMirrorDC.erl19
-rw-r--r--lib/wx/src/gen/wxMouseCaptureChangedEvent.erl19
-rw-r--r--lib/wx/src/gen/wxMouseCaptureLostEvent.erl65
-rw-r--r--lib/wx/src/gen/wxMouseEvent.erl19
-rw-r--r--lib/wx/src/gen/wxMoveEvent.erl19
-rw-r--r--lib/wx/src/gen/wxMultiChoiceDialog.erl78
-rw-r--r--lib/wx/src/gen/wxNavigationKeyEvent.erl19
-rw-r--r--lib/wx/src/gen/wxNotebook.erl62
-rw-r--r--lib/wx/src/gen/wxNotebookEvent.erl19
-rw-r--r--lib/wx/src/gen/wxNotifyEvent.erl19
-rw-r--r--lib/wx/src/gen/wxOverlay.erl57
-rw-r--r--lib/wx/src/gen/wxPageSetupDialog.erl19
-rw-r--r--lib/wx/src/gen/wxPageSetupDialogData.erl19
-rw-r--r--lib/wx/src/gen/wxPaintDC.erl19
-rw-r--r--lib/wx/src/gen/wxPaintEvent.erl19
-rw-r--r--lib/wx/src/gen/wxPalette.erl19
-rw-r--r--lib/wx/src/gen/wxPaletteChangedEvent.erl19
-rw-r--r--lib/wx/src/gen/wxPanel.erl62
-rw-r--r--lib/wx/src/gen/wxPasswordEntryDialog.erl69
-rw-r--r--lib/wx/src/gen/wxPen.erl19
-rw-r--r--lib/wx/src/gen/wxPickerBase.erl62
-rw-r--r--lib/wx/src/gen/wxPopupTransientWindow.erl66
-rw-r--r--lib/wx/src/gen/wxPopupWindow.erl62
-rw-r--r--lib/wx/src/gen/wxPostScriptDC.erl19
-rw-r--r--lib/wx/src/gen/wxPreviewCanvas.erl76
-rw-r--r--lib/wx/src/gen/wxPreviewControlBar.erl62
-rw-r--r--lib/wx/src/gen/wxPreviewFrame.erl85
-rw-r--r--lib/wx/src/gen/wxPrintData.erl19
-rw-r--r--lib/wx/src/gen/wxPrintDialog.erl78
-rw-r--r--lib/wx/src/gen/wxPrintDialogData.erl19
-rw-r--r--lib/wx/src/gen/wxPrintPreview.erl19
-rw-r--r--lib/wx/src/gen/wxPrinter.erl19
-rw-r--r--lib/wx/src/gen/wxPrintout.erl19
-rw-r--r--lib/wx/src/gen/wxProgressDialog.erl78
-rw-r--r--lib/wx/src/gen/wxQueryNewPaletteEvent.erl19
-rw-r--r--lib/wx/src/gen/wxRadioBox.erl65
-rw-r--r--lib/wx/src/gen/wxRadioButton.erl62
-rw-r--r--lib/wx/src/gen/wxRegion.erl19
-rw-r--r--lib/wx/src/gen/wxSashEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSashLayoutWindow.erl53
-rw-r--r--lib/wx/src/gen/wxSashWindow.erl62
-rw-r--r--lib/wx/src/gen/wxScreenDC.erl19
-rw-r--r--lib/wx/src/gen/wxScrollBar.erl64
-rw-r--r--lib/wx/src/gen/wxScrollEvent.erl19
-rw-r--r--lib/wx/src/gen/wxScrollWinEvent.erl19
-rw-r--r--lib/wx/src/gen/wxScrolledWindow.erl62
-rw-r--r--lib/wx/src/gen/wxSetCursorEvent.erl19
-rw-r--r--lib/wx/src/gen/wxShowEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSingleChoiceDialog.erl78
-rw-r--r--lib/wx/src/gen/wxSizeEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSizer.erl19
-rw-r--r--lib/wx/src/gen/wxSizerFlags.erl19
-rw-r--r--lib/wx/src/gen/wxSizerItem.erl19
-rw-r--r--lib/wx/src/gen/wxSlider.erl62
-rw-r--r--lib/wx/src/gen/wxSpinButton.erl62
-rw-r--r--lib/wx/src/gen/wxSpinCtrl.erl62
-rw-r--r--lib/wx/src/gen/wxSpinEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSplashScreen.erl85
-rw-r--r--lib/wx/src/gen/wxSplitterEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSplitterWindow.erl62
-rw-r--r--lib/wx/src/gen/wxStaticBitmap.erl62
-rw-r--r--lib/wx/src/gen/wxStaticBox.erl62
-rw-r--r--lib/wx/src/gen/wxStaticBoxSizer.erl19
-rw-r--r--lib/wx/src/gen/wxStaticLine.erl62
-rw-r--r--lib/wx/src/gen/wxStaticText.erl62
-rw-r--r--lib/wx/src/gen/wxStatusBar.erl62
-rw-r--r--lib/wx/src/gen/wxStdDialogButtonSizer.erl19
-rw-r--r--lib/wx/src/gen/wxStyledTextCtrl.erl79
-rw-r--r--lib/wx/src/gen/wxStyledTextEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSysColourChangedEvent.erl19
-rw-r--r--lib/wx/src/gen/wxSystemOptions.erl19
-rw-r--r--lib/wx/src/gen/wxSystemSettings.erl19
-rw-r--r--lib/wx/src/gen/wxTaskBarIcon.erl19
-rw-r--r--lib/wx/src/gen/wxTaskBarIconEvent.erl19
-rw-r--r--lib/wx/src/gen/wxTextAttr.erl19
-rw-r--r--lib/wx/src/gen/wxTextCtrl.erl62
-rw-r--r--lib/wx/src/gen/wxTextDataObject.erl19
-rw-r--r--lib/wx/src/gen/wxTextEntryDialog.erl78
-rw-r--r--lib/wx/src/gen/wxToggleButton.erl62
-rw-r--r--lib/wx/src/gen/wxToolBar.erl96
-rw-r--r--lib/wx/src/gen/wxToolTip.erl19
-rw-r--r--lib/wx/src/gen/wxToolbook.erl62
-rw-r--r--lib/wx/src/gen/wxTopLevelWindow.erl62
-rw-r--r--lib/wx/src/gen/wxTreeCtrl.erl62
-rw-r--r--lib/wx/src/gen/wxTreeEvent.erl19
-rw-r--r--lib/wx/src/gen/wxTreebook.erl62
-rw-r--r--lib/wx/src/gen/wxUpdateUIEvent.erl19
-rw-r--r--lib/wx/src/gen/wxWindow.erl97
-rw-r--r--lib/wx/src/gen/wxWindowCreateEvent.erl19
-rw-r--r--lib/wx/src/gen/wxWindowDC.erl19
-rw-r--r--lib/wx/src/gen/wxWindowDestroyEvent.erl19
-rw-r--r--lib/wx/src/gen/wxXmlResource.erl19
-rw-r--r--lib/wx/src/gen/wx_misc.erl19
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl6354
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl6354
-rw-r--r--lib/wx/src/wx.app.src19
-rw-r--r--lib/wx/src/wx.appup.src19
-rw-r--r--lib/wx/src/wx.erl19
-rw-r--r--lib/wx/src/wx_object.erl74
-rw-r--r--lib/wx/src/wxe.hrl21
-rw-r--r--lib/wx/src/wxe_master.erl19
-rw-r--r--lib/wx/src/wxe_server.erl97
-rw-r--r--lib/wx/src/wxe_util.erl38
-rw-r--r--lib/wx/test/Makefile19
-rw-r--r--lib/wx/test/wx_app_SUITE.erl19
-rw-r--r--lib/wx/test/wx_basic_SUITE.erl66
-rw-r--r--lib/wx/test/wx_class_SUITE.erl119
-rw-r--r--lib/wx/test/wx_event_SUITE.erl111
-rw-r--r--lib/wx/test/wx_obj_test.erl37
-rw-r--r--lib/wx/test/wx_opengl_SUITE.erl21
-rw-r--r--lib/wx/test/wx_test_lib.erl21
-rw-r--r--lib/wx/test/wx_test_lib.hrl21
-rw-r--r--lib/wx/test/wx_xtra_SUITE.erl19
-rwxr-xr-xlib/wx/test/wxt23
-rw-r--r--lib/wx/test/wxt.erl19
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/Makefile19
-rw-r--r--lib/xmerl/doc/examples/test_html.erl18
-rw-r--r--lib/xmerl/doc/src/Makefile19
-rw-r--r--lib/xmerl/doc/src/book.xml21
-rw-r--r--lib/xmerl/doc/src/notes.xml63
-rw-r--r--lib/xmerl/doc/src/notes_history.xml19
-rw-r--r--lib/xmerl/doc/src/part.xml21
-rw-r--r--lib/xmerl/doc/src/part_notes.xml21
-rw-r--r--lib/xmerl/doc/src/ref_man.xml21
-rw-r--r--lib/xmerl/doc/src/xmerl_sax_parser.xml21
-rw-r--r--lib/xmerl/doc/src/xmerl_ug.xmlsrc21
-rw-r--r--lib/xmerl/include/xmerl.hrl21
-rw-r--r--lib/xmerl/include/xmerl_xpath.hrl18
-rw-r--r--lib/xmerl/include/xmerl_xsd.hrl18
-rw-r--r--lib/xmerl/src/Makefile21
-rw-r--r--lib/xmerl/src/xmerl.app.src2
-rw-r--r--lib/xmerl/src/xmerl.appup.src19
-rw-r--r--lib/xmerl/src/xmerl.erl28
-rw-r--r--lib/xmerl/src/xmerl_b64Bin.yrl21
-rw-r--r--lib/xmerl/src/xmerl_b64Bin_scan.erl21
-rw-r--r--lib/xmerl/src/xmerl_eventp.erl27
-rw-r--r--lib/xmerl/src/xmerl_html.erl21
-rw-r--r--lib/xmerl/src/xmerl_internal.hrl21
-rw-r--r--lib/xmerl/src/xmerl_lib.erl21
-rw-r--r--lib/xmerl/src/xmerl_otpsgml.erl28
-rw-r--r--lib/xmerl/src/xmerl_regexp.erl37
-rw-r--r--lib/xmerl/src/xmerl_sax_old_dom.erl24
-rw-r--r--lib/xmerl/src/xmerl_sax_old_dom.hrl21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser.erl21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser.hrl21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_base.erlsrc24
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_list.erlsrc21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc21
-rw-r--r--lib/xmerl/src/xmerl_sax_simple_dom.erl24
-rw-r--r--lib/xmerl/src/xmerl_scan.erl161
-rw-r--r--lib/xmerl/src/xmerl_sgml.erl21
-rw-r--r--lib/xmerl/src/xmerl_simple.erl21
-rw-r--r--lib/xmerl/src/xmerl_text.erl21
-rw-r--r--lib/xmerl/src/xmerl_ucs.erl34
-rw-r--r--lib/xmerl/src/xmerl_uri.erl21
-rw-r--r--lib/xmerl/src/xmerl_validate.erl37
-rw-r--r--lib/xmerl/src/xmerl_xlate.erl21
-rw-r--r--lib/xmerl/src/xmerl_xml.erl28
-rw-r--r--lib/xmerl/src/xmerl_xpath.erl39
-rw-r--r--lib/xmerl/src/xmerl_xpath_lib.erl21
-rw-r--r--lib/xmerl/src/xmerl_xpath_parse.yrl21
-rw-r--r--lib/xmerl/src/xmerl_xpath_pred.erl24
-rw-r--r--lib/xmerl/src/xmerl_xpath_scan.erl21
-rw-r--r--lib/xmerl/src/xmerl_xs.erl21
-rw-r--r--lib/xmerl/src/xmerl_xsd.erl152
-rw-r--r--lib/xmerl/src/xmerl_xsd_type.erl27
-rw-r--r--lib/xmerl/test/Makefile19
-rw-r--r--lib/xmerl/test/xmerl_SUITE.erl19
-rw-r--r--lib/xmerl/test/xmerl_app_test.erl19
-rw-r--r--lib/xmerl/test/xmerl_appup_test.erl21
-rw-r--r--lib/xmerl/test/xmerl_sax_SUITE.erl21
-rw-r--r--lib/xmerl/test/xmerl_sax_std_SUITE.erl21
-rw-r--r--lib/xmerl/test/xmerl_std_SUITE.erl21
-rw-r--r--lib/xmerl/test/xmerl_test_lib.erl21
-rw-r--r--lib/xmerl/test/xmerl_xsd_MS2002-01-16_SUITE.erl21
-rw-r--r--lib/xmerl/test/xmerl_xsd_NIST2002-01-16_SUITE.erl21
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE.erl37
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml5
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd13
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd287
-rw-r--r--lib/xmerl/test/xmerl_xsd_Sun2002-01-16_SUITE.erl21
-rw-r--r--lib/xmerl/test/xmerl_xsd_lib.erl21
-rw-r--r--lib/xmerl/vsn.mk2
-rwxr-xr-xmake/cross_check_erl40
-rw-r--r--make/emd2exml.in40
-rwxr-xr-xmake/fakefop19
-rwxr-xr-xmake/install_bin19
-rw-r--r--make/lazy_configure.mk21
-rw-r--r--make/ose_lm.mk.in19
-rw-r--r--make/otp.mk.in19
-rw-r--r--make/otp_ded.mk.in19
-rw-r--r--make/otp_default_release_path.mk21
-rw-r--r--make/otp_release_targets.mk33
-rw-r--r--make/otp_released_app.mk21
-rw-r--r--make/otp_subdir.mk21
-rw-r--r--make/output.mk.in19
-rw-r--r--make/run_make.mk23
-rwxr-xr-xmake/save_args21
-rw-r--r--make/target.mk19
-rwxr-xr-xmake/unexpected_use19
-rwxr-xr-xmake/verify_runtime_dependencies19
-rwxr-xr-xotp_build23
-rwxr-xr-xotp_patch_apply19
-rw-r--r--otp_versions.table29
-rw-r--r--system/COPYRIGHT21
-rw-r--r--system/doc/Makefile21
-rw-r--r--system/doc/design_principles/Makefile21
-rw-r--r--system/doc/design_principles/applications.xml291
-rw-r--r--system/doc/design_principles/appup_cookbook.xml393
-rw-r--r--system/doc/design_principles/book.xml21
-rw-r--r--system/doc/design_principles/des_princ.xml136
-rw-r--r--system/doc/design_principles/distributed_applications.xml203
-rw-r--r--system/doc/design_principles/events.xml116
-rw-r--r--system/doc/design_principles/fsm.xml189
-rw-r--r--system/doc/design_principles/gen_server_concepts.xml181
-rw-r--r--system/doc/design_principles/included_applications.xml88
-rw-r--r--system/doc/design_principles/part.xml21
-rw-r--r--system/doc/design_principles/release_handling.xml649
-rw-r--r--system/doc/design_principles/release_structure.xml211
-rw-r--r--system/doc/design_principles/spec_proc.xml269
-rw-r--r--system/doc/design_principles/sup_princ.xml359
-rw-r--r--system/doc/design_principles/xmlfiles.mk21
-rw-r--r--system/doc/efficiency_guide/Makefile21
-rw-r--r--system/doc/efficiency_guide/advanced.xml344
-rw-r--r--system/doc/efficiency_guide/all.erl21
-rw-r--r--system/doc/efficiency_guide/appendix.xml19
-rw-r--r--system/doc/efficiency_guide/bench.erl21
-rw-r--r--system/doc/efficiency_guide/bench.hrl21
-rw-r--r--system/doc/efficiency_guide/binaryhandling.xml383
-rw-r--r--system/doc/efficiency_guide/book.xml21
-rw-r--r--system/doc/efficiency_guide/call_bm.erl21
-rw-r--r--system/doc/efficiency_guide/commoncaveats.xml156
-rw-r--r--system/doc/efficiency_guide/drivers.xml136
-rw-r--r--system/doc/efficiency_guide/functions.xml141
-rw-r--r--system/doc/efficiency_guide/introduction.xml49
-rw-r--r--system/doc/efficiency_guide/listhandling.xml141
-rw-r--r--system/doc/efficiency_guide/myths.xml149
-rw-r--r--system/doc/efficiency_guide/part.xml21
-rw-r--r--system/doc/efficiency_guide/processes.xml180
-rw-r--r--system/doc/efficiency_guide/profiling.xml340
-rw-r--r--system/doc/efficiency_guide/tablesDatabases.xml215
-rw-r--r--system/doc/efficiency_guide/xmlfiles.mk21
-rw-r--r--system/doc/embedded/Makefile21
-rw-r--r--system/doc/embedded/book.xml21
-rw-r--r--system/doc/embedded/embedded_nt.xml78
-rw-r--r--system/doc/embedded/embedded_solaris.xml795
-rw-r--r--system/doc/embedded/intro.xml19
-rw-r--r--system/doc/embedded/part.xml37
-rw-r--r--system/doc/embedded/starting.xml21
-rw-r--r--system/doc/embedded/target.xml21
-rw-r--r--system/doc/embedded/vme_problems.xml19
-rw-r--r--system/doc/embedded/xmlfiles.mk21
-rw-r--r--system/doc/embedded/xntp.xml19
-rw-r--r--system/doc/getting_started/Makefile21
-rw-r--r--system/doc/getting_started/book.xml21
-rw-r--r--system/doc/getting_started/conc_prog.xml371
-rw-r--r--system/doc/getting_started/intro.xml84
-rw-r--r--system/doc/getting_started/part.xml21
-rw-r--r--system/doc/getting_started/records_macros.xml109
-rw-r--r--system/doc/getting_started/robustness.xml166
-rw-r--r--system/doc/getting_started/seq_prog.xml844
-rw-r--r--system/doc/getting_started/xmlfiles.mk21
-rw-r--r--system/doc/installation_guide/Makefile19
-rw-r--r--system/doc/installation_guide/book.xml21
-rw-r--r--system/doc/installation_guide/install-binary.xml43
-rw-r--r--system/doc/installation_guide/part.xml22
-rw-r--r--system/doc/installation_guide/xmlfiles.mk19
-rw-r--r--system/doc/oam/Makefile21
-rw-r--r--system/doc/oam/book.xml21
-rw-r--r--system/doc/oam/oam_intro.xml412
-rw-r--r--system/doc/oam/part.xml21
-rw-r--r--system/doc/oam/xmlfiles.mk21
-rw-r--r--system/doc/programming_examples/Makefile21
-rw-r--r--system/doc/programming_examples/bit_syntax.xml234
-rw-r--r--system/doc/programming_examples/book.xml21
-rw-r--r--system/doc/programming_examples/funs.xmlsrc311
-rw-r--r--system/doc/programming_examples/list_comprehensions.xml107
-rw-r--r--system/doc/programming_examples/part.xml26
-rw-r--r--system/doc/programming_examples/records.xml109
-rw-r--r--system/doc/programming_examples/xmlfiles.mk21
-rw-r--r--system/doc/reference_manual/Makefile21
-rw-r--r--system/doc/reference_manual/book.xml21
-rw-r--r--system/doc/reference_manual/character_set.xml37
-rw-r--r--system/doc/reference_manual/code_loading.xml138
-rw-r--r--system/doc/reference_manual/data_types.xml182
-rw-r--r--system/doc/reference_manual/distributed.xml141
-rw-r--r--system/doc/reference_manual/errors.xml88
-rw-r--r--system/doc/reference_manual/expressions.xml765
-rw-r--r--system/doc/reference_manual/functions.xml100
-rw-r--r--system/doc/reference_manual/introduction.xml74
-rw-r--r--system/doc/reference_manual/macros.xml96
-rw-r--r--system/doc/reference_manual/modules.xml199
-rw-r--r--system/doc/reference_manual/part.xml19
-rw-r--r--system/doc/reference_manual/patterns.xml23
-rw-r--r--system/doc/reference_manual/ports.xml135
-rw-r--r--system/doc/reference_manual/processes.xml111
-rw-r--r--system/doc/reference_manual/records.xml89
-rw-r--r--system/doc/reference_manual/typespec.xml271
-rw-r--r--system/doc/reference_manual/xmlfiles.mk21
-rw-r--r--system/doc/system_architecture_intro/Makefile21
-rw-r--r--system/doc/system_architecture_intro/book.xml21
-rw-r--r--system/doc/system_architecture_intro/part.xml21
-rw-r--r--system/doc/system_architecture_intro/sys_arch_intro.xml21
-rw-r--r--system/doc/system_architecture_intro/xmlfiles.mk21
-rw-r--r--system/doc/system_principles/Makefile21
-rw-r--r--system/doc/system_principles/book.xml21
-rw-r--r--system/doc/system_principles/create_target.xmlsrc386
-rw-r--r--system/doc/system_principles/error_logging.xml59
-rw-r--r--system/doc/system_principles/part.xml21
-rw-r--r--system/doc/system_principles/system_principles.xml209
-rw-r--r--system/doc/system_principles/upgrade.xml117
-rw-r--r--system/doc/system_principles/versions.xml311
-rw-r--r--system/doc/system_principles/xmlfiles.mk21
-rw-r--r--system/doc/top/Makefile19
-rw-r--r--system/doc/top/book.xml21
-rw-r--r--system/doc/top/src/erl_html_tools.erl19
-rw-r--r--system/doc/top/src/erlresolvelinks.erl19
-rw-r--r--system/doc/top/src/otp_man_index.erl19
-rw-r--r--system/doc/top/templates/applications.html.src21
-rw-r--r--system/doc/top/templates/index.html.src21
-rw-r--r--system/doc/tutorial/Makefile21
-rw-r--r--system/doc/tutorial/appendix.xmlsrc21
-rw-r--r--system/doc/tutorial/book.xml21
-rw-r--r--system/doc/tutorial/c_port.xmlsrc107
-rw-r--r--system/doc/tutorial/c_portdriver.xmlsrc133
-rw-r--r--system/doc/tutorial/cnode.xmlsrc183
-rw-r--r--system/doc/tutorial/distribution.xml22
-rw-r--r--system/doc/tutorial/ei.c2
-rw-r--r--system/doc/tutorial/erl_interface.xmlsrc129
-rw-r--r--system/doc/tutorial/example.xmlsrc44
-rw-r--r--system/doc/tutorial/introduction.xml47
-rw-r--r--system/doc/tutorial/nif.xmlsrc148
-rw-r--r--system/doc/tutorial/overview.xml256
-rw-r--r--system/doc/tutorial/part.xml19
-rw-r--r--system/doc/tutorial/xmlfiles.mk19
-rw-r--r--xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf19
-rw-r--r--xcomp/erl-xcomp-arm-android.conf19
-rw-r--r--xcomp/erl-xcomp-arm-linux.conf19
-rw-r--r--xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf19
-rw-r--r--xcomp/erl-xcomp-mips-linux.conf19
-rw-r--r--xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf19
-rw-r--r--xcomp/erl-xcomp-powerpc-ose5.conf19
-rw-r--r--xcomp/erl-xcomp-powerpc64-bgq-linux.conf19
-rw-r--r--xcomp/erl-xcomp-sfk-linux-ose5.conf19
-rw-r--r--xcomp/erl-xcomp-vars.sh21
-rw-r--r--xcomp/erl-xcomp-vxworks_ppc32.conf19
-rw-r--r--xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf19
-rw-r--r--xcomp/erl-xcomp.conf.template19
6852 files changed, 283463 insertions, 186521 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..48d8031bd0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,40 @@
+language: erlang
+
+otp_release:
+ - 18.0
+
+sudo: false
+
+addons:
+ apt:
+ packages:
+ - autoconf
+ - libncurses-dev
+ - build-essential
+ - libssl-dev
+ - libwxgtk2.8-dev
+ - libgl1-mesa-dev
+ - libglu1-mesa-dev
+ - libpng3
+ - default-jdk
+ - g++
+ - xsltproc
+
+before_script:
+ - set -e
+ - export ERL_TOP=$PWD
+ - export PATH=$ERL_TOP/bin:$PATH
+ - export ERL_LIBS=''
+ - export MAKEFLAGS=-j6
+ - kerl_deactivate
+
+script:
+ - ./otp_build all -a
+
+after_success:
+ - ./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/EPLICENCE b/EPLICENCE
deleted file mode 100644
index 36aa84e332..0000000000
--- a/EPLICENCE
+++ /dev/null
@@ -1,286 +0,0 @@
-ERLANG PUBLIC LICENSE
-Version 1.1
-
-1. Definitions.
-
-1.1. ``Contributor'' means each entity that creates or contributes to
-the creation of Modifications.
-
-1.2. ``Contributor Version'' means the combination of the Original
-Code, prior Modifications used by a Contributor, and the Modifications
-made by that particular Contributor.
-
-1.3. ``Covered Code'' means the Original Code or Modifications or the
-combination of the Original Code and Modifications, in each case
-including portions thereof.
-
-1.4. ``Electronic Distribution Mechanism'' means a mechanism generally
-accepted in the software development community for the electronic
-transfer of data.
-
-1.5. ``Executable'' means Covered Code in any form other than Source
-Code.
-
-1.6. ``Initial Developer'' means the individual or entity identified
-as the Initial Developer in the Source Code notice required by Exhibit
-A.
-
-1.7. ``Larger Work'' means a work which combines Covered Code or
-portions thereof with code not governed by the terms of this License.
-
-1.8. ``License'' means this document.
-
-1.9. ``Modifications'' means any addition to or deletion from the
-substance or structure of either the Original Code or any previous
-Modifications. When Covered Code is released as a series of files, a
-Modification is:
-
-A. Any addition to or deletion from the contents of a file containing
- Original Code or previous Modifications.
-
-B. Any new file that contains any part of the Original Code or
- previous Modifications.
-
-1.10. ``Original Code'' means Source Code of computer software code
-which is described in the Source Code notice required by Exhibit A as
-Original Code, and which, at the time of its release under this
-License is not already Covered Code governed by this License.
-
-1.11. ``Source Code'' means the preferred form of the Covered Code for
-making modifications to it, including all modules it contains, plus
-any associated interface definition files, scripts used to control
-compilation and installation of an Executable, or a list of source
-code differential comparisons against either the Original Code or
-another well known, available Covered Code of the Contributor's
-choice. The Source Code can be in a compressed or archival form,
-provided the appropriate decompression or de-archiving software is
-widely available for no charge.
-
-1.12. ``You'' means an individual or a legal entity exercising rights
-under, and complying with all of the terms of, this License. For legal
-entities,``You'' includes any entity which controls, is controlled by,
-or is under common control with You. For purposes of this definition,
-``control'' means (a) the power, direct or indirect, to cause the
-direction or management of such entity, whether by contract or
-otherwise, or (b) ownership of fifty percent (50%) or more of the
-outstanding shares or beneficial ownership of such entity.
-
-2. Source Code License.
-
-2.1. The Initial Developer Grant.
-The Initial Developer hereby grants You a world-wide, royalty-free,
-non-exclusive license, subject to third party intellectual property
-claims:
-
-(a) to use, reproduce, modify, display, perform, sublicense and
- distribute the Original Code (or portions thereof) with or without
- Modifications, or as part of a Larger Work; and
-
-(b) under patents now or hereafter owned or controlled by Initial
- Developer, to make, have made, use and sell (``Utilize'') the
- Original Code (or portions thereof), but solely to the extent that
- any such patent is reasonably necessary to enable You to Utilize
- the Original Code (or portions thereof) and not to any greater
- extent that may be necessary to Utilize further Modifications or
- combinations.
-
-2.2. Contributor Grant.
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license, subject to third party intellectual property
-claims:
-
-(a) to use, reproduce, modify, display, perform, sublicense and
- distribute the Modifications created by such Contributor (or
- portions thereof) either on an unmodified basis, with other
- Modifications, as Covered Code or as part of a Larger Work; and
-
-(b) under patents now or hereafter owned or controlled by Contributor,
- to Utilize the Contributor Version (or portions thereof), but
- solely to the extent that any such patent is reasonably necessary
- to enable You to Utilize the Contributor Version (or portions
- thereof), and not to any greater extent that may be necessary to
- Utilize further Modifications or combinations.
-
-3. Distribution Obligations.
-
-3.1. Application of License.
-The Modifications which You contribute are governed by the terms of
-this License, including without limitation Section 2.2. The Source
-Code version of Covered Code may be distributed only under the terms
-of this License, and You must include a copy of this License with
-every copy of the Source Code You distribute. You may not offer or
-impose any terms on any Source Code version that alters or restricts
-the applicable version of this License or the recipients' rights
-hereunder. However, You may include an additional document offering
-the additional rights described in Section 3.5.
-
-3.2. Availability of Source Code.
-Any Modification which You contribute must be made available in Source
-Code form under the terms of this License either on the same media as
-an Executable version or via an accepted Electronic Distribution
-Mechanism to anyone to whom you made an Executable version available;
-and if made available via Electronic Distribution Mechanism, must
-remain available for at least twelve (12) months after the date it
-initially became available, or at least six (6) months after a
-subsequent version of that particular Modification has been made
-available to such recipients. You are responsible for ensuring that
-the Source Code version remains available even if the Electronic
-Distribution Mechanism is maintained by a third party.
-
-3.3. Description of Modifications.
-You must cause all Covered Code to which you contribute to contain a
-file documenting the changes You made to create that Covered Code and
-the date of any change. You must include a prominent statement that
-the Modification is derived, directly or indirectly, from Original
-Code provided by the Initial Developer and including the name of the
-Initial Developer in (a) the Source Code, and (b) in any notice in an
-Executable version or related documentation in which You describe the
-origin or ownership of the Covered Code.
-
-3.4. Intellectual Property Matters
-
-(a) Third Party Claims.
- If You have knowledge that a party claims an intellectual property
- right in particular functionality or code (or its utilization
- under this License), you must include a text file with the source
- code distribution titled ``LEGAL'' which describes the claim and
- the party making the claim in sufficient detail that a recipient
- will know whom to contact. If you obtain such knowledge after You
- make Your Modification available as described in Section 3.2, You
- shall promptly modify the LEGAL file in all copies You make
- available thereafter and shall take other steps (such as notifying
- appropriate mailing lists or newsgroups) reasonably calculated to
- inform those who received the Covered Code that new knowledge has
- been obtained.
-
-(b) Contributor APIs.
- If Your Modification is an application programming interface and
- You own or control patents which are reasonably necessary to
- implement that API, you must also include this information in the
- LEGAL file.
-
-3.5. Required Notices.
-You must duplicate the notice in Exhibit A in each file of the Source
-Code, and this License in any documentation for the Source Code, where
-You describe recipients' rights relating to Covered Code. If You
-created one or more Modification(s), You may add your name as a
-Contributor to the notice described in Exhibit A. If it is not
-possible to put such notice in a particular Source Code file due to
-its structure, then you must include such notice in a location (such
-as a relevant directory file) where a user would be likely to look for
-such a notice. You may choose to offer, and to charge a fee for,
-warranty, support, indemnity or liability obligations to one or more
-recipients of Covered Code. However, You may do so only on Your own
-behalf, and not on behalf of the Initial Developer or any
-Contributor. You must make it absolutely clear than any such warranty,
-support, indemnity or liability obligation is offered by You alone,
-and You hereby agree to indemnify the Initial Developer and every
-Contributor for any liability incurred by the Initial Developer or
-such Contributor as a result of warranty, support, indemnity or
-liability terms You offer.
-
-3.6. Distribution of Executable Versions.
-You may distribute Covered Code in Executable form only if the
-requirements of Section 3.1-3.5 have been met for that Covered Code,
-and if You include a notice stating that the Source Code version of
-the Covered Code is available under the terms of this License,
-including a description of how and where You have fulfilled the
-obligations of Section 3.2. The notice must be conspicuously included
-in any notice in an Executable version, related documentation or
-collateral in which You describe recipients' rights relating to the
-Covered Code. You may distribute the Executable version of Covered
-Code under a license of Your choice, which may contain terms different
-from this License, provided that You are in compliance with the terms
-of this License and that the license for the Executable version does
-not attempt to limit or alter the recipient's rights in the Source
-Code version from the rights set forth in this License. If You
-distribute the Executable version under a different license You must
-make it absolutely clear that any terms which differ from this License
-are offered by You alone, not by the Initial Developer or any
-Contributor. You hereby agree to indemnify the Initial Developer and
-every Contributor for any liability incurred by the Initial Developer
-or such Contributor as a result of any such terms You offer.
-
-3.7. Larger Works.
-You may create a Larger Work by combining Covered Code with other code
-not governed by the terms of this License and distribute the Larger
-Work as a single product. In such a case, You must make sure the
-requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Code due to statute
-or regulation then You must: (a) comply with the terms of this License
-to the maximum extent possible; and (b) describe the limitations and
-the code they affect. Such description must be included in the LEGAL
-file described in Section 3.4 and must be included with all
-distributions of the Source Code. Except to the extent prohibited by
-statute or regulation, such description must be sufficiently detailed
-for a recipient of ordinary skill to be able to understand it.
-
-5. Application of this License.
-
-This License applies to code to which the Initial Developer has
-attached the notice in Exhibit A, and to related Covered Code.
-
-6. CONNECTION TO MOZILLA PUBLIC LICENSE
-
-This Erlang License is a derivative work of the Mozilla Public
-License, Version 1.0. It contains terms which differ from the Mozilla
-Public License, Version 1.0.
-
-7. DISCLAIMER OF WARRANTY.
-
-COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN ``AS IS'' BASIS,
-WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
-DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
-NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
-THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE
-IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER
-CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR
-CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART
-OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER
-EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-This License and the rights granted hereunder will terminate
-automatically if You fail to comply with terms herein and fail to cure
-such breach within 30 days of becoming aware of the breach. All
-sublicenses to the Covered Code which are properly granted shall
-survive any termination of this License. Provisions which, by their
-nature, must remain in effect beyond the termination of this License
-shall survive.
-
-9. DISCLAIMER OF LIABILITY
-Any utilization of Covered Code shall not cause the Initial Developer
-or any Contributor to be liable for any damages (neither direct nor
-indirect).
-
-10. MISCELLANEOUS
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision is held to be unenforceable, such
-provision shall be reformed only to the extent necessary to make it
-enforceable. This License shall be construed by and in accordance with
-the substantive laws of Sweden. Any dispute, controversy or claim
-arising out of or relating to this License, or the breach, termination
-or invalidity thereof, shall be subject to the exclusive jurisdiction
-of Swedish courts, with the Stockholm City Court as the first
-instance.
-
-EXHIBIT A.
-
-``The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved via the world wide web at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
-
-The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-AB. All Rights Reserved.''
diff --git a/HOWTO/INSTALL-CROSS.md b/HOWTO/INSTALL-CROSS.md
index 7f852860c9..224f238fd0 100644
--- a/HOWTO/INSTALL-CROSS.md
+++ b/HOWTO/INSTALL-CROSS.md
@@ -550,16 +550,17 @@ Copyright and License
Copyright Ericsson AB 2009-2014. All Rights Reserved.
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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%
diff --git a/HOWTO/INSTALL-WIN32.md b/HOWTO/INSTALL-WIN32.md
index 0387572dd3..067c939d7a 100644
--- a/HOWTO/INSTALL-WIN32.md
+++ b/HOWTO/INSTALL-WIN32.md
@@ -4,82 +4,110 @@ How to Build Erlang/OTP on Windows
Introduction
------------
-This file describes how to build the Erlang emulator and the OTP
-libraries on Windows. The instructions apply to versions of Windows
-supporting the Cygwin emulated gnuish environment for Windows or the
-Msys ditto. We've built on the following platforms: Windows 2003
-server, Windows XP Home/Professional, Windows Vista and Windows 7 (32
-and 64 bit). You can probably build on Windows 2000, but you will not
-be able to install the latest Microsoft SDK, so you have to go back to
-some earlier compiler. Any Windows95'ish platform will surely get you
-into trouble, what I'm not sure of, but it certainly will...
-
-The procedure described uses either Cygwin or Msys as a build
-environment, you run the bash shell in Cygwin/Msys and use gnu
-make/configure/autoconf etc to do the build. The emulator C-source
-code is, however, mostly compiled with Microsoft Visual C++™,
-producing a native Windows binary. This is the same procedure as we
-use to build the pre-built binaries. The fact that we use VC++ and not
-gcc is explained further in the FAQ section.
-
-I describe the build procedure to make it possible for open source
-customers to build the emulator, given that they have the needed
-tools. The binary Windows releases is still a preferred alternative if
-one does not have Microsoft's development tools and/or don't want to
-install Cygwin or Msys.
-
-To use Cygwin/Msys, one needs basic experience from a Unix environment, if
-one does not know how to set environment variables, run programs etc
-in a Unix environment, one will be quite lost in the Cygwin os Msys
-ditto. I can unfortunately not teach all the world how to use
-Cygwin and bash, neither how to install Cygwin nor perform basic tasks
-on a computer. Please refer to other documentation on the net for
-help, or use the binary release instead if you have problems using the
-tools.
-
-However, if you feel comfortable with the environment and build
+This section describes how to build the Erlang emulator and the OTP
+libraries on Windows. Note that the Windows binary releases are still
+a preferred alternative if one does not have Microsoft’s development
+tools and/or don’t want to install Cygwin, MSYS or MSYS2.
+
+The instructions apply to versions of Windows supporting the Cygwin
+emulated gnuish environment or the MSYS or MSYS2 ditto. We’ve built on
+the following platforms: Windows 2012, Windows 7, Windows 8 and Windows 10.
+It’s probably possible to build on older platforms too, but you might
+not be able to install the appropriate Microsoft SDK, Visual Studio or
+OpenSSL, in which case you will need to go back to earlier compilers etc.
+
+The procedure described uses either Cygwin, MSYS or MSYS2 as a build
+environment. You run the bash shell in Cygwin/MSYS/MSYS2 and use the gnu
+make/configure/autoconf etc to do the build. The emulator C-source code
+is, however, mostly compiled with Microsoft Visual C++™, producing a
+native Windows binary. This is the same procedure as we use to build the
+pre-built binaries. Why we use VC++ and not gcc is explained further in
+the FAQ section.
+
+If you are not familiar with Cygwin, MSYS, MSYS2 or a Unix environment,
+you’ll probably need to read up a bit on how that works. There are plenty of
+documentation about this online.
+
+These instructions apply for both 32-bit and 64-bit Windows. Note that even
+if you build a 64-bit version of Erlang, most of the directories and files
+involved are still named win32. Some occurances of the name win64 are
+however present. The installation file for a 64-bit Windows version of
+Erlang, for example, is `otp_win64_%OTP-REL%.exe`.
+
+If you feel comfortable with the environment and build
system, and have all the necessary tools, you have a great opportunity
to make the Erlang/OTP distribution for Windows better. Please submit
-any suggestions and patches to the appropriate [mailing lists] [1] to let
+any suggestions to our [JIRA] [2] and patches to our [git project] [3] to let
them find their way into the next version of Erlang. If making changes
to the build system (like makefiles etc) please bear in mind that the
same makefiles are used on Unix/VxWorks, so that your changes
-don't break other platforms. That of course goes for C-code too, system
+don't break other platforms. That of course goes for C-code too; system
specific code resides in the `$ERL_TOP/erts/emulator/sys/win32` and
`$ERL_TOP/erts/etc/win32` directories mostly. The
`$ERL_TOP/erts/emulator/beam` directory is for common code.
-Before the R9C release of Erlang/OTP, the Windows release was built
-partly on a Unix (Solaris) box and partly on a Windows box, using Perl
-hacks to communicate and sync between the two machines. R9C was the
-first release ever built solely on Windows, where no Unix machine is
-needed at all. Now we've used this build procedure for a couple of
+We've used this build procedure for a couple of
releases, and it has worked fine for us. Still, there might be all
sorts of troubles on different machines and with different
-setups. I'll try to give hints wherever I've encountered difficulties,
+setups. We'll try to give hints wherever we've encountered difficulties,
but please share your experiences by using the [erlang-questions] [1]
-mailing list. I cannot of course help everyone with all
-their problems, please try to solve the problems and submit
-solutions/workarounds. Remember, it's all about sharing, not about
-demanding...
-
-Starting with R15B, our build system runs both on Cygwin and Msys
-(MinGW's fork of an early cygwin version). Msys is a smaller package
-to install and may on some machines run slightly faster. If Cygwin
-gives you trouble, try Msys instead, and v.v. Beginning with R15B
-there is also a native 64bit version of Erlang for 64bit Windows 7
-(only). These instructions apply to both the 32bit VM and the 64bit
-ditto.
-
-Note that even if you build a 64bit VM, most of the directories and
-files involved are still named win32. You can view the name win32 as
-meaning any windows version not beeing 16bit. A few occurences of the
-name Win64 are however present in the system, for example the
-installation file for a 64 bit windows version of Erlang is by default
-named `otp_win64_<version>.exe`.
-
-Lets go then, I'll start with a little FAQ, based on in house questions
-and misunderstandings.
+mailing list. We cannot, of course, help everyone with all
+their issues, so please try to solve such issues and submit
+solutions/workarounds.
+
+Lets go then! We’ll start with a short version of the setup procedure,
+followed by some FAQ, and then we’ll go into more details of the setup.
+
+
+Short Version
+--------------------------
+In the following sections, we've described as much as we could about the
+installation of the tools needed. Once the tools are installed, building
+is quite easy. We have also tried to make these instructions understandable
+for people with limited Unix experience. Cygwin/MSYS/MSYS2 is a whole new
+environment to some Windows users, why careful explanation of environment
+variables etc seemed to be in place.
+
+This is the short story though, for the experienced and impatient:
+
+ * Get and install complete Cygwin (latest), complete MinGW with MSYS or
+ complete MSYS2
+
+ * Install Visual Studio 12.0 (2013)
+
+ * Install Microsofts Windows SDK 8.1
+
+ * Get and install Sun's JDK 1.6.0 or later
+
+ * Get and install NSIS 2.01 or later (up to 2.46 tried and working)
+
+ * Get, build and install OpenSSL 0.9.8r or later (up to 1.0.2d
+ tried & working) with static libs.
+
+ * Get the Erlang source distribution (from
+ <http://www.erlang.org/download.html>) and unpack with
+ Cygwin's/MSYS's/MSYS2's `tar`.
+
+ * Set `ERL_TOP` to where you unpacked the source distribution
+
+ * `$ cd $ERL_TOP`
+
+ * Modify PATH and other environment variables so that all these tools
+ are runnable from a bash shell. Still standing in `$ERL_TOP`, issue
+ the following commands (for 32-bit Windows, remove the x64 from the
+ first row and change `otp_win64_%OTP-REL%` to `otp_win32_%OTP-REL%` on
+ the last row):
+
+ $ eval `./otp_build env_win32 x64`
+ $ ./otp_build autoconf
+ $ ./otp_build configure
+ $ ./otp_build boot -a
+ $ ./otp_build release -a
+ $ ./otp_build installer_win32
+ $ release/win32/otp_win64_%OTP-REL% /S
+
+ Voila! `Start->Programs->Erlang OTP %OTP-REL%->Erlang` starts the Erlang
+ Windows shell.
Frequently Asked Questions
@@ -88,12 +116,12 @@ Frequently Asked Questions
* Q: So, now I can build Erlang using GCC on Windows?
A: No, unfortunately not. You'll need Microsoft's Visual C++
- still, a Bourne-shell script (cc.sh) wraps the Visual C++ compiler
+ still. A Bourne-shell script (cc.sh) wraps the Visual C++ compiler
and runs it from within the Cygwin environment. All other tools
needed to build Erlang are free-ware/open source, but not the C
compiler. The Windows SDK is however enough to build Erlang, you
do not need to buy Visual C++, just download the SDK (SDK version
- 7.1 == Visual studio 2010).
+ 8.1 == Visual studio 2013).
* Q: Why haven't you got rid of VC++ then, you \*\*\*\*\*\*?
@@ -106,18 +134,17 @@ Frequently Asked Questions
mingw build will possibly be back, but as long as VC++ gives better
performance, the commercial build will be a VC++ one.
-* Q: OK, you need VC++, but now you've started to demand a very recent
- (and expensive) version of Visual studio, not the old and stable VC++
- 6.0 that was used in earlier versions. Why?
+* Q: OK, you need VC++, but now you've started to demand a quite recent
+ (and expensive) version of Visual Studio. Why?
A: Well, it's not expensive, it's free (as in free beer). Just
download and install the latest Windows SDK from Microsoft and all
the tools you need are there. The included debugger (WinDbg) is
- also quite usable, it's what I used when porting Erlang to 64bit
- Windows. Another reason to use the latest Microsoft compilers is
+ also quite usable. That's what I used when porting Erlang to 64bit
+ Windows. Another reason to use later Microsoft compilers is
DLL compatibility. DLL's using a new version of the standard
library might not load if the VM is compiled with an old VC++
- version, why we should aim to use the latest freely available SDK
+ version. So we should aim to use the latest freely available SDK
and compiler.
* Q: Can/will I build a Cygwin binary with the procedure you describe?
@@ -130,9 +157,7 @@ Frequently Asked Questions
some problems. Fixing those problems might be easy or might be hard.
I suggest you try yourself and share your experience. No one would be
happier if a simple `./configure && make` would produce a fully fledged
- Cygwin binary. Ericsson does however not pay me to do a Cygwin port, so
- such a port would have to happen in spare time, which is a limited
- resource...
+ Cygwin binary.
* Q: Hah, I saw you, you used GCC even though you said you didn't!
@@ -142,7 +167,7 @@ Frequently Asked Questions
particular file, `beam_emu.c` benefits immensely from being able
to use the GCC labels-as-values extension, which boosts emulator
performance by up to 50%. That does unfortunately not (yet) mean
- that all of OTP could be compiled using GCC, that particular
+ that all of OTP could be compiled using GCC. That particular
source code does not do anything system specific and actually is
adopted to the fact that GCC is used to compile it on Windows.
@@ -152,229 +177,184 @@ Frequently Asked Questions
A: No, never. The hassle of keeping the project files up to date and
do all the steps that constitute an OTP build from within the VC++ GUI
is simply not worth it, maybe even impossible. A VC++ project
- file for Erlang/OTP will never happen, at least I will never make
- one. Clicking around in super-multi-tab'd dialogs to add a file or
- compiler option when it's so much easier in a makefile is simply not
- my style.
+ file for Erlang/OTP will never happen.
* Q: So how does it all work then?
- A: Cygwin or Msys is the environment, which closely resembles the
- environments found on any Unix machine. It's almost like you had a
+ A: Cygwin, MSYS or MSYS2 is the environment, which closely resembles the
+ environment found on any Unix machine. It's almost like you had a
virtual Unix machine inside Windows. Configure, given certain
parameters, then creates makefiles that are used by the
- Cygwin/Msys gnu-make to built the system. Most of the actual
- compilers etc are not, however, Cygwin/Msys tools, so I've written
+ environment's gnu-make to built the system. Most of the actual
+ compilers etc are not, however, Cygwin/MSYS/MSYS2 tools, so we've written
a couple of wrappers (Bourne-shell scripts), which reside in
`$ERL_TOP/etc/win32/cygwin_tools` and
`$ERL_TOP/etc/win32/msys_tools`. They all do conversion of
parameters and switches common in the Unix environment to fit the
native Windows tools. Most notable is of course the paths, which
- in Cygwin/Msys are Unix-like paths with "forward slashes" (/) and
- no drive letters, the Cygwin specific command `cygpath` is used
- for most of the path conversions in a Cygwin environment, other
- tools are used (when needed) in the corresponding Msys
+ in Cygwin/MSYS/MSYS2 are Unix-like paths with "forward slashes" (/) and
+ no drive letters. The Cygwin specific command `cygpath` is used
+ for most of the path conversions in a Cygwin environment. Other
+ tools are used (when needed) in the corresponding MSYS and MSYS2
environment. Luckily most compilers accept forward slashes instead
of backslashes as path separators, but one still have to get the drive
letters etc right, though. The wrapper scripts are not general in
- the sense that, for example, cc.sh would understand and translates
- every possible gcc option and passes correct options to
+ the sense that, for example, cc.sh would understand and translate
+ every possible gcc option and pass correct options to
cl.exe. The principle is that the scripts are powerful enough to
allow building of Erlang/OTP, no more, no less. They might need
- extensions to cope with changes during the development of Erlang,
- that's one of the reasons I made them into shell-scripts and not
- Perl-scripts, I believe they are easier to understand and change
- that way. I might be wrong though, cause another reason I didn't
- write them in Perl is because I've never liked Perl and my Perl
- code is no pleasant reading...
+ extensions to cope with changes during the development of Erlang, and
+ that's one of the reasons we made them into shell-scripts and not
+ Perl-scripts. We believe they are easier to understand and change
+ that way.
In `$ERL_TOP`, there is a script called `otp_build`. That script handles
the hassle of giving all the right parameters to `configure`/`make` and
also helps you set up the correct environment variables to work with
- the Erlang source under Cygwin.
+ the Erlang source under Cygwin/MSYS/MSYS2.
* Q: You use and need Cygwin, but then you haven't taken the time to
port Erlang to the Cygwin environment but instead focus on your
commercial release, is that really ethical?
- A: No, not really, but see this as a step in the right direction. I'm
- aiming at GCC compiled emulators and a Cygwin version, but I really
- need to do other things as well... In time, but don't hold your
- breath...
+ A: No, not really, but see this as a step in the right direction.
* Q: Can I build something that looks exactly as the commercial release?
- A: Yes, we use the exactly same build procedure.
+ A: Yes, we use the exact same build procedure.
-* Q: Which version of Cygwin/Msys and other tools do you use then?
+* Q: Which version of Cygwin/MSYS/MSYS2 and other tools do you use then?
- A: For Cygwin and Msys alike, we try to use the latest releases
+ A: For Cygwin, MSYS and MSYS2 alike, we try to use the latest releases
available when building. What versions you use shouldn't really
- matter, I try to include workarounds for the bugs I've found in
- different Cygwin/Msys releases, please help me add workarounds
- for new Cygwin/Msys-related bugs as soon as you encounter
- them. Also please do submit bug reports to the appropriate Cygwin
- and/or Msys developers. The GCC we used for %OTP-REL% was version
- 4.7.0 (MinGW 64bit) and 4.3.4 (Cygwin 32bit). We used VC++ 10.0
- (i.e. Visual studio 2010), Sun's JDK 1.5.0\_17 (32bit) and Sun's
- JDK 1.7.0\_1 (64bit), NSIS 2.46, and Win32 OpenSSL 0.9.8r. Please
+ matter. We try to include workarounds for the bugs we've found in
+ different Cygwin/MSYS/MSYS2 releases. Please help us add workarounds
+ for new Cygwin/MSYS/MSYS2-related bugs as soon as you encounter
+ them. Also please do submit bug reports to the appropriate Cygwin, MSYS
+ and/or MSYS2 developers. The GCC we used for %OTP-REL% was version
+ 4.8.1 (MinGW 32bit) and 4.8.5 (MSYS2 64bit). We used VC++ 12.0
+ (i.e. Visual studio 2013), Sun's JDK 1.6.0\_45 (32bit) and Sun's
+ JDK 1.7.0\_1 (64bit), NSIS 2.46, and Win32 OpenSSL 1.0.2d. Please
read the next section for details on what you need.
-* Q: Can you help me setup X in Cygwin?
+* Q: Can you help me setup X in Cygwin/MSYS/MSYS2?
- A: No, unfortunately I haven't got time to help with Cygwin related
- user problems, please read Cygwin related web sites, newsgroups and
+ A: No, unfortunately we haven't got time to help with Cygwin/MSYS/MSYS2
+ related user problems, please read related websites, newsgroups and
mailing lists.
-* Q: Why is the instruction so long? Is it really that complicated?
-
- A: Partly it's long because I babble too much, partly because I've
- described as much as I could about the installation of the needed
- tools. Once the tools are installed, building is quite easy. I also
- have tried to make this instruction understandable for people with
- limited Unix experience. Cygwin/Msys is a whole new environment to some
- Windows users, why careful explanation of environment variables etc
- seemed to be in place. The short story, for the experienced and
- impatient is:
-
- * Get and install complete Cygwin (latest) or complete MinGW with msys
-
- * Install Microsofts Windows SDK 7.1 (and .Net 4)
-
- * Get and install Sun's JDK 1.5.0 or higher
-
- * Get and install NSIS 2.01 or higher (up to 2.46 tried and working)
-
- * Get, build and install OpenSSL 0.9.8r or higher (up to 1.0.0a
- tried & working) with static libs.
-
- * Get the Erlang source distribution (from
- <http://www.erlang.org/download.html>) and unpack with Cygwin's `tar`.
-
- * Set `ERL_TOP` to where you unpacked the source distribution
-
- * `$ cd $ERL_TOP`
-
- * Get (from <http://www.erlang.org/download/tcltk85_win32_bin.tar.gz>)
- and unpack the prebuilt TCL/TK binaries for windows with cygwin tar,
- standing in `$ERL_TOP`
-
- * Modify PATH and other environment variables so that all these tools
- are runnable from a bash shell. Still standing in `$ERL_TOP`, issue
- the following commands:
-
- $ eval `./otp_build env_win32`
- $ ./otp_build autoconf
- $ ./otp_build configure
- $ ./otp_build boot -a
- $ ./otp_build release -a
- $ ./otp_build installer_win32
- $ release/win32/otp_win32_%OTP-REL% /S
-
- Voila! `Start->Programs->Erlang OTP %OTP-REL%->Erlang` starts the Erlang
- Windows shell.
-
Tools you Need and Their Environment
------------------------------------
You need some tools to be able to build Erlang/OTP on Windows. Most
-notably you'll need Cygwin or Msys and Microsofts Windows SDK, but
-you also might want a Java compiler, the NSIS install system and
-OpenSSL. Well' here's the list:
+notably you'll need Cygwin, MSYS or MSYS2, Visual Studio and Microsofts
+Windows SDK, but you might also want a Java compiler, the NSIS install
+system and OpenSSL. Well, here's some information about the different
+tools:
* Cygwin, the very latest is usually best. Get all the development
- tools and of course all the basic ditto. In fact getting the complete
- package might be a good idea, as you'll start to love Cygwin after a
- while if you're accustomed to Unix. Make sure to get jar and also make
- sure *not* to install a Cygwin'ish Java... The Cygwin jar command is
- used but Sun's Java compiler and virtual machine...
+ tools and of course all the basic ditto. Make sure to get jar and
+ also make sure *not* to install a Cygwin'ish Java, since the Cygwin
+ jar command is used but Sun's Java compiler and virtual machine.
If you are going to build a 64bit Windows version, you should make
- sure to get MinGW's 64bit gcc installed with cygwin. It's in one of
+ sure to get MinGW's 64bit gcc installed with Cygwin. It's in one of
the development packages.
URL: <http://www.cygwin.com>
- Get the installer from the web site and use that to install
- Cygwin. Be sure to have fair privileges. If you're on a NT domain you
+ Get the installer from the website and use it to install
+ Cygwin. Be sure to have fair privileges. If you're on an NT domain you
should consider running `mkpasswd -d` and `mkgroup -d` after the
installation to get the user databases correct. See their respective
manual pages.
- When you start you first bash shell, you will get an awful prompt. You
+ When you start your first bash shell, you will get an awful prompt. You
might also have a `PATH` environment variable that contains backslashes
and such. Edit `$HOME/.profile` and `$HOME/.bashrc` to set fair prompts
- and set a correct PATH. Also do a `export SHELL` in `.profile`. For some
+ and a correct PATH. Also do an `export SHELL` in `.profile`. For some
non-obvious reason the environment variable `$SHELL` is not exported in
bash. Also note that `.profile` is run at login time and `.bashrc` when
sub shells are created. You'll need to explicitly source `.bashrc` from
`.profile` if you want the commands there to be run at login time (like
- setting up aliases, shell functions and the like). I personally
- usually do like this at the end of `.profile`:
+ setting up aliases, shell functions and the like). You can for example
+ do like this at the end of `.profile`:
ENV=$HOME/.bashrc
export ENV
. $ENV
- You might also, if you're a hard core type of person at least, want to
- setup X-windows (XFree86), that might be as easy as running startx
- from the command prompt and it might be much harder. Use Google to
- find help...
+ You might also want to setup X-windows (XFree86). That might be as easy
+ as running startx from the command prompt and it might be much harder.
+ Use Google to find help.
If you don't use X-windows, you might want to setup the Windows
console window by selecting properties in the console system menu
(upper left corner of the window, the Cygwin icon in the title
bar). Especially setting a larger screen buffer size (lines) is useful
as it gets you a scrollbar so you can see whatever error messages
- that might appear...
+ that might appear.
- If you want to use (t)csh instead of bash you're on your own, I
- haven't tried and know of no one that has. I expect
- that you use bash in all shell examples.
+ There are a few other shells available, but in all examples below we assume
+ that you use bash.
-* Alternatively you download MinGW and Msys. You'll find the latest
+* Alternatively you download MinGW and MSYS. You'll find the latest
installer at:
URL: <http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/>
- Make sure to install everything they've got.
+ Make sure to install the basic dev tools, but avoid the MinGW autoconf and
+ install the msys one instead.
To be able to build the 64bit VM, you will also need the 64bit
MinGW compiler from:
- URL: <http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds/>
+ URL: <http://sourceforge.net/projects/mingw-w64/files/latest/download?source=files>
- The latest version should do it. Make sure you download the
- `mingw-w64-bin_i686-mingw_<something>.zip`, not a linux
+ We've tried up to 1.0, but the latest version should do. Make sure you
+ download the `mingw-w64-bin_i686-mingw_<something>.zip`, not a linux
version. You unzip the package on top of your MinGW installation
(`c:\MinGW`) and that's it.
- Setting up your environment in Msys is similar to setting it up in
- Cygwin.
+* A third alternative is to download and install MSYS2 from:
-* Microsofts Windows SDK version 7.1 (corresponding to VC++ 10.0 and
- Visual Studio 2010). You'll find it here:
-
- URL: <http://www.microsoft.com/download/en/details.aspx?id=8279>
+ URL: <https://msys2.github.io/>
+
+ When you've followed the instructions there, you also need to install
+ these packages: autoconf, make, perl, and tar. You do so by running
+ the following in the msys console:
- but before you install that, you need to have .Net 4 installed,
- you'll find that here:
+ pacman -S msys/autoconf msys/make msys/perl msys/tar
- URL: <http://www.microsoft.com/download/en/details.aspx?id=17851>
+ You also need a gcc. If you installed the 64 bit MSYS2 you run:
- Use the web installer for the SDK, at least when I tried
- downloading the whole package as an image, I got SDK 7.0 instead,
- which is not what you want...
+ mingw64/mingw-w64-x86_64-gcc
- There will be a Windows command file in `%PROGRAMFILES%\Mirosoft
- SDKs\Windows\v7.1\Bin\SetEnv.cmd` that set's the appropriate
+ And for 32 bit MSYS2:
+
+ pacman -S mingw32/mingw-w64-i686-gcc
+ pacman -S mingw-w64-i686-editrights
+
+* Visual Studio 2013 (Visual Studio 12.0). Download and run the web
+ installer from:
+
+ https://www.visualstudio.com/
+
+* Microsofts Windows SDK version 8.1 (corresponding to VC++ 12.0 and
+ Visual Studio 2013). You'll find it here:
+
+ URL: <https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx>
+
+* To help setup the environment, there is a bat file,
+ `%PROGRAMFILES%\Mirosoft Visual Studio 12.0\VC\vcvarsall.bat`,
+ that set's the appropriate
environment for a Windows command prompt. This is not appropriate
for bash, so you'll need to convert it to bash-style environments
by editing your `.bash_profile`. In my case, where the SDK is
installed in the default directory and `%PROGRAMFILES%` is
`C:\Program Files`, the commands for setting up a 32bit build
- environment (on a 64bit or 32bit machine) look like this (in cygwin):
+ environment (on a 64bit or 32bit machine) look like this (in Cygwin):
# Some common paths
C_DRV=/cygdrive/c
@@ -383,314 +363,290 @@ OpenSSL. Well' here's the list:
# nsis
NSIS_BIN=$PRG_FLS/NSIS
# java
- JAVA_BIN=$PRG_FLS/Java/jdk1.6.0_16/bin
+ JAVA_BIN=$PROGRAMFILES/Java/jdk1.7.0_02/bin
##
## MS SDK
##
- CYGWIN=nowinsymlinks
- MVS10="$PRG_FILES/Microsoft Visual Studio 10.0"
- WIN_MVS10="C:\\Program Files\\Microsoft Visual Studio 10.0"
- SDK10="$PRG_FILES/Microsoft SDKs/Windows/v7.1"
- WIN_SDK10="C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1"
+ CYGWIN=nowinsymlinks
+
+ VISUAL_STUDIO_ROOT=$PRG_FLS/Microsoft\ Visual\ Studio\ 12.0
+ WIN_VISUAL_STUDIO_ROOT="C:\\Program Files\\Microsoft Visual Studio 12.0"
+ SDK=$PRG_FLS/Windows\ Kits/8.1
+ WIN_SDK="C:\\Program Files\\Windows Kits\\8.1"
PATH="$NSIS_BIN:\
- $MVS10/Common7/IDE:\
- $MVS10/Common7/Tools:\
- $MVS10/VC/Bin:\
- $MVS10/VC/Bin/VCPackages:\
- $SDK10/Bin/NETFX 4.0 Tools:\
- $SDK10/Bin:\
+ $VISUAL_STUDIO_ROOT/VC/bin:\
+ $VISUAL_STUDIO_ROOT/VC/vcpackages:\
+ $VISUAL_STUDIO_ROOT/Common7/IDE:\
+ $VISUAL_STUDIO_ROOT/Common7/Tools:\
+ $SDK/bin/x86
/usr/local/bin:/usr/bin:/bin:\
/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:\
/cygdrive/c/WINDOWS/system32/Wbem:\
$JAVA_BIN"
- LIBPATH="$WIN_MVS10\\VC\\LIB"
+ LIBPATH="$WIN_VISUAL_STUDIO_ROOT\\VC\\lib"
- LIB="$WIN_MVS10\\VC\\LIB;$WIN_SDK10\\LIB"
+ LIB="$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\;$WIN_SDK\\lib\\winv6.3\\um\\x86"
- INCLUDE="$WIN_MVS10\\VC\\INCLUDE;$WIN_SDK10\\INCLUDE;$WIN_SDK10\\INCLUDE\\gl"
+ INCLUDE="$WIN_VISUAL_STUDIO_ROOT\\VC\\include\\;$WIN_SDK\\include\\shared\\;
+ $WIN_SDK\\include\\um;$WIN_SDK\\include\\winrt\\;$WIN_SDK\\include\\um\\gl"
- export CYGWIN PATH LIBPATH LIB INCLUDE
+ export CYGWIN PATH LIBPATH LIB INCLUDE
- If you're using Msys instead, the only thing you need to change is
- the `C_DRV` setting, which would read:
+ If you're using MinGW's MSYS instead, you need to change the `C_DRV` setting,
+ which would read:
C_DRV=/c
- And of course you might need to change `C:\Program Files` etc if
- you're using a non-english version of Windows (XP). Note that in
- later versions of Windows, the national adoptions of the program
- files directories etc are not on the file system but only in the
- explorer, so even if explorer says that your programs reside in
- e.g. `C:\Program`, they might still reside in `C:\Program Files`
- in reality...
-
- If you are building a 64 bit version of Erlang, you should set up
- PATHs etc a little differently. I use the following script to
- make things work in both Cygwin and Msys:
-
- make_winpath()
- {
- P=$1
- if [ "$IN_CYGWIN" = "true" ]; then
- cygpath -d "$P"
- else
- (cd "$P" && /bin/cmd //C "for %i in (".") do @echo %~fsi")
- fi
- }
-
- make_upath()
- {
- P=$1
- if [ "$IN_CYGWIN" = "true" ]; then
- cygpath "$P"
- else
- echo "$P" | /bin/sed 's,^\([a-zA-Z]\):\\,/\L\1/,;s,\\,/,g'
- fi
- }
-
- # Some common paths
- if [ -x /usr/bin/msysinfo ]; then
- # Without this the path conversion won't work
- COMSPEC='C:\Windows\SysWOW64\cmd.exe'
- MSYSTEM=MINGW32
- export MSYSTEM COMSPEC
- IN_CYGWIN=false
- else
- CYGWIN=nowinsymlinks
- export CYGWIN
- IN_CYGWIN=true
- fi
-
- if [ "$IN_CYGWIN" = "true" ]; then
- PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:\
- /cygdrive/c/windows/system32:/cygdrive/c/windows:/cygdrive/c/windows/system32/Wbem
- else
- PATH=/usr/local/bin:/mingw/bin:/bin:/c/Windows/system32:/c/Windows:\
- /c/Windows/System32/Wbem
- fi
-
- if [ "$IN_CYGWIN" = "true" ]; then
- C_DRV=/cygdrive/c
- else
- C_DRV=/c
- fi
-
- PRG_FLS64=$C_DRV/Program\ Files
- PRG_FLS32=$C_DRV/Program\ Files\ \(x86\)
- VISUAL_STUDIO_ROOT32=$PRG_FLS32/Microsoft\ Visual\ Studio\ 10.0
- MS_SDK_ROOT64=$PRG_FLS64/Microsoft\ SDKs/Windows/v7.1
-
- # Okay, now mangle the paths and get rid of spaces by using short names
- WIN_VCROOT32=`make_winpath "$VISUAL_STUDIO_ROOT32"`
- VCROOT32=`make_upath $WIN_VCROOT32`
- WIN_SDKROOT64=`make_winpath "$MS_SDK_ROOT64"`
- SDKROOT64=`make_upath $WIN_SDKROOT64`
- WIN_PROGRAMFILES32=`make_winpath "$PRG_FLS32"`
- PROGRAMFILES32=`make_upath $WIN_PROGRAMFILES32`
-
- WIN_PROGRAMFILES64=`make_winpath "$PRG_FLS64"`
- PROGRAMFILES64=`make_upath $WIN_PROGRAMFILES64`
-
- # nsis
- NSIS_BIN=$PROGRAMFILES32/NSIS
- # java
- JAVA_BIN=$PROGRAMFILES64/Java/jdk1.7.0_01/bin
-
- ## The PATH variable should be Unix'ish
- VCPATH=$VCROOT32/Common7/IDE:$VCROOT32/VC/BIN/amd64:$VCROOT32/Common7/Tools:\
- $VCROOT32/VC/VCPackages:$SDKROOT64/bin/NETFX4~1.0TO/x64:$SDKROOT64/bin/x64:\
- $SDKROOT64/bin
-
- ## Microsoft SDK libs
-
- LIBPATH=$WIN_VCROOT32\\VC\\LIB\\amd64
- LIB=$WIN_VCROOT32\\VC\\LIB\\amd64\;$WIN_SDKROOT64\\LIB\\X64
- INCLUDE=$WIN_VCROOT32\\VC\\INCLUDE\;$WIN_SDKROOT64\\include\;\
- $WIN_SDKROOT64\\include\\gl
-
- # Put nsis, c compiler and java in path
- PATH=$NSIS_BIN:$VCPATH:$PATH:$JAVA_BIN
-
- # Make sure LIB and INCLUDE is available for others
- export PATH LIBPATH LIB INCLUDE
-
- All this is derived from the SetEnv.cmd command file mentioned
- earlier. The bottom line is to set the PATH so that NSIS and
- Microsoft SDK is found before the Msys/Cygwin tools and that Java
- is last in the PATH.
-
- Make a simple hello world (maybe one that prints out
- `sizeof(void *)`) and try to compile it with the `cl` command from within
- bash. If that does not work, your environment needs fixing. Also
- remember to fix up the PATH environment, especially old Erlang
- installations might have inserted quoted paths that Cygwin/Msys
- does not understand. Remove or correct such paths. There should be
- no backslashes in your path environment variable in Cygwin bash,
- but LIB and INCLUDE should contain Windows style paths with
- semicolon, drive letters and backslashes.
+ and you also need to change the PATH environment variable to:
-* Sun's Java JDK 1.5.0 or higher. Our Java code (jinterface, ic) is
- written for JDK 1.5.0. Get it for Windows and install it, the JRE is
- not enough. If you don't care about Java, you can skip this step, the
- result will be that jinterface is not built.
+ MINGW_BIN=/c/MinGW/bin
- URL: <http://java.sun.com>
- Add javac *LAST* to your path environment in bash, in my case this means:
+ PATH="$NSIS_BIN:\
+ $VISUAL_STUDIO_ROOT/VC/bin:\
+ $VISUAL_STUDIO_ROOT/VC/vcpackages:\
+ $VISUAL_STUDIO_ROOT/Common7/IDE:\
+ $VISUAL_STUDIO_ROOT/Common7/Tools:\
+ $SDK/bin/x86:/usr/local/bin:\
+ $MINGW_BIN:\
+ /bin:/c/Windows/system32:/c/Windows:\
+ /c/Windows/System32/Wbem:\
+ $JAVA_BIN"
- `PATH="$PATH:/cygdrive/c/Program Files/Java/jdk1.5.0_17/bin"`
+ For MSYS2 you use the same `C_DRV` and PATH as for MSYS, only update the `MINGW_BIN`:
+
+ MINGW_BIN=/mingw32/bin
+
+
+ If you are building a 64 bit version of Erlang, you should set up
+ PATHs etc a little differently. We have two templates to make things
+ work in both Cygwin and MSYS but needs editing to work with MSYS2 (see the
+ comments in the script).
+ The following one is for 32 bits:
+
+ make_winpath()
+ {
+ P=$1
+ if [ "$IN_CYGWIN" = "true" ]; then
+ cygpath -d "$P"
+ else
+ (cd "$P" && /bin/cmd //C "for %i in (".") do @echo %~fsi")
+ fi
+ }
+
+ make_upath()
+ {
+ P=$1
+ if [ "$IN_CYGWIN" = "true" ]; then
+ cygpath "$P"
+ else
+ echo "$P" | /bin/sed 's,^\([a-zA-Z]\):\\,/\L\1/,;s,\\,/,g'
+ fi
+ }
- No `CLASSPATH` or anything is needed. Type `javac` at the bash prompt
- and you should get a list of available Java options. Make sure by
- typing `type java` that you use the Java you installed. Note however that
- Cygwin's `jar.exe` is used, that's why the JDK bin-directory should be
- added last in the `PATH`.
+ # Some common paths
+ if [ -x /usr/bin/msys-?.0.dll ]; then
+ # Without this the path conversion won't work
+ COMSPEC='C:\Windows\System32\cmd.exe'
+ MSYSTEM=MINGW32 # Comment out this line if in MSYS2
+ export MSYSTEM COMSPEC
+ # For MSYS2: Change /mingw/bin to the msys bin dir on the line below
+ PATH=/usr/local/bin:/mingw/bin:/bin:/c/Windows/system32:\
+ /c/Windows:/c/Windows/System32/Wbem
+ C_DRV=/c
+ IN_CYGWIN=false
+ else
+ PATH=/ldisk/overrides:/usr/local/bin:/usr/bin:/bin:\
+ /usr/X11R6/bin:/cygdrive/c/windows/system32:\
+ /cygdrive/c/windows:/cygdrive/c/windows/system32/Wbem
+ C_DRV=/cygdrive/c
+ IN_CYGWIN=true
+ fi
+
+ obe_otp_gcc_vsn_map="
+ .*=>default
+ "
+ obe_otp_64_gcc_vsn_map="
+ .*=>default
+ "
+ # Program Files
+ PRG_FLS=$C_DRV/Program\ Files
-* Nullsoft NSIS installer system. You need this to build the self
- installing package. It's a free open source installer that's much
- nicer to use than the commercial Wise and Install shield
- installers. This is the installer we use for commercial releases as
- well from R9C an on.
+ # Visual Studio
+ VISUAL_STUDIO_ROOT=$PRG_FLS/Microsoft\ Visual\ Studio\ 12.0
+ WIN_VISUAL_STUDIO_ROOT="C:\\Program Files\\Microsoft Visual Studio 12.0"
- URL: <http://www.nullsoft.com/free/nsis>
+ # SDK
+ SDK=$PRG_FLS/Windows\ Kits/8.1
+ WIN_SDK="C:\\Program Files\\Windows Kits\\8.1"
- Install the lot, especially the modern user interface components, as
- it's definitely needed. Put `makensis` in your path, in my case:
+ # NSIS
+ NSIS_BIN=$PROGRAMFILES/NSIS
- PATH=/cygdrive/c/Program\ Files/NSIS:$PATH
+ # Java
+ JAVA_BIN=$PROGRAMFILES/Java/jdk1.7.0_02/bin
- type makensis at the bash prompt and you should get a list of options
- if everything is OK.
+ ## The PATH variable should be Cygwin'ish
+ VCPATH=
+ $VISUAL_STUDIO_ROOT/VC/bin:\
+ $VISUAL_STUDIO_ROOT/VC/vcpackages:\
+ $VISUAL_STUDIO_ROOT/Common7/IDE:\
+ $VISUAL_STUDIO_ROOT/Common7/Tools:\
+ $SDK/bin/x86
-* OpenSSL. This is if you want the SSL and crypto applications to
- compile (and run). There are prebuilt binaries available, but I
- strongly recommend building this yourself. It's quite easy.
+ ## Microsoft SDK libs
+ LIBPATH=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib
- First get the source from
+ LIB=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\;$WIN_KITS\\lib\\winv6.3\\um\\x86
- URL: <http://openssl.org/source/>
+ INCLUDE=$WIN_VISUAL_STUDIO_ROOT\\VC\\include\\;\
+ $WIN_KITS\\include\\shared\\;$WIN_KITS\\include\\um;\
+ $WIN_KITS\\include\\winrt\\;$WIN_KITS\\include\\um\\gl
- I would recommend using 0.9.8r.
+ # Put nsis, c compiler and java in path
+ export PATH=$VCPATH:$PATH:$JAVA_BIN:$NSIS_BIN
- Download the tar file and unpack it (using your bash prompt) into
- a directory of your choise.
+ # Make sure LIB and INCLUDE is available for others
+ export LIBPATH LIB INCLUDE
- You will need a Windowish Perl for the build. ActiveState has one:
- URL: <http://www.activestate.com/activeperl/downloads>
- Download and install that. Disable options to associate it with
- the .pl suffix and/or adding things to PATH, they are not needed.
+ The first part of the 64 bit template is identical to the 32 bit one,
+ but there are some environment variable differences:
- Now fire up the Microsoft Windows SDK command prompt in RELEASE
- mode for the architecture you are going to build. The easiest is
- to copy the shortcut from the SDKs start menu item and edit the
- command line in the shortcut (Right click->Properties) to end with
- `/Release`. Make sure the banner when you double click your
- shortcut (the text in the resulting command window) says
- `Targeting Windows XP x64 Release` if you are going to do a 64 bit
- build and `Targeting Windows XP x86 Release` if you are building a
- 32 bit version.
+ # Program Files
+ PRG_FLS64=$C_DRV/Program\ Files
+ PRG_FLS32=$C_DRV/Program\ Files\ \(x86\)
- Now cd to where you unpacked the OpenSSL source using your Release
- Windows command prompt (it should be on the same drive as where
- you are going to install it if everything is to work smothly).
+ # Visual Studio
+ VISUAL_STUDIO_ROOT=$PRG_FLS32/Microsoft\ Visual\ Studio\ 12.0
+ WIN_VISUAL_STUDIO_ROOT="C:\\Program Files (x86)\\Microsoft Visual Studio 12.0"
- C:\> cd <some dir>
+ # SDK
+ SDK=$PRG_FLS32/Windows\ Kits/8.1
+ WIN_SDK="C:\\Program Files (x86)\\Windows Kits\\8.1"
- Add ActiveState (or some other windows perl, not cygwins) to your PATH:
+ # NSIS
+ NSIS_BIN=$PROGRAMFILES/NSIS
+ # Java
+ JAVA_BIN=$PROGRAMFILES/Java/jdk1.7.0_02/bin
- C:\...\> set PATH=C:\Perl\bin;%PATH%
+ ## The PATH variable should be Cygwin'ish
+ VCPATH=
+ $VISUAL_STUDIO_ROOT/VC/bin/amd64:\
+ $VISUAL_STUDIO_ROOT/VC/vcpackages:\
+ $VISUAL_STUDIO_ROOT/Common7/IDE:\
+ $VISUAL_STUDIO_ROOT/Common7/Tools:\
+ $SDK/bin/x86
- Or if you installed the 64bit perl:
-
- C:\...\> set PATH=C:\Perl64\bin;%PATH%
+ ## Microsoft SDK libs
+ LIBPATH=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\amd64
- Configure OpenSSL for 32 bit:
+ LIB=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\amd64\\;\
+ $WIN_KITS\\lib\\winv6.3\\um\\x64
- C:\...\> perl Configure VC-WIN32 --prefix=/OpenSSL
+ INCLUDE=$WIN_VISUAL_STUDIO_ROOT\\VC\\include\\;\
+ $WIN_KITS\\include\\shared\\;$WIN_KITS\\include\\um;\
+ $WIN_KITS\\include\\winrt\\;$WIN_KITS\\include\\um\\gl
- Or for 64 bit:
+ # Put nsis, c compiler and java in path
+ export PATH=$VCPATH:$PATH:$JAVA_BIN:$NSIS_BIN
- C:\...\> perl Configure VC-WIN64A --prefix=/OpenSSL-Win64
+ # Make sure LIB and INCLUDE is available for others
+ export LIBPATH LIB INCLUDE
- Do some setup (for 32 bit):
- C:\...\> ms\do_ms
+ Make sure to set the PATH so that NSIS and Microsoft SDK is found
+ before the MSYS/Cygwin tools and that Java is last in the PATH.
- The same for 64 bit:
+ Make a simple hello world and try to compile it with the `cl`
+ command from within bash. If that does not work, your environment
+ needs fixing. Remember, there should be
+ no backslashes in your path environment variable in Cygwin bash,
+ but LIB and INCLUDE should contain Windows style paths with
+ semicolon, drive letters and backslashes.
- C:\...\> ms\do_win64a
+* Sun's Java JDK 1.6.0 or later. Our Java code (jinterface, ic) is
+ written for JDK 1.6.0. Get it for Windows and install it, the JRE is
+ not enough. If you don't care about Java, you can skip this step. The
+ result will be that jinterface is not built.
- Then build static libraries and install:
+ URL: <http://java.sun.com>
- C:\...\> nmake -f ms\nt.mak
- C:\...\> nmake -f ms\nt.mak install
+ Add javac *LAST* to your path environment in bash, in my case this means:
- That's it - you now have your perfectly consistent static build of
- openssl. If you want to get rid of any possibly patented
- algorithms in the lib, just read up on the OpenSSL FAQ and follow
- the instructions.
+ `PATH="$PATH:/cygdrive/c/Program Files/Java/jdk1.7.0_02/bin"`
- The installation locations chosen are where configure will look
- for OpenSSL, so try to keep them as is.
-
-* Building with wxWidgets. Download wxWidgets-2.8.9 or higher patch
- release (2.9.\* is a developer release which currently does not work
- with wxErlang).
+ No `CLASSPATH` or anything is needed. Type `javac` in the bash prompt
+ and you should get a list of available Java options. Make sure, e.g by
+ typing `type java`, that you use the Java you installed. Note however that
+ Cygwin's/MinGW's/MSYS2's `jar.exe` is used. That's why the JDK bin-directory should be
+ added last in the `PATH`.
- Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`.
+* Nullsoft NSIS installer system. You need this to build the self
+ installing package. It's a free open source installer that's much
+ nicer to use than the commercial Wise and Install shield
+ installers. This is the installer we use for commercial releases as
+ well.
+
+ URL: <http://nsis.sourceforge.net/download>
- edit: `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\include\wx\msw\setup.h`
- enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and `wxUSE_GRAPHICS_CONTEXT`
+ Install the lot, especially the modern user interface components, as
+ it's definitely needed. Put `makensis` in your path, in my case:
+
+ PATH=/cygdrive/c/Program\ Files/NSIS:$PATH
+
+ Type makensis at the bash prompt and you should get a list of options
+ if everything is OK.
+
+* OpenSSL. This is if you want the SSL and crypto applications to
+ compile (and run). There are prebuilt binaries, which you can just
+ download and install, available here:
+
+ URL: <http://openssl.org/community/binaries.html>
+
+ We would recommend using 1.0.2d.
+
+* Building with wxWidgets. Download wxWidgets-3.0.2 or higher.
+
+ Install or unpack it to the pgm folder:
+ Cygwin:
+ `DRIVE:/PATH/cygwin/opt/local/pgm`
+ MSYS:
+ `DRIVE:/PATH/MinGW/msys/1.0/opt/local/pgm`
+ MSYS2:
+ `DRIVE:/PATH/msys<32/64>/opt/local/pgm`
+
+ If the `wxUSE_POSTSCRIPT` isn't enabled in `<path\to\pgm>\wxMSW-3.0.2\include\wx\msw\setup.h`,
+ enable it.
build: From a command prompt with the VC tools available (See the
instructions for OpenSSL build above for help on starting the
proper command prompt in RELEASE mode):
- C:\...\> cd C:\cygwin\opt\local\pgm\wxMSW-2.8.11\build\msw
- C:\...\> nmake BUILD=release SHARED=0 UNICODE=1 USE_OPENGL=1 USE_GDIPLUS=1 DIR_SUFFIX_CPU= -f makefile.vc
- C:\...\> cd C:\cygwin\opt\local\pgm\wxMSW-2.8.11\contrib\build\stc
- C:\...\> nmake BUILD=release SHARED=0 UNICODE=1 USE_OPENGL=1 USE_GDIPLUS=1 DIR_SUFFIX_CPU= -f makefile.vc
+ C:\...\> cd <path\to\pgm>\wxMSW-3.0.2\build\msw
+ C:\...\> nmake BUILD=release SHARED=0 DIR_SUFFIX_CPU= -f makefile.vc
Or - if building a 64bit version:
- C:\...\> cd C:\cygwin\opt\local\pgm\wxMSW-2.8.11\build\msw
- C:\...\> nmake TARGET_CPU=amd64 BUILD=release SHARED=0 UNICODE=1 USE_OPENGL=1 USE_GDIPLUS=1 DIR_SUFFIX_CPU= -f makefile.vc
- C:\...\> cd C:\cygwin\opt\local\pgm\wxMSW-2.8.11\contrib\build\stc
- C:\...\> nmake TARGET_CPU=amd64 BUILD=release SHARED=0 UNICODE=1 USE_OPENGL=1 USE_GDIPLUS=1 DIR_SUFFIX_CPU= -f makefile.vc
+ C:\...\> cd <path\to\pgm>\wxMSW-3.0.2\build\msw
+ C:\...\> nmake TARGET_CPU=amd64 BUILD=release SHARED=0 DIR_SUFFIX_CPU= -f makefile.vc
-* The Erlang source distribution (from <http://www.erlang.org/download.html>).
- The same as for Unix platforms. Preferably use tar from within Cygwin to
+* Get the Erlang source distribution (from <http://www.erlang.org/download.html>).
+ The same as for Unix platforms. Preferably use tar from within Cygwin, MSYS or MSYS2 to
unpack the source tar.gz (`tar zxf otp_src_%OTP-REL%.tar.gz`).
- set the environment `ERL_TOP` to point to the root directory of the
+ Set the environment `ERL_TOP` to point to the root directory of the
source distribution. Let's say I stood in `$HOME/src` and unpacked
`otp_src_%OTP-REL%.tar.gz`, I then add the following to `.profile`:
ERL_TOP=$HOME/src/otp_src_%OTP-REL%
export $ERL_TOP
-* The TCL/TK binaries. You could compile Tcl/Tk for windows yourself,
- but you can get a stripped down version from our website which is
- suitable to include in the final binary package. If you want to supply
- tcl/tk yourself, read the instructions about how the tcl/tk tar file
- used in the build is constructed under `$ERL_TOP/lib/gs/tcl`. The easy
- way is to download <http://www.erlang.org/download/tcltk85_win32_bin.tar.gz>
- and unpack it standing in the `$ERL_TOP` directory. This will create the
- file `win32.tar.gz` in `$ERL_TOP/lib/gs/tcl/binaries`.
-
- One last alternative is to create a file named `SKIP` in the
- `$ERL_TOP/lib/gs/` after configure is run, but that will give you an
- erlang system without gs (which might be okay as you probably will use
- wx anyway).
-
- Note that there is no special 64bit version of TCL/TK needed, you
- can use the 32bit program even for a 64bit build.
The Shell Environment
---------------------
@@ -731,37 +687,18 @@ be easy after this. You could run `./otp_build env_win32` without
sets seems OK. The path is cleaned of spaces if possible (using DOS
style short names instead), the variables `OVERRIDE_TARGET`, `CC`, `CXX`,
`AR` and `RANLIB` are set to their respective wrappers and the directories
-`$ERL_TOP/erts/etc/win32/cygwin_tools/vc` and
-`$ERL_TOP/erts/etc/win32/cygwin_tool` are added first in the PATH.
-
-Try now a `type erlc`. That should result in the erlc wrapper script
-(which does not have the .sh extension, for reasons best kept
-untold...). It should reside in `$ERL_TOP/erts/etc/win32/cygwin_tools`
-or `$ERL_TOP/erts/etc/win32/msys_tools`. You could also try `which
-cc.sh`, which `ar.sh` etc.
+`$ERL_TOP/erts/etc/win32/<cygwin/msys>_tools/vc` and
+`$ERL_TOP/erts/etc/win32/<cygwin/msys>_tool` are added first in the PATH.
-Now you're ready to build...
+Now you can check which erlc you have by writing `type erlc` in your shell.
+It should reside in `$ERL_TOP/erts/etc/win32/cygwin_tools`
+or `$ERL_TOP/erts/etc/win32/msys_tools`.
Building and Installing
-----------------------
-Now it's assumed that you have executed `` eval `./otp_build env_win32` `` or
-`` eval `./otp_build env_win32 x64` `` for this particular shell...
-
-Building is easiest using the `otp_build` script. That script takes care
-of running configure, bootstrapping etc on Windows in a simple
-way. The `otp_build` script is the utility we use ourselves to build on
-different platforms and it therefore contains code for all sorts of
-platforms. The principle is, however, that for non-Unix platforms, one
-uses `./otp_build env_<target>` to set up environment and then the
-script knows how to build on the platform "by itself". You've already
-run `./otp_build env_win32` in the step above, so now it's mostly like
-we build on any platform. OK, here are then steps; Assuming you will
-want to build a full installation executable with NSIS, you can omit
-`<installation directory>` and the release will be copied to
-`$ERL_TOP/release/win32`: and there is where the packed self installing
-executable will reside too.
+Building is easiest using the `otp_build` script:
$ ./otp_build autoconf # Ignore the warning blob about versions of autoconf
$ ./otp_build configure <optional configure options>
@@ -769,18 +706,18 @@ executable will reside too.
$ ./otp_build release -a <installation directory>
$ ./otp_build installer_win32 <installation directory> # optional
-Now you will have a file called `otp_win32_R12B.exe` in the
-`<installation directory>`, i.e. `$ERL_TOP/release/win32`.
+Now you will have a file called `otp_win32_%OTP-REL%.exe` or `otp_win64_%OTP-REL%.exe`
+in the `<installation directory>`, i.e. `$ERL_TOP/release/win32`.
Lets get into more detail:
1. `$ ./otp_build autoconf` - This step rebuilds the configure scripts
- to work correctly in the cygwin environment. In an ideal world, this
+ to work correctly in your environment. In an ideal world, this
would not be needed, but alas, we have encountered several
incompatibilities between our distributed configure scripts (generated
- on a Linux platform) and the cygwin environment over the
- years. Running autoconf on cygwin ensures that the configure scripts
- are generated in a cygwin-compatible way and that they will work well
+ on a Linux platform) and the Cygwin/MSYS/MSYS2 environment over the
+ years. Running autoconf in Cygwin/MSYS/MSYS2 ensures that the configure
+ scripts are generated in a compatible way and that they will work well
in the next step.
2. `$ ./otp_build configure` - This runs the newly generated configure
@@ -789,38 +726,21 @@ Lets get into more detail:
this awkward target name and behave accordingly. The CC variable also
makes the compiler be `cc.sh`, which wraps MSVC++, so all configure
tests regarding the C compiler gets to run the right compiler. A lot of
- the tests are not needed on Windows, but I thought it best to run the
- whole configure anyway. The only configure option you might want to
- supply is `--with-ssl`, which might be needed if you have built your
- own OpenSSL distribution. The Shining Lights distribution should be
- found automatically by `configure`, if that fails, add a
- `--with-ssl=<dir>` that specifies the root directory of your OpenSSL
- installation.
+ the tests are not needed on Windows, but we thought it best to run the
+ whole configure anyway.
3. `$ ./otp_build boot -a` - This uses the bootstrap directory (shipped
with the source, `$ERL_TOP/bootstrap`) to build a complete OTP
- system. It first builds an emulator and sets up a minimal OTP system
- under `$ERL_TOP/bootstrap`, then starts to compile the different OTP
- compilers to make the `$ERL_TOP/bootstrap` system potent enough to be
- able to compile all Erlang code in OTP. Then, all Erlang and C code
- under `$ERL_TOP/lib` is built using the bootstrap system, giving a
- complete OTP system (although not installed). When this is done, one
- can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl`
- and you should have a prompt. If you omit the -a flag, you'll get a
- smaller system, that might be useful during development. Now
- exit from Erlang and start making a release of the thing:
+ system. When this is done you can run erl from within the source tree;
+ just type `$ERL_TOP/bin/erl` and you whould have the prompt.
4. `$ ./otp_build release -a` - Builds a commercial release tree from the
- source tree, default is to put it in `$ERL_TOP/release/win32`, you can
+ source tree. The default is to put it in `$ERL_TOP/release/win32`. You can
give any directory as parameter (Cygwin style), but it doesn't really
- matter if you're going to build a self extracting installer too. You
- could of course build release to the final directory and then run
- `./Install.exe` standing in the directory where the release was put,
- that will create a fully functional OTP installation. But let's make
- the nifty installer:
-
-5. `$ ./otp_build installer_win32` - Create the self extracting installer
- executable. The executable `otp_win32_%OTP-REL%.exe` will be placed
+ matter if you're going to build a self extracting installer too.
+
+5. `$ ./otp_build installer_win32` - Creates the self extracting installer executable.
+ The executable `otp_win32_%OTP-REL%.exe` or `otp_win64_%OTP-REL%.exe` will be placed
in the top directory of the release created in the previous step. If
no release directory is specified, the release is expected to have
been built to `$ERL_TOP/release/win32`, which also will be the place
@@ -829,7 +749,7 @@ Lets get into more detail:
/tmp/erl_release`), you're expected to give the same parameter here,
(i.e. `./otp_build installer_win32 /tmp/erl_release`). You need to have
a full NSIS installation and `makensis.exe` in your path for this to
- work of course. Once you have created the installer, you can run it to
+ work. Once you have created the installer, you can run it to
install Erlang/OTP in the regular way, just run the executable and
follow the steps in the installation wizard. To get all default settings
in the installation without any questions asked, you run the executable
@@ -849,37 +769,17 @@ Lets get into more detail:
and after a while Erlang/OTP-%OTP-REL% will have been installed in
`C:\Program Files\erl%ERTS-VSN%\`, with shortcuts in the menu etc.
- The necessary setup of an Erlang installation is actually done by the
- program `Install.exe`, which resides in the release top. That program
- creates `.ini`-files and copies the correct boot scripts. If one has
- the correct directory tree (like after a `./otp_build release -a`), only
- the running of `Install.exe` is necessary to get a fully functional
- OTP. What the self extracting installer adds is (of course) the
- possibility to distribute the binary easily, together with adding
- shortcuts to the Windows start menu. There is also some adding of
- entries in the registry, to associate `.erl` and `.beam` files with
- Erlang and get nifty icons, but that's not something you'll really need
- to run Erlang. The registry is also used to store uninstall information,
- but if one has not used the self extracting installer, one cannot
- (need not) do any uninstall, one just scratches the release directory
- and everything is gone. Erlang/OTP does not *need* to put anything
- in the Windows registry at all, and does not if you don't use the self
- extracting installer. In other words the installer is pure cosmetics.
-
-> *NOTE*: Beginning with R9C, the Windows installer does *not* add Erlang
-> to the system wide path. If one wants to have Erlang in the path, one
-> has to add it by hand.
Development
-----------
Once the system is built, you might want to change it. Having a test
-release in some nice directory might be useful, but you also can run
+release in some nice directory might be useful, but you can also run
Erlang from within the source tree. The target `local_setup`, makes
the program `$ERL_TOP/bin/erl.exe` usable and it also uses all the OTP
libraries in the source tree.
-If you hack the emulator, you can then build the emulator executable
+If you hack the emulator, you can build the emulator executable
by standing in `$ERL_TOP/erts/emulator` and do a simple
$ make opt
@@ -928,12 +828,12 @@ or even in the source directory...
$ cd $ERL_TOP/lib/stdlib/src
$ make opt
-Note that you're expected o have a fresh Erlang in your path when
+Note that you're expected to have a fresh Erlang in your path when
doing this, preferably the plain %OTP-REL% you have built in the previous
steps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before
-rebuilding specific libraries, that would give you a good enough
+rebuilding specific libraries. That would give you a good enough
Erlang system to compile any OTP erlang code. Setting up the path
-correctly is a little bit tricky, you still need to have
+correctly is a little bit tricky. You still need to have
`$ERL_TOP/erts/etc/win32/cygwin_tools/vc` and
`$ERL_TOP/erts/etc/win32/cygwin_tools` *before* the actual emulator
in the path. A typical setting of the path for using the bootstrap
@@ -968,72 +868,45 @@ Remember that:
That's basically all you need to get going.
+
Using GIT
---------
-You might want to check out versions of the source code from GitHUB. That is possible directly in cygwin, but not in Msys. There is a project MsysGIT:
+You might want to check out versions of the source code from GitHUB. That is possible directly in Cygwin, but not in MSYS. There is a project MsysGIT:
URL:<http://code.google.com/p/msysgit/>
that makes a nice Git port. The msys prompt you get from MsysGIT is
however not compatible with the full version from MinGW, so you will
need to check out files using MsysGIT's command prompt and then switch
-to a common Msys command prompt for building. Also all test suites
-cannot be built as MsysGIT/Msys does not handle symbolic links. To
-build test suites on Windows, you will need Cygwin for now. Hopefully
-all symbolic links will disappear from our repository soon and this
-issue will disappear.
+to a common MSYS command prompt for building. Also all test suites
+cannot be built as MsysGIT/MSYS does not handle symbolic links.
-Final Words
------------
-My hope is that the possibility to build the whole system on Windows
-will open up for free development on this platform too. There are many
-things one might want to do better in the Windows version, like the
-window-style command prompt as well as pure Cygwin porting. Although i
-realize it's a much larger step to start building on Windows (with all
-the software you need) than for instance on Linux, I sincerely hope
-that some of you will make the effort and start submitting Windows
-friendly patches.
-
-The first build system for Erlang using Cygwin on Windows was created
-by Per Bergkvist. I haven't used his build system, but it's rumored to
-be good. The idea to do this came from his work, so credit is well
-deserved.
-
-Of course this would have been completely impossible without the
-excellent Cygwin. The guys at Cygnus solutions and
-Redhat deserve a huge THANKS! as well as all the other people in the
-free software community who have helped in creating the magnificent
-software that constitutes Cygwin.
-
-Also the people developing the alternative command prompt Msys and
-the MinGW compiler are worth huge THANKS! The 64bit port would have
-been impossible without the 64bit MinGW compiler.
-
-Good luck and Happy Hacking,
-Patrik, OTP
Copyright and License
---------------------
%CopyrightBegin%
-Copyright Ericsson AB 2003-2014. All Rights Reserved.
+Copyright Ericsson AB 2003-2015. All Rights Reserved.
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
+Licensed under the Apache License, Version 2.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
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+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%
- [1]: http://www.erlang.org/faq.html "mailing lists"
+ [1]: http://www.erlang.org/static/doc/mailinglist.html
+ [2]: http://bugs.erlang.org
+ [3]: https://github.com/erlang/otp
[?TOC]: true
diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md
index 53b1b8cd8a..43bcdb3a9e 100644
--- a/HOWTO/INSTALL.md
+++ b/HOWTO/INSTALL.md
@@ -76,10 +76,10 @@ also find the utilities needed for building the documentation.
Read more and download from <http://www.openssl.org>.
* Oracle Java SE JDK -- The Java Development Kit (Standard Edition).
Required for building the application `jinterface` and parts of `ic` and `orber`.
- At least version 1.5.0 of the JDK is required.
+ At least version 1.6.0 of the JDK is required.
Download from <http://www.oracle.com/technetwork/java/javase/downloads>.
- We have also tested with IBM's JDK 1.5.0.
+ We have also tested with IBM's JDK 1.6.0.
* X Windows -- Development headers and libraries are needed
to build the Erlang/OTP application `gs` on Unix/Linux.
* `flex` -- Headers and libraries are needed to build the flex
@@ -210,6 +210,14 @@ the `$PATH`.
$ export PATH=$ERL_TOP/bin:$PATH # Assuming bash/sh
+For the FOP print formatter, two steps must be taken:
+
+* Adding the location of your installation of `fop` in `$FOP_HOME`.
+
+ $ export FOP_HOME=/path/to/fop/dir # Assuming bash/sh
+
+* Adding the `fop` script (in `$FOP_HOME`) to your `$PATH`, either by adding `$FOP_HOME` to `$PATH`, or by copying the `fop` script to a directory already in your `$PATH`.
+
Build the documentation.
$ make docs
@@ -366,9 +374,15 @@ Some of the available `configure` options are:
`jinterface` application won't be built)
* `--{enable,disable}-dynamic-ssl-lib` - Dynamic OpenSSL libraries
* `--{enable,disable}-builtin-zlib` - Use the built-in source for zlib.
-* `--with-ssl=PATH` - Specify location of OpenSSL include and lib
* `--{with,without}-ssl` - OpenSSL (without implies that the `crypto`,
`ssh`, and `ssl` won't be built)
+* `--with-ssl=PATH` - Specify location of OpenSSL include and lib
+* `--with-ssl-incl=PATH` - Location of OpenSSL `include` directory,
+ if different than specified by `--with-ssl=PATH`
+* `--with-ssl-rpath=yes|no|PATHS` - Runtime library path for OpenSSL.
+ Default is `yes`, which equates to a number of standard locations. If
+ `no`, then no runtime library paths will be used. Anything else should be
+ a comma separated list of paths.
* `--with-libatomic_ops=PATH` - Use the `libatomic_ops` library for atomic
memory accesses. If `configure` should inform you about no native atomic
implementation available, you typically want to try using the
@@ -392,7 +406,7 @@ Some of the available `configure` options are:
that has to be the same as the filename. You also have to define
`STATIC_ERLANG_{NIF,DRIVER}` when compiling the .o files for the nif/driver.
If your nif/driver depends on some other dynamic library, you now have to link
- that to the Erlang VM binary. This is easily achived by passing `LIBS=-llibname`
+ that to the Erlang VM binary. This is easily achieved by passing `LIBS=-llibname`
to configure.
* `--without-$app` - By default all applications in Erlang/OTP will be included
in a release. If this is not wanted it is possible to specify that Erlang/OTP
@@ -400,6 +414,18 @@ Some of the available `configure` options are:
no automatic dependency handling between applications. If you disable
an application that another application depends on, you also have to disable the
dependant application.
+* `--enable-gettimeofday-as-os-system-time` - Force usage of `gettimeofday()` for
+ OS system time.
+* `--enable-prefer-elapsed-monotonic-time-during-suspend` - Prefer an OS monotonic
+ time source with elapsed time during suspend.
+* `--disable-prefer-elapsed-monotonic-time-during-suspend` - Do not prefer an OS
+ monotonic time source with elapsed time during suspend.
+* `--with-clock-resolution=high|low` - Try to find clock sources for OS system
+ time, and OS monotonic time with higher or lower resolution than chosen by
+ default. Note that both alternatives may have a negative impact on the performance
+ and scalability compared to the default clock sources chosen.
+* `--disable-saved-compile-time` - Disable saving of compile date and time
+ in the emulator binary.
* `--enable-dirty-schedulers` - Enable the **experimental** dirty schedulers
functionality. Note that the dirty schedulers functionality is experimental,
and **not supported**. This functionality **will** be subject to backward
@@ -417,22 +443,33 @@ important when building Erlang/OTP. By default the VM will refuse to build
if native atomic memory operations are not available.
Erlang/OTP itself provides implementations of native atomic memory operations
-that can be used when compiling with a `gcc` compatible compiler on 32-bit
-and 64-bit x86, 32-bit and 64-bit SPARC V9, and 32-bit PowerPC. When compiling
-with a `gcc` compatible compiler on other architectures, the VM may be able to
-make use of native atomic operations using the `__sync_*` primitives, but this
-should only be used as a last resort since this wont give you optimal
-performance. When compiling on Windows using a MicroSoft Visual C++ compiler
-native atomic memory operations are provided by Windows APIs.
-
-You are recommended to use the native atomic implementation provided by
-Erlang/OTP, or the API provided by Windows. If these do not provide native
-atomics on your platform, you are recommended to build and install
-[libatomic_ops][] before building Erlang/OTP. The `libatomic_ops` library
-provides native atomic memory operations for a variety of platforms and
-compilers. When building Erlang/OTP you need to inform the build system of
-where the `libatomic_ops` library is installed using the
-`--with-libatomic_ops=PATH` configure switch.
+that can be used when compiling with a `gcc` compatible compiler for 32/64-bit
+x86, 32/64-bit SPARC V9, 32-bit PowerPC, or 32-bit Tile. When compiling with
+a `gcc` compatible compiler for other architectures, the VM may be able to make
+use of native atomic operations using the `__atomic_*` builtins (may be
+available when using a `gcc` of at least version 4.7) and/or using the
+`__sync_*` builtins (may be available when using a `gcc` of at least version
+4.1). If only the `gcc`'s `__sync_*` builtins are available, the performance
+will suffer. Such a configuration should only be used as a last resort. When
+compiling on Windows using a MicroSoft Visual C++ compiler native atomic
+memory operations are provided by Windows APIs.
+
+Native atomic implementation in the order preferred:
+1. The implementation provided by Erlang/OTP.
+2. The API provided by Windows.
+3. The implementation based on the `gcc` `__atomic_*` builtins.
+4. If none of the above are available for your architecture/compiler, you
+ are recommended to build and install [libatomic_ops][] before building
+ Erlang/OTP. The `libatomic_ops` library provides native atomic memory
+ operations for a variety of architectures and compilers. When building
+ Erlang/OTP you need to inform the build system of where the
+ `libatomic_ops` library is installed using the
+ `--with-libatomic_ops=PATH` `configure` switch.
+5. As a last resort, the implementation solely based on the `gcc`
+ `__sync_*` builtins. This will however cause lots of expensive and
+ unnecessary memory barrier instructions to be issued. That is,
+ performance will suffer. The `configure` script will warn at the end
+ of its execution if it cannot find any other alternative than this.
### Building ###
@@ -485,7 +522,7 @@ If you have Xcode 4.3, or later, you will also need to download
If you want to build the `wx` application, you will need to get wxWidgets-3.0
(`wxWidgets-3.0.0.tar.bz2` from <http://sourceforge.net/projects/wxwindows/files/3.0.0/>) or get it from github with bug fixes:
- $ git clone --branch WX_3_0_branch [email protected]:wxWidgets/wxWidgets.git
+ $ git clone --branch WX_3_0_BRANCH [email protected]:wxWidgets/wxWidgets.git
Be aware that the wxWidgets-3.0 is a new release of wxWidgets, it is not as
mature as the old releases and the OS X port still lags behind the other ports.
@@ -849,18 +886,19 @@ Copyright and License
%CopyrightBegin%
-Copyright Ericsson AB 1998-2014. All Rights Reserved.
+Copyright Ericsson AB 1998-2015. All Rights Reserved.
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
+Licensed under the Apache License, Version 2.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
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+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%
diff --git a/HOWTO/MARKDOWN.md b/HOWTO/MARKDOWN.md
index 8e8a5c02cf..2df0460dab 100644
--- a/HOWTO/MARKDOWN.md
+++ b/HOWTO/MARKDOWN.md
@@ -246,16 +246,17 @@ Copyright and License
Copyright Ericsson AB 2010-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.
+Licensed under the Apache License, Version 2.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%
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000..e454a52586
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,178 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/Makefile.in b/Makefile.in
index 3b545f08ce..b842f268bb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/OTP_VERSION b/OTP_VERSION
index 3309c98bff..0548779ef2 100644
--- a/OTP_VERSION
+++ b/OTP_VERSION
@@ -1 +1 @@
-17.5.6
+18.3.4
diff --git a/README.md b/README.md
index bf80b6391b..ed3bf26d6e 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,12 @@ In short:
* Once or twice a week, a status email called ["What's cooking in Erlang/OTP"] [4]
will be sent to the [`erlang-patches`] [3] mailing list.
+Bug Reports
+--------------------------
+
+Please look at the [instructions for submitting bugs reports] [6].
+
+
Copyright and License
---------------------
@@ -68,16 +74,17 @@ Copyright and License
>
> Copyright Ericsson AB 2010-2014. All Rights Reserved.
>
-> The contents of this file are subject to the Erlang Public License,
-> Version 1.1, (the "License"); you may not use this file except in
-> compliance with the License. You should have received a copy of the
-> Erlang Public License along with this software. If not, it can be
-> retrieved online at http://www.erlang.org/.
+> Licensed under the Apache License, Version 2.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
>
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
+> 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%
@@ -88,3 +95,4 @@ Copyright and License
[3]: http://www.erlang.org/static/doc/mailinglist.html
[4]: http://erlang.github.com/otp/
[5]: HOWTO/INSTALL.md
+ [6]: https://github.com/erlang/otp/wiki/Bug-reports
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index 6cc4fa1f43..ea3b3775aa 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 6cc4fa1f43..ea3b3775aa 100644
--- a/bootstrap/bin/start_clean.boot
+++ b/bootstrap/bin/start_clean.boot
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_a.beam b/bootstrap/lib/compiler/ebin/beam_a.beam
index 87e9759ffe..3ff689bd81 100644
--- a/bootstrap/lib/compiler/ebin/beam_a.beam
+++ b/bootstrap/lib/compiler/ebin/beam_a.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam
index e6c5cc9028..91c487f3d5 100644
--- a/bootstrap/lib/compiler/ebin/beam_asm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_asm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_block.beam b/bootstrap/lib/compiler/ebin/beam_block.beam
index 11482a1451..5d1e45fd72 100644
--- a/bootstrap/lib/compiler/ebin/beam_block.beam
+++ b/bootstrap/lib/compiler/ebin/beam_block.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam
index 6454719448..e503ad7484 100644
--- a/bootstrap/lib/compiler/ebin/beam_bool.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bool.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_bsm.beam b/bootstrap/lib/compiler/ebin/beam_bsm.beam
index 1b51483bb1..2f18ae4f30 100644
--- a/bootstrap/lib/compiler/ebin/beam_bsm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bsm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_clean.beam b/bootstrap/lib/compiler/ebin/beam_clean.beam
index f6a9ff987d..2fd2d2a82f 100644
--- a/bootstrap/lib/compiler/ebin/beam_clean.beam
+++ b/bootstrap/lib/compiler/ebin/beam_clean.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dead.beam b/bootstrap/lib/compiler/ebin/beam_dead.beam
index dc924a2905..6ae6de1d8b 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 89867ee4a3..17b3c40eda 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 f050f39ca0..7c5dca424f 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 0de15769c4..f4fccfeef7 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_flatten.beam b/bootstrap/lib/compiler/ebin/beam_flatten.beam
index 35dae78125..c1d5604349 100644
--- a/bootstrap/lib/compiler/ebin/beam_flatten.beam
+++ b/bootstrap/lib/compiler/ebin/beam_flatten.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_jump.beam b/bootstrap/lib/compiler/ebin/beam_jump.beam
index 2b839bc997..630a370a94 100644
--- a/bootstrap/lib/compiler/ebin/beam_jump.beam
+++ b/bootstrap/lib/compiler/ebin/beam_jump.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_listing.beam b/bootstrap/lib/compiler/ebin/beam_listing.beam
index 662edc0651..4d8f94c4ea 100644
--- a/bootstrap/lib/compiler/ebin/beam_listing.beam
+++ b/bootstrap/lib/compiler/ebin/beam_listing.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_peep.beam b/bootstrap/lib/compiler/ebin/beam_peep.beam
index 214fa56911..7a7856e247 100644
--- a/bootstrap/lib/compiler/ebin/beam_peep.beam
+++ b/bootstrap/lib/compiler/ebin/beam_peep.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_receive.beam b/bootstrap/lib/compiler/ebin/beam_receive.beam
index 5da32b5db6..78c9eb1c39 100644
--- a/bootstrap/lib/compiler/ebin/beam_receive.beam
+++ b/bootstrap/lib/compiler/ebin/beam_receive.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_split.beam b/bootstrap/lib/compiler/ebin/beam_split.beam
index 1d12f2cf1d..4821d92c96 100644
--- a/bootstrap/lib/compiler/ebin/beam_split.beam
+++ b/bootstrap/lib/compiler/ebin/beam_split.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_trim.beam b/bootstrap/lib/compiler/ebin/beam_trim.beam
index b844602370..6878a8a01c 100644
--- a/bootstrap/lib/compiler/ebin/beam_trim.beam
+++ b/bootstrap/lib/compiler/ebin/beam_trim.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_type.beam b/bootstrap/lib/compiler/ebin/beam_type.beam
index 7f80c1a691..cb3bc1a8bd 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 8507db5454..fc2e1b6c78 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 07225dc8b1..8b13cea141 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/beam_z.beam b/bootstrap/lib/compiler/ebin/beam_z.beam
index ad551bcc8c..ac156a37e9 100644
--- a/bootstrap/lib/compiler/ebin/beam_z.beam
+++ b/bootstrap/lib/compiler/ebin/beam_z.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl.beam b/bootstrap/lib/compiler/ebin/cerl.beam
index 0f0670c9ae..7ff73413d7 100644
--- a/bootstrap/lib/compiler/ebin/cerl.beam
+++ b/bootstrap/lib/compiler/ebin/cerl.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam
index 2f7f220ebd..0e466ad38e 100644
--- a/bootstrap/lib/compiler/ebin/cerl_inline.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_inline.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_sets.beam b/bootstrap/lib/compiler/ebin/cerl_sets.beam
new file mode 100644
index 0000000000..d16543cdbe
--- /dev/null
+++ b/bootstrap/lib/compiler/ebin/cerl_sets.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_trees.beam b/bootstrap/lib/compiler/ebin/cerl_trees.beam
index 1338631c23..b23668fb2b 100644
--- a/bootstrap/lib/compiler/ebin/cerl_trees.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_trees.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam
index eb682b953c..111f85acd2 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 ea1be86c83..4dd52e31bf 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -3,22 +3,23 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{application, compiler,
[{description, "ERTS CXC 138 10"},
- {vsn, "5.0.3"},
+ {vsn, "6.0.2"},
{modules, [
beam_a,
beam_asm,
@@ -45,6 +46,7 @@
cerl,
cerl_clauses,
cerl_inline,
+ cerl_sets,
cerl_trees,
compile,
core_scan,
@@ -56,6 +58,7 @@
rec_env,
sys_core_dsetel,
sys_core_fold,
+ sys_core_fold_lists,
sys_core_inline,
sys_pre_attributes,
sys_pre_expand,
@@ -68,5 +71,5 @@
{registered, []},
{applications, [kernel, stdlib]},
{env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","hipe-3.10.3","erts-6.0",
- "crypto-3.3"]}]}.
+ {runtime_dependencies, ["stdlib-2.5","kernel-4.0","hipe-3.12","erts-7.0",
+ "crypto-3.6"]}]}.
diff --git a/bootstrap/lib/compiler/ebin/compiler.appup b/bootstrap/lib/compiler/ebin/compiler.appup
index e73b9aa60c..ceb96264d5 100644
--- a/bootstrap/lib/compiler/ebin/compiler.appup
+++ b/bootstrap/lib/compiler/ebin/compiler.appup
@@ -3,19 +3,20 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
-{"5.0",
+{"6.0.2",
[{<<".*">>,[{restart_application, compiler}]}],
[{<<".*">>,[{restart_application, compiler}]}]
}.
diff --git a/bootstrap/lib/compiler/ebin/core_lib.beam b/bootstrap/lib/compiler/ebin/core_lib.beam
index 54f43c6c10..ec87099635 100644
--- a/bootstrap/lib/compiler/ebin/core_lib.beam
+++ b/bootstrap/lib/compiler/ebin/core_lib.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_lint.beam b/bootstrap/lib/compiler/ebin/core_lint.beam
index e172ec6af7..b1cbbf030d 100644
--- a/bootstrap/lib/compiler/ebin/core_lint.beam
+++ b/bootstrap/lib/compiler/ebin/core_lint.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_parse.beam b/bootstrap/lib/compiler/ebin/core_parse.beam
index 121ef65275..025ac1591b 100644
--- a/bootstrap/lib/compiler/ebin/core_parse.beam
+++ b/bootstrap/lib/compiler/ebin/core_parse.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_pp.beam b/bootstrap/lib/compiler/ebin/core_pp.beam
index e6e60fb658..7ba89c698e 100644
--- a/bootstrap/lib/compiler/ebin/core_pp.beam
+++ b/bootstrap/lib/compiler/ebin/core_pp.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_scan.beam b/bootstrap/lib/compiler/ebin/core_scan.beam
index 73f588232a..c54edfc0e7 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 27136581c1..d6c4dec85e 100644
--- a/bootstrap/lib/compiler/ebin/erl_bifs.beam
+++ b/bootstrap/lib/compiler/ebin/erl_bifs.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/rec_env.beam b/bootstrap/lib/compiler/ebin/rec_env.beam
index 4bd37b16c0..c49a2e23e9 100644
--- a/bootstrap/lib/compiler/ebin/rec_env.beam
+++ b/bootstrap/lib/compiler/ebin/rec_env.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam b/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam
index 29dfdfb755..14c69eec6c 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
index 64477ec574..cbdef8e1d7 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_fold_lists.beam b/bootstrap/lib/compiler/ebin/sys_core_fold_lists.beam
new file mode 100644
index 0000000000..58ae7c0393
--- /dev/null
+++ b/bootstrap/lib/compiler/ebin/sys_core_fold_lists.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 1e358ee0ea..4f44297bee 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_inline.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_inline.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam b/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
index f7621bbc3f..a1c6466ccd 100644
--- a/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
+++ b/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_pre_expand.beam b/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
index c0c537f623..6eba755081 100644
--- a/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
+++ b/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam
index 3670fd206c..10647442a3 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 851b5512c3..5c5a124e4c 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 1e549a41c7..f5cdbb6e40 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 1798a279b0..d54716bbee 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 0eb0cb6caf..741a702e88 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.beam b/bootstrap/lib/kernel/ebin/application.beam
index 6946d17545..97c6d9d415 100644
--- a/bootstrap/lib/kernel/ebin/application.beam
+++ b/bootstrap/lib/kernel/ebin/application.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam
index 2a4525c27f..c4fa46e33e 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 365bc7b53d..b81dfa81d3 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/auth.beam b/bootstrap/lib/kernel/ebin/auth.beam
index 3cc607cb14..74dde4fd1c 100644
--- a/bootstrap/lib/kernel/ebin/auth.beam
+++ b/bootstrap/lib/kernel/ebin/auth.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam
index 5428f2cf0c..71b2025094 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 340c5feed9..f2400a9a6f 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 8a7d6a8388..287a8c0de8 100644
--- a/bootstrap/lib/kernel/ebin/disk_log.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log_1.beam b/bootstrap/lib/kernel/ebin/disk_log_1.beam
index 5193dfa53d..9c887c8ed9 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_1.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_1.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/dist_ac.beam b/bootstrap/lib/kernel/ebin/dist_ac.beam
index 9d3f7548b6..ea948cfe88 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 ea09695075..f87dd4a45c 100644
--- a/bootstrap/lib/kernel/ebin/dist_util.beam
+++ b/bootstrap/lib/kernel/ebin/dist_util.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_boot_server.beam b/bootstrap/lib/kernel/ebin/erl_boot_server.beam
index 6e56a1061d..91899fe231 100644
--- a/bootstrap/lib/kernel/ebin/erl_boot_server.beam
+++ b/bootstrap/lib/kernel/ebin/erl_boot_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_epmd.beam b/bootstrap/lib/kernel/ebin/erl_epmd.beam
index bf171450e9..8910de12ef 100644
--- a/bootstrap/lib/kernel/ebin/erl_epmd.beam
+++ b/bootstrap/lib/kernel/ebin/erl_epmd.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erts_debug.beam b/bootstrap/lib/kernel/ebin/erts_debug.beam
index 17320342bc..bd73ff6c5c 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 5305c3854c..32a3a27993 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 dfaa1b07f0..b9c53bde49 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/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index d25be3994c..158fbd1c93 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 d11f60015a..85306ef123 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 412b8e0007..0f72880f49 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 d4972ecdd2..8892785416 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 6df9ac9564..9da5cce487 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 4fff1c069d..75743c63cc 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 036b0495c8..96dd4739ea 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
index 83305c1826..1be1dc1c57 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_config.beam b/bootstrap/lib/kernel/ebin/inet_config.beam
index e858ac20f1..f31fb16742 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 45e7d9e0d0..6401f0fcfa 100644
--- a/bootstrap/lib/kernel/ebin/inet_db.beam
+++ b/bootstrap/lib/kernel/ebin/inet_db.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_dns.beam b/bootstrap/lib/kernel/ebin/inet_dns.beam
index 9fd86024e0..b1c3bf3369 100644
--- a/bootstrap/lib/kernel/ebin/inet_dns.beam
+++ b/bootstrap/lib/kernel/ebin/inet_dns.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index 90ccd8b440..294afcea30 100644
--- a/bootstrap/lib/kernel/ebin/inet_parse.beam
+++ b/bootstrap/lib/kernel/ebin/inet_parse.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_res.beam b/bootstrap/lib/kernel/ebin/inet_res.beam
index 2636552e92..f35242f49a 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 503cbc11e2..19506c14e9 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 d854abd830..c2b42fef1c 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 2e54f1e1f4..1b389cbb4d 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/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index 3388f28e91..14f526c30c 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -21,7 +22,7 @@
{application, kernel,
[
{description, "ERTS CXC 138 10"},
- {vsn, "3.1"},
+ {vsn, "4.1.1"},
{modules, [application,
application_controller,
application_master,
@@ -115,6 +116,6 @@
{applications, []},
{env, [{error_logger, tty}]},
{mod, {kernel, []}},
- {runtime_dependencies, ["erts-6.1.2", "stdlib-2.0", "sasl-2.4"]}
+ {runtime_dependencies, ["erts-7.3", "stdlib-2.6", "sasl-2.6"]}
]
}.
diff --git a/bootstrap/lib/kernel/ebin/kernel.appup b/bootstrap/lib/kernel/ebin/kernel.appup
index b6fade4222..7810fb611b 100644
--- a/bootstrap/lib/kernel/ebin/kernel.appup
+++ b/bootstrap/lib/kernel/ebin/kernel.appup
@@ -1,25 +1,26 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
-{"3.1",
+{"4.1.1",
%% Up from - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
+ [{<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"3\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-17
%% Down to - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
+ [{<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"3\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-17
}.
diff --git a/bootstrap/lib/kernel/ebin/kernel.beam b/bootstrap/lib/kernel/ebin/kernel.beam
index c938b218e1..caeda89fa5 100644
--- a/bootstrap/lib/kernel/ebin/kernel.beam
+++ b/bootstrap/lib/kernel/ebin/kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel_config.beam b/bootstrap/lib/kernel/ebin/kernel_config.beam
index c35da2c73d..5a4649a054 100644
--- a/bootstrap/lib/kernel/ebin/kernel_config.beam
+++ b/bootstrap/lib/kernel/ebin/kernel_config.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam
index 33193008c7..e0bb445bf5 100644
--- a/bootstrap/lib/kernel/ebin/net_kernel.beam
+++ b/bootstrap/lib/kernel/ebin/net_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/os.beam b/bootstrap/lib/kernel/ebin/os.beam
index b1b92ca36b..9eaf7dfe5d 100644
--- a/bootstrap/lib/kernel/ebin/os.beam
+++ b/bootstrap/lib/kernel/ebin/os.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/pg2.beam b/bootstrap/lib/kernel/ebin/pg2.beam
index c26b5a4ffc..944f6a27a4 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 4d6df15730..a8b23f5490 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/seq_trace.beam b/bootstrap/lib/kernel/ebin/seq_trace.beam
index 13489135a2..efc5b7dc2a 100644
--- a/bootstrap/lib/kernel/ebin/seq_trace.beam
+++ b/bootstrap/lib/kernel/ebin/seq_trace.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user.beam b/bootstrap/lib/kernel/ebin/user.beam
index 0e06c78fce..d69339866a 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 4a2cd01b0d..6027806558 100644
--- a/bootstrap/lib/kernel/ebin/user_drv.beam
+++ b/bootstrap/lib/kernel/ebin/user_drv.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/wrap_log_reader.beam b/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
index f35187c269..68578800a0 100644
--- a/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
+++ b/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/include/dist.hrl b/bootstrap/lib/kernel/include/dist.hrl
index 77556d1303..47d9459a19 100644
--- a/bootstrap/lib/kernel/include/dist.hrl
+++ b/bootstrap/lib/kernel/include/dist.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/kernel/include/dist_util.hrl b/bootstrap/lib/kernel/include/dist_util.hrl
index c3a7f97418..d5df2be4ec 100644
--- a/bootstrap/lib/kernel/include/dist_util.hrl
+++ b/bootstrap/lib/kernel/include/dist_util.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/kernel/include/file.hrl b/bootstrap/lib/kernel/include/file.hrl
index 69aec1ee36..7cf033f7f5 100644
--- a/bootstrap/lib/kernel/include/file.hrl
+++ b/bootstrap/lib/kernel/include/file.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/bootstrap/lib/kernel/include/inet.hrl b/bootstrap/lib/kernel/include/inet.hrl
index 3e64d4bb79..d983fa9e72 100644
--- a/bootstrap/lib/kernel/include/inet.hrl
+++ b/bootstrap/lib/kernel/include/inet.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/kernel/include/inet_sctp.hrl b/bootstrap/lib/kernel/include/inet_sctp.hrl
index 169ba013aa..d6376e452e 100644
--- a/bootstrap/lib/kernel/include/inet_sctp.hrl
+++ b/bootstrap/lib/kernel/include/inet_sctp.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/kernel/include/net_address.hrl b/bootstrap/lib/kernel/include/net_address.hrl
index 9b9ea42931..9dd4b78cd4 100644
--- a/bootstrap/lib/kernel/include/net_address.hrl
+++ b/bootstrap/lib/kernel/include/net_address.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/stdlib/ebin/array.beam b/bootstrap/lib/stdlib/ebin/array.beam
index 76cb41da49..4ad9c7cd04 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/beam_lib.beam b/bootstrap/lib/stdlib/ebin/beam_lib.beam
index b22233171b..4d2303a8a5 100644
--- a/bootstrap/lib/stdlib/ebin/beam_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/beam_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/binary.beam b/bootstrap/lib/stdlib/ebin/binary.beam
index 14d6ba7976..666544c492 100644
--- a/bootstrap/lib/stdlib/ebin/binary.beam
+++ b/bootstrap/lib/stdlib/ebin/binary.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index b184c21d94..0e07dc1531 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 19e0443dd2..383d66e1a8 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 46adf4ee3a..916557d6ad 100644
--- a/bootstrap/lib/stdlib/ebin/dets.beam
+++ b/bootstrap/lib/stdlib/ebin/dets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_server.beam b/bootstrap/lib/stdlib/ebin/dets_server.beam
index 7ce673e23c..46c6769dfe 100644
--- a/bootstrap/lib/stdlib/ebin/dets_server.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_server.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam
index cb4da358d6..bcb506710b 100644
--- a/bootstrap/lib/stdlib/ebin/dets_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v8.beam b/bootstrap/lib/stdlib/ebin/dets_v8.beam
index eac0a308b7..30784ed4a6 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v8.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v8.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam
index c85adabcae..cda91beaaf 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v9.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dict.beam b/bootstrap/lib/stdlib/ebin/dict.beam
index e39c79bd5a..9ba2a9b62a 100644
--- a/bootstrap/lib/stdlib/ebin/dict.beam
+++ b/bootstrap/lib/stdlib/ebin/dict.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph.beam b/bootstrap/lib/stdlib/ebin/digraph.beam
index 40db38c992..01933d662b 100644
--- a/bootstrap/lib/stdlib/ebin/digraph.beam
+++ b/bootstrap/lib/stdlib/ebin/digraph.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph_utils.beam b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
index 64783f4e1d..458c6d2895 100644
--- a/bootstrap/lib/stdlib/ebin/digraph_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/edlin.beam b/bootstrap/lib/stdlib/ebin/edlin.beam
index f006e86851..51d61d7a0b 100644
--- a/bootstrap/lib/stdlib/ebin/edlin.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/edlin_expand.beam b/bootstrap/lib/stdlib/ebin/edlin_expand.beam
index e182f67bd8..3d9846bdcf 100644
--- a/bootstrap/lib/stdlib/ebin/edlin_expand.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin_expand.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 83469557cd..00cf6f2a5c 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
new file mode 100644
index 0000000000..4807dac5f9
--- /dev/null
+++ 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 95454c885a..6b8c0cd4c9 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 b2104b1d3f..db2d0e6b85 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 b851ca484e..d3e41be66b 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 8ae35899d0..744f2cdb36 100644
--- a/bootstrap/lib/stdlib/ebin/erl_lint.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam
index 4c27146a81..4b0e853390 100644
--- a/bootstrap/lib/stdlib/ebin/erl_parse.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam
index 4549b309ca..d40913093a 100644
--- a/bootstrap/lib/stdlib/ebin/erl_pp.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_pp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam
index b2b97bda8a..c29200f2e0 100644
--- a/bootstrap/lib/stdlib/ebin/erl_scan.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_tar.beam b/bootstrap/lib/stdlib/ebin/erl_tar.beam
index 24c65996b3..e525b3738b 100644
--- a/bootstrap/lib/stdlib/ebin/erl_tar.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_tar.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
index 673ee6e8b2..0b98a9ceed 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 87d58cf378..565904b903 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 401b41a2f5..e923cecea8 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 8d024aaa99..9ac333dbee 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 b5844d5ddb..24dbd901e5 100644
--- a/bootstrap/lib/stdlib/ebin/file_sorter.beam
+++ b/bootstrap/lib/stdlib/ebin/file_sorter.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam
index ab3600c2f2..5941f9189f 100644
--- a/bootstrap/lib/stdlib/ebin/filelib.beam
+++ b/bootstrap/lib/stdlib/ebin/filelib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam
index 4c64d477aa..e4b462f5ff 100644
--- a/bootstrap/lib/stdlib/ebin/filename.beam
+++ b/bootstrap/lib/stdlib/ebin/filename.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gb_sets.beam b/bootstrap/lib/stdlib/ebin/gb_sets.beam
index feadc1d1ed..71da2376ba 100644
--- a/bootstrap/lib/stdlib/ebin/gb_sets.beam
+++ b/bootstrap/lib/stdlib/ebin/gb_sets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gb_trees.beam b/bootstrap/lib/stdlib/ebin/gb_trees.beam
index 879b8cdf76..db59d5af19 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 6f15e461f6..ccaabd8087 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 e7aaf99eb0..d22f9ec402 100644
--- a/bootstrap/lib/stdlib/ebin/gen_event.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_event.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_fsm.beam b/bootstrap/lib/stdlib/ebin/gen_fsm.beam
index 1eee773838..119c20e1d7 100644
--- a/bootstrap/lib/stdlib/ebin/gen_fsm.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_fsm.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam
index 833287bbe2..d6e5d223fb 100644
--- a/bootstrap/lib/stdlib/ebin/gen_server.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_server.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib.beam b/bootstrap/lib/stdlib/ebin/io_lib.beam
index ad77021190..c95a88c0f0 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_format.beam b/bootstrap/lib/stdlib/ebin/io_lib_format.beam
index fcfce54d0e..032e15eeb1 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_format.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_format.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_fread.beam b/bootstrap/lib/stdlib/ebin/io_lib_fread.beam
index 8c45cf484c..b4af88d5b5 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 9504baab1b..eed02e5fa5 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lib.beam b/bootstrap/lib/stdlib/ebin/lib.beam
index c9086e1796..1cc92d1b8d 100644
--- a/bootstrap/lib/stdlib/ebin/lib.beam
+++ b/bootstrap/lib/stdlib/ebin/lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lists.beam b/bootstrap/lib/stdlib/ebin/lists.beam
index 96eb8f3a86..b2dabc7d22 100644
--- a/bootstrap/lib/stdlib/ebin/lists.beam
+++ b/bootstrap/lib/stdlib/ebin/lists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/maps.beam b/bootstrap/lib/stdlib/ebin/maps.beam
index 8473da95d7..02e46c38be 100644
--- a/bootstrap/lib/stdlib/ebin/maps.beam
+++ b/bootstrap/lib/stdlib/ebin/maps.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/math.beam b/bootstrap/lib/stdlib/ebin/math.beam
index c2e8dfb874..b4596ee515 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 55eec2691c..cc8503fdb3 100644
--- a/bootstrap/lib/stdlib/ebin/ms_transform.beam
+++ b/bootstrap/lib/stdlib/ebin/ms_transform.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/orddict.beam b/bootstrap/lib/stdlib/ebin/orddict.beam
index 5fea6d0622..665941a17c 100644
--- a/bootstrap/lib/stdlib/ebin/orddict.beam
+++ b/bootstrap/lib/stdlib/ebin/orddict.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam
index 7c2d60d845..7ceb6e46fb 100644
--- a/bootstrap/lib/stdlib/ebin/otp_internal.beam
+++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/pg.beam b/bootstrap/lib/stdlib/ebin/pg.beam
deleted file mode 100644
index 31f30461d8..0000000000
--- a/bootstrap/lib/stdlib/ebin/pg.beam
+++ /dev/null
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/proc_lib.beam b/bootstrap/lib/stdlib/ebin/proc_lib.beam
index 368d3e39a0..0f732c8cae 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/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam
index ec3f0d174e..d9bdf2b93c 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 6184f0c295..90bc537b85 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 b7eab3f8d1..4365c5518d 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
new file mode 100644
index 0000000000..0f3ffb7542
--- /dev/null
+++ b/bootstrap/lib/stdlib/ebin/rand.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/random.beam b/bootstrap/lib/stdlib/ebin/random.beam
index 4a95240dfe..f576b310df 100644
--- a/bootstrap/lib/stdlib/ebin/random.beam
+++ b/bootstrap/lib/stdlib/ebin/random.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/re.beam b/bootstrap/lib/stdlib/ebin/re.beam
index 74b369bb0c..875c4a5513 100644
--- a/bootstrap/lib/stdlib/ebin/re.beam
+++ b/bootstrap/lib/stdlib/ebin/re.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index 8c4734f208..9ad6d68ebd 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 fa64e33080..f295c9f116 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 90d82c23c0..c7862afc2f 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 e92798b83d..7287cbd451 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -2,24 +2,25 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
{application, stdlib,
[{description, "ERTS CXC 138 10"},
- {vsn, "2.3"},
+ {vsn, "2.7"},
{modules, [array,
base64,
beam_lib,
@@ -39,6 +40,7 @@
edlin_expand,
epp,
eval_bits,
+ erl_anno,
erl_bits,
erl_compile,
erl_eval,
@@ -77,13 +79,13 @@
orddict,
ordsets,
otp_internal,
- pg,
pool,
proc_lib,
proplists,
qlc,
qlc_pt,
queue,
+ rand,
random,
re,
sets,
@@ -103,7 +105,7 @@
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-2.4","kernel-3.0.2","erts-6.2","crypto-3.3",
+ {runtime_dependencies, ["sasl-2.6","kernel-4.1","erts-7.3","crypto-3.3",
"compiler-5.0"]}
]}.
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.appup b/bootstrap/lib/stdlib/ebin/stdlib.appup
index fb2e12f03c..e545adc484 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.appup
+++ b/bootstrap/lib/stdlib/ebin/stdlib.appup
@@ -1,27 +1,26 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
-{"2.3",
+{"2.7",
%% Up from - max one major revision back
- [{<<"2\\.[1-2](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3
- {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0
- {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
+ [{<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}], % 17.0-17.5
%% Down to - max one major revision back
- [{<<"2\\.[1-2](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3
- {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0
- {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
+ [{<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}] % 17.0-17.5
}.
diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam
index 79e579f0aa..e8ad12aa2d 100644
--- a/bootstrap/lib/stdlib/ebin/string.beam
+++ b/bootstrap/lib/stdlib/ebin/string.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam
index 40d9b28a18..65790d73dc 100644
--- a/bootstrap/lib/stdlib/ebin/supervisor.beam
+++ b/bootstrap/lib/stdlib/ebin/supervisor.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam
index 54d7385738..4af6cc8f40 100644
--- a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam
+++ b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index 1413b822f2..a569f8003f 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 106d75c18a..9887f37c70 100644
--- a/bootstrap/lib/stdlib/ebin/timer.beam
+++ b/bootstrap/lib/stdlib/ebin/timer.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/unicode.beam b/bootstrap/lib/stdlib/ebin/unicode.beam
index 76342ef108..dc8fdcaf86 100644
--- a/bootstrap/lib/stdlib/ebin/unicode.beam
+++ b/bootstrap/lib/stdlib/ebin/unicode.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/win32reg.beam b/bootstrap/lib/stdlib/ebin/win32reg.beam
index 5d023ecb93..b37ead63ba 100644
--- a/bootstrap/lib/stdlib/ebin/win32reg.beam
+++ b/bootstrap/lib/stdlib/ebin/win32reg.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam
index 465a8b95a7..200b0f705c 100644
--- a/bootstrap/lib/stdlib/ebin/zip.beam
+++ b/bootstrap/lib/stdlib/ebin/zip.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/include/assert.hrl b/bootstrap/lib/stdlib/include/assert.hrl
new file mode 100644
index 0000000000..f913760102
--- /dev/null
+++ b/bootstrap/lib/stdlib/include/assert.hrl
@@ -0,0 +1,261 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright (C) 2004-2014 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
+%%
+%% 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(ASSERT_HRL).
+-define(ASSERT_HRL, true).
+
+%% Asserts are enabled unless NOASSERT is defined, and ASSERT can be used to
+%% override it: if both ASSERT and NOASSERT are defined, then ASSERT takes
+%% precedence, and NOASSERT will become undefined.
+%%
+%% Furthermore, if NODEBUG is defined, it implies NOASSERT, unless DEBUG or
+%% ASSERT are defined.
+%%
+%% If asserts are disabled, all assert macros are defined to be the atom
+%% 'ok'. If asserts are enabled, all assert macros are defined to yield 'ok'
+%% as the result if the test succeeds, and raise an error exception if the
+%% test fails. The error term will then have the form {Name, Info} where
+%% Name is the name of the macro and Info is a list of tagged tuples.
+
+%% allow NODEBUG to imply NOASSERT, unless DEBUG
+-ifdef(NODEBUG).
+-ifndef(DEBUG).
+-ifndef(NOASSERT).
+-define(NOASSERT, true).
+-endif.
+-endif.
+-endif.
+
+%% allow ASSERT to override NOASSERT
+-ifdef(ASSERT).
+-undef(NOASSERT).
+-endif.
+
+%% Assert macros must not depend on any non-kernel or stdlib libraries.
+%%
+%% We must use fun-call wrappers ((fun () -> ... end)()) to avoid
+%% exporting local variables, and furthermore we only use variable names
+%% prefixed with "__", that hopefully will not be bound outside the fun.
+%% It is not possible to nest assert macros.
+
+-ifdef(NOASSERT).
+-define(assert(BoolExpr),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.
+-define(assert(BoolExpr),
+ begin
+ ((fun () ->
+ case (BoolExpr) of
+ true -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??BoolExpr)},
+ {expected, true},
+ case __V of false -> {value, __V};
+ _ -> {not_boolean,__V}
+ end]})
+ end
+ end)())
+ end).
+-endif.
+
+%% This is the inverse case of assert, for convenience.
+-ifdef(NOASSERT).
+-define(assertNot(BoolExpr),ok).
+-else.
+-define(assertNot(BoolExpr),
+ begin
+ ((fun () ->
+ case (BoolExpr) of
+ false -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??BoolExpr)},
+ {expected, false},
+ case __V of true -> {value, __V};
+ _ -> {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).
+-else.
+-define(assertMatch(Guard, Expr),
+ begin
+ ((fun () ->
+ case (Expr) of
+ Guard -> ok;
+ __V -> erlang:error({assertMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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).
+-else.
+-define(assertNotMatch(Guard, Expr),
+ begin
+ ((fun () ->
+ __V = (Expr),
+ case __V of
+ Guard -> erlang:error({assertNotMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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).
+-else.
+-define(assertEqual(Expect, Expr),
+ begin
+ ((fun (__X) ->
+ case (Expr) of
+ __X -> ok;
+ __V -> erlang:error({assertEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {expected, __X},
+ {value, __V}]})
+ end
+ end)(Expect))
+ end).
+-endif.
+
+%% This is the inverse case of assertEqual, for convenience.
+-ifdef(NOASSERT).
+-define(assertNotEqual(Unexpected, Expr), ok).
+-else.
+-define(assertNotEqual(Unexpected, Expr),
+ begin
+ ((fun (__X) ->
+ case (Expr) of
+ __X -> erlang:error({assertNotEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {value, __X}]});
+ _ -> ok
+ end
+ end)(Unexpected))
+ 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).
+-else.
+-define(assertException(Class, Term, Expr),
+ begin
+ ((fun () ->
+ try (Expr) of
+ __V -> erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_success, __V}]})
+ catch
+ Class:Term -> ok;
+ __C:__T ->
+ erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
+-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
+
+%% 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).
+-else.
+-define(assertNotException(Class, Term, Expr),
+ begin
+ ((fun () ->
+ try (Expr) of
+ _ -> ok
+ catch
+ __C:__T ->
+ case __C of
+ Class ->
+ case __T of
+ Term ->
+ erlang:error({assertNotException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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/bootstrap/lib/stdlib/include/erl_bits.hrl b/bootstrap/lib/stdlib/include/erl_bits.hrl
index 54ebe58585..8405a55d55 100644
--- a/bootstrap/lib/stdlib/include/erl_bits.hrl
+++ b/bootstrap/lib/stdlib/include/erl_bits.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/stdlib/include/erl_compile.hrl b/bootstrap/lib/stdlib/include/erl_compile.hrl
index f779c4382c..c5fb491308 100644
--- a/bootstrap/lib/stdlib/include/erl_compile.hrl
+++ b/bootstrap/lib/stdlib/include/erl_compile.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/stdlib/include/ms_transform.hrl b/bootstrap/lib/stdlib/include/ms_transform.hrl
index 9937d48fef..f8a2d35394 100644
--- a/bootstrap/lib/stdlib/include/ms_transform.hrl
+++ b/bootstrap/lib/stdlib/include/ms_transform.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/stdlib/include/qlc.hrl b/bootstrap/lib/stdlib/include/qlc.hrl
index 067fb83060..e3513314a0 100644
--- a/bootstrap/lib/stdlib/include/qlc.hrl
+++ b/bootstrap/lib/stdlib/include/qlc.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/bootstrap/lib/stdlib/include/zip.hrl b/bootstrap/lib/stdlib/include/zip.hrl
index 6e3ed9c78a..5f5abf9df3 100644
--- a/bootstrap/lib/stdlib/include/zip.hrl
+++ b/bootstrap/lib/stdlib/include/zip.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/configure.in b/configure.in
index 0e09af4eff..40498f2ff9 100644
--- a/configure.in
+++ b/configure.in
@@ -4,16 +4,17 @@ dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 1998-2014. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
@@ -270,7 +271,7 @@ AC_ARG_WITH(ssl-rpath,
AS_HELP_STRING([--with-ssl-rpath=yes|no|PATHS],
[runtime library path for OpenSSL. Default is 'yes', which equates to a
number of standard locations. If 'no', then no runtime
- library paths wil be used. Anything else should be a
+ library paths will be used. Anything else should be a
comma separated list of paths.]))
AC_ARG_ENABLE(dynamic-ssl-lib,
diff --git a/erl-build-tool-vars.sh b/erl-build-tool-vars.sh
index f66dc2d286..714a5e2185 100644
--- a/erl-build-tool-vars.sh
+++ b/erl-build-tool-vars.sh
@@ -3,16 +3,17 @@
#
# 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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/AUTHORS b/erts/AUTHORS
index dcf92c34da..d8746f65b2 100644
--- a/erts/AUTHORS
+++ b/erts/AUTHORS
@@ -3,16 +3,17 @@
Copyright Ericsson AB 1999-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/Makefile.in b/erts/Makefile.in
index 47298cccba..feed00dad5 100644
--- a/erts/Makefile.in
+++ b/erts/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 5735cdea5c..ec9b66bf29 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1,18 +1,19 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2015. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
dnl
@@ -60,7 +61,6 @@ AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only us
dnl Cross compilation variables
AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)])
@@ -142,18 +142,18 @@ MIXED_MSYS=no
AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment)
if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([Cygwin and VC])
- MIXED_CYGWIN_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
- elif test -x /usr/bin/msysinfo; then
+ if test -x /usr/bin/msys-?.0.dll; then
CFLAGS="-O2"
MIXED_MSYS=yes
AC_MSG_RESULT([MSYS and VC])
MIXED_MSYS_VC=yes
CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC"
+ elif test -x /usr/bin/cygpath; then
+ CFLAGS="-O2"
+ MIXED_CYGWIN=yes
+ AC_MSG_RESULT([Cygwin and VC])
+ MIXED_CYGWIN_VC=yes
+ CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
else
AC_MSG_RESULT([undeterminable])
AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
@@ -559,7 +559,7 @@ dnl
AC_DEFUN(LM_SYS_MULTICAST,
[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support,
-[AC_EGREP_CPP(yes,
+[AC_EGREP_CPP(^yes$,
[#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -724,6 +724,250 @@ esac
])# AC_C_DOUBLE_MIDDLE_ENDIAN
+AC_DEFUN(ERL_MONOTONIC_CLOCK,
+[
+ if test "$3" = "yes"; then
+ default_resolution_clock_gettime_monotonic="CLOCK_HIGHRES CLOCK_BOOTTIME CLOCK_MONOTONIC"
+ low_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST"
+ high_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_PRECISE"
+ else
+ default_resolution_clock_gettime_monotonic="CLOCK_HIGHRES CLOCK_UPTIME CLOCK_MONOTONIC"
+ low_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_COARSE CLOCK_UPTIME_FAST"
+ high_resolution_clock_gettime_monotonic="CLOCK_UPTIME_PRECISE"
+ fi
+
+ case "$1" in
+ high_resolution)
+ check_msg="high resolution "
+ prefer_resolution_clock_gettime_monotonic="$high_resolution_clock_gettime_monotonic"
+ ;;
+ low_resolution)
+ check_msg="low resolution "
+ prefer_resolution_clock_gettime_monotonic="$low_resolution_clock_gettime_monotonic"
+ ;;
+ custom_resolution)
+ check_msg="custom resolution "
+ prefer_resolution_clock_gettime_monotonic="$2"
+ ;;
+ *)
+ check_msg="custom "
+ prefer_resolution_clock_gettime_monotonic="$2"
+ ;;
+ esac
+
+ AC_CACHE_CHECK([for clock_gettime(CLOCK_MONOTONIC_RAW, _)], erl_cv_clock_gettime_monotonic_raw,
+ [
+ AC_TRY_COMPILE([
+#include <time.h>
+ ],
+ [
+ struct timespec ts;
+ long long result;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+ result = ((long long) ts.tv_sec) * 1000000000LL +
+ ((long long) ts.tv_nsec);
+ ],
+ erl_cv_clock_gettime_monotonic_raw=yes,
+ erl_cv_clock_gettime_monotonic_raw=no)
+ ])
+
+ AC_CACHE_CHECK([for clock_gettime() with ${check_msg}monotonic clock type], erl_cv_clock_gettime_monotonic_$1,
+ [
+ for clock_type in $prefer_resolution_clock_gettime_monotonic $default_resolution_clock_gettime_monotonic $high_resolution_clock_gettime_monotonic $low_resolution_clock_gettime_monotonic; do
+ AC_TRY_COMPILE([
+#include <time.h>
+ ],
+ [
+ struct timespec ts;
+ long long result;
+ clock_gettime($clock_type,&ts);
+ result = ((long long) ts.tv_sec) * 1000000000LL +
+ ((long long) ts.tv_nsec);
+ ],
+ erl_cv_clock_gettime_monotonic_$1=$clock_type,
+ erl_cv_clock_gettime_monotonic_$1=no)
+ test $erl_cv_clock_gettime_monotonic_$1 = no || break
+ done
+ ])
+
+ AC_CHECK_FUNCS([clock_getres clock_get_attributes gethrtime])
+
+ AC_CACHE_CHECK([for mach clock_get_time() with monotonic clock type], erl_cv_mach_clock_get_time_monotonic,
+ [
+ AC_TRY_COMPILE([
+#include <mach/clock.h>
+#include <mach/mach.h>
+ ],
+ [
+ kern_return_t res;
+ clock_serv_t clk_srv;
+ mach_timespec_t time_spec;
+
+ host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clk_srv);
+ res = clock_get_time(clk_srv, &time_spec);
+ mach_port_deallocate(mach_task_self(), clk_srv);
+ ],
+ erl_cv_mach_clock_get_time_monotonic=yes,
+ erl_cv_mach_clock_get_time_monotonic=no)
+ ])
+
+ erl_corrected_monotonic_clock=no
+ case $erl_cv_clock_gettime_monotonic_$1-$ac_cv_func_gethrtime-$erl_cv_mach_clock_get_time_monotonic-$host_os in
+ *-*-*-win32)
+ erl_monotonic_clock_func=WindowsAPI
+ ;;
+ CLOCK_*-*-*-linux*)
+ case $erl_cv_clock_gettime_monotonic_$1-$erl_cv_clock_gettime_monotonic_raw in
+ CLOCK_BOOTTIME-yes|CLOCK_MONOTONIC-yes)
+ erl_corrected_monotonic_clock=yes
+ ;;
+ *)
+ # We don't trust CLOCK_MONOTONIC to be NTP
+ # adjusted on linux systems that do not have
+ # CLOCK_MONOTONIC_RAW (although it seems to
+ # be...)
+ ;;
+ esac
+ erl_monotonic_clock_func=clock_gettime
+ ;;
+ no-no-no-linux*)
+ erl_monotonic_clock_func=times
+ ;;
+ CLOCK_*-*-*-*)
+ erl_monotonic_clock_func=clock_gettime
+ ;;
+ no-yes-*-*)
+ erl_monotonic_clock_func=gethrtime
+ ;;
+ no-no-yes-*)
+ erl_monotonic_clock_func=mach_clock_get_time
+ ;;
+ no-no-no-*)
+ erl_monotonic_clock_func=none
+ ;;
+ esac
+
+ erl_monotonic_clock_low_resolution=no
+ erl_monotonic_clock_lib=
+ erl_monotonic_clock_id=
+ case $erl_monotonic_clock_func in
+ clock_gettime)
+ erl_monotonic_clock_id=$erl_cv_clock_gettime_monotonic_$1
+ for low_res_id in $low_resolution_clock_gettime_monotonic; do
+ if test $erl_monotonic_clock_id = $low_res_id; then
+ erl_monotonic_clock_low_resolution=yes
+ break
+ fi
+ done
+ AC_CHECK_LIB(rt, clock_gettime, [erl_monotonic_clock_lib="-lrt"])
+ ;;
+ mach_clock_get_time)
+ erl_monotonic_clock_id=SYSTEM_CLOCK
+ ;;
+ times)
+ erl_monotonic_clock_low_resolution=yes
+ ;;
+ *)
+ ;;
+ esac
+
+])
+
+AC_DEFUN(ERL_WALL_CLOCK,
+[
+ default_resolution_clock_gettime_wall="CLOCK_REALTIME"
+ low_resolution_clock_gettime_wall="CLOCK_REALTIME_COARSE CLOCK_REALTIME_FAST"
+ high_resolution_clock_gettime_wall="CLOCK_REALTIME_PRECISE"
+
+ case "$1" in
+ high_resolution)
+ check_msg="high resolution "
+ prefer_resolution_clock_gettime_wall="$high_resolution_clock_gettime_wall"
+ ;;
+ low_resolution)
+ check_msg="low resolution "
+ prefer_resolution_clock_gettime_wall="$low_resolution_clock_gettime_wall"
+ ;;
+ custom_resolution)
+ check_msg="custom resolution "
+ prefer_resolution_clock_gettime_wall="$2"
+ ;;
+ *)
+ check_msg=""
+ prefer_resolution_clock_gettime_wall=
+ ;;
+ esac
+
+ AC_CACHE_CHECK([for clock_gettime() with ${check_msg}wall clock type], erl_cv_clock_gettime_wall_$1,
+ [
+ for clock_type in $prefer_resolution_clock_gettime_wall $default_resolution_clock_gettime_wall $high_resolution_clock_gettime_wall $low_resolution_clock_gettime_wall; do
+ AC_TRY_COMPILE([
+#include <time.h>
+ ],
+ [
+ struct timespec ts;
+ long long result;
+ clock_gettime($clock_type,&ts);
+ result = ((long long) ts.tv_sec) * 1000000000LL +
+ ((long long) ts.tv_nsec);
+ ],
+ erl_cv_clock_gettime_wall_$1=$clock_type,
+ erl_cv_clock_gettime_wall_$1=no)
+ test $erl_cv_clock_gettime_wall_$1 = no || break
+ done
+ ])
+
+ AC_CHECK_FUNCS([clock_getres clock_get_attributes gettimeofday])
+
+ AC_CACHE_CHECK([for mach clock_get_time() with wall clock type], erl_cv_mach_clock_get_time_wall,
+ [
+ AC_TRY_COMPILE([
+#include <mach/clock.h>
+#include <mach/mach.h>
+ ],
+ [
+ kern_return_t res;
+ clock_serv_t clk_srv;
+ mach_timespec_t time_spec;
+
+ host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &clk_srv);
+ res = clock_get_time(clk_srv, &time_spec);
+ mach_port_deallocate(mach_task_self(), clk_srv);
+ ],
+ erl_cv_mach_clock_get_time_wall=yes,
+ erl_cv_mach_clock_get_time_wall=no)
+ ])
+
+ erl_wall_clock_low_resolution=no
+ erl_wall_clock_id=
+ case $1-$erl_cv_clock_gettime_wall_$1-$erl_cv_mach_clock_get_time_wall-$ac_cv_func_gettimeofday-$host_os in
+ *-*-*-*-win32)
+ erl_wall_clock_func=WindowsAPI
+ erl_wall_clock_low_resolution=yes
+ ;;
+ high_resolution-no-yes-*-*)
+ erl_wall_clock_func=mach_clock_get_time
+ erl_wall_clock_id=CALENDAR_CLOCK
+ ;;
+ *-CLOCK_*-*-*-*)
+ erl_wall_clock_func=clock_gettime
+ erl_wall_clock_id=$erl_cv_clock_gettime_wall_$1
+ for low_res_id in $low_resolution_clock_gettime_wall; do
+ if test $erl_wall_clock_id = $low_res_id; then
+ erl_wall_clock_low_resolution=yes
+ break
+ fi
+ done
+ ;;
+ *-no-*-yes-*)
+ erl_wall_clock_func=gettimeofday
+ ;;
+ *)
+ erl_wall_clock_func=none
+ ;;
+ esac
+])
+
dnl ----------------------------------------------------------------------
dnl
dnl LM_CHECK_THR_LIB
@@ -908,24 +1152,226 @@ AC_SUBST(ERTS_INTERNAL_X_LIBS)
])
-AC_DEFUN(ETHR_CHK_SYNC_OP,
+AC_DEFUN(ETHR_CHK_GCC_ATOMIC_OP__,
[
- AC_MSG_CHECKING([for $3-bit $1()])
- case "$2" in
- "1") sync_call="$1(&var);";;
- "2") sync_call="$1(&var, ($4) 0);";;
- "3") sync_call="$1(&var, ($4) 0, ($4) 0);";;
+ # $1 - atomic_op
+
+ for atomic_bit_size in 32 64 128; do
+ case $atomic_bit_size in
+ 32) gcc_atomic_type="$gcc_atomic_type32";;
+ 64) gcc_atomic_type="$gcc_atomic_type64";;
+ 128) gcc_atomic_type="$gcc_atomic_type128";;
+ esac
+ gcc_atomic_lockfree="int x[[(2*__atomic_always_lock_free(sizeof($gcc_atomic_type), 0))-1]]"
+ case $1 in
+ __sync_add_and_fetch | __sync_fetch_and_and | __sync_fetch_and_or)
+ atomic_call="volatile $gcc_atomic_type var; $gcc_atomic_type res = $1(&var, ($gcc_atomic_type) 0);"
+ ;;
+ __sync_val_compare_and_swap)
+ atomic_call="volatile $gcc_atomic_type var; $gcc_atomic_type res = $1(&var, ($gcc_atomic_type) 0, ($gcc_atomic_type) 0);"
+ ;;
+ __atomic_store_n)
+ atomic_call="$gcc_atomic_lockfree; volatile $gcc_atomic_type var; $1(&var, ($gcc_atomic_type) 0, __ATOMIC_RELAXED); $1(&var, ($gcc_atomic_type) 0, __ATOMIC_RELEASE);"
+ ;;
+ __atomic_load_n)
+ atomic_call="$gcc_atomic_lockfree; volatile $gcc_atomic_type var; $gcc_atomic_type res = $1(&var, __ATOMIC_RELAXED); res = $1(&var, __ATOMIC_ACQUIRE);"
+ ;;
+ __atomic_add_fetch| __atomic_fetch_and | __atomic_fetch_or)
+ atomic_call="$gcc_atomic_lockfree; volatile $gcc_atomic_type var; $gcc_atomic_type res = $1(&var, ($gcc_atomic_type) 0, __ATOMIC_RELAXED); res = $1(&var, ($gcc_atomic_type) 0, __ATOMIC_ACQUIRE); res = $1(&var, ($gcc_atomic_type) 0, __ATOMIC_RELEASE);"
+ ;;
+ __atomic_compare_exchange_n)
+ atomic_call="$gcc_atomic_lockfree; volatile $gcc_atomic_type var; $gcc_atomic_type val; int res = $1(&var, &val, ($gcc_atomic_type) 0, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); res = $1(&var, &val, ($gcc_atomic_type) 0, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);"
+ ;;
+ *)
+ AC_MSG_ERROR([Internal error: missing implementation for $1])
+ ;;
+ esac
+ eval atomic${atomic_bit_size}_call=\"$atomic_call\"
+ done
+
+ AC_CACHE_CHECK([for 32-bit $1()], ethr_cv_32bit_$1,
+ [
+ ethr_cv_32bit_$1=no
+ AC_TRY_LINK([], [$atomic32_call], [ethr_cv_32bit_$1=yes])
+ ])
+ AC_CACHE_CHECK([for 64-bit $1()], ethr_cv_64bit_$1,
+ [
+ ethr_cv_64bit_$1=no
+ AC_TRY_LINK([], [$atomic64_call], [ethr_cv_64bit_$1=yes])
+ ])
+ AC_CACHE_CHECK([for 128-bit $1()], ethr_cv_128bit_$1,
+ [
+ ethr_cv_128bit_$1=no
+ AC_TRY_LINK([], [$atomic128_call], [ethr_cv_128bit_$1=yes])
+ ])
+
+ case $ethr_cv_128bit_$1-$ethr_cv_64bit_$1-$ethr_cv_32bit_$1 in
+ no-no-no)
+ have_atomic_ops=0;;
+ no-no-yes)
+ have_atomic_ops=4;;
+ no-yes-no)
+ have_atomic_ops=8;;
+ no-yes-yes)
+ have_atomic_ops=12;;
+ yes-no-no)
+ have_atomic_ops=16;;
+ yes-no-yes)
+ have_atomic_ops=20;;
+ yes-yes-no)
+ have_atomic_ops=24;;
+ yes-yes-yes)
+ have_atomic_ops=28;;
+ esac
+ AC_DEFINE_UNQUOTED([ETHR_HAVE_$1], [$have_atomic_ops], [Define as a bitmask corresponding to the word sizes that $1() can handle on your system])
+])
+
+AC_DEFUN(ETHR_CHK_IF_NOOP,
+[
+ ethr_test_filename="chk_if_$1$3_noop_config1test.$$"
+ cat > "${ethr_test_filename}.c" <<EOF
+int
+my_test(void)
+{
+ $1$2;
+ return 0;
+}
+EOF
+ $CC -O3 $ETHR_DEFS -c "${ethr_test_filename}.c" -o "${ethr_test_filename}1.o"
+ cat > "${ethr_test_filename}.c" <<EOF
+int
+my_test(void)
+{
+ ;
+ return 0;
+}
+EOF
+ $CC -O3 $ETHR_DEFS -c "${ethr_test_filename}.c" -o "${ethr_test_filename}2.o"
+ if diff "${ethr_test_filename}1.o" "${ethr_test_filename}2.o" >/dev/null 2>&1; then
+ ethr_$1$3_noop=yes
+ else
+ ethr_$1$3_noop=no
+ fi
+ rm -f "${ethr_test_filename}.c" "${ethr_test_filename}1.o" "${ethr_test_filename}2.o"
+])
+
+AC_DEFUN(ETHR_CHK_GCC_ATOMIC_OPS,
+[
+ AC_CHECK_SIZEOF(short)
+ AC_CHECK_SIZEOF(int)
+ AC_CHECK_SIZEOF(long)
+ AC_CHECK_SIZEOF(long long)
+ AC_CHECK_SIZEOF(__int128_t)
+
+ if test "$ac_cv_sizeof_short" = "4"; then
+ gcc_atomic_type32="short"
+ elif test "$ac_cv_sizeof_int" = "4"; then
+ gcc_atomic_type32="int"
+ elif test "$ac_cv_sizeof_long" = "4"; then
+ gcc_atomic_type32="long"
+ else
+ AC_MSG_ERROR([No 32-bit type found])
+ fi
+
+ if test "$ac_cv_sizeof_int" = "8"; then
+ gcc_atomic_type64="int"
+ elif test "$ac_cv_sizeof_long" = "8"; then
+ gcc_atomic_type64="long"
+ elif test "$ac_cv_sizeof_long_long" = "8"; then
+ gcc_atomic_type64="long long"
+ else
+ AC_MSG_ERROR([No 64-bit type found])
+ fi
+
+ if test "$ac_cv_sizeof___int128_t" = "16"; then
+ gcc_atomic_type128="__int128_t"
+ else
+ gcc_atomic_type128="#error "
+ fi
+ AC_CACHE_CHECK([for a working __sync_synchronize()], ethr_cv___sync_synchronize,
+ [
+ ethr_cv___sync_synchronize=no
+ AC_TRY_LINK([],
+ [ __sync_synchronize(); ],
+ [ethr_cv___sync_synchronize=yes])
+ if test $ethr_cv___sync_synchronize = yes; then
+ #
+ # Old gcc versions on at least x86 have a buggy
+ # __sync_synchronize() which does not emit a
+ # memory barrier. We try to detect this by
+ # compiling to assembly with and without
+ # __sync_synchronize() and compare the results.
+ #
+ ETHR_CHK_IF_NOOP(__sync_synchronize, [()], [])
+ if test $ethr___sync_synchronize_noop = yes; then
+ # Got a buggy implementation of
+ # __sync_synchronize...
+ ethr_cv___sync_synchronize="no; buggy implementation"
+ fi
+ fi
+ ])
+
+ if test "$ethr_cv___sync_synchronize" = "yes"; then
+ have_sync_synchronize_value="~0"
+ else
+ have_sync_synchronize_value="0"
+ fi
+ AC_DEFINE_UNQUOTED([ETHR_HAVE___sync_synchronize], [$have_sync_synchronize_value], [Define as a bitmask corresponding to the word sizes that __sync_synchronize() can handle on your system])
+
+ ETHR_CHK_GCC_ATOMIC_OP__(__sync_add_and_fetch)
+ ETHR_CHK_GCC_ATOMIC_OP__(__sync_fetch_and_and)
+ ETHR_CHK_GCC_ATOMIC_OP__(__sync_fetch_and_or)
+ ETHR_CHK_GCC_ATOMIC_OP__(__sync_val_compare_and_swap)
+
+ ETHR_CHK_GCC_ATOMIC_OP__(__atomic_store_n)
+ ETHR_CHK_GCC_ATOMIC_OP__(__atomic_load_n)
+ ETHR_CHK_GCC_ATOMIC_OP__(__atomic_add_fetch)
+ ETHR_CHK_GCC_ATOMIC_OP__(__atomic_fetch_and)
+ ETHR_CHK_GCC_ATOMIC_OP__(__atomic_fetch_or)
+ ETHR_CHK_GCC_ATOMIC_OP__(__atomic_compare_exchange_n)
+
+ ethr_have_gcc_native_atomics=no
+ ethr_arm_dbm_instr_val=0
+ case "$GCC-$host_cpu" in
+ yes-arm*)
+ AC_CACHE_CHECK([for ARM DMB instruction], ethr_cv_arm_dbm_instr,
+ [
+ ethr_cv_arm_dbm_instr=no
+ AC_TRY_LINK([],
+ [
+ __asm__ __volatile__("dmb sy" : : : "memory");
+ __asm__ __volatile__("dmb st" : : : "memory");
+ ],
+ [ethr_cv_arm_dbm_instr=yes])
+ ])
+ if test $ethr_cv_arm_dbm_instr = yes; then
+ ethr_arm_dbm_instr_val=1
+ test $ethr_cv_64bit___atomic_compare_exchange_n = yes &&
+ ethr_have_gcc_native_atomics=yes
+ fi;;
+ *)
+ ;;
esac
- have_sync_op=no
- AC_TRY_LINK([],
- [
- $4 res;
- volatile $4 var;
- res = $sync_call
- ],
- [have_sync_op=yes])
- test $have_sync_op = yes && $5
- AC_MSG_RESULT([$have_sync_op])
+ AC_DEFINE_UNQUOTED([ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION], [$ethr_arm_dbm_instr_val], [Define as a boolean indicating whether you have a gcc compatible compiler capable of generating the ARM DMB instruction, and are compiling for an ARM processor with ARM DMB instruction support, or not])
+ test $ethr_cv_32bit___sync_val_compare_and_swap = yes &&
+ ethr_have_gcc_native_atomics=yes
+ test $ethr_cv_64bit___sync_val_compare_and_swap = yes &&
+ ethr_have_gcc_native_atomics=yes
+ if test "$ethr_cv___sync_synchronize" = "yes"; then
+ test $ethr_cv_64bit___atomic_compare_exchange_n = yes &&
+ ethr_have_gcc_native_atomics=yes
+ test $ethr_cv_32bit___atomic_compare_exchange_n = yes &&
+ ethr_have_gcc_native_atomics=yes
+ fi
+ ethr_have_gcc_atomic_builtins=0
+ if test $ethr_have_gcc_native_atomics = yes; then
+ ethr_native_atomic_implementation=gcc_sync
+ test $ethr_cv_32bit___atomic_compare_exchange_n = yes && ethr_have_gcc_atomic_builtins=1
+ test $ethr_cv_64bit___atomic_compare_exchange_n = yes && ethr_have_gcc_atomic_builtins=1
+ test $ethr_have_gcc_atomic_builtins = 1 && ethr_native_atomic_implementation=gcc_atomic_sync
+ fi
+ AC_DEFINE_UNQUOTED([ETHR_HAVE_GCC___ATOMIC_BUILTINS], [$ethr_have_gcc_atomic_builtins], [Define as a boolean indicating whether you have a gcc __atomic builtins or not])
+ test $ethr_have_gcc_native_atomics = yes && ethr_have_native_atomics=yes
])
AC_DEFUN(ETHR_CHK_INTERLOCKED,
@@ -1005,6 +1451,16 @@ AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
test $enable_prefer_gcc_native_ethr_impls = yes &&
AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations])
+AC_ARG_ENABLE(trust-gcc-atomic-builtins-memory-barriers,
+ AS_HELP_STRING([--enable-trust-gcc-atomic-builtins-memory-barriers],
+ [trust gcc atomic builtins memory barriers]),
+[ case "$enableval" in
+ yes) trust_gcc_atomic_builtins_mbs=1 ;;
+ *) trust_gcc_atomic_builtins_mbs=0 ;;
+ esac ], trust_gcc_atomic_builtins_mbs=0)
+
+AC_DEFINE_UNQUOTED(ETHR_TRUST_GCC_ATOMIC_BUILTINS_MEMORY_BARRIERS, [$trust_gcc_atomic_builtins_mbs], [Define as a boolean indicating whether you trust gcc's __atomic_* builtins memory barrier implementations, or not])
+
AC_ARG_WITH(libatomic_ops,
AS_HELP_STRING([--with-libatomic_ops=PATH],
[specify and prefer usage of libatomic_ops in the ethread library]))
@@ -1016,12 +1472,33 @@ AC_ARG_WITH(with_sparc_memory_order,
LM_CHECK_THR_LIB
ERL_INTERNAL_LIBS
+ERL_MONOTONIC_CLOCK(try_find_pthread_compatible, CLOCK_HIGHRES CLOCK_MONOTONIC, no)
+
+case $erl_monotonic_clock_func in
+ clock_gettime)
+ AC_DEFINE(ETHR_HAVE_CLOCK_GETTIME_MONOTONIC, [1], [Define if you have a clock_gettime() with a monotonic clock])
+ ;;
+ mach_clock_get_time)
+ AC_DEFINE(ETHR_HAVE_MACH_CLOCK_GET_TIME, [1], [Define if you have a mach clock_get_time() with a monotonic clock])
+ ;;
+ gethrtime)
+ AC_DEFINE(ETHR_HAVE_GETHRTIME, [1], [Define if you have a monotonic gethrtime()])
+ ;;
+ *)
+ ;;
+esac
+
+if test "x$erl_monotonic_clock_id" != "x"; then
+ AC_DEFINE_UNQUOTED(ETHR_MONOTONIC_CLOCK_ID, [$erl_monotonic_clock_id], [Define to the monotonic clock id to use])
+fi
+
+ethr_native_atomic_implementation=none
ethr_have_native_atomics=no
ethr_have_native_spinlock=no
ETHR_THR_LIB_BASE="$THR_LIB_NAME"
ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE"
ETHR_DEFS="$THR_DEFS"
-ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS"
+ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS $erl_monotonic_clock_lib"
ETHR_LIBS=
ETHR_LIB_NAME=
@@ -1100,7 +1577,10 @@ case "$THR_LIB_NAME" in
ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()]))
fi
- test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
+ if test "$ethr_have_native_atomics" = "yes"; then
+ ethr_native_atomic_implementation=windows
+ ethr_have_native_spinlock=yes
+ fi
;;
pthread|ose_threads)
@@ -1329,6 +1809,50 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \
[Define if you have the pthread_attr_setguardsize function.]))
+ if test "x$erl_monotonic_clock_id" != "x"; then
+ AC_MSG_CHECKING(whether pthread_cond_timedwait() can use the monotonic clock $erl_monotonic_clock_id for timeout)
+ pthread_cond_timedwait_monotonic=no
+ AC_TRY_LINK([
+ #if defined(ETHR_NEED_NPTL_PTHREAD_H)
+ # include <nptl/pthread.h>
+ #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
+ # include <pthread/mit/pthread.h>
+ #elif defined(ETHR_HAVE_PTHREAD_H)
+ # include <pthread.h>
+ #endif
+ #ifdef ETHR_TIME_WITH_SYS_TIME
+ # include <time.h>
+ # include <sys/time.h>
+ #else
+ # ifdef ETHR_HAVE_SYS_TIME_H
+ # include <sys/time.h>
+ # else
+ # include <time.h>
+ # endif
+ #endif
+ #if defined(ETHR_HAVE_MACH_CLOCK_GET_TIME)
+ # include <mach/clock.h>
+ # include <mach/mach.h>
+ #endif
+ ],
+ [
+ int res;
+ pthread_condattr_t attr;
+ pthread_cond_t cond;
+ struct timespec cond_timeout;
+ pthread_mutex_t mutex;
+ res = pthread_condattr_init(&attr);
+ res = pthread_condattr_setclock(&attr, ETHR_MONOTONIC_CLOCK_ID);
+ res = pthread_cond_init(&cond, &attr);
+ res = pthread_cond_timedwait(&cond, &mutex, &cond_timeout);
+ ],
+ [pthread_cond_timedwait_monotonic=yes])
+ AC_MSG_RESULT([$pthread_cond_timedwait_monotonic])
+ if test $pthread_cond_timedwait_monotonic = yes; then
+ AC_DEFINE(ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC, [1], [Define if pthread_cond_timedwait() can be used with a monotonic clock])
+ fi
+ fi
+
linux_futex=no
AC_MSG_CHECKING([for Linux futexes])
AC_TRY_LINK([
@@ -1349,56 +1873,62 @@ case "$THR_LIB_NAME" in
AC_MSG_RESULT([$linux_futex])
test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
- fi
-
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_CHECK_SIZEOF(long long)
- AC_CHECK_SIZEOF(__int128_t)
-
- if test "$ac_cv_sizeof_int" = "4"; then
- int32="int"
- elif test "$ac_cv_sizeof_long" = "4"; then
- int32="long"
- elif test "$ac_cv_sizeof_long_long" = "4"; then
- int32="long long"
- else
- AC_MSG_ERROR([No 32-bit type found])
- fi
+ pthread_setname=no
+ AC_MSG_CHECKING([for pthread_setname_np])
+ old_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([#define __USE_GNU
+ #include <pthread.h>],
+ [pthread_setname_np(pthread_self(), "name");],
+ pthread_setname=linux)
+ AC_TRY_LINK([#define __USE_GNU
+ #include <pthread.h>],
+ [pthread_set_name_np(pthread_self(), "name");],
+ pthread_setname=bsd)
+ AC_TRY_LINK([#define _DARWIN_C_SOURCE
+ #include <pthread.h>],
+ [pthread_setname_np("name");],
+ pthread_setname=darwin)
+ AC_MSG_RESULT([$pthread_setname])
+ case $pthread_setname in
+ linux) AC_DEFINE(ETHR_HAVE_PTHREAD_SETNAME_NP_2, 1,
+ [Define if you have linux style pthread_setname_np]);;
+ bsd) AC_DEFINE(ETHR_HAVE_PTHREAD_SET_NAME_NP_2, 1,
+ [Define if you have bsd style pthread_set_name_np]);;
+ darwin) AC_DEFINE(ETHR_HAVE_PTHREAD_SETNAME_NP_1, 1,
+ [Define if you have darwin style pthread_setname_np]);;
+ *) ;;
+ esac
- if test "$ac_cv_sizeof_int" = "8"; then
- int64="int"
- elif test "$ac_cv_sizeof_long" = "8"; then
- int64="long"
- elif test "$ac_cv_sizeof_long_long" = "8"; then
- int64="long long"
- else
- AC_MSG_ERROR([No 64-bit type found])
- fi
+ pthread_getname=no
+ AC_MSG_CHECKING([for pthread_getname_np])
+ AC_TRY_LINK([#define __USE_GNU
+ #define _DARWIN_C_SOURCE
+ #include <pthread.h>],
+ [char buff[256]; pthread_getname_np(pthread_self(), buff, 256);],
+ pthread_getname=linux)
+ AC_TRY_LINK([#define __USE_GNU
+ #define _DARWIN_C_SOURCE
+ #include <pthread.h>],
+ [char buff[256]; pthread_getname_np(pthread_self(), buff);],
+ pthread_getname=ibm)
+ AC_MSG_RESULT([$pthread_getname])
+ case $pthread_getname in
+ linux) AC_DEFINE(ETHR_HAVE_PTHREAD_GETNAME_NP_3, 1,
+ [Define if you have linux style pthread_getname_np]);;
+ ibm) AC_DEFINE(ETHR_HAVE_PTHREAD_GETNAME_NP_2, 1,
+ [Define if you have ibm style pthread_getname_np]);;
+ *) ;;
+ esac
+ CFLAGS=$old_CFLAGS
- int128=no
- if test "$ac_cv_sizeof___int128_t" = "16"; then
- int128="__int128_t"
- fi
+ fi ## test "x$THR_LIB_NAME" = "xpthread"
if test "X$disable_native_ethr_impls" = "Xyes"; then
ethr_have_native_atomics=no
else
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers]))
-
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers]))
-
- if test $int128 != no; then
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers]))
- fi
+
+ ETHR_CHK_GCC_ATOMIC_OPS([])
AC_MSG_CHECKING([for a usable libatomic_ops implementation])
case "x$with_libatomic_ops" in
@@ -1448,6 +1978,7 @@ case "$THR_LIB_NAME" in
#endif
],
[ethr_have_native_atomics=yes
+ ethr_native_atomic_implementation=libatomic_ops
ethr_have_libatomic_ops=yes])
AC_MSG_RESULT([$ethr_have_libatomic_ops])
if test $ethr_have_libatomic_ops = yes; then
@@ -1479,15 +2010,19 @@ case "$THR_LIB_NAME" in
*)
AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);;
esac
+ ethr_native_atomic_implementation=ethread
ethr_have_native_atomics=yes;;
i86pc | i*86 | x86_64 | amd64)
if test "$enable_x86_out_of_order" = "yes"; then
AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized])
fi
+ ethr_native_atomic_implementation=ethread
ethr_have_native_atomics=yes;;
macppc | ppc | powerpc | "Power Macintosh")
+ ethr_native_atomic_implementation=ethread
ethr_have_native_atomics=yes;;
tile)
+ ethr_native_atomic_implementation=ethread
ethr_have_native_atomics=yes;;
*)
;;
@@ -1582,63 +2117,159 @@ esac
case "$GCC-$host_cpu" in
yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64)
+
+ if test $ac_cv_sizeof_void_p = 4; then
+ dw_cmpxchg="cmpxchg8b"
+ else
+ dw_cmpxchg="cmpxchg16b"
+ fi
+
gcc_dw_cmpxchg_asm=no
- AC_MSG_CHECKING([for gcc double word cmpxchg asm support])
- AC_TRY_COMPILE([],
+ gcc_pic_dw_cmpxchg_asm=no
+ gcc_cflags_pic=no
+ gcc_cmpxchg8b_pic_no_clobber_ebx=no
+ gcc_cmpxchg8b_pic_no_clobber_ebx_register_shortage=no
+
+ save_CFLAGS="$CFLAGS"
+
+ # Check if it works out of the box using passed CFLAGS
+ # and with -fPIC added to CFLAGS if the passed CFLAGS
+ # doesn't trigger position independent code
+ pic_cmpxchg=unknown
+ while true; do
+
+ case $pic_cmpxchg in
+ yes) pic_text="pic ";;
+ *) pic_text="";;
+ esac
+
+ AC_MSG_CHECKING([for gcc $pic_text$dw_cmpxchg plain asm support])
+
+ plain_cmpxchg=no
+ AC_TRY_COMPILE([],
[
char xchgd;
long new[2], xchg[2], *p;
__asm__ __volatile__(
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "pushl %%ebx\n\t"
- "movl %8, %%ebx\n\t"
-#endif
#if ETHR_SIZEOF_PTR == 4
"lock; cmpxchg8b %0\n\t"
#else
"lock; cmpxchg16b %0\n\t"
#endif
"setz %3\n\t"
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "popl %%ebx\n\t"
-#endif
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]),
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "r"(new[0])
-#else
- "b"(new[0])
-#endif
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=q"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "c"(new[1]), "b"(new[0])
: "cc", "memory");
+ ],
+ [plain_cmpxchg=yes])
+
+ AC_MSG_RESULT([$plain_cmpxchg])
+ if test $pic_cmpxchg = yes; then
+ gcc_pic_dw_cmpxchg_asm=$plain_cmpxchg
+ break
+ fi
+
+ gcc_dw_cmpxchg_asm=$plain_cmpxchg
+
+ # If not already compiling to position independent
+ # code add -fPIC to CFLAGS and do it again. This
+ # since we want also want to know how to compile
+ # to position independent code since this might
+ # cause problems with the use of the EBX register
+ # as input to the asm on 32-bit x86 and old gcc
+ # compilers (gcc vsn < 5).
+
+ AC_TRY_COMPILE([],
+ [
+#if !defined(__PIC__) || !__PIC__
+# error no pic
+#endif
],
- [gcc_dw_cmpxchg_asm=yes])
- if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then
+ [pic_cmpxchg=yes
+ gcc_cflags_pic=yes],
+ [pic_cmpxchg=no])
+
+ if test $pic_cmpxchg = yes; then
+ gcc_pic_dw_cmpxchg_asm=$gcc_dw_cmpxchg_asm
+ break
+ fi
+
+ CFLAGS="$save_CFLAGS -fPIC"
+ pic_cmpxchg=yes
+
+ done
+
+ if test $gcc_pic_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then
+
+ AC_MSG_CHECKING([for gcc pic cmpxchg8b asm support with EBX workaround])
+
+ # Check if we can work around it by managing the ebx
+ # register explicitly in the asm...
+
AC_TRY_COMPILE([],
+ [
+ char xchgd;
+ long new[2], xchg[2], *p;
+ __asm__ __volatile__(
+ "pushl %%ebx\n\t"
+ "movl %8, %%ebx\n\t"
+ "lock; cmpxchg8b %0\n\t"
+ "setz %3\n\t"
+ "popl %%ebx\n\t"
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=q"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "c"(new[1]), "r"(new[0])
+ : "cc", "memory");
+ ],
+ [gcc_pic_dw_cmpxchg_asm=yes
+ gcc_cmpxchg8b_pic_no_clobber_ebx=yes])
+
+ AC_MSG_RESULT([$gcc_pic_dw_cmpxchg_asm])
+
+ if test $gcc_pic_dw_cmpxchg_asm = no; then
+
+ AC_MSG_CHECKING([for gcc pic cmpxchg8b asm support with EBX and register shortage workarounds])
+ # If no optimization is enabled we sometimes get a
+ # register shortage. Check if we can work around
+ # this...
+
+ AC_TRY_COMPILE([],
[
char xchgd;
long new[2], xchg[2], *p;
-#if !defined(__PIC__) || !__PIC__
-# error nope
-#endif
__asm__ __volatile__(
- "pushl %%ebx\n\t"
- "movl (%7), %%ebx\n\t"
- "movl 4(%7), %%ecx\n\t"
- "lock; cmpxchg8b %0\n\t"
- "setz %3\n\t"
- "popl %%ebx\n\t"
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new)
+ "pushl %%ebx\n\t"
+ "movl (%7), %%ebx\n\t"
+ "movl 4(%7), %%ecx\n\t"
+ "lock; cmpxchg8b %0\n\t"
+ "setz %3\n\t"
+ "popl %%ebx\n\t"
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "r"(new)
: "cc", "memory");
],
- [gcc_dw_cmpxchg_asm=yes])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code])
+ [gcc_pic_dw_cmpxchg_asm=yes
+ gcc_cmpxchg8b_pic_no_clobber_ebx=yes
+ gcc_cmpxchg8b_pic_no_clobber_ebx_register_shortage=yes])
+
+ AC_MSG_RESULT([$gcc_pic_dw_cmpxchg_asm])
fi
+
+ if test $gcc_cflags_pic = yes; then
+ gcc_dw_cmpxchg_asm=$gcc_pic_dw_cmpxchg_asm
+ fi
+
+ fi
+
+ CFLAGS="$save_CFLAGS"
+
+ if test "$gcc_cmpxchg8b_pic_no_clobber_ebx" = "yes"; then
+ AC_DEFINE(ETHR_CMPXCHG8B_PIC_NO_CLOBBER_EBX, 1, [Define if gcc wont let you clobber ebx with cmpxchg8b and position independent code])
+ fi
+ if test "$gcc_cmpxchg8b_pic_no_clobber_ebx_register_shortage" = "yes"; then
+ AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code])
fi
- AC_MSG_RESULT([$gcc_dw_cmpxchg_asm])
if test "$gcc_dw_cmpxchg_asm" = "yes"; then
AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction])
fi;;
@@ -1660,109 +2291,233 @@ AC_SUBST(ETHR_X86_SSE2_ASM)
])
-
dnl ----------------------------------------------------------------------
dnl
dnl ERL_TIME_CORRECTION
dnl
-dnl In the presence of a high resolution realtime timer Erlang can adapt
-dnl its view of time relative to this timer. On solaris such a timer is
-dnl available with the syscall gethrtime(). On other OS's a fallback
-dnl solution using times() is implemented. (However on e.g. FreeBSD times()
-dnl is implemented using gettimeofday so it doesn't make much sense to
-dnl use it there...) On second thought, it seems to be safer to do it the
-dnl other way around. I.e. only use times() on OS's where we know it will
-dnl work...
+dnl Check for primitives that can be used for implementing
+dnl erts_os_monotonic_time() and erts_os_system_time()
dnl
AC_DEFUN(ERL_TIME_CORRECTION,
-[if test x$ac_cv_func_gethrtime = x; then
- AC_CHECK_FUNC(gethrtime)
-fi
-if test x$clock_gettime_correction = xunknown; then
- AC_TRY_COMPILE([#include <time.h>],
- [struct timespec ts;
- long long result;
- clock_gettime(CLOCK_MONOTONIC,&ts);
- result = ((long long) ts.tv_sec) * 1000000000LL +
- ((long long) ts.tv_nsec);],
- clock_gettime_compiles=yes,
- clock_gettime_compiles=no)
-else
- clock_gettime_compiles=no
+[
+
+AC_ARG_WITH(clock-resolution,
+AS_HELP_STRING([--with-clock-resolution=high|low|default],
+ [specify wanted clock resolution]))
+
+AC_ARG_WITH(clock-gettime-realtime-id,
+AS_HELP_STRING([--with-clock-gettime-realtime-id=CLOCKID],
+ [specify clock id to use with clock_gettime() for realtime time)]))
+
+AC_ARG_WITH(clock-gettime-monotonic-id,
+AS_HELP_STRING([--with-clock-gettime-monotonic-id=CLOCKID],
+ [specify clock id to use with clock_gettime() for monotonic time)]))
+
+AC_ARG_ENABLE(prefer-elapsed-monotonic-time-during-suspend,
+AS_HELP_STRING([--enable-prefer-elapsed-monotonic-time-during-suspend],
+ [Prefer an OS monotonic time source with elapsed time during suspend])
+AS_HELP_STRING([--disable-prefer-elapsed-monotonic-time-during-suspend],
+ [Do not prefer an OS monotonic time source with elapsed time during suspend]),
+[ case "$enableval" in
+ yes) prefer_elapsed_monotonic_time_during_suspend=yes ;;
+ *) prefer_elapsed_monotonic_time_during_suspend=no ;;
+ esac ], prefer_elapsed_monotonic_time_during_suspend=no)
+
+AC_ARG_ENABLE(gettimeofday-as-os-system-time,
+ AS_HELP_STRING([--enable-gettimeofday-as-os-system-time],
+ [Force usage of gettimeofday() for OS system time]),
+[ case "$enableval" in
+ yes) force_gettimeofday_os_system_time=yes ;;
+ *) force_gettimeofday_os_system_time=no ;;
+ esac ], force_gettimeofday_os_system_time=no)
+
+case "$with_clock_resolution" in
+ ""|no|yes)
+ with_clock_resolution=default;;
+ high|low|default)
+ ;;
+ *)
+ AC_MSG_ERROR([Invalid wanted clock resolution: $with_clock_resolution])
+ ;;
+esac
+
+if test "$force_gettimeofday_os_system_time" = "yes"; then
+
+ AC_CHECK_FUNCS([gettimeofday])
+ if test "$ac_cv_func_gettimeofday" = "yes"; then
+ AC_DEFINE(OS_SYSTEM_TIME_GETTIMEOFDAY, [1], [Define if you want to implement erts_os_system_time() using gettimeofday()])
+ else
+ AC_MSG_ERROR([No gettimeofday() available])
+ fi
+
+else # $force_gettimeofday_os_system_time != yes
+
+case "$with_clock_gettime_realtime_id" in
+ ""|no)
+ with_clock_gettime_realtime_id=no
+ ;;
+ CLOCK_*CPUTIME*)
+ AC_MSG_ERROR([Invalid clock_gettime() realtime clock id: Refusing to use the cputime clock id $with_clock_gettime_realtime_id as realtime clock id])
+ ;;
+ CLOCK_MONOTONIC*|CLOCK_BOOTTIME*|CLOCK_UPTIME*|CLOCK_HIGHRES*)
+ AC_MSG_ERROR([Invalid clock_gettime() realtime clock id: Refusing to use the monotonic clock id $with_clock_gettime_realtime_id as realtime clock id])
+ ;;
+ CLOCK_*)
+ ;;
+ *)
+ AC_MSG_ERROR([Invalid clock_gettime() clock id: $with_clock_gettime_realtime_id])
+ ;;
+esac
+
+case "$with_clock_resolution-$with_clock_gettime_realtime_id" in
+ high-no)
+ ERL_WALL_CLOCK(high_resolution);;
+ low-no)
+ ERL_WALL_CLOCK(low_resolution);;
+ default-no)
+ ERL_WALL_CLOCK(default_resolution);;
+ *)
+ ERL_WALL_CLOCK(custom_resolution, $with_clock_gettime_realtime_id);;
+esac
+
+case "$erl_wall_clock_func-$erl_wall_clock_id-$with_clock_gettime_realtime_id" in
+ *-*-no)
+ ;;
+ clock_gettime-$with_clock_gettime_realtime_id-$with_clock_gettime_realtime_id)
+ ;;
+ *)
+ AC_MSG_ERROR([$with_clock_gettime_realtime_id as clock id to clock_gettime() doesn't compile])
+ ;;
+esac
+
+case $erl_wall_clock_func in
+ none)
+ AC_MSG_ERROR([No wall clock source found])
+ ;;
+ mach_clock_get_time)
+ AC_DEFINE(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME, [1], [Define if you want to implement erts_os_system_time() using mach clock_get_time()])
+ ;;
+ clock_gettime)
+ AC_DEFINE(OS_SYSTEM_TIME_USING_CLOCK_GETTIME, [1], [Define if you want to implement erts_os_system_time() using clock_gettime()])
+ ;;
+ gettimeofday)
+ AC_DEFINE(OS_SYSTEM_TIME_GETTIMEOFDAY, [1], [Define if you want to implement erts_os_system_time() using gettimeofday()])
+ ;;
+ *)
+ ;;
+esac
+
+if test "x$erl_wall_clock_id" != "x"; then
+ AC_DEFINE_UNQUOTED(WALL_CLOCK_ID_STR, ["$erl_wall_clock_id"], [Define as a string of wall clock id to use])
+ AC_DEFINE_UNQUOTED(WALL_CLOCK_ID, [$erl_wall_clock_id], [Define to wall clock id to use])
fi
-
-AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction,
-[
-case $clock_gettime_correction in
- yes)
- erl_cv_time_correction=clock_gettime;;
- no|unknown)
- case $ac_cv_func_gethrtime in
- yes)
- erl_cv_time_correction=hrtime ;;
- no)
- case $host_os in
- linux*)
- case $clock_gettime_correction in
- unknown)
- if test x$clock_gettime_compiles = xyes; then
- if test X$cross_compiling != Xyes; then
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
- erl_cv_time_correction=times ;;
- *)
- erl_cv_time_correction=clock_gettime;;
- esac
- else
- case X$erl_xcomp_linux_clock_gettime_correction in
- X)
- erl_cv_time_correction=cross;;
- Xyes|Xno)
- if test $erl_xcomp_linux_clock_gettime_correction = yes; then
- erl_cv_time_correction=clock_gettime
- else
- erl_cv_time_correction=times
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);;
- esac
- fi
- else
- erl_cv_time_correction=times
- fi
- ;;
- *)
- erl_cv_time_correction=times ;;
- esac
- ;;
- *)
- erl_cv_time_correction=none ;;
- esac
- ;;
- esac
- ;;
+fi # $force_gettimeofday_os_system_time != yes
+
+case "$with_clock_gettime_monotonic_id" in
+ ""|no)
+ with_clock_gettime_monotonic_id=no
+ ;;
+ CLOCK_*CPUTIME*)
+ AC_MSG_ERROR([Invalid clock_gettime() monotonic clock id: Refusing to use the cputime clock id $with_clock_gettime_monotonic_id as monotonic clock id])
+ ;;
+ CLOCK_REALTIME*|CLOCK_TAI*)
+ AC_MSG_ERROR([Invalid clock_gettime() monotonic clock id: Refusing to use the realtime clock id $with_clock_gettime_monotonic_id as monotonic clock id])
+ ;;
+ CLOCK_*)
+ ;;
+ *)
+ AC_MSG_ERROR([Invalid clock_gettime() clock id: $with_clock_gettime_monotonic_id])
+ ;;
+esac
+
+case "$with_clock_resolution-$with_clock_gettime_monotonic_id" in
+ high-no)
+ ERL_MONOTONIC_CLOCK(high_resolution, undefined, $prefer_elapsed_monotonic_time_during_suspend);;
+ low-no)
+ ERL_MONOTONIC_CLOCK(low_resolution, undefined, $prefer_elapsed_monotonic_time_during_suspend);;
+ default-no)
+ ERL_MONOTONIC_CLOCK(default_resolution, undefined, $prefer_elapsed_monotonic_time_during_suspend);;
+ *)
+ ERL_MONOTONIC_CLOCK(custom_resolution, $with_clock_gettime_monotonic_id, $prefer_elapsed_monotonic_time_during_suspend);;
+esac
+
+case "$erl_monotonic_clock_func-$erl_monotonic_clock_id-$with_clock_gettime_monotonic_id" in
+ *-*-no)
+ ;;
+ clock_gettime-$with_clock_gettime_monotonic_id-$with_clock_gettime_monotonic_id)
+ ;;
+ *)
+ AC_MSG_ERROR([$with_clock_gettime_monotonic_id as clock id to clock_gettime() doesn't compile])
+ ;;
esac
-])
-xrtlib=""
-case $erl_cv_time_correction in
+case $erl_monotonic_clock_func in
times)
- AC_DEFINE(CORRECT_USING_TIMES,[],
- [Define if you do not have a high-res. timer & want to use times() instead])
+ AC_DEFINE(OS_MONOTONIC_TIME_USING_TIMES, [1], [Define if you want to implement erts_os_monotonic_time() using times()])
;;
- clock_gettime|cross)
- if test $erl_cv_time_correction = cross; then
- erl_cv_time_correction=clock_gettime
- AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
- fi
- xrtlib="-lrt"
- AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
- [Define if you want to use clock_gettime to simulate gethrtime])
+ mach_clock_get_time)
+ AC_DEFINE(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME, [1], [Define if you want to implement erts_os_monotonic_time() using mach clock_get_time()])
+ ;;
+ clock_gettime)
+ AC_DEFINE(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME, [1], [Define if you want to implement erts_os_monotonic_time() using clock_gettime()])
+ ;;
+ gethrtime)
+ AC_DEFINE(OS_MONOTONIC_TIME_USING_GETHRTIME, [1], [Define if you want to implement erts_os_monotonic_time() using gethrtime()])
+ ;;
+ *)
+ ;;
+esac
+
+if test $erl_corrected_monotonic_clock = yes; then
+ AC_DEFINE(ERTS_HAVE_CORRECTED_OS_MONOTONIC_TIME, [1], [Define if OS monotonic clock is corrected])
+fi
+
+if test $erl_monotonic_clock_low_resolution = yes; then
+ AC_DEFINE(ERTS_HAVE_LOW_RESOLUTION_OS_MONOTONIC_LOW, [1], [Define if you have a low resolution OS monotonic clock])
+fi
+
+xrtlib="$erl_monotonic_clock_lib"
+if test "x$erl_monotonic_clock_id" != "x"; then
+ AC_DEFINE_UNQUOTED(MONOTONIC_CLOCK_ID_STR, ["$erl_monotonic_clock_id"], [Define as a string of monotonic clock id to use])
+ AC_DEFINE_UNQUOTED(MONOTONIC_CLOCK_ID, [$erl_monotonic_clock_id], [Define to monotonic clock id to use])
+fi
+
+if test $erl_cv_clock_gettime_monotonic_raw = yes; then
+ AC_DEFINE(HAVE_CLOCK_GETTIME_MONOTONIC_RAW, [1], [Define if you have clock_gettime(CLOCK_MONOTONIC_RAW, _)])
+fi
+
+ERL_MONOTONIC_CLOCK(high_resolution, undefined, no)
+
+case $$erl_monotonic_clock_low_resolution-$erl_monotonic_clock_func in
+ no-mach_clock_get_time)
+ monotonic_hrtime=yes
+ AC_DEFINE(SYS_HRTIME_USING_MACH_CLOCK_GET_TIME, [1], [Define if you want to implement erts_os_hrtime() using mach clock_get_time()])
+ ;;
+ no-clock_gettime)
+ monotonic_hrtime=yes
+ AC_DEFINE(SYS_HRTIME_USING_CLOCK_GETTIME, [1], [Define if you want to implement erts_os_hrtime() using clock_gettime()])
+ ;;
+ no-gethrtime)
+ monotonic_hrtime=yes
+ AC_DEFINE(SYS_HRTIME_USING_GETHRTIME, [1], [Define if you want to implement erts_os_hrtime() using gethrtime()])
+ ;;
+ *)
+ monotonic_hrtime=no
;;
esac
+
+if test $monotonic_hrtime = yes; then
+ AC_DEFINE(HAVE_MONOTONIC_ERTS_SYS_HRTIME, [1], [Define if you have a monotonic erts_os_hrtime() implementation])
+fi
+
+if test "x$erl_monotonic_clock_id" != "x"; then
+ AC_DEFINE_UNQUOTED(HRTIME_CLOCK_ID_STR, ["$erl_monotonic_clock_id"], [Define as a string of monotonic clock id to use])
+ AC_DEFINE_UNQUOTED(HRTIME_CLOCK_ID, [$erl_monotonic_clock_id], [Define to monotonic clock id to use])
+fi
+
+
dnl
dnl Check if gethrvtime is working, and if to use procfs ioctl
dnl or (yet to be written) write to the procfs ctl file.
@@ -1835,6 +2590,7 @@ case X$erl_xcomp_gethrvtime_procfs_ioctl in
esac
])
+LIBRT=$xrtlib
case $erl_gethrvtime in
procfs_ioctl)
AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
@@ -1881,43 +2637,33 @@ case $erl_gethrvtime in
exit(0); return 0;
}
],
- erl_clock_gettime=yes,
- erl_clock_gettime=no,
+ erl_clock_gettime_cpu_time=yes,
+ erl_clock_gettime_cpu_time=no,
[
case X$erl_xcomp_clock_gettime_cpu_time in
- X) erl_clock_gettime=cross;;
- Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;;
+ X) erl_clock_gettime_cpu_time=cross;;
+ Xyes|Xno) erl_clock_gettime_cpu_time=$erl_xcomp_clock_gettime_cpu_time;;
*) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);;
esac
])
LIBS=$save_libs
- case $host_os in
- linux*)
- AC_MSG_RESULT([no; not stable])
- LIBRT=$xrtlib
+ AC_MSG_RESULT($erl_clock_gettime_cpu_time)
+ case $erl_clock_gettime_cpu_time in
+ yes)
+ AC_DEFINE(HAVE_CLOCK_GETTIME_CPU_TIME,[],
+ [define if clock_gettime() works for getting process time])
+ LIBRT=-lrt
+ ;;
+ cross)
+ erl_clock_gettime_cpu_time=no
+ AC_MSG_WARN([result no guessed because of cross compilation])
;;
*)
- AC_MSG_RESULT($erl_clock_gettime)
- case $erl_clock_gettime in
- yes)
- AC_DEFINE(HAVE_CLOCK_GETTIME,[],
- [define if clock_gettime() works for getting process time])
- LIBRT=-lrt
- ;;
- cross)
- erl_clock_gettime=no
- AC_MSG_WARN([result no guessed because of cross compilation])
- LIBRT=$xrtlib
- ;;
- *)
- LIBRT=$xrtlib
- ;;
- esac
;;
esac
- AC_SUBST(LIBRT)
;;
esac
+AC_SUBST(LIBRT)
])dnl
dnl ----------------------------------------------------------------------
diff --git a/erts/autoconf/config.guess b/erts/autoconf/config.guess
index f475ceb413..f7eb141e75 100755
--- a/erts/autoconf/config.guess
+++ b/erts/autoconf/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2013-02-12'
+timestamp='2015-03-04'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2013-02-12'
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
-# Originally written by Per Bothner.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
-# Please send patches with a ChangeLog entry to [email protected].
+# Please send patches to <[email protected]>.
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -132,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
@@ -147,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@@ -176,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd
;;
esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
@@ -192,7 +227,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
+ echo "${machine}-${os}${release}${abi}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -558,8 +593,9 @@ EOF
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
@@ -805,7 +841,7 @@ EOF
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
- i*:MSYS*:*)
+ *:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
@@ -853,21 +889,21 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -880,59 +916,57 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
@@ -951,57 +985,63 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
exit ;;
- or32:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
+ echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1234,19 +1274,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1337,154 +1389,6 @@ EOF
exit ;;
esac
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
cat >&2 <<EOF
$0: unable to guess system type
diff --git a/erts/autoconf/config.sub b/erts/autoconf/config.sub
index bb6edbdb47..8f1229c6f7 100755
--- a/erts/autoconf/config.sub
+++ b/erts/autoconf/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2013 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2013-02-12'
+timestamp='2015-03-08'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2013-02-12'
# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches with a ChangeLog entry to [email protected].
+# Please send patches to <[email protected]>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <[email protected]>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@@ -252,19 +252,20 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc \
+ | arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
- | c4x | clipper \
+ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -282,8 +283,10 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
@@ -295,11 +298,11 @@ case $basic_machine in
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | open8 \
- | or1k | or32 \
+ | open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
@@ -310,6 +313,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@@ -324,7 +328,10 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -366,21 +373,22 @@ case $basic_machine in
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
- | elxsi-* \
+ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
@@ -400,8 +408,10 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
@@ -413,6 +423,7 @@ case $basic_machine in
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
+ | or1k*-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -430,6 +441,7 @@ case $basic_machine in
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
+ | visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -506,6 +518,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-aros
;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -767,6 +782,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@@ -794,7 +812,7 @@ case $basic_machine in
os=-mingw64
;;
mingw32)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@@ -822,6 +840,10 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -830,7 +852,7 @@ case $basic_machine in
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-msys
;;
mvs)
@@ -1354,7 +1376,7 @@ case $os in
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
+ | -aos* | -aros* | -cloudabi* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1367,14 +1389,14 @@ case $os in
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1546,6 +1568,9 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
+ c8051-*)
+ os=-elf
+ ;;
hexagon-*)
os=-elf
;;
@@ -1589,9 +1614,6 @@ case $basic_machine in
mips*-*)
os=-elf
;;
- or1k-*)
- os=-elf
- ;;
or32-*)
os=-coff
;;
@@ -1786,4 +1808,3 @@ exit
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
-
diff --git a/erts/autoconf/configure.vxworks b/erts/autoconf/configure.vxworks
index 23a93faa31..96dd1f8401 100755
--- a/erts/autoconf/configure.vxworks
+++ b/erts/autoconf/configure.vxworks
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/vxworks/sed.general b/erts/autoconf/vxworks/sed.general
index efa4e99054..5adee4db45 100644
--- a/erts/autoconf/vxworks/sed.general
+++ b/erts/autoconf/vxworks/sed.general
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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.
+# Licensed under the Apache License, Version 2.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%
#
@@ -78,8 +79,6 @@ s|@WITH_SCTP@||
# HiPE
s|@HIPE_ENABLED@||
-s|@PERFCTR_PATH@||
-s|@USE_PERFCTR@||
# m4
s|@OPSYS@|noopsys|
diff --git a/erts/autoconf/vxworks/sed.vxworks_cpu32 b/erts/autoconf/vxworks/sed.vxworks_cpu32
index 163dd78897..e3d54246ab 100644
--- a/erts/autoconf/vxworks/sed.vxworks_cpu32
+++ b/erts/autoconf/vxworks/sed.vxworks_cpu32
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc32 b/erts/autoconf/vxworks/sed.vxworks_ppc32
index f00daef74c..012760e127 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc32
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc32
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc603 b/erts/autoconf/vxworks/sed.vxworks_ppc603
index 40296b8f07..55af52571b 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc603
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc603
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall b/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
index 2550432d1e..e0c0891aeb 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc860 b/erts/autoconf/vxworks/sed.vxworks_ppc860
index cd7c9ff797..8828339e34 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc860
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc860
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_simlinux b/erts/autoconf/vxworks/sed.vxworks_simlinux
index 67ddbf1575..950fb79ec5 100644
--- a/erts/autoconf/vxworks/sed.vxworks_simlinux
+++ b/erts/autoconf/vxworks/sed.vxworks_simlinux
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_simso b/erts/autoconf/vxworks/sed.vxworks_simso
index 1af88cef31..6f2796f04e 100644
--- a/erts/autoconf/vxworks/sed.vxworks_simso
+++ b/erts/autoconf/vxworks/sed.vxworks_simso
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/autoconf/vxworks/sed.vxworks_sparc b/erts/autoconf/vxworks/sed.vxworks_sparc
index ae26f234d2..e67c34af26 100644
--- a/erts/autoconf/vxworks/sed.vxworks_sparc
+++ b/erts/autoconf/vxworks/sed.vxworks_sparc
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/autoconf/win32.config.cache.static b/erts/autoconf/win32.config.cache.static
index b387db2b22..b3328e5414 100755
--- a/erts/autoconf/win32.config.cache.static
+++ b/erts/autoconf/win32.config.cache.static
@@ -221,7 +221,6 @@ ac_cv_type_size_t=${ac_cv_type_size_t=yes}
ac_cv_type_uid_t=${ac_cv_type_uid_t=no}
ac_cv_type_void_p=${ac_cv_type_void_p=yes}
ac_cv_working_alloca_h=${ac_cv_working_alloca_h=no}
-erl_cv_time_correction=${erl_cv_time_correction=none}
erts_cv___after_morecore_hook_can_track_malloc=${erts_cv___after_morecore_hook_can_track_malloc=no}
erts_cv_fwrite_unlocked=${erts_cv_fwrite_unlocked=no}
erts_cv_have__end_symbol=${erts_cv_have__end_symbol=no}
diff --git a/erts/autoconf/win64.config.cache.static b/erts/autoconf/win64.config.cache.static
index a8a2bfb59c..c7d92c7000 100755
--- a/erts/autoconf/win64.config.cache.static
+++ b/erts/autoconf/win64.config.cache.static
@@ -262,7 +262,6 @@ ac_cv_type_signal=${ac_cv_type_signal=void}
ac_cv_type_size_t=${ac_cv_type_size_t=yes}
ac_cv_type_uid_t=${ac_cv_type_uid_t=no}
ac_cv_working_alloca_h=${ac_cv_working_alloca_h=no}
-erl_cv_time_correction=${erl_cv_time_correction=none}
erts_cv___after_morecore_hook_can_track_malloc=${erts_cv___after_morecore_hook_can_track_malloc=no}
erts_cv_fwrite_unlocked=${erts_cv_fwrite_unlocked=no}
erts_cv_have__end_symbol=${erts_cv_have__end_symbol=no}
diff --git a/erts/configure.in b/erts/configure.in
index c93ab85c4f..4d6f88e63b 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -2,18 +2,19 @@ dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1997-2014. All Rights Reserved.
+dnl Copyright Ericsson AB 1997-2015. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
@@ -264,24 +265,6 @@ AS_HELP_STRING([--enable-m32-build],
esac
],enable_m32_build=no)
-AC_SUBST(PERFCTR_PATH)
-AC_ARG_WITH(perfctr,
-AS_HELP_STRING([--with-perfctr=PATH],
- [specify location of perfctr include and lib])
-AS_HELP_STRING([--without-perfctr], [don't use perfctr (default)]))
-
-if test "x$with_perfctr" = "xno" -o "x$with_perfctr" = "x" ; then
- PERFCTR_PATH=
-else
- if test ! -f "$with_perfctr/usr.lib/libperfctr.a" ; then
- AC_MSG_ERROR(Invalid path to option --with-perfctr=PATH)
- fi
- PERFCTR_PATH="$with_perfctr"
- AC_DEFINE(USE_PERFCTR,[1],
- [Define to enable hrvtime() on Linux systems with perfctr extension])
-fi
-
-
AC_ARG_WITH(dynamic-trace,
AS_HELP_STRING([--with-dynamic-trace={dtrace|systemtap}],
[specify use of dynamic trace framework, dtrace or systemtap])
@@ -335,15 +318,6 @@ if test X"$use_vm_probes" = X"yes"; then
[Define to enable VM dynamic trace probes])
fi
-
-AC_ARG_ENABLE(clock-gettime,
-AS_HELP_STRING([--enable-clock-gettime],
- [use clock-gettime for time correction]),
-[ case "$enableval" in
- no) clock_gettime_correction=no ;;
- *) clock_gettime_correction=yes ;;
- esac ], clock_gettime_correction=unknown)
-
AC_ARG_WITH(assumed-cache-line-size,
AS_HELP_STRING([--with-assumed-cache-line-size=SIZE],
[specify assumed cache line size in bytes (valid values are powers of two between and including 16 and 8192; default is 64)]))
@@ -368,6 +342,15 @@ AS_HELP_STRING([--enable-systemd], [enable systemd support in epmd]),
[],
[enable_systemd=no])
+AC_ARG_ENABLE(saved-compile-time,
+AS_HELP_STRING([--disable-saved-compile-time], [disable saved compile time]),
+[ case "$enableval" in
+ no) save_compile_time=0 ;;
+ *) save_compile_time=1 ;;
+ esac ], save_compile_time=1)
+
+AC_DEFINE_UNQUOTED(ERTS_SAVED_COMPILE_TIME, $save_compile_time, [Save compile time?])
+
dnl Magic test for clearcase.
OTP_RELEASE=
if test "${ERLANG_COMMERCIAL_BUILD}" != ""; then
@@ -485,7 +468,7 @@ case $host_os in
win32)
# The ethread library requires _WIN32_WINNT of at least 0x0403.
# -D_WIN32_WINNT=* from CPPFLAGS is saved in ETHR_DEFS.
- CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0501 -DWINVER=0x0501"
+ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600"
;;
darwin*)
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE"
@@ -649,7 +632,7 @@ fi
case $chk_opsys_ in
win32) OPSYS=win32;;
solaris2.*|SunOS5.*) OPSYS=sol2;;
- linux|Linux) OPSYS=linux;;
+ linux*|Linux) OPSYS=linux;;
darwin|Darwin) OPSYS=darwin;;
freebsd|FreeBSD) OPSYS=freebsd;;
*) OPSYS=noopsys
@@ -676,6 +659,7 @@ case $chk_arch_ in
powerpc) ARCH=ppc;;
ppc) ARCH=ppc;;
ppc64) ARCH=ppc64;;
+ ppc64le) ARCH=ppc64;;
"Power Macintosh") ARCH=ppc;;
armv5b) ARCH=arm;;
armv5teb) ARCH=arm;;
@@ -1128,10 +1112,31 @@ if test $ERTS_BUILD_SMP_EMU = yes; then
case "$ethr_have_native_atomics-$smp_require_native_atomics-$ethr_have_native_spinlock" in
yes-*)
+ if test "$ethr_native_atomic_implementation" = "gcc_sync"; then
+ test -f "$ERL_TOP/erts/CONF_INFO" ||
+ echo "" > "$ERL_TOP/erts/CONF_INFO"
+ cat >> $ERL_TOP/erts/CONF_INFO <<EOF
+
+ WARNING:
+ Only gcc's __sync_* builtins available for
+ atomic memory access. This will cause lots
+ of expensive and unnecessary memory barrier
+ instructions to be issued which will make
+ the performance of the runtime system
+ suffer. You are *strongly* advised to
+ upgrade to a gcc version that supports the
+ __atomic_* builtins (at least gcc version
+ 4.7) or build with libatomic_ops. See the
+ "Atomic Memory Operations and the VM"
+ chapter of \$ERL_TOP/HOWTO/INSTALL.md for
+ more information.
+
+EOF
+ fi
;;
no-yes-*)
- AC_MSG_ERROR([No native atomic implementation found. See Configuring section in INSTALL.md for more information.])
+ AC_MSG_ERROR([No native atomic implementation found. See the \"Atomic Memory Operations and the VM\" chapter of \$ERL_TOP/HOWTO/INSTALL.md for more information.])
;;
no-no-yes)
@@ -1560,10 +1565,11 @@ if test "$have_gethostbyname_r" = yes; then
[Define to flavour of gethostbyname_r]))
;;
*)
- AC_EGREP_CPP(yes,[#include <stdio.h>
- #ifdef __GLIBC__
- yes
- #endif
+ AC_EGREP_CPP(^yes$,[
+#include <stdio.h>
+#ifdef __GLIBC__
+yes
+#endif
], AC_DEFINE(HAVE_GETHOSTBYNAME_R, GHBN_R_GLIBC,
[Define to flavour of gethostbyname_r]))
;;
@@ -1770,6 +1776,10 @@ AC_CHECK_HEADER(sys/event.h, have_kernel_poll=kqueue)
AC_CHECK_HEADER(sys/epoll.h, have_kernel_poll=epoll)
AC_CHECK_HEADER(sys/devpoll.h, have_kernel_poll=/dev/poll)
+dnl Check if we have timerfds to be used for high accuracy
+dnl epoll_wait timeouts
+AC_CHECK_HEADERS([sys/timerfd.h])
+
dnl Check for kernel SCTP support
AC_SUBST(LIBSCTP)
if test "x$enable_sctp" != "xno" ; then
@@ -2115,7 +2125,7 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop
gethrtime localtime_r gmtime_r inet_pton \
memcpy mallopt sbrk _sbrk __sbrk brk _brk __brk \
flockfile fstat strlcpy strlcat setsid posix2time time2posix \
- setlocale nl_langinfo poll mlockall])
+ setlocale nl_langinfo poll mlockall ppoll])
AC_MSG_CHECKING([for isfinite])
AC_TRY_LINK([#include <math.h>],
@@ -2918,6 +2928,10 @@ else
#include <signal.h>
#include <stdlib.h>
+#if defined(__clang__) || defined(__llvm__)
+#error "Clang/LLVM generates broken code for FP exceptions"
+#endif
+
volatile int erl_fp_exception;
/*
@@ -3508,19 +3522,6 @@ fi
AC_SUBST(NATIVE_LIBS_ENABLED)
#
-# Check if HiPE should use a standard installation of perfctr.
-#
-AC_SUBST(USE_PERFCTR)
-if test "x$HIPE_ENABLED" = "xyes" ; then
- if test "x$with_perfctr" = "x" ; then
- AC_CHECK_LIB(perfctr, vperfctr_info, [USE_PERFCTR=1
- AC_DEFINE(USE_PERFCTR,[1],[Define to enable hrvtime() on Linux systems with perfctr extension])])
- elif test "x$with_perfctr" != "xno" ; then
- USE_PERFCTR=1
- fi
-fi
-
-#
# Check for working poll().
#
AC_MSG_CHECKING([for working poll()])
@@ -4115,7 +4116,7 @@ AC_ARG_WITH(ssl-rpath,
AS_HELP_STRING([--with-ssl-rpath=yes|no|PATHS],
[runtime library path for OpenSSL. Default is "yes", which equates to a
number of standard locations. If "no", then no runtime
- library paths wil be used. Anything else should be a
+ library paths will be used. Anything else should be a
comma separated list of paths.]),
[
case X$with_ssl in
@@ -4308,10 +4309,10 @@ case "$erl_xcomp_without_sysroot-$with_ssl" in
SSL_INCLUDE="-I$dir/include"
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$SSL_INCLUDE
- AC_EGREP_CPP(yes,[
+ AC_EGREP_CPP(^yes$,[
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x0090700fL
- yes
+yes
#endif
],[
ssl_found=yes
@@ -4506,10 +4507,10 @@ if test "x$SSL_APP" != "x" ; then
AC_MSG_CHECKING(for OpenSSL kerberos 5 support)
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$SSL_INCLUDE
- AC_EGREP_CPP(yes,[
+ AC_EGREP_CPP(^yes$,[
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_KRB5
- yes
+yes
#endif
],[
AC_MSG_RESULT([yes])
@@ -4706,18 +4707,32 @@ AC_SUBST(os_mon_programs)
AC_SUBST(CPU_SUP_LIBS)
AC_CHECK_LIB(kstat, kstat_open, [
- os_mon_programs="$os_mon_programs cpu_sup"
+ use_cpu_sup=yes
CPU_SUP_LIBS="$CPU_SUP_LIBS -lkstat"
])
+AC_CHECK_LIB(kvm, kvm_open, [
+ use_cpu_sup=yes
+ CPU_SUP_LIBS="$CPU_SUP_LIBS -lkvm"
+ ])
+
case $host_os in
solaris2*)
os_mon_programs="$os_mon_programs ferrule mod_syslog" ;;
+ darwin*)
+ use_cpu_sup=yes ;;
+ openbsd*)
+ use_cpu_sup=yes ;;
linux*)
- os_mon_programs="$os_mon_programs cpu_sup" ;;
+ use_cpu_sup=yes ;;
+ freebsd*)
+ use_cpu_sup=yes ;;
esac
-
+if test "$use_cpu_sup" = "yes"; then
+ os_mon_programs="$os_mon_programs cpu_sup"
+fi
+
AC_ARG_WITH(javac,
AS_HELP_STRING([--with-javac=JAVAC], [specify Java compiler to use])
AS_HELP_STRING([--with-javac], [use a Java compiler if found (default)])
@@ -4748,12 +4763,12 @@ fi
AC_CHECK_PROGS(JAVAC, $check_javac)
if test -n "$JAVAC"; then
- dnl Make sure it's at least JDK 1.5
- AC_CACHE_CHECK(for JDK version 1.5,
- ac_cv_prog_javac_ver_1_5,
+ dnl Make sure it's at least JDK 1.6
+ AC_CACHE_CHECK(for JDK version 1.6,
+ ac_cv_prog_javac_ver_1_6,
[ERL_TRY_LINK_JAVA([], [for (String i : args);],
- ac_cv_prog_javac_ver_1_5=yes, ac_cv_prog_javac_ver_1_5=no)])
- if test $ac_cv_prog_javac_ver_1_5 = no; then
+ ac_cv_prog_javac_ver_1_6=yes, ac_cv_prog_javac_ver_1_6=no)])
+ if test $ac_cv_prog_javac_ver_1_6 = no; then
unset -v JAVAC
fi
fi
@@ -4910,6 +4925,11 @@ LDFLAGS="$LDFLAGS $sanitizers"
])
dnl ----------------------------------------------------------------------
+dnl Check for log2
+dnl ----------------------------------------------------------------------
+AC_CHECK_FUNCS([log2])
+
+dnl ----------------------------------------------------------------------
dnl Output the result.
dnl ----------------------------------------------------------------------
diff --git a/erts/doc/Makefile b/erts/doc/Makefile
index 8ea3793d90..d415e544f3 100644
--- a/erts/doc/Makefile
+++ b/erts/doc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile
index e8b856c3ff..83f4c58560 100644
--- a/erts/doc/src/Makefile
+++ b/erts/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -177,6 +178,8 @@ release_docs_spec: docs
$(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
$(INSTALL_DATA) $(HTMLDIR)/* \
"$(RELSYSDIR)/doc/html"
+ $(INSTALL_DATA) $(ERL_TOP)/erts/example/time_compat.erl \
+ "$(RELSYSDIR)/doc/html"
$(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
$(INSTALL_DIR) "$(RELEASE_PATH)/man/man3"
$(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3"
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
index 835a4fc692..186c9a1143 100644
--- a/erts/doc/src/absform.xml
+++ b/erts/doc/src/absform.xml
@@ -4,21 +4,22 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
+
</legalnotice>
<title>The Abstract Format</title>
@@ -34,24 +35,24 @@
<p></p>
<p>This document describes the standard representation of parse trees for Erlang
programs as Erlang terms. This representation is known as the <em>abstract format</em>.
- Functions dealing with such parse trees are <c><![CDATA[compile:forms/[1,2]]]></c>
+ Functions dealing with such parse trees are <c>compile:forms/[1,2]</c>
and functions in the modules
- <c><![CDATA[epp]]></c>,
- <c><![CDATA[erl_eval]]></c>,
- <c><![CDATA[erl_lint]]></c>,
- <c><![CDATA[erl_pp]]></c>,
- <c><![CDATA[erl_parse]]></c>,
+ <c>epp</c>,
+ <c>erl_eval</c>,
+ <c>erl_lint</c>,
+ <c>erl_pp</c>,
+ <c>erl_parse</c>,
and
- <c><![CDATA[io]]></c>.
+ <c>io</c>.
They are also used as input and output for parse transforms (see the module
- <c><![CDATA[compile]]></c>).</p>
- <p>We use the function <c><![CDATA[Rep]]></c> to denote the mapping from an Erlang source
- construct <c><![CDATA[C]]></c> to its abstract format representation <c><![CDATA[R]]></c>, and write
- <c><![CDATA[R = Rep(C)]]></c>.
+ <c>compile</c>).</p>
+ <p>We use the function <c>Rep</c> to denote the mapping from an Erlang source
+ construct <c>C</c> to its abstract format representation <c>R</c>, and write
+ <c>R = Rep(C)</c>.
</p>
- <p>The word <c><![CDATA[LINE]]></c> below represents an integer, and denotes the
+ <p>The word <c>LINE</c> below represents an integer, and denotes the
number of the line in the source file where the construction occurred.
- Several instances of <c><![CDATA[LINE]]></c> in the same construction may denote
+ Several instances of <c>LINE</c> in the same construction may denote
different lines.</p>
<p>Since operators are not terms in their own right, when operators are
mentioned below, the representation of an operator should be taken to
@@ -60,71 +61,116 @@
</p>
<section>
- <title>Module declarations and forms</title>
+ <title>Module Declarations and Forms</title>
<p>A module declaration consists of a sequence of forms that are either
function declarations or attributes.</p>
<list type="bulleted">
<item>If D is a module declaration consisting of the forms
- <c><![CDATA[F_1]]></c>, ..., <c><![CDATA[F_k]]></c>, then
- Rep(D) = <c><![CDATA[[Rep(F_1), ..., Rep(F_k)]]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-module(Mod)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,module,Mod}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-export([Fun_1/A_1, ..., Fun_k/A_k])]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,export,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-import(Mod,[Fun_1/A_1, ..., Fun_k/A_k])]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-compile(Options)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,compile,Options}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-file(File,Line)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,file,{File,Line}}]]></c>.</item>
- <item>If F is a record declaration <c><![CDATA[-record(Name,{V_1, ..., V_k})]]></c>, then
- Rep(F) =
- <c><![CDATA[{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}]]></c>. For Rep(V), see below.</item>
- <item>If F is a wild attribute <c><![CDATA[-A(T)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,A,T}]]></c>.
+ <c>F_1</c>, ..., <c>F_k</c>, then
+ Rep(D) = <c>[Rep(F_1), ..., Rep(F_k)]</c>.</item>
+ <item>If F is an attribute <c>-module(Mod)</c>, then
+ Rep(F) = <c>{attribute,LINE,module,Mod}</c>.</item>
+ <item>If F is an attribute <c>-behavior(Behavior)</c>, then
+ Rep(F) = <c>{attribute,LINE,behavior,Behavior}</c>.</item>
+ <item>If F is an attribute <c>-behaviour(Behaviour)</c>, then
+ Rep(F) = <c>{attribute,LINE,behaviour,Behaviour}</c>.</item>
+ <item>If F is an attribute <c>-export([Fun_1/A_1, ..., Fun_k/A_k])</c>, then
+ Rep(F) = <c>{attribute,LINE,export,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}</c>.</item>
+ <item>If F is an attribute <c>-import(Mod,[Fun_1/A_1, ..., Fun_k/A_k])</c>, then
+ Rep(F) = <c>{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}</c>.</item>
+ <item>If F is an attribute <c>-export_type([Type_1/A_1, ..., Type_k/A_k])</c>, then
+ Rep(F) = <c>{attribute,LINE,export_type,[{Type_1,A_1}, ..., {Type_k,A_k}]}</c>.</item>
+ <item>If F is an attribute <c>-compile(Options)</c>, then
+ Rep(F) = <c>{attribute,LINE,compile,Options}</c>.</item>
+ <item>If F is an attribute <c>-file(File,Line)</c>, then
+ Rep(F) = <c>{attribute,LINE,file,{File,Line}}</c>.</item>
+ <item>If F is a record declaration
+ <c>-record(Name,{V_1, ..., V_k})</c>, then Rep(F) =
+ <c>{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}</c>.
+ For Rep(V), see below.</item>
+ <item>If F is a type declaration
+ <c>-Type Name(V_1, ..., V_k) :: T</c>, where
+ <c>Type</c> is either the atom <c>type</c> or the atom <c>opaque</c>,
+ each <c>V_i</c> is a variable, and <c>T</c> is a type, then Rep(F) =
+ <c>{attribute,LINE,Type,{Name,Rep(T),[Rep(V_1), ..., Rep(V_k)]}}</c>.
+ </item>
+ <item>If F is a function specification
+ <c>-Spec Name Ft_1; ...; Ft_k</c>,
+ where <c>Spec</c> is either the atom <c>spec</c> or the atom
+ <c>callback</c>, and each <c>Ft_i</c> is a possibly constrained
+ function type with an argument sequence of the same length
+ <c>Arity</c>, then Rep(F) =
+ <c>{attribute,Line,Spec,{{Name,Arity},[Rep(Ft_1), ..., Rep(Ft_k)]}}</c>.
+ </item>
+ <item>If F is a function specification
+ <c>-spec Mod:Name Ft_1; ...; Ft_k</c>,
+ where each <c>Ft_i</c> is a possibly constrained
+ function type with an argument sequence of the same length
+ <c>Arity</c>, then Rep(F) =
+ <c>{attribute,Line,spec,{{Mod,Name,Arity},[Rep(Ft_1), ..., Rep(Ft_k)]}}</c>.
+ </item>
+ <item>If F is a wild attribute <c>-A(T)</c>, then
+ Rep(F) = <c>{attribute,LINE,A,T}</c>.
<br></br></item>
- <item>If F is a function declaration <c><![CDATA[Name Fc_1 ; ... ; Name Fc_k]]></c>,
- where each <c><![CDATA[Fc_i]]></c> is a function clause with a
- pattern sequence of the same length <c><![CDATA[Arity]]></c>, then
- Rep(F) = <c><![CDATA[{function,LINE,Name,Arity,[Rep(Fc_1), ...,Rep(Fc_k)]}]]></c>.</item>
+ <item>If F is a function declaration
+ <c>Name Fc_1 ; ... ; Name Fc_k</c>,
+ where each <c>Fc_i</c> is a function clause with a
+ pattern sequence of the same length <c>Arity</c>, then
+ Rep(F) = <c>{function,LINE,Name,Arity,[Rep(Fc_1), ...,Rep(Fc_k)]}</c>.
+ </item>
</list>
<section>
- <title>Record fields</title>
+ <title>Record Fields</title>
<p>Each field in a record declaration may have an optional
- explicit default initializer expression</p>
+ explicit default initializer expression, as well as an
+ optional type.</p>
<list type="bulleted">
- <item>If V is <c><![CDATA[A]]></c>, then
- Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A)}]]></c>.</item>
- <item>If V is <c><![CDATA[A = E]]></c>, then
- Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A),Rep(E)}]]></c>.</item>
+ <item>If V is <c>A</c>, then
+ Rep(V) = <c>{record_field,LINE,Rep(A)}</c>.</item>
+ <item>If V is <c>A = E</c>,
+ where <c>E</c> is an expression, then
+ Rep(V) = <c>{record_field,LINE,Rep(A),Rep(E)}</c>.</item>
+ <item>If V is <c>A :: T</c>, where <c>T</c> is a
+ type and it does not contain
+ <c>undefined</c> syntactically, then Rep(V) =
+ <c>{typed_record_field,{record_field,LINE,Rep(A)},Rep(undefined | T)}</c>.
+ </item>
+ <item>If V is <c>A :: T</c>, where <c>T</c> is a type, then Rep(V) =
+ <c>{typed_record_field,{record_field,LINE,Rep(A)},Rep(T)}</c>.
+ </item>
+ <item>If V is <c>A = E :: T</c>, where
+ <c>E</c> is an expression and <c>T</c> is a type, then Rep(V) =
+ <c>{typed_record_field,{record_field,LINE,Rep(A),Rep(E)},Rep(T)}</c>.
+ </item>
</list>
</section>
<section>
- <title>Representation of parse errors and end of file</title>
+ <title>Representation of Parse Errors and End-of-file</title>
<p>In addition to the representations of forms, the list that represents
- a module declaration (as returned by functions in <c><![CDATA[erl_parse]]></c> and
- <c><![CDATA[epp]]></c>) may contain tuples <c><![CDATA[{error,E}]]></c> and <c><![CDATA[{warning,W}]]></c>, denoting
- syntactically incorrect forms and warnings, and <c><![CDATA[{eof,LINE}]]></c>, denoting an end
- of stream encountered before a complete form had been parsed.</p>
+ a module declaration (as returned by functions in <c>erl_parse</c> and
+ <c>epp</c>) may contain tuples <c>{error,E}</c> and
+ <c>{warning,W}</c>, denoting syntactically incorrect forms and
+ warnings, and <c>{eof,LINE}</c>, denoting an end-of-stream
+ encountered before a complete form had been parsed.</p>
</section>
</section>
<section>
- <title>Atomic literals</title>
+ <title>Atomic Literals</title>
<p>There are five kinds of atomic literals, which are represented in the
same way in patterns, expressions and guards:</p>
<list type="bulleted">
<item>If L is an integer or character literal, then
- Rep(L) = <c><![CDATA[{integer,LINE,L}]]></c>.</item>
+ Rep(L) = <c>{integer,LINE,L}</c>.</item>
<item>If L is a float literal, then
- Rep(L) = <c><![CDATA[{float,LINE,L}]]></c>.</item>
+ Rep(L) = <c>{float,LINE,L}</c>.</item>
<item>If L is a string literal consisting of the characters
- <c><![CDATA[C_1]]></c>, ..., <c><![CDATA[C_k]]></c>, then
- Rep(L) = <c><![CDATA[{string,LINE,[C_1, ..., C_k]}]]></c>.</item>
+ <c>C_1</c>, ..., <c>C_k</c>, then
+ Rep(L) = <c>{string,LINE,[C_1, ..., C_k]}</c>.</item>
<item>If L is an atom literal, then
- Rep(L) = <c><![CDATA[{atom,LINE,L}]]></c>.</item>
+ Rep(L) = <c>{atom,LINE,L}</c>.</item>
</list>
<p>Note that negative integer and float literals do not occur as such; they are
parsed as an application of the unary negation operator.</p>
@@ -132,47 +178,47 @@
<section>
<title>Patterns</title>
- <p>If <c><![CDATA[Ps]]></c> is a sequence of patterns <c><![CDATA[P_1, ..., P_k]]></c>, then
- Rep(Ps) = <c><![CDATA[[Rep(P_1), ..., Rep(P_k)]]]></c>. Such sequences occur as the
+ <p>If <c>Ps</c> is a sequence of patterns <c>P_1, ..., P_k</c>, then
+ Rep(Ps) = <c>[Rep(P_1), ..., Rep(P_k)]</c>. Such sequences occur as the
list of arguments to a function or fun.</p>
<p>Individual patterns are represented as follows:</p>
<list type="bulleted">
<item>If P is an atomic literal L, then Rep(P) = Rep(L).</item>
- <item>If P is a compound pattern <c><![CDATA[P_1 = P_2]]></c>, then
- Rep(P) = <c><![CDATA[{match,LINE,Rep(P_1),Rep(P_2)}]]></c>.</item>
- <item>If P is a variable pattern <c><![CDATA[V]]></c>, then
- Rep(P) = <c><![CDATA[{var,LINE,A}]]></c>,
+ <item>If P is a compound pattern <c>P_1 = P_2</c>, then
+ Rep(P) = <c>{match,LINE,Rep(P_1),Rep(P_2)}</c>.</item>
+ <item>If P is a variable pattern <c>V</c>, then
+ Rep(P) = <c>{var,LINE,A}</c>,
where A is an atom with a printname consisting of the same characters as
- <c><![CDATA[V]]></c>.</item>
- <item>If P is a universal pattern <c><![CDATA[_]]></c>, then
- Rep(P) = <c><![CDATA[{var,LINE,'_'}]]></c>.</item>
- <item>If P is a tuple pattern <c><![CDATA[{P_1, ..., P_k}]]></c>, then
- Rep(P) = <c><![CDATA[{tuple,LINE,[Rep(P_1), ..., Rep(P_k)]}]]></c>.</item>
- <item>If P is a nil pattern <c><![CDATA[[]]]></c>, then
- Rep(P) = <c><![CDATA[{nil,LINE}]]></c>.</item>
- <item>If P is a cons pattern <c><![CDATA[[P_h | P_t]]]></c>, then
- Rep(P) = <c><![CDATA[{cons,LINE,Rep(P_h),Rep(P_t)}]]></c>.</item>
- <item>If E is a binary pattern <c><![CDATA[<<P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k>>]]></c>, then
- Rep(E) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(P_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(P_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ <c>V</c>.</item>
+ <item>If P is a universal pattern <c>_</c>, then
+ Rep(P) = <c>{var,LINE,'_'}</c>.</item>
+ <item>If P is a tuple pattern <c>{P_1, ..., P_k}</c>, then
+ Rep(P) = <c>{tuple,LINE,[Rep(P_1), ..., Rep(P_k)]}</c>.</item>
+ <item>If P is a nil pattern <c>[]</c>, then
+ Rep(P) = <c>{nil,LINE}</c>.</item>
+ <item>If P is a cons pattern <c>[P_h | P_t]</c>, then
+ Rep(P) = <c>{cons,LINE,Rep(P_h),Rep(P_t)}</c>.</item>
+ <item>If E is a binary pattern <c>&lt;&lt;P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k>></c>, then
+ Rep(E) = <c>{bin,LINE,[{bin_element,LINE,Rep(P_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(P_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
For Rep(TSL), see below.
- An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
- (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
- <item>If P is <c><![CDATA[P_1 Op P_2]]></c>, where <c><![CDATA[Op]]></c> is a binary operator (this
- is either an occurrence of <c><![CDATA[++]]></c> applied to a literal string or character
+ An omitted <c>Size</c> is represented by <c>default</c>. An omitted <c>TSL</c>
+ (type specifier list) is represented by <c>default</c>.</item>
+ <item>If P is <c>P_1 Op P_2</c>, where <c>Op</c> is a binary operator (this
+ is either an occurrence of <c>++</c> applied to a literal string or character
list, or an occurrence of an expression that can be evaluated to a number
at compile time),
- then Rep(P) = <c><![CDATA[{op,LINE,Op,Rep(P_1),Rep(P_2)}]]></c>.</item>
- <item>If P is <c><![CDATA[Op P_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator (this is an
+ then Rep(P) = <c>{op,LINE,Op,Rep(P_1),Rep(P_2)}</c>.</item>
+ <item>If P is <c>Op P_0</c>, where <c>Op</c> is a unary operator (this is an
occurrence of an expression that can be evaluated to a number at compile
- time), then Rep(P) = <c><![CDATA[{op,LINE,Op,Rep(P_0)}]]></c>.</item>
- <item>If P is a record pattern <c><![CDATA[#Name{Field_1=P_1, ..., Field_k=P_k}]]></c>,
+ time), then Rep(P) = <c>{op,LINE,Op,Rep(P_0)}</c>.</item>
+ <item>If P is a record pattern <c>#Name{Field_1=P_1, ..., Field_k=P_k}</c>,
then Rep(P) =
- <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}]]></c>.</item>
- <item>If P is <c><![CDATA[#Name.Field]]></c>, then
- Rep(P) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
- <item>If P is <c><![CDATA[( P_0 )]]></c>, then
- Rep(P) = <c><![CDATA[Rep(P_0)]]></c>,
- i.e., patterns cannot be distinguished from their bodies.</item>
+ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}</c>.</item>
+ <item>If P is <c>#Name.Field</c>, then
+ Rep(P) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item>
+ <item>If P is <c>( P_0 )</c>, then
+ Rep(P) = <c>Rep(P_0)</c>,
+ that is, patterns cannot be distinguished from their bodies.</item>
</list>
<p>Note that every pattern has the same source form as some expression, and is
represented the same way as the corresponding expression.</p>
@@ -180,180 +226,167 @@
<section>
<title>Expressions</title>
- <p>A body B is a sequence of expressions <c><![CDATA[E_1, ..., E_k]]></c>, and
- Rep(B) = <c><![CDATA[[Rep(E_1), ..., Rep(E_k)]]]></c>.</p>
+ <p>A body B is a sequence of expressions <c>E_1, ..., E_k</c>, and
+ Rep(B) = <c>[Rep(E_1), ..., Rep(E_k)]</c>.</p>
<p>An expression E is one of the following alternatives:</p>
<list type="bulleted">
- <item>If P is an atomic literal <c><![CDATA[L]]></c>, then
- Rep(P) = Rep(L).</item>
- <item>If E is <c><![CDATA[P = E_0]]></c>, then
- Rep(E) = <c><![CDATA[{match,LINE,Rep(P),Rep(E_0)}]]></c>.</item>
- <item>If E is a variable <c><![CDATA[V]]></c>, then
- Rep(E) = <c><![CDATA[{var,LINE,A}]]></c>,
- where <c><![CDATA[A]]></c> is an atom with a printname consisting of the same
- characters as <c><![CDATA[V]]></c>.</item>
- <item>If E is a tuple skeleton <c><![CDATA[{E_1, ..., E_k}]]></c>, then
- Rep(E) = <c><![CDATA[{tuple,LINE,[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[[]]]></c>, then
- Rep(E) = <c><![CDATA[{nil,LINE}]]></c>.</item>
- <item>If E is a cons skeleton <c><![CDATA[[E_h | E_t]]]></c>, then
- Rep(E) = <c><![CDATA[{cons,LINE,Rep(E_h),Rep(E_t)}]]></c>.</item>
- <item>If E is a binary constructor <c><![CDATA[<<V_1:Size_1/TSL_1, ..., V_k:Size_k/TSL_k>>]]></c>, then
- Rep(E) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(V_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(V_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ <item>If P is an atomic literal <c>L</c>, then Rep(P) = Rep(L).</item>
+ <item>If E is <c>P = E_0</c>, then
+ Rep(E) = <c>{match,LINE,Rep(P),Rep(E_0)}</c>.</item>
+ <item>If E is a variable <c>V</c>, then Rep(E) = <c>{var,LINE,A}</c>,
+ where <c>A</c> is an atom with a printname consisting of the same
+ characters as <c>V</c>.</item>
+ <item>If E is a tuple skeleton <c>{E_1, ..., E_k}</c>, then
+ Rep(E) = <c>{tuple,LINE,[Rep(E_1), ..., Rep(E_k)]}</c>.</item>
+ <item>If E is <c>[]</c>, then
+ Rep(E) = <c>{nil,LINE}</c>.</item>
+ <item>If E is a cons skeleton <c>[E_h | E_t]</c>, then
+ Rep(E) = <c>{cons,LINE,Rep(E_h),Rep(E_t)}</c>.</item>
+ <item>If E is a binary constructor <c>&lt;&lt;V_1:Size_1/TSL_1, ..., V_k:Size_k/TSL_k>></c>, then Rep(E) =
+ <c>{bin,LINE,[{bin_element,LINE,Rep(V_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(V_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
For Rep(TSL), see below.
- An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
- (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
- <item>If E is <c><![CDATA[E_1 Op E_2]]></c>, where <c><![CDATA[Op]]></c> is a binary operator,
- then Rep(E) = <c><![CDATA[{op,LINE,Op,Rep(E_1),Rep(E_2)}]]></c>.</item>
- <item>If E is <c><![CDATA[Op E_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator, then
- Rep(E) = <c><![CDATA[{op,LINE,Op,Rep(E_0)}]]></c>.</item>
- <item>If E is <c><![CDATA[#Name{Field_1=E_1, ..., Field_k=E_k}]]></c>, then
- Rep(E) =
- <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}]]></c>.</item>
- <item>If E is <c><![CDATA[E_0#Name{Field_1=E_1, ..., Field_k=E_k}]]></c>, then
- Rep(E) =
- <c><![CDATA[{record,LINE,Rep(E_0),Name, [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}]]></c>.</item>
- <item>If E is <c><![CDATA[#Name.Field]]></c>, then
- Rep(E) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
- <item>If E is <c><![CDATA[E_0#Name.Field]]></c>, then
- Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Name,Rep(Field)}]]></c>.</item>
- <item>If E is <c><![CDATA[#{W_1, ..., W_k}]]></c> where each
- <c><![CDATA[W_i]]></c> is a map assoc or exact field, then Rep(E) =
- <c><![CDATA[{map,LINE,[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
- below.</item>
- <item>If E is <c><![CDATA[E_0#{W_1, ..., W_k}]]></c> where
- <c><![CDATA[W_i]]></c> is a map assoc or exact field, then Rep(E) =
- <c><![CDATA[{map,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For
- Rep(W), see below.</item>
- <item>If E is <c><![CDATA[catch E_0]]></c>, then
- Rep(E) = <c><![CDATA[{'catch',LINE,Rep(E_0)}]]></c>.</item>
- <item>If E is <c><![CDATA[E_0(E_1, ..., E_k)]]></c>, then
- Rep(E) = <c><![CDATA[{call,LINE,Rep(E_0),[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[E_m:E_0(E_1, ..., E_k)]]></c>, then
+ An omitted <c>Size</c> is represented by <c>default</c>. An omitted <c>TSL</c>
+ (type specifier list) is represented by <c>default</c>.</item>
+ <item>If E is <c>E_1 Op E_2</c>, where <c>Op</c> is a binary operator,
+ then Rep(E) = <c>{op,LINE,Op,Rep(E_1),Rep(E_2)}</c>.</item>
+ <item>If E is <c>Op E_0</c>, where <c>Op</c> is a unary operator, then
+ Rep(E) = <c>{op,LINE,Op,Rep(E_0)}</c>.</item>
+ <item>If E is <c>#Name{Field_1=E_1, ..., Field_k=E_k}</c>,
+ then Rep(E) =
+ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}</c>.</item>
+ <item>If E is <c>E_0#Name{Field_1=E_1, ..., Field_k=E_k}</c>, then
Rep(E) =
- <c><![CDATA[{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
- <item>If E is a list comprehension <c><![CDATA[[E_0 || W_1, ..., W_k]]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
+ <c>{record,LINE,Rep(E_0),Name,[{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}</c>.</item>
+ <item>If E is <c>#Name.Field</c>, then
+ Rep(E) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item>
+ <item>If E is <c>E_0#Name.Field</c>, then
+ Rep(E) = <c>{record_field,LINE,Rep(E_0),Name,Rep(Field)}</c>.</item>
+ <item>If E is <c>#{W_1, ..., W_k}</c> where each
+ <c>W_i</c> is a map assoc or exact field, then Rep(E) =
+ <c>{map,LINE,[Rep(W_1), ..., Rep(W_k)]}</c>. For Rep(W), see
below.</item>
- <item>If E is a binary comprehension <c><![CDATA[<<E_0 || W_1, ..., W_k>>]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
+ <item>If E is <c>E_0#{W_1, ..., W_k}</c> where
+ <c>W_i</c> is a map assoc or exact field, then Rep(E) =
+ <c>{map,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>.
+ For Rep(W), see below.</item>
+ <item>If E is <c>catch E_0</c>, then
+ Rep(E) = <c>{'catch',LINE,Rep(E_0)}</c>.</item>
+ <item>If E is <c>E_0(E_1, ..., E_k)</c>, then
+ Rep(E) = <c>{call,LINE,Rep(E_0),[Rep(E_1), ..., Rep(E_k)]}</c>.</item>
+ <item>If E is <c>E_m:E_0(E_1, ..., E_k)</c>, then Rep(E) =
+ <c>{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ..., Rep(E_k)]}</c>.
+ </item>
+ <item>If E is a list comprehension <c>[E_0 || W_1, ..., W_k]</c>,
+ where each <c>W_i</c> is a generator or a filter, then Rep(E) =
+ <c>{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>. For Rep(W), see
below.</item>
- <item>If E is <c><![CDATA[begin B end]]></c>, where <c><![CDATA[B]]></c> is a body, then
- Rep(E) = <c><![CDATA[{block,LINE,Rep(B)}]]></c>.</item>
- <item>If E is <c><![CDATA[if Ic_1 ; ... ; Ic_k end]]></c>,
- where each <c><![CDATA[Ic_i]]></c> is an if clause then
- Rep(E) =
- <c><![CDATA[{'if',LINE,[Rep(Ic_1), ..., Rep(Ic_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[case E_0 of Cc_1 ; ... ; Cc_k end]]></c>,
- where <c><![CDATA[E_0]]></c> is an expression and each <c><![CDATA[Cc_i]]></c> is a
- case clause then
- Rep(E) =
- <c><![CDATA[{'case',LINE,Rep(E_0),[Rep(Cc_1), ..., Rep(Cc_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[try B catch Tc_1 ; ... ; Tc_k end]]></c>,
- where <c><![CDATA[B]]></c> is a body and each <c><![CDATA[Tc_i]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],[]}]]></c>.</item>
- <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n end]]></c>,
- where <c><![CDATA[B]]></c> is a body,
- each <c><![CDATA[Cc_i]]></c> is a case clause and
- each <c><![CDATA[Tc_j]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],[]}]]></c>.</item>
- <item>If E is <c><![CDATA[try B after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are bodies then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[],[],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are a bodies and
- each <c><![CDATA[Cc_i]]></c> is a case clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[try B catch Tc_1 ; ... ; Tc_k after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are bodies and
- each <c><![CDATA[Tc_i]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are a bodies,
- each <c><![CDATA[Cc_i]]></c> is a case clause and
- each <c><![CDATA[Tc_j]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[receive Cc_1 ; ... ; Cc_k end]]></c>,
- where each <c><![CDATA[Cc_i]]></c> is a case clause then
+ <item>If E is a binary comprehension
+ <c>&lt;&lt;E_0 || W_1, ..., W_k>></c>,
+ where each <c>W_i</c> is a generator or a filter, then
+ Rep(E) = <c>{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>.
+ For Rep(W), see below.</item>
+ <item>If E is <c>begin B end</c>, where <c>B</c> is a body, then
+ Rep(E) = <c>{block,LINE,Rep(B)}</c>.</item>
+ <item>If E is <c>if Ic_1 ; ... ; Ic_k end</c>,
+ where each <c>Ic_i</c> is an if clause then Rep(E) =
+ <c>{'if',LINE,[Rep(Ic_1), ..., Rep(Ic_k)]}</c>.</item>
+ <item>If E is <c>case E_0 of Cc_1 ; ... ; Cc_k end</c>,
+ where <c>E_0</c> is an expression and each <c>Cc_i</c> is a
+ case clause then Rep(E) =
+ <c>{'case',LINE,Rep(E_0),[Rep(Cc_1), ..., Rep(Cc_k)]}</c>.</item>
+ <item>If E is <c>try B catch Tc_1 ; ... ; Tc_k end</c>,
+ where <c>B</c> is a body and each <c>Tc_i</c> is a catch clause then
Rep(E) =
- <c><![CDATA[{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[receive Cc_1 ; ... ; Cc_k after E_0 -> B_t end]]></c>,
- where each <c><![CDATA[Cc_i]]></c> is a case clause,
- <c><![CDATA[E_0]]></c> is an expression and <c><![CDATA[B_t]]></c> is a body, then
+ <c>{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],[]}</c>.</item>
+ <item>If E is <c>try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n end</c>,
+ where <c>B</c> is a body,
+ each <c>Cc_i</c> is a case clause and
+ each <c>Tc_j</c> is a catch clause then Rep(E) =
+ <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],[]}</c>.</item>
+ <item>If E is <c>try B after A end</c>,
+ where <c>B</c> and <c>A</c> are bodies then Rep(E) =
+ <c>{'try',LINE,Rep(B),[],[],Rep(A)}</c>.</item>
+ <item>If E is <c>try B of Cc_1 ; ... ; Cc_k after A end</c>,
+ where <c>B</c> and <c>A</c> are a bodies and
+ each <c>Cc_i</c> is a case clause then Rep(E) =
+ <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[],Rep(A)}</c>.</item>
+ <item>If E is <c>try B catch Tc_1 ; ... ; Tc_k after A end</c>,
+ where <c>B</c> and <c>A</c> are bodies and
+ each <c>Tc_i</c> is a catch clause then Rep(E) =
+ <c>{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}</c>.</item>
+ <item>If E is <c>try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n after A end</c>,
+ where <c>B</c> and <c>A</c> are a bodies,
+ each <c>Cc_i</c> is a case clause and
+ each <c>Tc_j</c> is a catch clause then
Rep(E) =
- <c><![CDATA[{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)],Rep(E_0),Rep(B_t)}]]></c>.</item>
- <item>If E is <c><![CDATA[fun Name / Arity]]></c>, then
- Rep(E) = <c><![CDATA[{'fun',LINE,{function,Name,Arity}}]]></c>.</item>
- <item>If E is <c><![CDATA[fun Module:Name/Arity]]></c>, then
- Rep(E) = <c><![CDATA[{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}]]></c>.
- (Before the R15 release: Rep(E) = <c><![CDATA[{'fun',LINE,{function,Module,Name,Arity}}]]></c>.)</item>
- <item>If E is <c><![CDATA[fun Fc_1 ; ... ; Fc_k end]]></c>
- where each <c><![CDATA[Fc_i]]></c> is a function clause then Rep(E) =
- <c><![CDATA[{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}]]></c>.</item>
- <item>If E is <c><![CDATA[fun Name Fc_1 ; ... ; Name Fc_k end]]></c>
- where <c><![CDATA[Name]]></c> is a variable and each
- <c><![CDATA[Fc_i]]></c> is a function clause then Rep(E) =
- <c><![CDATA[{named_fun,LINE,Name,[Rep(Fc_1), ..., Rep(Fc_k)]}]]></c>.
+ <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],Rep(A)}</c>.</item>
+ <item>If E is <c>receive Cc_1 ; ... ; Cc_k end</c>,
+ where each <c>Cc_i</c> is a case clause then Rep(E) =
+ <c>{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)]}</c>.</item>
+ <item>If E is <c>receive Cc_1 ; ... ; Cc_k after E_0 -> B_t end</c>,
+ where each <c>Cc_i</c> is a case clause,
+ <c>E_0</c> is an expression and <c>B_t</c> is a body, then Rep(E) =
+ <c>{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)],Rep(E_0),Rep(B_t)}</c>.</item>
+ <item>If E is <c>fun Name / Arity</c>, then
+ Rep(E) = <c>{'fun',LINE,{function,Name,Arity}}</c>.</item>
+ <item>If E is <c>fun Module:Name/Arity</c>, then Rep(E) =
+ <c>{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}</c>.
+ (Before the R15 release: Rep(E) =
+ <c>{'fun',LINE,{function,Module,Name,Arity}}</c>.)</item>
+ <item>If E is <c>fun Fc_1 ; ... ; Fc_k end</c>
+ where each <c>Fc_i</c> is a function clause then Rep(E) =
+ <c>{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}</c>.</item>
+ <item>If E is <c>fun Name Fc_1 ; ... ; Name Fc_k end</c>
+ where <c>Name</c> is a variable and each
+ <c>Fc_i</c> is a function clause then Rep(E) =
+ <c>{named_fun,LINE,Name,[Rep(Fc_1), ..., Rep(Fc_k)]}</c>.
</item>
- <item>If E is <c><![CDATA[query [E_0 || W_1, ..., W_k] end]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{'query',LINE,{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}}]]></c>.
- For Rep(W), see below.</item>
- <item>If E is <c><![CDATA[E_0.Field]]></c>, a Mnesia record access
- inside a query, then
- Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Rep(Field)}]]></c>.</item>
- <item>If E is <c><![CDATA[( E_0 )]]></c>, then
- Rep(E) = <c><![CDATA[Rep(E_0)]]></c>,
- i.e., parenthesized expressions cannot be distinguished from their bodies.</item>
+ <item>If E is <c>( E_0 )</c>, then
+ Rep(E) = <c>Rep(E_0)</c>, that is, parenthesized
+ expressions cannot be distinguished from their bodies.</item>
</list>
<section>
- <title>Generators and filters</title>
- <p>When W is a generator or a filter (in the body of a list or binary comprehension), then:</p>
+ <title>Generators and Filters</title>
+ <p>When W is a generator or a filter (in the body of a list or
+ binary comprehension), then:</p>
<list type="bulleted">
- <item>If W is a generator <c><![CDATA[P <- E]]></c>, where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[E]]></c>
- is an expression, then
- Rep(W) = <c><![CDATA[{generate,LINE,Rep(P),Rep(E)}]]></c>.</item>
- <item>If W is a generator <c><![CDATA[P <= E]]></c>, where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[E]]></c>
- is an expression, then
- Rep(W) = <c><![CDATA[{b_generate,LINE,Rep(P),Rep(E)}]]></c>.</item>
- <item>If W is a filter <c><![CDATA[E]]></c>, which is an expression, then
- Rep(W) = <c><![CDATA[Rep(E)]]></c>.</item>
+ <item>If W is a generator <c>P &lt;- E</c>, where <c>P</c> is
+ a pattern and <c>E</c> is an expression, then
+ Rep(W) = <c>{generate,LINE,Rep(P),Rep(E)}</c>.</item>
+ <item>If W is a generator <c>P &lt;= E</c>, where <c>P</c> is
+ a pattern and <c>E</c> is an expression, then
+ Rep(W) = <c>{b_generate,LINE,Rep(P),Rep(E)}</c>.</item>
+ <item>If W is a filter <c>E</c>, which is an expression, then
+ Rep(W) = <c>Rep(E)</c>.</item>
</list>
</section>
<section>
- <title>Binary element type specifiers</title>
+ <title>Binary Element Type Specifiers</title>
<p>A type specifier list TSL for a binary element is a sequence of type
- specifiers <c><![CDATA[TS_1 - ... - TS_k]]></c>.
- Rep(TSL) = <c><![CDATA[[Rep(TS_1), ..., Rep(TS_k)]]]></c>.</p>
+ specifiers <c>TS_1 - ... - TS_k</c>.
+ Rep(TSL) = <c>[Rep(TS_1), ..., Rep(TS_k)]</c>.</p>
<p>When TS is a type specifier for a binary element, then:</p>
<list type="bulleted">
- <item>If TS is an atom <c><![CDATA[A]]></c>, Rep(TS) = <c><![CDATA[A]]></c>.</item>
- <item>If TS is a couple <c><![CDATA[A:Value]]></c> where <c><![CDATA[A]]></c> is an atom and <c><![CDATA[Value]]></c>
- is an integer, Rep(TS) = <c><![CDATA[{A, Value}]]></c>.</item>
+ <item>If TS is an atom <c>A</c>, then Rep(TS) = <c>A</c>.</item>
+ <item>If TS is a couple <c>A:Value</c> where <c>A</c> is an atom
+ and <c>Value</c> is an integer, then Rep(TS) =
+ <c>{A,Value}</c>.</item>
</list>
</section>
<section>
- <title>Map assoc and exact fields</title>
+ <title>Map Assoc and Exact Fields</title>
<p>When W is an assoc or exact field (in the body of a map), then:</p>
<list type="bulleted">
- <item>If W is an assoc field <c><![CDATA[K => V]]></c>, where
- <c><![CDATA[K]]></c> and <c><![CDATA[V]]></c> are both expressions,
- then Rep(W) = <c><![CDATA[{map_field_assoc,LINE,Rep(K),Rep(V)}]]></c>.
+ <item>If W is an assoc field <c>K => V</c>, where
+ <c>K</c> and <c>V</c> are both expressions,
+ then Rep(W) = <c>{map_field_assoc,LINE,Rep(K),Rep(V)}</c>.
</item>
- <item>If W is an exact field <c><![CDATA[K := V]]></c>, where
- <c><![CDATA[K]]></c> and <c><![CDATA[V]]></c> are both expressions,
- then Rep(W) = <c><![CDATA[{map_field_exact,LINE,Rep(K),Rep(V)}]]></c>.
+ <item>If W is an exact field <c>K := V</c>, where
+ <c>K</c> and <c>V</c> are both expressions,
+ then Rep(W) = <c>{map_field_exact,LINE,Rep(K),Rep(V)}</c>.
</item>
</list>
</section>
@@ -361,112 +394,220 @@
<section>
<title>Clauses</title>
- <p>There are function clauses, if clauses, case clauses
+ <p>There are function clauses, if clauses, case clauses
and catch clauses.</p>
- <p>A clause <c><![CDATA[C]]></c> is one of the following alternatives:</p>
+ <p>A clause <c>C</c> is one of the following alternatives:</p>
<list type="bulleted">
- <item>If C is a function clause <c><![CDATA[( Ps ) -> B]]></c>
- where <c><![CDATA[Ps]]></c> is a pattern sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,Rep(Ps),[],Rep(B)}]]></c>.</item>
- <item>If C is a function clause <c><![CDATA[( Ps ) when Gs -> B]]></c>
- where <c><![CDATA[Ps]]></c> is a pattern sequence,
- <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is an if clause <c><![CDATA[Gs -> B]]></c>
- where <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[],Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is a case clause <c><![CDATA[P -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep(P)],[],Rep(B)}]]></c>.</item>
- <item>If C is a case clause <c><![CDATA[P when Gs -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern,
- <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[P -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[X : P -> B]]></c>
- where <c><![CDATA[X]]></c> is an atomic literal or a variable pattern,
- <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({X,P,_})],[],Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[P when Gs -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern, <c><![CDATA[Gs]]></c> is a guard sequence
- and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[X : P when Gs -> B]]></c>
- where <c><![CDATA[X]]></c> is an atomic literal or a variable pattern,
- <c><![CDATA[P]]></c> is a pattern, <c><![CDATA[Gs]]></c> is a guard sequence
- and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}]]></c>.</item>
+ <item>If C is a function clause <c>( Ps ) -> B</c>
+ where <c>Ps</c> is a pattern sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,Rep(Ps),[],Rep(B)}</c>.</item>
+ <item>If C is a function clause <c>( Ps ) when Gs -> B</c>
+ where <c>Ps</c> is a pattern sequence,
+ <c>Gs</c> is a guard sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is an if clause <c>Gs -> B</c>
+ where <c>Gs</c> is a guard sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[],Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is a case clause <c>P -> B</c>
+ where <c>P</c> is a pattern and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep(P)],[],Rep(B)}</c>.</item>
+ <item>If C is a case clause <c>P when Gs -> B</c>
+ where <c>P</c> is a pattern,
+ <c>Gs</c> is a guard sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>P -> B</c>
+ where <c>P</c> is a pattern and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>X : P -> B</c>
+ where <c>X</c> is an atomic literal or a variable pattern,
+ <c>P</c> is a pattern and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],[],Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>P when Gs -> B</c>
+ where <c>P</c> is a pattern, <c>Gs</c> is a guard sequence
+ and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>X : P when Gs -> B</c>
+ where <c>X</c> is an atomic literal or a variable pattern,
+ <c>P</c> is a pattern, <c>Gs</c> is a guard sequence
+ and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}</c>.</item>
</list>
</section>
<section>
<title>Guards</title>
- <p>A guard sequence Gs is a sequence of guards <c><![CDATA[G_1; ...; G_k]]></c>, and
- Rep(Gs) = <c><![CDATA[[Rep(G_1), ..., Rep(G_k)]]]></c>. If the guard sequence is
- empty, Rep(Gs) = <c><![CDATA[[]]]></c>.</p>
- <p>A guard G is a nonempty sequence of guard tests <c><![CDATA[Gt_1, ..., Gt_k]]></c>, and
- Rep(G) = <c><![CDATA[[Rep(Gt_1), ..., Rep(Gt_k)]]]></c>.</p>
- <p>A guard test <c><![CDATA[Gt]]></c> is one of the following alternatives:</p>
+ <p>A guard sequence Gs is a sequence of guards <c>G_1; ...; G_k</c>, and
+ Rep(Gs) = <c>[Rep(G_1), ..., Rep(G_k)]</c>. If the guard sequence is
+ empty, Rep(Gs) = <c>[]</c>.</p>
+ <p>A guard G is a nonempty sequence of guard tests
+ <c>Gt_1, ..., Gt_k</c>, and Rep(G) =
+ <c>[Rep(Gt_1), ..., Rep(Gt_k)]</c>.</p>
+ <p>A guard test <c>Gt</c> is one of the following alternatives:</p>
<list type="bulleted">
<item>If Gt is an atomic literal L, then Rep(Gt) = Rep(L).</item>
- <item>If Gt is a variable pattern <c><![CDATA[V]]></c>, then
- Rep(Gt) = <c><![CDATA[{var,LINE,A}]]></c>,
- where A is an atom with a printname consisting of the same characters as
- <c><![CDATA[V]]></c>.</item>
- <item>If Gt is a tuple skeleton <c><![CDATA[{Gt_1, ..., Gt_k}]]></c>, then
- Rep(Gt) = <c><![CDATA[{tuple,LINE,[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[[]]]></c>, then
- Rep(Gt) = <c><![CDATA[{nil,LINE}]]></c>.</item>
- <item>If Gt is a cons skeleton <c><![CDATA[[Gt_h | Gt_t]]]></c>, then
- Rep(Gt) = <c><![CDATA[{cons,LINE,Rep(Gt_h),Rep(Gt_t)}]]></c>.</item>
- <item>If Gt is a binary constructor <c><![CDATA[<<Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k>>]]></c>, then
- Rep(Gt) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(Gt_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(Gt_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ <item>If Gt is a variable pattern <c>V</c>, then
+ Rep(Gt) = <c>{var,LINE,A}</c>, where A is an atom with
+ a printname consisting of the same characters as <c>V</c>.</item>
+ <item>If Gt is a tuple skeleton <c>{Gt_1, ..., Gt_k}</c>, then
+ Rep(Gt) = <c>{tuple,LINE,[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item>
+ <item>If Gt is <c>[]</c>, then Rep(Gt) = <c>{nil,LINE}</c>.</item>
+ <item>If Gt is a cons skeleton <c>[Gt_h | Gt_t]</c>, then
+ Rep(Gt) = <c>{cons,LINE,Rep(Gt_h),Rep(Gt_t)}</c>.</item>
+ <item>If Gt is a binary constructor
+ <c>&lt;&lt;Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k>></c>, then
+ Rep(Gt) = <c>{bin,LINE,[{bin_element,LINE,Rep(Gt_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(Gt_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
For Rep(TSL), see above.
- An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
- (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
- <item>If Gt is <c><![CDATA[Gt_1 Op Gt_2]]></c>, where <c><![CDATA[Op]]></c>
- is a binary operator, then Rep(Gt) = <c><![CDATA[{op,LINE,Op,Rep(Gt_1),Rep(Gt_2)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[Op Gt_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator, then
- Rep(Gt) = <c><![CDATA[{op,LINE,Op,Rep(Gt_0)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[#Name{Field_1=Gt_1, ..., Field_k=Gt_k}]]></c>, then
+ An omitted <c>Size</c> is represented by <c>default</c>.
+ An omitted <c>TSL</c> (type specifier list) is represented
+ by <c>default</c>.</item>
+ <item>If Gt is <c>Gt_1 Op Gt_2</c>, where <c>Op</c>
+ is a binary operator, then Rep(Gt) =
+ <c>{op,LINE,Op,Rep(Gt_1),Rep(Gt_2)}</c>.</item>
+ <item>If Gt is <c>Op Gt_0</c>, where <c>Op</c> is a unary operator, then
+ Rep(Gt) = <c>{op,LINE,Op,Rep(Gt_0)}</c>.</item>
+ <item>If Gt is <c>#Name{Field_1=Gt_1, ..., Field_k=Gt_k}</c>, then
Rep(E) =
- <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(Gt_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(Gt_k)}]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[#Name.Field]]></c>, then
- Rep(Gt) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[Gt_0#Name.Field]]></c>, then
- Rep(Gt) = <c><![CDATA[{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[A(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A]]></c> is an atom, then
- Rep(Gt) = <c><![CDATA[{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[A_m:A(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A_m]]></c> is
- the atom <c><![CDATA[erlang]]></c> and <c><![CDATA[A]]></c> is an atom or an operator, then
- Rep(Gt) = <c><![CDATA[{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[{A_m,A}(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A_m]]></c> is
- the atom <c><![CDATA[erlang]]></c> and <c><![CDATA[A]]></c> is an atom or an operator, then
- Rep(Gt) = <c><![CDATA[{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[( Gt_0 )]]></c>, then
- Rep(Gt) = <c><![CDATA[Rep(Gt_0)]]></c>,
- i.e., parenthesized guard tests cannot be distinguished from their bodies.</item>
+ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(Gt_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(Gt_k)}]}</c>.</item>
+ <item>If Gt is <c>#Name.Field</c>, then
+ Rep(Gt) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item>
+ <item>If Gt is <c>Gt_0#Name.Field</c>, then
+ Rep(Gt) = <c>{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}</c>.</item>
+ <item>If Gt is <c>A(Gt_1, ..., Gt_k)</c>, where <c>A</c> is an atom, then
+ Rep(Gt) = <c>{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item>
+ <item>If Gt is <c>A_m:A(Gt_1, ..., Gt_k)</c>, where <c>A_m</c> is
+ the atom <c>erlang</c> and <c>A</c> is an atom or an operator, then
+ Rep(Gt) = <c>{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item>
+ <item>If Gt is <c>{A_m,A}(Gt_1, ..., Gt_k)</c>, where <c>A_m</c> is
+ the atom <c>erlang</c> and <c>A</c> is an atom or an operator, then
+ Rep(Gt) = <c>{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.
+ </item>
+ <item>If Gt is <c>( Gt_0 )</c>, then
+ Rep(Gt) = <c>Rep(Gt_0)</c>, that is, parenthesized
+ guard tests cannot be distinguished from their bodies.</item>
</list>
<p>Note that every guard test has the same source form as some expression,
and is represented the same way as the corresponding expression.</p>
</section>
<section>
- <title>The abstract format after preprocessing</title>
- <p>The compilation option <c><![CDATA[debug_info]]></c> can be given to the
- compiler to have the abstract code stored in
- the <c><![CDATA[abstract_code]]></c> chunk in the BEAM file
+ <title>Types</title>
+ <list type="bulleted">
+ <item>If T is an annotated type <c>Anno :: Type</c>,
+ where <c>Anno</c> is a variable and
+ <c>Type</c> is a type, then Rep(T) =
+ <c>{ann_type,LINE,[Rep(Anno),Rep(Type)]}</c>.</item>
+ <item>If T is an atom or integer literal L, then Rep(T) = Rep(L).
+ </item>
+ <item>If T is <c>L Op R</c>,
+ where <c>Op</c> is a binary operator and <c>L</c> and <c>R</c>
+ are types (this is an occurrence of an expression that can be
+ evaluated to an integer at compile time), then
+ Rep(T) = <c>{op,LINE,Op,Rep(L),Rep(R)}</c>.</item>
+ <item>If T is <c>Op A</c>, where <c>Op</c> is a
+ unary operator and <c>A</c> is a type (this is an occurrence of
+ an expression that can be evaluated to an integer at compile time),
+ then Rep(T) = <c>{op,LINE,Op,Rep(A)}</c>.</item>
+ <item>If T is a bitstring type <c>&lt;&lt;_:M,_:_*N>></c>,
+ where <c>M</c> and <c>N</c> are singleton integer types, then Rep(T) =
+ <c>{type,LINE,binary,[Rep(M),Rep(N)]}</c>.</item>
+ <item>If T is the empty list type <c>[]</c>, then Rep(T) =
+ <c>{type,Line,nil,[]}</c>.</item>
+ <item>If T is a fun type <c>fun()</c>, then Rep(T) =
+ <c>{type,LINE,'fun',[]}</c>.</item>
+ <item>If T is a fun type <c>fun((...) -> B)</c>,
+ where <c>B</c> is a type, then
+ Rep(T) = <c>{type,LINE,'fun',[{type,LINE,any},Rep(B)]}</c>.
+ </item>
+ <item>If T is a fun type <c>fun(Ft)</c>, where
+ <c>Ft</c> is a function type,
+ then Rep(T) = <c>Rep(Ft)</c>.</item>
+ <item>If T is an integer range type <c>L .. H</c>,
+ where <c>L</c> and <c>H</c> are singleton integer types, then
+ Rep(T) = <c>{type,LINE,range,[Rep(L),Rep(H)]}</c>.</item>
+ <item>If T is a map type <c>map()</c>, then Rep(T) =
+ <c>{type,LINE,map,any}</c>.</item>
+ <item>If T is a map type <c>#{P_1, ..., P_k}</c>, where each
+ <c>P_i</c> is a map pair type, then Rep(T) =
+ <c>{type,LINE,map,[Rep(P_1), ..., Rep(P_k)]}</c>.</item>
+ <item>If T is a map pair type <c>K => V</c>, where
+ <c>K</c> and <c>V</c> are types, then Rep(T) =
+ <c>{type,LINE,map_field_assoc,[Rep(K),Rep(V)]}</c>.</item>
+ <item>If T is a predefined (or built-in) type <c>N(A_1, ..., A_k)</c>,
+ where each <c>A_i</c> is a type, then Rep(T) =
+ <c>{type,LINE,N,[Rep(A_1), ..., Rep(A_k)]}</c>.</item>
+ <item>If T is a record type <c>#Name{F_1, ..., F_k}</c>,
+ where each <c>F_i</c> is a record field type, then Rep(T) =
+ <c>{type,LINE,record,[Rep(Name),Rep(F_1), ..., Rep(F_k)]}</c>.
+ </item>
+ <item>If T is a record field type <c>Name :: Type</c>,
+ where <c>Type</c> is a type, then Rep(T) =
+ <c>{type,LINE,field_type,[Rep(Name),Rep(Type)]}</c>.</item>
+ <item>If T is a remote type <c>M:N(A_1, ..., A_k)</c>, where
+ each <c>A_i</c> is a type, then Rep(T) =
+ <c>{remote_type,LINE,[Rep(M),Rep(N),[Rep(A_1), ..., Rep(A_k)]]}</c>.
+ </item>
+ <item>If T is a tuple type <c>tuple()</c>, then Rep(T) =
+ <c>{type,LINE,tuple,any}</c>.</item>
+ <item>If T is a tuple type <c>{A_1, ..., A_k}</c>, where
+ each <c>A_i</c> is a type, then Rep(T) =
+ <c>{type,LINE,tuple,[Rep(A_1), ..., Rep(A_k)]}</c>.</item>
+ <item>If T is a type union <c>T_1 | ... | T_k</c>,
+ where each <c>T_i</c> is a type, then Rep(T) =
+ <c>{type,LINE,union,[Rep(T_1), ..., Rep(T_k)]}</c>.</item>
+ <item>If T is a type variable <c>V</c>, then Rep(T) =
+ <c>{var,LINE,A}</c>, where <c>A</c> is an atom with a printname
+ consisting of the same characters as <c>V</c>. A type variable
+ is any variable except underscore (<c>_</c>).</item>
+ <item>If T is a user-defined type <c>N(A_1, ..., A_k)</c>,
+ where each <c>A_i</c> is a type, then Rep(T) =
+ <c>{user_type,LINE,N,[Rep(A_1), ..., Rep(A_k)]}</c>.</item>
+ <item>If T is <c>( T_0 )</c>, then Rep(T) = <c>Rep(T_0)</c>,
+ that is, parenthesized types cannot be distinguished from their
+ bodies.</item>
+ </list>
+
+ <section>
+ <title>Function Types</title>
+ <list type="bulleted">
+ <item>If Ft is a constrained function type <c>Ft_1 when Fc</c>,
+ where <c>Ft_1</c> is a function type and
+ <c>Fc</c> is a function constraint, then Rep(T) =
+ <c>{type,LINE,bounded_fun,[Rep(Ft_1),Rep(Fc)]}</c>.</item>
+ <item>If Ft is a function type <c>(A_1, ..., A_n) -> B</c>,
+ where each <c>A_i</c> and <c>B</c> are types, then
+ Rep(Ft) = <c>{type,LINE,'fun',[{type,LINE,product,[Rep(A_1),
+ ..., Rep(A_n)]},Rep(B)]}</c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Function Constraints</title>
+ <p>A function constraint Fc is a nonempty sequence of constraints
+ <c>C_1, ..., C_k</c>, and
+ Rep(Fc) = <c>[Rep(C_1), ..., Rep(C_k)]</c>.</p>
+ <list type="bulleted">
+ <item>If C is a constraint <c>is_subtype(V, T)</c> or <c>V :: T</c>,
+ where <c>V</c> is a type variable and <c>T</c> is a type, then
+ Rep(C) = <c>{type,LINE,constraint,[{atom,LINE,is_subtype},[Rep(V),Rep(T)]]}</c>.
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>The Abstract Format After Preprocessing</title>
+ <p>The compilation option <c>debug_info</c> can be given to the
+ compiler to have the abstract code stored in
+ the <c>abstract_code</c> chunk in the BEAM file
(for debugging purposes).</p>
- <p>In OTP R9C and later, the <c><![CDATA[abstract_code]]></c> chunk will
+ <p>In OTP R9C and later, the <c>abstract_code</c> chunk will
contain</p>
- <p><c><![CDATA[{raw_abstract_v1,AbstractCode}]]></c></p>
- <p>where <c><![CDATA[AbstractCode]]></c> is the abstract code as described
+ <p><c>{raw_abstract_v1,AbstractCode}</c></p>
+ <p>where <c>AbstractCode</c> is the abstract code as described
in this document.</p>
<p>In releases of OTP prior to R9C, the abstract code after some more
processing was stored in the BEAM file. The first element of the
- tuple would be either <c><![CDATA[abstract_v1]]></c> (R7B) or <c><![CDATA[abstract_v2]]></c>
+ tuple would be either <c>abstract_v1</c> (R7B) or <c>abstract_v2</c>
(R8B).</p>
</section>
</chapter>
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index e4912576f7..2263302707 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/erts/doc/src/book.xml b/erts/doc/src/book.xml
index dc02edc5c6..12eda03ee5 100644
--- a/erts/doc/src/book.xml
+++ b/erts/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/communication.xml b/erts/doc/src/communication.xml
index 02040c9edb..3deea3e4af 100644
--- a/erts/doc/src/communication.xml
+++ b/erts/doc/src/communication.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml
index 2b5fc877c3..61c9159823 100644
--- a/erts/doc/src/crash_dump.xml
+++ b/erts/doc/src/crash_dump.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -55,10 +56,12 @@
emulator or the operating system can be reconfigured to avoid the
crash, which is why interpreting the crash dump correctly is
important.</p>
+ <p>On systems that support OS signals, it is also possible to stop
+ the runtime system and generate a crash dump by sending the SIGUSR1.</p>
<p>The erlang crash dump is a readable text file, but it might not be
very easy to read. Using the Crashdump Viewer tool in the
<c><![CDATA[observer]]></c> application will simplify the task. This is an
- HTML based tool for browsing Erlang crash dumps.</p>
+ wx-widget based tool for browsing Erlang crash dumps.</p>
<section>
<marker id="general_info"></marker>
@@ -66,8 +69,9 @@
<p>The first part of the dump shows the creation time for the dump,
a slogan indicating the reason for the dump, the system version,
of the node from which the dump originates, the compile time of
- the emulator running the originating node and the number of
- atoms in the atom table.
+ the emulator running the originating node, the number of
+ atoms in the atom table and the runtime system thread that caused
+ the crash dump to happen.
</p>
<section>
@@ -85,22 +89,20 @@
operating system.</p>
<list type="bulleted">
<item>"<em>&lt;A&gt;</em>: Cannot allocate <em>&lt;N&gt;</em>
- bytes of memory (of type "<em>&lt;T&gt;</em>", thread
- <em>&lt;I&gt;</em>em>)." - The system has run out of memory. &lt;A&gt;
- is the allocator that failed to allocate memory, &lt;N&gt; is the
- number of bytes that &lt;A&gt; tried to allocate, &lt;T&gt; is the
- memory block type that the memory was needed for, and &lt;I&gt; is the
- thread identifier. The most common case is that a process stores huge
- amounts of data. In this case &lt;T&gt; is most often
- <c><![CDATA[heap]]></c>, <c><![CDATA[old_heap]]></c>,
- <c><![CDATA[heap_frag]]></c>, or <c><![CDATA[binary]]></c>.
- For more information on allocators see
- <seealso marker="erts_alloc">erts_alloc(3)</seealso>.</item>
+ bytes of memory (of type "<em>&lt;T&gt;</em>")." - The system
+ has run out of memory. &lt;A&gt; is the allocator that failed
+ to allocate memory, &lt;N&gt; is the number of bytes that
+ &lt;A&gt; tried to allocate, and &lt;T&gt; is the memory block
+ type that the memory was needed for. The most common case is
+ that a process stores huge amounts of data. In this case
+ &lt;T&gt; is most often <c><![CDATA[heap]]></c>, <c><![CDATA[old_heap]]></c>,
+ <c><![CDATA[heap_frag]]></c>, or <c><![CDATA[binary]]></c>. For more information on
+ allocators see
+ <seealso marker="erts_alloc">erts_alloc(3)</seealso>.</item>
<item>"<em>&lt;A&gt;</em>: Cannot reallocate <em>&lt;N&gt;</em>
- bytes of memory (of type "<em>&lt;T&gt;</em>", thread
- <em>&lt;I&gt;</em>em>)." - Same as above with the exception that memory
- was being reallocated instead of being allocated when the system ran
- out of memory.</item>
+ bytes of memory (of type "<em>&lt;T&gt;</em>")." - Same as
+ above with the exception that memory was being reallocated
+ instead of being allocated when the system ran out of memory.</item>
<item>"Unexpected op code <em>N</em>" - Error in compiled
code, <c><![CDATA[beam]]></c> file damaged or error in the compiler.</item>
<item>"Module <em>Name</em> undefined" <c><![CDATA[|]]></c> "Function
@@ -170,6 +172,60 @@
</section>
<section>
+ <marker id="scheduler"></marker>
+ <title>Scheduler information</title>
+ <p>Under the tag <em>=scheduler</em> information about the current state
+ and statistics of the schedulers in the runtime system is displayed.
+ On OSs that do allow instant suspension of other threads, the data within
+ this section will reflect what the runtime system looks like at the moment
+ when the crash happens.</p>
+ <p>The following fields can exist for a process:</p>
+ <taglist>
+ <tag><em>=scheduler:id</em></tag>
+ <item>Header, states the scheduler identifier.</item>
+ <tag><em>Scheduler Sleep Info Flags</em></tag>
+ <item>If empty the scheduler was doing some work.
+ If not empty the scheduler is either in some state of sleep,
+ or suspended. This entry is only present in a SMP enabled emulator</item>
+ <tag><em>Scheduler Sleep Info Aux Work</em></tag>
+ <item>If not empty, a scheduler internal auxiliary work is scheduled
+ to be done.</item>
+ <tag><em>Current Port</em></tag>
+ <item>The port identifier of the port that is currently being
+ executed by the scheduler.</item>
+ <tag><em>Current Process</em></tag>
+ <item>The process identifier of the process that is currently being
+ executed by the scheduler. If there is such a process this entry is
+ followed by the <em>State</em>,<em>Internal State</em>,
+ <em>Program Counter</em>, <em>CP</em> of that same process. See
+ <seealso marker="#processes">Process Information</seealso> for a
+ description what the different entries mean. Keep in mind that
+ this is a snapshot of what the entries are exactly when the crash
+ dump is starting to be generated. Therefore they will most likely
+ be different (and more telling) then the entries for the same
+ processes found in the <em>=proc</em> section. If there is no currently
+ running process, only the <em>Current Process</em> entry will be printed.
+ </item>
+ <tag><em>Current Process Limited Stack Trace</em></tag>
+ <item>This entry only shows up if there is a current process. It is very
+ similar to <seealso marker="#proc_data"><em>=proc_stack</em></seealso>,
+ except that only the function frames are printed (i.e. the stack variables
+ are omited). It is also limited to only print the top and bottom part
+ of the stack. If the stack is small (less that 512 slots) then the
+ entire stack will be printed. If not, an entry stating
+ <code>skipping ## slots</code> will be printed where ## is
+ replaced by the number of slots that has been skipped.</item>
+ <tag><em>Run Queue</em></tag>
+ <item>Displays statistics about how many processes and ports
+ of different priorities are scheduled on this scheduler.</item>
+ <tag><em>** crashed **</em></tag>
+ <item>This entry is normally not printed. It signifies that getting
+ the rest of the information about this scheduler failed for some reason.
+ </item>
+ </taglist>
+ </section>
+
+ <section>
<marker id="memory"></marker>
<title>Memory information</title>
<p>Under the tag <em>=memory</em> you will find information similar
@@ -249,9 +305,6 @@
<tag><em>Last scheduled in for | Current call</em></tag>
<item>The current function of the process. These fields will not
always exist.</item>
- <tag><em>Run queue</em></tag>
- <item>The identifier of the scheduler run queue in which the process is
- running.</item>
<tag><em>Spawned by</em></tag>
<item>The parent of the process, i.e. the process which executed
<c><![CDATA[spawn]]></c> or <c><![CDATA[spawn_link]]></c>.</item>
@@ -314,6 +367,9 @@
<item>The number of live argument registers. The argument registers,
if any are live, will follow. These may contain the arguments
of the function if they are not yet moved to the stack.</item>
+ <item><em>Internal State</em></item>
+ <item>A more detailed internal represantation of the state of
+ this process.</item>
</taglist>
<p>See also the section about <seealso marker="#proc_data">process data</seealso>.</p>
</section>
@@ -339,18 +395,38 @@
<tag><em>Name</em></tag>
<item>The name of the table, regardless of whether it is a
<c><![CDATA[named_table]]></c> or not.</item>
- <tag><em>Buckets</em></tag>
+ <tag><em>Hash table, Buckets</em></tag>
<item>This occurs if the table is a hash table, i.e. if it is not an
<c><![CDATA[ordered_set]]></c>.</item>
+ <tag><em>Hash table, Chain Length</em></tag>
+ <item>Only applicable for hash tables. Contains statistics about the
+ hash table, such as the max, min and avg chain length. Having a max much
+ larger than the avg, and a std dev much larger that
+ the expected std dev is a sign that the hashing of the terms is
+ behaving badly for some reason.</item>
<tag><em>Ordered set (AVL tree), Elements</em></tag>
<item>This occurs only if the table is an <c><![CDATA[ordered_set]]></c>. (The
number of elements is the same as the number of objects in the
table.)</item>
+ <tag><em>Fixed</em></tag>
+ <item>If the table is fixed using ets:safe_fixtable or some internal
+ mechanism.</item>
<tag><em>Objects</em></tag>
<item>The number of objects in the table</item>
<tag><em>Words</em></tag>
<item>The number of words (usually 4 bytes/word) allocated to data
in the table.</item>
+ <tag><em>Type</em></tag>
+ <item>The type of the table, i.e. <c>set</c>, <c>bag</c>,
+ <c>dublicate_bag</c> or <c>ordered_set</c>.</item>
+ <tag><em>Compressed</em></tag>
+ <item>If this table was compressed.</item>
+ <tag><em>Protection</em></tag>
+ <item>The protection of this table.</item>
+ <tag><em>Write Concurrency</em></tag>
+ <item>If write_concurrency was enabled for this table.</item>
+ <tag><em>Read Concurrency</em></tag>
+ <item>If read_concurrency was enabled for this table.</item>
</taglist>
</section>
diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml
index 616703fdef..a68e87d3b3 100644
--- a/erts/doc/src/driver.xml
+++ b/erts/doc/src/driver.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
index b34ca136f3..bad20d6343 100644
--- a/erts/doc/src/driver_entry.xml
+++ b/erts/doc/src/driver_entry.xml
@@ -4,20 +4,21 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -125,7 +126,7 @@
<section>
<title>DATA TYPES</title>
<taglist>
- <tag><b>ErlDrvEntry</b></tag>
+ <tag><em>ErlDrvEntry</em></tag>
<item>
<p/>
<code type="none">
@@ -210,7 +211,7 @@ typedef struct erl_drv_entry {
number &gt;= 0 or a pointer, or if the driver can't be started,
one of three error codes should be returned:</p>
<p>ERL_DRV_ERROR_GENERAL - general error, no error code</p>
- <p>ERL_DRV_ERROR_ERRNO - error with error code in erl_errno</p>
+ <p>ERL_DRV_ERROR_ERRNO - error with error code in <c>errno</c></p>
<p>ERL_DRV_ERROR_BADARG - error, badarg</p>
<p>If an error code is returned, the port isn't started.</p>
</item>
@@ -234,6 +235,7 @@ typedef struct erl_drv_entry {
</item>
<tag><marker id="ready_input"/>void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event)</tag>
+ <item/>
<tag><marker id="ready_output"/>void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event)</tag>
<item>
<p>This is called when a driver event (given in the
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
index 25f819ab50..7f61804bea 100644
--- a/erts/doc/src/epmd.xml
+++ b/erts/doc/src/epmd.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -36,7 +37,7 @@
<comsummary>
<p>Erlang Port Mapper Daemon</p>
<taglist>
- <tag><c><![CDATA[epmd [-d|-debug] [DbgExtra...] [-port No] [-daemon] [-relaxed_command_check]]]></c></tag>
+ <tag><c><![CDATA[epmd [-d|-debug] [DbgExtra...] [-address Addresses] [-port No] [-daemon] [-relaxed_command_check]]]></c></tag>
<item>
<p>Starts the port mapper daemon</p>
</item>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index f08467bfc6..ed3e7e34c4 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -4,20 +4,21 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -137,7 +138,7 @@
see <seealso marker="kernel:app">app(4)</seealso> and
<seealso marker="kernel:application">application(3)</seealso>.</p>
</item>
- <tag><marker id="args_file"><c><![CDATA[-args_file FileName]]></c></marker></tag>
+ <tag><marker id="args_file"/><c><![CDATA[-args_file FileName]]></c></tag>
<item>
<p>Command line arguments are read from the file <c><![CDATA[FileName]]></c>.
The arguments read from the file replace the
@@ -202,7 +203,7 @@
<seealso marker="kernel:app">app(4)</seealso> and
<seealso marker="kernel:application">application(3)</seealso>.</p>
</item>
- <tag><marker id="connect_all"><c><![CDATA[-connect_all false]]></c></marker></tag>
+ <tag><marker id="connect_all"/><c><![CDATA[-connect_all false]]></c></tag>
<item>
<p>If this flag is present, <c><![CDATA[global]]></c> will not maintain a
fully connected network of distributed Erlang nodes, and then
@@ -287,7 +288,7 @@
<p>Makes <c><![CDATA[init]]></c> write some debug information while
interpreting the boot script.</p>
</item>
- <tag><marker id="instr"><c><![CDATA[-instr]]></c>(emulator flag)</marker></tag>
+ <tag><marker id="instr"/><c><![CDATA[-instr]]></c>(emulator flag)</tag>
<item>
<p>Selects an instrumented Erlang runtime system (virtual
machine) to run, instead of the ordinary one. When running an
@@ -370,7 +371,7 @@
path, similar to <c><![CDATA[code:add_pathsa/1]]></c>. See
<seealso marker="kernel:code">code(3)</seealso>.
As an alternative to <c>-pa</c>, if several directories are
- to be prepended to the code and the directories have a
+ to be prepended to the code path and the directories have a
common parent directory, that parent directory could be
specified in the <c>ERL_LIBS</c> environment variable.
See <seealso marker="kernel:code">code(3)</seealso>.</p>
@@ -381,6 +382,33 @@
similar to <c><![CDATA[code:add_pathsz/1]]></c>. See
<seealso marker="kernel:code">code(3)</seealso>.</p>
</item>
+ <tag><c><![CDATA[-path Dir1 Dir2 ...]]></c></tag>
+ <item>
+ <p>Replaces the path specified in the boot script. See
+ <seealso marker="sasl:script">script(4)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-proto_dist Proto]]></c></tag>
+ <item>
+ <p>Specify a protocol for Erlang distribution.</p>
+ <taglist>
+ <tag><c>inet_tcp</c></tag>
+ <item>
+ <p>TCP over IPv4 (the default)</p>
+ </item>
+ <tag><c>inet_tls</c></tag>
+ <item>
+ <p>distribution over TLS/SSL</p>
+ </item>
+ <tag><c>inet6_tcp</c></tag>
+ <item>
+ <p>TCP over IPv6</p>
+ </item>
+ </taglist>
+ <p>For example, to start up IPv6 distributed nodes:</p>
+<pre>
+% <input>erl -name [email protected] -proto_dist inet6_tcp</input>
+</pre>
+ </item>
<tag><c><![CDATA[-remsh Node]]></c></tag>
<item>
<p>Starts Erlang with a remote shell connected to <c><![CDATA[Node]]></c>.</p>
@@ -435,7 +463,7 @@
flag and those running with the <c><![CDATA[-name]]></c> flag, as node
names must be unique in distributed Erlang systems.</p>
</item>
- <tag><marker id="smp"><c><![CDATA[-smp [enable|auto|disable]]]></c></marker></tag>
+ <tag><marker id="smp"/><c><![CDATA[-smp [enable|auto|disable]]]></c></tag>
<item>
<p><c>-smp enable</c> and <c>-smp</c> starts the Erlang runtime
system with SMP support enabled. This may fail if no runtime
@@ -461,7 +489,7 @@
<p><c><![CDATA[erl]]></c> invokes the code for the Erlang emulator (virtual
machine), which supports the following flags:</p>
<taglist>
- <tag><marker id="async_thread_stack_size"><c><![CDATA[+a size]]></c></marker></tag>
+ <tag><marker id="async_thread_stack_size"/><c><![CDATA[+a size]]></c></tag>
<item>
<p>Suggested stack size, in kilowords, for threads in the
async-thread pool. Valid range is 16-8192 kilowords. The
@@ -476,7 +504,7 @@
suggestion, and it might even be ignored on some
platforms.</p>
</item>
- <tag><marker id="async_thread_pool_size"><c><![CDATA[+A size]]></c></marker></tag>
+ <tag><marker id="async_thread_pool_size"/><c><![CDATA[+A size]]></c></tag>
<item>
<p>Sets the number of threads in async thread pool, valid range
is 0-1024. If thread support is available, the default is 10.</p>
@@ -495,24 +523,35 @@
<c><![CDATA[werl]]></c>, not <c><![CDATA[erl]]></c> (<c><![CDATA[oldshell]]></c>). Note also that
<c><![CDATA[Ctrl-Break]]></c> is used instead of <c><![CDATA[Ctrl-C]]></c> on Windows.</p>
</item>
- <tag><marker id="+c"><c><![CDATA[+c]]></c></marker></tag>
- <item>
- <p>Disable compensation for sudden changes of system time.</p>
- <p>Normally, <c><![CDATA[erlang:now/0]]></c> will not immediately reflect
- sudden changes in the system time, in order to keep timers
- (including <c><![CDATA[receive-after]]></c>) working. Instead, the time
- maintained by <c><![CDATA[erlang:now/0]]></c> is slowly adjusted towards
- the new system time. (Slowly means in one percent adjustments;
- if the time is off by one minute, the time will be adjusted
- in 100 minutes.)</p>
- <p>When the <c><![CDATA[+c]]></c> option is given, this slow adjustment
- will not take place. Instead <c><![CDATA[erlang:now/0]]></c> will always
- reflect the current system time. Note that timers are based
- on <c><![CDATA[erlang:now/0]]></c>. If the system time jumps, timers
- then time out at the wrong time.</p>
- <p><em>NOTE</em>: You can check whether the adjustment is enabled or
- disabled by calling
- <seealso marker="erlang#system_info_tolerant_timeofday">erlang:system_info(tolerant_timeofday)</seealso>.</p>
+ <tag><marker id="+c"/><c><![CDATA[+c true | false]]></c></tag>
+ <item>
+ <p>Enable or disable
+ <seealso marker="time_correction#Time_Correction">time correction</seealso>:</p>
+ <taglist>
+ <tag><c>true</c></tag>
+ <item><p>Enable time correction. This is the default if
+ time correction is supported on the specific platform.</p></item>
+
+ <tag><c>false</c></tag>
+ <item><p>Disable time correction.</p></item>
+ </taglist>
+ <p>For backwards compatibility, the boolean value can be omitted.
+ This is interpreted as <c>+c false</c>.
+ </p>
+ </item>
+ <tag><marker id="+C_"/><c><![CDATA[+C no_time_warp | single_time_warp | multi_time_warp]]></c></tag>
+ <item>
+ <p>Set
+ <seealso marker="time_correction#Time_Warp_Modes">time warp mode</seealso>:
+ </p>
+ <taglist>
+ <tag><c>no_time_warp</c></tag>
+ <item><p><seealso marker="time_correction#No_Time_Warp_Mode">No Time Warp Mode</seealso> (the default)</p></item>
+ <tag><c>single_time_warp</c></tag>
+ <item><p><seealso marker="time_correction#Single_Time_Warp_Mode">Single Time Warp Mode</seealso></p></item>
+ <tag><c>multi_time_warp</c></tag>
+ <item><p><seealso marker="time_correction#Multi_Time_Warp_Mode">Multi Time Warp Mode</seealso></p></item>
+ </taglist>
</item>
<tag><c><![CDATA[+d]]></c></tag>
<item>
@@ -528,7 +567,7 @@
produce a crash dump. On Unix systems, sending an emulator process
a SIGUSR1 signal will also force a crash dump.</p>
</item>
- <tag><marker id="+e"><c><![CDATA[+e Number]]></c></marker></tag>
+ <tag><marker id="+e"/><c><![CDATA[+e Number]]></c></tag>
<item>
<p>Set max number of ETS tables.</p>
</item>
@@ -613,7 +652,7 @@
information about the file names and line numbers.
</p>
</item>
- <tag><marker id="erts_alloc"><c><![CDATA[+MFlag Value]]></c></marker></tag>
+ <tag><marker id="erts_alloc"/><c><![CDATA[+MFlag Value]]></c></tag>
<item>
<p>Memory allocator specific flags, see
<seealso marker="erts_alloc">erts_alloc(3)</seealso> for
@@ -652,10 +691,10 @@
debugging.</item>
</taglist>
</item>
- <tag><marker id="+pc"/><marker id="printable_character_range"><c><![CDATA[+pc Range]]></c></marker></tag>
+ <tag><marker id="+pc"/><marker id="printable_character_range"/><c><![CDATA[+pc Range]]></c></tag>
<item>
<p>Sets the range of characters that the system will consider printable in heuristic detection of strings. This typically affects the shell, debugger and io:format functions (when ~tp is used in the format string).</p>
- <p>Currently two values for the <c>Range</c> are supported:
+ <p>Currently two values for the <c>Range</c> are supported:</p>
<taglist>
<tag><c>latin1</c></tag> <item>The default. Only characters
in the ISO-latin-1 range can be considered printable, which means
@@ -670,11 +709,10 @@
example your font does not cover all Unicode
characters.</item>
</taglist>
- </p>
<p>Se also <seealso marker="stdlib:io#printable_range/0">
io:printable_range/0</seealso>.</p>
</item>
- <tag><marker id="+P"/><marker id="max_processes"><c><![CDATA[+P Number|legacy]]></c></marker></tag>
+ <tag><marker id="+P"/><marker id="max_processes"/><c><![CDATA[+P Number|legacy]]></c></tag>
<item>
<p>Sets the maximum number of simultaneously existing processes for this
system if a <c>Number</c> is passed as value. Valid range for
@@ -694,7 +732,7 @@
circumstances be extremely expensive. The legacy algoritm is deprecated,
and the <c>legacy</c> option is scheduled for removal in OTP-R18.</p>
</item>
- <tag><marker id="+Q"/><marker id="max_ports"><c><![CDATA[+Q Number|legacy]]></c></marker></tag>
+ <tag><marker id="+Q"/><marker id="max_ports"/><c><![CDATA[+Q Number|legacy]]></c></tag>
<item>
<p>Sets the maximum number of simultaneously existing ports for this
system if a Number is passed as value. Valid range for <c>Number</c>
@@ -725,7 +763,7 @@
circumstances be extremely expensive. The legacy algoritm is deprecated,
and the <c>legacy</c> option is scheduled for removal in OTP-R18.</p>
</item>
- <tag><marker id="compat_rel"><c><![CDATA[+R ReleaseNumber]]></c></marker></tag>
+ <tag><marker id="compat_rel"/><c><![CDATA[+R ReleaseNumber]]></c></tag>
<item>
<p>Sets the compatibility mode.</p>
<p>The distribution mechanism is not backwards compatible by
@@ -745,7 +783,7 @@
<item>
<p>Force ets memory block to be moved on realloc.</p>
</item>
- <tag><marker id="+rg"><c><![CDATA[+rg ReaderGroupsLimit]]></c></marker></tag>
+ <tag><marker id="+rg"/><c><![CDATA[+rg ReaderGroupsLimit]]></c></tag>
<item>
<p>Limits the amount of reader groups used by read/write locks
optimized for read operations in the Erlang runtime system. By
@@ -763,7 +801,7 @@
schedulers to logical processors</seealso>, since the reader groups
are distributed better between schedulers.</p>
</item>
- <tag><marker id="+S"><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></marker></tag>
+ <tag><marker id="+S"/><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></tag>
<item>
<p>Sets the number of scheduler threads to create and scheduler
threads to set online when SMP support has been enabled. The maximum for
@@ -788,7 +826,7 @@
SMP support enabled (see the <seealso marker="#smp">-smp</seealso>
flag).</p>
</item>
- <tag><marker id="+SP"><c><![CDATA[+SP SchedulersPercentage:SchedulersOnlinePercentage]]></c></marker></tag>
+ <tag><marker id="+SP"/><c><![CDATA[+SP SchedulersPercentage:SchedulersOnlinePercentage]]></c></tag>
<item>
<p>Similar to <seealso marker="#+S">+S</seealso> but uses percentages to set the
number of scheduler threads to create, based on logical processors configured,
@@ -809,7 +847,7 @@
SMP support enabled (see the <seealso marker="#smp">-smp</seealso>
flag).</p>
</item>
- <tag><marker id="+SDcpu"><c><![CDATA[+SDcpu DirtyCPUSchedulers:DirtyCPUSchedulersOnline]]></c></marker></tag>
+ <tag><marker id="+SDcpu"/><c><![CDATA[+SDcpu DirtyCPUSchedulers:DirtyCPUSchedulersOnline]]></c></tag>
<item>
<p>Sets the number of dirty CPU scheduler threads to create and dirty
CPU scheduler threads to set online when threading support has been
@@ -833,7 +871,7 @@
enabled (it's disabled by default).
</p>
</item>
- <tag><marker id="+SDPcpu"><c><![CDATA[+SDPcpu DirtyCPUSchedulersPercentage:DirtyCPUSchedulersOnlinePercentage]]></c></marker></tag>
+ <tag><marker id="+SDPcpu"/><c><![CDATA[+SDPcpu DirtyCPUSchedulersPercentage:DirtyCPUSchedulersOnlinePercentage]]></c></tag>
<item>
<p>Similar to <seealso marker="#+SDcpu">+SDcpu</seealso> but uses percentages to set the
number of dirty CPU scheduler threads to create and number of dirty CPU scheduler threads
@@ -856,7 +894,7 @@
enabled (it's disabled by default).
</p>
</item>
- <tag><marker id="+SDio"><c><![CDATA[+SDio IOSchedulers]]></c></marker></tag>
+ <tag><marker id="+SDio"/><c><![CDATA[+SDio IOSchedulers]]></c></tag>
<item>
<p>Sets the number of dirty I/O scheduler threads to create when threading
support has been enabled. The valid range is 0-1024. By default, the number
@@ -874,7 +912,7 @@
<item>
<p>Scheduling specific flags.</p>
<taglist>
- <tag><marker id="+sbt"><c>+sbt BindType</c></marker></tag>
+ <tag><marker id="+sbt"/><c>+sbt BindType</c></tag>
<item>
<p>Set scheduler bind type.</p>
<p>Schedulers can also be bound using the
@@ -998,7 +1036,7 @@
<seealso marker="erlang#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
</p>
</item>
- <tag><marker id="+sbwt"><c>+sbwt none|very_short|short|medium|long|very_long</c></marker></tag>
+ <tag><marker id="+sbwt"/><c>+sbwt none|very_short|short|medium|long|very_long</c></tag>
<item>
<p>Set scheduler busy wait threshold. Default is <c>medium</c>.
The threshold determines how long schedulers should busy
@@ -1008,7 +1046,7 @@
without prior notice.
</p>
</item>
- <tag><marker id="+scl"><c>+scl true|false</c></marker></tag>
+ <tag><marker id="+scl"/><c>+scl true|false</c></tag>
<item>
<p>Enable or disable scheduler compaction of load. By default
scheduler compaction of load is enabled. When enabled, load
@@ -1025,7 +1063,7 @@
between schedulers.
</p>
</item>
- <tag><marker id="+sct"><c>+sct CpuTopology</c></marker></tag>
+ <tag><marker id="+sct"/><c>+sct CpuTopology</c></tag>
<item>
<list type="bulleted">
<item><c><![CDATA[<Id> = integer(); when 0 =< <Id> =< 65535]]></c></item>
@@ -1147,12 +1185,12 @@
<p>For more information, see
<seealso marker="erlang#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>.</p>
</item>
- <tag><marker id="+secio"><c>+secio true|false</c></marker></tag>
+ <tag><marker id="+secio"/><c>+secio true|false</c></tag>
<item>
<p>Enable or disable eager check I/O scheduling. The default
- is currently <c>false</c>, but will most likely be changed
- to <c>true</c> in OTP 18. The behaviour before this flag
- was introduced corresponds to <c>+secio false</c>.</p>
+ is currently <c>true</c>. The default was changed from <c>false</c>
+ to <c>true</c> as of erts version 7.0. The behaviour before this
+ flag was introduced corresponds to <c>+secio false</c>.</p>
<p>The flag effects when schedulers will check for I/O
operations possible to execute, and when such I/O operations
will execute. As the name of the parameter implies,
@@ -1164,7 +1202,7 @@
<p><seealso marker="erlang#system_info_eager_check_io"><c>erlang:system_info(eager_check_io)</c></seealso>
returns the value of this parameter used when starting the VM.</p>
</item>
- <tag><marker id="+sfwi"><c>+sfwi Interval</c></marker></tag>
+ <tag><marker id="+sfwi"/><c>+sfwi Interval</c></tag>
<item>
<p>Set scheduler forced wakeup interval. All run queues will
be scanned each <c>Interval</c> milliseconds. While there are
@@ -1173,12 +1211,12 @@
disables this feature, which also is the default.
</p>
<p>This feature has been introduced as a temporary workaround
- for lengthy executing native code, and native code that do not
+ for long-executing native code, and native code that does not
bump reductions properly in OTP. When these bugs have be fixed
the <c>+sfwi</c> flag will be removed.
</p>
</item>
- <tag><marker id="+stbt"><c>+stbt BindType</c></marker></tag>
+ <tag><marker id="+stbt"/><c>+stbt BindType</c></tag>
<item>
<p>Try to set scheduler bind type. The same as the
<seealso marker="#+sbt">+sbt</seealso> flag with the exception of
@@ -1186,7 +1224,7 @@
documentation of the <seealso marker="#+sbt">+sbt</seealso> flag.
</p>
</item>
- <tag><marker id="+sub"><c>+sub true|false</c></marker></tag>
+ <tag><marker id="+sub"/><c>+sub true|false</c></tag>
<item>
<p>Enable or disable
<seealso marker="erts:erlang#statistics_scheduler_wall_time">scheduler
@@ -1199,7 +1237,7 @@
balance scheduler utilization between schedulers. That is,
strive for equal scheduler utilization on all schedulers.
<br/>&nbsp;&nbsp;&nbsp;<c>+sub true</c> is only supported on
- systems where the runtime system detects and use a monotonically
+ systems where the runtime system detects and uses a monotonically
increasing high resolution clock. On other systems, the runtime
system will fail to start.
<br/>&nbsp;&nbsp;&nbsp;<c>+sub true</c> implies
@@ -1209,7 +1247,7 @@
utilization.
</p>
</item>
- <tag><marker id="+swct"><c>+swct very_eager|eager|medium|lazy|very_lazy</c></marker></tag>
+ <tag><marker id="+swct"/><c>+swct very_eager|eager|medium|lazy|very_lazy</c></tag>
<item>
<p>
Set scheduler wake cleanup threshold. Default is <c>medium</c>.
@@ -1223,7 +1261,7 @@
<p><em>NOTE:</em> This flag may be removed or changed at any time without prior notice.
</p>
</item>
- <tag><marker id="+sws"><c>+sws default|legacy</c></marker></tag>
+ <tag><marker id="+sws"/><c>+sws default|legacy</c></tag>
<item>
<p>
Set scheduler wakeup strategy. Default strategy changed in erts-5.10/OTP-R16A. This strategy was previously known as <c>proposal</c> in OTP-R15. The <c>legacy</c> strategy was used as default from R13 up to and including R15.
@@ -1231,7 +1269,7 @@
<p><em>NOTE:</em> This flag may be removed or changed at any time without prior notice.
</p>
</item>
- <tag><marker id="+swt"><c>+swt very_low|low|medium|high|very_high</c></marker></tag>
+ <tag><marker id="+swt"/><c>+swt very_low|low|medium|high|very_high</c></tag>
<item>
<p>Set scheduler wakeup threshold. Default is <c>medium</c>.
The threshold determines when to wake up sleeping schedulers
@@ -1245,7 +1283,7 @@
without prior notice.
</p>
</item>
- <tag><marker id="+spp"><c>+spp Bool</c></marker></tag>
+ <tag><marker id="+spp"/><c>+spp Bool</c></tag>
<item>
<p>Set default scheduler hint for port parallelism. If set to
<c>true</c>, the VM will schedule port tasks when doing so will
@@ -1261,7 +1299,7 @@
option to <seealso
marker="erlang#open_port/2">open_port/2</seealso></p>.
</item>
- <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag>
+ <tag><marker id="sched_thread_stack_size"/><c><![CDATA[+sss size]]></c></tag>
<item>
<p>Suggested stack size, in kilowords, for scheduler threads.
Valid range is 4-8192 kilowords. The default stack size
@@ -1269,11 +1307,11 @@
</item>
</taglist>
</item>
- <tag><marker id="+t"><c><![CDATA[+t size]]></c></marker></tag>
+ <tag><marker id="+t"/><c><![CDATA[+t size]]></c></tag>
<item>
<p>Set the maximum number of atoms the VM can handle. Default is 1048576.</p>
</item>
- <tag><marker id="+T"><c><![CDATA[+T Level]]></c></marker></tag>
+ <tag><marker id="+T"/><c><![CDATA[+T Level]]></c></tag>
<item>
<p>Enables modified timing and sets the modified timing level.
Currently valid range is 0-9. The timing of the runtime system
@@ -1311,13 +1349,14 @@
<item>
<p>Verbose.</p>
</item>
- <tag><c><![CDATA[+W w | i]]></c></tag>
+ <tag><c><![CDATA[+W w | i | e]]></c></tag>
<item>
<p>Sets the mapping of warning messages for <c><![CDATA[error_logger]]></c>.
Messages sent to the error logger using one of the warning
- routines can be mapped either to errors (default), warnings
- (<c><![CDATA[+W w]]></c>), or info reports (<c><![CDATA[+W i]]></c>). The current
- mapping can be retrieved using
+ routines can be mapped either to errors (<c><![CDATA[+W e]]></c>),
+ warnings (<c><![CDATA[+W w]]></c>), or info reports
+ (<c><![CDATA[+W i]]></c>). The default is warnings.
+ The current mapping can be retrieved using
<c><![CDATA[error_logger:warning_map/0]]></c>. See
<seealso marker="kernel:error_logger#warning_map/0">error_logger(3)</seealso>
for further information.</p>
@@ -1326,7 +1365,7 @@
<item>
<p>Miscellaneous flags.</p>
<taglist>
- <tag><marker id="+zdbbl"><c>+zdbbl size</c></marker></tag>
+ <tag><marker id="+zdbbl"/><c>+zdbbl size</c></tag>
<item>
<p>Set the distribution buffer busy limit
(<seealso marker="erlang#system_info_dist_buf_busy_limit">dist_buf_busy_limit</seealso>)
@@ -1339,6 +1378,18 @@
give lower latency and higher throughput at the expense
of higher memory usage.</p>
</item>
+ <tag><marker id="+zdntgc"/><c>+zdntgc time</c></tag>
+ <item>
+ <p>Set the delayed node table garbage collection time
+ (<seealso marker="erlang#system_info_delayed_node_table_gc">delayed_node_table_gc</seealso>)
+ in seconds. Valid values are either <c>infinity</c> or
+ an integer in the range [0-100000000]. Default is 60.</p>
+ <p>Node table entries that are not referred will linger
+ in the table for at least the amount of time that this
+ parameter determines. The lingering prevents repeated
+ deletions and insertions in the tables from occurring.
+ </p>
+ </item>
</taglist>
</item>
</taglist>
@@ -1401,7 +1452,7 @@
</item>
</taglist>
</item>
- <tag><marker id="ERL_AFLAGS"><c><![CDATA[ERL_AFLAGS]]></c></marker></tag>
+ <tag><marker id="ERL_AFLAGS"/><c><![CDATA[ERL_AFLAGS]]></c></tag>
<item>
<p>The content of this environment variable will be added to the
beginning of the command line for <c><![CDATA[erl]]></c>.</p>
@@ -1411,7 +1462,7 @@
the <c><![CDATA[-extra]]></c> section, i.e. the end of the command line
following after an <c><![CDATA[-extra]]></c> flag.</p>
</item>
- <tag><marker id="ERL_ZFLAGS"><c><![CDATA[ERL_ZFLAGS]]></c></marker> and <marker id="ERL_FLAGS"><c><![CDATA[ERL_FLAGS]]></c></marker></tag>
+ <tag><marker id="ERL_ZFLAGS"/><c><![CDATA[ERL_ZFLAGS]]></c> and <marker id="ERL_FLAGS"/><c><![CDATA[ERL_FLAGS]]></c></tag>
<item>
<p>The content of these environment variables will be added to the
end of the command line for <c><![CDATA[erl]]></c>.</p>
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
index 890293d802..b435d5c9b4 100644
--- a/erts/doc/src/erl_dist_protocol.xml
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -5,20 +5,21 @@
<header>
<copyright>
<year>2007</year>
- <year>2013</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -548,10 +549,10 @@ If Result > 0, the packet only consists of [119, Result].
-->
</section>
- <marker id="distribution_handshake"/>
<section>
<title>Distribution Handshake</title>
<p>
+ <marker id="distribution_handshake"/>
This section describes the distribution handshake protocol
introduced in the OTP-R6 release of Erlang/OTP. This
description was previously located in
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 77fc906aca..34dc8af238 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -4,20 +4,21 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2014</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -222,7 +223,7 @@
asynchronous function calls, using a thread pool provided by
Erlang. There is also a select call, that can be used for
asynchronous drivers.</item>
- <tag><marker id="multi_threading">Multi-threading</marker></tag>
+ <tag><marker id="multi_threading"/>Multi-threading</tag>
<item>
<p>A POSIX thread like API for multi-threading is provided. The
Erlang driver thread API only provide a subset of the functionality
@@ -296,7 +297,7 @@
<item><p>A driver can add and later remove drivers.</p></item>
<tag>Monitoring processes</tag>
<item><p>A driver can monitor a process that does not own a port.</p></item>
- <tag><marker id="version_management">Version management</marker></tag>
+ <tag><marker id="version_management"/>Version management</tag>
<item>
<p>Version management is enabled for drivers that have set the
<seealso marker="driver_entry#extended_marker">extended_marker</seealso>
@@ -346,6 +347,16 @@
the driver does not handle sizes that overflow an <c>int</c>
all will work as before.</p>
</item>
+ <tag><marker id="time_measurement"/>Time Measurement</tag>
+ <item><p>Support for time measurement in drivers:
+ <list>
+ <item><seealso marker="#ErlDrvTime"><c>ErlDrvTime</c></seealso></item>
+ <item><seealso marker="#ErlDrvTimeUnit"><c>ErlDrvTimeUnit</c></seealso></item>
+ <item><seealso marker="#erl_drv_monotonic_time"><c>erl_drv_monotonic_time()</c></seealso></item>
+ <item><seealso marker="#erl_drv_time_offset"><c>erl_drv_time_offset()</c></seealso></item>
+ <item><seealso marker="#erl_drv_convert_time_unit"><c>erl_drv_convert_time_unit()</c></seealso></item>
+ </list></p>
+ </item>
</taglist>
</section>
@@ -383,12 +394,12 @@
<item>
<p>
Rewrite driver callback
- <c><seealso marker="driver_entry#control">control</seealso></c>
+ <seealso marker="driver_entry#control"><c>control</c></seealso>
to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>.
</p>
<p>
Rewrite driver callback
- <c><seealso marker="driver_entry#call">call</seealso></c>
+ <seealso marker="driver_entry#call"><c>call</c></seealso>
to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>.
</p>
<note>
@@ -406,19 +417,19 @@
<item>
<p>
Driver callback
- <c><seealso marker="driver_entry#output">output</seealso></c>
+ <seealso marker="driver_entry#output"><c>output</c></seealso>
now gets <c>ErlDrvSizeT</c> as 3rd argument instead
of previously <c>int</c>.
</p>
<p>
Driver callback
- <c><seealso marker="driver_entry#control">control</seealso></c>
+ <seealso marker="driver_entry#control"><c>control</c></seealso>
now gets <c>ErlDrvSizeT</c> as 4th and 6th arguments instead
of previously <c>int</c>.
</p>
<p>
Driver callback
- <c><seealso marker="driver_entry#call">call</seealso></c>
+ <seealso marker="driver_entry#call"><c>call</c></seealso>
now gets <c>ErlDrvSizeT</c> as 4th and 6th arguments instead
of previously <c>int</c>.
</p>
@@ -859,6 +870,24 @@ typedef struct ErlIOVec {
<seealso marker="#erl_drv_tsd_get">erl_drv_tsd_get()</seealso>.
</p>
</item>
+ <tag><marker id="ErlDrvTime"/>ErlDrvTime</tag>
+ <item>
+ <p>A signed 64-bit integer type for representation of time.</p>
+ </item>
+ <tag><marker id="ErlDrvTimeUnit"/>ErlDrvTimeUnit</tag>
+ <item>
+ <p>An enumeration of time units supported by the driver API:</p>
+ <taglist>
+ <tag><c>ERL_DRV_SEC</c></tag>
+ <item><p>Seconds</p></item>
+ <tag><c>ERL_DRV_MSEC</c></tag>
+ <item><p>Milliseconds</p></item>
+ <tag><c>ERL_DRV_USEC</c></tag>
+ <item><p>Microseconds</p></item>
+ <tag><c>ERL_DRV_NSEC</c></tag>
+ <item><p>Nanoseconds</p></item>
+ </taglist>
+ </item>
</taglist>
</section>
@@ -1022,6 +1051,11 @@ typedef struct ErlIOVec {
<fsummary>Read a system timestamp</fsummary>
<desc>
<marker id="driver_get_now"></marker>
+ <warning><p><em>This function is deprecated! Do not use it!</em>
+ Use <seealso marker="#erl_drv_monotonic_time"><c>erl_drv_monotonic_time()</c></seealso>
+ (perhaps in combination with
+ <seealso marker="#erl_drv_time_offset"><c>erl_drv_time_offset()</c></seealso>)
+ instead.</p></warning>
<p>This function reads a timestamp into the memory pointed to by
the parameter <c>now</c>. See the description of <seealso marker="#ErlDrvNowData">ErlDrvNowData</seealso> for
specification of its fields. </p>
@@ -2810,7 +2844,7 @@ ERL_DRV_MAP int sz
</func>
<func>
- <name><ret>int</ret><nametext>erl_drv_putenv(char *key, char *value)</nametext></name>
+ <name><ret>int</ret><nametext>erl_drv_putenv(const char *key, char *value)</nametext></name>
<fsummary>Set the value of an environment variable</fsummary>
<desc>
<marker id="erl_drv_putenv"></marker>
@@ -2839,7 +2873,7 @@ ERL_DRV_MAP int sz
</desc>
</func>
<func>
- <name><ret>int</ret><nametext>erl_drv_getenv(char *key, char *value, size_t *value_size)</nametext></name>
+ <name><ret>int</ret><nametext>erl_drv_getenv(const char *key, char *value, size_t *value_size)</nametext></name>
<fsummary>Get the value of an environment variable</fsummary>
<desc>
<marker id="erl_drv_getenv"></marker>
@@ -2996,6 +3030,86 @@ ERL_DRV_MAP int sz
</desc>
</func>
+ <func>
+ <name><ret>ErlDrvTime</ret><nametext>erl_drv_monotonic_time(ErlDrvTimeUnit time_unit)</nametext></name>
+ <fsummary>Get Erlang Monotonic Time</fsummary>
+ <desc>
+ <marker id="erl_drv_monotonic_time"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>time_unit</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>
+ Returns
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>. Note that it is not uncommon with
+ negative values.
+ </p>
+ <p>Returns <c>ERL_DRV_TIME_ERROR</c> if called with an invalid
+ time unit argument, or if called from a thread that is not a
+ scheduler thread.</p>
+ <p>See also:</p>
+ <list>
+ <item><seealso marker="#ErlDrvTime"><c>ErlDrvTime</c></seealso></item>
+ <item><seealso marker="#ErlDrvTimeUnit"><c>ErlDrvTimeUnit</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvTime</ret><nametext>erl_drv_time_offset(ErlDrvTimeUnit time_unit)</nametext></name>
+ <fsummary>Get current Time Offset</fsummary>
+ <desc>
+ <marker id="erl_drv_time_offset"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>time_unit</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>Returns the current time offset between
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso>
+ and
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
+ converted into the <c>time_unit</c> passed as argument.</p>
+ <p>Returns <c>ERL_DRV_TIME_ERROR</c> if called with an invalid
+ time unit argument, or if called from a thread that is not a
+ scheduler thread.</p>
+ <p>See also:</p>
+ <list>
+ <item><seealso marker="#ErlDrvTime"><c>ErlDrvTime</c></seealso></item>
+ <item><seealso marker="#ErlDrvTimeUnit"><c>ErlDrvTimeUnit</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvTime</ret><nametext>erl_drv_convert_time_unit(ErlDrvTime val, ErlDrvTimeUnit from, ErlDrvTimeUnit to)</nametext></name>
+ <fsummary>Convert time unit of a time value</fsummary>
+ <desc>
+ <marker id="erl_drv_convert_time_unit"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>val</c></tag>
+ <item>Value to convert time unit for.</item>
+ <tag><c>from</c></tag>
+ <item>Time unit of <c>val</c>.</item>
+ <tag><c>to</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>Converts the <c>val</c> value of time unit <c>from</c> to
+ the corresponding value of time unit <c>to</c>. The result is
+ rounded using the floor function.</p>
+ <p>Returns <c>ERL_DRV_TIME_ERROR</c> if called with an invalid
+ time unit argument.</p>
+ <p>See also:</p>
+ <list>
+ <item><seealso marker="#ErlDrvTime"><c>ErlDrvTime</c></seealso></item>
+ <item><seealso marker="#ErlDrvTimeUnit"><c>ErlDrvTimeUnit</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
</funcs>
<section>
<title>SEE ALSO</title>
diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml
index a6e7dddbed..2ac974f497 100644
--- a/erts/doc/src/erl_ext_dist.xml
+++ b/erts/doc/src/erl_ext_dist.xml
@@ -5,20 +5,21 @@
<header>
<copyright>
<year>2007</year>
- <year>2014</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -149,10 +150,10 @@
</note>
</section>
- <marker id="distribution_header"/>
<section>
<title>Distribution header</title>
<p>
+ <marker id="distribution_header"/>
As of erts version 5.7.2 the old atom cache protocol was
dropped and a new one was introduced. This atom cache protocol
introduced the distribution header. Nodes with erts versions
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 3de94be9ff..420c9fea38 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -4,20 +4,21 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -66,34 +67,6 @@
</list>
</warning>
- <p>The NIF concept is officially supported from R14B. NIF source code
- written for earlier experimental versions might need adaption to run on R14B
- or later versions:</p>
- <list>
- <item>No incompatible changes between <em>R14B</em> and R14A.</item>
- <item>Incompatible changes between <em>R14A</em> and R13B04:
- <list>
- <item>Environment argument removed for <c>enif_alloc</c>,
- <c>enif_realloc</c>, <c>enif_free</c>, <c>enif_alloc_binary</c>,
- <c>enif_realloc_binary</c>, <c>enif_release_binary</c>,
- <c>enif_alloc_resource</c>, <c>enif_release_resource</c>,
- <c>enif_is_identical</c> and <c>enif_compare</c>.</item>
- <item>Character encoding argument added to <c>enif_get_atom</c>
- and <c>enif_make_existing_atom</c>.</item>
- <item>Module argument added to <c>enif_open_resource_type</c>
- while changing name spaces of resource types from global to module local.</item>
- </list>
- </item>
- <item>Incompatible changes between <em>R13B04</em> and R13B03:
- <list>
- <item>The function prototypes of the NIFs have changed to expect <c>argc</c> and <c>argv</c>
- arguments. The arity of a NIF is by that no longer limited to 3.</item>
- <item><c>enif_get_data</c> renamed as <c>enif_priv_data</c>.</item>
- <item><c>enif_make_string</c> got a third argument for character encoding.</item>
- </list>
- </item>
- </list>
-
<p>A minimal example of a NIF library can look like this:</p>
<p/>
<code type="none">
@@ -344,6 +317,17 @@ ok
libraries might however fail if deprecated features are used.
</p></item>
+ <tag><marker id="time_measurement"/>Time Measurement</tag>
+ <item><p>Support for time measurement in NIF libraries:
+ <list>
+ <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
+ <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
+ <item><seealso marker="#enif_monotonic_time"><c>enif_monotonic_time()</c></seealso></item>
+ <item><seealso marker="#enif_time_offset"><c>enif_time_offset()</c></seealso></item>
+ <item><seealso marker="#enif_convert_time_unit"><c>enif_convert_time_unit()</c></seealso></item>
+ </list></p>
+ </item>
+
<tag>Long-running NIFs</tag>
<item><p><marker id="dirty_nifs"/>Native functions
<seealso marker="#lengthy_work">
@@ -489,8 +473,9 @@ ok
independent environment with all its terms is valid until you explicitly
invalidates it with <seealso marker="#enif_free_env">enif_free_env</seealso>
or <c>enif_send</c>.</p>
- <p>All elements of a list/tuple must belong to the same environment as the
- list/tuple itself. Terms can be copied between environments with
+ <p>All contained terms of a list/tuple/map must belong to the same
+ environment as the list/tuple/map itself. Terms can be copied between
+ environments with
<seealso marker="#enif_make_copy">enif_make_copy</seealso>.</p>
</item>
<tag><marker id="ErlNifFunc"/>ErlNifFunc</tag>
@@ -586,17 +571,36 @@ typedef enum {
<item><p>A native signed 64-bit integer type.</p></item>
<tag><marker id="ErlNifUInt64"/>ErlNifUInt64</tag>
<item><p>A native unsigned 64-bit integer type.</p></item>
+
+ <tag><marker id="ErlNifTime"/>ErlNifTime</tag>
+ <item>
+ <p>A signed 64-bit integer type for representation of time.</p>
+ </item>
+ <tag><marker id="ErlNifTimeUnit"/>ErlNifTimeUnit</tag>
+ <item>
+ <p>An enumeration of time units supported by the NIF API:</p>
+ <taglist>
+ <tag><c>ERL_NIF_SEC</c></tag>
+ <item><p>Seconds</p></item>
+ <tag><c>ERL_NIF_MSEC</c></tag>
+ <item><p>Milliseconds</p></item>
+ <tag><c>ERL_NIF_USEC</c></tag>
+ <item><p>Microseconds</p></item>
+ <tag><c>ERL_NIF_NSEC</c></tag>
+ <item><p>Nanoseconds</p></item>
+ </taglist>
+ </item>
</taglist>
</section>
<funcs>
<func><name><ret>void *</ret><nametext>enif_alloc(size_t size)</nametext></name>
- <fsummary>Allocate dynamic memory.</fsummary>
+ <fsummary>Allocate dynamic memory</fsummary>
<desc><p>Allocate memory of <c>size</c> bytes. Return NULL if allocation failed.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_alloc_binary(size_t size, ErlNifBinary* bin)</nametext></name>
- <fsummary>Create a new binary.</fsummary>
+ <fsummary>Create a new binary</fsummary>
<desc><p>Allocate a new binary of size <c>size</c>
bytes. Initialize the structure pointed to by <c>bin</c> to
refer to the allocated binary. The binary must either be released by
@@ -623,7 +627,7 @@ typedef enum {
<desc><p>Allocate a memory managed resource object of type <c>type</c> and size <c>size</c> bytes.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_clear_env(ErlNifEnv* env)</nametext></name>
- <fsummary>Clear an environment for reuse.</fsummary>
+ <fsummary>Clear an environment for reuse</fsummary>
<desc><p>Free all terms in an environment and clear it for reuse. The environment must
have been allocated with <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.
</p></desc>
@@ -711,14 +715,14 @@ typedef enum {
<c>size-1</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_atom_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len, ErlNifCharEncoding encode)</nametext></name>
- <fsummary>Get the length of atom <c>term</c>.</fsummary>
+ <fsummary>Get the length of atom <c>term</c></fsummary>
<desc><p>Set <c>*len</c> to the length (number of bytes excluding
terminating null character) of the atom <c>term</c> with encoding
<c>encode</c>. Return true on success or false if <c>term</c> is not an
atom.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_double(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)</nametext></name>
- <fsummary>Read a floating-point number term.</fsummary>
+ <fsummary>Read a floating-point number term</fsummary>
<desc><p>Set <c>*dp</c> to the floating point value of
<c>term</c>. Return true on success or false if <c>term</c> is not a float.</p></desc>
</func>
@@ -747,17 +751,28 @@ typedef enum {
non-empty list.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_list_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len)</nametext></name>
- <fsummary>Get the length of list <c>term</c>.</fsummary>
+ <fsummary>Get the length of list <c>term</c></fsummary>
<desc><p>Set <c>*len</c> to the length of list <c>term</c> and return true,
or return false if <c>term</c> is not a list.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip)</nametext></name>
- <fsummary>Read an long integer term.</fsummary>
+ <fsummary>Read an long integer term</fsummary>
<desc><p>Set <c>*ip</c> to the long integer value of <c>term</c> and
return true, or return false if <c>term</c> is not an integer or is
outside the bounds of type <c>long int</c>.</p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp)</nametext></name>
+ <func><name><ret>int</ret><nametext>enif_get_map_size(ErlNifEnv* env, ERL_NIF_TERM term, size_t *size)</nametext></name>
+ <fsummary>Read the size of a map term</fsummary>
+ <desc><p>Set <c>*size</c> to the number of key-value pairs in the map <c>term</c> and
+ return true, or return false if <c>term</c> is not a map.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_map_value(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value)</nametext></name>
+ <fsummary>Get the value of a key in a map</fsummary>
+ <desc><p>Set <c>*value</c> to the value associated with <c>key</c> in the
+ map <c>map</c> and return true. Return false if <c>map</c> is not a map
+ or if <c>map</c> does not contain <c>key</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp)</nametext></name>
<fsummary>Get the pointer to a resource object</fsummary>
<desc><p>Set <c>*objp</c> to point to the resource object referred to by <c>term</c>.</p>
<p>Return true on success or false if <c>term</c> is not a handle to a resource object
@@ -766,7 +781,7 @@ typedef enum {
<func><name><ret>int</ret><nametext>enif_get_string(ErlNifEnv* env,
ERL_NIF_TERM list, char* buf, unsigned size,
ErlNifCharEncoding encode)</nametext></name>
- <fsummary>Get a C-string from a list.</fsummary>
+ <fsummary>Get a C-string from a list</fsummary>
<desc><p>Write a null-terminated string, in the buffer pointed to by
<c>buf</c> with size <c>size</c>, consisting of the characters
in the string <c>list</c>. The characters are written using encoding
@@ -779,7 +794,7 @@ typedef enum {
<c>size</c> is less than 1.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM term, int* arity, const ERL_NIF_TERM** array)</nametext></name>
- <fsummary>Inspect the elements of a tuple.</fsummary>
+ <fsummary>Inspect the elements of a tuple</fsummary>
<desc><p>If <c>term</c> is a tuple, set <c>*array</c> to point
to an array containing the elements of the tuple and set
<c>*arity</c> to the number of elements. Note that the array
@@ -789,23 +804,40 @@ typedef enum {
tuple.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM term, unsigned int* ip)</nametext></name>
- <fsummary>Read an unsigned integer term.</fsummary>
+ <fsummary>Read an unsigned integer term</fsummary>
<desc><p>Set <c>*ip</c> to the unsigned integer value of <c>term</c> and
return true, or return false if <c>term</c> is not an unsigned integer or
is outside the bounds of type <c>unsigned int</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_uint64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifUInt64* ip)</nametext></name>
- <fsummary>Read an unsigned 64-bit integer term.</fsummary>
+ <fsummary>Read an unsigned 64-bit integer term</fsummary>
<desc><p>Set <c>*ip</c> to the unsigned integer value of <c>term</c> and
return true, or return false if <c>term</c> is not an unsigned integer or
is outside the bounds of an unsigned 64-bit integer.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip)</nametext></name>
- <fsummary>Read an unsigned integer term.</fsummary>
+ <fsummary>Read an unsigned integer term</fsummary>
<desc><p>Set <c>*ip</c> to the unsigned long integer value of <c>term</c>
and return true, or return false if <c>term</c> is not an unsigned integer or is
outside the bounds of type <c>unsigned long</c>.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_getenv(const char* key, char* value, size_t *value_size)</nametext></name>
+ <fsummary>Get the value of an environment variable</fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_getenv">erl_drv_getenv</seealso>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_has_pending_exception(ErlNifEnv* env, ERL_NIF_TERM* reason)</nametext></name>
+ <fsummary>Check if an exception has been raised</fsummary>
+ <desc><p>Return true if a pending exception is associated
+ with the environment <c>env</c>. If <c>reason</c> is a null pointer, ignore it.
+ Otherwise, if there's a pending exception associated with <c>env</c>, set the ERL_NIF_TERM
+ to which <c>reason</c> points to the value of the exception's term. For example, if
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso> is called to set a
+ pending <c>badarg</c> exception, a subsequent call to <c>enif_has_pending_exception(env, &amp;reason)</c>
+ will set <c>reason</c> to the atom <c>badarg</c>, then return true.</p>
+ <p>See also: <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>
+ and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>.</p>
+ </desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin)</nametext></name>
<fsummary>Inspect the content of a binary</fsummary>
<desc><p>Initialize the structure pointed to by <c>bin</c> with
@@ -835,9 +867,14 @@ typedef enum {
<fsummary>Determine if a term is an empty list</fsummary>
<desc><p>Return true if <c>term</c> is an empty list.</p></desc>
</func>
- <marker id="enif_is_exception"/><func><name><ret>int</ret><nametext>enif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <func><name><ret>int</ret><nametext>enif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
<fsummary>Determine if a term is an exception</fsummary>
- <desc><p>Return true if <c>term</c> is an exception.</p></desc>
+ <desc><marker id="enif_is_exception"/>
+ <p>Return true if <c>term</c> is an exception.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_map(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a map</fsummary>
+ <desc><p>Return true if <c>term</c> is a map, false otherwise.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_is_number(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
<fsummary>Determine if a term is a number (integer or float)</fsummary>
@@ -898,40 +935,58 @@ typedef enum {
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom(ErlNifEnv* env, const char* name)</nametext></name>
<fsummary>Create an atom term</fsummary>
<desc><p>Create an atom term from the null-terminated C-string <c>name</c>
- with iso-latin-1 encoding.</p></desc>
+ with iso-latin-1 encoding. If the length of <c>name</c> exceeds the maximum length
+ allowed for an atom (255 characters), <c>enif_make_atom</c> invokes
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)</nametext></name>
<fsummary>Create an atom term</fsummary>
<desc><p>Create an atom term from the string <c>name</c> with length <c>len</c>.
- Null-characters are treated as any other characters.</p></desc>
+ Null-characters are treated as any other characters. If <c>len</c> is greater than the maximum length
+ allowed for an atom (255 characters), <c>enif_make_atom</c> invokes
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
- <fsummary>Make a badarg exception.</fsummary>
- <desc><p>Make a badarg exception to be returned from a NIF, and set
- an associated exception reason in <c>env</c>. If
- <c>enif_make_badarg</c> is called, the term it returns <em>must</em>
- be returned from the function that called it. No other return value
- is allowed. Also, the term returned from <c>enif_make_badarg</c> may
- be passed only to
- <seealso marker="#enif_is_exception">enif_is_exception</seealso> and
- not to any other NIF API function.</p></desc>
+ <fsummary>Make a badarg exception</fsummary>
+ <desc><p>Make a badarg exception to be returned from a NIF, and associate
+ it with the environment <c>env</c>. Once a NIF or any function
+ it calls invokes <c>enif_make_badarg</c>, the runtime ensures that a
+ <c>badarg</c> exception is raised when the NIF returns, even if the NIF
+ attempts to return a non-exception term instead.
+ The return value from <c>enif_make_badarg</c> may be used only as the
+ return value from the NIF that invoked it (directly or indirectly)
+ or be passed to
+ <seealso marker="#enif_is_exception">enif_is_exception</seealso>, but
+ not to any other NIF API function.</p>
+ <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>
+ and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>
+ </p>
+ <note><p>In earlier versions (older than erts-7.0, OTP 18) the return value
+ from <c>enif_make_badarg</c> had to be returned from the NIF. This
+ requirement is now lifted as the return value from the NIF is ignored
+ if <c>enif_make_badarg</c> has been invoked.</p></note></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
- <fsummary>Make a binary term.</fsummary>
+ <fsummary>Make a binary term</fsummary>
<desc><p>Make a binary term from <c>bin</c>. Any ownership of
the binary data will be transferred to the created term and
<c>bin</c> should be considered read-only for the rest of the NIF
call and then as released.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_copy(ErlNifEnv* dst_env, ERL_NIF_TERM src_term)</nametext></name>
- <fsummary>Make a copy of a term.</fsummary>
+ <fsummary>Make a copy of a term</fsummary>
<desc><p>Make a copy of term <c>src_term</c>. The copy will be created in
environment <c>dst_env</c>. The source term may be located in any
environment.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_double(ErlNifEnv* env, double d)</nametext></name>
<fsummary>Create a floating-point term</fsummary>
- <desc><p>Create a floating-point term from a <c>double</c>.</p></desc>
+ <desc><p>Create a floating-point term from a <c>double</c>. If the <c>double</c> argument is
+ not finite or is NaN, <c>enif_make_double</c> invokes
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding encode)</nametext></name>
<fsummary>Create an existing atom term</fsummary>
@@ -939,7 +994,9 @@ typedef enum {
the null-terminated C-string <c>name</c> with encoding
<seealso marker="#ErlNifCharEncoding">encode</seealso>. If the atom
already exists store the term in <c>*atom</c> and return true, otherwise
- return false.</p></desc>
+ return false. If the length of <c>name</c> exceeds the maximum length
+ allowed for an atom (255 characters), <c>enif_make_existing_atom</c>
+ returns false.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)</nametext></name>
<fsummary>Create an existing atom term</fsummary>
@@ -947,7 +1004,9 @@ typedef enum {
string <c>name</c> with length <c>len</c> and encoding
<seealso marker="#ErlNifCharEncoding">encode</seealso>. Null-characters
are treated as any other characters. If the atom already exists store the term
- in <c>*atom</c> and return true, otherwise return false.</p></desc>
+ in <c>*atom</c> and return true, otherwise return false. If <c>len</c> is greater
+ than the maximum length allowed for an atom (255 characters),
+ <c>enif_make_existing_atom_len</c> returns false.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_int(ErlNifEnv* env, int i)</nametext></name>
<fsummary>Create an integer term</fsummary>
@@ -958,7 +1017,7 @@ typedef enum {
<desc><p>Create an integer term from a signed 64-bit integer.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
- <fsummary>Create a list term.</fsummary>
+ <fsummary>Create a list term</fsummary>
<desc><p>Create an ordinary list term of length <c>cnt</c>. Expects
<c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
elements of the list. An empty list is returned if <c>cnt</c> is 0.</p></desc>
@@ -972,28 +1031,21 @@ typedef enum {
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)</nametext></name>
- <fsummary>Create a list term.</fsummary>
+ <fsummary>Create a list term</fsummary>
<desc><p>Create an ordinary list term with length indicated by the
function name. Prefer these functions (macros) over the variadic
<c>enif_make_list</c> to get a compile time error if the number of
arguments does not match.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_cell(ErlNifEnv* env, ERL_NIF_TERM head, ERL_NIF_TERM tail)</nametext></name>
- <fsummary>Create a list cell.</fsummary>
+ <fsummary>Create a list cell</fsummary>
<desc><p>Create a list cell <c>[head | tail]</c>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)</nametext></name>
- <fsummary>Create a list term from an array.</fsummary>
+ <fsummary>Create a list term from an array</fsummary>
<desc><p>Create an ordinary list containing the elements of array <c>arr</c>
of length <c>cnt</c>. An empty list is returned if <c>cnt</c> is 0.</p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list)</nametext></name>
- <fsummary>Create the reverse list of the list <c>term</c>.</fsummary>
- <desc><p>Set <c>*list</c> to the reverse list of the list <c>term</c> and return true,
- or return false if <c>term</c> is not a list. This function should only be used on
- short lists as a copy will be created of the list which will not be released until after the
- nif returns.</p></desc>
- </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_long(ErlNifEnv* env, long int i)</nametext></name>
<fsummary>Create an integer term from a long int</fsummary>
<desc><p>Create an integer term from a <c>long int</c>.</p></desc>
@@ -1008,12 +1060,42 @@ typedef enum {
reallocated.</p><p>Return a pointer to the raw binary data and set
<c>*termp</c> to the binary term.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_new_map(ErlNifEnv* env)</nametext></name>
+ <fsummary>Make an empty map term</fsummary>
+ <desc><p>Make an empty map term.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_map_put(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value, ERL_NIF_TERM* map_out)</nametext></name>
+ <fsummary>Insert key-value pair in map</fsummary>
+ <desc><p>Make a copy of map <c>map_in</c> and insert <c>key</c> with
+ <c>value</c>. If <c>key</c> already exists in <c>map_in</c>, the old
+ associated value is replaced by <c>value</c>. If successful set
+ <c>*map_out</c> to the new map and return true. Return false if
+ <c>map_in</c> is not a map.</p>
+ <p>The <c>map_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_map_update(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM new_value, ERL_NIF_TERM* map_out)</nametext></name>
+ <fsummary>Replace value for key in map</fsummary>
+ <desc><p>Make a copy of map <c>map_in</c> and replace the old associated
+ value for <c>key</c> with <c>new_value</c>. If successful set
+ <c>*map_out</c> to the new map and return true. Return false if
+ <c>map_in</c> is not a map or if it does no contain <c>key</c>.</p>
+ <p>The <c>map_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_map_remove(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out)</nametext></name>
+ <fsummary>Remove key from map</fsummary>
+ <desc><p>If map <c>map_in</c> contains <c>key</c>, make a copy of
+ <c>map_in</c> in <c>*map_out</c> and remove <c>key</c> and associated
+ value. If map <c>map_in</c> does not contain <c>key</c>, set
+ <c>*map_out</c> to <c>map_in</c>. Return true for success or false if
+ <c>map_in</c> is not a map.</p>
+ <p>The <c>map_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid)</nametext></name>
<fsummary>Make a pid term</fsummary>
<desc><p>Make a pid term from <c>*pid</c>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ref(ErlNifEnv* env)</nametext></name>
- <fsummary>Create a reference.</fsummary>
+ <fsummary>Create a reference</fsummary>
<desc><p>Create a reference like <seealso marker="erlang#make_ref-0">erlang:make_ref/0</seealso>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_resource(ErlNifEnv* env, void* obj)</nametext></name>
@@ -1051,20 +1133,28 @@ typedef enum {
<seealso marker="#enif_release_resource">enif_release_resource</seealso>.</p>
</desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in, ERL_NIF_TERM *list_out)</nametext></name>
+ <fsummary>Create the reverse of a list</fsummary>
+ <desc><p>Set <c>*list_out</c> to the reverse list of the list <c>list_in</c> and return true,
+ or return false if <c>list_in</c> is not a list. This function should only be used on
+ short lists as a copy will be created of the list which will not be released until after the
+ nif returns.</p>
+ <p>The <c>list_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, const char* string, ErlNifCharEncoding encoding)</nametext></name>
- <fsummary>Create a string.</fsummary>
+ <fsummary>Create a string</fsummary>
<desc><p>Create a list containing the characters of the
null-terminated string <c>string</c> with encoding <seealso marker="#ErlNifCharEncoding">encoding</seealso>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string_len(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding encoding)</nametext></name>
- <fsummary>Create a string.</fsummary>
+ <fsummary>Create a string</fsummary>
<desc><p>Create a list containing the characters of the string <c>string</c> with
length <c>len</c> and encoding <seealso marker="#ErlNifCharEncoding">encoding</seealso>.
Null-characters are treated as any other characters.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_sub_binary(ErlNifEnv*
env, ERL_NIF_TERM bin_term, size_t pos, size_t size)</nametext></name>
- <fsummary>Make a subbinary term.</fsummary>
+ <fsummary>Make a subbinary term</fsummary>
<desc><p>Make a subbinary of binary <c>bin_term</c>, starting at
zero-based position <c>pos</c> with a length of <c>size</c> bytes.
<c>bin_term</c> must be a binary or bitstring and
@@ -1072,7 +1162,7 @@ typedef enum {
bytes in <c>bin_term</c>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
- <fsummary>Create a tuple term.</fsummary>
+ <fsummary>Create a tuple term</fsummary>
<desc><p>Create a tuple term of arity <c>cnt</c>. Expects
<c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
elements of the tuple.</p></desc>
@@ -1086,14 +1176,14 @@ typedef enum {
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)</nametext></name>
- <fsummary>Create a tuple term.</fsummary>
+ <fsummary>Create a tuple term</fsummary>
<desc><p>Create a tuple term with length indicated by the
function name. Prefer these functions (macros) over the variadic
<c>enif_make_tuple</c> to get a compile time error if the number of
arguments does not match.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)</nametext></name>
- <fsummary>Create a tuple term from an array.</fsummary>
+ <fsummary>Create a tuple term from an array</fsummary>
<desc><p>Create a tuple containing the elements of array <c>arr</c>
of length <c>cnt</c>.</p></desc>
</func>
@@ -1109,6 +1199,72 @@ typedef enum {
<fsummary>Create an integer term from an unsigned long int</fsummary>
<desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_create(ErlNifEnv *env, ERL_NIF_TERM map, ErlNifMapIterator *iter, ErlNifMapIteratorEntry entry)</nametext></name>
+ <fsummary>Create a map iterator</fsummary>
+ <desc><p>Create an iterator for the map <c>map</c> by initializing the
+ structure pointed to by <c>iter</c>. The <c>entry</c> argument determines
+ the start position of the iterator: <c>ERL_NIF_MAP_ITERATOR_FIRST</c> or
+ <c>ERL_NIF_MAP_ITERATOR_LAST</c>. Return true on success or false if
+ <c>map</c> is not a map.</p>
+ <p>A map iterator is only useful during the lifetime of the environment
+ <c>env</c> that the <c>map</c> belongs to. The iterator must be destroyed by
+ calling <seealso marker="#enif_map_iterator_destroy">
+ enif_map_iterator_destroy</seealso>.</p>
+ <code type="none">
+ERL_NIF_TERM key, value;
+ErlNifMapIterator iter;
+enif_map_iterator_create(env, my_map, &amp;iter, ERL_NIF_MAP_ITERATOR_FIRST);
+
+while (enif_map_iterator_get_pair(env, &amp;iter, &amp;key, &amp;value)) {
+ do_something(key,value);
+ enif_map_iterator_next(env, &amp;iter);
+}
+enif_map_iterator_destroy(env, &amp;iter);
+ </code>
+ <note><p>The key-value pairs of a map have no defined iteration
+ order. The only guarantee is that the iteration order of a single map
+ instance is preserved during the lifetime of the environment that the map
+ belongs to.</p>
+ </note>
+ </desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_map_iterator_destroy(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Destroy a map iterator</fsummary>
+ <desc><p>Destroy a map iterator created by
+ <seealso marker="#enif_map_iterator_create">enif_map_iterator_create</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_get_pair(ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value)</nametext></name>
+ <fsummary>Get key and value at current map iterator position</fsummary>
+ <desc><p>Get key and value terms at current map iterator position.
+ On success set <c>*key</c> and <c>*value</c> and return true.
+ Return false if the iterator is positioned at head (before first entry)
+ or tail (beyond last entry).</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_is_head(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Check if map iterator is positioned before first</fsummary>
+ <desc><p>Return true if map iterator <c>iter</c> is positioned
+ before first entry.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_is_tail(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Check if map iterator is positioned after last</fsummary>
+ <desc><p>Return true if map iterator <c>iter</c> is positioned
+ after last entry.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_next(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Increment map iterator to point to next entry</fsummary>
+ <desc><p>Increment map iterator to point to next key-value entry.
+ Return true if the iterator is now positioned at a valid key-value entry,
+ or false if the iterator is positioned at the tail (beyond the last
+ entry).</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_prev(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Decrement map iterator to point to previous entry</fsummary>
+ <desc><p>Decrement map iterator to point to previous key-value entry.
+ Return true if the iterator is now positioned at a valid key-value entry,
+ or false if the iterator is positioned at the head (before the first
+ entry).</p></desc>
+ </func>
<func><name><ret>ErlNifMutex *</ret><nametext>enif_mutex_create(char *name)</nametext></name>
<fsummary></fsummary>
<desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_create">erl_drv_mutex_create</seealso>.
@@ -1169,19 +1325,32 @@ typedef enum {
<c>reload</c> or <c>upgrade</c>.</p>
<p>Was previously named <c>enif_get_data</c>.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_raise_exception(ErlNifEnv* env, ERL_NIF_TERM reason)</nametext></name>
+ <fsummary>Raise a NIF error exception</fsummary>
+ <desc><p>Create an error exception with the term <c>reason</c> to be returned from a NIF,
+ and associate it with the environment <c>env</c>. Once a NIF or any function it calls
+ invokes <c>enif_raise_exception</c>, the runtime ensures that the exception it creates
+ is raised when the NIF returns, even if the NIF attempts to return a non-exception
+ term instead. The return value from <c>enif_raise_exception</c> may be used only as
+ the return value from the NIF that invoked it (directly or indirectly) or be passed
+ to <seealso marker="#enif_is_exception">enif_is_exception</seealso>, but
+ not to any other NIF API function.</p>
+ <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>
+ and <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_realloc_binary(ErlNifBinary* bin, size_t size)</nametext></name>
- <fsummary>Change the size of a binary.</fsummary>
+ <fsummary>Change the size of a binary</fsummary>
<desc><p>Change the size of a binary <c>bin</c>. The source binary
may be read-only, in which case it will be left untouched and
a mutable copy is allocated and assigned to <c>*bin</c>. Return true on success,
false if memory allocation failed.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_release_binary(ErlNifBinary* bin)</nametext></name>
- <fsummary>Release a binary.</fsummary>
+ <fsummary>Release a binary</fsummary>
<desc><p>Release a binary obtained from <c>enif_alloc_binary</c>.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_release_resource(void* obj)</nametext></name>
- <fsummary>Release a resource object.</fsummary>
+ <fsummary>Release a resource object</fsummary>
<desc><p>Remove a reference to resource object <c>obj</c>obtained from
<seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.
The resource object will be destructed when the last reference is removed.
@@ -1257,12 +1426,12 @@ typedef enum {
</desc>
</func>
<func><name><ret>ErlNifPid *</ret><nametext>enif_self(ErlNifEnv* caller_env, ErlNifPid* pid)</nametext></name>
- <fsummary>Get the pid of the calling process.</fsummary>
+ <fsummary>Get the pid of the calling process</fsummary>
<desc><p>Initialize the pid variable <c>*pid</c> to represent the
calling process. Return <c>pid</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_send(ErlNifEnv* env, ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg)</nametext></name>
- <fsummary>Send a message to a process.</fsummary>
+ <fsummary>Send a message to a process</fsummary>
<desc><p>Send a message to a process.</p>
<taglist>
<tag><c>env</c></tag>
@@ -1347,6 +1516,88 @@ typedef enum {
<desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set</seealso>.
</p></desc>
</func>
+
+
+ <func>
+ <name><ret>ErlNifTime</ret><nametext>enif_monotonic_time(ErlNifTimeUnit time_unit)</nametext></name>
+ <fsummary>Get Erlang Monotonic Time</fsummary>
+ <desc>
+ <marker id="enif_monotonic_time"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>time_unit</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>
+ Returns
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>. Note that it is not uncommon with
+ negative values.
+ </p>
+ <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
+ time unit argument, or if called from a thread that is not a
+ scheduler thread.</p>
+ <p>See also:</p>
+ <list>
+ <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
+ <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlNifTime</ret><nametext>enif_time_offset(ErlNifTimeUnit time_unit)</nametext></name>
+ <fsummary>Get current Time Offset</fsummary>
+ <desc>
+ <marker id="enif_time_offset"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>time_unit</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>Returns the current time offset between
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso>
+ and
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
+ converted into the <c>time_unit</c> passed as argument.</p>
+ <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
+ time unit argument, or if called from a thread that is not a
+ scheduler thread.</p>
+ <p>See also:</p>
+ <list>
+ <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
+ <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to)</nametext></name>
+ <fsummary>Convert time unit of a time value</fsummary>
+ <desc>
+ <marker id="enif_convert_time_unit"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>val</c></tag>
+ <item>Value to convert time unit for.</item>
+ <tag><c>from</c></tag>
+ <item>Time unit of <c>val</c>.</item>
+ <tag><c>to</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>Converts the <c>val</c> value of time unit <c>from</c> to
+ the corresponding value of time unit <c>to</c>. The result is
+ rounded using the floor function.</p>
+ <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
+ time unit argument.</p>
+ <p>See also:</p>
+ <list>
+ <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
+ <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
</funcs>
<section>
<title>SEE ALSO</title>
diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml
index 171f84decc..db4f132609 100644
--- a/erts/doc/src/erl_prim_loader.xml
+++ b/erts/doc/src/erl_prim_loader.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -35,17 +36,11 @@
the system. The start script is also fetched with this low level
loader.</p>
<p><c>erl_prim_loader</c> knows about the environment and how to
- fetch modules. The loader could, for example, fetch files using
- the file system (with absolute file names as input), or a
- database (where the binary format of a module is stored).</p>
+ fetch modules.</p>
<p>The <c>-loader Loader</c> command line flag can be used to
choose the method used by the <c>erl_prim_loader</c>. Two
<c>Loader</c> methods are supported by the Erlang runtime system:
- <c>efile</c> and <c>inet</c>. If another loader is required, then
- it has to be implemented by the user. The <c>Loader</c> provided
- by the user must fulfill the protocol defined below, and it is
- started with the <c>erl_prim_loader</c> by evaluating
- <c>open_port({spawn,Loader},[binary])</c>.</p>
+ <c>efile</c> and <c>inet</c>.</p>
<warning><p>The support for loading of code from archive files is
experimental. The sole purpose of releasing it before it is ready
@@ -82,9 +77,6 @@
started on each of hosts given in <c><anno>Hosts</anno></c> in order to
answer the requests. See <seealso
marker="kernel:erl_boot_server">erl_boot_server(3)</seealso>.</p>
- <p>If <c>-loader</c> is something else, the given port program
- is started. The port program is supposed to follow
- the protocol specified below.</p>
</desc>
</func>
<func>
@@ -174,22 +166,6 @@
</funcs>
<section>
- <title>Protocol</title>
- <p>The following protocol must be followed if a user provided
- loader port program is used. The <c>Loader</c> port program is
- started with the command
- <c>open_port({spawn,Loader},[binary])</c>. The protocol is as
- follows:</p>
- <pre>
-Function Send Receive
--------------------------------------------------------------
-get_file [102 | FileName] [121 | BinaryFile] (on success)
- [122] (failure)
-
-stop eof terminate</pre>
- </section>
-
- <section>
<title>Command Line Flags</title>
<p>The <c>erl_prim_loader</c> module interprets the following
command line flags:</p>
@@ -198,10 +174,8 @@ stop eof terminate</pre>
<item>
<p>Specifies the name of the loader used by
<c>erl_prim_loader</c>. <c>Loader</c> can be <c>efile</c>
- (use the local file system), or <c>inet</c> (load using
- the <c>boot_server</c> on another Erlang node). If
- <c>Loader</c> is user defined, the defined <c>Loader</c> port
- program is started.</p>
+ (use the local file system) or <c>inet</c> (load using
+ the <c>boot_server</c> on another Erlang node).</p>
<p>If the <c>-loader</c> flag is omitted, it defaults to
<c>efile</c>.</p>
</item>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 0e5909a52d..30e6751f41 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -29,36 +30,107 @@
<file>erlang.xml</file>
</header>
<module>erlang</module>
- <modulesummary>The Erlang BIFs</modulesummary>
+ <modulesummary>The Erlang BIFs.</modulesummary>
<description>
- <p>By convention, most built-in functions (BIFs) are seen as being
- in the module <c>erlang</c>. A number of the BIFs are viewed more
+ <p>By convention, most Built-In Functions (BIFs) are seen as being
+ in this module. Some of the BIFs are viewed more
or less as part of the Erlang programming language and are
- <em>auto-imported</em>. Thus, it is not necessary to specify
- the module name and both the calls <c>atom_to_list(Erlang)</c> and
- <c>erlang:atom_to_list(Erlang)</c> are identical.</p>
- <p>In the text, auto-imported BIFs are listed without module prefix.
+ <em>auto-imported</em>. Thus, it is not necessary to specify the
+ module name. For example, the calls <c>atom_to_list(Erlang)</c>
+ and <c>erlang:atom_to_list(Erlang)</c> are identical.</p>
+ <p>Auto-imported BIFs are listed without module prefix.
BIFs listed with module prefix are not auto-imported.</p>
- <p>BIFs may fail for a variety of reasons. All BIFs fail with
+ <p>BIFs can fail for various reasons. All BIFs fail with
reason <c>badarg</c> if they are called with arguments of an
- incorrect type. The other reasons that may make BIFs fail are
- described in connection with the description of each individual
- BIF.</p>
- <p>Some BIFs may be used in guard tests, these are marked with
+ incorrect type. The other reasons are described in the
+ description of each individual BIF.</p>
+ <p>Some BIFs can be used in guard tests and are marked with
"Allowed in guard tests".</p>
</description>
<datatypes>
<datatype>
- <name><marker id="type-ext_binary">ext_binary()</marker></name>
+ <name>ext_binary()</name>
<desc>
+ <marker id="type-ext_binary"></marker>
<p>A binary data object, structured according to
the Erlang external term format.</p>
</desc>
</datatype>
+
<datatype>
<name name="timestamp"></name>
- <desc><p>See <seealso marker="#now/0">now/0</seealso>.</p>
+ <desc><p>See <seealso marker="#timestamp/0">erlang:timestamp/0</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="time_unit"></name>
+ <desc><p><marker id="type_time_unit"/>
+ Supported time unit representations:</p>
+ <taglist>
+ <tag><c>PartsPerSecond :: integer() >= 1</c></tag>
+ <item><p>Time unit expressed in parts per second. That is,
+ the time unit equals <c>1/PartsPerSecond</c> second.</p></item>
+
+ <tag><c>seconds</c></tag>
+ <item><p>Symbolic representation of the time unit
+ represented by the integer <c>1</c>.</p></item>
+
+ <tag><c>milli_seconds</c></tag>
+ <item><p>Symbolic representation of the time unit
+ represented by the integer <c>1000</c>.</p></item>
+
+ <tag><c>micro_seconds</c></tag>
+ <item><p>Symbolic representation of the time unit
+ represented by the integer <c>1000000</c>.</p></item>
+
+ <tag><c>nano_seconds</c></tag>
+ <item><p>Symbolic representation of the time unit
+ represented by the integer <c>1000000000</c>.</p></item>
+
+ <tag><c>native</c></tag>
+ <item><p>Symbolic representation of the native time unit
+ used by the Erlang runtime system.</p>
+
+ <p>The <c>native</c> time unit is determined at
+ runtime system start, and remains the same until
+ the runtime system terminates. If a runtime system
+ is stopped and then started again (even on the same
+ machine), the <c>native</c> time unit of the new
+ runtime system instance can differ from the
+ <c>native</c> time unit of the old runtime system
+ instance.</p>
+
+ <p>One can get an approximation of the <c>native</c>
+ time unit by calling <c>erlang:convert_time_unit(1,
+ seconds, native)</c>. The result equals the number
+ of whole <c>native</c> time units per second. In case
+ the number of <c>native</c> time units per second does
+ not add up to a whole number, the result is rounded downwards.</p>
+
+ <note>
+ <p>The value of the <c>native</c> time unit gives
+ you more or less no information at all about the
+ quality of time values. It sets a limit for
+ the
+ <seealso marker="time_correction#Time_Resolution">resolution</seealso>
+ as well as for the
+ <seealso marker="time_correction#Time_Precision">precision</seealso>
+ of time values,
+ but it gives absolutely no information at all about the
+ <seealso marker="time_correction#Time_Accuracy">accuracy</seealso>
+ of time values. The resolution of the <c>native</c> time
+ unit and the resolution of time values can differ
+ significantly.</p>
+ </note>
+ </item>
+
+ </taglist>
+
+ <p>The <c>time_unit/0</c> type may be extended. Use
+ <seealso marker="#convert_time_unit/3"><c>erlang:convert_time_unit/3</c></seealso>
+ in order to convert time values between time units.</p>
+
</desc>
</datatype>
</datatypes>
@@ -67,12 +139,15 @@
<func>
<name name="abs" arity="1" clause_i="1"/>
<name name="abs" arity="1" clause_i="2"/>
- <type variable="Float" name_i="1"/>
- <type variable="Int" name_i="2"/>
- <fsummary>Arithmetical absolute value</fsummary>
- <desc>
- <p>Returns an integer or float which is the arithmetical
- absolute value of <c><anno>Float</anno></c> or <c><anno>Int</anno></c>.</p>
+ <fsummary>Arithmetical absolute value.</fsummary>
+ <type>
+ <v>Float = float()</v>
+ <v>Int = integer()</v>
+ </type>
+ <desc>
+ <p>Returns an integer or float that is the arithmetical
+ absolute value of <c><anno>Float</anno></c> or
+ <c><anno>Int</anno></c>, for example:</p>
<pre>
> <input>abs(-3.33).</input>
3.33
@@ -81,206 +156,214 @@
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="adler32" arity="1"/>
- <fsummary>Compute adler32 checksum</fsummary>
+ <fsummary>Computes adler32 checksum.</fsummary>
<desc>
- <p>Computes and returns the adler32 checksum for <c><anno>Data</anno></c>.</p>
+ <p>Computes and returns the adler32 checksum for
+ <c><anno>Data</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="adler32" arity="2"/>
- <fsummary>Compute adler32 checksum</fsummary>
+ <fsummary>Computes adler32 checksum.</fsummary>
<desc>
- <p>Continue computing the adler32 checksum by combining
- the previous checksum, <c><anno>OldAdler</anno></c>, with the checksum of
- <c><anno>Data</anno></c>.</p>
- <p>The following code:</p>
- <code>
- X = erlang:adler32(Data1),
- Y = erlang:adler32(X,Data2).
- </code>
- <p>- would assign the same value to <c>Y</c> as this would:</p>
- <code>
- Y = erlang:adler32([Data1,Data2]).
- </code>
+ <p>Continues computing the adler32 checksum by combining
+ the previous checksum, <c><anno>OldAdler</anno></c>, with
+ the checksum of <c><anno>Data</anno></c>.</p>
+ <p>The following code:</p>
+ <code>
+ X = erlang:adler32(Data1),
+ Y = erlang:adler32(X,Data2).</code>
+ <p>assigns the same value to <c>Y</c> as this:</p>
+ <code>
+ Y = erlang:adler32([Data1,Data2]).</code>
</desc>
</func>
+
<func>
<name name="adler32_combine" arity="3"/>
- <fsummary>Combine two adler32 checksums</fsummary>
- <desc>
- <p>Combines two previously computed adler32 checksums.
- This computation requires the size of the data object for
- the second checksum to be known.</p>
- <p>The following code:</p>
- <code>
- Y = erlang:adler32(Data1),
- Z = erlang:adler32(Y,Data2).
- </code>
- <p>- would assign the same value to <c>Z</c> as this would:</p>
- <code>
- X = erlang:adler32(Data1),
- Y = erlang:adler32(Data2),
- Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
- </code>
+ <fsummary>Combines two adler32 checksums.</fsummary>
+ <desc>
+ <p>Combines two previously computed adler32 checksums.
+ This computation requires the size of the data object for
+ the second checksum to be known.</p>
+ <p>The following code:</p>
+ <code>
+ Y = erlang:adler32(Data1),
+ Z = erlang:adler32(Y,Data2).</code>
+ <p>assigns the same value to <c>Z</c> as this:</p>
+ <code>
+ X = erlang:adler32(Data1),
+ Y = erlang:adler32(Data2),
+ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code>
</desc>
</func>
+
<func>
<name name="append_element" arity="2"/>
- <fsummary>Append an extra element to a tuple</fsummary>
- <desc>
- <p>Returns a new tuple which has one element more than
- <c><anno>Tuple1</anno></c>, and contains the elements in <c><anno>Tuple1</anno></c>
- followed by <c><anno>Term</anno></c> as the last element. Semantically
- equivalent to
- <c>list_to_tuple(tuple_to_list(<anno>Tuple1</anno>) ++ [<anno>Term</anno>])</c>, but much
- faster.</p>
+ <fsummary>Appends an extra element to a tuple.</fsummary>
+ <desc>
+ <p>Returns a new tuple that has one element more than
+ <c><anno>Tuple1</anno></c>, and contains the elements in
+ <c><anno>Tuple1</anno></c>
+ followed by <c><anno>Term</anno></c> as the last element.
+ Semantically equivalent to
+ <c>list_to_tuple(tuple_to_list(<anno>Tuple1</anno>) ++
+ [<anno>Term</anno>])</c>, but much faster.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:append_element({one, two}, three).</input>
{one,two,three}</pre>
</desc>
</func>
+
<func>
<name name="apply" arity="2"/>
- <fsummary>Apply a function to an argument list</fsummary>
+ <fsummary>Applies a function to an argument list.</fsummary>
<desc>
- <p>Call a fun, passing the elements in <c><anno>Args</anno></c> as
- arguments.</p>
- <p>Note: If the number of elements in the arguments are known at
- compile-time, the call is better written as
+ <p>Calls a fun, passing the elements in <c><anno>Args</anno></c>
+ as arguments.</p>
+ <p>If the number of elements in the arguments are known at
+ compile time, the call is better written as
<c><anno>Fun</anno>(Arg1, Arg2, ... ArgN)</c>.</p>
<warning>
<p>Earlier, <c><anno>Fun</anno></c> could also be given as
<c>{Module, Function}</c>, equivalent to
- <c>apply(Module, Function, Args)</c>. This usage is
- deprecated and will stop working in a future release of
- Erlang/OTP.</p>
+ <c>apply(Module, Function, Args)</c>. This use is
+ deprecated and will stop working in a future release.</p>
</warning>
</desc>
</func>
+
<func>
<name name="apply" arity="3"/>
- <fsummary>Apply a function to an argument list</fsummary>
+ <fsummary>Applies a function to an argument list.</fsummary>
<desc>
<p>Returns the result of applying <c>Function</c> in
- <c><anno>Module</anno></c> to <c><anno>Args</anno></c>. The applied function must
+ <c><anno>Module</anno></c> to <c><anno>Args</anno></c>.
+ The applied function must
be exported from <c>Module</c>. The arity of the function is
the length of <c>Args</c>.</p>
+ <p>Example:</p>
<pre>
> <input>apply(lists, reverse, [[a, b, c]]).</input>
-[c,b,a]</pre>
- <p><c>apply</c> can be used to evaluate BIFs by using
- the module name <c>erlang</c>.</p>
- <pre>
+[c,b,a]
> <input>apply(erlang, atom_to_list, ['Erlang']).</input>
"Erlang"</pre>
- <p>Note: If the number of arguments are known at compile-time,
+ <p>If the number of arguments are known at compile time,
the call is better written as
<c><anno>Module</anno>:<anno>Function</anno>(Arg1, Arg2, ..., ArgN)</c>.</p>
<p>Failure: <c>error_handler:undefined_function/3</c> is called
if the applied function is not exported. The error handler
can be redefined (see
<seealso marker="#process_flag/2">process_flag/2</seealso>).
- If the <c>error_handler</c> is undefined, or if the user has
+ If <c>error_handler</c> is undefined, or if the user has
redefined the default <c>error_handler</c> so the replacement
module is undefined, an error with the reason <c>undef</c>
is generated.</p>
</desc>
</func>
+
<func>
<name name="atom_to_binary" arity="2"/>
- <fsummary>Return the binary representation of an atom</fsummary>
- <desc>
- <p>Returns a binary which corresponds to the text
- representation of <c><anno>Atom</anno></c>. If <c><anno>Encoding</anno></c>
- is <c>latin1</c>, there will be one byte for each character
- in the text representation. If <c><anno>Encoding</anno></c> is
- <c>utf8</c> or
- <c>unicode</c>, the characters will be encoded using UTF-8
- (meaning that characters from 16#80 up to 0xFF will be
- encoded in two bytes).</p>
-
- <note><p>Currently, <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> can
- never fail because the text representation of an atom can only contain
- characters from 0 to 16#FF. In a future release, the text representation
- of atoms might be allowed to contain any Unicode character
- and <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> will fail if the
- text representation for the <c><anno>Atom</anno></c> contains a Unicode
- character greater than 16#FF.</p></note>
-
+ <fsummary>Returns the binary representation of an atom.</fsummary>
+ <desc>
+ <p>Returns a binary corresponding to the text
+ representation of <c><anno>Atom</anno></c>.
+ If <c><anno>Encoding</anno></c>
+ is <c>latin1</c>, there is one byte for each character
+ in the text representation. If <c><anno>Encoding</anno></c> is
+ <c>utf8</c> or
+ <c>unicode</c>, the characters are encoded using UTF-8
+ (that is, characters from 128 through 255 are
+ encoded in two bytes).</p>
+ <note><p><c>atom_to_binary(<anno>Atom</anno>, latin1)</c> never
+ fails because the text representation of an atom can only
+ contain characters from 0 through 255. In a future release,
+ the text representation
+ of atoms can be allowed to contain any Unicode character and
+ <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> will then fail if the
+ text representation for <c><anno>Atom</anno></c> contains a Unicode
+ character greater than 255.</p></note>
+ <p>Example:</p>
<pre>
> <input>atom_to_binary('Erlang', latin1).</input>
&lt;&lt;"Erlang"&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="atom_to_list" arity="1"/>
- <fsummary>Text representation of an atom</fsummary>
+ <fsummary>Text representation of an atom.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
- representation of <c><anno>Atom</anno></c>.</p>
+ <p>Returns a string corresponding to the text
+ representation of <c><anno>Atom</anno></c>, for example:</p>
<pre>
> <input>atom_to_list('Erlang').</input>
"Erlang"</pre>
</desc>
</func>
+
<func>
<name name="binary_part" arity="2"/>
- <fsummary>Extracts a part of a binary</fsummary>
+ <fsummary>Extracts a part of a binary.</fsummary>
<desc>
- <p>Extracts the part of the binary described by <c><anno>PosLen</anno></c>.</p>
-
- <p>Negative length can be used to extract bytes at the end of a binary:</p>
-
+ <p>Extracts the part of the binary described by
+ <c><anno>PosLen</anno></c>.</p>
+ <p>Negative length can be used to extract bytes at the end
+ of a binary, for example:</p>
<code>
1> Bin = &lt;&lt;1,2,3,4,5,6,7,8,9,10&gt;&gt;.
2> binary_part(Bin,{byte_size(Bin), -5}).
-&lt;&lt;6,7,8,9,10&gt;&gt;
-</code>
-
- <p>If <c><anno>PosLen</anno></c> in any way references outside the binary, a <c>badarg</c> exception is raised.</p>
-
- <p><c><anno>Start</anno></c> is zero-based, i.e.:</p>
+&lt;&lt;6,7,8,9,10&gt;&gt;</code>
+ <p>Failure: <c>badarg</c> if <c><anno>PosLen</anno></c> in any way
+ references outside the binary.</p>
+ <p><c><anno>Start</anno></c> is zero-based, that is:</p>
<code>
1> Bin = &lt;&lt;1,2,3&gt;&gt;
2> binary_part(Bin,{0,2}).
-&lt;&lt;1,2&gt;&gt;
-</code>
-
- <p>See the STDLIB module <c>binary</c> for details about the <c><anno>PosLen</anno></c> semantics.</p>
-
+&lt;&lt;1,2&gt;&gt;</code>
+ <p>For details about the <c><anno>PosLen</anno></c> semantics, see the
+ <seealso marker="stdlib:binary">binary</seealso>
+ manual page in <c>STDLIB</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="binary_part" arity="3"/>
- <fsummary>Extracts a part of a binary</fsummary>
+ <fsummary>Extracts a part of a binary.</fsummary>
<desc>
- <p>The same as <c>binary_part(<anno>Subject</anno>, {<anno>Start</anno>, <anno>Length</anno>})</c>.</p>
-
+ <p>The same as <c>binary_part(<anno>Subject</anno>,
+ {<anno>Start</anno>, <anno>Length</anno>})</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="binary_to_atom" arity="2"/>
- <fsummary>Convert from text representation to an atom</fsummary>
+ <fsummary>Converts from text representation to an atom.</fsummary>
<desc>
<p>Returns the atom whose text representation is
- <c><anno>Binary</anno></c>. If <c><anno>Encoding</anno></c> is <c>latin1</c>, no
- translation of bytes in the binary is done. If <c><anno>Encoding</anno></c>
- is <c>utf8</c> or <c>unicode</c>, the binary must contain
- valid UTF-8 sequences; furthermore, only Unicode characters up
- to 0xFF are allowed.</p>
-
- <note><p><c>binary_to_atom(<anno>Binary</anno>, utf8)</c> will fail if
- the binary contains Unicode characters greater than 16#FF.
- In a future release, such Unicode characters might be allowed
- and <c>binary_to_atom(<anno>Binary</anno>, utf8)</c>
- will not fail in that case. For more information on Unicode support in atoms
- see <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8 encoded atoms</seealso>
- in the chapter about the external term format in the ERTS User's Guide.</p></note>
-
+ <c><anno>Binary</anno></c>.
+ If <c><anno>Encoding</anno></c> is <c>latin1</c>, no
+ translation of bytes in the binary is done.
+ If <c><anno>Encoding</anno></c>
+ is <c>utf8</c> or <c>unicode</c>, the binary must contain
+ valid UTF-8 sequences. Only Unicode characters up
+ to 255 are allowed.</p>
+ <note><p><c>binary_to_atom(<anno>Binary</anno>, utf8)</c> fails if
+ the binary contains Unicode characters greater than 255.
+ In a future release, such Unicode characters can be allowed
+ and <c>binary_to_atom(<anno>Binary</anno>, utf8)</c> does then not fail.
+ For more information on Unicode support in atoms, see the
+ <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8
+ encoded atoms</seealso>
+ in Section "External Term Format" in the User's Guide.</p></note>
+ <p>Examples:</p>
<pre>
> <input>binary_to_atom(&lt;&lt;"Erlang"&gt;&gt;, latin1).</input>
'Erlang'
@@ -290,20 +373,24 @@
called as binary_to_atom(&lt;&lt;208,128&gt;&gt;,utf8)</pre>
</desc>
</func>
+
<func>
<name name="binary_to_existing_atom" arity="2"/>
- <fsummary>Convert from text representation to an atom</fsummary>
+ <fsummary>Converts from text representation to an atom.</fsummary>
<desc>
- <p>Works like <seealso marker="#binary_to_atom/2">binary_to_atom/2</seealso>,
- but the atom must already exist.</p>
- <p>Failure: <c>badarg</c> if the atom does not already exist.</p>
+ <p>As
+ <seealso marker="#binary_to_atom/2">binary_to_atom/2</seealso>,
+ but the atom must exist.</p>
+ <p>Failure: <c>badarg</c> if the atom does not exist.</p>
</desc>
</func>
+
<func>
<name name="binary_to_float" arity="1"/>
- <fsummary>Convert from text representation to a float</fsummary>
+ <fsummary>Converts from text representation to a float.</fsummary>
<desc>
- <p>Returns the float whose text representation is <c><anno>Binary</anno></c>.</p>
+ <p>Returns the float whose text representation is
+ <c><anno>Binary</anno></c>, for example:</p>
<pre>
> <input>binary_to_float(&lt;&lt;"2.2017764e+0">>).</input>
2.2017764</pre>
@@ -311,12 +398,13 @@
representation of a float.</p>
</desc>
</func>
+
<func>
<name name="binary_to_integer" arity="1"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation is
- <c><anno>Binary</anno></c>.</p>
+ <c><anno>Binary</anno></c>, for example:</p>
<pre>
> <input>binary_to_integer(&lt;&lt;"123"&gt;&gt;).</input>
123</pre>
@@ -324,12 +412,13 @@
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="binary_to_integer" arity="2"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation in base
- <c><anno>Base</anno></c> is <c><anno>Binary</anno></c>.</p>
+ <c><anno>Base</anno></c> is <c><anno>Binary</anno></c>, for example:</p>
<pre>
> <input>binary_to_integer(&lt;&lt;"3FF"&gt;&gt;, 16).</input>
1023</pre>
@@ -337,93 +426,101 @@
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="binary_to_list" arity="1"/>
- <fsummary>Convert a binary to a list</fsummary>
+ <fsummary>Converts a binary to a list.</fsummary>
<desc>
- <p>Returns a list of integers which correspond to the bytes of
+ <p>Returns a list of integers corresponding to the bytes of
<c><anno>Binary</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="binary_to_list" arity="3"/>
- <fsummary>Convert part of a binary to a list</fsummary>
- <type_desc variable="Start">1..byte_size(<anno>Binary</anno>)</type_desc>
+ <fsummary>Converts part of a binary to a list.</fsummary>
+ <type_desc variable="Start">1..byte_size(<c><anno>Binary</anno></c>)</type_desc>
<desc>
<p>As <c>binary_to_list/1</c>, but returns a list of integers
corresponding to the bytes from position <c><anno>Start</anno></c> to
- position <c><anno>Stop</anno></c> in <c><anno>Binary</anno></c>. Positions in the
+ position <c><anno>Stop</anno></c> in <c><anno>Binary</anno></c>.
+ The positions in the
binary are numbered starting from 1.</p>
-
- <note><p>This function's indexing style of using one-based indices for
- binaries is deprecated. New code should use the functions in
- the STDLIB module <c>binary</c> instead. They consequently
- use the same (zero-based) style of indexing.</p></note>
+ <note><p>The one-based indexing for binaries used by
+ this function is deprecated. New code is to use
+ <seealso marker="stdlib:binary#bin_to_list/3">binary:bin_to_list/3</seealso>
+ in <c>STDLIB</c> instead. All functions in module
+ <c>binary</c> consistently use zero-based indexing.</p></note>
</desc>
</func>
+
<func>
<name name="bitstring_to_list" arity="1"/>
- <fsummary>Convert a bitstring to a list</fsummary>
+ <fsummary>Converts a bitstring to a list.</fsummary>
<desc>
- <p>Returns a list of integers which correspond to the bytes of
- <c><anno>Bitstring</anno></c>. If the number of bits in the binary is not
- divisible by 8, the last element of the list will be a bitstring
- containing the remaining bits (1 up to 7 bits).</p>
+ <p>Returns a list of integers corresponding to the bytes of
+ <c><anno>Bitstring</anno></c>. If the number of bits in the binary
+ is not divisible by 8, the last element of the list is a bitstring
+ containing the remaining 1-7 bits.</p>
</desc>
</func>
+
<func>
<name name="binary_to_term" arity="1"/>
- <fsummary>Decode an Erlang external term format binary</fsummary>
+ <fsummary>Decodes an Erlang external term format binary.</fsummary>
<desc>
- <p>Returns an Erlang term which is the result of decoding
- the binary object <c><anno>Binary</anno></c>, which must be encoded
+ <p>Returns an Erlang term that is the result of decoding
+ binary object <c><anno>Binary</anno></c>, which must be encoded
according to the Erlang external term format.</p>
- <warning>
- <p>When decoding binaries from untrusted sources, consider using
- <c>binary_to_term/2</c> to prevent denial of service attacks.</p>
- </warning>
- <p>See also
- <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>
- and
- <seealso marker="#binary_to_term/2">binary_to_term/2</seealso>.</p>
+ <warning><p>When decoding binaries from untrusted sources,
+ consider using <c>binary_to_term/2</c> to prevent Denial
+ of Service attacks.</p></warning>
+ <p>See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>
+ and
+ <seealso marker="#binary_to_term/2">binary_to_term/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="binary_to_term" arity="2"/>
- <fsummary>Decode an Erlang external term format binary</fsummary>
+ <fsummary>Decodes an Erlang external term format binary.</fsummary>
<desc>
<p>As <c>binary_to_term/1</c>, but takes options that affect decoding
of the binary.</p>
<taglist>
<tag><c>safe</c></tag>
<item>
- <p>Use this option when receiving binaries from an untrusted
+ <p>Use this option when receiving binaries from an untrusted
source.</p>
- <p>When enabled, it prevents decoding data that may be used to
- attack the Erlang system. In the event of receiving unsafe
- data, decoding fails with a badarg error.</p>
- <p>Currently, this prevents creation of new atoms directly,
- creation of new atoms indirectly (as they are embedded in
- certain structures like pids, refs, funs, etc.), and creation of
- new external function references. None of those resources are
- currently garbage collected, so unchecked creation of them can
- exhaust available memory.</p>
+ <p>When enabled, it prevents decoding data that can be used to
+ attack the Erlang system. In the event of receiving unsafe
+ data, decoding fails with a <c>badarg</c> error.</p>
+ <p>This prevents creation of new atoms directly,
+ creation of new atoms indirectly (as they are embedded in
+ certain structures, such as process identifiers,
+ refs, and funs), and
+ creation of new external function references.
+ None of those resources are garbage collected, so unchecked
+ creation of them can exhaust available memory.</p>
</item>
</taglist>
- <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe data
- is decoded.</p>
+ <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe
+ data is decoded.</p>
<p>See also
<seealso marker="#term_to_binary/1">term_to_binary/1</seealso>,
<seealso marker="#binary_to_term/1">binary_to_term/1</seealso>,
- and <seealso marker="#list_to_existing_atom/1">
- list_to_existing_atom/1</seealso>.</p>
+ and
+ <seealso marker="#list_to_existing_atom/1">list_to_existing_atom/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="bit_size" arity="1"/>
- <fsummary>Return the size of a bitstring</fsummary>
+ <fsummary>Returns the size of a bitstring.</fsummary>
<desc>
- <p>Returns an integer which is the size in bits of <c><anno>Bitstring</anno></c>.</p>
+ <p>Returns an integer that is the size in bits of
+ <c><anno>Bitstring</anno></c>, for example:</p>
<pre>
> <input>bit_size(&lt;&lt;433:16,3:3&gt;&gt;).</input>
19
@@ -432,30 +529,34 @@
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="bump_reductions" arity="1"/>
- <fsummary>Increment the reduction counter</fsummary>
+ <fsummary>Increments the reduction counter.</fsummary>
<desc>
<p>This implementation-dependent function increments
the reduction counter for the calling process. In the Beam
emulator, the reduction counter is normally incremented by
- one for each function and BIF call, and a context switch is
- forced when the counter reaches the maximum number of reductions
- for a process (2000 reductions in R12B).</p>
+ one for each function and BIF call. A context switch is
+ forced when the counter reaches the maximum number of
+ reductions for a process (2000 reductions in OTP R12B).</p>
<warning>
- <p>This BIF might be removed in a future version of the Beam
+ <p>This BIF can be removed in a future version of the Beam
machine without prior warning. It is unlikely to be
implemented in other Erlang implementations.</p>
</warning>
</desc>
</func>
+
<func>
<name name="byte_size" arity="1"/>
- <fsummary>Return the size of a bitstring (or binary)</fsummary>
+ <fsummary>Returns the size of a bitstring (or binary).</fsummary>
<desc>
- <p>Returns an integer which is the number of bytes needed to contain
- <c><anno>Bitstring</anno></c>. (That is, if the number of bits in <c><anno>Bitstring</anno></c> is not
- divisible by 8, the resulting number of bytes will be rounded <em>up</em>.)</p>
+ <p>Returns an integer that is the number of bytes needed to
+ contain <c><anno>Bitstring</anno></c>. That is, if the number of bits
+ in <c><anno>Bitstring</anno></c> is not divisible by 8, the resulting
+ number of bytes is rounded <em>up</em>.</p>
+ <p>Examples:</p>
<pre>
> <input>byte_size(&lt;&lt;433:16,3:3&gt;&gt;).</input>
3
@@ -464,222 +565,319 @@
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
- <name name="cancel_timer" arity="1"/>
- <fsummary>Cancel a timer</fsummary>
- <desc>
- <p>Cancels a timer, where <c><anno>TimerRef</anno></c> was returned by
- either
- <seealso marker="#send_after/3">erlang:send_after/3</seealso>
- or
- <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>.
- If the timer is there to be removed, the function returns
- the time in milliseconds left until the timer would have expired,
- otherwise <c>false</c> (which means that <c><anno>TimerRef</anno></c> was
- never a timer, that it has already been cancelled, or that it
- has already delivered its message).</p>
+ <name name="cancel_timer" arity="2"/>
+ <fsummary>Cancels a timer.</fsummary>
+ <desc>
+ <p>
+ Cancels a timer that has been created by
+ <seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>,
+ or <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>.
+ <c><anno>TimerRef</anno></c> identifies the timer, and
+ was returned by the BIF that created the timer.
+ </p>
+ <p>Available <c><anno>Option</anno></c>s:</p>
+ <taglist>
+ <tag><c>{async, Async}</c></tag>
+ <item>
+ <p>
+ Asynchronous request for cancellation. <c>Async</c>
+ defaults to <c>false</c> which will cause the
+ cancellation to be performed synchronously. When
+ <c>Async</c> is set to <c>true</c>, the cancel
+ operation is performed asynchronously. That is,
+ <c>erlang:cancel_timer()</c> will send an asynchronous
+ request for cancellation to the timer service that
+ manages the timer, and then return <c>ok</c>.
+ </p>
+ </item>
+ <tag><c>{info, Info}</c></tag>
+ <item>
+ <p>
+ Request information about the <c><anno>Result</anno></c>
+ of the cancellation. <c>Info</c> defaults to <c>true</c>
+ which means the <c><anno>Result</anno></c> is
+ given. When <c>Info</c> is set to <c>false</c>, no
+ information about the result of the cancellation
+ is given. When the operation is performed</p>
+ <taglist>
+ <tag>synchronously</tag>
+ <item>
+ <p>
+ If <c>Info</c> is <c>true</c>, the <c>Result</c> is
+ returned by <c>erlang:cancel_timer()</c>; otherwise,
+ <c>ok</c> is returned.
+ </p>
+ </item>
+ <tag>asynchronously</tag>
+ <item>
+ <p>
+ If <c>Info</c> is <c>true</c>, a message on the form
+ <c>{cancel_timer, <anno>TimerRef</anno>,
+ <anno>Result</anno>}</c> is sent to the
+ caller of <c>erlang:cancel_timer()</c> when the
+ cancellation operation has been performed; otherwise,
+ no message is sent.
+ </p>
+ </item>
+ </taglist>
+ </item>
+ </taglist>
+ <p>
+ More <c><anno>Option</anno></c>s may be added in the future.
+ </p>
+ <p>If <c><anno>Result</anno></c> is an integer, it represents
+ the time in milli-seconds left until the canceled timer would
+ have expired.</p>
+ <p>
+ If <c><anno>Result</anno></c> is <c>false</c>, a
+ timer corresponding to <c><anno>TimerRef</anno></c> could not
+ be found. This can be either because the timer had expired,
+ already had been canceled, or because <c><anno>TimerRef</anno></c>
+ never corresponded to a timer. Even if the timer had expired,
+ it does not tell you whether or not the timeout message has
+ arrived at its destination yet.
+ </p>
+ <note>
+ <p>
+ The timer service that manages the timer may be co-located
+ with another scheduler than the scheduler that the calling
+ process is executing on. If this is the case, communication
+ with the timer service takes much longer time than if it
+ is located locally. If the calling process is in critical
+ path, and can do other things while waiting for the result
+ of this operation, or is not interested in the result of
+ the operation, you want to use option <c>{async, true}</c>.
+ If using option <c>{async, false}</c>, the calling
+ process blocks until the operation has been performed.
+ </p>
+ </note>
<p>See also
- <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#send_after/4"><c>erlang:send_after/4</c></seealso>,
+ <seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>,
and
- <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
- <p>Note: Cancelling a timer does not guarantee that the message
- has not already been delivered to the message queue.</p>
+ <seealso marker="#read_timer/2"><c>erlang:read_timer/2</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="cancel_timer" arity="1"/>
+ <fsummary>Cancels a timer.</fsummary>
+ <desc>
+ <p>Cancels a timer. The same as calling
+ <seealso marker="#cancel_timer/2"><c>erlang:cancel_timer(TimerRef,
+ [])</c></seealso>.</p>
</desc>
</func>
-
<func>
<name name="check_old_code" arity="1"/>
- <fsummary>Check if a module has old code</fsummary>
+ <fsummary>Checks if a module has old code.</fsummary>
<desc>
- <p>Returns <c>true</c> if the <c><anno>Module</anno></c> has old code,
- and <c>false</c> otherwise.</p>
+ <p>Returns <c>true</c> if <c><anno>Module</anno></c> has old code,
+ otherwise <c>false</c>.</p>
<p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="check_process_code" arity="2"/>
- <fsummary>Check if a process is executing old code for a module</fsummary>
+ <fsummary>Checks if a process executes old code for a module.</fsummary>
<desc>
<p>The same as
- <seealso marker="#check_process_code/3"><c>erlang:check_process_code(<anno>Pid</anno>,
- <anno>Module</anno>, [])</c></seealso>.</p>
+ <seealso marker="#check_process_code/3"><c>erlang:check_process_code(<anno>Pid</anno>, <anno>Module</anno>, [])</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="check_process_code" arity="3"/>
- <fsummary>Check if a process is executing old code for a module</fsummary>
+ <fsummary>Checks if a process executes old code for a module.</fsummary>
<desc>
- <p>Check if the node local process identified by <c><anno>Pid</anno></c>
- is executing old code for <c><anno>Module</anno></c>.</p>
- <p>Currently available <c><anno>Option</anno>s</c>:</p>
+ <p>Checks if the node local process identified by <c><anno>Pid</anno></c>
+ executes old code for <c><anno>Module</anno></c>.</p>
+ <p>The available <c><anno>Option</anno></c>s are as follows:</p>
<taglist>
<tag><c>{allow_gc, boolean()}</c></tag>
<item>
- Determines if garbage collection is allowed when performing
- the operation. If <c>{allow_gc, false}</c> is passed, and
- a garbage collection is needed in order to determine the
- result of the operation, the operation will be aborted
- (see information on <c><anno>CheckResult</anno></c> below).
- The default is to allow garbage collection, i.e.,
- <c>{allow_gc, true}</c>.
+ <p>Determines if garbage collection is allowed when performing
+ the operation. If <c>{allow_gc, false}</c> is passed, and
+ a garbage collection is needed to determine the
+ result of the operation, the operation is aborted (see
+ information on <c><anno>CheckResult</anno></c> in the following).
+ The default is to allow garbage collection, that is,
+ <c>{allow_gc, true}</c>.</p>
</item>
<tag><c>{async, RequestId}</c></tag>
<item>
- The <c>check_process_code/3</c> function will return
- the value <c>async</c> immediately after the request
- has been sent. When the request has been processed, the
- process that called this function will be passed a
- message on the form:<br/>
- <c>{check_process_code, <anno>RequestId</anno>, <anno>CheckResult</anno>}</c>.
+ <p>The function <c>check_process_code/3</c> returns
+ the value <c>async</c> immediately after the request
+ has been sent. When the request has been processed, the
+ process that called this function is passed a
+ message on the form
+ <c>{check_process_code, <anno>RequestId</anno>, <anno>CheckResult</anno>}</c>.</p>
</item>
</taglist>
- <p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
- no <c>async</c> option has been passed, the operation will
- be performed at once. In all other cases a request for
- the operation will be sent to the process identified by
- <c><anno>Pid</anno></c>, and will be handled when
- appropriate. If no <c>async</c> option has been passed,
- the caller will block until <c><anno>CheckResult</anno></c>
- is available and can be returned.</p>
- <p><c><anno>CheckResult</anno></c> informs about the result of
- the request:</p>
+ <p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
+ no <c>async</c> option has been passed, the operation
+ is performed at once. Otherwise a request for
+ the operation is sent to the process identified by
+ <c><anno>Pid</anno></c>, and is handled when
+ appropriate. If no <c>async</c> option has been passed,
+ the caller blocks until <c><anno>CheckResult</anno></c>
+ is available and can be returned.</p>
+ <p><c><anno>CheckResult</anno></c> informs about the result of
+ the request as follows:</p>
<taglist>
<tag><c>true</c></tag>
<item>
- The process identified by <c><anno>Pid</anno></c> is
- executing old code for <c><anno>Module</anno></c>.
- That is, the current call of the process executes old
- code for this module, or the process has references
- to old code for this module, or the process contains
- funs that references old code for this module.
+ <p>The process identified by <c><anno>Pid</anno></c>
+ executes old code for <c><anno>Module</anno></c>.
+ That is, the current call of the process executes old
+ code for this module, or the process has references
+ to old code for this module, or the process contains
+ funs that references old code for this module.</p>
</item>
<tag><c>false</c></tag>
<item>
- The process identified by <c><anno>Pid</anno></c> is
- not executing old code for <c><anno>Module</anno></c>.
+ <p>The process identified by <c><anno>Pid</anno></c> does
+ not execute old code for <c><anno>Module</anno></c>.</p>
</item>
<tag><c>aborted</c></tag>
<item>
- The operation was aborted since the process needed to
- be garbage collected in order to determine the result
- of the operation, and the operation was requested
- by passing the <c>{allow_gc, false}</c> option.</item>
+ <p>The operation was aborted, as the process needed to
+ be garbage collected to determine the operation result,
+ and the operation was requested
+ by passing option <c>{allow_gc, false}</c>.</p></item>
</taglist>
<p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
- <item>
- If <c><anno>Pid</anno></c> is not a node local process identifier.
+ <item>If <c><anno>Pid</anno></c> is not a node local process identifier.
</item>
<tag><c>badarg</c></tag>
- <item>
- If <c><anno>Module</anno></c> is not an atom.
+ <item>If <c><anno>Module</anno></c> is not an atom.
</item>
<tag><c>badarg</c></tag>
- <item>
- If <c><anno>OptionList</anno></c> is not a valid list of options.
+ <item>If <c><anno>OptionList</anno></c> is an invalid list of options.
</item>
</taglist>
</desc>
</func>
+
+ <func>
+ <name name="convert_time_unit" arity="3"/>
+ <fsummary>Converts time unit of a time value.</fsummary>
+ <desc>
+ <p>Converts the <c><anno>Time</anno></c> value of time unit
+ <c><anno>FromUnit</anno></c> to the corresponding
+ <c><anno>ConvertedTime</anno></c> value of time unit
+ <c><anno>ToUnit</anno></c>. The result is rounded
+ using the floor function.</p>
+
+ <warning><p>You may lose accuracy and precision when converting
+ between time units. In order to minimize such loss, collect all
+ data at <c>native</c> time unit and do the conversion on the end
+ result.</p></warning>
+ </desc>
+ </func>
<func>
<name name="crc32" arity="1"/>
- <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
+ <fsummary>Computes crc32 (IEEE 802.3) checksum.</fsummary>
<desc>
- <p>Computes and returns the crc32 (IEEE 802.3 style) checksum for <c><anno>Data</anno></c>.</p>
+ <p>Computes and returns the crc32 (IEEE 802.3 style) checksum
+ for <c><anno>Data</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="crc32" arity="2"/>
- <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
+ <fsummary>Computes crc32 (IEEE 802.3) checksum.</fsummary>
<desc>
- <p>Continue computing the crc32 checksum by combining
- the previous checksum, <c><anno>OldCrc</anno></c>, with the checksum of
- <c><anno>Data</anno></c>.</p>
- <p>The following code:</p>
- <code>
- X = erlang:crc32(Data1),
- Y = erlang:crc32(X,Data2).
- </code>
- <p>- would assign the same value to <c>Y</c> as this would:</p>
- <code>
- Y = erlang:crc32([Data1,Data2]).
- </code>
+ <p>Continues computing the crc32 checksum by combining
+ the previous checksum, <c><anno>OldCrc</anno></c>, with the checksum of
+ <c><anno>Data</anno></c>.</p>
+ <p>The following code:</p>
+ <code>
+ X = erlang:crc32(Data1),
+ Y = erlang:crc32(X,Data2).</code>
+ <p>assigns the same value to <c>Y</c> as this:</p>
+ <code>
+ Y = erlang:crc32([Data1,Data2]).</code>
</desc>
</func>
+
<func>
<name name="crc32_combine" arity="3"/>
- <fsummary>Combine two crc32 (IEEE 802.3) checksums</fsummary>
- <desc>
- <p>Combines two previously computed crc32 checksums.
- This computation requires the size of the data object for
- the second checksum to be known.</p>
- <p>The following code:</p>
- <code>
- Y = erlang:crc32(Data1),
- Z = erlang:crc32(Y,Data2).
- </code>
- <p>- would assign the same value to <c>Z</c> as this would:</p>
+ <fsummary>Combines two crc32 (IEEE 802.3) checksums.</fsummary>
+ <desc>
+ <p>Combines two previously computed crc32 checksums.
+ This computation requires the size of the data object for
+ the second checksum to be known.</p>
+ <p>The following code:</p>
+ <code>
+ Y = erlang:crc32(Data1),
+ Z = erlang:crc32(Y,Data2).</code>
+ <p>assigns the same value to <c>Z</c> as this:</p>
<code>
- X = erlang:crc32(Data1),
- Y = erlang:crc32(Data2),
- Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).
- </code>
+ X = erlang:crc32(Data1),
+ Y = erlang:crc32(Data2),
+ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code>
</desc>
</func>
+
<func>
<name name="date" arity="0"/>
- <fsummary>Current date</fsummary>
+ <fsummary>Current date.</fsummary>
<desc>
<p>Returns the current date as <c>{Year, Month, Day}</c>.</p>
- <p>The time zone and daylight saving time correction depend on
+ <p>The time zone and Daylight Saving Time correction depend on
the underlying OS.</p>
+ <p>Example:</p>
<pre>
> <input>date().</input>
{1995,2,19}</pre>
</desc>
</func>
+
<func>
<name name="decode_packet" arity="3"/>
- <fsummary>Extracts a protocol packet from a binary</fsummary>
+ <fsummary>Extracts a protocol packet from a binary.</fsummary>
<desc>
-
<p>Decodes the binary <c><anno>Bin</anno></c> according to the packet
- protocol specified by <c><anno>Type</anno></c>. Very similar to the packet
- handling done by sockets with the option {packet,<anno>Type</anno>}.</p>
- <p>If an entire packet is contained in <c><anno>Bin</anno></c> it is
+ protocol specified by <c><anno>Type</anno></c>. Similar to the packet
+ handling done by sockets with option {packet,<anno>Type</anno>}.</p>
+ <p>If an entire packet is contained in <c><anno>Bin</anno></c>, it is
returned together with the remainder of the binary as
<c>{ok,<anno>Packet</anno>,<anno>Rest</anno>}</c>.</p>
<p>If <c><anno>Bin</anno></c> does not contain the entire packet,
- <c>{more,<anno>Length</anno>}</c> is returned. <c><anno>Length</anno></c> is either the
- expected <em>total size</em> of the packet or <c>undefined</c>
- if the expected packet size is not known. <c>decode_packet</c>
+ <c>{more,<anno>Length</anno>}</c> is returned.
+ <c><anno>Length</anno></c> is either the
+ expected <em>total size</em> of the packet, or <c>undefined</c>
+ if the expected packet size is unknown. <c>decode_packet</c>
can then be called again with more data added.</p>
- <p>If the packet does not conform to the protocol format
+ <p>If the packet does not conform to the protocol format,
<c>{error,<anno>Reason</anno>}</c> is returned.</p>
- <p>The following values of <c><anno>Type</anno></c> are valid:</p>
+ <p>The following <c>Type</c>s are valid:</p>
<taglist>
<tag><c>raw | 0</c></tag>
<item>
- <p>No packet handling is done. Entire binary is
+ <p>No packet handling is done. The entire binary is
returned unless it is empty.</p>
</item>
<tag><c>1 | 2 | 4</c></tag>
<item>
<p>Packets consist of a header specifying the number of
bytes in the packet, followed by that number of bytes.
- The length of header can be one, two, or four bytes;
+ The length of the header can be one, two, or four bytes;
the order of the bytes is big-endian. The header
- will be stripped off when the packet is returned.</p>
+ is stripped off when the packet is returned.</p>
</item>
<tag><c>line</c></tag>
<item>
- <p>A packet is a line terminated with newline. The
- newline character is included in the returned packet
- unless the line was truncated according to the option
- <c>line_length</c>.</p>
+ <p>A packet is a line terminated by a delimiter byte,
+ default is the latin1 newline character. The delimiter
+ byte is included in the returned packet unless the line
+ was truncated according to option <c>line_length</c>.</p>
</item>
<tag><c>asn1 | cdr | sunrm | fcgi | tpkt</c></tag>
<item>
@@ -697,41 +895,50 @@
<item>
<p>The Hypertext Transfer Protocol. The packets
are returned with the format according to
- <c><anno>HttpPacket</anno></c> described above. A packet is either a
- request, a response, a header or an end of header
- mark. Invalid lines are returned as <c><anno>HttpError</anno></c>.</p>
- <p>Recognized request methods and header fields are returned as atoms.
- Others are returned as strings. Strings of unrecognized header fields
- are formatted with only capital letters first and after hyphen characters
- (like <c>"Sec-Websocket-Key"</c>).</p>
- <p>The protocol type <c>http</c> should only be used for
- the first line when a <c><anno>HttpRequest</anno></c> or a
- <c><anno>HttpResponse</anno></c> is expected. The following calls
- should use <c>httph</c> to get <c><anno>HttpHeader</anno></c>'s until
- <c>http_eoh</c> is returned that marks the end of the
+ <c><anno>HttpPacket</anno></c> described earlier.
+ A packet is either a
+ request, a response, a header, or an end of header
+ mark. Invalid lines are returned as
+ <c><anno>HttpError</anno></c>.</p>
+ <p>Recognized request methods and header fields are returned
+ as atoms. Others are returned as strings. Strings of
+ unrecognized header fields are formatted with only
+ capital letters first and after hyphen characters, for
+ example, <c>"Sec-Websocket-Key"</c>.</p>
+ <p>The protocol type <c>http</c> is only to be used for
+ the first line when an <c><anno>HttpRequest</anno></c> or an
+ <c><anno>HttpResponse</anno></c> is expected.
+ The following calls are to use <c>httph</c> to get
+ <c><anno>HttpHeader</anno></c>s until
+ <c>http_eoh</c> is returned, which marks the end of the
headers and the beginning of any following message body.</p>
- <p>The variants <c>http_bin</c> and <c>httph_bin</c> will return
+ <p>The variants <c>http_bin</c> and <c>httph_bin</c> return
strings (<c>HttpString</c>) as binaries instead of lists.</p>
</item>
</taglist>
<p>The following options are available:</p>
<taglist>
<tag><c>{packet_size, integer() >= 0}</c></tag>
- <item><p>Sets the max allowed size of the packet body. If
- the packet header indicates that the length of the
- packet is longer than the max allowed length, the packet
- is considered invalid. Default is 0 which means no
- size limit.</p>
+ <item><p>Sets the maximum allowed size of the packet body.
+ If the packet header indicates that the length of the
+ packet is longer than the maximum allowed length, the
+ packet is considered invalid. Default is 0, which means
+ no size limit.</p>
</item>
<tag><c>{line_length, integer() >= 0}</c></tag>
- <item><p>For packet type <c>line</c>, truncate lines longer
- than the indicated length.</p>
- <p>Option <c>line_length</c> also applies to <c>http*</c>
- packet types as an alias for option <c>packet_size</c> in the
- case when <c>packet_size</c> itself is not set. This usage is
- only intended for backward compatibility.</p>
+ <item><p>For packet type <c>line</c>, lines longer than
+ the indicated length are truncated.</p>
+ <p>Option <c>line_length</c> also applies to <c>http*</c>
+ packet types as an alias for option <c>packet_size</c>
+ if <c>packet_size</c> itself is not set. This use is
+ only intended for backward compatibility.</p>
+ </item>
+ <tag><c>{line_delimiter, 0 =&lt; byte() =&lt; 255}</c></tag>
+ <item><p>For packet type <c>line</c>, sets the delimiting byte.
+ Default is the latin1 character <c>$\n</c>.</p>
</item>
</taglist>
+ <p>Examples:</p>
<pre>
> <input>erlang:decode_packet(1,&lt;&lt;3,"abcd"&gt;&gt;,[]).</input>
{ok,&lt;&lt;"abc"&gt;&gt;,&lt;&lt;"d"&gt;&gt;}
@@ -742,13 +949,11 @@
<func>
<name name="delete_element" arity="2"/>
- <fsummary>Delete element at index in a tuple</fsummary>
+ <fsummary>Deletes element at index in a tuple.</fsummary>
<type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>)</type_desc>
<desc>
- <p>
- Returns a new tuple with element at <c><anno>Index</anno></c> removed from
- tuple <c><anno>Tuple1</anno></c>.
- </p>
+ <p>Returns a new tuple with element at <c><anno>Index</anno></c>
+ removed from tuple <c><anno>Tuple1</anno></c>, for example:</p>
<pre>
> <input>erlang:delete_element(2, {one, two, three}).</input>
{one,three}</pre>
@@ -757,45 +962,49 @@
<func>
<name name="delete_module" arity="1"/>
- <fsummary>Make the current code for a module old</fsummary>
+ <fsummary>Makes the current code for a module old.</fsummary>
<desc>
- <p>Makes the current code for <c><anno>Module</anno></c> become old code, and
- deletes all references for this module from the export table.
+ <p>Makes the current code for <c><anno>Module</anno></c> become old code,
+ and deletes all references for this module from the export table.
Returns <c>undefined</c> if the module does not exist,
otherwise <c>true</c>.</p>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
- used elsewhere.</p>
+ <seealso marker="kernel:code">code(3)</seealso>) and is not
+ to be used elsewhere.</p>
</warning>
- <p>Failure: <c>badarg</c> if there is already an old version of
+ <p>Failure: <c>badarg</c> if there already is an old version of
<c>Module</c>.</p>
</desc>
</func>
+
<func>
<name name="demonitor" arity="1"/>
- <fsummary>Stop monitoring</fsummary>
+ <fsummary>Stops monitoring.</fsummary>
<desc>
- <p>If <c><anno>MonitorRef</anno></c> is a reference which the calling process
- obtained by calling
+ <p>If <c><anno>MonitorRef</anno></c> is a reference that the
+ calling process obtained by calling
<seealso marker="#monitor/2">monitor/2</seealso>,
this monitoring is turned off. If the monitoring is already
turned off, nothing happens.</p>
- <p>Once <c>demonitor(<anno>MonitorRef</anno>)</c> has returned it is
- guaranteed that no <c>{'DOWN', <anno>MonitorRef</anno>, _, _, _}</c> message
- due to the monitor will be placed in the caller's message queue
- in the future. A <c>{'DOWN', <anno>MonitorRef</anno>, _, _, _}</c> message
- might have been placed in the caller's message queue prior to
- the call, though. Therefore, in most cases, it is advisable
+ <p>Once <c>demonitor(<anno>MonitorRef</anno>)</c> has returned, it is
+ guaranteed that no <c>{'DOWN',
+ <anno>MonitorRef</anno>, _, _, _}</c> message,
+ because of the monitor, will be placed in the caller message queue
+ in the future. A <c>{'DOWN',
+ <anno>MonitorRef</anno>, _, _, _}</c> message
+ can have been placed in the caller message queue before
+ the call, though. It is therefore usually advisable
to remove such a <c>'DOWN'</c> message from the message queue
- after monitoring has been stopped.
- <seealso marker="#demonitor/2">demonitor(<anno>MonitorRef</anno>, [flush])</seealso> can be used instead of
+ after monitoring has been stopped.
+ <seealso marker="#demonitor/2"><c>demonitor(<anno>MonitorRef</anno>, [flush])</c></seealso>
+ can be used instead of
<c>demonitor(<anno>MonitorRef</anno>)</c> if this cleanup is wanted.</p>
<note>
- <p>Prior to OTP release R11B (erts version 5.5) <c>demonitor/1</c>
- behaved completely asynchronous, i.e., the monitor was active
+ <p>Prior to OTP release R11B (ERTS version 5.5) <c>demonitor/1</c>
+ behaved completely asynchronously, i.e., the monitor was active
until the "demonitor signal" reached the monitored entity. This
- had one undesirable effect, though. You could never know when
+ had one undesirable effect. You could never know when
you were guaranteed <em>not</em> to receive a <c>DOWN</c> message
due to the monitor.</p>
<p>Current behavior can be viewed as two combined operations:
@@ -804,31 +1013,31 @@
</note>
<p>Failure: It is an error if <c><anno>MonitorRef</anno></c> refers to a
monitoring started by another process. Not all such cases are
- cheap to check; if checking is cheap, the call fails with
- <c>badarg</c> (for example if <c><anno>MonitorRef</anno></c> is a remote
- reference).</p>
+ cheap to check. If checking is cheap, the call fails with
+ <c>badarg</c> for example, if <c><anno>MonitorRef</anno></c> is a
+ remote reference.</p>
</desc>
</func>
+
<func>
<name name="demonitor" arity="2"/>
- <fsummary>Stop monitoring</fsummary>
+ <fsummary>Stops monitoring.</fsummary>
<desc>
<p>The returned value is <c>true</c> unless <c>info</c> is part
- of <c><anno>OptionList</anno></c>.
- </p>
+ of <c><anno>OptionList</anno></c>.</p>
<p><c>demonitor(<anno>MonitorRef</anno>, [])</c> is equivalent to
- <seealso marker="#demonitor/1">demonitor(<anno>MonitorRef</anno>)</seealso>.</p>
- <p>Currently the following <c><anno>Option</anno></c>s are valid:</p>
+ <seealso marker="#demonitor/1"><c>demonitor(<anno>MonitorRef</anno>)</c></seealso>.</p>
+ <p>The available <c><anno>Option</anno></c>s are as follows:</p>
<taglist>
<tag><c>flush</c></tag>
<item>
- <p>Remove (one) <c>{_, <anno>MonitorRef</anno>, _, _, _}</c> message,
- if there is one, from the caller's message queue after
+ <p>Removes (one) <c>{_,
+ <anno>MonitorRef</anno>, _, _, _}</c> message,
+ if there is one, from the caller message queue after
monitoring has been stopped.</p>
<p>Calling <c>demonitor(<anno>MonitorRef</anno>, [flush])</c>
is equivalent to the following, but more efficient:</p>
<code type="none">
-
demonitor(MonitorRef),
receive
{_, MonitorRef, _, _, _} ->
@@ -839,78 +1048,90 @@
</item>
<tag><c>info</c></tag>
<item>
- <p>The returned value is one of the following:</p>
- <taglist>
- <tag><c>true</c></tag>
- <item><p>The monitor was found and removed. In this case
- no <c>'DOWN'</c> message due to this monitor have
- been nor will be placed in the message queue
- of the caller.
- </p>
- </item>
- <tag><c>false</c></tag>
- <item><p>The monitor was not found and could not be removed.
- This probably because someone already has placed a
- <c>'DOWN'</c> message corresponding to this monitor
- in the caller's message queue.
- </p>
- </item>
- </taglist>
- <p>If the <c>info</c> option is combined with the <c>flush</c>
- option, <c>false</c> will be returned if a flush was needed;
- otherwise, <c>true</c>.
- </p>
+ <p>The returned value is one of the following:</p>
+ <taglist>
+ <tag><c>true</c></tag>
+ <item>The monitor was found and removed. In this case,
+ no <c>'DOWN'</c> message corresponding to this
+ monitor has been delivered and will not be delivered.
+ </item>
+ <tag><c>false</c></tag>
+ <item>The monitor was not found and could not be removed.
+ This probably because someone already has placed a
+ <c>'DOWN'</c> message corresponding to this monitor
+ in the caller message queue.
+ </item>
+ </taglist>
+ <p>If option <c>info</c> is combined with option <c>flush</c>,
+ <c>false</c> is returned if a flush was needed,
+ otherwise <c>true</c>.</p>
</item>
</taglist>
<note>
- <p>More options may be added in the future.</p>
+ <p>More options can be added in a future release.</p>
</note>
- <p>Failure: <c>badarg</c> if <c><anno>OptionList</anno></c> is not a list, or
- if <c><anno>Option</anno></c> is not a valid option, or the same failure as for
- <seealso marker="#demonitor/1">demonitor/1</seealso></p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>OptionList</anno></c> is not a list.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>Option</anno></c> is an invalid option.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>The same failure as for
+ <seealso marker="#demonitor/1">demonitor/1</seealso>.
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="disconnect_node" arity="1"/>
- <fsummary>Force the disconnection of a node</fsummary>
+ <fsummary>Forces the disconnection of a node.</fsummary>
<desc>
- <p>Forces the disconnection of a node. This will appear to
- the node <c><anno>Node</anno></c> as if the local node has crashed. This
- BIF is mainly used in the Erlang network authentication
- protocols. Returns <c>true</c> if disconnection succeeds,
+ <p>Forces the disconnection of a node. This appears to
+ the node <c><anno>Node</anno></c> as if the local node has crashed.
+ This BIF is mainly used in the Erlang network authentication
+ protocols.</p>
+ <p>Returns <c>true</c> if disconnection succeeds,
otherwise <c>false</c>. If the local node is not alive,
- the function returns <c>ignored</c>.</p>
+ <c>ignored</c> is returned.</p>
</desc>
</func>
+
<func>
<name name="display" arity="1"/>
- <fsummary>Print a term on standard output</fsummary>
+ <fsummary>Prints a term on standard output.</fsummary>
<desc>
- <p>Prints a text representation of <c><anno>Term</anno></c> on the standard
- output. On OSE the term is printed to the ramlog.</p>
+ <p>Prints a text representation of <c><anno>Term</anno></c> on the
+ standard output. On OSE, the term is printed to the ramlog.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
</desc>
</func>
+
<func>
<name name="element" arity="2"/>
+ <fsummary>Returns the Nth element of a tuple.</fsummary>
<type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
- <fsummary>Get Nth element of a tuple</fsummary>
<desc>
<p>Returns the <c><anno>N</anno></c>th element (numbering from 1) of
- <c><anno>Tuple</anno></c>.</p>
+ <c><anno>Tuple</anno></c>, for example:</p>
<pre>
> <input>element(2, {a, b, c}).</input>
b</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="erase" arity="0"/>
- <fsummary>Return and delete the process dictionary</fsummary>
+ <fsummary>Returns and deletes the process dictionary.</fsummary>
<desc>
- <p>Returns the process dictionary and deletes it.</p>
+ <p>Returns the process dictionary and deletes it, for
+ example:</p>
<pre>
> <input>put(key1, {1, 2, 3}),</input>
<input>put(key2, [a, b, c]),</input>
@@ -918,13 +1139,16 @@ b</pre>
[{key1,{1,2,3}},{key2,[a,b,c]}]</pre>
</desc>
</func>
+
<func>
<name name="erase" arity="1"/>
- <fsummary>Return and delete a value from the process dictionary</fsummary>
+ <fsummary>Returns and deletes a value from the process dictionary.</fsummary>
<desc>
- <p>Returns the value <c><anno>Val</anno></c> associated with <c><anno>Key</anno></c> and
- deletes it from the process dictionary. Returns
- <c>undefined</c> if no value is associated with <c><anno>Key</anno></c>.</p>
+ <p>Returns the value <c><anno>Val</anno></c> associated with
+ <c><anno>Key</anno></c> and deletes it from the process dictionary.
+ Returns <c>undefined</c> if no value is associated with
+ <c><anno>Key</anno></c>.</p>
+ <p>Example:</p>
<pre>
> <input>put(key1, {merry, lambs, are, playing}),</input>
<input>X = erase(key1),</input>
@@ -932,16 +1156,19 @@ b</pre>
{{merry,lambs,are,playing},undefined}</pre>
</desc>
</func>
+
<func>
<name name="error" arity="1"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Stops the execution of the calling process with the reason
- <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c> is any term. The actual
- exit reason will be <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
+ <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c>
+ is any term. The exit reason is
+ <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
is a list of the functions most recently called (the current
function first). Since evaluating this function causes
the process to terminate, it has no return value.</p>
+ <p>Example:</p>
<pre>
> <input>catch error(foobar).</input>
{'EXIT',{foobar,[{erl_eval,do_apply,5},
@@ -951,29 +1178,34 @@ b</pre>
{shell,eval_loop,3}]}}</pre>
</desc>
</func>
+
<func>
<name name="error" arity="2"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Stops the execution of the calling process with the reason
- <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c> is any term. The actual
- exit reason will be <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
+ <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c>
+ is any term. The exit reason is
+ <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
is a list of the functions most recently called (the current
- function first). <c><anno>Args</anno></c> is expected to be the list of
- arguments for the current function; in Beam it will be used
- to provide the actual arguments for the current function in
- the <c>Where</c> term. Since evaluating this function causes
+ function first). <c><anno>Args</anno></c> is expected to be the
+ list of arguments for the current function; in Beam it is used
+ to provide the arguments for the current function in
+ the term <c>Where</c>. Since evaluating this function causes
the process to terminate, it has no return value.</p>
</desc>
</func>
+
<func>
<name name="exit" arity="1"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
- <p>Stops the execution of the calling process with the exit
- reason <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c> is any term. Since
+ <p>Stops the execution of the calling process with exit reason
+ <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c>
+ is any term. Since
evaluating this function causes the process to terminate, it
has no return value.</p>
+ <p>Example:</p>
<pre>
> <input>exit(foobar).</input>
** exception exit: foobar
@@ -981,110 +1213,117 @@ b</pre>
{'EXIT',foobar}</pre>
</desc>
</func>
+
<func>
<name name="exit" arity="2"/>
- <fsummary>Send an exit signal to a process or a port</fsummary>
+ <fsummary>Sends an exit signal to a process or a port.</fsummary>
<desc>
<p>Sends an exit signal with exit reason <c><anno>Reason</anno></c> to
the process or port identified by <c><anno>Pid</anno></c>.</p>
- <p>The following behavior apply if <c><anno>Reason</anno></c> is any term
- except <c>normal</c> or <c>kill</c>:</p>
- <p>If <c><anno>Pid</anno></c> is not trapping exits, <c><anno>Pid</anno></c> itself will
- exit with exit reason <c><anno>Reason</anno></c>. If <c><anno>Pid</anno></c> is trapping
- exits, the exit signal is transformed into a message
- <c>{'EXIT', From, <anno>Reason</anno>}</c> and delivered to the message
- queue of <c><anno>Pid</anno></c>. <c>From</c> is the pid of the process
- which sent the exit signal. See also
- <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
- <p>If <c><anno>Reason</anno></c> is the atom <c>normal</c>, <c><anno>Pid</anno></c> will
- not exit. If it is trapping exits, the exit signal is
- transformed into a message <c>{'EXIT', From, normal}</c>
- and delivered to its message queue.</p>
- <p>If <c><anno>Reason</anno></c> is the atom <c>kill</c>, that is if
- <c>exit(<anno>Pid</anno>, kill)</c> is called, an untrappable exit signal
- is sent to <c><anno>Pid</anno></c> which will unconditionally exit with
- exit reason <c>killed</c>.</p>
+ <p>The following behavior applies if <c><anno>Reason</anno></c>
+ is any term, except <c>normal</c> or <c>kill</c>:</p>
+ <list type="bulleted">
+ <item>If <c><anno>Pid</anno></c> is not trapping exits,
+ <c><anno>Pid</anno></c>
+ itself exits with exit reason <c><anno>Reason</anno></c>.
+ </item>
+ <item>If <c><anno>Pid</anno></c> is trapping exits, the exit
+ signal is transformed into a message
+ <c>{'EXIT', From, <anno>Reason</anno>}</c>
+ and delivered to the message queue of <c><anno>Pid</anno></c>.
+ </item>
+ <item><c>From</c> is the process identifier of the process
+ that sent the exit signal. See also
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.
+ </item>
+ </list>
+ <p>If <c><anno>Reason</anno></c> is the atom <c>normal</c>,
+ <c><anno>Pid</anno></c>
+ does not exit. If it is trapping exits, the exit signal is
+ transformed into a message <c>{'EXIT', From, normal}</c>
+ and delivered to its message queue.</p>
+ <p>If <c><anno>Reason</anno></c> is the atom <c>kill</c>,
+ that is, if <c>exit(<anno>Pid</anno>, kill)</c> is called,
+ an untrappable exit signal is sent to <c><anno>Pid</anno></c>,
+ which unconditionally exits with exit reason <c>killed</c>.
+ </p>
</desc>
</func>
+
<func>
<name name="external_size" arity="1"/>
- <fsummary>Calculate the maximum size for a term encoded in the Erlang
- external term format</fsummary>
+ <fsummary>Calculates the maximum size for a term encoded in the Erlang external term format.</fsummary>
<desc>
<p>Calculates, without doing the encoding, the maximum byte size for
a term encoded in the Erlang external term format. The following
condition applies always:</p>
- <p>
<pre>
> <input>Size1 = byte_size(term_to_binary(<anno>Term</anno>)),</input>
> <input>Size2 = erlang:external_size(<anno>Term</anno>),</input>
> <input>true = Size1 =&lt; Size2.</input>
-true
- </pre>
- </p>
- <p>This is equivalent to a call to: <code>erlang:external_size(<anno>Term</anno>, [])
- </code></p>
+true</pre>
+ <p>This is equivalent to a call to:</p>
+<code>erlang:external_size(<anno>Term</anno>, [])</code>
</desc>
</func>
+
<func>
<name name="external_size" arity="2"/>
- <fsummary>Calculate the maximum size for a term encoded in the Erlang
- external term format</fsummary>
+ <fsummary>Calculates the maximum size for a term encoded in the Erlang external term format.</fsummary>
<desc>
<p>Calculates, without doing the encoding, the maximum byte size for
a term encoded in the Erlang external term format. The following
condition applies always:</p>
- <p>
<pre>
> <input>Size1 = byte_size(term_to_binary(<anno>Term</anno>, <anno>Options</anno>)),</input>
> <input>Size2 = erlang:external_size(<anno>Term</anno>, <anno>Options</anno>),</input>
> <input>true = Size1 =&lt; Size2.</input>
-true
- </pre>
- </p>
- <p>The option <c>{minor_version, <anno>Version</anno>}</c> specifies how floats
- are encoded. See
- <seealso marker="#term_to_binary/2">term_to_binary/2</seealso> for
- a more detailed description.
- </p>
+true</pre>
+ <p>Option <c>{minor_version, <anno>Version</anno>}</c> specifies how
+ floats are encoded. For a detailed description, see
+ <seealso marker="#term_to_binary/2">term_to_binary/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="float" arity="1"/>
- <fsummary>Convert a number to a float</fsummary>
+ <fsummary>Converts a number to a float.</fsummary>
<desc>
- <p>Returns a float by converting <c><anno>Number</anno></c> to a float.</p>
+ <p>Returns a float by converting <c><anno>Number</anno></c> to a float,
+ for example:</p>
<pre>
> <input>float(55).</input>
55.0</pre>
<p>Allowed in guard tests.</p>
<note>
- <p>Note that if used on the top-level in a guard, it will
- test whether the argument is a floating point number; for
- clarity, use
+ <p>If used on the top level in a guard, it tests whether the
+ argument is a floating point number; for clarity, use
<seealso marker="#is_float/1">is_float/1</seealso> instead.</p>
<p>When <c>float/1</c> is used in an expression in a guard,
such as '<c>float(A) == 4.0</c>', it converts a number as
- described above.</p>
+ described earlier.</p>
</note>
</desc>
</func>
+
<func>
<name name="float_to_binary" arity="1"/>
- <fsummary>Text representation of a float</fsummary>
+ <fsummary>Text representation of a float.</fsummary>
<desc>
- <p>The same as <c>float_to_binary(<anno>Float</anno>,[{scientific,20}])</c>.</p>
+ <p>The same as
+ <c>float_to_binary(<anno>Float</anno>,[{scientific,20}])</c>.</p>
</desc>
</func>
+
<func>
<name name="float_to_binary" arity="2"/>
- <fsummary>Text representation of a float formatted using given options</fsummary>
+ <fsummary>Text representation of a float formatted using given options.</fsummary>
<desc>
- <p>Returns a binary which corresponds to the text
+ <p>Returns a binary corresponding to the text
representation of <c><anno>Float</anno></c> using fixed decimal
- point formatting. The <c><anno>Options</anno></c> behave in the same
- way as <seealso marker="#float_to_list/2">float_to_list/2</seealso>.
- </p>
+ point formatting. <c><anno>Options</anno></c> behaves in the same
+ way as <seealso marker="#float_to_list/2">float_to_list/2</seealso>.</p>
+ <p>Examples:</p>
<pre>
> <input>float_to_binary(7.12, [{decimals, 4}]).</input>
&lt;&lt;"7.1200">>
@@ -1092,31 +1331,42 @@ true
&lt;&lt;"7.12">></pre>
</desc>
</func>
+
<func>
<name name="float_to_list" arity="1"/>
- <fsummary>Text representation of a float</fsummary>
+ <fsummary>Text representation of a float.</fsummary>
<desc>
- <p>The same as <c>float_to_list(<anno>Float</anno>,[{scientific,20}])</c>.</p>
+ <p>The same as
+ <c>float_to_list(<anno>Float</anno>,[{scientific,20}])</c>.</p>
</desc>
</func>
+
<func>
<name name="float_to_list" arity="2"/>
- <fsummary>Text representation of a float formatted using given options</fsummary>
- <desc>
- <p>Returns a string which corresponds to the text
- representation of <c>Float</c> using fixed decimal point formatting.
- When <c>decimals</c> option is specified
- the returned value will contain at most <c>Decimals</c> number of
- digits past the decimal point. If the number doesn't fit in the
- internal static buffer of 256 bytes, the function throws <c>badarg</c>.
- When <c>compact</c> option is provided
- the trailing zeros at the end of the list are truncated (this option is
- only meaningful together with the <c>decimals</c> option). When
- <c>scientific</c> option is provided, the float will be formatted using
- scientific notation with <c>Decimals</c> digits of precision. If
- <c>Options</c> is <c>[]</c> the function behaves like
- <c><seealso marker="#float_to_list/1">float_to_list/1</seealso></c>.
- </p>
+ <fsummary>Text representation of a float formatted using given options.</fsummary>
+ <desc>
+ <p>Returns a string corresponding to the text representation
+ of <c>Float</c> using fixed decimal point formatting. The
+ options are as follows:</p>
+ <list type="bulleted">
+ <item>If option <c>decimals</c> is specified, the returned value
+ contains at most <c>Decimals</c> number of digits past the
+ decimal point. If the number does not fit in the internal
+ static buffer of 256 bytes, the function throws <c>badarg</c>.
+ </item>
+ <item>If option <c>compact</c> is provided, the trailing zeros
+ at the end of the list are truncated. This option is only
+ meaningful together with option <c>decimals</c>.
+ </item>
+ <item>If option <c>scientific</c> is provided, the float is
+ formatted using scientific notation with <c>Decimals</c>
+ digits of precision.
+ </item>
+ <item>If <c>Options</c> is <c>[]</c>, the function behaves as
+ <seealso marker="#float_to_list/1">float_to_list/1</seealso>.
+ </item>
+ </list>
+ <p>Examples:</p>
<pre>
> <input>float_to_list(7.12, [{decimals, 4}]).</input>
"7.1200"
@@ -1124,36 +1374,40 @@ true
"7.12"</pre>
</desc>
</func>
+
<func>
<name name="fun_info" arity="1"/>
- <fsummary>Information about a fun</fsummary>
+ <fsummary>Information about a fun.</fsummary>
<desc>
- <p>Returns a list containing information about the fun
- <c><anno>Fun</anno></c>. Each element of the list is a tuple. The order of
- the tuples is not defined, and more tuples may be added in a
+ <p>Returns a list with information about the fun
+ <c><anno>Fun</anno></c>. Each list element is a tuple. The order
+ of the tuples is undefined, and more tuples can be added in a
future release.</p>
<warning>
<p>This BIF is mainly intended for debugging, but it can
- occasionally be useful in library functions that might need
- to verify, for instance, the arity of a fun.</p>
+ sometimes be useful in library functions that need
+ to verify, for example, the arity of a fun.</p>
</warning>
- <p>There are two types of funs with slightly different
- semantics:</p>
- <p>A fun created by <c>fun M:F/A</c> is called an
- <em>external</em> fun. Calling it will always call the
- function <c>F</c> with arity <c>A</c> in the latest code for
- module <c>M</c>. Note that module <c>M</c> does not even need
- to be loaded when the fun <c>fun M:F/A</c> is created.</p>
- <p>All other funs are called <em>local</em>. When a local fun
- is called, the same version of the code that created the fun
- will be called (even if newer version of the module has been
- loaded).</p>
- <p>The following elements will always be present in the list
+ <p>Two types of funs have slightly different semantics:</p>
+ <list type="bulleted">
+ <item>A fun created by <c>fun M:F/A</c> is called an
+ <em>external</em> fun. Calling it will always call the
+ function <c>F</c> with arity <c>A</c> in the latest code for
+ module <c>M</c>. Notice that module <c>M</c> does not even
+ need to be loaded when the fun <c>fun M:F/A</c> is created.
+ </item>
+ <item>All other funs are called <em>local</em>. When a local fun
+ is called, the same version of the code that created the fun
+ is called (even if a newer version of the module has been
+ loaded).
+ </item>
+ </list>
+ <p>The following elements are always present in the list
for both local and external funs:</p>
<taglist>
<tag><c>{type, Type}</c></tag>
<item>
- <p><c>Type</c> is either <c>local</c> or <c>external</c>.</p>
+ <p><c>Type</c> is <c>local</c> or <c>external</c>.</p>
</item>
<tag><c>{module, Module}</c></tag>
<item>
@@ -1168,147 +1422,154 @@ true
<p><c>Name</c> (an atom) is a function name.</p>
<p>If <c>Fun</c> is a local fun, <c>Name</c> is the name
of the local function that implements the fun.
- (This name was generated by the compiler, and is generally
+ (This name was generated by the compiler, and is
only of informational use. As it is a local function, it
- is not possible to call it directly.)
+ cannot be called directly.)
If no code is currently loaded for the fun, <c>[]</c>
- will be returned instead of an atom.</p>
+ is returned instead of an atom.</p>
<p>If <c>Fun</c> is an external fun, <c>Name</c> is the name
of the exported function that the fun refers to.</p>
</item>
<tag><c>{arity, Arity}</c></tag>
<item>
<p><c>Arity</c> is the number of arguments that the fun
- should be called with.</p>
+ is to be called with.</p>
</item>
<tag><c>{env, Env}</c></tag>
<item>
<p><c>Env</c> (a list) is the environment or free variables
- for the fun. (For external funs, the returned list is
- always empty.)</p>
+ for the fun. For external funs, the returned list is
+ always empty.</p>
</item>
</taglist>
- <p>The following elements will only be present in the list if
+ <p>The following elements are only present in the list if
<c>Fun</c> is local:</p>
<taglist>
<tag><c>{pid, Pid}</c></tag>
<item>
- <p><c>Pid</c> is the pid of the process that originally
- created the fun.</p>
+ <p><c>Pid</c> is the process identifier of the process
+ that originally created the fun.</p>
</item>
<tag><c>{index, Index}</c></tag>
<item>
- <p><c>Index</c> (an integer) is an index into the module's
+ <p><c>Index</c> (an integer) is an index into the module
fun table.</p>
</item>
<tag><c>{new_index, Index}</c></tag>
<item>
- <p><c>Index</c> (an integer) is an index into the module's
+ <p><c>Index</c> (an integer) is an index into the module
fun table.</p>
</item>
<tag><c>{new_uniq, Uniq}</c></tag>
<item>
- <p><c>Uniq</c> (a binary) is a unique value for this fun.
- It is calculated from the compiled code for the entire module.</p>
+ <p><c>Uniq</c> (a binary) is a unique value for this fun. It
+ is calculated from the compiled code for the entire module.</p>
</item>
<tag><c>{uniq, Uniq}</c></tag>
<item>
<p><c>Uniq</c> (an integer) is a unique value for this fun.
- Starting in the R15 release, this integer is calculated from
- the compiled code for the entire module. Before R15, this
- integer was based on only the body of the fun.
- </p>
+ As from OTP R15, this integer is calculated from the
+ compiled code for the entire module. Before OTP R15, this
+ integer was based on only the body of the fun.</p>
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="fun_info" arity="2"/>
+ <fsummary>Information about a fun.</fsummary>
<type name="fun_info_item"/>
- <fsummary>Information about a fun</fsummary>
<desc>
<p>Returns information about <c><anno>Fun</anno></c> as specified by
- <c><anno>Item</anno></c>, in the form <c>{<anno>Item</anno>,<anno>Info</anno>}</c>.</p>
+ <c><anno>Item</anno></c>, in the form
+ <c>{<anno>Item</anno>,<anno>Info</anno>}</c>.</p>
<p>For any fun, <c><anno>Item</anno></c> can be any of the atoms
- <c>module</c>, <c>name</c>, <c>arity</c>, <c>env</c>, or <c>type</c>.</p>
- <p>For a local fun, <c><anno>Item</anno></c> can also be any of the atoms
- <c>index</c>, <c>new_index</c>, <c>new_uniq</c>,
+ <c>module</c>, <c>name</c>, <c>arity</c>, <c>env</c>, or
+ <c>type</c>.</p>
+ <p>For a local fun, <c><anno>Item</anno></c> can also be any of the
+ atoms <c>index</c>, <c>new_index</c>, <c>new_uniq</c>,
<c>uniq</c>, and <c>pid</c>. For an external fun, the value
of any of these items is always the atom <c>undefined</c>.</p>
<p>See
<seealso marker="#fun_info/1">erlang:fun_info/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="fun_to_list" arity="1"/>
- <fsummary>Text representation of a fun</fsummary>
+ <fsummary>Text representation of a fun.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of <c><anno>Fun</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="function_exported" arity="3"/>
- <fsummary>Check if a function is exported and loaded</fsummary>
+ <fsummary>Checks if a function is exported and loaded.</fsummary>
<desc>
<p>Returns <c>true</c> if the module <c><anno>Module</anno></c> is loaded
- and contains an exported function <c><anno>Function</anno>/<anno>Arity</anno></c>;
- otherwise <c>false</c>.</p>
- <p>Returns <c>false</c> for any BIF (functions implemented in C
- rather than in Erlang).</p>
+ and contains an exported function <c><anno>Function</anno>/<anno>Arity</anno></c>,
+ or if there is a BIF (a built-in function implemented in C)
+ with the given name, otherwise returns <c>false</c>.</p>
+ <note><p>This function used to return false for built-in
+ functions before the 18.0 release.</p></note>
</desc>
</func>
+
<func>
<name name="garbage_collect" arity="0"/>
- <fsummary>Force an immediate garbage collection of the calling process</fsummary>
+ <fsummary>Forces an immediate garbage collection of the calling process.</fsummary>
<desc>
- <p>Forces an immediate garbage collection of the currently
- executing process. The function should not be used, unless
- it has been noticed -- or there are good reasons to suspect --
+ <p>Forces an immediate garbage collection of the
+ executing process. The function is not to be used unless
+ it has been noticed (or there are good reasons to suspect)
that the spontaneous garbage collection will occur too late
- or not at all. Improper use may seriously degrade system
- performance.</p>
+ or not at all.</p>
+ <warning>
+ <p>Improper use can seriously degrade system performance.</p>
+ </warning>
</desc>
</func>
+
<func>
<name name="garbage_collect" arity="1"/>
- <fsummary>Garbage collect a process</fsummary>
+ <fsummary>Garbage collects a process.</fsummary>
<desc>
<p>The same as
<seealso marker="#garbage_collect/2"><c>garbage_collect(<anno>Pid</anno>, [])</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="garbage_collect" arity="2"/>
- <fsummary>Garbage collect a process</fsummary>
+ <fsummary>Garbage collects a process.</fsummary>
<desc>
- <p>Garbage collect the node local process identified by
- <c><anno>Pid</anno></c>.</p>
- <p>Currently available <c><anno>Option</anno></c>s:</p>
+ <p>Garbage collects the node local process identified by
+ <c><anno>Pid</anno></c>.</p>
+ <p>The available <c><anno>Option</anno></c>s are as follows:</p>
<taglist>
<tag><c>{async, RequestId}</c></tag>
- <item>
- The <c>garbage_collect/2</c> function will return
+ <item>The function <c>garbage_collect/2</c> returns
the value <c>async</c> immediately after the request
has been sent. When the request has been processed, the
- process that called this function will be passed a
- message on the form:<br/>
- <c>{garbage_collect, <anno>RequestId</anno>, <anno>GCResult</anno>}</c>.
- </item>
+ process that called this function is passed a message on
+ the form <c>{garbage_collect,
+ <anno>RequestId</anno>, <anno>GCResult</anno>}</c>.
+ </item>
</taglist>
<p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
no <c>async</c> option has been passed, the garbage
- collection will be performed at once, i.e. the same as
- calling
+ collection is performed at once, that is, the same as calling
<seealso marker="#garbage_collect/0">garbage_collect/0</seealso>.
- In all other cases a request for garbage collection will
- be sent to the process identified by <c><anno>Pid</anno></c>,
+ Otherwise a request for garbage collection
+ is sent to the process identified by <c><anno>Pid</anno></c>,
and will be handled when appropriate. If no <c>async</c>
- option has been passed, the caller will block until
- <c><anno>GCResult</anno></c> is available and can be
- returned.</p>
+ option has been passed, the caller blocks until
+ <c><anno>GCResult</anno></c> is available and can be returned.</p>
<p><c><anno>GCResult</anno></c> informs about the result of
- the garbage collection request:</p>
+ the garbage collection request as follows:</p>
<taglist>
<tag><c>true</c></tag>
<item>
@@ -1317,14 +1578,13 @@ true
</item>
<tag><c>false</c></tag>
<item>
- No garbage collection was performed. This since the
+ No garbage collection was performed, as
the process identified by <c><anno>Pid</anno></c>
terminated before the request could be satisfied.
</item>
</taglist>
- <p>Note that the same caveats as for
- <seealso marker="#garbage_collect/0">garbage_collect/0</seealso>
- apply.</p>
+ <p>Notice that the same caveats apply as for
+ <seealso marker="#garbage_collect/0">garbage_collect/0</seealso>.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
@@ -1333,17 +1593,18 @@ true
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>OptionList</anno></c> is not a valid list of options.
+ If <c><anno>OptionList</anno></c> is an invalid list of options.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="get" arity="0"/>
- <fsummary>Return the process dictionary</fsummary>
+ <fsummary>Returns the process dictionary.</fsummary>
<desc>
<p>Returns the process dictionary as a list of
- <c>{<anno>Key</anno>, <anno>Val</anno>}</c> tuples.</p>
+ <c>{<anno>Key</anno>, <anno>Val</anno>}</c> tuples, for example:</p>
<pre>
> <input>put(key1, merry),</input>
<input>put(key2, lambs),</input>
@@ -1352,13 +1613,15 @@ true
[{key1,merry},{key2,lambs},{key3,{are,playing}}]</pre>
</desc>
</func>
+
<func>
<name name="get" arity="1"/>
- <fsummary>Return a value from the process dictionary</fsummary>
+ <fsummary>Returns a value from the process dictionary.</fsummary>
<desc>
<p>Returns the value <c><anno>Val</anno></c> associated with <c><anno>Key</anno></c> in
the process dictionary, or <c>undefined</c> if <c><anno>Key</anno></c>
does not exist.</p>
+ <p>Example:</p>
<pre>
> <input>put(key1, merry),</input>
<input>put(key2, lambs),</input>
@@ -1367,20 +1630,35 @@ true
{are,playing}</pre>
</desc>
</func>
+
<func>
<name name="get_cookie" arity="0"/>
- <fsummary>Get the magic cookie of the local node</fsummary>
+ <fsummary>Gets the magic cookie of the local node.</fsummary>
+ <desc>
+ <p>Returns the magic cookie of the local node if the node is
+ alive, otherwise the atom <c>nocookie</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="get_keys" arity="0"/>
+ <fsummary>Return a list of all keys from the process dictionary</fsummary>
<desc>
- <p>Returns the magic cookie of the local node, if the node is
- alive; otherwise the atom <c>nocookie</c>.</p>
+ <p>Returns a list of keys all keys present in the process dictionary.</p>
+ <pre>
+> <input>put(dog, {animal,1}),</input>
+<input>put(cow, {animal,2}),</input>
+<input>put(lamb, {animal,3}),</input>
+<input>get_keys().</input>
+[dog,cow,lamb]</pre>
</desc>
</func>
<func>
<name name="get_keys" arity="1"/>
- <fsummary>Return a list of keys from the process dictionary</fsummary>
+ <fsummary>Returns a list of keys from the process dictionary.</fsummary>
<desc>
- <p>Returns a list of keys which are associated with the value
- <c><anno>Val</anno></c> in the process dictionary.</p>
+ <p>Returns a list of keys that are associated with the value
+ <c><anno>Val</anno></c> in the process dictionary, for example:</p>
<pre>
> <input>put(mary, {1, 2}),</input>
<input>put(had, {1, 2}),</input>
@@ -1392,40 +1670,40 @@ true
[mary,had,a,little,lamb]</pre>
</desc>
</func>
+
<func>
<name name="get_stacktrace" arity="0"/>
- <fsummary>Get the call stack back-trace of the last exception</fsummary>
+ <fsummary>Gets the call stack back-trace of the last exception.</fsummary>
<type name="stack_item"/>
<desc>
- <p>Get the call stack back-trace (<em>stacktrace</em>) of the last
- exception in the calling process as a list of
+ <p>Gets the call stack back-trace (<em>stacktrace</em>) of the
+ last exception in the calling process as a list of
<c>{<anno>Module</anno>,<anno>Function</anno>,<anno>Arity</anno>,<anno>Location</anno>}</c> tuples.
- The <c><anno>Arity</anno></c> field in the first tuple may be the argument
- list of that function call instead of an arity integer,
+ Field <c><anno>Arity</anno></c> in the first tuple can be the
+ argument list of that function call instead of an arity integer,
depending on the exception.</p>
<p>If there has not been any exceptions in a process, the
stacktrace is <c>[]</c>. After a code change for the process,
- the stacktrace may also be reset to [].</p>
+ the stacktrace can also be reset to <c>[]</c>.</p>
<p>The stacktrace is the same data as the <c>catch</c> operator
returns, for example:</p>
<p><c>{'EXIT',{badarg,Stacktrace}} = catch abs(x)</c></p>
- <p><c><anno>Location</anno></c> is a (possibly empty) list of two-tuples that
- may indicate the location in the source code of the function.
- The first element is an atom that describes the type of
- information in the second element. Currently the following
- items may occur:</p>
+ <p><c><anno>Location</anno></c> is a (possibly empty) list
+ of two-tuples that
+ can indicate the location in the source code of the function.
+ The first element is an atom describing the type of
+ information in the second element. The following
+ items can occur:</p>
<taglist>
<tag><c>file</c></tag>
- <item>
- <p>The second element of the tuple is a string (list of
- characters) representing the filename of the source file
- of the function.</p>
+ <item>The second element of the tuple is a string (list of
+ characters) representing the file name of the source file
+ of the function.
</item>
<tag><c>line</c></tag>
- <item>
- <p>The second element of the tuple is the line number
+ <item>The second element of the tuple is the line number
(an integer greater than zero) in the source file
- where the exception occurred or the function was called.</p>
+ where the exception occurred or the function was called.
</item>
</taglist>
<p>See also
@@ -1433,49 +1711,56 @@ true
<seealso marker="#error/2">erlang:error/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="group_leader" arity="0"/>
- <fsummary>Get the group leader for the calling process</fsummary>
+ <fsummary>Gets the group leader for the calling process.</fsummary>
<desc>
- <p>Returns the pid of the group leader for the process which
- evaluates the function.</p>
+ <p>Returns the process identifier of the group leader for the
+ process evaluating the function.</p>
<p>Every process is a member of some process group and all
- groups have a <em>group leader</em>. All IO from the group
+ groups have a <em>group leader</em>. All I/O from the group
is channeled to the group leader. When a new process is
spawned, it gets the same group leader as the spawning
process. Initially, at system start-up, <c>init</c> is both
its own group leader and the group leader of all processes.</p>
</desc>
</func>
+
<func>
<name name="group_leader" arity="2"/>
- <fsummary>Set the group leader for a process</fsummary>
+ <fsummary>Sets the group leader for a process.</fsummary>
<desc>
- <p>Sets the group leader of <c><anno>Pid</anno></c> to <c><anno>GroupLeader</anno></c>.
- Typically, this is used when a processes started from a
- certain shell should have another group leader than
+ <p>Sets the group leader of <c><anno>Pid</anno></c>
+ to <c><anno>GroupLeader</anno></c>.
+ Typically, this is used when a process started from a
+ certain shell is to have another group leader than
<c>init</c>.</p>
<p>See also
<seealso marker="#group_leader/0">group_leader/0</seealso>.</p>
</desc>
</func>
+
<func>
<name name="halt" arity="0"/>
- <fsummary>Halt the Erlang runtime system and indicate normal exit to the calling environment</fsummary>
+ <fsummary>Halts the Erlang runtime system and indicates normal exit to the calling environment.</fsummary>
<desc>
<p>The same as
<seealso marker="#halt/2"><c>halt(0, [])</c></seealso>.</p>
+ <p>Example:</p>
<pre>
> <input>halt().</input>
os_prompt% </pre>
</desc>
</func>
+
<func>
<name name="halt" arity="1"/>
- <fsummary>Halt the Erlang runtime system</fsummary>
+ <fsummary>Halts the Erlang runtime system.</fsummary>
<desc>
<p>The same as
<seealso marker="#halt/2"><c>halt(<anno>Status</anno>, [])</c></seealso>.</p>
+ <p>Example:</p>
<pre>
> <input>halt(17).</input>
os_prompt% <input>echo $?</input>
@@ -1483,178 +1768,189 @@ os_prompt% <input>echo $?</input>
os_prompt% </pre>
</desc>
</func>
+
<func>
<name name="halt" arity="2"/>
- <fsummary>Halt the Erlang runtime system</fsummary>
+ <fsummary>Halts the Erlang runtime system.</fsummary>
<desc>
<p><c><anno>Status</anno></c> must be a non-negative integer, a string,
or the atom <c>abort</c>.
Halts the Erlang runtime system. Has no return value.
- Depending on <c><anno>Status</anno></c>:
- </p>
+ Depending on <c><anno>Status</anno></c>, the following occurs:</p>
<taglist>
<tag>integer()</tag>
- <item>The runtime system exits with the integer value <c><anno>Status</anno></c>
- as status code to the calling environment (operating system).
+ <item>The runtime system exits with integer value
+ <c><anno>Status</anno></c>
+ as status code to the calling environment (OS).
</item>
<tag>string()</tag>
- <item>An erlang crash dump is produced with <c><anno>Status</anno></c> as slogan,
- and then the runtime system exits with status code <c>1</c>.
+ <item>An Erlang crash dump is produced with <c><anno>Status</anno></c>
+ as slogan. Then the runtime system exits with status code <c>1</c>.
</item>
<tag><c>abort</c></tag>
<item>
The runtime system aborts producing a core dump, if that is
- enabled in the operating system.
+ enabled in the OS.
</item>
</taglist>
- <p>Note that on many platforms, only the status codes 0-255 are
- supported by the operating system.
- </p>
- <p>For integer <c><anno>Status</anno></c> the Erlang runtime system closes all ports
- and allows async threads to finish their operations before exiting.
- To exit without such flushing use
- <c><anno>Option</anno></c> as <c>{flush,false}</c>.
- </p>
- <p>For statuses <c>string()</c> and <c>abort</c> the <c>flush</c>
- option is ignored and flushing is <em>not</em> done.
- </p>
+ <note><p>On many platforms, the OS supports only status
+ codes 0-255. A too large status code will be truncated by clearing
+ the high bits.</p></note>
+ <p>For integer <c><anno>Status</anno></c>, the Erlang runtime system
+ closes all ports and allows async threads to finish their
+ operations before exiting. To exit without such flushing, use
+ <c><anno>Option</anno></c> as <c>{flush,false}</c>.</p>
+ <p>For statuses <c>string()</c> and <c>abort</c>, option
+ <c>flush</c> is ignored and flushing is <em>not</em> done.</p>
</desc>
</func>
+
<func>
<name name="hash" arity="2"/>
- <fsummary>Hash function (deprecated)</fsummary>
+ <fsummary>Hash function (deprecated).</fsummary>
<desc>
<p>Returns a hash value for <c><anno>Term</anno></c> within the range
- <c>1..<anno>Range</anno></c>. The allowed range is 1..2^27-1.</p>
+ <c>1..<anno>Range</anno></c>. The maximum range is 1..2^27-1.</p>
<warning>
- <p>This BIF is deprecated as the hash value may differ on
- different architectures. Also the hash values for integer
- terms larger than 2^27 as well as large binaries are very
+ <p>This BIF is deprecated, as the hash value can differ on
+ different architectures. The hash values for integer
+ terms higher than 2^27 and large binaries are
poor. The BIF is retained for backward compatibility
- reasons (it may have been used to hash records into a file),
- but all new code should use one of the BIFs
+ reasons (it can have been used to hash records into a file),
+ but all new code is to use one of the BIFs
<c>erlang:phash/2</c> or <c>erlang:phash2/1,2</c> instead.</p>
</warning>
</desc>
</func>
+
<func>
<name name="hd" arity="1"/>
- <fsummary>Head of a list</fsummary>
+ <fsummary>Head of a list.</fsummary>
<desc>
- <p>Returns the head of <c><anno>List</anno></c>, that is, the first element.</p>
+ <p>Returns the head of <c><anno>List</anno></c>, that is,
+ the first element, for example:</p>
<pre>
> <input>hd([1,2,3,4,5]).</input>
1</pre>
<p>Allowed in guard tests.</p>
- <p>Failure: <c>badarg</c> if <c><anno>List</anno></c> is the empty list [].</p>
+ <p>Failure: <c>badarg</c> if <c><anno>List</anno></c> is the empty
+ list <c>[]</c>.</p>
</desc>
</func>
+
<func>
<name name="hibernate" arity="3"/>
- <fsummary>Hibernate a process until a message is sent to it</fsummary>
+ <fsummary>Hibernates a process until a message is sent to it.</fsummary>
<desc>
<p>Puts the calling process into a wait state where its memory
- allocation has been reduced as much as possible, which is
+ allocation has been reduced as much as possible. This is
useful if the process does not expect to receive any messages
- in the near future.</p>
- <p>The process will be awaken when a message is sent to it, and
- control will resume in <c><anno>Module</anno>:<anno>Function</anno></c> with
- the arguments given by <c><anno>Args</anno></c> with the call stack
- emptied, meaning that the process will terminate when that
- function returns. Thus <c>erlang:hibernate/3</c> will never
- return to its caller.</p>
+ soon.</p>
+ <p>The process is awaken when a message is sent to it, and control
+ resumes in <c><anno>Module</anno>:<anno>Function</anno></c> with
+ the arguments given by <c><anno>Args</anno></c> with the call
+ stack emptied, meaning that the process terminates when that
+ function returns. Thus <c>erlang:hibernate/3</c> never
+ returns to its caller.</p>
<p>If the process has any message in its message queue,
- the process will be awaken immediately in the same way as
- described above.</p>
+ the process is awakened immediately in the same way as
+ described earlier.</p>
<p>In more technical terms, what <c>erlang:hibernate/3</c> does
- is the following. It discards the call stack for the process.
- Then it garbage collects the process. After the garbage
- collection, all live data is in one continuous heap. The heap
+ is the following. It discards the call stack for the process,
+ and then garbage collects the process. After this,
+ all live data is in one continuous heap. The heap
is then shrunken to the exact same size as the live data
- which it holds (even if that size is less than the minimum
+ that it holds (even if that size is less than the minimum
heap size for the process).</p>
<p>If the size of the live data in the process is less than
the minimum heap size, the first garbage collection occurring
- after the process has been awaken will ensure that the heap
+ after the process is awakened ensures that the heap
size is changed to a size not smaller than the minimum heap
size.</p>
- <p>Note that emptying the call stack means that any surrounding
- <c>catch</c> is removed and has to be re-inserted after
+ <p>Notice that emptying the call stack means that any surrounding
+ <c>catch</c> is removed and must be reinserted after
hibernation. One effect of this is that processes started
using <c>proc_lib</c> (also indirectly, such as
- <c>gen_server</c> processes), should use
+ <c>gen_server</c> processes), are to use
<seealso marker="stdlib:proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>
- instead to ensure that the exception handler continues to work
+ instead, to ensure that the exception handler continues to work
when the process wakes up.</p>
</desc>
</func>
<func>
<name name="insert_element" arity="3"/>
- <fsummary>Insert an element at index in a tuple</fsummary>
+ <fsummary>Inserts an element at index in a tuple.</fsummary>
<type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>) + 1</type_desc>
<desc>
- <p>
- Returns a new tuple with element <c><anno>Term</anno></c> insert at position
- <c><anno>Index</anno></c> in tuple <c><anno>Tuple1</anno></c>.
- All elements from position <c><anno>Index</anno></c> and upwards are subsequently
- pushed one step higher in the new tuple <c><anno>Tuple2</anno></c>.
- </p>
+ <p>Returns a new tuple with element <c><anno>Term</anno></c>
+ inserted at position
+ <c><anno>Index</anno></c> in tuple <c><anno>Tuple1</anno></c>.
+ All elements from position <c><anno>Index</anno></c> and upwards are
+ pushed one step higher in the new tuple <c><anno>Tuple2</anno></c>.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:insert_element(2, {one, two, three}, new).</input>
{one,new,two,three}</pre>
</desc>
</func>
+
<func>
<name name="integer_to_binary" arity="1"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a binary which corresponds to the text
- representation of <c><anno>Integer</anno></c>.</p>
+ <p>Returns a binary corresponding to the text
+ representation of <c><anno>Integer</anno></c>, for example:</p>
<pre>
> <input>integer_to_binary(77).</input>
&lt;&lt;"77">></pre>
</desc>
</func>
+
<func>
<name name="integer_to_binary" arity="2"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a binary which corresponds to the text
- representation of <c><anno>Integer</anno></c> in base <c><anno>Base</anno></c>.</p>
+ <p>Returns a binary corresponding to the text
+ representation of <c><anno>Integer</anno></c> in base
+ <c><anno>Base</anno></c>, for example:</p>
<pre>
> <input>integer_to_binary(1023, 16).</input>
&lt;&lt;"3FF">></pre>
</desc>
</func>
+
<func>
<name name="integer_to_list" arity="1"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
- representation of <c><anno>Integer</anno></c>.</p>
+ <p>Returns a string corresponding to the text
+ representation of <c><anno>Integer</anno></c>, for example:</p>
<pre>
> <input>integer_to_list(77).</input>
"77"</pre>
</desc>
</func>
+
<func>
<name name="integer_to_list" arity="2"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
- representation of <c><anno>Integer</anno></c> in base <c><anno>Base</anno></c>.</p>
+ <p>Returns a string corresponding to the text
+ representation of <c><anno>Integer</anno></c> in base
+ <c><anno>Base</anno></c>, for example:</p>
<pre>
> <input>integer_to_list(1023, 16).</input>
"3FF"</pre>
</desc>
</func>
+
<func>
<name name="iolist_to_binary" arity="1"/>
- <fsummary>Convert an iolist to a binary</fsummary>
+ <fsummary>Converts an iolist to a binary.</fsummary>
<desc>
- <p>Returns a binary which is made from the integers and
- binaries in <c><anno>IoListOrBinary</anno></c>.</p>
+ <p>Returns a binary that is made from the integers and
+ binaries in <c><anno>IoListOrBinary</anno></c>, for example:</p>
<pre>
> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
&lt;&lt;1,2,3&gt;&gt;
@@ -1666,278 +1962,311 @@ os_prompt% </pre>
&lt;&lt;1,2,3,1,2,3,4,5,4,6&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="iolist_size" arity="1"/>
- <fsummary>Size of an iolist</fsummary>
+ <fsummary>Size of an iolist.</fsummary>
<desc>
- <p>Returns an integer which is the size in bytes
- of the binary that would be the result of
- <c>iolist_to_binary(<anno>Item</anno>)</c>.</p>
+ <p>Returns an integer that is the size in bytes
+ of the binary that would be the result of
+ <c>iolist_to_binary(<anno>Item</anno>)</c>, for example:</p>
<pre>
> <input>iolist_size([1,2|&lt;&lt;3,4>>]).</input>
4</pre>
</desc>
</func>
+
<func>
<name name="is_alive" arity="0"/>
- <fsummary>Check whether the local node is alive</fsummary>
+ <fsummary>Checks whether the local node is alive.</fsummary>
<desc>
- <p>Returns <c>true</c> if the local node is alive; that is, if
- the node can be part of a distributed system. Otherwise, it
- returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if the local node is alive (that is, if
+ the node can be part of a distributed system), otherwise
+ <c>false</c>.</p>
</desc>
</func>
+
<func>
<name name="is_atom" arity="1"/>
- <fsummary>Check whether a term is an atom</fsummary>
+ <fsummary>Checks whether a term is an atom.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an atom;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an atom,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_binary" arity="1"/>
- <fsummary>Check whether a term is a binary</fsummary>
+ <fsummary>Checks whether a term is a binary.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a binary;
- otherwise returns <c>false</c>.</p>
-
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a binary,
+ otherwise <c>false</c>.</p>
<p>A binary always contains a complete number of bytes.</p>
-
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_bitstring" arity="1"/>
- <fsummary>Check whether a term is a bitstring</fsummary>
+ <fsummary>Checks whether a term is a bitstring.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a bitstring (including a binary);
- otherwise returns <c>false</c>.</p>
-
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a
+ bitstring (including a binary), otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_boolean" arity="1"/>
- <fsummary>Check whether a term is a boolean</fsummary>
+ <fsummary>Checks whether a term is a boolean.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is
- either the atom <c>true</c> or the atom <c>false</c>
- (i.e. a boolean); otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is the
+ atom <c>true</c> or the atom <c>false</c> (that is, a boolean).
+ Otherwise returns <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_builtin" arity="3"/>
- <fsummary>Check if a function is a BIF implemented in C</fsummary>
+ <fsummary>Checks if a function is a BIF implemented in C.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Module</anno>:<anno>Function</anno>/<anno>Arity</anno></c> is
- a BIF implemented in C; otherwise returns <c>false</c>.
- This BIF is useful for builders of cross reference tools.</p>
+ <p>This BIF is useful for builders of cross-reference tools.</p>
+ <p>Returns <c>true</c> if
+ <c><anno>Module</anno>:<anno>Function</anno>/<anno>Arity</anno></c>
+ is a BIF implemented in C, otherwise <c>false</c>.</p>
</desc>
</func>
+
<func>
<name name="is_float" arity="1"/>
- <fsummary>Check whether a term is a float</fsummary>
+ <fsummary>Checks whether a term is a float.</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a floating point
- number; otherwise returns <c>false</c>.</p>
+ number, otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_function" arity="1"/>
- <fsummary>Check whether a term is a fun</fsummary>
+ <fsummary>Checks whether a term is a fun.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun; otherwise
- returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun, otherwise
+ <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_function" arity="2"/>
- <fsummary>Check whether a term is a fun with a given arity</fsummary>
+ <fsummary>Checks whether a term is a fun with a given arity.</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun that can be
- applied with <c><anno>Arity</anno></c> number of arguments; otherwise
- returns <c>false</c>.</p>
+ applied with <c><anno>Arity</anno></c> number of arguments, otherwise
+ <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_integer" arity="1"/>
- <fsummary>Check whether a term is an integer</fsummary>
+ <fsummary>Checks whether a term is an integer.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_list" arity="1"/>
- <fsummary>Check whether a term is a list</fsummary>
+ <fsummary>Checks whether a term is a list.</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a list with
- zero or more elements; otherwise returns <c>false</c>.</p>
+ zero or more elements, otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_map" arity="1"/>
- <fsummary>Check whether a term is a map</fsummary>
+ <fsummary>Checks whether a term is a map.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a map;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a map,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_number" arity="1"/>
- <fsummary>Check whether a term is a number</fsummary>
+ <fsummary>Checks whether a term is a number.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is either an integer or a
- floating point number; otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer or a
+ floating point number. Otherwise returns <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_pid" arity="1"/>
- <fsummary>Check whether a term is a pid</fsummary>
+ <fsummary>Checks whether a term is a process identifier.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a pid (process
- identifier); otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a process
+ identifier, otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_port" arity="1"/>
- <fsummary>Check whether a term is a port</fsummary>
+ <fsummary>Checks whether a term is a port.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a port identifier;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a port identifier,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_process_alive" arity="1"/>
- <fsummary>Check whether a process is alive</fsummary>
+ <fsummary>Checks whether a process is alive.</fsummary>
<desc>
- <p>
- <c><anno>Pid</anno></c> must refer to a process at the local node.
- Returns <c>true</c> if the process exists and is alive, that
- is, is not exiting and has not exited. Otherwise, returns
+ <p><c><anno>Pid</anno></c> must refer to a process at the local node.</p>
+ <p>Returns <c>true</c> if the process exists and is alive, that
+ is, is not exiting and has not exited. Otherwise returns
<c>false</c>.
</p>
</desc>
</func>
+
<func>
<name name="is_record" arity="2"/>
- <fsummary>Check whether a term appears to be a record</fsummary>
+ <fsummary>Checks whether a term appears to be a record.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple and its first
- element is <c><anno>RecordTag</anno></c>. Otherwise, returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple and its
+ first element is <c><anno>RecordTag</anno></c>.
+ Otherwise returns <c>false</c>.</p>
<note>
<p>Normally the compiler treats calls to <c>is_record/2</c>
- specially. It emits code to verify that <c><anno>Term</anno></c> is a
- tuple, that its first element is <c><anno>RecordTag</anno></c>, and that
- the size is correct. However, if the <c><anno>RecordTag</anno></c> is
- not a literal atom, the <c>is_record/2</c> BIF will be
- called instead and the size of the tuple will not be
- verified.</p>
+ specially. It emits code to verify that <c><anno>Term</anno></c>
+ is a tuple, that its first element is
+ <c><anno>RecordTag</anno></c>, and that the
+ size is correct. However, if <c><anno>RecordTag</anno></c> is
+ not a literal atom, the BIF <c>is_record/2</c> is called
+ instead and the size of the tuple is not verified.</p>
</note>
- <p>Allowed in guard tests, if <c><anno>RecordTag</anno></c> is a literal
- atom.</p>
+ <p>Allowed in guard tests, if <c><anno>RecordTag</anno></c> is
+ a literal atom.</p>
</desc>
</func>
+
<func>
<name name="is_record" arity="3"/>
- <fsummary>Check whether a term appears to be a record</fsummary>
- <desc>
- <p><c><anno>RecordTag</anno></c> must be an atom. Returns <c>true</c> if
- <c><anno>Term</anno></c> is a tuple, its first element is <c><anno>RecordTag</anno></c>,
- and its size is <c><anno>Size</anno></c>. Otherwise, returns <c>false</c>.</p>
- <p>Allowed in guard tests, provided that <c><anno>RecordTag</anno></c> is
+ <fsummary>Checks whether a term appears to be a record.</fsummary>
+ <desc>
+ <p><c><anno>RecordTag</anno></c> must be an atom.</p>
+ <p>Returns <c>true</c> if
+ <c><anno>Term</anno></c> is a tuple,
+ its first element is <c><anno>RecordTag</anno></c>,
+ and its size is <c><anno>Size</anno></c>.
+ Otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests if <c><anno>RecordTag</anno></c> is
a literal atom and <c>Size</c> is a literal integer.</p>
<note>
- <p>This BIF is documented for completeness. In most cases
- <c>is_record/2</c> should be used.</p>
+ <p>This BIF is documented for completeness. Usually
+ <c>is_record/2</c> is to be used.</p>
</note>
</desc>
</func>
+
<func>
<name name="is_reference" arity="1"/>
- <fsummary>Check whether a term is a reference</fsummary>
+ <fsummary>Checks whether a term is a reference.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a reference;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a reference,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_tuple" arity="1"/>
- <fsummary>Check whether a term is a tuple</fsummary>
+ <fsummary>Checks whether a term is a tuple.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="length" arity="1"/>
- <fsummary>Length of a list</fsummary>
+ <fsummary>Length of a list.</fsummary>
<desc>
- <p>Returns the length of <c><anno>List</anno></c>.</p>
+ <p>Returns the length of <c><anno>List</anno></c>, for example:</p>
<pre>
> <input>length([1,2,3,4,5,6,7,8,9]).</input>
9</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="link" arity="1"/>
- <fsummary>Create a link to another process (or port)</fsummary>
+ <fsummary>Creates a link to another process (or port).</fsummary>
<desc>
<p>Creates a link between the calling process and another
- process (or port) <c><anno>PidOrPort</anno></c>, if there is not such a link
+ process (or port) <c><anno>PidOrPort</anno></c>, if there is
+ not such a link
already. If a process attempts to create a link to itself,
nothing is done. Returns <c>true</c>.</p>
- <p>If <c><anno>PidOrPort</anno></c> does not exist, the behavior of the BIF depends
- on if the calling process is trapping exits or not (see
+ <p>If <c><anno>PidOrPort</anno></c> does not exist, the behavior
+ of the BIF
+ depends on if the calling process is trapping exits or not (see
<seealso marker="#process_flag/2">process_flag/2</seealso>):</p>
<list type="bulleted">
<item>If the calling process is not trapping exits, and
- checking <c><anno>PidOrPort</anno></c> is cheap -- that is, if <c><anno>PidOrPort</anno></c> is
- local -- <c>link/1</c> fails with reason <c>noproc</c>.</item>
+ checking <c><anno>PidOrPort</anno></c> is cheap
+ (that is, if <c><anno>PidOrPort</anno></c>
+ is local), <c>link/1</c> fails with reason <c>noproc</c>.</item>
<item>Otherwise, if the calling process is trapping exits,
- and/or <c><anno>PidOrPort</anno></c> is remote, <c>link/1</c> returns
- <c>true</c>, but an exit signal with reason <c>noproc</c>
+ and/or <c><anno>PidOrPort</anno></c> is remote, <c>link/1</c>
+ returns <c>true</c>, but an exit signal with reason <c>noproc</c>
is sent to the calling process.</item>
</list>
</desc>
</func>
+
<func>
<name name="list_to_atom" arity="1"/>
- <fsummary>Convert from text representation to an atom</fsummary>
- <desc>
- <p>Returns the atom whose text representation is <c><anno>String</anno></c>.</p>
- <p><c><anno>String</anno></c> may only contain ISO-latin-1
- characters (i.e. numbers below 256) as the current
- implementation does not allow unicode characters >= 256 in
- atoms. For more information on Unicode support in atoms
- see <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8 encoded atoms</seealso>
- in the chapter about the external term format in the ERTS User's Guide.</p>
+ <fsummary>Converts from text representation to an atom.</fsummary>
+ <desc>
+ <p>Returns the atom whose text representation is
+ <c><anno>String</anno></c>.</p>
+ <p><c><anno>String</anno></c> can only contain ISO-latin-1
+ characters (that is,
+ numbers less than 256) as the implementation does not
+ allow unicode characters equal to or above 256 in atoms.
+ For more information on Unicode support in atoms, see
+ <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8
+ encoded atoms</seealso>
+ in Section "External Term Format" in the User's Guide.</p>
+ <p>Example:</p>
<pre>
> <input>list_to_atom("Erlang").</input>
'Erlang'</pre>
</desc>
</func>
+
<func>
<name name="list_to_binary" arity="1"/>
- <fsummary>Convert a list to a binary</fsummary>
+ <fsummary>Converts a list to a binary.</fsummary>
<desc>
- <p>Returns a binary which is made from the integers and
- binaries in <c><anno>IoList</anno></c>.</p>
+ <p>Returns a binary that is made from the integers and
+ binaries in <c><anno>IoList</anno></c>, for example:</p>
<pre>
> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
&lt;&lt;1,2,3&gt;&gt;
@@ -1949,40 +2278,46 @@ os_prompt% </pre>
&lt;&lt;1,2,3,1,2,3,4,5,4,6&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="list_to_bitstring" arity="1"/>
+ <fsummary>Converts a list to a bitstring.</fsummary>
<type name="bitstring_list"/>
- <fsummary>Convert a list to a bitstring</fsummary>
<desc>
- <p>Returns a bitstring which is made from the integers and
- bitstrings in <c><anno>BitstringList</anno></c>. (The last tail in <c><anno>BitstringList</anno></c>
- is allowed to be a bitstring.)</p>
+ <p>Returns a bitstring that is made from the integers and
+ bitstrings in <c><anno>BitstringList</anno></c>. (The last tail in
+ <c><anno>BitstringList</anno></c> is allowed to be a bitstring.)</p>
+ <p>Example:</p>
<pre>
> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
&lt;&lt;1,2,3&gt;&gt;
> <input>Bin2 = &lt;&lt;4,5&gt;&gt;.</input>
&lt;&lt;4,5&gt;&gt;
-> <input>Bin3 = &lt;&lt;6,7:4,&gt;&gt;.</input>
-&lt;&lt;6&gt;&gt;
+> <input>Bin3 = &lt;&lt;6,7:4&gt;&gt;.</input>
+&lt;&lt;6,7:4&gt;&gt;
> <input>list_to_bitstring([Bin1,1,[2,3,Bin2],4|Bin3]).</input>
-&lt;&lt;1,2,3,1,2,3,4,5,4,6,7:46&gt;&gt;</pre>
+&lt;&lt;1,2,3,1,2,3,4,5,4,6,7:4&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="list_to_existing_atom" arity="1"/>
- <fsummary>Convert from text representation to an atom</fsummary>
+ <fsummary>Converts from text representation to an atom.</fsummary>
<desc>
- <p>Returns the atom whose text representation is <c><anno>String</anno></c>,
+ <p>Returns the atom whose text representation is
+ <c><anno>String</anno></c>,
but only if there already exists such atom.</p>
<p>Failure: <c>badarg</c> if there does not already exist an atom
whose text representation is <c><anno>String</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="list_to_float" arity="1"/>
- <fsummary>Convert from text representation to a float</fsummary>
+ <fsummary>Converts from text representation to a float.</fsummary>
<desc>
- <p>Returns the float whose text representation is <c><anno>String</anno></c>.</p>
+ <p>Returns the float whose text representation is
+ <c><anno>String</anno></c>, for example:</p>
<pre>
> <input>list_to_float("2.2017764e+0").</input>
2.2017764</pre>
@@ -1990,12 +2325,13 @@ os_prompt% </pre>
representation of a float.</p>
</desc>
</func>
+
<func>
<name name="list_to_integer" arity="1"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation is
- <c><anno>String</anno></c>.</p>
+ <c><anno>String</anno></c>, for example:</p>
<pre>
> <input>list_to_integer("123").</input>
123</pre>
@@ -2003,12 +2339,14 @@ os_prompt% </pre>
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="list_to_integer" arity="2"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation in base
- <c><anno>Base</anno></c> is <c><anno>String</anno></c>.</p>
+ <c><anno>Base</anno></c> is <c><anno>String</anno></c>,
+ for example:</p>
<pre>
> <input>list_to_integer("3FF", 16).</input>
1023</pre>
@@ -2016,47 +2354,52 @@ os_prompt% </pre>
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="list_to_pid" arity="1"/>
- <fsummary>Convert from text representation to a pid</fsummary>
+ <fsummary>Converts from text representation to a pid.</fsummary>
<desc>
- <p>Returns a pid whose text representation is <c><anno>String</anno></c>.</p>
- <warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
- </warning>
+ <p>Returns a process identifier whose text representation is a
+ <c><anno>String</anno></c>, for example:</p>
<pre>
> <input>list_to_pid("&lt;0.4.1>").</input>
&lt;0.4.1></pre>
<p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
- representation of a pid.</p>
+ representation of a process identifier.</p>
+ <warning>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
+ </warning>
</desc>
</func>
+
<func>
<name name="list_to_tuple" arity="1"/>
- <fsummary>Convert a list to a tuple</fsummary>
+ <fsummary>Converts a list to a tuple.</fsummary>
<desc>
- <p>Returns a tuple which corresponds to <c><anno>List</anno></c>. <c><anno>List</anno></c>
- can contain any Erlang terms.</p>
+ <p>Returns a tuple corresponding to <c><anno>List</anno></c>,
+ for example</p>
<pre>
> <input>list_to_tuple([share, ['Ericsson_B', 163]]).</input>
{share, ['Ericsson_B', 163]}</pre>
+ <p><c><anno>List</anno></c> can contain any Erlang terms.</p>
</desc>
</func>
+
<func>
<name name="load_module" arity="2"/>
- <fsummary>Load object code for a module</fsummary>
+ <fsummary>Loads object code for a module.</fsummary>
<desc>
- <p>If <c><anno>Binary</anno></c> contains the object code for the module
- <c><anno>Module</anno></c>, this BIF loads that object code. Also, if
- the code for the module <c><anno>Module</anno></c> already exists, all
+ <p>If <c><anno>Binary</anno></c> contains the object code for module
+ <c><anno>Module</anno></c>, this BIF loads that object code. If
+ the code for module <c><anno>Module</anno></c> already exists, all
export references are replaced so they point to the newly
loaded code. The previously loaded code is kept in the system
- as old code, as there may still be processes which are
- executing that code. It returns either
- <c>{module, <anno>Module</anno>}</c>, or <c>{error, <anno>Reason</anno>}</c> if loading
- fails. <c><anno>Reason</anno></c> is one of the following:</p>
+ as old code, as there can still be processes executing
+ that code.</p>
+ <p>Returns either <c>{module, <anno>Module</anno>}</c>, or
+ <c>{error, <anno>Reason</anno>}</c> if loading fails.
+ <c><anno>Reason</anno></c> is any of the following:</p>
<taglist>
<tag><c>badfile</c></tag>
<item>
@@ -2066,118 +2409,122 @@ os_prompt% </pre>
</item>
<tag><c>not_purged</c></tag>
<item>
- <p><c><anno>Binary</anno></c> contains a module which cannot be loaded
- because old code for this module already exists.</p>
+ <p><c><anno>Binary</anno></c> contains a module that cannot be
+ loaded because old code for this module already exists.</p>
</item>
</taglist>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
- used elsewhere.</p>
+ <seealso marker="kernel:code">code(3)</seealso>)
+ and is not to be used elsewhere.</p>
</warning>
</desc>
</func>
+
<func>
<name name="load_nif" arity="2"/>
- <fsummary>Load NIF library</fsummary>
+ <fsummary>Loads NIF library.</fsummary>
<desc>
<note>
- <p>In releases older than OTP R14B, NIFs were an
- experimental feature. Versions of OTP older than R14B might
+ <p>Before OTP R14B, NIFs were an
+ experimental feature. Versions before OTP R14B can
have different and possibly incompatible NIF semantics and
- interfaces. For example, in R13B03 the return value on
- failure was
- <c>{error,Reason,Text}</c>.</p>
+ interfaces. For example, in OTP R13B03 the return value on
+ failure was <c>{error,Reason,Text}</c>.</p>
</note>
<p>Loads and links a dynamic library containing native
- implemented functions (NIFs) for a module. <c><anno>Path</anno></c> is a
- file path to the sharable object/dynamic library file minus
- the OS-dependent file extension (.so for Unix and .dll for
- Windows). See <seealso marker="erl_nif">erl_nif</seealso>
- on how to implement a NIF library.</p>
- <p><c><anno>LoadInfo</anno></c> can be any term. It will be passed on to
+ implemented functions (NIFs) for a module. <c><anno>Path</anno></c>
+ is a file path to the shareable object/dynamic library file minus
+ the OS-dependent file extension (<c>.so</c> for Unix and
+ <c>.dll</c> for Windows. For information on how to
+ implement a NIF library, see
+ <seealso marker="erl_nif">erl_nif</seealso>.</p>
+ <p><c><anno>LoadInfo</anno></c> can be any term. It is passed on to
the library as part of the initialization. A good practice is
to include a module version number to support future code
upgrade scenarios.</p>
<p>The call to <c>load_nif/2</c> must be made
<em>directly</em> from the Erlang code of the module that the
- NIF library belongs to.</p>
- <p>It returns either <c>ok</c>, or <c>{error,{<anno>Reason</anno>,Text}}</c>
- if loading fails. <c><anno>Reason</anno></c> is one of the atoms below,
- while <c><anno>Text</anno></c> is a human readable string that may give
- some more information about the failure.</p>
+ NIF library belongs to. It returns either <c>ok</c>, or
+ <c>{error,{<anno>Reason</anno>,Text}}</c> if loading fails.
+ <c><anno>Reason</anno></c> is one of the following atoms
+ while <c><anno>Text</anno></c> is a human readable string that
+ can give more information about the failure:</p>
<taglist>
<tag><c>load_failed</c></tag>
- <item>
- <p>The OS failed to load the NIF library.</p>
+ <item>The OS failed to load the NIF library.
</item>
<tag><c>bad_lib</c></tag>
- <item>
- <p>The library did not fulfil the requirements as a NIF
- library of the calling module.</p>
+ <item>The library did not fulfill the requirements as a NIF
+ library of the calling module.
</item>
<tag><c>load | reload | upgrade</c></tag>
- <item>
- <p>The corresponding library callback was not successful.</p>
+ <item>The corresponding library callback was unsuccessful.
</item>
<tag><c>old_code</c></tag>
- <item>
- <p>The call to <c>load_nif/2</c> was made from the old
- code of a module that has been upgraded. This is not
- allowed.</p>
+ <item>The call to <c>load_nif/2</c> was made from the old
+ code of a module that has been upgraded; this is not
+ allowed.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="loaded" arity="0"/>
- <fsummary>List of all loaded modules</fsummary>
+ <fsummary>Lists all loaded modules.</fsummary>
<desc>
- <p>Returns a list of all loaded Erlang modules (current and/or
+ <p>Returns a list of all loaded Erlang modules (current and
old code), including preloaded modules.</p>
<p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="localtime" arity="0"/>
- <fsummary>Current local date and time</fsummary>
+ <fsummary>Current local date and time.</fsummary>
<desc>
- <p>Returns the current local date and time
- <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c>.</p>
- <p>The time zone and daylight saving time correction depend
- on the underlying OS.</p>
+ <p>Returns the current local date and time,
+ <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c>,
+ for example:</p>
<pre>
> <input>erlang:localtime().</input>
{{1996,11,6},{14,45,17}}</pre>
+ <p>The time zone and Daylight Saving Time correction depend
+ on the underlying OS.</p>
</desc>
</func>
+
<func>
<name name="localtime_to_universaltime" arity="1"/>
- <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
+ <fsummary>Converts from local to Universal Time Coordinated (UTC) date and time.</fsummary>
<desc>
<p>Converts local date and time to Universal Time Coordinated
- (UTC), if this is supported by the underlying OS. Otherwise,
- no conversion is done and <c><anno>Localtime</anno></c> is returned.</p>
+ (UTC), if supported by the underlying OS. Otherwise
+ no conversion is done and <c><anno>Localtime</anno></c>
+ is returned.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).</input>
{{1996,11,6},{13,45,17}}</pre>
- <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> does not denote
- a valid date and time.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> denotes an
+ invalid date and time.</p>
</desc>
</func>
+
<func>
<name name="localtime_to_universaltime" arity="2"/>
- <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
+ <fsummary>Converts from local to Universal Time Coordinated (UTC) date and time.</fsummary>
<desc>
<p>Converts local date and time to Universal Time Coordinated
- (UTC) just like <c>erlang:localtime_to_universaltime/1</c>,
- but the caller decides if daylight saving time is active or
- not.</p>
- <p>If <c><anno>IsDst</anno> == true</c> the <c><anno>Localtime</anno></c> is during
- daylight saving time, if <c><anno>IsDst</anno> == false</c> it is not,
- and if <c><anno>IsDst</anno> == undefined</c> the underlying OS may
+ (UTC) as <c>erlang:localtime_to_universaltime/1</c>,
+ but the caller decides if Daylight Saving Time is active.</p>
+ <p>If <c><anno>IsDst</anno> == true</c>, <c><anno>Localtime</anno></c> is
+ during Daylight Saving Time, if <c><anno>IsDst</anno> == false</c> it is
+ not. If <c><anno>IsDst</anno> == undefined</c>, the underlying OS can
guess, which is the same as calling
<c>erlang:localtime_to_universaltime(<anno>Localtime</anno>)</c>.</p>
+ <p>Examples:</p>
<pre>
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, true).</input>
{{1996,11,6},{12,45,17}}
@@ -2185,216 +2532,227 @@ os_prompt% </pre>
{{1996,11,6},{13,45,17}}
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, undefined).</input>
{{1996,11,6},{13,45,17}}</pre>
- <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> does not denote
- a valid date and time.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> denotes an
+ invalid date and time.</p>
</desc>
</func>
+
<func>
<name name="make_ref" arity="0"/>
- <fsummary>Return an almost unique reference</fsummary>
+ <fsummary>Returns a unique reference.</fsummary>
<desc>
- <p>Returns an almost unique reference.</p>
- <p>The returned reference will re-occur after approximately 2^82
- calls; therefore it is unique enough for practical purposes.</p>
- <pre>
-> <input>make_ref().</input>
-#Ref&lt;0.0.0.135></pre>
+ <p>Returns a <seealso marker="doc/efficiency_guide:advanced#unique_references">unique
+ reference</seealso>. The reference is unique among
+ connected nodes.</p>
+ <warning><p>Known issue: When a node is restarted multiple
+ times with the same node name, references created
+ on a newer node can be mistaken for a reference
+ created on an older node with the same node name.</p></warning>
</desc>
</func>
+
<func>
<name name="make_tuple" arity="2"/>
- <fsummary>Create a new tuple of a given arity</fsummary>
+ <fsummary>Creates a new tuple of a given arity.</fsummary>
<desc>
- <p>Returns a new tuple of the given <c><anno>Arity</anno></c>, where all
- elements are <c><anno>InitialValue</anno></c>.</p>
+ <p>Creates a new tuple of the given <c><anno>Arity</anno></c>, where all
+ elements are <c><anno>InitialValue</anno></c>, for example:</p>
<pre>
> <input>erlang:make_tuple(4, []).</input>
{[],[],[],[]}</pre>
</desc>
</func>
+
<func>
<name name="make_tuple" arity="3"/>
- <fsummary>Create a new tuple with given arity and contents</fsummary>
- <desc>
- <p><c>erlang:make_tuple</c> first creates a tuple of size <c><anno>Arity</anno></c>
- where each element has the value <c><anno>DefaultValue</anno></c>. It then fills
- in values from <c><anno>InitList</anno></c>. Each list element in <c><anno>InitList</anno></c>
- must be a two-tuple where the first element is a position in the
- newly created tuple and the second element is any term. If a position
- occurs more than once in the list, the term corresponding to
- last occurrence will be used.</p>
+ <fsummary>Creates a new tuple with given arity and contents.</fsummary>
+ <desc>
+ <p>Creates a tuple of size <c><anno>Arity</anno></c>, where each element
+ has value <c><anno>DefaultValue</anno></c>, and then fills in
+ values from <c><anno>InitList</anno></c>.
+ Each list element in <c><anno>InitList</anno></c>
+ must be a two-tuple, where the first element is a position in the
+ newly created tuple and the second element is any term. If a
+ position occurs more than once in the list, the term corresponding
+ to the last occurrence is used.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:make_tuple(5, [], [{2,ignored},{5,zz},{2,aa}]).</input>
{{[],aa,[],[],zz}</pre>
</desc>
</func>
+
<func>
<name name="map_size" arity="1"/>
- <fsummary>Return the size of a map</fsummary>
+ <fsummary>Returns the size of a map.</fsummary>
<desc>
- <p>Returns an integer which is the number of key-value pairs in <c><anno>Map</anno></c>.</p>
+ <p>Returns an integer, which is the number of key-value pairs
+ in <c><anno>Map</anno></c>, for example:</p>
<pre>
> <input>map_size(#{a=>1, b=>2, c=>3}).</input>
3</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="max" arity="2"/>
- <fsummary>Return the largest of two term</fsummary>
+ <fsummary>Returns the largest of two terms.</fsummary>
<desc>
- <p>Return the largest of <c><anno>Term1</anno></c> and <c><anno>Term2</anno></c>;
- if the terms compare equal, <c><anno>Term1</anno></c> will be returned.</p>
+ <p>Returns the largest of <c><anno>Term1</anno></c> and
+ <c><anno>Term2</anno></c>.
+ If the terms are equal, <c><anno>Term1</anno></c> is returned.</p>
</desc>
</func>
+
<func>
<name name="md5" arity="1"/>
- <fsummary>Compute an MD5 message digest</fsummary>
+ <fsummary>Computes an MD5 message digest.</fsummary>
<desc>
- <p>Computes an <c>MD5</c> message digest from <c><anno>Data</anno></c>, where
- the length of the digest is 128 bits (16 bytes). <c><anno>Data</anno></c>
+ <p>Computes an MD5 message digest from <c><anno>Data</anno></c>, where
+ the length of the digest is 128 bits (16 bytes).
+ <c><anno>Data</anno></c>
is a binary or a list of small integers and binaries.</p>
- <p>See The MD5 Message Digest Algorithm (RFC 1321) for more
- information about MD5.</p>
- <warning><p>The MD5 Message Digest Algorithm is <em>not</em> considered
- safe for code-signing or software integrity purposes.</p></warning>
+ <p>For more information about MD5, see RFC 1321 - The
+ MD5 Message-Digest Algorithm.</p>
+ <warning><p>The MD5 Message-Digest Algorithm is <em>not</em> considered
+ safe for code-signing or software-integrity purposes.</p></warning>
</desc>
</func>
+
<func>
<name name="md5_final" arity="1"/>
- <fsummary>Finish the update of an MD5 context and return the computed MD5 message digest</fsummary>
+ <fsummary>Finishes the update of an MD5 context and returns the computed MD5 message digest.</fsummary>
<desc>
<p>Finishes the update of an MD5 <c><anno>Context</anno></c> and returns
the computed <c>MD5</c> message digest.</p>
</desc>
</func>
+
<func>
<name name="md5_init" arity="0"/>
- <fsummary>Create an MD5 context</fsummary>
+ <fsummary>Creates an MD5 context.</fsummary>
<desc>
<p>Creates an MD5 context, to be used in subsequent calls to
<c>md5_update/2</c>.</p>
</desc>
</func>
+
<func>
<name name="md5_update" arity="2"/>
- <fsummary>Update an MD5 context with data, and return a new context</fsummary>
+ <fsummary>Updates an MD5 context with data and returns a new context.</fsummary>
<desc>
- <p>Updates an MD5 <c><anno>Context</anno></c> with <c><anno>Data</anno></c>, and returns
- a <c><anno>NewContext</anno></c>.</p>
+ <p>Updates an MD5 <c><anno>Context</anno></c> with
+ <c><anno>Data</anno></c> and returns a
+ <c><anno>NewContext</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="memory" arity="0"/>
+ <fsummary>Information about dynamically allocated memory.</fsummary>
<type name="memory_type"/>
- <fsummary>Information about dynamically allocated memory</fsummary>
- <desc>
- <p>Returns a list containing information about memory
- dynamically allocated by the Erlang emulator. Each element of
- the list is a tuple <c>{Type, Size}</c>. The first element
- <c><anno>Type</anno></c>is an atom describing memory type. The second
- element <c><anno>Size</anno></c>is memory size in bytes. A description of
- each memory type follows:</p>
+ <desc>
+ <p>Returns a list with information about memory
+ dynamically allocated by the Erlang emulator. Each list
+ element is a tuple <c>{Type, Size}</c>. The first element
+ <c><anno>Type</anno></c> is an atom describing memory type. The second
+ element <c><anno>Size</anno></c> is the memory size in bytes.</p>
+ <p>The memory types are as follows:</p>
<taglist>
<tag><c>total</c></tag>
<item>
- <p>The total amount of memory currently allocated, which is
- the same as the sum of memory size for <c>processes</c>
+ <p>The total amount of memory currently allocated. This is
+ the same as the sum of the memory size for <c>processes</c>
and <c>system</c>.</p>
</item>
<tag><c>processes</c></tag>
<item>
- <p>The total amount of memory currently allocated by
+ <p>The total amount of memory currently allocated for
the Erlang processes.</p>
</item>
<tag><c>processes_used</c></tag>
<item>
<p>The total amount of memory currently used by the Erlang
- processes.</p>
- <p>This memory is part of the memory presented as
+ processes. This is part of the memory presented as
<c>processes</c> memory.</p>
</item>
<tag><c>system</c></tag>
<item>
- <p>The total amount of memory currently allocated by
+ <p>The total amount of memory currently allocated for
the emulator that is not directly related to any Erlang
- process.</p>
- <p>Memory presented as <c>processes</c> is not included in
- this memory.</p>
+ process. Memory presented as <c>processes</c> is not
+ included in this memory.</p>
</item>
<tag><c>atom</c></tag>
<item>
- <p>The total amount of memory currently allocated for atoms.</p>
- <p>This memory is part of the memory presented as
+ <p>The total amount of memory currently allocated for atoms.
+ This memory is part of the memory presented as
<c>system</c> memory.</p>
</item>
<tag><c>atom_used</c></tag>
<item>
- <p>The total amount of memory currently used for atoms.</p>
- <p>This memory is part of the memory presented as
+ <p>The total amount of memory currently used for atoms.
+ This memory is part of the memory presented as
<c>atom</c> memory.</p>
</item>
<tag><c>binary</c></tag>
<item>
<p>The total amount of memory currently allocated for
- binaries.</p>
- <p>This memory is part of the memory presented as
- <c>system</c> memory.</p>
+ binaries. This memory is part of the memory presented
+ as <c>system</c> memory.</p>
</item>
<tag><c>code</c></tag>
<item>
<p>The total amount of memory currently allocated for
- Erlang code.</p>
- <p>This memory is part of the memory presented as
- <c>system</c> memory.</p>
+ Erlang code. This memory is part of the memory presented
+ as <c>system</c> memory.</p>
</item>
<tag><c>ets</c></tag>
<item>
<p>The total amount of memory currently allocated for ets
- tables.</p>
- <p>This memory is part of the memory presented as
+ tables. This memory is part of the memory presented as
<c>system</c> memory.</p>
</item>
<tag><c>low</c></tag>
<item>
- <p>Only on 64-bit halfword emulator.</p>
- <p>The total amount of memory allocated in low memory areas
- that are restricted to less than 4 Gb even though
- the system may have more physical memory.</p>
- <p>May be removed in future releases of halfword emulator.</p>
+ <p>Only on 64-bit halfword emulator.
+ The total amount of memory allocated in low memory areas
+ that are restricted to less than 4 GB, although
+ the system can have more memory.</p>
+ <p>Can be removed in a future release of the halfword
+ emulator.</p>
</item>
<tag><c>maximum</c></tag>
<item>
<p>The maximum total amount of memory allocated since
- the emulator was started.</p>
- <p>This tuple is only present when the emulator is run with
- instrumentation.</p>
+ the emulator was started. This tuple is only present
+ when the emulator is run with instrumentation.</p>
<p>For information on how to run the emulator with
- instrumentation see
+ instrumentation, see
<seealso marker="tools:instrument">instrument(3)</seealso>
and/or <seealso marker="erts:erl">erl(1)</seealso>.</p>
</item>
</taglist>
<note>
<p>The <c>system</c> value is not complete. Some allocated
- memory that should be part of the <c>system</c> value are
- not.</p>
+ memory that is to be part of this value is not.</p>
<p>When the emulator is run with instrumentation,
the <c>system</c> value is more accurate, but memory
- directly allocated by <c>malloc</c> (and friends) are still
+ directly allocated for <c>malloc</c> (and friends) is still
not part of the <c>system</c> value. Direct calls to
- <c>malloc</c> are only done from OS specific runtime
- libraries and perhaps from user implemented Erlang drivers
+ <c>malloc</c> are only done from OS-specific runtime
+ libraries and perhaps from user-implemented Erlang drivers
that do not use the memory allocation functions in
the driver interface.</p>
- <p>Since the <c>total</c> value is the sum of <c>processes</c>
- and <c>system</c> the error in <c>system</c> will propagate
+ <p>As the <c>total</c> value is the sum of <c>processes</c>
+ and <c>system</c>, the error in <c>system</c> propagates
to the <c>total</c> value.</p>
<p>The different amounts of memory that are summed are
- <em>not</em> gathered atomically which also introduce
+ <em>not</em> gathered atomically, which introduces
an error in the result.</p>
</note>
- <p>The different values has the following relation to each
+ <p>The different values have the following relation to each
other. Values beginning with an uppercase letter is not part
of the result.</p>
<code type="none">
@@ -2402,69 +2760,62 @@ os_prompt% </pre>
processes = processes_used + ProcessesNotUsed
system = atom + binary + code + ets + OtherSystem
atom = atom_used + AtomNotUsed
-
RealTotal = processes + RealSystem
RealSystem = system + MissedSystem</code>
- <p>More tuples in the returned list may be added in the future.</p>
+ <p>More tuples in the returned list can be added in a
+ future release.</p>
<note>
<p>The <c>total</c> value is supposed to be the total amount
of memory dynamically allocated by the emulator. Shared
libraries, the code of the emulator itself, and
- the emulator stack(s) are not supposed to be included. That
+ the emulator stacks are not supposed to be included. That
is, the <c>total</c> value is <em>not</em> supposed to be
- equal to the total size of all pages mapped to the emulator.
- Furthermore, due to fragmentation and pre-reservation of
- memory areas, the size of the memory segments which contain
- the dynamically allocated memory blocks can be substantially
+ equal to the total size of all pages mapped to the emulator.</p>
+ <p>Furthermore, because of fragmentation and prereservation of
+ memory areas, the size of the memory segments containing
+ the dynamically allocated memory blocks can be much
larger than the total size of the dynamically allocated
memory blocks.</p>
</note>
<note>
- <p>
- Since erts version 5.6.4 <c>erlang:memory/0</c> requires that
+ <p>As from <c>ERTS</c> 5.6.4, <c>erlang:memory/0</c> requires that
all <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
- allocators are enabled (default behaviour).
- </p>
+ allocators are enabled (default behavior).</p>
</note>
- <p>Failure:</p>
- <taglist>
- <tag><c>notsup</c></tag>
- <item>
- If an <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
- allocator has been disabled.
- </item>
- </taglist>
+ <p>Failure: <c>notsup</c> if an
+ <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
+ allocator has been disabled.</p>
</desc>
</func>
+
<func>
<name name="memory" arity="1" clause_i="1"/>
<name name="memory" arity="1" clause_i="2"/>
+ <fsummary>Information about dynamically allocated memory.</fsummary>
<type name="memory_type"/>
- <fsummary>Information about dynamically allocated memory</fsummary>
<desc>
<p>Returns the memory size in bytes allocated for memory of
type <c><anno>Type</anno></c>. The argument can also be given as a list
of <c>memory_type()</c> atoms, in which case a corresponding list of
<c>{memory_type(), Size :: integer >= 0}</c> tuples is returned.</p>
<note>
- <p>
- Since erts version 5.6.4 <c>erlang:memory/1</c> requires that
+ <p>As from <c>ERTS</c> version 5.6.4,
+ <c>erlang:memory/1</c> requires that
all <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
- allocators are enabled (default behaviour).
- </p>
+ allocators are enabled (default behavior).</p>
</note>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Type</anno></c> is not one of the memory types listed in the
- documentation of
+ If <c><anno>Type</anno></c> is not one of the memory types
+ listed in the description of
<seealso marker="#memory/0">erlang:memory/0</seealso>.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c>maximum</c> is passed as <c><anno>Type</anno></c> and the emulator
- is not run in instrumented mode.
+ If <c>maximum</c> is passed as <c><anno>Type</anno></c> and
+ the emulator is not run in instrumented mode.
</item>
<tag><c>notsup</c></tag>
<item>
@@ -2476,226 +2827,367 @@ os_prompt% </pre>
<seealso marker="#memory/0">erlang:memory/0</seealso>.</p>
</desc>
</func>
+
<func>
<name name="min" arity="2"/>
- <fsummary>Return the smallest of two term</fsummary>
+ <fsummary>Returns the smallest of two terms.</fsummary>
<desc>
- <p>Return the smallest of <c><anno>Term1</anno></c> and <c><anno>Term2</anno></c>;
- if the terms compare equal, <c><anno>Term1</anno></c> will be returned.</p>
+ <p>Returns the smallest of <c><anno>Term1</anno></c> and
+ <c><anno>Term2</anno></c>.
+ If the terms are equal, <c><anno>Term1</anno></c> is returned.</p>
</desc>
</func>
+
<func>
<name name="module_loaded" arity="1"/>
- <fsummary>Check if a module is loaded</fsummary>
+ <fsummary>Checks if a module is loaded.</fsummary>
<desc>
- <p>Returns <c>true</c> if the module <c><anno>Module</anno></c> is loaded,
- otherwise returns <c>false</c>. It does not attempt to load
+ <p>Returns <c>true</c> if the module <c><anno>Module</anno></c>
+ is loaded, otherwise <c>false</c>. It does not attempt to load
the module.</p>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
+ <seealso marker="kernel:code">code(3)</seealso>) and is not to be
used elsewhere.</p>
</warning>
</desc>
</func>
+
<func>
- <name name="monitor" arity="2"/>
- <fsummary>Start monitoring</fsummary>
- <desc>
- <p>The calling process starts monitoring <c><anno>Item</anno></c> which is
- an object of type <c><anno>Type</anno></c>.</p>
- <p>Currently only processes can be monitored, i.e. the only
- allowed <c><anno>Type</anno></c> is <c>process</c>, but other types may be
- allowed in the future.</p>
- <p><c><anno>Item</anno></c> can be:</p>
- <taglist>
- <tag><c>pid()</c></tag>
- <item>
- <p>The pid of the process to monitor.</p>
- </item>
- <tag><c>{RegName, Node}</c></tag>
- <item>
- <p>A tuple consisting of a registered name of a process and
- a node name. The process residing on the node <c>Node</c>
- with the registered name <c>RegName</c> will be monitored.</p>
- </item>
- <tag><c>RegName</c></tag>
- <item>
- <p>The process locally registered as <c>RegName</c> will be
- monitored.</p>
- </item>
- </taglist>
- <note>
- <p>When a process is monitored by registered name, the process
- that has the registered name at the time when
- <c>monitor/2</c> is called will be monitored.
- The monitor will not be effected, if the registered name is
- unregistered.</p>
- </note>
- <p>A <c>'DOWN'</c> message will be sent to the monitoring
- process if <c><anno>Item</anno></c> dies, if <c><anno>Item</anno></c> does not exist,
- or if the connection is lost to the node which <c><anno>Item</anno></c>
- resides on. A <c>'DOWN'</c> message has the following pattern:</p>
- <code type="none">
-{'DOWN', MonitorRef, Type, Object, Info}</code>
- <p>where <c>MonitorRef</c> and <c>Type</c> are the same as
- described above, and:</p>
- <taglist>
- <tag><c>Object</c></tag>
- <item>
- <p>A reference to the monitored object:</p>
- <list type="bulleted">
- <item>the pid of the monitored process, if <c><anno>Item</anno></c> was
- specified as a pid.</item>
- <item><c>{RegName, Node}</c>, if <c><anno>Item</anno></c> was specified as
- <c>{RegName, Node}</c>.</item>
- <item><c>{RegName, Node}</c>, if <c><anno>Item</anno></c> was specified as
- <c>RegName</c>. <c>Node</c> will in this case be the
- name of the local node (<c>node()</c>).</item>
- </list>
- </item>
- <tag><c>Info</c></tag>
- <item>
- <p>Either the exit reason of the process, <c>noproc</c>
- (non-existing process), or <c>noconnection</c> (no
- connection to <c><anno>Node</anno></c>).</p>
- </item>
- </taglist>
- <note>
- <p>If/when <c>monitor/2</c> is extended (e.g. to
- handle other item types than <c>process</c>), other
- possible values for <c>Object</c>, and <c>Info</c> in the
- <c>'DOWN'</c> message will be introduced.</p>
- </note>
- <p>The monitoring is turned off either when the <c>'DOWN'</c>
- message is sent, or when
- <seealso marker="#demonitor/1">demonitor/1</seealso>
- is called.</p>
- <p>If an attempt is made to monitor a process on an older node
- (where remote process monitoring is not implemented or one
- where remote process monitoring by registered name is not
- implemented), the call fails with <c>badarg</c>.</p>
- <p>Making several calls to <c>monitor/2</c> for the same
- <c><anno>Item</anno></c> is not an error; it results in as many, completely
- independent, monitorings.</p>
+ <name name="monitor" arity="2" clause_i="1"/>
+ <name name="monitor" arity="2" clause_i="2"/>
+ <fsummary>Starts monitoring.</fsummary>
+ <type name="registered_name"/>
+ <type name="registered_process_identifier"/>
+ <type name="monitor_process_identifier"/>
+ <desc>
+ <p>Send a monitor request of type <c><anno>Type</anno></c> to the
+ entity identified by <c><anno>Item</anno></c>. The caller of
+ <c>monitor/2</c> will later be notified by a monitor message on the
+ following format if the monitored state is changed:</p>
+ <code type="none">{Tag, <anno>MonitorRef</anno>, <anno>Type</anno>, Object, Info}</code>
+ <note><p>The monitor request is an asynchronous signal. That is, it
+ takes time before the signal reaches its destination.</p></note>
+ <p>Valid <c><anno>Type</anno></c>s:</p>
+ <taglist>
+ <tag><marker id="monitor_process"/><c>process</c></tag>
+ <item>
+ <p>Monitor the existence of the process identified by
+ <c><anno>Item</anno></c>. Valid
+ <c><anno>Item</anno></c>s in combination with the
+ <c>process <anno>Type</anno></c> can be any of the following:</p>
+ <taglist>
+ <tag><c>pid()</c></tag>
+ <item>
+ <p>The process identifier of the process to monitor.</p>
+ </item>
+ <tag><c>{RegisteredName, Node}</c></tag>
+ <item>
+ <p>A tuple consisting of a registered name of a process and
+ a node name. The process residing on the node <c>Node</c>
+ with the registered name <c>{RegisteredName, Node}</c> will
+ be monitored.</p>
+ </item>
+ <tag><c>RegisteredName</c></tag>
+ <item>
+ <p>The process locally registered as <c>RegisteredName</c>
+ will become monitored.</p>
+ </item>
+ </taglist>
+ <note><p>When a registered name is used, the
+ process that has the registered name when the
+ monitor request reach its destination will be monitored.
+ The monitor is not effected if the registered name is
+ unregistered, or unregistered and later registered on another
+ process.</p></note>
+ <p>The monitor is triggered either when the monitored process
+ terminates, is non existing, or if the connection to it is
+ lost. In the case the connection to it is lost, we do not know
+ if it still exist or not. After this type of monitor has been
+ triggered, the monitor is automatically removed.</p>
+ <p>When the monitor is triggered a <c>'DOWN'</c> message is
+ sent to the monitoring process. A <c>'DOWN'</c> message has
+ the following pattern:</p>
+ <code type="none">{'DOWN', MonitorRef, Type, Object, Info}</code>
+ <p>Here <c>MonitorRef</c> and <c>Type</c> are the same as
+ described earlier, and:</p>
+ <taglist>
+ <tag><c>Object</c></tag>
+ <item>
+ <p>equals:</p>
+ <taglist>
+ <tag><c><anno>Item</anno></c></tag>
+ <item>If <c><anno>Item</anno></c> is specified by a
+ process identifier.</item>
+ <tag><c>{RegisteredName, Node}</c></tag>
+ <item>If <c><anno>Item</anno></c> is specified as
+ <c>RegisteredName</c>, or <c>{RegisteredName, Node}</c>
+ where <c>Node</c> corresponds to the node that the
+ monitored process resides on.</item>
+ </taglist>
+ </item>
+ <tag><c>Info</c></tag>
+ <item>
+ <p>Either the exit reason of the process, <c>noproc</c>
+ (non-existing process), or <c>noconnection</c> (no
+ connection to the node where the monitored process
+ resides).</p></item>
+ </taglist>
+ <p>The monitoring is turned off when the <c>'DOWN'</c>
+ message is sent or when
+ <seealso marker="#demonitor/1">demonitor/1</seealso>
+ is called.</p>
+ <p>If an attempt is made to monitor a process on an older node
+ (where remote process monitoring is not implemented or
+ where remote process monitoring by registered name is not
+ implemented), the call fails with <c>badarg</c>.</p>
+ <note>
+ <p>The format of the <c>'DOWN'</c> message changed in ERTS
+ version 5.2 (OTP R9B) for monitoring
+ <em>by registered name</em>. Element <c>Object</c> of
+ the <c>'DOWN'</c> message could in earlier versions
+ sometimes be the process identifier of the monitored process and sometimes
+ be the registered name. Now element <c>Object</c> is
+ always a tuple consisting of the registered name and
+ the node name. Processes on new nodes (ERTS version 5.2
+ or higher) always get <c>'DOWN'</c> messages on
+ the new format even if they are monitoring processes on old
+ nodes. Processes on old nodes always get <c>'DOWN'</c>
+ messages on the old format.</p>
+ </note>
+ </item>
+ <tag><marker id="monitor_time_offset"/><c>time_offset</c></tag>
+ <item>
+ <p>Monitor changes in
+ <seealso marker="#time_offset/0">time offset</seealso>
+ between
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> and
+ <seealso marker="time_correction#Erlang_System_Time">Erlang
+ system time</seealso>. There is only one valid
+ <c><anno>Item</anno></c> in combination with the
+ <c>time_offset <anno>Type</anno></c>, namely the atom
+ <c>clock_service</c>. Note that the atom <c>clock_service</c> is
+ <em>not</em> the registered name of a process. In this specific
+ case it serves as an identifier of the runtime system internal
+ clock service at current runtime system instance.</p>
+
+ <p>The monitor is triggered when the time offset is changed.
+ This either if the time offset value is changed, or if the
+ offset is changed from preliminary to final during
+ <seealso marker="#system_flag_time_offset">finalization
+ of the time offset</seealso> when the
+ <seealso marker="time_correction#Single_Time_Warp_Mode">single
+ time warp mode</seealso> is used. When a change from preliminary
+ to final time offset is made, the monitor will be triggered once
+ regardless of whether the time offset value was actually changed
+ or not.</p>
+
+ <p>If the runtime system is in
+ <seealso marker="time_correction#Multi_Time_Warp_Mode">multi
+ time warp mode</seealso>, the time offset will be changed when
+ the runtime system detects that the
+ <seealso marker="time_correction#OS_System_Time">OS system
+ time</seealso> has changed. The runtime system will, however,
+ not detect this immediately when it happens. A task checking
+ the time offset is scheduled to execute at least once a minute,
+ so under normal operation this should be detected within a
+ minute, but during heavy load it might take longer time.</p>
+
+ <p>The monitor will <em>not</em> be automatically removed
+ after it has been triggered. That is, repeated changes of
+ the time offset will trigger the monitor repeatedly.</p>
+
+ <p>When the monitor is triggered a <c>'CHANGE'</c> message will
+ be sent to the monitoring process. A <c>'CHANGE'</c> message has
+ the following pattern:</p>
+ <code type="none">{'CHANGE', MonitorRef, Type, Item, NewTimeOffset}</code>
+ <p>where <c>MonitorRef</c>, <c><anno>Type</anno></c>, and
+ <c><anno>Item</anno></c> are the same as described above, and
+ <c>NewTimeOffset</c> is the new time offset.</p>
+
+ <p>When the <c>'CHANGE'</c> message has been received you are
+ guaranteed not to retrieve the old time offset when calling
+ <seealso marker="#time_offset/0"><c>erlang:time_offset()</c></seealso>.
+ Note that you can observe the change of the time offset
+ when calling <c>erlang:time_offset()</c> before you
+ get the <c>'CHANGE'</c> message.</p>
+
+ </item>
+ </taglist>
+ <p>Making several calls to <c>monitor/2</c> for the same
+ <c><anno>Item</anno></c> and/or <c><anno>Type</anno></c> is not
+ an error; it results in as many independent monitoring instances.</p>
+ <p>The monitor functionality is expected to be extended. That is,
+ other <c><anno>Type</anno></c>s and <c><anno>Item</anno></c>s
+ are expected to be supported in a future release.</p>
<note>
- <p>The format of the <c>'DOWN'</c> message changed in the 5.2
- version of the emulator (OTP release R9B) for monitor <em>by registered name</em>. The <c>Object</c> element of
- the <c>'DOWN'</c> message could in earlier versions
- sometimes be the pid of the monitored process and sometimes
- be the registered name. Now the <c>Object</c> element is
- always a tuple consisting of the registered name and
- the node name. Processes on new nodes (emulator version 5.2
- or greater) will always get <c>'DOWN'</c> messages on
- the new format even if they are monitoring processes on old
- nodes. Processes on old nodes will always get <c>'DOWN'</c>
- messages on the old format.</p>
+ <p>If or when <c>monitor/2</c> is extended, other
+ possible values for <c>Tag</c>, <c>Object</c> and
+ <c>Info</c> in the monitor message will be introduced.</p>
</note>
</desc>
</func>
+
<func>
<name name="monitor_node" arity="2"/>
- <fsummary>Monitor the status of a node</fsummary>
+ <fsummary>Monitors the status of a node.</fsummary>
<desc>
- <p>Monitors the status of the node <c><anno>Node</anno></c>. If <c><anno>Flag</anno></c>
- is <c>true</c>, monitoring is turned on; if <c><anno>Flag</anno></c> is
- <c>false</c>, monitoring is turned off.</p>
+ <p>Monitors the status of the node <c><anno>Node</anno></c>.
+ If <c><anno>Flag</anno></c>
+ is <c>true</c>, monitoring is turned on. If <c><anno>Flag</anno></c>
+ is <c>false</c>, monitoring is turned off.</p>
<p>Making several calls to <c>monitor_node(Node, true)</c> for
- the same <c><anno>Node</anno></c> is not an error; it results in as many,
- completely independent, monitorings.</p>
+ the same <c><anno>Node</anno></c> is not an error; it results
+ in as many independent monitoring instances.</p>
<p>If <c><anno>Node</anno></c> fails or does not exist, the message
<c>{nodedown, Node}</c> is delivered to the process. If a
process has made two calls to <c>monitor_node(Node, true)</c>
- and <c><anno>Node</anno></c> terminates, two <c>nodedown</c> messages are
- delivered to the process. If there is no connection to
- <c><anno>Node</anno></c>, there will be an attempt to create one. If this
- fails, a <c>nodedown</c> message is delivered.</p>
+ and <c><anno>Node</anno></c> terminates, two <c>nodedown</c> messages
+ are delivered to the process. If there is no connection to
+ <c><anno>Node</anno></c>, an attempt is made to create one.
+ If this fails, a <c>nodedown</c> message is delivered.</p>
<p>Nodes connected through hidden connections can be monitored
- as any other node.</p>
+ as any other nodes.</p>
<p>Failure: <c>badarg</c> if the local node is not alive.</p>
</desc>
</func>
+
<func>
<name name="monitor_node" arity="3"/>
- <fsummary>Monitor the status of a node</fsummary>
+ <fsummary>Monitors the status of a node.</fsummary>
<desc>
- <p>Behaves as <c>monitor_node/2</c> except that it allows an
+ <p>Behaves as
+ <seealso marker="#monitor_node/2">monitor_node/2</seealso>
+ except that it allows an
extra option to be given, namely <c>allow_passive_connect</c>.
- The option allows the BIF to wait the normal net connection
- timeout for the <em>monitored node</em> to connect itself,
+ This option allows the BIF to wait the normal network connection
+ time-out for the <em>monitored node</em> to connect itself,
even if it cannot be actively connected from this node
- (i.e. it is blocked). The state where this might be useful can
- only be achieved by using the kernel option
- <c>dist_auto_connect once</c>. If that kernel option is not
- used, the <c>allow_passive_connect</c> option has no
- effect.</p>
+ (that is, it is blocked). The state where this can be useful
+ can only be achieved by using the <c>Kernel</c> option
+ <c>dist_auto_connect once</c>. If that option is not
+ used, option <c>allow_passive_connect</c> has no effect.</p>
<note>
- <p>The <c>allow_passive_connect</c> option is used
+ <p>Option <c>allow_passive_connect</c> is used
internally and is seldom needed in applications where the
- network topology and the kernel options in effect is known in
- advance.</p>
+ network topology and the <c>Kernel</c> options in effect
+ are known in advance.</p>
</note>
<p>Failure: <c>badarg</c> if the local node is not alive or the
option list is malformed.</p>
</desc>
</func>
+
+ <func>
+ <name name="monotonic_time" arity="0"/>
+ <fsummary>Current Erlang monotonic time.</fsummary>
+ <desc>
+ <p>Returns the current
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> in <c>native</c>
+ <seealso marker="#type_time_unit">time unit</seealso>. This
+ is a monotonically increasing time since some unspecified point in
+ time.</p>
+
+ <note><p>This is a
+ <seealso marker="time_correction#Monotonically_Increasing">monotonically increasing</seealso> time, but <em>not</em> a
+ <seealso marker="time_correction#Strictly_Monotonically_Increasing">strictly monotonically increasing</seealso>
+ time. That is, consecutive calls to
+ <c>erlang:monotonic_time/0</c> can produce the same result.</p>
+
+ <p>Different runtime system instances will use different
+ unspecified points in time as base for their Erlang monotonic clocks.
+ That is, it is <em>pointless</em> comparing monotonic times from
+ different runtime system instances. Different runtime system instances
+ may also place this unspecified point in time different relative
+ runtime system start. It may be placed in the future (time at start
+ is a negative value), the past (time at start is a
+ positive value), or the runtime system start (time at start is
+ zero). The monotonic time at runtime system start can be
+ retrieved by calling
+ <seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>.</p></note>
+ </desc>
+ </func>
+ <func>
+ <name name="monotonic_time" arity="1"/>
+ <fsummary>Current Erlang monotonic time</fsummary>
+ <desc>
+ <p>Returns the current
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> converted
+ into the <c><anno>Unit</anno></c> passed as argument.</p>
+
+ <p>Same as calling
+ <seealso marker="#convert_time_unit/3"><c>erlang:convert_time_unit</c></seealso><c>(</c><seealso marker="#monotonic_time/0"><c>erlang:monotonic_time()</c></seealso><c>,
+ native, <anno>Unit</anno>)</c>
+ however optimized for commonly used <c><anno>Unit</anno></c>s.</p>
+ </desc>
+ </func>
<func>
<name name="nif_error" arity="1"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Works exactly like
- <seealso marker="#error/1">erlang:error/1</seealso>,
- but Dialyzer thinks that this BIF will return an arbitrary term.
- When used in a stub function for a NIF to generate an
- exception when the NIF library is not loaded, Dialyzer
- will not generate false warnings.</p>
+ <seealso marker="#error/1">erlang:error/1</seealso>, but
+ <c>Dialyzer</c> thinks that this BIF will return an arbitrary
+ term. When used in a stub function for a NIF to generate an
+ exception when the NIF library is not loaded, <c>Dialyzer</c>
+ does not generate false warnings.</p>
</desc>
</func>
+
<func>
<name name="nif_error" arity="2"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Works exactly like
- <seealso marker="#error/2">erlang:error/2</seealso>,
- but Dialyzer thinks that this BIF will return an arbitrary term.
- When used in a stub function for a NIF to generate an
- exception when the NIF library is not loaded, Dialyzer
- will not generate false warnings.</p>
+ <seealso marker="#error/2">erlang:error/2</seealso>, but
+ <c>Dialyzer</c> thinks that this BIF will return an arbitrary
+ term. When used in a stub function for a NIF to generate an
+ exception when the NIF library is not loaded, <c>Dialyzer</c>
+ does not generate false warnings.</p>
</desc>
</func>
+
<func>
<name name="node" arity="0"/>
- <fsummary>Name of the local node</fsummary>
+ <fsummary>Name of the local node.</fsummary>
<desc>
<p>Returns the name of the local node. If the node is not alive,
<c>nonode@nohost</c> is returned instead.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="node" arity="1"/>
- <fsummary>At which node is a pid, port or reference located</fsummary>
+ <fsummary>At which node a pid, port, or reference originates.</fsummary>
<desc>
- <p>Returns the node where <c><anno>Arg</anno></c> is located. <c><anno>Arg</anno></c> can
- be a pid, a reference, or a port. If the local node is not
+ <p>Returns the node where <c><anno>Arg</anno></c> originates.
+ <c><anno>Arg</anno></c> can
+ be a process identifier, a reference, or a port.
+ If the local node is not
alive, <c>nonode@nohost</c> is returned.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="nodes" arity="0"/>
- <fsummary>All visible nodes in the system</fsummary>
+ <fsummary>All visible nodes in the system.</fsummary>
<desc>
- <p>Returns a list of all visible nodes in the system, excluding
+ <p>Returns a list of all visible nodes in the system, except
the local node. Same as <c>nodes(visible)</c>.</p>
</desc>
</func>
+
<func>
<name name="nodes" arity="1"/>
- <fsummary>All nodes of a certain type in the system</fsummary>
+ <fsummary>All nodes of a certain type in the system.</fsummary>
<desc>
- <p>Returns a list of nodes according to argument given.
- The result returned when the argument is a list, is the list
+ <p>Returns a list of nodes according to the argument given.
+ The returned result when the argument is a list, is the list
of nodes satisfying the disjunction(s) of the list elements.</p>
<p><c><anno>NodeType</anno></c> can be any of the following:</p>
<taglist>
@@ -2717,129 +3209,130 @@ os_prompt% </pre>
</item>
<tag><c>known</c></tag>
<item>
- <p>Nodes which are known to this node, i.e., connected,
- previously connected, etc.</p>
+ <p>Nodes that are known to this node. That is, connected
+ nodes and nodes referred to by process identifiers, port
+ identifiers and references located on this node.
+ The set of known nodes is garbage collected. Notice that
+ this garbage collection can be delayed. For more
+ information, see
+ <seealso marker="erlang#system_info_delayed_node_table_gc">delayed_node_table_gc</seealso>.
+ </p>
</item>
</taglist>
<p>Some equalities: <c>[node()] = nodes(this)</c>,
<c>nodes(connected) = nodes([visible, hidden])</c>, and
<c>nodes() = nodes(visible)</c>.</p>
- <p>If the local node is not alive,
- <c>nodes(this) == nodes(known) == [nonode@nohost]</c>, for
- any other <c><anno>Arg</anno></c> the empty list [] is returned.</p>
</desc>
</func>
+
<func>
<name name="now" arity="0"/>
+ <fsummary>Elapsed time since 00:00 GMT.</fsummary>
<type name="timestamp"/>
- <fsummary>Elapsed time since 00:00 GMT</fsummary>
<desc>
+ <warning><p><em>This function is deprecated! Do not use it!</em>
+ See the users guide chapter
+ <seealso marker="time_correction">Time and Time Correction</seealso>
+ for more information. Specifically the
+ <seealso marker="time_correction#Dos_and_Donts">Dos and Dont's</seealso>
+ section for information on what to use instead of <c>erlang:now/0</c>.
+ </p></warning>
<p>Returns the tuple <c>{MegaSecs, Secs, MicroSecs}</c> which is
- the elapsed time since 00:00 GMT, January 1, 1970 (zero hour)
+ the elapsed time since 00:00 GMT, January 1, 1970 (zero hour),
on the assumption that the underlying OS supports this.
- Otherwise, some other point in time is chosen. It is also
- guaranteed that subsequent calls to this BIF returns
+ Otherwise some other point in time is chosen. It is also
+ guaranteed that subsequent calls to this BIF return
continuously increasing values. Hence, the return value from
- <c>now()</c> can be used to generate unique time-stamps,
- and if it is called in a tight loop on a fast machine
+ <c>now()</c> can be used to generate unique time-stamps.
+ If it is called in a tight loop on a fast machine,
the time of the node can become skewed.</p>
- <p>It can only be used to check the local time of day if
- the time-zone info of the underlying operating system is
+ <p>Can only be used to check the local time of day if
+ the time-zone information of the underlying OS is
properly configured.</p>
- <p>If you do not need the return value to be unique and
- monotonically increasing, use
- <seealso marker="kernel:os#timestamp/0">os:timestamp/0</seealso>
- instead to avoid some overhead.</p>
</desc>
</func>
+
<func>
<name name="open_port" arity="2"/>
- <fsummary>Open a port</fsummary>
+ <fsummary>Opens a port.</fsummary>
<desc>
<p>Returns a port identifier as the result of opening a
new Erlang port. A port can be seen as an external Erlang
- process.
- </p>
+ process.</p>
<p>The name of the executable as well as the arguments
- given in <c>cd</c>, <c>env</c>, <c>args</c> and <c>arg0</c> is subject to
- Unicode file name translation if the system is running
+ given in <c>cd</c>, <c>env</c>, <c>args</c>, and <c>arg0</c> are
+ subject to Unicode file name translation if the system is running
in Unicode file name mode. To avoid
- translation or force i.e. UTF-8, supply the executable
+ translation or to force, for example UTF-8, supply the executable
and/or arguments as a binary in the correct
- encoding. See the <seealso
- marker="kernel:file">file</seealso> module, the
- <seealso marker="kernel:file#native_name_encoding/0">
- file:native_name_encoding/0</seealso> function and the
- <seealso marker="stdlib:unicode_usage">stdlib users guide
- </seealso> for details.</p>
-
- <note><p>The characters in the name (if given as a list)
- can only be &gt; 255 if the Erlang VM is started in
- Unicode file name translation mode, otherwise the name
+ encoding. For details, see the module
+ <seealso marker="kernel:file">file</seealso>, the function
+ <seealso marker="kernel:file#native_name_encoding/0">file:native_name_encoding/0</seealso>, and the
+ <seealso marker="stdlib:unicode_usage">STDLIB </seealso>
+ User's Guide.</p>
+ <note><p>The characters in the name (if given as a list) can
+ only be higher than 255 if the Erlang Virtual Machine is started
+ in Unicode file name translation mode. Otherwise the name
of the executable is limited to the ISO-latin-1
character set.</p></note>
-
- <p><c><anno>PortName</anno></c> is one of the following:</p>
+ <p><c><anno>PortName</anno></c> can be any of the following:</p>
<taglist>
<tag><c>{spawn, <anno>Command</anno>}</c></tag>
<item>
- <p>Starts an external program. <c><anno>Command</anno></c> is the name
- of the external program which will be run. <c><anno>Command</anno></c>
+ <p>Starts an external program. <c><anno>Command</anno></c>
+ is the name of the external program to be run.
+ <c><anno>Command</anno></c>
runs outside the Erlang work space unless an Erlang
- driver with the name <c><anno>Command</anno></c> is found. If found,
- that driver will be started. A driver runs in the Erlang
- workspace, which means that it is linked with the Erlang
+ driver with the name <c><anno>Command</anno></c> is found.
+ If found, that driver is started. A driver runs in the Erlang
+ work space, which means that it is linked with the Erlang
runtime system.</p>
<p>When starting external programs on Solaris, the system
call <c>vfork</c> is used in preference to <c>fork</c>
for performance reasons, although it has a history of
- being less robust. If there are problems with using
- <c>vfork</c>, setting the environment variable
- <c>ERL_NO_VFORK</c> to any value will cause <c>fork</c>
+ being less robust. If there are problems using
+ <c>vfork</c>, setting environment variable
+ <c>ERL_NO_VFORK</c> to any value causes <c>fork</c>
to be used instead.</p>
-
- <p>For external programs, the <c>PATH</c> is searched
+ <p>For external programs, <c>PATH</c> is searched
(or an equivalent method is used to find programs,
- depending on operating system). This is done by invoking
- the shell on certain platforms. The first space
- separated token of the command will be considered as the
+ depending on OS). This is done by invoking
+ the shell on certain platforms. The first space-separated
+ token of the command is considered as the
name of the executable (or driver). This (among other
things) makes this option unsuitable for running
- programs having spaces in file or directory names. Use
- {spawn_executable, <anno>Command</anno>} instead if spaces in executable
- file names is desired.</p>
+ programs having spaces in file names or directory names.
+ If spaces in executable file names are desired, use
+ <c>{spawn_executable, <anno>Command</anno>}</c> instead.</p>
</item>
<tag><c>{spawn_driver, <anno>Command</anno>}</c></tag>
<item>
<p>Works like <c>{spawn, <anno>Command</anno>}</c>, but demands the
- first (space separated) token of the command to be the name of a
+ first (space-separated) token of the command to be the name of a
loaded driver. If no driver with that name is loaded, a
<c>badarg</c> error is raised.</p>
</item>
<tag><c>{spawn_executable, <anno>FileName</anno>}</c></tag>
<item>
-
<p>Works like <c>{spawn, <anno>FileName</anno>}</c>, but only runs
- external executables. The <c><anno>FileName</anno></c> in its whole
- is used as the name of the executable, including any
- spaces. If arguments are to be passed, the
- <c>args</c> and <c>arg0</c> <c><anno>PortSettings</anno></c> can be used.</p>
-
- <p>The shell is not usually invoked to start the
- program, it's executed directly. Neither is the
- <c>PATH</c> (or equivalent) searched. To find a program
- in the PATH to execute, use <seealso
- marker="kernel:os#find_executable/1">os:find_executable/1</seealso>.</p>
+ external executables. <c><anno>FileName</anno></c> in its whole
+ is used as the name of the executable, including any spaces.
+ If arguments are to be passed, the <c><anno>PortSettings</anno></c>
+ <c>args</c> and <c>arg0</c> can be used.</p>
+ <p>The shell is usually not invoked to start the
+ program, it is executed directly. <c>PATH</c> (or
+ equivalent) is not searched. To find a program
+ in <c>PATH</c> to execute, use
+ <seealso marker="kernel:os#find_executable/1">os:find_executable/1</seealso>.</p>
<p>Only if a shell script or <c>.bat</c> file is
- executed, the appropriate command interpreter will
- implicitly be invoked, but there will still be no
- command argument expansion or implicit PATH search.</p>
-
- <p>If the <c><anno>FileName</anno></c> cannot be run, an error
- exception, with the posix error code as the reason, is
- raised. The error reason may differ between operating
- systems. Typically the error <c>enoent</c> is raised
- when one tries to run a program that is not found and
+ executed, the appropriate command interpreter is
+ invoked implicitly, but there is still no
+ command argument expansion or implicit <c>PATH</c> search.</p>
+ <p>If <c><anno>FileName</anno></c> cannot be run, an error
+ exception is raised, with the POSIX error code as the reason.
+ The error reason can differ between OSs.
+ Typically the error <c>enoent</c> is raised when an
+ attempt is made to run a program that is not found and
<c>eacces</c> is raised when the given file is not
executable.</p>
</item>
@@ -2849,19 +3342,18 @@ os_prompt% </pre>
file descriptors used by Erlang. The file descriptor
<c><anno>In</anno></c> can be used for standard input, and the file
descriptor <c><anno>Out</anno></c> for standard output. It is only
- used for various servers in the Erlang operating system
- (<c>shell</c> and <c>user</c>). Hence, its use is very
- limited.</p>
+ used for various servers in the Erlang OS (<c>shell</c>
+ and <c>user</c>). Hence, its use is limited.</p>
</item>
</taglist>
<p><c><anno>PortSettings</anno></c> is a list of settings for the port.
- Valid settings are:</p>
+ The valid settings are as follows:</p>
<taglist>
<tag><c>{packet, <anno>N</anno>}</c></tag>
<item>
<p>Messages are preceded by their length, sent in <c><anno>N</anno></c>
- bytes, with the most significant byte first. Valid values
- for <c>N</c> are 1, 2, or 4.</p>
+ bytes, with the most significant byte first. The valid values
+ for <c>N</c> are 1, 2, and 4.</p>
</item>
<tag><c>stream</c></tag>
<item>
@@ -2872,116 +3364,108 @@ os_prompt% </pre>
<tag><c>{line, <anno>L</anno>}</c></tag>
<item>
<p>Messages are delivered on a per line basis. Each line
- (delimited by the OS-dependent newline sequence) is
- delivered in one single message. The message data format
- is <c>{Flag, Line}</c>, where <c>Flag</c> is either
- <c>eol</c> or <c>noeol</c> and <c>Line</c> is the actual
- data delivered (without the newline sequence).</p>
+ (delimited by the OS-dependent new line sequence) is
+ delivered in a single message. The message data format
+ is <c>{Flag, Line}</c>, where <c>Flag</c> is
+ <c>eol</c> or <c>noeol</c>, and <c>Line</c> is the
+ data delivered (without the new line sequence).</p>
<p><c><anno>L</anno></c> specifies the maximum line length in bytes.
- Lines longer than this will be delivered in more than one
- message, with the <c>Flag</c> set to <c>noeol</c> for all
+ Lines longer than this are delivered in more than one
+ message, with <c>Flag</c> set to <c>noeol</c> for all
but the last message. If end of file is encountered
- anywhere else than immediately following a newline
- sequence, the last line will also be delivered with
- the <c>Flag</c> set to <c>noeol</c>. In all other cases,
+ anywhere else than immediately following a new line
+ sequence, the last line is also delivered with
+ <c>Flag</c> set to <c>noeol</c>. Otherwise
lines are delivered with <c>Flag</c> set to <c>eol</c>.</p>
- <p>The <c>{packet, <anno>N</anno>}</c> and <c>{line, <anno>L</anno>}</c> settings are
- mutually exclusive.</p>
+ <p>The <c>{packet, <anno>N</anno>}</c> and <c>{line,
+ <anno>L</anno>}</c> settings are mutually exclusive.</p>
</item>
<tag><c>{cd, <anno>Dir</anno>}</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> and
- <c>{spawn_executable, <anno>FileName</anno>}</c>.
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c> and
+ <c>{spawn_executable, <anno>FileName</anno>}</c>.
The external program starts using <c><anno>Dir</anno></c> as its
- working directory. <c><anno>Dir</anno></c> must be a string.
- </p>
+ working directory. <c><anno>Dir</anno></c> must be a string.</p>
</item>
<tag><c>{env, <anno>Env</anno>}</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> and
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c> and
<c>{spawn_executable, <anno>FileName</anno>}</c>.
The environment of the started process is extended using
the environment specifications in <c><anno>Env</anno></c>.</p>
- <p><c><anno>Env</anno></c> should be a list of tuples <c>{<anno>Name</anno>, <anno>Val</anno>}</c>,
- where <c><anno>Name</anno></c> is the name of an environment variable,
- and <c><anno>Val</anno></c> is the value it is to have in the spawned
- port process. Both <c><anno>Name</anno></c> and <c><anno>Val</anno></c> must be
- strings. The one exception is <c><anno>Val</anno></c> being the atom
+ <p><c><anno>Env</anno></c> is to be a list of tuples
+ <c>{<anno>Name</anno>, <anno>Val</anno>}</c>,
+ where <c><anno>Name</anno></c> is the name of an
+ environment variable, and <c><anno>Val</anno></c> is the
+ value it is to have in the spawned
+ port process. Both <c><anno>Name</anno></c> and
+ <c><anno>Val</anno></c> must be strings. The one
+ exception is <c><anno>Val</anno></c> being the atom
<c>false</c> (in analogy with <c>os:getenv/1</c>), which
- removes the environment variable.
- </p>
+ removes the environment variable.</p>
</item>
<tag><c>{args, [ string() | binary() ]}</c></tag>
<item>
-
- <p>This option is only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
+ <p>Only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
and specifies arguments to the executable. Each argument
is given as a separate string and (on Unix) eventually
ends up as one element each in the argument vector. On
- other platforms, similar behavior is mimicked.</p>
-
- <p>The arguments are not expanded by the shell prior to
- being supplied to the executable, most notably this
- means that file wildcard expansion will not happen. Use
- <seealso
- marker="stdlib:filelib#wildcard/1">filelib:wildcard/1</seealso>
- to expand wildcards for the arguments. Note that even if
+ other platforms, a similar behavior is mimicked.</p>
+ <p>The arguments are not expanded by the shell before
+ being supplied to the executable. Most notably this
+ means that file wild card expansion does not happen.
+ To expand wild cards for the arguments, use
+ <seealso marker="stdlib:filelib#wildcard/1">filelib:wildcard/1</seealso>.
+ Notice that even if
the program is a Unix shell script, meaning that the
- shell will ultimately be invoked, wildcard expansion
- will not happen and the script will be provided with the
- untouched arguments. On Windows&reg;, wildcard expansion
- is always up to the program itself, why this isn't an
- issue.</p>
-
- <p>Note also that the actual executable name (a.k.a. <c>argv[0]</c>)
- should not be given in this list. The proper executable name will
- automatically be used as argv[0] where applicable.</p>
-
- <p>If one, for any reason, wants to explicitly set the
- program name in the argument vector, the <c>arg0</c>
- option can be used.</p>
-
+ shell ultimately is invoked, wild card expansion
+ does not happen, and the script is provided with the
+ untouched arguments. On Windows, wild card expansion
+ is always up to the program itself, therefore this is
+ not an issue issue.</p>
+ <p>The executable name (also known as <c>argv[0]</c>)
+ is not to be given in this list. The proper executable name
+ is automatically used as argv[0], where applicable.</p>
+ <p>If you explicitly want to set the
+ program name in the argument vector, option <c>arg0</c>
+ can be used.</p>
</item>
<tag><c>{arg0, string() | binary()}</c></tag>
<item>
-
- <p>This option is only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
+ <p>Only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
and explicitly specifies the program name argument when
- running an executable. This might in some circumstances,
- on some operating systems, be desirable. How the program
- responds to this is highly system dependent and no specific
+ running an executable. This can in some circumstances,
+ on some OSs, be desirable. How the program
+ responds to this is highly system-dependent and no specific
effect is guaranteed.</p>
-
</item>
-
<tag><c>exit_status</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> where
- <c><anno>Command</anno></c> refers to an external program, and for
- <c>{spawn_executable, <anno>FileName</anno>}</c>.</p>
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c>, where
+ <c><anno>Command</anno></c> refers to an external program, and
+ for <c>{spawn_executable, <anno>FileName</anno>}</c>.</p>
<p>When the external process connected to the port exits, a
message of the form <c>{Port,{exit_status,Status}}</c> is
sent to the connected process, where <c>Status</c> is the
exit status of the external process. If the program
- aborts, on Unix the same convention is used as the shells
- do (i.e., 128+signal).</p>
- <p>If the <c>eof</c> option has been given as well,
- the <c>eof</c> message and the <c>exit_status</c> message
- appear in an unspecified order.</p>
- <p>If the port program closes its stdout without exiting,
- the <c>exit_status</c> option will not work.</p>
+ aborts on Unix, the same convention is used as the shells
+ do (that is, 128+signal).</p>
+ <p>If option <c>eof</c> is also given, the messages <c>eof</c>
+ and <c>exit_status</c> appear in an unspecified order.</p>
+ <p>If the port program closes its <c>stdout</c> without exiting,
+ option <c>exit_status</c> does not work.</p>
</item>
<tag><c>use_stdio</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> and
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c> and
<c>{spawn_executable, <anno>FileName</anno>}</c>. It
allows the standard input and output (file descriptors 0
- and 1) of the spawned (UNIX) process for communication
+ and 1) of the spawned (Unix) process for communication
with Erlang.</p>
</item>
<tag><c>nouse_stdio</c></tag>
<item>
- <p>The opposite of <c>use_stdio</c>. Uses file descriptors
+ <p>The opposite of <c>use_stdio</c>. It uses file descriptors
3 and 4 for communication with Erlang.</p>
</item>
<tag><c>stderr_to_stdout</c></tag>
@@ -2993,14 +3477,15 @@ os_prompt% </pre>
</item>
<tag><c>overlapped_io</c></tag>
<item>
- <p>Affects ports to external programs on Windows&reg; only.
- The standard input and standard output handles of the port program
- will, if this option is supplied, be opened with the flag
- FILE_FLAG_OVERLAPPED, so that the port program can (and has to) do
+ <p>Affects ports to external programs on Windows only. The
+ standard input and standard output handles of the port program
+ are, if this option is supplied, opened with flag
+ <c>FILE_FLAG_OVERLAPPED</c>, so that the port program can
+ (and must) do
overlapped I/O on its standard handles. This is not normally
the case for simple port programs, but an option of value for the
- experienced Windows programmer. <em>On all other platforms, this
- option is silently discarded</em>.</p>
+ experienced Windows programmer. <em>On all other platforms, this
+ option is silently discarded.</em></p>
</item>
<tag><c>in</c></tag>
<item>
@@ -3012,345 +3497,354 @@ os_prompt% </pre>
</item>
<tag><c>binary</c></tag>
<item>
- <p>All IO from the port are binary data objects as opposed
+ <p>All I/O from the port is binary data objects as opposed
to lists of bytes.</p>
</item>
<tag><c>eof</c></tag>
<item>
- <p>The port will not be closed at the end of the file and
- produce an exit signal. Instead, it will remain open and
- a <c>{Port, eof}</c> message will be sent to the process
+ <p>The port is not closed at the end of the file and does not
+ produce an exit signal. Instead, it remains open and
+ a <c>{Port, eof}</c> message is sent to the process
holding the port.</p>
</item>
<tag><c>hide</c></tag>
<item>
- <p>When running on Windows, suppress creation of a new
+ <p>When running on Windows, suppresses creation of a new
console window when spawning the port program.
(This option has no effect on other platforms.)</p>
</item>
- <tag><marker id="open_port_parallelism"><c>{parallelism, Boolean}</c></marker></tag>
+ <tag><c>{parallelism, Boolean}</c></tag>
<item>
- <p>Set scheduler hint for port parallelism. If set to <c>true</c>,
- the VM will schedule port tasks when doing so will improve
- parallelism in the system. If set to <c>false</c>, the VM will
- try to perform port tasks immediately, improving latency at the
- expense of parallelism. The default can be set on system startup
- by passing the
- <seealso marker="erl#+spp">+spp</seealso> command line argument
- to <seealso marker="erl">erl(1)</seealso>.
- </p>
+ <marker id="open_port_parallelism"></marker>
+ <p>Sets scheduler hint for port parallelism. If set to
+ <c>true</c>, the Virtual Machine schedules port tasks;
+ when doing so, it improves parallelism in the system. If set
+ to <c>false</c>, the Virtual Machine tries to
+ perform port tasks immediately, improving latency at the
+ expense of parallelism. The default can be set at system startup
+ by passing command-line argument
+ <seealso marker="erl#+spp">+spp</seealso> to <c>erl(1)</c>.</p>
</item>
</taglist>
- <p>The default is <c>stream</c> for all types of port and
+ <p>Default is <c>stream</c> for all port types and
<c>use_stdio</c> for spawned ports.</p>
<p>Failure: If the port cannot be opened, the exit reason is
- <c>badarg</c>, <c>system_limit</c>, or the Posix error code which
- most closely describes the error, or <c>einval</c> if no Posix code
- is appropriate:</p>
+ <c>badarg</c>, <c>system_limit</c>, or the POSIX error code that
+ most closely describes the error, or <c>einval</c> if no POSIX
+ code is appropriate:</p>
<taglist>
<tag><c>badarg</c></tag>
- <item>
- <p>Bad input arguments to <c>open_port</c>.</p>
+ <item>Bad input arguments to <c>open_port</c>.
</item>
<tag><c>system_limit</c></tag>
- <item>
- <p>All available ports in the Erlang emulator are in use.</p>
+ <item>All available ports in the Erlang emulator are in use.
</item>
<tag><c>enomem</c></tag>
- <item>
- <p>There was not enough memory to create the port.</p>
+ <item>Not enough memory to create the port.
</item>
<tag><c>eagain</c></tag>
- <item>
- <p>There are no more available operating system processes.</p>
+ <item>No more available OS processes.
</item>
<tag><c>enametoolong</c></tag>
- <item>
- <p>The external command given was too long.</p>
+ <item>Too long external command.
</item>
<tag><c>emfile</c></tag>
- <item>
- <p>There are no more available file descriptors (for the operating system process
- that the Erlang emulator runs in).</p>
+ <item>No more available file descriptors (for the
+ OS process that the Erlang emulator runs in).
</item>
<tag><c>enfile</c></tag>
- <item>
- <p>The file table is full (for the entire operating system).</p>
+ <item>Full file table (for the entire OS).
</item>
<tag><c>eacces</c></tag>
- <item>
- <p>The <c>Command</c> given in <c>{spawn_executable, Command}</c> does not point out an executable file.</p>
+ <item><c>Command</c> given in <c>{spawn_executable, Command}</c>
+ does not point out an executable file.
</item>
<tag><c>enoent</c></tag>
- <item>
- <p>The <c><anno>FileName</anno></c> given in <c>{spawn_executable, <anno>FileName</anno>}</c> does not point out an existing file.</p>
+ <item><c><anno>FileName</anno></c> given in
+ <c>{spawn_executable, <anno>FileName</anno>}</c>
+ does not point out an existing file.
</item>
</taglist>
<p>During use of a port opened using <c>{spawn, Name}</c>,
- <c>{spawn_driver, Name}</c> or <c>{spawn_executable, Name}</c>,
+ <c>{spawn_driver, Name}</c>, or <c>{spawn_executable, Name}</c>,
errors arising when sending messages to it are reported to
the owning process using signals of the form
- <c>{'EXIT', Port, PosixCode}</c>. See <c>file(3)</c> for
- possible values of <c>PosixCode</c>.</p>
+ <c>{'EXIT', Port, PosixCode}</c>. For the possible values of
+ <c>PosixCode</c>, see the
+ <seealso marker="kernel:file">file(3)</seealso>
+ manual page in <c>Kernel</c>.</p>
<p>The maximum number of ports that can be open at the same
- time can be configured by passing the
- <seealso marker="erl#max_ports"><c>+Q</c></seealso>
- command line flag to
- <seealso marker="erl"><c>erl(1)</c></seealso>.</p>
+ time can be configured by passing command-line flag
+ <seealso marker="erl#max_ports"><c>+Q</c></seealso> to
+ <c>erl(1)</c>.</p>
</desc>
</func>
+
<func>
<name name="phash" arity="2"/>
+ <fsummary>Portable hash function.</fsummary>
<type_desc variable="Range">Range = 1..2^32, Hash = 1..Range</type_desc>
- <fsummary>Portable hash function</fsummary>
<desc>
- <p>Portable hash function that will give the same hash for
+ <p>Portable hash function that gives the same hash for
the same Erlang term regardless of machine architecture and
- ERTS version (the BIF was introduced in ERTS 4.9.1.1). Range
- can be between 1 and 2^32, the function returns a hash value
- for <c><anno>Term</anno></c> within the range <c>1..<anno>Range</anno></c>.</p>
- <p>This BIF could be used instead of the old deprecated
- <c>erlang:hash/2</c> BIF, as it calculates better hashes for
- all data-types, but consider using <c>phash2/1,2</c> instead.</p>
+ <c>ERTS</c> version (the BIF was introduced in <c>ERTS</c> 4.9.1.1).
+ The function returns a hash value for
+ <c><anno>Term</anno></c> within the range
+ <c>1..<anno>Range</anno></c>. The maximum value for
+ <c><anno>Range</anno></c> is 2^32.</p>
+ <p>This BIF can be used instead of the old deprecated BIF
+ <c>erlang:hash/2</c>, as it calculates better hashes for
+ all data types, but consider using <c>phash2/1,2</c> instead.</p>
</desc>
</func>
+
<func>
<name name="phash2" arity="1"/>
<name name="phash2" arity="2"/>
+ <fsummary>Portable hash function.</fsummary>
<type_desc variable="Range">1..2^32</type_desc>
<type_desc variable="Hash">0..Range-1</type_desc>
- <fsummary>Portable hash function</fsummary>
<desc>
- <p>Portable hash function that will give the same hash for
+ <p>Portable hash function that gives the same hash for
the same Erlang term regardless of machine architecture and
- ERTS version (the BIF was introduced in ERTS 5.2). Range can
- be between 1 and 2^32, the function returns a hash value for
- <c><anno>Term</anno></c> within the range <c>0..<anno>Range</anno>-1</c>. When called
- without the <c><anno>Range</anno></c> argument, a value in the range
- <c>0..2^27-1</c> is returned.</p>
- <p>This BIF should always be used for hashing terms. It
+ <c>ERTS</c> version (the BIF was introduced in <c>ERTS</c> 5.2).
+ The function returns a hash value for
+ <c><anno>Term</anno></c> within the range
+ <c>0..<anno>Range</anno>-1</c>. The maximum value for
+ <c><anno>Range</anno></c> is 2^32. When without argument
+ <c><anno>Range</anno></c>, a value in the range
+ 0..2^27-1 is returned.</p>
+ <p>This BIF is always to be used for hashing terms. It
distributes small integers better than <c>phash/2</c>, and
it is faster for bignums and binaries.</p>
- <p>Note that the range <c>0..<anno>Range</anno>-1</c> is different from
- the range of <c>phash/2</c> (<c>1..<anno>Range</anno></c>).</p>
+ <p>Notice that the range <c>0..<anno>Range</anno>-1</c> is
+ different from the range of <c>phash/2</c>, which is
+ <c>1..<anno>Range</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="pid_to_list" arity="1"/>
- <fsummary>Text representation of a pid</fsummary>
+ <fsummary>Text representation of a pid.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of <c><anno>Pid</anno></c>.</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
</warning>
</desc>
</func>
+
<func>
<name name="port_close" arity="1"/>
- <fsummary>Close an open port</fsummary>
+ <fsummary>Closes an open port.</fsummary>
<desc>
<p>Closes an open port. Roughly the same as
- <c><anno>Port</anno> ! {self(), close}</c> except for the error behaviour
- (see below), being synchronous, and that the port does
- <em>not</em> reply with <c>{Port, closed}</c>. Any process may
+ <c><anno>Port</anno> ! {self(), close}</c> except for the error behavior
+ (see the following), being synchronous, and that the port does
+ <em>not</em> reply with <c>{Port, closed}</c>. Any process can
close a port with <c>port_close/1</c>, not only the port owner
(the connected process). If the calling process is linked to
- port identified by <c><anno>Port</anno></c>, an exit signal due
- to that link will be received by the process prior to the return
- from <c>port_close/1</c>.</p>
- <p>For comparison: <c><anno>Port</anno> ! {self(), close}</c> fails with
- <c>badarg</c> if <c><anno>Port</anno></c> cannot be sent to (i.e.,
- <c><anno>Port</anno></c> refers neither to a port nor to a process). If
- <c><anno>Port</anno></c> is a closed port nothing happens. If <c><anno>Port</anno></c>
+ the port identified by <c><anno>Port</anno></c>, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_close/1</c> returns.</p>
+ <p>For comparison: <c><anno>Port</anno> ! {self(), close}</c>
+ only fails with <c>badarg</c> if <c><anno>Port</anno></c> does
+ not refer to a port or a process. If <c><anno>Port</anno></c>
+ is a closed port, nothing happens. If <c><anno>Port</anno></c>
is an open port and the calling process is the port owner,
- the port replies with <c>{Port, closed}</c> when all buffers
- have been flushed and the port really closes, but if
- the calling process is not the port owner the <em>port owner</em> fails with <c>badsig</c>.</p>
-
- <p>Note that any process can close a port using
- <c><anno>Port</anno> ! {PortOwner, close}</c> just as if it itself was
+ the port replies with <c>{Port, closed}</c> when all buffers
+ have been flushed and the port really closes. If the calling
+ process is not the port owner, the <em>port owner</em> fails
+ with <c>badsig</c>.</p>
+ <p>Notice that any process can close a port using
+ <c><anno>Port</anno> ! {PortOwner, close}</c> as if it itself was
the port owner, but the reply always goes to the port owner.</p>
- <p>As of OTP-R16 <c><anno>Port</anno> ! {PortOwner, close}</c> is truly
- asynchronous. Note that this operation has always been
+ <p>As from OTP R16, <c><anno>Port</anno> ! {PortOwner, close}</c> is truly
+ asynchronous. Notice that this operation has always been
documented as an asynchronous operation, while the underlying
implementation has been synchronous. <c>port_close/1</c> is
- however still fully synchronous. This due to its error
+ however still fully synchronous. This because of its error
behavior.</p>
- <p>Failure:</p>
- <taglist>
- <tag><c>badarg</c></tag>
- <item>
- If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
- </item>
- </taglist>
+ <p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not an identifier
+ of an open port, or the registered name of an open port.
+ If the calling process was previously linked to the closed
+ port, identified by <c><anno>Port</anno></c>, the exit
+ signal from the port is guaranteed to be delivered before
+ this <c>badarg</c> exception occurs.</p>
</desc>
</func>
+
<func>
<name name="port_command" arity="2"/>
- <fsummary>Send data to a port</fsummary>
+ <fsummary>Sends data to a port.</fsummary>
<desc>
<p>Sends data to a port. Same as
- <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c> except for the error
- behaviour and being synchronous (see below). Any process may
- send data to a port with <c>port_command/2</c>, not only the
+ <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c> except
+ for the error
+ behavior and being synchronous (see the following). Any process
+ can send data to a port with <c>port_command/2</c>, not only the
port owner (the connected process).</p>
<p>For comparison: <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c>
- fails with <c>badarg</c> if <c><anno>Port</anno></c> cannot be sent to
- (i.e., <c><anno>Port</anno></c> refers neither to a port nor to a process).
- If <c><anno>Port</anno></c> is a closed port the data message disappears
+ only fails with <c>badarg</c> if <c><anno>Port</anno></c>
+ does not refer to a port or a process. If
+ <c><anno>Port</anno></c> is a closed port, the data message
+ disappears
without a sound. If <c><anno>Port</anno></c> is open and the calling
process is not the port owner, the <em>port owner</em> fails
with <c>badsig</c>. The port owner fails with <c>badsig</c>
- also if <c><anno>Data</anno></c> is not a valid IO list.</p>
- <p>Note that any process can send to a port using
- <c><anno>Port</anno> ! {PortOwner, {command, <anno>Data</anno>}}</c> just as if it
- itself was the port owner.</p>
- <p>If the port is busy, the calling process will be suspended
- until the port is not busy anymore.</p>
- <p>As of OTP-R16 <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c> is
- truly asynchronous. Note that this operation has always been
+ also if <c><anno>Data</anno></c> is an invalid I/O list.</p>
+ <p>Notice that any process can send to a port using
+ <c><anno>Port</anno> ! {PortOwner, {command, <anno>Data</anno>}}</c>
+ as if it itself was the port owner.</p>
+ <p>If the port is busy, the calling process is suspended
+ until the port is not busy any more.</p>
+ <p>As from OTP-R16, <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c>
+ is truly asynchronous. Notice that this operation has always been
documented as an asynchronous operation, while the underlying
implementation has been synchronous. <c>port_command/2</c> is
- however still fully synchronous. This due to its error
+ however still fully synchronous. This because of its error
behavior.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ port, or the registered name of an open port. If the
+ calling process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Data</anno></c> is not a valid io list.
+ If <c><anno>Data</anno></c> is an invalid I/O list.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="port_command" arity="3"/>
- <fsummary>Send data to a port</fsummary>
+ <fsummary>Sends data to a port.</fsummary>
<desc>
<p>Sends data to a port. <c>port_command(Port, Data, [])</c>
equals <c>port_command(Port, Data)</c>.</p>
- <p>If the port command is aborted <c>false</c> is returned;
- otherwise, <c>true</c> is returned.</p>
- <p>If the port is busy, the calling process will be suspended
- until the port is not busy anymore.</p>
- <p>Currently the following <c><anno>Option</anno></c>s are valid:</p>
+ <p>If the port command is aborted, <c>false</c> is returned,
+ otherwise <c>true</c>.</p>
+ <p>If the port is busy, the calling process is suspended
+ until the port is not busy any more.</p>
+ <p>The following <c><anno>Option</anno></c>s are valid:</p>
<taglist>
<tag><c>force</c></tag>
- <item>The calling process will not be suspended if the port is
- busy; instead, the port command is forced through. The
- call will fail with a <c>notsup</c> exception if the
+ <item>The calling process is not suspended if the port is
+ busy, instead the port command is forced through. The
+ call fails with a <c>notsup</c> exception if the
driver of the port does not support this. For more
- information see the
- <seealso marker="driver_entry#driver_flags"><![CDATA[ERL_DRV_FLAG_SOFT_BUSY]]></seealso>
- driver flag.
+ information, see driver flag
+ <seealso marker="driver_entry#driver_flags"><![CDATA[ERL_DRV_FLAG_SOFT_BUSY]]></seealso>.
</item>
<tag><c>nosuspend</c></tag>
- <item>The calling process will not be suspended if the port is
- busy; instead, the port command is aborted and
+ <item>The calling process is not suspended if the port is
+ busy, instead the port command is aborted and
<c>false</c> is returned.
</item>
</taglist>
<note>
- <p>More options may be added in the future.</p>
+ <p>More options can be added in a future release.</p>
</note>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ port, or the registered name of an open port. If the
+ calling process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Data</anno></c> is not a valid io list.
+ If <c><anno>Data</anno></c> is an invalid I/O list.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>OptionList</anno></c> is not a valid option list.
+ If <c><anno>OptionList</anno></c> is an invalid option list.
</item>
<tag><c>notsup</c></tag>
<item>
- If the <c>force</c> option has been passed, but the
+ If option <c>force</c> has been passed, but the
driver of the port does not allow forcing through
a busy port.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="port_connect" arity="2"/>
- <fsummary>Set the owner of a port</fsummary>
+ <fsummary>Sets the owner of a port.</fsummary>
<desc>
<p>Sets the port owner (the connected port) to <c><anno>Pid</anno></c>.
- Roughly the same as <c><anno>Port</anno> ! {Owner, {connect, <anno>Pid</anno>}}</c>
+ Roughly the same as
+ <c><anno>Port</anno> ! {Owner, {connect, <anno>Pid</anno>}}</c>
except for the following:</p>
<list type="bulleted">
<item>
- <p>The error behavior differs, see below.</p>
+ <p>The error behavior differs, see the following.</p>
</item>
<item>
<p>The port does <em>not</em> reply with
<c>{Port,connected}</c>.</p>
</item>
<item>
- <p><c>port_connect/1</c> is synchronous, see below.</p>
+ <p><c>port_connect/1</c> is synchronous, see the following.</p>
</item>
<item>
<p>The new port owner gets linked to the port.</p>
</item>
</list>
- <p>The old port owner stays linked to the port and have to call
- <c>unlink(Port)</c> if this is not desired. Any process may
+ <p>The old port owner stays linked to the port and must call
+ <c>unlink(Port)</c> if this is not desired. Any process can
set the port owner to be any process with
<c>port_connect/2</c>.</p>
- <p>For comparison: <c><anno>Port</anno> ! {self(), {connect, <anno>Pid</anno>}}</c> fails
- with <c>badarg</c> if <c><anno>Port</anno></c> cannot be sent to (i.e.,
- <c><anno>Port</anno></c> refers neither to a port nor to a process). If
- <c><anno>Port</anno></c> is a closed port nothing happens. If <c><anno>Port</anno></c>
+ <p>For comparison:
+ <c><anno>Port</anno> ! {self(), {connect, <anno>Pid</anno>}}</c>
+ only fails with <c>badarg</c> if <c><anno>Port</anno></c>
+ does not refer to a port or a process. If
+ <c><anno>Port</anno></c> is a closed port, nothing happens.
+ If <c><anno>Port</anno></c>
is an open port and the calling process is the port owner,
the port replies with <c>{Port, connected}</c> to the old
- port owner. Note that the old port owner is still linked to
- the port, and that the new is not. If <c><anno>Port</anno></c> is an open
+ port owner. Notice that the old port owner is still linked to
+ the port, while the new is not. If <c><anno>Port</anno></c> is an open
port and the calling process is not the port owner,
the <em>port owner</em> fails with <c>badsig</c>. The port
owner fails with <c>badsig</c> also if <c><anno>Pid</anno></c> is not an
- existing local pid.</p>
- <p>Note that any process can set the port owner using
- <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c> just as if it
- itself was the port owner, but the reply always goes to
+ existing local process identifier.</p>
+ <p>Notice that any process can set the port owner using
+ <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c>
+ as if it itself was the port owner, but the reply always goes to
the port owner.</p>
- <p>As of OTP-R16 <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c> is
- truly asynchronous. Note that this operation has always been
+ <p>As from OTP-R16,
+ <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c> is
+ truly asynchronous. Notice that this operation has always been
documented as an asynchronous operation, while the underlying
implementation has been synchronous. <c>port_connect/2</c> is
- however still fully synchronous. This due to its error
+ however still fully synchronous. This because of its error
behavior.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ If <c><anno>Port</anno></c> is not an identifier of an open port, or
+ the registered name of an open port. If the calling
+ process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>If process identified by <c>Pid</c> is not an existing
@@ -3358,53 +3852,75 @@ os_prompt% </pre>
</taglist>
</desc>
</func>
+
<func>
<name name="port_control" arity="3"/>
- <fsummary>Perform a synchronous control operation on a port</fsummary>
+ <fsummary>Performs a synchronous control operation on a port.</fsummary>
<desc>
<p>Performs a synchronous control operation on a port.
- The meaning of <c><anno>Operation</anno></c> and <c><anno>Data</anno></c> depends on
- the port, i.e., on the port driver. Not all port drivers
+ The meaning of <c><anno>Operation</anno></c> and
+ <c><anno>Data</anno></c> depends on
+ the port, that is, on the port driver. Not all port drivers
support this control feature.</p>
- <p>Returns: a list of integers in the range 0 through 255, or a
+ <p>Returns a list of integers in the range 0..255, or a
binary, depending on the port driver. The meaning of
the returned data also depends on the port driver.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not an open port or
- the registered name of an open port, if <c><anno>Operation</anno></c>
- cannot fit in a 32-bit integer, if the port driver does not
- support synchronous control operations, or if the port driver
- so decides for any reason (probably something wrong with
- <c><anno>Operation</anno></c> or <c><anno>Data</anno></c>).</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c><anno>Port</anno></c> is not an open port or the registered
+ name of an open port.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c><anno>Operation</anno></c> cannot fit in a 32-bit integer.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the port driver does not support synchronous control
+ operations.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the port driver so decides for any reason (probably
+ something wrong with <c><anno>Operation</anno></c> or
+ <c><anno>Data</anno></c>).
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="port_call" arity="3"/>
- <fsummary>Synchronous call to a port with term data</fsummary>
+ <fsummary>Performs a synchronous call to a port with term data.</fsummary>
<desc>
<p>Performs a synchronous call to a port. The meaning of
- <c><anno>Operation</anno></c> and <c><anno>Data</anno></c> depends on the port, i.e.,
+ <c><anno>Operation</anno></c> and <c><anno>Data</anno></c>
+ depends on the port, that is,
on the port driver. Not all port drivers support this feature.</p>
- <p><c><anno>Port</anno></c> is a port identifier, referring to a driver.</p>
+ <p><c><anno>Port</anno></c> is a port identifier,
+ referring to a driver.</p>
<p><c><anno>Operation</anno></c> is an integer, which is passed on to
the driver.</p>
- <p><c><anno>Data</anno></c> is any Erlang term. This data is converted to
- binary term format and sent to the port.</p>
- <p>Returns: a term from the driver. The meaning of the returned
+ <p><c><anno>Data</anno></c> is any Erlang term. This data is converted
+ to binary term format and sent to the port.</p>
+ <p>Returns a term from the driver. The meaning of the returned
data also depends on the port driver.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ If <c><anno>Port</anno></c> is not an identifier of an open port,
+ or the registered name of an open port. If the calling
+ process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Operation</anno></c> does not fit in a
- 32-bit integer.
+ If <c><anno>Operation</anno></c> does not fit in a 32-bit integer.
</item>
<tag><c>badarg</c></tag>
<item>
@@ -3414,171 +3930,183 @@ os_prompt% </pre>
<tag><c>badarg</c></tag>
<item>
If the port driver so decides for any reason (probably
- something wrong with <c><anno>Operation</anno></c>, or
- <c><anno>Data</anno></c>).
+ something wrong with <c><anno>Operation</anno></c>
+ or <c><anno>Data</anno></c>).
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="port_info" arity="1"/>
- <fsummary>Information about a port</fsummary>
+ <fsummary>Information about a port.</fsummary>
<desc>
<p>Returns a list containing tuples with information about
- the <c><anno>Port</anno></c>, or <c>undefined</c> if the port is not open.
- The order of the tuples is not defined, nor are all the
- tuples mandatory.
- If <c>undefined</c> is returned and the calling process
- was linked to a previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/1</c>.</p>
- <p>Currently the result will containt information about the
- following <c>Item</c>s: <c>registered_name</c> (if the port has
- a registered name), <c>id</c>, <c>connected</c>, <c>links</c>,
- <c>name</c>, <c>input</c>, and <c>output</c>. For more information
- about the different <c>Item</c>s, see
+ <c><anno>Port</anno></c>, or <c>undefined</c> if the port is not open.
+ The order of the tuples is undefined, and all the
+ tuples are not mandatory.
+ If the port is closed and the calling process
+ was previously linked to the port, the exit signal from the
+ port is guaranteed to be delivered before <c>port_info/1</c>
+ returns <c>undefined</c>.</p>
+ <p>The result contains information about the following
+ <c>Item</c>s:</p>
+ <list type="bulleted">
+ <item><c>registered_name</c> (if the port has a registered
+ name)</item>
+ <item><c>id</c></item>
+ <item><c>connected</c></item>
+ <item><c>links</c></item>
+ <item><c>name</c></item>
+ <item><c>input</c></item>
+ <item><c>output</c></item>
+ </list>
+ <p>For more information about the different <c>Item</c>s, see
<seealso marker="#port_info/2">port_info/2</seealso>.</p>
<p>Failure: <c>badarg</c> if <c>Port</c> is not a local port
identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="1"/>
- <fsummary>Information about the connected process of a port</fsummary>
+ <fsummary>Information about the connected process of a port.</fsummary>
<desc>
<p><c><anno>Pid</anno></c> is the process identifier of the process
connected to the port.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="2"/>
- <fsummary>Information about the internal index of a port</fsummary>
+ <fsummary>Information about the internal index of a port.</fsummary>
<desc>
<p><c><anno>Index</anno></c> is the internal index of the port. This
- index may be used to separate ports.</p>
+ index can be used to separate ports.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="3"/>
- <fsummary>Information about the input of a port</fsummary>
+ <fsummary>Information about the input of a port.</fsummary>
<desc>
<p><c><anno>Bytes</anno></c> is the total number of bytes
read from the port.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="4"/>
- <fsummary>Information about the links of a port</fsummary>
+ <fsummary>Information about the links of a port.</fsummary>
<desc>
<p><c><anno>Pids</anno></c> is a list of the process identifiers
of the processes that the port is linked to.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="5"/>
- <fsummary>Information about the locking of a port</fsummary>
+ <fsummary>Information about the locking of a port.</fsummary>
<desc>
- <p><c><anno>Locking</anno></c> is currently either <c>false</c>
- (emulator without SMP support), <c>port_level</c> (port specific
- locking), or <c>driver_level</c> (driver specific locking). Note
- that these results are highly implementation specific and might
- change in the future.</p>
+ <p><c><anno>Locking</anno></c> is one of the following:</p>
+ <list type="bulleted">
+ <item><c>false</c> (emulator without SMP support)</item>
+ <item><c>port_level</c> (port-specific locking)</item>
+ <item><c>driver_level</c> (driver-specific locking)</item>
+ </list>
+ <p>Notice that these results are highly implementation-specific
+ and can change in a future release.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="6"/>
- <fsummary>Information about the memory size of a port</fsummary>
+ <fsummary>Information about the memory size of a port.</fsummary>
<desc>
- <p><c><anno>Bytes</anno></c> is the total amount of memory,
- in bytes, allocated for this port by the runtime system. Note
- that the port itself might have allocated memory which is not
+ <p><c><anno>Bytes</anno></c> is the total number of
+ bytes allocated for this port by the runtime system. The
+ port itself can have allocated memory that is not
included in <c><anno>Bytes</anno></c>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="7"/>
- <fsummary>Information about the monitors of a port</fsummary>
+ <fsummary>Information about the monitors of a port.</fsummary>
<desc>
<p><c><anno>Monitors</anno></c> represent processes that this port
- is monitoring.</p>
+ monitors.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="8"/>
- <fsummary>Information about the name of a port</fsummary>
+ <fsummary>Information about the name of a port.</fsummary>
<desc>
<p><c><anno>Name</anno></c> is the command name set by
<seealso marker="#open_port/2">open_port/2</seealso>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="9"/>
- <fsummary>Information about the OS pid of a port</fsummary>
+ <fsummary>Information about the OS pid of a port.</fsummary>
<desc>
<p><c><anno>OsPid</anno></c> is the process identifier (or equivalent)
of an OS process created with
@@ -3586,432 +4114,464 @@ os_prompt% </pre>
Command}, Options)</seealso>. If the port is not the result of spawning
an OS process, the value is <c>undefined</c>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="10"/>
- <fsummary>Information about the output of a port</fsummary>
+ <fsummary>Information about the output of a port.</fsummary>
<desc>
<p><c><anno>Bytes</anno></c> is the total number of bytes written
- to the port from Erlang processes using either
+ to the port from Erlang processes using
<seealso marker="#port_command/2">port_command/2</seealso>,
<seealso marker="#port_command/3">port_command/3</seealso>,
- or <c><anno>Port</anno> ! {Owner, {command, Data}</c>.
- </p>
+ or <c><anno>Port</anno> ! {Owner, {command, Data}</c>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="11"/>
- <fsummary>Information about the parallelism hint of a port</fsummary>
+ <fsummary>Information about the parallelism hint of a port.</fsummary>
<desc>
<p><c><anno>Boolean</anno></c> corresponds to the port parallelism
- hint being used by this port. For more information see
- the <seealso marker="#open_port_parallelism">parallelism</seealso>
- option of <seealso marker="#open_port/2">open_port/2</seealso>.</p>
+ hint being used by this port. For more information, see option
+ <seealso marker="#open_port_parallelism">parallelism</seealso>
+ of <seealso marker="#open_port/2">open_port/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="12"/>
- <fsummary>Information about the queue size of a port</fsummary>
+ <fsummary>Information about the queue size of a port.</fsummary>
<desc>
- <p><c><anno>Bytes</anno></c> is the total amount of data,
- in bytes, queued by the port using the ERTS driver queue
+ <p><c><anno>Bytes</anno></c> is the total number
+ of bytes queued by the port using the <c>ERTS</c> driver queue
implementation.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="13"/>
- <fsummary>Information about the registered name of a port</fsummary>
+ <fsummary>Information about the registered name of a port.</fsummary>
<desc>
<p><c><anno>RegisteredName</anno></c> is the registered name of
the port. If the port has no registered name, <c>[]</c> is returned.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_to_list" arity="1"/>
- <fsummary>Text representation of a port identifier</fsummary>
+ <fsummary>Text representation of a port identifier.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of the port identifier <c><anno>Port</anno></c>.</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
+ <p>This BIF is intended for debugging. It is not to be used
+ in application programs.</p>
</warning>
</desc>
</func>
+
<func>
<name name="ports" arity="0"/>
- <fsummary>All open ports</fsummary>
+ <fsummary>Lists all existing ports.</fsummary>
<desc>
<p>Returns a list of port identifiers corresponding to all the
- ports currently existing on the local node.</p>
-
- <p>Note that a port that is exiting, exists but is not open.</p>
+ ports existing on the local node.</p>
+ <p>Notice that an exiting port exists, but is not open.</p>
</desc>
</func>
+
<func>
<name name="pre_loaded" arity="0"/>
- <fsummary>List of all pre-loaded modules</fsummary>
+ <fsummary>Lists all pre-loaded modules.</fsummary>
<desc>
- <p>Returns a list of Erlang modules which are pre-loaded in
+ <p>Returns a list of Erlang modules that are preloaded in
the system. As all loading of code is done through the file
system, the file system must have been loaded previously.
- Hence, at least the module <c>init</c> must be pre-loaded.</p>
+ Hence, at least the module <c>init</c> must be preloaded.</p>
</desc>
</func>
+
<func>
<name name="process_display" arity="2"/>
- <fsummary>Write information about a local process on standard error</fsummary>
+ <fsummary>Writes information about a local process on standard error.</fsummary>
<desc>
<p>Writes information about the local process <c><anno>Pid</anno></c> on
- standard error. The currently allowed value for the atom
+ standard error. The only allowed value for the atom
<c><anno>Type</anno></c> is <c>backtrace</c>, which shows the contents of
the call stack, including information about the call chain, with
the current function printed first. The format of the output
is not further defined.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="1"/>
- <fsummary>Set process flag trap_exit for the calling process</fsummary>
+ <fsummary>Sets process flag <c>trap_exit</c> for the calling process.</fsummary>
<desc>
<p>When <c>trap_exit</c> is set to <c>true</c>, exit signals
- arriving to a process are converted to <c>{'EXIT', From, Reason}</c> messages, which can be received as ordinary
+ arriving to a process are converted to <c>{'EXIT', From, Reason}</c>
+ messages, which can be received as ordinary
messages. If <c>trap_exit</c> is set to <c>false</c>, the
process exits if it receives an exit signal other than
<c>normal</c> and the exit signal is propagated to its
- linked processes. Application processes should normally
- not trap exits.</p>
+ linked processes. Application processes are normally
+ not to trap exits.</p>
<p>Returns the old value of the flag.</p>
<p>See also <seealso marker="#exit/2">exit/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="2"/>
- <fsummary>Set process flag error_handler for the calling process</fsummary>
+ <fsummary>Sets process flag <c>error_handler</c> for the calling process.</fsummary>
<desc>
- <p>This is used by a process to redefine the error handler
+ <p>Used by a process to redefine the error handler
for undefined function calls and undefined registered
- processes. Inexperienced users should not use this flag
- since code auto-loading is dependent on the correct
+ processes. Inexperienced users are not to use this flag,
+ as code auto-loading depends on the correct
operation of the error handling module.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="3"/>
- <fsummary>Set process flag min_heap_size for the calling process</fsummary>
+ <fsummary>Sets process flag <c>min_heap_size</c> for the calling process.</fsummary>
<desc>
- <p>This changes the minimum heap size for the calling
- process.</p>
+ <p>Changes the minimum heap size for the calling process.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="4"/>
- <fsummary>Set process flag min_bin_vheap_size for the calling process</fsummary>
+ <fsummary>Sets process flag <c>min_bin_vheap_size</c> for the calling process.</fsummary>
<desc>
- <p>This changes the minimum binary virtual heap size for the calling
+ <p>Changes the minimum binary virtual heap size for the calling
process.</p>
- <p>Returns the old value of the flag.</p> </desc>
+ <p>Returns the old value of the flag.</p>
+ </desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="5"/>
+ <fsummary>Sets process flag <c>priority</c> for the calling process.</fsummary>
<type name="priority_level"/>
- <fsummary>Set process flag priority for the calling process</fsummary>
<desc>
<p><marker id="process_flag_priority"></marker>
- This sets the process priority. <c><anno>Level</anno></c> is an atom.
- There are currently four priority levels: <c>low</c>,
- <c>normal</c>, <c>high</c>, and <c>max</c>. The default
- priority level is <c>normal</c>. <em>NOTE</em>: The
- <c>max</c> priority level is reserved for internal use in
- the Erlang runtime system, and should <em>not</em> be used
- by others.
- </p>
- <p>Internally in each priority level processes are scheduled
- in a round robin fashion.
- </p>
+ Sets the process priority. <c><anno>Level</anno></c> is an atom.
+ There are four priority levels: <c>low</c>,
+ <c>normal</c>, <c>high</c>, and <c>max</c>. Default
+ is <c>normal</c>.</p>
+ <note>
+ <p>Priority level <c>max</c> is reserved for internal use in
+ the Erlang runtime system, and is <em>not</em> to be used
+ by others.</p>
+ </note>
+ <p>Internally in each priority level, processes are scheduled
+ in a round robin fashion.</p>
<p>Execution of processes on priority <c>normal</c> and
- priority <c>low</c> will be interleaved. Processes on
- priority <c>low</c> will be selected for execution less
- frequently than processes on priority <c>normal</c>.
- </p>
- <p>When there are runnable processes on priority <c>high</c>
- no processes on priority <c>low</c>, or <c>normal</c> will
- be selected for execution. Note, however, that this does
- <em>not</em> mean that no processes on priority <c>low</c>,
- or <c>normal</c> will be able to run when there are
- processes on priority <c>high</c> running. On the runtime
- system with SMP support there might be more processes running
- in parallel than processes on priority <c>high</c>, i.e.,
- a <c>low</c>, and a <c>high</c> priority process might
- execute at the same time.
- </p>
- <p>When there are runnable processes on priority <c>max</c>
+ <c>low</c> are interleaved. Processes on priority
+ <c>low</c> are selected for execution less
+ frequently than processes on priority <c>normal</c>.</p>
+ <p>When there are runnable processes on priority <c>high</c>,
+ no processes on priority <c>low</c> or <c>normal</c> are
+ selected for execution. Notice however, that this does
+ <em>not</em> mean that no processes on priority <c>low</c>
+ or <c>normal</c> can run when there are processes
+ running on priority <c>high</c>. On the runtime
+ system with SMP support, more processes can be running
+ in parallel than processes on priority <c>high</c>, that is,
+ a <c>low</c> and a <c>high</c> priority process can
+ execute at the same time.</p>
+ <p>When there are runnable processes on priority <c>max</c>,
no processes on priority <c>low</c>, <c>normal</c>, or
- <c>high</c> will be selected for execution. As with the
- <c>high</c> priority, processes on lower priorities might
- execute in parallel with processes on priority <c>max</c>.
- </p>
+ <c>high</c> are selected for execution. As with priority
+ <c>high</c>, processes on lower priorities can
+ execute in parallel with processes on priority <c>max</c>.</p>
<p>Scheduling is preemptive. Regardless of priority, a process
- is preempted when it has consumed more than a certain amount
+ is preempted when it has consumed more than a certain number
of reductions since the last time it was selected for
- execution.
- </p>
- <p><em>NOTE</em>: You should not depend on the scheduling
+ execution.</p>
+ <note>
+ <p>Do not depend on the scheduling
to remain exactly as it is today. Scheduling, at least on
- the runtime system with SMP support, is very likely to be
- modified in the future in order to better utilize available
- processor cores.
- </p>
- <p>There is currently <em>no</em> automatic mechanism for
- avoiding priority inversion, such as priority inheritance,
- or priority ceilings. When using priorities you have
- to take this into account and handle such scenarios by
- yourself.
- </p>
+ the runtime system with SMP support, is likely to be
+ changed in a future release to use available
+ processor cores better.</p>
+ </note>
+ <p>There is <em>no</em> automatic mechanism for
+ avoiding priority inversion, such as priority inheritance
+ or priority ceilings. When using priorities,
+ take this into account and handle such scenarios by
+ yourself.</p>
<p>Making calls from a <c>high</c> priority process into code
- that you don't have control over may cause the <c>high</c>
- priority process to wait for a processes with lower
- priority, i.e., effectively decreasing the priority of the
+ that you have no control over can cause the <c>high</c>
+ priority process to wait for a process with lower
+ priority. That is, effectively decreasing the priority of the
<c>high</c> priority process during the call. Even if this
- isn't the case with one version of the code that you don't
- have under your control, it might be the case in a future
- version of it. This might, for example, happen if a
- <c>high</c> priority process triggers code loading, since
- the code server runs on priority <c>normal</c>.
- </p>
+ is not the case with one version of the code that you have no
+ control over, it can be the case in a future
+ version of it. This can, for example, occur if a
+ <c>high</c> priority process triggers code loading, as
+ the code server runs on priority <c>normal</c>.</p>
<p>Other priorities than <c>normal</c> are normally not needed.
- When other priorities are used, they need to be used
- with care, especially the <c>high</c> priority <em>must</em>
- be used with care. A process on <c>high</c> priority should
- only perform work for short periods of time. Busy looping for
- long periods of time in a <c>high</c> priority process will
- most likely cause problems, since there are important servers
- in OTP running on priority <c>normal</c>.
- </p>
+ When other priorities are used, use them with care,
+ <em>especially</em> priority <c>high</c>. A
+ process on priority <c>high</c> is only
+ to perform work for short periods. Busy looping for
+ long periods in a <c>high</c> priority process does
+ most likely cause problems, as important OTP servers
+ run on priority <c>normal</c>.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="6"/>
- <fsummary>Set process flag save_calls for the calling process</fsummary>
+ <fsummary>Sets process flag <c>save_calls</c> for the calling process.</fsummary>
<desc>
<p><c><anno>N</anno></c> must be an integer in the interval 0..10000.
- If <c><anno>N</anno></c> &gt; 0, call saving is made active for the
- process, which means that information about the <c><anno>N</anno></c>
- most recent global function calls, BIF calls, sends and
+ If <c><anno>N</anno></c> is greater than 0, call saving is made
+ active for the
+ process. This means that information about the <c><anno>N</anno></c>
+ most recent global function calls, BIF calls, sends, and
receives made by the process are saved in a list, which
can be retrieved with
<c>process_info(Pid, last_calls)</c>. A global function
call is one in which the module of the function is
explicitly mentioned. Only a fixed amount of information
- is saved: a tuple <c>{Module, Function, Arity}</c> for
- function calls, and the mere atoms <c>send</c>,
- <c>'receive'</c> and <c>timeout</c> for sends and receives
- (<c>'receive'</c> when a message is received and
- <c>timeout</c> when a receive times out). If <c>N</c> = 0,
+ is saved, as follows:</p>
+ <list type="bulleted">
+ <item>A tuple <c>{Module, Function, Arity}</c> for
+ function calls</item>
+ <item> The atoms <c>send</c>, <c>'receive'</c>, and
+ <c>timeout</c> for sends and receives (<c>'receive'</c>
+ when a message is received and <c>timeout</c> when a
+ receive times out)</item>
+ </list>
+ <p>If <c>N</c> = 0,
call saving is disabled for the process, which is the
default. Whenever the size of the call saving list is set,
its contents are reset.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="7"/>
- <fsummary>Set process flag sensitive for the calling process</fsummary>
+ <fsummary>Sets process flag <c>sensitive</c> for the calling process.</fsummary>
<desc>
- <p>Set or clear the <c>sensitive</c> flag for the current process.
+ <p>Sets or clears flag <c>sensitive</c> for the current process.
When a process has been marked as sensitive by calling
- <c>process_flag(sensitive, true)</c>, features in the run-time
- system that can be used for examining the data and/or inner working
+ <c>process_flag(sensitive, true)</c>, features in the runtime
+ system that can be used for examining the data or inner working
of the process are silently disabled.</p>
<p>Features that are disabled include (but are not limited to)
the following:</p>
- <p>Tracing: Trace flags can still be set for the process, but no
- trace messages of any kind will be generated.
- (If the <c>sensitive</c> flag is turned off, trace messages will
- again be generated if there are any trace flags set.)</p>
- <p>Sequential tracing: The sequential trace token will be propagated
- as usual, but no sequential trace messages will be generated.</p>
- <p><c>process_info/1,2</c> cannot be used to read out the message
- queue or the process dictionary (both will be returned as empty lists).</p>
+ <list type="bulleted">
+ <item>Tracing: Trace flags can still be set for the process,
+ but no trace messages of any kind are generated. (If flag
+ <c>sensitive</c> is turned off, trace messages are again
+ generated if any trace flags are set.)</item>
+ <item>Sequential tracing: The sequential trace token is
+ propagated as usual, but no sequential trace messages are
+ generated.</item>
+ </list>
+ <p><c>process_info/1,2</c> cannot be used to read out the
+ message queue or the process dictionary (both are returned
+ as empty lists).</p>
<p>Stack back-traces cannot be displayed for the process.</p>
<p>In crash dumps, the stack, messages, and the process dictionary
- will be omitted.</p>
+ are omitted.</p>
<p>If <c>{save_calls,N}</c> has been set for the process, no
- function calls will be saved to the call saving list.
- (The call saving list will not be cleared; furthermore, send, receive,
- and timeout events will still be added to the list.)</p>
+ function calls are saved to the call saving list.
+ (The call saving list is not cleared. Furthermore, send, receive,
+ and timeout events are still added to the list.)</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="3"/>
- <fsummary>Set process flags for a process</fsummary>
+ <fsummary>Sets process flags for a process.</fsummary>
<desc>
- <p>Sets certain flags for the process <c><anno>Pid</anno></c>, in the same
- manner as
+ <p>Sets certain flags for the process <c><anno>Pid</anno></c>,
+ in the same manner as
<seealso marker="#process_flag/2">process_flag/2</seealso>.
- Returns the old value of the flag. The allowed values for
+ Returns the old value of the flag. The valid values for
<c><anno>Flag</anno></c> are only a subset of those allowed in
- <c>process_flag/2</c>, namely: <c>save_calls</c>.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c> is not a local process.</p>
+ <c>process_flag/2</c>, namely <c>save_calls</c>.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c>
+ is not a local process.</p>
</desc>
</func>
+
<func>
<name name="process_info" arity="1"/>
+ <fsummary>Information about a process.</fsummary>
<type name="process_info_result_item"/>
<type name="priority_level"/>
<type name="stack_item"/>
- <fsummary>Information about a process</fsummary>
<desc>
<p>Returns a list containing <c><anno>InfoTuple</anno></c>s with
miscellaneous information about the process identified by
- <c>Pid</c>, or <c>undefined</c> if the process is not alive.
- </p>
- <p>
- The order of the <c><anno>InfoTuple</anno></c>s is not defined, nor
- are all the <c><anno>InfoTuple</anno></c>s mandatory. The <c><anno>InfoTuple</anno></c>s
- part of the result may be changed without prior notice.
- Currently <c><anno>InfoTuple</anno></c>s with the following items
- are part of the result:
- <c>current_function</c>, <c>initial_call</c>, <c>status</c>,
- <c>message_queue_len</c>, <c>messages</c>, <c>links</c>,
- <c>dictionary</c>, <c>trap_exit</c>, <c>error_handler</c>,
- <c>priority</c>, <c>group_leader</c>, <c>total_heap_size</c>,
- <c>heap_size</c>, <c>stack_size</c>, <c>reductions</c>, and
- <c>garbage_collection</c>.
- If the process identified by <c><anno>Pid</anno></c> has a registered name
- also an <c><anno>InfoTuple</anno></c> with the item <c>registered_name</c>
- will appear.
- </p>
- <p>See <seealso marker="#process_info/2">process_info/2</seealso>
- for information about specific <c><anno>InfoTuple</anno></c>s.</p>
+ <c>Pid</c>, or <c>undefined</c> if the process is not alive.</p>
+ <p>The order of the <c><anno>InfoTuple</anno></c>s is undefined and
+ all <c><anno>InfoTuple</anno></c>s are not mandatory.
+ The <c><anno>InfoTuple</anno></c>s
+ part of the result can be changed without prior notice.</p>
+ <p>The <c><anno>InfoTuple</anno></c>s with the following items
+ are part of the result:</p>
+ <list type="bulleted">
+ <item><c>current_function</c></item>
+ <item><c>initial_call</c></item>
+ <item><c>status</c></item>
+ <item><c>message_queue_len</c></item>
+ <item><c>messages</c></item>
+ <item><c>links</c></item>
+ <item><c>dictionary</c></item>
+ <item><c>trap_exit</c></item>
+ <item><c>error_handler</c></item>
+ <item><c>priority</c></item>
+ <item><c>group_leader</c></item>
+ <item><c>total_heap_size</c></item>
+ <item><c>heap_size</c></item>
+ <item><c>stack_size</c></item>
+ <item><c>reductions</c></item>
+ <item><c>garbage_collection</c></item>
+ </list>
+ <p>If the process identified by <c><anno>Pid</anno></c> has a
+ registered name,
+ also an <c><anno>InfoTuple</anno></c> with item <c>registered_name</c>
+ appears.</p>
+ <p>For information about specific <c><anno>InfoTuple</anno></c>s, see
+ <seealso marker="#process_info/2">process_info/2</seealso>.</p>
<warning>
- <p>This BIF is intended for <em>debugging only</em>, use
- <seealso marker="#process_info/2">process_info/2</seealso>
- for all other purposes.
- </p>
+ <p>This BIF is intended for <em>debugging only</em>. For
+ all other purposes, use
+ <seealso marker="#process_info/2">process_info/2</seealso>.</p>
</warning>
- <p>Failure: <c>badarg</c> if <c>Pid</c> is not a local process.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c> is not a
+ local process.</p>
</desc>
</func>
+
<func>
<name name="process_info" arity="2" clause_i="1"/>
<name name="process_info" arity="2" clause_i="2"/>
+ <fsummary>Information about a process.</fsummary>
<type name="process_info_item"/>
<type name="process_info_result_item"/>
<type name="stack_item"/>
<type name="priority_level"/>
- <fsummary>Information about a process</fsummary>
<desc>
- <p>Returns information about the process identified by <c><anno>Pid</anno></c>
- as specified by the <c><anno>Item</anno></c> or the <c><anno>ItemList</anno></c>, or <c>undefined</c> if the
- process is not alive.
- </p>
- <p>If the process is alive and a single <c><anno>Item</anno></c> is given,
- the returned value is the corresponding
- <c><anno>InfoTuple</anno></c> unless <c>Item =:= registered_name</c>
- and the process has no registered name. In this case
- <c>[]</c> is returned. This strange behavior is due to
- historical reasons, and is kept for backward compatibility.
- </p>
- <p>If an <c>ItemList</c> is given, the result is an
- <c><anno>InfoTupleList</anno></c>. The <c><anno>InfoTuple</anno></c>s in the
- <c><anno>InfoTupleList</anno></c> will appear with the corresponding
- <c><anno>Item</anno></c>s in the same order as the <c><anno>Item</anno></c>s appeared
- in the <c><anno>ItemList</anno></c>. Valid <c><anno>Item</anno></c>s may appear multiple
- times in the <c><anno>ItemList</anno></c>.
- </p>
- <note><p>If <c>registered_name</c> is part of an <c><anno>ItemList</anno></c>
+ <p>Returns information about the process identified by
+ <c><anno>Pid</anno></c>, as specified by
+ <c><anno>Item</anno></c> or <c><anno>ItemList</anno></c>.
+ Returns <c>undefined</c> if the process is not alive.</p>
+ <p>If the process is alive and a single <c><anno>Item</anno></c>
+ is given, the returned value is the corresponding
+ <c><anno>InfoTuple</anno></c>, unless <c>Item =:= registered_name</c>
+ and the process has no registered name. In this case,
+ <c>[]</c> is returned. This strange behavior is because of
+ historical reasons, and is kept for backward compatibility.</p>
+ <p>If <c><anno>ItemList</anno></c> is given, the result is
+ <c><anno>InfoTupleList</anno></c>.
+ The <c><anno>InfoTuple</anno></c>s in
+ <c><anno>InfoTupleList</anno></c> appear with the corresponding
+ <c><anno>Item</anno></c>s in the same order as the
+ <c><anno>Item</anno></c>s appeared
+ in <c><anno>ItemList</anno></c>. Valid <c><anno>Item</anno></c>s can
+ appear multiple times in <c><anno>ItemList</anno></c>.</p>
+ <note><p>If <c>registered_name</c> is part of <c><anno>ItemList</anno></c>
and the process has no name registered a
- <c>{registered_name, []}</c> <c><anno>InfoTuple</anno></c> <em>will</em>
- appear in the resulting <c><anno>InfoTupleList</anno></c>. This
- behavior is different than when a single
- <c>Item =:= registered_name</c> is given, and than when
- <c>process_info/1</c> is used.
- </p></note>
- <p>Currently the following <c><anno>InfoTuple</anno></c>s with corresponding
+ <c>{registered_name, []}</c>, <c><anno>InfoTuple</anno></c>
+ <em>will</em> appear in the resulting
+ <c><anno>InfoTupleList</anno></c>. This
+ behavior is different when a single
+ <c>Item =:= registered_name</c> is given, and when
+ <c>process_info/1</c> is used.</p>
+ </note>
+ <p>The following <c><anno>InfoTuple</anno></c>s with corresponding
<c><anno>Item</anno></c>s are valid:</p>
<taglist>
<tag><c>{backtrace, <anno>Bin</anno>}</c></tag>
<item>
- <p>The binary <c><anno>Bin</anno></c> contains the same information as
- the output from
+ <p>Binary <c><anno>Bin</anno></c> contains the same information
+ as the output from
<c>erlang:process_display(<anno>Pid</anno>, backtrace)</c>. Use
<c>binary_to_list/1</c> to obtain the string of characters
from the binary.</p>
</item>
<tag><c>{binary, <anno>BinInfo</anno>}</c></tag>
<item>
- <p><c><anno>BinInfo</anno></c> is a list containing miscellaneous information
- about binaries currently being referred to by this process.
- This <c><anno>InfoTuple</anno></c> may be changed or removed without prior
- notice.</p>
+ <p><c><anno>BinInfo</anno></c> is a list containing miscellaneous
+ information about binaries currently being referred to by this
+ process. This <c><anno>InfoTuple</anno></c> can be changed or
+ removed without prior notice.</p>
</item>
<tag><c>{catchlevel, <anno>CatchLevel</anno>}</c></tag>
<item>
<p><c><anno>CatchLevel</anno></c> is the number of currently active
- catches in this process. This <c><anno>InfoTuple</anno></c> may be
+ catches in this process. This <c><anno>InfoTuple</anno></c> can be
changed or removed without prior notice.</p>
</item>
- <tag><c>{current_function, {<anno>Module</anno>, <anno>Function</anno>, <anno>Arity</anno>}}</c></tag>
+ <tag><c>{current_function, {<anno>Module</anno>,
+ <anno>Function</anno>, Arity}}</c></tag>
<item>
- <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>, <c><anno>Arity</anno></c> is
+ <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>,
+ <c><anno>Arity</anno></c> is
the current function call of the process.</p>
</item>
- <tag><c>{current_location, {<anno>Module</anno>, <anno>Function</anno>, <anno>Arity</anno>, <anno>Location</anno>}}</c></tag>
+ <tag><c>{current_location, {<anno>Module</anno>,
+ <anno>Function</anno>, <anno>Arity</anno>,
+ <anno>Location</anno>}}</c></tag>
<item>
- <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>, <c><anno>Arity</anno></c> is
+ <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>,
+ <c><anno>Arity</anno></c> is
the current function call of the process.
- <c><anno>Location</anno></c> is a list of two-tuples that describes the
- location in the source code.
- </p>
+ <c><anno>Location</anno></c> is a list of two-tuples describing the
+ location in the source code.</p>
</item>
<tag><c>{current_stacktrace, <anno>Stack</anno>}</c></tag>
<item>
- <p>Return the current call stack back-trace (<em>stacktrace</em>)
+ <p>Returns the current call stack back-trace (<em>stacktrace</em>)
of the process. The stack has the same format as returned by
- <seealso marker="#get_stacktrace/0">erlang:get_stacktrace/0</seealso>.
- </p>
+ <seealso marker="#get_stacktrace/0">erlang:get_stacktrace/0</seealso>.</p>
</item>
<tag><c>{dictionary, <anno>Dictionary</anno>}</c></tag>
<item>
- <p><c><anno>Dictionary</anno></c> is the dictionary of the process.</p>
+ <p><c><anno>Dictionary</anno></c> is the process dictionary.</p>
</item>
<tag><c>{error_handler, <anno>Module</anno>}</c></tag>
<item>
@@ -4020,34 +4580,36 @@ os_prompt% </pre>
</item>
<tag><c>{garbage_collection, <anno>GCInfo</anno>}</c></tag>
<item>
- <p><c><anno>GCInfo</anno></c> is a list which contains miscellaneous
+ <p><c><anno>GCInfo</anno></c> is a list containing miscellaneous
information about garbage collection for this process.
- The content of <c><anno>GCInfo</anno></c> may be changed without
+ The content of <c><anno>GCInfo</anno></c> can be changed without
prior notice.</p>
</item>
<tag><c>{group_leader, <anno>GroupLeader</anno>}</c></tag>
<item>
- <p><c><anno>GroupLeader</anno></c> is group leader for the IO of
+ <p><c><anno>GroupLeader</anno></c> is group leader for the I/O of
the process.</p>
</item>
<tag><c>{heap_size, <anno>Size</anno>}</c></tag>
<item>
- <p><c><anno>Size</anno></c> is the size in words of youngest heap generation
- of the process. This generation currently include the stack
- of the process. This information is highly implementation
- dependent, and may change if the implementation change.
- </p>
+ <p><c><anno>Size</anno></c> is the size in words of the youngest heap
+ generation of the process. This generation includes
+ the process stack. This information is highly
+ implementation-dependent, and can change if the
+ implementation changes.</p>
</item>
- <tag><c>{initial_call, {Module, Function, Arity}}</c></tag>
+ <tag><c>{initial_call, {<anno>Module</anno>, <anno>Function</anno>,
+ <anno>Arity</anno>}}</c></tag>
<item>
- <p><c>Module</c>, <c>Function</c>, <c>Arity</c> is
+ <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>,
+ <c><anno>Arity</anno></c> is
the initial function call with which the process was
spawned.</p>
</item>
<tag><c>{links, <anno>PidsAndPorts</anno>}</c></tag>
<item>
- <p><c><anno>PidsAndPorts</anno></c> is a list of pids and
- port identifiers, with processes or ports to which the process
+ <p><c><anno>PidsAndPorts</anno></c> is a list of process identifiers
+ and port identifiers, with processes or ports to which the process
has a link.</p>
</item>
<tag><c>{last_calls, false|Calls}</c></tag>
@@ -4061,14 +4623,14 @@ os_prompt% </pre>
<tag><c>{memory, <anno>Size</anno>}</c></tag>
<item>
<p><c><anno>Size</anno></c> is the size in bytes of the process. This
- includes call stack, heap and internal structures.</p>
+ includes call stack, heap, and internal structures.</p>
</item>
<tag><c>{message_queue_len, <anno>MessageQueueLen</anno>}</c></tag>
<item>
<p><c><anno>MessageQueueLen</anno></c> is the number of messages
currently in the message queue of the process. This is
the length of the list <c><anno>MessageQueue</anno></c> returned as
- the info item <c>messages</c> (see below).</p>
+ the information item <c>messages</c> (see the following).</p>
</item>
<tag><c>{messages, <anno>MessageQueue</anno>}</c></tag>
<item>
@@ -4077,31 +4639,35 @@ os_prompt% </pre>
</item>
<tag><c>{min_heap_size, <anno>MinHeapSize</anno>}</c></tag>
<item>
- <p><c><anno>MinHeapSize</anno></c> is the minimum heap size for the process.</p>
+ <p><c><anno>MinHeapSize</anno></c> is the minimum heap size
+ for the process.</p>
</item>
<tag><c>{min_bin_vheap_size, <anno>MinBinVHeapSize</anno>}</c></tag>
<item>
- <p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual heap size for the process.</p>
+ <p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual
+ heap size for the process.</p>
</item>
<tag><c>{monitored_by, <anno>Pids</anno>}</c></tag>
<item>
- <p>A list of pids that are monitoring the process (with
+ <p>A list of process identifiers monitoring the process (with
<c>monitor/2</c>).</p>
</item>
<tag><c>{monitors, <anno>Monitors</anno>}</c></tag>
<item>
<p>A list of monitors (started by <c>monitor/2</c>)
that are active for the process. For a local process
- monitor or a remote process monitor by pid, the list item
- is <c>{process, <anno>Pid</anno>}</c>, and for a remote process
+ monitor or a remote process monitor by a process
+ identifier, the list item is <c>{process, <anno>Pid</anno>}</c>.
+ For a remote process
monitor by name, the list item is
<c>{process, {<anno>RegName</anno>, <anno>Node</anno>}}</c>.</p>
</item>
- <tag><c>{priority, Level}</c></tag>
+ <tag><c>{priority, <anno>Level</anno>}</c></tag>
<item>
<p><c><anno>Level</anno></c> is the current priority level for
- the process. For more information on priorities see
- <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso>.</p>
+ the process. For more information on priorities, see
+ <seealso marker="#process_flag_priority">process_flag(priority,
+ Level)</seealso>.</p>
</item>
<tag><c>{reductions, <anno>Number</anno>}</c></tag>
<item>
@@ -4116,240 +4682,346 @@ os_prompt% </pre>
</item>
<tag><c>{sequential_trace_token, [] | <anno>SequentialTraceToken</anno>}</c></tag>
<item>
- <p><c><anno>SequentialTraceToken</anno></c> the sequential trace token for
- the process. This <c><anno>InfoTuple</anno></c> may be changed or removed
- without prior notice.</p>
+ <p><c><anno>SequentialTraceToken</anno></c> is the sequential trace
+ token for the process. This <c><anno>InfoTuple</anno></c> can be
+ changed or removed without prior notice.</p>
</item>
<tag><c>{stack_size, <anno>Size</anno>}</c></tag>
<item>
- <p><c><anno>Size</anno></c> is the stack size of the process in words.</p>
+ <p><c><anno>Size</anno></c> is the stack size, in words,
+ of the process.</p>
</item>
<tag><c>{status, <anno>Status</anno>}</c></tag>
<item>
- <p><c><anno>Status</anno></c> is the status of the process. <c><anno>Status</anno></c>
- is <c>exiting</c>, <c>garbage_collecting</c>,
- <c>waiting</c> (for a message), <c>running</c>,
- <c>runnable</c> (ready to run, but another process is
- running), or <c>suspended</c> (suspended on a "busy" port
- or by the <c>erlang:suspend_process/[1,2]</c> BIF).</p>
+ <p><c><anno>Status</anno></c> is the status of the process and is one
+ of the following:</p>
+ <list type="bulleted">
+ <item><c>exiting</c></item>
+ <item><c>garbage_collecting</c></item>
+ <item><c>waiting</c> (for a message)</item>
+ <item><c>running</c></item>
+ <item><c>runnable</c> (ready to run, but another process is
+ running)</item>
+ <item><c>suspended</c> (suspended on a "busy" port
+ or by the BIF <c>erlang:suspend_process/[1,2]</c>)</item>
+ </list>
</item>
<tag><c>{suspending, <anno>SuspendeeList</anno>}</c></tag>
<item>
- <p><c><anno>SuspendeeList</anno></c> is a list of <c>{<anno>Suspendee</anno>,
- <anno>ActiveSuspendCount</anno>, <anno>OutstandingSuspendCount</anno>}</c> tuples.
- <c><anno>Suspendee</anno></c> is the pid of a process that have been or is to
- be suspended by the process identified by <c><anno>Pid</anno></c> via the
- <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
- BIF, or the
- <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
- BIF. <c><anno>ActiveSuspendCount</anno></c> is the number of times the
- <c><anno>Suspendee</anno></c> has been suspended by <c><anno>Pid</anno></c>.
+ <p><c><anno>SuspendeeList</anno></c> is a list of
+ <c>{<anno>Suspendee</anno>, <anno>ActiveSuspendCount</anno>,
+ <anno>OutstandingSuspendCount</anno>}</c> tuples.
+ <c><anno>Suspendee</anno></c> is the process identifier of a
+ process that has been, or is to be,
+ suspended by the process identified by <c><anno>Pid</anno></c>
+ through one of the following BIFs:</p>
+ <list type="bulleted">
+ <item>
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
+ </item>
+ <item>
+ <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
+ </item>
+ </list>
+ <p><c><anno>ActiveSuspendCount</anno></c> is the number of
+ times <c><anno>Suspendee</anno></c> has been suspended by
+ <c><anno>Pid</anno></c>.
<c><anno>OutstandingSuspendCount</anno></c> is the number of not yet
- completed suspend requests sent by <c><anno>Pid</anno></c>. That is,
- if <c><anno>ActiveSuspendCount</anno> =/= 0</c>, <c><anno>Suspendee</anno></c> is
- currently in the suspended state, and if
- <c><anno>OutstandingSuspendCount</anno> =/= 0</c> the <c>asynchronous</c>
- option of <c>erlang:suspend_process/2</c> has been used and
- the suspendee has not yet been suspended by <c><anno>Pid</anno></c>.
- Note that the <c><anno>ActiveSuspendCount</anno></c> and
- <c><anno>OutstandingSuspendCount</anno></c> are not the total suspend count
- on <c><anno>Suspendee</anno></c>, only the parts contributed by <c>Pid</c>.
- </p>
+ completed suspend requests sent by <c><anno>Pid</anno></c>, that is:</p>
+ <list type="bulleted">
+ <item>If <c><anno>ActiveSuspendCount</anno> =/= 0</c>,
+ <c><anno>Suspendee</anno></c> is
+ currently in the suspended state.
+ </item>
+ <item>If <c><anno>OutstandingSuspendCount</anno> =/= 0</c>, option
+ <c>asynchronous</c> of <c>erlang:suspend_process/2</c>
+ has been used and the suspendee has not yet been
+ suspended by <c><anno>Pid</anno></c>.
+ </item>
+ </list>
+ <p>Notice that <c><anno>ActiveSuspendCount</anno></c> and
+ <c><anno>OutstandingSuspendCount</anno></c> are not the
+ total suspend count on <c><anno>Suspendee</anno></c>,
+ only the parts contributed by <c><anno>Pid</anno></c>.</p>
</item>
<tag><c>{total_heap_size, <anno>Size</anno>}</c></tag>
<item>
- <p><c><anno>Size</anno></c> is the total size in words of all heap
- fragments of the process. This currently include the stack
- of the process.
- </p>
+ <p><c><anno>Size</anno></c> is the total size, in words, of all heap
+ fragments of the process. This includes the process stack.</p>
</item>
<tag><c>{trace, <anno>InternalTraceFlags</anno>}</c></tag>
<item>
- <p><c><anno>InternalTraceFlags</anno></c> is an integer representing
- internal trace flag for this process. This <c><anno>InfoTuple</anno></c>
- may be changed or removed without prior notice.</p>
+ <p><c><anno>InternalTraceFlags</anno></c> is an integer
+ representing the internal trace flag for this process.
+ This <c><anno>InfoTuple</anno></c>
+ can be changed or removed without prior notice.</p>
</item>
<tag><c>{trap_exit, <anno>Boolean</anno>}</c></tag>
<item>
- <p><c><anno>Boolean</anno></c> is <c>true</c> if the process is trapping
- exits, otherwise it is <c>false</c>.</p>
+ <p><c><anno>Boolean</anno></c> is <c>true</c> if the process
+ is trapping exits, otherwise <c>false</c>.</p>
</item>
</taglist>
- <p>Note however, that not all implementations support every one
- of the above <c><anno>Item</anno></c>s.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c> is not a local process,
- or if <c><anno>Item</anno></c> is not a valid <c><anno>Item</anno></c>.</p>
+ <p>Notice that not all implementations support all
+ these <c><anno>Item</anno></c>s.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>Pid</anno></c> is not a local process.</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>Item</anno></c> is an invalid item.</item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="processes" arity="0"/>
- <fsummary>All processes</fsummary>
+ <fsummary>All processes.</fsummary>
<desc>
<p>Returns a list of process identifiers corresponding to
- all the processes currently existing on the local node.
- </p>
- <p>Note that a process that is exiting, exists but is not alive, i.e.,
- <c>is_process_alive/1</c> will return <c>false</c> for a process
- that is exiting, but its process identifier will be part
- of the result returned from <c>processes/0</c>.
- </p>
+ all the processes currently existing on the local node.</p>
+ <p>Notice that an exiting process exists, but is not alive.
+ That is, <c>is_process_alive/1</c> returns <c>false</c>
+ for an exiting process, but its process identifier is part
+ of the result returned from <c>processes/0</c>.</p>
+ <p>Example:</p>
<pre>
> <input>processes().</input>
[&lt;0.0.0&gt;,&lt;0.2.0&gt;,&lt;0.4.0&gt;,&lt;0.5.0&gt;,&lt;0.7.0&gt;,&lt;0.8.0&gt;]</pre>
</desc>
</func>
+
<func>
<name name="purge_module" arity="1"/>
- <fsummary>Remove old code for a module</fsummary>
+ <fsummary>Removes old code for a module.</fsummary>
<desc>
- <p>Removes old code for <c><anno>Module</anno></c>. Before this BIF is used,
- <c>erlang:check_process_code/2</c> should be called to check
- that no processes are executing old code in the module.</p>
+ <p>Removes old code for <c><anno>Module</anno></c>.
+ Before this BIF is used,
+ <c>erlang:check_process_code/2</c> is to be called to check
+ that no processes execute old code in the module.</p>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
- used elsewhere.</p>
+ <seealso marker="kernel:code">code(3)</seealso>)
+ and is not to be used elsewhere.</p>
</warning>
<p>Failure: <c>badarg</c> if there is no old code for
<c><anno>Module</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="put" arity="2"/>
- <fsummary>Add a new value to the process dictionary</fsummary>
- <desc>
- <p>Adds a new <c><anno>Key</anno></c> to the process dictionary, associated
- with the value <c><anno>Val</anno></c>, and returns <c>undefined</c>. If
- <c><anno>Key</anno></c> already exists, the old value is deleted and
- replaced by <c><anno>Val</anno></c> and the function returns the old value.</p>
- <note>
- <p>The values stored when <c>put</c> is evaluated within
- the scope of a <c>catch</c> will not be retracted if a
- <c>throw</c> is evaluated, or if an error occurs.</p>
- </note>
+ <fsummary>Adds a new value to the process dictionary.</fsummary>
+ <desc>
+ <p>Adds a new <c><anno>Key</anno></c> to the process dictionary,
+ associated with the value <c><anno>Val</anno></c>, and returns
+ <c>undefined</c>. If <c><anno>Key</anno></c> exists, the old
+ value is deleted and replaced by <c><anno>Val</anno></c>, and
+ the function returns the old value.</p>
+ <p>Example:</p>
<pre>
> <input>X = put(name, walrus), Y = put(name, carpenter),</input>
<input>Z = get(name),</input>
<input>{X, Y, Z}.</input>
{undefined,walrus,carpenter}</pre>
+ <note>
+ <p>The values stored when <c>put</c> is evaluated within
+ the scope of a <c>catch</c> are not retracted if a
+ <c>throw</c> is evaluated, or if an error occurs.</p>
+ </note>
</desc>
</func>
+
<func>
<name name="raise" arity="3"/>
+ <fsummary>Stops execution with an exception of given class, reason, and call stack backtrace.</fsummary>
<type name="raise_stacktrace"/>
- <fsummary>Stop execution with an exception of given class, reason and call stack backtrace</fsummary>
<desc>
<p>Stops the execution of the calling process with an
- exception of given class, reason and call stack backtrace
+ exception of given class, reason, and call stack backtrace
(<em>stacktrace</em>).</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. In general, it should
- be avoided in applications, unless you know
- very well what you are doing.</p>
+ <p>This BIF is intended for debugging. Avoid to use it in applications,
+ unless you really know what you are doing.</p>
</warning>
- <p><c><anno>Class</anno></c> is one of <c>error</c>, <c>exit</c> or
- <c>throw</c>, so if it were not for the stacktrace
- <c>erlang:raise(<anno>Class</anno>, <anno>Reason</anno>, <anno>Stacktrace</anno>)</c> is
- equivalent to <c>erlang:<anno>Class</anno>(<anno>Reason</anno>)</c>.
- <c><anno>Reason</anno></c> is any term and <c><anno>Stacktrace</anno></c> is a list as
- returned from <c>get_stacktrace()</c>, that is a list of
- 4-tuples <c>{Module, Function, Arity | Args,
- Location}</c> where <c>Module</c> and <c>Function</c>
- are atoms and the third element is an integer arity or an
- argument list. The stacktrace may also contain <c>{Fun,
- Args, Location}</c> tuples where
- <c>Fun</c> is a local fun and <c>Args</c> is an argument list.</p>
- <p>The <c>Location</c> element at the end is optional.
+ <p><c><anno>Class</anno></c> is <c>error</c>, <c>exit</c>, or
+ <c>throw</c>. So, if it were not for the stacktrace,
+ <c>erlang:raise(<anno>Class</anno>, <anno>Reason</anno>,
+ <anno>Stacktrace</anno>)</c> is
+ equivalent to <c>erlang:<anno>Class</anno>(<anno>Reason</anno>)</c>.</p>
+ <p><c><anno>Reason</anno></c> is any term.
+ <c><anno>Stacktrace</anno></c> is a list as
+ returned from <c>get_stacktrace()</c>, that is, a list of
+ four-tuples <c>{Module, Function, Arity | Args,
+ Location}</c>, where <c>Module</c> and <c>Function</c>
+ are atoms, and the third element is an integer arity or an
+ argument list. The stacktrace can also contain <c>{Fun,
+ Args, Location}</c> tuples, where <c>Fun</c> is a local
+ fun and <c>Args</c> is an argument list.</p>
+ <p>Element <c>Location</c> at the end is optional.
Omitting it is equivalent to specifying an empty list.</p>
<p>The stacktrace is used as the exception stacktrace for the
- calling process; it will be truncated to the current
+ calling process; it is truncated to the current
maximum stacktrace depth.</p>
- <p>Because evaluating this function causes the process to
- terminate, it has no return value - unless the arguments are
- invalid, in which case the function <em>returns the error reason</em>, that is <c>badarg</c>. If you want to be
- really sure not to return you can call
- <c>error(erlang:raise(<anno>Class</anno>, <anno>Reason</anno>, <anno>Stacktrace</anno>))</c>
+ <p>Since evaluating this function causes the process to
+ terminate, it has no return value unless the arguments are
+ invalid, in which case the function <em>returns the error
+ reason</em> <c>badarg</c>. If you want to be
+ sure not to return, you can call
+ <c>error(erlang:raise(<anno>Class</anno>, <anno>Reason</anno>,
+ <anno>Stacktrace</anno>))</c>
and hope to distinguish exceptions later.</p>
</desc>
</func>
+
<func>
- <name name="read_timer" arity="1"/>
- <fsummary>Number of milliseconds remaining for a timer</fsummary>
- <desc>
- <p><c><anno>TimerRef</anno></c> is a timer reference returned by
- <seealso marker="#send_after/3">erlang:send_after/3</seealso>
- or
- <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>.
- If the timer is active, the function returns the time in
- milliseconds left until the timer will expire, otherwise
- <c>false</c> (which means that <c><anno>TimerRef</anno></c> was never a
- timer, that it has been cancelled, or that it has already
- delivered its message).</p>
+ <name name="read_timer" arity="2"/>
+ <fsummary>Reads the state of a timer.</fsummary>
+ <desc>
+ <p>
+ Read the state of a timer that has been created by either
+ <seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>,
+ or <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>.
+ <c><anno>TimerRef</anno></c> identifies the timer, and
+ was returned by the BIF that created the timer.
+ </p>
+ <p>Available <c><anno>Option</anno>s</c>:</p>
+ <taglist>
+ <tag><c>{async, Async}</c></tag>
+ <item>
+ <p>
+ Asynchronous request for state information. <c>Async</c>
+ defaults to <c>false</c> which will cause the operation
+ to be performed synchronously. In this case, the <c>Result</c>
+ is returned by <c>erlang:read_timer()</c>. When
+ <c>Async</c> is <c>true</c>, <c>erlang:read_timer()</c>
+ sends an asynchronous request for the state information
+ to the timer service that manages the timer, and then returns
+ <c>ok</c>. A message on the format <c>{read_timer,
+ <anno>TimerRef</anno>, <anno>Result</anno>}</c> is
+ sent to the caller of <c>erlang:read_timer()</c> when the
+ operation has been processed.
+ </p>
+ </item>
+ </taglist>
+ <p>
+ More <c><anno>Option</anno></c>s may be added in the future.
+ </p>
+ <p>
+ If <c><anno>Result</anno></c> is an integer, it represents the
+ time in milli-seconds left until the timer expires.</p>
+ <p>
+ If <c><anno>Result</anno></c> is <c>false</c>, a
+ timer corresponding to <c><anno>TimerRef</anno></c> could not
+ be found. This can be because the timer had expired,
+ it had been canceled, or because <c><anno>TimerRef</anno></c>
+ never has corresponded to a timer. Even if the timer has expired,
+ it does not tell you whether or not the timeout message has
+ arrived at its destination yet.
+ </p>
+ <note>
+ <p>
+ The timer service that manages the timer may be co-located
+ with another scheduler than the scheduler that the calling
+ process is executing on. If this is the case, communication
+ with the timer service takes much longer time than if it
+ is located locally. If the calling process is in critical
+ path, and can do other things while waiting for the result
+ of this operation, you want to use option <c>{async, true}</c>.
+ If using option <c>{async, false}</c>, the calling
+ process will be blocked until the operation has been
+ performed.
+ </p>
+ </note>
<p>See also
- <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#send_after/4"><c>erlang:send_after/4</c></seealso>,
+ <seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>,
and
- <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>.</p>
+ <seealso marker="#cancel_timer/2"><c>erlang:cancel_timer/2</c></seealso>.</p>
</desc>
</func>
<func>
+ <name name="read_timer" arity="1"/>
+ <fsummary>Reads the state of a timer.</fsummary>
+ <desc>
+ <p>Read the state of a timer. The same as calling
+ <seealso marker="#read_timer/2"><c>erlang:read_timer(TimerRef,
+ [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="ref_to_list" arity="1"/>
- <fsummary>Text representation of a reference</fsummary>
+ <fsummary>Text representation of a reference.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of <c><anno>Ref</anno></c>.</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
</warning>
</desc>
</func>
+
<func>
<name name="register" arity="2"/>
- <fsummary>Register a name for a pid (or port)</fsummary>
+ <fsummary>Registers a name for a pid (or port).</fsummary>
<desc>
- <p>Associates the name <c><anno>RegName</anno></c> with a pid or a port
- identifier. <c><anno>RegName</anno></c>, which must be an atom, can be used
- instead of the pid / port identifier in the send operator
+ <p>Associates the name <c><anno>RegName</anno></c> with a process
+ identifier (pid) or a port identifier.
+ <c><anno>RegName</anno></c>, which must be an atom, can be used
+ instead of the pid or port identifier in send operator
(<c><anno>RegName</anno> ! Message</c>).</p>
+ <p>Example:</p>
<pre>
> <input>register(db, Pid).</input>
true</pre>
- <p>Failure: <c>badarg</c> if <c><anno>PidOrPort</anno></c> is not an existing,
- local process or port, if <c><anno>RegName</anno></c> is already in use,
- if the process or port is already registered (already has a
- name), or if <c><anno>RegName</anno></c> is the atom <c>undefined</c>.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>PidOrPort</anno></c> is not an existing local
+ process or port.</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>RegName</anno></c> is already in use.</item>
+ <tag><c>badarg</c></tag>
+ <item>If the process or port is already registered
+ (already has a name).</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>RegName</anno></c> is the atom
+ <c>undefined</c>.</item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="registered" arity="0"/>
- <fsummary>All registered names</fsummary>
+ <fsummary>All registered names.</fsummary>
<desc>
- <p>Returns a list of names which have been registered using
- <seealso marker="#register/2">register/2</seealso>.</p>
+ <p>Returns a list of names that have been registered using
+ <seealso marker="#register/2">register/2</seealso>, for
+ example:</p>
<pre>
> <input>registered().</input>
[code_server, file_server, init, user, my_db]</pre>
</desc>
</func>
+
<func>
<name name="resume_process" arity="1"/>
- <fsummary>Resume a suspended process</fsummary>
+ <fsummary>Resumes a suspended process.</fsummary>
<desc>
<p>Decreases the suspend count on the process identified by
- <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c> should previously have been
- suspended via
- <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>,
+ <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c>
+ is previously to have been suspended through
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
or
<seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
- by the process calling <c>erlang:resume_process(<anno>Suspendee</anno>)</c>. When
- the suspend count on <c><anno>Suspendee</anno></c> reach zero, <c><anno>Suspendee</anno></c>
- will be resumed, i.e., the state of the <c>Suspendee</c> is changed
- from suspended into the state <c><anno>Suspendee</anno></c> was in before it was
- suspended.
- </p>
+ by the process calling
+ <c>erlang:resume_process(<anno>Suspendee</anno>)</c>. When the
+ suspend count on <c><anno>Suspendee</anno></c> reaches zero,
+ <c><anno>Suspendee</anno></c> is resumed, that is, its state
+ is changed from suspended into the state it had before it was
+ suspended.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
@@ -4357,7 +5029,7 @@ true</pre>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Suspendee</anno></c> isn't a process identifier.
+ If <c><anno>Suspendee</anno></c> is not a process identifier.
</item>
<tag><c>badarg</c></tag>
<item>
@@ -4367,58 +5039,65 @@ true</pre>
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> is not alive.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ is not alive.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="round" arity="1"/>
- <fsummary>Return an integer by rounding a number</fsummary>
+ <fsummary>Returns an integer by rounding a number.</fsummary>
<desc>
- <p>Returns an integer by rounding <c><anno>Number</anno></c>.</p>
+ <p>Returns an integer by rounding <c><anno>Number</anno></c>,
+ for example:</p>
<pre>
-> <input>round(5.5).</input>
+<input>round(5.5).</input>
6</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="self" arity="0"/>
- <fsummary>Pid of the calling process</fsummary>
+ <fsummary>Returns pid of the calling process.</fsummary>
<desc>
- <p>Returns the pid (process identifier) of the calling process.</p>
+ <p>Returns the process identifier of the calling process, for
+ example:</p>
<pre>
> <input>self().</input>
&lt;0.26.0></pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="send" arity="2"/>
- <fsummary>Send a message</fsummary>
+ <fsummary>Sends a message.</fsummary>
<type name="dst"/>
<desc>
- <p>Sends a message and returns <c><anno>Msg</anno></c>. This is the same as
- <c><anno>Dest</anno> ! <anno>Msg</anno></c>.</p>
- <p><c><anno>Dest</anno></c> may be a remote or local pid, a (local) port, a
- locally registered name, or a tuple <c>{<anno>RegName</anno>, <anno>Node</anno>}</c>
+ <p>Sends a message and returns <c><anno>Msg</anno></c>. This
+ is the same as <c><anno>Dest</anno> ! <anno>Msg</anno></c>.</p>
+ <p><c><anno>Dest</anno></c> can be a remote or local process identifier,
+ a (local) port, a locally registered name, or a tuple
+ <c>{<anno>RegName</anno>, <anno>Node</anno>}</c>
for a registered name at another node.</p>
</desc>
</func>
+
<func>
<name name="send" arity="3"/>
+ <fsummary>Sends a message conditionally.</fsummary>
<type name="dst"/>
- <fsummary>Send a message conditionally</fsummary>
- <desc>
- <p>Sends a message and returns <c>ok</c>, or does not send
- the message but returns something else (see below). Otherwise
- the same as
- <seealso marker="#send/2">erlang:send/2</seealso>. See
- also
- <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
- for more detailed explanation and warnings.</p>
- <p>The possible options are:</p>
+ <desc>
+ <p>Either sends a message and returns <c>ok</c>, or does not send
+ the message but returns something else (see the following).
+ Otherwise the same as
+ <seealso marker="#send/2">erlang:send/2</seealso>.
+ For more detailed explanation and warnings, see
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.</p>
+ <p>The options are as follows:</p>
<taglist>
<tag><c>nosuspend</c></tag>
<item>
@@ -4428,319 +5107,366 @@ true</pre>
<tag><c>noconnect</c></tag>
<item>
<p>If the destination node would have to be auto-connected
- before doing the send, <c>noconnect</c> is returned
+ to do the send, <c>noconnect</c> is returned
instead.</p>
</item>
</taglist>
<warning>
- <p>As with <c>erlang:send_nosuspend/2,3</c>: Use with extreme
- care!</p>
+ <p>As with <c>erlang:send_nosuspend/2,3</c>: use with extreme
+ care.</p>
</warning>
</desc>
</func>
+
<func>
- <name name="send_after" arity="3"/>
- <type_desc variable="Time">0 &lt;= Time &lt;= 4294967295</type_desc>
+ <name name="send_after" arity="4"/>
<fsummary>Start a timer</fsummary>
<desc>
- <p>Starts a timer which will send the message <c>Msg</c>
- to <c><anno>Dest</anno></c> after <c><anno>Time</anno></c> milliseconds.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be greater than 4294967295.</p>
- <p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
- a registered process. The process referred to by the name is
- looked up at the time of delivery. No error is given if
- the name does not refer to a process.</p>
-
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will be automatically
- canceled if the process referred to by the <c>pid()</c> is not alive,
- or when the process exits. This feature was introduced in
- erts version 5.4.11. Note that timers will not be
- automatically canceled when <c><anno>Dest</anno></c> is an <c>atom</c>.</p>
- <p>See also
- <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
- <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>,
- and
- <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
- <p>Failure: <c>badarg</c> if the arguments does not satisfy
- the requirements specified above.</p>
+ <p>
+ Starts a timer. When the timer expires, the message
+ <c><anno>Msg</anno></c> is sent to the process
+ identified by <c><anno>Dest</anno></c>. Apart from
+ the format of the timeout message,
+ <c>erlang:send_after/4</c> works exactly as
+ <seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>.</p>
</desc>
</func>
<func>
+ <name name="send_after" arity="3"/>
+ <fsummary>Starts a timer.</fsummary>
+ <desc>
+ <p>Starts a timer. The same as calling
+ <seealso marker="#send_after/4"><c>erlang:send_after(<anno>Time</anno>,
+ <anno>Dest</anno>, <anno>Msg</anno>, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="send_nosuspend" arity="2"/>
- <fsummary>Try to send a message without ever blocking</fsummary>
+ <fsummary>Tries to send a message without ever blocking.</fsummary>
<type name="dst"/>
<desc>
<p>The same as
- <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [nosuspend])</seealso>, but returns <c>true</c> if
+ <seealso marker="#send/3">erlang:send(<anno>Dest</anno>,
+ <anno>Msg</anno>, [nosuspend])</seealso>,
+ but returns <c>true</c> if
the message was sent and <c>false</c> if the message was not
sent because the sender would have had to be suspended.</p>
- <p>This function is intended for send operations towards an
+ <p>This function is intended for send operations to an
unreliable remote node without ever blocking the sending
(Erlang) process. If the connection to the remote node
(usually not a real Erlang node, but a node written in C or
- Java) is overloaded, this function <em>will not send the message</em> but return <c>false</c> instead.</p>
- <p>The same happens, if <c><anno>Dest</anno></c> refers to a local port that
- is busy. For all other destinations (allowed for the ordinary
- send operator <c>'!'</c>) this function sends the message and
+ Java) is overloaded, this function <em>does not send the message</em>
+ and returns <c>false</c>.</p>
+ <p>The same occurs if <c><anno>Dest</anno></c> refers to a local port
+ that is busy. For all other destinations (allowed for the ordinary
+ send operator <c>'!'</c>), this function sends the message and
returns <c>true</c>.</p>
- <p>This function is only to be used in very rare circumstances
+ <p>This function is only to be used in rare circumstances
where a process communicates with Erlang nodes that can
- disappear without any trace causing the TCP buffers and
- the drivers queue to be over-full before the node will actually
- be shut down (due to tick timeouts) by <c>net_kernel</c>. The
- normal reaction to take when this happens is some kind of
+ disappear without any trace, causing the TCP buffers and
+ the drivers queue to be over-full before the node is
+ shut down (because of tick time-outs) by <c>net_kernel</c>.
+ The normal reaction to take when this occurs is some kind of
premature shutdown of the other node.</p>
- <p>Note that ignoring the return value from this function would
- result in <em>unreliable</em> message passing, which is
+ <p>Notice that ignoring the return value from this function would
+ result in an <em>unreliable</em> message passing, which is
contradictory to the Erlang programming model. The message is
<em>not</em> sent if this function returns <c>false</c>.</p>
- <p>Note also that in many systems, transient states of
+ <p>In many systems, transient states of
overloaded queues are normal. The fact that this function
- returns <c>false</c> does not in any way mean that the other
+ returns <c>false</c> does not mean that the other
node is guaranteed to be non-responsive, it could be a
- temporary overload. Also a return value of <c>true</c> does
- only mean that the message could be sent on the (TCP) channel
- without blocking, the message is not guaranteed to have
- arrived at the remote node. Also in the case of a disconnected
+ temporary overload. Also, a return value of <c>true</c> does
+ only mean that the message can be sent on the (TCP) channel
+ without blocking, the message is not guaranteed to
+ arrive at the remote node. For a disconnected
non-responsive node, the return value is <c>true</c> (mimics
- the behaviour of the <c>!</c> operator). The expected
- behaviour as well as the actions to take when the function
- returns <c>false</c> are application and hardware specific.</p>
+ the behavior of operator <c>!</c>). The expected
+ behavior and the actions to take when the function
+ returns <c>false</c> are application- and hardware-specific.</p>
<warning>
- <p>Use with extreme care!</p>
+ <p>Use with extreme care.</p>
</warning>
</desc>
</func>
+
<func>
<name name="send_nosuspend" arity="3"/>
- <fsummary>Try to send a message without ever blocking</fsummary>
+ <fsummary>Tries to send a message without ever blocking.</fsummary>
<type name="dst"/>
<desc>
<p>The same as
- <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [nosuspend | <anno>Options</anno>])</seealso>,
- but with boolean return value.</p>
+ <seealso marker="#send/3">erlang:send(<anno>Dest</anno>,
+ <anno>Msg</anno>, [nosuspend | <anno>Options</anno>])</seealso>,
+ but with a Boolean return value.</p>
<p>This function behaves like
- <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
- but takes a third parameter, a list of options. The only
- currently implemented option is <c>noconnect</c>. The option
- <c>noconnect</c> makes the function return <c>false</c> if
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2</seealso>,
+ but takes a third parameter, a list of options.
+ The only option is <c>noconnect</c>, which
+ makes the function return <c>false</c> if
the remote node is not currently reachable by the local
- node. The normal behaviour is to try to connect to the node,
- which may stall the process for a shorter period. The use of
- the <c>noconnect</c> option makes it possible to be
- absolutely sure not to get even the slightest delay when
+ node. The normal behavior is to try to connect to the node,
+ which can stall the process during a short period. The use of
+ option <c>noconnect</c> makes it possible to be
+ sure not to get the slightest delay when
sending to a remote process. This is especially useful when
- communicating with nodes who expect to always be
- the connecting part (i.e. nodes written in C or Java).</p>
+ communicating with nodes that expect to always be
+ the connecting part (that is, nodes written in C or Java).</p>
<p>Whenever the function returns <c>false</c> (either when a
suspend would occur or when <c>noconnect</c> was specified and
the node was not already connected), the message is guaranteed
<em>not</em> to have been sent.</p>
<warning>
- <p>Use with extreme care!</p>
+ <p>Use with extreme care.</p>
</warning>
</desc>
</func>
+
<func>
<name name="set_cookie" arity="2"/>
- <fsummary>Set the magic cookie of a node</fsummary>
+ <fsummary>Sets the magic cookie of a node.</fsummary>
<desc>
<p>Sets the magic cookie of <c><anno>Node</anno></c> to the atom
- <c><anno>Cookie</anno></c>. If <c><anno>Node</anno></c> is the local node, the function
+ <c><anno>Cookie</anno></c>. If <c><anno>Node</anno></c> is the
+ local node, the function
also sets the cookie of all other unknown nodes to
- <c><anno>Cookie</anno></c> (see
- <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual).</p>
+ <c><anno>Cookie</anno></c> (see Section
+ <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso>
+ in the Erlang Reference Manual in System Documentation).</p>
<p>Failure: <c>function_clause</c> if the local node is not
alive.</p>
</desc>
</func>
+
<func>
<name name="setelement" arity="3"/>
- <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>)</type_desc>
- <fsummary>Set Nth element of a tuple</fsummary>
+ <fsummary>Sets the Nth element of a tuple.</fsummary>
+ <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno></type_desc>
<desc>
- <p>Returns a tuple which is a copy of the argument <c><anno>Tuple1</anno></c>
- with the element given by the integer argument <c><anno>Index</anno></c>
+ <p>Returns a tuple that is a copy of argument
+ <c><anno>Tuple1</anno></c>
+ with the element given by integer argument
+ <c><anno>Index</anno></c>
(the first element is the element with index 1) replaced by
- the argument <c><anno>Value</anno></c>.</p>
+ argument <c><anno>Value</anno></c>, for example:</p>
<pre>
> <input>setelement(2, {10, green, bottles}, red).</input>
{10,red,bottles}</pre>
</desc>
</func>
+
<func>
<name name="size" arity="1"/>
- <fsummary>Size of a tuple or binary</fsummary>
+ <fsummary>Size of a tuple or binary.</fsummary>
<desc>
- <p>Returns an integer which is the size of the argument
- <c><anno>Item</anno></c>, which must be either a tuple or a binary.</p>
+ <p>Returns the number of elements in a tuple or the number of
+ bytes in a binary or bitstring, for example:</p>
<pre>
> <input>size({morni, mulle, bwange}).</input>
-3</pre>
+3
+> <input>size(&lt;&lt;11, 22, 33&gt;&gt;).</input>
+3
+</pre>
+ <p>For bitstrings the number of whole bytes is returned. That is, if the number of bits
+ in the bitstring is not divisible by 8, the resulting
+ number of bytes is rounded <em>down</em>.</p>
<p>Allowed in guard tests.</p>
+ <p>See also
+ <seealso marker="#tuple_size/1"><c>tuple_size/1</c></seealso>,
+ <seealso marker="#byte_size/1"><c>byte_size/1</c></seealso>
+ and
+ <seealso marker="#bit_size/1"><c>bit_size/1</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn" arity="1"/>
- <fsummary>Create a new process with a fun as entry point</fsummary>
+ <fsummary>Creates a new process with a fun as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c>. Otherwise works
- like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ <p>Returns the process identifier of a new process started by the
+ application of <c><anno>Fun</anno></c> to the empty list
+ <c>[]</c>. Otherwise
+ works like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn" arity="2"/>
- <fsummary>Create a new process with a fun as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a fun as entry point on a given node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c> on <c><anno>Node</anno></c>. If
- <c><anno>Node</anno></c> does not exist, a useless pid is returned.
- Otherwise works like
+ <p>Returns the process identifier of a new process started
+ by the application of <c><anno>Fun</anno></c> to the
+ empty list <c>[]</c> on <c><anno>Node</anno></c>. If
+ <c><anno>Node</anno></c> does not exist, a useless pid is
+ returned. Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn" arity="3"/>
- <fsummary>Create a new process with a function as entry point</fsummary>
- <desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>. The new process
- created will be placed in the system scheduler queue and be
- run some time later.</p>
- <p><c>error_handler:undefined_function(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> is evaluated by the new process if
- <c><anno>Module</anno>:<anno>Function</anno>/Arity</c> does not exist (where
- <c>Arity</c> is the length of <c><anno>Args</anno></c>). The error handler
+ <fsummary>Creates a new process with a function as entry point.</fsummary>
+ <desc>
+ <p>Returns the process identifier of a new process started by
+ the application of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c>.</p>
+ <p><c>error_handler:undefined_function(<anno>Module</anno>,
+ <anno>Function</anno>, <anno>Args</anno>)</c>
+ is evaluated by the new process if
+ <c><anno>Module</anno>:<anno>Function</anno>/Arity</c>
+ does not exist (where <c>Arity</c> is the length of
+ <c><anno>Args</anno></c>). The error handler
can be redefined (see
<seealso marker="#process_flag/2">process_flag/2</seealso>).
If <c>error_handler</c> is undefined, or the user has
- redefined the default <c>error_handler</c> its replacement is
- undefined, a failure with the reason <c>undef</c> will occur.</p>
+ redefined the default <c>error_handler</c> and its replacement is
+ undefined, a failure with reason <c>undef</c> occurs.</p>
+ <p>Example:</p>
<pre>
> <input>spawn(speed, regulator, [high_speed, thin_cut]).</input>
&lt;0.13.1></pre>
</desc>
</func>
+
<func>
<name name="spawn" arity="4"/>
- <fsummary>Create a new process with a function as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a function as entry point on a given node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. If
- <c><anno>Node</anno></c> does not exists, a useless pid is returned.
+ <p>Returns the process identifier (pid) of a new process started
+ by the application
+ of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c> on <c><anno>Node</anno></c>. If
+ <c><anno>Node</anno></c> does not exist, a useless pid is returned.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="1"/>
- <fsummary>Create and link to a new process with a fun as entry point</fsummary>
+ <fsummary>Creates and links to a new process with a fun as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list []. A link is created between
+ <p>Returns the process identifier of a new process started by
+ the application of <c><anno>Fun</anno></c> to the empty list
+ <c>[]</c>. A link is created between
the calling process and the new process, atomically.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="2"/>
- <fsummary>Create and link to a new process with a fun as entry point on a specified node</fsummary>
+ <fsummary>Creates and links to a new process with a fun as entry point on a specified node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list [] on <c><anno>Node</anno></c>. A link is
+ <p>Returns the process identifier (pid) of a new process started
+ by the application of <c><anno>Fun</anno></c> to the empty
+ list <c>[]</c> on <c><anno>Node</anno></c>. A link is
created between the calling process and the new process,
- atomically. If <c><anno>Node</anno></c> does not exist, a useless pid is
- returned (and due to the link, an exit signal with exit
- reason <c>noconnection</c> will be received). Otherwise works
- like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ atomically. If <c><anno>Node</anno></c> does not exist,
+ a useless pid is returned and an exit signal with
+ reason <c>noconnection</c> is sent to the calling
+ process. Otherwise works like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="3"/>
- <fsummary>Create and link to a new process with a function as entry point</fsummary>
+ <fsummary>Creates and links to a new process with a function as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>. A link is created
+ <p>Returns the process identifier of a new process started by
+ the application of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c>. A link is created
between the calling process and the new process, atomically.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="4"/>
- <fsummary>Create and link to a new process with a function as entry point on a given node</fsummary>
+ <fsummary>Creates and links to a new process with a function as entry point on a given node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. A
+ <p>Returns the process identifier (pid) of a new process
+ started by the application
+ of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c> on <c><anno>Node</anno></c>. A
link is created between the calling process and the new
- process, atomically. If <c><anno>Node</anno></c> does not exist, a useless
- pid is returned (and due to the link, an exit signal with exit
- reason <c>noconnection</c> will be received). Otherwise works
- like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ process, atomically. If <c><anno>Node</anno></c> does
+ not exist, a useless pid is returned and an exit signal with
+ reason <c>noconnection</c> is sent to the calling
+ process. Otherwise works like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_monitor" arity="1"/>
- <fsummary>Create and monitor a new process with a fun as entry point</fsummary>
+ <fsummary>Creates and monitors a new process with a fun as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list [] and reference for a monitor
- created to the new process.
+ <p>Returns the process identifier of a new process, started by
+ the application of <c><anno>Fun</anno></c> to the empty list
+ <c>[]</c>,
+ and a reference for a monitor created to the new process.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_monitor" arity="3"/>
- <fsummary>Create and monitor a new process with a function as entry point</fsummary>
+ <fsummary>Creates and monitors a new process with a function as entry point.</fsummary>
<desc>
<p>A new process is started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>, and the process is
- monitored at the same time. Returns the pid and a reference
- for the monitor.
- Otherwise works like
+ of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c>. The process is
+ monitored at the same time. Returns the process identifier
+ and a reference for the monitor. Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="2"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a fun as entry point</fsummary>
+ <fsummary>Creates a new process with a fun as entry point.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c>. Otherwise
- works like
+ <p>Returns the process identifier (pid) of a new process
+ started by the application of <c><anno>Fun</anno></c>
+ to the empty list <c>[]</c>. Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
- <p>If the option <c>monitor</c> is given, the newly created
- process will be monitored and both the pid and reference for
- the monitor will be returned.</p>
+ <p>If option <c>monitor</c> is given, the newly created
+ process is monitored, and both the pid and reference for
+ the monitor is returned.</p>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="3"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a fun as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a fun as entry point on a given node.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c> on <c><anno>Node</anno></c>. If
- <c><anno>Node</anno></c> does not exist, a useless pid is returned.
- Otherwise works like
+ <p>Returns the process identifier (pid) of a new process started
+ by the application of <c><anno>Fun</anno></c> to the
+ empty list <c>[]</c> on <c><anno>Node</anno></c>. If
+ <c><anno>Node</anno></c> does not exist, a useless pid is
+ returned. Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="4"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a function as entry point</fsummary>
+ <fsummary>Creates a new process with a function as entry point.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Works exactly like
+ <p>Works as
<seealso marker="#spawn/3">spawn/3</seealso>, except that an
extra option list is given when creating the process.</p>
- <p>If the option <c>monitor</c> is given, the newly created
- process will be monitored and both the pid and reference for
- the monitor will be returned.</p>
+ <p>If option <c>monitor</c> is given, the newly created
+ process is monitored, and both the pid and reference for
+ the monitor is returned.</p>
+ <p>The options are as follows:</p>
<taglist>
<tag><c>link</c></tag>
<item>
@@ -4749,112 +5475,123 @@ true</pre>
</item>
<tag><c>monitor</c></tag>
<item>
- <p>Monitor the new process (just like
+ <p>Monitors the new process (like
<seealso marker="#monitor/2">monitor/2</seealso> does).</p>
</item>
- <tag><c>{priority, <anno>Level</anno>}</c></tag>
+ <tag><c>{priority, <anno>Level</anno></c></tag>
<item>
<p>Sets the priority of the new process. Equivalent to
executing
- <seealso marker="#process_flag_priority">process_flag(priority, <anno>Level</anno>)</seealso> in the start function of the new process,
- except that the priority will be set before the process is
- selected for execution for the first time. For more information
- on priorities see
- <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso>.</p>
+ <seealso marker="#process_flag_priority">process_flag(priority,
+ <anno>Level</anno>)</seealso>
+ in the start function of the new process,
+ except that the priority is set before the process is
+ selected for execution for the first time. For more
+ information on priorities, see
+ <seealso marker="#process_flag_priority">process_flag(priority,
+ <anno>Level</anno>)</seealso>.</p>
</item>
<tag><c>{fullsweep_after, <anno>Number</anno>}</c></tag>
<item>
- <p>This option is only useful for performance tuning.
- In general, you should not use this option unless you
- know that there is problem with execution times and/or
- memory consumption, and you should measure to make sure
- that the option improved matters.
- </p>
+ <p>Useful only for performance tuning. Do not use this
+ option unless you
+ know that there is problem with execution times or
+ memory consumption, and ensure
+ that the option improves matters.</p>
<p>The Erlang runtime system uses a generational garbage
collection scheme, using an "old heap" for data that has
survived at least one garbage collection. When there is
no more room on the old heap, a fullsweep garbage
- collection will be done.</p>
- <p>The <c>fullsweep_after</c> option makes it possible to
+ collection is done.</p>
+ <p>Option <c>fullsweep_after</c> makes it possible to
specify the maximum number of generational collections
- before forcing a fullsweep even if there is still room on
- the old heap. Setting the number to zero effectively
- disables the general collection algorithm, meaning that
+ before forcing a fullsweep, even if there is room on
+ the old heap. Setting the number to zero
+ disables the general collection algorithm, that is,
all live data is copied at every garbage collection.</p>
- <p>Here are a few cases when it could be useful to change
- <c>fullsweep_after</c>. Firstly, if binaries that are no
- longer used should be thrown away as soon as possible.
- (Set <c><anno>Number</anno></c> to zero.) Secondly, a process that
- mostly have short-lived data will be fullsweeped seldom
- or never, meaning that the old heap will contain mostly
- garbage. To ensure a fullsweep once in a while, set
- <c><anno>Number</anno></c> to a suitable value such as 10 or 20.
- Thirdly, in embedded systems with limited amount of RAM
- and no virtual memory, one might want to preserve memory
- by setting <c><anno>Number</anno></c> to zero. (The value may be set
- globally, see
- <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)</p>
+ <p>A few cases when it can be useful to change
+ <c>fullsweep_after</c>:</p>
+ <list type="bulleted">
+ <item>If binaries that are no longer used are to be
+ thrown away as soon as possible. (Set
+ <c><anno>Number</anno></c> to zero.)
+ </item>
+ <item>A process that mostly have short-lived data is
+ fullsweeped seldom or never, that is, the old heap
+ contains mostly garbage. To ensure a fullsweep
+ occasionally, set <c><anno>Number</anno></c> to a
+ suitable value, such as 10 or 20.
+ </item>
+ <item>In embedded systems with a limited amount of RAM
+ and no virtual memory, you might want to preserve memory
+ by setting <c><anno>Number</anno></c> to zero.
+ (The value can be set globally, see
+ <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)
+ </item>
+ </list>
</item>
<tag><c>{min_heap_size, <anno>Size</anno>}</c></tag>
<item>
- <p>This option is only useful for performance tuning.
- In general, you should not use this option unless you
- know that there is problem with execution times and/or
- memory consumption, and you should measure to make sure
- that the option improved matters.
- </p>
- <p>Gives a minimum heap size in words. Setting this value
- higher than the system default might speed up some
+ <p>Useful only for performance tuning. Do not use this
+ option unless you know that there is problem with
+ execution times or memory consumption, and
+ ensure that the option improves matters.</p>
+ <p>Gives a minimum heap size, in words. Setting this value
+ higher than the system default can speed up some
processes because less garbage collection is done.
- Setting too high value, however, might waste memory and
- slow down the system due to worse data locality.
- Therefore, it is recommended to use this option only for
+ However, setting a too high value can waste memory and
+ slow down the system because of worse data locality.
+ Therefore, use this option only for
fine-tuning an application and to measure the execution
time with various <c><anno>Size</anno></c> values.</p>
</item>
<tag><c>{min_bin_vheap_size, <anno>VSize</anno>}</c></tag>
<item>
- <p>This option is only useful for performance tuning.
- In general, you should not use this option unless you
- know that there is problem with execution times and/or
- memory consumption, and you should measure to make sure
- that the option improved matters.
- </p>
- <p>Gives a minimum binary virtual heap size in words. Setting this value
- higher than the system default might speed up some
+ <p>Useful only for performance tuning. Do not use this
+ option unless you know that there is problem with
+ execution times or memory consumption, and
+ ensure that the option improves matters.</p>
+ <p>Gives a minimum binary virtual heap size, in words.
+ Setting this value
+ higher than the system default can speed up some
processes because less garbage collection is done.
- Setting too high value, however, might waste memory.
- Therefore, it is recommended to use this option only for
+ However, setting a too high value can waste memory.
+ Therefore, use this option only for
fine-tuning an application and to measure the execution
time with various <c><anno>VSize</anno></c> values.</p>
</item>
-
</taglist>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="5"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a function as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a function as entry point on a given node.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. If
+ <p>Returns the process identifier (pid) of a new process started
+ by the application
+ of <c><anno>Module</anno>:<anno>Function</anno></c> to
+ <c><anno>Args</anno></c> on <c><anno>Node</anno></c>. If
<c><anno>Node</anno></c> does not exist, a useless pid is returned.
Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
- <note><p>The <c>monitor</c> option is currently not supported by
+ <note><p>Option <c>monitor</c> is not supported by
<c>spawn_opt/5</c>.</p></note>
</desc>
</func>
+
<func>
<name name="split_binary" arity="2"/>
+ <fsummary>Splits a binary into two.</fsummary>
<type_desc variable="Pos">0..byte_size(Bin)</type_desc>
- <fsummary>Split a binary into two</fsummary>
<desc>
- <p>Returns a tuple containing the binaries which are the result
- of splitting <c><anno>Bin</anno></c> into two parts at position <c><anno>Pos</anno></c>.
+ <p>Returns a tuple containing the binaries that are the result
+ of splitting <c><anno>Bin</anno></c> into two parts at
+ position <c><anno>Pos</anno></c>.
This is not a destructive operation. After the operation,
- there will be three binaries altogether.</p>
+ there are three binaries altogether.</p>
+ <p>Example:</p>
<pre>
> <input>B = list_to_binary("0123456789").</input>
&lt;&lt;"0123456789">>
@@ -4868,156 +5605,269 @@ true</pre>
7</pre>
</desc>
</func>
+
<func>
- <name name="start_timer" arity="3"/>
- <type_desc variable="Time">0 &lt;= Time &lt;= 4294967295</type_desc>
- <fsummary>Start a timer</fsummary>
+ <name name="start_timer" arity="4"/>
+ <fsummary>Starts a timer.</fsummary>
<desc>
- <p>Starts a timer which will send the message
- <c>{timeout, <anno>TimerRef</anno>, <anno>Msg</anno>}</c> to <c><anno>Dest</anno></c>
- after <c><anno>Time</anno></c> milliseconds.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be greater than 4294967295.</p>
- <p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
- a registered process. The process referred to by the name is
- looked up at the time of delivery. No error is given if
- the name does not refer to a process.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will be automatically
- canceled if the process referred to by the <c>pid()</c> is not alive,
- or when the process exits. This feature was introduced in
- erts version 5.4.11. Note that timers will not be
- automatically canceled when <c><anno>Dest</anno></c> is an <c>atom()</c>.</p>
+ <p>
+ Starts a timer. When the timer expires, the message
+ <c>{timeout, <anno>TimerRef</anno>, <anno>Msg</anno>}</c>
+ is sent to the process identified by
+ <c><anno>Dest</anno></c>.
+ </p>
+ <p>Available <c><anno>Option</anno></c>s:</p>
+ <taglist>
+ <tag><c>{abs, false}</c></tag>
+ <item>
+ <p>
+ This is the default. It means the
+ <c><anno>Time</anno></c> value is interpreted
+ as a time in milli-seconds <em>relative</em> current
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>.
+ </p>
+ </item>
+ <tag><c>{abs, true}</c></tag>
+ <item>
+ <p>
+ Absolute <c><anno>Time</anno></c> value. The
+ <c><anno>Time</anno></c> value is interpreted as an
+ absolute Erlang monotonic time in milli-seconds.
+ </p>
+ </item>
+ </taglist>
+ <p>
+ More <c><anno>Option</anno></c>s may be added in the future.
+ </p>
+ <p>
+ The absolute point in time, the timer is set to expire on,
+ has to be in the interval
+ <c>[</c><seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso><c>,
+ </c><seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso><c>]</c>.
+ Further, if a relative time is specified, the <c><anno>Time</anno></c> value
+ is not allowed to be negative.
+ </p>
+ <p>
+ If <c><anno>Dest</anno></c> is a <c>pid()</c>, it must
+ be a <c>pid()</c> of a process created on the current
+ runtime system instance. This process may or may not
+ have terminated. If <c><anno>Dest</anno></c> is an
+ <c>atom()</c>, it is interpreted as the name of a
+ locally registered process. The process referred to by the
+ name is looked up at the time of timer expiration. No error
+ is given if the name does not refer to a process.
+ </p>
+ <p>
+ If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer is
+ automatically canceled if the process referred to by the
+ <c>pid()</c> is not alive, or if the process exits. This
+ feature was introduced in ERTS version 5.4.11. Notice that
+ timers are not automatically canceled when
+ <c><anno>Dest</anno></c> is an <c>atom()</c>.
+ </p>
<p>See also
- <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ <seealso marker="#send_after/4"><c>erlang:send_after/4</c></seealso>,
+ <seealso marker="#cancel_timer/2"><c>erlang:cancel_timer/2</c></seealso>,
and
- <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
- <p>Failure: <c>badarg</c> if the arguments does not satisfy
- the requirements specified above.</p>
+ <seealso marker="#read_timer/2"><c>erlang:read_timer/2</c></seealso>.</p>
+ <p>Failure: <c>badarg</c> if the arguments do not satisfy
+ the requirements specified here.</p>
</desc>
</func>
+
<func>
- <name name="statistics" arity="1" clause_i="1"/>
- <fsummary>Information about context switches</fsummary>
+ <name name="start_timer" arity="3"/>
+ <fsummary>Starts a timer.</fsummary>
<desc>
- <p><c><anno>ContextSwitches</anno></c> is the total number of context
- switches since the system started.</p>
+ <p>Starts a timer. The same as calling
+ <seealso marker="#start_timer/4"><c>erlang:start_timer(<anno>Time</anno>,
+ <anno>Dest</anno>, <anno>Msg</anno>, [])</c></seealso>.</p>
</desc>
</func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="1"/>
+ <fsummary>Information about active processes and ports.</fsummary>
+ <desc><marker id="statistics_active_tasks"></marker>
+ <p>
+ Returns a list where each element represents the amount
+ of active processes and ports on each run queue and its
+ associated scheduler. That is, the number of processes and
+ ports that are ready to run, or are currently running. The
+ element location in the list corresponds to the scheduler
+ and its run queue. The first element corresponds to scheduler
+ number 1 and so on. The information is <em>not</em> gathered
+ atomically. That is, the result is not necessarily a
+ consistent snapshot of the state, but instead quite
+ efficiently gathered. See also,
+ <seealso marker="#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso>,
+ <seealso marker="#statistics_run_queue_lengths"><c>statistics(run_queue_lengths)</c></seealso>, and
+ <seealso marker="#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
<func>
<name name="statistics" arity="1" clause_i="2"/>
- <fsummary>Information about exact reductions</fsummary>
+ <fsummary>Information about context switches.</fsummary>
<desc>
- <marker id="statistics_exact_reductions"></marker>
- <note><p><c>statistics(exact_reductions)</c> is
- a more expensive operation than
- <seealso marker="#statistics_reductions">statistics(reductions)</seealso>
- especially on an Erlang machine with SMP support.</p>
- </note>
+ <p>Returns the total number of context switches since the
+ system started.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="3"/>
- <fsummary>Information about garbage collection</fsummary>
+ <fsummary>Information about exact reductions.</fsummary>
<desc>
- <p>This information may not be valid for all implementations.</p>
- <pre>
-> <input>statistics(garbage_collection).</input>
-{85,23961,0}
-</pre>
+ <marker id="statistics_exact_reductions"></marker>
+ <p>Returns the number of exact reductions.</p>
+ <note><p><c>statistics(exact_reductions)</c> is
+ a more expensive operation than
+ <seealso marker="#statistics_reductions">statistics(reductions)</seealso>,
+ especially on an Erlang machine with SMP support.</p>
+ </note>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="4"/>
- <fsummary>Information about io</fsummary>
+ <fsummary>Information about garbage collection.</fsummary>
<desc>
- <p><c><anno>Input</anno></c> is the total number of bytes received
- through ports, and <c><anno>Output</anno></c> is the total number of
- bytes output to ports.</p>
+ <p>Returns information about garbage collection, for example:</p>
+ <pre>
+> <input>statistics(garbage_collection).</input>
+{85,23961,0}</pre>
+ <p>This information can be invalid for some implementations.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="5"/>
- <fsummary>Information about reductions</fsummary>
+ <fsummary>Information about I/O.</fsummary>
<desc>
- <marker id="statistics_reductions"></marker>
- <note>
- <p>Since erts-5.5 (OTP release R11B)
- this value does not include reductions performed in current
- time slices of currently scheduled processes. If an
- exact value is wanted, use
- <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p>
- </note>
- <pre>
-> <input>statistics(reductions).</input>
-{2046,11}
-</pre>
+ <p>Returns <c><anno>Input</anno></c>,
+ which is the total number of bytes
+ received through ports, and <c><anno>Output</anno></c>,
+ which is the total number of bytes output to ports.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="6"/>
- <fsummary>Information about the run-queue</fsummary>
+ <fsummary>Information about reductions.</fsummary>
<desc>
- <p>Returns the total length of the run queues, that is, the number
- of processes that are ready to run on all available run queues.</p>
+ <marker id="statistics_reductions"></marker>
+ <p>Returns information about reductions, for example:</p>
+ <pre>
+> <input>statistics(reductions).</input>
+{2046,11}</pre>
+ <note><p>As from <c>ERTS</c> 5.5 (OTP R11B),
+ this value does not include reductions performed in current
+ time slices of currently scheduled processes. If an
+ exact value is wanted, use
+ <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p>
+ </note>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="7"/>
- <fsummary>Information about run-time</fsummary>
- <desc>
- <p>Note that the run-time is the sum of the run-time for all
- threads in the Erlang run-time system and may therefore be greater
- than the wall-clock time. The time is returned in milliseconds.</p>
- <pre>
-> <input>statistics(runtime).</input>
-{1690,1620}
-</pre>
+ <fsummary>Information about the run-queues.</fsummary>
+ <desc><marker id="statistics_run_queue"></marker>
+ <p>
+ Returns the total length of the run-queues. That is, the number
+ of processes and ports that are ready to run on all available
+ run-queues. The information is gathered atomically. That
+ is, the result is a consistent snapshot of the state, but
+ this operation is much more expensive compared to
+ <seealso marker="#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>.
+ This especially when a large amount of schedulers is used.
+ </p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="8"/>
- <fsummary>Information about each schedulers work time</fsummary>
- <desc>
- <marker id="statistics_scheduler_wall_time"></marker>
- <p>
- Returns a list of tuples with <c>{<anno>SchedulerId</anno>,
- <anno>ActiveTime</anno>, <anno>TotalTime</anno>}</c>, where
- <c>SchedulerId</c> is an integer id of the scheduler, <c>ActiveTime</c> is
- the duration the scheduler has been busy, <c>TotalTime</c> is the total time duration since
- <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
- activation. The time unit is not defined and may be subject to change
- between releases, operating systems and system restarts.
- <c>scheduler_wall_time</c> should only be used to calculate relative
- values for scheduler-utilization. <c>ActiveTime</c> can never exceed <c>TotalTime</c>.
- </p>
-
- <p>The definition of a busy scheduler is when it is not idle or not
- scheduling (selecting) a process or port, meaning; executing process
- code, executing linked-in-driver or NIF code, executing
- built-in-functions or any other runtime handling, garbage collecting
- or handling any other memory management. Note, a scheduler may also be
- busy even if the operating system has scheduled out the scheduler
- thread.
- </p>
+ <fsummary>Information about the run-queue lengths.</fsummary>
+ <desc><marker id="statistics_run_queue_lengths"></marker>
+ <p>
+ Returns a list where each element represents the amount
+ of processes and ports ready to run for each run queue. The
+ element location in the list corresponds to the run queue
+ of a scheduler. The first element corresponds to the run
+ queue of scheduler number 1 and so on. The information is
+ <em>not</em> gathered atomically. That is, the result is
+ not necessarily a consistent snapshot of the state, but
+ instead quite efficiently gathered. See also,
+ <seealso marker="#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>,
+ <seealso marker="#statistics_active_tasks"><c>statistics(active_tasks)</c></seealso>, and
+ <seealso marker="#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso>.
+ </p>
+ </desc>
+ </func>
- <p>
- Returns <c>undefined</c> if the system flag
- <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
- is turned off.
- </p>
+ <func>
+ <name name="statistics" arity="1" clause_i="9"/>
+ <fsummary>Information about runtime.</fsummary>
+ <desc>
+ <p>Returns information about runtime, in milliseconds.</p>
+ <p>This is the sum of the runtime for all threads
+ in the Erlang runtime system and can therefore be greater
+ than the wall clock time.</p>
+ <p>Example:</p>
+ <pre>
+> <input>statistics(runtime).</input>
+{1690,1620}</pre>
+ </desc>
+ </func>
- <p>The list of scheduler information is unsorted and may appear in different order
- between calls.
- </p>
- <p>Using <c>scheduler_wall_time</c> to calculate scheduler utilization.</p>
+ <func>
+ <name name="statistics" arity="1" clause_i="10"/>
+ <fsummary>Information about each schedulers work time.</fsummary>
+ <desc>
+ <marker id="statistics_scheduler_wall_time"></marker>
+ <p>Returns a list of tuples with
+ <c>{<anno>SchedulerId</anno>, <anno>ActiveTime</anno>,
+ <anno>TotalTime</anno>}</c>, where
+ <c><anno>SchedulerId</anno></c> is an integer ID of the scheduler,
+ <c><anno>ActiveTime</anno></c> is
+ the duration the scheduler has been busy, and
+ <c><anno>TotalTime</anno></c> is the total time duration since
+ <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
+ activation. The time unit is undefined and can be subject
+ to change between releases, OSs, and system restarts.
+ <c>scheduler_wall_time</c> is only to be used to
+ calculate relative values for scheduler-utilization.
+ <c><anno>ActiveTime</anno></c> can never exceed
+ <c><anno>TotalTime</anno></c>.</p>
+ <p>The definition of a busy scheduler is when it is not idle
+ and is not scheduling (selecting) a process or port,
+ that is:</p>
+ <list type="bulleted">
+ <item>Executing process code</item>
+ <item>Executing linked-in-driver or NIF code</item>
+ <item>Executing built-in-functions, or any other runtime
+ handling</item>
+ <item>Garbage collecting</item>
+ <item>Handling any other memory management</item>
+ </list>
+ <p>Notice that a scheduler can also be busy even if the
+ OS has scheduled out the scheduler thread.</p>
+ <p>Returns <c>undefined</c> if system flag
+ <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
+ is turned off.</p>
+ <p>The list of scheduler information is unsorted and can
+ appear in different order between calls.</p>
+ <p>Using <c>scheduler_wall_time</c> to calculate scheduler-utilization:</p>
<pre>
> <input>erlang:system_flag(scheduler_wall_time, true).</input>
false
> <input>Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input>
-ok
-</pre>
- <p>Some time later we will take another snapshot and calculate scheduler-utilization per scheduler.</p>
+ok</pre>
+ <p>Some time later the user takes another snapshot and calculates
+ scheduler-utilization per scheduler, for example:</p>
<pre>
> <input>Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input>
ok
@@ -5030,86 +5880,127 @@ ok
{5,0.9717956667018103},
{6,0.9739235846420741},
{7,0.973237033077876},
- {8,0.9741297293248656}]
-</pre>
- <p>Using the same snapshots to calculate a total scheduler-utilization.</p>
+ {8,0.9741297293248656}]</pre>
+ <p>Using the same snapshots to calculate a total scheduler-utilization:</p>
<pre>
> <input>{A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) ->
{Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)), A/T.</input>
-0.9769136803764825
-</pre>
+0.9769136803764825</pre>
<note>
- <p><c>scheduler_wall_time</c> is by default disabled. Use <c>erlang:system_flag(scheduler_wall_time, true)</c> to enable it. </p>
+ <p><c>scheduler_wall_time</c> is by default disabled. To
+ enable it, use
+ <c>erlang:system_flag(scheduler_wall_time, true)</c>.</p>
</note>
</desc>
</func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="11"/>
+ <fsummary>Information about active processes and ports.</fsummary>
+ <desc><marker id="statistics_total_active_tasks"></marker>
+ <p>
+ Returns the total amount of active processes and ports in
+ the system. That is, the number of processes and ports that
+ are ready to run, or are currently running. The information
+ is <em>not</em> gathered atomically. That is, the result
+ is not necessarily a consistent snapshot of the state, but
+ instead quite efficiently gathered. See also,
+ <seealso marker="#statistics_active_tasks"><c>statistics(active_tasks)</c></seealso>,
+ <seealso marker="#statistics_run_queue_lengths"><c>statistics(run_queue_lengths)</c></seealso>, and
+ <seealso marker="#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
<func>
- <name name="statistics" arity="1" clause_i="9"/>
- <fsummary>Information about wall-clock</fsummary>
+ <name name="statistics" arity="1" clause_i="12"/>
+ <fsummary>Information about the run-queue lengths.</fsummary>
+ <desc><marker id="statistics_total_run_queue_lengths"></marker>
+ <p>
+ Returns the total length of the run-queues. That is, the number
+ of processes and ports that are ready to run on all available
+ run-queues. The information is <em>not</em> gathered atomically.
+ That is, the result is not necessarily a consistent snapshot of
+ the state, but much more efficiently gathered compared to
+ <seealso marker="#statistics_run_queue"><c>statistics(run_queue)</c></seealso>.
+ See also,
+ <seealso marker="#statistics_run_queue_lengths"><c>statistics(run_queue_lengths)</c></seealso>,
+ <seealso marker="#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso>, and
+ <seealso marker="#statistics_active_tasks"><c>statistics(active_tasks)</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="13"/>
+ <fsummary>Information about wall clock.</fsummary>
<desc>
- <p><c>wall_clock</c> can be used in the same manner as
+ <p>Returns information about wall clock. <c>wall_clock</c> can
+ be used in the same manner as
<c>runtime</c>, except that real time is measured as
opposed to runtime or CPU time.</p>
</desc>
</func>
+
<func>
<name name="suspend_process" arity="2"/>
- <fsummary>Suspend a process</fsummary>
+ <fsummary>Suspends a process.</fsummary>
<desc>
<p>Increases the suspend count on the process identified by
- <c><anno>Suspendee</anno></c> and puts it in the suspended state if it isn't
- already in the suspended state. A suspended process will not be
- scheduled for execution until the process has been resumed.
- </p>
-
+ <c><anno>Suspendee</anno></c> and puts it in the suspended
+ state if it is not
+ already in that state. A suspended process will not be
+ scheduled for execution until the process has been resumed.</p>
<p>A process can be suspended by multiple processes and can
be suspended multiple times by a single process. A suspended
- process will not leave the suspended state until its suspend
- count reach zero. The suspend count of <c><anno>Suspendee</anno></c>
- is decreased when
+ process does not leave the suspended state until its suspend
+ count reaches zero. The suspend count of
+ <c><anno>Suspendee</anno></c> is decreased when
<seealso marker="#resume_process/1">erlang:resume_process(<anno>Suspendee</anno>)</seealso>
is called by the same process that called
- <c>erlang:suspend_process(<anno>Suspendee</anno>)</c>. All increased suspend
- counts on other processes acquired by a process will automatically be
+ <c>erlang:suspend_process(<anno>Suspendee</anno>)</c>.
+ All increased suspend
+ counts on other processes acquired by a process are automatically
decreased when the process terminates.</p>
-
- <p>Currently the following options (<c><anno>Opt</anno></c>s) are available:</p>
+ <p>The options (<c><anno>Opt</anno></c>s) are as follows:</p>
<taglist>
<tag><c>asynchronous</c></tag>
<item>
A suspend request is sent to the process identified by
- <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c> will eventually suspend
- unless it is resumed before it was able to suspend. The caller
- of <c>erlang:suspend_process/2</c> will return immediately,
- regardless of whether the <c><anno>Suspendee</anno></c> has suspended yet
- or not. Note that the point in time when the <c><anno>Suspendee</anno></c>
- will actually suspend cannot be deduced from other events
- in the system. The only guarantee given is that the
- <c><anno>Suspendee</anno></c> will <em>eventually</em> suspend (unless it
- is resumed). If the <c>asynchronous</c> option has <em>not</em>
- been passed, the caller of <c>erlang:suspend_process/2</c> will
- be blocked until the <c><anno>Suspendee</anno></c> has actually suspended.
+ <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c>
+ eventually suspends
+ unless it is resumed before it could suspend. The caller
+ of <c>erlang:suspend_process/2</c> returns immediately,
+ regardless of whether <c><anno>Suspendee</anno></c> has
+ suspended yet or not. The point in time when
+ <c><anno>Suspendee</anno></c> suspends cannot be deduced
+ from other events in the system. It is only guaranteed that
+ <c><anno>Suspendee</anno></c> <em>eventually</em> suspends
+ (unless it
+ is resumed). If option <c>asynchronous</c> has <em>not</em>
+ been passed, the caller of <c>erlang:suspend_process/2</c> is
+ blocked until <c><anno>Suspendee</anno></c> has suspended.
</item>
<tag><c>unless_suspending</c></tag>
<item>
- The process identified by <c><anno>Suspendee</anno></c> will be suspended
- unless the calling process already is suspending the
- <c><anno>Suspendee</anno></c>. If <c>unless_suspending</c> is combined
- with the <c>asynchronous</c> option, a suspend request will be
- sent unless the calling process already is suspending the
- <c><anno>Suspendee</anno></c> or if a suspend request already has been sent
- and is in transit. If the calling process already is suspending
- the <c><anno>Suspendee</anno></c>, or if combined with the <c>asynchronous</c>
- option and a send request already is in transit,
- <c>false</c> is returned and the suspend count on <c><anno>Suspendee</anno></c>
- will remain unchanged.
+ The process identified by <c><anno>Suspendee</anno></c> is
+ suspended unless the calling process already is suspending
+ <c><anno>Suspendee</anno></c>.
+ If <c>unless_suspending</c> is combined
+ with option <c>asynchronous</c>, a suspend request is
+ sent unless the calling process already is suspending
+ <c><anno>Suspendee</anno></c> or if a suspend request
+ already has been sent and is in transit. If the calling
+ process already is suspending <c><anno>Suspendee</anno></c>,
+ or if combined with option <c>asynchronous</c>
+ and a send request already is in transit,
+ <c>false</c> is returned and the suspend count on
+ <c><anno>Suspendee</anno></c> remains unchanged.
</item>
</taglist>
-
<p>If the suspend count on the process identified by
- <c><anno>Suspendee</anno></c> was increased, <c>true</c> is returned; otherwise,
- <c>false</c> is returned.</p>
-
+ <c><anno>Suspendee</anno></c> is increased, <c>true</c>
+ is returned, otherwise <c>false</c>.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
@@ -5117,310 +6008,322 @@ ok
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Suspendee</anno></c> isn't a process identifier.
+ If <c><anno>Suspendee</anno></c> is not a process identifier.
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> is same the process as
- the process calling <c>erlang:suspend_process/2</c>.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ is the same process
+ as the process calling <c>erlang:suspend_process/2</c>.
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> is not alive.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ is not alive.
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> resides on another node.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ resides on another node.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>OptList</anno></c> isn't a proper list of valid <c><anno>Opt</anno></c>s.
+ If <c><anno>OptList</anno></c> is not a proper list of valid
+ <c><anno>Opt</anno></c>s.
</item>
<tag><c>system_limit</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> has been suspended more
- times by the calling process than can be represented by the
- currently used internal data structures. The current system limit
- is larger than 2 000 000 000 suspends, and it will never be less
- than that.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ has been suspended
+ more times by the calling process than can be represented by the
+ currently used internal data structures. The system limit is
+ higher than 2,000,000,000 suspends and will never be lower.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="suspend_process" arity="1"/>
- <fsummary>Suspend a process</fsummary>
+ <fsummary>Suspends a process.</fsummary>
<desc>
- <p>Suspends the process identified by <c><anno>Suspendee</anno></c>. The
- same as calling
- <seealso marker="#suspend_process/2">erlang:suspend_process(<anno>Suspendee</anno>, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>.
- </p>
+ <p>Suspends the process identified by
+ <c><anno>Suspendee</anno></c>. The same as calling
+ <seealso marker="#suspend_process/2">erlang:suspend_process(<anno>Suspendee</anno>,
+ [])</seealso>.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="1"/>
- <fsummary>Set system flag backtrace_depth</fsummary>
+ <fsummary>Sets system flag <c>backtrace_depth</c>.</fsummary>
<desc>
<p>Sets the maximum depth of call stack back-traces in the
exit reason element of <c>'EXIT'</c> tuples.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="2"/>
+ <fsummary>Sets system flag <c>cpu_topology</c>.</fsummary>
<type name="cpu_topology"/>
<type name="level_entry"/>
<type name="level_tag"/>
<type name="sub_level"/>
<type name="info_list"/>
- <fsummary>Set system flag cpu_topology</fsummary>
<desc>
<warning>
<p><marker id="system_flag_cpu_topology"></marker>
- This argument is <em>deprecated</em> and
- scheduled for removal in erts-5.10/OTP-R16. Instead of using
- this argument you are advised to use the <c>erl</c> command
- line argument <seealso marker="erts:erl#+sct">+sct</seealso>.
- When this argument has been removed a final CPU topology to use
- will be determined at emulator boot time.</p>
+ This argument is <em>deprecated</em> and scheduled for
+ removal in <c>ERTS</c> 5.10/OTP R16. Instead of using this
+ argument, use command-line argument
+ <seealso marker="erts:erl#+sct">+sct</seealso> in
+ <c>erl(1)</c>.</p>
+ <p>When this argument is removed, a final CPU topology
+ to use is determined at emulator boot time.</p>
</warning>
- <p>Sets the user defined <c><anno>CpuTopology</anno></c>. The user defined
- CPU topology will override any automatically detected
- CPU topology. By passing <c>undefined</c> as <c><anno>CpuTopology</anno></c>
- the system will revert back to the CPU topology automatically
+ <p>Sets the user-defined <c><anno>CpuTopology</anno></c>.
+ The user-defined
+ CPU topology overrides any automatically detected
+ CPU topology. By passing <c>undefined</c> as
+ <c><anno>CpuTopology</anno></c>,
+ the system reverts to the CPU topology automatically
detected. The returned value equals the value returned
from <c>erlang:system_info(cpu_topology)</c> before the
- change was made.
- </p>
+ change was made.</p>
<p>Returns the old value of the flag.</p>
<p>The CPU topology is used when binding schedulers to logical
processors. If schedulers are already bound when the CPU
- topology is changed, the schedulers will be sent a request
- to rebind according to the new CPU topology.
- </p>
- <p>The user defined CPU topology can also be set by passing
- the <seealso marker="erts:erl#+sct">+sct</seealso> command
- line argument to <c>erl</c>.
- </p>
- <p>For information on the <c><anno>CpuTopology</anno></c> type
- and more, see the documentation of
- <seealso marker="#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>,
- and the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso>
- and <seealso marker="erts:erl#+sbt">+sbt</seealso>
- command line flags.
- </p>
+ topology is changed, the schedulers are sent a request
+ to rebind according to the new CPU topology.</p>
+ <p>The user-defined CPU topology can also be set by passing
+ command-line argument
+ <seealso marker="erts:erl#+sct">+sct</seealso> to
+ <c>erl(1)</c>.</p>
+ <p>For information on type <c><anno>CpuTopology</anno></c>
+ and more, see
+ <seealso marker="#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>
+ as well as the command-line flags
+ <seealso marker="erts:erl#+sct">+sct</seealso> and
+ <seealso marker="erts:erl#+sbt">+sbt</seealso> in
+ <c>erl(1)</c>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="3"/>
- <fsummary>Set system flag dirty CPU schedulers online</fsummary>
+ <fsummary>Sets <c>system_flag_dirty_cpu_schedulers_online</c>.</fsummary>
<desc>
<p><marker id="system_flag_dirty_cpu_schedulers_online"></marker>
- Sets the amount of dirty CPU schedulers online. Valid range is
- <![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]> where <c>N</c> is the
- lesser of the return values of <c>erlang:system_info(dirty_cpu_schedulers)</c> and
- <c>erlang:system_info(schedulers_online)</c>.
- </p>
+ Sets the number of dirty CPU schedulers online. Range is
+ <![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]>, where <c>N</c>
+ is the smallest of the return values of
+ <c>erlang:system_info(dirty_cpu_schedulers)</c> and
+ <c>erlang:system_info(schedulers_online)</c>.</p>
<p>Returns the old value of the flag.</p>
- <p>Note that the number of dirty CPU schedulers online may change if the number of
- schedulers online changes. For example, if there are 12 schedulers and all are
- online, and 6 dirty CPU schedulers, all online as well, and <c>system_flag/2</c>
- is used to set the number of schedulers online to 6, then the number of dirty
- CPU schedulers online is automatically decreased by half as well, down to 3.
- Similarly, the number of dirty CPU schedulers online increases proportionally
- to increases in the number of schedulers online.</p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in order
- to try out the functionality.</p>
- <p>For more information see
+ <p>The number of dirty CPU schedulers online can change if the
+ number of schedulers online changes. For example, if 12
+ schedulers and 6 dirty CPU schedulers are online, and
+ <c>system_flag/2</c> is used to set the number of
+ schedulers online to 6, then the number of dirty CPU
+ schedulers online is automatically decreased by half as well,
+ down to 3. Similarly, the number of dirty CPU schedulers
+ online increases proportionally to increases in the number of
+ schedulers online.</p>
+ <note><p>The dirty schedulers functionality is experimental.
+ Enable support for dirty schedulers when building OTP to
+ try out the functionality.</p>
+ </note>
+ <p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">erlang:system_info(dirty_cpu_schedulers)</seealso>
and
- <seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>.
- </p>
+ <seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="4"/>
- <fsummary>Set system flag fullsweep_after</fsummary>
+ <fsummary>Sets system flag <c>fullsweep_after</c>.</fsummary>
<desc>
- <p><c><anno>Number</anno></c> is a non-negative integer which indicates
+ <p>Sets system flag <c>fullsweep_after</c>.
+ <c><anno>Number</anno></c> is a non-negative integer indicating
how many times generational garbage collections can be
done without forcing a fullsweep collection. The value
- applies to new processes; processes already running are
+ applies to new processes, while processes already running are
not affected.</p>
<p>Returns the old value of the flag.</p>
<p>In low-memory systems (especially without virtual
- memory), setting the value to 0 can help to conserve
+ memory), setting the value to <c>0</c> can help to conserve
memory.</p>
- <p>An alternative way to set this value is through the
- (operating system) environment variable
- <c>ERL_FULLSWEEP_AFTER</c>.</p>
+ <p>This value can also be set through (OS)
+ environment variable <c>ERL_FULLSWEEP_AFTER</c>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="5"/>
- <fsummary>Set system flag min_heap_size</fsummary>
- <desc>
- <p>Sets the default minimum heap size for processes. The
- size is given in words. The new <c>min_heap_size</c> only
- effects processes spawned after the change of
- <c>min_heap_size</c> has been made.
- The <c>min_heap_size</c> can be set for individual
- processes by use of
+ <fsummary>Sets system flag <c>min_heap_size</c>.</fsummary>
+ <desc>
+ <p>Sets the default minimum heap size for processes. The size
+ is given in words. The new <c>min_heap_size</c> effects
+ only processes spawned after the change of
+ <c>min_heap_size</c> has been made. <c>min_heap_size</c>
+ can be set for individual processes by using
<seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
- <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="6"/>
- <fsummary>Set system flag min_bin_vheap_size</fsummary>
+ <fsummary>Sets system flag <c>min_bin_vheap_size</c>.</fsummary>
<desc>
- <p>Sets the default minimum binary virtual heap size for processes. The
- size is given in words. The new <c>min_bin_vhheap_size</c> only
- effects processes spawned after the change of
+ <p>Sets the default minimum binary virtual heap size for
+ processes. The size is given in words.
+ The new <c>min_bin_vhheap_size</c> effects only
+ processes spawned after the change of
<c>min_bin_vhheap_size</c> has been made.
- The <c>min_bin_vheap_size</c> can be set for individual
- processes by use of
+ <c>min_bin_vheap_size</c> can be set for individual
+ processes by using
<seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
- <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="7"/>
- <fsummary>Set system flag multi_scheduling</fsummary>
+ <fsummary>Sets system flag <c>multi_scheduling</c>.</fsummary>
<desc>
<p><marker id="system_flag_multi_scheduling"></marker>
If multi-scheduling is enabled, more than one scheduler
thread is used by the emulator. Multi-scheduling can be
- blocked. When multi-scheduling has been blocked, only
- one scheduler thread will schedule Erlang processes.</p>
- <p>If <c><anno>BlockState</anno> =:= block</c>, multi-scheduling will
- be blocked. If <c><anno>BlockState</anno> =:= unblock</c> and no-one
- else is blocking multi-scheduling and this process has
- only blocked one time, multi-scheduling will be unblocked.
- One process can block multi-scheduling multiple times.
- If a process has blocked multiple times, it has to
+ blocked. When multi-scheduling is blocked, only
+ one scheduler thread schedules Erlang processes.</p>
+ <p>If <c><anno>BlockState</anno> =:= block</c>, multi-scheduling is
+ blocked. If <c><anno>BlockState</anno> =:= unblock</c> and no one
+ else blocks multi-scheduling, and this process has
+ blocked only once, multi-scheduling is unblocked.</p>
+ <p>One process can block multi-scheduling multiple times.
+ If a process has blocked multiple times, it must
unblock exactly as many times as it has blocked before it
has released its multi-scheduling block. If a process that
- has blocked multi-scheduling exits, it will release its
+ has blocked multi-scheduling exits, it releases its
blocking of multi-scheduling.</p>
<p>The return values are <c>disabled</c>, <c>blocked</c>,
or <c>enabled</c>. The returned value describes the
state just after the call to
<c>erlang:system_flag(multi_scheduling, <anno>BlockState</anno>)</c>
- has been made. The return values are described in the
- documentation of <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>.</p>
- <p><em>NOTE</em>: Blocking of multi-scheduling should normally
- not be needed. If you feel that you need to
- block multi-scheduling, think through the
- problem at least a couple of times again.
- Blocking multi-scheduling should only be used
- as a last resort since it will most likely be
- a <em>very inefficient</em> way to solve the
- problem.</p>
- <p>See also <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ has been made. For information about the return values, see
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>.</p>
+ <note><p>Blocking of multi-scheduling is normally not needed.
+ If you feel that you need to block multi-scheduling,
+ consider it a few more times again. Blocking multi-scheduling
+ is only to be used as a last resort, as it is most likely
+ a <em>very inefficient</em> way to solve the problem.</p>
+ </note>
+ <p>See also
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="8"/>
+ <fsummary>Sets system flag <c>scheduler_bind_type</c>.</fsummary>
<type name="scheduler_bind_type"/>
- <fsummary>Set system flag scheduler_bind_type</fsummary>
<desc>
<warning>
<p><marker id="system_flag_scheduler_bind_type"></marker>
- This argument is <em>deprecated</em> and
- scheduled for removal in erts-5.10/OTP-R16. Instead of using
- this argument you are advised to use the <c>erl</c> command
- line argument <seealso marker="erts:erl#+sbt">+sbt</seealso>.
- When this argument has been removed a final scheduler bind type
- to use will be determined at emulator boot time.</p>
+ This argument is <em>deprecated</em> and scheduled for
+ removal in <c>ERTS</c> 5.10/OTP R16. Instead of using this
+ argument, use command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso> in <c>erl(1)</c>.
+ When this argument is removed, a final scheduler bind
+ type to use is determined at emulator boot time.</p>
</warning>
<p>Controls if and how schedulers are bound to logical
processors.</p>
- <p>When <c>erlang:system_flag(scheduler_bind_type, <anno>How</anno>)</c> is
- called, an asynchronous signal is sent to all schedulers
- online which causes them to try to bind or unbind as requested.
- <em>NOTE:</em> If a scheduler fails to bind, this
- will often be silently ignored. This since it isn't always
- possible to verify valid logical processor identifiers. If
- an error is reported, it will be reported to the
- <c>error_logger</c>. If you want to verify that the
- schedulers actually have bound as requested, call
- <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
- </p>
- <p>Schedulers can currently only be bound on newer Linux,
+ <p>When <c>erlang:system_flag(scheduler_bind_type, <anno>How</anno>)</c>
+ is called, an asynchronous signal is sent to all schedulers
+ online, causing them to try to bind or unbind as requested.</p>
+ <note><p>If a scheduler fails to bind, this is often silently
+ ignored, as it is not always possible to verify valid
+ logical processor identifiers. If an error is reported,
+ it is reported to <c>error_logger</c>. To verify that the
+ schedulers have bound as requested, call
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.</p>
+ </note>
+ <p>Schedulers can be bound on newer Linux,
Solaris, FreeBSD, and Windows systems, but more systems will be
- supported in the future.
- </p>
+ supported in future releases.</p>
<p>In order for the runtime system to be able to bind schedulers,
- the CPU topology needs to be known. If the runtime system fails
- to automatically detect the CPU topology, it can be defined.
+ the CPU topology must be known. If the runtime system fails
+ to detect the CPU topology automatically, it can be defined.
For more information on how to define the CPU topology, see
- the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> command
- line flag.
- </p>
- <p>The runtime system will by default <em>not</em> bind schedulers
- to logical processors.
- </p>
- <p><em>NOTE:</em> If the Erlang runtime system is the only
- operating system process that binds threads to logical processors,
- this improves the performance of the runtime system. However,
- if other operating system processes (as for example another Erlang
- runtime system) also bind threads to logical processors, there
- might be a performance penalty instead. In some cases this
- performance penalty might be severe. If this is the case, you
- are advised to not bind the schedulers.</p>
- <p>Schedulers can be bound in different ways. The <c><anno>How</anno></c>
- argument determines how schedulers are bound. <c><anno>How</anno></c> can
- currently be one of:</p>
+ command-line flag <seealso marker="erts:erl#+sct">+sct</seealso>
+ in <c>erl(1)</c>.</p>
+ <p>The runtime system does by default <em>not</em> bind schedulers
+ to logical processors.</p>
+ <note><p>If the Erlang runtime system is the only OS
+ process binding threads to logical processors, this
+ improves the performance of the runtime system. However,
+ if other OS processes (for example, another Erlang
+ runtime system) also bind threads to logical processors,
+ there can be a performance penalty instead. Sometimes this
+ performance penalty can be severe. If so, it is recommended
+ to not bind the schedulers.</p>
+ </note>
+ <p>Schedulers can be bound in different ways. Argument
+ <c><anno>How</anno></c> determines how schedulers are
+ bound and can be any of the following:</p>
<taglist>
<tag><c>unbound</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt u</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt u</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>no_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt ns</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt ns</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>thread_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt ts</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt ts</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>processor_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt ps</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt ps</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt s</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt s</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>no_node_thread_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt nnts</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt nnts</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>no_node_processor_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt nnps</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt nnps</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>thread_no_node_processor_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt tnnps</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt tnnps</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>default_bind</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt db</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt db</seealso> in <c>erl(1)</c>.
</p></item>
</taglist>
- <p>The value returned equals <c><anno>How</anno></c> before the
- <c>scheduler_bind_type</c> flag was changed.</p>
- <p>Failure:</p>
+ <p>The returned value equals <c><anno>How</anno></c> before flag
+ <c>scheduler_bind_type</c> was changed.</p>
+ <p>Failures:</p>
<taglist>
<tag><c>notsup</c></tag>
<item>
@@ -5428,139 +6331,171 @@ ok
</item>
<tag><c>badarg</c></tag>
<item>
- <p>If <c>How</c> isn't one of the documented alternatives.</p>
+ <p>If <c><anno>How</anno></c> is not one of the documented
+ alternatives.</p>
</item>
<tag><c>badarg</c></tag>
<item>
- <p>If no CPU topology information is available.</p>
+ <p>If CPU topology information is unavailable.</p>
</item>
</taglist>
<p>The scheduler bind type can also be set by passing
- the <seealso marker="erts:erl#+sbt">+sbt</seealso> command
- line argument to <c>erl</c>.
- </p>
+ command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso> to <c>erl(1)</c>.</p>
<p>For more information, see
<seealso marker="#system_info_scheduler_bind_type">erlang:system_info(scheduler_bind_type)</seealso>,
<seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>,
- the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso>
- and <seealso marker="erts:erl#+sct">+sct</seealso> command line
- flags.
- </p>
+ as well as command-line flags
+ <seealso marker="erts:erl#+sbt">+sbt</seealso>
+ and <seealso marker="erts:erl#+sct">+sct</seealso>
+ in <c>erl(1)</c>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="9"/>
- <fsummary>Set system flag scheduler_wall_time</fsummary>
+ <fsummary>Sets system flag <c>scheduler_wall_time</c>.</fsummary>
<desc><p><marker id="system_flag_scheduler_wall_time"></marker>
- Turns on/off scheduler wall time measurements. </p>
- <p>For more information see,
- <seealso marker="#statistics_scheduler_wall_time">erlang:statistics(scheduler_wall_time)</seealso>.
- </p>
+ Turns on or off scheduler wall time measurements.</p>
+ <p>For more information, see
+ <seealso marker="#statistics_scheduler_wall_time">erlang:statistics(scheduler_wall_time)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="10"/>
- <fsummary>Set system flag schedulers_online</fsummary>
+ <fsummary>Sets system flag <c>schedulers_online</c>.</fsummary>
<desc>
<p><marker id="system_flag_schedulers_online"></marker>
- Sets the amount of schedulers online. Valid range is
- <![CDATA[1 <= SchedulersOnline <= erlang:system_info(schedulers)]]>.
- </p>
+ Sets the number of schedulers online. Range is
+ <![CDATA[1 <= SchedulersOnline <= erlang:system_info(schedulers)]]>.</p>
<p>Returns the old value of the flag.</p>
- <p>Note that if the emulator was built with support for <seealso
- marker="#system_flag_dirty_cpu_schedulers_online">dirty schedulers</seealso>,
- changing the number of schedulers online can also change the number of dirty
- CPU schedulers online. For example, if there are 12 schedulers and all are
- online, and 6 dirty CPU schedulers, all online as well, and <c>system_flag/2</c>
- is used to set the number of schedulers online to 6, then the number of dirty
- CPU schedulers online is automatically decreased by half as well, down to 3.
- Similarly, the number of dirty CPU schedulers online increases proportionally
- to increases in the number of schedulers online.</p>
- <p>For more information see,
- <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
+ <p>If the emulator was built with support for
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">dirty schedulers</seealso>,
+ changing the number of schedulers online can also change the
+ number of dirty CPU schedulers online. For example, if 12
+ schedulers and 6 dirty CPU schedulers are online, and
+ <c>system_flag/2</c> is used to set the number of schedulers
+ online to 6, then the number of dirty CPU schedulers online
+ is automatically decreased by half as well, down to 3.
+ Similarly, the number of dirty CPU schedulers online increases
+ proportionally to increases in the number of schedulers online.</p>
+ <p>For more information, see
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>
and
- <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
- </p>
+ <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="11"/>
- <fsummary>Set system flag trace_control_word</fsummary>
+ <fsummary>Sets system flag <c>trace_control_word</c>.</fsummary>
<desc>
- <p>Sets the value of the node's trace control word to
- <c><anno>TCW</anno></c>. <c><anno>TCW</anno></c> should be an unsigned integer. For
- more information see documentation of the
+ <p>Sets the value of the node trace control word to
+ <c><anno>TCW</anno></c>, which is to be an unsigned integer.
+ For more information, see the function
<seealso marker="erts:match_spec#set_tcw">set_tcw</seealso>
- function in the match specification documentation in the
- ERTS User's Guide.</p>
+ in Section "Match Specifications in Erlang" in the
+ User's Guide.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
+ <func>
+ <name name="system_flag" arity="2" clause_i="12"/>
+ <fsummary>Finalize the Time Offset</fsummary>
+ <desc>
+ <p><marker id="system_flag_time_offset"></marker>
+ Finalizes the <seealso marker="#time_offset/0">time offset</seealso>
+ when <seealso marker="time_correction#Single_Time_Warp_Mode">single
+ time warp mode</seealso> is used. If another time warp mode
+ is used, the time offset state is left unchanged.</p>
+ <p>Returns the old state identifier. That is:</p>
+ <list>
+ <item><p>If <c>preliminary</c> is returned, finalization was
+ performed and the time offset is now final.</p></item>
+
+ <item><p>If <c>final</c> is returned, the time offset was
+ already in the final state. This either because another
+ <c>erlang:system_flag(time_offset, finalize)</c> call, or
+ because <seealso marker="time_correction#No_Time_Warp_Mode">no
+ time warp mode</seealso> is used.</p></item>
+
+ <item><p>If <c>volatile</c> is returned, the time offset
+ cannot be finalized because
+ <seealso marker="time_correction#Multi_Time_Warp_Mode">multi
+ time warp mode</seealso> is used.</p></item>
+ </list>
+ </desc>
+ </func>
+
<func>
<name name="system_info" arity="1" clause_i="1"/>
<name name="system_info" arity="1" clause_i="2"/>
<name name="system_info" arity="1" clause_i="3"/>
<name name="system_info" arity="1" clause_i="4"/>
<name name="system_info" arity="1" clause_i="5"/>
+ <fsummary>Information about the system allocators.</fsummary>
<type variable="Allocator" name_i="2"/>
<type variable="Version" name_i="2"/>
<type variable="Features" name_i="2"/>
<type variable="Settings" name_i="2"/>
<type variable="Alloc" name_i="3"/>
- <fsummary>Information about the allocators of the system</fsummary>
<desc>
- <p>
- Returns various information about the
- <marker id="system_info_allocator_tags">allocators</marker> of the
+ <marker id="system_info_allocator_tags"></marker>
+ <p>Returns various information about the allocators of the
current system (emulator) as specified by
<c><anno>Item</anno></c>:</p>
+ <marker id="system_info_allocated_areas"></marker>
<taglist>
- <tag><marker id="system_info_allocated_areas"><c>allocated_areas</c></marker></tag>
+ <tag><c>allocated_areas</c></tag>
<item>
<p>Returns a list of tuples with information about
miscellaneous allocated memory areas.</p>
- <p>Each tuple contains an atom describing type of memory as
- first element and amount of allocated memory in bytes as
- second element. In those cases when there is information
- present about allocated and used memory, a third element
- is present. This third element contains the amount of
+ <p>Each tuple contains an atom describing the type of
+ memory as first element and the amount of allocated
+ memory in bytes as second element. When information
+ about allocated and used memory is present, also a
+ third element is present, containing the amount of
used memory in bytes.</p>
<p><c>erlang:system_info(allocated_areas)</c> is intended
- for debugging, and the content is highly implementation
- dependent. The content of the results will therefore
- change when needed without prior notice.</p>
- <p><em>Note:</em> The sum of these values is <em>not</em>
+ for debugging, and the content is highly
+ implementation-dependent. The content of the results
+ therefore changes when needed without prior notice.</p>
+ <p>Notice that the sum of these values is <em>not</em>
the total amount of memory allocated by the emulator.
Some values are part of other values, and some memory
- areas are not part of the result. If you are interested
- in the total amount of memory allocated by the emulator
- see <seealso marker="#memory/0">erlang:memory/0,1</seealso>.</p>
+ areas are not part of the result. For information about
+ the total amount of memory allocated by the emulator, see
+ <seealso marker="#memory/0">erlang:memory/0,1</seealso>.</p>
</item>
- <tag><marker id="system_info_allocator"><c>allocator</c></marker></tag>
+ <tag><c>allocator</c></tag>
<item>
- <p>Returns <c>{<anno>Allocator</anno>, <anno>Version</anno>, <anno>Features</anno>, <anno>Settings</anno>}.</c></p>
- <p>Explanation:</p>
+ <marker id="system_info_allocator"></marker>
+ <p>Returns <c>{<anno>Allocator</anno>, <anno>Version</anno>,
+ <anno>Features</anno>, <anno>Settings</anno></c>, where:</p>
<list type="bulleted">
<item>
- <p><c><anno>Allocator</anno></c> corresponds to the <c>malloc()</c>
- implementation used. If <c><anno>Allocator</anno></c> equals
+ <p><c><anno>Allocator</anno></c> corresponds to the
+ <c>malloc()</c> implementation used. If
+ <c><anno>Allocator</anno></c> equals
<c>undefined</c>, the <c>malloc()</c> implementation
- used could not be identified. Currently
- <c>glibc</c> can be identified.</p>
+ used cannot be identified. <c>glibc</c> can be
+ identified.</p>
</item>
<item>
- <p><c><anno>Version</anno></c> is a list of integers (but not a
- string) representing the version of
+ <p><c><anno>Version</anno></c> is a list of integers
+ (but not a string) representing the version of
the <c>malloc()</c> implementation used.</p>
</item>
<item>
- <p><c><anno>Features</anno></c> is a list of atoms representing
- allocation features used.</p>
+ <p><c><anno>Features</anno></c> is a list of atoms
+ representing the allocation features used.</p>
</item>
<item>
- <p><c><anno>Settings</anno></c> is a list of subsystems, their
- configurable parameters, and used values. Settings
- may differ between different combinations of
+ <p><c><anno>Settings</anno></c> is a list of subsystems,
+ their configurable parameters, and used values. Settings
+ can differ between different combinations of
platforms, allocators, and allocation features.
Memory sizes are given in bytes.</p>
</item>
@@ -5568,165 +6503,169 @@ ok
<p>See also "System Flags Effecting erts_alloc" in
<seealso marker="erts:erts_alloc#flags">erts_alloc(3)</seealso>.</p>
</item>
- <tag><marker id="system_info_alloc_util_allocators"><c>alloc_util_allocators</c></marker></tag>
+ <tag><c>alloc_util_allocators</c></tag>
<item>
- <p>Returns a list of the names of all allocators
- using the ERTS internal <c>alloc_util</c> framework
- as atoms. For more information see the
- <seealso marker="erts:erts_alloc#alloc_util">"the
- alloc_util framework" section in the
- erts_alloc(3)</seealso> documentation.
- </p>
+ <marker id="system_info_alloc_util_allocators"></marker>
+ <p>Returns a list of the names of all allocators using
+ the <c>ERTS</c> internal <c>alloc_util</c> framework
+ as atoms. For more information, see Section
+ <seealso marker="erts:erts_alloc#alloc_util">"The
+ alloc_util framework" in erts_alloc(3)</seealso>.</p>
</item>
- <tag><marker id="system_info_allocator_tuple"><c>{allocator, <anno>Alloc</anno>}</c></marker></tag>
+ <tag><c>{allocator, <anno>Alloc</anno>}</c></tag>
<item>
+ <marker id="system_info_allocator_tuple"></marker>
<p>Returns information about the specified allocator.
- As of erts version 5.6.1 the return value is a list
- of <c>{instance, InstanceNo, InstanceInfo}</c> tuples
+ As from <c>ERTS</c> 5.6.1, the return value is a list
+ of <c>{instance, InstanceNo, InstanceInfo}</c> tuples,
where <c>InstanceInfo</c> contains information about
- a specific instance of the allocator. As of erts version
- 5.10.4 the returned list when calling
+ a specific instance of the allocator. As from
+ <c>ERTS</c> 5.10.4, the returned list when calling
<c>erlang:system_info({allocator, mseg_alloc})</c> also
- include an <c>{erts_mmap, _}</c> tuple as one element
- in the list.
- If <c><anno>Alloc</anno></c> is not a recognized allocator,
- <c>undefined</c> is returned. If <c><anno>Alloc</anno></c> is disabled,
+ includes an <c>{erts_mmap, _}</c> tuple as one element
+ in the list. If <c><anno>Alloc</anno></c> is not a
+ recognized allocator, <c>undefined</c> is returned.
+ If <c><anno>Alloc</anno></c> is disabled,
<c>false</c> is returned.</p>
- <p><em>Note:</em> The information returned is highly
- implementation dependent and may be changed, or removed
+ <p>Notice that the information returned is highly
+ implementation-dependent and can be changed or removed
at any time without prior notice. It was initially
intended as a tool when developing new allocators, but
- since it might be of interest for others it has been
+ as it can be of interest for others it has been
briefly documented.</p>
<p>The recognized allocators are listed in
<seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>.
After reading the <c>erts_alloc(3)</c> documentation,
the returned information
- should more or less speak for itself. But it can be worth
+ more or less speaks for itself, but it can be worth
explaining some things. Call counts are presented by two
- values. The first value is giga calls, and the second
- value is calls. <c>mbcs</c>, and <c>sbcs</c> are
- abbreviations for, respectively, multi-block carriers, and
- single-block carriers. Sizes are presented in bytes. When
- it is not a size that is presented, it is the amount of
- something. Sizes and amounts are often presented by three
- values, the first is current value, the second is maximum
- value since the last call to
- <c>erlang:system_info({allocator, Alloc})</c>, and
- the third is maximum value since the emulator was started.
- If only one value is present, it is the current value.
+ values, the first value is giga calls, and the second
+ value is calls. <c>mbcs</c> and <c>sbcs</c> denote
+ multi-block carriers, and single-block carriers,
+ respectively. Sizes are presented in bytes. When a
+ size is not presented, it is the amount of something.
+ Sizes and amounts are often presented by three values:</p>
+ <list type="bulleted">
+ <item>The first is the current value.</item>
+ <item>The second is the maximum value since the last call
+ to <c>erlang:system_info({allocator, Alloc})</c>.</item>
+ <item>The third is the maximum value since the emulator
+ was started.</item>
+ </list>
+ <p>If only one value is present, it is the current value.
<c>fix_alloc</c> memory block types are presented by two
- values. The first value is memory pool size and
- the second value used memory size.</p>
+ values. The first value is the memory pool size and
+ the second value is the used memory size.</p>
</item>
- <tag><marker id="system_info_allocator_sizes"><c>{allocator_sizes, <anno>Alloc</anno>}</c></marker></tag>
+ <tag><c>{allocator_sizes, <anno>Alloc</anno>}</c></tag>
<item>
+ <marker id="system_info_allocator_sizes"></marker>
<p>Returns various size information for the specified
allocator. The information returned is a subset of the
information returned by
- <seealso marker="#system_info_allocator_tuple">erlang:system_info({allocator, <anno>Alloc</anno>})</seealso>.
+ <seealso marker="#system_info_allocator_tuple"><c>erlang:system_info({allocator, <anno>Alloc</anno>})</c></seealso>.
</p>
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="system_info" arity="1" clause_i="10"/>
<name name="system_info" arity="1" clause_i="11"/>
+ <fsummary>Information about the CPU topology of the system.</fsummary>
<type name="cpu_topology"/>
<type name="level_entry"/>
<type_desc name="cpu_topology">
- <marker id="system_info_cpu_topology"></marker>
All <c><anno>LevelEntry</anno></c>s of a list
must contain the same <c><anno>LevelTag</anno></c>, except
on the top level where both <c>node</c> and
- <c>processor</c> <c><anno>LevelTag</anno></c>s may co-exist.
+ <c>processor</c> <c><anno>LevelTag</anno></c>s can coexist.
</type_desc>
<type_desc name="level_entry">
- <c>{<anno>LevelTag</anno>, <anno>SubLevel</anno>} == {<anno>LevelTag</anno>, [], <anno>SubLevel</anno>}</c>
+ <c>{<anno>LevelTag</anno>,
+ <anno>SubLevel</anno>} == {<anno>LevelTag</anno>, [],
+ <anno>SubLevel</anno>}</c>
</type_desc>
<type name="level_tag"/>
<type_desc name="level_tag">
- More <c><anno>LevelTag</anno></c>s may be introduced in the future.
+ More <c><anno>LevelTag</anno></c>s can be introduced in a
+ future release.
</type_desc>
<type name="sub_level"/>
<type name="info_list"/>
<type_desc name="info_list">
- The <c>info_list()</c> may be extended in the future.
+ The <c>info_list()</c> can be extended in a future release.
</type_desc>
- <fsummary>Information about the CPU topology of the system</fsummary>
<desc>
- <p>Returns various information about the
- <marker id="system_info_cpu_topology_tags">CPU topology</marker>
- of the current system
- (emulator) as specified by <c><anno>Item</anno></c>:</p>
+ <marker id="system_info_cpu_topology_tags"></marker>
+ <marker id="system_info_cpu_topology"></marker>
+ <p>Returns various information about the CPU topology of
+ the current system (emulator) as specified by
+ <c><anno>Item</anno></c>:</p>
<taglist>
<tag><c>cpu_topology</c></tag>
<item>
- <p>Returns the <c><anno>CpuTopology</anno></c> which currently is used by the
- emulator. The CPU topology is used when binding schedulers
+ <p>Returns the <c><anno>CpuTopology</anno></c> currently used by
+ the emulator. The CPU topology is used when binding schedulers
to logical processors. The CPU topology used is the
- <seealso marker="erlang#system_info_cpu_topology_defined">user
- defined CPU topology</seealso> if such exists; otherwise, the
- <seealso marker="erlang#system_info_cpu_topology_detected">automatically
- detected CPU topology</seealso> if such exists. If no CPU topology
+ <seealso marker="erlang#system_info_cpu_topology_defined">user-defined CPU topology</seealso>,
+ if such exists, otherwise the
+ <seealso marker="erlang#system_info_cpu_topology_detected">automatically detected CPU topology</seealso>,
+ if such exists. If no CPU topology
exists, <c>undefined</c> is returned.</p>
- <p><c>node</c> refers to NUMA (non-uniform memory access)
- nodes, and <c>thread</c> refers to hardware threads
- (e.g. Intels hyper-threads).</p>
- <p>A level in the <c><anno>CpuTopology</anno></c> term can be omitted if
- only one entry exists and the <c><anno>InfoList</anno></c> is empty.
- </p>
+ <p><c>node</c> refers to Non-Uniform Memory Access (NUMA)
+ nodes. <c>thread</c> refers to hardware threads
+ (for example, Intel hyper-threads).</p>
+ <p>A level in term <c><anno>CpuTopology</anno></c> can be
+ omitted if only one entry exists and
+ <c><anno>InfoList</anno></c> is empty.</p>
<p><c>thread</c> can only be a sub level to <c>core</c>.
- <c>core</c> can be a sub level to either <c>processor</c>
- or <c>node</c>. <c>processor</c> can either be on the
+ <c>core</c> can be a sub level to <c>processor</c>
+ or <c>node</c>. <c>processor</c> can be on the
top level or a sub level to <c>node</c>. <c>node</c>
- can either be on the top level or a sub level to
+ can be on the top level or a sub level to
<c>processor</c>. That is, NUMA nodes can be processor
internal or processor external. A CPU topology can
consist of a mix of processor internal and external
- NUMA nodes, as long as each logical CPU belongs to one
- and only one NUMA node. Cache hierarchy is not part of
- the <c><anno>CpuTopology</anno></c> type yet, but will be in the
- future. Other things may also make it into the CPU
- topology in the future. In other words, expect the
- <c><anno>CpuTopology</anno></c> type to change.
- </p>
- </item>
- <tag><marker id="system_info_cpu_topology_defined"><c>{cpu_topology, defined}</c></marker></tag>
- <item>
- <p>Returns the user defined <c><anno>CpuTopology</anno></c>. For more
- information see the documentation of
- the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> command
- line flag, and the documentation of the
- <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
- argument.
- </p>
- </item>
- <tag><marker id="system_info_cpu_topology_detected"><c>{cpu_topology, detected}</c></marker></tag>
- <item>
- <p>Returns the automatically detected <c><anno>CpuTopology</anno></c>. The
- emulator currently only detects the CPU topology on some newer
- Linux, Solaris, FreeBSD, and Windows systems. On Windows system with
- more than 32 logical processors the CPU topology is not detected.
- </p>
- <p>For more information see the documentation of the
- <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
- argument.
- </p>
+ NUMA nodes, as long as each logical CPU belongs to
+ <em>one</em> NUMA node. Cache hierarchy is not part of
+ the <c><anno>CpuTopology</anno></c> type, but will be in a
+ future release. Other things can also make it into the CPU
+ topology in a future release. In other words, expect the
+ <c><anno>CpuTopology</anno></c> type to change.</p>
+ </item>
+ <tag><c>{cpu_topology, defined}</c></tag>
+ <item>
+ <marker id="system_info_cpu_topology_defined"></marker>
+ <p>Returns the user-defined <c><anno>CpuTopology</anno></c>.
+ For more information, see command-line flag
+ <seealso marker="erts:erl#+sct">+sct</seealso> in
+ <c>erl(1)</c> and argument
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>.</p>
+ </item>
+ <tag><c>{cpu_topology, detected}</c></tag>
+ <item>
+ <marker id="system_info_cpu_topology_detected"></marker>
+ <p>Returns the automatically detected
+ <c><anno>CpuTopology</anno>y</c>. The
+ emulator detects the CPU topology on some newer
+ Linux, Solaris, FreeBSD, and Windows systems.
+ On Windows system with more than 32 logical processors,
+ the CPU topology is not detected.</p>
+ <p>For more information, see argument
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>.</p>
</item>
<tag><c>{cpu_topology, used}</c></tag>
<item>
- <p>Returns the <c><anno>CpuTopology</anno></c> which is used by the
- emulator. For more information see the
- documentation of the
- <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
- argument.
- </p>
+ <p>Returns <c><anno>CpuTopology</anno></c> used by the emulator.
+ For more information, see argument
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>.</p>
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="system_info" arity="1" clause_i="6"/>
<name name="system_info" arity="1" clause_i="7"/>
@@ -5776,7 +6715,19 @@ ok
<name name="system_info" arity="1" clause_i="53"/>
<name name="system_info" arity="1" clause_i="54"/>
<name name="system_info" arity="1" clause_i="55"/>
- <fsummary>Information about the system</fsummary>
+ <name name="system_info" arity="1" clause_i="56"/>
+ <name name="system_info" arity="1" clause_i="57"/>
+ <name name="system_info" arity="1" clause_i="58"/>
+ <name name="system_info" arity="1" clause_i="59"/>
+ <name name="system_info" arity="1" clause_i="60"/>
+ <name name="system_info" arity="1" clause_i="61"/>
+ <name name="system_info" arity="1" clause_i="62"/>
+ <name name="system_info" arity="1" clause_i="63"/>
+ <name name="system_info" arity="1" clause_i="64"/>
+ <name name="system_info" arity="1" clause_i="65"/>
+ <name name="system_info" arity="1" clause_i="66"/>
+ <name name="system_info" arity="1" clause_i="67"/>
+ <fsummary>Information about the system.</fsummary>
<desc>
<p>Returns various information about the current system
(emulator) as specified by <c><anno>Item</anno></c>:</p>
@@ -5793,8 +6744,7 @@ ok
Other possible return values are <c>debug</c>, <c>purify</c>,
<c>quantify</c>, <c>purecov</c>, <c>gcov</c>, <c>valgrind</c>,
<c>gprof</c>, and <c>lcnt</c>. Possible return values
- may be added and/or removed at any time without prior notice.
- </p>
+ can be added or removed at any time without prior notice.</p>
</item>
<tag><c>c_compiler_used</c></tag>
<item>
@@ -5802,26 +6752,25 @@ ok
compiling the runtime system. The first element is an
atom describing the name of the compiler, or <c>undefined</c>
if unknown. The second element is a term describing the
- version of the compiler, or <c>undefined</c> if unknown.
- </p>
+ version of the compiler, or <c>undefined</c> if unknown.</p>
</item>
<tag><c>check_io</c></tag>
<item>
<p>Returns a list containing miscellaneous information
- regarding the emulators internal I/O checking. Note,
- the content of the returned list may vary between
- platforms and over time. The only thing guaranteed is
+ about the emulators internal I/O checking. Notice that
+ the content of the returned list can vary between
+ platforms and over time. It is only guaranteed
that a list is returned.</p>
</item>
<tag><c>compat_rel</c></tag>
<item>
<p>Returns the compatibility mode of the local node as
an integer. The integer returned represents the
- Erlang/OTP release which the current emulator has been
+ Erlang/OTP release that the current emulator has been
set to be backward compatible with. The compatibility
- mode can be configured at startup by using the command
- line flag <c>+R</c>, see
- <seealso marker="erts:erl#compat_rel">erl(1)</seealso>.</p>
+ mode can be configured at startup by using command-line flag
+ <seealso marker="erts:erl#compat_rel">+R</seealso> in
+ <c>erl(1)</c>.</p>
</item>
<tag><c>cpu_topology</c></tag>
<item>
@@ -5834,176 +6783,200 @@ ok
creation of a node is stored in process identifiers, port
identifiers, and references. This makes it (to some
extent) possible to distinguish between identifiers from
- different incarnations of a node. Currently valid
- creations are integers in the range 1..3, but this may
- (probably will) change in the future. If the node is not
- alive, 0 is returned.</p>
+ different incarnations of a node. The valid
+ creations are integers in the range 1..3, but this will
+ probably change in a future release. If the node is not
+ alive, <c>0</c> is returned.</p>
</item>
<tag><c>debug_compiled</c></tag>
<item>
<p>Returns <c>true</c> if the emulator has been debug
- compiled; otherwise, <c>false</c>.
- </p>
+ compiled, otherwise <c>false</c>.</p>
+ </item>
+ <tag><c>delayed_node_table_gc</c></tag>
+ <item>
+ <marker id="system_info_delayed_node_table_gc"></marker>
+ <p>Returns the amount of time in seconds garbage collection
+ of an entry in a node table is delayed. This limit can be set
+ on startup by passing the command line flag
+ <seealso marker="erts:erl#+zdntgc">+zdntgc</seealso>
+ to <c>erl</c>. For more information see the documentation of the
+ command line flag.</p>
</item>
- <tag><marker id="system_info_dirty_cpu_schedulers"><c>dirty_cpu_schedulers</c></marker></tag>
+ <tag><c>dirty_cpu_schedulers</c></tag>
<item>
+ <marker id="system_info_dirty_cpu_schedulers"></marker>
<p>Returns the number of dirty CPU scheduler threads used by
the emulator. Dirty CPU schedulers execute CPU-bound
- native functions such as NIFs, linked-in driver code, and BIFs
- that cannot be managed cleanly by the emulator's normal schedulers.
- </p>
- <p>The number of dirty CPU scheduler threads is determined at emulator
- boot time and cannot be changed after that. The number of dirty CPU
- scheduler threads online can however be changed at any time. The number of
- dirty CPU schedulers can be set on startup by passing
- the <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> or
- <seealso marker="erts:erl#+SDPcpu">+SDPcpu</seealso> command line flags,
- see <seealso marker="erts:erl#+SDcpu">erl(1)</seealso>.
- </p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in
- order to try out the functionality.</p>
- <p>See also <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>,
+ native functions, such as NIFs, linked-in driver code,
+ and BIFs that cannot be managed cleanly by the normal
+ emulator schedulers.</p>
+ <p>The number of dirty CPU scheduler threads is determined
+ at emulator boot time and cannot be changed after that.
+ However, the number of dirty CPU scheduler threads online
+ can be changed at any time. The number of dirty CPU
+ schedulers can be set at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> or
+ <seealso marker="erts:erl#+SDPcpu">+SDPcpu</seealso> in
+ <c>erl(1)</c>.</p>
+ <p>Notice that the dirty schedulers functionality is
+ experimental. Enable support for dirty schedulers when
+ building OTP to try out the functionality.</p>
+ <p>See also
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>,
<seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>,
<seealso marker="#system_info_dirty_io_schedulers">erlang:system_info(dirty_io_schedulers)</seealso>,
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>, and
<seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.</p>
</item>
- <tag><marker id="system_info_dirty_cpu_schedulers_online"><c>dirty_cpu_schedulers_online</c></marker></tag>
- <item>
- <p>Returns the number of dirty CPU schedulers online. The return value
- satisfies the following relationship:
- <c><![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]></c>, where <c>N</c> is
- the lesser of the return values of <c>erlang:system_info(dirty_cpu_schedulers)</c> and
- <c>erlang:system_info(schedulers_online)</c>.
- </p>
- <p>The number of dirty CPU schedulers online can be set on startup by passing
- the <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> command line flag, see
- <seealso marker="erts:erl#+SDcpu">erl(1)</seealso>.
- </p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in
- order to try out the functionality.</p>
+ <tag><c>dirty_cpu_schedulers_online</c></tag>
+ <item>
+ <marker id="system_info_dirty_cpu_schedulers_online"></marker>
+ <p>Returns the number of dirty CPU schedulers online.
+ The return value satisfies
+ <c><![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]></c>,
+ where <c>N</c> is the smallest of the return values of
+ <c>erlang:system_info(dirty_cpu_schedulers)</c> and
+ <c>erlang:system_info(schedulers_online)</c>.</p>
+ <p>The number of dirty CPU schedulers online can be set at
+ startup by passing command-line flag
+ <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> in
+ <c>erl(1)</c>.</p>
+ <p>Notice that the dirty schedulers functionality is
+ experimental. Enable support for dirty schedulers when
+ building OTP to try out the functionality.</p>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">erlang:system_info(dirty_cpu_schedulers)</seealso>,
<seealso marker="#system_info_dirty_io_schedulers">erlang:system_info(dirty_io_schedulers)</seealso>,
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>, and
- <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.
- </p>
- </item>
- <tag><marker id="system_info_dirty_io_schedulers"><c>dirty_io_schedulers</c></marker></tag>
- <item>
- <p>Returns the number of dirty I/O schedulers as an integer. Dirty I/O schedulers
- execute I/O-bound native functions such as NIFs and linked-in driver code that
- cannot be managed cleanly by the emulator's normal schedulers.
- </p>
- <p>This value can be set on startup by passing
- the <seealso marker="erts:erl#+SDio">+SDio</seealso> command line flag, see
- <seealso marker="erts:erl#+SDio">erl(1)</seealso>.
- </p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in
- order to try out the functionality.</p>
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.</p>
+ </item>
+ <tag><c>dirty_io_schedulers</c></tag>
+ <item>
+ <marker id="system_info_dirty_io_schedulers"></marker>
+ <p>Returns the number of dirty I/O schedulers as an integer.
+ Dirty I/O schedulers execute I/O-bound native functions,
+ such as NIFs and linked-in driver code, which cannot be
+ managed cleanly by the normal emulator schedulers.</p>
+ <p>This value can be set at startup by passing command-line
+ argument <seealso marker="erts:erl#+SDio">+SDio</seealso>
+ in <c>erl(1)</c>.</p>
+ <p>Notice that the dirty schedulers functionality is
+ experimental. Enable support for dirty schedulers when
+ building OTP to try out the functionality.</p>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">erlang:system_info(dirty_cpu_schedulers)</seealso>,
<seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>, and
- <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.
- </p>
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.</p>
</item>
<tag><c>dist</c></tag>
<item>
<p>Returns a binary containing a string of distribution
information formatted as in Erlang crash dumps. For more
- information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
- chapter in the ERTS User's Guide.</p>
+ information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
- <tag><marker id="system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></marker></tag>
+ <tag><c>dist_buf_busy_limit</c></tag>
<item>
+ <marker id="system_info_dist_buf_busy_limit"></marker>
<p>Returns the value of the distribution buffer busy limit
- in bytes. This limit can be set on startup by passing the
- <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso> command line
- flag to <c>erl</c>.</p>
+ in bytes. This limit can be set at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso>
+ to <c>erl</c>.</p>
</item>
<tag><c>dist_ctrl</c></tag>
<item>
<p>Returns a list of tuples
- <c>{Node, ControllingEntity}</c>, one entry for each
- connected remote node. The <c><anno>Node</anno></c> is the name of the
- node and the <c><anno>ControllingEntity</anno></c> is the port or pid
- responsible for the communication to that node. More
- specifically, the <c><anno>ControllingEntity</anno></c> for nodes
- connected via TCP/IP (the normal case) is the socket
- actually used in communication with the specific node.</p>
+ <c>{<anno>Node</anno>, <anno>ControllingEntity</anno>}</c>,
+ one entry for each connected remote node.
+ <c><anno>Node</anno></c> is the node name
+ and <c><anno>ControllingEntity</anno></c> is the port or process
+ identifier responsible for the communication to that node.
+ More specifically, <c><anno>ControllingEntity</anno></c> for
+ nodes connected through TCP/IP (the normal case) is the socket
+ used in communication with the specific node.</p>
</item>
<tag><c>driver_version</c></tag>
<item>
- <p>Returns a string containing the erlang driver version
- used by the runtime system. It will be on the form
+ <p>Returns a string containing the Erlang driver version
+ used by the runtime system. It has the form
<seealso marker="erts:erl_driver#version_management">"&lt;major ver&gt;.&lt;minor ver&gt;"</seealso>.</p>
</item>
<tag><c>dynamic_trace</c></tag>
<item>
<p>Returns an atom describing the dynamic trace framework
- compiled into the virtual machine. It can currently be either
- <c>dtrace</c>, <c>systemtap</c> or <c>none</c>. For a
- commercial or standard build, this is always <c>none</c>,
- the other return values indicate a custom configuration
- (e.g. <c>./configure --with-dynamic-trace=dtrace</c>). See
- the <seealso marker="runtime_tools:dyntrace">dyntrace
- </seealso> manual page and the
+ compiled into the virtual machine. It can be
+ <c>dtrace</c>, <c>systemtap</c>, or <c>none</c>. For a
+ commercial or standard build, it is always <c>none</c>.
+ The other return values indicate a custom configuration
+ (for example, <c>./configure --with-dynamic-trace=dtrace</c>).
+ For more information about dynamic tracing, see the
+ <seealso marker="runtime_tools:dyntrace">dyntrace</seealso>
+ manual page and the
<c>README.dtrace</c>/<c>README.systemtap</c> files in the
- Erlang source code top directory for more information
- about dynamic tracing.</p>
+ Erlang source code top directory.</p>
</item>
<tag><c>dynamic_trace_probes</c></tag>
<item>
- <p>Returns a <c>boolean()</c> indicating if dynamic trace probes
- (either dtrace or systemtap) are built into the
- emulator. This can only be <c>true</c> if the virtual
- machine was built for dynamic tracing
- (i.e. <c>system_info(dynamic_trace)</c> returns
+ <p>Returns a <c>boolean()</c> indicating if dynamic trace
+ probes (<c>dtrace</c> or <c>systemtap</c>) are built into
+ the emulator. This can only be <c>true</c> if the Virtual
+ Machine was built for dynamic tracing (that is,
+ <c>system_info(dynamic_trace)</c> returns
<c>dtrace</c> or <c>systemtap</c>).</p>
</item>
+ <tag><marker id="system_info_end_time"/><c>end_time</c></tag>
+ <item><p>The last <seealso marker="#monotonic_time/0">Erlang monotonic
+ time</seealso> in <c>native</c>
+ <seealso marker="#type_time_unit">time unit</seealso> that
+ can be represented internally in the current Erlang runtime system
+ instance. The time between the
+ <seealso marker="#system_info_start_time">start time</seealso> and
+ the end time is at least a quarter of a millennium.</p></item>
<tag><c>elib_malloc</c></tag>
<item>
<p>This option will be removed in a future release.
- The return value will always be <c>false</c> since
- the elib_malloc allocator has been removed.</p>
+ The return value will always be <c>false</c>, as the
+ <c>elib_malloc</c> allocator has been removed.</p>
</item>
- <tag><marker id="system_info_eager_check_io"><c>eager_check_io</c></marker></tag>
+ <tag><marker id="system_info_eager_check_io"/><c>eager_check_io</c></tag>
<item>
<p>
- Returns the value of the <c>erl</c>
- <seealso marker="erl#+secio">+secio</seealso> command line
- flag which is either <c>true</c> or <c>false</c>. See the
+ Returns the value of the <c>erl</c> command line flag
+ <seealso marker="erl#+secio">+secio</seealso>
+ which is either <c>true</c> or <c>false</c>. See the
documentation of the command line flag for information about
the different values.
</p>
</item>
<tag><c>ets_limit</c></tag>
<item>
- <p>Returns the maximum number of ETS tables allowed. This limit
- can be increased on startup by passing the <seealso
- marker="erts:erl#+e">+e</seealso> command line flag to
- <c>erl</c> or by setting the environment variable
- <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang runtime
- system.</p>
+ <p>Returns the maximum number of ETS tables allowed. This
+ limit can be increased at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+e">+e</seealso> to
+ <c>erl(1)</c> or by setting environment variable
+ <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang
+ runtime system.</p>
</item>
<tag><c>fullsweep_after</c></tag>
<item>
- <p>Returns <c>{fullsweep_after, integer() >= 0}</c> which is the
- <c>fullsweep_after</c> garbage collection setting used
- by default. For more information see
- <c>garbage_collection</c> described below.</p>
+ <p>Returns <c>{fullsweep_after, integer() >= 0}</c>, which is
+ the <c>fullsweep_after</c> garbage collection setting used
+ by default. For more information, see
+ <c>garbage_collection</c> described in the following.</p>
</item>
<tag><c>garbage_collection</c></tag>
<item>
<p>Returns a list describing the default garbage collection
settings. A process spawned on the local node by a
- <c>spawn</c> or <c>spawn_link</c> will use these
+ <c>spawn</c> or <c>spawn_link</c> uses these
garbage collection settings. The default settings can be
- changed by use of
+ changed by using
<seealso marker="#system_flag/2">system_flag/2</seealso>.
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>
can spawn a process that does not use the default
@@ -6017,8 +6990,8 @@ ok
</item>
<tag><c>heap_type</c></tag>
<item>
- <p>Returns the heap type used by the current emulator.
- Currently only the following heap type exists:</p>
+ <p>Returns the heap type used by the current emulator. One
+ heap type exists:</p>
<taglist>
<tag><c>private</c></tag>
<item>
@@ -6033,51 +7006,51 @@ ok
<item>
<p>Returns a binary containing a string of miscellaneous
system information formatted as in Erlang crash dumps.
- For more information see the
- <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter in the ERTS
- User's Guide.</p>
+ For more information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
<tag><c>kernel_poll</c></tag>
<item>
<p>Returns <c>true</c> if the emulator uses some kind of
- kernel-poll implementation; otherwise, <c>false</c>.</p>
+ kernel-poll implementation, otherwise <c>false</c>.</p>
</item>
<tag><c>loaded</c></tag>
<item>
<p>Returns a binary containing a string of loaded module
information formatted as in Erlang crash dumps. For more
- information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
- in the ERTS User's Guide.</p>
+ information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
- <tag><marker id="logical_processors"><c>logical_processors</c></marker></tag>
+ <tag><c>logical_processors</c></tag>
<item>
+ <marker id="logical_processors"></marker>
<p>Returns the detected number of logical processors configured
- on the system. The return value is either an integer, or
- the atom <c>unknown</c> if the emulator wasn't able to
- detect logical processors configured.
- </p>
+ in the system. The return value is either an integer, or
+ the atom <c>unknown</c> if the emulator cannot
+ detect the configured logical processors.</p>
</item>
- <tag><marker id="logical_processors_available"><c>logical_processors_available</c></marker></tag>
+ <tag><c>logical_processors_available</c></tag>
<item>
- <p>Returns the detected number of logical processors available to
- the Erlang runtime system. The return value is either an
- integer, or the atom <c>unknown</c> if the emulator wasn't
- able to detect logical processors available. The number
- of logical processors available is less than or equal to
- the number of <seealso marker="#logical_processors_online">logical
- processors online</seealso>.
- </p>
+ <marker id="logical_processors_available"></marker>
+ <p>Returns the detected number of logical processors available
+ to the Erlang runtime system. The return value is either an
+ integer, or the atom <c>unknown</c> if the emulator
+ cannot detect the available logical processors. The number
+ of available logical processors is less than or equal to
+ the number of
+ <seealso marker="#logical_processors_online">logical processors online</seealso>.</p>
</item>
- <tag><marker id="logical_processors_online"><c>logical_processors_online</c></marker></tag>
+ <tag><c>logical_processors_online</c></tag>
<item>
+ <marker id="logical_processors_online"></marker>
<p>Returns the detected number of logical processors online on
the system. The return value is either an integer,
- or the atom <c>unknown</c> if the emulator wasn't able to
+ or the atom <c>unknown</c> if the emulator cannot
detect logical processors online. The number of logical
processors online is less than or equal to the number of
- <seealso marker="#logical_processors">logical processors
- configured</seealso>.
- </p>
+ <seealso marker="#logical_processors">logical processors configured</seealso>.</p>
</item>
<tag><c>machine</c></tag>
<item>
@@ -6085,27 +7058,30 @@ ok
</item>
<tag><c>min_heap_size</c></tag>
<item>
- <p>Returns <c>{min_heap_size, <anno>MinHeapSize</anno>}</c> where <c><anno>MinHeapSize</anno></c> is the current system wide
- minimum heap size for spawned processes.</p>
+ <p>Returns <c>{min_heap_size, <anno>MinHeapSize</anno>}</c>,
+ where <c><anno>MinHeapSize</anno></c> is the current
+ system-wide minimum heap size for spawned processes.</p>
</item>
<tag><c>min_bin_vheap_size</c></tag>
<item>
- <p>Returns <c>{min_bin_vheap_size, <anno>MinBinVHeapSize</anno>}</c> where <c><anno>MinBinVHeapSize</anno></c> is the current system wide
+ <p>Returns <c>{min_bin_vheap_size,
+ <anno>MinBinVHeapSize</anno>}</c>, where
+ <c><anno>MinBinVHeapSize</anno></c> is the current system-wide
minimum binary virtual heap size for spawned processes.</p>
</item>
<tag><c>modified_timing_level</c></tag>
<item>
- <p>Returns the modified timing level (an integer) if
- modified timing has been enabled; otherwise,
- <c>undefined</c>. See the <c>+T</c> command line flag
- in the documentation of the
- <seealso marker="erts:erl#+T">erl(1)</seealso>
- command for more information on modified timing.</p>
+ <p>Returns the modified timing-level (an integer) if
+ modified timing is enabled, otherwise, <c>undefined</c>.
+ For more information about modified timing, see
+ command-line flag
+ <seealso marker="erts:erl#+T">+T</seealso>
+ in <c>erl(1)</c></p>
</item>
- <tag><marker id="system_info_multi_scheduling"><c>multi_scheduling</c></marker></tag>
+ <tag><c>multi_scheduling</c></tag>
<item>
- <p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>.
- A description of the return values:</p>
+ <marker id="system_info_multi_scheduling"></marker>
+ <p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>:</p>
<taglist>
<tag><c>disabled</c></tag>
<item>
@@ -6116,182 +7092,317 @@ ok
<tag><c>blocked</c></tag>
<item>
<p>The emulator has more than one scheduler thread,
- but all scheduler threads but one have been blocked,
- i.e., only one scheduler thread will schedule
- Erlang processes and execute Erlang code.</p>
+ but all scheduler threads except one are blocked,
+ that is, only one scheduler thread schedules
+ Erlang processes and executes Erlang code.</p>
</item>
<tag><c>enabled</c></tag>
<item>
<p>The emulator has more than one scheduler thread,
- and no scheduler threads have been blocked, i.e.,
- all available scheduler threads will schedule
+ and no scheduler threads are blocked, that is,
+ all available scheduler threads schedule
Erlang processes and execute Erlang code.</p>
</item>
</taglist>
- <p>See also <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
- <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
+ <p>See also
+ <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>,
+ and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><marker id="system_info_multi_scheduling_blockers"><c>multi_scheduling_blockers</c></marker></tag>
+ <tag><c>multi_scheduling_blockers</c></tag>
<item>
- <p>Returns a list of <c><anno>PID</anno></c>s when multi-scheduling
- is blocked; otherwise, the empty list. The <c><anno>PID</anno></c>s
- in the list is <c><anno>PID</anno></c>s of the processes currently
- blocking multi-scheduling. A <c><anno>PID</anno></c> will only be
- present once in the list, even if the corresponding
+ <marker id="system_info_multi_scheduling_blockers"></marker>
+ <p>Returns a list of <c><anno>Pid</anno></c>s when
+ multi-scheduling is blocked, otherwise the empty list is
+ returned. The <c><anno>Pid</anno></c>s in the list
+ represent all the processes currently
+ blocking multi-scheduling. A <c><anno>Pid</anno></c> occurs
+ only once in the list, even if the corresponding
process has blocked multiple times.</p>
- <p>See also <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
- <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
+ <p>See also
+ <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
<tag><c>nif_version</c></tag>
<item>
- <p>Returns a string containing the erlang NIF version
- used by the runtime system. It will be on the form "&lt;major ver&gt;.&lt;minor ver&gt;".</p>
+ <p>Returns a string containing the version of the Erlang NIF interface
+ used by the runtime system. It is on the form
+ "&lt;major ver&gt;.&lt;minor ver&gt;".</p>
</item>
- <tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag>
+ <tag><c>otp_release</c></tag>
<item>
+ <marker id="system_info_otp_release"></marker>
<p>Returns a string containing the OTP release number of the
- OTP release that the currently executing ERTS application is
+ OTP release that the currently executing <c>ERTS</c> application is
part of.</p>
- <p>As of OTP release 17, the OTP release number corresponds to
- the major OTP version number. There is no
- <c>erlang:system_info()</c> argument giving the exact OTP
- version. This since the exact OTP version in the general case
- is hard to determine. For more information see
- <seealso marker="doc/system_principles:versions">the
- documentation of versions in the system principles
- guide</seealso>.</p>
- </item>
- <tag><marker id="system_info_port_parallelism"><c>port_parallelism</c></marker></tag>
- <item><p>Returns the default port parallelism scheduling hint used.
- For more information see the
- <seealso marker="erl#+spp">+spp</seealso> command line argument
- of <seealso marker="erl">erl(1)</seealso>.</p></item>
+ <p>As from OTP 17, the OTP release number corresponds to
+ the major OTP version number. No
+ <c>erlang:system_info()</c> argument gives the exact OTP
+ version. This is because the exact OTP version in the general case
+ is difficult to determine. For more information, see the description
+ of versions in <seealso marker="doc/system_principles:versions">
+ System principles</seealso> in System Documentation.</p>
+ </item>
+ <tag><marker id="system_info_os_monotonic_time_source"/><c>os_monotonic_time_source</c></tag>
+ <item>
+ <p>Returns a list containing information about the source of
+ <seealso marker="erts:time_correction#OS_Monotonic_Time">OS
+ monotonic time</seealso> that is used by the runtime system.</p>
+ <p>If <c>[]</c> is returned, no OS monotonic time is
+ available. The list contains two-tuples with <c>Key</c>s
+ as first element, and <c>Value</c>s as second element. The
+ order of these tuples is undefined. The following
+ tuples can be part of the list, but more tuples can be
+ introduced in the future:</p>
+ <taglist>
+ <tag><c>{function, Function}</c></tag>
+ <item><p><c>Function</c> is the name of the function
+ used. This tuple always exist if OS monotonic time is
+ available to the runtime system.</p></item>
+
+ <tag><c>{clock_id, ClockId}</c></tag>
+ <item><p>This tuple only exist if <c>Function</c>
+ can be used with different clocks. <c>ClockId</c>
+ corresponds to the clock identifier used when calling
+ <c>Function</c>.</p></item>
+
+ <tag><c>{resolution, OsMonotonicTimeResolution}</c></tag>
+ <item><p>Highest possible
+ <seealso marker="time_correction#Time_Resolution">resolution</seealso>
+ of current OS monotonic time source as parts per
+ second. If no resolution information can be retrieved
+ from the OS, <c>OsMonotonicTimeResolution</c> is
+ set to the resolution of the time unit of
+ <c>Function</c>s return value. That is, the actual
+ resolution can be lower than
+ <c>OsMonotonicTimeResolution</c>. Also note that
+ the resolution does not say anything about the
+ <seealso marker="time_correction#Time_Accuracy">accuracy</seealso>,
+ and whether the
+ <seealso marker="time_correction#Time_Precision">precision</seealso>
+ do align with the resolution. You do,
+ however, know that the precision is not better than
+ <c>OsMonotonicTimeResolution</c>.</p></item>
+
+ <tag><c>{extended, Extended}</c></tag>
+ <item><p><c>Extended</c> equals <c>yes</c> if
+ the range of time values has been extended;
+ otherwise, <c>Extended</c> equals <c>no</c>. The
+ range needs to be extended if <c>Function</c>
+ returns values that wrap fast. This typically
+ is the case when the return value is a 32-bit
+ value.</p></item>
+
+ <tag><c>{parallel, Parallel}</c></tag>
+ <item><p><c>Parallel</c> equals <c>yes</c> if
+ <c>Function</c> is called in parallel from multiple
+ threads. If it is not called in parallel, because
+ calls needs to be serialized, <c>Parallel</c> equals
+ <c>no</c>.</p></item>
+
+ <tag><c>{time, OsMonotonicTime}</c></tag>
+ <item><p><c>OsMonotonicTime</c> equals current OS
+ monotonic time in <c>native</c>
+ <seealso marker="#type_time_unit">time unit</seealso>.</p></item>
+ </taglist>
+ </item>
+ <tag><marker id="system_info_os_system_time_source"/><c>os_system_time_source</c></tag>
+ <item>
+ <p>Returns a list containing information about the source of
+ <seealso marker="erts:time_correction#OS_System_Time">OS
+ system time</seealso> that is used by the runtime system.</p>
+ <p>The list contains two-tuples with <c>Key</c>s
+ as first element, and <c>Value</c>s as second element. The
+ order if these tuples is undefined. The following
+ tuples can be part of the list, but more tuples can be
+ introduced in the future:</p>
+ <taglist>
+ <tag><c>{function, Function}</c></tag>
+ <item><p><c>Function</c> is the name of the funcion
+ used.</p></item>
+
+ <tag><c>{clock_id, ClockId}</c></tag>
+ <item><p>This tuple only exist if <c>Function</c>
+ can be used with different clocks. <c>ClockId</c>
+ corresponds to the clock identifier used when calling
+ <c>Function</c>.</p></item>
+
+ <tag><c>{resolution, OsSystemTimeResolution}</c></tag>
+ <item><p>Highest possible
+ <seealso marker="time_correction#Time_Resolution">resolution</seealso>
+ of current OS system time source as parts per
+ second. If no resolution information can be retrieved
+ from the OS, <c>OsSystemTimeResolution</c> is
+ set to the resolution of the time unit of
+ <c>Function</c>s return value. That is, the actual
+ resolution may be lower than
+ <c>OsSystemTimeResolution</c>. Also note that
+ the resolution does not say anything about the
+ <seealso marker="time_correction#Time_Accuracy">accuracy</seealso>,
+ and whether the
+ <seealso marker="time_correction#Time_Precision">precision</seealso>
+ do align with the resolution. You do,
+ however, know that the precision is not better than
+ <c>OsSystemTimeResolution</c>.</p></item>
+
+ <tag><c>{parallel, Parallel}</c></tag>
+ <item><p><c>Parallel</c> equals <c>yes</c> if
+ <c>Function</c> is called in parallel from multiple
+ threads. If it is not called in parallel, because
+ calls needs to be serialized, <c>Parallel</c> equals
+ <c>no</c>.</p></item>
+
+ <tag><c>{time, OsSystemTime}</c></tag>
+ <item><p><c>OsSystemTime</c> equals current OS
+ system time in <c>native</c>
+ <seealso marker="#type_time_unit">time unit</seealso>.</p></item>
+ </taglist>
+ </item>
+ <tag><c>port_parallelism</c></tag>
+ <item>
+ <marker id="system_info_port_parallelism"></marker>
+ <p>Returns the default port parallelism scheduling hint used.
+ For more information, see command-line argument
+ <seealso marker="erl#+spp">+spp</seealso> in <c>erl(1)</c>.</p></item>
<tag><marker id="system_info_port_count"/><c>port_count</c></tag>
<item>
- <p>Returns the number of ports currently existing at
- the local node as an integer. The same value as
- <c>length(erlang:ports())</c> returns, but more efficient.</p>
+ <p>Returns the number of ports currently existing at the
+ local node. The value is given as an integer. This is
+ the same value as returned by
+ <c>length(erlang:ports())</c>, but more efficient.</p>
</item>
- <tag><marker id="system_info_port_limit"><c>port_limit</c></marker></tag>
+ <tag><c>port_limit</c></tag>
<item>
+ <marker id="system_info_port_limit"></marker>
<p>Returns the maximum number of simultaneously existing
- ports at the local node as an integer. This limit
- can be configured at startup by using the
- <seealso marker="erl#+Q">+Q</seealso>
- command line flag of
- <seealso marker="erl">erl(1)</seealso>.</p>
+ ports at the local node as an integer. This limit can be
+ configured at startup by using command-line flag
+ <seealso marker="erl#+Q">+Q</seealso> in <c>erl(1)</c>.</p>
</item>
<tag><marker id="system_info_process_count"/><c>process_count</c></tag>
<item>
- <p>Returns the number of processes currently existing at
- the local node as an integer. The same value as
- <c>length(processes())</c> returns, but more efficient.</p>
+ <p>Returns the number of processes currently existing at the
+ local node. The value is given as an integer. This is
+ the same value as returned by
+ <c>length(processes())</c>, but more efficient.</p>
</item>
- <tag><marker id="system_info_process_limit"><c>process_limit</c></marker></tag>
+ <tag><c>process_limit</c></tag>
<item>
+ <marker id="system_info_process_limit"></marker>
<p>Returns the maximum number of simultaneously existing
- processes at the local node as an integer. This limit
- can be configured at startup by using the
- <seealso marker="erl#+P">+P</seealso>
- command line flag of
- <seealso marker="erl">erl(1)</seealso>.</p>
+ processes at the local node. The value is given as an
+ integer. This limit can be configured at startup by using
+ command-line flag <seealso marker="erl#+P">+P</seealso>
+ in <c>erl(1)</c>.</p>
</item>
<tag><c>procs</c></tag>
<item>
<p>Returns a binary containing a string of process and port
information formatted as in Erlang crash dumps. For more
- information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
- in the ERTS User's Guide.</p>
+ information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
- <tag><marker id="system_info_scheduler_bind_type"><c>scheduler_bind_type</c></marker></tag>
+ <tag><c>scheduler_bind_type</c></tag>
<item>
- <p>Returns information on how user has requested
+ <marker id="system_info_scheduler_bind_type"></marker>
+ <p>Returns information about how the user has requested
schedulers to be bound or not bound.</p>
- <p><em>NOTE:</em> Even though user has requested
- schedulers to be bound, they might have silently failed
- to bind. In order to inspect actual scheduler bindings call
- <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
- </p>
- <p>For more information, see
- the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso>
- command line argument, and
- <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
- </p>
- </item>
- <tag><marker id="system_info_scheduler_bindings"><c>scheduler_bindings</c></marker></tag>
- <item>
- <p>Returns information on currently used scheduler
+ <p>Notice that even though a user has requested
+ schedulers to be bound, they can silently have failed
+ to bind. To inspect the scheduler bindings, call
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.</p>
+ <p>For more information, see command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso>
+ in <c>erl(1)</c> and
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.</p>
+ </item>
+ <tag><c>scheduler_bindings</c></tag>
+ <item>
+ <marker id="system_info_scheduler_bindings"></marker>
+ <p>Returns information about the currently used scheduler
bindings.</p>
<p>A tuple of a size equal to
- <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso> is returned. The elements of the tuple are integers
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>
+ is returned. The tuple elements are integers
or the atom <c>unbound</c>. Logical processor identifiers
are represented as integers. The <c>N</c>th
element of the tuple equals the current binding for
the scheduler with the scheduler identifier equal to
- <c>N</c>. E.g., if the schedulers have been bound,
+ <c>N</c>. For example, if the schedulers are bound,
<c>element(erlang:system_info(scheduler_id),
- erlang:system_info(scheduler_bindings))</c> will return
+ erlang:system_info(scheduler_bindings))</c> returns
the identifier of the logical processor that the calling
- process is executing on.
- </p>
- <p>Note that only schedulers online can be bound to logical
+ process is executing on.</p>
+ <p>Notice that only schedulers online can be bound to logical
processors.</p>
- <p>For more information, see
- the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso>
- command line argument,
+ <p>For more information, see command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso>
+ in <c>erl(1)</c> and
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
</p>
</item>
- <tag><marker id="system_info_scheduler_id"><c>scheduler_id</c></marker></tag>
+ <tag><c>scheduler_id</c></tag>
<item>
- <p>Returns the scheduler id (<c>SchedulerId</c>) of the
+ <marker id="system_info_scheduler_id"></marker>
+ <p>Returns the scheduler ID (<c>SchedulerId</c>) of the
scheduler thread that the calling process is executing
- on. <c><anno>SchedulerId</anno></c> is a positive integer; where
- <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]></c>. See also
+ on. <c><anno>SchedulerId</anno></c> is a positive integer,
+ where
+ <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]></c>.
+ See also
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><marker id="system_info_schedulers"><c>schedulers</c></marker></tag>
+ <tag><c>schedulers</c></tag>
<item>
+ <marker id="system_info_schedulers"></marker>
<p>Returns the number of scheduler threads used by
the emulator. Scheduler threads online schedules Erlang
processes and Erlang ports, and execute Erlang code
- and Erlang linked in driver code.</p>
+ and Erlang linked-in driver code.</p>
<p>The number of scheduler threads is determined at
- emulator boot time and cannot be changed after
- that. The amount of schedulers online can
- however be changed at any time.</p>
- <p>See also <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>,
+ emulator boot time and cannot be changed later.
+ However, the number of schedulers online can
+ be changed at any time.</p>
+ <p>See also
+ <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>,
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>,
<seealso marker="#system_info_scheduler_id">erlang:system_info(scheduler_id)</seealso>,
<seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
- <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
- and <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ and
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
</item>
- <tag><marker id="system_info_schedulers_online"><c>schedulers_online</c></marker></tag>
+ <tag><c>schedulers_online</c></tag>
<item>
- <p>Returns the amount of schedulers online. The scheduler
- identifiers of schedulers online satisfy the following
- relationship:
- <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers_online)]]></c>.
- </p>
+ <marker id="system_info_schedulers_online"></marker>
+ <p>Returns the number of schedulers online. The scheduler
+ identifiers of schedulers online satisfy the relationship
+ <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers_online)]]></c>.</p>
<p>For more information, see
- <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>
and
- <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.
- </p> <name name="system_info" arity="1" clause_i="49"/>
-
+ <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.</p>
</item>
<tag><c>smp_support</c></tag>
<item>
<p>Returns <c>true</c> if the emulator has been compiled
- with smp support; otherwise, <c>false</c>.</p>
- </item>
+ with SMP support, otherwise <c>false</c> is returned.</p>
+ </item>
+ <tag><marker id="system_info_start_time"/><c>start_time</c></tag>
+ <item><p>The <seealso marker="#monotonic_time/0">Erlang monotonic
+ time</seealso> in <c>native</c>
+ <seealso marker="#type_time_unit">time unit</seealso> at the
+ time when current Erlang runtime system instance started. See also
+ <seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>.
+ </p></item>
<tag><c>system_version</c></tag>
<item>
<p>Returns a string containing version number and
- some important properties such as the number of schedulers.</p>
+ some important properties, such as the number of schedulers.</p>
</item>
<tag><c>system_architecture</c></tag>
<item>
@@ -6301,109 +7412,168 @@ ok
<tag><c>threads</c></tag>
<item>
<p>Returns <c>true</c> if the emulator has been compiled
- with thread support; otherwise, <c>false</c> is
- returned.</p>
+ with thread support, otherwise <c>false</c> is returned.</p>
</item>
- <tag><marker id="system_info_thread_pool_size"><c>thread_pool_size</c></marker></tag>
+ <tag><c>thread_pool_size</c></tag>
<item>
+ <marker id="system_info_thread_pool_size"></marker>
<p>Returns the number of async threads in the async thread
pool used for asynchronous driver calls
- (<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>)
- as an integer.</p>
+ (<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>).
+ The value is given as an integer.</p>
</item>
- <tag><marker id="system_info_tolerant_timeofday"><c>tolerant_timeofday</c></marker></tag>
+
+ <tag><c>time_correction</c></tag>
+ <item>
+ <marker id="system_info_time_correction"></marker>
+ <p>Returns a boolean value indicating whether
+ <seealso marker="time_correction#Time_Correction">time correction</seealso>
+ is enabled or not.
+ </p></item>
+ <tag><c>time_offset</c></tag>
+ <item>
+ <marker id="system_info_time_offset"></marker>
+ <p>Returns the state of the time offset:</p>
+ <taglist>
+ <tag><c>preliminary</c></tag>
+ <item><p>The time offset is preliminary, and will be changed
+ at a later time when being finalized. The preliminary time offset
+ is used during the preliminary phase of the
+ <seealso marker="time_correction#Single_Time_Warp_Mode">single
+ time warp mode</seealso>.</p></item>
+
+ <tag><c>final</c></tag>
+ <item><p>The time offset is final. This either because
+ <seealso marker="time_correction#No_Time_Warp_Mode">no
+ time warp mode</seealso> is used, or because the time
+ offset have been finalized when
+ <seealso marker="time_correction#Single_Time_Warp_Mode">single
+ time warp mode</seealso> is used.</p></item>
+
+ <tag><c>volatile</c></tag>
+ <item><p>The time offset is volatile. That is, it can
+ change at any time. This is because
+ <seealso marker="time_correction#Multi_Time_Warp_Mode">multi
+ time warp mode</seealso> is used.</p></item>
+ </taglist>
+ </item>
+ <tag><marker id="system_info_time_warp_mode"/><c>time_warp_mode</c></tag>
+ <item><p>Returns a value identifying the
+ <seealso marker="time_correction#Time_Warp_Modes">time warp
+ mode</seealso> being used:</p>
+ <taglist>
+ <tag><c>no_time_warp</c></tag>
+ <item><p>The <seealso marker="time_correction#No_Time_Warp_Mode">no
+ time warp mode</seealso> is used.</p></item>
+
+ <tag><c>single_time_warp</c></tag>
+ <item><p>The <seealso marker="time_correction#Single_Time_Warp_Mode">single
+ time warp mode</seealso> is used.</p></item>
+
+ <tag><c>multi_time_warp</c></tag>
+ <item><p>The <seealso marker="time_correction#Multi_Time_Warp_Mode">multi
+ time warp mode</seealso> is used.</p></item>
+ </taglist>
+ </item>
+ <tag><c>tolerant_timeofday</c></tag>
<item>
- <p>Returns whether compensation for sudden changes of system
- time is <c>enabled</c> or <c>disabled</c>.</p>
- <p>See also <seealso marker="erts:erl#+c">+c</seealso>
- command line flag.</p>
+ <marker id="system_info_tolerant_timeofday"></marker>
+ <p>Returns whether a pre erts-7.0 backwards compatible compensation
+ for sudden changes of system time is <c>enabled</c> or <c>disabled</c>.
+ Such compensation is <c>enabled</c> when the
+ <seealso marker="#system_info_time_offset">time offset</seealso> is
+ <c>final</c>, and
+ <seealso marker="#system_info_time_correction">time correction</seealso>
+ is enabled.</p>
</item>
<tag><c>trace_control_word</c></tag>
<item>
- <p>Returns the value of the node's trace control word.
- For more information see documentation of the function
- <c>get_tcw</c> in "Match Specifications in Erlang",
- <seealso marker="erts:match_spec#get_tcw">ERTS User's Guide</seealso>.</p>
+ <p>Returns the value of the node trace control word. For
+ more information, see function <c>get_tcw</c> in Section
+ <seealso marker="erts:match_spec#get_tcw">Match Specifications in Erlang</seealso> in the User's Guide.</p>
</item>
- <tag><marker id="update_cpu_info"><c>update_cpu_info</c></marker></tag>
+ <tag><c>update_cpu_info</c></tag>
<item>
- <p>The runtime system rereads the CPU information available and
- updates its internally stored information about the
- <seealso marker="#system_info_cpu_topology_detected">detected CPU
- topology</seealso> and the amount of logical processors
+ <marker id="update_cpu_info"></marker>
+ <p>The runtime system rereads the CPU information available
+ and updates its internally stored information about the
+ <seealso marker="#system_info_cpu_topology_detected">detected
+ CPU topology</seealso> and the number of logical processors
<seealso marker="#logical_processors">configured</seealso>,
<seealso marker="#logical_processors_online">online</seealso>, and
- <seealso marker="#logical_processors_available">available</seealso>.
- If the CPU information has changed since the last time it was read,
- the atom <c>changed</c> is returned; otherwise, the atom
- <c>unchanged</c> is returned. If the CPU information has changed
+ <seealso marker="#logical_processors_available">available</seealso>.</p>
+ <p>If the CPU information has changed since the last time
+ it was read, the atom <c>changed</c> is returned, otherwise
+ the atom <c>unchanged</c>. If the CPU information has changed,
you probably want to
- <seealso marker="#system_flag_schedulers_online">adjust the amount
- of schedulers online</seealso>. You typically want to have as
- many schedulers online as
- <seealso marker="#logical_processors_available">logical processors
- available</seealso>.
- </p>
+ <seealso marker="#system_flag_schedulers_online">adjust the
+ number of schedulers online</seealso>. You typically want
+ to have as many schedulers online as
+ <seealso marker="#logical_processors_available">logical
+ processors available</seealso>.</p>
</item>
- <tag><marker id="system_info_version"><c>version</c></marker></tag>
+ <tag><c>version</c></tag>
<item>
+ <marker id="system_info_version"></marker>
<p>Returns a string containing the version number of the
emulator.</p>
</item>
<tag><c>wordsize</c></tag>
<item>
- <p>Same as <c>{wordsize, internal}.</c></p>
+ <p>Same as <c>{wordsize, internal}</c>.</p>
</item>
<tag><c>{wordsize, internal}</c></tag>
<item>
<p>Returns the size of Erlang term words in bytes as an
- integer, i.e. on a 32-bit architecture 4 is returned,
- and on a pure 64-bit architecture 8 is returned. On a
+ integer, that is, 4 is returned on a 32-bit architecture,
+ and 8 is returned on a pure 64-bit architecture. On a
halfword 64-bit emulator, 4 is returned, as the Erlang
- terms are stored using a virtual wordsize of half the
- system's wordsize.</p>
+ terms are stored using a virtual word size of half the
+ system word size.</p>
</item>
<tag><c>{wordsize, external}</c></tag>
<item>
- <p>Returns the true wordsize of the emulator, i.e. the size
- of a pointer, in bytes as an integer. On a pure 32-bit
- architecture 4 is returned, on both a halfword and pure
+ <p>Returns the true word size of the emulator, that is,
+ the size of a pointer. The value is given in bytes
+ as an integer. On a pure 32-bit architecture, 4 is
+ returned. On both a half word and on a pure
64-bit architecture, 8 is returned.</p>
</item>
</taglist>
<note>
- <p>The <c>scheduler</c> argument has changed name to
- <c>scheduler_id</c>. This in order to avoid mixup with
- the <c>schedulers</c> argument. The <c>scheduler</c>
- argument was introduced in ERTS version 5.5 and renamed
- in ERTS version 5.5.1.</p>
+ <p>Argument <c>scheduler</c> has changed name to
+ <c>scheduler_id</c> to avoid mix up with argument
+ <c>schedulers</c>. Argument <c>scheduler</c> was
+ introduced in <c>ERTS</c> 5.5 and renamed in
+ <c>ERTS</c> 5.5.1.</p>
</note>
</desc>
</func>
<func>
<name name="system_monitor" arity="0"/>
+ <fsummary>Current system performance monitoring settings.</fsummary>
<type name="system_monitor_option"/>
- <fsummary>Current system performance monitoring settings</fsummary>
<desc>
<p>Returns the current system monitoring settings set by
<seealso marker="#system_monitor/2">erlang:system_monitor/2</seealso>
- as <c>{<anno>MonitorPid</anno>, <anno>Options</anno>}</c>, or <c>undefined</c> if there
- are no settings. The order of the options may be different
+ as <c>{<anno>MonitorPid</anno>, <anno>Options</anno>}</c>,
+ or <c>undefined</c> if there
+ are no settings. The order of the options can be different
from the one that was set.</p>
</desc>
</func>
<func>
<name name="system_monitor" arity="1"/>
+ <fsummary>Sets or clears system performance monitoring options.</fsummary>
<type name="system_monitor_option"/>
- <fsummary>Set or clear system performance monitoring options</fsummary>
<desc>
- <p>When called with the argument <c>undefined</c>, all
+ <p>When called with argument <c>undefined</c>, all
system performance monitoring settings are cleared.</p>
- <p>Calling the function with <c>{<anno>MonitorPid</anno>, <anno>Options</anno>}</c> as
- argument, is the same as calling
- <seealso marker="#system_monitor/2">erlang:system_monitor(<anno>MonitorPid</anno>, <anno>Options</anno>)</seealso>.</p>
+ <p>Calling the function with <c>{<anno>MonitorPid</anno>,
+ <anno>Options</anno>}</c> as argument is the same as calling
+ <seealso marker="#system_monitor/2"><c>erlang:system_monitor(<anno>MonitorPid</anno>, <anno>Options</anno>)</c></seealso>.</p>
<p>Returns the previous system monitor settings just like
<seealso marker="#system_monitor/0">erlang:system_monitor/0</seealso>.</p>
</desc>
@@ -6411,102 +7581,101 @@ ok
<func>
<name name="system_monitor" arity="2"/>
+ <fsummary>Sets system performance monitoring options.</fsummary>
<type name="system_monitor_option"/>
- <fsummary>Set system performance monitoring options</fsummary>
<desc>
- <p>Sets system performance monitoring options. <c><anno>MonitorPid</anno></c>
- is a local pid that will receive system monitor messages, and
- the second argument is a list of monitoring options:</p>
+ <p>Sets the system performance monitoring options.
+ <c><anno>MonitorPid</anno></c> is a local process identifier (pid)
+ receiving system monitor messages. The
+ second argument is a list of monitoring options:</p>
<taglist>
<tag><c>{long_gc, Time}</c></tag>
<item>
<p>If a garbage collection in the system takes at least
- <c>Time</c> wallclock milliseconds, a message
+ <c>Time</c> wall clock milliseconds, a message
<c>{monitor, GcPid, long_gc, Info}</c> is sent to
- <c><anno>MonitorPid</anno></c>. <c>GcPid</c> is the pid that was
- garbage collected and <c>Info</c> is a list of two-element
- tuples describing the result of the garbage collection.
- One of the tuples is <c>{timeout, GcTime}</c> where
- <c>GcTime</c> is the actual time for the garbage
+ <c><anno>MonitorPid</anno></c>. <c>GcPid</c> is the pid that
+ was garbage collected. <c>Info</c> is a list of two-element
+ tuples describing the result of the garbage collection.</p>
+ <p>One of the tuples is <c>{timeout, GcTime}</c>, where
+ <c>GcTime</c> is the time for the garbage
collection in milliseconds. The other tuples are
- tagged with <c>heap_size</c>, <c>heap_block_size</c>,
- <c>stack_size</c>, <c>mbuf_size</c>, <c>old_heap_size</c>,
- and <c>old_heap_block_size</c>. These tuples are
- explained in the documentation of the
- <seealso marker="#gc_start">gc_start</seealso>
- trace message (see
- <seealso marker="#trace/3">erlang:trace/3</seealso>).
- New tuples may be added, and the order of the tuples in
- the <c>Info</c> list may be changed at any time without prior
- notice.
- </p>
+ tagged with <c>heap_size</c>, <c>heap_block_size</c>
+ <c>stack_size</c>, <c>mbuf_size</c>, <c>old_heap_size</c>,
+ and <c>old_heap_block_size</c>. These tuples are
+ explained in the description of trace message
+ <seealso marker="#gc_start">gc_start</seealso> (see
+ <seealso marker="#trace/3">erlang:trace/3</seealso>).
+ New tuples can be added, and the order of the tuples in
+ the <c>Info</c> list can be changed at any time without
+ prior notice.</p>
</item>
<tag><c>{long_schedule, Time}</c></tag>
<item>
- <p>If a process or port in the system runs uninterrupted
+ <p>If a process or port in the system runs uninterrupted
for at least <c>Time</c> wall clock milliseconds, a
message <c>{monitor, PidOrPort, long_schedule, Info}</c>
is sent to <c>MonitorPid</c>. <c>PidOrPort</c> is the
- process or port that was running and <c>Info</c> is a
- list of two-element tuples describing the event. In case
- of a <c>pid()</c>, the tuples <c>{timeout, Millis}</c>,
- <c>{in, Location}</c> and <c>{out, Location}</c> will be
+ process or port that was running. <c>Info</c> is a
+ list of two-element tuples describing the event.</p>
+ <p>If a <c>pid()</c>, the tuples <c>{timeout, Millis}</c>,
+ <c>{in, Location}</c>, and <c>{out, Location}</c> are
present, where <c>Location</c> is either an MFA
(<c>{Module, Function, Arity}</c>) describing the
function where the process was scheduled in/out, or the
- atom <c>undefined</c>. In case of a <c>port()</c>, the
+ atom <c>undefined</c>.</p>
+ <p>If a <c>port()</c>, the
tuples <c>{timeout, Millis}</c> and <c>{port_op,Op}</c>
- will be present. <c>Op</c> will be one of <c>proc_sig</c>,
+ are present. <c>Op</c> is one of <c>proc_sig</c>,
<c>timeout</c>, <c>input</c>, <c>output</c>,
- <c>event</c> or <c>dist_cmd</c>, depending on which
- driver callback was executing. <c>proc_sig</c> is an
- internal operation and should never appear, while the
+ <c>event</c>, or <c>dist_cmd</c>, depending on which
+ driver callback was executing.</p>
+ <p><c>proc_sig</c> is an
+ internal operation and is never to appear, while the
others represent the corresponding driver callbacks
<c>timeout</c>, <c>ready_input</c>, <c>ready_output</c>,
- <c>event</c> and finally <c>outputv</c> (when the port
- is used by distribution). The <c>Millis</c> value in
- the <c>timeout</c> tuple will tell you the actual
- uninterrupted execution time of the process or port,
- which will always be <c>&gt;=</c> the <c>Time</c> value
- supplied when starting the trace. New tuples may be
- added to the <c>Info</c> list in the future, and the
- order of the tuples in the list may be changed at any
- time without prior notice.
- </p>
- <p>This can be used to detect problems with NIF's or
- drivers that take too long to execute. Generally, 1 ms
- is considered a good maximum time for a driver callback
- or a NIF. However, a time sharing system should usually
- consider everything below 100 ms as "possible" and
- fairly "normal". Schedule times above that might however
- indicate swapping or a NIF/driver that is
- misbehaving. Misbehaving NIF's and drivers could cause
- bad resource utilization and bad overall performance of
- the system.</p>
+ <c>event</c>, and <c>outputv</c> (when the port
+ is used by distribution). Value <c>Millis</c> in
+ the <c>timeout</c> tuple informs about the
+ uninterrupted execution time of the process or port, which
+ always is equal to or higher than the <c>Time</c> value
+ supplied when starting the trace. New tuples can be
+ added to the <c>Info</c> list in a future release. The
+ order of the tuples in the list can be changed at any
+ time without prior notice.</p>
+ <p>This can be used to detect problems with NIFs or
+ drivers that take too long to execute. 1 ms is
+ considered a good maximum time for a driver callback
+ or a NIF. However, a time-sharing system is usually to
+ consider everything below 100 ms as "possible" and
+ fairly "normal". However, longer schedule times can
+ indicate swapping or a misbehaving NIF/driver.
+ Misbehaving NIFs and drivers can cause bad resource
+ utilization and bad overall system performance.</p>
</item>
<tag><c>{large_heap, Size}</c></tag>
<item>
<p>If a garbage collection in the system results in
the allocated size of a heap being at least <c>Size</c>
words, a message <c>{monitor, GcPid, large_heap, Info}</c>
- is sent to <c><anno>MonitorPid</anno></c>. <c>GcPid</c> and <c>Info</c>
- are the same as for <c>long_gc</c> above, except that
- the tuple tagged with <c>timeout</c> is not present.
- <em>Note</em>: As of erts version 5.6 the monitor message
- is sent if the sum of the sizes of all memory blocks allocated
- for all heap generations is equal to or larger than <c>Size</c>.
- Previously the monitor message was sent if the memory block
- allocated for the youngest generation was equal to or larger
- than <c>Size</c>.
- </p>
+ is sent to <c><anno>MonitorPid</anno></c>.
+ <c>GcPid</c> and <c>Info</c>
+ are the same as for <c>long_gc</c> earlier, except that
+ the tuple tagged with <c>timeout</c> is not present.</p>
+ <p>As of <c>ERTS</c> 5.6, the monitor message is sent
+ if the sum of the sizes of all memory blocks allocated
+ for all heap generations is equal to or higher than <c>Size</c>.
+ Previously the monitor message was sent if the memory block
+ allocated for the youngest generation was equal to or higher
+ than <c>Size</c>.</p>
</item>
<tag><c>busy_port</c></tag>
<item>
<p>If a process in the system gets suspended because it
sends to a busy port, a message
<c>{monitor, SusPid, busy_port, Port}</c> is sent to
- <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid that got
- suspended when sending to <c>Port</c>.</p>
+ <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid
+ that got suspended when sending to <c>Port</c>.</p>
</item>
<tag><c>busy_dist_port</c></tag>
<item>
@@ -6514,8 +7683,8 @@ ok
sends to a process on a remote node whose inter-node
communication was handled by a busy port, a message
<c>{monitor, SusPid, busy_dist_port, Port}</c> is sent to
- <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid that got
- suspended when sending through the inter-node
+ <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid
+ that got suspended when sending through the inter-node
communication port <c>Port</c>.</p>
</item>
</taglist>
@@ -6524,85 +7693,152 @@ ok
<note>
<p>If a monitoring process gets so large that it itself
starts to cause system monitor messages when garbage
- collecting, the messages will enlarge the process's
+ collecting, the messages enlarge the process
message queue and probably make the problem worse.</p>
<p>Keep the monitoring process neat and do not set the system
monitor limits too tight.</p>
</note>
- <p>Failure: <c>badarg</c> if <c><anno>MonitorPid</anno></c> does not exist or is not a local process.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>MonitorPid</anno></c> does not exist.</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>MonitorPid</anno></c> is not a local process.</item>
+ </taglist>
</desc>
</func>
<func>
<name name="system_profile" arity="0"/>
+ <fsummary>Current system profiling settings.</fsummary>
<type name="system_profile_option"/>
- <fsummary>Current system profiling settings</fsummary>
<desc>
<p>Returns the current system profiling settings set by
<seealso marker="#system_profile/2">erlang:system_profile/2</seealso>
- as <c>{<anno>ProfilerPid</anno>, <anno>Options</anno>}</c>, or <c>undefined</c> if there
- are no settings. The order of the options may be different
+ as <c>{<anno>ProfilerPid</anno>, <anno>Options</anno>}</c>,
+ or <c>undefined</c> if there
+ are no settings. The order of the options can be different
from the one that was set.</p>
</desc>
</func>
<func>
<name name="system_profile" arity="2"/>
+ <fsummary>Current system profiling settings.</fsummary>
<type name="system_profile_option"/>
- <fsummary>Current system profiling settings</fsummary>
<desc>
<p>Sets system profiler options. <c><anno>ProfilerPid</anno></c>
- is a local pid or port that will receive profiling messages. The
- receiver is excluded from all profiling.
+ is a local process identifier (pid) or port receiving profiling
+ messages. The receiver is excluded from all profiling.
The second argument is a list of profiling options:</p>
<taglist>
<tag><c>exclusive</c></tag>
<item>
- <p>
- If a synchronous call to a port from a process is done, the
+ <p>If a synchronous call to a port from a process is done, the
calling process is considered not runnable during the call
runtime to the port. The calling process is notified as
- <c>inactive</c> and subsequently <c>active</c> when the port
- callback returns.
- </p>
+ <c>inactive</c>, and later <c>active</c> when the port
+ callback returns.</p>
+ </item>
+ <tag><c>monotonic_timestamp</c></tag>
+ <item>
+ <p>Timestamps in profile messages will use
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>. The time-stamp (Ts) has the same
+ format and value as produced by
+ <c>erlang:monotonic_time(nano_seconds)</c>.</p>
</item>
<tag><c>runnable_procs</c></tag>
<item>
- <p>If a process is put into or removed from the run queue a message,
- <c>{profile, Pid, State, Mfa, Ts}</c>, is sent to
- <c><anno>ProfilerPid</anno></c>. Running processes that is reinserted into the
- run queue after having been preemptively scheduled out will not trigger this
- message.
- </p>
+ <p>If a process is put into or removed from the run queue, a
+ message, <c>{profile, Pid, State, Mfa, Ts}</c>, is sent to
+ <c><anno>ProfilerPid</anno></c>. Running processes that
+ are reinserted into the run queue after having been
+ preempted do not trigger this message.</p>
</item>
<tag><c>runnable_ports</c></tag>
<item>
- <p>If a port is put into or removed from the run queue a message,
- <c>{profile, Port, State, 0, Ts}</c>, is sent to
- <c><anno>ProfilerPid</anno></c>.
- </p>
+ <p>If a port is put into or removed from the run queue, a
+ message, <c>{profile, Port, State, 0, Ts}</c>, is sent to
+ <c><anno>ProfilerPid</anno></c>.</p>
</item>
<tag><c>scheduler</c></tag>
<item>
- <p>If a scheduler is put to sleep or awoken a message,
- <c>{profile, scheduler, Id, State, NoScheds, Ts}</c>, is sent
- to <c><anno>ProfilerPid</anno></c>.
- </p>
+ <p>If a scheduler is put to sleep or awoken, a message,
+ <c>{profile, scheduler, Id, State, NoScheds, Ts}</c>, is
+ sent to <c><anno>ProfilerPid</anno></c>.</p>
+ </item>
+ <tag><c>strict_monotonic_timestamp</c></tag>
+ <item>
+ <p>Timestamps in profile messages will consisting of
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> and a monotonically increasing
+ integer. The time-stamp (Ts) has the same format and value
+ as produced by <c>{erlang:monotonic_time(nano_seconds),
+ erlang:unique_integer([monotonic])}</c>.</p>
+ </item>
+ <tag><c>timestamp</c></tag>
+ <item>
+ <p>Timestamps in profile messages will include a
+ time-stamp (Ts) that has the same form as returned by
+ <c>erlang:now()</c>. This is also the default if no
+ timestamp flag is given. If <c>cpu_timestamp</c> has
+ been enabled via <c>erlang:trace/3</c>, this will also
+ effect the timestamp produced in profiling messages
+ when <c>timestamp</c> flag is enabled.</p>
</item>
</taglist>
- <note><p><c>erlang:system_profile</c> is considered experimental and
- its behaviour may change in the future.</p>
+ <note><p><c>erlang:system_profile</c> is considered experimental
+ and its behavior can change in a future release.</p>
</note>
</desc>
</func>
+ <func>
+ <name name="system_time" arity="0"/>
+ <fsummary>Current Erlang system time</fsummary>
+ <desc>
+ <p>Returns current
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
+ in <c>native</c>
+ <seealso marker="#type_time_unit">time unit</seealso>.</p>
+ <p>Calling <c>erlang:system_time()</c> is equivalent to:
+ <seealso marker="#monotonic_time/0"><c>erlang:monotonic_time()</c></seealso><c>
+ +
+ </c><seealso marker="#time_offset/0"><c>erlang:time_offset()</c></seealso>.</p>
+
+ <note><p>This time is <em>not</em> a monotonically increasing time
+ in the general case. For more information, see the documentation of
+ <seealso marker="time_correction#Time_Warp_Modes">time warp modes</seealso> in the
+ ERTS User's Guide.</p></note>
+ </desc>
+ </func>
+ <func>
+ <name name="system_time" arity="1"/>
+ <fsummary>Current Erlang system time</fsummary>
+ <desc>
+ <p>Returns current
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
+ converted into the <c><anno>Unit</anno></c> passed as argument.</p>
+
+ <p>Calling <c>erlang:system_time(<anno>Unit</anno>)</c> is equivalent to:
+ <seealso marker="#convert_time_unit/3"><c>erlang:convert_time_unit</c></seealso><c>(</c><seealso marker="#system_time/0"><c>erlang:system_time()</c></seealso><c>,
+ native, <anno>Unit</anno>)</c>.</p>
+
+ <note><p>This time is <em>not</em> a monotonically increasing time
+ in the general case. For more information, see the documentation of
+ <seealso marker="time_correction#Time_Warp_Modes">time warp modes</seealso> in the
+ ERTS User's Guide.</p></note>
+ </desc>
+ </func>
<func>
<name name="term_to_binary" arity="1"/>
- <fsummary>Encode a term to an Erlang external term format binary</fsummary>
+ <fsummary>Encodes a term to an Erlang external term format binary.</fsummary>
<desc>
- <p>Returns a binary data object which is the result of encoding
- <c><anno>Term</anno></c> according to the Erlang external term format.</p>
- <p>This can be used for a variety of purposes, for example
+ <p>Returns a binary data object that is the result of encoding
+ <c><anno>Term</anno></c> according to the Erlang external
+ term format.</p>
+ <p>This can be used for various purposes, for example,
writing a term to a file in an efficient way, or sending an
Erlang term to some type of communications channel not
supported by distributed Erlang.</p>
@@ -6610,247 +7846,372 @@ ok
<seealso marker="#binary_to_term/1">binary_to_term/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="term_to_binary" arity="2"/>
- <fsummary>Encode a term to en Erlang external term format binary</fsummary>
- <desc>
- <p>Returns a binary data object which is the result of encoding
- <c><anno>Term</anno></c> according to the Erlang external term format.</p>
- <p>If the option <c>compressed</c> is provided, the external
- term format will be compressed. The compressed format is
- automatically recognized by <c>binary_to_term/1</c> in R7B and later.</p>
- <p>It is also possible to specify a compression level by giving
- the option <c>{compressed, <anno>Level</anno>}</c>, where <c><anno>Level</anno></c> is an
- integer from 0 through 9. <c>0</c> means that no compression
- will be done (it is the same as not giving any <c>compressed</c> option);
- <c>1</c> will take the least time but may not compress as well as
- the higher levels; <c>9</c> will take the most time and may produce
- a smaller result. Note the "mays" in the preceding sentence; depending
- on the input term, level 9 compression may or may not produce a smaller
- result than level 1 compression.</p>
- <p>Currently, <c>compressed</c> gives the same result as
- <c>{compressed, 6}</c>.</p>
- <p>The option <c>{minor_version, <anno>Version</anno>}</c> can be use to control
- some details of the encoding. This option was
- introduced in R11B-4. Currently, the allowed values for <c><anno>Version</anno></c>
- are <c>0</c> and <c>1</c>.</p>
- <p><c>{minor_version, 1}</c> is since 17.0 the default, it forces any floats in
- the term to be encoded
- in a more space-efficient and exact way (namely in the 64-bit IEEE format,
- rather than converted to a textual representation). <c>binary_to_term/1</c>
- in R11B-4 and later is able decode this representation.</p>
- <p><c>{minor_version, 0}</c> meaning that floats
- will be encoded using a textual representation; this option is useful if
- you want to ensure that releases prior to R11B-4 can decode resulting
+ <fsummary>Encodes a term to en Erlang external term format binary.</fsummary>
+ <desc>
+ <p>Returns a binary data object that is the result of encoding
+ <c><anno>Term</anno></c> according to the Erlang external
+ term format.</p>
+ <p>If option <c>compressed</c> is provided, the external term
+ format is compressed. The compressed format is automatically
+ recognized by <c>binary_to_term/1</c> as from Erlang R7B.</p>
+ <p>A compression level can be specified by giving option
+ <c>{compressed, <anno>Level</anno>}</c>.
+ <c><anno>Level</anno></c> is an integer
+ with range 0..9, where:</p>
+ <list type="bulleted">
+ <item><c>0</c> - No compression is done (it is the same as
+ giving no <c>compressed</c> option).</item>
+ <item><c>1</c> - Takes least time but may not compress
+ as well as the higher levels.</item>
+ <item><c>6</c> - Default level when option <c>compressed</c>
+ is provided.</item>
+ <item><c>9</c> - Takes most time and tries to produce a smaller
+ result. Notice "tries" in the preceding sentence; depending
+ on the input term, level 9 compression either does or does
+ not produce a smaller result than level 1 compression.</item>
+ </list>
+ <p>Option <c>{minor_version, <anno>Version</anno>}</c>
+ can be used to control
+ some encoding details. This option was introduced in OTP R11B-4.
+ The valid values for <c><anno>Version</anno></c> are
+ <c>0</c> and <c>1</c>.</p>
+ <p>As from OTP 17.0, <c>{minor_version, 1}</c> is the default. It
+ forces any floats in the term to be encoded in a more
+ space-efficient and exact way (namely in the 64-bit IEEE format,
+ rather than converted to a textual representation).</p>
+ <p>As from OTP R11B-4, <c>binary_to_term/1</c> can decode this
+ representation.</p>
+ <p><c>{minor_version, 0}</c> means that floats are encoded
+ using a textual representation. This option is useful to
+ ensure that releases before OTP R11B-4 can decode resulting
binary.</p>
<p>See also
<seealso marker="#binary_to_term/1">binary_to_term/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="throw" arity="1"/>
- <fsummary>Throw an exception</fsummary>
+ <fsummary>Throws an exception.</fsummary>
<desc>
<p>A non-local return from a function. If evaluated within a
- <c>catch</c>, <c>catch</c> will return the value <c><anno>Any</anno></c>.</p>
+ <c>catch</c>, <c>catch</c> returns value <c><anno>Any</anno></c>.</p>
+ <p>Example:</p>
<pre>
> <input>catch throw({hello, there}).</input>
{hello,there}</pre>
<p>Failure: <c>nocatch</c> if not evaluated within a catch.</p>
</desc>
</func>
+
<func>
<name name="time" arity="0"/>
- <fsummary>Current time</fsummary>
+ <fsummary>Current time.</fsummary>
<desc>
<p>Returns the current time as <c>{Hour, Minute, Second}</c>.</p>
- <p>The time zone and daylight saving time correction depend on
+ <p>The time zone and Daylight Saving Time correction depend on
the underlying OS.</p>
+ <p>Example:</p>
<pre>
> <input>time().</input>
{9,42,44}</pre>
</desc>
</func>
+
+ <func>
+ <name name="time_offset" arity="0"/>
+ <fsummary>Current time offset</fsummary>
+ <desc>
+ <p>Returns the current time offset between
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso>
+ and
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso> in
+ <c>native</c> <seealso marker="#type_time_unit">time unit</seealso>.
+ Current time offset added to an Erlang monotonic time gives
+ corresponding Erlang system time.</p>
+
+ <p>The time offset may or may not change during operation depending
+ on the <seealso marker="time_correction#Time_Warp_Modes">time
+ warp mode</seealso> used.</p>
+
+ <note>
+ <p>A change in time offset may be observed at slightly
+ different points in time by different processes.</p>
+
+ <p>If the runtime system is in
+ <seealso marker="time_correction#Multi_Time_Warp_Mode">multi
+ time warp mode</seealso>, the time offset will be changed when
+ the runtime system detects that the
+ <seealso marker="time_correction#OS_System_Time">OS system
+ time</seealso> has changed. The runtime system will, however,
+ not detect this immediately when it happens. A task checking
+ the time offset is scheduled to execute at least once a minute,
+ so under normal operation this should be detected within a
+ minute, but during heavy load it might take longer time.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name name="time_offset" arity="1"/>
+ <fsummary>Current time offset</fsummary>
+ <desc>
+ <p>Returns the current time offset between
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso>
+ and
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
+ converted into the <c><anno>Unit</anno></c> passed as argument.</p>
+
+ <p>Same as calling
+ <seealso marker="#convert_time_unit/3"><c>erlang:convert_time_unit</c></seealso><c>(</c><seealso marker="#time_offset/0"><c>erlang:time_offset()</c></seealso><c>, native, <anno>Unit</anno>)</c>
+ however optimized for commonly used <c><anno>Unit</anno></c>s.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="timestamp" arity="0"/>
+ <fsummary>Current Erlang System time</fsummary>
+ <type name="timestamp"/>
+ <desc>
+ <p>Returns current
+ <seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
+ on the format <c>{MegaSecs, Secs, MicroSecs}</c>. This format is
+ the same as <seealso marker="kernel:os#timestamp/0"><c>os:timestamp/0</c></seealso>
+ and the deprecated <seealso marker="#now/0"><c>erlang:now/0</c></seealso>
+ uses. The reason for the existence of <c>erlang:timestamp()</c> is
+ purely to simplify usage for existing code that assumes this timestamp
+ format. Current Erlang system time can more efficiently be retrieved in
+ the time unit of your choice using
+ <seealso marker="#system_time/1"><c>erlang:system_time/1</c></seealso>.</p>
+
+ <p>The <c>erlang:timestamp()</c> BIF is equivalent to:</p><code type="none">
+timestamp() ->
+ ErlangSystemTime = erlang:system_time(micro_seconds),
+ MegaSecs = ErlangSystemTime div 1000000000000,
+ Secs = ErlangSystemTime div 1000000 - MegaSecs*1000000,
+ MicroSecs = ErlangSystemTime rem 1000000,
+ {MegaSecs, Secs, MicroSecs}.</code>
+ <p>It, however, uses a native implementation which does
+ not build garbage on the heap and with slightly better
+ performance.</p>
+
+ <note><p>This time is <em>not</em> a monotonically increasing time
+ in the general case. For more information, see the documentation of
+ <seealso marker="time_correction#Time_Warp_Modes">time warp modes</seealso> in the
+ ERTS User's Guide.</p></note>
+ </desc>
+
+ </func>
<func>
<name name="tl" arity="1"/>
- <fsummary>Tail of a list</fsummary>
+ <fsummary>Tail of a list.</fsummary>
<desc>
- <p>Returns the tail of <c><anno>List</anno></c>, that is, the list minus
- the first element.</p>
+ <p>Returns the tail of <c><anno>List</anno></c>, that is,
+ the list minus the first element, for example:</p>
<pre>
> <input>tl([geesties, guilies, beasties]).</input>
[guilies, beasties]</pre>
<p>Allowed in guard tests.</p>
- <p>Failure: <c>badarg</c> if <c><anno>List</anno></c> is the empty list [].</p>
+ <p>Failure: <c>badarg</c> if <c><anno>List</anno></c>
+ is the empty list <c>[]</c>.</p>
</desc>
</func>
+
<func>
<name name="trace" arity="3"/>
+ <fsummary>Sets trace flags for a process or processes.</fsummary>
<type name="trace_flag"/>
- <fsummary>Set trace flags for a process or processes</fsummary>
<desc>
<p>Turns on (if <c><anno>How</anno> == true</c>) or off (if
- <c><anno>How</anno> == false</c>) the trace flags in <c><anno>FlagList</anno></c> for
- the process or processes represented by <c><anno>PidSpec</anno></c>.</p>
- <p><c><anno>PidSpec</anno></c> is either a pid for a local process, or one of
- the following atoms:</p>
+ <c><anno>How</anno> == false</c>) the trace flags in
+ <c><anno>FlagList</anno></c> for
+ the process or processes represented by
+ <c><anno>PidSpec</anno></c>.</p>
+ <p><c><anno>PidSpec</anno></c> is either a process identifier
+ (pid) for a local process, or one of the following atoms:</p>
<taglist>
<tag><c>existing</c></tag>
<item>
- <p>All processes currently existing.</p>
+ <p>All currently existing processes.</p>
</item>
<tag><c>new</c></tag>
<item>
- <p>All processes that will be created in the future.</p>
+ <p>All processes that are created in the future.</p>
</item>
<tag><c>all</c></tag>
<item>
<p>All currently existing processes and all processes that
- will be created in the future.</p>
+ are created in the future.</p>
</item>
</taglist>
- <p><c><anno>FlagList</anno></c> can contain any number of the following
- flags (the "message tags" refers to the list of messages
- following below):</p>
+ <p><c><anno>FlagList</anno></c> can contain any number of the
+ following flags (the "message tags" refers to the list of
+ <seealso marker="#trace_3_trace_messages">trace messages</seealso>):</p>
<taglist>
<tag><c>all</c></tag>
<item>
- <p>Set all trace flags except <c>{tracer, Tracer}</c> and
- <c>cpu_timestamp</c> that are in their nature different
+ <p>Sets all trace flags except <c>{tracer, Tracer}</c> and
+ <c>cpu_timestamp</c>, which are in their nature different
than the others.</p>
</item>
<tag><c>send</c></tag>
<item>
- <p>Trace sending of messages.</p>
- <p>Message tags: <c>send</c>,
+ <p>Traces sending of messages.</p>
+ <p>Message tags: <c>send</c> and
<c>send_to_non_existing_process</c>.</p>
</item>
<tag><c>'receive'</c></tag>
<item>
- <p>Trace receiving of messages.</p>
+ <p>Traces receiving of messages.</p>
<p>Message tags: <c>'receive'</c>.</p>
</item>
<tag><c>procs</c></tag>
<item>
- <p>Trace process related events.</p>
+ <p>Traces process-related events.</p>
<p>Message tags: <c>spawn</c>, <c>exit</c>,
<c>register</c>, <c>unregister</c>, <c>link</c>,
- <c>unlink</c>, <c>getting_linked</c>,
+ <c>unlink</c>, <c>getting_linked</c>, and
<c>getting_unlinked</c>.</p>
</item>
<tag><c>call</c></tag>
<item>
- <p>Trace certain function calls. Specify which function
+ <p>Traces certain function calls. Specify which function
calls to trace by calling
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
- <p>Message tags: <c>call</c>, <c>return_from</c>.</p>
+ <p>Message tags: <c>call</c> and <c>return_from</c>.</p>
</item>
<tag><c>silent</c></tag>
<item>
- <p>Used in conjunction with the <c>call</c> trace flag.
- The <c>call</c>, <c>return_from</c> and <c>return_to</c>
- trace messages are inhibited if this flag is set,
- but if there are match specs they are executed as normal.</p>
+ <p>Used with the <c>call</c> trace flag.
+ The <c>call</c>, <c>return_from</c>, and <c>return_to</c>
+ trace messages are inhibited if this flag is set, but they
+ are executed as normal if there are match specifications.</p>
<p>Silent mode is inhibited by executing
<c>erlang:trace(_, false, [silent|_])</c>,
- or by a match spec executing the <c>{silent, false}</c>
- function.</p>
+ or by a match specification executing the function
+ <c>{silent, false}</c>.</p>
<p>The <c>silent</c> trace flag facilitates setting up
a trace on many or even all processes in the system.
- Then the interesting trace can be activated and
- deactivated using the <c>{silent,Bool}</c>
- match spec function, giving a high degree
- of control of which functions with which
- arguments that triggers the trace.</p>
- <p>Message tags: <c>call</c>, <c>return_from</c>,
+ The trace can then be activated and deactivated using the match
+ specification function <c>{silent,Bool}</c>, giving
+ a high degree of control of which functions with which
+ arguments that trigger the trace.</p>
+ <p>Message tags: <c>call</c>, <c>return_from</c>, and
<c>return_to</c>. Or rather, the absence of.</p>
</item>
<tag><c>return_to</c></tag>
<item>
- <p>Used in conjunction with the <c>call</c> trace flag.
- Trace the actual return from a traced function back to
+ <p>Used with the <c>call</c> trace flag.
+ Traces the return from a traced function back to
its caller. Only works for functions traced with
- the <c>local</c> option to
+ option <c>local</c> to
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
<p>The semantics is that a trace message is sent when a
- call traced function actually returns, that is, when a
- chain of tail recursive calls is ended. There will be
- only one trace message sent per chain of tail recursive
- calls, why the properties of tail recursiveness for
+ call traced function returns, that is, when a
+ chain of tail recursive calls ends. Only one trace
+ message is sent per chain of tail recursive calls,
+ so the properties of tail recursiveness for
function calls are kept while tracing with this flag.
Using <c>call</c> and <c>return_to</c> trace together
makes it possible to know exactly in which function a
process executes at any time.</p>
<p>To get trace messages containing return values from
- functions, use the <c>{return_trace}</c> match_spec
- action instead.</p>
+ functions, use the <c>{return_trace}</c> match
+ specification action instead.</p>
<p>Message tags: <c>return_to</c>.</p>
</item>
<tag><c>running</c></tag>
<item>
- <p>Trace scheduling of processes.</p>
- <p>Message tags: <c>in</c>, and <c>out</c>.</p>
+ <p>Traces scheduling of processes.</p>
+ <p>Message tags: <c>in</c> and <c>out</c>.</p>
</item>
<tag><c>exiting</c></tag>
<item>
- <p>Trace scheduling of an exiting processes.</p>
+ <p>Traces scheduling of exiting processes.</p>
<p>Message tags: <c>in_exiting</c>, <c>out_exiting</c>, and
<c>out_exited</c>.</p>
</item>
<tag><c>garbage_collection</c></tag>
<item>
- <p>Trace garbage collections of processes.</p>
- <p>Message tags: <c>gc_start</c>, <c>gc_end</c>.</p>
+ <p>Traces garbage collections of processes.</p>
+ <p>Message tags: <c>gc_start</c> and <c>gc_end</c>.</p>
</item>
<tag><c>timestamp</c></tag>
<item>
- <p>Include a time stamp in all trace messages. The time
- stamp (Ts) is of the same form as returned by
+ <p>Includes a time-stamp in all trace messages. The
+ time-stamp (Ts) has the same form as returned by
<c>erlang:now()</c>.</p>
</item>
<tag><c>cpu_timestamp</c></tag>
<item>
<p>A global trace flag for the Erlang node that makes all
- trace timestamps be in CPU time, not wallclock. It is
- only allowed with <c>PidSpec==all</c>. If the host
- machine operating system does not support high resolution
+ trace time-stamps using the <c>timestamp</c> flag to be
+ in CPU time, not wall clock time. That is, <c>cpu_timestamp</c>
+ will not be used if <c>monotonic_timestamp</c>, or
+ <c>strict_monotonic_timestamp</c> is enabled.
+ Only allowed with <c>PidSpec==all</c>. If the host
+ machine OS does not support high-resolution
CPU time measurements, <c>trace/3</c> exits with
- <c>badarg</c>.</p>
+ <c>badarg</c>. Notice that most OS do
+ not synchronize this value across cores, so be prepared
+ that time might seem to go backwards when using this option.</p>
+ </item>
+ <tag><c>monotonic_timestamp</c></tag>
+ <item>
+ <p>Includes an
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> time-stamp in all trace messages. The
+ time-stamp (Ts) has the same format and value as produced by
+ <c>erlang:monotonic_time(nano_seconds)</c>. This flag overrides
+ the <c>cpu_timestamp</c> flag.</p>
+ </item>
+ <tag><c>strict_monotonic_timestamp</c></tag>
+ <item>
+ <p>Includes an timestamp consisting of
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> and a monotonically increasing
+ integer in all trace messages. The time-stamp (Ts) has the
+ same format and value as produced by
+ <c>{erlang:monotonic_time(nano_seconds),
+ erlang:unique_integer([monotonic])}</c>. This flag overrides
+ the <c>cpu_timestamp</c> flag.</p>
</item>
<tag><c>arity</c></tag>
<item>
- <p>Used in conjunction with the <c>call</c> trace flag.
- <c>{M, F, Arity}</c> will be specified instead of
+ <p>Used with the <c>call</c> trace flag.
+ <c>{M, F, Arity}</c> is specified instead of
<c>{M, F, Args}</c> in call trace messages.</p>
</item>
<tag><c>set_on_spawn</c></tag>
<item>
<p>Makes any process created by a traced process inherit
- its trace flags, including the <c>set_on_spawn</c> flag.</p>
+ its trace flags, including flag <c>set_on_spawn</c>.</p>
</item>
<tag><c>set_on_first_spawn</c></tag>
<item>
<p>Makes the first process created by a traced process
- inherit its trace flags, excluding
- the <c>set_on_first_spawn</c> flag.</p>
+ inherit its trace flags, excluding flag
+ <c>set_on_first_spawn</c>.</p>
</item>
<tag><c>set_on_link</c></tag>
<item>
<p>Makes any process linked by a traced process inherit its
- trace flags, including the <c>set_on_link</c> flag.</p>
+ trace flags, including flag <c>set_on_link</c>.</p>
</item>
<tag><c>set_on_first_link</c></tag>
<item>
<p>Makes the first process linked to by a traced process
- inherit its trace flags, excluding
- the <c>set_on_first_link</c> flag.</p>
+ inherit its trace flags, excluding flag
+ <c>set_on_first_link</c>.</p>
</item>
<tag><c>{tracer, Tracer}</c></tag>
<item>
- <p>Specify where to send the trace messages. <c>Tracer</c>
- must be the pid of a local process or the port identifier
+ <p>Specifies where to send the trace messages. <c>Tracer</c>
+ must be the process identifier of a local process
+ or the port identifier
of a local port. If this flag is not given, trace
- messages will be sent to the process that called
+ messages are sent to the process that called
<c>erlang:trace/3</c>.</p>
</item>
</taglist>
@@ -6858,27 +8219,34 @@ ok
<c>set_on_link</c> is the same as having
<c>set_on_first_link</c> alone. Likewise for
<c>set_on_spawn</c> and <c>set_on_first_spawn</c>.</p>
- <p>If the <c>timestamp</c> flag is not given, the tracing
- process will receive the trace messages described below.
- <c>Pid</c> is the pid of the traced process in which
- the traced event has occurred. The third element of the tuple
- is the message tag.</p>
- <p>If the <c>timestamp</c> flag is given, the first element of
- the tuple will be <c>trace_ts</c> instead and the timestamp
- is added last in the tuple.</p>
+ <p>The tracing process receives the <em>trace messages</em> described
+ in the following list. <c>Pid</c> is the process identifier of the
+ traced process in which the traced event has occurred. The
+ third tuple element is the message tag.</p>
+ <p>If flag <c>timestamp</c>, <c>strict_monotonic_timestamp</c>, or
+ <c>monotonic_timestamp</c> is given, the first tuple
+ element is <c>trace_ts</c> instead, and the time-stamp
+ is added as an extra element last in the message tuple. If
+ multiple timestamp flags are passed, <c>timestamp</c> has
+ precedence over <c>strict_monotonic_timestamp</c> which
+ in turn has precedence over <c>monotonic_timestamp</c>. All
+ timestamp flags are remembered, so if two are passed
+ and the one with highest precedence later is disabled
+ the other one will become active.</p>
+ <marker id="trace_3_trace_messages"></marker>
<taglist>
<tag><c>{trace, Pid, 'receive', Msg}</c></tag>
<item>
- <p>When <c>Pid</c> receives the message <c>Msg</c>.</p>
+ <p>When <c>Pid</c> receives message <c>Msg</c>.</p>
</item>
<tag><c>{trace, Pid, send, Msg, To}</c></tag>
<item>
- <p>When <c>Pid</c> sends the message <c>Msg</c> to
- the process <c>To</c>.</p>
+ <p>When <c>Pid</c> sends message <c>Msg</c> to
+ process <c>To</c>.</p>
</item>
<tag><c>{trace, Pid, send_to_non_existing_process, Msg, To}</c></tag>
<item>
- <p>When <c>Pid</c> sends the message <c>Msg</c> to
+ <p>When <c>Pid</c> sends message <c>Msg</c> to
the non-existing process <c>To</c>.</p>
</item>
<tag><c>{trace, Pid, call, {M, F, Args}}</c></tag>
@@ -6886,7 +8254,7 @@ ok
<p>When <c>Pid</c> calls a traced function. The return
values of calls are never supplied, only the call and its
arguments.</p>
- <p>Note that the trace flag <c>arity</c> can be used to
+ <p>Trace flag <c>arity</c> can be used to
change the contents of this message, so that <c>Arity</c>
is specified instead of <c>Args</c>.</p>
</item>
@@ -6894,35 +8262,34 @@ ok
<item>
<p>When <c>Pid</c> returns <em>to</em> the specified
function. This trace message is sent if both
- the <c>call</c> and the <c>return_to</c> flags are set,
+ the flags <c>call</c> and <c>return_to</c> are set,
and the function is set to be traced on <em>local</em>
function calls. The message is only sent when returning
- from a chain of tail recursive function calls where at
+ from a chain of tail recursive function calls, where at
least one call generated a <c>call</c> trace message
- (that is, the functions match specification matched and
+ (that is, the functions match specification matched, and
<c>{message, false}</c> was not an action).</p>
</item>
<tag><c>{trace, Pid, return_from, {M, F, Arity}, ReturnValue}</c></tag>
<item>
<p>When <c>Pid</c> returns <em>from</em> the specified
- function. This trace message is sent if the <c>call</c>
- flag is set, and the function has a match specification
+ function. This trace message is sent if flag <c>call</c>
+ is set, and the function has a match specification
with a <c>return_trace</c> or <c>exception_trace</c> action.</p>
</item>
<tag><c>{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}</c></tag>
<item>
<p>When <c>Pid</c> exits <em>from</em> the specified
- function due to an exception. This trace message is sent
- if the <c>call</c> flag is set, and the function has
+ function because of an exception. This trace message is
+ sent if flag <c>call</c> is set, and the function has
a match specification with an <c>exception_trace</c> action.</p>
</item>
<tag><c>{trace, Pid, spawn, Pid2, {M, F, Args}}</c></tag>
<item>
<p>When <c>Pid</c> spawns a new process <c>Pid2</c> with
the specified function call as entry point.</p>
- <p>Note that <c>Args</c> is supposed to be the argument
- list, but may be any term in the case of an erroneous
- spawn.</p>
+ <p><c>Args</c> is supposed to be the argument list,
+ but can be any term if the spawn is erroneous.</p>
</item>
<tag><c>{trace, Pid, exit, Reason}</c></tag>
<item>
@@ -6952,148 +8319,158 @@ ok
<tag><c>{trace, Pid, unregister, RegName}</c></tag>
<item>
<p>When <c>Pid</c> gets the name <c>RegName</c> unregistered.
- Note that this is done automatically when a registered
+ This is done automatically when a registered
process exits.</p>
</item>
<tag><c>{trace, Pid, in, {M, F, Arity} | 0}</c></tag>
<item>
- <p>When <c>Pid</c> is scheduled to run. The process will
- run in function <c>{M, F, Arity}</c>. On some rare
- occasions the current function cannot be determined, then
- the last element <c>Arity</c> is 0.</p>
+ <p>When <c>Pid</c> is scheduled to run. The process
+ runs in function <c>{M, F, Arity}</c>. On some rare
+ occasions, the current function cannot be determined,
+ then the last element is <c>0</c>.</p>
</item>
<tag><c>{trace, Pid, out, {M, F, Arity} | 0}</c></tag>
<item>
<p>When <c>Pid</c> is scheduled out. The process was
- running in function {M, F, Arity}. On some rare occasions
+ running in function {M, F, Arity}. On some rare occasions,
the current function cannot be determined, then the last
- element <c>Arity</c> is 0.</p>
+ element is <c>0</c>.</p>
</item>
- <tag><marker id="gc_start"><c>{trace, Pid, gc_start, Info}</c></marker></tag>
+ <tag><c>{trace, Pid, gc_start, Info}</c></tag>
<item>
+ <marker id="gc_start"></marker>
<p>Sent when garbage collection is about to be started.
<c>Info</c> is a list of two-element tuples, where
the first element is a key, and the second is the value.
- You should not depend on the tuples have any defined
- order. Currently, the following keys are defined:</p>
+ Do not depend on any order of the tuples.
+ The following keys are defined:</p>
<taglist>
<tag><c>heap_size</c></tag>
<item>The size of the used part of the heap.</item>
<tag><c>heap_block_size</c></tag>
<item>The size of the memory block used for storing
- the heap and the stack.</item>
+ the heap and the stack.</item>
<tag><c>old_heap_size</c></tag>
<item>The size of the used part of the old heap.</item>
<tag><c>old_heap_block_size</c></tag>
<item>The size of the memory block used for storing
- the old heap.</item>
+ the old heap.</item>
<tag><c>stack_size</c></tag>
- <item>The actual size of the stack.</item>
+ <item>The size of the stack.</item>
<tag><c>recent_size</c></tag>
<item>The size of the data that survived the previous garbage
- collection.</item>
+ collection.</item>
<tag><c>mbuf_size</c></tag>
<item>The combined size of message buffers associated with
- the process.</item>
-
+ the process.</item>
<tag><c>bin_vheap_size</c></tag>
- <item>The total size of unique off-heap binaries referenced from the process heap.</item>
+ <item>The total size of unique off-heap binaries referenced
+ from the process heap.</item>
<tag><c>bin_vheap_block_size</c></tag>
- <item>The total size of binaries, in words, allowed in the virtual
- heap in the process before doing a garbage collection. </item>
+ <item>The total size of binaries allowed in the virtual
+ heap in the process before doing a garbage collection.</item>
<tag><c>bin_old_vheap_size</c></tag>
- <item>The total size of unique off-heap binaries referenced from the process old heap.</item>
- <tag><c>bin_vheap_block_size</c></tag>
- <item>The total size of binaries, in words, allowed in the virtual
- old heap in the process before doing a garbage collection. </item>
-
-
+ <item>The total size of unique off-heap binaries referenced
+ from the process old heap.</item>
+ <tag><c>bin_old_vheap_block_size</c></tag>
+ <item>The total size of binaries allowed in the virtual
+ old heap in the process before doing a garbage collection.</item>
</taglist>
<p>All sizes are in words.</p>
</item>
<tag><c>{trace, Pid, gc_end, Info}</c></tag>
<item>
<p>Sent when garbage collection is finished. <c>Info</c>
- contains the same kind of list as in the <c>gc_start</c>
- message, but the sizes reflect the new sizes after
+ contains the same kind of list as in message <c>gc_start</c>,
+ but the sizes reflect the new sizes after
garbage collection.</p>
</item>
</taglist>
- <p>If the tracing process dies, the flags will be silently
+ <p>If the tracing process dies, the flags are silently
removed.</p>
- <p>Only one process can trace a particular process. For this
- reason, attempts to trace an already traced process will fail.</p>
+ <p>Only one process can trace a particular process. Therefore,
+ attempts to trace an already traced process fail.</p>
<p>Returns: A number indicating the number of processes that
- matched <c><anno>PidSpec</anno></c>. If <c><anno>PidSpec</anno></c> is a pid,
- the return value will be <c>1</c>. If <c><anno>PidSpec</anno></c> is
- <c>all</c> or <c>existing</c> the return value will be
+ matched <c><anno>PidSpec</anno></c>.
+ If <c><anno>PidSpec</anno></c> is a process
+ identifier, the return value is <c>1</c>.
+ If <c><anno>PidSpec</anno></c>
+ is <c>all</c> or <c>existing</c>, the return value is
the number of processes running, excluding tracer processes.
- If <c><anno>PidSpec</anno></c> is <c>new</c>, the return value will be
+ If <c><anno>PidSpec</anno></c> is <c>new</c>, the return value is
<c>0</c>.</p>
- <p>Failure: If specified arguments are not supported. For
- example <c>cpu_timestamp</c> is not supported on all
- platforms.</p>
+ <p>Failure: <c>badarg</c> if the specified arguments are
+ not supported. For example, <c>cpu_timestamp</c> is not
+ supported on all platforms.</p>
</desc>
</func>
+
<func>
<name name="trace_delivered" arity="1"/>
- <fsummary>Notification when trace has been delivered</fsummary>
+ <fsummary>Notification when trace has been delivered.</fsummary>
<desc>
<p>The delivery of trace messages is dislocated on the time-line
- compared to other events in the system. If you know that the
- <c><anno>Tracee</anno></c> has passed some specific point in its execution,
+ compared to other events in the system. If you know that
+ <c><anno>Tracee</anno></c> has passed some specific point
+ in its execution,
and you want to know when at least all trace messages
- corresponding to events up to this point have reached the tracer
- you can use <c>erlang:trace_delivered(<anno>Tracee</anno>)</c>. A
+ corresponding to events up to this point have reached the
+ tracer, use <c>erlang:trace_delivered(<anno>Tracee</anno>)</c>. A
<c>{trace_delivered, <anno>Tracee</anno>, <anno>Ref</anno>}</c> message is sent to
the caller of <c>erlang:trace_delivered(<anno>Tracee</anno>)</c> when it
- is guaranteed that all trace messages have been delivered to
- the tracer up to the point that the <c><anno>Tracee</anno></c> had reached
+ is guaranteed that all trace messages are delivered to
+ the tracer up to the point that <c><anno>Tracee</anno></c> reached
at the time of the call to
<c>erlang:trace_delivered(<anno>Tracee</anno>)</c>.</p>
- <p>Note that the <c>trace_delivered</c> message does <em>not</em>
- imply that trace messages have been delivered; instead, it implies
- that all trace messages that <em>should</em> be delivered have
- been delivered. It is not an error if <c><anno>Tracee</anno></c> isn't, and
- hasn't been traced by someone, but if this is the case,
- <em>no</em> trace messages will have been delivered when the
+ <p>Notice that message <c>trace_delivered</c> does <em>not</em>
+ imply that trace messages have been delivered.
+ Instead it implies that all trace messages that
+ <em>are to be delivered</em> have been delivered.
+ It is not an error if <c><anno>Tracee</anno></c> is not, and
+ has not been traced by someone, but if this is the case,
+ <em>no</em> trace messages have been delivered when the
<c>trace_delivered</c> message arrives.</p>
- <p>Note that <c><anno>Tracee</anno></c> has to refer to a process currently,
+ <p>Notice that that <c><anno>Tracee</anno></c> must refer
+ to a process currently,
or previously existing on the same node as the caller of
<c>erlang:trace_delivered(<anno>Tracee</anno>)</c> resides on.
- The special <c><anno>Tracee</anno></c> atom <c>all</c> denotes all processes
+ The special <c><anno>Tracee</anno></c> atom <c>all</c>
+ denotes all processes
that currently are traced in the node.</p>
- <p>An example: Process <c>A</c> is <c><anno>Tracee</anno></c>, port <c>B</c> is
- tracer, and process <c>C</c> is the port owner of <c>B</c>.
- <c>C</c> wants to close <c>B</c> when <c>A</c> exits. <c>C</c>
- can ensure that the trace isn't truncated by calling
- <c>erlang:trace_delivered(A)</c> when <c>A</c> exits and wait
- for the <c>{trace_delivered, A, <anno>Ref</anno>}</c> message before closing
- <c>B</c>.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Tracee</anno></c> does not refer to a
+ <p>Example: Process <c>A</c> is <c><anno>Tracee</anno></c>,
+ port <c>B</c> is tracer, and process <c>C</c> is the port
+ owner of <c>B</c>. <c>C</c> wants to close <c>B</c> when
+ <c>A</c> exits. To ensure that the trace is not truncated,
+ <c>C</c> can call <c>erlang:trace_delivered(A)</c>, when
+ <c>A</c> exits, and wait for message <c>{trace_delivered, A,
+ <anno>Ref</anno>}</c> before closing <c>B</c>.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Tracee</anno></c>
+ does not refer to a
process (dead or alive) on the same node as the caller of
<c>erlang:trace_delivered(<anno>Tracee</anno>)</c> resides on.</p>
</desc>
</func>
+
<func>
<name name="trace_info" arity="2"/>
+ <fsummary>Trace information about a process or function.</fsummary>
<type name="trace_info_return"/>
<type name="trace_info_item_result"/>
<type name="trace_info_flag"/>
<type name="trace_match_spec"/>
- <fsummary>Trace information about a process or function</fsummary>
<desc>
<p>Returns trace information about a process or function.</p>
- <p>To get information about a process, <c><anno>PidOrFunc</anno></c> should
- be a pid or the atom <c>new</c>. The atom <c>new</c> means
- that the default trace state for processes to be created will
- be returned. <c><anno>Item</anno></c> must have one of the following
- values:</p>
+ <p>To get information about a process,
+ <c><anno>PidOrFunc</anno></c> is to
+ be a process identifier (pid) or the atom <c>new</c>.
+ The atom <c>new</c> means that the default trace state for
+ processes to be created is returned.</p>
+ <p>The following <c>Item</c>s are valid:</p>
<taglist>
<tag><c>flags</c></tag>
<item>
- <p>Return a list of atoms indicating what kind of traces is
- enabled for the process. The list will be empty if no
+ <p>Returns a list of atoms indicating what kind of traces is
+ enabled for the process. The list is empty if no
traces are enabled, and one or more of the followings
atoms if traces are enabled: <c>send</c>,
<c>'receive'</c>, <c>set_on_spawn</c>, <c>call</c>,
@@ -7104,358 +8481,474 @@ ok
</item>
<tag><c>tracer</c></tag>
<item>
- <p>Return the identifier for process or port tracing this
+ <p>Returns the identifier for process or port tracing this
process. If this process is not being traced, the return
- value will be <c>[]</c>.</p>
+ value is <c>[]</c>.</p>
</item>
</taglist>
- <p>To get information about a function, <c>PidOrFunc</c> should
- be a three-element tuple: <c>{Module, Function, Arity}</c> or
- the atom <c>on_load</c>. No wildcards are allowed. Returns
- <c>undefined</c> if the function does not exist or
- <c>false</c> if the function is not traced at all. <c>Item</c>
- must have one of the following values:</p>
+ <p>To get information about a function, <c>PidOrFunc</c> is to
+ be the three-element tuple <c>{Module, Function, Arity}</c> or
+ the atom <c>on_load</c>. No wild cards are allowed. Returns
+ <c>undefined</c> if the function does not exist, or
+ <c>false</c> if the function is not traced.</p>
+ <p>The following <c>Item</c>s are valid::</p>
<taglist>
<tag><c>traced</c></tag>
<item>
- <p>Return <c>global</c> if this function is traced on
+ <p>Returns <c>global</c> if this function is traced on
global function calls, <c>local</c> if this function is
- traced on local function calls (i.e local and global
- function calls), and <c>false</c> if neither local nor
- global function calls are traced.</p>
+ traced on local function calls (that is, local and global
+ function calls), and <c>false</c> if local or
+ global function calls are not traced.</p>
</item>
<tag><c>match_spec</c></tag>
<item>
- <p>Return the match specification for this function, if it
+ <p>Returns the match specification for this function, if it
has one. If the function is locally or globally traced but
has no match specification defined, the returned value
is <c>[]</c>.</p>
</item>
<tag><c>meta</c></tag>
<item>
- <p>Return the meta trace tracer process or port for this
- function, if it has one. If the function is not meta
- traced the returned value is <c>false</c>, and if
- the function is meta traced but has once detected that
- the tracer proc is invalid, the returned value is [].</p>
+ <p>Returns the meta-trace tracer process or port for this
+ function, if it has one. If the function is not
+ meta-traced, the returned value is <c>false</c>. If
+ the function is meta-traced but has once detected that
+ the tracer process is invalid, the returned value is [].</p>
</item>
<tag><c>meta_match_spec</c></tag>
<item>
- <p>Return the meta trace match specification for this
- function, if it has one. If the function is meta traced
+ <p>Returns the meta-trace match specification for this
+ function, if it has one. If the function is meta-traced
but has no match specification defined, the returned
value is <c>[]</c>.</p>
</item>
<tag><c>call_count</c></tag>
<item>
- <p>Return the call count value for this function or
+ <p>Returns the call count value for this function or
<c>true</c> for the pseudo function <c>on_load</c> if call
- count tracing is active. Return <c>false</c> otherwise.
+ count tracing is active. Otherwise <c>false</c> is returned.
See also
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
</item>
<tag><c>call_time</c></tag>
<item>
- <p>Return the call time values for this function or
+ <p>Returns the call time values for this function or
<c>true</c> for the pseudo function <c>on_load</c> if call
- time tracing is active. Returns <c>false</c> otherwise.
+ time tracing is active. Otherwise <c>false</c> is returned.
The call time values returned, <c>[{Pid, Count, S, Us}]</c>,
- is a list of each process that has executed the function and its specific counters.
- See also
+ is a list of each process that executed the function
+ and its specific counters. See also
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
</item>
<tag><c>all</c></tag>
<item>
- <p>Return a list containing the <c>{<anno>Item</anno>, Value}</c> tuples
- for all other items, or return <c>false</c> if no tracing
+ <p>Returns a list containing the
+ <c>{<anno>Item</anno>, Value}</c> tuples
+ for all other items, or returns <c>false</c> if no tracing
is active for this function.</p>
</item>
</taglist>
- <p>The actual return value will be <c>{<anno>Item</anno>, Value}</c>, where
- <c>Value</c> is the requested information as described above.
+ <p>The return value is <c>{<anno>Item</anno>, Value}</c>, where
+ <c>Value</c> is the requested information as described earlier.
If a pid for a dead process was given, or the name of a
- non-existing function, <c>Value</c> will be <c>undefined</c>.</p>
- <p>If <c><anno>PidOrFunc</anno></c> is the <c>on_load</c>, the information
+ non-existing function, <c>Value</c> is <c>undefined</c>.</p>
+ <p>If <c><anno>PidOrFunc</anno></c> is <c>on_load</c>, the information
returned refers to the default value for code that will be
loaded.</p>
</desc>
</func>
+
<func>
<name name="trace_pattern" arity="2" clause_i="1"/>
+ <fsummary>Sets trace patterns for global call tracing.</fsummary>
<type name="trace_pattern_mfa"/>
<type name="trace_match_spec"/>
- <fsummary>Set trace patterns for global call tracing</fsummary>
<desc>
<p>The same as
<seealso marker="#trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
retained for backward compatibility.</p>
</desc>
</func>
+
<func>
<name name="trace_pattern" arity="3"/>
+ <fsummary>Sets trace patterns for tracing of function calls.</fsummary>
<type name="trace_pattern_mfa"/>
<type name="trace_match_spec"/>
<type name="trace_pattern_flag"/>
- <fsummary>Set trace patterns for tracing of function calls</fsummary>
<desc>
- <p>This BIF is used to enable or disable call tracing for
- exported functions. It must be combined with
+ <p>Enables or disables call tracing for
+ one or more functions. Must be combined with
<seealso marker="#trace/3">erlang:trace/3</seealso>
to set the <c>call</c> trace flag for one or more processes.</p>
- <p>Conceptually, call tracing works like this: Inside
- the Erlang virtual machine there is a set of processes to be
- traced and a set of functions to be traced. Tracing will be
- enabled on the intersection of the set. That is, if a process
- included in the traced process set calls a function included
- in the traced function set, the trace action will be taken.
- Otherwise, nothing will happen.</p>
- <p>Use
- <seealso marker="#trace/3">erlang:trace/3</seealso> to
- add or remove one or more processes to the set of traced
- processes. Use <c>erlang:trace_pattern/2</c> to add or remove
- exported functions to the set of traced functions.</p>
- <p>The <c>erlang:trace_pattern/3</c> BIF can also add match
- specifications to an exported function. A match specification
- comprises a pattern that the arguments to the function must
- match, a guard expression which must evaluate to <c>true</c>
+ <p>Conceptually, call tracing works as follows. Inside
+ the Erlang Virtual Machine, a set of processes and
+ a set of functions are to be traced. If a traced process
+ calls a traced function, the trace action is taken.
+ Otherwise, nothing happens.</p>
+ <p>To add or remove one or more processes to the set of traced
+ processes, use
+ <seealso marker="#trace/3">erlang:trace/3</seealso>.</p>
+ <p>To add or remove functions to the set of traced
+ functions, use <c>erlang:trace_pattern/3</c>.</p>
+ <p>The BIF <c>erlang:trace_pattern/3</c> can also add match
+ specifications to a function. A match specification
+ comprises a pattern that the function arguments must
+ match, a guard expression that must evaluate to <c>true</c>,
and an action to be performed. The default action is to send a
trace message. If the pattern does not match or the guard
- fails, the action will not be executed.</p>
- <p>The <c><anno>MFA</anno></c> argument should be a tuple like
- <c>{Module, Function, Arity}</c> or the atom <c>on_load</c>
- (described below). It can be the module, function, and arity
- for an exported function (or a BIF in any module).
- The <c>'_'</c> atom can be used to mean any of that kind.
- Wildcards can be used in any of the following ways:</p>
+ fails, the action is not executed.</p>
+ <p>Argument <c><anno>MFA</anno></c> is to be a tuple, such as
+ <c>{Module, Function, Arity}</c>, or the atom <c>on_load</c>
+ (described in the following). It can be the module, function,
+ and arity for a function (or a BIF in any module).
+ The atom <c>'_'</c> can be used as a wild card in any of the
+ following ways:</p>
<taglist>
<tag><c>{Module,Function,'_'}</c></tag>
<item>
- <p>All exported functions of any arity named <c>Function</c>
+ <p>All functions of any arity named <c>Function</c>
in module <c>Module</c>.</p>
</item>
<tag><c>{Module,'_','_'}</c></tag>
<item>
- <p>All exported functions in module <c>Module</c>.</p>
+ <p>All functions in module <c>Module</c>.</p>
</item>
<tag><c>{'_','_','_'}</c></tag>
<item>
- <p>All exported functions in all loaded modules.</p>
+ <p>All functions in all loaded modules.</p>
</item>
</taglist>
<p>Other combinations, such as <c>{Module,'_',Arity}</c>, are
- not allowed. Local functions will match wildcards only if
- the <c>local</c> option is in the <c><anno>FlagList</anno></c>.</p>
- <p>If the <c><anno>MFA</anno></c> argument is the atom <c>on_load</c>,
- the match specification and flag list will be used on all
+ not allowed. Local functions match wild cards only if
+ option <c>local</c> is in <c><anno>FlagList</anno></c>.</p>
+ <p>If argument <c><anno>MFA</anno></c> is the atom <c>on_load</c>,
+ the match specification and flag list are used on all
modules that are newly loaded.</p>
- <p>The <c><anno>MatchSpec</anno></c> argument can take any of the following
- forms:</p>
+ <p>Argument <c><anno>MatchSpec</anno></c> can take the
+ following forms:</p>
<taglist>
<tag><c>false</c></tag>
<item>
- <p>Disable tracing for the matching function(s). Any match
- specification will be removed.</p>
+ <p>Disables tracing for the matching functions.
+ Any match specification is removed.</p>
</item>
<tag><c>true</c></tag>
<item>
- <p>Enable tracing for the matching function(s).</p>
+ <p>Enables tracing for the matching functions.</p>
</item>
<tag><c><anno>MatchSpecList</anno></c></tag>
<item>
<p>A list of match specifications. An empty list is
- equivalent to <c>true</c>. See the ERTS User's Guide
- for a description of match specifications.</p>
+ equivalent to <c>true</c>. For a description of match
+ specifications, see the User's Guide.</p>
</item>
<tag><c>restart</c></tag>
<item>
- <p>For the <c><anno>FlagList</anno></c> option <c>call_count</c> and <c>call_time</c>:
- restart the existing counters. The behaviour is undefined
+ <p>For the <c><anno>FlagList</anno></c> options <c>call_count</c>
+ and <c>call_time</c>: restarts
+ the existing counters. The behavior is undefined
for other <c><anno>FlagList</anno></c> options.</p>
</item>
<tag><c>pause</c></tag>
<item>
- <p>For the <c><anno>FlagList</anno></c> option <c>call_count</c> and <c>call_time</c>: pause
- the existing counters. The behaviour is undefined for
- other <c>FlagList</c> options.</p>
+ <p>For the <c><anno>FlagList</anno></c> options
+ <c>call_count</c> and <c>call_time</c>: pauses
+ the existing counters. The behavior is undefined for
+ other <c><anno>FlagList</anno></c> options.</p>
</item>
</taglist>
- <p>The <c><anno>FlagList</anno></c> parameter is a list of options.
- The following options are allowed:</p>
+ <p>Parameter <c><anno>FlagList</anno></c> is a list of options.
+ The following are the valid options:</p>
<taglist>
<tag><c>global</c></tag>
<item>
- <p>Turn on or off call tracing for global function calls
+ <p>Turns on or off call tracing for global function calls
(that is, calls specifying the module explicitly). Only
- exported functions will match and only global calls will
- generate trace messages. This is the default.</p>
+ exported functions match and only global calls
+ generate trace messages. <em>This is the default</em>.</p>
</item>
<tag><c>local</c></tag>
<item>
- <p>Turn on or off call tracing for all types of function
- calls. Trace messages will be sent whenever any of
+ <p>Turns on or off call tracing for all types of function
+ calls. Trace messages are sent whenever any of
the specified functions are called, regardless of how they
- are called. If the <c>return_to</c> flag is set for
- the process, a <c>return_to</c> message will also be sent
+ are called. If flag <c>return_to</c> is set for
+ the process, a <c>return_to</c> message is also sent
when this function returns to its caller.</p>
</item>
<tag><c>meta | {meta, <anno>Pid</anno>}</c></tag>
<item>
- <p>Turn on or off meta tracing for all types of function
- calls. Trace messages will be sent to the tracer process
+ <p>Turns on or off meta-tracing for all types of function
+ calls. Trace messages are sent to the tracer process
or port <c><anno>Pid</anno></c> whenever any of the specified
functions are called, regardless of how they are called.
- If no <c><anno>Pid</anno></c> is specified, <c>self()</c> is used as a
- default tracer process.</p>
- <p>Meta tracing traces all processes and does not care
+ If no <c><anno>Pid</anno></c> is specified,
+ <c>self()</c> is used as a default tracer process.</p>
+ <p>Meta-tracing traces all processes and does not care
about the process trace flags set by <c>trace/3</c>,
the trace flags are instead fixed to
<c>[call, timestamp]</c>.</p>
- <p>The match spec function <c>{return_trace}</c> works with
- meta trace and send its trace message to the same tracer
- process.</p>
+ <p>The match specification function <c>{return_trace}</c>
+ works with meta-trace and sends its trace message to the
+ same tracer process.</p>
</item>
<tag><c>call_count</c></tag>
<item>
<p>Starts (<c><anno>MatchSpec</anno> == true</c>) or stops
- (<c><anno>MatchSpec</anno> == false</c>) call count tracing for all
- types of function calls. For every function a counter is
+ (<c><anno>MatchSpec</anno> == false</c>)
+ call count tracing for all
+ types of function calls. For every function, a counter is
incremented when the function is called, in any process.
No process trace flags need to be activated.</p>
<p>If call count tracing is started while already running,
- the count is restarted from zero. Running counters can be
- paused with <c><anno>MatchSpec</anno> == pause</c>. Paused and running
- counters can be restarted from zero with
+ the count is restarted from zero. To pause running
+ counters, use <c><anno>MatchSpec</anno> == pause</c>.
+ Paused and running counters can be restarted from zero with
<c><anno>MatchSpec</anno> == restart</c>.</p>
- <p>The counter value can be read with
+ <p>To read the counter value, use
<seealso marker="#trace_info/2">erlang:trace_info/2</seealso>.</p>
</item>
<tag><c>call_time</c></tag>
<item>
<p>Starts (<c><anno>MatchSpec</anno> == true</c>) or stops
- (<c><anno>MatchSpec</anno> == false</c>) call time tracing for all
- types of function calls. For every function a counter is
- incremented when the function is called. Time spent in the function
- is accumulated in two other counters, seconds and micro-seconds.
+ (<c><anno>MatchSpec</anno> == false</c>) call time
+ tracing for all
+ types of function calls. For every function, a counter is
+ incremented when the function is called.
+ Time spent in the function is accumulated in
+ two other counters, seconds and microseconds.
The counters are stored for each call traced process.</p>
<p>If call time tracing is started while already running,
- the count and time is restarted from zero. Running counters can be
- paused with <c><anno>MatchSpec</anno> == pause</c>. Paused and running
- counters can be restarted from zero with
+ the count and time is restarted from zero. To pause
+ running counters, use <c><anno>MatchSpec</anno> == pause</c>.
+ Paused and running counters can be restarted from zero with
<c><anno>MatchSpec</anno> == restart</c>.</p>
- <p>The counter value can be read with
+ <p>To read the counter value, use
<seealso marker="#trace_info/2">erlang:trace_info/2</seealso>.</p>
</item>
-
</taglist>
- <p>The <c>global</c> and <c>local</c> options are mutually
- exclusive and <c>global</c> is the default (if no options are
- specified). The <c>call_count</c> and <c>meta</c> options
- perform a kind of local tracing, and can also not be combined
- with <c>global</c>. A function can be either globally or
+ <p>The options <c>global</c> and <c>local</c> are mutually
+ exclusive, and <c>global</c> is the default (if no options are
+ specified). The options <c>call_count</c> and <c>meta</c>
+ perform a kind of local tracing, and cannot be combined
+ with <c>global</c>. A function can be globally or
locally traced. If global tracing is specified for a
- specified set of functions; local, meta, call time and call count
- tracing for the matching set of local functions will be
- disabled, and vice versa.</p>
+ set of functions, then local, meta, call time, and call count
+ tracing for the matching set of local functions is
+ disabled, and conversely.</p>
<p>When disabling trace, the option must match the type of trace
- that is set on the function, so that local tracing must be
- disabled with the <c>local</c> option and global tracing with
- the <c>global</c> option (or no option at all), and so forth.</p>
- <p>There is no way to directly change part of a match
- specification list. If a function has a match specification,
- you can replace it with a completely new one. If you need to
- change an existing match specification, use the
+ set on the function. That is, local tracing must be
+ disabled with option <c>local</c> and global tracing with
+ option <c>global</c> (or no option), and so forth.</p>
+ <p>Part of a match specification list cannot be changed directly.
+ If a function has a match specification, it can be replaced
+ with a new one. To change an existing match specification,
+ use the BIF
<seealso marker="#trace_info/2">erlang:trace_info/2</seealso>
- BIF to retrieve the existing match specification.</p>
- <p>Returns the number of exported functions that matched
- the <c><anno>MFA</anno></c> argument. This will be zero if none matched at
- all.</p>
+ to retrieve the existing match specification.</p>
+ <p>Returns the number of functions matching
+ argument <c><anno>MFA</anno></c>. This is zero if none matched.</p>
</desc>
</func>
+
<func>
<name name="trunc" arity="1"/>
- <fsummary>Return an integer by the truncating a number</fsummary>
+ <fsummary>Returns an integer by truncating a number</fsummary>
<desc>
- <p>Returns an integer by the truncating <c><anno>Number</anno></c>.</p>
+ <p>Returns an integer by truncating <c><anno>Number</anno></c>,
+ for example:</p>
<pre>
> <input>trunc(5.5).</input>
5</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="tuple_size" arity="1"/>
- <fsummary>Return the size of a tuple</fsummary>
+ <fsummary>Returns the size of a tuple.</fsummary>
<desc>
- <p>Returns an integer which is the number of elements in <c><anno>Tuple</anno></c>.</p>
+ <p>Returns an integer that is the number of elements in
+ <c><anno>Tuple</anno></c>, for example:</p>
<pre>
> <input>tuple_size({morni, mulle, bwange}).</input>
3</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="tuple_to_list" arity="1"/>
- <fsummary>Convert a tuple to a list</fsummary>
+ <fsummary>Converts a tuple to a list.</fsummary>
<desc>
- <p>Returns a list which corresponds to <c><anno>Tuple</anno></c>.
- <c><anno>Tuple</anno></c> may contain any Erlang terms.</p>
+ <p>Returns a list corresponding to <c><anno>Tuple</anno></c>.
+ <c><anno>Tuple</anno></c> can contain any Erlang terms.</p>
+ <p>Example:</p>
<pre>
> <input>tuple_to_list({share, {'Ericsson_B', 163}}).</input>
[share,{'Ericsson_B',163}]</pre>
</desc>
</func>
+
<func>
<name name="universaltime" arity="0"/>
- <fsummary>Current date and time according to Universal Time Coordinated (UTC)</fsummary>
+ <fsummary>Current date and time according to Universal Time Coordinated (UTC).</fsummary>
<desc>
<p>Returns the current date and time according to Universal
- Time Coordinated (UTC), also called GMT, in the form
+ Time Coordinated (UTC) in the form
<c>{{Year, Month, Day}, {Hour, Minute, Second}}</c> if
- supported by the underlying operating system. If not,
- <c>erlang:universaltime()</c> is equivalent to
+ supported by the underlying OS.
+ Otherwise <c>erlang:universaltime()</c> is equivalent to
<c>erlang:localtime()</c>.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:universaltime().</input>
{{1996,11,6},{14,18,43}}</pre>
</desc>
</func>
+
<func>
<name name="universaltime_to_localtime" arity="1"/>
- <fsummary>Convert from Universal Time Coordinated (UTC) to local date and time</fsummary>
+ <fsummary>Converts from Universal Time Coordinated (UTC) to local date and time.</fsummary>
<desc>
<p>Converts Universal Time Coordinated (UTC) date and time to
- local date and time, if this is supported by the underlying
- OS. Otherwise, no conversion is done, and
+ local date and time in the form
+ <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c> if
+ supported by the underlying OS.
+ Otherwise no conversion is done, and
<c><anno>Universaltime</anno></c> is returned.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:universaltime_to_localtime({{1996,11,6},{14,18,43}}).</input>
{{1996,11,7},{15,18,43}}</pre>
- <p>Failure: <c>badarg</c> if <c>Universaltime</c> does not denote
- a valid date and time.</p>
+ <p>Failure: <c>badarg</c> if <c>Universaltime</c> denotes
+ an invalid date and time.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="unique_integer" arity="0"/>
+ <fsummary>Get a unique integer value</fsummary>
+ <desc>
+ <p>Generates and returns an
+ <seealso marker="doc/efficiency_guide:advanced#unique_integers">integer
+ unique on current runtime system instance</seealso>. The same as calling
+ <seealso marker="#unique_integer/1"><c>erlang:unique_integer([])</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="unique_integer" arity="1"/>
+ <fsummary>Get a unique integer value</fsummary>
+ <desc>
+ <p>Generates and returns an
+ <seealso marker="doc/efficiency_guide:advanced#unique_integers">integer
+ unique on current runtime system
+ instance</seealso>. The integer is unique in the
+ sense that this BIF, using the same set of
+ modifiers, will not return the same integer more
+ than once on the current runtime system instance.
+ Each integer value can of course be constructed
+ by other means.</p>
+
+ <p>By default, when <c>[]</c> is passed as
+ <c><anno>ModifierList</anno></c>, both negative and
+ positive integers can be returned. This in order
+ to utilize the range of integers that do
+ not need heap memory allocation as much as possible.
+ By default the returned integers are also only
+ guaranteed to be unique, that is, any returned integer
+ can be smaller or larger than previously
+ returned integers.</p>
+
+ <p>Valid <c><anno>Modifier</anno></c>s:</p>
+ <taglist>
+
+ <tag>positive</tag>
+ <item><p>Return only positive integers.</p>
+ <p>Note that by passing the <c>positive</c> modifier
+ you will get heap allocated integers (bignums)
+ quicker.</p>
+ </item>
+
+ <tag>monotonic</tag>
+ <item><p>Return
+ <seealso marker="time_correction#Strictly_Monotonically_Increasing">strictly
+ monotonically increasing</seealso> integers
+ corresponding to creation time. That is, the integer
+ returned will always be larger than previously
+ returned integers on the current runtime system
+ instance.</p>
+ <p>These values can be used to determine order between events
+ on the runtime system instance. That is, if both
+ <c>X = erlang:unique_integer([monotonic])</c> and
+ <c>Y = erlang:unique_integer([monotonic])</c> are
+ executed by different processes (or the same
+ process) on the same runtime system instance and
+ <c>X &lt; Y</c> we know that <c>X</c> was created
+ before <c>Y</c>.</p>
+ <warning><p>Strictly monotonically increasing values
+ are inherently quite expensive to generate and scales
+ poorly. This is because the values need to be
+ synchronized between cpu cores. That is, do not pass the <c>monotonic</c>
+ modifier unless you really need strictly monotonically
+ increasing values.</p></warning>
+ </item>
+
+ </taglist>
+
+ <p>All valid <c><anno>Modifier</anno></c>s
+ can be combined. Repeated (valid)
+ <c><anno>Modifier</anno></c>s in the <c>ModifierList</c>
+ are ignored.</p>
+
+ <note><p>Note that the set of integers returned by
+ <c>unique_integer/1</c> using different sets of
+ <c><anno>Modifier</anno></c>s <em>will overlap</em>.
+ For example, by calling <c>unique_integer([monotonic])</c>,
+ and <c>unique_integer([positive, monotonic])</c>
+ repeatedly, you will eventually see some integers being
+ returned by both calls.</p></note>
+
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>if <c><anno>ModifierList</anno></c> is not a
+ proper list.</item>
+ <tag><c>badarg</c></tag>
+ <item>if <c><anno>Modifier</anno></c> is not a
+ valid modifier.</item>
+ </taglist>
</desc>
</func>
<func>
<name name="unlink" arity="1"/>
- <fsummary>Remove a link, if there is one, to another process or port</fsummary>
+ <fsummary>Removes a link to another process or port.</fsummary>
<desc>
<p>Removes the link, if there is one, between the calling
- process and the process or port referred to by <c><anno>Id</anno></c>.</p>
+ process and the process or port referred to by
+ <c><anno>Id</anno></c>.</p>
<p>Returns <c>true</c> and does not fail, even if there is no
- link to <c><anno>Id</anno></c>, or if <c><anno>Id</anno></c> does not exist.</p>
- <p>Once <c>unlink(<anno>Id</anno>)</c> has returned it is guaranteed that
+ link to <c><anno>Id</anno></c>, or if <c><anno>Id</anno></c>
+ does not exist.</p>
+ <p>Once <c>unlink(<anno>Id</anno>)</c> has returned,
+ it is guaranteed that
the link between the caller and the entity referred to by
- <c><anno>Id</anno></c> has no effect on the caller in the future (unless
- the link is setup again). If caller is trapping exits, an
- <c>{'EXIT', <anno>Id</anno>, _}</c> message due to the link might have
- been placed in the caller's message queue prior to the call,
- though. Note, the <c>{'EXIT', <anno>Id</anno>, _}</c> message can be the
- result of the link, but can also be the result of <c><anno>Id</anno></c>
- calling <c>exit/2</c>. Therefore, it <em>may</em> be
- appropriate to cleanup the message queue when trapping exits
- after the call to <c>unlink(<anno>Id</anno>)</c>, as follow:</p>
+ <c><anno>Id</anno></c> has no effect on the caller
+ in the future (unless
+ the link is setup again). If the caller is trapping exits, an
+ <c>{'EXIT', <anno>Id</anno>, _}</c> message from the link
+ can have been placed in the caller's message queue before
+ the call.</p>
+ <p>Notice that the <c>{'EXIT', <anno>Id</anno>, _}</c>
+ message can be the
+ result of the link, but can also be the result of <c>Id</c>
+ calling <c>exit/2</c>. Therefore, it <em>can</em> be
+ appropriate to clean up the message queue when trapping exits
+ after the call to <c>unlink(<anno>Id</anno>)</c>, as follows:</p>
<code type="none">
-
unlink(Id),
receive
{'EXIT', Id, _} ->
@@ -7464,23 +8957,25 @@ ok
true
end</code>
<note>
- <p>Prior to OTP release R11B (erts version 5.5) <c>unlink/1</c>
- behaved completely asynchronous, i.e., the link was active
+ <p>Prior to OTP release R11B (ERTS version 5.5) <c>unlink/1</c>
+ behaved completely asynchronously, i.e., the link was active
until the "unlink signal" reached the linked entity. This
- had one undesirable effect, though. You could never know when
+ had an undesirable effect, as you could never know when
you were guaranteed <em>not</em> to be effected by the link.</p>
- <p>Current behavior can be viewed as two combined operations:
+ <p>The current behavior can be viewed as two combined operations:
asynchronously send an "unlink signal" to the linked entity
and ignore any future results of the link.</p>
</note>
</desc>
</func>
+
<func>
<name name="unregister" arity="1"/>
- <fsummary>Remove the registered name for a process (or port)</fsummary>
+ <fsummary>Removes the registered name for a process (or port).</fsummary>
<desc>
- <p>Removes the registered name <c><anno>RegName</anno></c>, associated with a
- pid or a port identifier.</p>
+ <p>Removes the registered name <c><anno>RegName</anno></c>
+ associated with a
+ process identifier or a port identifier, for example:</p>
<pre>
> <input>unregister(db).</input>
true</pre>
@@ -7489,31 +8984,34 @@ true</pre>
name.</p>
</desc>
</func>
+
<func>
<name name="whereis" arity="1"/>
- <fsummary>Get the pid (or port) with a given registered name</fsummary>
+ <fsummary>Gets the pid (or port) with a given registered name.</fsummary>
<desc>
- <p>Returns the pid or port identifier with the registered name
- <c>RegName</c>. Returns <c>undefined</c> if the name is not
- registered.</p>
+ <p>Returns the process identifier or port identifier with
+ the registered name <c>RegName</c>. Returns <c>undefined</c>
+ if the name is not registered.</p>
+ <p>Example:</p>
<pre>
> <input>whereis(db).</input>
&lt;0.43.0></pre>
</desc>
</func>
+
<func>
<name name="yield" arity="0"/>
- <fsummary>Let other processes get a chance to execute</fsummary>
+ <fsummary>Lets other processes get a chance to execute.</fsummary>
<desc>
- <p>Voluntarily let other processes (if any) get a chance to
+ <p>Voluntarily lets other processes (if any) get a chance to
execute. Using <c>erlang:yield()</c> is similar to
<c>receive after 1 -> ok end</c>, except that <c>yield()</c>
is faster.</p>
<warning><p>There is seldom or never any need to use this BIF,
- especially in the SMP-emulator as other processes will have a
- chance to run in another scheduler thread anyway.
- Using this BIF without a thorough grasp of how the scheduler
- works may cause performance degradation.</p></warning>
+ especially in the SMP emulator, as other processes have a
+ chance to run in another scheduler thread anyway.
+ Using this BIF without a thorough grasp of how the scheduler
+ works can cause performance degradation.</p></warning>
</desc>
</func>
</funcs>
diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml
index c3fc3b1686..9fc5864413 100644
--- a/erts/doc/src/erlc.xml
+++ b/erts/doc/src/erlc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml
index 71cee714a5..ccb8b2dd76 100644
--- a/erts/doc/src/erlsrv.xml
+++ b/erts/doc/src/erlsrv.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 1ade41f1aa..15b78ffa10 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -4,20 +4,21 @@
<cref>
<header>
<copyright>
- <year>2002</year><year>2014</year>
+ <year>2002</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -259,19 +260,19 @@
<p>The following flags are available for configuration of
<c>mseg_alloc</c>:</p>
<taglist>
- <tag><marker id="MMamcbf"><c><![CDATA[+MMamcbf <size>]]></c></marker></tag>
+ <tag><marker id="MMamcbf"/><c><![CDATA[+MMamcbf <size>]]></c></tag>
<item>
Absolute max cache bad fit (in kilobytes). A segment in the
memory segment cache is not reused if its size exceeds the
requested size with more than the value of this
parameter. Default value is 4096. </item>
- <tag><marker id="MMrmcbf"><c><![CDATA[+MMrmcbf <ratio>]]></c></marker></tag>
+ <tag><marker id="MMrmcbf"/><c><![CDATA[+MMrmcbf <ratio>]]></c></tag>
<item>
Relative max cache bad fit (in percent). A segment in the
memory segment cache is not reused if its size exceeds the
requested size with more than relative max cache bad fit
percent of the requested size. Default value is 20.</item>
- <tag><marker id="MMsco"><c><![CDATA[+MMsco true|false]]></c></marker></tag>
+ <tag><marker id="MMsco"/><c><![CDATA[+MMsco true|false]]></c></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> only flag. This
flag defaults to <c>true</c>. When a super carrier is used and this
@@ -291,7 +292,7 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
- <tag><marker id="MMscrfsd"><c><![CDATA[+MMscrfsd <amount>]]></c></marker></tag>
+ <tag><marker id="MMscrfsd"/><c><![CDATA[+MMscrfsd <amount>]]></c></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> reserved
free segment descriptors. This parameter defaults to <c>65536</c>.
@@ -304,7 +305,7 @@
<c>erts_mmap</c> tuple part of the result from calling
<seealso marker="erts:erlang#system_info_allocator_tuple">erlang:system_info({allocator, mseg_alloc})</seealso>.
</item>
- <tag><marker id="MMscrpm"><c><![CDATA[+MMscrpm true|false]]></c></marker></tag>
+ <tag><marker id="MMscrpm"/><c><![CDATA[+MMscrpm true|false]]></c></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> reserve physical
memory flag. This flag defaults to <c>true</c>. When this flag is
@@ -327,7 +328,7 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
- <tag><marker id="MMscs"><c><![CDATA[+MMscs <size in MB>]]></c></marker></tag>
+ <tag><marker id="MMscs"/><c><![CDATA[+MMscs <size in MB>]]></c></tag>
<item>
Set super carrier size (in MB). The super carrier size defaults to
zero; i.e, the super carrier is by default disabled. The super
@@ -342,7 +343,7 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
- <tag><marker id="MMmcs"><c><![CDATA[+MMmcs <amount>]]></c></marker></tag>
+ <tag><marker id="MMmcs"/><c><![CDATA[+MMmcs <amount>]]></c></tag>
<item>
Max cached segments. The maximum number of memory segments
stored in the memory segment cache. Valid range is
@@ -351,15 +352,15 @@
<p>The following flags are available for configuration of
<c>sys_alloc</c>:</p>
<taglist>
- <tag><marker id="MYe"><c>+MYe true</c></marker></tag>
+ <tag><marker id="MYe"/><c>+MYe true</c></tag>
<item>
Enable <c>sys_alloc</c>. Note: <c>sys_alloc</c> cannot be disabled.</item>
- <tag><marker id="MYm"><c>+MYm libc</c></marker></tag>
+ <tag><marker id="MYm"/><c>+MYm libc</c></tag>
<item>
<c>malloc</c> library to use. Currently only
<c>libc</c> is available. <c>libc</c> enables the standard
<c>libc</c> malloc implementation. By default <c>libc</c> is used.</item>
- <tag><marker id="MYtt"><c><![CDATA[+MYtt <size>]]></c></marker></tag>
+ <tag><marker id="MYtt"/><c><![CDATA[+MYtt <size>]]></c></tag>
<item>
Trim threshold size (in kilobytes). This is the maximum amount
of free memory at the top of the heap (allocated by
@@ -371,7 +372,7 @@
trim threshold is 128. <em>Note:</em> This flag will
only have any effect when the emulator has been linked with
the GNU C library, and uses its <c>malloc</c> implementation.</item>
- <tag><marker id="MYtp"><c><![CDATA[+MYtp <size>]]></c></marker></tag>
+ <tag><marker id="MYtp"/><c><![CDATA[+MYtp <size>]]></c></tag>
<item>
Top pad size (in kilobytes). This is the amount of extra
memory that will be allocated by <c>malloc</c> when
@@ -389,7 +390,7 @@
subsystem identifier, only the specific allocator identified will be
effected:</p>
<taglist>
- <tag><marker id="M_acul"><c><![CDATA[+M<S>acul <utilization>|de]]></c></marker></tag>
+ <tag><marker id="M_acul"/><c><![CDATA[+M<S>acul <utilization>|de]]></c></tag>
<item>
Abandon carrier utilization limit. A valid
<c><![CDATA[<utilization>]]></c> is an integer in the range
@@ -421,7 +422,7 @@
allocators based on the <c>alloc_util</c> framework with the
exception of <c>temp_alloc</c> (which would be pointless).
</item>
- <tag><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|gf|af]]></c></marker></tag>
+ <tag><marker id="M_as"/><c><![CDATA[+M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|gf|af]]></c></tag>
<item>
Allocation strategy. Valid strategies are <c>bf</c> (best fit),
<c>aobf</c> (address order best fit), <c>aoff</c> (address order first fit),
@@ -429,7 +430,7 @@
<c>aoffcaobf</c> (address order first fit carrier address order best fit),
<c>gf</c> (good fit), and <c>af</c> (a fit). See
<seealso marker="#strategy">the description of allocation strategies</seealso> in "the <c>alloc_util</c> framework" section.</item>
- <tag><marker id="M_asbcst"><c><![CDATA[+M<S>asbcst <size>]]></c></marker></tag>
+ <tag><marker id="M_asbcst"/><c><![CDATA[+M<S>asbcst <size>]]></c></tag>
<item>
Absolute singleblock carrier shrink threshold (in
kilobytes). When a block located in an
@@ -437,23 +438,23 @@
will be left unchanged if the amount of unused memory is less
than this threshold; otherwise, the carrier will be shrunk.
See also <seealso marker="#M_rsbcst">rsbcst</seealso>.</item>
- <tag><marker id="M_e"><c><![CDATA[+M<S>e true|false]]></c></marker></tag>
+ <tag><marker id="M_e"/><c><![CDATA[+M<S>e true|false]]></c></tag>
<item>
Enable allocator <c><![CDATA[<S>]]></c>.</item>
- <tag><marker id="M_lmbcs"><c><![CDATA[+M<S>lmbcs <size>]]></c></marker></tag>
+ <tag><marker id="M_lmbcs"/><c><![CDATA[+M<S>lmbcs <size>]]></c></tag>
<item>
Largest (<c>mseg_alloc</c>) multiblock carrier size (in
kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
on how sizes for mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section. On 32-bit Unix style OS
this limit can not be set higher than 128 megabyte.</item>
- <tag><marker id="M_mbcgs"><c><![CDATA[+M<S>mbcgs <ratio>]]></c></marker></tag>
+ <tag><marker id="M_mbcgs"/><c><![CDATA[+M<S>mbcgs <ratio>]]></c></tag>
<item>
(<c>mseg_alloc</c>) multiblock carrier growth stages. See
<seealso marker="#mseg_mbc_sizes">the description on how sizes for
mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><marker id="M_mbsd"><c><![CDATA[+M<S>mbsd <depth>]]></c></marker></tag>
+ <tag><marker id="M_mbsd"/><c><![CDATA[+M<S>mbsd <depth>]]></c></tag>
<item>
Max block search depth. This flag has effect only if the
good fit strategy has been selected for allocator
@@ -463,40 +464,40 @@
search depth sets a limit on the maximum number of blocks to
inspect in a free list during a search for suitable block
satisfying the request.</item>
- <tag><marker id="M_mmbcs"><c><![CDATA[+M<S>mmbcs <size>]]></c></marker></tag>
+ <tag><marker id="M_mmbcs"/><c><![CDATA[+M<S>mmbcs <size>]]></c></tag>
<item>
Main multiblock carrier size. Sets the size of the main
multiblock carrier for allocator <c><![CDATA[<S>]]></c>. The main
multiblock carrier is allocated via <c><![CDATA[sys_alloc]]></c> and is
never deallocated.</item>
- <tag><marker id="M_mmmbc"><c><![CDATA[+M<S>mmmbc <amount>]]></c></marker></tag>
+ <tag><marker id="M_mmmbc"/><c><![CDATA[+M<S>mmmbc <amount>]]></c></tag>
<item>
Max <c>mseg_alloc</c> multiblock carriers. Maximum number of
multiblock carriers allocated via <c>mseg_alloc</c> by
allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
new multiblock carriers will be allocated via
<c>sys_alloc</c>.</item>
- <tag><marker id="M_mmsbc"><c><![CDATA[+M<S>mmsbc <amount>]]></c></marker></tag>
+ <tag><marker id="M_mmsbc"/><c><![CDATA[+M<S>mmsbc <amount>]]></c></tag>
<item>
Max <c>mseg_alloc</c> singleblock carriers. Maximum number of
singleblock carriers allocated via <c>mseg_alloc</c> by
allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
new singleblock carriers will be allocated via
<c>sys_alloc</c>.</item>
- <tag><marker id="M_ramv"><c><![CDATA[+M<S>ramv <bool>]]></c></marker></tag>
+ <tag><marker id="M_ramv"/><c><![CDATA[+M<S>ramv <bool>]]></c></tag>
<item>
Realloc always moves. When enabled, reallocate operations will
more or less be translated into an allocate, copy, free sequence.
This often reduce memory fragmentation, but costs performance.
</item>
- <tag><marker id="M_rmbcmt"><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></marker></tag>
+ <tag><marker id="M_rmbcmt"/><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></tag>
<item>
Relative multiblock carrier move threshold (in percent). When
a block located in a multiblock carrier is shrunk,
the block will be moved if the ratio of the size of the returned
memory compared to the previous size is more than this threshold;
otherwise, the block will be shrunk at current location.</item>
- <tag><marker id="M_rsbcmt"><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></marker></tag>
+ <tag><marker id="M_rsbcmt"/><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></tag>
<item>
Relative singleblock carrier move threshold (in percent). When
a block located in a singleblock carrier is shrunk to
@@ -505,7 +506,7 @@
the block will be left unchanged in the singleblock carrier if
the ratio of unused memory is less than this threshold;
otherwise, it will be moved into a multiblock carrier. </item>
- <tag><marker id="M_rsbcst"><c><![CDATA[+M<S>rsbcst <ratio>]]></c></marker></tag>
+ <tag><marker id="M_rsbcst"/><c><![CDATA[+M<S>rsbcst <ratio>]]></c></tag>
<item>
Relative singleblock carrier shrink threshold (in
percent). When a block located in an <c>mseg_alloc</c>
@@ -513,20 +514,20 @@
unchanged if the ratio of unused memory is less than this
threshold; otherwise, the carrier will be shrunk.
See also <seealso marker="#M_asbcst">asbcst</seealso>.</item>
- <tag><marker id="M_sbct"><c><![CDATA[+M<S>sbct <size>]]></c></marker></tag>
+ <tag><marker id="M_sbct"/><c><![CDATA[+M<S>sbct <size>]]></c></tag>
<item>
Singleblock carrier threshold. Blocks larger than this
threshold will be placed in singleblock carriers. Blocks
smaller than this threshold will be placed in multiblock
carriers. On 32-bit Unix style OS this threshold can not be set higher
than 8 megabytes.</item>
- <tag><marker id="M_smbcs"><c><![CDATA[+M<S>smbcs <size>]]></c></marker></tag>
+ <tag><marker id="M_smbcs"/><c><![CDATA[+M<S>smbcs <size>]]></c></tag>
<item>
Smallest (<c>mseg_alloc</c>) multiblock carrier size (in
kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
on how sizes for mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><marker id="M_t"><c><![CDATA[+M<S>t true|false]]></c></marker></tag>
+ <tag><marker id="M_t"/><c><![CDATA[+M<S>t true|false]]></c></tag>
<item>
<p>Multiple, thread specific instances of the allocator.
This option will only have any effect on the runtime system
@@ -543,20 +544,20 @@
<c>alloc_util</c>, i.e. all allocators based on <c>alloc_util</c>
will be effected:</p>
<taglist>
- <tag><marker id="Muycs"><c><![CDATA[+Muycs <size>]]></c></marker></tag>
+ <tag><marker id="Muycs"/><c><![CDATA[+Muycs <size>]]></c></tag>
<item>
<c>sys_alloc</c> carrier size. Carriers allocated via
<c>sys_alloc</c> will be allocated in sizes which are
multiples of the <c>sys_alloc</c> carrier size. This is not
true for main multiblock carriers and carriers allocated
during a memory shortage, though.</item>
- <tag><marker id="Mummc"><c><![CDATA[+Mummc <amount>]]></c></marker></tag>
+ <tag><marker id="Mummc"/><c><![CDATA[+Mummc <amount>]]></c></tag>
<item>
Max <c>mseg_alloc</c> carriers. Maximum number of carriers
placed in separate memory segments. When this limit has been
reached, new carriers will be placed in memory retrieved from
<c>sys_alloc</c>.</item>
- <tag><marker id="Musac"><c><![CDATA[+Musac <bool>]]></c></marker></tag>
+ <tag><marker id="Musac"/><c><![CDATA[+Musac <bool>]]></c></tag>
<item>
Allow <c>sys_alloc</c> carriers. By default <c>true</c>. If
set to <c>false</c>, <c>sys_alloc</c> carriers will never be
@@ -564,19 +565,19 @@
</taglist>
<p>Instrumentation flags:</p>
<taglist>
- <tag><marker id="Mim"><c>+Mim true|false</c></marker></tag>
+ <tag><marker id="Mim"/><c>+Mim true|false</c></tag>
<item>
A map over current allocations is kept by the emulator. The
allocation map can be retrieved via the <c>instrument</c>
module. <c>+Mim true</c> implies <c>+Mis true</c>.
<c>+Mim true</c> is the same as
<seealso marker="erl#instr">-instr</seealso>.</item>
- <tag><marker id="Mis"><c>+Mis true|false</c></marker></tag>
+ <tag><marker id="Mis"/><c>+Mis true|false</c></tag>
<item>
Status over allocated memory is kept by the emulator. The
allocation status can be retrieved via the <c>instrument</c>
module.</item>
- <tag><marker id="Mit"><c>+Mit X</c></marker></tag>
+ <tag><marker id="Mit"/><c>+Mit X</c></tag>
<item>
Reserved for future use. Do <em>not</em> use this flag.</item>
</taglist>
@@ -586,7 +587,7 @@
</note>
<p>Other flags:</p>
<taglist>
- <tag><marker id="Mea"><c>+Mea min|max|r9c|r10b|r11b|config</c></marker></tag>
+ <tag><marker id="Mea"/><c>+Mea min|max|r9c|r10b|r11b|config</c></tag>
<item>
<taglist>
<tag><c>min</c></tag>
@@ -616,7 +617,7 @@
</item>
</taglist>
</item>
- <tag><marker id="Mlpm"><c>+Mlpm all|no</c></marker></tag>
+ <tag><marker id="Mlpm"/><c>+Mlpm all|no</c></tag>
<item>Lock physical memory. The default value is <c>no</c>, i.e.,
no physical memory will be locked. If set to <c>all</c>, all
memory mappings made by the runtime system, will be locked into
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
index 9159d68f60..f12f76890c 100644
--- a/erts/doc/src/escript.xml
+++ b/erts/doc/src/escript.xml
@@ -4,20 +4,21 @@
<comref>
<header>
<copyright>
- <year>2007</year><year>2014</year>
+ <year>2007</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -95,8 +96,8 @@ $ <input>escript factorial 5</input> </pre>
<note><p>
The encoding specified by the above mentioned comment
applies to the script itself. The encoding of the
- I/O-server, however, has to be set explicitly like this:
-<code>io:setopts([{encoding, unicode}])</code></p>
+ I/O-server, however, has to be set explicitly like this:</p>
+<code>io:setopts([{encoding, unicode}])</code>
<p>The default encoding of the I/O-server for <c>standard_io</c>
is <c>latin1</c>
since the script runs in a non-interactive terminal
diff --git a/erts/doc/src/inet_cfg.xml b/erts/doc/src/inet_cfg.xml
index d40bc5f9ee..5caf232a62 100644
--- a/erts/doc/src/inet_cfg.xml
+++ b/erts/doc/src/inet_cfg.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml
index 09b5493341..fe26df61f7 100644
--- a/erts/doc/src/init.xml
+++ b/erts/doc/src/init.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -248,7 +249,7 @@
evaluation), Erlang stops with an error message. Here is an
example that seeds the random number generator:</p>
<pre>
-% <input>erl -eval '{X,Y,Z}' = now(), random:seed(X,Y,Z).'</input></pre>
+% <input>erl -eval '{X,Y,Z} = now(), random:seed(X,Y,Z).'</input></pre>
<p>This example uses Erlang as a hexadecimal calculator:</p>
<pre>
% <input>erl -noshell -eval 'R = 16#1F+16#A0, io:format("~.16B~n", [R])' \\</input>
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index 334b47d34c..08dad8cc10 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -76,22 +77,26 @@
{ GuardFunction, ConditionExpression, ... }
</item>
<item>BoolFunction ::= <c><![CDATA[is_atom]]></c> |
- <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> | <c><![CDATA[is_list]]></c> |
- <c><![CDATA[is_number]]></c> | <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
- <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> | <c><![CDATA[is_binary]]></c> |
- <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> | <c><![CDATA[is_seq_trace]]></c> |
- <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> |
- <c><![CDATA[andalso]]></c> | <c><![CDATA[orelse]]></c></item>
+ <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> |
+ <c><![CDATA[is_list]]></c> | <c><![CDATA[is_number]]></c> |
+ <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
+ <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> |
+ <c><![CDATA[is_map]]></c> | <c><![CDATA[is_binary]]></c> |
+ <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> |
+ <c><![CDATA[is_seq_trace]]></c> | <c><![CDATA['and']]></c> |
+ <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> |
+ <c><![CDATA['xor']]></c> | <c><![CDATA[andalso]]></c> |
+ <c><![CDATA[orelse]]></c></item>
<item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } |
{ GuardFunction, ConditionExpression, ... } | TermConstruct
</item>
<item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
<c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
- <item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
- <c><![CDATA[[]]]></c> | [ConditionExpression, ...] | NonCompositeTerm | Constant
- </item>
- <item>NonCompositeTerm ::= term() (not list or tuple)
- </item>
+ <item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
+ <c><![CDATA[[]]]></c> | [ConditionExpression, ...] |
+ <c><![CDATA[#{}]]></c> | #{term() => ConditionExpression, ...} |
+ NonCompositeTerm | Constant</item>
+ <item>NonCompositeTerm ::= term() (not list or tuple or map)</item>
<item>Constant ::= {<c><![CDATA[const]]></c>, term()}
</item>
<item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> |
@@ -134,22 +139,26 @@
{ GuardFunction, ConditionExpression, ... }
</item>
<item>BoolFunction ::= <c><![CDATA[is_atom]]></c> |
- <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> | <c><![CDATA[is_list]]></c> |
- <c><![CDATA[is_number]]></c> | <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
- <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> | <c><![CDATA[is_binary]]></c> |
- <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> | <c><![CDATA[is_seq_trace]]></c> |
- <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> |
- <c><![CDATA[andalso]]></c> | <c><![CDATA[orelse]]></c></item>
+ <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> |
+ <c><![CDATA[is_list]]></c> | <c><![CDATA[is_number]]></c> |
+ <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
+ <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> |
+ <c><![CDATA[is_map]]></c> | <c><![CDATA[is_binary]]></c> |
+ <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> |
+ <c><![CDATA[is_seq_trace]]></c> | <c><![CDATA['and']]></c> |
+ <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> |
+ <c><![CDATA['xor']]></c> | <c><![CDATA[andalso]]></c> |
+ <c><![CDATA[orelse]]></c></item>
<item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } |
{ GuardFunction, ConditionExpression, ... } | TermConstruct
</item>
<item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
<c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
<item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
- <c><![CDATA[[]]]></c> | [ConditionExpression, ...] | NonCompositeTerm | Constant
- </item>
- <item>NonCompositeTerm ::= term() (not list or tuple)
- </item>
+ <c><![CDATA[[]]]></c> | [ConditionExpression, ...] | #{} |
+ #{term() => ConditionExpression, ...} | NonCompositeTerm |
+ Constant</item>
+ <item>NonCompositeTerm ::= term() (not list or tuple or map)</item>
<item>Constant ::= {<c><![CDATA[const]]></c>, term()}
</item>
<item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> |
@@ -172,9 +181,10 @@
<title>Functions allowed in all types of match specifications</title>
<p>The different functions allowed in <c><![CDATA[match_spec]]></c> work like this:
</p>
- <p><em>is_atom, is_float, is_integer, is_list, is_number, is_pid, is_port, is_reference, is_tuple, is_binary, is_function: </em> Like the corresponding guard tests in
- Erlang, return <c><![CDATA[true]]></c> or <c><![CDATA[false]]></c>.
- </p>
+ <p><em>is_atom, is_float, is_integer, is_list, is_number, is_pid, is_port,
+ is_reference, is_tuple, is_map, is_binary, is_function:</em> Like the
+ corresponding guard tests in Erlang, return <c><![CDATA[true]]></c> or
+ <c><![CDATA[false]]></c>.</p>
<p><em>is_record: </em>Takes an additional parameter, which SHALL
be the result of <c><![CDATA[record_info(size, <record_type>)]]></c>,
like in <c><![CDATA[{is_record, '$1', rectype, record_info(size, rectype)}]]></c>.
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 35e6e55e72..7ccddf4ff0 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,1369 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+
+<section><title>Erts 7.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>process_info(Pid, last_calls)</c> did not work for
+ <c>Pid /= self()</c>.</p>
+ <p>
+ Own Id: OTP-13418</p>
+ </item>
+ <item>
+ <p>
+ Make sure to create a crash dump when running out of
+ memory. This was accidentally removed in the erts-7.3
+ release.</p>
+ <p>
+ Own Id: OTP-13419</p>
+ </item>
+ <item>
+ <p>
+ Schedulers could be woken by a premature timeout on
+ Linux. This premature wakeup was however harmless.</p>
+ <p>
+ Own Id: OTP-13420</p>
+ </item>
+ <item>
+ <p>
+ A process communicating with a port via one of the
+ <c>erlang:port_*</c> BIFs could potentially end up in an
+ inconsistent state if the port terminated during the
+ communication. When this occurred the process could later
+ block in a <c>receive</c> even though it had messages
+ matching in its message queue.</p>
+ <p>
+ This bug was introduced in erts version 5.10 (OTP R16A).</p>
+ <p>
+ Own Id: OTP-13424 Aux Id: OTP-10336 </p>
+ </item>
+ <item>
+ <p>
+ The reference count of a process structure could under
+ rare circumstances be erroneously managed. When this
+ happened invalid memory accesses occurred.</p>
+ <p>
+ Own Id: OTP-13446</p>
+ </item>
+ <item>
+ <p>
+ Fix race between <c>process_flag(trap_exit,true)</c> and
+ a received exit signal.</p>
+ <p>
+ A process could terminate due to exit signal even though
+ <c>process_flag(trap_exit,true)</c> had returned. A very
+ specific timing between call to <c>process_flag/2</c> and
+ exit signal from another scheduler was required for this
+ to happen.</p>
+ <p>
+ Own Id: OTP-13452</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The '-path' flag to 'erl' has been documented. This flag
+ replaces the path specified in the boot script. It has
+ always existed, but was earlier only documented in SASL
+ (script).</p>
+ <p>
+ Own Id: OTP-13060</p>
+ </item>
+ <item>
+ <p>
+ The <c>call_time</c> tracing functionality internally
+ used a time based on OS system time in order to measure
+ call time which could cause erroneous results if OS
+ system time was changed during tracing.</p>
+ <p>
+ This functionality now use Erlang monotonic time in order
+ to measure time. Besides fixing the erroneous results due
+ to OS system time being used, the results are often also
+ better since Erlang monotonic time often has better
+ accuracy and precision.</p>
+ <p>
+ Own Id: OTP-13216</p>
+ </item>
+ <item>
+ <p>
+ Fix behaviour of -delay_write command line switch of
+ epmd, which is used for debugging - in some cases epmd
+ was sleeping twice the requested amount of time.</p>
+ <p>
+ Own Id: OTP-13220</p>
+ </item>
+ <item>
+ <p>
+ Fix race between timeout and exit signal that could cause
+ a process to ignore the exit signal and continue
+ execution. Bug exist since OTP 18.0.</p>
+ <p>
+ Own Id: OTP-13245</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in <c>erlang:halt/1,2</c> for large exit status
+ values, causing either <c>badarg</c> (on 32-bit) or exit
+ with a crash dump and/or core dump (on 64-bit). Make
+ <c>erlang:halt/1,2</c> tolerate any non negative integer
+ as exit status and truncate high order bits if the OS
+ does not support it.</p>
+ <p>
+ Own Id: OTP-13251 Aux Id: ERL-49 </p>
+ </item>
+ <item>
+ <p>
+ <seealso
+ marker="kernel:gen_tcp#accept/2"><c>gen_tcp:accept/2</c></seealso>
+ was not <seealso
+ marker="erts:time_correction#Time_Warp_Safe_Code">time
+ warp safe</seealso>. This since it used the same time as
+ returned by <seealso
+ marker="erts:erlang#now/0"><c>erlang:now/0</c></seealso>
+ when calculating timeout. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-13254 Aux Id: OTP-11997, OTP-13222 </p>
+ </item>
+ <item>
+ <p>
+ Fix faulty error handling when writing to a compressed
+ file.</p>
+ <p>
+ Own Id: OTP-13270</p>
+ </item>
+ <item>
+ <p>
+ Fix sendfile usage for large files on FreeBSD</p>
+ <p>
+ Own Id: OTP-13271</p>
+ </item>
+ <item>
+ <p>
+ Fix bug that could cause
+ <c>process_info(P,current_location)</c> to crash emulator
+ for hipe compiled modules.</p>
+ <p>
+ Own Id: OTP-13282 Aux Id: ERL-79 </p>
+ </item>
+ <item>
+ <p>
+ Out of memory errors have been changed to cause an exit
+ instead of abort.</p>
+ <p>
+ Own Id: OTP-13292</p>
+ </item>
+ <item>
+ <p>
+ When calling <c>garbage_collect/[1,2]</c> or
+ <c>check_process_code/[2,3]</c> from a process with a
+ higher priority than the priority of the process operated
+ on, the run queues could end up in an inconsistent state.
+ This bug has now been fixed.</p>
+ <p>
+ Own Id: OTP-13298 Aux Id: OTP-11388 </p>
+ </item>
+ <item>
+ <p>
+ A workaround for an issue with older gcc versions (less
+ than 5) and inline assembly on 32-bit x86 caused an
+ emulator crash when it had been compiled with a newer gcc
+ version. An improved <c>configure</c> test, run when
+ building OTP, now detects whether the workaround should
+ be used or not.</p>
+ <p>
+ Own Id: OTP-13326 Aux Id: ERL-80 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Introduced new statistics functionality in order to
+ more efficiently retrieve information about run able and
+ active processes and ports. For more information see:</p>
+ <list> <item><seealso
+ marker="erlang#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso></item>
+ <item><seealso
+ marker="erlang#statistics_run_queue_lengths"><c>statistics(run_queue_lengths)</c></seealso></item>
+ <item><seealso
+ marker="erlang#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso></item>
+ <item><seealso
+ marker="erlang#statistics_active_tasks"><c>statistics(active_tasks)</c></seealso></item>
+ </list>
+ <p>
+ Own Id: OTP-13201</p>
+ </item>
+ <item>
+ <p>
+ Time warp safety improvements.</p>
+ <p>
+ Introduced the options <c>monotonic_timestamp</c>, and
+ <c>strict_monotonic_timestamp</c> to the trace,
+ sequential trace, and system profile functionality. This
+ since the already existing <c>timestamp</c> option is not
+ time warp safe.</p>
+ <p>
+ Introduced the option <c>safe_fixed_monotonic_time</c> to
+ <c>ets:info/2</c> and <c>dets:info/2</c>. This since the
+ already existing <c>safe_fixed</c> option is not time
+ warp safe.</p>
+ <p>
+ Own Id: OTP-13222 Aux Id: OTP-11997 </p>
+ </item>
+ <item>
+ <p>
+ Fix a register race where down nodes goes undetected in
+ epmd</p>
+ <p>
+ Own Id: OTP-13301</p>
+ </item>
+ <item>
+ <p>
+ Improved the gcc inline assembly implementing double word
+ atomic compare and exchange on x86/x86_64 so that it also
+ can be used when compiling with clang.</p>
+ <p>
+ Own Id: OTP-13336</p>
+ </item>
+ <item>
+ <p>
+ An optimization preventing a long wait for a scheduler
+ thread looking up information about a process executing
+ on another scheduler thread had unintentionally been lost
+ in erts-5.10 (OTP R16A). This optimization has now been
+ reintroduced.</p>
+ <p>
+ Own Id: OTP-13365 Aux Id: OTP-9892 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Revert "Fix erroneous splitting of emulator path"</p>
+ <p>
+ Own Id: OTP-13202</p>
+ </item>
+ <item>
+ <p>
+ Fix HiPE enabled emulator for FreeBSD.</p>
+ <p>
+ Own Id: OTP-13204 Aux Id: pr926 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Small documentation fixes</p>
+ <p>
+ Own Id: OTP-13017</p>
+ </item>
+ <item>
+ <p>
+ Fix memory corruption bug caused by disabling
+ distribution and then re-enable distribution with a node
+ name that has previously been used by a remote node.</p>
+ <p>
+ Own Id: OTP-13076 Aux Id: seq12959 </p>
+ </item>
+ <item>
+ <p>
+ Renamed variables with name bool as Visual Studio 2015
+ now treats this is a keyword.</p>
+ <p>
+ Own Id: OTP-13079</p>
+ </item>
+ <item>
+ <p><c>erl_prim_loader</c> has not supported custom
+ loaders for several releases. In the documentation for
+ <c>erl_prim_loader</c>, all references to custom loaders
+ have now been removed.</p>
+ <p>
+ Own Id: OTP-13102</p>
+ </item>
+ <item>
+ <p>
+ Fixed compilation of erts together with libc versions
+ that do not define __uint32_t.</p>
+ <p>
+ Own Id: OTP-13105</p>
+ </item>
+ <item>
+ <p>
+ erl -make now returns non-zero exit codes on failure</p>
+ <p>
+ Own Id: OTP-13107</p>
+ </item>
+ <item>
+ <p>
+ Fix crash on init:restart in embedded mode caused by
+ on_load handler process not being relaunched leading to
+ load failure for modules such as crypto and asn1rt_nif
+ that need it to be present for correct NIF loading.</p>
+ <p>
+ Own Id: OTP-13115</p>
+ </item>
+ <item>
+ <p>
+ Fix maps decode in erlang:binary_to_term/1</p>
+ <p>Decoding a term with a large (HAMT) map in an small
+ (FLAT) map could cause a critical error if the external
+ format was not produced by beam.</p>
+ <p>
+ Own Id: OTP-13125</p>
+ </item>
+ <item>
+ <p>
+ Fix very rare bug in GC when big maps with a lot of hash
+ collisions from a remote node are waiting in inner
+ message queue.</p>
+ <p>
+ Own Id: OTP-13146</p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug that could cause a crash dump to become
+ almost empty.</p>
+ <p>
+ Own Id: OTP-13150</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Updated the xmllint target to just check the xml
+ files with real documentation content.<br/> Corrected
+ some errors and added some missing target in the DTD's.
+ </p>
+ <p>
+ Own Id: OTP-13026</p>
+ </item>
+ <item>
+ <p>
+ Add function enif_getenv to read OS environment variables
+ in a portable way from NIFs.</p>
+ <p>
+ Own Id: OTP-13147</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix bug in ETS that could cause stray objects marked for
+ deletion to occasionally be missed by the cleanup done by
+ <c>safe_fixtable(_,false)</c>.</p>
+ <p>
+ Own Id: OTP-12870</p>
+ </item>
+ <item>
+ <p>
+ Fixed VM crash that could occur if a trace port was
+ linked to a process, and the trace port terminated
+ abnormally while handling a trace message. This bug has
+ always existed in the runtime system with SMP support.</p>
+ <p>
+ Own Id: OTP-12901</p>
+ </item>
+ <item>
+ <p>
+ Instead of aborting, the vm now creates a crash dump when
+ a system process is terminated.</p>
+ <p>
+ Own Id: OTP-12934</p>
+ </item>
+ <item>
+ <p>
+ Fixed a rare emulator dead lock that occurred when
+ erlang:process_flag(priority,...) was called by a process
+ that was also scheduled for an internal system activity.</p>
+ <p>
+ Own Id: OTP-12943</p>
+ </item>
+ <item>
+ <p>
+ The runtime system on various posix platforms (except for
+ Linux and Solaris) could crash when large amounts of
+ file-descriptors were in use.</p>
+ <p>
+ Own Id: OTP-12954</p>
+ </item>
+ <item>
+ <p>
+ A beam file compiled by hipe for an incompatible runtime
+ system was sometimes not rejected by the loader, which
+ could lead to vm crash. This fix will also allow the same
+ hipe compiler to be used by both normal and debug-built
+ vm.</p>
+ <p>
+ Own Id: OTP-12962</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in <c>maps:merge/2</c> when called by hipe
+ compiled code that could cause vm crash. Bug exists since
+ erts-7.0 (OTP 18.0).</p>
+ <p>
+ Own Id: OTP-12965</p>
+ </item>
+ <item>
+ <p>
+ When tracing with <c>process_dump</c> option, the VM
+ could abort if there was an ongoing binary match
+ somewhere in the call stack of the traced process.</p>
+ <p>
+ Own Id: OTP-12968</p>
+ </item>
+ <item>
+ <p>
+ Fixed possible output deadlock in tty driver when hitting
+ "CTRL-C" in a non-smp emulator shell on unix.</p>
+ <p>
+ Own Id: OTP-12987 Aux Id: Seq12947 </p>
+ </item>
+ <item>
+ <p>
+ Fix <c>binary_to_integer</c> to throw badarg for "+" and
+ "-" similar to <c>list_to_integer</c>.</p>
+ <p>
+ Own Id: OTP-12988</p>
+ </item>
+ <item>
+ <p>
+ Suppress warning of unused argument when using macro
+ enif_make_pid.</p>
+ <p>
+ Own Id: OTP-12989</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Changed default clock source used for OS system time on
+ MacOS X to <c>gettimeofday()</c> in order to improve
+ performance. The system can be configured during build to
+ use the previously used higher resolution clock source by
+ passing the switch <seealso
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP_Configuring"><c>--with-clock-resolution=high</c></seealso>
+ when configuring the build.</p>
+ <p>
+ Own Id: OTP-12945 Aux Id: OTP-12892 </p>
+ </item>
+ <item>
+ <p>
+ Added the <c>configure</c> option <seealso
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP_Configuring"><c>--disable-saved-compile-time</c></seealso>
+ which disables saving of compile date and time in the
+ emulator binary.</p>
+ <p>
+ Own Id: OTP-12971</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a binary memory leak when printing to shell using
+ the tty driver (i.e. not -oldshell).</p>
+ <p>
+ Own Id: OTP-12941</p>
+ </item>
+ <item>
+ <p>
+ Fix a bug where the standard error port sometimes crashes
+ with eagain as the reason.</p>
+ <p>
+ Own Id: OTP-12942</p>
+ </item>
+ <item>
+ <p>
+ When tracing with <c>process_dump</c> option, the VM
+ could abort if there was an ongoing binary match
+ somewhere in the call stack of the traced process./</p>
+ <p>
+ Own Id: OTP-12968</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A process could end up in an inconsistent half exited
+ state in the runtime system without SMP support. This
+ could occur if the processes was traced by a port that it
+ also was linked to, and the port terminated abnormally
+ while handling a trace message for the process.</p>
+ <p>
+ This bug has always existed in the runtime system without
+ SMP support, but never in the runtime system with SMP
+ support.</p>
+ <p>
+ Own Id: OTP-12889 Aux Id: seq12885 </p>
+ </item>
+ <item>
+ <p>
+ Removed unnecessary copying of data when retrieving
+ corrected Erlang monotonic time.</p>
+ <p>
+ Own Id: OTP-12894</p>
+ </item>
+ <item>
+ <p>
+ Changed default OS monotonic clock source chosen at build
+ time. This in order to improve performance. The behavior
+ will now on most systems be that (both OS and Erlang)
+ monotonic time stops when the system is suspended.</p>
+ <p>
+ If you prefer that monotonic time elapse during suspend
+ of the machine, you can pass the command line argument
+ <c>--enable-prefer-elapsed-monotonic-time-during-suspend</c>
+ to <c>configure</c> when building Erlang/OTP. The
+ configuration stage will try to find such a clock source,
+ but might not be able to find it. Note that there might
+ be a performance penalty associated with such a clock
+ source.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12895</p>
+ </item>
+ <item>
+ <p>
+ <c>erlang:system_info(end_time)</c> returned a faulty
+ value on 32-bit architectures.</p>
+ <p>
+ Own Id: OTP-12896</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The <c>configure</c> command line argument
+ <c>--enable-gettimeofday-as-os-system-time</c> has been
+ added which force usage of <c>gettimeofday()</c> for OS
+ system time. This will improve performance of
+ <c>os:system_time()</c> and <c>os:timestamp()</c> on
+ MacOS X, at the expense of worse accuracy, resolution and
+ precision of Erlang monotonic time, Erlang system time,
+ and OS system time.</p>
+ <p>
+ Own Id: OTP-12892</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a rare hanging of the VM seen to happen just after
+ emulator start. Bug exists since R14.</p>
+ <p>
+ Own Id: OTP-12859 Aux Id: seq12882 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix issuing with spaces and quoting in the arguments when
+ using erlang:open_port spawn_executable on windows. The
+ behavior now mimics how unix works. This change implies a
+ backwards incompatibility for how spawn_executable works
+ on windows.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-11905</p>
+ </item>
+ <item>
+ <p>
+ Fix global call trace when hipe compiled code call beam
+ compiled functions. Tracing of beam functions should now
+ alway work regardless who the caller is.</p>
+ <p>
+ Own Id: OTP-11939</p>
+ </item>
+ <item>
+ <p>
+ Correct cache alignment for ETS <c>write_concurrency</c>
+ locks to improve performance by reduced false sharing.
+ May increase memory footprint for tables with
+ <c>write_concurrency</c>.</p>
+ <p>
+ Own Id: OTP-11974</p>
+ </item>
+ <item>
+ <p>
+ All possibly blocking operations in the fd/spawn and
+ terminal driver have been converted to non-blocking
+ operations. Before this fix it was possible for the VM to
+ be blocked for a long time if the entity consuming
+ stdout/stderr did not consume it fast enough.</p>
+ <p>
+ Own Id: OTP-12239</p>
+ </item>
+ <item>
+ <p>
+ Add missing overhead for offheap binaries created from
+ external format. This fix can improve the garbage
+ collection of large binaries originating from
+ <c>binary_to_term</c> or messages from remote nodes.</p>
+ <p>
+ Own Id: OTP-12554</p>
+ </item>
+ <item>
+ <p>
+ Ensure hashing of zero is consistent</p>
+ <p> Erlang treats positive and negative zero as
+ equal:</p>
+ <p>
+ <c>true = 0.0 =:= 0.0/-1</c></p>
+ <p>However, Erlangs hash functions: hash, phash and
+ phash2 did not reflect this behaviour. The hash values
+ produced by the different hash functions would not be
+ identical for positive and negative zero.</p> <p>This
+ change ensures that hash value of positive zero is always
+ produced regardless of the signedness of the zero float,
+ i.e.,</p>
+ <p>
+ <c>true = erlang:phash2(0.0) =:=
+ erlang:phash2(0.0/-1)</c></p>
+ <p>
+ Own Id: OTP-12641</p>
+ </item>
+ <item>
+ <p>
+ Ensure NIF term creation disallows illegal floating point
+ values and too long atoms. Such values will cause a NIF
+ to throw badarg exception when it returns.</p>
+ <p>
+ Own Id: OTP-12655</p>
+ </item>
+ <item>
+ <p>
+ Fixed building of Map results from match_specs</p>
+ <p>
+ A faulty "box-value" entered into the heap which could
+ cause a segmentation fault in the garbage collector if it
+ was written on a heap fragment.</p>
+ <p>
+ Own Id: OTP-12656</p>
+ </item>
+ <item>
+ <p>
+ Fix hipe bug when matching a "writable" binary. The bug
+ has been seen to sometimes cause a failed binary matching
+ of a correct utf8 character, but other symptoms are also
+ possible.</p>
+ <p>
+ Own Id: OTP-12667</p>
+ </item>
+ <item>
+ <p>
+ Keep dirty schedulers from waking other schedulers.</p>
+ <p>
+ Own Id: OTP-12685</p>
+ </item>
+ <item>
+ <p>
+ Disable floating point exceptions if the VM is compiled
+ by clang/llvm. This is a known long-standing problem in
+ clang/llvm.</p>
+ <p>
+ Own Id: OTP-12717</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in <c>file:sendfile</c> for FreeBSD causing not
+ the entire file to be sent.</p>
+ <p>
+ Own Id: OTP-12720</p>
+ </item>
+ <item>
+ <p>
+ Fix the broken Android support in erl_child_setup.c</p>
+ <p>
+ Own Id: OTP-12751</p>
+ </item>
+ <item>
+ <p>
+ Faulty statistics reported by the <c>fix_alloc</c>
+ allocator.</p>
+ <p>
+ Own Id: OTP-12766</p>
+ </item>
+ <item>
+ <p>
+ Fix two erts_snprintf() calls to correct sizes.</p>
+ <p>
+ - run_erl.c (ose): Use the size of the signal type, not
+ its pointer. - erl_node_tables.c: Use the size of the
+ _BUFFER in erts_snprintf() to make sure we can use the
+ full space.</p>
+ <p>
+ Own Id: OTP-12771</p>
+ </item>
+ <item>
+ <p>
+ Delayed memory allocations could be delayed an
+ unnecessarily long time.</p>
+ <p>
+ Own Id: OTP-12812</p>
+ </item>
+ <item>
+ <p>
+ Make sure that timeouts on a pool of acceptors are
+ released in the correct order.</p>
+ <p>
+ Own Id: OTP-12817</p>
+ </item>
+ <item>
+ <p>
+ Fix segmentation fault in module_info for deleted modules</p>
+ <p>
+ Own Id: OTP-12820</p>
+ </item>
+ <item>
+ <p>Fix garbage collection of literals in code purge</p>
+ <p>During code purging and check_process_code, the
+ checking of the binary reference embedded in the match
+ binary state was omitted for the tracing tests. This
+ would cause the binary match state to reference
+ deallocated memory.</p>
+ <p>
+ Own Id: OTP-12821</p>
+ </item>
+ <item>
+ <p>
+ A bug has been corrected for gen_tcp:close so when
+ {linger,{true,0}} is in effect it does not wait for data
+ in the driver queue to transfer out before closing the
+ port. Bug fix by Rory Byrne.</p>
+ <p>
+ Own Id: OTP-12840</p>
+ </item>
+ <item>
+ <p>
+ The documentation of the driver callback <seealso
+ marker="driver_entry#start"><c>start()</c></seealso>
+ erroneously stated that a return value of
+ <c>ERL_DRV_ERROR_ERRNO</c> caused the error value to be
+ passed via <c>erl_errno</c> when it should have been
+ <c>errno</c>.</p>
+ <p>
+ Own Id: OTP-12855</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add <c>md5</c> and <c>module</c> entries to
+ <c>?MODULE:module_info/0/1</c> and remove obsolete entry
+ 'import'.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-11940</p>
+ </item>
+ <item>
+ <p>
+ Debug function <c>erlang:display/1</c> shows content of
+ binaries and bitstrings, not only the length.</p>
+ <p>
+ Own Id: OTP-11941</p>
+ </item>
+ <item>
+ <p>The time functionality of Erlang has been extended.
+ This both includes a <seealso
+ marker="time_correction#The_New_Time_API">new
+ API</seealso> for time, as well as <seealso
+ marker="time_correction#Time_Warp_Modes">time warp
+ modes</seealso> which alters the behavior of the system
+ when system time changes. <em>You are strongly encouraged
+ to use the new API</em> instead of the old API based on
+ <seealso
+ marker="erlang#now/0"><c>erlang:now/0</c></seealso>.
+ <c>erlang:now/0</c> has been deprecated since it is and
+ forever will be a scalability bottleneck. For more
+ information see the <seealso
+ marker="time_correction">Time and Time
+ Correction</seealso> chapter of the ERTS User's
+ Guide.</p>
+ <p>Besides the API changes and time warp modes a lot of
+ scalability and performance improvements regarding time
+ management has been made internally in the runtime
+ system. Examples of such improvements are scheduler
+ specific timer wheels, scheduler specific BIF timer
+ management, parallel retrieval of monotonic time and
+ system time on systems with primitives that are not
+ buggy.</p>
+ <p>
+ Own Id: OTP-11997</p>
+ </item>
+ <item>
+ <p><c>erlang:function_exported(M, F, A)</c> will now
+ return <c>true</c> if <c>M:F/A</c> refers to a BIF.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12099</p>
+ </item>
+ <item>
+ <p>
+ New BIF: <c>erlang:get_keys/0</c>, lists all keys
+ associated with the process dictionary. Note:
+ <c>erlang:get_keys/0</c> is auto-imported.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12151 Aux Id: seq12521 </p>
+ </item>
+ <item>
+ <p>
+ Make distributed send of large messages yield to improve
+ real-time characteristics.</p>
+ <p>
+ Own Id: OTP-12232</p>
+ </item>
+ <item>
+ <p>
+ Use high accuracy poll timeouts</p>
+ <p>
+ Where available, use poll/select API's that can handle
+ time resolutions less than 1ms. In the cases where such
+ API's are not available the timeout is rounded up to the
+ nearest ms.</p>
+ <p>
+ Own Id: OTP-12236</p>
+ </item>
+ <item>
+ <p>
+ The internal group to user_drv protocol has been changed
+ to be synchronous in order to guarantee that output sent
+ to a process implementing the user_drv protocol is
+ printed before replying. This protocol is used by the
+ standard_output device and the ssh application when
+ acting as a client. </p>
+ <p>
+ This change changes the previous unlimited buffer when
+ printing to standard_io and other devices that end up in
+ user_drv to 1KB.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12240</p>
+ </item>
+ <item>
+ <p>The previously introduced "eager check I/O" feature is
+ now enabled by default.</p>
+ <p>Eager check I/O can be disabled using the <c>erl</c>
+ command line argument: <seealso
+ marker="erl#+secio"><c>+secio false</c></seealso></p>
+ <p>Characteristics impact compared to previous
+ default:</p> <list> <item>Lower latency and smoother
+ management of externally triggered I/O operations.</item>
+ <item>A slightly reduced priority of externally triggered
+ I/O operations.</item> </list>
+ <p>
+ Own Id: OTP-12254 Aux Id: OTP-12117 </p>
+ </item>
+ <item>
+ <p>
+ Properly support maps in match_specs</p>
+ <p>
+ Own Id: OTP-12270</p>
+ </item>
+ <item>
+ <p>
+ The notice that a crashdump has been written has been
+ moved to be printed before the crashdump is generated
+ instead of afterwords. The wording of the notice has also
+ been changed.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12292</p>
+ </item>
+ <item>
+ <p>
+ New function <c>ets:take/2</c>. Works the same as
+ <c>ets:delete/2</c> but also returns the deleted
+ object(s).</p>
+ <p>
+ Own Id: OTP-12309</p>
+ </item>
+ <item>
+ <p>
+ Tracing with cpu_timestamp option has been enabled on
+ Linux.</p>
+ <p>
+ Own Id: OTP-12366</p>
+ </item>
+ <item>
+ <p>
+ ets:info/1,2 now contains information about whether
+ write_concurrency or read_concurrency is enabled.</p>
+ <p>
+ Own Id: OTP-12376</p>
+ </item>
+ <item>
+ <p>
+ Improved usage of <c>gcc</c>'s builtins for atomic memory
+ access. These are used when no other implementation of
+ atomic memory operations is available. For example, when
+ compiling for ARM when <c>libatomic_ops</c> is not
+ available.</p>
+ <p>
+ The largest improvement will be seen when compiling with
+ a <c>gcc</c> with support for the <c>__atomic_*</c>
+ builtins (using a <c>gcc</c> of at least version 4.7),
+ but also when only the legacy <c>__sync_*</c> builtins
+ are available (using a <c>gcc</c> of at least version
+ 4.1) an improvement can be seen.</p>
+ <p>
+ For more information see the "<seealso
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP_Configuring_Atomic-Memory-Operations-and-the-VM">Atomic
+ Memory Operations and the VM</seealso>" section of
+ <c>$ERL_TOP/HOWTO/INSTALL.md</c>.</p>
+ <p>
+ Own Id: OTP-12383</p>
+ </item>
+ <item>
+ <p>
+ Introduce <c>math:log2/1</c> function to math module.</p>
+ <p>
+ Own Id: OTP-12411</p>
+ </item>
+ <item>
+ <p>The documentation of the Abstract Format (in the ERTS
+ User's Guide) has been updated with types and
+ specification. (Thanks to Anthony Ramine.) </p> <p> The
+ explicit representation of parentheses used in types of
+ the abstract format has been removed. Instead the new
+ functions <c>erl_parse:type_inop_prec()</c> and
+ <c>erl_parse:type_preop_prec()</c> can be used for
+ inserting parentheses where needed. </p>
+ <p>
+ Own Id: OTP-12492</p>
+ </item>
+ <item>
+ <p>
+ Remove perfctr support</p>
+ <p>
+ Development of perfctr in the linux kernel ceased in
+ 2010. The perfctr support code in the Erlang VM is thus
+ effectively dead code and therefor removed.</p>
+ <p>
+ Own Id: OTP-12508</p>
+ </item>
+ <item>
+ <p><c>zlib:inflateChunk/2</c> has been added. It works
+ like <c>zlib:inflate/2</c>, but decompresses no more data
+ than will fit in the buffer configured by
+ <c>zlib:setBufSize/2</c>.</p>
+ <p>
+ Own Id: OTP-12548</p>
+ </item>
+ <item>
+ <p>
+ Use linear search for small select_val arrays</p>
+ <p>
+ Own Id: OTP-12555</p>
+ </item>
+ <item>
+ <p>
+ New BIF ets:update_counter/4 with a default object as
+ argument, which will be inserted in the table if the key
+ was not found.</p>
+ <p>
+ Own Id: OTP-12563</p>
+ </item>
+ <item>
+ <p>
+ Export missing types from zlib module</p>
+ <p>
+ Own Id: OTP-12584</p>
+ </item>
+ <item>
+ <p>
+ Use persistent hashmaps for large Maps</p>
+ <p>Maps will use a
+ persistent hashmap implementation when the number of
+ pairs in a Map becomes sufficiently large. The change
+ will occur when a Map reaches 33 pairs in size but this
+ limit might change in the future.</p>
+ <p>The most significant impact for the user by this
+ change is speed, and to a lesser degree memory
+ consumption and introspection of Maps. Memory consumption
+ size is probalistic but lesser than <c>gb_trees</c> or
+ <c>dict</c> for instance. Any other impacts will be
+ transparent for the user except for the following
+ changes.</p>
+ <p>Semantics of Maps have changed in two incompatible
+ ways compared to the experimental implementation in OTP
+ 17:</p> <list> <item>Hashing of maps is done different by
+ <c>erlang:phash2/1,2</c>, <c>erlang:phash/1</c> and
+ <c>erlang:hash/2</c>.</item> <item>Comparing two maps
+ with ==, /=, =&lt;, &lt;, &gt;= and &gt;, is done
+ different if the keys contain floating point
+ numbers.</item> </list>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12585</p>
+ </item>
+ <item>
+ <p>
+ Scalability improvement for <seealso
+ marker="erlang#make_ref/0">erlang:make_ref/0</seealso>,
+ and other functionality that create references. Each
+ scheduler now manage its own set of references. By this
+ no communication at all is needed when creating
+ references.</p>
+ <p>
+ Previous implementation generated a strictly
+ monotonically increasing sequence of references
+ corresponding to creation time on the runtime system
+ instance. This is <em>not</em> the case with current
+ implementation. You can only expect reference to be
+ unique. The Erlang/OTP documentation has never mentioned
+ anything else but the uniqueness property, so this change
+ <em>is</em> fully compatible. The only reason we've
+ marked this as a potential incompatibility is since an
+ early draft for an Erlang specification mentions strict
+ monotonicity as a property.</p>
+ <p>
+ If you need to create data with a strict monotonicity
+ property use <seealso
+ marker="erlang#unique_integer/1">erlang:unique_integer([monotonic])</seealso>.
+ Do <em>not</em> use the deprecated <seealso
+ marker="erlang#now/0">erlang:now()</seealso>.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12610</p>
+ </item>
+ <item>
+ <p>
+ Enable different abort signal from heart</p>
+ <p>By using environment variable HEART_KILL_SIGNAL, heart
+ can now use a different signal to kill the old running
+ Erlang.</p>
+ <p>By default the signal is SIGKILL but SIGABRT may also
+ be used by setting environment variable:
+ HEART_KILL_SIGNAL=SIGABRT</p>
+ <p>
+ Own Id: OTP-12613 Aux Id: seq12826 </p>
+ </item>
+ <item>
+ <p>
+ Update autconf to latest version 2015-03-04</p>
+ <p>
+ Own Id: OTP-12646</p>
+ </item>
+ <item>
+ <p>
+ Optimization of timers internally in the VM. This include
+ process timers (<c>receive ... after</c>), port timers
+ (<c>driver_set_timer()</c>) as well as BIF timers
+ (<c>erlang:send_after()</c>/<c>erlang:start_timer()</c>).</p>
+ <p>
+ Each scheduler thread now has its own lock-free timer
+ service instead of one locked central service. This
+ dramatically improves performance of timer management on
+ systems with a large amount of schedulers and timers.</p>
+ <p>
+ The timer service internal data structure has also been
+ optimized to be able to handle more timers than before.
+ That is, each timer service is by its self able to handle
+ more timers without dramatic performance loss than the
+ old centralized timer service.</p>
+ <p>
+ The API of BIF timers has also been extended. Timeout
+ values are for example no longer limited to 32-bit
+ integers. For more information see the documentation of
+ <seealso
+ marker="erlang#start_timer/4"><c>erlang:start_timer/4</c></seealso>,
+ <seealso
+ marker="erlang#send_after/4"><c>erlang:send_after/4</c></seealso>,
+ <seealso
+ marker="erlang#cancel_timer/2"><c>erlang:cancel_timer/2</c></seealso>,
+ and <seealso
+ marker="erlang#read_timer/2"><c>erlang:read_timer/2</c></seealso>.</p>
+ <p>
+ Characteristics impact: Calls to the synchronous versions
+ of <c>erlang:cancel_timer()</c>, and
+ <c>erlang:read_timer()</c> may take substantially longer
+ time to complete than before. This occur when the timer
+ that is accessed is managed by a remote scheduler. You
+ typically want to use the new asynchronous option in
+ order to avoid blocking the calling process.</p>
+ <p>
+ Own Id: OTP-12650 Aux Id: OTP-11997 </p>
+ </item>
+ <item>
+ <p>
+ Specialize instructions from common assembler patterns</p>
+ <p>Specialize common instructions of <c>rem</c>,
+ <c>band</c>, <c>minus</c> and <c>plus</c> in the beam
+ loader. This will reduce the number of fetches and thus
+ lessen the instruction dispatch pressure during runtime
+ and speed up those operations in some common cases.</p>
+ <p>Specialize move patterns from x-registers to the stack
+ with a new <c>move_window</c> instruction. This change
+ will reduce instruction dispatch pressure.</p>
+ <p>
+ Own Id: OTP-12690</p>
+ </item>
+ <item>
+ <p>
+ Fix cross compilation for Android.</p>
+ <p>
+ Own Id: OTP-12693</p>
+ </item>
+ <item>
+ <p>
+ Fix incorrect use of autoconf macro AC_EGREP_CPP, which
+ could cause faulty configuration if run from a path
+ containing the string 'yes'.</p>
+ <p>
+ Own Id: OTP-12706</p>
+ </item>
+ <item>
+ <p>
+ Minimal Java version is now 1.6</p>
+ <p>
+ Own Id: OTP-12715</p>
+ </item>
+ <item>
+ <p>
+ Send format and args on process exit to error_logger</p>
+ <p>
+ Previously, the emulator would generate a whole string
+ with values and call the error_logger passing
+ <c>"~s~n"</c>. This changes it to a format string
+ containing <c>~p</c> with the respective values as
+ arguments.</p>
+ <p>
+ Own Id: OTP-12735</p>
+ </item>
+ <item>
+ <p>
+ Map error logger warnings to warning messages by default.</p>
+ <p>
+ Own Id: OTP-12755</p>
+ </item>
+ <item>
+ <p>
+ Configure architecture ppc64le architecture as a ppc64</p>
+ <p>
+ Own Id: OTP-12761</p>
+ </item>
+ <item>
+ <p>
+ Add function <c>enif_raise_exception</c> to allow a NIF
+ to raise an error exception with any type of reason.</p>
+ <p>
+ Own Id: OTP-12770</p>
+ </item>
+ <item>
+ <p>
+ Optimized node table statistics retrieval.</p>
+ <p>
+ Own Id: OTP-12777</p>
+ </item>
+ <item>
+ <p>
+ Map beam error logger warnings to warning messages by
+ default. Previously these messages were mapped to the
+ error channel by default.</p>
+ <p>
+ Own Id: OTP-12781</p>
+ </item>
+ <item>
+ <p>
+ gen_tcp:shutdown/2 is now asynchronous</p>
+ <p>
+ This solves the following problems with the old
+ implementation:</p>
+ <p>
+ It doesn't block when the TCP peer is idle or slow. This
+ is the expected behaviour when shutdown() is called: the
+ caller needs to be able to continue reading from the
+ socket, not be prevented from doing so.</p>
+ <p>
+ It doesn't truncate the output. The current version of
+ gen_tcp:shutdown/2 will truncate any outbound data in the
+ driver queue after about 10 seconds if the TCP peer is
+ idle of slow. Worse yet, it doesn't even inform anyone
+ that the data has been truncated: 'ok' is returned to the
+ caller; and a FIN rather than an RST is sent to the TCP
+ peer.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12797</p>
+ </item>
+ <item>
+ <p>
+ Introduced delayed node table GC. This in order to avoid
+ oscillation of entries in and out of the tables. The
+ oscillation caused unnecessary lock contention on the
+ table locks. The delay length can be set by passing the
+ <seealso marker="erl#+zdntgc"><c>+zdntgc</c></seealso>
+ command line argument.</p>
+ <p>
+ Characteristics impact: The tables can grow to very large
+ sizes with unused entries if the node is get huge amounts
+ of short lived connections from other nodes. This problem
+ can be alleviated by shortening the length of the delay
+ using the <c>+zdntgc</c> command line argument.</p>
+ <p>
+ Own Id: OTP-12802</p>
+ </item>
+ <item>
+ <p>Improved implementation of <seealso
+ marker="erlang#statistics/1"><c>erlang:statistics</c></seealso><c>(io)</c>
+ in order to reduce contention between schedulers.</p>
+ <p>Characteristics impact: The actual call to
+ <c>erlang:statistics(io)</c> takes longer time to
+ complete, but the overall impact on the system is
+ improved.</p>
+ <p>
+ Own Id: OTP-12842</p>
+ </item>
+ <item>
+ <p>
+ There are many cases where user code needs to be able to
+ distinguish between a socket that was closed normally and
+ one that was aborted. Setting the option
+ {show_econnreset, true} enables the user to receive
+ ECONNRESET errors on both active and passive sockets.</p>
+ <p>
+ Own Id: OTP-12843</p>
+ </item>
+ <item>
+ <p>
+ Do not preallocate too large event pool</p>
+ <p>
+ A default pool size of 4000 is too excessive for the
+ common case. This corresponds directly to the number of
+ threads in the system. Change
+ ERTS_TS_EV_ALLOC_DEFAULT_POOL_SIZE to 2048. Change
+ ERTS_TS_EV_ALLOC_POOL_SIZE to 32.</p>
+ <p>
+ Own Id: OTP-12849</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 6.4.1.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a bug that could cause a crash dump to become
+ almost empty.</p>
+ <p>
+ Own Id: OTP-13150</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 6.4.1.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The 'raw' socket option could not be used multiple times
+ in one call to any e.g gen_tcp function because only one
+ of the occurrences were used. This bug has been fixed,
+ and also a small bug concerning propagating error codes
+ from within inet:setopts/2.</p>
+ <p>
+ Own Id: OTP-11482 Aux Id: seq12872 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
<section><title>Erts 6.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -418,7 +1782,7 @@
<p>
Improved support for atomic memory operations provided by
the <url
- href="https://github.com/ivmai/libatomic_ops/"><c>libatomic_ops</c></url>
+ href="https://github.com/ivmai/libatomic_ops/">libatomic_ops</url>
library. Most importantly support for use of native
double word atomics when implemented by
<c>libatomic_ops</c> (for example, implemented for ARM).</p>
@@ -1385,22 +2749,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -3560,8 +4930,7 @@
<p>
Fix erl_prim_loader errors in handling of primary
archive. The following errors have been corrected:</p>
- <p>
- <list> <item> If primary archive was named "xxx", then a
+ <list> <item> If primary archive was named "xxx", then a
file in the same directory named "xxxyyy" would be
interpreted as a file named "yyy" inside the archive.
</item> <item> erl_prim_loader did not correctly create
@@ -3576,7 +4945,8 @@
erl_prim_loader:list_dir/1 would sometimes return an
empty string inside the file list. This was a virtual
element representing the top directory of the archive.
- This has been removed. </item> </list></p>
+ This has been removed. </item>
+ </list>
<p>
Thanks to Tuncer Ayaz and Shunichi Shinohara for
reporting and co-authoring corrections.</p>
@@ -6019,12 +7389,12 @@
Own Id: OTP-8726 Aux Id: seq11617 </p>
</item>
<item>
- <p>Fix libm linking with --as-needed flag
+ <p>Fix libm linking with --as-needed flag</p>
<p>
When building with "--as-needed" linker flags on Linux
the build will fail. This has now been fixed.</p>
<p>
- (Thanks to Christian Faulhammer)</p></p>
+ (Thanks to Christian Faulhammer)</p>
<p>
Own Id: OTP-8728</p>
</item>
diff --git a/erts/doc/src/notes_history.xml b/erts/doc/src/notes_history.xml
index 4420311912..0886ae4039 100644
--- a/erts/doc/src/notes_history.xml
+++ b/erts/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml
index 7b17b5b551..2f5eca93db 100644
--- a/erts/doc/src/part.xml
+++ b/erts/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/part_notes.xml b/erts/doc/src/part_notes.xml
index b5c8f0af09..83bb479715 100644
--- a/erts/doc/src/part_notes.xml
+++ b/erts/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/part_notes_history.xml b/erts/doc/src/part_notes_history.xml
index a99fa4a17f..055d1681d5 100644
--- a/erts/doc/src/part_notes_history.xml
+++ b/erts/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml
index 8ed7090a61..ac589f8cb5 100644
--- a/erts/doc/src/ref_man.xml
+++ b/erts/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/run_erl.xml b/erts/doc/src/run_erl.xml
index 28e94c6da8..0a5b2c6136 100644
--- a/erts/doc/src/run_erl.xml
+++ b/erts/doc/src/run_erl.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/start.xml b/erts/doc/src/start.xml
index e9a5714f93..386fbe6e88 100644
--- a/erts/doc/src/start.xml
+++ b/erts/doc/src/start.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/start_erl.xml b/erts/doc/src/start_erl.xml
index fe808f7737..62610b43b0 100644
--- a/erts/doc/src/start_erl.xml
+++ b/erts/doc/src/start_erl.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/time_correction.xml b/erts/doc/src/time_correction.xml
index 7f7c28fc30..236fe679cb 100644
--- a/erts/doc/src/time_correction.xml
+++ b/erts/doc/src/time_correction.xml
@@ -4,25 +4,26 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2014</year>
+ <year>1999</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
- <title>Time and time correction in Erlang</title>
- <prepared>Patrik Nyblom</prepared>
+ <title>Time and Time Correction in Erlang</title>
+ <prepared></prepared>
<responsible></responsible>
<docno></docno>
<approved></approved>
@@ -31,244 +32,871 @@
<rev>PA1</rev>
<file>time_correction.xml</file>
</header>
+
+ <section>
+ <title>New Extended Time Functionality</title>
+ <note><p>As of OTP 18 (<c>ERTS</c> version 7.0) the time functionality of
+ Erlang has been extended. This includes a
+ <seealso marker="#The_New_Time_API">new API</seealso>
+ for time and
+ <seealso marker="#Time_Warp_Modes">time warp
+ modes</seealso> that alter the system behavior when
+ system time changes.</p>
+
+ <p>The <seealso marker="#No_Time_Warp_Mode">default
+ time warp mode</seealso> has the same behavior as before, and the
+ old API still works. Thus, you are not required to change
+ anything unless you want to. However, <em>you are strongly
+ encouraged to use the new API</em> instead of the old API based
+ on <seealso marker="erlang#now/0"><c>erlang:now/0</c></seealso>.
+ <c>erlang:now/0</c> is deprecated, as it is and
+ will be a scalability bottleneck.</p>
+
+ <p>By using the new API, you
+ automatically get scalability and performance improvements. This
+ also enables you to use the
+ <seealso marker="#Multi_Time_Warp_Mode">multi-time warp mode</seealso>
+ that improves accuracy and precision of time measurements.</p>
+ </note>
+ </section>
+
+ <section>
+ <title>Terminology</title>
+ <p>To make it easier to understand this section, some terms
+ are defined. This is a mix of our own terminology
+ (Erlang/OS system time, Erlang/OS monotonic time, time warp)
+ and globally accepted terminology.</p>
+
+ <marker id="Monotonically_Increasing"/>
+ <section>
+ <title>Monotonically Increasing</title>
+ <p>In a monotonically increasing sequence of values, all values
+ that have a predecessor are either larger than or equal to its
+ predecessor.</p>
+ </section>
+
+ <marker id="Strictly_Monotonically_Increasing"/>
+ <section>
+ <title>Strictly Monotonically Increasing</title>
+ <p>In a strictly monotonically increasing sequence of values,
+ all values that have a predecessor are larger than its
+ predecessor.</p>
+ </section>
+
+ <marker id="UT1"/>
+ <section>
+ <title>UT1</title>
+ <p>Universal Time. UT1 is based on the rotation of the earth
+ and conceptually means solar time at 0° longitude.</p>
+ </section>
+
+ <marker id="UTC"/>
+ <section>
+ <title>UTC</title>
+ <p>Coordinated Universal Time. UTC almost aligns with
+ <seealso marker="#UT1">UT1</seealso>. However, UTC uses the
+ SI definition of a second, which has not exactly the same length
+ as the second used by UT1. This means that UTC slowly drifts from
+ UT1. To keep UTC relatively in sync with UT1, leap seconds
+ are inserted, and potentially also deleted. That is, an UTC day can
+ be 86400, 86401, or 86399 seconds long.</p>
+ </section>
+
+ <marker id="POSIX_Time"/>
+ <section>
+ <title>POSIX Time</title>
+ <p>Time since
+ <url href="http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap03.html#tag_21_03_00_17">Epoch</url>.
+ Epoch is defined to be 00:00:00 <seealso marker="#UTC">UTC</seealso>,
+ 1970-01-01.
+ <url href="http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap04.html#tag_04_14">A day in POSIX time</url>
+ is defined to be exactly 86400 seconds long. Strangely enough
+ Epoch is defined to be a time in UTC, and UTC has another
+ definition of how long a day is. Quoting the Open Group
+ <url href="http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_15">"POSIX time is therefore not necessarily UTC, despite its appearance"</url>.
+ The effect of this is that when an UTC leap second is
+ inserted, POSIX time either stops for a second, or repeats the
+ last second. If an UTC leap second would be deleted (which has not
+ happened yet), POSIX time would make a one second leap forward.</p>
+ </section>
+
+ <marker id="Time_Resolution"/>
+ <section>
+ <title>Time Resolution</title>
+ <p>The shortest time interval that can be distinguished when
+ reading time values.</p>
+ </section>
+
+ <marker id="Time_Precision"/>
+ <section>
+ <title>Time Precision</title>
+ <p>The shortest time interval that can be distinguished
+ repeatedly and reliably when reading time values. Precision
+ is limited by the
+ <seealso marker="#Time_Resolution">resolution</seealso>, but
+ resolution and precision can differ significantly.</p>
+ </section>
+
+ <marker id="Time_Accuracy"/>
+ <section>
+ <title>Time Accuracy</title>
+ <p>The correctness of time values.</p>
+ </section>
+
+ <marker id="Time_Warp"/>
+ <section>
+ <title>Time Warp</title>
+ <p>A time warp is a leap forwards or backwards in time. That
+ is, the difference of time values taken before and after the
+ time warp does not correspond to the actual elapsed time.</p>
+ </section>
+
+ <marker id="OS_System_Time"/>
+ <section>
+ <title>OS System Time</title>
+ <p>The operating systems view of
+ <seealso marker="#POSIX_Time">POSIX time</seealso>. To
+ retrieve it, call
+ <seealso marker="kernel:os#system_time/0"><c>os:system_time()</c></seealso>.
+ This may or may not be an accurate view of POSIX time. This time
+ may typically be adjusted both backwards and forwards without
+ limitation. That is, <seealso marker="#Time_Warp">time warps</seealso>
+ may be observed.</p>
+
+ <p>To get information about the Erlang runtime
+ system's source of OS system time, call
+ <seealso marker="erlang#system_info_os_system_time_source"><c>erlang:system_info(os_system_time_source)</c></seealso>.</p>
+ </section>
+
+ <marker id="OS_Monotonic_Time"/>
+ <section>
+ <title>OS Monotonic Time</title>
+ <p>A monotonically increasing time provided by the operating
+ system. This time does not leap and has a relatively steady
+ frequency although not completely correct. However, it is not
+ uncommon that OS monotonic time stops if the system is
+ suspended. This time typically increases since some
+ unspecified point in time that is not connected to
+ <seealso marker="#OS_System_Time">OS system time</seealso>.
+ This type of time is not necessarily provided by all
+ operating systems.</p>
+
+ <p>To get information about the Erlang
+ runtime system's source of OS monotonic time, call
+ <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>.</p>
+ </section>
+
+ <marker id="Erlang_System_Time"/>
+ <section>
+ <title>Erlang System Time</title>
+ <p>The Erlang runtime systems view of
+ <seealso marker="#POSIX_Time">POSIX time</seealso>. To
+ retrieve it, call
+ <seealso marker="erlang#system_time/0"><c>erlang:system_time()</c></seealso>.</p>
+
+ <p>This time may or may not be an accurate view of POSIX time,
+ and may
+ or may not align with <seealso marker="#OS_System_Time">OS system
+ time</seealso>. The runtime system works towards aligning the two
+ system times. Depending on the
+ <seealso marker="#Time_Warp_Modes">time warp mode</seealso> used,
+ this can be achieved by letting Erlang
+ system time perform a <seealso marker="#Time_Warp">time
+ warp</seealso>.</p>
+ </section>
+
+ <marker id="Erlang_Monotonic_Time"/>
+ <section>
+ <title>Erlang Monotonic Time</title>
+ <p>A monotonically increasing time provided by the
+ Erlang runtime system. Erlang monotonic time increases since
+ some unspecified point in time. To retrieve it, call
+ <seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time()</c></seealso>.
+ </p>
+
+ <p>The <seealso marker="#Time_Accuracy">accuracy</seealso> and
+ <seealso marker="#Time_Precision">precision</seealso> of Erlang
+ monotonic time heavily depends on the following:</p>
+
+ <list type="bulleted">
+ <item>Accuracy and precision of
+ <seealso marker="#OS_Monotonic_Time">OS monotonic time</seealso>
+ </item>
+ <item>Accuracy and precision of
+ <seealso marker="#OS_System_Time">OS system time</seealso>
+ </item>
+ <item><seealso marker="#Time_Warp_Modes">time warp mode</seealso> used
+ </item>
+ </list>
+
+ <p>On a system without OS monotonic time, Erlang monotonic
+ time guarantees monotonicity, but cannot give
+ other guarantees. The frequency adjustments made to
+ Erlang monotonic time depend on the time warp mode used.</p>
+
+ <p>Internally in the runtime system, Erlang monotonic
+ time is the "time engine" that is used for more or less
+ everything that has anything to do with time. All timers,
+ regardless of it is a <c>receive ... after</c> timer, BIF timer,
+ or a timer in the <c>timer</c> module, are triggered
+ relative Erlang monotonic time. Even
+ <seealso marker="#Erlang_System_Time">Erlang system
+ time</seealso> is based on Erlang monotonic time.
+ By adding current Erlang monotonic time with current time
+ offset, you get current Erlang system time.</p>
+
+ <p>To retrieve current time offset, call
+ <seealso marker="erlang#time_offset/0"><c>erlang:time_offset/0</c></seealso>.
+ </p>
+ </section>
+
+ </section>
+
+ <section>
+ <title>Introduction</title>
<p>Time is vital to an Erlang program and, more importantly, <em>correct</em>
time is vital to an Erlang program. As Erlang is a language with
- soft real time properties and we have the possibility to express
- time in our programs, the Virtual Machine and the language has to be
- very careful about what is considered a correct point in time and in
+ soft real-time properties and we can express
+ time in our programs, the Virtual Machine and the language must be
+ careful about what is considered a correct time and in
how time functions behave.</p>
- <p>In the beginning, Erlang was constructed assuming that the wall
+ <p>When Erlang was designed, it was assumed that the wall
clock time in the system showed a monotonic time moving forward at
- exactly the same pace as the definition of time. That more or less
- meant that an atomic clock (or better) was expected to be attached
+ exactly the same pace as the definition of time. This more or less meant
+ that an atomic clock (or better time source) was expected to be attached
to your hardware and that the hardware was then expected to be
- locked away from any human (or unearthly) tinkering for all
- eternity. While this might be a compelling thought, it's simply
- never the case.</p>
-
- <p>A "normal" modern computer can not keep time. Not on itself and
- not unless you actually have a chip level atomic clock wired to
- it. Time, as perceived by your computer, will normally need to be
- corrected. Hence the NTP protocol that together with the ntpd
- process will do it's best to keep your computers time in sync with
- the "real" time in the universe. Between NTP corrections, usually a
+ locked away from any human tinkering forever. While this can be a
+ compelling thought, it is simply never the case.</p>
+
+ <p>A "normal" modern computer cannot keep time, not on itself and
+ not unless you have a chip-level atomic clock wired to it. Time,
+ as perceived by your computer, must normally be corrected. Hence
+ the Network Time Protocol (NTP) protocol, together with the <c>ntpd</c>
+ process, does its best to keep your computer time in sync with
+ the correct time. Between NTP corrections, usually a
less potent time-keeper than an atomic clock is used.</p>
- <p>But NTP is not fail safe. The NTP server can be unavailable, the
- ntp.conf can be wrongly configured or your computer may from time to
- time be disconnected from the internet. Furthermore you can have a
- user (or even system administrator) on your system that thinks the
- right way to handle daylight saving time is to adjust the clock one
- hour two times a year (a tip, that is not the right way to do
- it...). To further complicate things, this user fetched your
- software from the internet and has never ever thought about what's
- the correct time as perceived by a computer. The user simply does
- not care about keeping the wall clock in sync with the rest of the
- universe. The user expects your program to have omnipotent knowledge
+ <p>However, NTP is not fail-safe. The NTP server can be unavailable,
+ <c>ntp.conf</c> can be wrongly configured, or your computer may
+ sometimes be disconnected from Internet. Furthermore, you can have a
+ user (or even system administrator) who thinks the correct
+ way to handle Daylight Saving Time is to adjust the clock one
+ hour two times a year (which is the incorrect way to do it).
+ To complicate things further, this user fetched your
+ software from Internet and has not considered what
+ the correct time is as perceived by a computer. The user does
+ not care about keeping the wall clock in sync with the correct
+ time. The user expects your program to have unlimited knowledge
about the time.</p>
<p>Most programmers also expect time to be reliable, at least until
- they realize that the wall clock time on their workstation is of by
- a minute. Then they simply set it to the correct time, maybe or
- maybe not in a smooth way. Most probably not in a smooth way.</p>
+ they realize that the wall clock time on their workstation is off by
+ a minute. Then they set it to the correct time, but most probably
+ not in a smooth way.</p>
- <p>The amount of problems that arise when you expect the wall clock
- time on the system to always be correct may be immense. Therefore Erlang
+ <p>The number of problems that arise when you always expect the wall clock
+ time on the system to be correct can be immense. Erlang therefore
introduced the "corrected estimate of time", or the "time
- correction" many years ago. The time correction relies on the fact
+ correction", many years ago. The time correction relies on the fact
that most operating systems have some kind of monotonic clock,
- either a real time extension or some built in "tick counter" that is
- independent of the wall clock settings. This counter may have
- microsecond resolution or much less, but generally it has a drift
- that is not to be ignored.</p>
-
- <p>So we have this monotonic ticking and we have the wall clock
- time. Two unreliable times that together can give us an estimate of
- an actual wall clock time that does not jump around and that
- monotonically moves forward. If the tick counter has a high
- resolution, this is fairly easy to do, if the counter has a low
- resolution, it's more expensive, but still doable down to
- frequencies of 50-60 Hz (of the tick counter).</p>
-
- <p>So the corrected time is the nearest approximation of an atomic
- clock that is available on the computer. We want it to have the
- following properties:</p>
- <taglist>
- <tag>Monotonic</tag>
- <item>The clock should not move backwards</item>
- <tag>Intervals should be near the truth</tag>
- <item>We want the actual time (as measured by an atomic clock or
- an astronomer) that passes between two time stamps, T1 and T2, to be as
- near to T2 - T1 as possible.</item>
- <tag>Tight coupling to the wall clock</tag>
- <item>We want a timer that is to be fired when the wall clock
- reaches a time in the future, to fire as near to that point in
- time as possible</item>
- </taglist>
- <p>To meet all the criteria, we have to utilize both times in such a
- way that Erlangs "corrected time" moves slightly slower or slightly
- faster than the wall clock to get in sync with it. The word
- "slightly" means a maximum of 1% difference to the wall clock time,
- meaning that a sudden change in the wall clock of one minute, takes
- 100 minutes to fix, by letting all "corrected time" move 1% slower
- or faster.</p>
-
- <p>Needless to say, correcting for a faulty handling of daylight
- saving time may be disturbing to a user comparing wall clock
- time to for example calendar:now_to_local_time(erlang:now()). But
- calendar:now_to_local_time/1 is not supposed to be used for presenting wall
- clock time to the user.</p>
-
- <p>Time correction is not perfect, but it saves you from the havoc
- of clocks jumping around, which would make timers in your program
- fire far to late or far to early and could bring your whole system
- to it's knees (or worse) just because someone detected a small error
- in the wall clock time of the server where your program runs. So
- while it might be confusing, it is still a really good feature of
- Erlang and you should not throw it away using time functions which
- may give you higher benchmark results, not unless you really know
- what you're doing.</p>
+ either a real-time extension or some built-in "tick counter" that is
+ independent of the wall clock settings. This counter can have
+ microsecond resolution or much less, but it has a drift that cannot
+ be ignored.</p>
+ </section>
<section>
- <title>What does time correction mean in my system?</title>
- <p>Time correction means that Erlang estimates a time from current
- and previous settings of the wall clock, and it uses a fairly
- exact tick counter to detect when the wall clock time has jumped
- for some reason, slowly adjusting to the new value.</p>
-
- <p>In practice, this means that the difference between two calls
- to time corrected functions, like erlang:now(), might differ up to
- one percent from the corresponding calls to non time corrected
- functions (like os:timestamp()). Furthermore, if comparing
- calendar:local_time/0 to calendar:now_to_local_time(erlang:now()),
- you might temporarily see a difference, depending on how well kept your
- system is.</p>
-
- <p>It is important to understand that it is (to the program)
- always unknown if it is the wall clock time that moves in the
- wrong pace or the Erlang corrected time. The only way to determine
- that, is to have an external source of universally correct time. If
- some such source is available, the wall clock time can be kept
- nearly perfect at all times, and no significant difference will be
- detected between erlang:now/0's pace and the wall clock's.</p>
-
- <p>Still, the time correction will mean that your system keeps
- it's real time characteristics very well, even when the wall clock
- is unreliable.</p>
+ <marker id="Time_Correction"/>
+ <title>Time Correction</title>
+ <p>If time correction is enabled, the Erlang runtime system
+ makes use of both
+ <seealso marker="#OS_System_Time">OS system time</seealso>
+ and <seealso marker="#OS_Monotonic_Time">OS monotonic time</seealso>,
+ to adjust the frequency of the Erlang
+ monotonic clock. Time correction ensures that
+ <seealso marker="#Erlang_Monotonic_Time">Erlang monotonic time</seealso>
+ does not warp and that the frequency is relatively accurate.
+ The type of frequency adjustments depends on the time warp mode used.
+ Section <seealso marker="#Time_Warp_Modes">Time Warp Modes</seealso>
+ provides more details.</p>
+
+ <p>By default time correction is enabled if support for
+ it exists on the specific platform. Support for it includes
+ both OS monotonic time, provided by the OS, and an
+ implementation in the Erlang runtime system using
+ OS monotonic time. To check if your system has support
+ for OS monotonic time, call
+ <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>.
+ To check if time correction is enabled on your system, call
+ <seealso marker="erlang#system_info_time_correction"><c>erlang:system_info(time_correction)</c></seealso>.</p>
+
+ <p>To enable or disable time correction, pass command-line argument
+ <seealso marker="erl#+c"><c>+c [true|false]</c></seealso>
+ to <c>erl</c>.</p>
+
+ <p>If time correction is disabled, Erlang monotonic time
+ may warp forwards or stop, or even freeze for extended
+ periods of time. There are then no guarantees that the frequency
+ of the Erlang monotonic clock is accurate or stable.</p>
+
+ <p><em>You typically never want to disable time correction</em>.
+ Previously a performance penalty was associated with time
+ correction, but nowadays it is usually the other way around.
+ If time correction is disabled, you probably get bad scalability,
+ bad performance, and bad time measurements.</p>
</section>
+
<section>
- <title>Where does Erlang use corrected time?</title>
- <p>For all functionality where real time characteristics are
- desirable, time correction is used. This basically means:</p>
- <taglist>
- <tag>erlang:now/0</tag>
- <item>The infamous erlang:now/0 function uses time correction so
- that differences between two "now-timestamps" will correspond to
- other timeouts in the system. erlang:now/0 also holds other
- properties, discussed later.</item>
- <tag>receive ... after</tag>
- <item>Timeouts on receive uses time correction to determine a
- stable timeout interval.</item>
- <tag>The timer module</tag>
- <item>As the timer module uses other built in functions which
- deliver corrected time, the timer module itself works with
- corrected time.</item>
- <tag>erlang:start_timer/3 and erlang:send_after/3</tag>
- <item>The timer BIF's work with corrected time, so that they
- will not fire prematurely or too late due to changes in the wall
- clock time.</item>
- </taglist>
-
- <p>All other functionality in the system where erlang:now/0 or any
- other time corrected functionality is used, will of course
- automatically benefit from it, as long as it's not "optimized" to
- use some other time stamp function (like os:timestamp/0).</p>
-
- <p>Modules like calendar and functions like erlang:localtime/0 use
- the wall clock time as it is currently set on the system. They
- will not use corrected time. However, if you use a now-value and
- convert it to local time, you will get a corrected local time
- value, which may or may not be what you want. Typically older code
- tend to use erlang:now/0 as a wall clock time, which is usually
- correct (at least when testing), but might surprise you when
- compared to other times in the system.</p>
+ <marker id="Time_Warp_Safe_Code"/>
+ <title>Time Warp Safe Code</title>
+ <p>Time warp safe code can handle
+ a <seealso marker="#Time_Warp">time warp</seealso> of
+ <seealso marker="#Erlang_System_Time">Erlang system time</seealso>.</p>
+
+ <p><seealso marker="erlang#now/0"><c>erlang:now/0</c></seealso>
+ behaves bad when Erlang system time warps. When Erlang
+ system time does a time warp backwards, the values returned
+ from <c>erlang:now/0</c> freeze (if you disregard the
+ microsecond increments made because of the actual call) until
+ OS system time reaches the point of the last value returned by
+ <c>erlang:now/0</c>. This freeze can continue for a long time. It
+ can take years, decades, and even longer until the freeze stops.</p>
+
+ <p>All uses of <c>erlang:now/0</c> are not necessarily
+ time warp unsafe. If you do not use it to get time, it
+ is time warp safe. However, <em>all uses of
+ <c>erlang:now/0</c> are suboptimal</em> from a performance
+ and scalability perspective. So you really want to replace
+ the use of it with other functionality. For examples
+ of how to replace the use of <c>erlang:now/0</c>, see Section
+ <seealso marker="#Dos_and_Donts">How to Work with the New
+ API</seealso>.</p>
</section>
+
<section>
- <title>What is erlang:now/0 really?</title>
- <p>erlang:now/0 is a function designed to serve multiple purposes
- (or a multi-headed beast if you're a VM designer). It is expected
- to hold the following properties:</p>
- <taglist>
- <tag>Monotonic</tag>
- <item>erlang:now() never jumps backwards - it always moves
- forward</item>
- <tag>Interval correct</tag>
- <item>The interval between two erlang:now() calls is expected to
- correspond to the correct time in real life (as defined by an
- atomic clock, or better)</item>
- <tag>Absolute correctness</tag>
- <item>The erlang:now/0 value should be possible to convert to an
- absolute and correct date-time, corresponding to the real world
- date and time (the wall clock)</item>
- <tag>System correspondence</tag>
- <item>The erlang:now/0 value converted to a date-time is
- expected to correspond to times given by other programs on the
- system (or by functions like os:timestamp/0)</item>
- <tag>Unique</tag>
- <item>No two calls to erlang:now on one Erlang node should
- return the same value</item>
- </taglist>
- <p>All these requirements are possible to uphold at the same
- time if (and only if):</p>
- <taglist>
- <tag>The wall clock time of the system is perfect</tag>
- <item>The system (Operating System) time needs to be perfectly
- in sync with the actual time as defined by an atomic clock or
- a better time source. A good installation using NTP, and that is
- up to date before Erlang starts, will have properties that for
- most users and programs will be near indistinguishable from the
- perfect time. Note that any larger corrections to the time done
- by hand, or after Erlang has started, will partly (or
- temporarily) invalidate some of the properties, as the time is
- no longer perfect.</item>
- <tag>Less than one call per microsecond to erlang:now/0 is
- done</tag>
- <item>This means that at <em>any</em> microsecond interval in
- time, there can be no more than one call to erlang:now/0 in the
- system. However, for the system not to loose it's properties
- completely, it's enough that it on average is no more than one
- call per microsecond (in one Erlang node).</item>
- </taglist>
- <p>The uniqueness property of erlang:now/0 is the most limiting
- property. It means that erlang:now() maintains a global state and
- that there is a hard-to-check property of the system that needs to
- be maintained. For most applications this is still not a problem,
- but a future system might very well manage to violate the
- frequency limit on the calls globally. The uniqueness property is
- also quite useless, as there are globally unique references that
- provide a much better unique value to programs. However the
- property will need to be maintained unless a really subtle
- backward compatibility issue is to be introduced.</p>
+ <title>Time Warp Modes</title>
+ <marker id="Time_Warp_Modes"/>
+ <p>Current <seealso marker="#Erlang_System_Time">Erlang system
+ time</seealso> is determined by adding current
+ <seealso marker="erlang#monotonic_time/0">Erlang monotonic time</seealso>
+ with current
+ <seealso marker="erlang#time_offset/0">time offset</seealso>. The
+ time offset is managed differently depending on which time
+ warp mode you use.</p>
+
+ <p>To set the time warp mode, pass command-line argument
+ <seealso marker="erl#+C_"><c>+C
+ [no_time_warp|single_time_warp|multi_time_warp]</c></seealso>
+ to <c>erl</c>.</p>
+
+ <marker id="No_Time_Warp_Mode"/>
+ <section>
+ <title>No Time Warp Mode</title>
+ <p>The time offset is determined at runtime system start
+ and does not change later. This is the default behavior, but
+ not because it is the best mode (which it is not). It is
+ default <em>only</em> because this is how the runtime system
+ behaved until <c>ERTS</c> 7.0.
+ Ensure that your Erlang code that may execute during a time
+ warp is <seealso marker="#Time_Warp_Safe_Code">time warp
+ safe</seealso> before enabling other modes.</p>
+
+ <p>As the time offset is not allowed to change, time
+ correction must adjust the frequency of the Erlang
+ monotonic clock to align Erlang system time with OS
+ system time smoothly. A significant downside of this approach
+ is that we on purpose will use a faulty frequency on the
+ Erlang monotonic clock if adjustments are needed. This
+ error can be as large as 1%. This error will show up in all
+ time measurements in the runtime system.</p>
+
+ <p>If time correction is not enabled, Erlang monotonic
+ time freezes when OS system time leaps backwards.
+ The freeze of monotonic time continues until
+ OS system time catches up. The freeze can continue for
+ a long time. When OS system time leaps forwards,
+ Erlang monotonic time also leaps forward.</p>
+ </section>
+
+ <marker id="Single_Time_Warp_Mode"/>
+ <section>
+ <title>Single Time Warp Mode</title>
+ <p>This mode is more or less a backwards compatibility mode
+ as of its introduction.</p>
+
+ <p>On an embedded system it is not uncommon that the system
+ has no power supply, not even a battery, when it is
+ shut off. The system clock on such a system is typically
+ way off when the system boots. If
+ <seealso marker="#No_Time_Warp_Mode">no time warp mode</seealso>
+ is used, and the Erlang runtime system is started before
+ OS system time has been corrected, Erlang system time
+ can be wrong for a long time, centuries or even longer.</p>
+
+ <p>If you need to use Erlang code that is not
+ <seealso marker="#Time_Warp_Safe_Code">time warp safe</seealso>,
+ and you need to start the Erlang runtime system before OS
+ system time has been corrected, you may want to use the single
+ time warp mode.</p>
+
+ <note><p>There are limitations to when you can
+ execute time warp unsafe code using this mode. If it is possible
+ to use time warp safe code only, it is <em>much</em> better
+ to use the <seealso marker="#Multi_Time_Warp_Mode">multi-time
+ warp mode</seealso> instead.</p></note>
+
+ <p>Using the single time warp mode, the time offset is
+ handled in two phases:</p>
+
+ <taglist>
+ <tag>Preliminary Phase</tag>
+ <item>
+ <p>This phase starts when the runtime
+ system starts. A preliminary time offset based on
+ current OS system time is determined. This offset is from
+ now on to be fixed during the whole preliminary phase.</p>
+
+ <p>If time correction is enabled, adjustments to the
+ Erlang monotonic clock are made to keep its
+ frequency as correct as possible. However, <em>no</em>
+ adjustments are made trying to align Erlang system
+ time and OS system time. That is, during the preliminary phase
+ Erlang system time and OS system time can diverge
+ from each other, and no attempt is made to prevent this.</p>
+
+ <p>If time correction is disabled, changes in OS system
+ time affects the monotonic clock the same way as
+ when the <seealso marker="#No_Time_Warp_Mode">no time warp
+ mode</seealso> is used.</p>
+ </item>
+
+ <tag>Final Phase</tag>
+ <item>
+ <p>This phase begins when the user finalizes the time
+ offset by calling
+ <seealso marker="erlang#system_flag_time_offset"><c>erlang:system_flag(time_offset, finalize)</c></seealso>.
+ The finalization can only be performed once.</p>
+
+ <p>During finalization, the time offset is adjusted and
+ fixated so that current Erlang system time aligns with
+ current OS system time. As the time offset can
+ change during the finalization, Erlang system time
+ can do a time warp at this point. The time offset is
+ from now on fixed until the runtime system terminates.
+ If time correction has been enabled, the time
+ correction from now on also makes adjustments
+ to align Erlang system time with OS system
+ time. When the system is in the final phase, it behaves
+ exactly as in the <seealso marker="#No_Time_Warp_Mode">no
+ time warp mode</seealso>.</p>
+ </item>
+ </taglist>
+
+ <p>In order for this to work properly, the user must ensure
+ that the following two requirements are satisfied:</p>
+
+ <taglist>
+ <tag>Forward Time Warp</tag>
+ <item><p>The time warp made when finalizing the time offset
+ can only be done forwards without encountering problems.
+ This implies that the user must ensure that OS
+ system time is set to a time earlier or equal to actual
+ POSIX time before starting the Erlang runtime system.</p>
+
+ <p>If you are not sure that OS system time is correct,
+ set it to a time that is guaranteed to be earlier than
+ actual POSIX time before starting the Erlang runtime
+ system, just to be safe.</p>
+ </item>
+
+ <tag>Finalize Correct OS System Time</tag>
+ <item><p>OS system time must be correct when
+ the user finalizes the time offset.</p>
+ </item>
+ </taglist>
+
+ <p>If these requirements are not fulfilled, the system
+ may behave very bad.</p>
+
+ <p>Assuming that these requirements are fulfilled,
+ time correction is enabled, and that OS system time
+ is adjusted using a time adjustment protocol such as NTP,
+ only small adjustments of Erlang monotonic
+ time are needed to keep system times
+ aligned after finalization. As long as the system is not
+ suspended, the largest adjustments needed are for
+ inserted (or deleted) leap seconds.</p>
+
+ <warning><p>To use this mode, ensure that
+ all Erlang code that will execute in both phases are
+ <seealso marker="#Time_Warp_Safe_Code">time warp
+ safe</seealso>.</p>
+ <p>Code executing only in the final phase does not have
+ to be able to cope with the time warp.</p></warning>
+ </section>
+
+ <marker id="Multi_Time_Warp_Mode"/>
+ <section>
+ <title>Multi-Time Warp Mode</title>
+ <p><em>Multi-time warp mode in combination with time
+ correction is the preferred configuration</em>. This as
+ the Erlang runtime system have better performance, scale
+ better, and behave better on almost all platforms. In
+ addition, the accuracy and precision of time measurements
+ are better. Only Erlang runtime systems executing on
+ ancient platforms benefit from another configuration.</p>
+
+ <p>The time offset may change at any time without limitations.
+ That is, Erlang system time may perform time warps both
+ forwards and backwards at <em>any</em> time. As we align
+ Erlang system time with OS system time by changing
+ the time offset, we can enable a time correction that tries
+ to adjust the frequency of the Erlang monotonic clock to be as
+ correct as possible. This makes time measurements using
+ Erlang monotonic time more accurate and precise.</p>
+
+ <p>If time correction is disabled, Erlang monotonic time
+ leaps forward if OS system time leaps forward. If
+ OS system time leaps backwards, Erlang monotonic time
+ stops briefly, but it does not freeze for extended periods
+ of time. This as the time offset is changed to
+ align Erlang system time with OS system time.</p>
+
+ <warning><p>To use this mode, ensure that all
+ Erlang code that will execute on the runtime system is
+ <seealso marker="#Time_Warp_Safe_Code">time warp
+ safe</seealso>.</p></warning>
+ </section>
</section>
+
<section>
- <title>Should I use erlang:now/0 or os:timestamp/0</title>
- <p>The simple answer is to use erlang:now/0 for everything where
- you want to keep real time characteristics, but use os:timestamp
- for things like logs, user communication and debugging (typically
- timer:ts uses os:timestamp, as it is a test tool, not a real world
- application API). The benefit of using os:timestamp/0 is that it's
- faster and does not involve any global state (unless the operating
- system has one). The downside is that it will be vulnerable to wall
- clock time changes.</p>
+ <title>New Time API</title>
+ <marker id="The_New_Time_API"/>
+ <p>The old time API is based on
+ <seealso marker="erlang#now/0"><c>erlang:now/0</c></seealso>.
+ <c>erlang:now/0</c> was intended to be used for many unrelated
+ things. This tied these unrelated operations together and
+ caused issues with performance, scalability, accuracy, and
+ precision for operations that did not need to have
+ such issues. To improve this, the new API spreads different
+ functionality over multiple functions.</p>
+
+ <p>To be backwards compatible, <c>erlang:now/0</c>
+ remains as is, but <em>you are strongly discouraged from using
+ it</em>. Many use cases of <c>erlang:now/0</c>
+ prevents you from using the new
+ <seealso marker="#Multi_Time_Warp_Mode">multi-time warp
+ mode</seealso>, which is an important part of this
+ new time functionality improvement.</p>
+
+ <p>Some of the new BIFs on some systems, perhaps surprisingly,
+ return negative integer values on a newly started runtime
+ system. This is not a bug, but a memory use optimization.</p>
+
+ <p>The new API consists of the following new BIFs:</p>
+
+ <list>
+ <item><p><seealso marker="erlang#convert_time_unit/3"><c>erlang:convert_time_unit/3</c></seealso></p></item>
+ <item><p><seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time/0</c></seealso></p></item>
+ <item><p><seealso marker="erlang#monotonic_time/1"><c>erlang:monotonic_time/1</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_time/0"><c>erlang:system_time/0</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_time/1"><c>erlang:system_time/1</c></seealso></p></item>
+ <item><p><seealso marker="erlang#time_offset/0"><c>erlang:time_offset/0</c></seealso></p></item>
+ <item><p><seealso marker="erlang#time_offset/1"><c>erlang:time_offset/1</c></seealso></p></item>
+ <item><p><seealso marker="erlang#timestamp/0"><c>erlang:timestamp/0</c></seealso></p></item>
+ <item><p><seealso marker="erlang#unique_integer/0"><c>erlang:unique_integer/0</c></seealso></p></item>
+ <item><p><seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer/1</c></seealso></p></item>
+ <item><p><seealso marker="kernel:os#system_time/0"><c>os:system_time/0</c></seealso></p></item>
+ <item><p><seealso marker="kernel:os#system_time/1"><c>os:system_time/1</c></seealso></p></item>
+ </list>
+
+ <p>The new API also consists of extensions of the following existing BIFs:</p>
+
+ <list>
+ <item><p><seealso marker="erlang#monitor/2"><c>erlang:monitor(time_offset, clock_service)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_flag_time_offset"><c>erlang:system_flag(time_offset, finalize)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_os_system_time_source"><c>erlang:system_info(os_system_time_source)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_time_offset"><c>erlang:system_info(time_offset)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_time_warp_mode"><c>erlang:system_info(time_warp_mode)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_time_correction"><c>erlang:system_info(time_correction)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso></p></item>
+ <item><p><seealso marker="erlang#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso></p></item>
+ </list>
+
+ <marker id="The_New_Erlang_Monotonic_Time"/>
+ <section>
+ <title>New Erlang Monotonic Time</title>
+ <p>Erlang monotonic time as such is new as of <c>ERTS</c> 7.0.
+ It is introduced to detach time measurements, such as elapsed
+ time from calendar time. In many use cases there is a need to
+ measure elapsed time or specify a time relative to another point
+ in time without the need to know the involved times in UTC or
+ any other globally defined time scale. By introducing a time
+ scale with a local definition of where it starts, time that do
+ not concern calendar time can be managed on that time
+ scale. Erlang monotonic time uses such a time scale with a
+ locally defined start.</p>
+
+ <p>The introduction of Erlang monotonic time allows
+ us to adjust the two Erlang times (Erlang
+ monotonic time and Erlang system time) separately. By
+ doing this, the accuracy of elapsed time does not have to
+ suffer just because the system time happened to be
+ wrong at some point in time. Separate adjustments
+ of the two times are only performed in the time warp
+ modes, and only fully separated in the
+ <seealso marker="#Multi_Time_Warp_Mode">multi-time
+ warp mode</seealso>. All other modes than the
+ multi-time warp mode are for backwards
+ compatibility reasons. When using these modes, the
+ accuracy of Erlang monotonic time suffer, as
+ the adjustments of Erlang monotonic time in these
+ modes are more or less tied to Erlang system time.</p>
+
+ <p>The adjustment of system time could have been made
+ smother than using a time warp approach, but we think
+ that would be a bad choice. As we can
+ express and measure time that is not connected to
+ calendar time by the use of Erlang monotonic time, it
+ is better to expose the change in Erlang system time
+ immediately. This as the Erlang applications
+ executing on the system can react on the change in
+ system time as soon as possible. This is also more or
+ less exactly how most operating systems handle this
+ (OS monotonic time and OS system time). By adjusting
+ system time smoothly, we would just hide the fact that
+ system time changed and make it harder for the Erlang
+ applications to react to the change in a sensible way.</p>
+
+ <p>To be able to react to a change in Erlang
+ system time, you must be able to detect that it
+ happened. The change in Erlang system time occurs when
+ current time offset is changed. We have therefore
+ introduced the possibility to monitor the time offset using
+ <seealso marker="erlang#monitor/2"><c>erlang:monitor(time_offset, clock_service)</c></seealso>.
+ A process monitoring the time
+ offset is sent a message on the following format
+ when the time offset is changed:</p>
+
+ <code type="none">{'CHANGE', MonitorReference, time_offset, clock_service, NewTimeOffset}</code>
+ </section>
+
+ <marker id="Unique_Values"/>
+ <section>
+ <title>Unique Values</title>
+ <p>Besides reporting time, <c>erlang:now/0</c> also
+ produces unique and strictly monotonically increasing
+ values. To detach this functionality from
+ time measurements, we have introduced
+ <seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer()</c></seealso>.
+ </p>
+ </section>
+
+ <marker id="Dos_and_Donts"/>
+ <section>
+ <title>How to Work with the New API</title>
+ <p>Previously <c>erlang:now/0</c> was the only option for doing
+ many things. This section deals with some things that
+ <c>erlang:now/0</c> can be used for, and how you are to
+ these using the new API.</p>
+
+ <marker id="Dos_and_Donts_Retrieve_Erlang_System_Time"/>
+ <section>
+ <title>Retrieve Erlang System Time</title>
+ <dont>
+ <p>
+ Use <c>erlang:now/0</c> to retrieve current Erlang system time.
+ </p>
+ </dont>
+ <do>
+ <p>
+ Use
+ <seealso marker="erlang#system_time/1"><c>erlang:system_time/1</c></seealso>
+ to retrieve current Erlang system time on the
+ <seealso marker="erlang#type_time_unit">time unit</seealso>
+ of your choice.</p>
+ <p>If you want the same format as returned by <c>erlang:now/0</c>, use
+ <seealso marker="erlang#timestamp/0"><c>erlang:timestamp/0</c></seealso>.
+ </p>
+ </do>
+ </section>
+
+ <marker id="Dos_and_Donts_Measure_Elapsed_Time"/>
+ <section>
+ <title>Measure Elapsed Time</title>
+ <dont>
+ <p>
+ Take timestamps with <c>erlang:now/0</c> and calculate
+ the difference in time with
+ <seealso marker="stdlib:timer#now_diff/2"><c>timer:now_diff/2</c></seealso>.
+ </p>
+ </dont>
+ <do>
+ <p>
+ Take timestamps with
+ <seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time/0</c></seealso>
+ and calculate the time difference using ordinary subtraction.
+ The result will be in <c>native</c>
+ <seealso marker="erlang#type_time_unit">time unit</seealso>.
+ If you want to convert the
+ result to another time unit, you can use
+ <seealso marker="erlang#convert_time_unit/3"><c>erlang:convert_time_unit/3</c></seealso>.
+ </p>
+
+ <p>An easier way to do this is to use
+ <seealso marker="erlang#monotonic_time/1"><c>erlang:monotonic_time/1</c></seealso>
+ with the desired time unit. However, you can then lose accuracy
+ and precision.
+ </p>
+ </do>
+ </section>
+
+ <marker id="Dos_and_Donts_Determine_Order_of_Events"/>
+ <section>
+ <title>Determine Order of Events</title>
+ <dont>
+ <p>
+ Determine the order of events by saving a timestamp
+ with <c>erlang:now/0</c> when the event occurs.
+ </p>
+ </dont>
+ <do>
+ <p>
+ Determine the order of events by saving the integer
+ returned by
+ <seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer([monotonic])</c></seealso>
+ when the event occurs. These integers will be strictly
+ monotonically ordered on current runtime system instance
+ corresponding to creation time.
+ </p>
+ </do>
+ </section>
+
+ <marker id="Dos_and_Donts_Determine_Order_of_Events_With_Time_of_the_Event"/>
+ <section>
+ <title>Determine Order of Events with Time of the Event</title>
+ <dont>
+ <p>
+ Determine the order of events by saving a timestamp
+ with <c>erlang:now/0</c> when the event occurs.
+ </p>
+ </dont>
+ <do>
+ <p>
+ Determine the order of events by saving a tuple containing
+ <seealso marker="erlang#monotonic_time/0">monotonic time</seealso>
+ and a <seealso marker="erlang#unique_integer/1">strictly
+ monotonically increasing integer</seealso> as follows:</p>
+
+ <code type="none">
+Time = erlang:monotonic_time(),
+UMI = erlang:unique_integer([monotonic]),
+EventTag = {Time, UMI}</code>
+
+ <p>These tuples will be strictly monotonically ordered
+ on current runtime system instance according to
+ creation time. It is important that the
+ monotonic time is in the first element (the most
+ significant element when comparing 2-tuples). Using
+ the monotonic time in the tuples, you can calculate time
+ between events.</p>
+
+ <p>If you are interested in Erlang system time at the
+ time when the event occurred, you can also save the time
+ offset before or after saving the events using
+ <seealso marker="erlang#time_offset/0"><c>erlang:time_offset/0</c></seealso>.
+ Erlang monotonic time added with the time
+ offset corresponds to Erlang system time.</p>
+
+ <p>If you are executing in a mode where time offset
+ can change, and you want to get the actual
+ Erlang system time when the event occurred, you can
+ save the time offset as a third element in the tuple
+ (the least significant element when comparing 3-tuples).</p>
+ </do>
+ </section>
+
+ <marker id="Dos_and_Donts_Create_a_Unique_Name"/>
+ <section>
+ <title>Create a Unique Name</title>
+ <dont>
+ <p>
+ Use the values returned from <c>erlang:now/0</c>
+ to create a name unique on the current runtime system instance.
+ </p>
+ </dont>
+ <do>
+ <p>
+ Use the value returned from
+ <seealso marker="erlang#unique_integer/0"><c>erlang:unique_integer/0</c></seealso>
+ to create a name unique on the current runtime system
+ instance. If you only want positive integers, you can use
+ <seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer([positive])</c></seealso>.
+ </p>
+ </do>
+ </section>
+
+ <marker id="Dos_and_Donts_Seed_Random_Number_Generation_With_a_Unique_Value"/>
+ <section>
+ <title>Seed Random Number Generation with a Unique Value</title>
+ <dont>
+ <p>
+ Seed random number generation using <c>erlang:now()</c>.
+ </p>
+ </dont>
+ <do>
+ <p>
+ Seed random number generation using a combination of
+ <seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time()</c></seealso>,
+ <seealso marker="erlang#time_offset/0"><c>erlang:time_offset()</c></seealso>,
+ <seealso marker="erlang#unique_integer/0"><c>erlang:unique_integer()</c></seealso>,
+ and other functionality.
+ </p>
+ </do>
+ </section>
+
+ <p>To sum up this section: <em>Do not use <c>erlang:now/0</c>.</em></p>
+ </section>
</section>
+
<section>
- <title>Turning off time correction</title>
- <p>If, for some reason, time correction causes trouble and you are
- absolutely confident that the wall clock on the system is nearly
- perfect, you can turn off time correction completely by giving the
- <c>+c</c> option to <c>erl</c>. The probability for this being a
- good idea, is very low.</p>
+ <marker id="Supporting_Both_New_and_Old_OTP_Releases"/>
+ <title>Support of Both New and Old OTP Releases</title>
+ <p>It can be required that your code must run on a variety
+ of OTP installations of different OTP releases. If so, you
+ cannot use the new API out of the box, as it will
+ not be available on old pre OTP 18 releases. The solution
+ is <em>not</em> to avoid using the new API, as your
+ code then would not benefit from the scalability
+ and accuracy improvements made. Instead, use the
+ new API when available, and fall back on <c>erlang:now/0</c>
+ when the new API is unavailable.</p>
+
+ <p>Fortunately most of the new API can easily be
+ implemented using existing primitives, except for:</p>
+
+ <list type="bulleted">
+ <item>
+ <seealso marker="erlang#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>
+ </item>
+ <item>
+ <seealso marker="erlang#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>
+ </item>
+ <item>
+ <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>
+ </item>
+ <item>
+ <seealso marker="erlang#system_info_os_system_time_source"><c>erlang:system_info(os_system_time_source)</c></seealso>)
+ </item>
+ </list>
+
+ <p>By wrapping the API with functions that fall back on
+ <c>erlang:now/0</c> when the new API is unavailable,
+ and using these wrappers instead of using the API directly,
+ the problem is solved. These wrappers can, for example,
+ be implemented as in
+ <url href="time_compat.erl">$ERL_TOP/erts/example/time_compat.erl</url>.</p>
</section>
</chapter>
-
diff --git a/erts/doc/src/tty.xml b/erts/doc/src/tty.xml
index db15195f65..cd46d1203c 100644
--- a/erts/doc/src/tty.xml
+++ b/erts/doc/src/tty.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/erts/doc/src/werl.xml b/erts/doc/src/werl.xml
index 49cc45e745..9e7ad584eb 100644
--- a/erts/doc/src/werl.xml
+++ b/erts/doc/src/werl.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml
index da8ccdecdf..0a641346d9 100644
--- a/erts/doc/src/zlib.xml
+++ b/erts/doc/src/zlib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -99,7 +100,7 @@ list_to_binary([Compressed|Last])</pre>
<datatype>
<name name="zwindowbits"/>
<desc>
- <p>Normally in the range <c>-15..-9 | 9..15</c>.</p>
+ <p>Normally in the range <c>-15..-8 | 8..15</c>.</p>
</desc>
</datatype>
</datatypes>
@@ -149,7 +150,7 @@ list_to_binary([Compressed|Last])</pre>
currently the only supported method is <c>deflated</c>.</p>
<p>The <c><anno>WindowBits</anno></c> parameter is the base two logarithm
of the window size (the size of the history buffer). It
- should be in the range 9 through 15. Larger values
+ should be in the range 8 through 15. Larger values
of this parameter result in better compression at the
expense of memory usage. The default value is 15 if
<c>deflateInit/2</c>. A negative <c><anno>WindowBits</anno></c>
@@ -288,7 +289,7 @@ list_to_binary([B1,B2])</pre>
<p>Initialize decompression session on zlib stream.</p>
<p>The <c><anno>WindowBits</anno></c> parameter is the base two logarithm
of the maximum window size (the size of the history buffer).
- It should be in the range 9 through 15.
+ It should be in the range 8 through 15.
The default value is 15 if <c>inflateInit/1</c> is used.
If a compressed stream with a larger window size is
given as input, inflate() will throw the <c>data_error</c>
@@ -312,6 +313,53 @@ list_to_binary([B1,B2])</pre>
</desc>
</func>
<func>
+ <name name="inflateChunk" arity="2"/>
+ <fsummary>Decompress data with limited output size</fsummary>
+ <desc>
+ <p>Like <c>inflate/2</c>, but decompress no more data than
+ will fit in the buffer configured via <c>setBufSize/2</c>.
+ Is is useful when decompressing a stream with a high compression
+ ratio such that a small amount of compressed input may expand up to
+ 1000 times.
+ It returns <c>{more, Decompressed}</c>, when there is more output
+ available, and <c>inflateChunk/1</c> should be used to read it.
+ It may introduce some output latency (reading
+ input without producing any output).</p>
+ <p>If a preset dictionary is needed at this point (see
+ <c>inflateSetDictionary</c> below), <c>inflateChunk/2</c> throws a
+ <c>{need_dictionary,Adler}</c> exception where <c>Adler</c> is
+ the adler32 checksum of the dictionary chosen by the
+ compressor.</p>
+
+ <pre>
+walk(Compressed, Handler) ->
+ Z = zlib:open(),
+ zlib:inflateInit(Z),
+ % Limit single uncompressed chunk size to 512kb
+ zlib:setBufSize(Z, 512 * 1024),
+ loop(Z, Handler, zlib:inflateChunk(Z, Compressed)),
+ zlib:inflateEnd(Z),
+ zlib:close(Z).
+
+loop(Z, Handler, {more, Uncompressed}) ->
+ Handler(Uncompressed),
+ loop(Z, Handler, zlib:inflateChunk(Z));
+loop(Z, Handler, Uncompressed) ->
+ Handler(Uncompressed).
+ </pre>
+ </desc>
+ </func>
+ <func>
+ <name name="inflateChunk" arity="1"/>
+ <fsummary>Read next uncompressed chunk</fsummary>
+ <desc>
+ <p>Read next chunk of uncompressed data, initialized by
+ <c>inflateChunk/2</c>.</p>
+ <p>This function should be repeatedly called, while it returns
+ <c>{more, Decompressed}</c>.</p>
+ </desc>
+ </func>
+ <func>
<name name="inflateSetDictionary" arity="2"/>
<fsummary>Initialize the decompression dictionary</fsummary>
<desc>
diff --git a/erts/emulator/Makefile b/erts/emulator/Makefile
index 2db3b349b6..550e6e6f5b 100644
--- a/erts/emulator/Makefile
+++ b/erts/emulator/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 7145824f91..a919f0e3ac 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -112,18 +113,24 @@ NO_INLINE_FUNCTIONS=true
else
ifeq ($(TYPE),lcnt)
-PURIFY =
+PURIFY =
TYPEMARKER = .lcnt
TYPE_FLAGS = @CFLAGS@ -DERTS_ENABLE_LOCK_COUNT
else
ifeq ($(TYPE),frmptr)
-PURIFY =
+PURIFY =
OMIT_OMIT_FP=yes
TYPEMARKER = .frmptr
TYPE_FLAGS = @CFLAGS@ -DERTS_FRMPTR
else
+ifeq ($(TYPE),icount)
+PURIFY =
+TYPEMARKER = .icount
+TYPE_FLAGS = @CFLAGS@ -DERTS_OPCODE_COUNTER_SUPPORT
+else
+
# If type isn't one of the above, it *is* opt type...
override TYPE=opt
PURIFY =
@@ -138,6 +145,7 @@ endif
endif
endif
endif
+endif
comma:=,
space:=
@@ -342,16 +350,6 @@ endif
EPCRE_LIB = $(ERL_TOP)/erts/emulator/pcre/obj/$(TARGET)/$(TYPE)/$(LIB_PREFIX)epcre$(LIB_SUFFIX)
DEPLIBS += $(EPCRE_LIB)
-PERFCTR_PATH=@PERFCTR_PATH@
-USE_PERFCTR=@USE_PERFCTR@
-ifdef PERFCTR_PATH
-LIBS += $(PERFCTR_PATH)/usr.lib/libperfctr.a
-else
-ifdef USE_PERFCTR
-LIBS += -lperfctr
-endif
-endif
-
LIBSCTP = @LIBSCTP@
ORG_THR_LIBS=@EMU_THR_LIBS@
@@ -559,9 +557,6 @@ HIPE_ppc64_TAB=hipe/hipe_ppc64.tab $(HIPE_ARCH64_TAB)
HIPE_arm_TAB=hipe/hipe_arm.tab
HIPE_ARCH_TAB=$(HIPE_$(ARCH)_TAB)
BIFS += hipe/hipe_bif0.tab hipe/hipe_bif1.tab hipe/hipe_bif2.tab $(HIPE_ARCH_TAB)
-ifdef USE_PERFCTR
-BIFS += hipe/hipe_perfctr.tab
-endif
endif
$(TARGET)/erl_bif_table.c \
@@ -657,10 +652,6 @@ COMMON_INCLUDES += -I../include/internal -I../include/internal/$(TARGET)
INCLUDES = -I$(TTF_DIR) $(COMMON_INCLUDES)
-ifdef PERFCTR_PATH
-INCLUDES += -I$(PERFCTR_PATH)/usr.lib -I$(PERFCTR_PATH)/linux/include
-endif
-
ifeq ($(TARGET),win32)
$(OBJDIR)/dll_sys.o: sys/$(ERLANG_OSTYPE)/sys.c
$(V_CC) $(CFLAGS) -DERL_RUN_SHARED_LIB=1 $(INCLUDES) -c $< -o $@
@@ -764,7 +755,8 @@ RUN_OBJS = \
$(OBJDIR)/erl_bif_ddll.o $(OBJDIR)/erl_bif_guard.o \
$(OBJDIR)/erl_bif_info.o $(OBJDIR)/erl_bif_op.o \
$(OBJDIR)/erl_bif_os.o $(OBJDIR)/erl_bif_lists.o \
- $(OBJDIR)/erl_bif_trace.o $(OBJDIR)/erl_bif_wrap.o \
+ $(OBJDIR)/erl_bif_trace.o $(OBJDIR)/erl_bif_unique.o \
+ $(OBJDIR)/erl_bif_wrap.o \
$(OBJDIR)/erl_trace.o $(OBJDIR)/copy.o \
$(OBJDIR)/utils.o $(OBJDIR)/bif.o \
$(OBJDIR)/io.o $(OBJDIR)/erl_printf_term.o\
@@ -788,7 +780,7 @@ RUN_OBJS = \
$(OBJDIR)/erl_fun.o $(OBJDIR)/erl_bif_port.o \
$(OBJDIR)/erl_term.o $(OBJDIR)/erl_node_tables.o \
$(OBJDIR)/erl_monitors.o $(OBJDIR)/erl_process_dump.o \
- $(OBJDIR)/erl_bif_timer.o $(OBJDIR)/erl_cpu_topology.o \
+ $(OBJDIR)/erl_hl_timer.o $(OBJDIR)/erl_cpu_topology.o \
$(OBJDIR)/erl_drv_thread.o $(OBJDIR)/erl_bif_chksum.o \
$(OBJDIR)/erl_bif_re.o $(OBJDIR)/erl_unicode.o \
$(OBJDIR)/packet_parser.o $(OBJDIR)/safe_hash.o \
@@ -897,7 +889,8 @@ OS_OBJS += $(OBJDIR)/erl_mseg.o \
$(OBJDIR)/erl_mmap.o \
$(OBJDIR)/erl_$(ERLANG_OSTYPE)_sys_ddll.o \
$(OBJDIR)/erl_mtrace_sys_wrap.o \
- $(OBJDIR)/erl_sys_common_misc.o
+ $(OBJDIR)/erl_sys_common_misc.o \
+ $(OBJDIR)/erl_os_monotonic_time_extender.o
HIPE_ARCH64_OBJS=$(OBJDIR)/hipe_bif64.o
@@ -920,14 +913,11 @@ HIPE_OBJS= \
$(OBJDIR)/hipe_mode_switch.o \
$(OBJDIR)/hipe_native_bif.o \
$(OBJDIR)/hipe_stack.o $(HIPE_ARCH_OBJS)
-ifdef USE_PERFCTR
-HIPE_OBJS += $(OBJDIR)/hipe_perfctr.o
-endif
ifdef HIPE_ENABLED
EXTRA_BASE_OBJS += $(HIPE_OBJS)
endif
-BASE_OBJS = $(RUN_OBJS) $(EMU_OBJS) $(OS_OBJS) $(EXTRA_BASE_OBJS)
+BASE_OBJS = $(EMU_OBJS) $(RUN_OBJS) $(OS_OBJS) $(EXTRA_BASE_OBJS)
before_DTrace_OBJS = $(BASE_OBJS) $(DRV_OBJS)
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index 84d2d5e3ed..fe91134ef4 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index 5904ae0f7e..ead56c83d8 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 5d06a32941..cb6d294a41 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -68,7 +69,9 @@ atom aborted
atom abs_path
atom absoluteURI
atom ac
+atom accessor
atom active
+atom active_tasks
atom all
atom all_but_first
atom all_names
@@ -94,21 +97,24 @@ atom args
atom arg0
atom arity
atom asn1
+atom async
atom asynchronous
atom atom
atom atom_used
atom attributes
atom await_port_send_result
atom await_proc_exit
+atom await_result
atom await_sched_wall_time_modifications
atom awaiting_load
atom awaiting_unload
atom backtrace backtrace_depth
-atom badarg badarith badarity badfile badmatch badsig badfun
+atom badarg badarith badarity badfile badfun badkey badmap badmatch badsig
atom bag
atom band
atom big
atom bif_return_trap
+atom bif_timer_server
atom binary
atom binary_bin_to_list_trap
atom binary_copy_trap
@@ -144,9 +150,11 @@ atom catchlevel
atom cd
atom cdr
atom cflags
+atom CHANGE='CHANGE'
atom characters_to_binary_int
atom characters_to_list_int
atom clear
+atom clock_service
atom close
atom closed
atom code
@@ -156,6 +164,7 @@ atom compat_rel
atom compile
atom compressed
atom config_h
+atom convert_time_unit
atom connect
atom connected
atom connection_closed
@@ -198,6 +207,7 @@ atom dotall
atom driver
atom driver_options
atom dsend
+atom dsend_continue_trap
atom dunlink
atom duplicate_bag
atom dupnames
@@ -236,7 +246,7 @@ atom first
atom firstline
atom flags
atom flush
-atom flush_monitor_message
+atom flush_monitor_messages
atom force
atom format_cpu_topology
atom free
@@ -257,7 +267,9 @@ atom get_seq_token
atom get_tcw
atom getenv
atom gather_gc_info_result
+atom gather_io_bytes
atom gather_sched_wall_time_result
+atom gather_system_check_result
atom getting_linked
atom getting_unlinked
atom global
@@ -279,7 +291,6 @@ atom http httph https http_response http_request http_header http_eoh http_error
atom id
atom if_clause
atom ignore
-atom imports
atom in
atom in_exiting
atom inactive
@@ -312,6 +323,7 @@ atom ldflags
atom Le='=<'
atom lf
atom line
+atom line_delimiter
atom line_length
atom linked_in_driver
atom links
@@ -335,6 +347,7 @@ atom max
atom maximum
atom max_tables max_processes
atom mbuf_size
+atom md5
atom memory
atom memory_internal
atom memory_types
@@ -342,8 +355,11 @@ atom message
atom message_binary
atom message_queue_len
atom messages
+atom merge_trap
atom meta
atom meta_match_spec
+atom micro_seconds
+atom milli_seconds
atom min_heap_size
atom min_bin_vheap_size
atom minor_version
@@ -354,12 +370,16 @@ atom monitored_by
atom monitor
atom monitor_nodes
atom monitors
+atom monotonic
+atom monotonic_timestamp
atom more
atom multi_scheduling
atom multiline
+atom nano_seconds
atom name
atom named_table
atom namelist
+atom native
atom native_addresses
atom Neq='=/='
atom Neqeq='/='
@@ -450,6 +470,7 @@ atom ports
atom port_count
atom port_limit
atom port_op
+atom positive
atom print
atom priority
atom private
@@ -494,6 +515,7 @@ atom return_from
atom return_to
atom return_trace
atom run_queue
+atom run_queue_lengths
atom runnable
atom runnable_ports
atom runnable_procs
@@ -509,6 +531,7 @@ atom schedulers_online
atom scheme
atom scientific
atom scope
+atom seconds
atom sensitive
atom sequential_tracer
atom sequential_trace_token
@@ -538,6 +561,7 @@ atom static
atom stderr_to_stdout
atom stop
atom stream
+atom strict_monotonic_timestamp
atom sunrm
atom suspend
atom suspended
@@ -554,12 +578,15 @@ atom term_to_binary_trap
atom this
atom thread_pool_size
atom threads
+atom time_offset
atom timeout
atom timeout_value
atom Times='*'
atom timestamp
atom total
+atom total_active_tasks
atom total_heap_size
+atom total_run_queue_lengths
atom tpkt
atom trace trace_ts traced
atom trace_control_word
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index df1983a83d..0e192b1ebd 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -33,18 +34,16 @@
#include "beam_catches.h"
#include "erl_binary.h"
#include "erl_nif.h"
+#include "erl_bits.h"
#include "erl_thr_progress.h"
static void set_default_trace_pattern(Eterm module);
static Eterm check_process_code(Process* rp, Module* modp, int allow_gc, int *redsp);
static void delete_code(Module* modp);
static void decrement_refc(BeamInstr* code);
-static int is_native(BeamInstr* code);
static int any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
static int any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
-
-
BIF_RETTYPE code_is_module_native_1(BIF_ALIST_1)
{
Module* modp;
@@ -59,8 +58,8 @@ BIF_RETTYPE code_is_module_native_1(BIF_ALIST_1)
return am_undefined;
}
erts_rlock_old_code(code_ix);
- res = ((modp->curr.code && is_native(modp->curr.code)) ||
- (modp->old.code != 0 && is_native(modp->old.code))) ?
+ res = (erts_is_module_native(modp->curr.code) ||
+ erts_is_module_native(modp->old.code)) ?
am_true : am_false;
erts_runlock_old_code(code_ix);
return res;
@@ -371,7 +370,7 @@ staging_epilogue(Process* c_p, int commit, Eterm res, int is_blocking,
ASSERT(commiter_state.stager == NULL);
commiter_state.stager = c_p;
erts_schedule_thr_prgr_later_op(smp_code_ix_commiter, NULL, &commiter_state.lop);
- erts_smp_proc_inc_refc(c_p);
+ erts_proc_inc_refc(c_p);
erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL);
/*
* smp_code_ix_commiter() will do the rest "later"
@@ -398,7 +397,7 @@ static void smp_code_ix_commiter(void* null)
erts_resume(p, ERTS_PROC_LOCK_STATUS);
}
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
- erts_smp_proc_dec_refc(p);
+ erts_proc_dec_refc(p);
}
#endif /* ERTS_SMP */
@@ -940,7 +939,15 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
break;
case TAG_PRIMARY_HEADER:
if (!header_is_transparent(val)) {
- Eterm* new_p = p + thing_arityval(val);
+ Eterm* new_p;
+ if (header_is_bin_matchstate(val)) {
+ ErlBinMatchState *ms = (ErlBinMatchState*) p;
+ ErlBinMatchBuffer *mb = &(ms->mb);
+ if (in_area(EXPAND_POINTER(mb->orig), mod_start, mod_size)) {
+ return 1;
+ }
+ }
+ new_p = p + thing_arityval(val);
ASSERT(start <= new_p && new_p < end);
p = new_p;
}
@@ -1106,25 +1113,3 @@ beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks, Eterm module)
}
return NIL;
}
-
-static int
-is_native(BeamInstr* code)
-{
- Uint i, num_functions = code[MI_NUM_FUNCTIONS];
-
- /* Check NativeAdress of first real function in module
- */
- for (i=0; i<num_functions; i++) {
- BeamInstr* func_info = (BeamInstr *) code[MI_FUNCTIONS+i];
- Eterm name = (Eterm) func_info[3];
-
- if (is_atom(name)) {
- return func_info[1] != 0;
- }
- else ASSERT(is_nil(name)); /* ignore BIF stubs */
- }
- /* Not a single non-BIF function? */
- return 0;
-}
-
-
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c
index 4e711c89e0..9860968687 100644
--- a/erts/emulator/beam/beam_bp.c
+++ b/erts/emulator/beam/beam_bp.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -74,6 +75,16 @@ extern BeamInstr beam_return_time_trace[1]; /* OpCode(i_return_time_trace) */
erts_smp_atomic32_t erts_active_bp_index;
erts_smp_atomic32_t erts_staging_bp_index;
+/*
+ * Inlined helpers
+ */
+
+static ERTS_INLINE ErtsMonotonicTime
+get_mtime(Process *c_p)
+{
+ return erts_get_monotonic_time(ERTS_PROC_GET_SCHDATA(c_p));
+}
+
/* *************************************************************************
** Local prototypes
*/
@@ -96,9 +107,6 @@ static int clear_function_break(BeamInstr *pc, Uint break_flags);
static BpDataTime* get_time_break(BeamInstr *pc);
static GenericBpData* check_break(BeamInstr *pc, Uint break_flags);
-static void bp_time_diff(bp_data_time_item_t *item,
- process_breakpoint_time_t *pbt,
- Uint ms, Uint s, Uint us);
static void bp_meta_unref(BpMetaPid* bmp);
static void bp_count_unref(BpCount* bcp);
@@ -109,13 +117,8 @@ static void uninstall_breakpoint(BeamInstr* pc);
/* bp_hash */
#define BP_TIME_ADD(pi0, pi1) \
do { \
- Uint r; \
(pi0)->count += (pi1)->count; \
- (pi0)->s_time += (pi1)->s_time; \
- (pi0)->us_time += (pi1)->us_time; \
- r = (pi0)->us_time / 1000000; \
- (pi0)->s_time += r; \
- (pi0)->us_time = (pi0)->us_time % 1000000; \
+ (pi0)->time += (pi1)->time; \
} while(0)
static void bp_hash_init(bp_time_hash_t *hash, Uint n);
@@ -947,7 +950,7 @@ do_call_trace(Process* c_p, BeamInstr* I, Eterm* reg,
void
erts_trace_time_call(Process* c_p, BeamInstr* I, BpDataTime* bdt)
{
- Uint ms,s,us;
+ ErtsMonotonicTime time;
process_breakpoint_time_t *pbt = NULL;
bp_data_time_item_t sitem, *item = NULL;
bp_time_hash_t *h = NULL;
@@ -960,7 +963,7 @@ erts_trace_time_call(Process* c_p, BeamInstr* I, BpDataTime* bdt)
* from the process psd */
pbt = ERTS_PROC_GET_CALL_TIME(c_p);
- get_sys_now(&ms, &s, &us);
+ time = get_mtime(c_p);
/* get pbt
* timestamp = t0
@@ -975,7 +978,7 @@ erts_trace_time_call(Process* c_p, BeamInstr* I, BpDataTime* bdt)
} else {
ASSERT(pbt->pc);
/* add time to previous code */
- bp_time_diff(&sitem, pbt, ms, s, us);
+ sitem.time = time - pbt->time;
sitem.pid = c_p->common.id;
sitem.count = 0;
@@ -1001,8 +1004,7 @@ erts_trace_time_call(Process* c_p, BeamInstr* I, BpDataTime* bdt)
/* Add count to this code */
sitem.pid = c_p->common.id;
sitem.count = 1;
- sitem.s_time = 0;
- sitem.us_time = 0;
+ sitem.time = 0;
/* this breakpoint */
ASSERT(bdt);
@@ -1019,15 +1021,13 @@ erts_trace_time_call(Process* c_p, BeamInstr* I, BpDataTime* bdt)
}
pbt->pc = I;
- pbt->ms = ms;
- pbt->s = s;
- pbt->us = us;
+ pbt->time = time;
}
void
erts_trace_time_return(Process *p, BeamInstr *pc)
{
- Uint ms,s,us;
+ ErtsMonotonicTime time;
process_breakpoint_time_t *pbt = NULL;
bp_data_time_item_t sitem, *item = NULL;
bp_time_hash_t *h = NULL;
@@ -1040,7 +1040,7 @@ erts_trace_time_return(Process *p, BeamInstr *pc)
* from the process psd */
pbt = ERTS_PROC_GET_CALL_TIME(p);
- get_sys_now(&ms,&s,&us);
+ time = get_mtime(p);
/* get pbt
* lookup bdt from code
@@ -1056,7 +1056,7 @@ erts_trace_time_return(Process *p, BeamInstr *pc)
*/
ASSERT(pbt->pc);
- bp_time_diff(&sitem, pbt, ms, s, us);
+ sitem.time = time - pbt->time;
sitem.pid = p->common.id;
sitem.count = 0;
@@ -1079,9 +1079,7 @@ erts_trace_time_return(Process *p, BeamInstr *pc)
}
pbt->pc = pc;
- pbt->ms = ms;
- pbt->s = s;
- pbt->us = us;
+ pbt->time = time;
}
}
@@ -1182,10 +1180,14 @@ int erts_is_time_break(Process *p, BeamInstr *pc, Eterm *retval) {
for(ix = 0; ix < hash.n; ix++) {
item = &(hash.item[ix]);
if (item->pid != NIL) {
+ ErtsMonotonicTime sec, usec;
+ usec = ERTS_MONOTONIC_TO_USEC(item->time);
+ sec = usec / 1000000;
+ usec = usec - sec*1000000;
t = TUPLE4(hp, item->pid,
make_small(item->count),
- make_small(item->s_time),
- make_small(item->us_time));
+ make_small((Uint) sec),
+ make_small((Uint) usec));
hp += 5;
*retval = CONS(hp, t, *retval); hp += 2;
}
@@ -1265,8 +1267,7 @@ static void bp_hash_rehash(bp_time_hash_t *hash, Uint n) {
}
item[hval].pid = hash->item[ix].pid;
item[hval].count = hash->item[ix].count;
- item[hval].s_time = hash->item[ix].s_time;
- item[hval].us_time = hash->item[ix].us_time;
+ item[hval].time = hash->item[ix].time;
}
}
@@ -1314,8 +1315,7 @@ static ERTS_INLINE bp_data_time_item_t * bp_hash_put(bp_time_hash_t *hash, bp_da
item = &(hash->item[hval]);
item->pid = sitem->pid;
- item->s_time = sitem->s_time;
- item->us_time = sitem->us_time;
+ item->time = sitem->time;
item->count = sitem->count;
hash->used++;
@@ -1329,41 +1329,7 @@ static void bp_hash_delete(bp_time_hash_t *hash) {
hash->item = NULL;
}
-static void bp_time_diff(bp_data_time_item_t *item, /* out */
- process_breakpoint_time_t *pbt, /* in */
- Uint ms, Uint s, Uint us) {
- int ds,dus;
-#ifdef DEBUG
- int dms;
-
-
- dms = ms - pbt->ms;
-#endif
- ds = s - pbt->s;
- dus = us - pbt->us;
-
- /* get_sys_now may return zero difftime,
- * this is ok.
- */
-
-#ifdef DEBUG
- ASSERT(dms >= 0 || ds >= 0 || dus >= 0);
-#endif
-
- if (dus < 0) {
- dus += 1000000;
- ds -= 1;
- }
- if (ds < 0) {
- ds += 1000000;
- }
-
- item->s_time = ds;
- item->us_time = dus;
-}
-
void erts_schedule_time_break(Process *p, Uint schedule) {
- Uint ms, s, us;
process_breakpoint_time_t *pbt = NULL;
bp_data_time_item_t sitem, *item = NULL;
bp_time_hash_t *h = NULL;
@@ -1386,8 +1352,7 @@ void erts_schedule_time_break(Process *p, Uint schedule) {
pbdt = get_time_break(pbt->pc);
if (pbdt) {
- get_sys_now(&ms,&s,&us);
- bp_time_diff(&sitem, pbt, ms, s, us);
+ sitem.time = get_mtime(p) - pbt->time;
sitem.pid = p->common.id;
sitem.count = 0;
@@ -1409,10 +1374,7 @@ void erts_schedule_time_break(Process *p, Uint schedule) {
* timestamp it and remove the previous
* timestamp in the psd.
*/
- get_sys_now(&ms,&s,&us);
- pbt->ms = ms;
- pbt->s = s;
- pbt->us = us;
+ pbt->time = get_mtime(p);
break;
default :
ASSERT(0);
diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h
index b061401863..2b89d6fc71 100644
--- a/erts/emulator/beam/beam_bp.h
+++ b/erts/emulator/beam/beam_bp.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -28,8 +29,7 @@
typedef struct {
Eterm pid;
Sint count;
- Uint s_time;
- Uint us_time;
+ ErtsMonotonicTime time;
} bp_data_time_item_t;
typedef struct {
@@ -45,9 +45,7 @@ typedef struct bp_data_time { /* Call time */
} BpDataTime;
typedef struct {
- Uint ms;
- Uint s;
- Uint us;
+ ErtsMonotonicTime time;
BeamInstr *pc;
} process_breakpoint_time_t; /* used within psd */
diff --git a/erts/emulator/beam/beam_catches.c b/erts/emulator/beam/beam_catches.c
index d374d0469e..7a1f4901aa 100644
--- a/erts/emulator/beam/beam_catches.c
+++ b/erts/emulator/beam/beam_catches.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -142,7 +143,7 @@ BeamInstr *beam_catches_car(unsigned i)
struct bc_pool* p = &bccix[erts_active_code_ix()];
if (i >= p->tabsize ) {
- erl_exit(1, "beam_catches_delmod: index %#x is out of range\r\n", i);
+ erts_exit(ERTS_ERROR_EXIT, "beam_catches_delmod: index %#x is out of range\r\n", i);
}
return p->beam_catches[i].cp;
}
@@ -156,10 +157,10 @@ void beam_catches_delmod(unsigned head, BeamInstr *code, unsigned code_bytes,
ASSERT((code_ix == erts_active_code_ix()) != bccix[erts_staging_code_ix()].is_staging);
for(i = head; i != (unsigned)-1;) {
if (i >= p->tabsize) {
- erl_exit(1, "beam_catches_delmod: index %#x is out of range\r\n", i);
+ erts_exit(ERTS_ERROR_EXIT, "beam_catches_delmod: index %#x is out of range\r\n", i);
}
if( (char*)p->beam_catches[i].cp - (char*)code >= code_bytes ) {
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"beam_catches_delmod: item %#x has cp %p which is not "
"in module's range [%p,%p[\r\n",
i, p->beam_catches[i].cp, code, ((char*)code + code_bytes));
diff --git a/erts/emulator/beam/beam_catches.h b/erts/emulator/beam/beam_catches.h
index 51ef463b2f..59ee64d033 100644
--- a/erts/emulator/beam/beam_catches.h
+++ b/erts/emulator/beam/beam_catches.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index a3cd08834f..90985e4f53 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -78,7 +79,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2)
{
Process* p = BIF_P;
Eterm MFA = BIF_ARG_1;
- Eterm bool = BIF_ARG_2;
+ Eterm boolean = BIF_ARG_2;
Eterm* tp;
Eterm mfa[3];
int i;
@@ -86,7 +87,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2)
Eterm res;
BpFunctions f;
- if (bool != am_true && bool != am_false)
+ if (boolean != am_true && boolean != am_false)
goto error;
if (is_not_tuple(MFA)) {
@@ -123,7 +124,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2)
erts_smp_thr_progress_block();
erts_bp_match_functions(&f, mfa, specified);
- if (bool == am_true) {
+ if (boolean == am_true) {
erts_set_debug_break(&f);
erts_install_breakpoints(&f);
erts_commit_staged_bp();
@@ -297,8 +298,8 @@ erts_debug_disassemble_1(BIF_ALIST_1)
(void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr);
hp = HAlloc(p, hsz);
addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr);
- ASSERT(is_atom(funcinfo[0]));
- ASSERT(is_atom(funcinfo[1]));
+ ASSERT(is_atom(funcinfo[0]) || funcinfo[0] == NIL);
+ ASSERT(is_atom(funcinfo[1]) || funcinfo[1] == NIL);
mfa = TUPLE3(hp, (Eterm) funcinfo[0], (Eterm) funcinfo[1], make_small((Eterm) funcinfo[2]));
hp += 4;
return TUPLE3(hp, addr, bin, mfa);
@@ -579,35 +580,65 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
unpacked = ap;
ap = addr + size;
switch (op) {
- case op_i_select_val_rfI:
- case op_i_select_val_xfI:
- case op_i_select_val_yfI:
+ case op_i_select_val_lins_rfI:
+ case op_i_select_val_lins_xfI:
+ case op_i_select_val_lins_yfI:
{
int n = ap[-1];
+ int ix = n;
- while (n > 0) {
- erts_print(to, to_arg, "%T f(" HEXF ") ", (Eterm) ap[0], ap[1]);
- ap += 2;
- size += 2;
- n--;
+ while (ix--) {
+ erts_print(to, to_arg, "%T ", (Eterm) ap[0]);
+ ap++;
+ size++;
+ }
+ ix = n;
+ while (ix--) {
+ erts_print(to, to_arg, "f(" HEXF ") ", (Eterm) ap[0]);
+ ap++;
+ size++;
}
}
break;
- case op_i_select_tuple_arity_rfI:
- case op_i_select_tuple_arity_xfI:
- case op_i_select_tuple_arity_yfI:
+ case op_i_select_val_bins_rfI:
+ case op_i_select_val_bins_xfI:
+ case op_i_select_val_bins_yfI:
{
int n = ap[-1];
while (n > 0) {
- Uint arity = arityval(ap[0]);
- erts_print(to, to_arg, " {%d} f(" HEXF ")", arity, ap[1]);
+ erts_print(to, to_arg, "%T f(" HEXF ") ", (Eterm) ap[0], ap[1]);
ap += 2;
size += 2;
n--;
}
}
break;
+ case op_i_select_tuple_arity_rfI:
+ case op_i_select_tuple_arity_xfI:
+ case op_i_select_tuple_arity_yfI:
+ {
+ int n = ap[-1];
+ int ix = n - 1; /* without sentinel */
+
+ while (ix--) {
+ Uint arity = arityval(ap[0]);
+ erts_print(to, to_arg, "{%d} ", arity, ap[1]);
+ ap++;
+ size++;
+ }
+ /* print sentinel */
+ erts_print(to, to_arg, "{%T} ", ap[0], ap[1]);
+ ap++;
+ size++;
+ ix = n;
+ while (ix--) {
+ erts_print(to, to_arg, "f(" HEXF ") ", ap[0]);
+ ap++;
+ size++;
+ }
+ }
+ break;
case op_i_jump_on_val_rfII:
case op_i_jump_on_val_xfII:
case op_i_jump_on_val_yfII:
@@ -635,11 +666,9 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
case op_i_put_tuple_rI:
case op_i_put_tuple_xI:
case op_i_put_tuple_yI:
- case op_new_map_jdII:
+ case op_new_map_dII:
case op_update_map_assoc_jsdII:
case op_update_map_exact_jsdII:
- case op_i_has_map_fields_fsI:
- case op_i_get_map_elements_fsI:
{
int n = unpacked[-1];
@@ -663,6 +692,32 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
}
}
break;
+ case op_i_get_map_elements_fsI:
+ {
+ int n = unpacked[-1];
+
+ while (n > 0) {
+ if (n % 3 == 1) {
+ erts_print(to, to_arg, " %X", ap[0]);
+ } else if (!is_header(ap[0])) {
+ erts_print(to, to_arg, " %T", (Eterm) ap[0]);
+ } else {
+ switch ((ap[0] >> 2) & 0x03) {
+ case R_REG_DEF:
+ erts_print(to, to_arg, " x(0)");
+ break;
+ case X_REG_DEF:
+ erts_print(to, to_arg, " x(%d)", ap[0] >> 4);
+ break;
+ case Y_REG_DEF:
+ erts_print(to, to_arg, " y(%d)", ap[0] >> 4);
+ break;
+ }
+ }
+ ap++, size++, n--;
+ }
+ }
+ break;
}
erts_print(to, to_arg, "\n");
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 8bfb7d2ad2..1fe4cc9374 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -241,10 +242,6 @@ BeamInstr beam_return_time_trace[1]; /* OpCode(i_return_time_trace) */
void** beam_ops;
#endif
-#ifndef ERTS_SMP /* Not supported with smp emulator */
-extern int count_instructions;
-#endif
-
#define SWAPIN \
HTOP = HEAP_TOP(c_p); \
E = c_p->stop
@@ -566,7 +563,8 @@ extern int count_instructions;
Store(term, Dst); \
} while (0)
-#define Move2(src1, dst1, src2, dst2) dst1 = (src1); dst2 = (src2)
+#define Move2(S1, D1, S2, D2) D1 = (S1); D2 = (S2)
+#define Move3(S1, D1, S2, D2, S3, D3) D1 = (S1); D2 = (S2); D3 = (S3)
#define MoveGenDest(src, dstp) \
if ((dstp) == NULL) { r(0) = (src); } else { *(dstp) = src; }
@@ -666,6 +664,9 @@ extern int count_instructions;
#define EqualImmed(X, Y, Action) if (X != Y) { Action; }
#define NotEqualImmed(X, Y, Action) if (X == Y) { Action; }
+#define EqualExact(X, Y, Action) if (!EQ(X,Y)) { Action; }
+#define IsLessThan(X, Y, Action) if (CMP_GE(X, Y)) { Action; }
+#define IsGreaterEqual(X, Y, Action) if (CMP_LT(X, Y)) { Action; }
#define IsFloat(Src, Fail) if (is_not_float(Src)) { Fail; }
@@ -703,9 +704,7 @@ extern int count_instructions;
Fail; \
}
-#define IsMap(Src, Fail) if (is_not_map(Src)) { Fail; }
-
-#define HasMapField(Src, Key, Fail) if (has_not_map_field(Src, Key)) { Fail; }
+#define IsMap(Src, Fail) if (!is_map(Src)) { Fail; }
#define GetMapElement(Src, Key, Dst, Fail) \
do { \
@@ -716,6 +715,15 @@ extern int count_instructions;
Dst = _res; \
} while (0)
+#define GetMapElementHash(Src, Key, Hx, Dst, Fail) \
+ do { \
+ Eterm _res = get_map_element_hash(Src, Key, Hx); \
+ if (is_non_value(_res)) { \
+ Fail; \
+ } \
+ Dst = _res; \
+ } while (0)
+
#define IsFunction(X, Action) \
do { \
if ( !(is_any_fun(X)) ) { \
@@ -964,8 +972,8 @@ static Eterm update_map_assoc(Process* p, Eterm* reg,
Eterm map, BeamInstr* I) NOINLINE;
static Eterm update_map_exact(Process* p, Eterm* reg,
Eterm map, BeamInstr* I) NOINLINE;
-static int has_not_map_field(Eterm map, Eterm key);
static Eterm get_map_element(Eterm map, Eterm key);
+static Eterm get_map_element_hash(Eterm map, Eterm key, Uint32 hx);
/*
* Functions not directly called by process_main(). OK to inline.
@@ -1081,16 +1089,32 @@ init_emulator(void)
DTRACE2(nif_return, process_name, mfa); \
}
-#else /* USE_VM_PROBES */
-
-#define DTRACE_LOCAL_CALL(p, m, f, a) do {} while (0)
-#define DTRACE_GLOBAL_CALL(p, m, f, a) do {} while (0)
-#define DTRACE_RETURN(p, m, f, a) do {} while (0)
-#define DTRACE_BIF_ENTRY(p, m, f, a) do {} while (0)
-#define DTRACE_BIF_RETURN(p, m, f, a) do {} while (0)
-#define DTRACE_NIF_ENTRY(p, m, f, a) do {} while (0)
-#define DTRACE_NIF_RETURN(p, m, f, a) do {} while (0)
+#define DTRACE_GLOBAL_CALL_FROM_EXPORT(p,e) \
+ do { \
+ if (DTRACE_ENABLED(global_function_entry)) { \
+ BeamInstr* fp = (BeamInstr *) (((Export *) (e))->addressv[erts_active_code_ix()]); \
+ DTRACE_GLOBAL_CALL((p), (Eterm)fp[-3], (Eterm)fp[-2], fp[-1]); \
+ } \
+ } while(0)
+
+#define DTRACE_RETURN_FROM_PC(p) \
+ do { \
+ BeamInstr* fp; \
+ if (DTRACE_ENABLED(function_return) && (fp = find_function_from_pc((p)->cp))) { \
+ DTRACE_RETURN((p), (Eterm)fp[0], (Eterm)fp[1], (Uint)fp[2]); \
+ } \
+ } while(0)
+#else /* USE_VM_PROBES */
+#define DTRACE_LOCAL_CALL(p, m, f, a) do {} while (0)
+#define DTRACE_GLOBAL_CALL(p, m, f, a) do {} while (0)
+#define DTRACE_GLOBAL_CALL_FROM_EXPORT(p, e) do {} while (0)
+#define DTRACE_RETURN(p, m, f, a) do {} while (0)
+#define DTRACE_RETURN_FROM_PC(p) do {} while (0)
+#define DTRACE_BIF_ENTRY(p, m, f, a) do {} while (0)
+#define DTRACE_BIF_RETURN(p, m, f, a) do {} while (0)
+#define DTRACE_NIF_ENTRY(p, m, f, a) do {} while (0)
+#define DTRACE_NIF_RETURN(p, m, f, a) do {} while (0)
#endif /* USE_VM_PROBES */
/*
@@ -1163,14 +1187,15 @@ void process_main(void)
Eterm (*arith_func)(Process* p, Eterm* reg, Uint live);
-#ifndef NO_JUMP_TABLE
- static void* opcodes[] = { DEFINE_OPCODES };
#ifdef ERTS_OPCODE_COUNTER_SUPPORT
static void* counting_opcodes[] = { DEFINE_COUNTING_OPCODES };
-#endif
+#else
+#ifndef NO_JUMP_TABLE
+ static void* opcodes[] = { DEFINE_OPCODES };
#else
int Go;
#endif
+#endif
Uint temp_bits; /* Temporary used by BsSkipBits2 & BsGetInteger2 */
@@ -1369,7 +1394,39 @@ void process_main(void)
ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
goto find_func_info;
}
-
+
+#define DO_BIG_ARITH(Func,Arg1,Arg2) \
+ do { \
+ Uint live = Arg(1); \
+ SWAPOUT; \
+ reg[0] = r(0); \
+ reg[live] = (Arg1); \
+ reg[live+1] = (Arg2); \
+ result = (Func)(c_p, reg, live); \
+ r(0) = reg[0]; \
+ SWAPIN; \
+ ERTS_HOLE_CHECK(c_p); \
+ if (is_value(result)) { \
+ StoreBifResult(4,result); \
+ } \
+ goto lb_Cl_error; \
+ } while(0)
+
+ OpCase(i_plus_jIxxd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), xb(Arg(3)))) {
+ Sint i = signed_val(xb(Arg(2))) + signed_val(xb(Arg(3)));
+ ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
+ if (MY_IS_SSMALL(i)) {
+ result = make_small(i);
+ StoreBifResult(4, result);
+ }
+ }
+ DO_BIG_ARITH(ARITH_FUNC(mixed_plus), xb(Arg(2)), xb(Arg(3)));
+ }
+
OpCase(i_plus_jId):
{
Eterm result;
@@ -1381,12 +1438,26 @@ void process_main(void)
result = make_small(i);
STORE_ARITH_RESULT(result);
}
-
}
arith_func = ARITH_FUNC(mixed_plus);
goto do_big_arith2;
}
+ OpCase(i_minus_jIxxd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), xb(Arg(3)))) {
+ Sint i = signed_val(xb(Arg(2))) - signed_val(xb(Arg(3)));
+ ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
+ if (MY_IS_SSMALL(i)) {
+ result = make_small(i);
+ StoreBifResult(4, result);
+ }
+ }
+ DO_BIG_ARITH(ARITH_FUNC(mixed_minus), xb(Arg(2)), xb(Arg(3)));
+ }
+
OpCase(i_minus_jId):
{
Eterm result;
@@ -1479,6 +1550,52 @@ void process_main(void)
Next(2);
}
+ OpCase(move_window3_xxxy): {
+ BeamInstr *next;
+ Eterm xt0, xt1, xt2;
+ Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(3)));
+ PreFetch(4, next);
+ xt0 = xb(Arg(0));
+ xt1 = xb(Arg(1));
+ xt2 = xb(Arg(2));
+ y[0] = xt0;
+ y[1] = xt1;
+ y[2] = xt2;
+ NextPF(4, next);
+ }
+ OpCase(move_window4_xxxxy): {
+ BeamInstr *next;
+ Eterm xt0, xt1, xt2, xt3;
+ Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(4)));
+ PreFetch(5, next);
+ xt0 = xb(Arg(0));
+ xt1 = xb(Arg(1));
+ xt2 = xb(Arg(2));
+ xt3 = xb(Arg(3));
+ y[0] = xt0;
+ y[1] = xt1;
+ y[2] = xt2;
+ y[3] = xt3;
+ NextPF(5, next);
+ }
+ OpCase(move_window5_xxxxxy): {
+ BeamInstr *next;
+ Eterm xt0, xt1, xt2, xt3, xt4;
+ Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(5)));
+ PreFetch(6, next);
+ xt0 = xb(Arg(0));
+ xt1 = xb(Arg(1));
+ xt2 = xb(Arg(2));
+ xt3 = xb(Arg(3));
+ xt4 = xb(Arg(4));
+ y[0] = xt0;
+ y[1] = xt1;
+ y[2] = xt2;
+ y[3] = xt3;
+ y[4] = xt4;
+ NextPF(6, next);
+ }
+
OpCase(i_move_call_only_fcr): {
r(0) = Arg(1);
}
@@ -1526,12 +1643,7 @@ void process_main(void)
* is not loaded, it points to code which will invoke the error handler
* (see lb_call_error_handler below).
*/
-#ifdef USE_VM_CALL_PROBES
- if (DTRACE_ENABLED(global_function_entry)) {
- BeamInstr* fp = (BeamInstr *) (((Export *) Arg(0))->addressv[erts_active_code_ix()]);
- DTRACE_GLOBAL_CALL(c_p, (Eterm)fp[-3], (Eterm)fp[-2], fp[-1]);
- }
-#endif
+ DTRACE_GLOBAL_CALL_FROM_EXPORT(c_p, Arg(0));
Dispatchx();
OpCase(i_move_call_ext_cre): {
@@ -1541,12 +1653,7 @@ void process_main(void)
/* FALL THROUGH */
OpCase(i_call_ext_e):
SET_CP(c_p, I+2);
-#ifdef USE_VM_CALL_PROBES
- if (DTRACE_ENABLED(global_function_entry)) {
- BeamInstr* fp = (BeamInstr *) (((Export *) Arg(0))->addressv[erts_active_code_ix()]);
- DTRACE_GLOBAL_CALL(c_p, (Eterm)fp[-3], (Eterm)fp[-2], fp[-1]);
- }
-#endif
+ DTRACE_GLOBAL_CALL_FROM_EXPORT(c_p, Arg(0));
Dispatchx();
OpCase(i_move_call_ext_only_ecr): {
@@ -1554,12 +1661,7 @@ void process_main(void)
}
/* FALL THROUGH */
OpCase(i_call_ext_only_e):
-#ifdef USE_VM_CALL_PROBES
- if (DTRACE_ENABLED(global_function_entry)) {
- BeamInstr* fp = (BeamInstr *) (((Export *) Arg(0))->addressv[erts_active_code_ix()]);
- DTRACE_GLOBAL_CALL(c_p, (Eterm)fp[-3], (Eterm)fp[-2], fp[-1]);
- }
-#endif
+ DTRACE_GLOBAL_CALL_FROM_EXPORT(c_p, Arg(0));
Dispatchx();
OpCase(init_y): {
@@ -1593,18 +1695,9 @@ void process_main(void)
Next(1);
}
-
OpCase(return): {
-#ifdef USE_VM_CALL_PROBES
- BeamInstr* fptr;
-#endif
SET_I(c_p->cp);
-
-#ifdef USE_VM_CALL_PROBES
- if (DTRACE_ENABLED(function_return) && (fptr = find_function_from_pc(c_p->cp))) {
- DTRACE_RETURN(c_p, (Eterm)fptr[0], (Eterm)fptr[1], (Uint)fptr[2]);
- }
-#endif
+ DTRACE_RETURN_FROM_PC(c_p);
/*
* We must clear the CP to make sure that a stale value do not
* create a false module dependcy preventing code upgrading.
@@ -2027,44 +2120,32 @@ void process_main(void)
}
GetArg1(1, timeout_value);
if (timeout_value != make_small(0)) {
-#if !defined(ARCH_64) || HALFWORD_HEAP
- Uint time_val;
-#endif
- if (is_small(timeout_value) && signed_val(timeout_value) > 0 &&
-#if defined(ARCH_64) && !HALFWORD_HEAP
- ((unsigned_val(timeout_value) >> 32) == 0)
-#else
- 1
-#endif
- ) {
- /*
- * The timer routiner will set c_p->i to the value in
- * c_p->def_arg_reg[0]. Note that it is safe to use this
- * location because there are no living x registers in
- * a receive statement.
- * Note that for the halfword emulator, the two first elements
- * of the array are used.
- */
- BeamInstr** pi = (BeamInstr**) c_p->def_arg_reg;
- *pi = I+3;
- set_timer(c_p, unsigned_val(timeout_value));
- } else if (timeout_value == am_infinity) {
+ if (timeout_value == am_infinity)
c_p->flags |= F_TIMO;
-#if !defined(ARCH_64) || HALFWORD_HEAP
- } else if (term_to_Uint(timeout_value, &time_val)) {
- BeamInstr** pi = (BeamInstr**) c_p->def_arg_reg;
- *pi = I+3;
- set_timer(c_p, time_val);
-#endif
- } else { /* Wrong time */
- OpCase(i_wait_error_locked): {
- erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
- /* Fall through */
+ else {
+ int tres = erts_set_proc_timer_term(c_p, timeout_value);
+ if (tres == 0) {
+ /*
+ * The timer routiner will set c_p->i to the value in
+ * c_p->def_arg_reg[0]. Note that it is safe to use this
+ * location because there are no living x registers in
+ * a receive statement.
+ * Note that for the halfword emulator, the two first elements
+ * of the array are used.
+ */
+ BeamInstr** pi = (BeamInstr**) c_p->def_arg_reg;
+ *pi = I+3;
}
+ else { /* Wrong time */
+ OpCase(i_wait_error_locked): {
+ erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
+ /* Fall through */
+ }
OpCase(i_wait_error): {
- c_p->freason = EXC_TIMEOUT_VALUE;
- goto find_func_info;
+ c_p->freason = EXC_TIMEOUT_VALUE;
+ goto find_func_info;
+ }
}
}
@@ -2082,6 +2163,22 @@ void process_main(void)
OpCase(wait_f):
wait2: {
+#ifndef ERTS_SMP
+ if (ERTS_PROC_IS_EXITING(c_p)) {
+ /*
+ * I non smp case:
+ *
+ * Currently executing process might be sent an exit
+ * signal if it is traced by a port that it also is
+ * linked to, and the port terminates during the
+ * trace. In this case we do *not* want to clear
+ * the active flag, which will make the process hang
+ * in limbo forever.
+ */
+ SWAPOUT;
+ goto do_schedule;
+ }
+#endif
c_p->i = (BeamInstr *) Arg(0); /* L1 */
SWAPOUT;
c_p->arity = 0;
@@ -2113,7 +2210,7 @@ void process_main(void)
if ((c_p->flags & (F_INSLPQUEUE | F_TIMO)) == 0) {
BeamInstr** p = (BeamInstr **) c_p->def_arg_reg;
*p = I+3;
- set_timer(c_p, Arg(1));
+ erts_set_proc_timer_uword(c_p, Arg(1));
}
goto wait2;
}
@@ -2141,19 +2238,18 @@ void process_main(void)
NextPF(0, next);
}
-
{
Eterm select_val2;
- OpCase(i_select_tuple_arity2_yfAfAf):
+ OpCase(i_select_tuple_arity2_yfAAff):
select_val2 = yb(Arg(0));
goto do_select_tuple_arity2;
- OpCase(i_select_tuple_arity2_xfAfAf):
+ OpCase(i_select_tuple_arity2_xfAAff):
select_val2 = xb(Arg(0));
goto do_select_tuple_arity2;
- OpCase(i_select_tuple_arity2_rfAfAf):
+ OpCase(i_select_tuple_arity2_rfAAff):
select_val2 = r(0);
I--;
@@ -2164,22 +2260,22 @@ void process_main(void)
select_val2 = *tuple_val(select_val2);
goto do_select_val2;
- OpCase(i_select_val2_yfcfcf):
+ OpCase(i_select_val2_yfccff):
select_val2 = yb(Arg(0));
goto do_select_val2;
- OpCase(i_select_val2_xfcfcf):
+ OpCase(i_select_val2_xfccff):
select_val2 = xb(Arg(0));
goto do_select_val2;
- OpCase(i_select_val2_rfcfcf):
+ OpCase(i_select_val2_rfccff):
select_val2 = r(0);
I--;
do_select_val2:
if (select_val2 == Arg(2)) {
- I += 2;
- } else if (select_val2 == Arg(4)) {
+ I += 3;
+ } else if (select_val2 == Arg(3)) {
I += 4;
}
@@ -2206,20 +2302,50 @@ void process_main(void)
do_select_tuple_arity:
if (is_tuple(select_val)) {
select_val = *tuple_val(select_val);
- goto do_binary_search;
+ goto do_linear_search;
+ }
+ SET_I((BeamInstr *) Arg(1));
+ Goto(*I);
+
+ OpCase(i_select_val_lins_xfI):
+ select_val = xb(Arg(0));
+ goto do_linear_search;
+
+ OpCase(i_select_val_lins_yfI):
+ select_val = yb(Arg(0));
+ goto do_linear_search;
+
+ OpCase(i_select_val_lins_rfI):
+ select_val = r(0);
+ I--;
+
+ do_linear_search: {
+ BeamInstr *vs = &Arg(3);
+ int ix = 0;
+
+ for(;;) {
+ if (vs[ix+0] >= select_val) { ix += 0; break; }
+ if (vs[ix+1] >= select_val) { ix += 1; break; }
+ ix += 2;
+ }
+
+ if (vs[ix] == select_val) {
+ I += ix + Arg(2) + 2;
}
+
SET_I((BeamInstr *) Arg(1));
Goto(*I);
+ }
- OpCase(i_select_val_xfI):
+ OpCase(i_select_val_bins_xfI):
select_val = xb(Arg(0));
goto do_binary_search;
- OpCase(i_select_val_yfI):
+ OpCase(i_select_val_bins_yfI):
select_val = yb(Arg(0));
goto do_binary_search;
- OpCase(i_select_val_rfI):
+ OpCase(i_select_val_bins_rfI):
select_val = r(0);
I--;
@@ -2353,65 +2479,16 @@ void process_main(void)
Goto(*I);
}
- OpCase(new_map_jdII): {
+ OpCase(new_map_dII): {
Eterm res;
x(0) = r(0);
SWAPOUT;
- res = new_map(c_p, reg, I);
+ res = new_map(c_p, reg, I-1);
SWAPIN;
r(0) = x(0);
- StoreResult(res, Arg(1));
- Next(4+Arg(3));
- }
-
- OpCase(i_has_map_fields_fsI): {
- map_t* mp;
- Eterm map;
- Eterm field;
- Eterm *ks;
- BeamInstr* fs;
- Uint sz,n;
-
- GetArg1(1, map);
-
- /* this instruction assumes Arg1 is a map,
- * i.e. that it follows a test is_map if needed.
- */
-
- mp = (map_t *)map_val(map);
- sz = map_get_size(mp);
-
- if (sz == 0) {
- SET_I((BeamInstr *) Arg(0));
- goto has_map_fields_fail;
- }
-
- ks = map_get_keys(mp);
- n = (Uint)Arg(2);
- fs = &Arg(3); /* pattern fields */
-
- ASSERT(n>0);
-
- while(sz) {
- field = (Eterm)*fs;
- if (EQ(field,*ks)) {
- n--;
- fs++;
- if (n == 0) break;
- }
- ks++; sz--;
- }
-
- if (n) {
- SET_I((BeamInstr *) Arg(0));
- goto has_map_fields_fail;
- }
-
- I += 4 + Arg(2);
-has_map_fields_fail:
- ASSERT(VALID_INSTR(*I));
- Goto(*I);
+ StoreResult(res, Arg(0));
+ Next(3+Arg(2));
}
#define PUT_TERM_REG(term, desc) \
@@ -2434,12 +2511,8 @@ do { \
OpCase(i_get_map_elements_fsI): {
Eterm map;
- map_t *mp;
- Eterm field;
- Eterm *ks;
- Eterm *vs;
BeamInstr *fs;
- Uint sz,n;
+ Uint sz, n;
GetArg1(1, map);
@@ -2447,41 +2520,55 @@ do { \
* i.e. that it follows a test is_map if needed.
*/
- mp = (map_t *)map_val(map);
- sz = map_get_size(mp);
+ n = (Uint)Arg(2) / 3;
+ fs = &Arg(3); /* pattern fields and target registers */
- if (sz == 0) {
- SET_I((BeamInstr *) Arg(0));
- goto get_map_elements_fail;
- }
+ if (is_flatmap(map)) {
+ flatmap_t *mp;
+ Eterm *ks;
+ Eterm *vs;
- n = (Uint)Arg(2) / 2;
- fs = &Arg(3); /* pattern fields and target registers */
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
+ mp = (flatmap_t *)flatmap_val(map);
+ sz = flatmap_get_size(mp);
- while(sz) {
- field = (Eterm)*fs;
- if (EQ(field,*ks)) {
- PUT_TERM_REG(*vs, fs[1]);
- n--;
- fs += 2;
- /* no more values to fetch, we are done */
- if (n == 0) break;
+ if (sz == 0) {
+ ClauseFail();
}
- ks++; sz--;
- vs++;
- }
- if (n) {
- SET_I((BeamInstr *) Arg(0));
- goto get_map_elements_fail;
- }
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+
+ while(sz) {
+ if (EQ((Eterm) fs[0], *ks)) {
+ PUT_TERM_REG(*vs, fs[1]);
+ n--;
+ fs += 3;
+ /* no more values to fetch, we are done */
+ if (n == 0) {
+ I = fs;
+ Next(-1);
+ }
+ }
+ ks++, sz--, vs++;
+ }
- I += 4 + Arg(2);
-get_map_elements_fail:
- ASSERT(VALID_INSTR(*I));
- Goto(*I);
+ ClauseFail();
+ } else {
+ const Eterm *v;
+ Uint32 hx;
+ ASSERT(is_hashmap(map));
+ while(n--) {
+ hx = fs[2];
+ ASSERT(hx == hashmap_make_hash((Eterm)fs[0]));
+ if ((v = erts_hashmap_get(hx, (Eterm)fs[0], map)) == NULL) {
+ ClauseFail();
+ }
+ PUT_TERM_REG(*v, fs[1]);
+ fs += 3;
+ }
+ I = fs;
+ Next(-1);
+ }
}
#undef PUT_TERM_REG
@@ -2499,7 +2586,13 @@ get_map_elements_fail:
StoreResult(res, Arg(2));
Next(5+Arg(4));
} else {
- goto badarg;
+ /*
+ * This can only happen if the code was compiled
+ * with the compiler in OTP 17.
+ */
+ c_p->freason = BADMAP;
+ c_p->fvalue = map;
+ goto lb_Cl_error;
}
}
@@ -2517,7 +2610,7 @@ get_map_elements_fail:
StoreResult(res, Arg(2));
Next(5+Arg(4));
} else {
- goto badarg;
+ goto lb_Cl_error;
}
}
@@ -2775,6 +2868,7 @@ get_map_elements_fail:
}
PreFetch(1, next);
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
reg[0] = r(0);
result = (*bf)(c_p, reg, I);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result));
@@ -2842,6 +2936,19 @@ get_map_elements_fail:
goto do_big_arith2;
}
+ OpCase(i_rem_jIxxd):
+ {
+ Eterm result;
+
+ if (xb(Arg(3)) == SMALL_ZERO) {
+ goto badarith;
+ } else if (is_both_small(xb(Arg(2)), xb(Arg(3)))) {
+ result = make_small(signed_val(xb(Arg(2))) % signed_val(xb(Arg(3))));
+ StoreBifResult(4, result);
+ }
+ DO_BIG_ARITH(ARITH_FUNC(int_rem),xb(Arg(2)),xb(Arg(3)));
+ }
+
OpCase(i_rem_jId):
{
Eterm result;
@@ -2857,6 +2964,20 @@ get_map_elements_fail:
}
}
+ OpCase(i_band_jIxcd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), Arg(3))) {
+ /*
+ * No need to untag -- TAG & TAG == TAG.
+ */
+ result = xb(Arg(2)) & Arg(3);
+ StoreBifResult(4, result);
+ }
+ DO_BIG_ARITH(ARITH_FUNC(band),xb(Arg(2)),Arg(3));
+ }
+
OpCase(i_band_jId):
{
Eterm result;
@@ -2872,6 +2993,8 @@ get_map_elements_fail:
goto do_big_arith2;
}
+#undef DO_BIG_ARITH
+
do_big_arith2:
{
Eterm result;
@@ -3523,6 +3646,8 @@ get_map_elements_fail:
erts_pre_nif(&env, c_p, (struct erl_module_nif*)I[2]);
reg[0] = r(0);
nif_bif_result = (*fp)(&env, bif_nif_arity, reg);
+ if (env.exception_thrown)
+ nif_bif_result = THE_NON_VALUE;
erts_post_nif(&env);
}
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(nif_bif_result));
@@ -3556,7 +3681,7 @@ get_map_elements_fail:
vbf = (BifFunction) Arg(0);
PROCESS_MAIN_CHK_LOCKS(c_p);
bif_nif_arity = I[-1];
- ASSERT(bif_nif_arity <= 3);
+ ASSERT(bif_nif_arity <= 4);
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
reg[0] = r(0);
{
@@ -3782,8 +3907,6 @@ get_map_elements_fail:
* Allocate the binary struct itself.
*/
bptr = erts_bin_nrml_alloc(num_bytes);
- bptr->flags = 0;
- bptr->orig_size = num_bytes;
erts_refc_init(&bptr->refc, 1);
erts_current_bin = (byte *) bptr->orig_bytes;
@@ -3883,8 +4006,6 @@ get_map_elements_fail:
* Allocate the binary struct itself.
*/
bptr = erts_bin_nrml_alloc(tmp_arg1);
- bptr->flags = 0;
- bptr->orig_size = tmp_arg1;
erts_refc_init(&bptr->refc, 1);
erts_current_bin = (byte *) bptr->orig_bytes;
@@ -3948,7 +4069,7 @@ get_map_elements_fail:
tmp_arg1 += Arg1;
store_bs_add_result:
- if (MY_IS_SSMALL((Sint) tmp_arg1)) {
+ if (tmp_arg1 <= MAX_SMALL) {
tmp_arg1 = make_small(tmp_arg1);
} else {
/*
@@ -4897,7 +5018,7 @@ get_map_elements_fail:
#ifdef NO_FPE_SIGNALS
OpCase(fclearerror):
OpCase(i_fcheckerror):
- erl_exit(1, "fclearerror/i_fcheckerror without fpe signals (beam_emu)");
+ erts_exit(ERTS_ERROR_EXIT, "fclearerror/i_fcheckerror without fpe signals (beam_emu)");
# define ERTS_NO_FPE_CHECK_INIT ERTS_FP_CHECK_INIT
# define ERTS_NO_FPE_ERROR ERTS_FP_ERROR
#else
@@ -4987,14 +5108,14 @@ get_map_elements_fail:
* ... remainder of original BEAM code
*/
ASSERT(I[-5] == (Uint) OpCode(i_func_info_IaaI));
- c_p->hipe.ncallee = (void(*)(void)) I[-4];
+ c_p->hipe.u.ncallee = (void(*)(void)) I[-4];
cmd = HIPE_MODE_SWITCH_CMD_CALL | (I[-1] << 8);
++hipe_trap_count;
goto L_hipe_mode_switch;
}
OpCase(hipe_trap_call_closure): {
ASSERT(I[-5] == (Uint) OpCode(i_func_info_IaaI));
- c_p->hipe.ncallee = (void(*)(void)) I[-4];
+ c_p->hipe.u.ncallee = (void(*)(void)) I[-4];
cmd = HIPE_MODE_SWITCH_CMD_CALL_CLOSURE | (I[-1] << 8);
++hipe_trap_count;
goto L_hipe_mode_switch;
@@ -5028,7 +5149,10 @@ get_map_elements_fail:
case HIPE_MODE_SWITCH_RES_RETURN:
ASSERT(is_value(reg[0]));
MoveReturn(reg[0], r(0));
- case HIPE_MODE_SWITCH_RES_CALL:
+ case HIPE_MODE_SWITCH_RES_CALL_EXPORTED:
+ c_p->i = c_p->hipe.u.callee_exp->addressv[erts_active_code_ix()];
+ /*fall through*/
+ case HIPE_MODE_SWITCH_RES_CALL_BEAM:
SET_I(c_p->i);
r(0) = reg[0];
Dispatch();
@@ -5052,7 +5176,7 @@ get_map_elements_fail:
I = handle_error(c_p, I, reg, NULL);
goto post_error_handling;
default:
- erl_exit(1, "hipe_mode_switch: result %u\n", c_p->def_arg_reg[3]);
+ erts_exit(ERTS_ERROR_EXIT, "hipe_mode_switch: result %u\n", c_p->def_arg_reg[3]);
}
}
OpCase(hipe_call_count): {
@@ -5132,7 +5256,7 @@ get_map_elements_fail:
OpCase(label_L):
OpCase(on_load):
OpCase(line_I):
- erl_exit(1, "meta op\n");
+ erts_exit(ERTS_ERROR_EXIT, "meta op\n");
/*
* One-time initialization of Beam emulator.
@@ -5145,22 +5269,14 @@ get_map_elements_fail:
#ifndef NO_JUMP_TABLE
#ifdef ERTS_OPCODE_COUNTER_SUPPORT
-
- /* Are tables correctly generated by beam_makeops? */
- ASSERT(sizeof(counting_opcodes) == sizeof(opcodes));
-
- if (count_instructions) {
#ifdef DEBUG
- counting_opcodes[op_catch_end_y] = LabelAddr(lb_catch_end_y);
+ counting_opcodes[op_catch_end_y] = LabelAddr(lb_catch_end_y);
#endif
- counting_opcodes[op_i_func_info_IaaI] = LabelAddr(lb_i_func_info_IaaI);
- beam_ops = counting_opcodes;
- }
- else
-#endif /* #ifndef ERTS_OPCODE_COUNTER_SUPPORT */
- {
- beam_ops = opcodes;
- }
+ counting_opcodes[op_i_func_info_IaaI] = LabelAddr(lb_i_func_info_IaaI);
+ beam_ops = counting_opcodes;
+#else /* #ifndef ERTS_OPCODE_COUNTER_SUPPORT */
+ beam_ops = opcodes;
+#endif /* ERTS_OPCODE_COUNTER_SUPPORT */
#endif /* NO_JUMP_TABLE */
em_call_error_handler = OpCode(call_error_handler);
@@ -5194,7 +5310,7 @@ get_map_elements_fail:
}
#ifdef NO_JUMP_TABLE
default:
- erl_exit(1, "unexpected op code %d\n",Go);
+ erts_exit(ERTS_ERROR_EXIT, "unexpected op code %d\n",Go);
}
#endif
return; /* Never executed */
@@ -5239,7 +5355,7 @@ translate_gc_bif(void* gcf)
} else if (gcf == erts_gc_binary_part_3) {
return binary_part_3;
} else {
- erl_exit(1, "bad gc bif");
+ erts_exit(ERTS_ERROR_EXIT, "bad gc bif");
}
}
@@ -5273,7 +5389,9 @@ Eterm error_atom[NUMBER_EXIT_CODES] = {
am_notalive, /* 14 */
am_system_limit, /* 15 */
am_try_clause, /* 16 */
- am_notsup /* 17 */
+ am_notsup, /* 17 */
+ am_badmap, /* 18 */
+ am_badkey, /* 19 */
};
/*
@@ -5302,7 +5420,7 @@ handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf)
Eterm* hp;
Eterm Value = c_p->fvalue;
Eterm Args = am_true;
- c_p->i = pc; /* In case we call erl_exit(). */
+ c_p->i = pc; /* In case we call erts_exit(). */
ASSERT(c_p->freason != TRAP); /* Should have been handled earlier. */
@@ -5366,7 +5484,7 @@ handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf)
c_p->cp = 0; /* To avoid keeping stale references. */
return new_pc;
}
- if (c_p->catches > 0) erl_exit(1, "Catch not found");
+ if (c_p->catches > 0) erts_exit(ERTS_ERROR_EXIT, "Catch not found");
}
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
terminate_proc(c_p, Value);
@@ -5476,18 +5594,35 @@ next_catch(Process* c_p, Eterm *reg) {
static void
terminate_proc(Process* c_p, Eterm Value)
{
+ Eterm *hp;
+ Eterm Args = NIL;
+
/* Add a stacktrace if this is an error. */
if (GET_EXC_CLASS(c_p->freason) == EXTAG_ERROR) {
Value = add_stacktrace(c_p, Value, c_p->ftrace);
}
/* EXF_LOG is a primary exception flag */
if (c_p->freason & EXF_LOG) {
+ int alive = erts_is_alive;
erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp, "Error in process %T ", c_p->common.id);
- if (erts_is_alive)
- erts_dsprintf(dsbufp, "on node %T ", erts_this_node->sysname);
- erts_dsprintf(dsbufp,"with exit value: %0.*T\n", display_items, Value);
- erts_send_error_to_logger(c_p->group_leader, dsbufp);
+
+ /* Build the format message */
+ erts_dsprintf(dsbufp, "Error in process ~p ");
+ if (alive)
+ erts_dsprintf(dsbufp, "on node ~p ");
+ erts_dsprintf(dsbufp, "with exit value:~n~p~n");
+
+ /* Build the args in reverse order */
+ hp = HAlloc(c_p, 2);
+ Args = CONS(hp, Value, Args);
+ if (alive) {
+ hp = HAlloc(c_p, 2);
+ Args = CONS(hp, erts_this_node->sysname, Args);
+ }
+ hp = HAlloc(c_p, 2);
+ Args = CONS(hp, c_p->common.id, Args);
+
+ erts_send_error_term_to_logger(c_p->group_leader, dsbufp, Args);
}
/*
* If we use a shared heap, the process will be garbage-collected.
@@ -5529,6 +5664,8 @@ expand_error_value(Process* c_p, Uint freason, Eterm Value) {
case (GET_EXC_INDEX(EXC_TRY_CLAUSE)):
case (GET_EXC_INDEX(EXC_BADFUN)):
case (GET_EXC_INDEX(EXC_BADARITY)):
+ case (GET_EXC_INDEX(EXC_BADMAP)):
+ case (GET_EXC_INDEX(EXC_BADKEY)):
/* Some common exceptions: value -> {atom, value} */
ASSERT(is_value(Value));
hp = HAlloc(c_p, 3);
@@ -5831,7 +5968,7 @@ build_stacktrace(Process* c_p, Eterm exc) {
* (e.g. spawn_link(erlang, abs, [1])).
*/
if (fi.current == NULL) {
- erts_set_current_function(&fi, c_p->initial);
+ erts_set_current_function(&fi, c_p->u.initial);
args = am_true; /* Just in case */
} else {
args = get_args_from_exc(exc);
@@ -6039,13 +6176,7 @@ apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg)
} else if (ERTS_PROC_GET_SAVED_CALLS_BUF(p)) {
save_calls(p, ep);
}
-
-#ifdef USE_VM_CALL_PROBES
- if (DTRACE_ENABLED(global_function_entry)) {
- BeamInstr *fptr = (BeamInstr *) ep->addressv[erts_active_code_ix()];
- DTRACE_GLOBAL_CALL(p, (Eterm)fptr[-3], (Eterm)fptr[-2], (Uint)fptr[-1]);
- }
-#endif
+ DTRACE_GLOBAL_CALL_FROM_EXPORT(p, ep);
return ep->addressv[erts_active_code_ix()];
}
@@ -6094,13 +6225,7 @@ fixed_apply(Process* p, Eterm* reg, Uint arity)
} else if (ERTS_PROC_GET_SAVED_CALLS_BUF(p)) {
save_calls(p, ep);
}
-
-#ifdef USE_VM_CALL_PROBES
- if (DTRACE_ENABLED(global_function_entry)) {
- BeamInstr *fptr = (BeamInstr *) ep->addressv[erts_active_code_ix()];
- DTRACE_GLOBAL_CALL(p, (Eterm)fptr[-3], (Eterm)fptr[-2], (Uint)fptr[-1]);
- }
-#endif
+ DTRACE_GLOBAL_CALL_FROM_EXPORT(p, ep);
return ep->addressv[erts_active_code_ix()];
}
@@ -6110,6 +6235,23 @@ erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* re
int arity;
Eterm tmp;
+#ifndef ERTS_SMP
+ if (ERTS_PROC_IS_EXITING(c_p)) {
+ /*
+ * I non smp case:
+ *
+ * Currently executing process might be sent an exit
+ * signal if it is traced by a port that it also is
+ * linked to, and the port terminates during the
+ * trace. In this case we do *not* want to clear
+ * the active flag, which will make the process hang
+ * in limbo forever. Get out of here and terminate
+ * the process...
+ */
+ return -1;
+ }
+#endif
+
if (is_not_atom(module) || is_not_atom(function)) {
/*
* No need to test args here -- done below.
@@ -6186,7 +6328,16 @@ erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* re
ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS);
-#ifdef ERTS_SMP
+#ifndef ERTS_SMP
+ if (ERTS_PROC_IS_EXITING(c_p)) {
+ /*
+ * See comment in the begining of the function...
+ *
+ * This second test is needed since gc might be traced.
+ */
+ return -1;
+ }
+#else /* ERTS_SMP */
ERTS_SMP_MSGQ_MV_INQ2PRIVQ(c_p);
if (!c_p->msg.len)
#endif
@@ -6422,57 +6573,75 @@ new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free)
return make_fun(funp);
}
-static int has_not_map_field(Eterm map, Eterm key)
+static Eterm get_map_element(Eterm map, Eterm key)
{
- map_t* mp;
- Eterm* keys;
- Uint i;
- Uint n;
-
- mp = (map_t *)map_val(map);
- keys = map_get_keys(mp);
- n = map_get_size(mp);
- if (is_immed(key)) {
- for (i = 0; i < n; i++) {
- if (keys[i] == key) {
- return 0;
+ Uint32 hx;
+ const Eterm *vs;
+ if (is_flatmap(map)) {
+ flatmap_t *mp;
+ Eterm *ks;
+ Uint i;
+ Uint n;
+
+ mp = (flatmap_t *)flatmap_val(map);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+ n = flatmap_get_size(mp);
+ if (is_immed(key)) {
+ for (i = 0; i < n; i++) {
+ if (ks[i] == key) {
+ return vs[i];
+ }
}
- }
- } else {
- for (i = 0; i < n; i++) {
- if (EQ(keys[i], key)) {
- return 0;
+ } else {
+ for (i = 0; i < n; i++) {
+ if (EQ(ks[i], key)) {
+ return vs[i];
+ }
}
}
+ return THE_NON_VALUE;
}
- return 1;
+ ASSERT(is_hashmap(map));
+ hx = hashmap_make_hash(key);
+ vs = erts_hashmap_get(hx,key,map);
+ return vs ? *vs : THE_NON_VALUE;
}
-static Eterm get_map_element(Eterm map, Eterm key)
+static Eterm get_map_element_hash(Eterm map, Eterm key, Uint32 hx)
{
- map_t *mp;
- Eterm* ks, *vs;
- Uint i;
- Uint n;
-
- mp = (map_t *)map_val(map);
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
- n = map_get_size(mp);
- if (is_immed(key)) {
- for (i = 0; i < n; i++) {
- if (ks[i] == key) {
- return vs[i];
+ const Eterm *vs;
+
+ if (is_flatmap(map)) {
+ flatmap_t *mp;
+ Eterm *ks;
+ Uint i;
+ Uint n;
+
+ mp = (flatmap_t *)flatmap_val(map);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+ n = flatmap_get_size(mp);
+ if (is_immed(key)) {
+ for (i = 0; i < n; i++) {
+ if (ks[i] == key) {
+ return vs[i];
+ }
}
- }
- } else {
- for (i = 0; i < n; i++) {
- if (EQ(ks[i], key)) {
- return vs[i];
+ } else {
+ for (i = 0; i < n; i++) {
+ if (EQ(ks[i], key)) {
+ return vs[i];
+ }
}
}
+ return THE_NON_VALUE;
}
- return THE_NON_VALUE;
+
+ ASSERT(is_hashmap(map));
+ ASSERT(hx == hashmap_make_hash(key));
+ vs = erts_hashmap_get(hx, key, map);
+ return vs ? *vs : THE_NON_VALUE;
}
#define GET_TERM(term, dest) \
@@ -6505,7 +6674,40 @@ new_map(Process* p, Eterm* reg, BeamInstr* I)
Eterm *mhp,*thp;
Eterm *E;
BeamInstr *ptr;
- map_t *mp;
+ flatmap_t *mp;
+ ErtsHeapFactory factory;
+
+ ptr = &Arg(4);
+
+ if (n > 2*MAP_SMALL_MAP_LIMIT) {
+ Eterm res;
+ if (HeapWordsLeft(p) < n) {
+ erts_garbage_collect(p, n, reg, Arg(2));
+ }
+
+ mhp = p->htop;
+ thp = p->htop;
+ E = p->stop;
+
+ for (i = 0; i < n/2; i++) {
+ GET_TERM(*ptr++, *mhp++);
+ GET_TERM(*ptr++, *mhp++);
+ }
+
+ p->htop = mhp;
+
+ erts_factory_proc_init(&factory, p);
+ res = erts_hashmap_from_array(&factory, thp, n/2, 0);
+ erts_factory_close(&factory);
+ if (p->mbuf) {
+ Uint live = Arg(2);
+ reg[live] = res;
+ erts_garbage_collect(p, 0, reg, live+1);
+ res = reg[live];
+ E = p->stop;
+ }
+ return res;
+ }
if (HeapWordsLeft(p) < need) {
erts_garbage_collect(p, need, reg, Arg(2));
@@ -6514,12 +6716,11 @@ new_map(Process* p, Eterm* reg, BeamInstr* I)
thp = p->htop;
mhp = thp + 1 + n/2;
E = p->stop;
- ptr = &Arg(4);
keys = make_tuple(thp);
*thp++ = make_arityval(n/2);
- mp = (map_t *)mhp; mhp += MAP_HEADER_SIZE;
- mp->thing_word = MAP_HEADER;
+ mp = (flatmap_t *)mhp; mhp += MAP_HEADER_FLATMAP_SZ;
+ mp->thing_word = MAP_HEADER_FLATMAP;
mp->size = n/2;
mp->keys = keys;
@@ -6528,7 +6729,7 @@ new_map(Process* p, Eterm* reg, BeamInstr* I)
GET_TERM(*ptr++, *mhp++);
}
p->htop = mhp;
- return make_map(mp);
+ return make_flatmap(mp);
}
static Eterm
@@ -6538,7 +6739,7 @@ update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
Uint num_old;
Uint num_updates;
Uint need;
- map_t *old_mp, *mp;
+ flatmap_t *old_mp, *mp;
Eterm res;
Eterm* hp;
Eterm* E;
@@ -6548,12 +6749,43 @@ update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
Eterm new_key;
Eterm* kp;
- if (is_not_map(map)) {
- return THE_NON_VALUE;
+ new_p = &Arg(5);
+ num_updates = Arg(4) / 2;
+
+ if (is_not_flatmap(map)) {
+ Uint32 hx;
+ Eterm val;
+
+ /* apparently the compiler does not emit is_map instructions,
+ * bad compiler */
+
+ if (is_not_hashmap(map))
+ return THE_NON_VALUE;
+
+ res = map;
+ E = p->stop;
+ while(num_updates--) {
+ /* assoc can't fail */
+ GET_TERM(new_p[0], new_key);
+ GET_TERM(new_p[1], val);
+ hx = hashmap_make_hash(new_key);
+
+ res = erts_hashmap_insert(p, hx, new_key, val, res, 0);
+ if (p->mbuf) {
+ Uint live = Arg(3);
+ reg[live] = res;
+ erts_garbage_collect(p, 0, reg, live+1);
+ res = reg[live];
+ E = p->stop;
+ }
+
+ new_p += 2;
+ }
+ return res;
}
- old_mp = (map_t *) map_val(map);
- num_old = map_get_size(old_mp);
+ old_mp = (flatmap_t *) flatmap_val(map);
+ num_old = flatmap_get_size(old_mp);
/*
* If the old map is empty, create a new map.
@@ -6568,14 +6800,13 @@ update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
* update list are new).
*/
- num_updates = Arg(4) / 2;
- need = 2*(num_old+num_updates) + 1 + MAP_HEADER_SIZE;
+ need = 2*(num_old+num_updates) + 1 + MAP_HEADER_FLATMAP_SZ;
if (HeapWordsLeft(p) < need) {
Uint live = Arg(3);
reg[live] = map;
erts_garbage_collect(p, need, reg, live+1);
map = reg[live];
- old_mp = (map_t *)map_val(map);
+ old_mp = (flatmap_t *)flatmap_val(map);
}
/*
@@ -6606,16 +6837,15 @@ update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
kp = p->htop + 1; /* Point to first key */
hp = kp + num_old + num_updates;
- res = make_map(hp);
- mp = (map_t *)hp;
- hp += MAP_HEADER_SIZE;
- mp->thing_word = MAP_HEADER;
+ res = make_flatmap(hp);
+ mp = (flatmap_t *)hp;
+ hp += MAP_HEADER_FLATMAP_SZ;
+ mp->thing_word = MAP_HEADER_FLATMAP;
mp->keys = make_tuple(kp-1);
- old_vals = map_get_values(old_mp);
- old_keys = map_get_keys(old_mp);
+ old_vals = flatmap_get_values(old_mp);
+ old_keys = flatmap_get_keys(old_mp);
- new_p = &Arg(5);
GET_TERM(*new_p, new_key);
n = num_updates;
@@ -6701,8 +6931,19 @@ update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
n = kp - p->htop - 1; /* Actual number of keys/values */
*p->htop = make_arityval(n);
+ p->htop = hp;
mp->size = n;
- p->htop = hp;
+
+ /* The expensive case, need to build a hashmap */
+ if (n > MAP_SMALL_MAP_LIMIT) {
+ res = erts_hashmap_from_ks_and_vs(p,flatmap_get_keys(mp),flatmap_get_values(mp),n);
+ if (p->mbuf) {
+ Uint live = Arg(3);
+ reg[live] = res;
+ erts_garbage_collect(p, 0, reg, live+1);
+ res = reg[live];
+ }
+ }
return res;
}
@@ -6717,7 +6958,7 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
Uint i;
Uint num_old;
Uint need;
- map_t *old_mp, *mp;
+ flatmap_t *old_mp, *mp;
Eterm res;
Eterm* hp;
Eterm* E;
@@ -6726,18 +6967,61 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
BeamInstr* new_p;
Eterm new_key;
- if (is_not_map(map)) {
- return THE_NON_VALUE;
+ new_p = &Arg(5);
+ n = Arg(4) / 2; /* Number of values to be updated */
+ ASSERT(n > 0);
+
+ if (is_not_flatmap(map)) {
+ Uint32 hx;
+ Eterm val;
+
+ /* apparently the compiler does not emit is_map instructions,
+ * bad compiler */
+
+ if (is_not_hashmap(map)) {
+ p->freason = BADMAP;
+ p->fvalue = map;
+ return THE_NON_VALUE;
+ }
+
+ res = map;
+ E = p->stop;
+ while(n--) {
+ GET_TERM(new_p[0], new_key);
+ GET_TERM(new_p[1], val);
+ hx = hashmap_make_hash(new_key);
+
+ res = erts_hashmap_insert(p, hx, new_key, val, res, 1);
+ if (is_non_value(res)) {
+ p->fvalue = new_key;
+ p->freason = BADKEY;
+ return res;
+ }
+
+ if (p->mbuf) {
+ Uint live = Arg(3);
+ reg[live] = res;
+ erts_garbage_collect(p, 0, reg, live+1);
+ res = reg[live];
+ E = p->stop;
+ }
+
+ new_p += 2;
+ }
+ return res;
}
- old_mp = (map_t *) map_val(map);
- num_old = map_get_size(old_mp);
+ old_mp = (flatmap_t *) flatmap_val(map);
+ num_old = flatmap_get_size(old_mp);
/*
- * If the old map is empty, create a new map.
+ * If the old map is empty, fail.
*/
if (num_old == 0) {
+ E = p->stop;
+ p->freason = BADKEY;
+ GET_TERM(new_p[0], p->fvalue);
return THE_NON_VALUE;
}
@@ -6745,13 +7029,13 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
* Allocate the exact heap space needed.
*/
- need = num_old + MAP_HEADER_SIZE;
+ need = num_old + MAP_HEADER_FLATMAP_SZ;
if (HeapWordsLeft(p) < need) {
Uint live = Arg(3);
reg[live] = map;
erts_garbage_collect(p, need, reg, live+1);
map = reg[live];
- old_mp = (map_t *)map_val(map);
+ old_mp = (flatmap_t *)flatmap_val(map);
}
/*
@@ -6761,23 +7045,20 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
hp = p->htop;
E = p->stop;
- old_vals = map_get_values(old_mp);
- old_keys = map_get_keys(old_mp);
+ old_vals = flatmap_get_values(old_mp);
+ old_keys = flatmap_get_keys(old_mp);
- res = make_map(hp);
- mp = (map_t *)hp;
- hp += MAP_HEADER_SIZE;
- mp->thing_word = MAP_HEADER;
+ res = make_flatmap(hp);
+ mp = (flatmap_t *)hp;
+ hp += MAP_HEADER_FLATMAP_SZ;
+ mp->thing_word = MAP_HEADER_FLATMAP;
mp->size = num_old;
mp->keys = old_mp->keys;
/* Get array of key/value pairs to be updated */
- new_p = &Arg(5);
GET_TERM(*new_p, new_key);
/* Update all values */
- n = Arg(4) / 2; /* Number of values to be updated */
- ASSERT(n > 0);
for (i = 0; i < num_old; i++) {
if (!EQ(*old_keys, new_key)) {
/* Not same keys */
@@ -6810,6 +7091,8 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
* update list did not previously exist.
*/
ASSERT(hp == p->htop + need);
+ p->freason = BADKEY;
+ p->fvalue = new_key;
return THE_NON_VALUE;
}
#undef GET_TERM
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 41c1b5d2c2..a6dce2d1d2 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -36,6 +37,7 @@
#include "beam_catches.h"
#include "erl_binary.h"
#include "erl_zlib.h"
+#include "erl_map.h"
#ifdef HIPE
#include "hipe_bif0.h"
@@ -204,10 +206,7 @@ typedef struct {
typedef struct {
Eterm term; /* The tagged term (in the heap). */
- Uint heap_size; /* (Exact) size on the heap. */
- SWord offset; /* Offset from temporary location to final. */
- ErlOffHeap off_heap; /* Start of linked list of ProcBins. */
- Eterm* heap; /* Heap for term. */
+ ErlHeapFragment* heap_frags;
} Literal;
/*
@@ -245,7 +244,7 @@ typedef struct {
/*
* This structure contains all information about the module being loaded.
*/
-
+#define MD5_SIZE 16
typedef struct LoaderState {
/*
* The current logical file within the binary.
@@ -292,7 +291,7 @@ typedef struct LoaderState {
StringPatch* string_patches; /* Linked list of position into string table to patch. */
BeamInstr catches; /* Linked list of catch_yf instructions. */
unsigned loaded_size; /* Final size of code when loaded. */
- byte mod_md5[16]; /* MD5 for module code. */
+ byte mod_md5[MD5_SIZE]; /* MD5 for module code. */
int may_load_nif; /* true if NIFs may later be loaded for this module */
int on_load; /* Index in the code for the on_load function
* (or 0 if there is no on_load function)
@@ -476,6 +475,8 @@ typedef struct LoaderState {
static void free_loader_state(Binary* magic);
+static ErlHeapFragment* new_literal_fragment(Uint size);
+static void free_literal_fragment(ErlHeapFragment*);
static void loader_state_dtor(Binary* magic);
static Eterm insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
Eterm group_leader, Eterm module,
@@ -524,11 +525,16 @@ static void new_literal_patch(LoaderState* stp, int pos);
static void new_string_patch(LoaderState* stp, int pos);
static Uint new_literal(LoaderState* stp, Eterm** hpp, Uint heap_size);
static int genopargcompare(GenOpArg* a, GenOpArg* b);
-static Eterm exported_from_module(Process* p, Eterm mod);
-static Eterm functions_in_module(Process* p, Eterm mod);
-static Eterm attributes_for_module(Process* p, Eterm mod);
-static Eterm compilation_info_for_module(Process* p, Eterm mod);
-static Eterm native_addresses(Process* p, Eterm mod);
+static Eterm get_module_info(Process* p, ErtsCodeIndex code_ix,
+ BeamInstr* code, Eterm module, Eterm what);
+static Eterm exported_from_module(Process* p, ErtsCodeIndex code_ix,
+ Eterm mod);
+static Eterm functions_in_module(Process* p, BeamInstr* code);
+static Eterm attributes_for_module(Process* p, BeamInstr* code);
+static Eterm compilation_info_for_module(Process* p, BeamInstr* code);
+static Eterm md5_of_module(Process* p, BeamInstr* code);
+static Eterm has_native(BeamInstr* code);
+static Eterm native_addresses(Process* p, BeamInstr* code);
int patch_funentries(Eterm Patchlist);
int patch(Eterm Addresses, Uint fe);
static int safe_mul(UWord a, UWord b, UWord* resp);
@@ -648,6 +654,7 @@ erts_prepare_loading(Binary* magic, Process *c_p, Eterm group_leader,
stp->code[MI_COMPILE_PTR] = 0;
stp->code[MI_COMPILE_SIZE] = 0;
stp->code[MI_COMPILE_SIZE_ON_HEAP] = 0;
+ stp->code[MI_MD5_PTR] = 0;
/*
* Read the atom table.
@@ -879,6 +886,28 @@ free_loader_state(Binary* magic)
}
}
+static ErlHeapFragment* new_literal_fragment(Uint size)
+{
+ ErlHeapFragment* bp;
+ bp = (ErlHeapFragment*) ERTS_HEAP_ALLOC(ERTS_ALC_T_PREPARED_CODE,
+ ERTS_HEAP_FRAG_SIZE(size));
+ ERTS_INIT_HEAP_FRAG(bp, size);
+ return bp;
+}
+
+static void free_literal_fragment(ErlHeapFragment* bp)
+{
+ ASSERT(bp != NULL);
+ do {
+ ErlHeapFragment* next_bp = bp->next;
+
+ erts_cleanup_offheap(&bp->off_heap);
+ ERTS_HEAP_FREE(ERTS_ALC_T_PREPARED_CODE, (void *) bp,
+ ERTS_HEAP_FRAG_SIZE(bp->size));
+ bp = next_bp;
+ }while (bp != NULL);
+}
+
/*
* This destructor function can safely be called multiple times.
*/
@@ -918,10 +947,9 @@ loader_state_dtor(Binary* magic)
if (stp->literals != 0) {
int i;
for (i = 0; i < stp->num_literals; i++) {
- if (stp->literals[i].heap != 0) {
- erts_free(ERTS_ALC_T_PREPARED_CODE,
- (void *) stp->literals[i].heap);
- stp->literals[i].heap = 0;
+ if (stp->literals[i].heap_frags != 0) {
+ free_literal_fragment(stp->literals[i].heap_frags);
+ stp->literals[i].heap_frags = 0;
}
}
erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->literals);
@@ -1446,6 +1474,7 @@ read_lambda_table(LoaderState* stp)
return 0;
}
+
static int
read_literal_table(LoaderState* stp)
{
@@ -1467,7 +1496,7 @@ read_literal_table(LoaderState* stp)
stp->allocated_literals = stp->num_literals;
for (i = 0; i < stp->num_literals; i++) {
- stp->literals[i].heap = 0;
+ stp->literals[i].heap_frags = 0;
}
for (i = 0; i < stp->num_literals; i++) {
@@ -1475,28 +1504,38 @@ read_literal_table(LoaderState* stp)
Sint heap_size;
byte* p;
Eterm val;
- Eterm* hp;
+ ErtsHeapFactory factory;
GetInt(stp, 4, sz); /* Size of external term format. */
GetString(stp, p, sz);
if ((heap_size = erts_decode_ext_size(p, sz)) < 0) {
LoadError1(stp, "literal %d: bad external format", i);
}
- hp = stp->literals[i].heap = erts_alloc(ERTS_ALC_T_PREPARED_CODE,
- heap_size*sizeof(Eterm));
- stp->literals[i].off_heap.first = 0;
- stp->literals[i].off_heap.overhead = 0;
- val = erts_decode_ext(&hp, &stp->literals[i].off_heap, &p);
- stp->literals[i].heap_size = hp - stp->literals[i].heap;
- if (stp->literals[i].heap_size > heap_size) {
- erl_exit(1, "overrun by %d word(s) for literal heap, term %d",
- stp->literals[i].heap_size - heap_size, i);
- }
- if (is_non_value(val)) {
- LoadError1(stp, "literal %d: bad external format", i);
- }
- stp->literals[i].term = val;
- stp->total_literal_size += stp->literals[i].heap_size;
+
+ if (heap_size > 0) {
+ erts_factory_message_init(&factory, NULL, NULL,
+ new_literal_fragment(heap_size));
+ factory.alloc_type = ERTS_ALC_T_PREPARED_CODE;
+ val = erts_decode_ext(&factory, &p);
+
+ if (is_non_value(val)) {
+ LoadError1(stp, "literal %d: bad external format", i);
+ }
+ erts_factory_close(&factory);
+ stp->literals[i].heap_frags = factory.heap_frags;
+ stp->total_literal_size += erts_used_frag_sz(factory.heap_frags);
+ }
+ else {
+ erts_factory_dummy_init(&factory);
+ val = erts_decode_ext(&factory, &p);
+ if (is_non_value(val)) {
+ LoadError1(stp, "literal %d: bad external format", i);
+ }
+ ASSERT(is_immed(val));
+ stp->literals[i].heap_frags = NULL;
+ }
+ stp->literals[i].term = val;
+
}
erts_free(ERTS_ALC_T_TMP, uncompressed);
return 1;
@@ -3169,7 +3208,11 @@ gen_increment_from_minus(LoaderState* stp, GenOpArg Reg, GenOpArg Integer,
static int
negation_is_small(LoaderState* stp, GenOpArg Int)
{
- return Int.type == TAG_i && IS_SSMALL(-Int.val);
+ /* Check for the rare case of overflow in BeamInstr (UWord) -> Sint
+ * Cast to the correct type before using IS_SSMALL (Sint) */
+ return Int.type == TAG_i &&
+ !(Int.val & ~((((BeamInstr)1) << ((sizeof(Sint)*8)-1))-1)) &&
+ IS_SSMALL(-((Sint)Int.val));
}
@@ -3319,9 +3362,10 @@ gen_select_tuple_arity(LoaderState* stp, GenOpArg S, GenOpArg Fail,
{
GenOp* op;
+ GenOpArg *tmp;
int arity = Size.val + 3;
int size = Size.val / 2;
- int i;
+ int i, j, align = 0;
/*
* Verify the validity of the list.
@@ -3336,9 +3380,37 @@ gen_select_tuple_arity(LoaderState* stp, GenOpArg S, GenOpArg Fail,
}
/*
+ * Use a special-cased instruction if there are only two values.
+ */
+ if (size == 2) {
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ op->op = genop_i_select_tuple_arity2_6;
+ GENOP_ARITY(op, arity - 1);
+ op->a[0] = S;
+ op->a[1] = Fail;
+ op->a[2].type = TAG_u;
+ op->a[2].val = Rest[0].val;
+ op->a[3].type = TAG_u;
+ op->a[3].val = Rest[2].val;
+ op->a[4] = Rest[1];
+ op->a[5] = Rest[3];
+
+ return op;
+ }
+
+ /*
* Generate the generic instruction.
+ * Assumption:
+ * Few different tuple arities to select on (fewer than 20).
+ * Use linear scan approach.
*/
+ align = 1;
+
+ arity += 2*align;
+ size += align;
+
NEW_GENOP(stp, op);
op->next = NULL;
op->op = genop_i_select_tuple_arity_3;
@@ -3346,39 +3418,36 @@ gen_select_tuple_arity(LoaderState* stp, GenOpArg S, GenOpArg Fail,
op->a[0] = S;
op->a[1] = Fail;
op->a[2].type = TAG_u;
- op->a[2].val = Size.val / 2;
- for (i = 0; i < Size.val; i += 2) {
- op->a[i+3].type = TAG_v;
- op->a[i+3].val = make_arityval(Rest[i].val);
- op->a[i+4] = Rest[i+1];
- }
+ op->a[2].val = size;
- /*
- * Sort the values to make them useful for a binary search.
- */
+ tmp = (GenOpArg *) erts_alloc(ERTS_ALC_T_LOADER_TMP, sizeof(GenOpArg)*(arity-2*align));
- qsort(op->a+3, size, 2*sizeof(GenOpArg),
- (int (*)(const void *, const void *)) genopargcompare);
-#ifdef DEBUG
- for (i = 3; i < arity-2; i += 2) {
- ASSERT(op->a[i].val < op->a[i+2].val);
+ for (i = 3; i < arity - 2*align; i+=2) {
+ tmp[i-3].type = TAG_v;
+ tmp[i-3].val = make_arityval(Rest[i-3].val);
+ tmp[i-2] = Rest[i-2];
}
-#endif
/*
- * Use a special-cased instruction if there are only two values.
+ * Sort the values to make them useful for a sentinel search
*/
- if (size == 2) {
- op->op = genop_i_select_tuple_arity2_6;
- op->arity--;
- op->a[2].type = TAG_u;
- op->a[2].val = arityval(op->a[3].val);
- op->a[3] = op->a[4];
- op->a[4].type = TAG_u;
- op->a[4].val = arityval(op->a[5].val);
- op->a[5] = op->a[6];
+
+ qsort(tmp, size - align, 2*sizeof(GenOpArg),
+ (int (*)(const void *, const void *)) genopargcompare);
+
+ j = 3;
+ for (i = 3; i < arity - 2*align; i += 2) {
+ op->a[j] = tmp[i-3];
+ op->a[j + size] = tmp[i-2];
+ j++;
}
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) tmp);
+
+ op->a[j].type = TAG_u;
+ op->a[j].val = ~((BeamInstr)0);
+ op->a[j+size] = Fail;
+
return op;
}
@@ -3600,45 +3669,109 @@ gen_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
GenOpArg Size, GenOpArg* Rest)
{
GenOp* op;
+ GenOpArg *tmp;
int arity = Size.val + 3;
int size = Size.val / 2;
- int i;
+ int i, j, align = 0;
+
+ if (size == 2) {
+
+ /*
+ * Use a special-cased instruction if there are only two values.
+ */
+
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ op->op = genop_i_select_val2_6;
+ GENOP_ARITY(op, arity - 1);
+ op->a[0] = S;
+ op->a[1] = Fail;
+ op->a[2] = Rest[0];
+ op->a[3] = Rest[2];
+ op->a[4] = Rest[1];
+ op->a[5] = Rest[3];
+
+ return op;
+
+ } else if (size > 10) {
+
+ /* binary search instruction */
+
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ op->op = genop_i_select_val_bins_3;
+ GENOP_ARITY(op, arity);
+ op->a[0] = S;
+ op->a[1] = Fail;
+ op->a[2].type = TAG_u;
+ op->a[2].val = size;
+ for (i = 3; i < arity; i++) {
+ op->a[i] = Rest[i-3];
+ }
+
+ /*
+ * Sort the values to make them useful for a binary search.
+ */
+
+ qsort(op->a+3, size, 2*sizeof(GenOpArg),
+ (int (*)(const void *, const void *)) genopargcompare);
+#ifdef DEBUG
+ for (i = 3; i < arity-2; i += 2) {
+ ASSERT(op->a[i].val < op->a[i+2].val);
+ }
+#endif
+ return op;
+ }
+
+ /* linear search instruction */
+
+ align = 1;
+
+ arity += 2*align;
+ size += align;
NEW_GENOP(stp, op);
op->next = NULL;
- op->op = genop_i_select_val_3;
+ op->op = genop_i_select_val_lins_3;
GENOP_ARITY(op, arity);
op->a[0] = S;
op->a[1] = Fail;
op->a[2].type = TAG_u;
op->a[2].val = size;
- for (i = 3; i < arity; i++) {
- op->a[i] = Rest[i-3];
+
+ tmp = (GenOpArg *) erts_alloc(ERTS_ALC_T_LOADER_TMP, sizeof(GenOpArg)*(arity-2*align));
+
+ for (i = 3; i < arity - 2*align; i++) {
+ tmp[i-3] = Rest[i-3];
}
/*
- * Sort the values to make them useful for a binary search.
+ * Sort the values to make them useful for a sentinel search
*/
- qsort(op->a+3, size, 2*sizeof(GenOpArg),
- (int (*)(const void *, const void *)) genopargcompare);
-#ifdef DEBUG
- for (i = 3; i < arity-2; i += 2) {
- ASSERT(op->a[i].val < op->a[i+2].val);
+ qsort(tmp, size - align, 2*sizeof(GenOpArg),
+ (int (*)(const void *, const void *)) genopargcompare);
+
+ j = 3;
+ for (i = 3; i < arity - 2*align; i += 2) {
+ op->a[j] = tmp[i-3];
+ op->a[j+size] = tmp[i-2];
+ j++;
}
-#endif
- /*
- * Use a special-cased instruction if there are only two values.
- */
- if (size == 2) {
- op->op = genop_i_select_val2_6;
- op->arity--;
- op->a[2] = op->a[3];
- op->a[3] = op->a[4];
- op->a[4] = op->a[5];
- op->a[5] = op->a[6];
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) tmp);
+
+ /* add sentinel */
+
+ op->a[j].type = TAG_u;
+ op->a[j].val = ~((BeamInstr)0);
+ op->a[j+size] = Fail;
+
+#ifdef DEBUG
+ for (i = 0; i < size - 1; i++) {
+ ASSERT(op->a[i+3].val <= op->a[i+4].val);
}
+#endif
return op;
}
@@ -3959,8 +4092,139 @@ tuple_append_put(LoaderState* stp, GenOpArg Arity, GenOpArg Dst,
}
/*
+ * Predicate to test whether the given literal is a map.
+ */
+
+static int
+literal_is_map(LoaderState* stp, GenOpArg Lit)
+{
+ Eterm term;
+
+ ASSERT(Lit.type == TAG_q);
+ term = stp->literals[Lit.val].term;
+ return is_map(term);
+}
+
+/*
+ * Predicate to test whether the given literal is an empty map.
+ */
+
+static int
+is_empty_map(LoaderState* stp, GenOpArg Lit)
+{
+ Eterm term;
+
+ if (Lit.type != TAG_q) {
+ return 0;
+ }
+ term = stp->literals[Lit.val].term;
+ return is_flatmap(term) && flatmap_get_size(flatmap_val(term)) == 0;
+}
+
+/*
+ * Pseudo predicate map_key_sort that will sort the Rest operand for
+ * map instructions as a side effect.
+ */
+
+typedef struct SortGenOpArg {
+ Eterm term; /* Term to use for comparing */
+ GenOpArg arg; /* Original data */
+} SortGenOpArg;
+
+static int
+genopargtermcompare(SortGenOpArg* a, SortGenOpArg* b)
+{
+ return CMP_TERM(a->term, b->term);
+}
+
+static int
+map_key_sort(LoaderState* stp, GenOpArg Size, GenOpArg* Rest)
+{
+ SortGenOpArg* t;
+ unsigned size = Size.val;
+ unsigned i;
+
+ if (size == 2) {
+ return 1; /* Already sorted. */
+ }
+
+
+ t = (SortGenOpArg *) erts_alloc(ERTS_ALC_T_TMP, size*sizeof(SortGenOpArg));
+
+ /*
+ * Copy original data and sort keys to a temporary array.
+ */
+ for (i = 0; i < size; i += 2) {
+ t[i].arg = Rest[i];
+ switch (Rest[i].type) {
+ case TAG_a:
+ t[i].term = Rest[i].val;
+ ASSERT(is_atom(t[i].term));
+ break;
+ case TAG_i:
+ t[i].term = make_small(Rest[i].val);
+ break;
+ case TAG_n:
+ t[i].term = NIL;
+ break;
+ case TAG_q:
+ t[i].term = stp->literals[Rest[i].val].term;
+ break;
+ default:
+ /*
+ * Not a literal key. Not allowed. Only a single
+ * variable key is allowed in each map instruction.
+ */
+ erts_free(ERTS_ALC_T_TMP, (void *) t);
+ return 0;
+ }
+#ifdef DEBUG
+ t[i+1].term = THE_NON_VALUE;
+#endif
+ t[i+1].arg = Rest[i+1];
+ }
+
+ /*
+ * Sort the temporary array.
+ */
+ qsort((void *) t, size / 2, 2 * sizeof(SortGenOpArg),
+ (int (*)(const void *, const void *)) genopargtermcompare);
+
+ /*
+ * Copy back the sorted, original data.
+ */
+ for (i = 0; i < size; i++) {
+ Rest[i] = t[i].arg;
+ }
+
+ erts_free(ERTS_ALC_T_TMP, (void *) t);
+ return 1;
+}
+
+static int
+hash_genop_arg(LoaderState* stp, GenOpArg Key, Uint32* hx)
+{
+ switch (Key.type) {
+ case TAG_a:
+ *hx = hashmap_make_hash(Key.val);
+ return 1;
+ case TAG_i:
+ *hx = hashmap_make_hash(make_small(Key.val));
+ return 1;
+ case TAG_n:
+ *hx = hashmap_make_hash(NIL);
+ return 1;
+ case TAG_q:
+ *hx = hashmap_make_hash(stp->literals[Key.val].term);
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/*
* Replace a get_map_elements with one key to an instruction with one
- * element
+ * element.
*/
static GenOp*
@@ -3968,37 +4232,99 @@ gen_get_map_element(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
GenOpArg Size, GenOpArg* Rest)
{
GenOp* op;
+ GenOpArg Key;
+ Uint32 hx = 0;
ASSERT(Size.type == TAG_u);
NEW_GENOP(stp, op);
op->next = NULL;
- op->op = genop_get_map_element_4;
- op->arity = 4;
-
op->a[0] = Fail;
op->a[1] = Src;
op->a[2] = Rest[0];
- op->a[3] = Rest[1];
+
+ Key = Rest[0];
+ if (hash_genop_arg(stp, Key, &hx)) {
+ op->arity = 5;
+ op->op = genop_i_get_map_element_hash_5;
+ op->a[3].type = TAG_u;
+ op->a[3].val = (BeamInstr) hx;
+ op->a[4] = Rest[1];
+ } else {
+ op->arity = 4;
+ op->op = genop_i_get_map_element_4;
+ op->a[3] = Rest[1];
+ }
return op;
}
static GenOp*
-gen_has_map_field(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
- GenOpArg Size, GenOpArg* Rest)
+gen_get_map_elements(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
+ GenOpArg Size, GenOpArg* Rest)
{
GenOp* op;
+ Uint32 hx;
+ Uint i;
+ GenOpArg* dst;
+#ifdef DEBUG
+ int good_hash;
+#endif
ASSERT(Size.type == TAG_u);
NEW_GENOP(stp, op);
+ op->op = genop_i_get_map_elements_3;
+ GENOP_ARITY(op, 3 + 3*(Size.val/2));
op->next = NULL;
- op->op = genop_has_map_field_3;
- op->arity = 4;
+ op->a[0] = Fail;
+ op->a[1] = Src;
+ op->a[2].type = TAG_u;
+ op->a[2].val = 3*(Size.val/2);
+
+ dst = op->a+3;
+ for (i = 0; i < Size.val / 2; i++) {
+ dst[0] = Rest[2*i];
+ dst[1] = Rest[2*i+1];
+#ifdef DEBUG
+ good_hash =
+#endif
+ hash_genop_arg(stp, dst[0], &hx);
+#ifdef DEBUG
+ ASSERT(good_hash);
+#endif
+ dst[2].type = TAG_u;
+ dst[2].val = (BeamInstr) hx;
+ dst += 3;
+ }
+ return op;
+}
+
+static GenOp*
+gen_has_map_fields(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
+ GenOpArg Size, GenOpArg* Rest)
+{
+ GenOp* op;
+ Uint i;
+ Uint n;
+
+ ASSERT(Size.type == TAG_u);
+ n = Size.val;
+
+ NEW_GENOP(stp, op);
+ GENOP_ARITY(op, 3 + 2*n);
+ op->next = NULL;
+ op->op = genop_get_map_elements_3;
op->a[0] = Fail;
op->a[1] = Src;
- op->a[2] = Rest[0];
+ op->a[2].type = TAG_u;
+ op->a[2].val = 2*n;
+
+ for (i = 0; i < n; i++) {
+ op->a[3+2*i] = Rest[i];
+ op->a[3+2*i+1].type = TAG_x;
+ op->a[3+2*i+1].val = 0; /* x(0); normally not used */
+ }
return op;
}
@@ -4042,7 +4368,7 @@ freeze_code(LoaderState* stp)
}
size = (stp->ci * sizeof(BeamInstr)) +
(stp->total_literal_size * sizeof(Eterm)) +
- strtab_size + attr_size + compile_size + line_size;
+ strtab_size + attr_size + compile_size + MD5_SIZE + line_size;
/*
* Move the code to its final location.
@@ -4079,8 +4405,9 @@ freeze_code(LoaderState* stp)
Uint* low;
Uint* high;
LiteralPatch* lp;
- struct erl_off_heap_header* off_heap = 0;
- struct erl_off_heap_header** off_heap_last = &off_heap;
+ ErlOffHeap code_off_heap;
+
+ ERTS_INIT_OFF_HEAP(&code_off_heap);
low = (Uint *) (code+stp->ci);
high = low + stp->total_literal_size;
@@ -4088,73 +4415,21 @@ freeze_code(LoaderState* stp)
code[MI_LITERALS_END] = (BeamInstr) high;
ptr = low;
for (i = 0; i < stp->num_literals; i++) {
- SWord offset;
- struct erl_off_heap_header* t_off_heap;
-
- sys_memcpy(ptr, stp->literals[i].heap,
- stp->literals[i].heap_size*sizeof(Eterm));
- offset = ptr - stp->literals[i].heap;
- stp->literals[i].offset = offset;
- high = ptr + stp->literals[i].heap_size;
- while (ptr < high) {
- Eterm val = *ptr;
- switch (primary_tag(val)) {
- case TAG_PRIMARY_LIST:
- case TAG_PRIMARY_BOXED:
- *ptr++ = offset_ptr(val, offset);
- break;
- case TAG_PRIMARY_HEADER:
- if (header_is_transparent(val)) {
- ptr++;
- } else {
- if (thing_subtag(val) == REFC_BINARY_SUBTAG) {
- struct erl_off_heap_header* oh;
-
- oh = (struct erl_off_heap_header*) ptr;
- if (oh->next) {
- Eterm** uptr = (Eterm **) (void *) &oh->next;
- *uptr += offset;
- }
- }
- ptr += 1 + thing_arityval(val);
- }
- break;
- default:
- ptr++;
- break;
- }
- }
- ASSERT(ptr == high);
-
- /*
- * Re-link the off_heap list for this term onto the
- * off_heap list for the entire module.
- */
- t_off_heap = stp->literals[i].off_heap.first;
- if (t_off_heap) {
- t_off_heap = (struct erl_off_heap_header *)
- offset_ptr((UWord) t_off_heap, offset);
- while (t_off_heap) {
- *off_heap_last = t_off_heap;
- off_heap_last = &t_off_heap->next;
- t_off_heap = t_off_heap->next;
- }
- }
+ if (stp->literals[i].heap_frags) {
+ move_multi_frags(&ptr, &code_off_heap, stp->literals[i].heap_frags,
+ &stp->literals[i].term, 1);
+ }
+ else ASSERT(is_immed(stp->literals[i].term));
}
- code[MI_LITERALS_OFF_HEAP] = (BeamInstr) off_heap;
+ code[MI_LITERALS_OFF_HEAP] = (BeamInstr) code_off_heap.first;
lp = stp->literal_patches;
while (lp != 0) {
BeamInstr* op_ptr;
- Uint literal;
Literal* lit;
op_ptr = code + lp->pos;
lit = &stp->literals[op_ptr[0]];
- literal = lit->term;
- if (is_boxed(literal) || is_list(literal)) {
- literal = offset_ptr(literal, lit->offset);
- }
- op_ptr[0] = literal;
+ op_ptr[0] = lit->term;
lp = lp->next;
}
literal_end += stp->total_literal_size;
@@ -4251,11 +4526,20 @@ freeze_code(LoaderState* stp)
code[MI_COMPILE_SIZE_ON_HEAP] = decoded_size;
}
CHKBLK(ERTS_ALC_T_CODE,code);
+ {
+ byte* md5_sum = str_table + strtab_size + attr_size + compile_size;
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ sys_memcpy(md5_sum, stp->mod_md5, MD5_SIZE);
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ code[MI_MD5_PTR] = (BeamInstr) md5_sum;
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ }
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Make sure that we have not overflowed the allocated code space.
*/
- ASSERT(str_table + strtab_size + attr_size + compile_size ==
+ ASSERT(str_table + strtab_size + attr_size + compile_size + MD5_SIZE ==
((byte *) code) + size);
/*
@@ -5076,19 +5360,18 @@ new_literal(LoaderState* stp, Eterm** hpp, Uint heap_size)
stp->total_literal_size += heap_size;
lit = stp->literals + stp->num_literals;
- lit->offset = 0;
- lit->heap_size = heap_size;
- lit->heap = erts_alloc(ERTS_ALC_T_PREPARED_CODE, heap_size*sizeof(Eterm));
- lit->term = make_boxed(lit->heap);
- lit->off_heap.first = 0;
- lit->off_heap.overhead = 0;
- *hpp = lit->heap;
+ lit->heap_frags = new_literal_fragment(heap_size);
+ lit->term = make_boxed(lit->heap_frags->mem);
+ *hpp = lit->heap_frags->mem;
return stp->num_literals++;
}
Eterm
erts_module_info_0(Process* p, Eterm module)
{
+ Module* modp;
+ ErtsCodeIndex code_ix = erts_active_code_ix();
+ BeamInstr* code;
Eterm *hp;
Eterm list = NIL;
Eterm tup;
@@ -5097,21 +5380,31 @@ erts_module_info_0(Process* p, Eterm module)
return THE_NON_VALUE;
}
- if (erts_get_module(module, erts_active_code_ix()) == NULL) {
+ modp = erts_get_module(module, code_ix);
+ if (modp == NULL) {
return THE_NON_VALUE;
}
+ code = modp->curr.code;
+ if (code == NULL) {
+ return THE_NON_VALUE;
+ }
+
#define BUILD_INFO(What) \
- tup = erts_module_info_1(p, module, What); \
+ tup = get_module_info(p, code_ix, code, module, What); \
hp = HAlloc(p, 5); \
tup = TUPLE2(hp, What, tup); \
hp += 3; \
list = CONS(hp, tup, list)
+ BUILD_INFO(am_md5);
+#ifdef HIPE
+ BUILD_INFO(am_native);
+#endif
BUILD_INFO(am_compile);
BUILD_INFO(am_attributes);
- BUILD_INFO(am_imports);
BUILD_INFO(am_exports);
+ BUILD_INFO(am_module);
#undef BUILD_INFO
return list;
}
@@ -5119,20 +5412,47 @@ erts_module_info_0(Process* p, Eterm module)
Eterm
erts_module_info_1(Process* p, Eterm module, Eterm what)
{
+ Module* modp;
+ ErtsCodeIndex code_ix = erts_active_code_ix();
+ BeamInstr* code;
+
+ if (is_not_atom(module)) {
+ return THE_NON_VALUE;
+ }
+
+ modp = erts_get_module(module, code_ix);
+ if (modp == NULL) {
+ return THE_NON_VALUE;
+ }
+
+ code = modp->curr.code;
+ if (code == NULL) {
+ return THE_NON_VALUE;
+ }
+
+ return get_module_info(p, code_ix, code, module, what);
+}
+
+static Eterm
+get_module_info(Process* p, ErtsCodeIndex code_ix, BeamInstr* code,
+ Eterm module, Eterm what)
+{
if (what == am_module) {
return module;
- } else if (what == am_imports) {
- return NIL;
+ } else if (what == am_md5) {
+ return md5_of_module(p, code);
} else if (what == am_exports) {
- return exported_from_module(p, module);
+ return exported_from_module(p, code_ix, module);
} else if (what == am_functions) {
- return functions_in_module(p, module);
+ return functions_in_module(p, code);
} else if (what == am_attributes) {
- return attributes_for_module(p, module);
+ return attributes_for_module(p, code);
} else if (what == am_compile) {
- return compilation_info_for_module(p, module);
+ return compilation_info_for_module(p, code);
} else if (what == am_native_addresses) {
- return native_addresses(p, module);
+ return native_addresses(p, code);
+ } else if (what == am_native) {
+ return has_native(code);
}
return THE_NON_VALUE;
}
@@ -5140,16 +5460,12 @@ erts_module_info_1(Process* p, Eterm module, Eterm what)
/*
* Builds a list of all functions in the given module:
* [{Name, Arity},...]
- *
- * Returns a tagged term, or 0 on error.
*/
Eterm
functions_in_module(Process* p, /* Process whose heap to use. */
- Eterm mod) /* Tagged atom for module. */
+ BeamInstr* code)
{
- Module* modp;
- BeamInstr* code;
int i;
Uint num_functions;
Uint need;
@@ -5157,15 +5473,6 @@ functions_in_module(Process* p, /* Process whose heap to use. */
Eterm* hp_end;
Eterm result = NIL;
- if (is_not_atom(mod)) {
- return THE_NON_VALUE;
- }
-
- modp = erts_get_module(mod, erts_active_code_ix());
- if (modp == NULL) {
- return THE_NON_VALUE;
- }
- code = modp->curr.code;
num_functions = code[MI_NUM_FUNCTIONS];
need = 5*num_functions;
hp = HAlloc(p, need);
@@ -5193,17 +5500,49 @@ functions_in_module(Process* p, /* Process whose heap to use. */
}
/*
+ * Returns 'true' if mod has any native compiled functions, otherwise 'false'
+ */
+
+static Eterm
+has_native(BeamInstr *code)
+{
+ Eterm result = am_false;
+#ifdef HIPE
+ if (erts_is_module_native(code)) {
+ result = am_true;
+ }
+#endif
+ return result;
+}
+
+int
+erts_is_module_native(BeamInstr* code)
+{
+ Uint i, num_functions;
+
+ /* Check NativeAdress of first real function in module */
+ if (code != NULL) {
+ num_functions = code[MI_NUM_FUNCTIONS];
+ for (i=0; i<num_functions; i++) {
+ BeamInstr* func_info = (BeamInstr *) code[MI_FUNCTIONS+i];
+ Eterm name = (Eterm) func_info[3];
+ if (is_atom(name)) {
+ return func_info[1] != 0;
+ }
+ else ASSERT(is_nil(name)); /* ignore BIF stubs */
+ }
+ }
+ return 0;
+}
+
+/*
* Builds a list of all functions including native addresses.
* [{Name,Arity,NativeAddress},...]
- *
- * Returns a tagged term, or 0 on error.
*/
static Eterm
-native_addresses(Process* p, Eterm mod)
+native_addresses(Process* p, BeamInstr* code)
{
- Module* modp;
- BeamInstr* code;
int i;
Eterm* hp;
Uint num_functions;
@@ -5211,16 +5550,6 @@ native_addresses(Process* p, Eterm mod)
Eterm* hp_end;
Eterm result = NIL;
- if (is_not_atom(mod)) {
- return THE_NON_VALUE;
- }
-
- modp = erts_get_module(mod, erts_active_code_ix());
- if (modp == NULL) {
- return THE_NON_VALUE;
- }
-
- code = modp->curr.code;
num_functions = code[MI_NUM_FUNCTIONS];
need = (6+BIG_UINT_HEAP_SIZE)*num_functions;
hp = HAlloc(p, need);
@@ -5247,25 +5576,18 @@ native_addresses(Process* p, Eterm mod)
/*
* Builds a list of all exported functions in the given module:
* [{Name, Arity},...]
- *
- * Returns a tagged term, or 0 on error.
*/
Eterm
exported_from_module(Process* p, /* Process whose heap to use. */
+ ErtsCodeIndex code_ix,
Eterm mod) /* Tagged atom for module. */
{
int i;
Eterm* hp = NULL;
Eterm* hend = NULL;
Eterm result = NIL;
- ErtsCodeIndex code_ix;
-
- if (is_not_atom(mod)) {
- return THE_NON_VALUE;
- }
- code_ix = erts_active_code_ix();
for (i = 0; i < export_list_size(code_ix); i++) {
Export* ep = export_list(i,code_ix);
@@ -5295,84 +5617,62 @@ exported_from_module(Process* p, /* Process whose heap to use. */
/*
* Returns a list of all attributes for the module.
- *
- * Returns a tagged term, or 0 on error.
*/
Eterm
attributes_for_module(Process* p, /* Process whose heap to use. */
- Eterm mod) /* Tagged atom for module. */
-
+ BeamInstr* code)
{
- Module* modp;
- BeamInstr* code;
- Eterm* hp;
byte* ext;
Eterm result = NIL;
- Eterm* end;
- if (is_not_atom(mod) || (is_not_list(result) && is_not_nil(result))) {
- return THE_NON_VALUE;
- }
-
- modp = erts_get_module(mod, erts_active_code_ix());
- if (modp == NULL) {
- return THE_NON_VALUE;
- }
- code = modp->curr.code;
ext = (byte *) code[MI_ATTR_PTR];
if (ext != NULL) {
- hp = HAlloc(p, code[MI_ATTR_SIZE_ON_HEAP]);
- end = hp + code[MI_ATTR_SIZE_ON_HEAP];
- result = erts_decode_ext(&hp, &MSO(p), &ext);
+ ErtsHeapFactory factory;
+ erts_factory_proc_prealloc_init(&factory, p, code[MI_ATTR_SIZE_ON_HEAP]);
+ result = erts_decode_ext(&factory, &ext);
if (is_value(result)) {
- ASSERT(hp <= end);
+ erts_factory_close(&factory);
}
- HRelease(p,end,hp);
}
return result;
}
/*
* Returns a list containing compilation information.
- *
- * Returns a tagged term, or 0 on error.
*/
Eterm
compilation_info_for_module(Process* p, /* Process whose heap to use. */
- Eterm mod) /* Tagged atom for module. */
+ BeamInstr* code)
{
- Module* modp;
- BeamInstr* code;
- Eterm* hp;
byte* ext;
Eterm result = NIL;
- Eterm* end;
- if (is_not_atom(mod) || (is_not_list(result) && is_not_nil(result))) {
- return THE_NON_VALUE;
- }
-
- modp = erts_get_module(mod, erts_active_code_ix());
- if (modp == NULL) {
- return THE_NON_VALUE;
- }
- code = modp->curr.code;
ext = (byte *) code[MI_COMPILE_PTR];
if (ext != NULL) {
- hp = HAlloc(p, code[MI_COMPILE_SIZE_ON_HEAP]);
- end = hp + code[MI_COMPILE_SIZE_ON_HEAP];
- result = erts_decode_ext(&hp, &MSO(p), &ext);
+ ErtsHeapFactory factory;
+ erts_factory_proc_prealloc_init(&factory, p, code[MI_COMPILE_SIZE_ON_HEAP]);
+ result = erts_decode_ext(&factory, &ext);
if (is_value(result)) {
- ASSERT(hp <= end);
+ erts_factory_close(&factory);
}
- HRelease(p,end,hp);
}
return result;
}
/*
+ * Returns the MD5 checksum for a module
+ */
+
+Eterm
+md5_of_module(Process* p, /* Process whose heap to use. */
+ BeamInstr* code)
+{
+ return new_binary(p, (byte *) code[MI_MD5_PTR], MD5_SIZE);
+}
+
+/*
* Build a single {M,F,A,Loction} item to be part of
* a stack trace.
*/
@@ -5548,7 +5848,7 @@ code_module_md5_1(BIF_ALIST_1)
res = am_undefined;
goto done;
}
- res = new_binary(p, stp->mod_md5, sizeof(stp->mod_md5));
+ res = new_binary(p, stp->mod_md5, MD5_SIZE);
done:
erts_free_aligned_binary_bytes(temp_alloc);
@@ -5841,6 +6141,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
LoaderState* stp;
BeamInstr Funcs;
BeamInstr Patchlist;
+ Eterm MD5Bin;
Eterm* tp;
BeamInstr* code = NULL;
BeamInstr* ptrs;
@@ -5869,12 +6170,15 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
goto error;
}
tp = tuple_val(Info);
- if (tp[0] != make_arityval(2)) {
+ if (tp[0] != make_arityval(3)) {
goto error;
}
Funcs = tp[1];
- Patchlist = tp[2];
-
+ Patchlist = tp[2];
+ MD5Bin = tp[3];
+ if (is_not_binary(MD5Bin) || (binary_size(MD5Bin) != MD5_SIZE)) {
+ goto error;
+ }
if ((n = erts_list_length(Funcs)) < 0) {
goto error;
}
@@ -5924,6 +6228,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(BeamInstr);
code_size += stp->chunks[ATTR_CHUNK].size;
code_size += stp->chunks[COMPILE_CHUNK].size;
+ code_size += MD5_SIZE;
code = erts_alloc_fnf(ERTS_ALC_T_CODE, code_size);
if (!code) {
goto error;
@@ -5944,6 +6249,8 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
code[MI_LITERALS_END] = 0;
code[MI_LITERALS_OFF_HEAP] = 0;
code[MI_ON_LOAD_FUNCTION_PTR] = 0;
+ code[MI_LINE_TABLE] = 0;
+ code[MI_MD5_PTR] = 0;
ci = MI_FUNCTIONS + n + 1;
/*
@@ -6029,6 +6336,15 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
if (info == NULL) {
goto error;
}
+ {
+ byte *tmp = NULL;
+ byte *md5 = NULL;
+ if ((md5 = erts_get_aligned_binary_bytes(MD5Bin, &tmp)) != NULL) {
+ sys_memcpy(info, md5, MD5_SIZE);
+ code[MI_MD5_PTR] = (BeamInstr) info;
+ }
+ erts_free_aligned_binary_bytes(tmp);
+ }
/*
* Insert the module in the module table.
diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h
index bd22b0c4de..d5af634fad 100644
--- a/erts/emulator/beam/beam_load.h
+++ b/erts/emulator/beam/beam_load.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -23,10 +24,10 @@
#include "beam_opcodes.h"
#include "erl_process.h"
+int erts_is_module_native(BeamInstr* code);
Eterm beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks,
Eterm module);
-
typedef struct gen_op_entry {
char* name;
int arity;
@@ -91,7 +92,6 @@ extern Uint erts_total_code_size;
#define MI_LITERALS_END 8
#define MI_LITERALS_OFF_HEAP 9
-
/*
* Pointer to the on_load function (or NULL if none).
*/
@@ -103,6 +103,11 @@ extern Uint erts_total_code_size;
#define MI_LINE_TABLE 11
/*
+ * Pointer to the module MD5 sum (16 bytes)
+ */
+#define MI_MD5_PTR 12
+
+/*
* Start of function pointer table. This table contains pointers to
* all functions in the module plus an additional pointer just beyond
* the end of the last function.
@@ -111,7 +116,7 @@ extern Uint erts_total_code_size;
* this table.
*/
-#define MI_FUNCTIONS 12
+#define MI_FUNCTIONS 13
/*
* Layout of the line table.
diff --git a/erts/emulator/beam/beam_ranges.c b/erts/emulator/beam/beam_ranges.c
index cb6470638f..19079ba150 100644
--- a/erts/emulator/beam/beam_ranges.c
+++ b/erts/emulator/beam/beam_ranges.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/benchmark.c b/erts/emulator/beam/benchmark.c
index 8613131176..44f5c760c2 100644
--- a/erts/emulator/beam/benchmark.c
+++ b/erts/emulator/beam/benchmark.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -37,37 +38,9 @@ unsigned long long major_gc;
#ifdef BM_TIMERS
-#if (defined(__i386__) || defined(__x86_64__)) && USE_PERFCTR
-
-#include "libperfctr.h"
-struct vperfctr *system_clock;
-double cpu_khz;
-BM_NEW_TIMER(start);
-
-static double get_hrvtime(void)
-{
- unsigned long long ticks;
- double milli_seconds;
-
- ticks = vperfctr_read_tsc(system_clock);
- milli_seconds = (double)ticks / cpu_khz;
- return milli_seconds;
-}
-
-static void stop_hrvtime(void)
-{
- if(system_clock)
- {
- vperfctr_stop(system_clock);
- vperfctr_close(system_clock);
- system_clock = NULL;
- }
-}
-
-#else /* not perfctr, asuming Solaris */
+/* assuming Solaris */
#include <time.h>
BM_TIMER_T system_clock;
-#endif
unsigned long local_pause_times[MAX_PAUSE_TIME];
unsigned long pause_times[MAX_PAUSE_TIME];
@@ -117,40 +90,6 @@ unsigned long long message_sizes[1000];
void init_benchmarking()
{
#ifdef BM_TIMERS
-#if (defined(__i386__) || defined(__x86_64__)) && USE_PERFCTR
- /* pass `--with-perfctr=/path/to/perfctr' when configuring */
- struct perfctr_info info;
- struct vperfctr_control control;
- int i;
-
- system_clock = vperfctr_open();
- if (system_clock != NULL)
- {
- if (vperfctr_info(system_clock,&info) >= 0)
- {
- cpu_khz = (double)info.cpu_khz;
- if (info.cpu_features & PERFCTR_FEATURE_RDTSC)
- {
- memset(&control,0,sizeof control);
- control.cpu_control.tsc_on = 1;
- }
- }
- if (vperfctr_control(system_clock,&control) < 0)
- {
- vperfctr_close(system_clock);
- system_clock = NULL;
- }
- }
-
- for (i = 0; i < 1000; i++)
- {
- BM_START_TIMER(system);
- BM_STOP_TIMER(system);
- }
-
- timer_time = system_time / 1000;
- start_time = 0;
-#else
int i;
for (i = 0; i < 1000; i++)
{
@@ -158,7 +97,6 @@ void init_benchmarking()
BM_STOP_TIMER(system);
}
timer_time = system_time / 1000;
-#endif
for (i = 0; i < MAX_PAUSE_TIME; i++) {
local_pause_times[i] = 0;
diff --git a/erts/emulator/beam/benchmark.h b/erts/emulator/beam/benchmark.h
index 766edaac42..0fb0b93f12 100644
--- a/erts/emulator/beam/benchmark.h
+++ b/erts/emulator/beam/benchmark.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -37,10 +38,7 @@
/* BM_TIMERS keeps track of the time spent in diferent parts of the
* system. It only measures accual active time, not time spent in idle
- * mode. These timers requires hardware support. For Linux, use the
- * package perfctr from user.it.uu.se/~mikpe/linux/perfctr. If this
- * package is not specified when configuring the system
- * (--with-perfctr=PATH), the Solaris hrtime_t will be used.
+ * mode. Currently, the Solaris hrtime_t will be used.
* To add new timers look below.
*/
#define BM_TIMERS
@@ -142,43 +140,12 @@ extern unsigned long long major_gc;
* meassure (send time in shared heap for instance).
*/
-#if (defined(__i386__) || defined(__x86_64__)) && USE_PERFCTR
-#include "libperfctr.h"
-
-#define BM_TIMER_T double
-
-extern struct vperfctr *system_clock;
-extern double cpu_khz;
-extern BM_TIMER_T start_time;
-
-#define BM_START_TIMER(t) start_time = \
- (BM_TIMER_T)vperfctr_read_tsc(system_clock) / \
- cpu_khz;
-
-#define BM_STOP_TIMER(t) do { \
- BM_TIMER_T tmp = ((BM_TIMER_T)vperfctr_read_tsc(system_clock) / cpu_khz); \
- tmp -= (start_time + timer_time); \
- t##_time += (tmp > 0 ? tmp : 0); \
-} while(0)
-
-#define BM_TIME_PRINTER(str,time) do { \
- int min,sec,milli,micro; \
- BM_TIMER_T tmp = (time) * 1000; \
- micro = (uint)(tmp - ((int)(tmp / 1000)) * 1000); \
- tmp /= 1000; \
- milli = (uint)(tmp - ((int)(tmp / 1000)) * 1000); \
- tmp /= 1000; \
- sec = (uint)(tmp - ((int)(tmp / 60)) * 60); \
- min = (uint)tmp / 60; \
- erts_fprintf(file,str": %d:%02d.%03d %03d\n",min,sec,milli,micro); \
-} while(0)
-
-#else /* !USE_PERFCTR (Assuming Solaris) */
+/* (Assuming Solaris) */
-#define BM_TIMER_T hrtime_t
-#define BM_START_TIMER(t) system_clock = sys_gethrtime()
+#define BM_TIMER_T ErtsMonotonicTime
+#define BM_START_TIMER(t) system_clock = ERTS_MONOTONIC_TO_NSEC(erts_os_monotonic_time())
#define BM_STOP_TIMER(t) do { \
- BM_TIMER_T tmp = (sys_gethrtime() - system_clock) - timer_time; \
+ BM_TIMER_T tmp = (ERTS_MONOTONIC_TO_NSEC(erts_os_monotonic_time()) - system_clock) - timer_time; \
t##_time += (tmp > 0 ? tmp : 0); \
} while(0)
@@ -196,7 +163,6 @@ extern BM_TIMER_T start_time;
} while(0)
extern BM_TIMER_T system_clock;
-#endif /* USE_PERFCTR */
extern BM_TIMER_T timer_time;
extern BM_TIMER_T system_time;
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index b43137597e..095df36a43 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -28,7 +29,9 @@
#include "global.h"
#include "erl_process.h"
#include "error.h"
+#define ERL_WANT_HIPE_BIF_WRAPPER__
#include "bif.h"
+#undef ERL_WANT_HIPE_BIF_WRAPPER__
#include "big.h"
#include "dist.h"
#include "erl_version.h"
@@ -40,16 +43,23 @@
#define ERTS_PTAB_WANT_BIF_IMPL__
#include "erl_ptab.h"
#include "erl_bits.h"
+#include "erl_bif_unique.h"
-static Export* flush_monitor_message_trap = NULL;
+Export *erts_await_result;
+static Export* flush_monitor_messages_trap = NULL;
static Export* set_cpu_topology_trap = NULL;
static Export* await_proc_exit_trap = NULL;
static Export* await_port_send_result_trap = NULL;
Export* erts_format_cpu_topology_trap = NULL;
+static Export dsend_continue_trap_export;
+Export *erts_convert_time_unit_trap = NULL;
static Export *await_sched_wall_time_mod_trap;
static erts_smp_atomic32_t sched_wall_time;
+static erts_smp_mtx_t ports_snapshot_mtx;
+erts_smp_atomic_t erts_dead_ports_ptr; /* To store dying ports during snapshot */
+
#define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
/*
@@ -391,7 +401,7 @@ remote_demonitor(Process *c_p, DistEntry *dep, Eterm ref, Eterm to)
return res;
}
-static int demonitor(Process *c_p, Eterm ref)
+static int demonitor(Process *c_p, Eterm ref, Eterm *multip)
{
ErtsMonitor *mon = NULL; /* The monitor entry to delete */
Process *rp; /* Local target process */
@@ -415,65 +425,73 @@ static int demonitor(Process *c_p, Eterm ref)
goto done;
}
- if (mon->type != MON_ORIGIN) {
- res = ERTS_DEMONITOR_BADARG;
- goto done;
- }
- to = mon->pid;
-
- if (is_atom(to)) {
- /* Monitoring a name at node to */
- ASSERT(is_node_name_atom(to));
- dep = erts_sysname_to_connected_dist_entry(to);
- ASSERT(dep != erts_this_dist_entry);
- if (dep)
- deref_de = 1;
- } else {
- ASSERT(is_pid(to));
- dep = pid_dist_entry(to);
- }
- if (dep != erts_this_dist_entry) {
- res = remote_demonitor(c_p, dep, ref, to);
- /* remote_demonitor() unlocks link lock on c_p */
- unlock_link = 0;
- }
- else { /* Local monitor */
- if (deref_de) {
- deref_de = 0;
- erts_deref_dist_entry(dep);
+ switch (mon->type) {
+ case MON_TIME_OFFSET:
+ *multip = am_true;
+ erts_demonitor_time_offset(ref);
+ res = ERTS_DEMONITOR_TRUE;
+ break;
+ case MON_ORIGIN:
+ to = mon->pid;
+ *multip = am_false;
+ if (is_atom(to)) {
+ /* Monitoring a name at node to */
+ ASSERT(is_node_name_atom(to));
+ dep = erts_sysname_to_connected_dist_entry(to);
+ ASSERT(dep != erts_this_dist_entry);
+ if (dep)
+ deref_de = 1;
+ } else {
+ ASSERT(is_pid(to));
+ dep = pid_dist_entry(to);
}
- dep = NULL;
- rp = erts_pid2proc_opt(c_p,
- ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_LINK,
- to,
- ERTS_PROC_LOCK_LINK,
- ERTS_P2P_FLG_ALLOW_OTHER_X);
- mon = erts_remove_monitor(&ERTS_P_MONITORS(c_p), ref);
+ if (dep != erts_this_dist_entry) {
+ res = remote_demonitor(c_p, dep, ref, to);
+ /* remote_demonitor() unlocks link lock on c_p */
+ unlock_link = 0;
+ }
+ else { /* Local monitor */
+ if (deref_de) {
+ deref_de = 0;
+ erts_deref_dist_entry(dep);
+ }
+ dep = NULL;
+ rp = erts_pid2proc_opt(c_p,
+ ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_LINK,
+ to,
+ ERTS_PROC_LOCK_LINK,
+ ERTS_P2P_FLG_ALLOW_OTHER_X);
+ mon = erts_remove_monitor(&ERTS_P_MONITORS(c_p), ref);
#ifndef ERTS_SMP
- ASSERT(mon);
+ ASSERT(mon);
#else
- if (!mon)
- res = ERTS_DEMONITOR_FALSE;
- else
+ if (!mon)
+ res = ERTS_DEMONITOR_FALSE;
+ else
#endif
- {
- res = ERTS_DEMONITOR_TRUE;
- erts_destroy_monitor(mon);
- }
- if (rp) {
- ErtsMonitor *rmon;
- rmon = erts_remove_monitor(&ERTS_P_MONITORS(rp), ref);
- if (rp != c_p)
- erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
- if (rmon != NULL)
- erts_destroy_monitor(rmon);
- }
- else {
- ERTS_SMP_ASSERT_IS_NOT_EXITING(c_p);
- }
+ {
+ res = ERTS_DEMONITOR_TRUE;
+ erts_destroy_monitor(mon);
+ }
+ if (rp) {
+ ErtsMonitor *rmon;
+ rmon = erts_remove_monitor(&ERTS_P_MONITORS(rp), ref);
+ if (rp != c_p)
+ erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
+ if (rmon != NULL)
+ erts_destroy_monitor(rmon);
+ }
+ else {
+ ERTS_SMP_ASSERT_IS_NOT_EXITING(c_p);
+ }
+ }
+ break;
+ default:
+ res = ERTS_DEMONITOR_BADARG;
+ *multip = am_false;
+ break;
}
-
done:
if (unlock_link)
@@ -490,7 +508,8 @@ static int demonitor(Process *c_p, Eterm ref)
BIF_RETTYPE demonitor_1(BIF_ALIST_1)
{
- switch (demonitor(BIF_P, BIF_ARG_1)) {
+ Eterm multi;
+ switch (demonitor(BIF_P, BIF_ARG_1, &multi)) {
case ERTS_DEMONITOR_FALSE:
case ERTS_DEMONITOR_TRUE:
BIF_RET(am_true);
@@ -508,6 +527,7 @@ BIF_RETTYPE demonitor_1(BIF_ALIST_1)
BIF_RETTYPE demonitor_2(BIF_ALIST_2)
{
Eterm res = am_true;
+ Eterm multi = am_false;
int info = 0;
int flush = 0;
Eterm list = BIF_ARG_2;
@@ -530,13 +550,18 @@ BIF_RETTYPE demonitor_2(BIF_ALIST_2)
if (is_not_nil(list))
goto badarg;
- switch (demonitor(BIF_P, BIF_ARG_1)) {
+ switch (demonitor(BIF_P, BIF_ARG_1, &multi)) {
case ERTS_DEMONITOR_FALSE:
if (info)
res = am_false;
- if (flush)
- BIF_TRAP2(flush_monitor_message_trap, BIF_P, BIF_ARG_1, res);
+ if (flush) {
+ flush_messages:
+ BIF_TRAP3(flush_monitor_messages_trap, BIF_P,
+ BIF_ARG_1, multi, res);
+ }
case ERTS_DEMONITOR_TRUE:
+ if (multi == am_true && flush)
+ goto flush_messages;
BIF_RET(res);
case ERTS_DEMONITOR_YIELD_TRUE:
ERTS_BIF_YIELD_RETURN(BIF_P, am_true);
@@ -587,22 +612,16 @@ erts_queue_monitor_message(Process *p,
ref_copy = copy_struct(ref, ref_size, &hp, ohp);
tup = TUPLE5(hp, am_DOWN, ref_copy, type, item_copy, reason_copy);
- erts_queue_message(p, p_locksp, bp, tup, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(p, p_locksp, bp, tup, NIL);
}
static BIF_RETTYPE
-local_pid_monitor(Process *p, Eterm target)
+local_pid_monitor(Process *p, Eterm target, Eterm mon_ref, int boolean)
{
BIF_RETTYPE ret;
- Eterm mon_ref;
Process *rp;
ErtsProcLocks p_locks = ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_LINK;
- mon_ref = erts_make_ref(p);
ERTS_BIF_PREP_RET(ret, mon_ref);
if (target == p->common.id) {
return ret;
@@ -615,12 +634,18 @@ local_pid_monitor(Process *p, Eterm target)
if (!rp) {
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_LINK);
p_locks &= ~ERTS_PROC_LOCK_LINK;
- erts_queue_monitor_message(p, &p_locks,
- mon_ref, am_process, target, am_noproc);
+ if (boolean)
+ ret = am_false;
+ else
+ erts_queue_monitor_message(p, &p_locks,
+ mon_ref, am_process, target, am_noproc);
}
else {
ASSERT(rp != p);
+ if (boolean)
+ ret = am_true;
+
erts_add_monitor(&ERTS_P_MONITORS(p), MON_ORIGIN, mon_ref, target, NIL);
erts_add_monitor(&ERTS_P_MONITORS(rp), MON_TARGET, mon_ref, p->common.id, NIL);
@@ -744,13 +769,28 @@ BIF_RETTYPE monitor_2(BIF_ALIST_2)
int deref_de = 0;
/* Only process monitors are implemented */
- if (BIF_ARG_1 != am_process) {
+ switch (BIF_ARG_1) {
+ case am_time_offset: {
+ Eterm ref;
+ if (BIF_ARG_2 != am_clock_service)
+ goto error;
+ ref = erts_make_ref(BIF_P);
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_LINK);
+ erts_add_monitor(&ERTS_P_MONITORS(BIF_P), MON_TIME_OFFSET,
+ ref, am_clock_service, NIL);
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);
+ erts_monitor_time_offset(BIF_P->common.id, ref);
+ BIF_RET(ref);
+ }
+ case am_process:
+ break;
+ default:
goto error;
}
if (is_internal_pid(target)) {
local_pid:
- ret = local_pid_monitor(BIF_P, target);
+ ret = local_pid_monitor(BIF_P, target, erts_make_ref(BIF_P), 0);
} else if (is_external_pid(target)) {
dep = external_pid_dist_entry(target);
if (dep == erts_this_dist_entry)
@@ -793,7 +833,6 @@ BIF_RETTYPE monitor_2(BIF_ALIST_2)
return ret;
}
-
/**********************************************************************/
/* this is a combination of the spawn and link BIFs */
@@ -1566,14 +1605,17 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2)
* true. For more info, see implementation of
* erts_send_exit_signal().
*/
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCKS_XSIG_SEND);
if (trap_exit)
state = erts_smp_atomic32_read_bor_mb(&BIF_P->state,
ERTS_PSFLG_TRAP_EXIT);
else
state = erts_smp_atomic32_read_band_mb(&BIF_P->state,
~ERTS_PSFLG_TRAP_EXIT);
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCKS_XSIG_SEND);
+
#ifdef ERTS_SMP
- if (ERTS_PROC_PENDING_EXIT(BIF_P)) {
+ if (state & ERTS_PSFLG_PENDING_EXIT) {
erts_handle_pending_exit(BIF_P, ERTS_PROC_LOCK_MAIN);
ERTS_BIF_EXITED(BIF_P);
}
@@ -1777,6 +1819,8 @@ BIF_RETTYPE whereis_1(BIF_ALIST_1)
* erlang:'!'/2
*/
+HIPE_WRAPPER_BIF_DISABLE_GC(ebif_bang, 2)
+
BIF_RETTYPE
ebif_bang_2(BIF_ALIST_2)
{
@@ -1795,34 +1839,36 @@ ebif_bang_2(BIF_ALIST_2)
#define SEND_USER_ERROR (-5)
#define SEND_INTERNAL_ERROR (-6)
#define SEND_AWAIT_RESULT (-7)
+#define SEND_YIELD_CONTINUE (-8)
+
-Sint do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp);
+Sint do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext*);
static Sint remote_send(Process *p, DistEntry *dep,
- Eterm to, Eterm full_to, Eterm msg, int suspend)
+ Eterm to, Eterm full_to, Eterm msg,
+ ErtsSendContext* ctx)
{
Sint res;
int code;
- ErtsDSigData dsd;
ASSERT(is_atom(to) || is_external_pid(to));
- code = erts_dsig_prepare(&dsd, dep, p, ERTS_DSP_NO_LOCK, !suspend);
+ code = erts_dsig_prepare(&ctx->dsd, dep, p, ERTS_DSP_NO_LOCK, !ctx->suspend);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
case ERTS_DSIG_PREP_NOT_CONNECTED:
res = SEND_TRAP;
break;
case ERTS_DSIG_PREP_WOULD_SUSPEND:
- ASSERT(!suspend);
+ ASSERT(!ctx->suspend);
res = SEND_YIELD;
break;
case ERTS_DSIG_PREP_CONNECTED: {
if (is_atom(to))
- code = erts_dsig_send_reg_msg(&dsd, to, msg);
+ code = erts_dsig_send_reg_msg(to, msg, ctx);
else
- code = erts_dsig_send_msg(&dsd, to, msg);
+ code = erts_dsig_send_msg(to, msg, ctx);
/*
* Note that reductions have been bumped on calling
* process by erts_dsig_send_reg_msg() or
@@ -1830,6 +1876,8 @@ static Sint remote_send(Process *p, DistEntry *dep,
*/
if (code == ERTS_DSIG_SEND_YIELD)
res = SEND_YIELD_RETURN;
+ else if (code == ERTS_DSIG_SEND_CONTINUE)
+ res = SEND_YIELD_CONTINUE;
else
res = 0;
break;
@@ -1850,7 +1898,8 @@ static Sint remote_send(Process *p, DistEntry *dep,
}
Sint
-do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
+do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext* ctx)
+{
Eterm portid;
Port *pt;
Process* rp;
@@ -1869,7 +1918,6 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
} else if (is_external_pid(to)) {
dep = external_pid_dist_entry(to);
if(dep == erts_this_dist_entry) {
-#if DEBUG
erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
erts_dsprintf(dsbufp,
"Discarding message %T from %T to %T in an old "
@@ -1880,10 +1928,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
external_pid_creation(to),
erts_this_node->creation);
erts_send_error_to_logger(p->group_leader, dsbufp);
-#endif
return 0;
}
- return remote_send(p, dep, to, to, msg, suspend);
+ return remote_send(p, dep, to, to, msg, ctx);
} else if (is_atom(to)) {
Eterm id = erts_whereis_name_to_id(p, to);
@@ -1914,7 +1961,6 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
} else if (is_external_port(to)
&& (external_port_dist_entry(to)
== erts_this_dist_entry)) {
-#if DEBUG
erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
erts_dsprintf(dsbufp,
"Discarding message %T from %T to %T in an old "
@@ -1925,7 +1971,6 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
external_port_creation(to),
erts_this_node->creation);
erts_send_error_to_logger(p->group_leader, dsbufp);
-#endif
return 0;
} else if (is_internal_port(to)) {
int ret_val;
@@ -1940,7 +1985,7 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
ret_val = 0;
if (pt) {
- int ps_flags = suspend ? 0 : ERTS_PORT_SIG_FLG_NOSUSPEND;
+ int ps_flags = ctx->suspend ? 0 : ERTS_PORT_SIG_FLG_NOSUSPEND;
*refp = NIL;
switch (erts_port_command(p, ps_flags, pt, msg, refp)) {
@@ -1949,12 +1994,12 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
return SEND_USER_ERROR;
case ERTS_PORT_OP_BUSY:
/* Nothing has been sent */
- if (suspend)
+ if (ctx->suspend)
erts_suspend(p, ERTS_PROC_LOCK_MAIN, pt);
return SEND_YIELD;
case ERTS_PORT_OP_BUSY_SCHEDULED:
/* Message was sent */
- if (suspend) {
+ if (ctx->suspend) {
erts_suspend(p, ERTS_PROC_LOCK_MAIN, pt);
ret_val = SEND_YIELD_RETURN;
break;
@@ -2034,9 +2079,14 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
return 0;
}
- ret = remote_send(p, dep, tp[1], to, msg, suspend);
- if (dep)
- erts_deref_dist_entry(dep);
+ ret = remote_send(p, dep, tp[1], to, msg, ctx);
+ if (ret != SEND_YIELD_CONTINUE) {
+ if (dep) {
+ erts_deref_dist_entry(dep);
+ }
+ } else {
+ ctx->dep_to_deref = dep;
+ }
return ret;
} else {
if (IS_TRACED(p)) /* XXX Is this really neccessary ??? */
@@ -2067,9 +2117,11 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
}
}
+HIPE_WRAPPER_BIF_DISABLE_GC(send, 3)
BIF_RETTYPE send_3(BIF_ALIST_3)
{
+ BIF_RETTYPE retval;
Eterm ref;
Process *p = BIF_P;
Eterm to = BIF_ARG_1;
@@ -2077,34 +2129,44 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
Eterm opts = BIF_ARG_3;
int connect = !0;
- int suspend = !0;
Eterm l = opts;
Sint result;
-
+ DeclareTypedTmpHeap(ErtsSendContext, ctx, BIF_P);
+ UseTmpHeap(sizeof(ErtsSendContext)/sizeof(Eterm), BIF_P);
+
+ ctx->suspend = !0;
+ ctx->dep_to_deref = NULL;
+ ctx->return_term = am_ok;
+ ctx->dss.reds = (Sint) (ERTS_BIF_REDS_LEFT(p) * TERM_TO_BINARY_LOOP_FACTOR);
+ ctx->dss.phase = ERTS_DSIG_SEND_PHASE_INIT;
+
while (is_list(l)) {
if (CAR(list_val(l)) == am_noconnect) {
connect = 0;
} else if (CAR(list_val(l)) == am_nosuspend) {
- suspend = 0;
+ ctx->suspend = 0;
} else {
- BIF_ERROR(p, BADARG);
+ ERTS_BIF_PREP_ERROR(retval, p, BADARG);
+ goto done;
}
l = CDR(list_val(l));
}
if(!is_nil(l)) {
- BIF_ERROR(p, BADARG);
+ ERTS_BIF_PREP_ERROR(retval, p, BADARG);
+ goto done;
}
#ifdef DEBUG
ref = NIL;
#endif
- result = do_send(p, to, msg, suspend, &ref);
+ result = do_send(p, to, msg, &ref, ctx);
if (result > 0) {
ERTS_VBUMP_REDS(p, result);
if (ERTS_IS_PROC_OUT_OF_REDS(p))
goto yield_return;
- BIF_RET(am_ok);
+ ERTS_BIF_PREP_RET(retval, am_ok);
+ goto done;
}
switch (result) {
@@ -2112,68 +2174,127 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
/* May need to yield even though we do not bump reds here... */
if (ERTS_IS_PROC_OUT_OF_REDS(p))
goto yield_return;
- BIF_RET(am_ok);
+ ERTS_BIF_PREP_RET(retval, am_ok);
break;
case SEND_TRAP:
if (connect) {
- BIF_TRAP3(dsend3_trap, p, to, msg, opts);
+ ERTS_BIF_PREP_TRAP3(retval, dsend3_trap, p, to, msg, opts);
} else {
- BIF_RET(am_noconnect);
+ ERTS_BIF_PREP_RET(retval, am_noconnect);
}
break;
case SEND_YIELD:
- if (suspend) {
- ERTS_BIF_YIELD3(bif_export[BIF_send_3], p, to, msg, opts);
+ if (ctx->suspend) {
+ ERTS_BIF_PREP_YIELD3(retval,
+ bif_export[BIF_send_3], p, to, msg, opts);
} else {
- BIF_RET(am_nosuspend);
+ ERTS_BIF_PREP_RET(retval, am_nosuspend);
}
break;
case SEND_YIELD_RETURN:
- if (!suspend)
- BIF_RET(am_nosuspend);
+ if (!ctx->suspend) {
+ ERTS_BIF_PREP_RET(retval, am_nosuspend);
+ break;
+ }
yield_return:
- ERTS_BIF_YIELD_RETURN(p, am_ok);
+ ERTS_BIF_PREP_YIELD_RETURN(retval, p, am_ok);
+ break;
case SEND_AWAIT_RESULT:
ASSERT(is_internal_ref(ref));
- BIF_TRAP3(await_port_send_result_trap, p, ref, am_nosuspend, am_ok);
+ ERTS_BIF_PREP_TRAP3(retval, await_port_send_result_trap, p, ref, am_nosuspend, am_ok);
+ break;
case SEND_BADARG:
- BIF_ERROR(p, BADARG);
+ ERTS_BIF_PREP_ERROR(retval, p, BADARG);
break;
case SEND_USER_ERROR:
- BIF_ERROR(p, EXC_ERROR);
+ ERTS_BIF_PREP_ERROR(retval, p, EXC_ERROR);
break;
case SEND_INTERNAL_ERROR:
- BIF_ERROR(p, EXC_INTERNAL_ERROR);
+ ERTS_BIF_PREP_ERROR(retval, p, EXC_INTERNAL_ERROR);
+ break;
+ case SEND_YIELD_CONTINUE:
+ BUMP_ALL_REDS(p);
+ erts_set_gc_state(p, 0);
+ ERTS_BIF_PREP_TRAP1(retval, &dsend_continue_trap_export, p,
+ erts_dsend_export_trap_context(p, ctx));
break;
default:
- ASSERT(! "Illegal send result");
+ erts_exit(ERTS_ABORT_EXIT, "send_3 invalid result %d\n", (int)result);
break;
}
- ASSERT(! "Can not arrive here");
- BIF_ERROR(p, BADARG);
+
+done:
+ UnUseTmpHeap(sizeof(ErtsSendContext)/sizeof(Eterm), BIF_P);
+ return retval;
}
+HIPE_WRAPPER_BIF_DISABLE_GC(send, 2)
+
BIF_RETTYPE send_2(BIF_ALIST_2)
{
return erl_send(BIF_P, BIF_ARG_1, BIF_ARG_2);
}
+static BIF_RETTYPE dsend_continue_trap_1(BIF_ALIST_1)
+{
+ Binary* bin = ((ProcBin*) binary_val(BIF_ARG_1))->val;
+ ErtsSendContext* ctx = (ErtsSendContext*) ERTS_MAGIC_BIN_DATA(bin);
+ Sint initial_reds = (Sint) (ERTS_BIF_REDS_LEFT(BIF_P) * TERM_TO_BINARY_LOOP_FACTOR);
+ int result;
+
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == erts_dsend_context_dtor);
+
+ ctx->dss.reds = initial_reds;
+ result = erts_dsig_send(&ctx->dsd, &ctx->dss);
+
+ switch (result) {
+ case ERTS_DSIG_SEND_OK:
+ erts_set_gc_state(BIF_P, 1);
+ BIF_RET(ctx->return_term);
+ break;
+ case ERTS_DSIG_SEND_YIELD: /*SEND_YIELD_RETURN*/
+ erts_set_gc_state(BIF_P, 1);
+ if (!ctx->suspend)
+ BIF_RET(am_nosuspend);
+ ERTS_BIF_YIELD_RETURN(BIF_P, ctx->return_term);
+
+ case ERTS_DSIG_SEND_CONTINUE: { /*SEND_YIELD_CONTINUE*/
+ BUMP_ALL_REDS(BIF_P);
+ BIF_TRAP1(&dsend_continue_trap_export, BIF_P, BIF_ARG_1);
+ }
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "dsend_continue_trap invalid result %d\n", (int)result);
+ break;
+ }
+ ASSERT(! "Can not arrive here");
+ BIF_ERROR(BIF_P, BADARG);
+}
+
Eterm erl_send(Process *p, Eterm to, Eterm msg)
{
+ Eterm retval;
Eterm ref;
Sint result;
+ DeclareTypedTmpHeap(ErtsSendContext, ctx, p);
+ UseTmpHeap(sizeof(ErtsSendContext)/sizeof(Eterm), p);
#ifdef DEBUG
ref = NIL;
#endif
+ ctx->suspend = !0;
+ ctx->dep_to_deref = NULL;
+ ctx->return_term = msg;
+ ctx->dss.reds = (Sint) (ERTS_BIF_REDS_LEFT(p) * TERM_TO_BINARY_LOOP_FACTOR);
+ ctx->dss.phase = ERTS_DSIG_SEND_PHASE_INIT;
- result = do_send(p, to, msg, !0, &ref);
+ result = do_send(p, to, msg, &ref, ctx);
if (result > 0) {
ERTS_VBUMP_REDS(p, result);
if (ERTS_IS_PROC_OUT_OF_REDS(p))
goto yield_return;
- BIF_RET(msg);
+ ERTS_BIF_PREP_RET(retval, msg);
+ goto done;
}
switch (result) {
@@ -2181,35 +2302,46 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg)
/* May need to yield even though we do not bump reds here... */
if (ERTS_IS_PROC_OUT_OF_REDS(p))
goto yield_return;
- BIF_RET(msg);
+ ERTS_BIF_PREP_RET(retval, msg);
break;
case SEND_TRAP:
- BIF_TRAP2(dsend2_trap, p, to, msg);
+ ERTS_BIF_PREP_TRAP2(retval, dsend2_trap, p, to, msg);
break;
case SEND_YIELD:
- ERTS_BIF_YIELD2(bif_export[BIF_send_2], p, to, msg);
+ ERTS_BIF_PREP_YIELD2(retval, bif_export[BIF_send_2], p, to, msg);
break;
case SEND_YIELD_RETURN:
yield_return:
- ERTS_BIF_YIELD_RETURN(p, msg);
+ ERTS_BIF_PREP_YIELD_RETURN(retval, p, msg);
+ break;
case SEND_AWAIT_RESULT:
ASSERT(is_internal_ref(ref));
- BIF_TRAP3(await_port_send_result_trap, p, ref, msg, msg);
+ ERTS_BIF_PREP_TRAP3(retval,
+ await_port_send_result_trap, p, ref, msg, msg);
+ break;
case SEND_BADARG:
- BIF_ERROR(p, BADARG);
+ ERTS_BIF_PREP_ERROR(retval, p, BADARG);
break;
case SEND_USER_ERROR:
- BIF_ERROR(p, EXC_ERROR);
+ ERTS_BIF_PREP_ERROR(retval, p, EXC_ERROR);
break;
case SEND_INTERNAL_ERROR:
- BIF_ERROR(p, EXC_INTERNAL_ERROR);
+ ERTS_BIF_PREP_ERROR(retval, p, EXC_INTERNAL_ERROR);
+ break;
+ case SEND_YIELD_CONTINUE:
+ BUMP_ALL_REDS(p);
+ erts_set_gc_state(p, 0);
+ ERTS_BIF_PREP_TRAP1(retval, &dsend_continue_trap_export, p,
+ erts_dsend_export_trap_context(p, ctx));
break;
default:
- ASSERT(! "Illegal send result");
+ erts_exit(ERTS_ABORT_EXIT, "invalid send result %d\n", (int)result);
break;
}
- ASSERT(! "Can not arrive here");
- BIF_ERROR(p, BADARG);
+
+done:
+ UnUseTmpHeap(sizeof(ErtsSendContext)/sizeof(Eterm), p);
+ return retval;
}
/**********************************************************************/
@@ -3448,91 +3580,6 @@ BIF_RETTYPE self_0(BIF_ALIST_0)
/**********************************************************************/
-/*
- New representation of refs in R9, see erl_term.h
-
- In the first data word, only the usual 18 bits are used. Ordinarily,
- in "long refs" all words are used (in other words, practically never
- wrap around), but for compatibility with older nodes, "short refs"
- exist. Short refs come into being by being converted from the old
- external format for refs (tag REFERENCE_EXT). Short refs are
- converted back to the old external format.
-
- When converting a long ref to the external format in the case of
- preparing for sending to an older node, the ref is truncated by only
- using the first word (with 18 significant bits), and using the old tag
- REFERENCE_EXT.
-
- When comparing refs or different size, only the parts up to the length
- of the shorter operand are used. This has the desirable effect that a
- long ref sent to an old node and back will be treated as equal to
- the original, although some of the bits have been lost.
-
- The hash value for a ref always considers only the first word, since
- in the above scenario, the original and the copy should have the same
- hash value.
-*/
-
-static Uint32 reference0; /* Initialized in erts_init_bif */
-static Uint32 reference1;
-static Uint32 reference2;
-static erts_smp_spinlock_t make_ref_lock;
-static erts_smp_mtx_t ports_snapshot_mtx;
-erts_smp_atomic_t erts_dead_ports_ptr; /* To store dying ports during snapshot */
-
-void
-erts_make_ref_in_array(Uint32 ref[ERTS_MAX_REF_NUMBERS])
-{
- erts_smp_spin_lock(&make_ref_lock);
-
- reference0++;
- if (reference0 >= MAX_REFERENCE) {
- reference0 = 0;
- reference1++;
- if (reference1 == 0) {
- reference2++;
- }
- }
-
- ref[0] = reference0;
- ref[1] = reference1;
- ref[2] = reference2;
-
- erts_smp_spin_unlock(&make_ref_lock);
-}
-
-Eterm erts_make_ref_in_buffer(Eterm buffer[REF_THING_SIZE])
-{
- Eterm* hp = buffer;
- Uint32 ref[ERTS_MAX_REF_NUMBERS];
-
- erts_make_ref_in_array(ref);
- write_ref_thing(hp, ref[0], ref[1], ref[2]);
- return make_internal_ref(hp);
-}
-
-Eterm erts_make_ref(Process *p)
-{
- Eterm* hp;
- Uint32 ref[ERTS_MAX_REF_NUMBERS];
-
- ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));
-
- hp = HAlloc(p, REF_THING_SIZE);
-
- erts_make_ref_in_array(ref);
- write_ref_thing(hp, ref[0], ref[1], ref[2]);
-
- return make_internal_ref(hp);
-}
-
-BIF_RETTYPE make_ref_0(BIF_ALIST_0)
-{
- return erts_make_ref(BIF_P);
-}
-
-/**********************************************************************/
-
/* return the time of day */
BIF_RETTYPE time_0(BIF_ALIST_0)
@@ -3839,7 +3886,7 @@ BIF_RETTYPE erts_debug_display_1(BIF_ALIST_1)
erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(64);
pres = erts_dsprintf(dsbufp, "%.*T\n", INT_MAX, BIF_ARG_1);
if (pres < 0)
- erl_exit(1, "Failed to convert term to string: %d (%s)\n",
+ erts_exit(ERTS_ERROR_EXIT, "Failed to convert term to string: %d (%s)\n",
-pres, erl_errno_id(-pres));
hp = HAlloc(BIF_P, 2*dsbufp->str_len); /* we need length * 2 heap words */
res = buf_to_intlist(&hp, dsbufp->str, dsbufp->str_len, NIL);
@@ -3861,7 +3908,7 @@ BIF_RETTYPE display_string_1(BIF_ALIST_1)
}
str = (char *) erts_alloc(ERTS_ALC_T_TMP, sizeof(char)*(len + 1));
if (intlist_to_buf(string, str, len) != len)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error\n", __FILE__, __LINE__);
str[len] = '\0';
erts_fprintf(stderr, "%s", str);
erts_free(ERTS_ALC_T_TMP, (void *) str);
@@ -3881,7 +3928,7 @@ BIF_RETTYPE display_nl_0(BIF_ALIST_0)
BIF_RETTYPE halt_0(BIF_ALIST_0)
{
VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt()\n"));
- erl_halt(0);
+ erts_halt(0);
ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined);
}
@@ -3894,17 +3941,18 @@ static char halt_msg[HALT_MSG_SIZE];
/* ARGSUSED */
BIF_RETTYPE halt_1(BIF_ALIST_1)
{
- Sint code;
+ Uint code;
- if (is_small(BIF_ARG_1) && (code = signed_val(BIF_ARG_1)) >= 0) {
+ if (term_to_Uint_mask(BIF_ARG_1, &code)) {
+ int pos_int_code = (int) (code & INT_MAX);
VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%T)\n", BIF_ARG_1));
- erl_halt((int)(- code));
+ erts_halt(pos_int_code);
ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined);
}
else if (ERTS_IS_ATOM_STR("abort", BIF_ARG_1)) {
VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%T)\n", BIF_ARG_1));
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erl_exit(ERTS_ABORT_EXIT, "");
+ erts_exit(ERTS_ABORT_EXIT, "");
}
else if (is_string(BIF_ARG_1) || BIF_ARG_1 == NIL) {
int i;
@@ -3915,11 +3963,11 @@ BIF_RETTYPE halt_1(BIF_ALIST_1)
halt_msg[i] = '\0';
VERBOSE(DEBUG_SYSTEM,("System halted by BIF halt(%T)\n", BIF_ARG_1));
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erl_exit(ERTS_DUMP_EXIT, "%s\n", halt_msg);
+ erts_exit(ERTS_DUMP_EXIT, "%s\n", halt_msg);
}
else
goto error;
- return NIL; /* Pedantic (lint does not know about erl_exit) */
+ return NIL; /* Pedantic (lint does not know about erts_exit) */
error:
BIF_ERROR(BIF_P, BADARG);
}
@@ -3930,7 +3978,7 @@ BIF_RETTYPE halt_1(BIF_ALIST_1)
/* ARGSUSED */
BIF_RETTYPE halt_2(BIF_ALIST_2)
{
- Sint code;
+ Uint code;
Eterm optlist = BIF_ARG_2;
int flush = 1;
@@ -3957,23 +4005,24 @@ BIF_RETTYPE halt_2(BIF_ALIST_2)
if (is_not_nil(optlist))
goto error;
- if (is_small(BIF_ARG_1) && (code = signed_val(BIF_ARG_1)) >= 0) {
+ if (term_to_Uint_mask(BIF_ARG_1, &code)) {
+ int pos_int_code = (int) (code & INT_MAX);
VERBOSE(DEBUG_SYSTEM,
("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2));
if (flush) {
- erl_halt((int)(- code));
+ erts_halt(pos_int_code);
ERTS_BIF_YIELD1(bif_export[BIF_halt_1], BIF_P, am_undefined);
}
else {
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erl_exit((int)(- code), "");
+ erts_exit(pos_int_code, "");
}
}
else if (ERTS_IS_ATOM_STR("abort", BIF_ARG_1)) {
VERBOSE(DEBUG_SYSTEM,
("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2));
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erl_exit(ERTS_ABORT_EXIT, "");
+ erts_exit(ERTS_ABORT_EXIT, "");
}
else if (is_string(BIF_ARG_1) || BIF_ARG_1 == NIL) {
int i;
@@ -3985,11 +4034,11 @@ BIF_RETTYPE halt_2(BIF_ALIST_2)
VERBOSE(DEBUG_SYSTEM,
("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2));
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erl_exit(ERTS_DUMP_EXIT, "%s\n", halt_msg);
+ erts_exit(ERTS_DUMP_EXIT, "%s\n", halt_msg);
}
else
goto error;
- return NIL; /* Pedantic (lint does not know about erl_exit) */
+ return NIL; /* Pedantic (lint does not know about erts_exit) */
error:
BIF_ERROR(BIF_P, BADARG);
}
@@ -3998,16 +4047,19 @@ BIF_RETTYPE halt_2(BIF_ALIST_2)
BIF_RETTYPE function_exported_3(BIF_ALIST_3)
{
+ int arity;
if (is_not_atom(BIF_ARG_1) ||
is_not_atom(BIF_ARG_2) ||
is_not_small(BIF_ARG_3)) {
BIF_ERROR(BIF_P, BADARG);
}
- if (erts_find_function(BIF_ARG_1, BIF_ARG_2, signed_val(BIF_ARG_3),
- erts_active_code_ix()) == NULL) {
- BIF_RET(am_false);
+ arity = signed_val(BIF_ARG_3);
+ if (erts_find_function(BIF_ARG_1, BIF_ARG_2, arity,
+ erts_active_code_ix()) != NULL ||
+ erts_is_builtin(BIF_ARG_1, BIF_ARG_2, arity)) {
+ BIF_RET(am_true);
}
- BIF_RET(am_true);
+ BIF_RET(am_false);
}
/**********************************************************************/
@@ -4042,7 +4094,7 @@ term2list_dsprintf(Process *p, Eterm term)
erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(64);
pres = erts_dsprintf(dsbufp, "%T", term);
if (pres < 0)
- erl_exit(1, "Failed to convert term to list: %d (%s)\n",
+ erts_exit(ERTS_ERROR_EXIT, "Failed to convert term to list: %d (%s)\n",
-pres, erl_errno_id(-pres));
hp = HAlloc(p, 2*dsbufp->str_len); /* we need length * 2 heap words */
res = buf_to_intlist(&hp, dsbufp->str, dsbufp->str_len, NIL);
@@ -4184,6 +4236,7 @@ BIF_RETTYPE list_to_pid_1(BIF_ALIST_1)
goto bad;
enp = erts_find_or_insert_node(dep->sysname, dep->creation);
+ ASSERT(enp != erts_this_node);
etp = (ExternalThing *) HAlloc(BIF_P, EXTERNAL_THING_HEAD_SIZE + 1);
etp->header = make_external_pid_header(1);
@@ -4510,6 +4563,28 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
break;
}
#endif
+ } else if (BIF_ARG_1 == am_time_offset
+ && ERTS_IS_ATOM_STR("finalize", BIF_ARG_2)) {
+ ErtsTimeOffsetState res;
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ res = erts_finalize_time_offset();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ switch (res) {
+ case ERTS_TIME_OFFSET_PRELIMINARY: {
+ DECL_AM(preliminary);
+ BIF_RET(AM_preliminary);
+ }
+ case ERTS_TIME_OFFSET_FINAL: {
+ DECL_AM(final);
+ BIF_RET(AM_final);
+ }
+ case ERTS_TIME_OFFSET_VOLATILE: {
+ DECL_AM(volatile);
+ BIF_RET(AM_volatile);
+ }
+ default:
+ ERTS_INTERNAL_ERROR("Unknown state");
+ }
} else if (ERTS_IS_ATOM_STR("scheduling_statistics", BIF_ARG_1)) {
int what;
if (ERTS_IS_ATOM_STR("disable", BIF_ARG_2))
@@ -4797,11 +4872,6 @@ void erts_init_trap_export(Export* ep, Eterm m, Eterm f, Uint a,
void erts_init_bif(void)
{
- reference0 = 0;
- reference1 = 0;
- reference2 = 0;
-
- erts_smp_spinlock_init(&make_ref_lock, "make_ref");
erts_smp_mtx_init(&ports_snapshot_mtx, "ports_snapshot");
erts_smp_atomic_init_nob(&erts_dead_ports_ptr, (erts_aint_t) NULL);
@@ -4818,9 +4888,21 @@ void erts_init_bif(void)
#endif
, &bif_return_trap);
- flush_monitor_message_trap = erts_export_put(am_erlang,
- am_flush_monitor_message,
- 2);
+ erts_await_result = erts_export_put(am_erts_internal,
+ am_await_result,
+ 1);
+
+ erts_init_trap_export(&dsend_continue_trap_export,
+ am_erts_internal, am_dsend_continue_trap, 1,
+ dsend_continue_trap_1);
+
+ flush_monitor_messages_trap = erts_export_put(am_erts_internal,
+ am_flush_monitor_messages,
+ 3);
+
+ erts_convert_time_unit_trap = erts_export_put(am_erlang,
+ am_convert_time_unit,
+ 3);
set_cpu_topology_trap = erts_export_put(am_erlang,
am_set_cpu_topology,
diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h
index 72c55ccb55..c6ed60376a 100644
--- a/erts/emulator/beam/bif.h
+++ b/erts/emulator/beam/bif.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,7 +21,9 @@
#ifndef __BIF_H__
#define __BIF_H__
+extern Export *erts_await_result;
extern Export* erts_format_cpu_topology_trap;
+extern Export *erts_convert_time_unit_trap;
#define BIF_RETTYPE Eterm
@@ -30,10 +33,12 @@ extern Export* erts_format_cpu_topology_trap;
#define BIF_ALIST_1 Process* A__p, Eterm* BIF__ARGS
#define BIF_ALIST_2 Process* A__p, Eterm* BIF__ARGS
#define BIF_ALIST_3 Process* A__p, Eterm* BIF__ARGS
+#define BIF_ALIST_4 Process* A__p, Eterm* BIF__ARGS
#define BIF_ARG_1 (BIF__ARGS[0])
#define BIF_ARG_2 (BIF__ARGS[1])
#define BIF_ARG_3 (BIF__ARGS[2])
+#define BIF_ARG_4 (BIF__ARGS[3])
#define ERTS_IS_PROC_OUT_OF_REDS(p) \
((p)->fcalls > 0 \
@@ -465,6 +470,8 @@ erts_bif_prep_await_proc_exit_apply_trap(Process *c_p,
Eterm args[],
int nargs);
+#ifdef ERL_WANT_HIPE_BIF_WRAPPER__
+
#ifndef HIPE
#define HIPE_WRAPPER_BIF_DISABLE_GC(BIF_NAME, ARITY)
@@ -509,6 +516,7 @@ BIF_RETTYPE hipe_wrapper_ ## BIF_NAME ## _ ## ARITY (Process* c_p, \
#endif
+#endif /* ERL_WANT_HIPE_BIF_WRAPPER__ */
#include "erl_bif_table.h"
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index e68b8e6274..3177d5dae7 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -92,6 +93,8 @@ bif erlang:loaded/0
bif erlang:localtime/0
bif erlang:localtime_to_universaltime/2
bif erlang:make_ref/0
+bif erlang:unique_integer/0
+bif erlang:unique_integer/1
bif erlang:md5/1
bif erlang:md5_init/0
bif erlang:md5_update/2
@@ -104,6 +107,13 @@ ubif erlang:node/1
ubif erlang:node/0
bif erlang:nodes/1
bif erlang:now/0
+bif erlang:monotonic_time/0
+bif erlang:monotonic_time/1
+bif erlang:system_time/0
+bif erlang:system_time/1
+bif erlang:time_offset/0
+bif erlang:time_offset/1
+bif erlang:timestamp/0
bif erlang:open_port/2
@@ -157,6 +167,14 @@ bif erts_internal:request_system_task/3
bif erts_internal:check_process_code/2
bif erts_internal:map_to_tuple_keys/1
+bif erts_internal:map_type/1
+bif erts_internal:map_hashmap_children/1
+
+bif erts_internal:time_unit/0
+
+bif erts_internal:is_system_process/1
+
+bif erts_internal:system_check/1
# inet_db support
bif erlang:port_set_data/2
@@ -194,15 +212,20 @@ bif math:erf/1
bif math:erfc/1
bif math:exp/1
bif math:log/1
+bif math:log2/1
bif math:log10/1
bif math:sqrt/1
bif math:atan2/2
bif math:pow/2
bif erlang:start_timer/3
+bif erlang:start_timer/4
bif erlang:send_after/3
+bif erlang:send_after/4
bif erlang:cancel_timer/1
+bif erlang:cancel_timer/2
bif erlang:read_timer/1
+bif erlang:read_timer/2
bif erlang:make_tuple/2
bif erlang:append_element/2
@@ -347,6 +370,8 @@ bif os:getenv/0
bif os:getenv/1
bif os:getpid/0
bif os:timestamp/0
+bif os:system_time/0
+bif os:system_time/1
#
# Bifs in the erl_ddll module (the module actually does not exist)
@@ -578,7 +603,7 @@ bif io:printable_range/0
bif os:unsetenv/1
#
-# New in R17A
+# New in 17.0
#
bif re:inspect/2
@@ -600,10 +625,21 @@ bif maps:values/1
bif erts_internal:cmp_term/2
+bif ets:take/2
+
#
-# New in 17.1.
+# New in 17.1
#
+
bif erlang:fun_info_mfa/1
+
+# New in 18.0
+#
+
+bif erlang:get_keys/0
+bif ets:update_counter/4
+bif erts_debug:map_info/1
+
#
# Obsolete
#
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index d1e46e3063..87d3be2b0f 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -1577,6 +1578,46 @@ Eterm erts_sint64_to_big(Sint64 x, Eterm **hpp)
return make_big(hp);
}
+Eterm
+erts_uint64_array_to_big(Uint **hpp, int neg, int len, Uint64 *array)
+{
+ Uint *headerp;
+ int i, pot_digits, digits;
+
+ headerp = *hpp;
+
+ pot_digits = digits = 0;
+ for (i = 0; i < len; i++) {
+#if defined(ARCH_32) || HALFWORD_HEAP
+ Uint low_val = array[i] & ((Uint) 0xffffffff);
+ Uint high_val = (array[i] >> 32) & ((Uint) 0xffffffff);
+ BIG_DIGIT(headerp, pot_digits) = low_val;
+ pot_digits++;
+ if (low_val)
+ digits = pot_digits;
+ BIG_DIGIT(headerp, pot_digits) = high_val;
+ pot_digits++;
+ if (high_val)
+ digits = pot_digits;
+#else
+ Uint val = array[i];
+ BIG_DIGIT(headerp, pot_digits) = val;
+ pot_digits++;
+ if (val)
+ digits = pot_digits;
+#endif
+ }
+
+ if (neg)
+ *headerp = make_neg_bignum_header(digits);
+ else
+ *headerp = make_pos_bignum_header(digits);
+
+ *hpp = headerp + 1 + digits;
+
+ return make_big(headerp);
+}
+
/*
** Convert a bignum to a double float
*/
@@ -1987,6 +2028,32 @@ term_to_Uint(Eterm term, Uint *up)
}
}
+/* same as term_to_Uint()
+ but also accept larger bignums by masking
+ */
+int
+term_to_Uint_mask(Eterm term, Uint *up)
+{
+ if (is_small(term)) {
+ Sint i = signed_val(term);
+ if (i < 0) {
+ *up = BADARG;
+ return 0;
+ }
+ *up = (Uint) i;
+ return 1;
+ } else if (is_big(term) && !big_sign(term)) {
+ ErtsDigit* xr = big_v(term);
+
+ ERTS_CT_ASSERT(sizeof(ErtsDigit) == sizeof(Uint));
+ *up = (Uint)*xr; /* just pick first word */
+ return 1;
+ } else {
+ *up = BADARG;
+ return 0;
+ }
+}
+
int
term_to_UWord(Eterm term, UWord *up)
{
@@ -2577,6 +2644,9 @@ Eterm erts_chars_to_integer(Process *BIF_P, char *bytes,
size--;
}
+ if (size == 0)
+ goto bytebuf_to_integer_1_error;
+
if (size < SMALL_DIGITS && base <= 10) {
/* *
* Take shortcut if we know that all chars are '0' < b < '9' and
diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h
index da31876d75..3c1f1e6b23 100644
--- a/erts/emulator/beam/big.h
+++ b/erts/emulator/beam/big.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -85,6 +86,7 @@ typedef Uint dsize_t; /* Vector size type */
/* The heap size needed for a bignum */
#define BIG_NEED_SIZE(x) ((x) + 1)
+#define BIG_NEED_FOR_BITS(bits) BIG_NEED_SIZE(((bits)-1)/D_EXP + 1)
#define BIG_UINT_HEAP_SIZE (1 + 1) /* always, since sizeof(Uint) <= sizeof(Eterm) */
@@ -104,6 +106,9 @@ typedef Uint dsize_t; /* Vector size type */
: ERTS_UINT64_BIG_HEAP_SIZE__((X) >= 0 ? (X) : -(Uint64)(X)))
#define ERTS_UINT64_HEAP_SIZE(X) \
(IS_USMALL(0, (X)) ? 0 : ERTS_UINT64_BIG_HEAP_SIZE__((X)))
+#define ERTS_MAX_SINT64_HEAP_SIZE (1 + 2)
+#define ERTS_MAX_UINT64_HEAP_SIZE (1 + 2)
+#define ERTS_UINT64_ARRAY_TO_BIG_MAX_HEAP_SZ(LEN) (2*(LEN)+1)
#else
@@ -111,6 +116,9 @@ typedef Uint dsize_t; /* Vector size type */
(IS_SSMALL((X)) ? 0 : (1 + 1))
#define ERTS_UINT64_HEAP_SIZE(X) \
(IS_USMALL(0, (X)) ? 0 : (1 + 1))
+#define ERTS_MAX_SINT64_HEAP_SIZE (1 + 1)
+#define ERTS_MAX_UINT64_HEAP_SIZE (1 + 1)
+#define ERTS_UINT64_ARRAY_TO_BIG_MAX_HEAP_SZ(LEN) ((LEN)+1)
#endif
@@ -153,9 +161,11 @@ Eterm bytes_to_big(byte*, dsize_t, int, Eterm*);
byte* big_to_bytes(Eterm, byte*);
int term_to_Uint(Eterm, Uint*);
+int term_to_Uint_mask(Eterm, Uint*);
int term_to_UWord(Eterm, UWord*);
int term_to_Sint(Eterm, Sint*);
#if HAVE_INT64
+Eterm erts_uint64_array_to_big(Uint **, int, int, Uint64 *);
int term_to_Uint64(Eterm, Uint64*);
int term_to_Sint64(Eterm, Sint64*);
#endif
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index f50d484576..247c8f1122 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -26,7 +27,9 @@
#include "global.h"
#include "erl_process.h"
#include "error.h"
+#define ERL_WANT_HIPE_BIF_WRAPPER__
#include "bif.h"
+#undef ERL_WANT_HIPE_BIF_WRAPPER__
#include "big.h"
#include "erl_binary.h"
#include "erl_bits.h"
@@ -44,7 +47,7 @@ erts_init_binary(void)
if ((((UWord) &((Binary *) 0)->orig_bytes[0]) % ((UWord) 8)) != 0) {
/* I assume that any compiler should be able to optimize this
away. If not, this test is not very expensive... */
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Internal error: Address of orig_bytes[0] of a Binary"
" is *not* 8-byte aligned\n");
}
@@ -83,8 +86,6 @@ new_binary(Process *p, byte *buf, Uint len)
* Allocate the binary struct itself.
*/
bptr = erts_bin_nrml_alloc(len);
- bptr->flags = 0;
- bptr->orig_size = len;
erts_refc_init(&bptr->refc, 1);
if (buf != NULL) {
sys_memcpy(bptr->orig_bytes, buf, len);
@@ -122,8 +123,6 @@ Eterm erts_new_mso_binary(Process *p, byte *buf, int len)
* Allocate the binary struct itself.
*/
bptr = erts_bin_nrml_alloc(len);
- bptr->flags = 0;
- bptr->orig_size = len;
erts_refc_init(&bptr->refc, 1);
if (buf != NULL) {
sys_memcpy(bptr->orig_bytes, buf, len);
@@ -177,7 +176,6 @@ erts_realloc_binary(Eterm bin, size_t size)
} else { /* REFC */
ProcBin* pb = (ProcBin *) bval;
Binary* newbin = erts_bin_realloc(pb->val, size);
- newbin->orig_size = size;
pb->val = newbin;
pb->size = size;
pb->bytes = (byte*) newbin->orig_bytes;
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 2cddfe2800..0ddf7f4e6d 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -36,7 +37,7 @@
#include "atom.h"
#include "beam_load.h"
#include "erl_instrument.h"
-#include "erl_bif_timer.h"
+#include "erl_hl_timer.h"
#include "erl_thr_progress.h"
/* Forward declarations -- should really appear somewhere else */
@@ -103,12 +104,12 @@ process_killer(void)
erts_printf("(k)ill (n)ext (r)eturn:\n");
while(1) {
if ((j = sys_get_key(0)) <= 0)
- erl_exit(0, "");
+ erts_exit(0, "");
switch(j) {
case 'k': {
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
erts_aint32_t state;
- erts_smp_proc_inc_refc(rp);
+ erts_proc_inc_refc(rp);
erts_smp_proc_lock(rp, rp_locks);
state = erts_smp_atomic32_read_acqb(&rp->state);
if (state & (ERTS_PSFLG_FREE
@@ -131,7 +132,7 @@ process_killer(void)
0);
}
erts_smp_proc_unlock(rp, rp_locks);
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
}
case 'n': br = 1; break;
case 'r': return;
@@ -209,25 +210,12 @@ print_process_info(int to, void *to_arg, Process *p)
erts_print(to, to_arg, "State: ");
state = erts_smp_atomic32_read_acqb(&p->state);
- if (state & ERTS_PSFLG_FREE)
- erts_print(to, to_arg, "Non Existing\n"); /* Should never happen */
- else if (state & ERTS_PSFLG_EXITING)
- erts_print(to, to_arg, "Exiting\n");
- else if (state & ERTS_PSFLG_GC) {
- garbing = 1;
- running = 1;
- erts_print(to, to_arg, "Garbing\n");
- }
- else if (state & ERTS_PSFLG_SUSPENDED)
- erts_print(to, to_arg, "Suspended\n");
- else if (state & ERTS_PSFLG_RUNNING) {
- running = 1;
- erts_print(to, to_arg, "Running\n");
- }
- else if (state & ERTS_PSFLG_ACTIVE)
- erts_print(to, to_arg, "Scheduled\n");
- else
- erts_print(to, to_arg, "Waiting\n");
+ erts_dump_process_state(to, to_arg, state);
+ if (state & ERTS_PSFLG_GC) {
+ garbing = 1;
+ running = 1;
+ } else if (state & ERTS_PSFLG_RUNNING)
+ running = 1;
/*
* If the process is registered as a global process, display the
@@ -240,9 +228,9 @@ print_process_info(int to, void *to_arg, Process *p)
* Display the initial function name
*/
erts_print(to, to_arg, "Spawned as: %T:%T/%bpu\n",
- p->initial[INITIAL_MOD],
- p->initial[INITIAL_FUN],
- p->initial[INITIAL_ARI]);
+ p->u.initial[INITIAL_MOD],
+ p->u.initial[INITIAL_FUN],
+ p->u.initial[INITIAL_ARI]);
if (p->current != NULL) {
if (running) {
@@ -255,7 +243,6 @@ print_process_info(int to, void *to_arg, Process *p)
p->current[1],
p->current[2]);
}
- erts_print(to, to_arg, "Run queue: %d\n", erts_get_runq_proc(p)->ix);
erts_print(to, to_arg, "Spawned by: %T\n", p->parent);
approx_started = (time_t) p->approx_started;
@@ -351,6 +338,10 @@ print_process_info(int to, void *to_arg, Process *p)
#endif
erts_stack_dump(to, to_arg, p);
}
+
+ /* Display all states */
+ erts_print(to, to_arg, "Internal State: ");
+ erts_dump_extended_process_state(to, to_arg, state);
}
static void
@@ -502,7 +493,7 @@ do_break(void)
halt immediately if break is called */
mode = erts_read_env("ERL_CONSOLE_MODE");
if (mode && strcmp(mode, "window") != 0)
- erl_exit(0, "");
+ erts_exit(0, "");
erts_free_read_env(mode);
#endif /* __WIN32__ */
@@ -512,7 +503,7 @@ do_break(void)
while (1) {
if ((i = sys_get_key(0)) <= 0)
- erl_exit(0, "");
+ erts_exit(0, "");
switch (i) {
case 'q':
case 'a':
@@ -522,9 +513,9 @@ do_break(void)
* The usual reason for a read error is Ctrl-C. Treat this as
* 'a' to avoid infinite loop.
*/
- erl_exit(0, "");
+ erts_exit(0, "");
case 'A': /* Halt generating crash dump */
- erl_exit(1, "Crash dump requested by user");
+ erts_exit(ERTS_ERROR_EXIT, "Crash dump requested by user");
case 'c':
return;
case 'p':
@@ -545,7 +536,9 @@ do_break(void)
erts_printf("Erlang (%s) emulator version "
ERLANG_VERSION "\n",
EMULATOR);
+#if ERTS_SAVED_COMPILE_TIME
erts_printf("Compiled on " ERLANG_COMPILE_DATE "\n");
+#endif
return;
case 'd':
distribution_info(ERTS_PRINT_STDOUT, NULL);
@@ -680,27 +673,39 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
char* dumpname;
int secs;
int env_erl_crash_dump_seconds_set = 1;
+ int i;
if (ERTS_SOMEONE_IS_CRASH_DUMPING)
return;
#ifdef ERTS_SMP
+ /* Order all managed threads to block, this has to be done
+ first to guarantee that this is the only thread to generate
+ crash dump. */
+ erts_thr_progress_fatal_error_block(&tpd_buf);
+
+#ifdef ERTS_THR_HAVE_SIG_FUNCS
/*
- * Wait for all managed threads to block. If all threads haven't blocked
- * after a minute, we go anyway and hope for the best...
- *
- * We do not release system again. We expect an exit() or abort() after
- * dump has been written.
+ * We suspend all scheduler threads so that we can dump some
+ * data about the currently running processes and scheduler data.
+ * We have to be very very careful when doing this as the schedulers
+ * could be anywhere.
*/
- erts_thr_progress_fatal_error_block(60000, &tpd_buf);
- /* Either worked or not... */
+ for (i = 0; i < erts_no_schedulers; i++) {
+ erts_tid_t tid = ERTS_SCHEDULER_IX(i)->tid;
+ if (!erts_equal_tids(tid,erts_thr_self()))
+ sys_thr_suspend(tid);
+ }
+
+#endif
/* Allow us to pass certain places without locking... */
erts_smp_atomic32_set_mb(&erts_writing_erl_crash_dump, 1);
erts_smp_tsd_set(erts_is_crash_dumping_key, (void *) 1);
-#else
+
+#else /* !ERTS_SMP */
erts_writing_erl_crash_dump = 1;
-#endif
+#endif /* ERTS_SMP */
envsz = sizeof(env);
/* ERL_CRASH_DUMP_SECONDS not set
@@ -753,11 +758,12 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
dumpname = "erl_crash.dump";
else
dumpname = &dumpnamebuf[0];
+
+ erts_fprintf(stderr,"\nCrash dump is being written to: %s...", dumpname);
fd = open(dumpname,O_WRONLY | O_CREAT | O_TRUNC,0640);
- if (fd < 0)
+ if (fd < 0)
return; /* Can't create the crash dump, skip it */
-
time(&now);
erts_fdprintf(fd, "=erl_crash_dump:0.3\n%s", ctime(&now));
@@ -770,10 +776,77 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
}
erts_fdprintf(fd, "System version: ");
erts_print_system_version(fd, NULL, NULL);
+#if ERTS_SAVED_COMPILE_TIME
erts_fdprintf(fd, "%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());
+
+#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_get_scheduler_data()->no);
+ } else {
+ if (!erts_thr_getname(erts_thr_self(), dumpnamebuf, MAXPATHLEN))
+ erts_fdprintf(fd, "Calling Thread: %s\n", dumpnamebuf);
+ else
+ erts_fdprintf(fd, "Calling Thread: %p\n", erts_thr_self());
+ }
+#else
+ erts_fdprintf(fd, "Calling Thread: scheduler:1\n");
+#endif
+
+#if defined(ERTS_HAVE_TRY_CATCH)
+
+ /*
+ * erts_print_scheduler_info is not guaranteed to be safe to call
+ * here for all schedulers as we may have suspended a scheduler
+ * in the middle of updating the STACK_TOP and STACK_START
+ * variables and thus when scanning the stack we could get
+ * segmentation faults. We protect against this very unlikely
+ * scenario by using the ERTS_SYS_TRY_CATCH.
+ */
+ 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"));
+ }
+#endif
+
+#ifdef ERTS_SMP
+
+#if defined(ERTS_THR_HAVE_SIG_FUNCS)
+
+ /* We resume all schedulers so that we are in a known safe state
+ when we write the rest of the crash dump */
+ for (i = 0; i < erts_no_schedulers; i++) {
+ erts_tid_t tid = ERTS_SCHEDULER_IX(i)->tid;
+ if (!erts_equal_tids(tid,erts_thr_self()))
+ sys_thr_resume(tid);
+ }
+#endif
+
+ /*
+ * Wait for all managed threads to block. If all threads haven't blocked
+ * after a minute, we go anyway and hope for the best...
+ *
+ * We do not release system again. We expect an exit() or abort() after
+ * dump has been written.
+ */
+ erts_thr_progress_fatal_error_wait(60000);
+ /* Either worked or not... */
+#endif
+
+#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));
+ }
+#endif
+
info(fd, NULL); /* General system info */
if (erts_ptab_initialized(&erts_proc))
process_info(fd, NULL); /* Info about each process and port */
@@ -803,7 +876,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
erts_fdprintf(fd, "=end\n");
close(fd);
- erts_fprintf(stderr,"\nCrash dump was written to: %s\n", dumpname);
+ erts_fprintf(stderr,"done\n");
}
void
diff --git a/erts/emulator/beam/code_ix.c b/erts/emulator/beam/code_ix.c
index 4344558348..209d008d18 100644
--- a/erts/emulator/beam/code_ix.c
+++ b/erts/emulator/beam/code_ix.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -130,7 +131,7 @@ int erts_try_seize_code_write_permission(Process* c_p)
ASSERT(code_writing_process != c_p);
qitem = erts_alloc(ERTS_ALC_T_CODE_IX_LOCK_Q, sizeof(*qitem));
qitem->p = c_p;
- erts_smp_proc_inc_refc(c_p);
+ erts_proc_inc_refc(c_p);
qitem->next = code_write_queue;
code_write_queue = qitem;
erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL);
@@ -151,7 +152,7 @@ void erts_release_code_write_permission(void)
}
erts_smp_proc_unlock(qitem->p, ERTS_PROC_LOCK_STATUS);
code_write_queue = qitem->next;
- erts_smp_proc_dec_refc(qitem->p);
+ erts_proc_dec_refc(qitem->p);
erts_free(ERTS_ALC_T_CODE_IX_LOCK_Q, qitem);
}
code_writing_process = NULL;
diff --git a/erts/emulator/beam/code_ix.h b/erts/emulator/beam/code_ix.h
index 16ad900228..5f00b409ef 100644
--- a/erts/emulator/beam/code_ix.h
+++ b/erts/emulator/beam/code_ix.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c
index 50548850eb..64be43edb4 100644
--- a/erts/emulator/beam/copy.c
+++ b/erts/emulator/beam/copy.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -21,6 +22,8 @@
# include "config.h"
#endif
+#define ERL_WANT_GC_INTERNALS__
+
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
@@ -32,7 +35,7 @@
#include "erl_bits.h"
#include "dtrace-wrapper.h"
-static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap*);
+static void move_one_frag(Eterm** hpp, ErlHeapFragment*, ErlOffHeap*);
/*
* Copy object "obj" to process p.
@@ -56,7 +59,7 @@ copy_object(Eterm obj, Process* to)
res = copy_struct(obj, size, &hp, &to->off_heap);
#ifdef DEBUG
if (eq(obj, res) == 0) {
- erl_exit(ERTS_ABORT_EXIT, "copy not equal to source\n");
+ erts_exit(ERTS_ABORT_EXIT, "copy not equal to source\n");
}
#endif
return res;
@@ -125,6 +128,52 @@ Uint size_object(Eterm obj)
obj = *bptr;
break;
}
+ case MAP_SUBTAG:
+ switch (MAP_HEADER_TYPE(hdr)) {
+ case MAP_HEADER_TAG_FLATMAP_HEAD :
+ {
+ Uint n;
+ flatmap_t *mp;
+ mp = (flatmap_t*)flatmap_val_rel(obj,base);
+ ptr = (Eterm *)mp;
+ n = flatmap_get_size(mp) + 1;
+ sum += n + 2;
+ ptr += 2; /* hdr + size words */
+ while (n--) {
+ obj = *ptr++;
+ if (!IS_CONST(obj)) {
+ ESTACK_PUSH(s, obj);
+ }
+ }
+ goto pop_next;
+ }
+ case MAP_HEADER_TAG_HAMT_HEAD_BITMAP :
+ case MAP_HEADER_TAG_HAMT_HEAD_ARRAY :
+ case MAP_HEADER_TAG_HAMT_NODE_BITMAP :
+ {
+ Eterm *head;
+ Uint sz;
+ head = hashmap_val_rel(obj, base);
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ sum += 1 + sz + header_arity(hdr);
+ head += 1 + header_arity(hdr);
+
+ if (sz == 0) {
+ goto pop_next;
+ }
+ while(sz-- > 1) {
+ obj = head[sz];
+ if (!IS_CONST(obj)) {
+ ESTACK_PUSH(s, obj);
+ }
+ }
+ obj = head[0];
+ }
+ break;
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "size_object: bad hashmap type %d\n", MAP_HEADER_TYPE(hdr));
+ }
+ break;
case SUB_BINARY_SUBTAG:
{
Eterm real_bin;
@@ -152,26 +201,8 @@ Uint size_object(Eterm obj)
goto pop_next;
}
break;
- case MAP_SUBTAG:
- {
- Uint n;
- map_t *mp;
- mp = (map_t*)map_val_rel(obj,base);
- ptr = (Eterm *)mp;
- n = map_get_size(mp) + 1;
- sum += n + 2;
- ptr += 2; /* hdr + size words */
- while (n--) {
- obj = *ptr++;
- if (!IS_CONST(obj)) {
- ESTACK_PUSH(s, obj);
- }
- }
- goto pop_next;
- }
- break;
- case BIN_MATCHSTATE_SUBTAG:
- erl_exit(ERTS_ABORT_EXIT,
+ case BIN_MATCHSTATE_SUBTAG:
+ erts_exit(ERTS_ABORT_EXIT,
"size_object: matchstate term not allowed");
default:
sum += thing_arityval(hdr) + 1;
@@ -188,7 +219,7 @@ Uint size_object(Eterm obj)
obj = ESTACK_POP(s);
break;
default:
- erl_exit(ERTS_ABORT_EXIT, "size_object: bad tag for %#x\n", obj);
+ erts_exit(ERTS_ABORT_EXIT, "size_object: bad tag for %#x\n", obj);
}
}
}
@@ -241,7 +272,7 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
goto L_copy_list;
case TAG_PRIMARY_BOXED: argp = &res; goto L_copy_boxed;
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s, line %d: Internal error in copy_struct: 0x%08x\n",
__FILE__, __LINE__,obj);
}
@@ -300,7 +331,7 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
case TAG_PRIMARY_IMMED1: *tailp = obj; goto L_copy;
case TAG_PRIMARY_BOXED: argp = tailp; goto L_copy_boxed;
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s, line %d: Internal error in copy_struct: 0x%08x\n",
__FILE__, __LINE__,obj);
}
@@ -338,15 +369,6 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
}
}
break;
- case MAP_SUBTAG:
- {
- i = map_get_size(objp) + 3;
- *argp = make_map_rel(htop, dst_base);
- while (i--) {
- *htop++ = *objp++;
- }
- }
- break;
case REFC_BINARY_SUBTAG:
{
ProcBin* pb;
@@ -457,7 +479,7 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
{
ExternalThing *etp = (ExternalThing *) htop;
- i = thing_arityval(hdr) + 1;
+ i = thing_arityval(hdr) + 1;
tp = htop;
while (i--) {
@@ -471,8 +493,30 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
*argp = make_external_rel(tp, dst_base);
}
break;
+ case MAP_SUBTAG:
+ tp = htop;
+ switch (MAP_HEADER_TYPE(hdr)) {
+ case MAP_HEADER_TAG_FLATMAP_HEAD :
+ i = flatmap_get_size(objp) + 3;
+ *argp = make_flatmap_rel(htop, dst_base);
+ while (i--) {
+ *htop++ = *objp++;
+ }
+ break;
+ case MAP_HEADER_TAG_HAMT_HEAD_BITMAP :
+ case MAP_HEADER_TAG_HAMT_HEAD_ARRAY :
+ *htop++ = *objp++;
+ case MAP_HEADER_TAG_HAMT_NODE_BITMAP :
+ i = 1 + hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ while (i--) { *htop++ = *objp++; }
+ *argp = make_hashmap_rel(tp, dst_base);
+ break;
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "copy_struct: bad hashmap type %d\n", MAP_HEADER_TYPE(hdr));
+ }
+ break;
case BIN_MATCHSTATE_SUBTAG:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"copy_struct: matchstate term not allowed");
default:
i = thing_arityval(hdr)+1;
@@ -496,13 +540,13 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
#ifdef DEBUG
if (htop != hbot)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Internal error in copy_struct() when copying %T:"
" htop=%p != hbot=%p (sz=%beu)\n",
org_obj, htop, hbot, org_sz);
#else
if (htop > hbot) {
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Internal error in copy_struct(): htop, hbot overrun\n");
}
#endif
@@ -565,11 +609,6 @@ Eterm copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
erts_refc_inc(&funp->fe->refc, 2);
}
goto off_heap_common;
-
- case MAP_SUBTAG:
- *hp++ = *tp++;
- sz--;
- break;
case EXTERNAL_PID_SUBTAG:
case EXTERNAL_PORT_SUBTAG:
case EXTERNAL_REF_SUBTAG:
@@ -605,7 +644,6 @@ Eterm copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
}
}
*hpp = hp;
-
return res;
}
@@ -624,8 +662,7 @@ void move_multi_frags(Eterm** hpp, ErlOffHeap* off_heap, ErlHeapFragment* first,
unsigned i;
for (bp=first; bp!=NULL; bp=bp->next) {
- move_one_frag(hpp, bp->mem, bp->used_size, off_heap);
- OH_OVERHEAD(off_heap, bp->off_heap.overhead);
+ move_one_frag(hpp, bp, off_heap);
}
hp_end = *hpp;
for (hp=hp_start; hp<hp_end; ++hp) {
@@ -661,10 +698,10 @@ void move_multi_frags(Eterm** hpp, ErlOffHeap* off_heap, ErlHeapFragment* first,
}
static void
-move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap)
+move_one_frag(Eterm** hpp, ErlHeapFragment* frag, ErlOffHeap* off_heap)
{
- Eterm* ptr = src;
- Eterm* end = ptr + src_sz;
+ Eterm* ptr = frag->mem;
+ Eterm* end = ptr + frag->used_size;
Eterm dummy_ref;
Eterm* hp = *hpp;
@@ -695,5 +732,7 @@ move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap)
}
}
*hpp = hp;
+ OH_OVERHEAD(off_heap, frag->off_heap.overhead);
+ frag->off_heap.first = NULL;
}
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index ec07ddcd9c..787241b960 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2013. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -44,6 +45,8 @@
#include "erl_thr_progress.h"
#include "dtrace-wrapper.h"
+#define DIST_CTL_DEFAULT_SIZE 64
+
/* Turn this on to get printouts of all distribution messages
* which go on the line
*/
@@ -65,9 +68,13 @@ static void bw(byte *buf, ErlDrvSizeT sz)
static void
dist_msg_dbg(ErtsDistExternal *edep, char *what, byte *buf, int sz)
{
+ ErtsHeapFactory factory;
+ DeclareTmpHeapNoproc(ctl_default,DIST_CTL_DEFAULT_SIZE);
+ Eterm* ctl = ctl_default;
byte *extp = edep->extp;
Eterm msg;
- Sint size = erts_decode_dist_ext_size(edep);
+ Sint ctl_len;
+ Sint size = ctl_len = erts_decode_dist_ext_size(edep);
if (size < 0) {
erts_fprintf(stderr,
"DIST MSG DEBUG: erts_decode_dist_ext_size(%s) failed:\n",
@@ -75,10 +82,9 @@ dist_msg_dbg(ErtsDistExternal *edep, char *what, byte *buf, int sz)
bw(buf, sz);
}
else {
- Eterm *hp;
ErlHeapFragment *mbuf = new_message_buffer(size);
- hp = mbuf->mem;
- msg = erts_decode_dist_ext(&hp, &mbuf->off_heap, edep);
+ erts_factory_static_init(&factory, ctl, ctl_len, &mbuf->off_heap);
+ msg = erts_decode_dist_ext(&factory, edep);
if (is_value(msg))
erts_fprintf(stderr, " %s: %T\n", what, msg);
else {
@@ -119,7 +125,7 @@ Export* dmonitor_p_trap = NULL;
/* forward declarations */
static void clear_dist_entry(DistEntry*);
-static int dsig_send(ErtsDSigData *, Eterm, Eterm, int);
+static int dsig_send_ctl(ErtsDSigData* dsdp, Eterm ctl, int force_busy);
static void send_nodes_mon_msgs(Process *, Eterm, Eterm, Eterm, Eterm);
static void init_nodes_monitors(void);
@@ -388,11 +394,7 @@ static void doit_node_link_net_exits(ErtsLink *lnk, void *vnecp)
Eterm tup;
Eterm *hp = erts_alloc_message_heap(3,&bp,&ohp,rp,&rp_locks);
tup = TUPLE2(hp, am_nodedown, name);
- erts_queue_message(rp, &rp_locks, bp, tup, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, tup, NIL);
}
erts_smp_proc_unlock(rp, rp_locks);
}
@@ -622,9 +624,7 @@ alloc_dist_obuf(Uint size)
ErtsDistOutputBuf *obuf;
Uint obuf_size = sizeof(ErtsDistOutputBuf)+sizeof(byte)*(size-1);
Binary *bin = erts_bin_drv_alloc(obuf_size);
- bin->flags = BIN_FLAG_DRV;
erts_refc_init(&bin->refc, 1);
- bin->orig_size = (SWord) obuf_size;
obuf = (ErtsDistOutputBuf *) &bin->orig_bytes[0];
#ifdef DEBUG
obuf->dbg_pattern = ERTS_DIST_OUTPUT_BUF_DBG_PATTERN;
@@ -709,6 +709,55 @@ static void clear_dist_entry(DistEntry *dep)
}
}
+void erts_dsend_context_dtor(Binary* ctx_bin)
+{
+ ErtsSendContext* ctx = ERTS_MAGIC_BIN_DATA(ctx_bin);
+ switch (ctx->dss.phase) {
+ case ERTS_DSIG_SEND_PHASE_MSG_SIZE:
+ DESTROY_SAVED_WSTACK(&ctx->dss.u.sc.wstack);
+ break;
+ case ERTS_DSIG_SEND_PHASE_MSG_ENCODE:
+ DESTROY_SAVED_WSTACK(&ctx->dss.u.ec.wstack);
+ break;
+ default:;
+ }
+ if (ctx->dss.phase >= ERTS_DSIG_SEND_PHASE_ALLOC && ctx->dss.obuf) {
+ free_dist_obuf(ctx->dss.obuf);
+ }
+ if (ctx->dep_to_deref)
+ erts_deref_dist_entry(ctx->dep_to_deref);
+}
+
+Eterm erts_dsend_export_trap_context(Process* p, ErtsSendContext* ctx)
+{
+ struct exported_ctx {
+ ErtsSendContext ctx;
+ ErtsAtomCacheMap acm;
+ };
+ Binary* ctx_bin = erts_create_magic_binary(sizeof(struct exported_ctx),
+ erts_dsend_context_dtor);
+ struct exported_ctx* dst = ERTS_MAGIC_BIN_DATA(ctx_bin);
+ Uint ctl_size = !HALFWORD_HEAP ? 0 : (arityval(ctx->ctl_heap[0]) + 1);
+ Eterm* hp = HAlloc(p, ctl_size + PROC_BIN_SIZE);
+
+ sys_memcpy(&dst->ctx, ctx, sizeof(ErtsSendContext));
+ ASSERT(ctx->dss.ctl == make_tuple(ctx->ctl_heap));
+#if !HALFWORD_HEAP
+ dst->ctx.dss.ctl = make_tuple(dst->ctx.ctl_heap);
+#else
+ /* Must put control tuple in low mem */
+ sys_memcpy(hp, ctx->ctl_heap, ctl_size*sizeof(Eterm));
+ dst->ctx.dss.ctl = make_tuple(hp);
+ hp += ctl_size;
+#endif
+ if (ctx->dss.acmp) {
+ sys_memcpy(&dst->acm, ctx->dss.acmp, sizeof(ErtsAtomCacheMap));
+ dst->ctx.dss.acmp = &dst->acm;
+ }
+ return erts_mk_magic_binary_term(&hp, &MSO(p), ctx_bin);
+}
+
+
/*
* The erts_dsig_send_*() functions implemented below, sends asynchronous
* distributed signals to other Erlang nodes. Before sending a distributed
@@ -731,7 +780,7 @@ erts_dsig_send_link(ErtsDSigData *dsdp, Eterm local, Eterm remote)
int res;
UseTmpHeapNoproc(4);
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send_ctl(dsdp, ctl, 0);
UnUseTmpHeapNoproc(4);
return res;
}
@@ -744,7 +793,7 @@ erts_dsig_send_unlink(ErtsDSigData *dsdp, Eterm local, Eterm remote)
int res;
UseTmpHeapNoproc(4);
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send_ctl(dsdp, ctl, 0);
UnUseTmpHeapNoproc(4);
return res;
}
@@ -772,7 +821,7 @@ erts_dsig_send_m_exit(ErtsDSigData *dsdp, Eterm watcher, Eterm watched,
erts_smp_de_links_unlock(dsdp->dep);
#endif
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ res = dsig_send_ctl(dsdp, ctl, 1);
UnUseTmpHeapNoproc(6);
return res;
}
@@ -793,7 +842,7 @@ erts_dsig_send_monitor(ErtsDSigData *dsdp, Eterm watcher, Eterm watched,
make_small(DOP_MONITOR_P),
watcher, watched, ref);
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send_ctl(dsdp, ctl, 0);
UnUseTmpHeapNoproc(5);
return res;
}
@@ -815,18 +864,17 @@ erts_dsig_send_demonitor(ErtsDSigData *dsdp, Eterm watcher,
make_small(DOP_DEMONITOR_P),
watcher, watched, ref);
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, force);
+ res = dsig_send_ctl(dsdp, ctl, force);
UnUseTmpHeapNoproc(5);
return res;
}
int
-erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
+erts_dsig_send_msg(Eterm remote, Eterm message, ErtsSendContext* ctx)
{
Eterm ctl;
- DeclareTmpHeapNoproc(ctl_heap,5);
Eterm token = NIL;
- Process *sender = dsdp->proc;
+ Process *sender = ctx->dsd.proc;
int res;
#ifdef USE_VM_PROBES
Sint tok_label = 0;
@@ -838,8 +886,7 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
DTRACE_CHARBUF(receiver_name, 64);
#endif
- UseTmpHeapNoproc(5);
- if (SEQ_TRACE_TOKEN(sender) != NIL
+ if (SEQ_TRACE_TOKEN(sender) != NIL
#ifdef USE_VM_PROBES
&& SEQ_TRACE_TOKEN(sender) != am_have_dt_utag
#endif
@@ -852,7 +899,7 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
*node_name = *sender_name = *receiver_name = '\0';
if (DTRACE_ENABLED(message_send) || DTRACE_ENABLED(message_send_remote)) {
erts_snprintf(node_name, sizeof(DTRACE_CHARBUF_NAME(node_name)),
- "%T", dsdp->dep->sysname);
+ "%T", ctx->dsd.dep->sysname);
erts_snprintf(sender_name, sizeof(DTRACE_CHARBUF_NAME(sender_name)),
"%T", sender->common.id);
erts_snprintf(receiver_name, sizeof(DTRACE_CHARBUF_NAME(receiver_name)),
@@ -867,26 +914,28 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
#endif
if (token != NIL)
- ctl = TUPLE4(&ctl_heap[0],
+ ctl = TUPLE4(&ctx->ctl_heap[0],
make_small(DOP_SEND_TT), am_Cookie, remote, token);
else
- ctl = TUPLE3(&ctl_heap[0], make_small(DOP_SEND), am_Cookie, remote);
+ ctl = TUPLE3(&ctx->ctl_heap[0], make_small(DOP_SEND), am_Cookie, remote);
DTRACE6(message_send, sender_name, receiver_name,
msize, tok_label, tok_lastcnt, tok_serial);
DTRACE7(message_send_remote, sender_name, node_name, receiver_name,
msize, tok_label, tok_lastcnt, tok_serial);
- res = dsig_send(dsdp, ctl, message, 0);
- UnUseTmpHeapNoproc(5);
+ ctx->dss.ctl = ctl;
+ ctx->dss.msg = message;
+ ctx->dss.force_busy = 0;
+ res = erts_dsig_send(&ctx->dsd, &ctx->dss);
return res;
}
int
-erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
+erts_dsig_send_reg_msg(Eterm remote_name, Eterm message,
+ ErtsSendContext* ctx)
{
Eterm ctl;
- DeclareTmpHeapNoproc(ctl_heap,6);
Eterm token = NIL;
- Process *sender = dsdp->proc;
+ Process *sender = ctx->dsd.proc;
int res;
#ifdef USE_VM_PROBES
Sint tok_label = 0;
@@ -898,7 +947,6 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
DTRACE_CHARBUF(receiver_name, 128);
#endif
- UseTmpHeapNoproc(6);
if (SEQ_TRACE_TOKEN(sender) != NIL
#ifdef USE_VM_PROBES
&& SEQ_TRACE_TOKEN(sender) != am_have_dt_utag
@@ -912,7 +960,7 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
*node_name = *sender_name = *receiver_name = '\0';
if (DTRACE_ENABLED(message_send) || DTRACE_ENABLED(message_send_remote)) {
erts_snprintf(node_name, sizeof(DTRACE_CHARBUF_NAME(node_name)),
- "%T", dsdp->dep->sysname);
+ "%T", ctx->dsd.dep->sysname);
erts_snprintf(sender_name, sizeof(DTRACE_CHARBUF_NAME(sender_name)),
"%T", sender->common.id);
erts_snprintf(receiver_name, sizeof(DTRACE_CHARBUF_NAME(receiver_name)),
@@ -927,17 +975,19 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
#endif
if (token != NIL)
- ctl = TUPLE5(&ctl_heap[0], make_small(DOP_REG_SEND_TT),
+ ctl = TUPLE5(&ctx->ctl_heap[0], make_small(DOP_REG_SEND_TT),
sender->common.id, am_Cookie, remote_name, token);
else
- ctl = TUPLE4(&ctl_heap[0], make_small(DOP_REG_SEND),
+ ctl = TUPLE4(&ctx->ctl_heap[0], make_small(DOP_REG_SEND),
sender->common.id, am_Cookie, remote_name);
DTRACE6(message_send, sender_name, receiver_name,
msize, tok_label, tok_lastcnt, tok_serial);
DTRACE7(message_send_remote, sender_name, node_name, receiver_name,
msize, tok_label, tok_lastcnt, tok_serial);
- res = dsig_send(dsdp, ctl, message, 0);
- UnUseTmpHeapNoproc(6);
+ ctx->dss.ctl = ctl;
+ ctx->dss.msg = message;
+ ctx->dss.force_busy = 0;
+ res = erts_dsig_send(&ctx->dsd, &ctx->dss);
return res;
}
@@ -994,7 +1044,7 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote,
DTRACE7(process_exit_signal_remote, sender_name, node_name,
remote_name, reason_str, tok_label, tok_lastcnt, tok_serial);
/* forced, i.e ignore busy */
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ res = dsig_send_ctl(dsdp, ctl, 1);
UnUseTmpHeapNoproc(6);
return res;
}
@@ -1010,7 +1060,7 @@ erts_dsig_send_exit(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason)
ctl = TUPLE4(&ctl_heap[0],
make_small(DOP_EXIT), local, remote, reason);
/* forced, i.e ignore busy */
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ res = dsig_send_ctl(dsdp, ctl, 1);
UnUseTmpHeapNoproc(5);
return res;
}
@@ -1026,7 +1076,7 @@ erts_dsig_send_exit2(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason
ctl = TUPLE4(&ctl_heap[0],
make_small(DOP_EXIT2), local, remote, reason);
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send_ctl(dsdp, ctl, 0);
UnUseTmpHeapNoproc(5);
return res;
}
@@ -1043,7 +1093,7 @@ erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote)
ctl = TUPLE3(&ctl_heap[0],
make_small(DOP_GROUP_LEADER), leader, remote);
- res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send_ctl(dsdp, ctl, 0);
UnUseTmpHeapNoproc(4);
return res;
}
@@ -1091,7 +1141,6 @@ int erts_net_message(Port *prt,
byte *buf,
ErlDrvSizeT len)
{
-#define DIST_CTL_DEFAULT_SIZE 64
ErtsDistExternal ede;
byte *t;
Sint ctl_len;
@@ -1104,7 +1153,7 @@ int erts_net_message(Port *prt,
Process* rp;
DeclareTmpHeapNoproc(ctl_default,DIST_CTL_DEFAULT_SIZE);
Eterm* ctl = ctl_default;
- ErlOffHeap off_heap;
+ ErtsHeapFactory factory;
Eterm* hp;
Sint type;
Eterm token;
@@ -1118,9 +1167,6 @@ int erts_net_message(Port *prt,
#endif
UseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
- /* Thanks to Luke Gorrie */
- off_heap.first = NULL;
- off_heap.overhead = 0;
ERTS_SMP_CHK_NO_PROC_LOCKS;
@@ -1181,14 +1227,15 @@ int erts_net_message(Port *prt,
}
hp = ctl;
- arg = erts_decode_dist_ext(&hp, &off_heap, &ede);
+ erts_factory_tmp_init(&factory, ctl, ctl_len, ERTS_ALC_T_DCTRL_BUF);
+ arg = erts_decode_dist_ext(&factory, &ede);
if (is_non_value(arg)) {
#ifdef ERTS_DIST_MSG_DBG
- erts_fprintf(stderr, "DIST MSG DEBUG: erts_dist_ext_size(CTL) failed:\n");
+ erts_fprintf(stderr, "DIST MSG DEBUG: erts_decode_dist_ext(CTL) failed:\n");
bw(buf, orig_len);
#endif
PURIFY_MSG("data error");
- goto data_error;
+ goto decode_error;
}
ctl_len = t - buf;
@@ -1668,7 +1715,7 @@ int erts_net_message(Port *prt,
goto invalid_message;
}
- erts_cleanup_offheap(&off_heap);
+ erts_factory_close(&factory);
if (ctl != ctl_default) {
erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl);
}
@@ -1681,206 +1728,248 @@ int erts_net_message(Port *prt,
erts_dsprintf(dsbufp, "Invalid distribution message: %.200T", arg);
erts_send_error_to_logger_nogl(dsbufp);
}
- data_error:
+decode_error:
PURIFY_MSG("data error");
- erts_cleanup_offheap(&off_heap);
+ erts_factory_close(&factory);
if (ctl != ctl_default) {
erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl);
}
+data_error:
UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
erts_deliver_port_exit(prt, dep->cid, am_killed, 0);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return -1;
}
-static int
-dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy)
+static int dsig_send_ctl(ErtsDSigData* dsdp, Eterm ctl, int force_busy)
+{
+ struct erts_dsig_send_context ctx;
+ int ret;
+ ctx.ctl = ctl;
+ ctx.msg = THE_NON_VALUE;
+ ctx.force_busy = force_busy;
+ ctx.phase = ERTS_DSIG_SEND_PHASE_INIT;
+#ifdef DEBUG
+ ctx.reds = 1; /* provoke assert below (no reduction count without msg) */
+#endif
+ ret = erts_dsig_send(dsdp, &ctx);
+ ASSERT(ret != ERTS_DSIG_SEND_CONTINUE);
+ return ret;
+}
+
+int
+erts_dsig_send(ErtsDSigData *dsdp, struct erts_dsig_send_context* ctx)
{
+ int retval;
+ Sint initial_reds = ctx->reds;
Eterm cid;
- int suspended = 0;
- int resume = 0;
- Uint32 pass_through_size;
- Uint data_size, dhdr_ext_size;
- ErtsAtomCacheMap *acmp;
- ErtsDistOutputBuf *obuf;
- DistEntry *dep = dsdp->dep;
- Uint32 flags = dep->flags;
- Process *c_p = dsdp->proc;
- if (!c_p || dsdp->no_suspend)
- force_busy = 1;
+ while (1) {
+ switch (ctx->phase) {
+ case ERTS_DSIG_SEND_PHASE_INIT:
+ ctx->flags = dsdp->dep->flags;
+ ctx->c_p = dsdp->proc;
- ERTS_SMP_LC_ASSERT(!c_p
- || (ERTS_PROC_LOCK_MAIN
- == erts_proc_lc_my_proc_locks(c_p)));
+ if (!ctx->c_p || dsdp->no_suspend)
+ ctx->force_busy = 1;
- if (!erts_is_alive)
- return ERTS_DSIG_SEND_OK;
+ ERTS_SMP_LC_ASSERT(!ctx->c_p
+ || (ERTS_PROC_LOCK_MAIN
+ == erts_proc_lc_my_proc_locks(ctx->c_p)));
- if (flags & DFLAG_DIST_HDR_ATOM_CACHE) {
- acmp = erts_get_atom_cache_map(c_p);
- pass_through_size = 0;
- }
- else {
- acmp = NULL;
- pass_through_size = 1;
- }
+ if (!erts_is_alive)
+ return ERTS_DSIG_SEND_OK;
-#ifdef ERTS_DIST_MSG_DBG
- erts_fprintf(stderr, ">>%s CTL: %T\n", pass_through_size ? "P" : " ", ctl);
- if (is_value(msg))
- erts_fprintf(stderr, " MSG: %T\n", msg);
-#endif
+ if (ctx->flags & DFLAG_DIST_HDR_ATOM_CACHE) {
+ ctx->acmp = erts_get_atom_cache_map(ctx->c_p);
+ ctx->pass_through_size = 0;
+ }
+ else {
+ ctx->acmp = NULL;
+ ctx->pass_through_size = 1;
+ }
- data_size = pass_through_size;
- erts_reset_atom_cache_map(acmp);
- data_size += erts_encode_dist_ext_size(ctl, flags, acmp);
- if (is_value(msg))
- data_size += erts_encode_dist_ext_size(msg, flags, acmp);
- erts_finalize_atom_cache_map(acmp, flags);
+ #ifdef ERTS_DIST_MSG_DBG
+ erts_fprintf(stderr, ">>%s CTL: %T\n", ctx->pass_through_size ? "P" : " ", ctx->ctl);
+ if (is_value(ctx->msg))
+ erts_fprintf(stderr, " MSG: %T\n", ctx->msg);
+ #endif
+
+ ctx->data_size = ctx->pass_through_size;
+ erts_reset_atom_cache_map(ctx->acmp);
+ erts_encode_dist_ext_size(ctx->ctl, ctx->flags, ctx->acmp, &ctx->data_size);
+
+ if (is_value(ctx->msg)) {
+ ctx->u.sc.wstack.wstart = NULL;
+ ctx->u.sc.flags = ctx->flags;
+ ctx->u.sc.level = 0;
+ ctx->phase = ERTS_DSIG_SEND_PHASE_MSG_SIZE;
+ } else {
+ ctx->phase = ERTS_DSIG_SEND_PHASE_ALLOC;
+ }
+ break;
- dhdr_ext_size = erts_encode_ext_dist_header_size(acmp);
- data_size += dhdr_ext_size;
+ case ERTS_DSIG_SEND_PHASE_MSG_SIZE:
+ if (erts_encode_dist_ext_size_int(ctx->msg, ctx, &ctx->data_size)) {
+ retval = ERTS_DSIG_SEND_CONTINUE;
+ goto done;
+ }
- obuf = alloc_dist_obuf(data_size);
- obuf->ext_endp = &obuf->data[0] + pass_through_size + dhdr_ext_size;
+ ctx->phase = ERTS_DSIG_SEND_PHASE_ALLOC;
+ case ERTS_DSIG_SEND_PHASE_ALLOC:
+ erts_finalize_atom_cache_map(ctx->acmp, ctx->flags);
+
+ ctx->dhdr_ext_size = erts_encode_ext_dist_header_size(ctx->acmp);
+ ctx->data_size += ctx->dhdr_ext_size;
+
+ ctx->obuf = alloc_dist_obuf(ctx->data_size);
+ ctx->obuf->ext_endp = &ctx->obuf->data[0] + ctx->pass_through_size + ctx->dhdr_ext_size;
+
+ /* Encode internal version of dist header */
+ ctx->obuf->extp = erts_encode_ext_dist_header_setup(ctx->obuf->ext_endp, ctx->acmp);
+ /* Encode control message */
+ erts_encode_dist_ext(ctx->ctl, &ctx->obuf->ext_endp, ctx->flags, ctx->acmp, NULL, NULL);
+ if (is_value(ctx->msg)) {
+ ctx->u.ec.flags = ctx->flags;
+ ctx->u.ec.level = 0;
+ ctx->u.ec.wstack.wstart = NULL;
+ ctx->phase = ERTS_DSIG_SEND_PHASE_MSG_ENCODE;
+ } else {
+ ctx->phase = ERTS_DSIG_SEND_PHASE_FIN;
+ }
+ break;
- /* Encode internal version of dist header */
- obuf->extp = erts_encode_ext_dist_header_setup(obuf->ext_endp, acmp);
- /* Encode control message */
- erts_encode_dist_ext(ctl, &obuf->ext_endp, flags, acmp);
- if (is_value(msg)) {
- /* Encode message */
- erts_encode_dist_ext(msg, &obuf->ext_endp, flags, acmp);
- }
+ case ERTS_DSIG_SEND_PHASE_MSG_ENCODE:
+ if (erts_encode_dist_ext(ctx->msg, &ctx->obuf->ext_endp, ctx->flags, ctx->acmp, &ctx->u.ec, &ctx->reds)) {
+ retval = ERTS_DSIG_SEND_CONTINUE;
+ goto done;
+ }
- ASSERT(obuf->extp < obuf->ext_endp);
- ASSERT(&obuf->data[0] <= obuf->extp - pass_through_size);
- ASSERT(obuf->ext_endp <= &obuf->data[0] + data_size);
+ ctx->phase = ERTS_DSIG_SEND_PHASE_FIN;
+ case ERTS_DSIG_SEND_PHASE_FIN: {
+ DistEntry *dep = dsdp->dep;
+ int suspended = 0;
+ int resume = 0;
- data_size = obuf->ext_endp - obuf->extp;
+ ASSERT(ctx->obuf->extp < ctx->obuf->ext_endp);
+ ASSERT(&ctx->obuf->data[0] <= ctx->obuf->extp - ctx->pass_through_size);
+ ASSERT(ctx->obuf->ext_endp <= &ctx->obuf->data[0] + ctx->data_size);
- /*
- * Signal encoded; now verify that the connection still exists,
- * and if so enqueue the signal and schedule it for send.
- */
- obuf->next = NULL;
- erts_smp_de_rlock(dep);
- cid = dep->cid;
- if (cid != dsdp->cid
- || dep->connection_id != dsdp->connection_id
- || dep->status & ERTS_DE_SFLG_EXITING) {
- /* Not the same connection as when we started; drop message... */
- erts_smp_de_runlock(dep);
- free_dist_obuf(obuf);
- }
- else {
- ErtsProcList *plp = NULL;
- erts_smp_mtx_lock(&dep->qlock);
- dep->qsize += size_obuf(obuf);
- if (dep->qsize >= erts_dist_buf_busy_limit)
- dep->qflgs |= ERTS_DE_QFLG_BUSY;
- if (!force_busy && (dep->qflgs & ERTS_DE_QFLG_BUSY)) {
- erts_smp_mtx_unlock(&dep->qlock);
+ ctx->data_size = ctx->obuf->ext_endp - ctx->obuf->extp;
- plp = erts_proclist_create(c_p);
- erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL);
- suspended = 1;
- erts_smp_mtx_lock(&dep->qlock);
- }
+ /*
+ * Signal encoded; now verify that the connection still exists,
+ * and if so enqueue the signal and schedule it for send.
+ */
+ ctx->obuf->next = NULL;
+ erts_smp_de_rlock(dep);
+ cid = dep->cid;
+ if (cid != dsdp->cid
+ || dep->connection_id != dsdp->connection_id
+ || dep->status & ERTS_DE_SFLG_EXITING) {
+ /* Not the same connection as when we started; drop message... */
+ erts_smp_de_runlock(dep);
+ free_dist_obuf(ctx->obuf);
+ }
+ else {
+ ErtsProcList *plp = NULL;
+ erts_smp_mtx_lock(&dep->qlock);
+ dep->qsize += size_obuf(ctx->obuf);
+ if (dep->qsize >= erts_dist_buf_busy_limit)
+ dep->qflgs |= ERTS_DE_QFLG_BUSY;
+ if (!ctx->force_busy && (dep->qflgs & ERTS_DE_QFLG_BUSY)) {
+ erts_smp_mtx_unlock(&dep->qlock);
+
+ plp = erts_proclist_create(ctx->c_p);
+ erts_suspend(ctx->c_p, ERTS_PROC_LOCK_MAIN, NULL);
+ suspended = 1;
+ erts_smp_mtx_lock(&dep->qlock);
+ }
- /* Enqueue obuf on dist entry */
- if (dep->out_queue.last)
- dep->out_queue.last->next = obuf;
- else
- dep->out_queue.first = obuf;
- dep->out_queue.last = obuf;
+ /* Enqueue obuf on dist entry */
+ if (dep->out_queue.last)
+ dep->out_queue.last->next = ctx->obuf;
+ else
+ dep->out_queue.first = ctx->obuf;
+ dep->out_queue.last = ctx->obuf;
+
+ if (!ctx->force_busy) {
+ if (!(dep->qflgs & ERTS_DE_QFLG_BUSY)) {
+ if (suspended)
+ resume = 1; /* was busy when we started, but isn't now */
+ #ifdef USE_VM_PROBES
+ if (resume && DTRACE_ENABLED(dist_port_not_busy)) {
+ DTRACE_CHARBUF(port_str, 64);
+ DTRACE_CHARBUF(remote_str, 64);
+
+ erts_snprintf(port_str, sizeof(DTRACE_CHARBUF_NAME(port_str)),
+ "%T", cid);
+ erts_snprintf(remote_str, sizeof(DTRACE_CHARBUF_NAME(remote_str)),
+ "%T", dep->sysname);
+ DTRACE3(dist_port_not_busy, erts_this_node_sysname,
+ port_str, remote_str);
+ }
+ #endif
+ }
+ else {
+ /* Enqueue suspended process on dist entry */
+ ASSERT(plp);
+ erts_proclist_store_last(&dep->suspended, plp);
+ }
+ }
- if (!force_busy) {
- if (!(dep->qflgs & ERTS_DE_QFLG_BUSY)) {
- if (suspended)
- resume = 1; /* was busy when we started, but isn't now */
-#ifdef USE_VM_PROBES
- if (resume && DTRACE_ENABLED(dist_port_not_busy)) {
- DTRACE_CHARBUF(port_str, 64);
- DTRACE_CHARBUF(remote_str, 64);
-
- erts_snprintf(port_str, sizeof(DTRACE_CHARBUF_NAME(port_str)),
- "%T", cid);
- erts_snprintf(remote_str, sizeof(DTRACE_CHARBUF_NAME(remote_str)),
- "%T", dep->sysname);
- DTRACE3(dist_port_not_busy, erts_this_node_sysname,
- port_str, remote_str);
- }
-#endif
+ erts_smp_mtx_unlock(&dep->qlock);
+ erts_schedule_dist_command(NULL, dep);
+ erts_smp_de_runlock(dep);
+
+ if (resume) {
+ erts_resume(ctx->c_p, ERTS_PROC_LOCK_MAIN);
+ erts_proclist_destroy(plp);
+ /*
+ * Note that the calling process still have to yield as if it
+ * suspended. If not, the calling process could later be
+ * erroneously scheduled when it shouldn't be.
+ */
+ }
}
- else {
- /* Enqueue suspended process on dist entry */
- ASSERT(plp);
- erts_proclist_store_last(&dep->suspended, plp);
+ ctx->obuf = NULL;
+
+ if (suspended) {
+ #ifdef USE_VM_PROBES
+ if (!resume && DTRACE_ENABLED(dist_port_busy)) {
+ DTRACE_CHARBUF(port_str, 64);
+ DTRACE_CHARBUF(remote_str, 64);
+ DTRACE_CHARBUF(pid_str, 16);
+
+ erts_snprintf(port_str, sizeof(DTRACE_CHARBUF_NAME(port_str)), "%T", cid);
+ erts_snprintf(remote_str, sizeof(DTRACE_CHARBUF_NAME(remote_str)),
+ "%T", dep->sysname);
+ erts_snprintf(pid_str, sizeof(DTRACE_CHARBUF_NAME(pid_str)),
+ "%T", ctx->c_p->common.id);
+ DTRACE4(dist_port_busy, erts_this_node_sysname,
+ port_str, remote_str, pid_str);
+ }
+ #endif
+ if (!resume && erts_system_monitor_flags.busy_dist_port)
+ monitor_generic(ctx->c_p, am_busy_dist_port, cid);
+ retval = ERTS_DSIG_SEND_YIELD;
+ } else {
+ retval = ERTS_DSIG_SEND_OK;
}
+ goto done;
}
-
- erts_smp_mtx_unlock(&dep->qlock);
- erts_schedule_dist_command(NULL, dep);
- erts_smp_de_runlock(dep);
-
- if (resume) {
- erts_resume(c_p, ERTS_PROC_LOCK_MAIN);
- erts_proclist_destroy(plp);
- /*
- * Note that the calling process still have to yield as if it
- * suspended. If not, the calling process could later be
- * erroneously scheduled when it shouldn't be.
- */
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "dsig_send invalid phase (%d)\n", (int)ctx->phase);
}
}
- if (c_p) {
- int reds;
- /*
- * Bump reductions on calling process.
- *
- * This is the reduction cost: Always a base cost of 8 reductions
- * plus 16 reductions per kilobyte generated external data.
- */
-
- data_size >>= (10-4);
-#if defined(ARCH_64) && !HALFWORD_HEAP
- data_size &= 0x003fffffffffffff;
-#elif defined(ARCH_32) || HALFWORD_HEAP
- data_size &= 0x003fffff;
-#else
-# error "Ohh come on ... !?!"
-#endif
- reds = 8 + ((int) data_size > 1000000 ? 1000000 : (int) data_size);
- BUMP_REDS(c_p, reds);
- }
-
- if (suspended) {
-#ifdef USE_VM_PROBES
- if (!resume && DTRACE_ENABLED(dist_port_busy)) {
- DTRACE_CHARBUF(port_str, 64);
- DTRACE_CHARBUF(remote_str, 64);
- DTRACE_CHARBUF(pid_str, 16);
-
- erts_snprintf(port_str, sizeof(DTRACE_CHARBUF_NAME(port_str)), "%T", cid);
- erts_snprintf(remote_str, sizeof(DTRACE_CHARBUF_NAME(remote_str)),
- "%T", dep->sysname);
- erts_snprintf(pid_str, sizeof(DTRACE_CHARBUF_NAME(pid_str)),
- "%T", c_p->common.id);
- DTRACE4(dist_port_busy, erts_this_node_sysname,
- port_str, remote_str, pid_str);
- }
-#endif
- if (!resume && erts_system_monitor_flags.busy_dist_port)
- monitor_generic(c_p, am_busy_dist_port, cid);
- return ERTS_DSIG_SEND_YIELD;
+done:
+ if (ctx->msg && ctx->c_p) {
+ BUMP_REDS(ctx->c_p, (initial_reds - ctx->reds) / TERM_TO_BINARY_LOOP_FACTOR);
}
- return ERTS_DSIG_SEND_OK;
+ return retval;
}
-
static Uint
dist_port_command(Port *prt, ErtsDistOutputBuf *obuf)
{
@@ -1891,7 +1980,7 @@ dist_port_command(Port *prt, ErtsDistOutputBuf *obuf)
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
if (size > (Uint) INT_MAX)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Absurdly large distribution output data buffer "
"(%beu bytes) passed.\n",
size);
@@ -1931,7 +2020,7 @@ dist_port_commandv(Port *prt, ErtsDistOutputBuf *obuf)
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
if (size > (Uint) INT_MAX)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Absurdly large distribution output data buffer "
"(%beu bytes) passed.\n",
size);
@@ -2001,6 +2090,7 @@ erts_dist_command(Port *prt, int reds_limit)
DistEntry *dep = prt->dist_entry;
Uint (*send)(Port *prt, ErtsDistOutputBuf *obuf);
erts_aint32_t sched_flags;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
@@ -2055,12 +2145,12 @@ erts_dist_command(Port *prt, int reds_limit)
ErtsDistOutputBuf *fob;
size = (*send)(prt, foq.first);
+ esdp->io.out += (Uint64) size;
#ifdef ERTS_RAW_DIST_MSG_DBG
erts_fprintf(stderr, ">> ");
bw(foq.first->extp, size);
#endif
reds += ERTS_PORT_REDS_DIST_CMD_DATA(size);
- erts_smp_atomic_add_nob(&erts_bytes_out, size);
fob = foq.first;
obufsize += size_obuf(fob);
foq.first = foq.first->next;
@@ -2140,12 +2230,12 @@ erts_dist_command(Port *prt, int reds_limit)
ASSERT(&oq.first->data[0] <= oq.first->extp
&& oq.first->extp < oq.first->ext_endp);
size = (*send)(prt, oq.first);
+ esdp->io.out += (Uint64) size;
#ifdef ERTS_RAW_DIST_MSG_DBG
erts_fprintf(stderr, ">> ");
bw(oq.first->extp, size);
#endif
reds += ERTS_PORT_REDS_DIST_CMD_DATA(size);
- erts_smp_atomic_add_nob(&erts_bytes_out, size);
fob = oq.first;
obufsize += size_obuf(fob);
oq.first = oq.first->next;
@@ -2437,7 +2527,7 @@ info_dist_entry(int to, void *arg, DistEntry *dep, int visible, int connected)
erts_print(to, arg, "Name: %T", dep->sysname);
#ifdef DEBUG
- erts_print(to, arg, " (refc=%d)", erts_refc_read(&dep->refc, 1));
+ erts_print(to, arg, " (refc=%d)", erts_refc_read(&dep->refc, 0));
#endif
erts_print(to, arg, "\n");
if (!connected && is_nil(dep->cid)) {
@@ -2483,7 +2573,9 @@ int distribution_info(int to, void *arg) /* Called by break handler */
}
for (dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
- info_dist_entry(to, arg, dep, 0, 0);
+ if (dep != erts_this_dist_entry) {
+ info_dist_entry(to, arg, dep, 0, 0);
+ }
}
return(0);
@@ -2561,13 +2653,8 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2)
if (!net_kernel)
goto error;
- /* By setting dist_entry==erts_this_dist_entry and DISTRIBUTION on
- net_kernel do_net_exist will be called when net_kernel
- is terminated !! */
- (void) ERTS_PROC_SET_DIST_ENTRY(net_kernel,
- ERTS_PROC_LOCK_MAIN,
- erts_this_dist_entry);
- erts_refc_inc(&erts_this_dist_entry->refc, 2);
+ /* By setting F_DISTRIBUTION on net_kernel,
+ * do_net_exist will be called when net_kernel is terminated !! */
net_kernel->flags |= F_DISTRIBUTION;
if (net_kernel != BIF_P)
@@ -2928,11 +3015,11 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
- ASSERT(erts_no_of_not_connected_dist_entries >= 0);
+ ASSERT(erts_no_of_not_connected_dist_entries > 0);
ASSERT(erts_no_of_hidden_dist_entries >= 0);
ASSERT(erts_no_of_visible_dist_entries >= 0);
if(not_connected)
- length += erts_no_of_not_connected_dist_entries;
+ length += (erts_no_of_not_connected_dist_entries - 1);
if(hidden)
length += erts_no_of_hidden_dist_entries;
if(visible)
@@ -2954,8 +3041,10 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
#endif
if(not_connected)
for(dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
- result = CONS(hp, dep->sysname, result);
- hp += 2;
+ if (dep != erts_this_dist_entry) {
+ result = CONS(hp, dep->sysname, result);
+ hp += 2;
+ }
}
if(hidden)
for(dep = erts_hidden_dist_entries; dep; dep = dep->next) {
@@ -3236,11 +3325,7 @@ send_nodes_mon_msg(Process *rp,
}
ASSERT(hend == hp);
- erts_queue_message(rp, rp_locksp, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, rp_locksp, bp, msg, NIL);
}
static void
@@ -3297,7 +3382,7 @@ send_nodes_mon_msgs(Process *c_p, Eterm what, Eterm node, Eterm type, Eterm reas
continue;
break;
default:
- erl_exit(ERTS_ABORT_EXIT, "Bad node type found\n");
+ erts_exit(ERTS_ABORT_EXIT, "Bad node type found\n");
}
}
@@ -3606,7 +3691,7 @@ erts_processes_monitoring_nodes(Process *c_p)
case ERTS_NODES_MON_OPT_TYPES: type = am_all; break;
case ERTS_NODES_MON_OPT_TYPE_VISIBLE: type = am_visible; break;
case ERTS_NODES_MON_OPT_TYPE_HIDDEN: type = am_hidden; break;
- default: erl_exit(ERTS_ABORT_EXIT, "Bad node type found\n");
+ default: erts_exit(ERTS_ABORT_EXIT, "Bad node type found\n");
}
olist = erts_bld_cons(hpp, szp,
erts_bld_tuple(hpp, szp, 2,
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index f32b999198..fb777d9ac1 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -22,6 +23,7 @@
#include "erl_process.h"
#include "erl_node_tables.h"
+#include "zlib.h"
#define DFLAG_PUBLISHED 0x01
#define DFLAG_ATOM_CACHE 0x02
@@ -264,17 +266,105 @@ erts_destroy_dist_link(ErtsDistLinkData *dldp)
#endif
+
+
+/* Define for testing */
+/* #define EXTREME_TTB_TRAPPING 1 */
+
+#ifndef EXTREME_TTB_TRAPPING
+#define TERM_TO_BINARY_LOOP_FACTOR 32
+#else
+#define TERM_TO_BINARY_LOOP_FACTOR 1
+#endif
+
+typedef enum { TTBSize, TTBEncode, TTBCompress } TTBState;
+typedef struct TTBSizeContext_ {
+ Uint flags;
+ int level;
+ Uint result;
+ Eterm obj;
+ ErtsWStack wstack;
+} TTBSizeContext;
+
+typedef struct TTBEncodeContext_ {
+ Uint flags;
+ int level;
+ byte* ep;
+ Eterm obj;
+ ErtsWStack wstack;
+ Binary *result_bin;
+} TTBEncodeContext;
+
+typedef struct {
+ Uint real_size;
+ Uint dest_len;
+ byte *dbytes;
+ Binary *result_bin;
+ Binary *destination_bin;
+ z_stream stream;
+} TTBCompressContext;
+
+typedef struct {
+ int alive;
+ TTBState state;
+ union {
+ TTBSizeContext sc;
+ TTBEncodeContext ec;
+ TTBCompressContext cc;
+ } s;
+} TTBContext;
+
+enum erts_dsig_send_phase {
+ ERTS_DSIG_SEND_PHASE_INIT,
+ ERTS_DSIG_SEND_PHASE_MSG_SIZE,
+ ERTS_DSIG_SEND_PHASE_ALLOC,
+ ERTS_DSIG_SEND_PHASE_MSG_ENCODE,
+ ERTS_DSIG_SEND_PHASE_FIN
+};
+
+struct erts_dsig_send_context {
+ enum erts_dsig_send_phase phase;
+ Sint reds;
+
+ Eterm ctl;
+ Eterm msg;
+ int force_busy;
+ Uint32 pass_through_size;
+ Uint data_size, dhdr_ext_size;
+ ErtsAtomCacheMap *acmp;
+ ErtsDistOutputBuf *obuf;
+ Uint32 flags;
+ Process *c_p;
+ union {
+ TTBSizeContext sc;
+ TTBEncodeContext ec;
+ }u;
+};
+
+typedef struct {
+ int suspend;
+
+ Eterm ctl_heap[6];
+ ErtsDSigData dsd;
+ DistEntry* dep_to_deref;
+ struct erts_dsig_send_context dss;
+
+ Eterm return_term;
+}ErtsSendContext;
+
+
/*
* erts_dsig_send_* return values.
*/
#define ERTS_DSIG_SEND_OK 0
#define ERTS_DSIG_SEND_YIELD 1
+#define ERTS_DSIG_SEND_CONTINUE 2
extern int erts_dsig_send_link(ErtsDSigData *, Eterm, Eterm);
-extern int erts_dsig_send_msg(ErtsDSigData *, Eterm, Eterm);
+extern int erts_dsig_send_msg(Eterm, Eterm, ErtsSendContext*);
extern int erts_dsig_send_exit_tt(ErtsDSigData *, Eterm, Eterm, Eterm, Eterm);
extern int erts_dsig_send_unlink(ErtsDSigData *, Eterm, Eterm);
-extern int erts_dsig_send_reg_msg(ErtsDSigData *, Eterm, Eterm);
+extern int erts_dsig_send_reg_msg(Eterm, Eterm, ErtsSendContext*);
extern int erts_dsig_send_group_leader(ErtsDSigData *, Eterm, Eterm);
extern int erts_dsig_send_exit(ErtsDSigData *, Eterm, Eterm, Eterm);
extern int erts_dsig_send_exit2(ErtsDSigData *, Eterm, Eterm, Eterm);
@@ -282,6 +372,10 @@ extern int erts_dsig_send_demonitor(ErtsDSigData *, Eterm, Eterm, Eterm, int);
extern int erts_dsig_send_monitor(ErtsDSigData *, Eterm, Eterm, Eterm);
extern int erts_dsig_send_m_exit(ErtsDSigData *, Eterm, Eterm, Eterm, Eterm);
+extern int erts_dsig_send(ErtsDSigData *dsdp, struct erts_dsig_send_context* ctx);
+extern void erts_dsend_context_dtor(Binary*);
+extern Eterm erts_dsend_export_trap_context(Process* p, ErtsSendContext* ctx);
+
extern int erts_dist_command(Port *prt, int reds);
extern void erts_dist_port_not_busy(Port *prt);
extern void erts_kill_dist_connection(DistEntry *dep, Uint32);
diff --git a/erts/emulator/beam/dtrace-wrapper.h b/erts/emulator/beam/dtrace-wrapper.h
index 6ec0c91e21..d343dc5ab0 100644
--- a/erts/emulator/beam/dtrace-wrapper.h
+++ b/erts/emulator/beam/dtrace-wrapper.h
@@ -4,16 +4,17 @@
* Copyright Dustin Sallings, Michal Ptaszek, Scott Lystig Fritchie 2011-2012.
* All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/elib_memmove.c b/erts/emulator/beam/elib_memmove.c
index d2fe8649ed..d4ca30158e 100644
--- a/erts/emulator/beam/elib_memmove.c
+++ b/erts/emulator/beam/elib_memmove.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_afit_alloc.c b/erts/emulator/beam/erl_afit_alloc.c
index eca4e3b3bb..4b0541c10e 100644
--- a/erts/emulator/beam/erl_afit_alloc.c
+++ b/erts/emulator/beam/erl_afit_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -240,7 +241,7 @@ info_options(Allctr_t *allctr,
if (hpp || szp) {
if (!atoms_initialized)
- erl_exit(1, "%s:%d: Internal error: Atoms not initialized",
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error: Atoms not initialized",
__FILE__, __LINE__);;
res = NIL;
diff --git a/erts/emulator/beam/erl_afit_alloc.h b/erts/emulator/beam/erl_afit_alloc.h
index b90ac8f7c5..ef050ff50e 100644
--- a/erts/emulator/beam/erl_afit_alloc.h
+++ b/erts/emulator/beam/erl_afit_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 90cd227fae..5f8cd2bbf7 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -39,7 +40,7 @@
#include "erl_instrument.h"
#include "erl_mseg.h"
#include "erl_monitors.h"
-#include "erl_bif_timer.h"
+#include "erl_hl_timer.h"
#include "erl_cpu_topology.h"
#include "erl_thr_queue.h"
#if defined(ERTS_ALC_T_DRV_SEL_D_STATE) || defined(ERTS_ALC_T_DRV_EV_D_STATE)
@@ -133,6 +134,7 @@ static ErtsAllocatorState_t binary_alloc_state;
static ErtsAllocatorState_t ets_alloc_state;
static ErtsAllocatorState_t driver_alloc_state;
static ErtsAllocatorState_t fix_alloc_state;
+static ErtsAllocatorState_t test_alloc_state;
typedef struct {
erts_smp_atomic32_t refc;
@@ -232,6 +234,7 @@ typedef struct {
struct au_init std_low_alloc;
struct au_init ll_low_alloc;
#endif
+ struct au_init test_alloc;
} erts_alc_hndl_args_init_t;
#define ERTS_AU_INIT__ {0, 0, 1, GOODFIT, DEFAULT_ALLCTR_INIT, {1,1,1,1}}
@@ -431,6 +434,33 @@ set_default_fix_alloc_opts(struct au_init *ip,
ip->init.util.acul = ERTS_ALC_DEFAULT_ACUL;
}
+static void
+set_default_test_alloc_opts(struct au_init *ip)
+{
+ SET_DEFAULT_ALLOC_OPTS(ip);
+ ip->enable = 0; /* Disabled by default */
+ ip->thr_spec = -1 * erts_no_schedulers;
+ ip->atype = AOFIRSTFIT;
+ ip->init.aoff.flavor = AOFF_BF;
+ ip->init.util.name_prefix = "test_";
+ ip->init.util.alloc_no = ERTS_ALC_A_TEST;
+ ip->init.util.mmbcs = 0; /* Main carrier size */
+ ip->init.util.ts = ERTS_ALC_MTA_TEST;
+ ip->init.util.acul = ERTS_ALC_DEFAULT_ACUL;
+
+ /* Use a constant minimal MBC size */
+#if ERTS_SA_MB_CARRIERS
+ ip->init.util.smbcs = ERTS_SACRR_UNIT_SZ;
+ ip->init.util.lmbcs = ERTS_SACRR_UNIT_SZ;
+ ip->init.util.sbct = ERTS_SACRR_UNIT_SZ;
+#else
+ ip->init.util.smbcs = 1 << 12;
+ ip->init.util.lmbcs = 1 << 12;
+ ip->init.util.sbct = 1 << 12;
+#endif
+}
+
+
#ifdef ERTS_SMP
static void
@@ -575,6 +605,17 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_THR_Q_EL_SL)]
= sizeof(ErtsThrQElement_t);
#endif
+ fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_LL_PTIMER)]
+ = erts_timer_type_size(ERTS_ALC_T_LL_PTIMER);
+ fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_HL_PTIMER)]
+ = erts_timer_type_size(ERTS_ALC_T_HL_PTIMER);
+ fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_BIF_TIMER)]
+ = erts_timer_type_size(ERTS_ALC_T_BIF_TIMER);
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_ABIF_TIMER)]
+ = erts_timer_type_size(ERTS_ALC_T_ABIF_TIMER);
+#endif
+
#ifdef HARD_DEBUG
hdbg_init();
#endif
@@ -601,6 +642,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
set_default_driver_alloc_opts(&init.driver_alloc);
set_default_fix_alloc_opts(&init.fix_alloc,
fix_type_sizes);
+ set_default_test_alloc_opts(&init.test_alloc);
if (argc && argv)
handle_args(argc, argv, &init);
@@ -611,11 +653,11 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) {
int err = errno;
char *errstr = err ? strerror(err) : "unknown";
- erl_exit(-1, "Failed to lock physical memory: %s (%d)\n",
+ erts_exit(1, "Failed to lock physical memory: %s (%d)\n",
errstr, err);
}
#else
- erl_exit(-1, "Failed to lock physical memory: Not supported\n");
+ erts_exit(1, "Failed to lock physical memory: Not supported\n");
#endif
}
@@ -760,16 +802,17 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
set_au_allocator(ERTS_ALC_A_ETS, &init.ets_alloc, ncpu);
set_au_allocator(ERTS_ALC_A_DRIVER, &init.driver_alloc, ncpu);
set_au_allocator(ERTS_ALC_A_FIXED_SIZE, &init.fix_alloc, ncpu);
+ set_au_allocator(ERTS_ALC_A_TEST, &init.test_alloc, ncpu);
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
if (!erts_allctrs[i].alloc)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Missing alloc function for %s\n", ERTS_ALC_A2AD(i));
if (!erts_allctrs[i].realloc)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Missing realloc function for %s\n", ERTS_ALC_A2AD(i));
if (!erts_allctrs[i].free)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Missing free function for %s\n", ERTS_ALC_A2AD(i));
}
@@ -821,6 +864,10 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
&init.fix_alloc,
&fix_alloc_state);
+ start_au_allocator(ERTS_ALC_A_TEST,
+ &init.test_alloc,
+ &test_alloc_state);
+
erts_mtrace_install_wrapper_functions();
extra_block_size += erts_instr_init(init.instr.stat, init.instr.map);
@@ -843,7 +890,7 @@ erts_alloc_late_init(void)
static void *
erts_realloc_fixed_size(ErtsAlcType_t type, void *extra, void *p, Uint size)
{
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Attempt to reallocate a block of the fixed size type %s\n",
ERTS_ALC_T2TD(type));
}
@@ -965,7 +1012,7 @@ start_au_allocator(ErtsAlcType_t alctr_n,
* tspec->size)
+ ERTS_CACHE_LINE_SIZE - 1));
if (!states)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Failed to allocate allocator states for %salloc\n",
init->init.util.name_prefix);
tspec->allctr = (Allctr_t **) states;
@@ -993,7 +1040,7 @@ start_au_allocator(ErtsAlcType_t alctr_n,
(tot_fix_list_size
+ ERTS_CACHE_LINE_SIZE - 1));
if (!fix_lists)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Failed to allocate fix lists for %salloc\n",
init->init.util.name_prefix);
@@ -1067,7 +1114,7 @@ start_au_allocator(ErtsAlcType_t alctr_n,
}
if (!as)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Failed to start %salloc\n", init->init.util.name_prefix);
ASSERT(as == (void *) as0);
@@ -1406,6 +1453,7 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
&init->fix_alloc,
&init->sl_alloc,
&init->temp_alloc
+ /* test_alloc not affected by +Mea??? or +Mu??? */
};
int aui_sz = (int) sizeof(aui)/sizeof(aui[0]);
char *arg;
@@ -1496,6 +1544,9 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
case 'T':
handle_au_arg(&init->temp_alloc, &argv[i][3], argv, &i, 0);
break;
+ case 'Z':
+ handle_au_arg(&init->test_alloc, &argv[i][3], argv, &i, 0);
+ break;
case 'Y': { /* sys_alloc */
if (has_prefix("tt", param+2)) {
/* set trim threshold */
@@ -1858,7 +1909,7 @@ erts_alc_fatal_error(int error, int func, ErtsAlcType_t n, ...)
case ERTS_ALC_O_FREE: op_str = "free"; break;
default: op_str = "UNKNOWN"; break;
}
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s: %s operation not supported (memory type: \"%s\")\n",
allctr_str, op_str, t_str);
break;
@@ -1872,18 +1923,18 @@ erts_alc_fatal_error(int error, int func, ErtsAlcType_t n, ...)
va_start(argp, n);
size = va_arg(argp, Uint);
va_end(argp);
- erl_exit(1,
- "%s: Cannot %s %lu bytes of memory (of type \"%s\", thread %d).\n",
- allctr_str, op, size, t_str, ERTS_ALC_GET_THR_IX());
+ erts_exit(ERTS_DUMP_EXIT,
+ "%s: Cannot %s %lu bytes of memory (of type \"%s\").\n",
+ allctr_str, op, size, t_str);
break;
}
case ERTS_ALC_E_NOALLCTR:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_alloc: Unknown allocator type: %d\n",
ERTS_ALC_T2A(ERTS_ALC_N2T(n)));
break;
default:
- erl_exit(ERTS_ABORT_EXIT, "erts_alloc: Unknown error: %d\n", error);
+ erts_exit(ERTS_ABORT_EXIT, "erts_alloc: Unknown error: %d\n", error);
break;
}
}
@@ -2210,11 +2261,12 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
return am_badarg;
}
- /* All alloc_util allocators *have* to be enabled */
+ /* All alloc_util allocators *have* to be enabled, except test_alloc */
for (ai = ERTS_ALC_A_MIN; ai <= ERTS_ALC_A_MAX; ai++) {
switch (ai) {
case ERTS_ALC_A_SYSTEM:
+ case ERTS_ALC_A_TEST:
break;
default:
if (!erts_allctrs_info[ai].enabled
@@ -2255,6 +2307,8 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
* contain any allocated memory.
*/
continue;
+ case ERTS_ALC_A_TEST:
+ continue;
case ERTS_ALC_A_EHEAP:
save = &size.processes;
break;
@@ -2322,6 +2376,24 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
&size.processes_used,
fi,
ERTS_ALC_T_MSG_REF);
+ add_fix_values(&size.processes,
+ &size.processes_used,
+ fi,
+ ERTS_ALC_T_LL_PTIMER);
+ add_fix_values(&size.processes,
+ &size.processes_used,
+ fi,
+ ERTS_ALC_T_HL_PTIMER);
+ add_fix_values(&size.processes,
+ &size.processes_used,
+ fi,
+ ERTS_ALC_T_BIF_TIMER);
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ add_fix_values(&size.processes,
+ &size.processes_used,
+ fi,
+ ERTS_ALC_T_ABIF_TIMER);
+#endif
}
if (want.atom || want.atom_used) {
@@ -2645,14 +2717,17 @@ erts_alloc_util_allocators(void *proc)
/*
* Currently all allocators except sys_alloc are
* alloc_util allocators.
+ * Also hide test_alloc which is disabled by default
+ * and only intended for our own testing.
*/
- sz = ((ERTS_ALC_A_MAX + 1 - ERTS_ALC_A_MIN) - 1)*2;
+ sz = ((ERTS_ALC_A_MAX + 1 - ERTS_ALC_A_MIN) - 2)*2;
ASSERT(sz > 0);
hp = HAlloc((Process *) proc, sz);
res = NIL;
for (i = ERTS_ALC_A_MAX; i >= ERTS_ALC_A_MIN; i--) {
switch (i) {
case ERTS_ALC_A_SYSTEM:
+ case ERTS_ALC_A_TEST:
break;
default: {
char *alc_str = (char *) ERTS_ALC_A2AD(i);
@@ -3114,7 +3189,7 @@ reply_alloc_info(void *vair)
make_small(0), ainfo);
}
else {
- erl_exit(ERTS_ABORT_EXIT, "%s:%d: internal error\n",
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d: internal error\n",
__FILE__, __LINE__);
}
}
@@ -3180,17 +3255,13 @@ reply_alloc_info(void *vair)
HRelease(rp, hp_end, hp);
}
- erts_queue_message(rp, &rp_locks, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL);
if (air->req_sched == sched_id)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
erts_smp_proc_unlock(rp, rp_locks);
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
if (erts_smp_atomic32_dec_read_nob(&air->refc) == 0)
aireq_free(air);
@@ -3264,7 +3335,7 @@ erts_request_alloc_info(struct process *c_p,
erts_smp_atomic32_init_nob(&air->refc,
(erts_aint32_t) erts_no_schedulers);
- erts_smp_proc_add_refc(c_p, (Sint32) erts_no_schedulers);
+ erts_proc_add_refc(c_p, (Sint) erts_no_schedulers);
#ifdef ERTS_SMP
if (erts_no_schedulers > 1)
@@ -3355,7 +3426,7 @@ void *safe_realloc(void *ptr, Uint sz)
* Keep alloc_SUITE_data/allocator_test.h updated if changes are made *
* to erts_alc_test() *
\* */
-#define ERTS_ALC_TEST_ABORT erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error\n")
+#define ERTS_ALC_TEST_ABORT erts_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error\n")
UWord erts_alc_test(UWord op, UWord a1, UWord a2, UWord a3)
{
@@ -3540,6 +3611,41 @@ UWord erts_alc_test(UWord op, UWord a1, UWord a2, UWord a3)
#else
case 0xf13: return (UWord) 0;
#endif
+ case 0xf14: return (UWord) erts_alloc(ERTS_ALC_T_TEST, (Uint)a1);
+
+ case 0xf15: erts_free(ERTS_ALC_T_TEST, (void*)a1); return 0;
+
+ case 0xf16: {
+ Uint extra_hdr_sz = UNIT_CEILING((Uint)a1);
+ ErtsAllocatorThrSpec_t* ts = &erts_allctr_thr_spec[ERTS_ALC_A_TEST];
+ Uint offset = ts->allctr[0]->mbc_header_size;
+ void* orig_creating_mbc = ts->allctr[0]->creating_mbc;
+ void* orig_destroying_mbc = ts->allctr[0]->destroying_mbc;
+ void* new_creating_mbc = *(void**)a2; /* inout arg */
+ void* new_destroying_mbc = *(void**)a3; /* inout arg */
+ int i;
+
+ for (i=0; i < ts->size; i++) {
+ Allctr_t* ap = ts->allctr[i];
+ if (ap->mbc_header_size != offset
+ || ap->creating_mbc != orig_creating_mbc
+ || ap->destroying_mbc != orig_destroying_mbc
+ || ap->mbc_list.first != NULL)
+ return -1;
+ }
+ for (i=0; i < ts->size; i++) {
+ ts->allctr[i]->mbc_header_size += extra_hdr_sz;
+ ts->allctr[i]->creating_mbc = new_creating_mbc;
+ ts->allctr[i]->destroying_mbc = new_destroying_mbc;
+ }
+ *(void**)a2 = orig_creating_mbc;
+ *(void**)a3 = orig_destroying_mbc;
+ return offset;
+ }
+ case 0xf17: {
+ ErtsAllocatorThrSpec_t* ts = &erts_allctr_thr_spec[ERTS_ALC_A_TEST];
+ return ts->allctr[0]->largest_mbc_size;
+ }
default:
break;
}
@@ -3782,7 +3888,7 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func)
found_type = GET_TYPE_OF_PATTERN(pre_pattern);
if (pre_pattern != MK_PATTERN(n)) {
if ((FIXED_FENCE_PATTERN_MASK & pre_pattern) != FIXED_FENCE_PATTERN)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"ERROR: Fence at beginning of memory block (p=0x%u) "
"clobbered.\n",
(UWord) ptr);
@@ -3799,12 +3905,12 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func)
char *op_str;
if ((FIXED_FENCE_PATTERN_MASK & post_pattern) != FIXED_FENCE_PATTERN)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"ERROR: Fence at end of memory block (p=0x%u, sz=%u) "
"clobbered.\n",
(UWord) ptr, (UWord) sz);
if (found_type != GET_TYPE_OF_PATTERN(post_pattern))
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"ERROR: Fence around memory block (p=0x%u, sz=%u) "
"clobbered.\n",
(UWord) ptr, (UWord) sz);
@@ -3827,7 +3933,7 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func)
default: op_str = "???"; break;
}
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"ERROR: Memory block (p=0x%u, sz=%u) allocated as type \"%s\","
" but %s as type \"%s\".\n",
(UWord) ptr, (UWord) sz, ftype, op_str, otype);
@@ -3939,7 +4045,7 @@ static Uint
install_debug_functions(void)
{
int i;
- ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
+ ERTS_CT_ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
sys_memcpy((void *)real_allctrs,(void *)erts_allctrs,sizeof(erts_allctrs));
diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h
index d3109b9432..f540bae20d 100644
--- a/erts/emulator/beam/erl_alloc.h
+++ b/erts/emulator/beam/erl_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index 21434eb117..7738531142 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -111,7 +112,7 @@ allocator STANDARD_LOW false std_low_alloc
allocator BINARY true binary_alloc
allocator DRIVER true driver_alloc
-
+allocator TEST true test_alloc
# --- Class declarations -----------------------------------------------------
#
@@ -163,9 +164,13 @@ type MSG_ROOTS TEMPORARY PROCESSES msg_roots
type ROOTSET TEMPORARY PROCESSES root_set
type LOADER_TMP TEMPORARY CODE loader_tmp
type PREPARED_CODE SHORT_LIVED CODE prepared_code
-type BIF_TIMER_TABLE LONG_LIVED SYSTEM bif_timer_table
-type SL_BIF_TIMER SHORT_LIVED PROCESSES bif_timer_sl
-type LL_BIF_TIMER STANDARD PROCESSES bif_timer_ll
+type TIMER_SERVICE LONG_LIVED SYSTEM timer_service
+type LL_PTIMER FIXED_SIZE PROCESSES ll_ptimer
+type HL_PTIMER FIXED_SIZE PROCESSES hl_ptimer
+type BIF_TIMER FIXED_SIZE PROCESSES bif_timer
+# type ABIF_TIMER FIXED_SIZE PROCESSES accessor_bif_timer
+type TIMER_REQUEST SHORT_LIVED PROCESSES timer_request
+type BTM_YIELD_STATE SHORT_LIVED PROCESSES btm_yield_state
type REG_TABLE STANDARD SYSTEM reg_tab
type FUN_TABLE STANDARD CODE fun_tab
type DIST_TABLE STANDARD SYSTEM dist_tab
@@ -269,6 +274,8 @@ type BUSY_CALLER_TAB SHORT_LIVED SYSTEM busy_caller_table
type BUSY_CALLER SHORT_LIVED SYSTEM busy_caller
type PROC_SYS_TSK SHORT_LIVED PROCESSES proc_sys_task
type PROC_SYS_TSK_QS SHORT_LIVED PROCESSES proc_sys_task_queues
+type NEW_TIME_OFFSET SHORT_LIVED SYSTEM new_time_offset
+type IOB_REQ SHORT_LIVED SYSTEM io_bytes_request
+if threads_no_smp
# Need thread safe allocs, but std_alloc and fix_alloc are not;
@@ -323,8 +330,6 @@ type ACTIVE_PROCS STANDARD PROCESSES active_procs
+endif
+if smp
-type SL_PTIMER SHORT_LIVED SYSTEM ptimer_sl
-type LL_PTIMER STANDARD SYSTEM ptimer_ll
type SYS_MSG_Q SHORT_LIVED PROCESSES system_messages_queue
type FP_EXCEPTION LONG_LIVED SYSTEM fp_exception
type LL_MPATHS LONG_LIVED SYSTEM ll_migration_paths
@@ -364,6 +369,7 @@ type AINFO_REQ STANDARD_LOW SYSTEM alloc_info_request
type SCHED_WTIME_REQ STANDARD_LOW SYSTEM sched_wall_time_request
type GC_INFO_REQ STANDARD_LOW SYSTEM gc_info_request
type PORT_DATA_HEAP STANDARD_LOW SYSTEM port_data_heap
+type SYS_CHECK_REQ STANDARD_LOW SYSTEM system_check_request
+else # "fullword"
@@ -384,6 +390,7 @@ type AINFO_REQ SHORT_LIVED SYSTEM alloc_info_request
type SCHED_WTIME_REQ SHORT_LIVED SYSTEM sched_wall_time_request
type GC_INFO_REQ SHORT_LIVED SYSTEM gc_info_request
type PORT_DATA_HEAP STANDARD SYSTEM port_data_heap
+type SYS_CHECK_REQ SHORT_LIVED SYSTEM system_check_request
+endif
@@ -415,6 +422,13 @@ type CS_PROG_PATH LONG_LIVED SYSTEM cs_prog_path
type ENVIRONMENT TEMPORARY SYSTEM environment
type PUTENV_STR SYSTEM SYSTEM putenv_string
type PRT_REP_EXIT STANDARD SYSTEM port_report_exit
+type SYS_BLOCKING STANDARD SYSTEM sys_blocking
+
++if smp
+type SYS_WRITE_BUF TEMPORARY SYSTEM sys_write_buf
++else
+type SYS_WRITE_BUF BINARY SYSTEM sys_write_buf
++endif
+endif
@@ -444,4 +458,7 @@ type CON_VPRINTF_BUF TEMPORARY SYSTEM con_vprintf_buf
+endif
+# This type should only be used for test
+type TEST TEST SYSTEM testing
+
# ----------------------------------------------------------------------------
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index e3172dc4fb..d9eaa7b32c 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -718,7 +719,7 @@ static void make_name_atoms(Allctr_t *allctr);
static Block_t *create_carrier(Allctr_t *, Uint, UWord);
static void destroy_carrier(Allctr_t *, Block_t *, Carrier_t **);
static void mbc_free(Allctr_t *allctr, void *p, Carrier_t **busy_pcrr_pp);
-static void dealloc_block(Allctr_t *, void *, int);
+static void dealloc_block(Allctr_t *, void *, ErtsAlcFixList_t *, int);
/* internal data... */
@@ -1067,17 +1068,21 @@ typedef struct {
} ErtsAllctrFixDDBlock_t;
#endif
+#define ERTS_ALC_FIX_NO_UNUSE (((ErtsAlcType_t) 1) << ERTS_ALC_N_BITS)
+
static ERTS_INLINE void
dealloc_fix_block(Allctr_t *allctr,
ErtsAlcType_t type,
void *ptr,
+ ErtsAlcFixList_t *fix,
int dec_cc_on_redirect)
{
#ifdef ERTS_SMP
/* May be redirected... */
- ((ErtsAllctrFixDDBlock_t *) ptr)->fix_type = type;
+ ASSERT((type & ERTS_ALC_FIX_NO_UNUSE) == 0);
+ ((ErtsAllctrFixDDBlock_t *) ptr)->fix_type = type | ERTS_ALC_FIX_NO_UNUSE;
#endif
- dealloc_block(allctr, ptr, dec_cc_on_redirect);
+ dealloc_block(allctr, ptr, fix, dec_cc_on_redirect);
}
static ERTS_INLINE void
@@ -1123,8 +1128,7 @@ fix_cpool_check_shrink(Allctr_t *allctr,
if (fix->u.cpool.min_list_size > fix->list_size)
fix->u.cpool.min_list_size = fix->list_size;
- fix->u.cpool.allocated--;
- dealloc_fix_block(allctr, type, p, 0);
+ dealloc_fix_block(allctr, type, p, fix, 0);
}
}
}
@@ -1170,7 +1174,8 @@ static ERTS_INLINE void
fix_cpool_free(Allctr_t *allctr,
ErtsAlcType_t type,
void *p,
- Carrier_t **busy_pcrr_pp)
+ Carrier_t **busy_pcrr_pp,
+ int unuse)
{
ErtsAlcFixList_t *fix;
@@ -1178,8 +1183,9 @@ fix_cpool_free(Allctr_t *allctr,
&& type <= ERTS_ALC_N_MAX_A_FIXED_SIZE);
fix = &allctr->fix[type - ERTS_ALC_N_MIN_A_FIXED_SIZE];
-
- fix->u.cpool.used--;
+
+ if (unuse)
+ fix->u.cpool.used--;
if ((!busy_pcrr_pp || !*busy_pcrr_pp)
&& !fix->u.cpool.shrink_list
@@ -1237,8 +1243,7 @@ fix_cpool_alloc_shrink(Allctr_t *allctr, erts_aint32_t flgs)
fix->list = *((void **) ptr);
fix->list_size--;
fix->u.cpool.shrink_list--;
- fix->u.cpool.allocated--;
- dealloc_fix_block(allctr, type, ptr, 0);
+ dealloc_fix_block(allctr, type, ptr, fix, 0);
}
if (fix->u.cpool.min_list_size > fix->list_size)
fix->u.cpool.min_list_size = fix->list_size;
@@ -1399,7 +1404,7 @@ fix_nocpool_alloc_shrink(Allctr_t *allctr, erts_aint32_t flgs)
ptr = fix->list;
fix->list = *((void **) ptr);
fix->list_size--;
- dealloc_block(allctr, ptr, 0);
+ dealloc_block(allctr, ptr, NULL, 0);
fix->u.nocpool.allocated--;
}
if (fix->list_size != 0) {
@@ -1432,6 +1437,16 @@ erts_alcu_fix_alloc_shrink(Allctr_t *allctr, erts_aint32_t flgs)
static void dealloc_carrier(Allctr_t *allctr, Carrier_t *crr, int superaligned);
+static ERTS_INLINE void
+dealloc_mbc(Allctr_t *allctr, Carrier_t *crr)
+{
+ ASSERT(IS_MB_CARRIER(crr));
+ if (allctr->destroying_mbc)
+ allctr->destroying_mbc(allctr, crr);
+
+ dealloc_carrier(allctr, crr, 1);
+}
+
#ifdef ERTS_SMP
static ERTS_INLINE Allctr_t*
@@ -1442,7 +1457,7 @@ get_pref_allctr(void *extra)
pref_ix = ERTS_ALC_GET_THR_IX();
- ASSERT(sizeof(UWord) == sizeof(Allctr_t *));
+ ERTS_CT_ASSERT(sizeof(UWord) == sizeof(Allctr_t *));
ASSERT(0 <= pref_ix && pref_ix < tspec->size);
return tspec->allctr[pref_ix];
@@ -1746,11 +1761,13 @@ handle_delayed_fix_dealloc(Allctr_t *allctr, void *ptr)
type = ((ErtsAllctrFixDDBlock_t *) ptr)->fix_type;
- ASSERT(ERTS_ALC_N_MIN_A_FIXED_SIZE <= type
- && type <= ERTS_ALC_N_MAX_A_FIXED_SIZE);
+ ASSERT(ERTS_ALC_N_MIN_A_FIXED_SIZE
+ <= (type & ~ERTS_ALC_FIX_NO_UNUSE));
+ ASSERT((type & ~ERTS_ALC_FIX_NO_UNUSE)
+ <= ERTS_ALC_N_MAX_A_FIXED_SIZE);
if (!ERTS_ALC_IS_CPOOL_ENABLED(allctr))
- fix_nocpool_free(allctr, type, ptr);
+ fix_nocpool_free(allctr, (type & ~ERTS_ALC_FIX_NO_UNUSE), ptr);
else {
Block_t *blk = UMEM2BLK(ptr);
Carrier_t *busy_pcrr_p;
@@ -1765,7 +1782,9 @@ handle_delayed_fix_dealloc(Allctr_t *allctr, void *ptr)
NULL, &busy_pcrr_p);
if (used_allctr == allctr) {
doit:
- fix_cpool_free(allctr, type, ptr, &busy_pcrr_p);
+ fix_cpool_free(allctr, (type & ~ERTS_ALC_FIX_NO_UNUSE),
+ ptr, &busy_pcrr_p,
+ !(type & ERTS_ALC_FIX_NO_UNUSE));
clear_busy_pool_carrier(allctr, busy_pcrr_p);
}
else {
@@ -1861,7 +1880,7 @@ handle_delayed_dealloc(Allctr_t *allctr,
* if this carrier is pulled from dc_list by cpool_fetch()
*/
ERTS_ALC_CPOOL_ASSERT(FBLK_TO_MBC(blk) != crr);
- ERTS_ALC_CPOOL_ASSERT(sizeof(ErtsAllctrDDBlock_t) == sizeof(void*));
+ ERTS_CT_ASSERT(sizeof(ErtsAllctrDDBlock_t) == sizeof(void*));
#ifdef MBC_ABLK_OFFSET_BITS
blk->u.carrier = crr;
#else
@@ -1885,7 +1904,7 @@ handle_delayed_dealloc(Allctr_t *allctr,
if (fix)
handle_delayed_fix_dealloc(allctr, ptr);
else
- dealloc_block(allctr, ptr, 1);
+ dealloc_block(allctr, ptr, NULL, 1);
}
}
@@ -1991,15 +2010,24 @@ erts_alcu_check_delayed_dealloc(Allctr_t *allctr,
ERTS_ALCU_DD_OPS_LIM_LOW, NULL, NULL, NULL)
static void
-dealloc_block(Allctr_t *allctr, void *ptr, int dec_cc_on_redirect)
+dealloc_block(Allctr_t *allctr, void *ptr, ErtsAlcFixList_t *fix, int dec_cc_on_redirect)
{
Block_t *blk = UMEM2BLK(ptr);
ERTS_SMP_LC_ASSERT(!allctr->thread_safe
|| erts_lc_mtx_is_locked(&allctr->mutex));
- if (IS_SBC_BLK(blk))
+ if (IS_SBC_BLK(blk)) {
destroy_carrier(allctr, blk, NULL);
+#ifdef ERTS_SMP
+ if (fix && ERTS_ALC_IS_CPOOL_ENABLED(allctr)) {
+ ErtsAlcType_t type = ((ErtsAllctrFixDDBlock_t *) ptr)->fix_type;
+ if (!(type & ERTS_ALC_FIX_NO_UNUSE))
+ fix->u.cpool.used--;
+ fix->u.cpool.allocated--;
+ }
+#endif
+ }
#ifndef ERTS_SMP
else
mbc_free(allctr, ptr, NULL);
@@ -2012,6 +2040,12 @@ dealloc_block(Allctr_t *allctr, void *ptr, int dec_cc_on_redirect)
used_allctr = get_used_allctr(allctr, ERTS_ALC_TS_PREF_LOCK_NO, ptr,
NULL, &busy_pcrr_p);
if (used_allctr == allctr) {
+ if (fix) {
+ ErtsAlcType_t type = ((ErtsAllctrFixDDBlock_t *) ptr)->fix_type;
+ if (!(type & ERTS_ALC_FIX_NO_UNUSE))
+ fix->u.cpool.used--;
+ fix->u.cpool.allocated--;
+ }
mbc_free(allctr, ptr, &busy_pcrr_p);
clear_busy_pool_carrier(allctr, busy_pcrr_p);
}
@@ -3125,7 +3159,7 @@ cpool_fetch(Allctr_t *allctr, UWord size)
cpool_entrance = sentinel;
cpdp = cpool_aint2cpd(cpool_read(&cpool_entrance->prev));
if (cpdp == sentinel)
- return NULL;
+ goto check_dc_list;
}
has_passed_sentinel = 0;
@@ -3136,18 +3170,18 @@ cpool_fetch(Allctr_t *allctr, UWord size)
if (cpool_entrance == sentinel) {
cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
if (cpdp == sentinel)
- return NULL;
+ break;
}
i = 0; /* Last one to inspect */
}
else if (cpdp == sentinel) {
if (has_passed_sentinel) {
/* We been here before. cpool_entrance must have been removed */
- return NULL;
+ break;
}
cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
if (cpdp == sentinel)
- return NULL;
+ break;
has_passed_sentinel = 1;
}
crr = (Carrier_t *)(((char *)cpdp) - offsetof(Carrier_t, cpool));
@@ -3171,10 +3205,12 @@ cpool_fetch(Allctr_t *allctr, UWord size)
return NULL;
}
+check_dc_list:
/* Last; check our own pending dealloc carrier list... */
crr = allctr->cpool.dc_list.last;
while (crr) {
if (erts_atomic_read_nob(&crr->cpool.max_size) >= size) {
+ Block_t* blk;
unlink_carrier(&allctr->cpool.dc_list, crr);
#ifdef ERTS_ALC_CPOOL_DEBUG
ERTS_ALC_CPOOL_ASSERT(erts_smp_atomic_xchg_nob(&crr->allctr,
@@ -3183,6 +3219,9 @@ cpool_fetch(Allctr_t *allctr, UWord size)
#else
erts_smp_atomic_set_nob(&crr->allctr, ((erts_aint_t) allctr));
#endif
+ blk = MBC_TO_FIRST_BLK(allctr, crr);
+ ASSERT(FBLK_TO_MBC(blk) == crr);
+ allctr->link_free_block(allctr, blk);
return crr;
}
crr = crr->prev;
@@ -3213,7 +3252,7 @@ check_pending_dealloc_carrier(Allctr_t *allctr,
dcrr = crr;
crr = crr->next;
- dealloc_carrier(allctr, dcrr, 1);
+ dealloc_mbc(allctr, dcrr);
i++;
} while (crr && i < ERTS_ALC_MAX_DEALLOC_CARRIER);
@@ -3244,18 +3283,20 @@ static void
schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr)
{
Allctr_t *orig_allctr;
+ Block_t *blk;
int check_pending_dealloc;
erts_aint_t max_size;
+ ASSERT(IS_MB_CARRIER(crr));
+
if (!ERTS_ALC_IS_CPOOL_ENABLED(allctr)) {
- dealloc_carrier(allctr, crr, 1);
+ dealloc_mbc(allctr, crr);
return;
}
orig_allctr = crr->cpool.orig_allctr;
if (allctr != orig_allctr) {
- Block_t *blk = MBC_TO_FIRST_BLK(allctr, crr);
int cinit = orig_allctr->dd.ix - allctr->dd.ix;
/*
@@ -3272,6 +3313,7 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr)
* since the block is an mbc block that is free and last
* in the carrier.
*/
+ blk = MBC_TO_FIRST_BLK(allctr, crr);
ERTS_ALC_CPOOL_ASSERT(IS_FREE_LAST_MBC_BLK(blk));
ERTS_ALC_CPOOL_ASSERT(IS_MBC_FIRST_ABLK(allctr, blk));
@@ -3291,11 +3333,13 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr)
if (crr->cpool.thr_prgr == ERTS_THR_PRGR_INVALID
|| erts_thr_progress_has_reached(crr->cpool.thr_prgr)) {
- dealloc_carrier(allctr, crr, 1);
+ dealloc_mbc(allctr, crr);
return;
}
- max_size = (erts_aint_t) allctr->largest_fblk_in_mbc(allctr, crr);
+ blk = MBC_TO_FIRST_BLK(allctr, crr);
+ ASSERT(IS_FREE_LAST_MBC_BLK(blk));
+ max_size = (erts_aint_t) MBC_FBLK_SZ(blk);
erts_atomic_set_nob(&crr->cpool.max_size, max_size);
crr->next = NULL;
@@ -3870,9 +3914,6 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
}
#endif
- if (allctr->destroying_mbc)
- (*allctr->destroying_mbc)(allctr, crr);
-
#ifdef ERTS_SMP
if (busy_pcrr_pp && *busy_pcrr_pp) {
ERTS_ALC_CPOOL_ASSERT(*busy_pcrr_pp == crr);
@@ -3896,12 +3937,15 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
else
#endif
STAT_SYS_ALLOC_MBC_FREE(allctr, crr_sz);
+
+ if (allctr->remove_mbc)
+ allctr->remove_mbc(allctr, crr);
}
#ifdef ERTS_SMP
schedule_dealloc_carrier(allctr, crr);
#else
- dealloc_carrier(allctr, crr, 1);
+ dealloc_mbc(allctr, crr);
#endif
}
}
@@ -4474,7 +4518,7 @@ make_name_atoms(Allctr_t *allctr)
size_t prefix_len = strlen(allctr->name_prefix);
if (prefix_len > MAX_ATOM_CHARACTERS + sizeof(realloc) - 1)
- erl_exit(1,"Too long allocator name: %salloc\n",allctr->name_prefix);
+ erts_exit(ERTS_ERROR_EXIT,"Too long allocator name: %salloc\n",allctr->name_prefix);
memcpy((void *) buf, (void *) allctr->name_prefix, prefix_len);
@@ -5215,7 +5259,7 @@ do_erts_alcu_free(ErtsAlcType_t type, void *extra, void *p,
if (allctr->fix) {
if (ERTS_ALC_IS_CPOOL_ENABLED(allctr))
- fix_cpool_free(allctr, type, p, busy_pcrr_pp);
+ fix_cpool_free(allctr, type, p, busy_pcrr_pp, 1);
else
fix_nocpool_free(allctr, type, p);
}
@@ -5676,7 +5720,7 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
/* erts_alcu_start assumes that allctr has been zeroed */
if (((UWord)allctr & ERTS_CRR_ALCTR_FLG_MASK) != 0) {
- erl_exit(ERTS_ABORT_EXIT, "%s:%d:erts_alcu_start: Alignment error\n",
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d:erts_alcu_start: Alignment error\n",
__FILE__, __LINE__);
}
@@ -5860,7 +5904,7 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
if (allctr->thread_safe)
erts_mtx_destroy(&allctr->mutex);
#endif
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Failed to create main carrier for %salloc\n",
init->name_prefix);
}
@@ -5942,7 +5986,7 @@ erts_alcu_init(AlcUInit_t *init)
erts_atomic_init_nob(&sentinel->prev, (erts_aint_t) sentinel);
}
#endif
- ASSERT(SBC_BLK_SZ_MASK == MBC_FBLK_SZ_MASK); /* see BLK_SZ */
+ ERTS_CT_ASSERT(SBC_BLK_SZ_MASK == MBC_FBLK_SZ_MASK); /* see BLK_SZ */
#if HAVE_ERTS_MSEG
ASSERT(erts_mseg_unit_size() == ERTS_SACRR_UNIT_SZ);
max_mseg_carriers = init->mmc;
@@ -6005,7 +6049,7 @@ erts_alcu_test(UWord op, UWord a1, UWord a2)
case 0x019: return (UWord) PREV_BLK((Block_t *) a1);
case 0x01a: return (UWord) IS_MBC_FIRST_BLK((Allctr_t*)a1, (Block_t *) a2);
case 0x01b: return (UWord) sizeof(Unit_t);
- case 0x01c: return (unsigned long) BLK_TO_MBC((Block_t*) a1);
+ case 0x01c: return (UWord) BLK_TO_MBC((Block_t*) a1);
case 0x01d: ((Allctr_t*) a1)->add_mbc((Allctr_t*)a1, (Carrier_t*)a2); break;
case 0x01e: ((Allctr_t*) a1)->remove_mbc((Allctr_t*)a1, (Carrier_t*)a2); break;
#ifdef ERTS_SMP
@@ -6030,6 +6074,16 @@ erts_alcu_test(UWord op, UWord a1, UWord a2)
case 0x023: return (UWord) 0;
case 0x024: return (UWord) 0;
#endif
+ case 0x025: /* UMEM2BLK_TEST*/
+#ifdef DEBUG
+# ifdef HARD_DEBUG
+ return (UWord)UMEM2BLK(a1-3*sizeof(UWord));
+# else
+ return (UWord)UMEM2BLK(a1-2*sizeof(UWord));
+# endif
+#else
+ return (UWord)UMEM2BLK(a1);
+#endif
default: ASSERT(0); return ~((UWord) 0);
}
@@ -6066,7 +6120,7 @@ erts_alcu_verify_unused(Allctr_t *allctr)
if (no) {
UWord sz = allctr->sbcs.blocks.curr.size;
sz += allctr->mbcs.blocks.curr.size;
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%salloc() used when expected to be unused!\n"
"Total amount of blocks allocated: %bpu\n"
"Total amount of bytes allocated: %bpu\n",
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index eee920e66c..f4a2ae7ff3 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -276,7 +277,7 @@ typedef struct ErtsDoubleLink_t_ {
typedef struct {
erts_atomic_t next;
erts_atomic_t prev;
- Allctr_t *orig_allctr;
+ Allctr_t *orig_allctr; /* read-only while carrier is alive */
ErtsThrPrgrVal thr_prgr;
erts_atomic_t max_size;
UWord abandon_limit;
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c
index 396aa88e0b..5cd067ff54 100644
--- a/erts/emulator/beam/erl_ao_firstfit_alloc.c
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -208,7 +209,9 @@ static Block_t* aoff_get_free_block(Allctr_t *, Uint, Block_t *, Uint);
static void aoff_link_free_block(Allctr_t *, Block_t*);
static void aoff_unlink_free_block(Allctr_t *allctr, Block_t *del);
static void aoff_creating_mbc(Allctr_t*, Carrier_t*);
+#ifdef DEBUG
static void aoff_destroying_mbc(Allctr_t*, Carrier_t*);
+#endif
static void aoff_add_mbc(Allctr_t*, Carrier_t*);
static void aoff_remove_mbc(Allctr_t*, Carrier_t*);
static UWord aoff_largest_fblk_in_mbc(Allctr_t*, Carrier_t*);
@@ -270,7 +273,11 @@ erts_aoffalc_start(AOFFAllctr_t *alc,
allctr->get_next_mbc_size = NULL;
allctr->creating_mbc = aoff_creating_mbc;
+#ifdef DEBUG
allctr->destroying_mbc = aoff_destroying_mbc;
+#else
+ allctr->destroying_mbc = NULL;
+#endif
allctr->add_mbc = aoff_add_mbc;
allctr->remove_mbc = aoff_remove_mbc;
allctr->largest_fblk_in_mbc = aoff_largest_fblk_in_mbc;
@@ -884,17 +891,18 @@ static void aoff_creating_mbc(Allctr_t *allctr, Carrier_t *carrier)
HARD_CHECK_TREE(NULL, 0, *root, 0);
}
+#define IS_CRR_IN_TREE(CRR,ROOT) \
+ ((CRR)->rbt_node.parent || (ROOT) == &(CRR)->rbt_node)
+
+#ifdef DEBUG
static void aoff_destroying_mbc(Allctr_t *allctr, Carrier_t *carrier)
{
AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr;
AOFF_Carrier_t *crr = (AOFF_Carrier_t*) carrier;
- AOFF_RBTree_t *root = alc->mbc_root;
- if (crr->rbt_node.parent || &crr->rbt_node == root) {
- aoff_remove_mbc(allctr, carrier);
- }
- /*else already removed */
+ ASSERT(!IS_CRR_IN_TREE(crr, alc->mbc_root));
}
+#endif
static void aoff_add_mbc(Allctr_t *allctr, Carrier_t *carrier)
{
@@ -902,6 +910,7 @@ static void aoff_add_mbc(Allctr_t *allctr, Carrier_t *carrier)
AOFF_Carrier_t *crr = (AOFF_Carrier_t*) carrier;
AOFF_RBTree_t **root = &alc->mbc_root;
+ ASSERT(!IS_CRR_IN_TREE(crr, *root));
HARD_CHECK_TREE(NULL, 0, *root, 0);
/* Link carrier in address order tree
@@ -918,6 +927,10 @@ static void aoff_remove_mbc(Allctr_t *allctr, Carrier_t *carrier)
AOFF_RBTree_t **root = &alc->mbc_root;
ASSERT(allctr == ERTS_ALC_CARRIER_TO_ALLCTR(carrier));
+
+ if (!IS_CRR_IN_TREE(crr,*root))
+ return;
+
HARD_CHECK_TREE(NULL, 0, *root, 0);
rbt_delete(root, &crr->rbt_node);
@@ -1022,7 +1035,7 @@ info_options(Allctr_t *allctr,
if (hpp || szp) {
if (!atoms_initialized)
- erl_exit(1, "%s:%d: Internal error: Atoms not initialized",
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error: Atoms not initialized",
__FILE__, __LINE__);;
res = NIL;
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.h b/erts/emulator/beam/erl_ao_firstfit_alloc.h
index 25b344c6a8..4200f20622 100644
--- a/erts/emulator/beam/erl_ao_firstfit_alloc.h
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_arith.c b/erts/emulator/beam/erl_arith.c
index 5150a8a507..b8c5ef9b09 100644
--- a/erts/emulator/beam/erl_arith.c
+++ b/erts/emulator/beam/erl_arith.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -2048,3 +2049,8 @@ Eterm erts_gc_bnot(Process* p, Eterm* reg, Uint live)
}
return result;
}
+
+/* Needed to remove compiler optimization */
+double erts_get_positive_zero_float() {
+ return 0.0f;
+}
diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c
index decae6b2ca..f071898046 100644
--- a/erts/emulator/beam/erl_async.c
+++ b/erts/emulator/beam/erl_async.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -176,7 +177,7 @@ erts_init_async(void)
ErtsThrQInit_t qinit = ERTS_THR_Q_INIT_DEFAULT;
#endif
erts_thr_opts_t thr_opts = ERTS_THR_OPTS_DEFAULT_INITER;
- char *ptr;
+ char *ptr, thr_name[16];
size_t tot_size = 0;
int i;
@@ -227,23 +228,16 @@ erts_init_async(void)
thr_opts.suggested_stack_size
= erts_async_thread_suggested_stack_size;
-#ifdef ETHR_HAVE_THREAD_NAMES
- thr_opts.name = malloc(sizeof(char)*(strlen("async_XXXX")+1));
-#endif
+ thr_opts.name = thr_name;
for (i = 0; i < erts_async_max_threads; i++) {
ErtsAsyncQ *aq = async_q(i);
-#ifdef ETHR_HAVE_THREAD_NAMES
- sprintf(thr_opts.name, "async_%d", i+1);
-#endif
+ erts_snprintf(thr_opts.name, 16, "async_%d", i+1);
erts_thr_create(&aq->thr_id, async_main, (void*) aq, &thr_opts);
}
-#ifdef ETHR_HAVE_THREAD_NAMES
- free(thr_opts.name);
-#endif
/* Wait for async threads to initialize... */
erts_mtx_lock(&async->init.data.mtx);
diff --git a/erts/emulator/beam/erl_async.h b/erts/emulator/beam/erl_async.h
index 95374a8fc9..65538bcef0 100644
--- a/erts/emulator/beam/erl_async.h
+++ b/erts/emulator/beam/erl_async.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_bestfit_alloc.c b/erts/emulator/beam/erl_bestfit_alloc.c
index 59c14899a2..f39a18ac88 100644
--- a/erts/emulator/beam/erl_bestfit_alloc.c
+++ b/erts/emulator/beam/erl_bestfit_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -939,7 +940,7 @@ info_options(Allctr_t *allctr,
if (hpp || szp) {
if (!atoms_initialized)
- erl_exit(1, "%s:%d: Internal error: Atoms not initialized",
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error: Atoms not initialized",
__FILE__, __LINE__);;
res = NIL;
diff --git a/erts/emulator/beam/erl_bestfit_alloc.h b/erts/emulator/beam/erl_bestfit_alloc.h
index 870439e886..b315518b88 100644
--- a/erts/emulator/beam/erl_bestfit_alloc.h
+++ b/erts/emulator/beam/erl_bestfit_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index 3bf78adce7..134aa2d396 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -32,10 +33,13 @@
#include "global.h"
#include "erl_process.h"
#include "error.h"
+#define ERL_WANT_HIPE_BIF_WRAPPER__
#include "bif.h"
+#undef ERL_WANT_HIPE_BIF_WRAPPER__
#include "big.h"
#include "erl_binary.h"
#include "erl_bits.h"
+#include "erl_bif_unique.h"
/*
@@ -2424,8 +2428,6 @@ static BIF_RETTYPE do_binary_copy(Process *p, Eterm bin, Eterm en)
}
cbs->result = erts_bin_nrml_alloc(target_size); /* Always offheap
if trapping */
- cbs->result->flags = 0;
- cbs->result->orig_size = target_size;
erts_refc_init(&(cbs->result->refc), 1);
t = (byte *) cbs->result->orig_bytes; /* No offset or anything */
pos = 0;
diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c
index 4302fe8f79..e3074d6309 100644
--- a/erts/emulator/beam/erl_bif_chksum.c
+++ b/erts/emulator/beam/erl_bif_chksum.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_bif_ddll.c b/erts/emulator/beam/erl_bif_ddll.c
index 56cd2ba04f..f4ef59993a 100644
--- a/erts/emulator/beam/erl_bif_ddll.c
+++ b/erts/emulator/beam/erl_bif_ddll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -45,6 +46,7 @@
#include "big.h"
#include "dist.h"
#include "erl_version.h"
+#include "erl_bif_unique.h"
#include "dtrace-wrapper.h"
#ifdef ERTS_SMP
@@ -1307,7 +1309,7 @@ static Eterm notify_when_loaded(Process *p, Eterm name_term, char *name, ErtsPro
case ERL_DE_FORCE_RELOAD:
break;
default:
- erl_exit(1,"Internal error, unknown state %u in dynamic driver.", drv->handle->status);
+ erts_exit(ERTS_ERROR_EXIT,"Internal error, unknown state %u in dynamic driver.", drv->handle->status);
}
p->flags |= F_USING_DDLL;
r = add_monitor(p, drv->handle, ERL_DE_PROC_AWAIT_LOAD);
@@ -1730,11 +1732,7 @@ static void notify_proc(Process *proc, Eterm ref, Eterm driver_name, Eterm type,
hp += REF_THING_SIZE;
mess = TUPLE5(hp,type,r,am_driver,driver_name,tag);
}
- erts_queue_message(proc, &rp_locks, bp, mess, am_undefined
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(proc, &rp_locks, bp, mess, am_undefined);
erts_smp_proc_unlock(proc, rp_locks);
ERTS_SMP_CHK_NO_PROC_LOCKS;
}
diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c
index bbd8aa31d9..4a9a6a5fcd 100644
--- a/erts/emulator/beam/erl_bif_guard.c
+++ b/erts/emulator/beam/erl_bif_guard.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -459,23 +460,25 @@ Eterm erts_gc_byte_size_1(Process* p, Eterm* reg, Uint live)
Eterm erts_gc_map_size_1(Process* p, Eterm* reg, Uint live)
{
Eterm arg = reg[live];
- if (is_map(arg)) {
- map_t *mp = (map_t*)map_val(arg);
- Uint size = map_get_size(mp);
- if (IS_USMALL(0, size)) {
- return make_small(size);
- } else {
- Eterm* hp;
- if (ERTS_NEED_GC(p, BIG_UINT_HEAP_SIZE)) {
- erts_garbage_collect(p, BIG_UINT_HEAP_SIZE, reg, live);
- }
- hp = p->htop;
- p->htop += BIG_UINT_HEAP_SIZE;
- return uint_to_big(size, hp);
- }
- } else {
- BIF_ERROR(p, BADARG);
- }
+ if (is_flatmap(arg)) {
+ flatmap_t *mp = (flatmap_t*)flatmap_val(arg);
+ return make_small(flatmap_get_size(mp));
+ } else if (is_hashmap(arg)) {
+ Eterm* hp;
+ Uint size;
+ size = hashmap_size(arg);
+ if (IS_USMALL(0, size)) {
+ return make_small(size);
+ }
+ if (ERTS_NEED_GC(p, BIG_UINT_HEAP_SIZE)) {
+ erts_garbage_collect(p, BIG_UINT_HEAP_SIZE, reg, live);
+ }
+ hp = p->htop;
+ p->htop += BIG_UINT_HEAP_SIZE;
+ return uint_to_big(size, hp);
+ }
+ p->fvalue = arg;
+ BIF_ERROR(p, BADMAP);
}
Eterm erts_gc_abs_1(Process* p, Eterm* reg, Uint live)
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index b90362d82c..ac7a70c642 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -42,6 +43,7 @@
#include "erl_cpu_topology.h"
#include "erl_async.h"
#include "erl_thr_progress.h"
+#include "erl_bif_unique.h"
#define ERTS_PTAB_WANT_DEBUG_FUNCS__
#include "erl_ptab.h"
#ifdef HIPE
@@ -59,9 +61,11 @@
static Export* alloc_info_trap = NULL;
static Export* alloc_sizes_trap = NULL;
+static Export* gather_io_bytes_trap = NULL;
static Export *gather_sched_wall_time_res_trap;
static Export *gather_gc_info_res_trap;
+static Export *gather_system_check_res_trap;
#define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
@@ -116,6 +120,9 @@ static char erts_system_version[] = ("Erlang/OTP " ERLANG_OTP_RELEASE
#ifdef ERTS_ENABLE_LOCK_COUNT
" [lock-counting]"
#endif
+#ifdef ERTS_OPCODE_COUNTER_SUPPORT
+ " [instruction-counting]"
+#endif
#ifdef PURIFY
" [purify-compiled]"
#endif
@@ -537,6 +544,7 @@ pi_locks(Eterm info)
switch (info) {
case am_status:
case am_priority:
+ case am_trap_exit:
return ERTS_PROC_LOCK_STATUS;
case am_links:
case am_monitors:
@@ -589,7 +597,7 @@ static Eterm pi_args[] = {
am_min_bin_vheap_size,
am_current_location,
am_current_stacktrace,
-};
+};
#define ERTS_PI_ARGS ((int) (sizeof(pi_args)/sizeof(Eterm)))
@@ -907,7 +915,7 @@ BIF_RETTYPE process_info_1(BIF_ALIST_1)
case ERTS_PI_FAIL_TYPE_AWAIT_EXIT:
ERTS_BIF_AWAIT_X_DATA_TRAP(BIF_P, BIF_ARG_1, am_undefined);
default:
- erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error", __FILE__, __LINE__);
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error", __FILE__, __LINE__);
}
}
@@ -947,7 +955,7 @@ BIF_RETTYPE process_info_2(BIF_ALIST_2)
case ERTS_PI_FAIL_TYPE_AWAIT_EXIT:
ERTS_BIF_AWAIT_X_DATA_TRAP(BIF_P, BIF_ARG_1, am_undefined);
default:
- erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error",
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error",
__FILE__, __LINE__);
}
}
@@ -1049,9 +1057,9 @@ process_info_aux(Process *BIF_P,
case am_initial_call:
hp = HAlloc(BIF_P, 3+4);
res = TUPLE3(hp,
- rp->initial[INITIAL_MOD],
- rp->initial[INITIAL_FUN],
- make_small(rp->initial[INITIAL_ARI]));
+ rp->u.initial[INITIAL_MOD],
+ rp->u.initial[INITIAL_FUN],
+ make_small(rp->u.initial[INITIAL_ARI]));
hp += 4;
break;
@@ -1101,19 +1109,18 @@ process_info_aux(Process *BIF_P,
heap_need += mq[i].copy_struct_size;
}
else {
- mq[i].copy_struct_size = 0;
- if (mp->data.attached)
- heap_need += erts_msg_attached_data_size(mp);
+ mq[i].copy_struct_size = mp->data.attached ?
+ erts_msg_attached_data_size(mp) : 0;
}
i++;
}
- hp = HAlloc(BIF_P, heap_need);
- hp_end = hp + heap_need;
- ASSERT(i == n);
- for (i--; i >= 0; i--) {
- Eterm msg = ERL_MESSAGE_TERM(mq[i].msgp);
- if (rp != BIF_P) {
+ if (rp != BIF_P) {
+ hp = HAlloc(BIF_P, heap_need);
+ hp_end = hp + heap_need;
+ ASSERT(i == n);
+ for (i--; i >= 0; i--) {
+ Eterm msg = ERL_MESSAGE_TERM(mq[i].msgp);
if (is_value(msg)) {
if (mq[i].copy_struct_size)
msg = copy_struct(msg,
@@ -1147,9 +1154,9 @@ process_info_aux(Process *BIF_P,
}
else {
/* Make our copy of the message */
- ASSERT(size_object(msg) == hfp->used_size);
+ ASSERT(size_object(msg) == erts_used_frag_sz(hfp));
msg = copy_struct(msg,
- hfp->used_size,
+ erts_used_frag_sz(hfp),
&hp,
&MSO(BIF_P));
}
@@ -1159,27 +1166,38 @@ process_info_aux(Process *BIF_P,
remove_bad_messages = 1;
continue;
}
+ res = CONS(hp, msg, res);
+ hp += 2;
}
- else {
+ HRelease(BIF_P, hp_end, hp+3);
+ }
+ else {
+ for (i--; i >= 0; i--) {
+ ErtsHeapFactory factory;
+ Eterm msg = ERL_MESSAGE_TERM(mq[i].msgp);
+
+ erts_factory_proc_prealloc_init(&factory, BIF_P,
+ mq[i].copy_struct_size+2);
if (mq[i].msgp->data.attached) {
/* Decode it on the heap */
- erts_move_msg_attached_data_to_heap(&hp,
- &MSO(BIF_P),
+ erts_move_msg_attached_data_to_heap(&factory,
mq[i].msgp);
msg = ERL_MESSAGE_TERM(mq[i].msgp);
ASSERT(!mq[i].msgp->data.attached);
- if (is_non_value(msg)) {
- /* Bad distribution message; ignore */
- remove_bad_messages = 1;
- continue;
- }
- }
+ }
+ if (is_value(msg)) {
+ hp = erts_produce_heap(&factory, 2, 0);
+ res = CONS(hp, msg, res);
+ }
+ else {
+ /* Bad distribution message; ignore */
+ remove_bad_messages = 1;
+ continue;
+ }
+ erts_factory_close(&factory);
}
-
- res = CONS(hp, msg, res);
- hp += 2;
+ hp = HAlloc(BIF_P, 3);
}
- HRelease(BIF_P, hp_end, hp+3);
erts_free(ERTS_ALC_T_TMP, mq);
if (remove_bad_messages) {
ErlMessage **mpp;
@@ -1516,7 +1534,7 @@ process_info_aux(Process *BIF_P,
}
case am_last_calls: {
- struct saved_calls *scb = ERTS_PROC_GET_SAVED_CALLS_BUF(BIF_P);
+ struct saved_calls *scb = ERTS_PROC_GET_SAVED_CALLS_BUF(rp);
if (!scb) {
hp = HAlloc(BIF_P, 3);
res = am_false;
@@ -1742,7 +1760,7 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
return res;
buf = (char *) erts_alloc(ERTS_ALC_T_TMP, len+1);
if (intlist_to_buf(*tp, buf, len) != len)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error\n", __FILE__, __LINE__);
buf[len] = '\0';
res = erts_instr_dump_memory_map(buf) ? am_true : am_false;
erts_free(ERTS_ALC_T_TMP, (void *) buf);
@@ -1761,7 +1779,7 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
return res;
buf = (char *) erts_alloc(ERTS_ALC_T_TMP, len+1);
if (intlist_to_buf(tp[1], buf, len) != len)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error\n", __FILE__, __LINE__);
buf[len] = '\0';
res = erts_instr_dump_stat(buf, 1) ? am_true : am_false;
erts_free(ERTS_ALC_T_TMP, (void *) buf);
@@ -2099,6 +2117,50 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(am_opt);
#endif
BIF_RET(res);
+ } else if (BIF_ARG_1 == am_time_offset) {
+ switch (erts_time_offset_state()) {
+ case ERTS_TIME_OFFSET_PRELIMINARY: {
+ ERTS_DECL_AM(preliminary);
+ BIF_RET(AM_preliminary);
+ }
+ case ERTS_TIME_OFFSET_FINAL: {
+ ERTS_DECL_AM(final);
+ BIF_RET(AM_final);
+ }
+ case ERTS_TIME_OFFSET_VOLATILE: {
+ ERTS_DECL_AM(volatile);
+ BIF_RET(AM_volatile);
+ }
+ default:
+ ERTS_INTERNAL_ERROR("Invalid time offset state");
+ }
+ } else if (ERTS_IS_ATOM_STR("os_monotonic_time_source", BIF_ARG_1)) {
+ BIF_RET(erts_monotonic_time_source(BIF_P));
+ } else if (ERTS_IS_ATOM_STR("os_system_time_source", BIF_ARG_1)) {
+ BIF_RET(erts_system_time_source(BIF_P));
+ } else if (ERTS_IS_ATOM_STR("time_correction", BIF_ARG_1)) {
+ BIF_RET(erts_has_time_correction() ? am_true : am_false);
+ } else if (ERTS_IS_ATOM_STR("start_time", BIF_ARG_1)) {
+ BIF_RET(erts_get_monotonic_start_time(BIF_P));
+ } else if (ERTS_IS_ATOM_STR("end_time", BIF_ARG_1)) {
+ BIF_RET(erts_get_monotonic_end_time(BIF_P));
+ } else if (ERTS_IS_ATOM_STR("time_warp_mode", BIF_ARG_1)) {
+ switch (erts_time_warp_mode()) {
+ case ERTS_NO_TIME_WARP_MODE: {
+ ERTS_DECL_AM(no_time_warp);
+ BIF_RET(AM_no_time_warp);
+ }
+ case ERTS_SINGLE_TIME_WARP_MODE: {
+ ERTS_DECL_AM(single_time_warp);
+ BIF_RET(AM_single_time_warp);
+ }
+ case ERTS_MULTI_TIME_WARP_MODE: {
+ ERTS_DECL_AM(multi_time_warp);
+ BIF_RET(AM_multi_time_warp);
+ }
+ default:
+ ERTS_INTERNAL_ERROR("Invalid time warp mode");
+ }
} else if (BIF_ARG_1 == am_allocated_areas) {
res = erts_allocated_areas(NULL, NULL, BIF_P);
BIF_RET(res);
@@ -2301,7 +2363,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
for (i = num_instructions-1; i >= 0; i--) {
res = erts_bld_cons(hpp, hszp,
erts_bld_tuple(hpp, hszp, 2,
- erts_atom_put(opc[i].name,
+ erts_atom_put((byte *)opc[i].name,
strlen(opc[i].name),
ERTS_ATOM_ENC_LATIN1,
1),
@@ -2638,6 +2700,15 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
hp = hsz ? HAlloc(BIF_P, hsz) : NULL;
res = erts_bld_uint(&hp, NULL, erts_dist_buf_busy_limit);
BIF_RET(res);
+ } else if (ERTS_IS_ATOM_STR("delayed_node_table_gc", BIF_ARG_1)) {
+ Uint hsz = 0;
+ Uint dntgc = erts_delayed_node_table_gc();
+ if (dntgc == ERTS_NODE_TAB_DELAY_GC_INFINITY)
+ BIF_RET(am_infinity);
+ (void) erts_bld_uint(NULL, &hsz, dntgc);
+ hp = hsz ? HAlloc(BIF_P, hsz) : NULL;
+ res = erts_bld_uint(&hp, NULL, dntgc);
+ BIF_RET(res);
} else if (ERTS_IS_ATOM_STR("ethread_info", BIF_ARG_1)) {
BIF_RET(erts_get_ethread_info(BIF_P));
}
@@ -2700,9 +2771,11 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(make_small(erts_db_get_max_tabs()));
}
else if (ERTS_IS_ATOM_STR("tolerant_timeofday",BIF_ARG_1)) {
- BIF_RET(erts_disable_tolerant_timeofday
- ? am_disabled
- : am_enabled);
+ if (erts_has_time_correction()
+ && erts_time_offset_state() == ERTS_TIME_OFFSET_FINAL) {
+ BIF_RET(am_enabled);
+ }
+ BIF_RET(am_disabled);
}
else if (ERTS_IS_ATOM_STR("eager_check_io",BIF_ARG_1)) {
BIF_RET(erts_eager_check_io ? am_true : am_false);
@@ -3150,7 +3223,6 @@ BIF_RETTYPE process_display_2(BIF_ALIST_2)
BIF_RET(am_true);
}
-
/* this is a general call which return some possibly useful information */
BIF_RETTYPE statistics_1(BIF_ALIST_1)
@@ -3163,6 +3235,39 @@ BIF_RETTYPE statistics_1(BIF_ALIST_1)
if (is_non_value(res))
BIF_RET(am_undefined);
BIF_TRAP1(gather_sched_wall_time_res_trap, BIF_P, res);
+ } else if (BIF_ARG_1 == am_total_active_tasks
+ || BIF_ARG_1 == am_total_run_queue_lengths) {
+ Uint no = erts_run_queues_len(NULL, 0, BIF_ARG_1 == am_total_active_tasks);
+ if (IS_USMALL(0, no))
+ res = make_small(no);
+ else {
+ Eterm *hp = HAlloc(BIF_P, BIG_UINT_HEAP_SIZE);
+ res = uint_to_big(no, hp);
+ }
+ BIF_RET(res);
+ } else if (BIF_ARG_1 == am_active_tasks
+ || BIF_ARG_1 == am_run_queue_lengths) {
+ Eterm res, *hp, **hpp;
+ Uint sz, *szp;
+ int no_qs = erts_no_run_queues;
+ Uint *qszs = erts_alloc(ERTS_ALC_T_TMP,sizeof(Uint)*no_qs*2);
+ (void) erts_run_queues_len(qszs, 0, BIF_ARG_1 == am_active_tasks);
+ sz = 0;
+ szp = &sz;
+ hpp = NULL;
+ while (1) {
+ int i;
+ for (i = 0; i < no_qs; i++)
+ qszs[no_qs+i] = erts_bld_uint(hpp, szp, qszs[i]);
+ res = erts_bld_list(hpp, szp, no_qs, &qszs[no_qs]);
+ if (hpp) {
+ erts_free(ERTS_ALC_T_TMP, qszs);
+ BIF_RET(res);
+ }
+ hp = HAlloc(BIF_P, sz);
+ szp = NULL;
+ hpp = &hp;
+ }
} else if (BIF_ARG_1 == am_context_switches) {
Eterm cs = erts_make_integer(erts_get_total_context_switches(), BIF_P);
hp = HAlloc(BIF_P, 3);
@@ -3211,7 +3316,7 @@ BIF_RETTYPE statistics_1(BIF_ALIST_1)
res = TUPLE2(hp, b1, b2);
BIF_RET(res);
} else if (BIF_ARG_1 == am_run_queue) {
- res = erts_run_queues_len(NULL);
+ res = erts_run_queues_len(NULL, 1, 0);
BIF_RET(make_small(res));
} else if (BIF_ARG_1 == am_wall_clock) {
UWord w1, w2;
@@ -3223,30 +3328,15 @@ BIF_RETTYPE statistics_1(BIF_ALIST_1)
res = TUPLE2(hp, b1, b2);
BIF_RET(res);
} else if (BIF_ARG_1 == am_io) {
- Eterm r1, r2;
- Eterm in, out;
- Uint hsz = 9;
- Uint bytes_in = (Uint) erts_smp_atomic_read_nob(&erts_bytes_in);
- Uint bytes_out = (Uint) erts_smp_atomic_read_nob(&erts_bytes_out);
-
- (void) erts_bld_uint(NULL, &hsz, bytes_in);
- (void) erts_bld_uint(NULL, &hsz, bytes_out);
- hp = HAlloc(BIF_P, hsz);
- in = erts_bld_uint(&hp, NULL, bytes_in);
- out = erts_bld_uint(&hp, NULL, bytes_out);
-
- r1 = TUPLE2(hp, am_input, in);
- hp += 3;
- r2 = TUPLE2(hp, am_output, out);
- hp += 3;
- BIF_RET(TUPLE2(hp, r1, r2));
+ Eterm ref = erts_request_io_bytes(BIF_P);
+ BIF_TRAP2(gather_io_bytes_trap, BIF_P, ref, make_small(erts_no_schedulers));
}
else if (ERTS_IS_ATOM_STR("run_queues", BIF_ARG_1)) {
Eterm res, *hp, **hpp;
Uint sz, *szp;
int no_qs = erts_no_run_queues;
Uint *qszs = erts_alloc(ERTS_ALC_T_TMP,sizeof(Uint)*no_qs*2);
- (void) erts_run_queues_len(qszs);
+ (void) erts_run_queues_len(qszs, 0, 0);
sz = 0;
szp = &sz;
hpp = NULL;
@@ -3400,6 +3490,29 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
else if (ERTS_IS_ATOM_STR("mmap", BIF_ARG_1)) {
BIF_RET(erts_mmap_debug_info(BIF_P));
}
+ else if (ERTS_IS_ATOM_STR("unique_monotonic_integer_state", BIF_ARG_1)) {
+ BIF_RET(erts_debug_get_unique_monotonic_integer_state(BIF_P));
+ }
+ else if (ERTS_IS_ATOM_STR("min_unique_monotonic_integer", BIF_ARG_1)) {
+ Sint64 value = erts_get_min_unique_monotonic_integer();
+ if (IS_SSMALL(value))
+ BIF_RET(make_small(value));
+ else {
+ Uint hsz = ERTS_SINT64_HEAP_SIZE(value);
+ Eterm *hp = HAlloc(BIF_P, hsz);
+ BIF_RET(erts_sint64_to_big(value, &hp));
+ }
+ }
+ else if (ERTS_IS_ATOM_STR("min_unique_integer", BIF_ARG_1)) {
+ Sint64 value = erts_get_min_unique_integer();
+ if (IS_SSMALL(value))
+ BIF_RET(make_small(value));
+ else {
+ Uint hsz = ERTS_SINT64_HEAP_SIZE(value);
+ Eterm *hp = HAlloc(BIF_P, hsz);
+ BIF_RET(erts_sint64_to_big(value, &hp));
+ }
+ }
}
else if (is_tuple(BIF_ARG_1)) {
Eterm* tp = tuple_val(BIF_ARG_1);
@@ -3594,6 +3707,58 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
BIF_RET(erts_debug_reader_groups_map(BIF_P, (int) groups));
}
+ else if (ERTS_IS_ATOM_STR("internal_hash", tp[1])) {
+ Uint hash = (Uint) make_internal_hash(tp[2]);
+ Uint hsz = 0;
+ Eterm* hp;
+ erts_bld_uint(NULL, &hsz, hash);
+ hp = HAlloc(BIF_P,hsz);
+ return erts_bld_uint(&hp, NULL, hash);
+ }
+ else if (ERTS_IS_ATOM_STR("atom", tp[1])) {
+ Uint ix;
+ if (!term_to_Uint(tp[2], &ix))
+ BIF_ERROR(BIF_P, BADARG);
+ while (ix >= atom_table_size()) {
+ char tmp[20];
+ erts_snprintf(tmp, sizeof(tmp), "am%x", atom_table_size());
+ erts_atom_put((byte *) tmp, strlen(tmp), ERTS_ATOM_ENC_LATIN1, 1);
+ }
+ return make_atom(ix);
+ }
+
+ break;
+ }
+ case 3: {
+ if (ERTS_IS_ATOM_STR("check_time_config", tp[1])) {
+ int res, time_correction;
+ ErtsTimeWarpMode time_warp_mode;
+ if (tp[2] == am_true)
+ time_correction = !0;
+ else if (tp[2] == am_false)
+ time_correction = 0;
+ else
+ break;
+ if (ERTS_IS_ATOM_STR("no_time_warp", tp[3]))
+ time_warp_mode = ERTS_NO_TIME_WARP_MODE;
+ else if (ERTS_IS_ATOM_STR("single_time_warp", tp[3]))
+ time_warp_mode = ERTS_SINGLE_TIME_WARP_MODE;
+ else if (ERTS_IS_ATOM_STR("multi_time_warp", tp[3]))
+ time_warp_mode = ERTS_MULTI_TIME_WARP_MODE;
+ else
+ break;
+ res = erts_check_time_adj_support(time_correction,
+ time_warp_mode);
+ BIF_RET(res ? am_true : am_false);
+ }
+ else if (ERTS_IS_ATOM_STR("make_unique_integer", tp[1])) {
+ Eterm res = erts_debug_make_unique_integer(BIF_P,
+ tp[2],
+ tp[3]);
+ if (is_non_value(res))
+ break;
+ BIF_RET(res);
+ }
break;
}
default:
@@ -3603,8 +3768,52 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
BIF_ERROR(BIF_P, BADARG);
}
+BIF_RETTYPE erts_internal_is_system_process_1(BIF_ALIST_1)
+{
+ if (is_internal_pid(BIF_ARG_1)) {
+ Process *rp = erts_proc_lookup(BIF_ARG_1);
+ if (rp && (rp->static_flags & ERTS_STC_FLG_SYSTEM_PROC))
+ BIF_RET(am_true);
+ BIF_RET(am_false);
+ }
+
+ if (is_external_pid(BIF_ARG_1)
+ && external_pid_dist_entry(BIF_ARG_1) == erts_this_dist_entry) {
+ BIF_RET(am_false);
+ }
+
+ BIF_ERROR(BIF_P, BADARG);
+}
+
+BIF_RETTYPE erts_internal_system_check_1(BIF_ALIST_1)
+{
+ Eterm res;
+ if (ERTS_IS_ATOM_STR("schedulers", BIF_ARG_1)) {
+ res = erts_system_check_request(BIF_P);
+ if (is_non_value(res))
+ BIF_RET(am_undefined);
+ BIF_TRAP1(gather_system_check_res_trap, BIF_P, res);
+ }
+
+ BIF_ERROR(BIF_P, BADARG);
+}
+
static erts_smp_atomic_t hipe_test_reschedule_flag;
+#if defined(VALGRIND) && defined(__GNUC__)
+/* Force noinline for valgrind suppression */
+static void broken_halt_test(Eterm bif_arg_2) __attribute__((noinline));
+#endif
+
+static void broken_halt_test(Eterm bif_arg_2)
+{
+ /* Ugly ugly code used by bif_SUITE:erlang_halt/1 */
+#if defined(ERTS_HAVE_TRY_CATCH)
+ erts_get_scheduler_data()->run_queue = NULL;
+#endif
+ erts_exit(ERTS_DUMP_EXIT, "%T", bif_arg_2);
+}
+
BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
{
@@ -3849,7 +4058,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
BIF_RET(am_true);
}
else if (ERTS_IS_ATOM_STR("abort", BIF_ARG_1)) {
- erl_exit(ERTS_ABORT_EXIT, "%T\n", BIF_ARG_2);
+ erts_exit(ERTS_ABORT_EXIT, "%T\n", BIF_ARG_2);
}
else if (ERTS_IS_ATOM_STR("kill_dist_connection", BIF_ARG_1)) {
DistEntry *dep = erts_sysname_to_connected_dist_entry(BIF_ARG_2);
@@ -3892,11 +4101,36 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
}
else if (ERTS_IS_ATOM_STR("wait", BIF_ARG_1)) {
if (ERTS_IS_ATOM_STR("deallocations", BIF_ARG_2)) {
- if (erts_debug_wait_deallocations(BIF_P)) {
+ int flag = ERTS_DEBUG_WAIT_COMPLETED_DEALLOCATIONS;
+ if (erts_debug_wait_completed(BIF_P, flag)) {
+ ERTS_BIF_YIELD_RETURN(BIF_P, am_ok);
+ }
+ }
+ if (ERTS_IS_ATOM_STR("timer_cancellations", BIF_ARG_2)) {
+ int flag = ERTS_DEBUG_WAIT_COMPLETED_TIMER_CANCELLATIONS;
+ if (erts_debug_wait_completed(BIF_P, flag)) {
ERTS_BIF_YIELD_RETURN(BIF_P, am_ok);
}
}
}
+ else if (ERTS_IS_ATOM_STR("broken_halt", BIF_ARG_1)) {
+ broken_halt_test(BIF_ARG_2);
+ }
+ else if (ERTS_IS_ATOM_STR("unique_monotonic_integer_state", BIF_ARG_1)) {
+ int res = erts_debug_set_unique_monotonic_integer_state(BIF_ARG_2);
+ BIF_RET(res ? am_true : am_false);
+ }
+ else if (ERTS_IS_ATOM_STR("node_tab_delayed_delete", BIF_ARG_1)) {
+ /* node_container_SUITE */
+ Sint64 msecs;
+ if (term_to_Sint64(BIF_ARG_2, &msecs)) {
+ /* Negative value restore original value... */
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_debug_test_node_tab_delayed_delete(msecs);
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ BIF_RET(am_ok);
+ }
+ }
}
BIF_ERROR(BIF_P, BADARG);
@@ -4094,59 +4328,41 @@ BIF_RETTYPE erts_debug_lock_counters_1(BIF_ALIST_1)
BIF_RET(am_ok);
} else if (is_tuple(BIF_ARG_1)) {
- Eterm* tp = tuple_val(BIF_ARG_1);
-
- switch (arityval(tp[0])) {
- case 2: {
- int opt = 0;
- int val = 0;
- if (ERTS_IS_ATOM_STR("copy_save", tp[1])) {
- opt = ERTS_LCNT_OPT_COPYSAVE;
- } else if (ERTS_IS_ATOM_STR("process_locks", tp[1])) {
- opt = ERTS_LCNT_OPT_PROCLOCK;
- } else if (ERTS_IS_ATOM_STR("port_locks", tp[1])) {
- opt = ERTS_LCNT_OPT_PORTLOCK;
- } else if (ERTS_IS_ATOM_STR("suspend", tp[1])) {
- opt = ERTS_LCNT_OPT_SUSPEND;
- } else if (ERTS_IS_ATOM_STR("location", tp[1])) {
- opt = ERTS_LCNT_OPT_LOCATION;
- } else {
- BIF_ERROR(BIF_P, BADARG);
- }
- if (tp[2] == am_true) {
- val = 1;
- } else if (tp[2] == am_false) {
- val = 0;
- } else {
- BIF_ERROR(BIF_P, BADARG);
- }
-
- erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erts_smp_thr_progress_block();
-
- if (val) {
- res = erts_lcnt_set_rt_opt(opt) ? am_true : am_false;
- } else {
- res = erts_lcnt_clear_rt_opt(opt) ? am_true : am_false;
- }
+ Eterm* ptr = tuple_val(BIF_ARG_1);
+
+ if ((arityval(ptr[0]) == 2) && (ptr[2] == am_false || ptr[2] == am_true)) {
+ int lock_opt = 0, enable = (ptr[2] == am_true) ? 1 : 0;
+ if (ERTS_IS_ATOM_STR("copy_save", ptr[1])) {
+ lock_opt = ERTS_LCNT_OPT_COPYSAVE;
+ } else if (ERTS_IS_ATOM_STR("process_locks", ptr[1])) {
+ lock_opt = ERTS_LCNT_OPT_PROCLOCK;
+ } else if (ERTS_IS_ATOM_STR("port_locks", ptr[1])) {
+ lock_opt = ERTS_LCNT_OPT_PORTLOCK;
+ } else if (ERTS_IS_ATOM_STR("suspend", ptr[1])) {
+ lock_opt = ERTS_LCNT_OPT_SUSPEND;
+ } else if (ERTS_IS_ATOM_STR("location", ptr[1])) {
+ lock_opt = ERTS_LCNT_OPT_LOCATION;
+ } else {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_thr_progress_block();
+
+ if (enable) res = erts_lcnt_set_rt_opt(lock_opt) ? am_true : am_false;
+ else res = erts_lcnt_clear_rt_opt(lock_opt) ? am_true : am_false;
+
#ifdef ERTS_SMP
- if (res != tp[2]) {
- if (opt == ERTS_LCNT_OPT_PORTLOCK) {
- erts_lcnt_enable_io_lock_count(val);
- } else if (opt == ERTS_LCNT_OPT_PROCLOCK) {
- erts_lcnt_enable_proc_lock_count(val);
- }
- }
+ if (res != ptr[2] && lock_opt == ERTS_LCNT_OPT_PORTLOCK) {
+ erts_lcnt_enable_io_lock_count(enable);
+ } else if (res != ptr[2] && lock_opt == ERTS_LCNT_OPT_PROCLOCK) {
+ erts_lcnt_enable_proc_lock_count(enable);
+ }
#endif
- erts_smp_thr_progress_unblock();
- erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
- BIF_RET(res);
- break;
- }
-
- default:
- break;
- }
+ erts_smp_thr_progress_unblock();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ BIF_RET(res);
+ }
}
#endif
@@ -4186,6 +4402,10 @@ erts_bif_info_init(void)
= erts_export_put(am_erlang, am_gather_sched_wall_time_result, 1);
gather_gc_info_res_trap
= erts_export_put(am_erlang, am_gather_gc_info_result, 1);
+ gather_io_bytes_trap
+ = erts_export_put(am_erts_internal, am_gather_io_bytes, 2);
+ gather_system_check_res_trap
+ = erts_export_put(am_erts_internal, am_gather_system_check_result, 1);
process_info_init();
os_info_init();
}
diff --git a/erts/emulator/beam/erl_bif_lists.c b/erts/emulator/beam/erl_bif_lists.c
index 820ed2385d..5583dcb371 100644
--- a/erts/emulator/beam/erl_bif_lists.c
+++ b/erts/emulator/beam/erl_bif_lists.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -390,7 +391,7 @@ keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List)
Eterm *tuple_ptr = tuple_val(term);
if (pos <= arityval(*tuple_ptr)) {
Eterm element = tuple_ptr[pos];
- if (CMP(Key, element) == 0) {
+ if (CMP_EQ(Key, element)) {
return term;
}
}
diff --git a/erts/emulator/beam/erl_bif_op.c b/erts/emulator/beam/erl_bif_op.c
index 37dd6457db..c9192fc420 100644
--- a/erts/emulator/beam/erl_bif_op.c
+++ b/erts/emulator/beam/erl_bif_op.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_bif_os.c b/erts/emulator/beam/erl_bif_os.c
index e07c622928..2333ca0851 100644
--- a/erts/emulator/beam/erl_bif_os.c
+++ b/erts/emulator/beam/erl_bif_os.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 7ce950e090..27c24197ea 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -790,7 +791,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_typep, int *err_nump)
} else {
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1);
if (intlist_to_buf(name, name_buf, i) != i)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error\n", __FILE__, __LINE__);
name_buf[i] = '\0';
}
driver = &vanilla_driver;
@@ -1168,7 +1169,7 @@ static Eterm http_bld_uri(struct packet_callback_args* pca,
return erts_bld_tuple(hpp, szp, 3, am_scheme, s1, s2);
default:
- erl_exit(1, "%s, line %d: type=%u\n", __FILE__, __LINE__, uri->type);
+ erts_exit(ERTS_ERROR_EXIT, "%s, line %d: type=%u\n", __FILE__, __LINE__, uri->type);
}
}
@@ -1328,7 +1329,8 @@ BIF_RETTYPE decode_packet_3(BIF_ALIST_3)
ErlSubBin* rest;
Eterm res;
Eterm options;
- int code;
+ int code;
+ char delimiter = '\n';
if (!is_binary(BIF_ARG_2) ||
(!is_list(BIF_ARG_3) && !is_nil(BIF_ARG_3))) {
@@ -1369,6 +1371,11 @@ BIF_RETTYPE decode_packet_3(BIF_ALIST_3)
case am_line_length:
trunc_len = val;
goto next_option;
+ case am_line_delimiter:
+ if (type == TCP_PB_LINE_LF && val >= 0 && val <= 255) {
+ delimiter = (char)val;
+ goto next_option;
+ }
}
}
}
@@ -1389,7 +1396,7 @@ BIF_RETTYPE decode_packet_3(BIF_ALIST_3)
pca.aligned_ptr = bin_ptr;
}
packet_sz = packet_get_length(type, (char*)pca.aligned_ptr, pca.bin_sz,
- max_plen, trunc_len, &http_state);
+ max_plen, trunc_len, delimiter, &http_state);
if (!(packet_sz > 0 && packet_sz <= pca.bin_sz)) {
if (packet_sz < 0) {
goto error;
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index 448c6f6f6d..86951f32b0 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c
deleted file mode 100644
index 03ac97283c..0000000000
--- a/erts/emulator/beam/erl_bif_timer.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2005-2012. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "erl_bif_timer.h"
-#include "global.h"
-#include "bif.h"
-#include "error.h"
-#include "big.h"
-#include "erl_thr_progress.h"
-
-/****************************************************************************
-** BIF Timer support
-****************************************************************************/
-
-#define BTM_FLG_SL_TIMER (((Uint32) 1) << 0)
-#define BTM_FLG_CANCELED (((Uint32) 1) << 1)
-#define BTM_FLG_HEAD (((Uint32) 1) << 2)
-#define BTM_FLG_BYNAME (((Uint32) 1) << 3)
-#define BTM_FLG_WRAP (((Uint32) 1) << 4)
-
-struct ErtsBifTimer_ {
- struct {
- union {
- ErtsBifTimer **head;
- ErtsBifTimer *prev;
- } u;
- ErtsBifTimer *next;
- } tab;
- union {
- Eterm name;
- struct {
- ErtsBifTimer *prev;
- ErtsBifTimer *next;
- Process *ess;
- } proc;
- } receiver;
- ErlTimer tm;
- ErlHeapFragment* bp;
- Uint32 flags;
- Eterm message;
- Uint32 ref_numbers[ERTS_REF_NUMBERS];
-};
-
-#ifdef SMALL_MEMORY
-#define TIMER_HASH_VEC_SZ 3331
-#define BTM_PREALC_SZ 10
-#else
-#define TIMER_HASH_VEC_SZ 10007
-#define BTM_PREALC_SZ 100
-#endif
-static ErtsBifTimer **bif_timer_tab;
-static Uint no_bif_timers;
-
-
-static erts_smp_rwmtx_t bif_timer_lock;
-
-#define erts_smp_safe_btm_rwlock(P, L) \
- safe_btm_lock((P), (L), 1)
-#define erts_smp_safe_btm_rlock(P, L) \
- safe_btm_lock((P), (L), 0)
-#define erts_smp_btm_rwlock() \
- erts_smp_rwmtx_rwlock(&bif_timer_lock)
-#define erts_smp_btm_tryrwlock() \
- erts_smp_rwmtx_tryrwlock(&bif_timer_lock)
-#define erts_smp_btm_rwunlock() \
- erts_smp_rwmtx_rwunlock(&bif_timer_lock)
-#define erts_smp_btm_rlock() \
- erts_smp_rwmtx_rlock(&bif_timer_lock)
-#define erts_smp_btm_tryrlock() \
- erts_smp_rwmtx_tryrlock(&bif_timer_lock)
-#define erts_smp_btm_runlock() \
- erts_smp_rwmtx_runlock(&bif_timer_lock)
-#define erts_smp_btm_lock_init() \
- erts_smp_rwmtx_init(&bif_timer_lock, "bif_timers")
-
-
-static ERTS_INLINE int
-safe_btm_lock(Process *c_p, ErtsProcLocks c_p_locks, int rw_lock)
-{
- ASSERT(c_p && c_p_locks);
-#ifdef ERTS_SMP
- if ((rw_lock ? erts_smp_btm_tryrwlock() : erts_smp_btm_tryrlock()) != EBUSY)
- return 0;
- erts_smp_proc_unlock(c_p, c_p_locks);
- if (rw_lock)
- erts_smp_btm_rwlock();
- else
- erts_smp_btm_rlock();
- erts_smp_proc_lock(c_p, c_p_locks);
- if (ERTS_PROC_IS_EXITING(c_p)) {
- if (rw_lock)
- erts_smp_btm_rwunlock();
- else
- erts_smp_btm_runlock();
- return 1;
- }
-#endif
- return 0;
-}
-
-ERTS_SCHED_PREF_PALLOC_IMPL(btm_pre, ErtsBifTimer, BTM_PREALC_SZ)
-
-static ERTS_INLINE int
-get_index(Uint32 *ref_numbers, Uint32 len)
-{
- Uint32 hash;
- /* len can potentially be larger than ERTS_REF_NUMBERS
- if it has visited another node... */
- if (len > ERTS_REF_NUMBERS)
- len = ERTS_REF_NUMBERS;
-
-#if ERTS_REF_NUMBERS != 3
-#error "ERTS_REF_NUMBERS changed. Update me..."
-#endif
- switch (len) {
- case 3: if (!ref_numbers[2]) len = 2;
- case 2: if (!ref_numbers[1]) len = 1;
- default: break;
- }
-
- ASSERT(1 <= len && len <= ERTS_REF_NUMBERS);
-
- hash = block_hash((byte *) ref_numbers, len * sizeof(Uint32), 0x08d12e65);
- return (int) (hash % ((Uint32) TIMER_HASH_VEC_SZ));
-}
-
-static Eterm
-create_ref(Uint *hp, Uint32 *ref_numbers, Uint32 len)
-{
- Uint32 *datap;
- int i;
-
-
- if (len > ERTS_MAX_REF_NUMBERS) {
- /* Such large refs should no be able to appear in the emulator */
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
- }
-
-#if defined(ARCH_64) && !HALFWORD_HEAP
- hp[0] = make_ref_thing_header(len/2 + 1);
- datap = (Uint32 *) &hp[1];
- *(datap++) = len;
-#else
- hp[0] = make_ref_thing_header(len);
- datap = (Uint32 *) &hp[1];
-#endif
-
- for (i = 0; i < len; i++)
- datap[i] = ref_numbers[i];
-
- return make_internal_ref(hp);
-}
-
-static int
-eq_non_standard_ref_numbers(Uint32 *rn1, Uint32 len1, Uint32 *rn2, Uint32 len2)
-{
-#if defined(ARCH_64) && !HALFWORD_HEAP
-#define MAX_REF_HEAP_SZ (1+(ERTS_MAX_REF_NUMBERS/2+1))
-#else
-#define MAX_REF_HEAP_SZ (1+ERTS_MAX_REF_NUMBERS)
-#endif
- DeclareTmpHeapNoproc(r1_hp,(MAX_REF_HEAP_SZ * 2));
- Eterm *r2_hp = r1_hp +MAX_REF_HEAP_SZ;
-
- return eq(create_ref(r1_hp, rn1, len1), create_ref(r2_hp, rn2, len2));
-#undef MAX_REF_HEAP_SZ
-}
-
-static ERTS_INLINE int
-eq_ref_numbers(Uint32 *rn1, Uint32 len1, Uint32 *rn2, Uint32 len2)
-{
- int res;
- if (len1 != ERTS_REF_NUMBERS || len2 != ERTS_REF_NUMBERS) {
- /* Can potentially happen, but will never... */
- return eq_non_standard_ref_numbers(rn1, len1, rn2, len2);
- }
-
-#if ERTS_REF_NUMBERS != 3
-#error "ERTS_REF_NUMBERS changed. Update me..."
-#endif
- res = rn1[0] == rn2[0] && rn1[1] == rn2[1] && rn1[2] == rn2[2];
-
- ASSERT(res
- ? eq_non_standard_ref_numbers(rn1, len1, rn2, len2)
- : !eq_non_standard_ref_numbers(rn1, len1, rn2, len2));
-
- return res;
-}
-
-static ERTS_INLINE ErtsBifTimer *
-tab_find(Eterm ref)
-{
- Uint32 *ref_numbers = internal_ref_numbers(ref);
- Uint32 ref_numbers_len = internal_ref_no_of_numbers(ref);
- int ix = get_index(ref_numbers, ref_numbers_len);
- ErtsBifTimer* btm;
-
- for (btm = bif_timer_tab[ix]; btm; btm = btm->tab.next)
- if (eq_ref_numbers(ref_numbers, ref_numbers_len,
- btm->ref_numbers, ERTS_REF_NUMBERS))
- return btm;
- return NULL;
-}
-
-static ERTS_INLINE void
-tab_remove(ErtsBifTimer* btm)
-{
- if (btm->flags & BTM_FLG_HEAD) {
- *btm->tab.u.head = btm->tab.next;
- if (btm->tab.next) {
- btm->tab.next->flags |= BTM_FLG_HEAD;
- btm->tab.next->tab.u.head = btm->tab.u.head;
- }
- }
- else {
- btm->tab.u.prev->tab.next = btm->tab.next;
- if (btm->tab.next)
- btm->tab.next->tab.u.prev = btm->tab.u.prev;
- }
- btm->flags |= BTM_FLG_CANCELED;
- ASSERT(no_bif_timers > 0);
- no_bif_timers--;
-}
-
-static ERTS_INLINE void
-tab_insert(ErtsBifTimer* btm)
-{
- int ix = get_index(btm->ref_numbers, ERTS_REF_NUMBERS);
- ErtsBifTimer* btm_list = bif_timer_tab[ix];
-
- if (btm_list) {
- btm_list->flags &= ~BTM_FLG_HEAD;
- btm_list->tab.u.prev = btm;
- }
-
- btm->flags |= BTM_FLG_HEAD;
- btm->tab.u.head = &bif_timer_tab[ix];
- btm->tab.next = btm_list;
- bif_timer_tab[ix] = btm;
- no_bif_timers++;
-}
-
-static ERTS_INLINE void
-link_proc(Process *p, ErtsBifTimer* btm)
-{
- btm->receiver.proc.ess = p;
- btm->receiver.proc.prev = NULL;
- btm->receiver.proc.next = p->u.bif_timers;
- if (p->u.bif_timers)
- p->u.bif_timers->receiver.proc.prev = btm;
- p->u.bif_timers = btm;
-}
-
-static ERTS_INLINE void
-unlink_proc(ErtsBifTimer* btm)
-{
- if (btm->receiver.proc.prev)
- btm->receiver.proc.prev->receiver.proc.next = btm->receiver.proc.next;
- else
- btm->receiver.proc.ess->u.bif_timers = btm->receiver.proc.next;
- if (btm->receiver.proc.next)
- btm->receiver.proc.next->receiver.proc.prev = btm->receiver.proc.prev;
-}
-
-static void
-bif_timer_cleanup(ErtsBifTimer* btm)
-{
- ASSERT(btm);
-
- if (btm->bp)
- free_message_buffer(btm->bp);
-
- if (!btm_pre_free(btm)) {
- if (btm->flags & BTM_FLG_SL_TIMER)
- erts_free(ERTS_ALC_T_SL_BIF_TIMER, (void *) btm);
- else
- erts_free(ERTS_ALC_T_LL_BIF_TIMER, (void *) btm);
- }
-}
-
-static void
-bif_timer_timeout(ErtsBifTimer* btm)
-{
- ASSERT(btm);
-
-
- erts_smp_btm_rwlock();
-
- if (btm->flags & BTM_FLG_CANCELED) {
- /*
- * A concurrent cancel is ongoing. Do not send the timeout message,
- * but cleanup here since the cancel call-back won't be called.
- */
-#ifndef ERTS_SMP
- ASSERT(0);
-#endif
- }
- else {
- ErtsProcLocks rp_locks = 0;
- Process* rp;
-
- tab_remove(btm);
-
- ASSERT(!erts_get_current_process());
-
- if (btm->flags & BTM_FLG_BYNAME)
- rp = erts_whereis_process(NULL, 0, btm->receiver.name, 0, 0);
- else {
- rp = btm->receiver.proc.ess;
- unlink_proc(btm);
- }
-
- if (rp) {
- Eterm message;
- ErlHeapFragment *bp;
-
- bp = btm->bp;
- btm->bp = NULL; /* Prevent cleanup of message buffer... */
-
- if (!(btm->flags & BTM_FLG_WRAP))
- message = btm->message;
- else {
-#if ERTS_REF_NUMBERS != 3
-#error "ERTS_REF_NUMBERS changed. Update me..."
-#endif
- Eterm ref;
- Uint *hp;
- Uint wrap_size = REF_THING_SIZE + 4;
- message = btm->message;
-
- if (!bp) {
- ErlOffHeap *ohp;
- ASSERT(is_immed(message));
- hp = erts_alloc_message_heap(wrap_size,
- &bp,
- &ohp,
- rp,
- &rp_locks);
- } else {
- Eterm old_size = bp->used_size;
- bp = erts_resize_message_buffer(bp, old_size + wrap_size,
- &message, 1);
- hp = &bp->mem[0] + old_size;
- }
-
- write_ref_thing(hp,
- btm->ref_numbers[0],
- btm->ref_numbers[1],
- btm->ref_numbers[2]);
- ref = make_internal_ref(hp);
- hp += REF_THING_SIZE;
- message = TUPLE3(hp, am_timeout, ref, message);
- }
-
- erts_queue_message(rp, &rp_locks, bp, message, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
- erts_smp_proc_unlock(rp, rp_locks);
- }
- }
-
- erts_smp_btm_rwunlock();
-
- bif_timer_cleanup(btm);
-}
-
-static Eterm
-setup_bif_timer(Uint32 xflags,
- Process *c_p,
- Eterm time,
- Eterm receiver,
- Eterm message)
-{
- Process *rp;
- ErtsBifTimer* btm;
- Uint timeout;
- Eterm ref;
- Uint32 *ref_numbers;
-
- if (!term_to_Uint(time, &timeout))
- return THE_NON_VALUE;
-#if defined(ARCH_64) && !HALFWORD_HEAP
- if ((timeout >> 32) != 0)
- return THE_NON_VALUE;
-#endif
- if (is_not_internal_pid(receiver) && is_not_atom(receiver))
- return THE_NON_VALUE;
-
- ref = erts_make_ref(c_p);
-
- if (is_atom(receiver))
- rp = NULL;
- else {
- rp = erts_pid2proc(c_p, ERTS_PROC_LOCK_MAIN,
- receiver, ERTS_PROC_LOCK_MSGQ);
- if (!rp)
- return ref;
- }
-
- if (timeout < ERTS_ALC_MIN_LONG_LIVED_TIME) {
- if (timeout < 1000) {
- btm = btm_pre_alloc();
- if (!btm)
- goto sl_timer_alloc;
- btm->flags = 0;
- }
- else {
- sl_timer_alloc:
- btm = (ErtsBifTimer *) erts_alloc(ERTS_ALC_T_SL_BIF_TIMER,
- sizeof(ErtsBifTimer));
- btm->flags = BTM_FLG_SL_TIMER;
- }
- }
- else {
- btm = (ErtsBifTimer *) erts_alloc(ERTS_ALC_T_LL_BIF_TIMER,
- sizeof(ErtsBifTimer));
- btm->flags = 0;
- }
-
- if (rp) {
- link_proc(rp, btm);
- erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ);
- }
- else {
- ASSERT(is_atom(receiver));
- btm->receiver.name = receiver;
- btm->flags |= BTM_FLG_BYNAME;
- }
-
- btm->flags |= xflags;
-
- ref_numbers = internal_ref_numbers(ref);
- ASSERT(internal_ref_no_of_numbers(ref) == 3);
-#if ERTS_REF_NUMBERS != 3
-#error "ERTS_REF_NUMBERS changed. Update me..."
-#endif
- btm->ref_numbers[0] = ref_numbers[0];
- btm->ref_numbers[1] = ref_numbers[1];
- btm->ref_numbers[2] = ref_numbers[2];
-
- ASSERT(eq_ref_numbers(btm->ref_numbers, ERTS_REF_NUMBERS,
- ref_numbers, ERTS_REF_NUMBERS));
-
- if (is_immed(message)) {
- btm->bp = NULL;
- btm->message = message;
- }
- else {
- ErlHeapFragment* bp;
- Eterm* hp;
- Uint size;
-
- size = size_object(message);
- btm->bp = bp = new_message_buffer(size);
- hp = bp->mem;
- btm->message = copy_struct(message, size, &hp, &bp->off_heap);
- }
-
- tab_insert(btm);
- ASSERT(btm == tab_find(ref));
- btm->tm.active = 0; /* MUST be initalized */
- erts_set_timer(&btm->tm,
- (ErlTimeoutProc) bif_timer_timeout,
- (ErlCancelProc) bif_timer_cleanup,
- (void *) btm,
- timeout);
- return ref;
-}
-
-/* send_after(Time, Pid, Message) -> Ref */
-BIF_RETTYPE send_after_3(BIF_ALIST_3)
-{
- Eterm res;
-
- if (erts_smp_safe_btm_rwlock(BIF_P, ERTS_PROC_LOCK_MAIN))
- ERTS_BIF_EXITED(BIF_P);
-
- res = setup_bif_timer(0, BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
-
- erts_smp_btm_rwunlock();
-
- if (is_non_value(res)) {
- BIF_ERROR(BIF_P, BADARG);
- }
- else {
- ASSERT(is_internal_ref(res));
- BIF_RET(res);
- }
-}
-
-/* start_timer(Time, Pid, Message) -> Ref */
-BIF_RETTYPE start_timer_3(BIF_ALIST_3)
-{
- Eterm res;
-
- if (erts_smp_safe_btm_rwlock(BIF_P, ERTS_PROC_LOCK_MAIN))
- ERTS_BIF_EXITED(BIF_P);
-
- res = setup_bif_timer(BTM_FLG_WRAP, BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
-
- erts_smp_btm_rwunlock();
-
- if (is_non_value(res)) {
- BIF_ERROR(BIF_P, BADARG);
- }
- else {
- ASSERT(is_internal_ref(res));
- BIF_RET(res);
- }
-}
-
-/* cancel_timer(Ref) -> false | RemainingTime */
-BIF_RETTYPE cancel_timer_1(BIF_ALIST_1)
-{
- Eterm res;
- ErtsBifTimer *btm;
-
- if (is_not_internal_ref(BIF_ARG_1)) {
- if (is_ref(BIF_ARG_1)) {
- BIF_RET(am_false);
- }
- BIF_ERROR(BIF_P, BADARG);
- }
-
- if (erts_smp_safe_btm_rwlock(BIF_P, ERTS_PROC_LOCK_MAIN))
- ERTS_BIF_EXITED(BIF_P);
-
- btm = tab_find(BIF_ARG_1);
- if (!btm || btm->flags & BTM_FLG_CANCELED) {
- erts_smp_btm_rwunlock();
- res = am_false;
- }
- else {
- Uint left = erts_time_left(&btm->tm);
- if (!(btm->flags & BTM_FLG_BYNAME)) {
- erts_smp_proc_lock(btm->receiver.proc.ess, ERTS_PROC_LOCK_MSGQ);
- unlink_proc(btm);
- erts_smp_proc_unlock(btm->receiver.proc.ess, ERTS_PROC_LOCK_MSGQ);
- }
- tab_remove(btm);
- ASSERT(!tab_find(BIF_ARG_1));
- erts_cancel_timer(&btm->tm);
- erts_smp_btm_rwunlock();
- res = erts_make_integer(left, BIF_P);
- }
-
- BIF_RET(res);
-}
-
-/* read_timer(Ref) -> false | RemainingTime */
-BIF_RETTYPE read_timer_1(BIF_ALIST_1)
-{
- Eterm res;
- ErtsBifTimer *btm;
-
- if (is_not_internal_ref(BIF_ARG_1)) {
- if (is_ref(BIF_ARG_1)) {
- BIF_RET(am_false);
- }
- BIF_ERROR(BIF_P, BADARG);
- }
-
- if (erts_smp_safe_btm_rlock(BIF_P, ERTS_PROC_LOCK_MAIN))
- ERTS_BIF_EXITED(BIF_P);
-
- btm = tab_find(BIF_ARG_1);
- if (!btm || btm->flags & BTM_FLG_CANCELED) {
- res = am_false;
- }
- else {
- Uint left = erts_time_left(&btm->tm);
- res = erts_make_integer(left, BIF_P);
- }
-
- erts_smp_btm_runlock();
-
- BIF_RET(res);
-}
-
-void
-erts_print_bif_timer_info(int to, void *to_arg)
-{
- int i;
- int lock = !ERTS_IS_CRASH_DUMPING;
-
- if (lock)
- erts_smp_btm_rlock();
-
- for (i = 0; i < TIMER_HASH_VEC_SZ; i++) {
- ErtsBifTimer *btm;
- for (btm = bif_timer_tab[i]; btm; btm = btm->tab.next) {
- Eterm receiver = (btm->flags & BTM_FLG_BYNAME
- ? btm->receiver.name
- : btm->receiver.proc.ess->common.id);
- erts_print(to, to_arg, "=timer:%T\n", receiver);
- erts_print(to, to_arg, "Message: %T\n", btm->message);
- erts_print(to, to_arg, "Time left: %u\n",
- erts_time_left(&btm->tm));
- }
- }
-
- if (lock)
- erts_smp_btm_runlock();
-}
-
-
-void
-erts_cancel_bif_timers(Process *p, ErtsProcLocks plocks)
-{
- ErtsBifTimer *btm;
-
- if (erts_smp_btm_tryrwlock() == EBUSY) {
- erts_smp_proc_unlock(p, plocks);
- erts_smp_btm_rwlock();
- erts_smp_proc_lock(p, plocks);
- }
-
- btm = p->u.bif_timers;
- while (btm) {
- ErtsBifTimer *tmp_btm;
- ASSERT(!(btm->flags & BTM_FLG_CANCELED));
- tab_remove(btm);
- tmp_btm = btm;
- btm = btm->receiver.proc.next;
- erts_cancel_timer(&tmp_btm->tm);
- }
-
- p->u.bif_timers = NULL;
-
- erts_smp_btm_rwunlock();
-}
-
-void erts_bif_timer_init(void)
-{
- int i;
- no_bif_timers = 0;
- init_btm_pre_alloc();
- erts_smp_btm_lock_init();
- bif_timer_tab = erts_alloc(ERTS_ALC_T_BIF_TIMER_TABLE,
- sizeof(ErtsBifTimer *)*TIMER_HASH_VEC_SZ);
- for (i = 0; i < TIMER_HASH_VEC_SZ; ++i)
- bif_timer_tab[i] = NULL;
-}
-
-Uint
-erts_bif_timer_memory_size(void)
-{
- Uint res;
- int lock = !ERTS_IS_CRASH_DUMPING;
-
- if (lock)
- erts_smp_btm_rlock();
-
- res = (sizeof(ErtsBifTimer *)*TIMER_HASH_VEC_SZ
- + no_bif_timers*sizeof(ErtsBifTimer));
-
- if (lock)
- erts_smp_btm_runlock();
-
- return res;
-}
-
-
-void
-erts_bif_timer_foreach(void (*func)(Eterm, Eterm, ErlHeapFragment *, void *),
- void *arg)
-{
- int i;
-
- ERTS_SMP_LC_ASSERT(erts_smp_thr_progress_is_blocking());
-
- for (i = 0; i < TIMER_HASH_VEC_SZ; i++) {
- ErtsBifTimer *btm;
- for (btm = bif_timer_tab[i]; btm; btm = btm->tab.next) {
- (*func)((btm->flags & BTM_FLG_BYNAME
- ? btm->receiver.name
- : btm->receiver.proc.ess->common.id),
- btm->message,
- btm->bp,
- arg);
- }
- }
-}
diff --git a/erts/emulator/beam/erl_bif_timer.h b/erts/emulator/beam/erl_bif_timer.h
deleted file mode 100644
index 1197c176f5..0000000000
--- a/erts/emulator/beam/erl_bif_timer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
- */
-
-
-#ifndef ERL_BIF_TIMER_H__
-#define ERL_BIF_TIMER_H__
-
-typedef struct ErtsBifTimer_ ErtsBifTimer;
-
-#include "sys.h"
-#include "erl_process.h"
-#include "erl_message.h"
-
-Uint erts_bif_timer_memory_size(void);
-void erts_print_bif_timer_info(int to, void *to_arg);
-void erts_cancel_bif_timers(Process *p, ErtsProcLocks plocks);
-void erts_bif_timer_init(void);
-void erts_bif_timer_foreach(void (*func)(Eterm,Eterm,ErlHeapFragment *,void *),
- void *arg);
-#endif
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index 06fbbea123..08807d72c9 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -38,6 +39,7 @@
#include "beam_bp.h"
#include "erl_binary.h"
#include "erl_thr_progress.h"
+#include "erl_bif_unique.h"
#define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
@@ -358,7 +360,7 @@ trace_pattern(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist)
ASSERT(finish_bp.stager == NULL);
finish_bp.stager = p;
erts_schedule_thr_prgr_later_op(smp_bp_finisher, NULL, &finish_bp.lop);
- erts_smp_proc_inc_refc(p);
+ erts_proc_inc_refc(p);
erts_suspend(p, ERTS_PROC_LOCK_MAIN, NULL);
ERTS_BIF_YIELD_RETURN(p, make_small(matches));
}
@@ -392,7 +394,7 @@ static void smp_bp_finisher(void* null)
erts_resume(p, ERTS_PROC_LOCK_STATUS);
}
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
- erts_smp_proc_dec_refc(p);
+ erts_proc_dec_refc(p);
}
}
#endif /* ERTS_SMP */
@@ -429,6 +431,9 @@ Uint
erts_trace_flag2bit(Eterm flag)
{
switch (flag) {
+ case am_timestamp: return F_NOW_TS;
+ case am_strict_monotonic_timestamp: return F_STRICT_MON_TS;
+ case am_monotonic_timestamp: return F_MON_TS;
case am_all: return TRACEE_FLAGS;
case am_send: return F_TRACE_SEND;
case am_receive: return F_TRACE_RECEIVE;
@@ -437,7 +442,6 @@ erts_trace_flag2bit(Eterm flag)
case am_set_on_first_spawn: return F_TRACE_SOS1;
case am_set_on_link: return F_TRACE_SOL;
case am_set_on_first_link: return F_TRACE_SOL1;
- case am_timestamp: return F_TIMESTAMP;
case am_running: return F_TRACE_SCHED;
case am_exiting: return F_TRACE_SCHED_EXIT;
case am_garbage_collection: return F_TRACE_GC;
@@ -590,7 +594,7 @@ Eterm trace_3(BIF_ALIST_3)
ERTS_TRACE_FLAGS(tracee_port) |= mask;
else
ERTS_TRACE_FLAGS(tracee_port) &= ~mask;
-
+
if (!ERTS_TRACE_FLAGS(tracee_port))
ERTS_TRACER_PROC(tracee_port) = NIL;
else if (tracer != NIL)
@@ -651,7 +655,7 @@ Eterm trace_3(BIF_ALIST_3)
if (pid_spec == am_all) {
if (on) {
if (!erts_cpu_timestamp) {
-#ifdef HAVE_CLOCK_GETTIME
+#ifdef HAVE_CLOCK_GETTIME_CPU_TIME
/*
Perhaps clock_gettime was found during config
on a different machine than this. We check
@@ -678,7 +682,7 @@ Eterm trace_3(BIF_ALIST_3)
if (erts_start_now_cpu() < 0) {
goto error;
}
-#endif /* HAVE_CLOCK_GETTIME */
+#endif /* HAVE_CLOCK_GETTIME_CPU_TIME */
erts_cpu_timestamp = !0;
}
}
@@ -976,7 +980,7 @@ trace_info_pid(Process* p, Eterm pid_spec, Eterm key)
}
if (key == am_flags) {
- int num_flags = 19; /* MAXIMUM number of flags. */
+ int num_flags = 21; /* MAXIMUM number of flags. */
Uint needed = 3+2*num_flags;
Eterm flag_list = NIL;
Eterm* limit;
@@ -994,6 +998,9 @@ trace_info_pid(Process* p, Eterm pid_spec, Eterm key)
#endif
hp = HAlloc(p, needed);
limit = hp+needed;
+ FLAG(F_NOW_TS, am_timestamp);
+ FLAG(F_STRICT_MON_TS, am_strict_monotonic_timestamp);
+ FLAG(F_MON_TS, am_monotonic_timestamp);
FLAG(F_TRACE_SEND, am_send);
FLAG(F_TRACE_RECEIVE, am_receive);
FLAG(F_TRACE_SOS, am_set_on_spawn);
@@ -1005,7 +1012,6 @@ trace_info_pid(Process* p, Eterm pid_spec, Eterm key)
FLAG(F_TRACE_SCHED, am_running);
FLAG(F_TRACE_SCHED_EXIT, am_exiting);
FLAG(F_TRACE_GC, am_garbage_collection);
- FLAG(F_TIMESTAMP, am_timestamp);
FLAG(F_TRACE_ARITY_ONLY, am_arity);
FLAG(F_TRACE_RETURN_TO, am_return_to);
FLAG(F_TRACE_SILENT, am_silent);
@@ -1796,7 +1802,11 @@ Eterm erts_seq_trace(Process *p, Eterm arg1, Eterm arg2,
} else if (arg1 == am_print) {
current_flag = SEQ_TRACE_PRINT;
} else if (arg1 == am_timestamp) {
- current_flag = SEQ_TRACE_TIMESTAMP;
+ current_flag = SEQ_TRACE_NOW_TS;
+ } else if (arg1 == am_strict_monotonic_timestamp) {
+ current_flag = SEQ_TRACE_STRICT_MON_TS;
+ } else if (arg1 == am_monotonic_timestamp) {
+ current_flag = SEQ_TRACE_MON_TS;
}
else
current_flag = 0;
@@ -1907,7 +1917,9 @@ BIF_RETTYPE erl_seq_trace_info(Process *p, Eterm item)
#endif
) {
if ((item == am_send) || (item == am_receive) ||
- (item == am_print) || (item == am_timestamp)) {
+ (item == am_print) || (item == am_timestamp)
+ || (item == am_monotonic_timestamp)
+ || (item == am_strict_monotonic_timestamp)) {
hp = HAlloc(p,3);
res = TUPLE2(hp, item, am_false);
BIF_RET(res);
@@ -1925,7 +1937,11 @@ BIF_RETTYPE erl_seq_trace_info(Process *p, Eterm item)
} else if (item == am_print) {
current_flag = SEQ_TRACE_PRINT;
} else if (item == am_timestamp) {
- current_flag = SEQ_TRACE_TIMESTAMP;
+ current_flag = SEQ_TRACE_NOW_TS;
+ } else if (item == am_strict_monotonic_timestamp) {
+ current_flag = SEQ_TRACE_STRICT_MON_TS;
+ } else if (item == am_monotonic_timestamp) {
+ current_flag = SEQ_TRACE_MON_TS;
} else {
current_flag = 0;
}
@@ -2235,6 +2251,7 @@ static Eterm system_profile_get(Process *p) {
if (erts_system_profile_flags.exclusive) {
res = CONS(hp, am_exclusive, res); hp += 2;
}
+
return TUPLE2(hp, system_profile, res);
}
}
@@ -2253,6 +2270,7 @@ BIF_RETTYPE system_profile_2(BIF_ALIST_2)
int system_blocked = 0;
Process *profiler_p = NULL;
Port *profiler_port = NULL;
+ int ts;
if (profiler == am_undefined || list == NIL) {
prev = system_profile_get(p);
@@ -2284,7 +2302,8 @@ BIF_RETTYPE system_profile_2(BIF_ALIST_2)
goto error;
}
- for (scheduler = 0, runnable_ports = 0, runnable_procs = 0, exclusive = 0;
+ for (ts = ERTS_TRACE_FLG_NOW_TIMESTAMP, scheduler = 0,
+ runnable_ports = 0, runnable_procs = 0, exclusive = 0;
is_list(list);
list = CDR(list_val(list))) {
@@ -2297,6 +2316,12 @@ BIF_RETTYPE system_profile_2(BIF_ALIST_2)
exclusive = !0;
} else if (t == am_scheduler) {
scheduler = !0;
+ } else if (t == am_timestamp) {
+ ts = ERTS_TRACE_FLG_NOW_TIMESTAMP;
+ } else if (t == am_strict_monotonic_timestamp) {
+ ts = ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP;
+ } else if (t == am_monotonic_timestamp) {
+ ts = ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP;
} else goto error;
}
if (is_not_nil(list)) goto error;
@@ -2309,7 +2334,7 @@ BIF_RETTYPE system_profile_2(BIF_ALIST_2)
erts_system_profile_flags.runnable_ports = !!runnable_ports;
erts_system_profile_flags.runnable_procs = !!runnable_procs;
erts_system_profile_flags.exclusive = !!exclusive;
-
+ erts_system_profile_ts_type = ts;
erts_smp_thr_progress_unblock();
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
diff --git a/erts/emulator/beam/erl_bif_unique.c b/erts/emulator/beam/erl_bif_unique.c
new file mode 100644
index 0000000000..5eca09c5a6
--- /dev/null
+++ b/erts/emulator/beam/erl_bif_unique.c
@@ -0,0 +1,557 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2014. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.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%
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sys.h"
+#include "erl_vm.h"
+#include "erl_alloc.h"
+#include "export.h"
+#include "bif.h"
+#include "erl_bif_unique.h"
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Reference *
+\* */
+
+static union {
+ erts_atomic64_t count;
+ char align__[ERTS_CACHE_LINE_SIZE];
+} global_reference erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+
+
+/*
+ * ref[0] indicate thread creating reference as follows:
+ *
+ * - ref[0] == 0 => Non-scheduler thread;
+ * - else; ref[0] <= erts_no_schedulers =>
+ * ordinary scheduler with id == ref[0];
+ * - else; ref[0] <= erts_no_schedulers
+ * + erts_no_dirty_cpu_schedulers =>
+ * dirty cpu scheduler with id == 'ref[0] - erts_no_schedulers';
+ * - else =>
+ * dirty io scheduler with id == 'ref[0]
+ * - erts_no_schedulers
+ * - erts_no_dirty_cpu_schedulers'
+ */
+
+#ifdef DEBUG
+static Uint32 max_thr_id;
+#endif
+
+static void
+init_reference(void)
+{
+#ifdef DEBUG
+ max_thr_id = (Uint32) erts_no_schedulers;
+#ifdef ERTS_DIRTY_SCHEDULERS
+ max_thr_id += (Uint32) erts_no_dirty_cpu_schedulers;
+ max_thr_id += (Uint32) erts_no_dirty_io_schedulers;
+#endif
+#endif
+ erts_atomic64_init_nob(&global_reference.count, 0);
+}
+
+static ERTS_INLINE void
+global_make_ref_in_array(Uint32 thr_id, Uint32 ref[ERTS_MAX_REF_NUMBERS])
+{
+ Uint64 value;
+
+ value = (Uint64) erts_atomic64_inc_read_mb(&global_reference.count);
+
+ erts_set_ref_numbers(ref, thr_id, value);
+}
+
+static ERTS_INLINE void
+make_ref_in_array(Uint32 ref[ERTS_MAX_REF_NUMBERS])
+{
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ if (esdp)
+ erts_sched_make_ref_in_array(esdp, ref);
+ else
+ global_make_ref_in_array(0, ref);
+}
+
+void
+erts_make_ref_in_array(Uint32 ref[ERTS_MAX_REF_NUMBERS])
+{
+ make_ref_in_array(ref);
+}
+
+Eterm erts_make_ref_in_buffer(Eterm buffer[REF_THING_SIZE])
+{
+ Eterm* hp = buffer;
+ Uint32 ref[ERTS_MAX_REF_NUMBERS];
+
+ make_ref_in_array(ref);
+ write_ref_thing(hp, ref[0], ref[1], ref[2]);
+ return make_internal_ref(hp);
+}
+
+Eterm erts_make_ref(Process *c_p)
+{
+ Eterm* hp;
+ Uint32 ref[ERTS_MAX_REF_NUMBERS];
+
+ ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(c_p));
+
+ hp = HAlloc(c_p, REF_THING_SIZE);
+
+ make_ref_in_array(ref);
+ write_ref_thing(hp, ref[0], ref[1], ref[2]);
+
+ return make_internal_ref(hp);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Unique Integer *
+\* */
+
+static struct {
+ union {
+ struct {
+ int left_shift;
+ int right_shift;
+ Uint64 mask;
+ Uint64 val0_max;
+ } o;
+ char align__[ERTS_CACHE_LINE_SIZE];
+ } r;
+ union {
+ erts_atomic64_t val1;
+ char align__[ERTS_CACHE_LINE_SIZE];
+ } w;
+} unique_data erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+
+static void
+init_unique_integer(void)
+{
+ int bits;
+ unique_data.r.o.val0_max = (Uint64) erts_no_schedulers;
+#ifdef ERTS_DIRTY_SCHEDULERS
+ unique_data.r.o.val0_max += (Uint64) erts_no_dirty_cpu_schedulers;
+ unique_data.r.o.val0_max += (Uint64) erts_no_dirty_io_schedulers;
+#endif
+ bits = erts_fit_in_bits_int64(unique_data.r.o.val0_max);
+ unique_data.r.o.left_shift = bits;
+ unique_data.r.o.right_shift = 64 - bits;
+ unique_data.r.o.mask = (((Uint64) 1) << bits) - 1;
+ erts_atomic64_init_nob(&unique_data.w.val1, -1);
+}
+
+#define ERTS_MAX_UNIQUE_INT_HEAP_SIZE ERTS_UINT64_ARRAY_TO_BIG_MAX_HEAP_SZ(2)
+
+static ERTS_INLINE Eterm
+bld_unique_integer_term(Eterm **hpp, Uint *szp,
+ Uint64 val0, Uint64 val1,
+ int positive)
+{
+ Uint hsz;
+ Uint64 unique_val[2];
+
+ unique_val[0] = ((Uint64) val0);
+ unique_val[0] |= ((Uint64) val1) << unique_data.r.o.left_shift;
+ unique_val[1] = ((Uint64) val1) >> unique_data.r.o.right_shift;
+ unique_val[1] &= unique_data.r.o.mask;
+
+ if (positive) {
+ unique_val[0]++;
+ if (unique_val[0] == 0)
+ unique_val[1]++;
+ }
+ else {
+ ASSERT(MIN_SMALL < 0);
+ if (unique_val[1] == 0
+ && unique_val[0] < ((Uint64) -1*((Sint64) MIN_SMALL))) {
+ Sint64 s_unique_val = (Sint64) unique_val[0];
+ s_unique_val += MIN_SMALL;
+ ASSERT(MIN_SMALL <= s_unique_val && s_unique_val < 0);
+ if (szp)
+ *szp = 0;
+ if (!hpp)
+ return THE_NON_VALUE;
+ return make_small((Sint) s_unique_val);
+ }
+ if (unique_val[0] < ((Uint64) -1*((Sint64) MIN_SMALL))) {
+ ASSERT(unique_val[1] != 0);
+ unique_val[1] -= 1;
+ }
+ unique_val[0] += MIN_SMALL;
+ }
+
+ if (!unique_val[1]) {
+ if (unique_val[0] <= MAX_SMALL) {
+ if (szp)
+ *szp = 0;
+ if (!hpp)
+ return THE_NON_VALUE;
+ return make_small((Uint) unique_val[0]);
+ }
+
+ if (szp)
+ *szp = ERTS_UINT64_HEAP_SIZE(unique_val[0]);
+ if (!hpp)
+ return THE_NON_VALUE;
+ return erts_uint64_to_big(unique_val[0], hpp);
+ }
+ else {
+ Eterm tmp, *tmp_hp, res;
+ DeclareTmpHeapNoproc(local_heap, 2*ERTS_MAX_UNIQUE_INT_HEAP_SIZE);
+
+ UseTmpHeapNoproc(2*ERTS_MAX_UNIQUE_INT_HEAP_SIZE);
+
+ tmp_hp = local_heap;
+
+ tmp = erts_uint64_array_to_big(&tmp_hp, 0, 2, unique_val);
+ ASSERT(is_big(tmp));
+
+ hsz = big_arity(tmp) + 1;
+
+ ASSERT(hsz <= ERTS_MAX_UNIQUE_INT_HEAP_SIZE);
+
+ if (szp)
+ *szp = hsz;
+
+ if (!hpp)
+ res = THE_NON_VALUE;
+ else {
+ int hix;
+ Eterm *hp = *hpp;
+ tmp_hp = big_val(tmp);
+ for (hix = 0; hix < hsz; hix++)
+ hp[hix] = tmp_hp[hix];
+
+ *hpp = hp + hsz;
+ res = make_big(hp);
+ }
+
+ UnUseTmpHeapNoproc(2*ERTS_MAX_UNIQUE_INT_HEAP_SIZE);
+
+ return res;
+ }
+}
+
+static ERTS_INLINE Eterm unique_integer_bif(Process *c_p, int positive)
+{
+ ErtsSchedulerData *esdp;
+ Uint64 thr_id, unique;
+ Uint hsz;
+ Eterm *hp;
+
+ esdp = ERTS_PROC_GET_SCHDATA(c_p);
+ thr_id = (Uint64) esdp->thr_id;
+ unique = esdp->unique++;
+ bld_unique_integer_term(NULL, &hsz, thr_id, unique, positive);
+ hp = hsz ? HAlloc(c_p, hsz) : NULL;
+ return bld_unique_integer_term(&hp, NULL, thr_id, unique, positive);
+}
+
+Uint
+erts_raw_unique_integer_heap_size(Uint64 val[ERTS_UNIQUE_INT_RAW_VALUES])
+{
+ Uint sz;
+ bld_unique_integer_term(NULL, &sz, val[0], val[1], 0);
+ return sz;
+}
+
+Eterm
+erts_raw_make_unique_integer(Eterm **hpp, Uint64 val[ERTS_UNIQUE_INT_RAW_VALUES])
+{
+ return bld_unique_integer_term(hpp, NULL, val[0], val[1], 0);
+}
+
+void
+erts_raw_get_unique_integer(Uint64 val[ERTS_UNIQUE_INT_RAW_VALUES])
+{
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ if (esdp) {
+ val[0] = (Uint64) esdp->thr_id;
+ val[1] = esdp->unique++;
+ }
+ else {
+ val[0] = (Uint64) 0;
+ val[1] = (Uint64) erts_atomic64_inc_read_nob(&unique_data.w.val1);
+ }
+}
+
+
+Sint64
+erts_get_min_unique_integer(void)
+{
+ return (Sint64) MIN_SMALL;
+}
+
+/* --- Debug --- */
+
+Eterm
+erts_debug_make_unique_integer(Process *c_p, Eterm etval0, Eterm etval1)
+{
+ Uint64 val0, val1;
+ Uint hsz;
+ Eterm res, *hp, *end_hp;
+
+ if (!term_to_Uint64(etval0, &val0))
+ return THE_NON_VALUE;
+
+ if (!term_to_Uint64(etval1, &val1))
+ return THE_NON_VALUE;
+
+ bld_unique_integer_term(NULL, &hsz, val0, val1, 0);
+
+ hp = HAlloc(c_p, hsz);
+ end_hp = hp + hsz;
+
+ res = bld_unique_integer_term(&hp, NULL, val0, val1, 0);
+ if (hp != end_hp)
+ ERTS_INTERNAL_ERROR("Heap allocation error");
+
+ return res;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Strict Monotonic Counter *
+\* */
+
+static struct {
+ union {
+ erts_atomic64_t value;
+ char align__[ERTS_CACHE_LINE_SIZE];
+ } w;
+} raw_unique_monotonic_integer erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+
+#if defined(ARCH_32) || HALFWORD_HEAP
+# define ERTS_UNIQUE_MONOTONIC_OFFSET ERTS_SINT64_MIN
+#else
+# define ERTS_UNIQUE_MONOTONIC_OFFSET MIN_SMALL
+#endif
+
+static void
+init_unique_monotonic_integer(void)
+{
+ erts_atomic64_init_nob(&raw_unique_monotonic_integer.w.value,
+ (erts_aint64_t) -1);
+}
+
+static ERTS_INLINE Uint64
+get_raw_unique_monotonic_integer(void)
+{
+ return (Uint64) erts_atomic64_inc_read_mb(&raw_unique_monotonic_integer.w.value);
+}
+
+static ERTS_INLINE Uint
+get_unique_monotonic_integer_heap_size(Uint64 raw, int positive)
+{
+ if (positive) {
+ Uint64 value = raw+1;
+ return ERTS_UINT64_HEAP_SIZE(value);
+ }
+ else {
+ Sint64 value = ((Sint64) raw) + ERTS_UNIQUE_MONOTONIC_OFFSET;
+ if (IS_SSMALL(value))
+ return 0;
+#if defined(ARCH_32) || HALFWORD_HEAP
+ return ERTS_SINT64_HEAP_SIZE(value);
+#else
+ return ERTS_UINT64_HEAP_SIZE((Uint64) value);
+#endif
+ }
+}
+
+static ERTS_INLINE Eterm
+make_unique_monotonic_integer_value(Eterm *hp, Uint hsz, Uint64 raw, int positive)
+{
+ Eterm res;
+#ifdef DEBUG
+ Eterm *end_hp = hp + hsz;
+#endif
+
+ if (positive) {
+ Uint64 value = raw+1;
+ res = hsz ? erts_uint64_to_big(value, &hp) : make_small(value);
+ }
+ else {
+ Sint64 value = ((Sint64) raw) + ERTS_UNIQUE_MONOTONIC_OFFSET;
+ if (hsz == 0)
+ res = make_small(value);
+ else {
+#if defined(ARCH_32) || HALFWORD_HEAP
+ res = erts_sint64_to_big(value, &hp);
+#else
+ res = erts_uint64_to_big((Uint64) value, &hp);
+#endif
+ }
+ }
+
+ ASSERT(end_hp == hp);
+
+ return res;
+}
+
+static ERTS_INLINE Eterm
+unique_monotonic_integer_bif(Process *c_p, int positive)
+{
+ Uint64 raw;
+ Uint hsz;
+ Eterm *hp;
+
+ raw = get_raw_unique_monotonic_integer();
+ hsz = get_unique_monotonic_integer_heap_size(raw, positive);
+ hp = hsz ? HAlloc(c_p, hsz) : NULL;
+ return make_unique_monotonic_integer_value(hp, hsz, raw, positive);
+}
+
+Sint64
+erts_raw_get_unique_monotonic_integer(void)
+{
+ return get_raw_unique_monotonic_integer();
+}
+
+Uint
+erts_raw_unique_monotonic_integer_heap_size(Sint64 raw)
+{
+ return get_unique_monotonic_integer_heap_size(raw, 0);
+}
+
+Eterm
+erts_raw_make_unique_monotonic_integer_value(Eterm **hpp, Sint64 raw)
+{
+ Uint hsz = get_unique_monotonic_integer_heap_size(raw, 0);
+ Eterm res = make_unique_monotonic_integer_value(*hpp, hsz, raw, 0);
+ *hpp += hsz;
+ return res;
+}
+
+Sint64
+erts_get_min_unique_monotonic_integer(void)
+{
+ return ERTS_UNIQUE_MONOTONIC_OFFSET;
+}
+
+/* --- Debug --- */
+
+int
+erts_debug_set_unique_monotonic_integer_state(Eterm et_value)
+{
+ Sint64 value;
+
+ if (!term_to_Sint64(et_value, &value)) {
+ Uint64 uvalue;
+ if (!term_to_Uint64(et_value, &uvalue))
+ return 0;
+ value = (Sint64) uvalue;
+ }
+
+ erts_atomic64_set_mb(&raw_unique_monotonic_integer.w.value,
+ (erts_aint64_t) value);
+ return 1;
+}
+
+Eterm
+erts_debug_get_unique_monotonic_integer_state(Process *c_p)
+{
+ Uint64 value;
+ Eterm hsz, *hp;
+
+ value = (Uint64) erts_atomic64_read_mb(&raw_unique_monotonic_integer.w.value);
+
+ if (IS_USMALL(0, value))
+ return make_small(value);
+ hsz = ERTS_UINT64_HEAP_SIZE(value);
+ hp = HAlloc(c_p, hsz);
+ return erts_uint64_to_big(value, &hp);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Initilazation *
+\* */
+
+void
+erts_bif_unique_init(void)
+{
+ init_reference();
+ init_unique_monotonic_integer();
+ init_unique_integer();
+}
+
+void
+erts_sched_bif_unique_init(ErtsSchedulerData *esdp)
+{
+ esdp->unique = (Uint64) 0;
+ esdp->ref = (Uint64) 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * The BIFs *
+\* */
+
+
+BIF_RETTYPE make_ref_0(BIF_ALIST_0)
+{
+ BIF_RETTYPE res;
+ Eterm* hp;
+
+ ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P));
+
+ hp = HAlloc(BIF_P, REF_THING_SIZE);
+
+ res = erts_sched_make_ref_in_buffer(ERTS_PROC_GET_SCHDATA(BIF_P), hp);
+
+ BIF_RET(res);
+}
+
+BIF_RETTYPE unique_integer_0(BIF_ALIST_0)
+{
+ BIF_RET(unique_integer_bif(BIF_P, 0));
+}
+
+BIF_RETTYPE unique_integer_1(BIF_ALIST_1)
+{
+ Eterm modlist = BIF_ARG_1;
+ int monotonic = 0;
+ int positive = 0;
+ BIF_RETTYPE res;
+
+ while (is_list(modlist)) {
+ Eterm *consp = list_val(modlist);
+ switch (CAR(consp)) {
+ case am_monotonic:
+ monotonic = 1;
+ break;
+ case am_positive:
+ positive = 1;
+ break;
+ default:
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ modlist = CDR(consp);
+ }
+
+ if (is_not_nil(modlist))
+ BIF_ERROR(BIF_P, BADARG);
+
+ if (monotonic)
+ res = unique_monotonic_integer_bif(BIF_P, positive);
+ else
+ res = unique_integer_bif(BIF_P, positive);
+
+ BIF_RET(res);
+}
diff --git a/erts/emulator/beam/erl_bif_unique.h b/erts/emulator/beam/erl_bif_unique.h
new file mode 100644
index 0000000000..37d5d91c39
--- /dev/null
+++ b/erts/emulator/beam/erl_bif_unique.h
@@ -0,0 +1,132 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2014. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.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 ERTS_BIF_UNIQUE_H__
+#define ERTS_BIF_UNIQUE_H__
+
+#include "erl_process.h"
+#include "big.h"
+
+void erts_bif_unique_init(void);
+void erts_sched_bif_unique_init(ErtsSchedulerData *esdp);
+
+/* reference */
+Eterm erts_make_ref(Process *);
+Eterm erts_make_ref_in_buffer(Eterm buffer[REF_THING_SIZE]);
+void erts_make_ref_in_array(Uint32 ref[ERTS_MAX_REF_NUMBERS]);
+
+/* strict monotonic counter */
+
+#define ERTS_MAX_UNIQUE_MONOTONIC_INTEGER_HEAP_SIZE ERTS_MAX_UINT64_HEAP_SIZE
+
+/*
+ * Note that a raw value is an intermediate value that
+ * not necessarily correspond to the end result.
+ */
+Sint64 erts_raw_get_unique_monotonic_integer(void);
+Uint erts_raw_unique_monotonic_integer_heap_size(Sint64 raw);
+Eterm erts_raw_make_unique_monotonic_integer_value(Eterm **hpp, Sint64 raw);
+
+Sint64 erts_get_min_unique_monotonic_integer(void);
+
+int erts_debug_set_unique_monotonic_integer_state(Eterm et_value);
+Eterm erts_debug_get_unique_monotonic_integer_state(Process *c_p);
+
+/* unique integer */
+#define ERTS_UNIQUE_INT_RAW_VALUES 2
+#define ERTS_MAX_UNIQUE_INT_HEAP_SIZE ERTS_UINT64_ARRAY_TO_BIG_MAX_HEAP_SZ(2)
+
+Uint erts_raw_unique_integer_heap_size(Uint64 val[ERTS_UNIQUE_INT_RAW_VALUES]);
+Eterm erts_raw_make_unique_integer(Eterm **hpp, Uint64 val[ERTS_UNIQUE_INT_RAW_VALUES]);
+void erts_raw_get_unique_integer(Uint64 val[ERTS_UNIQUE_INT_RAW_VALUES]);
+Sint64 erts_get_min_unique_integer(void);
+
+Eterm erts_debug_make_unique_integer(Process *c_p,
+ Eterm etval0,
+ Eterm etval1);
+
+
+ERTS_GLB_INLINE void erts_set_ref_numbers(Uint32 ref[ERTS_MAX_REF_NUMBERS],
+ Uint32 thr_id, Uint64 value);
+ERTS_GLB_INLINE Uint32 erts_get_ref_numbers_thr_id(Uint32 ref[ERTS_MAX_REF_NUMBERS]);
+ERTS_GLB_INLINE Uint64 erts_get_ref_numbers_value(Uint32 ref[ERTS_MAX_REF_NUMBERS]);
+ERTS_GLB_INLINE void erts_sched_make_ref_in_array(ErtsSchedulerData *esdp,
+ Uint32 ref[ERTS_MAX_REF_NUMBERS]);
+ERTS_GLB_INLINE Eterm erts_sched_make_ref_in_buffer(ErtsSchedulerData *esdp,
+ Eterm buffer[REF_THING_SIZE]);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE void
+erts_set_ref_numbers(Uint32 ref[ERTS_MAX_REF_NUMBERS], Uint32 thr_id, Uint64 value)
+{
+ /*
+ * We cannot use thread id in the first 18-bit word since
+ * the hash/phash/phash2 BIFs only hash on this word. If
+ * we did, we would get really poor hash values. Instead
+ * we have to shuffle the bits a bit.
+ */
+ ASSERT(thr_id == (thr_id & ((Uint32) 0x3ffff)));
+ ref[0] = (Uint32) (value & ((Uint64) 0x3ffff));
+ ref[1] = (((Uint32) (value & ((Uint64) 0xfffc0000)))
+ | (thr_id & ((Uint32) 0x3ffff)));
+ ref[2] = (Uint32) ((value >> 32) & ((Uint64) 0xffffffff));
+}
+
+ERTS_GLB_INLINE Uint32
+erts_get_ref_numbers_thr_id(Uint32 ref[ERTS_MAX_REF_NUMBERS])
+{
+ return ref[1] & ((Uint32) 0x3ffff);
+}
+
+ERTS_GLB_INLINE Uint64
+erts_get_ref_numbers_value(Uint32 ref[ERTS_MAX_REF_NUMBERS])
+{
+ return (((((Uint64) ref[2]) & ((Uint64) 0xffffffff)) << 32)
+ | (((Uint64) ref[1]) & ((Uint64) 0xfffc0000))
+ | (((Uint64) ref[0]) & ((Uint64) 0x3ffff)));
+}
+
+ERTS_GLB_INLINE void
+erts_sched_make_ref_in_array(ErtsSchedulerData *esdp,
+ Uint32 ref[ERTS_MAX_REF_NUMBERS])
+{
+ Uint64 value;
+
+ ASSERT(esdp);
+ value = esdp->ref++;
+ erts_set_ref_numbers(ref, (Uint32) esdp->thr_id, value);
+}
+
+ERTS_GLB_INLINE Eterm
+erts_sched_make_ref_in_buffer(ErtsSchedulerData *esdp,
+ Eterm buffer[REF_THING_SIZE])
+{
+ Eterm* hp = buffer;
+ Uint32 ref[ERTS_MAX_REF_NUMBERS];
+
+ erts_sched_make_ref_in_array(esdp, ref);
+ write_ref_thing(hp, ref[0], ref[1], ref[2]);
+ return make_internal_ref(hp);
+}
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
+#endif /* ERTS_BIF_UNIQUE_H__ */
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index 06dfeb1260..ea01bf08f0 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -194,6 +195,9 @@ ERTS_GLB_INLINE Binary *erts_bin_nrml_alloc(Uint size);
ERTS_GLB_INLINE Binary *erts_bin_realloc_fnf(Binary *bp, Uint size);
ERTS_GLB_INLINE Binary *erts_bin_realloc(Binary *bp, Uint size);
ERTS_GLB_INLINE void erts_bin_free(Binary *bp);
+ERTS_GLB_INLINE Binary *erts_create_magic_binary_x(Uint size,
+ void (*destructor)(Binary *),
+ int unaligned);
ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size,
void (*destructor)(Binary *));
@@ -231,41 +235,58 @@ erts_free_aligned_binary_bytes(byte* buf)
# define CHICKEN_PAD (sizeof(void*) - 1)
#endif
+/* Caller must initialize 'refc'
+*/
ERTS_GLB_INLINE Binary *
erts_bin_drv_alloc_fnf(Uint size)
{
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- void *res;
+ Binary *res;
+
if (bsize < size) /* overflow */
return NULL;
res = erts_alloc_fnf(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
- return (Binary *) res;
+ if (res) {
+ res->orig_size = size;
+ res->flags = BIN_FLAG_DRV;
+ }
+ return res;
}
+/* Caller must initialize 'refc'
+*/
ERTS_GLB_INLINE Binary *
erts_bin_drv_alloc(Uint size)
{
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- void *res;
+ Binary *res;
+
if (bsize < size) /* overflow */
erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, size);
res = erts_alloc(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
- return (Binary *) res;
+ res->orig_size = size;
+ res->flags = BIN_FLAG_DRV;
+ return res;
}
+/* Caller must initialize 'refc'
+*/
ERTS_GLB_INLINE Binary *
erts_bin_nrml_alloc(Uint size)
{
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- void *res;
+ Binary *res;
+
if (bsize < size) /* overflow */
erts_alloc_enomem(ERTS_ALC_T_BINARY, size);
res = erts_alloc(ERTS_ALC_T_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
- return (Binary *) res;
+ res->orig_size = size;
+ res->flags = 0;
+ return res;
}
ERTS_GLB_INLINE Binary *
@@ -280,6 +301,8 @@ erts_bin_realloc_fnf(Binary *bp, Uint size)
return NULL;
nbp = erts_realloc_fnf(type, (void *) bp, bsize);
ERTS_CHK_BIN_ALIGNMENT(nbp);
+ if (nbp)
+ nbp->orig_size = size;
return nbp;
}
@@ -297,6 +320,7 @@ erts_bin_realloc(Binary *bp, Uint size)
if (!nbp)
erts_realloc_enomem(type, bp, bsize);
ERTS_CHK_BIN_ALIGNMENT(nbp);
+ nbp->orig_size = size;
return nbp;
}
@@ -312,21 +336,30 @@ erts_bin_free(Binary *bp)
}
ERTS_GLB_INLINE Binary *
-erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
+erts_create_magic_binary_x(Uint size, void (*destructor)(Binary *),
+ int unaligned)
{
- Uint bsize = ERTS_MAGIC_BIN_SIZE(size);
+ Uint bsize = unaligned ? ERTS_MAGIC_BIN_UNALIGNED_SIZE(size)
+ : ERTS_MAGIC_BIN_SIZE(size);
Binary* bptr = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize);
ASSERT(bsize > size);
if (!bptr)
erts_alloc_n_enomem(ERTS_ALC_T2N(ERTS_ALC_T_BINARY), bsize);
ERTS_CHK_BIN_ALIGNMENT(bptr);
bptr->flags = BIN_FLAG_MAGIC;
- bptr->orig_size = ERTS_MAGIC_BIN_ORIG_SIZE(size);
+ bptr->orig_size = unaligned ? ERTS_MAGIC_BIN_UNALIGNED_ORIG_SIZE(size)
+ : ERTS_MAGIC_BIN_ORIG_SIZE(size);
erts_refc_init(&bptr->refc, 0);
ERTS_MAGIC_BIN_DESTRUCTOR(bptr) = destructor;
return bptr;
}
+ERTS_GLB_INLINE Binary *
+erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
+{
+ return erts_create_magic_binary_x(size, destructor, 0);
+}
+
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
-#endif
+#endif /* !__ERL_BINARY_H */
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 53c21c40e1..01734c55d7 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -107,6 +108,14 @@ erts_bits_destroy_state(ERL_BITS_PROTO_0)
void
erts_init_bits(void)
{
+ ERTS_CT_ASSERT(offsetof(Binary,orig_bytes) % 8 == 0);
+ ERTS_CT_ASSERT(offsetof(ErtsMagicBinary,u.aligned.data) % 8 == 0);
+ ERTS_CT_ASSERT(ERTS_MAGIC_BIN_BYTES_TO_ALIGN ==
+ (offsetof(ErtsMagicBinary,u.aligned.data)
+ - offsetof(ErtsMagicBinary,u.unaligned.data)));
+ ERTS_CT_ASSERT(offsetof(ErtsBinary,driver.binary.orig_bytes)
+ == offsetof(Binary,orig_bytes));
+
erts_smp_atomic_init_nob(&bits_bufs_size, 0);
#if defined(ERTS_SMP)
/* erl_process.c calls erts_bits_init_state() on all state instances */
@@ -165,6 +174,26 @@ erts_bs_start_match_2(Process *p, Eterm Binary, Uint Max)
return make_matchstate(ms);
}
+#ifdef DEBUG
+# define CHECK_MATCH_BUFFER(MB) check_match_buffer(MB)
+
+static void check_match_buffer(ErlBinMatchBuffer* mb)
+{
+ Eterm realbin;
+ Uint byteoffs;
+ byte* bytes, bitoffs, bitsz;
+ ProcBin* pb;
+ ERTS_GET_REAL_BIN(mb->orig, realbin, byteoffs, bitoffs, bitsz);
+ bytes = binary_bytes(realbin) + byteoffs;
+ ERTS_ASSERT(mb->base >= bytes && mb->base <= (bytes + binary_size(mb->orig)));
+ pb = (ProcBin *) boxed_val(realbin);
+ if (pb->thing_word == HEADER_PROC_BIN)
+ ERTS_ASSERT(pb->flags == 0);
+}
+#else
+# define CHECK_MATCH_BUFFER(MB)
+#endif
+
Eterm
erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb)
{
@@ -185,6 +214,7 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
return SMALL_ZERO;
}
+ CHECK_MATCH_BUFFER(mb);
if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */
return THE_NON_VALUE;
}
@@ -425,6 +455,7 @@ erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffe
{
ErlSubBin* sb;
+ CHECK_MATCH_BUFFER(mb);
if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */
return THE_NON_VALUE;
}
@@ -456,6 +487,7 @@ erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer
byte* fptr;
FloatDef f;
+ CHECK_MATCH_BUFFER(mb);
if (num_bits == 0) {
f.fd = 0.0;
hp = HeapOnlyAlloc(p, FLOAT_SIZE_OBJECT);
@@ -509,6 +541,8 @@ erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb)
{
ErlSubBin* sb;
Uint size;
+
+ CHECK_MATCH_BUFFER(mb);
size = mb->size-mb->offset;
sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);
sb->thing_word = HEADER_SUB_BIN;
@@ -1302,7 +1336,6 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term,
if (binp->orig_size < pb->size) {
Uint new_size = 2*pb->size;
binp = erts_bin_realloc(binp, new_size);
- binp->orig_size = new_size;
pb->val = binp;
pb->bytes = (byte *) binp->orig_bytes;
}
@@ -1374,8 +1407,6 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term,
* Allocate the binary data struct itself.
*/
bptr = erts_bin_nrml_alloc(bin_size);
- bptr->flags = 0;
- bptr->orig_size = bin_size;
erts_refc_init(&bptr->refc, 1);
erts_current_bin = (byte *) bptr->orig_bytes;
@@ -1478,7 +1509,6 @@ erts_bs_private_append(Process* p, Eterm bin, Eterm build_size_term, Uint unit)
* is safe to reallocate it.
*/
binp = erts_bin_realloc(binp, new_size);
- binp->orig_size = new_size;
pb->val = binp;
pb->bytes = (byte *) binp->orig_bytes;
} else {
@@ -1491,8 +1521,6 @@ erts_bs_private_append(Process* p, Eterm bin, Eterm build_size_term, Uint unit)
* binary and copy the contents of the old binary into it.
*/
Binary* bptr = erts_bin_nrml_alloc(new_size);
- bptr->flags = 0;
- bptr->orig_size = new_size;
erts_refc_init(&bptr->refc, 1);
sys_memcpy(bptr->orig_bytes, binp->orig_bytes, binp->orig_size);
pb->flags |= PB_IS_WRITABLE | PB_ACTIVE_WRITER;
@@ -1540,8 +1568,6 @@ erts_bs_init_writable(Process* p, Eterm sz)
* Allocate the binary data struct itself.
*/
bptr = erts_bin_nrml_alloc(bin_size);
- bptr->flags = 0;
- bptr->orig_size = bin_size;
erts_refc_init(&bptr->refc, 1);
/*
@@ -1588,9 +1614,7 @@ erts_emasculate_writable_binary(ProcBin* pb)
/* Our allocators are 8 byte aligned, i.e., shrinking with
less than 8 bytes will have no real effect */
if (unused >= 8) {
- Uint new_size = pb->size;
binp = erts_bin_realloc(binp, pb->size);
- binp->orig_size = new_size;
pb->val = binp;
pb->bytes = (byte *) binp->orig_bytes;
}
@@ -1605,6 +1629,7 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
byte* LSB;
byte* MSB;
+ CHECK_MATCH_BUFFER(mb);
ASSERT((mb->offset & 7) != 0);
ASSERT(mb->size - mb->offset >= 32);
@@ -1664,6 +1689,8 @@ erts_bs_get_utf8(ErlBinMatchBuffer* mb)
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,9,9,9,9,9,9,9,9
};
+ CHECK_MATCH_BUFFER(mb);
+
if ((remaining_bits = mb->size - mb->offset) < 8) {
return THE_NON_VALUE;
}
@@ -1748,6 +1775,7 @@ erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags)
return THE_NON_VALUE;
}
+ CHECK_MATCH_BUFFER(mb);
/*
* Set up the pointer to the source bytes.
*/
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index 388d943755..8b7807fbd9 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c
index f594cb9392..c263eebfcc 100644
--- a/erts/emulator/beam/erl_cpu_topology.c
+++ b/erts/emulator/beam/erl_cpu_topology.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -401,7 +402,7 @@ cpu_bind_order_sort(erts_cpu_topology_t *cpudata,
break;
default:
cmp_func = NULL;
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Bad cpu bind type: %d\n",
(int) cpu_bind_order);
break;
@@ -1589,7 +1590,7 @@ get_cpu_topology_term(Process *c_p, int type)
}
break;
default:
- erl_exit(ERTS_ABORT_EXIT, "Bad cpu topology type: %d\n", type);
+ erts_exit(ERTS_ABORT_EXIT, "Bad cpu topology type: %d\n", type);
break;
}
@@ -1966,7 +1967,7 @@ cpu_group_insert(erts_cpu_groups_map_t *map,
ix = 0;
} while (ix != start);
- erl_exit(ERTS_ABORT_EXIT, "Reader groups map full\n");
+ erts_exit(ERTS_ABORT_EXIT, "Reader groups map full\n");
}
@@ -2289,7 +2290,7 @@ remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg)
prev_cgm = cgm;
}
- erl_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n");
+ erts_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n");
}
static int
@@ -2319,7 +2320,7 @@ cpu_groups_lookup(erts_cpu_groups_map_t *map,
ix = 0;
} while (ix != start);
- erl_exit(ERTS_ABORT_EXIT, "Logical cpu id %d not found\n", logical);
+ erts_exit(ERTS_ABORT_EXIT, "Logical cpu id %d not found\n", logical);
}
static void
diff --git a/erts/emulator/beam/erl_cpu_topology.h b/erts/emulator/beam/erl_cpu_topology.h
index b502258dae..f3fbfc6da0 100644
--- a/erts/emulator/beam/erl_cpu_topology.h
+++ b/erts/emulator/beam/erl_cpu_topology.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 8f246ffa07..870b556851 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -279,6 +280,8 @@ static ERTS_INLINE void db_init_lock(DbTable* tb, int use_frequent_read_lock,
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
if (use_frequent_read_lock)
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
+ if (erts_ets_rwmtx_spin_count >= 0)
+ rwmtx_opt.main_spincount = erts_ets_rwmtx_spin_count;
#endif
#ifdef ERTS_SMP
erts_smp_rwmtx_init_opt_x(&tb->common.rwlock, &rwmtx_opt,
@@ -620,7 +623,7 @@ BIF_RETTYPE ets_safe_fixtable_2(BIF_ALIST_2)
erts_fprintf(stderr,
"ets:safe_fixtable(%T,%T); Process: %T, initial: %T:%T/%bpu\n",
BIF_ARG_1, BIF_ARG_2, BIF_P->common.id,
- BIF_P->initial[0], BIF_P->initial[1], BIF_P->initial[2]);
+ BIF_P->u.initial[0], BIF_P->u.initial[1], BIF_P->u.initial[2]);
#endif
kind = (BIF_ARG_2 == am_true) ? LCK_READ : LCK_WRITE_REC;
@@ -753,6 +756,31 @@ BIF_RETTYPE ets_prev_2(BIF_ALIST_2)
BIF_RET(ret);
}
+/*
+** take(Tab, Key)
+*/
+BIF_RETTYPE ets_take_2(BIF_ALIST_2)
+{
+ DbTable* tb;
+#ifdef DEBUG
+ int cret;
+#endif
+ Eterm ret;
+ CHECK_TABLES();
+
+ tb = db_get_table(BIF_P, BIF_ARG_1, DB_WRITE, LCK_WRITE_REC);
+ if (!tb) {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+#ifdef DEBUG
+ cret =
+#endif
+ tb->common.meth->db_take(BIF_P, tb, BIF_ARG_2, &ret);
+ ASSERT(cret == DB_ERROR_NONE);
+ db_unlock(tb, LCK_WRITE_REC);
+ BIF_RET(ret);
+}
+
/*
** update_element(Tab, Key, {Pos, Value})
** update_element(Tab, Key, [{Pos, Value}])
@@ -780,7 +808,7 @@ BIF_RETTYPE ets_update_element_3(BIF_ALIST_3)
list = BIF_ARG_3;
}
- if (!tb->common.meth->db_lookup_dbterm(tb, BIF_ARG_2, &handle)) {
+ if (!tb->common.meth->db_lookup_dbterm(BIF_P, tb, BIF_ARG_2, THE_NON_VALUE, &handle)) {
cret = DB_ERROR_BADKEY;
goto bail_out;
}
@@ -819,7 +847,7 @@ BIF_RETTYPE ets_update_element_3(BIF_ALIST_3)
}
finalize:
- tb->common.meth->db_finalize_dbterm(&handle);
+ tb->common.meth->db_finalize_dbterm(cret, &handle);
bail_out:
UnUseTmpHeap(2,BIF_P);
@@ -838,14 +866,8 @@ bail_out:
}
}
-/*
-** update_counter(Tab, Key, Incr)
-** update_counter(Tab, Key, {Upop})
-** update_counter(Tab, Key, [{Upop}])
-** Upop = {Pos,Incr} | {Pos,Incr,Threshold,WarpTo}
-** Returns new value(s) (integer or [integer])
-*/
-BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
+static BIF_RETTYPE
+do_update_counter(Process *p, Eterm arg1, Eterm arg2, Eterm arg3, Eterm arg4)
{
DbTable* tb;
int cret = DB_ERROR_BADITEM;
@@ -855,7 +877,7 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
Eterm* ret_list_currp = NULL;
Eterm* ret_list_prevp = NULL;
Eterm iter;
- DeclareTmpHeap(cell,5,BIF_P);
+ DeclareTmpHeap(cell, 5, p);
Eterm *tuple = cell+2;
DbUpdateHandle handle;
Uint halloc_size = 0; /* overestimated heap usage */
@@ -863,28 +885,29 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
Eterm* hstart;
Eterm* hend;
- if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_WRITE, LCK_WRITE_REC)) == NULL) {
- BIF_ERROR(BIF_P, BADARG);
+ if ((tb = db_get_table(p, arg1, DB_WRITE, LCK_WRITE_REC)) == NULL) {
+ BIF_ERROR(p, BADARG);
}
- UseTmpHeap(5,BIF_P);
+ UseTmpHeap(5, p);
if (!(tb->common.status & (DB_SET | DB_ORDERED_SET))) {
goto bail_out;
}
- if (is_integer(BIF_ARG_3)) { /* Incr */
- upop_list = CONS(cell, TUPLE2(tuple, make_small(tb->common.keypos+1),
- BIF_ARG_3), NIL);
+ if (is_integer(arg3)) { /* Incr */
+ upop_list = CONS(cell,
+ TUPLE2(tuple, make_small(tb->common.keypos+1), arg3),
+ NIL);
}
- else if (is_tuple(BIF_ARG_3)) { /* {Upop} */
- upop_list = CONS(cell, BIF_ARG_3, NIL);
+ else if (is_tuple(arg3)) { /* {Upop} */
+ upop_list = CONS(cell, arg3, NIL);
}
else { /* [{Upop}] (probably) */
- upop_list = BIF_ARG_3;
+ upop_list = arg3;
ret_list_prevp = &ret;
}
- if (!tb->common.meth->db_lookup_dbterm(tb, BIF_ARG_2, &handle)) {
+ if (!tb->common.meth->db_lookup_dbterm(p, tb, arg2, arg4, &handle)) {
goto bail_out; /* key not found */
}
@@ -957,13 +980,13 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
if (ret_list_prevp) { /* Prepare to return a list */
ret = NIL;
halloc_size += list_size;
- hstart = HAlloc(BIF_P, halloc_size);
+ hstart = HAlloc(p, halloc_size);
ret_list_currp = hstart;
htop = hstart + list_size;
hend = hstart + halloc_size;
}
else {
- hstart = htop = HAlloc(BIF_P, halloc_size);
+ hstart = htop = HAlloc(p, halloc_size);
}
hend = hstart + halloc_size;
@@ -1010,26 +1033,54 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
(is_list(ret) && (list_val(ret)+list_size)==ret_list_currp));
ASSERT(htop <= hend);
- HRelease(BIF_P,hend,htop);
+ HRelease(p, hend, htop);
finalize:
- tb->common.meth->db_finalize_dbterm(&handle);
+ tb->common.meth->db_finalize_dbterm(cret, &handle);
bail_out:
- UnUseTmpHeap(5,BIF_P);
+ UnUseTmpHeap(5, p);
db_unlock(tb, LCK_WRITE_REC);
switch (cret) {
case DB_ERROR_NONE:
BIF_RET(ret);
case DB_ERROR_SYSRES:
- BIF_ERROR(BIF_P, SYSTEM_LIMIT);
+ BIF_ERROR(p, SYSTEM_LIMIT);
default:
- BIF_ERROR(BIF_P, BADARG);
+ BIF_ERROR(p, BADARG);
break;
}
}
+/*
+** update_counter(Tab, Key, Incr)
+** update_counter(Tab, Key, Upop)
+** update_counter(Tab, Key, [{Upop}])
+** Upop = {Pos,Incr} | {Pos,Incr,Threshold,WarpTo}
+** Returns new value(s) (integer or [integer])
+*/
+BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
+{
+ return do_update_counter(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3, THE_NON_VALUE);
+}
+
+/*
+** update_counter(Tab, Key, Incr, Default)
+** update_counter(Tab, Key, Upop, Default)
+** update_counter(Tab, Key, [{Upop}], Default)
+** Upop = {Pos,Incr} | {Pos,Incr,Threshold,WarpTo}
+** Returns new value(s) (integer or [integer])
+*/
+BIF_RETTYPE ets_update_counter_4(BIF_ALIST_4)
+{
+ if (is_not_tuple(BIF_ARG_4)) {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ return do_update_counter(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3, BIF_ARG_4);
+}
+
+
/*
** The put BIF
*/
@@ -1199,7 +1250,7 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
erts_fprintf(stderr,
"ets:rename(%T,%T); Process: %T, initial: %T:%T/%bpu\n",
BIF_ARG_1, BIF_ARG_2, BIF_P->common.id,
- BIF_P->initial[0], BIF_P->initial[1], BIF_P->initial[2]);
+ BIF_P->u.initial[0], BIF_P->u.initial[1], BIF_P->u.initial[2]);
#endif
@@ -1244,7 +1295,7 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
goto badarg;
if (!remove_named_tab(tb, 1))
- erl_exit(1,"Could not find named tab %s", tb->common.id);
+ erts_exit(ERTS_ERROR_EXIT,"Could not find named tab %s", tb->common.id);
tb->common.id = tb->common.the_name = BIF_ARG_2;
@@ -1325,7 +1376,6 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
status |= DB_ORDERED_SET;
status &= ~(DB_SET | DB_BAG | DB_DUPLICATE_BAG);
}
- /*TT*/
else if (is_tuple(val)) {
Eterm *tp = tuple_val(val);
if (arityval(tp[0]) == 2) {
@@ -1515,7 +1565,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
erts_fprintf(stderr,
"ets:new(%T,%T)=%T; Process: %T, initial: %T:%T/%bpu\n",
BIF_ARG_1, BIF_ARG_2, ret, BIF_P->common.id,
- BIF_P->initial[0], BIF_P->initial[1], BIF_P->initial[2]);
+ BIF_P->u.initial[0], BIF_P->u.initial[1], BIF_P->u.initial[2]);
erts_fprintf(stderr, "ets: new: meta_pid_to_tab common.memory_size = %ld\n",
erts_smp_atomic_read_nob(&meta_pid_to_tab->common.memory_size));
erts_fprintf(stderr, "ets: new: meta_pid_to_fixed_tab common.memory_size = %ld\n",
@@ -1530,7 +1580,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
BIF_P->common.id,
make_small(slot)),
0) != DB_ERROR_NONE) {
- erl_exit(1,"Could not update ets metadata.");
+ erts_exit(ERTS_ERROR_EXIT,"Could not update ets metadata.");
}
db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC);
@@ -1648,7 +1698,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
erts_fprintf(stderr,
"ets:delete(%T); Process: %T, initial: %T:%T/%bpu\n",
BIF_ARG_1, BIF_P->common.id,
- BIF_P->initial[0], BIF_P->initial[1], BIF_P->initial[2]);
+ BIF_P->u.initial[0], BIF_P->u.initial[1], BIF_P->u.initial[2]);
#endif
CHECK_TABLES();
@@ -2643,7 +2693,9 @@ BIF_RETTYPE ets_match_object_3(BIF_ALIST_3)
BIF_RETTYPE ets_info_1(BIF_ALIST_1)
{
static Eterm fields[] = {am_protection, am_keypos, am_type, am_named_table,
- am_node, am_size, am_name, am_heir, am_owner, am_memory, am_compressed};
+ am_node, am_size, am_name, am_heir, am_owner, am_memory, am_compressed,
+ am_write_concurrency,
+ am_read_concurrency};
Eterm results[sizeof(fields)/sizeof(Eterm)];
DbTable* tb;
Eterm res;
@@ -2806,10 +2858,11 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3)
** External interface (NOT BIF's)
*/
+int erts_ets_rwmtx_spin_count = -1;
/* Init the db */
-void init_db(void)
+void init_db(ErtsDbSpinCount db_spin_count)
{
DbTable init_tb;
int i;
@@ -2818,10 +2871,48 @@ void init_db(void)
size_t size;
#ifdef ERTS_SMP
+ int max_spin_count = (1 << 15) - 1; /* internal limit */
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED;
+ switch (db_spin_count) {
+ case ERTS_DB_SPNCNT_NONE:
+ erts_ets_rwmtx_spin_count = 0;
+ break;
+ case ERTS_DB_SPNCNT_VERY_LOW:
+ erts_ets_rwmtx_spin_count = 100;
+ break;
+ case ERTS_DB_SPNCNT_LOW:
+ erts_ets_rwmtx_spin_count = 200;
+ erts_ets_rwmtx_spin_count += erts_no_schedulers * 50;
+ if (erts_ets_rwmtx_spin_count > 1000)
+ erts_ets_rwmtx_spin_count = 1000;
+ break;
+ case ERTS_DB_SPNCNT_HIGH:
+ erts_ets_rwmtx_spin_count = 2000;
+ erts_ets_rwmtx_spin_count += erts_no_schedulers * 100;
+ if (erts_ets_rwmtx_spin_count > 15000)
+ erts_ets_rwmtx_spin_count = 15000;
+ break;
+ case ERTS_DB_SPNCNT_VERY_HIGH:
+ erts_ets_rwmtx_spin_count = 15000;
+ erts_ets_rwmtx_spin_count += erts_no_schedulers * 500;
+ if (erts_ets_rwmtx_spin_count > max_spin_count)
+ erts_ets_rwmtx_spin_count = max_spin_count;
+ break;
+ case ERTS_DB_SPNCNT_EXTREMELY_HIGH:
+ erts_ets_rwmtx_spin_count = max_spin_count;
+ break;
+ case ERTS_DB_SPNCNT_NORMAL:
+ default:
+ erts_ets_rwmtx_spin_count = -1;
+ break;
+ }
+
+ if (erts_ets_rwmtx_spin_count >= 0)
+ rwmtx_opt.main_spincount = erts_ets_rwmtx_spin_count;
+
meta_main_tab_locks =
erts_alloc_permanent_cache_aligned(ERTS_ALC_T_DB_TABLES,
sizeof(erts_meta_main_tab_lock_t)
@@ -2848,7 +2939,7 @@ void init_db(void)
bits = erts_fit_in_bits_int32(db_max_tabs-1);
if (bits > SMALL_BITS) {
- erl_exit(1,"Max limit for ets tabled too high %u (max %u).",
+ erts_exit(ERTS_ERROR_EXIT,"Max limit for ets tabled too high %u (max %u).",
db_max_tabs, ((Uint)1)<<SMALL_BITS);
}
meta_main_tab_slot_mask = (((Uint)1)<<bits) - 1;
@@ -2909,7 +3000,7 @@ void init_db(void)
db_init_lock(meta_pid_to_tab, "meta_pid_to_tab", "meta_pid_to_tab_FIX");*/
if (db_create_hash(NULL, meta_pid_to_tab) != DB_ERROR_NONE) {
- erl_exit(1,"Unable to create ets metadata tables.");
+ erts_exit(ERTS_ERROR_EXIT,"Unable to create ets metadata tables.");
}
erts_smp_atomic_set_nob(&init_tb.common.memory_size, 0);
@@ -2940,7 +3031,7 @@ void init_db(void)
db_init_lock(meta_pid_to_fixed_tab, "meta_pid_to_fixed_tab", "meta_pid_to_fixed_tab_FIX");*/
if (db_create_hash(NULL, meta_pid_to_fixed_tab) != DB_ERROR_NONE) {
- erl_exit(1,"Unable to create ets metadata tables.");
+ erts_exit(ERTS_ERROR_EXIT,"Unable to create ets metadata tables.");
}
/* Non visual BIF to trap to. */
@@ -3137,7 +3228,7 @@ retry:
* yielding.
*/
#define ERTS_DB_INTERNAL_ERROR(LSTR) \
- erl_exit(ERTS_ABORT_EXIT, "%s:%d:erts_db_process_exiting(): " LSTR "\n", \
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d:erts_db_process_exiting(): " LSTR "\n", \
__FILE__, __LINE__)
int
@@ -3374,10 +3465,10 @@ static void fix_table_locked(Process* p, DbTable* tb)
#endif
erts_refc_inc(&tb->common.ref,1);
fix = tb->common.fixations;
- if (fix == NULL) {
- get_now(&(tb->common.megasec),
- &(tb->common.sec),
- &(tb->common.microsec));
+ if (fix == NULL) {
+ tb->common.time.monotonic
+ = erts_get_monotonic_time(ERTS_PROC_GET_SCHDATA(p));
+ tb->common.time.offset = erts_get_time_offset();
}
else {
for (; fix != NULL; fix = fix->next) {
@@ -3409,7 +3500,7 @@ static void fix_table_locked(Process* p, DbTable* tb)
make_small(tb->common.slot)),
0) != DB_ERROR_NONE) {
UnUseTmpHeap(3,p);
- erl_exit(1,"Could not insert ets metadata in safe_fixtable.");
+ erts_exit(ERTS_ERROR_EXIT,"Could not insert ets metadata in safe_fixtable.");
}
UnUseTmpHeap(3,p);
db_meta_unlock(meta_pid_to_fixed_tab, LCK_WRITE_REC);
@@ -3639,6 +3730,7 @@ static int free_table_cont(Process *p,
static Eterm table_info(Process* p, DbTable* tb, Eterm What)
{
Eterm ret = THE_NON_VALUE;
+ int use_monotonic;
if (What == am_size) {
ret = make_small(erts_smp_atomic_read_nob(&tb->common.nitems));
@@ -3670,6 +3762,10 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
ret = am_protected;
else if (tb->common.status & DB_PUBLIC)
ret = am_public;
+ } else if (What == am_write_concurrency) {
+ ret = tb->common.status & DB_FINE_LOCKED ? am_true : am_false;
+ } else if (What == am_read_concurrency) {
+ ret = tb->common.status & DB_FREQ_READ ? am_true : am_false;
} else if (What == am_name) {
ret = tb->common.the_name;
} else if (What == am_keypos) {
@@ -3692,7 +3788,10 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
ret = am_true;
else
ret = am_false;
- } else if (What == am_atom_put("safe_fixed",10)) {
+ } else if ((use_monotonic
+ = ERTS_IS_ATOM_STR("safe_fixed_monotonic_time",
+ What))
+ || ERTS_IS_ATOM_STR("safe_fixed", What)) {
#ifdef ERTS_SMP
erts_smp_mtx_lock(&tb->common.fixlock);
#endif
@@ -3701,7 +3800,19 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
Eterm *hp;
Eterm tpl, lst;
DbFixation *fix;
- need = 7;
+ Sint64 mtime;
+
+ need = 3;
+ if (use_monotonic) {
+ mtime = (Sint64) tb->common.time.monotonic;
+ mtime += ERTS_MONOTONIC_OFFSET_NATIVE;
+ if (!IS_SSMALL(mtime))
+ need += ERTS_SINT64_HEAP_SIZE(mtime);
+ }
+ else {
+ mtime = 0;
+ need += 4;
+ }
for (fix = tb->common.fixations; fix != NULL; fix = fix->next) {
need += 5;
}
@@ -3713,11 +3824,18 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
lst = CONS(hp,tpl,lst);
hp += 2;
}
- tpl = TUPLE3(hp,
- make_small(tb->common.megasec),
- make_small(tb->common.sec),
- make_small(tb->common.microsec));
- hp += 4;
+ if (use_monotonic)
+ tpl = (IS_SSMALL(mtime)
+ ? make_small(mtime)
+ : erts_sint64_to_big(mtime, &hp));
+ else {
+ Uint ms, s, us;
+ erts_make_timestamp_value(&ms, &s, &us,
+ tb->common.time.monotonic,
+ tb->common.time.offset);
+ tpl = TUPLE3(hp, make_small(ms), make_small(s), make_small(us));
+ hp += 4;
+ }
ret = TUPLE2(hp, tpl, lst);
} else {
ret = am_false;
@@ -3752,7 +3870,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
avg, std_dev_real, std_dev_exp,
make_small(stats.min_chain_len),
make_small(stats.max_chain_len),
- make_small(db_kept_items_hash(&tb->hash)));
+ make_small(stats.kept_items));
}
else {
ret = am_false;
@@ -3774,6 +3892,11 @@ static void print_table(int to, void *to_arg, int show, DbTable* tb)
+ sizeof(Uint)
- 1)
/ sizeof(Uint)));
+ erts_print(to, to_arg, "Type: %T\n", table_info(NULL, tb, am_type));
+ erts_print(to, to_arg, "Protection: %T\n", table_info(NULL, tb, am_protection));
+ erts_print(to, to_arg, "Compressed: %T\n", table_info(NULL, tb, am_compressed));
+ erts_print(to, to_arg, "Write Concurrency: %T\n", table_info(NULL, tb, am_write_concurrency));
+ 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 */
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index 5b4681fc90..a589af784c 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -61,7 +62,17 @@ union db_table {
"ERL_MAX_ETS_TABLES" */
#define ERL_MAX_ETS_TABLES_ENV "ERL_MAX_ETS_TABLES"
-void init_db(void);
+typedef enum {
+ ERTS_DB_SPNCNT_NONE,
+ ERTS_DB_SPNCNT_VERY_LOW,
+ ERTS_DB_SPNCNT_LOW,
+ ERTS_DB_SPNCNT_NORMAL,
+ ERTS_DB_SPNCNT_HIGH,
+ ERTS_DB_SPNCNT_VERY_HIGH,
+ ERTS_DB_SPNCNT_EXTREMELY_HIGH
+} ErtsDbSpinCount;
+
+void init_db(ErtsDbSpinCount);
int erts_db_process_exiting(Process *, ErtsProcLocks);
void db_info(int, void *, int);
void erts_db_foreach_table(void (*)(DbTable *, void *), void *);
@@ -69,6 +80,7 @@ void erts_db_foreach_offheap(DbTable *,
void (*func)(ErlOffHeap *, void *),
void *);
+extern int erts_ets_rwmtx_spin_count;
extern int user_requested_db_max_tabs; /* set in erl_init */
extern int erts_ets_realloc_always_moves; /* set in erl_init */
extern int erts_ets_always_compress; /* set in erl_init */
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 06dac8f161..fa925c94a5 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -147,8 +148,11 @@ static ERTS_INLINE Uint hash_to_ix(DbTableHash* tb, HashValue hval)
}
/* Remember a slot containing a pseudo-deleted item (INVALID_HASH)
-*/
-static ERTS_INLINE void add_fixed_deletion(DbTableHash* tb, int ix)
+ * Return false if we got raced by unfixing thread
+ * and the object should be deleted for real.
+ */
+static ERTS_INLINE int add_fixed_deletion(DbTableHash* tb, int ix,
+ erts_aint_t fixated_by_me)
{
erts_aint_t was_next;
erts_aint_t exp_next;
@@ -159,12 +163,18 @@ static ERTS_INLINE void add_fixed_deletion(DbTableHash* tb, int ix)
fixd->slot = ix;
was_next = erts_smp_atomic_read_acqb(&tb->fixdel);
do { /* Lockless atomic insertion in linked list: */
- exp_next = was_next;
+ if (NFIXED(tb) <= fixated_by_me) {
+ erts_db_free(ERTS_ALC_T_DB_FIX_DEL, (DbTable*)tb,
+ fixd, sizeof(FixedDeletion));
+ return 0; /* raced by unfixer */
+ }
+ exp_next = was_next;
fixd->next = (FixedDeletion*) exp_next;
- was_next = erts_smp_atomic_cmpxchg_relb(&tb->fixdel,
- (erts_aint_t) fixd,
- exp_next);
+ was_next = erts_smp_atomic_cmpxchg_mb(&tb->fixdel,
+ (erts_aint_t) fixd,
+ exp_next);
}while (was_next != exp_next);
+ return 1;
}
@@ -174,7 +184,7 @@ static ERTS_INLINE void add_fixed_deletion(DbTableHash* tb, int ix)
/* optimised version of make_hash (normal case? atomic key) */
#define MAKE_HASH(term) \
((is_atom(term) ? (atom_tab(atom_val(term))->slot.bucket.hvalue) : \
- make_hash2(term)) % MAX_HASH)
+ make_internal_hash(term)) % MAX_HASH)
#ifdef ERTS_SMP
# define DB_HASH_LOCK_MASK (DB_HASH_LOCK_CNT-1)
@@ -382,7 +392,7 @@ static HashDbTerm* search_list(DbTableHash* tb, Eterm key,
static void shrink(DbTableHash* tb, int nactive);
static void grow(DbTableHash* tb, int nactive);
static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2,
- DbTableHash*);
+ Uint sz, DbTableHash*);
static int analyze_pattern(DbTableHash *tb, Eterm pattern,
struct mp_info *mpi);
@@ -426,6 +436,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,
void *to_arg,
int show,
@@ -443,8 +454,11 @@ static int db_delete_all_objects_hash(Process* p, DbTable* tbl);
#ifdef HARDDEBUG
static void db_check_table_hash(DbTableHash *tb);
#endif
-static int db_lookup_dbterm_hash(DbTable *tbl, Eterm key, DbUpdateHandle* handle);
-static void db_finalize_dbterm_hash(DbUpdateHandle* handle);
+static int
+db_lookup_dbterm_hash(Process *p, DbTable *tbl, Eterm key, Eterm obj,
+ DbUpdateHandle* handle);
+static void
+db_finalize_dbterm_hash(int cret, DbUpdateHandle* handle);
static ERTS_INLINE void try_shrink(DbTableHash* tb)
{
@@ -536,6 +550,7 @@ DbTableMethod db_hash =
db_select_delete_continue_hash,
db_select_count_hash,
db_select_count_continue_hash,
+ db_take_hash,
db_delete_all_objects_hash,
db_free_table_hash,
db_free_table_continue_hash,
@@ -601,8 +616,8 @@ void db_unfix_table_hash(DbTableHash *tb)
|| (erts_smp_lc_rwmtx_is_rlocked(&tb->common.rwlock)
&& !tb->common.is_thread_safe));
restart:
- fixdel = (FixedDeletion*) erts_smp_atomic_xchg_acqb(&tb->fixdel,
- (erts_aint_t) NULL);
+ fixdel = (FixedDeletion*) erts_smp_atomic_xchg_mb(&tb->fixdel,
+ (erts_aint_t) NULL);
while (fixdel != NULL) {
FixedDeletion *fx = fixdel;
int ix = fx->slot;
@@ -646,25 +661,6 @@ restart:
/* ToDo: Maybe try grow/shrink the table as well */
}
-/* Only used by tests
-*/
-Uint db_kept_items_hash(DbTableHash *tb)
-{
- Uint kept_items = 0;
- Uint ix = 0;
- erts_smp_rwmtx_t* lck = RLOCK_HASH(tb,ix);
- HashDbTerm* b;
- do {
- for (b = BUCKET(tb, ix); b != NULL; b = b->next) {
- if (b->hvalue == INVALID_HASH) {
- ++kept_items;
- }
- }
- ix = next_slot(tb, ix, &lck);
- }while (ix);
- return kept_items;
-}
-
int db_create_hash(Process *p, DbTable *tbl)
{
DbTableHash *tb = &tbl->hash;
@@ -684,6 +680,8 @@ int db_create_hash(Process *p, DbTable *tbl)
int i;
if (tb->common.type & DB_FREQ_READ)
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
+ if (erts_ets_rwmtx_spin_count >= 0)
+ rwmtx_opt.main_spincount = erts_ets_rwmtx_spin_count;
tb->locks = (DbTableHashFineLocks*) erts_db_alloc_fnf(ERTS_ALC_T_DB_SEG, /* Other type maybe? */
(DbTable *) tb,
sizeof(DbTableHashFineLocks));
@@ -879,34 +877,49 @@ Ldone:
return ret;
}
+static Eterm
+get_term_list(Process *p, DbTableHash *tb, Eterm key, HashValue hval,
+ HashDbTerm *b1, HashDbTerm **bend)
+{
+ HashDbTerm* b2 = b1->next;
+ Eterm copy;
+ Uint sz = b1->dbterm.size + 2;
+
+ if (tb->common.status & (DB_BAG | DB_DUPLICATE_BAG)) {
+ while (b2 && has_key(tb, b2, key, hval)) {
+ if (b2->hvalue != INVALID_HASH)
+ sz += b2->dbterm.size + 2;
+
+ b2 = b2->next;
+ }
+ }
+ copy = build_term_list(p, b1, b2, sz, tb);
+ CHECK_TABLES();
+ if (bend) {
+ *bend = b2;
+ }
+ return copy;
+}
+
int db_get_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
{
DbTableHash *tb = &tbl->hash;
HashValue hval;
int ix;
- HashDbTerm* b1;
+ HashDbTerm* b;
erts_smp_rwmtx_t* lck;
hval = MAKE_HASH(key);
lck = RLOCK_HASH(tb,hval);
ix = hash_to_ix(tb, hval);
- b1 = BUCKET(tb, ix);
+ b = BUCKET(tb, ix);
- while(b1 != 0) {
- if (has_live_key(tb,b1,key,hval)) {
- HashDbTerm* b2 = b1->next;
- Eterm copy;
-
- if (tb->common.status & (DB_BAG | DB_DUPLICATE_BAG)) {
- while(b2 != NULL && has_key(tb,b2,key,hval))
- b2 = b2->next;
- }
- copy = build_term_list(p, b1, b2, tb);
- CHECK_TABLES();
- *ret = copy;
+ while(b != 0) {
+ if (has_live_key(tb, b, key, hval)) {
+ *ret = get_term_list(p, tb, key, hval, b, NULL);
goto done;
}
- b1 = b1->next;
+ b = b->next;
}
*ret = NIL;
done:
@@ -1048,7 +1061,6 @@ static int db_get_element_hash(Process *p, DbTable *tbl,
Eterm copy = db_copy_element_from_ets(&tb->common, p,
&b->dbterm, ndex, &hp, 2);
elem_list = CONS(hp, copy, elem_list);
- hp += 2;
}
b = b->next;
}
@@ -1139,9 +1151,9 @@ int db_erase_hash(DbTable *tbl, Eterm key, Eterm *ret)
while(b != 0) {
if (has_live_key(tb,b,key,hval)) {
--nitems_diff;
- if (nitems_diff == -1 && IS_FIXED(tb)) {
+ if (nitems_diff == -1 && IS_FIXED(tb)
+ && add_fixed_deletion(tb, ix, 0)) {
/* Pseudo remove (no need to keep several of same key) */
- add_fixed_deletion(tb, ix);
b->hvalue = INVALID_HASH;
} else {
*bp = b->next;
@@ -1193,9 +1205,8 @@ static int db_erase_object_hash(DbTable *tbl, Eterm object, Eterm *ret)
++nkeys;
if (db_eq(&tb->common,object, &b->dbterm)) {
--nitems_diff;
- if (nkeys==1 && IS_FIXED(tb)) { /* Pseudo remove */
- add_fixed_deletion(tb,ix);
- b->hvalue = INVALID_HASH;
+ if (nkeys==1 && IS_FIXED(tb) && add_fixed_deletion(tb,ix,0)) {
+ b->hvalue = INVALID_HASH; /* Pseudo remove */
bp = &b->next;
b = b->next;
} else {
@@ -1240,7 +1251,7 @@ static int db_slot_hash(Process *p, DbTable *tbl, Eterm slot_term, Eterm *ret)
lck = RLOCK_HASH(tb, slot);
nactive = NACTIVE(tb);
if (slot < nactive) {
- *ret = build_term_list(p, BUCKET(tb, slot), 0, tb);
+ *ret = build_term_list(p, BUCKET(tb, slot), NULL, 0, tb);
retval = DB_ERROR_NONE;
}
else if (slot == nactive) {
@@ -1817,14 +1828,17 @@ static int db_select_delete_hash(Process *p,
int did_erase = 0;
if (db_match_dbterm(&tb->common, p, mpi.mp, 0,
&(*current)->dbterm, NULL, 0) == am_true) {
+ HashDbTerm *del;
if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */
if (slot_ix != last_pseudo_delete) {
- add_fixed_deletion(tb, slot_ix);
- last_pseudo_delete = slot_ix;
+ if (!add_fixed_deletion(tb, slot_ix, fixated_by_me))
+ goto do_erase;
+ last_pseudo_delete = slot_ix;
}
(*current)->hvalue = INVALID_HASH;
} else {
- HashDbTerm *del = *current;
+ do_erase:
+ del = *current;
*current = (*current)->next;
free_term(tb, del);
did_erase = 1;
@@ -1928,14 +1942,17 @@ static int db_select_delete_continue_hash(Process *p,
int did_erase = 0;
if (db_match_dbterm(&tb->common, p, mp, 0,
&(*current)->dbterm, NULL, 0) == am_true) {
+ HashDbTerm *del;
if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */
if (slot_ix != last_pseudo_delete) {
- add_fixed_deletion(tb, slot_ix);
+ if (!add_fixed_deletion(tb, slot_ix, fixated_by_me))
+ goto do_erase;
last_pseudo_delete = slot_ix;
}
(*current)->hvalue = INVALID_HASH;
} else {
- HashDbTerm *del = *current;
+ do_erase:
+ del = *current;
*current = (*current)->next;
free_term(tb, del);
did_erase = 1;
@@ -2069,6 +2086,46 @@ trap:
}
+static int db_take_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
+{
+ DbTableHash *tb = &tbl->hash;
+ HashDbTerm **bp, *b;
+ HashValue hval = MAKE_HASH(key);
+ erts_smp_rwmtx_t *lck = WLOCK_HASH(tb, hval);
+ int ix = hash_to_ix(tb, hval);
+ int nitems_diff = 0;
+
+ *ret = NIL;
+ for (bp = &BUCKET(tb, ix), b = *bp; b; bp = &b->next, b = b->next) {
+ if (has_live_key(tb, b, key, hval)) {
+ HashDbTerm *bend;
+
+ *ret = get_term_list(p, tb, key, hval, b, &bend);
+ while (b != bend) {
+ --nitems_diff;
+ if (nitems_diff == -1 && IS_FIXED(tb)
+ && add_fixed_deletion(tb, ix, 0)) {
+ /* Pseudo remove (no need to keep several of same key) */
+ bp = &b->next;
+ b->hvalue = INVALID_HASH;
+ b = b->next;
+ } else {
+ *bp = b->next;
+ free_term(tb, b);
+ b = *bp;
+ }
+ }
+ break;
+ }
+ }
+ WUNLOCK_HASH(lck);
+ if (nitems_diff) {
+ erts_smp_atomic_add_nob(&tb->common.nitems, nitems_diff);
+ try_shrink(tb);
+ }
+ return DB_ERROR_NONE;
+}
+
/*
** Other interface routines (not directly coupled to one bif)
*/
@@ -2088,7 +2145,7 @@ int db_mark_all_deleted_hash(DbTable *tbl)
for (i = 0; i < NACTIVE(tb); i++) {
if ((list = BUCKET(tb,i)) != NULL) {
- add_fixed_deletion(tb, i);
+ add_fixed_deletion(tb, i, 0);
do {
list->hvalue = INVALID_HASH;
list = list->next;
@@ -2104,10 +2161,38 @@ int db_mark_all_deleted_hash(DbTable *tbl)
static void db_print_hash(int to, void *to_arg, int show, DbTable *tbl)
{
DbTableHash *tb = &tbl->hash;
+ DbHashStats stats;
int i;
erts_print(to, to_arg, "Buckets: %d\n", NACTIVE(tb));
-
+
+#ifdef ERTS_SMP
+ i = tbl->common.is_thread_safe;
+ /* If crash dumping we set table to thread safe in order to
+ avoid taking any locks */
+ if (ERTS_IS_CRASH_DUMPING)
+ tbl->common.is_thread_safe = 1;
+
+ db_calc_stats_hash(&tbl->hash, &stats);
+
+ tbl->common.is_thread_safe = i;
+#else
+ db_calc_stats_hash(&tbl->hash, &stats);
+#endif
+
+ erts_print(to, to_arg, "Chain Length Avg: %f\n", stats.avg_chain_len);
+ erts_print(to, to_arg, "Chain Length Max: %d\n", stats.max_chain_len);
+ erts_print(to, to_arg, "Chain Length Min: %d\n", stats.min_chain_len);
+ erts_print(to, to_arg, "Chain Length Std Dev: %f\n",
+ stats.std_dev_chain_len);
+ erts_print(to, to_arg, "Chain Length Expected Std Dev: %f\n",
+ stats.std_dev_expected);
+
+ if (IS_FIXED(tb))
+ erts_print(to, to_arg, "Fixed: %d\n", stats.kept_items);
+ else
+ erts_print(to, to_arg, "Fixed: false\n");
+
if (show) {
for (i = 0; i < NACTIVE(tb); i++) {
HashDbTerm* list = BUCKET(tb,i);
@@ -2402,10 +2487,10 @@ static int alloc_seg(DbTableHash *tb)
*/
static int free_seg(DbTableHash *tb, int free_records)
{
- int seg_ix = (tb->nslots >> SEGSZ_EXP) - 1;
+ const int seg_ix = (tb->nslots >> SEGSZ_EXP) - 1;
+ struct segment** const segtab = SEGTAB(tb);
+ struct ext_segment* const top = (struct ext_segment*) segtab[seg_ix];
int bytes;
- struct segment** segtab = SEGTAB(tb);
- struct ext_segment* top = (struct ext_segment*) segtab[seg_ix];
int nrecords = 0;
ASSERT(top != NULL);
@@ -2468,7 +2553,7 @@ static int free_seg(DbTableHash *tb, int free_records)
(void*)top, bytes);
#ifdef DEBUG
if (seg_ix > 0) {
- if (seg_ix < tb->nsegs) SEGTAB(tb)[seg_ix] = NULL;
+ segtab[seg_ix] = NULL;
} else {
SET_SEGTAB(tb, NULL);
}
@@ -2483,23 +2568,23 @@ static int free_seg(DbTableHash *tb, int free_records)
** Copy terms from ptr1 until ptr2
** works for ptr1 == ptr2 == 0 => []
** or ptr2 == 0
+** sz is either precalculated heap size or 0 if not known
*/
static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2,
- DbTableHash* tb)
+ Uint sz, DbTableHash* tb)
{
- int sz = 0;
HashDbTerm* ptr;
Eterm list = NIL;
Eterm copy;
Eterm *hp, *hend;
- ptr = ptr1;
- while(ptr != ptr2) {
-
- if (ptr->hvalue != INVALID_HASH)
- sz += ptr->dbterm.size + 2;
-
- ptr = ptr->next;
+ if (!sz) {
+ ptr = ptr1;
+ while(ptr != ptr2) {
+ if (ptr->hvalue != INVALID_HASH)
+ sz += ptr->dbterm.size + 2;
+ ptr = ptr->next;
+ }
}
hp = HAlloc(p, sz);
@@ -2730,59 +2815,129 @@ static HashDbTerm* next(DbTableHash *tb, Uint *iptr, erts_smp_rwmtx_t** lck_ptr,
return NULL;
}
-static int db_lookup_dbterm_hash(DbTable *tbl, Eterm key, DbUpdateHandle* handle)
+static int
+db_lookup_dbterm_hash(Process *p, DbTable *tbl, Eterm key, Eterm obj,
+ DbUpdateHandle* handle)
{
DbTableHash *tb = &tbl->hash;
- HashDbTerm* b;
- HashDbTerm** prevp;
- int ix;
HashValue hval;
+ HashDbTerm **bp, *b;
erts_smp_rwmtx_t* lck;
+ int flags = 0;
+
+ ASSERT(tb->common.status & DB_SET);
hval = MAKE_HASH(key);
- lck = WLOCK_HASH(tb,hval);
- ix = hash_to_ix(tb, hval);
- prevp = &BUCKET(tb, ix);
- b = *prevp;
+ lck = WLOCK_HASH(tb, hval);
+ bp = &BUCKET(tb, hash_to_ix(tb, hval));
+ b = *bp;
- while (b != 0) {
- if (has_live_key(tb,b,key,hval)) {
- handle->tb = tbl;
- handle->bp = (void**) prevp;
- handle->dbterm = &b->dbterm;
- handle->mustResize = 0;
- handle->new_size = b->dbterm.size;
- #if HALFWORD_HEAP
- handle->abs_vec = NULL;
- #endif
- handle->lck = lck;
- /* KEEP hval WLOCKED, db_finalize_dbterm_hash will WUNLOCK */
- return 1;
- }
- prevp = &b->next;
- b = *prevp;
+ for (;;) {
+ if (b == NULL) {
+ break;
+ }
+ if (has_key(tb, b, key, hval)) {
+ if (b->hvalue != INVALID_HASH) {
+ goto Ldone;
+ }
+ break;
+ }
+ bp = &b->next;
+ b = *bp;
}
- WUNLOCK_HASH(lck);
- return 0;
+
+ if (obj == THE_NON_VALUE) {
+ WUNLOCK_HASH(lck);
+ return 0;
+ }
+
+ {
+ Eterm *objp = tuple_val(obj);
+ int arity = arityval(*objp);
+ Eterm *htop, *hend;
+
+ ASSERT(arity >= tb->common.keypos);
+ htop = HAlloc(p, arity + 1);
+ hend = htop + arity + 1;
+ sys_memcpy(htop, objp, sizeof(Eterm) * (arity + 1));
+ htop[tb->common.keypos] = key;
+ obj = make_tuple(htop);
+
+ if (b == NULL) {
+ HashDbTerm *q = new_dbterm(tb, obj);
+
+ q->hvalue = hval;
+ q->next = NULL;
+ *bp = b = q;
+
+ {
+ int nitems = erts_smp_atomic_inc_read_nob(&tb->common.nitems);
+ int nactive = NACTIVE(tb);
+
+ if (nitems > nactive * (CHAIN_LEN + 1) && !IS_FIXED(tb)) {
+ grow(tb, nactive);
+ }
+ }
+ } else {
+ HashDbTerm *q, *next = b->next;
+
+ ASSERT(b->hvalue == INVALID_HASH);
+ q = replace_dbterm(tb, b, obj);
+ q->next = next;
+ q->hvalue = hval;
+ *bp = b = q;
+ erts_smp_atomic_inc_nob(&tb->common.nitems);
+ }
+
+ HRelease(p, hend, htop);
+ flags |= DB_NEW_OBJECT;
+ }
+
+Ldone:
+ handle->tb = tbl;
+ handle->bp = (void **)bp;
+ handle->dbterm = &b->dbterm;
+ handle->flags = flags;
+ handle->new_size = b->dbterm.size;
+#if HALFWORD_HEAP
+ handle->abs_vec = NULL;
+#endif
+ handle->lck = lck;
+ return 1;
}
/* Must be called after call to db_lookup_dbterm
*/
-static void db_finalize_dbterm_hash(DbUpdateHandle* handle)
+static void
+db_finalize_dbterm_hash(int cret, DbUpdateHandle* handle)
{
DbTable* tbl = handle->tb;
- HashDbTerm* oldp = (HashDbTerm*) *(handle->bp);
+ DbTableHash *tb = &tbl->hash;
+ HashDbTerm **bp = (HashDbTerm **) handle->bp;
+ HashDbTerm *b = *bp;
erts_smp_rwmtx_t* lck = (erts_smp_rwmtx_t*) handle->lck;
- ERTS_SMP_LC_ASSERT(IS_HASH_WLOCKED(&tbl->hash,lck)); /* locked by db_lookup_dbterm_hash */
+ ERTS_SMP_LC_ASSERT(IS_HASH_WLOCKED(tb, lck)); /* locked by db_lookup_dbterm_hash */
+
+ ASSERT((&b->dbterm == handle->dbterm) == !(tb->common.compress && handle->flags & DB_MUST_RESIZE));
- ASSERT((&oldp->dbterm == handle->dbterm) == !(tbl->common.compress && handle->mustResize));
+ if (handle->flags & DB_NEW_OBJECT && cret != DB_ERROR_NONE) {
+ if (IS_FIXED(tb) && add_fixed_deletion(tb, hash_to_ix(tb, b->hvalue),
+ 0)) {
+ b->hvalue = INVALID_HASH;
+ } else {
+ *bp = b->next;
+ free_term(tb, b);
+ }
- if (handle->mustResize) {
+ WUNLOCK_HASH(lck);
+ erts_smp_atomic_dec_nob(&tb->common.nitems);
+ try_shrink(tb);
+ } else if (handle->flags & DB_MUST_RESIZE) {
db_finalize_resize(handle, offsetof(HashDbTerm,dbterm));
WUNLOCK_HASH(lck);
- free_term(&tbl->hash, oldp);
+ free_term(tb, b);
}
else {
WUNLOCK_HASH(lck);
@@ -2833,6 +2988,7 @@ void db_calc_stats_hash(DbTableHash* tb, DbHashStats* stats)
erts_smp_rwmtx_t* lck;
int sum = 0;
int sq_sum = 0;
+ int kept_items = 0;
int ix;
int len;
@@ -2844,6 +3000,8 @@ void db_calc_stats_hash(DbTableHash* tb, DbHashStats* stats)
len = 0;
for (b = BUCKET(tb,ix); b!=NULL; b=b->next) {
len++;
+ if (b->hvalue == INVALID_HASH)
+ ++kept_items;
}
sum += len;
sq_sum += len*len;
@@ -2855,7 +3013,8 @@ void db_calc_stats_hash(DbTableHash* tb, DbHashStats* stats)
stats->std_dev_chain_len = sqrt((sq_sum - stats->avg_chain_len*sum) / NACTIVE(tb));
/* Expected standard deviation from a good uniform hash function,
ie binomial distribution (not taking the linear hashing into acount) */
- stats->std_dev_expected = sqrt(stats->avg_chain_len * (1 - 1.0/NACTIVE(tb)));
+ stats->std_dev_expected = sqrt(stats->avg_chain_len * (1 - 1.0/NACTIVE(tb)));
+ stats->kept_items = kept_items;
}
#ifdef HARDDEBUG
@@ -2869,7 +3028,7 @@ void db_check_table_hash(DbTable *tbl)
if ((list = BUCKET(tb,j)) != 0) {
while (list != 0) {
if (!is_tuple(make_tuple(list->dbterm.tpl))) {
- erl_exit(1, "Bad term in slot %d of ets table", j);
+ erts_exit(ERTS_ERROR_EXIT, "Bad term in slot %d of ets table", j);
}
list = list->next;
}
diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h
index 908cec11d4..66d8ec71d9 100644
--- a/erts/emulator/beam/erl_db_hash.h
+++ b/erts/emulator/beam/erl_db_hash.h
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2013. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -42,7 +43,7 @@ typedef struct hash_db_term {
typedef struct db_table_hash_fine_locks {
union {
erts_smp_rwmtx_t lck;
- byte _cache_line_alignment[64];
+ byte _cache_line_alignment[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_smp_rwmtx_t))];
}lck_vec[DB_HASH_LOCK_CNT];
} DbTableHashFineLocks;
@@ -104,6 +105,7 @@ typedef struct {
float std_dev_expected;
int max_chain_len;
int min_chain_len;
+ int kept_items;
}DbHashStats;
void db_calc_stats_hash(DbTableHash* tb, DbHashStats*);
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index a62a83a928..61293fbf9a 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -383,6 +384,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
Eterm pattern, Eterm *ret);
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,
int show, DbTable *tbl);
static int db_free_table_tree(DbTable *tbl);
@@ -398,8 +400,11 @@ static int db_delete_all_objects_tree(Process* p, DbTable* tbl);
#ifdef HARDDEBUG
static void db_check_table_tree(DbTable *tbl);
#endif
-static int db_lookup_dbterm_tree(DbTable *, Eterm key, DbUpdateHandle*);
-static void db_finalize_dbterm_tree(DbUpdateHandle*);
+static int
+db_lookup_dbterm_tree(Process *, DbTable *, Eterm key, Eterm obj,
+ DbUpdateHandle*);
+static void
+db_finalize_dbterm_tree(int cret, DbUpdateHandle *);
/*
** Static variables
@@ -431,6 +436,7 @@ DbTableMethod db_tree =
db_select_delete_continue_tree,
db_select_count_tree,
db_select_count_continue_tree,
+ db_take_tree,
db_delete_all_objects_tree,
db_free_table_tree,
db_free_table_continue_tree,
@@ -1111,7 +1117,7 @@ static int db_select_tree(Process *p, DbTable *tbl,
sc.all_objects = mpi.all_objects;
if (!mpi.got_partial && mpi.some_limitation &&
- CMP(mpi.least,mpi.most) == 0) {
+ CMP_EQ(mpi.least,mpi.most)) {
doit_select(tb,mpi.save_term,&sc,0 /* direction doesn't matter */);
RET_TO_BIF(sc.accum,DB_ERROR_NONE);
}
@@ -1207,7 +1213,7 @@ static int db_select_count_continue_tree(Process *p,
tptr = tuple_val(continuation);
if (arityval(*tptr) != 5)
- erl_exit(1,"Internal error in ets:select_count/1");
+ erts_exit(ERTS_ERROR_EXIT,"Internal error in ets:select_count/1");
lastkey = tptr[2];
end_condition = tptr[3];
@@ -1319,7 +1325,7 @@ static int db_select_count_tree(Process *p, DbTable *tbl,
sc.all_objects = mpi.all_objects;
if (!mpi.got_partial && mpi.some_limitation &&
- CMP(mpi.least,mpi.most) == 0) {
+ CMP_EQ(mpi.least,mpi.most)) {
doit_select_count(tb,mpi.save_term,&sc,0 /* dummy */);
RET_TO_BIF(erts_make_integer(sc.got,p),DB_ERROR_NONE);
}
@@ -1424,7 +1430,7 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl,
sc.all_objects = mpi.all_objects;
if (!mpi.got_partial && mpi.some_limitation &&
- CMP(mpi.least,mpi.most) == 0) {
+ CMP_EQ(mpi.least,mpi.most)) {
doit_select(tb,mpi.save_term,&sc, 0 /* direction doesn't matter */);
if (sc.accum != NIL) {
hp=HAlloc(p, 3);
@@ -1668,7 +1674,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
sc.mp = mpi.mp;
if (!mpi.got_partial && mpi.some_limitation &&
- CMP(mpi.least,mpi.most) == 0) {
+ CMP_EQ(mpi.least,mpi.most)) {
doit_select_delete(tb,mpi.save_term,&sc, 0 /* direction doesn't
matter */);
RET_TO_BIF(erts_make_integer(sc.accum,p),DB_ERROR_NONE);
@@ -1722,6 +1728,28 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
}
+static int db_take_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
+{
+ DbTableTree *tb = &tbl->tree;
+ TreeDbTerm *this;
+
+ *ret = NIL;
+ this = linkout_tree(tb, key, NULL);
+ if (this) {
+ Eterm copy, *hp, *hend;
+
+ hp = HAlloc(p, this->dbterm.size + 2);
+ hend = hp + this->dbterm.size + 2;
+ copy = db_copy_object_from_ets(&tb->common,
+ &this->dbterm, &hp, &MSO(p));
+ *ret = CONS(hp, copy, NIL);
+ hp += 2;
+ HRelease(p, hend, hp);
+ free_term(tb, this);
+ }
+ return DB_ERROR_NONE;
+}
+
/*
** Other interface routines (not directly coupled to one bif)
*/
@@ -2522,16 +2550,43 @@ static TreeDbTerm **find_node2(DbTableTree *tb, Eterm key)
return this;
}
-static int db_lookup_dbterm_tree(DbTable *tbl, Eterm key, DbUpdateHandle* handle)
+static int
+db_lookup_dbterm_tree(Process *p, DbTable *tbl, Eterm key, Eterm obj,
+ DbUpdateHandle* handle)
{
DbTableTree *tb = &tbl->tree;
TreeDbTerm **pp = find_node2(tb, key);
-
- if (pp == NULL) return 0;
+ int flags = 0;
+
+ if (pp == NULL) {
+ if (obj == THE_NON_VALUE) {
+ return 0;
+ } else {
+ Eterm *objp = tuple_val(obj);
+ int arity = arityval(*objp);
+ Eterm *htop, *hend;
+
+ ASSERT(arity >= tb->common.keypos);
+ htop = HAlloc(p, arity + 1);
+ hend = htop + arity + 1;
+ sys_memcpy(htop, objp, sizeof(Eterm) * (arity + 1));
+ htop[tb->common.keypos] = key;
+ obj = make_tuple(htop);
+
+ if (db_put_tree(tbl, obj, 1) != DB_ERROR_NONE) {
+ return 0;
+ }
+
+ pp = find_node2(tb, key);
+ ASSERT(pp != NULL);
+ HRelease(p, hend, htop);
+ flags |= DB_NEW_OBJECT;
+ }
+ }
handle->tb = tbl;
handle->dbterm = &(*pp)->dbterm;
- handle->mustResize = 0;
+ handle->flags = flags;
handle->bp = (void**) pp;
handle->new_size = (*pp)->dbterm.size;
#if HALFWORD_HEAP
@@ -2540,15 +2595,21 @@ static int db_lookup_dbterm_tree(DbTable *tbl, Eterm key, DbUpdateHandle* handle
return 1;
}
-static void db_finalize_dbterm_tree(DbUpdateHandle* handle)
+static void
+db_finalize_dbterm_tree(int cret, DbUpdateHandle *handle)
{
- if (handle->mustResize) {
- TreeDbTerm* oldp = (TreeDbTerm*) *handle->bp;
+ DbTable *tbl = handle->tb;
+ DbTableTree *tb = &tbl->tree;
+ TreeDbTerm *bp = (TreeDbTerm *) *handle->bp;
+ if (handle->flags & DB_NEW_OBJECT && cret != DB_ERROR_NONE) {
+ Eterm ret;
+ db_erase_tree(tbl, GETKEY(tb, bp->dbterm.tpl), &ret);
+ } else if (handle->flags & DB_MUST_RESIZE) {
db_finalize_resize(handle, offsetof(TreeDbTerm,dbterm));
- reset_static_stack(&handle->tb->tree);
+ reset_static_stack(tb);
- free_term(&handle->tb->tree, oldp);
+ free_term(tb, bp);
}
#ifdef DEBUG
handle->dbterm = 0;
@@ -2656,7 +2717,7 @@ static int key_given(DbTableTree *tb, Eterm pattern, TreeDbTerm **ret,
*ret = this;
return 1;
} else if (partly_bound != NULL && key != am_Underscore &&
- db_is_variable(key) < 0)
+ db_is_variable(key) < 0 && !db_has_map(key))
*partly_bound = key;
return 0;
diff --git a/erts/emulator/beam/erl_db_tree.h b/erts/emulator/beam/erl_db_tree.h
index 7bc235e135..6098387f5d 100644
--- a/erts/emulator/beam/erl_db_tree.h
+++ b/erts/emulator/beam/erl_db_tree.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 3927615e04..af5b611afd 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -198,11 +199,6 @@ set_match_trace(Process *tracee_p, Eterm fail_term, Eterm tracer,
return ret;
}
-
-/* Type checking... */
-
-#define BOXED_IS_TUPLE(Boxed) is_arity_value(*boxed_val((Boxed)))
-
/*
**
** Types and enum's (compiled matches)
@@ -218,7 +214,9 @@ typedef enum {
matchTuple,
matchPushT,
matchPushL,
+ matchPushM,
matchPop,
+ matchSwap,
matchBind,
matchCmp,
matchEqBin,
@@ -227,11 +225,15 @@ typedef enum {
matchEqRef,
matchEq,
matchList,
+ matchMap,
+ matchKey,
matchSkip,
matchPushC,
matchConsA, /* Car is below Cdr */
matchConsB, /* Cdr is below Car (unusual) */
matchMkTuple,
+ matchMkFlatMap,
+ matchMkHashMap,
matchCall0,
matchCall1,
matchCall2,
@@ -856,6 +858,13 @@ static int match_compact(ErlHeapFragment *expr, DMCErrInfo *err_info);
static Uint my_size_object(Eterm t);
static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap);
+/* Guard subroutines */
+static void
+dmc_rearrange_constants(DMCContext *context, DMC_STACK_TYPE(UWord) *text,
+ int textpos, Eterm *p, Uint nelems);
+static DMCRet
+dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
+ Eterm *p, Uint nelems, int *constant);
/* Guard compilation */
static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(UWord) *text,
Eterm t);
@@ -869,6 +878,9 @@ static DMCRet dmc_tuple(DMCContext *context,
DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant);
+static DMCRet
+dmc_map(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
+ Eterm t, int *constant);
static DMCRet dmc_variable(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(UWord) *text,
@@ -888,12 +900,14 @@ static DMCRet compile_guard_expr(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(UWord) *text,
Eterm t);
-/* match expression subroutine */
+/* match expression subroutines */
static DMCRet dmc_one_term(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(Eterm) *stack,
DMC_STACK_TYPE(UWord) *text,
Eterm c);
+static Eterm
+dmc_private_copy(DMCContext *context, Eterm c);
#ifdef DMC_DEBUG
@@ -1364,7 +1378,112 @@ restart:
for (;;) {
switch (t & _TAG_PRIMARY_MASK) {
case TAG_PRIMARY_BOXED:
- if (!BOXED_IS_TUPLE(t)) {
+ if (is_flatmap(t)) {
+ num_iters = flatmap_get_size(flatmap_val(t));
+ if (!structure_checked) {
+ DMC_PUSH(text, matchMap);
+ DMC_PUSH(text, num_iters);
+ }
+ structure_checked = 0;
+ for (i = 0; i < num_iters; ++i) {
+ Eterm key = flatmap_get_keys(flatmap_val(t))[i];
+ if (db_is_variable(key) >= 0) {
+ if (context.err_info) {
+ add_dmc_err(context.err_info,
+ "Variable found in map key.",
+ -1, 0UL, dmcError);
+ }
+ goto error;
+ } else if (key == am_Underscore) {
+ if (context.err_info) {
+ add_dmc_err(context.err_info,
+ "Underscore found in map key.",
+ -1, 0UL, dmcError);
+ }
+ goto error;
+ }
+ DMC_PUSH(text, matchKey);
+ DMC_PUSH(text, dmc_private_copy(&context, key));
+ {
+ int old_stack = ++(context.stack_used);
+ Eterm value = flatmap_get_values(flatmap_val(t))[i];
+ res = dmc_one_term(&context, &heap, &stack, &text,
+ value);
+ ASSERT(res != retFail);
+ if (res == retRestart) {
+ goto restart;
+ }
+ if (old_stack != context.stack_used) {
+ ASSERT(old_stack + 1 == context.stack_used);
+ DMC_PUSH(text, matchSwap);
+ }
+ if (context.stack_used > context.stack_need) {
+ context.stack_need = context.stack_used;
+ }
+ DMC_PUSH(text, matchPop);
+ --(context.stack_used);
+ }
+ }
+ break;
+ }
+ if (is_hashmap(t)) {
+ DECLARE_WSTACK(wstack);
+ Eterm *kv;
+ num_iters = hashmap_size(t);
+ if (!structure_checked) {
+ DMC_PUSH(text, matchMap);
+ DMC_PUSH(text, num_iters);
+ }
+ structure_checked = 0;
+
+ hashmap_iterator_init(&wstack, t, 0);
+
+ while ((kv=hashmap_iterator_next(&wstack)) != NULL) {
+ Eterm key = CAR(kv);
+ Eterm value = CDR(kv);
+ if (db_is_variable(key) >= 0) {
+ if (context.err_info) {
+ add_dmc_err(context.err_info,
+ "Variable found in map key.",
+ -1, 0UL, dmcError);
+ }
+ DESTROY_WSTACK(wstack);
+ goto error;
+ } else if (key == am_Underscore) {
+ if (context.err_info) {
+ add_dmc_err(context.err_info,
+ "Underscore found in map key.",
+ -1, 0UL, dmcError);
+ }
+ DESTROY_WSTACK(wstack);
+ goto error;
+ }
+ DMC_PUSH(text, matchKey);
+ DMC_PUSH(text, dmc_private_copy(&context, key));
+ {
+ int old_stack = ++(context.stack_used);
+ res = dmc_one_term(&context, &heap, &stack, &text,
+ value);
+ ASSERT(res != retFail);
+ if (res == retRestart) {
+ DESTROY_WSTACK(wstack);
+ goto restart;
+ }
+ if (old_stack != context.stack_used) {
+ ASSERT(old_stack + 1 == context.stack_used);
+ DMC_PUSH(text, matchSwap);
+ }
+ if (context.stack_used > context.stack_need) {
+ context.stack_need = context.stack_used;
+ }
+ DMC_PUSH(text, matchPop);
+ --(context.stack_used);
+ }
+ }
+ DESTROY_WSTACK(wstack);
+ break;
+ }
+ if (!is_tuple(t)) {
goto simple_term;
}
num_iters = arityval(*tuple_val(t));
@@ -1715,10 +1834,8 @@ Eterm db_prog_match(Process *c_p, Binary *bprog,
Uint32 *return_flags)
{
MatchProg *prog = Binary2MatchProg(bprog);
- Eterm *ep;
- Eterm *tp;
+ const Eterm *ep, *tp, **sp;
Eterm t;
- Eterm **sp;
Eterm *esp;
MatchVariable* variables;
BeamInstr *cp;
@@ -1808,7 +1925,7 @@ Eterm db_prog_match(Process *c_p, Binary *bprog,
restart:
ep = &term;
esp = (Eterm*)((char*)mpsp->u.heap + prog->stack_offset);
- sp = (Eterm **) esp;
+ sp = (const Eterm **)esp;
ret = am_true;
do_catch = 0;
fail_label = -1;
@@ -1829,11 +1946,11 @@ restart:
#ifdef DMC_DEBUG
if (*heap_fence != FENCE_PATTERN) {
- erl_exit(1, "Heap fence overwritten in db_prog_match after op "
+ erts_exit(ERTS_ERROR_EXIT, "Heap fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op, *heap_fence);
}
if (*stack_fence != FENCE_PATTERN) {
- erl_exit(1, "Stack fence overwritten in db_prog_match after op "
+ erts_exit(ERTS_ERROR_EXIT, "Stack fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op,
*stack_fence);
}
@@ -1887,9 +2004,57 @@ restart:
*sp++ = list_val_rel(*ep,base);
++ep;
break;
+ case matchMap:
+ if (!is_map_rel(*ep, base)) {
+ FAIL();
+ }
+ n = *pc++;
+ if (is_flatmap_rel(*ep,base)) {
+ if (flatmap_get_size(flatmap_val_rel(*ep, base)) < n) {
+ FAIL();
+ }
+ } else {
+ ASSERT(is_hashmap_rel(*ep,base));
+ if (hashmap_size_rel(*ep, base) < n) {
+ FAIL();
+ }
+ }
+ ep = flatmap_val_rel(*ep, base);
+ break;
+ case matchPushM:
+ if (!is_map_rel(*ep, base)) {
+ FAIL();
+ }
+ n = *pc++;
+ if (is_flatmap_rel(*ep,base)) {
+ if (flatmap_get_size(flatmap_val_rel(*ep, base)) < n) {
+ FAIL();
+ }
+ } else {
+ ASSERT(is_hashmap_rel(*ep,base));
+ if (hashmap_size_rel(*ep, base) < n) {
+ FAIL();
+ }
+ }
+ *sp++ = flatmap_val_rel(*ep++, base);
+ break;
+ case matchKey:
+ t = (Eterm) *pc++;
+ tp = erts_maps_get_rel(t, make_boxed_rel(ep, base), base);
+ if (!tp) {
+ FAIL();
+ }
+ *sp++ = ep;
+ ep = tp;
+ break;
case matchPop:
ep = *(--sp);
break;
+ case matchSwap:
+ tp = sp[-1];
+ sp[-1] = sp[-2];
+ sp[-2] = tp;
+ break;
case matchBind:
n = *pc++;
variables[n].term = *ep++;
@@ -1987,6 +2152,39 @@ restart:
}
*esp++ = t;
break;
+ case matchMkFlatMap:
+ n = *pc++;
+ ehp = HAllocX(build_proc, MAP_HEADER_FLATMAP_SZ + n, HEAP_XTRA);
+ t = *--esp;
+ {
+ flatmap_t *m = (flatmap_t *)ehp;
+ m->thing_word = MAP_HEADER_FLATMAP;
+ m->size = n;
+ m->keys = t;
+ }
+ t = make_flatmap(ehp);
+ ehp += MAP_HEADER_FLATMAP_SZ;
+ while (n--) {
+ *ehp++ = *--esp;
+ }
+ *esp++ = t;
+ break;
+ case matchMkHashMap:
+ n = *pc++;
+ esp -= 2*n;
+ ehp = HAllocX(build_proc, 2*n, HEAP_XTRA);
+ {
+ ErtsHeapFactory factory;
+ Uint ix;
+ for (ix = 0; ix < 2*n; ix++){
+ ehp[ix] = esp[ix];
+ }
+ erts_factory_proc_init(&factory, build_proc);
+ t = erts_hashmap_from_array(&factory, ehp, n, 0);
+ erts_factory_close(&factory);
+ }
+ *esp++ = t;
+ break;
case matchCall0:
bif = (Eterm (*)(Process*, ...)) *pc++;
t = (*bif)(build_proc, bif_args);
@@ -2417,7 +2615,7 @@ restart:
case matchHalt:
goto success;
default:
- erl_exit(1, "Internal error: unexpected opcode in match program.");
+ erts_exit(ERTS_ERROR_EXIT, "Internal error: unexpected opcode in match program.");
}
}
fail:
@@ -2441,11 +2639,11 @@ success:
#ifdef DMC_DEBUG
if (*heap_fence != FENCE_PATTERN) {
- erl_exit(1, "Heap fence overwritten in db_prog_match after op "
+ erts_exit(ERTS_ERROR_EXIT, "Heap fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op, *heap_fence);
}
if (*stack_fence != FENCE_PATTERN) {
- erl_exit(1, "Stack fence overwritten in db_prog_match after op "
+ erts_exit(ERTS_ERROR_EXIT, "Stack fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op,
*stack_fence);
}
@@ -2601,10 +2799,10 @@ Wterm db_do_read_element(DbUpdateHandle* handle, Sint position)
}
ASSERT(((DbTableCommon*)handle->tb)->compress);
- ASSERT(!handle->mustResize);
+ ASSERT(!(handle->flags & DB_MUST_RESIZE));
handle->dbterm = db_alloc_tmp_uncompressed(&handle->tb->common,
handle->dbterm);
- handle->mustResize = 1;
+ handle->flags |= DB_MUST_RESIZE;
return handle->dbterm->tpl[position];
}
@@ -2637,11 +2835,11 @@ void db_do_update_element(DbUpdateHandle* handle,
#endif
return;
}
- if (!handle->mustResize) {
+ if (!(handle->flags & DB_MUST_RESIZE)) {
if (handle->tb->common.compress) {
handle->dbterm = db_alloc_tmp_uncompressed(&handle->tb->common,
handle->dbterm);
- handle->mustResize = 1;
+ handle->flags |= DB_MUST_RESIZE;
oldval = handle->dbterm->tpl[position];
#if HALFWORD_HEAP
old_base = NULL;
@@ -2701,7 +2899,7 @@ both_size_set:
/* write new value in old dbterm, finalize will make a flat copy */
handle->dbterm->tpl[position] = newval;
- handle->mustResize = 1;
+ handle->flags |= DB_MUST_RESIZE;
#if HALFWORD_HEAP
if (old_base && newval_sz > 0) {
@@ -2996,6 +3194,7 @@ Eterm db_copy_from_comp(DbTableCommon* tb, DbTerm* bp, Eterm** hpp,
{
Eterm* hp = *hpp;
int i, arity = arityval(bp->tpl[0]);
+ ErtsHeapFactory factory;
hp[0] = bp->tpl[0];
*hpp += arity + 1;
@@ -3003,17 +3202,23 @@ Eterm db_copy_from_comp(DbTableCommon* tb, DbTerm* bp, Eterm** hpp,
hp[tb->keypos] = copy_struct_rel(bp->tpl[tb->keypos],
size_object_rel(bp->tpl[tb->keypos], bp->tpl),
hpp, off_heap, bp->tpl, NULL);
+
+ erts_factory_static_init(&factory, *hpp, bp->size - (arity+1), off_heap);
+
for (i=arity; i>0; i--) {
if (i != tb->keypos) {
if (is_immed(bp->tpl[i])) {
hp[i] = bp->tpl[i];
}
else {
- hp[i] = erts_decode_ext_ets(hpp, off_heap,
+ hp[i] = erts_decode_ext_ets(&factory,
elem2ext(bp->tpl, i));
}
}
}
+ *hpp = factory.hp;
+ erts_factory_close(&factory);
+
ASSERT((*hpp - hp) <= bp->size);
#ifdef DEBUG_CLONE
ASSERT(eq_rel(make_tuple(hp),NULL,make_tuple(bp->debug_clone),bp->debug_clone));
@@ -3032,12 +3237,13 @@ Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p,
if (tb->compress && pos != tb->keypos) {
byte* ext = elem2ext(obj->tpl, pos);
Sint sz = erts_decode_ext_size_ets(ext, db_alloced_size_comp(obj)) + extra;
- Eterm* hp = HAlloc(p, sz);
- Eterm* endp = hp + sz;
- Eterm copy = erts_decode_ext_ets(&hp, &MSO(p), ext);
- *hpp = hp;
- hp += extra;
- HRelease(p, endp, hp);
+ Eterm copy;
+ ErtsHeapFactory factory;
+
+ erts_factory_proc_prealloc_init(&factory, p, sz);
+ copy = erts_decode_ext_ets(&factory, ext);
+ *hpp = erts_produce_heap(&factory, extra, 0);
+ erts_factory_close(&factory);
#ifdef DEBUG_CLONE
ASSERT(eq_rel(copy, NULL, obj->debug_clone[pos], obj->debug_clone));
#endif
@@ -3151,39 +3357,86 @@ int db_is_variable(Eterm obj)
return N;
}
+/* check if node is (or contains) a map
+ * return 1 if node contains a map
+ * return 0 otherwise
+ */
+
+int db_has_map(Eterm node) {
+ DECLARE_ESTACK(s);
+
+ ESTACK_PUSH(s,node);
+ while (!ESTACK_ISEMPTY(s)) {
+ node = ESTACK_POP(s);
+ if (is_list(node)) {
+ while (is_list(node)) {
+ ESTACK_PUSH(s,CAR(list_val(node)));
+ node = CDR(list_val(node));
+ }
+ ESTACK_PUSH(s,node); /* Non wellformed list or [] */
+ } else if (is_tuple(node)) {
+ Eterm *tuple = tuple_val(node);
+ int arity = arityval(*tuple);
+ while(arity--) {
+ ESTACK_PUSH(s,*(++tuple));
+ }
+ } else if is_map(node) {
+ DESTROY_ESTACK(s);
+ return 1;
+ }
+ }
+ DESTROY_ESTACK(s);
+ return 0;
+}
/* check if obj is (or contains) a variable */
/* return 1 if obj contains a variable or underscore */
/* return 0 if obj is fully ground */
-int db_has_variable(Eterm obj)
-{
- switch(obj & _TAG_PRIMARY_MASK) {
- case TAG_PRIMARY_LIST: {
- while (is_list(obj)) {
- if (db_has_variable(CAR(list_val(obj))))
+int db_has_variable(Eterm node) {
+ DECLARE_ESTACK(s);
+
+ ESTACK_PUSH(s,node);
+ while (!ESTACK_ISEMPTY(s)) {
+ node = ESTACK_POP(s);
+ switch(node & _TAG_PRIMARY_MASK) {
+ case TAG_PRIMARY_LIST:
+ while (is_list(node)) {
+ ESTACK_PUSH(s,CAR(list_val(node)));
+ node = CDR(list_val(node));
+ }
+ ESTACK_PUSH(s,node); /* Non wellformed list or [] */
+ break;
+ case TAG_PRIMARY_BOXED:
+ if (is_tuple(node)) {
+ Eterm *tuple = tuple_val(node);
+ int arity = arityval(*tuple);
+ while(arity--) {
+ ESTACK_PUSH(s,*(++tuple));
+ }
+ } else if (is_flatmap(node)) {
+ Eterm *values = flatmap_get_values(flatmap_val(node));
+ Uint size = flatmap_get_size(flatmap_val(node));
+ ESTACK_PUSH(s, ((flatmap_t *) flatmap_val(node))->keys);
+ while (size--) {
+ ESTACK_PUSH(s, *(values++));
+ }
+ } else if (is_map(node)) { /* other map-nodes or map-heads */
+ Eterm *ptr = hashmap_val(node);
+ int i = hashmap_bitcount(MAP_HEADER_VAL(*ptr));
+ ptr += MAP_HEADER_ARITY(*ptr);
+ while(i--) { ESTACK_PUSH(s, *++ptr); }
+ }
+ break;
+ case TAG_PRIMARY_IMMED1:
+ if (node == am_Underscore || db_is_variable(node) >= 0) {
+ DESTROY_ESTACK(s);
return 1;
- obj = CDR(list_val(obj));
- }
- return(db_has_variable(obj)); /* Non wellformed list or [] */
- }
- case TAG_PRIMARY_BOXED:
- if (!BOXED_IS_TUPLE(obj)) {
- return 0;
- } else {
- Eterm *tuple = tuple_val(obj);
- int arity = arityval(*tuple++);
- while(arity--) {
- if (db_has_variable(*tuple))
- return 1;
- tuple++;
}
- return(0);
+ break;
}
- case TAG_PRIMARY_IMMED1:
- if (obj == am_Underscore || db_is_variable(obj) >= 0)
- return 1;
}
+ DESTROY_ESTACK(s);
return 0;
}
@@ -3243,11 +3496,9 @@ static DMCRet dmc_one_term(DMCContext *context,
{
Sint n;
Eterm *hp;
- ErlHeapFragment *tmp_mb;
Uint sz, sz2, sz3;
Uint i, j;
-
switch (c & _TAG_PRIMARY_MASK) {
case TAG_PRIMARY_IMMED1:
if ((n = db_is_variable(c)) >= 0) { /* variable */
@@ -3334,6 +3585,16 @@ static DMCRet dmc_one_term(DMCContext *context,
DMC_PUSH(*text, n);
DMC_PUSH(*stack, c);
break;
+ case (_TAG_HEADER_MAP >> _TAG_PRIMARY_SIZE):
+ if (is_flatmap(c))
+ n = flatmap_get_size(flatmap_val(c));
+ else
+ n = hashmap_size(c);
+ DMC_PUSH(*text, matchPushM);
+ ++(context->stack_used);
+ DMC_PUSH(*text, n);
+ DMC_PUSH(*stack, c);
+ break;
case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE):
{
Eterm* ref_val = internal_ref_val(c);
@@ -3415,28 +3676,36 @@ static DMCRet dmc_one_term(DMCContext *context,
#endif
break;
default: /* BINARY, FUN, VECTOR, or EXTERNAL */
- /*
- ** Make a private copy...
- */
- n = size_object(c);
- tmp_mb = new_message_buffer(n);
- hp = tmp_mb->mem;
DMC_PUSH(*text, matchEqBin);
- DMC_PUSH(*text, copy_struct(c, n, &hp, &(tmp_mb->off_heap)));
- tmp_mb->next = context->save;
- context->save = tmp_mb;
+ DMC_PUSH(*text, dmc_private_copy(context, c));
break;
}
break;
}
default:
- erl_exit(1, "db_match_compile: "
+ erts_exit(ERTS_ERROR_EXIT, "db_match_compile: "
"Bad object on heap: 0x%bex\n", c);
}
return retOk;
}
/*
+** Make a private copy of a term in a context.
+*/
+
+static Eterm
+dmc_private_copy(DMCContext *context, Eterm c)
+{
+ Uint n = size_object(c);
+ ErlHeapFragment *tmp_mb = new_message_buffer(n);
+ Eterm *hp = tmp_mb->mem;
+ Eterm copy = copy_struct(c, n, &hp, &(tmp_mb->off_heap));
+ tmp_mb->next = context->save;
+ context->save = tmp_mb;
+ return copy;
+}
+
+/*
** Match guard compilation
*/
@@ -3527,57 +3796,78 @@ static DMCRet dmc_list(DMCContext *context,
return retOk;
}
-static DMCRet dmc_tuple(DMCContext *context,
- DMCHeap *heap,
- DMC_STACK_TYPE(UWord) *text,
- Eterm t,
- int *constant)
+static void
+dmc_rearrange_constants(DMCContext *context, DMC_STACK_TYPE(UWord) *text,
+ int textpos, Eterm *p, Uint nelems)
{
DMC_STACK_TYPE(UWord) instr_save;
+ Uint i;
+
+ DMC_INIT_STACK(instr_save);
+ while (DMC_STACK_NUM(*text) > textpos) {
+ DMC_PUSH(instr_save, DMC_POP(*text));
+ }
+ for (i = nelems; i--;) {
+ do_emit_constant(context, text, p[i]);
+ }
+ while(!DMC_EMPTY(instr_save)) {
+ DMC_PUSH(*text, DMC_POP(instr_save));
+ }
+ DMC_FREE(instr_save);
+}
+
+static DMCRet
+dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
+ Eterm *p, Uint nelems, int *constant)
+{
int all_constant = 1;
int textpos = DMC_STACK_NUM(*text);
- Eterm *p = tuple_val(t);
- Uint nelems = arityval(*p);
Uint i;
- int c;
- DMCRet ret;
/*
- ** We remember where we started to layout code,
+ ** We remember where we started to layout code,
** assume all is constant and back up and restart if not so.
- ** The tuple should be laid out with the last element first,
- ** so we can memcpy the tuple to the eheap.
+ ** The array should be laid out with the last element first,
+ ** so we can memcpy it to the eheap.
*/
- for (i = nelems; i > 0; --i) {
- if ((ret = dmc_expr(context, heap, text, p[i], &c)) != retOk)
- return ret;
- if (!c && all_constant) {
- all_constant = 0;
- if (i < nelems) {
- Uint j;
+ for (i = nelems; i--;) {
+ DMCRet ret;
+ int c;
- /*
- * Oops, we need to relayout the constants.
- * Save the already laid out instructions.
- */
- DMC_INIT_STACK(instr_save);
- while (DMC_STACK_NUM(*text) > textpos)
- DMC_PUSH(instr_save, DMC_POP(*text));
- for (j = nelems; j > i; --j)
- do_emit_constant(context, text, p[j]);
- while(!DMC_EMPTY(instr_save))
- DMC_PUSH(*text, DMC_POP(instr_save));
- DMC_FREE(instr_save);
- }
- } else if (c && !all_constant) {
- /* push a constant */
- do_emit_constant(context, text, p[i]);
- }
+ ret = dmc_expr(context, heap, text, p[i], &c);
+ if (ret != retOk) {
+ return ret;
+ }
+ if (!c && all_constant) {
+ all_constant = 0;
+ if (i < nelems - 1) {
+ dmc_rearrange_constants(context, text, textpos,
+ p + i + 1, nelems - i - 1);
+ }
+ } else if (c && !all_constant) {
+ do_emit_constant(context, text, p[i]);
+ }
+ }
+ *constant = all_constant;
+ return retOk;
+}
+
+static DMCRet
+dmc_tuple(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
+ Eterm t, int *constant)
+{
+ int all_constant;
+ Eterm *p = tuple_val(t);
+ Uint nelems = arityval(*p);
+ DMCRet ret;
+
+ ret = dmc_array(context, heap, text, p + 1, nelems, &all_constant);
+ if (ret != retOk) {
+ return ret;
}
-
if (all_constant) {
- *constant = 1;
- return retOk;
+ *constant = 1;
+ return retOk;
}
DMC_PUSH(*text, matchMkTuple);
DMC_PUSH(*text, nelems);
@@ -3586,6 +3876,93 @@ static DMCRet dmc_tuple(DMCContext *context,
return retOk;
}
+static DMCRet
+dmc_map(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
+ Eterm t, int *constant)
+{
+ int nelems;
+ int constant_values;
+ DMCRet ret;
+ if (is_flatmap(t)) {
+ flatmap_t *m = (flatmap_t *)flatmap_val(t);
+ Eterm *values = flatmap_get_values(m);
+
+ nelems = flatmap_get_size(m);
+ ret = dmc_array(context, heap, text, values, nelems, &constant_values);
+
+ if (ret != retOk) {
+ return ret;
+ }
+ if (constant_values) {
+ *constant = 1;
+ return retOk;
+ }
+ DMC_PUSH(*text, matchPushC);
+ DMC_PUSH(*text, dmc_private_copy(context, m->keys));
+ if (++context->stack_used > context->stack_need) {
+ context->stack_need = context->stack_used;
+ }
+ DMC_PUSH(*text, matchMkFlatMap);
+ DMC_PUSH(*text, nelems);
+ context->stack_used -= nelems;
+ *constant = 0;
+ return retOk;
+ } else {
+ DECLARE_WSTACK(wstack);
+ Eterm *kv;
+ int c;
+
+ ASSERT(is_hashmap(t));
+
+ hashmap_iterator_init(&wstack, t, 1);
+ constant_values = 1;
+ nelems = hashmap_size(t);
+
+ while ((kv=hashmap_iterator_prev(&wstack)) != NULL) {
+ if ((ret = dmc_expr(context, heap, text, CDR(kv), &c)) != retOk) {
+ DESTROY_WSTACK(wstack);
+ return ret;
+ }
+ if (!c)
+ constant_values = 0;
+ }
+
+ if (constant_values) {
+ *constant = 1;
+ DESTROY_WSTACK(wstack);
+ return retOk;
+ }
+
+ *constant = 0;
+
+ hashmap_iterator_init(&wstack, t, 1);
+
+ while ((kv=hashmap_iterator_prev(&wstack)) != NULL) {
+ /* push key */
+ if ((ret = dmc_expr(context, heap, text, CAR(kv), &c)) != retOk) {
+ DESTROY_WSTACK(wstack);
+ return ret;
+ }
+ if (c) {
+ do_emit_constant(context, text, CAR(kv));
+ }
+ /* push value */
+ if ((ret = dmc_expr(context, heap, text, CDR(kv), &c)) != retOk) {
+ DESTROY_WSTACK(wstack);
+ return ret;
+ }
+ if (c) {
+ do_emit_constant(context, text, CDR(kv));
+ }
+ }
+ DMC_PUSH(*text, matchMkHashMap);
+ DMC_PUSH(*text, nelems);
+ context->stack_used -= nelems;
+ DESTROY_WSTACK(wstack);
+ return retOk;
+ }
+}
+
static DMCRet dmc_whole_expression(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(UWord) *text,
@@ -4553,7 +4930,7 @@ static DMCRet dmc_fun(DMCContext *context,
DMC_PUSH(*text, matchCall3);
break;
default:
- erl_exit(1,"ets:match() internal error, "
+ erts_exit(ERTS_ERROR_EXIT,"ets:match() internal error, "
"guard with more than 3 arguments.");
}
DMC_PUSH(*text, (UWord) b->biff);
@@ -4580,7 +4957,10 @@ static DMCRet dmc_expr(DMCContext *context,
return ret;
break;
case TAG_PRIMARY_BOXED:
- if (!BOXED_IS_TUPLE(t)) {
+ if (is_map(t)) {
+ return dmc_map(context, heap, text, t, constant);
+ }
+ if (!is_tuple(t)) {
goto simple_term;
}
p = tuple_val(t);
@@ -4830,7 +5210,7 @@ static Uint my_size_object(Eterm t)
tmp == am_const) {
sum += size_object(tuple_val(t)[2]);
} else {
- erl_exit(1,"Internal error, sizing unrecognized object in "
+ erts_exit(ERTS_ERROR_EXIT,"Internal error, sizing unrecognized object in "
"(d)ets:match compilation.");
}
break;
@@ -4855,7 +5235,7 @@ static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap)
*hp += 2;
break;
case TAG_PRIMARY_BOXED:
- if (BOXED_IS_TUPLE(t)) {
+ if (is_tuple(t)) {
if (arityval(*tuple_val(t)) == 1 &&
is_tuple(a = tuple_val(t)[1])) {
Uint i,n;
@@ -4875,7 +5255,7 @@ static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap)
sz = size_object(b);
ret = copy_struct(b,sz,hp,off_heap);
} else {
- erl_exit(1, "Trying to constant-copy non constant expression "
+ erts_exit(ERTS_ERROR_EXIT, "Trying to constant-copy non constant expression "
"0x%bex in (d)ets:match compilation.", t);
}
} else {
@@ -5126,6 +5506,18 @@ void db_match_dis(Binary *bp)
++t;
erts_printf("Tuple\t%beu\n", n);
break;
+ case matchMap:
+ ++t;
+ n = *t;
+ ++t;
+ erts_printf("Map\t%beu\n", n);
+ break;
+ case matchKey:
+ ++t;
+ p = (Eterm) *t;
+ ++t;
+ erts_printf("Key\t%p (%T)\n", t, p);
+ break;
case matchPushT:
++t;
n = *t;
@@ -5136,10 +5528,20 @@ void db_match_dis(Binary *bp)
++t;
erts_printf("PushL\n");
break;
+ case matchPushM:
+ ++t;
+ n = *t;
+ ++t;
+ erts_printf("PushM\t%beu\n", n);
+ break;
case matchPop:
++t;
erts_printf("Pop\n");
break;
+ case matchSwap:
+ ++t;
+ erts_printf("Swap\n");
+ break;
case matchBind:
++t;
n = *t;
@@ -5252,6 +5654,18 @@ void db_match_dis(Binary *bp)
++t;
erts_printf("MkTuple\t%beu\n", n);
break;
+ case matchMkFlatMap:
+ ++t;
+ n = *t;
+ ++t;
+ erts_printf("MkFlatMap\t%beu\n", n);
+ break;
+ case matchMkHashMap:
+ ++t;
+ n = *t;
+ ++t;
+ erts_printf("MkHashMap\t%beu\n", n);
+ break;
case matchOr:
++t;
n = *t;
diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h
index 328b19dfc9..0903a40460 100644
--- a/erts/emulator/beam/erl_db_util.h
+++ b/erts/emulator/beam/erl_db_util.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -76,6 +77,9 @@ typedef struct db_term {
union db_table;
typedef union db_table DbTable;
+#define DB_MUST_RESIZE 1
+#define DB_NEW_OBJECT 2
+
/* Info about a database entry while it's being updated
* (by update_counter or update_element)
*/
@@ -84,7 +88,7 @@ typedef struct {
DbTerm* dbterm;
void** bp; /* {Hash|Tree}DbTerm** */
Uint new_size;
- int mustResize;
+ int flags;
void* lck;
#if HALFWORD_HEAP
unsigned char* abs_vec; /* [i] true if dbterm->tpl[i] is absolute Eterm */
@@ -165,6 +169,7 @@ typedef struct db_table_method
DbTable* tb, /* [in out] */
Eterm continuation,
Eterm* ret);
+ int (*db_take)(Process *, DbTable *, Eterm, Eterm *);
int (*db_delete_all_objects)(Process* p,
DbTable* db /* [in out] */ );
@@ -182,15 +187,14 @@ typedef struct db_table_method
void *arg);
void (*db_check_table)(DbTable* tb);
- /* Lookup a dbterm for updating. Return false if not found.
- */
- int (*db_lookup_dbterm)(DbTable*, Eterm key,
- DbUpdateHandle* handle); /* [out] */
+ /* Lookup a dbterm for updating. Return false if not found. */
+ int (*db_lookup_dbterm)(Process *, DbTable *, Eterm key, Eterm obj,
+ DbUpdateHandle* handle);
- /* Must be called for each db_lookup_dbterm that returned true,
- ** even if dbterm was not updated.
- */
- void (*db_finalize_dbterm)(DbUpdateHandle* handle);
+ /* Must be called for each db_lookup_dbterm that returned true, even if
+ ** dbterm was not updated. If the handle was of a new object and cret is
+ ** not DB_ERROR_NONE, the object is removed from the table. */
+ void (*db_finalize_dbterm)(int cret, DbUpdateHandle* handle);
} DbTableMethod;
@@ -225,7 +229,10 @@ typedef struct db_table_common {
DbTableMethod* meth; /* table methods */
erts_smp_atomic_t nitems; /* Total number of items in table */
erts_smp_atomic_t memory_size;/* Total memory size. NOTE: in bytes! */
- Uint megasec,sec,microsec; /* Last fixation time */
+ struct { /* Last fixation time */
+ ErtsMonotonicTime monotonic;
+ ErtsMonotonicTime offset;
+ } time;
DbFixation* fixations; /* List of processes who have done safe_fixtable,
"local" fixations not included. */
/* All 32-bit fields */
@@ -339,6 +346,7 @@ void* db_store_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj);
void* db_store_term_comp(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj);
Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p, DbTerm* obj,
Uint pos, Eterm** hpp, Uint extra);
+int db_has_map(Eterm obj);
int db_has_variable(Eterm obj);
int db_is_variable(Eterm obj);
void db_do_update_element(DbUpdateHandle* handle,
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index 50bdc79506..4928aae9c2 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -188,6 +189,9 @@ pdisplay1(int to, void *to_arg, Process* p, Eterm obj)
case BINARY_DEF:
erts_print(to, to_arg, "#Bin");
break;
+ case MATCHSTATE_DEF:
+ erts_print(to, to_arg, "#Matchstate");
+ break;
default:
erts_print(to, to_arg, "unknown object %x", obj);
}
@@ -251,14 +255,14 @@ void erts_check_stack(Process *p)
Eterm *stack_end = p->htop;
if (p->stop > stack_start)
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"<%lu.%lu.%lu>: Stack underflow\n",
internal_pid_channel_no(p->common.id),
internal_pid_number(p->common.id),
internal_pid_serial(p->common.id));
if (p->stop < stack_end)
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"<%lu.%lu.%lu>: Stack overflow\n",
internal_pid_channel_no(p->common.id),
internal_pid_number(p->common.id),
@@ -283,7 +287,7 @@ void erts_check_stack(Process *p)
if (in_mbuf)
continue;
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"<%lu.%lu.%lu>: Wild stack pointer\n",
internal_pid_channel_no(p->common.id),
internal_pid_number(p->common.id),
@@ -368,7 +372,7 @@ void erts_check_memory(Process *p, Eterm *start, Eterm *end)
#ifdef DEBUG
if (hval == DEBUG_BAD_WORD) {
print_untagged_memory(start, end);
- erl_exit(1, "Uninitialized HAlloc'ed memory found @ 0x%0*lx!\n",
+ erts_exit(ERTS_ERROR_EXIT, "Uninitialized HAlloc'ed memory found @ 0x%0*lx!\n",
PTR_SIZE,(unsigned long)(pos - 1));
}
#endif
@@ -381,7 +385,7 @@ void erts_check_memory(Process *p, Eterm *start, Eterm *end)
if (verify_eterm(p,hval))
continue;
- erl_exit(1, "Wild pointer found @ 0x%0*lx!\n",
+ erts_exit(ERTS_ERROR_EXIT, "Wild pointer found @ 0x%0*lx!\n",
PTR_SIZE,(unsigned long)(pos - 1));
}
}
@@ -391,11 +395,11 @@ void verify_process(Process *p)
#define VERIFY_AREA(name,ptr,sz) { \
int n = (sz); \
while (n--) if(!verify_eterm(p,*(ptr+n))) \
- erl_exit(1,"Wild pointer found in " name " of %T!\n",p->common.id); }
+ erts_exit(ERTS_ERROR_EXIT,"Wild pointer found in " name " of %T!\n",p->common.id); }
#define VERIFY_ETERM(name,eterm) { \
if(!verify_eterm(p,eterm)) \
- erl_exit(1,"Wild pointer found in " name " of %T!\n",p->common.id); }
+ erts_exit(ERTS_ERROR_EXIT,"Wild pointer found in " name " of %T!\n",p->common.id); }
ErlMessage* mp = p->msg.first;
diff --git a/erts/emulator/beam/erl_debug.h b/erts/emulator/beam/erl_debug.h
index af51212281..4905e64f07 100644
--- a/erts/emulator/beam/erl_debug.h
+++ b/erts/emulator/beam/erl_debug.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index e498ac70ec..7ab58e336b 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -36,47 +37,6 @@
# endif
#endif
-#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"
-#if defined(SIZEOF_CHAR_SAVED__) && SIZEOF_CHAR_SAVED__ != SIZEOF_CHAR
-# error SIZEOF_CHAR mismatch
-#endif
-#if defined(SIZEOF_SHORT_SAVED__) && SIZEOF_SHORT_SAVED__ != SIZEOF_SHORT
-# error SIZEOF_SHORT mismatch
-#endif
-#if defined(SIZEOF_INT_SAVED__) && SIZEOF_INT_SAVED__ != SIZEOF_INT
-# error SIZEOF_INT mismatch
-#endif
-#if defined(SIZEOF_LONG_SAVED__) && SIZEOF_LONG_SAVED__ != SIZEOF_LONG
-# error SIZEOF_LONG mismatch
-#endif
-#if defined(SIZEOF_LONG_LONG_SAVED__) && SIZEOF_LONG_LONG_SAVED__ != SIZEOF_LONG_LONG
-# error SIZEOF_LONG_LONG mismatch
-#endif
-
/* This is OK to override by the NIF/driver implementor */
#if defined(HALFWORD_HEAP_EMULATOR_SAVED__) && !defined(HALFWORD_HEAP_EMULATOR)
#define HALFWORD_HEAP_EMULATOR HALFWORD_HEAP_EMULATOR_SAVED__
@@ -133,7 +93,7 @@ typedef struct {
#define ERL_DRV_EXTENDED_MARKER (0xfeeeeeed)
#define ERL_DRV_EXTENDED_MAJOR_VERSION 3
-#define ERL_DRV_EXTENDED_MINOR_VERSION 2
+#define ERL_DRV_EXTENDED_MINOR_VERSION 3
/*
* The emulator will refuse to load a driver with a major version
@@ -175,28 +135,12 @@ typedef struct {
/*
* Integer types
*/
-#if defined(__WIN32__) && (SIZEOF_VOID_P == 8)
-typedef unsigned __int64 ErlDrvTermData;
-typedef unsigned __int64 ErlDrvUInt;
-typedef signed __int64 ErlDrvSInt;
-#else
-typedef unsigned long ErlDrvTermData;
-typedef unsigned long ErlDrvUInt;
-typedef signed long ErlDrvSInt;
-#endif
-#if defined(__WIN32__)
-typedef unsigned __int64 ErlDrvUInt64;
-typedef __int64 ErlDrvSInt64;
-#elif SIZEOF_LONG == 8
-typedef unsigned long ErlDrvUInt64;
-typedef long ErlDrvSInt64;
-#elif SIZEOF_LONG_LONG == 8
-typedef unsigned long long ErlDrvUInt64;
-typedef long long ErlDrvSInt64;
-#else
-#error No 64-bit integer type
-#endif
+typedef ErlNapiUInt64 ErlDrvUInt64;
+typedef ErlNapiSInt64 ErlDrvSInt64;
+typedef ErlNapiUInt ErlDrvUInt;
+typedef ErlNapiSInt ErlDrvSInt;
+typedef ErlNapiUInt ErlDrvTermData;
#if defined(__WIN32__) || defined(_WIN32)
typedef ErlDrvUInt ErlDrvSizeT;
@@ -249,6 +193,17 @@ typedef struct {
unsigned long microsecs;
} ErlDrvNowData;
+typedef ErlDrvSInt64 ErlDrvTime;
+
+#define ERL_DRV_TIME_ERROR ((ErlDrvSInt64) ERTS_NAPI_TIME_ERROR__)
+
+typedef enum {
+ ERL_DRV_SEC = ERTS_NAPI_SEC__,
+ ERL_DRV_MSEC = ERTS_NAPI_MSEC__,
+ ERL_DRV_USEC = ERTS_NAPI_USEC__,
+ ERL_DRV_NSEC = ERTS_NAPI_NSEC__
+} ErlDrvTimeUnit;
+
/*
* Error codes that can be return from driver.
*/
@@ -684,8 +639,16 @@ EXTERN long driver_async(ErlDrvPort ix,
EXTERN int driver_lock_driver(ErlDrvPort ix);
/* Get the current 'now' timestamp (analogue to erlang:now()) */
-EXTERN int driver_get_now(ErlDrvNowData *now);
+EXTERN int driver_get_now(ErlDrvNowData *now) ERL_DRV_DEPRECATED_FUNC;
+/* Erlang Monotonic Time */
+EXTERN ErlDrvTime erl_drv_monotonic_time(ErlDrvTimeUnit time_unit);
+/* Time offset between Erlang Monotonic Time and Erlang System Time */
+EXTERN ErlDrvTime erl_drv_time_offset(ErlDrvTimeUnit time_unit);
+/* Time unit conversion */
+EXTERN ErlDrvTime erl_drv_convert_time_unit(ErlDrvTime val,
+ ErlDrvTimeUnit from,
+ ErlDrvTimeUnit to);
/* These were removed from the ANSI version, now they're back. */
@@ -695,8 +658,8 @@ EXTERN int driver_dl_close(void *);
EXTERN char *driver_dl_error(void);
/* environment */
-EXTERN int erl_drv_putenv(char *key, char *value);
-EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size);
+EXTERN int erl_drv_putenv(const char *key, char *value);
+EXTERN int erl_drv_getenv(const char *key, char *value, size_t *value_size);
#ifdef __OSE__
typedef ErlDrvUInt ErlDrvOseEventId;
diff --git a/erts/emulator/beam/erl_drv_nif.h b/erts/emulator/beam/erl_drv_nif.h
index 4e8c6dc68b..f6b946ae82 100644
--- a/erts/emulator/beam/erl_drv_nif.h
+++ b/erts/emulator/beam/erl_drv_nif.h
@@ -3,16 +3,17 @@
*
* 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -49,6 +50,90 @@ typedef enum {
} ErlDrvDirtyJobFlags;
#endif
+#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"
+#if defined(SIZEOF_CHAR_SAVED__) && SIZEOF_CHAR_SAVED__ != SIZEOF_CHAR
+# error SIZEOF_CHAR mismatch
+#endif
+#if defined(SIZEOF_SHORT_SAVED__) && SIZEOF_SHORT_SAVED__ != SIZEOF_SHORT
+# error SIZEOF_SHORT mismatch
+#endif
+#if defined(SIZEOF_INT_SAVED__) && SIZEOF_INT_SAVED__ != SIZEOF_INT
+# error SIZEOF_INT mismatch
+#endif
+#if defined(SIZEOF_LONG_SAVED__) && SIZEOF_LONG_SAVED__ != SIZEOF_LONG
+# error SIZEOF_LONG mismatch
+#endif
+#if defined(SIZEOF_LONG_LONG_SAVED__) && SIZEOF_LONG_LONG_SAVED__ != SIZEOF_LONG_LONG
+# error SIZEOF_LONG_LONG mismatch
+#endif
+
+#if !defined(__GNUC__) && (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+typedef unsigned __int64 ErlNapiUInt64;
+typedef signed __int64 ErlNapiSInt64;
+#define ERL_NAPI_SINT64_MAX__ 9223372036854775807i64
+#define ERL_NAPI_SINT64_MIN__ (-ERL_NAPI_SINT64_MAX__ - 1i64)
+#elif SIZEOF_LONG == 8
+typedef unsigned long ErlNapiUInt64;
+typedef signed long ErlNapiSInt64;
+#define ERL_NAPI_SINT64_MAX__ 9223372036854775807L
+#define ERL_NAPI_SINT64_MIN__ (-ERL_NAPI_SINT64_MAX__ - 1L)
+#elif SIZEOF_LONG_LONG == 8
+typedef unsigned long long ErlNapiUInt64;
+typedef signed long long ErlNapiSInt64;
+#define ERL_NAPI_SINT64_MAX__ 9223372036854775807LL
+#define ERL_NAPI_SINT64_MIN__ (-ERL_NAPI_SINT64_MAX__ - 1LL)
+#else
+# error No 64-bit integer type
+#endif
+
+#if SIZEOF_VOID_P == 8
+typedef ErlNapiUInt64 ErlNapiUInt;
+typedef ErlNapiSInt64 ErlNapiSInt;
+#elif SIZEOF_VOID_P == 4
+# if SIZEOF_LONG == SIZEOF_VOID_P
+typedef unsigned long ErlNapiUInt;
+typedef signed long ErlNapiSInt;
+# elif SIZEOF_INT == SIZEOF_VOID_P
+typedef unsigned int ErlNapiUInt;
+typedef signed int ErlNapiSInt;
+# else
+# error No 32-bit integer type
+# endif
+#else
+# error Not support arch
+#endif
+
+#define ERTS_NAPI_TIME_ERROR__ ERL_NAPI_SINT64_MIN__
+
+#define ERTS_NAPI_SEC__ 0
+#define ERTS_NAPI_MSEC__ 1
+#define ERTS_NAPI_USEC__ 2
+#define ERTS_NAPI_NSEC__ 3
+
#endif /* __ERL_DRV_NIF_H__ */
diff --git a/erts/emulator/beam/erl_drv_thread.c b/erts/emulator/beam/erl_drv_thread.c
index 147249f751..184f8e8931 100644
--- a/erts/emulator/beam/erl_drv_thread.c
+++ b/erts/emulator/beam/erl_drv_thread.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -42,7 +43,7 @@ fatal_error(int err, char *func)
else
estr = "Unknown error";
}
- erl_exit(ERTS_ABORT_EXIT, "Fatal error in %s: %s [%d]\n", func, estr, err);
+ erts_exit(ERTS_ABORT_EXIT, "Fatal error in %s: %s [%d]\n", func, estr, err);
}
#define ERL_DRV_TSD_KEYS_INC 10
@@ -601,17 +602,16 @@ erl_drv_thread_create(char *name,
#ifdef USE_THREADS
int res;
struct ErlDrvTid_ *dtid;
- ethr_thr_opts ethr_opts;
+ ethr_thr_opts ethr_opts = ETHR_THR_OPTS_DEFAULT_INITER;
ethr_thr_opts *use_opts;
- ethr_thr_opts def_ethr_opts = ETHR_THR_OPTS_DEFAULT_INITER;
- if (!opts)
+ if (!opts && !name)
use_opts = NULL;
else {
- sys_memcpy((void *) &ethr_opts,
- (void *) &def_ethr_opts,
- sizeof(ethr_thr_opts));
- ethr_opts.suggested_stack_size = opts->suggested_stack_size;
+ if(opts)
+ ethr_opts.suggested_stack_size = opts->suggested_stack_size;
+
+ ethr_opts.name = name;
use_opts = &ethr_opts;
}
diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c
index 88947b5536..2f13aa364f 100644
--- a/erts/emulator/beam/erl_fun.c
+++ b/erts/emulator/beam/erl_fun.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -184,7 +185,7 @@ erts_erase_fun_entry(ErlFunEntry* fe)
#endif
{
if (fe->address != unloaded_fun)
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"Internal error: "
"Invalid reference count found on #Fun<%T.%d.%d>: "
" About to erase fun still referred by code.\n",
diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h
index b673ef6b3c..0024b1ff71 100644
--- a/erts/emulator/beam/erl_fun.h
+++ b/erts/emulator/beam/erl_fun.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 0db42d4325..f48c46ca33 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,6 +21,8 @@
# include "config.h"
#endif
+#define ERL_WANT_GC_INTERNALS__
+
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
@@ -37,6 +40,7 @@
#include "hipe_mode_switch.h"
#endif
#include "dtrace-wrapper.h"
+#include "erl_bif_unique.h"
#define ERTS_INACT_WR_PB_LEAVE_MUCH_LIMIT 1
#define ERTS_INACT_WR_PB_LEAVE_MUCH_PERCENTAGE 20
@@ -55,7 +59,7 @@
erts_fprintf(stderr, "stop=%p\n", (p)->stop); \
erts_fprintf(stderr, "htop=%p\n", (p)->htop); \
erts_fprintf(stderr, "heap=%p\n", (p)->heap); \
- erl_exit(ERTS_ABORT_EXIT, "%s, line %d: %T: Overrun stack and heap\n", \
+ erts_exit(ERTS_ABORT_EXIT, "%s, line %d: %T: Overrun stack and heap\n", \
__FILE__,__LINE__,(P)->common.id); \
}
@@ -105,8 +109,7 @@ static Eterm* sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop,
char* src, Uint src_size);
static Eterm* collect_heap_frags(Process* p, Eterm* heap,
Eterm* htop, Eterm* objv, int nobj);
-static Uint adjust_after_fullsweep(Process *p, Uint size_before,
- int need, Eterm *objv, int nobj);
+static void adjust_after_fullsweep(Process *p, int need, Eterm *objv, int nobj);
static void shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj);
static void grow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj);
static void sweep_off_heap(Process *p, int fullsweep);
@@ -173,15 +176,15 @@ erts_init_gc(void)
int i = 0, ix;
Sint max_heap_size = 0;
- ASSERT(offsetof(ProcBin,thing_word) == offsetof(struct erl_off_heap_header,thing_word));
- ASSERT(offsetof(ProcBin,thing_word) == offsetof(ErlFunThing,thing_word));
- ASSERT(offsetof(ProcBin,thing_word) == offsetof(ExternalThing,header));
- ASSERT(offsetof(ProcBin,size) == offsetof(struct erl_off_heap_header,size));
- ASSERT(offsetof(ProcBin,size) == offsetof(ErlSubBin,size));
- ASSERT(offsetof(ProcBin,size) == offsetof(ErlHeapBin,size));
- ASSERT(offsetof(ProcBin,next) == offsetof(struct erl_off_heap_header,next));
- ASSERT(offsetof(ProcBin,next) == offsetof(ErlFunThing,next));
- ASSERT(offsetof(ProcBin,next) == offsetof(ExternalThing,next));
+ ERTS_CT_ASSERT(offsetof(ProcBin,thing_word) == offsetof(struct erl_off_heap_header,thing_word));
+ ERTS_CT_ASSERT(offsetof(ProcBin,thing_word) == offsetof(ErlFunThing,thing_word));
+ ERTS_CT_ASSERT(offsetof(ProcBin,thing_word) == offsetof(ExternalThing,header));
+ ERTS_CT_ASSERT(offsetof(ProcBin,size) == offsetof(struct erl_off_heap_header,size));
+ ERTS_CT_ASSERT(offsetof(ProcBin,size) == offsetof(ErlSubBin,size));
+ ERTS_CT_ASSERT(offsetof(ProcBin,size) == offsetof(ErlHeapBin,size));
+ ERTS_CT_ASSERT(offsetof(ProcBin,next) == offsetof(struct erl_off_heap_header,next));
+ ERTS_CT_ASSERT(offsetof(ProcBin,next) == offsetof(ErlFunThing,next));
+ ERTS_CT_ASSERT(offsetof(ProcBin,next) == offsetof(ExternalThing,next));
erts_test_long_gc_sleep = 0;
@@ -265,7 +268,7 @@ erts_next_heap_size(Uint size, Uint offset)
low = mid + 1;
}
}
- erl_exit(1, "no next heap size found: %beu, offset %beu\n", size, offset);
+ erts_exit(ERTS_ERROR_EXIT, "no next heap size found: %beu, offset %beu\n", size, offset);
}
return 0;
}
@@ -400,7 +403,7 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj)
{
Uint reclaimed_now = 0;
int done = 0;
- Uint ms1, s1, us1;
+ ErtsMonotonicTime start_time = 0; /* Shut up faulty warning... */
ErtsSchedulerData *esdp;
#ifdef USE_VM_PROBES
DTRACE_CHARBUF(pidbuf, DTRACE_TERM_BUF_SIZE);
@@ -417,10 +420,9 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj)
trace_gc(p, am_gc_start);
}
- erts_smp_atomic32_read_bor_nob(&p->state, ERTS_PSFLG_GC);
- if (erts_system_monitor_long_gc != 0) {
- get_now(&ms1, &s1, &us1);
- }
+ (void) erts_smp_atomic32_read_bor_nob(&p->state, ERTS_PSFLG_GC);
+ if (erts_system_monitor_long_gc != 0)
+ start_time = erts_get_monotonic_time(esdp);
ERTS_CHK_OFFHEAP(p);
@@ -468,16 +470,14 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj)
}
if (erts_system_monitor_long_gc != 0) {
- Uint ms2, s2, us2;
- Sint t;
+ ErtsMonotonicTime end_time;
+ Uint gc_time;
if (erts_test_long_gc_sleep)
while (0 != erts_milli_sleep(erts_test_long_gc_sleep));
- get_now(&ms2, &s2, &us2);
- t = ms2 - ms1;
- t = t*1000000 + s2 - s1;
- t = t*1000 + ((Sint) (us2 - us1))/1000;
- if (t > 0 && (Uint)t > erts_system_monitor_long_gc) {
- monitor_long_gc(p, t);
+ end_time = erts_get_monotonic_time(esdp);
+ gc_time = (Uint) ERTS_MONOTONIC_TO_MSEC(end_time - start_time);
+ if (gc_time && gc_time > erts_system_monitor_long_gc) {
+ monitor_long_gc(p, gc_time);
}
}
if (erts_system_monitor_large_heap != 0) {
@@ -677,7 +677,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals,
Uint area_size;
Eterm* old_htop;
Uint n;
- struct erl_off_heap_header** prev;
+ struct erl_off_heap_header** prev = NULL;
if (p->flags & F_DISABLE_GC)
return;
@@ -786,10 +786,10 @@ erts_garbage_collect_literals(Process* p, Eterm* literals,
*/
if (oh) {
- prev = &MSO(p).first;
- while (*prev) {
- prev = &(*prev)->next;
- }
+ prev = &MSO(p).first;
+ while (*prev) {
+ prev = &(*prev)->next;
+ }
}
/*
@@ -818,6 +818,10 @@ erts_garbage_collect_literals(Process* p, Eterm* literals,
oh = oh->next;
}
+ if (prev) {
+ *prev = NULL;
+ }
+
/*
* We no longer need this temporary area.
*/
@@ -868,29 +872,37 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
ErlMessage *msgp;
Uint size_after;
Uint need_after;
- Uint stack_size = STACK_SZ_ON_HEAP(p);
- Uint fragments = MBUF_SIZE(p) + combined_message_size(p);
- Uint size_before = fragments + (HEAP_TOP(p) - HEAP_START(p));
- Uint new_sz = next_heap_size(p, HEAP_SIZE(p) + fragments, 0);
+ const Uint stack_size = STACK_SZ_ON_HEAP(p);
+ const Uint size_before = MBUF_SIZE(p) + (HEAP_TOP(p) - HEAP_START(p));
+ Uint new_sz = HEAP_SIZE(p) + MBUF_SIZE(p) + combined_message_size(p);
+ new_sz = next_heap_size(p, new_sz, 0);
do_minor(p, new_sz, objv, nobj);
- /*
+ size_after = HEAP_TOP(p) - HEAP_START(p);
+ *recl += (size_before - size_after);
+
+ /*
* Copy newly received message onto the end of the new heap.
*/
- ErtsGcQuickSanityCheck(p);
- for (msgp = p->msg.first; msgp; msgp = msgp->next) {
- if (msgp->data.attached) {
- erts_move_msg_attached_data_to_heap(&p->htop, &p->off_heap, msgp);
- ErtsGcQuickSanityCheck(p);
- }
- }
+ ErtsGcQuickSanityCheck(p);
+ for (msgp = p->msg.first; msgp; msgp = msgp->next) {
+ if (msgp->data.attached) {
+ ErtsHeapFactory factory;
+ erts_factory_proc_prealloc_init(&factory, p,
+ erts_msg_attached_data_size(msgp));
+ erts_move_msg_attached_data_to_heap(&factory, msgp);
+ erts_factory_close(&factory);
+ ErtsGcQuickSanityCheck(p);
+ }
+ }
ErtsGcQuickSanityCheck(p);
GEN_GCS(p)++;
- size_after = HEAP_TOP(p) - HEAP_START(p);
- need_after = size_after + need + stack_size;
- *recl += (size_before - size_after);
+ need_after = ((HEAP_TOP(p) - HEAP_START(p))
+ + erts_used_frag_sz(MBUF(p))
+ + need
+ + stack_size);
/*
* Excessively large heaps should be shrunk, but
@@ -925,6 +937,7 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
}
ASSERT(HEAP_SIZE(p) == next_heap_size(p, HEAP_SIZE(p), 0));
+ ASSERT(MBUF(p) == NULL);
return 1; /* We are done. */
}
@@ -933,6 +946,7 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
* The heap size turned out to be just right. We are done.
*/
ASSERT(HEAP_SIZE(p) == next_heap_size(p, HEAP_SIZE(p), 0));
+ ASSERT(MBUF(p) == NULL);
return 1;
}
}
@@ -1212,7 +1226,9 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
{
Rootset rootset;
Roots* roots;
- Uint size_before;
+ const Uint size_before = ((HEAP_TOP(p) - HEAP_START(p))
+ + (OLD_HTOP(p) - OLD_HEAP(p))
+ + MBUF_SIZE(p));
Eterm* n_heap;
Eterm* n_htop;
char* src = (char *) HEAP_START(p);
@@ -1221,25 +1237,16 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
Uint oh_size = (char *) OLD_HTOP(p) - oh;
Uint n;
Uint new_sz;
- Uint fragments = MBUF_SIZE(p) + combined_message_size(p);
- ErlMessage *msgp;
-
- size_before = fragments + (HEAP_TOP(p) - HEAP_START(p));
+ int done;
/*
* Do a fullsweep GC. First figure out the size of the heap
* to receive all live data.
*/
- new_sz = HEAP_SIZE(p) + fragments + (OLD_HTOP(p) - OLD_HEAP(p));
- /*
- * We used to do
- *
- * new_sz += STACK_SZ_ON_HEAP(p);
- *
- * here for no obvious reason. (The stack size is already counted once
- * in HEAP_SIZE(p).)
- */
+ new_sz = (HEAP_SIZE(p) + MBUF_SIZE(p)
+ + combined_message_size(p)
+ + (OLD_HTOP(p) - OLD_HEAP(p)));
new_sz = next_heap_size(p, new_sz, 0);
/*
@@ -1432,42 +1439,56 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
ErtsGcQuickSanityCheck(p);
- /*
- * Copy newly received message onto the end of the new heap.
- */
- for (msgp = p->msg.first; msgp; msgp = msgp->next) {
- if (msgp->data.attached) {
- erts_move_msg_attached_data_to_heap(&p->htop, &p->off_heap, msgp);
- ErtsGcQuickSanityCheck(p);
+ *recl += size_before - (HEAP_TOP(p) - HEAP_START(p));
+
+ remove_message_buffers(p);
+
+ {
+ ErlMessage *msgp;
+
+ /*
+ * Copy newly received message onto the end of the new heap.
+ */
+ for (msgp = p->msg.first; msgp; msgp = msgp->next) {
+ if (msgp->data.attached) {
+ ErtsHeapFactory factory;
+ erts_factory_proc_prealloc_init(&factory, p,
+ erts_msg_attached_data_size(msgp));
+ erts_move_msg_attached_data_to_heap(&factory, msgp);
+ erts_factory_close(&factory);
+ ErtsGcQuickSanityCheck(p);
+ }
}
}
- *recl += adjust_after_fullsweep(p, size_before, need, objv, nobj);
-
-#ifdef HARDDEBUG
- disallow_heap_frag_ref_in_heap(p);
-#endif
- remove_message_buffers(p);
+ if (MBUF(p)) {
+ /* This is a very rare case when distributed messages copied above
+ * contained maps so big they did not fit on the heap causing the
+ * factory to create heap frags.
+ * Solution: Trigger a minor gc (without tenuring)
+ */
+ HIGH_WATER(p) = HEAP_START(p);
+ done = 0;
+ } else {
+ adjust_after_fullsweep(p, need, objv, nobj);
+ done = 1;
+ }
ErtsGcQuickSanityCheck(p);
- return 1; /* We are done. */
+ return done;
}
-static Uint
-adjust_after_fullsweep(Process *p, Uint size_before, int need, Eterm *objv, int nobj)
+static void
+adjust_after_fullsweep(Process *p, int need, Eterm *objv, int nobj)
{
- Uint wanted, sz, size_after, need_after;
+ Uint wanted, sz, need_after;
Uint stack_size = STACK_SZ_ON_HEAP(p);
- Uint reclaimed_now;
-
- size_after = (HEAP_TOP(p) - HEAP_START(p));
- reclaimed_now = (size_before - size_after);
/*
* Resize the heap if needed.
*/
- need_after = size_after + need + stack_size;
+ need_after = (HEAP_TOP(p) - HEAP_START(p)) + need + stack_size;
if (HEAP_SIZE(p) < need_after) {
/* Too small - grow to match requested need */
sz = next_heap_size(p, need_after, 0);
@@ -1490,8 +1511,6 @@ adjust_after_fullsweep(Process *p, Uint size_before, int need, Eterm *objv, int
shrink_new_heap(p, sz, objv, nobj);
}
}
-
- return reclaimed_now;
}
/*
@@ -1501,13 +1520,12 @@ adjust_after_fullsweep(Process *p, Uint size_before, int need, Eterm *objv, int
static Uint
combined_message_size(Process* p)
{
- Uint sz = 0;
+ Uint sz;
ErlMessage *msgp;
- for (msgp = p->msg.first; msgp; msgp = msgp->next) {
- if (msgp->data.attached) {
+ for (sz = 0, msgp = p->msg.first; msgp; msgp = msgp->next) {
+ if (msgp->data.attached)
sz += erts_msg_attached_data_size(msgp);
- }
}
return sz;
}
@@ -1869,6 +1887,21 @@ sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop, char* src, Uint sr
if (!header_is_thing(gval)) {
heap_ptr++;
} else {
+ if (header_is_bin_matchstate(gval)) {
+ ErlBinMatchState *ms = (ErlBinMatchState*) heap_ptr;
+ ErlBinMatchBuffer *mb = &(ms->mb);
+ Eterm* origptr;
+ origptr = &(mb->orig);
+ ptr = boxed_val(*origptr);
+ val = *ptr;
+ if (IS_MOVED_BOXED(val)) {
+ *origptr = val;
+ mb->base = binary_bytes(*origptr);
+ } else if (in_area(ptr, src, src_size)) {
+ MOVE_BOXED(ptr,val,htop,origptr);
+ mb->base = binary_bytes(*origptr);
+ }
+ }
heap_ptr += (thing_arityval(gval)+1);
}
break;
@@ -1931,7 +1964,18 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
if (p->dictionary != NULL) {
disallow_heap_frag_ref(p, n_htop, p->dictionary->data, p->dictionary->used);
}
- disallow_heap_frag_ref_in_heap(p);
+ /* OTP-18: Actually we do allow references from heap to heap fragments now.
+ This can happen when doing "binary_to_term" with a "fat" map contained
+ in another term. A "fat" map is a hashmap with higher heap demand than
+ first estimated by "binary_to_term" causing the factory to allocate
+ additional heap (fragments) for the hashmap tree nodes.
+ Run map_SUITE:t_gc_rare_map_overflow to provoke this.
+
+ Inverted references like this does not matter however. The copy done
+ below by move_one_area() with move markers in the fragments and the
+ sweeping done later by the GC should make everything ok in the end.
+ */
+ /***disallow_heap_frag_ref_in_heap(p);***/
#endif
/*
@@ -1940,7 +1984,8 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
* until next GC.
*/
qb = MBUF(p);
- while (qb != NULL) {
+ while (qb != NULL) {
+ ASSERT(!qb->off_heap.first); /* process fragments use the MSO(p) list */
frag_size = qb->used_size * sizeof(Eterm);
if (frag_size != 0) {
frag_begin = (char *) qb->mem;
@@ -2400,7 +2445,6 @@ sweep_off_heap(Process *p, int fullsweep)
}
pb->val = erts_bin_realloc(pb->val, new_size);
- pb->val->orig_size = new_size;
pb->bytes = (byte *) pb->val->orig_bytes;
}
}
@@ -2646,11 +2690,7 @@ reply_gc_info(void *vgcirp)
hpp = &hp;
}
- erts_queue_message(rp, &rp_locks, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL);
if (gcirp->req_sched == esdp->no)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
@@ -2658,7 +2698,7 @@ reply_gc_info(void *vgcirp)
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
if (erts_smp_atomic32_dec_read_nob(&gcirp->refc) == 0)
gcireq_free(vgcirp);
@@ -2682,7 +2722,7 @@ erts_gc_info_request(Process *c_p)
erts_smp_atomic32_init_nob(&gcirp->refc,
(erts_aint32_t) erts_no_schedulers);
- erts_smp_proc_add_refc(c_p, (Sint32) erts_no_schedulers);
+ erts_proc_add_refc(c_p, (Sint) erts_no_schedulers);
#ifdef ERTS_SMP
if (erts_no_schedulers > 1)
@@ -2748,7 +2788,7 @@ within(Eterm *ptr, Process *p)
#define ERTS_CHK_OFFHEAP_ASSERT(EXP) \
do { \
if (!(EXP)) \
- erl_exit(ERTS_ABORT_EXIT, \
+ erts_exit(ERTS_ABORT_EXIT, \
"%s:%d: Assertion failed: %s\n", \
__FILE__, __LINE__, #EXP); \
} while (0)
diff --git a/erts/emulator/beam/erl_gc.h b/erts/emulator/beam/erl_gc.h
index 5203dda263..ecd1bf4d22 100644
--- a/erts/emulator/beam/erl_gc.h
+++ b/erts/emulator/beam/erl_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,10 +21,12 @@
#ifndef __ERL_GC_H__
#define __ERL_GC_H__
-#include "erl_map.h"
+#if defined(ERL_WANT_GC_INTERNALS__) || defined(ERTS_DO_INCL_GLB_INLINE_FUNC_DEF)
/* GC declarations shared by beam/erl_gc.c and hipe/hipe_gc.c */
+#include "erl_map.h"
+
#if defined(DEBUG) && !ERTS_GLB_INLINE_INCL_FUNC_DEF
# define HARDDEBUG 1
#endif
@@ -53,7 +56,10 @@ do { \
nelts = header_arity(HDR); \
switch ((HDR) & _HEADER_SUBTAG_MASK) { \
case SUB_BINARY_SUBTAG: nelts++; break; \
- case MAP_SUBTAG: nelts+=map_get_size(PTR) + 1; break; \
+ case MAP_SUBTAG: \
+ if (is_flatmap_header(HDR)) nelts+=flatmap_get_size(PTR) + 1; \
+ else nelts += hashmap_bitcount(MAP_HEADER_VAL(HDR)); \
+ break; \
case FUN_SUBTAG: nelts+=((ErlFunThing*)(PTR))->num_free+1; break; \
} \
gval = make_boxed(HTOP); \
@@ -61,14 +67,11 @@ do { \
*HTOP++ = HDR; \
*PTR++ = gval; \
while (nelts--) *HTOP++ = *PTR++; \
- \
} while(0)
#define in_area(ptr,start,nbytes) \
((UWord)((char*)(ptr) - (char*)(start)) < (nbytes))
-extern Uint erts_test_long_gc_sleep;
-
#if defined(DEBUG) || defined(ERTS_OFFHEAP_DEBUG)
int within(Eterm *ptr, Process *p);
#endif
@@ -97,4 +100,33 @@ ERTS_GLB_INLINE Eterm follow_moved(Eterm term)
}
#endif
+#endif /* ERL_GC_C__ || HIPE_GC_C__ */
+
+/*
+ * Global exported
+ */
+
+extern Uint erts_test_long_gc_sleep;
+
+typedef struct {
+ Uint64 reclaimed;
+ Uint64 garbage_cols;
+} ErtsGCInfo;
+
+void erts_gc_info(ErtsGCInfo *gcip);
+void erts_init_gc(void);
+int erts_garbage_collect(struct process*, int, Eterm*, int);
+void erts_garbage_collect_hibernate(struct process* p);
+Eterm erts_gc_after_bif_call(struct process* p, Eterm result, Eterm* regs, Uint arity);
+void erts_garbage_collect_literals(struct process* p, Eterm* literals,
+ Uint lit_size,
+ struct erl_off_heap_header* oh);
+Uint erts_next_heap_size(Uint, Uint);
+Eterm erts_heap_sizes(struct process* p);
+
+void erts_offset_off_heap(struct erl_off_heap*, Sint, Eterm*, Eterm*);
+void erts_offset_heap_ptr(Eterm*, Uint, Sint, Eterm*, Eterm*);
+void erts_offset_heap(Eterm*, Uint, Sint, Eterm*, Eterm*);
+void erts_free_heap_frags(struct process* p);
+
#endif /* __ERL_GC_H__ */
diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c
index e9d8249ee1..9b4aad9d91 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.c
+++ b/erts/emulator/beam/erl_goodfit_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -570,8 +571,8 @@ info_options(Allctr_t *allctr,
if (hpp || szp) {
if (!atoms_initialized)
- erl_exit(1, "%s:%d: Internal error: Atoms not initialized",
- __FILE__, __LINE__);;
+ erts_exit(ERTS_ERROR_EXIT, "%s:%d: Internal error: Atoms not initialized",
+ __FILE__, __LINE__);
res = NIL;
add_2tup(hpp, szp, &res, am.as, am.gf);
diff --git a/erts/emulator/beam/erl_goodfit_alloc.h b/erts/emulator/beam/erl_goodfit_alloc.h
index 385de0da23..ababdbd0a1 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.h
+++ b/erts/emulator/beam/erl_goodfit_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c
new file mode 100644
index 0000000000..fb6d249145
--- /dev/null
+++ b/erts/emulator/beam/erl_hl_timer.c
@@ -0,0 +1,3179 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Description: High level timers implementing BIF timers
+ * as well as process and port timers.
+ *
+ * Author: Rickard Green
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sys.h"
+#include "global.h"
+#include "bif.h"
+#include "erl_bif_unique.h"
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
+#include "erl_hl_timer.h"
+
+#define ERTS_TMR_CHECK_CANCEL_ON_CREATE 0
+
+#if 0
+# define ERTS_HLT_HARD_DEBUG
+#endif
+#if 0
+# define ERTS_HLT_DEBUG
+#endif
+
+#if defined(ERTS_HLT_HARD_DEBUG) || defined(DEBUG)
+# if defined(ERTS_HLT_HARD_DEBUG)
+# undef ERTS_RBT_HARD_DEBUG
+# define ERTS_RBT_HARD_DEBUG 1
+# endif
+# ifndef ERTS_HLT_DEBUG
+# define ERTS_HLT_DEBUG 1
+# endif
+#endif
+
+#undef ERTS_HLT_ASSERT
+#if defined(ERTS_HLT_DEBUG)
+# define ERTS_HLT_ASSERT(E) ERTS_ASSERT(E)
+# undef ERTS_RBT_DEBUG
+# define ERTS_RBT_DEBUG
+#else
+# define ERTS_HLT_ASSERT(E) ((void) 1)
+#endif
+
+#if defined(ERTS_HLT_HARD_DEBUG) && defined(__GNUC__)
+#warning "* * * * * * * * * * * * * * * * * *"
+#warning "* ERTS_HLT_HARD_DEBUG IS ENABLED! *"
+#warning "* * * * * * * * * * * * * * * * * *"
+#endif
+
+#ifdef ERTS_HLT_HARD_DEBUG
+# define ERTS_HLT_HDBG_CHK_SRV(SRV) hdbg_chk_srv((SRV))
+static void hdbg_chk_srv(ErtsHLTimerService *srv);
+#else
+# define ERTS_HLT_HDBG_CHK_SRV(SRV) ((void) 1)
+#endif
+
+#if ERTS_REF_NUMBERS != 3
+#error "ERTS_REF_NUMBERS changed. Update me..."
+#endif
+
+typedef enum {
+ ERTS_TMR_BIF,
+ ERTS_TMR_PROC,
+ ERTS_TMR_PORT,
+ ERTS_TMR_CALLBACK
+} ErtsTmrType;
+
+#define ERTS_BIF_TIMER_SHORT_TIME 5000
+
+#ifdef ERTS_SMP
+# define ERTS_HLT_SMP_MEMBAR_LoadLoad_LoadStore \
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore)
+#else
+# define ERTS_HLT_SMP_MEMBAR_LoadLoad_LoadStore
+#endif
+
+/* Bit 0 to 9 contains scheduler id (see mask below) */
+#define ERTS_TMR_ROFLG_HLT (((Uint32) 1) << 10)
+#define ERTS_TMR_ROFLG_BIF_TMR (((Uint32) 1) << 11)
+#define ERTS_TMR_ROFLG_PRE_ALC (((Uint32) 1) << 12)
+#define ERTS_TMR_ROFLG_REG_NAME (((Uint32) 1) << 13)
+#define ERTS_TMR_ROFLG_PROC (((Uint32) 1) << 14)
+#define ERTS_TMR_ROFLG_PORT (((Uint32) 1) << 15)
+#define ERTS_TMR_ROFLG_CALLBACK (((Uint32) 1) << 16)
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+#define ERTS_TMR_ROFLG_ABIF_TMR (((Uint32) 1) << 17)
+#endif
+
+#define ERTS_TMR_ROFLG_SID_MASK \
+ (ERTS_TMR_ROFLG_HLT - (Uint32) 1)
+
+#define ERTS_TMR_STATE_ACTIVE ((erts_aint32_t) 0)
+#define ERTS_TMR_STATE_CANCELED ((erts_aint32_t) 1)
+#define ERTS_TMR_STATE_TIMED_OUT ((erts_aint32_t) 2)
+
+typedef struct ErtsHLTimer_ ErtsHLTimer;
+
+#define ERTS_HLT_PFLG_RED (((UWord) 1) << 0)
+#define ERTS_HLT_PFLG_SAME_TIME (((UWord) 1) << 1)
+
+#define ERTS_HLT_PFLGS_MASK \
+ (ERTS_HLT_PFLG_RED|ERTS_HLT_PFLG_SAME_TIME)
+
+#define ERTS_HLT_PFIELD_NOT_IN_TABLE (~((UWord) 0))
+
+typedef struct {
+ UWord parent; /* parent pointer and flags... */
+ union {
+ struct {
+ ErtsHLTimer *right;
+ ErtsHLTimer *left;
+ } t;
+ struct {
+ ErtsHLTimer *prev;
+ ErtsHLTimer *next;
+ } l;
+ } u;
+ ErtsHLTimer *same_time;
+} ErtsHLTimerTimeTree;
+
+typedef struct {
+ UWord parent; /* parent pointer and flags... */
+ ErtsHLTimer *right;
+ ErtsHLTimer *left;
+} ErtsHLTimerTree;
+
+typedef struct {
+ Uint32 roflgs;
+ erts_smp_atomic32_t refc;
+ union {
+ void *arg;
+ erts_atomic_t next;
+ } u;
+} ErtsTmrHead;
+
+struct ErtsHLTimer_ {
+ ErtsTmrHead head; /* NEED to be first! */
+ union {
+ ErtsThrPrgrLaterOp cleanup;
+ ErtsHLTimerTimeTree tree;
+ } time;
+ ErtsMonotonicTime timeout;
+ union {
+ Process *proc;
+ Port *port;
+ Eterm name;
+ void (*callback)(void *);
+ } receiver;
+
+#ifdef ERTS_HLT_HARD_DEBUG
+ int pending_timeout;
+#endif
+
+ erts_smp_atomic32_t state;
+
+ /* BIF timer only fields follow... */
+ struct {
+ Uint32 refn[ERTS_REF_NUMBERS];
+ ErtsHLTimerTree proc_tree;
+ ErtsHLTimerTree tree;
+ Eterm message;
+ ErlHeapFragment *bp;
+ } btm;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ struct {
+ Eterm accessor;
+ ErtsHLTimerTree tree;
+ } abtm;
+#endif
+};
+
+#define ERTS_HL_PTIMER_SIZE offsetof(ErtsHLTimer, btm)
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+#define ERTS_BIF_TIMER_SIZE offsetof(ErtsHLTimer, abtm)
+#define ERTS_ABIF_TIMER_SIZE sizeof(ErtsHLTimer)
+#else
+#define ERTS_BIF_TIMER_SIZE sizeof(ErtsHLTimer)
+#endif
+
+typedef struct {
+ ErtsTmrHead head; /* NEED to be first! */
+ union {
+ void *p;
+ void (*callback)(void *);
+ } u;
+ ErtsTWheelTimer tw_tmr;
+} ErtsTWTimer;
+
+typedef union {
+ ErtsTmrHead head;
+ ErtsHLTimer hlt;
+ ErtsTWTimer twt;
+} ErtsTimer;
+
+#ifdef SMALL_MEMORY
+#define BIF_TIMER_PREALC_SZ 10
+#define PTIMER_PREALC_SZ 10
+#else
+#define BIF_TIMER_PREALC_SZ 100
+#define PTIMER_PREALC_SZ 100
+#endif
+
+ERTS_SCHED_PREF_PALLOC_IMPL(bif_timer_pre,
+ ErtsHLTimer,
+ BIF_TIMER_PREALC_SZ)
+
+ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(tw_timer,
+ ErtsTWTimer,
+ PTIMER_PREALC_SZ,
+ ERTS_ALC_T_LL_PTIMER)
+
+#ifdef ERTS_HLT_DEBUG
+#define ERTS_TMR_TIMEOUT_YIELD_LIMIT 5
+#else
+#define ERTS_TMR_TIMEOUT_YIELD_LIMIT 100
+#endif
+#define ERTS_TMR_CANCELED_TIMER_LIMIT 100
+#define ERTS_TMR_CANCELED_TIMER_SMALL_LIMIT 5
+
+#define ERTS_TMR_TIMEOUT_YIELD_STATE_T same_time_list_yield_state_t
+#define ERTS_TMR_YIELDING_TIMEOUT_STATE_INITER {NULL, {0}}
+typedef struct {
+ int dummy;
+} ERTS_TMR_TIMEOUT_YIELD_STATE_T;
+
+typedef struct {
+ ErtsTmrHead marker;
+ erts_atomic_t last;
+} ErtsHLTCncldTmrQTail;
+
+#ifdef ERTS_SMP
+
+typedef struct {
+ /*
+ * This structure needs to be cache line aligned for best
+ * performance.
+ */
+ union {
+ /*
+ * Modified by threads returning canceled
+ * timers to this timer service.
+ */
+ ErtsHLTCncldTmrQTail data;
+ char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(
+ sizeof(ErtsHLTCncldTmrQTail))];
+ } tail;
+ /*
+ * Everything below this point is *only* accessed by the
+ * thread managing this timer service.
+ */
+ struct {
+ ErtsTimer *first;
+ ErtsTimer *unref_end;
+ struct {
+ ErtsThrPrgrVal thr_progress;
+ int thr_progress_reached;
+ ErtsTimer *unref_end;
+ } next;
+ int used_marker;
+ } head;
+} ErtsHLTCncldTmrQ;
+
+#endif /* ERTS_SMP */
+
+typedef struct {
+ ErtsHLTimer *root;
+ ERTS_TMR_TIMEOUT_YIELD_STATE_T state;
+} ErtsYieldingTimeoutState;
+
+struct ErtsHLTimerService_ {
+#ifdef ERTS_SMP
+ ErtsHLTCncldTmrQ canceled_queue;
+#endif
+ ErtsHLTimer *time_tree;
+ ErtsHLTimer *btm_tree;
+ ErtsHLTimer *next_timeout;
+ ErtsYieldingTimeoutState yield;
+ ErtsTWheelTimer service_timer;
+};
+
+static ERTS_INLINE int
+refn_is_lt(Uint32 *x, Uint32 *y)
+{
+ /* !0 if x < y */
+ if (x[2] < y[2])
+ return 1;
+ if (x[2] != y[2])
+ return 0;
+ if (x[1] < y[1])
+ return 1;
+ if (x[1] != y[1])
+ return 0;
+ return x[0] < y[0];
+}
+
+#define ERTS_RBT_PREFIX time
+#define ERTS_RBT_T ErtsHLTimer
+#define ERTS_RBT_KEY_T ErtsMonotonicTime
+#define ERTS_RBT_FLAGS_T UWord
+#define ERTS_RBT_INIT_EMPTY_TNODE(T) \
+ do { \
+ (T)->time.tree.parent = (UWord) NULL; \
+ (T)->time.tree.u.t.right = NULL; \
+ (T)->time.tree.u.t.left = NULL; \
+ } while (0)
+#define ERTS_RBT_IS_RED(T) \
+ ((int) ((T)->time.tree.parent & ERTS_HLT_PFLG_RED))
+#define ERTS_RBT_SET_RED(T) \
+ ((T)->time.tree.parent |= ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_IS_BLACK(T) \
+ (!ERTS_RBT_IS_RED((T)))
+#define ERTS_RBT_SET_BLACK(T) \
+ ((T)->time.tree.parent &= ~ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_GET_FLAGS(T) \
+ ((T)->time.tree.parent & ERTS_HLT_PFLGS_MASK)
+#define ERTS_RBT_SET_FLAGS(T, F) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (F)) & ~ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->time.tree.parent &= ~ERTS_HLT_PFLGS_MASK; \
+ (T)->time.tree.parent |= (F); \
+ } while (0)
+#define ERTS_RBT_GET_PARENT(T) \
+ ((ErtsHLTimer *) ((T)->time.tree.parent & ~ERTS_HLT_PFLGS_MASK))
+#define ERTS_RBT_SET_PARENT(T, P) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (P)) & ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->time.tree.parent &= ERTS_HLT_PFLGS_MASK; \
+ (T)->time.tree.parent |= (UWord) (P); \
+ } while (0)
+#define ERTS_RBT_GET_RIGHT(T) ((T)->time.tree.u.t.right)
+#define ERTS_RBT_SET_RIGHT(T, R) ((T)->time.tree.u.t.right = (R))
+#define ERTS_RBT_GET_LEFT(T) ((T)->time.tree.u.t.left)
+#define ERTS_RBT_SET_LEFT(T, L) ((T)->time.tree.u.t.left = (L))
+#define ERTS_RBT_GET_KEY(T) ((T)->timeout)
+#define ERTS_RBT_IS_LT(KX, KY) ((KX) < (KY))
+#define ERTS_RBT_IS_EQ(KX, KY) ((KX) == (KY))
+#define ERTS_RBT_WANT_DELETE
+#define ERTS_RBT_WANT_SMALLEST
+#define ERTS_RBT_WANT_LOOKUP_INSERT
+#define ERTS_RBT_WANT_REPLACE
+#define ERTS_RBT_WANT_FOREACH
+#ifdef ERTS_HLT_HARD_DEBUG
+# define ERTS_RBT_WANT_LOOKUP
+#endif
+#define ERTS_RBT_UNDEF
+
+#include "erl_rbtree.h"
+
+/* Use circular list for timers at same time */
+
+static ERTS_INLINE void
+same_time_list_insert(ErtsHLTimer **root, ErtsHLTimer *tmr)
+{
+ ErtsHLTimer *first = *root;
+ if (!first) {
+ ERTS_HLT_ASSERT((((UWord) root) & ERTS_HLT_PFLG_SAME_TIME) == 0);
+ tmr->time.tree.parent = ((UWord) root) | ERTS_HLT_PFLG_SAME_TIME;
+ tmr->time.tree.u.l.next = tmr;
+ tmr->time.tree.u.l.prev = tmr;
+ *root = tmr;
+ }
+ else {
+ tmr->time.tree.parent = ERTS_HLT_PFLG_SAME_TIME;
+ tmr->time.tree.u.l.next = first;
+ tmr->time.tree.u.l.prev = first->time.tree.u.l.prev;
+ first->time.tree.u.l.prev = tmr;
+ tmr->time.tree.u.l.prev->time.tree.u.l.next = tmr;
+ }
+}
+
+static ERTS_INLINE void
+same_time_list_delete(ErtsHLTimer *tmr)
+{
+ ErtsHLTimer **root, *next;
+
+ root = (ErtsHLTimer **) (tmr->time.tree.parent & ~ERTS_HLT_PFLG_SAME_TIME);
+ next = tmr->time.tree.u.l.next;
+
+ ERTS_HLT_ASSERT((tmr->time.tree.parent
+ == (((UWord) root) | ERTS_HLT_PFLG_SAME_TIME))
+ || (tmr->time.tree.parent
+ == ERTS_HLT_PFLG_SAME_TIME));
+
+ if (next == tmr) {
+ ERTS_HLT_ASSERT(root && *root == tmr);
+ ERTS_HLT_ASSERT(tmr->time.tree.u.l.prev == tmr);
+ *root = NULL;
+ }
+ else {
+ if (root) {
+ ERTS_HLT_ASSERT(*root == tmr);
+ *root = next;
+ next->time.tree.parent = ((UWord) root) | ERTS_HLT_PFLG_SAME_TIME;
+ }
+ tmr->time.tree.u.l.next->time.tree.u.l.prev = tmr->time.tree.u.l.prev;
+ tmr->time.tree.u.l.prev->time.tree.u.l.next = next;
+ }
+}
+
+static ERTS_INLINE void
+same_time_list_new_root(ErtsHLTimer **root)
+{
+ ErtsHLTimer *tmr = *root;
+ if (tmr) {
+ ERTS_HLT_ASSERT(root);
+ tmr->time.tree.parent = ((UWord) root) | ERTS_HLT_PFLG_SAME_TIME;
+ }
+}
+
+static ERTS_INLINE int
+same_time_list_foreach_destroy_yielding(ErtsHLTimer **root,
+ void (*op)(ErtsHLTimer *, void *),
+ void *arg,
+ ERTS_TMR_TIMEOUT_YIELD_STATE_T *ys,
+ Sint ylimit)
+{
+ Sint ycnt = ylimit;
+ ErtsHLTimer *end, *tmr = *root;
+ if (!tmr)
+ return 0;
+
+ ERTS_HLT_ASSERT(tmr->time.tree.parent
+ == (((UWord) root) | ERTS_HLT_PFLG_SAME_TIME));
+
+ end = tmr->time.tree.u.l.prev;
+ end->time.tree.u.l.next = NULL;
+
+ while (1) {
+ ErtsHLTimer *op_tmr = tmr;
+
+ ERTS_HLT_ASSERT((tmr->time.tree.parent
+ == (((UWord) root) | ERTS_HLT_PFLG_SAME_TIME))
+ || (tmr->time.tree.parent
+ == ERTS_HLT_PFLG_SAME_TIME));
+
+ tmr = tmr->time.tree.u.l.next;
+ (*op)(op_tmr, arg);
+ if (!tmr) {
+ *root = NULL;
+ return 0;
+ }
+ if (--ycnt <= 0) {
+ /* Make new circle of timers left to process... */
+ *root = tmr;
+ end->time.tree.u.l.next = tmr;
+ tmr->time.tree.u.l.prev = end;
+ tmr->time.tree.parent = ((UWord) root) | ERTS_HLT_PFLG_SAME_TIME;
+ return 1;
+ }
+ }
+}
+
+static ERTS_INLINE void
+same_time_list_foreach(ErtsHLTimer *root,
+ void (*op)(ErtsHLTimer *, void *),
+ void *arg)
+{
+ if (root) {
+ ErtsHLTimer *tmr = root;
+ do {
+ (*op)(tmr, arg);
+ tmr = tmr->time.tree.u.l.next;
+ } while (root != tmr);
+ }
+}
+
+#ifdef ERTS_HLT_HARD_DEBUG
+
+static ERTS_INLINE ErtsHLTimer *
+same_time_list_lookup(ErtsHLTimer *root, ErtsHLTimer *x)
+{
+ if (root) {
+ ErtsHLTimer *tmr = root;
+ do {
+ if (tmr == x)
+ return tmr;
+ tmr = tmr->time.tree.u.l.next;
+ } while (root != tmr);
+ }
+ return NULL;
+}
+
+#endif /* ERTS_HLT_HARD_DEBUG */
+
+#define ERTS_RBT_PREFIX btm
+#define ERTS_RBT_T ErtsHLTimer
+#define ERTS_RBT_KEY_T Uint32 *
+#define ERTS_RBT_FLAGS_T UWord
+#define ERTS_RBT_INIT_EMPTY_TNODE(T) \
+ do { \
+ (T)->btm.tree.parent = (UWord) NULL; \
+ (T)->btm.tree.right = NULL; \
+ (T)->btm.tree.left = NULL; \
+ } while (0)
+#define ERTS_RBT_IS_RED(T) \
+ ((int) ((T)->btm.tree.parent & ERTS_HLT_PFLG_RED))
+#define ERTS_RBT_SET_RED(T) \
+ ((T)->btm.tree.parent |= ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_IS_BLACK(T) \
+ (!ERTS_RBT_IS_RED((T)))
+#define ERTS_RBT_SET_BLACK(T) \
+ ((T)->btm.tree.parent &= ~ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_GET_FLAGS(T) \
+ ((T)->btm.tree.parent & ERTS_HLT_PFLGS_MASK)
+#define ERTS_RBT_SET_FLAGS(T, F) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (F)) & ~ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->btm.tree.parent &= ~ERTS_HLT_PFLGS_MASK; \
+ (T)->btm.tree.parent |= (F); \
+ } while (0)
+#define ERTS_RBT_GET_PARENT(T) \
+ ((ErtsHLTimer *) ((T)->btm.tree.parent & ~ERTS_HLT_PFLGS_MASK))
+#define ERTS_RBT_SET_PARENT(T, P) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (P)) & ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->btm.tree.parent &= ERTS_HLT_PFLGS_MASK; \
+ (T)->btm.tree.parent |= (UWord) (P); \
+ } while (0)
+#define ERTS_RBT_GET_RIGHT(T) ((T)->btm.tree.right)
+#define ERTS_RBT_SET_RIGHT(T, R) ((T)->btm.tree.right = (R))
+#define ERTS_RBT_GET_LEFT(T) ((T)->btm.tree.left)
+#define ERTS_RBT_SET_LEFT(T, L) ((T)->btm.tree.left = (L))
+#define ERTS_RBT_GET_KEY(T) ((T)->btm.refn)
+#define ERTS_RBT_IS_LT(KX, KY) refn_is_lt((KX), (KY))
+#define ERTS_RBT_IS_EQ(KX, KY) \
+ (((KX)[0] == (KY)[0]) & ((KX)[1] == (KY)[1]) & ((KX)[2] == (KY)[2]))
+#define ERTS_RBT_WANT_DELETE
+#define ERTS_RBT_WANT_INSERT
+#define ERTS_RBT_WANT_LOOKUP
+#define ERTS_RBT_WANT_FOREACH
+#define ERTS_RBT_UNDEF
+
+#include "erl_rbtree.h"
+
+#define ERTS_RBT_PREFIX proc_btm
+#define ERTS_RBT_T ErtsHLTimer
+#define ERTS_RBT_KEY_T Uint32 *
+#define ERTS_RBT_FLAGS_T UWord
+#define ERTS_RBT_INIT_EMPTY_TNODE(T) \
+ do { \
+ (T)->btm.proc_tree.parent = (UWord) NULL; \
+ (T)->btm.proc_tree.right = NULL; \
+ (T)->btm.proc_tree.left = NULL; \
+ } while (0)
+#define ERTS_RBT_IS_RED(T) \
+ ((int) ((T)->btm.proc_tree.parent & ERTS_HLT_PFLG_RED))
+#define ERTS_RBT_SET_RED(T) \
+ ((T)->btm.proc_tree.parent |= ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_IS_BLACK(T) \
+ (!ERTS_RBT_IS_RED((T)))
+#define ERTS_RBT_SET_BLACK(T) \
+ ((T)->btm.proc_tree.parent &= ~ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_GET_FLAGS(T) \
+ ((T)->btm.proc_tree.parent & ERTS_HLT_PFLGS_MASK)
+#define ERTS_RBT_SET_FLAGS(T, F) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (F)) & ~ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->btm.proc_tree.parent &= ~ERTS_HLT_PFLGS_MASK; \
+ (T)->btm.proc_tree.parent |= (F); \
+ } while (0)
+#define ERTS_RBT_GET_PARENT(T) \
+ ((ErtsHLTimer *) ((T)->btm.proc_tree.parent & ~ERTS_HLT_PFLGS_MASK))
+#define ERTS_RBT_SET_PARENT(T, P) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (P)) & ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->btm.proc_tree.parent &= ERTS_HLT_PFLGS_MASK; \
+ (T)->btm.proc_tree.parent |= (UWord) (P); \
+ } while (0)
+#define ERTS_RBT_GET_RIGHT(T) ((T)->btm.proc_tree.right)
+#define ERTS_RBT_SET_RIGHT(T, R) ((T)->btm.proc_tree.right = (R))
+#define ERTS_RBT_GET_LEFT(T) ((T)->btm.proc_tree.left)
+#define ERTS_RBT_SET_LEFT(T, L) ((T)->btm.proc_tree.left = (L))
+#define ERTS_RBT_GET_KEY(T) ((T)->btm.refn)
+#define ERTS_RBT_IS_LT(KX, KY) refn_is_lt((KX), (KY))
+#define ERTS_RBT_IS_EQ(KX, KY) \
+ (((KX)[0] == (KY)[0]) & ((KX)[1] == (KY)[1]) & ((KX)[2] == (KY)[2]))
+#define ERTS_RBT_WANT_DELETE
+#define ERTS_RBT_WANT_INSERT
+#define ERTS_RBT_WANT_LOOKUP
+#define ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING
+#define ERTS_RBT_UNDEF
+
+#include "erl_rbtree.h"
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+
+#define ERTS_RBT_PREFIX abtm
+#define ERTS_RBT_T ErtsHLTimer
+#define ERTS_RBT_KEY_T Uint32 *
+#define ERTS_RBT_FLAGS_T UWord
+#define ERTS_RBT_INIT_EMPTY_TNODE(T) \
+ do { \
+ (T)->abtm.tree.parent = (UWord) NULL; \
+ (T)->abtm.tree.right = NULL; \
+ (T)->abtm.tree.left = NULL; \
+ } while (0)
+#define ERTS_RBT_IS_RED(T) \
+ ((int) ((T)->abtm.tree.parent & ERTS_HLT_PFLG_RED))
+#define ERTS_RBT_SET_RED(T) \
+ ((T)->abtm.tree.parent |= ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_IS_BLACK(T) \
+ (!ERTS_RBT_IS_RED((T)))
+#define ERTS_RBT_SET_BLACK(T) \
+ ((T)->abtm.tree.parent &= ~ERTS_HLT_PFLG_RED)
+#define ERTS_RBT_GET_FLAGS(T) \
+ ((T)->abtm.tree.parent & ERTS_HLT_PFLGS_MASK)
+#define ERTS_RBT_SET_FLAGS(T, F) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (F)) & ~ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->abtm.tree.parent &= ~ERTS_HLT_PFLGS_MASK; \
+ (T)->abtm.tree.parent |= (F); \
+ } while (0)
+#define ERTS_RBT_GET_PARENT(T) \
+ ((ErtsHLTimer *) ((T)->abtm.tree.parent & ~ERTS_HLT_PFLGS_MASK))
+#define ERTS_RBT_SET_PARENT(T, P) \
+ do { \
+ ERTS_HLT_ASSERT((((UWord) (P)) & ERTS_HLT_PFLGS_MASK) == 0); \
+ (T)->abtm.tree.parent &= ERTS_HLT_PFLGS_MASK; \
+ (T)->abtm.tree.parent |= (UWord) (P); \
+ } while (0)
+#define ERTS_RBT_GET_RIGHT(T) ((T)->abtm.tree.right)
+#define ERTS_RBT_SET_RIGHT(T, R) ((T)->abtm.tree.right = (R))
+#define ERTS_RBT_GET_LEFT(T) ((T)->abtm.tree.left)
+#define ERTS_RBT_SET_LEFT(T, L) ((T)->abtm.tree.left = (L))
+#define ERTS_RBT_GET_KEY(T) ((T)->btm.refn)
+#define ERTS_RBT_IS_LT(KX, KY) refn_is_lt((KX), (KY))
+#define ERTS_RBT_IS_EQ(KX, KY) \
+ (((KX)[0] == (KY)[0]) & ((KX)[1] == (KY)[1]) & ((KX)[2] == (KY)[2]))
+#define ERTS_RBT_WANT_DELETE
+#define ERTS_RBT_WANT_INSERT
+#define ERTS_RBT_WANT_LOOKUP
+#define ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING
+#define ERTS_RBT_UNDEF
+
+#include "erl_rbtree.h"
+
+#endif /* ERTS_BTM_ACCESSOR_SUPPORT */
+
+#ifdef ERTS_SMP
+static void init_canceled_queue(ErtsHLTCncldTmrQ *cq);
+#endif
+
+void
+erts_hl_timer_init(void)
+{
+ init_tw_timer_alloc();
+ init_bif_timer_pre_alloc();
+}
+
+ErtsHLTimerService *
+erts_create_timer_service(void)
+{
+ ErtsYieldingTimeoutState init_yield = ERTS_TMR_YIELDING_TIMEOUT_STATE_INITER;
+ ErtsHLTimerService *srv;
+
+ srv = erts_alloc_permanent_cache_aligned(ERTS_ALC_T_TIMER_SERVICE,
+ sizeof(ErtsHLTimerService));
+ srv->time_tree = NULL;
+ srv->btm_tree = NULL;
+ srv->next_timeout = NULL;
+ srv->yield = init_yield;
+ erts_twheel_init_timer(&srv->service_timer);
+
+#ifdef ERTS_SMP
+ init_canceled_queue(&srv->canceled_queue);
+#endif
+
+ return srv;
+}
+
+size_t
+erts_timer_type_size(ErtsAlcType_t type)
+{
+ switch (type) {
+ case ERTS_ALC_T_LL_PTIMER: return sizeof(ErtsTWTimer);
+ case ERTS_ALC_T_HL_PTIMER: return ERTS_HL_PTIMER_SIZE;
+ case ERTS_ALC_T_BIF_TIMER: return ERTS_BIF_TIMER_SIZE;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ case ERTS_ALC_T_ABIF_TIMER: return ERTS_ABIF_TIMER_SIZE;
+#endif
+ default: ERTS_INTERNAL_ERROR("Unknown type");
+ }
+ return 0;
+}
+
+static ERTS_INLINE ErtsMonotonicTime
+get_timeout_pos(ErtsMonotonicTime now, ErtsMonotonicTime msec)
+{
+ ErtsMonotonicTime timeout_pos;
+ if (msec <= 0)
+ return ERTS_MONOTONIC_TO_CLKTCKS(now);
+ timeout_pos = ERTS_MONOTONIC_TO_CLKTCKS(now-1);
+ timeout_pos += ERTS_MSEC_TO_CLKTCKS(msec) + 1;
+ return timeout_pos;
+}
+
+static ERTS_INLINE Sint64
+get_time_left(ErtsSchedulerData *esdp, ErtsMonotonicTime timeout_pos)
+{
+ ErtsMonotonicTime now = erts_get_monotonic_time(esdp);
+
+ now = ERTS_MONOTONIC_TO_CLKTCKS(now-1)+1;
+ if (timeout_pos <= now)
+ return (Sint64) 0;
+ return (Sint64) ERTS_CLKTCKS_TO_MSEC(timeout_pos - now);
+}
+
+static ERTS_INLINE int
+proc_timeout_common(Process *proc, void *tmr)
+{
+ if (tmr == (void *) erts_smp_atomic_cmpxchg_mb(&proc->common.timer,
+ ERTS_PTMR_TIMEDOUT,
+ (erts_aint_t) tmr)) {
+ erts_aint32_t state = erts_smp_atomic32_read_acqb(&proc->state);
+ if (!(state & (ERTS_PSFLG_ACTIVE|ERTS_PSFLG_EXITING)))
+ erts_schedule_process(proc, state, 0);
+ return 1;
+ }
+ return 0;
+}
+
+static ERTS_INLINE int
+port_timeout_common(Port *port, void *tmr)
+{
+ if (tmr == (void *) erts_smp_atomic_cmpxchg_mb(&port->common.timer,
+ ERTS_PTMR_TIMEDOUT,
+ (erts_aint_t) tmr)) {
+ erts_port_task_schedule(port->common.id,
+ &port->timeout_task,
+ ERTS_PORT_TASK_TIMEOUT);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Basic timer wheel timer stuff
+ */
+
+static void
+scheduled_tw_timer_destroy(void *vtmr)
+{
+ tw_timer_free((ErtsTWTimer *) vtmr);
+}
+
+static void
+schedule_tw_timer_destroy(ErtsTWTimer *tmr)
+{
+ /*
+ * Reference to process/port can be
+ * dropped at once...
+ */
+ if (tmr->head.roflgs & ERTS_TMR_ROFLG_PROC)
+ erts_proc_dec_refc((Process *) tmr->u.p);
+ else if (tmr->head.roflgs & ERTS_TMR_ROFLG_PORT)
+ erts_port_dec_refc((Port *) tmr->u.p);
+
+ erts_schedule_thr_prgr_later_cleanup_op(
+ scheduled_tw_timer_destroy,
+ (void *) tmr,
+ &tmr->tw_tmr.u.cleanup,
+ sizeof(ErtsTWTimer));
+}
+
+static ERTS_INLINE void
+tw_timer_dec_refc(ErtsTWTimer *tmr)
+{
+ if (erts_smp_atomic32_dec_read_relb(&tmr->head.refc) == 0) {
+ ERTS_HLT_SMP_MEMBAR_LoadLoad_LoadStore;
+ schedule_tw_timer_destroy(tmr);
+ }
+}
+
+static void
+tw_proc_timeout(void *vtwtp)
+{
+ ErtsTWTimer *twtp = (ErtsTWTimer *) vtwtp;
+ Process *proc = (Process *) twtp->u.p;
+ if (proc_timeout_common(proc, vtwtp))
+ tw_timer_dec_refc(twtp);
+ tw_timer_dec_refc(twtp);
+}
+
+static void
+tw_port_timeout(void *vtwtp)
+{
+ ErtsTWTimer *twtp = (ErtsTWTimer *) vtwtp;
+ Port *port = (Port *) twtp->u.p;
+ if (port_timeout_common(port, vtwtp))
+ tw_timer_dec_refc(twtp);
+ tw_timer_dec_refc(twtp);
+}
+
+static void
+tw_ptimer_cancel(void *vtwtp)
+{
+ tw_timer_dec_refc((ErtsTWTimer *) vtwtp);
+}
+
+static void
+cancel_tw_timer(ErtsSchedulerData *esdp, ErtsTWTimer *tmr)
+{
+ ERTS_HLT_ASSERT((tmr->head.roflgs & ERTS_TMR_ROFLG_SID_MASK)
+ == (Uint32) esdp->no);
+ erts_twheel_cancel_timer(esdp->timer_wheel, &tmr->tw_tmr);
+}
+
+static void
+tw_callback_timeout(void *vtwtp)
+{
+ ErtsTWTimer *twtp = (ErtsTWTimer *) vtwtp;
+ void (*callback)(void *) = twtp->u.callback;
+ void *arg = twtp->head.u.arg;
+ tw_timer_dec_refc(twtp);
+ (*callback)(arg);
+}
+
+static ErtsTWTimer *
+create_tw_timer(ErtsSchedulerData *esdp,
+ ErtsTmrType type, void *p,
+ void (*callback)(void *), void *arg,
+ ErtsMonotonicTime timeout_pos)
+{
+ ErtsTWTimer *tmr;
+ void (*timeout_func)(void *);
+ void (*cancel_func)(void *);
+ erts_aint32_t refc;
+
+ tmr = tw_timer_alloc();
+ erts_twheel_init_timer(&tmr->tw_tmr);
+
+ tmr->head.roflgs = (Uint32) esdp->no;
+ ERTS_HLT_ASSERT((tmr->head.roflgs
+ & ~ERTS_TMR_ROFLG_SID_MASK) == 0);
+
+ switch (type) {
+
+ case ERTS_TMR_PROC:
+ tmr->u.p = p;
+ tmr->head.roflgs |= ERTS_TMR_ROFLG_PROC;
+ timeout_func = tw_proc_timeout;
+ cancel_func = tw_ptimer_cancel;
+ erts_proc_inc_refc((Process *) p);
+ refc = 2;
+ break;
+
+ case ERTS_TMR_PORT:
+ tmr->u.p = p;
+ tmr->head.roflgs |= ERTS_TMR_ROFLG_PORT;
+ timeout_func = tw_port_timeout;
+ cancel_func = tw_ptimer_cancel;
+ erts_port_inc_refc((Port *) p);
+ refc = 2;
+ break;
+
+ case ERTS_TMR_CALLBACK:
+ tmr->head.u.arg = arg;
+ tmr->u.callback = callback;
+
+ tmr->head.roflgs |= ERTS_TMR_ROFLG_CALLBACK;
+ timeout_func = tw_callback_timeout;
+ cancel_func = NULL;
+ refc = 1;
+ break;
+
+ default:
+ ERTS_INTERNAL_ERROR("Unsupported timer type");
+ return NULL;
+ }
+
+ erts_smp_atomic32_init_nob(&tmr->head.refc, refc);
+
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &tmr->tw_tmr,
+ timeout_func,
+ cancel_func,
+ tmr,
+ timeout_pos);
+
+ return tmr;
+}
+
+/*
+ * Basic high level timer stuff
+ */
+
+static ERTS_INLINE void
+hl_timer_destroy(ErtsHLTimer *tmr)
+{
+ Uint32 roflgs = tmr->head.roflgs;
+ if (!(roflgs & ERTS_TMR_ROFLG_BIF_TMR))
+ erts_free(ERTS_ALC_T_HL_PTIMER, tmr);
+ else {
+ if (roflgs & ERTS_TMR_ROFLG_PRE_ALC)
+ bif_timer_pre_free(tmr);
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ else if (roflgs & ERTS_TMR_ROFLG_ABIF_TMR)
+ erts_free(ERTS_ALC_T_ABIF_TIMER, tmr);
+#endif
+ else
+ erts_free(ERTS_ALC_T_BIF_TIMER, tmr);
+ }
+}
+
+static void
+scheduled_hl_timer_destroy(void *vtmr)
+{
+ hl_timer_destroy((ErtsHLTimer *) vtmr);
+}
+
+static void
+schedule_hl_timer_destroy(ErtsHLTimer *tmr, Uint32 roflgs)
+{
+ UWord size;
+
+ /*
+ * Reference to process/port can be dropped
+ * at once...
+ */
+
+ ERTS_HLT_ASSERT(erts_smp_atomic32_read_nob(&tmr->head.refc) == 0);
+
+ if (roflgs & ERTS_TMR_ROFLG_REG_NAME) {
+ ERTS_HLT_ASSERT(is_atom(tmr->receiver.name));
+ }
+ else if (roflgs & ERTS_TMR_ROFLG_PROC) {
+ ERTS_HLT_ASSERT(tmr->receiver.proc);
+ erts_proc_dec_refc(tmr->receiver.proc);
+ }
+ else if (roflgs & ERTS_TMR_ROFLG_PORT) {
+ ERTS_HLT_ASSERT(tmr->receiver.port);
+ erts_port_dec_refc(tmr->receiver.port);
+ }
+
+ if (!(roflgs & ERTS_TMR_ROFLG_BIF_TMR))
+ size = ERTS_HL_PTIMER_SIZE;
+ else {
+ /*
+ * Message buffer can be dropped at
+ * once...
+ */
+ size = sizeof(ErtsHLTimer);
+ }
+
+ erts_schedule_thr_prgr_later_cleanup_op(
+ scheduled_hl_timer_destroy, tmr,
+ &tmr->time.cleanup, size);
+}
+
+static ERTS_INLINE void
+hl_timer_pre_dec_refc(ErtsHLTimer *tmr)
+{
+#ifdef ERTS_HLT_DEBUG
+ erts_aint_t refc;
+ refc = erts_smp_atomic32_dec_read_nob(&tmr->head.refc);
+ ERTS_HLT_ASSERT(refc > 0);
+#else
+ erts_smp_atomic32_dec_nob(&tmr->head.refc);
+#endif
+}
+
+static ERTS_INLINE void
+hl_timer_dec_refc(ErtsHLTimer *tmr, Uint32 roflgs)
+{
+ if (erts_smp_atomic32_dec_read_relb(&tmr->head.refc) == 0) {
+ ERTS_HLT_SMP_MEMBAR_LoadLoad_LoadStore;
+ schedule_hl_timer_destroy(tmr, roflgs);
+ }
+}
+
+static void hlt_service_timeout(void *vesdp);
+#ifdef ERTS_SMP
+static void handle_canceled_queue(ErtsSchedulerData *esdp,
+ ErtsHLTCncldTmrQ *cq,
+ int use_limit,
+ int ops_limit,
+ int *need_thr_progress,
+ ErtsThrPrgrVal *thr_prgr_p,
+ int *need_more_work);
+#endif
+
+static ERTS_INLINE void
+check_canceled_queue(ErtsSchedulerData *esdp, ErtsHLTimerService *srv)
+{
+#if defined(ERTS_SMP) && ERTS_TMR_CHECK_CANCEL_ON_CREATE
+ ErtsHLTCncldTmrQ *cq = &srv->canceled_queue;
+ if (cq->head.first != cq->head.unref_end)
+ handle_canceled_queue(esdp, cq, 1,
+ ERTS_TMR_CANCELED_TIMER_SMALL_LIMIT,
+ NULL, NULL, NULL);
+#endif
+}
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+
+static void
+hlt_delete_abtm(ErtsHLTimer *tmr)
+{
+ Process *proc;
+
+ ERTS_HLT_ASSERT(tmr->head.roflgs & ERTS_TMR_ROFLG_ABIF_TMR);
+
+ proc = erts_proc_lookup(tmr->abtm.accessor);
+
+ if (proc) {
+ int deref = 0;
+ erts_smp_proc_lock(proc, ERTS_PROC_LOCK_BTM);
+ if (tmr->abtm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) {
+ abtm_rbt_delete(&proc->accessor_bif_timers, tmr);
+ deref = 1;
+ tmr->abtm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ }
+ erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
+ if (deref)
+ hl_timer_pre_dec_refc(tmr);
+ }
+}
+
+#endif
+
+static ErtsHLTimer *
+create_hl_timer(ErtsSchedulerData *esdp,
+ ErtsMonotonicTime timeout_pos,
+ int short_time, ErtsTmrType type,
+ void *rcvrp, Eterm rcvr, Eterm acsr,
+ Eterm msg, Uint32 *refn,
+ void (*callback)(void *), void *arg)
+{
+ ErtsHLTimerService *srv = esdp->timer_service;
+ ErtsHLTimer *tmr, *st_tmr;
+ erts_aint32_t refc;
+ Uint32 roflgs;
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ check_canceled_queue(esdp, srv);
+
+ ERTS_HLT_ASSERT((esdp->no & ~ERTS_TMR_ROFLG_SID_MASK) == 0);
+
+ roflgs = ((Uint32) esdp->no) | ERTS_TMR_ROFLG_HLT;
+
+ if (type != ERTS_TMR_BIF) {
+
+ tmr = erts_alloc(ERTS_ALC_T_HL_PTIMER,
+ ERTS_HL_PTIMER_SIZE);
+ tmr->timeout = timeout_pos;
+
+ switch (type) {
+
+ case ERTS_TMR_PROC:
+ ERTS_HLT_ASSERT(is_internal_pid(rcvr));
+
+ erts_proc_inc_refc((Process *) rcvrp);
+ tmr->receiver.proc = (Process *) rcvrp;
+ roflgs |= ERTS_TMR_ROFLG_PROC;
+ refc = 2;
+ break;
+
+ case ERTS_TMR_PORT:
+ ERTS_HLT_ASSERT(is_internal_port(rcvr));
+ erts_port_inc_refc((Port *) rcvrp);
+ tmr->receiver.port = (Port *) rcvrp;
+ roflgs |= ERTS_TMR_ROFLG_PORT;
+ refc = 2;
+ break;
+
+ case ERTS_TMR_CALLBACK:
+ roflgs |= ERTS_TMR_ROFLG_CALLBACK;
+ tmr->receiver.callback = callback;
+ tmr->head.u.arg = arg;
+ refc = 1;
+ break;
+
+ default:
+ ERTS_INTERNAL_ERROR("Unsupported timer type");
+ return NULL;
+ }
+
+ }
+ else { /* ERTS_TMR_BIF */
+ Uint hsz;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ int is_abif_tmr = is_value(acsr) && acsr != rcvr;
+#endif
+
+ if (short_time) {
+ tmr = bif_timer_pre_alloc();
+ if (!tmr)
+ goto alloc_bif_timer;
+ roflgs |= ERTS_TMR_ROFLG_PRE_ALC;
+ }
+ else {
+ alloc_bif_timer:
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ if (is_abif_tmr)
+ tmr = erts_alloc(ERTS_ALC_T_ABIF_TIMER,
+ ERTS_ABIF_TIMER_SIZE);
+ else
+#endif
+ tmr = erts_alloc(ERTS_ALC_T_BIF_TIMER,
+ ERTS_BIF_TIMER_SIZE);
+ }
+
+ tmr->timeout = timeout_pos;
+
+ roflgs |= ERTS_TMR_ROFLG_BIF_TMR;
+ if (is_internal_pid(rcvr)) {
+ roflgs |= ERTS_TMR_ROFLG_PROC;
+ tmr->receiver.proc = (Process *) rcvrp;
+ refc = 2;
+ }
+ else {
+ ERTS_HLT_ASSERT(is_atom(rcvr));
+ roflgs |= ERTS_TMR_ROFLG_REG_NAME;
+ tmr->receiver.name = rcvr;
+ refc = 1;
+ }
+
+ hsz = is_immed(msg) ? ((Uint) 0) : size_object(msg);
+ if (!hsz) {
+ tmr->btm.message = msg;
+ tmr->btm.bp = NULL;
+ }
+ else {
+ ErlHeapFragment *bp = new_message_buffer(hsz);
+ Eterm *hp = bp->mem;
+ tmr->btm.message = copy_struct(msg, hsz, &hp, &bp->off_heap);
+ tmr->btm.bp = bp;
+ }
+ tmr->btm.refn[0] = refn[0];
+ tmr->btm.refn[1] = refn[1];
+ tmr->btm.refn[2] = refn[2];
+
+ tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ if (is_abif_tmr) {
+ Process *aproc;
+ roflgs |= ERTS_TMR_ROFLG_ABIF_TMR;
+ tmr->abtm.accessor = acsr;
+ aproc = erts_proc_lookup(acsr);
+ if (!aproc)
+ tmr->abtm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ else {
+ refc++;
+ erts_smp_proc_lock(aproc, ERTS_PROC_LOCK_BTM);
+ abtm_rbt_insert(&aproc->accessor_bif_timers, tmr);
+ erts_smp_proc_unlock(aproc, ERTS_PROC_LOCK_BTM);
+ }
+ }
+#endif
+
+ btm_rbt_insert(&srv->btm_tree, tmr);
+ }
+
+ tmr->head.roflgs = roflgs;
+ erts_smp_atomic32_init_nob(&tmr->head.refc, refc);
+ erts_smp_atomic32_init_nob(&tmr->state, ERTS_TMR_STATE_ACTIVE);
+
+ if (!srv->next_timeout
+ || tmr->timeout < srv->next_timeout->timeout) {
+ if (srv->next_timeout)
+ erts_twheel_cancel_timer(esdp->timer_wheel,
+ &srv->service_timer);
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &srv->service_timer,
+ hlt_service_timeout,
+ NULL,
+ (void *) esdp,
+ tmr->timeout);
+ srv->next_timeout = tmr;
+ }
+
+ st_tmr = time_rbt_lookup_insert(&srv->time_tree, tmr);
+ tmr->time.tree.same_time = st_tmr;
+ if (st_tmr)
+ same_time_list_insert(&st_tmr->time.tree.same_time, tmr);
+
+#ifdef ERTS_HLT_HARD_DEBUG
+ tmr->pending_timeout = 0;
+#endif
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ return tmr;
+}
+
+static ERTS_INLINE void
+hlt_bif_timer_timeout(ErtsHLTimer *tmr, Uint32 roflgs)
+{
+ ErtsProcLocks proc_locks = ERTS_PROC_LOCKS_MSG_SEND;
+ Process *proc;
+ int queued_message = 0;
+ int dec_refc = 0;
+ Uint32 is_reg_name = (roflgs & ERTS_TMR_ROFLG_REG_NAME);
+ ERTS_HLT_ASSERT(roflgs & ERTS_TMR_ROFLG_BIF_TMR);
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ if (tmr->head.roflgs & ERTS_TMR_ROFLG_ABIF_TMR)
+ hlt_delete_abtm(tmr);
+#endif
+
+ if (is_reg_name) {
+ Eterm pid;
+ ERTS_HLT_ASSERT(is_atom(tmr->receiver.name));
+ pid = erts_whereis_name_to_id(NULL, tmr->receiver.name);
+ proc = erts_proc_lookup(pid);
+ }
+ else {
+ ERTS_HLT_ASSERT(roflgs & ERTS_TMR_ROFLG_PROC);
+ ERTS_HLT_ASSERT(tmr->receiver.proc);
+
+ proc = tmr->receiver.proc;
+ proc_locks |= ERTS_PROC_LOCK_BTM;
+ }
+ if (proc) {
+ erts_smp_proc_lock(proc, proc_locks);
+ /*
+ * If process is exiting, let it clean up
+ * the btm tree by itself (it may be in
+ * the middle of tree destruction).
+ */
+ if (!ERTS_PROC_IS_EXITING(proc)) {
+ erts_queue_message(proc, &proc_locks, tmr->btm.bp,
+ tmr->btm.message, NIL);
+ erts_smp_proc_unlock(proc, ERTS_PROC_LOCKS_MSG_SEND);
+ queued_message = 1;
+ proc_locks &= ~ERTS_PROC_LOCKS_MSG_SEND;
+ tmr->btm.bp = NULL;
+ if (tmr->btm.proc_tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) {
+ proc_btm_rbt_delete(&proc->bif_timers, tmr);
+ tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ dec_refc = 1;
+ }
+ }
+ if (proc_locks)
+ erts_smp_proc_unlock(proc, proc_locks);
+ if (dec_refc)
+ hl_timer_pre_dec_refc(tmr);
+ }
+ if (!queued_message && tmr->btm.bp)
+ free_message_buffer(tmr->btm.bp);
+}
+
+static ERTS_INLINE void
+hlt_proc_timeout(ErtsHLTimer *tmr)
+{
+ if (proc_timeout_common(tmr->receiver.proc, (void *) tmr))
+ hl_timer_dec_refc(tmr, tmr->head.roflgs);
+}
+
+static ERTS_INLINE void
+hlt_port_timeout(ErtsHLTimer *tmr)
+{
+ if (port_timeout_common(tmr->receiver.port, (void *) tmr))
+ hl_timer_dec_refc(tmr, tmr->head.roflgs);
+}
+
+static void hlt_timeout(ErtsHLTimer *tmr, void *vsrv)
+{
+ ErtsHLTimerService *srv = (ErtsHLTimerService *) vsrv;
+ Uint32 roflgs;
+ erts_aint32_t state;
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ roflgs = tmr->head.roflgs;
+ ERTS_HLT_ASSERT(roflgs & ERTS_TMR_ROFLG_HLT);
+
+ state = erts_smp_atomic32_cmpxchg_acqb(&tmr->state,
+ ERTS_TMR_STATE_TIMED_OUT,
+ ERTS_TMR_STATE_ACTIVE);
+
+ ERTS_HLT_ASSERT(state == ERTS_TMR_STATE_CANCELED
+ || state == ERTS_TMR_STATE_ACTIVE);
+
+ if (state == ERTS_TMR_STATE_ACTIVE) {
+
+ if (roflgs & ERTS_TMR_ROFLG_BIF_TMR)
+ hlt_bif_timer_timeout(tmr, roflgs);
+ else if (roflgs & ERTS_TMR_ROFLG_PROC)
+ hlt_proc_timeout(tmr);
+ else if (roflgs & ERTS_TMR_ROFLG_PORT)
+ hlt_port_timeout(tmr);
+ else {
+ ERTS_HLT_ASSERT(roflgs & ERTS_TMR_ROFLG_CALLBACK);
+ (*tmr->receiver.callback)(tmr->head.u.arg);
+ }
+
+ }
+
+ tmr->time.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ if ((roflgs & ERTS_TMR_ROFLG_BIF_TMR)
+ && tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) {
+ btm_rbt_delete(&srv->btm_tree, tmr);
+ tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ }
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ hl_timer_dec_refc(tmr, roflgs);
+}
+
+#ifdef ERTS_HLT_HARD_DEBUG
+static void
+set_pending_timeout(ErtsHLTimer *tmr, void *unused)
+{
+ tmr->pending_timeout = -1;
+}
+#endif
+
+static void
+hlt_service_timeout(void *vesdp)
+{
+ ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp;
+ ErtsHLTimerService *srv = esdp->timer_service;
+ ErtsHLTimer *tmr = srv->next_timeout;
+ int yield;
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ ERTS_HLT_ASSERT(esdp == erts_get_scheduler_data());
+
+ ERTS_HLT_ASSERT(!srv->yield.root || srv->yield.root == tmr);
+ ERTS_HLT_ASSERT(tmr);
+ ERTS_HLT_ASSERT(tmr->timeout <= erts_get_monotonic_time(esdp));
+
+ if (!srv->yield.root) {
+ ERTS_HLT_ASSERT(tmr->time.tree.parent
+ != ERTS_HLT_PFIELD_NOT_IN_TABLE);
+ time_rbt_delete(&srv->time_tree, tmr);
+ tmr->time.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+#ifdef ERTS_HLT_HARD_DEBUG
+ tmr->pending_timeout = 1;
+ if (tmr->time.tree.same_time)
+ same_time_list_foreach(tmr->time.tree.same_time, set_pending_timeout, NULL);
+#endif
+ }
+
+ if (!tmr->time.tree.same_time && !srv->yield.root)
+ yield = 0;
+ else {
+ yield = same_time_list_foreach_destroy_yielding(
+ &tmr->time.tree.same_time, hlt_timeout, (void *) srv,
+ &srv->yield.state, ERTS_TMR_TIMEOUT_YIELD_LIMIT);
+ }
+
+ if (yield)
+ srv->yield.root = tmr;
+ else {
+ srv->yield.root = NULL;
+ hlt_timeout(tmr, (void *) srv);
+
+ tmr = time_rbt_smallest(srv->time_tree);
+ srv->next_timeout = tmr;
+ }
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ if (tmr)
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &srv->service_timer,
+ hlt_service_timeout,
+ NULL,
+ vesdp,
+ tmr->timeout);
+}
+
+static void
+hlt_delete_timer(ErtsSchedulerData *esdp, ErtsHLTimer *tmr)
+{
+ ErtsHLTimerService *srv = esdp->timer_service;
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+
+ if (tmr->head.roflgs & ERTS_TMR_ROFLG_BIF_TMR) {
+
+ if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) {
+ btm_rbt_delete(&srv->btm_tree, tmr);
+ tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ }
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ if (tmr->head.roflgs & ERTS_TMR_ROFLG_ABIF_TMR)
+ hlt_delete_abtm(tmr);
+#endif
+ }
+
+ if (tmr->time.tree.parent == ERTS_HLT_PFIELD_NOT_IN_TABLE) {
+ /* Already removed... */
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+ return;
+ }
+
+ if (tmr->time.tree.parent & ERTS_HLT_PFLG_SAME_TIME) {
+ same_time_list_delete(tmr);
+ }
+ else if (tmr->time.tree.same_time) {
+ ErtsHLTimer *st_container;
+
+ ERTS_HLT_ASSERT((tmr->time.tree.parent & ERTS_HLT_PFLG_SAME_TIME) == 0);
+ st_container = tmr->time.tree.same_time->time.tree.u.l.prev;
+
+ ERTS_HLT_ASSERT(st_container);
+ ERTS_HLT_ASSERT(st_container->time.tree.parent
+ & ERTS_HLT_PFLG_SAME_TIME);
+ ERTS_HLT_ASSERT(tmr->timeout == st_container->timeout);
+
+ same_time_list_delete(st_container);
+ st_container->time.tree.same_time = tmr->time.tree.same_time;
+ same_time_list_new_root(&st_container->time.tree.same_time);
+
+ time_rbt_replace(&srv->time_tree, tmr, st_container);
+ ERTS_HLT_ASSERT((st_container->time.tree.parent
+ & ERTS_HLT_PFLG_SAME_TIME) == 0);
+
+ if (srv->next_timeout == tmr)
+ srv->next_timeout = st_container;
+ }
+ else {
+ ERTS_HLT_ASSERT((tmr->time.tree.parent & ERTS_HLT_PFLG_SAME_TIME) == 0);
+ time_rbt_delete(&srv->time_tree, tmr);
+ if (tmr == srv->next_timeout) {
+ ErtsHLTimer *smlst;
+ erts_twheel_cancel_timer(esdp->timer_wheel,
+ &srv->service_timer);
+ smlst = time_rbt_smallest(srv->time_tree);
+ srv->next_timeout = smlst;
+ if (smlst) {
+ ERTS_HLT_ASSERT(smlst->timeout > tmr->timeout);
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &srv->service_timer,
+ hlt_service_timeout,
+ NULL,
+ (void *) esdp,
+ smlst->timeout);
+ }
+ }
+ }
+ tmr->time.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+
+ hl_timer_dec_refc(tmr, tmr->head.roflgs);
+
+ ERTS_HLT_HDBG_CHK_SRV(srv);
+}
+
+/*
+ * Pass canceled timers back to originating scheduler
+ */
+
+static ERTS_INLINE void
+cleanup_sched_local_canceled_timer(ErtsSchedulerData *esdp,
+ ErtsTimer *tmr)
+{
+ Uint32 roflgs = tmr->head.roflgs;
+ ERTS_HLT_ASSERT(esdp == erts_get_scheduler_data());
+ ERTS_HLT_ASSERT((tmr->head.roflgs & ERTS_TMR_ROFLG_SID_MASK)
+ == (Uint32) esdp->no);
+ if (roflgs & ERTS_TMR_ROFLG_HLT) {
+ hlt_delete_timer(esdp, &tmr->hlt);
+ hl_timer_dec_refc(&tmr->hlt, roflgs);
+ }
+ else {
+ cancel_tw_timer(esdp, &tmr->twt);
+ tw_timer_dec_refc(&tmr->twt);
+ }
+}
+
+#ifdef ERTS_SMP
+
+static void
+init_canceled_queue(ErtsHLTCncldTmrQ *cq)
+{
+ erts_atomic_init_nob(&cq->tail.data.marker.u.next, ERTS_AINT_NULL);
+ erts_atomic_init_nob(&cq->tail.data.last,
+ (erts_aint_t) &cq->tail.data.marker);
+ cq->head.first = (ErtsTimer *) &cq->tail.data.marker;
+ cq->head.unref_end = (ErtsTimer *) &cq->tail.data.marker;
+ cq->head.next.thr_progress = erts_thr_progress_current();
+ cq->head.next.thr_progress_reached = 1;
+ cq->head.next.unref_end = (ErtsTimer *) &cq->tail.data.marker;
+ cq->head.used_marker = 1;
+}
+
+static ERTS_INLINE int
+cq_enqueue(ErtsHLTCncldTmrQ *cq, ErtsTimer *tmr, int cinit)
+{
+ erts_aint_t itmp;
+ ErtsTimer *enq, *this = tmr;
+
+ erts_atomic_init_nob(&this->head.u.next, ERTS_AINT_NULL);
+ /* Enqueue at end of list... */
+
+ enq = (ErtsTimer *) erts_atomic_read_nob(&cq->tail.data.last);
+ itmp = erts_atomic_cmpxchg_relb(&enq->head.u.next,
+ (erts_aint_t) this,
+ ERTS_AINT_NULL);
+ if (itmp == ERTS_AINT_NULL) {
+ /* We are required to move last pointer */
+#ifdef DEBUG
+ ASSERT(ERTS_AINT_NULL == erts_atomic_read_nob(&this->head.u.next));
+ ASSERT(((erts_aint_t) enq)
+ == erts_atomic_xchg_relb(&cq->tail.data.last,
+ (erts_aint_t) this));
+#else
+ erts_atomic_set_relb(&cq->tail.data.last, (erts_aint_t) this);
+#endif
+ return 1;
+ }
+ else {
+ /*
+ * We *need* to insert element somewhere in between the
+ * last element we read earlier and the actual last element.
+ */
+ int i = cinit;
+
+ while (1) {
+ erts_aint_t itmp2;
+ erts_atomic_set_nob(&this->head.u.next, itmp);
+ itmp2 = erts_atomic_cmpxchg_relb(&enq->head.u.next,
+ (erts_aint_t) this,
+ itmp);
+ if (itmp == itmp2)
+ return 0; /* inserted this */
+ if ((i & 1) == 0)
+ itmp = itmp2;
+ else {
+ enq = (ErtsTimer *) itmp2;
+ itmp = erts_atomic_read_acqb(&enq->head.u.next);
+ ASSERT(itmp != ERTS_AINT_NULL);
+ }
+ i++;
+ }
+ }
+}
+
+static ERTS_INLINE erts_aint_t
+check_insert_marker(ErtsHLTCncldTmrQ *cq, erts_aint_t ilast)
+{
+ if (!cq->head.used_marker
+ && cq->head.unref_end == (ErtsTimer *) ilast) {
+ erts_aint_t itmp;
+ ErtsTimer *last = (ErtsTimer *) ilast;
+
+ erts_atomic_init_nob(&cq->tail.data.marker.u.next, ERTS_AINT_NULL);
+ itmp = erts_atomic_cmpxchg_relb(&last->head.u.next,
+ (erts_aint_t) &cq->tail.data.marker,
+ ERTS_AINT_NULL);
+ if (itmp == ERTS_AINT_NULL) {
+ ilast = (erts_aint_t) &cq->tail.data.marker;
+ cq->head.used_marker = !0;
+ erts_atomic_set_relb(&cq->tail.data.last, ilast);
+ }
+ }
+ return ilast;
+}
+
+static ERTS_INLINE ErtsTimer *
+cq_dequeue(ErtsHLTCncldTmrQ *cq)
+{
+ ErtsTimer *tmr;
+
+ if (cq->head.first == cq->head.unref_end)
+ return NULL;
+
+ tmr = cq->head.first;
+ if (tmr == (ErtsTimer *) &cq->tail.data.marker) {
+ ASSERT(cq->head.used_marker);
+ cq->head.used_marker = 0;
+ tmr = (ErtsTimer *) erts_atomic_read_nob(&tmr->head.u.next);
+ if (tmr == cq->head.unref_end) {
+ cq->head.first = tmr;
+ return NULL;
+ }
+ }
+
+ cq->head.first = (ErtsTimer *) erts_atomic_read_nob(&tmr->head.u.next);
+
+ ASSERT(cq->head.first);
+
+ return tmr;
+}
+
+static int
+cq_check_incoming(ErtsSchedulerData *esdp, ErtsHLTCncldTmrQ *cq)
+{
+ erts_aint_t ilast = erts_atomic_read_nob(&cq->tail.data.last);
+ if (((ErtsTimer *) ilast) == (ErtsTimer *) &cq->tail.data.marker
+ && cq->head.first == (ErtsTimer *) &cq->tail.data.marker) {
+ /* Nothing more to do... */
+ return 0;
+ }
+
+ if (cq->head.next.thr_progress_reached
+ || erts_thr_progress_has_reached(cq->head.next.thr_progress)) {
+ cq->head.next.thr_progress_reached = 1;
+ /* Move unreferenced end pointer forward... */
+
+ ERTS_HLT_SMP_MEMBAR_LoadLoad_LoadStore;
+
+ cq->head.unref_end = cq->head.next.unref_end;
+
+ ilast = check_insert_marker(cq, ilast);
+
+ if (cq->head.unref_end != (ErtsTimer *) ilast) {
+ cq->head.next.unref_end = (ErtsTimer *) ilast;
+ cq->head.next.thr_progress = erts_thr_progress_later(esdp);
+ cq->head.next.thr_progress_reached = 0;
+ }
+ }
+ return 1;
+}
+
+static ERTS_INLINE void
+store_earliest_thr_prgr(ErtsThrPrgrVal *prev_val, ErtsHLTCncldTmrQ *cq)
+{
+ if (!cq->head.next.thr_progress_reached
+ && (*prev_val == ERTS_THR_PRGR_INVALID
+ || erts_thr_progress_cmp(cq->head.next.thr_progress,
+ *prev_val) < 0)) {
+ *prev_val = cq->head.next.thr_progress;
+ }
+}
+
+static void
+handle_canceled_queue(ErtsSchedulerData *esdp,
+ ErtsHLTCncldTmrQ *cq,
+ int use_limit,
+ int ops_limit,
+ int *need_thr_progress,
+ ErtsThrPrgrVal *thr_prgr_p,
+ int *need_more_work)
+{
+ int need_thr_prgr = 0;
+ int need_mr_wrk = 0;
+ int have_checked_incoming = 0;
+ int ops = 0;
+
+ ERTS_HLT_ASSERT(cq == &esdp->timer_service->canceled_queue);
+
+ while (1) {
+ ErtsTimer *tmr = cq_dequeue(cq);
+
+ if (tmr)
+ cleanup_sched_local_canceled_timer(esdp, tmr);
+ else {
+ if (have_checked_incoming)
+ break;
+ need_thr_prgr = cq_check_incoming(esdp, cq);
+ if (need_thr_progress) {
+ *need_thr_progress |= need_thr_prgr;
+ if (need_thr_prgr)
+ store_earliest_thr_prgr(thr_prgr_p, cq);
+ }
+ have_checked_incoming = 1;
+ continue;
+ }
+
+ if (use_limit && ++ops >= ops_limit) {
+ if (cq->head.first != cq->head.unref_end) {
+ need_mr_wrk = 1;
+ if (need_more_work)
+ *need_more_work |= 1;
+ }
+ break;
+ }
+ }
+
+ if (need_thr_progress && !(need_thr_prgr | need_mr_wrk)) {
+ need_thr_prgr = cq_check_incoming(esdp, cq);
+ *need_thr_progress |= need_thr_prgr;
+ if (need_thr_prgr)
+ store_earliest_thr_prgr(thr_prgr_p, cq);
+ }
+}
+
+void
+erts_handle_canceled_timers(void *vesdp,
+ int *need_thr_progress,
+ ErtsThrPrgrVal *thr_prgr_p,
+ int *need_more_work)
+{
+ ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp;
+ ERTS_HLT_ASSERT(esdp == erts_get_scheduler_data());
+
+ handle_canceled_queue(esdp, &esdp->timer_service->canceled_queue,
+ 1, ERTS_TMR_CANCELED_TIMER_LIMIT,
+ need_thr_progress, thr_prgr_p,
+ need_more_work);
+}
+
+#endif /* ERTS_SMP */
+
+static void
+queue_canceled_timer(ErtsSchedulerData *esdp, int rsched_id, ErtsTimer *tmr)
+{
+#ifdef ERTS_SMP
+ ErtsHLTCncldTmrQ *cq;
+ cq = &ERTS_SCHEDULER_IX(rsched_id-1)->timer_service->canceled_queue;
+ if (cq_enqueue(cq, tmr, rsched_id - (int) esdp->no))
+ erts_notify_canceled_timer(esdp, rsched_id);
+#else
+ ERTS_INTERNAL_ERROR("Unexpected enqueue of canceled timer");
+#endif
+}
+
+static void
+continue_cancel_ptimer(ErtsSchedulerData *esdp, ErtsTimer *tmr)
+{
+#ifdef ERTS_SMP
+ Uint32 sid = (tmr->head.roflgs & ERTS_TMR_ROFLG_SID_MASK);
+
+ if (esdp->no != sid)
+ queue_canceled_timer(esdp, sid, tmr);
+ else
+#endif
+ cleanup_sched_local_canceled_timer(esdp, tmr);
+}
+
+/*
+ * BIF timer specific
+ */
+
+Uint erts_bif_timer_memory_size(void)
+{
+ return (Uint) 0;
+}
+
+static BIF_RETTYPE
+setup_bif_timer(Process *c_p, ErtsMonotonicTime timeout_pos,
+ int short_time, Eterm rcvr, Eterm acsr,
+ Eterm msg, int wrap)
+{
+ BIF_RETTYPE ret;
+ Eterm ref, tmo_msg, *hp;
+ ErtsHLTimer *tmr;
+ ErtsSchedulerData *esdp;
+ DeclareTmpHeap(tmp_hp, 4, c_p);
+
+ if (is_not_internal_pid(rcvr) && is_not_atom(rcvr))
+ goto badarg;
+
+ esdp = ERTS_PROC_GET_SCHDATA(c_p);
+
+ hp = HAlloc(c_p, REF_THING_SIZE);
+ ref = erts_sched_make_ref_in_buffer(esdp, hp);
+
+ ASSERT(erts_get_ref_numbers_thr_id(
+ internal_ref_numbers(ref)) == (Uint32) esdp->no);
+
+ UseTmpHeap(4, c_p);
+
+ tmo_msg = wrap ? TUPLE3(tmp_hp, am_timeout, ref, msg) : msg;
+
+ tmr = create_hl_timer(esdp, timeout_pos, short_time,
+ ERTS_TMR_BIF, NULL, rcvr, acsr, tmo_msg,
+ internal_ref_numbers(ref), NULL, NULL);
+
+ UnUseTmpHeap(4, c_p);
+
+ if (is_internal_pid(rcvr)) {
+ Process *proc = erts_pid2proc_opt(c_p, ERTS_PROC_LOCK_MAIN,
+ rcvr, ERTS_PROC_LOCK_BTM,
+ ERTS_P2P_FLG_INC_REFC);
+ if (!proc) {
+ if (tmr->btm.bp)
+ free_message_buffer(tmr->btm.bp);
+ hlt_delete_timer(esdp, tmr);
+ hl_timer_destroy(tmr);
+ }
+ else {
+ proc_btm_rbt_insert(&proc->bif_timers, tmr);
+ erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
+ tmr->receiver.proc = proc;
+ }
+ }
+
+ ERTS_BIF_PREP_RET(ret, ref);
+ return ret;
+
+badarg:
+
+ ERTS_BIF_PREP_ERROR(ret, c_p, BADARG);
+ return ret;
+}
+
+static int
+cancel_bif_timer(ErtsHLTimer *tmr)
+{
+ erts_aint_t state;
+ Uint32 roflgs;
+ int res;
+
+ state = erts_smp_atomic32_cmpxchg_acqb(&tmr->state,
+ ERTS_TMR_STATE_CANCELED,
+ ERTS_TMR_STATE_ACTIVE);
+ if (state != ERTS_TMR_STATE_ACTIVE)
+ return 0;
+
+ if (tmr->btm.bp)
+ free_message_buffer(tmr->btm.bp);
+
+ res = -1;
+
+ roflgs = tmr->head.roflgs;
+ if (roflgs & ERTS_TMR_ROFLG_PROC) {
+ Process *proc = tmr->receiver.proc;
+ ERTS_HLT_ASSERT(!(tmr->head.roflgs & ERTS_TMR_ROFLG_REG_NAME));
+
+ erts_smp_proc_lock(proc, ERTS_PROC_LOCK_BTM);
+ /*
+ * If process is exiting, let it clean up
+ * the btm tree by itself (it may be in
+ * the middle of tree destruction).
+ */
+ if (!ERTS_PROC_IS_EXITING(proc)
+ && tmr->btm.proc_tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) {
+ proc_btm_rbt_delete(&proc->bif_timers, tmr);
+ tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ res = 1;
+ }
+ erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
+ }
+
+ return res;
+}
+
+static ERTS_INLINE Eterm
+access_sched_local_btm(Process *c_p, Eterm pid,
+ Eterm tref, Uint32 *trefn,
+ Uint32 *rrefn,
+ int async, int cancel,
+ int return_res,
+ int info)
+{
+ ErtsSchedulerData *esdp;
+ ErtsHLTimerService *srv;
+ ErtsHLTimer *tmr;
+ Sint64 time_left;
+ Process *proc;
+ ErtsProcLocks proc_locks;
+
+ time_left = -1;
+
+ if (!c_p)
+ esdp = erts_get_scheduler_data();
+ else {
+ esdp = ERTS_PROC_GET_SCHDATA(c_p);
+ ERTS_HLT_ASSERT(esdp == erts_get_scheduler_data());
+ }
+
+ ERTS_HLT_ASSERT(erts_get_ref_numbers_thr_id(trefn)
+ == (Uint32) esdp->no);
+
+ srv = esdp->timer_service;
+
+ tmr = btm_rbt_lookup(srv->btm_tree, trefn);
+ if (tmr) {
+ if (!cancel) {
+ erts_aint32_t state = erts_smp_atomic32_read_acqb(&tmr->state);
+ if (state == ERTS_TMR_STATE_ACTIVE)
+ time_left = get_time_left(esdp, tmr->timeout);
+ }
+ else {
+ int cncl_res = cancel_bif_timer(tmr);
+ if (cncl_res) {
+
+ time_left = get_time_left(esdp, tmr->timeout);
+
+ if (cncl_res > 0)
+ hl_timer_dec_refc(tmr, tmr->head.roflgs);
+
+ hlt_delete_timer(esdp, tmr);
+ }
+ }
+ }
+
+ if (!info)
+ return am_ok;
+
+ if (return_res) {
+ ERTS_HLT_ASSERT(c_p);
+ if (time_left < 0)
+ return am_false;
+ else if (time_left <= (Sint64) MAX_SMALL)
+ return make_small((Sint) time_left);
+ else {
+ Uint hsz = ERTS_SINT64_HEAP_SIZE(time_left);
+ Eterm *hp = HAlloc(c_p, hsz);
+ return erts_sint64_to_big(time_left, &hp);
+ }
+ }
+
+ if (c_p) {
+ proc = c_p;
+ proc_locks = ERTS_PROC_LOCK_MAIN;
+ }
+ else {
+ proc = erts_proc_lookup(pid);
+ proc_locks = 0;
+ }
+
+ if (proc) {
+ Uint hsz;
+ ErlOffHeap *ohp;
+ ErlHeapFragment* bp;
+ Eterm *hp, msg, ref, result;
+#ifdef ERTS_HLT_DEBUG
+ Eterm *hp_end;
+#endif
+
+ hsz = 3; /* 2-tuple */
+ if (!async)
+ hsz += REF_THING_SIZE;
+ else {
+ if (is_non_value(tref) || proc != c_p)
+ hsz += REF_THING_SIZE;
+ hsz += 1; /* upgrade to 3-tuple */
+ }
+ if (time_left > (Sint64) MAX_SMALL)
+ hsz += ERTS_SINT64_HEAP_SIZE(time_left);
+
+ if (proc == c_p) {
+ bp = NULL;
+ ohp = NULL;
+ hp = HAlloc(c_p, hsz);
+ }
+ else {
+ hp = erts_alloc_message_heap(hsz,
+ &bp,
+ &ohp,
+ proc,
+ &proc_locks);
+ }
+
+#ifdef ERTS_HLT_DEBUG
+ hp_end = hp + hsz;
+#endif
+
+ if (time_left < 0)
+ result = am_false;
+ else if (time_left <= (Sint64) MAX_SMALL)
+ result = make_small((Sint) time_left);
+ else
+ result = erts_sint64_to_big(time_left, &hp);
+
+ if (!async) {
+ write_ref_thing(hp,
+ rrefn[0],
+ rrefn[1],
+ rrefn[2]);
+ ref = make_internal_ref(hp);
+ hp += REF_THING_SIZE;
+ msg = TUPLE2(hp, ref, result);
+
+ ERTS_HLT_ASSERT(hp + 3 == hp_end);
+ }
+ else {
+ Eterm tag = cancel ? am_cancel_timer : am_read_timer;
+ if (is_value(tref) && proc == c_p)
+ ref = tref;
+ else {
+ write_ref_thing(hp,
+ trefn[0],
+ trefn[1],
+ trefn[2]);
+ ref = make_internal_ref(hp);
+ hp += REF_THING_SIZE;
+ }
+ msg = TUPLE3(hp, tag, ref, result);
+
+ ERTS_HLT_ASSERT(hp + 4 == hp_end);
+
+ }
+ erts_queue_message(proc, &proc_locks, bp, msg, NIL);
+
+ if (c_p)
+ proc_locks &= ~ERTS_PROC_LOCK_MAIN;
+ if (proc_locks)
+ erts_smp_proc_unlock(proc, proc_locks);
+ }
+
+ return am_ok;
+}
+
+#define ERTS_BTM_REQ_FLG_ASYNC (((Uint32) 1) << 0)
+#define ERTS_BTM_REQ_FLG_CANCEL (((Uint32) 1) << 1)
+#define ERTS_BTM_REQ_FLG_INFO (((Uint32) 1) << 2)
+
+typedef struct {
+ Eterm pid;
+ Uint32 trefn[ERTS_REF_NUMBERS];
+ Uint32 rrefn[ERTS_REF_NUMBERS];
+ Uint32 flags;
+} ErtsBifTimerRequest;
+
+static void
+bif_timer_access_request(void *vreq)
+{
+ ErtsBifTimerRequest *req = (ErtsBifTimerRequest *) vreq;
+ int async = (int) (req->flags & ERTS_BTM_REQ_FLG_ASYNC);
+ int cancel = (int) (req->flags & ERTS_BTM_REQ_FLG_CANCEL);
+ int info = (int) (req->flags & ERTS_BTM_REQ_FLG_INFO);
+ (void) access_sched_local_btm(NULL, req->pid, THE_NON_VALUE,
+ req->trefn, req->rrefn, async,
+ cancel, 0, info);
+ erts_free(ERTS_ALC_T_TIMER_REQUEST, vreq);
+}
+
+static int
+try_access_sched_remote_btm(ErtsSchedulerData *esdp,
+ Process *c_p, Uint32 sid,
+ Eterm tref, Uint32 *trefn,
+ int async, int cancel,
+ int info, Eterm *resp)
+{
+ ErtsHLTimer *tmr;
+ Sint64 time_left;
+
+ ERTS_HLT_ASSERT(c_p);
+
+ /*
+ * Check if the timer is aimed at current
+ * process of if this process is an accessor
+ * of the timer...
+ */
+ erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_BTM);
+ tmr = proc_btm_rbt_lookup(c_p->bif_timers, trefn);
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ if (!tmr)
+ tmr = abtm_rbt_lookup(c_p->accessor_bif_timers, trefn);
+#endif
+ erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_BTM);
+ if (!tmr)
+ return 0;
+
+ if (!cancel) {
+ erts_aint32_t state = erts_smp_atomic32_read_acqb(&tmr->state);
+ if (state == ERTS_TMR_STATE_ACTIVE)
+ time_left = get_time_left(esdp, tmr->timeout);
+ else
+ time_left = -1;
+ }
+ else {
+ int cncl_res = cancel_bif_timer(tmr);
+ if (!cncl_res)
+ time_left = -1;
+ else {
+ time_left = get_time_left(esdp, tmr->timeout);
+ if (cncl_res > 0)
+ queue_canceled_timer(esdp, sid, (ErtsTimer *) tmr);
+ }
+ }
+
+ if (!info) {
+ *resp = am_ok;
+ return 1;
+ }
+
+ if (!async) {
+ if (time_left < 0)
+ *resp = am_false;
+ else if (time_left <= (Sint64) MAX_SMALL)
+ *resp = make_small((Sint) time_left);
+ else {
+ Uint hsz = ERTS_SINT64_HEAP_SIZE(time_left);
+ Eterm *hp = HAlloc(c_p, hsz);
+ *resp = erts_sint64_to_big(time_left, &hp);
+ }
+ }
+ else {
+ Eterm tag, res, msg;
+ Uint hsz;
+ Eterm *hp;
+ ErtsProcLocks proc_locks = ERTS_PROC_LOCK_MAIN;
+
+ hsz = 4;
+ if (time_left > (Sint64) MAX_SMALL)
+ hsz += ERTS_SINT64_HEAP_SIZE(time_left);
+
+ hp = HAlloc(c_p, hsz);
+ if (cancel)
+ tag = am_cancel_timer;
+ else
+ tag = am_read_timer;
+
+ if (time_left < 0)
+ res = am_false;
+ else if (time_left <= (Sint64) MAX_SMALL)
+ res = make_small((Sint) time_left);
+ else
+ res = erts_sint64_to_big(time_left, &hp);
+
+ msg = TUPLE3(hp, tag, tref, res);
+
+ erts_queue_message(c_p, &proc_locks, NULL, msg, NIL);
+
+ proc_locks &= ~ERTS_PROC_LOCK_MAIN;
+ if (proc_locks)
+ erts_smp_proc_unlock(c_p, proc_locks);
+
+ *resp = am_ok;
+ }
+ return 1;
+}
+
+static BIF_RETTYPE
+access_bif_timer(Process *c_p, Eterm tref, int cancel, int async, int info)
+{
+ BIF_RETTYPE ret;
+ ErtsSchedulerData *esdp;
+ Uint32 sid;
+ Uint32 *trefn;
+ Eterm res;
+
+ if (is_not_internal_ref(tref)) {
+ if (is_not_ref(tref))
+ goto badarg;
+ else
+ goto no_timer;
+ }
+
+ esdp = ERTS_PROC_GET_SCHDATA(c_p);
+
+ trefn = internal_ref_numbers(tref);
+ sid = erts_get_ref_numbers_thr_id(trefn);
+ if (sid < 1 || erts_no_schedulers < sid)
+ goto no_timer;
+
+ if (sid == (Uint32) esdp->no) {
+ res = access_sched_local_btm(c_p, c_p->common.id,
+ tref, trefn, NULL,
+ async, cancel, !async,
+ info);
+ ERTS_BIF_PREP_RET(ret, res);
+ }
+ else if (try_access_sched_remote_btm(esdp, c_p, sid,
+ tref, trefn,
+ async, cancel,
+ info, &res)) {
+ ERTS_BIF_PREP_RET(ret, res);
+ }
+ else {
+ /*
+ * Schedule access for execution on
+ * remote scheduler...
+ */
+ ErtsBifTimerRequest *req = erts_alloc(ERTS_ALC_T_TIMER_REQUEST,
+ sizeof(ErtsBifTimerRequest));
+
+ req->flags = 0;
+ if (cancel)
+ req->flags |= ERTS_BTM_REQ_FLG_CANCEL;
+ if (async)
+ req->flags |= ERTS_BTM_REQ_FLG_ASYNC;
+ if (info)
+ req->flags |= ERTS_BTM_REQ_FLG_INFO;
+
+ req->pid = c_p->common.id;
+
+ req->trefn[0] = trefn[0];
+ req->trefn[1] = trefn[1];
+ req->trefn[2] = trefn[2];
+
+ if (async)
+ ERTS_BIF_PREP_RET(ret, am_ok);
+ else {
+ Eterm *hp, rref;
+ Uint32 *rrefn;
+
+ hp = HAlloc(c_p, REF_THING_SIZE);
+ rref = erts_sched_make_ref_in_buffer(esdp, hp);
+ rrefn = internal_ref_numbers(rref);
+
+ req->rrefn[0] = rrefn[0];
+ req->rrefn[1] = rrefn[1];
+ req->rrefn[2] = rrefn[2];
+
+ erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
+
+ if (ERTS_PROC_PENDING_EXIT(c_p))
+ ERTS_VBUMP_ALL_REDS(c_p);
+ else {
+ /*
+ * Caller needs to wait for a message containing
+ * the ref that we just created. No such message
+ * can exist in callers message queue at this time.
+ * We therefore move the save pointer of the
+ * callers message queue to the end of the queue.
+ *
+ * NOTE: It is of vital importance that the caller
+ * immediately do a receive unconditionaly
+ * waiting for the message with the reference;
+ * otherwise, next receive will *not* work
+ * as expected!
+ */
+ ERTS_SMP_MSGQ_MV_INQ2PRIVQ(c_p);
+ c_p->msg.save = c_p->msg.last;
+ }
+ erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
+
+ ERTS_BIF_PREP_TRAP1(ret, erts_await_result, c_p, rref);
+ }
+
+ erts_schedule_misc_aux_work(sid,
+ bif_timer_access_request,
+ (void *) req);
+ }
+
+ return ret;
+
+badarg:
+ ERTS_BIF_PREP_ERROR(ret, c_p, BADARG);
+ return ret;
+
+no_timer:
+ ERTS_BIF_PREP_RET(ret, am_false);
+ return ret;
+
+}
+
+static ERTS_INLINE int
+bool_arg(Eterm val, int *argp)
+{
+ switch (val) {
+ case am_true: *argp = 1; return 1;
+ case am_false: *argp = 0; return 1;
+ default: return 0;
+ }
+}
+
+static ERTS_INLINE int
+parse_bif_timer_options(Eterm option_list, int *async, int *info,
+ int *abs, Eterm *accessor)
+{
+ Eterm list = option_list;
+
+ if (async)
+ *async = 0;
+ if (info)
+ *info = 1;
+ if (abs)
+ *abs = 0;
+ if (accessor)
+ *accessor = THE_NON_VALUE;
+
+ while (is_list(list)) {
+ Eterm *consp, *tp, opt;
+
+ consp = list_val(list);
+ opt = CAR(consp);
+ if (is_not_tuple(opt))
+ return 0;
+
+ tp = tuple_val(opt);
+ if (arityval(tp[0]) != 2)
+ return 0;
+
+ switch (tp[1]) {
+ case am_async:
+ if (!async || !bool_arg(tp[2], async))
+ return 0;
+ break;
+ case am_info:
+ if (!info || !bool_arg(tp[2], info))
+ return 0;
+ break;
+ case am_abs:
+ if (!abs || !bool_arg(tp[2], abs))
+ return 0;
+ break;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ case am_accessor:
+ if (!accessor || is_not_internal_pid(tp[2]))
+ return 0;
+ *accessor = tp[2];
+ break;
+#endif
+ default:
+ return 0;
+ }
+
+ list = CDR(consp);
+ }
+
+ if (is_not_nil(list))
+ return 0;
+ return 1;
+}
+
+static void
+exit_cancel_bif_timer(ErtsHLTimer *tmr, void *vesdp)
+{
+ ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp;
+ Uint32 sid, roflgs;
+ erts_aint_t state;
+
+ state = erts_smp_atomic32_cmpxchg_acqb(&tmr->state,
+ ERTS_TMR_STATE_CANCELED,
+ ERTS_TMR_STATE_ACTIVE);
+
+ roflgs = tmr->head.roflgs;
+ sid = roflgs & ERTS_TMR_ROFLG_SID_MASK;
+
+ ERTS_HLT_ASSERT(sid == erts_get_ref_numbers_thr_id(tmr->btm.refn));
+ ERTS_HLT_ASSERT(tmr->btm.proc_tree.parent
+ != ERTS_HLT_PFIELD_NOT_IN_TABLE);
+
+ tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+
+ if (sid == (Uint32) esdp->no) {
+ if (state == ERTS_TMR_STATE_ACTIVE) {
+ if (tmr->btm.bp)
+ free_message_buffer(tmr->btm.bp);
+ hlt_delete_timer(esdp, tmr);
+ }
+ hl_timer_dec_refc(tmr, roflgs);
+ }
+ else {
+ if (state == ERTS_TMR_STATE_ACTIVE) {
+ if (tmr->btm.bp)
+ free_message_buffer(tmr->btm.bp);
+ queue_canceled_timer(esdp, sid, (ErtsTimer *) tmr);
+ }
+ else
+ hl_timer_dec_refc(tmr, roflgs);
+ }
+}
+
+#ifdef ERTS_HLT_DEBUG
+# define ERTS_BTM_MAX_DESTROY_LIMIT 2
+#else
+# define ERTS_BTM_MAX_DESTROY_LIMIT 50
+#endif
+
+typedef struct {
+ ErtsBifTimers *bif_timers;
+ union {
+ proc_btm_rbt_yield_state_t proc_btm_yield_state;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ abtm_rbt_yield_state_t abtm_yield_state;
+#endif
+ } u;
+} ErtsBifTimerYieldState;
+
+int erts_cancel_bif_timers(Process *p, ErtsBifTimers *btm, void **vyspp)
+{
+ ErtsSchedulerData *esdp = ERTS_PROC_GET_SCHDATA(p);
+ ErtsBifTimerYieldState ys = {btm, {ERTS_RBT_YIELD_STAT_INITER}};
+ ErtsBifTimerYieldState *ysp;
+ int res;
+
+ ysp = (ErtsBifTimerYieldState *) *vyspp;
+ if (!ysp)
+ ysp = &ys;
+
+ res = proc_btm_rbt_foreach_destroy_yielding(&ysp->bif_timers,
+ exit_cancel_bif_timer,
+ (void *) esdp,
+ &ysp->u.proc_btm_yield_state,
+ ERTS_BTM_MAX_DESTROY_LIMIT);
+
+ if (res == 0) {
+ if (ysp != &ys)
+ erts_free(ERTS_ALC_T_BTM_YIELD_STATE, ysp);
+ *vyspp = NULL;
+ }
+ else {
+
+ if (ysp == &ys) {
+ ysp = erts_alloc(ERTS_ALC_T_BTM_YIELD_STATE,
+ sizeof(ErtsBifTimerYieldState));
+ sys_memcpy((void *) ysp, (void *) &ys,
+ sizeof(ErtsBifTimerYieldState));
+ }
+
+ *vyspp = (void *) ysp;
+ }
+
+ return res;
+}
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+
+static void
+detach_bif_timer(ErtsHLTimer *tmr, void *vesdp)
+{
+ tmr->abtm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
+ hl_timer_dec_refc(tmr, tmr->head.roflgs);
+}
+
+int erts_detach_accessor_bif_timers(Process *p, ErtsBifTimers *btm, void **vyspp)
+{
+ ErtsSchedulerData *esdp = ERTS_PROC_GET_SCHDATA(p);
+ ErtsBifTimerYieldState ys = {btm, {ERTS_RBT_YIELD_STAT_INITER}};
+ ErtsBifTimerYieldState *ysp;
+ int res;
+
+ ysp = (ErtsBifTimerYieldState *) *vyspp;
+ if (!ysp)
+ ysp = &ys;
+
+ res = abtm_rbt_foreach_destroy_yielding(&ysp->bif_timers,
+ detach_bif_timer,
+ (void *) esdp,
+ &ysp->u.abtm_yield_state,
+ ERTS_BTM_MAX_DESTROY_LIMIT);
+
+ if (res == 0) {
+ if (ysp != &ys)
+ erts_free(ERTS_ALC_T_BTM_YIELD_STATE, ysp);
+ *vyspp = NULL;
+ }
+ else {
+
+ if (ysp == &ys) {
+ ysp = erts_alloc(ERTS_ALC_T_BTM_YIELD_STATE,
+ sizeof(ErtsBifTimerYieldState));
+ sys_memcpy((void *) ysp, (void *) &ys,
+ sizeof(ErtsBifTimerYieldState));
+ }
+
+ *vyspp = (void *) ysp;
+ }
+
+ return res;
+}
+
+#endif /* ERTS_BTM_ACCESSOR_SUPPORT */
+
+static ERTS_INLINE int
+parse_timeout_pos(ErtsSchedulerData *esdp, Eterm arg,
+ ErtsMonotonicTime *conv_arg, int abs,
+ ErtsMonotonicTime *tposp, int *stimep)
+{
+ ErtsMonotonicTime t;
+
+ if (!term_to_Sint64(arg, &t)) {
+ ERTS_HLT_ASSERT(!is_small(arg));
+ if (!is_big(arg))
+ return -1;
+
+ if (abs || !big_sign(arg))
+ return 1;
+
+ return -1;
+ }
+
+ if (conv_arg)
+ *conv_arg = t;
+
+ if (abs) {
+ t += -1*ERTS_MONOTONIC_OFFSET_MSEC; /* external to internal */
+ if (t < ERTS_MONOTONIC_TO_MSEC(ERTS_MONOTONIC_BEGIN))
+ return 1;
+ if (t > ERTS_MONOTONIC_TO_MSEC(ERTS_MONOTONIC_END))
+ return 1;
+ *stimep = (t - ERTS_MONOTONIC_TO_MSEC(esdp->last_monotonic_time)
+ < ERTS_BIF_TIMER_SHORT_TIME);
+ *tposp = ERTS_MSEC_TO_CLKTCKS(t);
+ }
+ else {
+ ErtsMonotonicTime now, ticks;
+
+ if (t < 0)
+ return -1;
+
+ ticks = ERTS_MSEC_TO_CLKTCKS(t);
+
+ if (ERTS_CLKTCK_RESOLUTION > 1000 && ticks < 0)
+ return 1;
+
+ ERTS_HLT_ASSERT(ticks >= 0);
+
+ now = erts_get_monotonic_time(esdp);
+ ticks += ERTS_MONOTONIC_TO_CLKTCKS(now-1);
+ ticks += 1;
+
+ if (ticks < ERTS_MONOTONIC_TO_CLKTCKS(ERTS_MONOTONIC_BEGIN))
+ return 1;
+ if (ticks > ERTS_MONOTONIC_TO_CLKTCKS(ERTS_MONOTONIC_END))
+ return 1;
+
+ *stimep = (t < ERTS_BIF_TIMER_SHORT_TIME);
+ *tposp = ticks;
+ }
+
+ return 0;
+}
+
+/*
+ *
+ * The BIF timer BIFs...
+ */
+
+BIF_RETTYPE send_after_3(BIF_ALIST_3)
+{
+ ErtsMonotonicTime timeout_pos;
+ int short_time, tres;
+
+ tres = parse_timeout_pos(ERTS_PROC_GET_SCHDATA(BIF_P), BIF_ARG_1, NULL,
+ 0, &timeout_pos, &short_time);
+ if (tres != 0)
+ BIF_ERROR(BIF_P, BADARG);
+
+ return setup_bif_timer(BIF_P, timeout_pos, short_time,
+ BIF_ARG_2, BIF_ARG_2, BIF_ARG_3, 0);
+}
+
+BIF_RETTYPE send_after_4(BIF_ALIST_4)
+{
+ ErtsMonotonicTime timeout_pos;
+ Eterm accessor;
+ int short_time, abs, tres;
+
+ if (!parse_bif_timer_options(BIF_ARG_4, NULL, NULL, &abs, &accessor))
+ BIF_ERROR(BIF_P, BADARG);
+
+ tres = parse_timeout_pos(ERTS_PROC_GET_SCHDATA(BIF_P), BIF_ARG_1, NULL,
+ abs, &timeout_pos, &short_time);
+ if (tres != 0)
+ BIF_ERROR(BIF_P, BADARG);
+
+ return setup_bif_timer(BIF_P, timeout_pos, short_time,
+ BIF_ARG_2, accessor, BIF_ARG_3, 0);
+}
+
+BIF_RETTYPE start_timer_3(BIF_ALIST_3)
+{
+ ErtsMonotonicTime timeout_pos;
+ int short_time, tres;
+
+ tres = parse_timeout_pos(ERTS_PROC_GET_SCHDATA(BIF_P), BIF_ARG_1, NULL,
+ 0, &timeout_pos, &short_time);
+ if (tres != 0)
+ BIF_ERROR(BIF_P, BADARG);
+
+ return setup_bif_timer(BIF_P, timeout_pos, short_time,
+ BIF_ARG_2, BIF_ARG_2, BIF_ARG_3, !0);
+}
+
+BIF_RETTYPE start_timer_4(BIF_ALIST_4)
+{
+ ErtsMonotonicTime timeout_pos;
+ Eterm accessor;
+ int short_time, abs, tres;
+
+ if (!parse_bif_timer_options(BIF_ARG_4, NULL, NULL, &abs, &accessor))
+ BIF_ERROR(BIF_P, BADARG);
+
+ tres = parse_timeout_pos(ERTS_PROC_GET_SCHDATA(BIF_P), BIF_ARG_1, NULL,
+ abs, &timeout_pos, &short_time);
+ if (tres != 0)
+ BIF_ERROR(BIF_P, BADARG);
+
+ return setup_bif_timer(BIF_P, timeout_pos, short_time,
+ BIF_ARG_2, accessor, BIF_ARG_3, !0);
+}
+
+BIF_RETTYPE cancel_timer_1(BIF_ALIST_1)
+{
+ return access_bif_timer(BIF_P, BIF_ARG_1, 1, 0, 1);
+}
+
+BIF_RETTYPE cancel_timer_2(BIF_ALIST_2)
+{
+ BIF_RETTYPE ret;
+ int async, info;
+
+ if (parse_bif_timer_options(BIF_ARG_2, &async, &info, NULL, NULL))
+ return access_bif_timer(BIF_P, BIF_ARG_1, 1, async, info);
+
+ ERTS_BIF_PREP_ERROR(ret, BIF_P, BADARG);
+ return ret;
+}
+
+BIF_RETTYPE read_timer_1(BIF_ALIST_1)
+{
+ return access_bif_timer(BIF_P, BIF_ARG_1, 0, 0, 1);
+}
+
+BIF_RETTYPE read_timer_2(BIF_ALIST_2)
+{
+ BIF_RETTYPE ret;
+ int async;
+
+ if (parse_bif_timer_options(BIF_ARG_2, &async, NULL, NULL, NULL))
+ return access_bif_timer(BIF_P, BIF_ARG_1, 0, async, 1);
+
+ ERTS_BIF_PREP_ERROR(ret, BIF_P, BADARG);
+ return ret;
+}
+
+static void
+start_callback_timer(ErtsSchedulerData *esdp,
+ int twt,
+ ErtsMonotonicTime timeout_pos,
+ void (*callback)(void *),
+ void *arg)
+
+{
+ if (twt)
+ create_tw_timer(esdp, ERTS_TMR_CALLBACK, NULL,
+ callback, arg, timeout_pos);
+ else
+ create_hl_timer(esdp, timeout_pos, 0,
+ ERTS_TMR_CALLBACK, NULL,
+ NIL, THE_NON_VALUE, NIL,
+ NULL, callback, arg);
+}
+
+typedef struct {
+ int twt;
+ ErtsMonotonicTime timeout_pos;
+ void (*callback)(void *);
+ void *arg;
+} ErtsStartCallbackTimerRequest;
+
+static void
+scheduled_start_callback_timer(void *vsctr)
+{
+ ErtsStartCallbackTimerRequest *sctr
+ = (ErtsStartCallbackTimerRequest *) vsctr;
+
+ start_callback_timer(erts_get_scheduler_data(),
+ sctr->twt,
+ sctr->timeout_pos,
+ sctr->callback,
+ sctr->arg);
+
+ erts_free(ERTS_ALC_T_TIMER_REQUEST, vsctr);
+}
+
+void
+erts_start_timer_callback(ErtsMonotonicTime tmo,
+ void (*callback)(void *),
+ void *arg)
+{
+ ErtsSchedulerData *esdp;
+ ErtsMonotonicTime timeout_pos;
+ int twt;
+
+ esdp = erts_get_scheduler_data();
+ timeout_pos = get_timeout_pos(erts_get_monotonic_time(esdp),
+ tmo);
+ twt = tmo < ERTS_TIMER_WHEEL_MSEC;
+
+ if (esdp)
+ start_callback_timer(esdp,
+ twt,
+ timeout_pos,
+ callback,
+ arg);
+ else {
+ ErtsStartCallbackTimerRequest *sctr;
+ sctr = erts_alloc(ERTS_ALC_T_TIMER_REQUEST,
+ sizeof(ErtsStartCallbackTimerRequest));
+ sctr->twt = twt;
+ sctr->timeout_pos = timeout_pos;
+ sctr->callback = callback;
+ sctr->arg = arg;
+ erts_schedule_misc_aux_work(1,
+ scheduled_start_callback_timer,
+ (void *) sctr);
+ }
+}
+
+/*
+ * Process and Port timer functionality.
+ *
+ * NOTE! These are only allowed to be called by a
+ * scheduler thread that currently is
+ * executing the process or port.
+ */
+
+static ERTS_INLINE void
+set_proc_timer_common(Process *c_p, ErtsSchedulerData *esdp, Sint64 tmo,
+ ErtsMonotonicTime timeout_pos, int short_time)
+{
+ void *tmr;
+ check_canceled_queue(esdp, esdp->timer_service);
+
+ if (tmo == 0)
+ c_p->flags |= F_TIMO;
+ else {
+
+ c_p->flags |= F_INSLPQUEUE;
+ c_p->flags &= ~F_TIMO;
+
+ if (tmo < ERTS_TIMER_WHEEL_MSEC)
+ tmr = (void *) create_tw_timer(esdp, ERTS_TMR_PROC, (void *) c_p,
+ NULL, NULL, timeout_pos);
+ else
+ tmr = (void *) create_hl_timer(esdp, timeout_pos, short_time,
+ ERTS_TMR_PROC, (void *) c_p,
+ c_p->common.id, THE_NON_VALUE,
+ NIL, NULL, NULL, NULL);
+ erts_smp_atomic_set_relb(&c_p->common.timer, (erts_aint_t) tmr);
+ }
+}
+
+int
+erts_set_proc_timer_term(Process *c_p, Eterm etmo)
+{
+ ErtsSchedulerData *esdp = ERTS_PROC_GET_SCHDATA(c_p);
+ ErtsMonotonicTime tmo, timeout_pos;
+ int short_time, tres;
+
+ ERTS_HLT_ASSERT(erts_smp_atomic_read_nob(&c_p->common.timer)
+ == ERTS_PTMR_NONE);
+
+ tres = parse_timeout_pos(esdp, etmo, &tmo, 0,
+ &timeout_pos, &short_time);
+ if (tres != 0)
+ return tres;
+
+ if ((tmo >> 32) != 0)
+ return 1;
+
+ set_proc_timer_common(c_p, esdp, tmo, timeout_pos, short_time);
+ return 0;
+}
+
+void
+erts_set_proc_timer_uword(Process *c_p, UWord tmo)
+{
+ ErtsSchedulerData *esdp = ERTS_PROC_GET_SCHDATA(c_p);
+
+ ERTS_HLT_ASSERT(erts_smp_atomic_read_nob(&c_p->common.timer)
+ == ERTS_PTMR_NONE);
+
+#ifndef ARCH_32
+ ERTS_HLT_ASSERT((tmo >> 32) == (UWord) 0);
+#endif
+
+ if (tmo == 0)
+ c_p->flags |= F_TIMO;
+ else {
+ ErtsMonotonicTime timeout_pos;
+ timeout_pos = get_timeout_pos(erts_get_monotonic_time(esdp),
+ (ErtsMonotonicTime) tmo);
+ set_proc_timer_common(c_p, esdp, (ErtsMonotonicTime) tmo,
+ timeout_pos,
+ tmo < ERTS_BIF_TIMER_SHORT_TIME);
+ }
+}
+
+void
+erts_cancel_proc_timer(Process *c_p)
+{
+ erts_aint_t tval;
+ tval = erts_smp_atomic_xchg_acqb(&c_p->common.timer,
+ ERTS_PTMR_NONE);
+ c_p->flags &= ~(F_INSLPQUEUE|F_TIMO);
+ if (tval == ERTS_PTMR_NONE)
+ return;
+ if (tval == ERTS_PTMR_TIMEDOUT) {
+ erts_smp_atomic_set_nob(&c_p->common.timer, ERTS_PTMR_NONE);
+ return;
+ }
+ continue_cancel_ptimer(ERTS_PROC_GET_SCHDATA(c_p),
+ (ErtsTimer *) tval);
+}
+
+void
+erts_set_port_timer(Port *c_prt, Sint64 tmo)
+{
+ void *tmr;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ ErtsMonotonicTime timeout_pos;
+
+ if (erts_smp_atomic_read_nob(&c_prt->common.timer) != ERTS_PTMR_NONE)
+ erts_cancel_port_timer(c_prt);
+
+ check_canceled_queue(esdp, esdp->timer_service);
+
+ timeout_pos = get_timeout_pos(erts_get_monotonic_time(esdp), tmo);
+
+ if (tmo < ERTS_TIMER_WHEEL_MSEC)
+ tmr = (void *) create_tw_timer(esdp, ERTS_TMR_PORT, (void *) c_prt,
+ NULL, NULL, timeout_pos);
+ else
+ tmr = (void *) create_hl_timer(esdp, timeout_pos, 0, ERTS_TMR_PORT,
+ (void *) c_prt, c_prt->common.id,
+ THE_NON_VALUE, NIL, NULL, NULL, NULL);
+ erts_smp_atomic_set_relb(&c_prt->common.timer, (erts_aint_t) tmr);
+}
+
+void
+erts_cancel_port_timer(Port *c_prt)
+{
+ erts_aint_t tval;
+ tval = erts_smp_atomic_xchg_acqb(&c_prt->common.timer,
+ ERTS_PTMR_NONE);
+ if (tval == ERTS_PTMR_NONE)
+ return;
+ if (tval == ERTS_PTMR_TIMEDOUT) {
+ while (!erts_port_task_is_scheduled(&c_prt->timeout_task))
+ erts_thr_yield();
+ erts_port_task_abort(&c_prt->timeout_task);
+ erts_smp_atomic_set_nob(&c_prt->common.timer, ERTS_PTMR_NONE);
+ return;
+ }
+ continue_cancel_ptimer(erts_get_scheduler_data(),
+ (ErtsTimer *) tval);
+}
+
+Sint64
+erts_read_port_timer(Port *c_prt)
+{
+ ErtsTimer *tmr;
+ erts_aint_t itmr;
+ ErtsMonotonicTime timeout_pos;
+
+ itmr = erts_smp_atomic_read_acqb(&c_prt->common.timer);
+ if (itmr == ERTS_PTMR_NONE)
+ return (Sint64) -1;
+ if (itmr == ERTS_PTMR_TIMEDOUT)
+ return (Sint64) 0;
+ tmr = (ErtsTimer *) itmr;
+ if (tmr->head.roflgs & ERTS_TMR_ROFLG_HLT)
+ timeout_pos = tmr->hlt.timeout;
+ else
+ timeout_pos = tmr->twt.tw_tmr.timeout_pos;
+ return get_time_left(NULL, timeout_pos);
+}
+
+/*
+ * Debug stuff...
+ */
+
+typedef struct {
+ int to;
+ void *to_arg;
+ ErtsMonotonicTime now;
+} ErtsBTMPrint;
+
+static void
+btm_print(ErtsHLTimer *tmr, void *vbtmp)
+{
+ ErtsBTMPrint *btmp = (ErtsBTMPrint *) vbtmp;
+ ErtsMonotonicTime left;
+ Eterm receiver;
+
+ if (tmr->timeout <= btmp->now)
+ left = 0;
+ left = ERTS_CLKTCKS_TO_MSEC(tmr->timeout - btmp->now);
+
+ receiver = ((tmr->head.roflgs & ERTS_TMR_ROFLG_REG_NAME)
+ ? tmr->receiver.name
+ : tmr->receiver.proc->common.id);
+
+ erts_print(btmp->to, btmp->to_arg,
+ "=timer:%T\n"
+ "Message: %T\n"
+ "Time left: %b64d\n",
+ receiver,
+ tmr->btm.message,
+ (Sint64) left);
+}
+
+void
+erts_print_bif_timer_info(int to, void *to_arg)
+{
+ ErtsBTMPrint btmp;
+ int six;
+
+ if (!ERTS_IS_CRASH_DUMPING)
+ ERTS_INTERNAL_ERROR("Not crash dumping");
+
+ btmp.to = to;
+ btmp.to_arg = to_arg;
+ btmp.now = erts_get_monotonic_time(NULL);
+ btmp.now = ERTS_MONOTONIC_TO_CLKTCKS(btmp.now);
+
+ for (six = 0; six < erts_no_schedulers; six++) {
+ ErtsHLTimerService *srv =
+ erts_aligned_scheduler_data[six].esd.timer_service;
+ btm_rbt_foreach(srv->btm_tree, btm_print, (void *) &btmp);
+ }
+}
+
+typedef struct {
+ void (*func)(Eterm,
+ Eterm,
+ ErlHeapFragment *,
+ void *);
+ void *arg;
+} ErtsBTMForeachDebug;
+
+static void
+debug_btm_foreach(ErtsHLTimer *tmr, void *vbtmfd)
+{
+ if (erts_smp_atomic32_read_nob(&tmr->state) == ERTS_TMR_STATE_ACTIVE) {
+ ErtsBTMForeachDebug *btmfd = (ErtsBTMForeachDebug *) vbtmfd;
+ (*btmfd->func)(((tmr->head.roflgs & ERTS_TMR_ROFLG_REG_NAME)
+ ? tmr->receiver.name
+ : tmr->receiver.proc->common.id),
+ tmr->btm.message,
+ tmr->btm.bp,
+ btmfd->arg);
+ }
+}
+
+void
+erts_debug_bif_timer_foreach(void (*func)(Eterm,
+ Eterm,
+ ErlHeapFragment *,
+ void *),
+ void *arg)
+{
+ ErtsBTMForeachDebug btmfd;
+ int six;
+
+ btmfd.func = func;
+ btmfd.arg = arg;
+
+ if (!erts_smp_thr_progress_is_blocking())
+ ERTS_INTERNAL_ERROR("Not blocking thread progress");
+
+ for (six = 0; six < erts_no_schedulers; six++) {
+ ErtsHLTimerService *srv =
+ erts_aligned_scheduler_data[six].esd.timer_service;
+ btm_rbt_foreach(srv->btm_tree,
+ debug_btm_foreach,
+ (void *) &btmfd);
+ }
+}
+
+typedef struct {
+ void (*tclbk)(void *);
+ void (*func)(void *,
+ ErtsMonotonicTime,
+ void *);
+ void *arg;
+} ErtsDebugForeachCallbackTimer;
+
+static void
+debug_callback_timer_foreach_list(ErtsHLTimer *tmr, void *vdfct)
+{
+ ErtsDebugForeachCallbackTimer *dfct
+ = (ErtsDebugForeachCallbackTimer *) vdfct;
+
+ if ((tmr->head.roflgs & ERTS_TMR_ROFLG_CALLBACK)
+ && (tmr->receiver.callback == dfct->tclbk))
+ (*dfct->func)(dfct->arg,
+ tmr->timeout,
+ tmr->head.u.arg);
+}
+
+static void
+debug_callback_timer_foreach(ErtsHLTimer *tmr, void *vdfct)
+{
+ ErtsDebugForeachCallbackTimer *dfct
+ = (ErtsDebugForeachCallbackTimer *) vdfct;
+
+ if (tmr->time.tree.same_time)
+ same_time_list_foreach(tmr->time.tree.same_time,
+ debug_callback_timer_foreach_list,
+ vdfct);
+
+ if ((tmr->head.roflgs & ERTS_TMR_ROFLG_CALLBACK)
+ && (tmr->receiver.callback == dfct->tclbk))
+ (*dfct->func)(dfct->arg,
+ tmr->timeout,
+ tmr->head.u.arg);
+}
+
+static void
+debug_tw_callback_timer(void *vdfct,
+ ErtsMonotonicTime timeout_pos,
+ void *vtwtp)
+{
+ ErtsTWTimer *twtp = (ErtsTWTimer *) vtwtp;
+ ErtsDebugForeachCallbackTimer *dfct
+ = (ErtsDebugForeachCallbackTimer *) vdfct;
+
+ if (twtp->u.callback == dfct->tclbk)
+ (*dfct->func)(dfct->arg,
+ timeout_pos,
+ twtp->head.u.arg);
+}
+
+void
+erts_debug_callback_timer_foreach(void (*tclbk)(void *),
+ void (*func)(void *,
+ ErtsMonotonicTime,
+ void *),
+ void *arg)
+{
+ int six;
+ ErtsDebugForeachCallbackTimer dfct;
+
+ dfct.tclbk = tclbk;
+ dfct.func = func;
+ dfct.arg = arg;
+
+ if (!erts_smp_thr_progress_is_blocking())
+ ERTS_INTERNAL_ERROR("Not blocking thread progress");
+
+ for (six = 0; six < erts_no_schedulers; six++) {
+ ErtsHLTimerService *srv =
+ erts_aligned_scheduler_data[six].esd.timer_service;
+ ErtsTimerWheel *twheel =
+ erts_aligned_scheduler_data[six].esd.timer_wheel;
+
+ erts_twheel_debug_foreach(twheel,
+ tw_callback_timeout,
+ debug_tw_callback_timer,
+ (void *) &dfct);
+
+ if (srv->yield.root)
+ debug_callback_timer_foreach(srv->yield.root,
+ (void *) &dfct);
+
+ time_rbt_foreach(srv->time_tree,
+ debug_callback_timer_foreach,
+ (void *) &dfct);
+ }
+}
+
+#ifdef ERTS_HLT_HARD_DEBUG
+
+typedef struct {
+ ErtsHLTimerService *srv;
+ int found_root;
+ ErtsHLTimer **rootpp;
+} ErtsHdbgHLT;
+
+static void
+st_hdbg_func(ErtsHLTimer *tmr, void *vhdbg)
+{
+ ErtsHdbgHLT *hdbg = (ErtsHdbgHLT *) vhdbg;
+ ErtsHLTimer **rootpp;
+ ERTS_HLT_ASSERT(tmr->time.tree.parent & ERTS_HLT_PFLG_SAME_TIME);
+ if (tmr->time.tree.parent == ERTS_HLT_PFLG_SAME_TIME) {
+ ERTS_HLT_ASSERT(tmr != *hdbg->rootpp);
+ }
+ else {
+ rootpp = (ErtsHLTimer **) (tmr->time.tree.parent
+ & ~ERTS_HLT_PFLG_SAME_TIME);
+ ERTS_HLT_ASSERT(rootpp == hdbg->rootpp);
+ ERTS_HLT_ASSERT(tmr == *rootpp);
+ ERTS_HLT_ASSERT(!hdbg->found_root);
+ hdbg->found_root = 1;
+ }
+ ERTS_HLT_ASSERT(tmr->time.tree.u.l.next->time.tree.u.l.prev == tmr);
+ ERTS_HLT_ASSERT(tmr->time.tree.u.l.prev->time.tree.u.l.next == tmr);
+ ERTS_HLT_ASSERT(btm_rbt_lookup(hdbg->srv->btm_tree, tmr->btm.refn) == tmr);
+}
+
+static void
+tt_hdbg_func(ErtsHLTimer *tmr, void *vhdbg)
+{
+ ErtsHdbgHLT *hdbg = (ErtsHdbgHLT *) vhdbg;
+ ErtsHLTimer *prnt;
+ ERTS_HLT_ASSERT((tmr->time.tree.parent & ERTS_HLT_PFLG_SAME_TIME) == 0);
+ prnt = (ErtsHLTimer *) (tmr->time.tree.parent & ~ERTS_HLT_PFLGS_MASK);
+ if (prnt) {
+ ERTS_HLT_ASSERT(prnt->time.tree.u.t.left == tmr
+ || prnt->time.tree.u.t.right == tmr);
+ }
+ else {
+ ERTS_HLT_ASSERT(!hdbg->found_root);
+ hdbg->found_root = 1;
+ ERTS_HLT_ASSERT(tmr == *hdbg->rootpp);
+ }
+ if (tmr->time.tree.u.t.left) {
+ prnt = (ErtsHLTimer *) (tmr->time.tree.u.t.left->time.tree.parent
+ & ~ERTS_HLT_PFLGS_MASK);
+ ERTS_HLT_ASSERT(tmr == prnt);
+ }
+ if (tmr->time.tree.u.t.right) {
+ prnt = (ErtsHLTimer *) (tmr->time.tree.u.t.right->time.tree.parent
+ & ~ERTS_HLT_PFLGS_MASK);
+ ERTS_HLT_ASSERT(tmr == prnt);
+ }
+ if (tmr->head.roflgs & ERTS_TMR_ROFLG_BIF_TMR)
+ ERTS_HLT_ASSERT(btm_rbt_lookup(hdbg->srv->btm_tree, tmr->btm.refn) == tmr);
+ if (tmr->time.tree.same_time) {
+ ErtsHdbgHLT st_hdbg;
+ st_hdbg.srv = hdbg->srv;
+ st_hdbg.found_root = 0;
+ st_hdbg.rootpp = &tmr->time.tree.same_time;
+ same_time_list_foreach(tmr->time.tree.same_time, st_hdbg_func, (void *) &st_hdbg);
+ ERTS_HLT_ASSERT(st_hdbg.found_root);
+ }
+}
+
+static void
+bt_hdbg_func(ErtsHLTimer *tmr, void *vhdbg)
+{
+ ErtsHdbgHLT *hdbg = (ErtsHdbgHLT *) vhdbg;
+ ErtsHLTimer *prnt;
+ ERTS_HLT_ASSERT((tmr->btm.tree.parent & ERTS_HLT_PFLG_SAME_TIME) == 0);
+ prnt = (ErtsHLTimer *) (tmr->btm.tree.parent & ~ERTS_HLT_PFLGS_MASK);
+ if (prnt) {
+ ERTS_HLT_ASSERT(prnt->btm.tree.left == tmr
+ || prnt->btm.tree.right == tmr);
+ }
+ else {
+ ERTS_HLT_ASSERT(!hdbg->found_root);
+ hdbg->found_root = 1;
+ ERTS_HLT_ASSERT(tmr == *hdbg->rootpp);
+ }
+ if (tmr->btm.tree.left) {
+ prnt = (ErtsHLTimer *) (tmr->btm.tree.left->btm.tree.parent
+ & ~ERTS_HLT_PFLGS_MASK);
+ ERTS_HLT_ASSERT(tmr == prnt);
+ }
+ if (tmr->btm.tree.right) {
+ prnt = (ErtsHLTimer *) (tmr->btm.tree.right->btm.tree.parent
+ & ~ERTS_HLT_PFLGS_MASK);
+ ERTS_HLT_ASSERT(tmr == prnt);
+ }
+ if (tmr->pending_timeout) {
+ if (tmr->pending_timeout > 0) /* container > 0 */
+ ERTS_HLT_ASSERT(tmr->time.tree.parent == ERTS_HLT_PFIELD_NOT_IN_TABLE);
+ else {
+ ERTS_HLT_ASSERT(tmr->time.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE);
+ ERTS_HLT_ASSERT(tmr->time.tree.parent & ERTS_HLT_PFLG_SAME_TIME);
+ }
+ }
+ else {
+ ErtsHLTimer *ttmr = time_rbt_lookup(hdbg->srv->time_tree, tmr->timeout);
+ ERTS_HLT_ASSERT(ttmr);
+ if (ttmr != tmr) {
+ ERTS_HLT_ASSERT(ttmr->time.tree.same_time);
+ ERTS_HLT_ASSERT(tmr == same_time_list_lookup(ttmr->time.tree.same_time, tmr));
+ }
+ }
+}
+
+static void
+hdbg_chk_srv(ErtsHLTimerService *srv)
+{
+ if (srv->time_tree) {
+ ErtsHdbgHLT hdbg;
+ hdbg.srv = srv;
+ hdbg.found_root = 0;
+ hdbg.rootpp = &srv->time_tree;
+ time_rbt_foreach(srv->time_tree, tt_hdbg_func, (void *) &hdbg);
+ ERTS_HLT_ASSERT(hdbg.found_root);
+ }
+ if (srv->btm_tree) {
+ ErtsHdbgHLT hdbg;
+ hdbg.srv = srv;
+ hdbg.found_root = 0;
+ hdbg.rootpp = &srv->btm_tree;
+ btm_rbt_foreach(srv->btm_tree, bt_hdbg_func, (void *) &hdbg);
+ ERTS_HLT_ASSERT(hdbg.found_root);
+ }
+}
+
+#endif /* ERTS_HLT_HARD_DEBUG */
diff --git a/erts/emulator/beam/erl_hl_timer.h b/erts/emulator/beam/erl_hl_timer.h
new file mode 100644
index 0000000000..0931bb8965
--- /dev/null
+++ b/erts/emulator/beam/erl_hl_timer.h
@@ -0,0 +1,88 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifndef ERL_HL_TIMER_H__
+#define ERL_HL_TIMER_H__
+
+typedef struct ErtsHLTimer_ ErtsBifTimers;
+typedef struct ErtsHLTimerService_ ErtsHLTimerService;
+
+#include "sys.h"
+#include "erl_process.h"
+#define ERL_PORT_GET_PORT_TYPE_ONLY__
+#include "erl_port.h"
+#undef ERL_PORT_GET_PORT_TYPE_ONLY__
+#include "erl_message.h"
+#include "erl_alloc_types.h"
+
+#define ERTS_PTMR_NONE ((erts_aint_t) NULL)
+#define ERTS_PTMR_TIMEDOUT (ERTS_PTMR_NONE + ((erts_aint_t) 1))
+
+#define ERTS_PTMR_INIT(P) \
+ erts_smp_atomic_init_nob(&(P)->common.timer, ERTS_PTMR_NONE)
+#define ERTS_PTMR_IS_SET(P) \
+ (ERTS_PTMR_NONE != erts_smp_atomic_read_nob(&(P)->common.timer))
+#define ERTS_PTMR_IS_TIMED_OUT(P) \
+ (ERTS_PTMR_TIMEDOUT == erts_smp_atomic_read_nob(&(P)->common.timer))
+
+#define ERTS_PTMR_CLEAR(P) \
+ do { \
+ ASSERT(ERTS_PTMR_IS_TIMED_OUT((P))); \
+ erts_smp_atomic_set_nob(&(P)->common.timer, \
+ ERTS_PTMR_NONE); \
+ } while (0)
+
+size_t erts_timer_type_size(ErtsAlcType_t type);
+int erts_set_proc_timer_term(Process *, Eterm);
+void erts_set_proc_timer_uword(Process *, UWord);
+void erts_cancel_proc_timer(Process *);
+void erts_set_port_timer(Port *, Sint64);
+void erts_cancel_port_timer(Port *);
+Sint64 erts_read_port_timer(Port *);
+int erts_cancel_bif_timers(Process *, ErtsBifTimers *, void **);
+int erts_detach_accessor_bif_timers(Process *, ErtsBifTimers *, void **);
+ErtsHLTimerService *erts_create_timer_service(void);
+void erts_hl_timer_init(void);
+void erts_start_timer_callback(ErtsMonotonicTime,
+ void (*)(void *),
+ void *);
+#ifdef ERTS_SMP
+void
+erts_handle_canceled_timers(void *vesdp,
+ int *need_thr_progress,
+ ErtsThrPrgrVal *thr_prgr_p,
+ int *need_more_work);
+#endif
+
+Uint erts_bif_timer_memory_size(void);
+void erts_print_bif_timer_info(int to, void *to_arg);
+
+void erts_debug_bif_timer_foreach(void (*func)(Eterm,
+ Eterm,
+ ErlHeapFragment *,
+ void *),
+ void *arg);
+void
+erts_debug_callback_timer_foreach(void (*tclbk)(void *),
+ void (*func)(void *,
+ ErtsMonotonicTime,
+ void *),
+ void *arg);
+#endif /* ERL_HL_TIMER_H__ */
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 743fd235bc..e729574ec7 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -35,7 +36,7 @@
#include "dist.h"
#include "erl_mseg.h"
#include "erl_threads.h"
-#include "erl_bif_timer.h"
+#include "erl_hl_timer.h"
#include "erl_instrument.h"
#include "erl_printf_term.h"
#include "erl_misc_utils.h"
@@ -45,6 +46,9 @@
#include "erl_thr_queue.h"
#include "erl_async.h"
#include "erl_ptab.h"
+#include "erl_bif_unique.h"
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
#ifdef HIPE
#include "hipe_mode_switch.h" /* for hipe_mode_switch_init() */
@@ -117,6 +121,8 @@ const int etp_big_endian = 1;
#else
const int etp_big_endian = 0;
#endif
+const Eterm etp_the_non_value = THE_NON_VALUE;
+
/*
* Note about VxWorks: All variables must be initialized by executable code,
* not by an initializer. Otherwise a new instance of the emulator will
@@ -134,7 +140,11 @@ static void erl_init(int ncpu,
int legacy_proc_tab,
int port_tab_sz,
int port_tab_sz_ignore_files,
- int legacy_port_tab);
+ int legacy_port_tab,
+ int time_correction,
+ ErtsTimeWarpMode time_warp_mode,
+ int node_tab_delete_delay,
+ ErtsDbSpinCount db_spin_count);
static erts_atomic_t exiting;
@@ -161,9 +171,6 @@ int H_MIN_SIZE; /* The minimum heap grain */
int BIN_VH_MIN_SIZE; /* The minimum binary virtual*/
Uint32 erts_debug_flags; /* Debug flags. */
-#ifdef ERTS_OPCODE_COUNTER_SUPPORT
-int count_instructions;
-#endif
int erts_backtrace_depth; /* How many functions to show in a backtrace
* in error codes.
*/
@@ -188,10 +195,6 @@ static int no_dirty_io_schedulers;
Uint32 verbose; /* See erl_debug.h for information about verbose */
#endif
-int erts_disable_tolerant_timeofday; /* Time correction can be disabled it is
- * not and/or it is too slow.
- */
-
int erts_atom_table_size = ATOM_LIMIT; /* Maximum number of atoms */
int erts_pd_initial_size = 10;
@@ -266,11 +269,24 @@ this_rel_num(void)
i++;
this_rel = atoi(&this_rel_str[i]);
if (this_rel < 1)
- erl_exit(-1, "Unexpected ERLANG_OTP_RELEASE format\n");
+ erts_exit(1, "Unexpected ERLANG_OTP_RELEASE format\n");
}
return this_rel;
}
+static ERTS_INLINE void
+set_default_time_adj(int *time_correction_p, ErtsTimeWarpMode *time_warp_mode_p)
+{
+ *time_correction_p = 1;
+ *time_warp_mode_p = ERTS_NO_TIME_WARP_MODE;
+ if (!erts_check_time_adj_support(*time_correction_p,
+ *time_warp_mode_p)) {
+ *time_correction_p = 0;
+ ASSERT(erts_check_time_adj_support(*time_correction_p,
+ *time_warp_mode_p));
+ }
+}
+
/*
* Common error printout function, all error messages
* that don't go to the error logger go through here.
@@ -286,13 +302,24 @@ static int early_init(int *argc, char **argv);
void
erts_short_init(void)
{
- int ncpu = early_init(NULL, NULL);
+
+ int ncpu;
+ int time_correction;
+ ErtsTimeWarpMode time_warp_mode;
+
+ set_default_time_adj(&time_correction,
+ &time_warp_mode);
+ ncpu = early_init(NULL, NULL);
erl_init(ncpu,
ERTS_DEFAULT_MAX_PROCESSES,
0,
ERTS_DEFAULT_MAX_PORTS,
0,
- 0);
+ 0,
+ time_correction,
+ time_warp_mode,
+ ERTS_NODE_TAB_DELAY_GC_DEFAULT,
+ ERTS_DB_SPNCNT_NORMAL);
erts_initialized = 1;
}
@@ -302,12 +329,17 @@ erl_init(int ncpu,
int legacy_proc_tab,
int port_tab_sz,
int port_tab_sz_ignore_files,
- int legacy_port_tab)
+ int legacy_port_tab,
+ int time_correction,
+ ErtsTimeWarpMode time_warp_mode,
+ int node_tab_delete_delay,
+ ErtsDbSpinCount db_spin_count)
{
init_benchmarking();
+ erts_bif_unique_init();
erts_init_monitors();
- erts_init_time();
+ erts_init_time(time_correction, time_warp_mode);
erts_init_sys_common_misc();
erts_init_process(ncpu, proc_tab_sz, legacy_proc_tab);
erts_init_scheduling(no_schedulers,
@@ -318,6 +350,7 @@ erl_init(int ncpu,
no_dirty_io_schedulers
#endif
);
+ erts_late_init_time_sup();
erts_init_cpu_topology(); /* Must be after init_scheduling */
erts_init_gc(); /* Must be after init_scheduling */
erts_alloc_late_init();
@@ -340,9 +373,8 @@ erl_init(int ncpu,
erts_ptab_init(); /* Must be after init_emulator() */
erts_init_binary(); /* Must be after init_emulator() */
erts_bp_init();
- init_db(); /* Must be after init_emulator */
- erts_bif_timer_init();
- erts_init_node_tables();
+ init_db(db_spin_count); /* Must be after init_emulator */
+ erts_init_node_tables(node_tab_delete_delay);
init_dist();
erl_drv_thr_init();
erts_init_async();
@@ -354,6 +386,7 @@ erl_init(int ncpu,
erts_init_bif_re();
erts_init_unicode(); /* after RE to get access to PCRE unicode */
erts_init_external();
+ erts_init_map();
erts_delay_trap = erts_export_put(am_erlang, am_delay_trap, 2);
erts_late_init_process();
#if HAVE_ERTS_MSEG
@@ -367,12 +400,13 @@ erl_init(int ncpu,
erl_nif_init();
}
-static void
+static Eterm
erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char** argv)
{
int i;
Eterm start_mod;
Eterm args;
+ Eterm res;
Eterm* hp;
Process parent;
ErlSpawnOpts so;
@@ -381,7 +415,7 @@ erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char**
start_mod = erts_atom_put((byte *) modname, sys_strlen(modname), ERTS_ATOM_ENC_LATIN1, 1);
if (erts_find_function(start_mod, am_start, 2,
erts_active_code_ix()) == NULL) {
- erl_exit(5, "No function %s:start/2\n", modname);
+ erts_exit(ERTS_ERROR_EXIT, "No function %s:start/2\n", modname);
}
/*
@@ -402,10 +436,11 @@ erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char**
hp += 2;
args = CONS(hp, env, args);
- so.flags = 0;
- (void) erl_create_process(&parent, start_mod, am_start, args, &so);
+ so.flags = SPO_SYSTEM_PROC;
+ res = erl_create_process(&parent, start_mod, am_start, args, &so);
erts_smp_proc_unlock(&parent, ERTS_PROC_LOCK_MAIN);
erts_cleanup_empty_process(&parent);
+ return res;
}
Eterm
@@ -477,12 +512,12 @@ load_preloaded(void)
length = preload_p[i].size;
module_name = erts_atom_put((byte *) name, sys_strlen(name), ERTS_ATOM_ENC_LATIN1, 1);
if ((code = sys_preload_begin(&preload_p[i])) == 0)
- erl_exit(1, "Failed to find preloaded code for module %s\n",
+ erts_exit(ERTS_ERROR_EXIT, "Failed to find preloaded code for module %s\n",
name);
res = erts_preload_module(NULL, 0, NIL, &module_name, code, length);
sys_preload_end(&preload_p[i]);
if (res != NIL)
- erl_exit(1,"Failed loading preloaded module %s (%T)\n",
+ erts_exit(ERTS_ERROR_EXIT,"Failed loading preloaded module %s (%T)\n",
name, res);
i++;
}
@@ -511,9 +546,9 @@ void erts_usage(void)
/* erts_fprintf(stderr, "-b func set the boot function (default boot)\n"); */
- erts_fprintf(stderr, "-c disable continuous date/time correction with\n");
- erts_fprintf(stderr, " respect to uptime\n");
-
+ erts_fprintf(stderr, "-c bool enable or disable time correction\n");
+ erts_fprintf(stderr, "-C mode set time warp mode; valid modes are:\n");
+ erts_fprintf(stderr, " no_time_warp|single_time_warp|multi_time_warp\n");
erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n");
erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n");
erts_fprintf(stderr, "-fn[u|a|l] Control how filenames are interpreted\n");
@@ -598,15 +633,22 @@ void erts_usage(void)
erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n");
- erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n");
+ erts_fprintf(stderr, "-W<i|w|e> set error logger warnings mapping,\n");
erts_fprintf(stderr, " see error_logger documentation for details\n");
erts_fprintf(stderr, "-zdbbl size set the distribution buffer busy limit in kilobytes\n");
erts_fprintf(stderr, " valid range is [1-%d]\n", INT_MAX/1024);
+ erts_fprintf(stderr, "-zdntgc time set delayed node table gc in seconds\n");
+ erts_fprintf(stderr, " valid values are infinity or intergers in the range [0-%d]\n",
+ ERTS_NODE_TAB_DELAY_GC_MAX);
+#if 0
+ erts_fprintf(stderr, "-zebwt val set ets busy wait threshold, valid values are:\n");
+ erts_fprintf(stderr, " none|very_short|short|medium|long|very_long|extremely_long\n");
+#endif
erts_fprintf(stderr, "\n");
erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n");
erts_fprintf(stderr, "from the erl script), these flags should be specified with +.\n");
erts_fprintf(stderr, "\n\n");
- erl_exit(-1, "");
+ erts_exit(1, "");
}
#ifdef USE_THREADS
@@ -685,7 +727,6 @@ early_init(int *argc, char **argv) /*
erts_sched_compact_load = 1;
erts_printf_eterm_func = erts_printf_term;
- erts_disable_tolerant_timeofday = 0;
display_items = 200;
erts_backtrace_depth = DEFAULT_BACKTRACE_SIZE;
erts_async_max_threads = ERTS_DEFAULT_NO_ASYNC_THREADS;
@@ -1191,7 +1232,13 @@ erl_start(int argc, char **argv)
int port_tab_sz_ignore_files = 0;
int legacy_proc_tab = 0;
int legacy_port_tab = 0;
+ int time_correction;
+ ErtsTimeWarpMode time_warp_mode;
+ int node_tab_delete_delay = ERTS_NODE_TAB_DELAY_GC_DEFAULT;
+ ErtsDbSpinCount db_spin_count = ERTS_DB_SPNCNT_NORMAL;
+ set_default_time_adj(&time_correction,
+ &time_warp_mode);
envbufsz = sizeof(envbuf);
if (erts_sys_getenv_raw(ERL_MAX_ETS_TABLES_ENV, envbuf, &envbufsz) == 0)
@@ -1223,7 +1270,7 @@ erl_start(int argc, char **argv)
verbose = DEBUG_DEFAULT;
#endif
- erts_error_logger_warnings = am_error;
+ erts_error_logger_warnings = am_warning;
while (i < argc) {
if (argv[i][0] != '-') {
@@ -1398,7 +1445,7 @@ erl_start(int argc, char **argv)
}
erts_fprintf(stderr, "(" EMULATOR ") emulator version "
ERLANG_VERSION "\n");
- erl_exit(0, "");
+ erts_exit(0, "");
}
break;
@@ -1909,15 +1956,51 @@ erl_start(int argc, char **argv)
}
break;
}
+ case 'C':
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ if (sys_strcmp(arg, "no_time_warp") == 0)
+ time_warp_mode = ERTS_NO_TIME_WARP_MODE;
+ else if (sys_strcmp(arg, "single_time_warp") == 0)
+ time_warp_mode = ERTS_SINGLE_TIME_WARP_MODE;
+ else if (sys_strcmp(arg, "multi_time_warp") == 0)
+ time_warp_mode = ERTS_MULTI_TIME_WARP_MODE;
+ else {
+ erts_fprintf(stderr,
+ "Invalid time warp mode: %s\n", arg);
+ erts_usage();
+ }
+ break;
case 'c':
- if (argv[i][2] == 0) { /* -c: documented option */
- erts_disable_tolerant_timeofday = 1;
+ if (sys_strcmp(argv[i]+2, "false") == 0)
+ goto time_correction_false;
+ else if (sys_strcmp(argv[i]+2, "true") == 0)
+ goto time_correction_true;
+ else if (argv[i][2] == '\0') {
+ if (i + 1 >= argc)
+ goto time_correction_false;
+ else {
+ if (sys_strcmp(argv[i+1], "false") == 0) {
+ (void) get_arg(argv[i]+2, argv[i+1], &i);
+ goto time_correction_false;
+ }
+ else if (sys_strcmp(argv[i+1], "true") == 0) {
+ (void) get_arg(argv[i]+2, argv[i+1], &i);
+ time_correction_true:
+ time_correction = 1;
+ break;
+ }
+ else {
+ time_correction_false:
+ time_correction = 0;
+ break;
+ }
+ }
}
-#ifdef ERTS_OPCODE_COUNTER_SUPPORT
- else if (argv[i][2] == 'i') { /* -ci: undcoumented option*/
- count_instructions = 1;
+ else {
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ erts_fprintf(stderr, "Invalid time correnction value: %s\n", arg);
+ erts_usage();
}
-#endif
break;
case 'W':
arg = get_arg(argv[i]+2, argv[i+1], &i);
@@ -1925,11 +2008,12 @@ erl_start(int argc, char **argv)
case 'i':
erts_error_logger_warnings = am_info;
break;
+ case 'e':
+ erts_error_logger_warnings = am_error;
+ break;
case 'w':
erts_error_logger_warnings = am_warning;
break;
- case 'e': /* The default */
- erts_error_logger_warnings = am_error;
default:
erts_fprintf(stderr, "unrecognized warning_map option %s\n", arg);
erts_usage();
@@ -1938,9 +2022,9 @@ erl_start(int argc, char **argv)
case 'z': {
char *sub_param = argv[i]+2;
- int new_limit;
if (has_prefix("dbbl", sub_param)) {
+ int new_limit;
arg = get_arg(sub_param+4, argv[i+1], &i);
new_limit = atoi(arg);
if (new_limit < 1 || INT_MAX/1024 < new_limit) {
@@ -1949,6 +2033,46 @@ erl_start(int argc, char **argv)
} else {
erts_dist_buf_busy_limit = new_limit*1024;
}
+ }
+ else if (has_prefix("dntgc", sub_param)) {
+ long secs;
+
+ arg = get_arg(sub_param+5, argv[i+1], &i);
+ if (sys_strcmp(arg, "infinity") == 0)
+ secs = ERTS_NODE_TAB_DELAY_GC_INFINITY;
+ else {
+ char *endptr;
+ errno = 0;
+ secs = strtol(arg, &endptr, 10);
+ if (errno != 0 || *arg == '\0' || *endptr != '\0'
+ || secs < 0 || ERTS_NODE_TAB_DELAY_GC_MAX < secs) {
+ erts_fprintf(stderr, "Invalid delayed node table gc: %s\n", arg);
+ erts_usage();
+ }
+ }
+ node_tab_delete_delay = (int) secs;
+ }
+ else if (has_prefix("ebwt", sub_param)) {
+ arg = get_arg(sub_param+4, argv[i+1], &i);
+ if (sys_strcmp(arg, "none") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_NONE;
+ else if (sys_strcmp(arg, "very_short") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_VERY_LOW;
+ else if (sys_strcmp(arg, "short") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_LOW;
+ else if (sys_strcmp(arg, "medium") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_NORMAL;
+ else if (sys_strcmp(arg, "long") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_HIGH;
+ else if (sys_strcmp(arg, "very_long") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_VERY_HIGH;
+ else if (sys_strcmp(arg, "extremely_long") == 0)
+ db_spin_count = ERTS_DB_SPNCNT_EXTREMELY_HIGH;
+ else {
+ erts_fprintf(stderr,
+ "Invalid ets busy wait threshold: %s\n", arg);
+ erts_usage();
+ }
} else {
erts_fprintf(stderr, "bad -z option %s\n", argv[i]);
erts_usage();
@@ -1963,6 +2087,30 @@ erl_start(int argc, char **argv)
i++;
}
+ if (!erts_check_time_adj_support(time_correction, time_warp_mode)) {
+ char *time_correction_str = time_correction ? "Enabled" : "Disabled";
+ char *time_warp_str = "undefined";
+ switch (time_warp_mode) {
+ case ERTS_NO_TIME_WARP_MODE:
+ time_warp_str = "no";
+ break;
+ case ERTS_SINGLE_TIME_WARP_MODE:
+ time_warp_str = "single";
+ break;
+ case ERTS_MULTI_TIME_WARP_MODE:
+ time_warp_str = "multi";
+ break;
+ default:
+ time_warp_str = "undefined";
+ break;
+ }
+ erts_fprintf(stderr, "%s time correction with %s time warp mode "
+ "is not supported on this platform\n",
+ time_correction_str,
+ time_warp_str);
+ erts_usage();
+ }
+
/* Output format on windows for sprintf defaults to three exponents.
* We use two-exponent to mimic normal sprintf behaviour.
*/
@@ -1996,7 +2144,11 @@ erl_start(int argc, char **argv)
legacy_proc_tab,
port_tab_sz,
port_tab_sz_ignore_files,
- legacy_port_tab);
+ legacy_port_tab,
+ time_correction,
+ time_warp_mode,
+ node_tab_delete_delay,
+ db_spin_count);
load_preloaded();
erts_end_staging_code_ix();
@@ -2004,7 +2156,8 @@ erl_start(int argc, char **argv)
erts_initialized = 1;
- erl_first_process_otp("otp_ring0", NULL, 0, boot_argc, boot_argv);
+ (void) erl_first_process_otp("otp_ring0", NULL, 0,
+ boot_argc, boot_argv);
#ifdef ERTS_SMP
erts_start_schedulers();
@@ -2012,13 +2165,17 @@ erl_start(int argc, char **argv)
erts_sys_main_thread(); /* May or may not return! */
#else
- erts_thr_set_main_status(1, 1);
+ {
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ erts_thr_set_main_status(1, 1);
#if ERTS_USE_ASYNC_READY_Q
- erts_get_scheduler_data()->aux_work_data.async_ready.queue
- = erts_get_async_ready_queue(1);
+ esdp->aux_work_data.async_ready.queue
+ = erts_get_async_ready_queue(1);
#endif
- set_main_stack_size();
- process_main();
+ set_main_stack_size();
+ erts_sched_init_time_sup(esdp);
+ process_main();
+ }
#endif
}
@@ -2090,23 +2247,17 @@ system_cleanup(int flush_async)
}
static __decl_noreturn void __noreturn
-erl_exit_vv(int n, int flush_async, char *fmt, va_list args1, va_list args2)
+erts_exit_vv(int n, int flush_async, char *fmt, va_list args1, va_list args2)
{
- unsigned int an;
-
system_cleanup(flush_async);
save_statistics();
- if (n < 0)
- an = -(unsigned int)n;
- else
- an = n;
if (erts_mtrace_enabled)
- erts_mtrace_exit((Uint32) an);
+ erts_mtrace_exit((Uint32) n);
/* Produce an Erlang core dump if error */
- if (((n > 0 && erts_no_crash_dump == 0) || n == ERTS_DUMP_EXIT)
+ 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);
}
@@ -2119,29 +2270,29 @@ erl_exit_vv(int n, int flush_async, char *fmt, va_list args1, va_list args2)
exit(0);
else if (n == ERTS_DUMP_EXIT)
ERTS_EXIT_AFTER_DUMP(1);
- else if (n > 0 || n == ERTS_ABORT_EXIT)
+ else if (n == ERTS_ERROR_EXIT || n == ERTS_ABORT_EXIT)
abort();
- exit(an);
+ exit(n);
}
/* Exit without flushing async threads */
-__decl_noreturn void __noreturn erl_exit(int n, char *fmt, ...)
+__decl_noreturn void __noreturn erts_exit(int n, char *fmt, ...)
{
va_list args1, args2;
va_start(args1, fmt);
va_start(args2, fmt);
- erl_exit_vv(n, 0, fmt, args1, args2);
+ erts_exit_vv(n, 0, fmt, args1, args2);
va_end(args2);
va_end(args1);
}
/* Exit after flushing async threads */
-__decl_noreturn void __noreturn erl_exit_flush_async(int n, char *fmt, ...)
+__decl_noreturn void __noreturn erts_flush_async_exit(int n, char *fmt, ...)
{
va_list args1, args2;
va_start(args1, fmt);
va_start(args2, fmt);
- erl_exit_vv(n, 1, fmt, args1, args2);
+ erts_exit_vv(n, 1, fmt, args1, args2);
va_end(args2);
va_end(args1);
}
diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c
index df7c443387..12a72ad839 100644
--- a/erts/emulator/beam/erl_instrument.c
+++ b/erts/emulator/beam/erl_instrument.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -1226,7 +1227,7 @@ erts_instr_init(int stat, int map_stat)
mem_anchor = NULL;
/* Install instrumentation functions */
- ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
+ ERTS_CT_ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
sys_memcpy((void *)real_allctrs,(void *)erts_allctrs,sizeof(erts_allctrs));
diff --git a/erts/emulator/beam/erl_instrument.h b/erts/emulator/beam/erl_instrument.h
index 37b9b67139..cb3b1920d3 100644
--- a/erts/emulator/beam/erl_instrument.h
+++ b/erts/emulator/beam/erl_instrument.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index b105ece6f1..3b3b247020 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -91,6 +92,7 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "driver_list", NULL },
{ "proc_link", "pid" },
{ "proc_msgq", "pid" },
+ { "proc_btm", "pid" },
{ "dist_entry", "address" },
{ "dist_entry_links", "address" },
{ "code_write_permission", NULL },
@@ -140,7 +142,6 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "async_enq_mtx", NULL },
#ifdef ERTS_SMP
{ "atom_tab", NULL },
- { "make_ref", NULL },
{ "misc_op_list_pre_alloc_lock", "address" },
{ "message_pre_alloc_lock", "address" },
{ "ptimer_pre_alloc_lock", "address", },
@@ -168,6 +169,8 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "timer_wheel", NULL },
{ "system_block", NULL },
{ "timeofday", NULL },
+ { "get_time", NULL },
+ { "get_corrected_time", NULL },
{ "breakpoints", NULL },
{ "pollsets_lock", NULL },
{ "pix_lock", "address" },
@@ -184,10 +187,8 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "efile_drv dtrace mutex", NULL },
#endif
{ "mtrace_buf", NULL },
-#ifdef __WIN32__
#ifdef ERTS_SMP
- { "sys_gethrtime", NULL },
-#endif
+ { "os_monotonic_time", NULL },
#endif
{ "erts_alloc_hard_debug", NULL },
{ "hard_dbg_mseg", NULL },
diff --git a/erts/emulator/beam/erl_lock_check.h b/erts/emulator/beam/erl_lock_check.h
index 3f7f417e61..66251ef4e8 100644
--- a/erts/emulator/beam/erl_lock_check.h
+++ b/erts/emulator/beam/erl_lock_check.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index cf6996ea06..bd00480ba2 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,7 +21,7 @@
/*
* Description: Statistics for locks.
*
- * Author: Bj�rn-Egil Dahlberg
+ * Author: Björn-Egil Dahlberg
* Date: 2008-07-03
*/
@@ -49,7 +50,7 @@ const char *str_undefined = "undefined";
static ethr_tsd_key lcnt_thr_data_key;
static int lcnt_n_thr;
-static erts_lcnt_thread_data_t *lcnt_thread_data[4096];
+static erts_lcnt_thread_data_t *lcnt_thread_data[2048];
/* local functions */
@@ -83,12 +84,12 @@ static ERTS_INLINE int lcnt_log2(Uint64 v) {
static char* lcnt_lock_type(Uint16 flag) {
switch(flag & ERTS_LCNT_LT_ALL) {
- case ERTS_LCNT_LT_SPINLOCK: return "spinlock";
- case ERTS_LCNT_LT_RWSPINLOCK: return "rw_spinlock";
- case ERTS_LCNT_LT_MUTEX: return "mutex";
- case ERTS_LCNT_LT_RWMUTEX: return "rw_mutex";
- case ERTS_LCNT_LT_PROCLOCK: return "proclock";
- default: return "";
+ case ERTS_LCNT_LT_SPINLOCK: return "spinlock";
+ case ERTS_LCNT_LT_RWSPINLOCK: return "rw_spinlock";
+ case ERTS_LCNT_LT_MUTEX: return "mutex";
+ case ERTS_LCNT_LT_RWMUTEX: return "rw_mutex";
+ case ERTS_LCNT_LT_PROCLOCK: return "proclock";
+ default: return "";
}
}
@@ -104,31 +105,27 @@ static void lcnt_clear_stats(erts_lcnt_lock_stats_t *stats) {
}
static void lcnt_time(erts_lcnt_time_t *time) {
-#if 0 || defined(HAVE_GETHRTIME)
- SysHrTime hr_time;
- hr_time = sys_gethrtime();
- time->s = (unsigned long)(hr_time / 1000000000LL);
- time->ns = (unsigned long)(hr_time - 1000000000LL*time->s);
-#else
- SysTimeval tv;
- sys_gettimeofday(&tv);
- time->s = tv.tv_sec;
- time->ns = tv.tv_usec*1000LL;
-#endif
+ /*
+ * erts_sys_hrtime() is the highest resolution
+ * we could find, it may or may not be monotonic...
+ */
+ ErtsMonotonicTime mtime = erts_sys_hrtime();
+ time->s = (unsigned long) (mtime / 1000000000LL);
+ time->ns = (unsigned long) (mtime - 1000000000LL*time->s);
}
static void lcnt_time_diff(erts_lcnt_time_t *d, erts_lcnt_time_t *t1, erts_lcnt_time_t *t0) {
long ds;
long dns;
-
+
ds = t1->s - t0->s;
dns = t1->ns - t0->ns;
-
+
/* the difference should not be able to get bigger than 1 sec in ns*/
-
+
if (dns < 0) {
- ds -= 1;
- dns += 1000000000LL;
+ ds -= 1;
+ dns += 1000000000LL;
}
ASSERT(ds >= 0);
@@ -149,7 +146,7 @@ static void lcnt_time_add(erts_lcnt_time_t *t, erts_lcnt_time_t *d) {
static erts_lcnt_thread_data_t *lcnt_thread_data_alloc(void) {
erts_lcnt_thread_data_t *eltd;
-
+
eltd = (erts_lcnt_thread_data_t*)malloc(sizeof(erts_lcnt_thread_data_t));
if (!eltd) {
ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
@@ -168,7 +165,6 @@ static erts_lcnt_thread_data_t *lcnt_get_thread_data(void) {
return (erts_lcnt_thread_data_t *)ethr_tsd_get(lcnt_thr_data_key);
}
-
/* debug */
#if 0
@@ -187,15 +183,15 @@ static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action) {
type = lcnt_lock_type(lock->flag);
r_state = ethr_atomic_read(&lock->r_state);
w_state = ethr_atomic_read(&lock->w_state);
-
+
if (lock->flag & flag) {
erts_fprintf(stderr,"%10s [%24s] [r/w state %4ld/%4ld] %2s id %T\r\n",
- action,
- lock->name,
- r_state,
- w_state,
- type,
- lock->id);
+ action,
+ lock->name,
+ r_state,
+ w_state,
+ type,
+ lock->id);
}
}
#endif
@@ -205,18 +201,18 @@ static erts_lcnt_lock_stats_t *lcnt_get_lock_stats(erts_lcnt_lock_t *lock, char
erts_lcnt_lock_stats_t *stats = NULL;
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_LOCATION) {
- for (i = 0; i < lock->n_stats; i++) {
- if ((lock->stats[i].file == file) && (lock->stats[i].line == line)) {
- return &(lock->stats[i]);
- }
- }
- if (lock->n_stats < ERTS_LCNT_MAX_LOCK_LOCATIONS) {
- stats = &lock->stats[lock->n_stats];
- lock->n_stats++;
- stats->file = file;
- stats->line = line;
- return stats;
- }
+ for (i = 0; i < lock->n_stats; i++) {
+ if ((lock->stats[i].file == file) && (lock->stats[i].line == line)) {
+ return &(lock->stats[i]);
+ }
+ }
+ if (lock->n_stats < ERTS_LCNT_MAX_LOCK_LOCATIONS) {
+ stats = &lock->stats[lock->n_stats];
+ lock->n_stats++;
+ stats->file = file;
+ stats->line = line;
+ return stats;
+ }
}
return &lock->stats[0];
}
@@ -226,53 +222,48 @@ static void lcnt_update_stats_hist(erts_lcnt_hist_t *hist, erts_lcnt_time_t *tim
unsigned long r;
if (time_wait->s > 0 || time_wait->ns > ERTS_LCNT_HISTOGRAM_MAX_NS) {
- idx = ERTS_LCNT_HISTOGRAM_SLOT_SIZE - 1;
+ idx = ERTS_LCNT_HISTOGRAM_SLOT_SIZE - 1;
} else {
- r = time_wait->ns >> ERTS_LCNT_HISTOGRAM_RSHIFT;
- if (r) idx = lcnt_log2(r);
- else idx = 0;
+ r = time_wait->ns >> ERTS_LCNT_HISTOGRAM_RSHIFT;
+ if (r) idx = lcnt_log2(r);
+ else idx = 0;
}
hist->ns[idx]++;
}
static void lcnt_update_stats(erts_lcnt_lock_stats_t *stats, int lock_in_conflict,
- erts_lcnt_time_t *time_wait) {
-
+ erts_lcnt_time_t *time_wait) {
+
ethr_atomic_inc(&stats->tries);
if (lock_in_conflict)
- ethr_atomic_inc(&stats->colls);
+ ethr_atomic_inc(&stats->colls);
if (time_wait) {
- lcnt_time_add(&(stats->timer), time_wait);
- stats->timer_n++;
- lcnt_update_stats_hist(&stats->hist,time_wait);
+ lcnt_time_add(&(stats->timer), time_wait);
+ stats->timer_n++;
+ lcnt_update_stats_hist(&stats->hist,time_wait);
}
}
-/*
- * interface
- */
+/* interface */
void erts_lcnt_init() {
erts_lcnt_thread_data_t *eltd = NULL;
-
+
/* init lock */
if (ethr_mutex_init(&lcnt_data_lock) != 0) abort();
/* init tsd */
lcnt_n_thr = 0;
-
ethr_tsd_key_create(&lcnt_thr_data_key,"lcnt_data");
lcnt_lock();
- erts_lcnt_rt_options = ERTS_LCNT_OPT_PROCLOCK | ERTS_LCNT_OPT_LOCATION;
-
+ erts_lcnt_rt_options = ERTS_LCNT_OPT_LOCATION | ERTS_LCNT_OPT_PROCLOCK;
eltd = lcnt_thread_data_alloc();
-
ethr_tsd_set(lcnt_thr_data_key, eltd);
-
+
/* init lcnt structure */
erts_lcnt_data = (erts_lcnt_data_t*)malloc(sizeof(erts_lcnt_data_t));
if (!erts_lcnt_data) {
@@ -297,7 +288,7 @@ void erts_lcnt_late_init() {
erts_lcnt_lock_list_t *erts_lcnt_list_init(void) {
erts_lcnt_lock_list_t *list;
-
+
list = (erts_lcnt_lock_list_t*)malloc(sizeof(erts_lcnt_lock_list_t));
if (!list) {
ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
@@ -311,14 +302,14 @@ erts_lcnt_lock_list_t *erts_lcnt_list_init(void) {
/* only do this on the list with the deleted locks! */
void erts_lcnt_list_clear(erts_lcnt_lock_list_t *list) {
erts_lcnt_lock_t *lock = NULL,
- *next = NULL;
+ *next = NULL;
lock = list->head;
-
+
while(lock != NULL) {
- next = lock->next;
- free(lock);
- lock = next;
+ next = lock->next;
+ free(lock);
+ lock = next;
}
list->head = NULL;
@@ -331,26 +322,25 @@ void erts_lcnt_list_insert(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock)
tail = list->tail;
if (tail) {
- tail->next = lock;
- lock->prev = tail;
+ tail->next = lock;
+ lock->prev = tail;
} else {
- list->head = lock;
- lock->prev = NULL;
- ASSERT(!lock->next);
+ list->head = lock;
+ lock->prev = NULL;
+ ASSERT(!lock->next);
}
lock->next = NULL;
list->tail = lock;
-
+
list->n++;
}
void erts_lcnt_list_delete(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock) {
-
if (lock->next) lock->next->prev = lock->prev;
if (lock->prev) lock->prev->next = lock->next;
if (list->head == lock) list->head = lock->next;
if (list->tail == lock) list->tail = lock->prev;
-
+
lock->prev = NULL;
lock->next = NULL;
list->n--;
@@ -368,12 +358,9 @@ void erts_lcnt_init_lock(erts_lcnt_lock_t *lock, char *name, Uint16 flag ) {
void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eterm id) {
int i;
- if (!name) {
- lock->flag = 0;
- return;
- }
+ if (name == NULL) { ERTS_LCNT_CLEAR_FLAG(lock); return; }
lcnt_lock();
-
+
lock->next = NULL;
lock->prev = NULL;
lock->flag = flag;
@@ -382,46 +369,55 @@ void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eter
ethr_atomic_init(&lock->r_state, 0);
ethr_atomic_init(&lock->w_state, 0);
-
#ifdef DEBUG
ethr_atomic_init(&lock->flowstate, 0);
#endif
-
+
lock->n_stats = 1;
for (i = 0; i < ERTS_LCNT_MAX_LOCK_LOCATIONS; i++) {
- lcnt_clear_stats(&lock->stats[i]);
+ lcnt_clear_stats(&lock->stats[i]);
}
erts_lcnt_list_insert(erts_lcnt_data->current_locks, lock);
lcnt_unlock();
}
-
+/* init empty, instead of zero struct */
+void erts_lcnt_init_lock_empty(erts_lcnt_lock_t *lock) {
+ lock->next = NULL;
+ lock->prev = NULL;
+ lock->flag = 0;
+ lock->name = NULL;
+ lock->id = NIL;
+ ethr_atomic_init(&lock->r_state, 0);
+ ethr_atomic_init(&lock->w_state, 0);
+#ifdef DEBUG
+ ethr_atomic_init(&lock->flowstate, 0);
+#endif
+ lock->n_stats = 0;
+ sys_memzero(lock->stats, sizeof(lock->stats));
+}
+/* destroy lock */
void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock) {
- erts_lcnt_lock_t *deleted_lock;
-
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
-
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
lcnt_lock();
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_COPYSAVE) {
- /* copy structure and insert the copy */
-
- deleted_lock = (erts_lcnt_lock_t*)malloc(sizeof(erts_lcnt_lock_t));
+ erts_lcnt_lock_t *deleted_lock;
+ /* copy structure and insert the copy */
+ deleted_lock = (erts_lcnt_lock_t*)malloc(sizeof(erts_lcnt_lock_t));
if (!deleted_lock) {
ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
}
- memcpy(deleted_lock, lock, sizeof(erts_lcnt_lock_t));
-
- deleted_lock->next = NULL;
- deleted_lock->prev = NULL;
-
- erts_lcnt_list_insert(erts_lcnt_data->deleted_locks, deleted_lock);
+ memcpy(deleted_lock, lock, sizeof(erts_lcnt_lock_t));
+ deleted_lock->next = NULL;
+ deleted_lock->prev = NULL;
+ erts_lcnt_list_insert(erts_lcnt_data->deleted_locks, deleted_lock);
}
/* delete original */
erts_lcnt_list_delete(erts_lcnt_data->current_locks, lock);
- lock->flag = 0;
-
+ ERTS_LCNT_CLEAR_FLAG(lock);
+
lcnt_unlock();
}
@@ -430,16 +426,15 @@ void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock) {
void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
erts_aint_t r_state = 0, w_state = 0;
erts_lcnt_thread_data_t *eltd;
-
+
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
eltd = lcnt_get_thread_data();
-
ASSERT(eltd);
-
+
w_state = ethr_atomic_read(&lock->w_state);
-
+
if (option & ERTS_LCNT_LO_WRITE) {
r_state = ethr_atomic_read(&lock->r_state);
ethr_atomic_inc( &lock->w_state);
@@ -447,48 +442,47 @@ void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
if (option & ERTS_LCNT_LO_READ) {
ethr_atomic_inc( &lock->r_state);
}
-
+
/* we cannot acquire w_lock if either w or r are taken */
/* we cannot acquire r_lock if w_lock is taken */
-
+
if ((w_state > 0) || (r_state > 0)) {
- eltd->lock_in_conflict = 1;
- if (eltd->timer_set == 0) {
- lcnt_time(&eltd->timer);
- }
- eltd->timer_set++;
+ eltd->lock_in_conflict = 1;
+ if (eltd->timer_set == 0) {
+ lcnt_time(&eltd->timer);
+ }
+ eltd->timer_set++;
} else {
- eltd->lock_in_conflict = 0;
+ eltd->lock_in_conflict = 0;
}
}
void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
erts_aint_t w_state;
erts_lcnt_thread_data_t *eltd;
-
+
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
w_state = ethr_atomic_read(&lock->w_state);
ethr_atomic_inc(&lock->w_state);
-
eltd = lcnt_get_thread_data();
ASSERT(eltd);
if (w_state > 0) {
- eltd->lock_in_conflict = 1;
- /* only set the timer if nobody else has it
- * This should only happen when proc_locks aquires several locks
- * 'atomicly'. All other locks will block the thread if w_state > 0
- * i.e. locked.
- */
- if (eltd->timer_set == 0) {
- lcnt_time(&eltd->timer);
- }
- eltd->timer_set++;
+ eltd->lock_in_conflict = 1;
+ /* only set the timer if nobody else has it
+ * This should only happen when proc_locks aquires several locks
+ * 'atomicly'. All other locks will block the thread if w_state > 0
+ * i.e. locked.
+ */
+ if (eltd->timer_set == 0) {
+ lcnt_time(&eltd->timer);
+ }
+ eltd->timer_set++;
} else {
- eltd->lock_in_conflict = 0;
+ eltd->lock_in_conflict = 0;
}
}
@@ -497,16 +491,19 @@ void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
void erts_lcnt_lock_unaquire(erts_lcnt_lock_t *lock) {
/* should check if this thread was "waiting" */
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
ethr_atomic_dec(&lock->w_state);
}
-/* erts_lcnt_lock_post
- * used when we get a lock (i.e. directly after a lock operation)
+/*
+ * erts_lcnt_lock_post
+ *
+ * Used when we get a lock (i.e. directly after a lock operation)
* if the timer was set then we had to wait for the lock
* lock_post will calculate the wait time.
*/
+
void erts_lcnt_lock_post(erts_lcnt_lock_t *lock) {
erts_lcnt_lock_post_x(lock, (char*)str_undefined, 0);
}
@@ -521,31 +518,31 @@ void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line
#endif
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
-
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
+
#ifdef DEBUG
if (!(lock->flag & (ERTS_LCNT_LT_RWMUTEX | ERTS_LCNT_LT_RWSPINLOCK))) {
- flowstate = ethr_atomic_read(&lock->flowstate);
- ASSERT(flowstate == 0);
- ethr_atomic_inc(&lock->flowstate);
+ flowstate = ethr_atomic_read(&lock->flowstate);
+ ASSERT(flowstate == 0);
+ ethr_atomic_inc(&lock->flowstate);
}
#endif
-
+
eltd = lcnt_get_thread_data();
-
+
ASSERT(eltd);
/* if lock was in conflict, time it */
stats = lcnt_get_lock_stats(lock, file, line);
if (eltd->timer_set) {
- lcnt_time(&timer);
-
- lcnt_time_diff(&time_wait, &timer, &(eltd->timer));
- lcnt_update_stats(stats, eltd->lock_in_conflict, &time_wait);
- eltd->timer_set--;
- ASSERT(eltd->timer_set >= 0);
+ lcnt_time(&timer);
+
+ lcnt_time_diff(&time_wait, &timer, &(eltd->timer));
+ lcnt_update_stats(stats, eltd->lock_in_conflict, &time_wait);
+ eltd->timer_set--;
+ ASSERT(eltd->timer_set >= 0);
} else {
- lcnt_update_stats(stats, eltd->lock_in_conflict, NULL);
+ lcnt_update_stats(stats, eltd->lock_in_conflict, NULL);
}
}
@@ -554,27 +551,28 @@ void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line
void erts_lcnt_unlock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
if (option & ERTS_LCNT_LO_WRITE) ethr_atomic_dec(&lock->w_state);
if (option & ERTS_LCNT_LO_READ ) ethr_atomic_dec(&lock->r_state);
}
void erts_lcnt_unlock(erts_lcnt_lock_t *lock) {
-#ifdef DEBUG
- erts_aint_t w_state;
- erts_aint_t flowstate;
-#endif
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
#ifdef DEBUG
- /* flowstate */
- flowstate = ethr_atomic_read(&lock->flowstate);
- ASSERT(flowstate == 1);
- ethr_atomic_dec(&lock->flowstate);
-
- /* write state */
- w_state = ethr_atomic_read(&lock->w_state);
- ASSERT(w_state > 0);
+ {
+ erts_aint_t w_state;
+ erts_aint_t flowstate;
+
+ /* flowstate */
+ flowstate = ethr_atomic_read(&lock->flowstate);
+ ASSERT(flowstate == 1);
+ ethr_atomic_dec(&lock->flowstate);
+
+ /* write state */
+ w_state = ethr_atomic_read(&lock->w_state);
+ ASSERT(w_state > 0);
+ }
#endif
ethr_atomic_dec(&lock->w_state);
}
@@ -583,35 +581,34 @@ void erts_lcnt_unlock(erts_lcnt_lock_t *lock) {
void erts_lcnt_trylock_opt(erts_lcnt_lock_t *lock, int res, Uint16 option) {
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
/* Determine lock_state via res instead of state */
if (res != EBUSY) {
- if (option & ERTS_LCNT_LO_WRITE) ethr_atomic_inc(&lock->w_state);
- if (option & ERTS_LCNT_LO_READ ) ethr_atomic_inc(&lock->r_state);
- lcnt_update_stats(&(lock->stats[0]), 0, NULL);
+ if (option & ERTS_LCNT_LO_WRITE) ethr_atomic_inc(&lock->w_state);
+ if (option & ERTS_LCNT_LO_READ ) ethr_atomic_inc(&lock->r_state);
+ lcnt_update_stats(&(lock->stats[0]), 0, NULL);
} else {
ethr_atomic_inc(&lock->stats[0].tries);
ethr_atomic_inc(&lock->stats[0].colls);
}
}
-
+
void erts_lcnt_trylock(erts_lcnt_lock_t *lock, int res) {
/* Determine lock_state via res instead of state */
-#ifdef DEBUG
- erts_aint_t flowstate;
-#endif
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
- if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
+ if (ERTS_LCNT_IS_LOCK_INVALID(lock)) return;
if (res != EBUSY) {
-
#ifdef DEBUG
- flowstate = ethr_atomic_read(&lock->flowstate);
- ASSERT(flowstate == 0);
- ethr_atomic_inc( &lock->flowstate);
+ {
+ erts_aint_t flowstate;
+ flowstate = ethr_atomic_read(&lock->flowstate);
+ ASSERT(flowstate == 0);
+ ethr_atomic_inc( &lock->flowstate);
+ }
#endif
- ethr_atomic_inc(&lock->w_state);
- lcnt_update_stats(&(lock->stats[0]), 0, NULL);
+ ethr_atomic_inc(&lock->w_state);
+ lcnt_update_stats(&(lock->stats[0]), 0, NULL);
} else {
ethr_atomic_inc(&lock->stats[0].tries);
ethr_atomic_inc(&lock->stats[0].colls);
@@ -666,13 +663,13 @@ void erts_lcnt_clear_counters(void) {
lcnt_lock();
list = erts_lcnt_data->current_locks;
-
+
for (lock = list->head; lock != NULL; lock = lock->next) {
- for( i = 0; i < ERTS_LCNT_MAX_LOCK_LOCATIONS; i++) {
- stats = &lock->stats[i];
- lcnt_clear_stats(stats);
- }
- lock->n_stats = 1;
+ for( i = 0; i < ERTS_LCNT_MAX_LOCK_LOCATIONS; i++) {
+ stats = &lock->stats[i];
+ lcnt_clear_stats(stats);
+ }
+ lock->n_stats = 1;
}
/* empty deleted locks in lock list */
@@ -685,14 +682,14 @@ void erts_lcnt_clear_counters(void) {
erts_lcnt_data_t *erts_lcnt_get_data(void) {
erts_lcnt_time_t timer_stop;
-
+
lcnt_lock();
-
+
lcnt_time(&timer_stop);
lcnt_time_diff(&(erts_lcnt_data->duration), &timer_stop, &timer_start);
-
+
lcnt_unlock();
-
+
return erts_lcnt_data;
}
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h
index ffbb93da1b..4cc6a5c695 100644
--- a/erts/emulator/beam/erl_lock_count.h
+++ b/erts/emulator/beam/erl_lock_count.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,7 +21,7 @@
/*
* Description: Statistics for locks.
*
- * Author: Bj�rn-Egil Dahlberg
+ * Author: Björn-Egil Dahlberg
* Date: 2008-07-03
* Abstract:
* Locks statistics internal representation.
@@ -76,7 +77,7 @@
/* histogram */
#define ERTS_LCNT_HISTOGRAM_MAX_NS (((unsigned long)1LL << 28) - 1)
-#if 0 || defined(HAVE_GETHRTIME)
+#if 0 || defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)
#define ERTS_LCNT_HISTOGRAM_SLOT_SIZE (30)
#define ERTS_LCNT_HISTOGRAM_RSHIFT (0)
#else
@@ -95,30 +96,35 @@
#define ERTS_LCNT_LO_WRITE (((Uint16) 1) << 7)
#define ERTS_LCNT_LO_READ_WRITE ( ERTS_LCNT_LO_READ \
- | ERTS_LCNT_LO_WRITE )
+ | ERTS_LCNT_LO_WRITE )
#define ERTS_LCNT_LT_ALL ( ERTS_LCNT_LT_SPINLOCK \
- | ERTS_LCNT_LT_RWSPINLOCK \
- | ERTS_LCNT_LT_MUTEX \
- | ERTS_LCNT_LT_RWMUTEX \
- | ERTS_LCNT_LT_PROCLOCK )
+ | ERTS_LCNT_LT_RWSPINLOCK \
+ | ERTS_LCNT_LT_MUTEX \
+ | ERTS_LCNT_LT_RWMUTEX \
+ | ERTS_LCNT_LT_PROCLOCK )
+
+#define ERTS_LCNT_LOCK_TYPE(lock) ((lock)->flag & ERTS_LCNT_LT_ALL)
+#define ERTS_LCNT_IS_LOCK_INVALID(lock) (!((lock)->flag & ERTS_LCNT_LT_ALL))
+#define ERTS_LCNT_CLEAR_FLAG(lock) ((lock)->flag = 0)
+
/* runtime options */
-#define ERTS_LCNT_OPT_SUSPEND (((Uint16) 1) << 0)
-#define ERTS_LCNT_OPT_LOCATION (((Uint16) 1) << 1)
-#define ERTS_LCNT_OPT_PROCLOCK (((Uint16) 1) << 2)
-#define ERTS_LCNT_OPT_COPYSAVE (((Uint16) 1) << 3)
-#define ERTS_LCNT_OPT_PORTLOCK (((Uint16) 1) << 4)
+#define ERTS_LCNT_OPT_SUSPEND (((Uint16) 1) << 0)
+#define ERTS_LCNT_OPT_LOCATION (((Uint16) 1) << 1)
+#define ERTS_LCNT_OPT_PROCLOCK (((Uint16) 1) << 2)
+#define ERTS_LCNT_OPT_PORTLOCK (((Uint16) 1) << 3)
+#define ERTS_LCNT_OPT_COPYSAVE (((Uint16) 1) << 4)
typedef struct {
unsigned long s;
unsigned long ns;
} erts_lcnt_time_t;
-
+
extern erts_lcnt_time_t timer_start;
typedef struct {
- Uint32 ns[ERTS_LCNT_HISTOGRAM_SLOT_SIZE]; /* log2 array of nano seconds occurences */
+ Uint32 ns[ERTS_LCNT_HISTOGRAM_SLOT_SIZE]; /* log2 array of nano seconds occurences */
} erts_lcnt_hist_t;
typedef struct erts_lcnt_lock_stats_s {
@@ -129,10 +135,10 @@ typedef struct erts_lcnt_lock_stats_s {
char *file; /* which file the lock was taken */
unsigned int line; /* line number in file */
-
+
ethr_atomic_t tries; /* n tries to get lock */
ethr_atomic_t colls; /* n collisions of tries to get lock */
-
+
unsigned long timer_n; /* #times waited for lock */
erts_lcnt_time_t timer; /* total wait time for lock */
erts_lcnt_hist_t hist;
@@ -155,7 +161,7 @@ typedef struct erts_lcnt_lock_s {
/* statistics */
unsigned int n_stats;
erts_lcnt_lock_stats_t stats[ERTS_LCNT_MAX_LOCK_LOCATIONS]; /* first entry is "undefined"*/
-
+
/* chains for list handling */
/* data is hold by lcnt_lock */
struct erts_lcnt_lock_s *prev;
@@ -167,7 +173,7 @@ typedef struct {
erts_lcnt_lock_t *tail;
unsigned long n;
} erts_lcnt_lock_list_t;
-
+
typedef struct {
erts_lcnt_time_t duration; /* time since last clear */
erts_lcnt_lock_list_t *current_locks;
@@ -205,6 +211,7 @@ void erts_lcnt_list_delete(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock);
/* lock operations (global) */
void erts_lcnt_init_lock(erts_lcnt_lock_t *lock, char *name, Uint16 flag);
void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eterm id);
+void erts_lcnt_init_lock_empty(erts_lcnt_lock_t *lock);
void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock);
void erts_lcnt_lock(erts_lcnt_lock_t *lock);
@@ -226,7 +233,5 @@ void erts_lcnt_clear_counters(void);
char *erts_lcnt_lock_type(Uint16 type);
erts_lcnt_data_t *erts_lcnt_get_data(void);
-#define ERTS_LCNT_LOCK_TYPE(lockp) ((lockp)->flag & ERTS_LCNT_LT_ALL)
-
#endif /* ifdef ERTS_ENABLE_LOCK_COUNT */
#endif /* ifndef ERTS_LOCK_COUNT_H__ */
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c
index a180047f6c..3c066cea7b 100644
--- a/erts/emulator/beam/erl_map.c
+++ b/erts/emulator/beam/erl_map.c
@@ -3,19 +3,23 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
+ * hashmaps are an adaption of Rich Hickeys Persistent HashMaps
+ * which were an adaption of Phil Bagwells - Hash Array Mapped Tries
+ *
* Author: Björn-Egil Dahlberg
*/
@@ -28,7 +32,10 @@
#include "global.h"
#include "erl_process.h"
#include "error.h"
+#define ERL_WANT_HIPE_BIF_WRAPPER__
#include "bif.h"
+#undef ERL_WANT_HIPE_BIF_WRAPPER__
+#include "erl_binary.h"
#include "erl_map.h"
@@ -62,39 +69,87 @@
* - erts_internal:map_to_tuple_keys/1
*/
+#ifndef DECL_AM
+#define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
+#endif
+
+/* for hashmap_from_list/1 */
+typedef struct {
+ Uint32 hx;
+ Uint32 skip;
+ Uint i;
+ Eterm val;
+} hxnode_t;
+
+
+static Eterm flatmap_merge(Process *p, Eterm nodeA, Eterm nodeB);
+static BIF_RETTYPE map_merge_mixed(Process *p, Eterm flat, Eterm tree, int swap_args);
+struct HashmapMergeContext_;
+static BIF_RETTYPE hashmap_merge(Process *p, Eterm nodeA, Eterm nodeB, int swap_args,
+ struct HashmapMergeContext_*);
+static Export hashmap_merge_trap_export;
+static BIF_RETTYPE maps_merge_trap_1(BIF_ALIST_1);
+static Uint hashmap_subtree_size(Eterm node);
+static Eterm hashmap_to_list(Process *p, Eterm map);
+static Eterm hashmap_keys(Process *p, Eterm map);
+static Eterm hashmap_values(Process *p, Eterm map);
+static Eterm hashmap_delete(Process *p, Uint32 hx, Eterm key, Eterm node);
+static Eterm flatmap_from_validated_list(Process *p, Eterm list, Uint size);
+static Eterm hashmap_from_validated_list(Process *p, Eterm list, Uint size);
+static Eterm hashmap_from_unsorted_array(ErtsHeapFactory*, hxnode_t *hxns, Uint n, int reject_dupkeys);
+static Eterm hashmap_from_sorted_unique_array(ErtsHeapFactory*, hxnode_t *hxns, Uint n, int is_root);
+static Eterm hashmap_from_chunked_array(ErtsHeapFactory*, hxnode_t *hxns, Uint n, Uint size, int is_root);
+static Eterm hashmap_info(Process *p, Eterm node);
+static Eterm hashmap_bld_tuple_uint(Uint **hpp, Uint *szp, Uint n, Uint nums[]);
+static int hxnodecmp(hxnode_t* a, hxnode_t* b);
+static int hxnodecmpkey(hxnode_t* a, hxnode_t* b);
+
+
+void erts_init_map(void) {
+ erts_init_trap_export(&hashmap_merge_trap_export,
+ am_maps, am_merge_trap, 1,
+ &maps_merge_trap_1);
+ return;
+}
+
+
/* erlang:map_size/1
* the corresponding instruction is implemented in:
* beam/erl_bif_guard.c
*/
BIF_RETTYPE map_size_1(BIF_ALIST_1) {
- if (is_map(BIF_ARG_1)) {
- Eterm *hp;
- Uint hsz = 0;
- map_t *mp = (map_t*)map_val(BIF_ARG_1);
- Uint n = map_get_size(mp);
-
- erts_bld_uint(NULL, &hsz, n);
+ if (is_flatmap(BIF_ARG_1)) {
+ flatmap_t *mp = (flatmap_t*)flatmap_val(BIF_ARG_1);
+ BIF_RET(make_small(flatmap_get_size(mp)));
+ } else if (is_hashmap(BIF_ARG_1)) {
+ Eterm *head, *hp, res;
+ Uint size, hsz=0;
+
+ head = hashmap_val(BIF_ARG_1);
+ size = head[1];
+ (void) erts_bld_uint(NULL, &hsz, size);
hp = HAlloc(BIF_P, hsz);
- BIF_RET(erts_bld_uint(&hp, NULL, n));
+ res = erts_bld_uint(&hp, NULL, size);
+ BIF_RET(res);
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
}
-/* maps:to_list/1
- */
+/* maps:to_list/1 */
BIF_RETTYPE maps_to_list_1(BIF_ALIST_1) {
- if (is_map(BIF_ARG_1)) {
+ if (is_flatmap(BIF_ARG_1)) {
Uint n;
Eterm* hp;
Eterm *ks,*vs, res, tup;
- map_t *mp = (map_t*)map_val(BIF_ARG_1);
+ flatmap_t *mp = (flatmap_t*)flatmap_val(BIF_ARG_1);
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
- n = map_get_size(mp);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+ n = flatmap_get_size(mp);
hp = HAlloc(BIF_P, (2 + 3) * n);
res = NIL;
@@ -104,108 +159,101 @@ BIF_RETTYPE maps_to_list_1(BIF_ALIST_1) {
}
BIF_RET(res);
+ } else if (is_hashmap(BIF_ARG_1)) {
+ return hashmap_to_list(BIF_P, BIF_ARG_1);
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
}
/* maps:find/2
* return value if key *matches* a key in the map
*/
-int erts_maps_find(Eterm key, Eterm map, Eterm *value) {
+const Eterm *
+#if HALFWORD_HEAP
+erts_maps_get_rel(Eterm key, Eterm map, Eterm *map_base)
+#else
+erts_maps_get(Eterm key, Eterm map)
+#endif
+{
+ Uint32 hx;
+ if (is_flatmap_rel(map, map_base)) {
+ Eterm *ks, *vs;
+ flatmap_t *mp;
+ Uint n, i;
- Eterm *ks,*vs;
- map_t *mp;
- Uint n,i;
+ mp = (flatmap_t *)flatmap_val_rel(map, map_base);
+ n = flatmap_get_size(mp);
- mp = (map_t*)map_val(map);
- n = map_get_size(mp);
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
+ if (n == 0) {
+ return NULL;
+ }
- for( i = 0; i < n; i++) {
- if (EQ(ks[i], key)) {
- *value = vs[i];
- return 1;
+ ks = (Eterm *)tuple_val_rel(mp->keys, map_base) + 1;
+ vs = flatmap_get_values(mp);
+
+ if (is_immed(key)) {
+ for (i = 0; i < n; i++) {
+ if (ks[i] == key) {
+ return &vs[i];
+ }
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ if (eq_rel(ks[i], map_base, key, NULL)) {
+ return &vs[i];
+ }
}
+ return NULL;
}
- return 0;
+ ASSERT(is_hashmap_rel(map, map_base));
+ hx = hashmap_make_hash(key);
+
+ return erts_hashmap_get_rel(hx, key, map, map_base);
}
BIF_RETTYPE maps_find_2(BIF_ALIST_2) {
if (is_map(BIF_ARG_2)) {
- Eterm *hp, value,res;
+ Eterm *hp, res;
+ const Eterm *value;
- if (erts_maps_find(BIF_ARG_1, BIF_ARG_2, &value)) {
+ value = erts_maps_get(BIF_ARG_1, BIF_ARG_2);
+ if (value) {
hp = HAlloc(BIF_P, 3);
res = make_tuple(hp);
*hp++ = make_arityval(2);
*hp++ = am_ok;
- *hp++ = value;
+ *hp++ = *value;
BIF_RET(res);
}
-
BIF_RET(am_error);
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_2;
+ BIF_ERROR(BIF_P, BADMAP);
}
+
/* maps:get/2
* return value if key *matches* a key in the map
- * exception bad_key if none matches
+ * exception badkey if none matches
*/
-
-int erts_maps_get(Eterm key, Eterm map, Eterm *value) {
- Eterm *ks,*vs;
- map_t *mp;
- Uint n,i;
-
- mp = (map_t*)map_val(map);
- n = map_get_size(mp);
-
- if (n == 0)
- return 0;
-
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
-
- if (is_immed(key)) {
- for( i = 0; i < n; i++) {
- if (ks[i] == key) {
- *value = vs[i];
- return 1;
- }
- }
- }
-
- for( i = 0; i < n; i++) {
- if (EQ(ks[i], key)) {
- *value = vs[i];
- return 1;
- }
- }
- return 0;
-}
-
BIF_RETTYPE maps_get_2(BIF_ALIST_2) {
if (is_map(BIF_ARG_2)) {
- Eterm *hp;
- Eterm value, error;
- char *s_error;
+ const Eterm *value;
- if (erts_maps_get(BIF_ARG_1, BIF_ARG_2, &value)) {
- BIF_RET(value);
+ value = erts_maps_get(BIF_ARG_1, BIF_ARG_2);
+ if (value) {
+ BIF_RET(*value);
}
- s_error = "bad_key";
- error = am_atom_put(s_error, sys_strlen(s_error));
-
- hp = HAlloc(BIF_P, 3);
- BIF_P->fvalue = TUPLE2(hp, error, BIF_ARG_1);
- BIF_ERROR(BIF_P, EXC_ERROR_2);
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADKEY);
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_2;
+ BIF_ERROR(BIF_P, BADMAP);
}
/* maps:from_list/1
@@ -213,13 +261,8 @@ BIF_RETTYPE maps_get_2(BIF_ALIST_2) {
*/
BIF_RETTYPE maps_from_list_1(BIF_ALIST_1) {
- Eterm *kv, item = BIF_ARG_1;
- Eterm *hp, *thp,*vs, *ks, keys, res;
- map_t *mp;
- Uint size = 0, unused_size = 0;
- Sint c = 0;
- Sint idx = 0;
-
+ Eterm item = BIF_ARG_1, res, *kv;
+ Uint size = 0;
if (is_list(item) || is_nil(item)) {
/* Calculate size and check validity */
@@ -240,450 +283,1329 @@ BIF_RETTYPE maps_from_list_1(BIF_ALIST_1) {
if (is_not_nil(item))
goto error;
- hp = HAlloc(BIF_P, 3 + 1 + (2 * size));
- thp = hp;
+ if (size > MAP_SMALL_MAP_LIMIT) {
+ BIF_RET(hashmap_from_validated_list(BIF_P, BIF_ARG_1, size));
+ } else {
+ BIF_RET(flatmap_from_validated_list(BIF_P, BIF_ARG_1, size));
+ }
+ }
+
+error:
+
+ BIF_ERROR(BIF_P, BADARG);
+}
+
+static Eterm flatmap_from_validated_list(Process *p, Eterm list, Uint size) {
+ Eterm *kv, item = list;
+ Eterm *hp, *thp,*vs, *ks, keys, res;
+ flatmap_t *mp;
+ Uint unused_size = 0;
+ Sint c = 0;
+ Sint idx = 0;
+
+
+ hp = HAlloc(p, 3 + 1 + (2 * size));
+ thp = hp;
+ keys = make_tuple(hp);
+ *hp++ = make_arityval(size);
+ ks = hp;
+ hp += size;
+ mp = (flatmap_t*)hp;
+ res = make_flatmap(mp);
+ hp += MAP_HEADER_FLATMAP_SZ;
+ vs = hp;
+
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = size; /* set later, might shrink*/
+ mp->keys = keys;
+
+ if (size == 0)
+ return res;
+
+ /* first entry */
+ kv = tuple_val(CAR(list_val(item)));
+ ks[0] = kv[1];
+ vs[0] = kv[2];
+ size = 1;
+ item = CDR(list_val(item));
+
+ /* insert sort key/value pairs */
+ while(is_list(item)) {
+
+ kv = tuple_val(CAR(list_val(item)));
+
+ /* compare ks backwards
+ * idx represent word index to be written (hole position).
+ * We cannot copy the elements when searching since we might
+ * have an equal key. So we search for just the index first =(
+ *
+ * It is perhaps faster to move the values in the first pass.
+ * Check for uniqueness during insert phase and then have a
+ * second phace compacting the map if duplicates are found
+ * during insert. .. or do someother sort .. shell-sort perhaps.
+ */
+
+ idx = size;
+
+ while(idx > 0 && (c = CMP_TERM(kv[1],ks[idx-1])) < 0) { idx--; }
+
+ if (c == 0) {
+ /* last compare was equal,
+ * i.e. we have to release memory
+ * and overwrite that key/value
+ */
+ ks[idx-1] = kv[1];
+ vs[idx-1] = kv[2];
+ unused_size++;
+ } else {
+ Uint i = size;
+ while(i > idx) {
+ ks[i] = ks[i-1];
+ vs[i] = vs[i-1];
+ i--;
+ }
+ ks[idx] = kv[1];
+ vs[idx] = kv[2];
+ size++;
+ }
+ item = CDR(list_val(item));
+ }
+
+ if (unused_size) {
+ /* the key tuple is embedded in the heap
+ * write a bignum to clear it.
+ */
+ /* release values as normal since they are on the top of the heap */
+
+ ks[size] = make_pos_bignum_header(unused_size - 1);
+ HRelease(p, vs + size + unused_size, vs + size);
+ }
+
+ *thp = make_arityval(size);
+ mp->size = size;
+ return res;
+}
+
+#define swizzle32(D,S) \
+ do { \
+ (D) = ((S) & 0x0000000f) << 28 | ((S) & 0x000000f0) << 20 \
+ | ((S) & 0x00000f00) << 12 | ((S) & 0x0000f000) << 4 \
+ | ((S) & 0x000f0000) >> 4 | ((S) & 0x00f00000) >> 12 \
+ | ((S) & 0x0f000000) >> 20 | ((S) & 0xf0000000) >> 28; \
+ } while(0)
+
+#define maskval(V,L) (((V) >> ((7 - (L))*4)) & 0xf)
+#define cdepth(V1,V2) (hashmap_clz((V1) ^ (V2)) >> 2)
+
+static Eterm hashmap_from_validated_list(Process *p, Eterm list, Uint size) {
+ Eterm item = list;
+ Eterm *hp;
+ Eterm *kv, res;
+ Uint32 sw, hx;
+ Uint ix = 0;
+ hxnode_t *hxns;
+ ErtsHeapFactory factory;
+ DeclareTmpHeap(tmp,2,p);
+ ASSERT(size > 0);
+
+ hp = HAlloc(p, (2 * size));
+
+ /* create tmp hx values and leaf ptrs */
+ hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, size * sizeof(hxnode_t));
+
+ UseTmpHeap(2,p);
+ while(is_list(item)) {
+ res = CAR(list_val(item));
+ kv = tuple_val(res);
+ hx = hashmap_restore_hash(tmp,0,kv[1]);
+ swizzle32(sw,hx);
+ hxns[ix].hx = sw;
+ hxns[ix].val = CONS(hp, kv[1], kv[2]); hp += 2;
+ hxns[ix].skip = 1; /* will be reassigned in from_array */
+ hxns[ix].i = ix;
+ ix++;
+ item = CDR(list_val(item));
+ }
+ UnUseTmpHeap(2,p);
+
+ erts_factory_proc_init(&factory, p);
+ res = hashmap_from_unsorted_array(&factory, hxns, size, 0);
+ erts_factory_close(&factory);
+
+ erts_free(ERTS_ALC_T_TMP, (void *) hxns);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
+
+ if (hashmap_size(res) <= MAP_SMALL_MAP_LIMIT) {
+ DECLARE_WSTACK(wstack);
+ Eterm *kv, *ks, *vs;
+ flatmap_t *mp;
+ Eterm keys;
+ Uint n = hashmap_size(res);
+
+ /* build flat structure */
+ hp = HAlloc(p, 3 + 1 + (2 * n));
keys = make_tuple(hp);
- *hp++ = make_arityval(size);
+ *hp++ = make_arityval(n);
ks = hp;
- hp += size;
- mp = (map_t*)hp;
- res = make_map(mp);
- hp += MAP_HEADER_SIZE;
+ hp += n;
+ mp = (flatmap_t*)hp;
+ hp += MAP_HEADER_FLATMAP_SZ;
vs = hp;
- mp->thing_word = MAP_HEADER;
- mp->size = size; /* set later, might shrink*/
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = n;
mp->keys = keys;
- if (size == 0)
- BIF_RET(res);
+ hashmap_iterator_init(&wstack, res, 0);
- item = BIF_ARG_1;
+ while ((kv=hashmap_iterator_next(&wstack)) != NULL) {
+ *ks++ = CAR(kv);
+ *vs++ = CDR(kv);
+ }
- /* first entry */
- kv = tuple_val(CAR(list_val(item)));
- ks[0] = kv[1];
- vs[0] = kv[2];
- size = 1;
- item = CDR(list_val(item));
+ /* it cannot have multiple keys */
+ erts_validate_and_sort_flatmap(mp);
- /* insert sort key/value pairs */
- while(is_list(item)) {
+ DESTROY_WSTACK(wstack);
+ return make_flatmap(mp);
+ }
- kv = tuple_val(CAR(list_val(item)));
-
- /* compare ks backwards
- * idx represent word index to be written (hole position).
- * We cannot copy the elements when searching since we might
- * have an equal key. So we search for just the index first =(
- *
- * It is perhaps faster to move the values in the first pass.
- * Check for uniqueness during insert phase and then have a
- * second phace compacting the map if duplicates are found
- * during insert. .. or do someother sort .. shell-sort perhaps.
- */
+ return res;
+}
- idx = size;
+Eterm erts_hashmap_from_array(ErtsHeapFactory* factory, Eterm *leafs, Uint n,
+ int reject_dupkeys) {
+ Uint32 sw, hx;
+ Uint ix;
+ hxnode_t *hxns;
+ Eterm res;
+
+ /* create tmp hx values and leaf ptrs */
+ hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(hxnode_t));
+
+ for (ix = 0; ix < n; ix++) {
+ hx = hashmap_make_hash(*leafs);
+ swizzle32(sw,hx);
+ hxns[ix].hx = sw;
+ hxns[ix].val = make_list(leafs);
+ hxns[ix].skip = 1;
+ hxns[ix].i = ix;
+ leafs += 2;
+ }
- while(idx > 0 && (c = CMP_TERM(kv[1],ks[idx-1])) < 0) { idx--; }
+ res = hashmap_from_unsorted_array(factory, hxns, n, reject_dupkeys);
- if (c == 0) {
- /* last compare was equal,
- * i.e. we have to release memory
- * and overwrite that key/value
- */
- ks[idx-1] = kv[1];
- vs[idx-1] = kv[2];
- unused_size++;
- } else {
- Uint i = size;
- while(i > idx) {
- ks[i] = ks[i-1];
- vs[i] = vs[i-1];
- i--;
+ erts_free(ERTS_ALC_T_TMP, (void *) hxns);
+
+ return res;
+}
+
+
+Eterm erts_hashmap_from_ks_and_vs_extra(Process *p, Eterm *ks, Eterm *vs, Uint n,
+ Eterm key, Eterm value) {
+ Uint32 sw, hx;
+ Uint i,sz;
+ hxnode_t *hxns;
+ ErtsHeapFactory factory;
+ Eterm *hp, res;
+
+ sz = (key == THE_NON_VALUE) ? n : (n + 1);
+ ASSERT(sz > MAP_SMALL_MAP_LIMIT);
+ hp = HAlloc(p, 2 * sz);
+
+ /* create tmp hx values and leaf ptrs */
+ hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, sz * sizeof(hxnode_t));
+
+ for(i = 0; i < n; i++) {
+ hx = hashmap_make_hash(ks[i]);
+ swizzle32(sw,hx);
+ hxns[i].hx = sw;
+ hxns[i].val = CONS(hp, ks[i], vs[i]); hp += 2;
+ hxns[i].skip = 1; /* will be reassigned in from_array */
+ hxns[i].i = i;
+ }
+
+ if (key != THE_NON_VALUE) {
+ hx = hashmap_make_hash(key);
+ swizzle32(sw,hx);
+ hxns[i].hx = sw;
+ hxns[i].val = CONS(hp, key, value); hp += 2;
+ hxns[i].skip = 1;
+ hxns[i].i = i;
+ }
+
+ erts_factory_proc_init(&factory, p);
+ res = hashmap_from_unsorted_array(&factory, hxns, sz, 0);
+ erts_factory_close(&factory);
+
+ erts_free(ERTS_ALC_T_TMP, (void *) hxns);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
+
+ return res;
+}
+
+static Eterm hashmap_from_unsorted_array(ErtsHeapFactory* factory,
+ hxnode_t *hxns, Uint n,
+ int reject_dupkeys) {
+ Uint jx = 0, ix = 0, lx, cx;
+ Eterm res;
+
+ if (n == 0) {
+ Eterm *hp;
+ hp = erts_produce_heap(factory, 2, 0);
+ hp[0] = MAP_HEADER_HAMT_HEAD_BITMAP(0);
+ hp[1] = 0;
+
+ return make_hashmap(hp);
+ }
+
+ /* sort and compact array (remove non-unique entries) */
+ qsort(hxns, n, sizeof(hxnode_t), (int (*)(const void *, const void *)) hxnodecmp);
+
+ ix = 0, cx = 0;
+ while(ix < n - 1) {
+ if (hxns[ix].hx == hxns[ix+1].hx) {
+
+ /* find region of equal hash values */
+ jx = ix + 1;
+ while(jx < n && hxns[ix].hx == hxns[jx].hx) { jx++; }
+ /* find all correct keys from region
+ * (last in list but now hash sorted so we check highest id instead) */
+
+ /* resort with keys instead of hash value within region */
+
+ qsort(&hxns[ix], jx - ix, sizeof(hxnode_t),
+ (int (*)(const void *, const void *)) hxnodecmpkey);
+
+ while(ix < jx) {
+ lx = ix;
+ while(++ix < jx && EQ(CAR(list_val(hxns[ix].val)),
+ CAR(list_val(hxns[lx].val)))) {
+ if (reject_dupkeys)
+ return THE_NON_VALUE;
+
+ if (hxns[ix].i > hxns[lx].i) {
+ lx = ix;
+ }
}
- ks[idx] = kv[1];
- vs[idx] = kv[2];
- size++;
+ hxns[cx].hx = hxns[lx].hx;
+ hxns[cx].val = hxns[lx].val;
+ cx++;
}
- item = CDR(list_val(item));
+ ix = jx;
+ continue;
+ }
+ if (ix > cx) {
+ hxns[cx].hx = hxns[ix].hx;
+ hxns[cx].val = hxns[ix].val;
}
+ cx++;
+ ix++;
+ }
- if (unused_size) {
- /* the key tuple is embedded in the heap
- * write a bignum to clear it.
- */
- /* release values as normal since they are on the top of the heap */
+ if (ix < n) {
+ hxns[cx].hx = hxns[ix].hx;
+ hxns[cx].val = hxns[ix].val;
+ cx++;
+ }
- ks[size] = make_pos_bignum_header(unused_size - 1);
- HRelease(BIF_P, vs + size + unused_size, vs + size);
- }
+ if (cx > 1) {
+ /* recursive decompose array */
+ res = hashmap_from_sorted_unique_array(factory, hxns, cx, 0);
+ } else {
+ Eterm *hp;
- *thp = make_arityval(size);
- mp->size = size;
- BIF_RET(res);
+ /* we only have one item, either because n was 1 or
+ * because we hade multiples of the same key.
+ *
+ * hash value has been swizzled, need to drag it down to get the
+ * correct slot. */
+
+ hp = erts_produce_heap(factory, HAMT_HEAD_BITMAP_SZ(1), 0);
+ hp[0] = MAP_HEADER_HAMT_HEAD_BITMAP(1 << ((hxns[0].hx >> 0x1c) & 0xf));
+ hp[1] = 1;
+ hp[2] = hxns[0].val;
+ res = make_hashmap(hp);
}
-error:
+ return res;
+}
- BIF_ERROR(BIF_P, BADARG);
+static Eterm hashmap_from_sorted_unique_array(ErtsHeapFactory* factory,
+ hxnode_t *hxns, Uint n, int lvl) {
+ Eterm res = NIL;
+ Uint i,ix,jx,elems;
+ Uint32 sw, hx;
+ Eterm val;
+ hxnode_t *tmp;
+ DeclareTmpHeapNoproc(th,2);
+ UseTmpHeapNoproc(2);
+ ASSERT(lvl < 32);
+ ix = 0;
+ elems = 1;
+ while (ix < n - 1) {
+ if (hxns[ix].hx == hxns[ix+1].hx) {
+ jx = ix + 1;
+ while (jx < n && hxns[ix].hx == hxns[jx].hx) { jx++; }
+ tmp = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, ((jx - ix)) * sizeof(hxnode_t));
+
+ for(i = 0; i < jx - ix; i++) {
+ val = hxns[i + ix].val;
+ hx = hashmap_restore_hash(th, lvl + 8, CAR(list_val(val)));
+ swizzle32(sw,hx);
+ tmp[i].hx = sw;
+ tmp[i].val = val;
+ tmp[i].i = i;
+ tmp[i].skip = 1;
+ }
+
+ qsort(tmp, jx - ix, sizeof(hxnode_t), (int (*)(const void *, const void *)) hxnodecmp);
+
+ hxns[ix].skip = jx - ix;
+ hxns[ix].val = hashmap_from_sorted_unique_array(factory, tmp, jx - ix, lvl + 8);
+ erts_free(ERTS_ALC_T_TMP, (void *) tmp);
+ ix = jx;
+ if (ix < n) { elems++; }
+ continue;
+ }
+ hxns[ix].skip = 1;
+ elems++;
+ ix++;
+ }
+
+ res = hashmap_from_chunked_array(factory, hxns, elems, n, !lvl);
+
+ ERTS_FACTORY_HOLE_CHECK(factory);
+
+ UnUseTmpHeapNoproc(2);
+ return res;
}
-/* maps:is_key/2
- */
+#define HALLOC_EXTRA 200
+static Eterm hashmap_from_chunked_array(ErtsHeapFactory *factory, hxnode_t *hxns, Uint n,
+ Uint size, int is_root) {
+ Uint ix, d, dn, dc, slot, elems;
+ Uint32 v, vp, vn, hdr;
+ Uint bp, sz;
+ DECLARE_ESTACK(stack);
+ Eterm res = NIL, *hp = NULL, *nhp;
-BIF_RETTYPE maps_is_key_2(BIF_ALIST_2) {
- if (is_map(BIF_ARG_2)) {
- Eterm *ks, key;
- map_t *mp;
- Uint n,i;
- mp = (map_t*)map_val(BIF_ARG_2);
- key = BIF_ARG_1;
- n = map_get_size(mp);
- ks = map_get_keys(mp);
+ /* if we get here with only one element then
+ * we have eight levels of collisions
+ */
- if (n == 0)
- BIF_RET(am_false);
+ if (n == 1) {
+ res = hxns[0].val;
+ v = hxns[0].hx;
+ for (d = 7; d > 0; d--) {
+ slot = maskval(v,d);
+ hp = erts_produce_heap(factory, HAMT_NODE_BITMAP_SZ(1), HALLOC_EXTRA);
+ hp[0] = MAP_HEADER_HAMT_NODE_BITMAP(1 << slot);
+ hp[1] = res;
+ res = make_hashmap(hp);
+ }
- if (is_immed(key)) {
- for( i = 0; i < n; i++) {
- if (ks[i] == key) {
- BIF_RET(am_true);
- }
+ slot = maskval(v,0);
+ hp = erts_produce_heap(factory, (is_root ? 3 : 2), 0);
+
+ if (is_root) {
+ hp[0] = MAP_HEADER_HAMT_HEAD_BITMAP(1 << slot);
+ hp[1] = size;
+ hp[2] = res;
+ } else {
+ hp[0] = MAP_HEADER_HAMT_NODE_BITMAP(1 << slot);
+ hp[1] = res;
+ }
+ return make_hashmap(hp);
+ }
+
+ /* push initial nodes on the stack,
+ * this is the starting depth */
+
+ ix = 0;
+ d = 0;
+ vp = hxns[ix].hx;
+ v = hxns[ix + hxns[ix].skip].hx;
+
+ ASSERT(vp > v);
+ slot = maskval(vp,d);
+
+ while(slot == maskval(v,d)) {
+ ESTACK_PUSH(stack, 1 << slot);
+ d++;
+ slot = maskval(vp,d);
+ }
+
+ res = hxns[ix].val;
+
+ if (hxns[ix].skip > 1) {
+ dc = 7;
+ /* build collision nodes */
+ while (dc > d) {
+ hp = erts_produce_heap(factory, HAMT_NODE_BITMAP_SZ(1), HALLOC_EXTRA);
+ hp[0] = MAP_HEADER_HAMT_NODE_BITMAP(1 << maskval(vp,dc));
+ hp[1] = res;
+ res = make_hashmap(hp);
+ dc--;
+ }
+ }
+
+ ESTACK_PUSH2(stack,res,1 << slot);
+
+ /* all of the other nodes .. */
+ elems = n - 2; /* remove first and last elements */
+ while(elems--) {
+ hdr = ESTACK_POP(stack);
+ ix = ix + hxns[ix].skip;
+
+ /* determine if node or subtree should be built by looking
+ * at the next value. */
+
+ vn = hxns[ix + hxns[ix].skip].hx;
+ dn = cdepth(v,vn);
+ ASSERT(v > vn);
+
+ res = hxns[ix].val;
+
+ if (hxns[ix].skip > 1) {
+ int wat = (d > dn) ? d : dn;
+ dc = 7;
+ /* build collision nodes */
+ while (dc > wat) {
+ hp = erts_produce_heap(factory, HAMT_NODE_BITMAP_SZ(1), HALLOC_EXTRA);
+ hp[0] = MAP_HEADER_HAMT_NODE_BITMAP(1 << maskval(v,dc));
+ hp[1] = res;
+ res = make_hashmap(hp);
+ dc--;
}
}
- for( i = 0; i < n; i++) {
- if (EQ(ks[i], key)) {
- BIF_RET(am_true);
+ /* next depth is higher (implies collision) */
+ if (d < dn) {
+ /* hdr is the popped one initially */
+ while(d < dn) {
+ slot = maskval(v, d);
+ bp = 1 << slot;
+ ESTACK_PUSH(stack, hdr | bp);
+ d++;
+ hdr = 0; /* clear hdr for all other collisions */
}
+
+ slot = maskval(v, d);
+ bp = 1 << slot;
+ /* no more collisions */
+ ESTACK_PUSH2(stack,res,bp);
+ } else if (d == dn) {
+ /* no collisions at all */
+ slot = maskval(v, d);
+ bp = 1 << slot;
+ ESTACK_PUSH2(stack,res,hdr | bp);
+ } else {
+ /* dn < n, we have a drop and we are done
+ * build nodes and subtree */
+ while (dn != d) {
+ slot = maskval(v, d);
+ bp = 1 << slot;
+ /* OR bitposition before sz calculation to handle
+ * redundant collisions */
+ hdr |= bp;
+ sz = hashmap_bitcount(hdr);
+ hp = erts_produce_heap(factory, HAMT_NODE_BITMAP_SZ(sz), HALLOC_EXTRA);
+ nhp = hp;
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(hdr);
+ *hp++ = res; sz--;
+ while (sz--) { *hp++ = ESTACK_POP(stack); }
+ ASSERT((hp - nhp) < 18);
+ res = make_hashmap(nhp);
+
+ /* we need to pop the next hdr and push if we don't need it */
+
+ hdr = ESTACK_POP(stack);
+ d--;
+ }
+ ESTACK_PUSH2(stack,res,hdr);
+ }
+
+ vp = v;
+ v = vn;
+ d = dn;
+ ERTS_FACTORY_HOLE_CHECK(factory);
+ }
+
+ /* v and vp are reused from above */
+ dn = cdepth(vp,v);
+ ix = ix + hxns[ix].skip;
+ res = hxns[ix].val;
+
+ if (hxns[ix].skip > 1) {
+ dc = 7;
+ /* build collision nodes */
+ while (dc > dn) {
+ hp = erts_produce_heap(factory, HAMT_NODE_BITMAP_SZ(1), HALLOC_EXTRA);
+ hp[0] = MAP_HEADER_HAMT_NODE_BITMAP(1 << maskval(v,dc));
+ hp[1] = res;
+ res = make_hashmap(hp);
+ dc--;
}
- BIF_RET(am_false);
}
- BIF_ERROR(BIF_P, BADARG);
+
+ hdr = ESTACK_POP(stack);
+ /* pop remaining subtree if any */
+ while (dn) {
+ slot = maskval(v, dn);
+ bp = 1 << slot;
+ /* OR bitposition before sz calculation to handle
+ * redundant collisions */
+ hdr |= bp;
+ sz = hashmap_bitcount(hdr);
+ hp = erts_produce_heap(factory, HAMT_NODE_BITMAP_SZ(sz), HALLOC_EXTRA);
+ nhp = hp;
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(hdr);
+ *hp++ = res; sz--;
+
+ while (sz--) { *hp++ = ESTACK_POP(stack); }
+ res = make_hashmap(nhp);
+ hdr = ESTACK_POP(stack);
+ dn--;
+ }
+
+ /* and finally the root .. */
+
+ slot = maskval(v, dn);
+ bp = 1 << slot;
+ hdr |= bp;
+ sz = hashmap_bitcount(hdr);
+ hp = erts_produce_heap(factory, sz + /* hdr + item */ (is_root ? 2 : 1), 0);
+ nhp = hp;
+
+ if (is_root) {
+ *hp++ = (hdr == 0xffff) ? MAP_HEADER_HAMT_HEAD_ARRAY : MAP_HEADER_HAMT_HEAD_BITMAP(hdr);
+ *hp++ = size;
+ } else {
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(hdr);
+ }
+
+ *hp++ = res; sz--;
+ while (sz--) { *hp++ = ESTACK_POP(stack); }
+
+ res = make_hashmap(nhp);
+
+ ASSERT(ESTACK_COUNT(stack) == 0);
+ DESTROY_ESTACK(stack);
+ ERTS_FACTORY_HOLE_CHECK(factory);
+ return res;
+}
+#undef HALLOC_EXTRA
+
+static int hxnodecmpkey(hxnode_t *a, hxnode_t *b) {
+ Sint c = CMP_TERM(CAR(list_val(a->val)), CAR(list_val(b->val)));
+#if ERTS_SIZEOF_ETERM <= SIZEOF_INT
+ return c;
+#else
+ return c > 0 ? 1 : (c < 0 ? -1 : 0);
+#endif
}
-/* maps:keys/1
- */
+static int hxnodecmp(hxnode_t *a, hxnode_t *b) {
+ if (a->hx < b->hx)
+ return 1;
+ else if (a->hx == b->hx)
+ return 0;
+ else
+ return -1;
+}
+
+/* maps:is_key/2 */
+
+BIF_RETTYPE maps_is_key_2(BIF_ALIST_2) {
+ if (is_map(BIF_ARG_2)) {
+ BIF_RET(erts_maps_get(BIF_ARG_1, BIF_ARG_2) ? am_true : am_false);
+ }
+ BIF_P->fvalue = BIF_ARG_2;
+ BIF_ERROR(BIF_P, BADMAP);
+}
+
+/* maps:keys/1 */
BIF_RETTYPE maps_keys_1(BIF_ALIST_1) {
- if (is_map(BIF_ARG_1)) {
+ if (is_flatmap(BIF_ARG_1)) {
Eterm *hp, *ks, res = NIL;
- map_t *mp;
+ flatmap_t *mp;
Uint n;
- mp = (map_t*)map_val(BIF_ARG_1);
- n = map_get_size(mp);
+ mp = (flatmap_t*)flatmap_val(BIF_ARG_1);
+ n = flatmap_get_size(mp);
if (n == 0)
BIF_RET(res);
hp = HAlloc(BIF_P, (2 * n));
- ks = map_get_keys(mp);
+ ks = flatmap_get_keys(mp);
while(n--) {
res = CONS(hp, ks[n], res); hp += 2;
}
BIF_RET(res);
+ } else if (is_hashmap(BIF_ARG_1)) {
+ BIF_RET(hashmap_keys(BIF_P, BIF_ARG_1));
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
}
-/* maps:merge/2
- */
+
+/* maps:merge/2 */
+
+HIPE_WRAPPER_BIF_DISABLE_GC(maps_merge, 2)
BIF_RETTYPE maps_merge_2(BIF_ALIST_2) {
- if (is_map(BIF_ARG_1) && is_map(BIF_ARG_2)) {
- Eterm *hp,*thp;
- Eterm tup;
- Eterm *ks,*vs,*ks1,*vs1,*ks2,*vs2;
- map_t *mp1,*mp2,*mp_new;
- Uint n1,n2,i1,i2,need,unused_size=0;
- Sint c = 0;
+ if (is_flatmap(BIF_ARG_1)) {
+ if (is_flatmap(BIF_ARG_2)) {
+ BIF_RET(flatmap_merge(BIF_P, BIF_ARG_1, BIF_ARG_2));
+ } else if (is_hashmap(BIF_ARG_2)) {
+ /* Will always become a tree */
+ return map_merge_mixed(BIF_P, BIF_ARG_1, BIF_ARG_2, 0);
+ }
+ BIF_P->fvalue = BIF_ARG_2;
+ } else if (is_hashmap(BIF_ARG_1)) {
+ if (is_hashmap(BIF_ARG_2)) {
+ return hashmap_merge(BIF_P, BIF_ARG_1, BIF_ARG_2, 0, NULL);
+ } else if (is_flatmap(BIF_ARG_2)) {
+ /* Will always become a tree */
+ return map_merge_mixed(BIF_P, BIF_ARG_2, BIF_ARG_1, 1);
+ }
+ BIF_P->fvalue = BIF_ARG_2;
+ } else {
+ BIF_P->fvalue = BIF_ARG_1;
+ }
+ BIF_ERROR(BIF_P, BADMAP);
+}
- mp1 = (map_t*)map_val(BIF_ARG_1);
- mp2 = (map_t*)map_val(BIF_ARG_2);
- n1 = map_get_size(mp1);
- n2 = map_get_size(mp2);
+static Eterm flatmap_merge(Process *p, Eterm nodeA, Eterm nodeB) {
+ Eterm *hp,*thp;
+ Eterm tup;
+ Eterm *ks,*vs,*ks1,*vs1,*ks2,*vs2;
+ flatmap_t *mp1,*mp2,*mp_new;
+ Uint n,n1,n2,i1,i2,need,unused_size=0;
+ Sint c = 0;
- need = MAP_HEADER_SIZE + 1 + 2*(n1 + n2);
+ mp1 = (flatmap_t*)flatmap_val(nodeA);
+ mp2 = (flatmap_t*)flatmap_val(nodeB);
+ n1 = flatmap_get_size(mp1);
+ n2 = flatmap_get_size(mp2);
- hp = HAlloc(BIF_P, need);
- thp = hp;
- tup = make_tuple(thp);
- ks = hp + 1; hp += 1 + n1 + n2;
- mp_new = (map_t*)hp; hp += MAP_HEADER_SIZE;
- vs = hp; hp += n1 + n2;
-
- mp_new->thing_word = MAP_HEADER;
- mp_new->size = 0;
- mp_new->keys = tup;
-
- i1 = 0; i2 = 0;
- ks1 = map_get_keys(mp1);
- vs1 = map_get_values(mp1);
- ks2 = map_get_keys(mp2);
- vs2 = map_get_values(mp2);
-
- while(i1 < n1 && i2 < n2) {
- c = CMP_TERM(ks1[i1],ks2[i2]);
- if ( c == 0) {
- /* use righthand side arguments map value,
- * but advance both maps */
- *ks++ = ks2[i2];
- *vs++ = vs2[i2];
- i1++, i2++, unused_size++;
- } else if ( c < 0) {
- *ks++ = ks1[i1];
- *vs++ = vs1[i1];
- i1++;
- } else {
- *ks++ = ks2[i2];
- *vs++ = vs2[i2];
- i2++;
- }
- }
+ need = MAP_HEADER_FLATMAP_SZ + 1 + 2 * (n1 + n2);
- /* copy remaining */
- while (i1 < n1) {
+ hp = HAlloc(p, need);
+ thp = hp;
+ tup = make_tuple(thp);
+ ks = hp + 1; hp += 1 + n1 + n2;
+ mp_new = (flatmap_t*)hp; hp += MAP_HEADER_FLATMAP_SZ;
+ vs = hp; hp += n1 + n2;
+
+ mp_new->thing_word = MAP_HEADER_FLATMAP;
+ mp_new->size = 0;
+ mp_new->keys = tup;
+
+ i1 = 0; i2 = 0;
+ ks1 = flatmap_get_keys(mp1);
+ vs1 = flatmap_get_values(mp1);
+ ks2 = flatmap_get_keys(mp2);
+ vs2 = flatmap_get_values(mp2);
+
+ while(i1 < n1 && i2 < n2) {
+ c = CMP_TERM(ks1[i1],ks2[i2]);
+ if (c == 0) {
+ /* use righthand side arguments map value,
+ * but advance both maps */
+ *ks++ = ks2[i2];
+ *vs++ = vs2[i2];
+ i1++, i2++, unused_size++;
+ } else if (c < 0) {
*ks++ = ks1[i1];
*vs++ = vs1[i1];
i1++;
- }
-
- while (i2 < n2) {
+ } else {
*ks++ = ks2[i2];
*vs++ = vs2[i2];
i2++;
}
+ }
- if (unused_size) {
- /* the key tuple is embedded in the heap, write a bignum to clear it.
- *
- * release values as normal since they are on the top of the heap
- * size = n1 + n1 - unused_size
- */
+ /* copy remaining */
+ while (i1 < n1) {
+ *ks++ = ks1[i1];
+ *vs++ = vs1[i1];
+ i1++;
+ }
+
+ while (i2 < n2) {
+ *ks++ = ks2[i2];
+ *vs++ = vs2[i2];
+ i2++;
+ }
+
+ if (unused_size) {
+ /* the key tuple is embedded in the heap, write a bignum to clear it.
+ *
+ * release values as normal since they are on the top of the heap
+ * size = n1 + n1 - unused_size
+ */
+
+ *ks = make_pos_bignum_header(unused_size - 1);
+ HRelease(p, vs + unused_size, vs);
+ }
+
+ n = n1 + n2 - unused_size;
+ *thp = make_arityval(n);
+ mp_new->size = n;
+
+ /* Reshape map to a hashmap if the map exceeds the limit */
+
+ if (n > MAP_SMALL_MAP_LIMIT) {
+ Uint32 hx,sw;
+ Uint i;
+ Eterm res;
+ hxnode_t *hxns;
+ ErtsHeapFactory factory;
+
+ ks = flatmap_get_keys(mp_new);
+ vs = flatmap_get_values(mp_new);
+
+ hp = HAlloc(p, 2 * n);
- *ks = make_pos_bignum_header(unused_size - 1);
- HRelease(BIF_P, vs + unused_size, vs);
+ hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP,n * sizeof(hxnode_t));
+
+ for (i = 0; i < n; i++) {
+ hx = hashmap_make_hash(ks[i]);
+ swizzle32(sw,hx);
+ hxns[i].hx = sw;
+ hxns[i].val = CONS(hp, ks[i], vs[i]); hp += 2;
+ hxns[i].skip = 1;
+ hxns[i].i = i;
}
- mp_new->size = n1 + n2 - unused_size;
- *thp = make_arityval(n1 + n2 - unused_size);
+ erts_factory_proc_init(&factory, p);
+ res = hashmap_from_unsorted_array(&factory, hxns, n, 0);
+ erts_factory_close(&factory);
+
+ erts_free(ERTS_ALC_T_TMP, (void *) hxns);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
- BIF_RET(make_map(mp_new));
+ return res;
}
- BIF_ERROR(BIF_P, BADARG);
+
+ return make_flatmap(mp_new);
}
-/* maps:new/2
- */
-BIF_RETTYPE maps_new_0(BIF_ALIST_0) {
- Eterm* hp;
- Eterm tup;
- map_t *mp;
+static Eterm map_merge_mixed(Process *p, Eterm flat, Eterm tree, int swap_args) {
+ Eterm *ks, *vs, *hp, res;
+ flatmap_t *mp;
+ Uint n, i;
+ hxnode_t *hxns;
+ Uint32 sw, hx;
+ ErtsHeapFactory factory;
- hp = HAlloc(BIF_P, (MAP_HEADER_SIZE + 1));
- tup = make_tuple(hp);
- *hp++ = make_arityval(0);
+ /* convert flat to tree */
- mp = (map_t*)hp;
- mp->thing_word = MAP_HEADER;
- mp->size = 0;
- mp->keys = tup;
+ ASSERT(is_flatmap(flat));
+ ASSERT(is_hashmap(tree));
+
+ mp = (flatmap_t*)flatmap_val(flat);
+ n = flatmap_get_size(mp);
+
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+
+ hp = HAlloc(p, 2 * n);
+
+ hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(hxnode_t));
- BIF_RET(make_map(mp));
+ for (i = 0; i < n; i++) {
+ hx = hashmap_make_hash(ks[i]);
+ swizzle32(sw,hx);
+ hxns[i].hx = sw;
+ hxns[i].val = CONS(hp, ks[i], vs[i]); hp += 2;
+ hxns[i].skip = 1;
+ hxns[i].i = i;
+ }
+
+ erts_factory_proc_init(&factory, p);
+ res = hashmap_from_unsorted_array(&factory, hxns, n, 0);
+ erts_factory_close(&factory);
+
+ erts_free(ERTS_ALC_T_TMP, (void *) hxns);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
+
+ return hashmap_merge(p, res, tree, swap_args, NULL);
}
-/* maps:put/3
- */
+#define PSTACK_TYPE struct HashmapMergePStackType
+struct HashmapMergePStackType {
+ Eterm nodeA, nodeB;
+ Eterm *srcA, *srcB;
+ Uint32 abm, bbm, rbm; /* node bitmaps */
+ int mix; /* &1: there are unique A stuff in node
+ * &2: there are unique B stuff in node */
+ int ix;
+ Eterm array[16]; /* temp node construction area */
+};
+
+typedef struct HashmapMergeContext_ {
+ Uint size; /* total key-value counter */
+ unsigned int lvl;
+ Eterm trap_bin;
+ ErtsPStack pstack;
+#ifdef DEBUG
+ Eterm dbg_map_A, dbg_map_B;
+#endif
+} HashmapMergeContext;
-Eterm erts_maps_put(Process *p, Eterm key, Eterm value, Eterm map) {
- Sint n,i;
- Sint c = 0;
- Eterm* hp, *shp;
- Eterm *ks,*vs, res, tup;
- map_t *mp = (map_t*)map_val(map);
+static void hashmap_merge_ctx_destructor(Binary* ctx_bin)
+{
+ HashmapMergeContext* ctx = (HashmapMergeContext*) ERTS_MAGIC_BIN_DATA(ctx_bin);
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(ctx_bin) == hashmap_merge_ctx_destructor);
- n = map_get_size(mp);
+ PSTACK_DESTROY_SAVED(&ctx->pstack);
+}
- if (n == 0) {
- hp = HAlloc(p, MAP_HEADER_SIZE + 1 + 2);
- tup = make_tuple(hp);
- *hp++ = make_arityval(1);
- *hp++ = key;
- res = make_map(hp);
- *hp++ = MAP_HEADER;
- *hp++ = 1;
- *hp++ = tup;
- *hp++ = value;
+BIF_RETTYPE maps_merge_trap_1(BIF_ALIST_1) {
+ Binary* ctx_bin = ((ProcBin *) binary_val(BIF_ARG_1))->val;
- return res;
- }
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(ctx_bin) == hashmap_merge_ctx_destructor);
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
+ return hashmap_merge(BIF_P, NIL, NIL, 0,
+ (HashmapMergeContext*) ERTS_MAGIC_BIN_DATA(ctx_bin));
+}
- /* only allocate for values,
- * assume key-tuple will be intact
+#define HALLOC_EXTRA 200
+#define MAP_MERGE_LOOP_FACTOR 8
+
+static BIF_RETTYPE hashmap_merge(Process *p, Eterm map_A, Eterm map_B,
+ int swap_args, HashmapMergeContext* ctx) {
+#define PSTACK_TYPE struct HashmapMergePStackType
+ PSTACK_DECLARE(s, 4);
+ HashmapMergeContext local_ctx;
+ struct HashmapMergePStackType* sp;
+ Uint32 hx;
+ Eterm res = THE_NON_VALUE;
+ Eterm hdrA, hdrB;
+ Eterm *hp, *nhp;
+ Eterm trap_ret;
+ Sint initial_reds = (Sint) (ERTS_BIF_REDS_LEFT(p) * MAP_MERGE_LOOP_FACTOR);
+ Sint reds = initial_reds;
+ DeclareTmpHeap(th,2,p);
+ UseTmpHeap(2,p);
+
+ /*
+ * Strategy: Do depth-first traversal of both trees (at the same time)
+ * and merge each pair of nodes.
*/
- hp = HAlloc(p, MAP_HEADER_SIZE + n);
- shp = hp; /* save hp, used if optimistic update fails */
- res = make_map(hp);
- *hp++ = MAP_HEADER;
- *hp++ = n;
- *hp++ = mp->keys;
-
- if (is_immed(key)) {
- for( i = 0; i < n; i ++) {
- if (ks[i] == key) {
- *hp++ = value;
- vs++;
- c = 1;
- } else {
- *hp++ = *vs++;
+ PSTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
+
+ if (ctx == NULL) { /* first call */
+ hashmap_head_t* a = (hashmap_head_t*) hashmap_val(map_A);
+ hashmap_head_t* b = (hashmap_head_t*) hashmap_val(map_B);
+
+ sp = PSTACK_PUSH(s);
+ sp->srcA = swap_args ? &map_B : &map_A;
+ sp->srcB = swap_args ? &map_A : &map_B;
+ sp->mix = 0;
+ local_ctx.size = a->size + b->size;
+ local_ctx.lvl = 0;
+ #ifdef DEBUG
+ local_ctx.dbg_map_A = map_A;
+ local_ctx.dbg_map_B = map_B;
+ local_ctx.trap_bin = THE_NON_VALUE;
+ #endif
+ ctx = &local_ctx;
+ }
+ else {
+ PSTACK_RESTORE(s, &ctx->pstack);
+ sp = PSTACK_TOP(s);
+ goto resume_from_trap;
+ }
+
+recurse:
+
+ sp->nodeA = *sp->srcA;
+ sp->nodeB = *sp->srcB;
+
+ if (sp->nodeA == sp->nodeB) {
+ res = sp->nodeA;
+ ctx->size -= is_list(sp->nodeB) ? 1 : hashmap_subtree_size(sp->nodeB);
+ }
+ else {
+ if (is_list(sp->nodeA)) { /* A is LEAF */
+ Eterm keyA = CAR(list_val(sp->nodeA));
+
+ if (is_list(sp->nodeB)) { /* LEAF + LEAF */
+ Eterm keyB = CAR(list_val(sp->nodeB));
+
+ if (EQ(keyA, keyB)) {
+ --ctx->size;
+ res = sp->nodeB;
+ sp->mix = 2; /* We assume values differ.
+ + Don't spend time comparing big values.
+ - Might waste some heap space for internal
+ nodes that could otherwise be reused. */
+ goto merge_nodes;
+ }
+ }
+ hx = hashmap_restore_hash(th, ctx->lvl, keyA);
+ sp->abm = 1 << hashmap_index(hx);
+ /* keep srcA pointing at the leaf */
+ }
+ else { /* A is NODE */
+ sp->srcA = boxed_val(sp->nodeA);
+ hdrA = *sp->srcA++;
+ ASSERT(is_header(hdrA));
+ switch (hdrA & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY: {
+ sp->srcA++;
+ sp->abm = 0xffff;
+ break;
+ }
+ case HAMT_SUBTAG_HEAD_BITMAP: sp->srcA++;
+ case HAMT_SUBTAG_NODE_BITMAP: {
+ sp->abm = MAP_HEADER_VAL(hdrA);
+ break;
+ }
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "bad header %ld\r\n", hdrA);
+ }
+ }
+
+ if (is_list(sp->nodeB)) { /* B is LEAF */
+ Eterm keyB = CAR(list_val(sp->nodeB));
+
+ hx = hashmap_restore_hash(th, ctx->lvl, keyB);
+ sp->bbm = 1 << hashmap_index(hx);
+ /* keep srcB pointing at the leaf */
+ }
+ else { /* B is NODE */
+ sp->srcB = boxed_val(sp->nodeB);
+ hdrB = *sp->srcB++;
+ ASSERT(is_header(hdrB));
+ switch (hdrB & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY: {
+ sp->srcB++;
+ sp->bbm = 0xffff;
+ break;
+ }
+ case HAMT_SUBTAG_HEAD_BITMAP: sp->srcB++;
+ case HAMT_SUBTAG_NODE_BITMAP: {
+ sp->bbm = MAP_HEADER_VAL(hdrB);
+ break;
+ }
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "bad header %ld\r\n", hdrB);
+ }
+ }
+ }
+
+merge_nodes:
+
+ for (;;) {
+ if (is_value(res)) { /* We have a complete (sub-)tree or leaf */
+ int child_mix;
+ if (ctx->lvl == 0)
+ break;
+
+ /* Pop from stack and continue build parent node */
+ ctx->lvl--;
+ child_mix = sp->mix;
+ sp = PSTACK_POP(s);
+ sp->array[sp->ix++] = res;
+ sp->mix |= child_mix;
+ res = THE_NON_VALUE;
+ if (sp->rbm) {
+ sp->srcA++;
+ sp->srcB++;
}
+ } else { /* Start build a node */
+ sp->ix = 0;
+ sp->rbm = sp->abm | sp->bbm;
+ ASSERT(!(sp->rbm == 0 && ctx->lvl > 0));
}
- } else {
- for( i = 0; i < n; i ++) {
- if (EQ(ks[i], key)) {
- *hp++ = value;
- vs++;
- c = 1;
+
+ if (--reds <= 0) {
+ goto trap;
+ }
+resume_from_trap:
+
+ while (sp->rbm) {
+ Uint32 next = sp->rbm & (sp->rbm-1);
+ Uint32 bit = sp->rbm ^ next;
+ sp->rbm = next;
+ if (sp->abm & bit) {
+ if (sp->bbm & bit) {
+ /* Bit clash. Push and resolve by recursive merge */
+ Eterm* srcA = sp->srcA;
+ Eterm* srcB = sp->srcB;
+ ctx->lvl++;
+ sp = PSTACK_PUSH(s);
+ sp->srcA = srcA;
+ sp->srcB = srcB;
+ sp->mix = 0;
+ goto recurse;
+ } else {
+ sp->array[sp->ix++] = *sp->srcA++;
+ sp->mix |= 1;
+ }
} else {
- *hp++ = *vs++;
+ ASSERT(sp->bbm & bit);
+ sp->array[sp->ix++] = *sp->srcB++;
+ sp->mix |= 2;
}
}
+
+ switch (sp->mix) {
+ case 0: /* Nodes A and B contain the *EXACT* same sub-trees
+ => fall through and reuse nodeA */
+
+ case 1: /* Only unique A stuff => reuse nodeA */
+ res = sp->nodeA;
+ break;
+
+ case 2: /* Only unique B stuff => reuse nodeB */
+ res = sp->nodeB;
+ break;
+
+ case 3: /* We have a mix => must build new node */
+ ASSERT(sp->ix == hashmap_bitcount(sp->abm | sp->bbm));
+ if (ctx->lvl == 0) {
+ nhp = HAllocX(p, HAMT_HEAD_BITMAP_SZ(sp->ix), HALLOC_EXTRA);
+ hp = nhp;
+ *hp++ = (sp->ix == 16 ? MAP_HEADER_HAMT_HEAD_ARRAY
+ : MAP_HEADER_HAMT_HEAD_BITMAP(sp->abm | sp->bbm));
+ *hp++ = ctx->size;
+ } else {
+ nhp = HAllocX(p, HAMT_NODE_BITMAP_SZ(sp->ix), HALLOC_EXTRA);
+ hp = nhp;
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(sp->abm | sp->bbm);
+ }
+ sys_memcpy(hp, sp->array, sp->ix * sizeof(Eterm));
+ res = make_boxed(nhp);
+ break;
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "strange mix %d\r\n", sp->mix);
+ }
}
- if (c)
- return res;
+ /* Done */
- /* need to make a new tuple,
- * use old hp since it needs to be recreated anyway.
- */
- tup = make_tuple(shp);
- *shp++ = make_arityval(n+1);
+#ifdef DEBUG
+ {
+ Eterm *head = hashmap_val(res);
+ Uint size = head[1];
+ Uint real_size = hashmap_subtree_size(res);
+ ASSERT(size == real_size);
+ }
+#endif
- hp = HAlloc(p, 3 + n + 1);
- res = make_map(hp);
- *hp++ = MAP_HEADER;
- *hp++ = n + 1;
- *hp++ = tup;
+ if (ctx != &local_ctx) {
+ ASSERT(ctx->trap_bin != THE_NON_VALUE);
+ ASSERT(p->flags & F_DISABLE_GC);
+ erts_set_gc_state(p, 1);
+ }
+ else {
+ ASSERT(ctx->trap_bin == THE_NON_VALUE);
+ ASSERT(!(p->flags & F_DISABLE_GC));
+ }
+ PSTACK_DESTROY(s);
+ UnUseTmpHeap(2,p);
+ BUMP_REDS(p, (initial_reds - reds) / MAP_MERGE_LOOP_FACTOR);
+ return res;
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
+trap: /* Yield */
- ASSERT(n >= 0);
+ if (ctx == &local_ctx) {
+ Binary* ctx_b = erts_create_magic_binary(sizeof(HashmapMergeContext),
+ hashmap_merge_ctx_destructor);
+ ctx = ERTS_MAGIC_BIN_DATA(ctx_b);
+ sys_memcpy(ctx, &local_ctx, sizeof(HashmapMergeContext));
+ hp = HAlloc(p, PROC_BIN_SIZE);
+ ASSERT(ctx->trap_bin == THE_NON_VALUE);
+ ctx->trap_bin = erts_mk_magic_binary_term(&hp, &MSO(p), ctx_b);
- /* copy map in order */
- while (n && ((c = CMP_TERM(*ks, key)) < 0)) {
- *shp++ = *ks++;
- *hp++ = *vs++;
- n--;
+ erts_set_gc_state(p, 0);
+ }
+ else {
+ ASSERT(ctx->trap_bin != THE_NON_VALUE);
+ ASSERT(p->flags & F_DISABLE_GC);
}
- *shp++ = key;
- *hp++ = value;
+ PSTACK_SAVE(s, &ctx->pstack);
+
+ BUMP_ALL_REDS(p);
+ ERTS_BIF_PREP_TRAP1(trap_ret, &hashmap_merge_trap_export,
+ p, ctx->trap_bin);
+ UnUseTmpHeap(2,p);
+ return trap_ret;
+}
- ASSERT(n >= 0);
+static Uint hashmap_subtree_size(Eterm node) {
+ DECLARE_WSTACK(stack);
+ Uint size = 0;
- while(n--) {
- *shp++ = *ks++;
- *hp++ = *vs++;
+ hashmap_iterator_init(&stack, node, 0);
+ while (hashmap_iterator_next(&stack)) {
+ size++;
}
- /* we have one word remaining
- * this will work out fine once we get the size word
- * in the header.
- */
- *shp = make_pos_bignum_header(0);
- return res;
+ DESTROY_WSTACK(stack);
+ return size;
+}
+
+
+static int hash_cmp(Uint32 ha, Uint32 hb)
+{
+ int i;
+ for (i=0; i<8; i++) {
+ int cmp = (int)(ha & 0xF) - (int)(hb & 0xF);
+ if (cmp)
+ return cmp;
+ ha >>= 4;
+ hb >>= 4;
+ }
+ return 0;
+}
+
+int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp)
+{
+ unsigned int lvl = 0;
+ DeclareTmpHeapNoproc(th,2);
+ UseTmpHeapNoproc(2);
+
+ if (ap && bp) {
+ ASSERT(CMP_TERM(CAR(ap), CAR(bp)) != 0);
+ for (;;) {
+ Uint32 ha = hashmap_restore_hash(th, lvl, CAR(ap));
+ Uint32 hb = hashmap_restore_hash(th, lvl, CAR(bp));
+ int cmp = hash_cmp(ha, hb);
+ if (cmp) {
+ UnUseTmpHeapNoproc(2);
+ return cmp;
+ }
+ lvl += 8;
+ }
+ }
+ UnUseTmpHeapNoproc(2);
+ return ap ? -1 : 1;
}
+/* maps:new/0 */
+
+BIF_RETTYPE maps_new_0(BIF_ALIST_0) {
+ Eterm* hp;
+ Eterm tup;
+ flatmap_t *mp;
+
+ hp = HAlloc(BIF_P, (MAP_HEADER_FLATMAP_SZ + 1));
+ tup = make_tuple(hp);
+ *hp++ = make_arityval(0);
+
+ mp = (flatmap_t*)hp;
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = 0;
+ mp->keys = tup;
+
+ BIF_RET(make_flatmap(mp));
+}
+
+/* maps:put/3 */
+
BIF_RETTYPE maps_put_3(BIF_ALIST_3) {
if (is_map(BIF_ARG_3)) {
BIF_RET(erts_maps_put(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3));
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_3;
+ BIF_ERROR(BIF_P, BADMAP);
}
-/* maps:remove/3
- */
+/* maps:remove/3 */
int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res) {
- Sint n;
- Uint need;
- Eterm *hp_start;
- Eterm *thp, *mhp;
- Eterm *ks, *vs, tup;
- map_t *mp = (map_t*)map_val(map);
+ Uint32 hx;
+ if (is_flatmap(map)) {
+ Sint n;
+ Uint need;
+ Eterm *hp_start;
+ Eterm *thp, *mhp;
+ Eterm *ks, *vs, tup;
+ flatmap_t *mp = (flatmap_t*)flatmap_val(map);
+
+ n = flatmap_get_size(mp);
+
+ if (n == 0) {
+ *res = map;
+ return 1;
+ }
- n = map_get_size(mp);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
- if (n == 0) {
- *res = map;
- return 1;
- }
+ /* Assume key exists.
+ * Release allocated if it didn't.
+ * Allocate key tuple first.
+ */
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
+ need = n + 1 - 1 + 3 + n - 1; /* tuple - 1 + map - 1 */
+ hp_start = HAlloc(p, need);
+ thp = hp_start;
+ mhp = thp + n; /* offset with tuple heap size */
- /* Assume key exists.
- * Release allocated if it didn't.
- * Allocate key tuple first.
- */
+ tup = make_tuple(thp);
+ *thp++ = make_arityval(n - 1);
- need = n + 1 - 1 + 3 + n - 1; /* tuple - 1 + map - 1 */
- hp_start = HAlloc(p, need);
- thp = hp_start;
- mhp = thp + n; /* offset with tuple heap size */
+ *res = make_flatmap(mhp);
+ *mhp++ = MAP_HEADER_FLATMAP;
+ *mhp++ = n - 1;
+ *mhp++ = tup;
- tup = make_tuple(thp);
- *thp++ = make_arityval(n - 1);
-
- *res = make_map(mhp);
- *mhp++ = MAP_HEADER;
- *mhp++ = n - 1;
- *mhp++ = tup;
-
- if (is_immed(key)) {
- while (1) {
- if (*ks == key) {
- goto found_key;
- } else if (--n) {
- *mhp++ = *vs++;
- *thp++ = *ks++;
- } else
- break;
- }
- } else {
- while(1) {
- if (EQ(*ks, key)) {
- goto found_key;
- } else if (--n) {
- *mhp++ = *vs++;
- *thp++ = *ks++;
- } else
- break;
+ if (is_immed(key)) {
+ while (1) {
+ if (*ks == key) {
+ goto found_key;
+ } else if (--n) {
+ *mhp++ = *vs++;
+ *thp++ = *ks++;
+ } else
+ break;
+ }
+ } else {
+ while(1) {
+ if (EQ(*ks, key)) {
+ goto found_key;
+ } else if (--n) {
+ *mhp++ = *vs++;
+ *thp++ = *ks++;
+ } else
+ break;
+ }
}
- }
- /* Not found, remove allocated memory
- * and return previous map.
- */
- HRelease(p, hp_start + need, hp_start);
+ /* Not found, remove allocated memory
+ * and return previous map.
+ */
+ HRelease(p, hp_start + need, hp_start);
- *res = map;
- return 1;
+ *res = map;
+ return 1;
found_key:
- /* Copy rest of keys and values */
- if (--n) {
- sys_memcpy(mhp, vs+1, n*sizeof(Eterm));
- sys_memcpy(thp, ks+1, n*sizeof(Eterm));
+ /* Copy rest of keys and values */
+ if (--n) {
+ sys_memcpy(mhp, vs+1, n*sizeof(Eterm));
+ sys_memcpy(thp, ks+1, n*sizeof(Eterm));
+ }
+ return 1;
}
+ ASSERT(is_hashmap(map));
+ hx = hashmap_make_hash(key);
+ *res = hashmap_delete(p, hx, key, map);
return 1;
}
@@ -694,32 +1616,32 @@ BIF_RETTYPE maps_remove_2(BIF_ALIST_2) {
BIF_RET(res);
}
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_2;
+ BIF_ERROR(BIF_P, BADMAP);
}
-/* maps:update/3
- */
-
int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res) {
+ Uint32 hx;
+ if (is_flatmap(map)) {
Sint n,i;
Eterm* hp,*shp;
Eterm *ks,*vs;
- map_t *mp = (map_t*)map_val(map);
+ flatmap_t *mp = (flatmap_t*)flatmap_val(map);
- if ((n = map_get_size(mp)) == 0) {
+ if ((n = flatmap_get_size(mp)) == 0) {
return 0;
}
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
/* only allocate for values,
* assume key-tuple will be intact
*/
- hp = HAlloc(p, MAP_HEADER_SIZE + n);
+ hp = HAlloc(p, MAP_HEADER_FLATMAP_SZ + n);
shp = hp;
- *hp++ = MAP_HEADER;
+ *hp++ = MAP_HEADER_FLATMAP;
*hp++ = n;
*hp++ = mp->keys;
@@ -741,7 +1663,7 @@ int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res)
}
}
- HRelease(p, shp + MAP_HEADER_SIZE + n, shp);
+ HRelease(p, shp + MAP_HEADER_FLATMAP_SZ + n, shp);
return 0;
found_key:
@@ -749,53 +1671,940 @@ found_key:
vs++;
if (++i < n)
sys_memcpy(hp, vs, (n - i)*sizeof(Eterm));
- *res = make_map(shp);
+ *res = make_flatmap(shp);
+ return 1;
+ }
+
+ ASSERT(is_hashmap(map));
+ hx = hashmap_make_hash(key);
+ *res = erts_hashmap_insert(p, hx, key, value, map, 1);
+ if (is_value(*res))
return 1;
+
+ return 0;
+}
+
+Eterm erts_maps_put(Process *p, Eterm key, Eterm value, Eterm map) {
+ Uint32 hx;
+ Eterm res;
+ if (is_flatmap(map)) {
+ Sint n,i;
+ Sint c = 0;
+ Eterm* hp, *shp;
+ Eterm *ks, *vs, tup;
+ flatmap_t *mp = (flatmap_t*)flatmap_val(map);
+
+ n = flatmap_get_size(mp);
+
+ if (n == 0) {
+ hp = HAlloc(p, MAP_HEADER_FLATMAP_SZ + 1 + 2);
+ tup = make_tuple(hp);
+ *hp++ = make_arityval(1);
+ *hp++ = key;
+ res = make_flatmap(hp);
+ *hp++ = MAP_HEADER_FLATMAP;
+ *hp++ = 1;
+ *hp++ = tup;
+ *hp++ = value;
+
+ return res;
+ }
+
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+
+ /* only allocate for values,
+ * assume key-tuple will be intact
+ */
+
+ hp = HAlloc(p, MAP_HEADER_FLATMAP_SZ + n);
+ shp = hp; /* save hp, used if optimistic update fails */
+ res = make_flatmap(hp);
+ *hp++ = MAP_HEADER_FLATMAP;
+ *hp++ = n;
+ *hp++ = mp->keys;
+
+ if (is_immed(key)) {
+ for( i = 0; i < n; i ++) {
+ if (ks[i] == key) {
+ *hp++ = value;
+ vs++;
+ c = 1;
+ } else {
+ *hp++ = *vs++;
+ }
+ }
+ } else {
+ for( i = 0; i < n; i ++) {
+ if (EQ(ks[i], key)) {
+ *hp++ = value;
+ vs++;
+ c = 1;
+ } else {
+ *hp++ = *vs++;
+ }
+ }
+ }
+
+ if (c)
+ return res;
+
+ /* the map will grow */
+
+ if (n >= MAP_SMALL_MAP_LIMIT) {
+ HRelease(p, shp + MAP_HEADER_FLATMAP_SZ + n, shp);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+
+ res = erts_hashmap_from_ks_and_vs_extra(p,ks,vs,n,key,value);
+
+ return res;
+ }
+
+ /* still a small map. need to make a new tuple,
+ * use old hp since it needs to be recreated anyway. */
+
+ tup = make_tuple(shp);
+ *shp++ = make_arityval(n+1);
+
+ hp = HAlloc(p, 3 + n + 1);
+ res = make_flatmap(hp);
+ *hp++ = MAP_HEADER_FLATMAP;
+ *hp++ = n + 1;
+ *hp++ = tup;
+
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+
+ ASSERT(n >= 0);
+
+ /* copy map in order */
+ while (n && ((c = CMP_TERM(*ks, key)) < 0)) {
+ *shp++ = *ks++;
+ *hp++ = *vs++;
+ n--;
+ }
+
+ *shp++ = key;
+ *hp++ = value;
+
+ ASSERT(n >= 0);
+
+ while(n--) {
+ *shp++ = *ks++;
+ *hp++ = *vs++;
+ }
+ /* we have one word remaining
+ * this will work out fine once we get the size word
+ * in the header.
+ */
+ *shp = make_pos_bignum_header(0);
+ return res;
+ }
+ ASSERT(is_hashmap(map));
+
+ hx = hashmap_make_hash(key);
+ res = erts_hashmap_insert(p, hx, key, value, map, 0);
+ ASSERT(is_hashmap(res));
+
+ return res;
}
+/* maps:update/3 */
+
BIF_RETTYPE maps_update_3(BIF_ALIST_3) {
- if (is_map(BIF_ARG_3)) {
+ if (is_not_map(BIF_ARG_3)) {
+ BIF_P->fvalue = BIF_ARG_3;
+ BIF_ERROR(BIF_P, BADMAP);
+ } else {
Eterm res;
if (erts_maps_update(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3, &res)) {
BIF_RET(res);
}
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADKEY);
}
- BIF_ERROR(BIF_P, BADARG);
}
-/* maps:values/1
- */
+/* maps:values/1 */
BIF_RETTYPE maps_values_1(BIF_ALIST_1) {
- if (is_map(BIF_ARG_1)) {
+ if (is_flatmap(BIF_ARG_1)) {
Eterm *hp, *vs, res = NIL;
- map_t *mp;
+ flatmap_t *mp;
Uint n;
- mp = (map_t*)map_val(BIF_ARG_1);
- n = map_get_size(mp);
+ mp = (flatmap_t*)flatmap_val(BIF_ARG_1);
+ n = flatmap_get_size(mp);
if (n == 0)
BIF_RET(res);
hp = HAlloc(BIF_P, (2 * n));
- vs = map_get_values(mp);
+ vs = flatmap_get_values(mp);
while(n--) {
res = CONS(hp, vs[n], res); hp += 2;
}
BIF_RET(res);
+ } else if (is_hashmap(BIF_ARG_1)) {
+ BIF_RET(hashmap_values(BIF_P, BIF_ARG_1));
}
- BIF_ERROR(BIF_P, BADARG);
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
+}
+
+static Eterm hashmap_to_list(Process *p, Eterm node) {
+ DECLARE_WSTACK(stack);
+ Eterm *hp, *kv;
+ Eterm res = NIL;
+
+ hp = HAlloc(p, hashmap_size(node) * (2 + 3));
+ hashmap_iterator_init(&stack, node, 0);
+ while ((kv=hashmap_iterator_next(&stack)) != NULL) {
+ Eterm tup = TUPLE2(hp, CAR(kv), CDR(kv));
+ hp += 3;
+ res = CONS(hp, tup, res);
+ hp += 2;
+ }
+ DESTROY_WSTACK(stack);
+ return res;
+}
+
+void hashmap_iterator_init(ErtsWStack* s, Eterm node, int reverse) {
+ Eterm hdr = *hashmap_val(node);
+ Uint sz;
+
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ sz = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ case HAMT_SUBTAG_NODE_BITMAP:
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ break;
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "bad header");
+ }
+
+ WSTACK_PUSH3((*s), (UWord)THE_NON_VALUE, /* end marker */
+ (UWord)(!reverse ? 0 : sz+1),
+ (UWord)node);
}
-int erts_validate_and_sort_map(map_t* mp)
+Eterm* hashmap_iterator_next(ErtsWStack* s) {
+ Eterm node, *ptr, hdr;
+ Uint32 sz;
+ Uint idx;
+
+ for (;;) {
+ ASSERT(!WSTACK_ISEMPTY((*s)));
+ node = (Eterm) WSTACK_POP((*s));
+ if (is_non_value(node)) {
+ return NULL;
+ }
+ idx = (Uint) WSTACK_POP((*s));
+ for (;;) {
+ ASSERT(is_boxed(node));
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ ptr++;
+ sz = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ ptr++;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(sz < 17);
+ break;
+ default:
+ erts_exit(ERTS_ABORT_EXIT, "bad header");
+ }
+
+ idx++;
+
+ if (idx <= sz) {
+ WSTACK_PUSH2((*s), (UWord)idx, (UWord)node);
+
+ if (is_list(ptr[idx])) {
+ return list_val(ptr[idx]);
+ }
+ ASSERT(is_boxed(ptr[idx]));
+ node = ptr[idx];
+ idx = 0;
+ }
+ else
+ break; /* and pop parent node */
+ }
+ }
+}
+
+Eterm* hashmap_iterator_prev(ErtsWStack* s) {
+ Eterm node, *ptr, hdr;
+ Uint32 sz;
+ Uint idx;
+
+ for (;;) {
+ ASSERT(!WSTACK_ISEMPTY((*s)));
+ node = (Eterm) WSTACK_POP((*s));
+ if (is_non_value(node)) {
+ return NULL;
+ }
+ idx = (Uint) WSTACK_POP((*s));
+ for (;;) {
+ ASSERT(is_boxed(node));
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ ptr++;
+ sz = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ ptr++;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(sz < 17);
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header");
+ }
+
+ if (idx > sz)
+ idx = sz;
+ else
+ idx--;
+
+ if (idx >= 1) {
+ WSTACK_PUSH2((*s), (UWord)idx, (UWord)node);
+
+ if (is_list(ptr[idx])) {
+ return list_val(ptr[idx]);
+ }
+ ASSERT(is_boxed(ptr[idx]));
+ node = ptr[idx];
+ idx = 17;
+ }
+ else
+ break; /* and pop parent node */
+ }
+ }
+}
+
+const Eterm *
+#if HALFWORD_HEAP
+erts_hashmap_get_rel(Uint32 hx, Eterm key, Eterm node, Eterm *map_base)
+#else
+erts_hashmap_get(Uint32 hx, Eterm key, Eterm node)
+#endif
{
- Eterm *ks = map_get_keys(mp);
- Eterm *vs = map_get_values(mp);
- Uint sz = map_get_size(mp);
+ Eterm *ptr, hdr, *res;
+ Uint ix, lvl = 0;
+ Uint32 hval,bp;
+ DeclareTmpHeapNoproc(th,2);
+ UseTmpHeapNoproc(2);
+
+ ASSERT(is_boxed(node));
+ ptr = boxed_val_rel(node, map_base);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ ASSERT(is_hashmap_header_head(hdr));
+ ptr++;
+
+ for (;;) {
+ hval = MAP_HEADER_VAL(hdr);
+ ix = hashmap_index(hx);
+ if (hval != 0xffff) {
+ bp = 1 << ix;
+ if (!(bp & hval)) {
+ /* not occupied */
+ res = NULL;
+ break;
+ }
+ ix = hashmap_bitcount(hval & (bp - 1));
+ }
+ node = ptr[ix+1];
+
+ if (is_list(node)) { /* LEAF NODE [K|V] */
+ ptr = list_val_rel(node,map_base);
+ res = eq_rel(CAR(ptr), map_base, key, NULL) ? &(CDR(ptr)) : NULL;
+ break;
+ }
+
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+
+ ASSERT(is_boxed(node));
+ ptr = boxed_val_rel(node, map_base);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ ASSERT(!is_hashmap_header_head(hdr));
+ }
+
+ UnUseTmpHeapNoproc(2);
+ return res;
+}
+
+Eterm erts_hashmap_insert(Process *p, Uint32 hx, Eterm key, Eterm value,
+ Eterm map, int is_update) {
+ Uint size, upsz;
+ Eterm *hp, res = THE_NON_VALUE;
+ DECLARE_ESTACK(stack);
+ if (erts_hashmap_insert_down(hx, key, map, &size, &upsz, &stack, is_update)) {
+ hp = HAlloc(p, size);
+ res = erts_hashmap_insert_up(hp, key, value, &upsz, &stack);
+ }
+
+ DESTROY_ESTACK(stack);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
+ ERTS_HOLE_CHECK(p);
+
+ return res;
+}
+
+
+int erts_hashmap_insert_down(Uint32 hx, Eterm key, Eterm node, Uint *sz,
+ Uint *update_size, ErtsEStack *sp, int is_update) {
+ Eterm *ptr;
+ Eterm hdr, ckey;
+ Uint32 ix, cix, bp, hval, chx;
+ Uint slot, lvl = 0, clvl;
+ Uint size = 0, n = 0;
+ DeclareTmpHeapNoproc(th,2);
+
+ *update_size = 1;
+
+ UseTmpHeapNoproc(2);
+ for (;;) {
+ switch(primary_tag(node)) {
+ case TAG_PRIMARY_LIST: /* LEAF NODE [K|V] */
+ ptr = list_val(node);
+ ckey = CAR(ptr);
+ if (EQ(ckey, key)) {
+ *update_size = 0;
+ goto unroll;
+ }
+ if (is_update) {
+ UnUseTmpHeapNoproc(2);
+ return 0;
+ }
+ goto insert_subnodes;
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ ix = hashmap_index(hx);
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ size += HAMT_HEAD_ARRAY_SZ;
+ ESTACK_PUSH2(*sp, ix, node);
+ node = ptr[ix+2];
+ break;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ hval = MAP_HEADER_VAL(hdr);
+ ix = hashmap_index(hx);
+ bp = 1 << ix;
+ if (hval == 0xffff) {
+ slot = ix;
+ n = 16;
+ } else {
+ slot = hashmap_bitcount(hval & (bp - 1));
+ n = hashmap_bitcount(hval);
+ }
+
+ ESTACK_PUSH4(*sp, n, bp, slot, node);
+
+ if (!(bp & hval)) { /* not occupied */
+ if (is_update) {
+ UnUseTmpHeapNoproc(2);
+ return 0;
+ }
+ size += HAMT_NODE_BITMAP_SZ(n+1);
+ goto unroll;
+ }
+
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ node = ptr[slot+1];
+ ASSERT(HAMT_NODE_BITMAP_SZ(n) <= 17);
+ size += HAMT_NODE_BITMAP_SZ(n);
+ break;
+
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ hval = MAP_HEADER_VAL(hdr);
+ ix = hashmap_index(hx);
+ bp = 1 << ix;
+ slot = hashmap_bitcount(hval & (bp - 1));
+ n = hashmap_bitcount(hval);
+
+ ESTACK_PUSH4(*sp, n, bp, slot, node);
+
+ /* occupied */
+ if (bp & hval) {
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ node = ptr[slot+2];
+ ASSERT(HAMT_HEAD_BITMAP_SZ(n) <= 18);
+ size += HAMT_HEAD_BITMAP_SZ(n);
+ break;
+ }
+ /* not occupied */
+ if (is_update) {
+ UnUseTmpHeapNoproc(2);
+ return 0;
+ }
+ size += HAMT_HEAD_BITMAP_SZ(n+1);
+ goto unroll;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header tag %ld\r\n", hdr & _HEADER_MAP_SUBTAG_MASK);
+ break;
+ }
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad primary tag %p\r\n", node);
+ break;
+ }
+ }
+insert_subnodes:
+ clvl = lvl;
+ chx = hashmap_restore_hash(th,clvl,ckey);
+ size += HAMT_NODE_BITMAP_SZ(2);
+ ix = hashmap_index(hx);
+ cix = hashmap_index(chx);
+
+ while (cix == ix) {
+ ESTACK_PUSH4(*sp, 0, 1 << ix, 0, MAP_HEADER_HAMT_NODE_BITMAP(0));
+ size += HAMT_NODE_BITMAP_SZ(1);
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ chx = hashmap_shift_hash(th,chx,clvl,ckey);
+ ix = hashmap_index(hx);
+ cix = hashmap_index(chx);
+ }
+ ESTACK_PUSH3(*sp, cix, ix, node);
+
+unroll:
+ *sz = size + /* res cons */ 2;
+ UnUseTmpHeapNoproc(2);
+ return 1;
+}
+
+Eterm erts_hashmap_insert_up(Eterm *hp, Eterm key, Eterm value,
+ Uint *update_size, ErtsEStack *sp) {
+ Eterm node, *ptr, hdr;
+ Eterm res;
+ Eterm *nhp = NULL;
+ Uint32 ix, cix, bp, hval;
+ Uint slot, n;
+ /* Needed for halfword */
+ DeclareTmpHeapNoproc(fake,1);
+ UseTmpHeapNoproc(1);
+
+ res = CONS(hp, key, value); hp += 2;
+
+ do {
+ node = ESTACK_POP(*sp);
+ switch(primary_tag(node)) {
+ case TAG_PRIMARY_LIST:
+ ix = (Uint32) ESTACK_POP(*sp);
+ cix = (Uint32) ESTACK_POP(*sp);
+
+ nhp = hp;
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP((1 << ix) | (1 << cix));
+ if (ix < cix) {
+ *hp++ = res;
+ *hp++ = node;
+ } else {
+ *hp++ = node;
+ *hp++ = res;
+ }
+ res = make_hashmap(nhp);
+ break;
+ case TAG_PRIMARY_HEADER:
+ /* subnodes, fake it */
+ *fake = node;
+ node = make_boxed(fake);
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ slot = (Uint) ESTACK_POP(*sp);
+ nhp = hp;
+ n = HAMT_HEAD_ARRAY_SZ - 2;
+ *hp++ = MAP_HEADER_HAMT_HEAD_ARRAY; ptr++;
+ *hp++ = (*ptr++) + *update_size;
+ while(n--) { *hp++ = *ptr++; }
+ nhp[slot+2] = res;
+ res = make_hashmap(nhp);
+ break;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ slot = (Uint) ESTACK_POP(*sp);
+ bp = (Uint32) ESTACK_POP(*sp);
+ n = (Uint32) ESTACK_POP(*sp);
+ hval = MAP_HEADER_VAL(hdr);
+ nhp = hp;
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(hval | bp); ptr++;
+
+ n -= slot;
+ while(slot--) { *hp++ = *ptr++; }
+ *hp++ = res;
+ if (hval & bp) { ptr++; n--; }
+ while(n--) { *hp++ = *ptr++; }
+
+ res = make_hashmap(nhp);
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ slot = (Uint) ESTACK_POP(*sp);
+ bp = (Uint32) ESTACK_POP(*sp);
+ n = (Uint32) ESTACK_POP(*sp);
+ hval = MAP_HEADER_VAL(hdr);
+ nhp = hp;
+ *hp++ = MAP_HEADER_HAMT_HEAD_BITMAP(hval | bp); ptr++;
+ *hp++ = (*ptr++) + *update_size;
+
+ n -= slot;
+ while(slot--) { *hp++ = *ptr++; }
+ *hp++ = res;
+ if (hval & bp) { ptr++; n--; }
+ while(n--) { *hp++ = *ptr++; }
+
+ if ((hval | bp) == 0xffff) {
+ *nhp = MAP_HEADER_HAMT_HEAD_ARRAY;
+ }
+ res = make_hashmap(nhp);
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header tag %x\r\n", hdr & _HEADER_MAP_SUBTAG_MASK);
+ break;
+ }
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad primary tag %x\r\n", primary_tag(node));
+ break;
+ }
+
+ } while(!ESTACK_ISEMPTY(*sp));
+
+ UnUseTmpHeapNoproc(1);
+ return res;
+}
+
+static Eterm hashmap_keys(Process* p, Eterm node) {
+ DECLARE_WSTACK(stack);
+ hashmap_head_t* root;
+ Eterm *hp, *kv;
+ Eterm res = NIL;
+
+ root = (hashmap_head_t*) boxed_val(node);
+ hp = HAlloc(p, root->size * 2);
+ hashmap_iterator_init(&stack, node, 0);
+ while ((kv=hashmap_iterator_next(&stack)) != NULL) {
+ res = CONS(hp, CAR(kv), res);
+ hp += 2;
+ }
+ DESTROY_WSTACK(stack);
+ return res;
+}
+
+static Eterm hashmap_values(Process* p, Eterm node) {
+ DECLARE_WSTACK(stack);
+ hashmap_head_t* root;
+ Eterm *hp, *kv;
+ Eterm res = NIL;
+
+ root = (hashmap_head_t*) boxed_val(node);
+ hp = HAlloc(p, root->size * 2);
+ hashmap_iterator_init(&stack, node, 0);
+ while ((kv=hashmap_iterator_next(&stack)) != NULL) {
+ res = CONS(hp, CDR(kv), res);
+ hp += 2;
+ }
+ DESTROY_WSTACK(stack);
+ return res;
+}
+
+static Eterm hashmap_delete(Process *p, Uint32 hx, Eterm key, Eterm map) {
+ Eterm *hp = NULL, *nhp = NULL, *hp_end = NULL;
+ Eterm *ptr;
+ Eterm hdr, res = map, node = map;
+ Uint32 ix, bp, hval;
+ Uint slot, lvl = 0;
+ Uint size = 0, n = 0;
+ DECLARE_ESTACK(stack);
+ DeclareTmpHeapNoproc(th,2);
+ UseTmpHeapNoproc(2);
+
+ for (;;) {
+ switch(primary_tag(node)) {
+ case TAG_PRIMARY_LIST:
+ if (EQ(CAR(list_val(node)), key)) {
+ goto unroll;
+ }
+ goto not_found;
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ ix = hashmap_index(hx);
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ size += HAMT_HEAD_ARRAY_SZ;
+ ESTACK_PUSH2(stack, ix, node);
+ node = ptr[ix+2];
+ break;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ hval = MAP_HEADER_VAL(hdr);
+ ix = hashmap_index(hx);
+ bp = 1 << ix;
+ if (hval == 0xffff) {
+ slot = ix;
+ n = 16;
+ } else if (bp & hval) {
+ slot = hashmap_bitcount(hval & (bp - 1));
+ n = hashmap_bitcount(hval);
+ } else {
+ /* not occupied */
+ goto not_found;
+ }
+
+ ESTACK_PUSH4(stack, n, bp, slot, node);
+
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ node = ptr[slot+1];
+ ASSERT(HAMT_NODE_BITMAP_SZ(n) <= 17);
+ size += HAMT_NODE_BITMAP_SZ(n);
+ break;
+
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ hval = MAP_HEADER_VAL(hdr);
+ ix = hashmap_index(hx);
+ bp = 1 << ix;
+ slot = hashmap_bitcount(hval & (bp - 1));
+ n = hashmap_bitcount(hval);
+
+ ESTACK_PUSH4(stack, n, bp, slot, node);
+
+ /* occupied */
+ if (bp & hval) {
+ hx = hashmap_shift_hash(th,hx,lvl,key);
+ node = ptr[slot+2];
+ ASSERT(HAMT_HEAD_BITMAP_SZ(n) <= 18);
+ size += HAMT_HEAD_BITMAP_SZ(n);
+ break;
+ }
+ /* not occupied */
+ goto not_found;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header tag %ld\r\n", hdr & _HEADER_MAP_SUBTAG_MASK);
+ break;
+ }
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad primary tag %p\r\n", node);
+ break;
+ }
+ }
+
+unroll:
+ /* the size is bounded and atleast one less than the previous size */
+ size -= 1;
+ n = hashmap_size(map) - 1;
+
+ if (n <= MAP_SMALL_MAP_LIMIT) {
+ DECLARE_WSTACK(wstack);
+ Eterm *kv, *ks, *vs;
+ flatmap_t *mp;
+ Eterm keys;
+
+ DESTROY_ESTACK(stack);
+
+ /* build flat structure */
+ hp = HAlloc(p, 3 + 1 + (2 * n));
+ keys = make_tuple(hp);
+ *hp++ = make_arityval(n);
+ ks = hp;
+ hp += n;
+ mp = (flatmap_t*)hp;
+ hp += MAP_HEADER_FLATMAP_SZ;
+ vs = hp;
+
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = n;
+ mp->keys = keys;
+
+ hashmap_iterator_init(&wstack, map, 0);
+
+ while ((kv=hashmap_iterator_next(&wstack)) != NULL) {
+ if (EQ(CAR(kv),key))
+ continue;
+ *ks++ = CAR(kv);
+ *vs++ = CDR(kv);
+ }
+
+ /* it cannot have multiple keys */
+ erts_validate_and_sort_flatmap(mp);
+
+ DESTROY_WSTACK(wstack);
+ UnUseTmpHeapNoproc(2);
+ return make_flatmap(mp);
+ }
+
+ hp = HAlloc(p, size);
+ hp_end = hp + size;
+ res = THE_NON_VALUE;
+
+ do {
+ node = ESTACK_POP(stack);
+
+ /* all nodes are things */
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ ix = (Uint) ESTACK_POP(stack);
+ nhp = hp;
+ if (res == THE_NON_VALUE) {
+ n = 16;
+ n -= ix;
+ *hp++ = MAP_HEADER_HAMT_HEAD_BITMAP(0xffff ^ (1 << ix)); ptr++;
+ *hp++ = (*ptr++) - 1;
+ while(ix--) { *hp++ = *ptr++; }
+ ptr++; n--;
+ while(n--) { *hp++ = *ptr++; }
+ res = make_hashmap(nhp);
+ } else {
+ n = 16;
+ *hp++ = MAP_HEADER_HAMT_HEAD_ARRAY; ptr++;
+ *hp++ = (*ptr++) - 1;
+ while(n--) { *hp++ = *ptr++; }
+ nhp[ix+2] = res;
+ res = make_hashmap(nhp);
+ }
+ break;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ slot = (Uint) ESTACK_POP(stack);
+ bp = (Uint32) ESTACK_POP(stack);
+ n = (Uint32) ESTACK_POP(stack);
+ nhp = hp;
+
+ /* bitmap change matrix
+ * res | none leaf bitmap
+ * ----------------------------
+ * n=1 | remove remove keep
+ * n=2 | other keep keep
+ * n>2 | shrink keep keep
+ *
+ * other: (remember, n is 2)
+ * shrink if the other bitmap value is a bitmap node
+ * remove if the other bitmap value is a leaf
+ *
+ * remove:
+ * this bitmap node is removed, res is moved up in tree (could be none)
+ * this is a special case of shrink
+ *
+ * keep:
+ * the current path index is still used down in the tree, need to keep it
+ * copy as usual with the updated res
+ *
+ * shrink:
+ * the current path index is no longer used down in the tree, remove it (shrink)
+ */
+ if (res == THE_NON_VALUE) {
+ if (n == 1) {
+ break;
+ } else if (n == 2) {
+ if (slot == 0) {
+ ix = 2; /* off by one 'cause hdr */
+ } else {
+ ix = 1; /* off by one 'cause hdr */
+ }
+ if (primary_tag(ptr[ix]) == TAG_PRIMARY_LIST) {
+ res = ptr[ix];
+ } else {
+ hval = MAP_HEADER_VAL(hdr);
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(hval ^ bp);
+ *hp++ = ptr[ix];
+ res = make_hashmap(nhp);
+ }
+ } else {
+ /* n > 2 */
+ hval = MAP_HEADER_VAL(hdr);
+ *hp++ = MAP_HEADER_HAMT_NODE_BITMAP(hval ^ bp); ptr++;
+ n -= slot;
+ while(slot--) { *hp++ = *ptr++; }
+ ptr++; n--;
+ while(n--) { *hp++ = *ptr++; }
+ res = make_hashmap(nhp);
+ }
+ } else if (primary_tag(res) == TAG_PRIMARY_LIST && n == 1) {
+ break;
+ } else {
+ /* res is bitmap or leaf && n > 1, keep */
+ n -= slot;
+ *hp++ = *ptr++;
+ while(slot--) { *hp++ = *ptr++; }
+ *hp++ = res;
+ ptr++; n--;
+ while(n--) { *hp++ = *ptr++; }
+ res = make_hashmap(nhp);
+ }
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ slot = (Uint) ESTACK_POP(stack);
+ bp = (Uint32) ESTACK_POP(stack);
+ n = (Uint32) ESTACK_POP(stack);
+ nhp = hp;
+
+ if (res != THE_NON_VALUE) {
+ *hp++ = *ptr++;
+ *hp++ = (*ptr++) - 1;
+ n -= slot;
+ while(slot--) { *hp++ = *ptr++; }
+ *hp++ = res;
+ ptr++; n--;
+ while(n--) { *hp++ = *ptr++; }
+ } else {
+ hval = MAP_HEADER_VAL(hdr);
+ *hp++ = MAP_HEADER_HAMT_HEAD_BITMAP(hval ^ bp); ptr++;
+ *hp++ = (*ptr++) - 1;
+ n -= slot;
+ while(slot--) { *hp++ = *ptr++; }
+ ptr++; n--;
+ while(n--) { *hp++ = *ptr++; }
+ }
+ res = make_hashmap(nhp);
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header tag %x\r\n", hdr & _HEADER_MAP_SUBTAG_MASK);
+ break;
+ }
+ } while(!ESTACK_ISEMPTY(stack));
+ HRelease(p, hp_end, hp);
+not_found:
+ DESTROY_ESTACK(stack);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
+ ERTS_HOLE_CHECK(p);
+ UnUseTmpHeapNoproc(2);
+ return res;
+}
+
+
+int erts_validate_and_sort_flatmap(flatmap_t* mp)
+{
+ Eterm *ks = flatmap_get_keys(mp);
+ Eterm *vs = flatmap_get_values(mp);
+ Uint sz = flatmap_get_size(mp);
Uint ix,jx;
Eterm tmp;
Sint c;
@@ -822,6 +2631,62 @@ int erts_validate_and_sort_map(map_t* mp)
return 1;
}
+#if 0 /* Can't get myself to remove this beautiful piece of code
+ for probabilistic overestimation of nr of nodes in a hashmap */
+
+/* Really rough estimate of sqrt(x)
+ * Guaranteed not to be less than sqrt(x)
+ */
+static int int_sqrt_ceiling(Uint x)
+{
+ int n;
+
+ if (x <= 2)
+ return x;
+
+ n = erts_fit_in_bits_uint(x-1);
+ if (n & 1) {
+ /* Calc: sqrt(2^n) = 2^(n/2) * sqrt(2) ~= 2^(n/2) * 3 / 2 */
+ return (1 << (n/2 - 1)) * 3;
+ }
+ else {
+ /* Calc: sqrt(2^n) = 2^(n/2) */
+ return 1 << (n / 2);
+ }
+}
+
+/* May not be enough if hashing is broken (not uniform)
+ * or if hell freezes over.
+ */
+Uint hashmap_overestimated_node_count(Uint k)
+{
+ /* k is nr of key-value pairs.
+ N(k) is expected nr of nodes in hamt.
+
+ Observation:
+ For uniformly distributed hash values, average of N varies between
+ 0.3*k and 0.4*k (with a beautiful sine curve)
+ and standard deviation of N is about sqrt(k)/3.
+
+ Assuming normal probability distribution, we overestimate nr of nodes
+ by 15 std.devs above the average, which gives a probability for overrun
+ less than 1.0e-49 (same magnitude as a git SHA1 collision).
+ */
+ return 2*k/5 + 1 + (15/3)*int_sqrt_ceiling(k);
+}
+#endif
+
+BIF_RETTYPE erts_debug_map_info_1(BIF_ALIST_1) {
+ if (is_hashmap(BIF_ARG_1)) {
+ BIF_RET(hashmap_info(BIF_P,BIF_ARG_1));
+ } else if (is_flatmap(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P, BADARG);
+ } else {
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
+ }
+}
+
/*
* erts_internal:map_to_tuple_keys/1
*
@@ -829,9 +2694,225 @@ int erts_validate_and_sort_map(map_t* mp)
*/
BIF_RETTYPE erts_internal_map_to_tuple_keys_1(BIF_ALIST_1) {
- if (is_map(BIF_ARG_1)) {
- map_t *mp = (map_t*)map_val(BIF_ARG_1);
+ if (is_flatmap(BIF_ARG_1)) {
+ flatmap_t *mp = (flatmap_t*)flatmap_val(BIF_ARG_1);
BIF_RET(mp->keys);
+ } else if (is_hashmap(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P, BADARG);
+ } else {
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
}
- BIF_ERROR(BIF_P, BADARG);
}
+
+/*
+ * erts_internal:map_type/1
+ *
+ * Used in erts_debug:size/1
+ */
+
+BIF_RETTYPE erts_internal_map_type_1(BIF_ALIST_1) {
+ DECL_AM(hashmap);
+ DECL_AM(hashmap_node);
+ DECL_AM(flatmap);
+ if (is_map(BIF_ARG_1)) {
+ Eterm hdr = *(boxed_val(BIF_ARG_1));
+ ASSERT(is_header(hdr));
+ switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_FLATMAP:
+ BIF_RET(AM_flatmap);
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ BIF_RET(AM_hashmap);
+ case HAMT_SUBTAG_NODE_BITMAP:
+ BIF_RET(AM_hashmap_node);
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header");
+ }
+ }
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
+}
+
+/*
+ * erts_internal:map_hashmap_children/1
+ *
+ * Used in erts_debug:size/1
+ */
+
+BIF_RETTYPE erts_internal_map_hashmap_children_1(BIF_ALIST_1) {
+ if (is_map(BIF_ARG_1)) {
+ Eterm node = BIF_ARG_1;
+ Eterm *ptr, hdr, *hp, res = NIL;
+ Uint sz = 0;
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_FLATMAP:
+ BIF_ERROR(BIF_P, BADARG);
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ ptr++;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ ptr++;
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ break;
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ sz = 16;
+ ptr += 2;
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
+ break;
+ }
+ ASSERT(sz < 17);
+ hp = HAlloc(BIF_P, 2*sz);
+ while(sz--) { res = CONS(hp, *ptr++, res); hp += 2; }
+ BIF_RET(res);
+ }
+ BIF_P->fvalue = BIF_ARG_1;
+ BIF_ERROR(BIF_P, BADMAP);
+}
+
+
+static Eterm hashmap_info(Process *p, Eterm node) {
+ Eterm *hp;
+ Eterm res = NIL, info = NIL;
+ Eterm *ptr, tup, hdr;
+ Uint sz;
+ DECL_AM(depth);
+ DECL_AM(leafs);
+ DECL_AM(bitmaps);
+ DECL_AM(arrays);
+ Uint nleaf=0, nbitmap=0, narray=0;
+ Uint bitmap_usage[16], leaf_usage[16];
+ Uint lvl = 0, clvl;
+ DECLARE_ESTACK(stack);
+
+ for (sz = 0; sz < 16; sz++) {
+ bitmap_usage[sz] = 0;
+ leaf_usage[sz] = 0;
+ }
+
+ ptr = boxed_val(node);
+ ESTACK_PUSH(stack, 0);
+ ESTACK_PUSH(stack, node);
+ do {
+ node = ESTACK_POP(stack);
+ clvl = ESTACK_POP(stack);
+ if (lvl < clvl)
+ lvl = clvl;
+ switch(primary_tag(node)) {
+ case TAG_PRIMARY_LIST:
+ nleaf++;
+ leaf_usage[clvl] += 1;
+ break;
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_NODE_BITMAP:
+ nbitmap++;
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(sz < 17);
+ bitmap_usage[sz-1] += 1;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+1]);
+ }
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ nbitmap++;
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ bitmap_usage[sz-1] += 1;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+2]);
+ }
+ break;
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ narray++;
+ sz = 16;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+2]);
+ }
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
+ break;
+ }
+ }
+ } while(!ESTACK_ISEMPTY(stack));
+
+
+ /* size */
+ sz = 0;
+ hashmap_bld_tuple_uint(NULL,&sz,16,leaf_usage);
+ hashmap_bld_tuple_uint(NULL,&sz,16,bitmap_usage);
+
+ /* alloc */
+ hp = HAlloc(p, 2+3 + 3*(2+4) + sz);
+
+ info = hashmap_bld_tuple_uint(&hp,NULL,16,leaf_usage);
+ tup = TUPLE3(hp, AM_leafs, make_small(nleaf),info); hp += 4;
+ res = CONS(hp, tup, res); hp += 2;
+
+ info = hashmap_bld_tuple_uint(&hp,NULL,16,bitmap_usage);
+ tup = TUPLE3(hp, AM_bitmaps, make_small(nbitmap), info); hp += 4;
+ res = CONS(hp, tup, res); hp += 2;
+
+ tup = TUPLE3(hp, AM_arrays, make_small(narray),NIL); hp += 4;
+ res = CONS(hp, tup, res); hp += 2;
+
+ tup = TUPLE2(hp, AM_depth, make_small(lvl)); hp += 3;
+ res = CONS(hp, tup, res); hp += 2;
+
+ DESTROY_ESTACK(stack);
+ ERTS_HOLE_CHECK(p);
+ return res;
+}
+
+static Eterm hashmap_bld_tuple_uint(Uint **hpp, Uint *szp, Uint n, Uint nums[]) {
+ Eterm res = THE_NON_VALUE;
+ Eterm *ts = (Eterm *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(Eterm));
+ Uint i;
+
+ for (i = 0; i < n; i++) {
+ ts[i] = erts_bld_uint(hpp, szp, nums[i]);
+ }
+ res = erts_bld_tuplev(hpp, szp, n, ts);
+ erts_free(ERTS_ALC_T_TMP, (void *) ts);
+ return res;
+}
+
+
+/* implementation of builtin emulations */
+
+#if !ERTS_AT_LEAST_GCC_VSN__(3, 4, 0)
+/* Count leading zeros emulation */
+Uint32 hashmap_clz(Uint32 x) {
+ Uint32 y;
+ int n = 32;
+ y = x >>16; if (y != 0) {n = n -16; x = y;}
+ y = x >> 8; if (y != 0) {n = n - 8; x = y;}
+ y = x >> 4; if (y != 0) {n = n - 4; x = y;}
+ y = x >> 2; if (y != 0) {n = n - 2; x = y;}
+ y = x >> 1; if (y != 0) return n - 2;
+ return n - x;
+}
+
+const Uint32 SK5 = 0x55555555, SK3 = 0x33333333;
+const Uint32 SKF0 = 0xF0F0F0F, SKFF = 0xFF00FF;
+
+/* CTPOP emulation */
+Uint32 hashmap_bitcount(Uint32 x) {
+ x -= ((x >> 1 ) & SK5);
+ x = (x & SK3 ) + ((x >> 2 ) & SK3 );
+ x = (x & SKF0) + ((x >> 4 ) & SKF0);
+ x += x >> 8;
+ return (x + (x >> 16)) & 0x3F;
+}
+#endif
diff --git a/erts/emulator/beam/erl_map.h b/erts/emulator/beam/erl_map.h
index cfacb2ec28..4d9d74bc37 100644
--- a/erts/emulator/beam/erl_map.h
+++ b/erts/emulator/beam/erl_map.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -22,13 +23,23 @@
#define __ERL_MAP_H__
#include "sys.h"
+
+/* instrinsic wrappers */
+#if ERTS_AT_LEAST_GCC_VSN__(3, 4, 0)
+#define hashmap_clz(x) ((Uint32) __builtin_clz((unsigned int)(x)))
+#define hashmap_bitcount(x) ((Uint32) __builtin_popcount((unsigned int) (x)))
+#else
+Uint32 hashmap_clz(Uint32 x);
+Uint32 hashmap_bitcount(Uint32 x);
+#endif
+
/* MAP */
-typedef struct map_s {
+typedef struct flatmap_s {
Eterm thing_word;
Uint size;
Eterm keys; /* tuple */
-} map_t;
+} flatmap_t;
/* map node
*
* -----------
@@ -42,31 +53,159 @@ typedef struct map_s {
* -----------
*/
+/* the head-node is a bitmap or array with an untagged size */
+
+
+#define hashmap_size(x) (((hashmap_head_t*) hashmap_val(x))->size)
+#define hashmap_size_rel(RTERM, BASE) hashmap_size(rterm2wterm(RTERM, BASE))
+#define hashmap_make_hash(Key) make_internal_hash(Key)
+
+#define hashmap_restore_hash(Heap,Lvl,Key) \
+ (((Lvl) < 8) ? hashmap_make_hash(Key) >> (4*(Lvl)) : hashmap_make_hash(CONS(Heap, make_small((Lvl)>>3), (Key))) >> (4*((Lvl) & 7)))
+#define hashmap_shift_hash(Heap,Hx,Lvl,Key) \
+ (((++(Lvl)) & 7) ? (Hx) >> 4 : hashmap_make_hash(CONS(Heap, make_small((Lvl)>>3), Key)))
/* erl_term.h stuff */
-#define make_map(x) make_boxed((Eterm*)(x))
-#define make_map_rel(x, BASE) make_boxed_rel((Eterm*)(x),(BASE))
-#define is_map(x) (is_boxed((x)) && is_map_header(*boxed_val((x))))
-#define is_map_rel(RTERM,BASE) is_map(rterm2wterm(RTERM,BASE))
-#define is_not_map(x) (!is_map((x)))
-#define is_map_header(x) (((x) & (_TAG_HEADER_MASK)) == _TAG_HEADER_MAP)
-#define header_is_map(x) ((((x) & (_HEADER_SUBTAG_MASK)) == MAP_SUBTAG))
-#define map_val(x) (_unchecked_boxed_val((x)))
-#define map_val_rel(RTERM, BASE) map_val(rterm2wterm(RTERM, BASE))
-
-#define map_get_values(x) (((Eterm *)(x)) + 3)
-#define map_get_keys(x) (((Eterm *)tuple_val(((map_t *)(x))->keys)) + 1)
-#define map_get_size(x) (((map_t*)(x))->size)
-
-#define MAP_HEADER _make_header(1,_TAG_HEADER_MAP)
-#define MAP_HEADER_SIZE (sizeof(map_t) / sizeof(Eterm))
-
-Eterm erts_maps_put(Process *p, Eterm key, Eterm value, Eterm map);
-int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res);
-int erts_maps_find(Eterm key, Eterm map, Eterm *value);
-int erts_maps_get(Eterm key, Eterm map, Eterm *value);
-int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res);
-int erts_validate_and_sort_map(map_t* map);
+#define flatmap_get_values(x) (((Eterm *)(x)) + 3)
+#define flatmap_get_keys(x) (((Eterm *)tuple_val(((flatmap_t *)(x))->keys)) + 1)
+#define flatmap_get_size(x) (((flatmap_t*)(x))->size)
+
+#ifdef DEBUG
+#define MAP_SMALL_MAP_LIMIT (3)
+#else
+#define MAP_SMALL_MAP_LIMIT (32)
#endif
+struct ErtsWStack_;
+struct ErtsEStack_;
+
+Eterm erts_maps_put(Process *p, Eterm key, Eterm value, Eterm map);
+int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res);
+int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res);
+
+Eterm erts_hashmap_insert(Process *p, Uint32 hx, Eterm key, Eterm value,
+ Eterm node, int is_update);
+int erts_hashmap_insert_down(Uint32 hx, Eterm key, Eterm node, Uint *sz,
+ Uint *upsz, struct ErtsEStack_ *sp, int is_update);
+Eterm erts_hashmap_insert_up(Eterm *hp, Eterm key, Eterm value,
+ Uint *upsz, struct ErtsEStack_ *sp);
+
+int erts_validate_and_sort_flatmap(flatmap_t* map);
+void hashmap_iterator_init(struct ErtsWStack_* s, Eterm node, int reverse);
+Eterm* hashmap_iterator_next(struct ErtsWStack_* s);
+Eterm* hashmap_iterator_prev(struct ErtsWStack_* s);
+int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp);
+Eterm erts_hashmap_from_array(ErtsHeapFactory*, Eterm *leafs, Uint n, int reject_dupkeys);
+
+#define erts_hashmap_from_ks_and_vs(P, KS, VS, N) \
+ erts_hashmap_from_ks_and_vs_extra((P), (KS), (VS), (N), THE_NON_VALUE, THE_NON_VALUE);
+
+Eterm erts_hashmap_from_ks_and_vs_extra(Process *p, Eterm *ks, Eterm *vs, Uint n,
+ Eterm k, Eterm v);
+
+const Eterm *
+#if HALFWORD_HEAP
+erts_maps_get_rel(Eterm key, Eterm map, Eterm *map_base);
+# define erts_maps_get(A, B) erts_maps_get_rel(A, B, NULL)
+#else
+erts_maps_get(Eterm key, Eterm map);
+# define erts_maps_get_rel(A, B, B_BASE) erts_maps_get(A, B)
+#endif
+
+const Eterm *
+#if HALFWORD_HEAP
+erts_hashmap_get_rel(Uint32 hx, Eterm key, Eterm node, Eterm *map_base);
+# define erts_hashmap_get(Hx, K, M) erts_hashmap_get_rel(Hx, K, M, NULL)
+#else
+erts_hashmap_get(Uint32 hx, Eterm key, Eterm map);
+# define erts_hashmap_get_rel(Hx, K, M, M_BASE) erts_hashmap_get(Hx, K, M)
+#endif
+
+/* hamt nodes v2.0
+ *
+ * node :: leaf | array | bitmap
+ * head
+ */
+typedef struct hashmap_head_s {
+ Eterm thing_word;
+ Uint size;
+ Eterm items[1];
+} hashmap_head_t;
+
+/* thing_word tagscheme
+ * Need two bits for map subtags
+ *
+ * Original HEADER representation:
+ *
+ * aaaaaaaaaaaaaaaa aaaaaaaaaatttt00 arity:26, tag:4
+ *
+ * For maps we have:
+ *
+ * vvvvvvvvvvvvvvvv aaaaaaaamm111100 val:16, arity:8, mtype:2
+ *
+ * unsure about trailing zeros
+ *
+ * map-tag:
+ * 00 - flat map tag (non-hamt) -> val:16 = #items
+ * 01 - map-node bitmap tag -> val:16 = bitmap
+ * 10 - map-head (array-node) -> val:16 = 0xffff
+ * 11 - map-head (bitmap-node) -> val:16 = bitmap
+ */
+
+/* erl_map.h stuff */
+
+#define is_hashmap_header_head(x) ((MAP_HEADER_TYPE(x) & (0x2)))
+
+#define MAKE_MAP_HEADER(Type,Arity,Val) \
+ (_make_header(((((Uint16)(Val)) << MAP_HEADER_ARITY_SZ) | (Arity)) << MAP_HEADER_TAG_SZ | (Type) , _TAG_HEADER_MAP))
+
+#define MAP_HEADER_FLATMAP \
+ MAKE_MAP_HEADER(MAP_HEADER_TAG_FLATMAP_HEAD,0x1,0x0)
+
+#define MAP_HEADER_HAMT_HEAD_ARRAY \
+ MAKE_MAP_HEADER(MAP_HEADER_TAG_HAMT_HEAD_ARRAY,0x1,0xffff)
+
+#define MAP_HEADER_HAMT_HEAD_BITMAP(Bmp) \
+ MAKE_MAP_HEADER(MAP_HEADER_TAG_HAMT_HEAD_BITMAP,0x1,Bmp)
+
+#define MAP_HEADER_HAMT_NODE_BITMAP(Bmp) \
+ MAKE_MAP_HEADER(MAP_HEADER_TAG_HAMT_NODE_BITMAP,0x0,Bmp)
+
+#define MAP_HEADER_FLATMAP_SZ (sizeof(flatmap_t) / sizeof(Eterm))
+
+#define HAMT_NODE_ARRAY_SZ (17)
+#define HAMT_HEAD_ARRAY_SZ (18)
+#define HAMT_NODE_BITMAP_SZ(n) (1 + n)
+#define HAMT_HEAD_BITMAP_SZ(n) (2 + n)
+
+/* 2 bits maps tag + 4 bits subtag + 2 ignore bits */
+#define _HEADER_MAP_SUBTAG_MASK (0xfc)
+/* 1 bit map tag + 1 ignore bit + 4 bits subtag + 2 ignore bits */
+#define _HEADER_MAP_HASHMAP_HEAD_MASK (0xbc)
+
+#define HAMT_SUBTAG_NODE_BITMAP ((MAP_HEADER_TAG_HAMT_NODE_BITMAP << _HEADER_ARITY_OFFS) | MAP_SUBTAG)
+#define HAMT_SUBTAG_HEAD_ARRAY ((MAP_HEADER_TAG_HAMT_HEAD_ARRAY << _HEADER_ARITY_OFFS) | MAP_SUBTAG)
+#define HAMT_SUBTAG_HEAD_BITMAP ((MAP_HEADER_TAG_HAMT_HEAD_BITMAP << _HEADER_ARITY_OFFS) | MAP_SUBTAG)
+#define HAMT_SUBTAG_HEAD_FLATMAP ((MAP_HEADER_TAG_FLATMAP_HEAD << _HEADER_ARITY_OFFS) | MAP_SUBTAG)
+
+#define hashmap_index(hash) (((Uint32)hash) & 0xf)
+
+/* hashmap heap size:
+ [one cons cell + one list term in parent node] per key
+ [one header + one boxed term in parent node] per inner node
+ [one header + one size word] for root node
+ Observed average number of nodes per key is about 0.35.
+*/
+#define HASHMAP_WORDS_PER_KEY 3
+#define HASHMAP_WORDS_PER_NODE 2
+#ifdef DEBUG
+# define HASHMAP_ESTIMATED_TOT_NODE_SIZE(KEYS) \
+ (HASHMAP_WORDS_PER_NODE * (KEYS) * 3/10) /* slightly under estimated */
+#else
+# define HASHMAP_ESTIMATED_TOT_NODE_SIZE(KEYS) \
+ (HASHMAP_WORDS_PER_NODE * (KEYS) * 4/10) /* slightly over estimated */
+#endif
+#define HASHMAP_ESTIMATED_HEAP_SIZE(KEYS) \
+ ((KEYS)*HASHMAP_WORDS_PER_KEY + HASHMAP_ESTIMATED_TOT_NODE_SIZE(KEYS))
+#endif
diff --git a/erts/emulator/beam/erl_math.c b/erts/emulator/beam/erl_math.c
index 16d4fdc09c..b46cc37495 100644
--- a/erts/emulator/beam/erl_math.c
+++ b/erts/emulator/beam/erl_math.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -207,6 +208,24 @@ BIF_RETTYPE math_log_1(BIF_ALIST_1)
return math_call_1(BIF_P, log, BIF_ARG_1);
}
+#ifdef HAVE_LOG2
+static double
+log2_wrapper(double x)
+{
+ return log2(x);
+}
+#else
+static double
+log2_wrapper(double x)
+{
+ return log(x) / 0.6931471805599453; /* log(2.0); */
+}
+#endif
+
+BIF_RETTYPE math_log2_1(BIF_ALIST_1)
+{
+ return math_call_1(BIF_P, log2_wrapper, BIF_ARG_1);
+}
BIF_RETTYPE math_log10_1(BIF_ALIST_1)
{
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 8870fac7d9..fa6b2fc613 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -93,9 +94,6 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
#endif
ErlHeapFragment* nbp;
- /* ToDo: Make use of 'used_size' to avoid realloc
- when shrinking just a few words */
-
#ifdef DEBUG
{
Uint off_sz = size < bp->used_size ? size : bp->used_size;
@@ -110,8 +108,10 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
}
#endif
- if (size == bp->used_size)
+ if (size >= (bp->used_size - bp->used_size / 16)) {
+ bp->used_size = size;
return bp;
+ }
#ifdef HARD_DEBUG
dbg_brefs = erts_alloc(ERTS_ALC_T_UNDEF, sizeof(Eterm *)*brefs_size);
@@ -237,8 +237,7 @@ erts_msg_distext2heap(Process *pp,
Eterm msg;
Uint tok_sz = 0;
Eterm *hp = NULL;
- Eterm *hp_end = NULL;
- ErlOffHeap *ohp;
+ ErtsHeapFactory factory;
Sint sz;
*bpp = NULL;
@@ -250,36 +249,26 @@ erts_msg_distext2heap(Process *pp,
tok_sz = heap_frag->used_size;
sz += tok_sz;
}
- if (pp)
+ if (pp) {
+ ErlOffHeap *ohp;
hp = erts_alloc_message_heap(sz, bpp, &ohp, pp, plcksp);
+ }
else {
*bpp = new_message_buffer(sz);
hp = (*bpp)->mem;
- ohp = &(*bpp)->off_heap;
}
- hp_end = hp + sz;
- msg = erts_decode_dist_ext(&hp, ohp, dist_extp);
+ erts_factory_message_init(&factory, pp, hp, *bpp);
+ msg = erts_decode_dist_ext(&factory, dist_extp);
if (is_non_value(msg))
goto decode_error;
if (is_not_nil(*tokenp)) {
ErlHeapFragment *heap_frag = erts_dist_ext_trailer(dist_extp);
- *tokenp = copy_struct(*tokenp, tok_sz, &hp, ohp);
+ hp = erts_produce_heap(&factory, tok_sz, 0);
+ *tokenp = copy_struct(*tokenp, tok_sz, &hp, factory.off_heap);
erts_cleanup_offheap(&heap_frag->off_heap);
}
erts_free_dist_ext_copy(dist_extp);
- if (hp_end != hp) {
- if (!(*bpp)) {
- HRelease(pp, hp_end, hp);
- }
- else {
- Uint final_size = hp - &(*bpp)->mem[0];
- Eterm brefs[2] = {msg, *tokenp};
- ASSERT(sz - (hp_end - hp) == final_size);
- *bpp = erts_resize_message_buffer(*bpp, final_size, &brefs[0], 2);
- msg = brefs[0];
- *tokenp = brefs[1];
- }
- }
+ erts_factory_close(&factory);
return msg;
decode_error:
@@ -288,13 +277,7 @@ erts_msg_distext2heap(Process *pp,
erts_cleanup_offheap(&heap_frag->off_heap);
}
erts_free_dist_ext_copy(dist_extp);
- if (*bpp) {
- free_message_buffer(*bpp);
- *bpp = NULL;
- }
- else if (hp) {
- HRelease(pp, hp_end, hp);
- }
+ *bpp = NULL;
return THE_NON_VALUE;
}
@@ -369,11 +352,7 @@ erts_queue_dist_message(Process *rcvr,
tok_label, tok_lastcnt, tok_serial);
}
#endif
- erts_queue_message(rcvr, rcvr_locks, mbuf, msg, token
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rcvr, rcvr_locks, mbuf, msg, token);
}
else {
/* Enqueue message on external format */
@@ -563,15 +542,15 @@ queue_message(Process *c_p,
}
void
-erts_queue_message(Process* receiver,
- ErtsProcLocks *receiver_locks,
- ErlHeapFragment* bp,
- Eterm message,
- Eterm seq_trace_token
#ifdef USE_VM_PROBES
- , Eterm dt_utag
+erts_queue_message_probe(Process* receiver, ErtsProcLocks *receiver_locks,
+ ErlHeapFragment* bp,
+ Eterm message, Eterm seq_trace_token, Eterm dt_utag)
+#else
+erts_queue_message(Process* receiver, ErtsProcLocks *receiver_locks,
+ ErlHeapFragment* bp,
+ Eterm message, Eterm seq_trace_token)
#endif
- )
{
queue_message(NULL,
receiver,
@@ -855,10 +834,11 @@ erts_msg_attached_data_size_aux(ErlMessage *msg)
}
void
-erts_move_msg_attached_data_to_heap(Eterm **hpp, ErlOffHeap *ohp, ErlMessage *msg)
+erts_move_msg_attached_data_to_heap(ErtsHeapFactory* factory,
+ ErlMessage *msg)
{
if (is_value(ERL_MESSAGE_TERM(msg)))
- erts_move_msg_mbuf_to_heap(hpp, ohp, msg);
+ erts_move_msg_mbuf_to_heap(&factory->hp, factory->off_heap, msg);
else if (msg->data.dist_ext) {
ASSERT(msg->data.dist_ext->heap_size >= 0);
if (is_not_nil(ERL_MESSAGE_TOKEN(msg))) {
@@ -866,12 +846,11 @@ erts_move_msg_attached_data_to_heap(Eterm **hpp, ErlOffHeap *ohp, ErlMessage *ms
heap_frag = erts_dist_ext_trailer(msg->data.dist_ext);
ERL_MESSAGE_TOKEN(msg) = copy_struct(ERL_MESSAGE_TOKEN(msg),
heap_frag->used_size,
- hpp,
- ohp);
+ &factory->hp,
+ factory->off_heap);
erts_cleanup_offheap(&heap_frag->off_heap);
}
- ERL_MESSAGE_TERM(msg) = erts_decode_dist_ext(hpp,
- ohp,
+ ERL_MESSAGE_TERM(msg) = erts_decode_dist_ext(factory,
msg->data.dist_ext);
erts_free_dist_ext_copy(msg->data.dist_ext);
msg->data.dist_ext = NULL;
@@ -1117,11 +1096,7 @@ erts_deliver_exit_message(Eterm from, Process *to, ErtsProcLocks *to_locksp,
/* the trace token must in this case be updated by the caller */
seq_trace_output(token, save, SEQ_TRACE_SEND, to->common.id, NULL);
temptoken = copy_struct(token, sz_token, &hp, &bp->off_heap);
- erts_queue_message(to, to_locksp, bp, save, temptoken
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(to, to_locksp, bp, save, temptoken);
} else {
ErlOffHeap *ohp;
sz_reason = size_object(reason);
@@ -1138,11 +1113,313 @@ erts_deliver_exit_message(Eterm from, Process *to, ErtsProcLocks *to_locksp,
? from
: copy_struct(from, sz_from, &hp, ohp));
save = TUPLE3(hp, am_EXIT, from_copy, mess);
- erts_queue_message(to, to_locksp, bp, save, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(to, to_locksp, bp, save, NIL);
+ }
+}
+
+void erts_factory_proc_init(ErtsHeapFactory* factory,
+ Process* p)
+{
+ erts_factory_proc_prealloc_init(factory, p, HEAP_LIMIT(p) - HEAP_TOP(p));
+}
+
+void erts_factory_proc_prealloc_init(ErtsHeapFactory* factory,
+ Process* p,
+ Sint size)
+{
+ factory->mode = FACTORY_HALLOC;
+ factory->p = p;
+ factory->hp_start = HAlloc(p, size);
+ factory->hp = factory->hp_start;
+ factory->hp_end = factory->hp_start + size;
+ factory->off_heap = &p->off_heap;
+ factory->off_heap_saved.first = p->off_heap.first;
+ factory->off_heap_saved.overhead = p->off_heap.overhead;
+ factory->heap_frags_saved = p->mbuf;
+ factory->heap_frags = NULL; /* not used */
+ factory->alloc_type = 0; /* not used */
+}
+
+void erts_factory_message_init(ErtsHeapFactory* factory,
+ Process* rp,
+ Eterm* hp,
+ ErlHeapFragment* bp)
+{
+ if (bp) {
+ factory->mode = FACTORY_HEAP_FRAGS;
+ factory->p = NULL;
+ factory->hp_start = bp->mem;
+ factory->hp = hp ? hp : bp->mem;
+ factory->hp_end = bp->mem + bp->alloc_size;
+ factory->off_heap = &bp->off_heap;
+ factory->heap_frags = bp;
+ factory->heap_frags_saved = bp;
+ factory->alloc_type = ERTS_ALC_T_HEAP_FRAG;
+ ASSERT(!bp->next);
+ }
+ else {
+ factory->mode = FACTORY_HALLOC;
+ factory->p = rp;
+ factory->hp_start = hp;
+ factory->hp = hp;
+ factory->hp_end = HEAP_TOP(rp);
+ factory->off_heap = &rp->off_heap;
+ factory->heap_frags_saved = rp->mbuf;
+ factory->heap_frags = NULL; /* not used */
+ factory->alloc_type = 0; /* not used */
+ }
+ factory->off_heap_saved.first = factory->off_heap->first;
+ factory->off_heap_saved.overhead = factory->off_heap->overhead;
+
+ ASSERT(factory->hp >= factory->hp_start && factory->hp <= factory->hp_end);
+}
+
+/* One static sized heap that must suffice.
+ No extra heap fragments will be allocated.
+*/
+void erts_factory_static_init(ErtsHeapFactory* factory,
+ Eterm* hp,
+ Uint size,
+ ErlOffHeap* off_heap)
+{
+ factory->mode = FACTORY_STATIC;
+ factory->hp_start = hp;
+ factory->hp = hp;
+ factory->hp_end = hp + size;
+ factory->off_heap = off_heap;
+ factory->off_heap_saved.first = factory->off_heap->first;
+ factory->off_heap_saved.overhead = factory->off_heap->overhead;
+}
+
+/* A temporary heap with default buffer allocated/freed by client.
+ * factory_close is same as factory_undo
+ */
+void erts_factory_tmp_init(ErtsHeapFactory* factory, Eterm* hp, Uint size,
+ Uint32 atype)
+{
+ factory->mode = FACTORY_TMP;
+ factory->hp_start = hp;
+ factory->hp = hp;
+ factory->hp_end = hp + size;
+ factory->heap_frags = NULL;
+ factory->off_heap_saved.first = NULL;
+ factory->off_heap_saved.overhead = 0;
+ factory->off_heap = &factory->off_heap_saved;
+ factory->alloc_type = atype;
+}
+
+/* When we know the term is an immediate and need no heap.
+*/
+void erts_factory_dummy_init(ErtsHeapFactory* factory)
+{
+ factory->mode = FACTORY_CLOSED;
+}
+
+static void reserve_heap(ErtsHeapFactory*, Uint need, Uint xtra);
+
+Eterm* erts_produce_heap(ErtsHeapFactory* factory, Uint need, Uint xtra)
+{
+ Eterm* res;
+
+ ASSERT((unsigned int)factory->mode > (unsigned int)FACTORY_CLOSED);
+ if (factory->hp + need > factory->hp_end) {
+ reserve_heap(factory, need, xtra);
}
+ res = factory->hp;
+ factory->hp += need;
+ return res;
+}
+
+Eterm* erts_reserve_heap(ErtsHeapFactory* factory, Uint need)
+{
+ ASSERT((unsigned int)factory->mode > (unsigned int)FACTORY_CLOSED);
+ if (factory->hp + need > factory->hp_end) {
+ reserve_heap(factory, need, 200);
+ }
+ return factory->hp;
+}
+
+static void reserve_heap(ErtsHeapFactory* factory, Uint need, Uint xtra)
+{
+ ErlHeapFragment* bp;
+
+ switch (factory->mode) {
+ case FACTORY_HALLOC:
+ HRelease(factory->p, factory->hp_end, factory->hp);
+ factory->hp = HAllocX(factory->p, need, xtra);
+ factory->hp_end = factory->hp + need;
+ return;
+
+ case FACTORY_HEAP_FRAGS:
+ case FACTORY_TMP:
+ bp = factory->heap_frags;
+
+ if (bp) {
+ ASSERT(factory->hp > bp->mem);
+ ASSERT(factory->hp <= factory->hp_end);
+ ASSERT(factory->hp_end == bp->mem + bp->alloc_size);
+
+ bp->used_size = factory->hp - bp->mem;
+ }
+ bp = (ErlHeapFragment*) ERTS_HEAP_ALLOC(factory->alloc_type,
+ ERTS_HEAP_FRAG_SIZE(need+xtra));
+ bp->next = factory->heap_frags;
+ factory->heap_frags = bp;
+ bp->alloc_size = need + xtra;
+ bp->used_size = need;
+ bp->off_heap.first = NULL;
+ bp->off_heap.overhead = 0;
+
+ factory->hp = bp->mem;
+ factory->hp_end = bp->mem + bp->alloc_size;
+ return;
+
+ case FACTORY_STATIC:
+ case FACTORY_CLOSED:
+ default:
+ ASSERT(!"Invalid factory mode");
+ }
+}
+
+void erts_factory_close(ErtsHeapFactory* factory)
+{
+ ErlHeapFragment* bp;
+
+ switch (factory->mode) {
+ case FACTORY_HALLOC:
+ HRelease(factory->p, factory->hp_end, factory->hp);
+ break;
+
+ case FACTORY_HEAP_FRAGS:
+ bp = factory->heap_frags;
+
+ if (bp) {
+ ASSERT(factory->hp >= bp->mem);
+ ASSERT(factory->hp <= factory->hp_end);
+ ASSERT(factory->hp_end == bp->mem + bp->alloc_size);
+
+ bp->used_size = factory->hp - bp->mem;
+ }
+ break;
+ case FACTORY_TMP:
+ erts_factory_undo(factory);
+ break;
+ case FACTORY_STATIC: break;
+ case FACTORY_CLOSED: break;
+ default:
+ ASSERT(!"Invalid factory mode");
+ }
+ factory->mode = FACTORY_CLOSED;
+}
+
+void erts_factory_trim_and_close(ErtsHeapFactory* factory,
+ Eterm *brefs, Uint brefs_size)
+{
+ if (factory->mode == FACTORY_HEAP_FRAGS) {
+ ErlHeapFragment* bp = factory->heap_frags;
+ if (bp->next == NULL) {
+ Uint used_sz = factory->hp - bp->mem;
+ ASSERT(used_sz <= bp->alloc_size);
+ factory->heap_frags = erts_resize_message_buffer(bp, used_sz,
+ brefs, brefs_size);
+ factory->mode = FACTORY_CLOSED;
+ return;
+ }
+ /*else we don't trim multi fragmented messages for now */
+ }
+ erts_factory_close(factory);
+}
+
+void erts_factory_undo(ErtsHeapFactory* factory)
+{
+ ErlHeapFragment* bp;
+ struct erl_off_heap_header *hdr, **hdr_nextp;
+
+ switch (factory->mode) {
+ case FACTORY_HALLOC:
+ case FACTORY_STATIC:
+ /* Cleanup off-heap
+ */
+ hdr_nextp = NULL;
+ for (hdr = factory->off_heap->first;
+ hdr != factory->off_heap_saved.first;
+ hdr = hdr->next) {
+
+ hdr_nextp = &hdr->next;
+ }
+
+ if (hdr_nextp != NULL) {
+ *hdr_nextp = NULL;
+ erts_cleanup_offheap(factory->off_heap);
+ factory->off_heap->first = factory->off_heap_saved.first;
+ factory->off_heap->overhead = factory->off_heap_saved.overhead;
+ }
+
+ if (factory->mode == FACTORY_HALLOC) {
+ /* Free heap frags
+ */
+ bp = factory->p->mbuf;
+ if (bp != factory->heap_frags_saved) {
+ do {
+ ErlHeapFragment *next_bp = bp->next;
+ ASSERT(bp->off_heap.first == NULL);
+ ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG, (void *) bp,
+ ERTS_HEAP_FRAG_SIZE(bp->alloc_size));
+ bp = next_bp;
+ } while (bp != factory->heap_frags_saved);
+
+ factory->p->mbuf = bp;
+ }
+
+ /* Rollback heap top
+ */
+ if (factory->heap_frags_saved == NULL) { /* No heap frags when we started */
+ ASSERT(factory->hp_start >= HEAP_START(factory->p));
+ ASSERT(factory->hp_start <= HEAP_LIMIT(factory->p));
+
+ HEAP_TOP(factory->p) = factory->hp_start;
+ }
+ else {
+ ASSERT(factory->heap_frags_saved == factory->p->mbuf);
+ if (factory->hp_start == factory->heap_frags_saved->mem) {
+ factory->p->mbuf = factory->p->mbuf->next;
+ ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG, factory->heap_frags_saved,
+ ERTS_HEAP_FRAG_SIZE(factory->heap_frags_saved->alloc_size));
+ }
+ else if (factory->hp_start != factory->hp_end) {
+ unsigned remains = factory->hp_start - factory->heap_frags_saved->mem;
+ ASSERT(remains > 0 && remains < factory->heap_frags_saved->used_size);
+ factory->heap_frags_saved->used_size = remains;
+ }
+ }
+ }
+ break;
+
+ case FACTORY_TMP:
+ case FACTORY_HEAP_FRAGS:
+ erts_cleanup_offheap(factory->off_heap);
+ factory->off_heap->first = NULL;
+
+ bp = factory->heap_frags;
+ while (bp != NULL) {
+ ErlHeapFragment* next_bp = bp->next;
+
+ ASSERT(bp->off_heap.first == NULL);
+ ERTS_HEAP_FREE(factory->alloc_type, (void *) bp,
+ ERTS_HEAP_FRAG_SIZE(bp->alloc_size));
+ bp = next_bp;
+ }
+ break;
+
+ case FACTORY_CLOSED: break;
+ default:
+ ASSERT(!"Invalid factory mode");
+ }
+ factory->mode = FACTORY_CLOSED;
+#ifdef DEBUG
+ factory->p = NULL;
+ factory->hp = NULL;
+ factory->heap_frags = NULL;
+#endif
}
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index 0f3bb8d281..92ba3e571c 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -51,6 +52,47 @@ typedef struct erl_off_heap {
(OHP)->first = NULL; \
(OHP)->overhead = 0; \
} while (0)
+
+typedef struct {
+ enum {
+ FACTORY_CLOSED = 0,
+ FACTORY_HALLOC,
+ FACTORY_HEAP_FRAGS,
+ FACTORY_STATIC,
+ FACTORY_TMP
+ } mode;
+ Process* p;
+ Eterm* hp_start;
+ Eterm* hp;
+ Eterm* hp_end;
+ struct erl_heap_fragment* heap_frags;
+ struct erl_heap_fragment* heap_frags_saved;
+ ErlOffHeap* off_heap;
+ ErlOffHeap off_heap_saved;
+ Uint32 alloc_type;
+} ErtsHeapFactory;
+
+void erts_factory_proc_init(ErtsHeapFactory*, Process*);
+void erts_factory_proc_prealloc_init(ErtsHeapFactory*, Process*, Sint size);
+void erts_factory_message_init(ErtsHeapFactory*, Process*, Eterm* hp, struct erl_heap_fragment*);
+void erts_factory_static_init(ErtsHeapFactory*, Eterm* hp, Uint size, ErlOffHeap*);
+void erts_factory_tmp_init(ErtsHeapFactory*, Eterm* hp, Uint size, Uint32 atype);
+void erts_factory_dummy_init(ErtsHeapFactory*);
+
+Eterm* erts_produce_heap(ErtsHeapFactory*, Uint need, Uint xtra);
+Eterm* erts_reserve_heap(ErtsHeapFactory*, Uint need);
+void erts_factory_close(ErtsHeapFactory*);
+void erts_factory_trim_and_close(ErtsHeapFactory*,Eterm *brefs, Uint brefs_size);
+void erts_factory_undo(ErtsHeapFactory*);
+
+#ifdef CHECK_FOR_HOLES
+# define ERTS_FACTORY_HOLE_CHECK(f) do { \
+ /*if ((f)->p) erts_check_for_holes((f)->p);*/ \
+ } while (0)
+#else
+# define ERTS_FACTORY_HOLE_CHECK(p)
+#endif
+
#include "external.h"
#include "erl_process.h"
@@ -124,7 +166,7 @@ typedef struct {
*(p)->msg.last = (mp); \
(p)->msg.last = &(mp)->next; \
(p)->msg.len++; \
-} while(0)
+} while (0)
#ifdef ERTS_SMP
@@ -197,17 +239,23 @@ do { \
do { \
if ((M)->data.attached) { \
Uint need__ = erts_msg_attached_data_size((M)); \
+ { SWPO ; } \
if ((ST) - (HT) >= need__) { \
- Uint *htop__ = (HT); \
- erts_move_msg_attached_data_to_heap(&htop__, &MSO((P)), (M));\
- ASSERT(htop__ - (HT) <= need__); \
- (HT) = htop__; \
+ ErtsHeapFactory factory__; \
+ erts_factory_proc_prealloc_init(&factory__, (P), need__); \
+ erts_move_msg_attached_data_to_heap(&factory__, (M)); \
+ erts_factory_close(&factory__); \
+ if ((P)->mbuf != NULL) { \
+ /* Heap was exhausted by messages. This is a rare case */ \
+ /* that can currently (OTP 18) only happen if hamts are */ \
+ /* far exceeding the estimated heap size. Do GC. */ \
+ (FC) -= erts_garbage_collect((P), 0, NULL, 0); \
+ } \
} \
else { \
- { SWPO ; } \
(FC) -= erts_garbage_collect((P), 0, NULL, 0); \
- { SWPI ; } \
} \
+ { SWPI ; } \
ASSERT(!(M)->data.attached); \
} \
} while (0)
@@ -233,11 +281,17 @@ ErlHeapFragment* erts_resize_message_buffer(ErlHeapFragment *, Uint,
Eterm *, Uint);
void free_message_buffer(ErlHeapFragment *);
void erts_queue_dist_message(Process*, ErtsProcLocks*, ErtsDistExternal *, Eterm);
-void erts_queue_message(Process*, ErtsProcLocks*, ErlHeapFragment*, Eterm, Eterm
#ifdef USE_VM_PROBES
- , Eterm dt_utag
+void erts_queue_message_probe(Process*, ErtsProcLocks*, ErlHeapFragment*,
+ Eterm message, Eterm seq_trace_token, Eterm dt_utag);
+#define erts_queue_message(RP,RL,BP,Msg,SEQ) \
+ erts_queue_message_probe((RP),(RL),(BP),(Msg),(SEQ),NIL)
+#else
+void erts_queue_message(Process*, ErtsProcLocks*, ErlHeapFragment*,
+ Eterm message, Eterm seq_trace_token);
+#define erts_queue_message_probe(RP,RL,BP,Msg,SEQ,TAG) \
+ erts_queue_message((RP),(RL),(BP),(Msg),(SEQ))
#endif
-);
void erts_deliver_exit_message(Eterm, Process*, ErtsProcLocks *, Eterm, Eterm);
Sint erts_send_message(Process*, Process*, ErtsProcLocks*, Eterm, unsigned);
void erts_link_mbuf_to_proc(Process *proc, ErlHeapFragment *bp);
@@ -245,23 +299,21 @@ void erts_link_mbuf_to_proc(Process *proc, ErlHeapFragment *bp);
void erts_move_msg_mbuf_to_heap(Eterm**, ErlOffHeap*, ErlMessage *);
Uint erts_msg_attached_data_size_aux(ErlMessage *msg);
-void erts_move_msg_attached_data_to_heap(Eterm **, ErlOffHeap *, ErlMessage *);
-
+void erts_move_msg_attached_data_to_heap(ErtsHeapFactory*, ErlMessage *);
Eterm erts_msg_distext2heap(Process *, ErtsProcLocks *, ErlHeapFragment **,
Eterm *, ErtsDistExternal *);
void erts_cleanup_offheap(ErlOffHeap *offheap);
-ERTS_GLB_INLINE Uint erts_msg_used_frag_sz(const ErlMessage *msg);
+ERTS_GLB_INLINE Uint erts_used_frag_sz(const ErlHeapFragment*);
ERTS_GLB_INLINE Uint erts_msg_attached_data_size(ErlMessage *msg);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-ERTS_GLB_INLINE Uint erts_msg_used_frag_sz(const ErlMessage *msg)
+ERTS_GLB_INLINE Uint erts_used_frag_sz(const ErlHeapFragment* bp)
{
- const ErlHeapFragment *bp;
Uint sz = 0;
- for (bp = msg->data.heap_frag; bp!=NULL; bp=bp->next) {
+ for ( ; bp!=NULL; bp=bp->next) {
sz += bp->used_size;
}
return sz;
@@ -271,7 +323,7 @@ ERTS_GLB_INLINE Uint erts_msg_attached_data_size(ErlMessage *msg)
{
ASSERT(msg->data.attached);
if (is_value(ERL_MESSAGE_TERM(msg)))
- return erts_msg_used_frag_sz(msg);
+ return erts_used_frag_sz(msg->data.heap_frag);
else if (msg->data.dist_ext->heap_size < 0)
return erts_msg_attached_data_size_aux(msg);
else {
diff --git a/erts/emulator/beam/erl_monitors.c b/erts/emulator/beam/erl_monitors.c
index 244a2b26db..bd899fa2f9 100644
--- a/erts/emulator/beam/erl_monitors.c
+++ b/erts/emulator/beam/erl_monitors.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -355,7 +356,7 @@ void erts_add_monitor(ErtsMonitor **root, Uint type, Eterm ref, Eterm pid,
tstack[tpos++] = this;
this = &((*this)->right);
} else { /* Equal key is an error for monitors */
- erl_exit(1,"Insertion of already present monitor!");
+ erts_exit(ERTS_ERROR_EXIT,"Insertion of already present monitor!");
break;
}
}
diff --git a/erts/emulator/beam/erl_monitors.h b/erts/emulator/beam/erl_monitors.h
index fb11dbbd22..901ed8940b 100644
--- a/erts/emulator/beam/erl_monitors.h
+++ b/erts/emulator/beam/erl_monitors.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -82,6 +83,7 @@
/* Type tags for monitors */
#define MON_ORIGIN 1
#define MON_TARGET 3
+#define MON_TIME_OFFSET 7
/* Type tags for links */
#define LINK_PID 1 /* ...Or port */
@@ -103,7 +105,7 @@ typedef struct erts_monitor_or_link {
typedef struct erts_monitor {
struct erts_monitor *left, *right;
Sint16 balance;
- Uint16 type; /* MON_ORIGIN | MON_TARGET */
+ Uint16 type; /* MON_ORIGIN | MON_TARGET | MON_TIME_OFFSET */
Eterm ref;
Eterm pid; /* In case of distributed named monitor, this is the
nodename atom in MON_ORIGIN process, otherwise a pid or
diff --git a/erts/emulator/beam/erl_mtrace.c b/erts/emulator/beam/erl_mtrace.c
index c8bb126687..fdaf02f37a 100644
--- a/erts/emulator/beam/erl_mtrace.c
+++ b/erts/emulator/beam/erl_mtrace.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -627,7 +628,7 @@ erts_mtrace_install_wrapper_functions(void)
if (erts_mtrace_enabled) {
int i;
/* Install trace functions */
- ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
+ ERTS_CT_ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
sys_memcpy((void *) real_allctrs,
(void *) erts_allctrs,
diff --git a/erts/emulator/beam/erl_mtrace.h b/erts/emulator/beam/erl_mtrace.h
index 204543ddb0..b34eab3c4a 100644
--- a/erts/emulator/beam/erl_mtrace.h
+++ b/erts/emulator/beam/erl_mtrace.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index adc3520ebb..1097916c97 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -36,6 +37,7 @@
#include "erl_thr_progress.h"
#include "dtrace-wrapper.h"
#include "erl_process.h"
+#include "erl_bif_unique.h"
#if defined(USE_DYNAMIC_TRACE) && (defined(USE_DTRACE) || defined(USE_SYSTEMTAP))
#define HAVE_USE_DTRACE 1
#endif
@@ -127,6 +129,7 @@ void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif)
env->heap_frag = NULL;
env->fpe_was_unmasked = erts_block_fpe();
env->tmp_obj_list = NULL;
+ env->exception_thrown = 0;
}
static void pre_nif_noproc(ErlNifEnv* env, struct erl_module_nif* mod_nif)
@@ -327,14 +330,14 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
#ifdef ERTS_SMP
c_p = NULL;
#else
- erl_exit(ERTS_ABORT_EXIT,"enif_send: env==NULL on non-SMP VM");
+ erts_exit(ERTS_ABORT_EXIT,"enif_send: env==NULL on non-SMP VM");
#endif
}
rp = (scheduler
? erts_proc_lookup(receiver)
: erts_pid2proc_opt(c_p, ERTS_PROC_LOCK_MAIN,
- receiver, rp_locks, ERTS_P2P_FLG_SMP_INC_REFC));
+ receiver, rp_locks, ERTS_P2P_FLG_INC_REFC));
if (rp == NULL) {
ASSERT(env == NULL || receiver != c_p->common.id);
return 0;
@@ -356,17 +359,13 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
if (flush_me) {
flush_env(env); /* Needed for ERTS_HOLE_CHECK */
}
- erts_queue_message(rp, &rp_locks, frags, msg, am_undefined
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, frags, msg, am_undefined);
if (c_p == rp)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
if (!scheduler)
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
if (flush_me) {
cache_env(env);
}
@@ -447,7 +446,7 @@ int enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)
int enif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term)
{
- return term == THE_NON_VALUE;
+ return env->exception_thrown && term == THE_NON_VALUE;
}
int enif_is_number(ErlNifEnv* env, ERL_NIF_TERM term)
@@ -551,9 +550,7 @@ int enif_alloc_binary(size_t size, ErlNifBinary* bin)
if (refbin == NULL) {
return 0; /* The NIF must take action */
}
- refbin->flags = BIN_FLAG_DRV; /* BUGBUG: Flag? */
erts_refc_init(&refbin->refc, 1);
- refbin->orig_size = (SWord) size;
bin->size = size;
bin->data = (unsigned char*) refbin->orig_bytes;
@@ -573,7 +570,6 @@ int enif_realloc_binary(ErlNifBinary* bin, size_t size)
if (!newbin) {
return 0;
}
- newbin->orig_size = size;
bin->ref_bin = newbin;
bin->data = (unsigned char*) newbin->orig_bytes;
bin->size = size;
@@ -742,7 +738,22 @@ Eterm enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term,
Eterm enif_make_badarg(ErlNifEnv* env)
{
- BIF_ERROR(env->proc, BADARG);
+ return enif_raise_exception(env, am_badarg);
+}
+
+Eterm enif_raise_exception(ErlNifEnv* env, ERL_NIF_TERM reason)
+{
+ env->exception_thrown = 1;
+ env->proc->fvalue = reason;
+ BIF_ERROR(env->proc, EXC_ERROR);
+}
+
+int enif_has_pending_exception(ErlNifEnv* env, ERL_NIF_TERM* reason)
+{
+ if (env->exception_thrown && reason != NULL) {
+ *reason = env->proc->fvalue;
+ }
+ return env->exception_thrown;
}
int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len,
@@ -964,8 +975,12 @@ ERL_NIF_TERM enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i)
ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d)
{
- Eterm* hp = alloc_heap(env,FLOAT_SIZE_OBJECT);
+ Eterm* hp;
FloatDef f;
+
+ if (!erts_isfinite(d))
+ return enif_make_badarg(env);
+ hp = alloc_heap(env,FLOAT_SIZE_OBJECT);
f.fd = d;
PUT_DOUBLE(f, hp);
return make_float(hp);
@@ -978,6 +993,8 @@ ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name)
ERL_NIF_TERM enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)
{
+ if (len > MAX_ATOM_CHARACTERS)
+ return enif_make_badarg(env);
return erts_atom_put((byte*)name, len, ERTS_ATOM_ENC_LATIN1, 1);
}
@@ -991,6 +1008,8 @@ int enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len,
ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)
{
ASSERT(encoding == ERL_NIF_LATIN1);
+ if (len > MAX_ATOM_CHARACTERS)
+ return 0;
return erts_atom_get(name, len, atom, ERTS_ATOM_ENC_LATIN1);
}
@@ -1154,6 +1173,27 @@ ErlNifTid enif_thread_self(void) { return erl_drv_thread_self(); }
int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2) { return erl_drv_equal_tids(tid1,tid2); }
void enif_thread_exit(void *resp) { erl_drv_thread_exit(resp); }
int enif_thread_join(ErlNifTid tid, void **respp) { return erl_drv_thread_join(tid,respp); }
+int enif_getenv(const char *key, char *value, size_t *value_size) { return erl_drv_getenv(key, value, value_size); }
+
+ErlNifTime enif_monotonic_time(ErlNifTimeUnit time_unit)
+{
+ return (ErlNifTime) erts_napi_monotonic_time((int) time_unit);
+}
+
+ErlNifTime enif_time_offset(ErlNifTimeUnit time_unit)
+{
+ return (ErlNifTime) erts_napi_time_offset((int) time_unit);
+}
+
+ErlNifTime
+enif_convert_time_unit(ErlNifTime val,
+ ErlNifTimeUnit from,
+ ErlNifTimeUnit to)
+{
+ return (ErlNifTime) erts_napi_convert_time_unit((ErtsMonotonicTime) val,
+ (int) from,
+ (int) to);
+}
int enif_fprintf(void* filep, const char* format, ...)
{
@@ -1190,7 +1230,11 @@ typedef struct enif_resource_t
struct enif_resource_type_t* type;
#ifdef DEBUG
erts_refc_t nif_refc;
+# ifdef ARCH_32
+ byte align__[4];
+# endif
#endif
+
char data[1];
}ErlNifResource;
@@ -1366,7 +1410,7 @@ static void rollback_opened_resource_types(void)
static void nif_resource_dtor(Binary* bin)
{
- ErlNifResource* resource = (ErlNifResource*) ERTS_MAGIC_BIN_DATA(bin);
+ ErlNifResource* resource = (ErlNifResource*) ERTS_MAGIC_BIN_UNALIGNED_DATA(bin);
ErlNifResourceType* type = resource->type;
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == &nif_resource_dtor);
@@ -1387,8 +1431,10 @@ static void nif_resource_dtor(Binary* bin)
void* enif_alloc_resource(ErlNifResourceType* type, size_t size)
{
- Binary* bin = erts_create_magic_binary(SIZEOF_ErlNifResource(size), &nif_resource_dtor);
- ErlNifResource* resource = ERTS_MAGIC_BIN_DATA(bin);
+ Binary* bin = erts_create_magic_binary_x(SIZEOF_ErlNifResource(size),
+ &nif_resource_dtor,
+ 1); /* unaligned */
+ ErlNifResource* resource = ERTS_MAGIC_BIN_UNALIGNED_DATA(bin);
ASSERT(type->owner && type->next && type->prev); /* not allowed in load/upgrade */
resource->type = type;
@@ -1403,7 +1449,7 @@ void* enif_alloc_resource(ErlNifResourceType* type, size_t size)
void enif_release_resource(void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
- ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_DATA(resource);
+ ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_UNALIGNED_DATA(resource);
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == &nif_resource_dtor);
#ifdef DEBUG
@@ -1417,7 +1463,7 @@ void enif_release_resource(void* obj)
void enif_keep_resource(void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
- ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_DATA(resource);
+ ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_UNALIGNED_DATA(resource);
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == &nif_resource_dtor);
#ifdef DEBUG
@@ -1429,7 +1475,7 @@ void enif_keep_resource(void* obj)
ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
- ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_DATA(resource);
+ ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_UNALIGNED_DATA(resource);
Eterm* hp = alloc_heap(env,PROC_BIN_SIZE);
return erts_mk_magic_binary_term(&hp, &MSO(env->proc), &bin->binary);
}
@@ -1458,7 +1504,7 @@ int enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* typ
return 0; / * Or should we allow "resource binaries" as handles? * /
}*/
mbin = pb->val;
- resource = (ErlNifResource*) ERTS_MAGIC_BIN_DATA(mbin);
+ resource = (ErlNifResource*) ERTS_MAGIC_BIN_UNALIGNED_DATA(mbin);
if (ERTS_MAGIC_BIN_DESTRUCTOR(mbin) != &nif_resource_dtor
|| resource->type != type) {
return 0;
@@ -1470,8 +1516,8 @@ int enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* typ
size_t enif_sizeof_resource(void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
- Binary* bin = &ERTS_MAGIC_BIN_FROM_DATA(resource)->binary;
- return ERTS_MAGIC_BIN_DATA_SIZE(bin) - offsetof(ErlNifResource,data);
+ Binary* bin = &ERTS_MAGIC_BIN_FROM_UNALIGNED_DATA(resource)->binary;
+ return ERTS_MAGIC_BIN_UNALIGNED_DATA_SIZE(bin) - offsetof(ErlNifResource,data);
}
@@ -1529,12 +1575,13 @@ int enif_consume_timeslice(ErlNifEnv* env, int percent)
* NIF exports need a few more items than the Export struct provides,
* including the erl_module_nif* and a NIF function pointer, so the
* NifExport below adds those. The Export member must be first in the
- * struct. The saved_mfa, saved_argc, nif_level, alloced_argv_sz and argv
- * members are used to track the MFA and arguments of the top NIF in case a
- * chain of one or more enif_schedule_nif() calls results in an exception,
- * since in that case the original MFA and registers have to be restored
- * before returning to Erlang to ensure stacktrace information associated
- * with the exception is correct.
+ * struct. The saved_mfa, exception_thrown, saved_argc, rootset_extra, and
+ * rootset members are used to track the MFA, any pending exception, and
+ * arguments of the top NIF in case a chain of one or more
+ * enif_schedule_nif() calls results in an exception, since in that case
+ * the original MFA and registers have to be restored before returning to
+ * Erlang to ensure stacktrace information associated with the exception is
+ * correct.
*/
typedef ERL_NIF_TERM (*NativeFunPtr)(ErlNifEnv*, int, const ERL_NIF_TERM[]);
@@ -1543,25 +1590,28 @@ typedef struct {
struct erl_module_nif* m;
NativeFunPtr fp;
Eterm saved_mfa[3];
+ int exception_thrown;
int saved_argc;
- int alloced_argv_sz;
- Eterm argv[1];
+ int rootset_extra;
+ Eterm rootset[1];
} NifExport;
/*
* If a process has saved arguments, they need to be part of the GC
* rootset. The function below is called from setup_rootset() in
- * erl_gc.c. This function is declared in erl_process.h.
+ * erl_gc.c. This function is declared in erl_process.h. Any exception term
+ * saved in the NifExport is also made part of the GC rootset here; it
+ * always resides in rootset[0].
*/
int
erts_setup_nif_gc(Process* proc, Eterm** objv, int* nobj)
{
NifExport* ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
- int gc = (ep && ep->saved_argc > 0);
+ int gc = ep && (ep->saved_argc > 0 || ep->rootset[0] != NIL);
if (gc) {
- *objv = ep->argv;
- *nobj = ep->saved_argc;
+ *objv = ep->rootset;
+ *nobj = 1 + ep->saved_argc;
}
return gc;
}
@@ -1573,14 +1623,14 @@ static NifExport*
allocate_nif_sched_data(Process* proc, int argc)
{
NifExport* ep;
- size_t argv_extra, total;
+ size_t total;
int i;
- argv_extra = argc > 1 ? sizeof(Eterm)*(argc-1) : 0;
- total = sizeof(NifExport) + argv_extra;
+ total = sizeof(NifExport) + argc*sizeof(Eterm);
ep = erts_alloc(ERTS_ALC_T_NIF_TRAP_EXPORT, total);
sys_memset((void*) ep, 0, total);
- ep->alloced_argv_sz = argc;
+ ep->rootset_extra = argc;
+ ep->rootset[0] = NIL;
for (i=0; i<ERTS_NUM_CODE_IX; i++) {
ep->exp.addressv[i] = &ep->exp.code[3];
}
@@ -1621,15 +1671,22 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
if (!ep)
ep = allocate_nif_sched_data(proc, argc);
- else if (need_save && ep->alloced_argv_sz < argc) {
+ else if (need_save && ep->rootset_extra < argc) {
NifExport* new_ep = allocate_nif_sched_data(proc, argc);
destroy_nif_export(ep);
ep = new_ep;
}
+ if (env->exception_thrown) {
+ ep->exception_thrown = 1;
+ ep->rootset[0] = env->proc->fvalue;
+ } else {
+ ep->exception_thrown = 0;
+ ep->rootset[0] = NIL;
+ }
ERTS_VBUMP_ALL_REDS(proc);
for (i = 0; i < argc; i++) {
if (need_save)
- ep->argv[i] = reg[i];
+ ep->rootset[i+1] = reg[i];
reg[i] = (Eterm) argv[i];
}
if (need_save) {
@@ -1665,7 +1722,7 @@ restore_nif_mfa(Process* proc, NifExport* ep, int exception)
proc->current[2] = ep->saved_mfa[2];
if (exception)
for (i = 0; i < ep->saved_argc; i++)
- reg[i] = ep->argv[i];
+ reg[i] = ep->rootset[i+1];
ep->saved_argc = 0;
ep->saved_mfa[0] = THE_NON_VALUE;
}
@@ -1690,6 +1747,7 @@ dirty_nif_finalizer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ASSERT(!ERTS_SCHEDULER_IS_DIRTY(env->proc->scheduler_data));
ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
ASSERT(ep);
+ ASSERT(!ep->exception_thrown);
if (ep->fp)
restore_nif_mfa(proc, ep, 0);
return argv[0];
@@ -1707,9 +1765,10 @@ dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ASSERT(!ERTS_SCHEDULER_IS_DIRTY(env->proc->scheduler_data));
ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
ASSERT(ep);
+ ASSERT(ep->exception_thrown);
if (ep->fp)
restore_nif_mfa(proc, ep, 1);
- return enif_make_badarg(env);
+ return enif_raise_exception(env, ep->rootset[0]);
}
/*
@@ -1754,14 +1813,13 @@ execute_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ASSERT(ep);
if (ep->fp)
fp = NULL;
- if (is_non_value(result)) {
+ if (is_non_value(result) || env->exception_thrown) {
if (proc->freason != TRAP) {
- ASSERT(proc->freason == BADARG);
return init_nif_sched_data(env, dirty_nif_exception, fp, 0, argc, argv);
} else {
if (ep->fp == NULL)
restore_nif_mfa(proc, ep, 1);
- return result;
+ return THE_NON_VALUE;
}
}
else
@@ -1835,6 +1893,7 @@ execute_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
NifExport* ep;
ERL_NIF_TERM result;
+ ASSERT(!env->exception_thrown);
ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
ASSERT(ep);
ep->fp = NULL;
@@ -1847,7 +1906,7 @@ execute_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
* which case we need to restore the original NIF MFA.
*/
if (ep->fp == NULL)
- restore_nif_mfa(proc, ep, is_non_value(result) && proc->freason != TRAP);
+ restore_nif_mfa(proc, ep, env->exception_thrown);
return result;
}
@@ -1913,29 +1972,33 @@ int enif_is_map(ErlNifEnv* env, ERL_NIF_TERM term)
int enif_get_map_size(ErlNifEnv* env, ERL_NIF_TERM term, size_t *size)
{
- if (is_map(term)) {
- map_t *mp;
- mp = (map_t*)map_val(term);
- *size = map_get_size(mp);
+ if (is_flatmap(term)) {
+ flatmap_t *mp;
+ mp = (flatmap_t*)flatmap_val(term);
+ *size = flatmap_get_size(mp);
return 1;
}
+ else if (is_hashmap(term)) {
+ *size = hashmap_size(term);
+ return 1;
+ }
return 0;
}
ERL_NIF_TERM enif_make_new_map(ErlNifEnv* env)
{
- Eterm* hp = alloc_heap(env,MAP_HEADER_SIZE+1);
+ Eterm* hp = alloc_heap(env,MAP_HEADER_FLATMAP_SZ+1);
Eterm tup;
- map_t *mp;
+ flatmap_t *mp;
tup = make_tuple(hp);
*hp++ = make_arityval(0);
- mp = (map_t*)hp;
- mp->thing_word = MAP_HEADER;
+ mp = (flatmap_t*)hp;
+ mp->thing_word = MAP_HEADER_FLATMAP;
mp->size = 0;
mp->keys = tup;
- return make_map(mp);
+ return make_flatmap(mp);
}
int enif_make_map_put(ErlNifEnv* env,
@@ -1944,7 +2007,7 @@ int enif_make_map_put(ErlNifEnv* env,
Eterm value,
Eterm *map_out)
{
- if (is_not_map(map_in)) {
+ if (!is_map(map_in)) {
return 0;
}
flush_env(env);
@@ -1958,10 +2021,16 @@ int enif_get_map_value(ErlNifEnv* env,
Eterm key,
Eterm *value)
{
- if (is_not_map(map)) {
+ const Eterm *ret;
+ if (!is_map(map)) {
return 0;
}
- return erts_maps_get(key, map, value);
+ ret = erts_maps_get(key, map);
+ if (ret) {
+ *value = *ret;
+ return 1;
+ }
+ return 0;
}
int enif_make_map_update(ErlNifEnv* env,
@@ -1971,7 +2040,7 @@ int enif_make_map_update(ErlNifEnv* env,
Eterm *map_out)
{
int res;
- if (is_not_map(map_in)) {
+ if (!is_map(map_in)) {
return 0;
}
@@ -1987,7 +2056,7 @@ int enif_make_map_remove(ErlNifEnv* env,
Eterm *map_out)
{
int res;
- if (is_not_map(map_in)) {
+ if (!is_map(map_in)) {
return 0;
}
flush_env(env);
@@ -2001,13 +2070,13 @@ int enif_map_iterator_create(ErlNifEnv *env,
ErlNifMapIterator *iter,
ErlNifMapIteratorEntry entry)
{
- if (is_map(map)) {
- map_t *mp = (map_t*)map_val(map);
+ if (is_flatmap(map)) {
+ flatmap_t *mp = (flatmap_t*)flatmap_val(map);
size_t offset;
switch (entry) {
- case ERL_NIF_MAP_ITERATOR_HEAD: offset = 0; break;
- case ERL_NIF_MAP_ITERATOR_TAIL: offset = map_get_size(mp) - 1; break;
+ case ERL_NIF_MAP_ITERATOR_FIRST: offset = 0; break;
+ case ERL_NIF_MAP_ITERATOR_LAST: offset = flatmap_get_size(mp) - 1; break;
default: goto error;
}
@@ -2016,14 +2085,37 @@ int enif_map_iterator_create(ErlNifEnv *env,
*/
iter->map = map;
- iter->ks = ((Eterm *)map_get_keys(mp)) + offset;
- iter->vs = ((Eterm *)map_get_values(mp)) + offset;
- iter->t_limit = map_get_size(mp) + 1;
+ iter->u.flat.ks = ((Eterm *)flatmap_get_keys(mp)) + offset;
+ iter->u.flat.vs = ((Eterm *)flatmap_get_values(mp)) + offset;
+ iter->size = flatmap_get_size(mp);
iter->idx = offset + 1;
return 1;
}
-
+ else if (is_hashmap(map)) {
+ iter->map = map;
+ iter->size = hashmap_size(map);
+ iter->u.hash.wstack = erts_alloc(ERTS_ALC_T_NIF, sizeof(ErtsDynamicWStack));
+ WSTACK_INIT(iter->u.hash.wstack, ERTS_ALC_T_NIF);
+
+ switch (entry) {
+ case ERL_NIF_MAP_ITERATOR_FIRST:
+ iter->idx = 1;
+ hashmap_iterator_init(&iter->u.hash.wstack->ws, map, 0);
+ iter->u.hash.kv = hashmap_iterator_next(&iter->u.hash.wstack->ws);
+ break;
+ case ERL_NIF_MAP_ITERATOR_LAST:
+ iter->idx = hashmap_size(map);
+ hashmap_iterator_init(&iter->u.hash.wstack->ws, map, 1);
+ iter->u.hash.kv = hashmap_iterator_prev(&iter->u.hash.wstack->ws);
+ break;
+ default:
+ goto error;
+ }
+ ASSERT(!!iter->u.hash.kv == (iter->idx >= 1 &&
+ iter->idx <= iter->size));
+ return 1;
+ }
error:
#ifdef DEBUG
iter->map = THE_NON_VALUE;
@@ -2033,48 +2125,97 @@ error:
void enif_map_iterator_destroy(ErlNifEnv *env, ErlNifMapIterator *iter)
{
- /* not used */
+ if (is_hashmap(iter->map)) {
+ WSTACK_DESTROY(iter->u.hash.wstack->ws);
+ erts_free(ERTS_ALC_T_NIF, iter->u.hash.wstack);
+ }
+ else
+ ASSERT(is_flatmap(iter->map));
+
#ifdef DEBUG
iter->map = THE_NON_VALUE;
#endif
-
}
int enif_map_iterator_is_tail(ErlNifEnv *env, ErlNifMapIterator *iter)
{
- ASSERT(iter && is_map(iter->map));
- ASSERT(iter->idx >= 0 && (iter->idx <= map_get_size(map_val(iter->map)) + 1));
- return (iter->t_limit == 1 || iter->idx == iter->t_limit);
+ ASSERT(iter);
+ if (is_flatmap(iter->map)) {
+ ASSERT(iter->idx >= 0);
+ ASSERT(iter->idx <= flatmap_get_size(flatmap_val(iter->map)) + 1);
+ return (iter->size == 0 || iter->idx > iter->size);
+ }
+ else {
+ ASSERT(is_hashmap(iter->map));
+ return iter->idx > iter->size;
+ }
}
int enif_map_iterator_is_head(ErlNifEnv *env, ErlNifMapIterator *iter)
{
- ASSERT(iter && is_map(iter->map));
- ASSERT(iter->idx >= 0 && (iter->idx <= map_get_size(map_val(iter->map)) + 1));
- return (iter->t_limit == 1 || iter->idx == 0);
+ ASSERT(iter);
+ if (is_flatmap(iter->map)) {
+ ASSERT(iter->idx >= 0);
+ ASSERT(iter->idx <= flatmap_get_size(flatmap_val(iter->map)) + 1);
+ return (iter->size == 0 || iter->idx == 0);
+ }
+ else {
+ ASSERT(is_hashmap(iter->map));
+ return iter->idx == 0;
+ }
}
int enif_map_iterator_next(ErlNifEnv *env, ErlNifMapIterator *iter)
{
- ASSERT(iter && is_map(iter->map));
- if (iter->idx < iter->t_limit) {
- iter->idx++;
- iter->ks++;
- iter->vs++;
+ ASSERT(iter);
+ if (is_flatmap(iter->map)) {
+ if (iter->idx <= iter->size) {
+ iter->idx++;
+ iter->u.flat.ks++;
+ iter->u.flat.vs++;
+ }
+ return (iter->idx <= iter->size);
+ }
+ else {
+ ASSERT(is_hashmap(iter->map));
+
+ if (iter->idx <= hashmap_size(iter->map)) {
+ if (iter->idx < 1) {
+ hashmap_iterator_init(&iter->u.hash.wstack->ws, iter->map, 0);
+ }
+ iter->u.hash.kv = hashmap_iterator_next(&iter->u.hash.wstack->ws);
+ iter->idx++;
+ ASSERT(!!iter->u.hash.kv == (iter->idx <= iter->size));
+ }
+ return iter->idx <= iter->size;
}
- return (iter->idx != iter->t_limit);
}
int enif_map_iterator_prev(ErlNifEnv *env, ErlNifMapIterator *iter)
{
- ASSERT(iter && is_map(iter->map));
- if (iter->idx > 0) {
- iter->idx--;
- iter->ks--;
- iter->vs--;
+ ASSERT(iter);
+ if (is_flatmap(iter->map)) {
+ if (iter->idx > 0) {
+ iter->idx--;
+ iter->u.flat.ks--;
+ iter->u.flat.vs--;
+ }
+ return iter->idx > 0;
+ }
+ else {
+ ASSERT(is_hashmap(iter->map));
+
+ if (iter->idx > 0) {
+ if (iter->idx > iter->size) {
+ hashmap_iterator_init(&iter->u.hash.wstack->ws, iter->map, 1);
+ }
+ iter->u.hash.kv = hashmap_iterator_prev(&iter->u.hash.wstack->ws);
+ iter->idx--;
+ ASSERT(!!iter->u.hash.kv == (iter->idx > 0));
+ }
+ return iter->idx > 0;
}
- return (iter->idx > 0);
}
int enif_map_iterator_get_pair(ErlNifEnv *env,
@@ -2082,15 +2223,25 @@ int enif_map_iterator_get_pair(ErlNifEnv *env,
Eterm *key,
Eterm *value)
{
- ASSERT(iter && is_map(iter->map));
- if (iter->idx > 0 && iter->idx < iter->t_limit) {
- ASSERT(iter->ks >= map_get_keys(map_val(iter->map)) &&
- iter->ks < (map_get_keys(map_val(iter->map)) + map_get_size(map_val(iter->map))));
- ASSERT(iter->vs >= map_get_values(map_val(iter->map)) &&
- iter->vs < (map_get_values(map_val(iter->map)) + map_get_size(map_val(iter->map))));
- *key = *(iter->ks);
- *value = *(iter->vs);
- return 1;
+ ASSERT(iter);
+ if (is_flatmap(iter->map)) {
+ if (iter->idx > 0 && iter->idx <= iter->size) {
+ ASSERT(iter->u.flat.ks >= flatmap_get_keys(flatmap_val(iter->map)) &&
+ iter->u.flat.ks < (flatmap_get_keys(flatmap_val(iter->map)) + flatmap_get_size(flatmap_val(iter->map))));
+ ASSERT(iter->u.flat.vs >= flatmap_get_values(flatmap_val(iter->map)) &&
+ iter->u.flat.vs < (flatmap_get_values(flatmap_val(iter->map)) + flatmap_get_size(flatmap_val(iter->map))));
+ *key = *(iter->u.flat.ks);
+ *value = *(iter->u.flat.vs);
+ return 1;
+ }
+ }
+ else {
+ ASSERT(is_hashmap(iter->map));
+ if (iter->idx > 0 && iter->idx <= iter->size) {
+ *key = CAR(iter->u.hash.kv);
+ *value = CDR(iter->u.hash.kv);
+ return 1;
+ }
}
return 0;
}
@@ -2589,6 +2740,8 @@ erts_unload_nif(struct erl_module_nif* lib)
void erl_nif_init()
{
+ ERTS_CT_ASSERT((offsetof(ErlNifResource,data) % 8) == ERTS_MAGIC_BIN_BYTES_TO_ALIGN);
+
resource_type_list.next = &resource_type_list;
resource_type_list.prev = &resource_type_list;
resource_type_list.dtor = NULL;
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 849024453c..75070ad901 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -46,9 +47,12 @@
** remove enif_schedule_dirty_nif, enif_schedule_dirty_nif_finalizer, enif_dirty_nif_finalizer
** add ErlNifEntry options
** add ErlNifFunc flags
+** 2.8: 18.0 add enif_has_pending_exception
+** 2.9: 18.2 enif_getenv
+** 2.10: Time API
*/
#define ERL_NIF_MAJOR_VERSION 2
-#define ERL_NIF_MINOR_VERSION 7
+#define ERL_NIF_MINOR_VERSION 10
/*
* The emulator will refuse to load a nif-lib with a major version
@@ -64,63 +68,36 @@
#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
+typedef ErlNapiUInt64 ErlNifUInt64;
+typedef ErlNapiSInt64 ErlNifSInt64;
+typedef ErlNapiUInt ErlNifUInt;
+typedef ErlNapiSInt ErlNifSInt;
#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
+typedef ErlNifUInt ERL_NIF_TERM;
#endif
typedef ERL_NIF_TERM ERL_NIF_UINT;
+typedef ErlNifSInt64 ErlNifTime;
+
+#define ERL_NIF_TIME_ERROR ((ErlNifSInt64) ERTS_NAPI_TIME_ERROR__)
+
+typedef enum {
+ ERL_NIF_SEC = ERTS_NAPI_SEC__,
+ ERL_NIF_MSEC = ERTS_NAPI_MSEC__,
+ ERL_NIF_USEC = ERTS_NAPI_USEC__,
+ ERL_NIF_NSEC = ERTS_NAPI_NSEC__
+} ErlNifTimeUnit;
+
struct enif_environment_t;
typedef struct enif_environment_t ErlNifEnv;
@@ -201,22 +178,35 @@ typedef enum
typedef struct /* All fields all internal and may change */
{
ERL_NIF_TERM map;
- ERL_NIF_UINT t_limit;
+ ERL_NIF_UINT size;
ERL_NIF_UINT idx;
- ERL_NIF_TERM *ks;
- ERL_NIF_TERM *vs;
+ union {
+ struct {
+ ERL_NIF_TERM *ks;
+ ERL_NIF_TERM *vs;
+ }flat;
+ struct {
+ struct ErtsDynamicWStack_* wstack;
+ ERL_NIF_TERM* kv;
+ }hash;
+ }u;
void* __spare__[2]; /* for future additions to be ABI compatible (same struct size) */
} ErlNifMapIterator;
typedef enum {
- ERL_NIF_MAP_ITERATOR_HEAD = 1,
- ERL_NIF_MAP_ITERATOR_TAIL = 2
+ ERL_NIF_MAP_ITERATOR_FIRST = 1,
+ ERL_NIF_MAP_ITERATOR_LAST = 2,
+
+ /* deprecated synonyms (undocumented in 17 and 18-rc) */
+ ERL_NIF_MAP_ITERATOR_HEAD = ERL_NIF_MAP_ITERATOR_FIRST,
+ ERL_NIF_MAP_ITERATOR_TAIL = ERL_NIF_MAP_ITERATOR_LAST
} ErlNifMapIteratorEntry;
#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"
+ void* erts_alc_test;
} TWinDynNifCallbacks;
extern TWinDynNifCallbacks WinDynNifCallbacks;
# undef ERL_NIF_API_FUNC_DECL
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 630cefae93..1448a508a2 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -156,6 +157,12 @@ ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_next, (ErlNifEnv *env, ErlNifMapIte
ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_prev, (ErlNifEnv *env, ErlNifMapIterator *iter));
ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_get_pair, (ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_schedule_nif,(ErlNifEnv*,const char*,int,ERL_NIF_TERM (*)(ErlNifEnv*,int,const ERL_NIF_TERM[]),int,const ERL_NIF_TERM[]));
+ERL_NIF_API_FUNC_DECL(int, enif_has_pending_exception, (ErlNifEnv *env, ERL_NIF_TERM* reason));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_raise_exception, (ErlNifEnv *env, ERL_NIF_TERM reason));
+ERL_NIF_API_FUNC_DECL(int,enif_getenv,(const char* key, char* value, size_t* value_size));
+ERL_NIF_API_FUNC_DECL(ErlNifTime, enif_monotonic_time, (ErlNifTimeUnit));
+ERL_NIF_API_FUNC_DECL(ErlNifTime, enif_time_offset, (ErlNifTimeUnit));
+ERL_NIF_API_FUNC_DECL(ErlNifTime, enif_convert_time_unit, (ErlNifTime, ErlNifTimeUnit, ErlNifTimeUnit));
/*
** ADD NEW ENTRIES HERE (before this comment) !!!
@@ -305,6 +312,12 @@ ERL_NIF_API_FUNC_DECL(int,enif_is_on_dirty_scheduler,(ErlNifEnv*));
# define enif_map_iterator_prev ERL_NIF_API_FUNC_MACRO(enif_map_iterator_prev)
# define enif_map_iterator_get_pair ERL_NIF_API_FUNC_MACRO(enif_map_iterator_get_pair)
# define enif_schedule_nif ERL_NIF_API_FUNC_MACRO(enif_schedule_nif)
+# define enif_has_pending_exception ERL_NIF_API_FUNC_MACRO(enif_has_pending_exception)
+# define enif_raise_exception ERL_NIF_API_FUNC_MACRO(enif_raise_exception)
+# define enif_getenv ERL_NIF_API_FUNC_MACRO(enif_getenv)
+# define enif_monotonic_time ERL_NIF_API_FUNC_MACRO(enif_monotonic_time)
+# define enif_time_offset ERL_NIF_API_FUNC_MACRO(enif_time_offset)
+# define enif_convert_time_unit ERL_NIF_API_FUNC_MACRO(enif_convert_time_unit)
/*
** ADD NEW ENTRIES HERE (before this comment)
@@ -538,7 +551,7 @@ static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list9(ErlNifEnv* env,
#ifndef enif_make_pid
-# define enif_make_pid(ENV, PID) ((const ERL_NIF_TERM)((PID)->pid))
+# define enif_make_pid(ENV, PID) ((void)(ENV),(const ERL_NIF_TERM)((PID)->pid))
#if SIZEOF_LONG == 8
# define enif_get_int64 enif_get_long
diff --git a/erts/emulator/beam/erl_node_container_utils.h b/erts/emulator/beam/erl_node_container_utils.h
index 17f6b32bb1..211b1a0090 100644
--- a/erts/emulator/beam/erl_node_container_utils.h
+++ b/erts/emulator/beam/erl_node_container_utils.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index c6d136f951..e69bd49c42 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -36,21 +37,24 @@ erts_smp_rwmtx_t erts_node_table_rwmtx;
DistEntry *erts_hidden_dist_entries;
DistEntry *erts_visible_dist_entries;
-DistEntry *erts_not_connected_dist_entries;
+DistEntry *erts_not_connected_dist_entries; /* including erts_this_dist_entry */
Sint erts_no_of_hidden_dist_entries;
Sint erts_no_of_visible_dist_entries;
-Sint erts_no_of_not_connected_dist_entries;
+Sint erts_no_of_not_connected_dist_entries; /* including erts_this_dist_entry */
DistEntry *erts_this_dist_entry;
ErlNode *erts_this_node;
char erts_this_node_sysname_BUFFER[256],
*erts_this_node_sysname = "uninitialized yet";
-static Uint node_entries;
-static Uint dist_entries;
+static Uint node_entries = 0;
+static Uint dist_entries = 0;
static int references_atoms_need_init = 1;
+static ErtsMonotonicTime orig_node_tab_delete_delay;
+static ErtsMonotonicTime node_tab_delete_delay;
+
/* -- The distribution table ---------------------------------------------- */
#ifdef DEBUG
@@ -87,9 +91,6 @@ dist_table_alloc(void *dep_tmpl)
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
- if(((DistEntry *) dep_tmpl) == erts_this_dist_entry)
- return dep_tmpl;
-
sysname = ((DistEntry *) dep_tmpl)->sysname;
chnl_nr = make_small((Uint) atom_val(sysname));
dep = (DistEntry *) erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry));
@@ -128,7 +129,9 @@ dist_table_alloc(void *dep_tmpl)
/* Link in */
- /* All new dist entries are "not connected" */
+ /* All new dist entries are "not connected".
+ * erts_this_dist_entry is also always included among "not connected"
+ */
dep->next = erts_not_connected_dist_entries;
if(erts_not_connected_dist_entries) {
ASSERT(erts_not_connected_dist_entries->prev == NULL);
@@ -145,9 +148,6 @@ dist_table_free(void *vdep)
{
DistEntry *dep = (DistEntry *) vdep;
- if(dep == erts_this_dist_entry)
- return;
-
ASSERT(is_nil(dep->cid));
ASSERT(dep->nlinks == NULL);
ASSERT(dep->node_links == NULL);
@@ -182,7 +182,7 @@ dist_table_free(void *vdep)
#endif
erts_free(ERTS_ALC_T_DIST_ENTRY, (void *) dep);
- ASSERT(dist_entries > 1);
+ ASSERT(dist_entries > 0);
dist_entries--;
}
@@ -290,21 +290,46 @@ DistEntry *erts_find_dist_entry(Eterm sysname)
return res;
}
-void erts_delete_dist_entry(DistEntry *dep)
+static void try_delete_dist_entry(void *vdep)
+{
+ DistEntry *dep = (DistEntry *) vdep;
+ erts_aint_t refc;
+
+ erts_smp_rwmtx_rwlock(&erts_dist_table_rwmtx);
+ /*
+ * Another thread might have looked up this dist entry after
+ * we decided to delete it (refc became zero). If so, the other
+ * thread incremented refc twice. Once for the new reference
+ * and once for this thread.
+ *
+ * If refc reach -1, no one has used the entry since we
+ * set up the timer. Delete the entry.
+ *
+ * If refc reach 0, the entry is currently not in use
+ * but has been used since we set up the timer. Set up a
+ * new timer.
+ *
+ * If refc > 0, the entry is in use. Keep the entry.
+ */
+ refc = erts_refc_dectest(&dep->refc, -1);
+ if (refc == -1)
+ (void) hash_erase(&erts_dist_table, (void *) dep);
+ erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx);
+
+ if (refc == 0)
+ erts_schedule_delete_dist_entry(dep);
+}
+
+void erts_schedule_delete_dist_entry(DistEntry *dep)
{
ASSERT(dep != erts_this_dist_entry);
- if(dep != erts_this_dist_entry) {
- erts_smp_rwmtx_rwlock(&erts_dist_table_rwmtx);
- /*
- * Another thread might have looked up this dist entry after
- * we decided to delete it (refc became zero). If so, the other
- * thread incremented refc twice. Once for the new reference
- * and once for this thread. Therefore, delete dist entry if
- * refc is 0 or -1 after a decrement.
- */
- if (erts_refc_dectest(&dep->refc, -1) <= 0)
- (void) hash_erase(&erts_dist_table, (void *) dep);
- erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx);
+ if (dep != erts_this_dist_entry) {
+ if (node_tab_delete_delay == 0)
+ try_delete_dist_entry((void *) dep);
+ else if (node_tab_delete_delay > 0)
+ erts_start_timer_callback(node_tab_delete_delay,
+ try_delete_dist_entry,
+ (void *) dep);
}
}
@@ -340,8 +365,7 @@ erts_dist_table_size(void)
ASSERT(dist_entries == (erts_no_of_visible_dist_entries
+ erts_no_of_hidden_dist_entries
- + erts_no_of_not_connected_dist_entries
- + 1 /* erts_this_dist_entry */));
+ + erts_no_of_not_connected_dist_entries));
#endif
res = (hash_table_sz(&erts_dist_table)
@@ -514,9 +538,6 @@ node_table_alloc(void *venp_tmpl)
{
ErlNode *enp;
- if(((ErlNode *) venp_tmpl) == erts_this_node)
- return venp_tmpl;
-
enp = (ErlNode *) erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode));
node_entries++;
@@ -534,8 +555,7 @@ node_table_free(void *venp)
{
ErlNode *enp = (ErlNode *) venp;
- if(enp == erts_this_node)
- return;
+ ERTS_SMP_LC_ASSERT(enp != erts_this_node || erts_thr_progress_is_blocking());
erts_deref_dist_entry(enp->dist_entry);
#ifdef DEBUG
@@ -543,7 +563,7 @@ node_table_free(void *venp)
#endif
erts_free(ERTS_ALC_T_NODE_ENTRY, venp);
- ASSERT(node_entries > 1);
+ ASSERT(node_entries > 0);
node_entries--;
}
@@ -556,14 +576,14 @@ erts_node_table_size(void)
#endif
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
- erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
+ erts_smp_rwmtx_rlock(&erts_node_table_rwmtx);
#ifdef DEBUG
hash_get_info(&hi, &erts_node_table);
ASSERT(node_entries == hi.objs);
#endif
res = hash_table_sz(&erts_node_table) + node_entries*sizeof(ErlNode);
if (lock)
- erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+ erts_smp_rwmtx_runlock(&erts_node_table_rwmtx);
return res;
}
@@ -572,10 +592,10 @@ erts_node_table_info(int to, void *to_arg)
{
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
- erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
+ erts_smp_rwmtx_rlock(&erts_node_table_rwmtx);
hash_info(to, to_arg, &erts_node_table);
if (lock)
- erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+ erts_smp_rwmtx_runlock(&erts_node_table_rwmtx);
}
@@ -609,21 +629,46 @@ ErlNode *erts_find_or_insert_node(Eterm sysname, Uint creation)
return res;
}
-void erts_delete_node(ErlNode *enp)
+static void try_delete_node(void *venp)
+{
+ ErlNode *enp = (ErlNode *) venp;
+ erts_aint_t refc;
+
+ erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
+ /*
+ * Another thread might have looked up this node after we
+ * decided to delete it (refc became zero). If so, the other
+ * thread incremented refc twice. Once for the new reference
+ * and once for this thread.
+ *
+ * If refc reach -1, no one has used the entry since we
+ * set up the timer. Delete the entry.
+ *
+ * If refc reach 0, the entry is currently not in use
+ * but has been used since we set up the timer. Set up a
+ * new timer.
+ *
+ * If refc > 0, the entry is in use. Keep the entry.
+ */
+ refc = erts_refc_dectest(&enp->refc, -1);
+ if (refc == -1)
+ (void) hash_erase(&erts_node_table, (void *) enp);
+ erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+
+ if (refc == 0)
+ erts_schedule_delete_node(enp);
+}
+
+void erts_schedule_delete_node(ErlNode *enp)
{
ASSERT(enp != erts_this_node);
- if(enp != erts_this_node) {
- erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
- /*
- * Another thread might have looked up this node after we
- * decided to delete it (refc became zero). If so, the other
- * thread incremented refc twice. Once for the new reference
- * and once for this thread. Therefore, delete node if refc
- * is 0 or -1 after a decrement.
- */
- if (erts_refc_dectest(&enp->refc, -1) <= 0)
- (void) hash_erase(&erts_node_table, (void *) enp);
- erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+ if (enp != erts_this_node) {
+ if (node_tab_delete_delay == 0)
+ try_delete_node((void *) enp);
+ else if (node_tab_delete_delay > 0)
+ erts_start_timer_callback(node_tab_delete_delay,
+ try_delete_node,
+ (void *) enp);
}
}
@@ -651,7 +696,7 @@ static void print_node(void *venp, void *vpndp)
erts_print(pndp->to, pndp->to_arg, " %d", enp->creation);
#ifdef DEBUG
erts_print(pndp->to, pndp->to_arg, " (refc=%ld)",
- erts_refc_read(&enp->refc, 1));
+ erts_refc_read(&enp->refc, 0));
#endif
pndp->no_sysname++;
}
@@ -674,13 +719,13 @@ void erts_print_node_info(int to,
pnd.no_total = 0;
if (lock)
- erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
+ erts_smp_rwmtx_rlock(&erts_node_table_rwmtx);
hash_foreach(&erts_node_table, print_node, (void *) &pnd);
if (pnd.no_sysname != 0) {
erts_print(to, to_arg, "\n");
}
if (lock)
- erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+ erts_smp_rwmtx_runlock(&erts_node_table_rwmtx);
if(no_sysname)
*no_sysname = pnd.no_sysname;
@@ -693,45 +738,67 @@ void erts_print_node_info(int to,
void
erts_set_this_node(Eterm sysname, Uint creation)
{
- erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
- erts_smp_rwmtx_rwlock(&erts_dist_table_rwmtx);
+ ERTS_SMP_LC_ASSERT(erts_thr_progress_is_blocking());
+ ASSERT(erts_refc_read(&erts_this_dist_entry->refc, 2));
- (void) hash_erase(&erts_dist_table, (void *) erts_this_dist_entry);
- erts_this_dist_entry->sysname = sysname;
- erts_this_dist_entry->creation = creation;
- (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);
+ if (erts_refc_dectest(&erts_this_node->refc, 0) == 0)
+ try_delete_node(erts_this_node);
- (void) hash_erase(&erts_node_table, (void *) erts_this_node);
- erts_this_node->sysname = sysname;
- erts_this_node->creation = creation;
- erts_this_node_sysname = erts_this_node_sysname_BUFFER;
- erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname),
- "%T", sysname);
- (void) hash_put(&erts_node_table, (void *) erts_this_node);
+ if (erts_refc_dectest(&erts_this_dist_entry->refc, 0) == 0)
+ try_delete_dist_entry(erts_this_dist_entry);
- erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx);
- erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+ erts_this_node = NULL; /* to make sure refc is bumped for this node */
+ erts_this_node = erts_find_or_insert_node(sysname, creation);
+ erts_this_dist_entry = erts_this_node->dist_entry;
+
+ erts_refc_inc(&erts_this_dist_entry->refc, 2);
+ erts_this_node_sysname = erts_this_node_sysname_BUFFER;
+ erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER),
+ "%T", sysname);
+}
+
+Uint
+erts_delayed_node_table_gc(void)
+{
+ if (node_tab_delete_delay < 0)
+ return (Uint) ERTS_NODE_TAB_DELAY_GC_INFINITY;
+ if (node_tab_delete_delay == 0)
+ return (Uint) 0;
+ return (Uint) ((node_tab_delete_delay-1)/1000 + 1);
}
-void erts_init_node_tables(void)
+void erts_init_node_tables(int dd_sec)
{
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
HashFunctions f;
+ ErlNode node_tmpl;
+
+ if (dd_sec == ERTS_NODE_TAB_DELAY_GC_INFINITY)
+ node_tab_delete_delay = (ErtsMonotonicTime) -1;
+ else
+ node_tab_delete_delay = ((ErtsMonotonicTime) dd_sec)*1000;
+
+ orig_node_tab_delete_delay = node_tab_delete_delay;
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED;
+ erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table");
+ erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table");
+
f.hash = (H_FUN) dist_table_hash;
f.cmp = (HCMP_FUN) dist_table_cmp;
f.alloc = (HALLOC_FUN) dist_table_alloc;
f.free = (HFREE_FUN) dist_table_free;
-
- erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry));
- dist_entries = 1;
-
hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f);
+ f.hash = (H_FUN) node_table_hash;
+ f.cmp = (HCMP_FUN) node_table_cmp;
+ f.alloc = (HALLOC_FUN) node_table_alloc;
+ f.free = (HFREE_FUN) node_table_free;
+ hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f);
+
erts_hidden_dist_entries = NULL;
erts_visible_dist_entries = NULL;
erts_not_connected_dist_entries = NULL;
@@ -739,69 +806,23 @@ void erts_init_node_tables(void)
erts_no_of_visible_dist_entries = 0;
erts_no_of_not_connected_dist_entries = 0;
- erts_this_dist_entry->next = NULL;
- erts_this_dist_entry->prev = NULL;
- erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */
-
- erts_smp_rwmtx_init_opt_x(&erts_this_dist_entry->rwmtx,
- &rwmtx_opt,
- "dist_entry",
- make_small(ERST_INTERNAL_CHANNEL_NO));
- erts_this_dist_entry->sysname = am_Noname;
- erts_this_dist_entry->cid = NIL;
- erts_this_dist_entry->connection_id = 0;
- erts_this_dist_entry->status = 0;
- erts_this_dist_entry->flags = 0;
- erts_this_dist_entry->version = 0;
-
- erts_smp_mtx_init_x(&erts_this_dist_entry->lnk_mtx,
- "dist_entry_links",
- make_small(ERST_INTERNAL_CHANNEL_NO));
- erts_this_dist_entry->node_links = NULL;
- erts_this_dist_entry->nlinks = NULL;
- erts_this_dist_entry->monitors = NULL;
-
- erts_smp_mtx_init_x(&erts_this_dist_entry->qlock,
- "dist_entry_out_queue",
- make_small(ERST_INTERNAL_CHANNEL_NO));
- erts_this_dist_entry->qflgs = 0;
- erts_this_dist_entry->qsize = 0;
- erts_this_dist_entry->out_queue.first = NULL;
- erts_this_dist_entry->out_queue.last = NULL;
- erts_this_dist_entry->suspended = NULL;
-
- erts_this_dist_entry->finalized_out_queue.first = NULL;
- erts_this_dist_entry->finalized_out_queue.last = NULL;
- erts_smp_atomic_init_nob(&erts_this_dist_entry->dist_cmd_scheduled, 0);
- erts_port_task_handle_init(&erts_this_dist_entry->dist_cmd);
- erts_this_dist_entry->send = NULL;
- erts_this_dist_entry->cache = NULL;
-
- (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);
-
- f.hash = (H_FUN) node_table_hash;
- f.cmp = (HCMP_FUN) node_table_cmp;
- f.alloc = (HALLOC_FUN) node_table_alloc;
- f.free = (HFREE_FUN) node_table_free;
+ node_tmpl.sysname = am_Noname;
+ node_tmpl.creation = 0;
+ erts_this_node = hash_put(&erts_node_table, &node_tmpl);
+ /* +1 for erts_this_node */
+ erts_refc_init(&erts_this_node->refc, 1);
- hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f);
+ ASSERT(erts_this_node->dist_entry != NULL);
+ erts_this_dist_entry = erts_this_node->dist_entry;
+ /* +1 for erts_this_dist_entry */
+ /* +1 for erts_this_node->dist_entry */
+ erts_refc_init(&erts_this_dist_entry->refc, 2);
- erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode));
- node_entries = 1;
- erts_refc_init(&erts_this_node->refc, 1); /* The system itself */
- erts_this_node->sysname = am_Noname;
- erts_this_node->creation = 0;
- erts_this_node->dist_entry = erts_this_dist_entry;
erts_this_node_sysname = erts_this_node_sysname_BUFFER;
- erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname),
+ erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER),
"%T", erts_this_node->sysname);
- (void) hash_put(&erts_node_table, (void *) erts_this_node);
-
- erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table");
- erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table");
-
references_atoms_need_init = 1;
}
@@ -847,6 +868,7 @@ static Eterm AM_dist_references;
static Eterm AM_node_references;
static Eterm AM_system;
static Eterm AM_timer;
+static Eterm AM_delayed_delete_timer;
static void setup_reference_table(void);
static Eterm reference_table_term(Uint **hpp, Uint *szp);
@@ -881,8 +903,10 @@ typedef struct dist_referrer_ {
int heap_ref;
int node_ref;
int ctrl_ref;
+ int system_ref;
Eterm id;
Uint creation;
+ Uint id_heap[ID_HEAP_SIZE];
} DistReferrer;
typedef struct {
@@ -931,6 +955,7 @@ erts_get_node_and_dist_references(struct process *proc)
INIT_AM(node_references);
INIT_AM(timer);
INIT_AM(system);
+ INIT_AM(delayed_delete_timer);
references_atoms_need_init = 0;
}
@@ -988,17 +1013,25 @@ insert_dist_referrer(ReferredDist *referred_dist,
sizeof(DistReferrer));
drp->next = referred_dist->referrers;
referred_dist->referrers = drp;
- drp->id = id;
+ if(IS_CONST(id))
+ drp->id = id;
+ else {
+ Uint *hp = &drp->id_heap[0];
+ ASSERT(is_tuple(id));
+ drp->id = copy_struct(id, size_object(id), &hp, NULL);
+ }
drp->creation = creation;
drp->heap_ref = 0;
drp->node_ref = 0;
drp->ctrl_ref = 0;
+ drp->system_ref = 0;
}
switch (type) {
case NODE_REF: drp->node_ref++; break;
case CTRL_REF: drp->ctrl_ref++; break;
case HEAP_REF: drp->heap_ref++; break;
+ case SYSTEM_REF: drp->system_ref++; break;
default: ASSERT(0);
}
}
@@ -1017,7 +1050,7 @@ insert_dist_entry(DistEntry *dist, int type, Eterm id, Uint creation)
}
if(!rdp)
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"Reference to non-existing distribution table entry found!\n");
insert_dist_referrer(rdp, type, id, creation);
@@ -1078,7 +1111,7 @@ insert_node(ErlNode *node, int type, Eterm id)
}
if (!rnp)
- erl_exit(1, "Reference to non-existing node table entry found!\n");
+ erts_exit(ERTS_ERROR_EXIT, "Reference to non-existing node table entry found!\n");
insert_node_referrer(rnp, type, id);
}
@@ -1261,6 +1294,33 @@ insert_sys_msg(Eterm from, Eterm to, Eterm msg, ErlHeapFragment *bp)
#endif
static void
+insert_delayed_delete_node(void *state,
+ ErtsMonotonicTime timeout_pos,
+ void *vnp)
+{
+ DeclareTmpHeapNoproc(heap,3);
+ UseTmpHeapNoproc(3);
+ insert_node((ErlNode *) vnp,
+ SYSTEM_REF,
+ TUPLE2(&heap[0], AM_system, AM_delayed_delete_timer));
+ UnUseTmpHeapNoproc(3);
+}
+
+static void
+insert_delayed_delete_dist_entry(void *state,
+ ErtsMonotonicTime timeout_pos,
+ void *vdep)
+{
+ DeclareTmpHeapNoproc(heap,3);
+ UseTmpHeapNoproc(3);
+ insert_dist_entry((DistEntry *) vdep,
+ SYSTEM_REF,
+ TUPLE2(&heap[0], AM_system, AM_delayed_delete_timer),
+ 0);
+ UnUseTmpHeapNoproc(3);
+}
+
+static void
setup_reference_table(void)
{
ErlHeapFragment *hfp;
@@ -1288,11 +1348,22 @@ setup_reference_table(void)
/* Go through the hole system, and build a table of all references
to ErlNode and DistEntry structures */
+ erts_debug_callback_timer_foreach(try_delete_node,
+ insert_delayed_delete_node,
+ NULL);
+ erts_debug_callback_timer_foreach(try_delete_dist_entry,
+ insert_delayed_delete_dist_entry,
+ NULL);
+
UseTmpHeapNoproc(3);
insert_node(erts_this_node,
SYSTEM_REF,
TUPLE2(&heap[0], AM_system, am_undefined));
+ insert_dist_entry(erts_this_dist_entry,
+ SYSTEM_REF,
+ TUPLE2(&heap[0], AM_system, am_undefined),
+ erts_this_node->creation);
UnUseTmpHeapNoproc(3);
max = erts_ptab_max(&erts_proc);
@@ -1355,12 +1426,6 @@ setup_reference_table(void)
insert_links(ERTS_P_LINKS(proc), proc->common.id);
if (ERTS_P_MONITORS(proc))
insert_monitors(ERTS_P_MONITORS(proc), proc->common.id);
- /* Insert controller */
- {
- DistEntry *dep = ERTS_PROC_GET_DIST_ENTRY(proc);
- if (dep)
- insert_dist_entry(dep, CTRL_REF, proc->common.id, 0);
- }
}
}
@@ -1469,7 +1534,7 @@ setup_reference_table(void)
erts_db_foreach_table(insert_ets_table, NULL);
/* Insert all bif timers */
- erts_bif_timer_foreach(insert_bif_timer, NULL);
+ erts_debug_bif_timer_foreach(insert_bif_timer, NULL);
/* Insert node table (references to dist) */
hash_foreach(&erts_node_table, insert_erl_node, NULL);
@@ -1601,7 +1666,7 @@ reference_table_term(Uint **hpp, Uint *szp)
tup = MK_2TUP(referred_nodes[i].node->sysname,
MK_UINT(referred_nodes[i].node->creation));
- tup = MK_3TUP(tup, MK_UINT(erts_refc_read(&referred_nodes[i].node->refc, 1)), nril);
+ tup = MK_3TUP(tup, MK_UINT(erts_refc_read(&referred_nodes[i].node->refc, 0)), nril);
nl = MK_CONS(tup, nl);
}
@@ -1624,6 +1689,10 @@ reference_table_term(Uint **hpp, Uint *szp)
tup = MK_2TUP(AM_heap, MK_UINT(drp->heap_ref));
drl = MK_CONS(tup, drl);
}
+ if(drp->system_ref) {
+ tup = MK_2TUP(AM_system, MK_UINT(drp->system_ref));
+ drl = MK_CONS(tup, drl);
+ }
if (is_internal_pid(drp->id)) {
ASSERT(!drp->node_ref);
@@ -1633,6 +1702,14 @@ reference_table_term(Uint **hpp, Uint *szp)
ASSERT(drp->ctrl_ref && !drp->node_ref);
tup = MK_2TUP(AM_port, drp->id);
}
+ else if (is_tuple(drp->id)) {
+ Eterm *t;
+ ASSERT(drp->system_ref && !drp->node_ref
+ && !drp->ctrl_ref && !drp->heap_ref);
+ t = tuple_val(drp->id);
+ ASSERT(2 == arityval(t[0]));
+ tup = MK_2TUP(t[1], t[2]);
+ }
else {
ASSERT(!drp->ctrl_ref && drp->node_ref);
ASSERT(is_atom(drp->id));
@@ -1650,7 +1727,7 @@ reference_table_term(Uint **hpp, Uint *szp)
/* DistList = [{Dist, Refc, ReferenceIdList}] */
tup = MK_3TUP(referred_dists[i].dist->sysname,
- MK_UINT(erts_refc_read(&referred_dists[i].dist->refc, 1)),
+ MK_UINT(erts_refc_read(&referred_dists[i].dist->refc, 0)),
dril);
dl = MK_CONS(tup, dl);
}
@@ -1705,3 +1782,15 @@ delete_reference_table(void)
}
}
+void
+erts_debug_test_node_tab_delayed_delete(Sint64 millisecs)
+{
+ erts_smp_thr_progress_block();
+
+ if (millisecs < 0)
+ node_tab_delete_delay = orig_node_tab_delete_delay;
+ else
+ node_tab_delete_delay = millisecs;
+
+ erts_smp_thr_progress_unblock();
+}
diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h
index af60071ea5..694ac84232 100644
--- a/erts/emulator/beam/erl_node_tables.h
+++ b/erts/emulator/beam/erl_node_tables.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -46,6 +47,10 @@
#define ERTS_PORT_TASK_ONLY_BASIC_TYPES__
#include "erl_port_task.h"
#undef ERTS_PORT_TASK_ONLY_BASIC_TYPES__
+
+#define ERTS_NODE_TAB_DELAY_GC_DEFAULT (60)
+#define ERTS_NODE_TAB_DELAY_GC_MAX (100*1000*1000)
+#define ERTS_NODE_TAB_DELAY_GC_INFINITY (ERTS_NODE_TAB_DELAY_GC_MAX+1)
#define ERST_INTERNAL_CHANNEL_NO 0
@@ -166,20 +171,21 @@ extern DistEntry *erts_this_dist_entry;
extern ErlNode *erts_this_node;
extern char *erts_this_node_sysname; /* must match erl_node_tables.c */
+Uint erts_delayed_node_table_gc(void);
DistEntry *erts_channel_no_to_dist_entry(Uint);
DistEntry *erts_sysname_to_connected_dist_entry(Eterm);
DistEntry *erts_find_or_insert_dist_entry(Eterm);
DistEntry *erts_find_dist_entry(Eterm);
-void erts_delete_dist_entry(DistEntry *);
+void erts_schedule_delete_dist_entry(DistEntry *);
Uint erts_dist_table_size(void);
void erts_dist_table_info(int, 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, Uint);
-void erts_delete_node(ErlNode *);
+void erts_schedule_delete_node(ErlNode *);
void erts_set_this_node(Eterm, Uint);
Uint erts_node_table_size(void);
-void erts_init_node_tables(void);
+void erts_init_node_tables(int);
void erts_node_table_info(int, void *);
void erts_print_node_info(int, void *, Eterm, int*, int*);
Eterm erts_get_node_and_dist_references(struct process *);
@@ -204,7 +210,7 @@ erts_deref_dist_entry(DistEntry *dep)
{
ASSERT(dep);
if (erts_refc_dectest(&dep->refc, 0) == 0)
- erts_delete_dist_entry(dep);
+ erts_schedule_delete_dist_entry(dep);
}
ERTS_GLB_INLINE void
@@ -212,7 +218,7 @@ erts_deref_node_entry(ErlNode *np)
{
ASSERT(np);
if (erts_refc_dectest(&np->refc, 0) == 0)
- erts_delete_node(np);
+ erts_schedule_delete_node(np);
}
ERTS_GLB_INLINE void
@@ -253,5 +259,6 @@ erts_smp_de_links_unlock(DistEntry *dep)
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
+void erts_debug_test_node_tab_delayed_delete(Sint64 millisecs);
#endif
diff --git a/erts/emulator/beam/erl_port.h b/erts/emulator/beam/erl_port.h
index ad3f104a68..acd68ef0ad 100644
--- a/erts/emulator/beam/erl_port.h
+++ b/erts/emulator/beam/erl_port.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -266,8 +267,7 @@ erts_prtsd_set(Port *prt, int ix, void *data)
#endif
-extern erts_smp_atomic_t erts_bytes_out; /* no bytes written out */
-extern erts_smp_atomic_t erts_bytes_in; /* no bytes sent into the system */
+Eterm erts_request_io_bytes(Process *c_p);
/* port status flags */
@@ -350,6 +350,7 @@ int erts_lc_is_port_locked(Port *);
ERTS_GLB_INLINE void erts_port_inc_refc(Port *prt);
ERTS_GLB_INLINE void erts_port_dec_refc(Port *prt);
ERTS_GLB_INLINE void erts_port_add_refc(Port *prt, Sint32 add_refc);
+ERTS_GLB_INLINE Sint erts_port_read_refc(Port *prt);
ERTS_GLB_INLINE int erts_smp_port_trylock(Port *prt);
ERTS_GLB_INLINE void erts_smp_port_lock(Port *prt);
@@ -359,37 +360,26 @@ ERTS_GLB_INLINE void erts_smp_port_unlock(Port *prt);
ERTS_GLB_INLINE void erts_port_inc_refc(Port *prt)
{
-#ifdef ERTS_SMP
- erts_ptab_inc_refc(&prt->common);
-#else
- erts_atomic32_inc_nob(&prt->refc);
-#endif
+ erts_ptab_atmc_inc_refc(&prt->common);
}
ERTS_GLB_INLINE void erts_port_dec_refc(Port *prt)
{
-#ifdef ERTS_SMP
- int referred = erts_ptab_dec_test_refc(&prt->common);
+ int referred = erts_ptab_atmc_dec_test_refc(&prt->common);
if (!referred)
erts_port_free(prt);
-#else
- int refc = erts_atomic32_dec_read_nob(&prt->refc);
- if (refc == 0)
- erts_port_free(prt);
-#endif
}
ERTS_GLB_INLINE void erts_port_add_refc(Port *prt, Sint32 add_refc)
{
-#ifdef ERTS_SMP
- int referred = erts_ptab_add_test_refc(&prt->common, add_refc);
+ int referred = erts_ptab_atmc_add_test_refc(&prt->common, add_refc);
if (!referred)
erts_port_free(prt);
-#else
- int refc = erts_atomic32_add_read_nob(&prt->refc, add_refc);
- if (refc == 0)
- erts_port_free(prt);
-#endif
+}
+
+ERTS_GLB_INLINE Sint erts_port_read_refc(Port *prt)
+{
+ return erts_ptab_atmc_read_refc(&prt->common);
}
ERTS_GLB_INLINE int
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 2aa0a27197..ddcca06b0a 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -1646,6 +1647,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
erts_aint32_t state;
int active;
Uint64 start_time = 0;
+ ErtsSchedulerData *esdp = runq->scheduler;
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(runq));
@@ -1662,7 +1664,6 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
*curr_port_pp = pp;
if (erts_sched_stat.enabled) {
- ErtsSchedulerData *esdp = erts_get_scheduler_data();
Uint old = ERTS_PORT_SCHED_ID(pp, esdp->no);
int migrated = old && old != esdp->no;
@@ -1718,11 +1719,16 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
switch (ptp->type) {
case ERTS_PORT_TASK_TIMEOUT:
reset_handle(ptp);
- reds = ERTS_PORT_REDS_TIMEOUT;
- if (!(state & ERTS_PORT_SFLGS_DEAD)) {
- DTRACE_DRIVER(driver_timeout, pp);
- (*pp->drv_ptr->timeout)((ErlDrvData) pp->drv_data);
- }
+ if (!ERTS_PTMR_IS_TIMED_OUT(pp))
+ reds = 0;
+ else {
+ ERTS_PTMR_CLEAR(pp);
+ reds = ERTS_PORT_REDS_TIMEOUT;
+ if (!(state & ERTS_PORT_SFLGS_DEAD)) {
+ DTRACE_DRIVER(driver_timeout, pp);
+ (*pp->drv_ptr->timeout)((ErlDrvData) pp->drv_data);
+ }
+ }
break;
case ERTS_PORT_TASK_INPUT:
reds = ERTS_PORT_REDS_INPUT;
@@ -1778,7 +1784,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
reds = erts_dist_command(pp, CONTEXT_REDS - pp->reds);
break;
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Invalid port task type: %d\n",
(int) ptp->type);
break;
@@ -1879,7 +1885,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
runq->scheduler->reductions += reds;
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(runq));
- ERTS_PORT_REDUCTIONS_EXECUTED(runq, reds);
+ ERTS_PORT_REDUCTIONS_EXECUTED(esdp, runq, reds);
return res;
}
@@ -2042,7 +2048,7 @@ begin_port_cleanup(Port *pp, ErtsPortTask **execqp, int *processing_busy_q_p)
break;
}
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Invalid port task type: %d\n",
(int) ptp->type);
}
diff --git a/erts/emulator/beam/erl_port_task.h b/erts/emulator/beam/erl_port_task.h
index 406cd3c492..335f7a77d5 100644
--- a/erts/emulator/beam/erl_port_task.h
+++ b/erts/emulator/beam/erl_port_task.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c
index d18760dc43..2917d58932 100644
--- a/erts/emulator/beam/erl_printf_term.c
+++ b/erts/emulator/beam/erl_printf_term.c
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2013. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -25,6 +26,7 @@
#include "sys.h"
#include "big.h"
#include "erl_map.h"
+#include "erl_binary.h"
#define PRINT_CHAR(CNT, FN, ARG, C) \
do { \
@@ -138,6 +140,25 @@ is_printable_string(Eterm list, Eterm* base)
return 0;
}
+static int is_printable_ascii(byte* bytep, Uint bytesize, Uint bitoffs)
+{
+ if (!bitoffs) {
+ while (bytesize--) {
+ if (*bytep < ' ' || *bytep >= 127)
+ return 0;
+ bytep++;
+ }
+ } else {
+ while (bytesize--) {
+ byte octet = (bytep[0] << bitoffs) | (bytep[1] >> (8-bitoffs));
+ if (octet < ' ' || octet >= 127)
+ return 0;
+ bytep++;
+ }
+ }
+ return 1;
+}
+
/* print a atom doing what quoting is necessary */
static int print_atom_name(fmtfn_t fn, void* arg, Eterm atom, long *dcount)
{
@@ -227,6 +248,17 @@ static int print_atom_name(fmtfn_t fn, void* arg, Eterm atom, long *dcount)
#define PRT_PATCH_FUN_SIZE ((Eterm) 7)
#define PRT_LAST_ARRAY_ELEMENT ((Eterm) 8) /* Note! Must be last... */
+#if 0
+static char *format_binary(Uint16 x, char *b) {
+ int z;
+ b[16] = '\0';
+ for (z = 0; z < 16; z++) {
+ b[15-z] = ((x>>z) & 0x1) ? '1' : '0';
+ }
+ return b;
+}
+#endif
+
static int
print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
Eterm* obj_base) /* ignored if !HALFWORD_HEAP */
@@ -283,13 +315,9 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
tl = CDR(cons);
if (is_not_nil(tl)) {
if (is_list(tl)) {
- WSTACK_PUSH(s, tl);
- WSTACK_PUSH(s, PRT_ONE_CONS);
- WSTACK_PUSH(s, PRT_COMMA);
+ WSTACK_PUSH3(s, tl, PRT_ONE_CONS, PRT_COMMA);
} else {
- WSTACK_PUSH(s, tl);
- WSTACK_PUSH(s, PRT_TERM);
- WSTACK_PUSH(s, PRT_BAR);
+ WSTACK_PUSH3(s, tl, PRT_TERM, PRT_BAR);
}
}
}
@@ -299,9 +327,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
break;
default: /* PRT_LAST_ARRAY_ELEMENT+1 and upwards */
obj = *popped.ptr;
- WSTACK_PUSH(s, (UWord) (popped.ptr + 1));
- WSTACK_PUSH(s, val-1);
- WSTACK_PUSH(s, PRT_COMMA);
+ WSTACK_PUSH3(s, (UWord) (popped.ptr + 1), val-1, PRT_COMMA);
break;
}
break;
@@ -431,8 +457,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
WSTACK_PUSH(s,PRT_CLOSE_TUPLE);
++nobj;
if (i > 0) {
- WSTACK_PUSH(s, (UWord) nobj);
- WSTACK_PUSH(s, PRT_LAST_ARRAY_ELEMENT+i-1);
+ WSTACK_PUSH2(s, (UWord) nobj, PRT_LAST_ARRAY_ELEMENT+i-1);
}
break;
case FLOAT_DEF: {
@@ -442,17 +467,66 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
}
break;
case BINARY_DEF:
- if (header_is_bin_matchstate(*boxed_val(wobj))) {
- PRINT_STRING(res, fn, arg, "#MatchState");
- }
- else {
- ProcBin* pb = (ProcBin *) binary_val(wobj);
- if (pb->size == 1)
- PRINT_STRING(res, fn, arg, "<<1 byte>>");
- else {
+ {
+ byte* bytep;
+ Uint bytesize = binary_size_rel(obj,obj_base);
+ Uint bitoffs;
+ Uint bitsize;
+ byte octet;
+ ERTS_GET_BINARY_BYTES_REL(obj, bytep, bitoffs, bitsize, obj_base);
+
+ if (bitsize || !bytesize
+ || !is_printable_ascii(bytep, bytesize, bitoffs)) {
+ int is_first = 1;
PRINT_STRING(res, fn, arg, "<<");
- PRINT_UWORD(res, fn, arg, 'u', 0, 1, (ErlPfUWord) pb->size);
- PRINT_STRING(res, fn, arg, " bytes>>");
+ while (bytesize) {
+ if (is_first)
+ is_first = 0;
+ else
+ PRINT_CHAR(res, fn, arg, ',');
+ if (bitoffs)
+ octet = (bytep[0] << bitoffs) | (bytep[1] >> (8-bitoffs));
+ else
+ octet = bytep[0];
+ PRINT_UWORD(res, fn, arg, 'u', 0, 1, octet);
+ ++bytep;
+ --bytesize;
+ }
+ if (bitsize) {
+ Uint bits = bitoffs + bitsize;
+ octet = bytep[0];
+ if (bits < 8)
+ octet >>= 8 - bits;
+ else if (bits > 8) {
+ bits -= 8; /* bits in last byte */
+ octet <<= bits;
+ octet |= bytep[1] >> (8 - bits);
+ }
+ octet &= (1 << bitsize) - 1;
+ if (is_first)
+ is_first = 0;
+ else
+ PRINT_CHAR(res, fn, arg, ',');
+ PRINT_UWORD(res, fn, arg, 'u', 0, 1, octet);
+ PRINT_CHAR(res, fn, arg, ':');
+ PRINT_UWORD(res, fn, arg, 'u', 0, 1, bitsize);
+ }
+ PRINT_STRING(res, fn, arg, ">>");
+ }
+ else {
+ PRINT_STRING(res, fn, arg, "<<\"");
+ while (bytesize) {
+ if (bitoffs)
+ octet = (bytep[0] << bitoffs) | (bytep[1] >> (8-bitoffs));
+ else
+ octet = bytep[0];
+ if (octet == '"')
+ PRINT_CHAR(res, fn, arg, '\\');
+ PRINT_CHAR(res, fn, arg, octet);
+ ++bytep;
+ --bytesize;
+ }
+ PRINT_STRING(res, fn, arg, "\">>");
}
}
break;
@@ -489,37 +563,77 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
}
break;
case MAP_DEF:
- {
- Uint n;
- Eterm *ks, *vs;
- map_t *mp = (map_t *)map_val(wobj);
- n = map_get_size(mp);
- ks = map_get_keys(mp);
- vs = map_get_values(mp);
-
- PRINT_CHAR(res, fn, arg, '#');
- PRINT_CHAR(res, fn, arg, '{');
- WSTACK_PUSH(s, PRT_CLOSE_TUPLE);
- if (n > 0) {
- n--;
- WSTACK_PUSH(s, vs[n]);
- WSTACK_PUSH(s, PRT_TERM);
- WSTACK_PUSH(s, PRT_ASSOC);
- WSTACK_PUSH(s, ks[n]);
- WSTACK_PUSH(s, PRT_TERM);
-
- while (n--) {
- WSTACK_PUSH(s, PRT_COMMA);
- WSTACK_PUSH(s, vs[n]);
- WSTACK_PUSH(s, PRT_TERM);
- WSTACK_PUSH(s, PRT_ASSOC);
- WSTACK_PUSH(s, ks[n]);
- WSTACK_PUSH(s, PRT_TERM);
- }
- }
- }
+ if (is_flatmap(wobj)) {
+ Uint n;
+ Eterm *ks, *vs;
+ flatmap_t *mp = (flatmap_t *)flatmap_val(wobj);
+ n = flatmap_get_size(mp);
+ ks = flatmap_get_keys(mp);
+ vs = flatmap_get_values(mp);
+
+ PRINT_CHAR(res, fn, arg, '#');
+ PRINT_CHAR(res, fn, arg, '{');
+ WSTACK_PUSH(s, PRT_CLOSE_TUPLE);
+ if (n > 0) {
+ n--;
+ WSTACK_PUSH5(s, vs[n], PRT_TERM, PRT_ASSOC, ks[n], PRT_TERM);
+ while (n--) {
+ WSTACK_PUSH6(s, PRT_COMMA, vs[n], PRT_TERM, PRT_ASSOC,
+ ks[n], PRT_TERM);
+ }
+ }
+ } else {
+ Uint n, mapval;
+ Eterm *head;
+ head = hashmap_val(wobj);
+ mapval = MAP_HEADER_VAL(*head);
+ switch (MAP_HEADER_TYPE(*head)) {
+ case MAP_HEADER_TAG_HAMT_HEAD_ARRAY:
+ case MAP_HEADER_TAG_HAMT_HEAD_BITMAP:
+ PRINT_STRING(res, fn, arg, "#<");
+ PRINT_UWORD(res, fn, arg, 'x', 0, 1, mapval);
+ PRINT_STRING(res, fn, arg, ">{");
+ WSTACK_PUSH(s,PRT_CLOSE_TUPLE);
+ n = hashmap_bitcount(mapval);
+ ASSERT(n < 17);
+ head += 2;
+ if (n > 0) {
+ n--;
+ WSTACK_PUSH(s, head[n]);
+ WSTACK_PUSH(s, PRT_TERM);
+ while (n--) {
+ WSTACK_PUSH(s, PRT_COMMA);
+ WSTACK_PUSH(s, head[n]);
+ WSTACK_PUSH(s, PRT_TERM);
+ }
+ }
+ break;
+ case MAP_HEADER_TAG_HAMT_NODE_BITMAP:
+ n = hashmap_bitcount(mapval);
+ head++;
+ PRINT_CHAR(res, fn, arg, '<');
+ PRINT_UWORD(res, fn, arg, 'x', 0, 1, mapval);
+ PRINT_STRING(res, fn, arg, ">{");
+ WSTACK_PUSH(s,PRT_CLOSE_TUPLE);
+ ASSERT(n < 17);
+ if (n > 0) {
+ n--;
+ WSTACK_PUSH(s, head[n]);
+ WSTACK_PUSH(s, PRT_TERM);
+ while (n--) {
+ WSTACK_PUSH(s, PRT_COMMA);
+ WSTACK_PUSH(s, head[n]);
+ WSTACK_PUSH(s, PRT_TERM);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case MATCHSTATE_DEF:
+ PRINT_STRING(res, fn, arg, "#MatchState");
break;
- default:
+ default:
PRINT_STRING(res, fn, arg, "<unknown:");
PRINT_POINTER(res, fn, arg, wobj);
PRINT_CHAR(res, fn, arg, '>');
@@ -528,17 +642,17 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
}
L_done:
-
DESTROY_WSTACK(s);
return res;
}
+
int
erts_printf_term(fmtfn_t fn, void* arg, ErlPfEterm term, long precision,
ErlPfEterm* term_base)
{
int res;
- ASSERT(sizeof(ErlPfEterm) == sizeof(Eterm));
+ ERTS_CT_ASSERT(sizeof(ErlPfEterm) == sizeof(Eterm));
res = print_term(fn, arg, (Eterm)term, &precision, (Eterm*)term_base);
if (res < 0)
diff --git a/erts/emulator/beam/erl_printf_term.h b/erts/emulator/beam/erl_printf_term.h
index f92c99d713..87618a36d7 100644
--- a/erts/emulator/beam/erl_printf_term.h
+++ b/erts/emulator/beam/erl_printf_term.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index ea63d20dfa..4ec98d5cc7 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -43,8 +44,11 @@
#include "erl_async.h"
#include "dtrace-wrapper.h"
#include "erl_ptab.h"
+#include "erl_bif_unique.h"
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
-
+#define ERTS_CHECK_TIME_REDS CONTEXT_REDS
#define ERTS_DELAYED_WAKEUP_INFINITY (~(Uint64) 0)
#define ERTS_DELAYED_WAKEUP_REDUCTIONS ((Uint64) CONTEXT_REDS/2)
@@ -152,7 +156,7 @@ extern BeamInstr beam_continue_exit[];
/* Eager check I/O not supported on OSE yet. */
int erts_eager_check_io = 0;
#else
-int erts_eager_check_io = 0;
+int erts_eager_check_io = 1;
#endif
int erts_sched_compact_load;
int erts_sched_balance_util = 0;
@@ -162,6 +166,9 @@ Uint erts_no_dirty_cpu_schedulers;
Uint erts_no_dirty_io_schedulers;
#endif
+static char *erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_NO_FLAGS] = {0};
+int erts_aux_work_no_flags = ERTS_SSI_AUX_WORK_NO_FLAGS;
+
#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_VERY_LAZY (4*1024*1024)
#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_LAZY (512*1024)
#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_MEDIUM (64*1024)
@@ -346,6 +353,7 @@ struct erts_system_monitor_flags_t erts_system_monitor_flags;
/* system performance monitor */
Eterm erts_system_profile;
struct erts_system_profile_flags_t erts_system_profile_flags;
+int erts_system_profile_ts_type = ERTS_TRACE_FLG_NOW_TIMESTAMP;
#if ERTS_MAX_PROCESSES > 0x7fffffff
#error "Need to store process_count in another type"
@@ -457,13 +465,12 @@ 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, Process* p, Eterm* sp,
- int yreg);
+static int stack_element_dump(int 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);
static void aux_work_timeout_late_init(void);
-static void setup_aux_work_timer(void);
+static void setup_aux_work_timer(ErtsSchedulerData *esdp);
static int execute_sys_tasks(Process *c_p,
erts_aint32_t *statep,
@@ -493,6 +500,8 @@ dbg_chk_aux_work_val(erts_aint32_t value)
valid |= ERTS_SSI_AUX_WORK_MISC_THR_PRGR;
valid |= ERTS_SSI_AUX_WORK_DD;
valid |= ERTS_SSI_AUX_WORK_DD_THR_PRGR;
+ valid |= ERTS_SSI_AUX_WORK_CNCLD_TMRS;
+ valid |= ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR;
valid |= ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP;
#endif
#if HAVE_ERTS_MSEG
@@ -504,9 +513,10 @@ dbg_chk_aux_work_val(erts_aint32_t value)
#ifdef ERTS_SSI_AUX_WORK_REAP_PORTS
valid |= ERTS_SSI_AUX_WORK_REAP_PORTS;
#endif
+ valid |= ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED;
if (~valid & value)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Invalid aux_work value found: 0x%x\n",
~valid & value);
}
@@ -562,6 +572,41 @@ erts_pre_init_process(void)
erts_tsd_key_create(&sched_data_key, "erts_sched_data_key");
#endif
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP_IX]
+ = "DELAYED_AW_WAKEUP";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_DD_IX]
+ = "DD";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_DD_THR_PRGR_IX]
+ = "DD_THR_PRGR";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC_IX]
+ = "FIX_ALLOC_DEALLOC";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM_IX]
+ = "FIX_ALLOC_LOWER_LIM";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP_IX]
+ = "THR_PRGR_LATER_OP";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_CNCLD_TMRS_IX]
+ = "CNCLD_TMRS";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR_IX]
+ = "CNCLD_TMRS_THR_PRGR";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_ASYNC_READY_IX]
+ = "ASYNC_READY";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN_IX]
+ = "ASYNC_READY_CLEAN";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_MISC_THR_PRGR_IX]
+ = "MISC_THR_PRGR";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_MISC_IX]
+ = "MISC";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_CHECK_CHILDREN_IX]
+ = "CHECK_CHILDREN";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_SET_TMO_IX]
+ = "SET_TMO";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK_IX]
+ = "MSEG_CACHE_CHECK";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_REAP_PORTS_IX]
+ = "REAP_PORTS";
+ erts_aux_work_flag_descr[ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED_IX]
+ = "DEBUG_WAIT_COMPLETED";
+
#ifdef ERTS_ENABLE_LOCK_CHECK
{
int ix;
@@ -581,11 +626,6 @@ erts_pre_init_process(void)
erts_psd_required_locks[ERTS_PSD_SCHED_ID].set_locks
= ERTS_PSD_SCHED_ID_SET_LOCKS;
- erts_psd_required_locks[ERTS_PSD_DIST_ENTRY].get_locks
- = ERTS_PSD_DIST_ENTRY_GET_LOCKS;
- erts_psd_required_locks[ERTS_PSD_DIST_ENTRY].set_locks
- = ERTS_PSD_DIST_ENTRY_SET_LOCKS;
-
erts_psd_required_locks[ERTS_PSD_CALL_TIME_BP].get_locks
= ERTS_PSD_CALL_TIME_BP_GET_LOCKS;
erts_psd_required_locks[ERTS_PSD_CALL_TIME_BP].set_locks
@@ -610,13 +650,11 @@ erts_pre_init_process(void)
#endif
}
-#ifdef ERTS_SMP
static void
release_process(void *vproc)
{
- erts_smp_proc_dec_refc((Process *) vproc);
+ erts_proc_dec_refc((Process *) vproc);
}
-#endif
/* initialize the scheduler */
void
@@ -632,16 +670,18 @@ erts_init_process(int ncpu, int proc_tab_size, int legacy_proc_tab)
erts_ptab_init_table(&erts_proc,
ERTS_ALC_T_PROC_TABLE,
-#ifdef ERTS_SMP
release_process,
-#else
- NULL,
-#endif
(ErtsPTabElementCommon *) &erts_invalid_process.common,
proc_tab_size,
sizeof(Process),
"process_table",
- legacy_proc_tab);
+ legacy_proc_tab,
+#ifdef ERTS_SMP
+ 1
+#else
+ 0
+#endif
+ );
last_reductions = 0;
last_exact_reductions = 0;
@@ -702,8 +742,8 @@ init_sched_wall_time(ErtsSchedWallTime *swtp)
static ERTS_INLINE Uint64
sched_wall_time_ts(void)
{
-#ifdef HAVE_GETHRTIME
- return (Uint64) sys_gethrtime();
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ return (Uint64) erts_os_monotonic_time();
#else
Uint64 res;
SysTimeval tv;
@@ -927,11 +967,25 @@ typedef struct {
erts_smp_atomic32_t refc;
} ErtsSchedWallTimeReq;
+typedef struct {
+ Process *proc;
+ Eterm ref;
+ Eterm ref_heap[REF_THING_SIZE];
+ Uint req_sched;
+ erts_smp_atomic32_t refc;
+} ErtsSystemCheckReq;
+
+
#if !HALFWORD_HEAP
ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(swtreq,
ErtsSchedWallTimeReq,
5,
ERTS_ALC_T_SCHED_WTIME_REQ)
+
+ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(screq,
+ ErtsSystemCheckReq,
+ 5,
+ ERTS_ALC_T_SYS_CHECK_REQ)
#else
static ERTS_INLINE ErtsSchedWallTimeReq *
swtreq_alloc(void)
@@ -945,6 +999,19 @@ swtreq_free(ErtsSchedWallTimeReq *ptr)
{
erts_free(ERTS_ALC_T_SCHED_WTIME_REQ, ptr);
}
+
+static ERTS_INLINE ErtsSystemCheckReq *
+screq_alloc(void)
+{
+ return erts_alloc(ERTS_ALC_T_SYS_CHECK_REQ,
+ sizeof(ErtsSystemCheckReq));
+}
+
+static ERTS_INLINE void
+screq_free(ErtsSystemCheckReq *ptr)
+{
+ erts_free(ERTS_ALC_T_SYS_CHECK_REQ, ptr);
+}
#endif
static void
@@ -1023,11 +1090,7 @@ reply_sched_wall_time(void *vswtrp)
hpp = &hp;
}
- erts_queue_message(rp, &rp_locks, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL);
if (swtrp->req_sched == esdp->no)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
@@ -1035,7 +1098,7 @@ reply_sched_wall_time(void *vswtrp)
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
if (erts_smp_atomic32_dec_read_nob(&swtrp->refc) == 0)
swtreq_free(vswtrp);
@@ -1067,7 +1130,7 @@ erts_sched_wall_time_request(Process *c_p, int set, int enable)
erts_smp_atomic32_init_nob(&swtrp->refc,
(erts_aint32_t) erts_no_schedulers);
- erts_smp_proc_add_refc(c_p, (Sint32) erts_no_schedulers);
+ erts_proc_add_refc(c_p, (Sint32) erts_no_schedulers);
#ifdef ERTS_SMP
if (erts_no_schedulers > 1)
@@ -1082,6 +1145,75 @@ erts_sched_wall_time_request(Process *c_p, int set, int enable)
return ref;
}
+static void
+reply_system_check(void *vscrp)
+{
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ ErtsSystemCheckReq *scrp = (ErtsSystemCheckReq *) vscrp;
+ ErtsProcLocks rp_locks = (scrp->req_sched == esdp->no ? ERTS_PROC_LOCK_MAIN : 0);
+ Process *rp = scrp->proc;
+ Eterm msg;
+ Eterm *hp = NULL;
+ Eterm **hpp;
+ Uint sz;
+ ErlOffHeap *ohp = NULL;
+ ErlHeapFragment *bp = NULL;
+
+ ASSERT(esdp);
+#ifdef ERTS_DIRTY_SCHEDULERS
+ ASSERT(!ERTS_SCHEDULER_IS_DIRTY(esdp));
+#endif
+
+ sz = REF_THING_SIZE;
+ hp = erts_alloc_message_heap(sz, &bp, &ohp, rp, &rp_locks);
+ hpp = &hp;
+ msg = STORE_NC(hpp, ohp, scrp->ref);
+
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL);
+
+ if (scrp->req_sched == esdp->no)
+ rp_locks &= ~ERTS_PROC_LOCK_MAIN;
+
+ if (rp_locks)
+ erts_smp_proc_unlock(rp, rp_locks);
+
+ erts_proc_dec_refc(rp);
+
+ if (erts_smp_atomic32_dec_read_nob(&scrp->refc) == 0)
+ screq_free(vscrp);
+}
+
+
+Eterm erts_system_check_request(Process *c_p) {
+ ErtsSchedulerData *esdp = ERTS_PROC_GET_SCHDATA(c_p);
+ Eterm ref;
+ ErtsSystemCheckReq *scrp;
+ Eterm *hp;
+
+ scrp = screq_alloc();
+ ref = erts_make_ref(c_p);
+ hp = &scrp->ref_heap[0];
+
+ scrp->proc = c_p;
+ scrp->ref = STORE_NC(&hp, NULL, ref);
+ scrp->req_sched = esdp->no;
+ erts_smp_atomic32_init_nob(&scrp->refc, (erts_aint32_t) erts_no_schedulers);
+
+ erts_proc_add_refc(c_p, (Sint) erts_no_schedulers);
+
+#ifdef ERTS_SMP
+ if (erts_no_schedulers > 1)
+ erts_schedule_multi_misc_aux_work(1,
+ erts_no_schedulers,
+ reply_system_check,
+ (void *) scrp);
+#endif
+
+ reply_system_check((void *) scrp);
+
+ return ref;
+}
+
static ERTS_INLINE ErtsProcList *
proclist_create(Process *p)
{
@@ -1128,7 +1260,7 @@ erts_psd_set_init(Process *p, ErtsProcLocks plocks, int ix, void *data)
xplocks &= ~plocks;
if (xplocks && erts_smp_proc_trylock(p, xplocks) == EBUSY) {
if (xplocks & ERTS_PROC_LOCK_MAIN) {
- erts_smp_proc_inc_refc(p);
+ erts_proc_inc_refc(p);
erts_smp_proc_unlock(p, plocks);
erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL);
refc = 1;
@@ -1144,7 +1276,7 @@ erts_psd_set_init(Process *p, ErtsProcLocks plocks, int ix, void *data)
if (xplocks)
erts_smp_proc_unlock(p, xplocks);
if (refc)
- erts_smp_proc_dec_refc(p);
+ erts_proc_dec_refc(p);
ASSERT(p->psd);
if (p->psd != psd)
erts_free(ERTS_ALC_T_PSD, psd);
@@ -1176,7 +1308,7 @@ erts_sched_finish_poke(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flags)
case 0:
break;
default:
- erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error\n",
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error\n",
__FILE__, __LINE__);
break;
}
@@ -1193,11 +1325,11 @@ set_aux_work_flags_wakeup_nob(ErtsSchedulerSleepInfo *ssi,
ERTS_DBG_CHK_SSI_AUX_WORK(ssi);
old_flgs = erts_atomic32_read_nob(&ssi->aux_work);
- if ((old_flgs & flgs) == 0) {
+ if ((old_flgs & flgs) != flgs) {
old_flgs = erts_atomic32_read_bor_nob(&ssi->aux_work, flgs);
- if ((old_flgs & flgs) == 0) {
+ if ((old_flgs & flgs) != flgs) {
#ifdef ERTS_SMP
erts_sched_poke(ssi);
#else
@@ -1217,7 +1349,7 @@ set_aux_work_flags_wakeup_relb(ErtsSchedulerSleepInfo *ssi,
old_flgs = erts_atomic32_read_bor_relb(&ssi->aux_work, flgs);
- if ((old_flgs & flgs) == 0) {
+ if ((old_flgs & flgs) != flgs) {
#ifdef ERTS_SMP
erts_sched_poke(ssi);
#else
@@ -1715,11 +1847,6 @@ handle_delayed_dealloc(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waitin
awdp->dd.thr_prgr = wakeup;
haw_thr_prgr_soft_wakeup(awdp, wakeup);
}
- else if (awdp->dd.completed_callback) {
- awdp->dd.completed_callback(awdp->dd.completed_arg);
- awdp->dd.completed_callback = NULL;
- awdp->dd.completed_arg = NULL;
- }
return aux_work & ~ERTS_SSI_AUX_WORK_DD;
}
@@ -1761,17 +1888,107 @@ handle_delayed_dealloc_thr_prgr(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, i
}
else {
unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_DD_THR_PRGR);
- if (awdp->dd.completed_callback) {
- awdp->dd.completed_callback(awdp->dd.completed_arg);
- awdp->dd.completed_callback = NULL;
- awdp->dd.completed_arg = NULL;
- }
}
return aux_work & ~ERTS_SSI_AUX_WORK_DD_THR_PRGR;
}
/*
+ * Canceled timers
+ */
+
+void
+erts_notify_canceled_timer(ErtsSchedulerData *esdp, int rsid)
+{
+ ASSERT(esdp && esdp == erts_get_scheduler_data());
+ if (esdp && !ERTS_SCHEDULER_IS_DIRTY(esdp))
+ schedule_aux_work_wakeup(&esdp->aux_work_data,
+ rsid,
+ ERTS_SSI_AUX_WORK_CNCLD_TMRS);
+ else
+ set_aux_work_flags_wakeup_relb(ERTS_SCHED_SLEEP_INFO_IX(rsid-1),
+ ERTS_SSI_AUX_WORK_CNCLD_TMRS);
+}
+
+static ERTS_INLINE erts_aint32_t
+handle_canceled_timers(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting)
+{
+ ErtsSchedulerSleepInfo *ssi = awdp->ssi;
+ int need_thr_progress = 0;
+ ErtsThrPrgrVal wakeup = ERTS_THR_PRGR_INVALID;
+ int more_work = 0;
+
+#ifdef ERTS_DIRTY_SCHEDULERS
+ ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp));
+#endif
+ unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS);
+ erts_handle_canceled_timers((void *) awdp->esdp,
+ &need_thr_progress,
+ &wakeup,
+ &more_work);
+ if (more_work) {
+ if (set_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS)
+ & ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR) {
+ unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR);
+ aux_work &= ~ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR;
+ }
+ return aux_work;
+ }
+
+ if (need_thr_progress) {
+ if (wakeup == ERTS_THR_PRGR_INVALID)
+ wakeup = erts_thr_progress_later(awdp->esdp);
+ awdp->cncld_tmrs.thr_prgr = wakeup;
+ set_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR);
+ haw_thr_prgr_soft_wakeup(awdp, wakeup);
+ }
+ return aux_work & ~ERTS_SSI_AUX_WORK_CNCLD_TMRS;
+}
+
+static ERTS_INLINE erts_aint32_t
+handle_canceled_timers_thr_prgr(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting)
+{
+ ErtsSchedulerSleepInfo *ssi;
+ int need_thr_progress;
+ int more_work;
+ ErtsThrPrgrVal wakeup = ERTS_THR_PRGR_INVALID;
+ ErtsThrPrgrVal current = haw_thr_prgr_current(awdp);
+
+#ifdef ERTS_DIRTY_SCHEDULERS
+ ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp));
+#endif
+ if (!erts_thr_progress_has_reached_this(current, awdp->cncld_tmrs.thr_prgr))
+ return aux_work & ~ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR;
+
+ ssi = awdp->ssi;
+ need_thr_progress = 0;
+ more_work = 0;
+
+ erts_handle_canceled_timers((void *) awdp->esdp,
+ &need_thr_progress,
+ &wakeup,
+ &more_work);
+ if (more_work) {
+ set_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS);
+ unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR);
+ return ((aux_work & ~ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR)
+ | ERTS_SSI_AUX_WORK_CNCLD_TMRS);
+ }
+
+ if (need_thr_progress) {
+ if (wakeup == ERTS_THR_PRGR_INVALID)
+ wakeup = erts_thr_progress_later(awdp->esdp);
+ awdp->cncld_tmrs.thr_prgr = wakeup;
+ haw_thr_prgr_soft_wakeup(awdp, wakeup);
+ }
+ else {
+ unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR);
+ }
+
+ return aux_work & ~ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR;
+}
+
+/*
* Handle scheduled thread progress later operations.
*/
#define ERTS_MAX_THR_PRGR_LATER_OPS 50
@@ -1860,78 +2077,142 @@ erts_schedule_thr_prgr_later_cleanup_op(void (*later_func)(void *),
#endif
}
-#ifdef ERTS_SMP
+static ERTS_INLINE erts_aint32_t
+handle_debug_wait_completed(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting)
+{
+ ErtsSchedulerSleepInfo *ssi = awdp->ssi;
+ erts_aint32_t saved_aux_work, flags;
-static erts_atomic32_t completed_dealloc_count;
+#ifdef ERTS_DIRTY_SCHEDULERS
+ ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp));
+#endif
+
+ flags = awdp->debug.wait_completed.flags;
+
+ if (aux_work & flags)
+ return aux_work;
+
+ saved_aux_work = erts_atomic32_read_acqb(&ssi->aux_work);
+
+ if (saved_aux_work & flags)
+ return aux_work & ~ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED;
+
+ awdp->debug.wait_completed.callback(awdp->debug.wait_completed.arg);
+
+ awdp->debug.wait_completed.flags = 0;
+ awdp->debug.wait_completed.callback = NULL;
+ awdp->debug.wait_completed.arg = NULL;
+
+ unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED);
+
+ return aux_work & ~ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED;
+}
+
+static erts_atomic32_t debug_wait_completed_count;
+static int debug_wait_completed_flags;
static void
-completed_dealloc(void *vproc)
+thr_debug_wait_completed(void *vproc)
{
- if (erts_atomic32_dec_read_mb(&completed_dealloc_count) == 0) {
+ if (erts_atomic32_dec_read_mb(&debug_wait_completed_count) == 0) {
erts_resume((Process *) vproc, (ErtsProcLocks) 0);
- erts_smp_proc_dec_refc((Process *) vproc);
+ erts_proc_dec_refc((Process *) vproc);
}
}
static void
-setup_completed_dealloc(void *vproc)
+setup_thr_debug_wait_completed(void *vproc)
{
ErtsSchedulerData *esdp = erts_get_scheduler_data();
- ErtsAuxWorkData *awdp = (esdp
- ? &esdp->aux_work_data
- : aux_thread_aux_work_data);
- erts_alloc_fix_alloc_shrink(awdp->sched_id, 0);
- set_aux_work_flags_wakeup_nob(awdp->ssi, ERTS_SSI_AUX_WORK_DD);
- awdp->dd.completed_callback = completed_dealloc;
- awdp->dd.completed_arg = vproc;
+ ErtsAuxWorkData *awdp;
+ erts_aint32_t wait_flags, aux_work_flags;
+#ifdef ERTS_SMP
+ awdp = esdp ? &esdp->aux_work_data : aux_thread_aux_work_data;
+#else
+ awdp = &esdp->aux_work_data;
+#endif
+
+ wait_flags = 0;
+ aux_work_flags = ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED;
+
+ if (debug_wait_completed_flags & ERTS_DEBUG_WAIT_COMPLETED_DEALLOCATIONS) {
+ erts_alloc_fix_alloc_shrink(awdp->sched_id, 0);
+ wait_flags |= (ERTS_SSI_AUX_WORK_DD
+ | ERTS_SSI_AUX_WORK_DD_THR_PRGR
+ | ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP);
+#ifdef ERTS_SMP
+ aux_work_flags |= ERTS_SSI_AUX_WORK_DD;
+#endif
+ }
+
+ if (debug_wait_completed_flags & ERTS_DEBUG_WAIT_COMPLETED_TIMER_CANCELLATIONS) {
+ wait_flags |= (ERTS_SSI_AUX_WORK_CNCLD_TMRS
+ | ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR
+ | ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP);
+#ifdef ERTS_SMP
+ if (awdp->esdp && !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp))
+ aux_work_flags |= ERTS_SSI_AUX_WORK_CNCLD_TMRS;
+#endif
+ }
+
+ set_aux_work_flags_wakeup_nob(awdp->ssi, aux_work_flags);
+
+ awdp->debug.wait_completed.flags = wait_flags;
+ awdp->debug.wait_completed.callback = thr_debug_wait_completed;
+ awdp->debug.wait_completed.arg = vproc;
}
static void
-prep_setup_completed_dealloc(void *vproc)
+prep_setup_thr_debug_wait_completed(void *vproc)
{
- erts_aint32_t count = (erts_aint32_t) (erts_no_schedulers+1);
- if (erts_atomic32_dec_read_mb(&completed_dealloc_count) == count) {
+ erts_aint32_t count = (erts_aint32_t) erts_no_schedulers;
+#ifdef ERTS_SMP
+ count += 1; /* aux thread */
+#endif
+ if (erts_atomic32_dec_read_mb(&debug_wait_completed_count) == count) {
/* scheduler threads */
erts_schedule_multi_misc_aux_work(0,
erts_no_schedulers,
- setup_completed_dealloc,
+ setup_thr_debug_wait_completed,
vproc);
+#ifdef ERTS_SMP
/* aux_thread */
erts_schedule_misc_aux_work(0,
- setup_completed_dealloc,
+ setup_thr_debug_wait_completed,
vproc);
+#endif
}
}
-#endif /* ERTS_SMP */
int
-erts_debug_wait_deallocations(Process *c_p)
+erts_debug_wait_completed(Process *c_p, int flags)
{
-#ifndef ERTS_SMP
- erts_alloc_fix_alloc_shrink(1, 0);
- return 1;
-#else
/* Only one process at a time can do this */
- erts_aint32_t count = (erts_aint32_t) (2*(erts_no_schedulers+1));
- if (0 == erts_atomic32_cmpxchg_mb(&completed_dealloc_count,
+ erts_aint32_t count = (erts_aint32_t) (2*erts_no_schedulers);
+#ifdef ERTS_SMP
+ count += 2; /* aux thread */
+#endif
+ if (0 == erts_atomic32_cmpxchg_mb(&debug_wait_completed_count,
count,
0)) {
+ debug_wait_completed_flags = flags;
erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL);
- erts_smp_proc_inc_refc(c_p);
+ erts_proc_inc_refc(c_p);
/* scheduler threads */
erts_schedule_multi_misc_aux_work(0,
erts_no_schedulers,
- prep_setup_completed_dealloc,
+ prep_setup_thr_debug_wait_completed,
(void *) c_p);
+#ifdef ERTS_SMP
/* aux_thread */
erts_schedule_misc_aux_work(0,
- prep_setup_completed_dealloc,
+ prep_setup_thr_debug_wait_completed,
(void *) c_p);
+#endif
return 1;
}
return 0;
-#endif
}
@@ -2011,7 +2292,7 @@ handle_reap_ports(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting)
erts_port_release(prt);
}
if (erts_smp_atomic32_dec_read_nob(&erts_halt_progress) == 0) {
- erl_exit_flush_async(erts_halt_code, "");
+ erts_flush_async_exit(erts_halt_code, "");
}
}
return aux_work & ~ERTS_SSI_AUX_WORK_REAP_PORTS;
@@ -2033,7 +2314,7 @@ static ERTS_INLINE erts_aint32_t
handle_setup_aux_work_timer(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting)
{
unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_SET_TMO);
- setup_aux_work_timer();
+ setup_aux_work_timer(awdp->esdp);
return aux_work & ~ERTS_SSI_AUX_WORK_SET_TMO;
}
@@ -2055,6 +2336,7 @@ handle_aux_work(ErtsAuxWorkData *awdp, erts_aint32_t orig_aux_work, int waiting)
erts_aint32_t aux_work = orig_aux_work;
erts_aint32_t ignore = 0;
+ ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp));
#ifdef ERTS_SMP
haw_thr_prgr_current_reset(awdp);
#endif
@@ -2093,6 +2375,11 @@ handle_aux_work(ErtsAuxWorkData *awdp, erts_aint32_t orig_aux_work, int waiting)
#ifdef ERTS_SMP
HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP,
handle_thr_prgr_later_op);
+ HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_CNCLD_TMRS,
+ handle_canceled_timers);
+ /* CNCLD_TMRS must be before CNCLD_TMRS_THR_PRGR */
+ HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR,
+ handle_canceled_timers_thr_prgr);
#endif
#if ERTS_USE_ASYNC_READY_Q
@@ -2127,6 +2414,14 @@ handle_aux_work(ErtsAuxWorkData *awdp, erts_aint32_t orig_aux_work, int waiting)
HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_REAP_PORTS,
handle_reap_ports);
+ /*
+ * ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED *need* to be
+ * the last flag checked!
+ */
+
+ HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED,
+ handle_debug_wait_completed);
+
ERTS_DBG_CHK_AUX_WORK_VAL(aux_work);
#ifdef ERTS_SMP
@@ -2142,8 +2437,8 @@ handle_aux_work(ErtsAuxWorkData *awdp, erts_aint32_t orig_aux_work, int waiting)
typedef struct {
union {
- ErlTimer data;
- char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErlTimer))];
+ ErtsTWheelTimer data;
+ char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsTWheelTimer))];
} timer;
int initialized;
@@ -2153,6 +2448,22 @@ typedef struct {
static ErtsAuxWorkTmo *aux_work_tmo;
+static ERTS_INLINE void
+start_aux_work_timer(ErtsSchedulerData *esdp)
+{
+ ErtsMonotonicTime tmo = erts_get_monotonic_time(esdp);
+ tmo = ERTS_MONOTONIC_TO_CLKTCKS(tmo-1);
+ tmo += ERTS_MSEC_TO_CLKTCKS(1000) + 1;
+ erts_twheel_init_timer(&aux_work_tmo->timer.data);
+ ASSERT(esdp);
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &aux_work_tmo->timer.data,
+ aux_work_timeout,
+ NULL,
+ (void *) esdp,
+ tmo);
+}
+
static void
aux_work_timeout_early_init(int no_schedulers)
{
@@ -2185,18 +2496,12 @@ void
aux_work_timeout_late_init(void)
{
aux_work_tmo->initialized = 1;
- if (erts_atomic32_read_nob(&aux_work_tmo->refc)) {
- aux_work_tmo->timer.data.active = 0;
- erts_set_timer(&aux_work_tmo->timer.data,
- aux_work_timeout,
- NULL,
- NULL,
- 1000);
- }
+ if (erts_atomic32_read_nob(&aux_work_tmo->refc))
+ start_aux_work_timer(erts_get_scheduler_data());
}
static void
-aux_work_timeout(void *unused)
+aux_work_timeout(void *vesdp)
{
erts_aint32_t refc;
int i;
@@ -2219,32 +2524,18 @@ aux_work_timeout(void *unused)
if (refc != 1
|| 1 != erts_atomic32_cmpxchg_relb(&aux_work_tmo->refc, 0, 1)) {
/* Setup next timeout... */
- aux_work_tmo->timer.data.active = 0;
- erts_set_timer(&aux_work_tmo->timer.data,
- aux_work_timeout,
- NULL,
- NULL,
- 1000);
+ start_aux_work_timer((ErtsSchedulerData *) vesdp);
}
}
static void
-setup_aux_work_timer(void)
+setup_aux_work_timer(ErtsSchedulerData *esdp)
{
-#ifndef ERTS_SMP
- if (!erts_get_scheduler_data())
+ if (!esdp || !esdp->timer_wheel)
set_aux_work_flags_wakeup_nob(ERTS_SCHED_SLEEP_INFO_IX(0),
ERTS_SSI_AUX_WORK_SET_TMO);
else
-#endif
- {
- aux_work_tmo->timer.data.active = 0;
- erts_set_timer(&aux_work_tmo->timer.data,
- aux_work_timeout,
- NULL,
- NULL,
- 1000);
- }
+ start_aux_work_timer(esdp);
}
erts_aint32_t
@@ -2275,7 +2566,7 @@ erts_set_aux_work_timeout(int ix, erts_aint32_t type, int enable)
if (refc == 1) {
erts_atomic32_inc_acqb(&aux_work_tmo->refc);
if (aux_work_tmo->initialized)
- setup_aux_work_timer();
+ setup_aux_work_timer(erts_get_scheduler_data());
}
}
return old;
@@ -2318,7 +2609,6 @@ erts_active_schedulers(void)
ERTS_ATOMIC_FOREACH_RUNQ(rq, as -= abs(rq->waiting));
- ASSERT(as >= 0);
return as;
}
@@ -2640,6 +2930,13 @@ thr_prgr_fin_wait(void *vssi)
static void init_aux_work_data(ErtsAuxWorkData *awdp, ErtsSchedulerData *esdp, char *dawwp);
+void
+erts_interupt_aux_thread_timed(ErtsMonotonicTime timeout_time)
+{
+ /* TODO only poke when needed (based on timeout_time) */
+ erts_sched_poke(ERTS_SCHED_SLEEP_INFO_IX(-1));
+}
+
static void *
aux_thread(void *unused)
{
@@ -2770,47 +3067,89 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
sched_wall_time_change(esdp, thr_prgr_active);
while (1) {
+ ErtsMonotonicTime current_time;
aux_work = erts_atomic32_read_acqb(&ssi->aux_work);
- if (aux_work) {
- if (!ERTS_SCHEDULER_IS_DIRTY(esdp) && !thr_prgr_active) {
+ if (aux_work && !ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (!thr_prgr_active) {
erts_thr_progress_active(esdp, thr_prgr_active = 1);
sched_wall_time_change(esdp, 1);
}
aux_work = handle_aux_work(&esdp->aux_work_data, aux_work, 1);
- if (aux_work && !ERTS_SCHEDULER_IS_DIRTY(esdp)
- && erts_thr_progress_update(esdp))
+ if (aux_work && erts_thr_progress_update(esdp))
erts_thr_progress_leader_update(esdp);
}
- if (aux_work)
- flgs = erts_smp_atomic32_read_acqb(&ssi->flags);
+ if (aux_work) {
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ flgs = erts_smp_atomic32_read_acqb(&ssi->flags);
+ current_time = erts_get_monotonic_time(esdp);
+ if (current_time >= erts_next_timeout_time(esdp->next_tmo_ref)) {
+ if (!thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 1);
+ sched_wall_time_change(esdp, 1);
+ }
+ erts_bump_timers(esdp->timer_wheel, current_time);
+ }
+ }
+ }
else {
+ ErtsMonotonicTime timeout_time;
+ int do_timeout = 0;
if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
- if (thr_prgr_active) {
- erts_thr_progress_active(esdp, thr_prgr_active = 0);
- sched_wall_time_change(esdp, 0);
+ timeout_time = erts_check_next_timeout_time(esdp);
+ current_time = erts_get_monotonic_time(esdp);
+ do_timeout = (current_time >= timeout_time);
+ } else
+ timeout_time = ERTS_MONOTONIC_TIME_MAX;
+ if (do_timeout) {
+ if (!thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 1);
+ sched_wall_time_change(esdp, 1);
}
- erts_thr_progress_prepare_wait(esdp);
}
+ else {
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 0);
+ sched_wall_time_change(esdp, 0);
+ }
+ erts_thr_progress_prepare_wait(esdp);
+ }
- ERTS_SCHED_FAIR_YIELD();
+ ERTS_SCHED_FAIR_YIELD();
- flgs = sched_spin_wait(ssi, spincount);
- if (flgs & ERTS_SSI_FLG_SLEEPING) {
- ASSERT(flgs & ERTS_SSI_FLG_WAITING);
- flgs = sched_set_sleeptype(ssi, ERTS_SSI_FLG_TSE_SLEEPING);
+ flgs = sched_spin_wait(ssi, spincount);
if (flgs & ERTS_SSI_FLG_SLEEPING) {
- int res;
- ASSERT(flgs & ERTS_SSI_FLG_TSE_SLEEPING);
ASSERT(flgs & ERTS_SSI_FLG_WAITING);
- do {
- res = erts_tse_wait(ssi->event);
- } while (res == EINTR);
+ flgs = sched_set_sleeptype(ssi, ERTS_SSI_FLG_TSE_SLEEPING);
+ if (flgs & ERTS_SSI_FLG_SLEEPING) {
+ int res;
+ ASSERT(flgs & ERTS_SSI_FLG_TSE_SLEEPING);
+ ASSERT(flgs & ERTS_SSI_FLG_WAITING);
+ current_time = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0 :
+ erts_get_monotonic_time(esdp);
+ do {
+ Sint64 timeout;
+ if (current_time >= timeout_time)
+ break;
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ timeout = ERTS_MONOTONIC_TO_NSEC(timeout_time
+ - current_time
+ - 1) + 1;
+ } else
+ timeout = -1;
+ res = erts_tse_twait(ssi->event, timeout);
+ current_time = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0 :
+ erts_get_monotonic_time(esdp);
+ } while (res == EINTR);
+ }
}
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp))
+ erts_thr_progress_finalize_wait(esdp);
}
- if (!ERTS_SCHEDULER_IS_DIRTY(esdp))
- erts_thr_progress_finalize_wait(esdp);
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp) && current_time >= timeout_time)
+ erts_bump_timers(esdp->timer_wheel, current_time);
}
if (!(flgs & ERTS_SSI_FLG_WAITING)) {
@@ -2843,7 +3182,6 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
else
#endif
{
- erts_aint_t dt;
erts_smp_atomic32_set_relb(&function_calls, 0);
*fcalls = 0;
@@ -2868,6 +3206,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
goto sys_aux_work;
while (spincount-- > 0) {
+ ErtsMonotonicTime current_time;
sys_poll_aux_work:
@@ -2877,8 +3216,11 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
ASSERT(!erts_port_task_have_outstanding_io_tasks());
erl_sys_schedule(1); /* Might give us something to do */
- dt = erts_do_time_read_and_reset();
- if (dt) erts_bump_timer(dt);
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ current_time = erts_get_monotonic_time(esdp);
+ if (current_time >= erts_next_timeout_time(esdp->next_tmo_ref))
+ erts_bump_timers(esdp->timer_wheel, current_time);
+ }
sys_aux_work:
#ifndef ERTS_SMP
@@ -2886,7 +3228,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
#endif
aux_work = erts_atomic32_read_acqb(&ssi->aux_work);
- if (aux_work) {
+ if (aux_work && !ERTS_SCHEDULER_IS_DIRTY(esdp)) {
if (!working)
sched_wall_time_change(esdp, working = 1);
#ifdef ERTS_SMP
@@ -2901,7 +3243,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
}
#ifndef ERTS_SMP
- if (rq->len != 0 || rq->misc.start)
+ if (erts_smp_atomic32_read_dirty(&rq->len) != 0 || rq->misc.start)
goto sys_woken;
#else
flgs = erts_smp_atomic32_read_acqb(&ssi->flags);
@@ -2993,11 +3335,14 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
erl_sys_schedule(0);
- dt = erts_do_time_read_and_reset();
- if (dt) erts_bump_timer(dt);
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ ErtsMonotonicTime current_time = erts_get_monotonic_time(esdp);
+ if (current_time >= erts_next_timeout_time(esdp->next_tmo_ref))
+ erts_bump_timers(esdp->timer_wheel, current_time);
+ }
#ifndef ERTS_SMP
- if (rq->len == 0 && !rq->misc.start)
+ if (erts_smp_atomic32_read_dirty(&rq->len) == 0 && !rq->misc.start)
goto sys_aux_work;
sys_woken:
#else
@@ -3466,7 +3811,7 @@ immigrate(ErtsRunQueue *c_rq, ErtsMigrationPath *mp)
prio = ERTS_PORT_PRIO_LEVEL;
break;
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s(): Invalid immigrate queue mask",
__FILE__, __LINE__, __func__);
prio = 0;
@@ -3490,7 +3835,7 @@ immigrate(ErtsRunQueue *c_rq, ErtsMigrationPath *mp)
rq = erts_port_runq(prt);
if (rq) {
if (rq != c_rq)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s(): Internal error",
__FILE__, __LINE__, __func__);
erts_enqueue_port(c_rq, prt);
@@ -3681,7 +4026,7 @@ evacuate_run_queue(ErtsRunQueue *rq,
prt_rq = erts_port_runq(prt);
if (prt_rq) {
if (prt_rq != to_rq)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s() internal error\n",
__FILE__, __LINE__, __func__);
erts_enqueue_port(to_rq, prt);
@@ -3882,7 +4227,7 @@ no_procs:
return 0;
else {
if (prt_rq != rq)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s() internal error\n",
__FILE__, __LINE__, __func__);
*rq_lockedp = 1;
@@ -4714,7 +5059,7 @@ erts_fprintf(stderr, "--------------------------------\n");
rq->out_of_work_count = 0;
(void) ERTS_RUNQ_FLGS_READ_BSET(rq, ERTS_RUNQ_FLGS_MIGRATION_INFO, flags);
- rq->max_len = rq->len;
+ rq->max_len = erts_smp_atomic32_read_dirty(&rq->len);
for (pix = 0; pix < ERTS_NO_PRIO_LEVELS; pix++) {
ErtsRunQueueInfo *rqi;
rqi = (pix == ERTS_PORT_PRIO_LEVEL
@@ -4872,7 +5217,7 @@ wakeup_other_check(ErtsRunQueue *rq, Uint32 flags)
{
int wo_reds = rq->wakeup_other_reds;
if (wo_reds) {
- int left_len = rq->len - 1;
+ int left_len = erts_smp_atomic32_read_dirty(&rq->len) - 1;
if (left_len < 1) {
int wo_reduce = wo_reds << wakeup_other.dec_shift;
wo_reduce &= wakeup_other.dec_mask;
@@ -4885,9 +5230,11 @@ wakeup_other_check(ErtsRunQueue *rq, Uint32 flags)
+ ERTS_WAKEUP_OTHER_FIXED_INC);
if (rq->wakeup_other > wakeup_other.limit) {
#ifdef ERTS_DIRTY_SCHEDULERS
- if (ERTS_RUNQ_IX_IS_DIRTY(rq->ix) && rq->waiting)
- wake_dirty_schedulers(rq, 1);
- else
+ if (ERTS_RUNQ_IX_IS_DIRTY(rq->ix)) {
+ if (rq->waiting) {
+ wake_dirty_schedulers(rq, 1);
+ }
+ } else
#endif
{
int empty_rqs =
@@ -4943,7 +5290,7 @@ wakeup_other_check_legacy(ErtsRunQueue *rq, Uint32 flags)
{
int wo_reds = rq->wakeup_other_reds;
if (wo_reds) {
- erts_aint32_t len = rq->len;
+ erts_aint32_t len = erts_smp_atomic32_read_dirty(&rq->len);
if (len < 2) {
rq->wakeup_other -= ERTS_WAKEUP_OTHER_DEC_LEGACY*wo_reds;
if (rq->wakeup_other < 0)
@@ -5039,7 +5386,7 @@ runq_supervisor(void *unused)
ErtsRunQueue *rq = ERTS_RUNQ_IX(ix);
if (ERTS_RUNQ_FLGS_GET(rq) & ERTS_RUNQ_FLG_NONEMPTY) {
erts_smp_runq_lock(rq);
- if (rq->len != 0)
+ if (erts_smp_atomic32_read_dirty(&rq->len) != 0)
wake_scheduler_on_empty_runq(rq); /* forced wakeup... */
erts_smp_runq_unlock(rq);
}
@@ -5198,8 +5545,7 @@ init_aux_work_data(ErtsAuxWorkData *awdp, ErtsSchedulerData *esdp, char *dawwp)
awdp->latest_wakeup = ERTS_THR_PRGR_VAL_FIRST;
awdp->misc.thr_prgr = ERTS_THR_PRGR_VAL_WAITING;
awdp->dd.thr_prgr = ERTS_THR_PRGR_VAL_WAITING;
- awdp->dd.completed_callback = NULL;
- awdp->dd.completed_arg = NULL;
+ awdp->cncld_tmrs.thr_prgr = ERTS_THR_PRGR_VAL_WAITING;
awdp->later_op.thr_prgr = ERTS_THR_PRGR_VAL_FIRST;
awdp->later_op.size = 0;
awdp->later_op.first = NULL;
@@ -5229,6 +5575,9 @@ init_aux_work_data(ErtsAuxWorkData *awdp, ErtsSchedulerData *esdp, char *dawwp)
awdp->delayed_wakeup.sched2jix[i] = -1;
}
#endif
+ awdp->debug.wait_completed.flags = 0;
+ awdp->debug.wait_completed.callback = NULL;
+ awdp->debug.wait_completed.arg = NULL;
}
static void
@@ -5237,6 +5586,7 @@ init_scheduler_data(ErtsSchedulerData* esdp, int num,
ErtsRunQueue* runq,
char** daww_ptr, size_t daww_sz)
{
+ esdp->timer_wheel = NULL;
#ifdef ERTS_SMP
erts_bits_init_state(&esdp->erl_bits_state);
esdp->match_pseudo_process = NULL;
@@ -5264,6 +5614,7 @@ init_scheduler_data(ErtsSchedulerData* esdp, int num,
#else
esdp->no = (Uint) num;
#endif
+
esdp->ssi = ssi;
esdp->current_process = NULL;
esdp->current_port = NULL;
@@ -5276,6 +5627,15 @@ init_scheduler_data(ErtsSchedulerData* esdp, int num,
esdp->run_queue = runq;
esdp->run_queue->scheduler = esdp;
+ esdp->last_monotonic_time = 0;
+ esdp->check_time_reds = 0;
+
+ esdp->thr_id = (Uint32) num;
+ erts_sched_bif_unique_init(esdp);
+
+ esdp->io.out = (Uint64) 0;
+ esdp->io.in = (Uint64) 0;
+
if (daww_ptr) {
init_aux_work_data(&esdp->aux_work_data, esdp, *daww_ptr);
#ifdef ERTS_SMP
@@ -5376,7 +5736,7 @@ erts_init_scheduling(int no_schedulers, int no_schedulers_online
}
rq->out_of_work_count = 0;
rq->max_len = 0;
- rq->len = 0;
+ erts_smp_atomic32_set_nob(&rq->len, 0);
rq->wakeup_other = 0;
rq->wakeup_other_reds = 0;
rq->halt_in_progress = 0;
@@ -5528,13 +5888,14 @@ erts_init_scheduling(int no_schedulers, int no_schedulers_online
init_misc_aux_work();
#if !HALFWORD_HEAP
init_swtreq_alloc();
+ init_screq_alloc();
#endif
+ erts_atomic32_init_nob(&debug_wait_completed_count, 0); /* debug only */
+ debug_wait_completed_flags = 0;
#ifdef ERTS_SMP
- erts_atomic32_init_nob(&completed_dealloc_count, 0); /* debug only */
-
aux_thread_aux_work_data =
erts_alloc_permanent_cache_aligned(ERTS_ALC_T_SCHDLR_DATA,
sizeof(ErtsAuxWorkData));
@@ -5874,6 +6235,7 @@ schedule_out_process(ErtsRunQueue *c_rq, erts_aint32_t state, Process *p, Proces
free_proxy_proc(proxy);
erts_smp_runq_lock(c_rq);
+
return 0;
#ifdef ERTS_DIRTY_SCHEDULERS
@@ -6197,9 +6559,6 @@ suspend_process(Process *c_p, Process *p)
if (suspended) {
- ASSERT(!(ERTS_PSFLG_RUNNING & state)
- || p == erts_get_current_process());
-
if (suspended > 0 && erts_system_profile_flags.runnable_procs) {
/* 'state' is before our change... */
@@ -6531,18 +6890,19 @@ suspend_scheduler(ErtsSchedulerData *esdp)
& ERTS_RUNQ_FLGS_QMASK);
aux_work = erts_atomic32_read_acqb(&ssi->aux_work);
if (aux_work|qmask) {
- if (!ERTS_SCHEDULER_IS_DIRTY(esdp) && !thr_prgr_active) {
- erts_thr_progress_active(esdp, thr_prgr_active = 1);
- sched_wall_time_change(esdp, 1);
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (!thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 1);
+ sched_wall_time_change(esdp, 1);
+ }
+ if (aux_work)
+ aux_work = handle_aux_work(&esdp->aux_work_data,
+ aux_work,
+ 1);
+
+ if (aux_work && erts_thr_progress_update(esdp))
+ erts_thr_progress_leader_update(esdp);
}
- if (aux_work)
- aux_work = handle_aux_work(&esdp->aux_work_data,
- aux_work,
- 1);
-
- if (!ERTS_SCHEDULER_IS_DIRTY(esdp) &&
- (aux_work && erts_thr_progress_update(esdp)))
- erts_thr_progress_leader_update(esdp);
if (qmask) {
#ifdef ERTS_DIRTY_SCHEDULERS
if (ERTS_SCHEDULER_IS_DIRTY(esdp)) {
@@ -6586,7 +6946,7 @@ suspend_scheduler(ErtsSchedulerData *esdp)
int res;
do {
- res = erts_tse_wait(ssi->event);
+ res = erts_tse_twait(ssi->event, -1);
} while (res == EINTR);
}
}
@@ -6642,6 +7002,8 @@ suspend_scheduler(ErtsSchedulerData *esdp)
}
}
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp))
+ (void) erts_get_monotonic_time(esdp);
erts_smp_runq_lock(esdp->run_queue);
non_empty_runq(esdp->run_queue);
@@ -6749,6 +7111,7 @@ suspend_scheduler(ErtsSchedulerData *esdp)
erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
while (1) {
+ ErtsMonotonicTime current_time;
erts_aint32_t qmask;
erts_aint32_t flgs;
@@ -6756,16 +7119,18 @@ suspend_scheduler(ErtsSchedulerData *esdp)
& ERTS_RUNQ_FLGS_QMASK);
aux_work = erts_atomic32_read_acqb(&ssi->aux_work);
if (aux_work|qmask) {
- if (!thr_prgr_active) {
- erts_thr_progress_active(esdp, thr_prgr_active = 1);
- sched_wall_time_change(esdp, 1);
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (!thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 1);
+ sched_wall_time_change(esdp, 1);
+ }
+ if (aux_work)
+ aux_work = handle_aux_work(&esdp->aux_work_data,
+ aux_work,
+ 1);
+ if (aux_work && erts_thr_progress_update(esdp))
+ erts_thr_progress_leader_update(esdp);
}
- if (aux_work)
- aux_work = handle_aux_work(&esdp->aux_work_data,
- aux_work,
- 1);
- if (aux_work && erts_thr_progress_update(esdp))
- erts_thr_progress_leader_update(esdp);
if (qmask) {
erts_smp_runq_lock(esdp->run_queue);
evacuate_run_queue(esdp->run_queue, &sbp);
@@ -6773,30 +7138,77 @@ suspend_scheduler(ErtsSchedulerData *esdp)
}
}
- if (!aux_work) {
- if (thr_prgr_active) {
- erts_thr_progress_active(esdp, thr_prgr_active = 0);
- sched_wall_time_change(esdp, 0);
+ if (aux_work) {
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ current_time = erts_get_monotonic_time(esdp);
+ if (current_time >= erts_next_timeout_time(esdp->next_tmo_ref)) {
+ if (!thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 1);
+ sched_wall_time_change(esdp, 1);
+ }
+ erts_bump_timers(esdp->timer_wheel, current_time);
+ }
}
- erts_thr_progress_prepare_wait(esdp);
- flgs = sched_spin_suspended(ssi,
- ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT);
- if (flgs == (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_WAITING
- | ERTS_SSI_FLG_SUSPENDED)) {
- flgs = sched_set_suspended_sleeptype(ssi);
+ }
+ else {
+ ErtsMonotonicTime timeout_time;
+ int do_timeout = 0;
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ timeout_time = erts_check_next_timeout_time(esdp);
+ current_time = erts_get_monotonic_time(esdp);
+ do_timeout = (current_time >= timeout_time);
+ } else
+ timeout_time = ERTS_MONOTONIC_TIME_MAX;
+ if (do_timeout) {
+ if (!thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 1);
+ sched_wall_time_change(esdp, 1);
+ }
+ }
+ else {
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (thr_prgr_active) {
+ erts_thr_progress_active(esdp, thr_prgr_active = 0);
+ sched_wall_time_change(esdp, 0);
+ }
+ erts_thr_progress_prepare_wait(esdp);
+ }
+ flgs = sched_spin_suspended(ssi,
+ ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT);
if (flgs == (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_TSE_SLEEPING
| ERTS_SSI_FLG_WAITING
| ERTS_SSI_FLG_SUSPENDED)) {
- int res;
-
- do {
- res = erts_tse_wait(ssi->event);
- } while (res == EINTR);
+ flgs = sched_set_suspended_sleeptype(ssi);
+ if (flgs == (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_TSE_SLEEPING
+ | ERTS_SSI_FLG_WAITING
+ | ERTS_SSI_FLG_SUSPENDED)) {
+ int res;
+
+ current_time = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0 :
+ erts_get_monotonic_time(esdp);
+ do {
+ Sint64 timeout;
+ if (current_time >= timeout_time)
+ break;
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ timeout = ERTS_MONOTONIC_TO_NSEC(timeout_time
+ - current_time
+ - 1) + 1;
+ } else
+ timeout = -1;
+ res = erts_tse_twait(ssi->event, timeout);
+ current_time = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0 :
+ erts_get_monotonic_time(esdp);
+ } while (res == EINTR);
+ }
}
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp))
+ erts_thr_progress_finalize_wait(esdp);
}
- erts_thr_progress_finalize_wait(esdp);
+
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp) && current_time >= timeout_time)
+ erts_bump_timers(esdp->timer_wheel, current_time);
}
flgs = sched_prep_spin_suspended(ssi, (ERTS_SSI_FLG_WAITING
@@ -7616,7 +8028,18 @@ sched_thread_func(void *vesdp)
ErtsSchedulerData *esdp = vesdp;
Uint no = esdp->no;
#ifdef ERTS_SMP
- ERTS_SCHED_SLEEP_INFO_IX(no - 1)->event = erts_tse_fetch();
+ erts_tse_t *tse;
+#endif
+
+ erts_sched_init_time_sup(esdp);
+
+ (void) ERTS_RUNQ_FLGS_SET_NOB(esdp->run_queue,
+ ERTS_RUNQ_FLG_EXEC);
+
+#ifdef ERTS_SMP
+ tse = erts_tse_fetch();
+ erts_tse_prepare_timed(tse);
+ ERTS_SCHED_SLEEP_INFO_IX(no - 1)->event = tse;
callbacks.arg = (void *) esdp->ssi;
callbacks.wakeup = thr_prgr_wakeup;
callbacks.prepare_wait = thr_prgr_prep_wait;
@@ -7694,7 +8117,7 @@ sched_thread_func(void *vesdp)
process_main();
/* No schedulers should *ever* terminate */
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Scheduler thread number %beu terminated\n",
no);
return NULL;
@@ -7717,6 +8140,8 @@ sched_dirty_cpu_thread_func(void *vesdp)
callbacks.wait = NULL;
callbacks.finalize_wait = NULL;
+ esdp->thr_id += erts_no_schedulers;
+
erts_thr_progress_register_unmanaged_thread(&callbacks);
#ifdef ERTS_ENABLE_LOCK_CHECK
{
@@ -7757,7 +8182,7 @@ sched_dirty_cpu_thread_func(void *vesdp)
process_main();
/* No schedulers should *ever* terminate */
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Dirty CPU scheduler thread number %beu terminated\n",
no);
return NULL;
@@ -7778,6 +8203,8 @@ sched_dirty_io_thread_func(void *vesdp)
callbacks.wait = NULL;
callbacks.finalize_wait = NULL;
+ esdp->thr_id += erts_no_schedulers + erts_no_dirty_cpu_schedulers;
+
erts_thr_progress_register_unmanaged_thread(&callbacks);
#ifdef ERTS_ENABLE_LOCK_CHECK
{
@@ -7818,7 +8245,7 @@ sched_dirty_io_thread_func(void *vesdp)
process_main();
/* No schedulers should *ever* terminate */
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Dirty I/O scheduler thread number %beu terminated\n",
no);
return NULL;
@@ -7835,31 +8262,25 @@ erts_start_schedulers(void)
Uint actual;
Uint wanted = erts_no_schedulers;
Uint wanted_no_schedulers = erts_no_schedulers;
+ char name[16];
ethr_thr_opts opts = ETHR_THR_OPTS_DEFAULT_INITER;
opts.detached = 1;
-#ifdef ETHR_HAVE_THREAD_NAMES
- opts.name = malloc(80);
- if (!opts.name) {
- ERTS_INTERNAL_ERROR("malloc failed to allocate memory!");
- }
-#endif
+ opts.name = name;
#ifdef ERTS_SMP
if (erts_runq_supervision_interval) {
opts.suggested_stack_size = 16;
-#ifdef ETHR_HAVE_THREAD_NAMES
- sprintf(opts.name, "runq_supervisor");
-#endif
+ erts_snprintf(opts.name, 16, "runq_supervisor");
erts_atomic_init_nob(&runq_supervisor_sleeping, 0);
if (0 != ethr_event_init(&runq_supervision_event))
- erl_exit(1, "Failed to create run-queue supervision event\n");
+ erts_exit(ERTS_ERROR_EXIT, "Failed to create run-queue supervision event\n");
if (0 != ethr_thr_create(&runq_supervisor_tid,
runq_supervisor,
NULL,
&opts))
- erl_exit(1, "Failed to create run-queue supervision thread\n");
+ erts_exit(ERTS_ERROR_EXIT, "Failed to create run-queue supervision thread\n");
}
#endif
@@ -7878,9 +8299,7 @@ erts_start_schedulers(void)
ASSERT(actual == esdp->no - 1);
-#ifdef ETHR_HAVE_THREAD_NAMES
- sprintf(opts.name, "scheduler_%d", actual + 1);
-#endif
+ erts_snprintf(opts.name, 16, "%lu_scheduler", actual + 1);
#ifdef __OSE__
/* This should be done in the bind strategy */
@@ -7902,21 +8321,17 @@ erts_start_schedulers(void)
int ix;
for (ix = 0; ix < erts_no_dirty_cpu_schedulers; ix++) {
ErtsSchedulerData *esdp = ERTS_DIRTY_CPU_SCHEDULER_IX(ix);
-#ifdef ETHR_HAVE_THREAD_NAMES
- sprintf(opts.name,"dirty_cpu_scheduler_%d", ix + 1);
-#endif
+ erts_snprintf(opts.name, 16, "%d_dirty_cpu_scheduler", ix + 1);
res = ethr_thr_create(&esdp->tid,sched_dirty_cpu_thread_func,(void*)esdp,&opts);
if (res != 0)
- erl_exit(1, "Failed to create dirty cpu scheduler thread %d\n", ix);
+ erts_exit(ERTS_ERROR_EXIT, "Failed to create dirty cpu scheduler thread %d\n", ix);
}
for (ix = 0; ix < erts_no_dirty_io_schedulers; ix++) {
ErtsSchedulerData *esdp = ERTS_DIRTY_IO_SCHEDULER_IX(ix);
-#ifdef ETHR_HAVE_THREAD_NAMES
- sprintf(opts.name,"dirty_io_scheduler_%d", ix + 1);
-#endif
+ erts_snprintf(opts.name, 16, "%d_dirty_io_scheduler", ix + 1);
res = ethr_thr_create(&esdp->tid,sched_dirty_io_thread_func,(void*)esdp,&opts);
if (res != 0)
- erl_exit(1, "Failed to create dirty io scheduler thread %d\n", ix);
+ erts_exit(ERTS_ERROR_EXIT, "Failed to create dirty io scheduler thread %d\n", ix);
}
}
#endif
@@ -7924,9 +8339,7 @@ erts_start_schedulers(void)
ERTS_THR_MEMORY_BARRIER;
-#ifdef ETHR_HAVE_THREAD_NAMES
- sprintf(opts.name, "aux");
-#endif
+ erts_snprintf(opts.name, 16, "aux");
#ifdef __OSE__
opts.coreNo = 0;
@@ -7934,10 +8347,10 @@ erts_start_schedulers(void)
res = ethr_thr_create(&aux_tid, aux_thread, NULL, &opts);
if (res != 0)
- erl_exit(1, "Failed to create aux thread\n");
+ erts_exit(ERTS_ERROR_EXIT, "Failed to create aux thread\n");
if (actual < 1)
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"Failed to create any scheduler-threads: %s (%d)\n",
erl_errno_id(res),
res);
@@ -7952,9 +8365,6 @@ erts_start_schedulers(void)
erts_send_error_to_logger_nogl(dsbufp);
}
-#ifdef ETHR_HAVE_THREAD_NAMES
- free(opts.name);
-#endif
}
#endif /* ERTS_SMP */
@@ -8095,9 +8505,8 @@ pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
resume_process(rp, rp_locks);
}
else {
-
rp = erts_pid2proc(c_p, c_p_locks|ERTS_PROC_LOCK_STATUS,
- pid, pid_locks|ERTS_PROC_LOCK_STATUS);
+ pid, ERTS_PROC_LOCK_STATUS);
if (!rp) {
c_p->flags &= ~F_P2PNR_RESCHED;
@@ -8106,40 +8515,84 @@ pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
ASSERT(!(c_p->flags & F_P2PNR_RESCHED));
- if (suspend) {
- if (suspend_process(c_p, rp))
- goto done;
- }
- else {
- if (!((ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS)
- & erts_smp_atomic32_read_acqb(&rp->state)))
- goto done;
+ /*
+ * Suspend the other process in order to prevent
+ * it from being selected for normal execution.
+ * This will however not prevent it from being
+ * selected for execution of a system task. If
+ * it is selected for execution of a system task
+ * we might be blocked for quite a while if the
+ * try-lock below fails. That is, there is room
+ * for improvement here...
+ */
- }
+ if (!suspend_process(c_p, rp)) {
+ /* Other process running */
- /* Other process running */
+ ASSERT(ERTS_PSFLG_RUNNING
+ & erts_smp_atomic32_read_nob(&rp->state));
- /*
- * If we got pending suspenders and suspend ourselves waiting
- * to suspend another process we might deadlock.
- * In this case we have to yield, be suspended by
- * someone else and then do it all over again.
- */
- if (!c_p->pending_suspenders) {
- /* Mark rp pending for suspend by c_p */
- add_pend_suspend(rp, c_p->common.id, handle_pend_sync_suspend);
- ASSERT(is_nil(c_p->suspendee));
+ running:
- /* Suspend c_p; when rp is suspended c_p will be resumed. */
- suspend_process(c_p, c_p);
- c_p->flags |= F_P2PNR_RESCHED;
+ /*
+ * If we got pending suspenders and suspend ourselves waiting
+ * to suspend another process we might deadlock.
+ * In this case we have to yield, be suspended by
+ * someone else and then do it all over again.
+ */
+ if (!c_p->pending_suspenders) {
+ /* Mark rp pending for suspend by c_p */
+ add_pend_suspend(rp, c_p->common.id, handle_pend_sync_suspend);
+ ASSERT(is_nil(c_p->suspendee));
+
+ /* Suspend c_p; when rp is suspended c_p will be resumed. */
+ suspend_process(c_p, c_p);
+ c_p->flags |= F_P2PNR_RESCHED;
+ }
+ /* Yield (caller is assumed to yield immediately in bif). */
+ erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_STATUS);
+ rp = ERTS_PROC_LOCK_BUSY;
+ }
+ else {
+ ErtsProcLocks need_locks = pid_locks & ~ERTS_PROC_LOCK_STATUS;
+ if (need_locks && erts_smp_proc_trylock(rp, need_locks) == EBUSY) {
+ if (ERTS_PSFLG_RUNNING_SYS
+ & erts_smp_atomic32_read_nob(&rp->state)) {
+ /* Executing system task... */
+ resume_process(rp, ERTS_PROC_LOCK_STATUS);
+ goto running;
+ }
+ erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_STATUS);
+ /*
+ * If we are unlucky, the process just got selected for
+ * execution of a system task. In this case we may be
+ * blocked here for quite a while... Execution of system
+ * tasks are fortunately quite rare events. We try to
+ * avoid this by checking if it is in a state executing
+ * system tasks (above), but it will not prevent all
+ * scenarios for a long block here...
+ */
+ rp = erts_pid2proc(c_p, c_p_locks|ERTS_PROC_LOCK_STATUS,
+ pid, pid_locks|ERTS_PROC_LOCK_STATUS);
+ if (!rp)
+ goto done;
+ }
+
+ /*
+ * The previous suspend has prevented the process
+ * from being selected for normal execution regardless
+ * of locks held or not held on it...
+ */
+ ASSERT(!(ERTS_PSFLG_RUNNING
+ & erts_smp_atomic32_read_nob(&rp->state)));
+
+ if (!suspend)
+ resume_process(rp, pid_locks|ERTS_PROC_LOCK_STATUS);
}
- /* Yield (caller is assumed to yield immediately in bif). */
- erts_smp_proc_unlock(rp, pid_locks|ERTS_PROC_LOCK_STATUS);
- rp = ERTS_PROC_LOCK_BUSY;
}
done:
+
if (rp && rp != ERTS_PROC_LOCK_BUSY && !(pid_locks & ERTS_PROC_LOCK_STATUS))
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_STATUS);
if (unlock_c_p_status)
@@ -8634,24 +9087,39 @@ resume_process_1(BIF_ALIST_1)
}
Uint
-erts_run_queues_len(Uint *qlen)
+erts_run_queues_len(Uint *qlen, int atomic_queues_read, int incl_active_sched)
{
int i = 0;
Uint len = 0;
- ERTS_ATOMIC_FOREACH_RUNQ(rq,
- {
- Sint pqlen = 0;
- int pix;
- for (pix = 0; pix < ERTS_NO_PROC_PRIO_LEVELS; pix++)
- pqlen += RUNQ_READ_LEN(&rq->procs.prio_info[pix].len);
+ if (atomic_queues_read)
+ ERTS_ATOMIC_FOREACH_RUNQ(rq,
+ {
+ Sint rq_len = (Sint) erts_smp_atomic32_read_dirty(&rq->len);
+ ASSERT(rq_len >= 0);
+ if (incl_active_sched
+ && (ERTS_RUNQ_FLGS_GET_NOB(rq) & ERTS_RUNQ_FLG_EXEC)) {
+ rq_len++;
+ }
+ if (qlen)
+ qlen[i++] = rq_len;
+ len += (Uint) rq_len;
+ }
+ );
+ else {
+ for (i = 0; i < erts_no_run_queues; i++) {
+ ErtsRunQueue *rq = ERTS_RUNQ_IX(i);
+ Sint rq_len = (Sint) erts_smp_atomic32_read_nob(&rq->len);
+ ASSERT(rq_len >= 0);
+ if (incl_active_sched
+ && (ERTS_RUNQ_FLGS_GET_NOB(rq) & ERTS_RUNQ_FLG_EXEC)) {
+ rq_len++;
+ }
+ if (qlen)
+ qlen[i] = rq_len;
+ len += (Uint) rq_len;
+ }
- if (pqlen < 0)
- pqlen = 0;
- if (qlen)
- qlen[i++] = pqlen;
- len += pqlen;
}
- );
return len;
}
@@ -8864,6 +9332,10 @@ erts_set_process_priority(Process *p, Eterm value)
a = erts_smp_atomic32_cmpxchg_mb(&p->state, n, e);
} while (a != e);
+
+ if (slocked)
+ erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
+
}
switch (oprio) {
@@ -8897,7 +9369,6 @@ Process *schedule(Process *p, int calls)
{
Process *proxy_p = NULL;
ErtsRunQueue *rq;
- erts_aint_t dt;
ErtsSchedulerData *esdp;
int context_reds;
int fcalls;
@@ -8997,7 +9468,7 @@ Process *schedule(Process *p, int calls)
schedule_out_process(rq, state, p, proxy_p); /* Returns with rq locked! */
proxy_p = NULL;
- ERTS_PROC_REDUCTIONS_EXECUTED(rq,
+ ERTS_PROC_REDUCTIONS_EXECUTED(esdp, rq,
(int) ERTS_PSFLGS_GET_USR_PRIO(state),
reds,
actual_reds);
@@ -9014,12 +9485,9 @@ Process *schedule(Process *p, int calls)
ASSERT(esdp->free_process == p);
esdp->free_process = NULL;
#else
- state = erts_smp_atomic32_read_nob(&p->state);
- if (!(state & ERTS_PSFLG_IN_RUNQ))
- erts_free_proc(p);
+ erts_proc_dec_refc(p);
#endif
}
-
#ifdef ERTS_SMP
ASSERT(!esdp->free_process);
#endif
@@ -9027,11 +9495,15 @@ Process *schedule(Process *p, int calls)
ERTS_SMP_CHK_NO_PROC_LOCKS;
- dt = erts_do_time_read_and_reset();
- if (dt) {
- erts_smp_runq_unlock(rq);
- erts_bump_timer(dt);
- erts_smp_runq_lock(rq);
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (esdp->check_time_reds >= ERTS_CHECK_TIME_REDS)
+ (void) erts_get_monotonic_time(esdp);
+
+ if (esdp->last_monotonic_time >= erts_next_timeout_time(esdp->next_tmo_ref)) {
+ erts_smp_runq_unlock(rq);
+ erts_bump_timers(esdp->timer_wheel, esdp->last_monotonic_time);
+ erts_smp_runq_lock(rq);
+ }
}
BM_STOP_TIMER(system);
@@ -9074,8 +9546,10 @@ Process *schedule(Process *p, int calls)
if (flags & (ERTS_RUNQ_FLG_CHK_CPU_BIND|ERTS_RUNQ_FLG_SUSPENDED)) {
if (flags & ERTS_RUNQ_FLG_SUSPENDED) {
+ (void) ERTS_RUNQ_FLGS_UNSET_NOB(rq, ERTS_RUNQ_FLG_EXEC);
suspend_scheduler(esdp);
- flags = ERTS_RUNQ_FLGS_GET_NOB(rq);
+ flags = ERTS_RUNQ_FLGS_SET_NOB(rq, ERTS_RUNQ_FLG_EXEC);
+ flags |= ERTS_RUNQ_FLG_EXEC;
}
if (flags & ERTS_RUNQ_FLG_CHK_CPU_BIND) {
flags = ERTS_RUNQ_FLGS_UNSET(rq, ERTS_RUNQ_FLG_CHK_CPU_BIND);
@@ -9090,10 +9564,9 @@ Process *schedule(Process *p, int calls)
suspend_scheduler(esdp);
#endif
- {
+ if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
erts_aint32_t aux_work;
- int leader_update = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0
- : erts_thr_progress_update(esdp);
+ int leader_update = erts_thr_progress_update(esdp);
aux_work = erts_atomic32_read_acqb(&esdp->ssi->aux_work);
if (aux_work | leader_update | ERTS_SCHED_FAIR) {
erts_smp_runq_unlock(rq);
@@ -9106,8 +9579,7 @@ Process *schedule(Process *p, int calls)
erts_smp_runq_lock(rq);
}
- ERTS_SMP_LC_ASSERT(ERTS_SCHEDULER_IS_DIRTY(esdp)
- || !erts_thr_progress_is_blocking());
+ ERTS_SMP_LC_ASSERT(!erts_thr_progress_is_blocking());
}
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq));
@@ -9166,7 +9638,10 @@ Process *schedule(Process *p, int calls)
}
#endif
+ (void) ERTS_RUNQ_FLGS_UNSET(rq, ERTS_RUNQ_FLG_EXEC);
scheduler_wait(&fcalls, esdp, rq);
+ flags = ERTS_RUNQ_FLGS_SET_NOB(rq, ERTS_RUNQ_FLG_EXEC);
+ flags |= ERTS_RUNQ_FLG_EXEC;
#ifdef ERTS_SMP
non_empty_runq(rq);
@@ -9177,6 +9652,7 @@ Process *schedule(Process *p, int calls)
else if (!ERTS_SCHEDULER_IS_DIRTY(esdp) &&
(fcalls > input_reductions &&
prepare_for_sys_schedule(esdp, !0))) {
+ ErtsMonotonicTime current_time;
/*
* Schedule system-level activities.
*/
@@ -9189,8 +9665,10 @@ Process *schedule(Process *p, int calls)
#endif
erts_smp_runq_unlock(rq);
erl_sys_schedule(1);
- dt = erts_do_time_read_and_reset();
- if (dt) erts_bump_timer(dt);
+
+ current_time = erts_get_monotonic_time(esdp);
+ if (current_time >= erts_next_timeout_time(esdp->next_tmo_ref))
+ erts_bump_timers(esdp->timer_wheel, current_time);
#ifdef ERTS_SMP
erts_smp_runq_lock(rq);
@@ -9329,17 +9807,14 @@ Process *schedule(Process *p, int calls)
| ERTS_PSFLG_PENDING_EXIT
| ERTS_PSFLG_ACTIVE_SYS))
== ERTS_PSFLG_SUSPENDED)) {
- if (state & ERTS_PSFLG_FREE) {
-#ifdef ERTS_SMP
- erts_smp_proc_dec_refc(p);
-#else
- erts_free_proc(p);
-#endif
- }
if (proxy_p) {
free_proxy_proc(proxy_p);
proxy_p = NULL;
}
+ else if (state & ERTS_PSFLG_FREE) {
+ /* free and not queued by proxy */
+ erts_proc_dec_refc(p);
+ }
goto pick_next_process;
}
state = new;
@@ -9363,6 +9838,8 @@ Process *schedule(Process *p, int calls)
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS);
+ state = erts_smp_atomic32_read_nob(&p->state);
+
if (erts_sched_stat.enabled) {
int prio;
UWord old = ERTS_PROC_SCHED_ID(p,
@@ -9478,6 +9955,20 @@ Process *schedule(Process *p, int calls)
/* Never run a suspended process */
ASSERT(!(ERTS_PSFLG_SUSPENDED & erts_smp_atomic32_read_nob(&p->state)));
+ ASSERT(erts_proc_read_refc(p) > 0);
+
+ if (!(state & ERTS_PSFLG_EXITING) && ERTS_PTMR_IS_TIMED_OUT(p)) {
+ BeamInstr** pi;
+#ifdef ERTS_SMP
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
+#endif
+ pi = (BeamInstr **) p->def_arg_reg;
+ p->i = *pi;
+ p->flags &= ~F_INSLPQUEUE;
+ p->flags |= F_TIMO;
+ ERTS_PTMR_CLEAR(p);
+ }
+
return p;
}
}
@@ -9530,15 +10021,7 @@ notify_sys_task_executed(Process *c_p, ErtsProcSysTask *st, Eterm st_result)
ASSERT(hp_start + hsz == hp);
#endif
- erts_queue_message(rp,
- &rp_locks,
- bp,
- msg,
- NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL);
if (c_p == rp)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
@@ -10394,6 +10877,8 @@ erts_free_proc(Process *p)
#ifdef ERTS_SMP
erts_proc_lock_fin(p);
#endif
+ ASSERT(erts_smp_atomic32_read_nob(&p->state) & ERTS_PSFLG_FREE);
+ ASSERT(0 == erts_proc_read_refc(p));
erts_free(ERTS_ALC_T_PROC, (void *) p);
}
@@ -10436,7 +10921,7 @@ alloc_process(ErtsRunQueue *rq, erts_aint32_t state)
init_arg.run_queue = rq;
init_arg.state = state;
- ASSERT(((char *) p) == ((char *) &p->common));
+ ERTS_CT_ASSERT(offsetof(Process,common) == 0);
if (!erts_ptab_new_element(&erts_proc,
&p->common,
@@ -10446,6 +10931,8 @@ alloc_process(ErtsRunQueue *rq, erts_aint32_t state)
return NULL;
}
+ ASSERT(erts_proc_read_refc(p) > 0);
+
ASSERT(internal_pid_serial(p->common.id) <= ERTS_MAX_PID_SERIAL);
p->approx_started = erts_get_approx_time();
@@ -10495,6 +10982,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
int ix = so->scheduler-1;
ASSERT(0 <= ix && ix < erts_no_run_queues);
rq = ERTS_RUNQ_IX(ix);
+ /* Unsupported feature... */
state |= ERTS_PSFLG_BOUND;
}
prio = (erts_aint32_t) so->priority;
@@ -10527,6 +11015,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->flags = erts_default_process_flags;
+ p->static_flags = 0;
+ if (so->flags & SPO_SYSTEM_PROC)
+ p->static_flags |= ERTS_STC_FLG_SYSTEM_PROC;
if (so->flags & SPO_USE_ARGS) {
p->min_heap_size = so->min_heap_size;
p->min_vheap_size = so->min_vheap_size;
@@ -10539,9 +11030,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->schedule_count = 0;
ASSERT(p->min_heap_size == erts_next_heap_size(p->min_heap_size, 0));
- p->initial[INITIAL_MOD] = mod;
- p->initial[INITIAL_FUN] = func;
- p->initial[INITIAL_ARI] = (Uint) arity;
+ p->u.initial[INITIAL_MOD] = mod;
+ p->u.initial[INITIAL_FUN] = func;
+ p->u.initial[INITIAL_ARI] = (Uint) arity;
/*
* Must initialize binary lists here before copying binaries to process.
@@ -10582,7 +11073,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
/* No need to initialize p->fcalls. */
- p->current = p->initial+INITIAL_MOD;
+ p->current = p->u.initial+INITIAL_MOD;
p->i = (BeamInstr *) beam_apply;
p->cp = (BeamInstr *) beam_apply+1;
@@ -10605,11 +11096,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->ftrace = NIL;
p->reds = 0;
-#ifdef ERTS_SMP
- p->common.u.alive.ptimer = NULL;
-#else
- sys_memset(&p->common.u.alive.tm, 0, sizeof(ErlTimer));
-#endif
+ ERTS_PTMR_INIT(p);
p->common.u.alive.reg = NULL;
ERTS_P_LINKS(p) = NULL;
@@ -10640,7 +11127,10 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->msg_inq.last = &p->msg_inq.first;
p->msg_inq.len = 0;
#endif
- p->u.bif_timers = NULL;
+ p->bif_timers = NULL;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ p->accessor_bif_timers = NULL;
+#endif
p->mbuf = NULL;
p->mbuf_sz = 0;
p->psd = NULL;
@@ -10798,11 +11288,7 @@ void erts_init_empty_process(Process *p)
p->bin_old_vheap = 0;
p->sys_task_qs = NULL;
p->bin_vheap_mature = 0;
-#ifdef ERTS_SMP
- p->common.u.alive.ptimer = NULL;
-#else
- memset(&(p->common.u.alive.tm), 0, sizeof(ErlTimer));
-#endif
+ ERTS_PTMR_INIT(p);
p->next = NULL;
p->off_heap.first = NULL;
p->off_heap.overhead = 0;
@@ -10823,14 +11309,17 @@ void erts_init_empty_process(Process *p)
p->msg.last = &p->msg.first;
p->msg.save = &p->msg.first;
p->msg.len = 0;
- p->u.bif_timers = NULL;
+ p->bif_timers = NULL;
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ p->accessor_bif_timers = NULL;
+#endif
p->dictionary = NULL;
p->seq_trace_clock = 0;
p->seq_trace_lastcnt = 0;
p->seq_trace_token = NIL;
- p->initial[0] = 0;
- p->initial[1] = 0;
- p->initial[2] = 0;
+ p->u.initial[0] = 0;
+ p->u.initial[1] = 0;
+ p->u.initial[2] = 0;
p->catches = 0;
p->cp = NULL;
p->i = NULL;
@@ -10851,6 +11340,8 @@ void erts_init_empty_process(Process *p)
p->parent = NIL;
p->approx_started = 0;
+ p->static_flags = 0;
+
p->common.u.alive.started_interval = 0;
#ifdef HIPE
@@ -10915,7 +11406,10 @@ erts_debug_verify_clean_empty_process(Process* p)
ASSERT(p->suspend_monitors == NULL);
ASSERT(p->msg.first == NULL);
ASSERT(p->msg.len == 0);
- ASSERT(p->u.bif_timers == NULL);
+ ASSERT(p->bif_timers == NULL);
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ ASSERT(p->accessor_bif_timers == NULL);
+#endif
ASSERT(p->dictionary == NULL);
ASSERT(p->catches == 0);
ASSERT(p->cp == NULL);
@@ -11079,9 +11573,24 @@ set_proc_exiting(Process *p,
*/
p->freason = EXTAG_EXIT;
KILL_CATCHES(p);
- cancel_timer(p);
p->i = (BeamInstr *) beam_exit;
+#ifndef ERTS_SMP
+ if (state & (ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS)) {
+ /*
+ * I non smp case:
+ *
+ * Currently executing process might be sent an exit
+ * signal if it is traced by a port that it also is
+ * linked to, and the port terminates during the
+ * trace. In this case we want schedule out the
+ * process as quickly as possible in order to detect
+ * the event as fast as possible.
+ */
+ ERTS_VBUMP_ALL_REDS(p);
+ }
+#endif
+
if (enqueue)
add2runq(enqueue > 0 ? p : make_proxy_proc(NULL, p, enq_prio),
state,
@@ -11179,10 +11688,14 @@ save_pending_exiter(Process *p)
{
ErtsProcList *plp;
ErtsRunQueue *rq;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_STATUS & erts_proc_lc_my_proc_locks(p));
- rq = erts_get_runq_current(NULL);
+ if (!esdp)
+ rq = RUNQ_READ_RQ(&p->run_queue);
+ else
+ rq = esdp->run_queue;
plp = proclist_create(p);
@@ -11199,6 +11712,7 @@ save_pending_exiter(Process *p)
else
#endif
wake_scheduler(rq);
+
}
#endif
@@ -11224,11 +11738,7 @@ send_exit_message(Process *to, ErtsProcLocks *to_locksp,
hp = erts_alloc_message_heap(term_size, &bp, &ohp, to, to_locksp);
mess = copy_struct(exit_term, term_size, &hp, ohp);
- erts_queue_message(to, to_locksp, bp, mess, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(to, to_locksp, bp, mess, NIL);
} else {
ErlHeapFragment* bp;
Eterm* hp;
@@ -11244,11 +11754,7 @@ send_exit_message(Process *to, ErtsProcLocks *to_locksp,
/* the trace token must in this case be updated by the caller */
seq_trace_output(token, mess, SEQ_TRACE_SEND, to->common.id, NULL);
temp_token = copy_struct(token, sz_token, &hp, &bp->off_heap);
- erts_queue_message(to, to_locksp, bp, mess, temp_token
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(to, to_locksp, bp, mess, temp_token);
}
}
@@ -11395,23 +11901,21 @@ send_exit_signal(Process *c_p, /* current process if and only
if (need_locks
&& erts_smp_proc_trylock(rp, need_locks) == EBUSY) {
/* ... but we havn't got all locks on it ... */
- save_pending_exiter(rp);
+ save_pending_exiter(rp);
/*
* The pending exit will be discovered when next
* process is scheduled in
*/
- goto set_pending_exit;
- }
- else {
- /* ...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);
+ goto set_pending_exit;
}
+ /* ...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);
}
else { /* Process running... */
@@ -11501,7 +12005,8 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext)
ErtsMonitor *rmon;
Process *rp;
- if (mon->type == MON_ORIGIN) {
+ switch (mon->type) {
+ case MON_ORIGIN:
/* We are monitoring someone else, we need to demonitor that one.. */
if (is_atom(mon->pid)) { /* remote by name */
ASSERT(is_node_name_atom(mon->pid));
@@ -11564,7 +12069,8 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext)
}
}
}
- } else { /* type == MON_TARGET */
+ break;
+ case MON_TARGET:
ASSERT(mon->type == MON_TARGET);
ASSERT(is_pid(mon->pid) || is_internal_port(mon->pid));
if (is_internal_port(mon->pid)) {
@@ -11623,6 +12129,12 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext)
}
}
}
+ break;
+ case MON_TIME_OFFSET:
+ erts_demonitor_time_offset(mon->ref);
+ break;
+ default:
+ ERTS_INTERNAL_ERROR("Invalid monitor type");
}
done:
/* As the monitors are previously removed from the process,
@@ -11742,7 +12254,7 @@ static void doit_exit_link(ErtsLink *lnk, void *vpcontext)
break;
default:
- erl_exit(1, "bad type in link list\n");
+ erts_exit(ERTS_ERROR_EXIT, "bad type in link list\n");
break;
}
erts_destroy_link(lnk);
@@ -11769,6 +12281,7 @@ erts_do_exit_process(Process* p, Eterm reason)
{
p->arity = 0; /* No live registers */
p->fvalue = reason;
+
#ifdef USE_VM_PROBES
if (DTRACE_ENABLED(process_exit)) {
@@ -11781,6 +12294,10 @@ erts_do_exit_process(Process* p, Eterm reason)
}
#endif
+ if (p->static_flags & ERTS_STC_FLG_SYSTEM_PROC)
+ erts_exit(ERTS_DUMP_EXIT, "System process %T terminated: %T\n",
+ p->common.id, reason);
+
#ifdef ERTS_SMP
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
/* By locking all locks (main lock is already locked) when going
@@ -11820,20 +12337,20 @@ erts_do_exit_process(Process* p, Eterm reason)
ASSERT((ERTS_TRACE_FLAGS(p) & F_INITIAL_TRACE_FLAGS)
== F_INITIAL_TRACE_FLAGS);
- cancel_timer(p); /* Always cancel timer just in case */
-
- if (p->u.bif_timers)
- erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);
+ ASSERT(erts_proc_read_refc(p) > 0);
+ if (ERTS_PTMR_IS_SET(p)) {
+ erts_cancel_proc_timer(p);
+ ASSERT(erts_proc_read_refc(p) > 0);
+ }
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
/*
- * The p->u.bif_timers of this process can *not* be used anymore;
+ * p->u.initial of this process can *not* be used anymore;
* will be overwritten by misc termination data.
*/
p->u.terminate = NULL;
-
erts_continue_exit_process(p);
}
@@ -11858,6 +12375,29 @@ erts_continue_exit_process(Process *p)
ASSERT(ERTS_PROC_IS_EXITING(p));
+ ASSERT(erts_proc_read_refc(p) > 0);
+ if (p->bif_timers) {
+ if (erts_cancel_bif_timers(p, p->bif_timers, &p->u.terminate)) {
+ ASSERT(erts_proc_read_refc(p) > 0);
+ goto yield;
+ }
+ ASSERT(erts_proc_read_refc(p) > 0);
+ p->bif_timers = NULL;
+ }
+
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ if (p->accessor_bif_timers) {
+ if (erts_detach_accessor_bif_timers(p,
+ p->accessor_bif_timers,
+ &p->u.terminate)) {
+ ASSERT(erts_proc_read_refc(p) > 0);
+ goto yield;
+ }
+ ASSERT(erts_proc_read_refc(p) > 0);
+ p->accessor_bif_timers = NULL;
+ }
+#endif
+
#ifdef ERTS_SMP
if (p->flags & F_HAVE_BLCKD_MSCHED) {
ErtsSchedSuspendResult ssr;
@@ -11873,7 +12413,7 @@ erts_continue_exit_process(Process *p)
break;
case ERTS_SCHDLR_SSPND_EINVAL:
default:
- erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error: %d\n",
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error: %d\n",
__FILE__, __LINE__, (int) ssr);
}
}
@@ -11951,6 +12491,8 @@ erts_continue_exit_process(Process *p)
p->scheduler_data->current_process = NULL;
p->scheduler_data->free_process = p;
+#else
+ erts_proc_inc_refc(p); /* Decremented in schedule() */
#endif
/* Time of death! */
@@ -11969,34 +12511,26 @@ erts_continue_exit_process(Process *p)
{
/* Inactivate and notify free */
erts_aint32_t n, e, a = erts_smp_atomic32_read_nob(&p->state);
-#ifdef ERTS_SMP
int refc_inced = 0;
-#endif
while (1) {
n = e = a;
ASSERT(a & ERTS_PSFLG_EXITING);
n |= ERTS_PSFLG_FREE;
n &= ~ERTS_PSFLG_ACTIVE;
-#ifdef ERTS_SMP
if ((n & ERTS_PSFLG_IN_RUNQ) && !refc_inced) {
- erts_smp_proc_inc_refc(p);
+ erts_proc_inc_refc(p);
refc_inced = 1;
}
-#endif
a = erts_smp_atomic32_cmpxchg_mb(&p->state, n, e);
if (a == e)
break;
}
-#ifdef ERTS_SMP
if (refc_inced && !(n & ERTS_PSFLG_IN_RUNQ))
- erts_smp_proc_dec_refc(p);
-#endif
+ erts_proc_dec_refc(p);
}
- dep = ((p->flags & F_DISTRIBUTION)
- ? ERTS_PROC_SET_DIST_ENTRY(p, ERTS_PROC_LOCKS_ALL, NULL)
- : NULL);
+ dep = (p->flags & F_DISTRIBUTION) ? erts_this_dist_entry : NULL;
scb = ERTS_PROC_SET_SAVED_CALLS_BUF(p, ERTS_PROC_LOCKS_ALL, NULL);
pbt = ERTS_PROC_SET_CALL_TIME(p, ERTS_PROC_LOCKS_ALL, NULL);
nif_export = ERTS_PROC_SET_NIF_TRAP_EXPORT(p, ERTS_PROC_LOCKS_ALL, NULL);
@@ -12008,8 +12542,6 @@ erts_continue_exit_process(Process *p)
if (dep) {
erts_do_net_exits(dep, reason);
- if(dep)
- erts_deref_dist_entry(dep);
}
/*
@@ -12082,64 +12614,6 @@ erts_continue_exit_process(Process *p)
}
-/* Callback for process timeout */
-static void
-timeout_proc(Process* p)
-{
- erts_aint32_t state;
- BeamInstr** pi = (BeamInstr **) p->def_arg_reg;
- p->i = *pi;
- p->flags |= F_TIMO;
- p->flags &= ~F_INSLPQUEUE;
-
- state = erts_smp_atomic32_read_acqb(&p->state);
- if (!(state & ERTS_PSFLG_ACTIVE))
- schedule_process(p, state, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS);
-}
-
-
-void
-cancel_timer(Process* p)
-{
- ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));
- p->flags &= ~(F_INSLPQUEUE|F_TIMO);
-#ifdef ERTS_SMP
- erts_cancel_smp_ptimer(p->common.u.alive.ptimer);
-#else
- erts_cancel_timer(&p->common.u.alive.tm);
-#endif
-}
-
-/*
- * Insert a process into the time queue, with a timeout 'timeout' in ms.
- */
-void
-set_timer(Process* p, Uint timeout)
-{
- ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));
-
- /* check for special case timeout=0 DONT ADD TO time queue */
- if (timeout == 0) {
- p->flags |= F_TIMO;
- return;
- }
- p->flags |= F_INSLPQUEUE;
- p->flags &= ~F_TIMO;
-
-#ifdef ERTS_SMP
- erts_create_smp_ptimer(&p->common.u.alive.ptimer,
- p->common.id,
- (ErlTimeoutProc) timeout_proc,
- timeout);
-#else
- erts_set_timer(&p->common.u.alive.tm,
- (ErlTimeoutProc) timeout_proc,
- NULL,
- (void*) p,
- timeout);
-#endif
-}
-
/*
* Stack dump functions follow.
*/
@@ -12155,7 +12629,7 @@ erts_stack_dump(int to, void *to_arg, Process *p)
}
erts_program_counter_info(to, to_arg, p);
for (sp = p->stop; sp < STACK_START(p); sp++) {
- yreg = stack_element_dump(to, to_arg, p, sp, yreg);
+ yreg = stack_element_dump(to, to_arg, sp, yreg);
}
}
@@ -12212,7 +12686,7 @@ print_function_from_pc(int to, void *to_arg, BeamInstr* x)
}
static int
-stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
+stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg)
{
Eterm x = *sp;
@@ -12241,6 +12715,188 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
}
/*
+ * Print scheduler information
+ */
+void
+erts_print_scheduler_info(int to, void *to_arg, ErtsSchedulerData *esdp) {
+ int i;
+ erts_aint32_t flg;
+ Process *p;
+
+ erts_print(to, to_arg, "=scheduler:%u\n", esdp->no);
+
+#ifdef ERTS_SMP
+ flg = erts_smp_atomic32_read_dirty(&esdp->ssi->flags);
+ erts_print(to, to_arg, "Scheduler Sleep Info Flags: ");
+ for (i = 0; i < ERTS_SSI_FLGS_MAX && flg; i++) {
+ erts_aint32_t chk = (1 << i);
+ if (flg & chk) {
+ switch (chk) {
+ case ERTS_SSI_FLG_SLEEPING:
+ erts_print(to, to_arg, "SLEEPING"); break;
+ case ERTS_SSI_FLG_POLL_SLEEPING:
+ erts_print(to, to_arg, "POLL_SLEEPING"); break;
+ case ERTS_SSI_FLG_TSE_SLEEPING:
+ erts_print(to, to_arg, "TSE_SLEEPING"); break;
+ case ERTS_SSI_FLG_WAITING:
+ erts_print(to, to_arg, "WAITING"); break;
+ case ERTS_SSI_FLG_SUSPENDED:
+ erts_print(to, to_arg, "SUSPENDED"); break;
+ default:
+ erts_print(to, to_arg, "UNKNOWN(%d)", flg); break;
+ }
+ if (flg > chk)
+ erts_print(to, to_arg, " | ");
+ flg -= chk;
+ }
+ }
+ erts_print(to, to_arg, "\n");
+#endif
+
+ flg = erts_atomic32_read_dirty(&esdp->ssi->aux_work);
+ erts_print(to, to_arg, "Scheduler Sleep Info Aux Work: ");
+ for (i = 0; i < ERTS_SSI_AUX_WORK_NO_FLAGS && flg; i++) {
+ erts_aint32_t chk = (1 << i);
+ if (flg & chk) {
+ if (erts_aux_work_flag_descr[i])
+ erts_print(to, to_arg, "%s", erts_aux_work_flag_descr[i]);
+ else
+ erts_print(to, to_arg, "1<<%d", i);
+ if (flg > chk)
+ erts_print(to, to_arg, " | ");
+ flg -= chk;
+ }
+ }
+ erts_print(to, to_arg, "\n");
+
+ erts_print(to, to_arg, "Current Port: ");
+ if (esdp->current_port)
+ erts_print(to, to_arg, "%T", esdp->current_port->common.id);
+ erts_print(to, to_arg, "\n");
+
+ for (i = 0; i < ERTS_NO_PROC_PRIO_LEVELS; i++) {
+ erts_print(to, to_arg, "Run Queue ");
+ switch (i) {
+ case PRIORITY_MAX:
+ erts_print(to, to_arg, "Max ");
+ break;
+ case PRIORITY_HIGH:
+ erts_print(to, to_arg, "High ");
+ break;
+ case PRIORITY_NORMAL:
+ erts_print(to, to_arg, "Normal ");
+ break;
+ case PRIORITY_LOW:
+ erts_print(to, to_arg, "Low ");
+ break;
+ default:
+ erts_print(to, to_arg, "Unknown ");
+ break;
+ }
+ erts_print(to, to_arg, "Length: %d\n",
+ erts_smp_atomic32_read_dirty(&esdp->run_queue->procs.prio_info[i].len));
+ }
+ erts_print(to, to_arg, "Run Queue Port Length: %d\n",
+ erts_smp_atomic32_read_dirty(&esdp->run_queue->ports.info.len));
+
+ flg = erts_smp_atomic32_read_dirty(&esdp->run_queue->flags);
+ erts_print(to, to_arg, "Run Queue Flags: ");
+ for (i = 0; i < ERTS_RUNQ_FLG_MAX && flg; i++) {
+ erts_aint32_t chk = (1 << i);
+ if (flg & chk) {
+ switch (chk) {
+ case (1 << PRIORITY_MAX):
+ erts_print(to, to_arg, "NONEMPTY_MAX"); break;
+ case (1 << PRIORITY_HIGH):
+ erts_print(to, to_arg, "NONEMPTY_HIGH"); break;
+ case (1 << PRIORITY_NORMAL):
+ erts_print(to, to_arg, "NONEMPTY_NORMAL"); break;
+ case (1 << PRIORITY_LOW):
+ erts_print(to, to_arg, "NONEMPTY_LOW"); break;
+ case (1 << (PRIORITY_MAX + ERTS_RUNQ_FLGS_EMIGRATE_SHFT)):
+ erts_print(to, to_arg, "EMIGRATE_MAX"); break;
+ case (1 << (PRIORITY_HIGH + ERTS_RUNQ_FLGS_EMIGRATE_SHFT)):
+ erts_print(to, to_arg, "EMIGRATE_HIGH"); break;
+ case (1 << (PRIORITY_NORMAL + ERTS_RUNQ_FLGS_EMIGRATE_SHFT)):
+ erts_print(to, to_arg, "EMIGRATE_NORMAL"); break;
+ case (1 << (PRIORITY_LOW + ERTS_RUNQ_FLGS_EMIGRATE_SHFT)):
+ erts_print(to, to_arg, "EMIGRATE_LOW"); break;
+ case (1 << (PRIORITY_MAX + ERTS_RUNQ_FLGS_IMMIGRATE_SHFT)):
+ erts_print(to, to_arg, "IMMIGRATE_MAX"); break;
+ case (1 << (PRIORITY_HIGH + ERTS_RUNQ_FLGS_IMMIGRATE_SHFT)):
+ erts_print(to, to_arg, "IMMIGRATE_HIGH"); break;
+ case (1 << (PRIORITY_NORMAL + ERTS_RUNQ_FLGS_IMMIGRATE_SHFT)):
+ erts_print(to, to_arg, "IMMIGRATE_NORMAL"); break;
+ case (1 << (PRIORITY_LOW + ERTS_RUNQ_FLGS_IMMIGRATE_SHFT)):
+ erts_print(to, to_arg, "IMMIGRATE_LOW"); break;
+ case (1 << (PRIORITY_MAX + ERTS_RUNQ_FLGS_EVACUATE_SHFT)):
+ erts_print(to, to_arg, "EVACUATE_MAX"); break;
+ case (1 << (PRIORITY_HIGH + ERTS_RUNQ_FLGS_EVACUATE_SHFT)):
+ erts_print(to, to_arg, "EVACUATE_HIGH"); break;
+ case (1 << (PRIORITY_NORMAL + ERTS_RUNQ_FLGS_EVACUATE_SHFT)):
+ erts_print(to, to_arg, "EVACUATE_NORMAL"); break;
+ case (1 << (PRIORITY_LOW + ERTS_RUNQ_FLGS_EVACUATE_SHFT)):
+ erts_print(to, to_arg, "EVACUATE_LOW"); break;
+ case ERTS_RUNQ_FLG_OUT_OF_WORK:
+ erts_print(to, to_arg, "OUT_OF_WORK"); break;
+ case ERTS_RUNQ_FLG_HALFTIME_OUT_OF_WORK:
+ erts_print(to, to_arg, "HALFTIME_OUT_OF_WORK"); break;
+ case ERTS_RUNQ_FLG_SUSPENDED:
+ erts_print(to, to_arg, "SUSPENDED"); break;
+ case ERTS_RUNQ_FLG_CHK_CPU_BIND:
+ erts_print(to, to_arg, "CHK_CPU_BIND"); break;
+ case ERTS_RUNQ_FLG_INACTIVE:
+ erts_print(to, to_arg, "INACTIVE"); break;
+ case ERTS_RUNQ_FLG_NONEMPTY:
+ erts_print(to, to_arg, "NONEMPTY"); break;
+ case ERTS_RUNQ_FLG_PROTECTED:
+ erts_print(to, to_arg, "PROTECTED"); break;
+ default:
+ erts_print(to, to_arg, "UNKNOWN(%d)", flg); break;
+ }
+ if (flg > chk)
+ erts_print(to, to_arg, " | ");
+ flg -= chk;
+ }
+ }
+ erts_print(to, to_arg, "\n");
+
+ /* This *MUST* to be the last information in scheduler block */
+ p = esdp->current_process;
+ erts_print(to, to_arg, "Current Process: ");
+ if (esdp->current_process && !(ERTS_TRACE_FLAGS(p) & F_SENSITIVE)) {
+ flg = erts_smp_atomic32_read_dirty(&p->state);
+ erts_print(to, to_arg, "%T\n", p->common.id);
+
+ erts_print(to, to_arg, "Current Process State: ");
+ erts_dump_process_state(to, to_arg, flg);
+
+ erts_print(to, to_arg, "Current Process Internal State: ");
+ erts_dump_extended_process_state(to, to_arg, flg);
+
+ erts_print(to, to_arg, "Current Process Program counter: %p (", p->i);
+ print_function_from_pc(to, to_arg, p->i);
+ erts_print(to, to_arg, ")\n");
+ erts_print(to, to_arg, "Current Process CP: %p (", p->cp);
+ print_function_from_pc(to, to_arg, p->cp);
+ erts_print(to, to_arg, ")\n");
+
+ /* Getting this stacktrace can segfault if we are very very
+ unlucky if called while a process is being garbage collected.
+ Therefore we only call this on other schedulers if we either
+ have protection against segfaults, or we know that the process
+ is not garbage collecting. It *should* always be safe to call
+ on a process owned by us, even if it is currently being garbage
+ collected.
+ */
+ erts_print(to, to_arg, "Current Process Limited Stack Trace:\n");
+ erts_limited_stack_trace(to, to_arg, p);
+ } else
+ erts_print(to, to_arg, "\n");
+
+}
+
+/*
* A nice system halt closing all open port goes as follows:
* 1) This function schedules the aux work ERTS_SSI_AUX_WORK_REAP_PORTS
* on all schedulers, then schedules itself out.
@@ -12254,10 +12910,10 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
* The same global atomic is used as refcount.
*
* A BIF that calls this should make sure to schedule out to never come back:
- * erl_halt((int)(- code));
+ * erts_halt(code);
* ERTS_BIF_YIELD1(bif_export[BIF_erlang_halt_1], BIF_P, NIL);
*/
-void erl_halt(int code)
+void erts_halt(int code)
{
if (-1 == erts_smp_atomic32_cmpxchg_acqb(&erts_halt_progress,
erts_no_schedulers,
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index f50b217d4a..b536426b0f 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -52,12 +53,16 @@ typedef struct process Process;
#include "erl_node_container_utils.h"
#include "erl_node_tables.h"
#include "erl_monitors.h"
-#include "erl_bif_timer.h"
+#include "erl_hl_timer.h"
#include "erl_time.h"
#include "erl_atom_table.h"
#include "external.h"
#include "erl_mseg.h"
#include "erl_async.h"
+#include "erl_gc.h"
+#define ERTS_ONLY_INCLUDE_TRACE_FLAGS
+#include "erl_trace.h"
+#undef ERTS_ONLY_INCLUDE_TRACE_FLAGS
#ifdef HIPE
#include "hipe_process.h"
@@ -168,6 +173,10 @@ extern int erts_sched_thread_suggested_stack_size;
(((Uint32) 1) << (ERTS_RUNQ_FLG_BASE2 + 5))
#define ERTS_RUNQ_FLG_PROTECTED \
(((Uint32) 1) << (ERTS_RUNQ_FLG_BASE2 + 6))
+#define ERTS_RUNQ_FLG_EXEC \
+ (((Uint32) 1) << (ERTS_RUNQ_FLG_BASE2 + 7))
+
+#define ERTS_RUNQ_FLG_MAX (ERTS_RUNQ_FLG_BASE2 + 8)
#define ERTS_RUNQ_FLGS_MIGRATION_QMASKS \
(ERTS_RUNQ_FLGS_EMIGRATE_QMASK \
@@ -211,6 +220,9 @@ extern int erts_sched_thread_suggested_stack_size;
#define ERTS_RUNQ_FLGS_SET(RQ, FLGS) \
((Uint32) erts_smp_atomic32_read_bor_relb(&(RQ)->flags, \
(erts_aint32_t) (FLGS)))
+#define ERTS_RUNQ_FLGS_SET_NOB(RQ, FLGS) \
+ ((Uint32) erts_smp_atomic32_read_bor_nob(&(RQ)->flags, \
+ (erts_aint32_t) (FLGS)))
#define ERTS_RUNQ_FLGS_BSET(RQ, MSK, FLGS) \
((Uint32) erts_smp_atomic32_read_bset_relb(&(RQ)->flags, \
(erts_aint32_t) (MSK), \
@@ -218,6 +230,9 @@ extern int erts_sched_thread_suggested_stack_size;
#define ERTS_RUNQ_FLGS_UNSET(RQ, FLGS) \
((Uint32) erts_smp_atomic32_read_band_relb(&(RQ)->flags, \
(erts_aint32_t) ~(FLGS)))
+#define ERTS_RUNQ_FLGS_UNSET_NOB(RQ, FLGS) \
+ ((Uint32) erts_smp_atomic32_read_band_nob(&(RQ)->flags, \
+ (erts_aint32_t) ~(FLGS)))
#define ERTS_RUNQ_FLGS_GET(RQ) \
((Uint32) erts_smp_atomic32_read_acqb(&(RQ)->flags))
#define ERTS_RUNQ_FLGS_GET_NOB(RQ) \
@@ -251,6 +266,8 @@ typedef enum {
#define ERTS_SSI_FLG_WAITING (((erts_aint32_t) 1) << 3)
#define ERTS_SSI_FLG_SUSPENDED (((erts_aint32_t) 1) << 4)
+#define ERTS_SSI_FLGS_MAX 5
+
#define ERTS_SSI_FLGS_SLEEP_TYPE \
(ERTS_SSI_FLG_TSE_SLEEPING|ERTS_SSI_FLG_POLL_SLEEPING)
@@ -263,24 +280,73 @@ typedef enum {
| ERTS_SSI_FLG_SUSPENDED)
/*
- * Keep ERTS_SSI_AUX_WORK flags in expected frequency order relative
- * eachother. Most frequent - lowest bit number.
+ * Keep ERTS_SSI_AUX_WORK flags ordered in expected frequency
+ * order relative eachother. Most frequent at lowest at lowest
+ * index.
+ *
+ * ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED_IX *need* to be
+ * highest index...
+ *
+ * Remember to update description in erts_pre_init_process()
+ * when adding new flags...
*/
-#define ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP (((erts_aint32_t) 1) << 0)
-#define ERTS_SSI_AUX_WORK_DD (((erts_aint32_t) 1) << 1)
-#define ERTS_SSI_AUX_WORK_DD_THR_PRGR (((erts_aint32_t) 1) << 2)
-#define ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC (((erts_aint32_t) 1) << 3)
-#define ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM (((erts_aint32_t) 1) << 4)
-#define ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP (((erts_aint32_t) 1) << 5)
-#define ERTS_SSI_AUX_WORK_ASYNC_READY (((erts_aint32_t) 1) << 6)
-#define ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN (((erts_aint32_t) 1) << 7)
-#define ERTS_SSI_AUX_WORK_MISC_THR_PRGR (((erts_aint32_t) 1) << 8)
-#define ERTS_SSI_AUX_WORK_MISC (((erts_aint32_t) 1) << 9)
-#define ERTS_SSI_AUX_WORK_CHECK_CHILDREN (((erts_aint32_t) 1) << 10)
-#define ERTS_SSI_AUX_WORK_SET_TMO (((erts_aint32_t) 1) << 11)
-#define ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK (((erts_aint32_t) 1) << 12)
-#define ERTS_SSI_AUX_WORK_REAP_PORTS (((erts_aint32_t) 1) << 13)
+typedef enum {
+ ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP_IX,
+ ERTS_SSI_AUX_WORK_DD_IX,
+ ERTS_SSI_AUX_WORK_DD_THR_PRGR_IX,
+ ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC_IX,
+ ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM_IX,
+ ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP_IX,
+ ERTS_SSI_AUX_WORK_CNCLD_TMRS_IX,
+ ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR_IX,
+ ERTS_SSI_AUX_WORK_ASYNC_READY_IX,
+ ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN_IX,
+ ERTS_SSI_AUX_WORK_MISC_THR_PRGR_IX,
+ ERTS_SSI_AUX_WORK_MISC_IX,
+ ERTS_SSI_AUX_WORK_CHECK_CHILDREN_IX,
+ ERTS_SSI_AUX_WORK_SET_TMO_IX,
+ ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK_IX,
+ ERTS_SSI_AUX_WORK_REAP_PORTS_IX,
+ ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED_IX, /* SHOULD be last flag index */
+
+ ERTS_SSI_AUX_WORK_NO_FLAGS /* Not a flag index... */
+} ErtsSsiAuxWorkFlagIndex;
+
+#define ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP_IX)
+#define ERTS_SSI_AUX_WORK_DD \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_DD_IX)
+#define ERTS_SSI_AUX_WORK_DD_THR_PRGR \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_DD_THR_PRGR_IX)
+#define ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC_IX)
+#define ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM_IX)
+#define ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP_IX)
+#define ERTS_SSI_AUX_WORK_CNCLD_TMRS \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_CNCLD_TMRS_IX)
+#define ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_CNCLD_TMRS_THR_PRGR_IX)
+#define ERTS_SSI_AUX_WORK_ASYNC_READY \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_ASYNC_READY_IX)
+#define ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN_IX)
+#define ERTS_SSI_AUX_WORK_MISC_THR_PRGR \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_MISC_THR_PRGR_IX)
+#define ERTS_SSI_AUX_WORK_MISC \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_MISC_IX)
+#define ERTS_SSI_AUX_WORK_CHECK_CHILDREN \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_CHECK_CHILDREN_IX)
+#define ERTS_SSI_AUX_WORK_SET_TMO \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_SET_TMO_IX)
+#define ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK_IX)
+#define ERTS_SSI_AUX_WORK_REAP_PORTS \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_REAP_PORTS_IX)
+#define ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED \
+ (((erts_aint32_t) 1) << ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED_IX)
typedef struct ErtsSchedulerSleepInfo_ ErtsSchedulerSleepInfo;
@@ -341,7 +407,7 @@ typedef struct {
} ErtsRunQueueInfo;
-#ifdef HAVE_GETHRTIME
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
# undef ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT_OPT
# define ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT_OPT 1
#endif
@@ -412,7 +478,7 @@ struct ErtsRunQueue_ {
int full_reds_history[ERTS_FULL_REDS_HISTORY_SIZE];
int out_of_work_count;
erts_aint32_t max_len;
- erts_aint32_t len;
+ erts_smp_atomic32_t len;
int wakeup_other;
int wakeup_other_reds;
int halt_in_progress;
@@ -456,19 +522,21 @@ typedef union {
extern ErtsAlignedRunQueue *erts_aligned_run_queues;
-#define ERTS_PROC_REDUCTIONS_EXECUTED(RQ, PRIO, REDS, AREDS) \
+#define ERTS_PROC_REDUCTIONS_EXECUTED(SD, RQ, PRIO, REDS, AREDS)\
do { \
(RQ)->procs.reductions += (AREDS); \
(RQ)->procs.prio_info[(PRIO)].reds += (REDS); \
(RQ)->check_balance_reds -= (REDS); \
(RQ)->wakeup_other_reds += (AREDS); \
+ (SD)->check_time_reds += (AREDS); \
} while (0)
-#define ERTS_PORT_REDUCTIONS_EXECUTED(RQ, REDS) \
+#define ERTS_PORT_REDUCTIONS_EXECUTED(SD, RQ, REDS) \
do { \
(RQ)->ports.info.reds += (REDS); \
(RQ)->check_balance_reds -= (REDS); \
(RQ)->wakeup_other_reds += (REDS); \
+ (SD)->check_time_reds += (REDS); \
} while (0)
typedef struct {
@@ -483,11 +551,6 @@ typedef struct {
} ErtsSchedWallTime;
typedef struct {
- Uint64 reclaimed;
- Uint64 garbage_cols;
-} ErtsGCInfo;
-
-typedef struct {
int sched;
erts_aint32_t aux_work;
} ErtsDelayedAuxWorkWakeupJob;
@@ -509,11 +572,12 @@ typedef struct {
#ifdef ERTS_SMP
struct {
ErtsThrPrgrVal thr_prgr;
- void (*completed_callback)(void *);
- void (*completed_arg)(void *);
} dd;
struct {
ErtsThrPrgrVal thr_prgr;
+ } cncld_tmrs;
+ struct {
+ ErtsThrPrgrVal thr_prgr;
UWord size;
ErtsThrPrgrLaterOp *first;
ErtsThrPrgrLaterOp *last;
@@ -536,6 +600,13 @@ typedef struct {
ErtsDelayedAuxWorkWakeupJob *job;
} delayed_wakeup;
#endif
+ struct {
+ struct {
+ erts_aint32_t flags;
+ void (*callback)(void *);
+ void *arg;
+ } wait_completed;
+ } debug;
} ErtsAuxWorkData;
#ifdef ERTS_DIRTY_SCHEDULERS
@@ -547,7 +618,7 @@ typedef enum {
typedef union {
struct {
ErtsDirtySchedulerType type: 1;
- unsigned num: 31;
+ Uint num: sizeof(Uint)*8 - 1;
} s;
Uint no;
} ErtsDirtySchedId;
@@ -562,6 +633,9 @@ struct ErtsSchedulerData_ {
Eterm* x_reg_array; /* X registers */
FloatDef* f_reg_array; /* Floating point registers. */
+ ErtsTimerWheel *timer_wheel;
+ ErtsNextTimeoutRef next_tmo_ref;
+ ErtsHLTimerService *timer_service;
#ifdef ERTS_SMP
ethr_tid tid; /* Thread id */
struct erl_bits_state erl_bits_state; /* erl_bits.c state */
@@ -588,8 +662,20 @@ struct ErtsSchedulerData_ {
ErtsAuxWorkData aux_work_data;
ErtsAtomCacheMap atom_cache_map;
+ ErtsMonotonicTime last_monotonic_time;
+ int check_time_reds;
+
+ Uint32 thr_id;
+ Uint64 unique;
+ Uint64 ref;
+
ErtsSchedAllocData alloc_data;
+ struct {
+ Uint64 out;
+ Uint64 in;
+ } io;
+
Uint64 reductions;
ErtsSchedWallTime sched_wall_time;
ErtsGCInfo gc_info;
@@ -653,7 +739,19 @@ erts_smp_inc_runq_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi, int prio)
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq));
- len = erts_smp_atomic32_read_nob(&rqi->len);
+ len = erts_smp_atomic32_read_dirty(&rq->len);
+
+#ifdef ERTS_SMP
+ if (len == 0)
+ erts_non_empty_runq(rq);
+#endif
+ len++;
+ if (rq->max_len < len)
+ rq->max_len = len;
+ ASSERT(len > 0);
+ erts_smp_atomic32_set_nob(&rq->len, len);
+
+ len = erts_smp_atomic32_read_dirty(&rqi->len);
ASSERT(len >= 0);
if (len == 0) {
ASSERT((erts_smp_atomic32_read_nob(&rq->flags)
@@ -666,15 +764,6 @@ erts_smp_inc_runq_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi, int prio)
rqi->max_len = len;
erts_smp_atomic32_set_relb(&rqi->len, len);
-
-#ifdef ERTS_SMP
- if (rq->len == 0)
- erts_non_empty_runq(rq);
-#endif
- rq->len++;
- if (rq->max_len < rq->len)
- rq->max_len = len;
- ASSERT(rq->len > 0);
}
ERTS_GLB_INLINE void
@@ -684,7 +773,12 @@ erts_smp_dec_runq_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi, int prio)
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq));
- len = erts_smp_atomic32_read_nob(&rqi->len);
+ len = erts_smp_atomic32_read_dirty(&rq->len);
+ len--;
+ ASSERT(len >= 0);
+ erts_smp_atomic32_set_nob(&rq->len, len);
+
+ len = erts_smp_atomic32_read_dirty(&rqi->len);
len--;
ASSERT(len >= 0);
if (len == 0) {
@@ -695,8 +789,6 @@ erts_smp_dec_runq_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi, int prio)
}
erts_smp_atomic32_set_relb(&rqi->len, len);
- rq->len--;
- ASSERT(rq->len >= 0);
}
ERTS_GLB_INLINE void
@@ -706,7 +798,7 @@ erts_smp_reset_max_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi)
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq));
- len = erts_smp_atomic32_read_nob(&rqi->len);
+ len = erts_smp_atomic32_read_dirty(&rqi->len);
ASSERT(rqi->max_len >= len);
rqi->max_len = len;
}
@@ -726,12 +818,11 @@ erts_smp_reset_max_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi)
#define ERTS_PSD_ERROR_HANDLER 0
#define ERTS_PSD_SAVED_CALLS_BUF 1
#define ERTS_PSD_SCHED_ID 2
-#define ERTS_PSD_DIST_ENTRY 3
-#define ERTS_PSD_CALL_TIME_BP 4
-#define ERTS_PSD_DELAYED_GC_TASK_QS 5
-#define ERTS_PSD_NIF_TRAP_EXPORT 6
+#define ERTS_PSD_CALL_TIME_BP 3
+#define ERTS_PSD_DELAYED_GC_TASK_QS 4
+#define ERTS_PSD_NIF_TRAP_EXPORT 5
-#define ERTS_PSD_SIZE 7
+#define ERTS_PSD_SIZE 6
typedef struct {
void *data[ERTS_PSD_SIZE];
@@ -749,9 +840,6 @@ typedef struct {
#define ERTS_PSD_SCHED_ID_GET_LOCKS ERTS_PROC_LOCK_STATUS
#define ERTS_PSD_SCHED_ID_SET_LOCKS ERTS_PROC_LOCK_STATUS
-#define ERTS_PSD_DIST_ENTRY_GET_LOCKS ERTS_PROC_LOCK_MAIN
-#define ERTS_PSD_DIST_ENTRY_SET_LOCKS ERTS_PROC_LOCK_MAIN
-
#define ERTS_PSD_CALL_TIME_BP_GET_LOCKS ERTS_PROC_LOCK_MAIN
#define ERTS_PSD_CALL_TIME_BP_SET_LOCKS ERTS_PROC_LOCK_MAIN
@@ -905,10 +993,10 @@ struct process {
ErlMessageQueue msg; /* Message queue */
- union {
- ErtsBifTimer *bif_timers; /* Bif timers aiming at this process */
- void *terminate;
- } u;
+ ErtsBifTimers *bif_timers; /* Bif timers aiming at this process */
+#ifdef ERTS_BTM_ACCESSOR_SUPPORT
+ ErtsBifTimers *accessor_bif_timers; /* Accessor bif timers */
+#endif
ProcDict *dictionary; /* Process dictionary, may be NULL */
@@ -919,9 +1007,12 @@ struct process {
#ifdef USE_VM_PROBES
Eterm dt_utag; /* Place to store the dynamc trace user tag */
Uint dt_utag_flags; /* flag field for the dt_utag */
-#endif
- BeamInstr initial[3]; /* Initial module(0), function(1), arity(2), often used instead
+#endif
+ union {
+ void *terminate;
+ BeamInstr initial[3]; /* Initial module(0), function(1), arity(2), often used instead
of pointer to funcinfo instruction, hence the BeamInstr datatype */
+ } u;
BeamInstr* current; /* Current Erlang function, part of the funcinfo:
* module(0), function(1), arity(2)
* (module and functions are tagged atoms;
@@ -934,6 +1025,8 @@ struct process {
Eterm parent; /* Pid of process that created this process. */
erts_approx_time_t approx_started; /* Time when started. */
+ Uint32 static_flags; /* Flags that do *not* change */
+
/* This is the place, where all fields that differs between memory
* architectures, have gone to.
*/
@@ -1079,6 +1172,9 @@ void erts_check_for_holes(Process* p);
#define ERTS_PSFLG_DIRTY_IO_PROC ERTS_PSFLG_BIT(19)
#define ERTS_PSFLG_DIRTY_CPU_PROC_IN_Q ERTS_PSFLG_BIT(20)
#define ERTS_PSFLG_DIRTY_IO_PROC_IN_Q ERTS_PSFLG_BIT(21)
+#define ERTS_PSFLG_MAX (ERTS_PSFLGS_ZERO_BIT_OFFSET + 22)
+#else
+#define ERTS_PSFLG_MAX (ERTS_PSFLGS_ZERO_BIT_OFFSET + 18)
#endif
#define ERTS_PSFLGS_IN_PRQ_MASK (ERTS_PSFLG_IN_PRQ_MAX \
@@ -1091,7 +1187,12 @@ void erts_check_for_holes(Process* p);
#define ERTS_PSFLGS_GET_USR_PRIO(PSFLGS) \
(((PSFLGS) >> ERTS_PSFLGS_USR_PRIO_OFFSET) & ERTS_PSFLGS_PRIO_MASK)
#define ERTS_PSFLGS_GET_PRQ_PRIO(PSFLGS) \
- (((PSFLGS) >> ERTS_PSFLGS_USR_PRIO_OFFSET) & ERTS_PSFLGS_PRIO_MASK)
+ (((PSFLGS) >> ERTS_PSFLGS_PRQ_PRIO_OFFSET) & ERTS_PSFLGS_PRIO_MASK)
+
+/*
+ * Static flags that do not change after process creation.
+ */
+#define ERTS_STC_FLG_SYSTEM_PROC (((Uint32) 1) << 0)
/* The sequential tracing token is a tuple of size 5:
*
@@ -1120,6 +1221,7 @@ void erts_check_for_holes(Process* p);
#define SPO_LINK 1
#define SPO_USE_ARGS 2
#define SPO_MONITOR 4
+#define SPO_SYSTEM_PROC 8
/*
* The following struct contains options for a process to be spawned.
@@ -1193,6 +1295,7 @@ struct erts_system_profile_flags_t {
unsigned int exclusive : 1;
};
extern struct erts_system_profile_flags_t erts_system_profile_flags;
+extern int erts_system_profile_ts_type;
/* process flags */
#define F_HIBERNATE_SCHED (1 << 0) /* Schedule out after hibernate op */
@@ -1208,63 +1311,90 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;
#define F_FORCE_GC (1 << 10) /* Force gc at process in-scheduling */
#define F_DISABLE_GC (1 << 11) /* Disable GC */
+#define ERTS_TRACE_FLAGS_TS_TYPE_SHIFT 0
+
+#define F_TRACE_FLAG(N) (1 << (ERTS_TRACE_TS_TYPE_BITS + (N)))
+
/* process trace_flags */
-#define F_SENSITIVE (1 << 0)
-#define F_TRACE_SEND (1 << 1)
-#define F_TRACE_RECEIVE (1 << 2)
-#define F_TRACE_SOS (1 << 3) /* Set on spawn */
-#define F_TRACE_SOS1 (1 << 4) /* Set on first spawn */
-#define F_TRACE_SOL (1 << 5) /* Set on link */
-#define F_TRACE_SOL1 (1 << 6) /* Set on first link */
-#define F_TRACE_CALLS (1 << 7)
-#define F_TIMESTAMP (1 << 8)
-#define F_TRACE_PROCS (1 << 9)
-#define F_TRACE_FIRST_CHILD (1 << 10)
-#define F_TRACE_SCHED (1 << 11)
-#define F_TRACE_GC (1 << 12)
-#define F_TRACE_ARITY_ONLY (1 << 13)
-#define F_TRACE_RETURN_TO (1 << 14) /* Return_to trace when breakpoint tracing */
-#define F_TRACE_SILENT (1 << 15) /* No call trace msg suppress */
-#define F_TRACER (1 << 16) /* May be (has been) tracer */
-#define F_EXCEPTION_TRACE (1 << 17) /* May have exception trace on stack */
+
+#define F_NOW_TS (ERTS_TRACE_FLG_NOW_TIMESTAMP \
+ << ERTS_TRACE_FLAGS_TS_TYPE_SHIFT)
+#define F_STRICT_MON_TS (ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP \
+ << ERTS_TRACE_FLAGS_TS_TYPE_SHIFT)
+#define F_MON_TS (ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP \
+ << ERTS_TRACE_FLAGS_TS_TYPE_SHIFT)
+#define F_SENSITIVE F_TRACE_FLAG(0)
+#define F_TRACE_SEND F_TRACE_FLAG(1)
+#define F_TRACE_RECEIVE F_TRACE_FLAG(2)
+#define F_TRACE_SOS F_TRACE_FLAG(3) /* Set on spawn */
+#define F_TRACE_SOS1 F_TRACE_FLAG(4) /* Set on first spawn */
+#define F_TRACE_SOL F_TRACE_FLAG(5) /* Set on link */
+#define F_TRACE_SOL1 F_TRACE_FLAG(6) /* Set on first link */
+#define F_TRACE_CALLS F_TRACE_FLAG(7)
+#define F_TRACE_PROCS F_TRACE_FLAG(8)
+#define F_TRACE_FIRST_CHILD F_TRACE_FLAG(9)
+#define F_TRACE_SCHED F_TRACE_FLAG(10)
+#define F_TRACE_GC F_TRACE_FLAG(11)
+#define F_TRACE_ARITY_ONLY F_TRACE_FLAG(12)
+#define F_TRACE_RETURN_TO F_TRACE_FLAG(13) /* Return_to trace when breakpoint tracing */
+#define F_TRACE_SILENT F_TRACE_FLAG(14) /* No call trace msg suppress */
+#define F_TRACER F_TRACE_FLAG(15) /* May be (has been) tracer */
+#define F_EXCEPTION_TRACE F_TRACE_FLAG(16) /* May have exception trace on stack */
/* port trace flags, currently the same as process trace flags */
-#define F_TRACE_SCHED_PORTS (1 << 18) /* Trace of port scheduling */
-#define F_TRACE_SCHED_PROCS (1 << 19) /* With virtual scheduling */
-#define F_TRACE_PORTS (1 << 20) /* Ports equivalent to F_TRACE_PROCS */
-#define F_TRACE_SCHED_NO (1 << 21) /* Trace with scheduler id */
-#define F_TRACE_SCHED_EXIT (1 << 22)
+#define F_TRACE_SCHED_PORTS F_TRACE_FLAG(17) /* Trace of port scheduling */
+#define F_TRACE_SCHED_PROCS F_TRACE_FLAG(18) /* With virtual scheduling */
+#define F_TRACE_PORTS F_TRACE_FLAG(19) /* Ports equivalent to F_TRACE_PROCS */
+#define F_TRACE_SCHED_NO F_TRACE_FLAG(20) /* Trace with scheduler id */
+#define F_TRACE_SCHED_EXIT F_TRACE_FLAG(21)
-#define F_NUM_FLAGS 23
+#define F_NUM_FLAGS (ERTS_TRACE_TS_TYPE_BITS + 22)
#ifdef DEBUG
# define F_INITIAL_TRACE_FLAGS (5 << F_NUM_FLAGS)
#else
# define F_INITIAL_TRACE_FLAGS 0
#endif
-
+/* F_TIMESTAMP_MASK is a bit-field of all all timestamp types */
+#define F_TIMESTAMP_MASK \
+ (ERTS_TRACE_TS_TYPE_MASK << ERTS_TRACE_FLAGS_TS_TYPE_SHIFT)
#define TRACEE_FLAGS ( F_TRACE_PROCS | F_TRACE_CALLS \
| F_TRACE_SOS | F_TRACE_SOS1| F_TRACE_RECEIVE \
| F_TRACE_SOL | F_TRACE_SOL1 | F_TRACE_SEND \
- | F_TRACE_SCHED | F_TIMESTAMP | F_TRACE_GC \
+ | F_TRACE_SCHED | F_TIMESTAMP_MASK | F_TRACE_GC \
| F_TRACE_ARITY_ONLY | F_TRACE_RETURN_TO \
| F_TRACE_SILENT | F_TRACE_SCHED_PROCS | F_TRACE_PORTS \
| F_TRACE_SCHED_PORTS | F_TRACE_SCHED_NO \
| F_TRACE_SCHED_EXIT)
#define ERTS_TRACEE_MODIFIER_FLAGS \
- (F_TRACE_SILENT | F_TIMESTAMP | F_TRACE_SCHED_NO)
+ (F_TRACE_SILENT | F_TIMESTAMP_MASK | F_TRACE_SCHED_NO)
#define ERTS_PORT_TRACEE_FLAGS \
(ERTS_TRACEE_MODIFIER_FLAGS | F_TRACE_PORTS | F_TRACE_SCHED_PORTS)
#define ERTS_PROC_TRACEE_FLAGS \
((TRACEE_FLAGS & ~ERTS_PORT_TRACEE_FLAGS) | ERTS_TRACEE_MODIFIER_FLAGS)
+#define SEQ_TRACE_FLAG(N) (1 << (ERTS_TRACE_TS_TYPE_BITS + (N)))
+
/* Sequential trace flags */
+
+/* SEQ_TRACE_TIMESTAMP_MASK is a bit-field */
+#define SEQ_TRACE_TIMESTAMP_MASK \
+ (ERTS_TRACE_TS_TYPE_MASK << ERTS_SEQ_TRACE_FLAGS_TS_TYPE_SHIFT)
+
#define SEQ_TRACE_SEND (1 << 0)
#define SEQ_TRACE_RECEIVE (1 << 1)
#define SEQ_TRACE_PRINT (1 << 2)
-#define SEQ_TRACE_TIMESTAMP (1 << 3)
+
+#define ERTS_SEQ_TRACE_FLAGS_TS_TYPE_SHIFT 3
+
+#define SEQ_TRACE_NOW_TS (ERTS_TRACE_FLG_NOW_TIMESTAMP \
+ << ERTS_SEQ_TRACE_FLAGS_TS_TYPE_SHIFT)
+#define SEQ_TRACE_STRICT_MON_TS (ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP \
+ << ERTS_SEQ_TRACE_FLAGS_TS_TYPE_SHIFT)
+#define SEQ_TRACE_MON_TS (ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP \
+ << ERTS_SEQ_TRACE_FLAGS_TS_TYPE_SHIFT)
#ifdef USE_VM_PROBES
#define DT_UTAG_PERMANENT (1 << 0)
@@ -1277,12 +1407,14 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;
#define ERTS_XSIG_FLG_IGN_KILL (((Uint32) 1) << 0)
#define ERTS_XSIG_FLG_NO_IGN_NORMAL (((Uint32) 1) << 1)
-#define CANCEL_TIMER(p) \
- do { \
- if ((p)->flags & (F_INSLPQUEUE)) \
- cancel_timer(p); \
- else \
- (p)->flags &= ~F_TIMO; \
+#define CANCEL_TIMER(P) \
+ do { \
+ if ((P)->flags & (F_INSLPQUEUE|F_TIMO)) { \
+ if ((P)->flags & F_INSLPQUEUE) \
+ erts_cancel_proc_timer((P)); \
+ else \
+ (P)->flags &= ~F_TIMO; \
+ } \
} while (0)
#if defined(ERTS_DIRTY_SCHEDULERS) && defined(ERTS_SMP)
@@ -1351,6 +1483,7 @@ void erts_init_scheduling(int, int
int erts_set_gc_state(Process *c_p, int enable);
Eterm erts_sched_wall_time_request(Process *c_p, int set, int enable);
+Eterm erts_system_check_request(Process *c_p);
Eterm erts_gc_info_request(Process *c_p);
Uint64 erts_get_proc_interval(void);
Uint64 erts_ensure_later_proc_interval(Uint64);
@@ -1569,6 +1702,9 @@ Eterm erts_multi_scheduling_blockers(Process *);
void erts_start_schedulers(void);
void erts_alloc_notify_delayed_dealloc(int);
void erts_alloc_ensure_handle_delayed_dealloc_call(int);
+#ifdef ERTS_SMP
+void erts_notify_canceled_timer(ErtsSchedulerData *, int);
+#endif
void erts_smp_notify_check_children_needed(void);
#endif
#if ERTS_USE_ASYNC_READY_Q
@@ -1590,7 +1726,7 @@ void erts_sched_notify_check_cpu_bind(void);
Uint erts_active_schedulers(void);
void erts_init_process(int, int, int);
Eterm erts_process_status(Process *, ErtsProcLocks, Process *, Eterm);
-Uint erts_run_queues_len(Uint *);
+Uint erts_run_queues_len(Uint *, int, int);
void erts_add_to_runq(Process *);
Eterm erts_bound_schedulers_term(Process *c_p);
Eterm erts_get_cpu_topology_term(Process *c_p, Eterm which);
@@ -1603,8 +1739,6 @@ void erts_schedule_misc_op(void (*)(void *), void *);
Eterm erl_create_process(Process*, Eterm, Eterm, Eterm, ErlSpawnOpts*);
void erts_do_exit_process(Process*, Eterm);
void erts_continue_exit_process(Process *);
-void set_timer(Process*, Uint);
-void cancel_timer(Process*);
/* Begin System profile */
Uint erts_runnable_process_count(void);
/* End System profile */
@@ -1614,7 +1748,11 @@ void erts_cleanup_empty_process(Process* p);
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);
Eterm erts_get_process_priority(Process *p);
Eterm erts_set_process_priority(Process *p, Eterm prio);
@@ -1656,7 +1794,11 @@ Eterm erts_get_reader_groups_map(Process *c_p);
Eterm erts_debug_reader_groups_map(Process *c_p, int groups);
Uint erts_debug_nbalance(void);
-int erts_debug_wait_deallocations(Process *c_p);
+
+#define ERTS_DEBUG_WAIT_COMPLETED_DEALLOCATIONS (1 << 0)
+#define ERTS_DEBUG_WAIT_COMPLETED_TIMER_CANCELLATIONS (1 << 1)
+
+int erts_debug_wait_completed(Process *c_p, int flags);
Uint erts_process_memory(Process *c_p);
@@ -1789,11 +1931,6 @@ erts_psd_set(Process *p, ErtsProcLocks plocks, int ix, void *data)
#define ERTS_PROC_SCHED_ID(P, L, ID) \
((UWord) erts_psd_set((P), (L), ERTS_PSD_SCHED_ID, (void *) (ID)))
-#define ERTS_PROC_GET_DIST_ENTRY(P) \
- ((DistEntry *) erts_psd_get((P), ERTS_PSD_DIST_ENTRY))
-#define ERTS_PROC_SET_DIST_ENTRY(P, L, D) \
- ((DistEntry *) erts_psd_set((P), (L), ERTS_PSD_DIST_ENTRY, (void *) (D)))
-
#define ERTS_PROC_GET_SAVED_CALLS_BUF(P) \
((struct saved_calls *) erts_psd_get((P), ERTS_PSD_SAVED_CALLS_BUF))
#define ERTS_PROC_SET_SAVED_CALLS_BUF(P, L, SCB) \
@@ -1965,14 +2102,10 @@ ERTS_GLB_INLINE Eterm erts_get_current_pid(void);
ERTS_GLB_INLINE Uint erts_get_scheduler_id(void);
ERTS_GLB_INLINE ErtsRunQueue *erts_get_runq_proc(Process *p);
ERTS_GLB_INLINE ErtsRunQueue *erts_get_runq_current(ErtsSchedulerData *esdp);
-#ifndef ERTS_ENABLE_LOCK_COUNT
ERTS_GLB_INLINE void erts_smp_runq_lock(ErtsRunQueue *rq);
-#endif
ERTS_GLB_INLINE int erts_smp_runq_trylock(ErtsRunQueue *rq);
ERTS_GLB_INLINE void erts_smp_runq_unlock(ErtsRunQueue *rq);
-#ifndef ERTS_ENABLE_LOCK_COUNT
ERTS_GLB_INLINE void erts_smp_xrunq_lock(ErtsRunQueue *rq, ErtsRunQueue *xrq);
-#endif
ERTS_GLB_INLINE void erts_smp_xrunq_unlock(ErtsRunQueue *rq, ErtsRunQueue *xrq);
ERTS_GLB_INLINE void erts_smp_runqs_lock(ErtsRunQueue *rq1, ErtsRunQueue *rq2);
ERTS_GLB_INLINE void erts_smp_runqs_unlock(ErtsRunQueue *rq1, ErtsRunQueue *rq2);
@@ -2050,12 +2183,6 @@ erts_smp_runq_lock(ErtsRunQueue *rq)
#endif
}
-#ifdef ERTS_ENABLE_LOCK_COUNT
-
-#define erts_smp_runq_lock(rq) erts_smp_mtx_lock_x(&(rq)->mtx, __FILE__, __LINE__)
-
-#endif
-
ERTS_GLB_INLINE int
erts_smp_runq_trylock(ErtsRunQueue *rq)
{
@@ -2074,31 +2201,6 @@ erts_smp_runq_unlock(ErtsRunQueue *rq)
#endif
}
-#ifdef ERTS_ENABLE_LOCK_COUNT
-
-#define erts_smp_xrunq_lock(rq, xrq) erts_smp_xrunq_lock_x((rq), (xrq), __FILE__, __LINE__)
-
-ERTS_GLB_INLINE void
-erts_smp_xrunq_lock_x(ErtsRunQueue *rq, ErtsRunQueue *xrq, char* file, int line)
-{
-#ifdef ERTS_SMP
- ERTS_SMP_LC_ASSERT(erts_smp_lc_mtx_is_locked(&rq->mtx));
- if (xrq != rq) {
- if (erts_smp_mtx_trylock(&xrq->mtx) == EBUSY) {
- if (rq < xrq)
- erts_smp_mtx_lock_x(&xrq->mtx, file, line);
- else {
- erts_smp_mtx_unlock(&rq->mtx);
- erts_smp_mtx_lock_x(&xrq->mtx, file, line);
- erts_smp_mtx_lock_x(&rq->mtx, file, line);
- }
- }
- }
-#endif
-}
-
-#else
-
ERTS_GLB_INLINE void
erts_smp_xrunq_lock(ErtsRunQueue *rq, ErtsRunQueue *xrq)
{
@@ -2118,8 +2220,6 @@ erts_smp_xrunq_lock(ErtsRunQueue *rq, ErtsRunQueue *xrq)
#endif
}
-#endif
-
ERTS_GLB_INLINE void
erts_smp_xrunq_unlock(ErtsRunQueue *rq, ErtsRunQueue *xrq)
{
@@ -2219,6 +2319,8 @@ extern int erts_disable_proc_not_running_opt;
void erts_smp_notify_inc_runq(ErtsRunQueue *runq);
+void erts_interupt_aux_thread_timed(ErtsMonotonicTime timeout_time);
+
#ifdef ERTS_SMP
void erts_sched_finish_poke(ErtsSchedulerSleepInfo *, erts_aint32_t);
ERTS_GLB_INLINE void erts_sched_poke(ErtsSchedulerSleepInfo *ssi);
@@ -2249,6 +2351,6 @@ erts_sched_poke(ErtsSchedulerSleepInfo *ssi)
#endif
-void erl_halt(int code);
+void erts_halt(int code);
extern erts_smp_atomic32_t erts_halt_progress;
extern int erts_halt_code;
diff --git a/erts/emulator/beam/erl_process_dict.c b/erts/emulator/beam/erl_process_dict.c
index af20b26b15..3253ee6b70 100644
--- a/erts/emulator/beam/erl_process_dict.c
+++ b/erts/emulator/beam/erl_process_dict.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -82,6 +83,7 @@
static void pd_hash_erase(Process *p, Eterm id, Eterm *ret);
static void pd_hash_erase_all(Process *p);
static Eterm pd_hash_get_keys(Process *p, Eterm value);
+static Eterm pd_hash_get_all_keys(Process *p, ProcDict *pd);
static Eterm pd_hash_get_all(Process *p, ProcDict *pd);
static Eterm pd_hash_put(Process *p, Eterm id, Eterm value);
@@ -275,6 +277,16 @@ BIF_RETTYPE get_1(BIF_ALIST_1)
BIF_RET(ret);
}
+BIF_RETTYPE get_keys_0(BIF_ALIST_0)
+{
+ Eterm ret;
+
+ PD_CHECK(BIF_P->dictionary);
+ ret = pd_hash_get_all_keys(BIF_P,BIF_P->dictionary);
+ PD_CHECK(BIF_P->dictionary);
+ BIF_RET(ret);
+}
+
BIF_RETTYPE get_keys_1(BIF_ALIST_1)
{
Eterm ret;
@@ -362,7 +374,7 @@ static void pd_hash_erase(Process *p, Eterm id, Eterm *ret)
"display term found in line %d:\n"
"%T\n", p->common.id, __LINE__, old);
#endif
- erl_exit(1, "Damaged process dictionary found during erase/1.");
+ erts_exit(ERTS_ERROR_EXIT, "Damaged process dictionary found during erase/1.");
}
if ((range = HASH_RANGE(p->dictionary)) > INITIAL_SIZE &&
range / 2 > (p->dictionary->numElements)) {
@@ -407,11 +419,52 @@ Eterm erts_pd_hash_get(Process *p, Eterm id)
"display term found in line %d:\n"
"%T\n", p->common.id, __LINE__, tmp);
#endif
- erl_exit(1, "Damaged process dictionary found during get/1.");
+ erts_exit(ERTS_ERROR_EXIT, "Damaged process dictionary found during get/1.");
}
return am_undefined;
}
+#define PD_GET_TKEY(Dst,Src) \
+do { \
+ ASSERT(is_tuple((Src))); \
+ ASSERT(arityval(*((Eterm*)tuple_val((Src)))) == 2); \
+ (Dst) = ((Eterm*)tuple_val((Src)))[1]; \
+} while(0)
+
+static Eterm pd_hash_get_all_keys(Process *p, ProcDict *pd) {
+ Eterm* hp;
+ Eterm res = NIL;
+ Eterm tmp, tmp2;
+ unsigned int i;
+ unsigned int num;
+
+ if (pd == NULL) {
+ return res;
+ }
+
+ num = HASH_RANGE(pd);
+ hp = HAlloc(p, pd->numElements * 2);
+
+ for (i = 0; i < num; ++i) {
+ tmp = ARRAY_GET(pd, i);
+ if (is_boxed(tmp)) {
+ PD_GET_TKEY(tmp,tmp);
+ res = CONS(hp, tmp, res);
+ hp += 2;
+ } else if (is_list(tmp)) {
+ while (tmp != NIL) {
+ tmp2 = TCAR(tmp);
+ PD_GET_TKEY(tmp2,tmp2);
+ res = CONS(hp, tmp2, res);
+ hp += 2;
+ tmp = TCDR(tmp);
+ }
+ }
+ }
+ return res;
+}
+#undef PD_GET_TKEY
+
static Eterm pd_hash_get_keys(Process *p, Eterm value)
{
Eterm *hp;
@@ -617,7 +670,7 @@ static Eterm pd_hash_put(Process *p, Eterm id, Eterm value)
"%T\n", p->common.id, __LINE__, old);
#endif
- erl_exit(1, "Damaged process dictionary found during put/2.");
+ erts_exit(ERTS_ERROR_EXIT, "Damaged process dictionary found during put/2.");
}
if (HASH_RANGE(p->dictionary) <= p->dictionary->numElements) {
grow(p);
@@ -971,7 +1024,7 @@ static void pd_check(ProcDict *pd)
}
continue;
} else {
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"Found tag 0x%08x in process dictionary at position %d",
(unsigned long) t, (int) i);
}
diff --git a/erts/emulator/beam/erl_process_dict.h b/erts/emulator/beam/erl_process_dict.h
index 8fad2a67ab..cc53800eb5 100644
--- a/erts/emulator/beam/erl_process_dict.h
+++ b/erts/emulator/beam/erl_process_dict.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index 2f3cf23b00..25f0b1ed38 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -43,8 +44,9 @@ 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, Process* p, Eterm* sp,
+static int stack_element_dump(int 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);
@@ -148,7 +150,7 @@ dump_process_info(int to, void *to_arg, Process *p)
if ((ERTS_TRACE_FLAGS(p) & F_SENSITIVE) == 0) {
erts_print(to, to_arg, "=proc_stack:%T\n", p->common.id);
for (sp = p->stop; sp < STACK_START(p); sp++) {
- yreg = stack_element_dump(to, to_arg, p, sp, yreg);
+ yreg = stack_element_dump(to, to_arg, sp, yreg);
}
erts_print(to, to_arg, "=proc_heap:%T\n", p->common.id);
@@ -243,9 +245,65 @@ dump_element_nl(int to, void *to_arg, Eterm x)
erts_putc(to, to_arg, '\n');
}
+static void
+stack_trace_dump(int to, void *to_arg, Eterm *sp) {
+ Eterm x = *sp;
+ if (is_CP(x)) {
+ erts_print(to, to_arg, "%p:", sp);
+ erts_print(to, to_arg, "SReturn addr 0x%X (", cp_val(x));
+ print_function_from_pc(to, to_arg, cp_val(x));
+ erts_print(to, to_arg, ")\n");
+ }
+}
+
+void
+erts_limited_stack_trace(int to, void *to_arg, Process *p)
+{
+ Eterm* sp;
+
+
+ if (ERTS_TRACE_FLAGS(p) & F_SENSITIVE) {
+ return;
+ }
+
+ if (STACK_START(p) < STACK_TOP(p)) {
+ return;
+ }
+
+ if ((STACK_START(p) - STACK_TOP(p)) < 512) {
+ if (erts_sys_is_area_readable((char*)STACK_TOP(p),
+ (char*)STACK_START(p)))
+ for (sp = STACK_TOP(p); sp < STACK_START(p); sp++)
+ stack_trace_dump(to, to_arg, sp);
+ else
+ erts_print(to, to_arg, "Could not read from stack memory: %p - %p\n",
+ STACK_TOP(p), STACK_START(p));
+ } else {
+ sp = STACK_TOP(p);
+ if (erts_sys_is_area_readable((char*)STACK_TOP(p),
+ (char*)(STACK_TOP(p) + 25)))
+ for (; sp < (STACK_TOP(p) + 256); sp++)
+ stack_trace_dump(to, to_arg, sp);
+ else
+ erts_print(to, to_arg, "Could not read from stack memory: %p - %p\n",
+ STACK_TOP(p), STACK_TOP(p) + 256);
+
+ erts_print(to, to_arg, "%p: skipping %d frames\n",
+ sp, STACK_START(p) - STACK_TOP(p) - 512);
+
+ if (erts_sys_is_area_readable((char*)(STACK_START(p) - 256),
+ (char*)STACK_START(p)))
+ for (sp = STACK_START(p) - 256; sp < STACK_START(p); sp++)
+ stack_trace_dump(to, to_arg, sp);
+ else
+ erts_print(to, to_arg, "Could not read from stack memory: %p - %p\n",
+ STACK_START(p) - 256, STACK_START(p));
+ }
+
+}
static int
-stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
+stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg)
{
Eterm x = *sp;
@@ -508,3 +566,114 @@ dump_externally(int to, void *to_arg, Eterm term)
erts_print(to, to_arg, "%02X", *s++);
}
}
+
+void erts_dump_process_state(int to, void *to_arg, erts_aint32_t psflg) {
+ if (psflg & ERTS_PSFLG_FREE)
+ erts_print(to, to_arg, "Non Existing\n"); /* Should never happen */
+ else if (psflg & ERTS_PSFLG_EXITING)
+ erts_print(to, to_arg, "Exiting\n");
+ else if (psflg & ERTS_PSFLG_GC) {
+ erts_print(to, to_arg, "Garbing\n");
+ }
+ else if (psflg & ERTS_PSFLG_SUSPENDED)
+ erts_print(to, to_arg, "Suspended\n");
+ else if (psflg & ERTS_PSFLG_RUNNING) {
+ erts_print(to, to_arg, "Running\n");
+ }
+ else if (psflg & ERTS_PSFLG_ACTIVE)
+ erts_print(to, to_arg, "Scheduled\n");
+ else
+ erts_print(to, to_arg, "Waiting\n");
+}
+
+void
+erts_dump_extended_process_state(int to, void *to_arg, erts_aint32_t psflg) {
+
+ int i;
+
+ switch (ERTS_PSFLGS_GET_ACT_PRIO(psflg)) {
+ case PRIORITY_MAX: erts_print(to, to_arg, "ACT_PRIO_MAX | "); break;
+ case PRIORITY_HIGH: erts_print(to, to_arg, "ACT_PRIO_HIGH | "); break;
+ case PRIORITY_NORMAL: erts_print(to, to_arg, "ACT_PRIO_NORMAL | "); break;
+ case PRIORITY_LOW: erts_print(to, to_arg, "ACT_PRIO_LOW | "); break;
+ }
+ switch (ERTS_PSFLGS_GET_USR_PRIO(psflg)) {
+ case PRIORITY_MAX: erts_print(to, to_arg, "USR_PRIO_MAX | "); break;
+ case PRIORITY_HIGH: erts_print(to, to_arg, "USR_PRIO_HIGH | "); break;
+ case PRIORITY_NORMAL: erts_print(to, to_arg, "USR_PRIO_NORMAL | "); break;
+ case PRIORITY_LOW: erts_print(to, to_arg, "USR_PRIO_LOW | "); break;
+ }
+ switch (ERTS_PSFLGS_GET_PRQ_PRIO(psflg)) {
+ case PRIORITY_MAX: erts_print(to, to_arg, "PRQ_PRIO_MAX"); break;
+ case PRIORITY_HIGH: erts_print(to, to_arg, "PRQ_PRIO_HIGH"); break;
+ case PRIORITY_NORMAL: erts_print(to, to_arg, "PRQ_PRIO_NORMAL"); break;
+ case PRIORITY_LOW: erts_print(to, to_arg, "PRQ_PRIO_LOW"); break;
+ }
+
+ psflg &= ~(ERTS_PSFLGS_ACT_PRIO_MASK |
+ ERTS_PSFLGS_USR_PRIO_MASK |
+ ERTS_PSFLGS_PRQ_PRIO_MASK);
+
+ if (psflg)
+ erts_print(to, to_arg, " | ");
+
+ for (i = 0; i < ERTS_PSFLG_MAX && psflg; i++) {
+ erts_aint32_t chk = (1 << i);
+ if (psflg & chk) {
+ switch (chk) {
+ case ERTS_PSFLG_IN_PRQ_MAX:
+ erts_print(to, to_arg, "IN_PRQ_MAX"); break;
+ case ERTS_PSFLG_IN_PRQ_HIGH:
+ erts_print(to, to_arg, "IN_PRQ_HIGH"); break;
+ case ERTS_PSFLG_IN_PRQ_NORMAL:
+ erts_print(to, to_arg, "IN_PRQ_NORMAL"); break;
+ case ERTS_PSFLG_IN_PRQ_LOW:
+ erts_print(to, to_arg, "IN_PRQ_LOW"); break;
+ case ERTS_PSFLG_FREE:
+ erts_print(to, to_arg, "FREE"); break;
+ case ERTS_PSFLG_EXITING:
+ erts_print(to, to_arg, "EXITING"); break;
+ case ERTS_PSFLG_PENDING_EXIT:
+ erts_print(to, to_arg, "PENDING_EXIT"); break;
+ case ERTS_PSFLG_ACTIVE:
+ erts_print(to, to_arg, "ACTIVE"); break;
+ case ERTS_PSFLG_IN_RUNQ:
+ erts_print(to, to_arg, "IN_RUNQ"); break;
+ case ERTS_PSFLG_RUNNING:
+ erts_print(to, to_arg, "RUNNING"); break;
+ case ERTS_PSFLG_SUSPENDED:
+ erts_print(to, to_arg, "SUSPENDED"); break;
+ case ERTS_PSFLG_GC:
+ erts_print(to, to_arg, "GC"); break;
+ case ERTS_PSFLG_BOUND:
+ erts_print(to, to_arg, "BOUND"); break;
+ case ERTS_PSFLG_TRAP_EXIT:
+ erts_print(to, to_arg, "TRAP_EXIT"); break;
+ case ERTS_PSFLG_ACTIVE_SYS:
+ erts_print(to, to_arg, "ACTIVE_SYS"); break;
+ case ERTS_PSFLG_RUNNING_SYS:
+ erts_print(to, to_arg, "RUNNING_SYS"); break;
+ case ERTS_PSFLG_PROXY:
+ erts_print(to, to_arg, "PROXY"); break;
+ case ERTS_PSFLG_DELAYED_SYS:
+ erts_print(to, to_arg, "DELAYED_SYS"); break;
+#ifdef ERTS_DIRTY_SCHEDULERS
+ case ERTS_PSFLG_DIRTY_CPU_PROC:
+ erts_print(to, to_arg, "DIRTY_CPU_PROC"); break;
+ case ERTS_PSFLG_DIRTY_IO_PROC:
+ erts_print(to, to_arg, "DIRTY_IO_PROC"); break;
+ case ERTS_PSFLG_DIRTY_CPU_PROC_IN_Q:
+ erts_print(to, to_arg, "DIRTY_CPU_PROC_IN_Q"); break;
+ case ERTS_PSFLG_DIRTY_IO_PROC_IN_Q:
+ erts_print(to, to_arg, "DIRTY_IO_PROC_IN_Q"); break;
+#endif
+ default:
+ erts_print(to, to_arg, "UNKNOWN(%d)", chk); break;
+ }
+ if (psflg > chk)
+ erts_print(to, to_arg, " | ");
+ psflg -= chk;
+ }
+ }
+ erts_print(to, to_arg, "\n");
+}
diff --git a/erts/emulator/beam/erl_process_lock.c b/erts/emulator/beam/erl_process_lock.c
index 82cc68222d..0bee2c848c 100644
--- a/erts/emulator/beam/erl_process_lock.c
+++ b/erts/emulator/beam/erl_process_lock.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -103,12 +104,16 @@ static struct {
Sint16 proc_lock_main;
Sint16 proc_lock_link;
Sint16 proc_lock_msgq;
+ Sint16 proc_lock_btm;
Sint16 proc_lock_status;
} lc_id;
#endif
erts_pix_lock_t erts_pix_locks[ERTS_NO_OF_PIX_LOCKS];
+#ifdef ERTS_ENABLE_LOCK_COUNT
+static void lcnt_enable_proc_lock_count(Process *proc, int enable);
+#endif
void
erts_init_proc_lock(int cpus)
@@ -145,6 +150,7 @@ erts_init_proc_lock(int cpus)
lc_id.proc_lock_main = erts_lc_get_lock_order_id("proc_main");
lc_id.proc_lock_link = erts_lc_get_lock_order_id("proc_link");
lc_id.proc_lock_msgq = erts_lc_get_lock_order_id("proc_msgq");
+ lc_id.proc_lock_btm = erts_lc_get_lock_order_id("proc_btm");
lc_id.proc_lock_status = erts_lc_get_lock_order_id("proc_status");
#endif
}
@@ -707,7 +713,7 @@ proc_safelock(int is_managed,
need_locks1 |= unlock_locks;
if (!is_managed && !have_locks1) {
refc1 = 1;
- erts_smp_proc_inc_refc(p1);
+ erts_proc_inc_refc(p1);
}
erts_smp_proc_unlock(p1, unlock_locks);
}
@@ -717,7 +723,7 @@ proc_safelock(int is_managed,
need_locks2 |= unlock_locks;
if (!is_managed && !have_locks2) {
refc2 = 1;
- erts_smp_proc_inc_refc(p2);
+ erts_proc_inc_refc(p2);
}
erts_smp_proc_unlock(p2, unlock_locks);
}
@@ -798,9 +804,9 @@ proc_safelock(int is_managed,
if (!is_managed) {
if (refc1)
- erts_smp_proc_dec_refc(p1);
+ erts_proc_dec_refc(p1);
if (refc2)
- erts_smp_proc_dec_refc(p2);
+ erts_proc_dec_refc(p2);
}
}
@@ -861,8 +867,8 @@ erts_pid2proc_opt(Process *c_p,
return NULL;
need_locks &= ~c_p_have_locks;
if (!need_locks) {
- if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
- erts_smp_proc_inc_refc(c_p);
+ if (flags & ERTS_P2P_FLG_INC_REFC)
+ erts_proc_inc_refc(c_p);
return c_p;
}
}
@@ -875,8 +881,8 @@ erts_pid2proc_opt(Process *c_p,
if (proc->common.id != pid)
proc = NULL;
else if (!need_locks) {
- if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
- erts_smp_proc_inc_refc(proc);
+ if (flags & ERTS_P2P_FLG_INC_REFC)
+ erts_proc_inc_refc(proc);
}
else {
int busy;
@@ -916,8 +922,8 @@ erts_pid2proc_opt(Process *c_p,
#endif
if (!busy) {
- if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
- erts_smp_proc_inc_refc(proc);
+ if (flags & ERTS_P2P_FLG_INC_REFC)
+ erts_proc_inc_refc(proc);
#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
/* all is great */
@@ -932,8 +938,8 @@ erts_pid2proc_opt(Process *c_p,
proc = ERTS_PROC_LOCK_BUSY;
else {
int managed;
- if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
- erts_smp_proc_inc_refc(proc);
+ if (flags & ERTS_P2P_FLG_INC_REFC)
+ erts_proc_inc_refc(proc);
#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
erts_lcnt_proc_lock_unaquire(&proc->lock, lcnt_locks);
@@ -941,7 +947,7 @@ erts_pid2proc_opt(Process *c_p,
managed = dhndl == ERTS_THR_PRGR_DHANDLE_MANAGED;
if (!managed) {
- erts_smp_proc_inc_refc(proc);
+ erts_proc_inc_refc(proc);
erts_thr_progress_unmanaged_continue(dhndl);
dec_refc_proc = proc;
@@ -978,14 +984,14 @@ erts_pid2proc_opt(Process *c_p,
erts_smp_proc_unlock(proc, need_locks);
- if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
+ if (flags & ERTS_P2P_FLG_INC_REFC)
dec_refc_proc = proc;
proc = NULL;
}
if (dec_refc_proc)
- erts_smp_proc_dec_refc(dec_refc_proc);
+ erts_proc_dec_refc(dec_refc_proc);
#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_PROC_LOCK_DEBUG)
ERTS_LC_ASSERT(!proc
@@ -1001,7 +1007,9 @@ erts_pid2proc_opt(Process *c_p,
void
erts_proc_lock_init(Process *p)
{
+#if ERTS_PROC_LOCK_OWN_IMPL || defined(ERTS_PROC_LOCK_DEBUG)
int i;
+#endif
#if ERTS_PROC_LOCK_OWN_IMPL
/* We always start with all locks locked */
#if ERTS_PROC_LOCK_ATOMIC_IMPL
@@ -1038,6 +1046,11 @@ erts_proc_lock_init(Process *p)
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_lc_trylock(1, &p->lock.msgq.lc);
#endif
+ erts_mtx_init_x(&p->lock.btm, "proc_btm", p->common.id, do_lock_count);
+ ethr_mutex_lock(&p->lock.btm.mtx);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_trylock(1, &p->lock.btm.lc);
+#endif
erts_mtx_init_x(&p->lock.status, "proc_status", p->common.id,
do_lock_count);
ethr_mutex_lock(&p->lock.status.mtx);
@@ -1045,7 +1058,6 @@ erts_proc_lock_init(Process *p)
erts_lc_trylock(1, &p->lock.status.lc);
#endif
#endif
- erts_atomic32_init_nob(&p->lock.refc, 1);
#ifdef ERTS_PROC_LOCK_DEBUG
for (i = 0; i <= ERTS_PROC_LOCK_MAX_BIT; i++)
erts_smp_atomic32_init_nob(&p->lock.locked[i], (erts_aint32_t) 1);
@@ -1064,6 +1076,7 @@ erts_proc_lock_fin(Process *p)
erts_mtx_destroy(&p->lock.main);
erts_mtx_destroy(&p->lock.link);
erts_mtx_destroy(&p->lock.msgq);
+ erts_mtx_destroy(&p->lock.btm);
erts_mtx_destroy(&p->lock.status);
#endif
#if defined(ERTS_ENABLE_LOCK_COUNT) && defined(ERTS_SMP)
@@ -1074,141 +1087,109 @@ erts_proc_lock_fin(Process *p)
/* --- Process lock counting ----------------------------------------------- */
#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
-void erts_lcnt_proc_lock_init(Process *p) {
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
- if (p->common.id != ERTS_INVALID_PID) {
- erts_lcnt_init_lock_x(&(p->lock.lcnt_main), "proc_main", ERTS_LCNT_LT_PROCLOCK, p->common.id);
- erts_lcnt_init_lock_x(&(p->lock.lcnt_msgq), "proc_msgq", ERTS_LCNT_LT_PROCLOCK, p->common.id);
- erts_lcnt_init_lock_x(&(p->lock.lcnt_link), "proc_link", ERTS_LCNT_LT_PROCLOCK, p->common.id);
- erts_lcnt_init_lock_x(&(p->lock.lcnt_status), "proc_status", ERTS_LCNT_LT_PROCLOCK, p->common.id);
- } else {
- erts_lcnt_init_lock(&(p->lock.lcnt_main), "proc_main", ERTS_LCNT_LT_PROCLOCK);
- erts_lcnt_init_lock(&(p->lock.lcnt_msgq), "proc_msgq", ERTS_LCNT_LT_PROCLOCK);
- erts_lcnt_init_lock(&(p->lock.lcnt_link), "proc_link", ERTS_LCNT_LT_PROCLOCK);
- erts_lcnt_init_lock(&(p->lock.lcnt_status), "proc_status", ERTS_LCNT_LT_PROCLOCK);
- }
- } else {
- sys_memzero(&(p->lock.lcnt_main), sizeof(p->lock.lcnt_main));
- sys_memzero(&(p->lock.lcnt_msgq), sizeof(p->lock.lcnt_msgq));
- sys_memzero(&(p->lock.lcnt_link), sizeof(p->lock.lcnt_link));
- sys_memzero(&(p->lock.lcnt_status), sizeof(p->lock.lcnt_status));
- }
+
+void erts_lcnt_enable_proc_lock_count(int enable) {
+ int ix, max = erts_ptab_max(&erts_proc);
+ Process *proc = NULL;
+ for (ix = 0; ix < max; ++ix) {
+ if ((proc = erts_pix2proc(ix)) != NULL)
+ lcnt_enable_proc_lock_count(proc, enable);
+ } /* for all processes */
}
-
+
+void erts_lcnt_proc_lock_init(Process *p) {
+ if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK)) {
+ erts_lcnt_init_lock_empty(&(p->lock.lcnt_main));
+ erts_lcnt_init_lock_empty(&(p->lock.lcnt_msgq));
+ erts_lcnt_init_lock_empty(&(p->lock.lcnt_btm));
+ erts_lcnt_init_lock_empty(&(p->lock.lcnt_link));
+ erts_lcnt_init_lock_empty(&(p->lock.lcnt_status));
+ } else { /* now the common case */
+ Eterm pid = (p->common.id != ERTS_INVALID_PID) ? p->common.id : NIL;
+ erts_lcnt_init_lock_x(&(p->lock.lcnt_main), "proc_main", ERTS_LCNT_LT_PROCLOCK, pid);
+ erts_lcnt_init_lock_x(&(p->lock.lcnt_msgq), "proc_msgq", ERTS_LCNT_LT_PROCLOCK, pid);
+ erts_lcnt_init_lock_x(&(p->lock.lcnt_btm), "proc_btm", ERTS_LCNT_LT_PROCLOCK, pid);
+ erts_lcnt_init_lock_x(&(p->lock.lcnt_link), "proc_link", ERTS_LCNT_LT_PROCLOCK, pid);
+ erts_lcnt_init_lock_x(&(p->lock.lcnt_status),"proc_status",ERTS_LCNT_LT_PROCLOCK, pid);
+ } /* the lock names should really be aligned to four characters */
+} /* logic reversed */
void erts_lcnt_proc_lock_destroy(Process *p) {
erts_lcnt_destroy_lock(&(p->lock.lcnt_main));
erts_lcnt_destroy_lock(&(p->lock.lcnt_msgq));
+ erts_lcnt_destroy_lock(&(p->lock.lcnt_btm));
erts_lcnt_destroy_lock(&(p->lock.lcnt_link));
erts_lcnt_destroy_lock(&(p->lock.lcnt_status));
}
-void erts_lcnt_proc_lock(erts_proc_lock_t *lock, ErtsProcLocks locks) {
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
- if (locks & ERTS_PROC_LOCK_MAIN) {
- erts_lcnt_lock(&(lock->lcnt_main));
- }
- if (locks & ERTS_PROC_LOCK_MSGQ) {
- erts_lcnt_lock(&(lock->lcnt_msgq));
- }
- if (locks & ERTS_PROC_LOCK_LINK) {
- erts_lcnt_lock(&(lock->lcnt_link));
- }
- if (locks & ERTS_PROC_LOCK_STATUS) {
- erts_lcnt_lock(&(lock->lcnt_status));
+static void lcnt_enable_proc_lock_count(Process *proc, int enable) {
+ if (enable) {
+ if (!ERTS_LCNT_LOCK_TYPE(&(proc->lock.lcnt_main))) {
+ erts_lcnt_proc_lock_init(proc);
+ }
}
+ else {
+ if (ERTS_LCNT_LOCK_TYPE(&(proc->lock.lcnt_main))) {
+ erts_lcnt_proc_lock_destroy(proc);
+ }
}
}
-void erts_lcnt_proc_lock_post_x(erts_proc_lock_t *lock, ErtsProcLocks locks, char *file, unsigned int line) {
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
+void erts_lcnt_proc_lock(erts_proc_lock_t *lock, ErtsProcLocks locks) {
+ if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK)) return;
+ if (locks & ERTS_PROC_LOCK_MAIN) { erts_lcnt_lock(&(lock->lcnt_main)); }
+ if (locks & ERTS_PROC_LOCK_MSGQ) { erts_lcnt_lock(&(lock->lcnt_msgq)); }
+ if (locks & ERTS_PROC_LOCK_BTM) { erts_lcnt_lock(&(lock->lcnt_btm)); }
+ if (locks & ERTS_PROC_LOCK_LINK) { erts_lcnt_lock(&(lock->lcnt_link)); }
+ if (locks & ERTS_PROC_LOCK_STATUS) { erts_lcnt_lock(&(lock->lcnt_status)); }
+}
+
+void erts_lcnt_proc_lock_post_x(erts_proc_lock_t *lock, ErtsProcLocks locks,
+ char *file, unsigned int line) {
+ if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK)) return;
if (locks & ERTS_PROC_LOCK_MAIN) {
erts_lcnt_lock_post_x(&(lock->lcnt_main), file, line);
}
if (locks & ERTS_PROC_LOCK_MSGQ) {
erts_lcnt_lock_post_x(&(lock->lcnt_msgq), file, line);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ erts_lcnt_lock_post_x(&(lock->lcnt_btm), file, line);
+ }
if (locks & ERTS_PROC_LOCK_LINK) {
erts_lcnt_lock_post_x(&(lock->lcnt_link), file, line);
}
if (locks & ERTS_PROC_LOCK_STATUS) {
erts_lcnt_lock_post_x(&(lock->lcnt_status), file, line);
}
- }
}
void erts_lcnt_proc_lock_unaquire(erts_proc_lock_t *lock, ErtsProcLocks locks) {
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
- if (locks & ERTS_PROC_LOCK_MAIN) {
- erts_lcnt_lock_unaquire(&(lock->lcnt_main));
- }
- if (locks & ERTS_PROC_LOCK_MSGQ) {
- erts_lcnt_lock_unaquire(&(lock->lcnt_msgq));
- }
- if (locks & ERTS_PROC_LOCK_LINK) {
- erts_lcnt_lock_unaquire(&(lock->lcnt_link));
- }
- if (locks & ERTS_PROC_LOCK_STATUS) {
- erts_lcnt_lock_unaquire(&(lock->lcnt_status));
- }
- }
+ if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK)) return;
+ if (locks & ERTS_PROC_LOCK_MAIN) { erts_lcnt_lock_unaquire(&(lock->lcnt_main)); }
+ if (locks & ERTS_PROC_LOCK_MSGQ) { erts_lcnt_lock_unaquire(&(lock->lcnt_msgq)); }
+ if (locks & ERTS_PROC_LOCK_BTM) { erts_lcnt_lock_unaquire(&(lock->lcnt_btm)); }
+ if (locks & ERTS_PROC_LOCK_LINK) { erts_lcnt_lock_unaquire(&(lock->lcnt_link)); }
+ if (locks & ERTS_PROC_LOCK_STATUS) { erts_lcnt_lock_unaquire(&(lock->lcnt_status)); }
}
void erts_lcnt_proc_unlock(erts_proc_lock_t *lock, ErtsProcLocks locks) {
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
- if (locks & ERTS_PROC_LOCK_MAIN) {
- erts_lcnt_unlock(&(lock->lcnt_main));
- }
- if (locks & ERTS_PROC_LOCK_MSGQ) {
- erts_lcnt_unlock(&(lock->lcnt_msgq));
- }
- if (locks & ERTS_PROC_LOCK_LINK) {
- erts_lcnt_unlock(&(lock->lcnt_link));
- }
- if (locks & ERTS_PROC_LOCK_STATUS) {
- erts_lcnt_unlock(&(lock->lcnt_status));
- }
- }
+ if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK)) return;
+ if (locks & ERTS_PROC_LOCK_MAIN) { erts_lcnt_unlock(&(lock->lcnt_main)); }
+ if (locks & ERTS_PROC_LOCK_MSGQ) { erts_lcnt_unlock(&(lock->lcnt_msgq)); }
+ if (locks & ERTS_PROC_LOCK_BTM) { erts_lcnt_unlock(&(lock->lcnt_btm)); }
+ if (locks & ERTS_PROC_LOCK_LINK) { erts_lcnt_unlock(&(lock->lcnt_link)); }
+ if (locks & ERTS_PROC_LOCK_STATUS) { erts_lcnt_unlock(&(lock->lcnt_status)); }
}
void erts_lcnt_proc_trylock(erts_proc_lock_t *lock, ErtsProcLocks locks, int res) {
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
- if (locks & ERTS_PROC_LOCK_MAIN) {
- erts_lcnt_trylock(&(lock->lcnt_main), res);
- }
- if (locks & ERTS_PROC_LOCK_MSGQ) {
- erts_lcnt_trylock(&(lock->lcnt_msgq), res);
- }
- if (locks & ERTS_PROC_LOCK_LINK) {
- erts_lcnt_trylock(&(lock->lcnt_link), res);
- }
- if (locks & ERTS_PROC_LOCK_STATUS) {
- erts_lcnt_trylock(&(lock->lcnt_status), res);
- }
- }
-}
-
-
-void erts_lcnt_enable_proc_lock_count(int enable)
-{
- int i, max = erts_ptab_max(&erts_proc);
-
- for (i = 0; i < max; ++i) {
- Process* p = erts_pix2proc(i);
- if (p) {
- if (enable) {
- if (!ERTS_LCNT_LOCK_TYPE(&(p->lock.lcnt_main))) {
- erts_lcnt_proc_lock_init(p);
- }
- } else {
- if (ERTS_LCNT_LOCK_TYPE(&(p->lock.lcnt_main))) {
- erts_lcnt_proc_lock_destroy(p);
- }
- }
- }
- }
-}
-
-#endif /* ifdef ERTS_ENABLE_LOCK_COUNT */
+ if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK)) return;
+ if (locks & ERTS_PROC_LOCK_MAIN) { erts_lcnt_trylock(&(lock->lcnt_main), res); }
+ if (locks & ERTS_PROC_LOCK_MSGQ) { erts_lcnt_trylock(&(lock->lcnt_msgq), res); }
+ if (locks & ERTS_PROC_LOCK_BTM) { erts_lcnt_trylock(&(lock->lcnt_btm), res); }
+ if (locks & ERTS_PROC_LOCK_LINK) { erts_lcnt_trylock(&(lock->lcnt_link), res); }
+ if (locks & ERTS_PROC_LOCK_STATUS) { erts_lcnt_trylock(&(lock->lcnt_status), res); }
+} /* reversed logic */
+#endif /* ERTS_ENABLE_LOCK_COUNT */
/* --- Process lock checking ----------------------------------------------- */
@@ -1235,6 +1216,10 @@ erts_proc_lc_lock(Process *p, ErtsProcLocks locks, char *file, unsigned int line
lck.id = lc_id.proc_lock_msgq;
erts_lc_lock_x(&lck,file,line);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ lck.id = lc_id.proc_lock_btm;
+ erts_lc_lock_x(&lck,file,line);
+ }
if (locks & ERTS_PROC_LOCK_STATUS) {
lck.id = lc_id.proc_lock_status;
erts_lc_lock_x(&lck,file,line);
@@ -1260,6 +1245,10 @@ erts_proc_lc_trylock(Process *p, ErtsProcLocks locks, int locked,
lck.id = lc_id.proc_lock_msgq;
erts_lc_trylock_x(locked, &lck, file, line);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ lck.id = lc_id.proc_lock_btm;
+ erts_lc_trylock_x(locked, &lck, file, line);
+ }
if (locks & ERTS_PROC_LOCK_STATUS) {
lck.id = lc_id.proc_lock_status;
erts_lc_trylock_x(locked, &lck, file, line);
@@ -1276,6 +1265,10 @@ erts_proc_lc_unlock(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_status;
erts_lc_unlock(&lck);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ lck.id = lc_id.proc_lock_btm;
+ erts_lc_unlock(&lck);
+ }
if (locks & ERTS_PROC_LOCK_MSGQ) {
lck.id = lc_id.proc_lock_msgq;
erts_lc_unlock(&lck);
@@ -1303,6 +1296,10 @@ erts_proc_lc_might_unlock(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_status;
erts_lc_might_unlock(&lck);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ lck.id = lc_id.proc_lock_btm;
+ erts_lc_might_unlock(&lck);
+ }
if (locks & ERTS_PROC_LOCK_MSGQ) {
lck.id = lc_id.proc_lock_msgq;
erts_lc_might_unlock(&lck);
@@ -1322,6 +1319,8 @@ erts_proc_lc_might_unlock(Process *p, ErtsProcLocks locks)
erts_lc_might_unlock(&p->lock.link.lc);
if (locks & ERTS_PROC_LOCK_MSGQ)
erts_lc_might_unlock(&p->lock.msgq.lc);
+ if (locks & ERTS_PROC_LOCK_BTM)
+ erts_lc_might_unlock(&p->lock.btm.lc);
if (locks & ERTS_PROC_LOCK_STATUS)
erts_lc_might_unlock(&p->lock.status.lc);
#endif
@@ -1347,6 +1346,10 @@ erts_proc_lc_require_lock(Process *p, ErtsProcLocks locks, char *file,
lck.id = lc_id.proc_lock_msgq;
erts_lc_require_lock(&lck, file, line);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ lck.id = lc_id.proc_lock_btm;
+ erts_lc_require_lock(&lck, file, line);
+ }
if (locks & ERTS_PROC_LOCK_STATUS) {
lck.id = lc_id.proc_lock_status;
erts_lc_require_lock(&lck, file, line);
@@ -1358,6 +1361,8 @@ erts_proc_lc_require_lock(Process *p, ErtsProcLocks locks, char *file,
erts_lc_require_lock(&p->lock.link.lc, file, line);
if (locks & ERTS_PROC_LOCK_MSGQ)
erts_lc_require_lock(&p->lock.msgq.lc, file, line);
+ if (locks & ERTS_PROC_LOCK_BTM)
+ erts_lc_require_lock(&p->lock.btm.lc, file, line);
if (locks & ERTS_PROC_LOCK_STATUS)
erts_lc_require_lock(&p->lock.status.lc, file, line);
#endif
@@ -1374,6 +1379,10 @@ erts_proc_lc_unrequire_lock(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_status;
erts_lc_unrequire_lock(&lck);
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ lck.id = lc_id.proc_lock_btm;
+ erts_lc_unrequire_lock(&lck);
+ }
if (locks & ERTS_PROC_LOCK_MSGQ) {
lck.id = lc_id.proc_lock_msgq;
erts_lc_unrequire_lock(&lck);
@@ -1393,6 +1402,8 @@ erts_proc_lc_unrequire_lock(Process *p, ErtsProcLocks locks)
erts_lc_unrequire_lock(&p->lock.link.lc);
if (locks & ERTS_PROC_LOCK_MSGQ)
erts_lc_unrequire_lock(&p->lock.msgq.lc);
+ if (locks & ERTS_PROC_LOCK_BTM)
+ erts_lc_unrequire_lock(&p->lock.btm.lc);
if (locks & ERTS_PROC_LOCK_STATUS)
erts_lc_unrequire_lock(&p->lock.status.lc);
#endif
@@ -1414,6 +1425,8 @@ erts_proc_lc_trylock_force_busy(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_link;
else if (locks & ERTS_PROC_LOCK_MSGQ)
lck.id = lc_id.proc_lock_msgq;
+ else if (locks & ERTS_PROC_LOCK_BTM)
+ lck.id = lc_id.proc_lock_btm;
else if (locks & ERTS_PROC_LOCK_STATUS)
lck.id = lc_id.proc_lock_status;
else
@@ -1448,7 +1461,8 @@ erts_proc_lc_chk_have_proc_locks(Process *p, ErtsProcLocks locks)
{
int have_locks_len = 0;
#if ERTS_PROC_LOCK_OWN_IMPL
- erts_lc_lock_t have_locks[4] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
+ erts_lc_lock_t have_locks[5] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
+ ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT};
@@ -1464,18 +1478,24 @@ erts_proc_lc_chk_have_proc_locks(Process *p, ErtsProcLocks locks)
have_locks[have_locks_len].id = lc_id.proc_lock_msgq;
have_locks[have_locks_len++].extra = p->common.id;
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ have_locks[have_locks_len].id = lc_id.proc_lock_btm;
+ have_locks[have_locks_len++].extra = p->common.id;
+ }
if (locks & ERTS_PROC_LOCK_STATUS) {
have_locks[have_locks_len].id = lc_id.proc_lock_status;
have_locks[have_locks_len++].extra = p->common.id;
}
#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
- erts_lc_lock_t have_locks[4];
+ erts_lc_lock_t have_locks[5];
if (locks & ERTS_PROC_LOCK_MAIN)
have_locks[have_locks_len++] = p->lock.main.lc;
if (locks & ERTS_PROC_LOCK_LINK)
have_locks[have_locks_len++] = p->lock.link.lc;
if (locks & ERTS_PROC_LOCK_MSGQ)
have_locks[have_locks_len++] = p->lock.msgq.lc;
+ if (locks & ERTS_PROC_LOCK_BTM)
+ have_locks[have_locks_len++] = p->lock.btm.lc;
if (locks & ERTS_PROC_LOCK_STATUS)
have_locks[have_locks_len++] = p->lock.status.lc;
#endif
@@ -1488,11 +1508,11 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
int have_locks_len = 0;
int have_not_locks_len = 0;
#if ERTS_PROC_LOCK_OWN_IMPL
- erts_lc_lock_t have_locks[4] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
+ erts_lc_lock_t have_locks[5] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT};
- erts_lc_lock_t have_not_locks[4] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
+ erts_lc_lock_t have_not_locks[5] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT};
@@ -1521,6 +1541,14 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
have_not_locks[have_not_locks_len].id = lc_id.proc_lock_msgq;
have_not_locks[have_not_locks_len++].extra = p->common.id;
}
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ have_locks[have_locks_len].id = lc_id.proc_lock_btm;
+ have_locks[have_locks_len++].extra = p->common.id;
+ }
+ else {
+ have_not_locks[have_not_locks_len].id = lc_id.proc_lock_btm;
+ have_not_locks[have_not_locks_len++].extra = p->common.id;
+ }
if (locks & ERTS_PROC_LOCK_STATUS) {
have_locks[have_locks_len].id = lc_id.proc_lock_status;
have_locks[have_locks_len++].extra = p->common.id;
@@ -1530,8 +1558,8 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
have_not_locks[have_not_locks_len++].extra = p->common.id;
}
#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
- erts_lc_lock_t have_locks[4];
- erts_lc_lock_t have_not_locks[4];
+ erts_lc_lock_t have_locks[5];
+ erts_lc_lock_t have_not_locks[5];
if (locks & ERTS_PROC_LOCK_MAIN)
have_locks[have_locks_len++] = p->lock.main.lc;
@@ -1545,6 +1573,10 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
have_locks[have_locks_len++] = p->lock.msgq.lc;
else
have_not_locks[have_not_locks_len++] = p->lock.msgq.lc;
+ if (locks & ERTS_PROC_LOCK_BTM)
+ have_locks[have_locks_len++] = p->lock.btm.lc;
+ else
+ have_not_locks[have_not_locks_len++] = p->lock.btm.lc;
if (locks & ERTS_PROC_LOCK_STATUS)
have_locks[have_locks_len++] = p->lock.status.lc;
else
@@ -1558,10 +1590,10 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
ErtsProcLocks
erts_proc_lc_my_proc_locks(Process *p)
{
- int resv[4];
+ int resv[5];
ErtsProcLocks res = 0;
#if ERTS_PROC_LOCK_OWN_IMPL
- erts_lc_lock_t locks[4] = {ERTS_LC_LOCK_INIT(lc_id.proc_lock_main,
+ erts_lc_lock_t locks[5] = {ERTS_LC_LOCK_INIT(lc_id.proc_lock_main,
p->common.id,
ERTS_LC_FLG_LT_PROCLOCK),
ERTS_LC_LOCK_INIT(lc_id.proc_lock_link,
@@ -1570,17 +1602,21 @@ erts_proc_lc_my_proc_locks(Process *p)
ERTS_LC_LOCK_INIT(lc_id.proc_lock_msgq,
p->common.id,
ERTS_LC_FLG_LT_PROCLOCK),
+ ERTS_LC_LOCK_INIT(lc_id.proc_lock_btm,
+ p->common.id,
+ ERTS_LC_FLG_LT_PROCLOCK),
ERTS_LC_LOCK_INIT(lc_id.proc_lock_status,
p->common.id,
ERTS_LC_FLG_LT_PROCLOCK)};
#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
- erts_lc_lock_t locks[4] = {p->lock.main.lc,
+ erts_lc_lock_t locks[5] = {p->lock.main.lc,
p->lock.link.lc,
p->lock.msgq.lc,
+ p->lock.btm.lc,
p->lock.status.lc};
#endif
- erts_lc_have_locks(resv, locks, 4);
+ erts_lc_have_locks(resv, locks, 5);
if (resv[0])
res |= ERTS_PROC_LOCK_MAIN;
if (resv[1])
@@ -1588,6 +1624,8 @@ erts_proc_lc_my_proc_locks(Process *p)
if (resv[2])
res |= ERTS_PROC_LOCK_MSGQ;
if (resv[3])
+ res |= ERTS_PROC_LOCK_BTM;
+ if (resv[4])
res |= ERTS_PROC_LOCK_STATUS;
return res;
@@ -1596,13 +1634,14 @@ erts_proc_lc_my_proc_locks(Process *p)
void
erts_proc_lc_chk_no_proc_locks(char *file, int line)
{
- int resv[4];
- int ids[4] = {lc_id.proc_lock_main,
+ int resv[5];
+ int ids[5] = {lc_id.proc_lock_main,
lc_id.proc_lock_link,
lc_id.proc_lock_msgq,
+ lc_id.proc_lock_btm,
lc_id.proc_lock_status};
- erts_lc_have_lock_ids(resv, ids, 4);
- if (!ERTS_IS_CRASH_DUMPING && (resv[0] || resv[1] || resv[2] || resv[3])) {
+ erts_lc_have_lock_ids(resv, ids, 5);
+ if (!ERTS_IS_CRASH_DUMPING && (resv[0] || resv[1] || resv[2] || resv[3] || resv[4])) {
erts_lc_fail("%s:%d: Thread has process locks locked when expected "
"not to have any process locks locked",
file, line);
diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h
index 052d992d3f..9c59301086 100644
--- a/erts/emulator/beam/erl_process_lock.h
+++ b/erts/emulator/beam/erl_process_lock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -65,7 +66,7 @@
#endif
-#define ERTS_PROC_LOCK_MAX_BIT 3
+#define ERTS_PROC_LOCK_MAX_BIT 4
typedef erts_aint32_t ErtsProcLocks;
@@ -81,17 +82,18 @@ typedef struct erts_proc_lock_t_ {
erts_lcnt_lock_t lcnt_main;
erts_lcnt_lock_t lcnt_link;
erts_lcnt_lock_t lcnt_msgq;
+ erts_lcnt_lock_t lcnt_btm;
erts_lcnt_lock_t lcnt_status;
#endif
#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
erts_mtx_t main;
erts_mtx_t link;
erts_mtx_t msgq;
+ erts_mtx_t btm;
erts_mtx_t status;
#else
# error "no implementation"
#endif
- erts_atomic32_t refc;
#ifdef ERTS_PROC_LOCK_DEBUG
erts_smp_atomic32_t locked[ERTS_PROC_LOCK_MAX_BIT+1];
#endif
@@ -120,11 +122,17 @@ typedef struct erts_proc_lock_t_ {
* Message queue lock:
* Protects the following fields in the process structure:
* * msg_inq
- * * bif_timers
*/
#define ERTS_PROC_LOCK_MSGQ (((ErtsProcLocks) 1) << 2)
/*
+ * Bif timer lock:
+ * Protects the following fields in the process structure:
+ * * bif_timers
+ */
+#define ERTS_PROC_LOCK_BTM (((ErtsProcLocks) 1) << 3)
+
+/*
* Status lock:
* Protects the following fields in the process structure:
* * pending_suspenders
@@ -463,6 +471,9 @@ erts_smp_proc_raw_trylock__(Process *p, ErtsProcLocks locks)
if (locks & ERTS_PROC_LOCK_MSGQ)
if (erts_mtx_trylock(&p->lock.msgq) == EBUSY)
goto busy_msgq;
+ if (locks & ERTS_PROC_LOCK_BTM)
+ if (erts_mtx_trylock(&p->lock.btm) == EBUSY)
+ goto busy_btm;
if (locks & ERTS_PROC_LOCK_STATUS)
if (erts_mtx_trylock(&p->lock.status) == EBUSY)
goto busy_status;
@@ -470,6 +481,9 @@ erts_smp_proc_raw_trylock__(Process *p, ErtsProcLocks locks)
return 0;
busy_status:
+ if (locks & ERTS_PROC_LOCK_BTM)
+ erts_mtx_unlock(&p->lock.btm);
+busy_btm:
if (locks & ERTS_PROC_LOCK_MSGQ)
erts_mtx_unlock(&p->lock.msgq);
busy_msgq:
@@ -509,6 +523,10 @@ erts_smp_proc_lock__(Process *p,
ERTS_LC_ASSERT((locks & ~ERTS_PROC_LOCKS_ALL) == 0);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_proc_lc_lock(p, locks, file, line);
+#endif
+
old_lflgs = erts_smp_proc_raw_trylock__(p, locks);
if (old_lflgs != 0) {
@@ -530,9 +548,6 @@ erts_smp_proc_lock__(Process *p,
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_proc_lock_post_x(&(p->lock), locks, file, line);
#endif
-#ifdef ERTS_ENABLE_LOCK_CHECK
- erts_proc_lc_lock(p, locks, file, line);
-#endif
#ifdef ERTS_PROC_LOCK_DEBUG
erts_proc_lock_op_debug(p, locks, 1);
@@ -549,6 +564,8 @@ erts_smp_proc_lock__(Process *p,
erts_mtx_lock(&p->lock.link);
if (locks & ERTS_PROC_LOCK_MSGQ)
erts_mtx_lock(&p->lock.msgq);
+ if (locks & ERTS_PROC_LOCK_BTM)
+ erts_mtx_lock(&p->lock.btm);
if (locks & ERTS_PROC_LOCK_STATUS)
erts_mtx_lock(&p->lock.status);
@@ -638,6 +655,8 @@ erts_smp_proc_unlock__(Process *p,
if (locks & ERTS_PROC_LOCK_STATUS)
erts_mtx_unlock(&p->lock.status);
+ if (locks & ERTS_PROC_LOCK_BTM)
+ erts_mtx_unlock(&p->lock.btm);
if (locks & ERTS_PROC_LOCK_MSGQ)
erts_mtx_unlock(&p->lock.msgq);
if (locks & ERTS_PROC_LOCK_LINK)
@@ -752,9 +771,10 @@ ERTS_GLB_INLINE void erts_smp_proc_lock(Process *, ErtsProcLocks);
ERTS_GLB_INLINE void erts_smp_proc_unlock(Process *, ErtsProcLocks);
ERTS_GLB_INLINE int erts_smp_proc_trylock(Process *, ErtsProcLocks);
-ERTS_GLB_INLINE void erts_smp_proc_inc_refc(Process *);
-ERTS_GLB_INLINE void erts_smp_proc_dec_refc(Process *);
-ERTS_GLB_INLINE void erts_smp_proc_add_refc(Process *, Sint32);
+ERTS_GLB_INLINE void erts_proc_inc_refc(Process *);
+ERTS_GLB_INLINE void erts_proc_dec_refc(Process *);
+ERTS_GLB_INLINE void erts_proc_add_refc(Process *, Sint);
+ERTS_GLB_INLINE Sint erts_proc_read_refc(Process *);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
@@ -814,28 +834,53 @@ erts_smp_proc_trylock(Process *p, ErtsProcLocks locks)
#endif
}
-ERTS_GLB_INLINE void erts_smp_proc_inc_refc(Process *p)
+ERTS_GLB_INLINE void erts_proc_inc_refc(Process *p)
{
+ ASSERT(!(erts_smp_atomic32_read_nob(&p->state) & ERTS_PSFLG_PROXY));
#ifdef ERTS_SMP
+ erts_ptab_atmc_inc_refc(&p->common);
+#else
erts_ptab_inc_refc(&p->common);
#endif
}
-ERTS_GLB_INLINE void erts_smp_proc_dec_refc(Process *p)
+ERTS_GLB_INLINE void erts_proc_dec_refc(Process *p)
{
+ Sint referred;
+ ASSERT(!(erts_smp_atomic32_read_nob(&p->state) & ERTS_PSFLG_PROXY));
#ifdef ERTS_SMP
- int referred = erts_ptab_dec_test_refc(&p->common);
- if (!referred)
- erts_free_proc(p);
+ referred = erts_ptab_atmc_dec_test_refc(&p->common);
+#else
+ referred = erts_ptab_dec_test_refc(&p->common);
#endif
+ if (!referred) {
+ ASSERT(ERTS_PROC_IS_EXITING(p));
+ erts_free_proc(p);
+ }
}
-ERTS_GLB_INLINE void erts_smp_proc_add_refc(Process *p, Sint32 add_refc)
+ERTS_GLB_INLINE void erts_proc_add_refc(Process *p, Sint add_refc)
{
+ Sint referred;
+ ASSERT(!(erts_smp_atomic32_read_nob(&p->state) & ERTS_PSFLG_PROXY));
#ifdef ERTS_SMP
- int referred = erts_ptab_add_test_refc(&p->common, add_refc);
- if (!referred)
+ referred = erts_ptab_atmc_add_test_refc(&p->common, add_refc);
+#else
+ referred = erts_ptab_add_test_refc(&p->common, add_refc);
+#endif
+ if (!referred) {
+ ASSERT(ERTS_PROC_IS_EXITING(p));
erts_free_proc(p);
+ }
+}
+
+ERTS_GLB_INLINE Sint erts_proc_read_refc(Process *p)
+{
+ ASSERT(!(erts_smp_atomic32_read_nob(&p->state) & ERTS_PSFLG_PROXY));
+#ifdef ERTS_SMP
+ return erts_ptab_atmc_read_refc(&p->common);
+#else
+ return erts_ptab_read_refc(&p->common);
#endif
}
@@ -868,7 +913,7 @@ void erts_proc_safelock(Process *a_proc,
#define ERTS_P2P_FLG_ALLOW_OTHER_X (1 << 0)
#define ERTS_P2P_FLG_TRY_LOCK (1 << 1)
-#define ERTS_P2P_FLG_SMP_INC_REFC (1 << 2)
+#define ERTS_P2P_FLG_INC_REFC (1 << 2)
#define ERTS_PROC_LOCK_BUSY ((Process *) &erts_invalid_process)
@@ -928,11 +973,14 @@ erts_pid2proc_opt(Process *c_p_unused,
int flags)
{
Process *proc = erts_proc_lookup_raw(pid);
- return ((!(flags & ERTS_P2P_FLG_ALLOW_OTHER_X)
- && proc
- && ERTS_PROC_IS_EXITING(proc))
- ? NULL
- : proc);
+ if (!proc)
+ return NULL;
+ if (!(flags & ERTS_P2P_FLG_ALLOW_OTHER_X)
+ && ERTS_PROC_IS_EXITING(proc))
+ return NULL;
+ if (flags & ERTS_P2P_FLG_INC_REFC)
+ erts_proc_inc_refc(proc);
+ return proc;
}
#endif /* !ERTS_SMP */
diff --git a/erts/emulator/beam/erl_ptab.c b/erts/emulator/beam/erl_ptab.c
index 02943ee683..9ed175fe01 100644
--- a/erts/emulator/beam/erl_ptab.c
+++ b/erts/emulator/beam/erl_ptab.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -360,7 +361,8 @@ erts_ptab_init_table(ErtsPTab *ptab,
int size,
UWord element_size,
char *name,
- int legacy)
+ int legacy,
+ int atomic_refc)
{
size_t tab_sz, alloc_sz;
Uint32 bits, cl, cli, ix, ix_per_cache_line, tab_cache_lines;
@@ -415,6 +417,8 @@ erts_ptab_init_table(ErtsPTab *ptab,
ptab->r.o.invalid_data = erts_ptab_id2data(ptab, invalid_element->id);
ptab->r.o.release_element = release_element;
+ ptab->r.o.atomic_refc = atomic_refc;
+
if (legacy) {
ptab->r.o.free_id_data = NULL;
ptab->r.o.dix_cl_mask = 0;
@@ -533,9 +537,10 @@ erts_ptab_new_element(ErtsPTab *ptab,
init_ptab_el(init_arg, (Eterm) data);
-#ifdef ERTS_SMP
- erts_smp_atomic32_init_nob(&ptab_el->refc, 1);
-#endif
+ if (ptab->r.o.atomic_refc)
+ erts_atomic_init_nob(&ptab_el->refc.atmc, 1);
+ else
+ ptab_el->refc.sint = 1;
pix = erts_ptab_data2pix(ptab, (Eterm) data);
@@ -608,9 +613,10 @@ erts_ptab_new_element(ErtsPTab *ptab,
init_ptab_el(init_arg, data);
-#ifdef ERTS_SMP
- erts_smp_atomic32_init_nob(&ptab_el->refc, 1);
-#endif
+ if (ptab->r.o.atomic_refc)
+ erts_atomic_init_nob(&ptab_el->refc.atmc, 1);
+ else
+ ptab_el->refc.sint = 1;
/* Move into slot reserved */
#ifdef DEBUG
@@ -1249,7 +1255,7 @@ ptab_list_bif_engine(Process *c_p, Eterm *res_accp, Binary *mbp)
return 1;
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:ptab_list_bif_engine(): Invalid state: %d\n",
__FILE__, __LINE__, (int) ptlbdp->state);
}
diff --git a/erts/emulator/beam/erl_ptab.h b/erts/emulator/beam/erl_ptab.h
index 876241159b..8fd961e3ce 100644
--- a/erts/emulator/beam/erl_ptab.h
+++ b/erts/emulator/beam/erl_ptab.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -51,11 +52,13 @@
typedef struct {
Eterm id;
-#ifdef ERTS_SMP
- erts_atomic32_t refc;
-#endif
+ union {
+ erts_atomic_t atmc;
+ Sint sint;
+ } refc;
Eterm tracer_proc;
Uint trace_flags;
+ erts_smp_atomic_t timer;
union {
/* --- While being alive --- */
struct {
@@ -63,11 +66,6 @@ typedef struct {
struct reg_proc *reg;
ErtsLink *links;
ErtsMonitor *monitors;
-#ifdef ERTS_SMP
- ErtsSmpPTimer *ptimer;
-#else
- ErlTimer tm;
-#endif
} alive;
/* --- While being released --- */
@@ -111,6 +109,7 @@ typedef struct {
Eterm invalid_data;
void (*release_element)(void *);
UWord element_size;
+ int atomic_refc;
} ErtsPTabReadOnlyData;
typedef struct {
@@ -181,7 +180,8 @@ void erts_ptab_init_table(ErtsPTab *ptab,
int size,
UWord element_size,
char *name,
- int legacy);
+ int legacy,
+ int atomic_refc);
int erts_ptab_new_element(ErtsPTab *ptab,
ErtsPTabElementCommon *ptab_el,
void *init_arg,
@@ -206,9 +206,15 @@ ERTS_GLB_INLINE erts_aint_t erts_ptab_pix2intptr_ddrb(ErtsPTab *ptab, int ix);
ERTS_GLB_INLINE erts_aint_t erts_ptab_pix2intptr_rb(ErtsPTab *ptab, int ix);
ERTS_GLB_INLINE erts_aint_t erts_ptab_pix2intptr_acqb(ErtsPTab *ptab, int ix);
ERTS_GLB_INLINE void erts_ptab_inc_refc(ErtsPTabElementCommon *ptab_el);
-ERTS_GLB_INLINE int erts_ptab_dec_test_refc(ErtsPTabElementCommon *ptab_el);
-ERTS_GLB_INLINE int erts_ptab_add_test_refc(ErtsPTabElementCommon *ptab_el,
- Sint32 add_refc);
+ERTS_GLB_INLINE Sint erts_ptab_dec_test_refc(ErtsPTabElementCommon *ptab_el);
+ERTS_GLB_INLINE Sint erts_ptab_add_test_refc(ErtsPTabElementCommon *ptab_el,
+ Sint add_refc);
+ERTS_GLB_INLINE Sint erts_ptab_read_refc(ErtsPTabElementCommon *ptab_el);
+ERTS_GLB_INLINE void erts_ptab_atmc_inc_refc(ErtsPTabElementCommon *ptab_el);
+ERTS_GLB_INLINE Sint erts_ptab_atmc_dec_test_refc(ErtsPTabElementCommon *ptab_el);
+ERTS_GLB_INLINE Sint erts_ptab_atmc_add_test_refc(ErtsPTabElementCommon *ptab_el,
+ Sint add_refc);
+ERTS_GLB_INLINE Sint erts_ptab_atmc_read_refc(ErtsPTabElementCommon *ptab_el);
ERTS_GLB_INLINE void erts_ptab_rlock(ErtsPTab *ptab);
ERTS_GLB_INLINE int erts_ptab_tryrlock(ErtsPTab *ptab);
ERTS_GLB_INLINE void erts_ptab_runlock(ErtsPTab *ptab);
@@ -365,50 +371,65 @@ ERTS_GLB_INLINE erts_aint_t erts_ptab_pix2intptr_acqb(ErtsPTab *ptab, int ix)
return erts_smp_atomic_read_acqb(&ptab->r.o.tab[ix]);
}
-ERTS_GLB_INLINE void erts_ptab_inc_refc(ErtsPTabElementCommon *ptab_el)
+ERTS_GLB_INLINE void erts_ptab_atmc_inc_refc(ErtsPTabElementCommon *ptab_el)
{
-#ifdef ERTS_SMP
#ifdef ERTS_ENABLE_LOCK_CHECK
- erts_aint32_t refc = erts_atomic32_inc_read_nob(&ptab_el->refc);
- ERTS_SMP_LC_ASSERT(refc > 1);
+ erts_aint_t refc = erts_atomic_inc_read_nob(&ptab_el->refc.atmc);
+ ERTS_LC_ASSERT(refc > 1);
#else
- erts_atomic32_inc_nob(&ptab_el->refc);
-#endif
+ erts_atomic_inc_nob(&ptab_el->refc.atmc);
#endif
}
-ERTS_GLB_INLINE int erts_ptab_dec_test_refc(ErtsPTabElementCommon *ptab_el)
+ERTS_GLB_INLINE Sint erts_ptab_atmc_dec_test_refc(ErtsPTabElementCommon *ptab_el)
{
-#ifdef ERTS_SMP
- erts_aint32_t refc = erts_atomic32_dec_read_nob(&ptab_el->refc);
+ erts_aint_t refc = erts_atomic_dec_read_relb(&ptab_el->refc.atmc);
ERTS_SMP_LC_ASSERT(refc >= 0);
- return (int) refc;
-#else
- return 0;
+#ifdef ERTS_SMP
+ if (refc == 0)
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
#endif
+ return (Sint) refc;
}
-ERTS_GLB_INLINE int erts_ptab_add_test_refc(ErtsPTabElementCommon *ptab_el,
- Sint32 add_refc)
+ERTS_GLB_INLINE Sint erts_ptab_atmc_add_test_refc(ErtsPTabElementCommon *ptab_el,
+ Sint add_refc)
{
-#ifdef ERTS_SMP
- erts_aint32_t refc;
+ erts_aint_t refc = erts_atomic_add_read_mb(&ptab_el->refc.atmc,
+ (erts_aint_t) add_refc);
+ ERTS_SMP_LC_ASSERT(refc >= 0);
+ return (Sint) refc;
+}
-#ifndef ERTS_ENABLE_LOCK_CHECK
- if (add_refc >= 0) {
- erts_atomic32_add_nob(&ptab_el->refc,
- (erts_aint32_t) add_refc);
- return 1;
- }
-#endif
+ERTS_GLB_INLINE Sint erts_ptab_atmc_read_refc(ErtsPTabElementCommon *ptab_el)
+{
+ return (Sint) erts_atomic_read_nob(&ptab_el->refc.atmc);
+}
+
+ERTS_GLB_INLINE void erts_ptab_inc_refc(ErtsPTabElementCommon *ptab_el)
+{
+ ptab_el->refc.sint++;
+ ASSERT(ptab_el->refc.sint > 1);
+}
- refc = erts_atomic32_add_read_nob(&ptab_el->refc,
- (erts_aint32_t) add_refc);
+ERTS_GLB_INLINE Sint erts_ptab_dec_test_refc(ErtsPTabElementCommon *ptab_el)
+{
+ Sint refc = --ptab_el->refc.sint;
ERTS_SMP_LC_ASSERT(refc >= 0);
- return (int) refc;
-#else
- return 0;
-#endif
+ return refc;
+}
+
+ERTS_GLB_INLINE Sint erts_ptab_add_test_refc(ErtsPTabElementCommon *ptab_el,
+ Sint add_refc)
+{
+ ptab_el->refc.sint += add_refc;
+ ERTS_SMP_LC_ASSERT(ptab_el->refc.sint >= 0);
+ return (Sint) ptab_el->refc.sint;
+}
+
+ERTS_GLB_INLINE Sint erts_ptab_read_refc(ErtsPTabElementCommon *ptab_el)
+{
+ return ptab_el->refc.sint;
}
ERTS_GLB_INLINE void erts_ptab_rlock(ErtsPTab *ptab)
diff --git a/erts/emulator/beam/erl_rbtree.h b/erts/emulator/beam/erl_rbtree.h
new file mode 100644
index 0000000000..5fefaea978
--- /dev/null
+++ b/erts/emulator/beam/erl_rbtree.h
@@ -0,0 +1,1741 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Description: A Red-Black (binary search) Tree implementation. The search,
+ * insert, and delete operations are all O(log n) operations
+ * on a Red-Black Tree. Red-Black Trees are described in
+ * "Introduction to Algorithms", by Thomas H. Cormen, Charles
+ * E. Leiserson, and Ronald L. Riverest.
+ *
+ * Use by defining mandatory defines as well as defines for
+ * API functions wanted, and include this header.
+ *
+ * Author: Rickard Green
+ *
+ *
+ * Mandatory defines:
+ * - ERTS_RBT_PREFIX - Prefix to use on functions.
+ * - ERTS_RBT_T - Type of a tree node.
+ * - ERTS_RBT_KEY_T - Type of key for a tree node.
+ * - ERTS_RBT_FLAGS_T - Type of flags for a tree node.
+ * - ERTS_RBT_INIT_EMPTY_TNODE(T) -Initialize an empty tree node.
+ * - ERTS_RBT_IS_RED(T) - Is tree node red?
+ * - ERTS_RBT_SET_RED(T) - Set tree node red.
+ * - ERTS_RBT_IS_BLACK(T) - Is tree node back?
+ * - ERTS_RBT_SET_BLACK(T) - Set tree node black.
+ * - ERTS_RBT_GET_FLAGS(T) - Get flags of tree node (incl colors).
+ * - ERTS_RBT_SET_FLAGS(T, F) - Set flags of tree note.
+ * - ERTS_RBT_GET_PARENT(T) - Get parent node.
+ * - ERTS_RBT_SET_PARENT(T, P) - Set parent node.
+ * - ERTS_RBT_GET_RIGHT(T) - Get right child node.
+ * - ERTS_RBT_SET_RIGHT(T, R) - Set right child node.
+ * - ERTS_RBT_GET_LEFT(T) - Get left child node.
+ * - ERTS_RBT_SET_LEFT(T, L) - Set left child node.
+ * - ERTS_RBT_GET_KEY(T) - Get key of node.
+ * - ERTS_RBT_IS_LT(KX, KY) - Is key KX less than key KY?
+ * - ERTS_RBT_IS_EQ(KX, KY) - Is key KX equal to key KY?
+ *
+ * Optional defines:
+ *
+ * - ERTS_RBT_UNDEF - Undefine all user defined ERTS_RBT_*
+ * defines after use.
+ *
+ * - ERTS_RBT_NO_API_INLINE - Do not inline API functions.
+ *
+ * Attached data management:
+ * - ERTS_RBT_UPDATE_ATTACHED_DATA_ROTATE(L, OP, NP) - Called
+ * when a rotate operation has been performed. If L (in int)
+ * is a non zero, a left rotation was performed; otherwise,
+ * a right rotation was performed. OR points to the old
+ * parent node and NP points to the new parent node.
+ * - ERTS_RBT_UPDATE_ATTACHED_DATA_DMOD(F, T) - Called when
+ * a delete operation modifies a tree node. A delete
+ * modification is either a removal or replacement of a
+ * node. F points to the parent of the tree node that was
+ * modified. T points to the next ancestor that will be
+ * modified. If T is NULL, no more removal and/or
+ * replacements will be made. One typically wants to update
+ * the attached data of each node between F and T. If T is
+ * NULL all the way up to the root.
+ * - ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(OR, NR) - Called
+ * when the root node changes. OR points to the old
+ * root node and NP points to the new root node.
+ *
+ * Request implementation of API functions:
+ * - ERTS_RBT_WANT_DELETE
+ * - ERTS_RBT_WANT_INSERT
+ * - ERTS_RBT_WANT_LOOKUP_INSERT
+ * - ERTS_RBT_WANT_REPLACE
+ * - ERTS_RBT_WANT_LOOKUP
+ * - ERTS_RBT_WANT_SMALLEST
+ * - ERTS_RBT_WANT_LARGEST
+ * - ERTS_RBT_WANT_FOREACH
+ * - ERTS_RBT_WANT_FOREACH_DESTROY
+ * - ERTS_RBT_WANT_FOREACH_YIELDING
+ * - ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING
+ * - ERTS_RBT_WANT_FOREACH_SMALL
+ * - ERTS_RBT_WANT_FOREACH_LARGE
+ * - ERTS_RBT_WANT_FOREACH_SMALL_DESTROY
+ * - ERTS_RBT_WANT_FOREACH_LARGE_DESTROY
+ * - ERTS_RBT_WANT_FOREACH_SMALL_YIELDING
+ * - ERTS_RBT_WANT_FOREACH_LARGE_YIELDING
+ * - ERTS_RBT_WANT_FOREACH_SMALL_DESTROY_YIELDING
+ * - ERTS_RBT_WANT_FOREACH_LARGE_DESTROY_YIELDING
+ * - ERTS_RBT_WANT_DEBUG_PRINT
+ *
+ * The yield state data type will equal
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t.
+ *
+ * The yield state should be statically initialized by
+ * ERTS_RBT_YIELD_STAT_INITER.
+ *
+ *
+ * The following API functions are implemented if corresponding
+ * ERTS_RBT_WANT_<OPERATION> is defined:
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_delete(
+ * ERTS_RBT_T **tree,
+ * ERTS_RBT_T *element);
+ * Delete element from tree.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_insert(
+ * ERTS_RBT_T **tree,
+ * ERTS_RBT_T *element);
+ * Insert element into tree.
+ *
+ * - ERTS_RBT_T * <ERTS_RBT_PREFIX>_rbt_lookup_insert(
+ * ERTS_RBT_T **tree,
+ * ERTS_RBT_T *element);
+ * Look up an element in the tree that compares as equal to the
+ * element passed as argument, and return the looked up element.
+ * If no element compared as equal, insert the element passed as
+ * argument into the tree, and return NULL.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_replace(
+ * ERTS_RBT_T **tree,
+ * ERTS_RBT_T *old_element,
+ * ERTS_RBT_T *new_element);
+ * Replace old_element in the tree with new_element. Both elements
+ * *should* compare as equal.
+ *
+ * - ERTS_RBT_T * <ERTS_RBT_PREFIX>_rbt_lookup(
+ * ERTS_RBT_T *tree,
+ * ERTS_RBT_KEY_T key);
+ * Look up an element with a key that compares as equal to
+ * the key passed as argument.
+ *
+ * - ERTS_RBT_T * <ERTS_RBT_PREFIX>_rbt_smallest(
+ * ERTS_RBT_T *tree);
+ * Look up the element with the smallest key.
+ *
+ * - ERTS_RBT_T * <ERTS_RBT_PREFIX>_rbt_largest(
+ * ERTS_RBT_T *tree);
+ * Look up the element with the largest key.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_foreach(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg);
+ * Operate by calling the operator 'op' on each element.
+ * Order is undefined.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_foreach_destroy(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg);
+ * Operate by calling the operator 'op' on each element.
+ * Order is undefined. Each element should be destroyed
+ * by 'op'.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - int <ERTS_RBT_PREFIX>_rbt_foreach_yielding(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg,
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate,
+ * Sint ylimit);
+ * Operate by calling the operator 'op' on each element.
+ * Order is undefined.
+ *
+ * Yield when 'ylimit' elements has been processed. Zero is
+ * returned when yielding, and a non-zero value is returned when
+ * the whole tree has been processed. The tree should not be
+ * modified until all of it has been processed.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - int <ERTS_RBT_PREFIX>_rbt_foreach_destroy_yielding(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg,
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate,
+ * Sint ylimit);
+ * Operate by calling the operator 'op' on each element.
+ * Order is undefined. Each element should be destroyed
+ * by 'op'.
+ *
+ * Yield when 'ylimit' elements has been processed. Zero is
+ * returned when yielding, and a non-zero value is returned when
+ * the whole tree has been processed.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_foreach_small(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg);
+ * Operate by calling the operator 'op' on each element from
+ * smallest towards larger elements.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_foreach_large(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg);
+ * Operate by calling the operator 'op' on each element from
+ * largest towards smaller elements.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - int <ERTS_RBT_PREFIX>_rbt_foreach_small_yielding(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg,
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate,
+ * Sint ylimit);
+ * Operate by calling the operator 'op' on each element from
+ * smallest towards larger elements.
+ *
+ * Yield when 'ylimit' elements has been processed. Zero is
+ * returned when yielding, and a non-zero value is returned when
+ * the whole tree has been processed. The tree should not be
+ * modified until all of it has been processed.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - int <ERTS_RBT_PREFIX>_rbt_foreach_large_yielding(
+ * ERTS_RBT_T *tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void *arg,
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate,
+ * Sint ylimit);
+ * Operate by calling the operator 'op' on each element from
+ * largest towards smaller elements.
+ *
+ * Yield when 'ylimit' elements has been processed. Zero is
+ * returned when yielding, and a non-zero value is returned when
+ * the whole tree has been processed. The tree should not be
+ * modified until all of it has been processed.
+ *
+ * 'arg' is passed as argument to 'op'.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_foreach_small_destroy(
+ * ERTS_RBT_T **tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void (*destr)(ERTS_RBT_T *, void *),
+ * void *arg);
+ * Operate by calling the operator 'op' on each element from
+ * smallest towards larger elements.
+ *
+ * Destroy elements by calling the destructor 'destr'. Elements
+ * are destroyed when not needed by the tree structure anymore.
+ * Note that elements are often *not* destroyed in another order
+ * than the order that the elements are operated on.
+ *
+ * 'arg' is passed as argument to 'op' and 'destroy'.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_foreach_large_destroy(
+ * ERTS_RBT_T **tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void (*destr)(ERTS_RBT_T *, void *),
+ * void *arg);
+ * Operate by calling the operator 'op' on each element from
+ * largest towards smaller elements.
+ *
+ * Destroy elements by calling the destructor 'destr'. Elements
+ * are destroyed when not needed by the tree structure anymore.
+ * Note that elements are often destroyed in another order
+ * than the order that the elements are operated on.
+ *
+ * 'arg' is passed as argument to 'op' and 'destroy'.
+ *
+ * - int <ERTS_RBT_PREFIX>_rbt_foreach_small_destroy_yielding(
+ * ERTS_RBT_T **tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void (*destr)(ERTS_RBT_T *, void *),
+ * void *arg,
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate,
+ * Sint ylimit);
+ * Operate by calling the operator 'op' on each element from
+ * smallest towards larger elements.
+ *
+ * Destroy elements by calling the destructor 'destr'. Elements
+ * are destroyed when not needed by the tree structure anymore.
+ * Note that elements are often destroyed in another order
+ * than the order that the elements are operated on.
+ *
+ * Yield when 'ylimit' elements has been processed. Zero is
+ * returned when yielding, and a non-zero value is returned when
+ * the whole tree has been processed. The tree should not be
+ * modified until all of it has been processed.
+ *
+ * 'arg' is passed as argument to 'op' and 'destroy'.
+ *
+ * - int <ERTS_RBT_PREFIX>_rbt_foreach_large_destroy_yielding(
+ * ERTS_RBT_T **tree,
+ * void (*op)(ERTS_RBT_T *, void *),
+ * void (*destr)(ERTS_RBT_T *, void *),
+ * void *arg,
+ * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate,
+ * Sint ylimit);
+ * Operate by calling the operator 'op' on each element from
+ * largest towards smaller elements.
+ *
+ * Destroy elements by calling the destructor 'destr'. Elements
+ * are destroyed when not needed by the tree structure anymore.
+ * Note that elements are often destroyed in another order
+ * than the order that the elements are operated on.
+ *
+ * Yield when 'ylimit' elements has been processed. Zero is
+ * returned when yielding, and a non-zero value is returned when
+ * the whole tree has been processed. The tree should not be
+ * modified until all of it has been processed.
+ *
+ * 'arg' is passed as argument to 'op' and 'destroy'.
+ *
+ * - void <ERTS_RBT_PREFIX>_rbt_debug_print(
+ * FILE *filep,
+ * ERTS_RBT_T *x,
+ * int indent,
+ * (void)(*print_node)(ERTS_RBT_T *));
+ * Prints the tree. Note that this function is recursive.
+ * Should only be used for debuging.
+ */
+
+
+/*
+ * Check that we have all mandatory defines
+ */
+#ifndef ERTS_RBT_PREFIX
+# error Missing definition of ERTS_RBT_PREFIX
+#endif
+#ifndef ERTS_RBT_T
+# error Missing definition of ERTS_RBT_T
+#endif
+#ifndef ERTS_RBT_KEY_T
+# error Missing definition of ERTS_RBT_KEY_T
+#endif
+#ifndef ERTS_RBT_FLAGS_T
+# error Missing definition of ERTS_RBT_FLAGS_T
+#endif
+#ifndef ERTS_RBT_INIT_EMPTY_TNODE
+# error Missing definition of ERTS_RBT_INIT_EMPTY_TNODE
+#endif
+#ifndef ERTS_RBT_IS_RED
+# error Missing definition of ERTS_RBT_IS_RED
+#endif
+#ifndef ERTS_RBT_SET_RED
+# error Missing definition of ERTS_RBT_SET_RED
+#endif
+#ifndef ERTS_RBT_IS_BLACK
+# error Missing definition of ERTS_RBT_IS_BLACK
+#endif
+#ifndef ERTS_RBT_SET_BLACK
+# error Missing definition of ERTS_RBT_SET_BLACK
+#endif
+#ifndef ERTS_RBT_GET_FLAGS
+# error Missing definition of ERTS_RBT_GET_FLAGS
+#endif
+#ifndef ERTS_RBT_SET_FLAGS
+# error Missing definition of ERTS_RBT_SET_FLAGS
+#endif
+#ifndef ERTS_RBT_GET_PARENT
+# error Missing definition of ERTS_RBT_GET_PARENT
+#endif
+#ifndef ERTS_RBT_SET_PARENT
+# error Missing definition of ERTS_RBT_SET_PARENT
+#endif
+#ifndef ERTS_RBT_GET_RIGHT
+# error Missing definition of ERTS_RBT_GET_RIGHT
+#endif
+#ifndef ERTS_RBT_GET_LEFT
+# error Missing definition of ERTS_RBT_GET_LEFT
+#endif
+#ifndef ERTS_RBT_IS_LT
+# error Missing definition of ERTS_RBT_IS_LT
+#endif
+#ifndef ERTS_RBT_GET_KEY
+# error Missing definition of ERTS_RBT_GET_KEY
+#endif
+#ifndef ERTS_RBT_IS_EQ
+# error Missing definition of ERTS_RBT_IS_EQ
+#endif
+
+#if defined(ERTS_RBT_HARD_DEBUG) || defined(DEBUG)
+# ifndef ERTS_RBT_DEBUG
+# define ERTS_RBT_DEBUG 1
+# endif
+#endif
+
+#if defined(ERTS_RBT_HARD_DEBUG) && defined(__GNUC__)
+#warning "* * * * * * * * * * * * * * * * * *"
+#warning "* ERTS_RBT_HARD_DEBUG IS ENABLED! *"
+#warning "* * * * * * * * * * * * * * * * * *"
+#endif
+
+#undef ERTS_RBT_ASSERT
+#if defined(ERTS_RBT_DEBUG)
+#define ERTS_RBT_ASSERT(E) ERTS_ASSERT(E)
+#else
+#define ERTS_RBT_ASSERT(E) ((void) 1)
+#endif
+
+#undef ERTS_RBT_API_INLINE__
+#if defined(ERTS_RBT_NO_API_INLINE) || defined(ERTS_RBT_DEBUG)
+# define ERTS_RBT_API_INLINE__
+#else
+# define ERTS_RBT_API_INLINE__ ERTS_INLINE
+#endif
+
+#ifndef ERTS_RBT_YIELD_STAT_INITER
+# define ERTS_RBT_YIELD_STAT_INITER {NULL, 0}
+#endif
+
+#define ERTS_RBT_CONCAT_MACRO_VALUES___(X, Y) \
+ X ## Y
+#define ERTS_RBT_CONCAT_MACRO_VALUES__(X, Y) \
+ ERTS_RBT_CONCAT_MACRO_VALUES___(X, Y)
+
+#undef ERTS_RBT_YIELD_STATE_T__
+#define ERTS_RBT_YIELD_STATE_T__ \
+ ERTS_RBT_CONCAT_MACRO_VALUES__(ERTS_RBT_PREFIX, _rbt_yield_state_t)
+
+typedef struct {
+ ERTS_RBT_T *x;
+ int up;
+} ERTS_RBT_YIELD_STATE_T__;
+
+#define ERTS_RBT_FUNC__(Name) \
+ ERTS_RBT_CONCAT_MACRO_VALUES__(ERTS_RBT_PREFIX, _rbt_ ## Name)
+
+#undef ERTS_RBT_NEED_REPLACE__
+#undef ERTS_RBT_NEED_INSERT__
+#undef ERTS_RBT_NEED_ROTATE__
+#undef ERTS_RBT_NEED_FOREACH_UNORDERED__
+#undef ERTS_RBT_NEED_FOREACH_ORDERED__
+#undef ERTS_RBT_NEED_HDBG_CHECK_TREE__
+#undef ERTS_RBT_HDBG_CHECK_TREE__
+
+#if defined(ERTS_RBT_WANT_REPLACE) || defined(ERTS_RBT_WANT_DELETE)
+# define ERTS_RBT_NEED_REPLACE__
+#endif
+#if defined(ERTS_RBT_WANT_INSERT) || defined(ERTS_RBT_WANT_LOOKUP_INSERT)
+# define ERTS_RBT_NEED_INSERT__
+#endif
+#if defined(ERTS_RBT_WANT_DELETE) || defined(ERTS_RBT_NEED_INSERT__)
+# define ERTS_RBT_NEED_ROTATE__
+#endif
+#if defined(ERTS_RBT_WANT_FOREACH) \
+ || defined(ERTS_RBT_WANT_FOREACH_YIELDING) \
+ || defined(ERTS_RBT_WANT_FOREACH_DESTROY) \
+ || defined(ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING)
+# define ERTS_RBT_NEED_FOREACH_UNORDERED__
+#endif
+#if defined(ERTS_RBT_WANT_FOREACH_SMALL) \
+ || defined(ERTS_RBT_WANT_FOREACH_LARGE) \
+ || defined(ERTS_RBT_WANT_FOREACH_SMALL_YIELDING) \
+ || defined(ERTS_RBT_WANT_FOREACH_LARGE_YIELDING) \
+ || defined(ERTS_RBT_WANT_FOREACH_SMALL_DESTROY) \
+ || defined(ERTS_RBT_WANT_FOREACH_LARGE_DESTROY) \
+ || defined(ERTS_RBT_WANT_FOREACH_SMALL_DESTROY_YIELDING) \
+ || defined(ERTS_RBT_WANT_FOREACH_LARGE_DESTROY_YIELDING)
+# define ERTS_RBT_NEED_FOREACH_ORDERED__
+#endif
+#if defined(ERTS_RBT_HARD_DEBUG) \
+ && (defined(ERTS_RBT_WANT_DELETE) \
+ || defined(ERTS_RBT_NEED_INSERT__))
+static void ERTS_RBT_FUNC__(hdbg_check_tree)(ERTS_RBT_T *root);
+# define ERTS_RBT_NEED_HDBG_CHECK_TREE__
+# define ERTS_RBT_HDBG_CHECK_TREE__(R) \
+ ERTS_RBT_FUNC__(hdbg_check_tree)((R))
+#else
+# define ERTS_RBT_HDBG_CHECK_TREE__(R) ((void) 1)
+#endif
+
+#ifdef ERTS_RBT_NEED_ROTATE__
+
+static ERTS_INLINE void
+ERTS_RBT_FUNC__(left_rotate__)(ERTS_RBT_T **root, ERTS_RBT_T *x)
+{
+ ERTS_RBT_T *y, *l, *p;
+
+ y = ERTS_RBT_GET_RIGHT(x);
+ l = ERTS_RBT_GET_LEFT(y);
+ ERTS_RBT_SET_RIGHT(x, l);
+
+ if (l)
+ ERTS_RBT_SET_PARENT(l, x);
+
+ p = ERTS_RBT_GET_PARENT(x);
+ ERTS_RBT_SET_PARENT(y, p);
+
+ if (!p) {
+ ERTS_RBT_ASSERT(*root == x);
+ *root = y;
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+ ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(x, y);
+#endif
+ }
+ else if (x == ERTS_RBT_GET_LEFT(p))
+ ERTS_RBT_SET_LEFT(p, y);
+ else {
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_RIGHT(p));
+ ERTS_RBT_SET_RIGHT(p, y);
+ }
+ ERTS_RBT_SET_LEFT(y, x);
+ ERTS_RBT_SET_PARENT(x, y);
+
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_ROTATE
+ ERTS_RBT_UPDATE_ATTACHED_DATA_ROTATE(!0, x, y);
+#endif
+
+}
+
+static ERTS_INLINE void
+ERTS_RBT_FUNC__(right_rotate__)(ERTS_RBT_T **root, ERTS_RBT_T *x)
+{
+ ERTS_RBT_T *y, *r, *p;
+
+ y = ERTS_RBT_GET_LEFT(x);
+ r = ERTS_RBT_GET_RIGHT(y);
+ ERTS_RBT_SET_LEFT(x, r);
+
+ if (r)
+ ERTS_RBT_SET_PARENT(r, x);
+
+ p = ERTS_RBT_GET_PARENT(x);
+ ERTS_RBT_SET_PARENT(y, p);
+
+ if (!p) {
+ ERTS_RBT_ASSERT(*root == x);
+ *root = y;
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+ ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(x, y);
+#endif
+ }
+ else if (x == ERTS_RBT_GET_RIGHT(p))
+ ERTS_RBT_SET_RIGHT(p, y);
+ else {
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_LEFT(p));
+ ERTS_RBT_SET_LEFT(p, y);
+ }
+
+ ERTS_RBT_SET_RIGHT(y, x);
+ ERTS_RBT_SET_PARENT(x, y);
+
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_ROTATE
+ ERTS_RBT_UPDATE_ATTACHED_DATA_ROTATE(0, x, y);
+#endif
+
+}
+
+#endif /* ERTS_RBT_NEED_ROTATE__ */
+
+#ifdef ERTS_RBT_NEED_REPLACE__
+
+/*
+ * Replace node x with node y
+ */
+static ERTS_INLINE void
+ERTS_RBT_FUNC__(replace__)(ERTS_RBT_T **root, ERTS_RBT_T *x, ERTS_RBT_T *y)
+{
+ ERTS_RBT_T *p, *r, *l;
+ ERTS_RBT_FLAGS_T f;
+
+ p = ERTS_RBT_GET_PARENT(x);
+ if (!p) {
+ ERTS_RBT_ASSERT(*root == x);
+ *root = y;
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+ ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(x, y);
+#endif
+ }
+ else if (x == ERTS_RBT_GET_LEFT(p))
+ ERTS_RBT_SET_LEFT(p, y);
+ else {
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_RIGHT(p));
+ ERTS_RBT_SET_RIGHT(p, y);
+ }
+ l = ERTS_RBT_GET_LEFT(x);
+ if (l) {
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_PARENT(l) == x);
+ ERTS_RBT_SET_PARENT(l, y);
+ }
+ r = ERTS_RBT_GET_RIGHT(x);
+ if (r) {
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_PARENT(r) == x);
+ ERTS_RBT_SET_PARENT(r, y);
+ }
+
+ f = ERTS_RBT_GET_FLAGS(x);
+ ERTS_RBT_SET_FLAGS(y, f);
+ ERTS_RBT_SET_PARENT(y, p);
+ ERTS_RBT_SET_RIGHT(y, r);
+ ERTS_RBT_SET_LEFT(y, l);
+}
+
+#endif /* ERTS_RBT_NEED_REPLACE__ */
+
+#ifdef ERTS_RBT_WANT_REPLACE
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(replace)(ERTS_RBT_T **root, ERTS_RBT_T *x, ERTS_RBT_T *y)
+{
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_EQ(ERTS_RBT_GET_KEY(x),
+ ERTS_RBT_GET_KEY(y)));
+
+ ERTS_RBT_FUNC__(replace__)(root, x, y);
+}
+
+#endif /* ERTS_RBT_WANT_REPLACE */
+
+#ifdef ERTS_RBT_WANT_DELETE
+
+/*
+ * Delete a node.
+ */
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(delete)(ERTS_RBT_T **root, ERTS_RBT_T *n)
+{
+ int spliced_is_black;
+ ERTS_RBT_T *p, *x, *y, *z = n;
+ ERTS_RBT_T null_x; /* null_x is used to get the fixup started when we
+ splice out a node without children. */
+
+ ERTS_RBT_HDBG_CHECK_TREE__(*root);
+
+ ERTS_RBT_INIT_EMPTY_TNODE(&null_x);
+
+ /* Remove node from tree... */
+
+ /* Find node to splice out */
+ if (!ERTS_RBT_GET_LEFT(z) || !ERTS_RBT_GET_RIGHT(z))
+ y = z;
+ else {
+ /* Set y to z:s successor */
+ y = ERTS_RBT_GET_RIGHT(z);
+ while (1) {
+ ERTS_RBT_T *t = ERTS_RBT_GET_LEFT(y);
+ if (!t)
+ break;
+ y = t;
+ }
+ }
+ /* splice out y */
+ x = ERTS_RBT_GET_LEFT(y);
+ if (!x)
+ x = ERTS_RBT_GET_RIGHT(y);
+ spliced_is_black = ERTS_RBT_IS_BLACK(y);
+ p = ERTS_RBT_GET_PARENT(y);
+ if (x)
+ ERTS_RBT_SET_PARENT(x, p);
+ else if (spliced_is_black) {
+ x = &null_x;
+ ERTS_RBT_SET_BLACK(x);
+ ERTS_RBT_SET_PARENT(x, p);
+ ERTS_RBT_SET_LEFT(y, x);
+ }
+
+ if (!p) {
+ ERTS_RBT_ASSERT(*root == y);
+ *root = x;
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+ ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(y, x);
+#endif
+ }
+ else {
+ if (y == ERTS_RBT_GET_LEFT(p))
+ ERTS_RBT_SET_LEFT(p, x);
+ else {
+ ERTS_RBT_ASSERT(y == ERTS_RBT_GET_RIGHT(p));
+ ERTS_RBT_SET_RIGHT(p, x);
+ }
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_DMOD
+ if (p != z)
+ ERTS_RBT_UPDATE_ATTACHED_DATA_DMOD(p, y == z ? NULL : z);
+#endif
+ }
+ if (y != z) {
+ /* We spliced out the successor of z; replace z by the successor */
+ ERTS_RBT_FUNC__(replace__)(root, z, y);
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_DMOD
+ ERTS_RBT_UPDATE_ATTACHED_DATA_DMOD(y, NULL);
+#endif
+ }
+
+ if (spliced_is_black) {
+ /* We removed a black node which makes the resulting tree
+ violate the Red-Black Tree properties. Fixup tree... */
+
+ p = ERTS_RBT_GET_PARENT(x);
+ while (ERTS_RBT_IS_BLACK(x) && p) {
+ ERTS_RBT_T *r, *l;
+
+ /*
+ * x has an "extra black" which we move up the tree
+ * until we reach the root or until we can get rid of it.
+ *
+ * y is the sibbling of x, and p is their parent
+ */
+
+ if (x == ERTS_RBT_GET_LEFT(p)) {
+ y = ERTS_RBT_GET_RIGHT(p);
+
+ ERTS_RBT_ASSERT(y);
+
+ if (ERTS_RBT_IS_RED(y)) {
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_RIGHT(y));
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_LEFT(y));
+
+ ERTS_RBT_SET_BLACK(y);
+
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(p));
+
+ ERTS_RBT_SET_RED(p);
+ ERTS_RBT_FUNC__(left_rotate__)(root, p);
+ p = ERTS_RBT_GET_PARENT(x);
+ y = ERTS_RBT_GET_RIGHT(p);
+ }
+
+ ERTS_RBT_ASSERT(y);
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(y));
+
+ l = ERTS_RBT_GET_LEFT(y);
+ r = ERTS_RBT_GET_RIGHT(y);
+ if ((!l || ERTS_RBT_IS_BLACK(l))
+ && (!r || ERTS_RBT_IS_BLACK(r))) {
+ ERTS_RBT_SET_RED(y);
+ x = p;
+ p = ERTS_RBT_GET_PARENT(x);
+ }
+ else {
+ if (!r || ERTS_RBT_IS_BLACK(r)) {
+ ERTS_RBT_SET_BLACK(l);
+ ERTS_RBT_SET_RED(y);
+ ERTS_RBT_FUNC__(right_rotate__)(root, y);
+ p = ERTS_RBT_GET_PARENT(x);
+ y = ERTS_RBT_GET_RIGHT(p);
+ }
+
+ ERTS_RBT_ASSERT(y);
+
+ if (p && ERTS_RBT_IS_RED(p)) {
+
+ ERTS_RBT_SET_BLACK(p);
+ ERTS_RBT_SET_RED(y);
+ }
+
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_RIGHT(y));
+
+ ERTS_RBT_SET_BLACK(ERTS_RBT_GET_RIGHT(y));
+ ERTS_RBT_FUNC__(left_rotate__)(root, p);
+ x = *root;
+ break;
+ }
+ }
+ else {
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_RIGHT(p));
+
+ y = ERTS_RBT_GET_LEFT(p);
+
+ ERTS_RBT_ASSERT(y);
+
+ if (ERTS_RBT_IS_RED(y)) {
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_RIGHT(y));
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_LEFT(y));
+
+ ERTS_RBT_SET_BLACK(y);
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(p));
+ ERTS_RBT_SET_RED(p);
+ ERTS_RBT_FUNC__(right_rotate__)(root, p);
+
+ p = ERTS_RBT_GET_PARENT(x);
+ y = ERTS_RBT_GET_LEFT(p);
+ }
+
+ ERTS_RBT_ASSERT(y);
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(y));
+
+ l = ERTS_RBT_GET_LEFT(y);
+ r = ERTS_RBT_GET_RIGHT(y);
+
+ if ((!r || ERTS_RBT_IS_BLACK(r))
+ && (!l || ERTS_RBT_IS_BLACK(l))) {
+ ERTS_RBT_SET_RED(y);
+ x = p;
+ p = ERTS_RBT_GET_PARENT(x);
+ }
+ else {
+ if (!l || ERTS_RBT_IS_BLACK(l)) {
+ ERTS_RBT_SET_BLACK(r);
+ ERTS_RBT_SET_RED(y);
+ ERTS_RBT_FUNC__(left_rotate__)(root, y);
+
+ p = ERTS_RBT_GET_PARENT(x);
+ y = ERTS_RBT_GET_LEFT(p);
+ }
+
+ ERTS_RBT_ASSERT(y);
+
+ if (p && ERTS_RBT_IS_RED(p)) {
+ ERTS_RBT_SET_BLACK(p);
+ ERTS_RBT_SET_RED(y);
+ }
+
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_LEFT(y));
+
+ ERTS_RBT_SET_BLACK(ERTS_RBT_GET_LEFT(y));
+ ERTS_RBT_FUNC__(right_rotate__)(root, p);
+ x = *root;
+ break;
+ }
+ }
+ }
+
+ ERTS_RBT_SET_BLACK(x);
+
+ x = &null_x;
+ p = ERTS_RBT_GET_PARENT(x);
+
+ if (p) {
+ if (ERTS_RBT_GET_LEFT(p) == x)
+ ERTS_RBT_SET_LEFT(p, NULL);
+ else {
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_RIGHT(p) == x);
+ ERTS_RBT_SET_RIGHT(p, NULL);
+ }
+
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_LEFT(x));
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_RIGHT(x));
+ }
+ else if (*root == x) {
+ *root = NULL;
+
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+ ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(x, NULL);
+#endif
+
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_LEFT(x));
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_RIGHT(x));
+ }
+ }
+
+ ERTS_RBT_HDBG_CHECK_TREE__(*root);
+
+}
+
+#endif /* ERTS_RBT_WANT_DELETE */
+
+#ifdef ERTS_RBT_NEED_INSERT__
+
+static void
+ERTS_RBT_FUNC__(insert_fixup__)(ERTS_RBT_T **root, ERTS_RBT_T *n)
+{
+ ERTS_RBT_T *x, *y;
+
+ x = n;
+
+ /*
+ * Rearrange the tree so that it satisfies the Red-Black Tree properties
+ */
+
+ ERTS_RBT_ASSERT(x != *root && ERTS_RBT_IS_RED(ERTS_RBT_GET_PARENT(x)));
+ do {
+ ERTS_RBT_T *p, *pp;
+
+ /*
+ * x and its parent are both red. Move the red pair up the tree
+ * until we get to the root or until we can separate them.
+ */
+
+ p = ERTS_RBT_GET_PARENT(x);
+ pp = ERTS_RBT_GET_PARENT(p);
+
+ ERTS_RBT_ASSERT(p && pp);
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(x));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(pp));
+
+ if (p == ERTS_RBT_GET_LEFT(pp)) {
+ y = ERTS_RBT_GET_RIGHT(pp);
+ if (y && ERTS_RBT_IS_RED(y)) {
+ ERTS_RBT_SET_BLACK(y);
+ ERTS_RBT_SET_BLACK(p);
+ ERTS_RBT_SET_RED(pp);
+ x = pp;
+ }
+ else {
+
+ if (x == ERTS_RBT_GET_RIGHT(p)) {
+ x = p;
+ ERTS_RBT_FUNC__(left_rotate__)(root, x);
+ p = ERTS_RBT_GET_PARENT(x);
+ pp = ERTS_RBT_GET_PARENT(p);
+
+ ERTS_RBT_ASSERT(p && pp);
+ }
+
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_LEFT(ERTS_RBT_GET_LEFT(pp)));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(x));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(p));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(pp));
+ ERTS_RBT_ASSERT(!y || ERTS_RBT_IS_BLACK(y));
+
+
+ ERTS_RBT_SET_BLACK(p);
+ ERTS_RBT_SET_RED(pp);
+ ERTS_RBT_FUNC__(right_rotate__)(root, pp);
+
+
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_LEFT(ERTS_RBT_GET_PARENT(x)) == x);
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(x));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(
+ ERTS_RBT_GET_RIGHT(
+ ERTS_RBT_GET_PARENT(x))));
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_PARENT(x)
+ || ERTS_RBT_IS_BLACK(ERTS_RBT_GET_PARENT(x)));
+ break;
+ }
+ }
+ else {
+ ERTS_RBT_ASSERT(p == ERTS_RBT_GET_RIGHT(pp));
+
+ y = ERTS_RBT_GET_LEFT(pp);
+ if (y && ERTS_RBT_IS_RED(y)) {
+ ERTS_RBT_SET_BLACK(y);
+ ERTS_RBT_SET_BLACK(p);
+ ERTS_RBT_SET_RED(pp);
+ x = pp;
+ }
+ else {
+
+ if (x == ERTS_RBT_GET_LEFT(p)) {
+ x = p;
+ ERTS_RBT_FUNC__(right_rotate__)(root, x);
+ p = ERTS_RBT_GET_PARENT(x);
+ pp = ERTS_RBT_GET_PARENT(p);
+
+ ERTS_RBT_ASSERT(p && pp);
+ }
+
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_RIGHT(ERTS_RBT_GET_RIGHT(pp)));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(x));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(p));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_BLACK(pp));
+ ERTS_RBT_ASSERT(!y || ERTS_RBT_IS_BLACK(y));
+
+
+ ERTS_RBT_SET_BLACK(p);
+ ERTS_RBT_SET_RED(pp);
+ ERTS_RBT_FUNC__(left_rotate__)(root, pp);
+
+
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_RIGHT(ERTS_RBT_GET_PARENT(x)) == x);
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(x));
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_RED(
+ ERTS_RBT_GET_LEFT(
+ ERTS_RBT_GET_PARENT(x))));
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_PARENT(x)
+ || ERTS_RBT_IS_BLACK(ERTS_RBT_GET_PARENT(x)));
+ break;
+ }
+ }
+ } while (x != *root && ERTS_RBT_IS_RED(ERTS_RBT_GET_PARENT(x)));
+
+ ERTS_RBT_SET_BLACK(*root);
+
+}
+
+static ERTS_INLINE ERTS_RBT_T *
+ERTS_RBT_FUNC__(insert_aux__)(ERTS_RBT_T **root, ERTS_RBT_T *n, int lookup)
+{
+ ERTS_RBT_KEY_T kn = ERTS_RBT_GET_KEY(n);
+
+ ERTS_RBT_HDBG_CHECK_TREE__(*root);
+
+ ERTS_RBT_INIT_EMPTY_TNODE(n);
+
+ if (!*root) {
+ ERTS_RBT_SET_BLACK(n);
+ *root = n;
+#ifdef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+ ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT(NULL, n);
+#endif
+ }
+ else {
+ ERTS_RBT_T *p, *x = *root;
+
+ while (1) {
+ ERTS_RBT_KEY_T kx;
+ ERTS_RBT_T *c;
+
+ kx = ERTS_RBT_GET_KEY(x);
+
+ if (lookup && ERTS_RBT_IS_EQ(kn, kx)) {
+
+ ERTS_RBT_HDBG_CHECK_TREE__(*root);
+
+ return x;
+ }
+
+ if (ERTS_RBT_IS_LT(kn, kx)) {
+ c = ERTS_RBT_GET_LEFT(x);
+ if (!c) {
+ ERTS_RBT_SET_PARENT(n, x);
+ ERTS_RBT_SET_LEFT(x, n);
+ p = x;
+ break;
+ }
+ }
+ else {
+ c = ERTS_RBT_GET_RIGHT(x);
+ if (!c) {
+ ERTS_RBT_SET_PARENT(n, x);
+ ERTS_RBT_SET_RIGHT(x, n);
+ p = x;
+ break;
+ }
+ }
+
+ x = c;
+ }
+
+ ERTS_RBT_ASSERT(p);
+
+ ERTS_RBT_SET_RED(n);
+ if (ERTS_RBT_IS_RED(p))
+ ERTS_RBT_FUNC__(insert_fixup__)(root, n);
+ }
+
+ ERTS_RBT_HDBG_CHECK_TREE__(*root);
+
+ return NULL;
+}
+
+#endif /* ERTS_RBT_NEED_INSERT__ */
+
+#ifdef ERTS_RBT_WANT_LOOKUP_INSERT
+
+static ERTS_RBT_API_INLINE__ ERTS_RBT_T *
+ERTS_RBT_FUNC__(lookup_insert)(ERTS_RBT_T **root, ERTS_RBT_T *n)
+{
+ return ERTS_RBT_FUNC__(insert_aux__)(root, n, !0);
+}
+
+#endif /* ERTS_RBT_WANT_LOOKUP_INSERT */
+
+#ifdef ERTS_RBT_WANT_INSERT
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(insert)(ERTS_RBT_T **root, ERTS_RBT_T *n)
+{
+ (void) ERTS_RBT_FUNC__(insert_aux__)(root, n, 0);
+}
+
+#endif /* ERTS_RBT_WANT_INSERT */
+
+#ifdef ERTS_RBT_WANT_LOOKUP
+
+static ERTS_RBT_API_INLINE__ ERTS_RBT_T *
+ERTS_RBT_FUNC__(lookup)(ERTS_RBT_T *root, ERTS_RBT_KEY_T key)
+{
+ ERTS_RBT_T *x = root;
+
+ if (!x)
+ return NULL;
+
+ while (1) {
+ ERTS_RBT_KEY_T kx = ERTS_RBT_GET_KEY(x);
+ ERTS_RBT_T *c;
+
+ if (ERTS_RBT_IS_EQ(key, kx))
+ return x;
+
+ if (ERTS_RBT_IS_LT(key, kx)) {
+ c = ERTS_RBT_GET_LEFT(x);
+ if (!c)
+ return NULL;
+ }
+ else {
+ c = ERTS_RBT_GET_RIGHT(x);
+ if (!c)
+ return NULL;
+ }
+
+ x = c;
+ }
+}
+
+#endif /* ERTS_RBT_WANT_LOOKUP */
+
+#ifdef ERTS_RBT_WANT_SMALLEST
+
+static ERTS_RBT_API_INLINE__ ERTS_RBT_T *
+ERTS_RBT_FUNC__(smallest)(ERTS_RBT_T *root)
+{
+ ERTS_RBT_T *x = root;
+
+ if (!x)
+ return NULL;
+
+ while (1) {
+ ERTS_RBT_T *c = ERTS_RBT_GET_LEFT(x);
+ if (!c)
+ break;
+ x = c;
+ }
+
+ return x;
+}
+
+#endif /* ERTS_RBT_WANT_SMALLEST */
+
+#ifdef ERTS_RBT_WANT_LARGEST
+
+static ERTS_RBT_API_INLINE__ ERTS_RBT_T *
+ERTS_RBT_FUNC__(largest)(ERTS_RBT_T *root)
+{
+ ERTS_RBT_T *x = root;
+
+ if (!x)
+ return NULL;
+
+ while (1) {
+ ERTS_RBT_T *c = ERTS_RBT_GET_RIGHT(x);
+ if (!c)
+ break;
+ x = c;
+ }
+
+ return x;
+}
+
+#endif /* ERTS_RBT_WANT_LARGEST */
+
+#ifdef ERTS_RBT_NEED_FOREACH_UNORDERED__
+
+static ERTS_INLINE int
+ERTS_RBT_FUNC__(foreach_unordered__)(ERTS_RBT_T **root,
+ int destroying,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg,
+ int yielding,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ ERTS_RBT_T *c, *p, *x;
+
+ ERTS_RBT_ASSERT(!yielding || ystate);
+
+ if (yielding && ystate->x) {
+ x = ystate->x;
+ ERTS_RBT_ASSERT(ystate->up);
+ goto restart_up;
+ }
+ else {
+ x = *root;
+ if (!x)
+ return 0;
+ if (destroying)
+ *root = NULL;
+ }
+
+ while (1) {
+
+ while (1) {
+
+ while (1) {
+ c = ERTS_RBT_GET_LEFT(x);
+ if (!c)
+ break;
+ x = c;
+ }
+
+ c = ERTS_RBT_GET_RIGHT(x);
+ if (!c)
+ break;
+ x = c;
+ }
+
+ while (1) {
+#ifdef ERTS_RBT_DEBUG
+ int cdir;
+#endif
+ if (yielding && ylimit-- <= 0) {
+ ystate->x = x;
+ ystate->up = 1;
+ return 1;
+ }
+
+ restart_up:
+
+ p = ERTS_RBT_GET_PARENT(x);
+
+#ifdef ERTS_RBT_DEBUG
+ ERTS_RBT_ASSERT(!destroying || !ERTS_RBT_GET_LEFT(x));
+ ERTS_RBT_ASSERT(!destroying || !ERTS_RBT_GET_RIGHT(x));
+
+ if (p) {
+ if (x == ERTS_RBT_GET_LEFT(p)) {
+ cdir = -1;
+ if (destroying)
+ ERTS_RBT_SET_LEFT(p, NULL);
+ }
+ else {
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_RIGHT(p));
+ cdir = 1;
+ if (destroying)
+ ERTS_RBT_SET_RIGHT(p, NULL);
+ }
+ }
+#endif
+
+ (*op)(x, arg);
+
+ if (!p) {
+ if (yielding) {
+ ystate->x = NULL;
+ ystate->up = 0;
+ }
+ return 0; /* Done */
+ }
+
+ c = ERTS_RBT_GET_RIGHT(p);
+ if (c && c != x) {
+ ERTS_RBT_ASSERT(cdir < 0);
+
+ /* Go down tree of x's sibling... */
+ x = c;
+ break;
+ }
+
+ x = p;
+ }
+ }
+}
+
+#endif /* ERTS_RBT_NEED_FOREACH_UNORDERED__ */
+
+#ifdef ERTS_RBT_NEED_FOREACH_ORDERED__
+
+static ERTS_INLINE int
+ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root,
+ int from_small,
+ int destroying,
+ void (*op)(ERTS_RBT_T *, void *),
+ void (*destroy)(ERTS_RBT_T *, void *),
+ void *arg,
+ int yielding,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ ERTS_RBT_T *c, *p, *x;
+
+ ERTS_RBT_ASSERT(!yielding || ystate);
+ ERTS_RBT_ASSERT(!destroying || destroy);
+
+ if (yielding && ystate->x) {
+ x = ystate->x;
+ if (ystate->up)
+ goto restart_up;
+ else
+ goto restart_down;
+ }
+ else {
+ x = *root;
+ if (!x)
+ return 0;
+ if (destroying)
+ *root = NULL;
+ }
+
+ while (1) {
+
+ while (1) {
+
+ while (1) {
+ c = from_small ? ERTS_RBT_GET_LEFT(x) : ERTS_RBT_GET_RIGHT(x);
+ if (!c)
+ break;
+ x = c;
+ }
+
+ (*op)(x, arg);
+
+ if (yielding && --ylimit <= 0) {
+ ystate->x = x;
+ ystate->up = 0;
+ return 1;
+ }
+
+ restart_down:
+
+ c = from_small ? ERTS_RBT_GET_RIGHT(x) : ERTS_RBT_GET_LEFT(x);
+ if (!c)
+ break;
+ x = c;
+ }
+
+ while (1) {
+ p = ERTS_RBT_GET_PARENT(x);
+
+ if (p) {
+
+ c = from_small ? ERTS_RBT_GET_RIGHT(p) : ERTS_RBT_GET_LEFT(p);
+ if (!c || c != x) {
+ ERTS_RBT_ASSERT((from_small
+ ? ERTS_RBT_GET_LEFT(p)
+ : ERTS_RBT_GET_RIGHT(p)) == x);
+
+ (*op)(p, arg);
+
+ if (yielding && --ylimit <= 0) {
+ ystate->x = x;
+ ystate->up = 1;
+ return 1;
+ restart_up:
+ p = ERTS_RBT_GET_PARENT(x);
+ }
+ }
+
+ if (c && c != x) {
+ ERTS_RBT_ASSERT((from_small
+ ? ERTS_RBT_GET_LEFT(p)
+ : ERTS_RBT_GET_RIGHT(p)) == x);
+
+ /* Go down tree of x's sibling... */
+ x = c;
+ break;
+ }
+ }
+
+ if (destroying) {
+
+#ifdef ERTS_RBT_DEBUG
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_LEFT(x)
+ && !ERTS_RBT_GET_RIGHT(x));
+
+ if (p) {
+ if (x == ERTS_RBT_GET_LEFT(p))
+ ERTS_RBT_SET_LEFT(p, NULL);
+ else {
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_RIGHT(p));
+ ERTS_RBT_SET_RIGHT(p, NULL);
+ }
+ }
+#endif
+
+ (*destroy)(x, arg);
+ }
+
+ if (!p) {
+ if (yielding) {
+ ystate->x = NULL;
+ ystate->up = 0;
+ }
+ return 1; /* Done */
+ }
+ x = p;
+ }
+ }
+}
+
+#endif /* ERTS_RBT_NEED_FOREACH_ORDERED__ */
+
+#ifdef ERTS_RBT_WANT_FOREACH
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach)(ERTS_RBT_T *root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg)
+{
+ (void) ERTS_RBT_FUNC__(foreach_unordered__)(&root, 0, op, arg,
+ 0, NULL, 0);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH */
+
+#ifdef ERTS_RBT_WANT_FOREACH_SMALL
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach_small)(ERTS_RBT_T *root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg)
+{
+ (void) ERTS_RBT_FUNC__(foreach_ordered__)(&root, 1, 0,
+ op, NULL, arg,
+ 0, NULL, 0);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_SMALL */
+
+#ifdef ERTS_RBT_WANT_FOREACH_LARGE
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach_large)(ERTS_RBT_T *root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg)
+{
+ (void) ERTS_RBT_FUNC__(foreach_ordered__)(&root, 0, 0,
+ op, NULL, arg,
+ 0, NULL, 0);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_LARGE */
+
+#ifdef ERTS_RBT_WANT_FOREACH_YIELDING
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach_yielding)(ERTS_RBT_T *root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ (void) ERTS_RBT_FUNC__(foreach_unordered__)(*root, 0, op, arg,
+ 1, ystate, ylimit);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_YIELDING */
+
+#ifdef ERTS_RBT_WANT_FOREACH_SMALL_YIELDING
+
+static ERTS_RBT_API_INLINE__ int
+ERTS_RBT_FUNC__(foreach_small_yielding)(ERTS_RBT_T *root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ return ERTS_RBT_FUNC__(foreach_ordered__)(&root, 1, 0,
+ op, NULL, arg,
+ 1, ystate, ylimit);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_SMALL_YIELDING */
+
+#ifdef ERTS_RBT_WANT_FOREACH_LARGE_YIELDING
+
+static ERTS_RBT_API_INLINE__ int
+ERTS_RBT_FUNC__(foreach_large_yielding)(ERTS_RBT_T *root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ return ERTS_RBT_FUNC__(foreach_ordered__)(&root, 0, 0,
+ op, NULL, arg,
+ 1, ystate, ylimit);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_LARGE_YIELDING */
+
+#ifdef ERTS_RBT_WANT_FOREACH_DESTROY
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach_destroy)(ERTS_RBT_T **root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg)
+{
+ (void) ERTS_RBT_FUNC__(foreach_unordered__)(root, 1, op, arg,
+ 0, NULL, 0);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_DESTROY */
+
+#ifdef ERTS_RBT_WANT_FOREACH_SMALL_DESTROY
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach_small_destroy)(ERTS_RBT_T **root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void (*destr)(ERTS_RBT_T *, void *),
+ void *arg)
+{
+ (void) ERTS_RBT_FUNC__(foreach_ordered__)(root, 1, 1,
+ op, destr, arg,
+ 0, NULL, 0);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_SMALL_DESTROY */
+
+#ifdef ERTS_RBT_WANT_FOREACH_LARGE_DESTROY
+
+static ERTS_RBT_API_INLINE__ void
+ERTS_RBT_FUNC__(foreach_large_destroy)(ERTS_RBT_T **root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void (*destr)(ERTS_RBT_T *, void *),
+ void *arg)
+{
+ (void) ERTS_RBT_FUNC__(foreach_ordered__)(root, 0, 1,
+ op, destr, arg,
+ 0, NULL, 0);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_LARGE_DESTROY */
+
+#ifdef ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING
+
+static ERTS_RBT_API_INLINE__ int
+ERTS_RBT_FUNC__(foreach_destroy_yielding)(ERTS_RBT_T **root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void *arg,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ return ERTS_RBT_FUNC__(foreach_unordered__)(root, 1, op, arg,
+ 1, ystate, ylimit);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING */
+
+#ifdef ERTS_RBT_WANT_FOREACH_SMALL_DESTROY_YIELDING
+
+static ERTS_RBT_API_INLINE__ int
+ERTS_RBT_FUNC__(foreach_small_destroy_yielding)(ERTS_RBT_T **root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void (*destr)(ERTS_RBT_T *, void *),
+ void *arg,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ return ERTS_RBT_FUNC__(foreach_ordered__)(root, 1, 1,
+ op, destr, arg,
+ 1, ystate, ylimit);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_SMALL_DESTROY_YIELDING */
+
+#ifdef ERTS_RBT_WANT_FOREACH_LARGE_DESTROY_YIELDING
+
+static ERTS_RBT_API_INLINE__ int
+ERTS_RBT_FUNC__(foreach_large_destroy_yielding)(ERTS_RBT_T **root,
+ void (*op)(ERTS_RBT_T *, void *),
+ void (*destr)(ERTS_RBT_T *, void *),
+ void *arg,
+ ERTS_RBT_YIELD_STATE_T__ *ystate,
+ Sint ylimit)
+{
+ return ERTS_RBT_FUNC__(foreach_ordered__)(root, 0, 1,
+ op, destr, arg,
+ 1, ystate, ylimit);
+}
+
+#endif /* ERTS_RBT_WANT_FOREACH_LARGE_DESTROY_YIELDING */
+
+#ifdef ERTS_RBT_WANT_DEBUG_PRINT
+
+static void
+ERTS_RBT_FUNC__(debug_print)(FILE *filep, ERTS_RBT_T *x, int indent,
+ void (*print_node)(ERTS_RBT_T *))
+{
+ if (x) {
+ ERTS_RBT_FUNC__(debug_print)(filep, ERTS_RBT_GET_RIGHT(x),
+ indent+2, print_node);
+ erts_fprintf(filep,
+ "%*s[%s:%p:",
+ indent, "",
+ ERTS_RBT_IS_BLACK(x) ? "Black" : "Red",
+ x);
+ (*print_node)(x);
+ erts_fprintf(filep, "]\n");
+ ERTS_RBT_FUNC__(debug_print)(filep, ERTS_RBT_GET_LEFT(x),
+ indent+2, print_node);
+ }
+}
+
+#endif /* ERTS_RBT_WANT_DEBUG_PRINT */
+
+#ifdef ERTS_RBT_NEED_HDBG_CHECK_TREE__
+
+static void
+ERTS_RBT_FUNC__(hdbg_check_tree)(ERTS_RBT_T *root)
+{
+ int black_depth = -1, no_black = 0;
+ ERTS_RBT_T *c, *p, *x = root;
+ ERTS_RBT_KEY_T kx;
+ ERTS_RBT_KEY_T kc;
+
+ if (!x)
+ return;
+
+ ERTS_RBT_ASSERT(!ERTS_RBT_GET_PARENT(x));
+
+ while (1) {
+
+ while (1) {
+
+ while (1) {
+
+ if (ERTS_RBT_IS_BLACK(x))
+ no_black++;
+ else {
+ c = ERTS_RBT_GET_RIGHT(x);
+ ERTS_RBT_ASSERT(!c || ERTS_RBT_IS_BLACK(c));
+ c = ERTS_RBT_GET_LEFT(x);
+ ERTS_RBT_ASSERT(!c || ERTS_RBT_IS_BLACK(c));
+ }
+
+ c = ERTS_RBT_GET_LEFT(x);
+ if (!c)
+ break;
+
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_PARENT(c));
+
+ kx = ERTS_RBT_GET_KEY(x);
+ kc = ERTS_RBT_GET_KEY(c);
+
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_LT(kc, kx)
+ || ERTS_RBT_IS_EQ(kc, kx));
+
+ x = c;
+ }
+
+ c = ERTS_RBT_GET_RIGHT(x);
+ if (!c) {
+ if (black_depth < 0)
+ black_depth = no_black;
+ ERTS_RBT_ASSERT(black_depth == no_black);
+ break;
+ }
+
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_PARENT(c));
+
+ kx = ERTS_RBT_GET_KEY(x);
+ kc = ERTS_RBT_GET_KEY(c);
+
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_LT(kx, kc)
+ || ERTS_RBT_IS_EQ(kx, kc));
+ x = c;
+ }
+
+ while (1) {
+ p = ERTS_RBT_GET_PARENT(x);
+
+ if (ERTS_RBT_IS_BLACK(x))
+ no_black--;
+
+ if (p) {
+
+ ERTS_RBT_ASSERT(x == ERTS_RBT_GET_LEFT(p)
+ || x == ERTS_RBT_GET_RIGHT(p));
+
+ c = ERTS_RBT_GET_RIGHT(p);
+ if (c && c != x) {
+ ERTS_RBT_ASSERT(ERTS_RBT_GET_LEFT(p) == x);
+
+ kx = ERTS_RBT_GET_KEY(x);
+ kc = ERTS_RBT_GET_KEY(c);
+
+ ERTS_RBT_ASSERT(ERTS_RBT_IS_LT(kx, kc)
+ || ERTS_RBT_IS_EQ(kx, kc));
+ /* Go down tree of x's sibling... */
+ x = c;
+ break;
+ }
+ }
+
+ if (!p) {
+ ERTS_RBT_ASSERT(root == x);
+ ERTS_RBT_ASSERT(no_black == 0);
+ return; /* Done */
+ }
+
+ x = p;
+ }
+ }
+}
+
+#undef ERTS_RBT_PRINT_TREE__
+
+#endif /* ERTS_RBT_NEED_HDBG_CHECK_TREE__ */
+
+#undef ERTS_RBT_ASSERT
+#undef ERTS_RBT_DEBUG
+#undef ERTS_RBT_API_INLINE__
+#undef ERTS_RBT_YIELD_STATE_T__
+#undef ERTS_RBT_NEED_REPLACE__
+#undef ERTS_RBT_NEED_INSERT__
+#undef ERTS_RBT_NEED_ROTATE__
+#undef ERTS_RBT_NEED_FOREACH_UNORDERED__
+#undef ERTS_RBT_NEED_FOREACH_ORDERED__
+#undef ERTS_RBT_NEED_HDBG_CHECK_TREE__
+#undef ERTS_RBT_HDBG_CHECK_TREE__
+
+#ifdef ERTS_RBT_UNDEF
+# undef ERTS_RBT_PREFIX
+# undef ERTS_RBT_T
+# undef ERTS_RBT_KEY_T
+# undef ERTS_RBT_FLAGS_T
+# undef ERTS_RBT_INIT_EMPTY_TNODE
+# undef ERTS_RBT_IS_RED
+# undef ERTS_RBT_SET_RED
+# undef ERTS_RBT_IS_BLACK
+# undef ERTS_RBT_SET_BLACK
+# undef ERTS_RBT_GET_FLAGS
+# undef ERTS_RBT_SET_FLAGS
+# undef ERTS_RBT_GET_PARENT
+# undef ERTS_RBT_SET_PARENT
+# undef ERTS_RBT_GET_RIGHT
+# undef ERTS_RBT_SET_RIGHT
+# undef ERTS_RBT_GET_LEFT
+# undef ERTS_RBT_SET_LEFT
+# undef ERTS_RBT_GET_KEY
+# undef ERTS_RBT_IS_LT
+# undef ERTS_RBT_IS_EQ
+# undef ERTS_RBT_UNDEF
+# undef ERTS_RBT_NO_API_INLINE
+# undef ERTS_RBT_UPDATE_ATTACHED_DATA_ROTATE
+# undef ERTS_RBT_UPDATE_ATTACHED_DATA_DMOD
+# undef ERTS_RBT_UPDATE_ATTACHED_DATA_CHGROOT
+# undef ERTS_RBT_WANT_DELETE
+# undef ERTS_RBT_WANT_INSERT
+# undef ERTS_RBT_WANT_LOOKUP_INSERT
+# undef ERTS_RBT_WANT_REPLACE
+# undef ERTS_RBT_WANT_LOOKUP
+# undef ERTS_RBT_WANT_SMALLEST
+# undef ERTS_RBT_WANT_LARGEST
+# undef ERTS_RBT_WANT_FOREACH
+# undef ERTS_RBT_WANT_FOREACH_DESTROY
+# undef ERTS_RBT_WANT_FOREACH_YIELDING
+# undef ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING
+# undef ERTS_RBT_WANT_FOREACH_SMALL
+# undef ERTS_RBT_WANT_FOREACH_LARGE
+# undef ERTS_RBT_WANT_FOREACH_SMALL_DESTROY
+# undef ERTS_RBT_WANT_FOREACH_LARGE_DESTROY
+# undef ERTS_RBT_WANT_FOREACH_SMALL_YIELDING
+# undef ERTS_RBT_WANT_FOREACH_LARGE_YIELDING
+# undef ERTS_RBT_WANT_FOREACH_SMALL_DESTROY_YIELDING
+# undef ERTS_RBT_WANT_FOREACH_LARGE_DESTROY_YIELDING
+# undef ERTS_RBT_WANT_DEBUG_PRINT
+#endif
diff --git a/erts/emulator/beam/erl_sched_spec_pre_alloc.c b/erts/emulator/beam/erl_sched_spec_pre_alloc.c
index a490aec734..caec24bc03 100644
--- a/erts/emulator/beam/erl_sched_spec_pre_alloc.c
+++ b/erts/emulator/beam/erl_sched_spec_pre_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_sched_spec_pre_alloc.h b/erts/emulator/beam/erl_sched_spec_pre_alloc.h
index 9144c73acd..4d07b0f674 100644
--- a/erts/emulator/beam/erl_sched_spec_pre_alloc.h
+++ b/erts/emulator/beam/erl_sched_spec_pre_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_smp.h b/erts/emulator/beam/erl_smp.h
index 6c40edeb3e..5fc5e989a6 100644
--- a/erts/emulator/beam/erl_smp.h
+++ b/erts/emulator/beam/erl_smp.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_sock.h b/erts/emulator/beam/erl_sock.h
index 7ae6116dc5..7be6062115 100644
--- a/erts/emulator/beam/erl_sock.h
+++ b/erts/emulator/beam/erl_sock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_sys_driver.h b/erts/emulator/beam/erl_sys_driver.h
index dab4a94a9b..4031eef0aa 100644
--- a/erts/emulator/beam/erl_sys_driver.h
+++ b/erts/emulator/beam/erl_sys_driver.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c
index 28cbe7004f..bae3385d3f 100644
--- a/erts/emulator/beam/erl_term.c
+++ b/erts/emulator/beam/erl_term.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -40,7 +41,7 @@ et_abort(const char *expr, const char *file, unsigned line)
* Prevent infinite loop.
*/
have_been_called = 1;
- erl_exit(1, "TYPE ASSERTION FAILED, file %s, line %u: %s\n", file, line, expr);
+ erts_exit(ERTS_ERROR_EXIT, "TYPE ASSERTION FAILED, file %s, line %u: %s\n", file, line, expr);
}
#else
erts_fprintf(stderr, "TYPE ASSERTION FAILED, file %s, line %u: %s\n", file, line, expr);
@@ -86,11 +87,13 @@ unsigned tag_val_def(Wterm x)
case (_TAG_HEADER_EXTERNAL_PID >> _TAG_PRIMARY_SIZE): return EXTERNAL_PID_DEF;
case (_TAG_HEADER_EXTERNAL_PORT >> _TAG_PRIMARY_SIZE): return EXTERNAL_PORT_DEF;
case (_TAG_HEADER_EXTERNAL_REF >> _TAG_PRIMARY_SIZE): return EXTERNAL_REF_DEF;
+ case (_TAG_HEADER_MAP >> _TAG_PRIMARY_SIZE): return MAP_DEF;
case (_TAG_HEADER_REFC_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF;
case (_TAG_HEADER_HEAP_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF;
case (_TAG_HEADER_SUB_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF;
- case (_TAG_HEADER_MAP >> _TAG_PRIMARY_SIZE): return MAP_DEF;
+ case (_TAG_HEADER_BIN_MATCHSTATE >> _TAG_PRIMARY_SIZE): return MATCHSTATE_DEF;
}
+
break;
}
case TAG_PRIMARY_IMMED1: {
@@ -127,10 +130,10 @@ FUNTY checked_##FUN(ARGTY x, const char *file, unsigned line) \
return _unchecked_##FUN(x); \
}
-ET_DEFINE_CHECKED(Eterm,make_boxed,Eterm*,_is_taggable_pointer);
+ET_DEFINE_CHECKED(Eterm,make_boxed,const Eterm*,_is_taggable_pointer);
ET_DEFINE_CHECKED(int,is_boxed,Eterm,!is_header);
ET_DEFINE_CHECKED(Eterm*,boxed_val,Wterm,_boxed_precond);
-ET_DEFINE_CHECKED(Eterm,make_list,Eterm*,_is_taggable_pointer);
+ET_DEFINE_CHECKED(Eterm,make_list,const Eterm*,_is_taggable_pointer);
ET_DEFINE_CHECKED(int,is_not_list,Eterm,!is_header);
ET_DEFINE_CHECKED(Eterm*,list_val,Wterm,_list_precond);
ET_DEFINE_CHECKED(Uint,unsigned_val,Eterm,is_small);
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index 37014ccf94..d5e91d80d9 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -147,21 +148,21 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#define MAP_SUBTAG (0xF << _TAG_PRIMARY_SIZE) /* MAP */
-#define _TAG_HEADER_ARITYVAL (TAG_PRIMARY_HEADER|ARITYVAL_SUBTAG)
-#define _TAG_HEADER_FUN (TAG_PRIMARY_HEADER|FUN_SUBTAG)
-#define _TAG_HEADER_POS_BIG (TAG_PRIMARY_HEADER|POS_BIG_SUBTAG)
-#define _TAG_HEADER_NEG_BIG (TAG_PRIMARY_HEADER|NEG_BIG_SUBTAG)
-#define _TAG_HEADER_FLOAT (TAG_PRIMARY_HEADER|FLOAT_SUBTAG)
-#define _TAG_HEADER_EXPORT (TAG_PRIMARY_HEADER|EXPORT_SUBTAG)
-#define _TAG_HEADER_REF (TAG_PRIMARY_HEADER|REF_SUBTAG)
-#define _TAG_HEADER_REFC_BIN (TAG_PRIMARY_HEADER|REFC_BINARY_SUBTAG)
-#define _TAG_HEADER_HEAP_BIN (TAG_PRIMARY_HEADER|HEAP_BINARY_SUBTAG)
-#define _TAG_HEADER_SUB_BIN (TAG_PRIMARY_HEADER|SUB_BINARY_SUBTAG)
-#define _TAG_HEADER_EXTERNAL_PID (TAG_PRIMARY_HEADER|EXTERNAL_PID_SUBTAG)
-#define _TAG_HEADER_EXTERNAL_PORT (TAG_PRIMARY_HEADER|EXTERNAL_PORT_SUBTAG)
-#define _TAG_HEADER_EXTERNAL_REF (TAG_PRIMARY_HEADER|EXTERNAL_REF_SUBTAG)
+#define _TAG_HEADER_ARITYVAL (TAG_PRIMARY_HEADER|ARITYVAL_SUBTAG)
+#define _TAG_HEADER_FUN (TAG_PRIMARY_HEADER|FUN_SUBTAG)
+#define _TAG_HEADER_POS_BIG (TAG_PRIMARY_HEADER|POS_BIG_SUBTAG)
+#define _TAG_HEADER_NEG_BIG (TAG_PRIMARY_HEADER|NEG_BIG_SUBTAG)
+#define _TAG_HEADER_FLOAT (TAG_PRIMARY_HEADER|FLOAT_SUBTAG)
+#define _TAG_HEADER_EXPORT (TAG_PRIMARY_HEADER|EXPORT_SUBTAG)
+#define _TAG_HEADER_REF (TAG_PRIMARY_HEADER|REF_SUBTAG)
+#define _TAG_HEADER_REFC_BIN (TAG_PRIMARY_HEADER|REFC_BINARY_SUBTAG)
+#define _TAG_HEADER_HEAP_BIN (TAG_PRIMARY_HEADER|HEAP_BINARY_SUBTAG)
+#define _TAG_HEADER_SUB_BIN (TAG_PRIMARY_HEADER|SUB_BINARY_SUBTAG)
+#define _TAG_HEADER_EXTERNAL_PID (TAG_PRIMARY_HEADER|EXTERNAL_PID_SUBTAG)
+#define _TAG_HEADER_EXTERNAL_PORT (TAG_PRIMARY_HEADER|EXTERNAL_PORT_SUBTAG)
+#define _TAG_HEADER_EXTERNAL_REF (TAG_PRIMARY_HEADER|EXTERNAL_REF_SUBTAG)
#define _TAG_HEADER_BIN_MATCHSTATE (TAG_PRIMARY_HEADER|BIN_MATCHSTATE_SUBTAG)
-#define _TAG_HEADER_MAP (TAG_PRIMARY_HEADER|MAP_SUBTAG)
+#define _TAG_HEADER_MAP (TAG_PRIMARY_HEADER|MAP_SUBTAG)
#define _TAG_HEADER_MASK 0x3F
@@ -198,7 +199,7 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#endif
#define _is_aligned(x) (((Uint)(x) & 0x3) == 0)
#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED)
-_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*)
+_ET_DECLARE_CHECKED(Eterm,make_boxed,const Eterm*)
#define make_boxed(x) _ET_APPLY(make_boxed,(x))
#if 1
#define _is_not_boxed(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED))
@@ -214,7 +215,7 @@ _ET_DECLARE_CHECKED(Eterm*,boxed_val,Wterm)
/* cons cell ("list") access methods */
#define _unchecked_make_list(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_LIST)
-_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*)
+_ET_DECLARE_CHECKED(Eterm,make_list,const Eterm*)
#define make_list(x) _ET_APPLY(make_list,(x))
#if 1
#define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST))
@@ -296,9 +297,10 @@ _ET_DECLARE_CHECKED(Uint,atom_val,Eterm)
#define atom_val(x) _ET_APPLY(atom_val,(x))
/* header (arityval or thing) access methods */
-#define _make_header(sz,tag) ((Uint)(((sz) << _HEADER_ARITY_OFFS) + (tag)))
+#define _make_header(sz,tag) ((Uint)(((Uint)(sz) << _HEADER_ARITY_OFFS) + (tag)))
#define is_header(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_HEADER)
-#define _unchecked_header_arity(x) ((x) >> _HEADER_ARITY_OFFS)
+#define _unchecked_header_arity(x) \
+ (is_map_header(x) ? MAP_HEADER_ARITY(x) : ((x) >> _HEADER_ARITY_OFFS))
_ET_DECLARE_CHECKED(Uint,header_arity,Eterm)
#define header_arity(x) _ET_APPLY(header_arity,(x))
@@ -361,6 +363,7 @@ _ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm)
((((x) & (_TAG_HEADER_MASK)) == _TAG_HEADER_REFC_BIN) || \
(((x) & (_TAG_HEADER_MASK)) == _TAG_HEADER_HEAP_BIN) || \
(((x) & (_TAG_HEADER_MASK)) == _TAG_HEADER_SUB_BIN))
+
#define make_binary(x) make_boxed((Eterm*)(x))
#define is_binary(x) (is_boxed((x)) && is_binary_header(*boxed_val((x))))
#define is_not_binary(x) (!is_binary((x)))
@@ -990,6 +993,44 @@ _ET_DECLARE_CHECKED(Uint32*,external_ref_data,Wterm)
_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
#define external_ref_node(x) _ET_APPLY(external_ref_node,(x))
+/* maps */
+
+#define MAP_HEADER_TAG_SZ (2)
+#define MAP_HEADER_ARITY_SZ (8)
+#define MAP_HEADER_VAL_SZ (16)
+
+#define MAP_HEADER_TAG_FLATMAP_HEAD (0x0)
+#define MAP_HEADER_TAG_HAMT_NODE_BITMAP (0x1)
+#define MAP_HEADER_TAG_HAMT_HEAD_ARRAY (0x2)
+#define MAP_HEADER_TAG_HAMT_HEAD_BITMAP (0x3)
+
+#define MAP_HEADER_TYPE(Hdr) (((Hdr) >> (_HEADER_ARITY_OFFS)) & (0x3))
+#define MAP_HEADER_ARITY(Hdr) (((Hdr) >> (_HEADER_ARITY_OFFS + MAP_HEADER_TAG_SZ)) & (0xff))
+#define MAP_HEADER_VAL(Hdr) (((Hdr) >> (_HEADER_ARITY_OFFS + MAP_HEADER_TAG_SZ + MAP_HEADER_ARITY_SZ)) & (0xffff))
+
+#define make_hashmap(x) make_boxed((Eterm*)(x))
+#define make_hashmap_rel make_boxed_rel
+#define is_hashmap(x) (is_boxed((x)) && is_hashmap_header(*boxed_val((x))))
+#define is_not_hashmap(x) (!is_hashmap(x))
+#define is_hashmap_rel(RTERM,BASE) is_hashmap(rterm2wterm(RTERM,BASE))
+#define is_hashmap_header(x) (((x) & (_HEADER_MAP_HASHMAP_HEAD_MASK)) == HAMT_SUBTAG_HEAD_ARRAY)
+#define hashmap_val(x) _unchecked_boxed_val((x))
+#define hashmap_val_rel(RTERM, BASE) hashmap_val(rterm2wterm(RTERM, BASE))
+
+#define make_flatmap(x) make_boxed((Eterm*)(x))
+#define make_flatmap_rel(x, BASE) make_boxed_rel((Eterm*)(x),(BASE))
+#define is_flatmap(x) (is_boxed((x)) && is_flatmap_header(*boxed_val((x))))
+#define is_flatmap_rel(RTERM,BASE) is_flatmap(rterm2wterm(RTERM,BASE))
+#define is_not_flatmap(x) (!is_flatmap((x)))
+#define is_flatmap_header(x) (((x) & (_HEADER_MAP_SUBTAG_MASK)) == HAMT_SUBTAG_HEAD_FLATMAP)
+#define flatmap_val(x) (_unchecked_boxed_val((x)))
+#define flatmap_val_rel(RTERM, BASE) flatmap_val(rterm2wterm(RTERM, BASE))
+
+#define is_map_header(x) (((x) & (_TAG_HEADER_MASK)) == _TAG_HEADER_MAP)
+#define is_map(x) (is_boxed((x)) && is_map_header(*boxed_val(x)))
+#define is_not_map(x) (!is_map(x))
+#define is_map_rel(RTERM,BASE) is_map(rterm2wterm(RTERM,BASE))
+
/* number tests */
#define is_integer(x) (is_small(x) || is_big(x))
@@ -1095,6 +1136,9 @@ _ET_DECLARE_CHECKED(Uint,y_reg_index,Uint)
#define FLOAT_DEF 0xe
#define BIG_DEF 0xf
#define SMALL_DEF 0x10
+#define MATCHSTATE_DEF 0x11 /* not a "real" term */
+
+#define FIRST_VACANT_TAG_DEF 0x12
#if ET_DEBUG
extern unsigned tag_val_def_debug(Wterm, const char*, unsigned);
diff --git a/erts/emulator/beam/erl_thr_progress.c b/erts/emulator/beam/erl_thr_progress.c
index 664c479eb6..7b06fd840f 100644
--- a/erts/emulator/beam/erl_thr_progress.c
+++ b/erts/emulator/beam/erl_thr_progress.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -501,7 +502,7 @@ erts_thr_progress_register_unmanaged_thread(ErtsThrPrgrCallbacks *callbacks)
if (tpd) {
if (!tpd->is_temporary)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s(): Double register of thread\n",
__FILE__, __LINE__, __func__);
is_blocking = tpd->is_blocking;
@@ -523,7 +524,7 @@ erts_thr_progress_register_unmanaged_thread(ErtsThrPrgrCallbacks *callbacks)
#endif
ASSERT(tpd->id >= 0);
if (tpd->id >= intrnl->unmanaged.no)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s(): Too many unmanaged registered threads\n",
__FILE__, __LINE__, __func__);
@@ -546,7 +547,7 @@ erts_thr_progress_register_managed_thread(ErtsSchedulerData *esdp,
if (tpd) {
if (!tpd->is_temporary)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s(): Double register of thread\n",
__FILE__, __LINE__, __func__);
is_blocking = tpd->is_blocking;
@@ -567,7 +568,7 @@ erts_thr_progress_register_managed_thread(ErtsSchedulerData *esdp,
tpd->id = erts_atomic32_inc_read_nob(&intrnl->misc.data.managed_id);
ASSERT(tpd->id >= 0);
if (tpd->id >= intrnl->managed.no)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:%s(): Too many managed registered threads\n",
__FILE__, __LINE__, __func__);
@@ -1032,7 +1033,7 @@ has_reached_wakeup(ErtsThrPrgrVal wakeup)
limit += 1;
if (!erts_thr_progress_has_passed__(limit, wakeup))
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Invalid wakeup request value found:"
" current=%b64u, wakeup=%b64u, limit=%b64u",
current, wakeup, limit);
@@ -1101,7 +1102,7 @@ request_wakeup_managed(ErtsThrPrgrData *tpd, ErtsThrPrgrVal value)
ix = erts_atomic32_inc_read_nob(&mwd->len) - 1;
#if ERTS_THR_PRGR_DBG_CHK_WAKEUP_REQUEST_VALUE
if (ix >= intrnl->managed.no)
- erl_exit(ERTS_ABORT_EXIT, "Internal error: Too many wakeup requests\n");
+ erts_exit(ERTS_ABORT_EXIT, "Internal error: Too many wakeup requests\n");
#endif
mwd->id[ix] = tpd->id;
@@ -1335,25 +1336,10 @@ erts_thr_progress_block(void)
thr_progress_block(tmp_thr_prgr_data(NULL), 1);
}
-void
-erts_thr_progress_fatal_error_block(SWord timeout,
- ErtsThrPrgrData *tmp_tpd_bufp)
+int
+erts_thr_progress_fatal_error_block(ErtsThrPrgrData *tmp_tpd_bufp)
{
ErtsThrPrgrData *tpd = perhaps_thr_prgr_data(NULL);
- erts_aint32_t bc;
- SWord time_left = timeout;
- SysTimeval to;
-
- /*
- * Counting poll intervals may give us a too long timeout
- * if cpu is busy. If we got tolerant time of day we use it
- * to prevent this.
- */
- if (!erts_disable_tolerant_timeofday) {
- erts_get_timeval(&to);
- to.tv_sec += timeout / 1000;
- to.tv_sec += timeout % 1000;
- }
if (!tpd) {
/*
@@ -1366,9 +1352,25 @@ erts_thr_progress_fatal_error_block(SWord timeout,
init_tmp_thr_prgr_data(tpd);
}
- bc = thr_progress_block(tpd, 0);
- if (bc == 0)
- return; /* Succefully blocked all managed threads */
+ /* Returns number of threads that have not yes been blocked */
+ return thr_progress_block(tpd, 0);
+}
+
+void
+erts_thr_progress_fatal_error_wait(SWord timeout) {
+ erts_aint32_t bc;
+ SWord time_left = timeout;
+ ErtsMonotonicTime timeout_time;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+
+ /*
+ * Counting poll intervals may give us a too long timeout
+ * if cpu is busy. We use timeout time to try to prevent
+ * this. In case we havn't got time correction this may
+ * however fail too...
+ */
+ timeout_time = erts_get_monotonic_time(esdp);
+ timeout_time += ERTS_MSEC_TO_MONOTONIC((ErtsMonotonicTime) timeout);
while (1) {
if (erts_milli_sleep(ERTS_THR_PRGR_FTL_ERR_BLCK_POLL_INTERVAL) == 0)
@@ -1378,14 +1380,8 @@ erts_thr_progress_fatal_error_block(SWord timeout,
break; /* Succefully blocked all managed threads */
if (time_left <= 0)
break; /* Timeout */
- if (!erts_disable_tolerant_timeofday) {
- SysTimeval now;
- erts_get_timeval(&now);
- if (now.tv_sec > to.tv_sec)
- break; /* Timeout */
- if (now.tv_sec == to.tv_sec && now.tv_usec >= to.tv_usec)
- break; /* Timeout */
- }
+ if (timeout_time <= erts_get_monotonic_time(esdp))
+ break; /* Timeout */
}
}
diff --git a/erts/emulator/beam/erl_thr_progress.h b/erts/emulator/beam/erl_thr_progress.h
index 03ddbd467c..b89cc4c267 100644
--- a/erts/emulator/beam/erl_thr_progress.h
+++ b/erts/emulator/beam/erl_thr_progress.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -83,8 +84,8 @@ typedef struct {
ErtsThrPrgrLeaderState leader_state;
} ErtsThrPrgrData;
-void erts_thr_progress_fatal_error_block(SWord timeout,
- ErtsThrPrgrData *tmp_tpd_bufp);
+int erts_thr_progress_fatal_error_block(ErtsThrPrgrData *tmp_tpd_bufp);
+void erts_thr_progress_fatal_error_wait(SWord timeout);
#endif /* ERTS_SMP */
diff --git a/erts/emulator/beam/erl_thr_queue.c b/erts/emulator/beam/erl_thr_queue.c
index f8ca87ddcc..7ff456b915 100644
--- a/erts/emulator/beam/erl_thr_queue.c
+++ b/erts/emulator/beam/erl_thr_queue.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -223,7 +224,7 @@ ErtsThrQCleanState_t
erts_thr_q_destroy(ErtsThrQ_t *q)
{
if (!q->q.blk)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Trying to destroy not created thread queue\n");
return erts_thr_q_finalize(q);
}
@@ -588,7 +589,7 @@ enqueue(ErtsThrQ_t *q, void *data, ErtsThrQElement_t *this)
#if ERTS_THR_Q_DBG_CHK_DATA
if (!data)
- erl_exit(ERTS_ABORT_EXIT, "Missing data in enqueue\n");
+ erts_exit(ERTS_ABORT_EXIT, "Missing data in enqueue\n");
#endif
ASSERT(!q->q.finalizing);
@@ -770,7 +771,7 @@ erts_thr_q_dequeue(ErtsThrQ_t *q)
#if ERTS_THR_Q_DBG_CHK_DATA
head->data.ptr = NULL;
if (!res)
- erl_exit(ERTS_ABORT_EXIT, "Missing data in dequeue\n");
+ erts_exit(ERTS_ABORT_EXIT, "Missing data in dequeue\n");
#endif
clean(q,
(q->head.deq_fini.automatic
diff --git a/erts/emulator/beam/erl_thr_queue.h b/erts/emulator/beam/erl_thr_queue.h
index 13af758b3f..27a6d03224 100644
--- a/erts/emulator/beam/erl_thr_queue.h
+++ b/erts/emulator/beam/erl_thr_queue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h
index 7214f3ea33..34f91e2ec8 100644
--- a/erts/emulator/beam/erl_threads.h
+++ b/erts/emulator/beam/erl_threads.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -476,6 +477,7 @@ ERTS_GLB_INLINE void erts_thr_detach(erts_tid_t tid);
ERTS_GLB_INLINE void erts_thr_exit(void *res);
ERTS_GLB_INLINE void erts_thr_install_exit_handler(void (*exit_handler)(void));
ERTS_GLB_INLINE erts_tid_t erts_thr_self(void);
+ERTS_GLB_INLINE int erts_thr_getname(erts_tid_t tid, char *buf, size_t len);
ERTS_GLB_INLINE int erts_equal_tids(erts_tid_t x, erts_tid_t y);
ERTS_GLB_INLINE void erts_mtx_init_x(erts_mtx_t *mtx, char *name, Eterm extra,
int enable_lcnt);
@@ -647,20 +649,29 @@ ERTS_GLB_INLINE void erts_tsd_set(erts_tsd_key_t key, void *value);
ERTS_GLB_INLINE void * erts_tsd_get(erts_tsd_key_t key);
ERTS_GLB_INLINE erts_tse_t *erts_tse_fetch(void);
ERTS_GLB_INLINE void erts_tse_return(erts_tse_t *ep);
+ERTS_GLB_INLINE void erts_tse_prepare_timed(erts_tse_t *ep);
ERTS_GLB_INLINE void erts_tse_set(erts_tse_t *ep);
ERTS_GLB_INLINE void erts_tse_reset(erts_tse_t *ep);
ERTS_GLB_INLINE int erts_tse_wait(erts_tse_t *ep);
ERTS_GLB_INLINE int erts_tse_swait(erts_tse_t *ep, int spincount);
+ERTS_GLB_INLINE int erts_tse_twait(erts_tse_t *ep, Sint64 tmo);
+ERTS_GLB_INLINE int erts_tse_stwait(erts_tse_t *ep, int spincount, Sint64 tmo);
ERTS_GLB_INLINE int erts_tse_is_tmp(erts_tse_t *ep);
ERTS_GLB_INLINE void erts_thr_set_main_status(int, int);
ERTS_GLB_INLINE int erts_thr_get_main_status(void);
ERTS_GLB_INLINE void erts_thr_yield(void);
+
#ifdef ETHR_HAVE_ETHR_SIG_FUNCS
#define ERTS_THR_HAVE_SIG_FUNCS 1
ERTS_GLB_INLINE void erts_thr_sigmask(int how, const sigset_t *set,
sigset_t *oset);
ERTS_GLB_INLINE void erts_thr_sigwait(const sigset_t *set, int *sig);
+
+#ifdef USE_THREADS
+ERTS_GLB_INLINE void erts_thr_kill(erts_tid_t tid, int sig);
+#endif
+
#endif /* #ifdef HAVE_ETHR_SIG_FUNCS */
#ifdef USE_THREADS
@@ -2129,6 +2140,16 @@ erts_thr_self(void)
#endif
}
+ERTS_GLB_INLINE int
+erts_thr_getname(erts_tid_t tid, char *buf, size_t len)
+{
+#ifdef USE_THREADS
+ return ethr_getname(tid, buf, len);
+#else
+ return -1;
+#endif
+}
+
ERTS_GLB_INLINE int
erts_equal_tids(erts_tid_t x, erts_tid_t y)
@@ -3441,6 +3462,15 @@ ERTS_GLB_INLINE void erts_tse_return(erts_tse_t *ep)
#endif
}
+ERTS_GLB_INLINE void erts_tse_prepare_timed(erts_tse_t *ep)
+{
+#ifdef USE_THREADS
+ int res = ethr_event_prepare_timed(&((ethr_ts_event *) ep)->event);
+ if (res != 0)
+ erts_thr_fatal_error(res, "prepare timed");
+#endif
+}
+
ERTS_GLB_INLINE void erts_tse_set(erts_tse_t *ep)
{
#ifdef USE_THREADS
@@ -3473,6 +3503,27 @@ ERTS_GLB_INLINE int erts_tse_swait(erts_tse_t *ep, int spincount)
#endif
}
+ERTS_GLB_INLINE int erts_tse_twait(erts_tse_t *ep, Sint64 tmo)
+{
+#ifdef USE_THREADS
+ return ethr_event_twait(&((ethr_ts_event *) ep)->event,
+ (ethr_sint64_t) tmo);
+#else
+ return ENOTSUP;
+#endif
+}
+
+ERTS_GLB_INLINE int erts_tse_stwait(erts_tse_t *ep, int spincount, Sint64 tmo)
+{
+#ifdef USE_THREADS
+ return ethr_event_stwait(&((ethr_ts_event *) ep)->event,
+ spincount,
+ (ethr_sint64_t) tmo);
+#else
+ return ENOTSUP;
+#endif
+}
+
ERTS_GLB_INLINE int erts_tse_is_tmp(erts_tse_t *ep)
{
#ifdef USE_THREADS
@@ -3517,6 +3568,15 @@ ERTS_GLB_INLINE void erts_thr_yield(void)
#ifdef ETHR_HAVE_ETHR_SIG_FUNCS
ERTS_GLB_INLINE void
+erts_thr_kill(erts_tid_t tid, int sig) {
+#ifdef USE_THREADS
+ int res = ethr_kill((ethr_tid)tid, sig);
+ if (res)
+ erts_thr_fatal_error(res, "killing thread");
+#endif
+}
+
+ERTS_GLB_INLINE void
erts_thr_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
#ifdef USE_THREADS
diff --git a/erts/emulator/beam/erl_time.h b/erts/emulator/beam/erl_time.h
index 4bbdcaa3e3..93a0d556bf 100644
--- a/erts/emulator/beam/erl_time.h
+++ b/erts/emulator/beam/erl_time.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -20,94 +21,49 @@
#ifndef ERL_TIME_H__
#define ERL_TIME_H__
-#define ERTS_SHORT_TIME_T_MAX ERTS_AINT32_T_MAX
-#define ERTS_SHORT_TIME_T_MIN ERTS_AINT32_T_MIN
-typedef erts_aint32_t erts_short_time_t;
+/* timer wheel size NEED to be a power of 2 */
+#ifdef SMALL_MEMORY
+#define ERTS_TIW_SIZE (1 << 13)
+#else
+#define ERTS_TIW_SIZE (1 << 16)
+#endif
-extern erts_smp_atomic32_t do_time; /* set at clock interrupt */
-extern SysTimeval erts_first_emu_time;
+#if defined(DEBUG) || 0
+#define ERTS_TIME_ASSERT(B) ERTS_ASSERT(B)
+#else
+#define ERTS_TIME_ASSERT(B) ((void) 1)
+#endif
-/*
-** Timer entry:
-*/
-typedef struct erl_timer {
- struct erl_timer* next; /* next entry tiw slot or chain */
- struct erl_timer* prev; /* prev entry tiw slot or chain */
- Uint slot; /* slot in timer wheel */
- Uint count; /* number of loops remaining */
- int active; /* 1=activated, 0=deactivated */
- /* called when timeout */
- void (*timeout)(void*);
- /* called when cancel (may be NULL) */
- void (*cancel)(void*);
- void* arg; /* argument to timeout/cancel procs */
-} ErlTimer;
+typedef enum {
+ ERTS_NO_TIME_WARP_MODE,
+ ERTS_SINGLE_TIME_WARP_MODE,
+ ERTS_MULTI_TIME_WARP_MODE
+} ErtsTimeWarpMode;
-typedef void (*ErlTimeoutProc)(void*);
-typedef void (*ErlCancelProc)(void*);
+typedef struct ErtsTimerWheel_ ErtsTimerWheel;
+typedef ErtsMonotonicTime * ErtsNextTimeoutRef;
-#ifdef ERTS_SMP
-/*
- * Process and port timer
- */
-typedef union ErtsSmpPTimer_ ErtsSmpPTimer;
-union ErtsSmpPTimer_ {
- struct {
- ErlTimer tm;
- Eterm id;
- void (*timeout_func)(void*);
- ErtsSmpPTimer **timer_ref;
- Uint32 flags;
- } timer;
- ErtsSmpPTimer *next;
-};
+extern SysTimeval erts_first_emu_time;
-void erts_create_smp_ptimer(ErtsSmpPTimer **timer_ref,
- Eterm id,
- ErlTimeoutProc timeout_func,
- Uint timeout);
-void erts_cancel_smp_ptimer(ErtsSmpPTimer *ptimer);
-#endif
+void erts_monitor_time_offset(Eterm id, Eterm ref);
+int erts_demonitor_time_offset(Eterm ref);
-/* timer-wheel api */
+int erts_init_time_sup(int, ErtsTimeWarpMode);
+void erts_late_init_time_sup(void);
-void erts_init_time(void);
-void erts_set_timer(ErlTimer*, ErlTimeoutProc, ErlCancelProc, void*, Uint);
-void erts_cancel_timer(ErlTimer*);
-void erts_bump_timer(erts_short_time_t);
+ErtsNextTimeoutRef erts_get_next_timeout_reference(ErtsTimerWheel *);
+void erts_init_time(int time_correction, ErtsTimeWarpMode time_warp_mode);
+void erts_bump_timers(ErtsTimerWheel *, ErtsMonotonicTime);
Uint erts_timer_wheel_memory_size(void);
-Uint erts_time_left(ErlTimer *);
-erts_short_time_t erts_next_time(void);
#ifdef DEBUG
void erts_p_slpq(void);
#endif
-ERTS_GLB_INLINE erts_short_time_t erts_do_time_read_and_reset(void);
-ERTS_GLB_INLINE void erts_do_time_add(erts_short_time_t);
-
-#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-
-ERTS_GLB_INLINE erts_short_time_t erts_do_time_read_and_reset(void)
-{
- erts_short_time_t time = erts_smp_atomic32_xchg_acqb(&do_time, 0);
- if (time < 0)
- erl_exit(ERTS_ABORT_EXIT, "Internal time management error\n");
- return time;
-}
-
-ERTS_GLB_INLINE void erts_do_time_add(erts_short_time_t elapsed)
-{
- erts_smp_atomic32_add_relb(&do_time, elapsed);
-}
-
-#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
-
-
/* time_sup */
-#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME))
+#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME_CPU_TIME))
# ifndef HAVE_ERTS_NOW_CPU
# define HAVE_ERTS_NOW_CPU
# ifdef HAVE_GETHRVTIME
@@ -121,25 +77,395 @@ void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec);
typedef UWord erts_approx_time_t;
erts_approx_time_t erts_get_approx_time(void);
-void erts_get_timeval(SysTimeval *tv);
-erts_time_t erts_get_time(void);
+int erts_has_time_correction(void);
+int erts_check_time_adj_support(int time_correction,
+ ErtsTimeWarpMode time_warp_mode);
+
+ErtsTimeWarpMode erts_time_warp_mode(void);
+
+typedef enum {
+ ERTS_TIME_OFFSET_PRELIMINARY,
+ ERTS_TIME_OFFSET_FINAL,
+ ERTS_TIME_OFFSET_VOLATILE
+} ErtsTimeOffsetState;
+
+ErtsTimeOffsetState erts_time_offset_state(void);
+ErtsTimeOffsetState erts_finalize_time_offset(void);
+struct process;
+Eterm erts_get_monotonic_start_time(struct process *c_p);
+Eterm erts_get_monotonic_end_time(struct process *c_p);
+Eterm erts_monotonic_time_source(struct process*c_p);
+Eterm erts_system_time_source(struct process*c_p);
+
+#ifdef SYS_CLOCK_RESOLUTION
+#define ERTS_CLKTCK_RESOLUTION ((ErtsMonotonicTime) (SYS_CLOCK_RESOLUTION*1000))
+#else
+#define ERTS_CLKTCK_RESOLUTION (erts_time_sup__.r.o.clktck_resolution)
+#endif
+
+#define ERTS_TIMER_WHEEL_MSEC (ERTS_TIW_SIZE/(ERTS_CLKTCK_RESOLUTION/1000))
+
+struct erts_time_sup_read_only__ {
+ ErtsMonotonicTime monotonic_time_unit;
+#if !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
+ ErtsMonotonicTime start;
+ struct {
+ ErtsMonotonicTime native;
+ ErtsMonotonicTime nsec;
+ ErtsMonotonicTime usec;
+ ErtsMonotonicTime msec;
+ ErtsMonotonicTime sec;
+ } start_offset;
+#endif
+#ifndef SYS_CLOCK_RESOLUTION
+ ErtsMonotonicTime clktck_resolution;
+#endif
+};
+
+typedef struct {
+ union {
+ struct erts_time_sup_read_only__ o;
+ char align__[(((sizeof(struct erts_time_sup_read_only__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } r;
+} ErtsTimeSupData;
+
+extern ErtsTimeSupData erts_time_sup__;
+
+ErtsMonotonicTime erts_napi_monotonic_time(int time_unit);
+ErtsMonotonicTime erts_napi_time_offset(int time_unit);
+ErtsMonotonicTime erts_napi_convert_time_unit(ErtsMonotonicTime val, int from, int to);
-ERTS_GLB_INLINE int erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p);
+ERTS_GLB_INLINE Uint64
+erts_time_unit_conversion(Uint64 value,
+ Uint32 from_time_unit,
+ Uint32 to_time_unit);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-ERTS_GLB_INLINE int
-erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p)
+ERTS_GLB_INLINE Uint64
+erts_time_unit_conversion(Uint64 value,
+ Uint32 from_time_unit,
+ Uint32 to_time_unit)
{
- if (t1p->tv_sec == t2p->tv_sec) {
- if (t1p->tv_usec < t2p->tv_usec)
- return -1;
- else if (t1p->tv_usec > t2p->tv_usec)
- return 1;
- return 0;
- }
- return t1p->tv_sec < t2p->tv_sec ? -1 : 1;
+ Uint64 high, low, result;
+ if (value <= ~((Uint64) 0)/to_time_unit)
+ return (value*to_time_unit)/from_time_unit;
+
+ low = value & ((Uint64) 0xffffffff);
+ high = (value >> 32) & ((Uint64) 0xffffffff);
+
+ low *= to_time_unit;
+ high *= to_time_unit;
+
+ high += (low >> 32) & ((Uint64) 0xffffffff);
+ low &= ((Uint64) 0xffffffff);
+
+ result = high % from_time_unit;
+ high /= from_time_unit;
+ high <<= 32;
+
+ result <<= 32;
+ result += low;
+ result /= from_time_unit;
+ result += high;
+
+ return result;
}
-#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
+/*
+ * Range of monotonic time internally
+ */
+
+#define ERTS_MONOTONIC_BEGIN \
+ ERTS_MONOTONIC_TIME_UNIT
+#define ERTS_MONOTONIC_END \
+ ((ERTS_MONOTONIC_TIME_MAX / ERTS_MONOTONIC_TIME_UNIT) \
+ * ERTS_MONOTONIC_TIME_UNIT)
+
+#if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
+
+/*
+ * If the monotonic time unit is a compile time constant,
+ * it is assumed (and need) to be a power of 10.
+ */
+
+#if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT < 1000*1000
+# error Compile time time unit needs to be at least 1000000
+#endif
+
+#if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT == 1000*1000*1000
+/* Nano-second time unit */
+
+#define ERTS_MONOTONIC_TO_SEC__(NSEC) ((NSEC) / (1000*1000*1000))
+#define ERTS_MONOTONIC_TO_MSEC__(NSEC) ((NSEC) / (1000*1000))
+#define ERTS_MONOTONIC_TO_USEC__(NSEC) ((NSEC) / 1000)
+#define ERTS_MONOTONIC_TO_NSEC__(NSEC) (NSEC)
+
+#define ERTS_SEC_TO_MONOTONIC__(SEC) (((ErtsMonotonicTime) (SEC))*(1000*1000*1000))
+#define ERTS_MSEC_TO_MONOTONIC__(MSEC) (((ErtsMonotonicTime) (MSEC))*(1000*1000))
+#define ERTS_USEC_TO_MONOTONIC__(USEC) (((ErtsMonotonicTime) (USEC))*1000)
+#define ERTS_NSEC_TO_MONOTONIC__(NSEC) ((ErtsMonotonicTime) (NSEC))
+
+#elif ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT == 1000*1000
+/* Micro-second time unit */
+
+#define ERTS_MONOTONIC_TO_SEC__(USEC) ((USEC) / (1000*1000))
+#define ERTS_MONOTONIC_TO_MSEC__(USEC) ((USEC) / 1000)
+#define ERTS_MONOTONIC_TO_USEC__(USEC) (USEC)
+#define ERTS_MONOTONIC_TO_NSEC__(USEC) ((USEC)*1000)
+
+#define ERTS_SEC_TO_MONOTONIC__(SEC) (((ErtsMonotonicTime) (SEC))*(1000*1000))
+#define ERTS_MSEC_TO_MONOTONIC__(MSEC) (((ErtsMonotonicTime) (MSEC))*1000)
+#define ERTS_USEC_TO_MONOTONIC__(USEC) ((ErtsMonotonicTime) (USEC))
+#define ERTS_NSEC_TO_MONOTONIC__(NSEC) (((ErtsMonotonicTime) (NSEC))/1000)
+
+#else
+#error Missing implementation for monotonic time unit
+#endif
+
+#define ERTS_MONOTONIC_TIME_UNIT \
+ ((ErtsMonotonicTime) ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT)
+
+/*
+ * NOTE! ERTS_MONOTONIC_TIME_START_EXTERNAL *need* to be a multiple
+ * of ERTS_MONOTONIC_TIME_UNIT.
+ */
+
+#ifdef ARCH_32
+/*
+ * Want to use a big-num of arity 2 as long as possible (584 years
+ * in the nano-second time unit case).
+ */
+#define ERTS_MONOTONIC_TIME_START_EXTERNAL \
+ (((((((ErtsMonotonicTime) 1) << 32)-1) \
+ / ERTS_MONOTONIC_TIME_UNIT) \
+ * ERTS_MONOTONIC_TIME_UNIT) \
+ + ERTS_MONOTONIC_TIME_UNIT)
+
+#else /* ARCH_64 */
+
+#if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT <= 10*1000*1000
+
+/*
+ * Using micro second time unit or lower. Start at zero since
+ * time will remain an immediate for a very long time anyway
+ * (1827 years in the 10 micro second case)...
+ */
+#define ERTS_MONOTONIC_TIME_START_EXTERNAL ((ErtsMonotonicTime) 0)
+
+#else /* ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT > 10*1000*1000 */
+
+/*
+ * Want to use an immediate as long as possible (36 years in the
+ * nano-second time unit case).
+*/
+#define ERTS_MONOTONIC_TIME_START_EXTERNAL \
+ ((((ErtsMonotonicTime) MIN_SMALL) \
+ / ERTS_MONOTONIC_TIME_UNIT) \
+ * ERTS_MONOTONIC_TIME_UNIT)
+
+#endif /* ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT > 1000*1000 */
+
+#endif /* ARCH_64 */
+
+/*
+ * Offsets from internal monotonic time to external monotonic time
+ */
+
+#define ERTS_MONOTONIC_OFFSET_NATIVE \
+ (ERTS_MONOTONIC_TIME_START_EXTERNAL - ERTS_MONOTONIC_BEGIN)
+#define ERTS_MONOTONIC_OFFSET_NSEC \
+ ERTS_MONOTONIC_TO_NSEC__(ERTS_MONOTONIC_OFFSET_NATIVE)
+#define ERTS_MONOTONIC_OFFSET_USEC \
+ ERTS_MONOTONIC_TO_USEC__(ERTS_MONOTONIC_OFFSET_NATIVE)
+#define ERTS_MONOTONIC_OFFSET_MSEC \
+ ERTS_MONOTONIC_TO_MSEC__(ERTS_MONOTONIC_OFFSET_NATIVE)
+#define ERTS_MONOTONIC_OFFSET_SEC \
+ ERTS_MONOTONIC_TO_SEC__(ERTS_MONOTONIC_OFFSET_NATIVE)
+
+#define ERTS_MONOTONIC_TO_CLKTCKS__(MON) \
+ ((MON) / (ERTS_MONOTONIC_TIME_UNIT/ERTS_CLKTCK_RESOLUTION))
+#define ERTS_CLKTCKS_TO_MONOTONIC__(TCKS) \
+ ((TCKS) * (ERTS_MONOTONIC_TIME_UNIT/ERTS_CLKTCK_RESOLUTION))
+
+#else /* !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT */
+
+/*
+ * Initialized in erts_init_sys_time_sup()
+ */
+#define ERTS_MONOTONIC_TIME_UNIT (erts_time_sup__.r.o.monotonic_time_unit)
+
+/*
+ * Offsets from internal monotonic time to external monotonic time
+ *
+ * Initialized in erts_init_time_sup()...
+ */
+#define ERTS_MONOTONIC_TIME_START_EXTERNAL (erts_time_sup__.r.o.start)
+#define ERTS_MONOTONIC_OFFSET_NATIVE (erts_time_sup__.r.o.start_offset.native)
+#define ERTS_MONOTONIC_OFFSET_NSEC (erts_time_sup__.r.o.start_offset.nsec)
+#define ERTS_MONOTONIC_OFFSET_USEC (erts_time_sup__.r.o.start_offset.usec)
+#define ERTS_MONOTONIC_OFFSET_MSEC (erts_time_sup__.r.o.start_offset.msec)
+#define ERTS_MONOTONIC_OFFSET_SEC (erts_time_sup__.r.o.start_offset.sec)
+
+#define ERTS_CONV_FROM_MON_UNIT___(M, TO) \
+ ((ErtsMonotonicTime) \
+ erts_time_unit_conversion((Uint64) (M), \
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT, \
+ (Uint32) (TO)))
+
+#define ERTS_CONV_TO_MON_UNIT___(M, FROM) \
+ ((ErtsMonotonicTime) \
+ erts_time_unit_conversion((Uint64) (M), \
+ (Uint32) (FROM), \
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT)) \
+
+#define ERTS_MONOTONIC_TO_SEC__(M) \
+ ERTS_CONV_FROM_MON_UNIT___((M), 1)
+#define ERTS_MONOTONIC_TO_MSEC__(M) \
+ ERTS_CONV_FROM_MON_UNIT___((M), 1000)
+#define ERTS_MONOTONIC_TO_USEC__(M) \
+ ERTS_CONV_FROM_MON_UNIT___((M), 1000*1000)
+#define ERTS_MONOTONIC_TO_NSEC__(M) \
+ ERTS_CONV_FROM_MON_UNIT___((M), 1000*1000*1000)
+
+#define ERTS_SEC_TO_MONOTONIC__(SEC) \
+ ERTS_CONV_TO_MON_UNIT___((SEC), 1)
+#define ERTS_MSEC_TO_MONOTONIC__(MSEC) \
+ ERTS_CONV_TO_MON_UNIT___((MSEC), 1000)
+#define ERTS_USEC_TO_MONOTONIC__(USEC) \
+ ERTS_CONV_TO_MON_UNIT___((USEC), 1000*1000)
+#define ERTS_NSEC_TO_MONOTONIC__(NSEC) \
+ ERTS_CONV_TO_MON_UNIT___((NSEC), 1000*1000*1000)
+
+#define ERTS_MONOTONIC_TO_CLKTCKS__(MON) \
+ ERTS_CONV_FROM_MON_UNIT___((MON), ERTS_CLKTCK_RESOLUTION)
+#define ERTS_CLKTCKS_TO_MONOTONIC__(TCKS) \
+ ERTS_CONV_TO_MON_UNIT___((TCKS), ERTS_CLKTCK_RESOLUTION)
+
+#endif /* !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT */
+
+#define ERTS_MONOTONIC_TIME_END_EXTERNAL \
+ (ERTS_MONOTONIC_TIME_START_EXTERNAL < 0 \
+ ? (ERTS_MONOTONIC_TIME_START_EXTERNAL \
+ + (ERTS_MONOTONIC_END - ERTS_MONOTONIC_BEGIN)) \
+ : (ERTS_MONOTONIC_END - ERTS_MONOTONIC_TIME_START_EXTERNAL))
+
+#define ERTS_MSEC_TO_CLKTCKS__(MON) \
+ ((MON) * (ERTS_CLKTCK_RESOLUTION/1000))
+#define ERTS_CLKTCKS_TO_MSEC__(TCKS) \
+ ((TCKS) / (ERTS_CLKTCK_RESOLUTION/1000))
+
+#define ERTS_MONOTONIC_TO_SEC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MONOTONIC_TO_SEC__((X)))
+#define ERTS_MONOTONIC_TO_MSEC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MONOTONIC_TO_MSEC__((X)))
+#define ERTS_MONOTONIC_TO_USEC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MONOTONIC_TO_USEC__((X)))
+#define ERTS_MONOTONIC_TO_NSEC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MONOTONIC_TO_NSEC__((X)))
+#define ERTS_SEC_TO_MONOTONIC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_SEC_TO_MONOTONIC__((X)))
+#define ERTS_MSEC_TO_MONOTONIC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MSEC_TO_MONOTONIC__((X)))
+#define ERTS_USEC_TO_MONOTONIC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_USEC_TO_MONOTONIC__((X)))
+#define ERTS_NSEC_TO_MONOTONIC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_NSEC_TO_MONOTONIC__((X)))
+
+#define ERTS_MONOTONIC_TO_CLKTCKS(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MONOTONIC_TO_CLKTCKS__((X)))
+#define ERTS_CLKTCKS_TO_MONOTONIC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_CLKTCKS_TO_MONOTONIC__((X)))
+
+#define ERTS_MSEC_TO_CLKTCKS(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_MSEC_TO_CLKTCKS__((X)))
+#define ERTS_CLKTCKS_TO_MSEC(X) \
+ (ERTS_TIME_ASSERT((X) >= 0), \
+ ERTS_CLKTCKS_TO_MSEC__((X)))
+
#endif /* ERL_TIME_H__ */
+
+/* timer-wheel api */
+#if defined(ERTS_WANT_TIMER_WHEEL_API) && !defined(ERTS_GOT_TIMER_WHEEL_API)
+#define ERTS_GOT_TIMER_WHEEL_API
+
+#include "erl_thr_progress.h"
+#include "erl_process.h"
+
+void erts_sched_init_time_sup(ErtsSchedulerData *esdp);
+
+
+#define ERTS_TWHEEL_SLOT_AT_ONCE -1
+#define ERTS_TWHEEL_SLOT_INACTIVE -2
+
+/*
+** Timer entry:
+*/
+typedef struct erl_timer {
+ struct erl_timer* next; /* next entry tiw slot or chain */
+ struct erl_timer* prev; /* prev entry tiw slot or chain */
+ union {
+ struct {
+ void (*timeout)(void*); /* called when timeout */
+ void (*cancel)(void*); /* called when cancel (may be NULL) */
+ void* arg; /* argument to timeout/cancel procs */
+ } func;
+ ErtsThrPrgrLaterOp cleanup;
+ } u;
+ ErtsMonotonicTime timeout_pos; /* Timeout in absolute clock ticks */
+ int slot;
+} ErtsTWheelTimer;
+
+typedef void (*ErlTimeoutProc)(void*);
+typedef void (*ErlCancelProc)(void*);
+
+void erts_twheel_set_timer(ErtsTimerWheel *tiw,
+ ErtsTWheelTimer *p, ErlTimeoutProc timeout,
+ ErlCancelProc cancel, void *arg,
+ ErtsMonotonicTime timeout_pos);
+void erts_twheel_cancel_timer(ErtsTimerWheel *tiw, ErtsTWheelTimer *p);
+ErtsTimerWheel *erts_create_timer_wheel(ErtsSchedulerData *esdp);
+
+ErtsMonotonicTime erts_check_next_timeout_time(ErtsSchedulerData *);
+
+ERTS_GLB_INLINE void erts_twheel_init_timer(ErtsTWheelTimer *p);
+ERTS_GLB_INLINE ErtsMonotonicTime erts_next_timeout_time(ErtsNextTimeoutRef);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE void erts_twheel_init_timer(ErtsTWheelTimer *p)
+{
+ p->slot = ERTS_TWHEEL_SLOT_INACTIVE;
+}
+
+ERTS_GLB_INLINE ErtsMonotonicTime erts_next_timeout_time(ErtsNextTimeoutRef nxt_tmo_ref)
+{
+ return *((ErtsMonotonicTime *) nxt_tmo_ref);
+}
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
+void
+erts_twheel_debug_foreach(ErtsTimerWheel *tiw,
+ void (*tclbk)(void *),
+ void (*func)(void *,
+ ErtsMonotonicTime,
+ void *),
+ void *arg);
+
+#endif /* timer wheel api */
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 3272a5326d..99005356ed 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -1,77 +1,28 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2012. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
/*
-** Support routines for the timer wheel
-**
-** This code contains two strategies for dealing with
-** date/time changes in the system.
-** If the system has some kind of high resolution timer (HAVE_GETHRTIME),
-** the high resolution timer is used to correct the time-of-day and the
-** timeouts, the base source is the hrtimer, but at certain intervals the
-** OS time-of-day is checked and if it is not within certain bounds, the
-** delivered time gets slowly adjusted for each call until
-** it corresponds to the system time (built-in adjtime...).
-** The call gethrtime() is detected by autoconf on Unix, but other
-** platforms may define it in erl_*_sys.h and implement
-** their own high resolution timer. The high resolution timer
-** strategy is (probably) best on all systems where the timer have
-** a resolution higher or equal to gettimeofday (or what's implemented
-** is sys_gettimeofday()). The actual resolution is the interesting thing,
-** not the unit's thats used (i.e. on VxWorks, nanoseconds can be
-** retrieved in terms of units, but the actual resolution is the same as
-** for the clock ticks).
-** If the systems best timer routine is kernel ticks returned from
-** sys_times(), and the actual resolution of sys_gettimeofday() is
-** better (like most unixes that does not have any realtime extensions),
-** another strategy is used. The tolerant gettimeofday() corrects
-** the value with respect to uptime (sys_times() return value) and checks
-** for correction both when delivering timeticks and delivering nowtime.
-** this strategy is slower, but accurate on systems without better timer
-** routines. The kernel tick resolution is not enough to implement
-** a gethrtime routine. On Linux and other non solaris unix-boxes the second
-** strategy is used, on all other platforms we use the first.
-**
-** The following is expected (from sys.[ch] and erl_*_sys.h):
-**
-** 64 bit integers. So it is, and so it will be.
-**
-** sys_init_time(), will return the clock resolution in MS and
-** that's about it. More could be added of course
-** If the clock-rate is constant (i.e. 1 ms) one can define
-** SYS_CLOCK_RESOLUTION (to 1),
-** which makes erts_deliver_time/erts_time_remaining a bit faster.
-**
-** if HAVE_GETHRTIME is defined:
-** sys_gethrtime() will return a SysHrTime (long long) representing
-** nanoseconds, sys_init_hrtime() will do any initialization.
-** else
-** a long (64bit) integer type called Sint64 should be defined.
-**
-** sys_times() will return clock_ticks since start and
-** fill in a SysTimes structure (struct tms). Instead of CLK_TCK,
-** SYS_CLK_TCK is used to determine the resolution of kernel ticks.
-**
-** sys_gettimeofday() will take a SysTimeval (a struct timeval) as parameter
-** and fill it in as gettimeofday(X,NULL).
-**
-*/
+ * Support routines for the time
+ */
+
+/* #define ERTS_TIME_CORRECTION_PRINT */
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -80,384 +31,1261 @@
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
-
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
+#include "erl_driver.h"
+#include "erl_nif.h"
+
static erts_smp_mtx_t erts_timeofday_mtx;
-
-static SysTimeval inittv; /* Used everywhere, the initial time-of-day */
+static erts_smp_mtx_t erts_get_time_mtx;
static SysTimes t_start; /* Used in elapsed_time_both */
-static SysTimeval gtv; /* Used in wall_clock_elapsed_time_both */
-static SysTimeval then; /* Used in get_now */
-static SysTimeval last_emu_time; /* Used in erts_get_emu_time() */
-SysTimeval erts_first_emu_time; /* Used in erts_get_emu_time() */
+static ErtsMonotonicTime prev_wall_clock_elapsed; /* Used in wall_clock_elapsed_time_both */
+static ErtsMonotonicTime previous_now; /* Used in get_now */
+
+static ErtsMonitor *time_offset_monitors = NULL;
+static Uint no_time_offset_monitors = 0;
+
+#ifdef DEBUG
+static int time_sup_initialized = 0;
+#endif
-union {
- erts_smp_atomic_t time;
- char align[ERTS_CACHE_LINE_SIZE];
-} approx erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+#define ERTS_MONOTONIC_TIME_KILO \
+ ((ErtsMonotonicTime) 1000)
+#define ERTS_MONOTONIC_TIME_MEGA \
+ (ERTS_MONOTONIC_TIME_KILO*ERTS_MONOTONIC_TIME_KILO)
+#define ERTS_MONOTONIC_TIME_GIGA \
+ (ERTS_MONOTONIC_TIME_MEGA*ERTS_MONOTONIC_TIME_KILO)
+#define ERTS_MONOTONIC_TIME_TERA \
+ (ERTS_MONOTONIC_TIME_GIGA*ERTS_MONOTONIC_TIME_KILO)
+static void init_time_napi(void);
static void
-init_approx_time(void)
+schedule_send_time_offset_changed_notifications(ErtsMonotonicTime new_offset);
+
+struct time_sup_read_only__ {
+ ErtsMonotonicTime (*get_time)(void);
+ int correction;
+ ErtsTimeWarpMode warp_mode;
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ ErtsMonotonicTime moffset;
+ int os_corrected_monotonic_time;
+ int os_monotonic_time_disable;
+ char *os_monotonic_time_func;
+ char *os_monotonic_time_clock_id;
+ int os_monotonic_time_locked;
+ Uint64 os_monotonic_time_resolution;
+ Uint64 os_monotonic_time_extended;
+#endif
+ char *os_system_time_func;
+ char *os_system_time_clock_id;
+ int os_system_time_locked;
+ Uint64 os_system_time_resolution;
+ Uint64 os_system_time_extended;
+ struct {
+ ErtsMonotonicTime large_diff;
+ ErtsMonotonicTime small_diff;
+ } adj;
+ struct {
+ ErtsMonotonicTime error;
+ ErtsMonotonicTime resolution;
+ int intervals;
+ int use_avg;
+ } drift_adj;
+};
+
+typedef struct {
+ ErtsMonotonicTime drift; /* Correction for os monotonic drift */
+ ErtsMonotonicTime error; /* Correction for error between system times */
+} ErtsMonotonicCorrection;
+
+typedef struct {
+ ErtsMonotonicTime erl_mtime;
+ ErtsMonotonicTime os_mtime;
+ ErtsMonotonicCorrection correction;
+} ErtsMonotonicCorrectionInstance;
+
+#define ERTS_MAX_DRIFT_INTERVALS 50
+typedef struct {
+ struct {
+ struct {
+ ErtsMonotonicTime sys;
+ ErtsMonotonicTime mon;
+ } diff;
+ struct {
+ ErtsMonotonicTime sys;
+ ErtsMonotonicTime mon;
+ } time;
+ } intervals[ERTS_MAX_DRIFT_INTERVALS];
+ struct {
+ ErtsMonotonicTime sys;
+ ErtsMonotonicTime mon;
+ } acc;
+ int ix;
+ int dirty_counter;
+} ErtsMonotonicDriftData;
+
+typedef struct {
+ ErtsMonotonicCorrectionInstance prev;
+ ErtsMonotonicCorrectionInstance curr;
+} ErtsMonotonicCorrectionInstances;
+
+typedef struct {
+ ErtsMonotonicCorrectionInstances insts;
+ ErtsMonotonicDriftData drift;
+ ErtsMonotonicTime last_check;
+ int short_check_interval;
+} ErtsMonotonicCorrectionData;
+
+struct time_sup_infrequently_changed__ {
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ struct {
+ erts_smp_rwmtx_t rwmtx;
+ ErtsTWheelTimer timer;
+ ErtsMonotonicCorrectionData cdata;
+ } parmon;
+ ErtsMonotonicTime minit;
+#endif
+ ErtsSystemTime sinit;
+ ErtsMonotonicTime not_corrected_moffset;
+ erts_smp_atomic64_t offset;
+ ErtsMonotonicTime shadow_offset;
+ erts_smp_atomic32_t preliminary_offset;
+};
+
+struct time_sup_frequently_changed__ {
+ ErtsMonotonicTime last_not_corrected_time;
+};
+
+static struct {
+ union {
+ struct time_sup_read_only__ o;
+ char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(struct time_sup_read_only__))];
+ } r;
+ union {
+ struct time_sup_infrequently_changed__ c;
+ char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(struct time_sup_infrequently_changed__))];
+ } inf;
+ union {
+ struct time_sup_frequently_changed__ c;
+ char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(struct time_sup_frequently_changed__))];
+ } f;
+} time_sup erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+
+ErtsTimeSupData erts_time_sup__ erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+
+/*
+ * erts_get_approx_time() returns an *approximate* time
+ * in seconds. NOTE that this time may jump backwards!!!
+ */
+erts_approx_time_t
+erts_get_approx_time(void)
{
- erts_smp_atomic_init_nob(&approx.time, 0);
+ ErtsSystemTime stime = erts_os_system_time();
+ return (erts_approx_time_t) ERTS_MONOTONIC_TO_SEC(stime);
}
-static ERTS_INLINE erts_approx_time_t
-get_approx_time(void)
+static ERTS_INLINE void
+init_time_offset(ErtsMonotonicTime offset)
{
- return (erts_approx_time_t) erts_smp_atomic_read_nob(&approx.time);
+ erts_smp_atomic64_init_nob(&time_sup.inf.c.offset, (erts_aint64_t) offset);
}
static ERTS_INLINE void
-update_approx_time(SysTimeval *tv)
+set_time_offset(ErtsMonotonicTime offset)
+{
+ erts_smp_atomic64_set_relb(&time_sup.inf.c.offset, (erts_aint64_t) offset);
+}
+
+static ERTS_INLINE ErtsMonotonicTime
+get_time_offset(void)
{
- erts_approx_time_t new_secs = (erts_approx_time_t) tv->tv_sec;
- erts_approx_time_t old_secs = get_approx_time();
- if (old_secs != new_secs)
- erts_smp_atomic_set_nob(&approx.time, new_secs);
+ return (ErtsMonotonicTime) erts_smp_atomic64_read_acqb(&time_sup.inf.c.offset);
}
+static ERTS_INLINE void
+update_last_mtime(ErtsSchedulerData *esdp, ErtsMonotonicTime mtime)
+{
+ if (!esdp)
+ esdp = erts_get_scheduler_data();
+ if (esdp) {
+ ASSERT(mtime >= esdp->last_monotonic_time);
+ esdp->last_monotonic_time = mtime;
+ esdp->check_time_reds = 0;
+ }
+}
+
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+
/*
- * erts_get_approx_time() returns an *approximate* time
- * in seconds. NOTE that this time may jump backwards!!!
+ * Time correction adjustments made due to
+ * error between Erlang system time and OS
+ * system time:
+ * - Large adjustment ~1%
+ * - Small adjustment ~0.05%
*/
-erts_approx_time_t
-erts_get_approx_time(void)
+#define ERTS_TCORR_ERR_UNIT 2048
+#define ERTS_TCORR_ERR_LARGE_ADJ 20
+#define ERTS_TCORR_ERR_SMALL_ADJ 1
+
+#define ERTS_INIT_SHORT_INTERVAL_COUNTER 10
+#define ERTS_LONG_TIME_CORRECTION_CHECK ERTS_SEC_TO_MONOTONIC(60)
+#define ERTS_SHORT_TIME_CORRECTION_CHECK ERTS_SEC_TO_MONOTONIC(15)
+
+#define ERTS_TIME_DRIFT_MAX_ADJ_DIFF ERTS_USEC_TO_MONOTONIC(50)
+#define ERTS_TIME_DRIFT_MIN_ADJ_DIFF ERTS_USEC_TO_MONOTONIC(5)
+
+/*
+ * Maximum drift of the OS monotonic clock expected.
+ *
+ * We use 1 milli second per second. If the monotonic
+ * clock drifts more than this we will fail to adjust for
+ * drift, and error correction will kick in instead.
+ * If it is larger than this, one could argue that the
+ * primitive is to poor to be used...
+ */
+#define ERTS_MAX_MONOTONIC_DRIFT ERTS_MSEC_TO_MONOTONIC(1)
+
+/*
+ * We assume that precision is 32 times worse than the
+ * resolution. This is a wild guess, but there are no
+ * practical way to determine actual precision.
+ */
+#define ERTS_ASSUMED_PRECISION_DROP 32
+
+#define ERTS_MIN_MONOTONIC_DRIFT_MEASUREMENT \
+ (ERTS_SHORT_TIME_CORRECTION_CHECK - 2*ERTS_MAX_MONOTONIC_DRIFT)
+
+
+static ERTS_INLINE ErtsMonotonicTime
+calc_corrected_erl_mtime(ErtsMonotonicTime os_mtime,
+ ErtsMonotonicCorrectionInstance *cip,
+ ErtsMonotonicTime *os_mdiff_p,
+ int os_drift_corrected)
{
- return get_approx_time();
+ ErtsMonotonicTime erl_mtime, diff = os_mtime - cip->os_mtime;
+ ERTS_TIME_ASSERT(diff >= 0);
+ if (!os_drift_corrected)
+ diff += (cip->correction.drift*diff)/ERTS_MONOTONIC_TIME_UNIT;
+ erl_mtime = cip->erl_mtime;
+ erl_mtime += diff;
+ erl_mtime += cip->correction.error*(diff/ERTS_TCORR_ERR_UNIT);
+ if (os_mdiff_p)
+ *os_mdiff_p = diff;
+ return erl_mtime;
}
-#ifdef HAVE_GETHRTIME
+static ERTS_INLINE ErtsMonotonicTime
+read_corrected_time(int os_drift_corrected)
+{
+ ErtsMonotonicTime os_mtime;
+ ErtsMonotonicCorrectionInstance ci;
-int erts_disable_tolerant_timeofday;
+ erts_smp_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx);
-static SysHrTime hr_init_time, hr_last_correction_check,
- hr_correction, hr_last_time;
+ os_mtime = erts_os_monotonic_time();
-static void init_tolerant_timeofday(void)
-{
- /* Should be in sys.c */
-#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
- if (sysconf(_SC_NPROCESSORS_CONF) > 1) {
- char b[1024];
- int maj,min,build;
- os_flavor(b,1024);
- os_version(&maj,&min,&build);
- if (!strcmp(b,"sunos") && maj <= 5 && min <= 7) {
- erts_disable_tolerant_timeofday = 1;
- }
+ if (os_mtime >= time_sup.inf.c.parmon.cdata.insts.curr.os_mtime)
+ ci = time_sup.inf.c.parmon.cdata.insts.curr;
+ else {
+ if (os_mtime < time_sup.inf.c.parmon.cdata.insts.prev.os_mtime)
+ erts_exit(ERTS_ABORT_EXIT,
+ "OS monotonic time stepped backwards\n");
+ ci = time_sup.inf.c.parmon.cdata.insts.prev;
}
+
+ erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
+
+ return calc_corrected_erl_mtime(os_mtime, &ci, NULL,
+ os_drift_corrected);
+}
+
+static ErtsMonotonicTime get_os_drift_corrected_time(void)
+{
+ return read_corrected_time(!0);
+}
+
+static ErtsMonotonicTime get_corrected_time(void)
+{
+ return read_corrected_time(0);
+}
+
+#ifdef ERTS_TIME_CORRECTION_PRINT
+
+static ERTS_INLINE void
+print_correction(int change,
+ ErtsMonotonicTime sdiff,
+ ErtsMonotonicTime old_ecorr,
+ ErtsMonotonicTime old_dcorr,
+ ErtsMonotonicTime new_ecorr,
+ ErtsMonotonicTime new_dcorr,
+ Uint tmo)
+{
+ ErtsMonotonicTime usec_sdiff;
+ if (sdiff < 0)
+ usec_sdiff = -1*ERTS_MONOTONIC_TO_USEC(-1*sdiff);
+ else
+ usec_sdiff = ERTS_MONOTONIC_TO_USEC(sdiff);
+
+ if (!change)
+ erts_fprintf(stderr,
+ "sdiff = %b64d usec : [ec=%b64d ppm, dc=%b64d ppb] : "
+ "tmo = %bpu msec\r\n",
+ usec_sdiff,
+ (1000000*old_ecorr) / ERTS_TCORR_ERR_UNIT,
+ (1000000000*old_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
+ tmo);
+ else
+ erts_fprintf(stderr,
+ "sdiff = %b64d usec : [ec=%b64d ppm, dc=%b64d ppb] "
+ "-> [ec=%b64d ppm, dc=%b64d ppb] : tmo = %bpu msec\r\n",
+ usec_sdiff,
+ (1000000*old_ecorr) / ERTS_TCORR_ERR_UNIT,
+ (1000000000*old_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
+ (1000000*new_ecorr) / ERTS_TCORR_ERR_UNIT,
+ (1000000000*new_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
+ tmo);
+}
+
#endif
- hr_init_time = sys_gethrtime();
- hr_last_correction_check = hr_last_time = hr_init_time;
- hr_correction = 0;
+
+static ERTS_INLINE ErtsMonotonicTime
+get_timeout_pos(ErtsMonotonicTime now, ErtsMonotonicTime tmo)
+{
+ ErtsMonotonicTime tpos;
+ tpos = ERTS_MONOTONIC_TO_CLKTCKS(now - 1);
+ tpos += ERTS_MSEC_TO_CLKTCKS(tmo);
+ tpos += 1;
+ return tpos;
}
-static void get_tolerant_timeofday(SysTimeval *tv)
+static void
+check_time_correction(void *vesdp)
{
- SysHrTime diff_time, curr;
+ int init_drift_adj = !vesdp;
+ ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp;
+ ErtsMonotonicCorrection new_correction;
+ ErtsMonotonicCorrectionInstance ci;
+ ErtsMonotonicTime mdiff, sdiff, os_mtime, erl_mtime, os_stime,
+ erl_stime, time_offset, timeout_pos;
+ Uint timeout;
+ int os_drift_corrected = time_sup.r.o.os_corrected_monotonic_time;
+ int set_new_correction = 0, begin_short_intervals = 0;
+
+ erts_smp_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx);
+
+ erts_os_times(&os_mtime, &os_stime);
+
+ ci = time_sup.inf.c.parmon.cdata.insts.curr;
+
+ erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
- if (erts_disable_tolerant_timeofday) {
- sys_gettimeofday(tv);
- return;
+ if (os_mtime < ci.os_mtime)
+ erts_exit(ERTS_ABORT_EXIT,
+ "OS monotonic time stepped backwards\n");
+
+ erl_mtime = calc_corrected_erl_mtime(os_mtime, &ci, &mdiff,
+ os_drift_corrected);
+ time_offset = get_time_offset();
+ erl_stime = erl_mtime + time_offset;
+
+ sdiff = erl_stime - os_stime;
+
+ if (time_sup.inf.c.shadow_offset) {
+ ERTS_TIME_ASSERT(time_sup.r.o.warp_mode == ERTS_SINGLE_TIME_WARP_MODE);
+ if (erts_smp_atomic32_read_nob(&time_sup.inf.c.preliminary_offset))
+ sdiff += time_sup.inf.c.shadow_offset;
+ else
+ time_sup.inf.c.shadow_offset = 0;
}
- *tv = inittv;
- diff_time = ((curr = sys_gethrtime()) + hr_correction - hr_init_time) / 1000;
- if (curr < hr_init_time) {
- erl_exit(1,"Unexpected behaviour from operating system high "
- "resolution timer");
+ new_correction = ci.correction;
+
+ if (time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE
+ && (sdiff < -2*time_sup.r.o.adj.small_diff
+ || 2*time_sup.r.o.adj.small_diff < sdiff)) {
+ /* System time diff exeeded limits; change time offset... */
+ time_offset -= sdiff;
+ sdiff = 0;
+ set_time_offset(time_offset);
+ schedule_send_time_offset_changed_notifications(time_offset);
+ begin_short_intervals = 1;
+ if (ci.correction.error != 0) {
+ set_new_correction = 1;
+ new_correction.error = 0;
+ }
+ }
+ else if ((time_sup.r.o.warp_mode == ERTS_SINGLE_TIME_WARP_MODE
+ && erts_smp_atomic32_read_nob(&time_sup.inf.c.preliminary_offset))
+ && (sdiff < -2*time_sup.r.o.adj.small_diff
+ || 2*time_sup.r.o.adj.small_diff < sdiff)) {
+ /*
+ * System time diff exeeded limits; change shadow offset
+ * and let OS system time leap away from Erlang system
+ * time.
+ */
+ time_sup.inf.c.shadow_offset -= sdiff;
+ sdiff = 0;
+ begin_short_intervals = 1;
+ if (ci.correction.error != 0) {
+ set_new_correction = 1;
+ new_correction.error = 0;
+ }
+ }
+ else if (ci.correction.error == 0) {
+ if (sdiff < -time_sup.r.o.adj.small_diff) {
+ set_new_correction = 1;
+ if (sdiff < -time_sup.r.o.adj.large_diff)
+ new_correction.error = ERTS_TCORR_ERR_LARGE_ADJ;
+ else
+ new_correction.error = ERTS_TCORR_ERR_SMALL_ADJ;
+ }
+ else if (sdiff > time_sup.r.o.adj.small_diff) {
+ set_new_correction = 1;
+ if (sdiff > time_sup.r.o.adj.large_diff)
+ new_correction.error = -ERTS_TCORR_ERR_LARGE_ADJ;
+ else
+ new_correction.error = -ERTS_TCORR_ERR_SMALL_ADJ;
+ }
+ }
+ else if (ci.correction.error > 0) {
+ if (sdiff < 0) {
+ if (ci.correction.error != ERTS_TCORR_ERR_LARGE_ADJ
+ && sdiff < -time_sup.r.o.adj.large_diff) {
+ new_correction.error = ERTS_TCORR_ERR_LARGE_ADJ;
+ set_new_correction = 1;
+ }
+ }
+ else if (sdiff > time_sup.r.o.adj.small_diff) {
+ set_new_correction = 1;
+ if (sdiff > time_sup.r.o.adj.large_diff)
+ new_correction.error = -ERTS_TCORR_ERR_LARGE_ADJ;
+ else
+ new_correction.error = -ERTS_TCORR_ERR_SMALL_ADJ;
+ }
+ else {
+ set_new_correction = 1;
+ new_correction.error = 0;
+ }
+ }
+ else /* if (ci.correction.error < 0) */ {
+ if (0 < sdiff) {
+ if (ci.correction.error != -ERTS_TCORR_ERR_LARGE_ADJ
+ && time_sup.r.o.adj.large_diff < sdiff) {
+ new_correction.error = -ERTS_TCORR_ERR_LARGE_ADJ;
+ set_new_correction = 1;
+ }
+ }
+ else if (sdiff < -time_sup.r.o.adj.small_diff) {
+ set_new_correction = 1;
+ if (sdiff < -time_sup.r.o.adj.large_diff)
+ new_correction.error = ERTS_TCORR_ERR_LARGE_ADJ;
+ else
+ new_correction.error = ERTS_TCORR_ERR_SMALL_ADJ;
+ }
+ else {
+ set_new_correction = 1;
+ new_correction.error = 0;
+ }
}
- if ((curr - hr_last_correction_check) / 1000 > 1000000) {
- /* Check the correction need */
- SysHrTime tv_diff, diffdiff;
- SysTimeval tmp;
- int done = 0;
-
- sys_gettimeofday(&tmp);
- tv_diff = ((SysHrTime) tmp.tv_sec) * 1000000 + tmp.tv_usec;
- tv_diff -= ((SysHrTime) inittv.tv_sec) * 1000000 + inittv.tv_usec;
- diffdiff = diff_time - tv_diff;
- if (diffdiff > 10000) {
- SysHrTime corr = (curr - hr_last_time) / 100;
- if (corr / 1000 >= diffdiff) {
- ++done;
- hr_correction -= ((SysHrTime)diffdiff) * 1000;
- } else {
- hr_correction -= corr;
+ if (!os_drift_corrected) {
+ ErtsMonotonicDriftData *ddp = &time_sup.inf.c.parmon.cdata.drift;
+ int ix = ddp->ix;
+ ErtsMonotonicTime mtime_diff, old_os_mtime;
+
+ old_os_mtime = ddp->intervals[ix].time.mon;
+ mtime_diff = os_mtime - old_os_mtime;
+
+ if ((mtime_diff >= ERTS_MIN_MONOTONIC_DRIFT_MEASUREMENT)
+ | init_drift_adj) {
+ ErtsMonotonicTime drift_adj, drift_adj_diff, old_os_stime,
+ smtime_diff, stime_diff, mtime_acc, stime_acc,
+ avg_drift_adj, max_drift;
+
+ old_os_stime = ddp->intervals[ix].time.sys;
+
+ mtime_acc = ddp->acc.mon;
+ stime_acc = ddp->acc.sys;
+
+ avg_drift_adj = (((stime_acc - mtime_acc)
+ * ERTS_MONOTONIC_TIME_UNIT)
+ / mtime_acc);
+
+ mtime_diff = os_mtime - old_os_mtime;
+ stime_diff = os_stime - old_os_stime;
+ smtime_diff = stime_diff - mtime_diff;
+ ix++;
+ if (ix >= time_sup.r.o.drift_adj.intervals)
+ ix = 0;
+ mtime_acc -= ddp->intervals[ix].diff.mon;
+ mtime_acc += mtime_diff;
+ stime_acc -= ddp->intervals[ix].diff.sys;
+ stime_acc += stime_diff;
+
+ ddp->intervals[ix].diff.mon = mtime_diff;
+ ddp->intervals[ix].diff.sys = stime_diff;
+ ddp->intervals[ix].time.mon = os_mtime;
+ ddp->intervals[ix].time.sys = os_stime;
+
+ ddp->ix = ix;
+ ddp->acc.mon = mtime_acc;
+ ddp->acc.sys = stime_acc;
+
+ max_drift = ERTS_MAX_MONOTONIC_DRIFT;
+ max_drift *= ERTS_MONOTONIC_TO_SEC(mtime_diff);
+
+ if (smtime_diff > time_sup.r.o.drift_adj.error + max_drift
+ || smtime_diff < -1*time_sup.r.o.drift_adj.error - max_drift) {
+ dirty_intervals:
+ /*
+ * We had a leap in system time. Mark array as
+ * dirty to ensure that dirty values are rotated
+ * out before we use it again...
+ */
+ ddp->dirty_counter = time_sup.r.o.drift_adj.intervals;
+ begin_short_intervals = 1;
}
- diff_time = (curr + hr_correction - hr_init_time) / 1000;
- } else if (diffdiff < -10000) {
- SysHrTime corr = (curr - hr_last_time) / 100;
- if (corr / 1000 >= -diffdiff) {
- ++done;
- hr_correction -= ((SysHrTime)diffdiff) * 1000;
- } else {
- hr_correction += corr;
+ else if (ddp->dirty_counter > 0) {
+ if (init_drift_adj) {
+ new_correction.drift = ((smtime_diff
+ * ERTS_MONOTONIC_TIME_UNIT)
+ / mtime_diff);
+ set_new_correction = 1;
+ }
+ ddp->dirty_counter--;
+ }
+ else {
+ if (ddp->dirty_counter == 0) {
+ /* Force set new drift correction... */
+ set_new_correction = 1;
+ ddp->dirty_counter--;
+ }
+
+ if (time_sup.r.o.drift_adj.use_avg)
+ drift_adj = (((stime_acc - mtime_acc)
+ * ERTS_MONOTONIC_TIME_UNIT)
+ / mtime_acc);
+ else
+ drift_adj = ((smtime_diff
+ * ERTS_MONOTONIC_TIME_UNIT)
+ / mtime_diff);
+
+ drift_adj_diff = avg_drift_adj - drift_adj;
+ if (drift_adj_diff < -ERTS_TIME_DRIFT_MAX_ADJ_DIFF
+ || ERTS_TIME_DRIFT_MAX_ADJ_DIFF < drift_adj_diff)
+ goto dirty_intervals;
+
+ drift_adj_diff = drift_adj - new_correction.drift;
+ if (drift_adj_diff) {
+ if (drift_adj_diff > ERTS_TIME_DRIFT_MAX_ADJ_DIFF)
+ drift_adj_diff = ERTS_TIME_DRIFT_MAX_ADJ_DIFF;
+ else if (drift_adj_diff < -ERTS_TIME_DRIFT_MAX_ADJ_DIFF)
+ drift_adj_diff = -ERTS_TIME_DRIFT_MAX_ADJ_DIFF;
+ new_correction.drift += drift_adj_diff;
+ if (drift_adj_diff < -ERTS_TIME_DRIFT_MIN_ADJ_DIFF
+ || ERTS_TIME_DRIFT_MIN_ADJ_DIFF < drift_adj_diff) {
+ set_new_correction = 1;
+ }
+ }
}
- diff_time = (curr + hr_correction - hr_init_time) / 1000;
- } else {
- ++done;
}
- if (done) {
- hr_last_correction_check = curr;
+ }
+
+ begin_short_intervals |= set_new_correction;
+
+ if (begin_short_intervals) {
+ time_sup.inf.c.parmon.cdata.short_check_interval
+ = ERTS_INIT_SHORT_INTERVAL_COUNTER;
+ }
+ else if ((os_mtime - time_sup.inf.c.parmon.cdata.last_check
+ >= ERTS_SHORT_TIME_CORRECTION_CHECK - ERTS_MONOTONIC_TIME_UNIT)
+ && time_sup.inf.c.parmon.cdata.short_check_interval > 0) {
+ time_sup.inf.c.parmon.cdata.short_check_interval--;
+ }
+ time_sup.inf.c.parmon.cdata.last_check = os_mtime;
+
+ if (new_correction.error == 0)
+ timeout = ERTS_MONOTONIC_TO_MSEC(ERTS_LONG_TIME_CORRECTION_CHECK);
+ else {
+ ErtsMonotonicTime ecorr = new_correction.error;
+ ErtsMonotonicTime abs_sdiff;
+ abs_sdiff = (sdiff < 0) ? -1*sdiff : sdiff;
+ if (ecorr < 0)
+ ecorr = -1*ecorr;
+ if (abs_sdiff > ecorr*(ERTS_LONG_TIME_CORRECTION_CHECK/ERTS_TCORR_ERR_UNIT))
+ timeout = ERTS_MONOTONIC_TO_MSEC(ERTS_LONG_TIME_CORRECTION_CHECK);
+ else {
+ timeout = ERTS_MONOTONIC_TO_MSEC((ERTS_TCORR_ERR_UNIT*abs_sdiff)/ecorr);
+ if (timeout < 10)
+ timeout = 10;
}
}
- tv->tv_sec += (int) (diff_time / ((SysHrTime) 1000000));
- tv->tv_usec += (int) (diff_time % ((SysHrTime) 1000000));
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec += 1;
+
+ if (timeout > ERTS_MONOTONIC_TO_MSEC(ERTS_SHORT_TIME_CORRECTION_CHECK)
+ && (time_sup.inf.c.parmon.cdata.short_check_interval
+ || time_sup.inf.c.parmon.cdata.drift.dirty_counter >= 0)) {
+ timeout = ERTS_MONOTONIC_TO_MSEC(ERTS_SHORT_TIME_CORRECTION_CHECK);
+ }
+
+ timeout_pos = get_timeout_pos(erl_mtime, timeout);
+
+#ifdef ERTS_TIME_CORRECTION_PRINT
+ print_correction(set_new_correction,
+ sdiff,
+ ci.correction.error,
+ ci.correction.drift,
+ new_correction.error,
+ new_correction.drift,
+ timeout);
+#endif
+
+ if (set_new_correction) {
+ erts_smp_rwmtx_rwlock(&time_sup.inf.c.parmon.rwmtx);
+
+ os_mtime = erts_os_monotonic_time();
+
+ /* Save previous correction instance */
+ time_sup.inf.c.parmon.cdata.insts.prev = ci;
+
+ /*
+ * Current correction instance begin when
+ * OS monotonic time has increased two units.
+ */
+ os_mtime += 2;
+
+ /*
+ * Erlang monotonic time corresponding to
+ * next OS monotonic time using previous
+ * correction.
+ */
+ erl_mtime = calc_corrected_erl_mtime(os_mtime, &ci, NULL,
+ os_drift_corrected);
+
+ /*
+ * Save new current correction instance.
+ */
+ time_sup.inf.c.parmon.cdata.insts.curr.erl_mtime = erl_mtime;
+ time_sup.inf.c.parmon.cdata.insts.curr.os_mtime = os_mtime;
+ time_sup.inf.c.parmon.cdata.insts.curr.correction = new_correction;
+
+ erts_smp_rwmtx_rwunlock(&time_sup.inf.c.parmon.rwmtx);
}
- hr_last_time = curr;
+
+ if (!esdp)
+ esdp = erts_get_scheduler_data();
+
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &time_sup.inf.c.parmon.timer,
+ check_time_correction,
+ NULL,
+ (void *) esdp,
+ timeout_pos);
}
-#define correction (hr_correction/1000000)
+static ErtsMonotonicTime get_os_corrected_time(void)
+{
+ ASSERT(time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE);
+ return erts_os_monotonic_time() + time_sup.r.o.moffset;
+}
-#else /* !HAVE_GETHRTIME */
-#if !defined(CORRECT_USING_TIMES)
-#define init_tolerant_timeofday()
-#define get_tolerant_timeofday(tvp) sys_gettimeofday(tvp)
-#else
+static void
+check_time_offset(void *vesdp)
+{
+ ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp;
+ ErtsMonotonicTime sdiff, os_mtime, erl_mtime, os_stime,
+ erl_stime, time_offset, timeout, timeout_pos;
-typedef Sint64 Milli;
-
-static clock_t init_ct;
-static Sint64 ct_wrap;
-static Milli init_tv_m;
-static Milli correction_supress;
-static Milli last_ct_diff;
-static Milli last_cc;
-static clock_t last_ct;
-
-/* sys_times() might need to be wrapped and the values shifted (right)
- a bit to cope with newer linux (2.5.*) kernels, this has to be taken care
- of dynamically to start with, a special version that uses
- the times() return value as a high resolution timer can be made
- to fully utilize the faster ticks, like on windows, but for now, we'll
- settle with this silly workaround */
-#ifdef ERTS_WRAP_SYS_TIMES
-#define KERNEL_TICKS() (sys_times_wrap() & \
- ((1UL << ((sizeof(clock_t) * 8) - 1)) - 1))
-#else
-SysTimes dummy_tms;
+ ASSERT(time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE);
+
+ erts_os_times(&os_mtime, &os_stime);
+
+ erl_mtime = os_mtime + time_sup.r.o.moffset;
+ time_offset = get_time_offset();
+ erl_stime = erl_mtime + time_offset;
-#define KERNEL_TICKS() (sys_times(&dummy_tms) & \
- ((1UL << ((sizeof(clock_t) * 8) - 1)) - 1))
+ sdiff = erl_stime - os_stime;
+ if ((sdiff < -2*time_sup.r.o.adj.small_diff
+ || 2*time_sup.r.o.adj.small_diff < sdiff)) {
+ /* System time diff exeeded limits; change time offset... */
+#ifdef ERTS_TIME_CORRECTION_PRINT
+ erts_fprintf(stderr, "sdiff = %b64d nsec -> 0 nsec\n",
+ ERTS_MONOTONIC_TO_NSEC(sdiff));
#endif
+ time_offset -= sdiff;
+ sdiff = 0;
+ set_time_offset(time_offset);
+ schedule_send_time_offset_changed_notifications(time_offset);
+ }
+#ifdef ERTS_TIME_CORRECTION_PRINT
+ else erts_fprintf(stderr, "sdiff = %b64d nsec\n",
+ ERTS_MONOTONIC_TO_NSEC(sdiff));
+#endif
+
+ timeout = ERTS_MONOTONIC_TO_MSEC(ERTS_LONG_TIME_CORRECTION_CHECK);
+ timeout_pos = get_timeout_pos(erl_mtime, timeout);
+
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &time_sup.inf.c.parmon.timer,
+ check_time_offset,
+ NULL,
+ vesdp,
+ timeout_pos);
+}
+
+static void
+init_check_time_correction(void *vesdp)
+{
+ ErtsMonotonicDriftData *ddp;
+ ErtsMonotonicTime old_mtime, old_stime, mtime, stime, mtime_diff,
+ stime_diff, smtime_diff, max_drift;
+ int ix;
+
+ ddp = &time_sup.inf.c.parmon.cdata.drift;
+ ix = ddp->ix;
+ old_mtime = ddp->intervals[0].time.mon;
+ old_stime = ddp->intervals[0].time.sys;
+
+ erts_os_times(&mtime, &stime);
+
+ mtime_diff = mtime - old_mtime;
+ stime_diff = stime - old_stime;
+ smtime_diff = stime_diff - mtime_diff;
+
+ max_drift = ERTS_MAX_MONOTONIC_DRIFT;
+ max_drift *= ERTS_MONOTONIC_TO_SEC(mtime_diff);
+
+ if (smtime_diff > time_sup.r.o.drift_adj.error + max_drift
+ || smtime_diff < -1*time_sup.r.o.drift_adj.error - max_drift) {
+ /* Had a system time leap... pretend no drift... */
+ stime_diff = mtime_diff;
+ }
+
+ /*
+ * We use old time values in order to trigger
+ * a drift adjustment, and repeat this interval
+ * in all slots...
+ */
+ for (ix = 0; ix < time_sup.r.o.drift_adj.intervals; ix++) {
+ ddp->intervals[ix].diff.mon = mtime_diff;
+ ddp->intervals[ix].diff.sys = stime_diff;
+ ddp->intervals[ix].time.mon = old_mtime;
+ ddp->intervals[ix].time.sys = old_stime;
+ }
+
+ ddp->acc.sys = stime_diff*time_sup.r.o.drift_adj.intervals;
+ ddp->acc.mon = mtime_diff*time_sup.r.o.drift_adj.intervals;
+ ddp->ix = 0;
+ ddp->dirty_counter = time_sup.r.o.drift_adj.intervals;
+
+ check_time_correction(vesdp);
+}
+
+static ErtsMonotonicTime
+finalize_corrected_time_offset(ErtsSystemTime *stimep)
+{
+ ErtsMonotonicTime os_mtime;
+ ErtsMonotonicCorrectionInstance ci;
+ int os_drift_corrected = time_sup.r.o.os_corrected_monotonic_time;
+
+ erts_smp_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx);
+
+ erts_os_times(&os_mtime, stimep);
+
+ ci = time_sup.inf.c.parmon.cdata.insts.curr;
-static void init_tolerant_timeofday(void)
+ erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
+
+ if (os_mtime < ci.os_mtime)
+ erts_exit(ERTS_ABORT_EXIT,
+ "OS monotonic time stepped backwards\n");
+
+ return calc_corrected_erl_mtime(os_mtime, &ci, NULL,
+ os_drift_corrected);
+}
+
+static void
+late_init_time_correction(ErtsSchedulerData *esdp)
{
- last_ct = init_ct = KERNEL_TICKS();
- last_cc = 0;
- init_tv_m = (((Milli) inittv.tv_sec) * 1000) +
- (inittv.tv_usec / 1000);
- ct_wrap = 0;
- correction_supress = 0;
+ int quick_init_drift_adj;
+ void (*check_func)(void *);
+ ErtsMonotonicTime timeout, timeout_pos;
+
+ quick_init_drift_adj =
+ ERTS_MONOTONIC_TO_USEC(time_sup.r.o.drift_adj.error) == 0;
+
+ if (quick_init_drift_adj)
+ timeout = ERTS_MONOTONIC_TO_MSEC(ERTS_SHORT_TIME_CORRECTION_CHECK/10);
+ else
+ timeout = ERTS_MONOTONIC_TO_MSEC(ERTS_SHORT_TIME_CORRECTION_CHECK);
+
+ if (!time_sup.r.o.os_corrected_monotonic_time)
+ check_func = init_check_time_correction;
+ else if (time_sup.r.o.get_time == get_os_corrected_time) {
+ quick_init_drift_adj = 0;
+ check_func = check_time_offset;
+ }
+ else
+ check_func = check_time_correction;
+
+ timeout_pos = get_timeout_pos(erts_get_monotonic_time(esdp),
+ timeout);
+
+ erts_twheel_init_timer(&time_sup.inf.c.parmon.timer);
+ erts_twheel_set_timer(esdp->timer_wheel,
+ &time_sup.inf.c.parmon.timer,
+ check_func,
+ NULL,
+ (quick_init_drift_adj
+ ? NULL
+ : esdp),
+ timeout_pos);
}
+#endif /* ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT */
-static void get_tolerant_timeofday(SysTimeval *tvp)
+static ErtsMonotonicTime get_not_corrected_time(void)
{
- clock_t current_ct;
- SysTimeval current_tv;
- Milli ct_diff;
- Milli tv_diff;
- Milli current_correction;
- Milli act_correction; /* long shown to be too small */
- Milli max_adjust;
+ ErtsMonotonicTime stime, mtime;
+
+ erts_smp_mtx_lock(&erts_get_time_mtx);
+
+ stime = erts_os_system_time();
+
+ mtime = stime - time_sup.inf.c.not_corrected_moffset;
+
+ if (mtime >= time_sup.f.c.last_not_corrected_time)
+ time_sup.f.c.last_not_corrected_time = mtime;
+ else {
+ mtime = time_sup.f.c.last_not_corrected_time;
+
+ if (time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE) {
+ ErtsMonotonicTime new_offset = stime - mtime;
+ new_offset = ERTS_MONOTONIC_TO_USEC(new_offset);
+ new_offset = ERTS_USEC_TO_MONOTONIC(new_offset);
+ if (time_sup.inf.c.not_corrected_moffset != new_offset) {
+ time_sup.inf.c.not_corrected_moffset = new_offset;
+ set_time_offset(new_offset);
+ schedule_send_time_offset_changed_notifications(new_offset);
+ }
+ }
- if (erts_disable_tolerant_timeofday) {
- sys_gettimeofday(tvp);
- return;
}
-#ifdef ERTS_WRAP_SYS_TIMES
-#define TICK_MS (1000 / SYS_CLK_TCK_WRAP)
+ ASSERT(stime == mtime + time_sup.inf.c.not_corrected_moffset);
+
+ erts_smp_mtx_unlock(&erts_get_time_mtx);
+
+ return mtime;
+}
+
+int erts_check_time_adj_support(int time_correction,
+ ErtsTimeWarpMode time_warp_mode)
+{
+ if (!time_correction)
+ return 1;
+
+ /* User wants time correction */
+
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ return !time_sup.r.o.os_monotonic_time_disable;
#else
-#define TICK_MS (1000 / SYS_CLK_TCK)
+ return 0;
#endif
- current_ct = KERNEL_TICKS();
- sys_gettimeofday(&current_tv);
-
- /* I dont know if uptime can move some units backwards
- on some systems, but I allow for small backward
- jumps to avoid such problems if they exist...*/
- if (last_ct > 100 && current_ct < (last_ct - 100)) {
- ct_wrap += ((Sint64) 1) << ((sizeof(clock_t) * 8) - 1);
- }
- last_ct = current_ct;
- ct_diff = ((ct_wrap + current_ct) - init_ct) * TICK_MS;
+}
+
+int
+erts_has_time_correction(void)
+{
+ return time_sup.r.o.correction;
+}
+
+void erts_init_sys_time_sup(void)
+{
+ ErtsSysInitTimeResult sys_init_time_res
+ = ERTS_SYS_INIT_TIME_RESULT_INITER;
+
+ sys_init_time(&sys_init_time_res);
+
+ erts_time_sup__.r.o.monotonic_time_unit
+ = sys_init_time_res.os_monotonic_time_unit;
+
+#ifndef SYS_CLOCK_RESOLUTION
+ erts_time_sup__.r.o.clktck_resolution
+ = sys_init_time_res.sys_clock_resolution;
+ erts_time_sup__.r.o.clktck_resolution *= 1000;
+#endif
+
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ time_sup.r.o.os_monotonic_time_disable
+ = !sys_init_time_res.have_os_monotonic_time;
+ time_sup.r.o.os_corrected_monotonic_time =
+ sys_init_time_res.have_corrected_os_monotonic_time;
+ time_sup.r.o.os_monotonic_time_func
+ = sys_init_time_res.os_monotonic_time_info.func;
+ time_sup.r.o.os_monotonic_time_clock_id
+ = sys_init_time_res.os_monotonic_time_info.clock_id;
+ time_sup.r.o.os_monotonic_time_locked
+ = sys_init_time_res.os_monotonic_time_info.locked_use;
+ time_sup.r.o.os_monotonic_time_resolution
+ = sys_init_time_res.os_monotonic_time_info.resolution;
+ time_sup.r.o.os_monotonic_time_extended
+ = sys_init_time_res.os_monotonic_time_info.extended;
+#endif
+ time_sup.r.o.os_system_time_func
+ = sys_init_time_res.os_system_time_info.func;
+ time_sup.r.o.os_system_time_clock_id
+ = sys_init_time_res.os_system_time_info.clock_id;
+ time_sup.r.o.os_system_time_locked
+ = sys_init_time_res.os_system_time_info.locked_use;
+ time_sup.r.o.os_system_time_resolution
+ = sys_init_time_res.os_system_time_info.resolution;
+}
+
+int
+erts_init_time_sup(int time_correction, ErtsTimeWarpMode time_warp_mode)
+{
+ ErtsMonotonicTime resolution, ilength, intervals, short_isecs;
+#if !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
+ ErtsMonotonicTime abs_native_offset, native_offset;
+#endif
+
+ init_time_napi();
+
+ erts_hl_timer_init();
+
+ ASSERT(ERTS_MONOTONIC_TIME_MIN < ERTS_MONOTONIC_TIME_MAX);
+
+ erts_smp_mtx_init(&erts_timeofday_mtx, "timeofday");
+ erts_smp_mtx_init(&erts_get_time_mtx, "get_time");
+
+ time_sup.r.o.correction = time_correction;
+ time_sup.r.o.warp_mode = time_warp_mode;
+
+ if (time_warp_mode == ERTS_SINGLE_TIME_WARP_MODE)
+ erts_smp_atomic32_init_nob(&time_sup.inf.c.preliminary_offset, 1);
+ else
+ erts_smp_atomic32_init_nob(&time_sup.inf.c.preliminary_offset, 0);
+ time_sup.inf.c.shadow_offset = 0;
+
+#if !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
/*
- * We will adjust the time in milliseconds and we allow for 1%
- * adjustments, but if this function is called more often then every 100
- * millisecond (which is obviously possible), we will never adjust, so
- * we accumulate small times by setting last_ct_diff iff max_adjust > 0
+ * NOTE! erts_time_sup__.r.o.start *need* to be a multiple
+ * of ERTS_MONOTONIC_TIME_UNIT.
*/
- if ((max_adjust = (ct_diff - last_ct_diff)/100) > 0)
- last_ct_diff = ct_diff;
- tv_diff = ((((Milli) current_tv.tv_sec) * 1000) +
- (current_tv.tv_usec / 1000)) - init_tv_m;
+#ifdef ARCH_32
+ erts_time_sup__.r.o.start = ((((ErtsMonotonicTime) 1) << 32)-1);
+ erts_time_sup__.r.o.start /= ERTS_MONOTONIC_TIME_UNIT;
+ erts_time_sup__.r.o.start *= ERTS_MONOTONIC_TIME_UNIT;
+ erts_time_sup__.r.o.start += ERTS_MONOTONIC_TIME_UNIT;
+ native_offset = erts_time_sup__.r.o.start - ERTS_MONOTONIC_BEGIN;
+ abs_native_offset = native_offset;
+#else /* ARCH_64 */
+ if (ERTS_MONOTONIC_TIME_UNIT <= 10*1000*1000) {
+ erts_time_sup__.r.o.start = 0;
+ native_offset = -ERTS_MONOTONIC_BEGIN;
+ abs_native_offset = ERTS_MONOTONIC_BEGIN;
+ }
+ else {
+ erts_time_sup__.r.o.start = ((ErtsMonotonicTime) MIN_SMALL);
+ erts_time_sup__.r.o.start /= ERTS_MONOTONIC_TIME_UNIT;
+ erts_time_sup__.r.o.start *= ERTS_MONOTONIC_TIME_UNIT;
+ native_offset = erts_time_sup__.r.o.start - ERTS_MONOTONIC_BEGIN;
+ abs_native_offset = -1*native_offset;
+ }
+#endif
- current_correction = ((ct_diff - tv_diff) / TICK_MS) * TICK_MS; /* trunc */
+ erts_time_sup__.r.o.start_offset.native = native_offset;
+ erts_time_sup__.r.o.start_offset.nsec = (ErtsMonotonicTime)
+ erts_time_unit_conversion((Uint64) abs_native_offset,
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT,
+ (Uint32) 1000*1000*1000);
+ erts_time_sup__.r.o.start_offset.usec = (ErtsMonotonicTime)
+ erts_time_unit_conversion((Uint64) abs_native_offset,
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT,
+ (Uint32) 1000*1000);
+ erts_time_sup__.r.o.start_offset.msec = (ErtsMonotonicTime)
+ erts_time_unit_conversion((Uint64) abs_native_offset,
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT,
+ (Uint32) 1000);
+ erts_time_sup__.r.o.start_offset.sec = (ErtsMonotonicTime)
+ erts_time_unit_conversion((Uint64) abs_native_offset,
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT,
+ (Uint32) 1);
+ if (native_offset < 0) {
+ erts_time_sup__.r.o.start_offset.nsec *= -1;
+ erts_time_sup__.r.o.start_offset.usec *= -1;
+ erts_time_sup__.r.o.start_offset.msec *= -1;
+ erts_time_sup__.r.o.start_offset.sec *= -1;
+ }
- /*
- * We allow the current_correction value to wobble a little, as it
- * suffers from the low resolution of the kernel ticks.
- * if it hasn't changed more than one tick in either direction,
- * we will keep the old value.
- */
- if ((last_cc > current_correction + TICK_MS) ||
- (last_cc < current_correction - TICK_MS)) {
- last_cc = current_correction;
- } else {
- current_correction = last_cc;
+#endif
+
+ resolution = time_sup.r.o.os_system_time_resolution;
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ if (resolution > time_sup.r.o.os_monotonic_time_resolution)
+ resolution = time_sup.r.o.os_monotonic_time_resolution;
+#endif
+
+ time_sup.r.o.adj.large_diff = erts_time_sup__.r.o.monotonic_time_unit;
+ time_sup.r.o.adj.large_diff *= 50;
+ time_sup.r.o.adj.large_diff /= resolution;
+ if (time_sup.r.o.adj.large_diff < ERTS_USEC_TO_MONOTONIC(500))
+ time_sup.r.o.adj.large_diff = ERTS_USEC_TO_MONOTONIC(500);
+ time_sup.r.o.adj.small_diff = time_sup.r.o.adj.large_diff/10;
+
+ time_sup.r.o.drift_adj.resolution = resolution;
+
+ if (time_sup.r.o.os_corrected_monotonic_time) {
+ time_sup.r.o.drift_adj.use_avg = 0;
+ time_sup.r.o.drift_adj.intervals = 0;
+ time_sup.r.o.drift_adj.error = 0;
+ time_sup.inf.c.parmon.cdata.drift.dirty_counter = -1;
}
-
- /*
- * As time goes, we try to get the actual correction to 0,
- * that is, make erlangs time correspond to the systems dito.
- * The act correction is what we seem to need (current_correction)
- * minus the correction suppression. The correction supression
- * will change slowly (max 1% of elapsed time) but in millisecond steps.
- */
- act_correction = current_correction - correction_supress;
- if (max_adjust > 0) {
+ else {
/*
- * Here we slowly adjust erlangs time to correspond with the
- * system time by changing the correction_supress variable.
- * It can change max_adjust milliseconds which is 1% of elapsed time
+ * Calculate length of the interval in seconds needed
+ * in order to get an error that is at most 1 micro second.
+ * If this interval is longer than the short time correction
+ * check interval we use the average of all values instead
+ * of the latest value.
*/
- if (act_correction > 0) {
- if (current_correction - correction_supress > max_adjust) {
- correction_supress += max_adjust;
- } else {
- correction_supress = current_correction;
- }
- act_correction = current_correction - correction_supress;
- } else if (act_correction < 0) {
- if (correction_supress - current_correction > max_adjust) {
- correction_supress -= max_adjust;
- } else {
- correction_supress = current_correction;
- }
- act_correction = current_correction - correction_supress;
+ short_isecs = ERTS_MONOTONIC_TO_SEC(ERTS_SHORT_TIME_CORRECTION_CHECK);
+ ilength = ERTS_ASSUMED_PRECISION_DROP * ERTS_MONOTONIC_TIME_UNIT;
+ ilength /= (resolution * ERTS_USEC_TO_MONOTONIC(1));
+ time_sup.r.o.drift_adj.use_avg = ilength > short_isecs;
+
+ if (ilength == 0)
+ intervals = 5;
+ else {
+ intervals = ilength / short_isecs;
+ if (intervals > ERTS_MAX_DRIFT_INTERVALS)
+ intervals = ERTS_MAX_DRIFT_INTERVALS;
+ else if (intervals < 5)
+ intervals = 5;
}
+ time_sup.r.o.drift_adj.intervals = (int) intervals;
+
+ /*
+ * drift_adj.error equals maximum assumed error
+ * over a short time interval. We use this value also
+ * when examining a large interval. In this case the
+ * error will be smaller, but we do not want to
+ * recalculate this over and over again.
+ */
+
+ time_sup.r.o.drift_adj.error = ERTS_MONOTONIC_TIME_UNIT;
+ time_sup.r.o.drift_adj.error *= ERTS_ASSUMED_PRECISION_DROP;
+ time_sup.r.o.drift_adj.error /= resolution * short_isecs;
}
- /*
- * The actual correction will correct the timeval so that system
- * time warps gets smothed down.
- */
- current_tv.tv_sec += act_correction / 1000;
- current_tv.tv_usec += (act_correction % 1000) * 1000;
-
- if (current_tv.tv_usec >= 1000000) {
- ++current_tv.tv_sec ;
- current_tv.tv_usec -= 1000000;
- } else if (current_tv.tv_usec < 0) {
- --current_tv.tv_sec;
- current_tv.tv_usec += 1000000;
+#ifdef ERTS_TIME_CORRECTION_PRINT
+ erts_fprintf(stderr, "resolution = %b64d\n", resolution);
+ erts_fprintf(stderr, "adj large diff = %b64d usec\n",
+ ERTS_MONOTONIC_TO_USEC(time_sup.r.o.adj.large_diff));
+ erts_fprintf(stderr, "adj small diff = %b64d usec\n",
+ ERTS_MONOTONIC_TO_USEC(time_sup.r.o.adj.small_diff));
+ if (!time_sup.r.o.os_corrected_monotonic_time) {
+ erts_fprintf(stderr, "drift intervals = %d\n",
+ time_sup.r.o.drift_adj.intervals);
+ erts_fprintf(stderr, "drift adj error = %b64d usec\n",
+ ERTS_MONOTONIC_TO_USEC(time_sup.r.o.drift_adj.error));
+ erts_fprintf(stderr, "drift adj max diff = %b64d nsec\n",
+ ERTS_MONOTONIC_TO_NSEC(ERTS_TIME_DRIFT_MAX_ADJ_DIFF));
+ erts_fprintf(stderr, "drift adj min diff = %b64d nsec\n",
+ ERTS_MONOTONIC_TO_NSEC(ERTS_TIME_DRIFT_MIN_ADJ_DIFF));
}
- *tvp = current_tv;
-#undef TICK_MS
-}
+#endif
-#endif /* CORRECT_USING_TIMES */
-#endif /* !HAVE_GETHRTIME */
+ if (ERTS_MONOTONIC_TIME_UNIT < ERTS_CLKTCK_RESOLUTION)
+ ERTS_INTERNAL_ERROR("Too small monotonic time time unit");
-/*
-** Why this? Well, most platforms have a constant clock resolution of 1,
-** we dont want the deliver_time/time_remaining routines to waste
-** time dividing and multiplying by/with a variable that's always one.
-** so the return value of sys_init_time is ignored on those platforms.
-*/
-
-#ifndef SYS_CLOCK_RESOLUTION
-static int clock_resolution;
-#define CLOCK_RESOLUTION clock_resolution
+#ifndef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ time_sup.r.o.correction = 0;
#else
-#define CLOCK_RESOLUTION SYS_CLOCK_RESOLUTION
+ if (time_sup.r.o.os_monotonic_time_disable)
+ time_sup.r.o.correction = 0;
+
+ if (time_sup.r.o.correction) {
+ ErtsMonotonicCorrectionData *cdatap;
+ erts_smp_rwmtx_opt_t rwmtx_opts = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
+ ErtsMonotonicTime offset;
+ erts_os_times(&time_sup.inf.c.minit,
+ &time_sup.inf.c.sinit);
+ time_sup.r.o.moffset = -1*time_sup.inf.c.minit;
+ time_sup.r.o.moffset += ERTS_MONOTONIC_BEGIN;
+ offset = time_sup.inf.c.sinit;
+ offset -= ERTS_MONOTONIC_BEGIN;
+ init_time_offset(offset);
+
+ rwmtx_opts.type = ERTS_SMP_RWMTX_TYPE_EXTREMELY_FREQUENT_READ;
+ rwmtx_opts.lived = ERTS_SMP_RWMTX_LONG_LIVED;
+
+ erts_smp_rwmtx_init_opt(&time_sup.inf.c.parmon.rwmtx,
+ &rwmtx_opts, "get_corrected_time");
+
+ cdatap = &time_sup.inf.c.parmon.cdata;
+
+ cdatap->drift.intervals[0].time.sys = time_sup.inf.c.sinit;
+ cdatap->drift.intervals[0].time.mon = time_sup.inf.c.minit;
+ cdatap->insts.curr.correction.drift = 0;
+ cdatap->insts.curr.correction.error = 0;
+ cdatap->insts.curr.erl_mtime = ERTS_MONOTONIC_BEGIN;
+ cdatap->insts.curr.os_mtime = time_sup.inf.c.minit;
+ cdatap->last_check = time_sup.inf.c.minit;
+ cdatap->short_check_interval = ERTS_INIT_SHORT_INTERVAL_COUNTER;
+ cdatap->insts.prev = cdatap->insts.curr;
+
+ if (!time_sup.r.o.os_corrected_monotonic_time)
+ time_sup.r.o.get_time = get_corrected_time;
+ else if (time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE)
+ time_sup.r.o.get_time = get_os_corrected_time;
+ else
+ time_sup.r.o.get_time = get_os_drift_corrected_time;
+ }
+ else
#endif
+ {
+ ErtsMonotonicTime stime, offset;
+ time_sup.r.o.get_time = get_not_corrected_time;
+ stime = time_sup.inf.c.sinit = erts_os_system_time();
+ offset = stime - ERTS_MONOTONIC_BEGIN;
+ time_sup.inf.c.not_corrected_moffset = offset;
+ init_time_offset(offset);
+ time_sup.f.c.last_not_corrected_time = 0;
+ }
-/*
-** The clock resolution should really be the resolution of the
-** time function in use, which on most platforms
-** is 1. On VxWorks the resolution should be
-** the number of ticks per second (or 1, which would work nicely to).
-**
-** Setting lower resolutions is mostly interesting when timers are used
-** instead of something like select.
-*/
+ prev_wall_clock_elapsed = 0;
+
+ previous_now = ERTS_MONOTONIC_TO_USEC(get_time_offset());
-static SysTimeval last_delivered;
+#ifdef DEBUG
+ time_sup_initialized = 1;
+#endif
-static void init_erts_deliver_time(const SysTimeval *inittv)
+ return ERTS_CLKTCK_RESOLUTION/1000;
+}
+
+void
+erts_late_init_time_sup(void)
{
- /* We set the initial values for deliver_time here */
- last_delivered = *inittv;
- last_delivered.tv_usec = 1000 * (last_delivered.tv_usec / 1000);
- /* ms resolution */
+ erts_late_sys_init_time();
}
-static void do_erts_deliver_time(const SysTimeval *current)
+void
+erts_sched_init_time_sup(ErtsSchedulerData *esdp)
{
- SysTimeval cur_time;
- erts_time_t elapsed;
-
- /* calculate and deliver appropriate number of ticks */
- cur_time = *current;
- cur_time.tv_usec = 1000 * (cur_time.tv_usec / 1000); /* ms resolution */
- elapsed = (1000 * (cur_time.tv_sec - last_delivered.tv_sec) +
- (cur_time.tv_usec - last_delivered.tv_usec) / 1000) /
- CLOCK_RESOLUTION;
-
- /* Sometimes the time jump backwards,
- resulting in a negative elapsed time. We compensate for
- this by simply pretend as if the time stood still. :) */
-
- if (elapsed > 0) {
+ esdp->timer_wheel = erts_create_timer_wheel(esdp);
+ esdp->next_tmo_ref = erts_get_next_timeout_reference(esdp->timer_wheel);
+ esdp->timer_service = erts_create_timer_service();
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ if (esdp->no == 1) {
+ /* A timer wheel to use must have beeen initialized */
+ if (time_sup.r.o.get_time != get_not_corrected_time)
+ late_init_time_correction(esdp);
+ }
+#endif
+}
- ASSERT(elapsed < ((erts_time_t) ERTS_SHORT_TIME_T_MAX));
+ErtsTimeWarpMode erts_time_warp_mode(void)
+{
+ return time_sup.r.o.warp_mode;
+}
- erts_do_time_add((erts_short_time_t) elapsed);
- last_delivered = cur_time;
+ErtsTimeOffsetState erts_time_offset_state(void)
+{
+ switch (time_sup.r.o.warp_mode) {
+ case ERTS_NO_TIME_WARP_MODE:
+ return ERTS_TIME_OFFSET_FINAL;
+ case ERTS_SINGLE_TIME_WARP_MODE:
+ if (erts_smp_atomic32_read_nob(&time_sup.inf.c.preliminary_offset))
+ return ERTS_TIME_OFFSET_PRELIMINARY;
+ return ERTS_TIME_OFFSET_FINAL;
+ case ERTS_MULTI_TIME_WARP_MODE:
+ return ERTS_TIME_OFFSET_VOLATILE;
+ default:
+ ERTS_INTERNAL_ERROR("Invalid time warp mode");
+ return ERTS_TIME_OFFSET_VOLATILE;
}
}
-int
-erts_init_time_sup(void)
+/*
+ * erts_finalize_time_offset() will only change time offset
+ * the first time it is called when the emulator has been
+ * started in "single time warp" mode. Returns previous
+ * state:
+ * * ERTS_TIME_OFFSET_PRELIMINARY - Finalization performed
+ * * ERTS_TIME_OFFSET_FINAL - Already finialized; nothing changed
+ * * ERTS_TIME_OFFSET_VOLATILE - Not supported, either in
+ * * no correction mode (or multi time warp mode; not yet implemented).
+ */
+
+ErtsTimeOffsetState
+erts_finalize_time_offset(void)
{
- erts_smp_mtx_init(&erts_timeofday_mtx, "timeofday");
+ switch (time_sup.r.o.warp_mode) {
+ case ERTS_NO_TIME_WARP_MODE:
+ return ERTS_TIME_OFFSET_FINAL;
+ case ERTS_MULTI_TIME_WARP_MODE:
+ return ERTS_TIME_OFFSET_VOLATILE;
+ case ERTS_SINGLE_TIME_WARP_MODE: {
+ ErtsTimeOffsetState res = ERTS_TIME_OFFSET_FINAL;
- init_approx_time();
+ erts_smp_mtx_lock(&erts_get_time_mtx);
- last_emu_time.tv_sec = 0;
- last_emu_time.tv_usec = 0;
+ if (erts_smp_atomic32_read_nob(&time_sup.inf.c.preliminary_offset)) {
+ ErtsMonotonicTime mtime, new_offset;
-#ifndef SYS_CLOCK_RESOLUTION
- clock_resolution = sys_init_time();
-#else
- (void) sys_init_time();
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ if (!time_sup.r.o.correction)
#endif
- sys_gettimeofday(&inittv);
-
-#ifdef HAVE_GETHRTIME
- sys_init_hrtime();
+ {
+ ErtsMonotonicTime stime = erts_os_system_time();
+
+ mtime = stime - time_sup.inf.c.not_corrected_moffset;
+
+ if (mtime >= time_sup.f.c.last_not_corrected_time) {
+ time_sup.f.c.last_not_corrected_time = mtime;
+ new_offset = time_sup.inf.c.not_corrected_moffset;
+ }
+ else {
+ mtime = time_sup.f.c.last_not_corrected_time;
+
+ ASSERT(time_sup.inf.c.not_corrected_moffset != stime - mtime);
+ new_offset = stime - mtime;
+ time_sup.inf.c.not_corrected_moffset = new_offset;
+ }
+
+ }
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ else {
+ ErtsSystemTime stime;
+ mtime = finalize_corrected_time_offset(&stime);
+ new_offset = stime - mtime;
+ }
#endif
- init_tolerant_timeofday();
+ new_offset = ERTS_MONOTONIC_TO_USEC(new_offset);
+ new_offset = ERTS_USEC_TO_MONOTONIC(new_offset);
- init_erts_deliver_time(&inittv);
- gtv = inittv;
- then.tv_sec = then.tv_usec = 0;
+ set_time_offset(new_offset);
+ schedule_send_time_offset_changed_notifications(new_offset);
- erts_deliver_time();
+ erts_smp_atomic32_set_nob(&time_sup.inf.c.preliminary_offset, 0);
+ res = ERTS_TIME_OFFSET_PRELIMINARY;
+ }
+
+ erts_smp_mtx_unlock(&erts_get_time_mtx);
+
+ return res;
+ }
+ default:
+ ERTS_INTERNAL_ERROR("Invalid time warp mode");
+ return ERTS_TIME_OFFSET_VOLATILE;
+ }
+}
- return CLOCK_RESOLUTION;
-}
/* info functions */
void
@@ -498,23 +1326,17 @@ elapsed_time_both(UWord *ms_user, UWord *ms_sys,
void
wall_clock_elapsed_time_both(UWord *ms_total, UWord *ms_diff)
{
- UWord prev_total;
- SysTimeval tv;
+ ErtsMonotonicTime now, elapsed;
erts_smp_mtx_lock(&erts_timeofday_mtx);
- get_tolerant_timeofday(&tv);
-
- *ms_total = 1000 * (tv.tv_sec - inittv.tv_sec) +
- (tv.tv_usec - inittv.tv_usec) / 1000;
+ now = time_sup.r.o.get_time();
+ update_last_mtime(NULL, now);
- prev_total = 1000 * (gtv.tv_sec - inittv.tv_sec) +
- (gtv.tv_usec - inittv.tv_usec) / 1000;
- *ms_diff = *ms_total - prev_total;
- gtv = tv;
-
- /* must sync the machine's idea of time here */
- do_erts_deliver_time(&tv);
+ elapsed = ERTS_MONOTONIC_TO_MSEC(now);
+ *ms_total = (UWord) elapsed;
+ *ms_diff = (UWord) (elapsed - prev_wall_clock_elapsed);
+ prev_wall_clock_elapsed = elapsed;
erts_smp_mtx_unlock(&erts_timeofday_mtx);
}
@@ -890,146 +1712,731 @@ univ_to_local(Sint *year, Sint *month, Sint *day,
return 0;
}
-
/* get a timestamp */
void
get_now(Uint* megasec, Uint* sec, Uint* microsec)
{
- SysTimeval now;
+ ErtsMonotonicTime now_megasec, now_sec, now, mtime, time_offset;
+ mtime = time_sup.r.o.get_time();
+ time_offset = get_time_offset();
+ update_last_mtime(NULL, mtime);
+ now = ERTS_MONOTONIC_TO_USEC(mtime + time_offset);
+
erts_smp_mtx_lock(&erts_timeofday_mtx);
-
- get_tolerant_timeofday(&now);
- do_erts_deliver_time(&now);
-
- /* Make sure time is later than last */
- if (then.tv_sec > now.tv_sec ||
- (then.tv_sec == now.tv_sec && then.tv_usec >= now.tv_usec)) {
- now = then;
- now.tv_usec++;
- }
- /* Check for carry from above + general reasonability */
- if (now.tv_usec >= 1000000) {
- now.tv_usec = 0;
- now.tv_sec++;
- }
- then = now;
+
+ /* Make sure now time is later than last time */
+ if (now <= previous_now)
+ now = previous_now + 1;
+
+ previous_now = now;
erts_smp_mtx_unlock(&erts_timeofday_mtx);
-
- *megasec = (Uint) (now.tv_sec / 1000000);
- *sec = (Uint) (now.tv_sec % 1000000);
- *microsec = (Uint) (now.tv_usec);
- update_approx_time(&now);
+ now_megasec = now / ERTS_MONOTONIC_TIME_TERA;
+ now_sec = now / ERTS_MONOTONIC_TIME_MEGA;
+ *megasec = (Uint) now_megasec;
+ *sec = (Uint) (now_sec - now_megasec*ERTS_MONOTONIC_TIME_MEGA);
+ *microsec = (Uint) (now - now_sec*ERTS_MONOTONIC_TIME_MEGA);
+
+ ASSERT(((ErtsMonotonicTime) *megasec)*ERTS_MONOTONIC_TIME_TERA
+ + ((ErtsMonotonicTime) *sec)*ERTS_MONOTONIC_TIME_MEGA
+ + ((ErtsMonotonicTime) *microsec) == now);
+}
+
+ErtsMonotonicTime
+erts_get_monotonic_time(ErtsSchedulerData *esdp)
+{
+ ErtsMonotonicTime mtime = time_sup.r.o.get_time();
+ update_last_mtime(esdp, mtime);
+ return mtime;
+}
+
+ErtsMonotonicTime
+erts_get_time_offset(void)
+{
+ return get_time_offset();
+}
+
+static ERTS_INLINE void
+make_timestamp_value(Uint* megasec, Uint* sec, Uint* microsec,
+ ErtsMonotonicTime mtime, ErtsMonotonicTime offset)
+{
+ ErtsMonotonicTime stime, as;
+ Uint ms;
+
+ stime = ERTS_MONOTONIC_TO_USEC(mtime + offset);
+
+ as = stime / ERTS_MONOTONIC_TIME_MEGA;
+ *megasec = ms = (Uint) (stime / ERTS_MONOTONIC_TIME_TERA);
+ *sec = (Uint) (as - (((ErtsMonotonicTime) ms)
+ * ERTS_MONOTONIC_TIME_MEGA));
+ *microsec = (Uint) (stime - as*ERTS_MONOTONIC_TIME_MEGA);
+
+ ASSERT(((ErtsMonotonicTime) ms)*ERTS_MONOTONIC_TIME_TERA
+ + ((ErtsMonotonicTime) *sec)*ERTS_MONOTONIC_TIME_MEGA
+ + *microsec == stime);
+}
+
+void
+erts_make_timestamp_value(Uint* megasec, Uint* sec, Uint* microsec,
+ ErtsMonotonicTime mtime, ErtsMonotonicTime offset)
+{
+ make_timestamp_value(megasec, sec, microsec, mtime, offset);
}
void
get_sys_now(Uint* megasec, Uint* sec, Uint* microsec)
{
- SysTimeval now;
-
- sys_gettimeofday(&now);
-
- *megasec = (Uint) (now.tv_sec / 1000000);
- *sec = (Uint) (now.tv_sec % 1000000);
- *microsec = (Uint) (now.tv_usec);
+ ErtsSystemTime stime = erts_os_system_time();
+ ErtsSystemTime ms, s, us;
+
+ us = ERTS_MONOTONIC_TO_USEC(stime);
+ s = us / (1000*1000);
+ ms = s / (1000*1000);
- update_approx_time(&now);
+ *megasec = (Uint) ms;
+ *sec = (Uint) (s - ms*(1000*1000));
+ *microsec = (Uint) (us - s*(1000*1000));
}
+#ifdef HAVE_ERTS_NOW_CPU
+void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec) {
+ SysCpuTime t;
+ SysTimespec tp;
-/* deliver elapsed *ticks* to the machine - takes a pointer
- to a struct timeval representing current time (to save
- a gettimeofday() where possible) or NULL */
+ sys_get_proc_cputime(t, tp);
+ *microsec = (Uint)(tp.tv_nsec / 1000);
+ t = (tp.tv_sec / 1000000);
+ *megasec = (Uint)(t % 1000000);
+ *sec = (Uint)(tp.tv_sec % 1000000);
+}
+#endif
-void erts_deliver_time(void) {
- SysTimeval now;
-
- erts_smp_mtx_lock(&erts_timeofday_mtx);
-
- get_tolerant_timeofday(&now);
- do_erts_deliver_time(&now);
-
- erts_smp_mtx_unlock(&erts_timeofday_mtx);
+#include "big.h"
+
+void
+erts_monitor_time_offset(Eterm id, Eterm ref)
+{
+ erts_smp_mtx_lock(&erts_get_time_mtx);
+ erts_add_monitor(&time_offset_monitors, MON_TIME_OFFSET, ref, id, NIL);
+ no_time_offset_monitors++;
+ erts_smp_mtx_unlock(&erts_get_time_mtx);
+}
- update_approx_time(&now);
+int
+erts_demonitor_time_offset(Eterm ref)
+{
+ int res;
+ ErtsMonitor *mon;
+ ASSERT(is_internal_ref(ref));
+ erts_smp_mtx_lock(&erts_get_time_mtx);
+ mon = erts_remove_monitor(&time_offset_monitors, ref);
+ if (!mon)
+ res = 0;
+ else {
+ ASSERT(no_time_offset_monitors > 0);
+ no_time_offset_monitors--;
+ res = 1;
+ }
+ erts_smp_mtx_unlock(&erts_get_time_mtx);
+ if (res)
+ erts_destroy_monitor(mon);
+ return res;
}
-/* get *real* time (not ticks) remaining until next timeout - if there
- isn't one, give a "long" time, that is guaranteed
- to not cause overflow when we report elapsed time later on */
+typedef struct {
+ Eterm pid;
+ Eterm ref;
+ Eterm heap[REF_THING_SIZE];
+} ErtsTimeOffsetMonitorInfo;
-void erts_time_remaining(SysTimeval *rem_time)
+typedef struct {
+ Uint ix;
+ ErtsTimeOffsetMonitorInfo *to_mon_info;
+} ErtsTimeOffsetMonitorContext;
+
+static void
+save_time_offset_monitor(ErtsMonitor *mon, void *vcntxt)
{
- erts_time_t ticks;
- SysTimeval cur_time;
- erts_time_t elapsed;
+ ErtsTimeOffsetMonitorContext *cntxt;
+ Eterm *from_hp, *to_hp;
+ Uint mix;
+ int hix;
- /* erts_next_time() returns no of ticks to next timeout or -1 if none */
+ cntxt = (ErtsTimeOffsetMonitorContext *) vcntxt;
+ mix = (cntxt->ix)++;
+ cntxt->to_mon_info[mix].pid = mon->pid;
+ to_hp = &cntxt->to_mon_info[mix].heap[0];
- ticks = (erts_time_t) erts_next_time();
- if (ticks == (erts_time_t) -1) {
- /* timer queue empty */
- /* this will cause at most 100000000 ticks */
- rem_time->tv_sec = 100000;
- rem_time->tv_usec = 0;
- } else {
- /* next timeout after ticks ticks */
- ticks *= CLOCK_RESOLUTION;
-
- erts_smp_mtx_lock(&erts_timeofday_mtx);
-
- get_tolerant_timeofday(&cur_time);
- cur_time.tv_usec = 1000 *
- (cur_time.tv_usec / 1000);/* ms resolution*/
- elapsed = 1000 * (cur_time.tv_sec - last_delivered.tv_sec) +
- (cur_time.tv_usec - last_delivered.tv_usec) / 1000;
-
- erts_smp_mtx_unlock(&erts_timeofday_mtx);
+ ASSERT(is_internal_ref(mon->ref));
+ from_hp = internal_ref_val(mon->ref);
+ ASSERT(thing_arityval(*from_hp) + 1 == REF_THING_SIZE);
+
+ for (hix = 0; hix < REF_THING_SIZE; hix++)
+ to_hp[hix] = from_hp[hix];
+
+ cntxt->to_mon_info[mix].ref
+ = make_internal_ref(&cntxt->to_mon_info[mix].heap[0]);
+
+}
+
+static void
+send_time_offset_changed_notifications(void *new_offsetp)
+{
+ ErtsMonotonicTime new_offset;
+ ErtsTimeOffsetMonitorInfo *to_mon_info = NULL; /* Shut up faulty warning */
+ Uint no_monitors;
+ char *tmp = NULL;
+
+#ifdef ARCH_64
+ new_offset = (ErtsMonotonicTime) new_offsetp;
+#else
+ new_offset = *((ErtsMonotonicTime *) new_offsetp);
+ erts_free(ERTS_ALC_T_NEW_TIME_OFFSET, new_offsetp);
+#endif
+ new_offset -= ERTS_MONOTONIC_OFFSET_NATIVE;
+
+ erts_smp_mtx_lock(&erts_get_time_mtx);
+
+ no_monitors = no_time_offset_monitors;
+ if (no_monitors) {
+ ErtsTimeOffsetMonitorContext cntxt;
+ Uint alloc_sz;
- if (ticks <= elapsed) { /* Ooops, better hurry */
- rem_time->tv_sec = rem_time->tv_usec = 0;
- return;
+ /* Monitor info array size */
+ alloc_sz = no_monitors*sizeof(ErtsTimeOffsetMonitorInfo);
+ /* + template max size */
+ alloc_sz += 6*sizeof(Eterm); /* 5-tuple */
+ alloc_sz += ERTS_MAX_SINT64_HEAP_SIZE*sizeof(Eterm); /* max offset size */
+ tmp = erts_alloc(ERTS_ALC_T_TMP, alloc_sz);
+
+ to_mon_info = (ErtsTimeOffsetMonitorInfo *) tmp;
+ cntxt.ix = 0;
+ cntxt.to_mon_info = to_mon_info;
+
+ erts_doforall_monitors(time_offset_monitors,
+ save_time_offset_monitor,
+ &cntxt);
+
+ ASSERT(cntxt.ix == no_monitors);
+ }
+
+ erts_smp_mtx_unlock(&erts_get_time_mtx);
+
+ if (no_monitors) {
+ Eterm *hp, *patch_refp, new_offset_term, message_template;
+ Uint mix, hsz;
+
+ /* Make message template */
+
+ hp = (Eterm *) (tmp + no_monitors*sizeof(ErtsTimeOffsetMonitorInfo));
+
+ hsz = 6; /* 5-tuple */
+ hsz += REF_THING_SIZE;
+ hsz += ERTS_SINT64_HEAP_SIZE(new_offset);
+
+ if (IS_SSMALL(new_offset))
+ new_offset_term = make_small(new_offset);
+ else
+ new_offset_term = erts_sint64_to_big(new_offset, &hp);
+ message_template = TUPLE5(hp,
+ am_CHANGE,
+ THE_NON_VALUE, /* Patch point for ref */
+ am_time_offset,
+ am_clock_service,
+ new_offset_term);
+ patch_refp = &hp[2];
+
+ ASSERT(*patch_refp == THE_NON_VALUE);
+
+ for (mix = 0; mix < no_monitors; mix++) {
+ Process *rp = erts_proc_lookup(to_mon_info[mix].pid);
+ if (rp) {
+ Eterm ref = to_mon_info[mix].ref;
+ ErtsProcLocks rp_locks = ERTS_PROC_LOCK_LINK;
+ erts_smp_proc_lock(rp, ERTS_PROC_LOCK_LINK);
+ if (erts_lookup_monitor(ERTS_P_MONITORS(rp), ref)) {
+ ErlHeapFragment *bp;
+ ErlOffHeap *ohp;
+ Eterm message;
+
+ hp = erts_alloc_message_heap(hsz, &bp, &ohp, rp, &rp_locks);
+ *patch_refp = ref;
+ ASSERT(hsz == size_object(message_template));
+ message = copy_struct(message_template, hsz, &hp, ohp);
+ erts_queue_message(rp, &rp_locks, bp, message, NIL);
+ }
+ erts_smp_proc_unlock(rp, rp_locks);
+ }
}
- rem_time->tv_sec = (ticks - elapsed) / 1000;
- rem_time->tv_usec = 1000 * ((ticks - elapsed) % 1000);
+
+ erts_free(ERTS_ALC_T_TMP, tmp);
}
}
-void erts_get_timeval(SysTimeval *tv)
+static void
+schedule_send_time_offset_changed_notifications(ErtsMonotonicTime new_offset)
{
- erts_smp_mtx_lock(&erts_timeofday_mtx);
- get_tolerant_timeofday(tv);
- erts_smp_mtx_unlock(&erts_timeofday_mtx);
- update_approx_time(tv);
+#ifdef ARCH_64
+ void *new_offsetp = (void *) new_offset;
+ ASSERT(sizeof(void *) == sizeof(ErtsMonotonicTime));
+#else
+ void *new_offsetp = erts_alloc(ERTS_ALC_T_NEW_TIME_OFFSET,
+ sizeof(ErtsMonotonicTime));
+ *((ErtsMonotonicTime *) new_offsetp) = new_offset;
+#endif
+ erts_schedule_misc_aux_work(1,
+ send_time_offset_changed_notifications,
+ new_offsetp);
}
-erts_time_t
-erts_get_time(void)
+static ERTS_INLINE Eterm
+make_time_val(Process *c_p, ErtsMonotonicTime time_val)
{
- SysTimeval sys_tv;
-
- erts_smp_mtx_lock(&erts_timeofday_mtx);
-
- get_tolerant_timeofday(&sys_tv);
-
- erts_smp_mtx_unlock(&erts_timeofday_mtx);
+ Sint64 val = (Sint64) time_val;
+ Eterm *hp;
+ Uint sz;
- update_approx_time(&sys_tv);
+ if (IS_SSMALL(val))
+ return make_small(val);
- return sys_tv.tv_sec;
+ sz = ERTS_SINT64_HEAP_SIZE(val);
+ hp = HAlloc(c_p, sz);
+ return erts_sint64_to_big(val, &hp);
}
-#ifdef HAVE_ERTS_NOW_CPU
-void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec) {
- SysCpuTime t;
- SysTimespec tp;
+Eterm
+erts_get_monotonic_start_time(struct process *c_p)
+{
+ return make_time_val(c_p, ERTS_MONOTONIC_TIME_START_EXTERNAL);
+}
- sys_get_proc_cputime(t, tp);
- *microsec = (Uint)(tp.tv_nsec / 1000);
- t = (tp.tv_sec / 1000000);
- *megasec = (Uint)(t % 1000000);
- *sec = (Uint)(tp.tv_sec % 1000000);
+Eterm
+erts_get_monotonic_end_time(struct process *c_p)
+{
+ return make_time_val(c_p, ERTS_MONOTONIC_TIME_END_EXTERNAL);
}
+
+static Eterm
+bld_monotonic_time_source(Uint **hpp, Uint *szp, Sint64 os_mtime)
+{
+#ifndef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ return NIL;
+#else
+ int i = 0;
+ Eterm k[6];
+ Eterm v[6];
+
+ if (time_sup.r.o.os_monotonic_time_disable)
+ return NIL;
+
+ k[i] = erts_bld_atom(hpp, szp, "function");
+ v[i++] = erts_bld_atom(hpp, szp,
+ time_sup.r.o.os_monotonic_time_func);
+
+ if (time_sup.r.o.os_monotonic_time_clock_id) {
+ k[i] = erts_bld_atom(hpp, szp, "clock_id");
+ v[i++] = erts_bld_atom(hpp, szp,
+ time_sup.r.o.os_monotonic_time_clock_id);
+ }
+
+ k[i] = erts_bld_atom(hpp, szp, "resolution");
+ v[i++] = erts_bld_uint64(hpp, szp,
+ time_sup.r.o.os_monotonic_time_resolution);
+
+ k[i] = erts_bld_atom(hpp, szp, "extended");
+ v[i++] = time_sup.r.o.os_monotonic_time_extended ? am_yes : am_no;
+
+ k[i] = erts_bld_atom(hpp, szp, "parallel");
+ v[i++] = time_sup.r.o.os_monotonic_time_locked ? am_no : am_yes;
+
+ k[i] = erts_bld_atom(hpp, szp, "time");
+ v[i++] = erts_bld_sint64(hpp, szp, os_mtime);
+
+ return erts_bld_2tup_list(hpp, szp, (Sint) i, k, v);
+#endif
+}
+
+Eterm
+erts_monotonic_time_source(struct process *c_p)
+{
+ Uint hsz = 0;
+ Eterm *hp = NULL;
+ Sint64 os_mtime = 0;
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ if (!time_sup.r.o.os_monotonic_time_disable)
+ os_mtime = (Sint64) erts_os_monotonic_time();
+#endif
+
+ bld_monotonic_time_source(NULL, &hsz, os_mtime);
+ if (hsz)
+ hp = HAlloc(c_p, hsz);
+ return bld_monotonic_time_source(&hp, NULL, os_mtime);
+}
+
+static Eterm
+bld_system_time_source(Uint **hpp, Uint *szp, Sint64 os_stime)
+{
+ int i = 0;
+ Eterm k[5];
+ Eterm v[5];
+
+ k[i] = erts_bld_atom(hpp, szp, "function");
+ v[i++] = erts_bld_atom(hpp, szp,
+ time_sup.r.o.os_system_time_func);
+
+ if (time_sup.r.o.os_system_time_clock_id) {
+ k[i] = erts_bld_atom(hpp, szp, "clock_id");
+ v[i++] = erts_bld_atom(hpp, szp,
+ time_sup.r.o.os_system_time_clock_id);
+ }
+
+ k[i] = erts_bld_atom(hpp, szp, "resolution");
+ v[i++] = erts_bld_uint64(hpp, szp,
+ time_sup.r.o.os_system_time_resolution);
+
+ k[i] = erts_bld_atom(hpp, szp, "parallel");
+ v[i++] = am_yes;
+
+ k[i] = erts_bld_atom(hpp, szp, "time");
+ v[i++] = erts_bld_sint64(hpp, szp, os_stime);
+
+ return erts_bld_2tup_list(hpp, szp, (Sint) i, k, v);
+}
+
+Eterm
+erts_system_time_source(struct process *c_p)
+{
+ Uint hsz = 0;
+ Eterm *hp = NULL;
+ Sint64 os_stime = (Sint64) erts_os_system_time();
+
+ bld_system_time_source(NULL, &hsz, os_stime);
+ if (hsz)
+ hp = HAlloc(c_p, hsz);
+ return bld_system_time_source(&hp, NULL, os_stime);
+}
+
+
+#include "bif.h"
+
+static ERTS_INLINE Eterm
+time_unit_conversion(Process *c_p, Eterm term, ErtsMonotonicTime val, ErtsMonotonicTime muloff)
+{
+ ErtsMonotonicTime result;
+ BIF_RETTYPE ret;
+
+ if (val < 0)
+ goto trap_to_erlang_code;
+
+ /* Convert to common user specified time units */
+ switch (term) {
+ case am_seconds:
+ case make_small(1):
+ result = ERTS_MONOTONIC_TO_SEC(val) + muloff*ERTS_MONOTONIC_OFFSET_SEC;
+ ERTS_BIF_PREP_RET(ret, make_time_val(c_p, result));
+ break;
+ case am_milli_seconds:
+ case make_small(1000):
+ result = ERTS_MONOTONIC_TO_MSEC(val) + muloff*ERTS_MONOTONIC_OFFSET_MSEC;
+ ERTS_BIF_PREP_RET(ret, make_time_val(c_p, result));
+ break;
+ case am_micro_seconds:
+ case make_small(1000*1000):
+ result = ERTS_MONOTONIC_TO_USEC(val) + muloff*ERTS_MONOTONIC_OFFSET_USEC;
+ ERTS_BIF_PREP_RET(ret, make_time_val(c_p, result));
+ break;
+#ifdef ARCH_64
+ case am_nano_seconds:
+ case make_small(1000*1000*1000):
+ result = ERTS_MONOTONIC_TO_NSEC(val) + muloff*ERTS_MONOTONIC_OFFSET_NSEC;
+ ERTS_BIF_PREP_RET(ret, make_time_val(c_p, result));
+ break;
#endif
+ default: {
+ Eterm value, native_res;
+#ifndef ARCH_64
+ Sint user_res;
+ if (term == am_nano_seconds)
+ goto to_nano_seconds;
+ if (term_to_Sint(term, &user_res)) {
+ if (user_res == 1000*1000*1000) {
+ to_nano_seconds:
+ result = (ERTS_MONOTONIC_TO_NSEC(val)
+ + muloff*ERTS_MONOTONIC_OFFSET_NSEC);
+ ERTS_BIF_PREP_RET(ret, make_time_val(c_p, result));
+ break;
+ }
+ if (user_res <= 0)
+ goto badarg;
+ }
+#else
+ if (is_small(term)) {
+ if (signed_val(term) <= 0)
+ goto badarg;
+ }
+#endif
+ else if (is_big(term)) {
+ if (big_sign(term))
+ goto badarg;
+ }
+ else {
+ badarg:
+ ERTS_BIF_PREP_ERROR(ret, c_p, BADARG);
+ break;
+ }
+
+ trap_to_erlang_code:
+ /* Do it in erlang code instead; pass along values to use... */
+ value = make_time_val(c_p, val + muloff*ERTS_MONOTONIC_OFFSET_NATIVE);
+ native_res = make_time_val(c_p, ERTS_MONOTONIC_TIME_UNIT);
+
+ ERTS_BIF_PREP_TRAP3(ret, erts_convert_time_unit_trap, c_p,
+ value, native_res, term);
+
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+/*
+ * Time Native API (drivers and NIFs)
+ */
+
+#define ERTS_NAPI_TIME_ERROR ((ErtsMonotonicTime) ERTS_NAPI_TIME_ERROR__)
+
+static void
+init_time_napi(void)
+{
+ /* Verify that time native api constants are as expected... */
+
+ ASSERT(sizeof(ErtsMonotonicTime) == sizeof(ErlDrvTime));
+ ASSERT(ERL_DRV_TIME_ERROR == (ErlDrvTime) ERTS_NAPI_TIME_ERROR);
+ ASSERT(ERL_DRV_TIME_ERROR < (ErlDrvTime) 0);
+ ASSERT(ERTS_NAPI_SEC__ == (int) ERL_DRV_SEC);
+ ASSERT(ERTS_NAPI_MSEC__ == (int) ERL_DRV_MSEC);
+ ASSERT(ERTS_NAPI_USEC__ == (int) ERL_DRV_USEC);
+ ASSERT(ERTS_NAPI_NSEC__ == (int) ERL_DRV_NSEC);
+
+ ASSERT(sizeof(ErtsMonotonicTime) == sizeof(ErlNifTime));
+ ASSERT(ERL_NIF_TIME_ERROR == (ErlNifTime) ERTS_NAPI_TIME_ERROR);
+ ASSERT(ERL_NIF_TIME_ERROR < (ErlNifTime) 0);
+ ASSERT(ERTS_NAPI_SEC__ == (int) ERL_NIF_SEC);
+ ASSERT(ERTS_NAPI_MSEC__ == (int) ERL_NIF_MSEC);
+ ASSERT(ERTS_NAPI_USEC__ == (int) ERL_NIF_USEC);
+ ASSERT(ERTS_NAPI_NSEC__ == (int) ERL_NIF_NSEC);
+}
+
+ErtsMonotonicTime
+erts_napi_monotonic_time(int time_unit)
+{
+ ErtsSchedulerData *esdp;
+ ErtsMonotonicTime mtime;
+
+ /* At least for now only allow schedulers to do this... */
+ esdp = erts_get_scheduler_data();
+ if (!esdp)
+ return ERTS_NAPI_TIME_ERROR;
+
+ mtime = time_sup.r.o.get_time();
+ update_last_mtime(esdp, mtime);
+
+ switch (time_unit) {
+ case ERTS_NAPI_SEC__:
+ mtime = ERTS_MONOTONIC_TO_SEC(mtime);
+ mtime += ERTS_MONOTONIC_OFFSET_SEC;
+ break;
+ case ERTS_NAPI_MSEC__:
+ mtime = ERTS_MONOTONIC_TO_MSEC(mtime);
+ mtime += ERTS_MONOTONIC_OFFSET_MSEC;
+ break;
+ case ERTS_NAPI_USEC__:
+ mtime = ERTS_MONOTONIC_TO_USEC(mtime);
+ mtime += ERTS_MONOTONIC_OFFSET_USEC;
+ break;
+ case ERTS_NAPI_NSEC__:
+ mtime = ERTS_MONOTONIC_TO_NSEC(mtime);
+ mtime += ERTS_MONOTONIC_OFFSET_NSEC;
+ break;
+ default:
+ return ERTS_NAPI_TIME_ERROR;
+ }
+
+ return mtime;
+}
+
+ErtsMonotonicTime
+erts_napi_time_offset(int time_unit)
+{
+ ErtsSchedulerData *esdp;
+ ErtsSystemTime offs;
+
+ /* At least for now only allow schedulers to do this... */
+ esdp = erts_get_scheduler_data();
+ if (!esdp)
+ return ERTS_NAPI_TIME_ERROR;
+
+ offs = get_time_offset();
+ switch (time_unit) {
+ case ERTS_NAPI_SEC__:
+ offs = ERTS_MONOTONIC_TO_SEC(offs);
+ offs -= ERTS_MONOTONIC_OFFSET_SEC;
+ break;
+ case ERTS_NAPI_MSEC__:
+ offs = ERTS_MONOTONIC_TO_MSEC(offs);
+ offs -= ERTS_MONOTONIC_OFFSET_MSEC;
+ break;
+ case ERTS_NAPI_USEC__:
+ offs = ERTS_MONOTONIC_TO_USEC(offs);
+ offs -= ERTS_MONOTONIC_OFFSET_USEC;
+ break;
+ case ERTS_NAPI_NSEC__:
+ offs = ERTS_MONOTONIC_TO_NSEC(offs);
+ offs -= ERTS_MONOTONIC_OFFSET_NSEC;
+ break;
+ default:
+ return ERTS_NAPI_TIME_ERROR;
+ }
+ return offs;
+}
+
+ErtsMonotonicTime
+erts_napi_convert_time_unit(ErtsMonotonicTime val, int from, int to)
+{
+ ErtsMonotonicTime ffreq, tfreq, denom;
+ /*
+ * Convertion between time units using floor function.
+ *
+ * Note that this needs to work also for negative
+ * values. Ordinary integer division on a negative
+ * value will give ceiling...
+ */
+
+ switch ((int) from) {
+ case ERTS_NAPI_SEC__: ffreq = 1; break;
+ case ERTS_NAPI_MSEC__: ffreq = 1000; break;
+ case ERTS_NAPI_USEC__: ffreq = 1000*1000; break;
+ case ERTS_NAPI_NSEC__: ffreq = 1000*1000*1000; break;
+ default: return ERTS_NAPI_TIME_ERROR;
+ }
+
+ switch ((int) to) {
+ case ERTS_NAPI_SEC__: tfreq = 1; break;
+ case ERTS_NAPI_MSEC__: tfreq = 1000; break;
+ case ERTS_NAPI_USEC__: tfreq = 1000*1000; break;
+ case ERTS_NAPI_NSEC__: tfreq = 1000*1000*1000; break;
+ default: return ERTS_NAPI_TIME_ERROR;
+ }
+
+ if (tfreq >= ffreq)
+ return val * (tfreq / ffreq);
+
+ denom = ffreq / tfreq;
+ if (val >= 0)
+ return val / denom;
+
+ return (val - (denom - 1)) / denom;
+}
+
+/* Built in functions */
+
+BIF_RETTYPE monotonic_time_0(BIF_ALIST_0)
+{
+ ErtsMonotonicTime mtime = time_sup.r.o.get_time();
+ update_last_mtime(ERTS_PROC_GET_SCHDATA(BIF_P), mtime);
+ mtime += ERTS_MONOTONIC_OFFSET_NATIVE;
+ BIF_RET(make_time_val(BIF_P, mtime));
+}
+
+BIF_RETTYPE monotonic_time_1(BIF_ALIST_1)
+{
+ ErtsMonotonicTime mtime = time_sup.r.o.get_time();
+ update_last_mtime(ERTS_PROC_GET_SCHDATA(BIF_P), mtime);
+ BIF_RET(time_unit_conversion(BIF_P, BIF_ARG_1, mtime, 1));
+}
+
+BIF_RETTYPE system_time_0(BIF_ALIST_0)
+{
+ ErtsMonotonicTime mtime, offset;
+ mtime = time_sup.r.o.get_time();
+ offset = get_time_offset();
+ update_last_mtime(ERTS_PROC_GET_SCHDATA(BIF_P), mtime);
+ BIF_RET(make_time_val(BIF_P, mtime + offset));
+}
+
+BIF_RETTYPE system_time_1(BIF_ALIST_0)
+{
+ ErtsMonotonicTime mtime, offset;
+ mtime = time_sup.r.o.get_time();
+ offset = get_time_offset();
+ update_last_mtime(ERTS_PROC_GET_SCHDATA(BIF_P), mtime);
+ BIF_RET(time_unit_conversion(BIF_P, BIF_ARG_1, mtime + offset, 0));
+}
+
+BIF_RETTYPE erts_internal_time_unit_0(BIF_ALIST_0)
+{
+ BIF_RET(make_time_val(BIF_P, ERTS_MONOTONIC_TIME_UNIT));
+}
+
+BIF_RETTYPE time_offset_0(BIF_ALIST_0)
+{
+ ErtsMonotonicTime time_offset = get_time_offset();
+ time_offset -= ERTS_MONOTONIC_OFFSET_NATIVE;
+ BIF_RET(make_time_val(BIF_P, time_offset));
+}
+
+BIF_RETTYPE time_offset_1(BIF_ALIST_1)
+{
+ BIF_RET(time_unit_conversion(BIF_P, BIF_ARG_1, get_time_offset(), -1));
+}
+
+
+BIF_RETTYPE timestamp_0(BIF_ALIST_0)
+{
+ Eterm *hp, res;
+ ErtsMonotonicTime mtime, offset;
+ Uint mega_sec, sec, micro_sec;
+
+ mtime = time_sup.r.o.get_time();
+ offset = get_time_offset();
+ update_last_mtime(ERTS_PROC_GET_SCHDATA(BIF_P), mtime);
+
+ make_timestamp_value(&mega_sec, &sec, &micro_sec, mtime, offset);
+
+ /*
+ * Mega seconds is the only value that potentially
+ * ever could be a bignum. However, that wont happen
+ * during at least the next 4 million years...
+ *
+ * (System time will also have wrapped in the
+ * 64-bit integer before we get there...)
+ */
+
+ ASSERT(IS_USMALL(0, mega_sec));
+ ASSERT(IS_USMALL(0, sec));
+ ASSERT(IS_USMALL(0, micro_sec));
+
+ hp = HAlloc(BIF_P, 4);
+ res = TUPLE3(hp,
+ make_small(mega_sec),
+ make_small(sec),
+ make_small(micro_sec));
+ BIF_RET(res);
+}
+
+BIF_RETTYPE os_system_time_0(BIF_ALIST_0)
+{
+ ErtsSystemTime stime = erts_os_system_time();
+ BIF_RET(make_time_val(BIF_P, stime));
+}
+
+BIF_RETTYPE os_system_time_1(BIF_ALIST_0)
+{
+ ErtsSystemTime stime = erts_os_system_time();
+ BIF_RET(time_unit_conversion(BIF_P, BIF_ARG_1, stime, 0));
+}
+
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index ea5c850a30..114853cac4 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -37,6 +38,7 @@
#include "erl_binary.h"
#include "erl_bits.h"
#include "erl_thr_progress.h"
+#include "erl_bif_unique.h"
#if 0
#define DEBUG_PRINTOUTS
@@ -76,6 +78,264 @@ enum ErtsSysMsgType {
SYS_MSG_TYPE_SYSPROF
};
+#define ERTS_TRACE_TS_NOW_MAX_SIZE \
+ 4
+#define ERTS_TRACE_TS_MONOTONIC_MAX_SIZE \
+ ERTS_MAX_SINT64_HEAP_SIZE
+#define ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE \
+ (3 + ERTS_MAX_SINT64_HEAP_SIZE \
+ + ERTS_MAX_UINT64_HEAP_SIZE)
+
+#define ERTS_TRACE_PATCH_TS_MAX_SIZE \
+ (1 + ((ERTS_TRACE_TS_NOW_MAX_SIZE \
+ > ERTS_TRACE_TS_MONOTONIC_MAX_SIZE) \
+ ? ((ERTS_TRACE_TS_NOW_MAX_SIZE \
+ > ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE) \
+ ? ERTS_TRACE_TS_NOW_MAX_SIZE \
+ : ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE) \
+ : ((ERTS_TRACE_TS_MONOTONIC_MAX_SIZE \
+ > ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE) \
+ ? ERTS_TRACE_TS_MONOTONIC_MAX_SIZE \
+ : ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE)))
+
+#define TFLGS_TS_TYPE(p) ERTS_TFLGS2TSTYPE(ERTS_TRACE_FLAGS((p)))
+
+/*
+ * FUTURE CHANGES:
+ *
+ * The timestamp functionality has intentionally been
+ * split in two parts for future use even though it
+ * is not used like this today. take_timestamp() takes
+ * the timestamp and calculate heap need for it (which
+ * is not constant). write_timestamp() writes the
+ * timestamp to the allocated heap. That is, one typically
+ * want to take the timestamp before allocating the heap
+ * and then write it to the heap.
+ *
+ * The trace output functionality now use patch_ts_size(),
+ * write_ts(), and patch_ts(). write_ts() both takes the
+ * timestamp and writes it. Since we don't know the
+ * heap need when allocating the heap area we need to
+ * over allocate (maximum size from patch_ts_size()) and
+ * then potentially (often) shrink the heap area after the
+ * timestamp has been written. The only reason it is
+ * currently done this way is because we do not want to
+ * make major changes of the trace behavior in a patch.
+ * This is planned to be changed in next major release.
+ */
+
+typedef struct {
+ int ts_type_flag;
+ union {
+ struct {
+ Uint ms;
+ Uint s;
+ Uint us;
+ } now;
+ struct {
+ ErtsMonotonicTime time;
+ Sint64 raw_unique;
+ } monotonic;
+ } u;
+} ErtsTraceTimeStamp;
+
+static ERTS_INLINE Uint
+take_timestamp(ErtsTraceTimeStamp *tsp, int ts_type)
+{
+ int ts_type_flag = ts_type & -ts_type; /* least significant flag */
+
+ ASSERT(ts_type_flag == ERTS_TRACE_FLG_NOW_TIMESTAMP
+ || ts_type_flag == ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP
+ || ts_type_flag == ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP
+ || ts_type_flag == 0);
+
+ tsp->ts_type_flag = ts_type_flag;
+ switch (ts_type_flag) {
+ case 0:
+ return (Uint) 0;
+ case ERTS_TRACE_FLG_NOW_TIMESTAMP:
+#ifdef HAVE_ERTS_NOW_CPU
+ if (erts_cpu_timestamp)
+ erts_get_now_cpu(&tsp->u.now.ms, &tsp->u.now.s, &tsp->u.now.us);
+ else
+#endif
+ get_now(&tsp->u.now.ms, &tsp->u.now.s, &tsp->u.now.us);
+ return (Uint) 4;
+ case ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP:
+ case ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP: {
+ Uint hsz = 0;
+ ErtsMonotonicTime mtime = erts_get_monotonic_time(NULL);
+ mtime = ERTS_MONOTONIC_TO_NSEC(mtime);
+ mtime += ERTS_MONOTONIC_OFFSET_NSEC;
+ hsz = (IS_SSMALL(mtime) ?
+ (Uint) 0
+ : ERTS_SINT64_HEAP_SIZE((Sint64) mtime));
+ tsp->u.monotonic.time = mtime;
+ if (ts_type_flag == ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP) {
+ Sint64 raw_unique;
+ hsz += 3; /* 2-tuple */
+ raw_unique = erts_raw_get_unique_monotonic_integer();
+ tsp->u.monotonic.raw_unique = raw_unique;
+ hsz += erts_raw_unique_monotonic_integer_heap_size(raw_unique);
+ }
+ return hsz;
+ }
+ default:
+ ERTS_INTERNAL_ERROR("invalid timestamp type");
+ return 0;
+ }
+}
+
+static ERTS_INLINE Eterm
+write_timestamp(ErtsTraceTimeStamp *tsp, Eterm **hpp)
+{
+ int ts_type_flag = tsp->ts_type_flag;
+ Eterm res;
+
+ switch (ts_type_flag) {
+ case 0:
+ return NIL;
+ case ERTS_TRACE_FLG_NOW_TIMESTAMP:
+ res = TUPLE3(*hpp,
+ make_small(tsp->u.now.ms),
+ make_small(tsp->u.now.s),
+ make_small(tsp->u.now.us));
+ *hpp += 4;
+ return res;
+ case ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP:
+ case ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP: {
+ Sint64 mtime, raw;
+ Eterm unique, emtime;
+
+ mtime = (Sint64) tsp->u.monotonic.time;
+ emtime = (IS_SSMALL(mtime)
+ ? make_small((Sint64) mtime)
+ : erts_sint64_to_big((Sint64) mtime, hpp));
+
+ if (ts_type_flag == ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP)
+ return emtime;
+
+ raw = tsp->u.monotonic.raw_unique;
+ unique = erts_raw_make_unique_monotonic_integer_value(hpp,
+ raw);
+ res = TUPLE2(*hpp, emtime, unique);
+ *hpp += 3;
+ return res;
+ }
+ default:
+ ERTS_INTERNAL_ERROR("invalid timestamp type");
+ return THE_NON_VALUE;
+ }
+}
+
+#define PATCH_TS_SIZE(p) patch_ts_size(TFLGS_TS_TYPE(p))
+
+static ERTS_INLINE Uint
+patch_ts_size(int ts_type)
+{
+ int ts_type_flag = ts_type & -ts_type; /* least significant flag */
+ switch (ts_type_flag) {
+ case 0:
+ return 0;
+ case ERTS_TRACE_FLG_NOW_TIMESTAMP:
+ return 1 + ERTS_TRACE_TS_NOW_MAX_SIZE;
+ case ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP:
+ return 1 + ERTS_TRACE_TS_MONOTONIC_MAX_SIZE;
+ case ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP:
+ return 1 + ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE;
+ default:
+ ERTS_INTERNAL_ERROR("invalid timestamp type");
+ return 0;
+ }
+}
+
+/*
+ * Write a timestamp. The timestamp MUST be the last
+ * thing built on the heap. This since write_ts() might
+ * adjust the size of the used area.
+ */
+static Eterm
+write_ts(int ts_type, Eterm *hp, ErlHeapFragment *bp, Process *tracer)
+{
+ ErtsTraceTimeStamp ts;
+ Sint shrink;
+ Eterm res, *ts_hp = hp;
+ Uint hsz;
+
+ ASSERT(ts_type);
+
+ hsz = take_timestamp(&ts, ts_type);
+
+ res = write_timestamp(&ts, &ts_hp);
+
+ ASSERT(ts_hp == hp + hsz);
+
+ switch (ts.ts_type_flag) {
+ case ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP:
+ shrink = ERTS_TRACE_TS_MONOTONIC_MAX_SIZE;
+ break;
+ case ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP:
+ shrink = ERTS_TRACE_TS_STRICT_MONOTONIC_MAX_SIZE;
+ break;
+ default:
+ return res;
+ }
+
+ shrink -= hsz;
+
+ ASSERT(shrink >= 0);
+
+ if (shrink) {
+ if (bp)
+ bp->used_size -= shrink;
+#ifndef ERTS_SMP
+ else if (tracer) {
+ Eterm *endp = ts_hp + shrink;
+ HRelease(tracer, endp, ts_hp);
+ }
+#endif
+ }
+
+ return res;
+}
+
+/*
+ * Patch a timestamp into a tuple. The tuple MUST be the last thing
+ * built on the heap before the call, and the timestamp MUST be
+ * the last thing after the call. This since patch_ts() might adjust
+ * the size of the used area.
+ */
+
+#define PATCH_TS__(Type, Tuple, Hp, Bp, Tracer) \
+ do { \
+ int ts_type__ = (Type); \
+ if (ts_type__) \
+ patch_ts(ts_type__, (Tuple), (Hp), (Bp), (Tracer)); \
+ } while (0)
+
+#ifdef ERTS_SMP
+#define PATCH_TS(Type, Tuple, Hp, Bp, Tracer) \
+ PATCH_TS__((Type), (Tuple), (Hp), (Bp), NULL)
+#else
+#define PATCH_TS(Type, Tuple, Hp, Bp, Tracer) \
+ PATCH_TS__((Type), (Tuple), (Hp), (Bp), (Tracer))
+#endif
+
+static ERTS_INLINE void
+patch_ts(int ts_type, Eterm tuple, Eterm* hp, ErlHeapFragment *bp, Process *tracer)
+{
+ Eterm *tptr = tuple_val(tuple);
+ int arity = arityval(*tptr);
+
+ ASSERT(ts_type);
+ ASSERT((tptr+arity+1) == hp);
+
+ tptr[0] = make_arityval(arity+1);
+ tptr[1] = am_trace_ts;
+
+ *hp = write_ts(ts_type, hp+1, bp, tracer);
+}
+
#ifdef ERTS_SMP
static void enqueue_sys_msg_unlocked(enum ErtsSysMsgType type,
Eterm from,
@@ -130,14 +390,9 @@ do { \
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_TRACE, (FPID), (TPID), (MSG), (BP)); \
} while(0)
#else
-#ifdef USE_VM_PROBES
-#define ERTS_ENQ_TRACE_MSG(FPID, TPROC, MSG, BP) \
- erts_queue_message((TPROC), NULL, (BP), (MSG), NIL, NIL)
-#else
#define ERTS_ENQ_TRACE_MSG(FPID, TPROC, MSG, BP) \
erts_queue_message((TPROC), NULL, (BP), (MSG), NIL)
#endif
-#endif
/*
* NOTE that the ERTS_GET_TRACER_REF() returns from the function (!!!)
@@ -369,23 +624,6 @@ erts_get_system_profile(void) {
return profile;
}
-
-#ifdef HAVE_ERTS_NOW_CPU
-# define GET_NOW(m, s, u) \
-do { \
- if (erts_cpu_timestamp) \
- erts_get_now_cpu(m, s, u); \
- else \
- get_now(m, s, u); \
-} while (0)
-#else
-# define GET_NOW(m, s, u) do {get_now(m, s, u);} while (0)
-#endif
-
-
-
-static Eterm* patch_ts(Eterm tuple4, Eterm* hp);
-
#ifdef ERTS_SMP
static void
do_send_to_port(Eterm to,
@@ -424,7 +662,7 @@ WRITE_SYS_MSG_TO_PORT(Eterm unused_to,
erts_encode_ext(message, &ptr);
if (!(ptr <= buffer+size)) {
- erl_exit(1, "Internal error in do_send_to_port: %d\n", ptr-buffer);
+ erts_exit(ERTS_ERROR_EXIT, "Internal error in do_send_to_port: %d\n", ptr-buffer);
}
#ifndef ERTS_SMP
@@ -440,11 +678,11 @@ WRITE_SYS_MSG_TO_PORT(Eterm unused_to,
/* Send {trace_ts, Pid, out, 0, Timestamp}
* followed by {trace_ts, Pid, in, 0, NewTimestamp}
*
- * 'NewTimestamp' is fetched from GET_NOW() through patch_ts().
+ * 'NewTimestamp' through patch_ts().
*/
static void
-do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
-#define LOCAL_HEAP_SIZE (4+5+5)
+do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp, int ts_type) {
+#define LOCAL_HEAP_SIZE (5+5+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
Eterm message;
Eterm *hp;
@@ -466,9 +704,11 @@ do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
SYS_MSG_TYPE_UNDEFINED,
message);
- message = TUPLE4(hp, am_trace_ts, pid, am_in, mfarity);
- hp += 5;
- hp = patch_ts(message, hp);
+
+ message = TUPLE5(hp, am_trace_ts, pid, am_in, mfarity,
+ NIL /* Will be overwritten by timestamp */);
+ hp += 6;
+ hp[-1] = write_ts(ts_type, hp, NULL, NULL);
do_send_to_port(trace_port->common.id,
trace_port,
@@ -485,7 +725,7 @@ do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
* It is assumed that 'message' is not an 'out' message.
*
* 'c_p' is the currently executing process, "tracee" is the traced process
- * which 'message' concerns => if (*tracee_flags & F_TIMESTAMP),
+ * which 'message' concerns => if (*tracee_flags & F_TIMESTAMP_MASK),
* 'message' must contain a timestamp.
*/
static void
@@ -493,8 +733,9 @@ send_to_port(Process *c_p, Eterm message,
Eterm *tracer_pid, Uint *tracee_flags) {
Port* trace_port;
#ifndef ERTS_SMP
-#define LOCAL_HEAP_SIZE (4)
- Eterm ts, *hp;
+ int ts_type;
+#define LOCAL_HEAP_SIZE ERTS_TRACE_PATCH_TS_MAX_SIZE
+ Eterm ts;
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
#endif
@@ -523,7 +764,7 @@ send_to_port(Process *c_p, Eterm message,
*/
if ( c_p == NULL ||
- (! IS_TRACED_FL(c_p, F_TRACE_SCHED | F_TIMESTAMP))) {
+ (! IS_TRACED_FL(c_p, F_TRACE_SCHED | F_TIMESTAMP_MASK))) {
#endif
do_send_to_port(*tracer_pid,
trace_port,
@@ -542,22 +783,12 @@ send_to_port(Process *c_p, Eterm message,
*/
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
- if (*tracee_flags & F_TIMESTAMP) {
- ASSERT(is_tuple(message));
- hp = tuple_val(message);
- ts = hp[arityval(hp[0])];
- } else {
- /* A fake schedule might be needed,
- * but this message does not contain a timestamp.
- * Create a dummy trace message with timestamp to be
- * passed to do_send_schedfix_to_port().
- */
- Uint ms,s,us;
- GET_NOW(&ms, &s, &us);
- hp = local_heap;
- ts = TUPLE3(hp, make_small(ms), make_small(s), make_small(us));
- hp += 4;
- }
+ /* A fake schedule might be needed.
+ * Create a dummy trace message with timestamp to be
+ * passed to do_send_schedfix_to_port().
+ */
+ ts_type = TFLGS_TS_TYPE(c_p);
+ ts = write_ts(ts_type, local_heap, NULL, NULL);
trace_port->control_flags &= ~PORT_CONTROL_FLAG_HEAVY;
do_send_to_port(*tracer_pid,
@@ -576,7 +807,7 @@ send_to_port(Process *c_p, Eterm message,
* just after writning the real trace message, and now gets scheduled
* in again.
*/
- do_send_schedfix_to_port(trace_port, c_p->common.id, ts);
+ do_send_schedfix_to_port(trace_port, c_p->common.id, ts, ts_type);
}
erts_port_release(trace_port);
@@ -636,11 +867,7 @@ profile_send(Eterm from, Eterm message) {
hp = erts_alloc_message_heap(sz, &bp, &off_heap, profile_p, 0);
msg = copy_struct(message, sz, &hp, &bp->off_heap);
- erts_queue_message(profile_p, NULL, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(profile_p, NULL, bp, msg, NIL);
}
}
@@ -649,20 +876,19 @@ profile_send(Eterm from, Eterm message) {
/* A fake schedule out/in message pair will be sent,
* if the driver so requests.
- * If (timestamp == NIL), one is fetched from GET_NOW().
*
* 'c_p' is the currently executing process, may be NULL.
*/
static void
seq_trace_send_to_port(Process *c_p,
Eterm seq_tracer,
- Eterm message,
- Eterm timestamp)
+ Eterm message)
{
Port* trace_port;
#ifndef ERTS_SMP
- Eterm ts, *hp;
-#define LOCAL_HEAP_SIZE (4)
+ int ts_type;
+ Eterm ts;
+#define LOCAL_HEAP_SIZE ERTS_TRACE_PATCH_TS_MAX_SIZE
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#endif
@@ -687,7 +913,7 @@ seq_trace_send_to_port(Process *c_p,
}
if (c_p == NULL
- || (! IS_TRACED_FL(c_p, F_TRACE_SCHED | F_TIMESTAMP))) {
+ || (! IS_TRACED_FL(c_p, F_TRACE_SCHED | F_TIMESTAMP_MASK))) {
#endif
do_send_to_port(seq_tracer,
trace_port,
@@ -704,20 +930,12 @@ seq_trace_send_to_port(Process *c_p,
* with 'running' and 'timestamp'.
*/
- if (timestamp != NIL) {
- ts = timestamp;
- } else {
- /* A fake schedule might be needed,
- * but this message does not contain a timestamp.
- * Create a dummy trace message with timestamp to be
- * passed to do_send_schedfix_to_port().
- */
- Uint ms,s,us;
- GET_NOW(&ms, &s, &us);
- hp = local_heap;
- ts = TUPLE3(hp, make_small(ms), make_small(s), make_small(us));
- hp += 4;
- }
+ /* A fake schedule might be needed.
+ * Create a dummy trace message with timestamp to be
+ * passed to do_send_schedfix_to_port().
+ */
+ ts_type = TFLGS_TS_TYPE(c_p);
+ ts = write_ts(ts_type, local_heap, NULL, NULL);
trace_port->control_flags &= ~PORT_CONTROL_FLAG_HEAVY;
do_send_to_port(seq_tracer,
@@ -736,7 +954,7 @@ seq_trace_send_to_port(Process *c_p,
* just after writing the real trace message, and now gets scheduled
* in again.
*/
- do_send_schedfix_to_port(trace_port, c_p->common.id, ts);
+ do_send_schedfix_to_port(trace_port, c_p->common.id, ts, ts_type);
}
erts_port_release(trace_port);
@@ -746,32 +964,6 @@ seq_trace_send_to_port(Process *c_p,
#endif
}
-#define TS_HEAP_WORDS 5
-#define TS_SIZE(p) ((ERTS_TRACE_FLAGS((p)) & F_TIMESTAMP) \
- ? TS_HEAP_WORDS \
- : 0)
-
-/*
- * Patch a timestamp into a tuple. The tuple must be the last thing
- * built on the heap.
- *
- * Returns the new hp pointer.
-*/
-static Eterm*
-patch_ts(Eterm tuple, Eterm* hp)
-{
- Uint ms, s, us;
- Eterm* ptr = tuple_val(tuple);
- int arity = arityval(*ptr);
-
- ASSERT((ptr+arity+1) == hp);
- ptr[0] = make_arityval(arity+1);
- ptr[1] = am_trace_ts;
- GET_NOW(&ms, &s, &us);
- *hp = TUPLE3(hp+1, make_small(ms), make_small(s), make_small(us));
- return hp+5;
-}
-
static ERTS_INLINE void
send_to_tracer(Process *tracee,
ERTS_TRACER_REF_TYPE tracer_ref,
@@ -784,13 +976,13 @@ send_to_tracer(Process *tracee,
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(tracee) & F_TIMESTAMP)
- *hpp = patch_ts(msg, *hpp);
-
- if (is_internal_pid(ERTS_TRACER_PROC(tracee)))
+ if (is_internal_pid(ERTS_TRACER_PROC(tracee))) {
+ PATCH_TS(TFLGS_TS_TYPE(tracee), msg, *hpp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(tracee->common.id, tracer_ref, msg, bp);
+ }
else {
ASSERT(is_internal_port(ERTS_TRACER_PROC(tracee)));
+ PATCH_TS(TFLGS_TS_TYPE(tracee), msg, *hpp, NULL, NULL);
send_to_port(no_fake_sched ? NULL : tracee,
msg,
&ERTS_TRACER_PROC(tracee),
@@ -804,7 +996,7 @@ send_to_tracer(Process *tracee,
static void
trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
{
-#define LOCAL_HEAP_SIZE (5+4+1+TS_HEAP_WORDS)
+#define LOCAL_HEAP_SIZE (5+4+1+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p);
Eterm tmp, mess, *hp;
ErlHeapFragment *bp = NULL;
@@ -860,7 +1052,7 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
size += 4;
if (sched_no)
size += 1;
- size += TS_SIZE(p);
+ size += PATCH_TS_SIZE(p);
hp = ERTS_ALLOC_SYSMSG_HEAP(size, &bp, &off_heap, tracer_ref);
}
@@ -934,7 +1126,7 @@ trace_send(Process *p, Eterm to, Eterm msg)
}
if (is_internal_port(ERTS_TRACER_PROC(p))) {
-#define LOCAL_HEAP_SIZE (11)
+#define LOCAL_HEAP_SIZE (6 + ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -942,9 +1134,7 @@ trace_send(Process *p, Eterm to, Eterm msg)
mess = TUPLE5(hp, am_trace, p->common.id, operation, msg, to);
hp += 6;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, NULL, NULL);
send_to_port(p, mess, &ERTS_TRACER_PROC(p), &ERTS_TRACE_FLAGS(p));
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#undef LOCAL_HEAP_SIZE
@@ -963,7 +1153,7 @@ trace_send(Process *p, Eterm to, Eterm msg)
sz_msg = size_object(msg);
sz_to = size_object(to);
- need = sz_msg + sz_to + 6 + TS_SIZE(p);
+ need = sz_msg + sz_to + 6 + PATCH_TS_SIZE(p);
hp = ERTS_ALLOC_SYSMSG_HEAP(need, &bp, &off_heap, tracer_ref);
@@ -980,10 +1170,7 @@ trace_send(Process *p, Eterm to, Eterm msg)
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- patch_ts(mess, hp);
- }
-
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(p->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
}
@@ -1000,7 +1187,7 @@ trace_receive(Process *rp, Eterm msg)
Eterm* hp;
if (is_internal_port(ERTS_TRACER_PROC(rp))) {
-#define LOCAL_HEAP_SIZE (10)
+#define LOCAL_HEAP_SIZE (5+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -1008,9 +1195,7 @@ trace_receive(Process *rp, Eterm msg)
mess = TUPLE4(hp, am_trace, rp->common.id, am_receive, msg);
hp += 5;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(rp) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(rp), mess, hp, NULL, NULL);
send_to_port(rp, mess, &ERTS_TRACER_PROC(rp), &ERTS_TRACE_FLAGS(rp));
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#undef LOCAL_HEAP_SIZE
@@ -1029,7 +1214,7 @@ trace_receive(Process *rp, Eterm msg)
sz_msg = size_object(msg);
- hsz = sz_msg + 5 + TS_SIZE(rp);
+ hsz = sz_msg + 5 + PATCH_TS_SIZE(rp);
hp = ERTS_ALLOC_SYSMSG_HEAP(hsz, &bp, &off_heap, tracer_ref);
@@ -1039,10 +1224,7 @@ trace_receive(Process *rp, Eterm msg)
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(rp) & F_TIMESTAMP) {
- patch_ts(mess, hp);
- }
-
+ PATCH_TS(TFLGS_TS_TYPE(rp), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(rp->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
}
@@ -1092,6 +1274,7 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
Eterm type_atom;
int sz_exit;
Eterm seq_tracer;
+ int ts_type;
seq_tracer = erts_get_system_seq_tracer();
@@ -1106,7 +1289,7 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
case SEQ_TRACE_PRINT: type_atom = am_print; break;
case SEQ_TRACE_RECEIVE: type_atom = am_receive; break;
default:
- erl_exit(1, "invalid type in seq_trace_output_generic: %d:\n", type);
+ erts_exit(ERTS_ERROR_EXIT, "invalid type in seq_trace_output_generic: %d:\n", type);
return; /* To avoid warning */
}
@@ -1119,8 +1302,10 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
return; /* no need to send anything */
}
+ ts_type = ERTS_SEQTFLGS2TSTYPE(unsigned_val(SEQ_TRACE_T_FLAGS(token)));
+
if (is_internal_port(seq_tracer)) {
-#define LOCAL_HEAP_SIZE (64)
+#define LOCAL_HEAP_SIZE (60 + ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -1136,17 +1321,17 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
mess = TUPLE5(hp, type_atom, lastcnt_serial, SEQ_TRACE_T_SENDER(token),
receiver, msg);
hp += 6;
+
erts_smp_mtx_lock(&smq_mtx);
- if ((unsigned_val(SEQ_TRACE_T_FLAGS(token)) & SEQ_TRACE_TIMESTAMP) == 0) {
+ if (!ts_type) {
mess = TUPLE3(hp, am_seq_trace, label, mess);
- seq_trace_send_to_port(NULL, seq_tracer, mess, NIL);
+ seq_trace_send_to_port(NULL, seq_tracer, mess);
} else {
- Uint ms,s,us,ts;
- GET_NOW(&ms, &s, &us);
- ts = TUPLE3(hp, make_small(ms),make_small(s), make_small(us));
- hp += 4;
- mess = TUPLE4(hp, am_seq_trace, label, mess, ts);
- seq_trace_send_to_port(process, seq_tracer, mess, ts);
+ mess = TUPLE4(hp, am_seq_trace, label, mess,
+ NIL /* Will be overwritten by timestamp */);
+ hp += 5;
+ hp[-1] = write_ts(ts_type, hp, NULL, NULL);
+ seq_trace_send_to_port(process, seq_tracer, mess);
}
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#undef LOCAL_HEAP_SIZE
@@ -1181,8 +1366,7 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
sz_lastcnt_serial = 3; /* TUPLE2 */
sz_msg = size_object(msg);
- sz_ts = ((unsigned_val(SEQ_TRACE_T_FLAGS(token)) & SEQ_TRACE_TIMESTAMP) ?
- 5 : 0);
+ sz_ts = patch_ts_size(ts_type);
if (exitfrom != NIL) {
sz_exit = 4; /* create {'EXIT',exitfrom,msg} */
sz_exitfrom = size_object(exitfrom);
@@ -1226,25 +1410,28 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
erts_smp_mtx_lock(&smq_mtx);
- if (sz_ts) {/* timestamp should be included */
- Uint ms,s,us,ts;
- GET_NOW(&ms, &s, &us);
- ts = TUPLE3(hp, make_small(ms),make_small(s), make_small(us));
- hp += 4;
- mess = TUPLE4(hp, am_seq_trace, label, mess, ts);
- } else {
+ if (!ts_type)
mess = TUPLE3(hp, am_seq_trace, label, mess);
+ else {
+ mess = TUPLE4(hp, am_seq_trace, label, mess,
+ NIL /* Will be overwritten by timestamp */);
+ hp += 5;
+ /* Write timestamp in element 6 of the 'msg' tuple */
+ hp[-1] = write_ts(ts_type, hp, bp,
+#ifndef ERTS_SMP
+ tracer
+#else
+ NULL
+#endif
+ );
}
#ifdef ERTS_SMP
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SEQTRACE, NIL, NIL, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
#else
- erts_queue_message(tracer, NULL, bp, mess, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- ); /* trace_token must be NIL here */
+ /* trace_token must be NIL here */
+ erts_queue_message(tracer, NULL, bp, mess, NIL);
#endif
}
}
@@ -1255,7 +1442,7 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
void
erts_trace_return_to(Process *p, BeamInstr *pc)
{
-#define LOCAL_HEAP_SIZE (4+5+5)
+#define LOCAL_HEAP_SIZE (4+5+ERTS_TRACE_PATCH_TS_MAX_SIZE)
Eterm* hp;
Eterm mfa;
Eterm mess;
@@ -1280,9 +1467,7 @@ erts_trace_return_to(Process *p, BeamInstr *pc)
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, NULL, NULL);
if (is_internal_port(ERTS_TRACER_PROC(p))) {
send_to_port(p, mess, &ERTS_TRACER_PROC(p), &ERTS_TRACE_FLAGS(p));
@@ -1329,6 +1514,7 @@ erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
Eterm mod, name;
int arity;
Uint meta_flags, *tracee_flags;
+ int ts_type;
#ifdef ERTS_SMP
Eterm tracee;
#endif
@@ -1364,7 +1550,7 @@ erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
* meta trace =>
* use fixed flag set instead of process flags
*/
- meta_flags = F_TRACE_CALLS | F_TIMESTAMP;
+ meta_flags = F_TRACE_CALLS | F_NOW_TS;
tracee_flags = &meta_flags;
#ifdef ERTS_SMP
tracee = NIL;
@@ -1378,8 +1564,10 @@ erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
name = fi[1];
arity = fi[2];
+ ts_type = ERTS_TFLGS2TSTYPE(*tracee_flags);
+
if (is_internal_port(*tracer_pid)) {
-#define LOCAL_HEAP_SIZE (4+6+5)
+#define LOCAL_HEAP_SIZE (4+6+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
@@ -1388,9 +1576,7 @@ erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
mess = TUPLE5(hp, am_trace, p->common.id, am_return_from, mfa, retval);
hp += 6;
erts_smp_mtx_lock(&smq_mtx);
- if (*tracee_flags & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(ts_type, mess, hp, NULL, NULL);
send_to_port(p, mess, tracer_pid, tracee_flags);
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#undef LOCAL_HEAP_SIZE
@@ -1401,24 +1587,15 @@ erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
ERTS_TRACER_REF_TYPE tracer_ref;
unsigned size;
unsigned retval_size;
-#ifdef DEBUG
- Eterm* limit;
-#endif
ASSERT(is_internal_pid(*tracer_pid));
ERTS_GET_TRACER_REF(tracer_ref, *tracer_pid, *tracee_flags);
-
+
retval_size = size_object(retval);
- size = 6 + 4 + retval_size;
- if (*tracee_flags & F_TIMESTAMP) {
- size += 1+4;
- }
+ size = 6 + 4 + retval_size + patch_ts_size(ts_type);
hp = ERTS_ALLOC_SYSMSG_HEAP(size, &bp, &off_heap, tracer_ref);
-#ifdef DEBUG
- limit = hp + size;
-#endif
/*
* Build the trace tuple and put it into receive queue of the tracer process.
@@ -1432,11 +1609,7 @@ erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
erts_smp_mtx_lock(&smq_mtx);
- if (*tracee_flags & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
-
- ASSERT(hp == limit);
+ PATCH_TS(ts_type, mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(tracee, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
@@ -1459,6 +1632,7 @@ erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
Eterm cv;
Eterm mess;
Uint meta_flags, *tracee_flags;
+ int ts_type;
#ifdef ERTS_SMP
Eterm tracee;
#endif
@@ -1497,15 +1671,17 @@ erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
* meta trace =>
* use fixed flag set instead of process flags
*/
- meta_flags = F_TRACE_CALLS | F_TIMESTAMP;
+ meta_flags = F_TRACE_CALLS | F_NOW_TS;
tracee_flags = &meta_flags;
#ifdef ERTS_SMP
tracee = NIL;
#endif
}
+ ts_type = ERTS_TFLGS2TSTYPE(*tracee_flags);
+
if (is_internal_port(*tracer_pid)) {
-#define LOCAL_HEAP_SIZE (4+3+6+5)
+#define LOCAL_HEAP_SIZE (4+3+6+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -1518,10 +1694,7 @@ erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
hp += 6;
ASSERT((hp - local_heap) <= LOCAL_HEAP_SIZE);
erts_smp_mtx_lock(&smq_mtx);
- if (*tracee_flags & F_TIMESTAMP) {
- hp = patch_ts(mess, hp); /* hp += 5 */
- ASSERT((hp - local_heap) == LOCAL_HEAP_SIZE);
- }
+ PATCH_TS(ts_type, mess, hp, NULL, NULL);
send_to_port(p, mess, tracer_pid, tracee_flags);
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#undef LOCAL_HEAP_SIZE
@@ -1532,24 +1705,15 @@ erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
ERTS_TRACER_REF_TYPE tracer_ref;
unsigned size;
unsigned value_size;
-#ifdef DEBUG
- Eterm* limit;
-#endif
ASSERT(is_internal_pid(*tracer_pid));
ERTS_GET_TRACER_REF(tracer_ref, *tracer_pid, *tracee_flags);
value_size = size_object(value);
- size = 6 + 4 + 3 + value_size;
- if (*tracee_flags & F_TIMESTAMP) {
- size += 1+4;
- }
+ size = 6 + 4 + 3 + value_size + patch_ts_size(ts_type);
hp = ERTS_ALLOC_SYSMSG_HEAP(size, &bp, &off_heap, tracer_ref);
-#ifdef DEBUG
- limit = hp + size;
-#endif
/*
* Build the trace tuple and put it into receive queue of the tracer process.
@@ -1566,11 +1730,7 @@ erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
erts_smp_mtx_lock(&smq_mtx);
- if (*tracee_flags & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
-
- ASSERT(hp == limit);
+ PATCH_TS(ts_type, mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(tracee, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
@@ -1603,6 +1763,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
Eterm pam_result = am_true;
Eterm mess;
Uint meta_flags, *tracee_flags;
+ int ts_type;
#ifdef ERTS_SMP
Eterm tracee;
#endif
@@ -1644,7 +1805,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
/* No trace messages for sensitive processes. */
return 0;
}
- meta_flags = F_TRACE_CALLS | F_TIMESTAMP;
+ meta_flags = F_TRACE_CALLS | F_NOW_TS;
tracee_flags = &meta_flags;
#ifdef ERTS_SMP
tracee = NIL;
@@ -1687,12 +1848,14 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
}
args = transformed_args;
+ ts_type = ERTS_TFLGS2TSTYPE(*tracee_flags);
+
if (is_internal_port(*tracer_pid)) {
#if HEAP_ON_C_STACK
- Eterm local_heap[64+MAX_ARG];
+ Eterm local_heap[60+ERTS_TRACE_PATCH_TS_MAX_SIZE+MAX_ARG];
#else
Eterm *local_heap = erts_alloc(ERTS_ALC_T_TEMP_TERM,
- sizeof(Eterm)*(64+MAX_ARG));
+ sizeof(Eterm)*(60+ERTS_TRACE_PATCH_TS_MAX_SIZE+MAX_ARG));
#endif
hp = local_heap;
@@ -1807,9 +1970,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
*hp++ = pam_result;
}
erts_smp_mtx_lock(&smq_mtx);
- if (*tracee_flags & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(ts_type, mess, hp, NULL, NULL);
send_to_port(p, mess, tracer_pid, tracee_flags);
erts_smp_mtx_unlock(&smq_mtx);
erts_match_set_release_result(p);
@@ -1831,9 +1992,6 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
unsigned sizes[MAX_ARG];
unsigned pam_result_size = 0;
int invalid_tracer;
-#ifdef DEBUG
- Eterm* limit;
-#endif
ASSERT(is_internal_pid(*tracer_pid));
@@ -1926,10 +2084,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
size += sizes[i];
}
}
- if (*tracee_flags & F_TIMESTAMP) {
- size += 1 + 4;
- /* One element in trace tuple + timestamp tuple. */
- }
+ size += patch_ts_size(ts_type);
if (pam_result != am_true) {
pam_result_size = size_object(pam_result);
size += 1 + pam_result_size;
@@ -1937,9 +2092,6 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
}
hp = ERTS_ALLOC_SYSMSG_HEAP(size, &bp, &off_heap, tracer_ref);
-#ifdef DEBUG
- limit = hp + size;
-#endif
/*
* Build the the {M,F,A} tuple in the message buffer.
@@ -1982,11 +2134,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
erts_smp_mtx_lock(&smq_mtx);
- if (*tracee_flags & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
-
- ASSERT(hp == limit);
+ PATCH_TS(ts_type, mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(tracee, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
@@ -2021,9 +2169,7 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
mess = TUPLE4(hp, am_trace, t_p->common.id, what, data);
hp += 5;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(t_p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(t_p), mess, hp, NULL, NULL);
send_to_port(
#ifndef ERTS_SMP
/* No fake schedule out and in again after an exit */
@@ -2053,7 +2199,7 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
sz_data = size_object(data);
- need = sz_data + 5 + TS_SIZE(t_p);
+ need = sz_data + 5 + PATCH_TS_SIZE(t_p);
hp = ERTS_ALLOC_SYSMSG_HEAP(need, &bp, &off_heap, tracer_ref);
@@ -2063,9 +2209,7 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(t_p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(t_p), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(t_p->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
@@ -2099,9 +2243,7 @@ trace_proc_spawn(Process *p, Eterm pid,
mess = TUPLE5(hp, am_trace, p->common.id, am_spawn, pid, mfa);
hp += 6;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, NULL, NULL);
send_to_port(p, mess, &ERTS_TRACER_PROC(p), &ERTS_TRACE_FLAGS(p));
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#undef LOCAL_HEAP_SIZE
@@ -2122,7 +2264,7 @@ trace_proc_spawn(Process *p, Eterm pid,
sz_args = size_object(args);
sz_pid = size_object(pid);
- need = sz_args + 4 + 6 + TS_SIZE(p);
+ need = sz_args + 4 + 6 + PATCH_TS_SIZE(p);
hp = ERTS_ALLOC_SYSMSG_HEAP(need, &bp, &off_heap, tracer_ref);
@@ -2135,9 +2277,7 @@ trace_proc_spawn(Process *p, Eterm pid,
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(p->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
@@ -2219,13 +2359,10 @@ trace_gc(Process *p, Eterm what)
#define LOCAL_HEAP_SIZE \
(sizeof(values)/sizeof(*values)) * \
(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) + \
- 5/*4-tuple */ + TS_HEAP_WORDS
+ 5/*4-tuple */ + ERTS_TRACE_PATCH_TS_MAX_SIZE
DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p);
-#ifdef DEBUG
- Eterm* limit;
-#endif
- ASSERT(sizeof(values)/sizeof(*values) == sizeof(tags)/sizeof(Eterm));
+ ERTS_CT_ASSERT(sizeof(values)/sizeof(*values) == sizeof(tags)/sizeof(Eterm));
UseTmpHeap(LOCAL_HEAP_SIZE,p);
@@ -2238,7 +2375,7 @@ trace_gc(Process *p, Eterm what)
sizeof(values)/sizeof(*values),
tags,
values);
- size += 5/*4-tuple*/ + TS_SIZE(p);
+ size += 5/*4-tuple*/ + PATCH_TS_SIZE(p);
#endif
} else {
ASSERT(is_internal_pid(ERTS_TRACER_PROC(p)));
@@ -2253,15 +2390,12 @@ trace_gc(Process *p, Eterm what)
sizeof(values)/sizeof(*values),
tags,
values);
- size += 5/*4-tuple*/ + TS_SIZE(p);
+ size += 5/*4-tuple*/ + PATCH_TS_SIZE(p);
hp = ERTS_ALLOC_SYSMSG_HEAP(size, &bp, &off_heap, tracer_ref);
}
-#ifdef DEBUG
- limit = hp + size;
ASSERT(size <= LOCAL_HEAP_SIZE);
-#endif
msg = erts_bld_atom_uword_2tup_list(&hp,
NULL,
@@ -2274,14 +2408,14 @@ trace_gc(Process *p, Eterm what)
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(msg, hp);
- }
- ASSERT(hp == limit);
- if (is_internal_port(ERTS_TRACER_PROC(p)))
+ if (is_internal_port(ERTS_TRACER_PROC(p))) {
+ PATCH_TS(TFLGS_TS_TYPE(p), msg, hp, NULL, NULL);
send_to_port(p, msg, &ERTS_TRACER_PROC(p), &ERTS_TRACE_FLAGS(p));
- else
+ }
+ else {
+ PATCH_TS(TFLGS_TS_TYPE(p), msg, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(p->common.id, tracer_ref, msg, bp);
+ }
erts_smp_mtx_unlock(&smq_mtx);
UnUseTmpHeap(LOCAL_HEAP_SIZE,p);
#undef LOCAL_HEAP_SIZE
@@ -2343,11 +2477,7 @@ monitor_long_schedule_proc(Process *p, BeamInstr *in_fp, BeamInstr *out_fp, Uint
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->common.id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL);
#endif
}
void
@@ -2408,11 +2538,7 @@ monitor_long_schedule_port(Port *pp, ErtsPortTaskType type, Uint time)
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, pp->common.id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL);
#endif
}
@@ -2483,11 +2609,7 @@ monitor_long_gc(Process *p, Uint time) {
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->common.id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL);
#endif
}
@@ -2558,11 +2680,7 @@ monitor_large_heap(Process *p) {
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->common.id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL);
#endif
}
@@ -2590,11 +2708,7 @@ monitor_generic(Process *p, Eterm type, Eterm spec) {
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->common.id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL);
#endif
}
@@ -2605,19 +2719,18 @@ monitor_generic(Process *p, Eterm type, Eterm spec) {
void
profile_scheduler(Eterm scheduler_id, Eterm state) {
- Eterm *hp, msg, timestamp;
- Uint Ms, s, us;
+ Eterm *hp, msg;
+ ErlHeapFragment *bp = NULL;
#ifndef ERTS_SMP
-#define LOCAL_HEAP_SIZE (4 + 7)
+#define LOCAL_HEAP_SIZE (7 + ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
#else
- ErlHeapFragment *bp;
Uint hsz;
- hsz = 4 + 7;
+ hsz = 7 + patch_ts_size(erts_system_profile_ts_type)-1;
bp = new_message_buffer(hsz);
hp = bp->mem;
@@ -2637,10 +2750,13 @@ profile_scheduler(Eterm scheduler_id, Eterm state) {
break;
}
- GET_NOW(&Ms, &s, &us);
- timestamp = TUPLE3(hp, make_small(Ms), make_small(s), make_small(us)); hp += 4;
- msg = TUPLE6(hp, am_profile, am_scheduler, scheduler_id, state,
- make_small(active_sched), timestamp); hp += 7;
+ msg = TUPLE6(hp, am_profile, am_scheduler, scheduler_id,
+ state, make_small(active_sched),
+ NIL /* Will be overwritten by timestamp */);
+ hp += 7;
+
+ /* Write timestamp in element 6 of the 'msg' tuple */
+ hp[-1] = write_ts(erts_system_profile_ts_type, hp, bp, NULL);
#ifndef ERTS_SMP
profile_send(NIL, msg);
@@ -2711,7 +2827,7 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
Eterm* hp;
if (is_internal_port(ERTS_TRACER_PROC(p))) {
-#define LOCAL_HEAP_SIZE (5+6)
+#define LOCAL_HEAP_SIZE (6+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -2720,9 +2836,7 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
mess = TUPLE5(hp, am_trace, calling_pid, am_open, p->common.id, drv_name);
hp += 6;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, NULL, NULL);
/* No fake schedule */
send_to_port(NULL, mess, &ERTS_TRACER_PROC(p), &ERTS_TRACE_FLAGS(p));
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -2736,7 +2850,7 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
ASSERT(is_internal_pid(ERTS_TRACER_PROC(p)));
- sz_data = 6 + TS_SIZE(p);
+ sz_data = 6 + PATCH_TS_SIZE(p);
ERTS_GET_TRACER_REF(tracer_ref,
ERTS_TRACER_PROC(p),
@@ -2749,9 +2863,7 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(p->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
@@ -2775,7 +2887,7 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
|| erts_thr_progress_is_blocking());
if (is_internal_port(ERTS_TRACER_PROC(t_p))) {
-#define LOCAL_HEAP_SIZE (5+5)
+#define LOCAL_HEAP_SIZE (5+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -2783,9 +2895,7 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
mess = TUPLE4(hp, am_trace, t_p->common.id, what, data);
hp += 5;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(t_p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(t_p), mess, hp, NULL, NULL);
/* No fake schedule */
send_to_port(NULL,mess,&ERTS_TRACER_PROC(t_p),&ERTS_TRACE_FLAGS(t_p));
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -2799,7 +2909,7 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
ASSERT(is_internal_pid(ERTS_TRACER_PROC(t_p)));
- sz_data = 5 + TS_SIZE(t_p);
+ sz_data = 5 + PATCH_TS_SIZE(t_p);
ERTS_GET_TRACER_REF(tracer_ref,
ERTS_TRACER_PROC(t_p),
@@ -2812,9 +2922,7 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(t_p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+ PATCH_TS(TFLGS_TS_TYPE(t_p), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(t_p->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
@@ -2842,7 +2950,7 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
Eterm sched_id = am_undefined;
if (is_internal_port(ERTS_TRACER_PROC(p))) {
-#define LOCAL_HEAP_SIZE (5+6)
+#define LOCAL_HEAP_SIZE (6+ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -2865,9 +2973,8 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
hp += ws;
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
+
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, NULL, NULL);
/* No fake scheduling */
send_to_port(NULL, mess, &ERTS_TRACER_PROC(p), &ERTS_TRACE_FLAGS(p));
@@ -2887,7 +2994,7 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
ERTS_TRACER_PROC(p),
ERTS_TRACE_FLAGS(p));
- hp = ERTS_ALLOC_SYSMSG_HEAP(ws+TS_SIZE(p), &bp, &off_heap, tracer_ref);
+ hp = ERTS_ALLOC_SYSMSG_HEAP(ws+PATCH_TS_SIZE(p), &bp, &off_heap, tracer_ref);
if (IS_TRACED_FL(p, F_TRACE_SCHED_NO)) {
#ifdef ERTS_SMP
@@ -2905,10 +3012,7 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
erts_smp_mtx_lock(&smq_mtx);
- if (ERTS_TRACE_FLAGS(p) & F_TIMESTAMP) {
- hp = patch_ts(mess, hp);
- }
-
+ PATCH_TS(TFLGS_TS_TYPE(p), mess, hp, bp, tracer_ref);
ERTS_ENQ_TRACE_MSG(p->common.id, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
}
@@ -2918,13 +3022,12 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
void
profile_runnable_port(Port *p, Eterm status) {
- Uint Ms, s, us;
- Eterm *hp, msg, timestamp;
-
+ Eterm *hp, msg;
+ ErlHeapFragment *bp = NULL;
Eterm count = make_small(0);
#ifndef ERTS_SMP
-#define LOCAL_HEAP_SIZE (4 + 6)
+#define LOCAL_HEAP_SIZE (6 + ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -2932,10 +3035,9 @@ profile_runnable_port(Port *p, Eterm status) {
hp = local_heap;
#else
- ErlHeapFragment *bp;
Uint hsz;
- hsz = 4 + 6;
+ hsz = 6 + patch_ts_size(erts_system_profile_ts_type)-1;
bp = new_message_buffer(hsz);
hp = bp->mem;
@@ -2943,9 +3045,12 @@ profile_runnable_port(Port *p, Eterm status) {
erts_smp_mtx_lock(&smq_mtx);
- GET_NOW(&Ms, &s, &us);
- timestamp = TUPLE3(hp, make_small(Ms), make_small(s), make_small(us)); hp += 4;
- msg = TUPLE5(hp, am_profile, p->common.id, status, count, timestamp); hp += 6;
+ msg = TUPLE5(hp, am_profile, p->common.id, status, count,
+ NIL /* Will be overwritten by timestamp */);
+ hp += 6;
+
+ /* Write timestamp in element 5 of the 'msg' tuple */
+ hp[-1] = write_ts(erts_system_profile_ts_type, hp, bp, NULL);
#ifndef ERTS_SMP
profile_send(p->common.id, msg);
@@ -2960,20 +3065,19 @@ profile_runnable_port(Port *p, Eterm status) {
/* Process profiling */
void
profile_runnable_proc(Process *p, Eterm status){
- Uint Ms, s, us;
- Eterm *hp, msg, timestamp;
+ Eterm *hp, msg;
Eterm where = am_undefined;
+ ErlHeapFragment *bp = NULL;
#ifndef ERTS_SMP
-#define LOCAL_HEAP_SIZE (4 + 6 + 4)
+#define LOCAL_HEAP_SIZE (4 + 6 + ERTS_TRACE_PATCH_TS_MAX_SIZE)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
#else
- ErlHeapFragment *bp;
- Uint hsz = 4 + 6 + 4;
+ Uint hsz = 4 + 6 + patch_ts_size(erts_system_profile_ts_type)-1;
#endif
if (!p->current) {
@@ -2982,7 +3086,7 @@ profile_runnable_proc(Process *p, Eterm status){
#ifdef ERTS_SMP
if (!p->current) {
- hsz = 4 + 6;
+ hsz -= 4;
}
bp = new_message_buffer(hsz);
@@ -2997,9 +3101,13 @@ profile_runnable_proc(Process *p, Eterm status){
erts_smp_mtx_lock(&smq_mtx);
- GET_NOW(&Ms, &s, &us);
- timestamp = TUPLE3(hp, make_small(Ms), make_small(s), make_small(us)); hp += 4;
- msg = TUPLE5(hp, am_profile, p->common.id, status, where, timestamp); hp += 6;
+ msg = TUPLE5(hp, am_profile, p->common.id, status, where,
+ NIL /* Will be overwritten by timestamp */);
+ hp += 6;
+
+ /* Write timestamp in element 5 of the 'msg' tuple */
+ hp[-1] = write_ts(erts_system_profile_ts_type, hp, bp, NULL);
+
#ifndef ERTS_SMP
profile_send(p->common.id, msg);
UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
@@ -3389,11 +3497,7 @@ sys_msg_dispatcher_func(void *unused)
}
else {
queue_proc_msg:
- erts_queue_message(proc,&proc_locks,smqp->bp,smqp->msg,NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(proc,&proc_locks,smqp->bp,smqp->msg,NIL);
#ifdef DEBUG_PRINTOUTS
erts_fprintf(stderr, "delivered\n");
#endif
@@ -3492,16 +3596,13 @@ init_sys_msg_dispatcher(void)
thr_opts.coreNo = 0;
#endif
thr_opts.detached = 1;
+ thr_opts.name = "sys_msg_dispatcher";
init_smq_element_alloc();
sys_message_queue = NULL;
sys_message_queue_end = NULL;
erts_smp_cnd_init(&smq_cnd);
erts_smp_mtx_init(&smq_mtx, "sys_msg_q");
-#ifdef ETHR_HAVE_THREAD_NAMES
- thr_opts.name = "sys_msg_dispatcher";
-#endif
-
erts_smp_thr_create(&sys_msg_dispatcher_tid,
sys_msg_dispatcher_func,
NULL,
diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h
index 4f2c70d6e7..a0058264d7 100644
--- a/erts/emulator/beam/erl_trace.h
+++ b/erts/emulator/beam/erl_trace.h
@@ -3,22 +3,53 @@
*
* Copyright Ericsson AB 2012-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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 ERL_TRACE_H__FLAGS__
+#define ERL_TRACE_H__FLAGS__
+/*
+ * NOTE! The bits used for these flags matter. The flag with
+ * the least significant bit will take precedence!
+ *
+ * The "now timestamp" has highest precedence due to
+ * compatibility reasons.
+ */
+#define ERTS_TRACE_FLG_NOW_TIMESTAMP (1 << 0)
+#define ERTS_TRACE_FLG_STRICT_MONOTONIC_TIMESTAMP (1 << 1)
+#define ERTS_TRACE_FLG_MONOTONIC_TIMESTAMP (1 << 2)
+
+/*
+ * The bits used effects trace flags (of processes and ports)
+ * as well as sequential trace flags. If changed make sure
+ * these arn't messed up...
+ */
+#define ERTS_TRACE_TS_TYPE_BITS 3
+#define ERTS_TRACE_TS_TYPE_MASK \
+ ((1 << ERTS_TRACE_TS_TYPE_BITS) - 1)
+
+#define ERTS_TFLGS2TSTYPE(TFLGS) \
+ ((int) (((TFLGS) >> ERTS_TRACE_FLAGS_TS_TYPE_SHIFT) \
+ & ERTS_TRACE_TS_TYPE_MASK))
+#define ERTS_SEQTFLGS2TSTYPE(SEQTFLGS) \
+ ((int) (((SEQTFLGS) >> ERTS_SEQ_TRACE_FLAGS_TS_TYPE_SHIFT) \
+ & ERTS_TRACE_TS_TYPE_MASK))
+
+#endif /* ERL_TRACE_H__FLAGS__ */
-#ifndef ERL_TRACE_H__
+#if !defined(ERL_TRACE_H__) && !defined(ERTS_ONLY_INCLUDE_TRACE_FLAGS)
#define ERL_TRACE_H__
struct binary;
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index f8e1431a53..36d85b0a22 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -2506,7 +2507,7 @@ void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars)
((Uint) (bytes[3] & ((byte) 0x3F)));
bytes += 4;
} else {
- erl_exit(1,"Internal unicode error in prim_file:internal_name2native/1");
+ erts_exit(ERTS_ERROR_EXIT,"Internal unicode error in prim_file:internal_name2native/1");
}
*target++ = (byte) (unipoint & 0xFF);
*target++ = (byte) ((unipoint >> 8) & 0xFF);
diff --git a/erts/emulator/beam/erl_unicode.h b/erts/emulator/beam/erl_unicode.h
index 1b63b797c2..4c25d89b7c 100644
--- a/erts/emulator/beam/erl_unicode.h
+++ b/erts/emulator/beam/erl_unicode.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_unicode_normalize.h b/erts/emulator/beam/erl_unicode_normalize.h
index fb0a111ca2..16c62db50e 100644
--- a/erts/emulator/beam/erl_unicode_normalize.h
+++ b/erts/emulator/beam/erl_unicode_normalize.h
@@ -1,21 +1,22 @@
/*
-* %CopyrightBegin%
-*
-* Copyright Ericsson AB 1999-2010. All Rights Reserved.
-*
-* The contents of this file are subject to the Erlang Public License,
-* Version 1.1, (the "License"); you may not use this file except in
-* compliance with the License. You should have received a copy of the
-* Erlang Public License along with this software. If not, it can be
-* retrieved online at http://www.erlang.org/.
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* %CopyrightEnd%
-*/
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.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%
+ */
/*
* This file is automatically generated by dec.erl, do not edit manually
*/
diff --git a/erts/emulator/beam/erl_utils.h b/erts/emulator/beam/erl_utils.h
index c32f8fd61c..6dab3bf297 100644
--- a/erts/emulator/beam/erl_utils.h
+++ b/erts/emulator/beam/erl_utils.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -113,12 +114,14 @@ void erts_silence_warn_unused_result(long unused);
int erts_fit_in_bits_int64(Sint64);
int erts_fit_in_bits_int32(Sint32);
+int erts_fit_in_bits_uint(Uint);
int erts_list_length(Eterm);
int erts_is_builtin(Eterm, Eterm, int);
Uint32 make_broken_hash(Eterm);
Uint32 block_hash(byte *, unsigned, Uint32);
Uint32 make_hash2(Eterm);
Uint32 make_hash(Eterm);
+Uint32 make_internal_hash(Eterm);
void erts_save_emu_args(int argc, char **argv);
Eterm erts_get_emu_args(struct process *c_p);
@@ -165,24 +168,26 @@ int eq(Eterm, Eterm);
#define EQ(x,y) (((x) == (y)) || (is_not_both_immed((x),(y)) && eq((x),(y))))
#if HALFWORD_HEAP
-Sint erts_cmp_rel_opt(Eterm, Eterm*, Eterm, Eterm*, int);
-#define cmp_rel(A,A_BASE,B,B_BASE) erts_cmp_rel_opt(A,A_BASE,B,B_BASE,0)
-#define cmp_rel_term(A,A_BASE,B,B_BASE) erts_cmp_rel_opt(A,A_BASE,B,B_BASE,1)
-#define CMP(A,B) erts_cmp_rel_opt(A,NULL,B,NULL,0)
-#define CMP_TERM(A,B) erts_cmp_rel_opt(A,NULL,B,NULL,1)
+Sint erts_cmp_rel_opt(Eterm, Eterm*, Eterm, Eterm*, int, int);
+#define cmp_rel(A,A_BASE,B,B_BASE) erts_cmp_rel_opt(A,A_BASE,B,B_BASE,0,0)
+#define cmp_rel_term(A,A_BASE,B,B_BASE) erts_cmp_rel_opt(A,A_BASE,B,B_BASE,1,0)
+#define CMP(A,B) erts_cmp_rel_opt(A,NULL,B,NULL,0,0)
+#define CMP_TERM(A,B) erts_cmp_rel_opt(A,NULL,B,NULL,1,0)
+#define CMP_EQ_ONLY(A,B) erts_cmp_rel_opt(A,NULL,B,NULL,0,1)
#else
-Sint cmp(Eterm, Eterm);
-Sint erts_cmp(Eterm, Eterm, int);
-#define cmp_rel(A,A_BASE,B,B_BASE) erts_cmp(A,B,0)
-#define cmp_rel_term(A,A_BASE,B,B_BASE) erts_cmp(A,B,1)
-#define CMP(A,B) erts_cmp(A,B,0)
-#define CMP_TERM(A,B) erts_cmp(A,B,1)
+Sint erts_cmp(Eterm, Eterm, int, int);
+Sint cmp(Eterm a, Eterm b);
+#define cmp_rel(A,A_BASE,B,B_BASE) erts_cmp(A,B,0,0)
+#define cmp_rel_term(A,A_BASE,B,B_BASE) erts_cmp(A,B,1,0)
+#define CMP(A,B) erts_cmp(A,B,0,0)
+#define CMP_TERM(A,B) erts_cmp(A,B,1,0)
+#define CMP_EQ_ONLY(A,B) erts_cmp(A,B,0,1)
#endif
#define cmp_lt(a,b) (CMP((a),(b)) < 0)
#define cmp_le(a,b) (CMP((a),(b)) <= 0)
-#define cmp_eq(a,b) (CMP((a),(b)) == 0)
-#define cmp_ne(a,b) (CMP((a),(b)) != 0)
+#define cmp_eq(a,b) (CMP_EQ_ONLY((a),(b)) == 0)
+#define cmp_ne(a,b) (CMP_EQ_ONLY((a),(b)) != 0)
#define cmp_ge(a,b) (CMP((a),(b)) >= 0)
#define cmp_gt(a,b) (CMP((a),(b)) > 0)
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 6687b044ee..8948ca2ea9 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,8 +21,6 @@
#ifndef __ERL_VM_H__
#define __ERL_VM_H__
-/* #define ERTS_OPCODE_COUNTER_SUPPORT */
-
/* FORCE_HEAP_FRAGS:
* Debug provocation to make HAlloc always create heap fragments (if allowed)
* even if there is room on heap.
@@ -119,9 +118,9 @@
#if defined(DEBUG) || defined(CHECK_FOR_HOLES)
#if HALFWORD_HEAP
-# define ERTS_HOLE_MARKER (0xaf5e78ccU)
+# define ERTS_HOLE_MARKER (0xdeadbeef)
#else
-# define ERTS_HOLE_MARKER (((0xaf5e78ccUL << 24) << 8) | 0xaf5e78ccUL)
+# define ERTS_HOLE_MARKER (((0xdeadbeef << 24) << 8) | 0xdeadbeef)
#endif
#endif
diff --git a/erts/emulator/beam/erl_zlib.c b/erts/emulator/beam/erl_zlib.c
index 8e33144f96..e44e86c39c 100644
--- a/erts/emulator/beam/erl_zlib.c
+++ b/erts/emulator/beam/erl_zlib.c
@@ -3,16 +3,17 @@
*
* 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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erl_zlib.h b/erts/emulator/beam/erl_zlib.h
index 160166c66b..2ca1e3735e 100644
--- a/erts/emulator/beam/erl_zlib.h
+++ b/erts/emulator/beam/erl_zlib.h
@@ -3,16 +3,17 @@
*
* 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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/erlang_dtrace.d b/erts/emulator/beam/erlang_dtrace.d
index e3ebbb84f4..c682f76e3a 100644
--- a/erts/emulator/beam/erlang_dtrace.d
+++ b/erts/emulator/beam/erlang_dtrace.d
@@ -4,16 +4,17 @@
* Copyright Dustin Sallings, Michal Ptaszek, Scott Lystig Fritchie 2011-2012.
* All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/error.h b/erts/emulator/beam/error.h
index ddc2c1396d..cba8672c68 100644
--- a/erts/emulator/beam/error.h
+++ b/erts/emulator/beam/error.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -140,7 +141,13 @@
#define EXC_NOTSUP ((17 << 8) | EXC_ERROR)
/* Not supported */
-#define NUMBER_EXIT_CODES 18 /* The number of exit code indices */
+#define EXC_BADMAP ((18 << 8) | EXC_ERROR)
+ /* Bad map */
+
+#define EXC_BADKEY ((19 << 8) | EXC_ERROR)
+ /* Bad key in map */
+
+#define NUMBER_EXIT_CODES 20 /* The number of exit code indices */
/*
* Internal pseudo-error codes.
@@ -152,6 +159,8 @@
*/
#define BADARG EXC_BADARG
#define BADARITH EXC_BADARITH
+#define BADKEY EXC_BADKEY
+#define BADMAP EXC_BADMAP
#define BADMATCH EXC_BADMATCH
#define SYSTEM_LIMIT EXC_SYSTEM_LIMIT
diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c
index b0f08d8245..2420df36b5 100644
--- a/erts/emulator/beam/export.c
+++ b/erts/emulator/beam/export.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h
index 61a54de59f..a8bc9d2f66 100644
--- a/erts/emulator/beam/export.h
+++ b/erts/emulator/beam/export.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 45d1f7514e..ffe3303796 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -36,7 +37,9 @@
#include "erl_process.h"
#include "error.h"
#include "external.h"
+#define ERL_WANT_HIPE_BIF_WRAPPER__
#include "bif.h"
+#undef ERL_WANT_HIPE_BIF_WRAPPER__
#include "big.h"
#include "dist.h"
#include "erl_binary.h"
@@ -92,9 +95,9 @@ static Uint is_external_string(Eterm obj, int* p_is_string);
static byte* enc_atom(ErtsAtomCacheMap *, Eterm, byte*, Uint32);
static byte* enc_pid(ErtsAtomCacheMap *, Eterm, byte*, Uint32);
struct B2TContext_t;
-static byte* dec_term(ErtsDistExternal *, Eterm**, byte*, ErlOffHeap*, Eterm*, struct B2TContext_t*);
+static byte* dec_term(ErtsDistExternal*, ErtsHeapFactory*, byte*, Eterm*, struct B2TContext_t*);
static byte* dec_atom(ErtsDistExternal *, byte*, Eterm*);
-static byte* dec_pid(ErtsDistExternal *, Eterm**, byte*, ErlOffHeap*, Eterm*);
+static byte* dec_pid(ErtsDistExternal *, ErtsHeapFactory*, byte*, Eterm*);
static Sint decoded_size(byte *ep, byte* endp, int internal_tags, struct B2TContext_t*);
static BIF_RETTYPE term_to_binary_trap_1(BIF_ALIST_1);
@@ -498,15 +501,37 @@ byte *erts_encode_ext_dist_header_finalize(byte *ext, ErtsAtomCache *cache, Uint
return ep;
}
-Uint erts_encode_dist_ext_size(Eterm term, Uint32 flags, ErtsAtomCacheMap *acmp)
+int erts_encode_dist_ext_size(Eterm term, Uint32 flags, ErtsAtomCacheMap *acmp,
+ Uint* szp)
{
- Uint sz = 0;
+ Uint sz;
+ if (encode_size_struct_int(NULL, acmp, term, flags, NULL, &sz)) {
+ return -1;
+ } else {
#ifndef ERTS_DEBUG_USE_DIST_SEP
- if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
+ if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
#endif
- sz++ /* VERSION_MAGIC */;
- sz += encode_size_struct2(acmp, term, flags);
- return sz;
+ sz++ /* VERSION_MAGIC */;
+
+ *szp += sz;
+ return 0;
+ }
+}
+
+int erts_encode_dist_ext_size_int(Eterm term, struct erts_dsig_send_context* ctx, Uint* szp)
+{
+ Uint sz;
+ if (encode_size_struct_int(&ctx->u.sc, ctx->acmp, term, ctx->flags, &ctx->reds, &sz)) {
+ return -1;
+ } else {
+#ifndef ERTS_DEBUG_USE_DIST_SEP
+ if (!(ctx->flags & DFLAG_DIST_HDR_ATOM_CACHE))
+#endif
+ sz++ /* VERSION_MAGIC */;
+
+ *szp += sz;
+ return 0;
+ }
}
Uint erts_encode_ext_size(Eterm term)
@@ -527,19 +552,16 @@ Uint erts_encode_ext_size_ets(Eterm term)
}
-void erts_encode_dist_ext(Eterm term, byte **ext, Uint32 flags, ErtsAtomCacheMap *acmp)
+int erts_encode_dist_ext(Eterm term, byte **ext, Uint32 flags, ErtsAtomCacheMap *acmp,
+ TTBEncodeContext* ctx, Sint* reds)
{
- byte *ep = *ext;
-#ifndef ERTS_DEBUG_USE_DIST_SEP
- if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
-#endif
- *ep++ = VERSION_MAGIC;
- ep = enc_term(acmp, term, ep, flags, NULL);
- if (!ep)
- erl_exit(ERTS_ABORT_EXIT,
- "%s:%d:erts_encode_dist_ext(): Internal data structure error\n",
- __FILE__, __LINE__);
- *ext = ep;
+ if (!ctx || !ctx->wstack.wstart) {
+ #ifndef ERTS_DEBUG_USE_DIST_SEP
+ if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
+ #endif
+ *(*ext)++ = VERSION_MAGIC;
+ }
+ return enc_term_int(ctx, acmp, term, *ext, flags, NULL, reds, ext);
}
void erts_encode_ext(Eterm term, byte **ext)
@@ -548,7 +570,7 @@ void erts_encode_ext(Eterm term, byte **ext)
*ep++ = VERSION_MAGIC;
ep = enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS, NULL);
if (!ep)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d:erts_encode_ext(): Internal data structure error\n",
__FILE__, __LINE__);
*ext = ep;
@@ -909,8 +931,7 @@ Sint erts_decode_ext_size_ets(byte *ext, Uint size)
** on return hpp is updated to point after allocated data
*/
Eterm
-erts_decode_dist_ext(Eterm** hpp,
- ErlOffHeap* off_heap,
+erts_decode_dist_ext(ErtsHeapFactory* factory,
ErtsDistExternal *edep)
{
Eterm obj;
@@ -930,7 +951,7 @@ erts_decode_dist_ext(Eterm** hpp,
goto error;
ep++;
}
- ep = dec_term(edep, hpp, ep, off_heap, &obj, NULL);
+ ep = dec_term(edep, factory, ep, &obj, NULL);
if (!ep)
goto error;
@@ -939,19 +960,22 @@ erts_decode_dist_ext(Eterm** hpp,
return obj;
error:
+ erts_factory_undo(factory);
bad_dist_ext(edep);
return THE_NON_VALUE;
}
-Eterm erts_decode_ext(Eterm **hpp, ErlOffHeap *off_heap, byte **ext)
+Eterm erts_decode_ext(ErtsHeapFactory* factory, byte **ext)
{
Eterm obj;
byte *ep = *ext;
- if (*ep++ != VERSION_MAGIC)
+ if (*ep++ != VERSION_MAGIC) {
+ erts_factory_undo(factory);
return THE_NON_VALUE;
- ep = dec_term(NULL, hpp, ep, off_heap, &obj, NULL);
+ }
+ ep = dec_term(NULL, factory, ep, &obj, NULL);
if (!ep) {
#ifdef DEBUG
bin_write(ERTS_PRINT_STDERR,NULL,*ext,500);
@@ -962,10 +986,10 @@ Eterm erts_decode_ext(Eterm **hpp, ErlOffHeap *off_heap, byte **ext)
return obj;
}
-Eterm erts_decode_ext_ets(Eterm **hpp, ErlOffHeap *off_heap, byte *ext)
+Eterm erts_decode_ext_ets(ErtsHeapFactory* factory, byte *ext)
{
Eterm obj;
- ext = dec_term(NULL, hpp, ext, off_heap, &obj, NULL);
+ ext = dec_term(NULL, factory, ext, &obj, NULL);
ASSERT(ext);
return obj;
}
@@ -974,9 +998,8 @@ Eterm erts_decode_ext_ets(Eterm **hpp, ErlOffHeap *off_heap, byte *ext)
BIF_RETTYPE erts_debug_dist_ext_to_term_2(BIF_ALIST_2)
{
+ ErtsHeapFactory factory;
Eterm res;
- Eterm *hp;
- Eterm *hendp;
Sint hsz;
ErtsDistExternal ede;
Eterm *tp;
@@ -1023,12 +1046,9 @@ BIF_RETTYPE erts_debug_dist_ext_to_term_2(BIF_ALIST_2)
if (hsz < 0)
goto badarg;
- hp = HAlloc(BIF_P, (Uint) hsz);
- hendp = hp + hsz;
-
- res = erts_decode_dist_ext(&hp, &MSO(BIF_P), &ede);
-
- HRelease(BIF_P, hendp, hp);
+ erts_factory_proc_prealloc_init(&factory, BIF_P, hsz);
+ res = erts_decode_dist_ext(&factory, &ede);
+ erts_factory_close(&factory);
if (is_value(res))
BIF_RET(res);
@@ -1156,12 +1176,11 @@ typedef struct {
byte* ep;
Eterm res;
Eterm* next;
- Eterm* hp_start;
- Eterm* hp;
- Eterm* hp_end;
+ ErtsHeapFactory factory;
int remaining_n;
char* remaining_bytes;
- Eterm* maps_head;
+ ErtsWStack flat_maps;
+ ErtsPStack hamt_array;
} B2TDecodeContext;
typedef struct {
@@ -1285,10 +1304,12 @@ binary2term_abort(ErtsBinary2TermState *state)
}
static ERTS_INLINE Eterm
-binary2term_create(ErtsDistExternal *edep, ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
+binary2term_create(ErtsDistExternal *edep, ErtsBinary2TermState *state,
+ ErtsHeapFactory* factory)
{
Eterm res;
- if (!dec_term(edep, hpp, state->extp, ohp, &res, NULL))
+
+ if (!dec_term(edep, factory, state->extp, &res, NULL))
res = THE_NON_VALUE;
if (state->exttmp) {
state->exttmp = 0;
@@ -1321,9 +1342,9 @@ erts_binary2term_abort(ErtsBinary2TermState *state)
}
Eterm
-erts_binary2term_create(ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
+erts_binary2term_create(ErtsBinary2TermState *state, ErtsHeapFactory* factory)
{
- return binary2term_create(NULL,state, hpp, ohp);
+ return binary2term_create(NULL,state, factory);
}
static void b2t_destroy_context(B2TContext* context)
@@ -1332,8 +1353,21 @@ static void b2t_destroy_context(B2TContext* context)
ERTS_ALC_T_EXT_TERM_DATA);
context->aligned_alloc = NULL;
binary2term_abort(&context->b2ts);
- if (context->state == B2TUncompressChunk) {
+ switch (context->state) {
+ case B2TUncompressChunk:
erl_zlib_inflate_finish(&context->u.uc.stream);
+ break;
+ case B2TDecode:
+ case B2TDecodeList:
+ case B2TDecodeTuple:
+ case B2TDecodeString:
+ case B2TDecodeBinary:
+ if (context->u.dc.hamt_array.pstart) {
+ erts_free(context->u.dc.hamt_array.alloc_type,
+ context->u.dc.hamt_array.pstart);
+ }
+ break;
+ default:;
}
}
@@ -1484,10 +1518,9 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binar
ctx->u.dc.ep = ctx->b2ts.extp;
ctx->u.dc.res = (Eterm) (UWord) NULL;
ctx->u.dc.next = &ctx->u.dc.res;
- ctx->u.dc.hp_start = HAlloc(p, ctx->heap_size);
- ctx->u.dc.hp = ctx->u.dc.hp_start;
- ctx->u.dc.hp_end = ctx->u.dc.hp_start + ctx->heap_size;
- ctx->u.dc.maps_head = NULL;
+ erts_factory_proc_prealloc_init(&ctx->u.dc.factory, p, ctx->heap_size);
+ ctx->u.dc.flat_maps.wstart = NULL;
+ ctx->u.dc.hamt_array.pstart = NULL;
ctx->state = B2TDecode;
/*fall through*/
case B2TDecode:
@@ -1497,11 +1530,10 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binar
case B2TDecodeBinary: {
ErtsDistExternal fakedep;
fakedep.flags = ctx->flags;
- dec_term(&fakedep, NULL, NULL, &MSO(p), NULL, ctx);
+ dec_term(&fakedep, NULL, NULL, NULL, ctx);
break;
}
case B2TDecodeFail:
- HRelease(p, ctx->u.dc.hp_end, ctx->u.dc.hp_start);
/*fall through*/
case B2TBadArg:
BUMP_REDS(p, (initial_reds - ctx->reds) / B2T_BYTES_PER_REDUCTION);
@@ -1526,11 +1558,11 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binar
case B2TDone:
b2t_destroy_context(ctx);
- if (ctx->u.dc.hp > ctx->u.dc.hp_end) {
- erl_exit(1, ":%s, line %d: heap overrun by %d words(s)\n",
- __FILE__, __LINE__, ctx->u.dc.hp - ctx->u.dc.hp_end);
+ if (ctx->u.dc.factory.hp > ctx->u.dc.factory.hp_end) {
+ erts_exit(ERTS_ERROR_EXIT, ":%s, line %d: heap overrun by %d words(s)\n",
+ __FILE__, __LINE__, ctx->u.dc.factory.hp - ctx->u.dc.factory.hp_end);
}
- HRelease(p, ctx->u.dc.hp_end, ctx->u.dc.hp);
+ erts_factory_close(&ctx->u.dc.factory);
if (!is_first_call) {
erts_set_gc_state(p, 1);
@@ -1676,12 +1708,12 @@ erts_term_to_binary_simple(Process* p, Eterm Term, Uint size, int level, Uint fl
if ((endp = enc_term(NULL, Term, bytes, flags, NULL))
== NULL) {
- erl_exit(1, "%s, line %d: bad term: %x\n",
+ erts_exit(ERTS_ERROR_EXIT, "%s, line %d: bad term: %x\n",
__FILE__, __LINE__, Term);
}
real_size = endp - bytes;
if (real_size > size) {
- erl_exit(1, "%s, line %d: buffer overflow: %d word(s)\n",
+ erts_exit(ERTS_ERROR_EXIT, "%s, line %d: buffer overflow: %d word(s)\n",
__FILE__, __LINE__, real_size - size);
}
@@ -1721,12 +1753,12 @@ erts_term_to_binary_simple(Process* p, Eterm Term, Uint size, int level, Uint fl
bytes[0] = VERSION_MAGIC;
if ((endp = enc_term(NULL, Term, bytes+1, flags, NULL))
== NULL) {
- erl_exit(1, "%s, line %d: bad term: %x\n",
+ erts_exit(ERTS_ERROR_EXIT, "%s, line %d: bad term: %x\n",
__FILE__, __LINE__, Term);
}
real_size = endp - bytes;
if (real_size > size) {
- erl_exit(1, "%s, line %d: buffer overflow: %d word(s)\n",
+ erts_exit(ERTS_ERROR_EXIT, "%s, line %d: buffer overflow: %d word(s)\n",
__FILE__, __LINE__, endp - (bytes + size));
}
return erts_realloc_binary(bin, real_size);
@@ -1740,54 +1772,14 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) {
return erts_term_to_binary_simple(p, Term, size, level, flags);
}
-/* Define for testing */
-/* #define EXTREME_TTB_TRAPPING 1 */
+/* Define EXTREME_TTB_TRAPPING for testing in dist.h */
#ifndef EXTREME_TTB_TRAPPING
-#define TERM_TO_BINARY_LOOP_FACTOR 32
#define TERM_TO_BINARY_COMPRESS_CHUNK (1 << 18)
#else
-#define TERM_TO_BINARY_LOOP_FACTOR 1
#define TERM_TO_BINARY_COMPRESS_CHUNK 10
#endif
-
-
-typedef enum { TTBSize, TTBEncode, TTBCompress } TTBState;
-typedef struct TTBSizeContext_ {
- Uint flags;
- int level;
- Uint result;
- Eterm obj;
- ErtsEStack estack;
-} TTBSizeContext;
-
-typedef struct TTBEncodeContext_ {
- Uint flags;
- int level;
- byte* ep;
- Eterm obj;
- ErtsWStack wstack;
- Binary *result_bin;
-} TTBEncodeContext;
-
-typedef struct {
- Uint real_size;
- Uint dest_len;
- byte *dbytes;
- Binary *result_bin;
- Binary *destination_bin;
- z_stream stream;
-} TTBCompressContext;
-
-typedef struct {
- int alive;
- TTBState state;
- union {
- TTBSizeContext sc;
- TTBEncodeContext ec;
- TTBCompressContext cc;
- } s;
-} TTBContext;
+#define TERM_TO_BINARY_MEMCPY_FACTOR 8
static void ttb_context_destructor(Binary *context_bin)
{
@@ -1796,7 +1788,7 @@ static void ttb_context_destructor(Binary *context_bin)
context->alive = 0;
switch (context->state) {
case TTBSize:
- DESTROY_SAVED_ESTACK(&context->s.sc.estack);
+ DESTROY_SAVED_WSTACK(&context->s.sc.wstack);
break;
case TTBEncode:
DESTROY_SAVED_WSTACK(&context->s.ec.wstack);
@@ -1864,7 +1856,7 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla
/* Setup enough to get started */
context->state = TTBSize;
context->alive = 1;
- context->s.sc.estack.start = NULL;
+ context->s.sc.wstack.wstart = NULL;
context->s.sc.flags = flags;
context->s.sc.level = level;
} else {
@@ -1899,8 +1891,6 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla
}
result_bin = erts_bin_nrml_alloc(size);
- result_bin->flags = 0;
- result_bin->orig_size = size;
erts_refc_init(&result_bin->refc, 0);
result_bin->orig_bytes[0] = VERSION_MAGIC;
/* Next state immediately, no need to export context */
@@ -1925,7 +1915,6 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla
}
real_size = endp - bytes;
result_bin = erts_bin_realloc(context->s.ec.result_bin,real_size);
- result_bin->orig_size = real_size;
level = context->s.ec.level;
BUMP_REDS(p, (initial_reds - reds) / TERM_TO_BINARY_LOOP_FACTOR);
if (level == 0 || real_size < 6) { /* We are done */
@@ -1962,8 +1951,6 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla
context->s.cc.result_bin = result_bin;
result_bin = erts_bin_nrml_alloc(real_size);
- result_bin->flags = 0;
- result_bin->orig_size = real_size;
erts_refc_init(&result_bin->refc, 0);
result_bin->orig_bytes[0] = VERSION_MAGIC;
@@ -2005,7 +1992,6 @@ static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint fla
erl_zlib_deflate_finish(&(context->s.cc.stream));
result_bin = erts_bin_realloc(context->s.cc.destination_bin,
context->s.cc.dest_len+6);
- result_bin->orig_size = context->s.cc.dest_len+6;
context->s.cc.destination_bin = NULL;
pb = (ProcBin *) HAlloc(p, PROC_BIN_SIZE);
pb->thing_word = HEADER_PROC_BIN;
@@ -2270,7 +2256,7 @@ static ERTS_INLINE ErlNode* dec_get_node(Eterm sysname, Uint creation)
}
static byte*
-dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Eterm* objp)
+dec_pid(ErtsDistExternal *edep, ErtsHeapFactory* factory, byte* ep, Eterm* objp)
{
Eterm sysname;
Uint data;
@@ -2309,15 +2295,15 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete
if(node == erts_this_node) {
*objp = make_internal_pid(data);
} else {
- ExternalThing *etp = (ExternalThing *) *hpp;
- *hpp += EXTERNAL_THING_HEAD_SIZE + 1;
+ ExternalThing *etp = (ExternalThing *) factory->hp;
+ factory->hp += EXTERNAL_THING_HEAD_SIZE + 1;
etp->header = make_external_pid_header(1);
- etp->next = off_heap->first;
+ etp->next = factory->off_heap->first;
etp->node = node;
etp->data.ui[0] = data;
- off_heap->first = (struct erl_off_heap_header*) etp;
+ factory->off_heap->first = (struct erl_off_heap_header*) etp;
*objp = make_external_pid(etp);
}
return ep;
@@ -2327,8 +2313,10 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete
#define ENC_TERM ((Eterm) 0)
#define ENC_ONE_CONS ((Eterm) 1)
#define ENC_PATCH_FUN_SIZE ((Eterm) 2)
-#define ENC_LAST_ARRAY_ELEMENT ((Eterm) 3)
-
+#define ENC_BIN_COPY ((Eterm) 3)
+#define ENC_MAP_PAIR ((Eterm) 4)
+#define ENC_HASHMAP_NODE ((Eterm) 5)
+#define ENC_LAST_ARRAY_ELEMENT ((Eterm) 6)
static byte*
enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags,
@@ -2364,6 +2352,9 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
WSTACK_RESTORE(s, &ctx->wstack);
ep = ctx->ep;
obj = ctx->obj;
+ if (is_non_value(obj)) {
+ goto outer_loop;
+ }
}
}
@@ -2387,8 +2378,8 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
obj = CAR(cons);
tl = CDR(cons);
- WSTACK_PUSH(s, is_list(tl) ? ENC_ONE_CONS : ENC_TERM);
- WSTACK_PUSH(s, tl);
+ WSTACK_PUSH2(s, (is_list(tl) ? ENC_ONE_CONS : ENC_TERM),
+ tl);
}
break;
case ENC_PATCH_FUN_SIZE:
@@ -2401,6 +2392,46 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
put_int32(ep - size_p, size_p);
}
goto outer_loop;
+ case ENC_BIN_COPY: {
+ Uint bits = (Uint)obj;
+ Uint bitoffs = WSTACK_POP(s);
+ byte* bytes = (byte*) WSTACK_POP(s);
+ byte* dst = (byte*) WSTACK_POP(s);
+ if (bits > r * (TERM_TO_BINARY_MEMCPY_FACTOR * 8)) {
+ Uint n = r * TERM_TO_BINARY_MEMCPY_FACTOR;
+ WSTACK_PUSH5(s, (UWord)(dst + n), (UWord)(bytes + n), bitoffs,
+ ENC_BIN_COPY, bits - 8*n);
+ bits = 8*n;
+ copy_binary_to_buffer(dst, 0, bytes, bitoffs, bits);
+ obj = THE_NON_VALUE;
+ r = 0; /* yield */
+ break;
+ } else {
+ copy_binary_to_buffer(dst, 0, bytes, bitoffs, bits);
+ r -= bits / (TERM_TO_BINARY_MEMCPY_FACTOR * 8);
+ goto outer_loop;
+ }
+ }
+ case ENC_MAP_PAIR: {
+ Uint pairs_left = obj;
+ Eterm *vptr = (Eterm*) WSTACK_POP(s);
+ Eterm *kptr = (Eterm*) WSTACK_POP(s);
+
+ obj = *kptr;
+ if (--pairs_left > 0) {
+ WSTACK_PUSH4(s, (UWord)(kptr+1), (UWord)(vptr+1),
+ ENC_MAP_PAIR, pairs_left);
+ }
+ WSTACK_PUSH2(s, ENC_TERM, *vptr);
+ break;
+ }
+ case ENC_HASHMAP_NODE:
+ if (is_list(obj)) { /* leaf node [K|V] */
+ ptr = list_val(obj);
+ WSTACK_PUSH2(s, ENC_TERM, CDR(ptr));
+ obj = CAR(ptr);
+ }
+ break;
case ENC_LAST_ARRAY_ELEMENT:
/* obj is the tuple */
{
@@ -2419,17 +2450,16 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
#else
Eterm* ptr = (Eterm *) obj;
#endif
- WSTACK_PUSH(s, val-1);
obj = *ptr++;
- WSTACK_PUSH(s, (UWord)ptr);
+ WSTACK_PUSH2(s, val-1, (UWord)ptr);
}
break;
}
L_jump_start:
- if (ctx && --r == 0) {
- *reds = r;
+ if (ctx && --r <= 0) {
+ *reds = 0;
ctx->obj = obj;
ctx->ep = ep;
WSTACK_SAVE(s, &ctx->wstack);
@@ -2578,39 +2608,59 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
ep += 4;
}
if (i > 0) {
- WSTACK_PUSH(s, ENC_LAST_ARRAY_ELEMENT+i-1);
- WSTACK_PUSH(s, (UWord)ptr);
+ WSTACK_PUSH2(s, ENC_LAST_ARRAY_ELEMENT+i-1, (UWord)ptr);
}
break;
case MAP_DEF:
- {
- map_t *mp = (map_t*)map_val(obj);
- Uint size = map_get_size(mp);
+ if (is_flatmap(obj)) {
+ flatmap_t *mp = (flatmap_t*)flatmap_val(obj);
+ Uint size = flatmap_get_size(mp);
*ep++ = MAP_EXT;
put_int32(size, ep); ep += 4;
if (size > 0) {
- Eterm *kptr = map_get_keys(mp);
- Eterm *vptr = map_get_values(mp);
-
- for (i = size-1; i >= 1; i--) {
- WSTACK_PUSH(s, ENC_TERM);
- WSTACK_PUSH(s, (UWord) vptr[i]);
- WSTACK_PUSH(s, ENC_TERM);
- WSTACK_PUSH(s, (UWord) kptr[i]);
- }
+ Eterm *kptr = flatmap_get_keys(mp);
+ Eterm *vptr = flatmap_get_values(mp);
- WSTACK_PUSH(s, ENC_TERM);
- WSTACK_PUSH(s, (UWord) vptr[0]);
+ WSTACK_PUSH4(s, (UWord)kptr, (UWord)vptr,
+ ENC_MAP_PAIR, size);
+ }
+ } else {
+ Eterm hdr;
+ Uint node_sz;
+ ptr = boxed_val(obj);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ *ep++ = MAP_EXT;
+ ptr++;
+ put_int32(*ptr, ep); ep += 4;
+ node_sz = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ *ep++ = MAP_EXT;
+ ptr++;
+ put_int32(*ptr, ep); ep += 4;
+ /*fall through*/
+ case HAMT_SUBTAG_NODE_BITMAP:
+ node_sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(node_sz < 17);
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
+ }
- obj = kptr[0];
- goto L_jump_start;
+ ptr++;
+ WSTACK_RESERVE(s, node_sz*2);
+ while(node_sz--) {
+ WSTACK_FAST_PUSH(s, ENC_HASHMAP_NODE);
+ WSTACK_FAST_PUSH(s, *ptr++);
}
}
break;
-
case FLOAT_DEF:
GET_DOUBLE(obj, f);
if (dflags & DFLAG_NEW_FLOATS) {
@@ -2644,6 +2694,7 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
Uint bitoffs;
Uint bitsize;
byte* bytes;
+ byte* data_dst;
ERTS_GET_BINARY_BYTES(obj, bytes, bitoffs, bitsize);
if (dflags & DFLAG_INTERNAL_TAGS) {
@@ -2689,7 +2740,7 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
j = binary_size(obj);
put_int32(j, ep);
ep += 4;
- copy_binary_to_buffer(ep, 0, bytes, bitoffs, 8*j);
+ data_dst = ep;
ep += j;
} else if (dflags & DFLAG_BIT_BINARIES) {
/* Bit-level binary. */
@@ -2699,7 +2750,7 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
ep += 4;
*ep++ = bitsize;
ep[j] = 0; /* Zero unused bits at end of binary */
- copy_binary_to_buffer(ep, 0, bytes, bitoffs, 8*j+bitsize);
+ data_dst = ep;
ep += j + 1;
} else {
/*
@@ -2713,11 +2764,18 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
put_int32((j+1), ep);
ep += 4;
ep[j] = 0; /* Zero unused bits at end of binary */
- copy_binary_to_buffer(ep, 0, bytes, bitoffs, 8*j+bitsize);
+ data_dst = ep;
ep += j+1;
*ep++ = SMALL_INTEGER_EXT;
*ep++ = bitsize;
}
+ if (ctx && j > r * TERM_TO_BINARY_MEMCPY_FACTOR) {
+ WSTACK_PUSH5(s, (UWord)data_dst, (UWord)bytes, bitoffs,
+ ENC_BIN_COPY, 8*j + bitsize);
+ } else {
+ copy_binary_to_buffer(data_dst, 0, bytes, bitoffs,
+ 8 * j + bitsize);
+ }
}
break;
case EXPORT_DEF:
@@ -2746,13 +2804,12 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
case FUN_DEF:
{
ErlFunThing* funp = (ErlFunThing *) fun_val(obj);
+ int ei;
if ((dflags & DFLAG_NEW_FUN_TAGS) != 0) {
- int ei;
-
*ep++ = NEW_FUN_EXT;
- WSTACK_PUSH(s, ENC_PATCH_FUN_SIZE);
- WSTACK_PUSH(s, (UWord) ep); /* Position for patching in size */
+ WSTACK_PUSH2(s, ENC_PATCH_FUN_SIZE,
+ (UWord) ep); /* Position for patching in size */
ep += 4;
*ep = funp->arity;
ep += 1;
@@ -2766,16 +2823,6 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
ep = enc_term(acmp, make_small(funp->fe->old_index), ep, dflags, off_heap);
ep = enc_term(acmp, make_small(funp->fe->old_uniq), ep, dflags, off_heap);
ep = enc_pid(acmp, funp->creator, ep, dflags);
-
- fun_env:
- for (ei = funp->num_free-1; ei > 0; ei--) {
- WSTACK_PUSH(s, ENC_TERM);
- WSTACK_PUSH(s, (UWord) funp->env[ei]);
- }
- if (funp->num_free != 0) {
- obj = funp->env[0];
- goto L_jump_start;
- }
} else {
/*
* Communicating with an obsolete erl_interface or
@@ -2807,7 +2854,13 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
*ep++ = SMALL_TUPLE_EXT;
put_int8(funp->num_free, ep);
ep += 1;
- goto fun_env;
+ }
+ for (ei = funp->num_free-1; ei > 0; ei--) {
+ WSTACK_PUSH2(s, ENC_TERM, (UWord) funp->env[ei]);
+ }
+ if (funp->num_free != 0) {
+ obj = funp->env[0];
+ goto L_jump_start;
}
}
break;
@@ -2861,57 +2914,42 @@ is_external_string(Eterm list, int* p_is_string)
return len;
}
-/* Assumes that the ones to undo are preluding the list. */
-static void
-undo_offheap_in_area(ErlOffHeap* off_heap, Eterm* start, Eterm* end)
-{
- const Uint area_sz = (end - start) * sizeof(Eterm);
- struct erl_off_heap_header* hdr;
- struct erl_off_heap_header** hdr_nextp = NULL;
-
- for (hdr = off_heap->first; ; hdr=hdr->next) {
- if (!in_area(hdr, start, area_sz)) {
- if (hdr_nextp != NULL) {
- *hdr_nextp = NULL;
- erts_cleanup_offheap(off_heap);
- off_heap->first = hdr;
- }
- break;
- }
- hdr_nextp = &hdr->next;
- }
- /* Assert that the ones to undo were indeed preluding the list. */
-#ifdef DEBUG
- for (hdr = off_heap->first; hdr != NULL; hdr = hdr->next) {
- ASSERT(!in_area(hdr, start, area_sz));
- }
-#endif /* DEBUG */
-}
+struct dec_term_hamt
+{
+ Eterm* objp; /* write result here */
+ Uint size; /* nr of leafs */
+ Eterm* leaf_array;
+};
/* Decode term from external format into *objp.
-** On failure return NULL and (R13B04) *hpp will be unchanged.
+** On failure calls erts_factory_undo() and returns NULL
*/
static byte*
-dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap,
- Eterm* objp, B2TContext* ctx)
+dec_term(ErtsDistExternal *edep,
+ ErtsHeapFactory* factory,
+ byte* ep,
+ Eterm* objp,
+ B2TContext* ctx)
{
- Eterm* hp_saved;
+#define PSTACK_TYPE struct dec_term_hamt
+ PSTACK_DECLARE(hamt_array, 5);
int n;
ErtsAtomEncoding char_enc;
register Eterm* hp; /* Please don't take the address of hp */
- Eterm *maps_head; /* for validation of maps */
+ DECLARE_WSTACK(flat_maps); /* for preprocessing of small maps */
Eterm* next;
SWord reds;
+#ifdef DEBUG
+ Eterm* dbg_resultp = ctx ? &ctx->u.dc.res : objp;
+#endif
if (ctx) {
- hp_saved = ctx->u.dc.hp_start;
reds = ctx->reds;
next = ctx->u.dc.next;
ep = ctx->u.dc.ep;
- hpp = &ctx->u.dc.hp;
- maps_head = ctx->u.dc.maps_head;
+ factory = &ctx->u.dc.factory;
if (ctx->state != B2TDecode) {
int n_limit = reds;
@@ -2956,7 +2994,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap,
break;
case B2TDecodeString:
- hp = *hpp;
+ hp = factory->hp;
hp[-1] = make_list(hp); /* overwrite the premature NIL */
while (n-- > 0) {
hp[0] = make_small(*ep++);
@@ -2964,7 +3002,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap,
hp += 2;
}
hp[-1] = NIL;
- *hpp = hp;
+ factory->hp = hp;
break;
case B2TDecodeBinary:
@@ -2986,15 +3024,21 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap,
return NULL;
}
}
+ PSTACK_CHANGE_ALLOCATOR(hamt_array, ERTS_ALC_T_SAVED_ESTACK);
+ WSTACK_CHANGE_ALLOCATOR(flat_maps, ERTS_ALC_T_SAVED_ESTACK);
+ if (ctx->u.dc.hamt_array.pstart) {
+ PSTACK_RESTORE(hamt_array, &ctx->u.dc.hamt_array);
+ }
+ if (ctx->u.dc.flat_maps.wstart) {
+ WSTACK_RESTORE(flat_maps, &ctx->u.dc.flat_maps);
+ }
}
else {
- hp_saved = *hpp;
reds = ERTS_SWORD_MAX;
next = objp;
*next = (Eterm) (UWord) NULL;
- maps_head = NULL;
}
- hp = *hpp;
+ hp = factory->hp;
while (next != NULL) {
@@ -3231,9 +3275,9 @@ dec_term_atom_common:
break;
}
case PID_EXT:
- *hpp = hp;
- ep = dec_pid(edep, hpp, ep, off_heap, objp);
- hp = *hpp;
+ factory->hp = hp;
+ ep = dec_pid(edep, factory, ep, objp);
+ hp = factory->hp;
if (ep == NULL) {
goto error;
}
@@ -3267,11 +3311,11 @@ dec_term_atom_common:
hp += EXTERNAL_THING_HEAD_SIZE + 1;
etp->header = make_external_port_header(1);
- etp->next = off_heap->first;
+ etp->next = factory->off_heap->first;
etp->node = node;
etp->data.ui[0] = num;
- off_heap->first = (struct erl_off_heap_header*)etp;
+ factory->off_heap->first = (struct erl_off_heap_header*)etp;
*objp = make_external_port(etp);
}
@@ -3351,10 +3395,10 @@ dec_term_atom_common:
#else
etp->header = make_external_ref_header(ref_words);
#endif
- etp->next = off_heap->first;
+ etp->next = factory->off_heap->first;
etp->node = node;
- off_heap->first = (struct erl_off_heap_header*)etp;
+ factory->off_heap->first = (struct erl_off_heap_header*)etp;
*objp = make_external_ref(etp);
ref_num = &(etp->data.ui32[0]);
}
@@ -3389,15 +3433,14 @@ dec_term_atom_common:
} else {
Binary* dbin = erts_bin_nrml_alloc(n);
ProcBin* pb;
- dbin->flags = 0;
- dbin->orig_size = n;
erts_refc_init(&dbin->refc, 1);
pb = (ProcBin *) hp;
hp += PROC_BIN_SIZE;
pb->thing_word = HEADER_PROC_BIN;
pb->size = n;
- pb->next = off_heap->first;
- off_heap->first = (struct erl_off_heap_header*)pb;
+ pb->next = factory->off_heap->first;
+ factory->off_heap->first = (struct erl_off_heap_header*)pb;
+ OH_OVERHEAD(factory->off_heap, pb->size / sizeof(Eterm));
pb->val = dbin;
pb->bytes = (byte*) dbin->orig_bytes;
pb->flags = 0;
@@ -3443,14 +3486,13 @@ dec_term_atom_common:
Binary* dbin = erts_bin_nrml_alloc(n);
ProcBin* pb;
- dbin->flags = 0;
- dbin->orig_size = n;
erts_refc_init(&dbin->refc, 1);
pb = (ProcBin *) hp;
pb->thing_word = HEADER_PROC_BIN;
pb->size = n;
- pb->next = off_heap->first;
- off_heap->first = (struct erl_off_heap_header*)pb;
+ pb->next = factory->off_heap->first;
+ factory->off_heap->first = (struct erl_off_heap_header*)pb;
+ OH_OVERHEAD(factory->off_heap, pb->size / sizeof(Eterm));
pb->val = dbin;
pb->bytes = (byte*) dbin->orig_bytes;
pb->flags = 0;
@@ -3502,9 +3544,9 @@ dec_term_atom_common:
if ((ep = dec_atom(edep, ep, &name)) == NULL) {
goto error;
}
- *hpp = hp;
- ep = dec_term(edep, hpp, ep, off_heap, &temp, NULL);
- hp = *hpp;
+ factory->hp = hp;
+ ep = dec_term(edep, factory, ep, &temp, NULL);
+ hp = factory->hp;
if (ep == NULL) {
goto error;
}
@@ -3532,46 +3574,57 @@ dec_term_atom_common:
break;
case MAP_EXT:
{
- map_t *mp;
Uint32 size,n;
Eterm *kptr,*vptr;
Eterm keys;
size = get_int32(ep); ep += 4;
- keys = make_tuple(hp);
- *hp++ = make_arityval(size);
- hp += size;
- kptr = hp - 1;
-
- mp = (map_t*)hp;
- hp += MAP_HEADER_SIZE;
- hp += size;
- vptr = hp - 1;
-
- /* kptr, last word for keys
- * vptr, last word for values
- */
-
- /*
- * Use thing_word to link through decoded maps.
- * The list of maps is for later validation.
- */
-
- mp->thing_word = (Eterm) COMPRESS_POINTER(maps_head);
- maps_head = (Eterm *) mp;
-
- mp->size = size;
- mp->keys = keys;
- *objp = make_map(mp);
-
- for (n = size; n; n--) {
- *vptr = (Eterm) COMPRESS_POINTER(next);
- *kptr = (Eterm) COMPRESS_POINTER(vptr);
- next = kptr;
- vptr--;
- kptr--;
- }
+ if (size <= MAP_SMALL_MAP_LIMIT) {
+ flatmap_t *mp;
+
+ keys = make_tuple(hp);
+ *hp++ = make_arityval(size);
+ hp += size;
+ kptr = hp - 1;
+
+ mp = (flatmap_t*)hp;
+ hp += MAP_HEADER_FLATMAP_SZ;
+ hp += size;
+ vptr = hp - 1;
+
+ /* kptr, last word for keys
+ * vptr, last word for values
+ */
+
+ WSTACK_PUSH(flat_maps, (UWord)mp);
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = size;
+ mp->keys = keys;
+ *objp = make_flatmap(mp);
+
+ for (n = size; n; n--) {
+ *vptr = (Eterm) COMPRESS_POINTER(next);
+ *kptr = (Eterm) COMPRESS_POINTER(vptr);
+ next = kptr;
+ vptr--;
+ kptr--;
+ }
+ }
+ else { /* Make hamt */
+ struct dec_term_hamt* hamt = PSTACK_PUSH(hamt_array);
+
+ hamt->objp = objp;
+ hamt->size = size;
+ hamt->leaf_array = hp;
+
+ for (n = size; n; n--) {
+ CDR(hp) = (Eterm) COMPRESS_POINTER(next);
+ CAR(hp) = (Eterm) COMPRESS_POINTER(&CDR(hp));
+ next = &CAR(hp);
+ hp += 2;
+ }
+ }
}
break;
case NEW_FUN_EXT:
@@ -3605,9 +3658,9 @@ dec_term_atom_common:
if ((ep = dec_atom(edep, ep, &module)) == NULL) {
goto error;
}
- *hpp = hp;
+ factory->hp = hp;
/* Index */
- if ((ep = dec_term(edep, hpp, ep, off_heap, &temp, NULL)) == NULL) {
+ if ((ep = dec_term(edep, factory, ep, &temp, NULL)) == NULL) {
goto error;
}
if (!is_small(temp)) {
@@ -3616,7 +3669,7 @@ dec_term_atom_common:
old_index = unsigned_val(temp);
/* Uniq */
- if ((ep = dec_term(edep, hpp, ep, off_heap, &temp, NULL)) == NULL) {
+ if ((ep = dec_term(edep, factory, ep, &temp, NULL)) == NULL) {
goto error;
}
if (!is_small(temp)) {
@@ -3628,8 +3681,8 @@ dec_term_atom_common:
* It is safe to link the fun into the fun list only when
* no more validity tests can fail.
*/
- funp->next = off_heap->first;
- off_heap->first = (struct erl_off_heap_header*)funp;
+ funp->next = factory->off_heap->first;
+ factory->off_heap->first = (struct erl_off_heap_header*)funp;
funp->fe = erts_put_fun_entry2(module, old_uniq, old_index,
uniq, index, arity);
@@ -3640,7 +3693,7 @@ dec_term_atom_common:
}
funp->native_address = funp->fe->native_address;
#endif
- hp = *hpp;
+ hp = factory->hp;
/* Environment */
for (i = num_free-1; i >= 0; i--) {
@@ -3666,14 +3719,14 @@ dec_term_atom_common:
ep += 4;
hp += ERL_FUN_SIZE;
hp += num_free;
- *hpp = hp;
+ factory->hp = hp;
funp->thing_word = HEADER_FUN;
funp->num_free = num_free;
*objp = make_fun(funp);
/* Creator pid */
if (*ep != PID_EXT
- || (ep = dec_pid(edep, hpp, ++ep, off_heap,
+ || (ep = dec_pid(edep, factory, ++ep,
&funp->creator))==NULL) {
goto error;
}
@@ -3684,7 +3737,7 @@ dec_term_atom_common:
}
/* Index */
- if ((ep = dec_term(edep, hpp, ep, off_heap, &temp, NULL)) == NULL) {
+ if ((ep = dec_term(edep, factory, ep, &temp, NULL)) == NULL) {
goto error;
}
if (!is_small(temp)) {
@@ -3693,7 +3746,7 @@ dec_term_atom_common:
old_index = unsigned_val(temp);
/* Uniq */
- if ((ep = dec_term(edep, hpp, ep, off_heap, &temp, NULL)) == NULL) {
+ if ((ep = dec_term(edep, factory, ep, &temp, NULL)) == NULL) {
goto error;
}
if (!is_small(temp)) {
@@ -3704,8 +3757,8 @@ dec_term_atom_common:
* It is safe to link the fun into the fun list only when
* no more validity tests can fail.
*/
- funp->next = off_heap->first;
- off_heap->first = (struct erl_off_heap_header*)funp;
+ funp->next = factory->off_heap->first;
+ factory->off_heap->first = (struct erl_off_heap_header*)funp;
old_uniq = unsigned_val(temp);
funp->fe = erts_put_fun_entry(module, old_uniq, old_index);
@@ -3713,7 +3766,7 @@ dec_term_atom_common:
#ifdef HIPE
funp->native_address = funp->fe->native_address;
#endif
- hp = *hpp;
+ hp = factory->hp;
/* Environment */
for (i = num_free-1; i >= 0; i--) {
@@ -3747,8 +3800,9 @@ dec_term_atom_common:
erts_refc_inc(&pb->val->refc, 1);
hp += PROC_BIN_SIZE;
- pb->next = off_heap->first;
- off_heap->first = (struct erl_off_heap_header*)pb;
+ pb->next = factory->off_heap->first;
+ factory->off_heap->first = (struct erl_off_heap_header*)pb;
+ OH_OVERHEAD(factory->off_heap, pb->size / sizeof(Eterm));
pb->flags = 0;
*objp = make_binary(pb);
break;
@@ -3764,8 +3818,9 @@ dec_term_atom_common:
erts_refc_inc(&pb->val->refc, 1);
hp += PROC_BIN_SIZE;
- pb->next = off_heap->first;
- off_heap->first = (struct erl_off_heap_header*)pb;
+ pb->next = factory->off_heap->first;
+ factory->off_heap->first = (struct erl_off_heap_header*)pb;
+ OH_OVERHEAD(factory->off_heap, pb->size / sizeof(Eterm));
pb->flags = 0;
sub = (ErlSubBin*)hp;
@@ -3791,8 +3846,13 @@ dec_term_atom_common:
if (next || ctx->state != B2TDecode) {
ctx->u.dc.ep = ep;
ctx->u.dc.next = next;
- ctx->u.dc.hp = hp;
- ctx->u.dc.maps_head = maps_head;
+ ctx->u.dc.factory.hp = hp;
+ if (!WSTACK_ISEMPTY(flat_maps)) {
+ WSTACK_SAVE(flat_maps, &ctx->u.dc.flat_maps);
+ }
+ if (!PSTACK_IS_EMPTY(hamt_array)) {
+ PSTACK_SAVE(hamt_array, &ctx->u.dc.hamt_array);
+ }
ctx->reds = 0;
return NULL;
}
@@ -3803,24 +3863,47 @@ dec_term_atom_common:
}
}
- /* Iterate through all the maps and check for validity and sort keys
+ ASSERT(hp <= factory->hp_end
+ || (factory->mode == FACTORY_CLOSED && is_immed(*dbg_resultp)));
+ factory->hp = hp;
+ /*
+ * From here on factory may produce (more) heap fragments
+ */
+
+ if (!PSTACK_IS_EMPTY(hamt_array)) {
+ do {
+ struct dec_term_hamt* hamt = PSTACK_TOP(hamt_array);
+
+ *hamt->objp = erts_hashmap_from_array(factory,
+ hamt->leaf_array,
+ hamt->size,
+ 1);
+ if (is_non_value(*hamt->objp))
+ goto error_hamt;
+
+ (void) PSTACK_POP(hamt_array);
+ } while (!PSTACK_IS_EMPTY(hamt_array));
+ PSTACK_DESTROY(hamt_array);
+ }
+
+ /* Iterate through all the (flat)maps and check for validity and sort keys
* - done here for when we know it is complete.
*/
- while (maps_head) {
- next = (Eterm *)(EXPAND_POINTER(*maps_head));
- *maps_head = MAP_HEADER;
- if (!erts_validate_and_sort_map((map_t*)maps_head))
- goto error;
- maps_head = next;
+ while(!WSTACK_ISEMPTY(flat_maps)) {
+ next = (Eterm *)WSTACK_POP(flat_maps);
+ if (!erts_validate_and_sort_flatmap((flatmap_t*)next))
+ goto error;
}
+ WSTACK_DESTROY(flat_maps);
+
+ ASSERT((Eterm*)EXPAND_POINTER(*dbg_resultp) != NULL);
if (ctx) {
ctx->state = B2TDone;
ctx->reds = reds;
}
- *hpp = hp;
return ep;
error:
@@ -3828,15 +3911,17 @@ error:
* Must unlink all off-heap objects that may have been
* linked into the process.
*/
- if (hp < *hpp) { /* Sometimes we used hp and sometimes *hpp */
- hp = *hpp; /* the largest must be the freshest */
+ if (factory->hp < hp) { /* Sometimes we used hp and sometimes factory->hp */
+ factory->hp = hp; /* the largest must be the freshest */
}
- undo_offheap_in_area(off_heap, hp_saved, hp);
- *hpp = hp_saved;
+error_hamt:
+ erts_factory_undo(factory);
+ PSTACK_DESTROY(hamt_array);
if (ctx) {
ctx->state = B2TDecodeFail;
ctx->reds = reds;
}
+ WSTACK_DESTROY(flat_maps);
return NULL;
}
@@ -3855,51 +3940,35 @@ static int
encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,
unsigned dflags, Sint *reds, Uint *res)
{
- DECLARE_ESTACK(s);
+ DECLARE_WSTACK(s);
Uint m, i, arity;
Uint result = 0;
Sint r = 0;
if (ctx) {
- ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
+ WSTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
r = *reds;
- if (ctx->estack.start) { /* restore saved stack */
- ESTACK_RESTORE(s, &ctx->estack);
+ if (ctx->wstack.wstart) { /* restore saved stack */
+ WSTACK_RESTORE(s, &ctx->wstack);
result = ctx->result;
obj = ctx->obj;
}
}
- goto L_jump_start;
+#define LIST_TAIL_OP ((0 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER)
+#define TERM_ARRAY_OP(N) (((N) << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER)
+#define TERM_ARRAY_OP_DEC(OP) ((OP) - (1 << _TAG_PRIMARY_SIZE))
+
+
+ for (;;) {
+ ASSERT(!is_header(obj));
- outer_loop:
- while (!ESTACK_ISEMPTY(s)) {
- obj = ESTACK_POP(s);
- handle_popped_obj:
- if (is_list(obj)) {
- Eterm* cons = list_val(obj);
- Eterm tl;
-
- tl = CDR(cons);
- obj = CAR(cons);
- ESTACK_PUSH(s, tl);
- } else if (is_nil(obj)) {
- result++;
- goto outer_loop;
- } else {
- /*
- * Other term (in the tail of a non-proper list or
- * in a fun's environment).
- */
- }
-
- L_jump_start:
if (ctx && --r == 0) {
*reds = r;
ctx->obj = obj;
ctx->result = result;
- ESTACK_SAVE(s, &ctx->estack);
+ WSTACK_SAVE(s, &ctx->wstack);
return -1;
}
switch (tag_val_def(obj)) {
@@ -3982,70 +4051,79 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,
result += m + 2 + 1;
} else {
result += 5;
- goto handle_popped_obj;
+ WSTACK_PUSH2(s, (UWord)CDR(list_val(obj)), (UWord)LIST_TAIL_OP);
+ obj = CAR(list_val(obj));
+ continue; /* big loop */
}
break;
case TUPLE_DEF:
{
Eterm* ptr = tuple_val(obj);
- Uint i;
arity = arityval(*ptr);
if (arity <= 0xff) {
result += 1 + 1;
} else {
result += 1 + 4;
}
- for (i = 1; i <= arity; ++i) {
- if (is_list(ptr[i])) {
- if ((m = is_string(obj)) && (m < MAX_STRING_LEN)) {
- result += m + 2 + 1;
- } else {
- result += 5;
- }
- }
- ESTACK_PUSH(s,ptr[i]);
+ if (arity > 1) {
+ WSTACK_PUSH2(s, (UWord) (ptr + 2),
+ (UWord) TERM_ARRAY_OP(arity-1));
}
- goto outer_loop;
+ else if (arity == 0) {
+ break;
+ }
+ obj = ptr[1];
+ continue; /* big loop */
}
- break;
case MAP_DEF:
- {
- map_t *mp = (map_t*)map_val(obj);
- Uint size = map_get_size(mp);
- Uint i;
- Eterm *ptr;
+ if (is_flatmap(obj)) {
+ flatmap_t *mp = (flatmap_t*)flatmap_val(obj);
+ Uint size = flatmap_get_size(mp);
result += 1 + 4; /* tag + 4 bytes size */
- /* push values first */
- ptr = map_get_values(mp);
- i = size;
- while(i--) {
- if (is_list(*ptr)) {
- if ((m = is_string(*ptr)) && (m < MAX_STRING_LEN)) {
- result += m + 2 + 1;
- } else {
- result += 5;
- }
- }
- ESTACK_PUSH(s,*ptr);
- ++ptr;
+ if (size) {
+ WSTACK_PUSH4(s, (UWord) flatmap_get_values(mp),
+ (UWord) TERM_ARRAY_OP(size),
+ (UWord) flatmap_get_keys(mp),
+ (UWord) TERM_ARRAY_OP(size));
+ }
+ } else {
+ Eterm *ptr;
+ Eterm hdr;
+ Uint node_sz;
+ ptr = boxed_val(obj);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ ptr++;
+ node_sz = 16;
+ result += 1 + 4; /* tag + 4 bytes size */
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ ptr++;
+ result += 1 + 4; /* tag + 4 bytes size */
+ /*fall through*/
+ case HAMT_SUBTAG_NODE_BITMAP:
+ node_sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(node_sz < 17);
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
}
- ptr = map_get_keys(mp);
- i = size;
- while(i--) {
- if (is_list(*ptr)) {
- if ((m = is_string(*ptr)) && (m < MAX_STRING_LEN)) {
- result += m + 2 + 1;
- } else {
- result += 5;
- }
+ ptr++;
+ WSTACK_RESERVE(s, node_sz*2);
+ while(node_sz--) {
+ if (is_list(*ptr)) {
+ WSTACK_FAST_PUSH(s, CAR(list_val(*ptr)));
+ WSTACK_FAST_PUSH(s, CDR(list_val(*ptr)));
+ } else {
+ WSTACK_FAST_PUSH(s, *ptr);
}
- ESTACK_PUSH(s,*ptr);
- ++ptr;
+ ptr++;
}
- goto outer_loop;
}
break;
case FLOAT_DEF:
@@ -4098,25 +4176,13 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,
result += 2 * (1 + 4); /* Index + Uniq */
result += 1 + (funp->num_free < 0x100 ? 1 : 4);
}
- for (i = 1; i < funp->num_free; i++) {
- obj = funp->env[i];
-
- if (is_not_list(obj)) {
- /* Push any non-list terms on the stack */
- ESTACK_PUSH(s, obj);
- } else {
- /* Lists must be handled specially. */
- if ((m = is_string(obj)) && (m < MAX_STRING_LEN)) {
- result += m + 2 + 1;
- } else {
- result += 5;
- ESTACK_PUSH(s, obj);
- }
- }
+ if (funp->num_free > 1) {
+ WSTACK_PUSH2(s, (UWord) (funp->env + 1),
+ (UWord) TERM_ARRAY_OP(funp->num_free-1));
}
if (funp->num_free != 0) {
obj = funp->env[0];
- goto L_jump_start;
+ continue; /* big loop */
}
break;
}
@@ -4136,20 +4202,51 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,
break;
default:
- erl_exit(1,"Internal data structure error (in encode_size_struct2)%x\n",
+ erts_exit(ERTS_ERROR_EXIT,"Internal data structure error (in encode_size_struct2)%x\n",
obj);
}
+
+ if (WSTACK_ISEMPTY(s)) {
+ break;
+ }
+ obj = (Eterm) WSTACK_POP(s);
+
+ if (is_header(obj)) {
+ switch (obj) {
+ case LIST_TAIL_OP:
+ obj = (Eterm) WSTACK_POP(s);
+ if (is_list(obj)) {
+ Eterm* cons = list_val(obj);
+
+ WSTACK_PUSH2(s, (UWord)CDR(cons), (UWord)LIST_TAIL_OP);
+ obj = CAR(cons);
+ }
+ break;
+
+ case TERM_ARRAY_OP(1):
+ obj = *(Eterm*)WSTACK_POP(s);
+ break;
+ default: { /* TERM_ARRAY_OP(N) when N > 1 */
+ Eterm* ptr = (Eterm*) WSTACK_POP(s);
+ WSTACK_PUSH2(s, (UWord) (ptr+1),
+ (UWord) TERM_ARRAY_OP_DEC(obj));
+ obj = *ptr;
+ }
+ }
+ }
}
- DESTROY_ESTACK(s);
+ WSTACK_DESTROY(s);
if (ctx) {
- ASSERT(ctx->estack.start == NULL);
+ ASSERT(ctx->wstack.wstart == NULL);
*reds = r;
}
*res = result;
return 0;
}
+
+
static Sint
decoded_size(byte *ep, byte* endp, int internal_tags, B2TContext* ctx)
{
@@ -4343,7 +4440,11 @@ init_done:
n = get_int32(ep);
ep += 4;
ADDTERMS(2*n);
- heap_size += 3 + n + 1 + n;
+ if (n <= MAP_SMALL_MAP_LIMIT) {
+ heap_size += 3 + n + 1 + n;
+ } else {
+ heap_size += HASHMAP_ESTIMATED_HEAP_SIZE(n);
+ }
break;
case STRING_EXT:
CHKSIZE(2);
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index 10565f67e5..d12051c6b4 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2013. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -148,8 +149,10 @@ typedef struct {
byte *extp;
int exttmp;
Uint extsize;
+ Uint heap_size;
} ErtsBinary2TermState;
+
/* -------------------------------------------------------------------------- */
void erts_init_atom_cache_map(ErtsAtomCacheMap *);
@@ -160,8 +163,12 @@ void erts_finalize_atom_cache_map(ErtsAtomCacheMap *, Uint32);
Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *);
byte *erts_encode_ext_dist_header_setup(byte *, ErtsAtomCacheMap *);
byte *erts_encode_ext_dist_header_finalize(byte *, ErtsAtomCache *, Uint32);
-Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *);
-void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *);
+struct erts_dsig_send_context;
+int erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap*, Uint* szp);
+int erts_encode_dist_ext_size_int(Eterm term, struct erts_dsig_send_context* ctx, Uint* szp);
+struct TTBEncodeContext_;
+int erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *,
+ struct TTBEncodeContext_ *, Sint* reds);
Uint erts_encode_ext_size(Eterm);
Uint erts_encode_ext_size_2(Eterm, unsigned);
@@ -180,18 +187,18 @@ void erts_destroy_dist_ext_copy(ErtsDistExternal *);
int erts_prepare_dist_ext(ErtsDistExternal *, byte *, Uint,
DistEntry *, ErtsAtomCache *);
Sint erts_decode_dist_ext_size(ErtsDistExternal *);
-Eterm erts_decode_dist_ext(Eterm **, ErlOffHeap *, ErtsDistExternal *);
+Eterm erts_decode_dist_ext(ErtsHeapFactory* factory, ErtsDistExternal *);
Sint erts_decode_ext_size(byte*, Uint);
Sint erts_decode_ext_size_ets(byte*, Uint);
-Eterm erts_decode_ext(Eterm **, ErlOffHeap *, byte**);
-Eterm erts_decode_ext_ets(Eterm **, ErlOffHeap *, byte*);
+Eterm erts_decode_ext(ErtsHeapFactory*, byte**);
+Eterm erts_decode_ext_ets(ErtsHeapFactory*, byte*);
Eterm erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags);
Sint erts_binary2term_prepare(ErtsBinary2TermState *, byte *, Sint);
void erts_binary2term_abort(ErtsBinary2TermState *);
-Eterm erts_binary2term_create(ErtsBinary2TermState *, Eterm **hpp, ErlOffHeap *);
+Eterm erts_binary2term_create(ErtsBinary2TermState *, ErtsHeapFactory*);
int erts_debug_max_atom_out_cache_index(void);
int erts_debug_atom_to_out_cache_index(Eterm);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 32a2dc43e8..1b8595fe57 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -41,6 +42,7 @@
#include "error.h"
#include "erl_utils.h"
#include "erl_port.h"
+#include "erl_gc.h"
struct enif_environment_t /* ErlNifEnv */
{
@@ -51,6 +53,7 @@ struct enif_environment_t /* ErlNifEnv */
ErlHeapFragment* heap_frag;
int fpe_was_unmasked;
struct enif_tmp_obj_t* tmp_obj_list;
+ int exception_thrown; /* boolean */
};
extern void erts_pre_nif(struct enif_environment_t*, Process*,
struct erl_module_nif*);
@@ -228,9 +231,23 @@ typedef struct {
ERTS_INTERNAL_BINARY_FIELDS
SWord orig_size;
void (*destructor)(Binary *);
- char magic_bin_data[1];
+ union {
+ struct {
+ ERTS_BINARY_STRUCT_ALIGNMENT
+ char data[1];
+ } aligned;
+ struct {
+ char data[1];
+ } unaligned;
+ } u;
} ErtsMagicBinary;
+#ifdef ARCH_32
+#define ERTS_MAGIC_BIN_BYTES_TO_ALIGN 4
+#else
+#define ERTS_MAGIC_BIN_BYTES_TO_ALIGN 0
+#endif
+
typedef union {
Binary binary;
ErtsMagicBinary magic_binary;
@@ -250,15 +267,30 @@ typedef union {
#define ERTS_MAGIC_BIN_DESTRUCTOR(BP) \
((ErtsBinary *) (BP))->magic_binary.destructor
#define ERTS_MAGIC_BIN_DATA(BP) \
- ((void *) ((ErtsBinary *) (BP))->magic_binary.magic_bin_data)
-#define ERTS_MAGIC_BIN_DATA_SIZE(BP) \
- ((BP)->orig_size - sizeof(void (*)(Binary *)))
+ ((void *) ((ErtsBinary *) (BP))->magic_binary.u.aligned.data)
+#define ERTS_MAGIC_DATA_OFFSET \
+ (offsetof(ErtsMagicBinary,u.aligned.data) - offsetof(Binary,orig_bytes))
#define ERTS_MAGIC_BIN_ORIG_SIZE(Sz) \
- (sizeof(void (*)(Binary *)) + (Sz))
+ (ERTS_MAGIC_DATA_OFFSET + (Sz))
#define ERTS_MAGIC_BIN_SIZE(Sz) \
- (offsetof(ErtsMagicBinary,magic_bin_data) + (Sz))
-#define ERTS_MAGIC_BIN_FROM_DATA(DATA) \
- ((ErtsBinary*)((char*)(DATA) - offsetof(ErtsMagicBinary,magic_bin_data)))
+ (offsetof(ErtsMagicBinary,u.aligned.data) + (Sz))
+
+/* On 32-bit arch these macro variants will save memory
+ by not forcing 8-byte alignment for the magic payload.
+*/
+#define ERTS_MAGIC_BIN_UNALIGNED_DATA(BP) \
+ ((void *) ((ErtsBinary *) (BP))->magic_binary.u.unaligned.data)
+#define ERTS_MAGIC_UNALIGNED_DATA_OFFSET \
+ (offsetof(ErtsMagicBinary,u.unaligned.data) - offsetof(Binary,orig_bytes))
+#define ERTS_MAGIC_BIN_UNALIGNED_DATA_SIZE(BP) \
+ ((BP)->orig_size - ERTS_MAGIC_UNALIGNED_DATA_OFFSET)
+#define ERTS_MAGIC_BIN_UNALIGNED_ORIG_SIZE(Sz) \
+ (ERTS_MAGIC_UNALIGNED_DATA_OFFSET + (Sz))
+#define ERTS_MAGIC_BIN_UNALIGNED_SIZE(Sz) \
+ (offsetof(ErtsMagicBinary,u.unaligned.data) + (Sz))
+#define ERTS_MAGIC_BIN_FROM_UNALIGNED_DATA(DATA) \
+ ((ErtsBinary*)((char*)(DATA) - offsetof(ErtsMagicBinary,u.unaligned.data)))
+
#define Binary2ErlDrvBinary(B) (&((ErtsBinary *) (B))->driver.binary)
#define ErlDrvBinary2Binary(D) ((Binary *) \
@@ -347,8 +379,6 @@ extern Uint display_items; /* no of items to display in traces etc */
extern int erts_backtrace_depth;
extern erts_smp_atomic32_t erts_max_gen_gcs;
-extern int erts_disable_tolerant_timeofday;
-
extern int bif_reductions; /* reductions + fcalls (when doing call_bif) */
extern int stackdump_on_exit;
@@ -371,16 +401,17 @@ extern int stackdump_on_exit;
* DESTROY_ESTACK(Stack)
*/
-typedef struct {
+typedef struct ErtsEStack_ {
Eterm* start;
Eterm* sp;
Eterm* end;
+ Eterm* edefault;
ErtsAlcType_t alloc_type;
}ErtsEStack;
#define DEF_ESTACK_SIZE (16)
-void erl_grow_estack(ErtsEStack*, Eterm* def_stack);
+void erl_grow_estack(ErtsEStack*, Uint need);
#define ESTK_CONCAT(a,b) a##b
#define ESTK_DEF_STACK(s) ESTK_CONCAT(s,_default_estack)
@@ -390,22 +421,23 @@ void erl_grow_estack(ErtsEStack*, Eterm* def_stack);
ESTK_DEF_STACK(s), /* start */ \
ESTK_DEF_STACK(s), /* sp */ \
ESTK_DEF_STACK(s) + DEF_ESTACK_SIZE, /* end */ \
+ ESTK_DEF_STACK(s), /* default */ \
ERTS_ALC_T_ESTACK /* alloc_type */ \
}
#define ESTACK_CHANGE_ALLOCATOR(s,t) \
do { \
- if (s.start != ESTK_DEF_STACK(s)) { \
- erl_exit(1, "Internal error - trying to change allocator " \
+ if ((s).start != ESTK_DEF_STACK(s)) { \
+ erts_exit(ERTS_ERROR_EXIT, "Internal error - trying to change allocator " \
"type of active estack\n"); \
} \
- s.alloc_type = (t); \
+ (s).alloc_type = (t); \
} while (0)
#define DESTROY_ESTACK(s) \
do { \
- if (s.start != ESTK_DEF_STACK(s)) { \
- erts_free(s.alloc_type, s.start); \
+ if ((s).start != ESTK_DEF_STACK(s)) { \
+ erts_free((s).alloc_type, (s).start); \
} \
} while(0)
@@ -416,16 +448,17 @@ do { \
*/
#define ESTACK_SAVE(s,dst)\
do {\
- if (s.start == ESTK_DEF_STACK(s)) {\
+ if ((s).start == ESTK_DEF_STACK(s)) {\
UWord _wsz = ESTACK_COUNT(s);\
- (dst)->start = erts_alloc(s.alloc_type,\
+ (dst)->start = erts_alloc((s).alloc_type,\
DEF_ESTACK_SIZE * sizeof(Eterm));\
- memcpy((dst)->start, s.start,_wsz*sizeof(Eterm));\
+ memcpy((dst)->start, (s).start,_wsz*sizeof(Eterm));\
(dst)->sp = (dst)->start + _wsz;\
(dst)->end = (dst)->start + DEF_ESTACK_SIZE;\
- (dst)->alloc_type = s.alloc_type;\
+ (dst)->edefault = NULL;\
+ (dst)->alloc_type = (s).alloc_type;\
} else\
- *(dst) = s;\
+ *(dst) = (s);\
} while (0)
#define DESTROY_SAVED_ESTACK(estack)\
@@ -444,89 +477,138 @@ do {\
*/
#define ESTACK_RESTORE(s, src) \
do { \
- ASSERT(s.start == ESTK_DEF_STACK(s)); \
- s = *(src); /* struct copy */ \
+ ASSERT((s).start == ESTK_DEF_STACK(s)); \
+ (s) = *(src); /* struct copy */ \
(src)->start = NULL; \
- ASSERT(s.sp >= s.start); \
- ASSERT(s.sp <= s.end); \
+ ASSERT((s).sp >= (s).start); \
+ ASSERT((s).sp <= (s).end); \
} while (0)
-#define ESTACK_IS_STATIC(s) (s.start == ESTK_DEF_STACK(s)))
+#define ESTACK_IS_STATIC(s) ((s).start == ESTK_DEF_STACK(s))
-#define ESTACK_PUSH(s, x) \
-do { \
- if (s.sp == s.end) { \
- erl_grow_estack(&s, ESTK_DEF_STACK(s)); \
- } \
- *s.sp++ = (x); \
+#define ESTACK_PUSH(s, x) \
+do { \
+ if ((s).sp == (s).end) { \
+ erl_grow_estack(&(s), 1); \
+ } \
+ *(s).sp++ = (x); \
} while(0)
#define ESTACK_PUSH2(s, x, y) \
do { \
- if (s.sp > s.end - 2) { \
- erl_grow_estack(&s, ESTK_DEF_STACK(s)); \
+ if ((s).sp > (s).end - 2) { \
+ erl_grow_estack(&(s), 2); \
} \
- *s.sp++ = (x); \
- *s.sp++ = (y); \
+ *(s).sp++ = (x); \
+ *(s).sp++ = (y); \
} while(0)
#define ESTACK_PUSH3(s, x, y, z) \
do { \
- if (s.sp > s.end - 3) { \
- erl_grow_estack(&s, ESTK_DEF_STACK(s)); \
+ if ((s).sp > (s).end - 3) { \
+ erl_grow_estack(&s, 3); \
} \
- *s.sp++ = (x); \
- *s.sp++ = (y); \
- *s.sp++ = (z); \
+ *(s).sp++ = (x); \
+ *(s).sp++ = (y); \
+ *(s).sp++ = (z); \
} while(0)
-#define ESTACK_COUNT(s) (s.sp - s.start)
-#define ESTACK_ISEMPTY(s) (s.sp == s.start)
-#define ESTACK_POP(s) (*(--s.sp))
+#define ESTACK_PUSH4(s, E1, E2, E3, E4) \
+do { \
+ if ((s).sp > (s).end - 4) { \
+ erl_grow_estack(&s, 4); \
+ } \
+ *(s).sp++ = (E1); \
+ *(s).sp++ = (E2); \
+ *(s).sp++ = (E3); \
+ *(s).sp++ = (E4); \
+} while(0)
+
+#define ESTACK_RESERVE(s, push_cnt) \
+do { \
+ if ((s).sp > (s).end - (push_cnt)) { \
+ erl_grow_estack(&(s), (push_cnt)); \
+ } \
+} while(0)
+
+/* Must be preceded by ESTACK_RESERVE */
+#define ESTACK_FAST_PUSH(s, x) \
+do { \
+ ASSERT((s).sp < (s).end); \
+ *s.sp++ = (x); \
+} while(0)
+
+#define ESTACK_COUNT(s) ((s).sp - (s).start)
+#define ESTACK_ISEMPTY(s) ((s).sp == (s).start)
+#define ESTACK_POP(s) (*(--(s).sp))
/*
* WSTACK: same as ESTACK but with UWord instead of Eterm
*/
-typedef struct {
+typedef struct ErtsWStack_ {
UWord* wstart;
UWord* wsp;
UWord* wend;
+ UWord* wdefault;
ErtsAlcType_t alloc_type;
}ErtsWStack;
#define DEF_WSTACK_SIZE (16)
-void erl_grow_wstack(ErtsWStack*, UWord* def_stack);
+void erl_grow_wstack(ErtsWStack*, Uint need);
#define WSTK_CONCAT(a,b) a##b
#define WSTK_DEF_STACK(s) WSTK_CONCAT(s,_default_wstack)
-#define DECLARE_WSTACK(s) \
+#define WSTACK_DECLARE(s) \
UWord WSTK_DEF_STACK(s)[DEF_WSTACK_SIZE]; \
ErtsWStack s = { \
WSTK_DEF_STACK(s), /* wstart */ \
WSTK_DEF_STACK(s), /* wsp */ \
WSTK_DEF_STACK(s) + DEF_WSTACK_SIZE, /* wend */ \
+ WSTK_DEF_STACK(s), /* wdflt */ \
ERTS_ALC_T_ESTACK /* alloc_type */ \
}
+#define DECLARE_WSTACK WSTACK_DECLARE
+
+typedef struct ErtsDynamicWStack_ {
+ UWord default_stack[DEF_WSTACK_SIZE];
+ ErtsWStack ws;
+}ErtsDynamicWStack;
+
+#define WSTACK_INIT(dwsp, ALC_TYPE) \
+do { \
+ (dwsp)->ws.wstart = (dwsp)->default_stack; \
+ (dwsp)->ws.wsp = (dwsp)->default_stack; \
+ (dwsp)->ws.wend = (dwsp)->default_stack + DEF_WSTACK_SIZE;\
+ (dwsp)->ws.wdefault = (dwsp)->default_stack; \
+ (dwsp)->ws.alloc_type = ALC_TYPE; \
+} while (0)
#define WSTACK_CHANGE_ALLOCATOR(s,t) \
do { \
if (s.wstart != WSTK_DEF_STACK(s)) { \
- erl_exit(1, "Internal error - trying to change allocator " \
+ erts_exit(ERTS_ERROR_EXIT, "Internal error - trying to change allocator " \
"type of active wstack\n"); \
} \
s.alloc_type = (t); \
} while (0)
-#define DESTROY_WSTACK(s) \
+#define WSTACK_DESTROY(s) \
do { \
- if (s.wstart != WSTK_DEF_STACK(s)) { \
+ if (s.wstart != s.wdefault) { \
erts_free(s.alloc_type, s.wstart); \
} \
} while(0)
+#define DESTROY_WSTACK WSTACK_DESTROY
+#define WSTACK_DEBUG(s) \
+ do { \
+ fprintf(stderr, "wstack size = %ld\r\n", s.wsp - s.wstart); \
+ fprintf(stderr, "wstack wstart = %p\r\n", s.wstart); \
+ fprintf(stderr, "wstack wsp = %p\r\n", s.wsp); \
+ } while(0)
/*
* Do not free the stack after this, it may have pointers into what
@@ -541,6 +623,7 @@ do {\
memcpy((dst)->wstart, s.wstart,_wsz*sizeof(UWord));\
(dst)->wsp = (dst)->wstart + _wsz;\
(dst)->wend = (dst)->wstart + DEF_WSTACK_SIZE;\
+ (dst)->wdefault = NULL;\
(dst)->alloc_type = s.alloc_type;\
} else\
*(dst) = s;\
@@ -569,12 +652,12 @@ do { \
ASSERT(s.wsp <= s.wend); \
} while (0)
-#define WSTACK_IS_STATIC(s) (s.wstart == WSTK_DEF_STACK(s)))
+#define WSTACK_IS_STATIC(s) (s.wstart == WSTK_DEF_STACK(s))
#define WSTACK_PUSH(s, x) \
do { \
if (s.wsp == s.wend) { \
- erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \
+ erl_grow_wstack(&s, 1); \
} \
*s.wsp++ = (x); \
} while(0)
@@ -582,7 +665,7 @@ do { \
#define WSTACK_PUSH2(s, x, y) \
do { \
if (s.wsp > s.wend - 2) { \
- erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \
+ erl_grow_wstack(&s, 2); \
} \
*s.wsp++ = (x); \
*s.wsp++ = (y); \
@@ -590,17 +673,179 @@ do { \
#define WSTACK_PUSH3(s, x, y, z) \
do { \
- if (s.wsp > s.wend - 3) { \
- erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \
+ if (s.wsp > s.wend - 3) { \
+ erl_grow_wstack(&s, 3); \
} \
*s.wsp++ = (x); \
*s.wsp++ = (y); \
*s.wsp++ = (z); \
} while(0)
+#define WSTACK_PUSH4(s, A1, A2, A3, A4) \
+do { \
+ if (s.wsp > s.wend - 4) { \
+ erl_grow_wstack(&s, 4); \
+ } \
+ *s.wsp++ = (A1); \
+ *s.wsp++ = (A2); \
+ *s.wsp++ = (A3); \
+ *s.wsp++ = (A4); \
+} while(0)
+
+#define WSTACK_PUSH5(s, A1, A2, A3, A4, A5) \
+do { \
+ if (s.wsp > s.wend - 5) { \
+ erl_grow_wstack(&s, 5); \
+ } \
+ *s.wsp++ = (A1); \
+ *s.wsp++ = (A2); \
+ *s.wsp++ = (A3); \
+ *s.wsp++ = (A4); \
+ *s.wsp++ = (A5); \
+} while(0)
+
+#define WSTACK_PUSH6(s, A1, A2, A3, A4, A5, A6) \
+do { \
+ if (s.wsp > s.wend - 6) { \
+ erl_grow_wstack(&s, 6); \
+ } \
+ *s.wsp++ = (A1); \
+ *s.wsp++ = (A2); \
+ *s.wsp++ = (A3); \
+ *s.wsp++ = (A4); \
+ *s.wsp++ = (A5); \
+ *s.wsp++ = (A6); \
+} while(0)
+
+#define WSTACK_RESERVE(s, push_cnt) \
+do { \
+ if (s.wsp > s.wend - (push_cnt)) { \
+ erl_grow_wstack(&s, (push_cnt)); \
+ } \
+} while(0)
+
+/* Must be preceded by WSTACK_RESERVE */
+#define WSTACK_FAST_PUSH(s, x) \
+do { \
+ ASSERT(s.wsp < s.wend); \
+ *s.wsp++ = (x); \
+} while(0)
+
#define WSTACK_COUNT(s) (s.wsp - s.wstart)
#define WSTACK_ISEMPTY(s) (s.wsp == s.wstart)
-#define WSTACK_POP(s) (*(--s.wsp))
+#define WSTACK_POP(s) ((ASSERT(s.wsp > s.wstart)),*(--s.wsp))
+
+#define WSTACK_ROLLBACK(s, count) (ASSERT(WSTACK_COUNT(s) >= (count)), \
+ s.wsp = s.wstart + (count))
+
+/* PSTACK - Stack of any type.
+ * Usage:
+ * {
+ * #define PSTACK_TYPE MyType
+ * PSTACK_DECLARE(s,16);
+ * MyType *sp = PSTACK_PUSH(s);
+ *
+ * sp->x = ....
+ * sp->y = ....
+ * sp = PSTACK_PUSH(s);
+ * ...
+ * sp = PSTACK_POP(s);
+ * if (PSTACK_IS_EMPTY(s)) {
+ * // sp is invalid when stack is empty after pop
+ * }
+ *
+ * PSTACK_DESTROY(s);
+ * }
+ */
+
+
+typedef struct ErtsPStack_ {
+ byte* pstart;
+ byte* psp;
+ byte* pend;
+ ErtsAlcType_t alloc_type;
+}ErtsPStack;
+
+void erl_grow_pstack(ErtsPStack* s, void* default_pstack, unsigned need_bytes);
+#define PSTK_CONCAT(a,b) a##b
+#define PSTK_DEF_STACK(s) PSTK_CONCAT(s,_default_pstack)
+
+#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 */\
+ ERTS_ALC_T_ESTACK /* alloc_type */ \
+}
+
+#define PSTACK_CHANGE_ALLOCATOR(s,t) \
+do { \
+ if (s.pstart != (byte*)PSTK_DEF_STACK(s)) { \
+ erts_exit(ERTS_ERROR_EXIT, "Internal error - trying to change allocator " \
+ "type of active pstack\n"); \
+ } \
+ s.alloc_type = (t); \
+ } while (0)
+
+#define PSTACK_DESTROY(s) \
+do { \
+ if (s.pstart != (byte*)PSTK_DEF_STACK(s)) { \
+ erts_free(s.alloc_type, s.pstart); \
+ } \
+} while(0)
+
+#define PSTACK_IS_EMPTY(s) (s.psp < s.pstart)
+
+#define PSTACK_COUNT(s) (((PSTACK_TYPE*)s.psp + 1) - (PSTACK_TYPE*)s.pstart)
+
+#define PSTACK_TOP(s) (ASSERT(!PSTACK_IS_EMPTY(s)), (PSTACK_TYPE*)(s.psp))
+
+#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_POP(s) ((PSTACK_TYPE*) (s.psp -= sizeof(PSTACK_TYPE)))
+
+/*
+ * Do not free the stack after this, it may have pointers into what
+ * was saved in 'dst'.
+ */
+#define PSTACK_SAVE(s,dst)\
+do {\
+ if (s.pstart == (byte*)PSTK_DEF_STACK(s)) {\
+ UWord _pbytes = PSTACK_COUNT(s) * sizeof(PSTACK_TYPE);\
+ (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)->alloc_type = s.alloc_type;\
+ } else\
+ *(dst) = s;\
+ } while (0)
+
+/*
+ * Use on empty stack, only the allocator can be changed before this.
+ * The src stack is reset to NULL.
+ */
+#define PSTACK_RESTORE(s, src) \
+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); \
+} while (0)
+
+#define PSTACK_DESTROY_SAVED(pstack)\
+do {\
+ if ((pstack)->pstart) {\
+ erts_free((pstack)->alloc_type, (pstack)->pstart);\
+ (pstack)->pstart = NULL;\
+ }\
+} while(0)
/* binary.c */
@@ -623,9 +868,6 @@ erts_bld_port_info(Eterm **hpp,
void erts_bif_info_init(void);
/* bif.c */
-Eterm erts_make_ref(Process *);
-Eterm erts_make_ref_in_buffer(Eterm buffer[REF_THING_SIZE]);
-void erts_make_ref_in_array(Uint32 ref[ERTS_MAX_REF_NUMBERS]);
ERTS_GLB_INLINE Eterm
erts_proc_store_ref(Process *c_p, Uint32 ref[ERTS_MAX_REF_NUMBERS]);
@@ -705,10 +947,13 @@ void print_process_info(int, void *, Process*);
void info(int, void *);
void loaded(int, void *);
+/* erl_arith.c */
+double erts_get_positive_zero_float(void);
+
/* config.c */
-__decl_noreturn void __noreturn erl_exit(int n, char*, ...);
-__decl_noreturn void __noreturn erl_exit_flush_async(int n, char*, ...);
+__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);
/* copy.c */
@@ -810,23 +1055,6 @@ void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
void MD5Final(unsigned char [16], MD5_CTX *);
-/* ggc.c */
-
-void erts_gc_info(ErtsGCInfo *gcip);
-void erts_init_gc(void);
-int erts_garbage_collect(Process*, int, Eterm*, int);
-void erts_garbage_collect_hibernate(Process* p);
-Eterm erts_gc_after_bif_call(Process* p, Eterm result, Eterm* regs, Uint arity);
-void erts_garbage_collect_literals(Process* p, Eterm* literals,
- Uint lit_size,
- struct erl_off_heap_header* oh);
-Uint erts_next_heap_size(Uint, Uint);
-Eterm erts_heap_sizes(Process* p);
-
-void erts_offset_off_heap(ErlOffHeap *, Sint, Eterm*, Eterm*);
-void erts_offset_heap_ptr(Eterm*, Uint, Sint, Eterm*, Eterm*);
-void erts_offset_heap(Eterm*, Uint, Sint, Eterm*, Eterm*);
-void erts_free_heap_frags(Process* p);
/* io.c */
@@ -907,6 +1135,9 @@ Sint erts_binary_set_loop_limit(Sint limit);
/* external.c */
void erts_init_external(void);
+/* erl_map.c */
+void erts_init_map(void);
+
/* erl_unicode.c */
void erts_init_unicode(void);
Sint erts_unicode_set_loop_limit(Sint limit);
@@ -1161,12 +1392,13 @@ erts_alloc_message_heap_state(Uint size,
state = erts_smp_atomic32_read_acqb(&receiver->state);
if (statep)
*statep = state;
- if (state & (ERTS_PSFLG_EXITING|ERTS_PSFLG_PENDING_EXIT))
+ if (state & (ERTS_PSFLG_EXITING
+ | ERTS_PSFLG_PENDING_EXIT))
goto allocate_in_mbuf;
#endif
if (size > (Uint) INT_MAX)
- erl_exit(ERTS_ABORT_EXIT, "HUGE size (%beu)\n", size);
+ erts_exit(ERTS_ABORT_EXIT, "HUGE size (%beu)\n", size);
if (
#if defined(ERTS_SMP)
@@ -1181,7 +1413,8 @@ erts_alloc_message_heap_state(Uint size,
state = erts_smp_atomic32_read_nob(&receiver->state);
if (statep)
*statep = state;
- if ((state & (ERTS_PSFLG_EXITING|ERTS_PSFLG_PENDING_EXIT))
+ if ((state & (ERTS_PSFLG_EXITING
+ | ERTS_PSFLG_PENDING_EXIT))
|| (receiver->flags & F_DISABLE_GC)
|| HEAP_LIMIT(receiver) - HEAP_TOP(receiver) <= size) {
/*
diff --git a/erts/emulator/beam/hash.c b/erts/emulator/beam/hash.c
index afaf32f8ce..895fe657d1 100644
--- a/erts/emulator/beam/hash.c
+++ b/erts/emulator/beam/hash.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -132,7 +133,7 @@ Hash* hash_init(ErtsAlcType_t type, Hash* h, char* name, int size, HashFunctions
while (h_size_table[ix] != -1 && h_size_table[ix] < size)
ix++;
if (h_size_table[ix] == -1)
- erl_exit(1, "panic: too large hash table size (%d)\n", size);
+ erts_exit(ERTS_ERROR_EXIT, "panic: too large hash table size (%d)\n", size);
size = h_size_table[ix];
sz = size*sizeof(HashBucket*);
diff --git a/erts/emulator/beam/hash.h b/erts/emulator/beam/hash.h
index 6dd66fc9b3..87fdb360e3 100644
--- a/erts/emulator/beam/hash.h
+++ b/erts/emulator/beam/hash.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/index.c b/erts/emulator/beam/index.c
index 79c3ecf1b3..5f6ea14732 100644
--- a/erts/emulator/beam/index.c
+++ b/erts/emulator/beam/index.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -83,7 +84,7 @@ index_put_entry(IndexTable* t, void* tmpl)
Uint sz;
if (ix >= t->limit) {
/* A core dump is unnecessary */
- erl_exit(ERTS_DUMP_EXIT, "no more index entries in %s (max=%d)\n",
+ erts_exit(ERTS_DUMP_EXIT, "no more index entries in %s (max=%d)\n",
t->htable.name, t->limit);
}
sz = INDEX_PAGE_SIZE*sizeof(IndexSlot*);
@@ -122,7 +123,7 @@ void erts_index_merge(Hash* src, IndexTable* dst)
ix = dst->entries++;
if (ix >= dst->size) {
if (ix >= dst->limit) {
- erl_exit(1, "no more index entries in %s (max=%d)\n",
+ erts_exit(ERTS_ERROR_EXIT, "no more index entries in %s (max=%d)\n",
dst->htable.name, dst->limit);
}
sz = INDEX_PAGE_SIZE*sizeof(IndexSlot*);
diff --git a/erts/emulator/beam/index.h b/erts/emulator/beam/index.h
index 537bc11056..14fab41026 100644
--- a/erts/emulator/beam/index.h
+++ b/erts/emulator/beam/index.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 7c6696405b..fbcb0c31fc 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -47,6 +48,9 @@
#include "external.h"
#include "dtrace-wrapper.h"
#include "erl_map.h"
+#include "erl_bif_unique.h"
+#include "erl_hl_timer.h"
+#include "erl_time.h"
extern ErlDrvEntry fd_driver_entry;
#ifndef __OSE__
@@ -63,8 +67,6 @@ static erts_smp_tsd_key_t driver_list_last_error_key; /* Save last DDLL error o
per thread basis (for BC interfaces) */
ErtsPTab erts_port erts_align_attribute(ERTS_CACHE_LINE_SIZE); /* The port table */
-erts_smp_atomic_t erts_bytes_out; /* No bytes sent out of the system */
-erts_smp_atomic_t erts_bytes_in; /* No bytes gotten into the system */
const ErlDrvTermData driver_term_nil = (ErlDrvTermData)NIL;
@@ -78,6 +80,9 @@ int erts_port_synchronous_ops = 0;
int erts_port_schedule_all_ops = 0;
int erts_port_parallelism = 0;
+static erts_atomic64_t bytes_in;
+static erts_atomic64_t bytes_out;
+
static void deliver_result(Eterm sender, Eterm pid, Eterm res);
static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *);
static void terminate_port(Port *p);
@@ -378,11 +383,7 @@ static Port *create_port(char *name,
prt->dist_entry = NULL;
ERTS_PORT_INIT_CONNECTED(prt, pid);
prt->common.u.alive.reg = NULL;
-#ifdef ERTS_SMP
- prt->common.u.alive.ptimer = NULL;
-#else
- sys_memset(&prt->common.u.alive.tm, 0, sizeof(ErlTimer));
-#endif
+ ERTS_PTMR_INIT(prt);
erts_port_task_handle_init(&prt->timeout_task);
prt->psd = NULL;
prt->drv_data = (SWord) 0;
@@ -391,7 +392,7 @@ static Port *create_port(char *name,
/* Set default tracing */
erts_get_default_tracing(&ERTS_TRACE_FLAGS(prt), &ERTS_TRACER_PROC(prt));
- ASSERT(((char *) prt) == ((char *) &prt->common));
+ ERTS_CT_ASSERT(offsetof(Port,common) == 0);
#if !ERTS_PORT_INIT_INSTR_NEED_ID
/*
@@ -462,11 +463,7 @@ erts_port_free(Port *prt)
| ERTS_PORT_SFLG_FREE));
ASSERT(state & ERTS_PORT_SFLG_PORT_DEBUG);
-#ifdef ERTS_SMP
- ERTS_LC_ASSERT(erts_atomic32_read_nob(&prt->common.refc) == 0);
-#else
- ERTS_LC_ASSERT(erts_atomic32_read_nob(&prt->refc) == 0);
-#endif
+ ERTS_LC_ASSERT(erts_atomic_read_nob(&prt->common.refc.atmc) == 0);
erts_port_task_fini_sched(&prt->sched);
@@ -735,11 +732,7 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */
/*
* Must clean up the port.
*/
-#ifdef ERTS_SMP
- erts_cancel_smp_ptimer(port->common.u.alive.ptimer);
-#else
- erts_cancel_timer(&(port->common.u.alive.tm));
-#endif
+ erts_cancel_port_timer(port);
stopq(port);
if (port->linebuf != NULL) {
erts_free(ERTS_ALC_T_LINEBUF,
@@ -1405,39 +1398,22 @@ finalize_force_imm_drv_call(ErtsTryImmDrvCallState *sp)
static ERTS_INLINE void
queue_port_sched_op_reply(Process *rp,
ErtsProcLocks *rp_locksp,
- Eterm *hp_start,
- Eterm *hp,
- Uint h_size,
- ErlHeapFragment* bp,
+ ErtsHeapFactory* factory,
Uint32 *ref_num,
Eterm msg)
{
- Eterm ref = make_internal_ref(hp);
+ Eterm* hp = erts_produce_heap(factory, ERTS_QUEUE_PORT_SCHED_OP_REPLY_SIZE, 0);
+ Eterm ref;
+
+ ref= make_internal_ref(hp);
write_ref_thing(hp, ref_num[0], ref_num[1], ref_num[2]);
hp += REF_THING_SIZE;
msg = TUPLE2(hp, ref, msg);
- hp += 3;
- if (!bp) {
- HRelease(rp, hp_start + h_size, hp);
- }
- else {
- Uint used_h_size = hp - hp_start;
- ASSERT(h_size >= used_h_size);
- if (h_size > used_h_size)
- bp = erts_resize_message_buffer(bp, used_h_size, &msg, 1);
- }
+ erts_factory_trim_and_close(factory, &msg, 1);
- erts_queue_message(rp,
- rp_locksp,
- bp,
- msg,
- NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, rp_locksp, factory->heap_frags, msg, NIL);
}
static void
@@ -1447,9 +1423,10 @@ port_sched_op_reply(Eterm to, Uint32 *ref_num, Eterm msg)
if (rp) {
ErlOffHeap *ohp;
ErlHeapFragment* bp;
+ ErtsHeapFactory factory;
Eterm msg_copy;
Uint hsz, msg_sz;
- Eterm *hp, *hp_start;
+ Eterm *hp;
ErtsProcLocks rp_locks = 0;
hsz = ERTS_QUEUE_PORT_SCHED_OP_REPLY_SIZE;
@@ -1460,22 +1437,22 @@ port_sched_op_reply(Eterm to, Uint32 *ref_num, Eterm msg)
hsz += msg_sz;
}
- hp_start = hp = erts_alloc_message_heap(hsz,
+ hp = erts_alloc_message_heap(hsz,
&bp,
&ohp,
rp,
&rp_locks);
+ erts_factory_message_init(&factory, rp, hp, bp);
if (is_immed(msg))
msg_copy = msg;
- else
+ else {
msg_copy = copy_struct(msg, msg_sz, &hp, ohp);
+ factory.hp = hp;
+ }
queue_port_sched_op_reply(rp,
&rp_locks,
- hp_start,
- hp,
- hsz,
- bp,
+ &factory,
ref_num,
msg_copy);
@@ -1552,20 +1529,29 @@ erts_schedule_proc2port_signal(Process *c_p,
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
if (sched_res != 0) {
- if (refp)
+ if (refp) {
+ /*
+ * We need to restore the message queue save
+ * pointer to the beginning of the message queue
+ * since the caller now wont wait for a message
+ * containing the reference created above...
+ */
+ ASSERT(c_p);
+ erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
+ JOIN_MESSAGE(c_p);
+ erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
*refp = NIL;
+ }
return ERTS_PORT_OP_DROPPED;
}
return ERTS_PORT_OP_SCHEDULED;
}
static ERTS_INLINE void
-send_badsig(Port *prt)
-{
+send_badsig(Port *prt) {
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
Process* rp;
Eterm connected = ERTS_PORT_GET_CONNECTED(prt);
-
ERTS_SMP_CHK_NO_PROC_LOCKS;
ERTS_LC_ASSERT(erts_get_scheduler_id());
@@ -1585,15 +1571,13 @@ send_badsig(Port *prt)
0);
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
- }
-}
+ } /* exit sent */
+} /* send_badsig */
static void
-badsig_received(int bang_op,
- Port *prt,
+badsig_received(int bang_op, Port *prt,
erts_aint32_t state,
- int bad_output_value)
-{
+ int bad_output_value) {
/*
* if (bang_op)
* we are part of a "Prt ! Something" operation
@@ -1609,12 +1593,12 @@ badsig_received(int bang_op,
}
if (bang_op)
send_badsig(prt);
- }
-}
+ } /* not invalid */
+} /* behaved accordingly */
static int
-port_badsig(Port *prt, erts_aint32_t state, int op, ErtsProc2PortSigData *sigdp)
-{
+port_badsig(Port *prt, erts_aint32_t state, int op,
+ ErtsProc2PortSigData *sigdp) {
if (op == ERTS_PROC2PORT_SIG_EXEC)
badsig_received(sigdp->flags & ERTS_P2P_SIG_DATA_FLG_BANG_OP,
prt,
@@ -1623,16 +1607,14 @@ port_badsig(Port *prt, erts_aint32_t state, int op, ErtsProc2PortSigData *sigdp)
if (sigdp->flags & ERTS_P2P_SIG_DATA_FLG_REPLY)
port_sched_op_reply(sigdp->caller, sigdp->ref, am_badarg);
return ERTS_PORT_REDS_BADSIG;
-}
-
-
-/*
- * bad_port_signal() will
+} /* port_badsig */
+/* bad_port_signal() will
* - preserve signal order of signals.
* - send a 'badsig' exit signal to connected process if 'from' is an
* internal pid and the port is alive when the bad signal reaches
* it.
*/
+
static ErtsPortOpResult
bad_port_signal(Process *c_p,
int flags,
@@ -1707,6 +1689,7 @@ call_driver_outputv(int bang_op,
if (bang_op && from != ERTS_PORT_GET_CONNECTED(prt))
send_badsig(prt);
else {
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ErlDrvSizeT size = evp->size;
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt)
@@ -1724,7 +1707,10 @@ call_driver_outputv(int bang_op,
prt->caller = NIL;
prt->bytes_out += size;
- erts_smp_atomic_add_nob(&erts_bytes_out, size);
+ if (esdp)
+ esdp->io.out += (Uint64) size;
+ else
+ erts_atomic64_add_nob(&bytes_out, (erts_aint64_t) size);
}
}
@@ -1804,7 +1790,7 @@ call_driver_output(int bang_op,
if (bang_op && from != ERTS_PORT_GET_CONNECTED(prt))
send_badsig(prt);
else {
-
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt)
|| ERTS_IS_CRASH_DUMPING);
@@ -1820,7 +1806,10 @@ call_driver_output(int bang_op,
prt->caller = NIL;
prt->bytes_out += size;
- erts_smp_atomic_add_nob(&erts_bytes_out, size);
+ if (esdp)
+ esdp->io.out += (Uint64) size;
+ else
+ erts_atomic64_add_nob(&bytes_out, (erts_aint64_t) size);
}
}
@@ -2767,6 +2756,9 @@ void erts_init_io(int port_tab_size,
drv_list_rwmtx_opts.type = ERTS_SMP_RWMTX_TYPE_EXTREMELY_FREQUENT_READ;
drv_list_rwmtx_opts.lived = ERTS_SMP_RWMTX_LONG_LIVED;
+ erts_atomic64_init_nob(&bytes_in, 0);
+ erts_atomic64_init_nob(&bytes_out, 0);
+
common_element_size = ERTS_ALC_DATA_ALIGN_SIZE(sizeof(Port));
common_element_size += ERTS_ALC_DATA_ALIGN_SIZE(sizeof(ErtsPortTaskBusyPortQ));
common_element_size += 10; /* name */
@@ -2805,10 +2797,8 @@ void erts_init_io(int port_tab_size,
port_tab_size,
common_element_size, /* Doesn't need to be excact */
"port_table",
- legacy_port_tab);
-
- erts_smp_atomic_init_nob(&erts_bytes_out, 0);
- erts_smp_atomic_init_nob(&erts_bytes_in, 0);
+ legacy_port_tab,
+ 1);
sys_init_io();
@@ -2829,7 +2819,6 @@ void erts_init_io(int port_tab_size,
}
#if defined(ERTS_ENABLE_LOCK_COUNT) && defined(ERTS_SMP)
-
static ERTS_INLINE void lcnt_enable_drv_lock_count(erts_driver_t *dp, int enable)
{
if (dp->lock) {
@@ -2869,25 +2858,26 @@ static ERTS_INLINE void lcnt_enable_port_lock_count(Port *prt, int enable)
}
}
-void erts_lcnt_enable_io_lock_count(int enable)
-{
+void erts_lcnt_enable_io_lock_count(int enable) {
erts_driver_t *dp;
- int i, max = erts_ptab_max(&erts_port);
+ int ix, max = erts_ptab_max(&erts_port);
+ Port *prt;
- for (i = 0; i < max; i++) {
- Port *prt = erts_pix2port(i);
- if (prt)
+ for (ix = 0; ix < max; ix++) {
+ if ((prt = erts_pix2port(ix)) != NULL) {
lcnt_enable_port_lock_count(prt, enable);
- }
+ }
+ } /* for all ports */
lcnt_enable_drv_lock_count(&vanilla_driver, enable);
lcnt_enable_drv_lock_count(&spawn_driver, enable);
lcnt_enable_drv_lock_count(&fd_driver, enable);
- for (dp = driver_list; dp; dp = dp->next)
+ /* enable lock counting in all drivers */
+ for (dp = driver_list; dp; dp = dp->next) {
lcnt_enable_drv_lock_count(dp, enable);
-}
-#endif
-
+ }
+} /* enable/disable lock counting of ports */
+#endif /* defined(ERTS_ENABLE_LOCK_COUNT) && defined(ERTS_SMP) */
/*
* Buffering of data when using line oriented I/O on ports
*/
@@ -3072,7 +3062,7 @@ deliver_result(Eterm sender, Eterm pid, Eterm res)
rp = (scheduler
? erts_proc_lookup(pid)
- : erts_pid2proc_opt(NULL, 0, pid, 0, ERTS_P2P_FLG_SMP_INC_REFC));
+ : erts_pid2proc_opt(NULL, 0, pid, 0, ERTS_P2P_FLG_INC_REFC));
if (rp) {
Eterm tuple;
@@ -3085,16 +3075,12 @@ deliver_result(Eterm sender, Eterm pid, Eterm res)
hp = erts_alloc_message_heap(sz_res + 3, &bp, &ohp, rp, &rp_locks);
res = copy_struct(res, sz_res, &hp, ohp);
tuple = TUPLE2(hp, sender, res);
- erts_queue_message(rp, &rp_locks, bp, tuple, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, tuple, NIL);
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
if (!scheduler)
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
}
}
@@ -3138,7 +3124,7 @@ static void deliver_read_message(Port* prt, erts_aint32_t state, Eterm to,
rp = (scheduler
? erts_proc_lookup(to)
- : erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC));
+ : erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_INC_REFC));
if (!rp)
return;
@@ -3153,8 +3139,6 @@ static void deliver_read_message(Port* prt, erts_aint32_t state, Eterm to,
Binary* bptr;
bptr = erts_bin_nrml_alloc(len);
- bptr->flags = 0;
- bptr->orig_size = len;
erts_refc_init(&bptr->refc, 1);
sys_memcpy(bptr->orig_bytes, buf, len);
@@ -3187,15 +3171,11 @@ static void deliver_read_message(Port* prt, erts_aint32_t state, Eterm to,
tuple = TUPLE2(hp, prt->common.id, tuple);
hp += 3;
- erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined);
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
if (!scheduler)
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
}
/*
@@ -3281,7 +3261,7 @@ deliver_vec_message(Port* prt, /* Port */
rp = (scheduler
? erts_proc_lookup(to)
- : erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC));
+ : erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_INC_REFC));
if (!rp)
return;
@@ -3358,14 +3338,10 @@ deliver_vec_message(Port* prt, /* Port */
tuple = TUPLE2(hp, prt->common.id, tuple);
hp += 3;
- erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined);
erts_smp_proc_unlock(rp, rp_locks);
if (!scheduler)
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
}
@@ -3455,11 +3431,8 @@ terminate_port(Port *prt)
send_closed_port_id = NIL;
}
-#ifdef ERTS_SMP
- erts_cancel_smp_ptimer(prt->common.u.alive.ptimer);
-#else
- erts_cancel_timer(&prt->common.u.alive.tm);
-#endif
+ if (ERTS_PTMR_IS_SET(prt))
+ erts_cancel_port_timer(prt);
drv = prt->drv_ptr;
if ((drv != NULL) && (drv->stop != NULL)) {
@@ -3505,7 +3478,7 @@ terminate_port(Port *prt)
if ((state & ERTS_PORT_SFLG_HALT)
&& (erts_smp_atomic32_dec_read_nob(&erts_halt_progress) == 0)) {
erts_port_release(prt); /* We will exit and never return */
- erl_exit_flush_async(erts_halt_code, "");
+ erts_flush_async_exit(erts_halt_code, "");
}
if (is_internal_port(send_closed_port_id))
deliver_result(send_closed_port_id, connected_id, am_closed);
@@ -3930,12 +3903,13 @@ port_sig_control(Port *prt,
if (res == ERTS_PORT_OP_DONE) {
Eterm msg;
- Eterm *hp, *hp_start;
+ Eterm *hp;
ErlHeapFragment *bp;
ErlOffHeap *ohp;
+ ErtsHeapFactory factory;
Process *rp;
ErtsProcLocks rp_locks = 0;
- Uint hsz;
+ Uint hsz, rsz;
int control_flags;
rp = erts_proc_lookup_raw(sigdp->caller);
@@ -3944,17 +3918,19 @@ port_sig_control(Port *prt,
control_flags = prt->control_flags;
- hsz = ERTS_QUEUE_PORT_SCHED_OP_REPLY_SIZE;
- hsz += port_control_result_size(control_flags,
+ rsz = port_control_result_size(control_flags,
resp_bufp,
&resp_size,
&resp_buf[0]);
+ hsz = rsz + ERTS_QUEUE_PORT_SCHED_OP_REPLY_SIZE;
- hp_start = hp = erts_alloc_message_heap(hsz,
+
+ hp = erts_alloc_message_heap(hsz,
&bp,
&ohp,
rp,
&rp_locks);
+ erts_factory_message_init(&factory, rp, hp, bp);
msg = write_port_control_result(control_flags,
resp_bufp,
@@ -3963,13 +3939,11 @@ port_sig_control(Port *prt,
&hp,
bp,
ohp);
+ factory.hp = hp;
queue_port_sched_op_reply(rp,
&rp_locks,
- hp_start,
- hp,
- hsz,
- bp,
+ &factory,
sigdp->ref,
msg);
@@ -4256,8 +4230,6 @@ port_sig_call(Port *prt,
if (res == ERTS_PORT_OP_DONE) {
Eterm msg;
Eterm *hp;
- ErlHeapFragment *bp;
- ErlOffHeap *ohp;
Process *rp;
ErtsProcLocks rp_locks = 0;
Sint hsz;
@@ -4268,29 +4240,31 @@ port_sig_call(Port *prt,
hsz = erts_decode_ext_size((byte *) resp_bufp, resp_size);
if (hsz >= 0) {
- Eterm *hp_start;
+ ErlHeapFragment* bp;
+ ErlOffHeap* ohp;
+ ErtsHeapFactory factory;
byte *endp;
hsz += 3; /* ok tuple */
hsz += ERTS_QUEUE_PORT_SCHED_OP_REPLY_SIZE;
- hp_start = hp = erts_alloc_message_heap(hsz,
- &bp,
- &ohp,
- rp,
- &rp_locks);
+ hp = erts_alloc_message_heap(hsz,
+ &bp,
+ &ohp,
+ rp,
+ &rp_locks);
endp = (byte *) resp_bufp;
- msg = erts_decode_ext(&hp, ohp, &endp);
+ erts_factory_message_init(&factory, rp, hp, bp);
+ msg = erts_decode_ext(&factory, &endp);
if (is_value(msg)) {
+ hp = erts_produce_heap(&factory,
+ 3,
+ ERTS_QUEUE_PORT_SCHED_OP_REPLY_SIZE);
msg = TUPLE2(hp, am_ok, msg);
- hp += 3;
queue_port_sched_op_reply(rp,
&rp_locks,
- hp_start,
- hp,
- hsz,
- bp,
+ &factory,
sigdp->ref,
msg);
@@ -4298,8 +4272,6 @@ port_sig_call(Port *prt,
erts_smp_proc_unlock(rp, rp_locks);
goto done;
}
- if (bp)
- free_message_buffer(bp);
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
}
@@ -4376,10 +4348,11 @@ erts_port_call(Process* c_p,
try_call_res = try_imm_drv_call(&try_call_state);
switch (try_call_res) {
case ERTS_TRY_IMM_DRV_CALL_OK: {
- Eterm *hp, *hp_end;
+ ErtsHeapFactory factory;
Sint hsz;
unsigned ret_flags = 0U;
Eterm term;
+ Eterm* hp;
res = call_driver_call(c_p->common.id,
prt,
@@ -4399,15 +4372,14 @@ erts_port_call(Process* c_p,
if (hsz < 0)
return ERTS_PORT_OP_BADARG;
hsz += 3;
- hp = HAlloc(c_p, hsz);
- hp_end = hp + hsz;
+ erts_factory_proc_prealloc_init(&factory, c_p, hsz);
endp = (byte *) resp_bufp;
- term = erts_decode_ext(&hp, &MSO(c_p), &endp);
+ term = erts_decode_ext(&factory, &endp);
if (term == THE_NON_VALUE)
return ERTS_PORT_OP_BADARG;
+ hp = erts_produce_heap(&factory,3,0);
*retvalp = TUPLE2(hp, am_ok, term);
- hp += 3;
- HRelease(c_p, hp_end, hp);
+ erts_factory_close(&factory);
if (resp_bufp != &resp_buf[0]
&& !(ret_flags & DRIVER_CALL_KEEP_BUFFER))
driver_free(resp_bufp);
@@ -4542,12 +4514,11 @@ port_sig_info(Port *prt,
prt,
sigdp->u.info.item);
if (is_value(value)) {
+ ErtsHeapFactory factory;
+ erts_factory_message_init(&factory, NULL, hp, bp);
queue_port_sched_op_reply(rp,
&rp_locks,
- hp_start,
- hp,
- hsz,
- bp,
+ &factory,
sigdp->ref,
value);
}
@@ -4618,6 +4589,102 @@ erts_port_info(Process* c_p,
}
typedef struct {
+ Uint sched_id;
+ Eterm pid;
+ Uint32 refn[ERTS_REF_NUMBERS];
+ erts_smp_atomic32_t refc;
+} ErtsIOBytesReq;
+
+static void
+reply_io_bytes(void *vreq)
+{
+ ErtsIOBytesReq *req = (ErtsIOBytesReq *) vreq;
+ Process *rp;
+
+ rp = erts_proc_lookup(req->pid);
+ if (rp) {
+ ErlOffHeap *ohp = NULL;
+ ErlHeapFragment *bp = NULL;
+ ErtsProcLocks rp_locks;
+ Eterm ref, msg, ein, eout, *hp;
+ Uint64 in, out;
+ Uint hsz;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ Uint sched_id = esdp->no;
+ in = esdp->io.in;
+ out = esdp->io.out;
+ if (req->sched_id != sched_id)
+ rp_locks = 0;
+ else {
+ in += (Uint64) erts_atomic64_read_nob(&bytes_in);
+ out += (Uint64) erts_atomic64_read_nob(&bytes_out);
+ rp_locks = ERTS_PROC_LOCK_MAIN;
+ }
+
+ hsz = 5 /* 4-tuple */ + REF_THING_SIZE;
+
+ erts_bld_uint64(NULL, &hsz, in);
+ erts_bld_uint64(NULL, &hsz, out);
+
+ hp = erts_alloc_message_heap(hsz, &bp, &ohp, rp, &rp_locks);
+
+ ref = make_internal_ref(hp);
+ write_ref_thing(hp, req->refn[0], req->refn[1], req->refn[2]);
+ hp += REF_THING_SIZE;
+
+ ein = erts_bld_uint64(&hp, NULL, in);
+ eout = erts_bld_uint64(&hp, NULL, out);
+
+ msg = TUPLE4(hp, ref, make_small(sched_id), ein, eout);
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL);
+
+ if (req->sched_id == sched_id)
+ rp_locks &= ~ERTS_PROC_LOCK_MAIN;
+ if (rp_locks)
+ erts_smp_proc_unlock(rp, rp_locks);
+ }
+
+ if (erts_smp_atomic32_dec_read_nob(&req->refc) == 0)
+ erts_free(ERTS_ALC_T_IOB_REQ, req);
+}
+
+Eterm
+erts_request_io_bytes(Process *c_p)
+{
+ Uint *hp;
+ Eterm ref;
+ Uint32 *refn;
+ ErtsSchedulerData *esdp = ERTS_PROC_GET_SCHDATA(c_p);
+ ErtsIOBytesReq *req = erts_alloc(ERTS_ALC_T_IOB_REQ,
+ sizeof(ErtsIOBytesReq));
+
+ hp = HAlloc(c_p, REF_THING_SIZE);
+ ref = erts_sched_make_ref_in_buffer(esdp, hp);
+ refn = internal_ref_numbers(ref);
+
+ req->sched_id = esdp->no;
+ req->pid = c_p->common.id;
+ req->refn[0] = refn[0];
+ req->refn[1] = refn[1];
+ req->refn[2] = refn[2];
+ erts_smp_atomic32_init_nob(&req->refc,
+ (erts_aint32_t) erts_no_schedulers);
+
+#ifdef ERTS_SMP
+ if (erts_no_schedulers > 1)
+ erts_schedule_multi_misc_aux_work(1,
+ erts_no_schedulers,
+ reply_io_bytes,
+ (void *) req);
+#endif
+
+ reply_io_bytes((void *) req);
+
+ return ref;
+}
+
+
+typedef struct {
int to;
void *arg;
} prt_one_lnk_data;
@@ -4826,7 +4893,7 @@ void erts_raw_port_command(Port* p, byte* buf, Uint len)
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(p));
if (len > (Uint) INT_MAX)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Absurdly large data buffer (%beu bytes) passed to"
"output callback of %s driver.\n",
len,
@@ -5006,24 +5073,6 @@ erts_free_port_names(ErtsPortNames *pnp)
erts_free(ERTS_ALC_T_PORT_NAMES, pnp);
}
-static void schedule_port_timeout(Port *p)
-{
- /*
- * Scheduling of port timeouts can be done without port locking, but
- * since the task handle is stored in the port structure and the ptimer
- * structure is protected by the port lock we require the port to be
- * locked for now...
- *
- * TODO: Implement scheduling of port timeouts without locking
- * the port.
- * /Rickard
- */
- ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(p));
- erts_port_task_schedule(p->common.id,
- &p->timeout_task,
- ERTS_PORT_TASK_TIMEOUT);
-}
-
ErlDrvTermData driver_mk_term_nil(void)
{
return driver_term_nil;
@@ -5052,7 +5101,7 @@ void driver_report_exit(ErlDrvPort ix, int status)
rp = (scheduler
? erts_proc_lookup(pid)
- : erts_pid2proc_opt(NULL, 0, pid, 0, ERTS_P2P_FLG_SMP_INC_REFC));
+ : erts_pid2proc_opt(NULL, 0, pid, 0, ERTS_P2P_FLG_INC_REFC));
if (!rp)
return;
@@ -5062,15 +5111,11 @@ void driver_report_exit(ErlDrvPort ix, int status)
hp += 3;
tuple = TUPLE2(hp, prt->common.id, tuple);
- erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined);
erts_smp_proc_unlock(rp, rp_locks);
if (!scheduler)
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
}
#define ERTS_B2T_STATES_DEF_STATES_SZ 5
@@ -5162,22 +5207,27 @@ cleanup_b2t_states(struct b2t_states__ *b2tsp)
static int
driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
{
+#define HEAP_EXTRA 200
#define ERTS_DDT_FAIL do { res = -1; goto done; } while (0)
Uint need = 0;
int depth = 0;
int res;
- Eterm *hp = NULL, *hp_start = NULL, *hp_end = NULL;
ErlDrvTermData* ptr;
ErlDrvTermData* ptr_end;
DECLARE_ESTACK(stack);
- Eterm mess = NIL; /* keeps compiler happy */
+ Eterm mess;
Process* rp = NULL;
- ErlHeapFragment *bp = NULL;
- ErlOffHeap *ohp;
+ ErtsHeapFactory factory;
ErtsProcLocks rp_locks = 0;
struct b2t_states__ b2t;
- int scheduler = 1; /* Silence erroneous warning... */
+ int scheduler;
+ int is_heap_need_limited = 1;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+
+ ERTS_UNDEF(mess,NIL);
+ ERTS_UNDEF(scheduler,1);
+ factory.mode = FACTORY_CLOSED;
init_b2t_states(&b2t);
/*
@@ -5341,18 +5391,27 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
#ifdef DEBUG
b2t.org_ext[b2t.ix] = ext;
#endif
- hsz = erts_binary2term_prepare(&b2t.state[b2t.ix++], ext, size);
+ hsz = erts_binary2term_prepare(&b2t.state[b2t.ix], ext, size);
if (hsz < 0)
ERTS_DDT_FAIL; /* Invalid data */
+ b2t.state[b2t.ix++].heap_size = hsz;
need += hsz;
ptr += 2;
depth++;
+ if (size > MAP_SMALL_MAP_LIMIT*3) { /* may contain big map */
+ is_heap_need_limited = 0;
+ }
break;
}
case ERL_DRV_MAP: { /* int */
ERTS_DDT_CHK_ENOUGH_ARGS(1);
if ((int) ptr[0] < 0) ERTS_DDT_FAIL;
- need += MAP_HEADER_SIZE + 1 + 2*ptr[0];
+ if (ptr[0] > MAP_SMALL_MAP_LIMIT) {
+ need += HASHMAP_ESTIMATED_HEAP_SIZE(ptr[0]);
+ is_heap_need_limited = 0;
+ } else {
+ need += MAP_HEADER_FLATMAP_SZ + 1 + 2*ptr[0];
+ }
depth -= 2*ptr[0];
if (depth < 0) ERTS_DDT_FAIL;
ptr++;
@@ -5382,14 +5441,23 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
scheduler = erts_get_scheduler_id() != 0;
rp = (scheduler
? erts_proc_lookup(to)
- : erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC));
+ : erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_INC_REFC));
if (!rp) {
res = 0;
goto done;
}
- hp_start = hp = erts_alloc_message_heap(need, &bp, &ohp, rp, &rp_locks);
- hp_end = hp + need;
+ /* Try copy directly to destination heap if we know there are no big maps */
+ if (is_heap_need_limited) {
+ ErlOffHeap *ohp;
+ ErlHeapFragment* bp;
+ Eterm* hp = erts_alloc_message_heap(need, &bp, &ohp, rp, &rp_locks);
+ erts_factory_message_init(&factory, rp, hp, bp);
+ }
+ else {
+ erts_factory_message_init(&factory, NULL, NULL,
+ new_message_buffer(need));
+ }
/*
* Interpret the instructions and build the term.
@@ -5410,13 +5478,15 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
case ERL_DRV_INT: /* signed int argument */
#if HALFWORD_HEAP
- mess = erts_bld_sint64(&hp, NULL, (Sint64)ptr[0]);
+ erts_reserve_heap(&factory, BIG_NEED_SIZE(2));
+ mess = erts_bld_sint64(&factory.hp, NULL, (Sint64)ptr[0]);
#else
+ erts_reserve_heap(&factory, BIG_UINT_HEAP_SIZE);
if (IS_SSMALL((Sint)ptr[0]))
mess = make_small((Sint)ptr[0]);
else {
- mess = small_to_big((Sint)ptr[0], hp);
- hp += BIG_UINT_HEAP_SIZE;
+ mess = small_to_big((Sint)ptr[0], factory.hp);
+ factory.hp += BIG_UINT_HEAP_SIZE;
}
#endif
ptr++;
@@ -5424,25 +5494,29 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
case ERL_DRV_UINT: /* unsigned int argument */
#if HALFWORD_HEAP
- mess = erts_bld_uint64(&hp, NULL, (Uint64)ptr[0]);
+ erts_reserve_heap(&factory, BIG_NEED_FOR_BITS(64));
+ mess = erts_bld_uint64(&factory.hp, NULL, (Uint64)ptr[0]);
#else
+ erts_reserve_heap(&factory, BIG_UINT_HEAP_SIZE);
if (IS_USMALL(0, (Uint)ptr[0]))
mess = make_small((Uint)ptr[0]);
else {
- mess = uint_to_big((Uint)ptr[0], hp);
- hp += BIG_UINT_HEAP_SIZE;
+ mess = uint_to_big((Uint)ptr[0], factory.hp);
+ factory.hp += BIG_UINT_HEAP_SIZE;
}
#endif
ptr++;
break;
case ERL_DRV_INT64: /* pointer to unsigned 64-bit int argument */
- mess = erts_bld_sint64(&hp, NULL, *((Sint64 *) ptr[0]));
+ erts_reserve_heap(&factory, BIG_NEED_FOR_BITS(64));
+ mess = erts_bld_sint64(&factory.hp, NULL, *((Sint64 *) ptr[0]));
ptr++;
break;
case ERL_DRV_UINT64: /* pointer to unsigned 64-bit int argument */
- mess = erts_bld_uint64(&hp, NULL, *((Uint64 *) ptr[0]));
+ erts_reserve_heap(&factory, BIG_NEED_FOR_BITS(64));
+ mess = erts_bld_uint64(&factory.hp, NULL, *((Uint64 *) ptr[0]));
ptr++;
break;
@@ -5456,11 +5530,14 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
Uint size = ptr[1];
Uint offset = ptr[2];
- erts_smp_atomic_add_nob(&erts_bytes_in, (erts_aint_t) size);
+ if (esdp)
+ esdp->io.in += (Uint64) size;
+ else
+ erts_atomic64_add_nob(&bytes_in, (erts_aint64_t) size);
if (size <= ERL_ONHEAP_BIN_LIMIT) {
- ErlHeapBin* hbp = (ErlHeapBin *) hp;
- hp += heap_bin_size(size);
+ ErlHeapBin* hbp = (ErlHeapBin *) erts_produce_heap(&factory,
+ heap_bin_size(size), HEAP_EXTRA);
hbp->thing_word = header_heap_bin(size);
hbp->size = size;
if (size > 0) {
@@ -5469,18 +5546,18 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
mess = make_binary(hbp);
}
else {
- ProcBin* pb = (ProcBin *) hp;
+ ProcBin* pb = (ProcBin *) erts_produce_heap(&factory,
+ PROC_BIN_SIZE, HEAP_EXTRA);
driver_binary_inc_refc(b); /* caller will free binary */
pb->thing_word = HEADER_PROC_BIN;
pb->size = size;
- pb->next = ohp->first;
- ohp->first = (struct erl_off_heap_header*)pb;
+ pb->next = factory.off_heap->first;
+ factory.off_heap->first = (struct erl_off_heap_header*)pb;
pb->val = ErlDrvBinary2Binary(b);
pb->bytes = ((byte*) b->orig_bytes) + offset;
pb->flags = 0;
mess = make_binary(pb);
- hp += PROC_BIN_SIZE;
- OH_OVERHEAD(ohp, pb->size / sizeof(Eterm));
+ OH_OVERHEAD(factory.off_heap, pb->size / sizeof(Eterm));
}
ptr += 3;
break;
@@ -5490,11 +5567,15 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
byte *bufp = (byte *) ptr[0];
Uint size = (Uint) ptr[1];
- erts_smp_atomic_add_nob(&erts_bytes_in, (erts_aint_t) size);
+ if (esdp)
+ esdp->io.in += (Uint64) size;
+ else
+ erts_atomic64_add_nob(&bytes_in, (erts_aint64_t) size);
if (size <= ERL_ONHEAP_BIN_LIMIT) {
- ErlHeapBin* hbp = (ErlHeapBin *) hp;
- hp += heap_bin_size(size);
+ ErlHeapBin* hbp = (ErlHeapBin *) erts_produce_heap(&factory,
+ heap_bin_size(size),
+ HEAP_EXTRA);
hbp->thing_word = header_heap_bin(size);
hbp->size = size;
if (size > 0) {
@@ -5507,20 +5588,18 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
ProcBin* pbp;
Binary* bp = erts_bin_nrml_alloc(size);
ASSERT(bufp);
- bp->flags = 0;
- bp->orig_size = (SWord) size;
erts_refc_init(&bp->refc, 1);
sys_memcpy((void *) bp->orig_bytes, (void *) bufp, size);
- pbp = (ProcBin *) hp;
- hp += PROC_BIN_SIZE;
+ pbp = (ProcBin *) erts_produce_heap(&factory,
+ PROC_BIN_SIZE, HEAP_EXTRA);
pbp->thing_word = HEADER_PROC_BIN;
pbp->size = size;
- pbp->next = ohp->first;
- ohp->first = (struct erl_off_heap_header*)pbp;
+ pbp->next = factory.off_heap->first;
+ factory.off_heap->first = (struct erl_off_heap_header*)pbp;
pbp->val = bp;
pbp->bytes = (byte*) bp->orig_bytes;
pbp->flags = 0;
- OH_OVERHEAD(ohp, pbp->size / sizeof(Eterm));
+ OH_OVERHEAD(factory.off_heap, pbp->size / sizeof(Eterm));
mess = make_binary(pbp);
}
ptr += 2;
@@ -5528,14 +5607,19 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
}
case ERL_DRV_STRING: /* char*, length */
- erts_smp_atomic_add_nob(&erts_bytes_in, (erts_aint_t) ptr[1]);
- mess = buf_to_intlist(&hp, (char*)ptr[0], ptr[1], NIL);
+ if (esdp)
+ esdp->io.in += (Uint64) ptr[1];
+ else
+ erts_atomic64_add_nob(&bytes_in, (erts_aint64_t) ptr[1]);
+ erts_reserve_heap(&factory, 2*ptr[1]);
+ mess = buf_to_intlist(&factory.hp, (char*)ptr[0], ptr[1], NIL);
ptr += 2;
break;
case ERL_DRV_STRING_CONS: /* char*, length */
mess = ESTACK_POP(stack);
- mess = buf_to_intlist(&hp, (char*)ptr[0], ptr[1], mess);
+ erts_reserve_heap(&factory, 2*ptr[1]);
+ mess = buf_to_intlist(&factory.hp, (char*)ptr[0], ptr[1], mess);
ptr += 2;
break;
@@ -5544,11 +5628,12 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
mess = ESTACK_POP(stack);
i--;
+ erts_reserve_heap(&factory, 2*i);
while(i > 0) {
Eterm hd = ESTACK_POP(stack);
- mess = CONS(hp, hd, mess);
- hp += 2;
+ mess = CONS(factory.hp, hd, mess);
+ factory.hp += 2;
i--;
}
ptr++;
@@ -5557,13 +5642,12 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
case ERL_DRV_TUPLE: { /* int */
int size = (int)ptr[0];
- Eterm* tp = hp;
+ Eterm* tp = erts_produce_heap(&factory, size+1, HEAP_EXTRA);
*tp = make_arityval(size);
mess = make_tuple(tp);
tp += size; /* point at last element */
- hp = tp+1; /* advance "heap" pointer */
while(size--) {
*tp-- = ESTACK_POP(stack);
@@ -5579,18 +5663,22 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
case ERL_DRV_FLOAT: { /* double * */
FloatDef f;
+ Eterm* fp = erts_produce_heap(&factory, FLOAT_SIZE_OBJECT, HEAP_EXTRA);
- mess = make_float(hp);
+ mess = make_float(fp);
f.fd = *((double *) ptr[0]);
- PUT_DOUBLE(f, hp);
- hp += FLOAT_SIZE_OBJECT;
+ if (!erts_isfinite(f.fd))
+ ERTS_DDT_FAIL;
+ PUT_DOUBLE(f, fp);
ptr++;
break;
}
case ERL_DRV_EXT2TERM: /* char *ext, int size */
ASSERT(b2t.org_ext[b2t.ix] == (byte *) ptr[0]);
- mess = erts_binary2term_create(&b2t.state[b2t.ix++], &hp, ohp);
+
+ erts_reserve_heap(&factory, b2t.state[b2t.ix].heap_size);
+ mess = erts_binary2term_create(&b2t.state[b2t.ix++], &factory);
if (mess == THE_NON_VALUE)
ERTS_DDT_FAIL;
ptr += 2;
@@ -5598,31 +5686,43 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
case ERL_DRV_MAP: { /* int */
int size = (int)ptr[0];
- Eterm* tp = hp;
- Eterm* vp;
- map_t *mp;
-
- *tp = make_arityval(size);
-
- hp += 1 + size;
- mp = (map_t*)hp;
- mp->thing_word = MAP_HEADER;
- mp->size = size;
- mp->keys = make_tuple(tp);
- mess = make_map(mp);
-
- hp += MAP_HEADER_SIZE + size; /* advance "heap" pointer */
-
- tp += size; /* point at last key */
- vp = hp - 1; /* point at last value */
-
- while(size--) {
- *vp-- = ESTACK_POP(stack);
- *tp-- = ESTACK_POP(stack);
- }
- if (!erts_validate_and_sort_map(mp))
- ERTS_DDT_FAIL;
- ptr++;
+ if (size > MAP_SMALL_MAP_LIMIT) {
+ int ix = 2*size;
+ Eterm* leafs;
+
+ erts_produce_heap(&factory, ix, HEAP_EXTRA);
+ leafs = factory.hp;
+ while(ix--) { *--leafs = ESTACK_POP(stack); }
+
+ mess = erts_hashmap_from_array(&factory, leafs, size, 1);
+ if (is_non_value(mess))
+ ERTS_DDT_FAIL;
+ } else {
+ Eterm* vp;
+ flatmap_t *mp;
+ Eterm* tp = erts_produce_heap(&factory,
+ 2*size + 1 + MAP_HEADER_FLATMAP_SZ,
+ HEAP_EXTRA);
+
+ *tp = make_arityval(size);
+
+ mp = (flatmap_t*) (tp + 1 + size);
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = size;
+ mp->keys = make_tuple(tp);
+ mess = make_flatmap(mp);
+
+ tp += size; /* point at last key */
+ vp = factory.hp - 1; /* point at last value */
+
+ while(size--) {
+ *vp-- = ESTACK_POP(stack);
+ *tp-- = ESTACK_POP(stack);
+ }
+ if (!erts_validate_and_sort_flatmap(mp))
+ ERTS_DDT_FAIL;
+ }
+ ptr++;
break;
}
@@ -5636,42 +5736,28 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
if (res > 0) {
mess = ESTACK_POP(stack); /* get resulting value */
- if (bp)
- bp = erts_resize_message_buffer(bp, hp - hp_start, &mess, 1);
- else {
- ASSERT(hp);
- HRelease(rp, hp_end, hp);
- }
+ erts_factory_close(&factory);
/* send message */
- erts_queue_message(rp, &rp_locks, bp, mess, am_undefined
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(rp, &rp_locks, factory.heap_frags, mess, am_undefined);
}
else {
if (b2t.ix > b2t.used)
b2t.used = b2t.ix;
for (b2t.ix = 0; b2t.ix < b2t.used; b2t.ix++)
erts_binary2term_abort(&b2t.state[b2t.ix]);
- if (bp)
- free_message_buffer(bp);
- else if (hp) {
- HRelease(rp, hp_end, hp);
- }
+ erts_factory_undo(&factory);
}
-#ifdef ERTS_SMP
if (rp) {
if (rp_locks)
erts_smp_proc_unlock(rp, rp_locks);
if (!scheduler)
- erts_smp_proc_dec_refc(rp);
+ erts_proc_dec_refc(rp);
}
-#endif
cleanup_b2t_states(&b2t);
DESTROY_ESTACK(stack);
return res;
#undef ERTS_DDT_FAIL
+#undef HEAP_EXTRA
}
static ERTS_INLINE int
@@ -5800,6 +5886,7 @@ int driver_output_binary(ErlDrvPort ix, char* hbuf, ErlDrvSizeT hlen,
{
erts_aint32_t state;
Port* prt = erts_drvport2port_state(ix, &state);
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ERTS_SMP_CHK_NO_PROC_LOCKS;
@@ -5810,7 +5897,10 @@ int driver_output_binary(ErlDrvPort ix, char* hbuf, ErlDrvSizeT hlen,
return 0;
prt->bytes_in += (hlen + len);
- erts_smp_atomic_add_nob(&erts_bytes_in, (erts_aint_t) (hlen + len));
+ if (esdp)
+ esdp->io.in += (Uint64) (hlen + len);
+ else
+ erts_atomic64_add_nob(&bytes_in, (erts_aint64_t) (hlen + len));
if (state & ERTS_PORT_SFLG_DISTRIBUTION) {
return erts_net_message(prt,
prt->dist_entry,
@@ -5835,6 +5925,7 @@ int driver_output2(ErlDrvPort ix, char* hbuf, ErlDrvSizeT hlen,
{
erts_aint32_t state;
Port* prt = erts_drvport2port_state(ix, &state);
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ERTS_SMP_CHK_NO_PROC_LOCKS;
@@ -5846,7 +5937,10 @@ int driver_output2(ErlDrvPort ix, char* hbuf, ErlDrvSizeT hlen,
return 0;
prt->bytes_in += (hlen + len);
- erts_smp_atomic_add_nob(&erts_bytes_in, (erts_aint_t) (hlen + len));
+ if (esdp)
+ esdp->io.in += (Uint64) (hlen + len);
+ else
+ erts_atomic64_add_nob(&bytes_in, (erts_aint64_t) (hlen + len));
if (state & ERTS_PORT_SFLG_DISTRIBUTION) {
if (len == 0)
return erts_net_message(prt,
@@ -5886,6 +5980,7 @@ int driver_outputv(ErlDrvPort ix, char* hbuf, ErlDrvSizeT hlen,
ErlDrvBinary** binv;
Port* prt;
erts_aint32_t state;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ERTS_SMP_CHK_NO_PROC_LOCKS;
@@ -5924,7 +6019,10 @@ int driver_outputv(ErlDrvPort ix, char* hbuf, ErlDrvSizeT hlen,
/* XXX handle distribution !!! */
prt->bytes_in += (hlen + size);
- erts_smp_atomic_add_nob(&erts_bytes_in, (erts_aint_t) (hlen + size));
+ if (esdp)
+ esdp->io.in += (Uint64) (hlen + size);
+ else
+ erts_atomic64_add_nob(&bytes_in, (erts_aint64_t) (hlen + size));
deliver_vec_message(prt, ERTS_PORT_GET_CONNECTED(prt), hbuf, hlen,
binv, iov, n, size);
return 0;
@@ -6000,9 +6098,7 @@ driver_alloc_binary(ErlDrvSizeT size)
bin = erts_bin_drv_alloc_fnf((Uint) size);
if (!bin)
return NULL; /* The driver write must take action */
- bin->flags = BIN_FLAG_DRV;
erts_refc_init(&bin->refc, 1);
- bin->orig_size = (SWord) size;
return Binary2ErlDrvBinary(bin);
}
@@ -6032,7 +6128,6 @@ ErlDrvBinary* driver_realloc_binary(ErlDrvBinary* bin, ErlDrvSizeT size)
if (!newbin)
return NULL;
- newbin->orig_size = size;
return Binary2ErlDrvBinary(newbin);
}
@@ -6616,18 +6711,6 @@ int driver_pushq(ErlDrvPort ix, char* buffer, ErlDrvSizeT len)
return code;
}
-static ERTS_INLINE void
-drv_cancel_timer(Port *prt)
-{
-#ifdef ERTS_SMP
- erts_cancel_smp_ptimer(prt->common.u.alive.ptimer);
-#else
- erts_cancel_timer(&prt->common.u.alive.tm);
-#endif
- if (erts_port_task_is_scheduled(&prt->timeout_task))
- erts_port_task_abort(&prt->timeout_task);
-}
-
int driver_set_timer(ErlDrvPort ix, unsigned long t)
{
Port* prt = erts_drvport2port(ix);
@@ -6639,19 +6722,8 @@ int driver_set_timer(ErlDrvPort ix, unsigned long t)
if (prt->drv_ptr->timeout == NULL)
return -1;
- drv_cancel_timer(prt);
-#ifdef ERTS_SMP
- erts_create_smp_ptimer(&prt->common.u.alive.ptimer,
- prt->common.id,
- (ErlTimeoutProc) schedule_port_timeout,
- t);
-#else
- erts_set_timer(&prt->common.u.alive.tm,
- (ErlTimeoutProc) schedule_port_timeout,
- NULL,
- prt,
- t);
-#endif
+
+ erts_set_port_timer(prt, (Sint64) t);
return 0;
}
@@ -6661,28 +6733,28 @@ int driver_cancel_timer(ErlDrvPort ix)
if (prt == ERTS_INVALID_ERL_DRV_PORT)
return -1;
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
- drv_cancel_timer(prt);
+ erts_cancel_port_timer(prt);
return 0;
}
-
int
driver_read_timer(ErlDrvPort ix, unsigned long* t)
{
Port* prt = erts_drvport2port(ix);
+ Sint64 left;
ERTS_SMP_CHK_NO_PROC_LOCKS;
if (prt == ERTS_INVALID_ERL_DRV_PORT)
return -1;
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
-#ifdef ERTS_SMP
- *t = (prt->common.u.alive.ptimer
- ? erts_time_left(&prt->common.u.alive.ptimer->timer.tm)
- : 0);
-#else
- *t = erts_time_left(&prt->common.u.alive.tm);
-#endif
+
+ left = erts_read_port_timer(prt);
+ if (left < 0)
+ left = 0;
+
+ *t = (unsigned long) left;
+
return 0;
}
@@ -6702,11 +6774,33 @@ driver_get_now(ErlDrvNowData *now_data)
return 0;
}
+ErlDrvTime
+erl_drv_monotonic_time(ErlDrvTimeUnit time_unit)
+{
+ return (ErlDrvTime) erts_napi_monotonic_time((int) time_unit);
+}
+
+ErlDrvTime
+erl_drv_time_offset(ErlDrvTimeUnit time_unit)
+{
+ return (ErlDrvTime) erts_napi_time_offset((int) time_unit);
+}
+
+ErlDrvTime
+erl_drv_convert_time_unit(ErlDrvTime val,
+ ErlDrvTimeUnit from,
+ ErlDrvTimeUnit to)
+{
+ return (ErlDrvTime) erts_napi_convert_time_unit((ErtsMonotonicTime) val,
+ (int) from,
+ (int) to);
+}
+
static void ref_to_driver_monitor(Eterm ref, ErlDrvMonitor *mon)
{
RefThing *refp;
ASSERT(is_internal_ref(ref));
- ASSERT(sizeof(RefThing) <= sizeof(ErlDrvMonitor));
+ ERTS_CT_ASSERT(sizeof(RefThing) <= sizeof(ErlDrvMonitor));
refp = ref_thing_ptr(ref);
memset(mon,0,sizeof(ErlDrvMonitor));
memcpy(mon,refp,sizeof(RefThing));
@@ -7229,7 +7323,7 @@ driver_system_info(ErlDrvSysInfo *sip, size_t si_size)
* of ErlDrvSysInfo (introduced in driver version 1.0).
*/
if (!sip || si_size < ERL_DRV_SYS_INFO_SIZE(smp_support))
- erl_exit(1,
+ erts_exit(ERTS_ERROR_EXIT,
"driver_system_info(%p, %ld) called with invalid arguments\n",
sip, si_size);
@@ -7536,15 +7630,15 @@ int null_func(void)
}
int
-erl_drv_putenv(char *key, char *value)
+erl_drv_putenv(const char *key, char *value)
{
- return erts_sys_putenv_raw(key, value);
+ return erts_sys_putenv_raw((char*)key, value);
}
int
-erl_drv_getenv(char *key, char *value, size_t *value_size)
+erl_drv_getenv(const char *key, char *value, size_t *value_size)
{
- return erts_sys_getenv_raw(key, value, value_size);
+ return erts_sys_getenv_raw((char*)key, value, value_size);
}
/* get heart_port
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c
index daa6e136c5..86dd3b5aac 100644
--- a/erts/emulator/beam/module.c
+++ b/erts/emulator/beam/module.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h
index 5235528e98..c8a6351b04 100644
--- a/erts/emulator/beam/module.h
+++ b/erts/emulator/beam/module.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 68fcc177ae..1d32e72247 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -166,22 +167,26 @@ is_tuple Fail=f S | select_tuple_arity S=d Fail=f Size=u Rest=* => \
select_tuple_arity S=d Fail=f Size=u Rest=* => \
gen_select_tuple_arity(S, Fail, Size, Rest)
-i_select_val r f I
-i_select_val x f I
-i_select_val y f I
+i_select_val_bins r f I
+i_select_val_bins x f I
+i_select_val_bins y f I
-i_select_val2 r f c f c f
-i_select_val2 x f c f c f
-i_select_val2 y f c f c f
+i_select_val_lins r f I
+i_select_val_lins x f I
+i_select_val_lins y f I
-i_select_tuple_arity2 r f A f A f
-i_select_tuple_arity2 x f A f A f
-i_select_tuple_arity2 y f A f A f
+i_select_val2 r f c c f f
+i_select_val2 x f c c f f
+i_select_val2 y f c c f f
i_select_tuple_arity r f I
i_select_tuple_arity x f I
i_select_tuple_arity y f I
+i_select_tuple_arity2 r f A A f f
+i_select_tuple_arity2 x f A A f f
+i_select_tuple_arity2 y f A A f f
+
i_jump_on_val_zero r f I
i_jump_on_val_zero x f I
i_jump_on_val_zero y f I
@@ -294,10 +299,49 @@ move_jump f c
move_jump f x
move_jump f y
+
+# Movement to and from the stack is common
+# Try to pack as much as we can into one instruction
+
+# Window move
+move_window/5
+move_window/6
+
+# x -> y
+
+move S1=r S2=y | move X1=x Y1=y => move2 S1 S2 X1 Y1
+
+move X1=x Y1=y | move X2=x Y2=y | move X3=x Y3=y | succ(Y1,Y2) | succ(Y2,Y3) => \
+ move_window X1 X2 X3 Y1 Y3
+
+move_window X1=x X2=x X3=x Y1=y Y3=y | move X4=x Y4=y | succ(Y3,Y4) => \
+ move_window X1 X2 X3 X4 Y1 Y4
+
+move_window X1=x X2=x X3=x X4=x Y1=y Y4=y | move X5=x Y5=y | succ(Y4,Y5) => \
+ move_window5 X1 X2 X3 X4 X5 Y1
+
+move_window X1=x X2=x X3=x Y1=y Y3=y => move_window3 X1 X2 X3 Y1
+move_window X1=x X2=x X3=x X4=x Y1=y Y4=y => move_window4 X1 X2 X3 X4 Y1
+
+move_window3 x x x y
+move_window4 x x x x y
+move_window5 x x x x x y
+
move X1=x Y1=y | move X2=x Y2=y => move2 X1 Y1 X2 Y2
move Y1=y X1=x | move Y2=y X2=x => move2 Y1 X1 Y2 X2
move X1=x X2=x | move X3=x X4=x => move2 X1 X2 X3 X4
+move S1=x S2=r | move S3=x S4=x => move2 S1 S2 S3 S4
+move S1=x S2=r | move X1=x Y1=y => move2 S1 S2 X1 Y1
+move S1=y S2=r | move X1=x Y1=y => move2 S1 S2 X1 Y1
+
+move Y1=y X1=x | move S1=r D1=x => move2 Y1 X1 S1 D1
+move S1=r D1=x | move Y1=y X1=x => move2 S1 D1 Y1 X1
+
+move2 X1=x Y1=y X2=x Y2=y | move X3=x Y3=y => move3 X1 Y1 X2 Y2 X3 Y3
+move2 Y1=y X1=x Y2=y X2=x | move Y3=y X3=x => move3 Y1 X1 Y2 X2 Y3 X3
+move2 X1=x X2=x X3=x X4=x | move X5=x X6=x => move3 X1 X2 X3 X4 X5 X6
+
move C=aiq X=x==1 => move_x1 C
move C=aiq X=x==2 => move_x2 C
@@ -309,6 +353,20 @@ move2 x y x y
move2 y x y x
move2 x x x x
+move2 x r x x
+
+move2 x r x y
+move2 r y x y
+move2 y r x y
+
+move2 r x y x
+move2 y x r x
+
+%macro: move3 Move3
+move3 x y x y x y
+move3 y x y x y x
+move3 x x x x x x
+
# The compiler almost never generates a "move Literal y(Y)" instruction,
# so let's cheat if we encounter one.
move S=n D=y => init D
@@ -388,14 +446,59 @@ i_is_ne_exact_literal x f c
i_is_ne_exact_literal y f c
#
+# Common Compare Specializations
+# We don't do all of them since we want
+# to keep the instruction set small-ish
+#
+
+is_eq_exact Lbl S1=xy S2=r => is_eq_exact Lbl S2 S1
+is_eq_exact Lbl S1=rx S2=xy => i_is_eq_exact_spec Lbl S1 S2
+%macro: i_is_eq_exact_spec EqualExact -fail_action
+
+i_is_eq_exact_spec f x x
+i_is_eq_exact_spec f x y
+i_is_eq_exact_spec f r x
+i_is_eq_exact_spec f r y
+%cold
+i_is_eq_exact_spec f r r
+%hot
+
+is_lt Lbl S1=rxc S2=rxc => i_is_lt_spec Lbl S1 S2
+
+%macro: i_is_lt_spec IsLessThan -fail_action
+
+i_is_lt_spec f x x
+i_is_lt_spec f x r
+i_is_lt_spec f x c
+i_is_lt_spec f r x
+i_is_lt_spec f r c
+i_is_lt_spec f c x
+i_is_lt_spec f c r
+%cold
+i_is_lt_spec f r r
+i_is_lt_spec f c c
+%hot
+
+is_ge Lbl S1=xc S2=xc => i_is_ge_spec Lbl S1 S2
+
+%macro: i_is_ge_spec IsGreaterEqual -fail_action
+
+i_is_ge_spec f x x
+i_is_ge_spec f x c
+i_is_ge_spec f c x
+%cold
+i_is_ge_spec f c c
+%hot
+
+#
# All other comparisons.
#
is_eq_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_eq_exact Lbl
is_ne_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_ne_exact Lbl
-is_ge Lbl S1 S2 => i_fetch S1 S2 | i_is_ge Lbl
is_lt Lbl S1 S2 => i_fetch S1 S2 | i_is_lt Lbl
+is_ge Lbl S1 S2 => i_fetch S1 S2 | i_is_ge Lbl
is_eq Lbl S1 S2 => i_fetch S1 S2 | i_is_eq Lbl
is_ne Lbl S1 S2 => i_fetch S1 S2 | i_is_ne Lbl
@@ -489,7 +592,6 @@ put_list s s d
%hot
%macro: i_fetch FetchArgs -pack
-i_fetch c c
i_fetch c r
i_fetch c x
i_fetch c y
@@ -506,6 +608,7 @@ i_fetch y x
i_fetch y y
%cold
+i_fetch c c
i_fetch s s
%hot
@@ -1469,79 +1572,67 @@ apply_last I P
# Map instructions in R17.
#
-put_map_assoc F n Dst Live Size Rest=* => new_map F Dst Live Size Rest
-put_map_assoc F Src=s Dst Live Size Rest=* => \
+sorted_put_map_assoc/5
+put_map_assoc F Map Dst Live Size Rest=* | map_key_sort(Size, Rest) => \
+ sorted_put_map_assoc F Map Dst Live Size Rest
+
+sorted_put_map_exact/5
+put_map_exact F Map Dst Live Size Rest=* | map_key_sort(Size, Rest) => \
+ sorted_put_map_exact F Map Dst Live Size Rest
+
+sorted_put_map_assoc j Map Dst Live Size Rest=* | is_empty_map(Map) => \
+ new_map Dst Live Size Rest
+sorted_put_map_assoc F Src=s Dst Live Size Rest=* => \
update_map_assoc F Src Dst Live Size Rest
-put_map_assoc F Src Dst Live Size Rest=* => \
+sorted_put_map_assoc F Src Dst Live Size Rest=* => \
move Src x | update_map_assoc F x Dst Live Size Rest
-put_map_exact F n Dst Live Size Rest=* => new_map F Dst Live Size Rest
-put_map_exact F Src=s Dst Live Size Rest=* => \
+
+sorted_put_map_exact F Src=s Dst Live Size Rest=* => \
update_map_exact F Src Dst Live Size Rest
-put_map_exact F Src Dst Live Size Rest=* => \
+sorted_put_map_exact F Src Dst Live Size Rest=* => \
move Src x | update_map_exact F x Dst Live Size Rest
-new_map j d I I
+new_map d I I
update_map_assoc j s d I I
update_map_exact j s d I I
-is_map Fail Literal=q => move Literal x | is_map Fail x
-is_map Fail c => jump Fail
+is_map Fail Lit=q | literal_is_map(Lit) =>
+is_map Fail cq => jump Fail
%macro: is_map IsMap -fail_action
is_map f r
is_map f x
is_map f y
-## Transform has_map_field(s) #{ K1 := _, K2 := _ }
+## Transform has_map_fields #{ K1 := _, K2 := _ } to has_map_elements
-has_map_field/3
-
-has_map_fields Fail Src Size=u==1 Rest=* => gen_has_map_field(Fail,Src,Size,Rest)
-has_map_fields Fail Src Size Rest=* => i_has_map_fields Fail Src Size Rest
-
-i_has_map_fields f s I
-
-has_map_field Fail Src=rxy Key=arxy => i_has_map_field Fail Src Key
-has_map_field Fail Src Key => move Key x | i_has_map_field Fail Src x
-
-%macro: i_has_map_field HasMapField -fail_action
-i_has_map_field f r a
-i_has_map_field f x a
-i_has_map_field f y a
-i_has_map_field f r r
-i_has_map_field f x r
-i_has_map_field f y r
-i_has_map_field f r x
-i_has_map_field f x x
-i_has_map_field f y x
-i_has_map_field f r y
-i_has_map_field f x y
-i_has_map_field f y y
+has_map_fields Fail Src Size Rest=* => \
+ gen_has_map_fields(Fail, Src, Size, Rest)
## Transform get_map_elements(s) #{ K1 := V1, K2 := V2 }
-get_map_element/4
-
-get_map_elements Fail Src=rxy Size=u==2 Rest=* => gen_get_map_element(Fail,Src,Size,Rest)
-get_map_elements Fail Src Size Rest=* => i_get_map_elements Fail Src Size Rest
+get_map_elements Fail Src=rxy Size=u==2 Rest=* => \
+ gen_get_map_element(Fail, Src, Size, Rest)
+get_map_elements Fail Src Size Rest=* | map_key_sort(Size, Rest) => \
+ gen_get_map_elements(Fail, Src, Size, Rest)
i_get_map_elements f s I
-get_map_element Fail Src=rxy Key=ax Dst => i_get_map_element Fail Src Key Dst
-get_map_element Fail Src=rxy Key=rycq Dst => \
+i_get_map_element Fail Src=rxy Key=ry Dst => \
move Key x | i_get_map_element Fail Src x Dst
-get_map_element Fail Src Key Dst => jump Fail
+
+%macro: i_get_map_element_hash GetMapElementHash -fail_action
+i_get_map_element_hash f r c I r
+i_get_map_element_hash f x c I r
+i_get_map_element_hash f y c I r
+i_get_map_element_hash f r c I x
+i_get_map_element_hash f x c I x
+i_get_map_element_hash f y c I x
+i_get_map_element_hash f r c I y
+i_get_map_element_hash f x c I y
+i_get_map_element_hash f y c I y
%macro: i_get_map_element GetMapElement -fail_action
-i_get_map_element f r a r
-i_get_map_element f x a r
-i_get_map_element f y a r
-i_get_map_element f r a x
-i_get_map_element f x a x
-i_get_map_element f y a x
-i_get_map_element f r a y
-i_get_map_element f x a y
-i_get_map_element f y a y
i_get_map_element f r x r
i_get_map_element f x x r
i_get_map_element f y x r
@@ -1570,17 +1661,21 @@ gc_bif2 p Live u$bif:erlang:sminus/2 Reg=d Int=i Dst | \
# GCing arithmetic instructions.
#
+gc_bif2 Fail I u$bif:erlang:splus/2 S1=x S2=x Dst=d => i_plus Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:splus/2 S1 S2 Dst=d => i_fetch S1 S2 | i_plus Fail I Dst
+gc_bif2 Fail I u$bif:erlang:sminus/2 S1=x S2=x Dst=d => i_minus Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:sminus/2 S1 S2 Dst=d => i_fetch S1 S2 | i_minus Fail I Dst
gc_bif2 Fail I u$bif:erlang:stimes/2 S1 S2 Dst=d => i_fetch S1 S2 | i_times Fail I Dst
gc_bif2 Fail I u$bif:erlang:div/2 S1 S2 Dst=d => i_fetch S1 S2 | i_m_div Fail I Dst
gc_bif2 Fail I u$bif:erlang:intdiv/2 S1 S2 Dst=d => i_fetch S1 S2 | i_int_div Fail I Dst
+gc_bif2 Fail I u$bif:erlang:rem/2 S1=x S2=x Dst=d => i_rem Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:rem/2 S1 S2 Dst=d => i_fetch S1 S2 | i_rem Fail I Dst
gc_bif2 Fail I u$bif:erlang:bsl/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bsl Fail I Dst
gc_bif2 Fail I u$bif:erlang:bsr/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bsr Fail I Dst
+gc_bif2 Fail I u$bif:erlang:band/2 S1=x S2=c Dst=d => i_band Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:band/2 S1 S2 Dst=d => i_fetch S1 S2 | i_band Fail I Dst
gc_bif2 Fail I u$bif:erlang:bor/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bor Fail I Dst
gc_bif2 Fail I u$bif:erlang:bxor/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bxor Fail I Dst
@@ -1594,16 +1689,20 @@ i_increment r I I d
i_increment x I I d
i_increment y I I d
+i_plus j I x x d
i_plus j I d
+i_minus j I x x d
i_minus j I d
i_times j I d
i_m_div j I d
i_int_div j I d
+i_rem j I x x d
i_rem j I d
i_bsl j I d
i_bsr j I d
+i_band j I x c d
i_band j I d
i_bor j I d
i_bxor j I d
diff --git a/erts/emulator/beam/packet_parser.c b/erts/emulator/beam/packet_parser.c
index db0e78b1a7..a737a86f14 100644
--- a/erts/emulator/beam/packet_parser.c
+++ b/erts/emulator/beam/packet_parser.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -255,6 +256,7 @@ int packet_get_length(enum PacketParseType htype,
const char* ptr, unsigned n, /* Bytes read so far */
unsigned max_plen, /* Max packet length, 0=no limit */
unsigned trunc_len, /* Truncate (lines) if longer, 0=no limit */
+ char delimiter, /* Line delimiting character */
int* statep) /* Protocol specific state */
{
unsigned hlen, plen;
@@ -298,9 +300,9 @@ int packet_get_length(enum PacketParseType htype,
goto remain;
case TCP_PB_LINE_LF: {
- /* TCP_PB_LINE_LF: [Data ... \n] */
+ /* TCP_PB_LINE_LF: [Data ... Delimiter] */
const char* ptr2;
- if ((ptr2 = memchr(ptr, '\n', n)) == NULL) {
+ if ((ptr2 = memchr(ptr, delimiter, n)) == NULL) {
if (n > max_plen && max_plen != 0) { /* packet full */
DEBUGF((" => packet full (no NL)=%d\r\n", n));
goto error;
diff --git a/erts/emulator/beam/packet_parser.h b/erts/emulator/beam/packet_parser.h
index 1c3a9aa3da..717d905fad 100644
--- a/erts/emulator/beam/packet_parser.h
+++ b/erts/emulator/beam/packet_parser.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -104,7 +105,8 @@ int packet_get_length(enum PacketParseType htype,
const char* ptr, unsigned n, /* Bytes read so far */
unsigned max_plen, /* Packet max length, 0=no limit */
unsigned trunc_len, /* Truncate (lines) if longer, 0=no limit */
- int* statep); /* Internal protocol state */
+ char delimiter, /* Line delimiting character */
+ int* statep); /* Internal protocol state */
ERTS_GLB_INLINE
void packet_get_body(enum PacketParseType htype,
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index c626cb2780..020e61d136 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -124,7 +125,7 @@ static RegProc* reg_alloc(RegProc *tmpl)
{
RegProc* obj = (RegProc*) erts_alloc(ERTS_ALC_T_REG_PROC, sizeof(RegProc));
if (!obj) {
- erl_exit(1, "Can't allocate %d bytes of memory\n", sizeof(RegProc));
+ erts_exit(ERTS_ERROR_EXIT, "Can't allocate %d bytes of memory\n", sizeof(RegProc));
}
obj->name = tmpl->name;
obj->p = tmpl->p;
@@ -269,7 +270,10 @@ erts_whereis_name_to_id(Process *c_p, Eterm name)
#ifdef ERTS_SMP
ErtsProcLocks c_p_locks = c_p ? ERTS_PROC_LOCK_MAIN : 0;
- ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ if (c_p) ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
+#endif
+
reg_safe_read_lock(c_p, &c_p_locks);
if (c_p && !c_p_locks)
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
@@ -380,8 +384,6 @@ erts_whereis_name(Process *c_p,
erts_smp_proc_unlock(rp->p, need_locks);
*proc = NULL;
}
- if (*proc && (flags & ERTS_P2P_FLG_SMP_INC_REFC))
- erts_smp_proc_inc_refc(rp->p);
}
#else
if (rp->p
@@ -390,6 +392,8 @@ erts_whereis_name(Process *c_p,
else
*proc = NULL;
#endif
+ if (*proc && (flags & ERTS_P2P_FLG_INC_REFC))
+ erts_proc_inc_refc(*proc);
}
}
diff --git a/erts/emulator/beam/register.h b/erts/emulator/beam/register.h
index 7170463375..144536f34b 100644
--- a/erts/emulator/beam/register.h
+++ b/erts/emulator/beam/register.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/safe_hash.c b/erts/emulator/beam/safe_hash.c
index 3326e5cc2a..3f039c8dfd 100644
--- a/erts/emulator/beam/safe_hash.c
+++ b/erts/emulator/beam/safe_hash.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/safe_hash.h b/erts/emulator/beam/safe_hash.h
index c691126ef9..a11370813c 100644
--- a/erts/emulator/beam/safe_hash.h
+++ b/erts/emulator/beam/safe_hash.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index c29d4b3777..6497a1e648 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,6 +21,41 @@
#ifndef __SYS_H__
#define __SYS_H__
+#ifdef ERTS_INLINE
+# ifndef ERTS_CAN_INLINE
+# define ERTS_CAN_INLINE 1
+# endif
+#else
+# if defined(__GNUC__)
+# define ERTS_CAN_INLINE 1
+# define ERTS_INLINE __inline__
+# elif defined(__WIN32__)
+# define ERTS_CAN_INLINE 1
+# define ERTS_INLINE __inline
+# else
+# define ERTS_CAN_INLINE 0
+# define ERTS_INLINE
+# endif
+#endif
+
+#if defined(DEBUG) || defined(ERTS_ENABLE_LOCK_CHECK)
+# undef ERTS_CAN_INLINE
+# define ERTS_CAN_INLINE 0
+# undef ERTS_INLINE
+# define ERTS_INLINE
+#endif
+
+#if ERTS_CAN_INLINE
+#define ERTS_GLB_INLINE static ERTS_INLINE
+#else
+#define ERTS_GLB_INLINE
+#endif
+
+#if ERTS_CAN_INLINE || defined(ERTS_DO_INCL_GLB_INLINE_FUNC_DEF)
+# define ERTS_GLB_INLINE_INCL_FUNC_DEF 1
+#else
+# define ERTS_GLB_INLINE_INCL_FUNC_DEF 0
+#endif
#if defined(VALGRIND) && !defined(NO_FPE_SIGNALS)
# define NO_FPE_SIGNALS
@@ -75,23 +111,6 @@ typedef int ErtsSysFdType;
typedef ERTS_SYS_FD_TYPE ErtsSysFdType;
#endif
-#ifdef ERTS_INLINE
-# ifndef ERTS_CAN_INLINE
-# define ERTS_CAN_INLINE 1
-# endif
-#else
-# if defined(__GNUC__)
-# define ERTS_CAN_INLINE 1
-# define ERTS_INLINE __inline__
-# elif defined(__WIN32__)
-# define ERTS_CAN_INLINE 1
-# define ERTS_INLINE __inline
-# else
-# define ERTS_CAN_INLINE 0
-# define ERTS_INLINE
-# endif
-#endif
-
#if !defined(__GNUC__)
# define ERTS_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) 0
#elif !defined(__GNUC_MINOR__)
@@ -132,24 +151,8 @@ typedef ERTS_SYS_FD_TYPE ErtsSysFdType;
# endif
#endif
-#if defined(DEBUG) || defined(ERTS_ENABLE_LOCK_CHECK)
-# undef ERTS_CAN_INLINE
-# define ERTS_CAN_INLINE 0
-# undef ERTS_INLINE
-# define ERTS_INLINE
-#endif
-
-#if ERTS_CAN_INLINE
-#define ERTS_GLB_INLINE static ERTS_INLINE
-#else
-#define ERTS_GLB_INLINE
-#endif
-
-#if ERTS_CAN_INLINE || defined(ERTS_DO_INCL_GLB_INLINE_FUNC_DEF)
-# define ERTS_GLB_INLINE_INCL_FUNC_DEF 1
-#else
-# define ERTS_GLB_INLINE_INCL_FUNC_DEF 0
-#endif
+#define ERTS_MK_VSN_INT(Major, Minor, Build) \
+ ((((Major) & 0x3ff) << 20) | (((Minor) & 0x3ff) << 10) | ((Build) & 0x3ff))
#ifndef ERTS_EXIT_AFTER_DUMP
# define ERTS_EXIT_AFTER_DUMP exit
@@ -188,6 +191,32 @@ __decl_noreturn void __noreturn erl_assert_error(const char* expr, const char *f
# define ASSERT(e) ((void) 1)
#endif
+/* ERTS_UNDEF can be used to silence false warnings about
+ * "variable may be used uninitialized" while keeping the variable
+ * marked as undefined by valgrind.
+ */
+#ifdef VALGRIND
+# define ERTS_UNDEF(V,I)
+#else
+# define ERTS_UNDEF(V,I) V = I
+#endif
+
+/*
+ * Compile time assert
+ * (the actual compiler error msg can be a bit confusing)
+ */
+#if ERTS_AT_LEAST_GCC_VSN__(3,1,1)
+# define ERTS_CT_ASSERT(e) \
+ do { \
+ enum { compile_time_assert__ = __builtin_choose_expr((e),0,(void)0) }; \
+ } while(0)
+#else
+# define ERTS_CT_ASSERT(e) \
+ do { \
+ enum { compile_time_assert__ = 1/(e) }; \
+ } while (0)
+#endif
+
/*
* Microsoft C/C++: We certainly want to use stdarg.h and prototypes.
* But MSC doesn't define __STDC__, unless we compile with the -Za
@@ -359,17 +388,45 @@ typedef Sint SWord;
typedef UWord BeamInstr;
#ifndef HAVE_INT64
-#if SIZEOF_LONG == 8
-#define HAVE_INT64 1
+# if SIZEOF_LONG == 8
+# define HAVE_INT64 1
typedef unsigned long Uint64;
typedef long Sint64;
-#elif SIZEOF_LONG_LONG == 8
-#define HAVE_INT64 1
+# ifdef ULONG_MAX
+# define ERTS_UINT64_MAX ULONG_MAX
+# endif
+# ifdef LONG_MAX
+# define ERTS_SINT64_MAX LONG_MAX
+# endif
+# ifdef LONG_MIN
+# define ERTS_SINT64_MIN LONG_MIN
+# endif
+# elif SIZEOF_LONG_LONG == 8
+# define HAVE_INT64 1
typedef unsigned long long Uint64;
typedef long long Sint64;
-#else
-#define HAVE_INT64 0
+# ifdef ULLONG_MAX
+# define ERTS_UINT64_MAX ULLONG_MAX
+# endif
+# ifdef LLONG_MAX
+# define ERTS_SINT64_MAX LLONG_MAX
+# endif
+# ifdef LLONG_MIN
+# define ERTS_SINT64_MIN LLONG_MIN
+# endif
+# else
+# error "No 64-bit integer type found"
+# endif
+#endif
+
+#ifndef ERTS_UINT64_MAX
+# define ERTS_UINT64_MAX (~((Uint64) 0))
+#endif
+#ifndef ERTS_SINT64_MAX
+# define ERTS_SINT64_MAX ((Sint64) ((((Uint64) 1) << 63)-1))
#endif
+#ifndef ERTS_SINT64_MIN
+# define ERTS_SINT64_MIN (-1*(((Sint64) 1) << 63))
#endif
#if SIZEOF_LONG == 4
@@ -554,15 +611,16 @@ static unsigned long zero_value = 0, one_value = 1;
# endif /* !__WIN32__ */
#endif /* WANT_NONBLOCKING */
-__decl_noreturn void __noreturn erl_exit(int n, char*, ...);
+__decl_noreturn void __noreturn erts_exit(int n, char*, ...);
-/* Some special erl_exit() codes: */
-#define ERTS_INTR_EXIT INT_MIN /* called from signal handler */
-#define ERTS_ABORT_EXIT (INT_MIN + 1) /* no crash dump; only abort() */
-#define ERTS_DUMP_EXIT (INT_MIN + 2) /* crash dump; then exit() */
+/* Some special erts_exit() codes: */
+#define ERTS_INTR_EXIT -1 /* called from signal handler */
+#define ERTS_ABORT_EXIT -2 /* no crash dump; only abort() */
+#define ERTS_DUMP_EXIT -3 /* crash dump; then exit() */
+#define ERTS_ERROR_EXIT -4 /* crash dump; then abort() */
#define ERTS_INTERNAL_ERROR(What) \
- erl_exit(ERTS_ABORT_EXIT, "%s:%d:%s(): Internal error: %s\n", \
+ erts_exit(ERTS_ABORT_EXIT, "%s:%d:%s(): Internal error: %s\n", \
__FILE__, __LINE__, __func__, What)
Eterm erts_check_io_info(void *p);
@@ -577,7 +635,6 @@ Uint erts_sys_misc_mem_sz(void);
/* Io constants to erts_print and erts_putc */
#define ERTS_PRINT_STDERR (2)
#define ERTS_PRINT_STDOUT (1)
-#define ERTS_PRINT_INVALID (0) /* Don't want to use 0 since CBUF was 0 */
#define ERTS_PRINT_FILE (-1)
#define ERTS_PRINT_SBUF (-2)
#define ERTS_PRINT_SNBUF (-3)
@@ -600,6 +657,7 @@ erts_dsprintf_buf_t *erts_create_logger_dsbuf(void);
int erts_send_info_to_logger(Eterm, erts_dsprintf_buf_t *);
int erts_send_warning_to_logger(Eterm, erts_dsprintf_buf_t *);
int erts_send_error_to_logger(Eterm, erts_dsprintf_buf_t *);
+int erts_send_error_term_to_logger(Eterm, erts_dsprintf_buf_t *, Eterm);
int erts_send_info_to_logger_str(Eterm, char *);
int erts_send_warning_to_logger_str(Eterm, char *);
int erts_send_error_to_logger_str(Eterm, char *);
@@ -646,14 +704,37 @@ extern char *erts_default_arg0;
extern char os_type[];
-extern int sys_init_time(void);
+typedef struct {
+ int have_os_monotonic_time;
+ int have_corrected_os_monotonic_time;
+ ErtsMonotonicTime os_monotonic_time_unit;
+ ErtsMonotonicTime sys_clock_resolution;
+ struct {
+ Uint64 resolution;
+ char *func;
+ char *clock_id;
+ int locked_use;
+ int extended;
+ } os_monotonic_time_info;
+ struct {
+ Uint64 resolution;
+ char *func;
+ char *clock_id;
+ int locked_use;
+ } os_system_time_info;
+} ErtsSysInitTimeResult;
+
+#define ERTS_SYS_INIT_TIME_RESULT_INITER \
+ {0, 0, (ErtsMonotonicTime) -1, (ErtsMonotonicTime) 1}
+
+extern void erts_init_sys_time_sup(void);
+extern void sys_init_time(ErtsSysInitTimeResult *);
+extern void erts_late_sys_init_time(void);
extern void erts_deliver_time(void);
extern void erts_time_remaining(SysTimeval *);
-extern int erts_init_time_sup(void);
extern void erts_sys_init_float(void);
extern void erts_thread_init_float(void);
extern void erts_thread_disable_fpe(void);
-
ERTS_GLB_INLINE int erts_block_fpe(void);
ERTS_GLB_INLINE void erts_unblock_fpe(int);
@@ -696,11 +777,9 @@ extern char *erts_sys_ddll_error(int code);
/*
* System interfaces for startup.
*/
-#include "erl_time.h"
-
void erts_sys_schedule_interrupt(int set);
#ifdef ERTS_SMP
-void erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec);
+void erts_sys_schedule_interrupt_timed(int, ErtsMonotonicTime);
void erts_sys_main_thread(void);
#endif
@@ -739,6 +818,12 @@ int univ_to_local(
int local_to_univ(Sint *year, Sint *month, Sint *day,
Sint *hour, Sint *minute, Sint *second, int isdst);
void get_now(Uint*, Uint*, Uint*);
+struct ErtsSchedulerData_;
+ErtsMonotonicTime erts_get_monotonic_time(struct ErtsSchedulerData_ *);
+ErtsMonotonicTime erts_get_time_offset(void);
+void
+erts_make_timestamp_value(Uint* megasec, Uint* sec, Uint* microsec,
+ ErtsMonotonicTime mtime, ErtsMonotonicTime offset);
void get_sys_now(Uint*, Uint*, Uint*);
void set_break_quit(void (*)(void), void (*)(void));
@@ -756,6 +841,8 @@ typedef struct {
} ErtsCheckIoDebugInfo;
int erts_check_io_debug(ErtsCheckIoDebugInfo *ip);
+int erts_sys_is_area_readable(char *start, char *stop);
+
/* xxxP */
#define SYS_DEFAULT_FLOAT_DECIMALS 20
void init_sys_float(void);
@@ -784,6 +871,11 @@ int erts_sys_unsetenv(char *key);
char *erts_read_env(char *key);
void erts_free_read_env(void *value);
+#if defined(ERTS_THR_HAVE_SIG_FUNCS) && !defined(ETHR_UNUSABLE_SIGUSRX)
+extern void sys_thr_resume(erts_tid_t tid);
+extern void sys_thr_suspend(erts_tid_t tid);
+#endif
+
/* utils.c */
/* Options to sys_alloc_opt */
@@ -842,7 +934,7 @@ erts_refc_inc(erts_refc_t *refcp, erts_aint_t min_val)
#ifdef ERTS_REFC_DEBUG
erts_aint_t val = erts_smp_atomic_inc_read_nob((erts_smp_atomic_t *) refcp);
if (val < min_val)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_refc_inc(): Bad refc found (refc=%ld < %ld)!\n",
val, min_val);
#else
@@ -856,7 +948,7 @@ erts_refc_inctest(erts_refc_t *refcp, erts_aint_t min_val)
erts_aint_t val = erts_smp_atomic_inc_read_nob((erts_smp_atomic_t *) refcp);
#ifdef ERTS_REFC_DEBUG
if (val < min_val)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_refc_inctest(): Bad refc found (refc=%ld < %ld)!\n",
val, min_val);
#endif
@@ -869,7 +961,7 @@ erts_refc_dec(erts_refc_t *refcp, erts_aint_t min_val)
#ifdef ERTS_REFC_DEBUG
erts_aint_t val = erts_smp_atomic_dec_read_nob((erts_smp_atomic_t *) refcp);
if (val < min_val)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_refc_dec(): Bad refc found (refc=%ld < %ld)!\n",
val, min_val);
#else
@@ -883,7 +975,7 @@ erts_refc_dectest(erts_refc_t *refcp, erts_aint_t min_val)
erts_aint_t val = erts_smp_atomic_dec_read_nob((erts_smp_atomic_t *) refcp);
#ifdef ERTS_REFC_DEBUG
if (val < min_val)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_refc_dectest(): Bad refc found (refc=%ld < %ld)!\n",
val, min_val);
#endif
@@ -896,7 +988,7 @@ erts_refc_add(erts_refc_t *refcp, erts_aint_t diff, erts_aint_t min_val)
#ifdef ERTS_REFC_DEBUG
erts_aint_t val = erts_smp_atomic_add_read_nob((erts_smp_atomic_t *) refcp, diff);
if (val < min_val)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_refc_add(%ld): Bad refc found (refc=%ld < %ld)!\n",
diff, val, min_val);
#else
@@ -910,7 +1002,7 @@ erts_refc_read(erts_refc_t *refcp, erts_aint_t min_val)
erts_aint_t val = erts_smp_atomic_read_nob((erts_smp_atomic_t *) refcp);
#ifdef ERTS_REFC_DEBUG
if (val < min_val)
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"erts_refc_read(): Bad refc found (refc=%ld < %ld)!\n",
val, min_val);
#endif
diff --git a/erts/emulator/beam/time.c b/erts/emulator/beam/time.c
index 2fd8e0cf00..988338ed81 100644
--- a/erts/emulator/beam/time.c
+++ b/erts/emulator/beam/time.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -76,6 +77,11 @@
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
+
+#define ERTS_MONOTONIC_DAY ERTS_SEC_TO_MONOTONIC(60*60*24)
+#define ERTS_CLKTCKS_DAY ERTS_MONOTONIC_TO_CLKTCKS(ERTS_MONOTONIC_DAY)
#ifdef ERTS_ENABLE_LOCK_CHECK
#define ASSERT_NO_LOCKED_LOCKS erts_lc_check_exact(NULL, 0)
@@ -83,26 +89,25 @@
#define ASSERT_NO_LOCKED_LOCKS
#endif
-static erts_smp_mtx_t tiw_lock;
-
-
-/* BEGIN tiw_lock protected variables
-**
-** The individual timer cells in tiw are also protected by the same mutex.
-*/
+#if 0
+# define ERTS_TW_DEBUG
+#endif
+#if defined(DEBUG) && !defined(ERTS_TW_DEBUG)
+# define ERTS_TW_DEBUG
+#endif
-#ifdef SMALL_MEMORY
-#define TIW_SIZE 8192
+#undef ERTS_TW_ASSERT
+#if defined(ERTS_TW_DEBUG)
+# define ERTS_TW_ASSERT(E) ERTS_ASSERT(E)
#else
-#define TIW_SIZE 65536 /* timing wheel size (should be a power of 2) */
+# define ERTS_TW_ASSERT(E) ((void) 1)
#endif
-static ErlTimer** tiw; /* the timing wheel, allocated in init_time() */
-static Uint tiw_pos; /* current position in wheel */
-static Uint tiw_nto; /* number of timeouts in wheel */
-static Uint tiw_min;
-static ErlTimer *tiw_min_ptr;
-/* END tiw_lock protected variables */
+#ifdef ERTS_TW_DEBUG
+# define ERTS_TWHEEL_BUMP_YIELD_LIMIT 5
+#else
+# define ERTS_TWHEEL_BUMP_YIELD_LIMIT 100
+#endif
/* Actual interval time chosen by sys_init_time() */
@@ -114,392 +119,580 @@ static int tiw_itime; /* Constant after init */
# define TIW_ITIME tiw_itime
#endif
-erts_smp_atomic32_t do_time; /* set at clock interrupt */
-static ERTS_INLINE erts_short_time_t do_time_read(void)
-{
- return erts_smp_atomic32_read_acqb(&do_time);
-}
-
-static ERTS_INLINE erts_short_time_t do_time_update(void)
+struct ErtsTimerWheel_ {
+ ErtsTWheelTimer *w[ERTS_TIW_SIZE];
+ ErtsMonotonicTime pos;
+ Uint nto;
+ struct {
+ ErtsTWheelTimer *head;
+ ErtsTWheelTimer *tail;
+ Uint nto;
+ } at_once;
+ int yield_slot;
+ int yield_slots_left;
+ int yield_start_pos;
+ ErtsTWheelTimer sentinel;
+ int true_next_timeout_time;
+ ErtsMonotonicTime next_timeout_time;
+};
+
+static ERTS_INLINE ErtsMonotonicTime
+find_next_timeout(ErtsSchedulerData *esdp,
+ ErtsTimerWheel *tiw,
+ int search_all,
+ ErtsMonotonicTime curr_time, /* When !search_all */
+ ErtsMonotonicTime max_search_time) /* When !search_all */
{
- return do_time_read();
-}
-
-static ERTS_INLINE void do_time_init(void)
-{
- erts_smp_atomic32_init_nob(&do_time, 0);
-}
+ int start_ix, tiw_pos_ix;
+ ErtsTWheelTimer *p;
+ int true_min_timeout = 0;
+ ErtsMonotonicTime min_timeout, min_timeout_pos, slot_timeout_pos;
+
+ if (tiw->nto == 0) { /* no timeouts in wheel */
+ if (!search_all)
+ min_timeout_pos = tiw->pos;
+ else {
+ curr_time = erts_get_monotonic_time(esdp);
+ tiw->pos = min_timeout_pos = ERTS_MONOTONIC_TO_CLKTCKS(curr_time);
+ }
+ min_timeout_pos += ERTS_MONOTONIC_TO_CLKTCKS(ERTS_MONOTONIC_DAY);
+ goto found_next;
+ }
-/* get the time (in units of TIW_ITIME) to the next timeout,
- or -1 if there are no timeouts */
+ slot_timeout_pos = min_timeout_pos = tiw->pos;
+ if (search_all)
+ min_timeout_pos += ERTS_MONOTONIC_TO_CLKTCKS(ERTS_MONOTONIC_DAY);
+ else
+ min_timeout_pos = ERTS_MONOTONIC_TO_CLKTCKS(curr_time + max_search_time);
-static erts_short_time_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
-{
- int i, tm, nto;
- Uint32 min;
- ErlTimer* p;
- erts_short_time_t dt;
-
- if (tiw_nto == 0)
- return -1; /* no timeouts in wheel */
+ start_ix = tiw_pos_ix = (int) (tiw->pos & (ERTS_TIW_SIZE-1));
- if (tiw_min_ptr) {
- min = tiw_min;
- dt = do_time_read();
- return ((min >= dt) ? (min - dt) : 0);
- }
-
- /* start going through wheel to find next timeout */
- tm = nto = 0;
- min = (Uint32) -1; /* max Uint32 */
- i = tiw_pos;
do {
- p = tiw[i];
- while (p != NULL) {
- nto++;
- if (p->count == 0) {
- /* found next timeout */
- dt = do_time_read();
- /* p->count is zero */
- tiw_min_ptr = p;
- tiw_min = tm;
- return ((tm >= dt) ? (tm - dt) : 0);
- } else {
- /* keep shortest time in 'min' */
- if (tm + p->count*TIW_SIZE < min) {
- min = tm + p->count*TIW_SIZE;
- tiw_min_ptr = p;
- tiw_min = min;
+ if (++slot_timeout_pos >= min_timeout_pos)
+ break;
+
+ p = tiw->w[tiw_pos_ix];
+
+ if (p) {
+ ErtsTWheelTimer *end = p;
+
+ do {
+ ErtsMonotonicTime timeout_pos;
+ timeout_pos = p->timeout_pos;
+ if (min_timeout_pos > timeout_pos) {
+ true_min_timeout = 1;
+ min_timeout_pos = timeout_pos;
+ if (min_timeout_pos <= slot_timeout_pos)
+ goto found_next;
}
- }
- p = p->next;
+ p = p->next;
+ } while (p != end);
}
- /* when we have found all timeouts the shortest time will be in min */
- if (nto == tiw_nto) break;
- tm++;
- i = (i + 1) % TIW_SIZE;
- } while (i != tiw_pos);
- dt = do_time_read();
- if (min <= (Uint32) dt)
- return 0;
- if ((min - (Uint32) dt) > (Uint32) ERTS_SHORT_TIME_T_MAX)
- return ERTS_SHORT_TIME_T_MAX;
- return (erts_short_time_t) (min - (Uint32) dt);
+
+ tiw_pos_ix++;
+ if (tiw_pos_ix == ERTS_TIW_SIZE)
+ tiw_pos_ix = 0;
+ } while (start_ix != tiw_pos_ix);
+
+found_next:
+
+ min_timeout = ERTS_CLKTCKS_TO_MONOTONIC(min_timeout_pos);
+ tiw->next_timeout_time = min_timeout;
+ tiw->true_next_timeout_time = true_min_timeout;
+
+ return min_timeout;
}
-static void remove_timer(ErlTimer *p) {
- /* first */
- if (!p->prev) {
- tiw[p->slot] = p->next;
- if(p->next)
- p->next->prev = NULL;
- } else {
- p->prev->next = p->next;
+static ERTS_INLINE void
+insert_timer_into_slot(ErtsTimerWheel *tiw, int slot, ErtsTWheelTimer *p)
+{
+ ERTS_TW_ASSERT(slot >= 0);
+ ERTS_TW_ASSERT(slot < ERTS_TIW_SIZE);
+ p->slot = slot;
+ if (!tiw->w[slot]) {
+ tiw->w[slot] = p;
+ p->next = p;
+ p->prev = p;
+ }
+ else {
+ ErtsTWheelTimer *next, *prev;
+ next = tiw->w[slot];
+ prev = next->prev;
+ p->next = next;
+ p->prev = prev;
+ prev->next = p;
+ next->prev = p;
}
+}
- /* last */
- if (!p->next) {
+static ERTS_INLINE void
+remove_timer(ErtsTimerWheel *tiw, ErtsTWheelTimer *p)
+{
+ int slot = p->slot;
+ ERTS_TW_ASSERT(slot != ERTS_TWHEEL_SLOT_INACTIVE);
+
+ if (slot >= 0) {
+ /*
+ * Timer in wheel or in circular
+ * list of timers currently beeing
+ * triggered (referred by sentinel).
+ */
+ ERTS_TW_ASSERT(slot < ERTS_TIW_SIZE);
+
+ if (p->next == p) {
+ ERTS_TW_ASSERT(tiw->w[slot] == p);
+ tiw->w[slot] = NULL;
+ }
+ else {
+ if (tiw->w[slot] == p)
+ tiw->w[slot] = p->next;
+ p->prev->next = p->next;
+ p->next->prev = p->prev;
+ }
+ }
+ else {
+ /* Timer in "at once" queue... */
+ ERTS_TW_ASSERT(slot == ERTS_TWHEEL_SLOT_AT_ONCE);
if (p->prev)
- p->prev->next = NULL;
- } else {
- p->next->prev = p->prev;
+ p->prev->next = p->next;
+ else {
+ ERTS_TW_ASSERT(tiw->at_once.head == p);
+ tiw->at_once.head = p->next;
+ }
+ if (p->next)
+ p->next->prev = p->prev;
+ else {
+ ERTS_TW_ASSERT(tiw->at_once.tail == p);
+ tiw->at_once.tail = p->prev;
+ }
+ ERTS_TW_ASSERT(tiw->at_once.nto > 0);
+ tiw->at_once.nto--;
}
- p->next = NULL;
- p->prev = NULL;
- /* Make sure cancel callback isn't called */
- p->active = 0;
- tiw_nto--;
+ p->slot = ERTS_TWHEEL_SLOT_INACTIVE;
+
+ tiw->nto--;
}
-/* Private export to erl_time_sup.c */
-erts_short_time_t erts_next_time(void)
+ErtsMonotonicTime
+erts_check_next_timeout_time(ErtsSchedulerData *esdp)
{
- erts_short_time_t ret;
+ ErtsTimerWheel *tiw = esdp->timer_wheel;
+ if (tiw->true_next_timeout_time)
+ return tiw->next_timeout_time;
+ return find_next_timeout(esdp, tiw, 1, 0, 0);
+}
+
+#ifndef ERTS_TW_DEBUG
+#define ERTS_DBG_CHK_SAFE_TO_SKIP_TO(TIW, TO) ((void) 0)
+#else
+#define ERTS_DBG_CHK_SAFE_TO_SKIP_TO(TIW, TO) debug_check_safe_to_skip_to((TIW), (TO))
+static void
+debug_check_safe_to_skip_to(ErtsTimerWheel *tiw, ErtsMonotonicTime skip_to_pos)
+{
+ int slots, ix;
+ ErtsTWheelTimer *tmr;
+ ErtsMonotonicTime tmp;
+
+ ix = (int) (tiw->pos & (ERTS_TIW_SIZE-1));
+ tmp = skip_to_pos - tiw->pos;
+ ERTS_TW_ASSERT(tmp >= 0);
+ if (tmp < (ErtsMonotonicTime) ERTS_TIW_SIZE)
+ slots = (int) tmp;
+ else
+ slots = ERTS_TIW_SIZE;
+
+ while (slots > 0) {
+ tmr = tiw->w[ix];
+ if (tmr) {
+ ErtsTWheelTimer *end = tmr;
+ do {
+ ERTS_TW_ASSERT(tmr->timeout_pos > skip_to_pos);
+ tmr = tmr->next;
+ } while (tmr != end);
+ }
+ ix++;
+ if (ix == ERTS_TIW_SIZE)
+ ix = 0;
+ slots--;
+ }
+}
+#endif
- erts_smp_mtx_lock(&tiw_lock);
- (void)do_time_update();
- ret = next_time_internal();
- erts_smp_mtx_unlock(&tiw_lock);
- return ret;
+static ERTS_INLINE void
+timeout_timer(ErtsTWheelTimer *p)
+{
+ ErlTimeoutProc timeout;
+ void *arg;
+ p->slot = ERTS_TWHEEL_SLOT_INACTIVE;
+ timeout = p->u.func.timeout;
+ arg = p->u.func.arg;
+ (*timeout)(arg);
+ ASSERT_NO_LOCKED_LOCKS;
}
-static ERTS_INLINE void bump_timer_internal(erts_short_time_t dt) /* PRE: tiw_lock is write-locked */
+void
+erts_bump_timers(ErtsTimerWheel *tiw, ErtsMonotonicTime curr_time)
{
- Uint keep_pos;
- Uint count;
- ErlTimer *p, **prev, *timeout_head, **timeout_tail;
- Uint dtime = (Uint) dt;
-
- /* no need to bump the position if there aren't any timeouts */
- if (tiw_nto == 0) {
- erts_smp_mtx_unlock(&tiw_lock);
- return;
+ int tiw_pos_ix, slots, yielded_slot_restarted, yield_count;
+ ErtsMonotonicTime bump_to, tmp_slots, old_pos;
+
+ yield_count = ERTS_TWHEEL_BUMP_YIELD_LIMIT;
+
+ /*
+ * In order to be fair we always continue with work
+ * where we left off when restarting after a yield.
+ */
+
+ if (tiw->yield_slot >= 0) {
+ yielded_slot_restarted = 1;
+ tiw_pos_ix = tiw->yield_slot;
+ slots = tiw->yield_slots_left;
+ bump_to = tiw->pos;
+ old_pos = tiw->yield_start_pos;
+ goto restart_yielded_slot;
}
- /* if do_time > TIW_SIZE we want to go around just once */
- count = (Uint)(dtime / TIW_SIZE) + 1;
- keep_pos = (tiw_pos + dtime) % TIW_SIZE;
- if (dtime > TIW_SIZE) dtime = TIW_SIZE;
-
- timeout_head = NULL;
- timeout_tail = &timeout_head;
- while (dtime > 0) {
- /* this is to decrease the counters with the right amount */
- /* when dtime >= TIW_SIZE */
- if (tiw_pos == keep_pos) count--;
- prev = &tiw[tiw_pos];
- while ((p = *prev) != NULL) {
- ASSERT( p != p->next);
- if (p->count < count) { /* we have a timeout */
- /* remove min time */
- if (tiw_min_ptr == p) {
- tiw_min_ptr = NULL;
- tiw_min = 0;
+ do {
+
+ yielded_slot_restarted = 0;
+
+ bump_to = ERTS_MONOTONIC_TO_CLKTCKS(curr_time);
+
+ while (1) {
+ ErtsTWheelTimer *p;
+
+ old_pos = tiw->pos;
+
+ if (tiw->nto == 0) {
+ empty_wheel:
+ ERTS_DBG_CHK_SAFE_TO_SKIP_TO(tiw, bump_to);
+ tiw->true_next_timeout_time = 0;
+ tiw->next_timeout_time = curr_time + ERTS_MONOTONIC_DAY;
+ tiw->pos = bump_to;
+ tiw->yield_slot = ERTS_TWHEEL_SLOT_INACTIVE;
+ return;
+ }
+
+ p = tiw->at_once.head;
+ while (p) {
+ if (--yield_count <= 0) {
+ ERTS_TW_ASSERT(tiw->nto > 0);
+ ERTS_TW_ASSERT(tiw->at_once.nto > 0);
+ tiw->yield_slot = ERTS_TWHEEL_SLOT_AT_ONCE;
+ tiw->true_next_timeout_time = 1;
+ tiw->next_timeout_time = ERTS_CLKTCKS_TO_MONOTONIC(old_pos);
+ return;
}
- /* Remove from list */
- remove_timer(p);
- *timeout_tail = p; /* Insert in timeout queue */
- timeout_tail = &p->next;
+ ERTS_TW_ASSERT(tiw->nto > 0);
+ ERTS_TW_ASSERT(tiw->at_once.nto > 0);
+ tiw->nto--;
+ tiw->at_once.nto--;
+ tiw->at_once.head = p->next;
+ if (p->next)
+ p->next->prev = NULL;
+ else
+ tiw->at_once.tail = NULL;
+
+ timeout_timer(p);
+
+ p = tiw->at_once.head;
}
- else {
- /* no timeout, just decrease counter */
- p->count -= count;
- prev = &p->next;
+
+ if (tiw->pos >= bump_to)
+ break;
+
+ if (tiw->nto == 0)
+ goto empty_wheel;
+
+ if (tiw->true_next_timeout_time) {
+ ErtsMonotonicTime skip_until_pos;
+ /*
+ * No need inspecting slots where we know no timeouts
+ * to trigger should reside.
+ */
+
+ skip_until_pos = ERTS_MONOTONIC_TO_CLKTCKS(tiw->next_timeout_time);
+ if (skip_until_pos > bump_to)
+ skip_until_pos = bump_to;
+
+ skip_until_pos--;
+
+ if (skip_until_pos > tiw->pos) {
+ ERTS_DBG_CHK_SAFE_TO_SKIP_TO(tiw, skip_until_pos);
+
+ tiw->pos = skip_until_pos;
+ }
+ }
+
+ tiw_pos_ix = (int) ((tiw->pos+1) & (ERTS_TIW_SIZE-1));
+ tmp_slots = (bump_to - tiw->pos);
+ if (tmp_slots < (ErtsMonotonicTime) ERTS_TIW_SIZE)
+ slots = (int) tmp_slots;
+ else
+ slots = ERTS_TIW_SIZE;
+
+ tiw->pos = bump_to;
+
+ while (slots > 0) {
+
+ p = tiw->w[tiw_pos_ix];
+ if (p) {
+ if (p->next == p) {
+ ERTS_TW_ASSERT(tiw->sentinel.next == &tiw->sentinel);
+ ERTS_TW_ASSERT(tiw->sentinel.prev == &tiw->sentinel);
+ }
+ else {
+ tiw->sentinel.next = p->next;
+ tiw->sentinel.prev = p->prev;
+ tiw->sentinel.next->prev = &tiw->sentinel;
+ tiw->sentinel.prev->next = &tiw->sentinel;
+ }
+ tiw->w[tiw_pos_ix] = NULL;
+
+ while (1) {
+
+ if (p->timeout_pos > bump_to) {
+ /* Very unusual case... */
+ ++yield_count;
+ insert_timer_into_slot(tiw, tiw_pos_ix, p);
+ }
+ else {
+ /* Normal case... */
+ timeout_timer(p);
+ tiw->nto--;
+ }
+
+ restart_yielded_slot:
+
+ p = tiw->sentinel.next;
+ if (p == &tiw->sentinel) {
+ ERTS_TW_ASSERT(tiw->sentinel.prev == &tiw->sentinel);
+ break;
+ }
+
+ if (--yield_count <= 0) {
+ tiw->true_next_timeout_time = 1;
+ tiw->next_timeout_time = ERTS_CLKTCKS_TO_MONOTONIC(old_pos);
+ tiw->yield_slot = tiw_pos_ix;
+ tiw->yield_slots_left = slots;
+ tiw->yield_start_pos = old_pos;
+ return; /* Yield! */
+ }
+
+ tiw->sentinel.next = p->next;
+ p->next->prev = &tiw->sentinel;
+ }
+ }
+ tiw_pos_ix++;
+ if (tiw_pos_ix == ERTS_TIW_SIZE)
+ tiw_pos_ix = 0;
+ slots--;
}
}
- tiw_pos = (tiw_pos + 1) % TIW_SIZE;
- dtime--;
- }
- tiw_pos = keep_pos;
- if (tiw_min_ptr)
- tiw_min -= dt;
-
- erts_smp_mtx_unlock(&tiw_lock);
-
- /* Call timedout timers callbacks */
- while (timeout_head) {
- p = timeout_head;
- timeout_head = p->next;
- /* Here comes hairy use of the timer fields!
- * They are reset without having the lock.
- * It is assumed that no code but this will
- * accesses any field until the ->timeout
- * callback is called.
- */
- p->next = NULL;
- p->prev = NULL;
- p->slot = 0;
- (*p->timeout)(p->arg);
- }
-}
-void erts_bump_timer(erts_short_time_t dt) /* dt is value from do_time */
-{
- erts_smp_mtx_lock(&tiw_lock);
- bump_timer_internal(dt);
+ } while (yielded_slot_restarted);
+
+ tiw->yield_slot = ERTS_TWHEEL_SLOT_INACTIVE;
+ tiw->true_next_timeout_time = 0;
+ tiw->next_timeout_time = curr_time + ERTS_MONOTONIC_DAY;
+
+ /* Search at most two seconds ahead... */
+ (void) find_next_timeout(NULL, tiw, 0, curr_time, ERTS_SEC_TO_MONOTONIC(2));
}
Uint
erts_timer_wheel_memory_size(void)
{
- return (Uint) TIW_SIZE * sizeof(ErlTimer*);
+ return sizeof(ErtsTimerWheel)*erts_no_schedulers;
+}
+
+ErtsTimerWheel *
+erts_create_timer_wheel(ErtsSchedulerData *esdp)
+{
+ ErtsMonotonicTime mtime;
+ int i;
+ ErtsTimerWheel *tiw;
+ tiw = erts_alloc_permanent_cache_aligned(ERTS_ALC_T_TIMER_WHEEL,
+ sizeof(ErtsTimerWheel));
+ for(i = 0; i < ERTS_TIW_SIZE; i++)
+ tiw->w[i] = NULL;
+
+ mtime = erts_get_monotonic_time(esdp);
+ tiw->pos = ERTS_MONOTONIC_TO_CLKTCKS(mtime);
+ tiw->nto = 0;
+ tiw->at_once.head = NULL;
+ tiw->at_once.tail = NULL;
+ tiw->at_once.nto = 0;
+ tiw->yield_slot = ERTS_TWHEEL_SLOT_INACTIVE;
+ tiw->true_next_timeout_time = 0;
+ tiw->next_timeout_time = mtime + ERTS_MONOTONIC_DAY;
+ tiw->sentinel.next = &tiw->sentinel;
+ tiw->sentinel.prev = &tiw->sentinel;
+ tiw->sentinel.u.func.timeout = NULL;
+ tiw->sentinel.u.func.cancel = NULL;
+ tiw->sentinel.u.func.arg = NULL;
+ return tiw;
+}
+
+ErtsNextTimeoutRef
+erts_get_next_timeout_reference(ErtsTimerWheel *tiw)
+{
+ return (ErtsNextTimeoutRef) &tiw->next_timeout_time;
}
+
/* this routine links the time cells into a free list at the start
and sets the time queue as empty */
void
-erts_init_time(void)
+erts_init_time(int time_correction, ErtsTimeWarpMode time_warp_mode)
{
- int i, itime;
+ int itime;
/* system dependent init; must be done before do_time_init()
if timer thread is enabled */
- itime = erts_init_time_sup();
+ itime = erts_init_time_sup(time_correction, time_warp_mode);
#ifdef TIW_ITIME_IS_CONSTANT
if (itime != TIW_ITIME) {
- erl_exit(ERTS_ABORT_EXIT, "timer resolution mismatch %d != %d", itime, TIW_ITIME);
+ erts_exit(ERTS_ABORT_EXIT, "timer resolution mismatch %d != %d", itime, TIW_ITIME);
}
#else
tiw_itime = itime;
#endif
+}
- erts_smp_mtx_init(&tiw_lock, "timer_wheel");
+void
+erts_twheel_set_timer(ErtsTimerWheel *tiw,
+ ErtsTWheelTimer *p, ErlTimeoutProc timeout,
+ ErlCancelProc cancel, void *arg,
+ ErtsMonotonicTime timeout_pos)
+{
+ ErtsMonotonicTime timeout_time;
- tiw = (ErlTimer**) erts_alloc(ERTS_ALC_T_TIMER_WHEEL,
- TIW_SIZE * sizeof(ErlTimer*));
- for(i = 0; i < TIW_SIZE; i++)
- tiw[i] = NULL;
- do_time_init();
- tiw_pos = tiw_nto = 0;
- tiw_min_ptr = NULL;
- tiw_min = 0;
-}
+ p->u.func.timeout = timeout;
+ p->u.func.cancel = cancel;
+ p->u.func.arg = arg;
+ ERTS_TW_ASSERT(p->slot == ERTS_TWHEEL_SLOT_INACTIVE);
+ if (timeout_pos <= tiw->pos) {
+ tiw->nto++;
+ tiw->at_once.nto++;
+ p->next = NULL;
+ p->prev = tiw->at_once.tail;
+ if (tiw->at_once.tail) {
+ ERTS_TW_ASSERT(tiw->at_once.head);
+ tiw->at_once.tail->next = p;
+ }
+ else {
+ ERTS_TW_ASSERT(!tiw->at_once.head);
+ tiw->at_once.head = p;
+ }
+ tiw->at_once.tail = p;
+ p->timeout_pos = tiw->pos;
+ p->slot = ERTS_TWHEEL_SLOT_AT_ONCE;
+ timeout_time = ERTS_CLKTCKS_TO_MONOTONIC(tiw->pos);
+ }
+ else {
+ int slot;
+ /* calculate slot */
+ slot = (int) (timeout_pos & (ERTS_TIW_SIZE-1));
-/*
-** Insert a process into the time queue, with a timeout 't'
-*/
-static void
-insert_timer(ErlTimer* p, Uint t)
-{
- Uint tm;
- Uint64 ticks;
+ insert_timer_into_slot(tiw, slot, p);
- /* The current slot (tiw_pos) in timing wheel is the next slot to be
- * be processed. Hence no extra time tick is needed.
- *
- * (x + y - 1)/y is precisely the "number of bins" formula.
- */
- ticks = (t + (TIW_ITIME - 1)) / TIW_ITIME;
+ tiw->nto++;
- /*
- * Ticks must be a Uint64, or the addition may overflow here,
- * resulting in an incorrect value for p->count below.
- */
- ticks += do_time_update(); /* Add backlog of unprocessed time */
-
- /* calculate slot */
- tm = (ticks + tiw_pos) % TIW_SIZE;
- p->slot = (Uint) tm;
- p->count = (Uint) (ticks / TIW_SIZE);
-
- /* insert at head of list at slot */
- p->next = tiw[tm];
- p->prev = NULL;
- if (p->next != NULL)
- p->next->prev = p;
- tiw[tm] = p;
-
-
- /* insert min time */
- if ((tiw_nto == 0) || ((tiw_min_ptr != NULL) && (ticks < tiw_min))) {
- tiw_min = ticks;
- tiw_min_ptr = p;
- }
- if ((tiw_min_ptr == p) && (ticks > tiw_min)) {
- /* some other timer might be 'min' now */
- tiw_min = 0;
- tiw_min_ptr = NULL;
+ timeout_time = ERTS_CLKTCKS_TO_MONOTONIC(timeout_pos);
+ p->timeout_pos = timeout_pos;
}
- tiw_nto++;
+ if (timeout_time < tiw->next_timeout_time) {
+ tiw->true_next_timeout_time = 1;
+ tiw->next_timeout_time = timeout_time;
+ }
}
void
-erts_set_timer(ErlTimer* p, ErlTimeoutProc timeout, ErlCancelProc cancel,
- void* arg, Uint t)
+erts_twheel_cancel_timer(ErtsTimerWheel *tiw, ErtsTWheelTimer *p)
{
-
- erts_deliver_time();
- erts_smp_mtx_lock(&tiw_lock);
- if (p->active) { /* XXX assert ? */
- erts_smp_mtx_unlock(&tiw_lock);
- return;
+ if (p->slot != ERTS_TWHEEL_SLOT_INACTIVE) {
+ ErlCancelProc cancel;
+ void *arg;
+ remove_timer(tiw, p);
+ cancel = p->u.func.cancel;
+ arg = p->u.func.arg;
+ if (cancel)
+ (*cancel)(arg);
}
- p->timeout = timeout;
- p->cancel = cancel;
- p->arg = arg;
- p->active = 1;
- insert_timer(p, t);
- erts_smp_mtx_unlock(&tiw_lock);
-#if defined(ERTS_SMP)
- if (t <= (Uint) ERTS_SHORT_TIME_T_MAX)
- erts_sys_schedule_interrupt_timed(1, (erts_short_time_t) t);
-#endif
}
void
-erts_cancel_timer(ErlTimer* p)
+erts_twheel_debug_foreach(ErtsTimerWheel *tiw,
+ void (*tclbk)(void *),
+ void (*func)(void *,
+ ErtsMonotonicTime,
+ void *),
+ void *arg)
{
- erts_smp_mtx_lock(&tiw_lock);
- if (!p->active) { /* allow repeated cancel (drivers) */
- erts_smp_mtx_unlock(&tiw_lock);
- return;
- }
-
- /* is it the 'min' timer, remove min */
- if (p == tiw_min_ptr) {
- tiw_min_ptr = NULL;
- tiw_min = 0;
+ ErtsTWheelTimer *tmr;
+ int ix;
+
+ tmr = tiw->sentinel.next;
+ while (tmr != &tiw->sentinel) {
+ if (tmr->u.func.timeout == tclbk)
+ (*func)(arg, tmr->timeout_pos, tmr->u.func.arg);
+ tmr = tmr->next;
}
- remove_timer(p);
- p->slot = p->count = 0;
-
- if (p->cancel != NULL) {
- erts_smp_mtx_unlock(&tiw_lock);
- (*p->cancel)(p->arg);
- return;
+ for (tmr = tiw->at_once.head; tmr; tmr = tmr->next) {
+ if (tmr->u.func.timeout == tclbk)
+ (*func)(arg, tmr->timeout_pos, tmr->u.func.arg);
}
- erts_smp_mtx_unlock(&tiw_lock);
-}
-
-/*
- Returns the amount of time left in ms until the timer 'p' is triggered.
- 0 is returned if 'p' isn't active.
- 0 is returned also if the timer is overdue (i.e., would have triggered
- immediately if it hadn't been cancelled).
-*/
-Uint
-erts_time_left(ErlTimer *p)
-{
- Uint left;
- erts_short_time_t dt;
- erts_smp_mtx_lock(&tiw_lock);
-
- if (!p->active) {
- erts_smp_mtx_unlock(&tiw_lock);
- return 0;
+ for (ix = 0; ix < ERTS_TIW_SIZE; ix++) {
+ tmr = tiw->w[ix];
+ if (tmr) {
+ do {
+ if (tmr->u.func.timeout == tclbk)
+ (*func)(arg, tmr->timeout_pos, tmr->u.func.arg);
+ tmr = tmr->next;
+ } while (tmr != tiw->w[ix]);
+ }
}
-
- if (p->slot < tiw_pos)
- left = (p->count + 1) * TIW_SIZE + p->slot - tiw_pos;
- else
- left = p->count * TIW_SIZE + p->slot - tiw_pos;
- dt = do_time_read();
- if (left < dt)
- left = 0;
- else
- left -= dt;
-
- erts_smp_mtx_unlock(&tiw_lock);
-
- return (Uint) left * TIW_ITIME;
}
-#ifdef DEBUG
+#ifdef ERTS_TW_DEBUG
void erts_p_slpq(void)
{
+ erts_printf("Not yet implemented...\n");
+#if 0
+ ErtsMonotonicTime current_time = erts_get_monotonic_time(NULL);
int i;
- ErlTimer* p;
+ ErtsTWheelTimer* p;
- erts_smp_mtx_lock(&tiw_lock);
-
/* print the whole wheel, starting at the current position */
- erts_printf("\ntiw_pos = %d tiw_nto %d\n", tiw_pos, tiw_nto);
- i = tiw_pos;
- if (tiw[i] != NULL) {
+ erts_printf("\ncurrent time = %bps tiw_pos = %d tiw_nto %d\n",
+ current_time, tiw->pos, tiw->nto);
+ i = tiw->pos;
+ if (tiw->w[i] != NULL) {
erts_printf("%d:\n", i);
- for(p = tiw[i]; p != NULL; p = p->next) {
- erts_printf(" (count %d, slot %d)\n",
- p->count, p->slot);
+ for(p = tiw->w[i]; p != NULL; p = p->next) {
+ erts_printf(" (timeout time %bps, slot %d)\n",
+ ERTS_CLKTCKS_TO_MONOTONIC(p->timeout_pos),
+ p->slot);
}
}
- for(i = (i+1)%TIW_SIZE; i != tiw_pos; i = (i+1)%TIW_SIZE) {
- if (tiw[i] != NULL) {
+ for(i = ((i+1) & (ERTS_TIW_SIZE-1)); i != (tiw->pos & (ERTS_TIW_SIZE-1)); i = ((i+1) & (ERTS_TIW_SIZE-1))) {
+ if (tiw->w[i] != NULL) {
erts_printf("%d:\n", i);
- for(p = tiw[i]; p != NULL; p = p->next) {
- erts_printf(" (count %d, slot %d)\n",
- p->count, p->slot);
+ for(p = tiw->w[i]; p != NULL; p = p->next) {
+ erts_printf(" (timeout time %bps, slot %d)\n",
+ ERTS_CLKTCKS_TO_MONOTONIC(p->timeout_pos), p->slot);
}
}
}
-
- erts_smp_mtx_unlock(&tiw_lock);
+#endif
}
-#endif /* DEBUG */
+#endif /* ERTS_TW_DEBUG */
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index f810fca9a4..b9ce70e364 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -49,6 +50,12 @@
#include "beam_bp.h"
#include "erl_ptab.h"
#include "erl_check_io.h"
+#include "erl_bif_unique.h"
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
+#ifdef HIPE
+# include "hipe_mode_switch.h"
+#endif
#undef M_TRIM_THRESHOLD
#undef M_TOP_PAD
@@ -187,12 +194,18 @@ erts_set_hole_marker(Eterm* ptr, Uint sz)
* Helper function for the ESTACK macros defined in global.h.
*/
void
-erl_grow_estack(ErtsEStack* s, Eterm* default_estack)
+erl_grow_estack(ErtsEStack* s, Uint need)
{
Uint old_size = (s->end - s->start);
- Uint new_size = old_size * 2;
+ Uint new_size;
Uint sp_offs = s->sp - s->start;
- if (s->start != default_estack) {
+
+ if (need < old_size)
+ new_size = 2*old_size;
+ else
+ new_size = ((need / old_size) + 2) * old_size;
+
+ if (s->start != s->edefault) {
s->start = erts_realloc(s->alloc_type, s->start,
new_size*sizeof(Eterm));
} else {
@@ -207,12 +220,18 @@ erl_grow_estack(ErtsEStack* s, Eterm* default_estack)
* Helper function for the WSTACK macros defined in global.h.
*/
void
-erl_grow_wstack(ErtsWStack* s, UWord* default_wstack)
+erl_grow_wstack(ErtsWStack* s, Uint need)
{
Uint old_size = (s->wend - s->wstart);
- Uint new_size = old_size * 2;
+ Uint new_size;
Uint sp_offs = s->wsp - s->wstart;
- if (s->wstart != default_wstack) {
+
+ if (need < old_size)
+ new_size = 2 * old_size;
+ else
+ new_size = ((need / old_size) + 2) * old_size;
+
+ if (s->wstart != s->wdefault) {
s->wstart = erts_realloc(s->alloc_type, s->wstart,
new_size*sizeof(UWord));
} else {
@@ -224,6 +243,32 @@ erl_grow_wstack(ErtsWStack* s, UWord* default_wstack)
s->wsp = s->wstart + sp_offs;
}
+/*
+ * Helper function for the PSTACK macros defined in global.h.
+ */
+void
+erl_grow_pstack(ErtsPStack* s, void* default_pstack, unsigned need_bytes)
+{
+ Uint old_size = s->pend - s->pstart;
+ Uint new_size;
+ Uint sp_offs = s->psp - s->pstart;
+
+ if (need_bytes < old_size)
+ new_size = 2 * old_size;
+ else
+ new_size = ((need_bytes / old_size) + 2) * old_size;
+
+ if (s->pstart != default_pstack) {
+ s->pstart = erts_realloc(s->alloc_type, s->pstart, new_size);
+ } else {
+ byte* new_ptr = erts_alloc(s->alloc_type, new_size);
+ sys_memcpy(new_ptr, s->pstart, old_size);
+ s->pstart = new_ptr;
+ }
+ s->pend = s->pstart + new_size;
+ s->psp = s->pstart + sp_offs;
+}
+
/* CTYPE macros */
#define LATIN1
@@ -311,6 +356,17 @@ int erts_fit_in_bits_int32(Sint32 value)
return fit_in_bits((Sint64) (Uint32) value, 4);
}
+int erts_fit_in_bits_uint(Uint value)
+{
+#if ERTS_SIZEOF_ETERM == 4
+ return fit_in_bits((Sint64) (Uint32) value, 4);
+#elif ERTS_SIZEOF_ETERM == 8
+ return fit_in_bits(value, 5);
+#else
+# error "No way, Jose"
+#endif
+}
+
int
erts_print(int to, void *arg, char *format, ...)
{
@@ -343,9 +399,6 @@ erts_print(int to, void *arg, char *format, ...)
case ERTS_PRINT_DSBUF:
res = erts_vdsprintf((erts_dsprintf_buf_t *) arg, format, arg_list);
break;
- case ERTS_PRINT_INVALID:
- res = -EINVAL;
- break;
default:
res = erts_vfdprintf((int) to, format, arg_list);
break;
@@ -788,11 +841,10 @@ Uint32 make_hash(Eterm term_arg)
Eterm hash = 0;
unsigned op;
- /* Must not collide with the real tag_val_def's: */
-#define MAKE_HASH_TUPLE_OP 0x11
-#define MAKE_HASH_TERM_ARRAY_OP 0x12
-#define MAKE_HASH_CDR_PRE_OP 0x13
-#define MAKE_HASH_CDR_POST_OP 0x14
+#define MAKE_HASH_TUPLE_OP (FIRST_VACANT_TAG_DEF)
+#define MAKE_HASH_TERM_ARRAY_OP (FIRST_VACANT_TAG_DEF+1)
+#define MAKE_HASH_CDR_PRE_OP (FIRST_VACANT_TAG_DEF+2)
+#define MAKE_HASH_CDR_POST_OP (FIRST_VACANT_TAG_DEF+3)
/*
** Convenience macro for calculating a bytewise hash on an unsigned 32 bit
@@ -902,12 +954,15 @@ tail_recur:
UINT32_HASH_RET(external_ref_numbers(term)[0],FUNNY_NUMBER9,FUNNY_NUMBER10);
case FLOAT_DEF:
{
- FloatDef ff;
- GET_DOUBLE(term, ff);
- hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]);
- break;
+ FloatDef ff;
+ GET_DOUBLE(term, ff);
+ if (ff.fd == 0.0f) {
+ /* ensure positive 0.0 */
+ ff.fd = erts_get_positive_zero_float();
+ }
+ hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]);
+ break;
}
-
case MAKE_HASH_CDR_PRE_OP:
term = (Eterm) WSTACK_POP(stack);
if (is_not_list(term)) {
@@ -972,23 +1027,8 @@ tail_recur:
break;
}
case MAP_DEF:
- {
- map_t *mp = (map_t *)map_val(term);
- int size = map_get_size(mp);
- Eterm *ks = map_get_keys(mp);
- Eterm *vs = map_get_values(mp);
-
- /* Use a prime with size to remedy some of
- * the {} and <<>> hash problems */
- hash = hash*FUNNY_NUMBER13 + FUNNY_NUMBER14 + size;
- if (size == 0)
- break;
-
- /* push values first */
- WSTACK_PUSH3(stack, (UWord)vs, (UWord) size, MAKE_HASH_TERM_ARRAY_OP);
- WSTACK_PUSH3(stack, (UWord)ks, (UWord) size, MAKE_HASH_TERM_ARRAY_OP);
- break;
- }
+ hash = hash*FUNNY_NUMBER13 + FUNNY_NUMBER14 + make_hash2(term);
+ break;
case TUPLE_DEF:
{
Eterm* ptr = tuple_val(term);
@@ -1015,7 +1055,7 @@ tail_recur:
}
default:
- erl_exit(1, "Invalid tag in make_hash(0x%X,0x%X)\n", term, op);
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_hash(0x%X,0x%X)\n", term, op);
return 0;
}
if (WSTACK_ISEMPTY(stack)) break;
@@ -1092,11 +1132,12 @@ Uint32
make_hash2(Eterm term)
{
Uint32 hash;
- Uint32 hash_xor_keys = 0;
- Uint32 hash_xor_values = 0;
+ Uint32 hash_xor_pairs;
DeclareTmpHeapNoproc(tmp_big,2);
-/* (HCONST * {2, ..., 16}) mod 2^32 */
+ ERTS_UNDEF(hash_xor_pairs, 0);
+
+/* (HCONST * {2, ..., 22}) mod 2^32 */
#define HCONST_2 0x3c6ef372UL
#define HCONST_3 0xdaa66d2bUL
#define HCONST_4 0x78dde6e4UL
@@ -1112,10 +1153,16 @@ make_hash2(Eterm term)
#define HCONST_14 0xa708a81eUL
#define HCONST_15 0x454021d7UL
#define HCONST_16 0xe3779b90UL
+#define HCONST_17 0x81af1549UL
+#define HCONST_18 0x1fe68f02UL
+#define HCONST_19 0xbe1e08bbUL
+#define HCONST_20 0x5c558274UL
+#define HCONST_21 0xfa8cfc2dUL
+#define HCONST_22 0x98c475e6UL
#define HASH_MAP_TAIL (_make_header(1,_TAG_HEADER_REF))
-#define HASH_MAP_KEY (_make_header(2,_TAG_HEADER_REF))
-#define HASH_MAP_VAL (_make_header(3,_TAG_HEADER_REF))
+#define HASH_MAP_PAIR (_make_header(2,_TAG_HEADER_REF))
+#define HASH_CDR (_make_header(3,_TAG_HEADER_REF))
#define UINT32_HASH_2(Expr1, Expr2, AConst) \
do { \
@@ -1138,6 +1185,13 @@ make_hash2(Eterm term)
} while(0)
#define IS_SSMALL28(x) (((Uint) (((x) >> (28-1)) + 1)) < 2)
+
+#ifdef ARCH_64
+# define POINTER_HASH(Ptr, AConst) UINT32_HASH_2((Uint32)(UWord)(Ptr), (((UWord)(Ptr)) >> 32), AConst)
+#else
+# define POINTER_HASH(Ptr, AConst) UINT32_HASH(Ptr, AConst)
+#endif
+
/* Optimization. Simple cases before declaration of estack. */
if (primary_tag(term) == TAG_PRIMARY_IMMED1) {
switch (term & _TAG_IMMED1_MASK) {
@@ -1192,9 +1246,9 @@ make_hash2(Eterm term)
if (c > 0)
UINT32_HASH(sh, HCONST_4);
if (is_list(term)) {
- term = *ptr;
- tmp = *++ptr;
- ESTACK_PUSH(s, tmp);
+ tmp = CDR(ptr);
+ ESTACK_PUSH(s, tmp);
+ term = CAR(ptr);
}
}
break;
@@ -1211,51 +1265,90 @@ make_hash2(Eterm term)
UINT32_HASH(arity, HCONST_9);
if (arity == 0) /* Empty tuple */
goto hash2_common;
- for (i = arity; i >= 1; i--) {
- tmp = elem[i];
- ESTACK_PUSH(s, tmp);
+ for (i = arity; ; i--) {
+ term = elem[i];
+ if (i == 1)
+ break;
+ ESTACK_PUSH(s, term);
}
- goto hash2_common;
- }
- break;
- case MAP_SUBTAG:
- {
- map_t *mp = (map_t *)map_val(term);
- int i;
- int size = map_get_size(mp);
- Eterm *ks = map_get_keys(mp);
- Eterm *vs = map_get_values(mp);
- UINT32_HASH(size, HCONST_16);
- if (size == 0) {
- goto hash2_common;
- }
- ESTACK_PUSH(s, hash_xor_values);
- ESTACK_PUSH(s, hash_xor_keys);
- ESTACK_PUSH(s, hash);
- ESTACK_PUSH(s, HASH_MAP_TAIL);
- hash = 0;
- hash_xor_keys = 0;
- hash_xor_values = 0;
- for (i = size - 1; i >= 0; i--) {
- tmp = vs[i];
- ESTACK_PUSH(s, HASH_MAP_VAL);
- ESTACK_PUSH(s, tmp);
- }
- /* We do not want to expose the tuple representation.
- * Do not push the keys as a tuple.
- */
- for (i = size - 1; i >= 0; i--) {
- tmp = ks[i];
- ESTACK_PUSH(s, HASH_MAP_KEY);
- ESTACK_PUSH(s, tmp);
- }
- goto hash2_common;
}
break;
+ case MAP_SUBTAG:
+ {
+ Eterm* ptr = boxed_val(term) + 1;
+ Uint size;
+ int i;
+ switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_FLATMAP:
+ {
+ flatmap_t *mp = (flatmap_t *)flatmap_val(term);
+ Eterm *ks = flatmap_get_keys(mp);
+ Eterm *vs = flatmap_get_values(mp);
+ size = flatmap_get_size(mp);
+ UINT32_HASH(size, HCONST_16);
+ if (size == 0)
+ goto hash2_common;
+
+ /* We want a portable hash function that is *independent* of
+ * the order in which keys and values are encountered.
+ * We therefore calculate context independent hashes for all .
+ * key-value pairs and then xor them together.
+ */
+ ESTACK_PUSH(s, hash_xor_pairs);
+ ESTACK_PUSH(s, hash);
+ ESTACK_PUSH(s, HASH_MAP_TAIL);
+ hash = 0;
+ hash_xor_pairs = 0;
+ for (i = size - 1; i >= 0; i--) {
+ ESTACK_PUSH(s, HASH_MAP_PAIR);
+ ESTACK_PUSH(s, vs[i]);
+ ESTACK_PUSH(s, ks[i]);
+ }
+ goto hash2_common;
+ }
+
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ size = *ptr++;
+ UINT32_HASH(size, HCONST_16);
+ if (size == 0)
+ goto hash2_common;
+ ESTACK_PUSH(s, hash_xor_pairs);
+ ESTACK_PUSH(s, hash);
+ ESTACK_PUSH(s, HASH_MAP_TAIL);
+ hash = 0;
+ hash_xor_pairs = 0;
+ }
+ switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ i = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ case HAMT_SUBTAG_NODE_BITMAP:
+ i = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header");
+ }
+ while (i) {
+ if (is_list(*ptr)) {
+ Eterm* cons = list_val(*ptr);
+ ESTACK_PUSH(s, HASH_MAP_PAIR);
+ ESTACK_PUSH(s, CDR(cons));
+ ESTACK_PUSH(s, CAR(cons));
+ }
+ else {
+ ASSERT(is_boxed(*ptr));
+ ESTACK_PUSH(s, *ptr);
+ }
+ i--; ptr++;
+ }
+ goto hash2_common;
+ }
+ break;
case EXPORT_SUBTAG:
{
Export* ep = *((Export **) (export_val(term) + 1));
-
UINT32_HASH_2
(ep->code[2],
atom_tab(atom_val(ep->code[0]))->slot.bucket.hvalue,
@@ -1270,7 +1363,6 @@ make_hash2(Eterm term)
{
ErlFunThing* funp = (ErlFunThing *) fun_val(term);
Uint num_free = funp->num_free;
-
UINT32_HASH_2
(num_free,
atom_tab(atom_val(funp->fe->module))->slot.bucket.hvalue,
@@ -1351,7 +1443,8 @@ make_hash2(Eterm term)
do {
Uint t;
Uint32 x, y;
- t = i < n ? BIG_DIGIT(ptr, i++) : 0;
+ ASSERT(i < n);
+ t = BIG_DIGIT(ptr, i++);
x = t & 0xffffffff;
y = t >> 32;
UINT32_HASH_2(x, y, con);
@@ -1384,6 +1477,10 @@ make_hash2(Eterm term)
{
FloatDef ff;
GET_DOUBLE(term, ff);
+ if (ff.fd == 0.0f) {
+ /* ensure positive 0.0 */
+ ff.fd = erts_get_positive_zero_float();
+ }
#if defined(WORDS_BIGENDIAN) || defined(DOUBLE_MIDDLE_ENDIAN)
UINT32_HASH_2(ff.fw[0], ff.fw[1], HCONST_12);
#else
@@ -1394,7 +1491,7 @@ make_hash2(Eterm term)
break;
default:
- erl_exit(1, "Invalid tag in make_hash2(0x%X)\n", term);
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_hash2(0x%X)\n", term);
}
}
break;
@@ -1425,7 +1522,7 @@ make_hash2(Eterm term)
UINT32_HASH(NIL_DEF, HCONST_2);
goto hash2_common;
default:
- erl_exit(1, "Invalid tag in make_hash2(0x%X)\n", term);
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_hash2(0x%X)\n", term);
}
case _TAG_IMMED1_SMALL:
{
@@ -1441,7 +1538,7 @@ make_hash2(Eterm term)
}
break;
default:
- erl_exit(1, "Invalid tag in make_hash2(0x%X)\n", term);
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_hash2(0x%X)\n", term);
hash2_common:
/* Uint32 hash always has the hash value of the previous term,
@@ -1459,20 +1556,397 @@ make_hash2(Eterm term)
switch (term) {
case HASH_MAP_TAIL: {
hash = (Uint32) ESTACK_POP(s);
- UINT32_HASH(hash_xor_keys, HCONST_16);
- UINT32_HASH(hash_xor_values, HCONST_16);
- hash_xor_keys = (Uint32) ESTACK_POP(s);
- hash_xor_values = (Uint32) ESTACK_POP(s);
+ UINT32_HASH(hash_xor_pairs, HCONST_19);
+ hash_xor_pairs = (Uint32) ESTACK_POP(s);
goto hash2_common;
}
- case HASH_MAP_KEY:
- hash_xor_keys ^= hash;
+ case HASH_MAP_PAIR:
+ hash_xor_pairs ^= hash;
hash = 0;
goto hash2_common;
- case HASH_MAP_VAL:
- hash_xor_values ^= hash;
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* Term hash function for internal use.
+ *
+ * Limitation #1: Is not "portable" in any way between different VM instances.
+ *
+ * Limitation #2: The hash value is only valid as long as the term exists
+ * somewhere in the VM. Why? Because external pids, ports and refs are hashed
+ * by mixing the node *pointer* value. If a node disappears and later reappears
+ * with a new ErlNode struct, externals from that node will hash different than
+ * before.
+ *
+ * One IMPORTANT property must hold (for hamt).
+ * EVERY BIT of the term that is significant for equality (see EQ)
+ * MUST BE USED AS INPUT FOR THE HASH. Two different terms must always have a
+ * chance of hashing different when salted: hash([Salt|A]) vs hash([Salt|B]).
+ *
+ * This is why we can not use cached hash values for atoms for example.
+ *
+ */
+
+#define CONST_HASH(AConst) \
+do { /* Lightweight mixing of constant (type info) */ \
+ hash ^= AConst; \
+ hash = (hash << 17) ^ (hash >> (32-17)); \
+} while (0)
+
+Uint32
+make_internal_hash(Eterm term)
+{
+ Uint32 hash;
+ Uint32 hash_xor_pairs;
+
+ ERTS_UNDEF(hash_xor_pairs, 0);
+
+ /* Optimization. Simple cases before declaration of estack. */
+ if (primary_tag(term) == TAG_PRIMARY_IMMED1) {
+ hash = 0;
+ #if ERTS_SIZEOF_ETERM == 8
+ UINT32_HASH_2((Uint32)term, (Uint32)(term >> 32), HCONST);
+ #elif ERTS_SIZEOF_ETERM == 4
+ UINT32_HASH(term, HCONST);
+ #else
+ # error "No you don't"
+ #endif
+ return hash;
+ }
+ {
+ Eterm tmp;
+ DECLARE_ESTACK(s);
+
+ hash = 0;
+ for (;;) {
+ switch (primary_tag(term)) {
+ case TAG_PRIMARY_LIST:
+ {
+ int c = 0;
+ Uint32 sh = 0;
+ Eterm* ptr = list_val(term);
+ while (is_byte(*ptr)) {
+ /* Optimization for strings. */
+ sh = (sh << 8) + unsigned_val(*ptr);
+ if (c == 3) {
+ UINT32_HASH(sh, HCONST_4);
+ c = sh = 0;
+ } else {
+ c++;
+ }
+ term = CDR(ptr);
+ if (is_not_list(term))
+ break;
+ ptr = list_val(term);
+ }
+ if (c > 0)
+ UINT32_HASH_2(sh, (Uint32)c, HCONST_22);
+
+ if (is_list(term)) {
+ tmp = CDR(ptr);
+ CONST_HASH(HCONST_17); /* Hash CAR in cons cell */
+ ESTACK_PUSH(s, tmp);
+ if (is_not_list(tmp)) {
+ ESTACK_PUSH(s, HASH_CDR);
+ }
+ term = CAR(ptr);
+ }
+ }
+ break;
+ case TAG_PRIMARY_BOXED:
+ {
+ Eterm hdr = *boxed_val(term);
+ ASSERT(is_header(hdr));
+ switch (hdr & _TAG_HEADER_MASK) {
+ case ARITYVAL_SUBTAG:
+ {
+ int i;
+ int arity = header_arity(hdr);
+ Eterm* elem = tuple_val(term);
+ UINT32_HASH(arity, HCONST_9);
+ if (arity == 0) /* Empty tuple */
+ goto pop_next;
+ for (i = arity; ; i--) {
+ term = elem[i];
+ if (i == 1)
+ break;
+ ESTACK_PUSH(s, term);
+ }
+ }
+ break;
+
+ case MAP_SUBTAG:
+ {
+ Eterm* ptr = boxed_val(term) + 1;
+ Uint size;
+ int i;
+ switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_FLATMAP:
+ {
+ flatmap_t *mp = (flatmap_t *)flatmap_val(term);
+ Eterm *ks = flatmap_get_keys(mp);
+ Eterm *vs = flatmap_get_values(mp);
+ size = flatmap_get_size(mp);
+ UINT32_HASH(size, HCONST_16);
+ if (size == 0)
+ goto pop_next;
+
+ /* We want a hash function that is *independent* of
+ * the order in which keys and values are encountered.
+ * We therefore calculate context independent hashes for all .
+ * key-value pairs and then xor them together.
+ */
+ ESTACK_PUSH(s, hash_xor_pairs);
+ ESTACK_PUSH(s, hash);
+ ESTACK_PUSH(s, HASH_MAP_TAIL);
+ hash = 0;
+ hash_xor_pairs = 0;
+ for (i = size - 1; i >= 0; i--) {
+ ESTACK_PUSH(s, HASH_MAP_PAIR);
+ ESTACK_PUSH(s, vs[i]);
+ ESTACK_PUSH(s, ks[i]);
+ }
+ goto pop_next;
+ }
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ size = *ptr++;
+ UINT32_HASH(size, HCONST_16);
+ if (size == 0)
+ goto pop_next;
+ ESTACK_PUSH(s, hash_xor_pairs);
+ ESTACK_PUSH(s, hash);
+ ESTACK_PUSH(s, HASH_MAP_TAIL);
+ hash = 0;
+ hash_xor_pairs = 0;
+ }
+ switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ i = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ case HAMT_SUBTAG_NODE_BITMAP:
+ i = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header");
+ }
+ while (i) {
+ if (is_list(*ptr)) {
+ Eterm* cons = list_val(*ptr);
+ ESTACK_PUSH(s, HASH_MAP_PAIR);
+ ESTACK_PUSH(s, CDR(cons));
+ ESTACK_PUSH(s, CAR(cons));
+ }
+ else {
+ ASSERT(is_boxed(*ptr));
+ ESTACK_PUSH(s, *ptr);
+ }
+ i--; ptr++;
+ }
+ goto pop_next;
+ }
+ break;
+ case EXPORT_SUBTAG:
+ {
+ Export* ep = *((Export **) (export_val(term) + 1));
+ /* Assumes Export entries never moves */
+ POINTER_HASH(ep, HCONST_14);
+ goto pop_next;
+ }
+
+ case FUN_SUBTAG:
+ {
+ ErlFunThing* funp = (ErlFunThing *) fun_val(term);
+ Uint num_free = funp->num_free;
+ UINT32_HASH_2(num_free, funp->fe->module, HCONST_20);
+ UINT32_HASH_2(funp->fe->old_index, funp->fe->old_uniq, HCONST_21);
+ if (num_free == 0) {
+ goto pop_next;
+ } else {
+ Eterm* bptr = funp->env + num_free - 1;
+ while (num_free-- > 1) {
+ term = *bptr--;
+ ESTACK_PUSH(s, term);
+ }
+ term = *bptr;
+ }
+ }
+ break;
+ case REFC_BINARY_SUBTAG:
+ case HEAP_BINARY_SUBTAG:
+ case SUB_BINARY_SUBTAG:
+ {
+ byte* bptr;
+ unsigned sz = binary_size(term);
+ Uint32 con = HCONST_13 + hash;
+ Uint bitoffs;
+ Uint bitsize;
+
+ ERTS_GET_BINARY_BYTES(term, bptr, bitoffs, bitsize);
+ if (sz == 0 && bitsize == 0) {
+ hash = con;
+ } else {
+ if (bitoffs == 0) {
+ hash = block_hash(bptr, sz, con);
+ if (bitsize > 0) {
+ UINT32_HASH_2(bitsize, (bptr[sz] >> (8 - bitsize)),
+ HCONST_15);
+ }
+ } else {
+ byte* buf = (byte *) erts_alloc(ERTS_ALC_T_TMP,
+ sz + (bitsize != 0));
+ erts_copy_bits(bptr, bitoffs, 1, buf, 0, 1, sz*8+bitsize);
+ hash = block_hash(buf, sz, con);
+ if (bitsize > 0) {
+ UINT32_HASH_2(bitsize, (buf[sz] >> (8 - bitsize)),
+ HCONST_15);
+ }
+ erts_free(ERTS_ALC_T_TMP, (void *) buf);
+ }
+ }
+ goto pop_next;
+ }
+ break;
+ case POS_BIG_SUBTAG:
+ case NEG_BIG_SUBTAG:
+ {
+ Eterm* ptr = big_val(term);
+ Uint i = 0;
+ Uint n = BIG_SIZE(ptr);
+ Uint32 con = BIG_SIGN(ptr) ? HCONST_10 : HCONST_11;
+#if D_EXP == 16
+ do {
+ Uint32 x, y;
+ x = i < n ? BIG_DIGIT(ptr, i++) : 0;
+ x += (Uint32)(i < n ? BIG_DIGIT(ptr, i++) : 0) << 16;
+ y = i < n ? BIG_DIGIT(ptr, i++) : 0;
+ y += (Uint32)(i < n ? BIG_DIGIT(ptr, i++) : 0) << 16;
+ UINT32_HASH_2(x, y, con);
+ } while (i < n);
+#elif D_EXP == 32
+ do {
+ Uint32 x, y;
+ x = i < n ? BIG_DIGIT(ptr, i++) : 0;
+ y = i < n ? BIG_DIGIT(ptr, i++) : 0;
+ UINT32_HASH_2(x, y, con);
+ } while (i < n);
+#elif D_EXP == 64
+ do {
+ Uint t;
+ Uint32 x, y;
+ ASSERT(i < n);
+ t = BIG_DIGIT(ptr, i++);
+ x = t & 0xffffffff;
+ y = t >> 32;
+ UINT32_HASH_2(x, y, con);
+ } while (i < n);
+#else
+#error "unsupported D_EXP size"
+#endif
+ goto pop_next;
+ }
+ break;
+ case REF_SUBTAG:
+ UINT32_HASH(internal_ref_numbers(term)[0], HCONST_7);
+ ASSERT(internal_ref_no_of_numbers(term) == 3);
+ UINT32_HASH_2(internal_ref_numbers(term)[1],
+ internal_ref_numbers(term)[2], HCONST_8);
+ goto pop_next;
+
+ case EXTERNAL_REF_SUBTAG:
+ {
+ ExternalThing* thing = external_thing_ptr(term);
+
+ ASSERT(external_thing_ref_no_of_numbers(thing) == 3);
+ /* See limitation #2 */
+ #ifdef ARCH_64
+ POINTER_HASH(thing->node, HCONST_7);
+ UINT32_HASH(external_thing_ref_numbers(thing)[0], HCONST_7);
+ #else
+ UINT32_HASH_2(thing->node,
+ external_thing_ref_numbers(thing)[0], HCONST_7);
+ #endif
+ UINT32_HASH_2(external_thing_ref_numbers(thing)[1],
+ external_thing_ref_numbers(thing)[2], HCONST_8);
+ goto pop_next;
+ }
+ case EXTERNAL_PID_SUBTAG: {
+ ExternalThing* thing = external_thing_ptr(term);
+ /* See limitation #2 */
+ #ifdef ARCH_64
+ POINTER_HASH(thing->node, HCONST_5);
+ UINT32_HASH(thing->data.ui[0], HCONST_5);
+ #else
+ UINT32_HASH_2(thing->node, thing->data.ui[0], HCONST_5);
+ #endif
+ goto pop_next;
+ }
+ case EXTERNAL_PORT_SUBTAG: {
+ ExternalThing* thing = external_thing_ptr(term);
+ /* See limitation #2 */
+ #ifdef ARCH_64
+ POINTER_HASH(thing->node, HCONST_6);
+ UINT32_HASH(thing->data.ui[0], HCONST_6);
+ #else
+ UINT32_HASH_2(thing->node, thing->data.ui[0], HCONST_6);
+ #endif
+ goto pop_next;
+ }
+ case FLOAT_SUBTAG:
+ {
+ FloatDef ff;
+ GET_DOUBLE(term, ff);
+ if (ff.fd == 0.0f) {
+ /* ensure positive 0.0 */
+ ff.fd = erts_get_positive_zero_float();
+ }
+ UINT32_HASH_2(ff.fw[0], ff.fw[1], HCONST_12);
+ goto pop_next;
+ }
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_hash2(0x%X)\n", term);
+ }
+ }
+ break;
+ case TAG_PRIMARY_IMMED1:
+ #if ERTS_SIZEOF_ETERM == 8
+ UINT32_HASH_2((Uint32)term, (Uint32)(term >> 32), HCONST);
+ #else
+ UINT32_HASH(term, HCONST);
+ #endif
+ goto pop_next;
+
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_hash2(0x%X)\n", term);
+
+ pop_next:
+ if (ESTACK_ISEMPTY(s)) {
+ DESTROY_ESTACK(s);
+ return hash;
+ }
+
+ term = ESTACK_POP(s);
+
+ switch (term) {
+ case HASH_MAP_TAIL: {
+ hash = (Uint32) ESTACK_POP(s);
+ UINT32_HASH(hash_xor_pairs, HCONST_19);
+ hash_xor_pairs = (Uint32) ESTACK_POP(s);
+ goto pop_next;
+ }
+ case HASH_MAP_PAIR:
+ hash_xor_pairs ^= hash;
hash = 0;
- goto hash2_common;
+ goto pop_next;
+
+ case HASH_CDR:
+ CONST_HASH(HCONST_18); /* Hash CDR i cons cell */
+ goto pop_next;
default:
break;
}
@@ -1480,9 +1954,10 @@ make_hash2(Eterm term)
}
}
+#undef CONST_HASH
#undef HASH_MAP_TAIL
-#undef HASH_MAP_KEY
-#undef HASH_MAP_VAL
+#undef HASH_MAP_PAIR
+#undef HASH_CDR
#undef UINT32_HASH_2
#undef UINT32_HASH
@@ -1613,12 +2088,15 @@ tail_recur:
break;
case FLOAT_DEF:
{
- FloatDef ff;
- GET_DOUBLE(term, ff);
- hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]);
+ FloatDef ff;
+ GET_DOUBLE(term, ff);
+ if (ff.fd == 0.0f) {
+ /* ensure positive 0.0 */
+ ff.fd = erts_get_positive_zero_float();
+ }
+ hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]);
}
break;
-
case MAKE_HASH_CDR_PRE_OP:
term = (Eterm) WSTACK_POP(stack);
if (is_not_list(term)) {
@@ -1699,23 +2177,8 @@ tail_recur:
break;
case MAP_DEF:
- {
- map_t *mp = (map_t *)map_val(term);
- int size = map_get_size(mp);
- Eterm *ks = map_get_keys(mp);
- Eterm *vs = map_get_values(mp);
-
- /* Use a prime with size to remedy some of
- * the {} and <<>> hash problems */
- hash = hash*FUNNY_NUMBER13 + FUNNY_NUMBER14 + size;
- if (size == 0)
- break;
-
- /* push values first */
- WSTACK_PUSH3(stack, (UWord)vs, (UWord) size, MAKE_HASH_TERM_ARRAY_OP);
- WSTACK_PUSH3(stack, (UWord)ks, (UWord) size, MAKE_HASH_TERM_ARRAY_OP);
- break;
- }
+ hash = hash*FUNNY_NUMBER13 + FUNNY_NUMBER14 + make_hash2(term);
+ break;
case TUPLE_DEF:
{
Eterm* ptr = tuple_val(term);
@@ -1742,7 +2205,7 @@ tail_recur:
}
default:
- erl_exit(1, "Invalid tag in make_broken_hash\n");
+ erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_broken_hash\n");
return 0;
}
if (WSTACK_ISEMPTY(stack)) break;
@@ -1758,101 +2221,157 @@ tail_recur:
#undef MAKE_HASH_CDR_POST_OP
}
-static int do_send_to_logger(Eterm tag, Eterm gleader, char *buf, int len)
+static Eterm
+do_allocate_logger_message(Eterm gleader, Eterm **hp, ErlOffHeap **ohp,
+ ErlHeapFragment **bp, Process **p, Uint sz)
{
- /* error_logger !
- {notify,{info_msg,gleader,{emulator,"~s~n",[<message as list>]}}} |
- {notify,{error,gleader,{emulator,"~s~n",[<message as list>]}}} |
- {notify,{warning_msg,gleader,{emulator,"~s~n",[<message as list>}]}} */
- Eterm* hp;
- Uint sz;
Uint gl_sz;
- Eterm gl;
- Eterm list,plist,format,tuple1,tuple2,tuple3;
- ErlOffHeap *ohp;
- ErlHeapFragment *bp = NULL;
-#if !defined(ERTS_SMP)
- Process *p;
-#endif
-
- ASSERT(is_atom(tag));
-
- if (len <= 0) {
- return -1;
- }
+ gl_sz = IS_CONST(gleader) ? 0 : size_object(gleader);
+ sz = sz + gl_sz;
#ifndef ERTS_SMP
#ifdef USE_THREADS
- p = NULL;
if (erts_get_scheduler_data()) /* Must be scheduler thread */
#endif
{
- p = erts_whereis_process(NULL, 0, am_error_logger, 0, 0);
- if (p) {
- erts_aint32_t state = erts_smp_atomic32_read_acqb(&p->state);
+ *p = erts_whereis_process(NULL, 0, am_error_logger, 0, 0);
+ if (*p) {
+ erts_aint32_t state = erts_smp_atomic32_read_acqb(&(*p)->state);
if (state & (ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS))
- p = NULL;
+ *p = NULL;
}
}
- if (!p) {
- /* buf *always* points to a null terminated string */
- erts_fprintf(stderr, "(no error logger present) %T: \"%s\"\n",
- tag, buf);
- return 0;
+ if (!*p) {
+ return NIL;
}
- /* So we have an error logger, lets build the message */
-#endif
- gl_sz = IS_CONST(gleader) ? 0 : size_object(gleader);
- sz = len * 2 /* message list */+ 2 /* cons surrounding message list */
- + gl_sz +
- 3 /*outer 2-tuple*/ + 4 /* middle 3-tuple */ + 4 /*inner 3-tuple */ +
- 8 /* "~s~n" */;
-#ifndef ERTS_SMP
- if (sz <= HeapWordsLeft(p)) {
- ohp = &MSO(p);
- hp = HEAP_TOP(p);
- HEAP_TOP(p) += sz;
+ /* So we have an error logger, lets build the message */
+ if (sz <= HeapWordsLeft(*p)) {
+ *ohp = &MSO(*p);
+ *hp = HEAP_TOP(*p);
+ HEAP_TOP(*p) += sz;
} else {
#endif
- bp = new_message_buffer(sz);
- ohp = &bp->off_heap;
- hp = bp->mem;
+ *bp = new_message_buffer(sz);
+ *ohp = &(*bp)->off_heap;
+ *hp = (*bp)->mem;
#ifndef ERTS_SMP
}
#endif
- gl = (is_nil(gleader)
+
+ return (is_nil(gleader)
? am_noproc
: (IS_CONST(gleader)
? gleader
- : copy_struct(gleader,gl_sz,&hp,ohp)));
- list = buf_to_intlist(&hp, buf, len, NIL);
- plist = CONS(hp,list,NIL);
- hp += 2;
- format = buf_to_intlist(&hp, "~s~n", 4, NIL);
- tuple1 = TUPLE3(hp, am_emulator, format, plist);
- hp += 4;
- tuple2 = TUPLE3(hp, tag, gl, tuple1);
- hp += 4;
- tuple3 = TUPLE2(hp, am_notify, tuple2);
+ : copy_struct(gleader,gl_sz,hp,*ohp)));
+}
+
+static void do_send_logger_message(Eterm *hp, ErlOffHeap *ohp, ErlHeapFragment *bp,
+ Process *p, Eterm message)
+{
#ifdef HARDDEBUG
- erts_fprintf(stderr, "%T\n", tuple3);
+ erts_fprintf(stderr, "%T\n", message);
#endif
#ifdef ERTS_SMP
{
Eterm from = erts_get_current_pid();
if (is_not_internal_pid(from))
from = NIL;
- erts_queue_error_logger_message(from, tuple3, bp);
+ erts_queue_error_logger_message(from, message, bp);
}
#else
- erts_queue_message(p, NULL /* only used for smp build */, bp, tuple3, NIL
-#ifdef USE_VM_PROBES
- , NIL
-#endif
- );
+ erts_queue_message(p, NULL /* only used for smp build */, bp, message, NIL);
#endif
+}
+
+/* error_logger !
+ {notify,{info_msg,gleader,{emulator,format,[args]}}} |
+ {notify,{error,gleader,{emulator,format,[args]}}} |
+ {notify,{warning_msg,gleader,{emulator,format,[args}]}} */
+static int do_send_to_logger(Eterm tag, Eterm gleader, char *buf, int len)
+{
+ Uint sz;
+ Eterm gl;
+ Eterm list,args,format,tuple1,tuple2,tuple3;
+
+ Eterm *hp = NULL;
+ ErlOffHeap *ohp = NULL;
+ ErlHeapFragment *bp = NULL;
+ Process *p = NULL;
+
+ ASSERT(is_atom(tag));
+
+ if (len <= 0) {
+ return -1;
+ }
+
+ sz = len * 2 /* message list */ + 2 /* cons surrounding message list */
+ + 3 /*outer 2-tuple*/ + 4 /* middle 3-tuple */ + 4 /*inner 3-tuple */
+ + 8 /* "~s~n" */;
+
+ /* gleader size is accounted and allocated next */
+ gl = do_allocate_logger_message(gleader, &hp, &ohp, &bp, &p, sz);
+
+ if(is_nil(gl)) {
+ /* buf *always* points to a null terminated string */
+ erts_fprintf(stderr, "(no error logger present) %T: \"%s\"\n",
+ tag, buf);
+ return 0;
+ }
+
+ list = buf_to_intlist(&hp, buf, len, NIL);
+ args = CONS(hp,list,NIL);
+ hp += 2;
+ format = buf_to_intlist(&hp, "~s~n", 4, NIL);
+ tuple1 = TUPLE3(hp, am_emulator, format, args);
+ hp += 4;
+ tuple2 = TUPLE3(hp, tag, gl, tuple1);
+ hp += 4;
+ tuple3 = TUPLE2(hp, am_notify, tuple2);
+
+ do_send_logger_message(hp, ohp, bp, p, tuple3);
+ return 0;
+}
+
+static int do_send_term_to_logger(Eterm tag, Eterm gleader,
+ char *buf, int len, Eterm args)
+{
+ Uint sz;
+ Eterm gl;
+ Uint args_sz;
+ Eterm format,tuple1,tuple2,tuple3;
+
+ Eterm *hp = NULL;
+ ErlOffHeap *ohp = NULL;
+ ErlHeapFragment *bp = NULL;
+ Process *p = NULL;
+
+ ASSERT(is_atom(tag));
+
+ args_sz = size_object(args);
+ sz = len * 2 /* format */ + args_sz
+ + 3 /*outer 2-tuple*/ + 4 /* middle 3-tuple */ + 4 /*inner 3-tuple */;
+
+ /* gleader size is accounted and allocated next */
+ gl = do_allocate_logger_message(gleader, &hp, &ohp, &bp, &p, sz);
+
+ if(is_nil(gl)) {
+ /* buf *always* points to a null terminated string */
+ erts_fprintf(stderr, "(no error logger present) %T: \"%s\" %T\n",
+ tag, buf, args);
+ return 0;
+ }
+
+ format = buf_to_intlist(&hp, buf, len, NIL);
+ args = copy_struct(args, args_sz, &hp, ohp);
+ tuple1 = TUPLE3(hp, am_emulator, format, args);
+ hp += 4;
+ tuple2 = TUPLE3(hp, tag, gl, tuple1);
+ hp += 4;
+ tuple3 = TUPLE2(hp, am_notify, tuple2);
+
+ do_send_logger_message(hp, ohp, bp, p, tuple3);
return 0;
}
@@ -1880,6 +2399,12 @@ send_error_to_logger(Eterm gleader, char *buf, int len)
return do_send_to_logger(am_error, gleader, buf, len);
}
+static ERTS_INLINE int
+send_error_term_to_logger(Eterm gleader, char *buf, int len, Eterm args)
+{
+ return do_send_term_to_logger(am_error, gleader, buf, len, args);
+}
+
#define LOGGER_DSBUF_INC_SZ 256
static erts_dsprintf_buf_t *
@@ -1955,6 +2480,15 @@ erts_send_error_to_logger(Eterm gleader, erts_dsprintf_buf_t *dsbufp)
}
int
+erts_send_error_term_to_logger(Eterm gleader, erts_dsprintf_buf_t *dsbufp, Eterm args)
+{
+ int res;
+ res = send_error_term_to_logger(gleader, dsbufp->str, dsbufp->str_len, args);
+ destroy_logger_dsbuf(dsbufp);
+ return res;
+}
+
+int
erts_send_info_to_logger_str(Eterm gleader, char *str)
{
return send_info_to_logger(gleader, str, sys_strlen(str));
@@ -2120,22 +2654,6 @@ tailrecur_ne:
++bb;
goto term_array;
}
- case MAP_SUBTAG:
- {
- aa = map_val_rel(a, a_base);
- if (!is_boxed(b) || *boxed_val_rel(b,b_base) != *aa)
- goto not_equal;
- bb = map_val_rel(b,b_base);
- sz = map_get_size((map_t*)aa);
-
- if (sz != map_get_size((map_t*)bb)) goto not_equal;
- if (sz == 0) goto pop_next;
-
- aa += 2;
- bb += 2;
- sz += 1; /* increment for tuple-keys */
- goto term_array;
- }
case REFC_BINARY_SUBTAG:
case HEAP_BINARY_SUBTAG:
case SUB_BINARY_SUBTAG:
@@ -2327,6 +2845,46 @@ tailrecur_ne:
}
break; /* not equal */
}
+ case MAP_SUBTAG:
+ if (is_flatmap_rel(a, a_base)) {
+ aa = flatmap_val_rel(a, a_base);
+ if (!is_boxed(b) || *boxed_val_rel(b,b_base) != *aa)
+ goto not_equal;
+ bb = flatmap_val_rel(b,b_base);
+ sz = flatmap_get_size((flatmap_t*)aa);
+
+ if (sz != flatmap_get_size((flatmap_t*)bb)) goto not_equal;
+ if (sz == 0) goto pop_next;
+
+ aa += 2;
+ bb += 2;
+ sz += 1; /* increment for tuple-keys */
+ goto term_array;
+
+ } else {
+ if (!is_boxed(b) || *boxed_val_rel(b,b_base) != hdr)
+ goto not_equal;
+
+ aa = hashmap_val_rel(a, a_base) + 1;
+ bb = hashmap_val_rel(b, b_base) + 1;
+ switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ aa++; bb++;
+ sz = 16;
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ aa++; bb++;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(sz > 0 && sz < 17);
+ break;
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "Unknown hashmap subsubtag\n");
+ }
+ goto term_array;
+ }
+ default:
+ ASSERT(!"Unknown boxed subtab in EQ");
}
break;
}
@@ -2436,21 +2994,68 @@ static int cmp_atoms(Eterm a, Eterm b)
*/
Sint cmp(Eterm a, Eterm b)
{
- return erts_cmp(a, b, 0);
+ return erts_cmp(a, b, 0, 0);
}
#endif
+#if HALFWORD_HEAP
+static Sint erts_cmp_compound_rel_opt(Eterm a, Eterm* a_base,
+ Eterm b, Eterm* b_base,
+ int exact, int eq_only);
+#else
+static Sint erts_cmp_compound(Eterm a, Eterm b, int exact, int eq_only);
+#endif
+
+#if HALFWORD_HEAP
+Sint erts_cmp_rel_opt(Eterm a, Eterm* a_base,
+ Eterm b, Eterm* b_base,
+ int exact, int eq_only)
+#else
+Sint erts_cmp(Eterm a, Eterm b, int exact, int eq_only)
+#endif
+{
+ if (is_atom(a) && is_atom(b)) {
+ return cmp_atoms(a, b);
+ } else if (is_both_small(a, b)) {
+ return (signed_val(a) - signed_val(b));
+ } else if (is_float_rel(a, a_base) && is_float_rel(b, b_base)) {
+ FloatDef af, bf;
+ GET_DOUBLE_REL(a, af, a_base);
+ GET_DOUBLE_REL(b, bf, b_base);
+ return float_comp(af.fd, bf.fd);
+ }
+#if HALFWORD_HEAP
+ return erts_cmp_compound_rel_opt(a,a_base,b,b_base,exact,eq_only);
+#else
+ return erts_cmp_compound(a,b,exact,eq_only);
+#endif
+}
+
+
/* erts_cmp(Eterm a, Eterm b, int exact)
* exact = 1 -> term-based compare
* exact = 0 -> arith-based compare
*/
#if HALFWORD_HEAP
-Sint erts_cmp_rel_opt(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base, int exact)
+static Sint erts_cmp_compound_rel_opt(Eterm a, Eterm* a_base,
+ Eterm b, Eterm* b_base,
+ int exact, int eq_only)
#else
-Sint erts_cmp(Eterm a, Eterm b, int exact)
+static Sint erts_cmp_compound(Eterm a, Eterm b, int exact, int eq_only)
#endif
{
- DECLARE_WSTACK(stack);
+#define PSTACK_TYPE struct erts_cmp_hashmap_state
+ struct erts_cmp_hashmap_state {
+ Sint wstack_rollback;
+ int was_exact;
+ Eterm *ap;
+ Eterm *bp;
+ Eterm min_key;
+ Sint cmp_res; /* result so far -1,0,+1 */
+ };
+ PSTACK_DECLARE(hmap_stack, 1);
+ WSTACK_DECLARE(stack);
+ WSTACK_DECLARE(b_stack); /* only used by hashmaps */
Eterm* aa;
Eterm* bb;
int i;
@@ -2466,6 +3071,26 @@ Sint erts_cmp(Eterm a, Eterm b, int exact)
Uint32 *anum;
Uint32 *bnum;
+/* The WSTACK contains naked Eterms and Operations marked with header-tags */
+#define OP_BITS 4
+#define OP_MASK 0xF
+#define TERM_ARRAY_OP 0
+#define SWITCH_EXACT_OFF_OP 1
+#define HASHMAP_PHASE1_ARE_KEYS_EQUAL 2
+#define HASHMAP_PHASE1_IS_MIN_KEY 3
+#define HASHMAP_PHASE1_CMP_VALUES 4
+#define HASHMAP_PHASE2_ARE_KEYS_EQUAL 5
+#define HASHMAP_PHASE2_IS_MIN_KEY_A 6
+#define HASHMAP_PHASE2_IS_MIN_KEY_B 7
+
+
+#define OP_WORD(OP) (((OP) << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER)
+#define TERM_ARRAY_OP_WORD(SZ) OP_WORD(((SZ) << OP_BITS) | TERM_ARRAY_OP)
+
+#define GET_OP(WORD) (ASSERT(is_header(WORD)), ((WORD) >> _TAG_PRIMARY_SIZE) & OP_MASK)
+#define GET_OP_ARG(WORD) (ASSERT(is_header(WORD)), ((WORD) >> (OP_BITS + _TAG_PRIMARY_SIZE)))
+
+
#define RETURN_NEQ(cmp) { j=(cmp); ASSERT(j != 0); goto not_equal; }
#define ON_CMP_GOTO(cmp) if ((j=(cmp)) == 0) goto pop_next; else goto not_equal
@@ -2481,6 +3106,8 @@ Sint erts_cmp(Eterm a, Eterm b, int exact)
} while (0)
+bodyrecur:
+ j = 0;
tailrecur:
if (is_same(a,a_base,b,b_base)) { /* Equal values or pointers. */
goto pop_next;
@@ -2607,25 +3234,96 @@ tailrecur_ne:
++aa;
++bb;
goto term_array;
- case (_TAG_HEADER_MAP >> _TAG_PRIMARY_SIZE) :
- if (!is_map_rel(b,b_base)) {
- a_tag = MAP_DEF;
- goto mixed_types;
- }
- aa = (Eterm *)map_val_rel(a,a_base);
- bb = (Eterm *)map_val_rel(b,b_base);
-
- i = map_get_size((map_t*)aa);
- if (i != map_get_size((map_t*)bb)) {
- RETURN_NEQ((int)(i - map_get_size((map_t*)bb)));
- }
- if (i == 0) {
- goto pop_next;
+ case (_TAG_HEADER_MAP >> _TAG_PRIMARY_SIZE) :
+ {
+ struct erts_cmp_hashmap_state* sp;
+ if (is_flatmap_header(ahdr)) {
+ if (!is_flatmap_rel(b,b_base)) {
+ if (is_hashmap_rel(b,b_base)) {
+ aa = (Eterm *)flatmap_val_rel(a,a_base);
+ i = flatmap_get_size((flatmap_t*)aa) - hashmap_size_rel(b,b_base);
+ ASSERT(i != 0);
+ RETURN_NEQ(i);
+ }
+ a_tag = MAP_DEF;
+ goto mixed_types;
+ }
+ aa = (Eterm *)flatmap_val_rel(a,a_base);
+ bb = (Eterm *)flatmap_val_rel(b,b_base);
+
+ i = flatmap_get_size((flatmap_t*)aa);
+ if (i != flatmap_get_size((flatmap_t*)bb)) {
+ RETURN_NEQ((int)(i - flatmap_get_size((flatmap_t*)bb)));
+ }
+ if (i == 0) {
+ goto pop_next;
+ }
+ aa += 2;
+ bb += 2;
+ if (exact) {
+ i += 1; /* increment for tuple-keys */
+ goto term_array;
+ }
+ else {
+ /* Value array */
+ WSTACK_PUSH3(stack,(UWord)(bb+1),(UWord)(aa+1),TERM_ARRAY_OP_WORD(i));
+ /* Switch back from 'exact' key compare */
+ WSTACK_PUSH(stack,OP_WORD(SWITCH_EXACT_OFF_OP));
+ /* Now do 'exact' compare of key tuples */
+ a = *aa;
+ b = *bb;
+ exact = 1;
+ goto bodyrecur;
+ }
+ }
+ if (!is_hashmap_rel(b,b_base)) {
+ if (is_flatmap_rel(b,b_base)) {
+ bb = (Eterm *)flatmap_val_rel(b,b_base);
+ i = hashmap_size_rel(a,a_base) - flatmap_get_size((flatmap_t*)bb);
+ ASSERT(i != 0);
+ RETURN_NEQ(i);
+ }
+ a_tag = MAP_DEF;
+ goto mixed_types;
+ }
+ i = hashmap_size_rel(a,a_base) - hashmap_size_rel(b,b_base);
+ if (i) {
+ RETURN_NEQ(i);
+ }
+ if (hashmap_size_rel(a,a_base) == 0) {
+ goto pop_next;
+ }
+
+ /* Hashmap compare strategy:
+ Phase 1. While keys are identical
+ Do synchronous stepping through leafs of both trees in hash
+ order. Maintain value compare result of minimal key.
+
+ Phase 2. If key diff was found in phase 1
+ Ignore values from now on.
+ Continue iterate trees by always advancing the one
+ lagging behind hash-wise. Identical keys are skipped.
+ A minimal key can only be candidate as tie-breaker if we
+ have passed that hash value in the other tree (which means
+ the key did not exist in the other tree).
+ */
+
+ sp = PSTACK_PUSH(hmap_stack);
+ hashmap_iterator_init(&stack, a, 0);
+ hashmap_iterator_init(&b_stack, b, 0);
+ sp->ap = hashmap_iterator_next(&stack);
+ sp->bp = hashmap_iterator_next(&b_stack);
+ sp->cmp_res = 0;
+ ASSERT(sp->ap && sp->bp);
+
+ a = CAR(sp->ap);
+ b = CAR(sp->bp);
+ sp->was_exact = exact;
+ exact = 1;
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE1_ARE_KEYS_EQUAL));
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
}
- aa += 2;
- bb += 2;
- i += 1; /* increment for tuple-keys */
- goto term_array;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (!is_float_rel(b,b_base)) {
a_tag = FLOAT_DEF;
@@ -2985,8 +3683,7 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */
goto not_equal;
}
} else {
- /* (ab)Use TAG_PRIMARY_HEADER to recognize a term_array */
- WSTACK_PUSH3(stack, i, (UWord)bb, (UWord)aa | TAG_PRIMARY_HEADER);
+ WSTACK_PUSH3(stack, (UWord)bb, (UWord)aa, TERM_ARRAY_OP_WORD(i));
goto tailrecur_ne;
}
}
@@ -2998,22 +3695,179 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */
pop_next:
if (!WSTACK_ISEMPTY(stack)) {
UWord something = WSTACK_POP(stack);
- if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
- aa = (Eterm*) something;
- bb = (Eterm*) WSTACK_POP(stack);
- i = WSTACK_POP(stack);
- goto term_array;
+ struct erts_cmp_hashmap_state* sp;
+ if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* an operation */
+ switch (GET_OP(something)) {
+ case TERM_ARRAY_OP:
+ i = GET_OP_ARG(something);
+ aa = (Eterm*)WSTACK_POP(stack);
+ bb = (Eterm*) WSTACK_POP(stack);
+ goto term_array;
+
+ case SWITCH_EXACT_OFF_OP:
+ /* Done with exact compare of map keys, switch back */
+ ASSERT(exact);
+ exact = 0;
+ goto pop_next;
+
+ case HASHMAP_PHASE1_ARE_KEYS_EQUAL: {
+ sp = PSTACK_TOP(hmap_stack);
+ if (j) {
+ /* Key diff found, enter phase 2 */
+ if (hashmap_key_hash_cmp(sp->ap, sp->bp) < 0) {
+ sp->min_key = CAR(sp->ap);
+ sp->cmp_res = -1;
+ sp->ap = hashmap_iterator_next(&stack);
+ }
+ else {
+ sp->min_key = CAR(sp->bp);
+ sp->cmp_res = 1;
+ sp->bp = hashmap_iterator_next(&b_stack);
+ }
+ exact = 1; /* only exact key compares in phase 2 */
+ goto case_HASHMAP_PHASE2_LOOP;
+ }
+
+ /* No key diff found so far, compare values if min key */
+
+ if (sp->cmp_res) {
+ a = CAR(sp->ap);
+ b = sp->min_key;
+ exact = 1;
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE1_IS_MIN_KEY));
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
+ }
+ /* no min key-value found yet */
+ a = CDR(sp->ap);
+ b = CDR(sp->bp);
+ exact = sp->was_exact;
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE1_CMP_VALUES));
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
+ }
+ case HASHMAP_PHASE1_IS_MIN_KEY:
+ sp = PSTACK_TOP(hmap_stack);
+ if (j < 0) {
+ a = CDR(sp->ap);
+ b = CDR(sp->bp);
+ exact = sp->was_exact;
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE1_CMP_VALUES));
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
+ }
+ goto case_HASHMAP_PHASE1_LOOP;
+
+ case HASHMAP_PHASE1_CMP_VALUES:
+ sp = PSTACK_TOP(hmap_stack);
+ if (j) {
+ sp->cmp_res = j;
+ sp->min_key = CAR(sp->ap);
+ }
+ case_HASHMAP_PHASE1_LOOP:
+ sp->ap = hashmap_iterator_next(&stack);
+ sp->bp = hashmap_iterator_next(&b_stack);
+ if (!sp->ap) {
+ /* end of maps with identical keys */
+ ASSERT(!sp->bp);
+ j = sp->cmp_res;
+ exact = sp->was_exact;
+ (void) PSTACK_POP(hmap_stack);
+ ON_CMP_GOTO(j);
+ }
+ a = CAR(sp->ap);
+ b = CAR(sp->bp);
+ exact = 1;
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE1_ARE_KEYS_EQUAL));
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
+
+ case_HASHMAP_PHASE2_LOOP:
+ if (sp->ap && sp->bp) {
+ a = CAR(sp->ap);
+ b = CAR(sp->bp);
+ ASSERT(exact);
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE2_ARE_KEYS_EQUAL));
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
+ }
+ goto case_HASHMAP_PHASE2_NEXT_STEP;
+
+ case HASHMAP_PHASE2_ARE_KEYS_EQUAL:
+ sp = PSTACK_TOP(hmap_stack);
+ if (j == 0) {
+ /* keys are equal, skip them */
+ sp->ap = hashmap_iterator_next(&stack);
+ sp->bp = hashmap_iterator_next(&b_stack);
+ goto case_HASHMAP_PHASE2_LOOP;
+ }
+ /* fall through */
+ case_HASHMAP_PHASE2_NEXT_STEP:
+ if (sp->ap || sp->bp) {
+ if (hashmap_key_hash_cmp(sp->ap, sp->bp) < 0) {
+ ASSERT(sp->ap);
+ a = CAR(sp->ap);
+ b = sp->min_key;
+ ASSERT(exact);
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE2_IS_MIN_KEY_A));
+ }
+ else { /* hash_cmp > 0 */
+ ASSERT(sp->bp);
+ a = CAR(sp->bp);
+ b = sp->min_key;
+ ASSERT(exact);
+ WSTACK_PUSH(stack, OP_WORD(HASHMAP_PHASE2_IS_MIN_KEY_B));
+ }
+ sp->wstack_rollback = WSTACK_COUNT(stack);
+ goto bodyrecur;
+ }
+ /* End of both maps */
+ j = sp->cmp_res;
+ exact = sp->was_exact;
+ (void) PSTACK_POP(hmap_stack);
+ ON_CMP_GOTO(j);
+
+ case HASHMAP_PHASE2_IS_MIN_KEY_A:
+ sp = PSTACK_TOP(hmap_stack);
+ if (j < 0) {
+ sp->min_key = CAR(sp->ap);
+ sp->cmp_res = -1;
+ }
+ sp->ap = hashmap_iterator_next(&stack);
+ goto case_HASHMAP_PHASE2_LOOP;
+
+ case HASHMAP_PHASE2_IS_MIN_KEY_B:
+ sp = PSTACK_TOP(hmap_stack);
+ if (j < 0) {
+ sp->min_key = CAR(sp->bp);
+ sp->cmp_res = 1;
+ }
+ sp->bp = hashmap_iterator_next(&b_stack);
+ goto case_HASHMAP_PHASE2_LOOP;
+
+ default:
+ ASSERT(!"Invalid cmp op");
+ } /* switch */
}
a = (Eterm) something;
b = (Eterm) WSTACK_POP(stack);
goto tailrecur;
}
- DESTROY_WSTACK(stack);
+ ASSERT(PSTACK_IS_EMPTY(hmap_stack));
+ PSTACK_DESTROY(hmap_stack);
+ WSTACK_DESTROY(stack);
+ WSTACK_DESTROY(b_stack);
return 0;
not_equal:
- DESTROY_WSTACK(stack);
+ if (!PSTACK_IS_EMPTY(hmap_stack) && !eq_only) {
+ WSTACK_ROLLBACK(stack, PSTACK_TOP(hmap_stack)->wstack_rollback);
+ goto pop_next;
+ }
+ PSTACK_DESTROY(hmap_stack);
+ WSTACK_DESTROY(stack);
+ WSTACK_DESTROY(b_stack);
return j;
#undef CMP_NODES
@@ -3663,145 +4517,6 @@ is_string(Eterm list)
return 0;
}
-#ifdef ERTS_SMP
-
-/*
- * Process and Port timers in smp case
- */
-
-ERTS_SCHED_PREF_PRE_ALLOC_IMPL(ptimer_pre, ErtsSmpPTimer, 1000)
-
-#define ERTS_PTMR_FLGS_ALLCD_SIZE \
- 2
-#define ERTS_PTMR_FLGS_ALLCD_MASK \
- ((((Uint32) 1) << ERTS_PTMR_FLGS_ALLCD_SIZE) - 1)
-
-#define ERTS_PTMR_FLGS_PREALLCD ((Uint32) 1)
-#define ERTS_PTMR_FLGS_SLALLCD ((Uint32) 2)
-#define ERTS_PTMR_FLGS_LLALLCD ((Uint32) 3)
-#define ERTS_PTMR_FLG_CANCELLED (((Uint32) 1) << (ERTS_PTMR_FLGS_ALLCD_SIZE+0))
-
-static void
-init_ptimers(void)
-{
- init_ptimer_pre_alloc();
-}
-
-static ERTS_INLINE void
-free_ptimer(ErtsSmpPTimer *ptimer)
-{
- switch (ptimer->timer.flags & ERTS_PTMR_FLGS_ALLCD_MASK) {
- case ERTS_PTMR_FLGS_PREALLCD:
- (void) ptimer_pre_free(ptimer);
- break;
- case ERTS_PTMR_FLGS_SLALLCD:
- erts_free(ERTS_ALC_T_SL_PTIMER, (void *) ptimer);
- break;
- case ERTS_PTMR_FLGS_LLALLCD:
- erts_free(ERTS_ALC_T_LL_PTIMER, (void *) ptimer);
- break;
- default:
- erl_exit(ERTS_ABORT_EXIT,
- "Internal error: Bad ptimer alloc type\n");
- break;
- }
-}
-
-/* Callback for process timeout cancelled */
-static void
-ptimer_cancelled(ErtsSmpPTimer *ptimer)
-{
- free_ptimer(ptimer);
-}
-
-/* Callback for process timeout */
-static void
-ptimer_timeout(ErtsSmpPTimer *ptimer)
-{
- if (is_internal_pid(ptimer->timer.id)) {
- Process *p;
- p = erts_pid2proc_opt(NULL,
- 0,
- ptimer->timer.id,
- ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS,
- ERTS_P2P_FLG_ALLOW_OTHER_X);
- if (p) {
- if (!ERTS_PROC_IS_EXITING(p)
- && !(ptimer->timer.flags & ERTS_PTMR_FLG_CANCELLED)) {
- ASSERT(*ptimer->timer.timer_ref == ptimer);
- *ptimer->timer.timer_ref = NULL;
- (*ptimer->timer.timeout_func)(p);
- }
- erts_smp_proc_unlock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS);
- }
- }
- else {
- Port *p;
- ASSERT(is_internal_port(ptimer->timer.id));
- p = erts_id2port_sflgs(ptimer->timer.id,
- NULL,
- 0,
- ERTS_PORT_SFLGS_DEAD);
- if (p) {
- if (!(ptimer->timer.flags & ERTS_PTMR_FLG_CANCELLED)) {
- ASSERT(*ptimer->timer.timer_ref == ptimer);
- *ptimer->timer.timer_ref = NULL;
- (*ptimer->timer.timeout_func)(p);
- }
- erts_port_release(p);
- }
- }
- free_ptimer(ptimer);
-}
-
-void
-erts_create_smp_ptimer(ErtsSmpPTimer **timer_ref,
- Eterm id,
- ErlTimeoutProc timeout_func,
- Uint timeout)
-{
- ErtsSmpPTimer *res = ptimer_pre_alloc();
- if (res)
- res->timer.flags = ERTS_PTMR_FLGS_PREALLCD;
- else {
- if (timeout < ERTS_ALC_MIN_LONG_LIVED_TIME) {
- res = erts_alloc(ERTS_ALC_T_SL_PTIMER, sizeof(ErtsSmpPTimer));
- res->timer.flags = ERTS_PTMR_FLGS_SLALLCD;
- }
- else {
- res = erts_alloc(ERTS_ALC_T_LL_PTIMER, sizeof(ErtsSmpPTimer));
- res->timer.flags = ERTS_PTMR_FLGS_LLALLCD;
- }
- }
- res->timer.timeout_func = timeout_func;
- res->timer.timer_ref = timer_ref;
- res->timer.id = id;
- res->timer.tm.active = 0; /* MUST be initalized */
-
- ASSERT(!*timer_ref);
-
- *timer_ref = res;
-
- erts_set_timer(&res->timer.tm,
- (ErlTimeoutProc) ptimer_timeout,
- (ErlCancelProc) ptimer_cancelled,
- (void*) res,
- timeout);
-}
-
-void
-erts_cancel_smp_ptimer(ErtsSmpPTimer *ptimer)
-{
- if (ptimer) {
- ASSERT(*ptimer->timer.timer_ref == ptimer);
- *ptimer->timer.timer_ref = NULL;
- ptimer->timer.flags |= ERTS_PTMR_FLG_CANCELLED;
- erts_cancel_timer(&ptimer->timer.tm);
- }
-}
-
-#endif
-
static int trim_threshold;
static int top_pad;
static int mmap_threshold;
@@ -3811,9 +4526,7 @@ Uint tot_bin_allocated;
void erts_init_utils(void)
{
-#ifdef ERTS_SMP
- init_ptimers();
-#endif
+
}
void erts_init_utils_mem(void)
@@ -4353,8 +5066,8 @@ erts_smp_ensure_later_interval_acqb(erts_interval_t *icp, Uint64 ic)
*/
Uint64 erts_timestamp_millis(void)
{
-#ifdef HAVE_GETHRTIME
- return (Uint64) (sys_gethrtime() / 1000000);
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ return ERTS_MONOTONIC_TO_MSEC(erts_os_monotonic_time());
#else
Uint64 res;
SysTimeval tv;
diff --git a/erts/emulator/beam/version.h b/erts/emulator/beam/version.h
index 3952c751b7..004725eaf5 100644
--- a/erts/emulator/beam/version.h
+++ b/erts/emulator/beam/version.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index 3b8e7acb6e..5e25747ddf 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -124,8 +125,6 @@
#include "dtrace-wrapper.h"
-void erl_exit(int n, char *fmt, ...);
-
static ErlDrvSysInfo sys_info;
/* For explanation of this var, see comment for same var in erl_async.c */
@@ -514,21 +513,10 @@ struct t_data
static void *ef_safe_alloc(Uint s)
{
void *p = EF_ALLOC(s);
- if (!p) erl_exit(1, "efile drv: Can't allocate %lu bytes of memory\n", (unsigned long)s);
- return p;
-}
-
-#if 0 /* Currently not used */
-
-static void *ef_safe_realloc(void *op, Uint s)
-{
- void *p = EF_REALLOC(op, s);
- if (!p) erl_exit(1, "efile drv: Can't reallocate %lu bytes of memory\n", (unsigned long)s);
+ if (!p) erts_exit(ERTS_ERROR_EXIT, "efile drv: Can't allocate %lu bytes of memory\n", (unsigned long)s);
return p;
}
-#endif
-
/*********************************************************************
* ErlIOVec manipulation functions.
*/
@@ -1531,10 +1519,10 @@ static void invoke_writev(void *data) {
* with errno.
*/
errno = EINVAL;
- if (! (status =
- erts_gzwrite((ErtsGzFile)d->fd,
- iov[i].iov_base,
- iov[i].iov_len)) == iov[i].iov_len) {
+ status = erts_gzwrite((ErtsGzFile)d->fd,
+ iov[i].iov_base,
+ iov[i].iov_len) == iov[i].iov_len;
+ if (! status) {
d->errInfo.posix_errno =
d->errInfo.os_errno = errno; /* XXX Correct? */
break;
@@ -1616,12 +1604,12 @@ static void invoke_altname(void *data)
}
static void invoke_pwritev(void *data) {
- struct t_data *d = (struct t_data *) data;
+ struct t_data* const d = (struct t_data *) data;
+ struct t_pwritev * const c = &d->c.pwritev;
SysIOVec *iov0;
SysIOVec *iov;
int iovlen;
int iovcnt;
- struct t_pwritev *c = &d->c.pwritev;
size_t p;
int segment;
size_t size, write_size, written;
@@ -1695,9 +1683,9 @@ static void invoke_pwritev(void *data) {
d->result_ok = 0;
d->again = 0;
deq_error:
- MUTEX_LOCK(d->c.writev.q_mtx);
- driver_deq(d->c.pwritev.port, c->size);
- MUTEX_UNLOCK(d->c.writev.q_mtx);
+ MUTEX_LOCK(c->q_mtx);
+ driver_deq(c->port, c->size);
+ MUTEX_UNLOCK(c->q_mtx);
goto done;
} else {
@@ -1708,9 +1696,9 @@ static void invoke_pwritev(void *data) {
ASSERT(written >= FILE_SEGMENT_WRITE);
}
- MUTEX_LOCK(d->c.writev.q_mtx);
- driver_deq(d->c.pwritev.port, written);
- MUTEX_UNLOCK(d->c.writev.q_mtx);
+ MUTEX_LOCK(c->q_mtx);
+ driver_deq(c->port, written);
+ MUTEX_UNLOCK(c->q_mtx);
done:
EF_FREE(iov); /* Free our copy of the vector, nothing to restore */
@@ -1938,6 +1926,8 @@ static void invoke_sendfile(void *data)
d->result_ok = 1;
if (d->c.sendfile.nbytes != 0)
d->c.sendfile.nbytes -= nbytes;
+ } else if (nbytes == 0 && d->c.sendfile.nbytes == 0) {
+ d->result_ok = 1;
} else
d->result_ok = 0;
} else {
@@ -2578,7 +2568,6 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
case FILE_CLOSE_ON_PORT_EXIT:
/* See file_stop. However this is never invoked after the port is killed. */
free_data(data);
- EF_FREE(desc);
desc = NULL;
/* This is it for this port, so just send dtrace and return, avoid doing anything to the freed data */
DTRACE6(efile_drv_return, sched_i1, sched_i2, sched_utag,
diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index 5a8e3bc5db..be5a891486 100644
--- a/erts/emulator/drivers/common/erl_efile.h
+++ b/erts/emulator/drivers/common/erl_efile.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/drivers/common/gzio.h b/erts/emulator/drivers/common/gzio.h
index ea50d922ec..a6fe2fb6f5 100644
--- a/erts/emulator/drivers/common/gzio.h
+++ b/erts/emulator/drivers/common/gzio.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/common/gzio_zutil.h b/erts/emulator/drivers/common/gzio_zutil.h
index 854205cc2c..9eefb86637 100644
--- a/erts/emulator/drivers/common/gzio_zutil.h
+++ b/erts/emulator/drivers/common/gzio_zutil.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 3c6922eb8e..2d2bd80783 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2013. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -293,6 +294,10 @@ static BOOL (WINAPI *fpSetHandleInformation)(HANDLE,DWORD,DWORD);
static unsigned long zero_value = 0;
static unsigned long one_value = 1;
+#define TCP_SHUT_WR SD_SEND
+#define TCP_SHUT_RD SD_RECEIVE
+#define TCP_SHUT_RDWR SD_BOTH
+
#elif defined (__OSE__)
/*
@@ -421,6 +426,10 @@ typedef unsigned long u_long;
inet_driver_select((d), (flags), (onoff)); \
} while(0)
+#define TCP_SHUT_WR SHUT_WR
+#define TCP_SHUT_RD SHUT_RD
+#define TCP_SHUT_RDWR SHUT_RDWR
+
#else /* !__OSE__ && !__WIN32__ */
#include <sys/time.h>
@@ -691,6 +700,9 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
inet_driver_select((d)->port, (ErlDrvEvent)(long)(d)->event, (flags), (onoff)); \
} while(0)
+#define TCP_SHUT_WR SHUT_WR
+#define TCP_SHUT_RD SHUT_RD
+#define TCP_SHUT_RDWR SHUT_RDWR
#endif /* !__WIN32__ && !__OSE__ */
@@ -820,6 +832,14 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define TCP_ADDF_CLOSE_SENT 2 /* Close sent (active mode only) */
#define TCP_ADDF_DELAYED_CLOSE_RECV 4 /* If receive fails, report {error,closed} (passive mode) */
#define TCP_ADDF_DELAYED_CLOSE_SEND 8 /* If send fails, report {error,closed} (passive mode) */
+#define TCP_ADDF_PENDING_SHUT_WR 16 /* Call shutdown(sock, SHUT_WR) when queue empties */
+#define TCP_ADDF_PENDING_SHUT_RDWR 32 /* Call shutdown(sock, SHUT_RDWR) when queue empties */
+#define TCP_ADDF_PENDING_SHUTDOWN \
+ (TCP_ADDF_PENDING_SHUT_WR | TCP_ADDF_PENDING_SHUT_RDWR)
+#define TCP_ADDF_SHOW_ECONNRESET 64 /* Tell user about incoming RST */
+#define TCP_ADDF_DELAYED_ECONNRESET 128 /* An ECONNRESET error occured on send or shutdown */
+#define TCP_ADDF_SHUTDOWN_WR_DONE 256 /* A shutdown(sock, SHUT_WR) or SHUT_RDWR was made */
+#define TCP_ADDF_LINGER_ZERO 512 /* Discard driver queue on port close */
/* *_REQ_* replies */
#define INET_REP_ERROR 0
@@ -864,6 +884,8 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define INET_LOPT_MSGQ_HIWTRMRK 36 /* set local msgq high watermark */
#define INET_LOPT_MSGQ_LOWTRMRK 37 /* set local msgq low watermark */
#define INET_LOPT_NETNS 38 /* Network namespace pathname */
+#define INET_LOPT_TCP_SHOW_ECONNRESET 39 /* tell user about incoming RST */
+#define INET_LOPT_LINE_DELIM 40 /* Line delimiting char */
/* SCTP options: a separate range, from 100: */
#define SCTP_OPT_RTOINFO 100
#define SCTP_OPT_ASSOCINFO 101
@@ -1026,7 +1048,7 @@ typedef union {
#endif
typedef struct _multi_timer_data {
- ErlDrvNowData when;
+ ErlDrvTime when;
ErlDrvTermData caller;
void (*timeout_function)(ErlDrvData drv_data, ErlDrvTermData caller);
struct _multi_timer_data *next;
@@ -1133,6 +1155,7 @@ typedef struct {
#else
Uint32 send_oct[2]; /* number of octets sent, 64 bits */
#endif
+ char delimiter; /* Line delimiting character (def: '\n') */
unsigned long send_cnt; /* number of packets sent */
unsigned long send_max; /* maximum packet send */
double send_avg; /* average packet size sent */
@@ -1407,6 +1430,8 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev);
static int tcp_recv(tcp_descriptor* desc, int request_len);
static int tcp_deliver(tcp_descriptor* desc, int len);
+static int tcp_shutdown_error(tcp_descriptor* desc, int err);
+
static int tcp_inet_output(tcp_descriptor* desc, HANDLE event);
static int tcp_inet_input(tcp_descriptor* desc, HANDLE event);
@@ -1549,7 +1574,7 @@ static const struct in6_addr in6addr_loopback =
#endif /* HAVE_IN6 */
/* XXX: is this a driver interface function ??? */
-void erl_exit(int n, char*, ...);
+void erts_exit(int n, char*, ...);
/*
* Malloc wrapper,
@@ -1562,7 +1587,7 @@ void erl_exit(int n, char*, ...);
static void *alloc_wrapper(ErlDrvSizeT size){
void *ret = driver_alloc(size);
if(ret == NULL)
- erl_exit(1,"Out of virtual memory in malloc (%s)", __FILE__);
+ erts_exit(ERTS_ERROR_EXIT,"Out of virtual memory in malloc (%s)", __FILE__);
return ret;
}
#define ALLOC(X) alloc_wrapper(X)
@@ -1570,7 +1595,7 @@ static void *alloc_wrapper(ErlDrvSizeT size){
static void *realloc_wrapper(void *current, ErlDrvSizeT size){
void *ret = driver_realloc(current,size);
if(ret == NULL)
- erl_exit(1,"Out of virtual memory in realloc (%s)", __FILE__);
+ erts_exit(ERTS_ERROR_EXIT,"Out of virtual memory in realloc (%s)", __FILE__);
return ret;
}
#define REALLOC(X,Y) realloc_wrapper(X,Y)
@@ -1831,7 +1856,7 @@ check_double_release(InetDrvBufStk *bs, ErlDrvBinary* buf)
int i;
for (i = 0; i < bs->buf.pos; ++i) {
if (bs->buf.stk[i] == buf) {
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Multiple buffer release in inet_drv, this "
"is a bug, save the core and send it to "
@@ -2726,7 +2751,7 @@ int ssl_tls_inetdrv(void* arg, unsigned type, unsigned major, unsigned minor,
{
tcp_descriptor* desc = (tcp_descriptor*) arg;
int i = 0;
- ErlDrvTermData spec[28];
+ ErlDrvTermData spec[30];
ErlDrvTermData caller = ERL_DRV_NIL;
ErlDrvBinary* bin;
int ret;
@@ -2767,11 +2792,11 @@ int ssl_tls_inetdrv(void* arg, unsigned type, unsigned major, unsigned minor,
if (desc->inet.active == INET_PASSIVE) {
i = LOAD_TUPLE(spec, i, 2);
i = LOAD_TUPLE(spec, i, 4);
- ASSERT(i <= 28);
+ ASSERT(i <= sizeof(spec)/sizeof(*spec));
ret = erl_drv_send_term(desc->inet.dport, caller, spec, i);
}
else {
- ASSERT(i <= 28);
+ ASSERT(i <= sizeof(spec)/sizeof(*spec));
ret = erl_drv_output_term(desc->inet.dport, spec, i);
}
done:
@@ -3957,9 +3982,9 @@ static int inet_init()
if (0 != erl_drv_tsd_key_create("inet_buffer_stack_key", &buffer_stack_key))
goto error;
- ASSERT(sizeof(struct in_addr) == 4);
+ ERTS_CT_ASSERT(sizeof(struct in_addr) == 4);
# if defined(HAVE_IN6) && defined(AF_INET6)
- ASSERT(sizeof(struct in6_addr) == 16);
+ ERTS_CT_ASSERT(sizeof(struct in6_addr) == 16);
# endif
INIT_ATOM(ok);
@@ -4005,7 +4030,7 @@ static int inet_init()
#ifdef HAVE_SCTP
/* Check the size of SCTP AssocID -- currently both this driver and the
Erlang part require 32 bit: */
- ASSERT(sizeof(sctp_assoc_t)==ASSOC_ID_LEN);
+ ERTS_CT_ASSERT(sizeof(sctp_assoc_t)==ASSOC_ID_LEN);
# if defined(HAVE_SCTP_BINDX)
p_sctp_bindx = sctp_bindx;
# if defined(HAVE_SCTP_PEELOFF)
@@ -6051,9 +6076,9 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
int arg_sz;
enum PacketParseType old_htype = desc->htype;
int old_active = desc->active;
- int propagate = 0; /* Set to 1 if failure to set this option
- should be propagated to erlang (not all
- errors can be propagated for BC reasons) */
+ int propagate; /* Set to 1 if failure to set this option
+ should be propagated to erlang (not all
+ errors can be propagated for BC reasons) */
int res;
#ifdef HAVE_SCTP
/* SCTP sockets are treated completely separately: */
@@ -6070,6 +6095,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
arg_ptr = (char*) &ival;
arg_sz = sizeof(ival);
proto = SOL_SOCKET;
+ propagate = 0;
switch(opt) {
case INET_LOPT_HEADER:
@@ -6121,7 +6147,12 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
desc->active_count = 0;
if ((desc->stype == SOCK_STREAM) && (desc->active != INET_PASSIVE) &&
(desc->state == INET_STATE_CLOSED)) {
- tcp_closed_message((tcp_descriptor *) desc);
+ tcp_descriptor *tdesc = (tcp_descriptor *) desc;
+ if (tdesc->tcp_add_flags & TCP_ADDF_DELAYED_ECONNRESET) {
+ tdesc->tcp_add_flags &= ~TCP_ADDF_DELAYED_ECONNRESET;
+ tcp_error_message(tdesc, ECONNRESET);
+ }
+ tcp_closed_message(tdesc);
if (desc->exitf) {
driver_exit(desc->port, 0);
return 0; /* Give up on this socket, descriptor lost */
@@ -6238,6 +6269,22 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
continue;
#endif
+ case INET_LOPT_TCP_SHOW_ECONNRESET:
+ if (desc->sprotocol == IPPROTO_TCP) {
+ tcp_descriptor* tdesc = (tcp_descriptor*) desc;
+ if (ival)
+ tdesc->tcp_add_flags |= TCP_ADDF_SHOW_ECONNRESET;
+ else
+ tdesc->tcp_add_flags &= ~TCP_ADDF_SHOW_ECONNRESET;
+ }
+ continue;
+
+ case INET_LOPT_LINE_DELIM:
+ DEBUGF(("inet_set_opts(%ld): s=%d, LINE_DELIM=%d\r\n",
+ (long)desc->port, desc->s, ival));
+ desc->delimiter = (char)ival;
+ continue;
+
case INET_OPT_REUSEADDR:
#ifdef __WIN32__
continue; /* Bjorn says */
@@ -6282,6 +6329,13 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
arg_sz = sizeof(li_val);
DEBUGF(("inet_set_opts(%ld): s=%d, SO_LINGER=%d,%d",
(long)desc->port, desc->s, li_val.l_onoff,li_val.l_linger));
+ if (desc->sprotocol == IPPROTO_TCP) {
+ tcp_descriptor* tdesc = (tcp_descriptor*) desc;
+ if (li_val.l_onoff && li_val.l_linger == 0)
+ tdesc->tcp_add_flags |= TCP_ADDF_LINGER_ZERO;
+ else
+ tdesc->tcp_add_flags &= ~TCP_ADDF_LINGER_ZERO;
+ }
break;
case INET_OPT_PRIORITY:
@@ -7063,7 +7117,7 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc,
do { \
ErlDrvSizeT new_need = ((Ptr) - (*dest)) + (Size); \
if (new_need > dest_used) { \
- erl_exit(1,"Internal error in inet_drv, " \
+ erts_exit(ERTS_ERROR_EXIT,"Internal error in inet_drv, " \
"miscalculated buffer size"); \
} \
dest_used = new_need; \
@@ -7217,6 +7271,17 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc,
continue;
#endif
+ case INET_LOPT_TCP_SHOW_ECONNRESET:
+ if (desc->sprotocol == IPPROTO_TCP) {
+ tcp_descriptor* tdesc = (tcp_descriptor*) desc;
+ *ptr++ = opt;
+ ival = !!(tdesc->tcp_add_flags & TCP_ADDF_SHOW_ECONNRESET);
+ put_int32(ival, ptr);
+ } else {
+ TRUNCATE_TO(0,ptr);
+ }
+ continue;
+
case INET_OPT_PRIORITY:
#ifdef SO_PRIORITY
type = SO_PRIORITY;
@@ -7429,7 +7494,7 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc,
do { \
int need; \
if ((Index) > spec_allocated) { \
- erl_exit(1,"Internal error in inet_drv, " \
+ erts_exit(ERTS_ERROR_EXIT,"Internal error in inet_drv, " \
"miscalculated buffer size"); \
} \
need = (Index) + (N); \
@@ -8315,6 +8380,7 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)
desc->deliver = INET_DELIVER_TERM; /* standard term format */
desc->active = INET_PASSIVE; /* start passive */
desc->active_count = 0;
+ desc->delimiter = '\n'; /* line delimiting char */
desc->oph = NULL;
desc->opt = NULL;
@@ -9060,6 +9126,11 @@ static tcp_descriptor* tcp_inet_copy(tcp_descriptor* desc,SOCKET s,
copy_desc->low = desc->low;
copy_desc->send_timeout = desc->send_timeout;
copy_desc->send_timeout_close = desc->send_timeout_close;
+
+ if (desc->tcp_add_flags & TCP_ADDF_SHOW_ECONNRESET)
+ copy_desc->tcp_add_flags |= TCP_ADDF_SHOW_ECONNRESET;
+ else
+ copy_desc->tcp_add_flags &= ~TCP_ADDF_SHOW_ECONNRESET;
/* The new port will be linked and connected to the original caller */
port = driver_create_port(port, owner, "tcp_inet", (ErlDrvData) copy_desc);
@@ -9421,7 +9492,11 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
if (desc->tcp_add_flags & TCP_ADDF_DELAYED_CLOSE_RECV) {
desc->tcp_add_flags &= ~(TCP_ADDF_DELAYED_CLOSE_RECV|
TCP_ADDF_DELAYED_CLOSE_SEND);
- return ctl_reply(INET_REP_ERROR, "closed", 6, rbuf, rsize);
+ if (desc->tcp_add_flags & TCP_ADDF_DELAYED_ECONNRESET) {
+ desc->tcp_add_flags &= ~TCP_ADDF_DELAYED_ECONNRESET;
+ return ctl_reply(INET_REP_ERROR, "econnreset", 10, rbuf, rsize);
+ } else
+ return ctl_reply(INET_REP_ERROR, "closed", 6, rbuf, rsize);
}
return ctl_error(ENOTCONN, rbuf, rsize);
}
@@ -9473,10 +9548,20 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
return ctl_error(EINVAL, rbuf, rsize);
}
how = buf[0];
- if (sock_shutdown(INETP(desc)->s, how) == 0) {
+ if (how != TCP_SHUT_RD && driver_sizeq(desc->inet.port) > 0) {
+ if (how == TCP_SHUT_WR) {
+ desc->tcp_add_flags |= TCP_ADDF_PENDING_SHUT_WR;
+ } else if (how == TCP_SHUT_RDWR) {
+ desc->tcp_add_flags |= TCP_ADDF_PENDING_SHUT_RDWR;
+ }
return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
- } else {
+ }
+ if (IS_SOCKET_ERROR(sock_shutdown(INETP(desc)->s, how))) {
+ if (how != TCP_SHUT_RD)
+ desc->tcp_add_flags |= TCP_ADDF_SHUTDOWN_WR_DONE;
return ctl_error(sock_errno(), rbuf, rsize);
+ } else {
+ return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
}
}
default:
@@ -9608,11 +9693,19 @@ static void tcp_inet_commandv(ErlDrvData e, ErlIOVec* ev)
if (!IS_CONNECTED(INETP(desc))) {
if (desc->tcp_add_flags & TCP_ADDF_DELAYED_CLOSE_SEND) {
desc->tcp_add_flags &= ~TCP_ADDF_DELAYED_CLOSE_SEND;
- inet_reply_error_am(INETP(desc), am_closed);
+ if (desc->tcp_add_flags & TCP_ADDF_DELAYED_ECONNRESET) {
+ /* Don't clear flag. Leave it enabled for the next receive
+ * operation.
+ */
+ inet_reply_error(INETP(desc), ECONNRESET);
+ } else
+ inet_reply_error_am(INETP(desc), am_closed);
}
else
inet_reply_error(INETP(desc), ENOTCONN);
}
+ else if (desc->tcp_add_flags & TCP_ADDF_PENDING_SHUTDOWN)
+ tcp_shutdown_error(desc, EPIPE);
else if (tcp_sendv(desc, ev) == 0)
inet_reply_ok(INETP(desc));
DEBUGF(("tcp_inet_commandv(%ld) }\r\n", (long)desc->inet.port));
@@ -9625,6 +9718,8 @@ static void tcp_inet_flush(ErlDrvData e)
/* Discard send queue to avoid hanging port (OTP-7615) */
tcp_clear_output(desc);
}
+ if (desc->tcp_add_flags & TCP_ADDF_LINGER_ZERO)
+ tcp_clear_output(desc);
}
static void tcp_inet_process_exit(ErlDrvData e, ErlDrvMonitor *monitorp)
@@ -9797,7 +9892,7 @@ static int tcp_remain(tcp_descriptor* desc, int* len)
tlen = packet_get_length(desc->inet.htype, ptr, n,
desc->inet.psize, desc->i_bufsz,
- &desc->http_state);
+ desc->inet.delimiter, &desc->http_state);
DEBUGF(("tcp_remain(%ld): s=%d, n=%d, nfill=%d nsz=%d, tlen %d\r\n",
(long)desc->inet.port, desc->inet.s, n, nfill, nsz, tlen));
@@ -9987,7 +10082,10 @@ static int tcp_recv(tcp_descriptor* desc, int request_len)
int err = sock_errno();
if (err == ECONNRESET) {
DEBUGF((" => detected close (connreset)\r\n"));
- return tcp_recv_closed(desc);
+ if (desc->tcp_add_flags & TCP_ADDF_SHOW_ECONNRESET)
+ return tcp_recv_error(desc, err);
+ else
+ return tcp_recv_closed(desc);
}
if (err == ERRNO_BLOCK) {
DEBUGF((" => would block\r\n"));
@@ -10199,7 +10297,19 @@ static void tcp_inet_event(ErlDrvData e, ErlDrvEvent event)
if (netEv.lNetworkEvents & FD_CLOSE) {
/* error in err = netEv.iErrorCode[FD_CLOSE_BIT] */
DEBUGF(("Detected close in %s, line %d\r\n", __FILE__, __LINE__));
- tcp_recv_closed(desc);
+ if (desc->tcp_add_flags & TCP_ADDF_SHOW_ECONNRESET) {
+ err = netEv.iErrorCode[FD_CLOSE_BIT];
+ if (err == ECONNRESET)
+ tcp_recv_error(desc, err);
+ else if (err == ECONNABORTED && IS_CONNECTED(INETP(desc))) {
+ /* translate this error to ECONNRESET */
+ tcp_recv_error(desc, ECONNRESET);
+ }
+ else
+ tcp_recv_closed(desc);
+ }
+ else
+ tcp_recv_closed(desc);
}
DEBUGF(("tcp_inet_event(%ld) }\r\n", (long)desc->inet.port));
return;
@@ -10506,8 +10616,11 @@ static int tcp_inet_input(tcp_descriptor* desc, HANDLE event)
return ret;
}
-static int tcp_send_error(tcp_descriptor* desc, int err)
+static int tcp_send_or_shutdown_error(tcp_descriptor* desc, int err)
{
+ int show_econnreset = (err == ECONNRESET
+ && desc->tcp_add_flags & TCP_ADDF_SHOW_ECONNRESET);
+
/*
* If the port is busy, we must do some clean-up before proceeding.
*/
@@ -10523,14 +10636,21 @@ static int tcp_send_error(tcp_descriptor* desc, int err)
/*
* We used to handle "expected errors" differently from unexpected ones.
- * Now we handle all errors in the same way. We just have to distinguish
- * between passive and active sockets.
+ * Now we handle all errors in the same way (unless the show_econnreset
+ * socket option is enabled). We just have to distinguish between passive
+ * and active sockets.
*/
DEBUGF(("driver_failure_eof(%ld) in %s, line %d\r\n",
(long)desc->inet.port, __FILE__, __LINE__));
if (desc->inet.active) {
- tcp_closed_message(desc);
- inet_reply_error_am(INETP(desc), am_closed);
+ if (show_econnreset) {
+ tcp_error_message(desc, err);
+ tcp_closed_message(desc);
+ inet_reply_error(INETP(desc), err);
+ } else {
+ tcp_closed_message(desc);
+ inet_reply_error_am(INETP(desc), am_closed);
+ }
if (desc->inet.exitf)
driver_exit(desc->inet.port, 0);
else
@@ -10542,7 +10662,10 @@ static int tcp_send_error(tcp_descriptor* desc, int err)
erl_inet_close(INETP(desc));
if (desc->inet.caller) {
- inet_reply_error_am(INETP(desc), am_closed);
+ if (show_econnreset)
+ inet_reply_error(INETP(desc), err);
+ else
+ inet_reply_error_am(INETP(desc), am_closed);
}
else {
/* No blocking send op to reply to right now.
@@ -10559,10 +10682,54 @@ static int tcp_send_error(tcp_descriptor* desc, int err)
* in the receive operation.
*/
desc->tcp_add_flags |= TCP_ADDF_DELAYED_CLOSE_RECV;
+
+ if (show_econnreset) {
+ /* Return {error, econnreset} instead of {error, closed}
+ * on send or receive operations.
+ */
+ desc->tcp_add_flags |= TCP_ADDF_DELAYED_ECONNRESET;
+ }
}
return -1;
}
+static int tcp_send_error(tcp_descriptor* desc, int err)
+{
+ /* EPIPE errors usually occur in one of three ways:
+ * 1. We write to a socket when we've already shutdown() the write side. On
+ * Windows the error returned for this is ESHUTDOWN rather than EPIPE.
+ * 2. The TCP peer sends us an RST through no fault of our own (perhaps
+ * by aborting the connection using SO_LINGER) and we then attempt
+ * to write to the socket. On Linux and Windows we would actually
+ * receive an ECONNRESET error for this, but on the BSDs, Darwin,
+ * Illumos and presumably Solaris, it's an EPIPE.
+ * 3. We cause the TCP peer to send us an RST by writing to a socket
+ * after we receive a FIN from them. Our first write will be
+ * successful, but if the they have closed the connection (rather
+ * than just shutting down the write side of it) this will cause their
+ * OS to send us an RST. Then, when we attempt to write to the socket
+ * a second time, we will get an EPIPE error. On Windows we get an
+ * ECONNABORTED.
+ *
+ * What we are going to do here is to treat all EPIPE messages that aren't
+ * of type 1 as ECONNRESET errors. This will allow users who have the
+ * show_econnreset socket option enabled to receive {error, econnreset} on
+ * both send and recv operations to indicate that an RST has been received.
+ */
+#ifdef __WIN_32__
+ if (err == ECONNABORTED)
+ err = ECONNRESET;
+#endif
+ if (err == EPIPE && !(desc->tcp_add_flags & TCP_ADDF_SHUTDOWN_WR_DONE))
+ err = ECONNRESET;
+ return tcp_send_or_shutdown_error(desc, err);
+}
+
+static int tcp_shutdown_error(tcp_descriptor* desc, int err)
+{
+ return tcp_send_or_shutdown_error(desc, err);
+}
+
/*
** Send non-blocking vector data
*/
@@ -10763,6 +10930,21 @@ static int tcp_send(tcp_descriptor* desc, char* ptr, ErlDrvSizeT len)
return 0;
}
+/* shutdown on the socket:
+** Assume caller has confirmed TCP_ADDF_PENDING_SHUTDOWN is set.
+*/
+static void tcp_shutdown_async(tcp_descriptor* desc)
+{
+ int how;
+
+ how = (desc->tcp_add_flags & TCP_ADDF_PENDING_SHUT_WR) ?
+ TCP_SHUT_WR : TCP_SHUT_RDWR;
+ if (IS_SOCKET_ERROR(sock_shutdown(INETP(desc)->s, how)))
+ tcp_shutdown_error(desc, sock_errno());
+ else
+ desc->tcp_add_flags |= TCP_ADDF_SHUTDOWN_WR_DONE;
+}
+
#ifdef __OSE__
static void tcp_inet_drv_output_ose(ErlDrvData data, ErlDrvEvent event)
@@ -10891,6 +11073,8 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
if ((iov = driver_peekq(ix, &vsize)) == NULL) {
sock_select(INETP(desc), FD_WRITE, 0);
send_empty_out_q_msgs(INETP(desc));
+ if (desc->tcp_add_flags & TCP_ADDF_PENDING_SHUTDOWN)
+ tcp_shutdown_async(desc);
goto done;
}
vsize = vsize > MAX_VSIZE ? MAX_VSIZE : vsize;
@@ -11960,115 +12144,18 @@ make_noninheritable_handle(SOCKET s)
* Multi-timers
*/
-static void absolute_timeout(unsigned millis, ErlDrvNowData *out)
-{
- unsigned rest;
- unsigned long millipart;
- unsigned long secpart;
- unsigned long megasecpart;
- unsigned tmo_secs = (millis / 1000U);
- unsigned tmo_millis = (millis % 1000);
- driver_get_now(out);
- rest = (out->microsecs) % 1000;
- millipart = ((out->microsecs) / 1000UL);
- if (rest >= 500) {
- ++millipart;
- }
- secpart = out->secs;
- megasecpart = out->megasecs;
- millipart += tmo_millis;
- secpart += (millipart / 1000000UL);
- millipart %= 1000000UL;
- secpart += tmo_secs;
- megasecpart += (secpart / 1000000UL);
- secpart %= 1000000UL;
- out->megasecs = megasecpart;
- out->secs = secpart;
- out->microsecs = (millipart * 1000UL);
-}
-
-static unsigned relative_timeout(ErlDrvNowData *in)
-{
- ErlDrvNowData now;
- unsigned rest;
- unsigned long millipart, in_millis, in_secs, in_megasecs;
-
- driver_get_now(&now);
-
- in_secs = in->secs;
- in_megasecs = in->megasecs;
-
- rest = (now.microsecs) % 1000;
- millipart = ((now.microsecs) / 1000UL);
- if (rest >= 500) {
- ++millipart;
- }
- in_millis = ((in->microsecs) / 1000UL);
- if ( in_millis < millipart ) {
- if (in_secs > 0) {
- --in_secs;
- } else {
- in_secs = (1000000UL - 1UL);
- if (in_megasecs <= now.megasecs) {
- return 0;
- } else {
- --in_megasecs;
- }
- }
- in_millis += 1000UL;
- }
- in_millis -= millipart;
-
- if (in_secs < now.secs) {
- if (in_megasecs <= now.megasecs) {
- return 0;
- } else {
- --in_megasecs;
- }
- in_secs += 1000000;
- }
- in_secs -= now.secs;
- if (in_megasecs < now.megasecs) {
- return 0;
- } else {
- in_megasecs -= now.megasecs;
- }
- return (unsigned) ((in_megasecs * 1000000000UL) +
- (in_secs * 1000UL) +
- in_millis);
-}
-
-#ifdef DEBUG
-static int nowcmp(ErlDrvNowData *d1, ErlDrvNowData *d2)
-{
- /* Assume it's not safe to do signed conversion on megasecs... */
- if (d1->megasecs < d2->megasecs) {
- return -1;
- } else if (d1->megasecs > d2->megasecs) {
- return 1;
- } else if (d1->secs != d2->secs) {
- return ((int) d1->secs) - ((int) d2->secs);
- }
- return ((int) d1->microsecs) - ((int) d2->microsecs);
-}
-#endif
-
static void fire_multi_timers(MultiTimerData **first, ErlDrvPort port,
ErlDrvData data)
{
- unsigned next_timeout;
+ ErlDrvTime next_timeout;
if (!*first) {
ASSERT(0);
return;
}
#ifdef DEBUG
{
- ErlDrvNowData chk;
- driver_get_now(&chk);
- chk.microsecs /= 10000UL;
- chk.microsecs *= 10000UL;
- chk.microsecs += 10000;
- ASSERT(nowcmp(&chk,&((*first)->when)) >= 0);
+ ErlDrvTime chk = erl_drv_monotonic_time(ERL_DRV_MSEC);
+ ASSERT(chk >= (*first)->when);
}
#endif
do {
@@ -12080,9 +12167,9 @@ static void fire_multi_timers(MultiTimerData **first, ErlDrvPort port,
return;
}
(*first)->prev = NULL;
- next_timeout = relative_timeout(&((*first)->when));
- } while (next_timeout == 0);
- driver_set_timer(port,next_timeout);
+ next_timeout = (*first)->when - erl_drv_monotonic_time(ERL_DRV_MSEC);
+ } while (next_timeout <= 0);
+ driver_set_timer(port, (unsigned long) next_timeout);
}
static void clean_multi_timers(MultiTimerData **first, ErlDrvPort port)
@@ -12105,8 +12192,10 @@ static void remove_multi_timer(MultiTimerData **first, ErlDrvPort port, MultiTim
driver_cancel_timer(port);
*first = p->next;
if (*first) {
- unsigned ntmo = relative_timeout(&((*first)->when));
- driver_set_timer(port,ntmo);
+ ErlDrvTime ntmo = (*first)->when - erl_drv_monotonic_time(ERL_DRV_MSEC);
+ if (ntmo < 0)
+ ntmo = 0;
+ driver_set_timer(port, (unsigned long) ntmo);
}
}
if (p->next != NULL) {
@@ -12122,32 +12211,16 @@ static MultiTimerData *add_multi_timer(MultiTimerData **first, ErlDrvPort port,
{
MultiTimerData *mtd, *p, *s;
mtd = ALLOC(sizeof(MultiTimerData));
- absolute_timeout(timeout, &(mtd->when));
+ mtd->when = erl_drv_monotonic_time(ERL_DRV_MSEC) + ((ErlDrvTime) timeout) + 1;
mtd->timeout_function = timeout_fun;
mtd->caller = caller;
mtd->next = mtd->prev = NULL;
for(p = *first,s = NULL; p != NULL; s = p, p = p->next) {
- if (p->when.megasecs >= mtd->when.megasecs) {
+ if (p->when >= mtd->when) {
break;
}
}
- if (!p || p->when.megasecs > mtd->when.megasecs) {
- goto found;
- }
- for (; p!= NULL; s = p, p = p->next) {
- if (p->when.secs >= mtd->when.secs) {
- break;
- }
- }
- if (!p || p->when.secs > mtd->when.secs) {
- goto found;
- }
- for (; p!= NULL; s = p, p = p->next) {
- if (p->when.microsecs >= mtd->when.microsecs) {
- break;
- }
- }
- found:
+
if (!p) {
if (!s) {
*first = mtd;
@@ -12173,10 +12246,6 @@ static MultiTimerData *add_multi_timer(MultiTimerData **first, ErlDrvPort port,
}
return mtd;
}
-
-
-
-
/*-----------------------------------------------------------------------------
diff --git a/erts/emulator/drivers/common/ram_file_drv.c b/erts/emulator/drivers/common/ram_file_drv.c
index 7f7cd7cd91..9cb44d0b7e 100644
--- a/erts/emulator/drivers/common/ram_file_drv.c
+++ b/erts/emulator/drivers/common/ram_file_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/drivers/common/zlib_drv.c b/erts/emulator/drivers/common/zlib_drv.c
index 3143e4511d..364048174c 100644
--- a/erts/emulator/drivers/common/zlib_drv.c
+++ b/erts/emulator/drivers/common/zlib_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -62,8 +63,17 @@
#define CRC32_COMBINE 23
#define ADLER32_COMBINE 24
+#define INFLATE_CHUNK 25
+
+
#define DEFAULT_BUFSZ 4000
+/* This flag is used in the same places, where zlib return codes
+ * (Z_OK, Z_STREAM_END, Z_NEED_DICT) are. So, we need to set it to
+ * relatively large value to avoid possible value clashes in future.
+ * */
+#define INFLATE_HAS_MORE 100
+
static int zlib_init(void);
static ErlDrvData zlib_start(ErlDrvPort port, char* buf);
static void zlib_stop(ErlDrvData e);
@@ -295,6 +305,58 @@ static int zlib_inflate(ZLibData* d, int flush)
return res;
}
+static int zlib_inflate_chunk(ZLibData* d)
+{
+ int res = Z_OK;
+
+ if ((d->bin == NULL) && (zlib_output_init(d) < 0)) {
+ errno = ENOMEM;
+ return Z_ERRNO;
+ }
+
+ while ((driver_sizeq(d->port) > 0) && (d->s.avail_out > 0) &&
+ (res != Z_STREAM_END)) {
+ int vlen;
+ SysIOVec* iov = driver_peekq(d->port, &vlen);
+ int len;
+
+ d->s.next_in = iov[0].iov_base;
+ d->s.avail_in = iov[0].iov_len;
+ while((d->s.avail_in > 0) && (d->s.avail_out > 0) && (res != Z_STREAM_END)) {
+ res = inflate(&d->s, Z_NO_FLUSH);
+ if (res == Z_NEED_DICT) {
+ /* Essential to eat the header bytes that zlib has looked at */
+ len = iov[0].iov_len - d->s.avail_in;
+ driver_deq(d->port, len);
+ return res;
+ }
+ if (res == Z_BUF_ERROR) {
+ /* Was possible more output, but actually not */
+ res = Z_OK;
+ }
+ else if (res < 0) {
+ return res;
+ }
+ }
+ len = iov[0].iov_len - d->s.avail_in;
+ driver_deq(d->port, len);
+ }
+
+ /* We are here because all input was consumed or EOS reached or output
+ * buffer is full */
+ if (d->want_crc) {
+ d->crc = crc32(d->crc, (unsigned char*) d->bin->orig_bytes,
+ d->binsz - d->s.avail_out);
+ }
+ zlib_output(d);
+ if ((res == Z_OK) && (d->s.avail_in > 0))
+ res = INFLATE_HAS_MORE;
+ else if (res == Z_STREAM_END) {
+ d->inflate_eos_seen = 1;
+ }
+ return res;
+}
+
static int zlib_deflate(ZLibData* d, int flush)
{
int res = Z_OK;
@@ -568,6 +630,18 @@ static ErlDrvSSizeT zlib_ctl(ErlDrvData drv_data, unsigned int command, char *bu
return zlib_return(res, rbuf, rlen);
}
+ case INFLATE_CHUNK:
+ if (d->state != ST_INFLATE) goto badarg;
+ if (len != 0) goto badarg;
+ res = zlib_inflate_chunk(d);
+ if (res == INFLATE_HAS_MORE) {
+ return zlib_value2(4, 0, rbuf, rlen);
+ } else if (res == Z_NEED_DICT) {
+ return zlib_value2(3, d->s.adler, rbuf, rlen);
+ } else {
+ return zlib_return(res, rbuf, rlen);
+ }
+
case GET_QSIZE:
return zlib_value(driver_sizeq(d->port), rbuf, rlen);
diff --git a/erts/emulator/drivers/ose/ose_efile.c b/erts/emulator/drivers/ose/ose_efile.c
index 035ff81a9b..c8337a95d5 100644
--- a/erts/emulator/drivers/ose/ose_efile.c
+++ b/erts/emulator/drivers/ose/ose_efile.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/drivers/ose/ose_signal_drv.c b/erts/emulator/drivers/ose/ose_signal_drv.c
index 4929b53856..2be9462a47 100644
--- a/erts/emulator/drivers/ose/ose_signal_drv.c
+++ b/erts/emulator/drivers/ose/ose_signal_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2013-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/drivers/ose/ttsl_drv.c b/erts/emulator/drivers/ose/ttsl_drv.c
index 8af2ce6af3..f759b47984 100644
--- a/erts/emulator/drivers/ose/ttsl_drv.c
+++ b/erts/emulator/drivers/ose/ttsl_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/drivers/unix/bin_drv.c b/erts/emulator/drivers/unix/bin_drv.c
index 1827187d57..21fb398907 100644
--- a/erts/emulator/drivers/unix/bin_drv.c
+++ b/erts/emulator/drivers/unix/bin_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/unix/multi_drv.c b/erts/emulator/drivers/unix/multi_drv.c
index 724d325ed5..7f8c2d9a0d 100644
--- a/erts/emulator/drivers/unix/multi_drv.c
+++ b/erts/emulator/drivers/unix/multi_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/unix/sig_drv.c b/erts/emulator/drivers/unix/sig_drv.c
index aab5d63a40..e6f2ecc494 100644
--- a/erts/emulator/drivers/unix/sig_drv.c
+++ b/erts/emulator/drivers/unix/sig_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c
index 491e0a090e..25cad37e25 100644
--- a/erts/emulator/drivers/unix/ttsl_drv.c
+++ b/erts/emulator/drivers/unix/ttsl_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -32,6 +33,10 @@ static ErlDrvData ttysl_start(ErlDrvPort, char*);
#ifdef HAVE_TERMCAP /* else make an empty driver that can not be opened */
+#ifndef WANT_NONBLOCKING
+#define WANT_NONBLOCKING
+#endif
+
#include "sys.h"
#include <ctype.h>
#include <stdlib.h>
@@ -39,6 +44,7 @@ static ErlDrvData ttysl_start(ErlDrvPort, char*);
#include <string.h>
#include <signal.h>
#include <fcntl.h>
+#include <limits.h>
#include <locale.h>
#include <unistd.h>
#include <termios.h>
@@ -57,6 +63,14 @@ static ErlDrvData ttysl_start(ErlDrvPort, char*);
#include <langinfo.h>
#endif
+#if defined IOV_MAX
+#define MAXIOV IOV_MAX
+#elif defined UIO_MAXIOV
+#define MAXIOV UIO_MAXIOV
+#else
+#define MAXIOV 16
+#endif
+
#define TRUE 1
#define FALSE 0
@@ -80,12 +94,15 @@ static volatile int cols_needs_update = FALSE;
#define OP_INSC 2
#define OP_DELC 3
#define OP_BEEP 4
+#define OP_PUTC_SYNC 5
/* Control op */
#define CTRL_OP_GET_WINSIZE 100
#define CTRL_OP_GET_UNICODE_STATE 101
#define CTRL_OP_SET_UNICODE_STATE 102
-
+/* We use 1024 as the buf size as that was the default buf size of FILE streams
+ on all platforms that I checked. */
+#define TTY_BUFFSIZE 1024
static int lbuf_size = BUFSIZ;
static Uint32 *lbuf; /* The current line buffer */
@@ -113,13 +130,19 @@ static int lpos; /* The current "cursor position" in the line buf
/* Main interface functions. */
static void ttysl_stop(ErlDrvData);
static void ttysl_from_erlang(ErlDrvData, char*, ErlDrvSizeT);
+static void ttysl_to_tty(ErlDrvData, ErlDrvEvent);
+static void ttysl_flush_tty(ErlDrvData);
static void ttysl_from_tty(ErlDrvData, ErlDrvEvent);
static void ttysl_stop_select(ErlDrvEvent, void*);
static Sint16 get_sint16(char*);
static ErlDrvPort ttysl_port;
static int ttysl_fd;
-static FILE *ttysl_out;
+static int ttysl_terminate = 0;
+static int ttysl_send_ok = 0;
+static ErlDrvBinary *putcbuf;
+static int putcpos;
+static int putclen;
/* Functions that work on the line buffer. */
static int start_lbuf(void);
@@ -201,22 +224,22 @@ struct erl_drv_entry ttsl_driver_entry = {
IF_IMPL(ttysl_stop),
IF_IMPL(ttysl_from_erlang),
IF_IMPL(ttysl_from_tty),
- NULL,
- "tty_sl",
- NULL,
- NULL,
+ IF_IMPL(ttysl_to_tty),
+ "tty_sl", /* driver_name */
+ NULL, /* finish */
+ NULL, /* handle */
IF_IMPL(ttysl_control),
NULL, /* timeout */
NULL, /* outputv */
NULL, /* ready_async */
- NULL, /* flush */
+ IF_IMPL(ttysl_flush_tty),
NULL, /* call */
NULL, /* event */
ERL_DRV_EXTENDED_MARKER,
ERL_DRV_EXTENDED_MAJOR_VERSION,
ERL_DRV_EXTENDED_MINOR_VERSION,
0, /* ERL_DRV_FLAGs */
- NULL,
+ NULL, /* handle2 */
NULL, /* process_exit */
IF_IMPL(ttysl_stop_select)
};
@@ -296,8 +319,7 @@ static ErlDrvData ttysl_start(ErlDrvPort port, char* buf)
return ERL_DRV_ERROR_GENERAL;
}
- /* Open the terminal and set the terminal */
- ttysl_out = fdopen(ttysl_fd, "w");
+ SET_NONBLOCKING(ttysl_fd);
#ifdef PRIMITIVE_UTF8_CHECK
setlocale(LC_CTYPE, ""); /* Set international environment,
@@ -317,8 +339,8 @@ static ErlDrvData ttysl_start(ErlDrvPort port, char* buf)
}
#endif
DEBUGLOG(("utf8_mode is %s\n",(utf8_mode) ? "on" : "off"));
- sys_sigset(SIGCONT, cont);
- sys_sigset(SIGWINCH, winch);
+ sys_signal(SIGCONT, cont);
+ sys_signal(SIGWINCH, winch);
driver_select(port, (ErlDrvEvent)(UWord)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 1);
ttysl_port = port;
@@ -400,12 +422,14 @@ static void ttysl_stop(ErlDrvData ttysl_data)
stop_lbuf();
stop_termcap();
tty_reset(ttysl_fd);
- driver_select(ttysl_port, (ErlDrvEvent)(UWord)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 0);
- sys_sigset(SIGCONT, SIG_DFL);
- sys_sigset(SIGWINCH, SIG_DFL);
+ driver_select(ttysl_port, (ErlDrvEvent)(UWord)ttysl_fd,
+ ERL_DRV_WRITE|ERL_DRV_READ|ERL_DRV_USE, 0);
+ sys_signal(SIGCONT, SIG_DFL);
+ sys_signal(SIGWINCH, SIG_DFL);
}
ttysl_port = (ErlDrvPort)-1;
ttysl_fd = -1;
+ ttysl_terminate = 0;
/* return TRUE; */
}
@@ -650,10 +674,26 @@ static int check_buf_size(byte *s, int n)
static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT count)
{
+ ErlDrvSizeT sz;
+
+ sz = driver_sizeq(ttysl_port);
+
+ putclen = count > TTY_BUFFSIZE ? TTY_BUFFSIZE : count;
+ putcbuf = driver_alloc_binary(putclen);
+ putcpos = 0;
+
if (lpos > MAXSIZE)
put_chars((byte*)"\n", 1);
switch (buf[0]) {
+ case OP_PUTC_SYNC:
+ /* Using sync means that we have to send an ok to the
+ controlling process for each command call. We delay
+ sending ok if the driver queue exceeds a certain size.
+ We do not set ourselves as a busy port, as this
+ could be very bad for user_drv, if it gets blocked on
+ the port_command. */
+ /* fall through */
case OP_PUTC:
DEBUGLOG(("OP: Putc(%lu)",(unsigned long) count-1));
if (check_buf_size((byte*)buf+1, count-1) == 0)
@@ -678,10 +718,106 @@ static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT coun
/* Unknown op, just ignore. */
break;
}
- fflush(ttysl_out);
+
+ driver_enq_bin(ttysl_port,putcbuf,0,putcpos);
+ driver_free_binary(putcbuf);
+
+ if (sz == 0) {
+ for (;;) {
+ int written, qlen;
+ SysIOVec *iov;
+
+ iov = driver_peekq(ttysl_port,&qlen);
+ if (iov)
+ written = writev(ttysl_fd, iov, qlen > MAXIOV ? MAXIOV : qlen);
+ else
+ written = 0;
+ if (written < 0) {
+ if (errno == ERRNO_BLOCK || errno == EINTR) {
+ driver_select(ttysl_port,(ErlDrvEvent)(long)ttysl_fd,
+ ERL_DRV_USE|ERL_DRV_WRITE,1);
+ break;
+ } else {
+ driver_failure_posix(ttysl_port, errno);
+ return;
+ }
+ } else {
+ if (driver_deq(ttysl_port, written) == 0)
+ break;
+ }
+ }
+ }
+
+ if (buf[0] == OP_PUTC_SYNC) {
+ if (driver_sizeq(ttysl_port) > TTY_BUFFSIZE && !ttysl_terminate) {
+ /* We delay sending the ack until the buffer has been consumed */
+ ttysl_send_ok = 1;
+ } else {
+ ErlDrvTermData spec[] = {
+ ERL_DRV_PORT, driver_mk_port(ttysl_port),
+ ERL_DRV_ATOM, driver_mk_atom("ok"),
+ ERL_DRV_TUPLE, 2
+ };
+ ASSERT(ttysl_send_ok == 0);
+ erl_drv_output_term(driver_mk_port(ttysl_port), spec,
+ sizeof(spec) / sizeof(spec[0]));
+ }
+ }
+
return; /* TRUE; */
}
+static void ttysl_to_tty(ErlDrvData ttysl_data, ErlDrvEvent fd) {
+ for (;;) {
+ int written, qlen;
+ SysIOVec *iov;
+ ErlDrvSizeT sz;
+
+ iov = driver_peekq(ttysl_port,&qlen);
+ if (iov)
+ written = writev(ttysl_fd, iov, qlen > MAXIOV ? MAXIOV : qlen);
+ else
+ written = 0;
+ if (written < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else if (errno != ERRNO_BLOCK){
+ driver_failure_posix(ttysl_port, errno);
+ }
+ break;
+ } else {
+ sz = driver_deq(ttysl_port, written);
+ if (sz < TTY_BUFFSIZE && ttysl_send_ok) {
+ ErlDrvTermData spec[] = {
+ ERL_DRV_PORT, driver_mk_port(ttysl_port),
+ ERL_DRV_ATOM, driver_mk_atom("ok"),
+ ERL_DRV_TUPLE, 2
+ };
+ ttysl_send_ok = 0;
+ erl_drv_output_term(driver_mk_port(ttysl_port), spec,
+ sizeof(spec) / sizeof(spec[0]));
+ }
+ if (sz == 0) {
+ driver_select(ttysl_port,(ErlDrvEvent)(long)ttysl_fd,
+ ERL_DRV_WRITE,0);
+ if (ttysl_terminate)
+ /* flush has been called, which means we should terminate
+ when queue is empty. This will not send any exit
+ message */
+ driver_failure_atom(ttysl_port, "normal");
+ break;
+ }
+ }
+ }
+
+ return;
+}
+
+static void ttysl_flush_tty(ErlDrvData ttysl_data) {
+ ttysl_terminate = 1;
+ return;
+}
+
static void ttysl_from_tty(ErlDrvData ttysl_data, ErlDrvEvent fd)
{
byte b[1024];
@@ -1070,7 +1206,15 @@ static int write_buf(Uint32 *s, int n)
/* The basic procedure for outputting one character. */
static int outc(int c)
{
- return (int)putc(c, ttysl_out);
+ putcbuf->orig_bytes[putcpos++] = c;
+ if (putcpos == putclen) {
+ driver_enq_bin(ttysl_port,putcbuf,0,putclen);
+ driver_free_binary(putcbuf);
+ putcpos = 0;
+ putclen = TTY_BUFFSIZE;
+ putcbuf = driver_alloc_binary(BUFSIZ);
+ }
+ return 1;
}
static int move_cursor(int from, int to)
@@ -1318,11 +1462,11 @@ static RETSIGTYPE suspend(int sig)
exit(1);
}
- sys_sigset(sig, SIG_DFL); /* Set signal handler to default */
+ sys_signal(sig, SIG_DFL); /* Set signal handler to default */
sys_sigrelease(sig); /* Allow 'sig' to come through */
kill(getpid(), sig); /* Send ourselves the signal */
sys_sigblock(sig); /* Reset to old mask */
- sys_sigset(sig, suspend); /* Reset signal handler */
+ sys_signal(sig, suspend); /* Reset signal handler */
if (tty_set(ttysl_fd) < 0) {
fprintf(stderr,"Can't set tty raw \n");
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 878beb055b..00da48b107 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -38,16 +39,21 @@
#ifdef HAVE_SYS_UIO_H
#include <sys/types.h>
#include <sys/uio.h>
+#if defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__))
+/* Need to define __BSD_VISIBLE in order to expose prototype of sendfile */
+#define __BSD_VISIBLE 1
+#include <sys/socket.h>
+#endif
#endif
#if defined(HAVE_SENDFILE) && (defined(__linux__) || (defined(__sun) && defined(__SVR4)))
#include <sys/sendfile.h>
#endif
#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
-#define DARWIN 1
+#define __DARWIN__ 1
#endif
-#if defined(DARWIN) || defined(HAVE_LINUX_FALLOC_H) || defined(HAVE_POSIX_FALLOCATE)
+#if defined(__DARWIN__) || defined(HAVE_LINUX_FALLOC_H) || defined(HAVE_POSIX_FALLOCATE)
#include <fcntl.h>
#endif
@@ -475,11 +481,11 @@ efile_fsync(Efile_error *errInfo, /* Where to return error codes. */
#ifdef NO_FSYNC
undefined fsync /* XXX: Really? */
#else
-#if defined(DARWIN) && defined(F_FULLFSYNC)
+#if defined(__DARWIN__) && defined(F_FULLFSYNC)
return check_error(fcntl(fd, F_FULLFSYNC), errInfo);
#else
return check_error(fsync(fd), errInfo);
-#endif /* DARWIN */
+#endif /* __DARWIN__ */
#endif /* NO_FSYNC */
}
@@ -961,7 +967,7 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,
retval = len;
}
} while (len == SENDFILE_CHUNK_SIZE);
-#elif defined(DARWIN)
+#elif defined(__DARWIN__)
int retval;
off_t len;
do {
diff --git a/erts/emulator/drivers/vxworks/vxworks_resolv.c b/erts/emulator/drivers/vxworks/vxworks_resolv.c
index 8fcbb736f7..a7de53c692 100644
--- a/erts/emulator/drivers/vxworks/vxworks_resolv.c
+++ b/erts/emulator/drivers/vxworks/vxworks_resolv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/win32/registry_drv.c b/erts/emulator/drivers/win32/registry_drv.c
index e908c956ae..4e396aa8d9 100644
--- a/erts/emulator/drivers/win32/registry_drv.c
+++ b/erts/emulator/drivers/win32/registry_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/win32/ttsl_drv.c b/erts/emulator/drivers/win32/ttsl_drv.c
index 502cb58dfa..4bd766a8a8 100644
--- a/erts/emulator/drivers/win32/ttsl_drv.c
+++ b/erts/emulator/drivers/win32/ttsl_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -46,6 +47,7 @@ static int rows; /* Number of rows available. */
#define OP_INSC 2
#define OP_DELC 3
#define OP_BEEP 4
+#define OP_PUTC_SYNC 5
/* Control op */
#define CTRL_OP_GET_WINSIZE 100
@@ -458,6 +460,7 @@ static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT coun
switch (buf[0]) {
case OP_PUTC:
+ case OP_PUTC_SYNC:
DEBUGLOG(("OP: Putc(%I64u)",(unsigned long long)count-1));
if (check_buf_size((byte*)buf+1, count-1) == 0)
return;
@@ -481,6 +484,20 @@ static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT coun
/* Unknown op, just ignore. */
break;
}
+
+ if (buf[0] == OP_PUTC_SYNC) {
+ /* On windows we do a blocking write to the tty so we just
+ send the ack immidiately. If at some point in the future
+ someone has a problem with tty output being blocking
+ this has to be changed. */
+ ErlDrvTermData spec[] = {
+ ERL_DRV_PORT, driver_mk_port(ttysl_port),
+ ERL_DRV_ATOM, driver_mk_atom("ok"),
+ ERL_DRV_TUPLE, 2
+ };
+ erl_drv_output_term(driver_mk_port(ttysl_port), spec,
+ sizeof(spec) / sizeof(spec[0]));
+ }
return;
}
diff --git a/erts/emulator/drivers/win32/win_con.c b/erts/emulator/drivers/win32/win_con.c
index 7b9cadd32b..7fe708dc7b 100644
--- a/erts/emulator/drivers/win32/win_con.c
+++ b/erts/emulator/drivers/win32/win_con.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -278,7 +279,7 @@ ConInit(void)
}
/*
- ConNormalExit() is called from erl_exit() when the emulator
+ ConNormalExit() is called from erts_exit() when the emulator
is stopping. If the exit has not been initiated by this
console thread (WM_DESTROY or ID_BREAK), the function must
invoke the console thread to save the user preferences.
@@ -528,7 +529,7 @@ ConThreadInit(LPVOID param)
/*
PostQuitMessage() results in WM_QUIT which makes GetMessage()
return 0 (which stops the main loop). Before we return from
- the console thread, the ctrl_handler is called to do erl_exit.
+ the console thread, the ctrl_handler is called to do erts_exit.
*/
(*ctrl_handler)(CTRL_CLOSE_EVENT);
return msg.wParam;
diff --git a/erts/emulator/drivers/win32/win_con.h b/erts/emulator/drivers/win32/win_con.h
index d46af86ca5..3f4e89a195 100644
--- a/erts/emulator/drivers/win32/win_con.h
+++ b/erts/emulator/drivers/win32/win_con.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index 7e4043fc1b..d95f29f49d 100644
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/TODO b/erts/emulator/hipe/TODO
index 624ab560e7..dd9760ea1c 100644
--- a/erts/emulator/hipe/TODO
+++ b/erts/emulator/hipe/TODO
@@ -3,16 +3,17 @@
Copyright Ericsson AB 2004-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/emulator/hipe/elf64ppc.x b/erts/emulator/hipe/elf64ppc.x
index 299eed8192..3cd4010cb3 100644
--- a/erts/emulator/hipe/elf64ppc.x
+++ b/erts/emulator/hipe/elf64ppc.x
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/hipe/hipe_amd64.c b/erts/emulator/hipe/hipe_amd64.c
index b5dff06987..1bb336637d 100644
--- a/erts/emulator/hipe/hipe_amd64.c
+++ b/erts/emulator/hipe/hipe_amd64.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -125,7 +126,7 @@ static void atexit_alloc_code_stats(void)
#define MAP_ANONYMOUS MAP_ANON
#endif
-static void morecore(unsigned int alloc_bytes)
+static int morecore(unsigned int alloc_bytes)
{
unsigned int map_bytes;
char *map_hint, *map_start;
@@ -174,10 +175,9 @@ static void morecore(unsigned int alloc_bytes)
abort();
}
#endif
- if (map_start == MAP_FAILED) {
- perror("mmap");
- abort();
- }
+ if (map_start == MAP_FAILED)
+ return -1;
+
ALLOC_CODE_STATS(total_mapped += map_bytes);
/* Merge adjacent mappings, so the trailing portion of the previous
@@ -197,6 +197,8 @@ static void morecore(unsigned int alloc_bytes)
}
ALLOC_CODE_STATS(atexit_alloc_code_stats());
+
+ return 0;
}
static void *alloc_code(unsigned int alloc_bytes)
@@ -206,8 +208,8 @@ static void *alloc_code(unsigned int alloc_bytes)
/* Align function entries. */
alloc_bytes = (alloc_bytes + 3) & ~3;
- if (code_bytes < alloc_bytes)
- morecore(alloc_bytes);
+ if (code_bytes < alloc_bytes && morecore(alloc_bytes) != 0)
+ return NULL;
ALLOC_CODE_STATS(++nr_allocs);
ALLOC_CODE_STATS(total_alloc += alloc_bytes);
res = code_next;
@@ -224,18 +226,18 @@ void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *
return alloc_code(nrbytes);
}
-/* called from hipe_bif0.c:hipe_bifs_make_native_stub_2()
- and hipe_bif0.c:hipe_make_stub() */
-void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
+/* Make stub for native code calling exported beam function.
+*/
+void *hipe_make_native_stub(void *callee_exp, unsigned int beamArity)
{
/*
* This creates a native code stub with the following contents:
*
- * movq $Address, P_BEAM_IP(%ebp) %% Actually two movl
+ * movq $Address, P_CALLEE_EXP(%ebp) %% Actually two movl
* movb $Arity, P_ARITY(%ebp)
* jmp callemu
*
- * The stub has variable size, depending on whether the P_BEAM_IP
+ * The stub has variable size, depending on whether the P_CALLEE_EXP
* and P_ARITY offsets fit in 8-bit signed displacements or not.
* The rel32 offset in the final jmp depends on its actual location,
* which also depends on the size of the previous instructions.
@@ -248,49 +250,51 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
codeSize = /* 23, 26, 29, or 32 bytes */
23 + /* 23 when all offsets are 8-bit */
- (P_BEAM_IP >= 128 ? 3 : 0) +
- ((P_BEAM_IP + 4) >= 128 ? 3 : 0) +
+ (P_CALLEE_EXP >= 128 ? 3 : 0) +
+ ((P_CALLEE_EXP + 4) >= 128 ? 3 : 0) +
(P_ARITY >= 128 ? 3 : 0);
codep = code = alloc_code(codeSize);
+ if (!code)
+ return NULL;
- /* movl $beamAddress, P_BEAM_IP(%ebp); 3 or 6 bytes, plus 4 */
+ /* movl $callee_exp, P_CALLEE_EXP(%ebp); 3 or 6 bytes, plus 4 */
codep[0] = 0xc7;
-#if P_BEAM_IP >= 128
+#if P_CALLEE_EXP >= 128
codep[1] = 0x85; /* disp32[EBP] */
- codep[2] = P_BEAM_IP & 0xFF;
- codep[3] = (P_BEAM_IP >> 8) & 0xFF;
- codep[4] = (P_BEAM_IP >> 16) & 0xFF;
- codep[5] = (P_BEAM_IP >> 24) & 0xFF;
+ codep[2] = P_CALLEE_EXP & 0xFF;
+ codep[3] = (P_CALLEE_EXP >> 8) & 0xFF;
+ codep[4] = (P_CALLEE_EXP >> 16) & 0xFF;
+ codep[5] = (P_CALLEE_EXP >> 24) & 0xFF;
codep += 6;
#else
codep[1] = 0x45; /* disp8[EBP] */
- codep[2] = P_BEAM_IP;
+ codep[2] = P_CALLEE_EXP;
codep += 3;
#endif
- codep[0] = ((unsigned long)beamAddress ) & 0xFF;
- codep[1] = ((unsigned long)beamAddress >> 8) & 0xFF;
- codep[2] = ((unsigned long)beamAddress >> 16) & 0xFF;
- codep[3] = ((unsigned long)beamAddress >> 24) & 0xFF;
+ codep[0] = ((unsigned long)callee_exp ) & 0xFF;
+ codep[1] = ((unsigned long)callee_exp >> 8) & 0xFF;
+ codep[2] = ((unsigned long)callee_exp >> 16) & 0xFF;
+ codep[3] = ((unsigned long)callee_exp >> 24) & 0xFF;
codep += 4;
- /* movl (shl 32 $beamAddress), P_BEAM_IP+4(%ebp); 3 or 6 bytes, plus 4 */
+ /* movl (shl 32 $callee_exp), P_CALLEE_EXP+4(%ebp); 3 or 6 bytes, plus 4 */
codep[0] = 0xc7;
-#if P_BEAM_IP+4 >= 128
+#if P_CALLEE_EXP+4 >= 128
codep[1] = 0x85; /* disp32[EBP] */
- codep[2] = (P_BEAM_IP+4) & 0xFF;
- codep[3] = ((P_BEAM_IP+4) >> 8) & 0xFF;
- codep[4] = ((P_BEAM_IP+4) >> 16) & 0xFF;
- codep[5] = ((P_BEAM_IP+4) >> 24) & 0xFF;
+ codep[2] = (P_CALLEE_EXP+4) & 0xFF;
+ codep[3] = ((P_CALLEE_EXP+4) >> 8) & 0xFF;
+ codep[4] = ((P_CALLEE_EXP+4) >> 16) & 0xFF;
+ codep[5] = ((P_CALLEE_EXP+4) >> 24) & 0xFF;
codep += 6;
#else
codep[1] = 0x45; /* disp8[EBP] */
- codep[2] = (P_BEAM_IP+4);
+ codep[2] = (P_CALLEE_EXP+4);
codep += 3;
#endif
- codep[0] = ((unsigned long)beamAddress >> 32) & 0xFF;
- codep[1] = ((unsigned long)beamAddress >> 40) & 0xFF;
- codep[2] = ((unsigned long)beamAddress >> 48) & 0xFF;
- codep[3] = ((unsigned long)beamAddress >> 56) & 0xFF;
+ codep[0] = ((unsigned long)callee_exp >> 32) & 0xFF;
+ codep[1] = ((unsigned long)callee_exp >> 40) & 0xFF;
+ codep[2] = ((unsigned long)callee_exp >> 48) & 0xFF;
+ codep[3] = ((unsigned long)callee_exp >> 56) & 0xFF;
codep += 4;
/* movb $beamArity, P_ARITY(%ebp); 3 or 6 bytes */
diff --git a/erts/emulator/hipe/hipe_amd64.h b/erts/emulator/hipe/hipe_amd64.h
index bf41d238dd..09b55a1243 100644
--- a/erts/emulator/hipe/hipe_amd64.h
+++ b/erts/emulator/hipe/hipe_amd64.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_amd64.tab b/erts/emulator/hipe/hipe_amd64.tab
index e039d74525..70287034a0 100644
--- a/erts/emulator/hipe/hipe_amd64.tab
+++ b/erts/emulator/hipe/hipe_amd64.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_amd64_abi.txt b/erts/emulator/hipe/hipe_amd64_abi.txt
index 8a34bfa67f..72aed13995 100644
--- a/erts/emulator/hipe/hipe_amd64_abi.txt
+++ b/erts/emulator/hipe/hipe_amd64_abi.txt
@@ -45,7 +45,7 @@ The first return value from a function is placed in %rax, the second
(if any) is placed in %rdx.
Notes:
-- Currently, NR_ARG_REGS==0.
+- Currently, NR_ARG_REGS == 4.
- C BIFs expect P in C parameter register 1: %rdi. By making Erlang
parameter registers 1-5 coincide with C parameter registers 2-6,
our BIF wrappers can simply move P to %rdi without having to shift
diff --git a/erts/emulator/hipe/hipe_amd64_asm.m4 b/erts/emulator/hipe/hipe_amd64_asm.m4
index 7c81040b8b..ecb25ec5c8 100644
--- a/erts/emulator/hipe/hipe_amd64_asm.m4
+++ b/erts/emulator/hipe/hipe_amd64_asm.m4
@@ -4,16 +4,17 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -33,7 +34,35 @@ define(HEAP_LIMIT_IN_REGISTER,0)dnl global for HL
define(SIMULATE_NSP,0)dnl change to 1 to simulate call/ret insns
`#define AMD64_LEAF_WORDS 'LEAF_WORDS
-`#define LEAF_WORDS 'LEAF_WORDS
+`#define LEAF_WORDS 'LEAF_WORDS
+`#define AMD64_NR_ARG_REGS 'NR_ARG_REGS
+`#define NR_ARG_REGS 'NR_ARG_REGS
+
+`#define AMD64_HP_IN_REGISTER 'HP_IN_REGISTER
+`#if AMD64_HP_IN_REGISTER'
+`#define AMD64_HEAP_POINTER 15'
+define(HP,%r15)dnl Only change this together with above
+`#endif'
+
+`#define AMD64_FCALLS_IN_REGISTER 'FCALLS_IN_REGISTER
+`#if AMD64_FCALLS_IN_REGISTER'
+`#define AMD64_FCALLS_REGISTER 11'
+define(FCALLS,%r11)dnl This goes together with line above
+`#endif'
+
+`#define AMD64_HEAP_LIMIT_IN_REGISTER 'HEAP_LIMIT_IN_REGISTER
+`#if AMD64_HEAP_LIMIT_IN_REGISTER'
+`#define AMD64_HEAP_LIMIT_REGISTER 12'
+define(HEAP_LIMIT,%r12)dnl Change this together with line above
+`#endif'
+
+`#define AMD64_SIMULATE_NSP 'SIMULATE_NSP
+
+
+`#ifdef ASM'
+/*
+ * Only assembler stuff from here on (when included from *.S)
+ */
/*
* Workarounds for Darwin.
@@ -63,33 +92,24 @@ ifelse(OPSYS,darwin,``
*/
`#define P %rbp'
-`#define AMD64_HP_IN_REGISTER 'HP_IN_REGISTER
`#if AMD64_HP_IN_REGISTER
-#define AMD64_HEAP_POINTER 15'
-define(HP,%r15)dnl Only change this together with above
-`#define SAVE_HP movq 'HP`, P_HP(P)
+#define SAVE_HP movq 'HP`, P_HP(P)
#define RESTORE_HP movq P_HP(P), 'HP`
#else
#define SAVE_HP /*empty*/
#define RESTORE_HP /*empty*/
#endif'
-`#define AMD64_FCALLS_IN_REGISTER 'FCALLS_IN_REGISTER
`#if AMD64_FCALLS_IN_REGISTER
-#define AMD64_FCALLS_REGISTER 11'
-define(FCALLS,%r11)dnl This goes together with line above
-`#define SAVE_FCALLS movq 'FCALLS`, P_FCALLS(P)
+#define SAVE_FCALLS movq 'FCALLS`, P_FCALLS(P)
#define RESTORE_FCALLS movq P_FCALLS(P), 'FCALLS`
#else
#define SAVE_FCALLS /*empty*/
#define RESTORE_FCALLS /*empty*/
#endif'
-`#define AMD64_HEAP_LIMIT_IN_REGISTER 'HEAP_LIMIT_IN_REGISTER
`#if AMD64_HEAP_LIMIT_IN_REGISTER
-#define AMD64_HEAP_LIMIT_REGISTER 12'
-define(HEAP_LIMIT,%r12)dnl Change this together with line above
-`#define RESTORE_HEAP_LIMIT movq P_HP_LIMIT(P), 'HEAP_LIMIT`
+#define RESTORE_HEAP_LIMIT movq P_HP_LIMIT(P), 'HEAP_LIMIT`
#else
#define RESTORE_HEAP_LIMIT /*empty*/
#endif'
@@ -99,7 +119,6 @@ define(NSP,%rsp)dnl
`#define SAVE_CSP movq %rsp, P_CSP(P)
#define RESTORE_CSP movq P_CSP(P), %rsp'
-`#define AMD64_SIMULATE_NSP 'SIMULATE_NSP
/*
* Context switching macros.
@@ -132,8 +151,6 @@ define(NSP,%rsp)dnl
/*
* Argument (parameter) registers.
*/
-`#define AMD64_NR_ARG_REGS 'NR_ARG_REGS
-`#define NR_ARG_REGS 'NR_ARG_REGS
define(defarg,`define(ARG$1,`$2')dnl
#`define ARG'$1 $2'
@@ -237,6 +254,10 @@ define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_REG_ARG($1,$3)',`NBIF_ST
`/* #define NBIF_ARG_3_0 'NBIF_ARG(%rsi,3,0)` */'
`/* #define NBIF_ARG_3_1 'NBIF_ARG(%rdx,3,1)` */'
`/* #define NBIF_ARG_3_2 'NBIF_ARG(%rcx,3,2)` */'
+`/* #define NBIF_ARG_4_0 'NBIF_ARG(%rsi,4,0)` */'
+`/* #define NBIF_ARG_4_1 'NBIF_ARG(%rdx,4,1)` */'
+`/* #define NBIF_ARG_4_2 'NBIF_ARG(%rcx,4,2)` */'
+`/* #define NBIF_ARG_4_3 'NBIF_ARG(%r8,4,3)` */'
`/* #define NBIF_ARG_5_0 'NBIF_ARG(%rsi,5,0)` */'
`/* #define NBIF_ARG_5_1 'NBIF_ARG(%rdx,5,1)` */'
`/* #define NBIF_ARG_5_2 'NBIF_ARG(%rcx,5,2)` */'
@@ -261,6 +282,9 @@ define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl
`/* #define NBIF_RET_1 'NBIF_RET(1)` */'
`/* #define NBIF_RET_2 'NBIF_RET(2)` */'
`/* #define NBIF_RET_3 'NBIF_RET(3)` */'
+`/* #define NBIF_RET_4 'NBIF_RET(4)` */'
`/* #define NBIF_RET_5 'NBIF_RET(5)` */'
+`#endif /* ASM */'
+
`#endif /* HIPE_AMD64_ASM_H */'
diff --git a/erts/emulator/hipe/hipe_amd64_bifs.m4 b/erts/emulator/hipe/hipe_amd64_bifs.m4
index a3219c7586..602e71c195 100644
--- a/erts/emulator/hipe/hipe_amd64_bifs.m4
+++ b/erts/emulator/hipe/hipe_amd64_bifs.m4
@@ -4,21 +4,22 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
-
+#`define ASM'
include(`hipe/hipe_amd64_asm.m4')
#`include' "config.h"
#`include' "hipe_literals.h"
@@ -51,9 +52,10 @@ define(HANDLE_GOT_MBUF,`
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 0-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
@@ -154,6 +156,42 @@ ASYM($1):
TYPE_FUNCTION(ASYM($1))
#endif')
+define(standard_bif_interface_4,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* set up the parameters */
+ movq P, %rdi
+ NBIF_ARG(%rsi,4,0)
+ NBIF_ARG(%rdx,4,1)
+ NBIF_ARG(%rcx,4,2)
+ NBIF_ARG(%r8,4,3)
+
+ /* make the call on the C stack */
+ SWITCH_ERLANG_TO_C
+ pushq %r8
+ pushq %rcx
+ pushq %rdx
+ pushq %rsi
+ movq %rsp, %rsi /* Eterm* BIF__ARGS */
+ CALL_BIF($2)
+ add $(4*8), %rsp
+ TEST_GOT_MBUF
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_4_simple_exception
+ NBIF_RET(4)
+ HANDLE_GOT_MBUF(4)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
diff --git a/erts/emulator/hipe/hipe_amd64_gc.h b/erts/emulator/hipe/hipe_amd64_gc.h
index c5a6fee6fe..e7a156c910 100644
--- a/erts/emulator/hipe/hipe_amd64_gc.h
+++ b/erts/emulator/hipe/hipe_amd64_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_amd64_glue.S b/erts/emulator/hipe/hipe_amd64_glue.S
index 8816906870..6fb93bce53 100644
--- a/erts/emulator/hipe/hipe_amd64_glue.S
+++ b/erts/emulator/hipe/hipe_amd64_glue.S
@@ -3,24 +3,24 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
-
+#define ASM
#include "hipe_amd64_asm.h"
#include "hipe_literals.h"
-#define ASM
#include "hipe_mode_switch.h"
/*
@@ -109,7 +109,7 @@ ASYM(nbif_return):
* stub (hipe_x86_loader.erl) which should look as follows:
*
* stub for f/N:
- * movq $<f's BEAM code address>, P_BEAM_IP(P)
+ * movq $<f's export entry address>, P_CALLEE_EXP(P)
* movb $<N>, P_ARITY(P)
* jmp nbif_callemu
*
@@ -119,7 +119,7 @@ ASYM(nbif_return):
GLOBAL(ASYM(nbif_callemu))
ASYM(nbif_callemu):
STORE_ARG_REGS
- movl $HIPE_MODE_SWITCH_RES_CALL, %eax
+ movl $HIPE_MODE_SWITCH_RES_CALL_EXPORTED, %eax
jmp .suspend_exit
/*
@@ -322,6 +322,7 @@ ASYM(nbif_fail):
GLOBAL(nbif_1_gc_after_bif)
GLOBAL(nbif_2_gc_after_bif)
GLOBAL(nbif_3_gc_after_bif)
+ GLOBAL(nbif_4_gc_after_bif)
.align 4
nbif_0_gc_after_bif:
xorl %edx, %edx
@@ -337,6 +338,10 @@ nbif_2_gc_after_bif:
.align 4
nbif_3_gc_after_bif:
movl $3, %edx
+ jmp .gc_after_bif
+ .align 4
+nbif_4_gc_after_bif:
+ movl $4, %edx
/*FALLTHROUGH*/
.align 4
.gc_after_bif:
@@ -360,6 +365,7 @@ nbif_3_gc_after_bif:
GLOBAL(nbif_1_simple_exception)
GLOBAL(nbif_2_simple_exception)
GLOBAL(nbif_3_simple_exception)
+ GLOBAL(nbif_4_simple_exception)
.align 4
nbif_0_simple_exception:
xorl %eax, %eax
@@ -375,6 +381,10 @@ nbif_2_simple_exception:
.align 4
nbif_3_simple_exception:
movl $3, %eax
+ jmp .nbif_simple_exception
+ .align 4
+nbif_4_simple_exception:
+ movl $4, %eax
/*FALLTHROUGH*/
.align 4
.nbif_simple_exception:
diff --git a/erts/emulator/hipe/hipe_amd64_glue.h b/erts/emulator/hipe/hipe_amd64_glue.h
index 36508467fa..e54b8b3a3f 100644
--- a/erts/emulator/hipe/hipe_amd64_glue.h
+++ b/erts/emulator/hipe/hipe_amd64_glue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_amd64_primops.h b/erts/emulator/hipe/hipe_amd64_primops.h
index 55cb0eadb8..23d8202e46 100644
--- a/erts/emulator/hipe/hipe_amd64_primops.h
+++ b/erts/emulator/hipe/hipe_amd64_primops.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_arch.h b/erts/emulator/hipe/hipe_arch.h
index 04ed980126..21dabc7cb6 100644
--- a/erts/emulator/hipe/hipe_arch.h
+++ b/erts/emulator/hipe/hipe_arch.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -29,6 +30,7 @@ extern void hipe_patch_load_fe(Uint *address, Uint value);
extern int hipe_patch_insn(void *address, Uint value, Eterm type);
extern int hipe_patch_call(void *callAddress, void *destAddress, void *trampoline);
+extern void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p);
extern void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity);
#if defined(__sparc__)
diff --git a/erts/emulator/hipe/hipe_arm.c b/erts/emulator/hipe/hipe_arm.c
index 3db3ffe9b1..01512e9aa1 100644
--- a/erts/emulator/hipe/hipe_arm.c
+++ b/erts/emulator/hipe/hipe_arm.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -260,9 +261,9 @@ int hipe_patch_insn(void *address, Uint32 value, Eterm type)
return 0;
}
-/* called from hipe_bif0.c:hipe_bifs_make_native_stub_2()
- and hipe_bif0.c:hipe_make_stub() */
-void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
+/* Make stub for native code calling exported beam function
+*/
+void *hipe_make_native_stub(void *callee_exp, unsigned int beamArity)
{
unsigned int *code;
unsigned int *tramp_callemu;
@@ -272,9 +273,9 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
* Native code calls BEAM via a stub looking as follows:
*
* mov r0, #beamArity
- * ldr r8, [pc,#0] // beamAddress
+ * ldr r8, [pc,#0] // callee_exp
* b nbif_callemu
- * .long beamAddress
+ * .long callee_exp
*
* I'm using r0 and r8 since they aren't used for
* parameter passing in native code. The branch to
@@ -283,6 +284,8 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
*/
code = alloc_stub(4, &tramp_callemu);
+ if (!code)
+ return NULL;
callemu_offset = ((int)&nbif_callemu - ((int)&code[2] + 8)) >> 2;
if (!(callemu_offset >= -0x00800000 && callemu_offset <= 0x007FFFFF)) {
callemu_offset = ((int)tramp_callemu - ((int)&code[2] + 8)) >> 2;
@@ -292,12 +295,12 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
/* mov r0, #beamArity */
code[0] = 0xE3A00000 | (beamArity & 0xFF);
- /* ldr r8, [pc,#0] // beamAddress */
+ /* ldr r8, [pc,#0] // callee_exp */
code[1] = 0xE59F8000;
/* b nbif_callemu */
code[2] = 0xEA000000 | (callemu_offset & 0x00FFFFFF);
- /* .long beamAddress */
- code[3] = (unsigned int)beamAddress;
+ /* .long callee_exp */
+ code[3] = (unsigned int)callee_exp;
hipe_flush_icache_range(code, 4*sizeof(int));
diff --git a/erts/emulator/hipe/hipe_arm.h b/erts/emulator/hipe/hipe_arm.h
index 19f2a986cf..a0e07cd6ce 100644
--- a/erts/emulator/hipe/hipe_arm.h
+++ b/erts/emulator/hipe/hipe_arm.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -40,8 +41,4 @@ static __inline__ int hipe_word32_address_ok(void *address)
extern void hipe_arm_inc_stack(void);
-/* for hipe_bifs_enter_code_2 */
-extern void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p);
-#define HIPE_ALLOC_CODE(n,c,t,p) hipe_alloc_code((n),(c),(t),(p))
-
#endif /* HIPE_ARM_H */
diff --git a/erts/emulator/hipe/hipe_arm.tab b/erts/emulator/hipe/hipe_arm.tab
index 49b89d6748..bcac2cd79d 100644
--- a/erts/emulator/hipe/hipe_arm.tab
+++ b/erts/emulator/hipe/hipe_arm.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_arm_asm.m4 b/erts/emulator/hipe/hipe_arm_asm.m4
index 85dc84973d..8ce8600f97 100644
--- a/erts/emulator/hipe/hipe_arm_asm.m4
+++ b/erts/emulator/hipe/hipe_arm_asm.m4
@@ -4,16 +4,17 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -29,6 +30,14 @@ define(LEAF_WORDS,16)dnl number of stack words for leaf functions
define(NR_ARG_REGS,3)dnl admissible values are 0 to 6, inclusive
`#define ARM_LEAF_WORDS 'LEAF_WORDS
+`#define ARM_NR_ARG_REGS 'NR_ARG_REGS
+`#define NR_ARG_REGS 'NR_ARG_REGS
+
+
+`#ifdef ASM'
+/*
+ * Only assembler stuff from here on (when included from *.S)
+ */
/*
* Reserved registers.
@@ -77,8 +86,6 @@ define(NR_ARG_REGS,3)dnl admissible values are 0 to 6, inclusive
/*
* Argument (parameter) registers.
*/
-`#define ARM_NR_ARG_REGS 'NR_ARG_REGS
-`#define NR_ARG_REGS 'NR_ARG_REGS
define(defarg,`define(ARG$1,`$2')dnl
#`define ARG'$1 $2'
@@ -157,6 +164,10 @@ define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_REG_ARG($1,$3)',`NBIF_ST
`/* #define NBIF_ARG_3_0 'NBIF_ARG(r1,3,0)` */'
`/* #define NBIF_ARG_3_1 'NBIF_ARG(r2,3,1)` */'
`/* #define NBIF_ARG_3_2 'NBIF_ARG(r3,3,2)` */'
+`/* #define NBIF_ARG_4_0 'NBIF_ARG(r1,4,0)` */'
+`/* #define NBIF_ARG_4_1 'NBIF_ARG(r2,4,1)` */'
+`/* #define NBIF_ARG_4_2 'NBIF_ARG(r3,4,2)` */'
+`/* #define NBIF_ARG_4_3 'NBIF_ARG(r4,4,3)` */'
`/* #define NBIF_ARG_5_0 'NBIF_ARG(r1,5,0)` */'
`/* #define NBIF_ARG_5_1 'NBIF_ARG(r2,5,1)` */'
`/* #define NBIF_ARG_5_2 'NBIF_ARG(r3,5,2)` */'
@@ -180,6 +191,7 @@ define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl
`/* #define NBIF_RET_1 'NBIF_RET(1)` */'
`/* #define NBIF_RET_2 'NBIF_RET(2)` */'
`/* #define NBIF_RET_3 'NBIF_RET(3)` */'
+`/* #define NBIF_RET_4 'NBIF_RET(4)` */'
`/* #define NBIF_RET_5 'NBIF_RET(5)` */'
dnl
@@ -195,4 +207,6 @@ define(QUICK_CALL_RET,`NBIF_POP_N(eval(RET_POP($2)))b $1')dnl
`/* #define QUICK_CALL_RET_F_3 'QUICK_CALL_RET(F,3)` */'
`/* #define QUICK_CALL_RET_F_5 'QUICK_CALL_RET(F,5)` */'
+`#endif /* ASM */'
+
`#endif /* HIPE_ARM_ASM_H */'
diff --git a/erts/emulator/hipe/hipe_arm_bifs.m4 b/erts/emulator/hipe/hipe_arm_bifs.m4
index 3ca9a1bcdb..3efe961964 100644
--- a/erts/emulator/hipe/hipe_arm_bifs.m4
+++ b/erts/emulator/hipe/hipe_arm_bifs.m4
@@ -4,21 +4,23 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2005-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
+#`define ASM'
include(`hipe/hipe_arm_asm.m4')
#`include' "config.h"
#`include' "hipe_literals.h"
@@ -41,9 +43,10 @@ define(TEST_GOT_MBUF,`ldr r1, [P, #P_MBUF] /* `TEST_GOT_MBUF' */
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 1-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
@@ -133,6 +136,39 @@ $1:
.type $1, %function
#endif')
+define(standard_bif_interface_4,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ .global $1
+$1:
+ /* Set up C argument registers. */
+ mov r0, P
+ NBIF_ARG(r1,4,0)
+ NBIF_ARG(r2,4,1)
+ NBIF_ARG(r3,4,2)
+ NBIF_ARG(r4,4,3)
+
+ /* Save caller-save registers and call the C function. */
+ SAVE_CONTEXT_BIF
+ str r1, [r0, #P_ARG0] /* Store BIF__ARGS in def_arg_reg[] */
+ str r2, [r0, #P_ARG1]
+ str r3, [r0, #P_ARG2]
+ str r4, [r0, #P_ARG3]
+ add r1, r0, #P_ARG0
+ CALL_BIF($2)
+ TEST_GOT_MBUF(4)
+
+ /* Restore registers. Check for exception. */
+ cmp r0, #THE_NON_VALUE
+ RESTORE_CONTEXT_BIF
+ beq nbif_4_simple_exception
+ NBIF_RET(4)
+ .ltorg
+ .size $1, .-$1
+ .type $1, %function
+#endif')
+
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
diff --git a/erts/emulator/hipe/hipe_arm_gc.h b/erts/emulator/hipe/hipe_arm_gc.h
index 787c6fef3e..dfffd6c630 100644
--- a/erts/emulator/hipe/hipe_arm_gc.h
+++ b/erts/emulator/hipe/hipe_arm_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_arm_glue.S b/erts/emulator/hipe/hipe_arm_glue.S
index 5723afac12..e4ce9b75ef 100644
--- a/erts/emulator/hipe/hipe_arm_glue.S
+++ b/erts/emulator/hipe/hipe_arm_glue.S
@@ -3,24 +3,24 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
-
+#define ASM
#include "hipe_arm_asm.h"
#include "hipe_literals.h"
-#define ASM
#include "hipe_mode_switch.h"
.text
@@ -141,7 +141,7 @@ hipe_arm_throw_to_native:
* which should look as follows:
*
* stub for f/N:
- * <set r8 to f's BEAM code address>
+ * <set r8 to f's export entry address>
* <set r0 to N>
* b nbif_callemu
*
@@ -150,10 +150,10 @@ hipe_arm_throw_to_native:
.global nbif_callemu
.type nbif_callemu, %function
nbif_callemu:
- str r8, [P, #P_BEAM_IP]
+ str r8, [P, #P_CALLEE_EXP]
str r0, [P, #P_ARITY]
STORE_ARG_REGS
- mov r0, #HIPE_MODE_SWITCH_RES_CALL
+ mov r0, #HIPE_MODE_SWITCH_RES_CALL_EXPORTED
b .suspend_exit
/*
@@ -331,6 +331,12 @@ nbif_2_gc_after_bif:
.type nbif_3_gc_after_bif, %function
nbif_3_gc_after_bif:
mov r1, #3
+ b .gc_after_bif
+
+ .global nbif_4_gc_after_bif
+ .type nbif_4_gc_after_bif, %function
+nbif_4_gc_after_bif:
+ mov r1, #4
/*FALLTHROUGH*/
.gc_after_bif:
str r1, [P, #P_NARITY]
@@ -377,6 +383,12 @@ nbif_2_simple_exception:
.type nbif_3_simple_exception, %function
nbif_3_simple_exception:
mov r1, #3
+ b .nbif_simple_exception
+
+ .global nbif_4_simple_exception
+ .type nbif_4_simple_exception, %function
+nbif_4_simple_exception:
+ mov r1, #4
/*FALLTHROUGH*/
.nbif_simple_exception:
ldr r0, [P, #P_FREASON]
diff --git a/erts/emulator/hipe/hipe_arm_glue.h b/erts/emulator/hipe/hipe_arm_glue.h
index 165f73320d..39bc27ec5f 100644
--- a/erts/emulator/hipe/hipe_arm_glue.h
+++ b/erts/emulator/hipe/hipe_arm_glue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_arm_primops.h b/erts/emulator/hipe/hipe_arm_primops.h
index 2a1a87b862..0e8f84dfb9 100644
--- a/erts/emulator/hipe/hipe_arm_primops.h
+++ b/erts/emulator/hipe/hipe_arm_primops.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index 8af174170d..c838150db8 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -89,25 +90,6 @@ static Eterm address_to_term(const void *address, Process *p)
/*
* BIFs for reading and writing memory. Used internally by HiPE.
*/
-#if 0 /* XXX: unused */
-BIF_RETTYPE hipe_bifs_read_u8_1(BIF_ALIST_1)
-{
- unsigned char *address = term_to_address(BIF_ARG_1);
- if (!address)
- BIF_ERROR(BIF_P, BADARG);
- BIF_RET(make_small(*address));
-}
-#endif
-
-#if 0 /* XXX: unused */
-BIF_RETTYPE hipe_bifs_read_u32_1(BIF_ALIST_1)
-{
- Uint32 *address = term_to_address(BIF_ARG_1);
- if (!address || !hipe_word32_address_ok(address))
- BIF_ERROR(BIF_P, BADARG);
- BIF_RET(Uint_to_term(*address, BIF_P));
-}
-#endif
BIF_RETTYPE hipe_bifs_write_u8_2(BIF_ALIST_2)
{
@@ -120,22 +102,6 @@ BIF_RETTYPE hipe_bifs_write_u8_2(BIF_ALIST_2)
BIF_RET(NIL);
}
-#if 0 /* XXX: unused */
-BIF_RETTYPE hipe_bifs_write_s32_2(BIF_ALIST_2)
-{
- Sint32 *address;
- Sint value;
-
- address = term_to_address(BIF_ARG_1);
- if (!address || !hipe_word32_address_ok(address))
- BIF_ERROR(BIF_P, BADARG);
- if (!term_to_Sint32(BIF_ARG_2, &value))
- BIF_ERROR(BIF_P, BADARG);
- *address = value;
- BIF_RET(NIL);
-}
-#endif
-
BIF_RETTYPE hipe_bifs_write_u32_2(BIF_ALIST_2)
{
Uint32 *address;
@@ -432,15 +398,17 @@ BIF_RETTYPE hipe_bifs_enter_code_2(BIF_ALIST_2)
ASSERT(bitoffs == 0);
ASSERT(bitsize == 0);
trampolines = NIL;
-#ifdef HIPE_ALLOC_CODE
- address = HIPE_ALLOC_CODE(nrbytes, BIF_ARG_2, &trampolines, BIF_P);
- if (!address)
- BIF_ERROR(BIF_P, BADARG);
-#else
- if (is_not_nil(BIF_ARG_2))
- BIF_ERROR(BIF_P, BADARG);
- address = erts_alloc(ERTS_ALC_T_HIPE, nrbytes);
-#endif
+ address = hipe_alloc_code(nrbytes, BIF_ARG_2, &trampolines, BIF_P);
+ if (!address) {
+ Uint nrcallees;
+
+ if (is_tuple(BIF_ARG_2))
+ nrcallees = arityval(tuple_val(BIF_ARG_2)[0]);
+ else
+ nrcallees = 0;
+ erts_exit(ERTS_ERROR_EXIT, "%s: failed to allocate %lu bytes and %lu trampolines\r\n",
+ __func__, (unsigned long)nrbytes, (unsigned long)nrcallees);
+ }
memcpy(address, bytes, nrbytes);
hipe_flush_icache_range(address, nrbytes);
hp = HAlloc(BIF_P, 3);
@@ -639,33 +607,6 @@ BIF_RETTYPE hipe_bifs_fun_to_address_1(BIF_ALIST_1)
BIF_RET(address_to_term(pc, BIF_P));
}
-static void *hipe_get_emu_address(Eterm m, Eterm f, unsigned int arity, int is_remote)
-{
- void *address = NULL;
- if (!is_remote)
- address = hipe_find_emu_address(m, f, arity);
- if (!address) {
- /* if not found, stub it via the export entry */
- /* no lock needed around erts_export_get_or_make_stub() */
- Export *export_entry = erts_export_get_or_make_stub(m, f, arity);
- address = export_entry->addressv[erts_active_code_ix()];
- }
- return address;
-}
-
-#if 0 /* XXX: unused */
-BIF_RETTYPE hipe_bifs_get_emu_address_1(BIF_ALIST_1)
-{
- struct mfa mfa;
- void *address;
-
- if (!term_to_mfa(BIF_ARG_1, &mfa))
- BIF_ERROR(BIF_P, BADARG);
- address = hipe_get_emu_address(mfa.mod, mfa.fun, mfa.ari);
- BIF_RET(address_to_term(address, BIF_P));
-}
-#endif
-
BIF_RETTYPE hipe_bifs_set_native_address_3(BIF_ALIST_3)
{
Eterm *pc;
@@ -713,33 +654,6 @@ BIF_RETTYPE hipe_bifs_set_native_address_3(BIF_ALIST_3)
BIF_RET(am_false);
}
-#if 0 /* XXX: unused */
-/*
- * hipe_bifs_address_to_fun(Address)
- * - Address is the address of the start of a emu function's code
- * - returns {Module, Function, Arity}
- */
-BIF_RETTYPE hipe_bifs_address_to_fun_1(BIF_ALIST_1)
-{
- Eterm *pc;
- Eterm *funcinfo;
- Eterm *hp;
-
- pc = term_to_address(BIF_ARG_1);
- if (!pc)
- BIF_ERROR(BIF_P, BADARG);
- funcinfo = find_function_from_pc(pc);
- if (!funcinfo)
- BIF_RET(am_false);
- hp = HAlloc(BIF_P, 4);
- hp[0] = make_arityval(3);
- hp[1] = funcinfo[0];
- hp[2] = funcinfo[1];
- hp[3] = make_small(funcinfo[2]);
- BIF_RET(make_tuple(hp));
-}
-#endif
-
BIF_RETTYPE hipe_bifs_enter_sdesc_1(BIF_ALIST_1)
{
struct sdesc *sdesc;
@@ -948,37 +862,6 @@ BIF_RETTYPE hipe_bifs_primop_address_1(BIF_ALIST_1)
BIF_RET(address_to_term(primop->address, BIF_P));
}
-#if 0 /* XXX: unused */
-/*
- * hipe_bifs_gbif_address(F,A) -> address or false
- */
-#define GBIF_LIST(ATOM,ARY,CFUN) extern Eterm gbif_##CFUN(void);
-#include "hipe_gbif_list.h"
-#undef GBIF_LIST
-
-BIF_RETTYPE hipe_bifs_gbif_address_2(BIF_ALIST_2)
-{
- Uint arity;
- void *address;
-
- if (is_not_atom(BIF_ARG_1) || is_not_small(BIF_ARG_2))
- BIF_RET(am_false); /* error or false, does it matter? */
- arity = signed_val(BIF_ARG_2);
- /* XXX: replace with a hash table later */
- do { /* trick to let us use 'break' instead of 'goto' */
-#define GBIF_LIST(ATOM,ARY,CFUN) if (BIF_ARG_1 == ATOM && arity == ARY) { address = CFUN; break; }
-#include "hipe_gbif_list.h"
-#undef GBIF_LIST
- printf("\r\n%s: guard BIF ", __FUNCTION__);
- fflush(stdout);
- erts_printf("%T", BIF_ARG_1);
- printf("/%lu isn't listed in hipe_gbif_list.h\r\n", arity);
- BIF_RET(am_false);
- } while (0);
- BIF_RET(address_to_term(address, BIF_P));
-}
-#endif
-
BIF_RETTYPE hipe_bifs_atom_to_word_1(BIF_ALIST_1)
{
if (is_not_atom(BIF_ARG_1))
@@ -1028,77 +911,13 @@ void hipe_emulate_fpe(Process* p)
}
#endif
-#if 0 /* XXX: unused */
-/*
- * At least parts of this should be inlined in native code.
- * The rest could be made a primop used by both the emulator and
- * native code...
- */
-BIF_RETTYPE hipe_bifs_make_fun_3(BIF_ALIST_3)
+void hipe_emasculate_binary(Eterm bin)
{
- Eterm free_vars;
- Eterm mod;
- Eterm *tp;
- Uint index;
- Uint uniq;
- Uint num_free;
- Eterm tmp_var;
- Uint *tmp_ptr;
- unsigned needed;
- ErlFunThing *funp;
- Eterm *hp;
- int i;
-
- if (is_not_list(BIF_ARG_1) && is_not_nil(BIF_ARG_1))
- BIF_ERROR(BIF_P, BADARG);
- free_vars = BIF_ARG_1;
-
- if (is_not_atom(BIF_ARG_2))
- BIF_ERROR(BIF_P, BADARG);
- mod = BIF_ARG_2;
-
- if (is_not_tuple(BIF_ARG_3) ||
- (arityval(*tuple_val(BIF_ARG_3)) != 3))
- BIF_ERROR(BIF_P, BADARG);
- tp = tuple_val(BIF_ARG_3);
-
- if (term_to_Uint(tp[1], &index) == 0)
- BIF_ERROR(BIF_P, BADARG);
- if (term_to_Uint(tp[2], &uniq) == 0)
- BIF_ERROR(BIF_P, BADARG);
- if (term_to_Uint(tp[3], &num_free) == 0)
- BIF_ERROR(BIF_P, BADARG);
-
- needed = ERL_FUN_SIZE + num_free;
- funp = (ErlFunThing *) HAlloc(BIF_P, needed);
- hp = funp->env;
-
- funp->thing_word = HEADER_FUN;
-
- /* Need a ErlFunEntry *fe
- * fe->refc++;
- * funp->fe = fe;
- */
-
- funp->num_free = num_free;
- funp->creator = BIF_P->id;
- for (i = 0; i < num_free; i++) {
- if (is_nil(free_vars))
- BIF_ERROR(BIF_P, BADARG);
- tmp_ptr = list_val(free_vars);
- tmp_var = CAR(tmp_ptr);
- free_vars = CDR(tmp_ptr);
- *hp++ = tmp_var;
- }
- if (is_not_nil(free_vars))
- BIF_ERROR(BIF_P, BADARG);
-
- funp->next = MSO(BIF_P).funs;
- MSO(BIF_P).funs = funp;
-
- BIF_RET(make_fun(funp));
+ ProcBin* pb = (ProcBin *) boxed_val(bin);
+ ASSERT(pb->thing_word == HEADER_PROC_BIN);
+ ASSERT(pb->flags != 0);
+ erts_emasculate_writable_binary(pb);
}
-#endif
/*
* args: Module, {Uniq, Index, BeamAddress}
@@ -1163,22 +982,6 @@ BIF_RETTYPE hipe_bifs_set_native_address_in_fe_2(BIF_ALIST_2)
BIF_RET(am_true);
}
-#if 0 /* XXX: unused */
-BIF_RETTYPE hipe_bifs_make_native_stub_2(BIF_ALIST_2)
-{
- void *beamAddress;
- Uint beamArity;
- void *stubAddress;
-
- if ((beamAddress = term_to_address(BIF_ARG_1)) == 0 ||
- is_not_small(BIF_ARG_2) ||
- (beamArity = unsigned_val(BIF_ARG_2)) >= 256)
- BIF_ERROR(BIF_P, BADARG);
- stubAddress = hipe_make_native_stub(beamAddress, beamArity);
- BIF_RET(address_to_term(stubAddress, BIF_P));
-}
-#endif
-
/*
* MFA info hash table:
* - maps MFA to native code entry point
@@ -1500,18 +1303,15 @@ void hipe_mfa_save_orig_beam_op(Eterm mod, Eterm fun, unsigned int ari, Eterm *p
static void *hipe_make_stub(Eterm m, Eterm f, unsigned int arity, int is_remote)
{
- void *BEAMAddress;
+ Export *export_entry;
void *StubAddress;
-#if 0
- if (is_not_atom(m) || is_not_atom(f) || arity > 255)
- return NULL;
-#endif
- BEAMAddress = hipe_get_emu_address(m, f, arity, is_remote);
- StubAddress = hipe_make_native_stub(BEAMAddress, arity);
-#if 0
- hipe_mfa_set_na(m, f, arity, StubAddress);
-#endif
+ ASSERT(is_remote);
+
+ export_entry = erts_export_get_or_make_stub(m, f, arity);
+ StubAddress = hipe_make_native_stub(export_entry, arity);
+ if (!StubAddress)
+ erts_exit(ERTS_ERROR_EXIT, "hipe_make_stub: code allocation failed\r\n");
return StubAddress;
}
@@ -1941,18 +1741,16 @@ BIF_RETTYPE hipe_bifs_check_crc_1(BIF_ALIST_1)
if (!term_to_Uint(BIF_ARG_1, &crc))
BIF_ERROR(BIF_P, BADARG);
- if (crc == HIPE_SYSTEM_CRC)
+ if (crc == HIPE_ERTS_CHECKSUM)
BIF_RET(am_true);
BIF_RET(am_false);
}
-BIF_RETTYPE hipe_bifs_system_crc_1(BIF_ALIST_1)
+BIF_RETTYPE hipe_bifs_system_crc_0(BIF_ALIST_0)
{
Uint crc;
- if (!term_to_Uint(BIF_ARG_1, &crc))
- BIF_ERROR(BIF_P, BADARG);
- crc ^= (HIPE_SYSTEM_CRC ^ HIPE_LITERALS_CRC);
+ crc = HIPE_SYSTEM_CRC;
BIF_RET(Uint_to_term(crc, BIF_P));
}
diff --git a/erts/emulator/hipe/hipe_bif0.h b/erts/emulator/hipe/hipe_bif0.h
index c512d66f9d..5527c6c3ed 100644
--- a/erts/emulator/hipe/hipe_bif0.h
+++ b/erts/emulator/hipe/hipe_bif0.h
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_bif0.tab b/erts/emulator/hipe/hipe_bif0.tab
index 2514b1c3a5..5ce254314a 100644
--- a/erts/emulator/hipe/hipe_bif0.tab
+++ b/erts/emulator/hipe/hipe_bif0.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -49,7 +50,6 @@ bif hipe_bifs:constants_size/0
bif hipe_bifs:merge_term/1
bif hipe_bifs:fun_to_address/1
-#bif hipe_bifs:get_emu_address/1
bif hipe_bifs:set_native_address/3
#bif hipe_bifs:address_to_fun/1
@@ -72,11 +72,10 @@ bif hipe_bifs:term_to_word/1
bif hipe_bifs:get_fe/2
bif hipe_bifs:set_native_address_in_fe/2
-#bif hipe_bifs:make_native_stub/2
bif hipe_bifs:find_na_or_make_stub/2
bif hipe_bifs:check_crc/1
-bif hipe_bifs:system_crc/1
+bif hipe_bifs:system_crc/0
bif hipe_bifs:get_rts_param/1
#bif hipe_bifs:tuple_to_float/1
@@ -142,4 +141,5 @@ atom bs_get_utf16
atom bs_validate_unicode
atom bs_validate_unicode_retract
atom emulate_fpe
-
+atom emasculate_binary
+atom is_divisible
diff --git a/erts/emulator/hipe/hipe_bif1.c b/erts/emulator/hipe/hipe_bif1.c
index 56767ef04b..a2682992a4 100644
--- a/erts/emulator/hipe/hipe_bif1.c
+++ b/erts/emulator/hipe/hipe_bif1.c
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 2001-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -574,22 +575,6 @@ BIF_RETTYPE hipe_bifs_pause_times_0(BIF_ALIST_0)
/* XXX: these macros have free variables */
#ifdef BM_TIMERS
-#if USE_PERFCTR
-#define MAKE_TIME(_timer_) { \
- BM_TIMER_T tmp = _timer_##_time; \
- milli = (uint)(tmp - ((int)(tmp / 1000)) * 1000); \
- tmp /= 1000; \
- sec = (uint)(tmp - ((int)(tmp / 60)) * 60); \
- min = (uint)tmp / 60; }
-
-#define MAKE_MICRO_TIME(_timer_) { \
- BM_TIMER_T tmp = _timer_##_time * 1000; \
- micro = (uint)(tmp - ((int)(tmp / 1000)) * 1000); \
- tmp /= 1000; \
- milli = (uint)(tmp - ((int)(tmp / 1000)) * 1000); \
- sec = (uint)tmp / 1000; }
-
-#else
#define MAKE_TIME(_timer_) { \
BM_TIMER_T tmp = _timer_##_time / 1000000; \
milli = tmp % 1000; \
@@ -604,7 +589,6 @@ BIF_RETTYPE hipe_bifs_pause_times_0(BIF_ALIST_0)
milli = tmp % 1000; \
sec = tmp / 1000; }
-#endif
#else
#define MAKE_TIME(_timer_)
#define MAKE_MICRO_TIME(_timer_)
@@ -852,9 +836,6 @@ BIF_RETTYPE hipe_bifs_misc_timer_clear_0(BIF_ALIST_0)
/*
* HiPE hrvtime().
* These implementations are currently available:
- * + On Linux with the perfctr extension we can use the process'
- * virtualised time-stamp counter. To enable this mode you must
- * pass `--with-perfctr=/path/to/perfctr' when configuring.
* + The fallback, which is the same as {X,_} = runtime(statistics).
*/
@@ -866,37 +847,6 @@ static double fallback_get_hrvtime(void)
return (double)ms_user;
}
-#if USE_PERFCTR
-
-#include "hipe_perfctr.h"
-static int hrvtime_started; /* 0: closed, +1: perfctr, -1: fallback */
-#define hrvtime_is_started() (hrvtime_started != 0)
-
-static void start_hrvtime(void)
-{
- if (hipe_perfctr_hrvtime_open() >= 0)
- hrvtime_started = 1;
- else
- hrvtime_started = -1;
-}
-
-static void stop_hrvtime(void)
-{
- if (hrvtime_started > 0)
- hipe_perfctr_hrvtime_close();
- hrvtime_started = 0;
-}
-
-static double get_hrvtime(void)
-{
- if (hrvtime_started > 0)
- return hipe_perfctr_hrvtime_get();
- else
- return fallback_get_hrvtime();
-}
-
-#else /* !USE_PERFCTR */
-
/*
* Fallback, if nothing better exists.
* This is the same as {X,_} = statistics(runtime), which uses
@@ -908,8 +858,6 @@ static double get_hrvtime(void)
#define stop_hrvtime() do{}while(0)
#define get_hrvtime() fallback_get_hrvtime()
-#endif /* !USE_PERFCTR */
-
BIF_RETTYPE hipe_bifs_get_hrvtime_0(BIF_ALIST_0)
{
Eterm *hp;
diff --git a/erts/emulator/hipe/hipe_bif1.h b/erts/emulator/hipe/hipe_bif1.h
index 89241fb835..80cdeb4a82 100644
--- a/erts/emulator/hipe/hipe_bif1.h
+++ b/erts/emulator/hipe/hipe_bif1.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_bif1.tab b/erts/emulator/hipe/hipe_bif1.tab
index eb445d56f7..6c4e05afdb 100644
--- a/erts/emulator/hipe/hipe_bif1.tab
+++ b/erts/emulator/hipe/hipe_bif1.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/hipe/hipe_bif2.c b/erts/emulator/hipe/hipe_bif2.c
index 054911e822..2328e69886 100644
--- a/erts/emulator/hipe/hipe_bif2.c
+++ b/erts/emulator/hipe/hipe_bif2.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_bif2.tab b/erts/emulator/hipe/hipe_bif2.tab
index 1b659cfa90..a29e1fbdbb 100644
--- a/erts/emulator/hipe/hipe_bif2.tab
+++ b/erts/emulator/hipe/hipe_bif2.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/hipe/hipe_bif64.c b/erts/emulator/hipe/hipe_bif64.c
index baaf5af2cd..b97cf2b7ee 100644
--- a/erts/emulator/hipe/hipe_bif64.c
+++ b/erts/emulator/hipe/hipe_bif64.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_bif64.h b/erts/emulator/hipe/hipe_bif64.h
index 6d494886ec..856b4003dc 100644
--- a/erts/emulator/hipe/hipe_bif64.h
+++ b/erts/emulator/hipe/hipe_bif64.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_bif64.tab b/erts/emulator/hipe/hipe_bif64.tab
index 228318af39..3062ab5848 100644
--- a/erts/emulator/hipe/hipe_bif64.tab
+++ b/erts/emulator/hipe/hipe_bif64.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4
index 5f92b6bac4..7240280345 100644
--- a/erts/emulator/hipe/hipe_bif_list.m4
+++ b/erts/emulator/hipe/hipe_bif_list.m4
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -192,6 +193,7 @@ standard_bif_interface_2(nbif_rethrow, hipe_rethrow)
standard_bif_interface_3(nbif_find_na_or_make_stub, hipe_find_na_or_make_stub)
standard_bif_interface_2(nbif_nonclosure_address, hipe_nonclosure_address)
nocons_nofail_primop_interface_0(nbif_fclearerror_error, hipe_fclearerror_error)
+standard_bif_interface_2(nbif_is_divisible, hipe_is_divisible)
/*
* Mbox primops with implicit P parameter.
@@ -250,6 +252,8 @@ gc_bif_interface_0(nbif_check_get_msg, hipe_check_get_msg)
nocons_nofail_primop_interface_0(nbif_emulate_fpe, hipe_emulate_fpe)
#endif
+noproc_primop_interface_1(nbif_emasculate_binary, hipe_emasculate_binary)
+
/*
* SMP-specific stuff
*/
@@ -266,18 +270,23 @@ noproc_primop_interface_1(nbif_atomic_inc, hipe_atomic_inc)
/* BIFs that disable GC while trapping are called via a wrapper
* to reserve stack space for the "trap frame".
*/
-define(CFUN,`ifelse($1,term_to_binary_1,hipe_wrapper_term_to_binary_1,
-ifelse($1,term_to_binary_2,hipe_wrapper_term_to_binary_2,
-ifelse($1,binary_to_term_1,hipe_wrapper_binary_to_term_1,
-ifelse($1,binary_to_term_2,hipe_wrapper_binary_to_term_2,
-ifelse($1,binary_to_list_1,hipe_wrapper_binary_to_list_1,
-ifelse($1,binary_to_list_3,hipe_wrapper_binary_to_list_3,
-ifelse($1,bitstring_to_list_1,hipe_wrapper_bitstring_to_list_1,
-ifelse($1,list_to_binary_1,hipe_wrapper_list_to_binary_1,
-ifelse($1,iolist_to_binary_1,hipe_wrapper_iolist_to_binary_1,
-ifelse($1,binary_list_to_bin_1,hipe_wrapper_binary_list_to_bin_1,
-ifelse($1,list_to_bitstring_1,hipe_wrapper_list_to_bitstring_1,
-$1)))))))))))')
+define(CFUN,`ifelse(
+$1, term_to_binary_1, hipe_wrapper_$1,
+$1, term_to_binary_2, hipe_wrapper_$1,
+$1, binary_to_term_1, hipe_wrapper_$1,
+$1, binary_to_term_2, hipe_wrapper_$1,
+$1, binary_to_list_1, hipe_wrapper_$1,
+$1, binary_to_list_3, hipe_wrapper_$1,
+$1, bitstring_to_list_1, hipe_wrapper_$1,
+$1, list_to_binary_1, hipe_wrapper_$1,
+$1, iolist_to_binary_1, hipe_wrapper_$1,
+$1, binary_list_to_bin_1, hipe_wrapper_$1,
+$1, list_to_bitstring_1, hipe_wrapper_$1,
+$1, send_2, hipe_wrapper_$1,
+$1, send_3, hipe_wrapper_$1,
+$1, ebif_bang_2, hipe_wrapper_$1,
+$1, maps_merge_2, hipe_wrapper_$1,
+$1)')
define(BIF_LIST,`standard_bif_interface_$3(nbif_$4, CFUN($4))')
include(TARGET/`erl_bif_list.h')
diff --git a/erts/emulator/hipe/hipe_debug.c b/erts/emulator/hipe/hipe_debug.c
index 32694a8f97..a48578c468 100644
--- a/erts/emulator/hipe/hipe_debug.c
+++ b/erts/emulator/hipe/hipe_debug.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -172,8 +173,10 @@ void hipe_print_pcb(Process *p)
printf("P: 0x%0*lx\r\n", 2*(int)sizeof(long), (unsigned long)p);
printf("-----------------------------------------------\r\n");
printf("Offset| Name | Value | *Value |\r\n");
+#undef U
#define U(n,x) \
printf(" % 4d | %s | 0x%0*lx | |\r\n", (int)offsetof(Process,x), n, 2*(int)sizeof(long), (unsigned long)p->x)
+#undef P
#define P(n,x) \
printf(" % 4d | %s | 0x%0*lx | 0x%0*lx |\r\n", (int)offsetof(Process,x), n, 2*(int)sizeof(long), (unsigned long)p->x, 2*(int)sizeof(long), p->x ? (unsigned long)*(p->x) : -1UL)
@@ -211,9 +214,9 @@ void hipe_print_pcb(Process *p)
U("seq..clock ", seq_trace_clock);
U("seq..astcnt", seq_trace_lastcnt);
U("seq..token ", seq_trace_token);
- U("intial[0] ", initial[0]);
- U("intial[1] ", initial[1]);
- U("intial[2] ", initial[2]);
+ U("intial[0] ", u.initial[0]);
+ U("intial[1] ", u.initial[1]);
+ U("intial[2] ", u.initial[2]);
P("current ", current);
P("cp ", cp);
P("i ", i);
@@ -231,7 +234,7 @@ void hipe_print_pcb(Process *p)
U("nsp ", hipe.nsp);
U("nstack ", hipe.nstack);
U("nstend ", hipe.nstend);
- U("ncallee ", hipe.ncallee);
+ U("ncallee ", hipe.u.ncallee);
hipe_arch_print_pcb(&p->hipe);
#endif /* HIPE */
#undef U
diff --git a/erts/emulator/hipe/hipe_debug.h b/erts/emulator/hipe/hipe_debug.h
index a28597000a..bf10d5a2a8 100644
--- a/erts/emulator/hipe/hipe_debug.h
+++ b/erts/emulator/hipe/hipe_debug.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_gbif_list.h b/erts/emulator/hipe/hipe_gbif_list.h
index 69dbab7ab9..dc93741a1d 100644
--- a/erts/emulator/hipe/hipe_gbif_list.h
+++ b/erts/emulator/hipe/hipe_gbif_list.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_gc.c b/erts/emulator/hipe/hipe_gc.c
index 86c4068072..2c747771ac 100644
--- a/erts/emulator/hipe/hipe_gc.c
+++ b/erts/emulator/hipe/hipe_gc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -22,6 +23,9 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+#define ERL_WANT_GC_INTERNALS__
+
#include "global.h"
#include "erl_gc.h"
diff --git a/erts/emulator/hipe/hipe_gc.h b/erts/emulator/hipe/hipe_gc.h
index 0d5614c9cf..e373324cdd 100644
--- a/erts/emulator/hipe/hipe_gc.h
+++ b/erts/emulator/hipe/hipe_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_mkliterals.c b/erts/emulator/hipe/hipe_mkliterals.c
index 0e287908b1..dfa5313739 100644
--- a/erts/emulator/hipe/hipe_mkliterals.c
+++ b/erts/emulator/hipe/hipe_mkliterals.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -268,9 +269,6 @@ static const struct literal {
/* freason codes */
{ "FREASON_TRAP", TRAP },
- /* special Erlang constants */
- { "THE_NON_VALUE", (int)THE_NON_VALUE },
-
/* funs */
#ifdef HIPE
{ "EFE_NATIVE_ADDRESS", offsetof(struct erl_fun_entry, native_address) },
@@ -498,8 +496,8 @@ static const struct rts_param rts_params[] = {
{ 38, "P_ARG4", 1, offsetof(struct process, def_arg_reg[4]) },
{ 39, "P_ARG5", 1, offsetof(struct process, def_arg_reg[5]) },
{ 40, "P_NSP", 1, offsetof(struct process, hipe.nsp) },
- { 41, "P_NCALLEE", 1, offsetof(struct process, hipe.ncallee) },
- { 42, "P_CLOSURE", 1, offsetof(struct process, hipe.closure) },
+ { 41, "P_NCALLEE", 1, offsetof(struct process, hipe.u.ncallee) },
+ { 42, "P_CLOSURE", 1, offsetof(struct process, hipe.u.closure) },
{ 43, "P_NSP_LIMIT", 1, offsetof(struct process, hipe.nstack) },
{ 44, "P_CSP",
#if defined(__i386__) || defined(__x86_64__)
@@ -524,6 +522,9 @@ static const struct rts_param rts_params[] = {
},
{ 49, "P_MSG_FIRST", 1, offsetof(struct process, msg.first) },
{ 50, "P_MSG_SAVE", 1, offsetof(struct process, msg.save) },
+ { 51, "P_CALLEE_EXP", 1, offsetof(struct process, hipe.u.callee_exp) },
+
+ { 52, "THE_NON_VALUE", 1, (int)THE_NON_VALUE },
};
#define NR_PARAMS ARRAY_SIZE(rts_params)
@@ -541,6 +542,8 @@ static void compute_crc(void)
crc_value = crc_update_int(crc_value, &literals[i].value);
crc_value &= 0x07FFFFFF;
literals_crc = crc_value;
+
+ crc_value = crc_init();
for (i = 0; i < NR_PARAMS; ++i)
if (rts_params[i].is_defined)
crc_value = crc_update_int(crc_value, &rts_params[i].value);
@@ -626,6 +629,7 @@ static int do_c(FILE *fp, const char* this_exe)
print_params(fp, c_define_param);
fprintf(fp, "#define HIPE_LITERALS_CRC %uU\n", literals_crc);
fprintf(fp, "#define HIPE_SYSTEM_CRC %uU\n", system_crc);
+ fprintf(fp, "#define HIPE_ERTS_CHECKSUM (HIPE_LITERALS_CRC ^ HIPE_SYSTEM_CRC)\n");
fprintf(fp, "\n");
fprintf(fp, "#define RTS_PARAMS_CASES");
print_params(fp, c_case_param);
@@ -643,13 +647,14 @@ static int do_e(FILE *fp, const char* this_exe)
fprintf(fp, "\n");
print_params(fp, e_define_param);
fprintf(fp, "\n");
+ fprintf(fp, "-define(HIPE_LITERALS_CRC, %u).\n", literals_crc);
if (is_xcomp) {
fprintf(fp, "-define(HIPE_SYSTEM_CRC, %u).\n", system_crc);
}
else {
- fprintf(fp, "-define(HIPE_SYSTEM_CRC, hipe_bifs:system_crc(%u)).\n",
- literals_crc);
+ fprintf(fp, "-define(HIPE_SYSTEM_CRC, hipe_bifs:system_crc()).\n");
}
+ fprintf(fp, "-define(HIPE_ERTS_CHECKSUM, (?HIPE_LITERALS_CRC bxor ?HIPE_SYSTEM_CRC)).\n");
return 0;
}
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index 1ae1d17b7f..9243e029f6 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -107,7 +108,7 @@ static const char *code_str(unsigned code)
static void __noreturn
hipe_abort(const char *expr, const char *file, unsigned line)
{
- erl_exit(1, "ASSERTION FAILED, file %s, line %u: %s\r\n", file, line, expr);
+ erts_exit(ERTS_ERROR_EXIT, "ASSERTION FAILED, file %s, line %u: %s\r\n", file, line, expr);
}
#define HIPE_ASSERT3(expr, file, line) \
@@ -140,7 +141,6 @@ void hipe_check_pcb(Process *p, const char *file, unsigned line)
#endif /* HIPE_DEBUG > 0 */
/* ensure that at least nwords words are available on the native stack */
-static void hipe_check_nstack(Process *p, unsigned nwords);
#if defined(__sparc__)
#include "hipe_sparc_glue.h"
@@ -159,7 +159,7 @@ static void hipe_check_nstack(Process *p, unsigned nwords);
Uint hipe_beam_pc_return[1]; /* needed in hipe_debug.c */
Uint hipe_beam_pc_throw[1]; /* needed in hipe_debug.c */
Uint hipe_beam_pc_resume[1]; /* needed by hipe_set_timeout() */
-static Eterm hipe_beam_catch_throw;
+Eterm hipe_beam_catch_throw;
void hipe_mode_switch_init(void)
{
@@ -185,22 +185,6 @@ void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure)
bfun[-4] = (Uint)nfun;
}
-void hipe_reserve_beam_trap_frame(Process *p, Eterm reg[], unsigned arity)
-{
- if (!hipe_bifcall_from_native_is_recursive(p))
- return;
-
- /* ensure that at least 2 words are available on the BEAM stack */
- if ((p->stop - 2) < p->htop) {
- DPRINTF("calling gc to reserve BEAM stack size");
- p->fcalls -= erts_garbage_collect(p, 2, reg, arity);
- ASSERT(!((p->stop - 2) < p->htop));
- }
- p->stop -= 2;
- p->stop[0] = NIL;
- p->stop[1] = hipe_beam_catch_throw;
-}
-
static __inline__ void
hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity)
{
@@ -223,15 +207,6 @@ hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity)
p->cp = hipe_beam_pc_return;
}
-void hipe_unreserve_beam_trap_frame(Process *p)
-{
- if (!hipe_bifcall_from_native_is_recursive(p))
- return;
-
- ASSERT(p->stop[0] == NIL && p->stop[1] == hipe_beam_catch_throw);
- p->stop += 2;
-}
-
static __inline__ void hipe_pop_beam_trap_frame(Process *p)
{
ASSERT(p->stop[1] == hipe_beam_catch_throw);
@@ -265,14 +240,14 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
/* BEAM calls a native code function */
unsigned arity = cmd >> 8;
- /* p->hipe.ncallee set in beam_emu */
+ /* p->hipe.u.ncallee set in beam_emu */
if (p->cp == hipe_beam_pc_return) {
/* Native called BEAM, which now tailcalls native. */
hipe_pop_beam_trap_frame(p);
result = hipe_tailcall_to_native(p, arity, reg);
break;
}
- DPRINTF("calling %#lx/%u", (long)p->hipe.ncallee, arity);
+ DPRINTF("calling %#lx/%u", (long)p->hipe.u.ncallee, arity);
result = hipe_call_to_native(p, arity, reg);
break;
}
@@ -290,18 +265,18 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
arity -= funp->num_free; /* arity == #formals */
reg[arity] = fun;
++arity; /* correct for having added the closure */
- /* HIPE_ASSERT(p->hipe.ncallee == (void(*)(void))funp->native_address); */
+ /* HIPE_ASSERT(p->hipe.u.ncallee == (void(*)(void))funp->native_address); */
/* just like a normal call from now on */
- /* p->hipe.ncallee set in beam_emu */
+ /* p->hipe.u.ncallee set in beam_emu */
if (p->cp == hipe_beam_pc_return) {
/* Native called BEAM, which now tailcalls native. */
hipe_pop_beam_trap_frame(p);
result = hipe_tailcall_to_native(p, arity, reg);
break;
}
- DPRINTF("calling %#lx/%u", (long)p->hipe.ncallee, arity);
+ DPRINTF("calling %#lx/%u", (long)p->hipe.u.ncallee, arity);
result = hipe_call_to_native(p, arity, reg);
break;
}
@@ -341,7 +316,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
break;
}
default:
- erl_exit(1, "hipe_mode_switch: cmd %#x\r\n", cmd);
+ erts_exit(ERTS_ERROR_EXIT, "hipe_mode_switch: cmd %#x\r\n", cmd);
}
do_return_from_native:
DPRINTF("result == %#x (%s)", result, code_str(result));
@@ -404,13 +379,13 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
if (is_recursive)
hipe_push_beam_trap_frame(p, reg, p->arity);
- result = HIPE_MODE_SWITCH_RES_CALL;
+ result = HIPE_MODE_SWITCH_RES_CALL_BEAM;
break;
}
- case HIPE_MODE_SWITCH_RES_CALL: {
+ case HIPE_MODE_SWITCH_RES_CALL_EXPORTED: {
/* Native code calls or tailcalls BEAM.
*
- * p->i is the callee's BEAM code
+ * p->hipe.u.callee_exp is the callee's export entry
* p->arity is the callee's arity
* p->def_arg_reg[] contains the register parameters
* p->hipe.nsp[] contains the stacked parameters
@@ -430,15 +405,15 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
* F(A1, ..., AN, FV1, ..., FVM, Closure)
* (Where Ai is argument i and FVj is free variable j)
*
- * p->hipe.closure contains the closure
+ * p->hipe.u.closure contains the closure
* p->def_arg_reg[] contains the register parameters
* p->hipe.nsp[] contains the stacked parameters
*/
ErlFunThing *closure;
unsigned num_free, arity, i, is_recursive;
- HIPE_ASSERT(is_fun(p->hipe.closure));
- closure = (ErlFunThing*)fun_val(p->hipe.closure);
+ HIPE_ASSERT(is_fun(p->hipe.u.closure));
+ closure = (ErlFunThing*)fun_val(p->hipe.u.closure);
num_free = closure->num_free;
arity = closure->fe->arity;
@@ -468,10 +443,10 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
p->i = closure->fe->address;
/* Change result code to the faster plain CALL type. */
- result = HIPE_MODE_SWITCH_RES_CALL;
+ result = HIPE_MODE_SWITCH_RES_CALL_BEAM;
}
/* Append the closure as the last parameter. Don't increment arity. */
- reg[arity] = p->hipe.closure;
+ reg[arity] = p->hipe.u.closure;
if (is_recursive) {
/* BEAM called native, which now calls BEAM.
@@ -549,7 +524,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
}
}
HIPE_CHECK_PCB(p);
- result = HIPE_MODE_SWITCH_RES_CALL;
+ result = HIPE_MODE_SWITCH_RES_CALL_BEAM;
p->def_arg_reg[3] = result;
return p;
}
@@ -577,7 +552,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
address = hipe_get_remote_na(mfa[0], mfa[1], arity);
if (!address)
goto do_apply_fail;
- p->hipe.ncallee = (void(*)(void)) address;
+ p->hipe.u.ncallee = (void(*)(void)) address;
result = hipe_tailcall_to_native(p, arity, reg);
goto do_return_from_native;
do_apply_fail:
@@ -585,7 +560,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
goto do_throw_to_native;
}
default:
- erl_exit(1, "hipe_mode_switch: result %#x\r\n", result);
+ erts_exit(ERTS_ERROR_EXIT, "hipe_mode_switch: result %#x\r\n", result);
}
HIPE_CHECK_PCB(p);
p->def_arg_reg[3] = result;
@@ -607,7 +582,6 @@ static unsigned hipe_next_nstack_size(unsigned size)
}
#if 0 && defined(HIPE_NSTACK_GROWS_UP)
-#define hipe_nstack_avail(p) ((p)->hipe.nstend - (p)->hipe.nsp)
void hipe_inc_nstack(Process *p)
{
Eterm *old_nstack = p->hipe.nstack;
@@ -631,7 +605,6 @@ void hipe_inc_nstack(Process *p)
#endif
#if defined(HIPE_NSTACK_GROWS_DOWN)
-#define hipe_nstack_avail(p) ((unsigned)((p)->hipe.nsp - (p)->hipe.nstack))
void hipe_inc_nstack(Process *p)
{
unsigned old_size = p->hipe.nstend - p->hipe.nstack;
@@ -663,12 +636,6 @@ void hipe_empty_nstack(Process *p)
p->hipe.nstend = NULL;
}
-static void hipe_check_nstack(Process *p, unsigned nwords)
-{
- while (hipe_nstack_avail(p) < nwords)
- hipe_inc_nstack(p);
-}
-
void hipe_set_closure_stub(ErlFunEntry *fe, unsigned num_free)
{
unsigned arity;
diff --git a/erts/emulator/hipe/hipe_mode_switch.h b/erts/emulator/hipe/hipe_mode_switch.h
index 06721e3c04..bc863a4f36 100644
--- a/erts/emulator/hipe/hipe_mode_switch.h
+++ b/erts/emulator/hipe/hipe_mode_switch.h
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -31,7 +32,7 @@
/* result codes for beam_emu <- hipe_mode_switch() return */
#define HIPE_MODE_SWITCH_RES_RETURN 4
-#define HIPE_MODE_SWITCH_RES_CALL 5
+#define HIPE_MODE_SWITCH_RES_CALL_EXPORTED 5
#define HIPE_MODE_SWITCH_RES_THROW 6
/* additional result codes for hipe_mode_switch() <- native return */
@@ -45,6 +46,8 @@
#define HIPE_MODE_SWITCH_RES_APPLY 13 /* mode_switch <- native */
+#define HIPE_MODE_SWITCH_RES_CALL_BEAM 14
+
#ifndef ASM
#include "error.h"
@@ -59,13 +62,58 @@ void hipe_empty_nstack(Process *p);
void hipe_set_closure_stub(ErlFunEntry *fe, unsigned num_free);
Eterm hipe_build_stacktrace(Process *p, struct StackTrace *s);
-void hipe_reserve_beam_trap_frame(Process*, Eterm reg[], unsigned arity);
-void hipe_unreserve_beam_trap_frame(Process*);
+ERTS_GLB_INLINE void hipe_reserve_beam_trap_frame(Process*, Eterm reg[], unsigned arity);
+ERTS_GLB_INLINE void hipe_unreserve_beam_trap_frame(Process*);
extern Uint hipe_beam_pc_return[];
extern Uint hipe_beam_pc_throw[];
extern Uint hipe_beam_pc_resume[];
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+#include "erl_gc.h"
+#include "hipe_stack.h"
+
+#if defined(__sparc__)
+#include "hipe_sparc_glue.h"
+#elif defined(__i386__)
+#include "hipe_x86_glue.h"
+#elif defined(__x86_64__)
+#include "hipe_amd64_glue.h"
+#elif defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__)
+#include "hipe_ppc_glue.h"
+#elif defined(__arm__)
+#include "hipe_arm_glue.h"
+#endif
+
+extern Eterm hipe_beam_catch_throw;
+
+ERTS_GLB_INLINE void hipe_reserve_beam_trap_frame(Process *p, Eterm reg[], unsigned arity)
+{
+ if (!hipe_bifcall_from_native_is_recursive(p))
+ return;
+
+ /* ensure that at least 2 words are available on the BEAM stack */
+ if ((p->stop - 2) < p->htop) {
+ p->fcalls -= erts_garbage_collect(p, 2, reg, arity);
+ ASSERT(!((p->stop - 2) < p->htop));
+ }
+ p->stop -= 2;
+ p->stop[0] = NIL;
+ p->stop[1] = hipe_beam_catch_throw;
+}
+
+ERTS_GLB_INLINE void hipe_unreserve_beam_trap_frame(Process *p)
+{
+ if (!hipe_bifcall_from_native_is_recursive(p))
+ return;
+
+ ASSERT(p->stop[0] == NIL && p->stop[1] == hipe_beam_catch_throw);
+ p->stop += 2;
+}
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
#endif /* ASM */
#endif /* HIPE_MODE_SWITCH_H */
diff --git a/erts/emulator/hipe/hipe_native_bif.c b/erts/emulator/hipe/hipe_native_bif.c
index 7d343dd91e..994f963ece 100644
--- a/erts/emulator/hipe/hipe_native_bif.c
+++ b/erts/emulator/hipe/hipe_native_bif.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -92,9 +93,6 @@ BIF_RETTYPE hipe_set_timeout(BIF_ALIST_1)
{
Process* p = BIF_P;
Eterm timeout_value = BIF_ARG_1;
-#if !defined(ARCH_64)
- Uint time_val;
-#endif
/* XXX: This should be converted to follow BEAM conventions,
* but that requires some compiler changes.
*
@@ -102,7 +100,8 @@ BIF_RETTYPE hipe_set_timeout(BIF_ALIST_1)
* p->def_arg_reg[0] and p->i are both defined and used.
* If a message arrives, BEAM resumes at p->i.
* If a timeout fires, BEAM resumes at p->def_arg_reg[0].
- * (See set_timer() and timeout_proc() in erl_process.c.)
+ * (See erts_set_proc_timer() and proc_timeout_common() in
+ * erl_hl_timer.c.)
*
* Here we set p->def_arg_reg[0] to hipe_beam_pc_resume.
* Assuming our caller invokes suspend immediately after
@@ -135,28 +134,21 @@ BIF_RETTYPE hipe_set_timeout(BIF_ALIST_1)
*/
if (p->flags & (F_INSLPQUEUE | F_TIMO))
return NIL; /* caller had better call nbif_suspend ASAP! */
- if (is_small(timeout_value) && signed_val(timeout_value) >= 0 &&
-#if defined(ARCH_64)
- (unsigned_val(timeout_value) >> 32) == 0
-#else
- 1
-#endif
- ) {
- set_timer(p, unsigned_val(timeout_value));
- } else if (timeout_value == am_infinity) {
+
+ if (timeout_value == am_infinity) {
/* p->flags |= F_TIMO; */ /* XXX: nbif_suspend_msg_timeout */
-#if !defined(ARCH_64)
- } else if (term_to_Uint(timeout_value, &time_val)) {
- set_timer(p, time_val);
-#endif
- } else {
+ }
+ else {
+ int tres = erts_set_proc_timer_term(p, timeout_value);
+ if (tres != 0) { /* Wrong time */
#ifdef ERTS_SMP
- if (p->hipe_smp.have_receive_locks) {
- p->hipe_smp.have_receive_locks = 0;
- erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_MSG_RECEIVE);
- }
+ if (p->hipe_smp.have_receive_locks) {
+ p->hipe_smp.have_receive_locks = 0;
+ erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_MSG_RECEIVE);
+ }
#endif
- BIF_ERROR(p, EXC_TIMEOUT_VALUE);
+ BIF_ERROR(p, EXC_TIMEOUT_VALUE);
+ }
}
return NIL; /* caller had better call nbif_suspend ASAP! */
}
@@ -170,7 +162,7 @@ void hipe_select_msg(Process *p)
msgp = PEEK_MESSAGE(p);
UNLINK_MESSAGE(p, msgp); /* decrements global 'erts_proc_tot_mem' variable */
JOIN_MESSAGE(p);
- CANCEL_TIMER(p); /* calls erl_cancel_timer() */
+ CANCEL_TIMER(p); /* calls erts_cancel_proc_timer() */
free_message(msgp);
}
@@ -179,7 +171,7 @@ void hipe_fclearerror_error(Process *p)
#if !defined(NO_FPE_SIGNALS)
erts_fp_check_init_error(&p->fp_exception);
#else
- erl_exit(ERTS_ABORT_EXIT, "Emulated FPE not cleared by HiPE");
+ erts_exit(ERTS_ABORT_EXIT, "Emulated FPE not cleared by HiPE");
#endif
}
@@ -330,8 +322,6 @@ char *hipe_bs_allocate(int len)
Binary *bptr;
bptr = erts_bin_nrml_alloc(len);
- bptr->flags = 0;
- bptr->orig_size = len;
erts_smp_atomic_init_nob(&bptr->refc, 1);
return bptr->orig_bytes;
}
@@ -341,7 +331,6 @@ Binary *hipe_bs_reallocate(Binary* oldbptr, int newsize)
Binary *bptr;
bptr = erts_bin_realloc(oldbptr, newsize);
- bptr->orig_size = newsize;
return bptr;
}
@@ -515,6 +504,18 @@ int hipe_bs_validate_unicode_retract(ErlBinMatchBuffer* mb, Eterm arg)
return 1;
}
+BIF_RETTYPE hipe_is_divisible(BIF_ALIST_2)
+{
+ /* Arguments are Eterm-sized unsigned integers */
+ Uint dividend = BIF_ARG_1;
+ Uint divisor = BIF_ARG_2;
+ if (dividend % divisor) {
+ BIF_ERROR(BIF_P, BADARG);
+ } else {
+ return NIL;
+ }
+}
+
/* This is like the loop_rec_fr BEAM instruction
*/
Eterm hipe_check_get_msg(Process *c_p)
diff --git a/erts/emulator/hipe/hipe_native_bif.h b/erts/emulator/hipe/hipe_native_bif.h
index 3f460a5a5c..55a0d3bb1b 100644
--- a/erts/emulator/hipe/hipe_native_bif.h
+++ b/erts/emulator/hipe/hipe_native_bif.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -67,6 +68,7 @@ AEXTERN(Eterm,nbif_bs_put_utf16le,(Process*,Eterm,byte*,unsigned int));
AEXTERN(Eterm,nbif_bs_get_utf16,(void));
AEXTERN(Eterm,nbif_bs_validate_unicode,(Process*,Eterm));
AEXTERN(Eterm,nbif_bs_validate_unicode_retract,(void));
+AEXTERN(void,nbif_is_divisible,(Process*,Uint,Uint));
AEXTERN(void,nbif_select_msg,(Process*));
AEXTERN(Eterm,nbif_cmp_2,(void));
@@ -92,12 +94,16 @@ BIF_RETTYPE hipe_bs_put_utf16le(BIF_ALIST_3);
BIF_RETTYPE hipe_bs_validate_unicode(BIF_ALIST_1);
struct erl_bin_match_buffer;
int hipe_bs_validate_unicode_retract(struct erl_bin_match_buffer*, Eterm);
+BIF_RETTYPE hipe_is_divisible(BIF_ALIST_2);
#ifdef NO_FPE_SIGNALS
AEXTERN(void,nbif_emulate_fpe,(Process*));
void hipe_emulate_fpe(Process*);
#endif
+AEXTERN(void,nbif_emasculate_binary,(Eterm));
+void hipe_emasculate_binary(Eterm);
+
/*
* Stuff that is different in SMP and non-SMP.
*/
diff --git a/erts/emulator/hipe/hipe_ops.tab b/erts/emulator/hipe/hipe_ops.tab
index 50c3a4ae2f..d021c72ac9 100644
--- a/erts/emulator/hipe/hipe_ops.tab
+++ b/erts/emulator/hipe/hipe_ops.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_perfctr.c b/erts/emulator/hipe/hipe_perfctr.c
deleted file mode 100644
index 371b3fb097..0000000000
--- a/erts/emulator/hipe/hipe_perfctr.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2011. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "sys.h"
-#include "error.h"
-#include "global.h"
-#include "bif.h"
-#include "big.h"
-#include "erl_binary.h"
-#include "hipe_perfctr.h"
-#include "libperfctr.h"
-
-static struct vperfctr *vperfctr;
-static unsigned int have_rdtsc;
-static double tsc_to_ms;
-static unsigned int tsc_on; /* control calls must set tsc_on if have_rdtsc is true */
-static unsigned int nractrs;
-static unsigned int users;
-#define USER_BIFS (1<<0)
-#define USER_HRVTIME (1<<1)
-
-static int hipe_perfctr_open(unsigned int user)
-{
- struct perfctr_info info;
-
- if (!vperfctr) {
- vperfctr = vperfctr_open();
- if (!vperfctr)
- return -1;
- if (vperfctr_info(vperfctr, &info) >= 0) {
- tsc_to_ms = (double)(info.tsc_to_cpu_mult ? : 1) / (double)info.cpu_khz;
- have_rdtsc = (info.cpu_features & PERFCTR_FEATURE_RDTSC) ? 1 : 0;
- }
- tsc_on = 0;
- nractrs = 0;
- }
- users |= user;
- return 0;
-}
-
-static void hipe_perfctr_reset(void)
-{
- struct vperfctr_control control;
-
- memset(&control, 0, sizeof control);
- if (have_rdtsc)
- control.cpu_control.tsc_on = 1;
- nractrs = 0;
- if (vperfctr_control(vperfctr, &control) >= 0)
- tsc_on = 1;
-}
-
-static void hipe_perfctr_close(unsigned int user)
-{
- if (!vperfctr)
- return;
- users &= ~user;
- switch (users) {
- case 0:
- vperfctr_unlink(vperfctr);
- vperfctr_close(vperfctr);
- vperfctr = NULL;
- tsc_on = 0;
- nractrs = 0;
- break;
- case USER_HRVTIME:
- hipe_perfctr_reset();
- }
-}
-
-/*
- * Interface for HiPE's hrvtime code.
- */
-
-int hipe_perfctr_hrvtime_open(void)
-{
- if (hipe_perfctr_open(USER_HRVTIME) < 0)
- return -1;
- if (have_rdtsc) {
- if (!tsc_on)
- hipe_perfctr_reset(); /* note: updates tsc_on */
- if (tsc_on)
- return 0;
- }
- hipe_perfctr_hrvtime_close();
- return -1;
-}
-
-void hipe_perfctr_hrvtime_close(void)
-{
- hipe_perfctr_close(USER_HRVTIME);
-}
-
-double hipe_perfctr_hrvtime_get(void)
-{
- return (double)vperfctr_read_tsc(vperfctr) * tsc_to_ms;
-}
-
-/*
- * BIF interface for user-programmable performance counters.
- */
-
-BIF_RETTYPE hipe_bifs_vperfctr_open_0(BIF_ALIST_0)
-{
- if (hipe_perfctr_open(USER_BIFS) < 0)
- BIF_RET(am_false); /* arity 0 BIFs can't fail :-( */
- BIF_RET(am_true);
-}
-
-BIF_RETTYPE hipe_bifs_vperfctr_close_0(BIF_ALIST_0)
-{
- hipe_perfctr_close(USER_BIFS);
- BIF_RET(NIL);
-}
-
-static Eterm ull_to_integer(unsigned long long x, Process *p)
-{
- unsigned long long tmpx;
- unsigned int ds, i;
- size_t sz;
- Eterm *hp;
- ErtsDigit *xp;
-
- if (x <= (unsigned long long)MAX_SMALL)
- return make_small(x);
-
- /* Calculate number of digits. */
- ds = 0;
- tmpx = x;
- do {
- ++ds;
- tmpx = (tmpx >> (D_EXP / 2)) >> (D_EXP / 2);
- } while (tmpx != 0);
-
- sz = BIG_NEED_SIZE(ds); /* number of words including arity */
- hp = HAlloc(p, sz);
- *hp = make_pos_bignum_header(sz-1);
-
- xp = (ErtsDigit*)(hp+1);
- i = 0;
- do {
- xp[i++] = (ErtsDigit)x;
- x = (x >> (D_EXP / 2)) >> (D_EXP / 2);
- } while (i < ds);
- while (i & (BIG_DIGITS_PER_WORD-1))
- xp[i++] = 0;
-
- return make_big(hp);
-}
-
-BIF_RETTYPE hipe_bifs_vperfctr_info_0(BIF_ALIST_0)
-{
- struct perfctr_info info;
-
- if (!vperfctr || vperfctr_info(vperfctr, &info) < 0)
- BIF_RET(am_false); /* arity 0 BIFs can't fail :-( */
- BIF_RET(new_binary(BIF_P, (void*)&info, sizeof info));
-}
-
-BIF_RETTYPE hipe_bifs_vperfctr_read_tsc_0(BIF_ALIST_0)
-{
- unsigned long long val;
-
- if (!vperfctr || !tsc_on)
- BIF_RET(am_false); /* arity 0 BIFs can't fail :-( */
- val = vperfctr_read_tsc(vperfctr);
- BIF_RET(ull_to_integer(val, BIF_P));
-}
-
-BIF_RETTYPE hipe_bifs_vperfctr_read_pmc_1(BIF_ALIST_1)
-{
- Uint pmc;
- unsigned long long val;
-
- if (!vperfctr ||
- is_not_small(BIF_ARG_1) ||
- (pmc = unsigned_val(BIF_ARG_1), pmc >= nractrs))
- BIF_RET(am_false); /* for consistency with the arity 0 BIFs */
- val = vperfctr_read_pmc(vperfctr, pmc);
- BIF_RET(ull_to_integer(val, BIF_P));
-}
-
-BIF_RETTYPE hipe_bifs_vperfctr_control_1(BIF_ALIST_1)
-{
- void *bytes;
- struct vperfctr_control control;
- Uint bitoffs;
- Uint bitsize;
-
- if (!vperfctr)
- BIF_ERROR(BIF_P, BADARG);
- if (is_not_binary(BIF_ARG_1))
- BIF_ERROR(BIF_P, BADARG);
- if (binary_size(BIF_ARG_1) != sizeof control)
- BIF_ERROR(BIF_P, BADARG);
- ERTS_GET_BINARY_BYTES(BIF_ARG_1, bytes, bitoffs, bitsize);
- ASSERT(bitoffs == 0);
- ASSERT(bitsize == 0);
- memcpy(&control, bytes, sizeof control);
- if (have_rdtsc)
- control.cpu_control.tsc_on = 1;
- if (vperfctr_control(vperfctr, &control) < 0) {
- hipe_perfctr_reset();
- BIF_ERROR(BIF_P, BADARG);
- }
- tsc_on = control.cpu_control.tsc_on;
- nractrs = control.cpu_control.nractrs;
- BIF_RET(NIL);
-}
diff --git a/erts/emulator/hipe/hipe_perfctr.h b/erts/emulator/hipe/hipe_perfctr.h
deleted file mode 100644
index 8fbf9ecf35..0000000000
--- a/erts/emulator/hipe/hipe_perfctr.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2011. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
- */
-
-
-extern int hipe_perfctr_hrvtime_open(void);
-extern void hipe_perfctr_hrvtime_close(void);
-extern double hipe_perfctr_hrvtime_get(void);
diff --git a/erts/emulator/hipe/hipe_perfctr.tab b/erts/emulator/hipe/hipe_perfctr.tab
deleted file mode 100644
index eaecea4651..0000000000
--- a/erts/emulator/hipe/hipe_perfctr.tab
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2011. All Rights Reserved.
-#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# %CopyrightEnd%
-#
-
-bif hipe_bifs:vperfctr_open/0
-bif hipe_bifs:vperfctr_close/0
-bif hipe_bifs:vperfctr_info/0
-bif hipe_bifs:vperfctr_read_tsc/0
-bif hipe_bifs:vperfctr_read_pmc/1
-bif hipe_bifs:vperfctr_control/1
diff --git a/erts/emulator/hipe/hipe_ppc.c b/erts/emulator/hipe/hipe_ppc.c
index 2d8fd61e1e..3f86de626d 100644
--- a/erts/emulator/hipe/hipe_ppc.c
+++ b/erts/emulator/hipe/hipe_ppc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -285,7 +286,7 @@ int hipe_patch_insn(void *address, Uint64 value, Eterm type)
}
}
-void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
+void *hipe_make_native_stub(void *callee_exp, unsigned int beamArity)
{
unsigned int *code;
@@ -293,17 +294,19 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
abort();
code = alloc_stub(7);
+ if (!code)
+ return NULL;
- /* addis r12,0,beamAddress@highest */
- code[0] = 0x3d800000 | (((unsigned long)beamAddress >> 48) & 0xffff);
- /* ori r12,r12,beamAddress@higher */
- code[1] = 0x618c0000 | (((unsigned long)beamAddress >> 32) & 0xffff);
+ /* addis r12,0,callee_exp@highest */
+ code[0] = 0x3d800000 | (((unsigned long)callee_exp >> 48) & 0xffff);
+ /* ori r12,r12,callee_exp@higher */
+ code[1] = 0x618c0000 | (((unsigned long)callee_exp >> 32) & 0xffff);
/* sldi r12,r12,32 (rldicr r12,r12,32,31) */
code[2] = 0x798c07c6;
- /* oris r12,r12,beamAddress@h */
- code[3] = 0x658c0000 | (((unsigned long)beamAddress >> 16) & 0xffff);
- /* ori r12,r12,beamAddress@l */
- code[4] = 0x618c0000 | ((unsigned long)beamAddress & 0xffff);
+ /* oris r12,r12,callee_exp@h */
+ code[3] = 0x658c0000 | (((unsigned long)callee_exp >> 16) & 0xffff);
+ /* ori r12,r12,callee_exp@l */
+ code[4] = 0x618c0000 | ((unsigned long)callee_exp & 0xffff);
/* addi r0,0,beamArity */
code[5] = 0x38000000 | (beamArity & 0x7FFF);
/* ba nbif_callemu */
@@ -355,18 +358,16 @@ int hipe_patch_insn(void *address, Uint32 value, Eterm type)
return 0;
}
-/* called from hipe_bif0.c:hipe_bifs_make_native_stub_2()
- and hipe_bif0.c:hipe_make_stub() */
-void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
+void *hipe_make_native_stub(void *callee_exp, unsigned int beamArity)
{
unsigned int *code;
/*
* Native code calls BEAM via a stub looking as follows:
*
- * addi r12,0,beamAddress@l
+ * addi r12,0,callee_exp@l
* addi r0,0,beamArity
- * addis r12,r12,beamAddress@ha
+ * addis r12,r12,callee_exp@ha
* ba nbif_callemu
*
* I'm using r0 and r12 since the standard SVR4 ABI allows
@@ -383,13 +384,15 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
abort();
code = alloc_stub(4);
+ if (!code)
+ return NULL;
- /* addi r12,0,beamAddress@l */
- code[0] = 0x39800000 | ((unsigned long)beamAddress & 0xFFFF);
+ /* addi r12,0,callee_exp@l */
+ code[0] = 0x39800000 | ((unsigned long)callee_exp & 0xFFFF);
/* addi r0,0,beamArity */
code[1] = 0x38000000 | (beamArity & 0x7FFF);
- /* addis r12,r12,beamAddress@ha */
- code[2] = 0x3D8C0000 | at_ha((unsigned long)beamAddress);
+ /* addis r12,r12,callee_exp@ha */
+ code[2] = 0x3D8C0000 | at_ha((unsigned long)callee_exp);
/* ba nbif_callemu */
code[3] = 0x48000002 | (unsigned long)&nbif_callemu;
diff --git a/erts/emulator/hipe/hipe_ppc.h b/erts/emulator/hipe/hipe_ppc.h
index 66000c1846..777c9384d5 100644
--- a/erts/emulator/hipe/hipe_ppc.h
+++ b/erts/emulator/hipe/hipe_ppc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -64,10 +65,6 @@ AEXTERN(void,hipe_ppc_inc_stack,(void));
extern void hipe_ppc_inc_stack(void); /* we don't have the AEXTERN() fallback :-( */
#endif
-/* for hipe_bifs_enter_code_2 */
-extern void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p);
-#define HIPE_ALLOC_CODE(n,c,t,p) hipe_alloc_code((n),(c),(t),(p))
-
#if !defined(__powerpc64__)
extern const unsigned int fconv_constant[];
#endif
diff --git a/erts/emulator/hipe/hipe_ppc.tab b/erts/emulator/hipe/hipe_ppc.tab
index 38b7f46d3a..5bf2320cbe 100644
--- a/erts/emulator/hipe/hipe_ppc.tab
+++ b/erts/emulator/hipe/hipe_ppc.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_ppc64.tab b/erts/emulator/hipe/hipe_ppc64.tab
index 0a390a3bb8..301a9752f7 100644
--- a/erts/emulator/hipe/hipe_ppc64.tab
+++ b/erts/emulator/hipe/hipe_ppc64.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/hipe/hipe_ppc_asm.m4 b/erts/emulator/hipe/hipe_ppc_asm.m4
index 343402f9f0..ea74923d1f 100644
--- a/erts/emulator/hipe/hipe_ppc_asm.m4
+++ b/erts/emulator/hipe/hipe_ppc_asm.m4
@@ -4,16 +4,17 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -23,6 +24,22 @@ changecom(`/*', `*/')dnl
#define HIPE_PPC_ASM_H'
/*
+ * Tunables.
+ */
+define(LEAF_WORDS,16)dnl number of stack words for leaf functions
+define(NR_ARG_REGS,4)dnl admissible values are 0 to 6, inclusive
+
+`#define PPC_LEAF_WORDS 'LEAF_WORDS
+`#define PPC_NR_ARG_REGS 'NR_ARG_REGS
+`#define NR_ARG_REGS 'NR_ARG_REGS
+
+
+`#ifdef ASM'
+/*
+ * Only assembler stuff from here on (when included from *.S)
+ */
+
+/*
* Handle 32 vs 64-bit.
*/
ifelse(ARCH,ppc64,`
@@ -53,13 +70,6 @@ define(WSIZE,4)dnl
`#define STORE 'STORE
`#define CMPI 'CMPI
-/*
- * Tunables.
- */
-define(LEAF_WORDS,16)dnl number of stack words for leaf functions
-define(NR_ARG_REGS,4)dnl admissible values are 0 to 6, inclusive
-
-`#define PPC_LEAF_WORDS 'LEAF_WORDS
/*
* Workarounds for Darwin.
@@ -193,8 +203,6 @@ NAME: \
/*
* Argument (parameter) registers.
*/
-`#define PPC_NR_ARG_REGS 'NR_ARG_REGS
-`#define NR_ARG_REGS 'NR_ARG_REGS
define(defarg,`define(ARG$1,`$2')dnl
#`define ARG'$1 $2'
@@ -273,6 +281,10 @@ define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_REG_ARG($1,$3)',`NBIF_ST
`/* #define NBIF_ARG_3_0 'NBIF_ARG(r3,3,0)` */'
`/* #define NBIF_ARG_3_1 'NBIF_ARG(r3,3,1)` */'
`/* #define NBIF_ARG_3_2 'NBIF_ARG(r3,3,2)` */'
+`/* #define NBIF_ARG_4_0 'NBIF_ARG(r3,4,0)` */'
+`/* #define NBIF_ARG_4_1 'NBIF_ARG(r3,4,1)` */'
+`/* #define NBIF_ARG_4_2 'NBIF_ARG(r3,4,2)` */'
+`/* #define NBIF_ARG_4_3 'NBIF_ARG(r3,4,3)` */'
`/* #define NBIF_ARG_5_0 'NBIF_ARG(r3,5,0)` */'
`/* #define NBIF_ARG_5_1 'NBIF_ARG(r3,5,1)` */'
`/* #define NBIF_ARG_5_2 'NBIF_ARG(r3,5,2)` */'
@@ -294,6 +306,7 @@ define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl
`/* #define NBIF_RET_1 'NBIF_RET(1)` */'
`/* #define NBIF_RET_2 'NBIF_RET(2)` */'
`/* #define NBIF_RET_3 'NBIF_RET(3)` */'
+`/* #define NBIF_RET_4 'NBIF_RET(4)` */'
`/* #define NBIF_RET_5 'NBIF_RET(5)` */'
dnl
@@ -309,4 +322,6 @@ define(QUICK_CALL_RET,`NBIF_POP_N(eval(RET_POP($2)))b $1')dnl
`/* #define QUICK_CALL_RET_F_3 'QUICK_CALL_RET(F,3)` */'
`/* #define QUICK_CALL_RET_F_5 'QUICK_CALL_RET(F,5)` */'
+`#endif /* ASM */'
+
`#endif /* HIPE_PPC_ASM_H */'
diff --git a/erts/emulator/hipe/hipe_ppc_bifs.m4 b/erts/emulator/hipe/hipe_ppc_bifs.m4
index 7cc2b5c7b6..28518827ec 100644
--- a/erts/emulator/hipe/hipe_ppc_bifs.m4
+++ b/erts/emulator/hipe/hipe_ppc_bifs.m4
@@ -4,21 +4,23 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
+#`define ASM'
include(`hipe/hipe_ppc_asm.m4')
#`include' "config.h"
#`include' "hipe_literals.h"
@@ -45,9 +47,10 @@ define(HANDLE_GOT_MBUF,`
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 0-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
@@ -143,6 +146,41 @@ ASYM($1):
TYPE_FUNCTION(ASYM($1))
#endif')
+define(standard_bif_interface_4,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* Set up C argument registers. */
+ mr r3, P
+ NBIF_ARG(r4,4,0)
+ NBIF_ARG(r5,4,1)
+ NBIF_ARG(r6,4,2)
+ NBIF_ARG(r7,4,3)
+
+ /* Save caller-save registers and call the C function. */
+ SAVE_CONTEXT_BIF
+ STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
+ STORE r5, P_ARG1(r3)
+ STORE r6, P_ARG2(r3)
+ STORE r7, P_ARG3(r3)
+ addi r4, r3, P_ARG0
+ CALL_BIF($2)
+ TEST_GOT_MBUF
+
+ /* Restore registers. Check for exception. */
+ CMPI r3, THE_NON_VALUE
+ RESTORE_CONTEXT_BIF
+ beq- 1f
+ NBIF_RET(4)
+1: /* workaround for bc:s small offset operand */
+ b CSYM(nbif_4_simple_exception)
+ HANDLE_GOT_MBUF(4)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
diff --git a/erts/emulator/hipe/hipe_ppc_gc.h b/erts/emulator/hipe/hipe_ppc_gc.h
index 823ba0ad06..0854d9e950 100644
--- a/erts/emulator/hipe/hipe_ppc_gc.h
+++ b/erts/emulator/hipe/hipe_ppc_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_ppc_glue.S b/erts/emulator/hipe/hipe_ppc_glue.S
index 6f0217c738..6e2022603c 100644
--- a/erts/emulator/hipe/hipe_ppc_glue.S
+++ b/erts/emulator/hipe/hipe_ppc_glue.S
@@ -3,24 +3,24 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
-
+#define ASM
#include "hipe_ppc_asm.h"
#include "hipe_literals.h"
-#define ASM
#include "hipe_mode_switch.h"
.text
@@ -296,7 +296,7 @@ CSYM(hipe_ppc_throw_to_native):
* which should look as follows:
*
* stub for f/N:
- * <set r12 to f's BEAM code address>
+ * <set r12 to f's export entry address>
* <set r0 to N>
* b nbif_callemu
*
@@ -312,10 +312,10 @@ CSYM(hipe_ppc_throw_to_native):
*/
GLOBAL(ASYM(nbif_callemu))
ASYM(nbif_callemu):
- STORE r12, P_BEAM_IP(P)
+ STORE r12, P_CALLEE_EXP(P)
STORE r0, P_ARITY(P)
STORE_ARG_REGS
- li r3, HIPE_MODE_SWITCH_RES_CALL
+ li r3, HIPE_MODE_SWITCH_RES_CALL_EXPORTED
b .suspend_exit
/*
@@ -463,10 +463,12 @@ ASYM(nbif_fail):
OPD(nbif_1_gc_after_bif)
OPD(nbif_2_gc_after_bif)
OPD(nbif_3_gc_after_bif)
+ OPD(nbif_4_gc_after_bif)
GLOBAL(CSYM(nbif_0_gc_after_bif))
GLOBAL(CSYM(nbif_1_gc_after_bif))
GLOBAL(CSYM(nbif_2_gc_after_bif))
GLOBAL(CSYM(nbif_3_gc_after_bif))
+ GLOBAL(CSYM(nbif_4_gc_after_bif))
CSYM(nbif_0_gc_after_bif):
li r4, 0
b .gc_after_bif
@@ -478,6 +480,9 @@ CSYM(nbif_2_gc_after_bif):
b .gc_after_bif
CSYM(nbif_3_gc_after_bif):
li r4, 3
+ b .gc_after_bif
+CSYM(nbif_4_gc_after_bif):
+ li r4, 4
/*FALLTHROUGH*/
.gc_after_bif:
stw r4, P_NARITY(P) /* Note: narity is a 32-bit field */
@@ -506,20 +511,29 @@ CSYM(nbif_3_gc_after_bif):
CSYM(nbif_0_simple_exception):
li r4, 0
b .nbif_simple_exception
+
OPD(nbif_1_simple_exception)
GLOBAL(CSYM(nbif_1_simple_exception))
CSYM(nbif_1_simple_exception):
li r4, 1
b .nbif_simple_exception
+
OPD(nbif_2_simple_exception)
GLOBAL(CSYM(nbif_2_simple_exception))
CSYM(nbif_2_simple_exception):
li r4, 2
b .nbif_simple_exception
+
OPD(nbif_3_simple_exception)
GLOBAL(CSYM(nbif_3_simple_exception))
CSYM(nbif_3_simple_exception):
li r4, 3
+ b .nbif_simple_exception
+
+ OPD(nbif_4_simple_exception)
+ GLOBAL(CSYM(nbif_4_simple_exception))
+CSYM(nbif_4_simple_exception):
+ li r4, 4
/*FALLTHROUGH*/
.nbif_simple_exception:
LOAD r3, P_FREASON(P)
diff --git a/erts/emulator/hipe/hipe_ppc_glue.h b/erts/emulator/hipe/hipe_ppc_glue.h
index f9c4460e60..93ca39fcb3 100644
--- a/erts/emulator/hipe/hipe_ppc_glue.h
+++ b/erts/emulator/hipe/hipe_ppc_glue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_ppc_primops.h b/erts/emulator/hipe/hipe_ppc_primops.h
index 7dba0afc88..ce3dda9eb3 100644
--- a/erts/emulator/hipe/hipe_ppc_primops.h
+++ b/erts/emulator/hipe/hipe_ppc_primops.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_primops.h b/erts/emulator/hipe/hipe_primops.h
index 52b4681cfe..0bec677574 100644
--- a/erts/emulator/hipe/hipe_primops.h
+++ b/erts/emulator/hipe/hipe_primops.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -67,6 +68,8 @@ PRIMOP_LIST(am_bs_get_utf16, &nbif_bs_get_utf16)
PRIMOP_LIST(am_bs_validate_unicode, &nbif_bs_validate_unicode)
PRIMOP_LIST(am_bs_validate_unicode_retract, &nbif_bs_validate_unicode_retract)
+PRIMOP_LIST(am_is_divisible, &nbif_is_divisible)
+
PRIMOP_LIST(am_cmp_2, &nbif_cmp_2)
PRIMOP_LIST(am_op_exact_eqeq_2, &nbif_eq_2)
@@ -80,6 +83,7 @@ PRIMOP_LIST(am_fclearerror_error, &nbif_fclearerror_error)
#ifdef NO_FPE_SIGNALS
PRIMOP_LIST(am_emulate_fpe, &nbif_emulate_fpe)
#endif
+PRIMOP_LIST(am_emasculate_binary, &nbif_emasculate_binary)
PRIMOP_LIST(am_debug_native_called, &nbif_hipe_bifs_debug_native_called)
#if defined(__sparc__)
diff --git a/erts/emulator/hipe/hipe_process.h b/erts/emulator/hipe/hipe_process.h
index 4ee99d78a2..60d09ea1c9 100644
--- a/erts/emulator/hipe/hipe_process.h
+++ b/erts/emulator/hipe/hipe_process.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -23,14 +24,17 @@
#define HIPE_PROCESS_H
#include "erl_alloc.h"
+#include "export.h"
struct hipe_process_state {
Eterm *nsp; /* Native stack pointer. */
Eterm *nstack; /* Native stack block start. */
Eterm *nstend; /* Native stack block end (start+size). */
- /* XXX: ncallee and closure could share space in a union */
- void (*ncallee)(void); /* Native code callee (label) to invoke. */
- Eterm closure; /* Used to pass a closure from native code. */
+ union {
+ void (*ncallee)(void); /* Native code callee (label) to invoke. */
+ Eterm closure; /* Used to pass a closure from native code. */
+ Export* callee_exp; /* Used to pass export entry from native code */
+ }u;
Eterm *nstgraylim; /* Gray/white stack boundary. */
Eterm *nstblacklim; /* Black/gray stack boundary. Must exist if
graylim exists. Ignored if no graylim. */
diff --git a/erts/emulator/hipe/hipe_risc_gc.h b/erts/emulator/hipe/hipe_risc_gc.h
index 947eb5956b..770ec93459 100644
--- a/erts/emulator/hipe/hipe_risc_gc.h
+++ b/erts/emulator/hipe/hipe_risc_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_risc_glue.h b/erts/emulator/hipe/hipe_risc_glue.h
index dbb7086dae..51db7eac01 100644
--- a/erts/emulator/hipe/hipe_risc_glue.h
+++ b/erts/emulator/hipe/hipe_risc_glue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_risc_stack.c b/erts/emulator/hipe/hipe_risc_stack.c
index 1183856c7e..fd04421381 100644
--- a/erts/emulator/hipe/hipe_risc_stack.c
+++ b/erts/emulator/hipe/hipe_risc_stack.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -226,7 +227,7 @@ void (*hipe_handle_stack_trap(Process *p))(void)
* The native stack MUST contain a stack frame as it appears on
* entry to a function (actuals, caller's frame, caller's return address).
* p->hipe.narity MUST contain the arity (number of actuals).
- * On exit, p->hipe.ncallee is set to the handler's PC and p->hipe.nsp
+ * On exit, p->hipe.u.ncallee is set to the handler's PC and p->hipe.nsp
* is set to its SP (low address of its stack frame).
*/
void hipe_find_handler(Process *p)
@@ -254,7 +255,7 @@ void hipe_find_handler(Process *p)
if ((exnra = sdesc_exnra(sdesc)) != 0 &&
(p->catches >= 0 ||
exnra == (unsigned long)&nbif_fail)) {
- p->hipe.ncallee = (void(*)(void)) exnra;
+ p->hipe.u.ncallee = (void(*)(void)) exnra;
p->hipe.nsp = nsp;
p->hipe.narity = 0;
/* update the gray/white boundary if we threw past it */
diff --git a/erts/emulator/hipe/hipe_signal.h b/erts/emulator/hipe/hipe_signal.h
index 4eacf52b5d..b2f461797d 100644
--- a/erts/emulator/hipe/hipe_signal.h
+++ b/erts/emulator/hipe/hipe_signal.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_sparc.c b/erts/emulator/hipe/hipe_sparc.c
index 49d4da7bab..bd95bc5d98 100644
--- a/erts/emulator/hipe/hipe_sparc.c
+++ b/erts/emulator/hipe/hipe_sparc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -130,7 +131,7 @@ static void atexit_alloc_code_stats(void)
#define ALLOC_CODE_STATS(X) do{}while(0)
#endif
-static void morecore(unsigned int alloc_bytes)
+static int morecore(unsigned int alloc_bytes)
{
unsigned int map_bytes;
char *map_hint, *map_start;
@@ -158,10 +159,9 @@ static void morecore(unsigned int alloc_bytes)
#endif
,
-1, 0);
- if (map_start == MAP_FAILED) {
- perror("mmap");
- abort();
- }
+ if (map_start == MAP_FAILED)
+ return -1;
+
ALLOC_CODE_STATS(total_mapped += map_bytes);
/* Merge adjacent mappings, so the trailing portion of the previous
@@ -177,6 +177,8 @@ static void morecore(unsigned int alloc_bytes)
}
ALLOC_CODE_STATS(atexit_alloc_code_stats());
+
+ return 0;
}
static void *alloc_code(unsigned int alloc_bytes)
@@ -186,8 +188,8 @@ static void *alloc_code(unsigned int alloc_bytes)
/* Align function entries. */
alloc_bytes = (alloc_bytes + 3) & ~3;
- if (code_bytes < alloc_bytes)
- morecore(alloc_bytes);
+ if (code_bytes < alloc_bytes && morecore(alloc_bytes) != 0)
+ return NULL;
ALLOC_CODE_STATS(++nr_allocs);
ALLOC_CODE_STATS(total_alloc += alloc_bytes);
res = code_next;
@@ -204,22 +206,22 @@ void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *
return alloc_code(nrbytes);
}
-/* called from hipe_bif0.c:hipe_bifs_make_native_stub_2()
- and hipe_bif0.c:hipe_make_stub() */
-void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
+void *hipe_make_native_stub(void *callee_exp, unsigned int beamArity)
{
unsigned int *code;
unsigned int callEmuOffset;
int i;
code = alloc_code(5*sizeof(int));
+ if (!code)
+ return NULL;
/* sethi %hi(Address), %i4 */
- code[0] = 0x39000000 | (((unsigned int)beamAddress >> 10) & 0x3FFFFF);
+ code[0] = 0x39000000 | (((unsigned int)callee_exp >> 10) & 0x3FFFFF);
/* or %g0, %o7, %i3 ! mov %o7, %i3 */
code[1] = 0xB610000F;
/* or %i4, %lo(Address), %i4 */
- code[2] = 0xB8172000 | ((unsigned int)beamAddress & 0x3FF);
+ code[2] = 0xB8172000 | ((unsigned int)callee_exp & 0x3FF);
/* call callemu */
callEmuOffset = (char*)nbif_callemu - (char*)&code[3];
code[3] = (1 << 30) | ((callEmuOffset >> 2) & 0x3FFFFFFF);
diff --git a/erts/emulator/hipe/hipe_sparc.h b/erts/emulator/hipe/hipe_sparc.h
index 1134b86004..0b74b2db26 100644
--- a/erts/emulator/hipe/hipe_sparc.h
+++ b/erts/emulator/hipe/hipe_sparc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -47,8 +48,4 @@ static __inline__ int hipe_word32_address_ok(void *address)
extern void hipe_sparc_inc_stack(void);
-/* for hipe_bifs_enter_code_2 */
-extern void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p);
-#define HIPE_ALLOC_CODE(n,c,t,p) hipe_alloc_code((n),(c),(t),(p))
-
#endif /* HIPE_SPARC_H */
diff --git a/erts/emulator/hipe/hipe_sparc.tab b/erts/emulator/hipe/hipe_sparc.tab
index c620c73c67..2f528c0607 100644
--- a/erts/emulator/hipe/hipe_sparc.tab
+++ b/erts/emulator/hipe/hipe_sparc.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_sparc_asm.m4 b/erts/emulator/hipe/hipe_sparc_asm.m4
index 227d10ed80..227a1658b4 100644
--- a/erts/emulator/hipe/hipe_sparc_asm.m4
+++ b/erts/emulator/hipe/hipe_sparc_asm.m4
@@ -4,16 +4,17 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2007-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -29,6 +30,14 @@ define(LEAF_WORDS,16)dnl number of stack words for leaf functions
define(NR_ARG_REGS,4)dnl admissible values are 0 to 6, inclusive
`#define SPARC_LEAF_WORDS 'LEAF_WORDS
+`#define SPARC_NR_ARG_REGS 'NR_ARG_REGS
+`#define NR_ARG_REGS 'NR_ARG_REGS
+
+
+`#ifdef ASM'
+/*
+ * Only assembler stuff from here on (when included from *.S)
+ */
/*
* Reserved registers.
@@ -80,9 +89,6 @@ define(NR_ARG_REGS,4)dnl admissible values are 0 to 6, inclusive
/*
* Argument (parameter) registers.
*/
-`#define SPARC_NR_ARG_REGS 'NR_ARG_REGS
-`#define NR_ARG_REGS 'NR_ARG_REGS
-
define(defarg,`define(ARG$1,`$2')dnl
#`define ARG'$1 $2'
)dnl
@@ -171,6 +177,10 @@ define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_REG_ARG($1,$3)',`NBIF_ST
`/* #define NBIF_ARG_3_0 'NBIF_ARG(r1,3,0)` */'
`/* #define NBIF_ARG_3_1 'NBIF_ARG(r2,3,1)` */'
`/* #define NBIF_ARG_3_2 'NBIF_ARG(r3,3,2)` */'
+`/* #define NBIF_ARG_4_0 'NBIF_ARG(r1,4,0)` */'
+`/* #define NBIF_ARG_4_1 'NBIF_ARG(r2,4,1)` */'
+`/* #define NBIF_ARG_4_2 'NBIF_ARG(r3,4,2)` */'
+`/* #define NBIF_ARG_4_3 'NBIF_ARG(r3,4,3)` */'
`/* #define NBIF_ARG_5_0 'NBIF_ARG(r1,5,0)` */'
`/* #define NBIF_ARG_5_1 'NBIF_ARG(r2,5,1)` */'
`/* #define NBIF_ARG_5_2 'NBIF_ARG(r3,5,2)` */'
@@ -195,6 +205,7 @@ define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl
`/* #define NBIF_RET_1 'NBIF_RET(1)` */'
`/* #define NBIF_RET_2 'NBIF_RET(2)` */'
`/* #define NBIF_RET_3 'NBIF_RET(3)` */'
+`/* #define NBIF_RET_4 'NBIF_RET(4)` */'
`/* #define NBIF_RET_5 'NBIF_RET(5)` */'
dnl
@@ -210,4 +221,6 @@ define(QUICK_CALL_RET,`ba $1; NBIF_POP_N(eval(RET_POP($2)))')dnl
`/* #define QUICK_CALL_RET_F_3 'QUICK_CALL_RET(F,3)` */'
`/* #define QUICK_CALL_RET_F_5 'QUICK_CALL_RET(F,5)` */'
+`#endif /* ASM */'
+
`#endif /* HIPE_SPARC_ASM_H */'
diff --git a/erts/emulator/hipe/hipe_sparc_bifs.m4 b/erts/emulator/hipe/hipe_sparc_bifs.m4
index ca5af45d58..a7bbe5b2cc 100644
--- a/erts/emulator/hipe/hipe_sparc_bifs.m4
+++ b/erts/emulator/hipe/hipe_sparc_bifs.m4
@@ -4,21 +4,23 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
+#`define ASM'
include(`hipe/hipe_sparc_asm.m4')
#`include' "config.h"
#`include' "hipe_literals.h"
@@ -53,9 +55,10 @@ define(HANDLE_GOT_MBUF,`
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 0-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
@@ -145,6 +148,39 @@ $1:
.type $1, #function
#endif')
+define(standard_bif_interface_4,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ .global $1
+$1:
+ /* Set up C argument registers. */
+ mov P, %o0
+ NBIF_ARG(%o1,4,0)
+ NBIF_ARG(%o2,4,1)
+ NBIF_ARG(%o3,4,2)
+ NBIF_ARG(%o4,4,3)
+
+ /* Save caller-save registers and call the C function. */
+ SAVE_CONTEXT_BIF
+ st %o1, [%o0+P_ARG0] ! Store BIF__ARGS in def_arg_reg
+ st %o2, [%o0+P_ARG1]
+ st %o3, [%o0+P_ARG2]
+ st %o4, [%o0+P_ARG3]
+ add %o0, P_ARG0, %o1
+ CALL_BIF($2)
+ nop
+ TEST_GOT_MBUF
+
+ /* Restore registers. Check for exception. */
+ TEST_GOT_EXN(4)
+ RESTORE_CONTEXT_BIF
+ NBIF_RET(4)
+ HANDLE_GOT_MBUF(4)
+ .size $1, .-$1
+ .type $1, #function
+#endif')
+
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
diff --git a/erts/emulator/hipe/hipe_sparc_gc.h b/erts/emulator/hipe/hipe_sparc_gc.h
index b870ddd59e..99e55df1ce 100644
--- a/erts/emulator/hipe/hipe_sparc_gc.h
+++ b/erts/emulator/hipe/hipe_sparc_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_sparc_glue.S b/erts/emulator/hipe/hipe_sparc_glue.S
index 44bdf1bc7e..7e47ffb52f 100644
--- a/erts/emulator/hipe/hipe_sparc_glue.S
+++ b/erts/emulator/hipe/hipe_sparc_glue.S
@@ -4,24 +4,24 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
-
+#define ASM
#include "hipe_sparc_asm.h"
#include "hipe_literals.h"
-#define ASM
#include "hipe_mode_switch.h"
.section ".text"
@@ -155,9 +155,9 @@ hipe_sparc_throw_to_native:
* which should look as follows:
*
* stub for f/N:
- * sethi %hi(f's BEAM code address), TEMP_ARG0
+ * sethi %hi(f's export entry address), TEMP_ARG0
* mov RA, TEMP_RA ! because the call below clobbers RA (%o7)
- * or TEMP_ARG0, %lo(f's BEAM code address), TEMP_ARG0
+ * or TEMP_ARG0, %lo(f's export entry address), TEMP_ARG0
* call nbif_callemu ! clobbers RA!
* mov N, TEMP_ARG1 ! delay slot: TEMP_ARG1 := ARITY
*
@@ -165,12 +165,12 @@ hipe_sparc_throw_to_native:
*/
.global nbif_callemu
nbif_callemu:
- st TEMP_ARG0, [P+P_BEAM_IP]
+ st TEMP_ARG0, [P+P_CALLEE_EXP]
st TEMP_ARG1, [P+P_ARITY]
st TEMP_RA, [P+P_NRA]
STORE_ARG_REGS
ba .flush_exit
- mov HIPE_MODE_SWITCH_RES_CALL, %o0
+ mov HIPE_MODE_SWITCH_RES_CALL_EXPORTED, %o0
/*
* nbif_apply
@@ -317,6 +317,7 @@ nbif_fail:
.global nbif_1_gc_after_bif
.global nbif_2_gc_after_bif
.global nbif_3_gc_after_bif
+ .global nbif_4_gc_after_bif
nbif_0_gc_after_bif:
ba .gc_after_bif
mov 0, %o1 /* delay slot */
@@ -327,7 +328,10 @@ nbif_2_gc_after_bif:
ba .gc_after_bif
mov 2, %o1 /* delay slot */
nbif_3_gc_after_bif:
- mov 3, %o1
+ ba .gc_after_bif
+ mov 3, %o1 /* delay slot */
+nbif_4_gc_after_bif:
+ mov 4, %o1
/*FALLTHROUGH*/
.gc_after_bif:
st %o1, [P+P_NARITY]
@@ -365,7 +369,11 @@ nbif_2_simple_exception:
mov 2, %o1 /* delay slot */
.global nbif_3_simple_exception
nbif_3_simple_exception:
- mov 3, %o1
+ ba .nbif_simple_exception
+ mov 3, %o1 /* delay slot */
+ .global nbif_4_simple_exception
+nbif_4_simple_exception:
+ mov 4, %o1
/*FALLTHROUGH*/
.nbif_simple_exception:
ld [P+P_FREASON], %o0
diff --git a/erts/emulator/hipe/hipe_sparc_glue.h b/erts/emulator/hipe/hipe_sparc_glue.h
index 1404c0d4c0..95ce1e5b4a 100644
--- a/erts/emulator/hipe/hipe_sparc_glue.h
+++ b/erts/emulator/hipe/hipe_sparc_glue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_sparc_primops.h b/erts/emulator/hipe/hipe_sparc_primops.h
index 413371e5f0..e42bcbad62 100644
--- a/erts/emulator/hipe/hipe_sparc_primops.h
+++ b/erts/emulator/hipe/hipe_sparc_primops.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_stack.c b/erts/emulator/hipe/hipe_stack.c
index 53c316ba52..e088b45c57 100644
--- a/erts/emulator/hipe/hipe_stack.c
+++ b/erts/emulator/hipe/hipe_stack.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_stack.h b/erts/emulator/hipe/hipe_stack.h
index 66f9f04c73..f575b97ce3 100644
--- a/erts/emulator/hipe/hipe_stack.h
+++ b/erts/emulator/hipe/hipe_stack.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -108,12 +109,23 @@ extern int hipe_fill_stacktrace(Process*, int, Eterm**);
#if 0 && defined(HIPE_NSTACK_GROWS_UP)
#define hipe_nstack_start(p) ((p)->hipe.nstack)
#define hipe_nstack_used(p) ((p)->hipe.nsp - (p)->hipe.nstack)
+#define hipe_nstack_avail(p) ((p)->hipe.nstend - (p)->hipe.nsp)
#endif
#if defined(HIPE_NSTACK_GROWS_DOWN)
#define hipe_nstack_start(p) ((p)->hipe.nsp)
#define hipe_nstack_used(p) ((p)->hipe.nstend - (p)->hipe.nsp)
+#define hipe_nstack_avail(p) ((unsigned)((p)->hipe.nsp - (p)->hipe.nstack))
#endif
+/* ensure that at least nwords words are available on the native stack */
+static __inline__ void hipe_check_nstack(Process *p, unsigned nwords)
+{
+ extern void hipe_inc_nstack(Process *p);
+
+ while (hipe_nstack_avail(p) < nwords)
+ hipe_inc_nstack(p);
+}
+
/*
* GC support procedures
*/
diff --git a/erts/emulator/hipe/hipe_x86.c b/erts/emulator/hipe/hipe_x86.c
index 327c74e9aa..19b70afced 100644
--- a/erts/emulator/hipe/hipe_x86.c
+++ b/erts/emulator/hipe/hipe_x86.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -108,7 +109,7 @@ static void atexit_alloc_code_stats(void)
#define MAP_ANONYMOUS MAP_ANON
#endif
-static void morecore(unsigned int alloc_bytes)
+static int morecore(unsigned int alloc_bytes)
{
unsigned int map_bytes;
char *map_hint, *map_start;
@@ -136,10 +137,9 @@ static void morecore(unsigned int alloc_bytes)
#endif
,
-1, 0);
- if (map_start == MAP_FAILED) {
- perror("mmap");
- abort();
- }
+ if (map_start == MAP_FAILED)
+ return -1;
+
ALLOC_CODE_STATS(total_mapped += map_bytes);
/* Merge adjacent mappings, so the trailing portion of the previous
@@ -155,6 +155,8 @@ static void morecore(unsigned int alloc_bytes)
}
ALLOC_CODE_STATS(atexit_alloc_code_stats());
+
+ return 0;
}
static void *alloc_code(unsigned int alloc_bytes)
@@ -164,8 +166,8 @@ static void *alloc_code(unsigned int alloc_bytes)
/* Align function entries. */
alloc_bytes = (alloc_bytes + 3) & ~3;
- if (code_bytes < alloc_bytes)
- morecore(alloc_bytes);
+ if (code_bytes < alloc_bytes && morecore(alloc_bytes) != 0)
+ return NULL;
ALLOC_CODE_STATS(++nr_allocs);
ALLOC_CODE_STATS(total_alloc += alloc_bytes);
res = code_next;
@@ -182,18 +184,16 @@ void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *
return alloc_code(nrbytes);
}
-/* called from hipe_bif0.c:hipe_bifs_make_native_stub_2()
- and hipe_bif0.c:hipe_make_stub() */
-void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
+void *hipe_make_native_stub(void *callee_exp, unsigned int beamArity)
{
/*
* This creates a native code stub with the following contents:
*
- * movl $Address, P_BEAM_IP(%ebp)
+ * movl $Address, P_CALLEE_EXP(%ebp)
* movb $Arity, P_ARITY(%ebp)
* jmp callemu
*
- * The stub has variable size, depending on whether the P_BEAM_IP
+ * The stub has variable size, depending on whether the P_CALLEE_EXP
* and P_ARITY offsets fit in 8-bit signed displacements or not.
* The rel32 offset in the final jmp depends on its actual location,
* which also depends on the size of the previous instructions.
@@ -206,28 +206,30 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity)
codeSize = /* 16, 19, or 22 bytes */
16 + /* 16 when both offsets are 8-bit */
- (P_BEAM_IP >= 128 ? 3 : 0) +
+ (P_CALLEE_EXP >= 128 ? 3 : 0) +
(P_ARITY >= 128 ? 3 : 0);
codep = code = alloc_code(codeSize);
+ if (!code)
+ return NULL;
- /* movl $beamAddress, P_BEAM_IP(%ebp); 3 or 6 bytes, plus 4 */
+ /* movl $beamAddress, P_CALLEE_EXP(%ebp); 3 or 6 bytes, plus 4 */
codep[0] = 0xc7;
-#if P_BEAM_IP >= 128
+#if P_CALLEE_EXP >= 128
codep[1] = 0x85; /* disp32[EBP] */
- codep[2] = P_BEAM_IP & 0xFF;
- codep[3] = (P_BEAM_IP >> 8) & 0xFF;
- codep[4] = (P_BEAM_IP >> 16) & 0xFF;
- codep[5] = (P_BEAM_IP >> 24) & 0xFF;
+ codep[2] = P_CALLEE_EXP & 0xFF;
+ codep[3] = (P_CALLEE_EXP >> 8) & 0xFF;
+ codep[4] = (P_CALLEE_EXP >> 16) & 0xFF;
+ codep[5] = (P_CALLEE_EXP >> 24) & 0xFF;
codep += 6;
#else
codep[1] = 0x45; /* disp8[EBP] */
- codep[2] = P_BEAM_IP;
+ codep[2] = P_CALLEE_EXP;
codep += 3;
#endif
- codep[0] = ((unsigned int)beamAddress) & 0xFF;
- codep[1] = ((unsigned int)beamAddress >> 8) & 0xFF;
- codep[2] = ((unsigned int)beamAddress >> 16) & 0xFF;
- codep[3] = ((unsigned int)beamAddress >> 24) & 0xFF;
+ codep[0] = ((unsigned int)callee_exp) & 0xFF;
+ codep[1] = ((unsigned int)callee_exp >> 8) & 0xFF;
+ codep[2] = ((unsigned int)callee_exp >> 16) & 0xFF;
+ codep[3] = ((unsigned int)callee_exp >> 24) & 0xFF;
codep += 4;
/* movb $beamArity, P_ARITY(%ebp); 3 or 6 bytes */
diff --git a/erts/emulator/hipe/hipe_x86.h b/erts/emulator/hipe/hipe_x86.h
index 97f09e38cd..30dc5666ae 100644
--- a/erts/emulator/hipe/hipe_x86.h
+++ b/erts/emulator/hipe/hipe_x86.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -53,8 +54,4 @@ extern void nbif_inc_stack_0(void);
extern void nbif_handle_fp_exception(void);
#endif
-/* for hipe_bifs_enter_code_2 */
-extern void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p);
-#define HIPE_ALLOC_CODE(n,c,t,p) hipe_alloc_code((n),(c),(t),(p))
-
#endif /* HIPE_X86_H */
diff --git a/erts/emulator/hipe/hipe_x86.tab b/erts/emulator/hipe/hipe_x86.tab
index fb33d0a6b9..55fb03cde8 100644
--- a/erts/emulator/hipe/hipe_x86.tab
+++ b/erts/emulator/hipe/hipe_x86.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/hipe/hipe_x86_abi.txt b/erts/emulator/hipe/hipe_x86_abi.txt
index aa04a12611..b74fcef127 100644
--- a/erts/emulator/hipe/hipe_x86_abi.txt
+++ b/erts/emulator/hipe/hipe_x86_abi.txt
@@ -3,16 +3,17 @@
Copyright Ericsson AB 2001-2011. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/emulator/hipe/hipe_x86_asm.m4 b/erts/emulator/hipe/hipe_x86_asm.m4
index 020ccf8d4b..3457574622 100644
--- a/erts/emulator/hipe/hipe_x86_asm.m4
+++ b/erts/emulator/hipe/hipe_x86_asm.m4
@@ -4,16 +4,17 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -33,6 +34,18 @@ define(SIMULATE_NSP,0)dnl change to 1 to simulate call/ret insns
`#define X86_LEAF_WORDS 'LEAF_WORDS
`#define LEAF_WORDS 'LEAF_WORDS
+`#define X86_NR_ARG_REGS 'NR_ARG_REGS
+`#define NR_ARG_REGS 'NR_ARG_REGS
+
+`#define X86_HP_IN_ESI 'HP_IN_ESI
+`#define X86_SIMULATE_NSP 'SIMULATE_NSP
+
+
+`#ifdef ASM'
+/*
+ * Only assembler stuff from here on (when included from *.S)
+ */
+
/*
* Workarounds for Darwin.
*/
@@ -60,7 +73,6 @@ ifelse(OPSYS,darwin,``
*/
`#define P %ebp'
-`#define X86_HP_IN_ESI 'HP_IN_ESI
`#if X86_HP_IN_ESI
#define SAVE_HP movl %esi, P_HP(P)
#define RESTORE_HP movl P_HP(P), %esi
@@ -73,7 +85,6 @@ ifelse(OPSYS,darwin,``
#define SAVE_CSP movl %esp, P_CSP(P)
#define RESTORE_CSP movl P_CSP(P), %esp'
-`#define X86_SIMULATE_NSP 'SIMULATE_NSP
/*
* Context switching macros.
@@ -100,12 +111,10 @@ ifelse(OPSYS,darwin,``
SAVE_CACHED_STATE; \
SWITCH_ERLANG_TO_C_QUICK'
+
/*
* Argument (parameter) registers.
*/
-`#define X86_NR_ARG_REGS 'NR_ARG_REGS
-`#define NR_ARG_REGS 'NR_ARG_REGS
-
ifelse(eval(NR_ARG_REGS >= 1),0,,
``#define ARG0 %eax
'')dnl
@@ -204,6 +213,7 @@ define(NBIF_COPY_NSP,`ifelse(eval($1 > NR_ARG_REGS),0,,`movl %esp, TEMP_NSP')')d
`/* #define NBIF_COPY_NSP_1 'NBIF_COPY_NSP(1)` */'
`/* #define NBIF_COPY_NSP_2 'NBIF_COPY_NSP(2)` */'
`/* #define NBIF_COPY_NSP_3 'NBIF_COPY_NSP(3)` */'
+`/* #define NBIF_COPY_NSP_4 'NBIF_COPY_NSP(4)` */'
`/* #define NBIF_COPY_NSP_5 'NBIF_COPY_NSP(5)` */'
dnl
@@ -227,6 +237,10 @@ define(NBIF_ARG_OPND,`ifelse(eval($2 >= NR_ARG_REGS),0,`ARG'$2,BASE_OFFSET(eval(
`/* #define NBIF_ARG_OPND_3_0 'NBIF_ARG_OPND(3,0)` */'
`/* #define NBIF_ARG_OPND_3_1 'NBIF_ARG_OPND(3,1)` */'
`/* #define NBIF_ARG_OPND_3_2 'NBIF_ARG_OPND(3,2)` */'
+`/* #define NBIF_ARG_OPND_4_0 'NBIF_ARG_OPND(4,0)` */'
+`/* #define NBIF_ARG_OPND_4_1 'NBIF_ARG_OPND(4,1)` */'
+`/* #define NBIF_ARG_OPND_4_2 'NBIF_ARG_OPND(4,2)` */'
+`/* #define NBIF_ARG_OPND_4_3 'NBIF_ARG_OPND(4,3)` */'
`/* #define NBIF_ARG_OPND_5_0 'NBIF_ARG_OPND(5,0)` */'
`/* #define NBIF_ARG_OPND_5_1 'NBIF_ARG_OPND(5,1)` */'
`/* #define NBIF_ARG_OPND_5_2 'NBIF_ARG_OPND(5,2)` */'
@@ -266,6 +280,7 @@ define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl
`/* #define NBIF_RET_1 'NBIF_RET(1)` */'
`/* #define NBIF_RET_2 'NBIF_RET(2)` */'
`/* #define NBIF_RET_3 'NBIF_RET(3)` */'
+`/* #define NBIF_RET_4 'NBIF_RET(4)` */'
`/* #define NBIF_RET_5 'NBIF_RET(5)` */'
dnl
@@ -282,4 +297,6 @@ define(LOAD_CALLER_SAVE,`LAR_N(eval(NR_CALLER_SAVE-1))')dnl
`#define STORE_CALLER_SAVE 'STORE_CALLER_SAVE
`#define LOAD_CALLER_SAVE 'LOAD_CALLER_SAVE
+`#endif /* ASM */'
+
`#endif /* HIPE_X86_ASM_H */'
diff --git a/erts/emulator/hipe/hipe_x86_bifs.m4 b/erts/emulator/hipe/hipe_x86_bifs.m4
index dd6980f555..0c0a8da6eb 100644
--- a/erts/emulator/hipe/hipe_x86_bifs.m4
+++ b/erts/emulator/hipe/hipe_x86_bifs.m4
@@ -4,21 +4,23 @@ changecom(`/*', `*/')dnl
*
* Copyright Ericsson AB 2001-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
+#`define ASM'
include(`hipe/hipe_x86_asm.m4')
#`include' "config.h"
#`include' "hipe_literals.h"
@@ -47,9 +49,10 @@ define(HANDLE_GOT_MBUF,`
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 0-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
@@ -157,6 +160,43 @@ ASYM($1):
TYPE_FUNCTION(ASYM($1))
#endif')
+define(standard_bif_interface_4,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(4)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(2,4,0)
+ NBIF_ARG(3,4,1)
+ NBIF_ARG(4,4,2)
+ NBIF_ARG(5,4,3)
+ lea 8(%esp), %eax
+ NBIF_ARG_REG(1,%eax) /* BIF__ARGS */
+ CALL_BIF($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_4_simple_exception
+ NBIF_RET(4)
+ HANDLE_GOT_MBUF(4)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
diff --git a/erts/emulator/hipe/hipe_x86_gc.h b/erts/emulator/hipe/hipe_x86_gc.h
index ac6b4f70bb..a8770ef4f9 100644
--- a/erts/emulator/hipe/hipe_x86_gc.h
+++ b/erts/emulator/hipe/hipe_x86_gc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_x86_glue.S b/erts/emulator/hipe/hipe_x86_glue.S
index 88b86f4de7..cf382c480d 100644
--- a/erts/emulator/hipe/hipe_x86_glue.S
+++ b/erts/emulator/hipe/hipe_x86_glue.S
@@ -4,24 +4,24 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
-
+#define ASM
#include "hipe_x86_asm.h"
#include "hipe_literals.h"
-#define ASM
#include "hipe_mode_switch.h"
/*
@@ -104,7 +104,7 @@ ASYM(nbif_return):
* stub (hipe_x86_loader.erl) which should look as follows:
*
* stub for f/N:
- * movl $<f's BEAM code address>, P_BEAM_IP(P)
+ * movl $<f's export entry address>, P_CALLEE_EXP(P)
* movb $<N>, P_ARITY(P)
* jmp nbif_callemu
*
@@ -114,7 +114,7 @@ ASYM(nbif_return):
GLOBAL(ASYM(nbif_callemu))
ASYM(nbif_callemu):
STORE_ARG_REGS
- movl $HIPE_MODE_SWITCH_RES_CALL, %eax
+ movl $HIPE_MODE_SWITCH_RES_CALL_EXPORTED, %eax
jmp .suspend_exit
/*
@@ -300,6 +300,7 @@ ASYM(nbif_fail):
GLOBAL(nbif_1_gc_after_bif)
GLOBAL(nbif_2_gc_after_bif)
GLOBAL(nbif_3_gc_after_bif)
+ GLOBAL(nbif_4_gc_after_bif)
.align 4
nbif_0_gc_after_bif:
xorl %edx, %edx
@@ -315,6 +316,10 @@ nbif_2_gc_after_bif:
.align 4
nbif_3_gc_after_bif:
movl $3, %edx
+ jmp .gc_after_bif
+ .align 4
+nbif_4_gc_after_bif:
+ movl $4, %edx
/*FALLTHROUGH*/
.align 4
.gc_after_bif:
@@ -338,6 +343,7 @@ nbif_3_gc_after_bif:
GLOBAL(nbif_1_simple_exception)
GLOBAL(nbif_2_simple_exception)
GLOBAL(nbif_3_simple_exception)
+ GLOBAL(nbif_4_simple_exception)
.align 4
nbif_0_simple_exception:
xorl %eax, %eax
@@ -353,6 +359,10 @@ nbif_2_simple_exception:
.align 4
nbif_3_simple_exception:
movl $3, %eax
+ jmp .nbif_simple_exception
+ .align 4
+nbif_4_simple_exception:
+ movl $4, %eax
/*FALLTHROUGH*/
.align 4
.nbif_simple_exception:
diff --git a/erts/emulator/hipe/hipe_x86_glue.h b/erts/emulator/hipe/hipe_x86_glue.h
index 4b6e495b9a..6c123e8938 100644
--- a/erts/emulator/hipe/hipe_x86_glue.h
+++ b/erts/emulator/hipe/hipe_x86_glue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_x86_primops.h b/erts/emulator/hipe/hipe_x86_primops.h
index 111b1fa8bd..3e057059bc 100644
--- a/erts/emulator/hipe/hipe_x86_primops.h
+++ b/erts/emulator/hipe/hipe_x86_primops.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c
index f5668013e2..b7dae88417 100644
--- a/erts/emulator/hipe/hipe_x86_signal.c
+++ b/erts/emulator/hipe/hipe_x86_signal.c
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -197,7 +198,7 @@ static void do_init(void)
#define INIT() do { if (!init_done()) do_init(); } while (0)
#endif /* __DARWIN__ */
-#if !defined(__GLIBC__) && !defined(__DARWIN__) && !defined(__NetBSD__)
+#if defined(__sun__)
/*
* Assume Solaris/x86 2.8.
* There is a number of sigaction() procedures in libc:
@@ -231,7 +232,56 @@ static void do_init(void)
}
#define _NSIG NSIG
#define INIT() do { if (!init_done()) do_init(); } while (0)
-#endif /* not glibc or darwin */
+#endif /* __sun__ */
+
+#if defined(__FreeBSD__)
+/*
+ * This is a copy of Darwin code for FreeBSD.
+ * CAVEAT: detailed semantics are not verified yet.
+ */
+#include <dlfcn.h>
+static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*);
+#define init_done() (__next_sigaction != 0)
+extern int _sigaction(int, const struct sigaction*, struct sigaction*);
+#define __SIGACTION _sigaction
+static void do_init(void)
+{
+ __next_sigaction = dlsym(RTLD_NEXT, "sigaction");
+ if (__next_sigaction != 0)
+ return;
+ perror("dlsym_freebsd");
+ abort();
+}
+#define _NSIG NSIG
+#define INIT() do { if (!init_done()) do_init(); } while (0)
+#endif /* __FreeBSD__ */
+
+#if !(defined(__GLIBC__) || defined(__DARWIN__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__sun__))
+/*
+ * Unknown libc -- assume musl. Note: musl deliberately does not provide a musl-specific
+ * feature test macro, so we cannot check for it.
+ *
+ * sigaction is a weak alias for __sigaction, which is a wrapper for __libc_sigaction.
+ * There are libc-internal calls to __libc_sigaction which install handlers, so we must
+ * override __libc_sigaction rather than __sigaction.
+ */
+#include <dlfcn.h>
+static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*);
+#define init_done() (__next_sigaction != 0)
+#define __SIGACTION __libc_sigaction
+static void do_init(void)
+{
+ __next_sigaction = dlsym(RTLD_NEXT, "__libc_sigaction");
+ if (__next_sigaction != 0)
+ return;
+ perror("dlsym");
+ abort();
+}
+#ifndef _NSIG
+#define _NSIG NSIG
+#endif
+#define INIT() do { if (!init_done()) do_init(); } while (0)
+#endif /* !(__GLIBC__ || __DARWIN__ || __NetBSD__ || __FreeBSD__ || __sun__) */
#if !defined(__NetBSD__)
/*
@@ -271,7 +321,7 @@ int __SIGACTION(int signum, const struct sigaction *act, struct sigaction *oldac
/*
* This catches the application's own sigaction() calls.
*/
-#if !defined(__DARWIN__) && !defined(__NetBSD__)
+#if !defined(__DARWIN__) && !defined(__NetBSD__) && !defined(__FreeBSD__)
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
{
return my_sigaction(signum, act, oldact);
diff --git a/erts/emulator/hipe/hipe_x86_stack.c b/erts/emulator/hipe/hipe_x86_stack.c
index 9ad3fa9d31..6629713a05 100644
--- a/erts/emulator/hipe/hipe_x86_stack.c
+++ b/erts/emulator/hipe/hipe_x86_stack.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -209,7 +210,7 @@ void (*hipe_handle_stack_trap(Process *p))(void)
* The native stack MUST contain a stack frame as it appears on
* entry to a function (return address, actuals, caller's frame).
* p->hipe.narity MUST contain the arity (number of actuals).
- * On exit, p->hipe.ncallee is set to the handler's PC and p->hipe.nsp
+ * On exit, p->hipe.u.ncallee is set to the handler's PC and p->hipe.nsp
* is set to its SP (low address of its stack frame).
*/
void hipe_find_handler(Process *p)
@@ -240,7 +241,7 @@ void hipe_find_handler(Process *p)
if ((exnra = sdesc_exnra(sdesc)) != 0 &&
(p->catches >= 0 ||
exnra == (unsigned long)nbif_fail)) {
- p->hipe.ncallee = (void(*)(void)) exnra;
+ p->hipe.u.ncallee = (void(*)(void)) exnra;
p->hipe.nsp = nsp;
p->hipe.narity = 0;
/* update the gray/white boundary if we threw past it */
diff --git a/erts/emulator/internal_doc/dec.erl b/erts/emulator/internal_doc/dec.erl
index dc995989fb..e64e37a7d9 100644
--- a/erts/emulator/internal_doc/dec.erl
+++ b/erts/emulator/internal_doc/dec.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -64,18 +65,17 @@ dec() ->
"*~n"
"* Copyright Ericsson AB 1999-2010. All Rights Reserved.~n"
"*~n"
- "* The contents of this file are subject to the Erlang Public License,~n"
- "* Version 1.1, (the \"License\"); you may not use this file except in~n"
- "* compliance with the License. You should have received a copy of the~n"
- "* Erlang Public License along with this software. If not, it can be~n"
- "* retrieved online at http://www.erlang.org/.~n"
+ "* Licensed under the Apache License, Version 2.0 (the \"License\");~n"
+ "* you may not use this file except in compliance with the License.~n"
+ "* You may obtain a copy of the License at~n"
+ "*~n"
+ "* http://www.apache.org/licenses/LICENSE-2.0~n"
"*~n"
- "* Software distributed under the License is distributed on an "
- "\"AS IS\"~n"
- "* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n"
- "* the License for the specific language governing rights and "
- "limitations~n"
- "* under the License.~n"
+ "* Unless required by applicable law or agreed to in writing, software~n"
+ "* distributed under the License is distributed on an \"AS IS\" BASIS,~n"
+ "* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~n"
+ "* See the License for the specific language governing permissions and~n"
+ "* limitations under the License.~n"
"*~n"
"* %CopyrightEnd%~n"
"*/~n"
diff --git a/erts/emulator/internal_doc/erl_ext_dist.txt b/erts/emulator/internal_doc/erl_ext_dist.txt
index 1cbbbcc7b8..23b7d0d8e5 100644
--- a/erts/emulator/internal_doc/erl_ext_dist.txt
+++ b/erts/emulator/internal_doc/erl_ext_dist.txt
@@ -3,16 +3,17 @@
Copyright Ericsson AB 1997-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/emulator/pcre/pcre.mk b/erts/emulator/pcre/pcre.mk
index 54412f6b1d..b844b77214 100644
--- a/erts/emulator/pcre/pcre.mk
+++ b/erts/emulator/pcre/pcre.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c
index 0051b45b31..105b129065 100644
--- a/erts/emulator/sys/common/erl_check_io.c
+++ b/erts/emulator/sys/common/erl_check_io.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -38,9 +39,10 @@
#include "erl_check_io.h"
#include "erl_thr_progress.h"
#include "dtrace-wrapper.h"
+#define ERTS_WANT_TIMER_WHEEL_API
+#include "erl_time.h"
-#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
-#else
+#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS
# include "safe_hash.h"
# define DRV_EV_STATE_HTAB_SIZE 1024
#endif
@@ -411,14 +413,16 @@ static void
grow_drv_ev_state(int min_ix)
{
int i;
+ int old_len;
int new_len;
- new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(min_ix + 1);
- if (new_len > max_fds)
- new_len = max_fds;
-
erts_smp_mtx_lock(&drv_ev_state_grow_lock);
- if (erts_smp_atomic_read_nob(&drv_ev_state_len) <= min_ix) {
+ old_len = erts_smp_atomic_read_nob(&drv_ev_state_len);
+ if (min_ix >= old_len) {
+ new_len = erts_poll_new_table_len(old_len, min_ix + 1);
+ if (new_len > max_fds)
+ new_len = max_fds;
+
for (i=0; i<DRV_EV_STATE_LOCK_CNT; i++) { /* lock all fd's */
erts_smp_mtx_lock(&drv_ev_state_locks[i].lck);
}
@@ -428,7 +432,7 @@ grow_drv_ev_state(int min_ix)
sizeof(ErtsDrvEventState)*new_len)
: erts_alloc(ERTS_ALC_T_DRV_EV_STATE,
sizeof(ErtsDrvEventState)*new_len));
- for (i = erts_smp_atomic_read_nob(&drv_ev_state_len); i < new_len; i++) {
+ for (i = old_len; i < new_len; i++) {
drv_ev_state[i].fd = (ErtsSysFdType) i;
drv_ev_state[i].driver.select = NULL;
#if ERTS_CIO_HAVE_DRV_EVENT
@@ -1590,9 +1594,9 @@ ERTS_CIO_EXPORT(erts_check_io_interrupt)(int set)
void
ERTS_CIO_EXPORT(erts_check_io_interrupt_timed)(int set,
- erts_short_time_t msec)
+ ErtsMonotonicTime timeout_time)
{
- ERTS_CIO_POLL_INTR_TMD(pollset.ps, set, msec);
+ ERTS_CIO_POLL_INTR_TMD(pollset.ps, set, timeout_time);
}
void
@@ -1600,9 +1604,12 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait)
{
ErtsPollResFd *pollres;
int pollres_len;
- SysTimeval wait_time;
+ ErtsMonotonicTime timeout_time;
int poll_ret, i;
erts_aint_t current_cio_time;
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+
+ ASSERT(esdp);
restart:
@@ -1612,12 +1619,9 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait)
#endif
/* Figure out timeout value */
- if (do_wait) {
- erts_time_remaining(&wait_time);
- } else { /* poll only */
- wait_time.tv_sec = 0;
- wait_time.tv_usec = 0;
- }
+ timeout_time = (do_wait
+ ? erts_check_next_timeout_time(esdp)
+ : ERTS_POLL_NO_TIMEOUT /* poll only */);
/*
* No need for an atomic inc op when incrementing
@@ -1640,14 +1644,12 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait)
erts_smp_atomic_set_nob(&pollset.in_poll_wait, 1);
- poll_ret = ERTS_CIO_POLL_WAIT(pollset.ps, pollres, &pollres_len, &wait_time);
+ poll_ret = ERTS_CIO_POLL_WAIT(pollset.ps, pollres, &pollres_len, timeout_time);
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_lc_check_exact(NULL, 0); /* No locks should be locked */
#endif
- erts_deliver_time(); /* sync the machine's idea of time */
-
#ifdef ERTS_BREAK_REQUESTED
if (ERTS_BREAK_REQUESTED)
erts_do_break_handling();
diff --git a/erts/emulator/sys/common/erl_check_io.h b/erts/emulator/sys/common/erl_check_io.h
index d01297d55c..c8675a7d9d 100644
--- a/erts/emulator/sys/common/erl_check_io.h
+++ b/erts/emulator/sys/common/erl_check_io.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -47,8 +48,8 @@ void erts_check_io_async_sig_interrupt_nkp(void);
#endif
void erts_check_io_interrupt_kp(int);
void erts_check_io_interrupt_nkp(int);
-void erts_check_io_interrupt_timed_kp(int, erts_short_time_t);
-void erts_check_io_interrupt_timed_nkp(int, erts_short_time_t);
+void erts_check_io_interrupt_timed_kp(int, ErtsMonotonicTime);
+void erts_check_io_interrupt_timed_nkp(int, ErtsMonotonicTime);
void erts_check_io_kp(int);
void erts_check_io_nkp(int);
void erts_init_check_io_kp(void);
@@ -65,7 +66,7 @@ int erts_check_io_max_files(void);
void erts_check_io_async_sig_interrupt(void);
#endif
void erts_check_io_interrupt(int);
-void erts_check_io_interrupt_timed(int, erts_short_time_t);
+void erts_check_io_interrupt_timed(int, ErtsMonotonicTime);
void erts_check_io(int);
void erts_init_check_io(void);
diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c
index 3f6813e1a5..4180e65fdc 100644
--- a/erts/emulator/sys/common/erl_mmap.c
+++ b/erts/emulator/sys/common/erl_mmap.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -1333,7 +1334,7 @@ os_unreserve_physical(char *ptr, UWord size)
void *res = mmap((void *) ptr, (size_t) size, ERTS_MMAP_UNRESERVE_PROT,
ERTS_MMAP_UNRESERVE_FLAGS, ERTS_MMAP_FD, 0);
if (res == (void *) MAP_FAILED)
- erl_exit(ERTS_ABORT_EXIT, "Failed to unreserve memory");
+ erts_exit(ERTS_ABORT_EXIT, "Failed to unreserve memory");
}
static void *
@@ -2125,7 +2126,7 @@ erts_mmap_init(ErtsMMapInit *init)
#endif
erts_page_inv_mask = pagesize - 1;
if (pagesize & erts_page_inv_mask)
- erl_exit(-1, "erts_mmap: Invalid pagesize: %bpu\n",
+ erts_exit(1, "erts_mmap: Invalid pagesize: %bpu\n",
pagesize);
ERTS_MMAP_OP_RINGBUF_INIT();
@@ -2139,7 +2140,7 @@ erts_mmap_init(ErtsMMapInit *init)
#if HAVE_MMAP && !defined(MAP_ANON)
mmap_state.mmap_fd = open("/dev/zero", O_RDWR);
if (mmap_state.mmap_fd < 0)
- erl_exit(-1, "erts_mmap: Failed to open /dev/zero\n");
+ erts_exit(1, "erts_mmap: Failed to open /dev/zero\n");
#endif
erts_smp_mtx_init(&mmap_state.mtx, "erts_mmap");
@@ -2154,7 +2155,7 @@ erts_mmap_init(ErtsMMapInit *init)
sz = end - ptr;
start = os_mmap_virtual(ptr, sz);
if (!start || start > ptr || start >= end)
- erl_exit(-1,
+ erts_exit(1,
"erts_mmap: Failed to create virtual range for super carrier\n");
sz = start - ptr;
if (sz)
@@ -2192,7 +2193,7 @@ erts_mmap_init(ErtsMMapInit *init)
start = os_mmap(NULL, sz, 1);
}
if (!start)
- erl_exit(-1,
+ erts_exit(1,
"erts_mmap: Failed to create super carrier of size %bpu MB\n",
init->scs/1024/1024);
end = start + sz;
@@ -2241,7 +2242,7 @@ erts_mmap_init(ErtsMMapInit *init)
if ((desc_size
+ ERTS_SUPERALIGNED_SIZE
+ ERTS_PAGEALIGNED_SIZE) > end - start)
- erl_exit(-1, "erts_mmap: No space for segments in super carrier\n");
+ erts_exit(1, "erts_mmap: No space for segments in super carrier\n");
mmap_state.sa.bot = start;
mmap_state.sa.bot += desc_size;
@@ -2279,7 +2280,7 @@ erts_mmap_init(ErtsMMapInit *init)
*/
#ifdef ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION
if (virtual_map && !os_reserve_physical(start, mmap_state.sa.bot - start))
- erl_exit(-1, "erts_mmap: Failed to reserve physical memory for descriptors\n");
+ erts_exit(1, "erts_mmap: Failed to reserve physical memory for descriptors\n");
#endif
mmap_state.desc.unused_start = start;
mmap_state.desc.unused_end = mmap_state.sa.bot;
diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h
index 778a8e0e80..66619c5161 100644
--- a/erts/emulator/sys/common/erl_mmap.h
+++ b/erts/emulator/sys/common/erl_mmap.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index 94a381e168..3398be2b07 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -1489,7 +1490,7 @@ erts_mseg_init(ErtsMsegInit_t *init)
#if HALFWORD_HEAP
if (sizeof(void *) != 8)
- erl_exit(-1,"Halfword emulator cannot be run in 32bit mode");
+ erts_exit(1,"Halfword emulator cannot be run in 32bit mode");
init->mmap.virtual_range.start = (char *) sbrk(0);
init->mmap.virtual_range.end = (char *) 0x100000000UL;
@@ -1499,7 +1500,7 @@ erts_mseg_init(ErtsMsegInit_t *init)
erts_mmap_init(&init->mmap);
if (!IS_2POW(GET_PAGE_SIZE))
- erl_exit(ERTS_ABORT_EXIT, "erts_mseg: Unexpected page_size %beu\n", GET_PAGE_SIZE);
+ erts_exit(ERTS_ABORT_EXIT, "erts_mseg: Unexpected page_size %beu\n", GET_PAGE_SIZE);
ASSERT((MSEG_ALIGNED_SIZE % GET_PAGE_SIZE) == 0);
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index 2284b3f8f1..ba04e919fc 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/common/erl_mtrace_sys_wrap.c b/erts/emulator/sys/common/erl_mtrace_sys_wrap.c
index 408aa7e016..a8c575835a 100644
--- a/erts/emulator/sys/common/erl_mtrace_sys_wrap.c
+++ b/erts/emulator/sys/common/erl_mtrace_sys_wrap.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/common/erl_os_monotonic_time_extender.c b/erts/emulator/sys/common/erl_os_monotonic_time_extender.c
new file mode 100644
index 0000000000..367b22d989
--- /dev/null
+++ b/erts/emulator/sys/common/erl_os_monotonic_time_extender.c
@@ -0,0 +1,89 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "erl_os_monotonic_time_extender.h"
+
+#ifdef USE_THREADS
+
+static void *os_monotonic_time_extender(void *vstatep)
+{
+ ErtsOsMonotonicTimeExtendState *state = (ErtsOsMonotonicTimeExtendState *) vstatep;
+ long sleep_time = state->check_interval*1000;
+ Uint32 (*raw_os_mtime)(void) = state->raw_os_monotonic_time;
+ Uint32 last_msb = 0;
+
+ while (1) {
+ Uint32 msb = (*raw_os_mtime)() & (((Uint32) 1) << 31);
+
+ if (msb != last_msb) {
+ int ix = ((int) (last_msb >> 31)) & 1;
+ Uint32 xtnd = (Uint32) erts_atomic32_read_nob(&state->extend[ix]);
+ erts_atomic32_set_nob(&state->extend[ix], (erts_aint32_t) (xtnd + 1));
+ last_msb = msb;
+ }
+ erts_milli_sleep(sleep_time);
+ }
+
+ erts_exit(ERTS_ABORT_EXIT, "os_monotonic_time_extender thread terminating");
+ return NULL;
+}
+
+static erts_tid_t os_monotonic_extender_tid;
+#endif
+
+void
+erts_init_os_monotonic_time_extender(ErtsOsMonotonicTimeExtendState *statep,
+ Uint32 (*raw_os_monotonic_time)(void),
+ int check_seconds)
+{
+#ifdef USE_THREADS
+ statep->raw_os_monotonic_time = raw_os_monotonic_time;
+ erts_atomic32_init_nob(&statep->extend[0], (erts_aint32_t) 0);
+ erts_atomic32_init_nob(&statep->extend[1], (erts_aint32_t) 0);
+ statep->check_interval = check_seconds;
+
+#else
+ statep->extend[0] = (Uint32) 0;
+ statep->extend[1] = (Uint32) 0;
+ statep->last_msb = (ErtsMonotonicTime) 0;
+#endif
+}
+
+void
+erts_late_init_os_monotonic_time_extender(ErtsOsMonotonicTimeExtendState *statep)
+{
+#ifdef USE_THREADS
+ erts_thr_opts_t thr_opts = ERTS_THR_OPTS_DEFAULT_INITER;
+ thr_opts.detached = 1;
+ thr_opts.suggested_stack_size = 4;
+
+#if 0
+ thr_opts.name = "os_monotonic_time_extender";
+#endif
+
+ erts_thr_create(&os_monotonic_extender_tid,
+ os_monotonic_time_extender,
+ (void*) statep,
+ &thr_opts);
+#endif
+}
diff --git a/erts/emulator/sys/common/erl_os_monotonic_time_extender.h b/erts/emulator/sys/common/erl_os_monotonic_time_extender.h
new file mode 100644
index 0000000000..8089c9aed9
--- /dev/null
+++ b/erts/emulator/sys/common/erl_os_monotonic_time_extender.h
@@ -0,0 +1,66 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifndef ERL_OS_MONOTONIC_TIME_EXTENDER_H__
+#define ERL_OS_MONOTONIC_TIME_EXTENDER_H__
+
+#include "sys.h"
+#include "erl_threads.h"
+
+typedef struct {
+#ifdef USE_THREADS
+ Uint32 (*raw_os_monotonic_time)(void);
+ erts_atomic32_t extend[2];
+ int check_interval;
+#else
+ Uint32 extend[2];
+ ErtsMonotonicTime last_msb;
+#endif
+} ErtsOsMonotonicTimeExtendState;
+
+#ifdef USE_THREADS
+# define ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(S, RT) ((void) 1)
+# define ERTS_EXTEND_OS_MONOTONIC_TIME(S, RT) \
+ ((((ErtsMonotonicTime) \
+ erts_atomic32_read_nob(&((S)->extend[((int) ((RT) >> 31)) & 1]))) \
+ << 32) \
+ + (RT))
+#else
+# define ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(S, RT) \
+ do { \
+ Uint32 msb__ = (RT) & (((Uint32) 1) << 31); \
+ if (msb__ != (S)->last_msb) { \
+ int ix__ = ((int) ((S)->last_msb >> 31)) & 1; \
+ (S)->extend[ix__]++; \
+ (S)->last_msb = msb; \
+ } \
+ } while (0)
+# define ERTS_EXTEND_OS_MONOTONIC_TIME(S, RT) \
+ ((((ErtsMonotonicTime) (S)->extend[((int) ((RT) >> 31)) & 1]) << 32) + (RT))
+#endif
+
+void
+erts_init_os_monotonic_time_extender(ErtsOsMonotonicTimeExtendState *statep,
+ Uint32 (*raw_os_monotonic_time)(void),
+ int check_seconds);
+void
+erts_late_init_os_monotonic_time_extender(ErtsOsMonotonicTimeExtendState *statep);
+
+#endif
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index aa412a20c8..21fa214364 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -153,9 +154,6 @@ int ERTS_SELECT(int nfds, ERTS_fd_set *readfds, ERTS_fd_set *writefds,
#define ERTS_POLL_COALESCE_KP_RES (ERTS_POLL_USE_KQUEUE || ERTS_POLL_USE_EPOLL)
-#define ERTS_EV_TABLE_MIN_LENGTH 1024
-#define ERTS_EV_TABLE_EXP_THRESHOLD (2048*1024)
-
#ifdef ERTS_POLL_NEED_ASYNC_INTERRUPT_SUPPORT
# define ERTS_POLL_ASYNC_INTERRUPT_SUPPORT 1
#else
@@ -314,13 +312,16 @@ struct ErtsPollSet_ {
#if ERTS_POLL_USE_WAKEUP_PIPE
int wake_fds[2];
#endif
+#if ERTS_POLL_USE_TIMERFD
+ int timer_fd;
+#endif
#if ERTS_POLL_USE_FALLBACK
int fallback_used;
#endif
#if defined(USE_THREADS) || ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
erts_atomic32_t wakeup_state;
#endif
- erts_smp_atomic32_t timeout;
+ erts_atomic64_t timeout_time;
#ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS
erts_smp_atomic_t no_avoided_wakeups;
erts_smp_atomic_t no_avoided_interrupts;
@@ -384,6 +385,26 @@ static void check_poll_status(ErtsPollSet ps);
static void print_misc_debug_info(void);
#endif
+static ERTS_INLINE void
+init_timeout_time(ErtsPollSet ps)
+{
+ erts_atomic64_init_nob(&ps->timeout_time,
+ (erts_aint64_t) ERTS_MONOTONIC_TIME_MAX);
+}
+
+static ERTS_INLINE void
+set_timeout_time(ErtsPollSet ps, ErtsMonotonicTime time)
+{
+ erts_atomic64_set_relb(&ps->timeout_time,
+ (erts_aint64_t) time);
+}
+
+static ERTS_INLINE ErtsMonotonicTime
+get_timeout_time(ErtsPollSet ps)
+{
+ return (ErtsMonotonicTime) erts_atomic64_read_acqb(&ps->timeout_time);
+}
+
#define ERTS_POLL_NOT_WOKEN 0
#define ERTS_POLL_WOKEN -1
#define ERTS_POLL_WOKEN_INTR 1
@@ -410,7 +431,7 @@ static ERTS_INLINE int
is_interrupted_reset(ErtsPollSet ps)
{
#if defined(USE_THREADS) || ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
- return (erts_atomic32_xchg_nob(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN)
+ return (erts_atomic32_xchg_acqb(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN)
== ERTS_POLL_WOKEN_INTR);
#else
return 0;
@@ -421,7 +442,7 @@ static ERTS_INLINE void
woke_up(ErtsPollSet ps)
{
#if defined(USE_THREADS) || ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
- erts_aint32_t wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state);
+ erts_aint32_t wakeup_state = erts_atomic32_read_acqb(&ps->wakeup_state);
if (wakeup_state == ERTS_POLL_NOT_WOKEN)
(void) erts_atomic32_cmpxchg_nob(&ps->wakeup_state,
ERTS_POLL_WOKEN,
@@ -448,14 +469,9 @@ wake_poller(ErtsPollSet ps, int interrupted, int async_signal_safe)
wakeup_state = erts_atomic32_cmpxchg_relb(&ps->wakeup_state,
ERTS_POLL_WOKEN,
ERTS_POLL_NOT_WOKEN);
- else {
- /*
- * We might unnecessarily write to the pipe, however,
- * that isn't problematic.
- */
- wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state);
- erts_atomic32_set_relb(&ps->wakeup_state, ERTS_POLL_WOKEN_INTR);
- }
+ else
+ wakeup_state = erts_atomic32_xchg_relb(&ps->wakeup_state,
+ ERTS_POLL_WOKEN_INTR);
wake = wakeup_state == ERTS_POLL_NOT_WOKEN;
}
/*
@@ -560,6 +576,75 @@ create_wakeup_pipe(ErtsPollSet ps)
#endif /* ERTS_POLL_USE_WAKEUP_PIPE */
/*
+ * --- timer fd -----------------------------------------------------------
+ */
+
+#if ERTS_POLL_USE_TIMERFD
+
+/* We use the timerfd when using epoll_wait to get high accuracy
+ timeouts, i.e. we want to sleep with < ms accuracy. */
+
+static void
+create_timerfd(ErtsPollSet ps)
+{
+ int do_wake = 0;
+ int timer_fd;
+ timer_fd = timerfd_create(CLOCK_MONOTONIC,0);
+ ERTS_POLL_EXPORT(erts_poll_control)(ps,
+ timer_fd,
+ ERTS_POLL_EV_IN,
+ 1, &do_wake);
+#if ERTS_POLL_USE_FALLBACK
+ /* We depend on the wakeup pipe being handled by kernel poll */
+ if (ps->fds_status[timer_fd].flags & ERTS_POLL_FD_FLG_INFLBCK)
+ fatal_error("%s:%d:create_wakeup_pipe(): Internal error\n",
+ __FILE__, __LINE__);
+#endif
+ if (ps->internal_fd_limit <= timer_fd)
+ ps->internal_fd_limit = timer_fd + 1;
+ ps->timer_fd = timer_fd;
+}
+
+static ERTS_INLINE void
+timerfd_set(ErtsPollSet ps, struct itimerspec *its)
+{
+#ifdef DEBUG
+ struct itimerspec old_its;
+ int res;
+ res = timerfd_settime(ps->timer_fd, 0, its, &old_its);
+ ASSERT(res == 0);
+ ASSERT(old_its.it_interval.tv_sec == 0 &&
+ old_its.it_interval.tv_nsec == 0 &&
+ old_its.it_value.tv_sec == 0 &&
+ old_its.it_value.tv_nsec == 0);
+
+#else
+ timerfd_settime(ps->timer_fd, 0, its, NULL);
+#endif
+}
+
+static ERTS_INLINE int
+timerfd_clear(ErtsPollSet ps, int res, int max_res) {
+
+ struct itimerspec its;
+ /* we always have to clear the timer */
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = 0;
+ its.it_value.tv_nsec = 0;
+ timerfd_settime(ps->timer_fd, 0, &its, NULL);
+
+ /* only timeout fd triggered */
+ if (res == 1 && ps->res_events[0].data.fd == ps->timer_fd)
+ return 0;
+
+ return res;
+}
+
+#endif /* ERTS_POLL_USE_TIMERFD */
+
+
+/*
* --- Poll set update requests ----------------------------------------------
*/
#if ERTS_POLL_USE_UPDATE_REQUESTS_QUEUE
@@ -611,27 +696,33 @@ free_update_requests_block(ErtsPollSet ps,
* --- Growing poll set structures -------------------------------------------
*/
-int
-ERTS_POLL_EXPORT(erts_poll_get_table_len) (int new_len)
+#ifndef ERTS_KERNEL_POLL_VERSION /* only one shared implementation */
+
+#define ERTS_FD_TABLE_MIN_LENGTH 1024
+#define ERTS_FD_TABLE_EXP_THRESHOLD (2048*1024)
+
+int erts_poll_new_table_len (int old_len, int need_len)
{
- if (new_len < ERTS_EV_TABLE_MIN_LENGTH) {
- new_len = ERTS_EV_TABLE_MIN_LENGTH;
- } else if (new_len < ERTS_EV_TABLE_EXP_THRESHOLD) {
- /* find next power of 2 */
- --new_len;
- new_len |= new_len >> 1;
- new_len |= new_len >> 2;
- new_len |= new_len >> 4;
- new_len |= new_len >> 8;
- new_len |= new_len >> 16;
- ++new_len;
- } else {
- /* grow incrementally */
- new_len += ERTS_EV_TABLE_EXP_THRESHOLD;
+ int new_len;
+
+ ASSERT(need_len > old_len);
+ if (need_len < ERTS_FD_TABLE_MIN_LENGTH) {
+ new_len = ERTS_FD_TABLE_MIN_LENGTH;
}
+ else {
+ new_len = old_len;
+ do {
+ if (new_len < ERTS_FD_TABLE_EXP_THRESHOLD)
+ new_len *= 2;
+ else
+ new_len += ERTS_FD_TABLE_EXP_THRESHOLD;
+
+ } while (new_len < need_len);
+ }
+ ASSERT(new_len >= need_len);
return new_len;
}
-
+#endif
#if ERTS_POLL_USE_KERNEL_POLL
static void
@@ -645,7 +736,7 @@ grow_res_events(ErtsPollSet ps, int new_len)
#elif ERTS_POLL_USE_KQUEUE
struct kevent
#endif
- ) * ERTS_POLL_EXPORT(erts_poll_get_table_len)(new_len);
+ ) * erts_poll_new_table_len(ps->res_events_len, new_len);
/* We do not need to save previously stored data */
if (ps->res_events)
erts_free(ERTS_ALC_T_POLL_RES_EVS, ps->res_events);
@@ -659,7 +750,7 @@ static void
grow_poll_fds(ErtsPollSet ps, int min_ix)
{
int i;
- int new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(min_ix + 1);
+ int new_len = erts_poll_new_table_len(ps->poll_fds_len, min_ix + 1);
if (new_len > max_fds)
new_len = max_fds;
ps->poll_fds = (ps->poll_fds_len
@@ -681,7 +772,7 @@ grow_poll_fds(ErtsPollSet ps, int min_ix)
static void
grow_select_fds(int fd, ERTS_fd_set* fds)
{
- int new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(fd + 1);
+ int new_len = erts_poll_new_table_len(fds->sz, fd + 1);
if (new_len > max_fds)
new_len = max_fds;
new_len = ERTS_FD_SIZE(new_len);
@@ -708,7 +799,7 @@ static void
grow_fds_status(ErtsPollSet ps, int min_fd)
{
int i;
- int new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(min_fd + 1);
+ int new_len = erts_poll_new_table_len(ps->fds_status_len, min_fd + 1);
ASSERT(min_fd < max_fds);
if (new_len > max_fds)
new_len = max_fds;
@@ -1497,6 +1588,12 @@ poll_control(ErtsPollSet ps, int fd, ErtsPollEvents events, int on, int *do_wake
goto done;
}
#endif
+#if ERTS_POLL_USE_TIMERFD
+ if (fd == ps->timer_fd) {
+ new_events = ERTS_POLL_EV_NVAL;
+ goto done;
+ }
+#endif
}
if (fd >= ps->fds_status_len)
@@ -1644,6 +1741,9 @@ save_kp_result(ErtsPollSet ps, ErtsPollResFd pr[], int max_res, int chk_fds_res)
#if ERTS_POLL_USE_WAKEUP_PIPE
int wake_fd = ps->wake_fds[0];
#endif
+#if ERTS_POLL_USE_TIMERFD
+ int timer_fd = ps->timer_fd;
+#endif
for (i = 0; i < n; i++) {
@@ -1659,6 +1759,11 @@ save_kp_result(ErtsPollSet ps, ErtsPollResFd pr[], int max_res, int chk_fds_res)
continue;
}
#endif
+#if ERTS_POLL_USE_TIMERFD
+ if (fd == timer_fd) {
+ continue;
+ }
+#endif
ASSERT(!(ps->fds_status[fd].flags & ERTS_POLL_FD_FLG_INFLBCK));
/* epoll_wait() can repeat the same fd in result array... */
ix = (int) ps->fds_status[fd].res_ev_ix;
@@ -1733,6 +1838,11 @@ save_kp_result(ErtsPollSet ps, ErtsPollResFd pr[], int max_res, int chk_fds_res)
continue;
}
#endif
+#if ERTS_POLL_USE_TIMERFD
+ if (fd == timer_fd) {
+ continue;
+ }
+#endif
revents = ERTS_POLL_EV_N2E(ps->res_events[i].events);
pr[res].fd = fd;
pr[res].events = revents;
@@ -1993,44 +2103,186 @@ save_poll_result(ErtsPollSet ps, ErtsPollResFd pr[], int max_res,
}
}
+static ERTS_INLINE ErtsMonotonicTime
+get_timeout(ErtsPollSet ps,
+ int resolution,
+ ErtsMonotonicTime timeout_time)
+{
+ ErtsMonotonicTime timeout, save_timeout_time;
+
+ if (timeout_time == ERTS_POLL_NO_TIMEOUT) {
+ save_timeout_time = ERTS_MONOTONIC_TIME_MIN;
+ timeout = 0;
+ }
+ else {
+ ErtsMonotonicTime diff_time, current_time;
+ current_time = erts_get_monotonic_time(NULL);
+ diff_time = timeout_time - current_time;
+ if (diff_time <= 0) {
+ save_timeout_time = ERTS_MONOTONIC_TIME_MIN;
+ timeout = 0;
+ }
+ else {
+ save_timeout_time = current_time;
+ switch (resolution) {
+ case 1000:
+ /* Round up to nearest even milli second */
+ timeout = ERTS_MONOTONIC_TO_MSEC(diff_time - 1) + 1;
+ if (timeout > (ErtsMonotonicTime) INT_MAX)
+ timeout = (ErtsMonotonicTime) INT_MAX;
+ save_timeout_time += ERTS_MSEC_TO_MONOTONIC(timeout);
+ break;
+ case 1000000:
+ /* Round up to nearest even micro second */
+ timeout = ERTS_MONOTONIC_TO_USEC(diff_time - 1) + 1;
+ save_timeout_time += ERTS_USEC_TO_MONOTONIC(timeout);
+ break;
+ case 1000000000:
+ /* Round up to nearest even nano second */
+ timeout = ERTS_MONOTONIC_TO_NSEC(diff_time - 1) + 1;
+ save_timeout_time += ERTS_NSEC_TO_MONOTONIC(timeout);
+ break;
+ default:
+ ERTS_INTERNAL_ERROR("Invalid resolution");
+ timeout = 0;
+ save_timeout_time = 0;
+ break;
+ }
+ }
+ }
+ set_timeout_time(ps, save_timeout_time);
+ return timeout;
+}
+
+#if ERTS_POLL_USE_SELECT
+
+static ERTS_INLINE int
+get_timeout_timeval(ErtsPollSet ps,
+ SysTimeval *tvp,
+ ErtsMonotonicTime timeout_time)
+{
+ ErtsMonotonicTime timeout = get_timeout(ps,
+ 1000*1000,
+ timeout_time);
+
+ if (!timeout) {
+ tvp->tv_sec = 0;
+ tvp->tv_usec = 0;
+
+ return 0;
+ }
+ else {
+ ErtsMonotonicTime sec = timeout/(1000*1000);
+ tvp->tv_sec = sec;
+ tvp->tv_usec = timeout - sec*(1000*1000);
+
+ ASSERT(tvp->tv_sec >= 0);
+ ASSERT(tvp->tv_usec >= 0);
+ ASSERT(tvp->tv_usec < 1000*1000);
+
+ return !0;
+ }
+
+}
+
+#endif
+
+#if ERTS_POLL_USE_KQUEUE || (ERTS_POLL_USE_POLL && defined(HAVE_PPOLL)) || ERTS_POLL_USE_TIMERFD
+
+static ERTS_INLINE int
+get_timeout_timespec(ErtsPollSet ps,
+ struct timespec *tsp,
+ ErtsMonotonicTime timeout_time)
+{
+ ErtsMonotonicTime timeout = get_timeout(ps,
+ 1000*1000*1000,
+ timeout_time);
+
+ if (!timeout) {
+ tsp->tv_sec = 0;
+ tsp->tv_nsec = 0;
+ return 0;
+ }
+ else {
+ ErtsMonotonicTime sec = timeout/(1000*1000*1000);
+ tsp->tv_sec = sec;
+ tsp->tv_nsec = timeout - sec*(1000*1000*1000);
+
+ ASSERT(tsp->tv_sec >= 0);
+ ASSERT(tsp->tv_nsec >= 0);
+ ASSERT(tsp->tv_nsec < 1000*1000*1000);
+
+ return !0;
+ }
+}
+
+#endif
+
+#if ERTS_POLL_USE_TIMERFD
+
static ERTS_INLINE int
-check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res)
+get_timeout_itimerspec(ErtsPollSet ps,
+ struct itimerspec *itsp,
+ ErtsMonotonicTime timeout_time)
+{
+
+ itsp->it_interval.tv_sec = 0;
+ itsp->it_interval.tv_nsec = 0;
+
+ return get_timeout_timespec(ps, &itsp->it_value, timeout_time);
+}
+
+#endif
+
+static ERTS_INLINE int
+check_fd_events(ErtsPollSet ps, ErtsMonotonicTime timeout_time, int max_res)
{
int res;
if (erts_smp_atomic_read_nob(&ps->no_of_user_fds) == 0
- && tv->tv_usec == 0 && tv->tv_sec == 0) {
+ && timeout_time == ERTS_POLL_NO_TIMEOUT) {
/* Nothing to poll and zero timeout; done... */
return 0;
}
else {
- long timeout = tv->tv_sec*1000 + tv->tv_usec/1000;
- if (timeout > ERTS_AINT32_T_MAX)
- timeout = ERTS_AINT32_T_MAX;
- ASSERT(timeout >= 0);
- erts_smp_atomic32_set_relb(&ps->timeout, (erts_aint32_t) timeout);
+ int timeout;
#if ERTS_POLL_USE_FALLBACK
if (!(ps->fallback_used = ERTS_POLL_NEED_FALLBACK(ps))) {
#if ERTS_POLL_USE_EPOLL /* --- epoll ------------------------------- */
- if (timeout > INT_MAX)
- timeout = INT_MAX;
if (max_res > ps->res_events_len)
grow_res_events(ps, max_res);
+#if ERTS_POLL_USE_TIMERFD
+ {
+ struct itimerspec its;
+ timeout = get_timeout_itimerspec(ps, &its, timeout_time);
+ if (timeout) {
+#ifdef ERTS_SMP
+ erts_thr_progress_prepare_wait(NULL);
+#endif
+ timerfd_set(ps, &its);
+ res = epoll_wait(ps->kp_fd, ps->res_events, max_res, -1);
+ res = timerfd_clear(ps, res, max_res);
+ } else {
+ res = epoll_wait(ps->kp_fd, ps->res_events, max_res, 0);
+ }
+ }
+#else /* !ERTS_POLL_USE_TIMERFD */
+ timeout = (int) get_timeout(ps, 1000, timeout_time);
#ifdef ERTS_SMP
if (timeout)
erts_thr_progress_prepare_wait(NULL);
#endif
- res = epoll_wait(ps->kp_fd, ps->res_events, max_res, (int)timeout);
+ res = epoll_wait(ps->kp_fd, ps->res_events, max_res, timeout);
+#endif /* !ERTS_POLL_USE_TIMERFD */
#elif ERTS_POLL_USE_KQUEUE /* --- kqueue ------------------------------ */
struct timespec ts;
if (max_res > ps->res_events_len)
grow_res_events(ps, max_res);
+ timeout = get_timeout_timespec(ps, &ts, timeout_time);
#ifdef ERTS_SMP
if (timeout)
erts_thr_progress_prepare_wait(NULL);
#endif
- ts.tv_sec = tv->tv_sec;
- ts.tv_nsec = tv->tv_usec*1000;
res = kevent(ps->kp_fd, NULL, 0, ps->res_events, max_res, &ts);
#endif /* ----------------------------------------- */
}
@@ -2049,8 +2301,7 @@ check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res)
#if ERTS_POLL_USE_WAKEUP_PIPE
nfds++; /* Wakeup pipe */
#endif
- if (timeout > INT_MAX)
- timeout = INT_MAX;
+ timeout = (int) get_timeout(ps, 1000, timeout_time);
poll_res.dp_nfds = nfds < max_res ? nfds : max_res;
if (poll_res.dp_nfds > ps->res_events_len)
grow_res_events(ps, poll_res.dp_nfds);
@@ -2059,33 +2310,41 @@ check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res)
if (timeout)
erts_thr_progress_prepare_wait(NULL);
#endif
- poll_res.dp_timeout = (int) timeout;
+ poll_res.dp_timeout = timeout;
res = ioctl(ps->kp_fd, DP_POLL, &poll_res);
-#elif ERTS_POLL_USE_POLL /* --- poll -------------------------------- */
- if (timeout > INT_MAX)
- timeout = INT_MAX;
+#elif ERTS_POLL_USE_POLL && defined(HAVE_PPOLL) /* --- ppoll ---------------- */
+ struct timespec ts;
+ timeout = get_timeout_timespec(ps, &ts, timeout_time);
#ifdef ERTS_SMP
if (timeout)
erts_thr_progress_prepare_wait(NULL);
#endif
- res = poll(ps->poll_fds, ps->no_poll_fds, (int) timeout);
+ res = ppoll(ps->poll_fds, ps->no_poll_fds, &ts, NULL);
+#elif ERTS_POLL_USE_POLL /* --- poll --------------------------------- */
+ timeout = (int) get_timeout(ps, 1000, timeout_time);
+#ifdef ERTS_SMP
+ if (timeout)
+ erts_thr_progress_prepare_wait(NULL);
+#endif
+ res = poll(ps->poll_fds, ps->no_poll_fds, timeout);
#elif ERTS_POLL_USE_SELECT /* --- select ------------------------------ */
- SysTimeval to = *tv;
+ SysTimeval to;
+ timeout = get_timeout_timeval(ps, &to, timeout_time);
ERTS_FD_COPY(&ps->input_fds, &ps->res_input_fds);
ERTS_FD_COPY(&ps->output_fds, &ps->res_output_fds);
-
+
#ifdef ERTS_SMP
- if (to.tv_sec || to.tv_usec)
+ if (timeout)
erts_thr_progress_prepare_wait(NULL);
#endif
res = ERTS_SELECT(ps->max_fd + 1,
- &ps->res_input_fds,
- &ps->res_output_fds,
- NULL,
- &to);
+ &ps->res_input_fds,
+ &ps->res_output_fds,
+ NULL,
+ &to);
#ifdef ERTS_SMP
- if (to.tv_sec || to.tv_usec)
+ if (timeout)
erts_thr_progress_finalize_wait(NULL);
if (res < 0
&& errno == EBADF
@@ -2108,10 +2367,10 @@ check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res)
handle_update_requests(ps);
ERTS_POLLSET_UNLOCK(ps);
res = ERTS_SELECT(ps->max_fd + 1,
- &ps->res_input_fds,
- &ps->res_output_fds,
- NULL,
- &to);
+ &ps->res_input_fds,
+ &ps->res_output_fds,
+ NULL,
+ &to);
if (res == 0) {
errno = EAGAIN;
res = -1;
@@ -2133,15 +2392,14 @@ int
ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
ErtsPollResFd pr[],
int *len,
- SysTimeval *utvp)
+ ErtsMonotonicTime timeout_time)
{
+ ErtsMonotonicTime to;
int res, no_fds;
int ebadf = 0;
#ifdef ERTS_SMP
int ps_locked = 0;
#endif
- SysTimeval *tvp;
- SysTimeval itv;
no_fds = *len;
#ifdef ERTS_POLL_MAX_RES
@@ -2151,13 +2409,9 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
*len = 0;
- ASSERT(utvp);
-
- tvp = utvp;
-
#ifdef ERTS_POLL_DEBUG_PRINT
- erts_printf("Entering erts_poll_wait(), timeout=%d\n",
- (int) tvp->tv_sec*1000 + tvp->tv_usec/1000);
+ erts_printf("Entering erts_poll_wait(), timeout_time=%bps\n",
+ timeout_time);
#endif
if (ERTS_POLLSET_SET_POLLED_CHK(ps)) {
@@ -2166,12 +2420,9 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
goto done;
}
- if (is_woken(ps)) {
- /* Use zero timeout */
- itv.tv_sec = 0;
- itv.tv_usec = 0;
- tvp = &itv;
- }
+ to = (is_woken(ps)
+ ? ERTS_POLL_NO_TIMEOUT /* Use zero timeout */
+ : timeout_time);
#if ERTS_POLL_USE_UPDATE_REQUESTS_QUEUE
if (ERTS_POLLSET_HAVE_UPDATE_REQUESTS(ps)) {
@@ -2181,7 +2432,7 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
}
#endif
- res = check_fd_events(ps, tvp, no_fds);
+ res = check_fd_events(ps, to, no_fds);
woke_up(ps);
@@ -2224,7 +2475,7 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
#endif
done:
- erts_smp_atomic32_set_relb(&ps->timeout, ERTS_AINT32_T_MAX);
+ set_timeout_time(ps, ERTS_MONOTONIC_TIME_MAX);
#ifdef ERTS_POLL_DEBUG_PRINT
erts_printf("Leaving %s = erts_poll_wait()\n",
res == 0 ? "0" : erl_errno_id(res));
@@ -2268,13 +2519,14 @@ ERTS_POLL_EXPORT(erts_poll_async_sig_interrupt)(ErtsPollSet ps)
void
ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet ps,
int set,
- erts_short_time_t msec)
+ ErtsMonotonicTime timeout_time)
{
#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT || defined(ERTS_SMP)
if (!set)
reset_wakeup_state(ps);
else {
- if (erts_smp_atomic32_read_acqb(&ps->timeout) > (erts_aint32_t) msec)
+ ErtsMonotonicTime max_wait_time = get_timeout_time(ps);
+ if (max_wait_time > timeout_time)
wake_poller(ps, 1, 0);
#ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS
else {
@@ -2414,6 +2666,9 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(void)
#if ERTS_POLL_USE_WAKEUP_PIPE
create_wakeup_pipe(ps);
#endif
+#if ERTS_POLL_USE_TIMERFD
+ create_timerfd(ps);
+#endif
#if ERTS_POLL_USE_FALLBACK
if (kp_fd >= ps->fds_status_len)
grow_fds_status(ps, kp_fd);
@@ -2431,7 +2686,7 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(void)
ps->internal_fd_limit = kp_fd + 1;
ps->kp_fd = kp_fd;
#endif
- erts_smp_atomic32_init_nob(&ps->timeout, ERTS_AINT32_T_MAX);
+ init_timeout_time(ps);
#ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS
erts_smp_atomic_init_nob(&ps->no_avoided_wakeups, 0);
erts_smp_atomic_init_nob(&ps->no_avoided_interrupts, 0);
@@ -2504,6 +2759,10 @@ ERTS_POLL_EXPORT(erts_poll_destroy_pollset)(ErtsPollSet ps)
if (ps->wake_fds[1] >= 0)
close(ps->wake_fds[1]);
#endif
+#if ERTS_POLL_USE_TIMERFD
+ if (ps->timer_fd >= 0)
+ close(ps->timer_fd);
+#endif
erts_smp_spin_lock(&pollsets_lock);
if (ps == pollsets)
@@ -2608,6 +2867,9 @@ ERTS_POLL_EXPORT(erts_poll_info)(ErtsPollSet ps, ErtsPollInfo *pip)
#if ERTS_POLL_USE_WAKEUP_PIPE
pip->poll_set_size++; /* Wakeup pipe */
#endif
+#if ERTS_POLL_USE_TIMERFD
+ pip->poll_set_size++; /* timerfd */
+#endif
pip->fallback_poll_set_size =
#if !ERTS_POLL_USE_FALLBACK
@@ -2736,14 +2998,18 @@ ERTS_POLL_EXPORT(erts_poll_get_selected_events)(ErtsPollSet ps,
ev[fd] = 0;
else {
ev[fd] = ps->fds_status[fd].events;
+ if (
#if ERTS_POLL_USE_WAKEUP_PIPE
- if (fd == ps->wake_fds[0] || fd == ps->wake_fds[1])
- ev[fd] |= ERTS_POLL_EV_NVAL;
+ fd == ps->wake_fds[0] || fd == ps->wake_fds[1] ||
+#endif
+#if ERTS_POLL_USE_TIMERFD
+ fd == ps->timer_fd ||
#endif
#if ERTS_POLL_USE_KERNEL_POLL
- if (fd == ps->kp_fd)
- ev[fd] |= ERTS_POLL_EV_NVAL;
+ fd == ps->kp_fd ||
#endif
+ 0)
+ ev[fd] |= ERTS_POLL_EV_NVAL;
}
}
ERTS_POLLSET_UNLOCK(ps);
diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h
index 2f1c05f401..bd3a46ef0f 100644
--- a/erts/emulator/sys/common/erl_poll.h
+++ b/erts/emulator/sys/common/erl_poll.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -29,6 +30,8 @@
#include "sys.h"
+#define ERTS_POLL_NO_TIMEOUT ERTS_MONOTONIC_TIME_MIN
+
#if 0
#define ERTS_POLL_COUNT_AVOIDED_WAKEUPS
#endif
@@ -96,6 +99,8 @@
# endif
#endif
+#define ERTS_POLL_USE_TIMERFD 0
+
typedef Uint32 ErtsPollEvents;
#undef ERTS_POLL_EV_E2N
@@ -128,8 +133,14 @@ struct erts_sys_fd_type {
#include <sys/epoll.h>
+#ifdef HAVE_SYS_TIMERFD_H
+#include <sys/timerfd.h>
+#undef ERTS_POLL_USE_TIMERFD
+#define ERTS_POLL_USE_TIMERFD 1
+#endif
+
#define ERTS_POLL_EV_E2N(EV) \
- ((__uint32_t) (EV))
+ ((uint32_t) (EV))
#define ERTS_POLL_EV_N2E(EV) \
((ErtsPollEvents) (EV))
@@ -241,7 +252,7 @@ void ERTS_POLL_EXPORT(erts_poll_interrupt)(ErtsPollSet,
int);
void ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet,
int,
- erts_short_time_t);
+ ErtsMonotonicTime);
ErtsPollEvents ERTS_POLL_EXPORT(erts_poll_control)(ErtsPollSet,
ErtsSysFdType,
ErtsPollEvents,
@@ -254,7 +265,7 @@ void ERTS_POLL_EXPORT(erts_poll_controlv)(ErtsPollSet,
int ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet,
ErtsPollResFd [],
int *,
- SysTimeval *);
+ ErtsMonotonicTime);
int ERTS_POLL_EXPORT(erts_poll_max_fds)(void);
void ERTS_POLL_EXPORT(erts_poll_info)(ErtsPollSet,
ErtsPollInfo *);
@@ -265,6 +276,6 @@ void ERTS_POLL_EXPORT(erts_poll_get_selected_events)(ErtsPollSet,
ErtsPollEvents [],
int);
-int ERTS_POLL_EXPORT(erts_poll_get_table_len)(int);
+int erts_poll_new_table_len(int old_len, int need_len);
#endif /* #ifndef ERL_POLL_H__ */
diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c
index e63f0bda54..e292741bfa 100644
--- a/erts/emulator/sys/common/erl_sys_common_misc.c
+++ b/erts/emulator/sys/common/erl_sys_common_misc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/common/erl_util_queue.h b/erts/emulator/sys/common/erl_util_queue.h
index 47925e2264..b50e062dd5 100644
--- a/erts/emulator/sys/common/erl_util_queue.h
+++ b/erts/emulator/sys/common/erl_util_queue.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/ose/driver_int.h b/erts/emulator/sys/ose/driver_int.h
index 2c9ac955d8..4a5b7171d1 100644
--- a/erts/emulator/sys/ose/driver_int.h
+++ b/erts/emulator/sys/ose/driver_int.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/ose/erl_main.c b/erts/emulator/sys/ose/erl_main.c
index 23a9bc93a4..877e85f43a 100644
--- a/erts/emulator/sys/ose/erl_main.c
+++ b/erts/emulator/sys/ose/erl_main.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/ose/erl_ose_sys.h b/erts/emulator/sys/ose/erl_ose_sys.h
index cd66d95c26..d0cd3180bf 100644
--- a/erts/emulator/sys/ose/erl_ose_sys.h
+++ b/erts/emulator/sys/ose/erl_ose_sys.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
@@ -112,6 +113,8 @@ extern clock_t sys_times(SysTimes *buffer);
/* No use in having other resolutions than 1 Ms. */
#define SYS_CLOCK_RESOLUTION 1
+#define erts_isfinite finite
+
#ifdef NO_FPE_SIGNALS
#define erts_get_current_fp_exception() NULL
diff --git a/erts/emulator/sys/ose/erl_ose_sys_ddll.c b/erts/emulator/sys/ose/erl_ose_sys_ddll.c
index ebd80deeaf..5051f7fcc1 100644
--- a/erts/emulator/sys/ose/erl_ose_sys_ddll.c
+++ b/erts/emulator/sys/ose/erl_ose_sys_ddll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/ose/erl_poll.c b/erts/emulator/sys/ose/erl_poll.c
index 7d2a3d1e0b..c690f08dea 100644
--- a/erts/emulator/sys/ose/erl_poll.c
+++ b/erts/emulator/sys/ose/erl_poll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -114,7 +115,7 @@ struct ErtsPollSet_ {
Uint item_count;
PROCESS interrupt;
erts_atomic32_t wakeup_state;
- erts_smp_atomic32_t timeout;
+ erts_atomic64_t timeout_time;
#ifdef ERTS_SMP
erts_smp_mtx_t mtx;
#endif
@@ -122,6 +123,26 @@ struct ErtsPollSet_ {
static int max_fds = -1;
+static ERTS_INLINE void
+init_timeout_time(ErtsPollSet ps)
+{
+ erts_atomic64_init_nob(&ps->timeout_time,
+ (erts_aint64_t) ERTS_MONOTONIC_TIME_MAX);
+}
+
+static ERTS_INLINE void
+set_timeout_time(ErtsPollSet ps, ErtsMonotonicTime time)
+{
+ erts_atomic64_set_relb(&ps->timeout_time,
+ (erts_aint64_t) time);
+}
+
+static ERTS_INLINE ErtsMonotonicTime
+get_timeout_time(ErtsPollSet ps)
+{
+ return (ErtsMonotonicTime) erts_atomic64_read_acqb(&ps->timeout_time);
+}
+
#define ERTS_POLL_NOT_WOKEN ((erts_aint32_t) (1 << 0))
#define ERTS_POLL_WOKEN_INTR ((erts_aint32_t) (1 << 1))
#define ERTS_POLL_WOKEN_TIMEDOUT ((erts_aint32_t) (1 << 2))
@@ -386,12 +407,14 @@ void erts_poll_interrupt(ErtsPollSet ps,int set) {
}
-void erts_poll_interrupt_timed(ErtsPollSet ps,int set,erts_short_time_t msec) {
+void erts_poll_interrupt_timed(ErtsPollSet ps,
+ int set,
+ ErtsTimeoutTime timeout_time) {
HARDTRACEF("erts_poll_interrupt_timed called!\n");
if (!set)
reset_interrupt(ps);
- else if (erts_smp_atomic32_read_acqb(&ps->timeout) > (erts_aint32_t) msec)
+ else if (get_timeout_time(ps) > timeout_time)
set_interrupt(ps);
}
@@ -453,12 +476,14 @@ done:
}
int erts_poll_wait(ErtsPollSet ps,
- ErtsPollResFd pr[],
- int *len,
- SysTimeval *utvp) {
+ ErtsPollResFd pr[],
+ int *len,
+ ErtsMonotonicTime timeout_time)
+{
int res = ETIMEDOUT, no_fds, currid = 0;
OSTIME timeout;
union SIGNAL *sig;
+ ErtsMonotonicTime current_time, diff_time, timeout;
// HARDTRACEF("%ux: In erts_poll_wait",ps);
if (ps->interrupt == (PROCESS)0)
ps->interrupt = current_process();
@@ -472,16 +497,29 @@ int erts_poll_wait(ErtsPollSet ps,
*len = 0;
- ASSERT(utvp);
-
- /* erts_printf("Entering erts_poll_wait(), timeout=%d\n",
- (int) utvp->tv_sec*1000 + utvp->tv_usec/1000); */
+ /* erts_printf("Entering erts_poll_wait(), timeout_time=%bps\n",
+ timeout_time); */
- timeout = utvp->tv_sec*1000 + utvp->tv_usec/1000;
+ if (timeout_time == ERTS_POLL_NO_TIMEOUT) {
+ no_timeout:
+ timeout = (OSTIME) 0;
+ save_timeout_time = ERTS_MONOTONIC_TIME_MIN;
+ }
+ else {
+ ErtsMonotonicTime current_time, diff_time;
+ current_time = erts_get_monotonic_time(NULL);
+ diff_time = timeout_time - current_time;
+ if (diff_time <= 0)
+ goto no_timeout;
+ diff_time = (ERTS_MONOTONIC_TO_MSEC(diff_time - 1) + 1);
+ if (diff_time > INT_MAX)
+ diff_time = INT_MAX;
+ timeout = (OSTIME) diff_time;
+ save_timeout_time = current_time;
+ save_timeout_time += ERTS_MSEC_TO_MONOTONIC(diff_time);
+ }
- if (timeout > ((time_t) ERTS_AINT32_T_MAX))
- timeout = ERTS_AINT32_T_MAX;
- erts_smp_atomic32_set_relb(&ps->timeout, (erts_aint32_t) timeout);
+ set_timeout_time(ps, save_timeout_time);
while (currid < no_fds) {
if (timeout > 0) {
@@ -620,14 +658,14 @@ int erts_poll_wait(ErtsPollSet ps,
break;
default:
res = 0;
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d: Internal error: Invalid wakeup_state=%d\n",
__FILE__, __LINE__, (int) wakeup_state);
}
}
erts_atomic32_set_nob(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN);
- erts_smp_atomic32_set_nob(&ps->timeout, ERTS_AINT32_T_MAX);
+ set_timeout_time(ps, ERTS_MONOTONIC_TIME_MAX);
*len = currid;
@@ -690,7 +728,7 @@ ErtsPollSet erts_poll_create_pollset(void)
ps->info = NULL;
ps->interrupt = (PROCESS)0;
erts_atomic32_init_nob(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN);
- erts_smp_atomic32_init_nob(&ps->timeout, ERTS_AINT32_T_MAX);
+ init_timeout_time(ps);
#ifdef ERTS_SMP
erts_smp_mtx_init(&ps->mtx, "pollset");
#endif
diff --git a/erts/emulator/sys/ose/sys.c b/erts/emulator/sys/ose/sys.c
index 5b950a7dae..e354faf02c 100644
--- a/erts/emulator/sys/ose/sys.c
+++ b/erts/emulator/sys/ose/sys.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -298,9 +299,9 @@ erts_sys_schedule_interrupt(int set)
#ifdef ERTS_SMP
void
-erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec)
+erts_sys_schedule_interrupt_timed(int set, ErtsMonotonicTime timeout_time)
{
- ERTS_CHK_IO_INTR_TMD(set, msec);
+ ERTS_CHK_IO_INTR_TMD(set, timeout_time);
}
#endif
@@ -569,7 +570,7 @@ break_requested(void)
fprintf(stderr,"break!\n");
#endif
if (ERTS_BREAK_REQUESTED)
- erl_exit(ERTS_INTR_EXIT, "");
+ erts_exit(ERTS_INTR_EXIT, "");
ERTS_SET_BREAK_REQUESTED;
ERTS_CHK_IO_AS_INTR(); /* Make sure we don't sleep in poll */
diff --git a/erts/emulator/sys/ose/sys_float.c b/erts/emulator/sys/ose/sys_float.c
index d9d6bb7c04..51875792ae 100644
--- a/erts/emulator/sys/ose/sys_float.c
+++ b/erts/emulator/sys/ose/sys_float.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -89,7 +90,7 @@ void erts_fp_check_init_error(volatile unsigned long *fpexnp)
snprintf(buf, sizeof buf, "ERTS_FP_CHECK_INIT at %p: detected unhandled FPE at %p\r\n",
__builtin_return_address(0), (void*)*fpexnp);
if (write(2, buf, strlen(buf)) <= 0)
- erl_exit(ERTS_ABORT_EXIT, "%s", buf);
+ erts_exit(ERTS_ABORT_EXIT, "%s", buf);
*fpexnp = 0;
#if defined(__i386__) || defined(__x86_64__)
erts_restore_fpu();
diff --git a/erts/emulator/sys/ose/sys_time.c b/erts/emulator/sys/ose/sys_time.c
index 7e96f68424..5dac75956a 100644
--- a/erts/emulator/sys/ose/sys_time.c
+++ b/erts/emulator/sys/ose/sys_time.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/unix/driver_int.h b/erts/emulator/sys/unix/driver_int.h
index a7ee8087ab..a6b9085245 100644
--- a/erts/emulator/sys/unix/driver_int.h
+++ b/erts/emulator/sys/unix/driver_int.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c
index 5ad92dad02..a3c5c20641 100644
--- a/erts/emulator/sys/unix/erl_child_setup.c
+++ b/erts/emulator/sys/unix/erl_child_setup.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -55,7 +56,7 @@ void sys_sigrelease(int sig)
#endif /* !SIG_SIGSET */
#if defined(__ANDROID__)
-int __system_properties_fd(void);
+static int system_properties_fd(void);
#endif /* __ANDROID__ */
#if defined(__ANDROID__)
@@ -104,14 +105,19 @@ main(int argc, char *argv[])
#if defined(HAVE_CLOSEFROM)
closefrom(from);
#elif defined(__ANDROID__)
- for (i = from; i <= to; i++) {
- if (i!=__system_properties_fd)
- (void) close(i);
+ if (from <= to) {
+ int spfd = system_properties_fd();
+ for (i = from; i <= to; i++) {
+ if (i != spfd) {
+ (void) close(i);
+ }
+ }
}
-#else
- for (i = from; i <= to; i++)
+#else /* !__ANDROID__ */
+ for (i = from; i <= to; i++) {
(void) close(i);
-#endif
+ }
+#endif /* HAVE_CLOSEFROM */
if (!(argv[CS_ARGV_WD_IX][0] == '.' && argv[CS_ARGV_WD_IX][1] == '\0')
&& chdir(argv[CS_ARGV_WD_IX]) < 0)
@@ -143,9 +149,9 @@ main(int argc, char *argv[])
}
#if defined(__ANDROID__)
-int __system_properties_fd(void)
+static int system_properties_fd(void)
{
- int s, fd;
+ int fd;
char *env;
env = getenv("ANDROID_PROPERTY_WORKSPACE");
@@ -156,4 +162,3 @@ int __system_properties_fd(void)
return fd;
}
#endif /* __ANDROID__ */
-
diff --git a/erts/emulator/sys/unix/erl_main.c b/erts/emulator/sys/unix/erl_main.c
index b26f93f77e..c417bea622 100644
--- a/erts/emulator/sys/unix/erl_main.c
+++ b/erts/emulator/sys/unix/erl_main.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 26ed2fb558..8d4e98bf3a 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
@@ -45,7 +46,7 @@
#include <fcntl.h>
#include "erl_errno.h"
#include <signal.h>
-
+#include <setjmp.h>
#if HAVE_SYS_SOCKETIO_H
# include <sys/socketio.h>
@@ -114,11 +115,6 @@
/*
* Make sure that MAXPATHLEN is defined.
*/
-#ifdef GETHRTIME_WITH_CLOCK_GETTIME
-#undef HAVE_GETHRTIME
-#define HAVE_GETHRTIME 1
-#endif
-
#ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
@@ -160,35 +156,134 @@ typedef struct timeval SysTimeval;
typedef struct tms SysTimes;
-extern int erts_ticks_per_sec;
-
-#define SYS_CLK_TCK (erts_ticks_per_sec)
+#define SYS_CLK_TCK (erts_sys_time_data__.r.o.ticks_per_sec)
#define sys_times(Arg) times(Arg)
-#define ERTS_WRAP_SYS_TIMES 1
-extern int erts_ticks_per_sec_wrap;
-#define SYS_CLK_TCK_WRAP (erts_ticks_per_sec_wrap)
-extern clock_t sys_times_wrap(void);
+#if SIZEOF_LONG == 8
+typedef long ErtsMonotonicTime;
+typedef long ErtsSysHrTime;
+#elif SIZEOF_LONG_LONG == 8
+typedef long long ErtsMonotonicTime;
+typedef long long ErtsSysHrTime;
+#else
+#error No signed 64-bit type found...
+#endif
-#ifdef HAVE_GETHRTIME
-#ifdef GETHRTIME_WITH_CLOCK_GETTIME
-typedef long long SysHrTime;
+typedef ErtsMonotonicTime ErtsSystemTime;
-extern SysHrTime sys_gethrtime(void);
-#define sys_init_hrtime() /* Nothing */
+#define ERTS_MONOTONIC_TIME_MIN (((ErtsMonotonicTime) 1) << 63)
+#define ERTS_MONOTONIC_TIME_MAX (~ERTS_MONOTONIC_TIME_MIN)
-#else /* Real gethrtime (Solaris) */
+/*
+ * OS monotonic time and OS system time
+ */
+#undef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) \
+ && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+# if defined(__linux__)
+# define ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__ 1
+# endif
+#endif
-typedef hrtime_t SysHrTime;
+ErtsSystemTime erts_os_system_time(void);
-#define sys_gethrtime() gethrtime()
-#define sys_init_hrtime() /* Nothing */
+#undef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+#undef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
+#undef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
-#endif /* GETHRTIME_WITH_CLOCK_GETTIME */
-#endif /* HAVE_GETHRTIME */
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
+# if defined(__linux__)
+# define ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__ 1
+# endif
+#elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
+#elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
+#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+/* Time unit determined at runtime... */
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT 0
+#else /* No OS monotonic available... */
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000)
+#endif
+
+/*
+ * erts_sys_hrtime() is the highest resolution
+ * time function found. Time unit is nano-seconds.
+ * It may or may not be monotonic.
+ */
+ErtsSysHrTime erts_sys_hrtime(void);
+
+struct erts_sys_time_read_only_data__ {
+#ifdef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
+ ErtsMonotonicTime (*os_monotonic_time)(void);
+#endif
+#ifdef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+ void (*os_times)(ErtsMonotonicTime *, ErtsSystemTime *);
+#endif
+ int ticks_per_sec;
+};
+
+typedef struct {
+ union {
+ struct erts_sys_time_read_only_data__ o;
+ char align__[(((sizeof(struct erts_sys_time_read_only_data__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } r;
+} ErtsSysTimeData__;
+
+extern ErtsSysTimeData__ erts_sys_time_data__;
+
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+
+#ifdef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
+ERTS_GLB_INLINE
+#endif
+ErtsMonotonicTime erts_os_monotonic_time(void);
-#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME))
+#ifdef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+ERTS_GLB_INLINE
+#endif
+void erts_os_times(ErtsMonotonicTime *, ErtsSystemTime *);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+#ifdef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
+
+ERTS_GLB_INLINE ErtsMonotonicTime
+erts_os_monotonic_time(void)
+{
+ return (*erts_sys_time_data__.r.o.os_monotonic_time)();
+}
+
+#endif /* ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__ */
+
+#ifdef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+
+ERTS_GLB_INLINE void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ return (*erts_sys_time_data__.r.o.os_times)(mtimep, stimep);
+}
+
+#endif /* ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__ */
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
+#endif /* ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT */
+
+/*
+ *
+ */
+
+#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME_CPU_TIME))
typedef long long SysCpuTime;
typedef struct timespec SysTimespec;
@@ -200,7 +295,7 @@ typedef struct timespec SysTimespec;
int sys_start_hrvtime(void);
int sys_stop_hrvtime(void);
-#elif defined(HAVE_CLOCK_GETTIME)
+#elif defined(HAVE_CLOCK_GETTIME_CPU_TIME)
#define sys_clock_gettime(cid,tp) clock_gettime((cid),&(tp))
#define sys_get_proc_cputime(t,tp) sys_clock_gettime(CLOCK_PROCESS_CPUTIME_ID,(tp))
@@ -211,13 +306,8 @@ int sys_stop_hrvtime(void);
#define SYS_CLOCK_RESOLUTION 1
/* These are defined in sys.c */
-#if defined(SIG_SIGSET) /* Old SysV */
-RETSIGTYPE (*sys_sigset())();
-#elif defined(SIG_SIGNAL) /* Old BSD */
-RETSIGTYPE (*sys_sigset())();
-#else
-RETSIGTYPE (*sys_sigset(int, RETSIGTYPE (*func)(int)))(int);
-#endif
+typedef void (*SIGFUNC)(int);
+extern SIGFUNC sys_signal(int, SIGFUNC);
extern void sys_sigrelease(int);
extern void sys_sigblock(int);
extern void sys_stop_cat(void);
@@ -247,6 +337,8 @@ extern void sys_stop_cat(void);
# define HAVE_ISFINITE
#endif
+#define erts_isfinite isfinite
+
#ifdef NO_FPE_SIGNALS
#define erts_get_current_fp_exception() NULL
@@ -354,4 +446,28 @@ extern int exit_async(void);
#define ERTS_EXIT_AFTER_DUMP _exit
+#if !defined(__APPLE__) && !defined(__MACH__)
+/* Some OS X versions do not allow (ab)using signal handlers like this */
+#define ERTS_HAVE_TRY_CATCH 1
+
+/* We try to simulate a try catch in C with the help of signal handlers.
+ * Only use this as a very last resort, as it is not very portable and
+ * quite unstable. It is also not thread safe, so make sure that only
+ * one thread can call this at a time!
+ */
+extern void erts_sys_sigsegv_handler(int);
+extern jmp_buf erts_sys_sigsegv_jmp;
+#define ERTS_SYS_TRY_CATCH(EXPR,CATCH) \
+ do { \
+ SIGFUNC prev_handler = sys_signal(SIGSEGV, \
+ erts_sys_sigsegv_handler); \
+ if (!setjmp(erts_sys_sigsegv_jmp)) { \
+ EXPR; \
+ } else { \
+ CATCH; \
+ } \
+ sys_signal(SIGSEGV,prev_handler); \
+ } while(0)
+#endif
+
#endif /* #ifndef _ERL_UNIX_SYS_H */
diff --git a/erts/emulator/sys/unix/erl_unix_sys_ddll.c b/erts/emulator/sys/unix/erl_unix_sys_ddll.c
index 2659d623c7..daed5af1b6 100644
--- a/erts/emulator/sys/unix/erl_unix_sys_ddll.c
+++ b/erts/emulator/sys/unix/erl_unix_sys_ddll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index cd87b320e2..d94b37430e 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -34,6 +35,7 @@
#include <termios.h>
#include <ctype.h>
#include <sys/utsname.h>
+#include <sys/select.h>
#ifdef ISC32
#include <sys/bsdtypes.h>
@@ -85,14 +87,24 @@ static erts_smp_rwmtx_t environ_rwmtx;
#define DISABLE_VFORK 0
#endif
+#if defined IOV_MAX
+#define MAXIOV IOV_MAX
+#elif defined UIO_MAXIOV
+#define MAXIOV UIO_MAXIOV
+#else
+#define MAXIOV 16
+#endif
+
#ifdef USE_THREADS
# ifdef ENABLE_CHILD_WAITER_THREAD
# define CHLDWTHR ENABLE_CHILD_WAITER_THREAD
# else
# define CHLDWTHR 0
# endif
+# define FDBLOCK 1
#else
# define CHLDWTHR 0
+# define FDBLOCK 0
#endif
/*
* [OTP-3906]
@@ -121,6 +133,15 @@ struct ErtsSysReportExit_ {
#endif
};
+/* Used by the fd driver iff the fd could not be set to non-blocking */
+typedef struct ErtsSysBlocking_ {
+ ErlDrvPDL pdl;
+ int res;
+ int err;
+ unsigned int pkey;
+} ErtsSysBlocking;
+
+
/* This data is shared by these drivers - initialized by spawn_init() */
static struct driver_data {
ErlDrvPort port_num;
@@ -129,6 +150,8 @@ static struct driver_data {
int pid;
int alive;
int status;
+ int terminating;
+ ErtsSysBlocking *blocking;
} *driver_data; /* indexed by fd */
static ErtsSysReportExit *report_exit_list;
@@ -202,8 +225,14 @@ static erts_smp_atomic_t sys_misc_mem_sz;
#if defined(ERTS_SMP)
static void smp_sig_notify(char c);
static int sig_notify_fds[2] = {-1, -1};
+
+static int sig_suspend_fds[2] = {-1, -1};
+#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
+
#endif
+jmp_buf erts_sys_sigsegv_jmp;
+
#if CHLDWTHR || defined(ERTS_SMP)
erts_mtx_t chld_stat_mtx;
#endif
@@ -280,7 +309,7 @@ struct {
int (*event)(ErlDrvPort, ErlDrvEvent, ErlDrvEventData);
void (*check_io_as_interrupt)(void);
void (*check_io_interrupt)(int);
- void (*check_io_interrupt_tmd)(int, erts_short_time_t);
+ void (*check_io_interrupt_tmd)(int, ErtsMonotonicTime);
void (*check_io)(int);
Uint (*size)(void);
Eterm (*info)(void *);
@@ -386,9 +415,9 @@ erts_sys_schedule_interrupt(int set)
#ifdef ERTS_SMP
void
-erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec)
+erts_sys_schedule_interrupt_timed(int set, ErtsMonotonicTime timeout_time)
{
- ERTS_CHK_IO_INTR_TMD(set, msec);
+ ERTS_CHK_IO_INTR_TMD(set, timeout_time);
}
#endif
@@ -504,11 +533,14 @@ thr_create_prepare_child(void *vtcdp)
void
erts_sys_pre_init(void)
{
+#ifdef USE_THREADS
+ erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER;
+#endif
+
erts_printf_add_cr_to_stdout = 1;
erts_printf_add_cr_to_stderr = 1;
+
#ifdef USE_THREADS
- {
- erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER;
eid.thread_create_child_func = thr_create_prepare_child;
/* Before creation in parent */
@@ -531,6 +563,12 @@ erts_sys_pre_init(void)
erts_lcnt_init();
#endif
+#endif /* USE_THREADS */
+
+ erts_init_sys_time_sup();
+
+#ifdef USE_THREADS
+
#if CHLDWTHR || defined(ERTS_SMP)
erts_mtx_init(&chld_stat_mtx, "child_status");
#endif
@@ -541,7 +579,7 @@ erts_sys_pre_init(void)
erts_cnd_init(&chld_stat_cnd);
children_alive = 0;
#endif
- }
+
#ifdef ERTS_SMP
erts_smp_atomic32_init_nob(&erts_break_requested, 0);
erts_smp_atomic32_init_nob(&erts_got_sigusr1, 0);
@@ -554,7 +592,9 @@ erts_sys_pre_init(void)
#if !CHLDWTHR && !defined(ERTS_SMP)
children_died = 0;
#endif
+
#endif /* USE_THREADS */
+
erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0);
{
@@ -598,14 +638,14 @@ erl_sys_init(void)
res = erts_sys_getenv_raw("BINDIR", bindir, &bindirsz);
if (res != 0) {
if (res < 0)
- erl_exit(-1,
+ erts_exit(1,
"Environment variable BINDIR is not set\n");
if (res > 0)
- erl_exit(-1,
+ erts_exit(1,
"Value of environment variable BINDIR is too large\n");
}
if (bindir[0] != DIR_SEPARATOR_CHAR)
- erl_exit(-1,
+ erts_exit(1,
"Environment variable BINDIR does not contain an"
" absolute path\n");
csp_path_sz = (strlen(bindir)
@@ -640,39 +680,7 @@ erl_sys_init(void)
/* signal handling */
-#ifdef SIG_SIGSET /* Old SysV */
-RETSIGTYPE (*sys_sigset(sig, func))()
-int sig;
-RETSIGTYPE (*func)();
-{
- return(sigset(sig, func));
-}
-void sys_sigblock(int sig)
-{
- sighold(sig);
-}
-void sys_sigrelease(int sig)
-{
- sigrelse(sig);
-}
-#else /* !SIG_SIGSET */
-#ifdef SIG_SIGNAL /* Old BSD */
-RETSIGTYPE (*sys_sigset(sig, func))(int, int)
-int sig;
-RETSIGTYPE (*func)();
-{
- return(signal(sig, func));
-}
-sys_sigblock(int sig)
-{
- sigblock(sig);
-}
-sys_sigrelease(int sig)
-{
- sigsetmask(sigblock(0) & ~sigmask(sig));
-}
-#else /* !SIG_SIGNAL */ /* The True Way - POSIX!:-) */
-RETSIGTYPE (*sys_sigset(int sig, RETSIGTYPE (*func)(int)))(int)
+SIGFUNC sys_signal(int sig, SIGFUNC func)
{
struct sigaction act, oact;
@@ -705,23 +713,35 @@ void sys_sigrelease(int sig)
sigaddset(&mask, sig);
sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)NULL);
}
-#endif /* !SIG_SIGNAL */
-#endif /* !SIG_SIGSET */
-#if (0) /* not used? -- gordon */
-static void (*break_func)();
-static RETSIGTYPE break_handler(int sig)
-{
-#ifdef QNX
- /* Turn off SIGCHLD during break processing */
- sys_sigblock(SIGCHLD);
-#endif
- (*break_func)();
-#ifdef QNX
- sys_sigrelease(SIGCHLD);
-#endif
+void erts_sys_sigsegv_handler(int signo) {
+ if (signo == SIGSEGV) {
+ longjmp(erts_sys_sigsegv_jmp, 1);
+ }
+}
+
+/*
+ * Function returns 1 if we can read from all values in between
+ * start and stop.
+ */
+int
+erts_sys_is_area_readable(char *start, char *stop) {
+ int fds[2];
+ if (!pipe(fds)) {
+ /* We let write try to figure out if the pointers are readable */
+ int res = write(fds[1], start, (char*)stop - (char*)start);
+ if (res == -1) {
+ close(fds[0]);
+ close(fds[1]);
+ return 0;
+ }
+ close(fds[0]);
+ close(fds[1]);
+ return 1;
+ }
+ return 0;
+
}
-#endif /* 0 */
static ERTS_INLINE int
prepare_crash_dump(int secs)
@@ -805,7 +825,7 @@ break_requested(void)
fprintf(stderr,"break!\n");
#endif
if (ERTS_BREAK_REQUESTED)
- erl_exit(ERTS_INTR_EXIT, "");
+ erts_exit(ERTS_INTR_EXIT, "");
ERTS_SET_BREAK_REQUESTED;
ERTS_CHK_IO_AS_INTR(); /* Make sure we don't sleep in poll */
@@ -844,14 +864,28 @@ sigusr1_exit(void)
}
prepare_crash_dump(secs);
- erl_exit(1, "Received SIGUSR1\n");
+ erts_exit(ERTS_ERROR_EXIT, "Received SIGUSR1\n");
}
#ifdef ETHR_UNUSABLE_SIGUSRX
#warning "Unusable SIGUSR1 & SIGUSR2. Disabling use of these signals"
-#endif
-#ifndef ETHR_UNUSABLE_SIGUSRX
+#else
+
+#ifdef ERTS_SMP
+void
+sys_thr_suspend(erts_tid_t tid) {
+ erts_thr_kill(tid, ERTS_SYS_SUSPEND_SIGNAL);
+}
+
+void
+sys_thr_resume(erts_tid_t tid) {
+ int i = 0, res;
+ do {
+ res = write(sig_suspend_fds[1],&i,sizeof(i));
+ } while (res < 0 && errno == EAGAIN);
+}
+#endif
#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
static RETSIGTYPE user_signal1(void)
@@ -866,27 +900,27 @@ static RETSIGTYPE user_signal1(int signum)
#endif
}
-#ifdef QUANTIFY
+#ifdef ERTS_SMP
#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
-static RETSIGTYPE user_signal2(void)
+static RETSIGTYPE suspend_signal(void)
#else
-static RETSIGTYPE user_signal2(int signum)
+static RETSIGTYPE suspend_signal(int signum)
#endif
{
-#ifdef ERTS_SMP
- smp_sig_notify('2');
-#else
- quantify_save_data();
-#endif
+ int res;
+ int buf[1];
+ do {
+ res = read(sig_suspend_fds[0], buf, sizeof(int));
+ } while (res < 0 && errno == EINTR);
}
-#endif
+#endif /* #ifdef ERTS_SMP */
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
static void
quit_requested(void)
{
- erl_exit(ERTS_INTR_EXIT, "");
+ erts_exit(ERTS_INTR_EXIT, "");
}
#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
@@ -904,9 +938,9 @@ static RETSIGTYPE do_quit(int signum)
/* Disable break */
void erts_set_ignore_break(void) {
- sys_sigset(SIGINT, SIG_IGN);
- sys_sigset(SIGQUIT, SIG_IGN);
- sys_sigset(SIGTSTP, SIG_IGN);
+ sys_signal(SIGINT, SIG_IGN);
+ sys_signal(SIGQUIT, SIG_IGN);
+ sys_signal(SIGTSTP, SIG_IGN);
}
/* Don't use ctrl-c for break handler but let it be
@@ -929,14 +963,14 @@ void erts_replace_intr(void) {
void init_break_handler(void)
{
- sys_sigset(SIGINT, request_break);
+ sys_signal(SIGINT, request_break);
#ifndef ETHR_UNUSABLE_SIGUSRX
- sys_sigset(SIGUSR1, user_signal1);
-#ifdef QUANTIFY
- sys_sigset(SIGUSR2, user_signal2);
-#endif
+ sys_signal(SIGUSR1, user_signal1);
+#ifdef ERTS_SMP
+ sys_signal(ERTS_SYS_SUSPEND_SIGNAL, suspend_signal);
+#endif /* #ifdef ERTS_SMP */
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
- sys_sigset(SIGQUIT, do_quit);
+ sys_signal(SIGQUIT, do_quit);
}
int sys_max_files(void)
@@ -953,8 +987,13 @@ static void block_signals(void)
sys_sigblock(SIGINT);
#ifndef ETHR_UNUSABLE_SIGUSRX
sys_sigblock(SIGUSR1);
+#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
+#endif /* #ifndef ERTS_SMP */
+
+#if defined(ERTS_SMP) && !defined(ETHR_UNUSABLE_SIGUSRX)
+ sys_sigblock(ERTS_SYS_SUSPEND_SIGNAL);
#endif
-#endif
+
}
static void unblock_signals(void)
@@ -968,26 +1007,13 @@ static void unblock_signals(void)
#ifndef ETHR_UNUSABLE_SIGUSRX
sys_sigrelease(SIGUSR1);
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
+#endif /* #ifndef ERTS_SMP */
+
+#if defined(ERTS_SMP) && !defined(ETHR_UNUSABLE_SIGUSRX)
+ sys_sigrelease(ERTS_SYS_SUSPEND_SIGNAL);
#endif
-}
-/************************** Time stuff **************************/
-#ifdef HAVE_GETHRTIME
-#ifdef GETHRTIME_WITH_CLOCK_GETTIME
-SysHrTime sys_gethrtime(void)
-{
- struct timespec ts;
- long long result;
- if (clock_gettime(CLOCK_MONOTONIC,&ts) != 0) {
- erl_exit(1,"Fatal, could not get clock_monotonic value!, "
- "errno = %d\n", errno);
- }
- result = ((long long) ts.tv_sec) * 1000000000LL +
- ((long long) ts.tv_nsec);
- return (SysHrTime) result;
}
-#endif
-#endif
/************************** OS info *******************************/
@@ -1094,11 +1120,16 @@ void fini_getenv_state(GETENV_STATE *state)
/* Driver interfaces */
static ErlDrvData spawn_start(ErlDrvPort, char*, SysDriverOpts*);
static ErlDrvData fd_start(ErlDrvPort, char*, SysDriverOpts*);
+#if FDBLOCK
+static void fd_async(void *);
+static void fd_ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data);
+#endif
static ErlDrvSSizeT fd_control(ErlDrvData, unsigned int, char *, ErlDrvSizeT,
char **, ErlDrvSizeT);
static ErlDrvData vanilla_start(ErlDrvPort, char*, SysDriverOpts*);
static int spawn_init(void);
static void fd_stop(ErlDrvData);
+static void fd_flush(ErlDrvData);
static void stop(ErlDrvData);
static void ready_input(ErlDrvData, ErlDrvEvent);
static void ready_output(ErlDrvData, ErlDrvEvent);
@@ -1143,8 +1174,12 @@ struct erl_drv_entry fd_driver_entry = {
fd_control,
NULL,
outputv,
- NULL, /* ready_async */
- NULL, /* flush */
+#if FDBLOCK
+ fd_ready_async, /* ready_async */
+#else
+ NULL,
+#endif
+ fd_flush, /* flush */
NULL, /* call */
NULL, /* event */
ERL_DRV_EXTENDED_MARKER,
@@ -1198,13 +1233,28 @@ static RETSIGTYPE onchld(int signum)
#endif
}
+static int set_blocking_data(struct driver_data *dd) {
+
+ dd->blocking = erts_alloc(ERTS_ALC_T_SYS_BLOCKING, sizeof(ErtsSysBlocking));
+
+ erts_smp_atomic_add_nob(&sys_misc_mem_sz, sizeof(ErtsSysBlocking));
+
+ dd->blocking->pdl = driver_pdl_create(dd->port_num);
+ dd->blocking->res = 0;
+ dd->blocking->err = 0;
+ dd->blocking->pkey = driver_async_port_key(dd->port_num);
+
+ return 1;
+}
+
static int set_driver_data(ErlDrvPort port_num,
int ifd,
int ofd,
int packet_bytes,
int read_write,
int exit_status,
- int pid)
+ int pid,
+ int is_blocking)
{
Port *prt;
ErtsSysReportExit *report_exit;
@@ -1236,8 +1286,13 @@ static int set_driver_data(ErlDrvPort port_num,
driver_data[ifd].pid = pid;
driver_data[ifd].alive = 1;
driver_data[ifd].status = 0;
+ driver_data[ifd].terminating = 0;
+ driver_data[ifd].blocking = NULL;
if (read_write & DO_WRITE) {
driver_data[ifd].ofd = ofd;
+ if (is_blocking && FDBLOCK)
+ if (!set_blocking_data(driver_data+ifd))
+ return -1;
if (ifd != ofd)
driver_data[ofd] = driver_data[ifd]; /* structure copy */
} else { /* DO_READ only */
@@ -1253,6 +1308,11 @@ static int set_driver_data(ErlDrvPort port_num,
driver_data[ofd].pid = pid;
driver_data[ofd].alive = 1;
driver_data[ofd].status = 0;
+ driver_data[ofd].terminating = 0;
+ driver_data[ofd].blocking = NULL;
+ if (is_blocking && FDBLOCK)
+ if (!set_blocking_data(driver_data+ofd))
+ return -1;
return(ofd);
}
}
@@ -1262,11 +1322,13 @@ static int spawn_init()
int i;
#if CHLDWTHR
erts_thr_opts_t thr_opts = ERTS_THR_OPTS_DEFAULT_INITER;
+
thr_opts.detached = 0;
thr_opts.suggested_stack_size = 0; /* Smallest possible */
+ thr_opts.name = "child_waiter";
#endif
- sys_sigset(SIGPIPE, SIG_IGN); /* Ignore - we'll handle the write failure */
+ sys_signal(SIGPIPE, SIG_IGN); /* Ignore - we'll handle the write failure */
driver_data = (struct driver_data *)
erts_alloc(ERTS_ALC_T_DRV_TAB, max_files * sizeof(struct driver_data));
erts_smp_atomic_add_nob(&sys_misc_mem_sz,
@@ -1279,7 +1341,7 @@ static int spawn_init()
sys_sigblock(SIGCHLD);
#endif
- sys_sigset(SIGCHLD, onchld); /* Reap children */
+ sys_signal(SIGCHLD, onchld); /* Reap children */
#if CHLDWTHR
erts_thr_create(&child_waiter_tid, child_waiter, NULL, &thr_opts);
@@ -1745,7 +1807,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op
}
res = set_driver_data(port_num, ifd[0], ofd[1], opts->packet_bytes,
- opts->read_write, opts->exit_status, pid);
+ opts->read_write, opts->exit_status, pid, 0);
/* Don't unblock SIGCHLD until now, since the call above must
first complete putting away the info about our new subprocess. */
unblock_signals();
@@ -1830,6 +1892,7 @@ static ErlDrvData fd_start(ErlDrvPort port_num, char* name,
SysDriverOpts* opts)
{
ErlDrvData res;
+ int non_blocking = 0;
if (((opts->read_write & DO_READ) && opts->ifd >= max_files) ||
((opts->read_write & DO_WRITE) && opts->ofd >= max_files))
@@ -1902,6 +1965,20 @@ static ErlDrvData fd_start(ErlDrvPort port_num, char* name,
* case - it can be called with any old pre-existing file descriptors,
* the relations between which (if they're even two) we can only guess
* at - still, we try our best...
+ *
+ * Added note OTP 18: Some systems seem to use stdout/stderr to log data
+ * using unix pipes, so we cannot allow the system to block on a write.
+ * Therefore we use an async thread to write the data to fd's that could
+ * not be set to non-blocking. When no async threads are available we
+ * fall back on the old behaviour.
+ *
+ * Also the guarantee about what is delivered to the OS has changed.
+ * Pre 18 the fd driver did no flushing of data before terminating.
+ * Now it does. This is because we want to be able to guarantee that things
+ * such as escripts and friends really have outputted all data before
+ * terminating. This could potentially block the termination of the system
+ * for a very long time, but if the user wants to terminate fast she should
+ * use erlang:halt with flush=false.
*/
if (opts->read_write & DO_READ) {
@@ -1924,6 +2001,7 @@ static ErlDrvData fd_start(ErlDrvPort port_num, char* name,
imagine a scenario where setting non-blocking mode
here would cause problems - go ahead and do it. */
+ non_blocking = 1;
SET_NONBLOCKING(opts->ofd);
} else { /* output fd is a tty, input fd isn't */
@@ -1966,6 +2044,7 @@ static ErlDrvData fd_start(ErlDrvPort port_num, char* name,
(nfd = open(tty, O_WRONLY)) != -1) {
dup2(nfd, opts->ofd);
close(nfd);
+ non_blocking = 1;
SET_NONBLOCKING(opts->ofd);
}
}
@@ -1974,8 +2053,9 @@ static ErlDrvData fd_start(ErlDrvPort port_num, char* name,
}
CHLD_STAT_LOCK;
res = (ErlDrvData)(long)set_driver_data(port_num, opts->ifd, opts->ofd,
- opts->packet_bytes,
- opts->read_write, 0, -1);
+ opts->packet_bytes,
+ opts->read_write, 0, -1,
+ !non_blocking);
CHLD_STAT_UNLOCK;
return res;
}
@@ -2001,14 +2081,30 @@ static void nbio_stop_fd(ErlDrvPort prt, int fd)
SET_BLOCKING(fd);
}
-static void fd_stop(ErlDrvData fd) /* Does not close the fds */
+static void fd_stop(ErlDrvData ev) /* Does not close the fds */
{
int ofd;
+ int fd = (int)(long)ev;
+ ErlDrvPort prt = driver_data[fd].port_num;
- nbio_stop_fd(driver_data[(int)(long)fd].port_num, (int)(long)fd);
- ofd = driver_data[(int)(long)fd].ofd;
- if (ofd != (int)(long)fd && ofd != -1)
- nbio_stop_fd(driver_data[(int)(long)fd].port_num, (int)(long)ofd);
+#if FDBLOCK
+ if (driver_data[fd].blocking) {
+ erts_free(ERTS_ALC_T_SYS_BLOCKING,driver_data[fd].blocking);
+ driver_data[fd].blocking = NULL;
+ erts_smp_atomic_add_nob(&sys_misc_mem_sz, -1*sizeof(ErtsSysBlocking));
+ }
+#endif
+
+ nbio_stop_fd(prt, fd);
+ ofd = driver_data[fd].ofd;
+ if (ofd != fd && ofd != -1)
+ nbio_stop_fd(prt, ofd);
+}
+
+static void fd_flush(ErlDrvData fd)
+{
+ if (!driver_data[(int)(long)fd].terminating)
+ driver_data[(int)(long)fd].terminating = 1;
}
static ErlDrvData vanilla_start(ErlDrvPort port_num, char* name,
@@ -2031,8 +2127,8 @@ static ErlDrvData vanilla_start(ErlDrvPort port_num, char* name,
CHLD_STAT_LOCK;
res = (ErlDrvData)(long)set_driver_data(port_num, fd, fd,
- opts->packet_bytes,
- opts->read_write, 0, -1);
+ opts->packet_bytes,
+ opts->read_write, 0, -1, 0);
CHLD_STAT_UNLOCK;
return res;
}
@@ -2069,6 +2165,7 @@ static void stop(ErlDrvData fd)
}
}
+/* used by fd_driver */
static void outputv(ErlDrvData e, ErlIOVec* ev)
{
int fd = (int)(long)e;
@@ -2094,12 +2191,21 @@ static void outputv(ErlDrvData e, ErlIOVec* ev)
ev->iov[0].iov_base = lbp;
ev->iov[0].iov_len = pb;
ev->size += pb;
+
+ if (driver_data[fd].blocking && FDBLOCK)
+ driver_pdl_lock(driver_data[fd].blocking->pdl);
+
if ((sz = driver_sizeq(ix)) > 0) {
driver_enqv(ix, ev, 0);
+
+ if (driver_data[fd].blocking && FDBLOCK)
+ driver_pdl_unlock(driver_data[fd].blocking->pdl);
+
if (sz + ev->size >= (1 << 13))
set_busy_port(ix, 1);
}
- else {
+ else if (!driver_data[fd].blocking || !FDBLOCK) {
+ /* We try to write directly if the fd in non-blocking */
int vsize = ev->vsize > MAX_VSIZE ? MAX_VSIZE : ev->vsize;
n = writev(ofd, (const void *) (ev->iov), vsize);
@@ -2115,10 +2221,22 @@ static void outputv(ErlDrvData e, ErlIOVec* ev)
driver_enqv(ix, ev, n); /* n is the skip value */
driver_select(ix, ofd, ERL_DRV_WRITE|ERL_DRV_USE, 1);
}
+#if FDBLOCK
+ else {
+ if (ev->size != 0) {
+ driver_enqv(ix, ev, 0);
+ driver_pdl_unlock(driver_data[fd].blocking->pdl);
+ driver_async(ix, &driver_data[fd].blocking->pkey,
+ fd_async, driver_data+fd, NULL);
+ } else {
+ driver_pdl_unlock(driver_data[fd].blocking->pdl);
+ }
+ }
+#endif
/* return 0;*/
}
-
+/* Used by spawn_driver and vanilla driver */
static void output(ErlDrvData e, char* buf, ErlDrvSizeT len)
{
int fd = (int)(long)e;
@@ -2181,6 +2299,23 @@ static int port_inp_failure(ErlDrvPort port_num, int ready_fd, int res)
ASSERT(res <= 0);
(void) driver_select(port_num, ready_fd, ERL_DRV_READ|ERL_DRV_WRITE, 0);
clear_fd_data(ready_fd);
+
+ if (driver_data[ready_fd].blocking && FDBLOCK) {
+ driver_pdl_lock(driver_data[ready_fd].blocking->pdl);
+ if (driver_sizeq(driver_data[ready_fd].port_num) > 0) {
+ driver_pdl_unlock(driver_data[ready_fd].blocking->pdl);
+ /* We have stuff in the output queue, so we just
+ set the state to terminating and wait for fd_async_ready
+ to terminate the port */
+ if (res == 0)
+ driver_data[ready_fd].terminating = 2;
+ else
+ driver_data[ready_fd].terminating = -err;
+ return 0;
+ }
+ driver_pdl_unlock(driver_data[ready_fd].blocking->pdl);
+ }
+
if (res == 0) {
if (driver_data[ready_fd].report_exit) {
CHLD_STAT_LOCK;
@@ -2231,6 +2366,7 @@ static void ready_input(ErlDrvData e, ErlDrvEvent ready_fd)
port_num = driver_data[fd].port_num;
packet_bytes = driver_data[fd].packet_bytes;
+
if (packet_bytes == 0) {
byte *read_buf = (byte *) erts_alloc(ERTS_ALC_T_SYS_READ_BUF,
ERTS_SYS_READ_BUF_SZ);
@@ -2354,6 +2490,8 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
if ((iv = (struct iovec*) driver_peekq(ix, &vsize)) == NULL) {
driver_select(ix, ready_fd, ERL_DRV_WRITE, 0);
+ if (driver_data[fd].terminating)
+ driver_failure_atom(driver_data[fd].port_num,"normal");
return; /* 0; */
}
vsize = vsize > MAX_VSIZE ? MAX_VSIZE : vsize;
@@ -2379,6 +2517,86 @@ static void stop_select(ErlDrvEvent fd, void* _)
close((int)fd);
}
+#if FDBLOCK
+
+static void
+fd_async(void *async_data)
+{
+ int res;
+ struct driver_data *dd = (struct driver_data*)async_data;
+ SysIOVec *iov0;
+ SysIOVec *iov;
+ int iovlen;
+ int err = 0;
+ /* much of this code is stolen from efile_drv:invoke_writev */
+ driver_pdl_lock(dd->blocking->pdl);
+ iov0 = driver_peekq(dd->port_num, &iovlen);
+ iovlen = iovlen < MAXIOV ? iovlen : MAXIOV;
+ iov = erts_alloc_fnf(ERTS_ALC_T_SYS_WRITE_BUF,
+ sizeof(SysIOVec)*iovlen);
+ if (!iov) {
+ res = -1;
+ err = ENOMEM;
+ driver_pdl_unlock(dd->blocking->pdl);
+ } else {
+ memcpy(iov,iov0,iovlen*sizeof(SysIOVec));
+ driver_pdl_unlock(dd->blocking->pdl);
+
+ do {
+ res = writev(dd->ofd, iov, iovlen);
+ } while (res < 0 && errno == EINTR);
+ if (res < 0)
+ err = errno;
+
+ erts_free(ERTS_ALC_T_SYS_WRITE_BUF, iov);
+ }
+ dd->blocking->res = res;
+ dd->blocking->err = err;
+}
+
+void fd_ready_async(ErlDrvData drv_data,
+ ErlDrvThreadData thread_data) {
+ struct driver_data *dd = (struct driver_data *)thread_data;
+ ErlDrvPort port_num = dd->port_num;
+
+ ASSERT(dd->blocking);
+ ASSERT(dd == (driver_data + (int)(long)drv_data));
+
+ if (dd->blocking->res > 0) {
+ driver_pdl_lock(dd->blocking->pdl);
+ if (driver_deq(port_num, dd->blocking->res) == 0) {
+ driver_pdl_unlock(dd->blocking->pdl);
+ set_busy_port(port_num, 0);
+ if (dd->terminating) {
+ /* The port is has been ordered to terminate
+ from either fd_flush or port_inp_failure */
+ if (dd->terminating == 1)
+ driver_failure_atom(port_num, "normal");
+ else if (dd->terminating == 2)
+ driver_failure_eof(port_num);
+ else if (dd->terminating < 0)
+ driver_failure_posix(port_num, -dd->terminating);
+ return; /* -1; */
+ }
+ } else {
+ driver_pdl_unlock(dd->blocking->pdl);
+ /* still data left to write in queue */
+ driver_async(port_num, &dd->blocking->pkey, fd_async, dd, NULL);
+ return /* 0; */;
+ }
+ } else if (dd->blocking->res < 0) {
+ if (dd->blocking->err == ERRNO_BLOCK) {
+ set_busy_port(port_num, 1);
+ /* still data left to write in queue */
+ driver_async(port_num, &dd->blocking->pkey, fd_async, dd, NULL);
+ } else
+ driver_failure_posix(port_num, dd->blocking->err);
+ return; /* -1; */
+ }
+ return; /* 0; */
+}
+
+#endif
void erts_do_break_handling(void)
{
@@ -2648,18 +2866,30 @@ void sys_preload_end(Preload* p)
/* Nothing */
}
-/* Read a key from console (?) */
-
+/* Read a key from console, used by break.c
+ Here we assume that all schedulers are stopped so that erl_poll
+ does not interfere with the select below.
+*/
int sys_get_key(fd)
int fd;
{
- int c;
+ int c, ret;
unsigned char rbuf[64];
+ fd_set fds;
fflush(stdout); /* Flush query ??? */
- if ((c = read(fd,rbuf,64)) <= 0) {
- return c;
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+
+ ret = select(fd+1, &fds, NULL, NULL, NULL);
+
+ if (ret == 1) {
+ do {
+ c = read(fd,rbuf,64);
+ } while (c < 0 && errno == EAGAIN);
+ if (c <= 0)
+ return c;
}
return rbuf[0];
@@ -2935,7 +3165,7 @@ signal_dispatcher_thread_func(void *unused)
if (res < 0) {
if (errno == EINTR)
continue;
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"signal-dispatcher thread got unexpected error: %s (%d)\n",
erl_errno_id(errno),
errno);
@@ -2983,15 +3213,8 @@ signal_dispatcher_thread_func(void *unused)
case '1': /* SIGUSR1 */
sigusr1_exit();
break;
-#ifdef QUANTIFY
- case '2': /* SIGUSR2 */
- quantify_save_data(); /* Might take a substantial amount of
- time, but this is a test/debug
- build */
- break;
-#endif
default:
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"signal-dispatcher thread received unknown "
"signal notification: '%c'\n",
buf[i]);
@@ -3007,9 +3230,10 @@ init_smp_sig_notify(void)
{
erts_smp_thr_opts_t thr_opts = ERTS_SMP_THR_OPTS_DEFAULT_INITER;
thr_opts.detached = 1;
+ thr_opts.name = "sys_sig_dispatcher";
if (pipe(sig_notify_fds) < 0) {
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"Failed to create signal-dispatcher pipe: %s (%d)\n",
erl_errno_id(errno),
errno);
@@ -3021,6 +3245,17 @@ init_smp_sig_notify(void)
NULL,
&thr_opts);
}
+
+static void
+init_smp_sig_suspend(void) {
+ if (pipe(sig_suspend_fds) < 0) {
+ erts_exit(ERTS_ABORT_EXIT,
+ "Failed to create sig_suspend pipe: %s (%d)\n",
+ erl_errno_id(errno),
+ errno);
+ }
+}
+
#ifdef __DARWIN__
int erts_darwin_main_thread_pipe[2];
@@ -3030,7 +3265,7 @@ static void initialize_darwin_main_thread_pipes(void)
{
if (pipe(erts_darwin_main_thread_pipe) < 0 ||
pipe(erts_darwin_main_thread_result_pipe) < 0) {
- erl_exit(1,"Fatal error initializing Darwin main thread stealing");
+ erts_exit(ERTS_ERROR_EXIT,"Fatal error initializing Darwin main thread stealing");
}
}
@@ -3048,9 +3283,11 @@ erts_sys_main_thread(void)
#endif
smp_sig_notify(0); /* Notify initialized */
- while (1) {
- /* Wait for a signal to arrive... */
+
+ /* Wait for a signal to arrive... */
+
#ifdef __DARWIN__
+ while (1) {
/*
* The wx driver needs to be able to steal the main thread for Cocoa to
* work properly.
@@ -3065,12 +3302,24 @@ erts_sys_main_thread(void)
void* (*func)(void*);
void* arg;
void *resp;
- read(erts_darwin_main_thread_pipe[0],&func,sizeof(void* (*)(void*)));
- read(erts_darwin_main_thread_pipe[0],&arg, sizeof(void*));
+ res = read(erts_darwin_main_thread_pipe[0],&func,sizeof(void* (*)(void*)));
+ if (res != sizeof(void* (*)(void*)))
+ break;
+ res = read(erts_darwin_main_thread_pipe[0],&arg,sizeof(void*));
+ if (res != sizeof(void*))
+ break;
resp = (*func)(arg);
write(erts_darwin_main_thread_result_pipe[1],&resp,sizeof(void *));
}
-#else
+
+ if (res == -1 && errno != EINTR)
+ break;
+ }
+ /* Something broke with the main thread pipe, so we ignore it for now.
+ Most probably erts has closed this pipe and is about to exit. */
+#endif /* #ifdef __DARWIN__ */
+
+ while (1) {
#ifdef DEBUG
int res =
#else
@@ -3079,7 +3328,6 @@ erts_sys_main_thread(void)
select(0, NULL, NULL, NULL, NULL);
ASSERT(res < 0);
ASSERT(errno == EINTR);
-#endif
}
}
@@ -3171,6 +3419,7 @@ erl_sys_args(int* argc, char** argv)
#ifdef ERTS_SMP
init_smp_sig_notify();
+ init_smp_sig_suspend();
#endif
/* Handled arguments have been marked with NULL. Slide arguments
diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c
index cafeab547e..8fe7e599e5 100644
--- a/erts/emulator/sys/unix/sys_float.c
+++ b/erts/emulator/sys/unix/sys_float.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -32,7 +33,7 @@ void
erts_sys_init_float(void)
{
# ifdef SIGFPE
- sys_sigset(SIGFPE, SIG_IGN); /* Ignore so we can test for NaN and Inf */
+ sys_signal(SIGFPE, SIG_IGN); /* Ignore so we can test for NaN and Inf */
# endif
}
@@ -85,11 +86,11 @@ static void set_current_fp_exception(unsigned long pc)
void erts_fp_check_init_error(volatile unsigned long *fpexnp)
{
- char buf[64];
+ char buf[128];
snprintf(buf, sizeof buf, "ERTS_FP_CHECK_INIT at %p: detected unhandled FPE at %p\r\n",
__builtin_return_address(0), (void*)*fpexnp);
if (write(2, buf, strlen(buf)) <= 0)
- erl_exit(ERTS_ABORT_EXIT, "%s", buf);
+ erts_exit(ERTS_ABORT_EXIT, "%s", buf);
*fpexnp = 0;
#if defined(__i386__) || defined(__x86_64__)
erts_restore_fpu();
@@ -667,7 +668,7 @@ static void fpe_sig_handler(int sig)
static void erts_thread_catch_fp_exceptions(void)
{
- sys_sigset(SIGFPE, fpe_sig_handler);
+ sys_signal(SIGFPE, fpe_sig_handler);
unmask_fpe();
}
diff --git a/erts/emulator/sys/unix/sys_time.c b/erts/emulator/sys/unix/sys_time.c
index fcce54a2c4..95b3daa4ed 100644
--- a/erts/emulator/sys/unix/sys_time.c
+++ b/erts/emulator/sys/unix/sys_time.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -31,8 +32,21 @@
# undef _FILE_OFFSET_BITS
#endif
+#include <stdlib.h>
#include "sys.h"
#include "global.h"
+#include "erl_os_monotonic_time_extender.h"
+
+#undef ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+#undef ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) \
+ || defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) \
+ || defined(SYS_HRTIME_USING_MACH_CLOCK_GET_TIME)
+# include <mach/clock.h>
+# include <mach/mach.h>
+# define ERTS_MACH_CLOCKS
+#endif
#ifdef NO_SYSCONF
# define TICKS_PER_SEC() HZ
@@ -53,9 +67,23 @@
/******************* Routines for time measurement *********************/
-int erts_ticks_per_sec = 0; /* Will be SYS_CLK_TCK in erl_unix_sys.h */
-int erts_ticks_per_sec_wrap = 0; /* Will be SYS_CLK_TCK_WRAP */
-static int ticks_bsr = 0; /* Shift wrapped tick value this much to the right */
+#undef ERTS_SYS_TIME_INTERNAL_STATE_WRITE_FREQ__
+#undef ERTS_SYS_TIME_INTERNAL_STATE_READ_ONLY__
+#undef ERTS_SYS_TIME_INTERNAL_STATE_READ_MOSTLY__
+
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+
+static Uint32
+get_tick_count(void)
+{
+ struct tms unused;
+ return (Uint32) times(&unused);
+}
+
+#define ERTS_SYS_TIME_INTERNAL_STATE_READ_ONLY__
+#define ERTS_SYS_TIME_INTERNAL_STATE_READ_MOSTLY__
+
+#endif
/*
* init timers, chose a tick length, and return it.
@@ -63,37 +91,824 @@ static int ticks_bsr = 0; /* Shift wrapped tick value this much to the right */
* does almost everything. Other platforms have to
* emulate Unix in this sense.
*/
-int sys_init_time(void)
+
+ErtsSysTimeData__ erts_sys_time_data__ erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+
+#if defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+
+#define ERTS_SYS_TIME_INTERNAL_STATE_WRITE_FREQ__
+
+static ErtsMonotonicTime clock_gettime_monotonic(void);
+static ErtsMonotonicTime clock_gettime_monotonic_verified(void);
+#if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+static ErtsMonotonicTime clock_gettime_monotonic_raw(void);
+#endif
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+static void clock_gettime_times(ErtsMonotonicTime *, ErtsSystemTime *);
+static void clock_gettime_times_verified(ErtsMonotonicTime *, ErtsSystemTime *);
+#if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+static void clock_gettime_times_raw(ErtsMonotonicTime *, ErtsSystemTime *);
+#endif
+#endif
+
+#endif /* defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) */
+
+#ifdef ERTS_MACH_CLOCKS
+# define ERTS_SYS_TIME_INTERNAL_STATE_READ_ONLY__
+typedef struct {
+ clock_id_t id;
+ clock_serv_t srv;
+ char *name;
+} ErtsMachClock;
+
+typedef struct {
+ host_name_port_t host;
+ struct {
+ ErtsMachClock monotonic;
+ ErtsMachClock wall;
+ } clock;
+} ErtsMachClocks;
+static void mach_clocks_init(void);
+static void mach_clocks_fini(void);
+# ifdef HAVE_CLOCK_GET_ATTRIBUTES
+# define ERTS_HAVE_MACH_CLOCK_GETRES
+static Sint64
+mach_clock_getres(ErtsMachClock *clk);
+# endif
+#endif /* ERTS_MACH_CLOCKS */
+
+#ifdef ERTS_SYS_TIME_INTERNAL_STATE_READ_ONLY__
+struct sys_time_internal_state_read_only__ {
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+ int times_shift;
+#endif
+#ifdef ERTS_MACH_CLOCKS
+ ErtsMachClocks mach;
+#endif
+};
+#endif
+
+#ifdef ERTS_SYS_TIME_INTERNAL_STATE_READ_MOSTLY__
+struct sys_time_internal_state_read_mostly__ {
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+ ErtsOsMonotonicTimeExtendState os_mtime_xtnd;
+#endif
+};
+#endif
+
+#ifdef ERTS_SYS_TIME_INTERNAL_STATE_WRITE_FREQ__
+struct sys_time_internal_state_write_freq__ {
+ erts_smp_mtx_t mtx;
+#if defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+ ErtsMonotonicTime last_delivered;
+#endif
+};
+#endif
+
+#if defined(ERTS_SYS_TIME_INTERNAL_STATE_READ_ONLY__) \
+ || defined(ERTS_SYS_TIME_INTERNAL_STATE_WRITE_FREQ__)
+static struct {
+#ifdef ERTS_SYS_TIME_INTERNAL_STATE_READ_ONLY__
+ union {
+ struct sys_time_internal_state_read_only__ o;
+ char align__[(((sizeof(struct sys_time_internal_state_read_only__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } r;
+#endif
+#ifdef ERTS_SYS_TIME_INTERNAL_STATE_READ_MOSTLY__
+ union {
+ struct sys_time_internal_state_read_mostly__ m;
+ char align__[(((sizeof(struct sys_time_internal_state_read_mostly__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } wr;
+#endif
+#ifdef ERTS_SYS_TIME_INTERNAL_STATE_WRITE_FREQ__
+ union {
+ struct sys_time_internal_state_write_freq__ f;
+ char align__[(((sizeof(struct sys_time_internal_state_write_freq__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } w;
+#endif
+} internal_state erts_align_attribute(ERTS_CACHE_LINE_SIZE);
+#endif
+
+void
+sys_init_time(ErtsSysInitTimeResult *init_resp)
{
+#if defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)
+ int major, minor, build, vsn;
+#endif
+#if defined(ERTS_MACH_CLOCKS)
+ mach_clocks_init();
+#endif
+#if !defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)
+
+ init_resp->have_os_monotonic_time = 0;
+
+#else /* defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) */
+
+#ifdef ERTS_HAVE_CORRECTED_OS_MONOTONIC_TIME
+ init_resp->have_corrected_os_monotonic_time = 1;
+#else
+ init_resp->have_corrected_os_monotonic_time = 0;
+#endif
+
+ init_resp->os_monotonic_time_info.resolution = (Uint64) 1000*1000*1000;
+#if defined(HAVE_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID)
+ {
+ struct timespec ts;
+ if (clock_getres(MONOTONIC_CLOCK_ID, &ts) == 0) {
+ if (ts.tv_sec == 0 && ts.tv_nsec != 0)
+ init_resp->os_monotonic_time_info.resolution /= ts.tv_nsec;
+ else if (ts.tv_sec >= 1)
+ init_resp->os_monotonic_time_info.resolution = 1;
+ }
+ }
+#elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID)
+ init_resp->os_monotonic_time_info.resolution
+ = mach_clock_getres(&internal_state.r.o.mach.clock.monotonic);
+#endif
+
+#ifdef MONOTONIC_CLOCK_ID_STR
+ init_resp->os_monotonic_time_info.clock_id = MONOTONIC_CLOCK_ID_STR;
+#else
+ init_resp->os_monotonic_time_info.clock_id = NULL;
+#endif
+
+ init_resp->os_monotonic_time_info.locked_use = 0;
+
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+ init_resp->os_monotonic_time_info.func = "clock_gettime";
+#elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+ init_resp->os_monotonic_time_info.func = "clock_get_time";
+#elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME)
+ init_resp->os_monotonic_time_info.func = "gethrtime";
+#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
+ init_resp->os_monotonic_time_info.func = "times";
+#else
+# error Unknown erts_os_monotonic_time() implementation
+#endif
+
+ init_resp->have_os_monotonic_time = 1;
+
+ os_version(&major, &minor, &build);
+
+ vsn = ERTS_MK_VSN_INT(major, minor, build);
+
+
+#if defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+ if (vsn >= ERTS_MK_VSN_INT(2, 6, 33)) {
+ erts_sys_time_data__.r.o.os_monotonic_time =
+ clock_gettime_monotonic;
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+ erts_sys_time_data__.r.o.os_times =
+ clock_gettime_times;
+#endif
+ }
+ else {
+ /*
+ * Linux versions prior to 2.6.33 have a
+ * known bug that sometimes cause the NTP
+ * adjusted monotonic clock to take small
+ * steps backwards. Use raw monotonic clock
+ * if it is present; otherwise, fall back
+ * on locked verification of values.
+ */
+ init_resp->have_corrected_os_monotonic_time = 0;
+#if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+ /* We know that CLOCK_MONOTONIC_RAW is defined,
+ but we don't know if we got a kernel that
+ supports it. Support for CLOCK_MONOTONIC_RAW
+ appeared in kernel 2.6.28... */
+ if (vsn >= ERTS_MK_VSN_INT(2, 6, 28)) {
+ erts_sys_time_data__.r.o.os_monotonic_time =
+ clock_gettime_monotonic_raw;
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+ erts_sys_time_data__.r.o.os_times =
+ clock_gettime_times_raw;
+#endif
+ init_resp->os_monotonic_time_info.clock_id =
+ "CLOCK_MONOTONIC_RAW";
+ }
+ else
+#endif /* defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) */
+ {
+ erts_sys_time_data__.r.o.os_monotonic_time =
+ clock_gettime_monotonic_verified;
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+ erts_sys_time_data__.r.o.os_times =
+ clock_gettime_times_verified;
+#endif
+ erts_smp_mtx_init(&internal_state.w.f.mtx,
+ "os_monotonic_time");
+ internal_state.w.f.last_delivered
+ = clock_gettime_monotonic();
+ init_resp->os_monotonic_time_info.locked_use = 1;
+ }
+ }
+#else /* !(defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)) */
+ {
+ char flavor[1024];
+
+ os_flavor(flavor, sizeof(flavor));
+
+ if (sys_strcmp(flavor, "sunos") == 0) {
+ /*
+ * Don't trust hrtime on multi processors
+ * on SunOS prior to SunOS 5.8
+ */
+ if (vsn < ERTS_MK_VSN_INT(5, 8, 0)) {
+#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
+ if (sysconf(_SC_NPROCESSORS_CONF) > 1)
+#endif
+ init_resp->have_os_monotonic_time = 0;
+ }
+ }
+ }
+#endif /* !(defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)) */
+
+#endif /* defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) */
+
+#ifdef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
+ init_resp->os_monotonic_time_unit = ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT;
+#endif
+ init_resp->sys_clock_resolution = SYS_CLOCK_RESOLUTION;
+
/*
- * This (erts_ticks_per_sec) is only for times() (CLK_TCK),
- * the resolution is always one millisecond..
+ * This (erts_sys_time_data__.r.o.ticks_per_sec) is only for
+ * times() (CLK_TCK), the resolution is always one millisecond..
*/
- if ((erts_ticks_per_sec = TICKS_PER_SEC()) < 0)
- erl_exit(1, "Can't get clock ticks/sec\n");
- if (erts_ticks_per_sec >= 1000) {
- /* Workaround for beta linux kernels, need to be done in runtime
- to make erlang run on both 2.4 and 2.5 kernels. In the future,
- the kernel ticks might as
- well be used as a high res timer instead, but that's for when the
- majority uses kernels with HZ == 1024 */
- ticks_bsr = 3;
- } else {
- ticks_bsr = 0;
+ if ((erts_sys_time_data__.r.o.ticks_per_sec = TICKS_PER_SEC()) < 0)
+ erts_exit(ERTS_ABORT_EXIT, "Can't get clock ticks/sec\n");
+
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+#if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
+# error Time unit is supposed to be determined at runtime...
+#endif
+ {
+ ErtsMonotonicTime resolution = erts_sys_time_data__.r.o.ticks_per_sec;
+ ErtsMonotonicTime time_unit = resolution;
+ int shift = 0;
+
+ while (time_unit < 1000*1000) {
+ time_unit <<= 1;
+ shift++;
+ }
+
+ init_resp->os_monotonic_time_info.resolution = resolution;
+ init_resp->os_monotonic_time_unit = time_unit;
+ init_resp->os_monotonic_time_info.extended = 1;
+ internal_state.r.o.times_shift = shift;
+
+ erts_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd,
+ get_tick_count,
+ (1 << 29) / resolution);
+ }
+#endif /* defined(OS_MONOTONIC_TIME_USING_TIMES) */
+
+#ifdef WALL_CLOCK_ID_STR
+ init_resp->os_system_time_info.clock_id = WALL_CLOCK_ID_STR;
+#else
+ init_resp->os_system_time_info.clock_id = NULL;
+#endif
+
+ init_resp->os_system_time_info.locked_use = 0;
+ init_resp->os_system_time_info.resolution = (Uint64) 1000*1000*1000;
+#if defined(HAVE_CLOCK_GETRES) && defined(WALL_CLOCK_ID)
+ {
+ struct timespec ts;
+ if (clock_getres(WALL_CLOCK_ID, &ts) == 0) {
+ if (ts.tv_sec == 0 && ts.tv_nsec != 0)
+ init_resp->os_system_time_info.resolution /= ts.tv_nsec;
+ else if (ts.tv_sec >= 1)
+ init_resp->os_system_time_info.resolution = 1;
+ }
}
- erts_ticks_per_sec_wrap = (erts_ticks_per_sec >> ticks_bsr);
- return SYS_CLOCK_RESOLUTION;
+#elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(WALL_CLOCK_ID)
+ init_resp->os_system_time_info.resolution
+ = mach_clock_getres(&internal_state.r.o.mach.clock.wall);
+#endif
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+ init_resp->os_system_time_info.func = "clock_gettime";
+#elif defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+ init_resp->os_system_time_info.func = "clock_get_time";
+#elif defined(OS_SYSTEM_TIME_GETTIMEOFDAY)
+ init_resp->os_system_time_info.func = "gettimeofday";
+ init_resp->os_system_time_info.resolution = 1000*1000;
+ init_resp->os_system_time_info.clock_id = NULL;
+#else
+# error Missing erts_os_system_time() implementation
+#endif
+
+}
+
+void
+erts_late_sys_init_time(void)
+{
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+ erts_late_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd);
+#endif
+}
+
+static ERTS_INLINE ErtsSystemTime
+adj_stime_time_unit(ErtsSystemTime stime, Uint32 res)
+{
+ if (res == ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT)
+ return stime;
+ if (res == (Uint32) 1000*1000*1000
+ && ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT == 1000*1000)
+ return stime/1000;
+ if (res == (Uint32) 1000*1000
+ && ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT == 1000*1000*1000)
+ return stime*1000;
+ return ((ErtsSystemTime)
+ erts_time_unit_conversion(stime,
+ (Uint32) res,
+ (Uint32) ERTS_MONOTONIC_TIME_UNIT));
}
-clock_t sys_times_wrap(void)
+#define ERTS_TimeSpec2Sint64(TS) \
+ ((((Sint64) (TS)->tv_sec) * ((Sint64) 1000*1000*1000)) \
+ + ((Sint64) (TS)->tv_nsec))
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * POSIX clock_gettime() *
+\* */
+
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) \
+ || defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static ERTS_INLINE Sint64
+posix_clock_gettime(clockid_t id, char *name)
+{
+ struct timespec ts;
+
+ if (clock_gettime(id, &ts) != 0) {
+ int err = errno;
+ char *errstr = err ? strerror(err) : "unknown";
+ erts_exit(ERTS_ABORT_EXIT,
+ "clock_gettime(%s, _) failed: %s (%d)\n",
+ name, errstr, err);
+ }
+ return ERTS_TimeSpec2Sint64(&ts);
+}
+
+#endif /* defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) \
+ || defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+ErtsSystemTime
+erts_os_system_time(void)
+{
+ Sint64 stime = posix_clock_gettime(WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR);
+ return adj_stime_time_unit((ErtsSystemTime) stime,
+ (Uint32) 1000*1000*1000);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+#define ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+
+static ERTS_INLINE void
+posix_clock_gettime_times(clockid_t mid, char *mname,
+ ErtsMonotonicTime *mtimep,
+ clockid_t sid, char *sname,
+ ErtsSystemTime *stimep)
+{
+ struct timespec mts, sts;
+ int mres, sres, merr, serr;
+
+ mres = clock_gettime(mid, &mts);
+ merr = errno;
+ sres = clock_gettime(sid, &sts);
+ serr = errno;
+
+ if (mres != 0) {
+ char *errstr = merr ? strerror(merr) : "unknown";
+ erts_exit(ERTS_ABORT_EXIT,
+ "clock_gettime(%s, _) failed: %s (%d)\n",
+ mname, errstr, merr);
+ }
+ if (sres != 0) {
+ char *errstr = serr ? strerror(serr) : "unknown";
+ erts_exit(ERTS_ABORT_EXIT,
+ "clock_gettime(%s, _) failed: %s (%d)\n",
+ sname, errstr, serr);
+ }
+
+ *mtimep = (ErtsMonotonicTime) ERTS_TimeSpec2Sint64(&mts);
+ *stimep = (ErtsSystemTime) ERTS_TimeSpec2Sint64(&sts);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+#if defined(__linux__)
+
+static ErtsMonotonicTime clock_gettime_monotonic_verified(void)
+{
+ ErtsMonotonicTime mtime;
+
+ mtime = (ErtsMonotonicTime) posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
+
+ erts_smp_mtx_lock(&internal_state.w.f.mtx);
+ if (mtime < internal_state.w.f.last_delivered)
+ mtime = internal_state.w.f.last_delivered;
+ else
+ internal_state.w.f.last_delivered = mtime;
+ erts_smp_mtx_unlock(&internal_state.w.f.mtx);
+
+ return mtime;
+}
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static void clock_gettime_times_verified(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR,
+ mtimep,
+ WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR,
+ stimep);
+
+ erts_smp_mtx_lock(&internal_state.w.f.mtx);
+ if (*mtimep < internal_state.w.f.last_delivered)
+ *mtimep = internal_state.w.f.last_delivered;
+ else
+ internal_state.w.f.last_delivered = *mtimep;
+ erts_smp_mtx_unlock(&internal_state.w.f.mtx);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+static ErtsMonotonicTime clock_gettime_monotonic(void)
{
- SysTimes dummy;
- clock_t result = (sys_times(&dummy) >> ticks_bsr);
- return result;
+ return (ErtsMonotonicTime) posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
}
+#if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+static ErtsMonotonicTime clock_gettime_monotonic_raw(void)
+{
+ return (ErtsMonotonicTime) posix_clock_gettime(CLOCK_MONOTONIC_RAW,
+ "CLOCK_MONOTONIC_RAW");
+}
+
+#endif /* defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) */
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static void clock_gettime_times(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR,
+ mtimep,
+ WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR,
+ stimep);
+}
+
+#if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+
+static void clock_gettime_times_raw(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(CLOCK_MONOTONIC_RAW,
+ "CLOCK_MONOTONIC_RAW",
+ mtimep,
+ WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR,
+ stimep);
+}
+
+#endif /* defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) */
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+#else /* !defined(__linux__) */
+
+ErtsMonotonicTime erts_os_monotonic_time(void)
+{
+ return posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
+}
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+void erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR,
+ mtimep,
+ WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR,
+ stimep);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+#endif /* !defined(__linux__) */
+
+#endif /* defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) */
+
+#if defined(SYS_HRTIME_USING_CLOCK_GETTIME)
+# define ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+ErtsSysHrTime
+erts_sys_hrtime(void)
+{
+ return (ErtsSysHrTime) posix_clock_gettime(HRTIME_CLOCK_ID,
+ HRTIME_CLOCK_ID_STR);
+}
+
+#endif /* defined(SYS_HRTIME_USING_CLOCK_GETTIME) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * MACH clock_get_time() *
+\* */
+
+#if defined(ERTS_MACH_CLOCKS)
+
+static void
+mach_clocks_fini(void)
+{
+ mach_port_t task = mach_task_self();
+ mach_port_deallocate(task, internal_state.r.o.mach.host);
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+ mach_port_deallocate(task, internal_state.r.o.mach.clock.monotonic.srv);
+#endif
+#if defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+ mach_port_deallocate(task, internal_state.r.o.mach.clock.wall.srv);
+#endif
+}
+
+static void
+mach_clocks_init(void)
+{
+ kern_return_t kret;
+ host_name_port_t host;
+ clock_id_t id;
+ clock_serv_t *clck_srv_p;
+ char *name;
+
+ host = internal_state.r.o.mach.host = mach_host_self();
+
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) \
+ || defined(SYS_HRTIME_USING_MACH_CLOCK_GET_TIME)
+ id = internal_state.r.o.mach.clock.monotonic.id = MONOTONIC_CLOCK_ID;
+ name = internal_state.r.o.mach.clock.monotonic.name = MONOTONIC_CLOCK_ID_STR;
+ clck_srv_p = &internal_state.r.o.mach.clock.monotonic.srv;
+ kret = host_get_clock_service(host, id, clck_srv_p);
+ if (kret != KERN_SUCCESS) {
+ erts_exit(ERTS_ABORT_EXIT,
+ "host_get_clock_service(_, %s, _) failed\n",
+ name);
+ }
+#endif
+
+#if defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+ id = internal_state.r.o.mach.clock.wall.id = WALL_CLOCK_ID;
+ name = internal_state.r.o.mach.clock.wall.name = WALL_CLOCK_ID_STR;
+ clck_srv_p = &internal_state.r.o.mach.clock.wall.srv;
+ kret = host_get_clock_service(host, id, clck_srv_p);
+ if (kret != KERN_SUCCESS) {
+ erts_exit(ERTS_ABORT_EXIT,
+ "host_get_clock_service(_, %s, _) failed\n",
+ name);
+ }
+#endif
+
+ if (atexit(mach_clocks_fini) != 0) {
+ int err = errno;
+ char *errstr = err ? strerror(err) : "unknown";
+ erts_exit(ERTS_ABORT_EXIT,
+ "Failed to register mach_clocks_fini() "
+ "for call at exit: %s (%d)\n",
+ errstr, err);
+ }
+}
+
+#ifdef ERTS_HAVE_MACH_CLOCK_GETRES
+
+static Sint64
+mach_clock_getres(ErtsMachClock *clk)
+{
+ kern_return_t kret;
+ natural_t attr[1];
+ mach_msg_type_number_t cnt;
+
+ cnt = sizeof(attr);
+ kret = clock_get_attributes(clk->srv,
+ CLOCK_GET_TIME_RES,
+ (clock_attr_t) attr,
+ &cnt);
+ if (kret != KERN_SUCCESS || cnt != 1) {
+ erts_exit(ERTS_ABORT_EXIT,
+ "clock_get_attributes(%s, _) failed\n",
+ clk->name);
+ }
+
+ return (Sint64) attr[0];
+}
+
+#endif /* ERTS_HAVE_MACH_CLOCK_GETRES */
+
+static ERTS_INLINE Sint64
+mach_clock_get_time(ErtsMachClock *clk)
+{
+ kern_return_t kret;
+ mach_timespec_t time_spec;
+
+ kret = clock_get_time(clk->srv, &time_spec);
+ if (kret != KERN_SUCCESS)
+ erts_exit(ERTS_ABORT_EXIT, "clock_get_time(%s, _) failed\n", clk->name);
+
+ return ERTS_TimeSpec2Sint64(&time_spec);
+}
+
+#endif /* defined(ERTS_MACH_CLOCKS) */
+
+#if defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+
+#define ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+
+ErtsSystemTime
+erts_os_system_time(void)
+{
+ Sint64 stime = mach_clock_get_time(&internal_state.r.o.mach.clock.wall);
+ return adj_stime_time_unit((ErtsSystemTime) stime,
+ (Uint32) 1000*1000*1000);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+
+ErtsMonotonicTime
+erts_os_monotonic_time(void)
+{
+ return (ErtsMonotonicTime)
+ mach_clock_get_time(&internal_state.r.o.mach.clock.monotonic);
+}
+
+#if defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+
+#define ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+
+void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ kern_return_t mkret, skret;
+ mach_timespec_t mon_time_spec, sys_time_spec;
+
+ mkret = clock_get_time(internal_state.r.o.mach.clock.monotonic.srv,
+ &mon_time_spec);
+ skret = clock_get_time(internal_state.r.o.mach.clock.wall.srv,
+ &sys_time_spec);
+
+ if (mkret != KERN_SUCCESS)
+ erts_exit(ERTS_ABORT_EXIT,
+ "clock_get_time(%s, _) failed\n",
+ internal_state.r.o.mach.clock.monotonic.name);
+ if (skret != KERN_SUCCESS)
+ erts_exit(ERTS_ABORT_EXIT,
+ "clock_get_time(%s, _) failed\n",
+ internal_state.r.o.mach.clock.wall.name);
+
+ *mtimep = (ErtsMonotonicTime) ERTS_TimeSpec2Sint64(&mon_time_spec);
+ *stimep = (ErtsSystemTime) ERTS_TimeSpec2Sint64(&sys_time_spec);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+#endif /* defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+#if defined(SYS_HRTIME_USING_MACH_CLOCK_GET_TIME)
+
+#define ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+ErtsSysHrTime
+erts_sys_hrtime(void)
+{
+ return (ErtsSysHrTime)
+ mach_clock_get_time(&internal_state.r.o.mach.clock.monotonic);
+}
+
+#endif /* defined(SYS_HRTIME_USING_MACH_CLOCK_GET_TIME) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Solaris gethrtime() - OS monotonic time *
+\* */
+
+#if defined(OS_MONOTONIC_TIME_USING_GETHRTIME)
+
+ErtsMonotonicTime erts_os_monotonic_time(void)
+{
+ return (ErtsMonotonicTime) gethrtime();
+}
+
+#endif /* defined(OS_MONOTONIC_TIME_USING_GETHRTIME) */
+
+#if defined(SYS_HRTIME_USING_GETHRTIME)
+
+#define ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+ErtsSysHrTime
+erts_sys_hrtime(void)
+{
+ return (ErtsSysHrTime) gethrtime();
+}
+
+#endif /* defined(SYS_HRTIME_USING_GETHRTIME) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * gettimeofday() - OS system time *
+\* */
+
+#if defined(OS_SYSTEM_TIME_GETTIMEOFDAY)
+
+ErtsSystemTime
+erts_os_system_time(void)
+{
+ ErtsSystemTime stime;
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) != 0) {
+ int err = errno;
+ char *errstr = err ? strerror(err) : "unknown";
+ erts_exit(ERTS_ABORT_EXIT,
+ "gettimeofday(_, NULL) failed: %s (%d)\n",
+ errstr, err);
+ }
+
+ stime = (ErtsSystemTime) tv.tv_sec;
+ stime *= (ErtsSystemTime) 1000*1000;
+ stime += (ErtsSystemTime) tv.tv_usec;
+
+ return adj_stime_time_unit(stime, (Uint32) 1000*1000);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_GETTIMEOFDAY) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * times() - OS monotonic time *
+\* */
+
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+
+ErtsMonotonicTime
+erts_os_monotonic_time(void)
+{
+ Uint32 ticks = get_tick_count();
+ ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ return ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks) << internal_state.r.o.times_shift;
+}
+
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Fallbacks *
+\* */
+
+#ifndef ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+ErtsSysHrTime
+erts_sys_hrtime(void)
+{
+ return (ErtsSysHrTime) ERTS_MONOTONIC_TO_NSEC(erts_os_system_time());
+}
+
+#endif
+
+#if !defined(ERTS_HAVE_ERTS_OS_TIMES_IMPL__) \
+ && defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)
+
+void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ *mtimep = erts_os_monotonic_time();
+ *stimep = erts_os_system_time();
+}
+
+#endif
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifdef HAVE_GETHRVTIME_PROCFS_IOCTL
diff --git a/erts/emulator/sys/win32/dosmap.c b/erts/emulator/sys/win32/dosmap.c
index 15416a66c5..a98065c666 100644
--- a/erts/emulator/sys/win32/dosmap.c
+++ b/erts/emulator/sys/win32/dosmap.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/win32/driver_int.h b/erts/emulator/sys/win32/driver_int.h
index 97e188816e..b931da52f5 100644
--- a/erts/emulator/sys/win32/driver_int.h
+++ b/erts/emulator/sys/win32/driver_int.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/win32/erl_main.c b/erts/emulator/sys/win32/erl_main.c
index 5471bffb52..21d9a58da6 100644
--- a/erts/emulator/sys/win32/erl_main.c
+++ b/erts/emulator/sys/win32/erl_main.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/win32/erl_poll.c b/erts/emulator/sys/win32/erl_poll.c
index 972170d465..547d4b1d21 100644
--- a/erts/emulator/sys/win32/erl_poll.c
+++ b/erts/emulator/sys/win32/erl_poll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -25,6 +26,7 @@
#include "sys.h"
#include "erl_alloc.h"
#include "erl_poll.h"
+#include "erl_time.h"
/*
* Some debug macros
@@ -285,7 +287,7 @@ struct ErtsPollSet_ {
#ifdef ERTS_SMP
erts_smp_mtx_t mtx;
#endif
- erts_smp_atomic32_t timeout;
+ erts_atomic64_t timeout_time;
};
#ifdef ERTS_SMP
@@ -363,6 +365,26 @@ do { \
wait_standby(PS); \
} while(0)
+static ERTS_INLINE void
+init_timeout_time(ErtsPollSet ps)
+{
+ erts_atomic64_init_nob(&ps->timeout_time,
+ (erts_aint64_t) ERTS_MONOTONIC_TIME_MAX);
+}
+
+static ERTS_INLINE void
+set_timeout_time(ErtsPollSet ps, ErtsMonotonicTime time)
+{
+ erts_atomic64_set_relb(&ps->timeout_time,
+ (erts_aint64_t) time);
+}
+
+static ERTS_INLINE ErtsMonotonicTime
+get_timeout_time(ErtsPollSet ps)
+{
+ return (ErtsMonotonicTime) erts_atomic64_read_acqb(&ps->timeout_time);
+}
+
#define ERTS_POLL_NOT_WOKEN ((erts_aint32_t) 0)
#define ERTS_POLL_WOKEN_IO_READY ((erts_aint32_t) 1)
#define ERTS_POLL_WOKEN_INTR ((erts_aint32_t) 2)
@@ -414,7 +436,7 @@ wakeup_cause(ErtsPollSet ps)
break;
default:
res = 0;
- erl_exit(ERTS_ABORT_EXIT,
+ erts_exit(ERTS_ABORT_EXIT,
"%s:%d: Internal error: Invalid wakeup_state=%d\n",
__FILE__, __LINE__, (int) wakeup_state);
}
@@ -422,15 +444,29 @@ wakeup_cause(ErtsPollSet ps)
}
static ERTS_INLINE DWORD
-poll_wait_timeout(ErtsPollSet ps, SysTimeval *tvp)
+poll_wait_timeout(ErtsPollSet ps, ErtsMonotonicTime timeout_time)
{
- time_t timeout = tvp->tv_sec * 1000 + tvp->tv_usec / 1000;
+ ErtsMonotonicTime current_time, diff_time, timeout;
- if (timeout <= 0) {
+ if (timeout_time == ERTS_POLL_NO_TIMEOUT) {
+ no_timeout:
+ set_timeout_time(ps, ERTS_MONOTONIC_TIME_MIN);
woke_up(ps);
return (DWORD) 0;
}
+ current_time = erts_get_monotonic_time(NULL);
+ diff_time = timeout_time - current_time;
+ if (diff_time <= 0)
+ goto no_timeout;
+
+ /* Round up to nearest milli second */
+ timeout = (ERTS_MONOTONIC_TO_MSEC(diff_time - 1) + 1);
+ if (timeout > INT_MAX)
+ timeout = INT_MAX; /* Also prevents DWORD overflow */
+
+ set_timeout_time(ps, current_time + ERTS_MSEC_TO_MONOTONIC(timeout));
+
ResetEvent(ps->event_io_ready);
/*
* Since we don't know the internals of ResetEvent() we issue
@@ -442,10 +478,6 @@ poll_wait_timeout(ErtsPollSet ps, SysTimeval *tvp)
if (erts_atomic32_read_nob(&ps->wakeup_state) != ERTS_POLL_NOT_WOKEN)
return (DWORD) 0;
- if (timeout > ((time_t) ERTS_AINT32_T_MAX))
- timeout = ERTS_AINT32_T_MAX; /* Also prevents DWORD overflow */
-
- erts_smp_atomic32_set_relb(&ps->timeout, (erts_aint32_t) timeout);
return (DWORD) timeout;
}
@@ -544,7 +576,7 @@ static void signal_standby(ErtsPollSet ps)
--(ps->standby_wait_counter);
if (ps->standby_wait_counter < 0) {
LeaveCriticalSection(&(ps->standby_crit));
- erl_exit(1,"Standby signalled by more threads than expected");
+ erts_exit(ERTS_ERROR_EXIT,"Standby signalled by more threads than expected");
}
if (!(ps->standby_wait_counter)) {
SetEvent(ps->standby_wait_event);
@@ -706,7 +738,7 @@ static void *break_waiter(void *param)
erts_mtx_unlock(&break_waiter_lock);
break;
default:
- erl_exit(1,"Unexpected event in break_waiter");
+ erts_exit(ERTS_ERROR_EXIT,"Unexpected event in break_waiter");
}
}
}
@@ -1012,12 +1044,12 @@ void erts_poll_interrupt(ErtsPollSet ps, int set /* bool */)
void erts_poll_interrupt_timed(ErtsPollSet ps,
int set /* bool */,
- erts_short_time_t msec)
+ ErtsMonotonicTime timeout_time)
{
- HARDTRACEF(("In erts_poll_interrupt_timed(%d,%ld)",set,msec));
+ HARDTRACEF(("In erts_poll_interrupt_timed(%d,%ld)",set,timeout_time));
if (!set)
reset_interrupt(ps);
- else if (erts_smp_atomic32_read_acqb(&ps->timeout) > (erts_aint32_t) msec)
+ else if (get_timeout_time(ps) > timeout_time)
set_interrupt(ps);
HARDTRACEF(("Out erts_poll_interrupt_timed"));
}
@@ -1092,7 +1124,7 @@ void erts_poll_controlv(ErtsPollSet ps,
int erts_poll_wait(ErtsPollSet ps,
ErtsPollResFd pr[],
int *len,
- SysTimeval *tvp)
+ ErtsMonotonicTime timeout_time)
{
int no_fds;
DWORD timeout;
@@ -1125,7 +1157,7 @@ int erts_poll_wait(ErtsPollSet ps,
HARDDEBUGF(("Oups!"));
/* Oups, got signalled before we took the lock, can't reset */
if(!is_io_ready(ps)) {
- erl_exit(1,"Internal error: "
+ erts_exit(ERTS_ERROR_EXIT,"Internal error: "
"Inconsistent io structures in erl_poll.\n");
}
START_WAITER(ps,w);
@@ -1149,7 +1181,7 @@ int erts_poll_wait(ErtsPollSet ps,
no_fds = ERTS_POLL_MAX_RES;
#endif
- timeout = poll_wait_timeout(ps, tvp);
+ timeout = poll_wait_timeout(ps, timeout_time);
/*HARDDEBUGF(("timeout = %ld",(long) timeout));*/
@@ -1183,7 +1215,7 @@ int erts_poll_wait(ErtsPollSet ps,
ERTS_SET_BREAK_REQUESTED;
break;
case BREAK_WAITER_GOT_HALT:
- erl_exit(0,"");
+ erts_exit(0,"");
break;
default:
break;
@@ -1242,7 +1274,7 @@ int erts_poll_wait(ErtsPollSet ps,
erts_mtx_unlock(&w->mtx);
}
done:
- erts_smp_atomic32_set_nob(&ps->timeout, ERTS_AINT32_T_MAX);
+ set_timeout_time(ps, ERTS_MONOTONIC_TIME_MAX);
*len = num;
ERTS_POLLSET_UNLOCK(ps);
HARDTRACEF(("Out erts_poll_wait"));
@@ -1326,7 +1358,7 @@ ErtsPollSet erts_poll_create_pollset(void)
#ifdef ERTS_SMP
erts_smp_mtx_init(&ps->mtx, "pollset");
#endif
- erts_smp_atomic32_init_nob(&ps->timeout, ERTS_AINT32_T_MAX);
+ init_timeout_time(ps);
HARDTRACEF(("Out erts_poll_create_pollset"));
return ps;
diff --git a/erts/emulator/sys/win32/erl_win32_sys_ddll.c b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
index 338f0d7386..7c24a77e31 100644
--- a/erts/emulator/sys/win32/erl_win32_sys_ddll.c
+++ b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -51,7 +52,8 @@ void erl_sys_ddll_init(void) {
#define ERL_NIF_API_FUNC_DECL(RET,NAME,ARGS) nif_callbacks.NAME = NAME
#include "erl_nif_api_funcs.h"
#undef ERL_NIF_API_FUNC_DECL
-
+ nif_callbacks.erts_alc_test = erts_alc_test;
+
return;
}
diff --git a/erts/emulator/sys/win32/erl_win_dyn_driver.h b/erts/emulator/sys/win32/erl_win_dyn_driver.h
index 4010d939e5..9c699fdba0 100644
--- a/erts/emulator/sys/win32/erl_win_dyn_driver.h
+++ b/erts/emulator/sys/win32/erl_win_dyn_driver.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -102,6 +103,11 @@ WDD_TYPEDEF(ErlDrvSInt, driver_pdl_inc_refc, (ErlDrvPDL));
WDD_TYPEDEF(ErlDrvSInt, driver_pdl_dec_refc, (ErlDrvPDL));
WDD_TYPEDEF(void, driver_system_info, (ErlDrvSysInfo *, size_t));
WDD_TYPEDEF(int, driver_get_now, (ErlDrvNowData *));
+WDD_TYPEDEF(ErlDrvTime, erl_drv_monotonic_time, (ErlDrvTimeUnit));
+WDD_TYPEDEF(ErlDrvTime, erl_drv_time_offset, (ErlDrvTimeUnit));
+WDD_TYPEDEF(ErlDrvTime, erl_drv_convert_time_unit, (ErlDrvTime,
+ ErlDrvTimeUnit,
+ ErlDrvTimeUnit));
WDD_TYPEDEF(int, driver_monitor_process, (ErlDrvPort port,
ErlDrvTermData process,
ErlDrvMonitor *monitor));
@@ -144,8 +150,8 @@ WDD_TYPEDEF(ErlDrvTid, erl_drv_thread_self, (void));
WDD_TYPEDEF(int, erl_drv_equal_tids, (ErlDrvTid tid1, ErlDrvTid tid2));
WDD_TYPEDEF(void, erl_drv_thread_exit, (void *resp));
WDD_TYPEDEF(int, erl_drv_thread_join, (ErlDrvTid, void **respp));
-WDD_TYPEDEF(int, erl_drv_putenv, (char *key, char *value));
-WDD_TYPEDEF(int, erl_drv_getenv, (char *key, char *value, size_t *value_size));
+WDD_TYPEDEF(int, erl_drv_putenv, (const char *key, char *value));
+WDD_TYPEDEF(int, erl_drv_getenv, (const char *key, char *value, size_t *value_size));
typedef struct {
WDD_FTYPE(null_func) *null_func;
@@ -216,6 +222,9 @@ typedef struct {
WDD_FTYPE(driver_pdl_dec_refc) *driver_pdl_dec_refc;
WDD_FTYPE(driver_system_info) *driver_system_info;
WDD_FTYPE(driver_get_now) *driver_get_now;
+ WDD_FTYPE(erl_drv_monotonic_time) *erl_drv_monotonic_time;
+ WDD_FTYPE(erl_drv_time_offset) *erl_drv_time_offset;
+ WDD_FTYPE(erl_drv_convert_time_unit) *erl_drv_convert_time_unit;
WDD_FTYPE(driver_monitor_process) *driver_monitor_process;
WDD_FTYPE(driver_demonitor_process) *driver_demonitor_process;
WDD_FTYPE(driver_get_monitored_process) *driver_get_monitored_process;
@@ -327,6 +336,9 @@ extern TWinDynDriverCallbacks WinDynDriverCallbacks;
#define driver_pdl_dec_refc (WinDynDriverCallbacks.driver_pdl_dec_refc)
#define driver_system_info (WinDynDriverCallbacks.driver_system_info)
#define driver_get_now (WinDynDriverCallbacks.driver_get_now)
+#define erl_drv_monotonic_time (WinDynDriverCallbacks.erl_drv_monotonic_time)
+#define erl_drv_time_offset (WinDynDriverCallbacks.erl_drv_time_offset)
+#define erl_drv_convert_time_unit (WinDynDriverCallbacks.erl_drv_convert_time_unit)
#define driver_monitor_process \
(WinDynDriverCallbacks.driver_monitor_process)
#define driver_demonitor_process \
@@ -462,6 +474,9 @@ do { \
((W).driver_pdl_dec_refc) = driver_pdl_dec_refc; \
((W).driver_system_info) = driver_system_info; \
((W).driver_get_now) = driver_get_now; \
+((W).erl_drv_monotonic_time) = erl_drv_monotonic_time; \
+((W).erl_drv_time_offset) = erl_drv_time_offset; \
+((W).erl_drv_convert_time_unit) = erl_drv_convert_time_unit; \
((W).driver_monitor_process) = driver_monitor_process; \
((W).driver_demonitor_process) = driver_demonitor_process; \
((W).driver_get_monitored_process) = driver_get_monitored_process; \
diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h
index 838f0c61eb..7e8dd8a4ca 100644
--- a/erts/emulator/sys/win32/erl_win_sys.h
+++ b/erts/emulator/sys/win32/erl_win_sys.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -120,9 +121,6 @@
/*
* For erl_time_sup
*/
-#define HAVE_GETHRTIME
-
-#define sys_init_hrtime() /* Nothing */
#define SYS_CLK_TCK 1000
#define SYS_CLOCK_RESOLUTION 1
@@ -164,18 +162,81 @@ typedef struct {
#if defined (__GNUC__)
typedef unsigned long long Uint64;
typedef long long Sint64;
-
-typedef long long SysHrTime;
+# ifdef ULLONG_MAX
+# define ERTS_UINT64_MAX ULLONG_MAX
+# endif
+# ifdef LLONG_MAX
+# define ERTS_SINT64_MAX LLONG_MAX
+# endif
+# ifdef LLONG_MIN
+# define ERTS_SINT64_MIN LLONG_MIN
+# endif
+
+typedef long long ErtsMonotonicTime;
+typedef long long ErtsSysHrTime;
#else
typedef ULONGLONG Uint64;
typedef LONGLONG Sint64;
-typedef LONGLONG SysHrTime;
+typedef LONGLONG ErtsMonotonicTime;
+typedef LONGLONG ErtsSysHrTime;
#endif
-extern int sys_init_time(void);
+typedef ErtsMonotonicTime ErtsSystemTime;
+
+ErtsSystemTime erts_os_system_time(void);
+
+#define ERTS_MONOTONIC_TIME_MIN (((ErtsMonotonicTime) 1) << 63)
+#define ERTS_MONOTONIC_TIME_MAX (~ERTS_MONOTONIC_TIME_MIN)
+
+#define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+#define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT 0
+
+struct erts_sys_time_read_only_data__ {
+ ErtsMonotonicTime (*os_monotonic_time)(void);
+ void (*os_times)(ErtsMonotonicTime *, ErtsSystemTime*);
+ ErtsSysHrTime (*sys_hrtime)(void);
+};
+
+typedef struct {
+ union {
+ struct erts_sys_time_read_only_data__ o;
+ char align__[(((sizeof(struct erts_sys_time_read_only_data__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } r;
+} ErtsSysTimeData__;
+
+extern ErtsSysTimeData__ erts_sys_time_data__;
+
+ERTS_GLB_INLINE ErtsMonotonicTime erts_os_monotonic_time(void);
+ERTS_GLB_INLINE void erts_os_times(ErtsMonotonicTime *,
+ ErtsSystemTime *);
+ERTS_GLB_INLINE ErtsSysHrTime erts_sys_hrtime(void);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE ErtsMonotonicTime
+erts_os_monotonic_time(void)
+{
+ return (*erts_sys_time_data__.r.o.os_monotonic_time)();
+}
+
+ERTS_GLB_INLINE void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ (*erts_sys_time_data__.r.o.os_times)(mtimep, stimep);
+}
+
+ERTS_GLB_INLINE ErtsSysHrTime
+erts_sys_hrtime(void)
+{
+ return (*erts_sys_time_data__.r.o.sys_hrtime)();
+}
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
extern void sys_gettimeofday(SysTimeval *tv);
-extern SysHrTime sys_gethrtime(void);
extern clock_t sys_times(SysTimes *buffer);
extern char *win_build_environment(char *);
@@ -207,6 +268,8 @@ extern volatile int erl_fp_exception;
int _finite(double x);
#endif
+#define erts_isfinite _finite
+
/*#define NO_FPE_SIGNALS*/
#define erts_get_current_fp_exception() NULL
#define __ERTS_FP_CHECK_INIT(fpexnp) do {} while (0)
@@ -236,4 +299,16 @@ typedef long ssize_t;
int init_async(int);
int exit_async(void);
#endif
+
+#define ERTS_HAVE_TRY_CATCH 1
+
+#define ERTS_SYS_TRY_CATCH(EXPR,CATCH) \
+ __try { \
+ EXPR; \
+ } \
+ __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) \
+ { \
+ CATCH; \
+ }
+
#endif
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index 0ded6b274e..37d3e16256 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -37,7 +38,7 @@
void erts_sys_init_float(void);
void erl_start(int, char**);
-void erl_exit(int n, char*, ...);
+void erts_exit(int n, char*, ...);
void erl_error(char*, va_list);
void erl_crash_dump(char*, int, char*, ...);
@@ -199,7 +200,7 @@ erts_sys_misc_mem_sz(void)
*/
void sys_tty_reset(int exit_code)
{
- if (exit_code > 0)
+ if (exit_code == ERTS_ERROR_EXIT)
ConWaitForExit();
else
ConNormalExit();
@@ -247,6 +248,27 @@ void erl_sys_args(int* argc, char** argv)
#endif
}
+/*
+ * Function returns 1 if we can read from all values in between
+ * start and stop.
+ */
+int
+erts_sys_is_area_readable(char *start, char *stop) {
+ volatile char tmp;
+ __try
+ {
+ while(start < stop) {
+ tmp = *start;
+ start++;
+ }
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ return 0;
+ }
+ return 1;
+}
+
int erts_sys_prepare_crash_dump(int secs)
{
Port *heart_port;
@@ -1392,39 +1414,46 @@ int parse_command(wchar_t* cmd){
return i;
}
-static BOOL need_quotes(wchar_t *str)
-{
- int in_quote = 0;
- int backslashed = 0;
- int naked_space = 0;
- while (*str != L'\0') {
- switch (*str) {
- case L'\\' :
- backslashed = !backslashed;
- break;
- case L'"':
- if (backslashed) {
- backslashed=0;
- } else {
- in_quote = !in_quote;
- }
- break;
- case L' ':
- backslashed = 0;
- if (!(backslashed || in_quote)) {
- naked_space++;
- }
- break;
- default:
- backslashed = 0;
+/*
+ * Translating of command line arguments to correct format. In the examples
+ * below the '' are not part of the actual string.
+ * 'io:format("hello").' -> 'io:format(\"hello\").'
+ * 'io:format("is anybody in there?").' -> '"io:format(\"is anybody in there?\")."'
+ * 'Just nod if you can hear me.' -> '"Just nod if you can hear me."'
+ * 'Is there ""anyone at home?' -> '"Is there \"\"anyone at home?"'
+ * 'Relax."' -> 'Relax.\"'
+ *
+ * If new == NULL we just calculate the length.
+ *
+ * The reason for having to quote all of the is becasue CreateProcessW removes
+ * one level of escaping since it takes a single long command line rather
+ * than the argument chunks that unix uses.
+ */
+static int escape_and_quote(wchar_t *str, wchar_t *new, BOOL *quoted) {
+ int i, j = 0;
+ if (new == NULL)
+ *quoted = FALSE;
+ else if (*quoted)
+ new[j++] = L'"';
+ for ( i = 0; str[i] != L'\0'; i++,j++) {
+ if (str[i] == L' ' && new == NULL && *quoted == FALSE) {
+ *quoted = TRUE;
+ j++;
+ }
+ /* check if we have to escape quotes */
+ if (str[i] == L'"') {
+ if (new) new[j] = L'\\';
+ j++;
}
- ++str;
+ if (new) new[j] = str[i];
+ }
+ if (*quoted) {
+ if (new) new[j] = L'"';
+ j++;
}
- return (naked_space > 0);
+ return j;
}
-
-
/*
*----------------------------------------------------------------------
@@ -1585,31 +1614,24 @@ create_child_process
wcscpy(appname, execPath);
}
if (argv == NULL) {
- BOOL orig_need_q = need_quotes(execPath);
+ BOOL orig_need_q;
wchar_t *ptr;
- int ocl = wcslen(execPath);
+ int ocl = escape_and_quote(execPath, NULL, &orig_need_q);
if (run_cmd) {
newcmdline = (wchar_t *) erts_alloc(ERTS_ALC_T_TMP,
- (ocl + ((orig_need_q) ? 3 : 1)
- + 11)*sizeof(wchar_t));
+ (ocl + 1 + 11)*sizeof(wchar_t));
memcpy(newcmdline,L"cmd.exe /c ",11*sizeof(wchar_t));
ptr = newcmdline + 11;
} else {
newcmdline = (wchar_t *) erts_alloc(ERTS_ALC_T_TMP,
- (ocl + ((orig_need_q) ? 3 : 1))*sizeof(wchar_t));
+ (ocl + 1)*sizeof(wchar_t));
ptr = (wchar_t *) newcmdline;
}
- if (orig_need_q) {
- *ptr++ = L'"';
- }
- memcpy(ptr,execPath,ocl*sizeof(wchar_t));
- ptr += ocl;
- if (orig_need_q) {
- *ptr++ = L'"';
- }
- *ptr = L'\0';
+ ptr += escape_and_quote(execPath, ptr, &orig_need_q);
+ ptr[0] = L'\0';
} else {
- int sum = 1; /* '\0' */
+ int sum = 0;
+ BOOL *qte = NULL;
wchar_t **ar = argv;
wchar_t *n;
wchar_t *save_arg0 = NULL;
@@ -1620,11 +1642,13 @@ create_child_process
if (run_cmd) {
sum += 11; /* cmd.exe /c */
}
+
+ while (*ar != NULL) ar++;
+ qte = erts_alloc(ERTS_ALC_T_TMP, (ar - argv)*sizeof(BOOL));
+
+ ar = argv;
while (*ar != NULL) {
- sum += wcslen(*ar);
- if (need_quotes(*ar)) {
- sum += 2; /* quotes */
- }
+ sum += escape_and_quote(*ar,NULL,qte+(ar - argv));
sum++; /* space */
++ar;
}
@@ -1636,26 +1660,18 @@ create_child_process
n += 11;
}
while (*ar != NULL) {
- int q = need_quotes(*ar);
- sum = wcslen(*ar);
- if (q) {
- *n++ = L'"';
- }
- memcpy(n,*ar,sum*sizeof(wchar_t));
- n += sum;
- if (q) {
- *n++ = L'"';
- }
+ n += escape_and_quote(*ar,n,qte+(ar - argv));
*n++ = L' ';
++ar;
}
- *(n-1) = L'\0';
+ *(n-1) = L'\0'; /* overwrite last space with '\0' */
if (save_arg0 != NULL) {
argv[0] = save_arg0;
}
+ erts_free(ERTS_ALC_T_TMP, qte);
}
- DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags));
+ DEBUGF((stderr,"Creating child process: %S, createFlags = %d\n", newcmdline, createFlags));
ok = CreateProcessW((wchar_t *) appname,
(wchar_t *) newcmdline,
NULL,
@@ -2190,7 +2206,7 @@ static void fd_stop(ErlDrvData data)
ASSERT(dp->out.flushEvent);
SetEvent(dp->out.flushEvent);
} while (WaitForSingleObject(dp->out.flushReplyEvent, 10) == WAIT_TIMEOUT
- || !(dp->out.flags & DF_THREAD_FLUSHED));
+ && !(dp->out.flags & DF_THREAD_FLUSHED));
}
}
@@ -3094,13 +3110,13 @@ check_supported_os_version(void)
|| int_os_version.dwMajorVersion < major
|| (int_os_version.dwMajorVersion == major
&& int_os_version.dwMinorVersion < minor))
- erl_exit(-1,
+ erts_exit(1,
"Windows version not supported "
"(min required: winnt %d.%d)\n",
major, minor);
}
#else
- erl_exit(-1,
+ erts_exit(1,
"Windows version not supported "
"(min required: win %d.%d)\n",
nt_major, nt_minor);
@@ -3157,25 +3173,31 @@ thr_create_prepare_child(void *vtcdp)
void
erts_sys_pre_init(void)
{
+#ifdef USE_THREADS
+ erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER;
+#endif
int_os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&int_os_version);
check_supported_os_version();
+
#ifdef USE_THREADS
- {
- erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER;
+ eid.thread_create_child_func = thr_create_prepare_child;
+ /* Before creation in parent */
+ eid.thread_create_prepare_func = thr_create_prepare;
+ /* After creation in parent */
+ eid.thread_create_parent_func = thr_create_cleanup;
- eid.thread_create_child_func = thr_create_prepare_child;
- /* Before creation in parent */
- eid.thread_create_prepare_func = thr_create_prepare;
- /* After creation in parent */
- eid.thread_create_parent_func = thr_create_cleanup,
+ erts_thr_init(&eid);
+#endif
+
+ erts_init_sys_time_sup();
- erts_thr_init(&eid);
+#ifdef USE_THREADS
#ifdef ERTS_ENABLE_LOCK_COUNT
- erts_lcnt_init();
+ erts_lcnt_init();
#endif
- }
#endif
+
erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0);
}
@@ -3258,9 +3280,9 @@ erts_sys_schedule_interrupt(int set)
#ifdef ERTS_SMP
void
-erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec)
+erts_sys_schedule_interrupt_timed(int set, ErtsMonotonicTime timeout_time)
{
- erts_check_io_interrupt_timed(set, msec);
+ erts_check_io_interrupt_timed(set, timeout_time);
}
#endif
diff --git a/erts/emulator/sys/win32/sys_env.c b/erts/emulator/sys/win32/sys_env.c
index 9f977ad6c8..67b6e55377 100644
--- a/erts/emulator/sys/win32/sys_env.c
+++ b/erts/emulator/sys/win32/sys_env.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/sys/win32/sys_float.c b/erts/emulator/sys/win32/sys_float.c
index 0e19746cf5..86e822da5b 100644
--- a/erts/emulator/sys/win32/sys_float.c
+++ b/erts/emulator/sys/win32/sys_float.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/sys/win32/sys_interrupt.c b/erts/emulator/sys/win32/sys_interrupt.c
index 36c43e93da..a89211fa8e 100644
--- a/erts/emulator/sys/win32/sys_interrupt.c
+++ b/erts/emulator/sys/win32/sys_interrupt.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -80,7 +81,7 @@ BOOL WINAPI ctrl_handler_ignore_break(DWORD dwCtrlType)
return TRUE;
/* else pour through... */
case CTRL_CLOSE_EVENT:
- erl_exit(0, "");
+ erts_exit(0, "");
break;
}
return TRUE;
@@ -105,7 +106,7 @@ BOOL WINAPI ctrl_handler_replace_intr(DWORD dwCtrlType)
/* else pour through... */
case CTRL_CLOSE_EVENT:
case CTRL_SHUTDOWN_EVENT:
- erl_exit(0, "");
+ erts_exit(0, "");
break;
}
return TRUE;
@@ -132,7 +133,7 @@ BOOL WINAPI ctrl_handler(DWORD dwCtrlType)
return TRUE;
/* else pour through... */
case CTRL_CLOSE_EVENT:
- erl_exit(0, "");
+ erts_exit(0, "");
break;
}
return TRUE;
diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c
index b84c8f85ce..3cf7f7cf07 100644
--- a/erts/emulator/sys/win32/sys_time.c
+++ b/erts/emulator/sys/win32/sys_time.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -25,6 +26,11 @@
#endif
#include "sys.h"
#include "assert.h"
+#include "erl_os_monotonic_time_extender.h"
+#include "erl_time.h"
+
+/* Need to look more closely at qpc before use... */
+#define ERTS_DISABLE_USE_OF_QPC_FOR_MONOTONIC_TIME 1
#define LL_LITERAL(X) ERTS_I64_LITERAL(X)
@@ -61,11 +67,6 @@
(epoch) = ((ull.QuadPart / TICKS_PER_SECOND) - EPOCH_JULIAN_DIFF); \
} while(0)
-static SysHrTime wrap = 0;
-static DWORD last_tick_count = 0;
-static erts_smp_mtx_t wrap_lock;
-static ULONGLONG (WINAPI *pGetTickCount64)(void) = NULL;
-
/* Getting timezone information is a heavy operation, so we want to do this
only once */
@@ -76,27 +77,348 @@ static int days_in_month[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}};
-int
-sys_init_time(void)
+#define ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT 10
+
+/*
+ * erts_os_monotonic_time()
+ */
+
+struct sys_time_internal_state_read_only__ {
+ ULONGLONG (WINAPI *pGetTickCount64)(void);
+ BOOL (WINAPI *pQueryPerformanceCounter)(LARGE_INTEGER *);
+ Sint32 pcf;
+ int using_get_tick_count_time_unit;
+};
+
+struct sys_time_internal_state_read_mostly__ {
+ ErtsOsMonotonicTimeExtendState os_mtime_xtnd;
+};
+
+struct sys_time_internal_state_write_freq__ {
+ erts_smp_mtx_t mtime_mtx;
+ ULONGLONG wrap;
+ ULONGLONG last_tick_count;
+};
+
+__declspec(align(ASSUMED_CACHE_LINE_SIZE)) struct {
+ union {
+ struct sys_time_internal_state_read_only__ o;
+ char align__[(((sizeof(struct sys_time_internal_state_read_only__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } r;
+ union {
+ struct sys_time_internal_state_read_mostly__ m;
+ char align__[(((sizeof(struct sys_time_internal_state_read_mostly__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } wr;
+ union {
+ struct sys_time_internal_state_write_freq__ f;
+ char align__[(((sizeof(struct sys_time_internal_state_write_freq__) - 1)
+ / ASSUMED_CACHE_LINE_SIZE) + 1)
+ * ASSUMED_CACHE_LINE_SIZE];
+ } w;
+} internal_state;
+
+__declspec(align(ASSUMED_CACHE_LINE_SIZE)) ErtsSysTimeData__ erts_sys_time_data__;
+
+
+static ERTS_INLINE ErtsSystemTime
+SystemTime2MilliSec(SYSTEMTIME *stp)
+{
+ ErtsSystemTime stime;
+ FILETIME ft;
+ ULARGE_INTEGER ull;
+
+ SystemTimeToFileTime(stp, &ft);
+ FILETIME_TO_ULI(ull,ft);
+ /* now in 100 ns units */
+ stime = (ErtsSystemTime) ull.QuadPart;
+ stime -= (((ErtsSystemTime) EPOCH_JULIAN_DIFF)
+ * ((ErtsSystemTime) (10*1000*1000)));
+ stime /= (ErtsSystemTime) (10*1000); /* ms */
+ return stime;
+}
+
+static ErtsMonotonicTime
+os_monotonic_time_qpc(void)
{
+ LARGE_INTEGER pc;
+
+ if (!(*internal_state.r.o.pQueryPerformanceCounter)(&pc))
+ erts_exit(ERTS_ABORT_EXIT, "QueryPerformanceCounter() failed\n");
+
+ return (ErtsMonotonicTime) pc.QuadPart;
+}
+
+static void
+os_times_qpc(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ LARGE_INTEGER pc;
+ SYSTEMTIME st;
+ ErtsSystemTime stime;
+ BOOL qpcr;
+
+ qpcr = (*internal_state.r.o.pQueryPerformanceCounter)(&pc);
+ GetSystemTime(&st);
+
+ if (!qpcr)
+ erts_exit(ERTS_ABORT_EXIT, "QueryPerformanceCounter() failed\n");
+
+ *mtimep = (ErtsMonotonicTime) pc.QuadPart;
+
+ stime = SystemTime2MilliSec(&st);
+
+ *stimep = ((ErtsSystemTime)
+ erts_time_unit_conversion((Uint64) stime,
+ (Uint32) 1000,
+ internal_state.r.o.pcf));
+}
+
+static Uint32
+get_tick_count(void)
+{
+ return (Uint32) GetTickCount();
+}
+
+static ErtsMonotonicTime
+os_monotonic_time_gtc32(void)
+{
+ ErtsMonotonicTime mtime;
+ Uint32 ticks = (Uint32) GetTickCount();
+ ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime = ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ return mtime;
+}
+
+static void
+os_times_gtc32(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ SYSTEMTIME st;
+ ErtsSystemTime stime, mtime;
+ Uint32 ticks;
+
+ ticks = (Uint32) GetTickCount();
+ GetSystemTime(&st);
+
+ ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime = ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *mtimep = mtime;
+
+ stime = SystemTime2MilliSec(&st);
+ stime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *stimep = stime;
+
+}
+
+static ErtsMonotonicTime
+os_monotonic_time_gtc64(void)
+{
+ ULONGLONG ticks = (*internal_state.r.o.pGetTickCount64)();
+ ErtsMonotonicTime mtime = (ErtsMonotonicTime) ticks;
+ return mtime << ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+}
+
+static void
+os_times_gtc64(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ SYSTEMTIME st;
+ ErtsSystemTime stime, mtime;
+ ULONGLONG ticks;
+
+ ticks = (*internal_state.r.o.pGetTickCount64)();
+ GetSystemTime(&st);
+
+ mtime = (ErtsMonotonicTime) ticks;
+ mtime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *mtimep = mtime;
+
+ stime = SystemTime2MilliSec(&st);
+ stime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *stimep = stime;
+}
+
+static ErtsSysHrTime
+sys_hrtime_qpc(void)
+{
+ LARGE_INTEGER pc;
+
+ if (!(*internal_state.r.o.pQueryPerformanceCounter)(&pc))
+ erts_exit(ERTS_ABORT_EXIT, "QueryPerformanceCounter() failed\n");
+
+ ASSERT(pc.QuadPart > 0);
+
+ return (ErtsSysHrTime) erts_time_unit_conversion((Uint64) pc.QuadPart,
+ internal_state.r.o.pcf,
+ (Uint32) 1000*1000*1000);
+}
+
+static ErtsSysHrTime
+sys_hrtime_gtc32(void)
+{
+ ErtsSysHrTime time;
+ Uint32 ticks = (Uint32) GetTickCount();
+ ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ tick_count);
+ time = (ErtsSysHrTime) ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ time *= (ErtsSysHrTime) (1000 * 1000);
+ return time;
+}
+
+static ErtsSysHrTime
+sys_hrtime_gtc64(void)
+{
+ ErtsSysHrTime time = (*internal_state.r.o.pGetTickCount64)();
+ time *= (ErtsSysHrTime) (1000*1000);
+ return time;
+}
+
+/*
+ * Init
+ */
+
+void
+sys_init_time(ErtsSysInitTimeResult *init_resp)
+{
+ ErtsMonotonicTime (*os_mtime_func)(void);
+ void (*os_times_func)(ErtsMonotonicTime *, ErtsSystemTime *);
+ ErtsSysHrTime (*sys_hrtime_func)(void) = NULL;
+ ErtsMonotonicTime time_unit;
char kernel_dll_name[] = "kernel32";
HMODULE module;
+ init_resp->os_monotonic_time_info.clock_id = NULL;
+
module = GetModuleHandle(kernel_dll_name);
- pGetTickCount64 = (module != NULL) ?
- (ULONGLONG (WINAPI *)(void))
- GetProcAddress(module,"GetTickCount64") :
- NULL;
+ if (!module) {
+ get_tick_count:
+ erts_smp_mtx_init(&internal_state.w.f.mtime_mtx,
+ "os_monotonic_time");
+ internal_state.w.f.wrap = 0;
+ internal_state.w.f.last_tick_count = 0;
+
+ init_resp->os_monotonic_time_info.func = "GetTickCount";
+ init_resp->os_monotonic_time_info.locked_use = 0;
+ /* 10-16 ms resolution according to MicroSoft documentation */
+ init_resp->os_monotonic_time_info.resolution = 100; /* 10 ms */
+ time_unit = (ErtsMonotonicTime) 1000;
+ time_unit <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ internal_state.r.o.using_get_tick_count_time_unit = 1;
+ os_mtime_func = os_monotonic_time_gtc32;
+ os_times_func = os_times_gtc32;
+ init_resp->os_monotonic_time_info.extended = 1;
+ erts_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd,
+ get_tick_count,
+ 60*60*24*7); /* Check once a week */
+ if (!sys_hrtime_func)
+ sys_hrtime_func = sys_hrtime_gtc32;
+ }
+ else {
+ int major, minor, build;
+
+ os_version(&major, &minor, &build);
+
+ if (major < 6) {
+
+ get_tick_count64:
+
+ internal_state.r.o.pGetTickCount64
+ = ((ULONGLONG (WINAPI *)(void))
+ GetProcAddress(module, "GetTickCount64"));
+ if (!internal_state.r.o.pGetTickCount64)
+ goto get_tick_count;
+
+ init_resp->os_monotonic_time_info.func = "GetTickCount64";
+ init_resp->os_monotonic_time_info.locked_use = 0;
+ /* 10-16 ms resolution according to MicroSoft documentation */
+ init_resp->os_monotonic_time_info.resolution = 100; /* 10 ms */
+ time_unit = (ErtsMonotonicTime) 1000;
+ time_unit <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ internal_state.r.o.using_get_tick_count_time_unit = 1;
+ os_mtime_func = os_monotonic_time_gtc64;
+ os_times_func = os_times_gtc64;
+ if (!sys_hrtime_func)
+ sys_hrtime_func = sys_hrtime_gtc64;
+ }
+ else { /* Vista or newer... */
+
+ LARGE_INTEGER pf;
+ BOOL (WINAPI *QPF)(LARGE_INTEGER *);
+
+ QPF = ((BOOL (WINAPI *)(LARGE_INTEGER *))
+ GetProcAddress(module, "QueryPerformanceFrequency"));
+ if (!QPF)
+ goto get_tick_count64;
+ if (!(*QPF)(&pf))
+ goto get_tick_count64;
+
+ internal_state.r.o.pQueryPerformanceCounter
+ = ((BOOL (WINAPI *)(LARGE_INTEGER *))
+ GetProcAddress(module, "QueryPerformanceCounter"));
+ if (!internal_state.r.o.pQueryPerformanceCounter)
+ goto get_tick_count64;
+
+ if (pf.QuadPart > (((LONGLONG) 1) << 32))
+ goto get_tick_count64;
+
+ internal_state.r.o.pcf = (Uint32) pf.QuadPart;
+ sys_hrtime_func = sys_hrtime_qpc;
+
+ /*
+ * We only use QueryPerformanceCounter() for
+ * os-monotonic-time if its frequency is equal
+ * to, or larger than GHz in order to ensure
+ * that the user wont be able to observe faulty
+ * order between values retrieved on different threads.
+ */
+ if (pf.QuadPart < (LONGLONG) 1000*1000*1000)
+ goto get_tick_count64;
+
+ if (ERTS_DISABLE_USE_OF_QPC_FOR_MONOTONIC_TIME)
+ goto get_tick_count64;
+
+ init_resp->os_monotonic_time_info.func = "QueryPerformanceCounter";
+ init_resp->os_monotonic_time_info.locked_use = 0;
+ time_unit = (ErtsMonotonicTime) pf.QuadPart;
+ internal_state.r.o.using_get_tick_count_time_unit = 0;
+ init_resp->os_monotonic_time_info.resolution = time_unit;
+ os_mtime_func = os_monotonic_time_qpc;
+ os_times_func = os_times_qpc;
+ }
+ }
+
+ erts_sys_time_data__.r.o.os_monotonic_time = os_mtime_func;
+ erts_sys_time_data__.r.o.os_times = os_times_func;
+ init_resp->os_monotonic_time_unit = time_unit;
+ init_resp->have_os_monotonic_time = 1;
+ init_resp->have_corrected_os_monotonic_time = 0;
+ init_resp->sys_clock_resolution = 1;
+
+ init_resp->os_system_time_info.func = "GetSystemTime";
+ init_resp->os_system_time_info.clock_id = NULL;
+ init_resp->os_system_time_info.resolution = 100;
+ init_resp->os_system_time_info.locked_use = 0;
if(GetTimeZoneInformation(&static_tzi) &&
static_tzi.StandardDate.wMonth != 0 &&
static_tzi.DaylightDate.wMonth != 0) {
have_static_tzi = 1;
}
+}
- erts_smp_mtx_init(&wrap_lock, "sys_gethrtime");
-
- return 1;
+void
+erts_late_sys_init_time(void)
+{
+ if (erts_sys_time_data__.r.o.os_monotonic_time == os_monotonic_time_gtc32)
+ erts_late_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd);
}
/* Returns a switchtimes for DST as UTC filetimes given data from a
@@ -377,41 +699,27 @@ sys_gettimeofday(SysTimeval *tv)
EPOCH_JULIAN_DIFF);
}
-extern int erts_initialized;
-SysHrTime
-sys_gethrtime(void)
+ErtsSystemTime
+erts_os_system_time(void)
{
- if (pGetTickCount64 != NULL) {
- return ((SysHrTime) pGetTickCount64()) * LL_LITERAL(1000000);
- } else {
- DWORD ticks;
- SysHrTime res;
- erts_smp_mtx_lock(&wrap_lock);
- ticks = (SysHrTime) (GetTickCount() & 0x7FFFFFFF);
- if (ticks < (SysHrTime) last_tick_count) {
- /* Detect a race that should no longer be here... */
- if ((((SysHrTime) last_tick_count) - ((SysHrTime) ticks)) > 1000) {
- wrap += LL_LITERAL(1) << 31;
- } else {
- /*
- * XXX Debug: Violates locking order, remove all this,
- * after testing!
- */
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp, "Did not wrap when last_tick %d "
- "and tick %d",
- last_tick_count, ticks);
- erts_send_error_to_logger_nogl(dsbufp);
- ticks = last_tick_count;
- }
- }
- last_tick_count = ticks;
- res = ((((LONGLONG) ticks) + wrap) * LL_LITERAL(1000000));
- erts_smp_mtx_unlock(&wrap_lock);
- return res;
+ SYSTEMTIME st;
+ ErtsSystemTime stime;
+
+ GetSystemTime(&st);
+ stime = SystemTime2MilliSec(&st);
+
+ if (internal_state.r.o.using_get_tick_count_time_unit) {
+ stime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ return stime;
}
+
+ return ((ErtsSystemTime)
+ erts_time_unit_conversion((Uint64) stime,
+ (Uint32) 1000,
+ internal_state.r.o.pcf));
}
+
clock_t
sys_times(SysTimes *buffer) {
clock_t kernel_ticks = (GetTickCount() /
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index dfbe47786a..77614d455c 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -108,6 +109,7 @@ MODULES= \
trace_call_time_SUITE \
scheduler_SUITE \
old_scheduler_SUITE \
+ unique_SUITE \
z_SUITE \
old_mod \
long_timers_test \
@@ -124,7 +126,8 @@ NO_OPT= bs_bincomp \
bs_match_tail \
bs_match_misc \
bs_utf \
- guard
+ guard \
+ map
NATIVE= hibernate
diff --git a/erts/emulator/test/a_SUITE.erl b/erts/emulator/test/a_SUITE.erl
index 17579be416..16f060fe34 100644
--- a/erts/emulator/test/a_SUITE.erl
+++ b/erts/emulator/test/a_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/after_SUITE.erl b/erts/emulator/test/after_SUITE.erl
index 7cc329cc69..5017a83185 100644
--- a/erts/emulator/test/after_SUITE.erl
+++ b/erts/emulator/test/after_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -27,7 +28,8 @@
init_per_group/2,end_per_group/2,
t_after/1, receive_after/1, receive_after_big/1,
receive_after_errors/1, receive_var_zero/1, receive_zero/1,
- multi_timeout/1, receive_after_32bit/1]).
+ multi_timeout/1, receive_after_32bit/1,
+ receive_after_blast/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -40,7 +42,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[t_after, receive_after, receive_after_big,
receive_after_errors, receive_var_zero, receive_zero,
- multi_timeout, receive_after_32bit].
+ multi_timeout, receive_after_32bit, receive_after_blast].
groups() ->
[].
@@ -70,30 +72,23 @@ end_per_testcase(_Func, Config) ->
t_after(Config) when is_list(Config) ->
?line spawn(fun frequent_process/0),
?line Period = test_server:minutes(1),
- ?line Before = erlang:now(),
+ ?line Before = erlang:monotonic_time(),
receive
after Period ->
- ?line After = erlang:now(),
+ ?line After = erlang:monotonic_time(),
?line report(Period, Before, After)
end.
-
report(Period, Before, After) ->
- ?line Elapsed = (element(1, After)*1000000000
- +element(2, After)*1000
- +element(3, After) div 1000) -
- (element(1,Before)*1000000000
- + element(2,Before)*1000 + element(3,Before) div 1000),
- ?line case Elapsed*100 / Period of
- Percent when Percent > 100.10 ->
- ?line test_server:fail({too_inaccurate, Percent});
- Percent when Percent < 100.0 ->
- ?line test_server:fail({too_early, Percent});
- Percent ->
- ?line Comment = io_lib:format("Elapsed/expected: ~.2f %",
- [Percent]),
- {comment, lists:flatten(Comment)}
- end.
+ case erlang:convert_time_unit(After - Before, native, 100*1000) / Period of
+ Percent when Percent > 100.10 ->
+ test_server:fail({too_inaccurate, Percent});
+ Percent when Percent < 100.0 ->
+ test_server:fail({too_early, Percent});
+ Percent ->
+ Comment = io_lib:format("Elapsed/expected: ~.2f %", [Percent]),
+ {comment, lists:flatten(Comment)}
+ end.
frequent_process() ->
receive
@@ -251,4 +246,26 @@ recv_after_32bit(I, T) when I rem 2 =:= 0 ->
receive after T -> exit(timeout) end;
recv_after_32bit(_, _) ->
receive after 16#ffffFFFF -> exit(timeout) end.
-
+
+blaster() ->
+ receive
+ {go, TimeoutTime} ->
+ Tmo = TimeoutTime - erlang:monotonic_time(milli_seconds),
+ receive after Tmo -> ok end
+ end.
+
+spawn_blasters(0) ->
+ [];
+spawn_blasters(N) ->
+ [spawn_monitor(fun () -> blaster() end)|spawn_blasters(N-1)].
+
+receive_after_blast(Config) when is_list(Config) ->
+ PMs = spawn_blasters(10000),
+ TimeoutTime = erlang:monotonic_time(milli_seconds) + 5000,
+ lists:foreach(fun ({P, _}) -> P ! {go, TimeoutTime} end, PMs),
+ lists:foreach(fun ({P, M}) ->
+ receive
+ {'DOWN', M, process, P, normal} ->
+ ok
+ end
+ end, PMs).
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 35c44c229a..aa6a1fbcdc 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
@@ -30,7 +31,8 @@
rbtree/1,
mseg_clear_cache/1,
erts_mmap/1,
- cpool/1]).
+ cpool/1,
+ migration/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -42,7 +44,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic, coalesce, threads, realloc_copy, bucket_index,
- bucket_mask, rbtree, mseg_clear_cache, erts_mmap, cpool].
+ bucket_mask, rbtree, mseg_clear_cache, erts_mmap, cpool, migration].
groups() ->
[].
@@ -63,7 +65,7 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
- [{watchdog, Dog},{testcase, Case}|Config].
+ [{watchdog, Dog}, {testcase, Case}, {debug,false} | Config].
end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
@@ -111,6 +113,14 @@ cpool(suite) -> [];
cpool(doc) -> [];
cpool(Cfg) -> ?line drv_case(Cfg).
+migration(Cfg) ->
+ case erlang:system_info(smp_support) of
+ true ->
+ drv_case(Cfg, concurrent, "+MZe true");
+ false ->
+ {skipped, "No smp"}
+ end.
+
erts_mmap(Config) when is_list(Config) ->
case {?t:os_type(), is_halfword_vm()} of
{{unix, _}, false} ->
@@ -175,18 +185,17 @@ erts_mmap_do(Config, SCO, SCRPM, SCRFSD) ->
%% %%
drv_case(Config) ->
- drv_case(Config, "").
+ drv_case(Config, one_shot, "").
-drv_case(Config, Command) when is_list(Config),
- is_list(Command) ->
+drv_case(Config, Mode, NodeOpts) when is_list(Config) ->
case ?t:os_type() of
{Family, _} when Family == unix; Family == win32 ->
- ?line {ok, Node} = start_node(Config),
+ ?line {ok, Node} = start_node(Config, NodeOpts),
?line Self = self(),
?line Ref = make_ref(),
?line spawn_link(Node,
fun () ->
- Res = run_drv_case(Config, Command),
+ Res = run_drv_case(Config, Mode),
Self ! {Ref, Res}
end),
?line Result = receive {Ref, Rslt} -> Rslt end,
@@ -198,62 +207,183 @@ drv_case(Config, Command) when is_list(Config),
| io_lib:format("~p",[SkipOs])])}
end.
-run_drv_case(Config, Command) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line CaseName = ?config(testcase,Config),
- case erl_ddll:load_driver(DataDir, CaseName) of
- ok -> ok;
- {error, Error} ->
- io:format("~s\n", [erl_ddll:format_error(Error)]),
- ?line ?t:fail()
+run_drv_case(Config, Mode) ->
+ DataDir = ?config(data_dir,Config),
+ CaseName = ?config(testcase,Config),
+ File = filename:join(DataDir, CaseName),
+ {ok,CaseName,Bin} = compile:file(File, [binary,return_errors]),
+ {module,CaseName} = erlang:load_module(CaseName,Bin),
+ print_stats(CaseName),
+ ok = CaseName:init(File),
+
+ SlaveState = slave_init(CaseName),
+ case Mode of
+ one_shot ->
+ Result = one_shot(CaseName);
+
+ concurrent ->
+ Result = concurrent(CaseName)
end,
- ?line Port = open_port({spawn, atom_to_list(CaseName)}, []),
- ?line true = is_port(Port),
- ?line Port ! {self(), {command, Command}},
- ?line Result = receive_drv_result(Port, CaseName),
- ?line Port ! {self(), close},
- ?line receive
- {Port, closed} ->
- ok
- end,
- ?line ok = erl_ddll:unload_driver(CaseName),
- ?line Result.
-
-receive_drv_result(Port, CaseName) ->
- ?line receive
- {print, Port, CaseName, Str} ->
- ?line ?t:format("~s", [Str]),
- ?line receive_drv_result(Port, CaseName);
- {'EXIT', Port, Error} ->
- ?line ?t:fail(Error);
- {'EXIT', error, Error} ->
- ?line ?t:fail(Error);
- {failed, Port, CaseName, Comment} ->
- ?line ?t:fail(Comment);
- {skipped, Port, CaseName, Comment} ->
- ?line {skipped, Comment};
- {succeeded, Port, CaseName, ""} ->
- ?line succeeded;
- {succeeded, Port, CaseName, Comment} ->
- ?line {comment, Comment}
- end.
-
-start_node(Config) ->
- start_node(Config, []).
+
+ wait_for_memory_deallocations(),
+ print_stats(CaseName),
+
+ true = erlang:delete_module(CaseName),
+ slave_end(SlaveState),
+ Result.
+
+slave_init(migration) ->
+ A0 = case application:start(sasl) of
+ ok -> [sasl];
+ _ -> []
+ end,
+ case application:start(os_mon) of
+ ok -> [os_mon|A0];
+ _ -> A0
+ end;
+slave_init(_) -> [].
+
+slave_end(Apps) ->
+ lists:foreach(fun (A) -> application:stop(A) end, Apps).
+
+wait_for_memory_deallocations() ->
+ try
+ erts_debug:set_internal_state(wait, deallocations)
+ catch
+ error:undef ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ wait_for_memory_deallocations()
+ end.
+
+print_stats(migration) ->
+ {Btot,Ctot} = lists:foldl(fun({instance,Inr,Istats}, {Bacc,Cacc}) ->
+ {mbcs,MBCS} = lists:keyfind(mbcs, 1, Istats),
+ Btup = lists:keyfind(blocks, 1, MBCS),
+ Ctup = lists:keyfind(carriers, 1, MBCS),
+ io:format("{instance,~p,~p,~p}\n", [Inr, Btup, Ctup]),
+ {tuple_add(Bacc,Btup),tuple_add(Cacc,Ctup)};
+ (_, Acc) -> Acc
+ end,
+ {{blocks,0,0,0},{carriers,0,0,0}},
+ erlang:system_info({allocator,test_alloc})),
+
+ io:format("Number of blocks : ~p\n", [Btot]),
+ io:format("Number of carriers: ~p\n", [Ctot]);
+
+print_stats(_) -> ok.
+
+tuple_add(T1, T2) ->
+ list_to_tuple(lists:zipwith(fun(E1,E2) when is_number(E1), is_number(E2) ->
+ E1 + E2;
+ (A,A) ->
+ A
+ end,
+ tuple_to_list(T1), tuple_to_list(T2))).
+
+
+one_shot(CaseName) ->
+ State = CaseName:start({1, 0, erlang:system_info(build_type)}),
+ Result0 = CaseName:run(State),
+ false = (Result0 =:= continue),
+ Result1 = handle_result(State, Result0),
+ CaseName:stop(State),
+ Result1.
+
+
+many_shot(CaseName, I, Mem) ->
+ State = CaseName:start({I, Mem, erlang:system_info(build_type)}),
+ Result1 = repeat_while(fun() ->
+ Result0 = CaseName:run(State),
+ handle_result(State, Result0)
+ end,
+ 10*1000, I),
+ CaseName:stop(State),
+ flush_log(),
+ Result1.
+
+concurrent(CaseName) ->
+ NSched = erlang:system_info(schedulers),
+ Mem = (free_memory() * 3) div 4,
+ PRs = lists:map(fun(I) -> spawn_opt(fun() ->
+ many_shot(CaseName, I,
+ Mem div NSched)
+ end,
+ [monitor, {scheduler,I}])
+ end,
+ lists:seq(1, NSched)),
+ lists:foreach(fun({Pid,Ref}) ->
+ receive {'DOWN', Ref, process, Pid, Reason} ->
+ Reason
+ end
+ end,
+ PRs),
+ ok.
+
+repeat_while(Fun, Timeout, I) ->
+ TRef = erlang:start_timer(Timeout, self(), timeout),
+ R = repeat_while_loop(Fun, TRef, I),
+ erlang:cancel_timer(TRef, [{async,true},{info,false}]),
+ R.
+
+repeat_while_loop(Fun, TRef, I) ->
+ receive
+ {timeout, TRef, timeout} ->
+ io:format("~p: Timeout, enough is enough.",[I]),
+ succeeded
+ after 0 ->
+ %%io:format("~p calls fun\n", [self()]),
+ case Fun() of
+ continue -> repeat_while_loop(Fun, TRef, I);
+ R -> R
+ end
+ end.
+
+flush_log() ->
+ receive
+ {print, Str} ->
+ ?t:format("~s", [Str]),
+ flush_log()
+ after 0 ->
+ ok
+ end.
+
+handle_result(_State, Result0) ->
+ flush_log(),
+ case Result0 of
+ {'EXIT', Error} ->
+ ?line ?t:fail(Error);
+ {'EXIT', error, Error} ->
+ ?line ?t:fail(Error);
+ {failed, Comment} ->
+ ?line ?t:fail(Comment);
+ {skipped, Comment} ->
+ ?line {skipped, Comment};
+ {succeeded, ""} ->
+ ?line succeeded;
+ {succeeded, Comment} ->
+ ?line {comment, Comment};
+ continue ->
+ continue
+ end.
+
start_node(Config, Opts) when is_list(Config), is_list(Opts) ->
- ?line Pa = filename:dirname(code:which(?MODULE)),
- ?line {A, B, C} = now(),
- ?line Name = list_to_atom(atom_to_list(?MODULE)
- ++ "-"
- ++ atom_to_list(?config(testcase, Config))
- ++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)),
- ?line ?t:start_node(Name, slave, [{args, Opts++" -pa "++Pa}]).
+ case ?config(debug,Config) of
+ true -> {ok, node()};
+ _ -> start_node_1(Config, Opts)
+ end.
+start_node_1(Config, Opts) ->
+ Pa = filename:dirname(code:which(?MODULE)),
+ Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(?config(testcase, Config))
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-"
+ ++ integer_to_list(erlang:unique_integer([positive]))),
+ ?t:start_node(Name, slave, [{args, Opts++" -pa "++Pa}]).
+
+stop_node(Node) when Node =:= node() -> ok;
stop_node(Node) ->
?t:stop_node(Node).
@@ -263,3 +393,23 @@ is_halfword_vm() ->
{4, 8} -> true;
{WS, WS} -> false
end.
+
+free_memory() ->
+ %% Free memory in MB.
+ try
+ SMD = memsup:get_system_memory_data(),
+ {value, {free_memory, Free}} = lists:keysearch(free_memory, 1, SMD),
+ TotFree = (Free +
+ case lists:keysearch(cached_memory, 1, SMD) of
+ {value, {cached_memory, Cached}} -> Cached;
+ false -> 0
+ end +
+ case lists:keysearch(buffered_memory, 1, SMD) of
+ {value, {buffered_memory, Buffed}} -> Buffed;
+ false -> 0
+ end),
+ TotFree div (1024*1024)
+ catch
+ error : undef ->
+ ?t:fail({"os_mon not built"})
+ end.
diff --git a/erts/emulator/test/alloc_SUITE_data/Makefile.src b/erts/emulator/test/alloc_SUITE_data/Makefile.src
index 1d4286e671..e31de54e1b 100644
--- a/erts/emulator/test/alloc_SUITE_data/Makefile.src
+++ b/erts/emulator/test/alloc_SUITE_data/Makefile.src
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -24,7 +25,8 @@ TEST_DRVS = basic@dll@ \
bucket_mask@dll@ \
rbtree@dll@ \
mseg_clear_cache@dll@ \
- cpool@dll@
+ cpool@dll@ \
+ migration@dll@
CC = @CC@
LD = @LD@
diff --git a/erts/emulator/test/alloc_SUITE_data/allocator_test.h b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
index 2d6c5f9dc7..97ee58cdad 100644
--- a/erts/emulator/test/alloc_SUITE_data/allocator_test.h
+++ b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -19,9 +20,20 @@
#ifndef ALLOCATOR_TEST_H__
#define ALLOCATOR_TEST_H__
-typedef ErlDrvUInt Ulong;
+#if SIZEOF_VOID_P == SIZEOF_INT
+typedef unsigned int Ulong;
+#elif SIZEOF_VOID_P == SIZEOF_LONG
+typedef unsigned long Ulong;
+#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
+typedef unsigned long long Ulong;
+#else
+# error No pointer sized integer type found ???
+#endif
-#ifndef __WIN32__
+#ifdef __WIN32__
+typedef Ulong erts_alc_test_Fn(Ulong, Ulong, Ulong, Ulong);
+# define erts_alc_test ((erts_alc_test_Fn*)WinDynNifCallbacks.erts_alc_test)
+#else
Ulong erts_alc_test(Ulong, Ulong, Ulong, Ulong);
#endif
@@ -84,6 +96,7 @@ typedef void* erts_cond;
#define CPOOL_DELETE(A,B) ((Carrier_t *) ALC_TEST2(0x022, (A), (B)))
#define CPOOL_IS_EMPTY(A) ((int) ALC_TEST1(0x023, (A)))
#define CPOOL_IS_IN_POOL(A,B) ((int) ALC_TEST2(0x024, (A), (B)))
+#define UMEM2BLK_TEST(P) ((Block_t*) ALC_TEST1(0x025, (P)))
/* From erl_goodfit_alloc.c */
#define BKT_IX(A, S) ((Ulong) ALC_TEST2(0x100, (A), (S)))
@@ -141,5 +154,9 @@ typedef void* erts_cond;
#define THR_JOIN(T) ((void) ALC_TEST1(0xf11, (T)))
#define THR_EXIT(R) ((void) ALC_TEST1(0xf12, (R)))
#define IS_SMP_ENABLED ((int) ALC_TEST0(0xf13))
+#define ALLOC_TEST(S) ((void*) ALC_TEST1(0xf14, (S)))
+#define FREE_TEST(P) ((void) ALC_TEST1(0xf15, (P)))
+#define SET_TEST_MBC_USER_HEADER(SZ,CMBC,DMBC) ((int)ALC_TEST3(0xf16, (SZ), (CMBC), (DMBC)))
+#define GET_TEST_MBC_SIZE() ((int) ALC_TEST0(0xf17))
#endif
diff --git a/erts/emulator/test/alloc_SUITE_data/basic.c b/erts/emulator/test/alloc_SUITE_data/basic.c
index 0c27665712..debb3d7ebe 100644
--- a/erts/emulator/test/alloc_SUITE_data/basic.c
+++ b/erts/emulator/test/alloc_SUITE_data/basic.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -59,3 +60,6 @@ testcase_cleanup(TestCaseState_t *tcs)
if (tcs->extra)
STOP_ALC((Allctr_t *) tcs->extra);
}
+
+ERL_NIF_INIT(basic, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/basic.erl b/erts/emulator/test/alloc_SUITE_data/basic.erl
new file mode 100644
index 0000000000..a018fd5582
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/basic.erl
@@ -0,0 +1,10 @@
+-module(basic).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_index.c b/erts/emulator/test/alloc_SUITE_data/bucket_index.c
index 32fd16fc10..45cb53fbf7 100644
--- a/erts/emulator/test/alloc_SUITE_data/bucket_index.c
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_index.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -112,3 +113,5 @@ test_it(TestCaseState_t *tcs, unsigned sbct)
sbct ? sbct_buf : "default");
}
+ERL_NIF_INIT(bucket_index, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_index.erl b/erts/emulator/test/alloc_SUITE_data/bucket_index.erl
new file mode 100644
index 0000000000..c54f54e2f5
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_index.erl
@@ -0,0 +1,10 @@
+-module(bucket_index).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_mask.c b/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
index 34979cacf1..c94c265f4e 100644
--- a/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -51,7 +52,7 @@ testcase_run(TestCaseState_t *tcs)
typedef struct linked_block {
struct linked_block* next;
}Linked;
- Linked* link;
+ Linked* link = NULL;
Linked* fence_list;
Linked* pad_list;
void* tmp;
@@ -182,3 +183,5 @@ testcase_run(TestCaseState_t *tcs)
tcs->extra = NULL;
}
+ERL_NIF_INIT(bucket_mask, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_mask.erl b/erts/emulator/test/alloc_SUITE_data/bucket_mask.erl
new file mode 100644
index 0000000000..589a50e1fa
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_mask.erl
@@ -0,0 +1,10 @@
+-module(bucket_mask).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/coalesce.c b/erts/emulator/test/alloc_SUITE_data/coalesce.c
index 9da49a0d14..7791409a34 100644
--- a/erts/emulator/test/alloc_SUITE_data/coalesce.c
+++ b/erts/emulator/test/alloc_SUITE_data/coalesce.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -316,3 +317,6 @@ testcase_cleanup(TestCaseState_t *tcs)
if (tcs->extra)
STOP_ALC((Allctr_t *) tcs->extra);
}
+
+ERL_NIF_INIT(coalesce, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/coalesce.erl b/erts/emulator/test/alloc_SUITE_data/coalesce.erl
new file mode 100644
index 0000000000..453c726c4e
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/coalesce.erl
@@ -0,0 +1,10 @@
+-module(coalesce).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/cpool.c b/erts/emulator/test/alloc_SUITE_data/cpool.c
index 276ed7be04..73026cc758 100644
--- a/erts/emulator/test/alloc_SUITE_data/cpool.c
+++ b/erts/emulator/test/alloc_SUITE_data/cpool.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -85,13 +86,13 @@ thread_func(void *arg)
for (i = 0; i < (TEST_NO_CARRIERS_PER_THREAD+TEST_CARRIERS_OFFSET); i++) {
int d;
if (i < TEST_NO_CARRIERS_PER_THREAD) {
- CPOOL_INSERT(alloc, crr[i]);
+ (void) CPOOL_INSERT(alloc, crr[i]);
if ((i & 0x7) == 0)
FATAL_ASSERT(CPOOL_IS_IN_POOL(alloc, crr[i]));
}
d = i-TEST_CARRIERS_OFFSET;
if (d >= 0) {
- CPOOL_DELETE(alloc, crr[d]);
+ (void) CPOOL_DELETE(alloc, crr[d]);
if ((d & 0x7) == 0)
FATAL_ASSERT(!CPOOL_IS_IN_POOL(alloc, crr[d]));
}
@@ -128,7 +129,7 @@ testcase_run(TestCaseState_t *tcs)
for (c = 0; c < TEST_NO_CARRIERS_PER_THREAD; c++) {
Carrier_t *crr = (Carrier_t *) p;
p += zcrr_sz;
- ZERO_CRR_INIT(alloc, crr);
+ (void) ZERO_CRR_INIT(alloc, crr);
threads[t].crr[c] = crr;
}
}
@@ -155,3 +156,6 @@ testcase_run(TestCaseState_t *tcs)
ASSERT(tcs, no_threads == TEST_NO_THREADS);
}
+
+ERL_NIF_INIT(cpool, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/cpool.erl b/erts/emulator/test/alloc_SUITE_data/cpool.erl
new file mode 100644
index 0000000000..89053471fa
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/cpool.erl
@@ -0,0 +1,10 @@
+-module(cpool).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/migration.c b/erts/emulator/test/alloc_SUITE_data/migration.c
new file mode 100644
index 0000000000..b006360043
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/migration.c
@@ -0,0 +1,343 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2014. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Test the carrier migration logic
+ */
+
+#ifndef __WIN32__
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "testcase_driver.h"
+#include "allocator_test.h"
+
+#define FATAL_ASSERT(A) \
+ ((void) ((A) \
+ ? 1 \
+ : (fatal_assert_failed(#A, \
+ (char *) __FILE__, \
+ __LINE__), \
+ 0)))
+
+static void
+fatal_assert_failed(char* expr, char* file, int line)
+{
+ fflush(stdout);
+ fprintf(stderr, "%s:%d: Assertion failed: %s\n",
+ file, line, expr);
+ fflush(stderr);
+ abort();
+}
+
+
+char *
+testcase_name(void)
+{
+ return "migration";
+}
+
+/* Turns out random_r() is a nonstandard glibc extension.
+#define HAVE_RANDOM_R
+*/
+#ifdef HAVE_RANDOM_R
+
+typedef struct { struct random_data rnd; char rndbuf[32]; } MyRandState;
+
+static void myrand_init(MyRandState* mrs, unsigned int seed)
+{
+ int res;
+ memset(&mrs->rnd, 0, sizeof(mrs->rnd));
+ res = initstate_r(seed, mrs->rndbuf, sizeof(mrs->rndbuf), &mrs->rnd);
+ FATAL_ASSERT(res == 0);
+}
+
+static int myrand(MyRandState* mrs)
+{
+ int32_t x;
+ int res = random_r(&mrs->rnd, &x);
+ FATAL_ASSERT(res == 0);
+ return (int)x;
+}
+
+#else /* !HAVE_RANDOM_R */
+
+typedef unsigned int MyRandState;
+
+static void myrand_init(MyRandState* mrs, unsigned int seed)
+{
+ *mrs = seed;
+}
+
+static int myrand(MyRandState* mrs)
+{
+ /* Taken from rand(3) man page.
+ * Modified to return a full 31-bit value by using low half of *mrs as well.
+ */
+ *mrs = (*mrs) * 1103515245 + 12345;
+ return (int) (((*mrs >> 16) | (*mrs << 16)) & ~(1 << 31));
+}
+
+#endif /* !HAVE_RANDOM_R */
+
+#define MAX_BLOCK_PER_THR 200
+#define BLOCKS_PER_MBC 10
+#define MAX_ROUNDS 10000
+
+typedef struct MyBlock_ {
+ struct MyBlock_* next;
+ struct MyBlock_** prevp;
+} MyBlock;
+
+typedef struct {
+ MyBlock* blockv[MAX_BLOCK_PER_THR];
+ MyRandState rand_state;
+ enum { GROWING, SHRINKING, CLEANUP, DONE } phase;
+ int nblocks;
+ int goal_nblocks;
+ int round;
+ int nr_of_migrations;
+ int nr_of_carriers;
+ int max_blocks_in_mbc;
+ int block_size;
+ int max_nblocks;
+} MigrationState;
+
+typedef struct {
+ ErlNifMutex* mtx;
+ int nblocks;
+ MyBlock* first;
+ MigrationState* employer;
+} MyCrrInfo;
+
+
+static int crr_info_offset = -1;
+static void (*orig_create_mbc_fn)(Allctr_t *allctr, Carrier_t *carrier);
+static void (*orig_destroying_mbc_fn)(Allctr_t *allctr, Carrier_t *carrier);
+
+static void my_creating_mbc(Allctr_t *allctr, Carrier_t *carrier)
+{
+ MyCrrInfo* mci = (MyCrrInfo*) ((char*)carrier + crr_info_offset);
+ if (orig_create_mbc_fn)
+ orig_create_mbc_fn(allctr, carrier);
+
+ mci->mtx = enif_mutex_create("alloc_SUITE.migration");
+ mci->nblocks = 0;
+ mci->first = NULL;
+ mci->employer = NULL;
+}
+
+static void my_destroying_mbc(Allctr_t *allctr, Carrier_t *carrier)
+{
+ MyCrrInfo* mci = (MyCrrInfo*) ((char*)carrier + crr_info_offset);
+
+ FATAL_ASSERT(mci->nblocks == 0);
+ FATAL_ASSERT(mci->first == NULL);
+ enif_mutex_destroy(mci->mtx);
+
+ if (orig_destroying_mbc_fn)
+ orig_destroying_mbc_fn(allctr, carrier);
+}
+
+static int migration_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ void* creating_mbc_arg = (void*)my_creating_mbc;
+ void* destroying_mbc_arg = (void*)my_destroying_mbc;
+
+ if (testcase_nif_init(env, priv_data, load_info))
+ return -1;
+
+ crr_info_offset = SET_TEST_MBC_USER_HEADER(sizeof(MyCrrInfo),
+ &creating_mbc_arg,
+ &destroying_mbc_arg);
+ FATAL_ASSERT(crr_info_offset >= 0);
+ orig_create_mbc_fn = creating_mbc_arg;
+ orig_destroying_mbc_fn = destroying_mbc_arg;
+
+ return 0;
+}
+
+static void add_block(MyBlock* p, MigrationState* state)
+{
+ MyCrrInfo* mci = (MyCrrInfo*)((char*)BLK_TO_MBC(UMEM2BLK_TEST(p)) + crr_info_offset);
+
+ enif_mutex_lock(mci->mtx);
+ if (++mci->nblocks > state->max_blocks_in_mbc)
+ state->max_blocks_in_mbc = mci->nblocks;
+ p->next = mci->first;
+ p->prevp = &mci->first;
+ mci->first = p;
+ if (p->next)
+ p->next->prevp = &p->next;
+ if (mci->employer != state) {
+ if (!mci->employer) {
+ FATAL_ASSERT(mci->nblocks == 1);
+ state->nr_of_carriers++;
+ }
+ else {
+ state->nr_of_migrations++;
+ }
+ mci->employer = state;
+ }
+ enif_mutex_unlock(mci->mtx);
+}
+
+static void remove_block(MyBlock* p)
+{
+ MyCrrInfo* mci = (MyCrrInfo*)((char*)BLK_TO_MBC(UMEM2BLK_TEST(p)) + crr_info_offset);
+
+ enif_mutex_lock(mci->mtx);
+ mci->nblocks--;
+ if (p->next)
+ p->next->prevp = p->prevp;
+ *p->prevp = p->next;
+ enif_mutex_unlock(mci->mtx);
+}
+
+static int rand_int(MigrationState* state, int low, int high)
+{
+ int x;
+ FATAL_ASSERT(high >= low);
+ x = myrand(&state->rand_state);
+ return low + (x % (high+1-low));
+}
+
+
+static void do_cleanup(TestCaseState_t *tcs, MigrationState* state)
+{
+ if (state->nblocks == 0) {
+ state->phase = DONE;
+ testcase_printf(tcs, "%d: Done %d rounds", tcs->thr_nr, state->round);
+ testcase_printf(tcs, "%d: Cleanup all blocks", tcs->thr_nr);
+ testcase_printf(tcs, "%d: Empty carriers detected = %d", tcs->thr_nr,
+ state->nr_of_carriers);
+ testcase_printf(tcs, "%d: Migrations detected = %d", tcs->thr_nr,
+ state->nr_of_migrations);
+ testcase_printf(tcs, "%d: Max blocks in carrier = %d", tcs->thr_nr,
+ state->max_blocks_in_mbc);
+ }
+ else {
+ state->nblocks--;
+ if (state->blockv[state->nblocks]) {
+ remove_block(state->blockv[state->nblocks]);
+ FREE_TEST(state->blockv[state->nblocks]);
+ }
+ }
+}
+
+
+void
+testcase_run(TestCaseState_t *tcs)
+{
+ MigrationState* state = (MigrationState*) tcs->extra;
+
+ if (!tcs->extra) {
+ if (!IS_SMP_ENABLED)
+ testcase_skipped(tcs, "No SMP support");
+
+ tcs->extra = enif_alloc(sizeof(MigrationState));
+ state = (MigrationState*) tcs->extra;
+ memset(state->blockv, 0, sizeof(state->blockv));
+ myrand_init(&state->rand_state, tcs->thr_nr);
+ state->phase = GROWING;
+ state->nblocks = 0;
+ state->round = 0;
+ state->nr_of_migrations = 0;
+ state->nr_of_carriers = 0;
+ state->max_blocks_in_mbc = 0;
+ state->block_size = GET_TEST_MBC_SIZE() / (BLOCKS_PER_MBC+1);
+ if (MAX_BLOCK_PER_THR * state->block_size < tcs->free_mem) {
+ state->max_nblocks = MAX_BLOCK_PER_THR;
+ } else {
+ state->max_nblocks = tcs->free_mem / state->block_size;
+ }
+ state->goal_nblocks = rand_int(state, 1, state->max_nblocks);
+ }
+
+ switch (state->phase) {
+ case GROWING: {
+ MyBlock* p;
+ FATAL_ASSERT(!state->blockv[state->nblocks]);
+ p = ALLOC_TEST(rand_int(state, state->block_size/2, state->block_size));
+ FATAL_ASSERT(p);
+ add_block(p, state);
+ state->blockv[state->nblocks] = p;
+ if (++state->nblocks >= state->goal_nblocks) {
+ /*testcase_printf(tcs, "%d: Grown to %d blocks", tcs->thr_nr, state->nblocks);*/
+ state->phase = SHRINKING;
+ state->goal_nblocks = rand_int(state, 0, state->goal_nblocks-1);
+ }
+ else
+ FATAL_ASSERT(!state->blockv[state->nblocks]);
+ break;
+ }
+ case SHRINKING: {
+ int ix = rand_int(state, 0, state->nblocks-1);
+ FATAL_ASSERT(state->blockv[ix]);
+ remove_block(state->blockv[ix]);
+ FREE_TEST(state->blockv[ix]);
+ state->blockv[ix] = state->blockv[--state->nblocks];
+ state->blockv[state->nblocks] = NULL;
+
+ if (state->nblocks <= state->goal_nblocks) {
+ /*testcase_printf(tcs, "%d: Shrunk to %d blocks", tcs->thr_nr, state->nblocks);*/
+ if (++state->round >= MAX_ROUNDS) {
+ state->phase = CLEANUP;
+ } else {
+ state->phase = GROWING;
+ state->goal_nblocks = rand_int(state, state->goal_nblocks+1, state->max_nblocks);
+ }
+ }
+ break;
+ }
+ case CLEANUP:
+ do_cleanup(tcs, state);
+ break;
+
+ default:
+ FATAL_ASSERT(!"Invalid phase");
+ }
+
+ if (state->phase == DONE) {
+ }
+ else {
+ testcase_continue(tcs);
+ }
+}
+
+void
+testcase_cleanup(TestCaseState_t *tcs)
+{
+ MigrationState* state = (MigrationState*) tcs->extra;
+
+ while (state->phase != DONE)
+ do_cleanup(tcs, state);
+
+ enif_free(tcs->extra);
+ tcs->extra = NULL;
+}
+
+
+ERL_NIF_INIT(migration, testcase_nif_funcs, migration_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/migration.erl b/erts/emulator/test/alloc_SUITE_data/migration.erl
new file mode 100644
index 0000000000..440a99becd
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/migration.erl
@@ -0,0 +1,10 @@
+-module(migration).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c
index 7d5608f890..e5df3d647f 100644
--- a/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c
+++ b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -100,3 +101,6 @@ testcase_cleanup(TestCaseState_t *tcs)
tcs->extra = NULL;
}
}
+
+ERL_NIF_INIT(mseg_clear_cache, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl
new file mode 100644
index 0000000000..befd6c2e8e
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl
@@ -0,0 +1,10 @@
+-module(mseg_clear_cache).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/rbtree.c b/erts/emulator/test/alloc_SUITE_data/rbtree.c
index 49df2f0245..38bbbdf90c 100644
--- a/erts/emulator/test/alloc_SUITE_data/rbtree.c
+++ b/erts/emulator/test/alloc_SUITE_data/rbtree.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -19,7 +20,7 @@
#include "testcase_driver.h"
#include "allocator_test.h"
-#define NO_BLOCKS 100000
+int NO_BLOCKS;
#define RIGHT_VISITED (1 << 0)
#define LEFT_VISITED (1 << 1)
@@ -264,9 +265,10 @@ check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
ASSERT(tcs, curr_blacks == 0);
ASSERT(tcs, i == -1);
+ /*
testcase_printf(tcs, "Red-Black Tree OK! Max depth = %d; "
"Black depth = %d\n", max_i+1, blacks < 0 ? 0 : blacks);
-
+ */
return res;
}
@@ -467,6 +469,12 @@ testcase_run(TestCaseState_t *tcs)
Allctr_t *a;
rbtree_test_data *td;
+ NO_BLOCKS = 100*1000;
+ if (enif_is_identical(tcs->build_type,
+ enif_make_atom(tcs->curr_env,"valgrind"))) {
+ NO_BLOCKS /= 10;
+ }
+
/* Best fit... */
testcase_printf(tcs, "Setup...\n");
@@ -576,3 +584,6 @@ testcase_run(TestCaseState_t *tcs)
testcase_printf(tcs, "aoffcaobf test succeeded!\n");
}
+
+ERL_NIF_INIT(rbtree, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/rbtree.erl b/erts/emulator/test/alloc_SUITE_data/rbtree.erl
new file mode 100644
index 0000000000..f5b7120ff2
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/rbtree.erl
@@ -0,0 +1,10 @@
+-module(rbtree).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/realloc_copy.c b/erts/emulator/test/alloc_SUITE_data/realloc_copy.c
index 12454c75e4..c4147eb00d 100644
--- a/erts/emulator/test/alloc_SUITE_data/realloc_copy.c
+++ b/erts/emulator/test/alloc_SUITE_data/realloc_copy.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -277,3 +278,5 @@ testcase_cleanup(TestCaseState_t *tcs)
STOP_ALC((Allctr_t *) tcs->extra);
}
+ERL_NIF_INIT(realloc_copy, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/realloc_copy.erl b/erts/emulator/test/alloc_SUITE_data/realloc_copy.erl
new file mode 100644
index 0000000000..cc6617bf64
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/realloc_copy.erl
@@ -0,0 +1,10 @@
+-module(realloc_copy).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
index 5c4b11454f..7dcca544e5 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -22,141 +23,147 @@
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
+#include <limits.h>
#ifdef __WIN32__
-#undef HAVE_VSNPRINTF
-#define HAVE_VSNPRINTF 1
-#define vsnprintf _vsnprintf
+static void my_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
+{
+ _vsnprintf(outBuf, size, format, ap);
+ outBuf[size-1] = 0; /* be sure string is terminated */
+}
+#elif defined(HAVE_VSNPRINTF)
+# define my_vsnprintf(B,S,F,A) (void)vsnprintf(B,S,F,A)
+#else
+# warning Using unsafe 'vsprintf' without buffer overflow protection
+# define my_vsnprintf(B,S,F,A) (void)vsprintf(B,F,A)
#endif
-#ifndef HAVE_VSNPRINTF
-#define HAVE_VSNPRINTF 0
-#endif
+static void my_snprintf(char *outBuf, size_t size, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ my_vsnprintf(outBuf, size, format, ap);
+ va_end(ap);
+}
#define COMMENT_BUF_SZ 4096
#define TESTCASE_FAILED 0
#define TESTCASE_SKIPPED 1
#define TESTCASE_SUCCEEDED 2
+#define TESTCASE_CONTINUE 3
typedef struct {
TestCaseState_t visible;
- ErlDrvPort port;
- ErlDrvTermData port_id;
int result;
- jmp_buf done_jmp_buf;
+ jmp_buf* done_jmp_buf;
char *comment;
char comment_buf[COMMENT_BUF_SZ];
} InternalTestCaseState_t;
-ErlDrvData testcase_drv_start(ErlDrvPort port, char *command);
-void testcase_drv_stop(ErlDrvData drv_data);
-void testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
-
-static ErlDrvEntry testcase_drv_entry = {
- NULL,
- testcase_drv_start,
- testcase_drv_stop,
- testcase_drv_run,
- NULL,
- NULL,
- "testcase_drv",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- ERL_DRV_EXTENDED_MARKER,
- ERL_DRV_EXTENDED_MAJOR_VERSION,
- ERL_DRV_EXTENDED_MINOR_VERSION,
- 0,
- NULL,
- NULL,
- NULL
+ERL_NIF_TERM testcase_nif_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM testcase_nif_stop(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM testcase_nif_run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+
+ErlNifFunc testcase_nif_funcs[] =
+{
+ {"start", 1, testcase_nif_start},
+ {"run", 1, testcase_nif_run},
+ {"stop", 1, testcase_nif_stop}
};
+static ErlNifResourceType* testcase_rt;
+static ERL_NIF_TERM print_atom;
-DRIVER_INIT(testcase_drv)
+int testcase_nif_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- testcase_drv_entry.driver_name = testcase_name();
- return &testcase_drv_entry;
+ testcase_rt = enif_open_resource_type(env, NULL, "testcase_rt", NULL,
+ ERL_NIF_RT_CREATE, NULL);
+
+ print_atom = enif_make_atom(env, "print");
+ return 0;
}
-ErlDrvData
-testcase_drv_start(ErlDrvPort port, char *command)
-{
+ERL_NIF_TERM
+testcase_nif_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{ /* (ThrNr, FreeMeg, BuildType) */
+ ERL_NIF_TERM ret;
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *)
- driver_alloc(sizeof(InternalTestCaseState_t));
- if (!itcs) {
- return ERL_DRV_ERROR_GENERAL;
+ enif_alloc_resource(testcase_rt, sizeof(InternalTestCaseState_t));
+ int free_megabyte;
+ const int max_megabyte = INT_MAX / (1024*1024);
+ const ERL_NIF_TERM* tpl;
+ int tpl_arity;
+
+ if (!itcs
+ || !enif_get_tuple(env, argv[0], &tpl_arity, &tpl)
+ || tpl_arity != 3
+ || !enif_get_int(env, tpl[0], &itcs->visible.thr_nr)
+ || !enif_get_int(env, tpl[1], &free_megabyte)) {
+ enif_make_badarg(env);
}
-
+ itcs->visible.free_mem = (free_megabyte < max_megabyte ?
+ free_megabyte : max_megabyte) * (1024*1024);
itcs->visible.testcase_name = testcase_name();
+ itcs->visible.build_type = tpl[2];
itcs->visible.extra = NULL;
- itcs->port = port;
- itcs->port_id = driver_mk_port(port);
itcs->result = TESTCASE_FAILED;
itcs->comment = "";
- return (ErlDrvData) itcs;
+ ret = enif_make_resource(env, itcs);
+ enif_release_resource(itcs);
+ return ret;
}
-void
-testcase_drv_stop(ErlDrvData drv_data)
+ERL_NIF_TERM
+testcase_nif_stop(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- testcase_cleanup((TestCaseState_t *) drv_data);
- driver_free((void *) drv_data);
+ InternalTestCaseState_t *itcs;
+ if (!enif_get_resource(env, argv[0], testcase_rt, (void**)&itcs))
+ return enif_make_badarg(env);
+ testcase_cleanup(&itcs->visible);
+ return enif_make_atom(env,"ok");
}
-void
-testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
+ERL_NIF_TERM
+testcase_nif_run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) drv_data;
- ErlDrvTermData result_atom;
- ErlDrvTermData msg[12];
+ InternalTestCaseState_t *itcs;
+ const char* result_atom;
+ jmp_buf the_jmp_buf;
- itcs->visible.command = buf;
- itcs->visible.command_len = len;
+ if (!enif_get_resource(env, argv[0], testcase_rt, (void**)&itcs))
+ return enif_make_badarg(env);
- if (setjmp(itcs->done_jmp_buf) == 0) {
- testcase_run((TestCaseState_t *) itcs);
+ itcs->visible.curr_env = env;
+
+ /* For some unknown reason, first call to setjmp crashes on win64
+ * when jmp_buf is allocated as part of the resource. But it works when
+ * allocated on stack. It used to work when this was a driver.
+ */
+ itcs->done_jmp_buf = &the_jmp_buf;
+
+ if (setjmp(the_jmp_buf) == 0) {
+ testcase_run(&itcs->visible);
itcs->result = TESTCASE_SUCCEEDED;
}
switch (itcs->result) {
- case TESTCASE_SUCCEEDED:
- result_atom = driver_mk_atom("succeeded");
- break;
- case TESTCASE_SKIPPED:
- result_atom = driver_mk_atom("skipped");
- break;
- case TESTCASE_FAILED:
+ case TESTCASE_CONTINUE:
+ return enif_make_atom(env, "continue");
+
+ case TESTCASE_SUCCEEDED: result_atom = "succeeded"; break;
+ case TESTCASE_SKIPPED: result_atom = "skipped"; break;
+ case TESTCASE_FAILED: result_atom = "failed"; break;
default:
- result_atom = driver_mk_atom("failed");
- break;
+ result_atom = "failed";
+ my_snprintf(itcs->comment_buf, sizeof(itcs->comment_buf),
+ "Unexpected test result code %d.", itcs->result);
+ itcs->comment = itcs->comment_buf;
}
- msg[0] = ERL_DRV_ATOM;
- msg[1] = (ErlDrvTermData) result_atom;
-
- msg[2] = ERL_DRV_PORT;
- msg[3] = itcs->port_id;
-
- msg[4] = ERL_DRV_ATOM;
- msg[5] = driver_mk_atom(itcs->visible.testcase_name);
-
- msg[6] = ERL_DRV_STRING;
- msg[7] = (ErlDrvTermData) itcs->comment;
- msg[8] = (ErlDrvTermData) strlen(itcs->comment);
-
- msg[9] = ERL_DRV_TUPLE;
- msg[10] = (ErlDrvTermData) 4;
-
- erl_drv_output_term(itcs->port_id, msg, 11);
+ return enif_make_tuple2(env, enif_make_atom(env, result_atom),
+ enif_make_string(env, itcs->comment, ERL_NIF_LATIN1));
}
int
@@ -171,34 +178,22 @@ testcase_assertion_failed(TestCaseState_t *tcs,
void
testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
{
- InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
- ErlDrvTermData msg[12];
+ InternalTestCaseState_t* itcs = (InternalTestCaseState_t*)tcs;
+ ErlNifPid pid;
+ ErlNifEnv* msg_env = enif_alloc_env();
+ ERL_NIF_TERM msg;
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
- msg[0] = ERL_DRV_ATOM;
- msg[1] = (ErlDrvTermData) driver_mk_atom("print");
-
- msg[2] = ERL_DRV_PORT;
- msg[3] = itcs->port_id;
-
- msg[4] = ERL_DRV_ATOM;
- msg[5] = driver_mk_atom(itcs->visible.testcase_name);
+ msg = enif_make_tuple2(msg_env, print_atom,
+ enif_make_string(msg_env, itcs->comment_buf, ERL_NIF_LATIN1));
- msg[6] = ERL_DRV_STRING;
- msg[7] = (ErlDrvTermData) itcs->comment_buf;
- msg[8] = (ErlDrvTermData) strlen(itcs->comment_buf);
+ enif_send(itcs->visible.curr_env, enif_self(itcs->visible.curr_env, &pid),
+ msg_env, msg);
- msg[9] = ERL_DRV_TUPLE;
- msg[10] = (ErlDrvTermData) 4;
-
- erl_drv_output_term(itcs->port_id, msg, 11);
+ enif_free_env(msg_env);
}
@@ -207,17 +202,13 @@ void testcase_succeeded(TestCaseState_t *tcs, char *frmt, ...)
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
itcs->result = TESTCASE_SUCCEEDED;
itcs->comment = itcs->comment_buf;
- longjmp(itcs->done_jmp_buf, 1);
+ longjmp(*itcs->done_jmp_buf, 1);
}
void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...)
@@ -225,17 +216,20 @@ void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...)
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
itcs->result = TESTCASE_SKIPPED;
itcs->comment = itcs->comment_buf;
- longjmp(itcs->done_jmp_buf, 1);
+ longjmp(*itcs->done_jmp_buf, 1);
+}
+
+void testcase_continue(TestCaseState_t *tcs)
+{
+ InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
+ itcs->result = TESTCASE_CONTINUE;
+ longjmp(*itcs->done_jmp_buf, 1);
}
void testcase_failed(TestCaseState_t *tcs, char *frmt, ...)
@@ -245,37 +239,33 @@ void testcase_failed(TestCaseState_t *tcs, char *frmt, ...)
size_t bufsz = sizeof(buf);
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
itcs->result = TESTCASE_FAILED;
itcs->comment = itcs->comment_buf;
- if (erl_drv_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
+ if (enif_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
&& strcmp("true", buf) == 0) {
fprintf(stderr, "Testcase \"%s\" failed: %s\n",
itcs->visible.testcase_name, itcs->comment);
abort();
}
- longjmp(itcs->done_jmp_buf, 1);
+ longjmp(*itcs->done_jmp_buf, 1);
}
void *testcase_alloc(size_t size)
{
- return driver_alloc(size);
+ return enif_alloc(size);
}
void *testcase_realloc(void *ptr, size_t size)
{
- return driver_realloc(ptr, size);
+ return enif_realloc(ptr, size);
}
void testcase_free(void *ptr)
{
- driver_free(ptr);
+ enif_free(ptr);
}
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.h b/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
index 66d567cb44..f0ca91bd06 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -19,13 +20,15 @@
#ifndef TESTCASE_DRIVER_H__
#define TESTCASE_DRIVER_H__
-#include "erl_driver.h"
+#include "erl_nif.h"
#include <stdlib.h>
typedef struct {
+ ErlNifEnv* curr_env;
char *testcase_name;
- char *command;
- int command_len;
+ int thr_nr;
+ int free_mem; /* in bytes */
+ ERL_NIF_TERM build_type; /* opt, debug, valgrind, ... */
void *extra;
} TestCaseState_t;
@@ -33,9 +36,11 @@ typedef struct {
((void) ((B) ? 1 : testcase_assertion_failed((TCS), __FILE__, __LINE__, #B)))
+int testcase_nif_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
void testcase_printf(TestCaseState_t *tcs, char *frmt, ...);
void testcase_succeeded(TestCaseState_t *tcs, char *frmt, ...);
void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...);
+void testcase_continue(TestCaseState_t *tcs);
void testcase_failed(TestCaseState_t *tcs, char *frmt, ...);
int testcase_assertion_failed(TestCaseState_t *tcs, char *file, int line,
char *assertion);
@@ -44,8 +49,11 @@ void *testcase_realloc(void *ptr, size_t size);
void testcase_free(void *ptr);
+/* Implemented by testcase: */
char *testcase_name(void);
void testcase_run(TestCaseState_t *tcs);
void testcase_cleanup(TestCaseState_t *tcs);
-#endif
+extern ErlNifFunc testcase_nif_funcs[3];
+
+#endif /* TESTCASE_DRIVER_H__ */
diff --git a/erts/emulator/test/alloc_SUITE_data/threads.c b/erts/emulator/test/alloc_SUITE_data/threads.c
index 1247e5d7dd..2f5f841e3d 100644
--- a/erts/emulator/test/alloc_SUITE_data/threads.c
+++ b/erts/emulator/test/alloc_SUITE_data/threads.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -85,7 +86,7 @@ static void fail(int t_no, char *frmt, ...)
tc_failed = 1;
- if (erl_drv_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
+ if (enif_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
&& strcmp("true", buf) == 0) {
fprintf(stderr, "Testcase \"%s\" failed: %s\n",
testcase_name(), err_buf);
@@ -186,7 +187,6 @@ testcase_run(TestCaseState_t *tcs)
for(i = 1; i <= NO_OF_THREADS; i++) {
char *alc;
- int res;
threads[i].arg.no_ops_per_bl = NO_OF_OPS_PER_BL;
@@ -396,7 +396,7 @@ alloc_op(int t_no, Allctr_t *a, block *bp, int id, int clean_up)
bp->p = (unsigned char *) ALLOC(a, bp->s);
if(!bp->p)
fail(t_no, "ALLOC(%lu) failed [id=%d])\n", bp->s, id);
- memset((void *) bp->p, id, (size_t) bp->s);
+ memset((void *) bp->p, (unsigned char)id, (size_t) bp->s);
}
else {
unsigned char *p = (unsigned char *) REALLOC(a, bp->p, bp->as[bp->i]);
@@ -406,7 +406,7 @@ alloc_op(int t_no, Allctr_t *a, block *bp, int id, int clean_up)
if(bp->s < bp->as[bp->i]) {
CHECK_BLOCK_DATA(t_no, p, bp->s, id);
- memset((void *) p, id, (size_t) bp->as[bp->i]);
+ memset((void *) p, (unsigned char)id, (size_t) bp->as[bp->i]);
}
else
CHECK_BLOCK_DATA(t_no, p, bp->as[bp->i], id);
@@ -445,3 +445,6 @@ thread_func(void *arg)
exit_thread(td->t_no, 1);
return NULL;
}
+
+ERL_NIF_INIT(threads, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/threads.erl b/erts/emulator/test/alloc_SUITE_data/threads.erl
new file mode 100644
index 0000000000..a7b4965f5e
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/threads.erl
@@ -0,0 +1,10 @@
+-module(threads).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/beam_SUITE.erl b/erts/emulator/test/beam_SUITE.erl
index 60339ea422..706a4a1c16 100644
--- a/erts/emulator/test/beam_SUITE.erl
+++ b/erts/emulator/test/beam_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/beam_literals_SUITE.erl b/erts/emulator/test/beam_literals_SUITE.erl
index 85236e4203..9f14ca26e5 100644
--- a/erts/emulator/test/beam_literals_SUITE.erl
+++ b/erts/emulator/test/beam_literals_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -226,10 +227,11 @@ literal_type_tests(Config) when is_list(Config) ->
%% Generate an Erlang module with all different type of type tests.
?line Tests = make_test([{T, L} || T <- type_tests(), L <- literals()]),
?line Mod = literal_test,
- ?line Func = {function, 0, test, 0, [{clause,0,[],[],Tests}]},
- ?line Form = [{attribute,0,module,Mod},
- {attribute,0,compile,export_all},
- Func, {eof,0}],
+ Anno = erl_anno:new(0),
+ Func = {function, Anno, test, 0, [{clause,Anno,[],[],Tests}]},
+ Form = [{attribute,Anno,module,Mod},
+ {attribute,Anno,compile,export_all},
+ Func, {eof,Anno}],
%% Print generated code for inspection.
?line lists:foreach(fun (F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Form),
@@ -261,7 +263,8 @@ test(T, L) ->
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
- {match,0,{atom,0,Val},hd(E)}.
+ Anno = erl_anno:new(0),
+ {match,Anno,{atom,Anno,Val},hd(E)}.
test(T, A, L) ->
S = lists:flatten(io_lib:format("begin io:format(\"~~p~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ",
@@ -269,7 +272,8 @@ test(T, A, L) ->
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
- {match,0,{atom,0,Val},hd(E)}.
+ Anno = erl_anno:new(0),
+ {match,Anno,{atom,Anno,Val},hd(E)}.
literals() ->
[42,
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index fbc229bc53..d6a771e7b9 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -20,6 +21,7 @@
-module(bif_SUITE).
-include_lib("test_server/include/test_server.hrl").
+-include_lib("kernel/include/file.hrl").
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
@@ -681,8 +683,38 @@ erlang_halt(Config) when is_list(Config) ->
{badrpc,nodedown} = rpc:call(N2, erlang, halt, [0]),
{ok,N3} = slave:start(H, halt_node3),
{badrpc,nodedown} = rpc:call(N3, erlang, halt, [0,[]]),
- ok.
+ % This test triggers a segfault when dumping a crash dump
+ % to make sure that we can handle it properly.
+ {ok,N4} = slave:start(H, halt_node4),
+ CrashDump = filename:join(proplists:get_value(priv_dir,Config),
+ "segfault_erl_crash.dump"),
+ true = rpc:call(N4, os, putenv, ["ERL_CRASH_DUMP",CrashDump]),
+ false = rpc:call(N4, erts_debug, set_internal_state,
+ [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, 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
+ {0,0} -> ct:fail("Could not find end marker in crash dump");
+ _ -> ok
+ end.
+
+wait_until_stable_size(_File,-10) ->
+ {error,enoent};
+wait_until_stable_size(File,PrevSz) ->
+ timer:sleep(250),
+ case file:read_file_info(File) of
+ {error,enoent} ->
+ 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,#file_info{size = NewSz }} ->
+ wait_until_stable_size(File,NewSz)
+ end.
%% Helpers
diff --git a/erts/emulator/test/big_SUITE.erl b/erts/emulator/test/big_SUITE.erl
index 3193d56e2a..e8f881f2a4 100644
--- a/erts/emulator/test/big_SUITE.erl
+++ b/erts/emulator/test/big_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/big_SUITE_data/literal_test.erl b/erts/emulator/test/big_SUITE_data/literal_test.erl
index dc0adeb1ca..1620693bfa 100644
--- a/erts/emulator/test/big_SUITE_data/literal_test.erl
+++ b/erts/emulator/test/big_SUITE_data/literal_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 44e9e4f243..96ba2f64d4 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -520,7 +521,9 @@ external_size_1(Term, Size0, Limit) when Size0 < Limit ->
external_size_1(_, _, _) -> ok.
t_iolist_size(Config) when is_list(Config) ->
- ?line Seed = now(),
+ ?line Seed = {erlang:monotonic_time(),
+ erlang:time_offset(),
+ erlang:unique_integer([positive])},
?line io:format("Seed: ~p", [Seed]),
?line random:seed(Seed),
?line Base = <<0:(1 bsl 20)/unit:8>>,
diff --git a/erts/emulator/test/bs_bincomp_SUITE.erl b/erts/emulator/test/bs_bincomp_SUITE.erl
index f1c2dff560..dcd13c19df 100644
--- a/erts/emulator/test/bs_bincomp_SUITE.erl
+++ b/erts/emulator/test/bs_bincomp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/bs_bit_binaries_SUITE.erl b/erts/emulator/test/bs_bit_binaries_SUITE.erl
index 7f2cd1e881..a07fd7609c 100644
--- a/erts/emulator/test/bs_bit_binaries_SUITE.erl
+++ b/erts/emulator/test/bs_bit_binaries_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index 1a8724d63b..7ed99f5b4e 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -28,7 +29,7 @@
mem_leak/1, coerce_to_float/1, bjorn/1,
huge_float_field/1, huge_binary/1, system_limit/1, badarg/1,
copy_writable_binary/1, kostis/1, dynamic/1, bs_add/1,
- otp_7422/1, zero_width/1, bad_append/1]).
+ otp_7422/1, zero_width/1, bad_append/1, bs_add_overflow/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -39,7 +40,7 @@ all() ->
in_guard, mem_leak, coerce_to_float, bjorn,
huge_float_field, huge_binary, system_limit, badarg,
copy_writable_binary, kostis, dynamic, bs_add, otp_7422, zero_width,
- bad_append].
+ bad_append, bs_add_overflow].
groups() ->
[].
@@ -550,10 +551,24 @@ huge_binary(Config) when is_list(Config) ->
?line 16777216 = size(<<0:(id(1 bsl 26)),(-1):(id(1 bsl 26))>>),
?line garbage_collect(),
{Shift,Return} = case free_mem() of
- undefined -> {32,ok};
- Mb when Mb > 600 -> {32,ok};
- Mb when Mb > 300 -> {31,"Limit huge binaries to 256 Mb"};
- _ -> {30,"Limit huge binary to 128 Mb"}
+ undefined ->
+ %% This test has to be inlined inside the case to
+ %% use a literal Shift
+ ?line garbage_collect(),
+ ?line id(<<0:((1 bsl 32)-1)>>),
+ {32,ok};
+ Mb when Mb > 600 ->
+ ?line garbage_collect(),
+ ?line id(<<0:((1 bsl 32)-1)>>),
+ {32,ok};
+ Mb when Mb > 300 ->
+ ?line garbage_collect(),
+ ?line id(<<0:((1 bsl 31)-1)>>),
+ {31,"Limit huge binaries to 256 Mb"};
+ _ ->
+ ?line garbage_collect(),
+ ?line id(<<0:((1 bsl 30)-1)>>),
+ {30,"Limit huge binary to 128 Mb"}
end,
?line garbage_collect(),
?line id(<<0:((1 bsl Shift)-1)>>),
@@ -910,5 +925,19 @@ append_unit_8(Bin) ->
append_unit_16(Bin) ->
<<Bin/binary-unit:16,0:1>>.
+%% Produce a large result of bs_add that, if cast to signed int, would overflow
+%% into a negative number that fits a smallnum.
+bs_add_overflow(Config) ->
+ case erlang:system_info(wordsize) of
+ 8 ->
+ {skip, "64-bit architecture"};
+ 4 ->
+ Large = <<0:((1 bsl 30)-1)>>,
+ {'EXIT',{system_limit,_}} =
+ (catch <<Large/bits, Large/bits, Large/bits, Large/bits,
+ Large/bits, Large/bits, Large/bits, Large/bits,
+ Large/bits>>),
+ ok
+ end.
id(I) -> I.
diff --git a/erts/emulator/test/bs_match_bin_SUITE.erl b/erts/emulator/test/bs_match_bin_SUITE.erl
index 96e69dbc0b..ba79643e69 100644
--- a/erts/emulator/test/bs_match_bin_SUITE.erl
+++ b/erts/emulator/test/bs_match_bin_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/bs_match_int_SUITE.erl b/erts/emulator/test/bs_match_int_SUITE.erl
index ce03ecb548..368f71978d 100644
--- a/erts/emulator/test/bs_match_int_SUITE.erl
+++ b/erts/emulator/test/bs_match_int_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/erts/emulator/test/bs_match_misc_SUITE.erl b/erts/emulator/test/bs_match_misc_SUITE.erl
index b0904acbe9..e875dc859c 100644
--- a/erts/emulator/test/bs_match_misc_SUITE.erl
+++ b/erts/emulator/test/bs_match_misc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/bs_match_tail_SUITE.erl b/erts/emulator/test/bs_match_tail_SUITE.erl
index 1397f2069c..58b0d3fef6 100644
--- a/erts/emulator/test/bs_match_tail_SUITE.erl
+++ b/erts/emulator/test/bs_match_tail_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/bs_utf_SUITE.erl b/erts/emulator/test/bs_utf_SUITE.erl
index 4ab7d674a6..0625c22163 100644
--- a/erts/emulator/test/bs_utf_SUITE.erl
+++ b/erts/emulator/test/bs_utf_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl
index 2ed5aaa0d0..6a2588aadd 100644
--- a/erts/emulator/test/busy_port_SUITE.erl
+++ b/erts/emulator/test/busy_port_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -516,13 +517,13 @@ hs_busy_pcmd(Prt, Opts, StartFun, EndFun) ->
P = spawn_link(fun () ->
erlang:yield(),
Tester ! {self(), doing_port_command},
- Start = now(),
+ Start = erlang:monotonic_time(micro_seconds),
Res = try {return,
port_command(Prt, [], Opts)}
catch Exception:Error -> {Exception, Error}
end,
- End = now(),
- Time = round(timer:now_diff(End, Start)/1000),
+ End = erlang:monotonic_time(micro_seconds),
+ Time = round((End - Start)/1000),
Tester ! {self(), port_command_result, Res, Time}
end),
receive
@@ -776,7 +777,7 @@ run_command(_M,spawn,{Args,Opts}) ->
run_command(M,spawn,Args) ->
run_command(M,spawn,{Args,[]});
run_command(Mod,Func,Args) ->
- erlang:display({{Mod,Func,Args},now()}),
+ erlang:display({{Mod,Func,Args}, erlang:system_time(micro_seconds)}),
apply(Mod,Func,Args).
validate_scenario(Data,[{print,Var}|T]) ->
diff --git a/erts/emulator/test/busy_port_SUITE_data/Makefile.src b/erts/emulator/test/busy_port_SUITE_data/Makefile.src
index f7937bc8d3..0f2842e515 100644
--- a/erts/emulator/test/busy_port_SUITE_data/Makefile.src
+++ b/erts/emulator/test/busy_port_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c
index 52c41f8ca5..f83fa1eeaa 100644
--- a/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c
+++ b/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c
index 7807b47e3d..be913cf56e 100644
--- a/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c
+++ b/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c
@@ -3,16 +3,17 @@
*
* 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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c b/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c
index 2008b33a72..40e42b6ac2 100644
--- a/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c
+++ b/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c
@@ -3,16 +3,17 @@
*
* 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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c
index 30bcd86d1d..3c5bafb451 100644
--- a/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c
+++ b/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl
index ef1f2aa04c..064404a038 100644
--- a/erts/emulator/test/call_trace_SUITE.erl
+++ b/erts/emulator/test/call_trace_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index b0408cabe1..9f318a38be 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -389,61 +390,63 @@ module_md5_ok(Code) ->
make_stub(Config) when is_list(Config) ->
catch erlang:purge_module(my_code_test),
+ MD5 = erlang:md5(<<>>),
?line Data = ?config(data_dir, Config),
?line File = filename:join(Data, "my_code_test"),
?line {ok,my_code_test,Code} = compile:file(File, [binary]),
- ?line my_code_test = code:make_stub_module(my_code_test, Code, {[],[]}),
+ ?line my_code_test = code:make_stub_module(my_code_test, Code, {[],[],MD5}),
?line true = erlang:delete_module(my_code_test),
?line true = erlang:purge_module(my_code_test),
?line my_code_test = code:make_stub_module(my_code_test,
make_unaligned_sub_binary(Code),
- {[],[]}),
+ {[],[],MD5}),
?line true = erlang:delete_module(my_code_test),
?line true = erlang:purge_module(my_code_test),
?line my_code_test = code:make_stub_module(my_code_test, zlib:gzip(Code),
- {[],[]}),
+ {[],[],MD5}),
?line true = erlang:delete_module(my_code_test),
?line true = erlang:purge_module(my_code_test),
%% Should fail.
?line {'EXIT',{badarg,_}} =
- (catch code:make_stub_module(my_code_test, <<"bad">>, {[],[]})),
+ (catch code:make_stub_module(my_code_test, <<"bad">>, {[],[],MD5})),
?line {'EXIT',{badarg,_}} =
(catch code:make_stub_module(my_code_test,
bit_sized_binary(Code),
- {[],[]})),
+ {[],[],MD5})),
?line {'EXIT',{badarg,_}} =
(catch code:make_stub_module(my_code_test_with_wrong_name,
- Code, {[],[]})),
+ Code, {[],[],MD5})),
ok.
make_stub_many_funs(Config) when is_list(Config) ->
catch erlang:purge_module(many_funs),
+ MD5 = erlang:md5(<<>>),
?line Data = ?config(data_dir, Config),
?line File = filename:join(Data, "many_funs"),
?line {ok,many_funs,Code} = compile:file(File, [binary]),
- ?line many_funs = code:make_stub_module(many_funs, Code, {[],[]}),
+ ?line many_funs = code:make_stub_module(many_funs, Code, {[],[],MD5}),
?line true = erlang:delete_module(many_funs),
?line true = erlang:purge_module(many_funs),
?line many_funs = code:make_stub_module(many_funs,
make_unaligned_sub_binary(Code),
- {[],[]}),
+ {[],[],MD5}),
?line true = erlang:delete_module(many_funs),
?line true = erlang:purge_module(many_funs),
%% Should fail.
?line {'EXIT',{badarg,_}} =
- (catch code:make_stub_module(many_funs, <<"bad">>, {[],[]})),
+ (catch code:make_stub_module(many_funs, <<"bad">>, {[],[],MD5})),
?line {'EXIT',{badarg,_}} =
(catch code:make_stub_module(many_funs,
bit_sized_binary(Code),
- {[],[]})),
+ {[],[],MD5})),
ok.
constant_pools(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/code_SUITE_data/another_code_test.erl b/erts/emulator/test/code_SUITE_data/another_code_test.erl
index 1c9b5bdb5b..f6f9e32996 100644
--- a/erts/emulator/test/code_SUITE_data/another_code_test.erl
+++ b/erts/emulator/test/code_SUITE_data/another_code_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/code_SUITE_data/cpbugx.erl b/erts/emulator/test/code_SUITE_data/cpbugx.erl
index fb617c1973..ea01ce411b 100644
--- a/erts/emulator/test/code_SUITE_data/cpbugx.erl
+++ b/erts/emulator/test/code_SUITE_data/cpbugx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/code_SUITE_data/fun_confusion.erl b/erts/emulator/test/code_SUITE_data/fun_confusion.erl
index 16000861df..8d42937d3c 100644
--- a/erts/emulator/test/code_SUITE_data/fun_confusion.erl
+++ b/erts/emulator/test/code_SUITE_data/fun_confusion.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/code_SUITE_data/literals.erl b/erts/emulator/test/code_SUITE_data/literals.erl
index 658427095e..9802d9d3f9 100644
--- a/erts/emulator/test/code_SUITE_data/literals.erl
+++ b/erts/emulator/test/code_SUITE_data/literals.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/code_SUITE_data/many_funs.erl b/erts/emulator/test/code_SUITE_data/many_funs.erl
index 0f9c3a85a4..e832f271d0 100644
--- a/erts/emulator/test/code_SUITE_data/many_funs.erl
+++ b/erts/emulator/test/code_SUITE_data/many_funs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/code_SUITE_data/my_code_test.erl b/erts/emulator/test/code_SUITE_data/my_code_test.erl
index 5039b7f937..57d867a5ac 100644
--- a/erts/emulator/test/code_SUITE_data/my_code_test.erl
+++ b/erts/emulator/test/code_SUITE_data/my_code_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/code_SUITE_data/versions.erl b/erts/emulator/test/code_SUITE_data/versions.erl
index 7a6fd8847d..0e2d92c8f1 100644
--- a/erts/emulator/test/code_SUITE_data/versions.erl
+++ b/erts/emulator/test/code_SUITE_data/versions.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/code_parallel_load_SUITE.erl b/erts/emulator/test/code_parallel_load_SUITE.erl
index 428f1242ab..b7ac0420cd 100644
--- a/erts/emulator/test/code_parallel_load_SUITE.erl
+++ b/erts/emulator/test/code_parallel_load_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -190,13 +191,15 @@ handle_cpc_responses(N, Tag, Module) ->
generate(Module, Attributes, FunStrings) ->
FunForms = function_forms(FunStrings),
Forms = [
- {attribute,1,module,Module},
- {attribute,2,export,[FA || {FA,_} <- FunForms]}
- ] ++ [{attribute, 3, A, V}|| {A, V} <- Attributes] ++
+ {attribute,a(1),module,Module},
+ {attribute,a(2),export,[FA || {FA,_} <- FunForms]}
+ ] ++ [{attribute, a(3), A, V}|| {A, V} <- Attributes] ++
[ Function || {_, Function} <- FunForms],
{ok, Module, Bin} = compile:forms(Forms),
Bin.
+a(L) ->
+ erl_anno:new(L).
function_forms([]) -> [];
function_forms([S|Ss]) ->
diff --git a/erts/emulator/test/crypto_SUITE.erl b/erts/emulator/test/crypto_SUITE.erl
index a82bd4fe38..3622592586 100644
--- a/erts/emulator/test/crypto_SUITE.erl
+++ b/erts/emulator/test/crypto_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/crypto_reference.erl b/erts/emulator/test/crypto_reference.erl
index b91535a50e..7797eacd75 100644
--- a/erts/emulator/test/crypto_reference.erl
+++ b/erts/emulator/test/crypto_reference.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl
index ffb68ed4ee..cabd6472d4 100644
--- a/erts/emulator/test/ddll_SUITE.erl
+++ b/erts/emulator/test/ddll_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/decode_packet_SUITE.erl b/erts/emulator/test/decode_packet_SUITE.erl
index 2baf91cf29..6a5ca20ac3 100644
--- a/erts/emulator/test/decode_packet_SUITE.erl
+++ b/erts/emulator/test/decode_packet_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -52,7 +53,9 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
- Seed = {S1,S2,S3} = now(),
+ Seed = {S1,S2,S3} = {erlang:monotonic_time(),
+ erlang:time_offset(),
+ erlang:unique_integer()},
random:seed(S1,S2,S3),
io:format("*** SEED: ~p ***\n", [Seed]),
Dog=?t:timetrap(?t:minutes(1)),
diff --git a/erts/emulator/test/dgawd_handler.erl b/erts/emulator/test/dgawd_handler.erl
index 27085b7b7e..bba69ef87e 100644
--- a/erts/emulator/test/dgawd_handler.erl
+++ b/erts/emulator/test/dgawd_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index aa6cf2b881..151fab0a0e 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -163,7 +164,7 @@ bulk_send(Terms, BinSize) ->
?line stop_node(Node),
?line test_server:timetrap_cancel(Dog),
- {comment, integer_to_list(trunc(Size/1024/Elapsed+0.5)) ++ " K/s"}.
+ {comment, integer_to_list(trunc(Size/1024/max(1,Elapsed)+0.5)) ++ " K/s"}.
bulk_sendsend(Terms, BinSize) ->
{Rate1, MonitorCount1} = bulk_sendsend2(Terms, BinSize, 5),
@@ -1337,10 +1338,7 @@ unwanted_cixs() ->
get_conflicting_atoms(_CIX, 0) ->
[];
get_conflicting_atoms(CIX, N) ->
- {A, B, C} = now(),
- Atom = list_to_atom("atom" ++ integer_to_list(A*1000000000000
- + B*1000000
- + C)),
+ Atom = list_to_atom("atom" ++ integer_to_list(erlang:unique_integer([positive]))),
case erts_debug:get_internal_state({atom_out_cache_index, Atom}) of
CIX ->
[Atom|get_conflicting_atoms(CIX, N-1)];
@@ -1351,10 +1349,7 @@ get_conflicting_atoms(CIX, N) ->
get_conflicting_unicode_atoms(_CIX, 0) ->
[];
get_conflicting_unicode_atoms(CIX, N) ->
- {A, B, C} = now(),
- Atom = string_to_atom([16#1f608] ++ "atom" ++ integer_to_list(A*1000000000000
- + B*1000000
- + C)),
+ Atom = string_to_atom([16#1f608] ++ "atom" ++ integer_to_list(erlang:unique_integer([positive]))),
case erts_debug:get_internal_state({atom_out_cache_index, Atom}) of
CIX ->
[Atom|get_conflicting_unicode_atoms(CIX, N-1)];
@@ -1967,8 +1962,7 @@ dmsg_bad_atom_cache_ref() ->
%%% Utilities
timestamp() ->
- {A,B,C} = erlang:now(),
- (C div 1000) + (B * 1000) + (A * 1000000000).
+ erlang:monotonic_time(milli_seconds).
start_node(X) ->
start_node(X, [], []).
@@ -1992,7 +1986,9 @@ start_node(Config, Args, Rel) when is_list(Config), is_list(Rel) ->
++ "-"
++ atom_to_list(?config(testcase, Config))
++ "-"
- ++ integer_to_list(timestamp()))),
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-"
+ ++ integer_to_list(erlang:unique_integer([positive])))),
start_node(Name, Args, Rel).
stop_node(Node) ->
@@ -2109,7 +2105,7 @@ node_monitor(Master) ->
Master ! {nodeup, node(), Node}
end,
Nodes0),
- ?t:format("~p ~p: ~p~n", [node(), erlang:now(), Nodes0]),
+ ?t:format("~p ~p: ~p~n", [node(), erlang:system_time(micro_seconds), Nodes0]),
node_monitor_loop(Master);
false ->
net_kernel:monitor_nodes(false, Opts),
@@ -2130,7 +2126,7 @@ node_monitor_loop(Master) ->
receive
{nodeup, Node, _InfoList} = Msg ->
Master ! {nodeup, node(), Node},
- ?t:format("~p ~p: ~p~n", [node(), erlang:now(), Msg]),
+ ?t:format("~p ~p: ~p~n", [node(), erlang:system_time(micro_seconds), Msg]),
node_monitor_loop(Master);
{nodedown, Node, InfoList} = Msg ->
Reason = case lists:keysearch(nodedown_reason, 1, InfoList) of
@@ -2138,7 +2134,7 @@ node_monitor_loop(Master) ->
_ -> undefined
end,
Master ! {nodedown, node(), Node, Reason},
- ?t:format("~p ~p: ~p~n", [node(), erlang:now(), Msg]),
+ ?t:format("~p ~p: ~p~n", [node(), erlang:system_time(micro_seconds), Msg]),
node_monitor_loop(Master)
end.
diff --git a/erts/emulator/test/distribution_SUITE_data/run.erl b/erts/emulator/test/distribution_SUITE_data/run.erl
index e2137a1ec5..d5ed139369 100644
--- a/erts/emulator/test/distribution_SUITE_data/run.erl
+++ b/erts/emulator/test/distribution_SUITE_data/run.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -29,16 +30,19 @@ from(H, [_ | T]) -> from(H, T);
from(H, []) -> [].
start() ->
- net_kernel:start([fideridum,shortnames]),
- {ok, Node} = slave:start(host(), heppel),
- P = spawn(Node, a, b, []),
- B1 = term_to_binary(P),
- N1 = node(P),
- ok = net_kernel:stop(),
- N2 = node(P),
- io:format("~w~n", [N1 == N2]),
+ Result = do_it(),
+
+ %% Do GCs and node_and_dist_references
+ %% in an attempt to crash the VM (without OTP-13076 fix)
+ lists:foreach(fun(P) -> erlang:garbage_collect(P) end,
+ processes()),
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:get_internal_state(node_and_dist_references),
+
+ io:format("~w~n", [Result]),
+
if
- N1 == N2 ->
+ Result ->
init:stop();
true ->
%% Make sure that the io:format/2 output is really written
@@ -46,3 +50,29 @@ start() ->
erlang:yield(),
init:stop()
end.
+
+
+do_it() ->
+ {ok, _} = net_kernel:start([fideridum,shortnames]),
+ {ok, Node} = slave:start(host(), heppel),
+ P = spawn(Node, net_kernel, stop, []),
+ B1 = term_to_binary(P),
+ N1 = node(P),
+ ok = net_kernel:stop(),
+ N2 = node(P),
+
+ %% OTP-13076
+ %% Restart distribution with same node name as previous remote node
+ %% Repeat to wrap around creation
+ Result = lists:foldl(fun(_, Acc) ->
+ timer:sleep(2), % give net_kernel:stop() time to take effect :-(
+ {ok, _} = net_kernel:start([heppel,shortnames]),
+ N3 = node(P),
+ ok = net_kernel:stop(),
+ N4 = node(P),
+ Acc and (N3 =:= N1) and (N4 =:= N1)
+ end,
+ (N2 =:= N1),
+ lists:seq(1,3)),
+
+ Result.
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 623d62f876..4211c49848 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
@@ -390,12 +391,12 @@ timer_measure(Config) when is_list(Config) ->
try_timeouts(_, 0) -> ok;
try_timeouts(Port, Timeout) ->
- ?line TimeBefore = now(),
+ ?line TimeBefore = erlang:monotonic_time(),
?line erlang:port_command(Port, <<?START_TIMER,Timeout:32>>),
receive
{Port,{data,[?TIMER]}} ->
?line Elapsed = erl_millisecs() - erl_millisecs(TimeBefore),
- io:format("Elapsed: ~p Timeout: ~p\n", [Elapsed,Timeout]),
+ io:format("Elapsed: ~p Timeout: ~p\n", [Elapsed, Timeout]),
if
Elapsed < Timeout ->
?line ?t:fail(too_short);
@@ -455,7 +456,7 @@ timer_delay(Config) when is_list(Config) ->
Name = 'timer_drv',
?line Port = start_driver(Config, Name, false),
- ?line TimeBefore = now(),
+ ?line TimeBefore = erlang:monotonic_time(),
Timeout0 = 350,
?line erlang:port_command(Port, <<?DELAY_START_TIMER,Timeout0:32>>),
Timeout = Timeout0 +
@@ -499,7 +500,7 @@ timer_change(Config) when is_list(Config) ->
try_change_timer(_Port, 0) -> ok;
try_change_timer(Port, Timeout) ->
?line Timeout_3 = Timeout*3,
- ?line TimeBefore = now(),
+ ?line TimeBefore = erlang:monotonic_time(),
?line erlang:port_command(Port, <<?START_TIMER,Timeout_3:32>>),
?line erlang:port_command(Port, <<?START_TIMER,Timeout:32>>),
receive
@@ -2520,13 +2521,11 @@ uniform(N) ->
end,
random:uniform(N).
-%% return millisecs from statistics source
erl_millisecs() ->
- {Ms, S, Us} = erlang:now(),
- Ms * 1000000000 + S * 1000 + Us / 1000.
+ erl_millisecs(erlang:monotonic_time()).
-erl_millisecs({Ms,S,Us}) ->
- Ms * 1000000000 + S * 1000 + Us / 1000.
+erl_millisecs(MonotonicTime) ->
+ (1000*MonotonicTime)/erlang:convert_time_unit(1,seconds,native).
%% Start/stop drivers.
start_driver(Config, Name, Binary) ->
@@ -2575,18 +2574,15 @@ sleep(Ms) when is_integer(Ms), Ms >= 0 ->
start_node(Config) when is_list(Config) ->
- ?line Pa = filename:dirname(code:which(?MODULE)),
- ?line {A, B, C} = now(),
- ?line Name = list_to_atom(atom_to_list(?MODULE)
- ++ "-"
- ++ atom_to_list(?config(testcase, Config))
- ++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)),
- ?line ?t:start_node(Name, slave, [{args, "-pa "++Pa}]).
+ Pa = filename:dirname(code:which(?MODULE)),
+ Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(?config(testcase, Config))
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-"
+ ++ integer_to_list(erlang:unique_integer([positive]))),
+ ?t:start_node(Name, slave, [{args, "-pa "++Pa}]).
stop_node(Node) ->
?t:stop_node(Node).
diff --git a/erts/emulator/test/driver_SUITE_data/async_blast_drv.c b/erts/emulator/test/driver_SUITE_data/async_blast_drv.c
index 72be107168..a1008afcae 100644
--- a/erts/emulator/test/driver_SUITE_data/async_blast_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/async_blast_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/driver_SUITE_data/caller_drv.c b/erts/emulator/test/driver_SUITE_data/caller_drv.c
index 2731f9b317..3bb20d86f5 100644
--- a/erts/emulator/test/driver_SUITE_data/caller_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/caller_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/chkio_drv.c b/erts/emulator/test/driver_SUITE_data/chkio_drv.c
index faf1040276..614b68e865 100644
--- a/erts/emulator/test/driver_SUITE_data/chkio_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/chkio_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c b/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c
index 578a210ab2..192ac02d3e 100644
--- a/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/driver_SUITE_data/invalid_extended_marker_drv.c b/erts/emulator/test/driver_SUITE_data/invalid_extended_marker_drv.c
index 59145447f8..4bc5b85338 100644
--- a/erts/emulator/test/driver_SUITE_data/invalid_extended_marker_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/invalid_extended_marker_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/io_ready_exit_drv.c b/erts/emulator/test/driver_SUITE_data/io_ready_exit_drv.c
index 1e107309df..11ccd2574e 100644
--- a/erts/emulator/test/driver_SUITE_data/io_ready_exit_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/io_ready_exit_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
index e2b338f801..e2221b9e17 100644
--- a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/driver_SUITE_data/larger_major_vsn_drv.c b/erts/emulator/test/driver_SUITE_data/larger_major_vsn_drv.c
index 4eb0e6fa57..3e46d89288 100644
--- a/erts/emulator/test/driver_SUITE_data/larger_major_vsn_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/larger_major_vsn_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/larger_minor_vsn_drv.c b/erts/emulator/test/driver_SUITE_data/larger_minor_vsn_drv.c
index 396deb9bef..d7336ed59b 100644
--- a/erts/emulator/test/driver_SUITE_data/larger_minor_vsn_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/larger_minor_vsn_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/missing_callback_drv.c b/erts/emulator/test/driver_SUITE_data/missing_callback_drv.c
index 851f2c745b..e7480d2e00 100644
--- a/erts/emulator/test/driver_SUITE_data/missing_callback_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/missing_callback_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson AB. Portions
* created by Ericsson are Copyright 2008, Ericsson Utvecklings AB. All
diff --git a/erts/emulator/test/driver_SUITE_data/monitor_drv.c b/erts/emulator/test/driver_SUITE_data/monitor_drv.c
index 81dfb65191..1418250484 100644
--- a/erts/emulator/test/driver_SUITE_data/monitor_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/monitor_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/otp_6879_drv.c b/erts/emulator/test/driver_SUITE_data/otp_6879_drv.c
index ff44145ca7..594a996ab9 100644
--- a/erts/emulator/test/driver_SUITE_data/otp_6879_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/otp_6879_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
index ad29d17f06..fdf8e4c0ad 100644
--- a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
index cbee1c3dce..685cda3e07 100644
--- a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/smaller_major_vsn_drv.c b/erts/emulator/test/driver_SUITE_data/smaller_major_vsn_drv.c
index 6b9d4745ba..d50546b919 100644
--- a/erts/emulator/test/driver_SUITE_data/smaller_major_vsn_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/smaller_major_vsn_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/smaller_minor_vsn_drv.c b/erts/emulator/test/driver_SUITE_data/smaller_minor_vsn_drv.c
index 42b1d2a187..082694de82 100644
--- a/erts/emulator/test/driver_SUITE_data/smaller_minor_vsn_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/smaller_minor_vsn_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/sys_info_base_drv.c b/erts/emulator/test/driver_SUITE_data/sys_info_base_drv.c
index 964034f5a6..c69961928e 100644
--- a/erts/emulator/test/driver_SUITE_data/sys_info_base_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/sys_info_base_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
+/* ``Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/sys_info_curr_drv.c b/erts/emulator/test/driver_SUITE_data/sys_info_curr_drv.c
index 6d2c47fdaf..a847dbb6ad 100644
--- a/erts/emulator/test/driver_SUITE_data/sys_info_curr_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/sys_info_curr_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.c b/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.c
index c6c70a2075..7c22e2c365 100644
--- a/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.c
+++ b/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.h b/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.h
index 5a6ddb15cf..35e60c0d86 100644
--- a/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.h
+++ b/erts/emulator/test/driver_SUITE_data/sys_info_drv_impl.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/sys_info_prev_drv.c b/erts/emulator/test/driver_SUITE_data/sys_info_prev_drv.c
index 2271d7027b..33a4794fba 100644
--- a/erts/emulator/test/driver_SUITE_data/sys_info_prev_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/sys_info_prev_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
+/* ``Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/thr_alloc_drv.c b/erts/emulator/test/driver_SUITE_data/thr_alloc_drv.c
index 500725a7cd..f1f2b438f0 100644
--- a/erts/emulator/test/driver_SUITE_data/thr_alloc_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/thr_alloc_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/thr_free_drv.c b/erts/emulator/test/driver_SUITE_data/thr_free_drv.c
index 439fe6a184..54205f190e 100644
--- a/erts/emulator/test/driver_SUITE_data/thr_free_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/thr_free_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c b/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c
index 5a9112afa3..f7a7cc2b8e 100644
--- a/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/driver_SUITE_data/vsn_mismatch_drv_impl.c b/erts/emulator/test/driver_SUITE_data/vsn_mismatch_drv_impl.c
index 53b0a029ce..6750b8a78b 100644
--- a/erts/emulator/test/driver_SUITE_data/vsn_mismatch_drv_impl.c
+++ b/erts/emulator/test/driver_SUITE_data/vsn_mismatch_drv_impl.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/driver_SUITE_data/zero_extended_marker_garb_drv.c b/erts/emulator/test/driver_SUITE_data/zero_extended_marker_garb_drv.c
index ed705e565f..e7f4edde08 100644
--- a/erts/emulator/test/driver_SUITE_data/zero_extended_marker_garb_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/zero_extended_marker_garb_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/efile_SUITE.erl b/erts/emulator/test/efile_SUITE.erl
index f79bb761d1..4d8d89db9b 100644
--- a/erts/emulator/test/efile_SUITE.erl
+++ b/erts/emulator/test/efile_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/erts/emulator/test/erl_drv_thread_SUITE.erl b/erts/emulator/test/erl_drv_thread_SUITE.erl
index 84a82cced0..2cd569ce4f 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE.erl
+++ b/erts/emulator/test/erl_drv_thread_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/Makefile.src b/erts/emulator/test/erl_drv_thread_SUITE_data/Makefile.src
index 216707e8a5..169fad9231 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/Makefile.src
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/Makefile.src
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/basic.c b/erts/emulator/test/erl_drv_thread_SUITE_data/basic.c
index fca2c1dbea..8ceb9eff08 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/basic.c
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/basic.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/rwlock.c b/erts/emulator/test/erl_drv_thread_SUITE_data/rwlock.c
index 064f52c16b..98d0162b55 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/rwlock.c
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/rwlock.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c b/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c
index 2cd3209231..7f5faf9121 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.h b/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.h
index 18d5229780..bffe4f9f27 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.h
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c b/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c
index 3809c915e0..4c952767c2 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/erl_link_SUITE.erl b/erts/emulator/test/erl_link_SUITE.erl
index 435c0872e6..a7a45046ca 100644
--- a/erts/emulator/test/erl_link_SUITE.erl
+++ b/erts/emulator/test/erl_link_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1035,16 +1036,13 @@ get_names(N, T) when is_atom(T) ->
get_names(0, _, Acc) ->
Acc;
get_names(N, T, Acc) ->
- {A, B, C} = now(),
get_names(N-1, T, [list_to_atom(atom_to_list(?MODULE)
++ "-"
++ atom_to_list(T)
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ integer_to_list(erlang:system_time(seconds))
++ "-"
- ++ integer_to_list(C)) | Acc]).
+ ++ integer_to_list(erlang:unique_integer([positive]))) | Acc]).
start_node(Name) ->
?line start_node(Name, "").
diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl
index e5c904cfb9..35677f9953 100644
--- a/erts/emulator/test/erts_debug_SUITE.erl
+++ b/erts/emulator/test/erts_debug_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -71,6 +72,11 @@ test_size(Config) when is_list(Config) ->
4 = do_test_size(#{}),
32 = do_test_size(#{b => 2,c => 3,txt => "hello world"}),
+ true = do_test_size(maps:from_list([{I,I}||I<-lists:seq(1,256)])) >= map_size_lower_bound(256),
+ true = do_test_size(maps:from_list([{I,I}||I<-lists:seq(1,4096)])) >= map_size_lower_bound(4096),
+ true = do_test_size(maps:from_list([{I,I}||I<-lists:seq(1,254)])) >= map_size_lower_bound(254),
+ true = do_test_size(maps:from_list([{I,I}||I<-lists:seq(1,239)])) >= map_size_lower_bound(239),
+
%% Test internal consistency of sizes, but without testing
%% exact sizes.
Const = id(42),
@@ -92,14 +98,14 @@ test_size(Config) when is_list(Config) ->
%% Test shared data structures.
do_test_size([ConsCell1|ConsCell1],
- 3*ConsCellSz,
- 2*ConsCellSz),
+ 3*ConsCellSz,
+ 2*ConsCellSz),
do_test_size(fun() -> {ConsCell1,ConsCell2} end,
- FunSz2 + 2*ConsCellSz,
- FunSz2 + ConsCellSz),
+ FunSz2 + 2*ConsCellSz,
+ FunSz2 + ConsCellSz),
do_test_size({SimplestFun,SimplestFun},
- 2*FunSz0+do_test_size({a,b}),
- FunSz0+do_test_size({a,b})),
+ 2*FunSz0+do_test_size({a,b}),
+ FunSz0+do_test_size({a,b})),
M = id(#{ "atom" => first, i => 0}),
do_test_size([M,M#{ "atom" := other },M#{i := 42}],54,32),
@@ -113,6 +119,13 @@ do_test_size(Term, FlatSz, Sz) ->
FlatSz = erts_debug:flat_size(Term),
Sz = erts_debug:size(Term).
+map_size_lower_bound(N) ->
+ %% this est. is a bit lower that actual lower bound
+ %% number of internal nodes
+ T = (N - 1) div 15,
+ %% total words
+ 2 + 17 * T + 2 * N.
+
flat_size_big(Config) when is_list(Config) ->
%% Build a term whose external size only fits in a big num (on 32-bit CPU).
flat_size_big_1(16#11111111111111117777777777777777888889999, 0, 16#FFFFFFF).
@@ -126,23 +139,48 @@ flat_size_big_1(Term, Size0, Limit) when Size0 < Limit ->
flat_size_big_1(_, _, _) -> ok.
df(Config) when is_list(Config) ->
- ?line P0 = pps(),
- ?line PrivDir = ?config(priv_dir, Config),
- ?line ok = file:set_cwd(PrivDir),
- ?line erts_debug:df(?MODULE),
- ?line Beam = filename:join(PrivDir, ?MODULE_STRING++".dis"),
- ?line {ok,Bin} = file:read_file(Beam),
- ?line ok = io:put_chars(binary_to_list(Bin)),
- ?line ok = file:delete(Beam),
- ?line true = (P0 == pps()),
+ P0 = pps(),
+ PrivDir = ?config(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+
+ AllLoaded = [M || {M,_} <- code:all_loaded()],
+ {Pid,Ref} = spawn_monitor(fun() -> df_smoke(AllLoaded) end),
+ receive
+ {'DOWN',Ref,process,Pid,Status} ->
+ normal = Status
+ after 20*1000 ->
+ %% Not finished (i.e. a slow computer). Stop now.
+ Pid ! stop,
+ receive
+ {'DOWN',Ref,process,Pid,Status} ->
+ normal = Status,
+ io:format("...")
+ end
+ end,
+ io:nl(),
+ _ = [_ = file:delete(atom_to_list(M) ++ ".dis") ||
+ M <- AllLoaded],
+
+ true = (P0 == pps()),
ok.
+df_smoke([M|Ms]) ->
+ io:format("~p", [M]),
+ erts_debug:df(M),
+ receive
+ stop ->
+ ok
+ after 0 ->
+ df_smoke(Ms)
+ end;
+df_smoke([]) -> ok.
+
pps() ->
{erlang:ports()}.
instructions(Config) when is_list(Config) ->
- ?line Is = erts_debug:instructions(),
- ?line _ = [list_to_atom(I) || I <- Is],
+ Is = erts_debug:instructions(),
+ _ = [list_to_atom(I) || I <- Is],
ok.
id(I) ->
diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl
index 1de6d6fb56..d49ab3de4d 100644
--- a/erts/emulator/test/estone_SUITE.erl
+++ b/erts/emulator/test/estone_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
@@ -339,7 +340,6 @@ micros() ->
].
macro(Ms,DataDir) ->
- erlang:now(), %% compensate for old 4.3 firsttime clock bug :-(
statistics(reductions),
statistics(runtime),
lists(500), %% fixup cache on first round
@@ -369,10 +369,9 @@ run_micro(Top, M, DataDir) ->
apply_micro(M) ->
{GC0, Words0, _} = statistics(garbage_collection),
statistics(reductions),
- Before = erlang:now(),
-
+ Before = monotonic_time(),
Compensate = apply_micro(M#micro.function, M#micro.loops),
- After = erlang:now(),
+ After = monotonic_time(),
{GC1, Words1, _} = statistics(garbage_collection),
{_, Reds} = statistics(reductions),
Elapsed = subtr(Before, After),
@@ -383,18 +382,19 @@ apply_micro(M) ->
{weight_percentage, M#micro.weight},
{loops, M#micro.loops},
{microsecs,MicroSecs},
- {estones, (M#micro.weight * M#micro.weight * ?STONEFACTOR) div MicroSecs},
+ {estones, (M#micro.weight * M#micro.weight * ?STONEFACTOR) div max(1,MicroSecs)},
{gcs, GC1 - GC0},
{kilo_word_reclaimed, (Words1 - Words0) div 1000},
{kilo_reductions, Reds div 1000},
- {gc_intensity, gci(Elapsed, GC1 - GC0, Words1 - Words0)}].
+ {gc_intensity, gci(max(1,Elapsed), GC1 - GC0, Words1 - Words0)}].
+monotonic_time() ->
+ try erlang:monotonic_time() catch error:undef -> erlang:now() end.
-subtr(Before, After) ->
- (element(1,After)*1000000000000
- +element(2,After)*1000000+element(3,After)) -
- (element(1,Before)*1000000000000
- +element(2,Before)*1000000+element(3,Before)).
+subtr(Before, After) when is_integer(Before), is_integer(After) ->
+ erlang:convert_time_unit(After-Before, native, micro_seconds);
+subtr({_,_,_}=Before, {_,_,_}=After) ->
+ timer:now_diff(After, Before).
gci(Micros, Words, Gcs) ->
((256 * Gcs) / Micros) + (Words / Micros).
@@ -633,10 +633,10 @@ tup_trav(T, P, End) ->
%% Port I/O
port_io(I) ->
EstoneCat = get(estone_cat),
- Before = erlang:now(),
+ Before = monotonic_time(),
Pps = make_port_pids(5, I, EstoneCat), %% 5 ports
send_procs(Pps, go),
- After = erlang:now(),
+ After = monotonic_time(),
wait_for_pids(Pps),
subtr(Before, After).
@@ -854,10 +854,10 @@ handle_call(_From, State, [abc]) ->
%% Binary handling, creating, manipulating and sending binaries
binary_h(I) ->
- Before = erlang:now(),
+ Before = monotonic_time(),
P = spawn(?MODULE, echo, [self()]),
B = list_to_binary(lists:duplicate(2000, 5)),
- After = erlang:now(),
+ After = monotonic_time(),
Compensate = subtr(Before, After),
binary_h_2(I, P, B),
Compensate.
diff --git a/erts/emulator/test/evil_SUITE.erl b/erts/emulator/test/evil_SUITE.erl
index f982b9d4ff..484d2a8bf5 100644
--- a/erts/emulator/test/evil_SUITE.erl
+++ b/erts/emulator/test/evil_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl
index 09a7a87a9a..11caea3698 100644
--- a/erts/emulator/test/exception_SUITE.erl
+++ b/erts/emulator/test/exception_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl
index 4a45afa9e9..c1a76b8af4 100644
--- a/erts/emulator/test/float_SUITE.erl
+++ b/erts/emulator/test/float_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -294,16 +295,13 @@ id(I) -> I.
start_node(Config) when is_list(Config) ->
?line Pa = filename:dirname(code:which(?MODULE)),
- ?line {A, B, C} = now(),
?line Name = list_to_atom(atom_to_list(?MODULE)
++ "-"
++ atom_to_list(?config(testcase, Config))
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ integer_to_list(erlang:system_time(seconds))
++ "-"
- ++ integer_to_list(C)),
+ ++ integer_to_list(erlang:unique_integer([positive]))),
?line ?t:start_node(Name, slave, [{args, "-pa "++Pa}]).
stop_node(Node) ->
diff --git a/erts/emulator/test/float_SUITE_data/fp_drv.c b/erts/emulator/test/float_SUITE_data/fp_drv.c
index 82d18d6440..5919dd8e2f 100644
--- a/erts/emulator/test/float_SUITE_data/fp_drv.c
+++ b/erts/emulator/test/float_SUITE_data/fp_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson AB. Portions
* created by Ericsson are Copyright 2008, Ericsson AB. All Rights
diff --git a/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl b/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl
index 31af2b2698..79ab74dfff 100644
--- a/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl
+++ b/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index 2968f5bebb..b18f9f5c6b 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/fun_r13_SUITE.erl b/erts/emulator/test/fun_r13_SUITE.erl
index 76ddf9fec9..7ab5e65cb3 100644
--- a/erts/emulator/test/fun_r13_SUITE.erl
+++ b/erts/emulator/test/fun_r13_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 36889b6c36..1e155e7b09 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -77,7 +78,7 @@ grow_heap1(List, MaxLen, CurLen, up) ->
grow_heap1([], _MaxLen, _, down) ->
ok;
grow_heap1([_|List], MaxLen, CurLen, down) ->
- {_,_,C} = erlang:now(),
+ C=erlang:unique_integer([positive]),
Num = C rem (length(List))+1,
Elem = lists:nth(Num, List),
NewList = lists:delete(Elem, List),
@@ -136,7 +137,7 @@ grow_stack_heap1(List, MaxLen, CurLen, up) ->
grow_stack_heap1([], _MaxLen, _, down) -> ok;
grow_stack_heap1([_|List], MaxLen, CurLen, down) ->
grow_stack1(CurLen*2,0),
- {_,_,C}=erlang:now(),
+ C=erlang:unique_integer([positive]),
Num=C rem (length(List))+1,
Elem=lists:nth(Num, List),
NewList=lists:delete(Elem, List),
@@ -146,8 +147,8 @@ grow_stack_heap1([_|List], MaxLen, CurLen, down) ->
%% Create an arbitrary element/term.
make_arbit() ->
- {AA,BB,CC}=erlang:now(),
- A=AA+1, B=BB+1, C=CC+1,
+ {AA,BB,CC}=erlang:timestamp(),
+ A=AA+1, B=BB+1, C=(CC+erlang:unique_integer([positive])) rem 1000000 + 1,
New =
case C rem 9 of
0 -> make_string((B div C) +5);
@@ -171,7 +172,7 @@ make_string(Length) ->
make_string(_, 0, Acc) ->
Acc;
make_string(Alph, Length, Acc) ->
- {_,_,C}=erlang:now(),
+ C=erlang:unique_integer([positive]),
Pos=1+(Length*C rem length(Alph)),
make_string(Alph, Length-1,
[lists:nth(Pos,Alph)|Acc]).
diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl
index a5df9b59a0..b3a85c6423 100644
--- a/erts/emulator/test/guard_SUITE.erl
+++ b/erts/emulator/test/guard_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/hash_SUITE.erl b/erts/emulator/test/hash_SUITE.erl
index 647bb45049..2ea49467b8 100644
--- a/erts/emulator/test/hash_SUITE.erl
+++ b/erts/emulator/test/hash_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -73,6 +74,7 @@ config(priv_dir,_) ->
init_per_group/2,end_per_group/2,
test_basic/1,test_cmp/1,test_range/1,test_spread/1,
test_phash2/1,otp_5292/1,bit_level_binaries/1,otp_7127/1,
+ test_hash_zero/1,
end_per_testcase/2,init_per_testcase/2]).
init_per_testcase(_Case, Config) ->
Dog=test_server:timetrap(test_server:minutes(10)),
@@ -86,7 +88,9 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[test_basic, test_cmp, test_range, test_spread,
- test_phash2, otp_5292, bit_level_binaries, otp_7127].
+ test_phash2, otp_5292, bit_level_binaries, otp_7127,
+ test_hash_zero
+ ].
groups() ->
[].
@@ -160,6 +164,8 @@ otp_7127(doc) ->
otp_7127(Config) when is_list(Config) ->
otp_7127_test().
+test_hash_zero(Config) when is_list(Config) ->
+ hash_zero_test().
-endif.
@@ -591,6 +597,26 @@ otp_7127_test() ->
38990304 = erlang:phash2(<<"Scott9">>),
ok.
+hash_zero_test() ->
+ Zs = [0.0, -0.0, 0/-1, 0.0/-1, 0/-(1 bsl 65),
+ binary_to_term(<<131,70,0,0,0,0,0,0,0,0>>), %% +0.0
+ binary_to_term(<<131,70,128,0,0,0,0,0,0,0>>)], %% -0.0
+ ok = hash_zero_test(Zs,fun(T) -> erlang:phash2(T, 1 bsl 32) end),
+ ok = hash_zero_test(Zs,fun(T) -> erlang:phash(T, 1 bsl 32) end),
+ ok = hash_zero_test(Zs,fun(T) -> erlang:hash(T, (1 bsl 27) - 1) end),
+ ok.
+
+hash_zero_test([Z|Zs],F) ->
+ hash_zero_test(Zs,Z,F(Z),F).
+hash_zero_test([Z|Zs],Z0,V,F) ->
+ true = Z0 =:= Z, %% assert exact equal
+ Z0 = Z, %% assert matching
+ V = F(Z), %% assert hash
+ hash_zero_test(Zs,Z0,V,F);
+hash_zero_test([],_,_,_) ->
+ ok.
+
+
%%
%% Reference implementation of integer hashing
%%
diff --git a/erts/emulator/test/hibernate_SUITE.erl b/erts/emulator/test/hibernate_SUITE.erl
index 31938e6c65..4ac8c272db 100644
--- a/erts/emulator/test/hibernate_SUITE.erl
+++ b/erts/emulator/test/hibernate_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/ignore_cores.erl b/erts/emulator/test/ignore_cores.erl
index 8b1ac0fe6c..13f34cd10f 100644
--- a/erts/emulator/test/ignore_cores.erl
+++ b/erts/emulator/test/ignore_cores.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/list_bif_SUITE.erl b/erts/emulator/test/list_bif_SUITE.erl
index 45a44d8b43..9e930822cf 100644
--- a/erts/emulator/test/list_bif_SUITE.erl
+++ b/erts/emulator/test/list_bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/long_timers_test.erl b/erts/emulator/test/long_timers_test.erl
index 28a4fba9f6..9415e1cced 100644
--- a/erts/emulator/test/long_timers_test.erl
+++ b/erts/emulator/test/long_timers_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -28,7 +29,7 @@
-define(MAX_TIMEOUT, 60). % Minutes
--define(MAX_LATE, 10*1000). % Milliseconds
+-define(MAX_LATE_MS, 15*1000). % Milliseconds
-define(REG_NAME, '___LONG___TIMERS___TEST___SERVER___').
-define(DRV_NAME, timer_driver).
@@ -75,7 +76,7 @@ check_result() ->
erlang:demonitor(Mon),
receive {'DOWN', Mon, _, _, _} -> ok after 0 -> ok end,
stop_node(Node),
- check(TORs, (timer:now_diff(End, Start) div 1000) - ?MAX_LATE, ok)
+ check(TORs, ms((End - Start) - max_late()), ok)
end.
check([#timeout_rec{timeout = Timeout,
@@ -83,7 +84,7 @@ check([#timeout_rec{timeout = Timeout,
timeout_diff = undefined} | TORs],
NeedRes,
_Ok) when Timeout < NeedRes ->
- io:format("~p timeout = ~p failed! No timeout.~n",
+ io:format("~p timeout = ~p ms failed! No timeout.~n",
[Type, Timeout]),
check(TORs, NeedRes, failed);
check([#timeout_rec{timeout_diff = undefined} | TORs],
@@ -95,7 +96,7 @@ check([#timeout_rec{timeout = Timeout,
timeout_diff = {error, Reason}} | TORs],
NeedRes,
_Ok) ->
- io:format("~p timeout = ~p failed! exit reason ~p~n",
+ io:format("~p timeout = ~p ms failed! exit reason ~p~n",
[Type, Timeout, Reason]),
check(TORs, NeedRes, failed);
check([#timeout_rec{timeout = Timeout,
@@ -103,43 +104,77 @@ check([#timeout_rec{timeout = Timeout,
timeout_diff = TimeoutDiff} | TORs],
NeedRes,
Ok) ->
- case (0 =< TimeoutDiff) and (TimeoutDiff =< ?MAX_LATE) of
- true ->
- io:format("~p timeout = ~p succeded! timeout diff = ~p.~n",
- [Type, Timeout, TimeoutDiff]),
- check(TORs, NeedRes, Ok);
- false ->
- io:format("~p timeout = ~p failed! timeout diff = ~p.~n",
- [Type, Timeout, TimeoutDiff]),
- check(TORs, NeedRes, failed)
- end;
+ {NewOk, SuccessStr} = case ((0 =< TimeoutDiff)
+ andalso (TimeoutDiff =< max_late())) of
+ true -> {Ok, "succeeded"};
+ false -> {failed, "FAILED"}
+ end,
+ io:format("~s timeout = ~s ms ~s! timeout diff = ~s.~n",
+ [type_str(Type),
+ time_str(Timeout),
+ SuccessStr,
+ time_str(TimeoutDiff, erlang:convert_time_unit(1, seconds, native))]),
+ check(TORs, NeedRes, NewOk);
check([], _NeedRes, Ok) ->
Ok.
+type_str(receive_after) -> "receive ... after";
+type_str(bif_timer) -> "BIF timer";
+type_str(driver) -> "driver".
+
+time_str(Time, Unit) ->
+ lists:flatten([time_str(Time), " ", unit_str(Unit)]).
+
+time_str(Time) ->
+ lists:reverse(conv_time_str(lists:reverse(integer_to_list(Time)))).
+
+conv_time_str([X,Y,Z,C|Cs]) when C /= $- ->
+ [X,Y,Z,$`|conv_time_str([C|Cs])];
+conv_time_str(Cs) ->
+ Cs.
+
+unit_str(1) -> "s";
+unit_str(1000) -> "ms";
+unit_str(1000000) -> "us";
+unit_str(1000000000) -> "ns";
+unit_str(Res) when is_integer(Res) -> ["/ ", integer_to_list(Res), " s"];
+unit_str(Res) -> Res.
+
+to_diff(Timeout, Start, Stop) ->
+ %% 'Timeout' in milli seconds
+ %% 'Start', 'Stop', and result in native unit
+ (Stop - Start) - erlang:convert_time_unit(Timeout, milli_seconds, native).
+
+ms(Time) ->
+ erlang:convert_time_unit(Time, native, milli_seconds).
+
+max_late() ->
+ erlang:convert_time_unit(?MAX_LATE_MS, milli_seconds, native).
+
receive_after(Timeout) ->
- Start = now(),
+ Start = erlang:monotonic_time(),
receive
{get_result, ?REG_NAME} ->
?REG_NAME ! #timeout_rec{pid = self(),
type = receive_after,
timeout = Timeout}
after Timeout ->
- Stop = now(),
+ Stop = erlang:monotonic_time(),
receive
{get_result, ?REG_NAME} ->
- TimeoutDiff = ((timer:now_diff(Stop, Start) div 1000)
- - Timeout),
?REG_NAME ! #timeout_rec{pid = self(),
type = receive_after,
timeout = Timeout,
- timeout_diff = TimeoutDiff}
+ timeout_diff = to_diff(Timeout,
+ Start,
+ Stop)}
end
end.
driver(Timeout) ->
Port = open_port({spawn, ?DRV_NAME},[]),
link(Port),
- Start = now(),
+ Start = erlang:monotonic_time(),
erlang:port_command(Port, <<?START_TIMER, Timeout:32>>),
receive
{get_result, ?REG_NAME} ->
@@ -147,38 +182,38 @@ driver(Timeout) ->
type = driver,
timeout = Timeout};
{Port,{data,[?TIMER]}} ->
- Stop = now(),
+ Stop = erlang:monotonic_time(),
unlink(Port),
true = erlang:port_close(Port),
receive
{get_result, ?REG_NAME} ->
- TimeoutDiff = ((timer:now_diff(Stop, Start) div 1000)
- - Timeout),
?REG_NAME ! #timeout_rec{pid = self(),
type = driver,
timeout = Timeout,
- timeout_diff = TimeoutDiff}
+ timeout_diff = to_diff(Timeout,
+ Start,
+ Stop)}
end
end.
bif_timer(Timeout) ->
+ Start = erlang:monotonic_time(),
Tmr = erlang:start_timer(Timeout, self(), ok),
- Start = now(),
receive
{get_result, ?REG_NAME} ->
?REG_NAME ! #timeout_rec{pid = self(),
type = bif_timer,
timeout = Timeout};
{timeout, Tmr, ok} ->
- Stop = now(),
+ Stop = erlang:monotonic_time(),
receive
{get_result, ?REG_NAME} ->
- TimeoutDiff = ((timer:now_diff(Stop, Start) div 1000)
- - Timeout),
?REG_NAME ! #timeout_rec{pid = self(),
type = bif_timer,
timeout = Timeout,
- timeout_diff = TimeoutDiff}
+ timeout_diff = to_diff(Timeout,
+ Start,
+ Stop)}
end
end.
@@ -189,7 +224,7 @@ test(Starter, DrvDir, StartDone) ->
register(?REG_NAME, self()),
{group_leader, GL} = process_info(whereis(net_kernel),group_leader),
group_leader(GL, self()),
- Start = now(),
+ Start = erlang:monotonic_time(),
TORs = lists:map(fun (Min) ->
TO = Min*60*1000,
[#timeout_rec{pid = spawn_opt(
@@ -222,7 +257,7 @@ test(Starter, DrvDir, StartDone) ->
test_loop(TORs, Start) ->
receive
{get_result, ?REG_NAME, Pid} ->
- End = now(),
+ End = erlang:monotonic_time(),
Pid ! {result, ?REG_NAME, get_test_results(TORs), Start, End},
erl_ddll:unload_driver(?DRV_NAME),
erl_ddll:stop(),
diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl
index e877f7a240..a256cf4195 100644
--- a/erts/emulator/test/map_SUITE.erl
+++ b/erts/emulator/test/map_SUITE.erl
@@ -2,16 +2,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -21,17 +22,24 @@
]).
-export([
- t_build_and_match_literals/1,
- t_update_literals/1,t_match_and_update_literals/1,
+ t_build_and_match_literals/1, t_build_and_match_literals_large/1,
+ t_update_literals/1, t_update_literals_large/1,
+ t_match_and_update_literals/1, t_match_and_update_literals_large/1,
t_update_map_expressions/1,
- t_update_assoc/1,t_update_exact/1,
- t_guard_bifs/1, t_guard_sequence/1, t_guard_update/1,
- t_guard_receive/1, t_guard_fun/1,
+ t_update_assoc/1, t_update_assoc_large/1,
+ t_update_exact/1, t_update_exact_large/1,
+ t_guard_bifs/1,
+ t_guard_sequence/1, t_guard_sequence_large/1,
+ t_guard_update/1, t_guard_update_large/1,
+ t_guard_receive/1, t_guard_receive_large/1,
+ t_guard_fun/1,
+ t_update_deep/1,
t_list_comprehension/1,
t_map_sort_literals/1,
t_map_equal/1,
- %t_size/1,
+ t_map_compare/1,
t_map_size/1,
+ t_is_map/1,
%% Specific Map BIFs
t_bif_map_get/1,
@@ -50,6 +58,11 @@
%% erlang
t_erlang_hash/1,
t_map_encode_decode/1,
+ t_gc_rare_map_overflow/1,
+
+ %% non specific BIF related
+ t_bif_build_and_check/1,
+ t_bif_merge_and_check/1,
%% maps module not bifs
t_maps_fold/1,
@@ -58,25 +71,45 @@
t_maps_without/1,
%% misc
+ t_hashmap_balance/1,
t_erts_internal_order/1,
+ t_erts_internal_hash/1,
t_pdict/1,
t_ets/1,
t_dets/1,
- t_tracing/1
+ t_tracing/1,
+
+ %% instruction-level tests
+ t_has_map_fields/1,
+ y_regs/1,
+ badmap_17/1
]).
-include_lib("stdlib/include/ms_transform.hrl").
+-define(CHECK(Cond,Term),
+ case (catch (Cond)) of
+ true -> true;
+ _ -> io:format("###### CHECK FAILED ######~nINPUT: ~p~n", [Term]),
+ exit(Term)
+ end).
+
suite() -> [].
all() -> [
- t_build_and_match_literals,
- t_update_literals, t_match_and_update_literals,
+ t_build_and_match_literals, t_build_and_match_literals_large,
+ t_update_literals, t_update_literals_large,
+ t_match_and_update_literals, t_match_and_update_literals_large,
t_update_map_expressions,
- t_update_assoc,t_update_exact,
- t_guard_bifs, t_guard_sequence, t_guard_update,
- t_guard_receive,t_guard_fun, t_list_comprehension,
- t_map_equal,
+ t_update_assoc, t_update_assoc_large,
+ t_update_exact, t_update_exact_large,
+ t_guard_bifs,
+ t_guard_sequence, t_guard_sequence_large,
+ t_guard_update, t_guard_update_large,
+ t_guard_receive, t_guard_receive_large,
+ t_guard_fun, t_list_comprehension,
+ t_update_deep,
+ t_map_equal, t_map_compare,
t_map_sort_literals,
%% Specific Map BIFs
@@ -89,7 +122,12 @@ all() -> [
%% erlang
t_erlang_hash, t_map_encode_decode,
- t_map_size,
+ t_gc_rare_map_overflow,
+ t_map_size, t_is_map,
+
+ %% non specific BIF related
+ t_bif_build_and_check,
+ t_bif_merge_and_check,
%% maps module
t_maps_fold, t_maps_map,
@@ -97,10 +135,17 @@ all() -> [
%% Other functions
+ t_hashmap_balance,
t_erts_internal_order,
+ t_erts_internal_hash,
t_pdict,
t_ets,
- t_tracing
+ t_tracing,
+
+ %% instruction-level tests
+ t_has_map_fields,
+ y_regs,
+ badmap_17
].
groups() -> [].
@@ -126,6 +171,9 @@ t_build_and_match_literals(Config) when is_list(Config) ->
#{1:=a,2:=b,3:="c","4":="d",<<"5">>:=<<"e">>,{"6",7}:="f",8:=g} =
id(#{1=>a,2=>b,3=>"c","4"=>"d",<<"5">>=><<"e">>,{"6",7}=>"f",8=>g}),
+ #{[]:=a,42.0:=b,x:={x,y},[a,b]:=list} =
+ id(#{[]=>a,42.0=>b,x=>{x,y},[a,b]=>list}),
+
#{<<"hi all">> := 1} = id(#{<<"hi",32,"all">> => 1}),
#{a:=X,a:=X=3,b:=4} = id(#{a=>3,b=>4}), % weird but ok =)
@@ -147,17 +195,461 @@ t_build_and_match_literals(Config) when is_list(Config) ->
{'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = id(#{x=>"three"}))),
ok.
+t_build_and_match_literals_large(Config) when is_list(Config) ->
+ % normal non-repeating
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M0,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M0,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M0,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M0,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M0,
+
+ 60 = map_size(M0),
+ 60 = maps:size(M0),
+
+ % with repeating
+ M1 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 10=>na0,20=>nb0,30=>"nc0","40"=>"nd0",<<"50">>=>"ne0",{["00"]}=>"n10",
+ 11=>na1,21=>nb1,31=>"nc1","41"=>"nd1",<<"51">>=>"ne1",{["01"]}=>"n11",
+ 12=>na2,22=>nb2,32=>"nc2","42"=>"nd2",<<"52">>=>"ne2",{["02"]}=>"n12",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+
+ 13=>na3,23=>nb3,33=>"nc3","43"=>"nd3",<<"53">>=>"ne3",{["03"]}=>"n13",
+ 14=>na4,24=>nb4,34=>"nc4","44"=>"nd4",<<"54">>=>"ne4",{["04"]}=>"n14",
+
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }),
+
+ #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1,
+ #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1,
+ #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1,
+ #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1,
+ #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1,
+
+ 60 = map_size(M1),
+ 60 = maps:size(M1),
+
+ % with floats
+
+ M2 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9"}),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ 90 = map_size(M2),
+ 90 = maps:size(M2),
+
+ % with bignums
+ M3 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ 36893488147419103232=>big1, 73786976294838206464=>big2,
+ 147573952589676412928=>big3, 18446744073709551616=>big4,
+ 4294967296=>big5, 8589934592=>big6,
+ 4294967295=>big7, 67108863=>big8
+ }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+
+ 98 = map_size(M3),
+ 98 = maps:size(M3),
+
+ %% with maps
+
+ M4 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M4,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M4,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M4,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M4,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M4,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M4,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M4,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M4,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M4,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M4,
+
+ #{ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := "small map key 2",
+ #{ third => small, map => key } := "small map key 3" } = M4,
+
+ #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M4,
+
+
+ #{ 15:=V1,25:=b5,35:=V2,"45":="d5",<<"55">>:=V3,{["05"]}:="15",
+ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := V4,
+ #{ third => small, map => key } := "small map key 3",
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := V5 } = M4,
+
+ a5 = V1,
+ "c5" = V2,
+ "e5" = V3,
+ "small map key 2" = V4,
+ "large map key 1" = V5,
+
+ 95 = map_size(M4),
+ 95 = maps:size(M4),
+
+ % call for value
+
+ M5 = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ #{ one => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M5,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M5,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M5,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M5,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M5,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M5,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M5,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M5,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M5,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M5,
+
+ #{ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := "small map key 2",
+ #{ third => small, map => key } := "small map key 3" } = M5,
+
+ #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M5,
+
+ 95 = map_size(M5),
+ 95 = maps:size(M5),
+
+ %% remember
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0,
+
+ #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1,
+ #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1,
+ #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1,
+ #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1,
+ #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
-%% Tests size(Map).
-%% not implemented, perhaps it shouldn't be either
+ ok.
-%t_size(Config) when is_list(Config) ->
-% 0 = size(#{}),
-% 1 = size(#{a=>1}),
-% 1 = size(#{a=>#{a=>1}}),
-% 2 = size(#{a=>1, b=>2}),
-% 3 = size(#{a=>1, b=>2, b=>"3"}),
-% ok.
t_map_size(Config) when is_list(Config) ->
0 = map_size(id(#{})),
@@ -174,16 +666,108 @@ t_map_size(Config) when is_list(Config) ->
true = map_is_size(M#{ "a" => 2}, 2),
false = map_is_size(M#{ "c" => 2}, 2),
+ Ks = [build_key(fun(K) -> <<1,K:32,1>> end,I)||I<-lists:seq(1,100)],
+ ok = build_and_check_size(Ks,0,#{}),
+
+ %% try deep collisions
+ %% statistically we get another subtree at 50k -> 100k elements
+ %% Try to be nice and don't use too much memory in the testcase,
+
+ N = 500000,
+ Is = lists:seq(1,N),
+ N = map_size(maps:from_list([{I,I}||I<-Is])),
+ N = map_size(maps:from_list([{<<I:32>>,I}||I<-Is])),
+ N = map_size(maps:from_list([{integer_to_list(I),I}||I<-Is])),
+ N = map_size(maps:from_list([{float(I),I}||I<-Is])),
+
%% Error cases.
- {'EXIT',{badarg,_}} = (catch map_size([])),
- {'EXIT',{badarg,_}} = (catch map_size(<<1,2,3>>)),
- {'EXIT',{badarg,_}} = (catch map_size(1)),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},_}} =
+ (catch map_size(T))
+ end),
+ ok.
+
+build_and_check_size([K|Ks],N,M0) ->
+ N = map_size(M0),
+ M1 = M0#{ K => K },
+ build_and_check_size(Ks,N + 1,M1);
+build_and_check_size([],N,M) ->
+ N = map_size(M),
ok.
map_is_size(M,N) when map_size(M) =:= N -> true;
map_is_size(_,_) -> false.
+t_is_map(Config) when is_list(Config) ->
+ true = is_map(#{}),
+ true = is_map(#{a=>1}),
+ false = is_map({a,b}),
+ false = is_map(x),
+ if is_map(#{}) -> ok end,
+ if is_map(#{b=>1}) -> ok end,
+ if not is_map([1,2,3]) -> ok end,
+ if not is_map(x) -> ok end,
+ ok.
+
% test map updates without matching
+t_update_literals_large(Config) when is_list(Config) ->
+ Map = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ #{ one => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{x:="d",q:="4"} = loop_update_literals_x_q(Map, [
+ {"a","1"},{"b","2"},{"c","3"},{"d","4"}
+ ]),
+ ok.
+
t_update_literals(Config) when is_list(Config) ->
Map = #{x=>1,y=>2,z=>3,q=>4},
#{x:="d",q:="4"} = loop_update_literals_x_q(Map, [
@@ -191,13 +775,15 @@ t_update_literals(Config) when is_list(Config) ->
]),
ok.
+
loop_update_literals_x_q(Map, []) -> Map;
loop_update_literals_x_q(Map, [{X,Q}|Vs]) ->
loop_update_literals_x_q(Map#{q=>Q,x=>X},Vs).
% test map updates with matching
t_match_and_update_literals(Config) when is_list(Config) ->
- Map = #{x=>0,y=>"untouched",z=>"also untouched",q=>1},
+ Map = #{ x=>0,y=>"untouched",z=>"also untouched",q=>1,
+ #{ "one" => small, map => key } => "small map key 1" },
#{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [
{1,2},{3,4},{5,6},{7,8}
]),
@@ -211,8 +797,78 @@ t_match_and_update_literals(Config) when is_list(Config) ->
#{ 4 := another_number, int := 3 } = M2#{ 4 => another_number },
ok.
+t_match_and_update_literals_large(Config) when is_list(Config) ->
+ Map = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ x=>0,y=>"untouched",z=>"also untouched",q=>1,
+
+ #{ "one" => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [
+ {1,2},{3,4},{5,6},{7,8}
+ ]),
+ M0 = id(Map#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat}),
+ M1 = id(Map#{}),
+ M2 = M1#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat},
+ M0 = M2,
+
+ #{ 4 := another_number, int := 3 } = M2#{ 4 => another_number },
+ ok.
+
+
loop_match_and_update_literals_x_q(Map, []) -> Map;
-loop_match_and_update_literals_x_q(#{q:=Q0,x:=X0} = Map, [{X,Q}|Vs]) ->
+loop_match_and_update_literals_x_q(#{ q:=Q0, x:=X0,
+ #{ "one" => small, map => key } := "small map key 1" } = Map, [{X,Q}|Vs]) ->
loop_match_and_update_literals_x_q(Map#{q=>Q0+Q,x=>X0+X},Vs).
@@ -224,13 +880,17 @@ t_update_map_expressions(Config) when is_list(Config) ->
#{ a :=42, b:=42, c:=42 } = (maps:from_list([{a,1},{b,2},{c,3}]))#{ a := 42, b := 42, c := 42 },
#{ "a" :=1, "b":=42, "c":=42 } = (maps:from_list([{"a",1},{"b",2}]))#{ "b" := 42, "c" => 42 },
+ Ks = lists:seq($a,$z),
+ #{ "aa" := {$a,$a}, "ac":=41, "dc":=42 } =
+ (maps:from_list([{[K1,K2],{K1,K2}}|| K1 <- Ks, K2 <- Ks]))#{ "ac" := 41, "dc" => 42 },
- %% Error cases, FIXME: should be 'badmap'?
- {'EXIT',{badarg,_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
- {'EXIT',{badarg,_}} = (catch (id([]))#{ a := 42, b => 2 }),
+ %% Error cases.
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},_}} =
+ (catch (T)#{a:=42,b=>2})
+ end),
ok.
-
t_update_assoc(Config) when is_list(Config) ->
M0 = id(#{1=>a,2=>b,3.0=>c,4=>d,5=>e}),
@@ -243,8 +903,75 @@ t_update_assoc(Config) when is_list(Config) ->
M2 = M0#{3.0:=wrong,3.0=>new},
%% Errors cases.
- BadMap = id(badmap),
- {'EXIT',{badarg,_}} = (catch BadMap#{nonexisting=>val}),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},_}} =
+ (catch T#{nonexisting=>val})
+ end),
+ ok.
+
+
+t_update_assoc_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ M1 = M0#{1=>42,2=>100,4=>[a,b,c]},
+ #{1:=42,2:=100,10.0:=fa0,4:=[a,b,c],25:=b5} = M1,
+ #{ 10:=43, 24:=b4, 15:=a5, 35:="c5", 2.0:=100, 13.0:=fa3, 4.0:=[a,b,c]} =
+ M0#{1.0=>float,10:=43,2.0=>wrong,2.0=>100,4.0=>[a,b,c]},
+
+ M2 = M0#{13.0=>new},
+ #{10:=a0,20:=b0,13.0:=new,"40":="d0",<<"50">>:="e0"} = M2,
+ M2 = M0#{13.0:=wrong,13.0=>new},
ok.
@@ -267,13 +994,122 @@ t_update_exact(Config) when is_list(Config) ->
1 := update2, 1.0 := new_val2, 1.0 => new_val3,
1.0 => new_val4 },
+ %% Errors cases.
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},_}} =
+ (catch T#{nonexisting=>val})
+ end),
+ Empty = id(#{}),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch Empty#{nonexisting:=val}),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+
+ ok.
+
+t_update_exact_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ M1 = M0#{10:=42,<<"55">>:=100,10.0:=[a,b,c]},
+ #{ 10:=42,<<"55">>:=100,{["05"]}:="15",10.0:=[a,b,c],
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1" } = M1,
+
+ M1 = M0#{10:=wrong,10=>42,<<"55">>=>wrong,<<"55">>:=100,10.0:=[a,b,c]},
+
+ M2 = M0#{13.0:=new},
+ #{10:=a0,20:=b0,13.0:=new} = M2,
+ M2 = M0#{13.0=>wrong,13.0:=new},
%% Errors cases.
- {'EXIT',{badarg,_}} = (catch M0#{nonexisting:=val}),
- {'EXIT',{badarg,_}} = (catch M0#{1.0:=v,1.0=>v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42.0:=v,42:=v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+
+ ok.
+t_update_deep(Config) when is_list(Config) ->
+ N = 250000,
+ M0 = maps:from_list([{integer_to_list(I),a}||I<-lists:seq(1,N)]),
+ #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0,
+
+ M1 = M0#{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b },
+ #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0,
+ #{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b } = M1,
+
+ M2 = M0#{ "1" => c, "10" => c, "100" => c, "1000" => c, "10000" => c },
+ #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0,
+ #{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b } = M1,
+ #{ "1" := c, "10" := c, "100" := c, "1000" := c, "10000" := c } = M2,
+
+ M3 = M2#{ "n1" => d, "n10" => d, "n100" => d, "n1000" => d, "n10000" => d },
+ #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0,
+ #{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b } = M1,
+ #{ "1" := c, "10" := c, "100" := c, "1000" := c, "10000" := c } = M2,
+ #{ "1" := c, "10" := c, "100" := c, "1000" := c, "10000" := c } = M3,
+ #{ "n1" := d, "n10" := d, "n100" := d, "n1000" := d, "n10000" := d } = M3,
ok.
t_guard_bifs(Config) when is_list(Config) ->
@@ -305,12 +1141,82 @@ t_guard_sequence(Config) when is_list(Config) ->
{3,gg,M3} = map_guard_sequence_2(M3 = id(#{a=>gg, b=>4})),
{4,sc,sc,M4} = map_guard_sequence_2(M4 = id(#{a=>sc, b=>3, c=>sc2})),
{5,kk,kk,M5} = map_guard_sequence_2(M5 = id(#{a=>kk, b=>other, c=>sc2})),
-
+
%% error case
{'EXIT',{function_clause,_}} = (catch map_guard_sequence_1(#{seq=>6,val=>id("e")})),
{'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(#{b=>5})),
ok.
+t_guard_sequence_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+ {1, "a"} = map_guard_sequence_1(M0#{seq=>1,val=>id("a")}),
+ {2, "b"} = map_guard_sequence_1(M0#{seq=>2,val=>id("b")}),
+ {3, "c"} = map_guard_sequence_1(M0#{seq=>3,val=>id("c")}),
+ {4, "d"} = map_guard_sequence_1(M0#{seq=>4,val=>id("d")}),
+ {5, "e"} = map_guard_sequence_1(M0#{seq=>5,val=>id("e")}),
+
+ {1,M1} = map_guard_sequence_2(M1 = id(M0#{a=>3})),
+ {2,M2} = map_guard_sequence_2(M2 = id(M0#{a=>4, b=>4})),
+ {3,gg,M3} = map_guard_sequence_2(M3 = id(M0#{a=>gg, b=>4})),
+ {4,sc,sc,M4} = map_guard_sequence_2(M4 = id(M0#{a=>sc, b=>3, c=>sc2})),
+ {5,kk,kk,M5} = map_guard_sequence_2(M5 = id(M0#{a=>kk, b=>other, c=>sc2})),
+
+ {'EXIT',{function_clause,_}} = (catch map_guard_sequence_1(M0#{seq=>6,val=>id("e")})),
+ {'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(M0#{b=>5})),
+ ok.
+
+
map_guard_sequence_1(#{seq:=1=Seq, val:=Val}) -> {Seq,Val};
map_guard_sequence_1(#{seq:=2=Seq, val:=Val}) -> {Seq,Val};
map_guard_sequence_1(#{seq:=3=Seq, val:=Val}) -> {Seq,Val};
@@ -330,6 +1236,66 @@ t_guard_update(Config) when is_list(Config) ->
second = map_guard_update(#{y=>old}, #{x=>second,y=>old}),
ok.
+t_guard_update_large(Config) when is_list(Config) ->
+ M0 = id(#{ 70=>a0,80=>b0,90=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10",
+ 71=>a1,81=>b1,91=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11",
+ 72=>a2,82=>b2,92=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12",
+ 73=>a3,83=>b3,93=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13",
+ 74=>a4,84=>b4,94=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14",
+
+ 75=>a5,85=>b5,95=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15",
+ 76=>a6,86=>b6,96=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16",
+ 77=>a7,87=>b7,97=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17",
+ 78=>a8,88=>b8,98=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18",
+ 79=>a9,89=>b9,99=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19",
+
+ 70.0=>fa0,80.0=>fb0,90.0=>"fc0",
+ 71.0=>fa1,81.0=>fb1,91.0=>"fc1",
+ 72.0=>fa2,82.0=>fb2,92.0=>"fc2",
+ 73.0=>fa3,83.0=>fb3,93.0=>"fc3",
+ 74.0=>fa4,84.0=>fb4,94.0=>"fc4",
+
+ 75.0=>fa5,85.0=>fb5,95.0=>"fc5",
+ 76.0=>fa6,86.0=>fb6,96.0=>"fc6",
+ 77.0=>fa7,87.0=>fb7,97.0=>"fc7",
+ 78.0=>fa8,88.0=>fb8,98.0=>"fc8",
+ 79.0=>fa9,89.0=>fb9,99.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ error = map_guard_update(M0#{},M0#{}),
+ first = map_guard_update(M0#{},M0#{x=>first}),
+ second = map_guard_update(M0#{y=>old}, M0#{x=>second,y=>old}),
+ ok.
+
+
map_guard_update(M1, M2) when M1#{x=>first} =:= M2 -> first;
map_guard_update(M1, M2) when M1#{x=>second} =:= M2 -> second;
map_guard_update(_, _) -> error.
@@ -359,6 +1325,42 @@ t_guard_receive(Config) when is_list(Config) ->
done = call(Pid, done),
ok.
+-define(t_guard_receive_large_procs, 1500).
+
+t_guard_receive_large(Config) when is_list(Config) ->
+ M = lists:foldl(fun(_,#{procs := Ps } = M) ->
+ M#{ procs := Ps#{ spawn_link(fun() -> grecv_loop() end) => 0 }}
+ end, #{procs => #{}, done => 0}, lists:seq(1,?t_guard_receive_large_procs)),
+ lists:foreach(fun(Pid) ->
+ Pid ! {self(), hello}
+ end, maps:keys(maps:get(procs,M))),
+ ok = guard_receive_large_loop(M),
+ ok.
+
+guard_receive_large_loop(#{done := ?t_guard_receive_large_procs}) ->
+ ok;
+guard_receive_large_loop(M) ->
+ receive
+ #{pid := Pid, msg := hello} ->
+ case M of
+ #{done := Count, procs := #{Pid := 150}} ->
+ Pid ! {self(), done},
+ guard_receive_large_loop(M#{done := Count + 1});
+ #{procs := #{Pid := Count} = Ps} ->
+ Pid ! {self(), hello},
+ guard_receive_large_loop(M#{procs := Ps#{Pid := Count + 1}})
+ end
+ end.
+
+grecv_loop() ->
+ receive
+ {_, done} ->
+ ok;
+ {Pid, hello} ->
+ Pid ! #{pid=>self(), msg=>hello},
+ grecv_loop()
+ end.
+
call(Pid, M) ->
Pid ! {self(), M}, receive {Pid, Res} -> Res end.
@@ -389,6 +1391,11 @@ guard_receive_loop() ->
t_list_comprehension(Config) when is_list(Config) ->
[#{k:=1},#{k:=2},#{k:=3}] = [#{k=>I} || I <- [1,2,3]],
+
+ Ks = lists:seq($a,$z),
+ Ms = [#{[K1,K2]=>{K1,K2}} || K1 <- Ks, K2 <- Ks],
+ [#{"aa" := {$a,$a}},#{"ab":={$a,$b}}|_] = Ms,
+ [#{"zz" := {$z,$z}},#{"zy":={$z,$y}}|_] = lists:reverse(Ms),
ok.
t_guard_fun(Config) when is_list(Config) ->
@@ -434,7 +1441,7 @@ t_map_sort_literals(Config) when is_list(Config) ->
true = #{ c => 1, b => 1, a => 1 } < id(#{ b => 1, c => 1, d => 1}),
true = #{ "a" => 1 } < id(#{ <<"a">> => 1}),
false = #{ <<"a">> => 1 } < id(#{ "a" => 1}),
- false = #{ 1 => 1 } < id(#{ 1.0 => 1}),
+ true = #{ 1 => 1 } < id(#{ 1.0 => 1}),
false = #{ 1.0 => 1 } < id(#{ 1 => 1}),
%% value order
@@ -442,16 +1449,47 @@ t_map_sort_literals(Config) when is_list(Config) ->
false = #{ a => 2 } < id(#{ a => 1}),
false = #{ a => 2, b => 1 } < id(#{ a => 1, b => 3}),
true = #{ a => 1, b => 1 } < id(#{ a => 1, b => 3}),
+ false = #{ a => 1 } < id(#{ a => 1.0}),
+ false = #{ a => 1.0 } < id(#{ a => 1}),
true = #{ "a" => "hi", b => 134 } == id(#{ b => 134,"a" => "hi"}),
+ %% large maps
+
+ M = maps:from_list([{I,I}||I <- lists:seq(1,500)]),
+
+ %% size order
+ true = M#{ a => 1, b => 2} < id(M#{ a => 1, b => 1, c => 1}),
+ true = M#{ b => 1, a => 1} < id(M#{ c => 1, a => 1, b => 1}),
+ false = M#{ c => 1, b => 1, a => 1} < id(M#{ c => 1, a => 1}),
+
+ %% key order
+ true = M#{ a => 1 } < id(M#{ b => 1}),
+ false = M#{ b => 1 } < id(M#{ a => 1}),
+ true = M#{ a => 1, b => 1, c => 1 } < id(M#{ b => 1, c => 1, d => 1}),
+ true = M#{ b => 1, c => 1, d => 1 } > id(M#{ a => 1, b => 1, c => 1}),
+ true = M#{ c => 1, b => 1, a => 1 } < id(M#{ b => 1, c => 1, d => 1}),
+ true = M#{ "a" => 1 } < id(M#{ <<"a">> => 1}),
+ false = M#{ <<"a">> => 1 } < id(#{ "a" => 1}),
+ true = M#{ 1 => 1 } < id(maps:remove(1,M#{ 1.0 => 1})),
+ false = M#{ 1.0 => 1 } < id(M#{ 1 => 1}),
+
+ %% value order
+ true = M#{ a => 1 } < id(M#{ a => 2}),
+ false = M#{ a => 2 } < id(M#{ a => 1}),
+ false = M#{ a => 2, b => 1 } < id(M#{ a => 1, b => 3}),
+ true = M#{ a => 1, b => 1 } < id(M#{ a => 1, b => 3}),
+ false = M#{ a => 1 } < id(M#{ a => 1.0}),
+ false = M#{ a => 1.0 } < id(M#{ a => 1}),
+
+ true = M#{ "a" => "hi", b => 134 } == id(M#{ b => 134,"a" => "hi"}),
+
%% lists:sort
SortVs = [#{"a"=>1},#{a=>2},#{1=>3},#{<<"a">>=>4}],
[#{1:=ok},#{a:=ok},#{"a":=ok},#{<<"a">>:=ok}] = lists:sort([#{"a"=>ok},#{a=>ok},#{1=>ok},#{<<"a">>=>ok}]),
[#{1:=3},#{a:=2},#{"a":=1},#{<<"a">>:=4}] = lists:sort(SortVs),
[#{1:=3},#{a:=2},#{"a":=1},#{<<"a">>:=4}] = lists:sort(lists:reverse(SortVs)),
-
ok.
t_map_equal(Config) when is_list(Config) ->
@@ -471,27 +1509,292 @@ t_map_equal(Config) when is_list(Config) ->
true = id(#{ a => 1, b => 3, c => <<"wat">> }) =:= id(#{ a => 1, b => 3, c=><<"wat">>}),
ok.
+
+t_map_compare(Config) when is_list(Config) ->
+ Seed = {erlang:monotonic_time(),
+ erlang:time_offset(),
+ erlang:unique_integer()},
+ io:format("seed = ~p\n", [Seed]),
+ random:seed(Seed),
+ repeat(100, fun(_) -> float_int_compare() end, []),
+ repeat(100, fun(_) -> recursive_compare() end, []),
+ ok.
+
+float_int_compare() ->
+ Terms = numeric_keys(3),
+ %%io:format("Keys to use: ~p\n", [Terms]),
+ Pairs = lists:map(fun(K) -> list_to_tuple([{K,V} || V <- Terms]) end, Terms),
+ lists:foreach(fun(Size) ->
+ MapGen = fun() -> map_gen(list_to_tuple(Pairs), Size) end,
+ repeat(100, fun do_compare/1, [MapGen, MapGen])
+ end,
+ lists:seq(1,length(Terms))),
+ ok.
+
+numeric_keys(N) ->
+ lists:foldl(fun(_,Acc) ->
+ Int = random:uniform(N*4) - N*2,
+ Float = float(Int),
+ [Int, Float, Float * 0.99, Float * 1.01 | Acc]
+ end,
+ [],
+ lists:seq(1,N)).
+
+
+repeat(0, _, _) ->
+ ok;
+repeat(N, Fun, Arg) ->
+ Fun(Arg),
+ repeat(N-1, Fun, Arg).
+
+copy_term(T) ->
+ Papa = self(),
+ P = spawn_link(fun() -> receive Msg -> Papa ! Msg end end),
+ P ! T,
+ receive R -> R end.
+
+do_compare([Gen1, Gen2]) ->
+ M1 = Gen1(),
+ M2 = Gen2(),
+ %%io:format("Maps to compare: ~p AND ~p\n", [M1, M2]),
+ C = (M1 < M2),
+ Erlang = maps_lessthan(M1, M2),
+ C = Erlang,
+ ?CHECK(M1==M1, M1),
+
+ %% Change one key from int to float (or vice versa) and check compare
+ ML1 = maps:to_list(M1),
+ {K1,V1} = lists:nth(random:uniform(length(ML1)), ML1),
+ case K1 of
+ I when is_integer(I) ->
+ case maps:find(float(I),M1) of
+ error ->
+ M1f = maps:remove(I, maps:put(float(I), V1, M1)),
+ ?CHECK(M1f > M1, [M1f, M1]);
+ _ -> ok
+ end;
+
+ F when is_float(F), round(F) == F ->
+ case maps:find(round(F),M1) of
+ error ->
+ M1i = maps:remove(F, maps:put(round(F), V1, M1)),
+ ?CHECK(M1i < M1, [M1i, M1]);
+ _ -> ok
+ end;
+
+ _ -> ok % skip floats with decimals
+ end,
+
+ ?CHECK(M2 == M2, [M2]).
+
+
+maps_lessthan(M1, M2) ->
+ case {maps:size(M1),maps:size(M2)} of
+ {_S,_S} ->
+ {K1,V1} = lists:unzip(term_sort(maps:to_list(M1))),
+ {K2,V2} = lists:unzip(term_sort(maps:to_list(M2))),
+
+ case erts_internal:cmp_term(K1,K2) of
+ -1 -> true;
+ 0 -> (V1 < V2);
+ 1 -> false
+ end;
+
+ {S1, S2} ->
+ S1 < S2
+ end.
+
+term_sort(L) ->
+ lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) =< 0 end,
+ L).
+
+
+cmp(T1, T2, Exact) when is_tuple(T1) and is_tuple(T2) ->
+ case {size(T1),size(T2)} of
+ {_S,_S} -> cmp(tuple_to_list(T1), tuple_to_list(T2), Exact);
+ {S1,S2} when S1 < S2 -> -1;
+ {S1,S2} when S1 > S2 -> 1
+ end;
+
+cmp([H1|T1], [H2|T2], Exact) ->
+ case cmp(H1,H2, Exact) of
+ 0 -> cmp(T1,T2, Exact);
+ C -> C
+ end;
+
+cmp(M1, M2, Exact) when is_map(M1) andalso is_map(M2) ->
+ cmp_maps(M1,M2,Exact);
+cmp(M1, M2, Exact) ->
+ cmp_others(M1, M2, Exact).
+
+cmp_maps(M1, M2, Exact) ->
+ case {maps:size(M1),maps:size(M2)} of
+ {_S,_S} ->
+ {K1,V1} = lists:unzip(term_sort(maps:to_list(M1))),
+ {K2,V2} = lists:unzip(term_sort(maps:to_list(M2))),
+
+ case cmp(K1, K2, true) of
+ 0 -> cmp(V1, V2, Exact);
+ C -> C
+ end;
+
+ {S1,S2} when S1 < S2 -> -1;
+ {S1,S2} when S1 > S2 -> 1
+ end.
+
+cmp_others(I, F, true) when is_integer(I), is_float(F) ->
+ -1;
+cmp_others(F, I, true) when is_float(F), is_integer(I) ->
+ 1;
+cmp_others(T1, T2, _) ->
+ case {T1<T2, T1==T2} of
+ {true,false} -> -1;
+ {false,true} -> 0;
+ {false,false} -> 1
+ end.
+
+map_gen(Pairs, Size) ->
+ {_,L} = lists:foldl(fun(_, {Keys, Acc}) ->
+ KI = random:uniform(size(Keys)),
+ K = element(KI,Keys),
+ KV = element(random:uniform(size(K)), K),
+ {erlang:delete_element(KI,Keys), [KV | Acc]}
+ end,
+ {Pairs, []},
+ lists:seq(1,Size)),
+
+ maps:from_list(L).
+
+
+recursive_compare() ->
+ Leafs = {atom, 17, 16.9, 17.1, [], self(), spawn(fun() -> ok end), make_ref(), make_ref()},
+ {A, B} = term_gen_recursive(Leafs, 0, 0),
+ %%io:format("Recursive term A = ~p\n", [A]),
+ %%io:format("Recursive term B = ~p\n", [B]),
+
+ ?CHECK({true,false} =:= case do_cmp(A, B, false) of
+ -1 -> {A<B, A>=B};
+ 0 -> {A==B, A/=B};
+ 1 -> {A>B, A=<B}
+ end,
+ {A,B}),
+ A2 = copy_term(A),
+ ?CHECK(A == A2, {A,A2}),
+ ?CHECK(0 =:= cmp(A, A2, false), {A,A2}),
+
+ B2 = copy_term(B),
+ ?CHECK(B == B2, {B,B2}),
+ ?CHECK(0 =:= cmp(B, B2, false), {B,B2}),
+ ok.
+
+do_cmp(A, B, Exact) ->
+ C = cmp(A, B, Exact),
+ C.
+
+%% Generate two terms {A,B} that may only differ
+%% at float vs integer types.
+term_gen_recursive(Leafs, Flags, Depth) ->
+ MaxDepth = 10,
+ Rnd = case {Flags, Depth} of
+ {_, MaxDepth} -> % Only leafs
+ random:uniform(size(Leafs)) + 3;
+ {0, 0} -> % Only containers
+ random:uniform(3);
+ {0,_} -> % Anything
+ random:uniform(size(Leafs)+3)
+ end,
+ case Rnd of
+ 1 -> % Make map
+ Size = random:uniform(size(Leafs)),
+ lists:foldl(fun(_, {Acc1,Acc2}) ->
+ {K1,K2} = term_gen_recursive(Leafs, Flags,
+ Depth+1),
+ {V1,V2} = term_gen_recursive(Leafs, Flags, Depth+1),
+ %%ok = check_keys(K1,K2, 0),
+ {maps:put(K1,V1, Acc1), maps:put(K2,V2, Acc2)}
+ end,
+ {maps:new(), maps:new()},
+ lists:seq(1,Size));
+ 2 -> % Make cons
+ {Car1,Car2} = term_gen_recursive(Leafs, Flags, Depth+1),
+ {Cdr1,Cdr2} = term_gen_recursive(Leafs, Flags, Depth+1),
+ {[Car1 | Cdr1], [Car2 | Cdr2]};
+ 3 -> % Make tuple
+ Size = random:uniform(size(Leafs)),
+ L = lists:map(fun(_) -> term_gen_recursive(Leafs, Flags, Depth+1) end,
+ lists:seq(1,Size)),
+ {L1, L2} = lists:unzip(L),
+ {list_to_tuple(L1), list_to_tuple(L2)};
+
+ N -> % Make leaf
+ case element(N-3, Leafs) of
+ I when is_integer(I) ->
+ case random:uniform(4) of
+ 1 -> {I, float(I)};
+ 2 -> {float(I), I};
+ _ -> {I,I}
+ end;
+ T -> {T,T}
+ end
+ end.
+
+check_keys(K1, K2, _) when K1 =:= K2 ->
+ case erlang:phash3(K1) =:= erlang:phash3(K2) of
+ true -> ok;
+ false ->
+ io:format("Same keys with different hash values !!!\nK1 = ~p\nK2 = ~p\n", [K1,K2]),
+ error
+ end;
+check_keys(K1, K2, 0) ->
+ case {erlang:phash3(K1), erlang:phash3(K2)} of
+ {H,H} -> check_keys(K1, K2, 1);
+ {_,_} -> ok
+ end;
+check_keys(K1, K2, L) when L < 10 ->
+ case {erlang:phash3([L|K1]), erlang:phash3([L|K2])} of
+ {H,H} -> check_keys(K1, K2, L+1);
+ {_,_} -> ok
+ end;
+check_keys(K1, K2, L) ->
+ io:format("Same hash value at level ~p !!!\nK1 = ~p\nK2 = ~p\n", [L,K1,K2]),
+ error.
+
%% BIFs
t_bif_map_get(Config) when is_list(Config) ->
-
+ %% small map
1 = maps:get(a, #{ a=> 1}),
2 = maps:get(b, #{ a=> 1, b => 2}),
"hi" = maps:get("hello", #{ a=>1, "hello" => "hi"}),
"tuple hi" = maps:get({1,1.0}, #{ a=>a, {1,1.0} => "tuple hi"}),
- M = id(#{ k1=>"v1", <<"k2">> => <<"v3">> }),
- "v4" = maps:get(<<"k2">>, M#{ <<"k2">> => "v4" }),
+ M0 = id(#{ k1=>"v1", <<"k2">> => <<"v3">> }),
+ "v4" = maps:get(<<"k2">>, M0#{<<"k2">> => "v4"}),
- %% error case
- {'EXIT',{badarg, [{maps,get,_,_}|_]}} = (catch maps:get(a,[])),
- {'EXIT',{badarg, [{maps,get,_,_}|_]}} = (catch maps:get(a,<<>>)),
- {'EXIT',{bad_key,[{maps,get,_,_}|_]}} = (catch maps:get({1,1}, #{{1,1.0} => "tuple"})),
- {'EXIT',{bad_key,[{maps,get,_,_}|_]}} = (catch maps:get(a,#{})),
- {'EXIT',{bad_key,[{maps,get,_,_}|_]}} = (catch maps:get(a,#{ b=>1, c=>2})),
+ %% large map
+ M1 = maps:from_list([{I,I}||I<-lists:seq(1,100)] ++
+ [{a,1},{b,2},{"hello","hi"},{{1,1.0},"tuple hi"},
+ {k1,"v1"},{<<"k2">>,"v3"}]),
+ 1 = maps:get(a, M1),
+ 2 = maps:get(b, M1),
+ "hi" = maps:get("hello", M1),
+ "tuple hi" = maps:get({1,1.0}, M1),
+ "v3" = maps:get(<<"k2">>, M1),
+
+ %% error cases
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,get,_,_}|_]}} =
+ (catch maps:get(a, T))
+ end),
+
+ {'EXIT',{{badkey,{1,1}},[{maps,get,_,_}|_]}} =
+ (catch maps:get({1,1}, #{{1,1.0} => "tuple"})),
+ {'EXIT',{{badkey,a},[{maps,get,_,_}|_]}} = (catch maps:get(a, #{})),
+ {'EXIT',{{badkey,a},[{maps,get,_,_}|_]}} =
+ (catch maps:get(a, #{b=>1, c=>2})),
ok.
t_bif_map_find(Config) when is_list(Config) ->
-
+ %% small map
{ok, 1} = maps:find(a, #{ a=> 1}),
{ok, 2} = maps:find(b, #{ a=> 1, b => 2}),
{ok, "int"} = maps:find(1, #{ 1 => "int"}),
@@ -500,8 +1803,18 @@ t_bif_map_find(Config) when is_list(Config) ->
{ok, "hi"} = maps:find("hello", #{ a=>1, "hello" => "hi"}),
{ok, "tuple hi"} = maps:find({1,1.0}, #{ a=>a, {1,1.0} => "tuple hi"}),
- M = id(#{ k1=>"v1", <<"k2">> => <<"v3">> }),
- {ok, "v4"} = maps:find(<<"k2">>, M#{ <<"k2">> => "v4" }),
+ M0 = id(#{ k1=>"v1", <<"k2">> => <<"v3">> }),
+ {ok, "v4"} = maps:find(<<"k2">>, M0#{ <<"k2">> => "v4" }),
+
+ %% large map
+ M1 = maps:from_list([{I,I}||I<-lists:seq(1,100)] ++
+ [{a,1},{b,2},{"hello","hi"},{{1,1.0},"tuple hi"},
+ {k1,"v1"},{<<"k2">>,"v3"}]),
+ {ok, 1} = maps:find(a, M1),
+ {ok, 2} = maps:find(b, M1),
+ {ok, "hi"} = maps:find("hello", M1),
+ {ok, "tuple hi"} = maps:find({1,1.0}, M1),
+ {ok, "v3"} = maps:find(<<"k2">>, M1),
%% error case
error = maps:find(a,#{}),
@@ -510,9 +1823,10 @@ t_bif_map_find(Config) when is_list(Config) ->
error = maps:find(1, #{ 1.0 => "float"}),
error = maps:find({1.0,1}, #{ a=>a, {1,1.0} => "tuple hi"}), % reverse types in tuple key
-
- {'EXIT',{badarg,[{maps,find,_,_}|_]}} = (catch maps:find(a,id([]))),
- {'EXIT',{badarg,[{maps,find,_,_}|_]}} = (catch maps:find(a,id(<<>>))),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,find,_,_}|_]}} =
+ (catch maps:find(a, T))
+ end),
ok.
@@ -537,26 +1851,27 @@ t_bif_map_is_key(Config) when is_list(Config) ->
false = maps:is_key(1.0, maps:put(1, "number", M1)),
%% error case
- {'EXIT',{badarg,[{maps,is_key,_,_}|_]}} = (catch maps:is_key(a,id([]))),
- {'EXIT',{badarg,[{maps,is_key,_,_}|_]}} = (catch maps:is_key(a,id(<<>>))),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,is_key,_,_}|_]}} =
+ (catch maps:is_key(a, T))
+ end),
ok.
t_bif_map_keys(Config) when is_list(Config) ->
[] = maps:keys(#{}),
- [1,2,3,4,5] = maps:keys(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e}),
- [1,2,3,4,5] = maps:keys(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c}),
+ [1,2,3,4,5] = lists:sort(maps:keys(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e})),
+ [1,2,3,4,5] = lists:sort(maps:keys(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c})),
% values in key order: [4,int,"hi",<<"key">>]
M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number},
- [4,int,"hi",<<"key">>] = maps:keys(M1),
+ [4,int,"hi",<<"key">>] = lists:sort(maps:keys(M1)),
%% error case
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(154)),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(atom)),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys([])),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(<<>>)),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,keys,_,_}|_]}} =
+ (catch maps:keys(T))
+ end),
ok.
t_bif_map_new(Config) when is_list(Config) ->
@@ -584,11 +1899,58 @@ t_bif_map_merge(Config) when is_list(Config) ->
#{4 := integer, 18446744073709551629 := wat, float := 3.3, int := 3,
{1,2} := "tuple", "hi" := "hello again", <<"key">> := <<"value">>} = maps:merge(M0,M1),
- %% error case
- {'EXIT',{badarg,[{maps,merge,_,_}|_]}} = (catch maps:merge((1 bsl 65 + 3), <<>>)),
- {'EXIT',{badarg,[{maps,merge,_,_}|_]}} = (catch maps:merge(<<>>, id(#{ a => 1}))),
- {'EXIT',{badarg,[{maps,merge,_,_}|_]}} = (catch maps:merge(id(#{ a => 2}), <<>> )),
+ %% try deep collisions
+ N = 150000,
+ Is = lists:seq(1,N),
+ M2 = maps:from_list([{I,I}||I<-Is]),
+ 150000 = maps:size(M2),
+ M3 = maps:from_list([{<<I:32>>,I}||I<-Is]),
+ 150000 = maps:size(M3),
+ M4 = maps:merge(M2,M3),
+ 300000 = maps:size(M4),
+ M5 = maps:from_list([{integer_to_list(I),I}||I<-Is]),
+ 150000 = maps:size(M5),
+ M6 = maps:merge(M4,M5),
+ 450000 = maps:size(M6),
+ M7 = maps:from_list([{float(I),I}||I<-Is]),
+ 150000 = maps:size(M7),
+ M8 = maps:merge(M7,M6),
+ 600000 = maps:size(M8),
+
+ #{ 1 := 1, "1" := 1, <<1:32>> := 1 } = M8,
+ #{ 10 := 10, "10" := 10, <<10:32>> := 10 } = M8,
+ #{ 100 := 100, "100" := 100, <<100:32>> := 100 } = M8,
+ #{ 1000 := 1000, "1000" := 1000, <<1000:32>> := 1000 } = M8,
+ #{ 10000 := 10000, "10000" := 10000, <<10000:32>> := 10000 } = M8,
+ #{ 100000 := 100000, "100000" := 100000, <<100000:32>> := 100000 } = M8,
+
+ %% overlapping
+ M8 = maps:merge(M2,M8),
+ M8 = maps:merge(M3,M8),
+ M8 = maps:merge(M4,M8),
+ M8 = maps:merge(M5,M8),
+ M8 = maps:merge(M6,M8),
+ M8 = maps:merge(M7,M8),
+ M8 = maps:merge(M8,M8),
+
+ %% maps:merge/2 and mixed
+
+ Ks1 = [764492191,2361333849], %% deep collision
+ Ks2 = lists:seq(1,33),
+ M9 = maps:from_list([{K,K}||K <- Ks1]),
+ M10 = maps:from_list([{K,K}||K <- Ks2]),
+ M11 = maps:merge(M9,M10),
+ ok = check_keys_exist(Ks1 ++ Ks2, M11),
+ %% error case
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,merge,_,_}|_]}} =
+ (catch maps:merge(#{}, T)),
+ {'EXIT',{{badmap,T},[{maps,merge,_,_}|_]}} =
+ (catch maps:merge(T, #{})),
+ {'EXIT',{{badmap,T},[{maps,merge,_,_}|_]}} =
+ (catch maps:merge(T, T))
+ end),
ok.
@@ -598,41 +1960,48 @@ t_bif_map_put(Config) when is_list(Config) ->
M1 = #{ "hi" := "hello"} = maps:put("hi", "hello", #{}),
- ["hi"] = maps:keys(M1),
- ["hello"] = maps:values(M1),
+ true = is_members(["hi"],maps:keys(M1)),
+ true = is_members(["hello"],maps:values(M1)),
M2 = #{ int := 3 } = maps:put(int, 3, M1),
- [int,"hi"] = maps:keys(M2),
- [3,"hello"] = maps:values(M2),
+ true = is_members([int,"hi"],maps:keys(M2)),
+ true = is_members([3,"hello"],maps:values(M2)),
M3 = #{ <<"key">> := <<"value">> } = maps:put(<<"key">>, <<"value">>, M2),
- [int,"hi",<<"key">>] = maps:keys(M3),
- [3,"hello",<<"value">>] = maps:values(M3),
+ true = is_members([int,"hi",<<"key">>],maps:keys(M3)),
+ true = is_members([3,"hello",<<"value">>],maps:values(M3)),
M4 = #{ 18446744073709551629 := wat } = maps:put(18446744073709551629, wat, M3),
- [18446744073709551629,int,"hi",<<"key">>] = maps:keys(M4),
- [wat,3,"hello",<<"value">>] = maps:values(M4),
+ true = is_members([18446744073709551629,int,"hi",<<"key">>],maps:keys(M4)),
+ true = is_members([wat,3,"hello",<<"value">>],maps:values(M4)),
M0 = #{ 4 := number } = M5 = maps:put(4, number, M4),
- [4,18446744073709551629,int,"hi",<<"key">>] = maps:keys(M5),
- [number,wat,3,"hello",<<"value">>] = maps:values(M5),
+ true = is_members([4,18446744073709551629,int,"hi",<<"key">>],maps:keys(M5)),
+ true = is_members([number,wat,3,"hello",<<"value">>],maps:values(M5)),
M6 = #{ <<"key">> := <<"other value">> } = maps:put(<<"key">>, <<"other value">>, M5),
- [4,18446744073709551629,int,"hi",<<"key">>] = maps:keys(M6),
- [number,wat,3,"hello",<<"other value">>] = maps:values(M6),
+ true = is_members([4,18446744073709551629,int,"hi",<<"key">>],maps:keys(M6)),
+ true = is_members([number,wat,3,"hello",<<"other value">>],maps:values(M6)),
%% error case
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,154)),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,atom)),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,[])),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,<<>>)),
- ok.
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,put,_,_}|_]}} =
+ (catch maps:put(1, a, T))
+ end),
+ ok.
+
+is_members(Ks,Ls) when length(Ks) =/= length(Ls) -> false;
+is_members(Ks,Ls) -> is_members_do(Ks,Ls).
+
+is_members_do([],[]) -> true;
+is_members_do([],_) -> false;
+is_members_do([K|Ks],Ls) ->
+ is_members_do(Ks, lists:delete(K,Ls)).
t_bif_map_remove(Config) when is_list(Config) ->
0 = erlang:map_size(maps:remove(some_key, #{})),
@@ -641,20 +2010,20 @@ t_bif_map_remove(Config) when is_list(Config) ->
4 => number, 18446744073709551629 => wat},
M1 = maps:remove("hi", M0),
- [4,18446744073709551629,int,<<"key">>] = maps:keys(M1),
- [number,wat,3,<<"value">>] = maps:values(M1),
+ true = is_members([4,18446744073709551629,int,<<"key">>],maps:keys(M1)),
+ true = is_members([number,wat,3,<<"value">>],maps:values(M1)),
M2 = maps:remove(int, M1),
- [4,18446744073709551629,<<"key">>] = maps:keys(M2),
- [number,wat,<<"value">>] = maps:values(M2),
+ true = is_members([4,18446744073709551629,<<"key">>],maps:keys(M2)),
+ true = is_members([number,wat,<<"value">>],maps:values(M2)),
M3 = maps:remove(<<"key">>, M2),
- [4,18446744073709551629] = maps:keys(M3),
- [number,wat] = maps:values(M3),
+ true = is_members([4,18446744073709551629],maps:keys(M3)),
+ true = is_members([number,wat],maps:values(M3)),
M4 = maps:remove(18446744073709551629, M3),
- [4] = maps:keys(M4),
- [number] = maps:values(M4),
+ true = is_members([4],maps:keys(M4)),
+ true = is_members([number],maps:values(M4)),
M5 = maps:remove(4, M4),
[] = maps:keys(M5),
@@ -666,11 +2035,10 @@ t_bif_map_remove(Config) when is_list(Config) ->
#{ "hi" := "hello", int := 3, 4 := number} = maps:remove(18446744073709551629,maps:remove(<<"key">>,M0)),
%% error case
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(a,1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(1,154)),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(a,atom)),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(1,[])),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(a,<<>>)),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,remove,_,_}|_]}} =
+ (catch maps:remove(a, T))
+ end),
ok.
t_bif_map_update(Config) when is_list(Config) ->
@@ -693,10 +2061,10 @@ t_bif_map_update(Config) when is_list(Config) ->
4 := number, 18446744073709551629 := wazzup} = maps:update(18446744073709551629, wazzup, M0),
%% error case
- {'EXIT',{badarg,[{maps,update,_,_}|_]}} = (catch maps:update(1,none,{})),
- {'EXIT',{badarg,[{maps,update,_,_}|_]}} = (catch maps:update(1,none,<<"value">>)),
- {'EXIT',{badarg,[{maps,update,_,_}|_]}} = (catch maps:update(5,none,M0)),
-
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,update,_,_}|_]}} =
+ (catch maps:update(1, none, T))
+ end),
ok.
@@ -704,21 +2072,29 @@ t_bif_map_update(Config) when is_list(Config) ->
t_bif_map_values(Config) when is_list(Config) ->
[] = maps:values(#{}),
+ [1] = maps:values(#{a=>1}),
- [a,b,c,d,e] = maps:values(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e}),
- [a,b,c,d,e] = maps:values(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c}),
+ true = is_members([a,b,c,d,e],maps:values(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e})),
+ true = is_members([a,b,c,d,e],maps:values(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c})),
- % values in key order: [4,int,"hi",<<"key">>]
M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number},
M2 = M1#{ "hi" => "hello2", <<"key">> => <<"value2">> },
- [number,3,"hello2",<<"value2">>] = maps:values(M2),
- [number,3,"hello",<<"value">>] = maps:values(M1),
+ true = is_members([number,3,"hello2",<<"value2">>],maps:values(M2)),
+ true = is_members([number,3,"hello",<<"value">>],maps:values(M1)),
+
+ Vs = lists:seq(1000,20000),
+ M3 = maps:from_list([{K,K}||K<-Vs]),
+ M4 = maps:merge(M1,M3),
+ M5 = maps:merge(M2,M3),
+ true = is_members(Vs,maps:values(M3)),
+ true = is_members([number,3,"hello",<<"value">>]++Vs,maps:values(M4)),
+ true = is_members([number,3,"hello2",<<"value2">>]++Vs,maps:values(M5)),
%% error case
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values(1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values(atom)),
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values([])),
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values(<<>>)),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},[{maps,values,_,_}|_]}} =
+ (catch maps:values(T))
+ end),
ok.
t_erlang_hash(Config) when is_list(Config) ->
@@ -732,61 +2108,61 @@ t_erlang_hash(Config) when is_list(Config) ->
t_bif_erlang_phash2() ->
39679005 = erlang:phash2(#{}),
- 78942764 = erlang:phash2(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 }),
- 37338230 = erlang:phash2(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} }),
- 14363616 = erlang:phash2(#{ 1 => a }),
- 51612236 = erlang:phash2(#{ a => 1 }),
+ 33667975 = erlang:phash2(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 }), % 78942764
+ 95332690 = erlang:phash2(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} }), % 37338230
+ 108954384 = erlang:phash2(#{ 1 => a }), % 14363616
+ 59617982 = erlang:phash2(#{ a => 1 }), % 51612236
- 37468437 = erlang:phash2(#{{} => <<>>}),
- 44049159 = erlang:phash2(#{<<>> => {}}),
+ 42770201 = erlang:phash2(#{{} => <<>>}), % 37468437
+ 71687700 = erlang:phash2(#{<<>> => {}}), % 44049159
M0 = #{ a => 1, "key" => <<"value">> },
M1 = maps:remove("key",M0),
M2 = M1#{ "key" => <<"value">> },
- 118679416 = erlang:phash2(M0),
- 51612236 = erlang:phash2(M1),
- 118679416 = erlang:phash2(M2),
+ 70249457 = erlang:phash2(M0), % 118679416
+ 59617982 = erlang:phash2(M1), % 51612236
+ 70249457 = erlang:phash2(M2), % 118679416
ok.
t_bif_erlang_phash() ->
Sz = 1 bsl 32,
- 268440612 = erlang:phash(#{},Sz),
- 1196461908 = erlang:phash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz),
- 3944426064 = erlang:phash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz),
- 1394238263 = erlang:phash(#{ 1 => a },Sz),
- 4066388227 = erlang:phash(#{ a => 1 },Sz),
+ 1113425985 = erlang:phash(#{},Sz), % 268440612
+ 1510068139 = erlang:phash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 1196461908
+ 3182345590 = erlang:phash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 3944426064
+ 2927531828 = erlang:phash(#{ 1 => a },Sz), % 1394238263
+ 1670235874 = erlang:phash(#{ a => 1 },Sz), % 4066388227
- 1578050717 = erlang:phash(#{{} => <<>>},Sz),
- 1578050717 = erlang:phash(#{<<>> => {}},Sz), % yep, broken
+ 3935089469 = erlang:phash(#{{} => <<>>},Sz), % 1578050717
+ 71692856 = erlang:phash(#{<<>> => {}},Sz), % 1578050717
M0 = #{ a => 1, "key" => <<"value">> },
M1 = maps:remove("key",M0),
M2 = M1#{ "key" => <<"value">> },
- 3590546636 = erlang:phash(M0,Sz),
- 4066388227 = erlang:phash(M1,Sz),
- 3590546636 = erlang:phash(M2,Sz),
+ 2620391445 = erlang:phash(M0,Sz), % 3590546636
+ 1670235874 = erlang:phash(M1,Sz), % 4066388227
+ 2620391445 = erlang:phash(M2,Sz), % 3590546636
ok.
t_bif_erlang_hash() ->
Sz = 1 bsl 27 - 1,
- 5158 = erlang:hash(#{},Sz),
- 71555838 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz),
- 5497225 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz),
- 126071654 = erlang:hash(#{ 1 => a },Sz),
- 126426236 = erlang:hash(#{ a => 1 },Sz),
+ 39684169 = erlang:hash(#{},Sz), % 5158
+ 33673142 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 71555838
+ 95337869 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 5497225
+ 108959561 = erlang:hash(#{ 1 => a },Sz), % 126071654
+ 59623150 = erlang:hash(#{ a => 1 },Sz), % 126426236
- 101655720 = erlang:hash(#{{} => <<>>},Sz),
- 101655720 = erlang:hash(#{<<>> => {}},Sz), % yep, broken
+ 42775386 = erlang:hash(#{{} => <<>>},Sz), % 101655720
+ 71692856 = erlang:hash(#{<<>> => {}},Sz), % 101655720
M0 = #{ a => 1, "key" => <<"value">> },
M1 = maps:remove("key",M0),
M2 = M1#{ "key" => <<"value">> },
- 38260486 = erlang:hash(M0,Sz),
- 126426236 = erlang:hash(M1,Sz),
- 38260486 = erlang:hash(M2,Sz),
+ 70254632 = erlang:hash(M0,Sz), % 38260486
+ 59623150 = erlang:hash(M1,Sz), % 126426236
+ 70254632 = erlang:hash(M2,Sz), % 38260486
ok.
@@ -807,7 +2183,9 @@ t_map_encode_decode(Config) when is_list(Config) ->
{<<>>, sc9}, {3.14158, sc10},
{[3.14158], sc11}, {more_atoms, sc12},
{{more_tuples}, sc13}, {self(), sc14},
- {{},{}},{[],[]}
+ {{},{}},{[],[]},
+ {map_s, #{a=>a, 2=>b, 3=>c}},
+ {map_l, maps:from_list([{I,I}||I <- lists:seq(1,74)])}
],
ok = map_encode_decode_and_match(Pairs,[],#{}),
@@ -820,14 +2198,35 @@ t_map_encode_decode(Config) when is_list(Config) ->
%% literally #{ "hi" => "value", a=>33, b=>55 } in the internal order
#{ a:=33, b:=55, "hi" := "value"} = erlang:binary_to_term(<<131,116,0,0,0,3,
- 107,0,2,104,105, % "hi" :: list()
+ 107,0,2,104,105, % "hi" :: list()
107,0,5,118,97,108,117,101, % "value" :: list()
- 100,0,1,97, % a :: atom()
- 97,33, % 33 :: integer()
- 100,0,1,98, % b :: atom()
- 97,55 % 55 :: integer()
+ 100,0,1,97, % a :: atom()
+ 97,33, % 33 :: integer()
+ 100,0,1,98, % b :: atom()
+ 97,55 % 55 :: integer()
>>),
+ %% Maps of different sizes
+ lists:foldl(fun(Key, M0) ->
+ M1 = M0#{Key => Key},
+ case Key rem 17 of
+ 0 ->
+ M1 = binary_to_term(term_to_binary(M1));
+ _ ->
+ ok
+ end,
+ M1
+ end,
+ #{},
+ lists:seq(1,10000)),
+
+ %% many maps in same binary
+ MapList = lists:foldl(fun(K, [M|_]=Acc) -> [M#{K => K} | Acc] end,
+ [#{}],
+ lists:seq(1,100)),
+ MapList = binary_to_term(term_to_binary(MapList)),
+ MapListR = lists:reverse(MapList),
+ MapListR = binary_to_term(term_to_binary(MapListR)),
%% error cases
%% template: <<131,116,0,0,0,2,100,0,1,97,100,0,1,98,97,1,97,1>>
@@ -850,51 +2249,77 @@ t_map_encode_decode(Config) when is_list(Config) ->
%% bad size (too small) .. should fail just truncate it .. weird.
%% possibly change external format so truncated will be #{a:=1}
- #{ a:=b } =
- erlang:binary_to_term(<<131,116,0,0,0,1,100,0,1,97,100,0,1,98,97,1,97,1>>),
-
+ #{ a:=b } = erlang:binary_to_term(<<131,116,0,0,0,1,100,0,1,97,100,0,1,98,97,1,97,1>>),
+
+ %% specific fannerl (opensource app) binary_to_term error in 18.1
+
+ #{bias := {1,1,0},
+ bit_fail := 0,
+ connections := #{{2,9} := _,
+ {8,14} := _,
+ {2,12} := _,
+ {5,7} := _,
+ {11,16} := _,
+ {11,15} := _},
+ layers := {5,7,3},
+ network_type := fann_nettype_layer,
+ num_input := 5,
+ num_layers := 3,
+ num_output := 3,
+ rprop_delta_max := _,
+ rprop_delta_min := _,
+ total_connections := 66,
+ total_neurons := 17,
+ train_error_function := fann_errorfunc_tanh,
+ train_stop_function := fann_stopfunc_mse,
+ training_algorithm := fann_train_rprop} = erlang:binary_to_term(fannerl()),
ok.
map_encode_decode_and_match([{K,V}|Pairs], EncodedPairs, M0) ->
M1 = maps:put(K,V,M0),
B0 = erlang:term_to_binary(M1),
- Ls = lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) < 0 end, [{K, erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs]),
- %% sort Ks and Vs according to term spec, then match it
- KVbins = lists:foldr(fun({_,Kbin,Vbin}, Acc) -> [Kbin,Vbin | Acc] end, [], Ls),
- ok = match_encoded_map(B0, length(Ls), KVbins),
+ Ls = [{erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs],
+ ok = match_encoded_map(B0, length(Ls), Ls),
%% decode and match it
M1 = erlang:binary_to_term(B0),
map_encode_decode_and_match(Pairs,Ls,M1);
map_encode_decode_and_match([],_,_) -> ok.
match_encoded_map(<<131,116,Size:32,Encoded/binary>>,Size,Items) ->
- match_encoded_map(Encoded,Items);
+ match_encoded_map_stripped_size(Encoded,Items,Items);
match_encoded_map(_,_,_) -> no_match_size.
-match_encoded_map(<<>>,[]) -> ok;
-match_encoded_map(Bin,[<<131,Item/binary>>|Items]) ->
- Size = erlang:byte_size(Item),
- <<EncodedTerm:Size/binary, Bin1/binary>> = Bin,
- EncodedTerm = Item, %% Asssert
- match_encoded_map(Bin1,Items).
+match_encoded_map_stripped_size(<<>>,_,_) -> ok;
+match_encoded_map_stripped_size(B0,[{<<131,K/binary>>,<<131,V/binary>>}|Items],Ls) ->
+ Ksz = byte_size(K),
+ Vsz = byte_size(V),
+ case B0 of
+ <<K:Ksz/binary,V:Vsz/binary,B1/binary>> ->
+ match_encoded_map_stripped_size(B1,Ls,Ls);
+ _ ->
+ match_encoded_map_stripped_size(B0,Items,Ls)
+ end;
+match_encoded_map_stripped_size(_,[],_) -> fail.
t_bif_map_to_list(Config) when is_list(Config) ->
[] = maps:to_list(#{}),
- [{a,1},{b,2}] = maps:to_list(#{a=>1,b=>2}),
- [{a,1},{b,2},{c,3}] = maps:to_list(#{c=>3,a=>1,b=>2}),
- [{a,1},{b,2},{g,3}] = maps:to_list(#{g=>3,a=>1,b=>2}),
- [{a,1},{b,2},{g,3},{"c",4}] = maps:to_list(#{g=>3,a=>1,b=>2,"c"=>4}),
- [{3,v2},{hi,v4},{{hi,3},v5},{"hi",v3},{<<"hi">>,v1}] = maps:to_list(#{
- <<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5}),
+ [{a,1},{b,2}] = lists:sort(maps:to_list(#{a=>1,b=>2})),
+ [{a,1},{b,2},{c,3}] = lists:sort(maps:to_list(#{c=>3,a=>1,b=>2})),
+ [{a,1},{b,2},{g,3}] = lists:sort(maps:to_list(#{g=>3,a=>1,b=>2})),
+ [{a,1},{b,2},{g,3},{"c",4}] = lists:sort(maps:to_list(#{g=>3,a=>1,b=>2,"c"=>4})),
+ [{3,v2},{hi,v4},{{hi,3},v5},{"hi",v3},{<<"hi">>,v1}] =
+ lists:sort(maps:to_list(#{<<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5})),
- [{3,v7},{hi,v9},{{hi,3},v10},{"hi",v8},{<<"hi">>,v6}] = maps:to_list(#{
- <<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5,
- <<"hi">>=>v6,3=>v7,"hi"=>v8,hi=>v9,{hi,3}=>v10}),
+ [{3,v7},{hi,v9},{{hi,3},v10},{"hi",v8},{<<"hi">>,v6}] =
+ lists:sort(maps:to_list(#{<<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5,
+ <<"hi">>=>v6,3=>v7,"hi"=>v8,hi=>v9,{hi,3}=>v10})),
%% error cases
- {'EXIT', {badarg,_}} = (catch maps:to_list(id(a))),
- {'EXIT', {badarg,_}} = (catch maps:to_list(id(42))),
+ do_badmap(fun(T) ->
+ {'EXIT', {{badmap,T},_}} =
+ (catch maps:to_list(T))
+ end),
ok.
@@ -903,7 +2328,7 @@ t_bif_map_from_list(Config) when is_list(Config) ->
A = maps:from_list([]),
0 = erlang:map_size(A),
- #{a:=1,b:=2} = maps:from_list([{a,1},{b,2}]),
+ #{a:=1,b:=2} = maps:from_list([{a,1},{b,2}]),
#{c:=3,a:=1,b:=2} = maps:from_list([{a,1},{b,2},{c,3}]),
#{g:=3,a:=1,b:=2} = maps:from_list([{a,1},{b,2},{g,3}]),
@@ -916,6 +2341,13 @@ t_bif_map_from_list(Config) when is_list(Config) ->
maps:from_list([ {{hi,3},v3}, {"hi",v0},{3,v1}, {<<"hi">>,v4}, {hi,v2},
{<<"hi">>,v6}, {{hi,3},v10},{"hi",v11}, {hi,v9}, {3,v8}]),
+ %% repeated keys (large -> small)
+ Ps1 = [{a,I}|| I <- lists:seq(1,32)],
+ Ps2 = [{a,I}|| I <- lists:seq(33,64)],
+
+ M = maps:from_list(Ps1 ++ [{b,1},{c,1}] ++ Ps2),
+ #{ a := 64, b := 1, c := 1 } = M,
+
%% error cases
{'EXIT', {badarg,_}} = (catch maps:from_list(id([{a,b},b]))),
{'EXIT', {badarg,_}} = (catch maps:from_list(id([{a,b},{b,b,3}]))),
@@ -925,6 +2357,184 @@ t_bif_map_from_list(Config) when is_list(Config) ->
{'EXIT', {badarg,_}} = (catch maps:from_list(id(42))),
ok.
+t_bif_build_and_check(Config) when is_list(Config) ->
+ ok = check_build_and_remove(750,[
+ fun(K) -> [K,K] end,
+ fun(K) -> [float(K),K] end,
+ fun(K) -> K end,
+ fun(K) -> {1,K} end,
+ fun(K) -> {K} end,
+ fun(K) -> [K|K] end,
+ fun(K) -> [K,1,2,3,4] end,
+ fun(K) -> {K,atom} end,
+ fun(K) -> float(K) end,
+ fun(K) -> integer_to_list(K) end,
+ fun(K) -> list_to_atom(integer_to_list(K)) end,
+ fun(K) -> [K,{K,[K,{K,[K]}]}] end,
+ fun(K) -> <<K:32>> end
+ ]),
+
+ ok.
+
+check_build_and_remove(_,[]) -> ok;
+check_build_and_remove(N,[F|Fs]) ->
+ {M,Ks} = build_and_check(N, maps:new(), F, []),
+ ok = remove_and_check(Ks,M),
+ check_build_and_remove(N,Fs).
+
+build_and_check(0, M0, _, Ks) -> {M0, Ks};
+build_and_check(N, M0, F, Ks) ->
+ K = build_key(F,N),
+ M1 = maps:put(K,K,M0),
+ ok = check_keys_exist([I||{I,_} <- [{K,M1}|Ks]], M1),
+ M2 = maps:update(K,v,M1),
+ v = maps:get(K,M2),
+ build_and_check(N-1,M1,F,[{K,M1}|Ks]).
+
+remove_and_check([],_) -> ok;
+remove_and_check([{K,Mc}|Ks], M0) ->
+ K = maps:get(K,M0),
+ true = maps:is_key(K,M0),
+ true = Mc =:= M0,
+ true = M0 == Mc,
+ M1 = maps:remove(K,M0),
+ false = M1 =:= Mc,
+ false = Mc == M1,
+ false = maps:is_key(K,M1),
+ true = maps:is_key(K,M0),
+ ok = check_keys_exist([I||{I,_} <- Ks],M1),
+ error = maps:find(K,M1),
+ remove_and_check(Ks, M1).
+
+build_key(F,N) when N rem 3 =:= 0 -> F(N);
+build_key(F,N) when N rem 3 =:= 1 -> K = F(N), {K,K};
+build_key(F,N) when N rem 3 =:= 2 -> K = F(N), [K,K].
+
+check_keys_exist([], _) -> ok;
+check_keys_exist([K|Ks],M) ->
+ true = maps:is_key(K,M),
+ check_keys_exist(Ks,M).
+
+t_bif_merge_and_check(Config) when is_list(Config) ->
+
+ io:format("rand:export_seed() -> ~p\n",[rand:export_seed()]),
+
+ %% simple disjunct ones
+ %% make sure all keys are unique
+ Kss = [[a,b,c,d],
+ [1,2,3,4],
+ [],
+ ["hi"],
+ [e],
+ [build_key(fun(K) -> {small,K} end, I) || I <- lists:seq(1,32)],
+ lists:seq(5, 28),
+ lists:seq(29, 59),
+ [build_key(fun(K) -> integer_to_list(K) end, I) || I <- lists:seq(2000,10000)],
+ [build_key(fun(K) -> <<K:32>> end, I) || I <- lists:seq(1,80)],
+ [build_key(fun(K) -> {<<K:32>>} end, I) || I <- lists:seq(100,1000)]],
+
+
+ KsMs = build_keys_map_pairs(Kss),
+ Cs = [{CKs1,CM1,CKs2,CM2} || {CKs1,CM1} <- KsMs, {CKs2,CM2} <- KsMs],
+ ok = merge_and_check_combo(Cs),
+
+ %% overlapping ones
+
+ KVs1 = [{a,1},{b,2},{c,3}],
+ KVs2 = [{b,3},{c,4},{d,5}],
+ KVs = [{I,I} || I <- lists:seq(1,32)],
+ KVs3 = KVs1 ++ KVs,
+ KVs4 = KVs2 ++ KVs,
+
+ M1 = maps:from_list(KVs1),
+ M2 = maps:from_list(KVs2),
+ M3 = maps:from_list(KVs3),
+ M4 = maps:from_list(KVs4),
+
+ M12 = maps:merge(M1,M2),
+ ok = check_key_values(KVs2 ++ [{a,1}], M12),
+ M21 = maps:merge(M2,M1),
+ ok = check_key_values(KVs1 ++ [{d,5}], M21),
+
+ M34 = maps:merge(M3,M4),
+ ok = check_key_values(KVs4 ++ [{a,1}], M34),
+ M43 = maps:merge(M4,M3),
+ ok = check_key_values(KVs3 ++ [{d,5}], M43),
+
+ M14 = maps:merge(M1,M4),
+ ok = check_key_values(KVs4 ++ [{a,1}], M14),
+ M41 = maps:merge(M4,M1),
+ ok = check_key_values(KVs1 ++ [{d,5}] ++ KVs, M41),
+
+ [begin Ma = random_map(SzA, a),
+ Mb = random_map(SzB, b),
+ ok = merge_maps(Ma, Mb)
+ end || SzA <- [3,10,20,100,200,1000], SzB <- [3,10,20,100,200,1000]],
+
+ ok.
+
+% Generate random map with an average of Sz number of pairs: K -> {V,K}
+random_map(Sz, V) ->
+ random_map_insert(#{}, 0, V, Sz*2).
+
+random_map_insert(M0, K0, _, Sz) when K0 > Sz ->
+ M0;
+random_map_insert(M0, K0, V, Sz) ->
+ Key = K0 + rand:uniform(3),
+ random_map_insert(M0#{Key => {V,Key}}, Key, V, Sz).
+
+
+merge_maps(A, B) ->
+ AB = maps:merge(A, B),
+ %%io:format("A=~p\nB=~p\n",[A,B]),
+ maps_foreach(fun(K,VB) -> VB = maps:get(K, AB)
+ end, B),
+ maps_foreach(fun(K,VA) ->
+ case {maps:get(K, AB),maps:find(K, B)} of
+ {VA, error} -> ok;
+ {VB, {ok, VB}} -> ok
+ end
+ end, A),
+
+ maps_foreach(fun(K,V) ->
+ case {maps:find(K, A),maps:find(K, B)} of
+ {{ok, V}, error} -> ok;
+ {error, {ok, V}} -> ok;
+ {{ok,_}, {ok, V}} -> ok
+ end
+ end, AB),
+ ok.
+
+maps_foreach(Fun, Map) ->
+ maps:fold(fun(K,V,_) -> Fun(K,V) end, void, Map).
+
+
+check_key_values([],_) -> ok;
+check_key_values([{K,V}|KVs],M) ->
+ V = maps:get(K,M),
+ check_key_values(KVs,M).
+
+merge_and_check_combo([]) -> ok;
+merge_and_check_combo([{Ks1,M1,Ks2,M2}|Cs]) ->
+ M12 = maps:merge(M1,M2),
+ ok = check_keys_exist(Ks1 ++ Ks2, M12),
+ M21 = maps:merge(M2,M1),
+ ok = check_keys_exist(Ks1 ++ Ks2, M21),
+
+ true = M12 =:= M21,
+ M12 = M21,
+
+ merge_and_check_combo(Cs).
+
+build_keys_map_pairs([]) -> [];
+build_keys_map_pairs([Ks|Kss]) ->
+ M = maps:from_list(keys_to_pairs(Ks)),
+ ok = check_keys_exist(Ks, M),
+ [{Ks,M}|build_keys_map_pairs(Kss)].
+
+keys_to_pairs(Ks) -> [{K,K} || K <- Ks].
+
+
%% Maps module, not BIFs
t_maps_fold(_Config) ->
Vs = lists:seq(1,100),
@@ -963,6 +2573,74 @@ t_maps_without(_Config) ->
%% MISC
+%% Verify that the the number of nodes in hashmaps
+%% of different types and sizes does not deviate too
+%% much from the theoretical model.
+t_hashmap_balance(_Config) ->
+ io:format("Integer keys\n", []),
+ hashmap_balance(fun(I) -> I end),
+ io:format("Float keys\n", []),
+ hashmap_balance(fun(I) -> float(I) end),
+ io:format("String keys\n", []),
+ hashmap_balance(fun(I) -> integer_to_list(I) end),
+ io:format("Binary (big) keys\n", []),
+ hashmap_balance(fun(I) -> <<I:16/big>> end),
+ io:format("Binary (little) keys\n", []),
+ hashmap_balance(fun(I) -> <<I:16/little>> end),
+ io:format("Atom keys\n", []),
+ erts_debug:set_internal_state(available_internal_state, true),
+ hashmap_balance(fun(I) -> erts_debug:get_internal_state({atom,I}) end),
+ erts_debug:set_internal_state(available_internal_state, false),
+
+ ok.
+
+hashmap_balance(KeyFun) ->
+ F = fun(I, {M0,Max0}) ->
+ Key = KeyFun(I),
+ M1 = M0#{Key => Key},
+ Max1 = case erts_internal:map_type(M1) of
+ hashmap ->
+ Nodes = hashmap_nodes(M1),
+ Avg = maps:size(M1) * 0.4,
+ StdDev = math:sqrt(maps:size(M1)) / 3,
+ SD_diff = abs(Nodes - Avg) / StdDev,
+ %%io:format("~p keys: ~p nodes avg=~p SD_diff=~p\n",
+ %% [maps:size(M1), Nodes, Avg, SD_diff]),
+ {MaxDiff0, _} = Max0,
+ case {Nodes > Avg, SD_diff > MaxDiff0} of
+ {true, true} -> {SD_diff, M1};
+ _ -> Max0
+ end;
+
+ flatmap -> Max0
+ end,
+ {M1, Max1}
+ end,
+
+ {_,{MaxDiff,MaxMap}} = lists:foldl(F,
+ {#{}, {0, 0}},
+ lists:seq(1,10000)),
+ io:format("Max std dev diff ~p for map of size ~p (nodes=~p, flatsize=~p)\n",
+ [MaxDiff, maps:size(MaxMap), hashmap_nodes(MaxMap), erts_debug:flat_size(MaxMap)]),
+
+ true = (MaxDiff < 6), % The probability of this line failing is about 0.000000001
+ % for a uniform hash. I've set the probability this "high" for now
+ % to detect flaws in our make_internal_hash.
+ % Hard limit is 15 (see hashmap_over_estimated_heap_size).
+ ok.
+
+hashmap_nodes(M) ->
+ Info = erts_debug:map_info(M),
+ lists:foldl(fun(Tpl,Acc) ->
+ case element(1,Tpl) of
+ bitmaps -> Acc + element(2,Tpl);
+ arrays -> Acc + element(2,Tpl);
+ _ -> Acc
+ end
+ end,
+ 0,
+ Info).
+
t_erts_internal_order(_Config) when is_list(_Config) ->
-1 = erts_internal:cmp_term(1,2),
@@ -1004,6 +2682,80 @@ t_erts_internal_order(_Config) when is_list(_Config) ->
1 = maps:get(0,M1),
ok.
+t_erts_internal_hash(_Config) when is_list(_Config) ->
+ K1 = 0.0,
+ K2 = 0.0/-1,
+ M = maps:from_list([{I,I}||I<-lists:seq(1,32)]),
+
+ M1 = M#{ K1 => a, K2 => b },
+ b = maps:get(K2,M1),
+
+ M2 = M#{ K2 => a, K1 => b },
+ b = maps:get(K1,M2),
+
+ %% test previously faulty hash list optimization
+
+ M3 = M#{[0] => a, [0,0] => b, [0,0,0] => c, [0,0,0,0] => d},
+ a = maps:get([0],M3),
+ b = maps:get([0,0],M3),
+ c = maps:get([0,0,0],M3),
+ d = maps:get([0,0,0,0],M3),
+
+ M4 = M#{{[0]} => a, {[0,0]} => b, {[0,0,0]} => c, {[0,0,0,0]} => d},
+ a = maps:get({[0]},M4),
+ b = maps:get({[0,0]},M4),
+ c = maps:get({[0,0,0]},M4),
+ d = maps:get({[0,0,0,0]},M4),
+
+ M5 = M3#{[0,0,0] => e, [0,0,0,0] => f, [0,0,0,0,0] => g,
+ [0,0,0,0,0,0] => h, [0,0,0,0,0,0,0] => i,
+ [0,0,0,0,0,0,0,0] => j, [0,0,0,0,0,0,0,0,0] => k},
+
+ a = maps:get([0],M5),
+ b = maps:get([0,0],M5),
+ e = maps:get([0,0,0],M5),
+ f = maps:get([0,0,0,0],M5),
+ g = maps:get([0,0,0,0,0],M5),
+ h = maps:get([0,0,0,0,0,0],M5),
+ i = maps:get([0,0,0,0,0,0,0],M5),
+ j = maps:get([0,0,0,0,0,0,0,0],M5),
+ k = maps:get([0,0,0,0,0,0,0,0,0],M5),
+
+ M6 = M4#{{[0,0,0]} => e, {[0,0,0,0]} => f, {[0,0,0,0,0]} => g,
+ {[0,0,0,0,0,0]} => h, {[0,0,0,0,0,0,0]} => i,
+ {[0,0,0,0,0,0,0,0]} => j, {[0,0,0,0,0,0,0,0,0]} => k},
+
+ a = maps:get({[0]},M6),
+ b = maps:get({[0,0]},M6),
+ e = maps:get({[0,0,0]},M6),
+ f = maps:get({[0,0,0,0]},M6),
+ g = maps:get({[0,0,0,0,0]},M6),
+ h = maps:get({[0,0,0,0,0,0]},M6),
+ i = maps:get({[0,0,0,0,0,0,0]},M6),
+ j = maps:get({[0,0,0,0,0,0,0,0]},M6),
+ k = maps:get({[0,0,0,0,0,0,0,0,0]},M6),
+
+ M7 = maps:merge(M5,M6),
+
+ a = maps:get([0],M7),
+ b = maps:get([0,0],M7),
+ e = maps:get([0,0,0],M7),
+ f = maps:get([0,0,0,0],M7),
+ g = maps:get([0,0,0,0,0],M7),
+ h = maps:get([0,0,0,0,0,0],M7),
+ i = maps:get([0,0,0,0,0,0,0],M7),
+ j = maps:get([0,0,0,0,0,0,0,0],M7),
+ k = maps:get([0,0,0,0,0,0,0,0,0],M7),
+ a = maps:get({[0]},M7),
+ b = maps:get({[0,0]},M7),
+ e = maps:get({[0,0,0]},M7),
+ f = maps:get({[0,0,0,0]},M7),
+ g = maps:get({[0,0,0,0,0]},M7),
+ h = maps:get({[0,0,0,0,0,0]},M7),
+ i = maps:get({[0,0,0,0,0,0,0]},M7),
+ j = maps:get({[0,0,0,0,0,0,0,0]},M7),
+ k = maps:get({[0,0,0,0,0,0,0,0,0]},M7),
+ ok.
t_pdict(_Config) ->
@@ -1131,5 +2883,297 @@ trace_collector(Msg,Parent) ->
Parent ! Msg,
Parent.
+t_has_map_fields(Config) when is_list(Config) ->
+ true = has_map_fields_1(#{one=>1}),
+ true = has_map_fields_1(#{one=>1,two=>2}),
+ false = has_map_fields_1(#{two=>2}),
+ false = has_map_fields_1(#{}),
+
+ true = has_map_fields_2(#{c=>1,b=>2,a=>3}),
+ true = has_map_fields_2(#{c=>1,b=>2,a=>3,x=>42}),
+ false = has_map_fields_2(#{b=>2,c=>1}),
+ false = has_map_fields_2(#{x=>y}),
+ false = has_map_fields_2(#{}),
+
+ true = has_map_fields_3(#{c=>1,b=>2,a=>3}),
+ true = has_map_fields_3(#{c=>1,b=>2,a=>3,[]=>42}),
+ true = has_map_fields_3(#{b=>2,a=>3,[]=>42,42.0=>43}),
+ true = has_map_fields_3(#{a=>3,[]=>42,42.0=>43}),
+ true = has_map_fields_3(#{[]=>42,42.0=>43}),
+ false = has_map_fields_3(#{b=>2,c=>1}),
+ false = has_map_fields_3(#{[]=>y}),
+ false = has_map_fields_3(#{42.0=>x,a=>99}),
+ false = has_map_fields_3(#{}),
+
+ ok.
+
+has_map_fields_1(#{one:=_}) -> true;
+has_map_fields_1(#{}) -> false.
+
+has_map_fields_2(#{a:=_,b:=_,c:=_}) -> true;
+has_map_fields_2(#{}) -> false.
+
+has_map_fields_3(#{a:=_,b:=_}) -> true;
+has_map_fields_3(#{[]:=_,42.0:=_}) -> true;
+has_map_fields_3(#{}) -> false.
+
+y_regs(Config) when is_list(Config) ->
+ Val = [length(Config)],
+ Map0 = y_regs_update(#{}, Val),
+ Map2 = y_regs_update(Map0, Val),
+
+ Map3 = maps:from_list([{I,I*I} || I <- lists:seq(1, 100)]),
+ Map4 = y_regs_update(Map3, Val),
+
+ true = is_map(Map2) andalso is_map(Map4),
+
+ ok.
+
+y_regs_update(Map0, Val0) ->
+ Val1 = {t,Val0},
+ K1 = id({key,1}),
+ K2 = id({key,2}),
+ Map1 = Map0#{K1=>K1,
+ a=>Val0,b=>Val0,c=>Val0,d=>Val0,e=>Val0,
+ f=>Val0,g=>Val0,h=>Val0,i=>Val0,j=>Val0,
+ k=>Val0,l=>Val0,m=>Val0,n=>Val0,o=>Val0,
+ p=>Val0,q=>Val0,r=>Val0,s=>Val0,t=>Val0,
+ u=>Val0,v=>Val0,w=>Val0,x=>Val0,y=>Val0,
+ z=>Val0,
+ aa=>Val0,ab=>Val0,ac=>Val0,ad=>Val0,ae=>Val0,
+ af=>Val0,ag=>Val0,ah=>Val0,ai=>Val0,aj=>Val0,
+ ak=>Val0,al=>Val0,am=>Val0,an=>Val0,ao=>Val0,
+ ap=>Val0,aq=>Val0,ar=>Val0,as=>Val0,at=>Val0,
+ au=>Val0,av=>Val0,aw=>Val0,ax=>Val0,ay=>Val0,
+ az=>Val0,
+ K2=>[a,b,c]},
+ Map2 = Map1#{K1=>K1,
+ a:=Val1,b:=Val1,c:=Val1,d:=Val1,e:=Val1,
+ f:=Val1,g:=Val1,h:=Val1,i:=Val1,j:=Val1,
+ k:=Val1,l:=Val1,m:=Val1,n:=Val1,o:=Val1,
+ p:=Val1,q:=Val1,r:=Val1,s:=Val1,t:=Val1,
+ u:=Val1,v:=Val1,w:=Val1,x:=Val1,y:=Val1,
+ z:=Val1,
+ aa:=Val1,ab:=Val1,ac:=Val1,ad:=Val1,ae:=Val1,
+ af:=Val1,ag:=Val1,ah:=Val1,ai:=Val1,aj:=Val1,
+ ak:=Val1,al:=Val1,am:=Val1,an:=Val1,ao:=Val1,
+ ap:=Val1,aq:=Val1,ar:=Val1,as:=Val1,at:=Val1,
+ au:=Val1,av:=Val1,aw:=Val1,ax:=Val1,ay:=Val1,
+ az:=Val1,
+ K2=>[a,b,c]},
+
+ %% Traverse the maps to validate them.
+ _ = erlang:phash2({Map1,Map2}, 100000),
+
+ _ = id({K1,K2,Val0,Val1}), %Force use of Y registers.
+ Map2.
+
+do_badmap(Test) ->
+ Terms = [Test,fun erlang:abs/1,make_ref(),self(),0.0/id(-1),
+ <<0:1024>>,<<1:1>>,<<>>,<<1,2,3>>,
+ [],{a,b,c},[a,b],atom,10.0,42,(1 bsl 65) + 3],
+ [Test(T) || T <- Terms].
+
+%% Test that a module compiled with the OTP 17 compiler will
+%% generate the correct 'badmap' exception.
+badmap_17(Config) ->
+ case ?MODULE of
+ map_SUITE -> do_badmap_17(Config);
+ _ -> {skip,"Run in map_SUITE"}
+ end.
+
+do_badmap_17(Config) ->
+ Mod = badmap_17,
+ DataDir = test_server:lookup_config(data_dir, Config),
+ Beam = filename:join(DataDir, Mod),
+ {module,Mod} = code:load_abs(Beam),
+ do_badmap(fun Mod:update/1).
+
%% Use this function to avoid compile-time evaluation of an expression.
id(I) -> I.
+
+
+%% OTP-13146
+%% Provoke major GC with a lot of "fat" maps on external format in msg queue
+%% causing heap fragments to be allocated.
+t_gc_rare_map_overflow(Config) ->
+ Pa = filename:dirname(code:which(?MODULE)),
+ {ok, Node} = test_server:start_node(gc_rare_map_overflow, slave, [{args, "-pa \""++Pa++"\""}]),
+ erts_debug:set_internal_state(available_internal_state, true),
+ try
+ Echo = spawn_link(Node, fun Loop() -> receive {From,Msg} -> From ! Msg
+ end,
+ Loop()
+ end),
+ FatMap = fatmap(34),
+ false = (flatmap =:= erts_internal:map_type(FatMap)),
+
+ t_gc_rare_map_overflow_do(Echo, FatMap, fun() -> erlang:garbage_collect() end),
+
+ %% Repeat test for minor gc:
+ t_gc_rare_map_overflow_do(Echo, FatMap, fun() -> minor_collect() end),
+
+ unlink(Echo),
+
+ %% Test fatmap in exit signal
+ Exiter = spawn_link(Node, fun Loop() -> receive {From,Msg} ->
+ "not_a_map" = Msg % badmatch!
+ end,
+ Loop()
+ end),
+ process_flag(trap_exit, true),
+ Exiter ! {self(), FatMap},
+ {'EXIT', Exiter, {{badmatch,FatMap}, _}} = receive M -> M end,
+ ok
+
+ after
+ process_flag(trap_exit, false),
+ erts_debug:set_internal_state(available_internal_state, false),
+ test_server:stop_node(Node)
+ end.
+
+t_gc_rare_map_overflow_do(Echo, FatMap, GcFun) ->
+ Master = self(),
+ true = receive M -> false after 0 -> true end, % assert empty msg queue
+ Echo ! {Master, token},
+ repeat(1000, fun(_) -> Echo ! {Master, FatMap} end, void),
+
+ timer:sleep(100), % Wait for maps to arrive in our msg queue
+ token = receive Tok -> Tok end, % and provoke move from outer to inner msg queue
+
+ %% Do GC that will "overflow" and create heap frags due to all the fat maps
+ GcFun(),
+
+ %% Now check that all maps in msg queueu are intact
+ %% Will crash emulator in OTP-18.1
+ repeat(1000, fun(_) -> FatMap = receive FM -> FM end end, void),
+ ok.
+
+minor_collect() ->
+ Before = minor_gcs(),
+ erts_debug:set_internal_state(force_gc, self()),
+ erlang:yield(),
+ After = minor_gcs(),
+ io:format("minor_gcs: ~p -> ~p\n", [Before, After]).
+
+minor_gcs() ->
+ {garbage_collection, Info} = process_info(self(), garbage_collection),
+ {minor_gcs, GCS} = lists:keyfind(minor_gcs, 1, Info),
+ GCS.
+
+%% Generate a map with N (or N+1) keys that has an abnormal heap demand.
+%% Done by finding keys that collide in the first 32-bit hash.
+fatmap(N) ->
+ %%erts_debug:set_internal_state(available_internal_state, true),
+ Table = ets:new(void, [bag, private]),
+
+ Seed0 = rand:seed_s(exsplus, {4711, 3141592, 2718281}),
+ Seed1 = fatmap_populate(Table, Seed0, (1 bsl 16)),
+ Keys = fatmap_generate(Table, Seed1, N, []),
+ ets:delete(Table),
+ maps:from_list([{K,K} || K <- Keys]).
+
+fatmap_populate(_, Seed, 0) -> Seed;
+fatmap_populate(Table, Seed, N) ->
+ {I, NextSeed} = rand:uniform_s(1 bsl 48, Seed),
+ Hash = internal_hash(I),
+ ets:insert(Table, [{Hash, I}]),
+ fatmap_populate(Table, NextSeed, N-1).
+
+
+fatmap_generate(_, _, N, Acc) when N =< 0 ->
+ Acc;
+fatmap_generate(Table, Seed, N0, Acc0) ->
+ {I, NextSeed} = rand:uniform_s(1 bsl 48, Seed),
+ Hash = internal_hash(I),
+ case ets:member(Table, Hash) of
+ true ->
+ NewKeys = [I | ets:lookup_element(Table, Hash, 2)],
+ Acc1 = lists:usort(Acc0 ++ NewKeys),
+ N1 = N0 - (length(Acc1) - length(Acc0)),
+ fatmap_generate(Table, NextSeed, N1, Acc1);
+ false ->
+ fatmap_generate(Table, NextSeed, N0, Acc0)
+ end.
+
+internal_hash(Term) ->
+ erts_debug:get_internal_state({internal_hash, Term}).
+
+
+%% map external_format (fannerl).
+fannerl() ->
+ <<131,116,0,0,0,28,100,0,13,108,101,97,114,110,105,110,103,95,114,
+ 97,116,101,70,63,230,102,102,96,0,0,0,100,0,17,108,101,97,114,110,105,110,
+ 103,95,109,111,109,101,110,116,117,109,70,0,0,0,0,0,0,0,0,100,0,
+ 18,116,114,97,105,110,105,110,103,95,97,108,103,111,114,105,116,104,109,100,0,
+ 16,102,97,110,110,95,116,114,97,105,110,95,114,112,114,111,112,
+ 100,0,17,109,101,97,110,95,115,113,117,97,114,101,95,101,114,114,111,114,70,
+ 0,0,0,0,0,0,0,0,100,0,8,98,105,116,95,102,97,105,108,97,0,100,0,20,
+ 116,114,97,105,110,95,101,114,114,111,114,95,102,117,110,99,116,105,111,
+ 110,100,0,19,102,97,110,110,95,101,114,114,111,114,102,117,110,99,
+ 95,116,97,110,104,100,0,9,110,117,109,95,105,110,112,117,116,97,5,100,0,10,110,
+ 117,109,95,111,117,116,112,117,116,97,3,100,0,13,116,111,116,97,108,
+ 95,110,101,117,114,111,110,115,97,17,100,0,17,116,111,116,97,108,95,99,111,110,
+ 110,101,99,116,105,111,110,115,97,66,100,0,12,110,101,116,119,111,114,107,
+ 95,116,121,112,101,100,0,18,102,97,110,110,95,110,101,116,116,121,112,101,
+ 95,108,97,121,101,114,100,0,15,99,111,110,110,101,99,116,105,111,110,95,
+ 114,97,116,101,70,63,240,0,0,0,0,0,0,100,0,10,110,117,109,95,108,97,121,101,
+ 114,115,97,3,100,0,19,116,114,97,105,110,95,115,116,111,112,95,102,117,110,
+ 99,116,105,111,110,100,0,17,102,97,110,110,95,115,116,111,112,102,117,110,
+ 99,95,109,115,101,100,0,15,113,117,105,99,107,112,114,111,112,95,100,101,99,
+ 97,121,70,191,26,54,226,224,0,0,0,100,0,12,113,117,105,99,107,112,114,
+ 111,112,95,109,117,70,63,252,0,0,0,0,0,0,100,0,21,114,112,114,111,112,95,105,
+ 110,99,114,101,97,115,101,95,102,97,99,116,111,114,70,63,243,51,51,
+ 64,0,0,0,100,0,21,114,112,114,111,112,95,100,101,99,114,101,97,115,101,
+ 95,102,97,99,116,111,114,70,63,224,0,0,0,0,0,0,100,0,15,114,112,114,111,112,
+ 95,100,101,108,116,97,95,109,105,110,70,0,0,0,0,0,0,0,0,100,0,15,114,112,114,
+ 111,112,95,100,101,108,116,97,95,109,97,120,70,64,73,0,0,0,0,0,0,100,0,
+ 16,114,112,114,111,112,95,100,101,108,116,97,95,122,101,114,111,70,63,185,153,
+ 153,160,0,0,0,100,0,26,115,97,114,112,114,111,112,95,119,101,105,103,
+ 104,116,95,100,101,99,97,121,95,115,104,105,102,116,70,192,26,147,116,192,0,0,0,
+ 100,0,35,115,97,114,112,114,111,112,95,115,116,101,112,95,101,114,
+ 114,111,114,95,116,104,114,101,115,104,111,108,100,95,102,97,99,116,111,114,70,
+ 63,185,153,153,160,0,0,0,100,0,24,115,97,114,112,114,111,112,95,115,
+ 116,101,112,95,101,114,114,111,114,95,115,104,105,102,116,70,63,246,40,245,
+ 192,0,0,0,100,0,19,115,97,114,112,114,111,112,95,116,101,109,112,101,114,
+ 97,116,117,114,101,70,63,142,184,81,224,0,0,0,100,0,6,108,97,121,101,114,115,
+ 104,3,97,5,97,7,97,3,100,0,4,98,105,97,115,104,3,97,1,97,1,97,0,100,0,11,
+ 99,111,110,110,101,99,116,105,111,110,115,116,0,0,0,66,104,2,97,0,97,6,70,
+ 191,179,51,44,64,0,0,0,104,2,97,1,97,6,70,63,178,130,90,32,0,0,0,104,2,97,2,
+ 97,6,70,63,82,90,88,0,0,0,0,104,2,97,3,97,6,70,63,162,91,63,192,0,0,0,104,2,
+ 97,4,97,6,70,191,151,70,169,0,0,0,0,104,2,97,5,97,6,70,191,117,52,222,0,0,0,
+ 0,104,2,97,0,97,7,70,63,152,240,139,0,0,0,0,104,2,97,1,97,7,70,191,166,31,
+ 187,160,0,0,0,104,2,97,2,97,7,70,191,150,70,63,0,0,0,0,104,2,97,3,97,7,70,
+ 63,152,181,126,128,0,0,0,104,2,97,4,97,7,70,63,151,187,162,128,0,0,0,104,2,
+ 97,5,97,7,70,191,143,161,101,0,0,0,0,104,2,97,0,97,8,70,191,153,102,36,128,0,
+ 0,0,104,2,97,1,97,8,70,63,160,139,250,64,0,0,0,104,2,97,2,97,8,70,63,164,62,
+ 196,64,0,0,0,104,2,97,3,97,8,70,191,178,78,209,192,0,0,0,104,2,97,4,97,8,70,
+ 191,185,19,76,224,0,0,0,104,2,97,5,97,8,70,63,183,142,196,96,0,0,0,104,2,97,0,
+ 97,9,70,63,150,104,248,0,0,0,0,104,2,97,1,97,9,70,191,164,4,100,224,0,0,0,
+ 104,2,97,2,97,9,70,191,169,42,42,224,0,0,0,104,2,97,3,97,9,70,63,145,54,78,128,0,
+ 0,0,104,2,97,4,97,9,70,63,126,243,134,0,0,0,0,104,2,97,5,97,9,70,63,177,
+ 203,25,96,0,0,0,104,2,97,0,97,10,70,63,172,104,47,64,0,0,0,104,2,97,1,97,10,
+ 70,63,161,242,193,64,0,0,0,104,2,97,2,97,10,70,63,175,208,241,192,0,0,0,104,2,
+ 97,3,97,10,70,191,129,202,161,0,0,0,0,104,2,97,4,97,10,70,63,178,151,55,32,0,0,0,
+ 104,2,97,5,97,10,70,63,137,155,94,0,0,0,0,104,2,97,0,97,11,70,191,179,
+ 106,160,0,0,0,0,104,2,97,1,97,11,70,63,184,253,164,96,0,0,0,104,2,97,2,97,11,
+ 70,191,143,30,157,0,0,0,0,104,2,97,3,97,11,70,63,153,225,140,128,0,0,0,104,
+ 2,97,4,97,11,70,63,161,35,85,192,0,0,0,104,2,97,5,97,11,70,63,175,200,55,192,
+ 0,0,0,104,2,97,0,97,12,70,191,180,116,132,96,0,0,0,104,2,97,1,97,12,70,191,
+ 165,151,152,0,0,0,0,104,2,97,2,97,12,70,191,180,197,91,160,0,0,0,104,2,97,3,97,12,
+ 70,191,91,30,160,0,0,0,0,104,2,97,4,97,12,70,63,180,251,45,32,0,0,0,
+ 104,2,97,5,97,12,70,63,165,134,77,64,0,0,0,104,2,97,6,97,14,70,63,181,56,242,96,
+ 0,0,0,104,2,97,7,97,14,70,191,165,239,234,224,0,0,0,104,2,97,8,97,14,
+ 70,191,154,65,216,128,0,0,0,104,2,97,9,97,14,70,63,150,250,236,0,0,0,0,104,2,97,
+ 10,97,14,70,191,141,105,108,0,0,0,0,104,2,97,11,97,14,70,191,152,40,
+ 165,0,0,0,0,104,2,97,12,97,14,70,63,141,159,46,0,0,0,0,104,2,97,13,97,14,70,
+ 191,183,172,137,32,0,0,0,104,2,97,6,97,15,70,63,163,26,123,192,0,0,0,104,
+ 2,97,7,97,15,70,63,176,184,106,32,0,0,0,104,2,97,8,97,15,70,63,152,234,144,
+ 0,0,0,0,104,2,97,9,97,15,70,191,172,58,70,160,0,0,0,104,2,97,10,97,15,70,
+ 63,161,211,211,192,0,0,0,104,2,97,11,97,15,70,191,148,171,120,128,0,0,0,104,
+ 2,97,12,97,15,70,63,180,117,214,224,0,0,0,104,2,97,13,97,15,70,191,104,
+ 230,216,0,0,0,0,104,2,97,6,97,16,70,63,178,53,103,96,0,0,0,104,2,97,7,97,16,
+ 70,63,170,230,232,64,0,0,0,104,2,97,8,97,16,70,191,183,45,100,192,0,0,0,
+ 104,2,97,9,97,16,70,63,184,100,97,32,0,0,0,104,2,97,10,97,16,70,63,169,174,
+ 254,64,0,0,0,104,2,97,11,97,16,70,191,119,121,234,0,0,0,0,104,2,97,12,97,
+ 16,70,63,149,12,170,128,0,0,0,104,2,97,13,97,16,70,191,144,193,191,0,0,0,0>>.
diff --git a/erts/emulator/test/map_SUITE_data/badmap_17.beam b/erts/emulator/test/map_SUITE_data/badmap_17.beam
new file mode 100644
index 0000000000..277fc34b94
--- /dev/null
+++ b/erts/emulator/test/map_SUITE_data/badmap_17.beam
Binary files differ
diff --git a/erts/emulator/test/map_SUITE_data/badmap_17.erl b/erts/emulator/test/map_SUITE_data/badmap_17.erl
new file mode 100644
index 0000000000..0ec65e0e33
--- /dev/null
+++ b/erts/emulator/test/map_SUITE_data/badmap_17.erl
@@ -0,0 +1,26 @@
+-module(badmap_17).
+-export([update/1]).
+
+%% Compile this source file with OTP 17.
+
+update(Map) ->
+ try
+ update_1(Map),
+ error(update_did_not_fail)
+ catch
+ error:{badmap,Map} ->
+ ok
+ end,
+ try
+ update_2(Map),
+ error(update_did_not_fail)
+ catch
+ error:{badmap,Map} ->
+ ok
+ end.
+
+update_1(M) ->
+ M#{a=>42}.
+
+update_2(M) ->
+ M#{a:=42}.
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index fdce157abc..3f986ca2ed 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -30,6 +31,7 @@
-export([fpe/1]).
-export([otp_9422/1]).
-export([faulty_seq_trace/1, do_faulty_seq_trace/0]).
+-export([maps/1]).
-export([runner/2, loop_runner/3]).
-export([f1/1, f2/2, f3/2, fn/1, fn/2, fn/3]).
-export([do_boxed_and_small/0]).
@@ -62,7 +64,8 @@ all() ->
moving_labels,
faulty_seq_trace,
empty_list,
- otp_9422];
+ otp_9422,
+ maps];
true -> [not_run]
end.
@@ -167,12 +170,11 @@ test_1(Config) when is_list(Config) ->
[{['$1','$1'],[{is_atom, '$1'}],[kakalorum]}],
[{call, {?MODULE, f2, [a, a]}}]),
-% case tr0(fun() -> ?MODULE:f2(a, a) end,
-% {?MODULE, f2, 2},
-% [{['$1','$1'],[{is_atom, '$1'}],[{message, {process_dump}}]}]) of
-% [{trace, _, call, {?MODULE, f2, [a, a]}, Bin}] ->
-% erlang:display(binary_to_list(Bin))
-% end,
+ %% Verify that 'process_dump' can handle a matchstate on the stack.
+ tr(fun() -> fbinmatch(<<0>>, 0) end,
+ {?MODULE, f1, 1},
+ [{['_'],[],[{message, {process_dump}}]}],
+ [fun({trace, _, call, {?MODULE, f1, [0]}, _Bin}) -> true end]),
% Error cases
?line errchk([{['$1','$1'],[{is_atom, '$1'}],[{banka, kanin}]}]),
@@ -899,6 +901,74 @@ fpe(Config) when is_list(Config) ->
_ -> ok
end.
+maps(Config) when is_list(Config) ->
+ {ok,#{},[],[]} = erlang:match_spec_test(#{}, [{'_',[],['$_']}], table),
+ {ok,#{},[],[]} = erlang:match_spec_test(#{}, [{#{},[],['$_']}], table),
+ {ok,false,[],[]} =
+ erlang:match_spec_test(#{}, [{not_a_map,[],['$_']}], table),
+ {ok,bar,[],[]} =
+ erlang:match_spec_test(#{foo => bar},
+ [{#{foo => '$1'},[],['$1']}],
+ table),
+ {ok,false,[],[]} =
+ erlang:match_spec_test(#{foo => bar},
+ [{#{foo => qux},[],[qux]}],
+ table),
+ {ok,false,[],[]} =
+ erlang:match_spec_test(#{}, [{#{foo => '_'},[],[foo]}], table),
+ {error,_} =
+ erlang:match_spec_test(#{}, [{#{'$1' => '_'},[],[foo]}], table),
+ {ok,bar,[],[]} =
+ erlang:match_spec_test({#{foo => bar}},
+ [{{#{foo => '$1'}},[],['$1']}],
+ table),
+ {ok,#{foo := 3},[],[]} =
+ erlang:match_spec_test({}, [{{},[],[#{foo => {'+',1,2}}]}], table),
+
+ {ok,"camembert",[],[]} =
+ erlang:match_spec_test(#{b => "camembert",c => "cabécou"},
+ [{#{b => '$1',c => "cabécou"},[],['$1']}], table),
+
+ {ok,#{a :="camembert",b := "hi"},[],[]} =
+ erlang:match_spec_test(#{<<"b">> =>"camembert","c"=>"cabécou", "wat"=>"hi", b=><<"other">>},
+ [{#{<<"b">> => '$1',"wat" => '$2'},[],[#{a=>'$1',b=>'$2'}]}],
+ table),
+ %% large maps
+
+ Ls0 = [{I,<<I:32>>}||I <- lists:seq(1,415)],
+ M0 = maps:from_list(Ls0),
+ M1 = #{a=>1,b=>2,c=>3,d=>4},
+
+ R1 = M0#{263 := #{ a=> 3 }},
+ Ms1 = [{M1#{c:='$1'},[],[M0#{263 := #{a => '$1'}}]}],
+
+ {ok,R1,[],[]} = erlang:match_spec_test(M1,Ms1,table),
+
+ Ms2 = [{M0#{63:='$1', 19:='$2'},[],[M0#{19:='$1', 63:='$2'}]}],
+ R2 = M0#{63 := maps:get(19,M0), 19 := maps:get(63,M0) },
+ {ok,R2,[],[]} = erlang:match_spec_test(M0,Ms2,table),
+
+ ok = maps_check_loop(M1),
+ ok = maps_check_loop(M0),
+ M2 = maps:from_list([{integer_to_list(K),V} || {K,V} <- Ls0]),
+ ok = maps_check_loop(M2),
+ ok.
+
+maps_check_loop(M) ->
+ Ks = maps:keys(M),
+ maps_check_loop(M,M,M,M,Ks,lists:reverse(Ks),1).
+
+maps_check_loop(Orig,M0,MsM0,Rm0,[K|Ks],[Rk|Rks],Ix) ->
+ MsK = list_to_atom([$$]++integer_to_list(Ix)),
+ MsM1 = MsM0#{K := MsK},
+ Rm1 = Rm0#{Rk := MsK},
+ M1 = M0#{Rk := maps:get(K,MsM0)},
+ Ms = [{MsM1,[],[Rm1]}],
+ {ok,M1,[],[]} = erlang:match_spec_test(Orig,Ms,table),
+ maps_check_loop(Orig,M1,MsM1,Rm1,Ks,Rks,Ix+1);
+maps_check_loop(_,_,_,_,[],[],_) -> ok.
+
+
empty_list(Config) when is_list(Config) ->
Val=[{'$1',[], [{message,'$1'},{message,{caller}},{return_trace}]}],
%% Did crash debug VM in faulty assert:
@@ -928,14 +998,14 @@ tr(Fun, MFA, TraceFlags, Pat, PatFlags, Expected0) ->
erlang:trace(P, true, TraceFlags),
erlang:trace_pattern(MFA, Pat, PatFlags),
lists:map(
- fun(X) ->
- list_to_tuple([trace, P | tuple_to_list(X)])
+ fun(X) when is_function(X,1) -> X;
+ (X) -> list_to_tuple([trace, P | tuple_to_list(X)])
end,
Expected0)
end).
tr(RunFun, ControlFun) ->
- P = spawn(?MODULE, runner, [self(), RunFun]),
+ P = spawn_link(?MODULE, runner, [self(), RunFun]),
collect(P, ControlFun(P)).
collect(P, TMs) ->
@@ -954,18 +1024,33 @@ collect([]) ->
collect([TM | TMs]) ->
?t:format( "Expecting: ~p~n", [TM]),
receive
- M ->
- case if element(1, M) == trace_ts ->
- list_to_tuple(lists:reverse(
- tl(lists:reverse(tuple_to_list(M)))));
- true -> M
- end of
- TM ->
- ?t:format("Got: ~p~n", [M]),
- collect(TMs);
- _ ->
- ?t:format("Got unexpected: ~p~n", [M]),
- flush({got_unexpected,M})
+ M0 ->
+ M = case element(1, M0) of
+ trace_ts ->
+ list_to_tuple(lists:reverse(
+ tl(lists:reverse(tuple_to_list(M0)))));
+ _ -> M0
+ end,
+ case is_function(TM,1) of
+ true ->
+ case (catch TM(M)) of
+ true ->
+ ?t:format("Got: ~p~n", [M]),
+ collect(TMs);
+ _ ->
+ ?t:format("Got unexpected: ~p~n", [M]),
+ flush({got_unexpected,M})
+ end;
+
+ false ->
+ case M of
+ TM ->
+ ?t:format("Got: ~p~n", [M]),
+ collect(TMs);
+ _ ->
+ ?t:format("Got unexpected: ~p~n", [M]),
+ flush({got_unexpected,M})
+ end
end
end.
@@ -1045,6 +1130,10 @@ fn(X, Y) ->
fn(X, Y, Z) ->
[X, Y, Z].
+fbinmatch(<<Int, Rest/binary>>, Acc) ->
+ fbinmatch(Rest, [?MODULE:f1(Int) | Acc]);
+fbinmatch(<<>>, Acc) -> Acc.
+
id(X) ->
X.
diff --git a/erts/emulator/test/module_info_SUITE.erl b/erts/emulator/test/module_info_SUITE.erl
index 8a63d9fe3e..7c2101ca05 100644
--- a/erts/emulator/test/module_info_SUITE.erl
+++ b/erts/emulator/test/module_info_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,7 +25,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- exports/1,functions/1,native/1]).
+ exports/1,functions/1,deleted/1,native/1,info/1]).
%%-compile(native).
@@ -51,9 +52,8 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-modules() ->
- [exports, functions, native].
+modules() ->
+ [exports, functions, deleted, native, info].
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(3)),
@@ -81,40 +81,66 @@ all_functions() ->
%% Test that the list of exported functions from this module is correct.
exports(Config) when is_list(Config) ->
- ?line All = all_exported(),
- ?line All = lists:sort(?MODULE:module_info(exports)),
- ?line (catch ?MODULE:foo()),
- ?line All = lists:sort(?MODULE:module_info(exports)),
+ All = all_exported(),
+ All = lists:sort(?MODULE:module_info(exports)),
+ (catch ?MODULE:foo()),
+ All = lists:sort(?MODULE:module_info(exports)),
ok.
%% Test that the list of exported functions from this module is correct.
functions(Config) when is_list(Config) ->
- ?line All = all_functions(),
- ?line All = lists:sort(?MODULE:module_info(functions)),
+ All = all_functions(),
+ All = lists:sort(?MODULE:module_info(functions)),
+ ok.
+
+%% Test that deleted modules cause badarg
+deleted(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ File = filename:join(Data, "module_info_test"),
+ {ok,module_info_test,Code} = compile:file(File, [binary]),
+ {module,module_info_test} = erlang:load_module(module_info_test, Code),
+ 17 = module_info_test:f(),
+ [_|_] = erlang:get_module_info(module_info_test, attributes),
+ [_|_] = erlang:get_module_info(module_info_test),
+
+ %% first delete it
+ true = erlang:delete_module(module_info_test),
+ {'EXIT',{undef, _}} = (catch module_info_test:f()),
+ {'EXIT',{badarg, _}} = (catch erlang:get_module_info(module_info_test,attributes)),
+ {'EXIT',{badarg, _}} = (catch erlang:get_module_info(module_info_test)),
+
+ %% then purge it
+ true = erlang:purge_module(module_info_test),
+ {'EXIT',{undef, _}} = (catch module_info_test:f()),
+ {'EXIT',{badarg, _}} = (catch erlang:get_module_info(module_info_test,attributes)),
+ {'EXIT',{badarg, _}} = (catch erlang:get_module_info(module_info_test)),
ok.
%% Test that the list of exported functions from this module is correct.
+%% Verify that module_info(native) works.
native(Config) when is_list(Config) ->
- ?line All = all_functions(),
- ?line case ?MODULE:module_info(native_addresses) of
- [] ->
- {comment,"no native functions"};
- L ->
- %% Verify that all functions have unique addresses.
- ?line S0 = sofs:set(L, [{name,arity,addr}]),
- ?line S1 = sofs:projection({external,fun ?MODULE:native_proj/1}, S0),
- ?line S2 = sofs:relation_to_family(S1),
- ?line S3 = sofs:family_specification(fun ?MODULE:native_filter/1, S2),
- ?line 0 = sofs:no_elements(S3),
- ?line S4 = sofs:range(S1),
-
- %% Verify that the set of function with native addresses
- %% is a subset of all functions in the module.
- ?line AllSet = sofs:set(All, [{name,arity}]),
- ?line true = sofs:is_subset(S4, AllSet),
-
- {comment,integer_to_list(sofs:no_elements(S0))++" native functions"}
- end.
+ All = all_functions(),
+ case ?MODULE:module_info(native_addresses) of
+ [] ->
+ false = ?MODULE:module_info(native),
+ {comment,"no native functions"};
+ L ->
+ true = ?MODULE:module_info(native),
+ %% Verify that all functions have unique addresses.
+ S0 = sofs:set(L, [{name,arity,addr}]),
+ S1 = sofs:projection({external,fun ?MODULE:native_proj/1}, S0),
+ S2 = sofs:relation_to_family(S1),
+ S3 = sofs:family_specification(fun ?MODULE:native_filter/1, S2),
+ 0 = sofs:no_elements(S3),
+ S4 = sofs:range(S1),
+
+ %% Verify that the set of function with native addresses
+ %% is a subset of all functions in the module.
+ AllSet = sofs:set(All, [{name,arity}]),
+ true = sofs:is_subset(S4, AllSet),
+
+ {comment,integer_to_list(sofs:no_elements(S0))++" native functions"}
+ end.
native_proj({Name,Arity,Addr}) ->
{Addr,{Name,Arity}}.
@@ -122,6 +148,22 @@ native_proj({Name,Arity,Addr}) ->
native_filter(Set) ->
sofs:no_elements(Set) =/= 1.
+%% Test that the module info of this module is correct. Use
+%% erlang:get_module_info(?MODULE) to avoid compiler optimization tricks.
+info(Config) when is_list(Config) ->
+ Info = erlang:get_module_info(?MODULE),
+ All = all_exported(),
+ {ok,{?MODULE,MD5}} = beam_lib:md5(code:which(?MODULE)),
+ {module, ?MODULE} = lists:keyfind(module, 1, Info),
+ {md5, MD5} = lists:keyfind(md5, 1, Info),
+ {exports, Exports} = lists:keyfind(exports, 1, Info),
+ All = lists:sort(Exports),
+ {attributes, Attrs} = lists:keyfind(attributes, 1, Info),
+ {vsn,_} = lists:keyfind(vsn, 1, Attrs),
+ {compile, Compile} = lists:keyfind(compile, 1, Info),
+ {options,_} = lists:keyfind(options, 1, Compile),
+ ok.
+
%% Helper functions (local).
add_arity(L) ->
diff --git a/erts/emulator/test/module_info_SUITE_data/module_info_test.erl b/erts/emulator/test/module_info_SUITE_data/module_info_test.erl
new file mode 100644
index 0000000000..6eaf21b9c9
--- /dev/null
+++ b/erts/emulator/test/module_info_SUITE_data/module_info_test.erl
@@ -0,0 +1,24 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%% %CopyrightEnd%
+%%
+
+-module(module_info_test).
+-export([f/0]).
+
+f() ->
+ 17.
diff --git a/erts/emulator/test/monitor_SUITE.erl b/erts/emulator/test/monitor_SUITE.erl
index aec59867d8..4db17969c0 100644
--- a/erts/emulator/test/monitor_SUITE.erl
+++ b/erts/emulator/test/monitor_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -26,7 +27,8 @@
case_1/1, case_1a/1, case_2/1, case_2a/1, mon_e_1/1, demon_e_1/1, demon_1/1,
demon_2/1, demon_3/1, demonitor_flush/1,
local_remove_monitor/1, remote_remove_monitor/1, mon_1/1, mon_2/1,
- large_exit/1, list_cleanup/1, mixer/1, named_down/1, otp_5827/1]).
+ large_exit/1, list_cleanup/1, mixer/1, named_down/1, otp_5827/1,
+ monitor_time_offset/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -38,7 +40,8 @@ all() ->
[case_1, case_1a, case_2, case_2a, mon_e_1, demon_e_1,
demon_1, mon_1, mon_2, demon_2, demon_3,
demonitor_flush, {group, remove_monitor}, large_exit,
- list_cleanup, mixer, named_down, otp_5827].
+ list_cleanup, mixer, named_down, otp_5827,
+ monitor_time_offset].
groups() ->
[{remove_monitor, [],
@@ -59,7 +62,7 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(15)),
- [{watchdog, Dog}|Config].
+ [{watchdog, Dog},{testcase, Func}|Config].
end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
@@ -663,110 +666,96 @@ list_cleanup(Config) when is_list(Config) ->
mixer(doc) ->
"Test mixing of internal and external monitors.";
mixer(Config) when is_list(Config) ->
- ?line PA = filename:dirname(code:which(?MODULE)),
- ?line NN = [j0,j1,j2,j3],
-% ?line NN = [j0,j1],
- ?line NL0 = [begin
- {ok, J} = test_server:start_node
- (X, slave, [{args, "-pa " ++ PA}]),
- J
- end || X <- NN],
- ?line NL1 = lists:duplicate(2,node()) ++ NL0,
- ?line Perm = perm(NL1),
- ?line lists:foreach(
- fun(NL) ->
- ?line Js = [ start_jeeves({[],M}) || M <- (NL ++ NL) ],
- ?line [ask_jeeves(P,{monitor_process,self()}) || P <- Js],
- ?line {monitored_by,MB} =
- process_info(self(),monitored_by),
- ?line MBL = lists:sort(MB),
- ?line JsL = lists:sort(Js),
- ?line MBL = JsL,
- ?line {monitors,[]} = process_info(self(),monitors),
- ?line [tell_jeeves(P,{exit,flaff}) || P <- Js],
- ?line wait_for_m([],[],200)
- end,
- Perm),
- ?line lists:foreach(
- fun(NL) ->
- ?line Js = [ start_jeeves({[],M}) || M <- (NL ++ NL) ],
- ?line Rs = [begin
- {monitor_process,Ref} =
- ask_jeeves(P,{monitor_process,self()}),
- {P,Ref}
- end
- || P <- Js],
- ?line {monitored_by,MB} =
- process_info(self(),monitored_by),
- ?line MBL = lists:sort(MB),
- ?line JsL = lists:sort(Js),
- ?line MBL = JsL,
- ?line {monitors,[]} = process_info(self(),monitors),
- ?line [ask_jeeves(P,{demonitor,Ref}) || {P,Ref} <- Rs],
- ?line wait_for_m([],[],200),
- ?line [tell_jeeves(P,{exit,flaff}) || P <- Js]
- end,
- Perm),
- ?line lists:foreach(
- fun(NL) ->
- ?line Js = [ start_jeeves({[],M}) || M <- (NL ++ NL) ],
- ?line [ask_jeeves(P,{monitor_process,self()}) || P <- Js],
- ?line [erlang:monitor(process,P) || P <- Js],
- ?line {monitored_by,MB} =
- process_info(self(),monitored_by),
- ?line MBL = lists:sort(MB),
- ?line JsL = lists:sort(Js),
- ?line MBL = JsL,
- ?line {monitors,M} =
- process_info(self(),monitors),
- ?line ML = lists:sort([P||{process,P} <- M]),
- ?line ML = JsL,
- ?line [begin
- tell_jeeves(P,{exit,flaff}),
- receive {'DOWN',_,process,P,_} -> ok end
- end || P <- Js],
- ?line wait_for_m([],[],200)
- end,
- Perm),
- ?line lists:foreach(
- fun(NL) ->
- ?line Js = [ start_jeeves({[],M}) || M <- (NL ++ NL) ],
- ?line Rs = [begin
- {monitor_process,Ref} =
- ask_jeeves(P,{monitor_process,self()}),
- {P,Ref}
- end
- || P <- Js],
- ?line R2s = [{P,erlang:monitor(process,P)} || P <- Js],
- ?line {monitored_by,MB} =
- process_info(self(),monitored_by),
- ?line MBL = lists:sort(MB),
- ?line JsL = lists:sort(Js),
- ?line MBL = JsL,
- ?line {monitors,M} =
- process_info(self(),monitors),
- ?line ML = lists:sort([P||{process,P} <- M]),
- ?line ML = JsL,
- ?line [ask_jeeves(P,{demonitor,Ref}) || {P,Ref} <- Rs],
- ?line wait_for_m(lists:sort(M),[],200),
- ?line [erlang:demonitor(Ref) || {_P,Ref} <- R2s],
- ?line wait_for_m([],[],200),
- ?line [tell_jeeves(P,{exit,flaff}) || P <- Js]
- end,
- Perm),
- [test_server:stop_node(K) || K <- NL0 ],
+ PA = filename:dirname(code:which(?MODULE)),
+ NN = [j0,j1,j2],
+ NL0 = [begin
+ {ok, J} = test_server:start_node(X,slave,[{args, "-pa " ++ PA}]),
+ J
+ end || X <- NN],
+ NL1 = lists:duplicate(2,node()) ++ NL0,
+ Perm = perm(NL1),
+ lists:foreach(
+ fun(NL) ->
+ Js = [start_jeeves({[],M}) || M <- (NL ++ NL)],
+ [ask_jeeves(P,{monitor_process,self()}) || P <- Js],
+ {monitored_by,MB} = process_info(self(),monitored_by),
+ MBL = lists:sort(MB),
+ JsL = lists:sort(Js),
+ MBL = JsL,
+ {monitors,[]} = process_info(self(),monitors),
+ [tell_jeeves(P,{exit,flaff}) || P <- Js],
+ wait_for_m([],[],200)
+ end,
+ Perm),
+ lists:foreach(
+ fun(NL) ->
+ Js = [start_jeeves({[],M}) || M <- (NL ++ NL)],
+ Rs = [begin
+ {monitor_process,Ref} = ask_jeeves(P,{monitor_process,self()}),
+ {P,Ref}
+ end || P <- Js],
+ {monitored_by,MB} = process_info(self(),monitored_by),
+ MBL = lists:sort(MB),
+ JsL = lists:sort(Js),
+ MBL = JsL,
+ {monitors,[]} = process_info(self(),monitors),
+ [ask_jeeves(P,{demonitor,Ref}) || {P,Ref} <- Rs],
+ wait_for_m([],[],200),
+ [tell_jeeves(P,{exit,flaff}) || P <- Js]
+ end,
+ Perm),
+ lists:foreach(
+ fun(NL) ->
+ Js = [start_jeeves({[],M}) || M <- (NL ++ NL)],
+ [ask_jeeves(P,{monitor_process,self()}) || P <- Js],
+ [erlang:monitor(process,P) || P <- Js],
+ {monitored_by,MB} = process_info(self(),monitored_by),
+ MBL = lists:sort(MB),
+ JsL = lists:sort(Js),
+ MBL = JsL,
+ {monitors,M} = process_info(self(),monitors),
+ ML = lists:sort([P||{process,P} <- M]),
+ ML = JsL,
+ [begin
+ tell_jeeves(P,{exit,flaff}),
+ receive {'DOWN',_,process,P,_} -> ok end
+ end || P <- Js],
+ wait_for_m([],[],200)
+ end,
+ Perm),
+ lists:foreach(
+ fun(NL) ->
+ Js = [start_jeeves({[],M}) || M <- (NL ++ NL)],
+ Rs = [begin
+ {monitor_process,Ref} = ask_jeeves(P,{monitor_process,self()}),
+ {P,Ref}
+ end || P <- Js],
+ R2s = [{P,erlang:monitor(process,P)} || P <- Js],
+ {monitored_by,MB} = process_info(self(),monitored_by),
+ MBL = lists:sort(MB),
+ JsL = lists:sort(Js),
+ MBL = JsL,
+ {monitors,M} = process_info(self(),monitors),
+ ML = lists:sort([P||{process,P} <- M]),
+ ML = JsL,
+ [ask_jeeves(P,{demonitor,Ref}) || {P,Ref} <- Rs],
+ wait_for_m(lists:sort(M),[],200),
+ [erlang:demonitor(Ref) || {_P,Ref} <- R2s],
+ wait_for_m([],[],200),
+ [tell_jeeves(P,{exit,flaff}) || P <- Js]
+ end,
+ Perm),
+ [test_server:stop_node(K) || K <- NL0],
ok.
named_down(doc) -> ["Test that DOWN message for a named monitor isn't"
" delivered until name has been unregistered"];
named_down(suite) -> [];
named_down(Config) when is_list(Config) ->
- ?line {A,B,C} = now(),
?line Name = list_to_atom(atom_to_list(?MODULE)
++ "-named_down-"
- ++ integer_to_list(A)
- ++ "-" ++ integer_to_list(B)
- ++ "-" ++ integer_to_list(C)),
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-" ++ integer_to_list(erlang:unique_integer([positive]))),
?line Prio = process_flag(priority,high),
%% Spawn a bunch of high prio cpu bound processes to prevent
%% normal prio processes from terminating during the next
@@ -837,6 +826,89 @@ otp_5827(Config) when is_list(Config) ->
?line ?t:fail("erlang:monitor/2 hangs")
end.
+monitor_time_offset(Config) when is_list(Config) ->
+ {ok, Node} = start_node(Config, "+C single_time_warp"),
+ Me = self(),
+ PMs = lists:map(fun (_) ->
+ Pid = spawn(Node,
+ fun () ->
+ check_monitor_time_offset(Me)
+ end),
+ {Pid, erlang:monitor(process, Pid)}
+ end,
+ lists:seq(1, 100)),
+ lists:foreach(fun ({P, _M}) ->
+ P ! check_no_change_message
+ end, PMs),
+ lists:foreach(fun ({P, M}) ->
+ receive
+ {no_change_message_received, P} ->
+ ok;
+ {'DOWN', M, process, P, Reason} ->
+ ?t:fail(Reason)
+ end
+ end, PMs),
+ preliminary = rpc:call(Node, erlang, system_flag, [time_offset, finalize]),
+ lists:foreach(fun ({P, M}) ->
+ receive
+ {change_messages_received, P} ->
+ erlang:demonitor(M, [flush]);
+ {'DOWN', M, process, P, Reason} ->
+ ?t:fail(Reason)
+ end
+ end, PMs),
+ stop_node(Node),
+ ok.
+
+check_monitor_time_offset(Leader) ->
+ Mon1 = erlang:monitor(time_offset, clock_service),
+ Mon2 = erlang:monitor(time_offset, clock_service),
+ Mon3 = erlang:monitor(time_offset, clock_service),
+ Mon4 = erlang:monitor(time_offset, clock_service),
+
+ erlang:demonitor(Mon2, [flush]),
+
+ Mon5 = erlang:monitor(time_offset, clock_service),
+ Mon6 = erlang:monitor(time_offset, clock_service),
+ Mon7 = erlang:monitor(time_offset, clock_service),
+
+ receive check_no_change_message -> ok end,
+ receive
+ {'CHANGE', _, time_offset, clock_service, _} ->
+ exit(unexpected_change_message_received)
+ after 0 ->
+ Leader ! {no_change_message_received, self()}
+ end,
+ receive after 100 -> ok end,
+ erlang:demonitor(Mon4, [flush]),
+ receive
+ {'CHANGE', Mon3, time_offset, clock_service, _} ->
+ ok
+ end,
+ receive
+ {'CHANGE', Mon6, time_offset, clock_service, _} ->
+ ok
+ end,
+ erlang:demonitor(Mon5, [flush]),
+ receive
+ {'CHANGE', Mon7, time_offset, clock_service, _} ->
+ ok
+ end,
+ receive
+ {'CHANGE', Mon1, time_offset, clock_service, _} ->
+ ok
+ end,
+ receive
+ {'CHANGE', _, time_offset, clock_service, _} ->
+ exit(unexpected_change_message_received)
+ after 1000 ->
+ ok
+ end,
+ Leader ! {change_messages_received, self()}.
+
+%%
+%% ...
+%%
wait_for_m(_,_,0) ->
exit(monitor_wait_timeout);
@@ -959,3 +1031,25 @@ generate(_Fun, 0) ->
[];
generate(Fun, N) ->
[Fun() | generate(Fun, N-1)].
+
+start_node(Config) ->
+ start_node(Config, "").
+
+start_node(Config, Args) ->
+ TestCase = ?config(testcase, Config),
+ PA = filename:dirname(code:which(?MODULE)),
+ ESTime = erlang:monotonic_time(1) + erlang:time_offset(1),
+ Unique = erlang:unique_integer([positive]),
+ Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(TestCase)
+ ++ "-"
+ ++ integer_to_list(ESTime)
+ ++ "-"
+ ++ integer_to_list(Unique)),
+ test_server:start_node(Name,
+ slave,
+ [{args, "-pa " ++ PA ++ " " ++ Args}]).
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
diff --git a/erts/emulator/test/mtx_SUITE.erl b/erts/emulator/test/mtx_SUITE.erl
index a492501959..87dace4721 100644
--- a/erts/emulator/test/mtx_SUITE.erl
+++ b/erts/emulator/test/mtx_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -441,10 +442,10 @@ hammer_ets_rwlock_test(XOpts, UW, C, N, NP, SC) ->
receive after infinity -> ok end
end) | Ps0]
end,
- Start = now(),
+ Start = erlang:monotonic_time(),
lists:foreach(fun (P) -> P ! go end, Ps),
lists:foreach(fun (P) -> receive {done, P} -> ok end end, Ps),
- Stop = now(),
+ Stop = erlang:monotonic_time(),
lists:foreach(fun (P) ->
unlink(P),
exit(P, bang),
@@ -453,7 +454,7 @@ hammer_ets_rwlock_test(XOpts, UW, C, N, NP, SC) ->
{'DOWN', M, process, P, _} -> ok
end
end, Ps),
- Res = timer:now_diff(Stop, Start)/1000000,
+ Res = (Stop-Start)/erlang:convert_time_unit(1,seconds,native),
Caller ! {?MODULE, self(), Res}
end,
TP = spawn_link(T),
diff --git a/erts/emulator/test/mtx_SUITE_data/Makefile.src b/erts/emulator/test/mtx_SUITE_data/Makefile.src
index 04412280c0..dc880118f1 100644
--- a/erts/emulator/test/mtx_SUITE_data/Makefile.src
+++ b/erts/emulator/test/mtx_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
index 7c8137dc83..1911291448 100644
--- a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
+++ b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/nested_SUITE.erl b/erts/emulator/test/nested_SUITE.erl
index 2cd67ebaae..7cfa837ee5 100644
--- a/erts/emulator/test/nested_SUITE.erl
+++ b/erts/emulator/test/nested_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 4560077a51..2400505159 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,7 +40,10 @@
get_length/1, make_atom/1, make_string/1, reverse_list_test/1,
otp_9828/1,
otp_9668/1, consume_timeslice/1, dirty_nif/1, dirty_nif_send/1,
- dirty_nif_exception/1, nif_schedule/1
+ dirty_nif_exception/1, call_dirty_nif_exception/1, nif_schedule/1,
+ nif_exception/1, call_nif_exception/1,
+ nif_nan_and_inf/1, nif_atom_too_long/1,
+ nif_monotonic_time/1, nif_time_offset/1, nif_convert_time_unit/1
]).
-export([many_args_100/100]).
@@ -68,7 +72,9 @@ all() ->
make_string,reverse_list_test,
otp_9828,
otp_9668, consume_timeslice,
- nif_schedule, dirty_nif, dirty_nif_send, dirty_nif_exception
+ nif_schedule, dirty_nif, dirty_nif_send, dirty_nif_exception,
+ nif_exception, nif_nan_and_inf, nif_atom_too_long,
+ nif_monotonic_time, nif_time_offset, nif_convert_time_unit
].
groups() ->
@@ -451,7 +457,7 @@ maps(Config) when is_list(Config) ->
M = maps_from_list_nif(Pairs),
R = {RIs,Is} = sorted_list_from_maps_nif(M),
io:format("Pairs: ~p~nMap: ~p~nReturned: ~p~n", [lists:sort(Pairs),M,R]),
- Is = lists:sort(Pairs),
+ true = (lists:sort(Is) =:= lists:sort(Pairs)),
Is = lists:reverse(RIs),
#{} = maps_from_list_nif([]),
@@ -611,7 +617,6 @@ resource_new_do2(Type) ->
?line {PtrA,BinA} = get_resource(Type, ResA),
?line {PtrB,BinB} = get_resource(Type, ResB),
?line true = (PtrA =/= PtrB),
- ?line [] = last_resource_dtor_call(),
%% forget ResA and make it garbage
{{PtrA,BinA}, {ResB,PtrB,BinB}}.
@@ -1188,7 +1193,9 @@ send3(Config) when is_list(Config) ->
%% Let a number of processes send random message blobs between each other
%% using enif_send. Kill and spawn new ones randomly to keep a ~constant
%% number of workers running.
- Seed = now(),
+ Seed = {erlang:monotonic_time(),
+ erlang:time_offset(),
+ erlang:unique_integer()},
io:format("seed: ~p\n",[Seed]),
random:seed(Seed),
ets:new(nif_SUITE,[named_table,public]),
@@ -1383,7 +1390,7 @@ is_checks(Config) when is_list(Config) ->
self(), hd(erlang:ports()), [], [1,9,9,8],
{hejsan, "hejsan", [$h,"ejs",<<"an">>]}, -18446744073709551616.2e2),
try
- ?line error = check_is_exception(),
+ ?line check_is_exception(),
?line throw(expected_badarg)
catch
error:badarg ->
@@ -1595,19 +1602,94 @@ dirty_nif_exception(Config) when is_list(Config) ->
N when is_integer(N) ->
ensure_lib_loaded(Config),
try
- call_dirty_nif_exception(),
+ %% this checks that the expected exception occurs when the
+ %% dirty NIF returns the result of enif_make_badarg
+ %% directly
+ call_dirty_nif_exception(1),
?t:fail(expected_badarg)
catch
error:badarg ->
- [{?MODULE,call_dirty_nif_exception,[],_}|_] =
+ [{?MODULE,call_dirty_nif_exception,[1],_}|_] =
erlang:get_stacktrace(),
ok
- end
+ end,
+ try
+ %% this checks that the expected exception occurs when the
+ %% dirty NIF calls enif_make_badarg at some point but then
+ %% returns a value that isn't an exception
+ call_dirty_nif_exception(0),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ [{?MODULE,call_dirty_nif_exception,[0],_}|_] =
+ erlang:get_stacktrace(),
+ ok
+ end,
+ %% this checks that a dirty NIF can raise various terms as
+ %% exceptions
+ ok = nif_raise_exceptions(call_dirty_nif_exception)
catch
error:badarg ->
{skipped,"No dirty scheduler support"}
end.
+nif_exception(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ try
+ %% this checks that the expected exception occurs when the NIF
+ %% calls enif_make_badarg at some point but then tries to return a
+ %% value that isn't an exception
+ call_nif_exception(0),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ %% this checks that a NIF can raise various terms as exceptions
+ ok = nif_raise_exceptions(call_nif_exception),
+ ok.
+
+nif_nan_and_inf(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ try
+ call_nif_nan_or_inf(nan),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ try
+ call_nif_nan_or_inf(inf),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ try
+ call_nif_nan_or_inf(tuple),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end.
+
+nif_atom_too_long(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ try
+ call_nif_atom_too_long(all),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ try
+ call_nif_atom_too_long(len),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end.
+
next_msg(_Pid) ->
receive
M -> M
@@ -1632,7 +1714,9 @@ tmpmem() ->
false -> undefined;
MemInfo ->
MSBCS = lists:foldl(
- fun ({instance, _, L}, Acc) ->
+ fun ({instance, 0, _}, Acc) ->
+ Acc; % Ignore instance 0
+ ({instance, _, L}, Acc) ->
{value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
{value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
[MBCS,SBCS | Acc]
@@ -1687,7 +1771,162 @@ check(Exp,Got,Line) ->
io:format("CHECK at ~p: Expected ~p but got ~p\n",[Line,Exp,Got]),
Got
end.
-
+
+nif_raise_exceptions(NifFunc) ->
+ ExcTerms = [{error, test}, "a string", <<"a binary">>,
+ 42, [1,2,3,4,5], [{p,1},{p,2},{p,3}]],
+ lists:foldl(fun(Term, ok) ->
+ try
+ erlang:apply(?MODULE,NifFunc,[Term]),
+ ?t:fail({expected,Term})
+ catch
+ error:Term ->
+ [{?MODULE,NifFunc,[Term],_}|_] = erlang:get_stacktrace(),
+ ok
+ end
+ end, ok, ExcTerms).
+
+-define(ERL_NIF_TIME_ERROR, -9223372036854775808).
+-define(TIME_UNITS, [seconds, milli_seconds, micro_seconds, nano_seconds]).
+
+nif_monotonic_time(Config) ->
+ ?ERL_NIF_TIME_ERROR = monotonic_time(invalid_time_unit),
+ mtime_loop(1000000).
+
+mtime_loop(0) ->
+ ok;
+mtime_loop(N) ->
+ chk_mtime(?TIME_UNITS),
+ mtime_loop(N-1).
+
+chk_mtime([]) ->
+ ok;
+chk_mtime([TU|TUs]) ->
+ A = erlang:monotonic_time(TU),
+ B = monotonic_time(TU),
+ C = erlang:monotonic_time(TU),
+ try
+ true = A =< B,
+ true = B =< C
+ catch
+ _ : _ ->
+ ?t:fail({monotonic_time_missmatch, TU, A, B, C})
+ end,
+ chk_mtime(TUs).
+
+nif_time_offset(Config) ->
+ ?ERL_NIF_TIME_ERROR = time_offset(invalid_time_unit),
+ toffs_loop(1000000).
+
+toffs_loop(0) ->
+ ok;
+toffs_loop(N) ->
+ chk_toffs(?TIME_UNITS),
+ toffs_loop(N-1).
+
+chk_toffs([]) ->
+ ok;
+chk_toffs([TU|TUs]) ->
+ TO = erlang:time_offset(TU),
+ NifTO = time_offset(TU),
+ case TO =:= NifTO of
+ true ->
+ ok;
+ false ->
+ case erlang:system_info(time_warp_mode) of
+ no_time_warp ->
+ ?t:fail({time_offset_mismatch, TU, TO, NifTO});
+ _ ->
+ %% Most frequent time offset change
+ %% is currently only every 15:th
+ %% second so this should currently
+ %% work...
+ NTO = erlang:time_offset(TU),
+ case NifTO =:= NTO of
+ true ->
+ ok;
+ false ->
+ ?t:fail({time_offset_mismatch, TU, TO, NifTO, NTO})
+ end
+ end
+ end,
+ chk_toffs(TUs).
+
+nif_convert_time_unit(Config) ->
+ ?ERL_NIF_TIME_ERROR = convert_time_unit(0, seconds, invalid_time_unit),
+ ?ERL_NIF_TIME_ERROR = convert_time_unit(0, invalid_time_unit, seconds),
+ ?ERL_NIF_TIME_ERROR = convert_time_unit(0, invalid_time_unit, invalid_time_unit),
+ lists:foreach(fun (Offset) ->
+ lists:foreach(fun (Diff) ->
+ chk_ctu(Diff+(Offset*1000*1000*1000))
+ end,
+ [999999999999,
+ 99999999999,
+ 9999999999,
+ 999999999,
+ 99999999,
+ 9999999,
+ 999999,
+ 99999,
+ 999,
+ 99,
+ 9,
+ 1,
+ 11,
+ 101,
+ 1001,
+ 10001,
+ 100001,
+ 1000001,
+ 10000001,
+ 100000001,
+ 1000000001,
+ 100000000001,
+ 1000000000001,
+ 5,
+ 50,
+ 500,
+ 5000,
+ 50000,
+ 500000,
+ 5000000,
+ 50000000,
+ 500000000,
+ 5000000000,
+ 50000000000,
+ 500000000000])
+ end,
+ [-4711, -1000, -475, -5, -4, -3, -2, -1, 0,
+ 1, 2, 3, 4, 5, 475, 1000, 4711]),
+ ctu_loop(1000000).
+
+ctu_loop(0) ->
+ ok;
+ctu_loop(N) ->
+ chk_ctu(erlang:monotonic_time(nano_seconds)),
+ ctu_loop(N-1).
+
+chk_ctu(Time) ->
+ chk_ctu(Time, ?TIME_UNITS).
+
+chk_ctu(_Time, []) ->
+ ok;
+chk_ctu(Time, [FromTU|FromTUs]) ->
+ chk_ctu(Time, FromTU, ?TIME_UNITS),
+ chk_ctu(Time, FromTUs).
+
+chk_ctu(_Time, _FromTU, []) ->
+ ok;
+chk_ctu(Time, FromTU, [ToTU|ToTUs]) ->
+ T = erlang:convert_time_unit(Time, nano_seconds, FromTU),
+ TE = erlang:convert_time_unit(T, FromTU, ToTU),
+ TN = convert_time_unit(T, FromTU, ToTU),
+ case TE =:= TN of
+ false ->
+ ?t:fail({conversion_mismatch, FromTU, T, ToTU, TE, TN});
+ true ->
+ chk_ctu(Time, FromTU, ToTUs)
+ end.
%% The NIFs:
lib_version() -> undefined.
@@ -1741,8 +1980,11 @@ consume_timeslice_nif(_,_) -> ?nif_stub.
call_nif_schedule(_,_) -> ?nif_stub.
call_dirty_nif(_,_,_) -> ?nif_stub.
send_from_dirty_nif(_) -> ?nif_stub.
-call_dirty_nif_exception() -> ?nif_stub.
+call_dirty_nif_exception(_) -> ?nif_stub.
call_dirty_nif_zero_args() -> ?nif_stub.
+call_nif_exception(_) -> ?nif_stub.
+call_nif_nan_or_inf(_) -> ?nif_stub.
+call_nif_atom_too_long(_) -> ?nif_stub.
%% maps
is_map_nif(_) -> ?nif_stub.
@@ -1755,6 +1997,11 @@ make_map_remove_nif(_,_) -> ?nif_stub.
maps_from_list_nif(_) -> ?nif_stub.
sorted_list_from_maps_nif(_) -> ?nif_stub.
+%% Time
+monotonic_time(_) -> ?nif_stub.
+time_offset(_) -> ?nif_stub.
+convert_time_unit(_,_,_) -> ?nif_stub.
+
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 85544db2ab..8ebce4fef4 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -33,6 +34,10 @@ static ERL_NIF_TERM atom_self;
static ERL_NIF_TERM atom_ok;
static ERL_NIF_TERM atom_join;
static ERL_NIF_TERM atom_binary_resource_type;
+static ERL_NIF_TERM atom_seconds;
+static ERL_NIF_TERM atom_milli_seconds;
+static ERL_NIF_TERM atom_micro_seconds;
+static ERL_NIF_TERM atom_nano_seconds;
typedef struct
@@ -137,6 +142,10 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
atom_ok = enif_make_atom(env,"ok");
atom_join = enif_make_atom(env,"join");
atom_binary_resource_type = enif_make_atom(env,"binary_resource_type");
+ atom_seconds = enif_make_atom(env,"seconds");
+ atom_milli_seconds = enif_make_atom(env,"milli_seconds");
+ atom_micro_seconds = enif_make_atom(env,"micro_seconds");
+ atom_nano_seconds = enif_make_atom(env,"nano_seconds");
*priv_data = data;
return 0;
@@ -380,7 +389,8 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifSInt64 sint64;
ErlNifUInt64 uint64;
double d;
- ERL_NIF_TERM atom, ref1, ref2;
+ ERL_NIF_TERM atom, ref1, ref2, term;
+ size_t len;
sint = INT_MIN;
do {
@@ -502,6 +512,7 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
goto error;
}
}
+
ref1 = enif_make_ref(env);
ref2 = enif_make_ref(env);
if (!enif_is_ref(env,ref1) || !enif_is_ref(env,ref2)
@@ -881,15 +892,19 @@ static ERL_NIF_TERM check_is(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
*
* This function is separate from check_is because it calls enif_make_badarg
* and so it must return the badarg exception as its return value. Thus, the
- * badarg exception indicates success. Failure is indicated by returning an
- * error atom.
+ * badarg exception indicates success.
*/
static ERL_NIF_TERM check_is_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
+ ERL_NIF_TERM badarg, exc_term;
ERL_NIF_TERM error_atom = enif_make_atom(env, "error");
- ERL_NIF_TERM badarg = enif_make_badarg(env);
- if (enif_is_exception(env, error_atom)) return error_atom;
- if (!enif_is_exception(env, badarg)) return error_atom;
+ ERL_NIF_TERM badarg_atom = enif_make_atom(env, "badarg");
+ assert(!enif_is_exception(env, error_atom));
+ badarg = enif_make_badarg(env);
+ assert(enif_is_exception(env, badarg));
+ assert(enif_has_pending_exception(env, NULL));
+ assert(enif_has_pending_exception(env, &exc_term));
+ assert(enif_is_identical(exc_term, badarg_atom));
return badarg;
}
@@ -1533,9 +1548,12 @@ static ERL_NIF_TERM nif_sched1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
static ERL_NIF_TERM call_nif_schedule(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
+ ERL_NIF_TERM result;
if (argc != 2)
return enif_make_atom(env, "false");
- return enif_schedule_nif(env, "nif_sched1", 0, nif_sched1, argc, argv);
+ result = enif_schedule_nif(env, "nif_sched1", 0, nif_sched1, argc, argv);
+ assert(!enif_is_exception(env, result));
+ return result;
}
#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
@@ -1608,16 +1626,31 @@ static ERL_NIF_TERM send_from_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_
static ERL_NIF_TERM call_dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
switch (argc) {
- case 0: {
- ERL_NIF_TERM args[255];
- int i;
- for (i = 0; i < 255; i++)
- args[i] = enif_make_int(env, i);
- return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
- call_dirty_nif_exception, 255, argv);
+ case 1: {
+ int arg;
+ if (enif_get_int(env, argv[0], &arg) && arg < 2) {
+ ERL_NIF_TERM args[255];
+ int i;
+ args[0] = argv[0];
+ for (i = 1; i < 255; i++)
+ args[i] = enif_make_int(env, i);
+ return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
+ call_dirty_nif_exception, 255, args);
+ } else {
+ return enif_raise_exception(env, argv[0]);
+ }
+ }
+ case 2: {
+ int return_badarg_directly;
+ enif_get_int(env, argv[0], &return_badarg_directly);
+ assert(return_badarg_directly == 1 || return_badarg_directly == 0);
+ if (return_badarg_directly)
+ return enif_make_badarg(env);
+ else {
+ /* ignore return value */ enif_make_badarg(env);
+ return enif_make_atom(env, "ok");
+ }
}
- case 1:
- return enif_make_badarg(env);
default:
return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
call_dirty_nif_exception, argc-1, argv);
@@ -1637,6 +1670,100 @@ static ERL_NIF_TERM call_dirty_nif_zero_args(ErlNifEnv* env, int argc, const ERL
}
#endif
+/*
+ * If argv[0] is the integer 0, call enif_make_badarg, but don't return its
+ * return value. Instead, return ok. Result should still be a badarg
+ * exception for the erlang caller.
+ *
+ * For any other value of argv[0], use it as an exception term and return
+ * the exception.
+ */
+static ERL_NIF_TERM call_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM exc_term;
+ ERL_NIF_TERM badarg_atom = enif_make_atom(env, "badarg");
+ int arg;
+
+ if (enif_get_int(env, argv[0], &arg) && arg == 0) {
+ /* ignore return value */ enif_make_badarg(env);
+ assert(enif_has_pending_exception(env, NULL));
+ assert(enif_has_pending_exception(env, &exc_term));
+ assert(enif_is_identical(badarg_atom, exc_term));
+ return enif_make_atom(env, "ok");
+ } else {
+ ERL_NIF_TERM exc_retval = enif_raise_exception(env, argv[0]);
+ assert(enif_has_pending_exception(env, NULL));
+ assert(enif_has_pending_exception(env, &exc_term));
+ assert(enif_is_identical(argv[0], exc_term));
+ return exc_retval;
+ }
+}
+
+#if !defined(NAN) || !defined(INFINITY)
+double zero(void)
+{
+ return 0.0;
+}
+#endif
+
+static ERL_NIF_TERM call_nif_nan_or_inf(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ double val;
+ char arg[6];
+ ERL_NIF_TERM res;
+
+ assert(argc == 1);
+ enif_get_atom(env, argv[0], arg, sizeof arg, ERL_NIF_LATIN1);
+ if (strcmp(arg, "nan") == 0) {
+ /* Verify that enif_make_double raises a badarg for NaN */
+#ifdef NAN
+ val = NAN;
+#else
+ val = 0.0/zero();
+#endif
+ } else {
+ /* Verify that enif_make_double raises a badarg for NaN and infinity */
+#ifdef INFINITY
+ val = INFINITY;
+#else
+ val = 1.0/zero();
+#endif
+ }
+ res = enif_make_double(env, val);
+ assert(enif_is_exception(env, res));
+ assert(enif_has_pending_exception(env, NULL));
+ if (strcmp(arg, "tuple") == 0) {
+ return enif_make_tuple2(env, argv[0], res);
+ } else {
+ return res;
+ }
+}
+
+static ERL_NIF_TERM call_nif_atom_too_long(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ char str[257];
+ char arg[4];
+ size_t len;
+ int i;
+ ERL_NIF_TERM res;
+
+ assert(argc == 1);
+ enif_get_atom(env, argv[0], arg, sizeof arg, ERL_NIF_LATIN1);
+ /* Verify that creating an atom from a string that's too long results in a badarg */
+ for (i = 0; i < sizeof str; ++i) {
+ str[i] = 'a';
+ }
+ str[256] = '\0';
+ if (strcmp(arg, "len") == 0) {
+ len = strlen(str);
+ res = enif_make_atom_len(env, str, len);
+ } else {
+ res = enif_make_atom(env, str);
+ }
+ assert(enif_is_exception(env, res));
+ return res;
+}
+
static ERL_NIF_TERM is_map_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_int(env, enif_is_map(env,argv[0]));
@@ -1713,12 +1840,13 @@ static ERL_NIF_TERM sorted_list_from_maps_nif(ErlNifEnv* env, int argc, const ER
if (argc != 1 && !enif_is_map(env, map))
return enif_make_int(env, __LINE__);
- if(!enif_map_iterator_create(env, map, &iter_f, ERL_NIF_MAP_ITERATOR_HEAD))
+ if(!enif_map_iterator_create(env, map, &iter_f, ERL_NIF_MAP_ITERATOR_FIRST))
return enif_make_int(env, __LINE__);
cnt = 0;
+ next_ret = 1;
while(enif_map_iterator_get_pair(env,&iter_f,&key,&value)) {
- if (cnt && !next_ret)
+ if (!next_ret)
return enif_make_int(env, __LINE__);
list_f = enif_make_list_cell(env, enif_make_tuple2(env, key, value), list_f);
next_ret = enif_map_iterator_next(env,&iter_f);
@@ -1727,12 +1855,13 @@ static ERL_NIF_TERM sorted_list_from_maps_nif(ErlNifEnv* env, int argc, const ER
if (cnt && next_ret)
return enif_make_int(env, __LINE__);
- if(!enif_map_iterator_create(env, map, &iter_b, ERL_NIF_MAP_ITERATOR_TAIL))
+ if(!enif_map_iterator_create(env, map, &iter_b, ERL_NIF_MAP_ITERATOR_LAST))
return enif_make_int(env, __LINE__);
cnt = 0;
+ prev_ret = 1;
while(enif_map_iterator_get_pair(env,&iter_b,&key,&value)) {
- if (cnt && !prev_ret)
+ if (!prev_ret)
return enif_make_int(env, __LINE__);
/* Test that iter_f can step "backwards" */
@@ -1744,6 +1873,7 @@ static ERL_NIF_TERM sorted_list_from_maps_nif(ErlNifEnv* env, int argc, const ER
list_b = enif_make_list_cell(env, enif_make_tuple2(env, key, value), list_b);
prev_ret = enif_map_iterator_prev(env,&iter_b);
+ cnt++;
}
if (cnt) {
@@ -1763,6 +1893,87 @@ static ERL_NIF_TERM sorted_list_from_maps_nif(ErlNifEnv* env, int argc, const ER
return enif_make_tuple2(env, list_f, list_b);
}
+
+static ERL_NIF_TERM monotonic_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifTimeUnit time_unit;
+
+ if (argc != 1)
+ return atom_false;
+
+ if (enif_compare(argv[0], atom_seconds) == 0)
+ time_unit = ERL_NIF_SEC;
+ else if (enif_compare(argv[0], atom_milli_seconds) == 0)
+ time_unit = ERL_NIF_MSEC;
+ else if (enif_compare(argv[0], atom_micro_seconds) == 0)
+ time_unit = ERL_NIF_USEC;
+ else if (enif_compare(argv[0], atom_nano_seconds) == 0)
+ time_unit = ERL_NIF_NSEC;
+ else
+ time_unit = 4711; /* invalid time unit */
+
+ return enif_make_int64(env, enif_monotonic_time(time_unit));
+}
+
+static ERL_NIF_TERM time_offset(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifTimeUnit time_unit;
+
+ if (argc != 1)
+ return atom_false;
+
+ if (enif_compare(argv[0], atom_seconds) == 0)
+ time_unit = ERL_NIF_SEC;
+ else if (enif_compare(argv[0], atom_milli_seconds) == 0)
+ time_unit = ERL_NIF_MSEC;
+ else if (enif_compare(argv[0], atom_micro_seconds) == 0)
+ time_unit = ERL_NIF_USEC;
+ else if (enif_compare(argv[0], atom_nano_seconds) == 0)
+ time_unit = ERL_NIF_NSEC;
+ else
+ time_unit = 4711; /* invalid time unit */
+ return enif_make_int64(env, enif_time_offset(time_unit));
+}
+
+static ERL_NIF_TERM convert_time_unit(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifSInt64 i64;
+ ErlNifTime val;
+ ErlNifTimeUnit from, to;
+
+ if (argc != 3)
+ return atom_false;
+
+ if (!enif_get_int64(env, argv[0], &i64))
+ return enif_make_badarg(env);
+
+ val = (ErlNifTime) i64;
+
+ if (enif_compare(argv[1], atom_seconds) == 0)
+ from = ERL_NIF_SEC;
+ else if (enif_compare(argv[1], atom_milli_seconds) == 0)
+ from = ERL_NIF_MSEC;
+ else if (enif_compare(argv[1], atom_micro_seconds) == 0)
+ from = ERL_NIF_USEC;
+ else if (enif_compare(argv[1], atom_nano_seconds) == 0)
+ from = ERL_NIF_NSEC;
+ else
+ from = 4711; /* invalid time unit */
+
+ if (enif_compare(argv[2], atom_seconds) == 0)
+ to = ERL_NIF_SEC;
+ else if (enif_compare(argv[2], atom_milli_seconds) == 0)
+ to = ERL_NIF_MSEC;
+ else if (enif_compare(argv[2], atom_micro_seconds) == 0)
+ to = ERL_NIF_USEC;
+ else if (enif_compare(argv[2], atom_nano_seconds) == 0)
+ to = ERL_NIF_NSEC;
+ else
+ to = 4711; /* invalid time unit */
+
+ return enif_make_int64(env, enif_convert_time_unit(val, from, to));
+}
+
static ErlNifFunc nif_funcs[] =
{
{"lib_version", 0, lib_version},
@@ -1818,9 +2029,12 @@ static ErlNifFunc nif_funcs[] =
#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
{"call_dirty_nif", 3, call_dirty_nif},
{"send_from_dirty_nif", 1, send_from_dirty_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
- {"call_dirty_nif_exception", 0, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND},
+ {"call_dirty_nif_exception", 1, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND},
{"call_dirty_nif_zero_args", 0, call_dirty_nif_zero_args, ERL_NIF_DIRTY_JOB_CPU_BOUND},
#endif
+ {"call_nif_exception", 1, call_nif_exception},
+ {"call_nif_nan_or_inf", 1, call_nif_nan_or_inf},
+ {"call_nif_atom_too_long", 1, call_nif_atom_too_long},
{"is_map_nif", 1, is_map_nif},
{"get_map_size_nif", 1, get_map_size_nif},
{"make_new_map_nif", 0, make_new_map_nif},
@@ -1829,7 +2043,10 @@ static ErlNifFunc nif_funcs[] =
{"make_map_update_nif", 3, make_map_update_nif},
{"make_map_remove_nif", 2, make_map_remove_nif},
{"maps_from_list_nif", 1, maps_from_list_nif},
- {"sorted_list_from_maps_nif", 1, sorted_list_from_maps_nif}
+ {"sorted_list_from_maps_nif", 1, sorted_list_from_maps_nif},
+ {"monotonic_time", 1, monotonic_time},
+ {"time_offset", 1, time_offset},
+ {"convert_time_unit", 3, convert_time_unit}
};
ERL_NIF_INIT(nif_SUITE,nif_funcs,load,reload,upgrade,unload)
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.c b/erts/emulator/test/nif_SUITE_data/nif_mod.c
index 11b5d0cc35..f7e729e2b6 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -239,7 +240,7 @@ static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ADD_CALL("get_priv_data_ptr");
- return enif_make_ulong(env, (unsigned long)priv_data(env));
+ return enif_make_uint64(env, (ErlNifUInt64)priv_data(env));
}
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.erl b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
index 6634624698..e65d4577c7 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.erl
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/nif_SUITE_data/testcase_driver.h b/erts/emulator/test/nif_SUITE_data/testcase_driver.h
index 98339e4746..e32e63069a 100644
--- a/erts/emulator/test/nif_SUITE_data/testcase_driver.h
+++ b/erts/emulator/test/nif_SUITE_data/testcase_driver.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index 3f9b339ed2..fecaad5232 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -73,6 +74,8 @@ init_per_suite(Config) ->
Config.
end_per_suite(_Config) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:set_internal_state(node_tab_delayed_delete, -1), %% restore original value
available_internal_state(false).
init_per_group(_GroupName, Config) ->
@@ -419,6 +422,8 @@ node_table_gc(doc) ->
["Tests that node tables are garbage collected."];
node_table_gc(suite) -> [];
node_table_gc(Config) when is_list(Config) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:set_internal_state(node_tab_delayed_delete, 0),
?line PreKnown = nodes(known),
?line ?t:format("PreKnown = ~p~n", [PreKnown]),
?line make_node_garbage(0, 200000, 1000, []),
@@ -428,6 +433,7 @@ node_table_gc(Config) when is_list(Config) ->
?line ?t:format("PostAreas = ~p~n", [PostAreas]),
?line true = length(PostKnown) =< length(PreKnown),
?line nc_refc_check(node()),
+ erts_debug:set_internal_state(node_tab_delayed_delete, -1), %% restore original value
?line ok.
make_node_garbage(N, L, I, Ps) when N < L ->
@@ -579,6 +585,8 @@ node_controller_refc(doc) ->
"as they should for entities controlling a connections."];
node_controller_refc(suite) -> [];
node_controller_refc(Config) when is_list(Config) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:set_internal_state(node_tab_delayed_delete, 0),
?line NodeFirstName = get_nodefirstname(),
?line ?line {ok, Node} = start_node(NodeFirstName),
?line true = lists:member(Node, nodes()),
@@ -606,6 +614,7 @@ node_controller_refc(Config) when is_list(Config) ->
?line false = get_dist_references(Node),
?line false = lists:member(Node, nodes(known)),
?line nc_refc_check(node()),
+ erts_debug:set_internal_state(node_tab_delayed_delete, -1), %% restore original value
?line ok.
%%
@@ -989,23 +998,32 @@ check_nd_refc({ThisNodeName, ThisCreation}, NodeRefs, DistRefs, Fail) ->
check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) ->
lists:foreach(
fun ({Entry, Refc, ReferrerList}) ->
- FoundRefs =
+ {DelayedDeleteTimer,
+ FoundRefs} =
lists:foldl(
- fun ({_Referrer, ReferencesList}, A1) ->
- A1 + lists:foldl(fun ({_T,Rs},A2) ->
- A2+Rs
- end,
- 0,
- ReferencesList)
+ fun ({Referrer, ReferencesList}, {DDT, A1}) ->
+ {case Referrer of
+ {system,delayed_delete_timer} ->
+ true;
+ _ ->
+ DDT
+ end,
+ A1 + lists:foldl(fun ({_T,Rs},A2) ->
+ A2+Rs
+ end,
+ 0,
+ ReferencesList)}
end,
- 0,
+ {false, 0},
ReferrerList),
- %% Reference count equals found references ?
- case Refc =:= FoundRefs of
- true ->
+ %% Reference count equals found references?
+ case {Refc, FoundRefs, DelayedDeleteTimer} of
+ {X, X, _} ->
+ ok;
+ {0, 1, true} ->
ok;
- false ->
+ _ ->
exit({invalid_reference_count, Table, Entry})
end,
@@ -1013,7 +1031,8 @@ check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) ->
case {Entry, Refc} of
{ThisNodeName, 0} -> ok;
{{ThisNodeName, ThisCreation}, 0} -> ok;
- {_, 0} -> exit({not_referred_entry_in_table, Table, Entry});
+ {_, 0} when DelayedDeleteTimer == false ->
+ exit({not_referred_entry_in_table, Table, Entry});
{_, _} -> ok
end
@@ -1117,26 +1136,18 @@ wait_until(Pred) ->
false -> receive after 100 -> wait_until(Pred) end
end.
+get_nodefirstname_string() ->
+ atom_to_list(?MODULE)
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-"
+ ++ integer_to_list(erlang:unique_integer([positive])).
get_nodefirstname() ->
- {A, B, C} = now(),
- list_to_atom(atom_to_list(?MODULE)
- ++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)).
+ list_to_atom(get_nodefirstname_string()).
get_nodename() ->
- {A, B, C} = now(),
- list_to_atom(atom_to_list(?MODULE)
- ++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)
+ list_to_atom(get_nodefirstname_string()
++ "@"
++ hostname()).
diff --git a/erts/emulator/test/nofrag_SUITE.erl b/erts/emulator/test/nofrag_SUITE.erl
index 57eec87e63..3660a58c56 100644
--- a/erts/emulator/test/nofrag_SUITE.erl
+++ b/erts/emulator/test/nofrag_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
index abe5b8eb91..90b6a36262 100644
--- a/erts/emulator/test/num_bif_SUITE.erl
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -428,7 +429,7 @@ t_string_to_integer(Config) when is_list(Config) ->
list_to_binary(Value))),
{'EXIT', {badarg, _}} =
(catch erlang:list_to_integer(Value))
- end,["1.0"," 1"," -1",""]),
+ end,["1.0"," 1"," -1","","+"]),
% Custom base error cases
lists:foreach(fun({Value,Base}) ->
diff --git a/erts/emulator/test/old_mod.erl b/erts/emulator/test/old_mod.erl
index 124842390a..1586a024d8 100644
--- a/erts/emulator/test/old_mod.erl
+++ b/erts/emulator/test/old_mod.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/old_scheduler_SUITE.erl b/erts/emulator/test/old_scheduler_SUITE.erl
index 262536a068..97c99fe07b 100644
--- a/erts/emulator/test/old_scheduler_SUITE.erl
+++ b/erts/emulator/test/old_scheduler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -116,7 +117,7 @@ equal(Config) when is_list(Config) ->
%% start controllers
?line Receiver =
- spawn(fun() -> receiver(now(), Time, Self, Normal, Low) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
?line Starter =
spawn(fun() -> starter(Normal, Low, Receiver) end),
@@ -154,7 +155,7 @@ many_low(Config) when is_list(Config) ->
Time = 30,
?line Receiver =
- spawn(fun() -> receiver(now(), Time, Self, Normal, Low) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
?line Starter =
spawn(fun() -> starter(Normal, Low, Receiver) end),
?line {NRs,NAvg,LRs,LAvg,Ratio} =
@@ -185,7 +186,7 @@ few_low(Config) when is_list(Config) ->
Time = 30,
?line Receiver =
- spawn(fun() -> receiver(now(), Time, Self, Normal, Low) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
?line Starter =
spawn(fun() -> starter(Normal, Low, Receiver) end),
?line {NRs,NAvg,LRs,LAvg,Ratio} =
@@ -220,7 +221,7 @@ max(Config) when is_list(Config) ->
Time = 30,
?line Receiver1 =
- spawn(fun() -> receiver(now(), Time, Self, Max, High) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, High) end),
?line Starter1 =
spawn(fun() -> starter(Max, High, Receiver1) end),
?line {M1Rs,M1Avg,HRs,HAvg,Ratio1} =
@@ -238,7 +239,7 @@ max(Config) when is_list(Config) ->
end,
?line Receiver2 =
- spawn(fun() -> receiver(now(), Time, Self, Max, Normal) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Normal) end),
?line Starter2 =
spawn(fun() -> starter(Max, Normal, Receiver2) end),
?line {M2Rs,M2Avg,NRs,NAvg,Ratio2} =
@@ -256,7 +257,7 @@ max(Config) when is_list(Config) ->
end,
?line Receiver3 =
- spawn(fun() -> receiver(now(), Time, Self, Max, Low) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Low) end),
?line Starter3 =
spawn(fun() -> starter(Max, Low, Receiver3) end),
?line {M3Rs,M3Avg,LRs,LAvg,Ratio3} =
@@ -290,7 +291,7 @@ high(Config) when is_list(Config) ->
Time = 30,
?line Receiver1 =
- spawn(fun() -> receiver(now(), Time, Self, High, Normal) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Normal) end),
?line Starter1 =
spawn(fun() -> starter(High, Normal, Receiver1) end),
?line {H1Rs,H1Avg,NRs,NAvg,Ratio1} =
@@ -308,7 +309,7 @@ high(Config) when is_list(Config) ->
end,
?line Receiver2 =
- spawn(fun() -> receiver(now(), Time, Self, High, Low) end),
+ spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Low) end),
?line Starter2 =
spawn(fun() -> starter(High, Low, Receiver2) end),
?line {H2Rs,H2Avg,LRs,LAvg,Ratio2} =
@@ -337,12 +338,13 @@ receiver(T0, TimeSec, Main, {P1,P1N}, {P2,P2N}) ->
%% uncomment lines below to get life sign (debug)
receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 0) ->
-% T = elapsed_ms(T0, now()),
+% T = erlang:convert_time_unit(erlang:monotonic_time() - T0, native, milli_seconds),
% erlang:display({round(T/1000),P1Rs,P2Rs}),
receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 100000);
receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, C) ->
- Remain = Time - elapsed_ms(T0, now()), % test time remaining
+ Remain = Time - erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native, milli_seconds), % test time remaining
Remain1 = if Remain < 0 ->
0;
true ->
@@ -409,6 +411,3 @@ flush_loop() ->
ok
end,
flush_loop().
-
-elapsed_ms({_MS0,S0,MuS0},{_MS1,S1,MuS1}) ->
- round(((S1-S0)*1000)+((MuS1-MuS0)/1000)).
diff --git a/erts/emulator/test/op_SUITE.erl b/erts/emulator/test/op_SUITE.erl
index ef4689b850..6eda78a57b 100644
--- a/erts/emulator/test/op_SUITE.erl
+++ b/erts/emulator/test/op_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -273,7 +274,8 @@ run_test_module(Cases, GuardsOk) ->
?line Bbts = lists:foldr(fun internal_bif/2, [Ok], Es),
?line Fun3 = make_function(bif_tests, Bbts),
?line Id = {function,1,id,1,[{clause,1,[{var,1,'I'}],[],[{var,1,'I'}]}]},
- ?line Module = make_module(op_tests, [Fun1,Fun2,Fun3,Id]),
+ Module0 = make_module(op_tests, [Fun1,Fun2,Fun3,Id]),
+ Module = erl_parse:new_anno(Module0),
?line lists:foreach(fun(F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Module),
%% Compile, load, and run the generated module.
@@ -365,13 +367,16 @@ make_module(Name, Funcs) ->
make_function(Name, Body) ->
{function,1,Name,0,[{clause,1,[],[],Body}]}.
-eval(E) ->
+eval(E0) ->
+ E = erl_parse:new_anno(E0),
?line case catch erl_eval:exprs(E, []) of
{'EXIT',Reason} -> {'EXIT',Reason};
{value,Val,_Bs} -> Val
end.
-unvalue(V) -> erl_parse:abstract(V).
+unvalue(V) ->
+ Abstr = erl_parse:abstract(V),
+ erl_parse:anno_to_term(Abstr).
value({nil,_}) -> [];
value({integer,_,X}) -> X;
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 9083545060..3d0509a28c 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1407,6 +1408,12 @@ spawn_executable(Config) when is_list(Config) ->
run_echo_args(SpaceDir,[ExactFile2,"hello world","dlrow olleh"]),
[ExactFile2,"hello world","dlrow olleh"] =
run_echo_args(SpaceDir,[binary, ExactFile2,"hello world","dlrow olleh"]),
+
+ [ExactFile2,"hello \"world\"","\"dlrow\" olleh"] =
+ run_echo_args(SpaceDir,[binary, ExactFile2,"hello \"world\"","\"dlrow\" olleh"]),
+ [ExactFile2,"hello \"world\"","\"dlrow\" olleh"] =
+ run_echo_args(SpaceDir,[binary, ExactFile2,"hello \"world\"","\"dlrow\" olleh"]),
+
[ExactFile2] = run_echo_args(SpaceDir,[default]),
[ExactFile2,"hello world","dlrow olleh"] =
run_echo_args(SpaceDir,[switch_order,ExactFile2,"hello world",
@@ -1809,7 +1816,7 @@ exit_status_msb_test(Config, SleepSecs) when is_list(Config) ->
Parent = self(),
?t:format("SleepSecs = ~p~n", [SleepSecs]),
PortProg = "sleep " ++ integer_to_list(SleepSecs),
- Start = now(),
+ Start = erlang:monotonic_time(micro_seconds),
NoProcs = case NoSchedsOnln of
NProcs when NProcs < ?EXIT_STATUS_MSB_MAX_PROCS ->
NProcs;
@@ -1881,12 +1888,12 @@ exit_status_msb_test(Config, SleepSecs) when is_list(Config) ->
receive {P, started, SIds} -> SIds end
end,
Procs),
- StartedTime = timer:now_diff(now(), Start)/1000000,
+ StartedTime = (erlang:monotonic_time(micro_seconds) - Start)/1000000,
?t:format("StartedTime = ~p~n", [StartedTime]),
true = StartedTime < SleepSecs,
erlang:system_flag(multi_scheduling, block),
lists:foreach(fun (P) -> receive {P, done} -> ok end end, Procs),
- DoneTime = timer:now_diff(now(), Start)/1000000,
+ DoneTime = (erlang:monotonic_time(micro_seconds) - Start)/1000000,
?t:format("DoneTime = ~p~n", [DoneTime]),
true = DoneTime > SleepSecs,
ok = verify_multi_scheduling_blocked(),
diff --git a/erts/emulator/test/port_SUITE_data/dead_port.c b/erts/emulator/test/port_SUITE_data/dead_port.c
index ea91546b0c..c859dbc402 100644
--- a/erts/emulator/test/port_SUITE_data/dead_port.c
+++ b/erts/emulator/test/port_SUITE_data/dead_port.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/emulator/test/port_SUITE_data/port_test.erl b/erts/emulator/test/port_SUITE_data/port_test.erl
index 56abfd5ded..b07038e73d 100644
--- a/erts/emulator/test/port_SUITE_data/port_test.erl
+++ b/erts/emulator/test/port_SUITE_data/port_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/port_bif_SUITE.erl b/erts/emulator/test/port_bif_SUITE.erl
index 0c5b09d45a..b65a22a528 100644
--- a/erts/emulator/test/port_bif_SUITE.erl
+++ b/erts/emulator/test/port_bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index bf31655066..97aa5e573e 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -379,16 +380,15 @@ eat_high(Low) ->
process_flag(priority, high),
receive after 1000 -> ok end,
exit(Low, {you, are, dead}),
- {_, Sec, _} = now(),
- loop(Sec, Sec).
+ loop(erlang:monotonic_time() + erlang:convert_time_unit(5,seconds,native)).
%% Busy loop for 5 seconds.
-loop(OrigSec, CurrentSec) when CurrentSec < OrigSec+5 ->
- {_, NewSec, _} = now(),
- loop(OrigSec, NewSec);
-loop(_, _) ->
- ok.
+loop(StopTime) ->
+ case StopTime >= erlang:monotonic_time() of
+ true -> ok;
+ false -> loop(StopTime)
+ end.
%% Tries to send two different exit messages to a process.
@@ -1478,7 +1478,15 @@ processes_this_tab(doc) ->
processes_this_tab(suite) ->
[];
processes_this_tab(Config) when is_list(Config) ->
- sys_mem_cond_run(1024, fun () -> chk_processes_bif_test_res(processes_bif_test()) end).
+ Mem = case {erlang:system_info(build_type),
+ erlang:system_info(allocator)} of
+ {lcnt, {_, _Vsn, [sys_alloc], _Opts}} ->
+ %% When running +Mea min + lcnt we may need more memory
+ 1024 * 4;
+ _ ->
+ 1024
+ end,
+ sys_mem_cond_run(Mem, fun () -> chk_processes_bif_test_res(processes_bif_test()) end).
chk_processes_bif_test_res(ok) -> ok;
chk_processes_bif_test_res({comment, _} = Comment) -> Comment;
@@ -2450,16 +2458,13 @@ start_node(Config) ->
start_node(Config, Args) when is_list(Config) ->
Pa = filename:dirname(code:which(?MODULE)),
- {A, B, C} = now(),
Name = list_to_atom(atom_to_list(?MODULE)
++ "-"
++ atom_to_list(?config(testcase, Config))
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ integer_to_list(erlang:system_time(seconds))
++ "-"
- ++ integer_to_list(C)),
+ ++ integer_to_list(erlang:unique_integer([positive]))),
?t:start_node(Name, slave, [{args, "-pa "++Pa++" "++Args}]).
stop_node(Node) ->
diff --git a/erts/emulator/test/pseudoknot_SUITE.erl b/erts/emulator/test/pseudoknot_SUITE.erl
index 5a7cdcecd5..58ef3cd563 100644
--- a/erts/emulator/test/pseudoknot_SUITE.erl
+++ b/erts/emulator/test/pseudoknot_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/random_iolist.erl b/erts/emulator/test/random_iolist.erl
index 8f21b5a3b3..9a0f034e72 100644
--- a/erts/emulator/test/random_iolist.erl
+++ b/erts/emulator/test/random_iolist.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index 2e7ac1f50c..ccae0df72e 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/ref_SUITE.erl b/erts/emulator/test/ref_SUITE.erl
index e13dfa1575..1042c23d65 100644
--- a/erts/emulator/test/ref_SUITE.erl
+++ b/erts/emulator/test/ref_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/register_SUITE.erl b/erts/emulator/test/register_SUITE.erl
index 9953df3458..5ecca0f547 100644
--- a/erts/emulator/test/register_SUITE.erl
+++ b/erts/emulator/test/register_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/save_calls_SUITE.erl b/erts/emulator/test/save_calls_SUITE.erl
index ddf8b2d919..4e50fdc898 100644
--- a/erts/emulator/test/save_calls_SUITE.erl
+++ b/erts/emulator/test/save_calls_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -155,8 +156,19 @@ save_calls_1() ->
?line erlang:process_flag(self(), save_calls, 10),
?line {last_calls, L3} = process_info(self(), last_calls),
+ true = (L3 /= false),
?line L31 = lists:filter(fun is_local_function/1, L3),
?line [] = L31,
+ erlang:process_flag(self(), save_calls, 0),
+
+ %% Also check that it works on another process ...
+ Pid = spawn(fun () -> receive after infinity -> ok end end),
+ erlang:process_flag(Pid, save_calls, 10),
+ {last_calls, L4} = process_info(Pid, last_calls),
+ true = (L4 /= false),
+ L41 = lists:filter(fun is_local_function/1, L4),
+ [] = L41,
+ exit(Pid,kill),
ok.
do_bipp() ->
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index 3906471f87..986a73ebb1 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1829,11 +1830,11 @@ do_it(Tracer, Low, Normal, High, Max) ->
do_it(Tracer, Low, Normal, High, Max, RedsPerSchedLimit) ->
OldPrio = process_flag(priority, max),
go_work(Low, Normal, High, Max),
- StartWait = now(),
+ StartWait = erlang:monotonic_time(milli_seconds),
%% Give the emulator a chance to balance the load...
wait_balance(5),
- EndWait = now(),
- BalanceWait = timer:now_diff(EndWait,StartWait) div 1000,
+ EndWait = erlang:monotonic_time(milli_seconds),
+ BalanceWait = EndWait-StartWait,
erlang:display({balance_wait, BalanceWait}),
Timeout = ?DEFAULT_TIMEOUT - ?t:minutes(4) - BalanceWait,
Res = case Timeout < ?MIN_SCHEDULER_TEST_TIMEOUT of
@@ -2027,17 +2028,14 @@ start_node(Config) ->
start_node(Config, "").
start_node(Config, Args) when is_list(Config) ->
- ?line Pa = filename:dirname(code:which(?MODULE)),
- ?line {A, B, C} = now(),
- ?line Name = list_to_atom(atom_to_list(?MODULE)
- ++ "-"
- ++ atom_to_list(?config(testcase, Config))
- ++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)),
+ Pa = filename:dirname(code:which(?MODULE)),
+ Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(?config(testcase, Config))
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-"
+ ++ integer_to_list(erlang:unique_integer([positive]))),
?line ?t:start_node(Name, slave, [{args, "-pa "++Pa++" "++Args}]).
stop_node(Node) ->
diff --git a/erts/emulator/test/send_term_SUITE.erl b/erts/emulator/test/send_term_SUITE.erl
index 8e1f8df43a..670865cd3f 100644
--- a/erts/emulator/test/send_term_SUITE.erl
+++ b/erts/emulator/test/send_term_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -279,7 +280,10 @@ generate_external_terms_files(BaseDir) ->
{4444444444444444,-44444, [[[[[[[[[[[5]]]]]]]]]]], make_ref()},
{444444444444444444444,-44444, {{{{{{{{{{{{6}}}}}}}}}}}}, make_ref()},
{444444444444444,-44444, {{{{{{{{{{{{7}}}}}}}}}}}}, make_ref()},
- {4444444444444444444,-44444, {{{{{{{{{{{{8}}}}}}}}}}}}, make_ref()}],
+ {4444444444444444444,-44444, {{{{{{{{{{{{8}}}}}}}}}}}}, make_ref()},
+ #{},
+ #{1 => 11, 2 => 22, 3 => 33},
+ maps:from_list([{K,K*11} || K <- lists:seq(1,100)])],
ok = file:write_file(filename:join([BaseDir,
"send_term_SUITE_data",
"ext_terms.bin"]),
@@ -354,16 +358,17 @@ write_bytes(IoDev, Prefix, [B|Bs], N) ->
write_bytes(IoDev, ",", Bs, N+1).
write_license(IoDev) ->
- S = "/* ``The contents of this file are subject to the Erlang Public License,~n"
- " * Version 1.1, (the \"License\"); you may not use this file except in~n"
- " * compliance with the License. You should have received a copy of the~n"
- " * Erlang Public License along with this software. If not, it can be~n"
- " * retrieved via the world wide web at http://www.erlang.org/.~n"
- " * ~n"
- " * Software distributed under the License is distributed on an \"AS IS\"~n"
- " * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n"
- " * the License for the specific language governing rights and limitations~n"
- " * under the License.~n"
+ S = "/* ``Licensed under the Apache License, Version 2.0 (the \"License\");~n"
+ " * you may not use this file except in compliance with the License.~n"
+ " * You may obtain a copy of the License at~n"
+ " * ~n"
+ " * http://www.apache.org/licenses/LICENSE-2.0~n"
+ " * ~n"
+ " * Unless required by applicable law or agreed to in writing, software~n"
+ " * distributed under the License is distributed on an \"AS IS\" BASIS,~n"
+ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~n"
+ " * See the License for the specific language governing permissions and~n"
+ " * limitations under the License.~n"
" * ~n"
" * The Initial Developer of the Original Code is Ericsson AB.~n"
" * Portions created by Ericsson are Copyright 2007, Ericsson AB.~n"
diff --git a/erts/emulator/test/send_term_SUITE_data/ext_terms.bin b/erts/emulator/test/send_term_SUITE_data/ext_terms.bin
index b239284323..5ff0b2ccf1 100644
--- a/erts/emulator/test/send_term_SUITE_data/ext_terms.bin
+++ b/erts/emulator/test/send_term_SUITE_data/ext_terms.bin
Binary files differ
diff --git a/erts/emulator/test/send_term_SUITE_data/ext_terms.h b/erts/emulator/test/send_term_SUITE_data/ext_terms.h
index 08134f3b05..83277078c6 100644
--- a/erts/emulator/test/send_term_SUITE_data/ext_terms.h
+++ b/erts/emulator/test/send_term_SUITE_data/ext_terms.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson AB.
* Portions created by Ericsson are Copyright 2007, Ericsson AB.
@@ -24,9 +25,9 @@
#ifndef EXT_TERMS_H__
#define EXT_TERMS_H__
static struct {
- unsigned char ext[162];
+ unsigned char ext[637];
int ext_size;
- unsigned char cext[162];
+ unsigned char cext[637];
int cext_size;
} ext_terms[] = {
{{131,104,3,98,0,0,18,103,98,255,255,237,153,108,0,0,0,2,100,0,7,97,110,95,97,116,111,109,107,0,6,97,32,108,105,115,116,106},
@@ -37,26 +38,26 @@ static struct {
46,
{131,108,0,0,0,4,110,9,0,0,0,160,222,197,173,201,53,54,110,7,1,199,113,21,183,140,242,3,107,0,6,98,108,117,112,112,33,100,0,5,98,108,105,112,112,106},
46},
- {{131,104,5,103,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,38,0,0,0,0,3,104,2,114,0,3,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,40,0,0,0,0,0,0,0,0,102,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3,103,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,37,0,0,0,0,3,102,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,59,0,0,0,0,0,0,0,0},
- 162,
- {131,80,0,0,0,161,120,156,203,96,77,79,97,224,77,140,207,203,79,73,117,72,207,47,74,74,76,103,96,96,80,3,98,6,230,12,166,34,6,102,116,89,102,160,140,6,3,20,164,97,209,203,200,12,52,145,39,17,85,80,21,108,96,26,166,4,35,51,216,14,20,97,144,21,214,48,43,0,1,209,36,52},
- 82},
- {{131,104,5,104,0,106,106,112,0,0,0,79,0,21,87,190,182,1,38,106,214,65,228,1,52,27,227,2,212,0,0,0,1,0,0,0,0,100,0,15,115,101,110,100,95,116,101,114,109,95,83,85,73,84,69,97,1,98,0,184,11,180,103,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,37,0,0,0,0,3,109,0,0,0,31,104,101,106,32,104,111,112,112,32,116,114,97,108,108,97,108,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97},
- 123,
- {131,80,0,0,0,122,120,156,203,96,205,96,200,202,42,96,96,96,240,103,16,13,223,183,141,81,45,235,154,227,19,70,19,233,199,76,87,128,130,140,64,204,144,194,192,95,156,154,151,18,95,146,90,148,27,31,28,234,25,226,154,200,152,196,176,131,123,75,122,10,3,79,98,94,126,74,170,67,122,126,81,82,98,58,80,173,42,72,3,115,46,144,144,207,72,205,82,200,200,47,40,80,40,41,74,204,201,73,204,73,68,5,0,18,237,35,68},
- 117},
+ {{131,104,5,103,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,41,0,0,0,0,2,104,2,114,0,3,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,2,0,0,0,42,0,0,0,3,0,0,0,0,102,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,2,103,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,40,0,0,0,0,3,102,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,3,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,56,0,0,0,3,0,0,0,0},
+ 204,
+ {131,80,0,0,0,203,120,156,203,96,77,79,97,16,73,140,207,203,79,73,117,72,205,169,48,54,201,200,171,52,50,210,53,76,98,96,96,208,4,98,6,166,12,166,34,6,102,28,138,152,128,10,180,128,152,25,164,50,13,183,73,12,76,64,107,132,179,19,115,114,48,229,52,64,242,204,105,56,229,25,152,193,246,99,147,5,89,107,1,179,30,0,103,37,46,144},
+ 96},
+ {{131,104,5,104,0,106,106,112,0,0,0,86,0,123,56,104,225,98,55,108,63,185,201,160,64,191,31,210,203,0,0,0,2,0,0,0,0,100,0,15,115,101,110,100,95,116,101,114,109,95,83,85,73,84,69,97,2,98,3,217,195,71,103,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,40,0,0,0,0,3,109,0,0,0,31,104,101,106,32,104,111,112,112,32,116,114,97,108,108,97,108,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97},
+ 130,
+ {131,80,0,0,0,129,120,156,203,96,205,96,200,202,42,96,96,96,8,99,168,182,200,120,152,100,158,99,191,243,228,2,135,253,242,151,78,3,5,153,128,152,33,133,129,191,56,53,47,37,190,36,181,40,55,62,56,212,51,196,53,145,41,137,249,230,97,247,244,20,6,225,236,196,156,156,84,135,212,156,10,99,147,140,188,74,35,35,93,195,36,160,22,13,144,62,230,92,32,33,159,145,154,165,144,145,95,80,160,80,82,4,84,154,152,147,136,10,0,219,221,39,33},
+ 123},
{{131,108,0,0,0,4,110,10,0,28,199,113,166,118,185,145,86,105,9,110,5,1,28,103,24,89,10,107,0,2,98,33,100,0,10,98,108,105,112,112,112,112,112,112,112,106},
46,
{131,108,0,0,0,4,110,10,0,28,199,113,166,118,185,145,86,105,9,110,5,1,28,103,24,89,10,107,0,2,98,33,100,0,10,98,108,105,112,112,112,112,112,112,112,106},
46},
- {{131,104,5,98,0,0,18,103,103,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,38,0,0,0,0,3,104,2,114,0,3,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,40,0,0,0,0,0,0,0,0,102,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3,98,255,255,237,153,108,0,0,0,2,100,0,7,97,110,95,97,116,111,109,107,0,6,97,32,108,105,115,116,106},
- 120,
- {131,80,0,0,0,119,120,156,203,96,77,98,96,16,74,79,79,97,224,77,140,207,203,79,73,117,72,207,47,74,74,76,103,96,96,80,3,98,6,230,12,166,34,6,102,116,89,102,160,140,6,3,20,164,97,209,203,200,156,244,255,255,219,153,57,64,38,83,10,3,123,98,94,124,98,73,126,110,54,3,91,162,66,78,102,113,73,22,0,167,192,30,158},
- 93},
- {{131,104,4,103,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,38,0,0,0,0,3,104,2,114,0,3,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,40,0,0,0,0,0,0,0,0,102,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3,103,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,0,0,0,0,0,3,102,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3},
- 131,
- {131,80,0,0,0,130,120,156,203,96,73,79,97,224,77,140,207,203,79,73,117,72,207,47,74,74,76,103,96,96,80,3,98,6,230,12,166,34,6,102,116,89,102,160,140,6,3,20,164,97,209,203,200,12,52,145,39,17,85,16,12,152,211,48,37,24,153,1,215,214,30,50},
- 72},
+ {{131,104,5,98,0,0,18,103,103,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,41,0,0,0,0,2,104,2,114,0,3,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,2,0,0,0,42,0,0,0,3,0,0,0,0,102,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,2,98,255,255,237,153,108,0,0,0,2,100,0,7,97,110,95,97,116,111,109,107,0,6,97,32,108,105,115,116,106},
+ 141,
+ {131,80,0,0,0,140,120,156,203,96,77,98,96,16,74,79,79,97,16,73,140,207,203,79,73,117,72,205,169,48,54,201,200,171,52,50,210,53,4,202,49,104,2,49,3,83,6,83,17,3,51,14,69,76,64,5,90,64,204,12,82,153,134,219,36,6,166,164,255,255,223,206,204,1,177,82,24,216,19,243,226,19,75,242,115,179,25,216,18,21,114,50,139,75,178,0,77,99,35,202},
+ 100},
+ {{131,104,4,103,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,41,0,0,0,0,2,104,2,114,0,3,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,2,0,0,0,42,0,0,0,3,0,0,0,0,102,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,2,103,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,0,0,0,0,3,102,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,3},
+ 166,
+ {131,80,0,0,0,165,120,156,203,96,73,79,97,16,73,140,207,203,79,73,117,72,205,169,48,54,201,200,171,52,50,210,53,76,98,96,96,208,4,98,6,166,12,166,34,6,102,28,138,152,128,10,180,128,152,25,164,50,13,183,73,12,76,64,107,132,179,19,115,114,176,200,129,0,115,26,110,121,102,0,219,33,38,209},
+ 84},
{{131,104,3,98,0,0,18,103,98,255,255,237,153,108,0,0,0,2,100,0,7,97,110,95,97,116,111,109,107,0,6,97,32,108,105,115,116,106},
38,
{131,104,3,98,0,0,18,103,98,255,255,237,153,108,0,0,0,2,100,0,7,97,110,95,97,116,111,109,107,0,6,97,32,108,105,115,116,106},
@@ -65,46 +66,58 @@ static struct {
33,
{131,104,3,98,0,0,18,103,98,255,255,237,153,108,0,0,0,2,100,0,4,97,116,111,109,107,0,4,108,105,115,116,106},
33},
- {{131,104,4,103,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,38,0,0,0,0,3,104,2,114,0,3,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,40,0,0,0,0,0,0,0,0,102,100,0,13,97,95,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3,103,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,0,0,0,0,0,3,102,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,1,3},
- 131,
- {131,80,0,0,0,130,120,156,203,96,73,79,97,224,77,140,207,203,79,73,117,72,207,47,74,74,76,103,96,96,80,3,98,6,230,12,166,34,6,102,116,89,102,160,140,6,3,20,164,97,209,203,200,12,52,145,39,17,85,16,12,152,211,48,37,24,153,1,215,214,30,50},
+ {{131,104,4,103,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,41,0,0,0,0,2,104,2,114,0,3,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,2,0,0,0,42,0,0,0,3,0,0,0,0,102,100,0,20,97,95,110,111,100,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,2,103,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,0,0,0,0,3,102,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,0,0,0,0,3},
+ 166,
+ {131,80,0,0,0,165,120,156,203,96,73,79,97,16,73,140,207,203,79,73,117,72,205,169,48,54,201,200,171,52,50,210,53,76,98,96,96,208,4,98,6,166,12,166,34,6,102,28,138,152,128,10,180,128,152,25,164,50,13,183,73,12,76,64,107,132,179,19,115,114,176,200,129,0,115,26,110,121,102,0,219,33,38,209},
+ 84},
+ {{131,104,4,110,8,0,28,199,17,175,172,214,173,61,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,0,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,57,0,0,0,3,0,0,0,0},
+ 81,
+ {131,80,0,0,0,80,120,156,203,96,201,227,96,144,57,46,184,126,205,181,181,182,73,255,255,7,165,100,48,98,133,12,69,12,204,41,12,194,217,137,57,57,169,14,169,57,21,198,38,25,121,149,70,70,186,134,73,204,12,12,12,150,64,12,162,25,0,231,161,20,138},
+ 71},
+ {{131,104,4,110,9,0,28,199,241,98,116,219,231,23,24,98,255,255,82,100,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,107,0,1,1,106,106,106,106,106,106,106,106,106,106,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,58,0,0,0,3,0,0,0,0},
+ 122,
+ {131,80,0,0,0,121,120,156,203,96,201,227,100,144,57,254,49,169,228,246,115,113,137,164,255,255,131,82,114,24,24,24,24,73,34,178,25,24,25,179,224,160,136,129,57,133,65,56,59,49,39,39,213,33,53,167,194,216,36,35,175,210,200,72,215,48,137,25,168,214,10,136,65,52,3,0,142,142,25,0},
+ 80},
+ {{131,104,4,110,8,0,28,199,129,17,222,251,42,6,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,2,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,59,0,0,0,3,0,0,0,0},
+ 83,
+ {131,80,0,0,0,82,120,156,203,96,201,227,96,144,57,222,40,120,239,183,22,91,210,255,255,65,41,25,140,216,97,34,83,17,3,115,10,131,112,118,98,78,78,170,67,106,78,133,177,73,70,94,165,145,145,174,97,18,51,3,3,131,53,16,131,104,6,0,233,167,20,95},
72},
- {{131,104,4,110,8,0,28,199,17,175,172,214,173,61,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,0,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,60,0,0,0,0,0,0,0,0},
- 74,
- {131,80,0,0,0,73,120,156,203,96,201,227,96,144,57,46,184,126,205,181,181,182,73,255,255,7,165,100,48,98,133,12,69,12,204,41,12,60,137,121,249,41,169,14,233,249,69,73,137,233,204,12,12,12,54,12,80,0,0,73,17,18,208},
- 63},
- {{131,104,4,110,9,0,28,199,241,98,116,219,231,23,24,98,255,255,82,100,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,107,0,1,1,106,106,106,106,106,106,106,106,106,106,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,61,0,0,0,0,0,0,0,0},
- 115,
- {131,80,0,0,0,114,120,156,203,96,201,227,100,144,57,254,49,169,228,246,115,113,137,164,255,255,131,82,114,24,24,24,24,73,34,178,25,24,25,179,224,160,136,129,57,133,129,39,49,47,63,37,213,33,61,191,40,41,49,157,25,168,200,150,1,10,0,208,188,23,70},
+ {{131,104,4,110,9,0,28,199,113,221,139,146,14,239,240,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,3,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,60,0,0,0,3,0,0,0,0},
+ 84,
+ {131,80,0,0,0,83,120,156,203,96,201,227,100,144,57,94,120,183,123,18,223,251,15,73,255,255,7,165,100,48,98,135,137,204,69,12,204,41,12,194,217,137,57,57,169,14,169,57,21,198,38,25,121,149,70,70,186,134,73,204,12,12,12,54,64,12,162,25,0,106,11,22,31},
+ 73},
+ {{131,104,4,110,9,0,28,199,177,214,190,98,202,104,2,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,4,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,61,0,0,0,3,0,0,0,0},
+ 84,
+ {131,80,0,0,0,83,120,156,203,96,201,227,100,144,57,190,241,218,190,164,83,25,76,73,255,255,7,165,100,48,98,135,137,44,69,12,204,41,12,194,217,137,57,57,169,14,169,57,21,198,38,25,121,149,70,70,186,134,73,204,12,12,12,182,64,12,162,25,0,74,151,21,164},
+ 73},
+ {{131,104,4,110,7,0,28,199,85,220,50,202,15,98,255,255,82,100,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,107,0,1,5,106,106,106,106,106,106,106,106,106,106,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,62,0,0,0,3,0,0,0,0},
+ 120,
+ {131,80,0,0,0,119,120,156,203,96,201,99,103,144,57,30,122,199,232,20,127,210,255,255,65,41,57,12,12,12,140,36,17,217,12,140,172,89,112,80,196,192,156,194,32,156,157,152,147,147,234,144,154,83,97,108,146,145,87,105,100,164,107,152,196,12,84,107,7,196,32,154,1,0,225,225,23,138},
+ 78},
+ {{131,104,4,110,9,0,28,199,241,98,116,219,231,23,24,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,6,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,63,0,0,0,3,0,0,0,0},
+ 84,
+ {131,80,0,0,0,83,120,156,203,96,201,227,100,144,57,254,49,169,228,246,115,113,137,164,255,255,131,82,50,24,177,195,68,182,34,6,230,20,6,225,236,196,156,156,84,135,212,156,10,99,147,140,188,74,35,35,93,195,36,102,6,6,6,123,32,6,209,12,0,64,205,21,133},
+ 73},
+ {{131,104,4,110,7,0,28,199,59,73,56,148,1,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,7,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,64,0,0,0,3,0,0,0,0},
+ 82,
+ {131,80,0,0,0,81,120,156,203,96,201,99,103,144,57,110,237,105,49,133,49,233,255,255,160,148,12,70,236,48,145,189,136,129,57,133,65,56,59,49,39,39,213,33,53,167,194,216,36,35,175,210,200,72,215,48,137,153,129,129,193,1,136,65,52,3,0,137,143,19,30},
71},
- {{131,104,4,110,8,0,28,199,129,17,222,251,42,6,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,2,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,62,0,0,0,0,0,0,0,0},
- 76,
- {131,80,0,0,0,75,120,156,203,96,201,227,96,144,57,222,40,120,239,183,22,91,210,255,255,65,41,25,140,216,97,34,83,17,3,115,10,3,79,98,94,126,74,170,67,122,126,81,82,98,58,51,3,3,131,29,3,20,0,0,76,82,18,165},
- 64},
- {{131,104,4,110,9,0,28,199,113,221,139,146,14,239,240,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,3,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,63,0,0,0,0,0,0,0,0},
- 77,
- {131,80,0,0,0,76,120,156,203,96,201,227,100,144,57,94,120,183,123,18,223,251,15,73,255,255,7,165,100,48,98,135,137,204,69,12,204,41,12,60,137,121,249,41,169,14,233,249,69,73,137,233,204,12,12,12,246,12,80,0,0,192,110,20,101},
- 65},
- {{131,104,4,110,9,0,28,199,177,214,190,98,202,104,2,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,4,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,64,0,0,0,0,0,0,0,0},
- 77,
- {131,80,0,0,0,76,120,156,203,96,201,227,100,144,57,190,241,218,190,164,83,25,76,73,255,255,7,165,100,48,98,135,137,44,69,12,204,41,12,60,137,121,249,41,169,14,233,249,69,73,137,233,204,12,12,12,14,12,80,0,0,164,94,19,234},
- 65},
- {{131,104,4,110,7,0,28,199,85,220,50,202,15,98,255,255,82,100,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,108,0,0,0,1,107,0,1,5,106,106,106,106,106,106,106,106,106,106,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,65,0,0,0,0,0,0,0,0},
- 113,
- {131,80,0,0,0,112,120,156,203,96,201,99,103,144,57,30,122,199,232,20,127,210,255,255,65,41,57,12,12,12,140,36,17,217,12,140,172,89,112,80,196,192,156,194,192,147,152,151,159,146,234,144,158,95,148,148,152,206,12,84,228,200,0,5,0,46,116,21,208},
- 69},
- {{131,104,4,110,9,0,28,199,241,98,116,219,231,23,24,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,6,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,66,0,0,0,0,0,0,0,0},
- 77,
- {131,80,0,0,0,76,120,156,203,96,201,227,100,144,57,254,49,169,228,246,115,113,137,164,255,255,131,82,50,24,177,195,68,182,34,6,230,20,6,158,196,188,252,148,84,135,244,252,162,164,196,116,102,6,6,6,39,6,40,0,0,155,123,19,203},
- 65},
- {{131,104,4,110,7,0,28,199,59,73,56,148,1,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,7,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,67,0,0,0,0,0,0,0,0},
- 75,
- {131,80,0,0,0,74,120,156,203,96,201,99,103,144,57,110,237,105,49,133,49,233,255,255,160,148,12,70,236,48,145,189,136,129,57,133,129,39,49,47,63,37,213,33,61,191,40,41,49,157,153,129,129,193,153,1,10,0,245,21,17,100},
- 62},
- {{131,104,4,110,8,0,28,199,17,175,172,214,173,61,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,8,114,0,3,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,3,0,0,0,68,0,0,0,0,0,0,0,0},
- 76,
- {131,80,0,0,0,75,120,156,203,96,201,227,96,144,57,46,184,126,205,181,181,182,73,255,255,7,165,100,48,98,135,137,28,69,12,204,41,12,60,137,121,249,41,169,14,233,249,69,73,137,233,204,12,12,12,46,12,80,0,0,112,226,19,66},
- 64}
+ {{131,104,4,110,8,0,28,199,17,175,172,214,173,61,98,255,255,82,100,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,97,8,114,0,3,100,0,19,107,97,108,108,101,64,101,108,120,51,52,104,110,121,50,50,45,49,98,3,0,0,0,65,0,0,0,3,0,0,0,0},
+ 83,
+ {131,80,0,0,0,82,120,156,203,96,201,227,96,144,57,46,184,126,205,181,181,182,73,255,255,7,165,100,48,98,135,137,28,69,12,204,41,12,194,217,137,57,57,169,14,169,57,21,198,38,25,121,149,70,70,186,134,73,204,12,12,12,142,64,12,162,25,0,18,103,20,252},
+ 72},
+ {{131,116,0,0,0,0},
+ 6,
+ {131,116,0,0,0,0},
+ 6},
+ {{131,116,0,0,0,3,97,1,97,11,97,2,97,22,97,3,97,33},
+ 18,
+ {131,116,0,0,0,3,97,1,97,11,97,2,97,22,97,3,97,33},
+ 18},
+ {{131,116,0,0,0,100,97,48,98,0,0,2,16,97,62,98,0,0,2,170,97,11,97,121,97,39,98,0,0,1,173,97,83,98,0,0,3,145,97,63,98,0,0,2,181,97,34,98,0,0,1,118,97,68,98,0,0,2,236,97,26,98,0,0,1,30,97,78,98,0,0,3,90,97,52,98,0,0,2,60,97,15,97,165,97,64,98,0,0,2,192,97,75,98,0,0,3,57,97,81,98,0,0,3,123,97,71,98,0,0,3,13,97,20,97,220,97,50,98,0,0,2,38,97,17,97,187,97,25,98,0,0,1,19,97,65,98,0,0,2,203,97,98,98,0,0,4,54,97,79,98,0,0,3,101,97,13,97,143,97,44,98,0,0,1,228,97,8,97,88,97,99,98,0,0,4,65,97,36,98,0,0,1,140,97,67,98,0,0,2,225,97,7,97,77,97,66,98,0,0,2,214,97,85,98,0,0,3,167,97,76,98,0,0,3,68,97,1,97,11,97,32,98,0,0,1,96,97,69,98,0,0,2,247,97,37,98,0,0,1,151,97,35,98,0,0,1,129,97,84,98,0,0,3,156,97,3,97,33,97,82,98,0,0,3,134,97,45,98,0,0,1,239,97,55,98,0,0,2,93,97,6,97,66,97,2,97,22,97,94,98,0,0,4,10,97,49,98,0,0,2,27,97,41,98,0,0,1,195,97,91,98,0,0,3,233,97,87,98,0,0,3,189,97,33,98,0,0,1,107,97,42,98,0,0,1,206,97,74,98,0,0,3,46,97,60,98,0,0,2,148,97,43,98,0,0,1,217,97,10,97,110,97,70,98,0,0,3,2,97,9,97,99,97,72,98,0,0,3,24,97,86,98,0,0,3,178,97,19,97,209,97,56,98,0,0,2,104,97,95,98,0,0,4,21,97,57,98,0,0,2,115,97,51,98,0,0,2,49,97,14,97,154,97,5,97,55,97,54,98,0,0,2,82,97,18,97,198,97,61,98,0,0,2,159,97,31,98,0,0,1,85,97,22,97,242,97,29,98,0,0,1,63,97,97,98,0,0,4,43,97,21,97,231,97,89,98,0,0,3,211,97,27,98,0,0,1,41,97,24,98,0,0,1,8,97,47,98,0,0,2,5,97,100,98,0,0,4,76,97,40,98,0,0,1,184,97,96,98,0,0,4,32,97,73,98,0,0,3,35,97,90,98,0,0,3,222,97,30,98,0,0,1,74,97,58,98,0,0,2,126,97,80,98,0,0,3,112,97,88,98,0,0,3,200,97,59,98,0,0,2,137,97,77,98,0,0,3,79,97,23,97,253,97,28,98,0,0,1,52,97,46,98,0,0,1,250,97,92,98,0,0,3,244,97,53,98,0,0,2,71,97,93,98,0,0,3,255,97,16,97,176,97,38,98,0,0,1,162,97,4,97,44,97,12,97,132},
+ 637,
+ {131,80,0,0,2,124,120,156,21,143,123,100,87,113,24,135,207,126,219,218,165,86,171,109,181,182,118,107,181,181,123,171,181,181,218,90,91,91,171,93,90,91,173,221,219,158,93,24,145,40,145,49,70,98,140,68,68,70,196,196,136,137,24,137,136,68,68,70,140,68,68,34,34,35,34,117,158,191,158,247,115,121,223,239,57,55,130,32,152,228,224,120,16,68,146,57,33,150,217,204,45,10,195,49,234,41,23,66,68,223,163,193,224,57,123,53,111,210,172,250,65,134,42,155,115,86,6,169,210,172,99,27,75,156,116,124,69,187,65,45,221,98,134,86,145,68,42,159,56,100,94,192,118,94,176,219,27,41,52,234,188,99,60,68,76,53,93,86,167,72,226,46,165,230,95,137,167,159,9,195,70,246,233,44,112,202,141,47,196,209,73,147,227,71,122,221,122,66,135,104,38,42,252,139,92,171,99,180,152,255,102,191,234,1,249,98,142,139,214,22,137,38,143,30,199,59,148,25,252,164,198,246,8,155,104,34,194,78,46,251,106,34,149,186,153,20,217,121,205,144,27,223,233,19,47,201,211,188,66,177,120,79,155,102,57,117,46,220,167,68,115,157,68,174,114,218,32,66,2,19,156,113,76,231,146,120,70,10,31,56,106,125,154,81,95,75,163,86,117,157,195,162,146,173,60,36,150,26,170,149,61,236,224,13,245,142,143,200,241,122,111,248,149,191,200,114,108,0,15,148,144,198,55,6,188,190,70,166,65,17,233,34,158,10,23,99,153,180,214,193,1,205,85,198,84,185,156,117,33,159,65,241,153,108,179,54,142,185,48,203,121,205,107,244,139,183,28,215,156,167,83,213,197,46,254,178,199,118,21,229,226,15,195,6,27,28,177,214,202,136,234,31,201,172,80,96,254,152,24,74,217,194,237,255,248,120,145,79},
+ 418}
};
-#define NO_OF_EXT_TERMS 19
+#define NO_OF_EXT_TERMS 22
#endif
diff --git a/erts/emulator/test/send_term_SUITE_data/send_term_drv.c b/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
index 381a4f20d5..abb13d4603 100644
--- a/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
+++ b/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/erts/emulator/test/sensitive_SUITE.erl b/erts/emulator/test/sensitive_SUITE.erl
index e073eab596..2e51712737 100644
--- a/erts/emulator/test/sensitive_SUITE.erl
+++ b/erts/emulator/test/sensitive_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/signal_SUITE.erl b/erts/emulator/test/signal_SUITE.erl
index 736dfe5b56..4aa690fb0f 100644
--- a/erts/emulator/test/signal_SUITE.erl
+++ b/erts/emulator/test/signal_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -515,12 +516,10 @@ repeat(Fun, N) when is_integer(N) ->
repeat(Fun, N-1).
start_node(Config) ->
- {A, B, C} = now(),
Name = list_to_atom(atom_to_list(?MODULE)
++ "-" ++ atom_to_list(?config(testcase, Config))
- ++ "-" ++ integer_to_list(A)
- ++ "-" ++ integer_to_list(B)
- ++ "-" ++ integer_to_list(C)),
+ ++ "-" ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-" ++ integer_to_list(erlang:unique_integer([positive]))),
Pa = filename:dirname(code:which(?MODULE)),
?t:start_node(Name, slave, [{args, "-pa " ++ Pa}]).
diff --git a/erts/emulator/test/smoke_test_SUITE.erl b/erts/emulator/test/smoke_test_SUITE.erl
index 10b7e16a74..5bb98e5ad9 100644
--- a/erts/emulator/test/smoke_test_SUITE.erl
+++ b/erts/emulator/test/smoke_test_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -167,16 +168,13 @@ start_node(Config) ->
start_node(Config, Args) when is_list(Config) ->
Pa = filename:dirname(code:which(?MODULE)),
- {A, B, C} = now(),
Name = list_to_atom(atom_to_list(?MODULE)
++ "-"
++ atom_to_list(?config(testcase, Config))
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ integer_to_list(erlang:system_time(seconds))
++ "-"
- ++ integer_to_list(C)),
+ ++ integer_to_list(erlang:unique_integer([positive]))),
Opts = [{args, "-pa "++Pa++" "++Args}],
?t:start_node(Name, slave, Opts).
diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl
index c428be6c5a..a6305d453c 100644
--- a/erts/emulator/test/statistics_SUITE.erl
+++ b/erts/emulator/test/statistics_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,7 +32,7 @@
run_queue_one/1,
scheduler_wall_time/1,
reductions/1, reductions_big/1, garbage_collection/1, io/1,
- badarg/1]).
+ badarg/1, run_queues_lengths_active_tasks/1]).
%% Internal exports.
@@ -53,7 +54,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[{group, wall_clock}, {group, runtime}, reductions,
reductions_big, {group, run_queue}, scheduler_wall_time,
- garbage_collection, io, badarg].
+ garbage_collection, io, badarg,
+ run_queues_lengths_active_tasks].
groups() ->
[{wall_clock, [],
@@ -308,7 +310,7 @@ scheduler_wall_time(Config) when is_list(Config) ->
try
Schedulers = erlang:system_info(schedulers_online),
%% Let testserver and everyone else finish their work
- timer:sleep(500),
+ timer:sleep(1500),
%% Empty load
EmptyLoad = get_load(),
{false, _} = {lists:any(fun(Load) -> Load > 50 end, EmptyLoad),EmptyLoad},
@@ -347,7 +349,7 @@ scheduler_wall_time(Config) when is_list(Config) ->
[exit(Pid, kill) || Pid <- [P1|HalfHogs++LastHogs]],
AfterLoad = get_load(),
- {false,_} = {lists:any(fun(Load) -> Load > 5 end, AfterLoad),AfterLoad},
+ {false,_} = {lists:any(fun(Load) -> Load > 25 end, AfterLoad),AfterLoad},
true = erlang:system_flag(scheduler_wall_time, false)
after
erlang:system_flag(scheduler_wall_time, false)
@@ -355,7 +357,7 @@ scheduler_wall_time(Config) when is_list(Config) ->
get_load() ->
Start = erlang:statistics(scheduler_wall_time),
- timer:sleep(500),
+ timer:sleep(1500),
End = erlang:statistics(scheduler_wall_time),
lists:reverse(lists:sort(load_percentage(lists:sort(Start),lists:sort(End)))).
@@ -408,3 +410,63 @@ badarg(Config) when is_list(Config) ->
?line case catch statistics(bad_atom) of
{'EXIT', {badarg, _}} -> ok
end.
+
+tok_loop() ->
+ tok_loop().
+
+run_queues_lengths_active_tasks(Config) ->
+ TokLoops = lists:map(fun (_) ->
+ spawn_opt(fun () ->
+ tok_loop()
+ end,
+ [link, {priority, low}])
+ end,
+ lists:seq(1,10)),
+
+ TRQLs0 = statistics(total_run_queue_lengths),
+ TATs0 = statistics(total_active_tasks),
+ true = is_integer(TRQLs0),
+ true = is_integer(TATs0),
+ true = TRQLs0 >= 0,
+ true = TATs0 >= 11,
+
+ NoScheds = erlang:system_info(schedulers),
+ RQLs0 = statistics(run_queue_lengths),
+ ATs0 = statistics(active_tasks),
+ NoScheds = length(RQLs0),
+ NoScheds = length(ATs0),
+ true = lists:sum(RQLs0) >= 0,
+ true = lists:sum(ATs0) >= 11,
+
+ SO = erlang:system_flag(schedulers_online, 1),
+
+ %% Give newly suspended schedulers some time to
+ %% migrate away work from their run queues...
+ receive after 1000 -> ok end,
+
+ TRQLs1 = statistics(total_run_queue_lengths),
+ TATs1 = statistics(total_active_tasks),
+ true = TRQLs1 >= 10,
+ true = TATs1 >= 11,
+ NoScheds = erlang:system_info(schedulers),
+
+ RQLs1 = statistics(run_queue_lengths),
+ ATs1 = statistics(active_tasks),
+ NoScheds = length(RQLs1),
+ NoScheds = length(ATs1),
+ TRQLs2 = lists:sum(RQLs1),
+ TATs2 = lists:sum(ATs1),
+ true = TRQLs2 >= 10,
+ true = TATs2 >= 11,
+ [TRQLs2|_] = RQLs1,
+ [TATs2|_] = ATs1,
+
+ erlang:system_flag(schedulers_online, SO),
+
+ lists:foreach(fun (P) ->
+ unlink(P),
+ exit(P, bang)
+ end,
+ TokLoops),
+
+ ok.
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index f959714be7..bee42c07d9 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -264,6 +265,37 @@ memory_test(_Config) ->
[]),
cmp_memory(MWs, "unlink procs"),
+ mem_workers_call(MWs,
+ fun () ->
+ lists:foreach(
+ fun (P) ->
+ Tmr = erlang:start_timer(1 bsl 34,
+ P,
+ hello),
+ Tmrs = case get('BIF_TMRS') of
+ undefined -> [];
+ Rs -> Rs
+ end,
+ true = is_reference(Tmr),
+ put('BIF_TMRS', [Tmr|Tmrs])
+ end, Ps)
+ end,
+ []),
+ cmp_memory(MWs, "start BIF timer procs"),
+
+ mem_workers_call(MWs,
+ fun () ->
+ lists:foreach(fun (Tmr) ->
+ true = is_reference(Tmr),
+ true = is_integer(erlang:cancel_timer(Tmr))
+ end, get('BIF_TMRS')),
+ put('BIF_TMRS', undefined),
+ garbage_collect()
+ end,
+ []),
+ erts_debug:set_internal_state(wait, deallocations),
+ cmp_memory(MWs, "cancel BIF timer procs"),
+
DMs = mem_workers_call(MWs,
fun () ->
lists:map(fun (P) ->
@@ -533,16 +565,13 @@ get_ets_limit(Config, EtsMax) ->
start_node(Config, Envs) when is_list(Config) ->
Pa = filename:dirname(code:which(?MODULE)),
- {A, B, C} = now(),
Name = list_to_atom(atom_to_list(?MODULE)
++ "-"
++ atom_to_list(?config(testcase, Config))
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ integer_to_list(erlang:system_time(seconds))
++ "-"
- ++ integer_to_list(C)),
+ ++ integer_to_list(erlang:unique_integer([positive]))),
?t:start_node(Name, peer, [{args, "-pa "++Pa}, {env, Envs}]).
stop_node(Node) ->
diff --git a/erts/emulator/test/system_profile_SUITE.erl b/erts/emulator/test/system_profile_SUITE.erl
index a387c08ef9..2ecb4a28a7 100644
--- a/erts/emulator/test/system_profile_SUITE.erl
+++ b/erts/emulator/test/system_profile_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -112,13 +113,27 @@ runnable_procs(suite) ->
runnable_procs(doc) ->
["Tests system_profiling with runnable_procs."];
runnable_procs(Config) when is_list(Config) ->
+ lists:foreach(fun (TsType) ->
+ Arg = case TsType of
+ no_timestamp ->
+ {timestamp, []};
+ _ ->
+ {TsType, [TsType]}
+ end,
+ do_runnable_procs(Arg),
+ receive after 1000 -> ok end
+ end,
+ [no_timestamp, timestamp, monotonic_timestamp,
+ strict_monotonic_timestamp]).
+
+do_runnable_procs({TsType, TsTypeFlag}) ->
Pid = start_profiler_process(),
% start a ring of processes
% FIXME: Set #laps and #nodes in config file
Nodes = 10,
Laps = 10,
Master = ring(Nodes),
- undefined = erlang:system_profile(Pid, [runnable_procs]),
+ undefined = erlang:system_profile(Pid, [runnable_procs]++TsTypeFlag),
% loop a message
ok = ring_message(Master, message, Laps),
Events = get_profiler_events(),
@@ -126,9 +141,9 @@ runnable_procs(Config) when is_list(Config) ->
erlang:system_profile(undefined, []),
put(master, Master),
put(laps, Laps),
- true = has_runnable_event(Events),
+ true = has_runnable_event(TsType, Events),
Pids = sort_events_by_pid(Events),
- ok = check_events(Pids),
+ ok = check_events(TsType, Pids),
erase(),
exit(Pid,kill),
ok.
@@ -138,8 +153,22 @@ runnable_ports(suite) ->
runnable_ports(doc) ->
["Tests system_profiling with runnable_port."];
runnable_ports(Config) when is_list(Config) ->
+ lists:foreach(fun (TsType) ->
+ Arg = case TsType of
+ no_timestamp ->
+ {timestamp, []};
+ _ ->
+ {TsType, [TsType]}
+ end,
+ do_runnable_ports(Arg, Config),
+ receive after 1000 -> ok end
+ end,
+ [no_timestamp, timestamp, monotonic_timestamp,
+ strict_monotonic_timestamp]).
+
+do_runnable_ports({TsType, TsTypeFlag}, Config) ->
Pid = start_profiler_process(),
- undefined = erlang:system_profile(Pid, [runnable_ports]),
+ undefined = erlang:system_profile(Pid, [runnable_ports]++TsTypeFlag),
EchoPid = echo(Config),
% FIXME: Set config to number_of_echos
Laps = 10,
@@ -148,9 +177,9 @@ runnable_ports(Config) when is_list(Config) ->
Events = get_profiler_events(),
kill_em_all = kill_echo(EchoPid),
erlang:system_profile(undefined, []),
- true = has_runnable_event(Events),
+ true = has_runnable_event(TsType, Events),
Pids = sort_events_by_pid(Events),
- ok = check_events(Pids),
+ ok = check_events(TsType, Pids),
erase(),
exit(Pid,kill),
ok.
@@ -165,8 +194,19 @@ scheduler(Config) when is_list(Config) ->
{_, 1} -> {skipped, "No need for scheduler test when only one scheduler online."};
_ ->
Nodes = 10,
- ok = check_block_system(Nodes),
- ok = check_multi_scheduling_block(Nodes)
+ lists:foreach(fun (TsType) ->
+ Arg = case TsType of
+ no_timestamp ->
+ {timestamp, []};
+ _ ->
+ {TsType, [TsType]}
+ end,
+ ok = check_block_system(Arg, Nodes),
+ ok = check_multi_scheduling_block(Arg, Nodes),
+ receive after 1000 -> ok end
+ end,
+ [no_timestamp, timestamp, monotonic_timestamp,
+ strict_monotonic_timestamp])
end.
% the profiler pid should not be profiled
@@ -194,9 +234,9 @@ dont_profile_profiler(Config) when is_list(Config) ->
%%% Check scheduler profiling
-check_multi_scheduling_block(Nodes) ->
+check_multi_scheduling_block({TsType, TsTypeFlag}, Nodes) ->
Pid = start_profiler_process(),
- undefined = erlang:system_profile(Pid, [scheduler]),
+ undefined = erlang:system_profile(Pid, [scheduler]++TsTypeFlag),
{ok, Supervisor} = start_load(Nodes),
wait(600),
erlang:system_flag(multi_scheduling, block),
@@ -204,23 +244,23 @@ check_multi_scheduling_block(Nodes) ->
erlang:system_flag(multi_scheduling, unblock),
{Pid, [scheduler]} = erlang:system_profile(undefined, []),
Events = get_profiler_events(),
- true = has_scheduler_event(Events),
+ true = has_scheduler_event(TsType, Events),
stop_load(Supervisor),
exit(Pid,kill),
erase(),
ok.
-check_block_system(Nodes) ->
+check_block_system({TsType, TsTypeFlag}, Nodes) ->
Dummy = spawn(?MODULE, profiler_process, [[]]),
Pid = start_profiler_process(),
- undefined = erlang:system_profile(Pid, [scheduler]),
+ undefined = erlang:system_profile(Pid, [scheduler]++TsTypeFlag),
{ok, Supervisor} = start_load(Nodes),
wait(300),
undefined = erlang:system_monitor(Dummy, [busy_port]),
{Dummy, [busy_port]} = erlang:system_monitor(undefined, []),
{Pid, [scheduler]} = erlang:system_profile(undefined, []),
Events = get_profiler_events(),
- true = has_scheduler_event(Events),
+ true = has_scheduler_event(TsType, Events),
stop_load(Supervisor),
exit(Pid,kill),
exit(Dummy,kill),
@@ -229,40 +269,49 @@ check_block_system(Nodes) ->
%%% Check events
-check_events([]) -> ok;
-check_events([Pid | Pids]) ->
+check_events(_TsType, []) -> ok;
+check_events(TsType, [Pid | Pids]) ->
Master = get(master),
Laps = get(laps),
CheckPids = get(pids),
{Events, N} = get_pid_events(Pid),
ok = check_event_flow(Events),
- ok = check_event_ts(Events),
+ ok = check_event_ts(TsType, Events),
IsMember = lists:member(Pid, CheckPids),
case Pid of
Master ->
io:format("Expected ~p and got ~p profile events from ~p: ok~n", [Laps*2+2, N, Pid]),
N = Laps*2 + 2,
- check_events(Pids);
+ check_events(TsType, Pids);
Pid when IsMember == true ->
io:format("Expected ~p and got ~p profile events from ~p: ok~n", [Laps*2, N, Pid]),
N = Laps*2,
- check_events(Pids);
+ check_events(TsType, Pids);
Pid ->
- check_events(Pids)
+ check_events(TsType, Pids)
end.
%% timestamp consistency check for descending timestamps
-check_event_ts(Events) ->
- check_event_ts(Events, undefined).
-check_event_ts([], _) -> ok;
-check_event_ts([Event | Events], undefined) ->
- check_event_ts(Events, Event);
-check_event_ts([{Pid, _, _, TS1}=Event | Events], {Pid,_,_,TS0}) ->
- Time = timer:now_diff(TS1, TS0),
+check_event_ts(TsType, Events) ->
+ check_event_ts(TsType, Events, undefined).
+check_event_ts(_TsType, [], _) -> ok;
+check_event_ts(TsType, [Event | Events], undefined) ->
+ check_event_ts(TsType, Events, Event);
+check_event_ts(TsType, [{Pid, _, _, TS1}=Event | Events], {Pid,_,_,TS0}) ->
+ Time = case TsType of
+ timestamp ->
+ timer:now_diff(TS1, TS0);
+ monotonic_timestamp ->
+ TS1 - TS0;
+ strict_monotonic_timestamp ->
+ {MT1, _} = TS1,
+ {MT0, _} = TS0,
+ MT1 - MT0
+ end,
if
Time < 0.0 -> timestamp_error;
- true -> check_event_ts(Events, Event)
+ true -> check_event_ts(TsType, Events, Event)
end.
%% consistency check for active vs. inactive activity (runnable)
@@ -427,6 +476,44 @@ port_echo_loop(Port) ->
%% Helpers
%%%
+check_ts(no_timestamp, Ts) ->
+ try
+ no_timestamp = Ts
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok;
+check_ts(timestamp, Ts) ->
+ try
+ {Ms,S,Us} = Ts,
+ true = is_integer(Ms),
+ true = is_integer(S),
+ true = is_integer(Us)
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok;
+check_ts(monotonic_timestamp, Ts) ->
+ try
+ true = is_integer(Ts)
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok;
+check_ts(strict_monotonic_timestamp, Ts) ->
+ try
+ {MT, UMI} = Ts,
+ true = is_integer(MT),
+ true = is_integer(UMI)
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok.
+
start_load(N) ->
Pid = spawn_link(?MODULE, run_load, [N, []]),
{ok, Pid}.
@@ -453,21 +540,24 @@ list_load() ->
end,
list_load().
-
-has_scheduler_event(Events) ->
+has_scheduler_event(TsType, Events) ->
lists:any(
fun (Pred) ->
case Pred of
- {profile, scheduler, _ID, _Activity, _NR, _TS} -> true;
+ {profile, scheduler, _ID, _Activity, _NR, TS} ->
+ check_ts(TsType, TS),
+ true;
_ -> false
end
end, Events).
-has_runnable_event(Events) ->
+has_runnable_event(TsType, Events) ->
lists:any(
fun (Pred) ->
case Pred of
- {profile, _Pid, _Activity, _MFA, _TS} -> true;
+ {profile, _Pid, _Activity, _MFA, TS} ->
+ check_ts(TsType, TS),
+ true;
_ -> false
end
end, Events).
diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl
index a0a8a9c42c..787870588d 100644
--- a/erts/emulator/test/time_SUITE.erl
+++ b/erts/emulator/test/time_SUITE.erl
@@ -3,21 +3,23 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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(time_SUITE).
+-compile({nowarn_deprecated_function, {erlang,now,0}}).
%% "Time is on my side." -- The Rolling Stones
@@ -34,7 +36,15 @@
bad_univ_to_local/1, bad_local_to_univ/1,
univ_to_seconds/1, seconds_to_univ/1,
consistency/1,
- now_unique/1, now_update/1, timestamp/1]).
+ now_unique/1, now_update/1, timestamp/1,
+ time_warp_modes/1,
+ monotonic_time_monotonicity/1,
+ monotonic_time_monotonicity_parallel/1,
+ time_unit_conversion/1,
+ signed_time_unit_conversion/1,
+ erlang_timestamp/1]).
+
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([local_to_univ_utc/1]).
@@ -56,6 +66,12 @@
-define(dst_timezone, 2).
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ [{testcase, Func}|Config].
+
+end_per_testcase(_Func, Config) ->
+ ok.
+
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
@@ -63,7 +79,13 @@ all() ->
bad_univ_to_local, bad_local_to_univ,
univ_to_seconds, seconds_to_univ,
consistency,
- {group, now}, timestamp].
+ {group, now}, timestamp,
+ time_warp_modes,
+ monotonic_time_monotonicity,
+ monotonic_time_monotonicity_parallel,
+ time_unit_conversion,
+ signed_time_unit_conversion,
+ erlang_timestamp].
groups() ->
[{now, [], [now_unique, now_update]}].
@@ -298,7 +320,41 @@ timestamp(suite) ->
timestamp(doc) ->
["Test that os:timestamp works."];
timestamp(Config) when is_list(Config) ->
- repeating_timestamp_check(100000).
+ try
+ repeating_timestamp_check(100000)
+ catch
+ throw : {fail, Failure} ->
+ %%
+ %% Our time warping test machines currently warps
+ %% time every 6:th second. If we get a warp during
+ %% 10 seconds, assume this is a time warping test
+ %% and ignore the failure.
+ %%
+ case had_time_warp(10) of
+ true ->
+ {skip, "Seems to be time warp test run..."};
+ false ->
+ test_server:fail(Failure)
+ end
+ end.
+
+os_system_time_offset() ->
+ erlang:convert_time_unit(os:system_time() - erlang:monotonic_time(),
+ native, micro_seconds).
+
+had_time_warp(Secs) ->
+ had_time_warp(os_system_time_offset(), Secs).
+
+had_time_warp(OrigOffs, 0) ->
+ false;
+had_time_warp(OrigOffs, N) ->
+ receive after 1000 -> ok end,
+ case OrigOffs - os_system_time_offset() of
+ Diff when Diff > 500000; Diff < -500000 ->
+ true;
+ _Diff ->
+ had_time_warp(OrigOffs, N-1)
+ end.
repeating_timestamp_check(0) ->
ok;
@@ -324,15 +380,15 @@ repeating_timestamp_check(N) ->
NSecs = NA*1000000+NB+round(NC/1000000),
case Secs - NSecs of
TooLarge when TooLarge > 3600 ->
- test_server:fail(
- lists:flatten(
+ throw({fail,
+ lists:flatten(
io_lib:format("os:timestamp/0 is ~w s more than erlang:now/0",
- [TooLarge])));
+ [TooLarge]))});
TooSmall when TooSmall < -3600 ->
- test_server:fail(
+ throw({fail,
lists:flatten(
io_lib:format("os:timestamp/0 is ~w s less than erlang:now/0",
- [-TooSmall])));
+ [-TooSmall]))});
_ ->
ok
end,
@@ -420,6 +476,440 @@ now_update1(N) when N > 0 ->
now_update1(0) ->
?line test_server:fail().
+time_warp_modes(Config) when is_list(Config) ->
+ %% All time warp modes always supported in
+ %% combination with no time correction...
+ check_time_warp_mode(Config, false, no_time_warp),
+ check_time_warp_mode(Config, false, single_time_warp),
+ check_time_warp_mode(Config, false, multi_time_warp),
+
+ erts_debug:set_internal_state(available_internal_state, true),
+ try
+ case erts_debug:get_internal_state({check_time_config,
+ true, no_time_warp}) of
+ false -> ok;
+ true -> check_time_warp_mode(Config, true, no_time_warp)
+ end,
+ case erts_debug:get_internal_state({check_time_config,
+ true, single_time_warp}) of
+ false -> ok;
+ true -> check_time_warp_mode(Config, true, single_time_warp)
+ end,
+ case erts_debug:get_internal_state({check_time_config,
+ true, multi_time_warp}) of
+ false -> ok;
+ true -> check_time_warp_mode(Config, true, multi_time_warp)
+ end
+ after
+ erts_debug:set_internal_state(available_internal_state, false)
+ end.
+
+check_time_warp_mode(Config, TimeCorrection, TimeWarpMode) ->
+ io:format("~n~n~n***** Testing TimeCorrection=~p TimeWarpMode=~p *****~n",
+ [TimeCorrection, TimeWarpMode]),
+ Mon = erlang:monitor(time_offset, clock_service),
+ _ = erlang:time_offset(),
+ Start = erlang:monotonic_time(1000),
+ MonotonicityTimeout = 2000,
+ {ok, Node} = start_node(Config,
+ "+c " ++ atom_to_list(TimeCorrection)
+ ++ " +C " ++ atom_to_list(TimeWarpMode)),
+ StartTime = rpc:call(Node, erlang, system_info, [start_time]),
+ Me = self(),
+ MonotincityTestStarted = make_ref(),
+ MonotincityTestDone = make_ref(),
+ spawn_link(Node,
+ fun () ->
+ Me ! MonotincityTestStarted,
+ cmp_times(erlang:start_timer(MonotonicityTimeout,
+ self(),
+ timeout),
+ erlang:monotonic_time()),
+ Me ! MonotincityTestDone
+ end),
+ receive MonotincityTestStarted -> ok end,
+ check_time_offset(Node, TimeWarpMode),
+ TimeWarpMode = rpc:call(Node, erlang, system_info, [time_warp_mode]),
+ TimeCorrection = rpc:call(Node, erlang, system_info, [time_correction]),
+ receive MonotincityTestDone -> ok end,
+ MonotonicTime = rpc:call(Node, erlang, monotonic_time, []),
+ MonotonicTimeUnit = rpc:call(Node,
+ erlang,
+ convert_time_unit,
+ [1, seconds, native]),
+ UpMilliSeconds = erlang:convert_time_unit(MonotonicTime - StartTime,
+ MonotonicTimeUnit,
+ milli_seconds),
+ io:format("UpMilliSeconds=~p~n", [UpMilliSeconds]),
+ End = erlang:monotonic_time(milli_seconds),
+ stop_node(Node),
+ try
+ true = (UpMilliSeconds > (98*MonotonicityTimeout) div 100),
+ true = (UpMilliSeconds < (102*(End-Start)) div 100)
+ catch
+ error:_ ->
+ io:format("Uptime inconsistency", []),
+ case {TimeCorrection, erlang:system_info(time_correction)} of
+ {true, true} ->
+ ?t:fail(uptime_inconsistency);
+ {true, false} ->
+ _ = erlang:time_offset(),
+ receive
+ {'CHANGE', Mon, time_offset, clock_service, _} ->
+ ignore
+ after 1000 ->
+ ?t:fail(uptime_inconsistency)
+ end;
+ _ ->
+ ignore
+ end
+ end,
+ erlang:demonitor(Mon, [flush]),
+ ok.
+
+check_time_offset(Node, no_time_warp) ->
+ final = rpc:call(Node, erlang, system_info, [time_offset]),
+ final = rpc:call(Node, erlang, system_flag, [time_offset, finalize]),
+ final = rpc:call(Node, erlang, system_info, [time_offset]);
+check_time_offset(Node, single_time_warp) ->
+ preliminary = rpc:call(Node, erlang, system_info, [time_offset]),
+ preliminary = rpc:call(Node, erlang, system_flag, [time_offset, finalize]),
+ final = rpc:call(Node, erlang, system_info, [time_offset]),
+ final = rpc:call(Node, erlang, system_flag, [time_offset, finalize]);
+check_time_offset(Node, multi_time_warp) ->
+ volatile = rpc:call(Node, erlang, system_info, [time_offset]),
+ volatile = rpc:call(Node, erlang, system_flag, [time_offset, finalize]),
+ volatile = rpc:call(Node, erlang, system_info, [time_offset]).
+
+monotonic_time_monotonicity(Config) when is_list(Config) ->
+ Done = erlang:start_timer(10000,self(),timeout),
+ cmp_times(Done, erlang:monotonic_time()).
+
+cmp_times(Done, X0) ->
+ X1 = erlang:monotonic_time(),
+ X2 = erlang:monotonic_time(),
+ X3 = erlang:monotonic_time(),
+ X4 = erlang:monotonic_time(),
+ X5 = erlang:monotonic_time(),
+ true = (X0 =< X1),
+ true = (X1 =< X2),
+ true = (X2 =< X3),
+ true = (X3 =< X4),
+ true = (X4 =< X5),
+ receive
+ {timeout, Done, timeout} ->
+ ok
+ after 0 ->
+ cmp_times(Done, X5)
+ end.
+
+-define(NR_OF_MONOTONIC_CALLS, 100000).
+
+monotonic_time_monotonicity_parallel(Config) when is_list(Config) ->
+ Me = self(),
+ Result = make_ref(),
+ Go = make_ref(),
+ UpAndRunning = make_ref(),
+ NoOnlnScheds = erlang:system_info(schedulers_online),
+ OffsetUI = erlang:unique_integer([monotonic]),
+ OffsetMT = erlang:monotonic_time(),
+ MinHSz = ?NR_OF_MONOTONIC_CALLS*(2
+ + 3
+ + erts_debug:flat_size(OffsetUI)
+ + erts_debug:flat_size(OffsetMT)),
+ Ps = lists:map(
+ fun (Sched) ->
+ spawn_opt(
+ fun () ->
+ Me ! {self(), UpAndRunning},
+ receive Go -> ok end,
+ Res = fetch_monotonic(?NR_OF_MONOTONIC_CALLS, []),
+ Me ! {self(), Result, Sched, Res}
+ end,
+ [{scheduler, Sched},
+ {priority, max},
+ {min_heap_size, MinHSz}])
+ end,
+ lists:seq(1, NoOnlnScheds)),
+ lists:foreach(fun (P) -> receive {P, UpAndRunning} -> ok end end, Ps),
+ lists:foreach(fun (P) -> P ! Go end, Ps),
+ TMs = recv_monotonics(Result, OffsetMT, OffsetUI, NoOnlnScheds, []),
+ true = check_monotonic_result(TMs, OffsetMT, OffsetUI, true).
+
+check_monotonic_result([{_Sched, _PrevUI, _MT, _PostUI}],
+ _OffsetMT, _OffsetUI, Res) ->
+ Res;
+check_monotonic_result([{_ASched, _APrevUI, AMT, APostUI} = A,
+ {_BSched, BPrevUI, BMT, _BPostUI} = B | _] = L,
+ OffsetMT, OffsetUI, Res) ->
+ NewRes = case (AMT =< BMT) orelse (BPrevUI < APostUI) of
+ true ->
+ Res;
+ false ->
+ io:format("INCONSISTENCY: ~p ~p~n", [A, B]),
+ false
+ end,
+ check_monotonic_result(tl(L), OffsetMT, OffsetUI, NewRes).
+
+recv_monotonics(_Result, _OffsetMT, _OffsetUI, 0, Acc) ->
+ lists:keysort(2, Acc);
+recv_monotonics(Result, OffsetMT, OffsetUI, N, Acc) ->
+ receive
+ {_, Result, Sched, Res} ->
+ CRes = convert_monotonic(Sched, OffsetMT, OffsetUI, Res, []),
+ recv_monotonics(Result, OffsetMT, OffsetUI, N-1, CRes ++ Acc)
+ end.
+
+convert_monotonic(_Sched, _OffsetMT, _OffsetUI, [{_MT, _UI}], Acc) ->
+ Acc;
+convert_monotonic(Sched, OffsetMT, OffsetUI,
+ [{MT, UI}, {_PrevMT, PrevUI} | _] = L, Acc) ->
+ convert_monotonic(Sched, OffsetMT, OffsetUI, tl(L),
+ [{Sched, PrevUI-OffsetUI, MT-OffsetMT, UI-OffsetUI}
+ | Acc]).
+
+fetch_monotonic(0, Acc) ->
+ Acc;
+fetch_monotonic(N, Acc) ->
+ MT = erlang:monotonic_time(),
+ UI = erlang:unique_integer([monotonic]),
+ fetch_monotonic(N-1, [{MT, UI} | Acc]).
+
+-define(CHK_RES_CONVS_TIMEOUT, 400).
+
+time_unit_conversion(Config) when is_list(Config) ->
+ Mon = erlang:monitor(time_offset, clock_service),
+ start_check_res_convs(Mon, 1000000000000),
+ start_check_res_convs(Mon, 2333333333333),
+ start_check_res_convs(Mon, 5732678356789),
+ erlang:demonitor(Mon, [flush]).
+
+start_check_res_convs(Mon, Res) ->
+ io:format("Checking ~p time_unit~n", [Res]),
+ check_res_convs(Mon,
+ erlang:start_timer(?CHK_RES_CONVS_TIMEOUT,
+ self(),
+ timeout),
+ Res).
+
+
+check_res_convs(Mon, Done, Res) ->
+ receive
+ {timeout, Done, timeout} ->
+ case Res div 10 of
+ 0 ->
+ ok;
+ NewRes ->
+ start_check_res_convs(Mon, NewRes)
+ end
+ after 0 ->
+ do_check_res_convs(Mon, Done, Res)
+ end.
+
+do_check_res_convs(Mon, Done, Res) ->
+ TStart = erlang:monotonic_time(),
+ T = erlang:monotonic_time(Res),
+ TEnd = erlang:monotonic_time(),
+ TMin = erlang:convert_time_unit(TStart, native, Res),
+ TMax = erlang:convert_time_unit(TEnd, native, Res),
+ %io:format("~p =< ~p =< ~p~n", [TMin, T, TEnd]),
+ true = (TMin =< T),
+ true = (TMax >= T),
+ check_time_offset_res_conv(Mon, Res),
+ check_res_convs(Mon, Done, Res).
+
+
+check_time_offset_res_conv(Mon, Res) ->
+ TORes = erlang:time_offset(Res),
+ TO = erlang:time_offset(),
+ case erlang:convert_time_unit(TO, native, Res) of
+ TORes ->
+ ok;
+ TORes2 ->
+ case check_time_offset_change(Mon, TO, 1000) of
+ {TO, false} ->
+ ?t:fail({time_unit_conversion_inconsistency,
+ TO, TORes, TORes2});
+ {_NewTO, true} ->
+ ?t:format("time_offset changed", []),
+ check_time_offset_res_conv(Mon, Res)
+ end
+ end.
+
+signed_time_unit_conversion(Config) when is_list(Config) ->
+ chk_strc(1000000000, 1000000),
+ chk_strc(1000000000, 1000),
+ chk_strc(1000000000, 1),
+ chk_strc(1000000, 1000),
+ chk_strc(1000000, 1),
+ chk_strc(1000, 1),
+ chk_strc(4711, 17),
+ chk_strc(1 bsl 10, 1),
+ chk_strc(1 bsl 16, 10),
+ chk_strc(1 bsl 17, 1 bsl 8),
+ chk_strc((1 bsl 17) + 1, (1 bsl 8) - 1),
+ chk_strc(1 bsl 17, 11),
+ ok.
+
+chk_strc(Res0, Res1) ->
+ case (Res0 /= Res1) andalso (Res0 =< 1000000) andalso (Res1 =< 1000000) of
+ true ->
+ {FromRes, ToRes} = case Res0 > Res1 of
+ true -> {Res0, Res1};
+ false -> {Res1, Res0}
+ end,
+ MinFromValuesPerToValue = FromRes div ToRes,
+ MaxFromValuesPerToValue = ((FromRes-1) div ToRes)+1,
+ io:format("~p -> ~p [~p, ~p]~n",
+ [FromRes, ToRes,
+ MinFromValuesPerToValue, MaxFromValuesPerToValue]),
+ chk_values_per_value(FromRes, ToRes,
+ -10*FromRes, 10*FromRes,
+ MinFromValuesPerToValue,
+ MaxFromValuesPerToValue,
+ undefined, MinFromValuesPerToValue);
+ _ ->
+ ok
+ end,
+ chk_random_values(Res0, Res1),
+ chk_random_values(Res1, Res0),
+ ok.
+
+chk_random_values(FR, TR) ->
+% case (FR rem TR == 0) orelse (TR rem FR == 0) of
+% true ->
+ io:format("rand values ~p -> ~p~n", [FR, TR]),
+ random:seed(268438039, 268440479, 268439161),
+ Values = lists:map(fun (_) -> random:uniform(1 bsl 65) - (1 bsl 64) end,
+ lists:seq(1, 100000)),
+ CheckFun = fun (V) ->
+ CV = erlang:convert_time_unit(V, FR, TR),
+ case {(FR*CV) div TR =< V,
+ (FR*(CV+1)) div TR >= V} of
+ {true, true} ->
+ ok;
+ Failure ->
+ ?t:fail({Failure, CV, V, FR, TR})
+ end
+ end,
+ lists:foreach(CheckFun, Values).%;
+% false -> ok
+% end.
+
+
+chk_values_per_value(_FromRes, _ToRes,
+ EndValue, EndValue,
+ MinFromValuesPerToValue, MaxFromValuesPerToValue,
+ _ToValue, FromValueCount) ->
+% io:format("~p [~p]~n", [EndValue, FromValueCount]),
+ case ((MinFromValuesPerToValue =< FromValueCount)
+ andalso (FromValueCount =< MaxFromValuesPerToValue)) of
+ false ->
+ ?t:fail({MinFromValuesPerToValue,
+ FromValueCount,
+ MaxFromValuesPerToValue});
+ true ->
+ ok
+ end;
+chk_values_per_value(FromRes, ToRes, Value, EndValue,
+ MinFromValuesPerToValue, MaxFromValuesPerToValue,
+ ToValue, FromValueCount) ->
+ case erlang:convert_time_unit(Value, FromRes, ToRes) of
+ ToValue ->
+ chk_values_per_value(FromRes, ToRes,
+ Value+1, EndValue,
+ MinFromValuesPerToValue,
+ MaxFromValuesPerToValue,
+ ToValue, FromValueCount+1);
+ NewToValue ->
+ case ((MinFromValuesPerToValue =< FromValueCount)
+ andalso (FromValueCount =< MaxFromValuesPerToValue)) of
+ false ->
+ ?t:fail({MinFromValuesPerToValue,
+ FromValueCount,
+ MaxFromValuesPerToValue});
+ true ->
+% io:format("~p -> ~p [~p]~n",
+% [Value, NewToValue, FromValueCount]),
+ chk_values_per_value(FromRes, ToRes,
+ Value+1, EndValue,
+ MinFromValuesPerToValue,
+ MaxFromValuesPerToValue,
+ NewToValue, 1)
+ end
+ end.
+
+erlang_timestamp(Config) when is_list(Config) ->
+ Mon = erlang:monitor(time_offset, clock_service),
+ {TO, _} = check_time_offset_change(Mon,
+ erlang:time_offset(),
+ 0),
+ Done = erlang:start_timer(10000,self(),timeout),
+ ok = check_erlang_timestamp(Done, Mon, TO).
+
+check_erlang_timestamp(Done, Mon, TO) ->
+ receive
+ {timeout, Done, timeout} ->
+ erlang:demonitor(Mon, [flush]),
+ ok
+ after 0 ->
+ do_check_erlang_timestamp(Done, Mon, TO)
+ end.
+
+do_check_erlang_timestamp(Done, Mon, TO) ->
+ MinMon = erlang:monotonic_time(),
+ {MegaSec, Sec, MicroSec} = erlang:timestamp(),
+ MaxMon = erlang:monotonic_time(),
+ TsMin = erlang:convert_time_unit(MinMon+TO,
+ native,
+ micro_seconds),
+ TsMax = erlang:convert_time_unit(MaxMon+TO,
+ native,
+ micro_seconds),
+ TsTime = (MegaSec*1000000+Sec)*1000000+MicroSec,
+ case (TsMin =< TsTime) andalso (TsTime =< TsMax) of
+ true ->
+ NewTO = case erlang:time_offset() of
+ TO ->
+ TO;
+ _ ->
+ check_time_offset_change(Mon, TO, 0)
+ end,
+ check_erlang_timestamp(Done, Mon, NewTO);
+ false ->
+ io:format("TsMin=~p TsTime=~p TsMax=~p~n", [TsMin, TsTime, TsMax]),
+ ?t:format("Detected inconsistency; "
+ "checking for time_offset change...", []),
+ case check_time_offset_change(Mon, TO, 1000) of
+ {TO, false} ->
+ ?t:fail(timestamp_inconsistency);
+ {NewTO, true} ->
+ ?t:format("time_offset changed", []),
+ check_erlang_timestamp(Done, Mon, NewTO)
+ end
+ end.
+
+check_time_offset_change(Mon, TO, Wait) ->
+ process_changed_time_offset(Mon, TO, false, Wait).
+
+process_changed_time_offset(Mon, TO, Changed, Wait) ->
+ receive
+ {'CHANGE', Mon, time_offset, clock_service, NewTO} ->
+ process_changed_time_offset(Mon, NewTO, true, Wait)
+ after Wait ->
+ case erlang:time_offset() of
+ TO ->
+ {TO, Changed};
+ _OtherTO ->
+ receive
+ {'CHANGE', Mon, time_offset, clock_service, NewTO} ->
+ process_changed_time_offset(Mon, NewTO, true, Wait)
+ end
+ end
+ end.
+
+
+
%% Returns the test data: a list of {Utc, Local} tuples.
test_data() ->
@@ -554,4 +1044,25 @@ bad_dates() ->
{{1996, 4, 30}, {12, 0, -1}}, % Sec
{{1996, 4, 30}, {12, 0, 60}}].
-
+
+start_node(Config) ->
+ start_node(Config, "").
+
+start_node(Config, Args) ->
+ TestCase = ?config(testcase, Config),
+ PA = filename:dirname(code:which(?MODULE)),
+ ESTime = erlang:monotonic_time(1) + erlang:time_offset(1),
+ Unique = erlang:unique_integer([positive]),
+ Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(TestCase)
+ ++ "-"
+ ++ integer_to_list(ESTime)
+ ++ "-"
+ ++ integer_to_list(Unique)),
+ test_server:start_node(Name,
+ slave,
+ [{args, "-pa " ++ PA ++ " " ++ Args}]).
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl
index c28224729d..51d59f09f3 100644
--- a/erts/emulator/test/timer_bif_SUITE.erl
+++ b/erts/emulator/test/timer_bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -26,11 +27,18 @@
cancel_timer_1/1,
start_timer_big/1, send_after_big/1,
start_timer_e/1, send_after_e/1, cancel_timer_e/1,
- read_timer_trivial/1, read_timer/1,
- cleanup/1, evil_timers/1, registered_process/1]).
+ read_timer_trivial/1, read_timer/1, read_timer_async/1,
+ cleanup/1, evil_timers/1, registered_process/1, same_time_yielding/1,
+ same_time_yielding_with_cancel/1, same_time_yielding_with_cancel_other/1,
+% same_time_yielding_with_cancel_other_accessor/1,
+ auto_cancel_yielding/1]).
-include_lib("test_server/include/test_server.hrl").
+-define(SHORT_TIMEOUT, 5000). %% Bif timers as short as this may be pre-allocated
+-define(TIMEOUT_YIELD_LIMIT, 100).
+-define(AUTO_CANCEL_YIELD_LIMIT, 100).
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:seconds(30)),
case catch erts_debug:get_internal_state(available_internal_state) of
@@ -45,6 +53,7 @@ end_per_testcase(_Case, Config) ->
ok.
init_per_suite(Config) ->
+ erts_debug:set_internal_state(available_internal_state, true),
Config.
end_per_suite(_Config) ->
@@ -56,8 +65,12 @@ all() ->
[start_timer_1, send_after_1, send_after_2,
cancel_timer_1, start_timer_e, send_after_e,
cancel_timer_e, start_timer_big, send_after_big,
- read_timer_trivial, read_timer, cleanup, evil_timers,
- registered_process].
+ read_timer_trivial, read_timer, read_timer_async,
+ cleanup, evil_timers, registered_process,
+ same_time_yielding, same_time_yielding_with_cancel,
+ same_time_yielding_with_cancel_other,
+% same_time_yielding_with_cancel_other_accessor,
+ auto_cancel_yielding].
groups() ->
[].
@@ -162,7 +175,7 @@ cancel_timer_1(Config) when is_list(Config) ->
start_timer_e(doc) -> ["Error cases for start_timer/3"];
start_timer_e(Config) when is_list(Config) ->
?line {'EXIT', _} = (catch erlang:start_timer(-4, self(), hej)),
- ?line {'EXIT', _} = (catch erlang:start_timer(4728472847827482,
+ ?line {'EXIT', _} = (catch erlang:start_timer(1 bsl 64,
self(), hej)),
?line {'EXIT', _} = (catch erlang:start_timer(4.5, self(), hej)),
@@ -180,7 +193,7 @@ send_after_e(doc) -> ["Error cases for send_after/3"];
send_after_e(suite) -> [];
send_after_e(Config) when is_list(Config) ->
?line {'EXIT', _} = (catch erlang:send_after(-4, self(), hej)),
- ?line {'EXIT', _} = (catch erlang:send_after(4728472847827482,
+ ?line {'EXIT', _} = (catch erlang:send_after(1 bsl 64,
self(), hej)),
?line {'EXIT', _} = (catch erlang:send_after(4.5, self(), hej)),
@@ -213,20 +226,58 @@ read_timer_trivial(Config) when is_list(Config) ->
read_timer(doc) -> ["Test that read_timer/1 seems to return the correct values."];
read_timer(suite) -> [];
read_timer(Config) when is_list(Config) ->
- ?line Big = 1 bsl 31,
- ?line R = erlang:send_after(Big, self(), hej_hopp),
+ process_flag(scheduler, 1),
+ Big = 1 bsl 31,
+ R = erlang:send_after(Big, self(), hej_hopp),
+
+ receive after 200 -> ok end, % Delay and clear reductions.
+ Left = erlang:read_timer(R),
+ Left2 = erlang:cancel_timer(R),
+ case Left == Left2 of
+ true -> ok;
+ false -> Left = Left2 + 1
+ end,
+ false = erlang:read_timer(R),
- ?line receive after 200 -> ok end, % Delay and clear reductions.
- ?line Left = erlang:read_timer(R),
- ?line Left = erlang:cancel_timer(R),
- ?line false = erlang:read_timer(R),
+ case Big - Left of
+ Diff when Diff >= 200, Diff < 10000 ->
+ ok;
+ _Diff ->
+ test_server:fail({big, Big, Left})
+ end,
+ process_flag(scheduler, 0),
+ ok.
- ?line case Big - Left of
- Diff when Diff >= 200, Diff < 10000 ->
- ok;
- _Diff ->
- test_server:fail({big, Big, Left})
- end,
+read_timer_async(doc) -> ["Test that read_timer/1 seems to return the correct values."];
+read_timer_async(suite) -> [];
+read_timer_async(Config) when is_list(Config) ->
+ process_flag(scheduler, 1),
+ Big = 1 bsl 33,
+ R = erlang:send_after(Big, self(), hej_hopp),
+
+ %% Access from another scheduler
+ process_flag(scheduler, erlang:system_info(schedulers_online)),
+
+ receive after 200 -> ok end, % Delay and clear reductions.
+ ok = erlang:read_timer(R, [{async, true}]),
+ ok = erlang:cancel_timer(R, [{async, true}, {info, true}]),
+ ok = erlang:read_timer(R, [{async, true}]),
+
+ {read_timer, R, Left} = receive_one(),
+ {cancel_timer, R, Left2} = receive_one(),
+ case Left == Left2 of
+ true -> ok;
+ false -> Left = Left2 + 1
+ end,
+ {read_timer, R, false} = receive_one(),
+
+ case Big - Left of
+ Diff when Diff >= 200, Diff < 10000 ->
+ ok;
+ _Diff ->
+ test_server:fail({big, Big, Left})
+ end,
+ process_flag(scheduler, 0),
ok.
cleanup(doc) -> [];
@@ -236,39 +287,42 @@ cleanup(Config) when is_list(Config) ->
%% Timer on dead process
?line P1 = spawn(fun () -> ok end),
?line wait_until(fun () -> process_is_cleaned_up(P1) end),
- ?line T1 = erlang:start_timer(10000, P1, "hej"),
- ?line T2 = erlang:send_after(10000, P1, "hej"),
+ ?line T1 = erlang:start_timer(?SHORT_TIMEOUT*2, P1, "hej"),
+ ?line T2 = erlang:send_after(?SHORT_TIMEOUT*2, P1, "hej"),
+ receive after 1000 -> ok end,
?line Mem = mem(),
?line false = erlang:read_timer(T1),
?line false = erlang:read_timer(T2),
?line Mem = mem(),
%% Process dies before timeout
- ?line P2 = spawn(fun () -> receive after 500 -> ok end end),
- ?line T3 = erlang:start_timer(10000, P2, "hej"),
- ?line T4 = erlang:send_after(10000, P2, "hej"),
- ?line true = Mem < mem(),
+ ?line P2 = spawn(fun () -> receive after (?SHORT_TIMEOUT div 10) -> ok end end),
+ ?line T3 = erlang:start_timer(?SHORT_TIMEOUT*2, P2, "hej"),
+ ?line T4 = erlang:send_after(?SHORT_TIMEOUT*2, P2, "hej"),
+ ?line true = mem_larger_than(Mem),
?line true = is_integer(erlang:read_timer(T3)),
?line true = is_integer(erlang:read_timer(T4)),
?line wait_until(fun () -> process_is_cleaned_up(P2) end),
+ receive after 1000 -> ok end,
?line false = erlang:read_timer(T3),
?line false = erlang:read_timer(T4),
?line Mem = mem(),
%% Cancel timer
- ?line P3 = spawn(fun () -> receive after 20000 -> ok end end),
- ?line T5 = erlang:start_timer(10000, P3, "hej"),
- ?line T6 = erlang:send_after(10000, P3, "hej"),
- ?line true = Mem < mem(),
+ ?line P3 = spawn(fun () -> receive after ?SHORT_TIMEOUT*4 -> ok end end),
+ ?line T5 = erlang:start_timer(?SHORT_TIMEOUT*2, P3, "hej"),
+ ?line T6 = erlang:send_after(?SHORT_TIMEOUT*2, P3, "hej"),
+ ?line true = mem_larger_than(Mem),
?line true = is_integer(erlang:cancel_timer(T5)),
?line true = is_integer(erlang:cancel_timer(T6)),
?line false = erlang:read_timer(T5),
?line false = erlang:read_timer(T6),
?line exit(P3, kill),
+ ?line wait_until(fun () -> process_is_cleaned_up(P3) end),
?line Mem = mem(),
%% Timeout
?line Ref = make_ref(),
- ?line T7 = erlang:start_timer(500, self(), Ref),
- ?line T8 = erlang:send_after(500, self(), Ref),
- ?line true = Mem < mem(),
+ ?line T7 = erlang:start_timer(?SHORT_TIMEOUT+1, self(), Ref),
+ ?line T8 = erlang:send_after(?SHORT_TIMEOUT+1, self(), Ref),
+ ?line true = mem_larger_than(Mem),
?line true = is_integer(erlang:read_timer(T7)),
?line true = is_integer(erlang:read_timer(T8)),
?line receive {timeout, T7, Ref} -> ok end,
@@ -420,10 +474,10 @@ registered_process(suite) -> [];
registered_process(Config) when is_list(Config) ->
?line Mem = mem(),
%% Cancel
- ?line T1 = erlang:start_timer(500, ?MODULE, "hej"),
- ?line T2 = erlang:send_after(500, ?MODULE, "hej"),
+ ?line T1 = erlang:start_timer(?SHORT_TIMEOUT+1, ?MODULE, "hej"),
+ ?line T2 = erlang:send_after(?SHORT_TIMEOUT+1, ?MODULE, "hej"),
?line undefined = whereis(?MODULE),
- ?line true = Mem < mem(),
+ ?line true = mem_larger_than(Mem),
?line true = is_integer(erlang:cancel_timer(T1)),
?line true = is_integer(erlang:cancel_timer(T2)),
?line false = erlang:read_timer(T1),
@@ -431,10 +485,10 @@ registered_process(Config) when is_list(Config) ->
?line Mem = mem(),
%% Timeout register after start
?line Ref1 = make_ref(),
- ?line T3 = erlang:start_timer(500, ?MODULE, Ref1),
- ?line T4 = erlang:send_after(500, ?MODULE, Ref1),
+ ?line T3 = erlang:start_timer(?SHORT_TIMEOUT+1, ?MODULE, Ref1),
+ ?line T4 = erlang:send_after(?SHORT_TIMEOUT+1, ?MODULE, Ref1),
?line undefined = whereis(?MODULE),
- ?line true = Mem < mem(),
+ ?line true = mem_larger_than(Mem),
?line true = is_integer(erlang:read_timer(T3)),
?line true = is_integer(erlang:read_timer(T4)),
?line true = register(?MODULE, self()),
@@ -443,9 +497,9 @@ registered_process(Config) when is_list(Config) ->
?line Mem = mem(),
%% Timeout register before start
?line Ref2 = make_ref(),
- ?line T5 = erlang:start_timer(500, ?MODULE, Ref2),
- ?line T6 = erlang:send_after(500, ?MODULE, Ref2),
- ?line true = Mem < mem(),
+ ?line T5 = erlang:start_timer(?SHORT_TIMEOUT+1, ?MODULE, Ref2),
+ ?line T6 = erlang:send_after(?SHORT_TIMEOUT+1, ?MODULE, Ref2),
+ ?line true = mem_larger_than(Mem),
?line true = is_integer(erlang:read_timer(T5)),
?line true = is_integer(erlang:read_timer(T6)),
?line receive {timeout, T5, Ref2} -> ok end,
@@ -454,10 +508,133 @@ registered_process(Config) when is_list(Config) ->
?line true = unregister(?MODULE),
?line ok.
-mem() ->
- AA = erlang:system_info(allocated_areas),
- {value,{bif_timer,Mem}} = lists:keysearch(bif_timer, 1, AA),
- Mem.
+same_time_yielding(Config) when is_list(Config) ->
+ Mem = mem(),
+ SchdlrsOnln = erlang:system_info(schedulers_online),
+ Tmo = erlang:monotonic_time(milli_seconds) + 3000,
+ Tmrs = lists:map(fun (I) ->
+ process_flag(scheduler, (I rem SchdlrsOnln) + 1),
+ erlang:start_timer(Tmo, self(), hej, [{abs, true}])
+ end,
+ lists:seq(1, (?TIMEOUT_YIELD_LIMIT*3+1)*SchdlrsOnln)),
+ true = mem_larger_than(Mem),
+ lists:foreach(fun (Tmr) -> receive {timeout, Tmr, hej} -> ok end end, Tmrs),
+ Done = erlang:monotonic_time(milli_seconds),
+ true = Done >= Tmo,
+ case erlang:system_info(build_type) of
+ opt -> true = Done < Tmo + 200;
+ _ -> true = Done < Tmo + 1000
+ end,
+ Mem = mem(),
+ ok.
+
+same_time_yielding_with_cancel(Config) when is_list(Config) ->
+ same_time_yielding_with_cancel_test(false, false).
+
+same_time_yielding_with_cancel_other(Config) when is_list(Config) ->
+ same_time_yielding_with_cancel_test(true, false).
+
+%same_time_yielding_with_cancel_other_accessor(Config) when is_list(Config) ->
+% same_time_yielding_with_cancel_test(true, true).
+
+do_cancel_tmrs(Tmo, Tmrs, Tester) ->
+ BeginCancel = erlang:convert_time_unit(Tmo,
+ milli_seconds,
+ micro_seconds) - 100,
+ busy_wait_until(fun () ->
+ erlang:monotonic_time(micro_seconds) >= BeginCancel
+ end),
+ lists:foreach(fun (Tmr) ->
+ erlang:cancel_timer(Tmr,
+ [{async, true},
+ {info, true}])
+ end, Tmrs),
+ case Tester == self() of
+ true -> ok;
+ false -> forward_msgs(Tester)
+ end.
+
+same_time_yielding_with_cancel_test(Other, Accessor) ->
+ Mem = mem(),
+ SchdlrsOnln = erlang:system_info(schedulers_online),
+ Tmo = erlang:monotonic_time(milli_seconds) + 3000,
+ Tester = self(),
+ Cancelor = case Other of
+ false ->
+ Tester;
+ true ->
+ spawn(fun () ->
+ receive
+ {timers, Tmrs} ->
+ do_cancel_tmrs(Tmo, Tmrs, Tester)
+ end
+ end)
+ end,
+ Opts = case Accessor of
+ false -> [{abs, true}];
+ true -> [{accessor, Cancelor}, {abs, true}]
+ end,
+ Tmrs = lists:map(fun (I) ->
+ process_flag(scheduler, (I rem SchdlrsOnln) + 1),
+ erlang:start_timer(Tmo, self(), hej, Opts)
+ end,
+ lists:seq(1, (?TIMEOUT_YIELD_LIMIT*3+1)*SchdlrsOnln)),
+ true = mem_larger_than(Mem),
+ case Other of
+ false ->
+ do_cancel_tmrs(Tmo, Tmrs, Tester);
+ true ->
+ Cancelor ! {timers, Tmrs}
+ end,
+ {Tmos, Cncls} = lists:foldl(fun (Tmr, {T, C}) ->
+ receive
+ {timeout, Tmr, hej} ->
+ receive
+ {cancel_timer, Tmr, Info} ->
+ false = Info,
+ {T+1, C}
+ end;
+ {cancel_timer, Tmr, false} ->
+ receive
+ {timeout, Tmr, hej} ->
+ {T+1, C}
+ end;
+ {cancel_timer, Tmr, TimeLeft} ->
+ true = is_integer(TimeLeft),
+ {T, C+1}
+ end
+ end,
+ {0, 0},
+ Tmrs),
+ io:format("Timeouts: ~p Cancels: ~p~n", [Tmos, Cncls]),
+ Mem = mem(),
+ case Other of
+ true -> exit(Cancelor, bang);
+ false -> ok
+ end,
+ {comment,
+ "Timeouts: " ++ integer_to_list(Tmos) ++ " Cancels: "
+ ++ integer_to_list(Cncls)}.
+
+auto_cancel_yielding(Config) when is_list(Config) ->
+ Mem = mem(),
+ SchdlrsOnln = erlang:system_info(schedulers_online),
+ P = spawn(fun () ->
+ lists:foreach(
+ fun (I) ->
+ process_flag(scheduler, (I rem SchdlrsOnln)+1),
+ erlang:start_timer((1 bsl 28)+I*10, self(), hej)
+ end,
+ lists:seq(1,
+ ((?AUTO_CANCEL_YIELD_LIMIT*3+1)
+ *SchdlrsOnln))),
+ receive after infinity -> ok end
+ end),
+ true = mem_larger_than(Mem),
+ exit(P, bang),
+ wait_until(fun () -> process_is_cleaned_up(P) end),
+ Mem = mem(),
+ ok.
process_is_cleaned_up(P) when is_pid(P) ->
undefined == erts_debug:get_internal_state({process_status, P}).
@@ -468,6 +645,19 @@ wait_until(Pred) when is_function(Pred) ->
_ -> receive after 50 -> ok end, wait_until(Pred)
end.
+busy_wait_until(Pred) when is_function(Pred) ->
+ case catch Pred() of
+ true -> ok;
+ _ -> busy_wait_until(Pred)
+ end.
+
+forward_msgs(To) ->
+ receive
+ Msg ->
+ To ! Msg
+ end,
+ forward_msgs(To).
+
get(Time, Msg) ->
receive
Msg ->
@@ -486,9 +676,10 @@ get_msg() ->
end.
start_slave() ->
- ?line {A, B, C} = now(),
?line Pa = filename:dirname(code:which(?MODULE)),
- ?line Name = atom_to_list(?MODULE) ++ "-" ++ integer_to_list(A+B+C),
+ ?line Name = atom_to_list(?MODULE)
+ ++ "-" ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-" ++ integer_to_list(erlang:unique_integer([positive])),
{ok, Node} = ?t:start_node(Name, slave, [{args, "-pa " ++ Pa}]),
Node.
@@ -549,5 +740,58 @@ type(X) when is_port(X) -> {port, node(X)};
type(X) when is_binary(X) -> binary;
type(X) when is_atom(X) -> atom;
type(_) -> unknown.
-
+
+mem_larger_than(no_fix_alloc) ->
+ true;
+mem_larger_than(Mem) ->
+ mem() > Mem.
+
+mem() ->
+ erts_debug:set_internal_state(wait, timer_cancellations),
+ erts_debug:set_internal_state(wait, deallocations),
+ case mem_get() of
+ {-1, -1} -> no_fix_alloc;
+ {A, U} -> io:format("mem = ~p ~p~n", [A, U]), U
+ end.
+
+mem_get() ->
+ % Bif timer memory
+ Ref = make_ref(),
+ erlang:system_info({memory_internal, Ref, [fix_alloc]}),
+ mem_recv(erlang:system_info(schedulers), Ref, {0, 0}).
+
+mem_recv(0, _Ref, AU) ->
+ AU;
+mem_recv(N, Ref, AU) ->
+ receive
+ {Ref, _, IL} ->
+ mem_recv(N-1, Ref, mem_parse_ilists(IL, AU))
+ end.
+
+
+mem_parse_ilists([], AU) ->
+ AU;
+mem_parse_ilists([I|Is], AU) ->
+ mem_parse_ilists(Is, mem_parse_ilist(I, AU)).
+
+mem_parse_ilist({fix_alloc, false}, _) ->
+ {-1, -1};
+mem_parse_ilist({fix_alloc, _, IDL}, {A, U}) ->
+ case lists:keyfind(fix_types, 1, IDL) of
+ {fix_types, TL} ->
+ {ThisA, ThisU} = mem_get_btm_aus(TL, 0, 0),
+ {ThisA + A, ThisU + U};
+ {fix_types, Mask, TL} ->
+ {ThisA, ThisU} = mem_get_btm_aus(TL, 0, 0),
+ {(ThisA + A) band Mask , (ThisU + U) band Mask}
+ end.
+
+mem_get_btm_aus([], A, U) ->
+ {A, U};
+mem_get_btm_aus([{BtmType, BtmA, BtmU} | Types],
+ A, U) when BtmType == bif_timer;
+ BtmType == accessor_bif_timer ->
+ mem_get_btm_aus(Types, BtmA+A, BtmU+U);
+mem_get_btm_aus([_|Types], A, U) ->
+ mem_get_btm_aus(Types, A, U).
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 4d7598cf1f..6eae182e45 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/test/trace_bif_SUITE.erl b/erts/emulator/test/trace_bif_SUITE.erl
index 2c78aa394f..96b7dd159f 100644
--- a/erts/emulator/test/trace_bif_SUITE.erl
+++ b/erts/emulator/test/trace_bif_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -66,7 +67,8 @@ trace_on_and_off(Config) when is_list(Config) ->
?line Pid = spawn(?MODULE, bif_process, []),
?line Self = self(),
?line 1 = erlang:trace(Pid, true, [call,timestamp]),
- ?line {flags,[timestamp,call]} = erlang:trace_info(Pid,flags),
+ ?line {flags, Flags} = erlang:trace_info(Pid,flags),
+ ?line [call,timestamp] = lists:sort(Flags),
?line {tracer, Self} = erlang:trace_info(Pid,tracer),
?line 1 = erlang:trace(Pid, false, [timestamp]),
?line {flags,[call]} = erlang:trace_info(Pid,flags),
@@ -110,93 +112,145 @@ do_trace_bif(Flags) ->
trace_bif_timestamp(doc) -> "Test tracing BIFs with timestamps.";
trace_bif_timestamp(Config) when is_list(Config) ->
- do_trace_bif_timestamp([]).
-
+ do_trace_bif_timestamp([], timestamp, [timestamp]),
+ do_trace_bif_timestamp([], timestamp,
+ [timestamp,
+ monotonic_timestamp,
+ strict_monotonic_timestamp]),
+ do_trace_bif_timestamp([], strict_monotonic_timestamp,
+ [strict_monotonic_timestamp]),
+ do_trace_bif_timestamp([], strict_monotonic_timestamp,
+ [monotonic_timestamp, strict_monotonic_timestamp]),
+ do_trace_bif_timestamp([], monotonic_timestamp, [monotonic_timestamp]).
+
trace_bif_timestamp_local(doc) ->
"Test tracing BIFs with timestamps and local flag.";
trace_bif_timestamp_local(Config) when is_list(Config) ->
- do_trace_bif_timestamp([local]).
-
-do_trace_bif_timestamp(Flags) ->
- ?line Pid=spawn(?MODULE, bif_process, []),
- ?line 1 = erlang:trace(Pid, true, [call,timestamp]),
- ?line erlang:trace_pattern({erlang,'_','_'}, [], Flags),
-
- ?line Pid ! {do_bif, time, []},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}}),
-
- ?line Pid ! {do_bif, statistics, [runtime]},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,
- {erlang,statistics, [runtime]}}),
-
- ?line Pid ! {do_time_bif},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,
- {erlang,time, []}}),
-
- ?line Pid ! {do_statistics_bif},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,
- {erlang,statistics, [runtime]}}),
+ do_trace_bif_timestamp([local], timestamp, [timestamp]),
+ do_trace_bif_timestamp([local], timestamp,
+ [timestamp,
+ monotonic_timestamp,
+ strict_monotonic_timestamp]),
+ do_trace_bif_timestamp([local], strict_monotonic_timestamp,
+ [strict_monotonic_timestamp]),
+ do_trace_bif_timestamp([local], strict_monotonic_timestamp,
+ [monotonic_timestamp, strict_monotonic_timestamp]),
+ do_trace_bif_timestamp([local], monotonic_timestamp, [monotonic_timestamp]).
+
+do_trace_bif_timestamp(Flags, TsType, TsFlags) ->
+ io:format("Testing with TsType=~p TsFlags=~p~n", [TsType, TsFlags]),
+ Pid=spawn(?MODULE, bif_process, []),
+ 1 = erlang:trace(Pid, true, [call]++TsFlags),
+ erlang:trace_pattern({erlang,'_','_'}, [], Flags),
+
+ Ts0 = make_ts(TsType),
+ Pid ! {do_bif, time, []},
+ Ts1 = receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}},
+ Ts0,TsType),
+
+ Pid ! {do_bif, statistics, [runtime]},
+ Ts2 = receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}},
+ Ts1, TsType),
+
+ Pid ! {do_time_bif},
+ Ts3 = receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,time, []}},
+ Ts2, TsType),
+
+ Pid ! {do_statistics_bif},
+ Ts4 = receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}},
+ Ts3, TsType),
+
+ check_ts(TsType, Ts4, make_ts(TsType)),
%% We should be able to turn off the timestamp.
- ?line 1 = erlang:trace(Pid, false, [timestamp]),
+ 1 = erlang:trace(Pid, false, TsFlags),
- ?line Pid ! {do_statistics_bif},
- ?line receive_trace_msg({trace,Pid,call,
- {erlang,statistics, [runtime]}}),
+ Pid ! {do_statistics_bif},
+ receive_trace_msg({trace,Pid,call,
+ {erlang,statistics, [runtime]}}),
- ?line Pid ! {do_bif, statistics, [runtime]},
- ?line receive_trace_msg({trace,Pid,call,
- {erlang,statistics, [runtime]}}),
+ Pid ! {do_bif, statistics, [runtime]},
+ receive_trace_msg({trace,Pid,call,
+ {erlang,statistics, [runtime]}}),
- ?line 1 = erlang:trace(Pid, false, [call]),
- ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags),
+ 1 = erlang:trace(Pid, false, [call]),
+ erlang:trace_pattern({erlang,'_','_'}, false, Flags),
- ?line exit(Pid, die),
+ exit(Pid, die),
ok.
trace_bif_return(doc) ->
"Test tracing BIF's with return/return_to trace.";
trace_bif_return(Config) when is_list(Config) ->
- ?line Pid=spawn(?MODULE, bif_process, []),
- ?line 1 = erlang:trace(Pid, true, [call,timestamp,return_to]),
- ?line erlang:trace_pattern({erlang,'_','_'}, [{'_',[],[{return_trace}]}],
- [local]),
-
-
- ?line Pid ! {do_bif, time, []},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}}),
- ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
- {erlang,time,0}}),
- ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
- {?MODULE, bif_process,0}}),
-
-
- ?line Pid ! {do_bif, statistics, [runtime]},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,
- {erlang,statistics, [runtime]}}),
- ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
- {erlang,statistics,1}}),
- ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
- {?MODULE, bif_process,0}}),
-
-
- ?line Pid ! {do_time_bif},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,
- {erlang,time, []}}),
- ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
- {erlang,time,0}}),
- ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
- {?MODULE, bif_process,0}}),
-
-
-
- ?line Pid ! {do_statistics_bif},
- ?line receive_trace_msg_ts({trace_ts,Pid,call,
- {erlang,statistics, [runtime]}}),
- ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
- {erlang,statistics,1}}),
- ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
- {?MODULE, bif_process,0}}),
+ do_trace_bif_return(timestamp, [timestamp]),
+ do_trace_bif_return(timestamp,
+ [timestamp,
+ monotonic_timestamp,
+ strict_monotonic_timestamp]),
+ do_trace_bif_return(strict_monotonic_timestamp,
+ [strict_monotonic_timestamp]),
+ do_trace_bif_return(strict_monotonic_timestamp,
+ [monotonic_timestamp, strict_monotonic_timestamp]),
+ do_trace_bif_return(monotonic_timestamp, [monotonic_timestamp]).
+
+do_trace_bif_return(TsType, TsFlags) ->
+ io:format("Testing with TsType=~p TsFlags=~p~n", [TsType, TsFlags]),
+ Pid=spawn(?MODULE, bif_process, []),
+ 1 = erlang:trace(Pid, true, [call,return_to]++TsFlags),
+ erlang:trace_pattern({erlang,'_','_'}, [{'_',[],[{return_trace}]}],
+ [local]),
+
+ Ts0 = make_ts(TsType),
+ Pid ! {do_bif, time, []},
+ Ts1 = receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}},
+ Ts0, TsType),
+ Ts2 = receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,time,0}},
+ Ts1, TsType),
+ Ts3 = receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}},
+ Ts2, TsType),
+
+
+ Pid ! {do_bif, statistics, [runtime]},
+ Ts4 = receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}},
+ Ts3, TsType),
+ Ts5 = receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,statistics,1}},
+ Ts4, TsType),
+ Ts6 = receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}},
+ Ts5, TsType),
+
+
+ Pid ! {do_time_bif},
+ Ts7 = receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,time, []}},
+ Ts6, TsType),
+ Ts8 = receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,time,0}},
+ Ts7, TsType),
+ Ts9 = receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}},
+ Ts8, TsType),
+
+
+
+ Pid ! {do_statistics_bif},
+ Ts10 = receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}},
+ Ts9, TsType),
+ Ts11 = receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,statistics,1}},
+ Ts10, TsType),
+ Ts12 = receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}},
+ Ts11, TsType),
+ check_ts(TsType, Ts12, make_ts(TsType)),
ok.
@@ -212,10 +266,11 @@ receive_trace_msg(Mess) ->
?t:fail()
end.
-receive_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}) ->
+receive_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}, PrevTs, TsType) ->
receive
- {trace_ts, Pid, call, {erlang, F, A}, _Ts} ->
- ok;
+ {trace_ts, Pid, call, {erlang, F, A}, Ts} ->
+ check_ts(TsType, PrevTs, Ts),
+ Ts;
Other ->
io:format("Expected: {trace, ~p, call, {~p, ~p, ~p}, TimeStamp}},~n"
"Got: ~p~n",
@@ -226,10 +281,11 @@ receive_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}) ->
?t:fail()
end.
-receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {erlang,F,A}}) ->
+receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {erlang,F,A}}, PrevTs, TsType) ->
receive
- {trace_ts, Pid, return_from, {erlang, F, A}, _Value, _Ts} ->
- ok;
+ {trace_ts, Pid, return_from, {erlang, F, A}, _Value, Ts} ->
+ check_ts(TsType, PrevTs, Ts),
+ Ts;
Other ->
io:format("Expected: {trace_ts, ~p, return_from, {~p, ~p, ~p}, Value, TimeStamp}},~n"
"Got: ~p~n",
@@ -240,10 +296,11 @@ receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {erlang,F,A}}) ->
?t:fail()
end.
-receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}) ->
+receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}, PrevTs, TsType) ->
receive
- {trace_ts, Pid, return_to, {M, F, A}, _Ts} ->
- ok;
+ {trace_ts, Pid, return_to, {M, F, A}, Ts} ->
+ check_ts(TsType, PrevTs, Ts),
+ Ts;
Other ->
io:format("Expected: {trace_ts, ~p, return_to, {~p, ~p, ~p}, TimeStamp}},~n"
"Got: ~p~n",
@@ -254,13 +311,42 @@ receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}) ->
?t:fail()
end.
+make_ts(timestamp) ->
+ erlang:now();
+make_ts(monotonic_timestamp) ->
+ erlang:monotonic_time(nano_seconds);
+make_ts(strict_monotonic_timestamp) ->
+ MT = erlang:monotonic_time(nano_seconds),
+ UMI = erlang:unique_integer([monotonic]),
+ {MT, UMI}.
+
+check_ts(timestamp, PrevTs, Ts) ->
+ {Ms, S, Us} = Ts,
+ true = is_integer(Ms),
+ true = is_integer(S),
+ true = is_integer(Us),
+ true = PrevTs < Ts,
+ Ts;
+check_ts(monotonic_timestamp, PrevTs, Ts) ->
+ true = is_integer(Ts),
+ true = PrevTs =< Ts,
+ Ts;
+check_ts(strict_monotonic_timestamp, PrevTs, Ts) ->
+ {MT, UMI} = Ts,
+ true = is_integer(MT),
+ true = is_integer(UMI),
+ true = PrevTs < Ts,
+ Ts.
+
bif_process() ->
receive
{do_bif, Name, Args} ->
apply(erlang, Name, Args),
bif_process();
{do_time_bif} ->
- _ = time(), %Assignment tells compiler to keep call.
+ %% Match the return value to ensure that the time() call
+ %% is not optimized away.
+ {_,_,_} = time(),
bif_process();
{do_statistics_bif} ->
statistics(runtime),
@@ -276,13 +362,16 @@ trace_info_old_code(Config) when is_list(Config) ->
?line MFA = {M,F,0} = {test,foo,0},
?line Fname = atom_to_list(M)++".erl",
?line AbsForms =
- [{attribute,1,module,M}, % -module(M).
- {attribute,2,export,[{F,0}]}, % -export([F/0]).
- {function,3,F,0, % F() ->
- [{clause,4,[],[],[{atom,4,F}]}]}], % F.
+ [{attribute,a(1),module,M}, % -module(M).
+ {attribute,a(2),export,[{F,0}]}, % -export([F/0]).
+ {function,a(3),F,0, % F() ->
+ [{clause,a(4),[],[],[{atom,a(4),F}]}]}], % F.
%%
?line {ok,M,Mbin} = compile:forms(AbsForms),
?line {module,M} = code:load_binary(M, Fname, Mbin),
?line true = erlang:delete_module(M),
?line {traced,undefined} = erlang:trace_info(MFA, traced),
ok.
+
+a(L) ->
+ erl_anno:new(L).
diff --git a/erts/emulator/test/trace_call_count_SUITE.erl b/erts/emulator/test/trace_call_count_SUITE.erl
index 2ac58493ff..c7881bbd70 100644
--- a/erts/emulator/test/trace_call_count_SUITE.erl
+++ b/erts/emulator/test/trace_call_count_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/trace_call_time_SUITE.erl b/erts/emulator/test/trace_call_time_SUITE.erl
index 3036d2957b..f359e1bd80 100644
--- a/erts/emulator/test/trace_call_time_SUITE.erl
+++ b/erts/emulator/test/trace_call_time_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -326,10 +327,10 @@ combo(Config) when is_list(Config) ->
%%
?line [3,2,1] = seq_r(1, 3, fun(X) -> X+1 end),
- ?line T0 = now(),
+ ?line T0 = erlang:monotonic_time(),
?line with_bif(Nbc),
- ?line T1 = now(),
- ?line TimeB = timer:now_diff(T1,T0),
+ ?line T1 = erlang:monotonic_time(),
+ ?line TimeB = erlang:convert_time_unit(T1-T0, native, micro_seconds),
%%
?line List = collect(100),
@@ -695,17 +696,17 @@ setup(Opts) ->
Pid.
execute(Pids, Mfa) when is_list(Pids) ->
- T0 = now(),
+ T0 = erlang:monotonic_time(),
[P ! {self(), execute, Mfa} || P <- Pids],
As = [receive {P, answer, Answer} -> Answer end || P <- Pids],
- T1 = now(),
- {As, timer:now_diff(T1,T0)};
+ T1 = erlang:monotonic_time(),
+ {As, erlang:convert_time_unit(T1-T0, native, micro_seconds)};
execute(P, Mfa) ->
- T0 = now(),
+ T0 = erlang:monotonic_time(),
P ! {self(), execute, Mfa},
A = receive {P, answer, Answer} -> Answer end,
- T1 = now(),
- {A, timer:now_diff(T1,T0)}.
+ T1 = erlang:monotonic_time(),
+ {A, erlang:convert_time_unit(T1-T0, native, micro_seconds)}.
diff --git a/erts/emulator/test/trace_local_SUITE.erl b/erts/emulator/test/trace_local_SUITE.erl
index 1bed49aad2..7431099340 100644
--- a/erts/emulator/test/trace_local_SUITE.erl
+++ b/erts/emulator/test/trace_local_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl b/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl
index be9bea209a..a5947de4aa 100644
--- a/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl
+++ b/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/trace_meta_SUITE.erl b/erts/emulator/test/trace_meta_SUITE.erl
index 45987cc319..3b105ec6fe 100644
--- a/erts/emulator/test/trace_meta_SUITE.erl
+++ b/erts/emulator/test/trace_meta_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -72,7 +73,7 @@ config(priv_dir,_) ->
info/1, tracer/1, combo/1, nosilent/1]).
init_per_testcase(_Case, Config) ->
- ?line Dog=test_server:timetrap(test_server:minutes(5)),
+ Dog=test_server:timetrap(test_server:minutes(5)),
[{watchdog, Dog}|Config].
end_per_testcase(_Case, Config) ->
@@ -179,107 +180,112 @@ nosilent(Config) when is_list(Config) ->
%%%
basic_test() ->
- ?line Pid = setup(),
- ?line erlang:trace_pattern({?MODULE,'_','_'},[],[meta]),
- ?line [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
- ?line ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,exported,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local2,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
- ?line erlang:trace_pattern({?MODULE,'_','_'},false,[meta]),
- ?line [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
- ?line ?NM,
- ?line [1,1,1,0] = lambda_slave(fun() ->
- exported_wrap(1)
- end),
- ?line ?NM,
- ?line erlang:trace_pattern({?MODULE,'_','_'},[],[meta]),
- ?line [1,1,1,0] = lambda_slave(fun() ->
- exported_wrap(1)
- end),
- ?line ?CTT(Pid,{?MODULE,_,_}) = receive_next(), %% The fun
- ?line ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,exported,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local2,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
- ?line erlang:trace_pattern({?MODULE,'_','_'},false,[meta]),
- ?line shutdown(),
- ?line ?NM,
+ Pid = setup(),
+ erlang:trace_pattern({?MODULE,'_','_'},[],[meta]),
+ [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
+ ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,exported,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local2,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
+ erlang:trace_pattern({?MODULE,'_','_'},false,[meta]),
+ [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
+ ?NM,
+ [1,1,1,0] = lambda_slave(fun() ->
+ exported_wrap(1)
+ end),
+ ?NM,
+ erlang:trace_pattern({?MODULE,'_','_'},[],[meta]),
+ [1,1,1,0] = lambda_slave(fun() ->
+ exported_wrap(1)
+ end),
+ ?CTT(Pid,{?MODULE,_,_}) = receive_next(), %% The fun
+ ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,exported,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local2,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
+ erlang:trace_pattern({?MODULE,'_','_'},false,[meta]),
+ shutdown(),
+ ?NM,
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return_test() ->
- ?line Pid = setup(),
- ?line erlang:trace_pattern({?MODULE,'_','_'},[{'_',[],[{return_trace}]}],
+ Pid = setup(),
+ erlang:trace_pattern({?MODULE,'_','_'},[{'_',[],[{return_trace}]}],
[meta]),
- ?line erlang:trace_pattern({erlang,phash2,'_'},[{'_',[],[{return_trace}]}],
+ erlang:trace_pattern({erlang,phash2,'_'},[{'_',[],[{return_trace}]}],
[meta]),
- ?line [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
- ?line ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,exported,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local2,[1]}) = receive_next(),
- ?line ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
- ?line ?CTT(Pid,{erlang,phash2,[1,1]}) = receive_next(),
- ?line ?RFT(Pid,{erlang,phash2,2},0) = receive_next(),
- ?line ?RFT(Pid,{?MODULE,local_tail,1},[1,0]) = receive_next(),
- ?line ?RFT(Pid,{?MODULE,local2,1},[1,0]) = receive_next(),
- ?line ?RFT(Pid,{?MODULE,local,1},[1,1,0]) = receive_next(),
- ?line ?RFT(Pid,{?MODULE,exported,1},[1,1,1,0]) = receive_next(),
- ?line ?RFT(Pid,{?MODULE,exported_wrap,1},[1,1,1,0]) = receive_next(),
- ?line shutdown(),
- ?line ?NM,
+ [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
+ ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,exported,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local2,[1]}) = receive_next(),
+ ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
+ ?CTT(Pid,{erlang,phash2,[1,1]}) = receive_next(),
+ ?RFT(Pid,{erlang,phash2,2},0) = receive_next(),
+ ?RFT(Pid,{?MODULE,local_tail,1},[1,0]) = receive_next(),
+ ?RFT(Pid,{?MODULE,local2,1},[1,0]) = receive_next(),
+ ?RFT(Pid,{?MODULE,local,1},[1,1,0]) = receive_next(),
+ ?RFT(Pid,{?MODULE,exported,1},[1,1,1,0]) = receive_next(),
+ ?RFT(Pid,{?MODULE,exported_wrap,1},[1,1,1,0]) = receive_next(),
+ shutdown(),
+ ?NM,
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
on_and_off_test() ->
- ?line Pid = setup(),
- ?line 1 = erlang:trace_pattern({?MODULE,local_tail,1},[],[meta]),
- ?line LocalTail = fun() ->
- local_tail(1)
- end,
- ?line [1,0] = lambda_slave(LocalTail),
- ?line ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
- ?line 0 = erlang:trace_pattern({?MODULE,local_tail,1},[],[global]),
- ?line [1,0] = lambda_slave(LocalTail),
- ?line ?NM,
- ?line 1 = erlang:trace_pattern({?MODULE,exported_wrap,1},[],[meta]),
- ?line [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
- ?line ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
- ?line 1 = erlang:trace_pattern({erlang,phash2,2},[],[meta]),
- ?line [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
- ?line ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
- ?line ?CTT(Pid,{erlang,phash2,[1,1]}) = receive_next(),
- ?line shutdown(),
- ?line erlang:trace_pattern({'_','_','_'},false,[meta]),
- ?line N = erlang:trace_pattern({erlang,'_','_'},true,[meta]),
- ?line case erlang:trace_pattern({erlang,'_','_'},false,[meta]) of
- N ->
- ok;
- Else ->
- exit({number_mismatch, {expected, N}, {got, Else}})
- end,
- ?line case erlang:trace_pattern({erlang,'_','_'},false,[meta]) of
- N ->
- ok;
- Else2 ->
- exit({number_mismatch, {expected, N}, {got, Else2}})
- end,
- ?line ?NM,
+ Pid = setup(),
+ 1 = erlang:trace_pattern({?MODULE,local_tail,1},[],[meta]),
+ LocalTail = fun() ->
+ local_tail(1)
+ end,
+ [1,0] = lambda_slave(LocalTail),
+ ?CTT(Pid,{?MODULE,local_tail,[1]}) = receive_next(),
+ 0 = erlang:trace_pattern({?MODULE,local_tail,1},[],[global]),
+ [1,0] = lambda_slave(LocalTail),
+ ?NM,
+ 1 = erlang:trace_pattern({?MODULE,exported_wrap,1},[],[meta]),
+ [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
+ ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
+ 1 = erlang:trace_pattern({erlang,phash2,2},[],[meta]),
+ [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
+ ?CTT(Pid,{?MODULE,exported_wrap,[1]}) = receive_next(),
+ ?CTT(Pid,{erlang,phash2,[1,1]}) = receive_next(),
+ shutdown(),
+ erlang:trace_pattern({'_','_','_'},false,[meta]),
+ N = erlang:trace_pattern({erlang,'_','_'},true,[meta]),
+ case erlang:trace_pattern({erlang,'_','_'},false,[meta]) of
+ N -> ok;
+ Else ->
+ exit({number_mismatch, {expected, N}, {got, Else}})
+ end,
+ case erlang:trace_pattern({erlang,'_','_'},false,[meta]) of
+ N -> ok;
+ Else2 ->
+ exit({number_mismatch, {expected, N}, {got, Else2}})
+ end,
+ %% ?NM,
+ %% Can't check for erlang:*/* stuff since common_test or test_server
+ %% will likely call list_to_binary in the logger. just drain any potential
+ %% message
+ ok = flush(),
ok.
-
+
+flush() ->
+ receive _ -> flush() after 0 -> ok end.
+
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
stack_grow_test() ->
- ?line Pid = setup(),
- ?line 1 = erlang:trace_pattern({?MODULE,loop,4},
+ Pid = setup(),
+ 1 = erlang:trace_pattern({?MODULE,loop,4},
[{'_',[],[{return_trace}]}],[meta]),
- ?line Num = 1 bsl 15,
- ?line Surface =
+ Num = 1 bsl 15,
+ Surface =
fun (This, ?RFT(P,{?MODULE,loop,4},N), N) when P == Pid->
if N == Num ->
?NM,
@@ -288,7 +294,7 @@ stack_grow_test() ->
This(This, receive_next(), N+1)
end
end,
- ?line Dive =
+ Dive =
fun (This, ?CTT(P,{?MODULE,loop,[{hej,hopp},[a,b,c],4.5,N]}), N)
when P == Pid->
if N == 0 ->
@@ -297,272 +303,263 @@ stack_grow_test() ->
This(This, receive_next(), N-1)
end
end,
- ?line apply_slave(?MODULE,loop,[{hej,hopp},[a,b,c],4.5,Num]),
-% ?line apply_slave_async(?MODULE,loop,[{hej,hopp},[a,b,c],4.5,Num]),
-% ?line List = collect(test_server:seconds(5)),
- ?line ok = Dive(Dive, receive_next(), Num),
- ?line ?NM,
+ apply_slave(?MODULE,loop,[{hej,hopp},[a,b,c],4.5,Num]),
+% apply_slave_async(?MODULE,loop,[{hej,hopp},[a,b,c],4.5,Num]),
+% List = collect(test_server:seconds(5)),
+ ok = Dive(Dive, receive_next(), Num),
+ ?NM,
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
info_test() ->
- ?line setup(),
- ?line Prog = [{['$1'],[{is_integer,'$1'}],[{message, false}]},
- {'_',[],[]}],
- ?line Self = self(),
- ?line GoOn = make_ref(),
-
- ?line Pid =
+ setup(),
+ Prog = [{['$1'],[{is_integer,'$1'}],[{message, false}]}, {'_',[],[]}],
+ Self = self(),
+ GoOn = make_ref(),
+ Pid =
spawn_link(
fun () ->
erlang:trace_pattern({?MODULE,exported_wrap,1},
- Prog, [{meta, Self}]),
+ Prog, [{meta, Self}]),
Self ! {self(), GoOn}
end),
- ?line receive {Pid, GoOn} -> ok end,
- ?line {traced,false} = erlang:trace_info({?MODULE,exported_wrap,1}, traced),
- ?line {match_spec, false} =
+ receive {Pid, GoOn} -> ok end,
+ {traced,false} = erlang:trace_info({?MODULE,exported_wrap,1}, traced),
+ {match_spec, false} =
erlang:trace_info({?MODULE,exported_wrap,1}, match_spec),
- ?line {meta, Self} = erlang:trace_info({?MODULE,exported_wrap,1}, meta),
- ?line {meta_match_spec, MMS} =
+ {meta, Self} = erlang:trace_info({?MODULE,exported_wrap,1}, meta),
+ {meta_match_spec, MMS} =
erlang:trace_info({?MODULE,exported_wrap,1}, meta_match_spec),
- ?line case MMS of
- Prog ->
- ok;
- Wrong ->
- exit({bad_result, {erlang,trace_info,
- [{?MODULE,exported_wrap,1},
- meta_match_spec]},
- {expected, Prog}, {got, Wrong}})
- end,
- ?line erlang:garbage_collect(self()),
- ?line receive
- after 1 ->
- ok
- end,
- ?line io:format("~p~n",[MMS]),
- ?line {meta_match_spec,MMS2} =
+ case MMS of
+ Prog ->
+ ok;
+ Wrong ->
+ exit({bad_result, {erlang,trace_info,
+ [{?MODULE,exported_wrap,1},
+ meta_match_spec]},
+ {expected, Prog}, {got, Wrong}})
+ end,
+ erlang:garbage_collect(self()),
+ receive
+ after 1 ->
+ ok
+ end,
+ io:format("~p~n",[MMS]),
+ {meta_match_spec,MMS2} =
erlang:trace_info({?MODULE,exported_wrap,1}, meta_match_spec),
- ?line io:format("~p~n",[MMS2]),
- ?line case MMS2 of
- Prog ->
- ok;
- Wrong2 ->
- exit({bad_result, {erlang,trace_info,
- [{?MODULE,exported_wrap,1},
- meta_match_spec]},
- {expected, Prog}, {got, Wrong2}})
- end,
- ?line {all, [_|_]=L} = erlang:trace_info({?MODULE,exported_wrap,1}, all),
- ?line {value, {meta, Self}} =
- lists:keysearch(meta, 1, L),
- ?line {value, {meta_match_spec, MMS}} =
- lists:keysearch(meta_match_spec, 1, L),
-
- ?line erlang:trace_pattern({?MODULE,exported_wrap,1}, true, [meta]),
- ?line {meta_match_spec, []} =
+ io:format("~p~n",[MMS2]),
+ case MMS2 of
+ Prog ->
+ ok;
+ Wrong2 ->
+ exit({bad_result, {erlang,trace_info,
+ [{?MODULE,exported_wrap,1},
+ meta_match_spec]},
+ {expected, Prog}, {got, Wrong2}})
+ end,
+ {all, [_|_]=L} = erlang:trace_info({?MODULE,exported_wrap,1}, all),
+ {value, {meta, Self}} = lists:keysearch(meta, 1, L),
+ {value, {meta_match_spec, MMS}} = lists:keysearch(meta_match_spec, 1, L),
+
+ erlang:trace_pattern({?MODULE,exported_wrap,1}, true, [meta]),
+ {meta_match_spec, []} =
erlang:trace_info({?MODULE,exported_wrap,1}, meta_match_spec),
-
- ?line erlang:trace_pattern({?MODULE,exported_wrap,1}, false, [meta]),
- ?line {meta, false} = erlang:trace_info({?MODULE,exported_wrap,1}, meta),
- ?line {meta_match_spec, false} =
+
+ erlang:trace_pattern({?MODULE,exported_wrap,1}, false, [meta]),
+ {meta, false} = erlang:trace_info({?MODULE,exported_wrap,1}, meta),
+ {meta_match_spec, false} =
erlang:trace_info({?MODULE,exported_wrap,1}, meta_match_spec),
- ?line {all, false} = erlang:trace_info({?MODULE,exported_wrap,1}, all),
-
- ?line shutdown(),
- ?line ?NM,
+ {all, false} = erlang:trace_info({?MODULE,exported_wrap,1}, all),
+ shutdown(),
+ ?NM,
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tracer_test() ->
- ?line Slave = setup(),
- ?line Self = self(),
-
- ?line MatchSpec = [{'_',[],[{return_trace}]}],
- ?line Tracer1 = spawn_link(fun () -> relay_n(3, Self) end),
- ?line Setter =
- spawn_link(
- fun () ->
- erlang:trace_pattern({?MODULE,receiver,1},
- MatchSpec,
- [{meta,Tracer1}]),
- erlang:trace_pattern({erlang,phash2,2},
- MatchSpec,
- [{meta,Tracer1}]),
- Self ! {self(), done}
- end),
- ?line receive {Setter, done} -> ok end,
- ?line Ref = make_ref(),
- ?line apply_slave_async(?MODULE, receiver, [Ref]),
- ?line {Tracer1,?CTT(Slave,{?MODULE,receiver,[Ref]})} = receive_next(100),
- ?line {Tracer1,?CTT(Slave,{erlang,phash2,[1,1]})} = receive_next(100),
- ?line {Tracer1,?RFT(Slave,{erlang,phash2,2},0)} = receive_next(100),
+ Slave = setup(),
+ Self = self(),
+
+ MatchSpec = [{'_',[],[{return_trace}]}],
+ Tracer1 = spawn_link(fun () -> relay_n(3, Self) end),
+ Setter = spawn_link(
+ fun () ->
+ erlang:trace_pattern({?MODULE,receiver,1},
+ MatchSpec,
+ [{meta,Tracer1}]),
+ erlang:trace_pattern({erlang,phash2,2},
+ MatchSpec,
+ [{meta,Tracer1}]),
+ Self ! {self(), done}
+ end),
+ receive {Setter, done} -> ok end,
+ Ref = make_ref(),
+ apply_slave_async(?MODULE, receiver, [Ref]),
+ {Tracer1,?CTT(Slave,{?MODULE,receiver,[Ref]})} = receive_next(100),
+ {Tracer1,?CTT(Slave,{erlang,phash2,[1,1]})} = receive_next(100),
+ {Tracer1,?RFT(Slave,{erlang,phash2,2},0)} = receive_next(100),
%% Initiate a return_trace that will fail since the tracer just stopped
- ?line Slave ! Ref,
- ?line receive_no_next(100),
+ Slave ! Ref,
+ receive_no_next(100),
%% The breakpoint has not been hit since the tracer stopped
- ?line {meta,Tracer1} =
+ {meta,Tracer1} =
erlang:trace_info({?MODULE,receiver,1}, meta),
- ?line {meta_match_spec, MatchSpec} =
+ {meta_match_spec, MatchSpec} =
erlang:trace_info({?MODULE,receiver,1}, meta_match_spec),
- ?line {meta,Tracer1} =
+ {meta,Tracer1} =
erlang:trace_info({erlang,phash2,2}, meta),
- ?line {meta_match_spec, MatchSpec} =
+ {meta_match_spec, MatchSpec} =
erlang:trace_info({erlang,phash2,2}, meta_match_spec),
%% Initiate trace messages that will fail
- ?line Ref2 = make_ref(),
- ?line apply_slave_async(?MODULE, receiver, [Ref2]),
- ?line Slave ! Ref2,
- ?line receive_no_next(100),
- ?line {meta,[]} =
+ Ref2 = make_ref(),
+ apply_slave_async(?MODULE, receiver, [Ref2]),
+ Slave ! Ref2,
+ receive_no_next(100),
+ {meta,[]} =
erlang:trace_info({?MODULE,receiver,1}, meta),
- ?line {meta_match_spec, MatchSpec} =
+ {meta_match_spec, MatchSpec} =
erlang:trace_info({?MODULE,receiver,1}, meta_match_spec),
- ?line {meta,[]} =
+ {meta,[]} =
erlang:trace_info({erlang,phash2,2}, meta),
- ?line {meta_match_spec, MatchSpec} =
+ {meta_match_spec, MatchSpec} =
erlang:trace_info({erlang,phash2,2}, meta_match_spec),
%% Change tracer
- ?line Tracer2 = spawn_link(fun () -> relay_n(4, Self) end),
- ?line erlang:trace_pattern({?MODULE,receiver,1},
- MatchSpec,
- [{meta,Tracer2}]),
- ?line erlang:trace_pattern({erlang,phash2,2},
- MatchSpec,
- [{meta,Tracer2}]),
- ?line Ref3 = make_ref(),
- ?line apply_slave_async(?MODULE, receiver, [Ref3]),
- ?line {Tracer2,?CTT(Slave,{?MODULE,receiver,[Ref3]})} = receive_next(),
- ?line {Tracer2,?CTT(Slave,{erlang,phash2,[1,1]})} = receive_next(),
- ?line {Tracer2,?RFT(Slave,{erlang,phash2,2},0)} = receive_next(),
+ Tracer2 = spawn_link(fun () -> relay_n(4, Self) end),
+ erlang:trace_pattern({?MODULE,receiver,1},
+ MatchSpec,
+ [{meta,Tracer2}]),
+ erlang:trace_pattern({erlang,phash2,2},
+ MatchSpec,
+ [{meta,Tracer2}]),
+ Ref3 = make_ref(),
+ apply_slave_async(?MODULE, receiver, [Ref3]),
+ {Tracer2,?CTT(Slave,{?MODULE,receiver,[Ref3]})} = receive_next(),
+ {Tracer2,?CTT(Slave,{erlang,phash2,[1,1]})} = receive_next(),
+ {Tracer2,?RFT(Slave,{erlang,phash2,2},0)} = receive_next(),
%% Change tracer between call trace and return trace
- ?line Tracer3 = spawn_link(fun () -> relay_n(4, Self) end),
- ?line erlang:trace_pattern({?MODULE,receiver,1},
- MatchSpec,
- [{meta,Tracer3}]),
- ?line erlang:trace_pattern({erlang,phash2,2},
- MatchSpec,
- [{meta,Tracer3}]),
- ?line Slave ! Ref3,
+ Tracer3 = spawn_link(fun () -> relay_n(4, Self) end),
+ erlang:trace_pattern({?MODULE,receiver,1},
+ MatchSpec,
+ [{meta,Tracer3}]),
+ erlang:trace_pattern({erlang,phash2,2},
+ MatchSpec,
+ [{meta,Tracer3}]),
+ Slave ! Ref3,
%% The return trace should still come from Tracer2
- ?line {Tracer2,?RFT(Slave,{?MODULE,receiver,1},Ref3)} = receive_next(),
- ?line Ref4 = make_ref(),
+ {Tracer2,?RFT(Slave,{?MODULE,receiver,1},Ref3)} = receive_next(),
+ Ref4 = make_ref(),
%% Now should Tracer3 be used
- ?line apply_slave_async(?MODULE, receiver, [Ref4]),
- ?line Slave ! Ref4,
- ?line {Tracer3,?CTT(Slave,{?MODULE,receiver,[Ref4]})} = receive_next(),
- ?line {Tracer3,?CTT(Slave,{erlang,phash2,[1,1]})} = receive_next(),
- ?line {Tracer3,?RFT(Slave,{erlang,phash2,2},0)} = receive_next(),
- ?line {Tracer3,?RFT(Slave,{?MODULE,receiver,1},Ref4)} = receive_next(),
+ apply_slave_async(?MODULE, receiver, [Ref4]),
+ Slave ! Ref4,
+ {Tracer3,?CTT(Slave,{?MODULE,receiver,[Ref4]})} = receive_next(),
+ {Tracer3,?CTT(Slave,{erlang,phash2,[1,1]})} = receive_next(),
+ {Tracer3,?RFT(Slave,{erlang,phash2,2},0)} = receive_next(),
+ {Tracer3,?RFT(Slave,{?MODULE,receiver,1},Ref4)} = receive_next(),
%% The breakpoint has not been hit since the tracer stopped
- ?line {meta,Tracer3} =
- erlang:trace_info({?MODULE,receiver,1}, meta),
- ?line {meta_match_spec, MatchSpec} =
+ {meta,Tracer3} = erlang:trace_info({?MODULE,receiver,1}, meta),
+ {meta_match_spec, MatchSpec} =
erlang:trace_info({?MODULE,receiver,1}, meta_match_spec),
- ?line {meta,Tracer3} =
+ {meta,Tracer3} =
erlang:trace_info({erlang,phash2,2}, meta),
- ?line {meta_match_spec, MatchSpec} =
+ {meta_match_spec, MatchSpec} =
erlang:trace_info({erlang,phash2,2}, meta_match_spec),
-
- ?line shutdown(),
- ?line ?NM,
+ shutdown(),
+ ?NM,
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
combo_test() ->
- ?line Slave = setup(),
- ?line Self = self(),
-
- ?line MatchSpec = [{'_',[],[{return_trace}]}],
- ?line Flags = lists:sort([call, return_to]),
- ?line LocalTracer = spawn_link(fun () -> relay_n(6, Self) end),
- ?line MetaTracer = spawn_link(fun () -> relay_n(4, Self) end),
- ?line 1 = erlang:trace_pattern({?MODULE,receiver,1},
- MatchSpec,
- [local,{meta,MetaTracer}]),
- ?line 1 = erlang:trace_pattern({erlang,phash2,2},
- MatchSpec,
- [local,{meta,MetaTracer}]),
- ?line 1 = erlang:trace(Slave, true,
- [{tracer,LocalTracer} | Flags]),
+ Slave = setup(),
+ Self = self(),
+
+ MatchSpec = [{'_',[],[{return_trace}]}],
+ Flags = lists:sort([call, return_to]),
+ LocalTracer = spawn_link(fun () -> relay_n(6, Self) end),
+ MetaTracer = spawn_link(fun () -> relay_n(4, Self) end),
+ 1 = erlang:trace_pattern({?MODULE,receiver,1},
+ MatchSpec,
+ [local,{meta,MetaTracer}]),
+ 1 = erlang:trace_pattern({erlang,phash2,2},
+ MatchSpec,
+ [local,{meta,MetaTracer}]),
+ 1 = erlang:trace(Slave, true,
+ [{tracer,LocalTracer} | Flags]),
%%
- ?line {all, TraceInfo1} =
+ {all, TraceInfo1} =
erlang:trace_info({?MODULE,receiver,1}, all),
- ?line {meta,MetaTracer} =
+ {meta,MetaTracer} =
erlang:trace_info({?MODULE,receiver,1}, meta),
- ?line {value,{meta,MetaTracer}} =
+ {value,{meta,MetaTracer}} =
lists:keysearch(meta, 1, TraceInfo1),
- ?line {meta_match_spec,MatchSpec} =
+ {meta_match_spec,MatchSpec} =
erlang:trace_info({?MODULE,receiver,1}, meta_match_spec),
- ?line {value,{meta_match_spec,MatchSpec}} =
+ {value,{meta_match_spec,MatchSpec}} =
lists:keysearch(meta_match_spec, 1, TraceInfo1),
- ?line {traced,local} =
+ {traced,local} =
erlang:trace_info({?MODULE,receiver,1}, traced),
- ?line {value,{traced,local}} =
+ {value,{traced,local}} =
lists:keysearch(traced, 1, TraceInfo1),
- ?line {match_spec,MatchSpec} =
+ {match_spec,MatchSpec} =
erlang:trace_info({?MODULE,receiver,1}, match_spec),
- ?line {value,{match_spec,MatchSpec}} =
+ {value,{match_spec,MatchSpec}} =
lists:keysearch(match_spec, 1, TraceInfo1),
%%
- ?line {all, TraceInfo2} =
+ {all, TraceInfo2} =
erlang:trace_info({erlang,phash2,2}, all),
- ?line {meta,MetaTracer} =
+ {meta,MetaTracer} =
erlang:trace_info({erlang,phash2,2}, meta),
- ?line {value,{meta,MetaTracer}} =
+ {value,{meta,MetaTracer}} =
lists:keysearch(meta, 1, TraceInfo2),
- ?line {meta_match_spec,MatchSpec} =
+ {meta_match_spec,MatchSpec} =
erlang:trace_info({erlang,phash2,2}, meta_match_spec),
- ?line {value,{meta_match_spec,MatchSpec}} =
+ {value,{meta_match_spec,MatchSpec}} =
lists:keysearch(meta_match_spec, 1, TraceInfo2),
- ?line {traced,local} =
+ {traced,local} =
erlang:trace_info({erlang,phash2,2}, traced),
- ?line {value,{traced,local}} =
+ {value,{traced,local}} =
lists:keysearch(traced, 1, TraceInfo2),
- ?line {match_spec,MatchSpec} =
+ {match_spec,MatchSpec} =
erlang:trace_info({erlang,phash2,2}, match_spec),
- ?line {value,{match_spec,MatchSpec}} =
+ {value,{match_spec,MatchSpec}} =
lists:keysearch(match_spec, 1, TraceInfo2),
%%
- ?line {flags,Flags1} = erlang:trace_info(Slave, flags),
- ?line Flags = lists:sort(Flags1),
- ?line {tracer,LocalTracer} = erlang:trace_info(Slave, tracer),
+ {flags,Flags1} = erlang:trace_info(Slave, flags),
+ Flags = lists:sort(Flags1),
+ {tracer,LocalTracer} = erlang:trace_info(Slave, tracer),
%%
- ?line Ref = make_ref(),
- ?line apply_slave_async(?MODULE, receiver, [Ref]),
- ?line Slave ! Ref,
- ?line ?CTT(Slave,{?MODULE,receiver,[Ref]}) = receive_next_bytag(MetaTracer),
- ?line ?CTT(Slave,{erlang,phash2,[1,1]}) = receive_next_bytag(MetaTracer),
- ?line ?RFT(Slave,{erlang,phash2,2},0) = receive_next_bytag(MetaTracer),
- ?line ?RFT(Slave,{?MODULE,receiver,1},Ref) = receive_next_bytag(MetaTracer),
- ?line ?CT(Slave,{?MODULE,receiver,[Ref]}) = receive_next_bytag(LocalTracer),
- ?line ?CT(Slave,{erlang,phash2,[1,1]}) = receive_next_bytag(LocalTracer),
- ?line case {receive_next_bytag(LocalTracer),
+ Ref = make_ref(),
+ apply_slave_async(?MODULE, receiver, [Ref]),
+ Slave ! Ref,
+ ?CTT(Slave,{?MODULE,receiver,[Ref]}) = receive_next_bytag(MetaTracer),
+ ?CTT(Slave,{erlang,phash2,[1,1]}) = receive_next_bytag(MetaTracer),
+ ?RFT(Slave,{erlang,phash2,2},0) = receive_next_bytag(MetaTracer),
+ ?RFT(Slave,{?MODULE,receiver,1},Ref) = receive_next_bytag(MetaTracer),
+ ?CT(Slave,{?MODULE,receiver,[Ref]}) = receive_next_bytag(LocalTracer),
+ ?CT(Slave,{erlang,phash2,[1,1]}) = receive_next_bytag(LocalTracer),
+ case {receive_next_bytag(LocalTracer),
receive_next_bytag(LocalTracer)} of
{?RF(Slave,{erlang,phash2,2},0),
?RT(Slave,{?MODULE,receiver,1})} ->
- ?line ok;
+ ok;
{?RT(Slave,{?MODULE,receiver,1}),
?RF(Slave,{erlang,phash2,2},0)} ->
- ?line ok;
+ ok;
Error1 -> ?t:fail({unexpected_message, Error1})
end,
- ?line case {receive_next_bytag(LocalTracer),
+ case {receive_next_bytag(LocalTracer),
receive_next_bytag(LocalTracer)} of
{?RF(Slave,{?MODULE,receiver,1},Ref),
?RT(Slave,{?MODULE,slave,1})} ->
- ?line ok;
+ ok;
{?RT(Slave,{?MODULE,slave,1}),
?RF(Slave,{?MODULE,receiver,1},Ref)} ->
- ?line ok;
+ ok;
Error2 -> ?t:fail({unexpected_message, Error2})
end,
-
- ?line shutdown(),
- ?line ?NM,
+ shutdown(),
+ ?NM,
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -570,38 +567,38 @@ combo_test() ->
%% Setup silent local call tracing, and start it using meta trace.
nosilent_test() ->
- ?line Pid = setup(),
- ?line Trigger = {?MODULE,id,1},
- ?line TriggerMS = [{[start],[],[{silent,false}]},
- {[stop],[],[{silent,true},{return_trace}]}],
- ?line 1 = erlang:trace(Pid, true, [call,silent,return_to]),
- ?line erlang:trace_pattern({?MODULE,'_','_'},[],[local]),
- ?line 1 = erlang:trace_pattern({?MODULE,local2,1},
- [{'_',[],[{return_trace}]}],
- [local]),
- ?line 1 = erlang:trace_pattern({?MODULE,slave,1},false,[local]),
- ?line 1 = erlang:trace_pattern(Trigger,false,[local]),
- ?line 1 = erlang:trace_pattern(Trigger,TriggerMS,[meta]),
- ?line [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
- ?line receive_no_next(17),
- ?line start = apply_slave(?MODULE, id, [start]),
- ?line ?CTT(Pid,{?MODULE,id,[start]}) = receive_next(),
- ?line [2,2,2,0] = apply_slave(?MODULE,exported_wrap,[2]),
- ?line ?CT(Pid,{?MODULE,exported_wrap,[2]}) = receive_next(),
- ?line ?CT(Pid,{?MODULE,exported,[2]}) = receive_next(),
- ?line ?CT(Pid,{?MODULE,local,[2]}) = receive_next(),
- ?line ?CT(Pid,{?MODULE,local2,[2]}) = receive_next(),
- ?line ?CT(Pid,{?MODULE,local_tail,[2]}) = receive_next(),
- ?line ?RF(Pid,{?MODULE,local2,1}, [2,0]) = receive_next(),
- ?line ?RT(Pid,{?MODULE,local,1}) = receive_next(),
- ?line ?RT(Pid,{?MODULE,exported,1}) = receive_next(),
- ?line ?RT(Pid,{?MODULE,slave,1}) = receive_next(),
- ?line stop = apply_slave(?MODULE, id, [stop]),
- ?line ?CTT(Pid,{?MODULE,id,[stop]}) = receive_next(),
- ?line ?RFT(Pid,{?MODULE,id,1}, stop) = receive_next(),
- ?line [3,3,3,0] = apply_slave(?MODULE,exported_wrap,[3]),
- ?line receive_no_next(17),
- ?line shutdown(),
+ Pid = setup(),
+ Trigger = {?MODULE,id,1},
+ TriggerMS = [{[start],[],[{silent,false}]},
+ {[stop],[],[{silent,true},{return_trace}]}],
+ 1 = erlang:trace(Pid, true, [call,silent,return_to]),
+ erlang:trace_pattern({?MODULE,'_','_'},[],[local]),
+ 1 = erlang:trace_pattern({?MODULE,local2,1},
+ [{'_',[],[{return_trace}]}],
+ [local]),
+ 1 = erlang:trace_pattern({?MODULE,slave,1},false,[local]),
+ 1 = erlang:trace_pattern(Trigger,false,[local]),
+ 1 = erlang:trace_pattern(Trigger,TriggerMS,[meta]),
+ [1,1,1,0] = apply_slave(?MODULE,exported_wrap,[1]),
+ receive_no_next(17),
+ start = apply_slave(?MODULE, id, [start]),
+ ?CTT(Pid,{?MODULE,id,[start]}) = receive_next(),
+ [2,2,2,0] = apply_slave(?MODULE,exported_wrap,[2]),
+ ?CT(Pid,{?MODULE,exported_wrap,[2]}) = receive_next(),
+ ?CT(Pid,{?MODULE,exported,[2]}) = receive_next(),
+ ?CT(Pid,{?MODULE,local,[2]}) = receive_next(),
+ ?CT(Pid,{?MODULE,local2,[2]}) = receive_next(),
+ ?CT(Pid,{?MODULE,local_tail,[2]}) = receive_next(),
+ ?RF(Pid,{?MODULE,local2,1}, [2,0]) = receive_next(),
+ ?RT(Pid,{?MODULE,local,1}) = receive_next(),
+ ?RT(Pid,{?MODULE,exported,1}) = receive_next(),
+ ?RT(Pid,{?MODULE,slave,1}) = receive_next(),
+ stop = apply_slave(?MODULE, id, [stop]),
+ ?CTT(Pid,{?MODULE,id,[stop]}) = receive_next(),
+ ?RFT(Pid,{?MODULE,id,1}, stop) = receive_next(),
+ [3,3,3,0] = apply_slave(?MODULE,exported_wrap,[3]),
+ receive_no_next(17),
+ shutdown(),
ok.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -645,9 +642,9 @@ slave(Sync) ->
Sync ! sync,
receive
{From,apply, M, F, A} ->
- ?line ?dbgformat("Apply: ~p:~p/~p (~p)~n",[M,F,length(A),A]),
- ?line Res = apply(M,F,A),
- ?line ?dbgformat("done Apply: ~p:~p/~p (~p)~n",[M,F,length(A),A]),
+ ?dbgformat("Apply: ~p:~p/~p (~p)~n",[M,F,length(A),A]),
+ Res = apply(M,F,A),
+ ?dbgformat("done Apply: ~p:~p/~p (~p)~n",[M,F,length(A),A]),
From ! {apply, Res},
erlang:trace_pattern({?MODULE,slave,1},false,[meta]),
slave(From);
diff --git a/erts/emulator/test/trace_nif_SUITE.erl b/erts/emulator/test/trace_nif_SUITE.erl
index a7484a22fd..1cd50350e3 100644
--- a/erts/emulator/test/trace_nif_SUITE.erl
+++ b/erts/emulator/test/trace_nif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl
index 99df8da107..a77710205e 100644
--- a/erts/emulator/test/trace_port_SUITE.erl
+++ b/erts/emulator/test/trace_port_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -34,7 +35,8 @@
fake_schedule_after_getting_linked/1,
fake_schedule_after_getting_unlinked/1,
gc/1,
- default_tracer/1]).
+ default_tracer/1,
+ tracer_port_crash/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -44,7 +46,7 @@ test_cases() ->
fake_schedule_after_register,
fake_schedule_after_getting_linked,
fake_schedule_after_getting_unlinked, gc,
- default_tracer].
+ default_tracer, tracer_port_crash].
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -472,6 +474,42 @@ default_tracer(Config) when is_list(Config) ->
?line M = N,
ok.
+tracer_port_crash(Config) when is_list(Config) ->
+ case test_server:is_native(?MODULE) orelse
+ test_server:is_native(lists) of
+ true ->
+ {skip,"Native code"};
+ false ->
+ Tr = start_tracer(Config),
+ Port = get(tracer_port),
+ Tracee = spawn(fun () ->
+ register(trace_port_linker, self()),
+ link(Port),
+ receive go -> ok end,
+ lists:reverse([1,b,c]),
+ receive die -> ok end
+ end),
+ Tr ! {unlink_tracer_port, self()},
+ receive {unlinked_tracer_port, Tr} -> ok end,
+ port_control(Port, $c, []), %% Make port commands crash tracer port...
+ trace_func({lists,reverse,1}, []),
+ trace_pid(Tracee, true, [call]),
+ trace_info(Tracee, flags),
+ trace_info(self(), tracer),
+ Tracee ! go,
+ receive after 1000 -> ok end,
+ case whereis(trace_port_linker) of
+ undefined ->
+ ok;
+ Id ->
+% erts_debug:set_internal_state(available_internal_state, true),
+% erts_debug:set_internal_state(abort, {trace_port_linker, Id})
+ ?t:fail({trace_port_linker, Id})
+ end,
+ undefined = process_info(Tracee),
+ ok
+ end.
+
%%% Help functions.
huge_data() -> huge_data(16384).
@@ -630,6 +668,10 @@ tracer_loop(RelayTo, Port) ->
{Port,{data,Msg}} ->
RelayTo ! binary_to_term(Msg),
tracer_loop(RelayTo, Port);
+ {unlink_tracer_port, From} ->
+ unlink(Port),
+ From ! {unlinked_tracer_port, self()},
+ tracer_loop(RelayTo, Port);
Other ->
exit({bad_message,Other})
end.
diff --git a/erts/emulator/test/trace_port_SUITE_data/echo_drv.c b/erts/emulator/test/trace_port_SUITE_data/echo_drv.c
index a8d4ede4fe..e40b9193ea 100644
--- a/erts/emulator/test/trace_port_SUITE_data/echo_drv.c
+++ b/erts/emulator/test/trace_port_SUITE_data/echo_drv.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include "erl_driver.h"
+#include <errno.h>
@@ -14,6 +15,7 @@ enum e_heavy {
typedef struct _erl_drv_data {
ErlDrvPort erlang_port;
enum e_heavy heavy;
+ int crash;
} EchoDrvData;
static EchoDrvData echo_drv_data, *echo_drv_data_p;
@@ -78,6 +80,7 @@ static EchoDrvData *echo_drv_start(ErlDrvPort port, char *command)
echo_drv_data_p = &echo_drv_data;
echo_drv_data_p->erlang_port = port;
echo_drv_data_p->heavy = heavy_off;
+ echo_drv_data_p->crash = 0;
return echo_drv_data_p;
}
@@ -87,6 +90,12 @@ static void echo_drv_stop(EchoDrvData *data_p) {
static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
EchoDrvData* data_p = (EchoDrvData *) drv_data;
+
+ if (data_p->crash) {
+ driver_failure_posix(data_p->erlang_port, EINTR);
+ return;
+ }
+
driver_output(data_p->erlang_port, buf, len);
switch (data_p->heavy) {
case heavy_off:
@@ -100,6 +109,7 @@ static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
data_p->heavy = heavy_off;
break;
}
+
}
static void echo_drv_finish() {
@@ -115,6 +125,8 @@ static ErlDrvSSizeT echo_drv_control(ErlDrvData drv_data,
case 'h':
data_p->heavy = heavy_set;
break;
+ case 'c':
+ data_p->crash = 1;
}
return 0;
}
diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl
index f627eea07f..f1f077be6b 100644
--- a/erts/emulator/test/tuple_SUITE.erl
+++ b/erts/emulator/test/tuple_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/test/unique_SUITE.erl b/erts/emulator/test/unique_SUITE.erl
new file mode 100644
index 0000000000..6fa634b886
--- /dev/null
+++ b/erts/emulator/test/unique_SUITE.erl
@@ -0,0 +1,391 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(unique_SUITE).
+
+-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([unique_monotonic_integer_white_box/1,
+ unique_integer_white_box/1]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%-define(P(V), V).
+-define(P(V), print_ret_val(?FILE, ?LINE, V)).
+
+-define(PRINT(V), print_ret_val(?FILE, ?LINE, V)).
+
+
+init_per_testcase(Case, Config) ->
+ ?line Dog=test_server:timetrap(test_server:minutes(2)),
+ [{watchdog, Dog}, {testcase, Case}|Config].
+
+end_per_testcase(_, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [unique_monotonic_integer_white_box,
+ unique_integer_white_box].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ Config.
+
+end_per_suite(_Config) ->
+ erts_debug:set_internal_state(available_internal_state, false),
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+%%
+%%
+%% Unique counter white box test case
+%%
+%%
+
+unique_monotonic_integer_white_box(Config) when is_list(Config) ->
+ {ok, Node} = start_node(Config),
+ TestServer = self(),
+ Success = make_ref(),
+ %% Run this in a separate node, so we don't mess up
+ %% the system when moving the strict monotonic counter
+ %% around in a non-strict monotonic way...
+ Test = spawn(Node,
+ fun () ->
+ unique_monotonic_integer_white_box_test(TestServer, Success)
+ end),
+ Mon = erlang:monitor(process, Test),
+ receive
+ {'DOWN', Mon, process, Test, Error} ->
+ ?t:fail(Error);
+ Success ->
+ ok
+ end,
+ erlang:demonitor(Mon, [flush]),
+ stop_node(Node),
+ ok.
+
+set_unique_monotonic_integer_state(MinCounter, NextValue) ->
+ true = erts_debug:set_internal_state(unique_monotonic_integer_state,
+ NextValue-MinCounter-1).
+
+
+
+unique_monotonic_integer_white_box_test(TestServer, Success) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+
+ WordSize = erlang:system_info({wordsize, internal}),
+ SmallBits = WordSize*8 - 4,
+
+ MinSmall = -1*(1 bsl (SmallBits-1)),
+ MaxSmall = (1 bsl (SmallBits-1))-1,
+ %% Make sure we got small sizes correct...
+ 0 = erts_debug:size(MinSmall),
+ false = 0 =:= erts_debug:size(MinSmall-1),
+ 0 = erts_debug:size(MaxSmall),
+ false = 0 =:= erts_debug:size(MaxSmall+1),
+
+ ?PRINT({min_small, MinSmall}),
+ ?PRINT({max_small, MaxSmall}),
+
+ MinSint64 = -1*(1 bsl 63),
+ MaxSint64 = (1 bsl 63)-1,
+
+ ?PRINT({min_Sint64, MinSint64}),
+ ?PRINT({max_Sint64, MaxSint64}),
+
+ MinCounter = erts_debug:get_internal_state(min_unique_monotonic_integer),
+ MaxCounter = MinCounter + (1 bsl 64) - 1,
+
+ ?PRINT({min_counter, MinCounter}),
+ ?PRINT({max_counter, MaxCounter}),
+
+ case WordSize of
+ 4 ->
+ MinCounter = MinSint64;
+ 8 ->
+ MinCounter = MinSmall
+ end,
+
+ StartState = erts_debug:get_internal_state(unique_monotonic_integer_state),
+
+ %% Verify that we get expected results over all internal limits...
+
+ case MinCounter < MinSmall of
+ false ->
+ 8 = WordSize,
+ ok;
+ true ->
+ 4 = WordSize,
+ ?PRINT(over_min_small),
+ set_unique_monotonic_integer_state(MinCounter, MinSmall-2),
+ true = (?P(erlang:unique_integer([monotonic])) == MinSmall - 2),
+ true = (?P(erlang:unique_integer([monotonic])) == MinSmall - 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MinSmall),
+ true = (?P(erlang:unique_integer([monotonic])) == MinSmall + 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MinSmall + 2),
+ garbage_collect(),
+ ok
+ end,
+
+ ?PRINT(over_zero), %% Not really an interesting limit, but...
+ set_unique_monotonic_integer_state(MinCounter, -2),
+ true = (?P(erlang:unique_integer([monotonic])) == -2),
+ true = (?P(erlang:unique_integer([monotonic])) == -1),
+ true = (?P(erlang:unique_integer([monotonic])) == 0),
+ true = (?P(erlang:unique_integer([monotonic])) == 1),
+ true = (?P(erlang:unique_integer([monotonic])) == 2),
+ garbage_collect(),
+
+ ?PRINT(over_max_small),
+ set_unique_monotonic_integer_state(MinCounter, MaxSmall-2),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSmall - 2),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSmall - 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSmall),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSmall + 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSmall + 2),
+ garbage_collect(),
+
+ case MaxCounter > MaxSint64 of
+ false ->
+ 4 = WordSize,
+ ok;
+ true ->
+ 8 = WordSize,
+ ?PRINT(over_max_sint64),
+ set_unique_monotonic_integer_state(MinCounter, MaxSint64-2),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSint64 - 2),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSint64 - 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSint64),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSint64 + 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxSint64 + 2),
+ garbage_collect()
+ end,
+
+ ?PRINT(over_max_min_counter),
+ set_unique_monotonic_integer_state(MinCounter, if MaxCounter == MaxSint64 ->
+ MaxCounter-2;
+ true ->
+ MinCounter-3
+ end),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxCounter - 2),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxCounter - 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MaxCounter),
+ true = (?P(erlang:unique_integer([monotonic])) == MinCounter),
+ true = (?P(erlang:unique_integer([monotonic])) == MinCounter + 1),
+ true = (?P(erlang:unique_integer([monotonic])) == MinCounter + 2),
+ garbage_collect(),
+
+ %% Restore initial state and hope we didn't mess it up for the
+ %% system...
+ true = erts_debug:set_internal_state(unique_monotonic_integer_state,
+ StartState),
+
+ TestServer ! Success.
+
+%%
+%%
+%% Unique integer white box test case
+%%
+%%
+
+-record(uniqint_info, {min_int,
+ max_int,
+ max_small,
+ schedulers,
+ sched_bits}).
+
+unique_integer_white_box(Config) when is_list(Config) ->
+ UinqintInfo = init_uniqint_info(),
+ #uniqint_info{min_int = MinInt,
+ max_int = MaxInt,
+ max_small = MaxSmall} = UinqintInfo,
+ io:format("****************************************************~n", []),
+ io:format("*** Around MIN_UNIQ_INT ~p ***~n", [MinInt]),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around(MinInt, UinqintInfo),
+ io:format("****************************************************~n", []),
+ io:format("*** Around 0 ***~n", []),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around(0, UinqintInfo),
+ io:format("****************************************************~n", []),
+ io:format("*** Around MAX_SMALL ~p ***~n", [MaxSmall]),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around(MaxSmall, UinqintInfo),
+ io:format("****************************************************~n", []),
+ io:format("*** Around 2^64+MIN_UNIQ_INT ~p ***~n", [(1 bsl 64)+MinInt]),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around((1 bsl 64)+MinInt, UinqintInfo),
+ io:format("****************************************************~n", []),
+ io:format("*** Around 2^64 ~p~n", [(1 bsl 64)]),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around((1 bsl 64), UinqintInfo),
+ io:format("****************************************************~n", []),
+ io:format("*** Around 2^64-MIN_UNIQ_INT ~p ***~n", [(1 bsl 64)-MinInt]),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around((1 bsl 64)-MinInt, UinqintInfo),
+ io:format("****************************************************~n", []),
+ io:format("*** Around MAX_UNIQ_INT ~p ***~n", [MaxInt]),
+ io:format("****************************************************~n", []),
+ check_unique_integer_around(MaxInt, UinqintInfo),
+ ok.
+
+
+%%% Internal unique_integer_white_box/1 test case
+
+calc_sched_bits(NoScheds, Shift) when NoScheds < 1 bsl Shift ->
+ Shift;
+calc_sched_bits(NoScheds, Shift) ->
+ calc_sched_bits(NoScheds, Shift+1).
+
+init_uniqint_info() ->
+ SmallBits = erlang:system_info({wordsize, internal})*8-4,
+ io:format("SmallBits=~p~n", [SmallBits]),
+ Schedulers = erlang:system_info(schedulers),
+ io:format("Schedulers=~p~n", [Schedulers]),
+ MinSmall = -1*(1 bsl (SmallBits-1)),
+ io:format("MinSmall=~p~n", [MinSmall]),
+ MaxSmall = (1 bsl (SmallBits-1))-1,
+ io:format("MaxSmall=~p~n", [MaxSmall]),
+ SchedBits = calc_sched_bits(Schedulers, 0),
+ io:format("SchedBits=~p~n", [SchedBits]),
+ MaxInt = ((((1 bsl 64) - 1) bsl SchedBits) bor Schedulers) + MinSmall,
+ io:format("MaxInt=~p~n", [MaxInt]),
+ #uniqint_info{min_int = MinSmall,
+ max_int = MaxInt,
+ max_small = MaxSmall,
+ schedulers = Schedulers,
+ sched_bits = SchedBits}.
+
+valid_uniqint(Int, #uniqint_info{min_int = MinInt} = UinqintInfo) when Int < MinInt ->
+ valid_uniqint(MinInt, UinqintInfo);
+valid_uniqint(Int, #uniqint_info{min_int = MinInt,
+ sched_bits = SchedBits,
+ schedulers = Scheds}) ->
+ Int1 = Int - MinInt,
+ {Inc, ThreadNo} = case Int1 band ((1 bsl SchedBits) - 1) of
+ TN when TN > Scheds ->
+ {1, Scheds};
+ TN ->
+ {0, TN}
+ end,
+ Counter = ((Int1 bsr SchedBits) + Inc) rem (1 bsl 64),
+ ((Counter bsl SchedBits) bor ThreadNo) + MinInt.
+
+smaller_valid_uniqint(Int, UinqintInfo) ->
+ Cand = Int-1,
+ case valid_uniqint(Cand, UinqintInfo) of
+ RI when RI < Int ->
+ RI;
+ _ ->
+ smaller_valid_uniqint(Cand, UinqintInfo)
+ end.
+
+int32_to_bigendian_list(Int) ->
+ 0 = Int bsr 32,
+ [(Int bsr 24) band 16#ff,
+ (Int bsr 16) band 16#ff,
+ (Int bsr 8) band 16#ff,
+ Int band 16#ff].
+
+mk_uniqint(Int, #uniqint_info {min_int = MinInt,
+ sched_bits = SchedBits} = _UinqintInfo) ->
+ Int1 = Int - MinInt,
+ ThrId = Int1 band ((1 bsl SchedBits) - 1),
+ Value = (Int1 bsr SchedBits) band ((1 bsl 64) - 1),
+ 0 = Int1 bsr (SchedBits + 64),
+ NodeName = atom_to_list(node()),
+ Make = {make_unique_integer, ThrId, Value},
+ %% erlang:display(Make),
+ Res = erts_debug:get_internal_state(Make),
+ %% erlang:display({uniq_int, Res}),
+ Res.
+
+check_uniqint(Int, UinqintInfo) ->
+ UniqInt = mk_uniqint(Int, UinqintInfo),
+ io:format("UniqInt=~p ", [UniqInt]),
+ case UniqInt =:= Int of
+ true ->
+ io:format("OK~n~n", []);
+ false ->
+ io:format("result UniqInt=~p FAILED~n", [UniqInt]),
+ exit(badres)
+ end.
+
+check_unique_integer_around(Int, #uniqint_info{min_int = MinInt,
+ max_int = MaxInt} = UinqintInfo) ->
+ {Start, End} = case {Int =< MinInt+100, Int >= MaxInt-100} of
+ {true, false} ->
+ {MinInt, MinInt+100};
+ {false, false} ->
+ {smaller_valid_uniqint(Int-100, UinqintInfo),
+ valid_uniqint(Int+100, UinqintInfo)};
+ {false, true} ->
+ {MaxInt-100, MaxInt}
+ end,
+ lists:foldl(fun (I, OldRefInt) ->
+ RefInt = valid_uniqint(I, UinqintInfo),
+ case OldRefInt =:= RefInt of
+ true ->
+ ok;
+ false ->
+ check_uniqint(RefInt, UinqintInfo)
+ end,
+ RefInt
+ end,
+ none,
+ lists:seq(Start, End)).
+
+
+%% helpers
+
+print_ret_val(File, Line, Value) ->
+ io:format("~s:~p: ~p~n", [File, Line, Value]),
+ Value.
+
+start_node(Config) ->
+ start_node(Config, []).
+start_node(Config, Opts) when is_list(Config), is_list(Opts) ->
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line A = erlang:monotonic_time(1) + erlang:time_offset(1),
+ ?line B = erlang:unique_integer([positive]),
+ ?line Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(?config(testcase, Config))
+ ++ "-"
+ ++ integer_to_list(A)
+ ++ "-"
+ ++ integer_to_list(B)),
+ ?line ?t:start_node(Name, slave, [{args, Opts++" -pa "++Pa}]).
+
+stop_node(Node) ->
+ ?t:stop_node(Node).
diff --git a/erts/emulator/test/z_SUITE.erl b/erts/emulator/test/z_SUITE.erl
index b0c6224dfe..f4d9030255 100644
--- a/erts/emulator/test/z_SUITE.erl
+++ b/erts/emulator/test/z_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index 0b7c16f606..9a8c3585e6 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/utils/beam_strip b/erts/emulator/utils/beam_strip
index 1ce0fea180..0e7bc46b63 100755
--- a/erts/emulator/utils/beam_strip
+++ b/erts/emulator/utils/beam_strip
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/utils/count b/erts/emulator/utils/count
index 617f5c25e8..c4dd42c949 100755
--- a/erts/emulator/utils/count
+++ b/erts/emulator/utils/count
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/utils/loaded b/erts/emulator/utils/loaded
index d124a64a78..ab77ffdb6c 100644
--- a/erts/emulator/utils/loaded
+++ b/erts/emulator/utils/loaded
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/emulator/utils/make_alloc_types b/erts/emulator/utils/make_alloc_types
index 53051b7692..925b9d5810 100755
--- a/erts/emulator/utils/make_alloc_types
+++ b/erts/emulator/utils/make_alloc_types
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
@@ -190,16 +191,17 @@ print DST "/*
*
* Copyright Ericsson AB ", (1900 + (localtime)[5]), ". All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the \"License\"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an \"AS IS\"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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.
*
*/
@@ -244,7 +246,7 @@ print DST "
print DST "#define ERTS_ALC_C_MIN ($c_no)\n\n";
-foreach my $c (keys(%c_tab)) {
+foreach my $c (sort keys(%c_tab)) {
push(@c_order, $c);
set_number($c_tab{$c}, $c_no);
print DST "#define ERTS_ALC_C_$c ($c_no)\n";
diff --git a/erts/emulator/utils/make_compiler_flags b/erts/emulator/utils/make_compiler_flags
index ca1bc47113..d75ea0817e 100755
--- a/erts/emulator/utils/make_compiler_flags
+++ b/erts/emulator/utils/make_compiler_flags
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/utils/make_driver_tab b/erts/emulator/utils/make_driver_tab
index 5c68143d58..3203c7110a 100755
--- a/erts/emulator/utils/make_driver_tab
+++ b/erts/emulator/utils/make_driver_tab
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1999-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/utils/make_preload b/erts/emulator/utils/make_preload
index fade9829ca..62c4419589 100755
--- a/erts/emulator/utils/make_preload
+++ b/erts/emulator/utils/make_preload
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/emulator/utils/make_tables b/erts/emulator/utils/make_tables
index 597a201e5a..233e95f176 100755
--- a/erts/emulator/utils/make_tables
+++ b/erts/emulator/utils/make_tables
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1999-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/emulator/utils/make_version b/erts/emulator/utils/make_version
index 0ba1c77930..37bdff181a 100755
--- a/erts/emulator/utils/make_version
+++ b/erts/emulator/utils/make_version
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -58,7 +59,11 @@ print FILE <<EOF;
#define ERLANG_OTP_RELEASE "$release"
#define ERLANG_OTP_VERSION "$otp_version"
#define ERLANG_VERSION "$version"
-#define ERLANG_COMPILE_DATE "$time_str"
+#if ERTS_SAVED_COMPILE_TIME
+# define ERLANG_COMPILE_DATE "$time_str"
+#else
+# define ERLANG_COMPILE_DATE ""
+#endif
#define ERLANG_ARCHITECTURE "$architecture"
EOF
diff --git a/erts/emulator/utils/mkver.c b/erts/emulator/utils/mkver.c
index 844014e8f5..6641873712 100644
--- a/erts/emulator/utils/mkver.c
+++ b/erts/emulator/utils/mkver.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -34,8 +35,10 @@ int argc;
char** argv;
{
FILE *file;
+#if ERTS_SAVED_COMPILE_TIME
time_t now;
- char *cnow;
+#endif
+ char *cnow = "";
if (argc != 2) {
fprintf(stderr, "usage: mkver version\n");
@@ -47,9 +50,11 @@ char** argv;
exit(1);
}
+#if ERTS_SAVED_COMPILE_TIME
time(&now);
cnow = ctime(&now);
cnow[24] = '\0'; /* tidelipom */
+#endif
fprintf(file, "/* This file was created by mkver -- don't modify.*/\n");
fprintf(file, "#define ERLANG_VERSION \"%s\"\n", argv[1]);
fprintf(file, "#define ERLANG_COMPILE_DATE \"%s\"\n", cnow);
diff --git a/erts/emulator/valgrind/suppress.patched.3.6.0 b/erts/emulator/valgrind/suppress.patched.3.6.0
index b3507bdba7..fcde4a0123 100644
--- a/erts/emulator/valgrind/suppress.patched.3.6.0
+++ b/erts/emulator/valgrind/suppress.patched.3.6.0
@@ -273,6 +273,11 @@ obj:*/ssleay.*
fun:AES_cbc_encrypt
...
}
+{
+ crypto RC4 can do harmless word aligned read past end of input
+ Memcheck:Addr8
+ fun:RC4
+}
{
erts_bits_init_state; Why is this needed?
@@ -357,3 +362,15 @@ fun:async_main
...
}
+{
+Deliberate invalid read by test case bif_SUITE:erlang_halt
+Memcheck:Addr4
+...
+fun:erts_print_scheduler_info
+...
+fun:erts_exit
+fun:broken_halt_test
+fun:erts_debug_set_internal_state_2
+fun:process_main
+}
+
diff --git a/erts/emulator/valgrind/suppress.standard b/erts/emulator/valgrind/suppress.standard
index a4da31a61d..bb07c92fc1 100644
--- a/erts/emulator/valgrind/suppress.standard
+++ b/erts/emulator/valgrind/suppress.standard
@@ -260,6 +260,11 @@ obj:*/ssleay.*
fun:AES_cbc_encrypt
...
}
+{
+ crypto RC4 can do harmless word aligned read past end of input
+ Memcheck:Addr8
+ fun:RC4
+}
{
Prebuilt constant terms in os_info_init (PossiblyLost)
@@ -325,3 +330,15 @@ fun:async_main
...
}
+{
+Deliberate invalid read by test case bif_SUITE:erlang_halt
+Memcheck:Addr4
+...
+fun:erts_print_scheduler_info
+...
+fun:erts_exit
+fun:broken_halt_test
+fun:erts_debug_set_internal_state_2
+fun:process_main
+}
+
diff --git a/erts/emulator/zlib/zlib.mk b/erts/emulator/zlib/zlib.mk
index ff5ffa5328..53d7badd64 100644
--- a/erts/emulator/zlib/zlib.mk
+++ b/erts/emulator/zlib/zlib.mk
@@ -6,16 +6,17 @@
#
# Copyright Ericsson AB 2011-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/epmd/Makefile b/erts/epmd/Makefile
index 4c1af393ac..25a33462ee 100644
--- a/erts/epmd/Makefile
+++ b/erts/epmd/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/epmd/epmd.mk b/erts/epmd/epmd.mk
index a73f4bc077..08245b784e 100644
--- a/erts/epmd/epmd.mk
+++ b/erts/epmd/epmd.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/epmd/src/Makefile b/erts/epmd/src/Makefile
index 7d586c7438..3e09a40566 100644
--- a/erts/epmd/src/Makefile
+++ b/erts/epmd/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/epmd/src/Makefile.in b/erts/epmd/src/Makefile.in
index 0c7787a3b1..b6e3ba7762 100644
--- a/erts/epmd/src/Makefile.in
+++ b/erts/epmd/src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c
index 9699491526..5513cb2d7e 100644
--- a/erts/epmd/src/epmd.c
+++ b/erts/epmd/src/epmd.c
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -28,7 +29,7 @@
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
-
+#include <time.h>
/* forward declarations */
static void usage(EpmdVars *);
@@ -342,10 +343,10 @@ static void run_daemon(EpmdVars *g)
for (fd = 0; fd < g->max_conn ; fd++) /* close all files ... */
close(fd);
/* Syslog on linux will try to write to whatever if we dont
- inform it of that the log is closed. */
+ inform it that the log is closed. */
closelog();
- /* These chouldn't be needed but for safety... */
+ /* These shouldn't be needed but for safety... */
open("/dev/null", O_RDONLY); /* Order is important! */
open("/dev/null", O_WRONLY);
@@ -386,7 +387,7 @@ static void run_daemon(EpmdVars *g)
close(1);
close(2);
- /* These chouldn't be needed but for safety... */
+ /* These shouldn't be needed but for safety... */
open("nul", O_RDONLY);
open("nul", O_WRONLY);
@@ -498,11 +499,7 @@ static void dbg_gen_printf(int onsyslog,int perr,int from_level,
#ifdef HAVE_SYSLOG_H
if (onsyslog)
{
- int len;
- len = erts_vsnprintf(buf, DEBUG_BUFFER_SIZE, format, args);
- if (perr != 0 && len < sizeof(buf)) {
- erts_snprintf(buf+len, sizeof(buf)-len, ": %s", strerror(perr));
- }
+ erts_vsnprintf(buf, DEBUG_BUFFER_SIZE, format, args);
syslog(LOG_ERR,"epmd: %s",buf);
}
#endif
diff --git a/erts/epmd/src/epmd.h b/erts/epmd/src/epmd.h
index 5d6e9ac165..10483bb5a2 100644
--- a/erts/epmd/src/epmd.h
+++ b/erts/epmd/src/epmd.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/epmd/src/epmd_cli.c b/erts/epmd/src/epmd_cli.c
index bd30bc35d9..6fc05e153e 100644
--- a/erts/epmd/src/epmd_cli.c
+++ b/erts/epmd/src/epmd_cli.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -135,19 +136,33 @@ void epmd_call(EpmdVars *g,int what)
static int conn_to_epmd(EpmdVars *g)
{
struct EPMD_SOCKADDR_IN address;
+ size_t salen = 0;
int connect_sock;
-
- connect_sock = socket(FAMILY, SOCK_STREAM, 0);
- if (connect_sock<0)
- goto error;
+ unsigned short sport = g->port;
+
+#if defined(EPMD6)
+ SET_ADDR6(address, in6addr_loopback, sport);
+ salen = sizeof(struct sockaddr_in6);
+
+ connect_sock = socket(AF_INET6, SOCK_STREAM, 0);
+ if (connect_sock>=0) {
- { /* store port number in unsigned short */
- unsigned short sport = g->port;
- SET_ADDR(address, EPMD_ADDR_LOOPBACK, sport);
+ if (connect(connect_sock, (struct sockaddr*)&address, salen) == 0)
+ return connect_sock;
+
+ close(connect_sock);
}
+#endif
+ SET_ADDR(address, htonl(INADDR_LOOPBACK), sport);
+ salen = sizeof(struct sockaddr_in);
+
+ connect_sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (connect_sock<0)
+ goto error;
- if (connect(connect_sock, (struct sockaddr*)&address, sizeof address) < 0)
+ if (connect(connect_sock, (struct sockaddr*)&address, salen) < 0)
goto error;
+
return connect_sock;
error:
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index 52badd7086..09317094c7 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -54,6 +55,7 @@
# ifndef WINDOWS_H_INCLUDES_WINSOCK2_H
# include <winsock2.h>
# endif
+# include <ws2tcpip.h>
# include <windows.h>
# include <process.h>
#endif
@@ -129,6 +131,10 @@
# include <systemd/sd-daemon.h>
#endif /* HAVE_SYSTEMD_DAEMON */
+#if defined(HAVE_IN6) && defined(AF_INET6) && defined(HAVE_INET_PTON)
+# define EPMD6
+#endif
+
/* ************************************************************************ */
/* Replace some functions by others by making the function name a macro */
@@ -182,33 +188,53 @@
/* ************************************************************************ */
/* Macros that let us use IPv6 */
-#if defined(HAVE_IN6) && defined(AF_INET6) && defined(EPMD6)
+#if HAVE_IN6
+# if ! defined(HAVE_IN6ADDR_ANY) || ! HAVE_IN6ADDR_ANY
+# if HAVE_DECL_IN6ADDR_ANY_INIT
+static const struct in6_addr in6addr_any = { { IN6ADDR_ANY_INIT } };
+# else
+static const struct in6_addr in6addr_any =
+ { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
+# endif /* HAVE_IN6ADDR_ANY_INIT */
+# endif /* ! HAVE_DECL_IN6ADDR_ANY */
+
+# if ! defined(HAVE_IN6ADDR_LOOPBACK) || ! HAVE_IN6ADDR_LOOPBACK
+# if HAVE_DECL_IN6ADDR_LOOPBACK_INIT
+static const struct in6_addr in6addr_loopback =
+ { { IN6ADDR_LOOPBACK_INIT } };
+# else
+static const struct in6_addr in6addr_loopback =
+ { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } };
+# endif /* HAVE_IN6ADDR_LOOPBACK_INIT */
+# endif /* ! HAVE_DECL_IN6ADDR_LOOPBACK */
+#endif /* HAVE_IN6 */
+
+#define IS_ADDR_LOOPBACK(addr) ((addr).s_addr == htonl(INADDR_LOOPBACK))
+
+#if defined(EPMD6)
-#define EPMD_SOCKADDR_IN sockaddr_in6
-#define EPMD_IN_ADDR in6_addr
-#define EPMD_S_ADDR s6_addr
-#define EPMD_ADDR_LOOPBACK in6addr_loopback.s6_addr
-#define EPMD_ADDR_ANY in6addr_any.s6_addr
+#define EPMD_SOCKADDR_IN sockaddr_storage
#define FAMILY AF_INET6
-#define SET_ADDR(dst, addr, port) do { \
- memset((char*)&(dst), 0, sizeof(dst)); \
- memcpy((char*)&(dst).sin6_addr.s6_addr, (char*)&(addr), 16); \
- (dst).sin6_family = AF_INET6; \
- (dst).sin6_flowinfo = 0; \
- (dst).sin6_port = htons(port); \
+#define SET_ADDR6(dst, addr, port) do { \
+ struct sockaddr_in6 *sa = (struct sockaddr_in6 *)&(dst); \
+ memset(sa, 0, sizeof(dst)); \
+ sa->sin6_family = AF_INET6; \
+ sa->sin6_addr = (addr); \
+ sa->sin6_port = htons(port); \
} while(0)
-#define IS_ADDR_LOOPBACK(addr) \
- (memcmp((addr).s6_addr, in6addr_loopback.s6_addr, 16) == 0)
+#define SET_ADDR(dst, addr, port) do { \
+ struct sockaddr_in *sa = (struct sockaddr_in *)&(dst); \
+ memset(sa, 0, sizeof(dst)); \
+ sa->sin_family = AF_INET; \
+ sa->sin_addr.s_addr = (addr); \
+ sa->sin_port = htons(port); \
+ } while(0)
#else /* Not IP v6 */
#define EPMD_SOCKADDR_IN sockaddr_in
-#define EPMD_IN_ADDR in_addr
-#define EPMD_S_ADDR s_addr
-#define EPMD_ADDR_LOOPBACK htonl(INADDR_LOOPBACK)
-#define EPMD_ADDR_ANY htonl(INADDR_ANY)
#define FAMILY AF_INET
#define SET_ADDR(dst, addr, port) do { \
@@ -218,8 +244,6 @@
(dst).sin_port = htons(port); \
} while(0)
-#define IS_ADDR_LOOPBACK(addr) ((addr).s_addr == htonl(INADDR_LOOPBACK))
-
#endif /* Not IP v6 */
/* ************************************************************************ */
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 26e42adb19..e1bac99ef9 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -4,16 +4,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -75,6 +76,7 @@ static time_t current_time(EpmdVars*);
static Connection *conn_init(EpmdVars*);
static int conn_open(EpmdVars*,int);
+static int conn_local_peer_check(EpmdVars*, int);
static int conn_close_fd(EpmdVars*,int);
static void node_init(EpmdVars*);
@@ -205,10 +207,11 @@ void run(EpmdVars *g)
{
struct EPMD_SOCKADDR_IN iserv_addr[MAX_LISTEN_SOCKETS];
int listensock[MAX_LISTEN_SOCKETS];
- int num_sockets;
+ int num_sockets = 0;
int i;
int opt;
unsigned short sport = g->port;
+ int bound = 0;
node_init(g);
g->conn = conn_init(g);
@@ -251,64 +254,82 @@ void run(EpmdVars *g)
if (g->addresses != NULL && /* String contains non-separator characters if: */
g->addresses[strspn(g->addresses," ,")] != '\000')
{
- char *tmp;
- char *token;
- int loopback_ok = 0;
+ char *tmp = NULL;
+ char *token = NULL;
+
+ /* Always listen on the loopback. */
+ SET_ADDR(iserv_addr[num_sockets],htonl(INADDR_LOOPBACK),sport);
+ num_sockets++;
+#if defined(EPMD6)
+ SET_ADDR6(iserv_addr[num_sockets],in6addr_loopback,sport);
+ num_sockets++;
+#endif
- if ((tmp = (char *)malloc(strlen(g->addresses) + 1)) == NULL)
+ if ((tmp = strdup(g->addresses)) == NULL)
{
dbg_perror(g,"cannot allocate memory");
epmd_cleanup_exit(g,1);
}
- strcpy(tmp,g->addresses);
- for(token = strtok(tmp,", "), num_sockets = 0;
+ for(token = strtok(tmp,", ");
token != NULL;
- token = strtok(NULL,", "), num_sockets++)
+ token = strtok(NULL,", "))
{
- struct EPMD_IN_ADDR addr;
-#ifdef HAVE_INET_PTON
- int ret;
+ struct in_addr addr;
+#if defined(EPMD6)
+ struct in6_addr addr6;
+ struct sockaddr_storage *sa = &iserv_addr[num_sockets];
- if ((ret = inet_pton(FAMILY,token,&addr)) == -1)
+ if (inet_pton(AF_INET6,token,&addr6) == 1)
{
- dbg_perror(g,"cannot convert IP address to network format");
- epmd_cleanup_exit(g,1);
+ SET_ADDR6(iserv_addr[num_sockets],addr6,sport);
+ }
+ else if (inet_pton(AF_INET,token,&addr) == 1)
+ {
+ SET_ADDR(iserv_addr[num_sockets],addr.s_addr,sport);
+ }
+ else
+#else
+ if ((addr.s_addr = inet_addr(token)) != INADDR_NONE)
+ {
+ SET_ADDR(iserv_addr[num_sockets],addr.s_addr,sport);
}
- else if (ret == 0)
-#elif !defined(EPMD6)
- if ((addr.EPMD_S_ADDR = inet_addr(token)) == INADDR_NONE)
+ else
#endif
{
dbg_tty_printf(g,0,"cannot parse IP address \"%s\"",token);
epmd_cleanup_exit(g,1);
}
+#if defined(EPMD6)
+ if (sa->ss_family == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&addr6))
+ continue;
+
+ if (sa->ss_family == AF_INET)
+#endif
if (IS_ADDR_LOOPBACK(addr))
- loopback_ok = 1;
+ continue;
- if (num_sockets - loopback_ok == MAX_LISTEN_SOCKETS - 1)
+ num_sockets++;
+
+ if (num_sockets >= MAX_LISTEN_SOCKETS)
{
dbg_tty_printf(g,0,"cannot listen on more than %d IP addresses",
MAX_LISTEN_SOCKETS);
epmd_cleanup_exit(g,1);
}
-
- SET_ADDR(iserv_addr[num_sockets],addr.EPMD_S_ADDR,sport);
}
free(tmp);
-
- if (!loopback_ok)
- {
- SET_ADDR(iserv_addr[num_sockets],EPMD_ADDR_LOOPBACK,sport);
- num_sockets++;
- }
}
else
{
- SET_ADDR(iserv_addr[0],EPMD_ADDR_ANY,sport);
- num_sockets = 1;
+ SET_ADDR(iserv_addr[num_sockets],htonl(INADDR_ANY),sport);
+ num_sockets++;
+#if defined(EPMD6)
+ SET_ADDR6(iserv_addr[num_sockets],in6addr_any,sport);
+ num_sockets++;
+#endif
}
#ifdef HAVE_SYSTEMD_DAEMON
}
@@ -339,13 +360,39 @@ void run(EpmdVars *g)
#endif /* HAVE_SYSTEMD_DAEMON */
for (i = 0; i < num_sockets; i++)
{
- if ((listensock[i] = socket(FAMILY,SOCK_STREAM,0)) < 0)
+ struct sockaddr *sa = (struct sockaddr *)&iserv_addr[i];
+#if defined(EPMD6)
+ size_t salen = (sa->sa_family == AF_INET6 ?
+ sizeof(struct sockaddr_in6) :
+ sizeof(struct sockaddr_in));
+#else
+ size_t salen = sizeof(struct sockaddr_in);
+#endif
+
+ if ((listensock[i] = socket(sa->sa_family,SOCK_STREAM,0)) < 0)
{
- dbg_perror(g,"error opening stream socket");
+ switch (errno) {
+ case EAFNOSUPPORT:
+ case EPROTONOSUPPORT:
+ continue;
+ default:
+ dbg_perror(g,"error opening stream socket");
+ epmd_cleanup_exit(g,1);
+ }
+ }
+ g->listenfd[bound++] = listensock[i];
+
+#if HAVE_DECL_IPV6_V6ONLY
+ opt = 1;
+ if (sa->sa_family == AF_INET6 &&
+ setsockopt(listensock[i],IPPROTO_IPV6,IPV6_V6ONLY,&opt,
+ sizeof(opt)) <0)
+ {
+ dbg_perror(g,"can't set IPv6 only socket option");
epmd_cleanup_exit(g,1);
}
- g->listenfd[i] = listensock[i];
-
+#endif
+
/*
* Note that we must not enable the SO_REUSEADDR on Windows,
* because addresses will be reused even if they are still in use.
@@ -377,8 +424,7 @@ void run(EpmdVars *g)
dbg_perror(g,"failed to set non-blocking mode of listening socket %d",
listensock[i]);
- if (bind(listensock[i], (struct sockaddr*) &iserv_addr[i],
- sizeof(iserv_addr[i])) < 0)
+ if (bind(listensock[i], (struct sockaddr*) &iserv_addr[i], salen) < 0)
{
if (errno == EADDRINUSE)
{
@@ -399,6 +445,11 @@ void run(EpmdVars *g)
}
select_fd_set(g, listensock[i]);
}
+ if (bound == 0) {
+ dbg_perror(g,"unable to bind any address");
+ epmd_cleanup_exit(g,1);
+ }
+ num_sockets = bound;
#ifdef HAVE_SYSTEMD_DAEMON
}
sd_notifyf(0, "READY=1\n"
@@ -443,8 +494,8 @@ void run(EpmdVars *g)
}
for (i = 0; i < num_sockets; i++)
- if (FD_ISSET(listensock[i],&read_mask)) {
- if (do_accept(g, listensock[i]) && g->active_conn < g->max_conn) {
+ if (FD_ISSET(g->listenfd[i],&read_mask)) {
+ if (do_accept(g, g->listenfd[i]) && g->active_conn < g->max_conn) {
/*
* The accept() succeeded, and we have at least one file
* descriptor still free, which means that another accept()
@@ -699,11 +750,9 @@ static void do_request(g, fd, s, buf, bsize)
put_int16(node->creation, wbuf+2);
}
- if (g->delay_write) /* Test of busy server */
- sleep(g->delay_write);
-
if (reply(g, fd, wbuf, 4) != 4)
{
+ node_unreg(g, name);
dbg_tty_printf(g,1,"** failed to send ALIVE2_RESP for \"%s\"",
name);
return;
@@ -1006,15 +1055,6 @@ static int conn_open(EpmdVars *g,int fd)
for (i = 0; i < g->max_conn; i++) {
if (g->conn[i].open == EPMD_FALSE) {
- struct sockaddr_in si;
- struct sockaddr_in di;
-#ifdef HAVE_SOCKLEN_T
- socklen_t st;
-#else
- int st;
-#endif
- st = sizeof(si);
-
g->active_conn++;
s = &g->conn[i];
@@ -1025,20 +1065,7 @@ static int conn_open(EpmdVars *g,int fd)
s->open = EPMD_TRUE;
s->keep = EPMD_FALSE;
- /* Determine if connection is from localhost */
- if (getpeername(s->fd,(struct sockaddr*) &si,&st) ||
- st < sizeof(si)) {
- /* Failure to get peername is regarded as non local host */
- s->local_peer = EPMD_FALSE;
- } else {
- /* Only 127.x.x.x and connections from the host's IP address
- allowed, no false positives */
- s->local_peer =
- (((((unsigned) ntohl(si.sin_addr.s_addr)) & 0xFF000000U) ==
- 0x7F000000U) ||
- (getsockname(s->fd,(struct sockaddr*) &di,&st) ?
- EPMD_FALSE : si.sin_addr.s_addr == di.sin_addr.s_addr));
- }
+ s->local_peer = conn_local_peer_check(g, s->fd);
dbg_tty_printf(g,2,(s->local_peer) ? "Local peer connected" :
"Non-local peer connected");
@@ -1046,7 +1073,7 @@ static int conn_open(EpmdVars *g,int fd)
s->got = 0;
s->mod_time = current_time(g); /* Note activity */
- s->buf = (char *)malloc(INBUF_SIZE);
+ s->buf = malloc(INBUF_SIZE);
if (s->buf == NULL) {
dbg_printf(g,0,"epmd: Insufficient memory");
@@ -1064,6 +1091,60 @@ static int conn_open(EpmdVars *g,int fd)
return EPMD_FALSE;
}
+static int conn_local_peer_check(EpmdVars *g, int fd)
+{
+ struct EPMD_SOCKADDR_IN si;
+ struct EPMD_SOCKADDR_IN di;
+
+ struct sockaddr_in *si4 = (struct sockaddr_in *)&si;
+ struct sockaddr_in *di4 = (struct sockaddr_in *)&di;
+
+#if defined(EPMD6)
+ struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&si;
+ struct sockaddr_in6 *di6 = (struct sockaddr_in6 *)&di;
+#endif
+
+#ifdef HAVE_SOCKLEN_T
+ socklen_t st;
+#else
+ int st;
+#endif
+
+ st = sizeof(si);
+
+ /* Determine if connection is from localhost */
+ if (getpeername(fd,(struct sockaddr*) &si,&st) ||
+ st > sizeof(si)) {
+ /* Failure to get peername is regarded as non local host */
+ return EPMD_FALSE;
+ }
+
+ /* Only 127.x.x.x and connections from the host's IP address
+ allowed, no false positives */
+#if defined(EPMD6)
+ if (si.ss_family == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&(si6->sin6_addr)))
+ return EPMD_TRUE;
+
+ if (si.ss_family == AF_INET)
+#endif
+ if ((((unsigned) ntohl(si4->sin_addr.s_addr)) & 0xFF000000U) ==
+ 0x7F000000U)
+ return EPMD_TRUE;
+
+ if (getsockname(fd,(struct sockaddr*) &di,&st))
+ return EPMD_FALSE;
+
+#if defined(EPMD6)
+ if (si.ss_family == AF_INET6)
+ return IN6_ARE_ADDR_EQUAL( &(si6->sin6_addr), &(di6->sin6_addr));
+ if (si.ss_family == AF_INET)
+#endif
+ return si4->sin_addr.s_addr == di4->sin_addr.s_addr;
+#if defined(EPMD6)
+ return EPMD_FALSE;
+#endif
+}
+
static int conn_close_fd(EpmdVars *g,int fd)
{
int i;
diff --git a/erts/epmd/test/Makefile b/erts/epmd/test/Makefile
index 45c8be6809..7c5302a2f1 100644
--- a/erts/epmd/test/Makefile
+++ b/erts/epmd/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl
index a752abf33b..d5837e5b8c 100644
--- a/erts/epmd/test/epmd_SUITE.erl
+++ b/erts/epmd/test/epmd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -42,6 +43,7 @@
-export(
[
register_name/1,
+ register_name_ipv6/1,
register_names_1/1,
register_names_2/1,
register_duplicate_name/1,
@@ -75,7 +77,9 @@
buffer_overrun_2/1,
no_nonlocal_register/1,
no_nonlocal_kill/1,
- no_live_killing/1
+ no_live_killing/1,
+
+ socket_reset_before_alive2_reply_is_written/1
]).
@@ -110,7 +114,8 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [register_name, register_names_1, register_names_2,
+ [register_name, register_name_ipv6,
+ register_names_1, register_names_2,
register_duplicate_name, unicode_name, long_unicode_name,
get_port_nr, slow_get_port_nr,
unregister_others_name_1, unregister_others_name_2,
@@ -122,7 +127,8 @@ all() ->
returns_valid_populated_extra_with_nulls,
names_stdout,
{group, buffer_overrun}, no_nonlocal_register,
- no_nonlocal_kill, no_live_killing].
+ no_nonlocal_kill, no_live_killing,
+ socket_reset_before_alive2_reply_is_written].
groups() ->
[{buffer_overrun, [],
@@ -168,6 +174,24 @@ register_name(Config) when is_list(Config) ->
?line ok = close(Sock), % Unregister
ok.
+register_name_ipv6(doc) ->
+ ["Register a name over IPv6"];
+register_name_ipv6(suite) ->
+ [];
+register_name_ipv6(Config) when is_list(Config) ->
+ % Test if the host has an IPv6 loopback address
+ Res = gen_tcp:listen(0, [inet6, {ip, {0,0,0,0,0,0,0,1}}]),
+ case Res of
+ {ok,LSock} ->
+ gen_tcp:close(LSock),
+ ?line ok = epmdrun(),
+ ?line {ok,Sock} = register_node6("foobar6"),
+ ?line ok = close(Sock), % Unregister
+ ok;
+ _Error ->
+ {skip, "Host does not have an IPv6 loopback address"}
+ end.
+
register_names_1(doc) ->
["Register and unregister two nodes"];
register_names_1(suite) ->
@@ -241,13 +265,14 @@ register_node(Name) ->
register_node(Name,Port) ->
register_node_v2(Port,$M,0,5,5,Name,"").
+register_node6(Name) ->
+ register_node_v2({0,0,0,0,0,0,0,1},?DUMMY_PORT,$M,0,5,5,Name,"").
+
register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
- Utf8Name = unicode:characters_to_binary(Name),
- Req = [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot,
- put16(HVsn), put16(LVsn),
- put16(size(Utf8Name)), binary_to_list(Utf8Name),
- size16(Extra), Extra],
- case send_req(Req) of
+ register_node_v2("localhost", Port, NodeType, Prot, HVsn, LVsn, Name, Extra).
+register_node_v2(Addr, Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
+ Req = alive2_req(Port, NodeType, Prot, HVsn, LVsn, Name, Extra),
+ case send_req(Req, Addr) of
{ok,Sock} ->
case recv(Sock,4) of
{ok, [?EPMD_ALIVE2_RESP,_Res=0,_C0,_C1]} ->
@@ -937,6 +962,42 @@ no_live_killing(Config) when is_list(Config) ->
?line close(Sock3),
ok.
+socket_reset_before_alive2_reply_is_written(doc) ->
+ ["Check for regression - don't make zombie from node which "
+ "sends TCP RST at wrong time"];
+socket_reset_before_alive2_reply_is_written(suite) ->
+ [];
+socket_reset_before_alive2_reply_is_written(Config) when is_list(Config) ->
+ %% - delay_write for easier triggering of race condition
+ %% - relaxed_command_check for gracefull shutdown of epmd even if there
+ %% is stuck node.
+ ?line ok = epmdrun("-delay_write 1 -relaxed_command_check"),
+
+ %% We can't use send_req/1 directly as we want to do inet:setopts/2
+ %% on our socket.
+ ?line {ok, Sock} = connect(),
+
+ %% Issuing close/1 on such socket will result in immediate RST packet.
+ ?line ok = inet:setopts(Sock, [{linger, {true, 0}}]),
+
+ Req = alive2_req(4711, 77, 0, 5, 5, "test", []),
+ ?line ok = send(Sock, [size16(Req), Req]),
+
+ timer:sleep(500), %% Wait for the first 1/2 of delay_write before closing
+ ?line ok = close(Sock),
+
+ timer:sleep(500 + ?SHORT_PAUSE), %% Wait for the other 1/2 of delay_write
+
+ %% Wait another delay_write interval, due to delay doubling in epmd.
+ %% Should be removed when this is issue is fixed there.
+ timer:sleep(1000),
+
+ ?line {ok, SockForNames} = connect_active(),
+
+ %% And there should be no stuck nodes
+ ?line {ok, []} = do_get_names(SockForNames),
+ ?line ok = close(SockForNames),
+ ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Terminate all tests with killing epmd.
@@ -1150,7 +1211,9 @@ send_direct(Sock, Bytes) ->
end.
send_req(Req) ->
- case connect() of
+ send_req(Req, "localhost").
+send_req(Req, Addr) ->
+ case connect(Addr) of
{ok,Sock} ->
case send(Sock, [size16(Req), Req]) of
ok ->
@@ -1199,3 +1262,12 @@ flat_count([_|T], N) ->
flat_count(T, N);
flat_count([], N) -> N.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+alive2_req(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
+ Utf8Name = unicode:characters_to_binary(Name),
+ [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot,
+ put16(HVsn), put16(LVsn),
+ put16(size(Utf8Name)), binary_to_list(Utf8Name),
+ size16(Extra), Extra].
diff --git a/erts/etc/Makefile b/erts/etc/Makefile
index 5b54ef9c3e..9a14cee89c 100644
--- a/erts/etc/Makefile
+++ b/erts/etc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/common/Makefile b/erts/etc/common/Makefile
index 73ab79d145..bbf51d0efd 100644
--- a/erts/etc/common/Makefile
+++ b/erts/etc/common/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in
index 0cf965f915..8e55fa78c9 100644
--- a/erts/etc/common/Makefile.in
+++ b/erts/etc/common/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/etc/common/ct_run.c b/erts/etc/common/ct_run.c
index 9e67b94f30..548514ee6c 100644
--- a/erts/etc/common/ct_run.c
+++ b/erts/etc/common/ct_run.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c
index 09afb25182..c45626606c 100644
--- a/erts/etc/common/dialyzer.c
+++ b/erts/etc/common/dialyzer.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index 055064abc4..f9d909e01c 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index b68e109b43..af1c198281 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -72,6 +73,7 @@ static const char plusM_au_allocs[]= {
'R', /* driver_alloc */
'S', /* sl_alloc */
'T', /* temp_alloc */
+ 'Z', /* test_alloc */
'\0'
};
@@ -157,6 +159,8 @@ static char *plusr_val_switches[] = {
/* +z arguments with values */
static char *plusz_val_switches[] = {
"dbbl",
+ "dntgc",
+ "ebwt",
NULL
};
@@ -715,7 +719,7 @@ int main(int argc, char **argv)
* on itself here. We'll avoid doing that.
*/
if (strcmp(argv[i], "-make") == 0) {
- add_args("-noshell", "-noinput", "-s", "make", "all", NULL);
+ add_args("-noshell", "-noinput", "-s", "make", "all_or_nothing", NULL);
add_Eargs("-B");
haltAfterwards = 1;
i = argc; /* Skip rest of command line */
@@ -808,6 +812,7 @@ int main(int argc, char **argv)
case 'a':
case 'A':
case 'b':
+ case 'C':
case 'e':
case 'i':
case 'n':
@@ -881,6 +886,19 @@ int main(int argc, char **argv)
}
add_Eargs(argv[i]);
break;
+ case 'c':
+ argv[i][0] = '-';
+ if (argv[i][2] == '\0' && i+1 < argc) {
+ if (sys_strcmp(argv[i+1], "true") == 0
+ || sys_strcmp(argv[i+1], "false") == 0) {
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ break;
+ }
+ }
+ add_Eargs(argv[i]);
+ break;
case 'M': {
int x;
for (x = 0; plusM_au_allocs[x]; x++)
@@ -1150,15 +1168,15 @@ usage_aux(void)
#endif
"] "
"[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] "
- "[-args_file FILENAME] [+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] "
- "[+h HEAP_SIZE_OPTION] [+K BOOLEAN] "
+ "[-args_file FILENAME] [+A THREADS] [+a SIZE] [+B[c|d|i]] [+c [BOOLEAN]] "
+ "[+C MODE] [+h HEAP_SIZE_OPTION] [+K BOOLEAN] "
"[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+Q MAX_PORTS] "
"[+R COMPAT_REL] "
"[+r] [+rg READER_GROUPS_LIMIT] [+s SCHEDULER_OPTION] "
"[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] "
"[+SP PERCENTAGE_SCHEDULERS:PERCENTAGE_SCHEDULERS_ONLINE] "
"[+T LEVEL] [+V] [+v] "
- "[+W<i|w>] [+z MISC_OPTION] [args ...]\n");
+ "[+W<i|w|e>] [+z MISC_OPTION] [args ...]\n");
exit(1);
}
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index c92fedee4b..7fd02ed436 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index 2830641802..1a826221fb 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -109,7 +110,7 @@
# include <sys/time.h>
# include <unistd.h>
# include <signal.h>
-# if defined(CORRECT_USING_TIMES)
+# if defined(OS_MONOTONIC_TIME_USING_TIMES)
# include <sys/times.h>
# include <limits.h>
# endif
@@ -117,11 +118,12 @@
#define HEART_COMMAND_ENV "HEART_COMMAND"
#define ERL_CRASH_DUMP_SECONDS_ENV "ERL_CRASH_DUMP_SECONDS"
+#define HEART_KILL_SIGNAL "HEART_KILL_SIGNAL"
-#define MSG_HDR_SIZE 2
-#define MSG_HDR_PLUS_OP_SIZE 3
-#define MSG_BODY_SIZE 2048
-#define MSG_TOTAL_SIZE 2050
+#define MSG_HDR_SIZE (2)
+#define MSG_HDR_PLUS_OP_SIZE (3)
+#define MSG_BODY_SIZE (2048)
+#define MSG_TOTAL_SIZE (2050)
unsigned char cmd[MSG_BODY_SIZE];
@@ -470,10 +472,6 @@ message_loop(erlin_fd, erlout_fd)
switch (mp->op) {
case HEART_BEAT:
timestamp(&last_received);
-#ifdef USE_WATCHDOG
- /* reset the hardware watchdog timer */
- wd_reset();
-#endif
break;
case SHUT_DOWN:
return R_SHUT_DOWN;
@@ -555,14 +553,22 @@ kill_old_erlang(void){
static void
kill_old_erlang(void){
pid_t pid;
- int i;
- int res;
+ int i, res;
+ int sig = SIGKILL;
+ char *sigenv = NULL;
+
+ sigenv = get_env(HEART_KILL_SIGNAL);
+ if (sigenv && strcmp(sigenv, "SIGABRT") == 0) {
+ print_error("kill signal SIGABRT requested");
+ sig = SIGABRT;
+ }
+
if(heart_beat_kill_pid != 0){
pid = (pid_t) heart_beat_kill_pid;
- res = kill(pid,SIGKILL);
+ res = kill(pid,sig);
for(i=0; i < 5 && res == 0; ++i){
sleep(1);
- res = kill(pid,SIGKILL);
+ res = kill(pid,sig);
}
if(errno != ESRCH){
print_error("Unable to kill old process, "
@@ -708,14 +714,12 @@ do_terminate(int erlin_fd, int reason) {
print_error("Would reboot. Terminating.");
else {
kill_old_erlang();
- /* suppress gcc warning with 'if' */
ret = system(command);
print_error("Executed \"%s\" -> %d. Terminating.",command, ret);
}
free_env_val(command);
} else {
kill_old_erlang();
- /* suppress gcc warning with 'if' */
ret = system((char*)&cmd[0]);
print_error("Executed \"%s\" -> %d. Terminating.",cmd, ret);
}
@@ -1084,9 +1088,9 @@ time_t timestamp(time_t *res)
return r;
}
-#elif defined(HAVE_GETHRTIME) || defined(GETHRTIME_WITH_CLOCK_GETTIME)
+#elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME) || defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
-#if defined(GETHRTIME_WITH_CLOCK_GETTIME)
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
typedef long long SysHrTime;
SysHrTime sys_gethrtime(void);
@@ -1095,7 +1099,7 @@ SysHrTime sys_gethrtime(void)
{
struct timespec ts;
long long result;
- if (clock_gettime(CLOCK_MONOTONIC,&ts) != 0) {
+ if (clock_gettime(MONOTONIC_CLOCK_ID,&ts) != 0) {
print_error("Fatal, could not get clock_monotonic value, terminating! "
"errno = %d\n", errno);
exit(1);
@@ -1122,7 +1126,7 @@ time_t timestamp(time_t *res)
return r;
}
-#elif defined(CORRECT_USING_TIMES)
+#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
# ifdef NO_SYSCONF
# include <sys/param.h>
diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c
index 9ec4192667..e298c5e7f7 100644
--- a/erts/etc/common/inet_gethost.c
+++ b/erts/etc/common/inet_gethost.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/run_erl_common.c b/erts/etc/common/run_erl_common.c
index 20b78eb05e..c03d5e3ae2 100644
--- a/erts/etc/common/run_erl_common.c
+++ b/erts/etc/common/run_erl_common.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -32,6 +33,10 @@
#include <time.h>
#include <unistd.h>
+#ifdef __ANDROID__
+# include <termios.h>
+#endif
+
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
#endif
diff --git a/erts/etc/common/run_erl_common.h b/erts/etc/common/run_erl_common.h
index 14207ee4de..cecf7521f9 100644
--- a/erts/etc/common/run_erl_common.h
+++ b/erts/etc/common/run_erl_common.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/run_erl_vsn.h b/erts/etc/common/run_erl_vsn.h
index f6ac753bde..2c3e67e81c 100644
--- a/erts/etc/common/run_erl_vsn.h
+++ b/erts/etc/common/run_erl_vsn.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/safe_string.c b/erts/etc/common/safe_string.c
index b2f8814408..cdcdbf16f0 100644
--- a/erts/etc/common/safe_string.c
+++ b/erts/etc/common/safe_string.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/safe_string.h b/erts/etc/common/safe_string.h
index ff063fe641..f9d2b2023a 100644
--- a/erts/etc/common/safe_string.h
+++ b/erts/etc/common/safe_string.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/to_erl_common.c b/erts/etc/common/to_erl_common.c
index ab706fffe0..8aa94ccfa4 100644
--- a/erts/etc/common/to_erl_common.c
+++ b/erts/etc/common/to_erl_common.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/to_erl_common.h b/erts/etc/common/to_erl_common.h
index 9967db94b8..a139da418f 100644
--- a/erts/etc/common/to_erl_common.h
+++ b/erts/etc/common/to_erl_common.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c
index b45867f845..0aa0996808 100644
--- a/erts/etc/common/typer.c
+++ b/erts/etc/common/typer.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/ose/run_erl.c b/erts/etc/ose/run_erl.c
index 8bc49a485e..6775525297 100644
--- a/erts/etc/ose/run_erl.c
+++ b/erts/etc/ose/run_erl.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -615,7 +616,7 @@ int run_erl(int argc,char **argv) {
returns */
PROCESS main_pid;
hunt_in_block("run_erl","main",&main_pid);
- sig = alloc(sizeof(sig),ERTS_SIGNAL_RUN_ERL_DAEMON);
+ sig = alloc(sizeof(*sig),ERTS_SIGNAL_RUN_ERL_DAEMON);
send(&sig,main_pid);
sig = receive(sigsel);
pid = sender(&sig);
diff --git a/erts/etc/ose/run_erl.h b/erts/etc/ose/run_erl.h
index 128f551670..bdc8b6c355 100644
--- a/erts/etc/ose/run_erl.h
+++ b/erts/etc/ose/run_erl.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/ose/run_erl_main.c b/erts/etc/ose/run_erl_main.c
index 2d92924ff2..8895c773a1 100644
--- a/erts/etc/ose/run_erl_main.c
+++ b/erts/etc/ose/run_erl_main.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/unix/Install.src b/erts/etc/unix/Install.src
index 8eb1db75bd..6634ae31d3 100644
--- a/erts/etc/unix/Install.src
+++ b/erts/etc/unix/Install.src
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/etc/unix/Makefile b/erts/etc/unix/Makefile
index c137a31ec2..04ae11de3b 100644
--- a/erts/etc/unix/Makefile
+++ b/erts/etc/unix/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/etc/unix/README b/erts/etc/unix/README
index 45b4aec2da..6bda610a03 100644
--- a/erts/etc/unix/README
+++ b/erts/etc/unix/README
@@ -3,16 +3,17 @@
Copyright Ericsson AB 1996-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/etc/unix/RELNOTES b/erts/etc/unix/RELNOTES
index d1a110fce3..629867d2ae 100644
--- a/erts/etc/unix/RELNOTES
+++ b/erts/etc/unix/RELNOTES
@@ -3,16 +3,17 @@
Copyright Ericsson AB 1996-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src
index 78fefbea55..2a806bb2f1 100644
--- a/erts/etc/unix/cerl.src
+++ b/erts/etc/unix/cerl.src
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -43,6 +44,7 @@
# -gcov Run emulator compiled for gcov
# -valgrind Run emulator compiled for valgrind
# -lcnt Run emulator compiled for lock counting
+# -icount Run emulator compiled for instruction counting
# -nox Unset the DISPLAY variable to disable us of X Windows
#
# FIXME For GDB you can also set the break point using "-break FUNCTION".
@@ -180,6 +182,11 @@ while [ $# -gt 0 ]; do
cargs="$cargs -frmptr"
TYPE=.frmptr
;;
+ "-icount")
+ shift
+ cargs="$cargs -icount"
+ TYPE=.icount
+ ;;
"-dump")
shift
GDB=dump
@@ -375,7 +382,9 @@ elif [ "x$GDB" = "xegdb" ]; then
# Set annotation level for gdb in emacs 22 and higher. Seems to
# be working with level 1 for emacs 22 and level 3 for emacs 23...
emacs_major=`$EMACS --version | head -1 | sed 's,^[^0-9]*\([0-9]*\).*,\1,g'`
- if [ '!' -z "$emacs_major" -a $emacs_major -gt 22 ]; then
+ if [ '!' -z "$emacs_major" -a $emacs_major -gt 23 ]; then
+ GDBARGS="-i=mi "
+ elif [ '!' -z "$emacs_major" -a $emacs_major -gt 22 ]; then
GDBARGS="--annotate=3 "
elif [ '!' -z "$emacs_major" -a $emacs_major -gt 21 ]; then
GDBARGS="--annotate=1 "
diff --git a/erts/etc/unix/dyn_erl.c b/erts/etc/unix/dyn_erl.c
index 984935417e..4eebfae50a 100644
--- a/erts/etc/unix/dyn_erl.c
+++ b/erts/etc/unix/dyn_erl.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/unix/erl.src.src b/erts/etc/unix/erl.src.src
index ce5d2b5def..94c6f9f854 100644
--- a/erts/etc/unix/erl.src.src
+++ b/erts/etc/unix/erl.src.src
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 141d51824f..19d67de92f 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -146,14 +147,10 @@ define etp-1
etp-immediate-1 ($arg0)
else
# (($arg0) & 0x3) == 0
- if (($arg0) == 0x0)
+ if (($arg0) == etp_the_non_value)
printf "<the non-value>"
else
- if (($arg0) == 0x4)
- printf "<the non-value debug>"
- else
- etp-cp-1 ($arg0)
- end
+ etp-cp-1 ($arg0)
end
end
end
@@ -355,7 +352,32 @@ define etp-boxed-1
etp-array-1 ((Eterm*)(($arg0)&~0x3)) ($arg1) ($arg1) \
1 ((((Eterm*)(($arg0)&~0x3))[0]>>6)+1) '}'
else
- etp-boxed-immediate-1 ($arg0)
+ if (((Eterm*)(($arg0) & ~0x3))[0] & 0x3c) == 0x3c
+ # A map
+ if (((Eterm*)(($arg0) & ~0x3))[0] & 0xc0) == 0x0
+ # Flat map
+ printf "#{Keys:"
+ etp-1 ((flatmap_t*)(($arg0)&~0x3))->keys (($arg1)+1)
+ printf " Values:{"
+ etp-array-1 ((Eterm*)(($arg0)&~0x3)+3) ($arg1) ($arg1) \
+ 0 ((flatmap_t*)(($arg0)&~0x3))->size '}'
+ printf "}"
+ else
+ # Hashmap
+ printf "#<%x>{", (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff)
+ if (((Eterm*)(($arg0) & ~0x3))[0] & 0xc0) >= 0x80
+ # head bitmap/array
+ etp-bitmap-array-1 ((Eterm*)(($arg0)&~0x3)+2) ($arg1) ($arg1) \
+ 0 (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) '}'
+ else
+ # node bitmap
+ etp-bitmap-array-1 ((Eterm*)(($arg0)&~0x3)+1) ($arg1) ($arg1) \
+ 0 (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) '}'
+ end
+ end
+ else
+ etp-boxed-immediate-1 ($arg0)
+ end
end
end
end
@@ -478,6 +500,36 @@ define etp-array-1
end
end
+define etp-bitmap-array-1
+# Args: Eterm* p, int depth, int width, int pos, int bitmap, int end_char
+#
+# Reentrant
+#
+# Same as etp-array-1 with size = bitcount(bitmap)
+#
+ if ($arg4) & 1 != 0
+ if (($arg1) < $etp_max_depth) && (($arg2) < $etp_max_depth)
+ etp-1 (($arg0)[($arg3)]) (($arg1)+1)
+ if (($arg4) & (($arg4)-1)) != 0
+ printf ","
+ end
+ etp-bitmap-array-1 ($arg0) ($arg1) (($arg2)+1) (($arg3)+1) (($arg4)>>1) ($arg5)
+ else
+ printf "...%c", ($arg5)
+ end
+ else
+ if ($arg4) == 0
+ printf "%c", ($arg5)
+ else
+ etp-bitmap-array-1 $arg0 $arg1 $arg2 $arg3 (($arg4)>>1) $arg5
+
+ # WARNING: One might be tempted to optimize the bitcounting here
+ # by passing the bitmap argument as ($arg4 & ($arg4 - 1)). This is a very
+ # bad idea as arguments are passed as string substitution.
+ # The size of $arg4 would thus grow exponentially for each recursion.
+ end
+ end
+end
#define etpa-1
@@ -1065,8 +1117,8 @@ define etp-cp-1
set $etp_cp_mid = $etp_cp_low + ($etp_cp_high-$etp_cp_low)/2
end
if $etp_cp_p
- # 12 = MI_FUNCTIONS
- set $etp_cp_low = (Eterm**)($etp_cp_p->start + 12)
+ # 13 = MI_FUNCTIONS
+ set $etp_cp_low = (Eterm**)($etp_cp_p->start + 13)
# 0 = MI_NUM_FUNCTIONS
set $etp_cp_high = $etp_cp_low +$etp_cp_p->start[0]
set $etp_cp_p = 0
@@ -3514,11 +3566,13 @@ end
define etp-carrier-blocks
set $etp_crr = (Carrier_t*) $arg0
set $etp_alc = (Allctr_t*)($etp_crr->allctr.counter & ~7)
+ set $etp_crr_end = ((char*)$etp_crr + ($etp_crr->chdr & ~7) - (sizeof(void*) & ~8))
set $etp_blk = (Block_t*) ((char*)$etp_crr + $etp_alc->mbc_header_size)
set $etp_prev_blk = 0
set $etp_error_cnt = 0
set $etp_ablk_cnt = 0
set $etp_fblk_cnt = 0
+ set $etp_aborted = 0
if $argc == 2
set $etp_be_silent = $arg1
@@ -3565,16 +3619,23 @@ define etp-carrier-blocks
end
set $etp_prev_blk = $etp_blk
set $etp_blk = (Block_t*) ((char*)$etp_blk + $etp_blk_sz)
+ if $etp_blk < (Block_t*) ((char*)$etp_prev_blk + $etp_alc->min_block_size) || $etp_blk >= $etp_crr_end
+ printf "ERROR: Invalid size of block at %#lx. ABORTING\n", $etp_prev_blk
+ set $etp_aborted = 1
+ loop_break
+ end
end
- if ((char*)$etp_blk + $etp_blk_sz) != ((char*)$etp_crr + ($etp_crr->chdr & ~7))
- printf "ERROR: Last block not at end of carrier\n"
- set $etp_error_cnt = $etp_error_cnt + 1
+ if !$etp_aborted
+ if ((char*)$etp_blk + $etp_blk_sz) != $etp_crr_end
+ printf "ERROR: Last block not at end of carrier\n"
+ set $etp_error_cnt = $etp_error_cnt + 1
+ end
+ printf "Allocated blocks: %u\n", $etp_ablk_cnt
+ printf "Free blocks: %u\n", $etp_fblk_cnt
end
- printf "Allocated blocks: %u\n", $etp_ablk_cnt
- printf "Free blocks: %u\n", $etp_fblk_cnt
if $etp_error_cnt
- printf "%u ERRORs reported above\n", $etp-error-cnt
+ printf "%u ERRORs reported above\n", $etp_error_cnt
end
end
diff --git a/erts/etc/unix/etp-thr.py b/erts/etc/unix/etp-thr.py
index 64fb858d20..16bc7f4016 100644
--- a/erts/etc/unix/etp-thr.py
+++ b/erts/etc/unix/etp-thr.py
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/etc/unix/etp_commands.erl b/erts/etc/unix/etp_commands.erl
index 66cb76edbc..fe16a71876 100644
--- a/erts/etc/unix/etp_commands.erl
+++ b/erts/etc/unix/etp_commands.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/etc/unix/etp_commands.mk b/erts/etc/unix/etp_commands.mk
index 1d9a269b68..def6f7bda0 100644
--- a/erts/etc/unix/etp_commands.mk
+++ b/erts/etc/unix/etp_commands.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/unix/format_man_pages b/erts/etc/unix/format_man_pages
index 93dcdcd8fa..7abe65cecb 100644
--- a/erts/etc/unix/format_man_pages
+++ b/erts/etc/unix/format_man_pages
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 1996-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c
index 049e83f9e4..c8414030ca 100644
--- a/erts/etc/unix/run_erl.c
+++ b/erts/etc/unix/run_erl.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/unix/setuid_socket_wrap.c b/erts/etc/unix/setuid_socket_wrap.c
index 3f0657770c..59ed8eae6f 100644
--- a/erts/etc/unix/setuid_socket_wrap.c
+++ b/erts/etc/unix/setuid_socket_wrap.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/unix/start.src b/erts/etc/unix/start.src
index 8479be0987..377f5e85c8 100644
--- a/erts/etc/unix/start.src
+++ b/erts/etc/unix/start.src
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/unix/start_erl.src b/erts/etc/unix/start_erl.src
index ea8022c449..b889101783 100644
--- a/erts/etc/unix/start_erl.src
+++ b/erts/etc/unix/start_erl.src
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/unix/to_erl.c b/erts/etc/unix/to_erl.c
index 38a94ed9c3..82d3218964 100644
--- a/erts/etc/unix/to_erl.c
+++ b/erts/etc/unix/to_erl.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c
index 9d85d642ab..82bae947d4 100644
--- a/erts/etc/win32/Install.c
+++ b/erts/etc/win32/Install.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/etc/win32/Makefile b/erts/etc/win32/Makefile
index cc9021da70..12c04fc9a5 100644
--- a/erts/etc/win32/Makefile
+++ b/erts/etc/win32/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/Nmakefile.start_erl b/erts/etc/win32/Nmakefile.start_erl
index 5bf9fd78d5..cf83713bab 100644
--- a/erts/etc/win32/Nmakefile.start_erl
+++ b/erts/etc/win32/Nmakefile.start_erl
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/beam.rc b/erts/etc/win32/beam.rc
index cd7db67d4d..9e137ecd62 100644
--- a/erts/etc/win32/beam.rc
+++ b/erts/etc/win32/beam.rc
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1997-2009. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/erts/etc/win32/cygwin_tools/erl b/erts/etc/win32/cygwin_tools/erl
index 576825c4be..51a7be5584 100755
--- a/erts/etc/win32/cygwin_tools/erl
+++ b/erts/etc/win32/cygwin_tools/erl
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/erlc b/erts/etc/win32/cygwin_tools/erlc
index a18ec27bf4..588b53b1be 100755
--- a/erts/etc/win32/cygwin_tools/erlc
+++ b/erts/etc/win32/cygwin_tools/erlc
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/javac.sh b/erts/etc/win32/cygwin_tools/javac.sh
index f9ee24593f..f2f97ef152 100755
--- a/erts/etc/win32/cygwin_tools/javac.sh
+++ b/erts/etc/win32/cygwin_tools/javac.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh b/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh
index 20fe143890..0f87f3d077 100755
--- a/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh
+++ b/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/make_local_ini.sh b/erts/etc/win32/cygwin_tools/make_local_ini.sh
index 8e29573dc4..0bcb362ffe 100755
--- a/erts/etc/win32/cygwin_tools/make_local_ini.sh
+++ b/erts/etc/win32/cygwin_tools/make_local_ini.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/mingw/ar.sh b/erts/etc/win32/cygwin_tools/mingw/ar.sh
index 5b8f58e5de..2ebfe4e435 100755
--- a/erts/etc/win32/cygwin_tools/mingw/ar.sh
+++ b/erts/etc/win32/cygwin_tools/mingw/ar.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/mingw/cc.sh b/erts/etc/win32/cygwin_tools/mingw/cc.sh
index ae284893fa..5993f70686 100755
--- a/erts/etc/win32/cygwin_tools/mingw/cc.sh
+++ b/erts/etc/win32/cygwin_tools/mingw/cc.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/mingw/coffix.c b/erts/etc/win32/cygwin_tools/mingw/coffix.c
index 5dff030a69..383c422008 100644
--- a/erts/etc/win32/cygwin_tools/mingw/coffix.c
+++ b/erts/etc/win32/cygwin_tools/mingw/coffix.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh b/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh
index f3865c8cae..8da91dd0ef 100755
--- a/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh
+++ b/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/mingw/ld.sh b/erts/etc/win32/cygwin_tools/mingw/ld.sh
index 145bd2fad9..16caf0b6d2 100755
--- a/erts/etc/win32/cygwin_tools/mingw/ld.sh
+++ b/erts/etc/win32/cygwin_tools/mingw/ld.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/mingw/mc.sh b/erts/etc/win32/cygwin_tools/mingw/mc.sh
index 873149172a..4462bfc5d3 100755
--- a/erts/etc/win32/cygwin_tools/mingw/mc.sh
+++ b/erts/etc/win32/cygwin_tools/mingw/mc.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/mingw/rc.sh b/erts/etc/win32/cygwin_tools/mingw/rc.sh
index 37296f9e9f..b8a2d2fbcf 100755
--- a/erts/etc/win32/cygwin_tools/mingw/rc.sh
+++ b/erts/etc/win32/cygwin_tools/mingw/rc.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/vc/ar.sh b/erts/etc/win32/cygwin_tools/vc/ar.sh
index 24d275b01a..e0bd1bd5ca 100755
--- a/erts/etc/win32/cygwin_tools/vc/ar.sh
+++ b/erts/etc/win32/cygwin_tools/vc/ar.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/vc/cc.sh b/erts/etc/win32/cygwin_tools/vc/cc.sh
index 4939465d08..651b6e098d 100755
--- a/erts/etc/win32/cygwin_tools/vc/cc.sh
+++ b/erts/etc/win32/cygwin_tools/vc/cc.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -266,7 +267,7 @@ for x in $SOURCES; do
echo
echo
after_sed=`date '+%s'`
- echo Made dependencises for $x':' `expr $after_sed '-' $start_time` 's' >&2
+ echo Made dependencies for $x':' `expr $after_sed '-' $start_time` 's' >&2
fi
else
cat $MSG_FILE
diff --git a/erts/etc/win32/cygwin_tools/vc/cc_wrap.c b/erts/etc/win32/cygwin_tools/vc/cc_wrap.c
index 18ecc31c17..b42e0e1037 100644
--- a/erts/etc/win32/cygwin_tools/vc/cc_wrap.c
+++ b/erts/etc/win32/cygwin_tools/vc/cc_wrap.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/cygwin_tools/vc/coffix.c b/erts/etc/win32/cygwin_tools/vc/coffix.c
index dee0132a61..0633c6ddea 100644
--- a/erts/etc/win32/cygwin_tools/vc/coffix.c
+++ b/erts/etc/win32/cygwin_tools/vc/coffix.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/cygwin_tools/vc/emu_cc.sh b/erts/etc/win32/cygwin_tools/vc/emu_cc.sh
index 6c179aed00..fb6ee2d7a2 100755
--- a/erts/etc/win32/cygwin_tools/vc/emu_cc.sh
+++ b/erts/etc/win32/cygwin_tools/vc/emu_cc.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/vc/ld.sh b/erts/etc/win32/cygwin_tools/vc/ld.sh
index 406c63ffee..ff538122b2 100755
--- a/erts/etc/win32/cygwin_tools/vc/ld.sh
+++ b/erts/etc/win32/cygwin_tools/vc/ld.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2002-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/vc/ld_wrap.c b/erts/etc/win32/cygwin_tools/vc/ld_wrap.c
index 7fb3c145ee..000c13befd 100644
--- a/erts/etc/win32/cygwin_tools/vc/ld_wrap.c
+++ b/erts/etc/win32/cygwin_tools/vc/ld_wrap.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/cygwin_tools/vc/mc.sh b/erts/etc/win32/cygwin_tools/vc/mc.sh
index 676b072655..2de5cbba9b 100755
--- a/erts/etc/win32/cygwin_tools/vc/mc.sh
+++ b/erts/etc/win32/cygwin_tools/vc/mc.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/cygwin_tools/vc/rc.sh b/erts/etc/win32/cygwin_tools/vc/rc.sh
index 054c672e64..414ffa0448 100755
--- a/erts/etc/win32/cygwin_tools/vc/rc.sh
+++ b/erts/etc/win32/cygwin_tools/vc/rc.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2002-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/etc/win32/erl.c b/erts/etc/win32/erl.c
index 772b668586..59693955a5 100644
--- a/erts/etc/win32/erl.c
+++ b/erts/etc/win32/erl.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erl.rc b/erts/etc/win32/erl.rc
index 88213d48f2..e8848e7969 100644
--- a/erts/etc/win32/erl.rc
+++ b/erts/etc/win32/erl.rc
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1998-2009. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/erts/etc/win32/erl_log.c b/erts/etc/win32/erl_log.c
index 85cc49e0e3..2a873dffac 100644
--- a/erts/etc/win32/erl_log.c
+++ b/erts/etc/win32/erl_log.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_global.h b/erts/etc/win32/erlsrv/erlsrv_global.h
index f25e09ea45..f535599cf1 100644
--- a/erts/etc/win32/erlsrv/erlsrv_global.h
+++ b/erts/etc/win32/erlsrv/erlsrv_global.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.c b/erts/etc/win32/erlsrv/erlsrv_interactive.c
index 260f0d9b97..d2236ac9f7 100644
--- a/erts/etc/win32/erlsrv/erlsrv_interactive.c
+++ b/erts/etc/win32/erlsrv/erlsrv_interactive.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.h b/erts/etc/win32/erlsrv/erlsrv_interactive.h
index bc6e55fdef..a83f5a4b85 100644
--- a/erts/etc/win32/erlsrv/erlsrv_interactive.h
+++ b/erts/etc/win32/erlsrv/erlsrv_interactive.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_main.c b/erts/etc/win32/erlsrv/erlsrv_main.c
index 6d8e208fc8..caca18de00 100644
--- a/erts/etc/win32/erlsrv/erlsrv_main.c
+++ b/erts/etc/win32/erlsrv/erlsrv_main.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.c b/erts/etc/win32/erlsrv/erlsrv_registry.c
index ad50da89a4..f95f4ef074 100644
--- a/erts/etc/win32/erlsrv/erlsrv_registry.c
+++ b/erts/etc/win32/erlsrv/erlsrv_registry.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.h b/erts/etc/win32/erlsrv/erlsrv_registry.h
index 4be10e9ff2..3aa265686a 100644
--- a/erts/etc/win32/erlsrv/erlsrv_registry.h
+++ b/erts/etc/win32/erlsrv/erlsrv_registry.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_service.c b/erts/etc/win32/erlsrv/erlsrv_service.c
index 2e56c579a2..d9fa165355 100644
--- a/erts/etc/win32/erlsrv/erlsrv_service.c
+++ b/erts/etc/win32/erlsrv/erlsrv_service.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_service.h b/erts/etc/win32/erlsrv/erlsrv_service.h
index c46689d83e..c87292325c 100644
--- a/erts/etc/win32/erlsrv/erlsrv_service.h
+++ b/erts/etc/win32/erlsrv/erlsrv_service.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_util.c b/erts/etc/win32/erlsrv/erlsrv_util.c
index 4b1ba071e8..800395ff12 100644
--- a/erts/etc/win32/erlsrv/erlsrv_util.c
+++ b/erts/etc/win32/erlsrv/erlsrv_util.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/erlsrv/erlsrv_util.h b/erts/etc/win32/erlsrv/erlsrv_util.h
index 6881906a52..1afcd1dd7e 100644
--- a/erts/etc/win32/erlsrv/erlsrv_util.h
+++ b/erts/etc/win32/erlsrv/erlsrv_util.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/init_file.c b/erts/etc/win32/init_file.c
index d452afa65c..93d82b1823 100644
--- a/erts/etc/win32/init_file.c
+++ b/erts/etc/win32/init_file.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/init_file.h b/erts/etc/win32/init_file.h
index ae40e88520..404b5fd03b 100644
--- a/erts/etc/win32/init_file.h
+++ b/erts/etc/win32/init_file.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/msys_tools/erl b/erts/etc/win32/msys_tools/erl
index 525253fd84..110d48c769 100644
--- a/erts/etc/win32/msys_tools/erl
+++ b/erts/etc/win32/msys_tools/erl
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/erlc b/erts/etc/win32/msys_tools/erlc
index 3f53ef7f4f..b50090b6de 100644
--- a/erts/etc/win32/msys_tools/erlc
+++ b/erts/etc/win32/msys_tools/erlc
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/javac.sh b/erts/etc/win32/msys_tools/javac.sh
index 2d884bc2c8..5b51648a19 100644
--- a/erts/etc/win32/msys_tools/javac.sh
+++ b/erts/etc/win32/msys_tools/javac.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/make_bootstrap_ini.sh b/erts/etc/win32/msys_tools/make_bootstrap_ini.sh
index b61965f546..1797f67c78 100644
--- a/erts/etc/win32/msys_tools/make_bootstrap_ini.sh
+++ b/erts/etc/win32/msys_tools/make_bootstrap_ini.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/make_local_ini.sh b/erts/etc/win32/msys_tools/make_local_ini.sh
index 6c5d84c4f5..11f722e7f8 100644
--- a/erts/etc/win32/msys_tools/make_local_ini.sh
+++ b/erts/etc/win32/msys_tools/make_local_ini.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/vc/ar.sh b/erts/etc/win32/msys_tools/vc/ar.sh
index f4c61e1d92..4c98e3cc29 100644
--- a/erts/etc/win32/msys_tools/vc/ar.sh
+++ b/erts/etc/win32/msys_tools/vc/ar.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/vc/cc.sh b/erts/etc/win32/msys_tools/vc/cc.sh
index 38b3d2ee81..72005862ed 100644
--- a/erts/etc/win32/msys_tools/vc/cc.sh
+++ b/erts/etc/win32/msys_tools/vc/cc.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -241,7 +242,7 @@ for x in $SOURCES; do
if [ $PREPROCESSING = true ]; then
output_flag="-E"
else
- output_flag="-c -Fo`cmd //C echo ${output_filename}`"
+ output_flag="-FS -c -Fo`cmd //C echo ${output_filename}`"
fi
params="$COMMON_CFLAGS $MD $DEBUG_FLAGS $OPTIMIZE_FLAGS \
$CMD ${output_flag} $MPATH"
@@ -249,6 +250,8 @@ for x in $SOURCES; do
echo cc.sh "$SAVE" >>$CC_SH_DEBUG_LOG
echo cl.exe $params >>$CC_SH_DEBUG_LOG
fi
+ # MSYS2 (currently) converts the paths wrong, avoid it
+ export MSYS2_ARG_CONV_EXCL=-FoC
eval cl.exe $params >$MSG_FILE 2>$ERR_FILE
RES=$?
if test $PREPROCESSING = false; then
@@ -265,7 +268,7 @@ for x in $SOURCES; do
echo
echo
after_sed=`date '+%s'`
- echo Made dependencises for $x':' `expr $after_sed '-' $start_time` 's' >&2
+ echo Made dependencies for $x':' `expr $after_sed '-' $start_time` 's' >&2
fi
else
cat $MSG_FILE
@@ -273,6 +276,7 @@ for x in $SOURCES; do
fi
rm -f $ERR_FILE $MSG_FILE
if [ $RES != 0 ]; then
+ echo Failed: cl.exe $params
rm -rf $TMPOBJDIR
exit $RES
fi
@@ -311,7 +315,10 @@ if [ $LINKING = true ]; then
stdlib="-lLIBMTD";;
esac
# And finally call the next script to do the linking...
- params="$out_spec $LINKCMD $stdlib"
+ params="$out_spec $LINKCMD $stdlib"
+ if [ "X$CC_SH_DEBUG_LOG" != "X" ]; then
+ echo ld.sh $ACCUM_OBJECTS $params
+ fi
eval ld.sh $ACCUM_OBJECTS $params
RES=$?
fi
diff --git a/erts/etc/win32/msys_tools/vc/coffix.c b/erts/etc/win32/msys_tools/vc/coffix.c
index 1773b222fe..4f21cfc389 100644
--- a/erts/etc/win32/msys_tools/vc/coffix.c
+++ b/erts/etc/win32/msys_tools/vc/coffix.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/msys_tools/vc/emu_cc.sh b/erts/etc/win32/msys_tools/vc/emu_cc.sh
index 68ce4e359f..10d59214ea 100644
--- a/erts/etc/win32/msys_tools/vc/emu_cc.sh
+++ b/erts/etc/win32/msys_tools/vc/emu_cc.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -28,6 +29,7 @@ WTOOLDIR0=`win2msys_path.sh "$TOOLDIR"`
WTOOLDIR=`cmd //C echo $WTOOLDIR0`
# Do primitive 'make'
newer_exe=`find $TOOLDIR -newer $COFFIX.c -name coffix.exe -print`
+export MSYS2_ARG_CONV_EXCL="-FeC"
if [ -z $newer_exe ]; then
echo recompiling $COFFIX.exe
cl.exe -Fe${WTOOLDIR}/coffix.exe ${WTOOLDIR}/coffix.c
diff --git a/erts/etc/win32/msys_tools/vc/ld.sh b/erts/etc/win32/msys_tools/vc/ld.sh
index 0fcbf6f7d9..11b2fc077b 100644
--- a/erts/etc/win32/msys_tools/vc/ld.sh
+++ b/erts/etc/win32/msys_tools/vc/ld.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/msys_tools/vc/mc.sh b/erts/etc/win32/msys_tools/vc/mc.sh
index 27d985f73e..14b5ebaa8f 100644
--- a/erts/etc/win32/msys_tools/vc/mc.sh
+++ b/erts/etc/win32/msys_tools/vc/mc.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -79,9 +80,14 @@ if [ -n "$OUTPUT_DIRNAME" ]; then
exit $RES
fi
fi
+# MSYS2 (currently) converts the paths wrong, avoid it
+export MSYS2_ARG_CONV_EXCL=
eval $MCC "$CMD" >/tmp/mc.exe.${p}.1 2>/tmp/mc.exe.${p}.2
RES=$?
-tail +2 /tmp/mc.exe.${p}.2 >&2
+if [ $RES != 0 ]; then
+ echo Failed: $MCC "$CMD"
+fi
+tail -n +2 /tmp/mc.exe.${p}.2 >&2
cat /tmp/mc.exe.${p}.1
rm -f /tmp/mc.exe.${p}.2 /tmp/mc.exe.${p}.1
exit $RES
diff --git a/erts/etc/win32/msys_tools/vc/rc.sh b/erts/etc/win32/msys_tools/vc/rc.sh
index dfa9e324db..1f8ade17cb 100644
--- a/erts/etc/win32/msys_tools/vc/rc.sh
+++ b/erts/etc/win32/msys_tools/vc/rc.sh
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -78,9 +79,14 @@ if [ "X$RC_SH_DEBUG_LOG" != "X" ]; then
echo rc.sh "$SAVE" >>$RC_SH_DEBUG_LOG
echo rc.exe $CMD >>$RC_SH_DEBUG_LOG
fi
+# MSYS2 (currently) converts the paths wrong, avoid it
+export MSYS2_ARG_CONV_EXCL=-Fo
eval $RCC "$CMD" >/tmp/rc.exe.${p}.1 2>/tmp/rc.exe.${p}.2
RES=$?
-tail +2 /tmp/rc.exe.${p}.2 >&2
+if [ $RES != 0 ]; then
+ echo Failed: $RCC "$CMD"
+fi
+tail -n +2 /tmp/rc.exe.${p}.2 >&2
cat /tmp/rc.exe.${p}.1
rm -f /tmp/rc.exe.${p}.2 /tmp/rc.exe.${p}.1
exit $RES
diff --git a/erts/etc/win32/nsis/Makefile b/erts/etc/win32/nsis/Makefile
index 7bcecaa264..64f44ff86d 100644
--- a/erts/etc/win32/nsis/Makefile
+++ b/erts/etc/win32/nsis/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -41,7 +42,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk
TARGET_DIR = $(RELEASE_PATH)
-ifeq ($(MSYSTEM),MINGW32)
+ifdef MSYSTEM
+ ifeq ($(MSYSTEM),$(filter $(MSYSTEM),MSYS MINGW32 MINGW64))
+ USEMSYS := true
+ endif
+endif
+
+ifeq ($(USEMSYS),true)
MAKENSISFLAGS = //V2
WTESTROOT=$(shell (msys2win_path.sh "$(RELEASE_PATH)"))
@@ -62,7 +69,7 @@ else
endif
REDIST_FILE=$(shell (sh ./find_redist.sh || echo ""))
-ifeq ($(MSYSTEM),MINGW32)
+ifeq ($(USEMSYS),true)
NICEREDISTFILE=$(shell (msys2win_path.sh -m "$(REDIST_FILE)" 2>/dev/null || echo ""))
else
NICEREDISTFILE=$(shell (cygpath -d -m "$(REDIST_FILE)" 2>/dev/null || echo ""))
diff --git a/erts/etc/win32/nsis/dll_version_helper.sh b/erts/etc/win32/nsis/dll_version_helper.sh
index e75edf3738..86e36f62c9 100755
--- a/erts/etc/win32/nsis/dll_version_helper.sh
+++ b/erts/etc/win32/nsis/dll_version_helper.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/etc/win32/nsis/erlang20.nsi b/erts/etc/win32/nsis/erlang20.nsi
index 3333c4a9aa..bf6ba0b9a6 100644
--- a/erts/etc/win32/nsis/erlang20.nsi
+++ b/erts/etc/win32/nsis/erlang20.nsi
@@ -9,16 +9,17 @@
;
; Copyright Ericsson AB 2012. All Rights Reserved.
;
-; The contents of this file are subject to the Erlang Public License,
-; Version 1.1, (the "License"); you may not use this file except in
-; compliance with the License. You should have received a copy of the
-; Erlang Public License along with this software. If not, it can be
-; retrieved online at http://www.erlang.org/.
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
;
-; Software distributed under the License is distributed on an "AS IS"
-; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-; the License for the specific language governing rights and limitations
-; under the License.
+; 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%
;
diff --git a/erts/etc/win32/nsis/find_redist.sh b/erts/etc/win32/nsis/find_redist.sh
index 7c449c9e4e..03e92b21c7 100755
--- a/erts/etc/win32/nsis/find_redist.sh
+++ b/erts/etc/win32/nsis/find_redist.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -163,7 +164,7 @@ fi
#echo $BPATH_LIST
for BP in $BPATH_LIST; do
- for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1"; do
+ for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1" "VC redist 1033"; do
BPATH=$BP
fail=false
allow_fail=false
diff --git a/erts/etc/win32/port_entry.c b/erts/etc/win32/port_entry.c
index 30b54035e0..5681a2a548 100644
--- a/erts/etc/win32/port_entry.c
+++ b/erts/etc/win32/port_entry.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/resource.h b/erts/etc/win32/resource.h
index 697931952a..32d8b8885d 100644
--- a/erts/etc/win32/resource.h
+++ b/erts/etc/win32/resource.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/start_erl.c b/erts/etc/win32/start_erl.c
index 0ca12f09c9..a4437c2f6b 100644
--- a/erts/etc/win32/start_erl.c
+++ b/erts/etc/win32/start_erl.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/etc/win32/win_erlexec.c b/erts/etc/win32/win_erlexec.c
index c622e6eeee..f2460197e6 100644
--- a/erts/etc/win32/win_erlexec.c
+++ b/erts/etc/win32/win_erlexec.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/Makefile b/erts/example/Makefile
index 6e1a88b4da..cc5bcce191 100644
--- a/erts/example/Makefile
+++ b/erts/example/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -30,7 +31,7 @@ CFLAGS += $(OUR_C_FLAGS)
CXXFLAGS += $(OUR_C_FLAGS)
TARGETS = pg_sync.beam pg_async.beam pg_sync.so pg_async.so \
-next_perm.so next_perm.beam
+next_perm.so next_perm.beam time_compat.beam
all: $(TARGETS)
diff --git a/erts/example/matrix_nif.c b/erts/example/matrix_nif.c
index 404329e36c..dfe446e879 100644
--- a/erts/example/matrix_nif.c
+++ b/erts/example/matrix_nif.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/example/matrix_nif.erl b/erts/example/matrix_nif.erl
index 9008977e01..d56b358247 100644
--- a/erts/example/matrix_nif.erl
+++ b/erts/example/matrix_nif.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/example/next_perm.cc b/erts/example/next_perm.cc
index d7c8f1ad97..c7b7096e7b 100644
--- a/erts/example/next_perm.cc
+++ b/erts/example/next_perm.cc
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/next_perm.erl b/erts/example/next_perm.erl
index 40a5c24d35..d414470f3a 100644
--- a/erts/example/next_perm.erl
+++ b/erts/example/next_perm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/example/pg_async.c b/erts/example/pg_async.c
index 7ffb4bb1f3..cd6bc9e0c2 100644
--- a/erts/example/pg_async.c
+++ b/erts/example/pg_async.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_async.erl b/erts/example/pg_async.erl
index 10506bfe9f..20ee94f61a 100644
--- a/erts/example/pg_async.erl
+++ b/erts/example/pg_async.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/example/pg_async2.c b/erts/example/pg_async2.c
index 368f9d32d0..9eb3ec9d54 100644
--- a/erts/example/pg_async2.c
+++ b/erts/example/pg_async2.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_async2.erl b/erts/example/pg_async2.erl
index 4803abf508..082852f617 100644
--- a/erts/example/pg_async2.erl
+++ b/erts/example/pg_async2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/example/pg_encode.c b/erts/example/pg_encode.c
index 34ca1fe46c..e1ec4abb1d 100644
--- a/erts/example/pg_encode.c
+++ b/erts/example/pg_encode.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_encode.h b/erts/example/pg_encode.h
index 4477c0c079..df3f8fcaaa 100644
--- a/erts/example/pg_encode.h
+++ b/erts/example/pg_encode.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_encode2.c b/erts/example/pg_encode2.c
index a0e99ba3b3..cdf8e71e44 100644
--- a/erts/example/pg_encode2.c
+++ b/erts/example/pg_encode2.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_encode2.h b/erts/example/pg_encode2.h
index 4477c0c079..df3f8fcaaa 100644
--- a/erts/example/pg_encode2.h
+++ b/erts/example/pg_encode2.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_sync.c b/erts/example/pg_sync.c
index 6eaa6138e6..88096671a5 100644
--- a/erts/example/pg_sync.c
+++ b/erts/example/pg_sync.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/example/pg_sync.erl b/erts/example/pg_sync.erl
index 58cc149e12..76fb27332e 100644
--- a/erts/example/pg_sync.erl
+++ b/erts/example/pg_sync.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/example/time_compat.erl b/erts/example/time_compat.erl
new file mode 100644
index 0000000000..b87c6cc550
--- /dev/null
+++ b/erts/example/time_compat.erl
@@ -0,0 +1,305 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%% If your code need to be able to execute on ERTS versions both
+%% earlier and later than 7.0, the best approach is to use the new
+%% time API introduced in ERTS 7.0 and implement a fallback
+%% solution using the old primitives to be used on old ERTS
+%% versions. This way your code can automatically take advantage
+%% of the improvements in the API when available. This is an
+%% example of how to implement such an API, but it can be used
+%% as is if you want to. Just add (a preferrably renamed version of)
+%% this module to your project, and call the API via this module
+%% instead of calling the BIFs directly.
+%%
+
+-module(time_compat).
+
+%% We don't want warnings about the use of erlang:now/0 in
+%% this module.
+-compile(nowarn_deprecated_function).
+%%
+%% We don't use
+%% -compile({nowarn_deprecated_function, [{erlang, now, 0}]}).
+%% since this will produce warnings when compiled on systems
+%% where it has not yet been deprecated.
+%%
+
+-export([monotonic_time/0,
+ monotonic_time/1,
+ erlang_system_time/0,
+ erlang_system_time/1,
+ os_system_time/0,
+ os_system_time/1,
+ time_offset/0,
+ time_offset/1,
+ convert_time_unit/3,
+ timestamp/0,
+ unique_integer/0,
+ unique_integer/1,
+ monitor/2,
+ system_info/1,
+ system_flag/2]).
+
+monotonic_time() ->
+ try
+ erlang:monotonic_time()
+ catch
+ error:undef ->
+ %% Use Erlang system time as monotonic time
+ erlang_system_time_fallback()
+ end.
+
+monotonic_time(Unit) ->
+ try
+ erlang:monotonic_time(Unit)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Unit]);
+ error:undef ->
+ %% Use Erlang system time as monotonic time
+ STime = erlang_system_time_fallback(),
+ try
+ convert_time_unit_fallback(STime, native, Unit)
+ catch
+ error:bad_time_unit -> erlang:error(badarg, [Unit])
+ end
+ end.
+
+erlang_system_time() ->
+ try
+ erlang:system_time()
+ catch
+ error:undef ->
+ erlang_system_time_fallback()
+ end.
+
+erlang_system_time(Unit) ->
+ try
+ erlang:system_time(Unit)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Unit]);
+ error:undef ->
+ STime = erlang_system_time_fallback(),
+ try
+ convert_time_unit_fallback(STime, native, Unit)
+ catch
+ error:bad_time_unit -> erlang:error(badarg, [Unit])
+ end
+ end.
+
+os_system_time() ->
+ try
+ os:system_time()
+ catch
+ error:undef ->
+ os_system_time_fallback()
+ end.
+
+os_system_time(Unit) ->
+ try
+ os:system_time(Unit)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Unit]);
+ error:undef ->
+ STime = os_system_time_fallback(),
+ try
+ convert_time_unit_fallback(STime, native, Unit)
+ catch
+ error:bad_time_unit -> erlang:error(badarg, [Unit])
+ end
+ end.
+
+time_offset() ->
+ try
+ erlang:time_offset()
+ catch
+ error:undef ->
+ %% Erlang system time and Erlang monotonic
+ %% time are always aligned
+ 0
+ end.
+
+time_offset(Unit) ->
+ try
+ erlang:time_offset(Unit)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Unit]);
+ error:undef ->
+ try
+ _ = integer_time_unit(Unit)
+ catch
+ error:bad_time_unit -> erlang:error(badarg, [Unit])
+ end,
+ %% Erlang system time and Erlang monotonic
+ %% time are always aligned
+ 0
+ end.
+
+convert_time_unit(Time, FromUnit, ToUnit) ->
+ try
+ erlang:convert_time_unit(Time, FromUnit, ToUnit)
+ catch
+ error:undef ->
+ try
+ convert_time_unit_fallback(Time, FromUnit, ToUnit)
+ catch
+ _:_ ->
+ erlang:error(badarg, [Time, FromUnit, ToUnit])
+ end;
+ error:Error ->
+ erlang:error(Error, [Time, FromUnit, ToUnit])
+ end.
+
+timestamp() ->
+ try
+ erlang:timestamp()
+ catch
+ error:undef ->
+ erlang:now()
+ end.
+
+unique_integer() ->
+ try
+ erlang:unique_integer()
+ catch
+ error:undef ->
+ {MS, S, US} = erlang:now(),
+ (MS*1000000+S)*1000000+US
+ end.
+
+unique_integer(Modifiers) ->
+ try
+ erlang:unique_integer(Modifiers)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Modifiers]);
+ error:undef ->
+ case is_valid_modifier_list(Modifiers) of
+ true ->
+ %% now() converted to an integer
+ %% fullfill the requirements of
+ %% all modifiers: unique, positive,
+ %% and monotonic...
+ {MS, S, US} = erlang:now(),
+ (MS*1000000+S)*1000000+US;
+ false ->
+ erlang:error(badarg, [Modifiers])
+ end
+ end.
+
+monitor(Type, Item) ->
+ try
+ erlang:monitor(Type, Item)
+ catch
+ error:Error ->
+ case {Error, Type, Item} of
+ {badarg, time_offset, clock_service} ->
+ %% Time offset is final and will never change.
+ %% Return a dummy reference, there will never
+ %% be any need for 'CHANGE' messages...
+ make_ref();
+ _ ->
+ erlang:error(Error, [Type, Item])
+ end
+ end.
+
+system_info(Item) ->
+ try
+ erlang:system_info(Item)
+ catch
+ error:badarg ->
+ case Item of
+ time_correction ->
+ case erlang:system_info(tolerant_timeofday) of
+ enabled -> true;
+ disabled -> false
+ end;
+ time_warp_mode ->
+ no_time_warp;
+ time_offset ->
+ final;
+ NotSupArg when NotSupArg == os_monotonic_time_source;
+ NotSupArg == os_system_time_source;
+ NotSupArg == start_time;
+ NotSupArg == end_time ->
+ %% Cannot emulate this...
+ erlang:error(notsup, [NotSupArg]);
+ _ ->
+ erlang:error(badarg, [Item])
+ end;
+ error:Error ->
+ erlang:error(Error, [Item])
+ end.
+
+system_flag(Flag, Value) ->
+ try
+ erlang:system_flag(Flag, Value)
+ catch
+ error:Error ->
+ case {Error, Flag, Value} of
+ {badarg, time_offset, finalize} ->
+ %% Time offset is final
+ final;
+ _ ->
+ erlang:error(Error, [Flag, Value])
+ end
+ end.
+
+%%
+%% Internal functions
+%%
+
+integer_time_unit(native) -> 1000*1000;
+integer_time_unit(nano_seconds) -> 1000*1000*1000;
+integer_time_unit(micro_seconds) -> 1000*1000;
+integer_time_unit(milli_seconds) -> 1000;
+integer_time_unit(seconds) -> 1;
+integer_time_unit(I) when is_integer(I), I > 0 -> I;
+integer_time_unit(BadRes) -> erlang:error(bad_time_unit, [BadRes]).
+
+erlang_system_time_fallback() ->
+ {MS, S, US} = erlang:now(),
+ (MS*1000000+S)*1000000+US.
+
+os_system_time_fallback() ->
+ {MS, S, US} = os:timestamp(),
+ (MS*1000000+S)*1000000+US.
+
+convert_time_unit_fallback(Time, FromUnit, ToUnit) ->
+ FU = integer_time_unit(FromUnit),
+ TU = integer_time_unit(ToUnit),
+ case Time < 0 of
+ true -> TU*Time - (FU - 1);
+ false -> TU*Time
+ end div FU.
+
+is_valid_modifier_list([positive|Ms]) ->
+ is_valid_modifier_list(Ms);
+is_valid_modifier_list([monotonic|Ms]) ->
+ is_valid_modifier_list(Ms);
+is_valid_modifier_list([]) ->
+ true;
+is_valid_modifier_list(_) ->
+ false.
diff --git a/erts/include/erl_fixed_size_int_types.h b/erts/include/erl_fixed_size_int_types.h
index 3bbc37aea7..dfaea5650b 100644
--- a/erts/include/erl_fixed_size_int_types.h
+++ b/erts/include/erl_fixed_size_int_types.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/erl_int_sizes_config.h.in b/erts/include/erl_int_sizes_config.h.in
index 14d7c6a702..b18f5ebc00 100644
--- a/erts/include/erl_int_sizes_config.h.in
+++ b/erts/include/erl_int_sizes_config.h.in
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/erl_memory_trace_parser.h b/erts/include/erl_memory_trace_parser.h
index 3b6f76d2fd..426ff05061 100644
--- a/erts/include/erl_memory_trace_parser.h
+++ b/erts/include/erl_memory_trace_parser.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/erl_native_features_config.h.in b/erts/include/erl_native_features_config.h.in
index d1674cb256..2bd1d96229 100644
--- a/erts/include/erl_native_features_config.h.in
+++ b/erts/include/erl_native_features_config.h.in
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/README b/erts/include/internal/README
index f7b78a3468..fca0c5e489 100644
--- a/erts/include/internal/README
+++ b/erts/include/internal/README
@@ -3,16 +3,17 @@
Copyright Ericsson AB 2004-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/include/internal/erl_errno.h b/erts/include/internal/erl_errno.h
index 2e095e9f64..33bfbe3d51 100644
--- a/erts/include/internal/erl_errno.h
+++ b/erts/include/internal/erl_errno.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/erl_memory_trace_protocol.h b/erts/include/internal/erl_memory_trace_protocol.h
index bda1f65c87..b86e2de278 100644
--- a/erts/include/internal/erl_memory_trace_protocol.h
+++ b/erts/include/internal/erl_memory_trace_protocol.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/erl_misc_utils.h b/erts/include/internal/erl_misc_utils.h
index 507e1726f4..7ab7a26838 100644
--- a/erts/include/internal/erl_misc_utils.h
+++ b/erts/include/internal/erl_misc_utils.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/erl_printf.h b/erts/include/internal/erl_printf.h
index 5bc93a979b..3846828fb9 100644
--- a/erts/include/internal/erl_printf.h
+++ b/erts/include/internal/erl_printf.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/erl_printf_format.h b/erts/include/internal/erl_printf_format.h
index 62fe4120e4..efd926be99 100644
--- a/erts/include/internal/erl_printf_format.h
+++ b/erts/include/internal/erl_printf_format.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/erts_internal.mk.in b/erts/include/internal/erts_internal.mk.in
index 489531372c..76aab59c38 100644
--- a/erts/include/internal/erts_internal.mk.in
+++ b/erts/include/internal/erts_internal.mk.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/include/internal/ethr_atomics.h b/erts/include/internal/ethr_atomics.h
index 612894b8c1..f366c2d0ad 100644
--- a/erts/include/internal/ethr_atomics.h
+++ b/erts/include/internal/ethr_atomics.h
@@ -12,16 +12,17 @@
*
* Copyright Ericsson AB 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ethr_internal.h b/erts/include/internal/ethr_internal.h
index c9b1db5b46..d4ded6ff05 100644
--- a/erts/include/internal/ethr_internal.h
+++ b/erts/include/internal/ethr_internal.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -57,6 +58,33 @@ ETHR_PROTO_NORETURN__ ethr_abort__(void);
int ethr_win_get_errno__(void);
#endif
+#ifdef ETHR_INCLUDE_MONOTONIC_CLOCK__
+#undef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+#if defined(ETHR_HAVE_CLOCK_GETTIME_MONOTONIC) \
+ || defined(ETHR_HAVE_MACH_CLOCK_GET_TIME) \
+ || defined(ETHR_HAVE_GETHRTIME)
+#ifdef ETHR_TIME_WITH_SYS_TIME
+# include <time.h>
+# include <sys/time.h>
+#else
+# ifdef ETHR_HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#ifdef ETHR_HAVE_MACH_CLOCK_GET_TIME
+#include <mach/clock.h>
+#include <mach/mach.h>
+#endif
+#define ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ethr_sint64_t ethr_get_monotonic_time(void);
+int ethr_get_monotonic_time_is_broken(void);
+#endif
+#endif /* ETHR_INCLUDE_MONOTONIC_CLOCK__ */
+
+void ethr_init_event__(void);
+
/* implemented in lib_src/common/ethread_aux.c */
int ethr_init_common__(ethr_init_data *id);
int ethr_late_init_common__(ethr_late_init_data *lid);
diff --git a/erts/include/internal/ethr_mutex.h b/erts/include/internal/ethr_mutex.h
index 6c931e0cd4..f76c4262ca 100644
--- a/erts/include/internal/ethr_mutex.h
+++ b/erts/include/internal/ethr_mutex.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ethr_optimized_fallbacks.h b/erts/include/internal/ethr_optimized_fallbacks.h
index 45399d18e6..6ef4e2bace 100644
--- a/erts/include/internal/ethr_optimized_fallbacks.h
+++ b/erts/include/internal/ethr_optimized_fallbacks.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h
index ad5d05704c..8964f95652 100644
--- a/erts/include/internal/ethread.h
+++ b/erts/include/internal/ethread.h
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2004-2013. All Rights Reserved.
+ * Copyright Ericsson AB 2004-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -53,7 +54,8 @@
#endif
#if defined(ETHR_DEBUG) || !defined(ETHR_INLINE) || ETHR_XCHK \
- || (defined(__GNUC__) && defined(ERTS_MIXED_CYGWIN_VC))
+ || (defined(__GNUC__) && defined(ERTS_MIXED_CYGWIN_VC)) \
+ || (defined(__GNUC__) && defined(ERTS_MIXED_MSYS_VC))
# undef ETHR_INLINE
# define ETHR_INLINE
# undef ETHR_FORCE_INLINE
@@ -214,8 +216,6 @@ typedef OSPPDKEY ethr_tsd_key;
/* Out own RW mutexes are probably faster, but use OSEs mutexes */
#define ETHR_USE_OWN_RWMTX_IMPL__
-#define ETHR_HAVE_THREAD_NAMES
-
#else /* No supported thread lib found */
#ifdef ETHR_NO_SUPP_THR_LIB_NOT_FATAL
@@ -364,6 +364,9 @@ extern ethr_runtime_t ethr_runtime__;
# include "sparc64/ethread.h"
# endif
# endif
+# if ETHR_HAVE_GCC___ATOMIC_BUILTINS
+# include "gcc/ethread.h"
+# endif
# include "libatomic_ops/ethread.h"
# include "gcc/ethread.h"
# endif
@@ -501,21 +504,18 @@ typedef struct {
typedef struct {
int detached; /* boolean (default false) */
int suggested_stack_size; /* kilo words (default sys dependent) */
+ char *name; /* max 14 char long (default no-name) */
#ifdef ETHR_OSE_THREADS
- char *name;
U32 coreNo;
#endif
} ethr_thr_opts;
#if defined(ETHR_OSE_THREADS)
-/* Default ethr name is big as we want to be able to sprint stuff in there */
-#define ETHR_THR_OPTS_DEFAULT_INITER \
- {0, -1, "ethread", 0}
+#define ETHR_THR_OPTS_DEFAULT_INITER {0, -1, NULL, 0}
#else
-#define ETHR_THR_OPTS_DEFAULT_INITER {0, -1}
+#define ETHR_THR_OPTS_DEFAULT_INITER {0, -1, NULL}
#endif
-
#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
# define ETHR_NEED_SPINLOCK_PROTOTYPES__
# define ETHR_NEED_RWSPINLOCK_PROTOTYPES__
@@ -529,6 +529,8 @@ int ethr_thr_join(ethr_tid, void **);
int ethr_thr_detach(ethr_tid);
void ethr_thr_exit(void *);
ethr_tid ethr_self(void);
+int ethr_getname(ethr_tid, char *, size_t);
+void ethr_setname(char *);
int ethr_equal_tids(ethr_tid, ethr_tid);
int ethr_tsd_key_create(ethr_tsd_key *,char *);
@@ -540,6 +542,7 @@ void *ethr_tsd_get(ethr_tsd_key);
#include <signal.h>
int ethr_sigmask(int how, const sigset_t *set, sigset_t *oset);
int ethr_sigwait(const sigset_t *set, int *sig);
+int ethr_kill(const ethr_tid tid, const int sig);
#endif
void ethr_compiler_barrier(void);
diff --git a/erts/include/internal/ethread.mk.in b/erts/include/internal/ethread.mk.in
index 13071711e1..89924a3215 100644
--- a/erts/include/internal/ethread.mk.in
+++ b/erts/include/internal/ethread.mk.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/include/internal/ethread_header_config.h.in b/erts/include/internal/ethread_header_config.h.in
index b36322490a..f4b08cfced 100644
--- a/erts/include/internal/ethread_header_config.h.in
+++ b/erts/include/internal/ethread_header_config.h.in
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2004-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2004-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -84,32 +85,62 @@
/* Define if run in Sparc RMO, PSO, or TSO mode */
#undef ETHR_SPARC_RMO
-/* Define if you have __sync_add_and_fetch() for 32-bit integers */
-#undef ETHR_HAVE___SYNC_ADD_AND_FETCH32
+/* Define as a boolean indicating whether you have a gcc compatible compiler
+ capable of generating the ARM DMB instruction, and are compiling for an ARM
+ processor with ARM DMB instruction support, or not */
+#undef ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION
+
+/* Define as a bitmask corresponding to the word sizes that
+ __sync_synchronize() can handle on your system */
+#undef ETHR_HAVE___sync_synchronize
+
+/* Define as a bitmask corresponding to the word sizes that
+ __sync_add_and_fetch() can handle on your system */
+#undef ETHR_HAVE___sync_add_and_fetch
+
+/* Define as a bitmask corresponding to the word sizes that
+ __sync_fetch_and_and() can handle on your system */
+#undef ETHR_HAVE___sync_fetch_and_and
+
+/* Define as a bitmask corresponding to the word sizes that
+ __sync_fetch_and_or() can handle on your system */
+#undef ETHR_HAVE___sync_fetch_and_or
+
+/* Define as a bitmask corresponding to the word sizes that
+ __sync_val_compare_and_swap() can handle on your system */
+#undef ETHR_HAVE___sync_val_compare_and_swap
-/* Define if you have __sync_add_and_fetch() for 64-bit integers */
-#undef ETHR_HAVE___SYNC_ADD_AND_FETCH64
+/* Define as a boolean indicating whether you have a gcc __atomic builtins or
+ not */
+#undef ETHR_HAVE_GCC___ATOMIC_BUILTINS
-/* Define if you have __sync_fetch_and_and() for 32-bit integers */
-#undef ETHR_HAVE___SYNC_FETCH_AND_AND32
+/* Define as a boolean indicating whether you trust gcc's __atomic_* builtins
+ memory barrier implementations, or not */
+#undef ETHR_TRUST_GCC_ATOMIC_BUILTINS_MEMORY_BARRIERS
-/* Define if you have __sync_fetch_and_and() for 64-bit integers */
-#undef ETHR_HAVE___SYNC_FETCH_AND_AND64
+/* Define as a bitmask corresponding to the word sizes that __atomic_store_n()
+ can handle on your system */
+#undef ETHR_HAVE___atomic_store_n
-/* Define if you have __sync_fetch_and_or() for 32-bit integers */
-#undef ETHR_HAVE___SYNC_FETCH_AND_OR32
+/* Define as a bitmask corresponding to the word sizes that __atomic_load_n()
+ can handle on your system */
+#undef ETHR_HAVE___atomic_load_n
-/* Define if you have __sync_fetch_and_or() for 64-bit integers */
-#undef ETHR_HAVE___SYNC_FETCH_AND_OR64
+/* Define as a bitmask corresponding to the word sizes that
+ __atomic_add_fetch() can handle on your system */
+#undef ETHR_HAVE___atomic_add_fetch
-/* Define if you have __sync_val_compare_and_swap() for 32-bit integers */
-#undef ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32
+/* Define as a bitmask corresponding to the word sizes that
+ __atomic_fetch_and() can handle on your system */
+#undef ETHR_HAVE___atomic_fetch_and
-/* Define if you have __sync_val_compare_and_swap() for 64-bit integers */
-#undef ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64
+/* Define as a bitmask corresponding to the word sizes that
+ __atomic_fetch_or() can handle on your system */
+#undef ETHR_HAVE___atomic_fetch_or
-/* Define if you have __sync_val_compare_and_swap() for 128-bit integers */
-#undef ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128
+/* Define as a bitmask corresponding to the word sizes that
+ __atomic_compare_exchange_n() can handle on your system */
+#undef ETHR_HAVE___atomic_compare_exchange_n
/* Define if you prefer gcc native ethread implementations */
#undef ETHR_PREFER_GCC_NATIVE_IMPLS
@@ -135,6 +166,10 @@
/* Define if you use a gcc that supports the double word cmpxchg instruction */
#undef ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT
+/* Define if gcc wont let you clobber ebx with cmpxchg8b and position
+ independent code */
+#undef ETHR_CMPXCHG8B_PIC_NO_CLOBBER_EBX
+
/* Define if you get a register shortage with cmpxchg8b and position independent code */
#undef ETHR_CMPXCHG8B_REGISTER_SHORTAGE
@@ -237,3 +272,18 @@
/* Assumed cache-line size (in bytes) */
#undef ASSUMED_CACHE_LINE_SIZE
+
+/* Define if you have a clock_gettime() with a monotonic clock */
+#undef ETHR_HAVE_CLOCK_GETTIME_MONOTONIC
+
+/* Define if you have a monotonic gethrtime() */
+#undef ETHR_HAVE_GETHRTIME
+
+/* Define if you have a mach clock_get_time() with a monotonic clock */
+#undef ETHR_HAVE_MACH_CLOCK_GET_TIME
+
+/* Define to the monotonic clock id to use */
+#undef ETHR_MONOTONIC_CLOCK_ID
+
+/* Define if pthread_cond_timedwait() can be used with a monotonic clock */
+#undef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
diff --git a/erts/include/internal/ethread_inline.h b/erts/include/internal/ethread_inline.h
index ffb756c84f..3ba910d993 100644
--- a/erts/include/internal/ethread_inline.h
+++ b/erts/include/internal/ethread_inline.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -20,6 +21,29 @@
#ifndef ETHREAD_INLINE_H__
#define ETHREAD_INLINE_H__
+#define ETHR_GCC_COMPILER_FALSE 0 /* Not a gcc compatible compiler */
+#define ETHR_GCC_COMPILER_TRUE 1 /* The GNU gcc compiler */
+/* Negative integers for gcc compatible compilers */
+#define ETHR_GCC_COMPILER_CLANG -1 /* The Clang gcc compatible compiler */
+#define ETHR_GCC_COMPILER_ICC -2 /* The Intel gcc compatible compiler */
+/* Line them up... */
+
+/*
+ * Unfortunately there is no easy and certain way of
+ * detecting a true gcc compiler, since the compatible
+ * ones all define the same defines as the true gnu-gcc...
+ */
+#if !defined(__GNUC__) && !defined(__GNUG__)
+# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_FALSE
+#elif defined(__clang__)
+# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_CLANG
+#elif defined(__ICC) || defined(__INTEL_COMPILER)
+# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_ICC
+#else
+/* Seems to be the true gnu-gcc... */
+# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_TRUE
+#endif
+
#if !defined(__GNUC__)
# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) 0
#elif !defined(__GNUC_MINOR__)
diff --git a/erts/include/internal/gcc/ethr_atomic.h b/erts/include/internal/gcc/ethr_atomic.h
index f598f8537b..231eaa6927 100644
--- a/erts/include/internal/gcc/ethr_atomic.h
+++ b/erts/include/internal/gcc/ethr_atomic.h
@@ -1,95 +1,99 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
/*
- * Description: Native atomics ethread support using gcc's builtins
+ * Description: Native atomics ethread support using gcc's __atomic
+ * and __sync builtins
* Author: Rickard Green
+ *
+ * Note: The C11 memory model implemented by gcc's __atomic
+ * builtins does not match the ethread API very well.
+ *
+ * Due to this we cannot use the __ATOMIC_SEQ_CST
+ * memory model. For more information see the comment
+ * in the begining of ethr_membar.h in this directory.
*/
#undef ETHR_INCLUDE_ATOMIC_IMPL__
-#if !defined(ETHR_GCC_ATOMIC32_H__) && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__)
-#define ETHR_GCC_ATOMIC32_H__
-#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32)
-# define ETHR_INCLUDE_ATOMIC_IMPL__ 4
-#endif
+#if !defined(ETHR_GCC_ATOMIC_ATOMIC32_H__) \
+ && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__) \
+ && ((ETHR_HAVE___sync_val_compare_and_swap & 4) \
+ || (ETHR_HAVE___atomic_compare_exchange_n & 4))
+
+#define ETHR_GCC_ATOMIC_ATOMIC32_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 4
#undef ETHR_ATOMIC_WANT_32BIT_IMPL__
-#elif !defined(ETHR_GCC_ATOMIC64_H__) && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__)
-#define ETHR_GCC_ATOMIC64_H__
-#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64)
-# define ETHR_INCLUDE_ATOMIC_IMPL__ 8
-#endif
-#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
-#endif
-#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
+#elif !defined(ETHR_GCC_ATOMIC64_H__) \
+ && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__) \
+ && ((ETHR_HAVE___sync_val_compare_and_swap & 8) \
+ || (ETHR_HAVE___atomic_compare_exchange_n & 8))
-#ifndef ETHR_GCC_ATOMIC_COMMON__
-#define ETHR_GCC_ATOMIC_COMMON__
+#define ETHR_GCC_ATOMIC64_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 8
+#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
-#define ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ 0
-#if defined(__i386__) || defined(__x86_64__) || defined(__sparc__) \
- || defined(__powerpc__) || defined(__ppc__) || defined(__mips__)
-# undef ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
-# define ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ 1
#endif
-#endif /* ETHR_GCC_ATOMIC_COMMON__ */
+#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
#define ETHR_HAVE_NATIVE_ATOMIC32 1
-#define ETHR_NATIVE_ATOMIC32_IMPL "gcc"
#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
#define ETHR_ATMC_T__ ethr_native_atomic32_t
#define ETHR_AINT_T__ ethr_sint32_t
-#if defined(ETHR_HAVE___SYNC_ADD_AND_FETCH32)
-# define ETHR_HAVE___SYNC_ADD_AND_FETCH
-#endif
-#if defined(ETHR_HAVE___SYNC_FETCH_AND_AND32)
-# define ETHR_HAVE___SYNC_FETCH_AND_AND
-#endif
-#if defined(ETHR_HAVE___SYNC_FETCH_AND_OR32)
-# define ETHR_HAVE___SYNC_FETCH_AND_OR
+#if ((ETHR_HAVE___sync_val_compare_and_swap & 4) \
+ && (ETHR_HAVE___atomic_compare_exchange_n & 4))
+# define ETHR_NATIVE_ATOMIC32_IMPL "gcc_atomic_and_sync_builtins"
+#elif (ETHR_HAVE___atomic_compare_exchange_n & 4)
+# define ETHR_NATIVE_ATOMIC32_IMPL "gcc_atomic_builtins"
+#elif (ETHR_HAVE___sync_val_compare_and_swap & 4)
+# define ETHR_NATIVE_ATOMIC32_IMPL "gcc_sync_builtins"
+#else
+# error "!?"
#endif
#elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
#define ETHR_HAVE_NATIVE_ATOMIC64 1
-#define ETHR_NATIVE_ATOMIC64_IMPL "gcc"
#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
#define ETHR_ATMC_T__ ethr_native_atomic64_t
#define ETHR_AINT_T__ ethr_sint64_t
-#if defined(ETHR_HAVE___SYNC_ADD_AND_FETCH64)
-# define ETHR_HAVE___SYNC_ADD_AND_FETCH
-#endif
-#if defined(ETHR_HAVE___SYNC_FETCH_AND_AND64)
-# define ETHR_HAVE___SYNC_FETCH_AND_AND
-#endif
-#if defined(ETHR_HAVE___SYNC_FETCH_AND_OR64)
-# define ETHR_HAVE___SYNC_FETCH_AND_OR
+#if ((ETHR_HAVE___sync_val_compare_and_swap & 8) \
+ && (ETHR_HAVE___atomic_compare_exchange_n & 8))
+# define ETHR_NATIVE_ATOMIC64_IMPL "gcc_atomic_and_sync_builtins"
+#elif (ETHR_HAVE___atomic_compare_exchange_n & 8)
+# define ETHR_NATIVE_ATOMIC64_IMPL "gcc_atomic_builtins"
+#elif (ETHR_HAVE___sync_val_compare_and_swap & 8)
+# define ETHR_NATIVE_ATOMIC64_IMPL "gcc_sync_builtins"
+#else
+# error "!?"
#endif
#else
#error "Unsupported integer size"
#endif
+#undef ETHR_NATIVE_ATOMIC_IMPL__
+
typedef struct {
- volatile ETHR_AINT_T__ counter;
+ volatile ETHR_AINT_T__ value;
} ETHR_ATMC_T__;
-
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
@@ -98,13 +102,19 @@ typedef struct {
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADDR 1
#endif
+
static ETHR_INLINE ETHR_AINT_T__ *
ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
{
- return (ETHR_AINT_T__ *) &var->counter;
+ return (ETHR_AINT_T__ *) &var->value;
}
-#if ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
+/*
+ * set()
+ */
+#if (ETHR_HAVE___atomic_store_n & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET 1
@@ -115,12 +125,109 @@ ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
static ETHR_INLINE void
ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
{
- var->counter = value;
+ __atomic_store_n(&var->value, value, __ATOMIC_RELAXED);
}
-#endif /* ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ */
+#endif /* ETHR_GCC_RELAXED_VERSIONS__ */
-#if ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
+#if (ETHR_GCC_RELB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET_RELB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET_RELB 1
+#endif
+
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
+{
+ __atomic_store_n(&var->value, value, __ATOMIC_RELEASE);
+}
+
+#endif /* ETHR_GCC_RELB_VERSIONS__ */
+
+#elif (ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET 1
+#endif
+
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
+{
+ var->value = value;
+}
+
+#endif /* ETHR_GCC_RELAXED_VERSIONS__ */
+
+#if (ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET_RELB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET_RELB 1
+#endif
+
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
+{
+ var->value = value;
+}
+
+#endif /* ETHR_GCC_RELB_VERSIONS__ */
+
+#endif /* ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ */
+
+#endif /* ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__ */
+
+/*
+ * read()
+ */
+
+#if (ETHR_HAVE___atomic_load_n & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
+{
+ return __atomic_load_n(&var->value, __ATOMIC_RELAXED);
+}
+
+#endif /* ETHR_GCC_RELAXED_VERSIONS__ */
+
+#if ((ETHR_GCC_ACQB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__) \
+ & ~ETHR___atomic_load_ACQUIRE_barrier_bug)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ_ACQB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ_ACQB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
+{
+ return __atomic_load_n(&var->value, __ATOMIC_ACQUIRE);
+}
+
+#endif /* ETHR_GCC_ACQB_VERSIONS__ */
+
+#elif (ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ 1
@@ -131,12 +238,90 @@ ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
static ETHR_INLINE ETHR_AINT_T__
ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
{
- return var->counter;
+ return var->value;
+}
+
+#endif /* ETHR_GCC_RELAXED_VERSIONS__ */
+
+#if (ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_ACQB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ_ACQB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ_ACQB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
+{
+ return var->value;
+}
+
+#endif /* ETHR_GCC_ACQB_VERSIONS__ */
+
+#endif /* ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ */
+
+#endif /* ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ */
+
+/*
+ * add_return()
+ */
+#if (ETHR_HAVE___atomic_add_fetch & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
+{
+ return __atomic_add_fetch(&var->value, incr, __ATOMIC_RELAXED);
}
-#endif /* ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ */
+#endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
-#if defined(ETHR_HAVE___SYNC_ADD_AND_FETCH)
+#if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_ACQB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_ACQB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
+{
+ return __atomic_add_fetch(&var->value, incr, __ATOMIC_ACQUIRE);
+}
+
+#endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_RELB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_RELB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_RELB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
+{
+ return __atomic_add_fetch(&var->value, incr, __ATOMIC_RELEASE);
+}
+
+#endif /* ETHR_GCC_RELB_MOD_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_add_fetch */
+
+#if ((ETHR_HAVE___sync_add_and_fetch & ETHR_INCLUDE_ATOMIC_IMPL__) \
+ & ETHR_GCC_MB_MOD_VERSIONS__)
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_MB 1
@@ -147,12 +332,68 @@ ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
static ETHR_INLINE ETHR_AINT_T__
ETHR_NATMC_FUNC__(add_return_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
- return __sync_add_and_fetch(&var->counter, incr);
+ return __sync_add_and_fetch(&var->value, incr);
}
+#endif /* ETHR_HAVE___sync_add_and_fetch */
+
+/*
+ * and_retold()
+ */
+#if (ETHR_HAVE___atomic_fetch_and & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD 1
#endif
-#if defined(ETHR_HAVE___SYNC_FETCH_AND_AND)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
+{
+ return __atomic_fetch_and(&var->value, mask, __ATOMIC_RELAXED);
+}
+
+#endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_ACQB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD_ACQB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
+{
+ return __atomic_fetch_and(&var->value, mask, __ATOMIC_ACQUIRE);
+}
+
+#endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_RELB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_RELB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD_RELB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
+{
+ return __atomic_fetch_and(&var->value, mask, __ATOMIC_RELEASE);
+}
+
+#endif /* ETHR_GCC_RELB_MOD_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_fetch_and */
+
+#if ((ETHR_HAVE___sync_fetch_and_and & ETHR_INCLUDE_ATOMIC_IMPL__) \
+ & ETHR_GCC_MB_MOD_VERSIONS__)
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_MB 1
@@ -163,12 +404,68 @@ ETHR_NATMC_FUNC__(add_return_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
static ETHR_INLINE ETHR_AINT_T__
ETHR_NATMC_FUNC__(and_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- return __sync_fetch_and_and(&var->counter, mask);
+ return __sync_fetch_and_and(&var->value, mask);
}
+#endif /* ETHR_HAVE___sync_fetch_and_and */
+
+/*
+ * or_retold()
+ */
+#if (ETHR_HAVE___atomic_fetch_or & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
+{
+ return __atomic_fetch_or(&var->value, mask, __ATOMIC_RELAXED);
+}
+
+#endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_ACQB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD_ACQB 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
+{
+ return __atomic_fetch_or(&var->value, mask, __ATOMIC_ACQUIRE);
+}
+
+#endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_RELB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_RELB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD_RELB 1
#endif
-#if defined(ETHR_HAVE___SYNC_FETCH_AND_OR)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
+{
+ return __atomic_fetch_or(&var->value, mask, __ATOMIC_RELEASE);
+}
+
+#endif /* ETHR_GCC_RELB_MOD_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_fetch_or */
+
+#if ((ETHR_HAVE___sync_fetch_and_or & ETHR_INCLUDE_ATOMIC_IMPL__) \
+ & ETHR_GCC_MB_MOD_VERSIONS__)
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_MB 1
@@ -179,11 +476,73 @@ ETHR_NATMC_FUNC__(and_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
static ETHR_INLINE ETHR_AINT_T__
ETHR_NATMC_FUNC__(or_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- return (ETHR_AINT_T__) __sync_fetch_and_or(&var->counter, mask);
+ return (ETHR_AINT_T__) __sync_fetch_and_or(&var->value, mask);
+}
+
+#endif /* ETHR_HAVE___sync_fetch_and_or */
+
+/*
+ * cmpxchg()
+ */
+#if (ETHR_HAVE___atomic_compare_exchange_n & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG 1
+#endif
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ exp)
+{
+ ETHR_AINT_T__ xchg = exp;
+ if (__atomic_compare_exchange_n(&var->value,
+ &xchg,
+ new,
+ 0, /* No spurious failures, please */
+ __ATOMIC_RELAXED,
+ __ATOMIC_RELAXED))
+ return exp;
+ return xchg;
}
+#endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_ACQB 1
+#else
+# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_ACQB 1
#endif
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ exp)
+{
+ ETHR_AINT_T__ xchg = exp;
+ if (__atomic_compare_exchange_n(&var->value,
+ &xchg,
+ new,
+ 0, /* No spurious failures, please */
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_ACQUIRE))
+ return exp;
+ return xchg;
+}
+
+#endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_compare_exchange_n */
+
+#if ((ETHR_HAVE___sync_val_compare_and_swap & ETHR_INCLUDE_ATOMIC_IMPL__) \
+ & ETHR_GCC_MB_MOD_VERSIONS__)
+
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_MB 1
#else
@@ -195,17 +554,16 @@ ETHR_NATMC_FUNC__(cmpxchg_mb)(ETHR_ATMC_T__ *var,
ETHR_AINT_T__ new,
ETHR_AINT_T__ old)
{
- return __sync_val_compare_and_swap(&var->counter, old, new);
+ return __sync_val_compare_and_swap(&var->value, old, new);
}
+#endif /* ETHR_HAVE___sync_val_compare_and_swap */
+
#endif /* ETHR_TRY_INLINE_FUNCS */
#undef ETHR_NATMC_FUNC__
#undef ETHR_ATMC_T__
#undef ETHR_AINT_T__
#undef ETHR_AINT_SUFFIX__
-#undef ETHR_HAVE___SYNC_ADD_AND_FETCH
-#undef ETHR_HAVE___SYNC_FETCH_AND_AND
-#undef ETHR_HAVE___SYNC_FETCH_AND_OR
#endif
diff --git a/erts/include/internal/gcc/ethr_dw_atomic.h b/erts/include/internal/gcc/ethr_dw_atomic.h
index 6736f9c547..675912d86e 100644
--- a/erts/include/internal/gcc/ethr_dw_atomic.h
+++ b/erts/include/internal/gcc/ethr_dw_atomic.h
@@ -1,52 +1,57 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2011. All Rights Reserved.
+ * Copyright Ericsson AB 2011-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
/*
- * Description: Native double word atomics using gcc's builtins
+ * Description: Native double word atomics using gcc's __atomic
+ * and __sync builtins
* Author: Rickard Green
+ *
+ * Note: The C11 memory model implemented by gcc's __atomic
+ * builtins does not match the ethread API very well.
+ *
+ * Due to this we cannot use the __ATOMIC_SEQ_CST
+ * memory model. For more information see the comment
+ * in the begining of ethr_membar.h in this directory.
*/
#undef ETHR_INCLUDE_DW_ATOMIC_IMPL__
-#ifndef ETHR_GCC_DW_ATOMIC_H__
-# define ETHR_GCC_DW_ATOMIC_H__
-# if ((ETHR_SIZEOF_PTR == 4 \
- && defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64)) \
- || (ETHR_SIZEOF_PTR == 8 \
- && defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128) \
- && defined(ETHR_HAVE_INT128_T)))
-# define ETHR_INCLUDE_DW_ATOMIC_IMPL__
-# endif
+#if !defined(ETHR_GCC_ATOMIC_DW_ATOMIC_H__) \
+ && ((ETHR_HAVE___sync_val_compare_and_swap & (2*ETHR_SIZEOF_PTR)) \
+ || (ETHR_HAVE___atomic_compare_exchange_n & (2*ETHR_SIZEOF_PTR)))
+# define ETHR_GCC_ATOMIC_DW_ATOMIC_H__
+# define ETHR_INCLUDE_DW_ATOMIC_IMPL__
#endif
#ifdef ETHR_INCLUDE_DW_ATOMIC_IMPL__
# define ETHR_HAVE_NATIVE_SU_DW_ATOMIC
-# define ETHR_NATIVE_DW_ATOMIC_IMPL "gcc"
-# if defined(__i386__) || defined(__x86_64__)
-/*
- * If ETHR_RTCHK_USE_NATIVE_DW_ATOMIC_IMPL__ is defined, it will be used
- * at runtime in order to determine if native or fallback implementation
- * should be used.
- */
-# define ETHR_RTCHK_USE_NATIVE_DW_ATOMIC_IMPL__ \
- ETHR_X86_RUNTIME_CONF_HAVE_DW_CMPXCHG__
-# endif
+#if ((ETHR_HAVE___sync_val_compare_and_swap & (2*ETHR_SIZEOF_PTR)) \
+ && (ETHR_HAVE___atomic_compare_exchange_n & (2*ETHR_SIZEOF_PTR)))
+# define ETHR_NATIVE_DW_ATOMIC_IMPL "gcc_atomic_and_sync_builtins"
+#elif (ETHR_HAVE___atomic_compare_exchange_n & (2*ETHR_SIZEOF_PTR))
+# define ETHR_NATIVE_DW_ATOMIC_IMPL "gcc_atomic_builtins"
+#elif (ETHR_HAVE___sync_val_compare_and_swap & (2*ETHR_SIZEOF_PTR))
+# define ETHR_NATIVE_DW_ATOMIC_IMPL "gcc_sync_builtins"
+#else
+# error "!?"
+#endif
# if ETHR_SIZEOF_PTR == 4
# define ETHR_DW_NATMC_ALIGN_MASK__ 0x7
@@ -89,15 +94,138 @@ typedef union {
# define ETHR_DW_DBG_ALIGNED__(PTR)
# endif
-#define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_ADDR
+
+#define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_ADDR 1
+
static ETHR_INLINE ethr_sint_t *
ethr_native_dw_atomic_addr(ethr_native_dw_atomic_t *var)
{
return (ethr_sint_t *) ETHR_DW_NATMC_MEM__(var);
}
+#if (ETHR_HAVE___atomic_store_n & (2*ETHR_SIZEOF_PTR))
+
+#if (ETHR_GCC_RELAXED_VERSIONS__ & (2*ETHR_SIZEOF_PTR))
+
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_SET 1
+
+static ETHR_INLINE void
+ethr_native_su_dw_atomic_set(ethr_native_dw_atomic_t *var,
+ ETHR_NATIVE_SU_DW_SINT_T value)
+{
+ ethr_native_dw_ptr_t p = (ethr_native_dw_ptr_t) ETHR_DW_NATMC_MEM__(var);
+ ETHR_DW_DBG_ALIGNED__(p);
+ __atomic_store_n(p, value, __ATOMIC_RELAXED);
+}
+
+#endif /* ETHR_GCC_RELAXED_VERSIONS__ */
+
+#if (ETHR_GCC_RELB_VERSIONS__ & (2*ETHR_SIZEOF_PTR))
+
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_SET_RELB 1
+
+static ETHR_INLINE void
+ethr_native_su_dw_atomic_set_relb(ethr_native_dw_atomic_t *var,
+ ETHR_NATIVE_SU_DW_SINT_T value)
+{
+ ethr_native_dw_ptr_t p = (ethr_native_dw_ptr_t) ETHR_DW_NATMC_MEM__(var);
+ ETHR_DW_DBG_ALIGNED__(p);
+ __atomic_store_n(p, value, __ATOMIC_RELEASE);
+}
+
+#endif /* ETHR_GCC_RELB_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_store_n */
+
+#if (ETHR_HAVE___atomic_load_n & (2*ETHR_SIZEOF_PTR))
+
+#if (ETHR_GCC_RELAXED_VERSIONS__ & (2*ETHR_SIZEOF_PTR))
+
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_READ 1
+
+static ETHR_INLINE ETHR_NATIVE_SU_DW_SINT_T
+ethr_native_su_dw_atomic_read(ethr_native_dw_atomic_t *var)
+{
+ ethr_native_dw_ptr_t p = (ethr_native_dw_ptr_t) ETHR_DW_NATMC_MEM__(var);
+ ETHR_DW_DBG_ALIGNED__(p);
+ return __atomic_load_n(p, __ATOMIC_RELAXED);
+}
+
+#endif /* ETHR_GCC_RELAXED_VERSIONS__ */
+
+#if ((ETHR_GCC_ACQB_VERSIONS__ & (2*ETHR_SIZEOF_PTR)) \
+ & ~ETHR___atomic_load_ACQUIRE_barrier_bug)
+
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_READ_ACQB 1
+
+static ETHR_INLINE ETHR_NATIVE_SU_DW_SINT_T
+ethr_native_su_dw_atomic_read_acqb(ethr_native_dw_atomic_t *var)
+{
+ ethr_native_dw_ptr_t p = (ethr_native_dw_ptr_t) ETHR_DW_NATMC_MEM__(var);
+ ETHR_DW_DBG_ALIGNED__(p);
+ return __atomic_load_n(p, __ATOMIC_ACQUIRE);
+}
+
+#endif /* ETHR_GCC_ACQB_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_load_n */
+
+#if (ETHR_HAVE___atomic_compare_exchange_n & (2*ETHR_SIZEOF_PTR))
+
+#if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & (2*ETHR_SIZEOF_PTR))
-#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_MB
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG 1
+
+static ETHR_INLINE ETHR_NATIVE_SU_DW_SINT_T
+ethr_native_su_dw_atomic_cmpxchg(ethr_native_dw_atomic_t *var,
+ ETHR_NATIVE_SU_DW_SINT_T new,
+ ETHR_NATIVE_SU_DW_SINT_T exp)
+{
+ ethr_native_dw_ptr_t p = (ethr_native_dw_ptr_t) ETHR_DW_NATMC_MEM__(var);
+ ETHR_NATIVE_SU_DW_SINT_T xchg = exp;
+ ETHR_DW_DBG_ALIGNED__(p);
+ if (__atomic_compare_exchange_n(p,
+ &xchg,
+ new,
+ 0,
+ __ATOMIC_RELAXED,
+ __ATOMIC_RELAXED))
+ return exp;
+ return xchg;
+}
+
+#endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
+
+#if (ETHR_GCC_ACQB_MOD_VERSIONS__ & (2*ETHR_SIZEOF_PTR))
+
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_ACQB 1
+
+static ETHR_INLINE ETHR_NATIVE_SU_DW_SINT_T
+ethr_native_su_dw_atomic_cmpxchg_acqb(ethr_native_dw_atomic_t *var,
+ ETHR_NATIVE_SU_DW_SINT_T new,
+ ETHR_NATIVE_SU_DW_SINT_T exp)
+{
+ ethr_native_dw_ptr_t p = (ethr_native_dw_ptr_t) ETHR_DW_NATMC_MEM__(var);
+ ETHR_NATIVE_SU_DW_SINT_T xchg = exp;
+ ETHR_DW_DBG_ALIGNED__(p);
+ if (__atomic_compare_exchange_n(p,
+ &xchg,
+ new,
+ 0,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_ACQUIRE))
+ return exp;
+ return xchg;
+}
+
+#endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
+
+#endif /* ETHR_HAVE___atomic_compare_exchange_n */
+
+#if ((ETHR_HAVE___sync_val_compare_and_swap & (2*ETHR_SIZEOF_PTR)) \
+ & ETHR_GCC_MB_MOD_VERSIONS__)
+
+#define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_MB 1
static ETHR_INLINE ETHR_NATIVE_SU_DW_SINT_T
ethr_native_su_dw_atomic_cmpxchg_mb(ethr_native_dw_atomic_t *var,
@@ -109,7 +237,8 @@ ethr_native_su_dw_atomic_cmpxchg_mb(ethr_native_dw_atomic_t *var,
return __sync_val_compare_and_swap(p, old, new);
}
-#endif /* ETHR_TRY_INLINE_FUNCS */
+#endif /* ETHR_HAVE___sync_val_compare_and_swap */
-#endif /* ETHR_GCC_DW_ATOMIC_H__ */
+#endif /* ETHR_TRY_INLINE_FUNCS */
+#endif /* ETHR_INCLUDE_DW_ATOMIC_IMPL__ */
diff --git a/erts/include/internal/gcc/ethr_membar.h b/erts/include/internal/gcc/ethr_membar.h
index 7d428fc68e..07960ce040 100644
--- a/erts/include/internal/gcc/ethr_membar.h
+++ b/erts/include/internal/gcc/ethr_membar.h
@@ -1,73 +1,214 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2011. All Rights Reserved.
+ * Copyright Ericsson AB 2011-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
/*
- * Description: Memory barriers when using gcc's builtins
+ * Description: Memory barriers when using gcc's __atomic and
+ * __sync builtins
* Author: Rickard Green
+ *
+ * Note: The C11 memory model implemented by gcc's __atomic
+ * builtins does not match the ethread API very well.
+ *
+ * A function with a barrier postfix in the ethread atomic
+ * API needs to ensure that all stores and loads are
+ * ordered around it according to the semantics of the
+ * barrier specified.
+ *
+ * The C11 aproch is different. The __atomic builtins
+ * API takes a memory model parameter. Assuming that all
+ * memory syncronizations using the involved atomic
+ * variables are made using this API, the synchronizations
+ * will adhere to the memory models used. That is, you do
+ * *not* know how loads and stores will be ordered around
+ * a specific __atomic operation in the general case. You
+ * only know the total effect of the combination of
+ * operations issued will adhere to the model.
+ *
+ * This limits how we can use the __atomic builtins. What
+ * we cannot use:
+ *
+ * 1. We cannot rely on __atomic_thread_fence() to issue
+ * any specific memory barriers at all. This regardless
+ * of memory model parameter passed. That is, we cannot
+ * use the __atomic_thread_fence() builtin at all.
+ *
+ * Why is this? If all __atomic builtins accessing
+ * memory issue memory barriers, __atomic_thread_fence()
+ * does not have to issue memory barriers. The
+ * implementation for the Itanium architecture is an
+ * example of this. Even using the __ATOMIC_RELAXED
+ * memory model all __atomic builtins accessing memory
+ * will issue memory barriers. Due to this no memory
+ * barriers at all will be issued by
+ * __atomic_thread_fence() using either one of the
+ * __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, or
+ * __ATOMIC_RELEASE memory models.
+ *
+ * 2. We cannot rely on any __atomic builtin with the
+ * __ATOMIC_SEQ_CST memory model parameters to
+ * issue any specific memory barriers. That is, we
+ * cannot use these memory models at all.
+ *
+ * Why is this? Since all synchronizations is expected
+ * to be made using the __atomic builtins, memory
+ * barriers only have to be issued by some of them,
+ * and you do not know which ones wont issue memory
+ * barriers.
+ *
+ * One can easily be fooled into believing that when
+ * using the __ATOMIC_SEQ_CST memory model on all
+ * operations, all operations will issue full memory
+ * barriers. This is however not the case. The
+ * implementation for the x86_64 architecture is an
+ * example of this. Since all operations except loads
+ * issue full memory barriers, no memory barriers at
+ * all is issued by loads. This could also be
+ * implemented by issuing a full memory barrier on
+ * loads, but no barrier at all on stores.
+ *
+ * What can be used then?
+ * 1. All (legacy) __sync builtins implying full memory
+ * barriers issued.
+ * 2. All __atomic builtins using the __ATOMIC_RELAXED
+ * memory model can, of course, be used. This since
+ * no ordering guarantees at all are made.
+ * 3. All __atomic builtins accessing memory using the
+ * __ATOMIC_ACQUIRE and __ATOMIC_RELEASE memory
+ * models. This since an __atomic builtin memory
+ * access using the __ATOMIC_ACQUIRE must at least
+ * issue an aquire memory barrier and an __atomic
+ * builtin memory acess with the __ATOMIC_RELEASE
+ * memory model must at least issue a release memory
+ * barrier. Otherwise the two can not be paired.
+ * 4. All __atomic builtins accessing memory using the
+ * __ATOMIC_CONSUME builtin can be used for the same
+ * reason __ATOMIC_ACQUIRE can be used. The ethread
+ * atomic framework implementing the ethread API
+ * using native implementations does not expect the
+ * native implementations to produce versions with
+ * data dependent read barriers, so until the
+ * framework is changed we haven't got any use for
+ * for it.
+ *
+ * For some architectures we have our own memory barrier
+ * implementations. We prefer to use these since they
+ * should be as fine grained as possible. For other
+ * architectures we use the __sync_synchronize() builtin
+ * which issue a full memory barrier. For these
+ * architectures we have to assume that all loads and
+ * stores can be reordered without limitation. That is,
+ * unnecessary memory barriers will be issued if such
+ * reordering actually cannot occur.
*/
-#ifndef ETHR_GCC_MEMBAR_H__
-#define ETHR_GCC_MEMBAR_H__
+/*
+ * We prefer to use our own memory barrier implementation if
+ * such exist instead of using __sync_synchronize()...
+ */
+#if defined(__i386__) || defined(__x86_64__)
+# include "../i386/ethr_membar.h"
+#elif defined(__sparc__)
+# include "../sparc32/ethr_membar.h"
+#elif defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__)
+# include "../ppc32/ethr_membar.h"
+#elif !defined(ETHR_GCC_ATOMIC_MEMBAR_H__) \
+ && (ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION \
+ || ETHR_HAVE___sync_synchronize \
+ || (ETHR_HAVE___sync_val_compare_and_swap & 12))
+#define ETHR_GCC_ATOMIC_MEMBAR_H__
#define ETHR_LoadLoad (1 << 0)
#define ETHR_LoadStore (1 << 1)
#define ETHR_StoreLoad (1 << 2)
#define ETHR_StoreStore (1 << 3)
+#define ETHR_COMPILER_BARRIER __asm__ __volatile__("" : : : "memory")
+
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION
+
+static __inline__ __attribute__((__always_inline__)) void
+ethr_full_fence__(void)
+{
+ __asm__ __volatile__("dmb sy" : : : "memory");
+}
+
+static __inline__ __attribute__((__always_inline__)) void
+ethr_store_fence__(void)
+{
+ __asm__ __volatile__("dmb st" : : : "memory");
+}
+
+#define ETHR_MEMBAR(B) \
+ ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore, ethr_store_fence__(), ethr_full_fence__())
+
+#elif ETHR_HAVE___sync_synchronize
+
+static __inline__ __attribute__((__always_inline__)) void
+ethr_full_fence__(void)
+{
+ /*
+ * The compiler barriers are here to fix missing clobbers
+ * in __sync_synchronize() when using buggy LLVM
+ * implementation of __sync_synchronize(). They
+ * do not introduce any unnecessary overhead when used
+ * here, so we use them for all systems.
+ */
+ ETHR_COMPILER_BARRIER;
+ __sync_synchronize();
+ ETHR_COMPILER_BARRIER;
+}
+
+#else /* !ETHR_HAVE___sync_synchronize */
+
/*
- * According to the documentation __sync_synchronize() will
- * issue a full memory barrier. However, __sync_synchronize()
- * is known to erroneously be a noop on at least some
- * platforms with some gcc versions. This has suposedly been
- * fixed in some gcc version, but we don't know from which
- * version. Therefore, we only use it when it has been
- * verified to work. Otherwise we use the workaround
- * below.
+ * Buggy __sync_synchronize(); call __sync_val_compare_and_swap()
+ * instead which imply a full memory barrier (and hope that one
+ * isn't buggy too).
*/
-#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32)
+#if (ETHR_HAVE___sync_val_compare_and_swap & 4)
# define ETHR_MB_T__ ethr_sint32_t
-#elif defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64)
+#elif (ETHR_HAVE___sync_val_compare_and_swap & 8)
# define ETHR_MB_T__ ethr_sint64_t
-#else
-# error "No __sync_val_compare_and_swap"
#endif
-#define ETHR_SYNC_SYNCHRONIZE_WORKAROUND__ \
-do { \
- volatile ETHR_MB_T__ x___ = 0; \
- (void) __sync_val_compare_and_swap(&x___, (ETHR_MB_T__) 0, (ETHR_MB_T__) 1); \
-} while (0)
-#define ETHR_COMPILER_BARRIER __asm__ __volatile__("" : : : "memory")
+static __inline__ __attribute__((__always_inline__)) void
+ethr_full_fence__(void)
+{
+ volatile ETHR_MB_T__ x = 0;
+ (void) __sync_val_compare_and_swap(&x, (ETHR_MB_T__) 0, (ETHR_MB_T__) 1);
+}
-#if defined(__mips__) && ETHR_AT_LEAST_GCC_VSN__(4, 2, 0)
-# define ETHR_MEMBAR(B) __sync_synchronize()
-# define ETHR_READ_DEPEND_MEMORY_BARRIER __sync_synchronize()
-#elif ((defined(__powerpc__) || defined(__ppc__)) \
- && ETHR_AT_LEAST_GCC_VSN__(4, 1, 2))
-# define ETHR_MEMBAR(B) __sync_synchronize()
-#else /* Use workaround */
-# define ETHR_MEMBAR(B) \
- ETHR_SYNC_SYNCHRONIZE_WORKAROUND__
-# define ETHR_READ_DEPEND_MEMORY_BARRIER \
- ETHR_SYNC_SYNCHRONIZE_WORKAROUND__
+#endif /* !ETHR_HAVE___sync_synchronize */
+
+#ifndef ETHR_MEMBAR
+# define ETHR_MEMBAR(B) ethr_full_fence__()
#endif
+/*
+ * Define ETHR_READ_DEPEND_MEMORY_BARRIER for all architechtures
+ * not known to order data dependent loads
+ */
+
+#if !defined(__ia64__) && !defined(__arm__)
+# define ETHR_READ_DEPEND_MEMORY_BARRIER ETHR_MEMBAR(ETHR_LoadLoad)
+#endif
-#endif /* ETHR_GCC_MEMBAR_H__ */
+#endif /* ETHR_GCC_ATOMIC_MEMBAR_H__ */
diff --git a/erts/include/internal/gcc/ethread.h b/erts/include/internal/gcc/ethread.h
index 365a3535cf..12b41f8704 100644
--- a/erts/include/internal/gcc/ethread.h
+++ b/erts/include/internal/gcc/ethread.h
@@ -1,37 +1,310 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
/*
- * Description: Native atomic ethread support when using gcc
+ * Description: Native atomic ethread support when using gcc's __atomic
+ * and __sync builtins
* Author: Rickard Green
*/
-#ifndef ETHREAD_GCC_H__
-#define ETHREAD_GCC_H__
-
-#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32) \
- || defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64)
+#if !defined(ETHREAD_GCC_NATIVE_H__) && ETHR_GCC_COMPILER
+#define ETHREAD_GCC_NATIVE_H__
#ifndef ETHR_MEMBAR
# include "ethr_membar.h"
#endif
+#define ETHR_GCC_VERSIONS_MASK__ 28
+
+#undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__
+#undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__
+#undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__
+#undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__
+#undef ETHR_GCC_RELAXED_VERSIONS__
+#undef ETHR_GCC_RELAXED_MOD_VERSIONS__
+#undef ETHR_GCC_ACQB_VERSIONS__
+#undef ETHR_GCC_ACQB_MOD_VERSIONS__
+#undef ETHR_GCC_RELB_VERSIONS__
+#undef ETHR_GCC_RELB_MOD_VERSIONS__
+#undef ETHR_GCC_MB_MOD_VERSIONS__
+
+/*
+ * True GNU GCCs before version 4.8 do not emit a memory barrier
+ * after the load in the __atomic_load_n(_, __ATOMIC_ACQUIRE)
+ * case (which is needed on most architectures).
+ */
+#undef ETHR___atomic_load_ACQUIRE_barrier_bug
+#if ETHR_GCC_COMPILER != ETHR_GCC_COMPILER_TRUE
+/*
+ * A gcc compatible compiler. We have no information
+ * about the existence of this bug, but we assume
+ * that it is not impossible that it could have
+ * been "inherited". Therefore, until we are certain
+ * that the bug does not exist, we assume that it
+ * does.
+ */
+# define ETHR___atomic_load_ACQUIRE_barrier_bug ETHR_GCC_VERSIONS_MASK__
+#elif !ETHR_AT_LEAST_GCC_VSN__(4, 8, 0)
+/* True gcc of version < 4.8, i.e., bug exist... */
+# define ETHR___atomic_load_ACQUIRE_barrier_bug ETHR_GCC_VERSIONS_MASK__
+#else /* True gcc of version >= 4.8 */
+/*
+ * Sizes less than or equal to word size have been fixed,
+ * but double word size has not been fixed.
+ */
+# if ETHR_SIZEOF_PTR == 8
+# define ETHR___atomic_load_ACQUIRE_barrier_bug \
+ (~(8|4) & ETHR_GCC_VERSIONS_MASK__)
+# elif ETHR_SIZEOF_PTR == 4
+# define ETHR___atomic_load_ACQUIRE_barrier_bug \
+ (~4 & ETHR_GCC_VERSIONS_MASK__)
+# else
+# error word size not supported
+# endif
+#endif
+
+#define ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__ 0
+#define ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ 0
+#define ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ 0
+#define ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ 0
+#define ETHR_GCC_RELAXED_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+#define ETHR_GCC_RELAXED_MOD_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+
+#if ETHR_TRUST_GCC_ATOMIC_BUILTINS_MEMORY_BARRIERS
+# define ETHR_GCC_ACQB_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+# define ETHR_GCC_ACQB_MOD_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+# define ETHR_GCC_RELB_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+# define ETHR_GCC_RELB_MOD_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+#else
+/*
+ * This is currently the default (on most platforms) since
+ * we've seen too many memory barrier bugs produced by gcc...
+ */
+# define ETHR_GCC_ACQB_VERSIONS__ 0
+# define ETHR_GCC_ACQB_MOD_VERSIONS__ 0
+# define ETHR_GCC_RELB_VERSIONS__ 0
+# define ETHR_GCC_RELB_MOD_VERSIONS__ 0
+#endif
+/*
+ * In the general case we do not want any full barrier versions
+ * if we can implement more relaxed ones (using __atomic_* builtins).
+ * This since the implementations normally need extra memory barrier
+ * instructions to implement these. The x86/x86_64 implementations
+ * are an exception see below.
+ */
+#define ETHR_GCC_MB_MOD_VERSIONS__ \
+ (ETHR_GCC_VERSIONS_MASK__ & ~ETHR_HAVE___atomic_compare_exchange_n)
+
+#if ETHR_SIZEOF_PTR == 8
+# define ETHR_GCC_VOLATILE_BIT_MASK__ 12
+#elif ETHR_SIZEOF_PTR == 4
+# define ETHR_GCC_VOLATILE_BIT_MASK__ 4
+#endif
+
+#if defined(__i386__) || defined(__x86_64__) || defined(__sparc__) \
+ || defined(__powerpc__) || defined(__ppc__) || defined(__mips__) \
+ || defined(__alpha__) || defined(__ia64__)
+
+/*
+ * Aligned volatile stores and loads of data smaller
+ * than or equal to word size are atomic...
+ */
+# undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__
+# define ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__ ETHR_GCC_VOLATILE_BIT_MASK__
+# undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__
+# define ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ ETHR_GCC_VOLATILE_BIT_MASK__
+
+#elif defined(__arm__)
+
+/* volatile stores are problematic on some machines... */
+# undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__
+# define ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ ETHR_GCC_VOLATILE_BIT_MASK__
+
+#endif
+
+#if defined(__ia64__)
+
+/* Volatile stores produce stores with release barriers. */
+# undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__
+# define ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ ETHR_GCC_VOLATILE_BIT_MASK__
+
+/* Volatile loads produce loads with acquire barrier. */
+# undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__
+# define ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ ETHR_GCC_VOLATILE_BIT_MASK__
+
+/*
+ * We trust gcc to produce acquire/release barriers on itanium.
+ * Since all atomic ops also have at least acquire or release
+ * barriers (also when passed the relaxed memory model) it
+ * would be very inefficient not to use these as native
+ * barriers on Itanium.
+ */
+# undef ETHR_GCC_ACQB_VERSIONS__
+# define ETHR_GCC_ACQB_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+# undef ETHR_GCC_ACQB_MOD_VERSIONS__
+# define ETHR_GCC_ACQB_MOD_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+# undef ETHR_GCC_RELB_VERSIONS__
+# define ETHR_GCC_RELB_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+# undef ETHR_GCC_RELB_MOD_VERSIONS__
+# define ETHR_GCC_RELB_MOD_VERSIONS__ ETHR_GCC_VERSIONS_MASK__
+
+/*
+ * Itanium is not effected by the load acquire
+ * bug since the barrier is part of the instruction
+ * on Itanium (ld.acq), and not a separate instruction
+ * as on most platforms.
+ */
+# undef ETHR___atomic_load_ACQUIRE_barrier_bug
+# define ETHR___atomic_load_ACQUIRE_barrier_bug 0
+
+/*
+ * No point exposing relaxed versions since they are
+ * implemended using either acquire or release
+ * barriers.
+ */
+# undef ETHR_GCC_RELAXED_VERSIONS__
+# define ETHR_GCC_RELAXED_VERSIONS__ 0
+
+/* #endif defined(__ia64__) */
+#elif defined(__i386__) || defined(__x86_64__)
+
+/*
+ * Want full barrier versions of all modification
+ * operations since all of these are implemented
+ * using locked instructions implying full memory
+ * barriers.
+ */
+# undef ETHR_GCC_MB_MOD_VERSIONS__
+# define ETHR_GCC_MB_MOD_VERSIONS__ ETHR_HAVE___sync_val_compare_and_swap
+
+/*
+ * No point exposing acquire/release versions
+ * when we got full memory barrier versions
+ * of modification operations since all of these
+ * are implemented using locked instructions
+ * implying full memory barriers.
+ */
+# if ETHR_GCC_ACQB_MOD_VERSIONS__
+# undef ETHR_GCC_ACQB_MOD_VERSIONS__
+# define ETHR_GCC_ACQB_MOD_VERSIONS__ \
+ (ETHR_GCC_VERSIONS_MASK__ & ~ETHR_HAVE___sync_val_compare_and_swap)
+# endif
+# if ETHR_GCC_RELB_MOD_VERSIONS__
+# undef ETHR_GCC_RELB_MOD_VERSIONS__
+# define ETHR_GCC_RELB_MOD_VERSIONS__ \
+ (ETHR_GCC_VERSIONS_MASK__ & ~ETHR_HAVE___sync_val_compare_and_swap)
+# endif
+
+# ifdef ETHR_X86_OUT_OF_ORDER
+
+/* See above... */
+# undef ETHR_GCC_RELAXED_MOD_VERSIONS__
+# define ETHR_GCC_RELAXED_MOD_VERSIONS__ 0
+
+# else /* !ETHR_X86_OUT_OF_ORDER, i.e., we don't use any x86-OOO instructions... */
+
+/*
+ * Not effected by the load acquire barrier bug,
+ * since no barrier at all is needed for a load
+ * acquire...
+ */
+# undef ETHR___atomic_load_ACQUIRE_barrier_bug
+# define ETHR___atomic_load_ACQUIRE_barrier_bug 0
+
+/* Stores imply release barriers semantics. */
+# undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__
+# define ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ ETHR_GCC_VOLATILE_BIT_MASK__
+
+/* Loads imply acquire barrier semantics. */
+# undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__
+# define ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ ETHR_GCC_VOLATILE_BIT_MASK__
+
+/*
+ * Trust load acquire and store release for sizes
+ * where volatile operation implies these barrier
+ * semantics since no barriers are needed.
+ */
+# if !ETHR_GCC_ACQB_VERSIONS__
+# undef ETHR_GCC_ACQB_VERSIONS__
+# define ETHR_GCC_ACQB_VERSIONS__ ETHR_GCC_VOLATILE_BIT_MASK__
+# endif
+# if !ETHR_GCC_RELB_VERSIONS__
+# undef ETHR_GCC_RELB_VERSIONS__
+# define ETHR_GCC_RELB_VERSIONS__ ETHR_GCC_VOLATILE_BIT_MASK__
+# endif
+
+/*
+ * No point exposing relaxed versions at all since
+ * all mod operations are implemented with locked
+ * instructions implying full memory barriers and
+ * volatile store and load imply release and
+ * acquire barrier semantics.
+ */
+# undef ETHR_GCC_RELAXED_VERSIONS__
+# define ETHR_GCC_RELAXED_VERSIONS__ 0
+
+# endif /* !ETHR_X86_OUT_OF_ORDER */
+
+/* #endif defined(__i386__) || defined(__x86_64__) */
+#elif defined(__powerpc__) || defined(__ppc__)
+
+# if !defined(ETHR_PPC_HAVE_LWSYNC)
+/*
+ * Release barriers are typically implemented using
+ * the lwsync instruction. We want our runtime
+ * configure test to determine if the lwsync
+ * instruction is available on the system or not
+ * before we use it. Therefore, do not implement any
+ * native ops using the __ATOMIC_RELEASE model.
+ */
+# undef ETHR_GCC_RELB_VERSIONS__
+# define ETHR_GCC_RELB_VERSIONS__ 0
+# if defined(ETHR_GCC_IMPLEMENT_ACQB_USING_LWSYNC)
+/*
+ * Acquire barriers are usually implemented by other means
+ * than lwsync, but can be implemented using lwsync. Define
+ * ETHR_GCC_IMPLEMENT_ACQB_USING_LWSYNC if acquire barriers
+ * are implemented using lwsync.
+ */
+# undef ETHR_GCC_ACQB_VERSIONS__
+# define ETHR_GCC_ACQB_VERSIONS__ 0
+# endif
+# endif
+
+#endif /* defined(__powerpc__) || defined(__ppc__) */
+
+#if !ETHR_GCC_RELAXED_VERSIONS__
+# undef ETHR_GCC_RELAXED_MOD_VERSIONS__
+# define ETHR_GCC_RELAXED_MOD_VERSIONS__ 0
+#endif
+
+#if !ETHR_GCC_ACQB_VERSIONS__
+# undef ETHR_GCC_ACQB_MOD_VERSIONS__
+# define ETHR_GCC_ACQB_MOD_VERSIONS__ 0
+#endif
+
+#if !ETHR_GCC_RELB_VERSIONS__
+# undef ETHR_GCC_RELB_MOD_VERSIONS__
+# define ETHR_GCC_RELB_MOD_VERSIONS__ 0
+#endif
+
#if !defined(ETHR_HAVE_NATIVE_ATOMIC32)
# define ETHR_ATOMIC_WANT_32BIT_IMPL__
# include "ethr_atomic.h"
@@ -42,12 +315,51 @@
# include "ethr_atomic.h"
#endif
+#if defined(__x86_64__)
+/*
+ * No instructions available for native implementation
+ * of these for dw-atomics...
+ */
+# undef ETHR_GCC_RELAXED_VERSIONS__
+# define ETHR_GCC_RELAXED_VERSIONS__ 0
+# undef ETHR_GCC_ACQB_VERSIONS__
+# define ETHR_GCC_ACQB_VERSIONS__ 0
+# undef ETHR_GCC_RELB_VERSIONS__
+# define ETHR_GCC_RELB_VERSIONS__ 0
+#endif
+
+#if !ETHR_GCC_RELAXED_VERSIONS__
+# undef ETHR_GCC_RELAXED_MOD_VERSIONS__
+# define ETHR_GCC_RELAXED_MOD_VERSIONS__ 0
+#endif
+
+#if !ETHR_GCC_ACQB_VERSIONS__
+# undef ETHR_GCC_ACQB_MOD_VERSIONS__
+# define ETHR_GCC_ACQB_MOD_VERSIONS__ 0
+#endif
+
+#if !ETHR_GCC_RELB_VERSIONS__
+# undef ETHR_GCC_RELB_MOD_VERSIONS__
+# define ETHR_GCC_RELB_MOD_VERSIONS__ 0
+#endif
+
#if (!defined(ETHR_HAVE_NATIVE_DW_ATOMIC) \
&& !(ETHR_SIZEOF_PTR == 4 && defined(ETHR_HAVE_NATIVE_ATOMIC64)) \
&& !(ETHR_SIZEOF_PTR == 8 && defined(ETHR_HAVE_NATIVE_ATOMIC128)))
# include "ethr_dw_atomic.h"
#endif
-#endif
+#undef ETHR___atomic_load_ACQUIRE_barrier_bug
+#undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__
+#undef ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__
+#undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__
+#undef ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__
+#undef ETHR_GCC_RELAXED_VERSIONS__
+#undef ETHR_GCC_RELB_VERSIONS__
+#undef ETHR_GCC_RELB_VERSIONS__
+#undef ETHR_GCC_RELAXED_MOD_VERSIONS__
+#undef ETHR_GCC_ACQB_MOD_VERSIONS__
+#undef ETHR_GCC_RELB_MOD_VERSIONS__
+#undef ETHR_GCC_MB_MOD_VERSIONS__
-#endif
+#endif /* ETHREAD_GCC_NATIVE_H__ */
diff --git a/erts/include/internal/i386/atomic.h b/erts/include/internal/i386/atomic.h
index fc1b619935..6a6435e58d 100644
--- a/erts/include/internal/i386/atomic.h
+++ b/erts/include/internal/i386/atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/i386/ethr_dw_atomic.h b/erts/include/internal/i386/ethr_dw_atomic.h
index 9fb89bbe43..5444a6345c 100644
--- a/erts/include/internal/i386/ethr_dw_atomic.h
+++ b/erts/include/internal/i386/ethr_dw_atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -114,13 +115,19 @@ ethr_native_dw_atomic_addr(ethr_native_dw_atomic_t *var)
return (ethr_sint_t *) ETHR_DW_NATMC_MEM__(var);
}
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
+#if defined(ETHR_CMPXCHG8B_PIC_NO_CLOBBER_EBX) && defined(__PIC__) && __PIC__
+#if ETHR_SIZEOF_PTR != 4
+# error unexpected pic issue
+#endif
/*
* When position independent code is used in 32-bit mode, the EBX register
- * is used for storage of global offset table address, and we may not
- * use it as input or output in an asm. We need to save and restore the
- * EBX register explicitly (for some reason gcc doesn't provide this
- * service to us).
+ * is used for storage of global offset table address. When compiling with
+ * an old gcc (< vsn 5) we may not use it as input or output in an inline
+ * asm. We then need to save and restore the EBX register explicitly (for
+ * some reason old gcc compilers didn't provide this service to us).
+ * ETHR_CMPXCHG8B_PIC_NO_CLOBBER_EBX will be defined if we need to
+ * explicitly manage EBX ourselves.
+ *
*/
# define ETHR_NO_CLOBBER_EBX__ 1
#else
@@ -150,36 +157,53 @@ ethr_native_dw_atomic_cmpxchg_mb(ethr_native_dw_atomic_t *var,
ETHR_DW_DBG_ALIGNED__(p);
+#if ETHR_NO_CLOBBER_EBX__ && ETHR_CMPXCHG8B_REGISTER_SHORTAGE
+ /*
+ * gcc wont let us use ebx as input and we
+ * get a register shortage
+ */
+
__asm__ __volatile__(
-#if ETHR_NO_CLOBBER_EBX__
"pushl %%ebx\n\t"
-# if ETHR_CMPXCHG8B_REGISTER_SHORTAGE
"movl (%7), %%ebx\n\t"
"movl 4(%7), %%ecx\n\t"
-# else
- "movl %8, %%ebx\n\t"
-# endif
-#endif
- "lock; cmpxchg" ETHR_DW_CMPXCHG_SFX__ " %0\n\t"
+ "lock; cmpxchg8b %0\n\t"
"setz %3\n\t"
-#if ETHR_NO_CLOBBER_EBX__
"popl %%ebx\n\t"
-#endif
: "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]),
-#if ETHR_NO_CLOBBER_EBX__
-# if ETHR_CMPXCHG8B_REGISTER_SHORTAGE
- "3"(new)
-# else
- "3"(new[1]),
- "r"(new[0])
-# endif
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "r"(new)
+ : "cc", "memory");
+
+#elif ETHR_NO_CLOBBER_EBX__
+ /*
+ * gcc wont let us use ebx as input
+ */
+
+ __asm__ __volatile__(
+ "pushl %%ebx\n\t"
+ "movl %8, %%ebx\n\t"
+ "lock; cmpxchg8b %0\n\t"
+ "setz %3\n\t"
+ "popl %%ebx\n\t"
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=q"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "c"(new[1]), "r"(new[0])
+ : "cc", "memory");
+
#else
- "3"(new[1]),
- "b"(new[0])
-#endif
+ /*
+ * gcc lets us place values in the registers where
+ * we want them
+ */
+
+ __asm__ __volatile__(
+ "lock; cmpxchg" ETHR_DW_CMPXCHG_SFX__ " %0\n\t"
+ "setz %3\n\t"
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=q"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "c"(new[1]), "b"(new[0])
: "cc", "memory");
+#endif
+
return (int) xchgd;
}
diff --git a/erts/include/internal/i386/ethr_membar.h b/erts/include/internal/i386/ethr_membar.h
index 92d9de7f3f..97ae5eda2c 100644
--- a/erts/include/internal/i386/ethr_membar.h
+++ b/erts/include/internal/i386/ethr_membar.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/i386/ethread.h b/erts/include/internal/i386/ethread.h
index 80e4dc7b99..23dcd1dc19 100644
--- a/erts/include/internal/i386/ethread.h
+++ b/erts/include/internal/i386/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/i386/rwlock.h b/erts/include/internal/i386/rwlock.h
index 1a8cd7da0c..9859338eab 100644
--- a/erts/include/internal/i386/rwlock.h
+++ b/erts/include/internal/i386/rwlock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/i386/spinlock.h b/erts/include/internal/i386/spinlock.h
index a84fba91b1..e010684d14 100644
--- a/erts/include/internal/i386/spinlock.h
+++ b/erts/include/internal/i386/spinlock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/libatomic_ops/ethr_atomic.h b/erts/include/internal/libatomic_ops/ethr_atomic.h
index 734cdf0890..828210036c 100644
--- a/erts/include/internal/libatomic_ops/ethr_atomic.h
+++ b/erts/include/internal/libatomic_ops/ethr_atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/libatomic_ops/ethr_dw_atomic.h b/erts/include/internal/libatomic_ops/ethr_dw_atomic.h
index 4dd9f41e96..ce9b251cbe 100644
--- a/erts/include/internal/libatomic_ops/ethr_dw_atomic.h
+++ b/erts/include/internal/libatomic_ops/ethr_dw_atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/libatomic_ops/ethr_membar.h b/erts/include/internal/libatomic_ops/ethr_membar.h
index b8530a0094..7d2b807586 100644
--- a/erts/include/internal/libatomic_ops/ethr_membar.h
+++ b/erts/include/internal/libatomic_ops/ethr_membar.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/libatomic_ops/ethread.h b/erts/include/internal/libatomic_ops/ethread.h
index d65ee19b04..e34f43bb46 100644
--- a/erts/include/internal/libatomic_ops/ethread.h
+++ b/erts/include/internal/libatomic_ops/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ose/ethr_event.h b/erts/include/internal/ose/ethr_event.h
index 000a600813..c18f30aa4a 100644
--- a/erts/include/internal/ose/ethr_event.h
+++ b/erts/include/internal/ose/ethr_event.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ppc32/atomic.h b/erts/include/internal/ppc32/atomic.h
index b558626b09..572b0e5191 100644
--- a/erts/include/internal/ppc32/atomic.h
+++ b/erts/include/internal/ppc32/atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ppc32/ethr_membar.h b/erts/include/internal/ppc32/ethr_membar.h
index ff5cc86bfb..fe77721cd9 100644
--- a/erts/include/internal/ppc32/ethr_membar.h
+++ b/erts/include/internal/ppc32/ethr_membar.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ppc32/ethread.h b/erts/include/internal/ppc32/ethread.h
index e41c83c5da..25e85c58bd 100644
--- a/erts/include/internal/ppc32/ethread.h
+++ b/erts/include/internal/ppc32/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/ppc32/rwlock.h b/erts/include/internal/ppc32/rwlock.h
index 311f000b69..aee232f79d 100644
--- a/erts/include/internal/ppc32/rwlock.h
+++ b/erts/include/internal/ppc32/rwlock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/ppc32/spinlock.h b/erts/include/internal/ppc32/spinlock.h
index 4c95ec9efb..829db6a135 100644
--- a/erts/include/internal/ppc32/spinlock.h
+++ b/erts/include/internal/ppc32/spinlock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/pthread/ethr_event.h b/erts/include/internal/pthread/ethr_event.h
index d0a77990cc..deb4b29686 100644
--- a/erts/include/internal/pthread/ethr_event.h
+++ b/erts/include/internal/pthread/ethr_event.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -46,12 +47,12 @@ typedef struct {
ethr_atomic32_t futex;
} ethr_event;
-#define ETHR_FUTEX__(FTX, OP, VAL) \
+#define ETHR_FUTEX__(FTX, OP, VAL, TIMEOUT) \
(-1 == syscall(__NR_futex, \
(void *) ethr_atomic32_addr((FTX)), \
(OP), \
(int) (VAL), \
- NULL, \
+ (TIMEOUT), \
NULL, \
0) \
? errno : 0)
@@ -64,7 +65,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
ethr_sint32_t val;
val = ethr_atomic32_xchg_mb(&e->futex, ETHR_EVENT_ON__);
if (val == ETHR_EVENT_OFF_WAITER__) {
- int res = ETHR_FUTEX__(&e->futex, ETHR_FUTEX_WAKE__, 1);
+ int res = ETHR_FUTEX__(&e->futex, ETHR_FUTEX_WAKE__, 1, NULL);
if (res != 0)
ETHR_FATAL_ERROR__(res);
}
@@ -80,35 +81,68 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
#endif
#elif defined(ETHR_PTHREADS)
-/* --- Posix mutex/cond implementation of events ---------------------------- */
+/* --- Posix mutex/cond pipe/select implementation of events ---------------- */
+
+#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+# define __DARWIN__ 1
+#endif
+
+#ifdef __DARWIN__
+typedef struct ethr_event_fdsets___ ethr_event_fdsets__;
+#endif
typedef struct {
ethr_atomic32_t state;
pthread_mutex_t mtx;
pthread_cond_t cnd;
+ int fd[2];
+#ifdef __DARWIN__
+ ethr_event_fdsets__ *fdsets;
+#endif
} ethr_event;
-#define ETHR_EVENT_OFF_WAITER__ -1L
-#define ETHR_EVENT_OFF__ 1L
-#define ETHR_EVENT_ON__ 0L
+#define ETHR_EVENT_OFF_WAITER_SELECT__ ((ethr_sint32_t) -2)
+#define ETHR_EVENT_OFF_WAITER__ ((ethr_sint32_t) -1)
+#define ETHR_EVENT_OFF__ ((ethr_sint32_t) 1)
+#define ETHR_EVENT_ON__ ((ethr_sint32_t) 0)
+
+#define ETHR_EVENT_IS_WAITING__(VAL) ((VAL) < 0)
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
+#ifndef ETHR_HAVE_PTHREAD_TIMED_COND_MONOTONIC
+#include <unistd.h>
+#include <errno.h>
+#endif
+
static void ETHR_INLINE
ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
{
ethr_sint32_t val;
val = ethr_atomic32_xchg_mb(&e->state, ETHR_EVENT_ON__);
- if (val == ETHR_EVENT_OFF_WAITER__) {
- int res = pthread_mutex_lock(&e->mtx);
- if (res != 0)
- ETHR_FATAL_ERROR__(res);
- res = pthread_cond_signal(&e->cnd);
- if (res != 0)
- ETHR_FATAL_ERROR__(res);
- res = pthread_mutex_unlock(&e->mtx);
- if (res != 0)
- ETHR_FATAL_ERROR__(res);
+ if (ETHR_EVENT_IS_WAITING__(val)) {
+ int res;
+ if (val == ETHR_EVENT_OFF_WAITER_SELECT__) {
+ ssize_t wres;
+ int fd = e->fd[1];
+ ETHR_ASSERT(fd >= 0);
+ do {
+ wres = write(fd, "!", 1);
+ } while (wres < 0 && errno == EINTR);
+ if (wres < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
+ ETHR_FATAL_ERROR__(errno);
+ }
+ else {
+ res = pthread_mutex_lock(&e->mtx);
+ if (res != 0)
+ ETHR_FATAL_ERROR__(res);
+ res = pthread_cond_signal(&e->cnd);
+ if (res != 0)
+ ETHR_FATAL_ERROR__(res);
+ res = pthread_mutex_unlock(&e->mtx);
+ if (res != 0)
+ ETHR_FATAL_ERROR__(res);
+ }
}
}
@@ -124,9 +158,12 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
#endif
int ethr_event_init(ethr_event *e);
+int ethr_event_prepare_timed(ethr_event *e);
int ethr_event_destroy(ethr_event *e);
int ethr_event_wait(ethr_event *e);
int ethr_event_swait(ethr_event *e, int spincount);
+int ethr_event_twait(ethr_event *e, ethr_sint64_t timeout);
+int ethr_event_stwait(ethr_event *e, int spincount, ethr_sint64_t timeout);
#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
void ethr_event_set(ethr_event *e);
void ethr_event_reset(ethr_event *e);
diff --git a/erts/include/internal/sparc32/atomic.h b/erts/include/internal/sparc32/atomic.h
index fe1daaa9cf..0b535242ad 100644
--- a/erts/include/internal/sparc32/atomic.h
+++ b/erts/include/internal/sparc32/atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/sparc32/ethr_membar.h b/erts/include/internal/sparc32/ethr_membar.h
index 6eb0c5a1d6..6133de5eb7 100644
--- a/erts/include/internal/sparc32/ethr_membar.h
+++ b/erts/include/internal/sparc32/ethr_membar.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/sparc32/ethread.h b/erts/include/internal/sparc32/ethread.h
index 5ad92d3da7..513d9f8773 100644
--- a/erts/include/internal/sparc32/ethread.h
+++ b/erts/include/internal/sparc32/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/sparc32/rwlock.h b/erts/include/internal/sparc32/rwlock.h
index 8b6f2e9c57..44de6113b7 100644
--- a/erts/include/internal/sparc32/rwlock.h
+++ b/erts/include/internal/sparc32/rwlock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/sparc32/spinlock.h b/erts/include/internal/sparc32/spinlock.h
index d4e36e09cf..695fa112b6 100644
--- a/erts/include/internal/sparc32/spinlock.h
+++ b/erts/include/internal/sparc32/spinlock.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/sparc64/ethread.h b/erts/include/internal/sparc64/ethread.h
index 65fd58d492..5f518e5596 100644
--- a/erts/include/internal/sparc64/ethread.h
+++ b/erts/include/internal/sparc64/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/tile/atomic.h b/erts/include/internal/tile/atomic.h
index 1f1553c346..1a2881442e 100644
--- a/erts/include/internal/tile/atomic.h
+++ b/erts/include/internal/tile/atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/tile/ethr_membar.h b/erts/include/internal/tile/ethr_membar.h
index 7cb4f3cf9a..ccb420d558 100644
--- a/erts/include/internal/tile/ethr_membar.h
+++ b/erts/include/internal/tile/ethr_membar.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/tile/ethread.h b/erts/include/internal/tile/ethread.h
index 7f579b50e7..577d275965 100644
--- a/erts/include/internal/tile/ethread.h
+++ b/erts/include/internal/tile/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/include/internal/win/ethr_atomic.h b/erts/include/internal/win/ethr_atomic.h
index e11f1abf47..f17526a94d 100644
--- a/erts/include/internal/win/ethr_atomic.h
+++ b/erts/include/internal/win/ethr_atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/win/ethr_dw_atomic.h b/erts/include/internal/win/ethr_dw_atomic.h
index a3e7ffc3aa..8bed4fb26e 100644
--- a/erts/include/internal/win/ethr_dw_atomic.h
+++ b/erts/include/internal/win/ethr_dw_atomic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/win/ethr_event.h b/erts/include/internal/win/ethr_event.h
index 6363174a74..458565b9ea 100644
--- a/erts/include/internal/win/ethr_event.h
+++ b/erts/include/internal/win/ethr_event.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -55,9 +56,12 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
#endif
int ethr_event_init(ethr_event *e);
+int ethr_event_prepare_timed(ethr_event *e);
int ethr_event_destroy(ethr_event *e);
int ethr_event_wait(ethr_event *e);
int ethr_event_swait(ethr_event *e, int spincount);
+int ethr_event_twait(ethr_event *e, ethr_sint64_t timeout);
+int ethr_event_stwait(ethr_event *e, int spincount, ethr_sint64_t timeout);
#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
void ethr_event_set(ethr_event *e);
void ethr_event_reset(ethr_event *e);
diff --git a/erts/include/internal/win/ethr_membar.h b/erts/include/internal/win/ethr_membar.h
index a17f2459fc..9cba6b605d 100644
--- a/erts/include/internal/win/ethr_membar.h
+++ b/erts/include/internal/win/ethr_membar.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/win/ethread.h b/erts/include/internal/win/ethread.h
index 8be35e810e..2fda028825 100644
--- a/erts/include/internal/win/ethread.h
+++ b/erts/include/internal/win/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/include/internal/x86_64/ethread.h b/erts/include/internal/x86_64/ethread.h
index 59c3980535..8887b8d77f 100644
--- a/erts/include/internal/x86_64/ethread.h
+++ b/erts/include/internal/x86_64/ethread.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/lib/internal/README b/erts/lib/internal/README
index f5b7ac27ab..9beba10bc2 100644
--- a/erts/lib/internal/README
+++ b/erts/lib/internal/README
@@ -3,16 +3,17 @@
Copyright Ericsson AB 2004-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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%
diff --git a/erts/lib_src/Makefile b/erts/lib_src/Makefile
index f94e47a856..632b8a0b09 100644
--- a/erts/lib_src/Makefile
+++ b/erts/lib_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index b680c03b1d..74e32ccdce 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -92,6 +93,11 @@ CFLAGS += -DERTS_FRMPTR
OMIT_OMIT_FP=yes
PRE_LD=
else
+ifeq ($(TYPE),icount)
+TYPE_SUFFIX = .icount
+CFLAGS += -DERTS_OPCODE_COUNTER_SUPPORT
+PRE_LD=
+else
override TYPE=opt
OMIT_FP=true
TYPE_SUFFIX=
@@ -105,6 +111,7 @@ endif
endif
endif
endif
+endif
OPSYS=@OPSYS@
sol2CFLAGS=
diff --git a/erts/lib_src/common/erl_memory_trace_parser.c b/erts/lib_src/common/erl_memory_trace_parser.c
index 625c140cf9..a81068089e 100644
--- a/erts/lib_src/common/erl_memory_trace_parser.c
+++ b/erts/lib_src/common/erl_memory_trace_parser.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c
index 7833dd8219..1262c50718 100644
--- a/erts/lib_src/common/erl_misc_utils.c
+++ b/erts/lib_src/common/erl_misc_utils.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/common/erl_printf.c b/erts/lib_src/common/erl_printf.c
index 2c177ee5ac..387a104a7a 100644
--- a/erts/lib_src/common/erl_printf.c
+++ b/erts/lib_src/common/erl_printf.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -87,6 +88,41 @@ void (*erts_printf_unblock_fpe)(int) = NULL;
# define FWRITE fwrite
#endif
+/* We use write for stdout and stderr as they could be
+ set to non-blocking by shell drivers, and non-blocking
+ FILE * functions work unpredictably as best */
+static int
+printf_putc(int c, FILE *stream) {
+ if ((FILE*)stream == stdout || (FILE*)stream == stderr) {
+ int fd = stream == stdout ? fileno(stdout) : fileno(stderr);
+ /* cast to a char here, because write expects bytes. */
+ unsigned char buf[1] = { c };
+ int res;
+ do {
+ res = write(fd, buf, 1);
+ } while (res == -1 && (errno == EAGAIN || errno == EINTR));
+ if (res == -1) return EOF;
+ return res;
+ }
+
+ return PUTC(c, stream);
+}
+
+static size_t
+printf_fwrite(const void *ptr, size_t size, size_t nitems,
+ FILE *stream) {
+ if ((FILE*)stream == stdout || (FILE*)stream == stderr) {
+ int fd = stream == stdout ? fileno(stdout) : fileno(stderr);
+ int res;
+ do {
+ res = write(fd, ptr, size*nitems);
+ } while (res == -1 && (errno == EAGAIN || errno == EINTR));
+ if (res == -1) return 0;
+ return res;
+ }
+ return FWRITE(ptr, size, nitems, stream);
+}
+
static int
get_error_result(void)
{
@@ -103,10 +139,10 @@ write_f_add_cr(void *vfp, char* buf, size_t len)
size_t i;
ASSERT(vfp);
for (i = 0; i < len; i++) {
- if (buf[i] == '\n' && PUTC('\r', (FILE *) vfp) == EOF)
- return get_error_result();
- if (PUTC(buf[i], (FILE *) vfp) == EOF)
- return get_error_result();
+ if (buf[i] == '\n' && printf_putc('\r', (FILE *) vfp) == EOF)
+ return get_error_result();
+ if (printf_putc(buf[i], (FILE *) vfp) == EOF)
+ return get_error_result();
}
return len;
}
@@ -119,12 +155,12 @@ write_f(void *vfp, char* buf, size_t len)
if (len <= 64) { /* Try to optimize writes of small bufs. */
int i;
for (i = 0; i < len; i++)
- if (PUTC(buf[i], (FILE *) vfp) == EOF)
+ if (printf_putc(buf[i], (FILE *) vfp) == EOF)
return get_error_result();
}
else
#endif
- if (FWRITE((void *) buf, sizeof(char), len, (FILE *) vfp) != len)
+ if (printf_fwrite((void *) buf, sizeof(char), len, (FILE *) vfp) != len)
return get_error_result();
return len;
}
diff --git a/erts/lib_src/common/erl_printf_format.c b/erts/lib_src/common/erl_printf_format.c
index d6ae76f14c..307680505c 100644
--- a/erts/lib_src/common/erl_printf_format.c
+++ b/erts/lib_src/common/erl_printf_format.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/lib_src/common/ethr_atomics.c b/erts/lib_src/common/ethr_atomics.c
index c52166a7ec..42c078377d 100644
--- a/erts/lib_src/common/ethr_atomics.c
+++ b/erts/lib_src/common/ethr_atomics.c
@@ -12,16 +12,17 @@
*
* Copyright Ericsson AB 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/common/ethr_aux.c b/erts/lib_src/common/ethr_aux.c
index b77f2178f2..0cbb1b2fb8 100644
--- a/erts/lib_src/common/ethr_aux.c
+++ b/erts/lib_src/common/ethr_aux.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -40,8 +41,8 @@
#include <unistd.h>
#endif
-#define ERTS_TS_EV_ALLOC_DEFAULT_POOL_SIZE 4000
-#define ERTS_TS_EV_ALLOC_POOL_SIZE 25
+#define ERTS_TS_EV_ALLOC_DEFAULT_POOL_SIZE 2048
+#define ERTS_TS_EV_ALLOC_POOL_SIZE 32
erts_cpu_info_t *ethr_cpu_info__;
@@ -148,6 +149,8 @@ ethr_init_common__(ethr_init_data *id)
{
int res;
+ ethr_init_event__();
+
#if defined(ETHR_X86_RUNTIME_CONF__)
x86_init();
#endif
diff --git a/erts/lib_src/common/ethr_cbf.c b/erts/lib_src/common/ethr_cbf.c
index 04feceec89..e79ec2b40c 100644
--- a/erts/lib_src/common/ethr_cbf.c
+++ b/erts/lib_src/common/ethr_cbf.c
@@ -3,16 +3,17 @@
*
* 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/common/ethr_mutex.c b/erts/lib_src/common/ethr_mutex.c
index 4e56efaf8b..72aa34ec1c 100644
--- a/erts/lib_src/common/ethr_mutex.c
+++ b/erts/lib_src/common/ethr_mutex.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/ose/ethr_event.c b/erts/lib_src/ose/ethr_event.c
index 87294c98ea..24ea191c4b 100644
--- a/erts/lib_src/ose/ethr_event.c
+++ b/erts/lib_src/ose/ethr_event.c
@@ -3,16 +3,17 @@
*
* 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/ose/ethread.c b/erts/lib_src/ose/ethread.c
index 53628382b1..dc16acdd08 100644
--- a/erts/lib_src/ose/ethread.c
+++ b/erts/lib_src/ose/ethread.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/pthread/ethr_event.c b/erts/lib_src/pthread/ethr_event.c
index 9434d60d0a..69e7be342c 100644
--- a/erts/lib_src/pthread/ethr_event.c
+++ b/erts/lib_src/pthread/ethr_event.c
@@ -3,16 +3,17 @@
*
* 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -28,7 +29,17 @@
#include "config.h"
#endif
+#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+# define __DARWIN__ 1
+#endif
+#ifdef __DARWIN__
+# define _DARWIN_UNLIMITED_SELECT
+#endif
+
#include "ethread.h"
+#undef ETHR_INCLUDE_MONOTONIC_CLOCK__
+#define ETHR_INCLUDE_MONOTONIC_CLOCK__
+#include "ethr_internal.h"
#if defined(ETHR_LINUX_FUTEX_IMPL__)
/* --- Linux futex implementation of ethread events ------------------------- */
@@ -38,6 +49,12 @@
#define ETHR_YIELD_AFTER_BUSY_LOOPS 50
+void
+ethr_init_event__(void)
+{
+
+}
+
int
ethr_event_init(ethr_event *e)
{
@@ -46,27 +63,55 @@ ethr_event_init(ethr_event *e)
}
int
+ethr_event_prepare_timed(ethr_event *e)
+{
+ return 0;
+}
+
+int
ethr_event_destroy(ethr_event *e)
{
return 0;
}
static ETHR_INLINE int
-wait__(ethr_event *e, int spincount)
+wait__(ethr_event *e, int spincount, ethr_sint64_t timeout)
{
unsigned sc = spincount;
int res;
ethr_sint32_t val;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
+ ethr_sint64_t time = 0; /* SHUT UP annoying faulty warning... */
+ struct timespec ts, *tsp;
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ ethr_sint64_t start = 0; /* SHUT UP annoying faulty warning... */
+#endif
if (spincount < 0)
ETHR_FATAL_ERROR__(EINVAL);
+ if (timeout < 0) {
+ tsp = NULL;
+ }
+ else {
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ start = ethr_get_monotonic_time();
+#endif
+ tsp = &ts;
+ time = timeout;
+ if (spincount == 0) {
+ val = ethr_atomic32_read(&e->futex);
+ if (val == ETHR_EVENT_ON__)
+ goto return_event_on;
+ goto set_timeout;
+ }
+ }
+
while (1) {
while (1) {
val = ethr_atomic32_read(&e->futex);
if (val == ETHR_EVENT_ON__)
- return 0;
+ goto return_event_on;
if (sc == 0)
break;
sc--;
@@ -79,44 +124,200 @@ wait__(ethr_event *e, int spincount)
}
}
+ if (timeout >= 0) {
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ time = timeout - (ethr_get_monotonic_time() - start);
+#endif
+ set_timeout:
+ if (time <= 0) {
+ val = ethr_atomic32_read(&e->futex);
+ if (val == ETHR_EVENT_ON__)
+ goto return_event_on;
+ return ETIMEDOUT;
+ }
+ ts.tv_sec = time / (1000*1000*1000);
+ ts.tv_nsec = time % (1000*1000*1000);
+ }
+
if (val != ETHR_EVENT_OFF_WAITER__) {
val = ethr_atomic32_cmpxchg(&e->futex,
ETHR_EVENT_OFF_WAITER__,
ETHR_EVENT_OFF__);
if (val == ETHR_EVENT_ON__)
- return 0;
+ goto return_event_on;
ETHR_ASSERT(val == ETHR_EVENT_OFF__);
}
res = ETHR_FUTEX__(&e->futex,
ETHR_FUTEX_WAIT__,
- ETHR_EVENT_OFF_WAITER__);
- if (res == EINTR)
+ ETHR_EVENT_OFF_WAITER__,
+ tsp);
+ switch (res) {
+ case EINTR:
+ case ETIMEDOUT:
+ return res;
+ case 0:
+ case EWOULDBLOCK:
break;
- if (res != 0 && res != EWOULDBLOCK)
+ default:
ETHR_FATAL_ERROR__(res);
+ }
}
- return res;
+return_event_on:
+
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
+
+ return 0;
+
}
#elif defined(ETHR_PTHREADS)
-/* --- Posix mutex/cond implementation of events ---------------------------- */
+/* --- Posix mutex/cond pipe/select implementation of events ---------------- */
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef __DARWIN__
+
+struct ethr_event_fdsets___ {
+ fd_set *rsetp;
+ fd_set *esetp;
+ size_t mem_size;
+ fd_mask mem[1];
+};
+
+#endif
+
+static void
+setup_nonblocking_pipe(ethr_event *e)
+{
+ int flgs;
+ int res;
+
+ res = pipe(e->fd);
+ if (res != 0)
+ ETHR_FATAL_ERROR__(errno);
+
+ ETHR_ASSERT(e->fd[0] >= 0 && e->fd[1] >= 0);
+
+ flgs = fcntl(e->fd[0], F_GETFL, 0);
+ fcntl(e->fd[0], F_SETFL, flgs | O_NONBLOCK);
+ flgs = fcntl(e->fd[1], F_GETFL, 0);
+ fcntl(e->fd[1], F_SETFL, flgs | O_NONBLOCK);
+
+
+#ifndef __DARWIN__
+ if (e->fd[0] >= FD_SETSIZE)
+ ETHR_FATAL_ERROR__(ENOTSUP);
+#else
+ {
+ int nmasks;
+ ethr_event_fdsets__ *fdsets;
+ size_t mem_size;
+
+ nmasks = (e->fd[0]+NFDBITS)/NFDBITS;
+ mem_size = 2*nmasks*sizeof(fd_mask);
+ if (mem_size < 2*sizeof(fd_set)) {
+ mem_size = 2*sizeof(fd_set);
+ nmasks = mem_size/(2*sizeof(fd_mask));
+ }
+
+ fdsets = malloc(sizeof(ethr_event_fdsets__)
+ + mem_size
+ - sizeof(fd_mask));
+ if (!fdsets)
+ ETHR_FATAL_ERROR__(ENOMEM);
+ fdsets->rsetp = (fd_set *) (char *) &fdsets->mem[0];
+ fdsets->esetp = (fd_set *) (char *) &fdsets->mem[nmasks];
+ fdsets->mem_size = mem_size;
+ e->fdsets = fdsets;
+ }
+#endif
+
+ ETHR_MEMBAR(ETHR_StoreStore);
+}
+
+#define ETHR_EVENT_INVALID_FD__ -1
+#define ETHR_EVENT_COND_TIMEDWAIT__ -2
+
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+static pthread_condattr_t monotonic_clock_cond_attr;
+#endif
+static pthread_condattr_t *monotonic_clock_cond_attr_p;
+
+#ifndef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+# undef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+#endif
+#ifndef ETHR_MONOTONIC_CLOCK_ID
+# undef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+#endif
+
+void
+ethr_init_event__(void)
+{
+ monotonic_clock_cond_attr_p = NULL;
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+ if (!ethr_get_monotonic_time_is_broken()
+ && pthread_condattr_init(&monotonic_clock_cond_attr) == 0) {
+ if (pthread_condattr_setclock(&monotonic_clock_cond_attr,
+ ETHR_MONOTONIC_CLOCK_ID) == 0)
+ monotonic_clock_cond_attr_p = &monotonic_clock_cond_attr;
+ else
+ pthread_condattr_destroy(&monotonic_clock_cond_attr);
+ }
+#endif
+}
int
ethr_event_init(ethr_event *e)
{
int res;
+
ethr_atomic32_init(&e->state, ETHR_EVENT_OFF__);
+
res = pthread_mutex_init(&e->mtx, NULL);
if (res != 0)
return res;
- res = pthread_cond_init(&e->cnd, NULL);
+
+ res = pthread_cond_init(&e->cnd, monotonic_clock_cond_attr_p);
if (res != 0) {
pthread_mutex_destroy(&e->mtx);
return res;
}
+
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+ /*
+ * If ethr_get_monotonic_time() is broken we
+ * fall back on the pipe/select solution...
+ */
+ if (monotonic_clock_cond_attr_p) {
+ e->fd[0] = e->fd[1] = ETHR_EVENT_COND_TIMEDWAIT__;
+ return 0;
+ }
+#endif
+
+ e->fd[0] = e->fd[1] = ETHR_EVENT_INVALID_FD__;
+
+#ifdef __DARWIN__
+ e->fdsets = NULL;
+#endif
+
+ return 0;
+}
+
+int
+ethr_event_prepare_timed(ethr_event *e)
+{
+ if (e->fd[0] == ETHR_EVENT_INVALID_FD__)
+ setup_nonblocking_pipe(e);
+
return 0;
}
@@ -124,22 +325,73 @@ int
ethr_event_destroy(ethr_event *e)
{
int res;
+ if (e->fd[0] >= 0) {
+ close(e->fd[0]);
+ close(e->fd[1]);
+ }
+#ifdef __DARWIN__
+ if (e->fdsets)
+ free(e->fdsets);
+#endif
res = pthread_mutex_destroy(&e->mtx);
if (res != 0)
return res;
- res = pthread_cond_destroy(&e->cnd);
- if (res != 0)
- return res;
- return 0;
+ return pthread_cond_destroy(&e->cnd);
}
static ETHR_INLINE int
-wait__(ethr_event *e, int spincount)
+wait__(ethr_event *e, int spincount, ethr_sint64_t timeout)
{
int sc = spincount;
ethr_sint32_t val;
int res, ulres;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
+ ethr_sint64_t time = 0; /* SHUT UP annoying faulty warning... */
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ ethr_sint64_t start = 0; /* SHUT UP annoying faulty warning... */
+#endif
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+ struct timespec cond_timeout;
+#endif
+
+ val = ethr_atomic32_read(&e->state);
+ if (val == ETHR_EVENT_ON__)
+ goto return_event_on;
+
+ if (timeout < 0) {
+ if (spincount == 0)
+ goto set_event_off_waiter;
+ }
+ if (timeout == 0)
+ return ETIMEDOUT;
+ else {
+ time = timeout;
+ switch (e->fd[0]) {
+ case ETHR_EVENT_INVALID_FD__:
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ start = ethr_get_monotonic_time();
+#endif
+ setup_nonblocking_pipe(e);
+ break;
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+ case ETHR_EVENT_COND_TIMEDWAIT__:
+ time += ethr_get_monotonic_time();
+ cond_timeout.tv_sec = time / (1000*1000*1000);
+ cond_timeout.tv_nsec = time % (1000*1000*1000);
+ if (spincount == 0)
+ goto set_event_off_waiter;
+ break;
+#endif
+ default:
+ /* Already initialized pipe... */
+ if (spincount == 0)
+ goto set_select_timeout;
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ start = ethr_get_monotonic_time();
+#endif
+ break;
+ }
+ }
if (spincount < 0)
ETHR_FATAL_ERROR__(EINVAL);
@@ -147,7 +399,8 @@ wait__(ethr_event *e, int spincount)
while (1) {
val = ethr_atomic32_read(&e->state);
if (val == ETHR_EVENT_ON__)
- return 0;
+ goto return_event_on;
+
if (sc == 0)
break;
sc--;
@@ -160,40 +413,162 @@ wait__(ethr_event *e, int spincount)
}
}
- if (val != ETHR_EVENT_OFF_WAITER__) {
- val = ethr_atomic32_cmpxchg(&e->state,
- ETHR_EVENT_OFF_WAITER__,
- ETHR_EVENT_OFF__);
- if (val == ETHR_EVENT_ON__)
- return 0;
- ETHR_ASSERT(val == ETHR_EVENT_OFF__);
+ if (timeout < 0
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+ || e->fd[0] == ETHR_EVENT_COND_TIMEDWAIT__
+#endif
+ ) {
+
+ set_event_off_waiter:
+
+ if (val != ETHR_EVENT_OFF_WAITER__) {
+ ethr_sint32_t act;
+ act = ethr_atomic32_cmpxchg(&e->state,
+ ETHR_EVENT_OFF_WAITER__,
+ val);
+ if (act == ETHR_EVENT_ON__)
+ goto return_event_on;
+ ETHR_ASSERT(act == val);
+ }
+
+ res = pthread_mutex_lock(&e->mtx);
+ if (res != 0)
+ ETHR_FATAL_ERROR__(res);
+
+ while (1) {
+
+ val = ethr_atomic32_read(&e->state);
+ if (val == ETHR_EVENT_ON__) {
+ ETHR_ASSERT(res == 0);
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
+ break;
+ }
+
+#ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
+ if (timeout > 0) {
+ res = pthread_cond_timedwait(&e->cnd, &e->mtx, &cond_timeout);
+ if (res == EINTR || res == ETIMEDOUT)
+ break;
+ }
+ else
+#endif
+ {
+ res = pthread_cond_wait(&e->cnd, &e->mtx);
+ if (res == EINTR)
+ break;
+ }
+ if (res != 0)
+ ETHR_FATAL_ERROR__(res);
+ }
+
+ ulres = pthread_mutex_unlock(&e->mtx);
+ if (ulres != 0)
+ ETHR_FATAL_ERROR__(ulres);
+
}
+ else {
+ int fd;
+ int sres;
+ ssize_t rres;
+#ifndef __DARWIN__
+ fd_set rset, eset;
+#endif
+ fd_set *rsetp, *esetp;
+ struct timeval select_timeout;
- ETHR_ASSERT(val == ETHR_EVENT_OFF_WAITER__
- || val == ETHR_EVENT_OFF__);
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ time -= ethr_get_monotonic_time() - start;
+ if (time <= 0)
+ return ETIMEDOUT;
+#endif
- res = pthread_mutex_lock(&e->mtx);
- if (res != 0)
- ETHR_FATAL_ERROR__(res);
+ set_select_timeout:
- while (1) {
+ ETHR_ASSERT(time > 0);
+
+ /*
+ * timeout in nano-second, but we can only wait
+ * for micro-seconds...
+ */
+ time = ((time - 1) / 1000) + 1;
+
+ select_timeout.tv_sec = time / (1000*1000);
+ select_timeout.tv_usec = time % (1000*1000);
+
+ ETHR_ASSERT(val != ETHR_EVENT_ON__);
+
+ fd = e->fd[0];
+
+ /* Cleanup pipe... */
+ do {
+ char buf[64];
+ rres = read(fd, buf, sizeof(buf));
+ } while (rres > 0 || (rres < 0 && errno == EINTR));
+ if (rres < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
+ ETHR_FATAL_ERROR__(errno);
+
+ /*
+ * Need to verify that state is still off
+ * after cleaning the pipe...
+ */
+ if (val == ETHR_EVENT_OFF_WAITER_SELECT__) {
+ val = ethr_atomic32_read(&e->state);
+ if (val == ETHR_EVENT_ON__)
+ goto return_event_on;
+ }
+ else {
+ ethr_sint32_t act;
+ act = ethr_atomic32_cmpxchg(&e->state,
+ ETHR_EVENT_OFF_WAITER_SELECT__,
+ val);
+ if (act == ETHR_EVENT_ON__)
+ goto return_event_on;
+ ETHR_ASSERT(act == val);
+ }
+
+
+#ifdef __DARWIN__
+ rsetp = e->fdsets->rsetp;
+ esetp = e->fdsets->esetp;
+ memset((void *) &e->fdsets->mem[0], 0, e->fdsets->mem_size);
+#else
+ FD_ZERO(&rset);
+ FD_ZERO(&eset);
+ rsetp = &rset;
+ esetp = &eset;
+#endif
+
+ FD_SET(fd, rsetp);
+ FD_SET(fd, esetp);
+
+ sres = select(fd + 1, rsetp, NULL, esetp, &select_timeout);
+ if (sres == 0)
+ res = ETIMEDOUT;
+ else {
+ res = EINTR;
+ if (sres < 0 && errno != EINTR)
+ ETHR_FATAL_ERROR__(errno);
+ /* else:
+ * Event is *probably* set, but it can be a
+ * lingering writer. That is, it is important
+ * that we verify that it actually is set. If
+ * it isn't, return EINTR (spurious wakeup).
+ */
+ }
val = ethr_atomic32_read(&e->state);
if (val == ETHR_EVENT_ON__)
- break;
+ goto return_event_on;
- res = pthread_cond_wait(&e->cnd, &e->mtx);
- if (res == EINTR)
- break;
- if (res != 0)
- ETHR_FATAL_ERROR__(res);
}
- ulres = pthread_mutex_unlock(&e->mtx);
- if (ulres != 0)
- ETHR_FATAL_ERROR__(ulres);
+ return res;
+
+return_event_on:
+
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
- return res; /* 0 || EINTR */
+ return 0;
}
#else
@@ -215,11 +590,23 @@ ethr_event_set(ethr_event *e)
int
ethr_event_wait(ethr_event *e)
{
- return wait__(e, 0);
+ return wait__(e, 0, -1);
}
int
ethr_event_swait(ethr_event *e, int spincount)
{
- return wait__(e, spincount);
+ return wait__(e, spincount, -1);
+}
+
+int
+ethr_event_twait(ethr_event *e, ethr_sint64_t timeout)
+{
+ return wait__(e, 0, timeout);
+}
+
+int
+ethr_event_stwait(ethr_event *e, int spincount, ethr_sint64_t timeout)
+{
+ return wait__(e, spincount, timeout);
}
diff --git a/erts/lib_src/pthread/ethr_x86_sse2_asm.c b/erts/lib_src/pthread/ethr_x86_sse2_asm.c
index 6cbe73cf16..7ce5a6d98a 100644
--- a/erts/lib_src/pthread/ethr_x86_sse2_asm.c
+++ b/erts/lib_src/pthread/ethr_x86_sse2_asm.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/pthread/ethread.c b/erts/lib_src/pthread/ethread.c
index 79784c5b84..ef11559654 100644
--- a/erts/lib_src/pthread/ethread.c
+++ b/erts/lib_src/pthread/ethread.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -42,6 +43,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
+#include <string.h>
#include <limits.h>
@@ -49,6 +51,8 @@
#define ETHREAD_IMPL__
#include "ethread.h"
+#undef ETHR_INCLUDE_MONOTONIC_CLOCK__
+#define ETHR_INCLUDE_MONOTONIC_CLOCK__
#include "ethr_internal.h"
#ifndef ETHR_HAVE_ETHREAD_DEFINES
@@ -77,6 +81,8 @@ typedef struct {
void *(*thr_func)(void *);
void *arg;
void *prep_func_res;
+ char *name;
+ char name_buff[16];
} ethr_thr_wrap_data__;
static void *thr_wrapper(void *vtwd)
@@ -98,6 +104,8 @@ static void *thr_wrapper(void *vtwd)
tsep = twd->tse; /* We aren't allowed to follow twd after
result has been set! */
+ if (twd->name)
+ ethr_setname(twd->name);
ethr_atomic32_set(&twd->result, result);
@@ -232,6 +240,10 @@ ethr_x86_cpuid__(int *eax, int *ebx, int *ecx, int *edx)
#endif /* ETHR_X86_RUNTIME_CONF__ */
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+static void init_get_monotonic_time(void);
+#endif
+
/*
* --------------------------------------------------------------------------
* Exported functions
@@ -254,6 +266,10 @@ ethr_init(ethr_init_data *id)
goto error;
#endif
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+ init_get_monotonic_time();
+#endif
+
res = ethr_init_common__(id);
if (res != 0)
goto error;
@@ -315,6 +331,12 @@ ethr_thr_create(ethr_tid *tid, void * (*func)(void *), void *arg,
twd.thr_func = func;
twd.arg = arg;
+ if (opts && opts->name) {
+ snprintf(twd.name_buff, 16, "%s", opts->name);
+ twd.name = twd.name_buff;
+ } else
+ twd.name = NULL;
+
res = pthread_attr_init(&attr);
if (res != 0)
return res;
@@ -445,6 +467,30 @@ ethr_self(void)
}
int
+ethr_getname(ethr_tid tid, char *buf, size_t len)
+{
+#if defined(ETHR_HAVE_PTHREAD_GETNAME_NP_3)
+ return pthread_getname_np((pthread_t) tid, buf, len);
+#elif defined(ETHR_HAVE_PTHREAD_GETNAME_NP_2)
+ return pthread_getname_np((pthread_t) tid, buf);
+#else
+ return ENOSYS;
+#endif
+}
+
+void
+ethr_setname(char *name)
+{
+#if defined(ETHR_HAVE_PTHREAD_SETNAME_NP_2)
+ pthread_setname_np(ethr_self(), name);
+#elif defined(ETHR_HAVE_PTHREAD_SET_NAME_NP_2)
+ pthread_set_name_np(ethr_self(), name);
+#elif defined(ETHR_HAVE_PTHREAD_SETNAME_NP_1)
+ pthread_setname_np(name);
+#endif
+}
+
+int
ethr_equal_tids(ethr_tid tid1, ethr_tid tid2)
{
return pthread_equal((pthread_t) tid1, (pthread_t) tid2);
@@ -565,8 +611,157 @@ int ethr_sigwait(const sigset_t *set, int *sig)
return 0;
}
+int ethr_kill(const ethr_tid tid, const int sig)
+{
+#if ETHR_XCHK
+ if (ethr_not_inited__) {
+ ETHR_ASSERT(0);
+ return EACCES;
+ }
+#endif
+ return pthread_kill((const pthread_t)tid, sig);
+}
+
#endif /* #if ETHR_HAVE_ETHR_SIG_FUNCS */
+#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+
+static int broken_get_monotonic_time;
+
+#if defined(ETHR_HAVE_CLOCK_GETTIME_MONOTONIC)
+# ifndef ETHR_MONOTONIC_CLOCK_ID
+# error ETHR_MONOTONIC_CLOCK_ID should have been defined
+# endif
+
+ethr_sint64_t
+ethr_get_monotonic_time(void)
+{
+ ethr_sint64_t time;
+ struct timespec ts;
+
+ if (broken_get_monotonic_time)
+ return (ethr_sint64_t) 0;
+
+ if (0 != clock_gettime(ETHR_MONOTONIC_CLOCK_ID, &ts))
+ ETHR_FATAL_ERROR__(errno);
+
+ time = (ethr_sint64_t) ts.tv_sec;
+ time *= (ethr_sint64_t) 1000*1000*1000;
+ time += (ethr_sint64_t) ts.tv_nsec;
+ return time;
+}
+
+#elif defined(ETHR_HAVE_MACH_CLOCK_GET_TIME)
+# ifndef ETHR_MONOTONIC_CLOCK_ID
+# error ETHR_MONOTONIC_CLOCK_ID should have been defined
+# endif
+
+ethr_sint64_t
+ethr_get_monotonic_time(void)
+{
+ ethr_sint64_t time;
+ kern_return_t res;
+ clock_serv_t clk_srv;
+ mach_timespec_t time_spec;
+
+ if (broken_get_monotonic_time)
+ return (ethr_sint64_t) 0;
+
+ errno = EFAULT;
+ host_get_clock_service(mach_host_self(),
+ ETHR_MONOTONIC_CLOCK_ID,
+ &clk_srv);
+ res = clock_get_time(clk_srv, &time_spec);
+ if (res != KERN_SUCCESS)
+ ETHR_FATAL_ERROR__(errno);
+ mach_port_deallocate(mach_task_self(), clk_srv);
+
+ time = (ethr_sint64_t) time_spec.tv_sec;
+ time *= (ethr_sint64_t) 1000*1000*1000;
+ time += (ethr_sint64_t) time_spec.tv_nsec;
+ return time;
+}
+
+#elif defined(ETHR_HAVE_GETHRTIME)
+
+ethr_sint64_t
+ethr_get_monotonic_time(void)
+{
+ if (broken_get_monotonic_time)
+ return (ethr_sint64_t) 0;
+ return (ethr_sint64_t) gethrtime();
+}
+
+#else
+#error missing monotonic clock
+#endif
+
+int
+ethr_get_monotonic_time_is_broken(void)
+{
+ return broken_get_monotonic_time;
+}
+
+#include <string.h>
+#include <ctype.h>
+#include <sys/utsname.h>
+
+static void
+init_get_monotonic_time(void)
+{
+ struct utsname uts;
+ int vsn[3];
+ int i;
+ char *c;
+
+ broken_get_monotonic_time = 0;
+
+ (void) uname(&uts);
+
+ for (c = uts.sysname; *c; c++) {
+ if (isupper((int) *c))
+ *c = tolower((int) *c);
+ }
+
+ c = uts.release;
+ for (i = 0; i < sizeof(vsn)/sizeof(int); i++) {
+ if (!isdigit((int) *c))
+ vsn[i] = 0;
+ else {
+ char *c2 = c;
+ do {
+ c2++;
+ } while (isdigit((int) *c2));
+ *c2 = '\0';
+ vsn[i] = atoi(c);
+ c = c2;
+ c++;
+ }
+ }
+
+ if (strcmp("linux", uts.sysname) == 0) {
+ if (vsn[0] < 2
+ || (vsn[0] == 2 && vsn[1] < 6)
+ || (vsn[0] == 2 && vsn[1] == 6 && vsn[2] < 33)) {
+ broken_get_monotonic_time = 1;
+ }
+ }
+ else if (strcmp("sunos", uts.sysname) == 0) {
+ if ((vsn[0] < 5
+ || (vsn[0] == 5 && vsn[1] < 8))
+#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
+ && sysconf(_SC_NPROCESSORS_CONF) > 1
+#endif
+ ) {
+ broken_get_monotonic_time = 1;
+ }
+ }
+
+}
+
+
+#endif /* ETHR_HAVE_ETHR_GET_MONOTONIC_TIME */
+
ETHR_IMPL_NORETURN__
ethr_abort__(void)
{
diff --git a/erts/lib_src/utils/make_atomics_api b/erts/lib_src/utils/make_atomics_api
index 74736c5a2d..4b37e3fa74 100755
--- a/erts/lib_src/utils/make_atomics_api
+++ b/erts/lib_src/utils/make_atomics_api
@@ -6,16 +6,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1419,16 +1420,17 @@ comments() ->
*
* Copyright Ericsson AB ", Years, ". All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the \"License\"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.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
*
- * Software distributed under the License is distributed on an \"AS IS\"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/lib_src/win/ethr_event.c b/erts/lib_src/win/ethr_event.c
index bc2f635c26..6951a216c5 100644
--- a/erts/lib_src/win/ethr_event.c
+++ b/erts/lib_src/win/ethr_event.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -25,9 +26,16 @@
#define ETHR_EVENT_IMPL__
#include "ethread.h"
+#include "ethr_internal.h"
/* --- Windows implementation of thread events ------------------------------ */
+void
+ethr_init_event__(void)
+{
+
+}
+
int
ethr_event_init(ethr_event *e)
{
@@ -39,6 +47,12 @@ ethr_event_init(ethr_event *e)
}
int
+ethr_event_prepare_timed(ethr_event *e)
+{
+ return 0;
+}
+
+int
ethr_event_destroy(ethr_event *e)
{
BOOL res = CloseHandle(e->handle);
@@ -58,11 +72,29 @@ ethr_event_reset(ethr_event *e)
}
static ETHR_INLINE int
-wait(ethr_event *e, int spincount)
+wait(ethr_event *e, int spincount, ethr_sint64_t timeout)
{
- DWORD code;
+ DWORD code, tmo;
int sc, res, until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
+ if (timeout < 0)
+ tmo = INFINITE;
+ else if (timeout == 0) {
+ ethr_sint32_t state = ethr_atomic32_read(&e->state);
+ if (state == ETHR_EVENT_ON__) {
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
+ return 0;
+ }
+ return ETIMEDOUT;
+ }
+ else {
+ /*
+ * Timeout in nano-seconds, but we can only
+ * wait for milli-seconds...
+ */
+ tmo = (DWORD) (timeout - 1) / (1000*1000) + 1;
+ }
+
if (spincount < 0)
ETHR_FATAL_ERROR__(EINVAL);
@@ -72,8 +104,10 @@ wait(ethr_event *e, int spincount)
ethr_sint32_t state;
while (1) {
state = ethr_atomic32_read(&e->state);
- if (state == ETHR_EVENT_ON__)
+ if (state == ETHR_EVENT_ON__) {
+ ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore);
return 0;
+ }
if (sc == 0)
break;
sc--;
@@ -95,7 +129,9 @@ wait(ethr_event *e, int spincount)
ETHR_ASSERT(state == ETHR_EVENT_OFF__);
}
- code = WaitForSingleObject(e->handle, INFINITE);
+ code = WaitForSingleObject(e->handle, tmo);
+ if (code == WAIT_TIMEOUT)
+ return ETIMEDOUT;
if (code != WAIT_OBJECT_0)
ETHR_FATAL_ERROR__(ethr_win_get_errno__());
}
@@ -105,11 +141,23 @@ wait(ethr_event *e, int spincount)
int
ethr_event_wait(ethr_event *e)
{
- return wait(e, 0);
+ return wait(e, 0, -1);
}
int
ethr_event_swait(ethr_event *e, int spincount)
{
- return wait(e, spincount);
+ return wait(e, spincount, -1);
+}
+
+int
+ethr_event_twait(ethr_event *e, ethr_sint64_t timeout)
+{
+ return wait(e, 0, timeout);
+}
+
+int
+ethr_event_stwait(ethr_event *e, int spincount, ethr_sint64_t timeout)
+{
+ return wait(e, spincount, timeout);
}
diff --git a/erts/lib_src/win/ethread.c b/erts/lib_src/win/ethread.c
index 14d0b6deff..22b0b4040c 100644
--- a/erts/lib_src/win/ethread.c
+++ b/erts/lib_src/win/ethread.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -508,6 +509,19 @@ ethr_self(void)
return *tid;
}
+/* getname and setname are not available on windows */
+int
+ethr_getname(ethr_tid tid, char *buf, size_t len)
+{
+ return ENOSYS;
+}
+
+void
+ethr_setname(char *name)
+{
+ return;
+}
+
int
ethr_equal_tids(ethr_tid tid1, ethr_tid tid2)
{
diff --git a/erts/preloaded/Makefile b/erts/preloaded/Makefile
index 31fdeb96c5..fbe62d57bb 100644
--- a/erts/preloaded/Makefile
+++ b/erts/preloaded/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 10138cab22..f1ae49150b 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 7a3d94dd16..990973c57d 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 9b364d8b21..7461e3bc5b 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index a190129b2c..0060a2cf42 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 621f036f33..b1868d7e10 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam
index 6695f4cd15..dc16909d26 100644
--- a/erts/preloaded/ebin/prim_eval.beam
+++ b/erts/preloaded/ebin/prim_eval.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 5e9230826d..f6e15ba499 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 83230d42ae..673627498e 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index b3abba3223..813060c41d 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 7006764d96..5ce932aeec 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/Makefile b/erts/preloaded/src/Makefile
index 4ea2d41075..52034a0881 100644
--- a/erts/preloaded/src/Makefile
+++ b/erts/preloaded/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/preloaded/src/add_abstract_code b/erts/preloaded/src/add_abstract_code
index 211a60c930..4f479db2e8 100644
--- a/erts/preloaded/src/add_abstract_code
+++ b/erts/preloaded/src/add_abstract_code
@@ -6,16 +6,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index 6b86a427ba..9f6cba33bd 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 611a568014..063b9a1f26 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -38,7 +39,6 @@
-export([integer_to_list/2]).
-export([integer_to_binary/2]).
--export([flush_monitor_message/2]).
-export([set_cpu_topology/1, format_cpu_topology/1]).
-export([await_proc_exit/3]).
-export([memory/0, memory/1]).
@@ -48,7 +48,7 @@
await_sched_wall_time_modifications/2,
gather_gc_info_result/1]).
--deprecated([hash/2]).
+-deprecated([hash/2, now/0]).
%% Get rid of autoimports of spawn to avoid clashes with ourselves.
-compile({no_auto_import,[spawn_link/1]}).
@@ -58,12 +58,21 @@
-compile({no_auto_import,[spawn_opt/5]}).
-export_type([timestamp/0]).
+-export_type([time_unit/0]).
-type ext_binary() :: binary().
-type timestamp() :: {MegaSecs :: non_neg_integer(),
Secs :: non_neg_integer(),
MicroSecs :: non_neg_integer()}.
+-type time_unit() ::
+ pos_integer()
+ | 'seconds'
+ | 'milli_seconds'
+ | 'micro_seconds'
+ | 'nano_seconds'
+ | 'native'.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Native code BIF stubs and their types
%% (BIF's actually implemented in this module goes last in the file)
@@ -81,7 +90,7 @@
-export([binary_to_list/3, binary_to_term/1, binary_to_term/2]).
-export([bit_size/1, bitsize/1, bitstring_to_list/1]).
-export([bump_reductions/1, byte_size/1, call_on_load_function/1]).
--export([cancel_timer/1, check_old_code/1, check_process_code/2,
+-export([cancel_timer/1, cancel_timer/2, check_old_code/1, check_process_code/2,
check_process_code/3, crc32/1]).
-export([crc32/2, crc32_combine/3, date/0, decode_packet/3]).
-export([delete_element/2]).
@@ -93,7 +102,7 @@
float_to_list/1, float_to_list/2]).
-export([fun_info/2, fun_info_mfa/1, fun_to_list/1, function_exported/3]).
-export([garbage_collect/0, garbage_collect/1, garbage_collect/2]).
--export([garbage_collect_message_area/0, get/0, get/1, get_keys/1]).
+-export([garbage_collect_message_area/0, get/0, get/1, get_keys/0, get_keys/1]).
-export([get_module_info/1, get_stacktrace/0, group_leader/0]).
-export([group_leader/2, halt/0, halt/1, halt/2, hash/2, hibernate/3]).
-export([insert_element/3]).
@@ -104,7 +113,8 @@
-export([list_to_bitstring/1, list_to_existing_atom/1, list_to_float/1]).
-export([list_to_integer/1, list_to_integer/2]).
-export([list_to_pid/1, list_to_tuple/1, loaded/0]).
--export([localtime/0, make_ref/0, map_size/1, match_spec_test/3, md5/1, md5_final/1]).
+-export([localtime/0, make_ref/0]).
+-export([map_size/1, match_spec_test/3, md5/1, md5_final/1]).
-export([md5_init/0, md5_update/2, module_loaded/1, monitor/2]).
-export([monitor_node/2, monitor_node/3, nif_error/1, nif_error/2]).
-export([node/0, node/1, now/0, phash/2, phash2/1, phash2/2]).
@@ -112,13 +122,19 @@
-export([port_connect/2, port_control/3, port_get_data/1]).
-export([port_set_data/2, port_to_list/1, ports/0]).
-export([posixtime_to_universaltime/1, pre_loaded/0, prepare_loading/2]).
+-export([monotonic_time/0, monotonic_time/1]).
+-export([system_time/0, system_time/1]).
+-export([convert_time_unit/3]).
+-export([unique_integer/0, unique_integer/1]).
+-export([time_offset/0, time_offset/1, timestamp/0]).
-export([process_display/2]).
-export([process_flag/3, process_info/1, processes/0, purge_module/1]).
--export([put/2, raise/3, read_timer/1, ref_to_list/1, register/2]).
--export([registered/0, resume_process/1, round/1, self/0, send_after/3]).
+-export([put/2, raise/3, read_timer/1, read_timer/2, ref_to_list/1, register/2]).
+-export([send_after/3, send_after/4, start_timer/3, start_timer/4]).
+-export([registered/0, resume_process/1, round/1, self/0]).
-export([seq_trace/2, seq_trace_print/1, seq_trace_print/2, setnode/2]).
-export([setnode/3, size/1, spawn/3, spawn_link/3, split_binary/2]).
--export([start_timer/3, suspend_process/2, system_monitor/0]).
+-export([suspend_process/2, system_monitor/0]).
-export([system_monitor/1, system_monitor/2, system_profile/0]).
-export([system_profile/2, throw/1, time/0, trace/3, trace_delivered/1]).
-export([trace_info/2, trunc/1, tuple_size/1, universaltime/0]).
@@ -169,6 +185,8 @@
'receive' |
'print' |
'timestamp' |
+ 'monotonic_timestamp' |
+ 'strict_monotonic_timestamp' |
'label' |
'serial'.
@@ -182,7 +200,10 @@
'exclusive' |
'runnable_ports' |
'runnable_procs' |
- 'scheduler'.
+ 'scheduler' |
+ 'timestamp' |
+ 'monotonic_timestamp' |
+ 'strict_monotonic_timestamp'.
-type system_monitor_option() ::
'busy_port' |
@@ -214,6 +235,8 @@
garbage_collection |
timestamp |
cpu_timestamp |
+ monotonic_timestamp |
+ strict_monotonic_timestamp |
arity |
set_on_spawn |
set_on_first_spawn |
@@ -242,6 +265,8 @@
running |
garbage_collection |
timestamp |
+ monotonic_timestamp |
+ strict_monotonic_timestamp |
arity.
-type trace_info_return() ::
@@ -410,12 +435,27 @@ call_on_load_function(_P1) ->
erlang:nif_error(undefined).
%% cancel_timer/1
--spec erlang:cancel_timer(TimerRef) -> Time | false when
+-spec erlang:cancel_timer(TimerRef) -> Result when
TimerRef :: reference(),
- Time :: non_neg_integer().
+ Time :: non_neg_integer(),
+ Result :: Time | false.
+
cancel_timer(_TimerRef) ->
erlang:nif_error(undefined).
+%% cancel_timer/2
+-spec erlang:cancel_timer(TimerRef, Options) -> Result | ok when
+ TimerRef :: reference(),
+ Async :: boolean(),
+ Info :: boolean(),
+ Option :: {async, Async} | {info, Info},
+ Options :: [Option],
+ Time :: non_neg_integer(),
+ Result :: Time | false.
+
+cancel_timer(_TimerRef, _Options) ->
+ erlang:nif_error(undefined).
+
%% check_old_code/1
-spec check_old_code(Module) -> boolean() when
Module :: module().
@@ -931,6 +971,12 @@ get() ->
get(_Key) ->
erlang:nif_error(undefined).
+%% get_keys/0
+-spec get_keys() -> [Key] when
+ Key :: term().
+get_keys() ->
+ erlang:nif_error(undefined).
+
%% get_keys/1
-spec get_keys(Val) -> [Key] when
Val :: term(),
@@ -1184,13 +1230,18 @@ md5_update(_Context, _Data) ->
module_loaded(_Module) ->
erlang:nif_error(undefined).
+-type registered_name() :: atom().
+
+-type registered_process_identifier() :: registered_name() | {registered_name(), node()}.
+
+-type monitor_process_identifier() :: pid() | registered_process_identifier().
+
%% monitor/2
--spec monitor(Type, Item) -> MonitorRef when
- Type :: process,
- Item :: pid() | RegName | {RegName, Node},
- RegName :: module(),
- Node :: node(),
+-spec monitor(process, monitor_process_identifier()) -> MonitorRef when
+ MonitorRef :: reference();
+ (time_offset, clock_service) -> MonitorRef when
MonitorRef :: reference().
+
monitor(_Type, _Item) ->
erlang:nif_error(undefined).
@@ -1292,6 +1343,90 @@ ports() ->
posixtime_to_universaltime(_P1) ->
erlang:nif_error(undefined).
+-spec erlang:unique_integer(ModifierList) -> integer() when
+ ModifierList :: [Modifier],
+ Modifier :: positive | monotonic.
+
+unique_integer(_ModifierList) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:unique_integer() -> integer().
+
+unique_integer() ->
+ erlang:nif_error(undefined).
+
+-spec erlang:monotonic_time() -> integer().
+
+monotonic_time() ->
+ erlang:nif_error(undefined).
+
+-spec erlang:monotonic_time(Unit) -> integer() when
+ Unit :: time_unit().
+
+monotonic_time(_Unit) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:system_time() -> integer().
+
+system_time() ->
+ erlang:nif_error(undefined).
+
+-spec erlang:system_time(Unit) -> integer() when
+ Unit :: time_unit().
+
+system_time(_Unit) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:convert_time_unit(Time, FromUnit, ToUnit) -> ConvertedTime when
+ Time :: integer(),
+ ConvertedTime :: integer(),
+ FromUnit :: time_unit(),
+ ToUnit :: time_unit().
+
+convert_time_unit(Time, FromUnit, ToUnit) ->
+ try
+ FU = case FromUnit of
+ native -> erts_internal:time_unit();
+ nano_seconds -> 1000*1000*1000;
+ micro_seconds -> 1000*1000;
+ milli_seconds -> 1000;
+ seconds -> 1;
+ _ when FromUnit > 0 -> FromUnit
+ end,
+ TU = case ToUnit of
+ native -> erts_internal:time_unit();
+ nano_seconds -> 1000*1000*1000;
+ micro_seconds -> 1000*1000;
+ milli_seconds -> 1000;
+ seconds -> 1;
+ _ when ToUnit > 0 -> ToUnit
+ end,
+ case Time < 0 of
+ true -> TU*Time - (FU - 1);
+ false -> TU*Time
+ end div FU
+ catch
+ _ : _ ->
+ erlang:error(badarg, [Time, FromUnit, ToUnit])
+ end.
+
+-spec erlang:time_offset() -> integer().
+
+time_offset() ->
+ erlang:nif_error(undefined).
+
+-spec erlang:time_offset(Unit) -> integer() when
+ Unit :: time_unit().
+
+time_offset(_Unit) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:timestamp() -> Timestamp when
+ Timestamp :: timestamp().
+
+timestamp() ->
+ erlang:nif_error(undefined).
+
%% prepare_loading/2
-spec erlang:prepare_loading(Module, Code) -> PreparedCode | {error, Reason} when
Module :: module(),
@@ -1357,11 +1492,26 @@ raise(_Class, _Reason, _Stacktrace) ->
erlang:nif_error(undefined).
%% read_timer/1
--spec erlang:read_timer(TimerRef) -> non_neg_integer() | false when
- TimerRef :: reference().
+-spec erlang:read_timer(TimerRef) -> Result when
+ TimerRef :: reference(),
+ Time :: non_neg_integer(),
+ Result :: Time | false.
+
read_timer(_TimerRef) ->
erlang:nif_error(undefined).
+%% read_timer/2
+-spec erlang:read_timer(TimerRef, Options) -> Result | ok when
+ TimerRef :: reference(),
+ Async :: boolean(),
+ Option :: {async, Async},
+ Options :: [Option],
+ Time :: non_neg_integer(),
+ Result :: Time | false.
+
+read_timer(_TimerRef, _Options) ->
+ erlang:nif_error(undefined).
+
%% ref_to_list/1
-spec erlang:ref_to_list(Ref) -> string() when
Ref :: reference().
@@ -1406,9 +1556,23 @@ self() ->
Dest :: pid() | atom(),
Msg :: term(),
TimerRef :: reference().
+
send_after(_Time, _Dest, _Msg) ->
erlang:nif_error(undefined).
+%% send_after/4
+-spec erlang:send_after(Time, Dest, Msg, Options) -> TimerRef when
+ Time :: integer(),
+ Dest :: pid() | atom(),
+ Msg :: term(),
+ Options :: [Option],
+ Abs :: boolean(),
+ Option :: {abs, Abs},
+ TimerRef :: reference().
+
+send_after(_Time, _Dest, _Msg, _Options) ->
+ erlang:nif_error(undefined).
+
%% seq_trace/2
-spec erlang:seq_trace(P1, P2) -> seq_trace_info_returns() | {term(), term(), term(), term(), term()} when
P1 :: atom(),
@@ -1480,9 +1644,23 @@ split_binary(_Bin, _Pos) ->
Dest :: pid() | atom(),
Msg :: term(),
TimerRef :: reference().
+
start_timer(_Time, _Dest, _Msg) ->
erlang:nif_error(undefined).
+%% start_timer/4
+-spec erlang:start_timer(Time, Dest, Msg, Options) -> TimerRef when
+ Time :: integer(),
+ Dest :: pid() | atom(),
+ Msg :: term(),
+ Options :: [Option],
+ Abs :: boolean(),
+ Option :: {abs, Abs},
+ TimerRef :: reference().
+
+start_timer(_Time, _Dest, _Msg, _Options) ->
+ erlang:nif_error(undefined).
+
%% suspend_process/2
-spec erlang:suspend_process(Suspendee, OptList) -> boolean() when
Suspendee :: pid(),
@@ -1651,7 +1829,7 @@ element(_N, _Tuple) ->
%% Not documented
-spec erlang:get_module_info(Module, Item) -> ModuleInfo when
Module :: atom(),
- Item :: module | imports | exports | functions | attributes | compile | native_addresses,
+ Item :: module | exports | functions | attributes | compile | native_addresses | md5,
ModuleInfo :: atom() | [] | [{atom(), arity()}] | [{atom(), term()}] | [{atom(), arity(), integer()}].
get_module_info(_Module, _Item) ->
erlang:nif_error(undefined).
@@ -1805,6 +1983,7 @@ localtime_to_universaltime(_Localtime, _IsDst) ->
%% CHECK! Why the strange very thorough specification of the error
%% condition with disallowed arity in erl_bif_types?
%% Not documented
+%% Shadowed by erl_bif_types: erlang:make_fun/3
-spec erlang:make_fun(Module, Function, Arity) -> function() when
Module :: atom(),
Function :: atom(),
@@ -2008,6 +2187,8 @@ send(_Dest,_Msg,_Options) ->
('receive') -> {'receive', boolean()};
(print) -> {print, boolean()};
(timestamp) -> {timestamp, boolean()};
+ (monotonic_timestamp) -> {timestamp, boolean()};
+ (strict_monotonic_timestamp) -> {strict_monotonic_timestamp, boolean()};
(label) -> [] | {label, non_neg_integer()};
(serial) -> [] | {serial, {non_neg_integer(), non_neg_integer()}}.
seq_trace_info(_What) ->
@@ -2035,7 +2216,9 @@ setelement(_Index, _Tuple1, _Value) ->
spawn_opt(_Tuple) ->
erlang:nif_error(undefined).
--spec statistics(context_switches) -> {ContextSwitches,0} when
+-spec statistics(active_tasks) -> [ActiveTasks] when
+ ActiveTasks :: non_neg_integer();
+ (context_switches) -> {ContextSwitches,0} when
ContextSwitches :: non_neg_integer();
(exact_reductions) -> {Total_Exact_Reductions,
Exact_Reductions_Since_Last_Call} when
@@ -2052,6 +2235,8 @@ spawn_opt(_Tuple) ->
Total_Reductions :: non_neg_integer(),
Reductions_Since_Last_Call :: non_neg_integer();
(run_queue) -> non_neg_integer();
+ (run_queue_lengths) -> [RunQueueLenght] when
+ RunQueueLenght :: non_neg_integer();
(runtime) -> {Total_Run_Time, Time_Since_Last_Call} when
Total_Run_Time :: non_neg_integer(),
Time_Since_Last_Call :: non_neg_integer();
@@ -2059,6 +2244,10 @@ spawn_opt(_Tuple) ->
SchedulerId :: pos_integer(),
ActiveTime :: non_neg_integer(),
TotalTime :: non_neg_integer();
+ (total_active_tasks) -> ActiveTasks when
+ ActiveTasks :: non_neg_integer();
+ (total_run_queue_lengths) -> TotalRunQueueLenghts when
+ TotalRunQueueLenghts :: non_neg_integer();
(wall_clock) -> {Total_Wallclock_Time,
Wallclock_Time_Since_Last_Call} when
Total_Wallclock_Time :: non_neg_integer(),
@@ -2118,6 +2307,8 @@ subtract(_,_) ->
(trace_control_word, TCW) -> OldTCW when
TCW :: non_neg_integer(),
OldTCW :: non_neg_integer();
+ (time_offset, finalize) -> OldState when
+ OldState :: preliminary | final | volatile;
%% These are deliberately not documented
(internal_cpu_topology, term()) -> term();
(sequential_tracer, pid() | port() | false) -> pid() | port() | false;
@@ -2222,6 +2413,7 @@ tuple_to_list(_Tuple) ->
CpuTopology :: cpu_topology();
(creation) -> integer();
(debug_compiled) -> boolean();
+ (delayed_node_table_gc) -> infinity | non_neg_integer();
(dirty_cpu_schedulers) -> non_neg_integer();
(dirty_cpu_schedulers_online) -> non_neg_integer();
(dirty_io_schedulers) -> non_neg_integer();
@@ -2251,9 +2443,11 @@ tuple_to_list(_Tuple) ->
MinBinVHeapSize :: pos_integer()};
(modified_timing_level) -> integer() | undefined;
(multi_scheduling) -> disabled | blocked | enabled;
- (multi_scheduling_blockers) -> [PID :: pid()];
+ (multi_scheduling_blockers) -> [Pid :: pid()];
(nif_version) -> string();
(otp_release) -> string();
+ (os_monotonic_time_source) -> [{atom(),term()}];
+ (os_system_time_source) -> [{atom(),term()}];
(port_count) -> non_neg_integer();
(port_limit) -> pos_integer();
(process_count) -> pos_integer();
@@ -2271,10 +2465,14 @@ tuple_to_list(_Tuple) ->
(scheduler_id) -> SchedulerId :: pos_integer();
(schedulers | schedulers_online) -> pos_integer();
(smp_support) -> boolean();
+ (start_time) -> integer();
(system_version) -> string();
(system_architecture) -> string();
(threads) -> boolean();
(thread_pool_size) -> non_neg_integer();
+ (time_correction) -> true | false;
+ (time_offset) -> preliminary | final | volatile;
+ (time_warp_mode) -> no_time_warp | single_time_warp | multi_time_warp;
(tolerant_timeofday) -> enabled | disabled;
(trace_control_word) -> non_neg_integer();
(update_cpu_info) -> changed | unchanged;
@@ -3041,16 +3239,6 @@ integer_to_binary(I0, Base, R0) ->
true -> integer_to_binary(I1, Base, R1)
end.
-%% erlang:flush_monitor_message/2 is for internal use only!
-%%
-%% erlang:demonitor(Ref, [flush]) traps to
-%% erlang:flush_monitor_message(Ref, Res) when
-%% it needs to flush a monitor message.
-flush_monitor_message(Ref, Res) when erlang:is_reference(Ref),
- erlang:is_atom(Res) ->
- receive {_, Ref, _, _, _} -> ok after 0 -> ok end,
- Res.
-
-record(cpu, {node = -1,
processor = -1,
processor_node = -1,
@@ -3434,7 +3622,11 @@ blocks_size([], Acc) ->
get_fix_proc([{ProcType, A1, U1}| Rest], {A0, U0}) when ProcType == proc;
ProcType == monitor_sh;
ProcType == nlink_sh;
- ProcType == msg_ref ->
+ ProcType == msg_ref;
+ ProcType == ll_ptimer;
+ ProcType == hl_ptimer;
+ ProcType == bif_timer;
+ ProcType == accessor_bif_timer ->
get_fix_proc(Rest, {A0+A1, U0+U1});
get_fix_proc([_|Rest], Acc) ->
get_fix_proc(Rest, Acc);
diff --git a/erts/preloaded/src/erts.app.src b/erts/preloaded/src/erts.app.src
index 345a6ae3be..8442aaf7e8 100644
--- a/erts/preloaded/src/erts.app.src
+++ b/erts/preloaded/src/erts.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -35,7 +36,7 @@
{registered, []},
{applications, []},
{env, []},
- {runtime_dependencies, ["stdlib-2.0", "kernel-3.0", "sasl-2.4"]}
+ {runtime_dependencies, ["stdlib-2.5", "kernel-4.0", "sasl-2.4"]}
]}.
%% vim: ft=erlang
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index 2c5bd82cf0..6db77a8482 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,14 +31,25 @@
-export([await_port_send_result/3]).
-export([cmp_term/2]).
--export([map_to_tuple_keys/1]).
+-export([map_to_tuple_keys/1, map_type/1, map_hashmap_children/1]).
-export([port_command/3, port_connect/2, port_close/1,
port_control/3, port_call/3, port_info/1, port_info/2]).
+-export([system_check/1,
+ gather_system_check_result/1]).
+
-export([request_system_task/3]).
-export([check_process_code/2]).
+-export([flush_monitor_messages/3]).
+
+-export([await_result/1, gather_io_bytes/2]).
+
+-export([time_unit/0]).
+
+-export([is_system_process/1]).
+
%%
%% Await result of send to port
%%
@@ -49,6 +61,33 @@ await_port_send_result(Ref, Busy, Ok) ->
end.
%%
+%% Await result...
+%%
+
+await_result(Ref) when is_reference(Ref) ->
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+%%
+%% statistics(io) end up in gather_io_bytes/2
+%%
+
+gather_io_bytes(Ref, No) when is_reference(Ref),
+ is_integer(No),
+ No > 0 ->
+ gather_io_bytes(Ref, No, 0, 0).
+
+gather_io_bytes(_Ref, 0, InAcc, OutAcc) ->
+ {{input, InAcc}, {output, OutAcc}};
+gather_io_bytes(Ref, No, InAcc, OutAcc) ->
+ receive
+ {Ref, _SchedId, In, Out} ->
+ gather_io_bytes(Ref, No-1, InAcc + In, OutAcc + Out)
+ end.
+
+%%
%% Statically linked port NIFs
%%
@@ -161,6 +200,23 @@ request_system_task(_Pid, _Prio, _Request) ->
check_process_code(_Module, _OptionList) ->
erlang:nif_error(undefined).
+-spec system_check(Type) -> 'ok' when
+ Type :: 'schedulers'.
+
+system_check(_Type) ->
+ erlang:nif_error(undefined).
+
+gather_system_check_result(Ref) when is_reference(Ref) ->
+ gather_system_check_result(Ref, erlang:system_info(schedulers)).
+
+gather_system_check_result(_Ref, 0) ->
+ ok;
+gather_system_check_result(Ref, N) ->
+ receive
+ Ref ->
+ gather_system_check_result(Ref, N - 1)
+ end.
+
%% term compare where integer() < float() = true
-spec cmp_term(A,B) -> Result when
@@ -178,3 +234,52 @@ cmp_term(_A,_B) ->
map_to_tuple_keys(_M) ->
erlang:nif_error(undefined).
+
+%% return the internal map type
+-spec map_type(M) -> Type when
+ M :: map(),
+ Type :: 'flatmap' | 'hashmap' | 'hashmap_node'.
+
+map_type(_M) ->
+ erlang:nif_error(undefined).
+
+%% return the internal hashmap sub-nodes from
+%% a hashmap node
+-spec map_hashmap_children(M) -> Children when
+ M :: map(), %% hashmap node
+ Children :: [map() | nonempty_improper_list(term(),term())].
+
+map_hashmap_children(_M) ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:flush_monitor_messages(Ref, Multi, Res) -> term() when
+ Ref :: reference(),
+ Multi :: boolean(),
+ Res :: term().
+
+%% erlang:demonitor(Ref, [flush]) traps to
+%% erts_internal:flush_monitor_messages(Ref, Res) when
+%% it needs to flush monitor messages.
+flush_monitor_messages(Ref, Multi, Res) when is_reference(Ref) ->
+ receive
+ {_, Ref, _, _, _} ->
+ case Multi of
+ false ->
+ Res;
+ _ ->
+ flush_monitor_messages(Ref, Multi, Res)
+ end
+ after 0 ->
+ Res
+ end.
+
+-spec erts_internal:time_unit() -> pos_integer().
+
+time_unit() ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:is_system_process(Pid) -> boolean() when
+ Pid :: pid().
+
+is_system_process(_Pid) ->
+ erlang:nif_error(undefined).
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index e95e11b3e6..0ad5824ad1 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -166,7 +167,6 @@ stop(Status) -> init ! {stop,{stop,Status}}, ok.
boot(BootArgs) ->
register(init, self()),
process_flag(trap_exit, true),
- start_on_load_handler_process(),
{Start0,Flags,Args} = parse_boot_args(BootArgs),
Start = map(fun prepare_run_args/1, Start0),
Flags0 = flags_to_atoms_again(Flags),
@@ -224,6 +224,7 @@ code_path_choice() ->
end.
boot(Start,Flags,Args) ->
+ start_on_load_handler_process(),
BootPid = do_boot(Flags,Start),
State = #state{flags = Flags,
args = Args,
@@ -591,12 +592,9 @@ kill_all_pids(Heart) ->
kill_all_pids(Heart) % Continue until all are really killed.
end.
-%% All except zombies.
-alive_processes() ->
- [P || P <- processes(), erlang:is_process_alive(P)].
-
+%% All except system processes.
get_pids(Heart) ->
- Pids = alive_processes(),
+ Pids = [P || P <- processes(), not erts_internal:is_system_process(P)],
delete(Heart,self(),Pids).
delete(Heart,Init,[Heart|Pids]) -> delete(Heart,Init,Pids);
diff --git a/erts/preloaded/src/otp_ring0.erl b/erts/preloaded/src/otp_ring0.erl
index 2ccf142f30..3158fc7d21 100644
--- a/erts/preloaded/src/otp_ring0.erl
+++ b/erts/preloaded/src/otp_ring0.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/preloaded/src/prim_eval.S b/erts/preloaded/src/prim_eval.S
index 958a79a1da..1b7b00a7c9 100644
--- a/erts/preloaded/src/prim_eval.S
+++ b/erts/preloaded/src/prim_eval.S
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/preloaded/src/prim_eval.erl b/erts/preloaded/src/prim_eval.erl
index ec5af8c138..732e22468e 100644
--- a/erts/preloaded/src/prim_eval.erl
+++ b/erts/preloaded/src/prim_eval.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 34679404a2..ab5359ebbc 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1275,6 +1276,7 @@ lseek_position(_) ->
%% Translates the response from the driver into
%% {ok, Result} or {error, Reason}.
+-dialyzer({no_improper_lists, translate_response/2}).
translate_response(?FILE_RESP_OK, []) ->
ok;
translate_response(?FILE_RESP_ERROR, List) when is_list(List) ->
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index 79ff013c77..bd74831bb7 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -127,37 +128,18 @@ drv2protocol(_) -> undefined.
%% TODO: shutdown equivalent for SCTP
%%
shutdown(S, read) when is_port(S) ->
- shutdown_2(S, 0);
+ shutdown_1(S, 0);
shutdown(S, write) when is_port(S) ->
shutdown_1(S, 1);
shutdown(S, read_write) when is_port(S) ->
shutdown_1(S, 2).
shutdown_1(S, How) ->
- case subscribe(S, [subs_empty_out_q]) of
- {ok,[{subs_empty_out_q,N}]} when N > 0 ->
- shutdown_pend_loop(S, N); %% wait for pending output to be sent
- _Other -> ok
- end,
- shutdown_2(S, How).
-
-shutdown_2(S, How) ->
case ctl_cmd(S, ?TCP_REQ_SHUTDOWN, [How]) of
{ok, []} -> ok;
{error,_}=Error -> Error
end.
-shutdown_pend_loop(S, N0) ->
- receive
- {empty_out_q,S} -> ok
- after ?INET_CLOSE_TIMEOUT ->
- case getstat(S, [send_pend]) of
- {ok,[{send_pend,N0}]} -> ok;
- {ok,[{send_pend,N}]} -> shutdown_pend_loop(S, N);
- _ -> ok
- end
- end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% CLOSE(insock()) -> ok
@@ -165,11 +147,16 @@ shutdown_pend_loop(S, N0) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close(S) when is_port(S) ->
- case subscribe(S, [subs_empty_out_q]) of
- {ok, [{subs_empty_out_q,N}]} when N > 0 ->
- close_pend_loop(S, N); %% wait for pending output to be sent
+ case getopt(S, linger) of
+ {ok,{true,0}} ->
+ close_port(S);
_ ->
- close_port(S)
+ case subscribe(S, [subs_empty_out_q]) of
+ {ok, [{subs_empty_out_q,N}]} when N > 0 ->
+ close_pend_loop(S, N); %% wait for pending output to be sent
+ _ ->
+ close_port(S)
+ end
end.
close_pend_loop(S, N) ->
@@ -245,7 +232,7 @@ bindx(S, AddFlag, Addrs) ->
%% if timeout is given:
%% timeout < 0 -> infinity
%% 0 -> immediate connect (mostly works for loopback)
-%% > 0 -> wait for timout ms if not connected then
+%% > 0 -> wait for timeout ms if not connected then
%% return {error, timeout}
%%
%% ASYNC_CONNECT(insock(), IP, Port, Timeout) -> {ok, S, Ref} | {error, Reason}
@@ -286,7 +273,7 @@ async_connect(S, IP, Port, Time) ->
%% if timeout is given:
%% timeout < 0 -> infinity
%% 0 -> immediate accept (poll)
-%% > 0 -> wait for timout ms for accept if no accept then
+%% > 0 -> wait for timeout ms for accept if no accept then
%% return {error, timeout}
%%
%% ASYNC_ACCEPT(insock(), Timeout)
@@ -1159,6 +1146,8 @@ enc_opt(delay_send) -> ?INET_LOPT_TCP_DELAY_SEND;
enc_opt(packet_size) -> ?INET_LOPT_PACKET_SIZE;
enc_opt(read_packets) -> ?INET_LOPT_READ_PACKETS;
enc_opt(netns) -> ?INET_LOPT_NETNS;
+enc_opt(show_econnreset) -> ?INET_LOPT_TCP_SHOW_ECONNRESET;
+enc_opt(line_delimiter) -> ?INET_LOPT_LINE_DELIM;
enc_opt(raw) -> ?INET_OPT_RAW;
% Names of SCTP opts:
enc_opt(sctp_rtoinfo) -> ?SCTP_OPT_RTOINFO;
@@ -1216,6 +1205,8 @@ dec_opt(?INET_LOPT_TCP_DELAY_SEND) -> delay_send;
dec_opt(?INET_LOPT_PACKET_SIZE) -> packet_size;
dec_opt(?INET_LOPT_READ_PACKETS) -> read_packets;
dec_opt(?INET_LOPT_NETNS) -> netns;
+dec_opt(?INET_LOPT_TCP_SHOW_ECONNRESET) -> show_econnreset;
+dec_opt(?INET_LOPT_LINE_DELIM) -> line_delimiter;
dec_opt(?INET_OPT_RAW) -> raw;
dec_opt(I) when is_integer(I) -> undefined.
@@ -1298,6 +1289,7 @@ type_opt_1(packet) ->
{httph_bin,?TCP_PB_HTTPH_BIN},
{ssl, ?TCP_PB_SSL_TLS}, % obsolete
{ssl_tls, ?TCP_PB_SSL_TLS}]};
+type_opt_1(line_delimiter) -> int;
type_opt_1(mode) ->
{enum,[{list, ?INET_MODE_LIST},
{binary, ?INET_MODE_BINARY}]};
@@ -1315,6 +1307,7 @@ type_opt_1(delay_send) -> bool;
type_opt_1(packet_size) -> uint;
type_opt_1(read_packets) -> uint;
type_opt_1(netns) -> binary;
+type_opt_1(show_econnreset) -> bool;
%%
%% SCTP options (to be set). If the type is a record type, the corresponding
%% record signature is returned, otherwise, an "elementary" type tag
diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl
index 1d5ab52a24..c4b949afcb 100644
--- a/erts/preloaded/src/prim_zip.erl
+++ b/erts/preloaded/src/prim_zip.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/preloaded/src/zip_internal.hrl b/erts/preloaded/src/zip_internal.hrl
index a8f7b1f1b7..d5cf52fae4 100644
--- a/erts/preloaded/src/zip_internal.hrl
+++ b/erts/preloaded/src/zip_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl
index df7b2e6198..473ad649c7 100644
--- a/erts/preloaded/src/zlib.erl
+++ b/erts/preloaded/src/zlib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,13 +25,14 @@
deflate/2,deflate/3,deflateEnd/1,
inflateInit/1,inflateInit/2,inflateSetDictionary/2,
inflateSync/1,inflateReset/1,inflate/2,inflateEnd/1,
+ inflateChunk/1, inflateChunk/2,
setBufSize/2,getBufSize/1,
crc32/1,crc32/2,crc32/3,adler32/2,adler32/3,getQSize/1,
crc32_combine/4,adler32_combine/4,
compress/1,uncompress/1,zip/1,unzip/1,
gzip/1,gunzip/1]).
--export_type([zstream/0]).
+-export_type([zstream/0, zlevel/0, zwindowbits/0, zmemlevel/0, zstrategy/0]).
%% flush argument encoding
-define(Z_NO_FLUSH, 0).
@@ -100,6 +102,7 @@
-define(INFLATE_RESET, 12).
-define(INFLATE_END, 13).
-define(INFLATE, 14).
+-define(INFLATE_CHUNK, 25).
-define(CRC32_0, 15).
-define(CRC32_1, 16).
@@ -124,7 +127,7 @@
-type zlevel() :: 'none' | 'default' | 'best_compression' | 'best_speed'
| 0..9.
-type zmethod() :: 'deflated'.
--type zwindowbits() :: -15..-9 | 9..47.
+-type zwindowbits() :: -15..-8 | 8..47.
-type zmemlevel() :: 1..9.
-type zstrategy() :: 'default' | 'filtered' | 'huffman_only' | 'rle'.
@@ -263,6 +266,39 @@ inflate(Z, Data) ->
erlang:error(badarg)
end.
+-spec inflateChunk(Z, Data) -> Decompressed | {more, Decompressed} when
+ Z :: zstream(),
+ Data :: iodata(),
+ Decompressed :: iolist().
+inflateChunk(Z, Data) ->
+ try port_command(Z, Data) of
+ true ->
+ inflateChunk(Z)
+ catch
+ error:_Err ->
+ flush(Z),
+ erlang:error(badarg)
+ end.
+
+-spec inflateChunk(Z) -> Decompressed | {more, Decompressed} when
+ Z :: zstream(),
+ Decompressed :: iolist().
+inflateChunk(Z) ->
+ Status = call(Z, ?INFLATE_CHUNK, []),
+ Data = receive
+ {Z, {data, Bin}} ->
+ Bin
+ after 0 ->
+ []
+ end,
+
+ case Status of
+ Good when (Good == ok) orelse (Good == stream_end) ->
+ Data;
+ inflate_has_more ->
+ {more, Data}
+ end.
+
-spec inflateEnd(Z) -> 'ok' when
Z :: zstream().
inflateEnd(Z) ->
@@ -496,8 +532,8 @@ arg_method(_) -> erlang:error(badarg).
-spec arg_bitsz(zwindowbits()) -> zwindowbits().
arg_bitsz(Bits) when is_integer(Bits) andalso
- ((8 < Bits andalso Bits < 48) orelse
- (-15 =< Bits andalso Bits < -8)) ->
+ ((8 =< Bits andalso Bits < 48) orelse
+ (-15 =< Bits andalso Bits =< -8)) ->
Bits;
arg_bitsz(_) -> erlang:error(badarg).
@@ -514,7 +550,9 @@ call(Z, Cmd, Arg) ->
[2,A,B,C,D] ->
(A bsl 24)+(B bsl 16)+(C bsl 8)+D;
[3,A,B,C,D] ->
- erlang:error({need_dictionary,(A bsl 24)+(B bsl 16)+(C bsl 8)+D})
+ erlang:error({need_dictionary,(A bsl 24)+(B bsl 16)+(C bsl 8)+D});
+ [4, _, _, _, _] ->
+ inflate_has_more
catch
error:badarg -> %% Rethrow loses port_control from stacktrace.
erlang:error(badarg)
diff --git a/erts/start_scripts/Makefile b/erts/start_scripts/Makefile
index 14d5d46195..8025681924 100644
--- a/erts/start_scripts/Makefile
+++ b/erts/start_scripts/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/start_scripts/no_dot_erlang.rel.src b/erts/start_scripts/no_dot_erlang.rel.src
index 6208572c00..bcc9fa9e8a 100644
--- a/erts/start_scripts/no_dot_erlang.rel.src
+++ b/erts/start_scripts/no_dot_erlang.rel.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/start_scripts/start_all_example.rel.src b/erts/start_scripts/start_all_example.rel.src
index 2a1cabe7bb..2c4deb4485 100644
--- a/erts/start_scripts/start_all_example.rel.src
+++ b/erts/start_scripts/start_all_example.rel.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/start_scripts/start_clean.rel.src b/erts/start_scripts/start_clean.rel.src
index e229721e36..25519deb17 100644
--- a/erts/start_scripts/start_clean.rel.src
+++ b/erts/start_scripts/start_clean.rel.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/start_scripts/start_sasl.rel.src b/erts/start_scripts/start_sasl.rel.src
index e68a34af76..9cf417ade5 100644
--- a/erts/start_scripts/start_sasl.rel.src
+++ b/erts/start_scripts/start_sasl.rel.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/test/Makefile b/erts/test/Makefile
index 6fbc19fcae..5263d8cd4f 100644
--- a/erts/test/Makefile
+++ b/erts/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl
index a49d8f069f..3b0c083702 100644
--- a/erts/test/erl_print_SUITE.erl
+++ b/erts/test/erl_print_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/erl_print_SUITE_data/Makefile.src b/erts/test/erl_print_SUITE_data/Makefile.src
index fdffed3b2d..e6ea5cc6b9 100644
--- a/erts/test/erl_print_SUITE_data/Makefile.src
+++ b/erts/test/erl_print_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/erl_print_SUITE_data/character_test.h b/erts/test/erl_print_SUITE_data/character_test.h
index 9c66618a71..9ff032cb07 100644
--- a/erts/test/erl_print_SUITE_data/character_test.h
+++ b/erts/test/erl_print_SUITE_data/character_test.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/test/erl_print_SUITE_data/erl_print_tests.c b/erts/test/erl_print_SUITE_data/erl_print_tests.c
index acb213cd3a..fb23dc35a6 100644
--- a/erts/test/erl_print_SUITE_data/erl_print_tests.c
+++ b/erts/test/erl_print_SUITE_data/erl_print_tests.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -502,16 +503,17 @@ main(int argc, char *argv[])
" * %%CopyrightBegin%%\n"
" * Copyright Ericsson AB 1996-2009. All Rights Reserved.\n"
" * \n"
- " * The contents of this file are subject to the Erlang Public License,\n"
- " * Version 1.1, (the \"License\"); you may not use this file except in\n"
- " * compliance with the License. You should have received a copy of the\n"
- " * Erlang Public License along with this software. If not, it can be\n"
- " * retrieved online at http://www.erlang.org/.\n"
- " * \n"
- " * Software distributed under the License is distributed on an \"AS IS\"\n"
- " * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See\n"
- " * the License for the specific language governing rights and limitations\n"
- " * under the License.\n"
+ " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
+ " * you may not use this file except in compliance with the License.\n"
+ " * You may obtain a copy of the License at\n"
+ " * \n"
+ " * http://www.apache.org/licenses/LICENSE-2.0\n"
+ " * \n"
+ " * Unless required by applicable law or agreed to in writing, software\n"
+ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+ " * See the License for the specific language governing permissions and\n"
+ " * limitations under the License.\n"
" * %%CopyrightEnd%%\n"
" */\n"
"\n");
diff --git a/erts/test/erl_print_SUITE_data/integer_64_test.h b/erts/test/erl_print_SUITE_data/integer_64_test.h
index 0df09ded44..0c3e7b98a8 100644
--- a/erts/test/erl_print_SUITE_data/integer_64_test.h
+++ b/erts/test/erl_print_SUITE_data/integer_64_test.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/test/erl_print_SUITE_data/integer_test.h b/erts/test/erl_print_SUITE_data/integer_test.h
index 94c8d59897..b91f3622d6 100644
--- a/erts/test/erl_print_SUITE_data/integer_test.h
+++ b/erts/test/erl_print_SUITE_data/integer_test.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/test/erl_print_SUITE_data/snprintf_test.h b/erts/test/erl_print_SUITE_data/snprintf_test.h
index 0849b60562..c612a65521 100644
--- a/erts/test/erl_print_SUITE_data/snprintf_test.h
+++ b/erts/test/erl_print_SUITE_data/snprintf_test.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/test/erl_print_SUITE_data/string_test.h b/erts/test/erl_print_SUITE_data/string_test.h
index 32249ab6e9..0e257888e6 100644
--- a/erts/test/erl_print_SUITE_data/string_test.h
+++ b/erts/test/erl_print_SUITE_data/string_test.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl
index 5002836954..c21064fd3f 100644
--- a/erts/test/erlc_SUITE.erl
+++ b/erts/test/erlc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/erlc_SUITE_data/include/erl_test.hrl b/erts/test/erlc_SUITE_data/include/erl_test.hrl
index fd89cb2f60..e7d096d2c1 100644
--- a/erts/test/erlc_SUITE_data/include/erl_test.hrl
+++ b/erts/test/erlc_SUITE_data/include/erl_test.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/test/erlc_SUITE_data/src/erl_test_bad.erl b/erts/test/erlc_SUITE_data/src/erl_test_bad.erl
index fb62f835ca..b8c4ee2786 100644
--- a/erts/test/erlc_SUITE_data/src/erl_test_bad.erl
+++ b/erts/test/erlc_SUITE_data/src/erl_test_bad.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/test/erlc_SUITE_data/src/erl_test_missing_header.erl b/erts/test/erlc_SUITE_data/src/erl_test_missing_header.erl
index 4d6c42c803..f043fbebc4 100644
--- a/erts/test/erlc_SUITE_data/src/erl_test_missing_header.erl
+++ b/erts/test/erlc_SUITE_data/src/erl_test_missing_header.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/erlc_SUITE_data/src/erl_test_ok.erl b/erts/test/erlc_SUITE_data/src/erl_test_ok.erl
index 50fa063a94..a82eda95b3 100644
--- a/erts/test/erlc_SUITE_data/src/erl_test_ok.erl
+++ b/erts/test/erlc_SUITE_data/src/erl_test_ok.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/test/erlc_SUITE_data/src/start_ok.script b/erts/test/erlc_SUITE_data/src/start_ok.script
index 4cd89f0439..7ef97dc3f3 100644
--- a/erts/test/erlc_SUITE_data/src/start_ok.script
+++ b/erts/test/erlc_SUITE_data/src/start_ok.script
@@ -52,7 +52,6 @@
shell_default,
timer,
gen_fsm,
- pg,
unix,
dict,
pool,
@@ -156,7 +155,6 @@
{timer,1},
{gen_fsm,1},
{io_lib_pretty,1},
- {pg,1},
{slave,1},
{unix,1},
{dict,1},
diff --git a/erts/test/erlc_SUITE_data/src/yecc_test_bad.yrl b/erts/test/erlc_SUITE_data/src/yecc_test_bad.yrl
index 409718e24c..de17b903d6 100644
--- a/erts/test/erlc_SUITE_data/src/yecc_test_bad.yrl
+++ b/erts/test/erlc_SUITE_data/src/yecc_test_bad.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/test/erlc_SUITE_data/src/yecc_test_ok.yrl b/erts/test/erlc_SUITE_data/src/yecc_test_ok.yrl
index a96085ac2d..9433dcb90d 100644
--- a/erts/test/erlc_SUITE_data/src/yecc_test_ok.yrl
+++ b/erts/test/erlc_SUITE_data/src/yecc_test_ok.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/erts/test/erlexec_SUITE.erl b/erts/test/erlexec_SUITE.erl
index f5ea8f160a..9279872d25 100644
--- a/erts/test/erlexec_SUITE.erl
+++ b/erts/test/erlexec_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -462,13 +463,10 @@ split_emu_clt([A|As], Emu, Misc, Extra, extra = Type) ->
get_nodename(T) ->
- {A, B, C} = now(),
atom_to_list(T)
++ "-"
++ atom_to_list(?MODULE)
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ integer_to_list(erlang:system_time(seconds))
++ "-"
- ++ integer_to_list(C).
+ ++ integer_to_list(erlang:unique_integer([positive])).
diff --git a/erts/test/erlexec_SUITE_data/Makefile.src b/erts/test/erlexec_SUITE_data/Makefile.src
index 2a8decaa4b..145aaedd64 100644
--- a/erts/test/erlexec_SUITE_data/Makefile.src
+++ b/erts/test/erlexec_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/erlexec_SUITE_data/erlexec_tests.c b/erts/test/erlexec_SUITE_data/erlexec_tests.c
index 1d1ca881d9..569bf7bcc4 100644
--- a/erts/test/erlexec_SUITE_data/erlexec_tests.c
+++ b/erts/test/erlexec_SUITE_data/erlexec_tests.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/erts/test/ethread_SUITE.erl b/erts/test/ethread_SUITE.erl
index 24075286a8..4a40dbb11e 100644
--- a/erts/test/ethread_SUITE.erl
+++ b/erts/test/ethread_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/ethread_SUITE_data/Makefile.src b/erts/test/ethread_SUITE_data/Makefile.src
index ad2556f327..e8b9c79576 100644
--- a/erts/test/ethread_SUITE_data/Makefile.src
+++ b/erts/test/ethread_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/ethread_SUITE_data/ethread_tests.c b/erts/test/ethread_SUITE_data/ethread_tests.c
index 1d8083ef1f..b51771c736 100644
--- a/erts/test/ethread_SUITE_data/ethread_tests.c
+++ b/erts/test/ethread_SUITE_data/ethread_tests.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -1456,6 +1457,9 @@ do { \
ASSERT(ethr_ ## A ## _read ## B(&A) == 0x33333333); \
} while (0)
+ethr_atomic32_t atomic32;
+ethr_atomic_t atomic;
+ethr_dw_atomic_t dw_atomic;
static void
atomic_basic_test(void)
@@ -1464,8 +1468,6 @@ atomic_basic_test(void)
* Verify that each op does what it is expected
* to do for at least one input.
*/
- ethr_atomic32_t atomic32;
- ethr_atomic_t atomic;
print_line("AT_AINT32_MAX=%d",AT_AINT32_MAX);
print_line("AT_AINT32_MIN=%d",AT_AINT32_MIN);
@@ -1628,7 +1630,6 @@ atomic_basic_test(void)
/* Double word */
{
- ethr_dw_atomic_t dw_atomic;
ethr_dw_sint_t dw0, dw1;
dw0.sint[0] = 4711;
dw0.sint[1] = 4712;
diff --git a/erts/test/ignore_cores.erl b/erts/test/ignore_cores.erl
index 8b1ac0fe6c..13f34cd10f 100644
--- a/erts/test/ignore_cores.erl
+++ b/erts/test/ignore_cores.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/install_SUITE.erl b/erts/test/install_SUITE.erl
index f1d8dc2587..b380b064bd 100644
--- a/erts/test/install_SUITE.erl
+++ b/erts/test/install_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/nt_SUITE.erl b/erts/test/nt_SUITE.erl
index b255195a00..dbae8df7fe 100644
--- a/erts/test/nt_SUITE.erl
+++ b/erts/test/nt_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/nt_SUITE_data/Makefile.src b/erts/test/nt_SUITE_data/Makefile.src
index b26666252e..26da26b195 100644
--- a/erts/test/nt_SUITE_data/Makefile.src
+++ b/erts/test/nt_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/nt_SUITE_data/nt_info.c b/erts/test/nt_SUITE_data/nt_info.c
index 33cf046bb6..41d9a44c18 100644
--- a/erts/test/nt_SUITE_data/nt_info.c
+++ b/erts/test/nt_SUITE_data/nt_info.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl
index 2969383d66..69a0d19719 100644
--- a/erts/test/otp_SUITE.erl
+++ b/erts/test/otp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,7 +24,7 @@
init_per_suite/1,end_per_suite/1]).
-export([undefined_functions/1,deprecated_not_in_obsolete/1,
obsolete_but_not_deprecated/1,call_to_deprecated/1,
- call_to_size_1/1,strong_components/1,
+ call_to_size_1/1,call_to_now_0/1,strong_components/1,
erl_file_encoding/1,xml_file_encoding/1,runtime_dependencies/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -35,7 +36,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[undefined_functions, deprecated_not_in_obsolete,
obsolete_but_not_deprecated, call_to_deprecated,
- call_to_size_1, strong_components,
+ call_to_size_1, call_to_now_0, strong_components,
erl_file_encoding, xml_file_encoding,
runtime_dependencies].
@@ -287,48 +288,58 @@ call_to_deprecated(Config) when is_list(Config) ->
{comment,integer_to_list(length(DeprecatedCalls))++" calls to deprecated functions"}.
call_to_size_1(Config) when is_list(Config) ->
- Server = ?config(xref_server, Config),
-
%% Applications that do not call erlang:size/1:
Apps = [asn1,compiler,debugger,kernel,observer,parsetools,
runtime_tools,stdlib,tools,webtool],
+ not_recommended_calls(Config, Apps, {erlang,size,1}).
+
+call_to_now_0(Config) when is_list(Config) ->
+ %% Applications that do not call erlang:now/1:
+ Apps = [asn1,common_test,compiler,debugger,dialyzer,
+ gs,kernel,mnesia,observer,parsetools,reltool,
+ runtime_tools,sasl,stdlib,syntax_tools,
+ test_server,tools,webtool],
+ not_recommended_calls(Config, Apps, {erlang,now,0}).
+
+not_recommended_calls(Config, Apps, MFA) ->
+ Server = ?config(xref_server, Config),
- Fs = [{erlang,size,1}],
+ Fs = [MFA],
Q1 = io_lib:format("E || ~p : Fun", [Fs]),
- ?line {ok,AllCallsToSize1} = xref:q(Server, lists:flatten(Q1)),
+ {ok,AllCallsToMFA} = xref:q(Server, lists:flatten(Q1)),
Q2 = io_lib:format("E | ~p : App || ~p : Fun", [Apps,Fs]),
- ?line {ok,CallsToSize1} = xref:q(Server, lists:flatten(Q2)),
+ {ok,CallsToMFA} = xref:q(Server, lists:flatten(Q2)),
- case CallsToSize1 of
+ case CallsToMFA of
[] ->
ok;
_ ->
- io:format("These calls cause an error:~n"),
+ io:format("These calls are not allowed:\n"),
foreach(fun ({MFA1,MFA2}) ->
- io:format("~s calls soon to be deprecated ~s",
+ io:format("~s calls non-recommended ~s",
[format_mfa(MFA1),format_mfa(MFA2)])
- end, CallsToSize1)
+ end, CallsToMFA)
end,
- %% Enumerate calls to erlang:size/1 from other applications than
- %% the ones known not to call erlang:size/1:
- case AllCallsToSize1--CallsToSize1 of
+ %% Enumerate calls to MFA from other applications than
+ %% the ones known not to call MFA:
+ case AllCallsToMFA--CallsToMFA of
[] ->
ok;
Calls ->
- io:format("~n~nThese calls do not cause an error (yet):~n"),
+ io:format("~n~nThese calls are allowed for now:\n"),
foreach(fun ({MFA1,MFA2}) ->
- io:format("~s calls soon to be deprecated ~s",
+ io:format("~s calls non-recommended ~s",
[format_mfa(MFA1),format_mfa(MFA2)])
end, Calls)
end,
- case CallsToSize1 of
+ case CallsToMFA of
[] ->
ok;
_ ->
- ?line ?t:fail({length(CallsToSize1),calls_to_size_1})
+ ?t:fail({length(CallsToMFA),calls_to_size_1})
end.
strong_components(Config) when is_list(Config) ->
diff --git a/erts/test/run_erl_SUITE.erl b/erts/test/run_erl_SUITE.erl
index de05e6f206..328477d870 100644
--- a/erts/test/run_erl_SUITE.erl
+++ b/erts/test/run_erl_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/test/run_erl_SUITE_data/defuncter.pl b/erts/test/run_erl_SUITE_data/defuncter.pl
index 261f1b8061..666d4cca41 100644
--- a/erts/test/run_erl_SUITE_data/defuncter.pl
+++ b/erts/test/run_erl_SUITE_data/defuncter.pl
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/run_erl_SUITE_data/run_erl_test.pl b/erts/test/run_erl_SUITE_data/run_erl_test.pl
index 2155225e7f..b9e3f0a363 100644
--- a/erts/test/run_erl_SUITE_data/run_erl_test.pl
+++ b/erts/test/run_erl_SUITE_data/run_erl_test.pl
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/upgrade_SUITE.erl b/erts/test/upgrade_SUITE.erl
index 217056971e..83cd2359d8 100644
--- a/erts/test/upgrade_SUITE.erl
+++ b/erts/test/upgrade_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(upgrade_SUITE).
@@ -39,7 +40,7 @@
%% - typer requires hipe (in the .app file)
%% - erl_interface, jinterface support no upgrade
-define(appup_exclude,
- [dialyzer,hipe,typer,erl_interface,jinterface]).
+ [dialyzer,hipe,typer,erl_interface,jinterface,ose]).
init_per_suite(Config) ->
%% Check that a real release is running, not e.g. cerl
@@ -238,7 +239,10 @@ do_upgrade(FromVsn,FromApps,ToRel,ToApps,InstallDir) ->
[{"OTP upgrade test",FromVsn,_,permanent}] =
rpc:call(Node,release_handler,which_releases,[]),
- {ok,ToVsn} = rpc:call(Node,release_handler,unpack_release,[ToRel]),
+ ToRelName = filename:basename(ToRel),
+ copy_file(ToRel++".tar.gz",
+ filename:join([InstallDir,releases,ToRelName++".tar.gz"])),
+ {ok,ToVsn} = rpc:call(Node,release_handler,unpack_release,[ToRelName]),
[{"OTP upgrade test",ToVsn,_,unpacked},
{"OTP upgrade test",FromVsn,_,permanent}] =
rpc:call(Node,release_handler,which_releases,[]),
diff --git a/erts/test/upgrade_SUITE_data/start.src b/erts/test/upgrade_SUITE_data/start.src
index 70d1a322c9..7098a6919a 100644
--- a/erts/test/upgrade_SUITE_data/start.src
+++ b/erts/test/upgrade_SUITE_data/start.src
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/erts/test/utils/gccifier.c b/erts/test/utils/gccifier.c
index 7e4ffc7281..ca022eb390 100644
--- a/erts/test/utils/gccifier.c
+++ b/erts/test/utils/gccifier.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/erts/test/utils/gccifier.sh b/erts/test/utils/gccifier.sh
index 978aecf424..24b4d2f335 100755
--- a/erts/test/utils/gccifier.sh
+++ b/erts/test/utils/gccifier.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl
index 056561d3db..7f3260e4cb 100644
--- a/erts/test/z_SUITE.erl
+++ b/erts/test/z_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 9e5aa999e6..89c3ab8edb 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -3,21 +3,22 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
-VSN = 6.4.1
+VSN = 7.3.1
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/.gitignore b/lib/.gitignore
index 4125111ebd..b1da61706d 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -133,10 +133,12 @@
# mnesia
+/mnesia/doc/src/Mnesia_App_A.xml
/mnesia/doc/src/Mnesia_App_B.xml
/mnesia/doc/src/Mnesia_App_C.xml
/mnesia/doc/src/Mnesia_App_D.xml
/mnesia/doc/src/Mnesia_chap2.xml
+/mnesia/doc/src/Mnesia_chap3.xml
/mnesia/doc/src/Mnesia_chap4.xml
/mnesia/doc/src/Mnesia_chap5.xml
/mnesia/doc/src/Mnesia_chap7.xml
@@ -546,6 +548,8 @@ snmp/doc/intex.html
/syntax_tools/doc/src/erl_syntax.xml
/syntax_tools/doc/src/erl_syntax_lib.xml
/syntax_tools/doc/src/erl_tidy.xml
+/syntax_tools/doc/src/merl.xml
+/syntax_tools/doc/src/merl_transform.xml
/syntax_tools/doc/src/igor.xml
/syntax_tools/doc/src/prettypr.xml
diff --git a/lib/Makefile b/lib/Makefile
index 95170d8a56..34c2fe9a9e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/asn1/Makefile b/lib/asn1/Makefile
index 18e95a2471..1db7532024 100644
--- a/lib/asn1/Makefile
+++ b/lib/asn1/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile
index a7cd03f516..2b72e1a214 100644
--- a/lib/asn1/c_src/Makefile
+++ b/lib/asn1/c_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c
index 317a464060..828b55eec6 100644
--- a/lib/asn1/c_src/asn1_erl_nif.c
+++ b/lib/asn1/c_src/asn1_erl_nif.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile
index 3b3e1bd8f9..463e9231dc 100644
--- a/lib/asn1/doc/src/Makefile
+++ b/lib/asn1/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -48,7 +49,9 @@ XML_HTML_FILE = \
notes_history.xml
XML_CHAPTER_FILES = \
- asn1_ug.xml \
+ asn1_introduction.xml \
+ asn1_getting_started.xml \
+ asn1_overview.xml \
asn1_spec.xml \
notes.xml
diff --git a/lib/asn1/doc/src/asn1_getting_started.xml b/lib/asn1/doc/src/asn1_getting_started.xml
new file mode 100644
index 0000000000..ca7dc3a3cc
--- /dev/null
+++ b/lib/asn1/doc/src/asn1_getting_started.xml
@@ -0,0 +1,1291 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Getting Started</title>
+ <prepared>Kenneth Lundin</prepared>
+ <docno></docno>
+ <date>1999-03-25</date>
+ <rev>D</rev>
+ <file>asn1_getting_started.xml</file>
+ </header>
+
+ <section>
+ <title>Example</title>
+ <p>The following example demonstrates the basic functionality used to
+ run the Erlang ASN.1 compiler.</p>
+ <p>Create a file named <c>People.asn</c> containing the following:</p>
+ <pre>
+People DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+ Person ::= SEQUENCE {
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL
+ }
+END </pre>
+ <p>This file must be compiled before it can be used.
+ The ASN.1 compiler checks that the syntax is correct and that the
+ text represents proper ASN.1 code before generating an abstract
+ syntax tree. The code-generator then uses the abstract syntax
+ tree to generate code.</p>
+ <p>The generated Erlang files are placed in the current directory or
+ in the directory specified with option <c>{outdir,Dir}</c>.</p>
+ <p>The following shows how the compiler
+ can be called from the Erlang shell:</p>
+
+ <pre>
+1><input> asn1ct:compile("People", [ber]).</input>
+ok
+2> </pre>
+
+ <p>Option <c>verbose</c> can be added to get information
+ about the generated files:</p>
+ <pre>
+2><input> asn1ct:compile("People", [ber,verbose]).</input>
+Erlang ASN.1 compiling "People.asn"
+--{generated,"People.asn1db"}--
+--{generated,"People.hrl"}--
+--{generated,"People.erl"}--
+ok
+3> </pre>
+
+ <p>ASN.1 module <c>People</c> is now accepted and the
+ abstract syntax tree is saved in file <c>People.asn1db</c>.
+ The generated Erlang code is compiled using the Erlang compiler
+ and loaded into the Erlang runtime system. There is now an API
+ for <c>encode/2</c> and <c>decode/2</c> in module
+ <c>People</c>, which is called like:<br></br>
+ <c><![CDATA['People':encode(<Type name>, <Value>)]]></c>
+ <br></br>
+ or<br></br>
+<c><![CDATA['People':decode(<Type name>, <Value>)]]></c></p>
+
+ <p>Assume that there is a network
+ application that receives instances of the ASN.1 defined
+ type <c>Person</c>, modifies, and sends them back again:</p>
+
+ <code type="none">
+receive
+ {Port,{data,Bytes}} ->
+ case 'People':decode('Person',Bytes) of
+ {ok,P} ->
+ {ok,Answer} = 'People':encode('Person',mk_answer(P)),
+ Port ! {self(),{command,Answer}};
+ {error,Reason} ->
+ exit({error,Reason})
+ end
+ end, </code>
+ <p>In this example, a series of bytes is received from an
+ external source and the bytes are then decoded into a valid
+ Erlang term. This was achieved with the call
+ <c>'People':decode('Person',Bytes)</c>, which returned
+ an Erlang value of the ASN.1 type <c>Person</c>. Then an answer was
+ constructed and encoded using
+ <c>'People':encode('Person',Answer)</c>, which takes an
+ instance of a defined ASN.1 type and transforms it to a
+ binary according to the BER or PER encoding rules.</p>
+ <p>The encoder and decoder can also be run from the shell:</p>
+ <pre>
+2> <input>Rockstar = {'Person',"Some Name",roving,50}.</input>
+{'Person',"Some Name",roving,50}
+3> <input>{ok,Bin} = 'People':encode('Person',Rockstar).</input>
+{ok,&lt;&lt;243,17,19,9,83,111,109,101,32,78,97,109,101,2,1,2,
+ 2,1,50&gt;&gt;}
+4> <input>{ok,Person} = 'People':decode('Person',Bin).</input>
+{ok,{'Person',"Some Name",roving,50}}
+5> </pre>
+
+ <section>
+ <title>Module Dependencies</title>
+ <p>It is common that ASN.1 modules import defined types, values, and
+ other entities from another ASN.1 module.</p>
+ <p>Earlier versions of the ASN.1 compiler required that modules
+ that were imported from had to be compiled before the module
+ that imported. This caused problems when ASN.1 modules had circular
+ dependencies.</p>
+ <p>Referenced modules are now parsed when the compiler finds an
+ entity that is imported. No code is generated for
+ the referenced module. However, the compiled modules rely on
+ that the referenced modules are also compiled.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>ASN.1 Application User Interface</title>
+ <p>The <c>ASN.1</c> application provides the following two
+ separate user interfaces:</p>
+ <list type="bulleted">
+ <item>
+ <p>The module <c>asn1ct</c>, which provides the compile-time functions
+ (including the compiler)</p>
+ </item>
+ <item>
+ <p>The module <c>asn1rt_nif</c>, which provides the runtime functions
+ for the ASN.1 decoder for the BER back end</p>
+ </item>
+ </list>
+ <p>The reason for this division of the interfaces into compile-time
+ and runtime
+ is that only runtime modules (<c>asn1rt*</c>) need to be loaded in
+ an embedded system.
+ </p>
+
+ <section>
+ <title>Compile-Time Functions</title>
+ <p>The ASN.1 compiler can be started directly from the command line
+ by the <c>erlc</c> program. This is convenient when compiling
+ many ASN.1 files from the command line or when using Makefiles.
+ Some examples of how the <c>erlc</c> command can be used to start
+ the ASN.1 compiler:</p>
+ <pre>
+erlc Person.asn
+erlc -bper Person.asn
+erlc -bber ../Example.asn
+erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn</pre>
+ <p>Useful options for the ASN.1 compiler:</p>
+ <taglist>
+ <tag><c>-b[ber | per | uper]</c></tag>
+ <item>
+ <p>Choice of encoding rules. If omitted, <c>ber</c> is the
+ default.</p>
+ </item>
+ <tag><c>-o OutDirectory</c></tag>
+ <item>
+ <p>Where to put the generated files. Default is the current
+ directory.</p>
+ </item>
+ <tag><c>-I IncludeDir</c></tag>
+ <item>
+ <p>Where to search for <c>.asn1db</c> files and ASN.1
+ source specs to resolve references to other
+ modules. This option can be repeated many times if there
+ are several places to search in. The compiler
+ searches the current directory first.</p>
+ </item>
+ <tag><c>+der</c></tag>
+ <item>
+ <p>DER encoding rule. Only when using option <c>-ber</c>.</p>
+ </item>
+ <tag><c>+asn1config</c></tag>
+ <item>
+ <p>This functionality works together with option
+ <c>ber</c>. It enables the specialized decodes, see Section
+ <seealso marker="asn1_spec">Specialized Decode</seealso>.</p>
+ </item>
+ <tag><c>+undec_rest</c></tag>
+ <item>
+ <p>A buffer that holds a message being decoded can also have
+ trailing bytes. If those trailing bytes are important, they
+ can be returned along with the decoded value by compiling
+ the ASN.1 specification with option <c>+undec_rest</c>.
+ The return value from the decoder is
+ <c>{ok,Value,Rest}</c> where <c>Rest</c> is a binary
+ containing the trailing bytes.</p>
+ </item>
+ <tag><c>+'Any Erlc Option'</c></tag>
+ <item>
+ <p>Any option can be added to the Erlang compiler when
+ compiling the generated Erlang files. Any option
+ unrecognized by the ASN.1 compiler is passed to the
+ Erlang compiler.</p>
+ </item>
+ </taglist>
+ <p>For a complete description of <c>erlc</c>, see
+ ERTS Reference Manual.</p>
+ <p>The compiler and other compile-time functions can also be started
+ from the Erlang shell. Here follows a brief
+ description of the primary functions. For a
+ complete description of each function, see module <c>asn1ct</c> in
+ the <seealso marker="asn1ct">ASN.1 Reference Manual</seealso>.</p>
+ <p>The compiler is started by <c>asn1ct:compile/1</c> with
+ default options, or <c>asn1ct:compile/2</c> if explicit options
+ are given.</p>
+ <p>Example:</p>
+ <pre>
+asn1ct:compile("H323-MESSAGES.asn1"). </pre>
+ <p>This equals:</p>
+ <pre>
+asn1ct:compile("H323-MESSAGES.asn1",[ber]). </pre>
+ <p>If PER encoding is wanted:</p>
+ <pre>
+asn1ct:compile("H323-MESSAGES.asn1",[per]). </pre>
+ <p>The generic encode and decode functions can be called
+ as follows:</p>
+ <pre>
+'H323-MESSAGES':encode('SomeChoiceType',{call,&lt;&lt;"octetstring"&gt;&gt;}).
+'H323-MESSAGES':decode('SomeChoiceType',Bytes). </pre>
+ </section>
+
+ <section>
+ <title>Runtime Functions</title>
+ <p>When an ASN.1 specification is compiled with option <c>ber</c>,
+ the <c>asn1rt_nif</c> module and the NIF library in
+ <c>asn1/priv_dir</c> are needed at runtime.</p>
+ <p>By calling function <c>info/0</c> in a generated module, you
+ get information about which compiler options were used.</p>
+ </section>
+
+ <section>
+ <title>Errors</title>
+ <p>Errors detected at
+ compile-time are displayed on the screen together with line
+ numbers indicating where in the source file the respective error
+ was detected. If no errors are found, an Erlang ASN.1 module is
+ created.</p>
+ <p>The runtime encoders and decoders execute within a catch and
+ return <c>{ok, Data}</c> or
+ <c>{error, {asn1, Description}}</c> where
+ <c>Description</c> is
+ an Erlang term describing the error.</p>
+ </section>
+ </section>
+
+ <section>
+ <marker id="inlineExamples"></marker>
+ <title>Multi-File Compilation</title>
+ <p>There are various reasons for using multi-file compilation:</p>
+ <list type="bulleted">
+ <item>To choose the name for the generated module, for
+ example, because you need to compile the same specs for
+ different encoding rules.</item>
+ <item>You want only one resulting module.</item>
+ </list>
+ <p>Specify which ASN.1 specs to compile in a module with extension
+ <c>.set.asn</c>. Choose a module name and provide the
+ names of the ASN.1 specs. For example, if you have the specs
+ <c>File1.asn</c>, <c>File2.asn</c>, and <c>File3.asn</c>, your
+ module <c>MyModule.set.asn</c> looks as follows:</p>
+ <pre>
+File1.asn
+File2.asn
+File3.asn </pre>
+ <p>If you compile with the following, the result is one merged
+ module <c>MyModule.erl</c> with the generated code from the three
+ ASN.1 specs:</p>
+ <code type="none">
+~> erlc MyModule.set.asn </code>
+ </section>
+
+ <section>
+ <title>Remark about Tags</title>
+
+ <p>Tags used to be important for all users of ASN.1, because it
+ was necessary to add tags manually to certain constructs in order
+ for the ASN.1 specification to be valid. Example of
+ an old-style specification:</p>
+
+ <pre>
+Tags DEFINITIONS ::=
+BEGIN
+ Afters ::= CHOICE { cheese [0] IA5String,
+ dessert [1] IA5String }
+END </pre>
+
+ <p>Without the tags (the numbers in square brackets) the ASN.1
+ compiler refused to compile the file.</p>
+
+ <p>In 1994 the global tagging mode <c>AUTOMATIC TAGS</c> was introduced.
+ By putting <c>AUTOMATIC TAGS</c> in the module header, the ASN.1
+ compiler automatically adds tags when needed. The following is the
+ same specification in <c>AUTOMATIC TAGS</c> mode:</p>
+
+ <pre>
+Tags DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+ Afters ::= CHOICE { cheese IA5String,
+ dessert IA5String }
+END </pre>
+
+ <p>Tags are not mentioned any more in this User's Guide.</p>
+ </section>
+
+ <section>
+ <marker id="ASN1Types"></marker>
+ <title>ASN.1 Types</title>
+ <p>This section describes the ASN.1 types including their
+ functionality, purpose, and how values are assigned in Erlang.
+ </p>
+ <p>ASN.1 has both primitive and constructed types:</p>
+ <p></p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>Primitive Types</em></cell>
+ <cell align="left" valign="middle"><em>Constructed Types</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#BOOLEAN">BOOLEAN</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#SEQUENCE">SEQUENCE</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#INTEGER">INTEGER</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#SET">SET</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#REAL">REAL</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#CHOICE">CHOICE</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#NULL">NULL</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#SOF">SET OF and SEQUENCE OF</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#ENUMERATED">ENUMERATED</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#ANY">ANY</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#BIT STRING">BIT STRING</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#ANY">ANY DEFINED BY</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#OCTET STRING">OCTET STRING</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#NegotiationTypes">EXTERNAL</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#Character Strings">Character Strings</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#NegotiationTypes">EMBEDDED PDV</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#OBJECT IDENTIFIER">OBJECT IDENTIFIER</seealso></cell>
+ <cell align="left" valign="middle"><seealso marker="#NegotiationTypes">CHARACTER STRING</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#Object Descriptor">Object Descriptor</seealso></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><seealso marker="#The TIME types">TIME Types</seealso></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <tcaption>Supported ASN.1 Types</tcaption>
+ </table>
+ <marker id="TypeNameValue"></marker>
+ <note>
+ <p>The values of each ASN.1 type have their own representation in Erlang, as
+ described in the following sections. Users must provide
+ these values for encoding according to the representation, as shown in the
+ following example:</p>
+ </note>
+ <pre>
+Operational ::= BOOLEAN --ASN.1 definition </pre>
+ <p>In Erlang code it can look as follows:</p>
+ <pre>
+Val = true,
+{ok,Bytes} = MyModule:encode('Operational', Val), </pre>
+
+ <section>
+ <marker id="BOOLEAN"></marker>
+ <title>BOOLEAN</title>
+ <p>Booleans in ASN.1 express values that can be either
+ <c>TRUE</c> or <c>FALSE</c>.
+ The meanings assigned to <c>TRUE</c> and <c>FALSE</c> are outside the scope
+ of this text.</p>
+ <p>In ASN.1 it is possible to have:</p>
+ <pre>
+Operational ::= BOOLEAN</pre>
+ <p>Assigning a value to type <c>Operational</c> in Erlang is possible by
+ using the following Erlang code:</p>
+ <code type="erl">
+Myvar1 = true,</code>
+ <p>Thus, in Erlang the atoms <c>true</c> and <c>false</c> are used
+ to encode a boolean value.</p>
+ </section>
+
+ <section>
+ <marker id="INTEGER"></marker>
+ <title>INTEGER</title>
+ <p>ASN.1 itself specifies indefinitely large integers. Erlang
+ systems with version 4.3 and higher support very large
+ integers, in practice indefinitely large integers.</p>
+ <p>The concept of subtyping can be applied to integers and
+ to other ASN.1 types. The details of subtyping are not
+ explained here; for more information, see X.680. Various
+ syntaxes are allowed when defining a type as an integer:</p>
+ <pre>
+T1 ::= INTEGER
+T2 ::= INTEGER (-2..7)
+T3 ::= INTEGER (0..MAX)
+T4 ::= INTEGER (0&lt;..MAX)
+T5 ::= INTEGER (MIN&lt;..-99)
+T6 ::= INTEGER {red(0),blue(1),white(2)}</pre>
+ <p>The Erlang representation of an ASN.1 <c>INTEGER</c> is an integer or
+ an atom if a <c>Named Number List</c> (see <c>T6</c> in the previous
+ list) is specified.</p>
+ <p>The following is an example of Erlang code that assigns values for the
+ types in the previous list:</p>
+ <pre>
+T1value = 0,
+T2value = 6,
+T6value1 = blue,
+T6value2 = 0,
+T6value3 = white</pre>
+ <p>These Erlang variables are now bound to valid instances of
+ ASN.1 defined types. This style of value can be passed directly
+ to the encoder for transformation into a series of bytes.</p>
+ <p>The decoder returns an atom if the value corresponds to a
+ symbol in the <c>Named Number List</c>.</p>
+ </section>
+
+ <section>
+ <marker id="REAL"></marker>
+ <title>REAL</title>
+ <p>The following ASN.1 type is used for real numbers:</p>
+ <pre>
+R1 ::= REAL</pre>
+ <p>It is assigned a value in Erlang as follows:</p>
+ <pre>
+R1value1 = "2.14",
+R1value2 = {256,10,-2},</pre>
+ <p>In the last line, notice that the tuple {256,10,-2} is the real number
+ 2.56 in a special notation, which encodes faster than simply
+ stating the number as <c>"2.56"</c>. The arity three tuple is
+ <c>{Mantissa,Base,Exponent}</c>, that is, Mantissa * Base^Exponent.</p>
+ </section>
+
+ <section>
+ <marker id="NULL"></marker>
+ <title>NULL</title>
+ <p>The type <c>NULL</c> is suitable where supply and recognition of a value
+ is important but the actual value is not.</p>
+ <pre>
+Notype ::= NULL</pre>
+ <p>This type is assigned in Erlang as follows:</p>
+ <pre>
+N1 = 'NULL',</pre>
+ <p>The actual value is the quoted atom <c>'NULL'</c>.</p>
+ </section>
+
+ <section>
+ <marker id="ENUMERATED"></marker>
+ <title>ENUMERATED</title>
+ <p>The type <c>ENUMERATED</c> can be used when the value you want to
+ describe can only take one of a set of predefined values. Example:</p>
+ <pre>
+DaysOfTheWeek ::= ENUMERATED {
+ sunday(1),monday(2),tuesday(3),
+ wednesday(4),thursday(5),friday(6),saturday(7) }</pre>
+ <p>For example, to assign a weekday value in Erlang, use the same atom
+ as in the <c>Enumerations</c> of the type definition:</p>
+ <pre>
+Day1 = saturday,</pre>
+ <p>The enumerated type is similar to an integer type, when
+ defined with a set of predefined values. The difference is that
+ an enumerated type can only have specified
+ values, whereas an integer can have any value.</p>
+ </section>
+
+ <section>
+ <marker id="BIT STRING"></marker>
+ <title>BIT STRING</title>
+ <p>The type <c>BIT STRING</c> can be used to model information that
+ is made up of arbitrary length series of bits. It is intended
+ to be used for selection of flags, not for binary files.</p>
+ <p>In ASN.1, <c>BIT STRING</c> definitions can look as follows:</p>
+ <pre>
+Bits1 ::= BIT STRING
+Bits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}</pre>
+ <p>The following two notations are available for representation of <c>BIT
+ STRING</c> values in Erlang and as input to the encode functions:</p>
+ <list type="ordered">
+ <item>A bitstring. By default, a <c>BIT STRING</c> with no
+ symbolic names is decoded to an Erlang bitstring.</item>
+ <item>A list of atoms corresponding to atoms in the <c>NamedBitList</c>
+ in the <c>BIT STRING</c> definition. A <c>BIT STRING</c> with symbolic
+ names is always decoded to the format shown in the following
+ example:</item>
+ </list>
+ <pre>
+Bits1Val1 = &lt;&lt;0:1,1:1,0:1,1:1,1:1&gt;&gt;,
+Bits2Val1 = [gnu,punk],
+Bits2Val2 = &lt;&lt;2#1110:4&gt;&gt;,
+Bits2Val3 = [bar,gnu,gnome],</pre>
+ <p><c>Bits2Val2</c> and <c>Bits2Val3</c> denote the same value.</p>
+ <p><c>Bits2Val1</c> is assigned symbolic values. The assignment means
+ that the bits corresponding to <c>gnu</c> and <c>punk</c>, that is, bits
+ 2 and 14 are set to 1, and the rest are set to 0. The symbolic values
+ are shown as a list of values. If a named value, which is not
+ specified in the type definition, is shown, a runtime error occurs.</p>
+ <p><c>BIT STRING</c>s can also be subtyped with, for example, a <c>SIZE</c>
+ specification:</p>
+ <pre>
+Bits3 ::= BIT STRING (SIZE(0..31)) </pre>
+ <p>This means that no bit higher than 31 can be set.</p>
+
+ <section>
+ <title>Deprecated Representations for BIT STRING</title>
+ <p>In addition to the representations described earlier, the
+ following deprecated representations are available if the
+ specification has been compiled with option
+ <c>legacy_erlang_types</c>:</p>
+ <list type="ordered">
+ <item>Aa a list of binary digits (0 or 1). This format is
+ accepted as input to the encode functions, and a <c>BIT STRING</c>
+ is decoded to this format if option
+ <em>legacy_bit_string</em> is given.
+ </item>
+ <item>As <c>{Unused,Binary}</c> where <c>Unused</c> denotes
+ how many trailing zero-bits 0-7 that are unused in the
+ least significant byte in <c>Binary</c>. This format is
+ accepted as input to the encode functions, and a <c>BIT
+ STRING</c> is decoded to this format if
+ <c>compact_bit_string</c> has been given.
+ </item>
+ <item>As a hexadecimal number (or an integer). Avoid this
+ as it is easy to misinterpret a <c>BIT
+ STRING</c> value in this format.
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <marker id="OCTET STRING"></marker>
+ <title>OCTET STRING</title>
+ <p><c>OCTET STRING</c> is the simplest of all ASN.1 types. <c>OCTET
+ STRING</c> only moves or transfers, for example, binary files or other
+ unstructured information complying with two rules: the
+ bytes consist of octets and encoding is not required.</p>
+ <p>It is possible to have the following ASN.1 type definitions:</p>
+ <pre>
+O1 ::= OCTET STRING
+O2 ::= OCTET STRING (SIZE(28)) </pre>
+ <p>With the following example assignments in Erlang:</p>
+ <pre>
+O1Val = &lt;&lt;17,13,19,20,0,0,255,254&gt;&gt;,
+O2Val = &lt;&lt;"must be exactly 28 chars...."&gt;&gt;,</pre>
+ <p>By default, an <c>OCTET STRING</c> is always represented as
+ an Erlang binary. If the specification has been compiled with
+ option <c>legacy_erlang_types</c>, the encode functions
+ accept both lists and binaries, and the decode functions
+ decode an <c>OCTET STRING</c> to a list.</p>
+ </section>
+
+ <section>
+ <marker id="Character Strings"></marker>
+ <title>Character Strings</title>
+ <p>ASN.1 supports a wide variety of character sets. The main difference
+ between an <c>OCTET STRING</c> and a character string is that the
+ <c>OCTET STRING</c> has no imposed semantics on the bytes delivered.</p>
+ <p>However, when using, for example, IA5String (which closely
+ resembles ASCII), byte 65 (in decimal
+ notation) <em>means</em> character 'A'.
+ </p>
+ <p>For example, if a defined type is to be a VideotexString and
+ an octet is received with the unsigned integer value <c>X</c>,
+ the octet is to be interpreted as specified in standard
+ ITU-T T.100, T.101.
+ </p>
+ <p>The ASN.1 to Erlang compiler
+ does not determine the correct interpretation of each BER
+ string octet value with different character strings. The
+ application is responsible for interpretation
+ of octets. Therefore, from the BER
+ string point of view, octets are very similar to
+ character strings and are compiled in the same way.
+ </p>
+ <p>When PER is
+ used, there is a significant difference in the encoding scheme
+ between <c>OCTET STRING</c>s and other strings. The constraints
+ specified for a type are especially important for PER, where
+ they affect the encoding.
+ </p>
+ <p>Examples:</p>
+ <pre>
+Digs ::= NumericString (SIZE(1..3))
+TextFile ::= IA5String (SIZE(0..64000)) </pre>
+ <p>The corresponding Erlang assignments:</p>
+ <pre>
+DigsVal1 = "456",
+DigsVal2 = "123",
+TextFileVal1 = "abc...xyz...",
+TextFileVal2 = [88,76,55,44,99,121 .......... a lot of characters here ....]</pre>
+ <p>The Erlang representation for "BMPString" and
+ "UniversalString" is either a list of ASCII values or a list
+ of quadruples. The quadruple representation associates to the
+ Unicode standard representation of characters. The ASCII
+ characters are all represented by quadruples beginning with
+ three zeros like {0,0,0,65} for character 'A'. When
+ decoding a value for these strings, the result is a list of
+ quadruples, or integers when the value is an ASCII character.</p>
+
+ <p>The following example shows how it works. Assume the following
+ specification is in file <c>PrimStrings.asn1</c>:</p>
+ <pre>
+PrimStrings DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+ BMP ::= BMPString
+END </pre>
+
+ <p>Encoding and decoding some strings:</p>
+
+ <pre>
+1> <input>asn1ct:compile('PrimStrings', [ber]).</input>
+ok
+2> <input>{ok,Bytes1} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,45,56}]).</input>
+{ok,&lt;&lt;30,4,53,54,45,56>>}
+3> <input>'PrimStrings':decode('BMP', Bytes1).</input>
+{ok,[{0,0,53,53},{0,0,45,56}]}
+4> <input>{ok,Bytes2} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,0,65}]).</input>
+{ok,&lt;&lt;30,4,53,53,0,65>>}
+5> <input>'PrimStrings':decode('BMP', Bytes2).</input>
+{ok,[{0,0,53,53},65]}
+6> <input>{ok,Bytes3} = 'PrimStrings':encode('BMP', "BMP string").</input>
+{ok,&lt;&lt;30,20,0,66,0,77,0,80,0,32,0,115,0,116,0,114,0,105,0,110,0,103>>}
+7> <input>'PrimStrings':decode('BMP', Bytes3).</input>
+{ok,"BMP string"} </pre>
+
+ <p>Type UTF8String is represented as a UTF-8 encoded binary in
+ Erlang. Such binaries can be created directly using the binary syntax
+ or by converting from a list of Unicode code points using function
+ <c>unicode:characters_to_binary/1</c>.</p>
+
+ <p>The following shows examples of how UTF-8 encoded binaries can
+ be created and manipulated:</p>
+ <pre>
+1> <input>Gs = "Мой маленький Гном".</input>
+[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
+ 1081,32,1043,1085,1086,1084]
+2> <input>Gbin = unicode:characters_to_binary(Gs).</input>
+&lt;&lt;208,156,208,190,208,185,32,208,188,208,176,208,187,208,
+ 181,208,189,209,140,208,186,208,184,208,185,32,208,147,
+ 208,...>>
+3> <input>Gbin = &lt;&lt;"Мой маленький Гном"/utf8>>.</input>
+&lt;&lt;208,156,208,190,208,185,32,208,188,208,176,208,187,208,
+ 181,208,189,209,140,208,186,208,184,208,185,32,208,147,
+ 208,...>>
+4> <input>Gs = unicode:characters_to_list(Gbin).</input>
+[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
+ 1081,32,1043,1085,1086,1084]</pre>
+
+ <p>For details, see the <seealso marker="stdlib:unicode">unicode</seealso>
+ module in <c>stdlib</c>.</p>
+
+ <p>In the following example, this ASN.1 specification is used:</p>
+ <pre>
+UTF DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+ UTF ::= UTF8String
+END </pre>
+
+ <p>Encoding and decoding a string with Unicode characters:</p>
+
+ <pre>
+5> <input>asn1ct:compile('UTF', [ber]).</input>
+ok
+6> <input>{ok,Bytes1} = 'UTF':encode('UTF', &lt;&lt;"Гном"/utf8>>).</input>
+{ok,&lt;&lt;12,8,208,147,208,189,208,190,208,188>>}
+7> <input>{ok,Bin1} = 'UTF':decode('UTF', Bytes1).</input>
+{ok,&lt;&lt;208,147,208,189,208,190,208,188>>}
+8> <input>io:format("~ts\n", [Bin1]).</input>
+Гном
+ok
+9> <input>unicode:characters_to_list(Bin1).</input>
+[1043,1085,1086,1084] </pre>
+ </section>
+
+ <section>
+ <marker id="OBJECT IDENTIFIER"></marker>
+ <title>OBJECT IDENTIFIER</title>
+ <p>The type <c>OBJECT IDENTIFIER</c> is used whenever a unique identity is
+ required. An ASN.1 module, a transfer syntax, and so on, is identified
+ with an <c>OBJECT IDENTIFIER</c>. Assume the following example:</p>
+ <pre>
+Oid ::= OBJECT IDENTIFIER</pre>
+ <p>Therefore, the following example is a valid Erlang instance of
+ type 'Oid':</p>
+ <pre>
+OidVal1 = {1,2,55},</pre>
+ <p>The <c>OBJECT IDENTIFIER</c> value is simply a tuple with the
+ consecutive values, which must be integers.
+ </p>
+ <p>The first value is limited to the values 0, 1, or 2. The
+ second value must be in the range 0..39 when the first value
+ is 0 or 1.
+ </p>
+ <p>The <c>OBJECT IDENTIFIER</c> is an important type and it is
+ widely used within different standards to identify various
+ objects uniquely. Dubuisson: ASN.1 - Communication Between
+ Heterogeneous Systems includes an
+ easy-to-understand description of the use of
+ <c>OBJECT IDENTIFIER</c>.</p>
+ </section>
+
+ <section>
+ <marker id="Object Descriptor"></marker>
+ <title>Object Descriptor</title>
+ <p>Values of this type can be assigned a value as an ordinary string
+ as follows:</p>
+
+ <pre>
+ "This is the value of an Object descriptor"</pre>
+ </section>
+
+ <section>
+ <marker id="The TIME types"></marker>
+ <title>TIME Types</title>
+ <p>Two time types are defined within ASN.1: Generalized
+ Time and Universal Time Coordinated (UTC). Both are assigned a
+ value as an ordinary string within double quotes, for example,
+ "19820102070533.8".</p>
+ <p>For DER encoding, the compiler does not check the validity
+ of the time values. The DER requirements upon those strings are
+ regarded as a matter for the application to fulfill.</p>
+ </section>
+
+ <section>
+ <marker id="SEQUENCE"></marker>
+ <title>SEQUENCE</title>
+ <p>The structured types of ASN.1 are constructed from other types
+ in a manner similar to the concepts of array and struct in C.</p>
+ <p>A <c>SEQUENCE</c> in ASN.1 is
+ comparable with a struct in C and a record in Erlang.
+ A <c>SEQUENCE</c> can be defined as follows:</p>
+ <pre>
+Pdu ::= SEQUENCE {
+ a INTEGER,
+ b REAL,
+ c OBJECT IDENTIFIER,
+ d NULL } </pre>
+ <p>This is a 4-component structure called <c>Pdu</c>. The record format
+ is the major format for representation of <c>SEQUENCE</c> in Erlang.
+ For each <c>SEQUENCE</c> and <c>SET</c> in an ASN.1 module an Erlang
+ record declaration is generated. For <c>Pdu</c>, a record
+ like the following is defined:</p>
+ <pre>
+-record('Pdu',{a, b, c, d}). </pre>
+ <p>The record declarations for a module <c>M</c> are placed in a
+ separate <c>M.hrl</c> file.</p>
+ <p>Values can be assigned in Erlang as follows:</p>
+ <pre>
+MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}. </pre>
+ <p>The decode functions return a record as result when decoding
+ a <c>SEQUENCE</c> or a <c>SET</c>.</p>
+
+ <p>A <c>SEQUENCE</c> and a <c>SET</c> can contain a component
+ with a <c>DEFAULT</c> keyword followed by the actual value, which
+ is the default value. The <c>DEFAULT</c> keyword means that the
+ application doing the encoding can omit encoding of the value, which
+ results in fewer bytes to send to the receiving application.</p>
+
+ <p>An application can use the atom <c>asn1_DEFAULT</c> to indicate
+ that the encoding is to be omitted for that position in
+ the <c>SEQUENCE</c>.</p>
+
+ <p>Depending on the encoding rules, the encoder can also compare
+ the given value to the default value and automatically omit the
+ encoding if the values are equal. How much effort the encoder makes
+ to compare the values depends on the encoding rules. The DER
+ encoding rules forbid encoding a value equal to the default value,
+ so it has a more thorough and time-consuming comparison than the
+ encoders for the other encoding rules.</p>
+
+ <p>In the following example, this ASN.1 specification is used:</p>
+ <pre>
+File DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+Seq1 ::= SEQUENCE {
+ a INTEGER DEFAULT 1,
+ b Seq2 DEFAULT {aa TRUE, bb 15}
+}
+
+Seq2 ::= SEQUENCE {
+ aa BOOLEAN,
+ bb INTEGER
+}
+
+Seq3 ::= SEQUENCE {
+ bs BIT STRING {a(0), b(1), c(2)} DEFAULT {a, c}
+}
+END </pre>
+ <p>Example where the BER encoder is able to omit encoding
+ of the default values:</p>
+ <pre>
+1> <input>asn1ct:compile('File', [ber]).</input>
+ok
+2> <input>'File':encode('Seq1', {'Seq1',asn1_DEFAULT,asn1_DEFAULT}).</input>
+{ok,&lt;&lt;48,0>>}
+3> <input>'File':encode('Seq1', {'Seq1',1,{'Seq2',true,15}}).</input>
+{ok,&lt;&lt;48,0>>} </pre>
+
+ <p>Example with a named <c>BIT STRING</c> where the BER
+ encoder does not omit the encoding:</p>
+ <pre>
+4> <input>'File':encode('Seq3', {'Seq3',asn1_DEFAULT).</input>
+{ok,&lt;&lt;48,0>>}
+5> <input>'File':encode('Seq3', {'Seq3',&lt;&lt;16#101:3>>).</input>
+{ok,&lt;&lt;48,4,128,2,5,160>>} </pre>
+
+ <p>The DER encoder omits the encoding for the same <c>BIT STRING</c>:</p>
+ <pre>
+6> <input>asn1ct:compile('File', [ber,der]).</input>
+ok
+7> <input>'File':encode('Seq3', {'Seq3',asn1_DEFAULT).</input>
+{ok,&lt;&lt;48,0>>}
+8> <input>'File':encode('Seq3', {'Seq3',&lt;&lt;16#101:3>>).</input>
+{ok,&lt;&lt;48,0>>} </pre>
+ </section>
+
+ <section>
+ <marker id="SET"></marker>
+ <title>SET</title>
+ <p>In Erlang, the <c>SET</c> type is used exactly as <c>SEQUENCE</c>.
+ Notice that if BER or DER encoding rules are used, decoding a
+ <c>SET</c> is slower than decoding a <c>SEQUENCE</c> because the
+ components must be sorted.</p>
+ </section>
+
+ <section>
+ <title>Extensibility for SEQUENCE and SET</title>
+ <p>When a <c>SEQUENCE</c> or <c>SET</c> contains an extension marker
+ and extension components as the following, the type can get more
+ components in newer versions of the ASN.1 spec:</p>
+ <pre>
+SExt ::= SEQUENCE {
+ a INTEGER,
+ ...,
+ b BOOLEAN }</pre>
+ <p>In this case it has got a new
+ component <c>b</c>. Thus, incoming messages that are decoded
+ can have more or fever components than this one.
+ </p>
+ <p>The component <c>b</c> is treated as
+ an original component when encoding a message. In this case, as
+ it is not an optional element, it must be encoded.
+ </p>
+ <p>During decoding, the <c>b</c> field of the record gets the decoded
+ value of the <c>b</c>
+ component, if present, otherwise the value <c>asn1_NOVALUE</c>.</p>
+ </section>
+
+ <section>
+ <marker id="CHOICE"></marker>
+ <title>CHOICE</title>
+ <p>The type <c>CHOICE</c> is a space saver and is similar to the
+ concept of a 'union' in C.</p>
+ <p>Assume the following:</p>
+ <pre>
+SomeModuleName DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+T ::= CHOICE {
+ x REAL,
+ y INTEGER,
+ z OBJECT IDENTIFIER }
+END </pre>
+ <p>It is then possible to assign values as follows:</p>
+ <pre>
+TVal1 = {y,17},
+TVal2 = {z,{0,1,2}},</pre>
+ <p>A <c>CHOICE</c> value is always represented as the tuple
+ <c>{ChoiceAlternative, Val}</c> where <c>ChoiceAlternative</c>
+ is an atom denoting the selected choice alternative.
+ </p>
+
+ <section>
+ <title>Extensible CHOICE</title>
+ <p>When a <c>CHOICE</c> contains an extension marker and the
+ decoder detects an unknown alternative of the <c>CHOICE</c>,
+ the value is represented as follows:</p>
+ <pre>
+{asn1_ExtAlt, BytesForOpenType}</pre>
+ <p>Here <c>BytesForOpenType</c> is a list of bytes constituting the
+ encoding of the "unknown" <c>CHOICE</c> alternative.</p>
+ </section>
+ </section>
+
+ <section>
+ <marker id="SOF"></marker>
+ <title>SET OF and SEQUENCE OF</title>
+ <p>The types <c>SET OF</c> and <c>SEQUENCE OF</c> correspond
+ to the concept of an array
+ in several programming languages. The Erlang syntax for
+ both types is straightforward, for example:</p>
+ <pre>
+Arr1 ::= SET SIZE (5) OF INTEGER (4..9)
+Arr2 ::= SEQUENCE OF OCTET STRING </pre>
+ <p>In Erlang the following can apply:</p>
+ <pre>
+Arr1Val = [4,5,6,7,8],
+Arr2Val = ["abc",[14,34,54],"Octets"], </pre>
+ <p>Notice that the definition of type <c>SET OF</c> implies that
+ the order of the components is undefined, but in practice there is
+ no difference between <c>SET OF</c> and <c>SEQUENCE OF</c>.
+ The ASN.1 compiler for Erlang does not randomize the order of the
+ <c>SET OF</c> components before encoding.</p>
+ <p>However, for a value of type <c>SET OF</c>, the DER
+ encoding format requires the elements to be sent in ascending
+ order of their encoding, which implies an expensive sorting
+ procedure in runtime. Therefore it is recommended to
+ use <c>SEQUENCE OF</c> instead of <c>SET OF</c> if possible.</p>
+ </section>
+
+ <section>
+ <marker id="ANY"></marker>
+ <title>ANY and ANY DEFINED BY</title>
+ <p>The types <c>ANY</c> and <c>ANY DEFINED BY</c> have been removed
+ from the standard since 1994. It is recommended not to use
+ these types any more. They can, however, exist in some old ASN.1
+ modules. The idea with this type was to leave a "hole" in a
+ definition where it was possible to
+ put unspecified data of any kind, even non-ASN.1 data.</p>
+ <p>A value of this type is encoded as an <c>open type</c>.</p>
+ <p>Instead of <c>ANY</c> and <c>ANY DEFINED BY</c>, it is
+ recommended to use
+ <c>information object class</c>, <c>table constraints</c>, and
+ <c>parameterization</c>. In particular the construct
+ <c>TYPE-IDENTIFIER.@Type</c> accomplish the same as the
+ deprecated <c>ANY</c>.</p>
+ <p>See also
+ <seealso marker="#Information Object">Information object</seealso>.</p>
+ </section>
+
+ <section>
+ <marker id="NegotiationTypes"></marker>
+ <title>EXTERNAL, EMBEDDED PDV, and CHARACTER STRING</title>
+ <p>The types <c>EXTERNAL</c>, <c>EMBEDDED PDV</c>, and
+ <c>CHARACTER STRING</c> are used in presentation layer negotiation.
+ They are encoded according to their associated type, see X.680.</p>
+ <p>The type <c>EXTERNAL</c> had a slightly different associated type
+ before 1994. X.691 states that encoding must follow
+ the older associated type. So, generated encode/decode
+ functions convert values of the newer format to the older format
+ before encoding. This implies that it is allowed to use
+ <c>EXTERNAL</c> type values of either format for encoding. Decoded
+ values are always returned in the newer format.</p>
+ </section>
+
+ <section>
+ <title>Embedded Named Types</title>
+ <p>The structured types previously described can have other named
+ types as their components. The general syntax to assign a value
+ to component <c>C</c> of a named ASN.1 type <c>T</c> in Erlang
+ is the record syntax <c>#'T'{'C'=Value}</c>.
+ Here <c>Value</c> can be a value of yet another type <c>T2</c>,
+ for example:</p>
+ <pre>
+EmbeddedExample DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+B ::= SEQUENCE {
+ a Arr1,
+ b T }
+
+Arr1 ::= SET SIZE (5) OF INTEGER (4..9)
+
+T ::= CHOICE {
+ x REAL,
+ y INTEGER,
+ z OBJECT IDENTIFIER }
+ END </pre>
+ <p><c>SEQUENCE</c> <c>b</c> can be encoded as follows in Erlang:</p>
+ <pre>
+1> 'EmbeddedExample':encode('B', {'B',[4,5,6,7,8],{x,"7.77"}}).
+{ok,&lt;&lt;5,56,0,8,3,55,55,55,46,69,45,50>>} </pre>
+ </section>
+ </section>
+
+ <section>
+ <title>Naming of Records in .hrl Files</title>
+ <p>When an ASN.1 specification is compiled, all defined types of type
+ <c>SET</c> or <c>SEQUENCE</c> result in a corresponding record in the
+ generated <c>.hrl</c> file. This is because the values for
+ <c>SET</c> and <c>SEQUENCE</c> are represented as records as
+ mentioned earlier.</p>
+ <p>Some special cases of this functionality are presented in the
+ next section.</p>
+
+ <section>
+ <title>Embedded Structured Types</title>
+ <p>In ASN.1 it is also possible to have components that are themselves
+ structured types.
+ For example, it is possible to have the following:</p>
+ <pre>
+Emb ::= SEQUENCE {
+ a SEQUENCE OF OCTET STRING,
+ b SET {
+ a INTEGER,
+ b INTEGER DEFAULT 66},
+ c CHOICE {
+ a INTEGER,
+ b FooType } }
+
+FooType ::= [3] VisibleString </pre>
+ <p>The following records are generated because of type <c>Emb</c>:</p>
+ <pre>
+-record('Emb,{a, b, c}).
+-record('Emb_b',{a, b = asn1_DEFAULT}). % the embedded SET type </pre>
+ <p>Values of type <c>Emb</c> can be assigned as follows:</p>
+ <code type="none">
+V = #'Emb'{a=["qqqq",[1,2,255]],
+ b = #'Emb_b'{a=99},
+ c ={b,"Can you see this"}}.</code>
+ <p>For an embedded type of type <c>SEQUENCE</c>/<c>SET</c> in a
+ <c>SEQUENCE</c>/<c>SET</c>, the record name is extended with an
+ underscore and the component name. If the embedded structure is
+ deeper with the <c>SEQUENCE</c>, <c>SET</c>, or <c>CHOICE</c>
+ types in the line, each component name/alternative name is
+ added to the record name.</p>
+ <p>Example:</p>
+ <pre>
+Seq ::= SEQUENCE{
+ a CHOICE{
+ b SEQUENCE {
+ c INTEGER
+ }
+ }
+} </pre>
+ <p>This results in the following record:</p>
+ <pre>
+-record('Seq_a_b',{c}). </pre>
+ <p>If the structured type has a component with an embedded
+ <c>SEQUENCE OF</c>/<c>SET OF</c> which embedded type in turn
+ is a <c>SEQUENCE</c>/<c>SET</c>, it gives a record with the
+ <c>SEQUENCE OF</c>/<c>SET OF</c>
+ addition as in the following example:</p>
+ <pre>
+Seq ::= SEQUENCE {
+ a SEQUENCE OF SEQUENCE {
+ b
+ }
+ c SET OF SEQUENCE {
+ d
+ }
+} </pre>
+ <p>This results in the following records:</p>
+ <pre>
+-record('Seq_a_SEQOF'{b}).
+-record('Seq_c_SETOF'{d}). </pre>
+ <p>A parameterized type is to be considered as an embedded
+ type. Each time such a type is referenced, an instance of it is
+ defined. Thus, in the following example a record with name
+ <c>'Seq_b'</c> is generated in the <c>.hrl</c> file and is used
+ to hold values:</p>
+ <pre>
+Seq ::= SEQUENCE {
+ b PType{INTEGER}
+}
+
+PType{T} ::= SEQUENCE{
+ id T
+} </pre>
+ </section>
+
+ <section>
+ <title>Recursive Types</title>
+ <p>Types that refer to themselves are called recursive types.
+ Example:</p>
+ <pre>
+Rec ::= CHOICE {
+ nothing NULL,
+ something SEQUENCE {
+ a INTEGER,
+ b OCTET STRING,
+ c Rec }} </pre>
+ <p>This is allowed in ASN.1 and the ASN.1-to-Erlang compiler
+ supports this recursive type.
+ A value for this type is assigned in Erlang as follows:</p>
+ <pre>
+V = {something,#'Rec_something'{a = 77,
+ b = "some octets here",
+ c = {nothing,'NULL'}}}. </pre>
+ </section>
+ </section>
+
+ <section>
+ <title>ASN.1 Values</title>
+ <p>Values can be assigned to an ASN.1 type within the ASN.1 code
+ itself, as opposed to the actions in the previous section where
+ a value was assigned to an ASN.1 type in Erlang. The full value
+ syntax of ASN.1 is supported and X.680 describes in detail how
+ to assign values in ASN.1. A short example:</p>
+ <pre>
+TT ::= SEQUENCE {
+ a INTEGER,
+ b SET OF OCTET STRING }
+
+tt TT ::= {a 77,b {"kalle","kula"}} </pre>
+ <p>The value defined here can be used in several ways. It can, for
+ example, be used as the value in some <c>DEFAULT</c> component:</p>
+ <pre>
+SS ::= SET {
+ s OBJECT IDENTIFIER,
+ val TT DEFAULT tt } </pre>
+ <p>It can also be used from inside an Erlang program. If this ASN.1
+ code is defined in ASN.1 module <c>Values</c>, the ASN.1 value
+ <c>tt</c> can be reached from Erlang as a function call to
+ <c>'Values':tt()</c> as in the following example:</p>
+ <pre>
+1> <input>Val = 'Values':tt().</input>
+{'TT',77,["kalle","kula"]}
+2> <input>{ok,Bytes} = 'Values':encode('TT',Val).</input>
+{ok,&lt;&lt;48,18,128,1,77,161,13,4,5,107,97,108,108,101,4,4,
+ 107,117,108,97&gt;&gt;}
+4> <input>'Values':decode('TT',Bytes).</input>
+{ok,{'TT',77,["kalle","kula"]}}
+5> </pre>
+ <p>This example shows that a function is generated by the compiler
+ that returns a valid Erlang representation of the value, although
+ the value is of a complex type.</p>
+ <p>Furthermore, a macro is generated for each value in the <c>.hrl</c>
+ file. So, the defined value <c>tt</c> can also be extracted by
+ <c>?tt</c> in application code.</p>
+ </section>
+
+ <section>
+ <title>Macros</title>
+ <p>The type <c>MACRO</c> is not supported. It is no longer part of
+ the ASN.1 standard.</p>
+ </section>
+
+ <section>
+ <marker id="Information Object"></marker>
+ <title>ASN.1 Information Objects (X.681)</title>
+ <p>Information Object Classes, Information Objects, and Information
+ Object Sets (in the following called classes, objects, and
+ object sets, respectively) are defined in the standard
+ definition X.681. Only a brief explanation is given here.</p>
+ <p>These constructs makes it possible to define open types, that
+ is, values of that type can be of any ASN.1 type. Also,
+ relationships can be defined between different types and
+ values, as classes can hold types, values, objects, object
+ sets, and other classes in their fields. A class can be
+ defined in ASN.1 as follows:</p>
+ <pre>
+GENERAL-PROCEDURE ::= CLASS {
+ &amp;Message,
+ &amp;Reply OPTIONAL,
+ &amp;Error OPTIONAL,
+ &amp;id PrintableString UNIQUE
+}
+WITH SYNTAX {
+ NEW MESSAGE &amp;Message
+ [REPLY &amp;Reply]
+ [ERROR &amp;Error]
+ ADDRESS &amp;id
+} </pre>
+ <p>An object is an instance of a class. An object set is a set
+ containing objects of a specified class. A definition can look
+ as follows:</p>
+ <pre>
+object1 GENERAL-PROCEDURE ::= {
+ NEW MESSAGE PrintableString
+ ADDRESS "home"
+}
+
+object2 GENERAL-PROCEDURE ::= {
+ NEW MESSAGE INTEGER
+ ERROR INTEGER
+ ADDRESS "remote"
+}</pre>
+ <p>The object <c>object1</c> is an instance of the class
+ <c>GENERAL-PROCEDURE</c> and has one type field and one
+ fixed type value field. The object <c>object2</c> has also an
+ optional field <c>ERROR</c>, which is a type field. The field
+ <c>ADDRESS</c> is a <c>UNIQUE</c> field. Objects in an object set
+ must have unique values in their <c>UNIQUE</c> field, as in
+ <c>GENERAL-PROCEDURES</c>:</p>
+ <pre>
+GENERAL-PROCEDURES GENERAL-PROCEDURE ::= {
+ object1 | object2} </pre>
+ <p>You cannot encode a class, object, or object set, only refer to
+ it when defining other ASN.1 entities. Typically you refer to a
+ class as well as to object sets by table constraints and component
+ relation constraints (X.682) in ASN.1 types, as in the following:</p>
+ <pre>
+StartMessage ::= SEQUENCE {
+ msgId GENERAL-PROCEDURE.&amp;id ({GENERAL-PROCEDURES}),
+ content GENERAL-PROCEDURE.&amp;Message ({GENERAL-PROCEDURES}{@msgId}),
+ } </pre>
+ <p>In type <c>StartMessage</c>, the constraint following field
+ <c>content</c> tells that in a value of type
+ <c>StartMessage</c> the value in field <c>content</c> must
+ come from the same object that is chosen by field <c>msgId</c>.</p>
+ <p>So, the value
+ <c>#'StartMessage'{msgId="home",content="Any Printable String"}</c>
+ is legal to encode as a <c>StartMessage</c> value. However, the value
+ <c>#'StartMessage'{msgId="remote", content="Some String"}</c>
+ is illegal as the constraint in <c>StartMessage</c> tells that
+ when you have chosen a value from a specific object in object
+ set <c>GENERAL-PROCEDURES</c> in field
+ <c>msgId</c>, you must choose a value from that same object in
+ the content field too. In this second case, it is to be
+ any <c>INTEGER</c> value.</p>
+ <p><c>StartMessage</c> can in field <c>content</c> be
+ encoded with a value of any type that an object in object set
+ <c>GENERAL-PROCEDURES</c> has in its <c>NEW MESSAGE</c> field.
+ This field refers to a type field
+ <c>&amp;Message</c> in the class. Field <c>msgId</c> is always
+ encoded as a <c>PrintableString</c>, as the field refers to a
+ fixed type in the class.</p>
+ <p>In practice, object sets are usually declared to be extensible so
+ that more objects can be added to the set later. Extensibility is
+ indicated as follows:</p>
+ <pre>
+GENERAL-PROCEDURES GENERAL-PROCEDURE ::= {
+ object1 | object2, ...} </pre>
+ <p>When decoding a type that uses an extensible set constraint,
+ it is always possible that the value in field <c>UNIQUE</c>
+ is unknown (that is, the type has been encoded with a later
+ version of the ASN.1 specification). The unencoded data is then
+ returned wrapped in a tuple as follows:</p>
+
+ <pre>
+{asn1_OPENTYPE,Binary}</pre>
+
+ <p>Here <c>Binary</c> is an Erlang binary that contains the encoded
+ data. (If option <c>legacy_erlang_types</c> has been given,
+ only the binary is returned.)</p>
+ </section>
+
+ <section>
+ <title>Parameterization (X.683)</title>
+ <p>Parameterization, which is defined in X.683, can be used when
+ defining types, values, value sets, classes, objects, or object sets.
+ A part of a definition can be supplied as a parameter. For
+ example, if a <c>Type</c> is used in a definition with a certain
+ purpose, you want the type name to express the intention. This
+ can be done with parameterization.</p>
+ <p>When many types (or another ASN.1 entity) only differ in some
+ minor cases, but the structure of the types is similar, only
+ one general type can be defined and the differences can be supplied
+ through parameters.</p>
+ <p>Example of use of parameterization:</p>
+ <pre>
+General{Type} ::= SEQUENCE
+{
+ number INTEGER,
+ string Type
+}
+
+T1 ::= General{PrintableString}
+
+T2 ::= General{BIT STRING}</pre>
+ <p>An example of a value that can be encoded as type <c>T1</c> is
+ <c>{12,"hello"}</c>.</p>
+ <p>Notice that the compiler does not generate encode/decode functions
+ for parameterized types, only for the instances of the parameterized
+ types. Therefore, if a file contains the types <c>General{}</c>,
+ <c>T1</c>, and <c>T2</c> as in the previous example, encode/decode
+ functions are only generated for <c>T1</c> and <c>T2</c>.
+ </p>
+ </section>
+</chapter>
+
diff --git a/lib/asn1/doc/src/asn1_introduction.xml b/lib/asn1/doc/src/asn1_introduction.xml
new file mode 100644
index 0000000000..3c69eb82ab
--- /dev/null
+++ b/lib/asn1/doc/src/asn1_introduction.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Introduction</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2015-03-31</date>
+ <rev>A</rev>
+ <file>asn1_introduction.xml</file>
+ </header>
+
+ <p>The <c>ASN.1</c> application provides the following:</p>
+
+ <list type="bulleted">
+ <item>An ASN.1 compiler for Erlang, which generates encode and
+ decode functions to be used by Erlang programs sending and
+ receiving ASN.1 specified data.</item>
+ <item>Runtime functions used by the generated code.</item>
+ <item>Support for the following encoding rules:
+ <list><item>Basic Encoding Rules (BER)</item>
+ <item>Distinguished Encoding Rules (DER), a specialized form of
+ BER that is used in security-conscious applications</item>
+ <item>Packed Encoding Rules (PER), both the aligned and
+ unaligned variant</item>
+ </list>
+ </item>
+ </list>
+
+ <section>
+ <title>Scope</title>
+ <p>This application covers all features of ASN.1 up to the 1997
+ edition of the specification. In the 2002 edition,
+ new features were introduced. The following features
+ of the 2002 edition are fully or partly supported:</p>
+ <list type="bulleted">
+ <item>
+ <p>Decimal notation (for example, <c>"1.5e3</c>) for REAL values.
+ The NR1, NR2, and NR3 formats as explained in ISO 6093 are
+ supported.</p>
+ </item>
+ <item>
+ <p>The <c>RELATIVE-OID</c> type for relative object identifiers is
+ fully supported.</p>
+ </item>
+ <item>
+ <p>The subtype constraint (<c>CONTAINING</c>/<c>ENCODED BY</c>) to
+ constrain the content of an octet string or a bit string is
+ parsed when compiling, but no further action is taken. This
+ constraint is not a PER-visible constraint.</p>
+ </item>
+ <item>
+ <p>The subtype constraint by regular expressions (<c>PATTERN</c>)
+ for character string types is parsed when compiling, but no
+ further action is taken. This constraint is not a
+ PER-visible constraint.</p>
+ </item>
+ <item>
+ <p>Multiple-line comments as in C, <c>/* ... */</c>, are
+ supported.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language, concepts of OTP, and is familiar with the
+ ASN.1 notation. The ASN.1 notation is documented in the standard
+ definition X.680, which is the primary text. It can also be
+ helpful, but not necessary, to read the standard definitions
+ X.681, X.682, X.683, X.690, and X.691.</p>
+ <p>A good book explaining those reference texts is
+ Dubuisson: ASN.1 - Communication Between Heterogeneous Systems,
+ is free to download at
+ <url href="http://www.oss.com/asn1/dubuisson.html">http://www.oss.com/asn1/dubuisson.html</url>.</p>
+ </section>
+
+</chapter>
+
diff --git a/lib/asn1/doc/src/asn1_overview.xml b/lib/asn1/doc/src/asn1_overview.xml
new file mode 100644
index 0000000000..3929db7a54
--- /dev/null
+++ b/lib/asn1/doc/src/asn1_overview.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ASN.1</title>
+ <prepared>Kenneth Lundin</prepared>
+ <docno></docno>
+ <date>1999-03-25</date>
+ <rev>D</rev>
+ <file>asn1_overview.xml</file>
+ </header>
+
+<section>
+ <title>Introduction</title>
+
+ <p>ASN.1 is a formal language for
+ describing data structures to be exchanged between distributed
+ computer systems. The purpose of ASN.1 is to have a platform
+ and programming language independent notation to express types
+ using a standardized set of rules for the transformation of
+ values of a defined type into a stream of bytes. This stream of
+ bytes can then be sent on any type of communication
+ channel. This way, two applications written in different
+ programming languages running on different computers, and with
+ different internal representation of data, can exchange instances
+ of structured data types.</p>
+
+</section>
+</chapter>
+
diff --git a/lib/asn1/doc/src/asn1_spec.xmlsrc b/lib/asn1/doc/src/asn1_spec.xmlsrc
index 9001aca65c..5409ba0aa1 100644
--- a/lib/asn1/doc/src/asn1_spec.xmlsrc
+++ b/lib/asn1/doc/src/asn1_spec.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,94 +30,100 @@
<file>asn1_spec.xml</file>
</header>
<marker id="SpecializedDecodes"></marker>
- <p>When performance is of highest priority and one is interested in
- a limited part of the ASN.1 encoded message, before one decide what
- to do with the rest of it, one may want to decode only this small
- part. The situation may be a server that has to decide to which
- addressee it will send a message. The addressee may be interested in
- the entire message, but the server may be a bottleneck that one want
- to spare any unnecessary load. Instead of making two <em>complete decodes</em> (the normal case of decode), one in the server and one
- in the addressee, it is only necessary to make one <em>specialized decode</em>(in the server) and another complete decode(in the
- addressee). The following specialized decodes <em>exclusive decode</em> and <em>selected decode</em> support to solve this and
- similar problems.
- </p>
- <p>So far this functionality is only provided when using the
- optimized BER_BIN version, that is when compiling with the
- options <c>ber_bin</c> and <c>optimize</c>. It does also work
- using the <c>nif</c> option. We have no intent to make this
- available on the default BER version, but maybe in the PER_BIN
- version (<c>per_bin</c>).
- </p>
+ <p>When performance is of highest priority and you are interested in
+ a limited part of the ASN.1 encoded message before deciding what
+ to do with the rest of it, an option is to decode only this small
+ part. The situation can be a server that has to decide the
+ addressee of a message. The addressee can be interested in
+ the entire message, but the server can be a bottleneck that you want
+ to spare any unnecessary load.</p>
+ <p> Instead of making two <em>complete decodes</em> (the normal case of
+ decode), one in the server and one in the addressee, it is only
+ necessary to make one <em>specialized decode</em>(in the server)
+ and another complete decode(in the addressee). This section
+ describes the following two specialized decodes, which support
+ to solve this and similar problems:</p>
+ <list type="bulleted">
+ <item><em>Exclusive decode</em></item>
+ <item><em>Selected decode</em></item>
+ </list>
+ <p>This functionality is only provided when using <c>BER</c>
+ (option <c>ber</c>).</p>
<section>
<title>Exclusive Decode</title>
<p>The basic idea with exclusive
- decode is that you specify which parts of the message you want to
+ decode is to specify which parts of the message you want to
exclude from being decoded. These parts remain encoded and are
- returned in the value structure as binaries. They may be decoded
+ returned in the value structure as binaries. They can be decoded
in turn by passing them to a certain <c>decode_part/2</c>
- function. The performance gain is high when the message is large
- and you can do an exclusive decode and later on one or several
- decodes of the parts or a second complete decode instead of two or
+ function. The performance gain is high for large messages.
+ You can do an exclusive decode and later one or more
+ decodes of the parts, or a second complete decode instead of two or
more complete decodes.
</p>
<section>
- <title>How To Make It Work</title>
- <p>In order to make exclusive decode work you have to do the
- following:
+ <title>Procedure</title>
+ <p>To perform an exclusive decode:
</p>
<list type="bulleted">
- <item>First,decide the name of the function for the exclusive
- decode.</item>
- <item>Second, write instructions that must consist of the name
- of the exclusive decode function, the name of the ASN.1
- specification and a notation that tells which parts of the
- message structure will be excluded from decode. These
- instructions shall be included in a configuration
- file. </item>
- <item>Third, compile with the additional option
- <c>asn1config</c>. The compiler searches for a configuration
- file with the same name as the ASN.1 spec but with the
- extension .asn1config. This configuration file is not the same
- as used for compilation of a set of files. See section
- <seealso marker="#UndecodedPart">Writing an Exclusive Decode Instruction.</seealso></item>
+ <item><em>Step 1:</em> Decide the name of the function for the
+ exclusive decode.</item>
+ <item><p><em>Step 2:</em> Include the following instructions in
+ a configuration file:</p>
+ <list type="bulleted">
+ <item>The name of the exclusive decode function</item>
+ <item>The name of the ASN.1 specification</item>
+ <item>A notation that tells which parts of the message
+ structure to be excluded from decode</item>
+ </list></item>
+ <item><em>Step 3</em> Compile with the additional option
+ <c>asn1config</c>. The compiler searches for a configuration
+ file with the same name as the ASN.1 specification but with
+ extension <c>.asn1config</c>. This configuration file is not
+ the same as used for compilation of a set of files. See Section
+ <seealso marker="#UndecodedPart">Writing an Exclusive Decode
+ Instruction.</seealso></item>
</list>
</section>
<section>
<title>User Interface</title>
- <p>The run-time user interface for exclusive decode consists of
- two different functions. First, the function for an exclusive
- decode, whose name the user decides in the configuration
- file. Second, the compiler generates a <c>decode_part/2</c>
- function when exclusive decode is chosen. This function decodes
- the parts that were left undecoded during the exclusive
- decode. Both functions are described below.
- </p>
- <p>If the exclusive decode function has for example got the name
+ <p>The runtime user interface for exclusive decode consists of
+ the following two functions:</p>
+ <list type="bulleted">
+ <item>A function for an exclusive decode, whose name the user
+ decides in the configuration file</item>
+ <item>The compiler generates a <c>decode_part/2</c>
+ function when exclusive decode is chosen. This function decodes
+ the parts that were left undecoded during the exclusive
+ decode.</item>
+ </list>
+ <p>Both functions are described in the following.</p>
+ <p>If the exclusive decode function has, for example, the name
<c>decode_exclusive</c> and an ASN.1 encoded message
- <c>Bin</c> shall be exclusive decoded, the call is:</p>
+ <c>Bin</c> is to be exclusive decoded, the call is as follows:</p>
<pre>
{ok,Excl_Message} = 'MyModule':decode_exclusive(Bin) </pre>
<marker id="UndecodedPart"></marker>
- <p>The result <c>Excl_Message</c> has the same structure as an
- complete decode would have, except for the parts of the top-type
- that were not decoded. The undecoded parts will be on their place
- in the structure on the format <c>{Type_Key,Undecoded_Value}</c>.
+ <p>The result <c>Excl_Message</c> has the same structure as a
+ complete decode would have, except for the parts of the top type
+ that were not decoded. The undecoded parts are on their places
+ in the structure on format <c>{Type_Key,Undecoded_Value}</c>.
</p>
- <p>Each undecoded part that shall be decoded must be fed into the <c>decode_part/2</c> function,like:</p>
+ <p>Each undecoded part that is to be decoded must be fed into
+ function <c>decode_part/2</c> as follows:</p>
<pre>
-{ok,Part_Message} = 'MyModule':decode_part(Type_Key,Undecoded_Value) </pre>
+{ok,Part_Message} = 'MyModule':decode_part(Type_Key,Undecoded_Value)</pre>
</section>
<section>
<marker id="Exclusive Instruction"></marker>
<title>Writing an Exclusive Decode Instruction</title>
- <p>This instruction is written in the configuration file on the
- format:</p>
+ <p>This instruction is written in the configuration file
+ in the following format:</p>
<pre>
-
Exclusive_Decode_Instruction = {exclusive_decode,{Module_Name,Decode_Instructions}}.
Module_Name = atom()
@@ -137,70 +144,76 @@ Element = {Name,parts} |
Top_Type = atom()
-Name = atom()
- </pre>
- <p>Observe that the instruction must be a valid Erlang term ended
- by a dot.
+Name = atom()</pre>
+ <p>The instruction must be a valid Erlang term ended by a dot.
</p>
- <p>In the <c>Type_List</c> the "path" from the top type to each
- undecoded sub-components is described. The top type of the path is
+ <p>In <c>Type_List</c> the "path" from the top type to each
+ undecoded subcomponents is described. The top type of the path is
an atom, the name of it. The action on each component/type that
- follows will be described by one of <c>{Name,parts}, {Name,undecoded}, {Name,Element_List}</c></p>
- <p>The use and effect of the actions are:
+ follows is described by one of
+ <c>{Name,parts}, {Name,undecoded}, {Name,Element_List}</c>.</p>
+ <p>The use and effect of the actions are as follows:
</p>
<list type="bulleted">
- <item><c>{Name,undecoded}</c> Tells that the element will be
- left undecoded during the exclusive decode. The type of Name may
- be any ASN.1 type. The value of element Name will be returned as a
- tuple,as mentioned <seealso marker="#UndecodedPart">above</seealso>, in the value structure of the top type.</item>
- <item><c>{Name,parts}</c> The type of Name may be one of
- SEQUENCE OF or SET OF. The action implies that the different
- components of Name will be left undecoded. The value of Name
- will be returned as a tuple, as <seealso marker="#UndecodedPart">above </seealso>, where the second element is a list of
- binaries. That is because the representation of a SEQUENCE OF/
- SET OF in Erlang is a list of its internal type. Any of the
- elements of this list or the entire list can be decoded by the
- <c>decode_part</c> function.</item>
- <item><c>{Name,Element_List}</c>This action is used when one or
- more of the sub-types of Name will be exclusive decoded.</item>
+ <item><c>{Name,undecoded}</c> - Tells that the element is left
+ undecoded during the exclusive decode. The type of <c>Name</c>
+ can be any ASN.1 type. The value of element <c>Name</c> is
+ returned as a tuple (as mentioned in the previous section) in
+ the value structure of the top type.</item>
+ <item><c>{Name,parts}</c> - The type of <c>Name</c> can be one of
+ <c>SEQUENCE OF</c> or <c>SET OF</c>. The action implies that
+ the different components of <c>Name</c> are left undecoded. The
+ value of <c>Name</c> is returned as a tuple (as mentioned in
+ the previous section) where the second element is a list of
+ binaries. This is because the representation of a <c>SEQUENCE OF</c>
+ or a <c>SET OF</c> in Erlang is a list of its internal type. Any
+ of the elements in this list or the entire list can be decoded by
+ function <c>decode_part</c>.</item>
+ <item><c>{Name,Element_List}</c> - This action is used when one or
+ more of the subtypes of <c>Name</c> is exclusive decoded.</item>
</list>
- <p>Name in the actions above may be a component name of a
- SEQUENCE or a SET or a name of an alternative in a CHOICE.
+ <p><c>Name</c> in these actions can be a component name of a
+ <c>SEQUENCE OF</c> or a <c>SET OF</c>, or a name of an alternative
+ in a <c>CHOICE</c>.
</p>
</section>
<section>
<title>Example</title>
- <p>In the examples below we use the definitions from the following ASN.1 spec:</p>
+ <p>In this examples, the definitions from the following ASN.1
+ specification are used:</p>
<marker id="Asn1spec"></marker>
<codeinclude file="Seq.asn" tag="" type="none"></codeinclude>
- <p>If <c>Button</c> is a top type and we want to exclude
- component <c>number</c> from decode the Type_List in the
- instruction in the configuration file will be
- <c>['Button',[{number,undecoded}]]</c>. If we call the decode
- function <c>decode_Button_exclusive</c> the Decode_Instruction
- will be
+ <p>If <c>Button</c> is a top type and it is needed to exclude
+ component <c>number</c> from decode, <c>Type_List</c> in the
+ instruction in the configuration file is
+ <c>['Button',[{number,undecoded}]]</c>. If you call the decode
+ function <c>decode_Button_exclusive</c>, <c>Decode_Instruction</c> is
<c>{decode_Button_exclusive,['Button',[{number,undecoded}]]}</c>.
</p>
- <p>We also have another top type <c>Window</c> whose sub
- component actions in type <c>Status</c> and the parts of component
- <c>buttonList</c> shall be left undecoded. For this type we name
- the function <c>decode__Window_exclusive</c>. The whole
- Exclusive_Decode_Instruction configuration is as follows: </p>
+ <p>Another top type is <c>Window</c> whose subcomponent
+ actions in type <c>Status</c> and the parts of component
+ <c>buttonList</c> are to be left undecoded. For this type, the
+ function is named <c>decode__Window_exclusive</c>. The complete
+ <c>Exclusive_Decode_Instruction</c> configuration is as follows:</p>
<codeinclude file="Seq.asn1config" tag="" type="none"></codeinclude>
+ <p>The following figure shows the bytes of a <c>Window:status</c>
+ message. The components <c>buttonList</c> and <c>actions</c> are
+ excluded from decode. Only <c>state</c> and <c>enabled</c> are decoded
+ when <c>decode__Window_exclusive</c> is called.</p>
<p></p>
<image file="exclusive_Win_But.gif">
- <icaption>Figure symbolizes the bytes of a Window:status message. The components buttonList and actions are excluded from decode. Only state and enabled are decoded when decode__Window_exclusive is called. </icaption>
+ <icaption>Bytes of a Window:status Message</icaption>
</image>
<p></p>
- <p>Compiling GUI.asn including the configuration file is done like:</p>
+ <p>Compiling <c>GUI.asn</c> including the configuration file is done
+ as follows:</p>
<pre>
-unix> erlc -bber_bin +optimize +asn1config GUI.asn
+unix> erlc -bber +asn1config GUI.asn
-erlang> asn1ct:compile('GUI',[ber_bin,optimize,asn1config]). </pre>
- <p>The module can be used like:</p>
+erlang> asn1ct:compile('GUI', [ber,asn1config]).</pre>
+ <p>The module can be used as follows:</p>
<pre>
-
1> Button_Msg = {'Button',123,true}.
{'Button',123,true}
2> {ok,Button_Bytes} = 'GUI':encode('Button',Button_Msg).
@@ -289,35 +302,39 @@ BoolOpt,{Type_Key_Choice,Val_Choice}}}}=
11> 'GUI':decode_part(Type_Key_SeqOf,hd(Val_SEQOF)).
{ok,{'Button',3,true}}
12> 'GUI':decode_part(Type_Key_Choice,Val_Choice).
-{ok,{possibleActions,[{'Action',16,{'Button',17,true}}]}}
- </pre>
+{ok,{possibleActions,[{'Action',16,{'Button',17,true}}]}}</pre>
</section>
</section>
<section>
<title>Selective Decode</title>
- <p>This specialized decode decodes one single subtype of a
- constructed value. It is the fastest method to extract one sub
- value. The typical use of this decode is when one want to
- inspect, for instance a version number,to be able to decide what
+ <p>This specialized decode decodes a subtype of a
+ constructed value and is the fastest method to extract a
+ subvalue. This decode is typically used when you want to
+ inspect, for example, a version number, to be able to decide what
to do with the entire value. The result is returned as
<c>{ok,Value}</c> or <c>{error,Reason}</c>.
</p>
<section>
- <title>How To Make It Work</title>
- <p>The following steps are necessary:
+ <title>Procedure</title>
+ <p>To perform a selective decode:
</p>
<list type="bulleted">
- <item>Write instructions in the configuration
- file. Including the name of a user function, the name of the ASN.1
- specification and a notation that tells which part of the type
- will be decoded. </item>
- <item>Compile with the additional option
- <c>asn1config</c>. The compiler searches for a configuration file
- with the same name as the ASN.1 spec but with the extension
- .asn1config. In the same file you can provide configuration specs
- for exclusive decode as well. The generated Erlang module has the
+ <item><p><em>Step 1:</em> Include the following instructions in
+ the configuration file:</p>
+ <list type="bulleted">
+ <item>The name of the user function</item>
+ <item>The name of the ASN.1 specification</item>
+ <item>A notation that tells which part of the type to be
+ decoded</item>
+ </list></item>
+ <item><em>Step 2:</em> Compile with the additional option
+ <c>asn1config</c>. The compiler searches for a configuration file
+ with the same name as the ASN.1 specification, but with extension
+ <c>.asn1config</c>. In the same file you can also provide
+ configuration specifications for exclusive decode.
+ The generated Erlang module has the
usual functionality for encode/decode preserved and the
specialized decode functionality added. </item>
</list>
@@ -326,21 +343,20 @@ BoolOpt,{Type_Key_Choice,Val_Choice}}}}=
<section>
<title>User Interface</title>
<p>The only new user interface function is the one provided by the
- user in the configuration file. You can invoke that function by
+ user in the configuration file. The function is started by
the <c>ModuleName:FunctionName</c> notation.
</p>
- <p>So, if you have the following spec
+ <p>For example, if the configuration file includes the specification
<c>{selective_decode,{'ModuleName',[{selected_decode_Window,TypeList}]}}</c>
- in the con-fig file, you do the selective decode by
+ do the selective decode by
<c>{ok,Result}='ModuleName':selected_decode_Window(EncodedBinary).</c></p>
</section>
<section>
<marker id="Selective Instruction"></marker>
<title>Writing a Selective Decode Instruction</title>
- <p>It is possible to describe one or many selective decode
- functions in a configuration file, you have to use the following
- notation:</p>
+ <p>One or more selective decode functions can be described in a
+ configuration file. Use the following notation:</p>
<pre>
Selective_Decode_Instruction = {selective_decode,{Module_Name,Decode_Instructions}}.
@@ -358,37 +374,43 @@ Element_List = Name|List_Selector
Name = atom()
-List_Selector = [integer()] </pre>
- <p>Observe that the instruction must be a valid Erlang term ended
- by a dot.
- </p>
- <p>The <c>Module_Name</c> is the same as the name of the ASN.1
- spec, but without the extension. A <c>Decode_Instruction</c> is
- a tuple with your chosen function name and the components from
- the top type that leads to the single type you want to
- decode. Notice that you have to choose a name of your function
- that will not be the same as any of the generated functions. The
- first element of the <c>Type_List</c> is the top type of the
- encoded message. In the <c>Element_List</c> it is followed by
- each of the component names that leads to selected type. Each of
- the names in the <c>Element_List</c> must be constructed types
- except the last name, which can be any type.
+List_Selector = [integer()]</pre>
+ <p>The instruction must be a valid Erlang term ended by a dot.
</p>
- <p>The List_Selector makes it possible to choose one of the
- encoded components in a SEQUENCE OF/ SET OF. It is also possible
- to go further in that component and pick a sub type of that to
- decode. So in the <c>Type_List</c>: <c>['Window',status,buttonList,[1],number]</c> the
- component <c>buttonList</c> has to be a SEQUENCE OF or SET OF type. In
- this example component <c>number</c> of the first of the encoded
- elements in the SEQUENCE OF <c>buttonList</c> is selected. This apply on
- the ASN.1 spec <seealso marker="#Asn1spec">above</seealso>.
+ <list type="bulleted">
+ <item><c>Module_Name</c> is the same as the name of the ASN.1
+ specification, but without the extension.</item>
+ <item><c>Decode_Instruction</c> is a tuple with your chosen
+ function name and the components from the top type that leads
+ to the single type you want to decode. Ensure to choose a name
+ of your function that is not the same as any of the generated
+ functions.</item>
+ <item> The first element of <c>Type_List</c> is the top type of the
+ encoded message. In <c>Element_List</c>, it is followed by
+ each of the component names that leads to selected type.</item>
+ <item>Each name in <c>Element_List</c> must be a constructed type
+ except the last name, which can be any type.</item>
+ <item><c>List_Selector</c> makes it possible to choose one of the
+ encoded components in a a <c>SEQUENCE OF</c> or a <c>SET OF</c>.
+ It is also possible to go further in that component and pick a
+ subtype of that to decode. So, in the <c>Type_List</c>:
+ <c>['Window',status,buttonList,[1],number]</c>, component
+ <c>buttonList</c> must be of type <c>SEQUENCE OF</c> or
+ <c>SET OF</c>.</item>
+ </list>
+ <p>In the example, component <c>number</c> of the first of the encoded
+ elements in the <c>SEQUENCE OF</c> <c>buttonList</c> is selected.
+ This applies on the ASN.1 specification in Section
+ <seealso marker="#Asn1spec">Writing an Exclusive Decode
+ Instruction</seealso>.
</p>
</section>
<section>
<title>Another Example</title>
- <p>In this example we use the same ASN.1 spec as <seealso marker="#Asn1spec">above</seealso>. A valid selective decode
- instruction is:</p>
+ <p>In this example, the same ASN.1 specification as in Section
+ <seealso marker="#Asn1spec">Writing an Exclusive Decode Instruction</seealso>
+ is used. The following is a valid selective decode instruction:</p>
<pre>
{selective_decode,
{'GUI',
@@ -404,16 +426,17 @@ List_Selector = [integer()] </pre>
actions,
possibleActions,
[1],
- handle,number]}]}}.
- </pre>
- <p>The first <c>Decode_Instruction</c>,
+ handle,number]}]}}.</pre>
+ <p>The first instruction,
<c>{selected_decode_Window1,['Window',status,buttonList,[1],number]}</c>
- is commented in the previous section. The instruction
- <c>{selected_decode_Action,['Action',handle,number]}</c> picks
- the component <c>number</c> in the <c>handle</c> component of the type
- <c>Action</c>. If we have the value <c>ValAction = {'Action',17,{'Button',4711,false}}</c> the internal value 4711
- should be picked by <c>selected_decode_Action</c>. In an Erlang
- terminal it looks like:</p>
+ is described in the previous section.</p>
+ <p> The second instruction,
+ <c>{selected_decode_Action,['Action',handle,number]}</c>, takes
+ component <c>number</c> in the <c>handle</c> component of type
+ <c>Action</c>. If the value is
+ <c>ValAction = {'Action',17,{'Button',4711,false}}</c>, the internal
+ value 4711 is to be picked by <c>selected_decode_Action</c>. In an
+ Erlang terminal it looks as follows:</p>
<pre>
ValAction = {'Action',17,{'Button',4711,false}}.
{'Action',17,{'Button',4711,false}}
@@ -423,44 +446,41 @@ ValAction = {'Action',17,{'Button',4711,false}}.
&lt;&lt;48,18,2,1,17,160,13,172,11,171,9,48,7,128,2,18,103,129,1,0&gt;&gt;
9> 'GUI':selected_decode_Action(BinBytes).
{ok,4711}
-10> </pre>
+10></pre>
<p>The third instruction,
<c>['Window',status,actions,possibleActions,[1],handle,number]</c>,
- which is a little more complicated,</p>
+ works as follows:</p>
<list type="bulleted">
- <item>starts with type <em>Window</em>. </item>
- <item>Picks component <em>status</em> of <c>Window</c> that is
- of type <c>Status</c>.</item>
- <item>Then takes component <em>actions</em> of type
+ <item><em>Step 1:</em> Starts with type <c>Window</c>.</item>
+ <item><em>Step 2:</em> Takes component <c>status</c> of <c>Window</c>
+ that is of type <c>Status</c>.</item>
+ <item><em>Step 3:</em> Takes <em>actions</em> of type
<c>Status</c>.</item>
- <item>Then <em>possibleActions</em> of the internal defined
- CHOICE type.</item>
- <item>Thereafter it goes into the first component of the
- SEQUENCE OF by <em>[1]</em>. That component is of type
- <c>Action</c>.</item>
- <item>The instruction next picks component
- <em>handle</em>.</item>
- <item>And finally component <em>number</em> of the type
+ <item><em>Step 4:</em> Takes <c>possibleActions</c> of the internally
+ defined <c>CHOICE</c> type.</item>
+ <item><em>Step 5:</em> Goes into the first component of
+ <c>SEQUENCE OF</c> by <c>[1]</c>. That component is of type
+ <c>Action</c>.</item>
+ <item><em>Step 6:</em> Takes component <c>handle</c>.</item>
+ <item><em>Step 7:</em> Takes component <c>number</c> of type
<c>Button</c>.</item>
</list>
- <p>The following figures shows which components are in the
- TypeList
- <c>['Window',status,actions,possibleActions,[1],handle,number]</c>. And
- which part of a message that will be decoded by
- selected_decode_Window2.
- </p>
+ <p>The following figure shows which components are in <c>TypeList</c>
+ <c>['Window',status,actions,possibleActions,[1],handle,number]</c>:</p>
<p></p>
<image file="selective_TypeList.gif">
- <icaption>The elements specified in the config file for selective decode of a sub-value in a Window message</icaption>
+ <icaption>Elements Specified in Configuration File for Selective Decode of a Subvalue in a Window Message</icaption>
</image>
+ <p>In the following figure, only the marked element is decoded by
+ <c>selected_decode_Window2</c>:</p>
<p></p>
<image file="selective_Window2.gif">
- <icaption>Figure symbolizes the bytes of a Window:status message. Only the marked element is decoded when selected_decode_Window2 is called. </icaption>
+ <icaption>Bytes of a Window:status Message</icaption>
</image>
- <p>With the following example you can examine that both
+ <p>With the following example, you can examine that both
<c>selected_decode_Window2</c> and
- <c>selected_decode_Window1</c> decodes the intended sub-value
- of the value <c>Val</c></p>
+ <c>selected_decode_Window1</c> decodes the intended subvalue
+ of value <c>Val</c>:</p>
<pre>
1> Val = {'Window',{status,{'Status',12,
[{'Button',13,true},
@@ -478,8 +498,8 @@ ValAction = {'Action',17,{'Button',4711,false}}.
4> 'GUI':selected_decode_Window1(Bin).
{ok,13}
5> 'GUI':selected_decode_Window2(Bin).
-{ok,18} </pre>
- <p>Observe that the value feed into the selective decode
+{ok,18}</pre>
+ <p>Notice that the value fed into the selective decode
functions must be a binary.
</p>
</section>
@@ -489,19 +509,19 @@ ValAction = {'Action',17,{'Button',4711,false}}.
<title>Performance</title>
<p>To give an indication on the possible performance gain using
the specialized decodes, some measures have been performed. The
- relative figures in the outcome between selective, exclusive and
- complete decode (the normal case) depends on the structure of
- the type, the size of the message and on what level the
+ relative figures in the outcome between selective, exclusive, and
+ complete decode (the normal case) depend on the structure of
+ the type, the size of the message, and on what level the
selective and exclusive decodes are specified.
</p>
<section>
- <title>ASN.1 Specifications, Messages and Configuration</title>
- <p>The specs <seealso marker="#Asn1spec">GUI</seealso> and
+ <title>ASN.1 Specifications, Messages, and Configuration</title>
+ <p>The specifications <seealso marker="#Asn1spec">GUI</seealso> and
<url href="http://www.itu.int/ITU-T/asn1/database/itu-t/h/h248/2002/MEDIA-GATEWAY-CONTROL.html">MEDIA-GATEWAY-CONTROL</url>
- was used in the test.
+ were used in the test.
</p>
- <p>For the GUI spec the configuration looked like:</p>
+ <p>For the <c>GUI</c> specification the configuration was as follows:</p>
<pre>
{selective_decode,
{'GUI',
@@ -523,9 +543,8 @@ ValAction = {'Action',17,{'Button',4711,false}}.
['Window',
[{status,
[{buttonList,parts},
- {actions,undecoded}]}]]}]}}.
- </pre>
- <p>The MEDIA-GATEWAY-CONTROL configuration was:</p>
+ {actions,undecoded}]}]]}]}}.</pre>
+ <p>The <c>MEDIA-GATEWAY-CONTROL</c> configuration was as follows:</p>
<pre>
{exclusive_decode,
{'MEDIA-GATEWAY-CONTROL',
@@ -538,9 +557,8 @@ ValAction = {'Action',17,{'Button',4711,false}}.
{selective_decode,
{'MEDIA-GATEWAY-CONTROL',
[{decode_MegacoMessage_selective,
- ['MegacoMessage',mess,version]}]}}.
- </pre>
- <p>The corresponding values were:</p>
+ ['MegacoMessage',mess,version]}]}}.</pre>
+ <p>The corresponding values were as follows:</p>
<pre>
{'Window',{status,{'Status',12,
[{'Button',13,true},
@@ -649,177 +667,178 @@ ValAction = {'Action',17,{'Button',4711,false}}.
{'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},
{'StatisticsParameter',[0,12,0,6],[[48,46,50]]},
{'StatisticsParameter',[0,12,0,7],[[50,48]]},
- {'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}
- </pre>
- <p>The size of the encoded values was 458 bytes for GUI and 464
- bytes for MEDIA-GATEWAY-CONTROL.
+ {'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}</pre>
+ <p>The size of the encoded values was 458 bytes for <c>GUI</c> and 464
+ bytes for <c>MEDIA-GATEWAY-CONTROL</c>.
</p>
</section>
<section>
<title>Results</title>
- <p>The ASN.1 specs in the test are compiled with the options
- <c>ber_bin, optimize, driver</c> and <c>asn1config</c>. If the
- <c>driver</c> option had been omitted there should have been
+ <p>The ASN.1 specifications in the test were compiled with options
+ <c>ber_bin, optimize, driver</c> and <c>asn1config</c>. Omitting
+ option <c>driver</c> gives
higher values for <c>decode</c> and <c>decode_part</c>. These tests have
- not been re-run using nifs, but are expected to perform about 5% better
+ not been rerun using NIFs, but are expected to perform about 5% better
than the linked-in driver.
</p>
<p>The test program runs 10000 decodes on the value, resulting
- in a printout with the elapsed time in microseconds for the
+ in an output with the elapsed time in microseconds for the
total number of decodes.
</p>
<table>
<row>
<cell align="left" valign="top"><em>Function</em></cell>
- <cell align="left" valign="top"><em>Time</em>(microseconds)</cell>
- <cell align="left" valign="top"><em>Kind of Decode</em></cell>
- <cell align="left" valign="top"><em>ASN.1 spec</em></cell>
- <cell align="left" valign="top"><em>% of time vs. complete decode</em></cell>
+ <cell align="left" valign="top"><em>Time</em> (microseconds)</cell>
+ <cell align="left" valign="top"><em>Decode Type</em></cell>
+ <cell align="left" valign="top"><em>ASN.1 Specification</em></cell>
+ <cell align="left" valign="top"><em>% of Time versus Complete Decode</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>decode_MegacoMessage_selective/1</c></cell>
<cell align="left" valign="middle"><c>374045</c></cell>
- <cell align="left" valign="middle"><c>selective</c></cell>
+ <cell align="left" valign="middle"><c>Selective</c></cell>
<cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
<cell align="left" valign="middle"><em>8.3</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>decode_MegacoMessage_exclusive/1</c></cell>
<cell align="left" valign="middle"><c>621107</c></cell>
- <cell align="left" valign="middle"><c>exclusive</c></cell>
+ <cell align="left" valign="middle"><c>Exclusive</c></cell>
<cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
<cell align="left" valign="middle"><em>13.8</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>decode/2</c></cell>
<cell align="left" valign="middle"><c>4507457</c></cell>
- <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>Complete</c></cell>
<cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
<cell align="left" valign="middle"><em>100</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>selected_decode_Window1/1</c></cell>
<cell align="left" valign="middle"><c>449585</c></cell>
- <cell align="left" valign="middle"><c>selective</c></cell>
+ <cell align="left" valign="middle"><c>Selective</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>7.6</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>selected_decode_Window2/1</c></cell>
<cell align="left" valign="middle"><c>890666</c></cell>
- <cell align="left" valign="middle"><c>selective</c></cell>
+ <cell align="left" valign="middle"><c>Selective</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>15.1</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>decode_Window_status_exclusive/1</c></cell>
<cell align="left" valign="middle"><c>1251878</c></cell>
- <cell align="left" valign="middle"><c>exclusive</c></cell>
+ <cell align="left" valign="middle"><c>Exclusive</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>21.3</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>decode/2</c></cell>
<cell align="left" valign="middle"><c>5889197</c></cell>
- <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>Complete</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>100</em></cell>
</row>
- <tcaption>Results of complete, exclusive and selective decode</tcaption>
+ <tcaption>Results of Complete, Exclusive, and Selective Decode</tcaption>
</table>
- <p>Another interesting question is what the relation is between
+ <p>It is also of interest to know the relation is between
a complete decode, an exclusive decode followed by
- <c>decode_part</c> of the excluded parts and a selective decode
- followed by a complete decode. Some situations may be compared to
- this simulation, e.g. inspect a sub-value and later on look at
+ <c>decode_part</c> of the excluded parts, and a selective decode
+ followed by a complete decode. Some situations can be compared to
+ this simulation, for example, inspect a subvalue and later inspect
the entire value. The following table shows figures from this
- test. The number of loops and time unit is the same as in the
+ test. The number of loops and the time unit are the same as in the
previous test.
</p>
<table>
<row>
<cell align="left" valign="top"><em>Actions</em></cell>
<cell align="left" valign="top"><em>Function</em>&nbsp;&nbsp;&nbsp;&nbsp;</cell>
- <cell align="left" valign="top"><em>Time</em>(microseconds)</cell>
- <cell align="left" valign="top"><em>ASN.1 spec</em></cell>
- <cell align="left" valign="top"><em>% of time vs. complete decode</em></cell>
+ <cell align="left" valign="top"><em>Time</em> (microseconds)</cell>
+ <cell align="left" valign="top"><em>ASN.1 Specification</em></cell>
+ <cell align="left" valign="top"><em>% of Time vs. Complete Decode</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>Complete</c></cell>
<cell align="left" valign="middle"><c>decode/2</c></cell>
<cell align="left" valign="middle"><c>4507457</c></cell>
<cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
<cell align="left" valign="middle"><em>100</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>selective and complete</c></cell>
+ <cell align="left" valign="middle"><c>Selective and Complete</c></cell>
<cell align="left" valign="middle"><c>decode_&shy;MegacoMessage_&shy;selective/1</c></cell>
<cell align="left" valign="middle"><c>4881502</c></cell>
<cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
<cell align="left" valign="middle"><em>108.3</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>exclusive and decode_part</c></cell>
+ <cell align="left" valign="middle"><c>Exclusive and decode_part</c></cell>
<cell align="left" valign="middle"><c>decode_&shy;MegacoMessage_&shy;exclusive/1</c></cell>
<cell align="left" valign="middle"><c>5481034</c></cell>
<cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
<cell align="left" valign="middle"><em>112.3</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>Complete</c></cell>
<cell align="left" valign="middle"><c>decode/2</c></cell>
<cell align="left" valign="middle"><c>5889197</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>100</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>selective and complete</c></cell>
+ <cell align="left" valign="middle"><c>Selective and Complete</c></cell>
<cell align="left" valign="middle"><c>selected_&shy;decode_&shy;Window1/1</c></cell>
<cell align="left" valign="middle"><c>6337636</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>107.6</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>selective and complete</c></cell>
+ <cell align="left" valign="middle"><c>Selective and Complete</c></cell>
<cell align="left" valign="middle"><c>selected_&shy;decode_&shy;Window2/1</c></cell>
<cell align="left" valign="middle"><c>6795319</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>115.4</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>exclusive and decode_part</c></cell>
+ <cell align="left" valign="middle"><c>Exclusive and decode_part</c></cell>
<cell align="left" valign="middle"><c>decode_&shy;Window_&shy;status_&shy;exclusive/1</c></cell>
<cell align="left" valign="middle"><c>6249200</c></cell>
<cell align="left" valign="middle"><c>GUI</c></cell>
<cell align="left" valign="middle"><em>106.1</em></cell>
</row>
- <tcaption>Results of complete, exclusive + decode_part and selective + complete decodes</tcaption>
+ <tcaption>Results of Complete, Exclusive + decode_part, and Selective + complete decodes</tcaption>
</table>
<p>Other ASN.1 types and values can differ much from these
- figures. Therefore it is important that you, in every case where
+ figures. It is therefore important that you, in every case where
you intend to use either of these decodes, perform some tests
- that shows if you will benefit your purpose.
+ that show if you will benefit your purpose.
</p>
</section>
<section>
- <title>Comments</title>
- <p>Generally speaking the gain of selective and exclusive decode
- in advance of complete decode is greater the bigger value and the
- less deep in the structure you have to decode. One should also
- prefer selective decode instead of exclusive decode if you are
- interested in just one single sub-value.</p>
- <p>Another observation is that the exclusive decode followed by
- decode_part decodes is very attractive if the parts will be sent
- to different servers for decoding or if one in some cases not is
- interested in all parts.</p>
- <p>The fastest selective decode are when the decoded type is a
+ <title>Final Remarks</title>
+ <list type="bulleted">
+ <item>The gain of using selective and exclusive decode instead of a
+ complete decode is greater the bigger the value and the
+ less deep in the structure you have to decode.</item>
+ <item>Use selective decode instead of exclusive decode if you are
+ interested in only a single subvalue.</item>
+ <item>Exclusive decode followed by
+ <c>decode_part</c> decodes is attractive if the parts are sent
+ to different servers for decoding, or if you in some cases are not
+ interested in all parts.</item>
+ <item>The fastest selective decode is when the decoded type is a
primitive type and not so deep in the structure of the top
- type. The <c>selected_decode_Window2</c> decodes a big constructed
- value, which explains why this operation is relatively slow.</p>
- <p>It may vary from case to case which combination of
- selective/complete decode or exclusive/part decode is the fastest.</p>
+ type. <c>selected_decode_Window2</c> decodes a high constructed
+ value, which explains why this operation is relatively slow.</item>
+ <item>It can vary from case to case which combination of
+ selective/complete decode or exclusive/part decode is the fastest.</item>
+ </list>
</section>
</section>
</chapter>
diff --git a/lib/asn1/doc/src/asn1_ug.xml b/lib/asn1/doc/src/asn1_ug.xml
deleted file mode 100644
index 8b33497dd3..0000000000
--- a/lib/asn1/doc/src/asn1_ug.xml
+++ /dev/null
@@ -1,1417 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year><year>2013</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Asn1</title>
- <prepared>Kenneth Lundin</prepared>
- <docno></docno>
- <date>1999-03-25</date>
- <rev>D</rev>
- <file>asn1_ug.xml</file>
- </header>
-
- <section>
- <title>Introduction</title>
-
- <section>
- <title>Features</title>
- <p>The Asn1 application provides:</p>
- <list type="bulleted">
- <item>An ASN.1 compiler for Erlang, which generates encode and
- decode functions to be used by Erlang programs sending and
- receiving ASN.1 specified data.</item>
- <item>Run-time functions used by the generated code.</item>
- <item>Support for the following encoding rules:
- <list>
- <item>
- Basic Encoding Rules (<em>BER</em>)
- </item>
- <item>
- Distinguished Encoding Rules (<em>DER</em>), a specialized
- form of BER that is used in security-conscious
- applications.
- </item>
- <item>
- Packed Encoding Rules (<em>PER</em>); both the aligned and
- unaligned variant.
- </item>
- </list>
- </item>
- </list>
- </section>
-
- <section>
- <title>Overview</title>
- <p>ASN.1 (Abstract Syntax Notation One) is a formal language for
- describing data structures to be exchanged between distributed
- computer systems. The purpose of ASN.1 is to have a platform
- and programming language independent notation to express types
- using a standardized set of rules for the transformation of
- values of a defined type into a stream of bytes. This stream of
- bytes can then be sent on any type of communication
- channel. This way, two applications written in different
- programming languages running on different computers with
- different internal representation of data can exchange instances
- of structured data types.</p>
- </section>
-
- <section>
- <title>Prerequisites</title>
- <p>It is assumed that the reader is familiar with the ASN.1
- notation as documented in the standard definition [<cite
- id="X.680"></cite>] which is the primary text. It may also be
- helpful, but not necessary, to read the standard definitions
- [<cite id="X.681"></cite>] [<cite id="X.682"></cite>] [<cite
- id="X.683"></cite>] [<cite id="X.690"></cite>] [<cite
- id="X.691"></cite>]. </p>
- <p>A good book explaining those reference texts is
- [<cite id="DUBUISSON"></cite>], which is free to download at
- <url href="http://www.oss.com/asn1/dubuisson.html">http://www.oss.com/asn1/dubuisson.html</url>.
- </p>
- </section>
-
- <section>
- <title>Capabilities</title>
- <p>This application covers all features of ASN.1 up to the 1997
- edition of the specification. In the 2002 edition of ASN.1 a
- number of new features were introduced. The following features
- of the 2002 edition are fully or partly supported as shown
- below:</p>
- <list type="bulleted">
- <item>
- <p>Decimal notation (e.g., "1.5e3") for REAL values. The
- NR1, NR2 and NR3 formats as explained in ISO6093 are
- supported.</p>
- </item>
- <item>
- <p>The RELATIVE-OID type for relative object identifiers is
- fully supported.</p>
- </item>
- <item>
- <p>The subtype constraint (CONTAINING/ENCODED BY) to
- constrain the content of an octet string or a bit string is
- parsed when compiling, but no further action is taken. This
- constraint is not a PER-visible constraint.</p>
- </item>
- <item>
- <p>The subtype constraint by regular expressions (PATTERN)
- for character string types is parsed when compiling, but no
- further action is taken. This constraint is not a
- PER-visible constraint.</p>
- </item>
- <item>
- <p>Multiple-line comments as in C, <c>/* ... */</c>, are
- supported.</p>
- </item>
- </list>
- </section>
-
- </section>
-
- <section>
- <title>Getting Started with Asn1</title>
-
- <section>
- <title>A First Example</title>
- <p>The following example demonstrates the basic functionality used to run
- the Erlang ASN.1 compiler.</p>
- <p>Create a file called <c>People.asn</c> containing the following:</p>
- <pre>
-People DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
- Person ::= SEQUENCE {
- name PrintableString,
- location INTEGER {home(0),field(1),roving(2)},
- age INTEGER OPTIONAL
- }
-END </pre>
- <p>This file (<c>People.asn</c>) must be compiled before it can be
- used.
- The ASN.1 compiler checks that the syntax is correct and that the
- text represents proper ASN.1 code before generating an abstract
- syntax tree. The code-generator then uses the abstract syntax
- tree in order to generate code.
- </p>
- <p>The generated Erlang files will be placed in the current directory or
- in the directory specified with the <c>{outdir,Dir}</c> option.
- The following shows how the compiler
- can be called from the Erlang shell:</p>
- <pre>
-1><input> asn1ct:compile("People", [ber]).</input>
-ok
-2> </pre>
-
- <p>The <c>verbose</c> option can be given to have information
- about the generated files printed:</p>
- <pre>
-2><input> asn1ct:compile("People", [ber,verbose]).</input>
-Erlang ASN.1 compiling "People.asn"
---{generated,"People.asn1db"}--
---{generated,"People.hrl"}--
---{generated,"People.erl"}--
-ok
-3> </pre>
-
- <p>The ASN.1 module <c>People</c> is now accepted and the
- abstract syntax tree is saved in the <c>People.asn1db</c> file;
- the generated Erlang code is compiled using the Erlang compiler
- and loaded into the Erlang run-time system. Now there is an API
- for <c>encode/2</c> and <c>decode/2</c> in the module
- <c>People</c>, which is invoked by: <br></br>
- <c><![CDATA['People':encode(<Type name>, <Value>)]]></c>
- <br></br>
- or <br></br>
-<c><![CDATA['People':decode(<Type name>, <Value>)]]></c></p>
-
- <p>Assume there is a network
- application which receives instances of the ASN.1 defined
- type Person, modifies and sends them back again:</p>
- <code type="none">
-receive
- {Port,{data,Bytes}} ->
- case 'People':decode('Person',Bytes) of
- {ok,P} ->
- {ok,Answer} = 'People':encode('Person',mk_answer(P)),
- Port ! {self(),{command,Answer}};
- {error,Reason} ->
- exit({error,Reason})
- end
- end, </code>
- <p>In the example above, a series of bytes is received from an
- external source and the bytes are then decoded into a valid
- Erlang term. This was achieved with the call
- <c>'People':decode('Person',Bytes)</c> which returned
- an Erlang value of the ASN.1 type <c>Person</c>. Then an answer was
- constructed and encoded using
- <c>'People':encode('Person',Answer)</c> which takes an
- instance of a defined ASN.1 type and transforms it to a
- binary according to the BER or PER encoding rules.
- <br></br>
-The encoder and the decoder can also be run from
- the shell.</p>
- <pre>
-2> <input>Rockstar = {'Person',"Some Name",roving,50}.</input>
-{'Person',"Some Name",roving,50}
-3> <input>{ok,Bin} = 'People':encode('Person',Rockstar).</input>
-{ok,&lt;&lt;243,17,19,9,83,111,109,101,32,78,97,109,101,2,1,2,
- 2,1,50&gt;&gt;}
-4> <input>{ok,Person} = 'People':decode('Person',Bin).</input>
-{ok,{'Person',"Some Name",roving,50}}
-5> </pre>
- </section>
-
- <section>
- <title>Module dependencies</title>
- <p>It is common that ASN.1 modules import defined types, values and
- other entities from another ASN.1 module.</p>
- <p>Earlier versions of the ASN.1 compiler required that modules that
- were imported from had to be compiled before the module that
- imported. This caused problems when ASN.1 modules had circular
- dependencies.</p>
- <p>Referenced modules are now parsed when the compiler finds an
- entity that is imported. There will not be any code generated for
- the referenced module. However, the compiled module rely on
- that the referenced modules also will be compiled.</p>
- </section>
- </section>
-
- <section>
- <title>The Asn1 Application User Interface</title>
- <p>The Asn1 application provides two separate user interfaces:</p>
- <list type="bulleted">
- <item>
- <p>The module <c>asn1ct</c> which provides the compile-time functions
- (including the compiler).</p>
- </item>
- <item>
- <p>The module <c>asn1rt_nif</c> which provides the run-time functions
- for the ASN.1 decoder for the BER back-end.</p>
- </item>
- </list>
- <p>The reason for the division of the interface into compile-time
- and run-time
- is that only run-time modules (<c>asn1rt*</c>) need to be loaded in
- an embedded system.
- </p>
-
- <section>
- <title>Compile-time Functions</title>
- <p>The ASN.1 compiler can be invoked directly from the command-line
- by means of the <c>erlc</c> program. This is convenient when compiling
- many ASN.1 files from the command-line or when using Makefiles.
- Here are some examples of how the <c>erlc</c> command can be used to invoke the
- ASN.1 compiler:</p>
- <pre>
-erlc Person.asn
-erlc -bper Person.asn
-erlc -bber ../Example.asn
-erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn </pre>
- <p>The useful options for the ASN.1 compiler are:</p>
- <taglist>
- <tag><c>-b[ber | per | uper]</c></tag>
- <item>
- <p>Choice of encoding rules, if omitted <c>ber</c> is the
- default.</p>
- </item>
- <tag><c>-o OutDirectory</c></tag>
- <item>
- <p>Where to put the generated files, default is the current
- directory.</p>
- </item>
- <tag><c>-I IncludeDir</c></tag>
- <item>
- <p>Where to search for <c>.asn1db</c> files and ASN.1
- source specs in order to resolve references to other
- modules. This option can be repeated many times if there
- are several places to search in. The compiler will always
- search the current directory first.</p>
- </item>
- <tag><c>+der</c></tag>
- <item>
- <p>DER encoding rule. Only when using <c>-ber</c> option.</p>
- </item>
- <tag><c>+asn1config</c></tag>
- <item>
- <p>This functionality works together with the
- <c>ber</c> option. It enables the
- specialized decodes, see the <seealso marker="asn1_spec">Specialized Decode</seealso> chapter.
- </p>
- </item>
- <tag><c>+undec_rest</c></tag>
- <item>
- <p>A buffer that holds a message being decoded may also have
- trailing bytes. If those trailing bytes are important they
- can be returned along with the decoded value by compiling
- the ASN.1 specification with the <c>+undec_rest</c> option.
- The return value from the decoder will be
- <c>{ok,Value,Rest}</c> where <c>Rest</c> is a binary
- containing the trailing bytes.</p>
- </item>
- <tag><c>+'Any Erlc Option'</c></tag>
- <item>
- <p>You may add any option to the Erlang compiler when
- compiling the generated Erlang files. Any option
- unrecognized by the ASN.1 compiler will be passed to the
- Erlang compiler.</p>
- </item>
- </taglist>
- <p>For a complete description of <c>erlc</c> see Erts Reference Manual.</p>
- <p>The compiler and other compile-time functions can also be invoked from
- the Erlang shell. Below follows a brief
- description of the primary functions, for a
- complete description of each function see
- <seealso marker="asn1ct">the Asn1 Reference Manual</seealso>, the
- <c>asn1ct</c> module.</p>
- <p>The compiler is invoked by using <c>asn1ct:compile/1</c> with
- default options, or <c>asn1ct:compile/2</c> if explicit options
- are given.
- Example:</p>
- <pre>
-asn1ct:compile("H323-MESSAGES.asn1"). </pre>
- <p>which equals:</p>
- <pre>
-asn1ct:compile("H323-MESSAGES.asn1",[ber]). </pre>
- <p>If one wants PER encoding:</p>
- <pre>
-asn1ct:compile("H323-MESSAGES.asn1",[per]). </pre>
- <p>The generic encode and decode functions can be invoked like this:</p>
- <pre>
-'H323-MESSAGES':encode('SomeChoiceType',{call,"octetstring"}).
-'H323-MESSAGES':decode('SomeChoiceType',Bytes). </pre>
- </section>
-
- <section>
- <title>Run-time Functions</title>
- <p>When an ASN.1 specification is compiled with the <c>ber</c>
- option, the module <c>asn1rt_nif</c> module and the NIF library in
- <c>asn1/priv_dir</c> will be needed at run-time.</p>
- <p>By invoking the function <c>info/0</c> in a generated module, one
- gets information about which compiler options were used.</p>
- </section>
-
- <section>
- <title>Errors</title>
- <p>Errors detected at
- compile time appear on the screen together with
- a line number indicating where in the source file the error
- was detected. If no errors are found, an Erlang ASN.1 module will
- be created.</p>
- <p>The run-time encoders and decoders execute within a catch and
- returns <c>{ok, Data}</c> or
- <c>{error, {asn1, Description}}</c> where
- <c>Description</c> is
- an Erlang term describing the error. </p>
- </section>
- </section>
-
- <section>
- <marker id="inlineExamples"></marker>
- <title>Multi-file Compilation</title>
- <p>There are various reasons for using multi-file compilation:</p>
- <list type="bulleted">
- <item>You want to choose the name for the generated module,
- perhaps because you need to compile the same specs for
- different encoding rules.</item>
- <item>You want only one resulting module.</item>
- </list>
- <p>You need to specify which ASN.1 specs you will
- compile in a module that must have the extension
- <c>.set.asn</c>. You chose name of the module and provide the
- names of the ASN.1 specs. For instance, if you have the specs
- <c>File1.asn</c>, <c>File2.asn</c> and <c>File3.asn</c> your
- module <c>MyModule.set.asn</c> will look like:</p>
- <pre>
-File1.asn
-File2.asn
-File3.asn </pre>
- <p>If you compile with:</p>
- <code type="none">
-~> erlc MyModule.set.asn </code>
- <p>the result will be one merged module <c>MyModule.erl</c> with
- the generated code from the three ASN.1 specs.
- </p>
- </section>
-
- <section>
- <title>A quick note about tags</title>
-
- <p>Tags used to be important for all users of ASN.1, because it
- was necessary to manually add tags to certain constructs in order
- for the ASN.1 specification to be valid. Here is an example of
- an old-style specification:</p>
-
- <pre>
-Tags DEFINITIONS ::=
-BEGIN
- Afters ::= CHOICE { cheese [0] IA5String,
- dessert [1] IA5String }
-END </pre>
-
- <p>Without the tags (the numbers in square brackets) the ASN.1
- compiler would refuse to compile the file.</p>
-
- <p>In 1994 the global tagging mode AUTOMATIC TAGS was introduced.
- By putting AUTOMATIC TAGS in the module header, the ASN.1 compiler
- will automatically add tags when needed. Here is the same
- specification in AUTOMATIC TAGS mode:</p>
-
- <pre>
-Tags DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
- Afters ::= CHOICE { cheese IA5String,
- dessert IA5String }
-END
-</pre>
-
- <p>Tags will not be mentioned any more in this manual.</p>
- </section>
-
- <section>
- <marker id="ASN1Types"></marker>
- <title>The ASN.1 Types</title>
- <p>This section describes the ASN.1 types including their
- functionality, purpose and how values are assigned in Erlang.
- </p>
- <p>ASN.1 has both primitive and constructed types:</p>
- <p></p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Primitive types</em></cell>
- <cell align="left" valign="middle"><em>Constructed types</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#BOOLEAN">BOOLEAN</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#SEQUENCE">SEQUENCE</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#INTEGER">INTEGER</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#SET">SET</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#REAL">REAL</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#CHOICE">CHOICE</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#NULL">NULL</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#SOF">SET OF and SEQUENCE OF</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#ENUMERATED">ENUMERATED</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#ANY">ANY</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#BIT STRING">BIT STRING</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#ANY">ANY DEFINED BY</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#OCTET STRING">OCTET STRING</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#NegotiationTypes">EXTERNAL</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#Character Strings">Character Strings</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#NegotiationTypes">EMBEDDED PDV</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#OBJECT IDENTIFIER">OBJECT IDENTIFIER</seealso></cell>
- <cell align="left" valign="middle"><seealso marker="#NegotiationTypes">CHARACTER STRING</seealso></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#Object Descriptor">Object Descriptor</seealso></cell>
- <cell align="left" valign="middle"></cell>
- </row>
- <row>
- <cell align="left" valign="middle"><seealso marker="#The TIME types">The TIME types</seealso></cell>
- <cell align="left" valign="middle"></cell>
- </row>
- <tcaption>The supported ASN.1 types</tcaption>
- </table>
- <marker id="TypeNameValue"></marker>
- <note>
- <p>Values of each ASN.1 type has its own representation in Erlang
- described in the following subsections. Users shall provide
- these values for encoding according to the representation, as
- in the example below.</p>
- </note>
- <pre>
-Operational ::= BOOLEAN --ASN.1 definition </pre>
- <p>In Erlang code it may look like:</p>
- <pre>
-Val = true,
-{ok,Bytes} = MyModule:encode('Operational', Val), </pre>
- <p>Below follows a description of how
- values of each type can be represented in Erlang.
- </p>
-
- <section>
- <marker id="BOOLEAN"></marker>
- <title>BOOLEAN</title>
- <p>Booleans in ASN.1 express values that can be either
- TRUE or FALSE.
- The meanings assigned to TRUE or FALSE is beyond the scope
- of this text. <br></br>
-
- In ASN.1 it is possible to have:</p>
- <pre>
-Operational ::= BOOLEAN
- </pre>
- <p>Assigning a value to the type Operational in Erlang is possible by
- using the following Erlang code:</p>
- <code type="erl">
-Myvar1 = true,
- </code>
- <p>Thus, in Erlang the atoms <c>true</c> and <c>false</c> are used
- to encode a boolean value.</p>
- </section>
-
- <section>
- <marker id="INTEGER"></marker>
- <title>INTEGER</title>
- <p>ASN.1 itself specifies indefinitely large integers, and the Erlang
- systems with versions 4.3 and higher, support very large
- integers, in practice indefinitely large integers.</p>
- <p>The concept of sub-typing can be applied to integers as well
- as to other ASN.1 types. The details of sub-typing are not
- explained here, for further info see [<cite id="X.680"></cite>]. A variety
- of syntaxes are allowed when defining a type as an integer:</p>
- <pre>
-T1 ::= INTEGER
-T2 ::= INTEGER (-2..7)
-T3 ::= INTEGER (0..MAX)
-T4 ::= INTEGER (0&lt;..MAX)
-T5 ::= INTEGER (MIN&lt;..-99)
-T6 ::= INTEGER {red(0),blue(1),white(2)}
- </pre>
- <p>The Erlang representation of an ASN.1 INTEGER is an integer or
- an atom if a so called <c>Named Number List</c> (see T6 above)
- is specified.</p>
- <p>Below is an example of Erlang code which assigns values for the
- above types: </p>
- <pre>
-T1value = 0,
-T2value = 6,
-T6value1 = blue,
-T6value2 = 0,
-T6value3 = white
- </pre>
- <p>The Erlang variables above are now bound to valid instances of
- ASN.1 defined types. This style of value can be passed directly
- to the encoder for transformation into a series of bytes.</p>
- <p>The decoder will return an atom if the value corresponds to a
- symbol in the Named Number List.</p>
- </section>
-
- <section>
- <marker id="REAL"></marker>
- <title>REAL</title>
- <p>The following ASN.1 type is used for real numbers:</p>
- <pre>
-R1 ::= REAL
- </pre>
- <p>It can be assigned a value in Erlang as:</p>
- <pre>
-R1value1 = "2.14",
-R1value2 = {256,10,-2},
- </pre>
- <p>In the last line note that the tuple {256,10,-2} is the real number
- 2.56 in a special notation, which will encode faster than simply
- stating the number as <c>"2.56"</c>. The arity three tuple is
- <c>{Mantissa,Base,Exponent}</c> i.e. Mantissa * Base^Exponent.</p>
- </section>
-
- <section>
- <marker id="NULL"></marker>
- <title>NULL</title>
- <p>Null is suitable in cases where supply and recognition of a value
- is important but the actual value is not.</p>
- <pre>
-Notype ::= NULL
- </pre>
- <p>The NULL type can be assigned in Erlang:</p>
- <pre>
-N1 = 'NULL',
- </pre>
- <p>The actual value is the quoted atom 'NULL'.</p>
- </section>
-
- <section>
- <marker id="ENUMERATED"></marker>
- <title>ENUMERATED</title>
- <p>The enumerated type can be used, when the value we wish to
- describe, may only take one of a set of predefined values.</p>
- <pre>
-DaysOfTheWeek ::= ENUMERATED {
- sunday(1),monday(2),tuesday(3),
- wednesday(4),thursday(5),friday(6),saturday(7) }
- </pre>
- <p>For example to assign a weekday value in Erlang use the same atom
- as in the <c>Enumerations</c> of the type definition:</p>
- <pre>
-Day1 = saturday,
- </pre>
- <p>The enumerated type is very similar to an integer type, when
- defined with a set of predefined values. An enumerated type
- differs from an integer in that it may only have specified
- values, whereas an integer can also have any other value.</p>
- </section>
-
- <section>
- <marker id="BIT STRING"></marker>
- <title>BIT STRING</title>
- <p>The BIT STRING type can be used to model information which
- is made up of arbitrary length series of bits. It is intended
- to be used for a selection of flags, not for binary files. <br></br>
-
- In ASN.1 BIT STRING definitions may look like:
- </p>
- <pre>
-Bits1 ::= BIT STRING
-Bits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}
- </pre>
- <p>There are two notations available for representation of
- BIT STRING values in Erlang and as input to the encode functions.</p>
- <list type="ordered">
- <item>A bitstring. By default, a BIT STRING with no
- symbolic names will be decoded to an Erlang bitstring.</item>
- <item>A list of atoms corresponding to atoms in the <c>NamedBitList</c>
- in the BIT STRING definition. A BIT STRING with symbolic
- names will always be decoded to this format.</item>
- </list>
- <p>Example:</p>
- <pre>
-Bits1Val1 = &lt;&lt;0:1,1:1,0:1,1:1,1:1&gt;&gt;,
-Bits2Val1 = [gnu,punk],
-Bits2Val2 = &lt;&lt;2#1110:4&gt;&gt;,
-Bits2Val3 = [bar,gnu,gnome],
- </pre>
- <p><c>Bits2Val2</c> and <c>Bits2Val3</c> above denote the same value.</p>
- <p><c>Bits2Val1</c> is assigned symbolic values. The assignment means
- that the bits corresponding to <c>gnu</c> and <c>punk</c> i.e. bits
- 2 and 14 are set to 1 and the rest set to 0. The symbolic values
- appear as a list of values. If a named value appears, which is not
- specified in the type definition, a run-time error will occur.</p>
- <p>BIT STRINGS may also be sub-typed with, for example, a SIZE
- specification:</p>
- <pre>
-Bits3 ::= BIT STRING (SIZE(0..31)) </pre>
- <p>This means that no bit higher than 31 can ever be set.</p>
-
- <section>
- <title>Deprecated representations for BIT STRING</title>
- <p>In addition to the representations described above, the
- following deprecated representations are available if the
- specification has been compiled with the
- <c>legacy_erlang_types</c> option:</p>
- <list type="ordered">
- <item>A list of binary digits (0 or 1). This format is
- accepted as input to the encode functions, and a BIT STRING
- will be decoded to this format if the
- <em>legacy_bit_string</em> option has been given.
- </item>
- <item>As <c>{Unused,Binary}</c> where <c>Unused</c> denotes
- how many trailing zero-bits 0 to 7 that are unused in the
- least significant byte in <c>Binary</c>. This format is
- accepted as input to the encode functions, and a <c>BIT
- STRING</c> will be decoded to this format if
- <em>compact_bit_string</em> has been given.
- </item>
- <item>A hexadecimal number (or an integer). This format
- should be avoided, since it is easy to misinterpret a BIT
- STRING value in this format.
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <marker id="OCTET STRING"></marker>
- <title>OCTET STRING</title>
- <p>The OCTET STRING is the simplest of all ASN.1 types. The
- OCTET STRING only moves or transfers e.g. binary files or other
- unstructured information complying to two rules. Firstly, the
- bytes consist of octets and secondly, encoding is not
- required.</p>
- <p>It is possible to have the following ASN.1 type definitions:</p>
- <pre>
-O1 ::= OCTET STRING
-O2 ::= OCTET STRING (SIZE(28)) </pre>
- <p>With the following example assignments in Erlang:</p>
- <pre>
-O1Val = &lt;&lt;17,13,19,20,0,0,255,254&gt;&gt;,
-O2Val = &lt;&lt;"must be exactly 28 chars...."&gt;&gt;,</pre>
- <p>By default, an OCTET STRING is always represented as
- an Erlang binary. If the specification has been compiled with
- the <c>legacy_erlang_types</c> option, the encode functions
- will accept both lists and binaries, and the decode functions
- will decode an OCTET STRING to a list.</p>
- </section>
-
- <section>
- <marker id="Character Strings"></marker>
- <title>Character Strings</title>
- <p>ASN.1 supports a wide variety of character sets. The main difference
- between OCTET STRINGS and the Character strings is that OCTET
- STRINGS have no imposed semantics on the bytes delivered.</p>
- <p>However, when using for instance the IA5String (which closely
- resembles ASCII) the byte 65 (in decimal
- notation) <em>means</em> the character 'A'.
- </p>
- <p>For example, if a defined type is to be a VideotexString and
- an octet is received with the unsigned integer value X, then
- the octet should be interpreted as specified in the standard
- ITU-T T.100,T.101.
- </p>
- <p>The ASN.1 to Erlang compiler
- will not determine the correct interpretation of each BER
- (Basic Encoding Rules) string octet value with different
- Character strings. Interpretation of octets is the
- responsibility of the application. Therefore, from the BER
- string point of view, octets appear to be very similar to
- character strings and are compiled in the same way.
- </p>
- <p>It should be noted that when PER (Packed Encoding Rules) is
- used, there is a significant difference in the encoding scheme
- between OCTET STRINGS and other strings. The constraints
- specified for a type are especially important for PER, where
- they affect the encoding.
- </p>
- <p>Here are some examples:</p>
- <pre>
-Digs ::= NumericString (SIZE(1..3))
-TextFile ::= IA5String (SIZE(0..64000)) </pre>
- <p>with corresponding Erlang assignments:</p>
- <pre>
-DigsVal1 = "456",
-DigsVal2 = "123",
-TextFileVal1 = "abc...xyz...",
-TextFileVal2 = [88,76,55,44,99,121 .......... a lot of characters here ....] </pre>
- <p>The Erlang representation for "BMPString" and
- "UniversalString" is either a list of ASCII values or a list
- of quadruples. The quadruple representation associates to the
- Unicode standard representation of characters. The ASCII
- characters are all represented by quadruples beginning with
- three zeros like {0,0,0,65} for the 'A' character. When
- decoding a value for these strings the result is a list of
- quadruples, or integers when the value is an ASCII character.</p>
-
- <p>The following example shows how it works. We have the following
- specification in the file <c>PrimStrings.asn1</c>.</p>
- <pre>
-PrimStrings DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
- BMP ::= BMPString
-END
- </pre>
-
- <p>Encoding and decoding some strings:</p>
-
- <pre>
-1> <input>asn1ct:compile('PrimStrings', [ber]).</input>
-ok
-2> <input>{ok,Bytes1} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,45,56}]).</input>
-{ok,&lt;&lt;30,4,53,54,45,56>>}
-3> <input>'PrimStrings':decode('BMP', Bytes1).</input>
-{ok,[{0,0,53,53},{0,0,45,56}]}
-4> <input>{ok,Bytes2} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,0,65}]).</input>
-{ok,&lt;&lt;30,4,53,53,0,65>>}
-5> <input>'PrimStrings':decode('BMP', Bytes2).</input>
-{ok,[{0,0,53,53},65]}
-6> <input>{ok,Bytes3} = 'PrimStrings':encode('BMP', "BMP string").</input>
-{ok,&lt;&lt;30,20,0,66,0,77,0,80,0,32,0,115,0,116,0,114,0,105,0,110,0,103>>}
-7> <input>'PrimStrings':decode('BMP', Bytes3).</input>
-{ok,"BMP string"} </pre>
-
- <p>The UTF8String type is represented as a UTF-8 encoded binary in
- Erlang. Such binaries can be created directly using the binary syntax
- or by converting from a list of Unicode code points using the
- <c>unicode:characters_to_binary/1</c> function.</p>
-
- <p>Here are some examples showing how UTF-8 encoded binaries can
- be created and manipulated:</p>
-
- <pre>
-1> <input>Gs = "Мой маленький Гном".</input>
-[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
- 1081,32,1043,1085,1086,1084]
-2> <input>Gbin = unicode:characters_to_binary(Gs).</input>
-&lt;&lt;208,156,208,190,208,185,32,208,188,208,176,208,187,208,
- 181,208,189,209,140,208,186,208,184,208,185,32,208,147,
- 208,...>>
-3> <input>Gbin = &lt;&lt;"Мой маленький Гном"/utf8>>.</input>
-&lt;&lt;208,156,208,190,208,185,32,208,188,208,176,208,187,208,
- 181,208,189,209,140,208,186,208,184,208,185,32,208,147,
- 208,...>>
-4> <input>Gs = unicode:characters_to_list(Gbin).</input>
-[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
- 1081,32,1043,1085,1086,1084]
- </pre>
-
- <p>See the <seealso marker="stdlib:unicode">unicode</seealso> module
- for more details.</p>
-
- <p>In the following example we will use this ASN.1 specification:</p>
- <pre>
-UTF DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
- UTF ::= UTF8String
-END
- </pre>
-
- <p>Encoding and decoding a string with Unicode characters:</p>
-
- <pre>
-5> <input>asn1ct:compile('UTF', [ber]).</input>
-ok
-6> <input>{ok,Bytes1} = 'UTF':encode('UTF', &lt;&lt;"Гном"/utf8>>).</input>
-{ok,&lt;&lt;12,8,208,147,208,189,208,190,208,188>>}
-7> <input>{ok,Bin1} = 'UTF':decode('UTF', Bytes1).</input>
-{ok,&lt;&lt;208,147,208,189,208,190,208,188>>}
-8> <input>io:format("~ts\n", [Bin1]).</input>
-Гном
-ok
-9> <input>unicode:characters_to_list(Bin1).</input>
-[1043,1085,1086,1084]
- </pre>
- </section>
-
- <section>
- <marker id="OBJECT IDENTIFIER"></marker>
- <title>OBJECT IDENTIFIER</title>
- <p>The OBJECT IDENTIFIER is used whenever a unique identity is required.
- An ASN.1 module, a transfer syntax, etc. is identified with an
- OBJECT IDENTIFIER. Assume the example below:</p>
- <pre>
-Oid ::= OBJECT IDENTIFIER
- </pre>
- <p>Therefore, the example below is a valid Erlang instance of the
- type 'Oid'.</p>
- <pre>
-OidVal1 = {1,2,55},
- </pre>
- <p>The OBJECT IDENTIFIER value is simply a tuple with the
- consecutive values which must be integers.
- </p>
- <p>The first value is limited to the values 0, 1 or 2 and the
- second value must be in the range 0..39 when the first value
- is 0 or 1.
- </p>
- <p>The OBJECT IDENTIFIER is a very important type and it is
- widely used within different standards to uniquely identify
- various objects. In [<cite id="DUBUISSON"></cite>], there is an
- easy-to-understand description of the usage of
- OBJECT IDENTIFIER.</p>
- <p></p>
- </section>
-
- <section>
- <marker id="Object Descriptor"></marker>
- <title>Object Descriptor</title>
- <p>Values of this type can be assigned a value as an ordinary string
- like this:</p>
-
- <pre>
- "This is the value of an Object descriptor"</pre>
- </section>
-
- <section>
- <marker id="The TIME types"></marker>
- <title>The TIME Types</title>
- <p>Two different time types are defined within ASN.1, Generalized
- Time and UTC (Universal Time Coordinated), both are assigned a
- value as an ordinary string within double quotes i.e.
- "19820102070533.8".</p>
- <p>In case of DER encoding the compiler does not check the validity
- of the time values. The DER requirements upon those strings is
- regarded as a matter for the application to fulfill.</p>
- </section>
-
- <section>
- <marker id="SEQUENCE"></marker>
- <title>SEQUENCE</title>
- <p>The structured types of ASN.1 are constructed from other types
- in a manner similar to the concepts of array and struct in C.
- <br></br>
- A SEQUENCE in ASN.1 is
- comparable with a struct in C and a record in Erlang.
- A SEQUENCE may be defined as:</p>
- <pre>
-Pdu ::= SEQUENCE {
- a INTEGER,
- b REAL,
- c OBJECT IDENTIFIER,
- d NULL } </pre>
- <p>This is a 4-component structure called 'Pdu'. The major format
- for representation of SEQUENCE in Erlang is the record format.
- For each SEQUENCE and <c>SET</c> in an ASN.1 module an Erlang
- record declaration is generated. For <c>Pdu</c> above, a record
- like this is defined:</p>
- <pre>
--record('Pdu',{a, b, c, d}). </pre>
- <p>The record declarations for a module <c>M</c> are placed in a
- separate <c>M.hrl</c> file.</p>
- <p>Values can be assigned in Erlang as shown below:</p>
- <pre>
-MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}. </pre>
- <p>The decode functions will return a record as result when decoding
- a <c>SEQUENCE</c> or a <c>SET</c>.</p>
-
- <p>A <c>SEQUENCE</c> and a <c>SET</c> may contain a component
- with a <c>DEFAULT</c> key word followed by the actual value that
- is the default value. The <c>DEFAULT</c> keyword means that the
- application doing the encoding can omit encoding of the value,
- thus resulting in fewer bytes to send to the receiving
- application.</p>
-
- <p>An application can use the atom <c>asn1_DEFAULT</c> to indicate
- that the encoding should be omitted for that position in
- the SEQUENCE.</p>
-
- <p>Depending on the encoding rules, the encoder may also compare
- the given value to the default value and automatically omit the
- encoding if they are equal. How much effort the encoder makes to
- to compare the values depends on the encoding rules. The DER
- encoding rules forbids encoding a value equal to the default value,
- so it has a more thorough and time-consuming comparison than the
- encoders for the other encoding rules.</p>
-
- <p>In the following example we will use this ASN.1 specification:</p>
- <pre>
-File DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
-Seq1 ::= SEQUENCE {
- a INTEGER DEFAULT 1,
- b Seq2 DEFAULT {aa TRUE, bb 15}
-}
-
-Seq2 ::= SEQUENCE {
- aa BOOLEAN,
- bb INTEGER
-}
-
-Seq3 ::= SEQUENCE {
- bs BIT STRING {a(0), b(1), c(2)} DEFAULT {a, c}
-}
-END </pre>
- <p>Here is an example where the BER encoder is able to omit encoding
- of the default values:</p>
- <pre>
-1> <input>asn1ct:compile('File', [ber]).</input>
-ok
-2> <input>'File':encode('Seq1', {'Seq1',asn1_DEFAULT,asn1_DEFAULT}).</input>
-{ok,&lt;&lt;48,0>>}
-3> <input>'File':encode('Seq1', {'Seq1',1,{'Seq2',true,15}}).</input>
-{ok,&lt;&lt;48,0>>} </pre>
-
- <p>And here is an example with a named BIT STRING where the BER
- encoder will not omit the encoding:</p>
- <pre>
-4> <input>'File':encode('Seq3', {'Seq3',asn1_DEFAULT).</input>
-{ok,&lt;&lt;48,0>>}
-5> <input>'File':encode('Seq3', {'Seq3',&lt;&lt;16#101:3>>).</input>
-{ok,&lt;&lt;48,4,128,2,5,160>>} </pre>
-
- <p>The DER encoder will omit the encoding for the same BIT STRING:</p>
- <pre>
-6> <input>asn1ct:compile('File', [ber,der]).</input>
-ok
-7> <input>'File':encode('Seq3', {'Seq3',asn1_DEFAULT).</input>
-{ok,&lt;&lt;48,0>>}
-8> <input>'File':encode('Seq3', {'Seq3',&lt;&lt;16#101:3>>).</input>
-{ok,&lt;&lt;48,0>>} </pre>
- </section>
-
- <section>
- <marker id="SET"></marker>
- <title>SET</title>
- <p>In Erlang, the SET type is used exactly as SEQUENCE. Note
- that if the BER or DER encoding rules are used, decoding a
- SET is slower than decoding a SEQUENCE because the components
- must be sorted.</p>
- </section>
-
- <section>
- <title>Notes about extensibility for SEQUENCE and SET</title>
- <p>When a SEQUENCE or SET contains an extension marker and
- extension components like this:</p>
- <pre>
-SExt ::= SEQUENCE {
- a INTEGER,
- ...,
- b BOOLEAN }
- </pre>
- <p>It means that the type may get more components in newer
- versions of the ASN.1 spec. In this case it has got a new
- component <c>b</c>. Thus, incoming messages that will be decoded
- may have more or fever components than this one.
- </p>
- <p>The component <c>b</c> will be treated as
- an original component when encoding a message. In this case, as
- it is not an optional element, it must be encoded.
- </p>
- <p>During decoding the <c>b</c> field of the record will get the decoded
- value of the <c>b</c>
- component if present and otherwise the value <c>asn1_NOVALUE</c>.</p>
- </section>
-
- <section>
- <marker id="CHOICE"></marker>
- <title>CHOICE</title>
- <p>The CHOICE type is a space saver and is similar to the concept of a
- 'union' in the C language.</p>
- <p>Assume:</p>
- <pre>
-SomeModuleName DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
-T ::= CHOICE {
- x REAL,
- y INTEGER,
- z OBJECT IDENTIFIER }
-END </pre>
- <p>It is then possible to assign values:</p>
- <pre>
-TVal1 = {y,17},
-TVal2 = {z,{0,1,2}},
- </pre>
- <p>A CHOICE value is always represented as the tuple
- <c>{ChoiceAlternative, Val}</c> where <c>ChoiceAlternative</c>
- is an atom denoting the selected choice alternative.
- </p>
-
- <section>
- <title>Extensible CHOICE</title>
- <p>When a CHOICE contains an extension marker and the decoder detects
- an unknown alternative of the CHOICE the value is represented as:</p>
- <pre>
-{asn1_ExtAlt, BytesForOpenType}
- </pre>
- <p>Where <c>BytesForOpenType</c> is a list of bytes constituting the
- encoding of the "unknown" CHOICE alternative. </p>
- </section>
- </section>
-
- <section>
- <marker id="SOF"></marker>
- <title>SET OF and SEQUENCE OF</title>
- <p>The SET OF and SEQUENCE OF types correspond to the concept of an array
- found in several programming languages. The Erlang syntax for
- both of these types is straight forward. For example:</p>
- <pre>
-Arr1 ::= SET SIZE (5) OF INTEGER (4..9)
-Arr2 ::= SEQUENCE OF OCTET STRING </pre>
- <p>We may have the following in Erlang:</p>
- <pre>
-Arr1Val = [4,5,6,7,8],
-Arr2Val = ["abc",[14,34,54],"Octets"], </pre>
- <p>Please note that the definition of the SET OF type implies that
- the order of the components is undefined, but in practice there is
- no difference between SET OF and SEQUENCE OF. The ASN.1 compiler
- for Erlang does not randomize the order of the SET OF components
- before encoding.</p>
- <p>However, in case of a value of the type <c>SET OF</c>, the DER
- encoding format requires the elements to be sent in ascending
- order of their encoding, which implies an expensive sorting
- procedure in run-time. Therefore it is strongly recommended to
- use <c>SEQUENCE OF</c> instead of <c>SET OF</c> if it is possible.</p>
- </section>
-
- <section>
- <marker id="ANY"></marker>
- <title>ANY and ANY DEFINED BY</title>
- <p>The types <c>ANY</c> and <c>ANY DEFINED BY</c> have been removed
- from the standard since 1994. It is recommended not to use
- these types any more. They may, however, exist in some old ASN.1
- modules.
- The idea with this type was to leave a "hole" in a definition where
- one could put unspecified data of any kind, even non ASN.1 data.</p>
- <p>A value of this type is encoded as an <c>open type</c>.</p>
- <p>Instead of <c>ANY</c>/<c>ANY DEFINED BY</c> one should use
- <c>information object class</c>, <c>table constraints</c> and
- <c>parameterization</c>. In particular the construct
- <c>TYPE-IDENTIFIER.@Type</c> accomplish the same as the
- deprecated <c>ANY</c>.</p>
- <p>See also <seealso marker="#Information Object">Information object</seealso></p>
- </section>
-
- <section>
- <marker id="NegotiationTypes"></marker>
- <title>EXTERNAL, EMBEDDED PDV and CHARACTER STRING</title>
- <p>These types are used in presentation layer negotiation. They are
- encoded according to their associated type, see [<cite id="X.680"></cite>].</p>
- <p>The <c>EXTERNAL</c> type had a slightly different associated type
- before 1994. [<cite id="X.691"></cite>] states that encoding shall follow
- the older associate type. Therefore does generated encode/decode
- functions convert values of the newer format to the older format
- before encoding. This implies that it is allowed to use
- <c>EXTERNAL</c> type values of either format for encoding. Decoded
- values are always returned on the newer format.</p>
- </section>
-
- <section>
- <title>Embedded Named Types</title>
- <p>The structured types previously described may very well have other named types
- as their components. The general syntax to assign a value to the component C
- of a named ASN.1 type T in Erlang is the record syntax
- <c>#'T'{'C'=Value}</c>.
- Where <c>Value</c> may be a value of yet another type T2.</p>
- <p>For example:</p>
- <pre>
-EmbeddedExample DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
-B ::= SEQUENCE {
- a Arr1,
- b T }
-
-Arr1 ::= SET SIZE (5) OF INTEGER (4..9)
-
-T ::= CHOICE {
- x REAL,
- y INTEGER,
- z OBJECT IDENTIFIER }
- END </pre>
- <p>The SEQUENCE b can be encoded like this in Erlang:</p>
- <pre>
-1> 'EmbeddedExample':encode('B', {'B',[4,5,6,7,8],{x,"7.77"}}).
-{ok,&lt;&lt;5,56,0,8,3,55,55,55,46,69,45,50>>} </pre>
- </section>
- </section>
-
- <section>
- <title>Naming of Records in .hrl Files</title>
- <p>When an ASN.1 specification is compiled all defined types of
- type SET or SEQUENCE will result in a corresponding record in the
- generated hrl file. This is because the values for SET/SEQUENCE
- as mentioned in sections above are represented as records.</p>
- <p>Though there are some special cases of this functionality that
- are presented below.</p>
-
- <section>
- <title>Embedded Structured Types</title>
- <p>It is also possible in ASN.1 to have components that are themselves
- structured types.
- For example, it is possible to have:</p>
- <pre>
-Emb ::= SEQUENCE {
- a SEQUENCE OF OCTET STRING,
- b SET {
- a INTEGER,
- b INTEGER DEFAULT 66},
- c CHOICE {
- a INTEGER,
- b FooType } }
-
-FooType ::= [3] VisibleString </pre>
- <p>The following records are generated because of the type <c>Emb</c>:</p>
- <pre>
--record('Emb,{a, b, c}).
--record('Emb_b',{a, b = asn1_DEFAULT}). % the embedded SET type
- </pre>
- <p>Values of the <c>Emb</c> type can be assigned like this:</p>
- <code type="none">
-V = #'Emb'{a=["qqqq",[1,2,255]],
- b = #'Emb_b'{a=99},
- c ={b,"Can you see this"}}.
- </code>
- <p>For an embedded type of type SEQUENCE/SET in a SEQUENCE/SET
- the record name is extended with an underscore and the component
- name. If the embedded structure is deeper with SEQUENCE, SET or
- CHOICE types in the line, each component-/alternative-name will
- be added to the record-name.</p>
- <p>For example:</p>
- <pre>
-Seq ::= SEQUENCE{
- a CHOICE{
- b SEQUENCE {
- c INTEGER
- }
- }
-} </pre>
- <p>will result in the following record:</p>
- <pre>
--record('Seq_a_b',{c}). </pre>
- <p>If the structured type has a component with an embedded
- SEQUENCE OF/SET OF which embedded type in turn is a
- SEQUENCE/SET it will give a record with the SEQOF/SETOF
- addition as in the following example:</p>
- <pre>
-Seq ::= SEQUENCE {
- a SEQUENCE OF SEQUENCE {
- b
- }
- c SET OF SEQUENCE {
- d
- }
-} </pre>
- <p>This results in the records:</p>
- <pre>
--record('Seq_a_SEQOF'{b}).
--record('Seq_c_SETOF'{d}). </pre>
- <p>A parameterized type should be considered as an embedded
- type. Each time a such type is referenced an instance of it is
- defined. Thus in the following example a record with name
- <c>'Seq_b'</c> is generated in the .hrl file and used to hold
- values.</p>
- <pre>
-Seq ::= SEQUENCE {
- b PType{INTEGER}
-}
-
-PType{T} ::= SEQUENCE{
- id T
-} </pre>
- </section>
-
- <section>
- <title>Recursive Types</title>
- <p>Types may refer to themselves. Suppose:</p>
- <pre>
-Rec ::= CHOICE {
- nothing NULL,
- something SEQUENCE {
- a INTEGER,
- b OCTET STRING,
- c Rec }} </pre>
- <p>This type is recursive; that is, it refers to itself. This is allowed
- in ASN.1 and the ASN.1-to-Erlang compiler supports this recursive
- type. A value for this type is assigned in Erlang as shown below:</p>
- <pre>
-V = {something,#'Rec_something'{a = 77,
- b = "some octets here",
- c = {nothing,'NULL'}}}. </pre>
- </section>
- </section>
-
- <section>
- <title>ASN.1 Values</title>
- <p>Values can be assigned to ASN.1 type within the ASN.1 code
- itself, as opposed to the actions taken in the previous chapter where
- a value was assigned to an ASN.1 type in Erlang. The full value
- syntax of ASN.1 is supported and [X.680] describes in detail how
- to assign values in ASN.1. Below is a short example:</p>
- <pre>
-TT ::= SEQUENCE {
- a INTEGER,
- b SET OF OCTET STRING }
-
-tt TT ::= {a 77,b {"kalle","kula"}} </pre>
- <p>The value defined here could be used in several ways.
- Firstly, it could be used as the value in some DEFAULT component:</p>
- <pre>
-SS ::= SET {
- s OBJECT IDENTIFIER,
- val TT DEFAULT tt } </pre>
- <p>It could also be used from inside an Erlang program. If the above ASN.1
- code was defined in ASN.1 module <c>Values</c>, then the ASN.1 value
- <c>tt</c> can be reached from Erlang as
- a function call to <c>'Values':tt()</c> as in the example below.</p>
- <pre>
-1> <input>Val = 'Values':tt().</input>
-{'TT',77,["kalle","kula"]}
-2> <input>{ok,Bytes} = 'Values':encode('TT',Val).</input>
-{ok,&lt;&lt;48,18,128,1,77,161,13,4,5,107,97,108,108,101,4,4,
- 107,117,108,97&gt;&gt;}
-4> <input>'Values':decode('TT',Bytes).</input>
-{ok,{'TT',77,["kalle","kula"]}}
-5>
- </pre>
- <p>The above example shows that a function is generated by the compiler
- that returns a valid Erlang representation of the value, even though
- the value is of a complex type.</p>
- <p>Furthermore, there is a macro generated for each value in the .hrl
- file. So, the defined value <c>tt</c> can also be extracted by
- <c>?tt</c> in application code.</p>
- </section>
-
- <section>
- <title>Macros</title>
- <p>MACRO is not supported as the the type is no longer part of the
- ASN.1 standard.</p>
- </section>
-
- <section>
- <marker id="Information Object"></marker>
- <title>ASN.1 Information Objects (X.681)</title>
- <p>Information Object Classes, Information Objects and Information
- Object Sets (in the following called classes, objects and
- object sets respectively) are defined in the standard
- definition [<cite id="X.681"></cite>]. In the following only a brief
- explanation is given. </p>
- <p>These constructs makes it possible to define open types,
- i.e. values of that type can be of any ASN.1 type. It is also
- possible to define relationships between different types and
- values, since classes can hold types, values, objects, object
- sets and other classes in its fields.
- An Information Object Class may be defined in ASN.1 as:</p>
- <pre>
-GENERAL-PROCEDURE ::= CLASS {
- &amp;Message,
- &amp;Reply OPTIONAL,
- &amp;Error OPTIONAL,
- &amp;id PrintableString UNIQUE
-}
-WITH SYNTAX {
- NEW MESSAGE &amp;Message
- [REPLY &amp;Reply]
- [ERROR &amp;Error]
- ADDRESS &amp;id
-} </pre>
- <p>An object is an instance of a class and an object set is a set
- containing objects of one specified class. A definition may look like
- below.</p>
- <p>The object <c>object1</c> is an instance of the CLASS
- GENERAL-PROCEDURE and has one type field and one fixed type value
- field. The object <c>object2</c> also has an OPTIONAL field ERROR,
- which is a type field.</p>
- <pre>
-object1 GENERAL-PROCEDURE ::= {
- NEW MESSAGE PrintableString
- ADDRESS "home"
-}
-
-object2 GENERAL-PROCEDURE ::= {
- NEW MESSAGE INTEGER
- ERROR INTEGER
- ADDRESS "remote"
-} </pre>
- <p>The field ADDRESS is a UNIQUE field. Objects in an object set must
- have unique values in their UNIQUE field, as in GENERAL-PROCEDURES: </p>
- <pre>
-GENERAL-PROCEDURES GENERAL-PROCEDURE ::= {
- object1 | object2} </pre>
- <p>One can not encode a class, object or object set, only referring to
- it when defining other ASN.1 entities. Typically one refers to a
- class and to object sets by table constraints and component
- relation constraints [<cite id="X.682"></cite>] in ASN.1 types, as in: </p>
- <pre>
-StartMessage ::= SEQUENCE {
- msgId GENERAL-PROCEDURE.&amp;id ({GENERAL-PROCEDURES}),
- content GENERAL-PROCEDURE.&amp;Message ({GENERAL-PROCEDURES}{@msgId}),
- } </pre>
- <p>In the type <c>StartMessage</c> the constraint following the
- <c>content</c> field tells that in a value of type
- <c>StartMessage</c> the value in the <c>content</c> field must
- come from the same object that is chosen by the <c>msgId</c>
- field.</p>
- <p>So, the value <c>#'StartMessage'{msgId="home",content="Any Printable String"}</c> is legal to encode as a StartMessage
- value, while the value <c>#'StartMessage'{msgId="remote", content="Some String"}</c> is illegal since the constraint
- in StartMessage tells that when you have chosen a value from a
- specific object in the object set GENERAL-PROCEDURES in the
- msgId field you have to choose a value from that same object in
- the content field too. In this second case it should have been
- any INTEGER value.</p>
- <p><c>StartMessage</c> can in the <c>content</c> field be
- encoded with a value of any type that an object in the
- <c>GENERAL-PROCEDURES</c> object set has in its <c>NEW MESSAGE</c> field. This field refers to a type field
- <c>&amp;Message</c> in the class. The <c>msgId</c> field is always
- encoded as a PrintableString, since the field refers to a fixed type
- in the class.</p>
- <p>In practice, object sets are usually declared to be extensible so
- so that more objects can be added to the set later. Extensibility is
- indicated like this:</p>
- <pre>
-GENERAL-PROCEDURES GENERAL-PROCEDURE ::= {
- object1 | object2, ...} </pre>
- <p>When decoding a type that uses an extensible set constraint,
- there is always the possibility that the value in the UNIQUE
- field is unknown (i.e. the type has been encoded with a later
- version of the ASN.1 specification). When that happens, the
- unencoded data will be returned wrapped in a tuple like this:</p>
-
- <pre>
-{asn1_OPENTYPE,Binary}</pre>
- <p>where <c>Binary</c> is an Erlang binary that contains the encoded
- data. (If the option <c>legacy_erlang_types</c> has been given,
- just the binary will be returned.)</p>
- </section>
-
- <section>
- <title>Parameterization (X.683)</title>
- <p>Parameterization, which is defined in the standard [<cite id="X.683"></cite>], can be used when defining types, values, value
- sets, information object classes, information objects or
- information object sets.
- A part of a definition can be supplied as a parameter. For
- instance, if a Type is used in a definition with certain
- purpose, one want the type-name to express the intention. This
- can be done with parameterization.</p>
- <p>When many types (or another ASN.1 entity) only differs in some
- minor cases, but the structure of the types are similar, only
- one general type can be defined and the differences may be supplied
- through parameters. </p>
- <p>One example of use of parameterization is:</p>
- <pre>
-General{Type} ::= SEQUENCE
-{
- number INTEGER,
- string Type
-}
-
-T1 ::= General{PrintableString}
-
-T2 ::= General{BIT STRING}
- </pre>
- <p>An example of a value that can be encoded as type T1 is {12,"hello"}.</p>
- <p>Note that the compiler does not generate encode/decode functions for
- parameterized types, but only for the instances of the parameterized
- types. Therefore, if a file contains the types General{}, T1 and T2 above,
- encode/decode functions will only be generated for T1 and T2.
- </p>
- </section>
-</chapter>
-
diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index 32ff2d52cf..e056a89432 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -35,43 +36,45 @@
<modulesummary>ASN.1 compiler and compile-time support functions</modulesummary>
<description>
<p>The ASN.1 compiler takes an ASN.1 module as input and generates a
- corresponding Erlang module which can encode and decode the data-types
- specified. Alternatively the compiler takes a specification module
- (se below) specifying all input modules and generates one module with
- encode/decode functions. There are also some generic functions which
- can be used in during development of applications which handles ASN.1
- data (encoded as BER or PER).</p>
+ corresponding Erlang module, which can encode and decode the specified
+ data types. Alternatively, the compiler takes a specification module
+ specifying all input modules, and generates a module with
+ encode/decode functions. In addition, some generic functions
+ can be used during development of applications that handles ASN.1
+ data (encoded as <c>BER</c> or <c>PER</c>).</p>
+
<note>
- <p>By default in OTP 17, the representation of the BIT STRING
- and OCTET STRING types as Erlang terms have changed. BIT
- STRING values are now Erlang bitstrings and OCTET STRING values
- are binaries. Also, an undecoded open type will now be wrapped in
- a <c>asn1_OPENTYPE</c> tuple. For details see <seealso
- marker="asn1_ug#BIT STRING">BIT STRING</seealso>, <seealso
- marker="asn1_ug#OCTET STRING">OCTET STRING</seealso>, and
- <seealso marker="asn1_ug#Information%20Object">ASN.1 Information Objects</seealso> in User's Guide.</p>
- <p>To revert to the old representation of the types, use the
- <c>legacy_erlang_types</c> option.</p>
+ <p>By default in OTP 17, the representation of the <c>BIT STRING</c>
+ and <c>OCTET STRING</c> types as Erlang terms were changed. <c>BIT
+ STRING</c> values are now Erlang bit strings and <c>OCTET STRING</c>
+ values are binaries. Also, an undecoded open type is now wrapped in
+ an <c>asn1_OPENTYPE</c> tuple. For details, see <seealso
+ marker="asn1_getting_started#BIT STRING">BIT STRING</seealso>, <seealso
+ marker="asn1_getting_started#OCTET STRING">OCTET STRING</seealso>, and
+ <seealso marker="asn1_getting_started#Information Object">ASN.1 Information Objects</seealso> in the User's Guide.</p>
+ <p>To revert to the old representation of the types, use option
+ <c>legacy_erlang_types</c>.</p>
</note>
+
<note>
- <p>In R16, the options have been simplified. The back-end is chosen
+ <p>In OTP R16, the options were simplified. The back end is chosen
using one of the options <c>ber</c>, <c>per</c>, or <c>uper</c>.
- The options <c>optimize</c>, <c>nif</c>, and <c>driver</c> options
- are no longer necessary (and the ASN.1 compiler will print a
- warning if they are used). The options <c>ber_bin</c>, <c>per_bin</c>,
- and <c>uper_bin</c> options will still work, but will print a warning.
+ Options <c>optimize</c>, <c>nif</c>, and <c>driver</c> options
+ are no longer necessary (and the ASN.1 compiler generates a
+ warning if they are used). Options <c>ber_bin</c>, <c>per_bin</c>,
+ and <c>uper_bin</c> options still work, but generates a warning.
</p>
- <p>Another change in R16 is that the generated <c>encode/2</c>
- function always returns a binary.
- The <c>encode/2</c> function for the BER back-end used to return
- an iolist.</p>
+ <p>Another change in OTP R16 is that the generated function
+ <c>encode/2</c> always returns a binary. Function <c>encode/2</c>
+ for the <c>BER</c> back end used to return an iolist.</p>
</note>
</description>
+
<funcs>
<func>
<name>compile(Asn1module) -> ok | {error, Reason}</name>
<name>compile(Asn1module, Options) -> ok | {error, Reason}</name>
- <fsummary>Compile an ASN.1 module and generate encode/decode functions according to the encoding rules BER or PER.</fsummary>
+ <fsummary>Compiles an ASN.1 module and generates encode/decode functions according to encoding rules BER or PER.</fsummary>
<type>
<v>Asn1module = atom() | string()</v>
<v>Options = [Option| OldOption]</v>
@@ -85,79 +88,82 @@
<v>Prefix = string()</v>
</type>
<desc>
- <p>Compiles the ASN.1 module <c>Asn1module</c> and generates an
- Erlang module <c>Asn1module.erl</c> with encode and decode
+ <p>Compiles the <c>ASN.1</c> module <c>Asn1module</c> and generates
+ an Erlang module <c>Asn1module.erl</c> with encode and decode
functions for the types defined in <c>Asn1module</c>. For each
- ASN.1 value defined in the module an Erlang function which
+ ASN.1 value defined in the module, an Erlang function that
returns the value in Erlang representation is generated.</p>
- <p>If <c>Asn1module</c> is a filename without extension first
- <c>".asn1"</c> is assumed, then <c>".asn"</c> and finally
+ <p>If <c>Asn1module</c> is a filename without extension, first
+ <c>".asn1"</c> is assumed, then <c>".asn"</c>, and finally
<c>".py"</c> (to be compatible with the old ASN.1 compiler).
- Of course <c>Asn1module</c> can be a full pathname (relative or
+ <c>Asn1module</c> can be a full pathname (relative or
absolute) including filename with (or without) extension.
<marker id="asn1set"></marker>
</p>
- <p>If one wishes to compile a set of Asn1 modules into one
- Erlang file with encode/decode functions one has to list all
+ <p>If it is needed to compile a set of <c>ASN.1</c> modules into an
+ Erlang file with encode/decode functions, ensure to list all
involved files in a configuration file. This configuration
- file must have a double extension ".set.asn", (".asn" can
- alternatively be ".asn1" or ".py"). The input files' names
- must be listed, within quotation marks (""), one at each row
+ file must have a double extension <c>".set.asn"</c>
+ (<c>".asn"</c> can alternatively be <c>".asn1"</c> or <c>".py"</c>).
+ List the input file names
+ within quotation marks (""), one at each row
in the file. If the input files are <c>File1.asn</c>,
- <c>File2.asn</c> and <c>File3.asn</c> the configuration file
- shall look like:</p>
+ <c>File2.asn</c>, and <c>File3.asn</c>, the configuration file
+ must look as follows:</p>
<pre>
File1.asn
File2.asn
-File3.asn </pre>
- <p>The output files will in this case get their names from the
- configuration file. If the configuration file has the name
- <c>SetOfFiles.set.asn</c> the name of the output files will be
- <c>SetOfFiles.hrl, SetOfFiles.erl and SetOfFiles.asn1db</c>.</p>
- <p>Sometimes in a system of ASN.1 modules there are different
- default tag modes, e.g. AUTOMATIC, IMPLICIT or EXPLICIT. The
- multi file compilation resolves the default tagging as if
+File3.asn</pre>
+ <p>The output files in this case get their names from the
+ configuration file. If the configuration file is named
+ <c>SetOfFiles.set.asn</c>, the names of the output files are
+ <c>SetOfFiles.hrl, SetOfFiles.erl, and SetOfFiles.asn1db</c>.</p>
+ <p>Sometimes in a system of <c>ASN.1</c> modules, different
+ default tag modes, for example, <c>AUTOMATIC</c>, <c>IMPLICIT</c>,
+ or <c>EXPLICIT</c>. The
+ multi-file compilation resolves the default tagging as if
the modules were compiled separately.</p>
- <p>Another unwanted effect that may occur in multi file compilation
- is name collisions. The compiler solves this problem in two
- ways: If the definitions are identical then the output module
- keeps only one definition with the original name. But if
- definitions only have same name and differs in the definition,
- then they will be renamed. The new names will be the definition
- name and the original module name concatenated.</p>
- <p>If any name collision have occurred the compiler reports a
- "NOTICE: ..." message that tells if a definition was renamed,
+ <p>Name collisions is another unwanted effect that can occur in
+ multi file-compilation. The compiler solves this problem in one
+ of two ways:</p>
+ <list type="bulleted">
+ <item>If the definitions are identical, the output module
+ keeps only one definition with the original name.</item>
+ <item>If the definitions have the same name and differs in the
+ definition, they are renamed. The new names are the definition
+ name and the original module name concatenated.</item>
+ </list>
+ <p>If a name collision occurs, the compiler reports a
+ <c>"NOTICE: ..."</c> message that tells if a definition was renamed,
and the new name that must be used to encode/decode data.</p>
-
- <p>
- <c>Options</c> is a list with options specific for the asn1
+ <p><c>Options</c> is a list with options specific for the <c>ASN.1</c>
compiler and options that are applied to the Erlang compiler.
- The latter are those that not is recognized as asn1 specific.
- Available options are:
+ The latter are not recognized as <c>ASN.1</c> specific. The
+ available options are as follows:
</p>
<taglist>
<tag><c>ber | per | uper</c></tag>
<item>
<p>
The encoding rule to be used. The supported encoding rules
- are BER (Basic Encoding Rules),
- PER aligned (Packed Encoding Rules) and PER unaligned.
- If the encoding rule option is omitted <c>ber</c>
+ are Basic Encoding Rules (BER),
+ Packed Encoding Rules (PER) aligned, and PER unaligned.
+ If the encoding rule option is omitted, <c>ber</c>
is the default.
</p>
<p>
The generated Erlang module always gets the same name
- as the ASN.1 module and as a consequence of this only one
- encoding rule per ASN.1 module can be used at runtime.
+ as the <c>ASN.1</c> module. Therefore, only one
+ encoding rule per <c>ASN.1</c> module can be used at runtime.
</p>
</item>
<tag><c>der</c></tag>
<item>
<p>
- By this option the Distinguished Encoding Rules (DER) is chosen.
+ With this option the Distinguished Encoding Rules (DER) is chosen.
DER is regarded as a specialized variant of the BER encoding
- rule, therefore the <c>der</c> option only makes sense together
- with the <c>ber</c> option.
+ rule. Therefore, this option only makes sense together
+ with option <c>ber</c>.
This option
sometimes adds sorting and value checks when encoding, which
implies a slower encoding. The decoding routines are the same
@@ -167,118 +173,123 @@ File3.asn </pre>
<tag><c>compact_bit_string</c></tag>
<item>
<p>
- The BIT STRING type will be decoded to the "compact notation".
+ The <c>BIT STRING</c> type is decoded to "compact notation".
<em>This option is not recommended for new code.</em>
</p>
- <p>For details see
- <seealso marker="asn1_ug#BIT STRING">
- BIT STRING type section in the Users Guide
- </seealso>.
+ <p>For details, see Section
+ <seealso marker="asn1_getting_started#BIT STRING">
+ BIT STRING</seealso> in the User's Guide.
</p>
- <p>This option implies the <c>legacy_erlang_types</c> option.</p>
+ <p>This option implies option <c>legacy_erlang_types</c>.</p>
</item>
<tag><c>legacy_bit_string</c></tag>
<item>
<p>
- The BIT STRING type will be decoded to the legacy
- format, i.e. a list of zeroes and ones.
+ The <c>BIT STRING</c> type is decoded to the legacy
+ format, that is, a list of zeroes and ones.
<em>This option is not recommended for new code.</em>
</p>
- <p>For details see
- <seealso marker="asn1_ug#BIT STRING">
- BIT STRING type section in the Users Guide
- </seealso>.
- <p>This option implies the <c>legacy_erlang_types</c> option.</p>
- </p>
+ <p>For details, see Section
+ <seealso marker="asn1_getting_started#BIT STRING">BIT STRING</seealso>
+ in the User's Guide</p>
+ <p>This option implies option <c>legacy_erlang_types</c>.</p>
</item>
<tag><c>legacy_erlang_types</c></tag>
<item>
- <p>Use the same Erlang types to represent BIT STRING and
- OCTET STRING as in R16. For details see <seealso
- marker="asn1_ug#BIT STRING">BIT STRING</seealso> and
- <seealso marker="asn1_ug#OCTET STRING">OCTET
- STRING</seealso> in User's Guide.</p>
- <p><em>This option is not recommended for
- new code.</em></p>
+ <p>Use the same Erlang types to represent <c>BIT STRING</c> and
+ <c>OCTET STRING</c> as in OTP R16.</p>
+ <p>For details, see Section <seealso
+ marker="asn1_getting_started#BIT STRING">BIT STRING</seealso> and Section
+ <seealso marker="asn1_getting_started#OCTET STRING">OCTET
+ STRING</seealso> in the User's Guide.</p>
+ <p><em>This option is not recommended for new code.</em></p>
</item>
<tag><c>{n2n, EnumTypeName}</c></tag>
<item>
<p>
- Tells the compiler to generate functions for conversion between
- names (as atoms) and numbers and vice versa for the EnumTypeName specified. There can be multiple occurrences of this option in order to specify several type names. The type names must be declared as ENUMERATIONS in the ASN.1 spec.
- If the EnumTypeName does not exist in the ASN.1 spec the
- compilation will stop with an error code.
- The generated conversion functions are named
+ Tells the compiler to generate functions for conversion
+ between names (as atoms) and numbers and conversely for
+ the specified <c>EnumTypeName</c>. There can be multiple
+ occurrences of this option to specify several type names.
+ The type names must be declared as <c>ENUMERATIONS</c> in
+ the ASN.1 specification.</p>
+ <p>
+ If <c>EnumTypeName</c> does not exist in the ASN.1 specification,
+ the compilation stops with an error code.</p>
+ <p>
+ The generated conversion functions are named
<c>name2num_EnumTypeName/1</c> and
<c>num2name_EnumTypeName/1</c>.
</p>
</item>
<tag><c>noobj</c></tag>
<item>
- <p>Do not compile (i.e do not produce object code) the generated
- <c>.erl</c> file. If this option is omitted the generated Erlang module
- will be compiled.</p>
+ <p>Do not compile (that is, do not produce object code) the
+ generated <c>.erl</c> file. If this option is omitted, the
+ generated Erlang module is compiled.</p>
</item>
<tag><c>{i, IncludeDir}</c></tag>
<item>
<p>Adds <c>IncludeDir</c> to the search-path for
- <c>.asn1db</c> and asn1 source files. The compiler tries
- to open a <c>.asn1db</c> file when a module imports
- definitions from another ASN.1 module. If no
- <c>.asn1db</c> file is found the asn1 source file is
- parsed. Several <c>{i, IncludeDir}</c> can be given.
+ <c>.asn1db</c> and <c>ASN.1</c> source files. The compiler
+ tries to open an <c>.asn1db</c> file when a module imports
+ definitions from another <c>ASN.1</c> module. If no
+ <c>.asn1db</c> file is found, the <c>ASN.1</c> source file is
+ parsed. Several <c>{i, IncludeDir}</c> can be given.
</p>
</item>
<tag><c>{outdir, Dir}</c></tag>
<item>
- <p>Specifies the directory <c>Dir</c> where all generated files
- shall be placed. If omitted the files are placed in the
- current directory.</p>
+ <p>Specifies directory <c>Dir</c> where all generated files
+ are to be placed. If this option is omitted, the files are
+ placed in the current directory.</p>
</item>
<tag><c>asn1config</c></tag>
<item>
- <p>When one of the specialized decodes, exclusive or
- selective decode, is wanted one has to give instructions in
- a configuration file. The option <c>asn1config</c> enables
- specialized decodes and takes the configuration file, which
- has the same name as the ASN.1 spec but with extension
- <c>.asn1config</c>, in concern.
+ <p>When using one of the specialized decodes, exclusive or
+ selective decode, instructions must be given in
+ a configuration file. Option <c>asn1config</c> enables
+ specialized decodes and takes the configuration file in
+ concern. The configuration file has
+ the same name as the ASN.1 specification, but with extension
+ <c>.asn1config</c>.
</p>
- <p>The instructions for exclusive decode must follow the
- <seealso marker="asn1_spec#Exclusive Instruction">instruction and grammar in the User's Guide</seealso>.
+ <p>For instructions for exclusive decode, see Section
+ <seealso marker="asn1_spec#Exclusive Instruction">Exclusive
+ Decode</seealso> in the User's Guide.
</p>
- <p>You can also find the instructions for selective decode
- in the
- <seealso marker="asn1_spec#Selective Instruction">User's Guide</seealso>.
+ <p>For instructions for selective decode, see Section
+ <seealso marker="asn1_spec#Selective Instruction">Selective
+ Decode</seealso> in the User's Guide.
</p>
</item>
<tag><c>undec_rest</c></tag>
<item>
- <p>A buffer that holds a message, being decoded may
- also have some following bytes. Now it is possible to get
- those following bytes returned together with the decoded
- value. If an asn1 spec is compiled with this option a tuple
- <c>{ok, Value, Rest}</c> is returned. <c>Rest</c> may be a
+ <p>A buffer that holds a message, being decoded it can also
+ have some following bytes. Those following bytes can now
+ be returned together with the decoded value. If an
+ ASN.1 specification is compiled with this option, a tuple
+ <c>{ok, Value, Rest}</c> is returned. <c>Rest</c> can be a
list or a binary. Earlier versions of the compiler ignored
those following bytes.</p>
</item>
<tag><c>no_ok_wrapper</c></tag>
<item>
- <p>If this option is given, the generated <c>encode/2</c>
- and <c>decode/2</c> functions will not wrap a successful
+ <p>With this option, the generated <c>encode/2</c>
+ and <c>decode/2</c> functions do not wrap a successful
return value in an <c>{ok,...}</c> tuple. If any error
- occurs, there will be an exception.</p>
+ occurs, an exception will be raised.</p>
</item>
<tag><c>{macro_name_prefix, Prefix}</c></tag>
<item>
<p>All macro names generated by the compiler are prefixed with
- <c>Prefix</c>. This is useful when multiple protocols that contains
+ <c>Prefix</c>. This is useful when multiple protocols that contain
macros with identical names are included in a single module.</p>
</item>
<tag><c>{record_name_prefix, Prefix}</c></tag>
<item>
<p>All record names generated by the compiler are prefixed with
- <c>Prefix</c>. This is useful when multiple protocols that contains
+ <c>Prefix</c>. This is useful when multiple protocols that contain
records with identical names are included in a single module.</p>
</item>
<tag><c>verbose</c></tag>
@@ -291,27 +302,27 @@ File3.asn </pre>
<p>Causes warnings to be treated as errors.</p>
</item>
</taglist>
- <p>Any additional option that is applied will be passed to
- the final step when the generated .erl file is compiled.
+ <p>Any more option that is applied is passed to
+ the final step when the generated <c>.erl</c> file is compiled.
</p>
<p>The compiler generates the following files:</p>
<list type="bulleted">
- <item>
- <p><c>Asn1module.hrl</c> (if any SET or SEQUENCE is defined)</p>
+ <item><c>Asn1module.hrl</c> (if any <c>SET</c> or <c>SEQUENCE</c>
+ is defined)
</item>
- <item>
- <p><c>Asn1module.erl</c> the Erlang module with encode, decode and value functions.</p>
+ <item><c>Asn1module.erl</c> - Erlang module with encode, decode,
+ and value functions
</item>
- <item>
- <p><c>Asn1module.asn1db</c> intermediate format used by the compiler when modules IMPORTS
- definitions from each other.</p>
+ <item><c>Asn1module.asn1db</c> - Intermediate format used by the
+ compiler when modules <c>IMPORT</c> definitions from each other.
</item>
</list>
</desc>
</func>
+
<func>
<name>encode(Module, Type, Value)-> {ok, Bytes} | {error, Reason}</name>
- <fsummary>Encode an ASN.1 value.</fsummary>
+ <fsummary>Encodes an ASN.1 value.</fsummary>
<type>
<v>Module = Type = atom()</v>
<v>Value = term()</v>
@@ -319,11 +330,11 @@ File3.asn </pre>
<v>Reason = term()</v>
</type>
<desc>
- <p>Encodes <c>Value</c> of <c>Type</c> defined in the ASN.1 module
- <c>Module</c>. To get as fast execution as possible the
- encode function only performs rudimentary tests that the input
- <c>Value</c>
- is a correct instance of <c>Type</c>. The length of strings is for example
+ <p>Encodes <c>Value</c> of <c>Type</c> defined in the <c>ASN.1</c> module
+ <c>Module</c>. To get as fast execution as possible, the
+ encode function performs only the rudimentary tests that input
+ <c>Value</c> is a correct instance of <c>Type</c>. So, for example,
+ the length of strings is
not always checked. Returns <c>{ok, Bytes}</c> if successful or
<c>{error, Reason}</c> if an error occurred.
</p>
@@ -331,6 +342,7 @@ File3.asn </pre>
Use <c>Module:encode(Type, Value)</c> instead.</p>
</desc>
</func>
+
<func>
<name>decode(Module, Type, Bytes) -> {ok, Value} | {error, Reason}</name>
<fsummary>Decode from Bytes into an ASN.1 value.</fsummary>
@@ -346,26 +358,37 @@ File3.asn </pre>
Use <c>Module:decode(Type, Bytes)</c> instead.</p>
</desc>
</func>
+
<func>
<name>value(Module, Type) -> {ok, Value} | {error, Reason}</name>
- <fsummary>Create an ASN.1 value for test purposes.</fsummary>
+ <fsummary>Creates an ASN.1 value for test purposes.</fsummary>
<type>
<v>Module = Type = atom()</v>
<v>Value = term()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Returns an Erlang term which is an example of a valid Erlang
- representation of a value of the ASN.1 type <c>Type</c>. The value
+ <p>Returns an Erlang term that is an example of a valid Erlang
+ representation of a value of the <c>ASN.1</c> type <c>Type</c>. The value
is a random value and subsequent calls to this function will for most
types return different values.</p>
+ <note>
+ <p>Currently, the <c>value</c> function has many limitations.
+ Essentially, it will mostly work for old specifications based
+ on the 1997 standard for ASN.1, but not for most modern-style
+ applications. Another limitation is that the <c>value</c> function
+ may not work if options that change code generations strategies
+ such as the options <c>macro_name_prefix</c> and
+ <c>record_name_prefix</c> have been used.</p>
+ </note>
</desc>
</func>
+
<func>
<name>test(Module) -> ok | {error, Reason}</name>
<name>test(Module, Type | Options) -> ok | {error, Reason}</name>
<name>test(Module, Type, Value | Options) -> ok | {error, Reason}</name>
- <fsummary>Perform a test of encode and decode for types in an ASN.1 module.</fsummary>
+ <fsummary>Performs a test of encode and decode for types in an ASN.1 module.</fsummary>
<type>
<v>Module = Type = atom()</v>
<v>Value = term()</v>
@@ -376,9 +399,17 @@ File3.asn </pre>
<p>Performs a test of encode and decode of types in <c>Module</c>.
The generated functions are called by this function.
This function is useful during test to secure that the generated
- encode and decode functions and the general runtime support work
- as expected.</p>
-
+ encode and decode functions as well as the general runtime support
+ work as expected.</p>
+ <note>
+ <p>Currently, the <c>test</c> functions have many limitations.
+ Essentially, they will mostly work for old specifications based
+ on the 1997 standard for ASN.1, but not for most modern-style
+ applications. Another limitation is that the <c>test</c> functions
+ may not work if options that change code generations strategies
+ such as the options <c>macro_name_prefix</c> and
+ <c>record_name_prefix</c> have been used.</p>
+ </note>
<list type="bulleted">
<item>
<p><c>test/1</c> iterates over all types in <c>Module</c>.</p>
@@ -390,14 +421,12 @@ File3.asn </pre>
<p><c>test/3</c> tests type <c>Type</c> with <c>Value</c>.</p>
</item>
</list>
-
- <p>Schematically the following happens for each type in the module:</p>
+ <p>Schematically, the following occurs for each type in the module:</p>
<code type="none">
{ok, Value} = asn1ct:value(Module, Type),
{ok, Bytes} = asn1ct:encode(Module, Type, Value),
{ok, Value} = asn1ct:decode(Module, Type, Bytes).</code>
-
- <p>The <c>test</c> functions utilizes the <c>*.asn1db</c> files
+ <p>The <c>test</c> functions use the <c>*.asn1db</c> files
for all included modules. If they are located in a different
directory than the current working directory, use the include
option to add paths. This is only needed when automatically
diff --git a/lib/asn1/doc/src/asn1rt.xml b/lib/asn1/doc/src/asn1rt.xml
index 3cf56b01ca..65556f3f87 100644
--- a/lib/asn1/doc/src/asn1rt.xml
+++ b/lib/asn1/doc/src/asn1rt.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -46,7 +47,7 @@
<func>
<name>decode(Module,Type,Bytes) -> {ok,Value}|{error,Reason}</name>
- <fsummary>Decode from bytes into an ASN.1 value.</fsummary>
+ <fsummary>Decodes from Bytes into an ASN.1 value.</fsummary>
<type>
<v>Module = Type = atom()</v>
<v>Value = Reason = term()</v>
@@ -61,7 +62,7 @@
<func>
<name>encode(Module,Type,Value)-> {ok,Bytes} | {error,Reason}</name>
- <fsummary>Encode an ASN.1 value.</fsummary>
+ <fsummary>Encodes an ASN.1 value.</fsummary>
<type>
<v>Module = Type = atom()</v>
<v>Value = term()</v>
@@ -69,12 +70,12 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Encodes <c>Value</c> of <c>Type</c> defined in the ASN.1
+ <p>Encodes <c>Value</c> of <c>Type</c> defined in the <c>ASN.1</c>
module <c>Module</c>. Returns a binary if successful. To get
- as fast execution as possible the encode function only
- performs rudimentary tests that the input <c>Value</c> is a
- correct instance of <c>Type</c>. The length of strings is, for
- example, not always checked. </p>
+ as fast execution as possible, the encode function performs
+ only the rudimentary test that input <c>Value</c> is a correct
+ instance of <c>Type</c>. For example, the length of strings is
+ not always checked.</p>
<p>Use <c>Module:encode(Type, Value)</c> instead of this function.</p>
</desc>
</func>
@@ -88,23 +89,23 @@
<v>Reason = term()</v>
</type>
<desc>
- <p><c>info/1</c> returns the version of the asn1 compiler that was
+ <p>Returns the version of the <c>ASN.1</c> compiler that was
used to compile the module. It also returns the compiler options
- that was used.</p>
+ that were used.</p>
<p>Use <c>Module:info()</c> instead of this function.</p>
</desc>
</func>
<func>
<name>utf8_binary_to_list(UTF8Binary) -> {ok,UnicodeList} | {error,Reason}</name>
- <fsummary>Transforms an utf8 encoded binary to a unicode list.</fsummary>
+ <fsummary>Transforms an UTF8 encoded binary to a unicode list.</fsummary>
<type>
<v>UTF8Binary = binary()</v>
<v>UnicodeList = [integer()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p><c>utf8_binary_to_list/1</c> Transforms a UTF8 encoded binary
+ <p>Transforms a UTF8 encoded binary
to a list of integers, where each integer represents one
character as its unicode value. The function fails if the binary
is not a properly encoded UTF8 string.</p>
@@ -114,14 +115,14 @@
<func>
<name>utf8_list_to_binary(UnicodeList) -> {ok,UTF8Binary} | {error,Reason}</name>
- <fsummary>Transforms an unicode list ot an utf8 binary.</fsummary>
+ <fsummary>Transforms an unicode list to a UTF8 binary.</fsummary>
<type>
<v>UnicodeList = [integer()]</v>
<v>UTF8Binary = binary()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p><c>utf8_list_to_binary/1</c> Transforms a list of integers,
+ <p>Transforms a list of integers,
where each integer represents one character as its unicode
value, to a UTF8 encoded binary.</p>
<p>Use <seealso marker="stdlib:unicode#characters_to_binary-1">unicode:characters_to_binary/1</seealso> instead of this function.</p>
diff --git a/lib/asn1/doc/src/book.xml b/lib/asn1/doc/src/book.xml
index 2399267cb0..0947938429 100644
--- a/lib/asn1/doc/src/book.xml
+++ b/lib/asn1/doc/src/book.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index 9feb673c04..78d856b0be 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,6 +32,80 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 4.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When compiling to the PER format, the ASN.1 compiler
+ would crash when attempting to compile an ASN.1 module
+ with a constrained INTEGER with more than 65536 values
+ and named values. (Thanks to Ingars for reporting this
+ bug.)</p>
+ <p>
+ Own Id: OTP-13257</p>
+ </item>
+ <item>
+ <p>The ASN.1 compiler will now emit Dialyzer suppressions
+ for improper lists. Thus, there is no longer any need to
+ use <c>--Wno_improper_lists</c> when analyzing modules
+ generated by the ASN.1 compiler.</p>
+ <p>
+ Own Id: OTP-13324</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Asn1 4.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Trying to encode an empty named BIT STRING in BER would
+ fail with a <c>function_clause</c> exception. (Thanks to
+ Svilen Ivanov for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13149</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Asn1 4.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Many bugs have been eliminated in the the ASN.1 compiler
+ so that it can now successfully compile many more ASN.1
+ specifications. Error messages have also been improved.</p>
+ <p>
+ Own Id: OTP-12395</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation for <c>asn1ct:test/1,2,3</c> and
+ <c>asn1ct:value/2</c> has been updated with information
+ about the limitations of the functions.</p>
+ <p>
+ Own Id: OTP-12765 Aux Id: seq12866, seq12867 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Asn1 3.0.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/asn1/doc/src/part.xml b/lib/asn1/doc/src/part.xml
index 735ec2e616..9423dc5b9e 100644
--- a/lib/asn1/doc/src/part.xml
+++ b/lib/asn1/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,11 +30,14 @@
<file>part.sgml</file>
</header>
<description>
- <p>The <em>Asn1</em> application
- contains modules with compile-time and run-time support for ASN.1.
+ <p>The <c>ASN.1</c> application
+ contains modules with compile-time and runtime support for
+ Abstract Syntax Notation One (ASN.1).
</p>
</description>
- <xi:include href="asn1_ug.xml"/>
+ <xi:include href="asn1_introduction.xml"/>
+ <xi:include href="asn1_overview.xml"/>
+ <xi:include href="asn1_getting_started.xml"/>
<xi:include href="asn1_spec.xml"/>
</part>
diff --git a/lib/asn1/doc/src/ref_man.xml b/lib/asn1/doc/src/ref_man.xml
index 0a0ed5416a..01f42f54db 100644
--- a/lib/asn1/doc/src/ref_man.xml
+++ b/lib/asn1/doc/src/ref_man.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Asn1 Reference Manual</title>
+ <title>ASN.1 Reference Manual</title>
<prepared>OTP Team</prepared>
<docno></docno>
<date>1997-10-04</date>
@@ -29,8 +30,8 @@
<file>application.sgml</file>
</header>
<description>
- <p>The <em>Asn1</em> application
- contains modules with compile-time and run-time support for ASN.1.</p>
+ <p>The <c>ASN.1</c> application
+ contains modules with compile-time and runtime support for ASN.1.</p>
</description>
<xi:include href="asn1ct.xml"/>
<xi:include href="asn1rt.xml"/>
diff --git a/lib/asn1/doc/users_guide/Makefile b/lib/asn1/doc/users_guide/Makefile
index 996b2582af..ae3a55b945 100644
--- a/lib/asn1/doc/users_guide/Makefile
+++ b/lib/asn1/doc/users_guide/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/asn1/doc/users_guide/users_guide.sgml b/lib/asn1/doc/users_guide/users_guide.sgml
index 9387e6b9ab..ff4289c419 100644
--- a/lib/asn1/doc/users_guide/users_guide.sgml
+++ b/lib/asn1/doc/users_guide/users_guide.sgml
@@ -1,15 +1,16 @@
<!doctype userguide PUBLIC "-//Stork//DTD userguide//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile
index 6798da0072..5b34017e9b 100644
--- a/lib/asn1/src/Makefile
+++ b/lib/asn1/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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.
+# Licensed under the Apache License, Version 2.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%
#
@@ -206,6 +207,7 @@ $(EBIN)/asn1ct_constructed_per.beam: asn1ct_constructed_per.erl asn1_records.hrl
$(EBIN)/asn1ct_func.beam: asn1ct_func.erl
$(EBIN)/asn1ct_gen.beam: asn1ct_gen.erl asn1_records.hrl
$(EBIN)/asn1ct_gen_ber_bin_v2.beam: asn1ct_gen_ber_bin_v2.erl asn1_records.hrl
+$(EBIN)/asn1ct_gen_check.beam: asn1_records.hrl
$(EBIN)/asn1ct_gen_per.beam: asn1ct_gen_per.erl asn1_records.hrl
$(EBIN)/asn1ct_gen_per_rt2ct.beam: asn1ct_gen_per_rt2ct.erl asn1_records.hrl
$(EBIN)/asn1ct_imm.beam: asn1ct_imm.erl
diff --git a/lib/asn1/src/asn1.app.src b/lib/asn1/src/asn1.app.src
index 02cbba0f10..1f8805ff5e 100644
--- a/lib/asn1/src/asn1.app.src
+++ b/lib/asn1/src/asn1.app.src
@@ -11,5 +11,5 @@
]},
{env, []},
{applications, [kernel, stdlib]},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}
+ {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-7.0"]}
]}.
diff --git a/lib/asn1/src/asn1.appup.src b/lib/asn1/src/asn1.appup.src
index e4b3508cc4..66907055b9 100644
--- a/lib/asn1/src/asn1.appup.src
+++ b/lib/asn1/src/asn1.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/asn1/src/asn1_app.erl b/lib/asn1/src/asn1_app.erl
index 9fff96e0bf..d1d8a955c2 100644
--- a/lib/asn1/src/asn1_app.erl
+++ b/lib/asn1/src/asn1_app.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/asn1/src/asn1_db.erl b/lib/asn1/src/asn1_db.erl
index 48d9dd16d7..32052885d3 100644
--- a/lib/asn1/src/asn1_db.erl
+++ b/lib/asn1/src/asn1_db.erl
@@ -3,23 +3,25 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(asn1_db).
--export([dbstart/1,dbnew/2,dbload/1,dbload/3,dbsave/2,dbput/3,dbget/2]).
+-export([dbstart/1,dbnew/2,dbload/1,dbload/3,dbsave/2,dbput/2,
+ dbput/3,dbget/2]).
-export([dbstop/0]).
-record(state, {parent, monitor, includes, table}).
@@ -44,6 +46,7 @@ dbload(Module) ->
dbnew(Module, Erule) -> req({new, Module, Erule}).
dbsave(OutFile, Module) -> cast({save, OutFile, Module}).
dbput(Module, K, V) -> cast({set, Module, K, V}).
+dbput(Module, Kvs) -> cast({set, Module, Kvs}).
dbget(Module, K) -> req({get, Module, K}).
dbstop() -> Resp = req(stop), erase(?MODULE), Resp.
@@ -82,6 +85,10 @@ loop(#state{parent = Parent, monitor = MRef, table = Table,
[{_, Modtab}] = ets:lookup(Table, Mod),
ets:insert(Modtab, {K2, V}),
loop(State);
+ {set, Mod, Kvs} ->
+ [{_, Modtab}] = ets:lookup(Table, Mod),
+ ets:insert(Modtab, Kvs),
+ loop(State);
{From, {get, Mod, K2}} ->
%% XXX If there is no information for Mod, get_table/3
%% will attempt to load information from an .asn1db
diff --git a/lib/asn1/src/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl
index 6c1cf1b12a..1ffc6c2980 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -81,9 +82,19 @@
module :: atom(),
val :: atom()}).
--record(state,{module,mname,type,tname,value,vname,erule,parameters=[],
- inputmodules,abscomppath=[],recordtopname=[],options,
- sourcedir}).
+-record(state,
+ {module,
+ mname,
+ tname,
+ erule,
+ parameters=[],
+ inputmodules=[],
+ abscomppath=[],
+ recordtopname=[],
+ options,
+ sourcedir,
+ error_context %Top-level thingie (contains line numbers)
+ }).
%% state record used by back-end at partial decode
%% active is set to 'yes' when a partial decode function is generated.
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index df341e5aab..d0ab947f32 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,7 +35,8 @@
%% Application internal exports
-export([compile_asn/3,compile_asn1/3,compile_py/3,compile/3,
vsn/0,
- get_name_of_def/1,get_pos_of_def/1]).
+ get_name_of_def/1,get_pos_of_def/1,
+ unset_pos_mod/1]).
-export([read_config_data/1,get_gen_state_field/1,
partial_inc_dec_toptype/1,update_gen_state/2,
get_tobe_refed_func/1,reset_gen_state/0,is_function_generated/1,
@@ -166,46 +168,26 @@ set_scan_parse_pass(#st{files=Files}=St) ->
{error,St#st{error=Error}}
end.
-set_scan_parse_pass_1([F|Fs], St) ->
+set_scan_parse_pass_1([F|Fs], #st{file=File}=St) ->
case asn1ct_tok:file(F) of
{error,Error} ->
throw(Error);
Tokens when is_list(Tokens) ->
- case catch asn1ct_parser2:parse(Tokens) of
+ case asn1ct_parser2:parse(File, Tokens) of
{ok,M} ->
[M|set_scan_parse_pass_1(Fs, St)];
- {error,ErrorTerm} ->
- throw(handle_parse_error(ErrorTerm, St))
+ {error,Errors} ->
+ throw(Errors)
end
end;
set_scan_parse_pass_1([], _) -> [].
-parse_pass(#st{code=Tokens}=St) ->
- case catch asn1ct_parser2:parse(Tokens) of
+parse_pass(#st{file=File,code=Tokens}=St) ->
+ case asn1ct_parser2:parse(File, Tokens) of
{ok,M} ->
{ok,St#st{code=M}};
- {error,ErrorTerm} ->
- {error,St#st{error=handle_parse_error(ErrorTerm, St)}}
- end.
-
-handle_parse_error(ErrorTerm, #st{file=File,opts=Opts}) ->
- case ErrorTerm of
- {{Line,_Mod,Message},_TokTup} ->
- if
- is_integer(Line) ->
- BaseName = filename:basename(File),
- error("syntax error at line ~p in module ~s:~n",
- [Line,BaseName], Opts);
- true ->
- error("syntax error in module ~p:~n",
- [File], Opts)
- end,
- print_error_message(Message),
- Message;
- {Line,_Mod,[Message,Token]} ->
- error("syntax error: ~p ~p at line ~p~n",
- [Message,Token,Line], Opts),
- {Line,[Message,Token]}
+ {error,Errors} ->
+ {error,St#st{error=Errors}}
end.
merge_pass(#st{file=Base,code=Code}=St) ->
@@ -559,7 +541,10 @@ unset_pos_mod(Def) when is_record(Def,pvaluesetdef) ->
unset_pos_mod(Def) when is_record(Def,pobjectdef) ->
Def#pobjectdef{pos=undefined};
unset_pos_mod(Def) when is_record(Def,pobjectsetdef) ->
- Def#pobjectsetdef{pos=undefined}.
+ Def#pobjectsetdef{pos=undefined};
+unset_pos_mod(#'ComponentType'{} = Def) ->
+ Def#'ComponentType'{pos=undefined};
+unset_pos_mod(Def) -> Def.
get_pos_of_def(#typedef{pos=Pos}) ->
Pos;
@@ -1406,33 +1391,6 @@ prepare_bytes(Bytes) -> list_to_binary(Bytes).
vsn() ->
?vsn.
-
-
-print_error_message([got,H|T]) when is_list(H) ->
- io:format(" got:"),
- print_listing(H,"and"),
- print_error_message(T);
-print_error_message([expected,H|T]) when is_list(H) ->
- io:format(" expected one of:"),
- print_listing(H,"or"),
- print_error_message(T);
-print_error_message([H|T]) ->
- io:format(" ~p",[H]),
- print_error_message(T);
-print_error_message([]) ->
- io:format("~n").
-
-print_listing([H1,H2|[]],AndOr) ->
- io:format(" ~p ~s ~p",[H1,AndOr,H2]);
-print_listing([H1,H2|T],AndOr) ->
- io:format(" ~p,",[H1]),
- print_listing([H2|T],AndOr);
-print_listing([H],_AndOr) ->
- io:format(" ~p",[H]);
-print_listing([],_) ->
- ok.
-
-
specialized_decode_prepare(Erule,M,TsAndVs,Options) ->
case lists:member(asn1config,Options) of
true ->
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index 240f1cbb16..f2c895bfaa 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,8 +24,6 @@
%% Main Module for ASN.1 compile time functions
%-compile(export_all).
-%% Avoid warning for local function error/1 clashing with autoimported BIF.
--compile({no_auto_import,[error/1]}).
-export([check/2,storeindb/2,format_error/1]).
%-define(debug,1).
-include("asn1_records.hrl").
@@ -60,17 +59,9 @@
-define(N_BMPString, 30).
-define(TAG_PRIMITIVE(Num),
- case S#state.erule of
- ber ->
- #tag{class='UNIVERSAL',number=Num,type='IMPLICIT',form=0};
- _ -> []
- end).
+ #tag{class='UNIVERSAL',number=Num,type='IMPLICIT',form=0}).
-define(TAG_CONSTRUCTED(Num),
- case S#state.erule of
- ber ->
- #tag{class='UNIVERSAL',number=Num,type='IMPLICIT',form=32};
- _ -> []
- end).
+ #tag{class='UNIVERSAL',number=Num,type='IMPLICIT',form=32}).
-record(newt,{type=unchanged,tag=unchanged,constraint=unchanged,inlined=no}). % used in check_type to update type and tag
@@ -249,26 +240,18 @@ check_exports(S,Module = #module{}) ->
{exports,all} ->
[];
{exports,ExportList} when is_list(ExportList) ->
- IsNotDefined =
+ IsNotDefined =
fun(X) ->
- case catch get_referenced_type(S,X) of
- {error,{asn1,_}} ->
- true;
- _ -> false
+ try
+ _ = get_referenced_type(S,X),
+ false
+ catch {error,_} ->
+ true
end
end,
- case lists:filter(IsNotDefined,ExportList) of
- [] ->
- [];
- NoDefExp ->
- GetName =
- fun(T = #'Externaltypereference'{type=N})->
- %%{exported,undefined,entity,N}
- NewS=S#state{type=T,tname=N},
- error({export,"exported undefined entity",NewS})
- end,
- lists:map(GetName,NoDefExp)
- end
+ [return_asn1_error(S, Ext, {undefined_export, Undef}) ||
+ Ext = #'Externaltypereference'{type=Undef} <- ExportList,
+ IsNotDefined(Ext)]
end.
check_imports(S, #module{imports={imports,Imports}}) ->
@@ -276,53 +259,18 @@ check_imports(S, #module{imports={imports,Imports}}) ->
check_imports_1(_S, [], Acc) ->
Acc;
-check_imports_1(S, [#'SymbolsFromModule'{symbols=Imports,module=ModuleRef}|SFMs], Acc0) ->
+check_imports_1(S, [#'SymbolsFromModule'{symbols=Imports,module=ModuleRef}|SFMs], Acc) ->
Module = name_of_def(ModuleRef),
- Refs0 = [{catch get_referenced_type(S, Ref),Ref} || Ref <- Imports],
- Refs = [{M,R} || {{M,_},R} <- Refs0],
- {Illegal,Other} = lists:splitwith(fun({error,_}) -> true;
- (_) -> false
- end, Refs),
- ChainedRefs = [R || {M,R} <- Other, M =/= Module],
- IllegalRefs = [R || {error,R} <- Illegal] ++
- [R || {M,R} <- ChainedRefs,
- ok =/= chained_import(S, Module, M, name_of_def(R))],
- Acc = [return_asn1_error(S, Ref, {undefined_import,name_of_def(Ref),Module}) ||
- Ref <- IllegalRefs] ++ Acc0,
- check_imports_1(S, SFMs, Acc).
-
-chained_import(S,ImpMod,DefMod,Name) ->
- %% Name is a referenced structure that is not defined in ImpMod,
- %% but must be present in the Imports list of ImpMod. The chain of
- %% imports of Name must end in DefMod.
- GetImports =
- fun(_M_) ->
- case asn1_db:dbget(_M_,'MODULE') of
- #module{imports={imports,ImportList}} ->
- ImportList;
- _ -> []
- end
- end,
- FindNameInImports =
- fun([],N,_) -> {no_mod,N};
- ([#'SymbolsFromModule'{symbols=Imports,module=ModuleRef}|SFMs],N,F) ->
- case [name_of_def(X) || X <- Imports, name_of_def(X) =:= N] of
- [] -> F(SFMs,N,F);
- [N] -> {name_of_def(ModuleRef),N}
- end
- end,
- case GetImports(ImpMod) of
- [] ->
- error;
- Imps ->
- case FindNameInImports(Imps,Name,FindNameInImports) of
- {no_mod,_} ->
- error;
- {DefMod,_} -> ok;
- {OtherMod,_} ->
- chained_import(S,OtherMod,DefMod,Name)
- end
- end.
+ Refs = [{try get_referenced_type(S, Ref)
+ catch throw:Error -> Error end,
+ Ref}
+ || Ref <- Imports],
+ CreateError = fun(Ref) ->
+ Error = {undefined_import,name_of_def(Ref),Module},
+ return_asn1_error(S, Ref, Error)
+ end,
+ Errors = [CreateError(Ref) || {{error, _}, Ref} <- Refs],
+ check_imports_1(S, SFMs, Errors ++ Acc).
checkt(S0, Names) ->
Check = fun do_checkt/3,
@@ -335,7 +283,7 @@ checkt(S0, Names) ->
check_fold(S0, lists:reverse(CtxtSwitch), Check) ++ Types.
do_checkt(S, Name, #typedef{typespec=TypeSpec}=Type0) ->
- NewS = S#state{type=Type0,tname=Name},
+ NewS = S#state{tname=Name},
try check_type(NewS, Type0, TypeSpec) of
#type{}=Ts ->
case Type0#typedef.checked of
@@ -350,7 +298,7 @@ do_checkt(S, Name, #typedef{typespec=TypeSpec}=Type0) ->
end
catch
{error,Reason} ->
- error({type,Reason,NewS});
+ Reason;
{asn1_class,_ClassDef} ->
{asn1_class,Name};
pobjectsetdef ->
@@ -384,33 +332,32 @@ do_checkv(S, Name, Value)
is_record(Value, typedef); %Value set may be parsed as object set.
is_record(Value, pvaluedef);
is_record(Value, pvaluesetdef) ->
- NewS = S#state{value=Value},
- try check_value(NewS, Value) of
+ try check_value(S, Value) of
{valueset,VSet} ->
Pos = asn1ct:get_pos_of_def(Value),
CheckedVSDef = #typedef{checked=true,pos=Pos,
name=Name,typespec=VSet},
- asn1_db:dbput(NewS#state.mname, Name, CheckedVSDef),
+ asn1_db:dbput(S#state.mname, Name, CheckedVSDef),
{valueset,Name};
V ->
%% update the valuedef
- asn1_db:dbput(NewS#state.mname, Name, V),
+ asn1_db:dbput(S#state.mname, Name, V),
ok
catch
{error,Reason} ->
- error({value,Reason,NewS});
+ Reason;
{pobjectsetdef} ->
{pobjectsetdef,Name};
{objectsetdef} ->
{objectsetdef,Name};
- {objectdef} ->
+ {asn1_class, _} ->
%% this is an object, save as typedef
#valuedef{checked=C,pos=Pos,name=N,type=Type,
value=Def} = Value,
ClassName = Type#type.def,
NewSpec = #'Object'{classname=ClassName,def=Def},
NewDef = #typedef{checked=C,pos=Pos,name=N,typespec=NewSpec},
- asn1_db:dbput(NewS#state.mname, Name, NewDef),
+ asn1_db:dbput(S#state.mname, Name, NewDef),
{objectdef,Name}
end.
@@ -419,7 +366,7 @@ checkp(S, Names) ->
check_fold(S, Names, fun do_checkp/3).
do_checkp(S0, Name, #ptypedef{typespec=TypeSpec}=Type0) ->
- S = S0#state{type=Type0,tname=Name},
+ S = S0#state{tname=Name},
try check_ptype(S, Type0, TypeSpec) of
#type{}=Ts ->
Type = Type0#ptypedef{checked=true,typespec=Ts},
@@ -427,7 +374,7 @@ do_checkp(S0, Name, #ptypedef{typespec=TypeSpec}=Type0) ->
ok
catch
{error,Reason} ->
- error({type,Reason,S});
+ Reason;
{asn1_class,_ClassDef} ->
{asn1_class,Name};
{asn1_param_class,_} ->
@@ -438,100 +385,81 @@ do_checkp(S0, Name, #ptypedef{typespec=TypeSpec}=Type0) ->
checkc(S, Names) ->
check_fold(S, Names, fun do_checkc/3).
-do_checkc(S0, Name, Class0) ->
- {Class1,ClassSpec} =
- case Class0 of
- #classdef{} ->
- {Class0,Class0};
- #typedef{} ->
- {#classdef{name=Name},Class0#typedef.typespec}
- end,
- S = S0#state{type=Class0,tname=Name},
- try check_class(S, ClassSpec) of
- C ->
- Class = Class1#classdef{checked=true,typespec=C},
- asn1_db:dbput(S#state.mname, Name, Class),
- ok
- catch
- {error,Reason} ->
- error({class,Reason,S})
- end.
+do_checkc(S, Name, Class) ->
+ try
+ case is_classname(Name) of
+ false ->
+ asn1_error(S, {illegal_class_name,Name});
+ true ->
+ do_checkc_1(S, Name, Class)
+ end
+ catch {error,Reason} -> Reason
+ end.
+
+do_checkc_1(S, Name, #classdef{}=Class) ->
+ C = check_class(S, Class),
+ store_class(S, true, Class#classdef{typespec=C}, Name),
+ ok;
+do_checkc_1(S, Name, #typedef{typespec=#type{def=Def}=TS}) ->
+ C = check_class(S, TS),
+ {Mod,Pos} = case Def of
+ #'Externaltypereference'{module=M, pos=P} ->
+ {M,P};
+ {pt, #'Externaltypereference'{module=M, pos=P}, _} ->
+ {M,P}
+ end,
+ Class = #classdef{name=Name, typespec=C, pos=Pos, module=Mod},
+ store_class(S, true, Class, Name),
+ ok.
+
+%% is_classname(Atom) -> true|false.
+is_classname(Name) when is_atom(Name) ->
+ lists:all(fun($-) -> true;
+ (D) when $0 =< D, D =< $9 -> true;
+ (UC) when $A =< UC, UC =< $Z -> true;
+ (_) -> false
+ end, atom_to_list(Name)).
-checko(S,[Name|Os],Acc,ExclO,ExclOS) ->
- ?dbg("Checking object ~p~n",[Name]),
- Result =
- case asn1_db:dbget(S#state.mname,Name) of
- undefined ->
- error({type,{internal_error,'???'},S});
- Object when is_record(Object,typedef) ->
- NewS = S#state{type=Object,tname=Name},
- case catch(check_object(NewS,Object,Object#typedef.typespec)) of
- {error,Reason} ->
- error({type,Reason,NewS});
- {'EXIT',Reason} ->
- error({type,{internal_error,Reason},NewS});
- {asn1,Reason} ->
- error({type,Reason,NewS});
- O ->
- NewObj = Object#typedef{checked=true,typespec=O},
- asn1_db:dbput(NewS#state.mname,Name,NewObj),
- if
- is_record(O,'Object') ->
- case O#'Object'.gen of
- true ->
- {ok,ExclO,ExclOS};
- false ->
- {ok,[Name|ExclO],ExclOS}
- end;
- is_record(O,'ObjectSet') ->
- case O#'ObjectSet'.gen of
- true ->
- {ok,ExclO,ExclOS};
- false ->
- {ok,ExclO,[Name|ExclOS]}
- end
- end
- end;
- PObject when is_record(PObject,pobjectdef) ->
- NewS = S#state{type=PObject,tname=Name},
- case (catch check_pobject(NewS,PObject)) of
- {error,Reason} ->
- error({type,Reason,NewS});
- {'EXIT',Reason} ->
- error({type,{internal_error,Reason},NewS});
- {asn1,Reason} ->
- error({type,Reason,NewS});
- PO ->
- NewPObj = PObject#pobjectdef{def=PO},
- asn1_db:dbput(NewS#state.mname,Name,NewPObj),
- {ok,[Name|ExclO],ExclOS}
- end;
- PObjSet when is_record(PObjSet,pvaluesetdef) ->
- %% this is a parameterized object set. Might be a parameterized
- %% value set, couldn't it?
- NewS = S#state{type=PObjSet,tname=Name},
- case (catch check_pobjectset(NewS,PObjSet)) of
- {error,Reason} ->
- error({type,Reason,NewS});
- {'EXIT',Reason} ->
- error({type,{internal_error,Reason},NewS});
- {asn1,Reason} ->
- error({type,Reason,NewS});
- POS ->
- %%NewPObjSet = PObjSet#pvaluesetdef{valueset=POS},
- asn1_db:dbput(NewS#state.mname,Name,POS),
- {ok,ExclO,[Name|ExclOS]}
- end
- end,
- case Result of
- {ok,NewExclO,NewExclOS} ->
- checko(S,Os,Acc,NewExclO,NewExclOS);
- _ ->
- checko(S,Os,[Result|Acc],ExclO,ExclOS)
+checko(S0,[Name|Os],Acc,ExclO,ExclOS) ->
+ Item = asn1_db:dbget(S0#state.mname, Name),
+ S = S0#state{error_context=Item},
+ try checko_1(S, Item, Name, ExclO, ExclOS) of
+ {NewExclO,NewExclOS} ->
+ checko(S, Os, Acc, NewExclO, NewExclOS)
+ catch
+ throw:{error, Error} ->
+ checko(S, Os, [Error|Acc], ExclO, ExclOS)
end;
checko(_S,[],Acc,ExclO,ExclOS) ->
{lists:reverse(Acc),lists:reverse(ExclO),lists:reverse(ExclOS)}.
+checko_1(S, #typedef{typespec=TS}=Object, Name, ExclO, ExclOS) ->
+ NewS = S#state{tname=Name},
+ O = check_object(NewS, Object, TS),
+ NewObj = Object#typedef{checked=true,typespec=O},
+ asn1_db:dbput(NewS#state.mname, Name, NewObj),
+ case O of
+ #'Object'{gen=true} ->
+ {ExclO,ExclOS};
+ #'Object'{gen=false} ->
+ {[Name|ExclO],ExclOS};
+ #'ObjectSet'{gen=true} ->
+ {ExclO,ExclOS};
+ #'ObjectSet'{gen=false} ->
+ {ExclO,[Name|ExclOS]}
+ end;
+checko_1(S, #pobjectdef{}=PObject, Name, ExclO, ExclOS) ->
+ NewS = S#state{tname=Name},
+ PO = check_pobject(NewS, PObject),
+ NewPObj = PObject#pobjectdef{def=PO},
+ asn1_db:dbput(NewS#state.mname, Name, NewPObj),
+ {[Name|ExclO],ExclOS};
+checko_1(S, #pvaluesetdef{}=PObjSet, Name, ExclO, ExclOS) ->
+ NewS = S#state{tname=Name},
+ POS = check_pobjectset(NewS, PObjSet),
+ asn1_db:dbput(NewS#state.mname, Name, POS),
+ {ExclO,[Name|ExclOS]}.
+
check_class(S,CDef=#classdef{checked=Ch,name=Name,typespec=TS}) ->
case Ch of
true -> TS;
@@ -551,22 +479,16 @@ check_class(S = #state{mname=M,tname=T},ClassSpec)
Tref = #'Externaltypereference'{type=TName} ->
{MName,RefType} = get_referenced_type(S,Tref),
#classdef{} = CD = get_class_def(S, RefType),
- NewState = update_state(S#state{type=RefType,
- tname=TName}, MName),
+ NewState = update_state(S#state{tname=TName}, MName),
check_class(NewState, CD);
{pt,ClassRef,Params} ->
%% parameterized class
{_,PClassDef} = get_referenced_type(S,ClassRef),
- NewParaList =
- [match_parameters(S,TmpParam,S#state.parameters)||
- TmpParam <- Params],
+ NewParaList = match_parameters(S, Params),
instantiate_pclass(S,PClassDef,NewParaList)
end;
-check_class(S,C) when is_record(C,objectclass) ->
- NewFieldSpec = check_class_fields(S,C#objectclass.fields),
- C#objectclass{fields=NewFieldSpec};
-check_class(_S,{poc,_ObjSet,_Params}) ->
- 'fix this later';
+check_class(S, #objectclass{}=C) ->
+ check_objectclass(S, C);
check_class(S,ClassName) ->
{RefMod,Def} = get_referenced_type(S,ClassName),
case Def of
@@ -579,8 +501,7 @@ check_class(S,ClassName) ->
false ->
Name=ClassName#'Externaltypereference'.type,
store_class(S,idle,ClassDef,Name),
-% NewS = S#state{mname=RefMod,type=Def,tname=Name},
- NewS = update_state(S#state{type=Def,tname=Name},RefMod),
+ NewS = update_state(S#state{tname=Name}, RefMod),
CheckedTS = check_class(NewS,ClassDef#classdef.typespec),
store_class(S,true,ClassDef#classdef{typespec=CheckedTS},Name),
CheckedTS
@@ -594,11 +515,20 @@ check_class(S,ClassName) ->
end
end.
+check_objectclass(S, #objectclass{fields=Fs0,syntax=Syntax0}=C) ->
+ Fs = check_class_fields(S, Fs0),
+ case Syntax0 of
+ {'WITH SYNTAX',Syntax1} ->
+ Syntax = preprocess_syntax(S, Syntax1, Fs),
+ C#objectclass{fields=Fs,syntax={preprocessed_syntax,Syntax}};
+ _ ->
+ C#objectclass{fields=Fs}
+ end.
+
instantiate_pclass(S=#state{parameters=_OldArgs},PClassDef,Params) ->
#ptypedef{args=Args,typespec=Type} = PClassDef,
MatchedArgs = match_args(S,Args, Params, []),
-% NewS = S#state{type=Type,parameters=MatchedArgs++OldArgs,abscomppath=[]},
- NewS = S#state{type=Type,parameters=MatchedArgs,abscomppath=[]},
+ NewS = S#state{parameters=MatchedArgs,abscomppath=[]},
check_class(NewS,#classdef{name=S#state.tname,typespec=Type}).
store_class(S,Mode,ClassDef,ClassName) ->
@@ -613,6 +543,12 @@ check_class_fields(S,[F|Fields],Acc) ->
case element(1,F) of
fixedtypevaluefield ->
{_,Name,Type,Unique,OSpec} = F,
+ case {Unique,OSpec} of
+ {'UNIQUE',{'DEFAULT',_}} ->
+ asn1_error(S, {unique_and_default,Name});
+ {_,_} ->
+ ok
+ end,
RefType = check_type(S,#typedef{typespec=Type},Type),
{fixedtypevaluefield,Name,RefType,Unique,OSpec};
object_or_fixedtypevalue_field ->
@@ -621,7 +557,7 @@ check_class_fields(S,[F|Fields],Acc) ->
Cat =
case asn1ct_gen:type(asn1ct_gen:get_inner(Type2#type.def)) of
Def when is_record(Def,'Externaltypereference') ->
- {_,D} = get_referenced_type(S,Def),
+ {_,D} = get_referenced_type(S, Def, true),
D;
{undefined,user} ->
%% neither of {primitive,bif} or {constructed,bif}
@@ -644,18 +580,14 @@ check_class_fields(S,[F|Fields],Acc) ->
objectset_or_fixedtypevalueset_field ->
{_,Name,Type,OSpec} = F,
RefType =
- case (catch check_type(S,#typedef{typespec=Type},Type)) of
- {asn1_class,_ClassDef} ->
+ try check_type(S,#typedef{typespec=Type},Type) of
+ #type{} = CheckedType ->
+ CheckedType
+ catch {asn1_class,_ClassDef} ->
case if_current_checked_type(S,Type) of
- true ->
- Type#type.def;
- _ ->
- check_class(S,Type)
- end;
- CheckedType when is_record(CheckedType,type) ->
- CheckedType;
- _ ->
- error({class,"internal error, check_class_fields",S})
+ true -> Type#type.def;
+ _ -> check_class(S,Type)
+ end
end,
if
is_record(RefType,'Externaltypereference') ->
@@ -733,38 +665,34 @@ check_pobjectset(S,PObjSet) ->
PObjSet
end.
+-record(osi, %Object set information.
+ {st,
+ classref,
+ uniq,
+ ext
+ }).
+
check_object(_S,ObjDef,ObjSpec) when (ObjDef#typedef.checked == true) ->
ObjSpec;
check_object(S,_ObjDef,#'Object'{classname=ClassRef,def=ObjectDef}) ->
?dbg("check_object ~p~n",[ObjectDef]),
-%% io:format("check_object,object: ~p~n",[ObjectDef]),
-% {MName,_ClassDef} = get_referenced_type(S,ClassRef),
- NewClassRef = check_externaltypereference(S,ClassRef),
- ClassDef =
- case get_referenced_type(S,ClassRef) of
- {MName,ClDef=#classdef{checked=false}} ->
- NewState = update_state(S#state{type=ClDef,
- tname=ClassRef#'Externaltypereference'.type},MName),
- ObjClass=
- check_class(NewState,ClDef),
- #classdef{checked=true,
- typespec=ObjClass};
- {_,_ClDef} when is_record(_ClDef,classdef) ->
- _ClDef;
- {MName,_TDef=#typedef{checked=false,pos=Pos,
- name=_TName,typespec=TS}} ->
- ClDef = #classdef{pos=Pos,name=_TName,typespec=TS},
- NewState = update_state(S#state{type=_TDef,
- tname=ClassRef#'Externaltypereference'.type},MName),
- ObjClass =
- check_class(NewState,ClDef),
- ClDef#classdef{checked=true,typespec=ObjClass};
- {_,_ClDef} ->
- _ClDef
+ _ = check_externaltypereference(S,ClassRef),
+ {ClassDef, NewClassRef} =
+ case get_referenced_type(S, ClassRef, true) of
+ {MName,#classdef{checked=false, name=CLName}=ClDef} ->
+ Type = ClassRef#'Externaltypereference'.type,
+ NewState = update_state(S#state{tname=Type}, MName),
+ ObjClass = check_class(NewState, ClDef),
+ {ClDef#classdef{checked=true, typespec=ObjClass},
+ #'Externaltypereference'{module=MName, type=CLName}};
+ {MName,#classdef{name=CLName}=ClDef} ->
+ {ClDef, #'Externaltypereference'{module=MName, type=CLName}};
+ _ ->
+ asn1_error(S, illegal_object)
end,
NewObj =
case ObjectDef of
- Def when is_tuple(Def), (element(1,Def)==object) ->
+ {object,_,_}=Def ->
NewSettingList = check_objectdefn(S,Def,ClassDef),
#'Object'{def=NewSettingList};
{po,{object,DefObj},ArgsList} ->
@@ -778,425 +706,287 @@ check_object(S,_ObjDef,#'Object'{classname=ClassRef,def=ObjectDef}) ->
instantiate_po(S,ClassDef,Object,ArgList);
#'Externalvaluereference'{} ->
{_,Object} = get_referenced_type(S,ObjectDef),
- check_object(S,Object,Object#typedef.typespec);
+ check_object(S, Object, object_to_check(S, Object));
[] ->
- %% An object with no fields. All class fields must be
- %% optional or default. Check that all fields in
- %% class are 'OPTIONAL' or 'DEFAULT'
- class_fields_optional_check(S,ClassDef),
- #'Object'{def={object,defaultsyntax,[]}};
- _ ->
- exit({error,{no_object,ObjectDef},S})
+ %% An object with no fields (parsed as a value).
+ Def = {object,defaultsyntax,[]},
+ NewSettingList = check_objectdefn(S, Def, ClassDef),
+ #'Object'{def=NewSettingList};
+ _ ->
+ asn1_error(S, illegal_object)
end,
- Gen = gen_incl(S,NewObj#'Object'.def,
- (ClassDef#classdef.typespec)#objectclass.fields),
+ Fields = (ClassDef#classdef.typespec)#objectclass.fields,
+ Gen = gen_incl(S,NewObj#'Object'.def, Fields),
NewObj#'Object'{classname=NewClassRef,gen=Gen};
-
-
-check_object(S,
- _ObjSetDef,
- ObjSet=#'ObjectSet'{class=ClassRef}) ->
-%% io:format("check_object,SET: ~p~n",[ObjSet#'ObjectSet'.set]),
- ?dbg("check_object set: ~p~n",[ObjSet#'ObjectSet'.set]),
- {_,ClassDef} = get_referenced_type(S,ClassRef),
- NewClassRef = check_externaltypereference(S,ClassRef),
- {UniqueFieldName,UniqueInfo} =
- case (catch get_unique_fieldname(S,ClassDef)) of
- {error,'__undefined_',_} ->
- {{unique,undefined},{unique,undefined}};
- {asn1,Msg,_} -> error({class,Msg,S});
- {'EXIT',Msg} -> error({class,{internal_error,Msg},S});
+check_object(S, _, #'ObjectSet'{class=ClassRef0,set=Set0}=ObjSet0) ->
+ {_,ClassDef} = get_referenced_type(S, ClassRef0),
+ ClassRef = check_externaltypereference(S, ClassRef0),
+ {UniqueFieldName,UniqueInfo} =
+ case get_unique_fieldname(S, ClassDef) of
+ no_unique -> {{unique,undefined},{unique,undefined}};
Other -> {element(1,Other),Other}
end,
- NewObjSet=
- case prepare_objset(ObjSet#'ObjectSet'.set) of
- {set,SET,EXT} ->
- CheckedSet = check_object_list(S,NewClassRef,SET),
- NewSet = get_unique_valuelist(S,CheckedSet,UniqueInfo),
- ObjSet#'ObjectSet'{uniquefname=UniqueFieldName,
- set=extensionmark(NewSet,EXT)};
-
- {'SingleValue',ERef = #'Externalvaluereference'{}} ->
- {RefedMod,ObjDef} = get_referenced_type(S,ERef),
- #'Object'{def=CheckedObj} =
- check_object(S,ObjDef,ObjDef#typedef.typespec),
-
- NewSet = get_unique_valuelist(S,[{{RefedMod,get_datastr_name(ObjDef)},
- CheckedObj}],
- UniqueInfo),
- ObjSet#'ObjectSet'{uniquefname=UniqueFieldName,
- set=NewSet};
- ['EXTENSIONMARK'] ->
- ObjSet#'ObjectSet'{uniquefname=UniqueFieldName,
- set=['EXTENSIONMARK']};
-
- OSref when is_record(OSref,'Externaltypereference') ->
- {_,OS=#typedef{typespec=OSdef}} = get_referenced_type(S,OSref),
- check_object(S,OS,OSdef);
-
- {Type,{'EXCEPT',Exclusion}} when is_record(Type,type) ->
- {_,TDef} = get_referenced_type(S,Type#type.def),
- OS = TDef#typedef.typespec,
- NewSet = reduce_objectset(OS#'ObjectSet'.set,Exclusion),
- NewOS = OS#'ObjectSet'{set=NewSet},
- check_object(S,TDef#typedef{typespec=NewOS},
- NewOS);
- #type{def={pt,DefinedObjSet,ParamList}} ->
- {_,PObjSetDef} = get_referenced_type(S,DefinedObjSet),
- NewParamList =
- [match_parameters(S,TmpParam,S#state.parameters)||
- TmpParam <- ParamList],
- instantiate_pos(S,ClassRef,PObjSetDef,NewParamList);
-
- %% actually this is an ObjectSetFromObjects construct, it
- %% is when the object set is retrieved from an object
- %% field.
- #type{def=#'ObjectClassFieldType'{classname=ObjName,
- fieldname=FieldName}} ->
- {RefedObjMod,TDef} = get_referenced_type(S,ObjName),
- OS=TDef#typedef.typespec,
- %% should get the right object set here. Get the field
- %% FieldName out of the object set OS of class
- %% OS#'ObjectSet'.class
- OS2=check_object(S,TDef,OS),
- NewSet=object_set_from_objects(S,RefedObjMod,FieldName,OS2),
- ObjSet#'ObjectSet'{uniquefname=UniqueFieldName,
- set=NewSet};
- {'ObjectSetFromObjects',{_,_,ObjName},FieldName} ->
- {RefedObjMod,TDef} = get_referenced_type(S,ObjName),
- OS=TDef#typedef.typespec,
- %% should get the right object set here. Get the field
- %% FieldName out of the object set OS of class
- %% OS#'ObjectSet'.class
- OS2=check_object(S,TDef,OS),
- NewSet=object_set_from_objects(S,RefedObjMod,FieldName,OS2),
- ObjSet#'ObjectSet'{uniquefname=UniqueFieldName,
- set=NewSet};
- {'ObjectSetFromObjects',{_,ObjName},FieldName} ->
- %% This is a ObjectSetFromObjects, i.e.
- %% ObjectSetFromObjects ::= ReferencedObjects "." FieldName
- %% with a defined object as ReferencedObjects. And
- %% the FieldName of the Class (object) contains an object set.
- {RefedObjMod,TDef} = get_referenced_type(S,ObjName),
- O1 = TDef#typedef.typespec,
- O2 = check_object(S,TDef,O1),
- NewSet = object_set_from_objects(S,RefedObjMod,FieldName,O2),
- OS2=ObjSet#'ObjectSet'{uniquefname=UniqueFieldName,
- set=NewSet},
- %%io:format("ObjectSet: ~p~n",[OS2]),
- OS2;
- {pos,{objectset,_,DefinedObjSet},Params} ->
- {_,PObjSetDef} = get_referenced_type(S,DefinedObjSet),
- NewParamList =
- [match_parameters(S,TmpParam,S#state.parameters)||
- TmpParam <- Params],
- instantiate_pos(S,ClassRef,PObjSetDef,NewParamList);
- Unknown ->
- exit({error,{unknown_object_set,Unknown},S})
- end,
- NewSet2 = remove_duplicate_objects(NewObjSet#'ObjectSet'.set),
- NewObjSet2 = NewObjSet#'ObjectSet'{set=NewSet2},
- Gen = gen_incl_set(S,NewObjSet2#'ObjectSet'.set,
- ClassDef),
- ?dbg("check_object done~n",[]),
- NewObjSet2#'ObjectSet'{class=NewClassRef,gen=Gen}.
+ OSI0 = #osi{st=S,classref=ClassRef,uniq=UniqueInfo,ext=false},
+ {Set1,OSI1} = if
+ is_list(Set0) ->
+ check_object_set_list(Set0, OSI0);
+ true ->
+ check_object_set(Set0, OSI0)
+ end,
+ Ext = case Set1 of
+ [] ->
+ %% FIXME: X420 does not compile unless we force
+ %% empty sets to be extensible. There should be
+ %% a better way.
+ true;
+ [_|_] ->
+ OSI1#osi.ext
+ end,
+ Set2 = remove_duplicate_objects(S, Set1),
+ Set = case Ext of
+ false -> Set2;
+ true -> Set2 ++ ['EXTENSIONMARK']
+ end,
+ ObjSet = ObjSet0#'ObjectSet'{uniquefname=UniqueFieldName,set=Set},
+ Gen = gen_incl_set(S, Set, ClassDef),
+ ObjSet#'ObjectSet'{class=ClassRef,gen=Gen}.
+
+check_object_set({element_set,Root0,Ext0}, OSI0) ->
+ OSI = case Ext0 of
+ none -> OSI0;
+ _ -> OSI0#osi{ext=true}
+ end,
+ case {Root0,Ext0} of
+ {empty,empty} -> {[],OSI};
+ {empty,Ext} -> check_object_set(Ext, OSI);
+ {Root,none} -> check_object_set(Root, OSI);
+ {Root,empty} -> check_object_set(Root, OSI);
+ {Root,Ext} -> check_object_set_list([Root,Ext], OSI)
+ end;
+check_object_set(#'Externaltypereference'{}=Ref, #osi{st=S}=OSI) ->
+ {_,#typedef{typespec=OSdef}=OS} = get_referenced_type(S, Ref),
+ ObjectSet = check_object(S, OS, OSdef),
+ check_object_set_objset(ObjectSet, OSI);
+check_object_set(#'Externalvaluereference'{}=Ref, #osi{st=S}=OSI) ->
+ {RefedMod,ObjName,#'Object'{def=Def}} = check_referenced_object(S, Ref),
+ ObjList = check_object_set_mk(RefedMod, ObjName, Def, OSI),
+ {ObjList,OSI};
+check_object_set({'EXCEPT',Incl0,Excl0}, OSI) ->
+ {Incl1,_} = check_object_set(Incl0, OSI),
+ {Excl1,_} = check_object_set(Excl0, OSI),
+ Exclude = sofs:set([N || {N,_} <- Excl1], [name]),
+ Incl2 = [{Name,Obj} || {Name,_,_}=Obj <- Incl1],
+ Incl3 = sofs:relation(Incl2, [{name,object}]),
+ Incl4 = sofs:drestriction(Incl3, Exclude),
+ Incl5 = sofs:to_external(Incl4),
+ Incl = [Obj || {_,Obj} <- Incl5],
+ {Incl,OSI};
+check_object_set({object,_,_}=Obj0, OSI) ->
+ #osi{st=S,classref=ClassRef} = OSI,
+ #'Object'{def=Def} =
+ check_object(S, #typedef{typespec=Obj0},
+ #'Object'{classname=ClassRef,def=Obj0}),
+ ObjList = check_object_set_mk(Def, OSI),
+ {ObjList,OSI};
+check_object_set(#'ObjectClassFieldType'{classname=ObjName,
+ fieldname=FieldNames},
+ #osi{st=S}=OSI) ->
+ Set = check_ObjectSetFromObjects(S, ObjName, FieldNames),
+ check_object_set_objset_list(Set, OSI);
+check_object_set({'ObjectSetFromObjects',Obj,FieldNames}, #osi{st=S}=OSI) ->
+ ObjName = element(tuple_size(Obj), Obj),
+ Set = check_ObjectSetFromObjects(S, ObjName, FieldNames),
+ check_object_set_objset_list(Set, OSI);
+check_object_set({pt,DefinedObjSet,ParamList0}, OSI) ->
+ #osi{st=S,classref=ClassRef} = OSI,
+ {_,PObjSetDef} = get_referenced_type(S, DefinedObjSet),
+ ParamList = match_parameters(S, ParamList0),
+ ObjectSet = instantiate_pos(S, ClassRef, PObjSetDef, ParamList),
+ check_object_set_objset(ObjectSet, OSI);
+check_object_set({pos,{objectset,_,DefinedObjSet},Params0}, OSI) ->
+ #osi{st=S,classref=ClassRef} = OSI,
+ {_,PObjSetDef} = get_referenced_type(S, DefinedObjSet),
+ Params = match_parameters(S, Params0),
+ ObjectSet = instantiate_pos(S, ClassRef, PObjSetDef, Params),
+ check_object_set_objset(ObjectSet, OSI);
+check_object_set({pv,{simpledefinedvalue,DefinedObject},Params}=PV, OSI) ->
+ #osi{st=S,classref=ClassRef} = OSI,
+ Args = match_parameters(S, Params),
+ #'Object'{def=Def} =
+ check_object(S, PV,
+ #'Object'{classname=ClassRef ,
+ def={po,{object,DefinedObject},Args}}),
+ ObjList = check_object_set_mk(Def, OSI),
+ {ObjList,OSI};
+check_object_set({'SingleValue',Val}, OSI) ->
+ check_object_set(Val, OSI);
+check_object_set({'ValueFromObject',{object,Object},FieldNames}, OSI) ->
+ #osi{st=S} = OSI,
+ case extract_field(S, Object, FieldNames) of
+ #'Object'{def=Def} ->
+ ObjList = check_object_set_mk(Def, OSI),
+ {ObjList,OSI};
+ _ ->
+ asn1_error(S, illegal_object)
+ end;
+check_object_set(#type{def=Def}, OSI) ->
+ check_object_set(Def, OSI);
+check_object_set({union,A0,B0}, OSI0) ->
+ {A,OSI1} = check_object_set(A0, OSI0),
+ {B,OSI} = check_object_set(B0, OSI1),
+ {A++B,OSI}.
+
+check_object_set_list([H|T], OSI0) ->
+ {Set0,OSI1} = check_object_set(H, OSI0),
+ {Set1,OSI2} = check_object_set_list(T, OSI1),
+ {Set0++Set1,OSI2};
+check_object_set_list([], OSI) ->
+ {[],OSI}.
+
+check_object_set_objset(#'ObjectSet'{set=Set}, OSI) ->
+ check_object_set_objset_list(Set, OSI).
+
+check_object_set_objset_list(Set, OSI) ->
+ check_object_set_objset_list_1(Set, OSI, []).
+
+check_object_set_objset_list_1(['EXTENSIONMARK'|T], OSI, Acc) ->
+ check_object_set_objset_list_1(T, OSI#osi{ext=true}, Acc);
+check_object_set_objset_list_1([H|T], OSI, Acc) ->
+ check_object_set_objset_list_1(T, OSI, [H|Acc]);
+check_object_set_objset_list_1([], OSI, Acc) ->
+ {Acc,OSI}.
+
+check_object_set_mk(Fields, OSI) ->
+ check_object_set_mk(no_mod, no_name, Fields, OSI).
+
+check_object_set_mk(M, N, Def, #osi{uniq={unique,undefined}}) ->
+ {_,_,Fields} = Def,
+ [{{M,N},no_unique_value,Fields}];
+check_object_set_mk(M, N, Def, #osi{uniq={UniqField,_}}) ->
+ {_,_,Fields} = Def,
+ case lists:keyfind(UniqField, 1, Fields) of
+ {UniqField,#valuedef{value=Val}} ->
+ [{{M,N},Val,Fields}];
+ false ->
+ case Fields of
+ [{_,#typedef{typespec=#'ObjectSet'{set=['EXTENSIONMARK']}}}] ->
+ %% FIXME: If object is missing the unique field and
+ %% only contains a reference to an empty object set,
+ %% we will remove the entire object as a workaround
+ %% to get X420 to compile. There should be a better
+ %% way.
+ [];
+ _ ->
+ [{{M,N},no_unique_value,Fields}]
+ end
+ end.
%% remove_duplicate_objects/1 remove duplicates of objects.
%% For instance may Set contain objects of same class from
%% different object sets that in fact might be duplicates.
-remove_duplicate_objects(Set) when is_list(Set) ->
- Pred = fun({A,B,_},{A,C,_}) when B =< C -> true;
- ({A,_,_},{B,_,_}) when A < B -> true;
- ('EXTENSIONMARK','EXTENSIONMARK') -> true;
- (T,A) when is_tuple(T),is_atom(A) -> true;% EXTENSIONMARK last in list
- (_,_) -> false
- end,
- lists:usort(Pred,Set).
+remove_duplicate_objects(S, Set0) when is_list(Set0) ->
+ Set1 = [{Id,Orig} || {_,Id,_}=Orig <- Set0],
+ Set2 = sofs:relation(Set1),
+ Set3 = sofs:relation_to_family(Set2),
+ Set = sofs:to_external(Set3),
+ remove_duplicate_objects_1(S, Set).
+
+remove_duplicate_objects_1(S, [{no_unique_value,Objs}|T]) ->
+ Objs ++ remove_duplicate_objects_1(S, T);
+remove_duplicate_objects_1(S, [{_,[_]=Objs}|T]) ->
+ Objs ++ remove_duplicate_objects_1(S, T);
+remove_duplicate_objects_1(S, [{Id,[_|_]=Objs}|T]) ->
+ MakeSortable = fun(What) -> sortable_type(S, What) end,
+ Tagged = order_tag_set(Objs, MakeSortable),
+ case lists:ukeysort(1, Tagged) of
+ [{_,Obj}] ->
+ [Obj|remove_duplicate_objects_1(S, T)];
+ [_|_] ->
+ asn1_error(S, {non_unique_object,Id})
+ end;
+remove_duplicate_objects_1(_, []) ->
+ [].
-%%
-extensionmark(L,true) ->
- case lists:member('EXTENSIONMARK',L) of
- true -> L;
- _ -> L ++ ['EXTENSIONMARK']
+order_tag_set([{_, _, Fields}=Orig|Fs], Fun) ->
+ Pair = {[{FId, traverse(F, Fun)} || {FId, F} <- Fields], Orig},
+ [Pair|order_tag_set(Fs, Fun)];
+order_tag_set([], _) -> [].
+
+sortable_type(S, #'Externaltypereference'{}=ERef) ->
+ try get_referenced_type(S, ERef) of
+ {_,#typedef{}=OI} ->
+ OI#typedef{pos=undefined,name=undefined}
+ catch
+ _:_ ->
+ ERef
end;
-extensionmark(L,_) ->
- L.
+sortable_type(_, #typedef{}=TD) ->
+ asn1ct:unset_pos_mod(TD#typedef{name=undefined});
+sortable_type(_, Type) ->
+ asn1ct:unset_pos_mod(Type).
+
+traverse(Structure0, Fun) ->
+ Structure = Fun(Structure0),
+ traverse_1(Structure, Fun).
+
+traverse_1(#typedef{typespec=TS0} = TD, Fun) ->
+ TS = traverse(TS0, Fun),
+ TD#typedef{typespec=TS};
+traverse_1(#valuedef{type=TS0} = VD, Fun) ->
+ TS = traverse(TS0, Fun),
+ VD#valuedef{type=TS};
+traverse_1(#type{def=TS0} = TD, Fun) ->
+ TS = traverse(TS0, Fun),
+ TD#type{def=TS};
+traverse_1(#'SEQUENCE'{components=Cs0} = Seq, Fun) ->
+ Cs = traverse_seq_set(Cs0, Fun),
+ Seq#'SEQUENCE'{components=Cs};
+traverse_1({'SEQUENCE OF',Type0}, Fun) ->
+ Type = traverse(Type0, Fun),
+ {'SEQUENCE OF',Type};
+traverse_1({'SET OF',Type0}, Fun) ->
+ Type = traverse(Type0, Fun),
+ {'SET OF',Type};
+traverse_1(#'SET'{components=Cs0} = Set, Fun) ->
+ Cs = traverse_seq_set(Cs0, Fun),
+ Set#'SET'{components=Cs};
+traverse_1({'CHOICE', Cs0}, Fun) ->
+ Cs = traverse_seq_set(Cs0, Fun),
+ {'CHOICE', Cs};
+traverse_1(Leaf, _) ->
+ Leaf.
+
+traverse_seq_set(List, Fun) when is_list(List) ->
+ traverse_seq_set_1(List, Fun);
+traverse_seq_set({Set, Ext}, Fun) ->
+ {traverse_seq_set_1(Set, Fun), traverse_seq_set_1(Ext, Fun)};
+traverse_seq_set({Set1, Set2, Set3}, Fun) ->
+ {traverse_seq_set_1(Set1, Fun),
+ traverse_seq_set_1(Set2, Fun),
+ traverse_seq_set_1(Set3, Fun)}.
+
+traverse_seq_set_1([#'ComponentType'{} = CT0|Cs], Fun) ->
+ CT = #'ComponentType'{typespec=TS0} = Fun(CT0),
+ TS = traverse(TS0, Fun),
+ [CT#'ComponentType'{typespec=TS}|traverse_seq_set_1(Cs, Fun)];
+traverse_seq_set_1([{'COMPONENTS OF', _} = CO0|Cs], Fun) ->
+ {'COMPONENTS OF', TS0} = Fun(CO0),
+ TS = traverse(TS0, Fun),
+ [{'COMPONENTS OF', TS}|traverse_seq_set_1(Cs, Fun)];
+traverse_seq_set_1([], _) ->
+ [].
-object_to_check(#typedef{typespec=ObjDef}) ->
+object_to_check(_, #typedef{typespec=ObjDef}) ->
ObjDef;
-object_to_check(#valuedef{type=ClassName,value=ObjectRef}) ->
+object_to_check(S, #valuedef{type=Class,value=ObjectRef}) ->
%% If the object definition is parsed as an object the ClassName
- %% is parsed as a type
- #'Object'{classname=ClassName#type.def,def=ObjectRef}.
-
-prepare_objset({'SingleValue',Set}) when is_list(Set) ->
- {set,Set,false};
-prepare_objset(L=['EXTENSIONMARK']) ->
- L;
-prepare_objset(Set) when is_list(Set) ->
- {set,Set,false};
-prepare_objset({{'SingleValue',Set},Ext}) ->
- {set,merge_sets(Set,Ext),true};
-%%prepare_objset({Set,Ext}) when is_list(Set),is_list(Ext) ->
-%% {set,lists:append([Set,Ext]),true};
-prepare_objset({Set,Ext}) when is_list(Set) ->
- {set,merge_sets(Set,Ext),true};
-prepare_objset({{object,definedsyntax,_ObjFields}=Set,Ext}) ->
- {set,merge_sets(Set, Ext),true};
-prepare_objset(ObjDef={object,definedsyntax,_ObjFields}) ->
- {set,[ObjDef],false};
-prepare_objset({ObjDef=#type{},Ext}) when is_list(Ext) ->
- {set,[ObjDef|Ext],true};
-prepare_objset({#type{}=Type,#type{}=Ext}) ->
- {set,[Type,Ext],true};
-prepare_objset(Ret) ->
- Ret.
-
-class_fields_optional_check(S,#classdef{typespec=ClassSpec}) ->
- Fields = ClassSpec#objectclass.fields,
- class_fields_optional_check1(S,Fields).
-
-class_fields_optional_check1(_S,[]) ->
- ok;
-class_fields_optional_check1(S,[{typefield,_,'OPTIONAL'}|Rest]) ->
- class_fields_optional_check1(S,Rest);
-class_fields_optional_check1(S,[{fixedtypevaluefield,_,_,_,'OPTIONAL'}|Rest]) ->
- class_fields_optional_check1(S,Rest);
-class_fields_optional_check1(S,[{fixedtypevaluesetfield,_,_,'OPTIONAL'}|Rest]) ->
- class_fields_optional_check1(S,Rest);
-class_fields_optional_check1(S,[{objectfield,_,_,_,'OPTIONAL'}|Rest]) ->
- class_fields_optional_check1(S,Rest);
-class_fields_optional_check1(S,[{objectsetfield,_,_,'OPTIONAL'}|Rest]) ->
- class_fields_optional_check1(S,Rest).
-
-%% ObjectSetFromObjects functionality
-
-%% The fieldname is a list of field names.They may be objects or
-%% object sets. If ObjectSet is an object set the resulting object set
-%% is the union of object sets if the last field name is an object
-%% set. If the last field is an object the resulting object set is
-%% the set of objects in ObjectSet.
-object_set_from_objects(S,RefedObjMod,FieldName,ObjectSet) ->
- object_set_from_objects(S,RefedObjMod,FieldName,ObjectSet,[]).
-object_set_from_objects(S,RefedObjMod,FieldName,ObjectSet,InterSect)
- when is_record(ObjectSet,'ObjectSet') ->
- #'ObjectSet'{class=Cl,set=Set} = ObjectSet,
- {_,ClassDef} = get_referenced_type(S,Cl),
- object_set_from_objects(S,RefedObjMod,ClassDef,FieldName,Set,InterSect,[]);
-object_set_from_objects(S,RefedObjMod,FieldName,Object,InterSect)
- when is_record(Object,'Object') ->
- #'Object'{classname=Cl,def=Def}=Object,
- object_set_from_objects(S,RefedObjMod,Cl,FieldName,[Def],InterSect,[]).
-object_set_from_objects(S,RefedObjMod,ClassDef,FieldName,['EXTENSIONMARK'|Os],
- InterSect,Acc) ->
- object_set_from_objects(S,RefedObjMod,ClassDef,FieldName,Os,InterSect,%%Acc);
- ['EXTENSIONMARK'|Acc]);
-object_set_from_objects(S,RefedObjMod,ClassDef,FieldName,[O|Os],InterSect,Acc) ->
- case object_set_from_objects2(S,mod_of_obj(RefedObjMod,element(1,O)),
- ClassDef,FieldName,element(3,O),InterSect) of
- ObjS when is_list(ObjS) ->
- object_set_from_objects(S,RefedObjMod,ClassDef,FieldName,Os,InterSect,ObjS++Acc);
- Obj ->
- object_set_from_objects(S,RefedObjMod,ClassDef,FieldName,Os,InterSect,[Obj|Acc])
- end;
-object_set_from_objects(_S,_RefedObjMod,_ClassDef,_FieldName,[],InterSect,Acc) ->
- %% For instance may Acc contain objects of same class from
- %% different object sets that in fact might be duplicates.
- remove_duplicate_objects(osfo_intersection(InterSect,Acc)).
-%% Acc.
-object_set_from_objects2(S,RefedObjMod,ClassDef,[{valuefieldreference,OName}],
- Fields,_InterSect) ->
- %% this is an object
- case lists:keysearch(OName,1,Fields) of
- {value,{_,TDef}} ->
- mk_object_set_from_object(S,RefedObjMod,TDef,ClassDef);
+ %% is parsed as a type.
+ case Class of
+ #type{def=#'Externaltypereference'{}=Def} ->
+ #'Object'{classname=Def,def=ObjectRef};
_ ->
- [] % it may be an absent optional field
- end;
-object_set_from_objects2(S,RefedObjMod,ClassDef,[{typefieldreference,OSName}],
- Fields,_InterSect) ->
- %% this is an object set
- case lists:keysearch(OSName,1,Fields) of
- {value,{_,TDef}} ->
- case TDef#typedef.typespec of
- #'ObjectSet'{class=_NextClName,set=NextSet} ->%% = TDef#typedef.typespec,
- NextSet;
- #'Object'{def=_ObjDef} ->
- mk_object_set_from_object(S,RefedObjMod,TDef,ClassDef)
-%% ObjDef
- %% error({error,{internal,unexpected_object,TDef}})
- end;
- _ ->
- [] % it may be an absent optional field
- end;
-object_set_from_objects2(S,RefedObjMod,_ClassDef,[{valuefieldreference,OName}|Rest],
- Fields,InterSect) ->
- %% this is an object
- case lists:keysearch(OName,1,Fields) of
- {value,{_,TDef}} ->
- #'Object'{classname=NextClName,def=ODef}=TDef#typedef.typespec,
- {_,_,NextFields}=ODef,
- {_,NextClass} = get_referenced_type(S,NextClName),
- object_set_from_objects2(S,RefedObjMod,NextClass,Rest,NextFields,InterSect);
- _ ->
- []
- end;
-object_set_from_objects2(S,RefedObjMod,_ClassDef,[{typefieldreference,OSName}|Rest],
- Fields,InterSect) ->
- %% this is an object set
- Next = {NextClName,NextSet} =
- case lists:keysearch(OSName,1,Fields) of
- {value,{_,TDef}} when is_record(TDef,'ObjectSet') ->
- #'ObjectSet'{class=NextClN,set=NextS} = TDef,
- {NextClN,NextS};
- {value,{_,#typedef{typespec=OS}}} ->
- %% objectsets in defined syntax will come here as typedef{}
- %% #'ObjectSet'{class=NextClN,set=NextS} = OS,
- case OS of
- #'ObjectSet'{class=NextClN,set=NextS} ->
- {NextClN,NextS};
- #'Object'{classname=NextClN,def=NextDef} ->
- {NextClN,[NextDef]}
- end;
- _ ->
- {[],[]}
- end,
- case Next of
- {[],[]} ->
- [];
- _ ->
- {_,NextClass} = get_referenced_type(S,NextClName),
- object_set_from_objects(S,RefedObjMod,NextClass,Rest,NextSet,InterSect,[])
- end.
-
-mk_object_set_from_object(S,RefedObjMod,TDef,Class) ->
- #'Object'{classname=_NextClName,def=ODef} = TDef#typedef.typespec,
- {_,_,NextFields}=ODef,
-
- UniqueFieldName =
- case (catch get_unique_fieldname(S,Class)) of
- {error,'__undefined_',_} -> {unique,undefined};
- {asn1,Msg,_} -> error({class,Msg,S});
- {'EXIT',Msg} -> error({class,{internal_error,Msg},S});
- {Other,_} -> Other
- end,
- VDef = get_unique_value(S,NextFields,UniqueFieldName),
- %% XXXXXXXXXXX
- case VDef of
- [] ->
- ['EXTENSIONMARK'];
- _ ->
- {{RefedObjMod,get_datastr_name(TDef)},VDef,NextFields}
+ asn1_error(S, illegal_object)
end.
-
-
-mod_of_obj(_RefedObjMod,{NewMod,ObjName})
- when is_atom(NewMod),is_atom(ObjName) ->
- NewMod;
-mod_of_obj(RefedObjMod,_) ->
- RefedObjMod.
-
-
-merge_sets(Root,{'SingleValue',Ext}) ->
- merge_sets(Root,Ext);
-merge_sets(Root,Ext) when is_list(Root),is_list(Ext) ->
- Root ++ Ext;
-merge_sets(Root,Ext) when is_list(Ext) ->
- [Root|Ext];
-merge_sets(Root,Ext) when is_list(Root) ->
- Root++[Ext];
-merge_sets(Root,Ext) ->
- [Root]++[Ext].
-
-reduce_objectset(ObjectSet,Exclusion) ->
- case Exclusion of
- {'SingleValue',#'Externalvaluereference'{value=Name}} ->
- case lists:keysearch(Name,1,ObjectSet) of
- {value,El} ->
- lists:subtract(ObjectSet,[El]);
- _ ->
- ObjectSet
- end
- end.
-
-%% Checks a list of objects or object sets and returns a list of selected
-%% information for the code generation.
-check_object_list(S,ClassRef,ObjectList) ->
- check_object_list(S,ClassRef,ObjectList,[]).
-
-check_object_list(S,ClassRef,[ObjOrSet|Objs],Acc) ->
- ?dbg("check_object_list: ~p~n",[ObjOrSet]),
- case ObjOrSet of
- ObjDef when is_tuple(ObjDef),(element(1,ObjDef)==object) ->
- Def =
- check_object(S,#typedef{typespec=ObjDef},
-% #'Object'{classname={objectclassname,ClassRef},
- #'Object'{classname=ClassRef,
- def=ObjDef}),
- check_object_list(S,ClassRef,Objs,[{{no_mod,no_name},Def#'Object'.def}|Acc]);
- {'SingleValue',Ref = #'Externalvaluereference'{}} ->
- ?dbg("{SingleValue,Externalvaluereference}~n",[]),
- {RefedMod,ObjName,
- #'Object'{def=Def}} = check_referenced_object(S,Ref),
- check_object_list(S,ClassRef,Objs,[{{RefedMod,ObjName},Def}|Acc]);
- ObjRef when is_record(ObjRef,'Externalvaluereference') ->
- ?dbg("Externalvaluereference~n",[]),
- {RefedMod,ObjName,
- #'Object'{def=Def}} = check_referenced_object(S,ObjRef),
- check_object_list(S,ClassRef,Objs,[{{RefedMod,ObjName},Def}|Acc]);
- {'ValueFromObject',{_,Object},FieldName} ->
- {_,Def} = get_referenced_type(S,Object),
- TypeDef = get_fieldname_element(S,Def,FieldName),
- (TypeDef#typedef.typespec)#'ObjectSet'.set;
- ObjSet when is_record(ObjSet,type) ->
- ObjSetDef =
- case ObjSet#type.def of
- Ref when is_record(Ref,'Externaltypereference') ->
- {_,D} = get_referenced_type(S,ObjSet#type.def),
- D;
- Other ->
- throw({asn1_error,{'unknown objecset',Other,S}})
- end,
- #'ObjectSet'{set=ObjectsInSet} =
- check_object(S,ObjSetDef,ObjSetDef#typedef.typespec),
- AccList = transform_set_to_object_list(ObjectsInSet,[]),
- check_object_list(S,ClassRef,Objs,AccList++Acc);
- union ->
- check_object_list(S,ClassRef,Objs,Acc);
- {pos,{objectset,_,DefinedObjectSet},Params} ->
- OSDef = #type{def={pt,DefinedObjectSet,Params}},
- #'ObjectSet'{set=Set} =
- check_object(S,ObjOrSet,#'ObjectSet'{class=ClassRef,
- set=OSDef}),
- check_object_list(S,ClassRef,Objs,Set ++ Acc);
- {pv,{simpledefinedvalue,DefinedObject},Params} ->
- Args = [match_parameters(S,Param,S#state.parameters)||
- Param<-Params],
- #'Object'{def=Def} =
- check_object(S,ObjOrSet,
- #'Object'{classname=ClassRef ,
- def={po,{object,DefinedObject},
- Args}}),
- check_object_list(S,ClassRef,Objs,[{{no_mod,no_name},Def}|Acc]);
- {'ObjectSetFromObjects',Os,FieldName} when is_tuple(Os) ->
- NewSet =
- check_ObjectSetFromObjects(S, element(tuple_size(Os), Os),
- FieldName,[]),
- check_object_list(S,ClassRef,Objs,NewSet++Acc);
- {{'ObjectSetFromObjects',Os,FieldName},InterSection}
- when is_tuple(Os) ->
- NewSet =
- check_ObjectSetFromObjects(S, element(tuple_size(Os), Os),
- FieldName,InterSection),
- check_object_list(S,ClassRef,Objs,NewSet++Acc);
- Other ->
- exit({error,{'unknown object',Other},S})
- end;
-%% Finally reverse the accumulated list and if there are any extension
-%% marks in the object set put one indicator of that in the end of the
-%% list.
-check_object_list(_,_,[],Acc) ->
- lists:reverse(Acc).
check_referenced_object(S,ObjRef)
when is_record(ObjRef,'Externalvaluereference')->
@@ -1213,195 +1003,134 @@ check_referenced_object(S,ObjRef)
check_object(update_state(S,RefedMod),ObjectDef,ObjectDef#typedef.typespec)}
end.
-check_ObjectSetFromObjects(S,ObjName,FieldName,InterSection) ->
- {RefedMod,TDef} = get_referenced_type(S,ObjName),
- ObjOrSet = check_object(update_state(S,RefedMod),TDef,TDef#typedef.typespec),
- InterSec = prepare_intersection(S,InterSection),
- _NewSet = object_set_from_objects(S,RefedMod,FieldName,ObjOrSet,InterSec).
+check_ObjectSetFromObjects(S, ObjName, Fields) ->
+ {_,Obj0} = get_referenced_type(S, ObjName),
+ case check_object(S, Obj0, Obj0#typedef.typespec) of
+ #'ObjectSet'{}=Obj1 ->
+ get_fieldname_set(S, Obj1, Fields);
+ #'Object'{classname=Class,
+ def={object,_,ObjFs}} ->
+ ObjSet = #'ObjectSet'{class=Class,
+ set=[{'_','_',ObjFs}]},
+ get_fieldname_set(S, ObjSet, Fields)
+ end.
-prepare_intersection(_S,[]) ->
- [];
-prepare_intersection(S,{'EXCEPT',ObjRef}) ->
- except_names(S,ObjRef);
-prepare_intersection(_S,T) ->
- exit({error,{internal_error,not_implemented,object_set_from_objects,T}}).
-except_names(_S,{'SingleValue',#'Externalvaluereference'{value=ObjName}}) ->
- [{except,ObjName}];
-except_names(_,T) ->
- exit({error,{internal_error,not_implemented,object_set_from_objects,T}}).
-
-osfo_intersection(InterSect,ObjList) ->
- Res = [X|| X = {{_,N},_,_} <- ObjList,
- lists:member({except,N},InterSect) == false],
- case lists:member('EXTENSIONMARK',ObjList) of
- true ->
- Res ++ ['EXTENSIONMARK'];
+%% get_type_from_object(State, ObjectOrObjectSet, [{RefType,FieldName}]) ->
+%% Type
+get_type_from_object(S, Object, FieldNames)
+ when is_record(Object, 'Externaltypereference');
+ is_record(Object, 'Externalvaluereference') ->
+ extract_field(S, Object, FieldNames).
+
+%% get_value_from_object(State, ObjectOrObjectSet, [{RefType,FieldName}]) ->
+%% UntaggedValue
+get_value_from_object(S, Def, FieldNames) ->
+ case extract_field(S, Def, FieldNames) of
+ #valuedef{value=Val} ->
+ Val;
+ {valueset,_}=Val ->
+ Val;
_ ->
- Res
+ asn1_error(S, illegal_value)
end.
-%% get_fieldname_element/3
-%% gets the type/value/object/... of the referenced element in FieldName
-%% FieldName is a list and may have more than one element.
-%% Each element in FieldName can be either {typefieldreference,AnyFieldName}
-%% or {valuefieldreference,AnyFieldName}
-%% Def is the def of the first object referenced by FieldName
-get_fieldname_element(S,Def,[{_RefType,FieldName}]) when is_record(Def,typedef) ->
- {_,_,ObjComps} = (Def#typedef.typespec)#'Object'.def,
- check_fieldname_element(S,lists:keysearch(FieldName,1,ObjComps));
-get_fieldname_element(S,Def,[{_RefType,FieldName}|Rest])
- when is_record(Def,typedef) ->
- %% As FieldName is followd by other FieldNames it has to be an
- %% object or objectset.
- {_,_,ObjComps} = (Def#typedef.typespec)#'Object'.def,
- NewDef = check_fieldname_element(S,lists:keysearch(FieldName,1,ObjComps)),
- ObjDef = fun(#'Object'{def=D}) -> D;
- (#'ObjectSet'{set=Set}) -> Set
- end
- (NewDef),
- case ObjDef of
+%% extract_field(State, ObjectOrObjectSet, [{RefType,FieldName}])
+%% RefType = typefieldreference | valuefieldreference
+%%
+%% Get the type, value, object, object set, or value set from the
+%% referenced object or object set. The list of field name tuples
+%% may have more than one element. All field names but the last
+%% refers to either an object or object set.
+
+extract_field(S, Def0, FieldNames) ->
+ {_,Def1} = get_referenced_type(S, Def0),
+ Def2 = check_object(S, Def1, Def1#typedef.typespec),
+ Def = Def1#typedef{typespec=Def2},
+ get_fieldname_element(S, Def, FieldNames).
+
+%% get_fieldname_element(State, Element, [{RefType,FieldName}]
+%% RefType = typefieldreference | valuefieldreference
+%%
+%% Get the type, value, object, object set, or value set from the referenced
+%% element. The list of field name tuples may have more than one element.
+%% All field names but the last refers to either an object or object set.
+
+get_fieldname_element(S, Object0, [{_RefType,FieldName}|Fields]) ->
+ Object = case Object0 of
+ #typedef{typespec=#'Object'{def=Obj}} -> Obj;
+ {_,_,_}=Obj -> Obj
+ end,
+ case check_fieldname_element(S, FieldName, Object) of
+ #'Object'{def=D} when Fields =/= [] ->
+ get_fieldname_element(S, D, Fields);
+ #'ObjectSet'{}=Set ->
+ get_fieldname_set(S, Set, Fields);
+ Result when Fields =:= [] ->
+ Result
+ end;
+get_fieldname_element(_S, Def, []) ->
+ Def.
+
+get_fieldname_set(S, #'ObjectSet'{set=Set0}, T) ->
+ get_fieldname_set_1(S, Set0, T, []).
+
+get_fieldname_set_1(S, ['EXTENSIONMARK'=Ext|T], Fields, Acc) ->
+ get_fieldname_set_1(S, T, Fields, [Ext|Acc]);
+get_fieldname_set_1(S, [H|T], Fields, Acc) ->
+ try get_fieldname_element(S, H, Fields) of
L when is_list(L) ->
- [get_fieldname_element(S,X,Rest) || X <- L];
- _ ->
- get_fieldname_element(S,ObjDef,Rest)
+ get_fieldname_set_1(S, T, Fields, L++Acc);
+ {valueset,L} ->
+ get_fieldname_set_1(S, T, Fields, L++Acc);
+ Other ->
+ get_fieldname_set_1(S, T, Fields, [Other|Acc])
+ catch
+ throw:{error,_} ->
+ get_fieldname_set_1(S, T, Fields, Acc)
end;
-get_fieldname_element(S,{object,_,Fields},[{_RefType,FieldName}|Rest]) ->
- NewDef = check_fieldname_element(S,lists:keysearch(FieldName,1,Fields)),
- get_fieldname_element(S,NewDef,Rest);
-get_fieldname_element(_S,Def,[]) ->
- Def;
-get_fieldname_element(_S,Def,[{_RefType,_FieldName}|_RestFName])
- when is_record(Def,typedef) ->
- ok.
+get_fieldname_set_1(_, [], _Fields, Acc) ->
+ case Acc of
+ [#valuedef{}|_] ->
+ {valueset,Acc};
+ _ ->
+ Acc
+ end.
+
+check_fieldname_element(S, Name, {_,_,Fields}) ->
+ case lists:keyfind(Name, 1, Fields) of
+ {Name,Def} ->
+ check_fieldname_element_1(S, Def);
+ false ->
+ asn1_error(S, {undefined_field,Name})
+ end.
-check_fieldname_element(S,{value,{_,Def}}) ->
- check_fieldname_element(S,Def);
-check_fieldname_element(S, #typedef{typespec=Ts}=TDef) ->
+check_fieldname_element_1(S, #typedef{typespec=Ts}=TDef) ->
case Ts of
#'Object'{} ->
check_object(S, TDef, Ts);
_ ->
check_type(S, TDef, Ts)
end;
-check_fieldname_element(S, #valuedef{}=VDef) ->
+check_fieldname_element_1(S, #valuedef{}=VDef) ->
try
check_value(S, VDef)
catch
- throw:{objectdef} ->
+ throw:{asn1_class, _} ->
#valuedef{checked=C,pos=Pos,name=N,type=Type,
value=Def} = VDef,
ClassName = Type#type.def,
NewSpec = #'Object'{classname=ClassName,def=Def},
NewDef = #typedef{checked=C,pos=Pos,name=N,typespec=NewSpec},
- check_fieldname_element(S, NewDef)
+ check_fieldname_element_1(S, NewDef)
end;
-check_fieldname_element(S,Eref)
- when is_record(Eref,'Externaltypereference');
- is_record(Eref,'Externalvaluereference') ->
- {_,TDef}=get_referenced_type(S,Eref),
- check_fieldname_element(S,TDef);
-check_fieldname_element(S,Other) ->
- throw({error,{assigned_object_error,"not_assigned_object",Other,S}}).
+check_fieldname_element_1(_S, {value_tag,Val}) ->
+ #valuedef{value=Val};
+check_fieldname_element_1(S, Eref)
+ when is_record(Eref, 'Externaltypereference');
+ is_record(Eref, 'Externalvaluereference') ->
+ {_,TDef} = get_referenced_type(S, Eref),
+ check_fieldname_element_1(S, TDef).
-transform_set_to_object_list([{Name,_UVal,Fields}|Objs],Acc) ->
- transform_set_to_object_list(Objs,[{Name,{object,generatesyntax,Fields}}|Acc]);
-transform_set_to_object_list(['EXTENSIONMARK'|Objs],Acc) ->
-%% transform_set_to_object_list(Objs,['EXTENSIONMARK'|Acc]);
- transform_set_to_object_list(Objs,Acc);
-transform_set_to_object_list([],Acc) ->
- Acc.
-
-get_unique_valuelist(_S,ObjSet,{unique,undefined}) -> % no unique field in object
- lists:map(fun({N,{_,_,F}})->{N,no_unique_value,F};
- (V={_,_,_}) ->V;
- ({A,B}) -> {A,no_unique_value,B}
- end, ObjSet);
-get_unique_valuelist(S,ObjSet,{UFN,Opt}) ->
- get_unique_vlist(S,ObjSet,UFN,Opt,[]).
-
-
-get_unique_vlist(_S,[],_,_,[]) ->
- ['EXTENSIONMARK'];
-get_unique_vlist(S,[],_,Opt,Acc) ->
- case catch check_uniqueness(remove_duplicate_objects(Acc)) of
- {asn1_error,_} when Opt =/= 'OPTIONAL' ->
- error({'ObjectSet',"not unique objects in object set",S});
- {asn1_error,_} ->
- lists:reverse(Acc);
- _ ->
- lists:reverse(Acc)
- end;
-get_unique_vlist(S,['EXTENSIONMARK'|Rest],UniqueFieldName,Opt,Acc) ->
- get_unique_vlist(S,Rest,UniqueFieldName,Opt,Acc);
-get_unique_vlist(S,[{ObjName,Obj}|Rest],UniqueFieldName,Opt,Acc) ->
- {_,_,Fields} = Obj,
- NewObjInf =
- case get_unique_value(S,Fields,UniqueFieldName) of
- #valuedef{value=V} -> [{ObjName,V,Fields}];
- [] -> []; % maybe the object only was a reference to an
- % empty object set.
- no_unique_value -> [{ObjName,no_unique_value,Fields}]
- end,
- get_unique_vlist(S,Rest,UniqueFieldName,Opt,NewObjInf++Acc);
-
-get_unique_vlist(S,[V={_,_,_}|Rest],UniqueFieldName,Opt,Acc) ->
- get_unique_vlist(S,Rest,UniqueFieldName,Opt,[V|Acc]).
-
-get_unique_value(S,Fields,UniqueFieldName) ->
- Module = S#state.mname,
- case lists:keysearch(UniqueFieldName,1,Fields) of
- {value,Field} ->
- case element(2,Field) of
- VDef when is_record(VDef,valuedef) ->
- VDef;
- {'ValueFromObject',Object,Name} ->
- case Object of
- {object,Ext} when is_record(Ext,'Externaltypereference') ->
- OtherModule = Ext#'Externaltypereference'.module,
- ExtObjName = Ext#'Externaltypereference'.type,
- ObjDef = asn1_db:dbget(OtherModule,ExtObjName),
- ObjSpec = ObjDef#typedef.typespec,
- get_unique_value(OtherModule,element(3,ObjSpec),Name);
- {object,{_,_,ObjName}} ->
- ObjDef = asn1_db:dbget(Module,ObjName),
- ObjSpec = ObjDef#typedef.typespec,
- get_unique_value(Module,element(3,ObjSpec),Name);
- {po,Object,_Params} ->
- exit({error,{'parameterized object not implemented yet',
- Object},S})
- end;
- Value when is_atom(Value);is_number(Value) ->
- #valuedef{value=Value,module=Module};
- {'CHOICE',{C,Value}} when is_atom(C) ->
- %% #valuedef{value=normalize_value(S,element(3,Field),VDef,[])}
- case Value of
- Scalar when is_atom(Scalar);is_number(Scalar) ->
- #valuedef{value=Value,module=Module};
- Eref = #'Externalvaluereference'{} ->
- element(2,get_referenced_type(S,Eref))
- end
- end;
- false ->
- case Fields of
- [{_,#typedef{typespec=#'ObjectSet'{set=['EXTENSIONMARK']}}}] ->
- [];
- _ ->
- no_unique_value
- end
- end.
-
-check_uniqueness(NameValueList) ->
- check_uniqueness1(lists:keysort(2,NameValueList)).
-
-check_uniqueness1([]) ->
- true;
-check_uniqueness1([_]) ->
- true;
-check_uniqueness1([{_,N,_},{_,N,_}|_Rest]) ->
- throw({asn1_error,{'objects in set must have unique values in UNIQUE fields',N}});
-check_uniqueness1([_|Rest]) ->
- check_uniqueness1(Rest).
-
%% instantiate_po/4
%% ClassDef is the class of Object,
%% Object is the Parameterized object, which is referenced,
@@ -1410,8 +1139,7 @@ check_uniqueness1([_|Rest]) ->
instantiate_po(S=#state{parameters=_OldArgs},_ClassDef,Object,ArgsList) when is_record(Object,pobjectdef) ->
FormalParams = get_pt_args(Object),
MatchedArgs = match_args(S,FormalParams,ArgsList,[]),
-% NewS = S#state{type=Object,parameters=MatchedArgs++OldArgs},
- NewS = S#state{type=Object,parameters=MatchedArgs},
+ NewS = S#state{parameters=MatchedArgs},
check_object(NewS,Object,#'Object'{classname=Object#pobjectdef.class,
def=Object#pobjectdef.def}).
@@ -1421,20 +1149,14 @@ instantiate_po(S=#state{parameters=_OldArgs},_ClassDef,Object,ArgsList) when is_
%% on the right side of the assignment,
%% ArgsList is the list of actual parameters, i.e. real objects
instantiate_pos(S=#state{parameters=_OldArgs},ClassRef,ObjectSetDef,ArgsList) ->
-% ClassName = ClassDef#classdef.name,
FormalParams = get_pt_args(ObjectSetDef),
OSet = case get_pt_spec(ObjectSetDef) of
- {valueset,Set} ->
-% #'ObjectSet'{class=name2Extref(S#state.mname,
-% ClassName),set=Set};
- #'ObjectSet'{class=ClassRef,set=Set};
- Set when is_record(Set,'ObjectSet') -> Set;
- _ ->
- error({type,"parameterized object set failure",S})
+ {valueset,Set} -> #'ObjectSet'{class=ClassRef,set=Set};
+ Set when is_record(Set,'ObjectSet') -> Set;
+ _ -> asn1_error(S, invalid_objectset)
end,
MatchedArgs = match_args(S,FormalParams,ArgsList,[]),
-% NewS = S#state{type=ObjectSetDef,parameters=MatchedArgs++OldArgs},
- NewS = S#state{type=ObjectSetDef,parameters=MatchedArgs},
+ NewS = S#state{parameters=MatchedArgs},
check_object(NewS,ObjectSetDef,OSet).
@@ -1468,7 +1190,7 @@ gen_incl1(S,Fields,[C|CFields]) ->
check_object(S,TDef,TDef#typedef.typespec);
ERef ->
{_,T} = get_referenced_type(S,ERef),
- check_object(S,T,object_to_check(T))
+ check_object(S, T, object_to_check(S, T))
end,
case gen_incl(S,ObjDef#'Object'.def,
ClassFields) of
@@ -1485,7 +1207,7 @@ gen_incl1(S,Fields,[C|CFields]) ->
end.
get_objclass_fields(S,Eref=#'Externaltypereference'{}) ->
- {_,ClassDef} = get_referenced_type(S,Eref),
+ {_,ClassDef} = get_referenced_type(S,Eref, true),
get_objclass_fields(S,ClassDef);
get_objclass_fields(S,CD=#classdef{typespec=#'Externaltypereference'{}}) ->
get_objclass_fields(S,CD#classdef.typespec);
@@ -1501,10 +1223,10 @@ gen_incl_set(S,Fields,#typedef{typespec=#type{def=Eref}})
{_,CDef} = get_referenced_type(S,Eref),
gen_incl_set(S,Fields,CDef);
gen_incl_set(S,Fields,ClassDef) ->
- case catch get_unique_fieldname(S,ClassDef) of
- Tuple when tuple_size(Tuple) =:= 3 ->
+ case get_unique_fieldname(S, ClassDef) of
+ no_unique ->
false;
- _ ->
+ {_, _} ->
gen_incl_set1(S,Fields,
(ClassDef#classdef.typespec)#objectclass.fields)
end.
@@ -1529,475 +1251,392 @@ gen_incl_set1(S,[Object|Rest],CFields)->
gen_incl_set1(S,Rest,CFields)
end.
-check_objectdefn(S,Def,CDef) when is_record(CDef,classdef) ->
- WithSyntax = (CDef#classdef.typespec)#objectclass.syntax,
- ClassFields = (CDef#classdef.typespec)#objectclass.fields,
+
+%%%
+%%% Check an object definition.
+%%%
+
+check_objectdefn(S, Def, #classdef{typespec=ObjClass}) ->
+ #objectclass{syntax=Syntax0,fields=ClassFields} = ObjClass,
case Def of
{object,defaultsyntax,Fields} ->
- check_defaultfields(S,Fields,ClassFields);
+ check_defaultfields(S, Fields, ClassFields);
{object,definedsyntax,Fields} ->
- {_,WSSpec} = WithSyntax,
- NewFields =
- case catch( convert_definedsyntax(S,Fields,WSSpec,
- ClassFields,[])) of
- {asn1,{_ErrorType,ObjToken,ClassToken}} ->
- throw({asn1,{'match error in object',ObjToken,
- 'found in object',ClassToken,'found in class'}});
- Err={asn1,_} -> throw(Err);
- Err={'EXIT',_} -> throw(Err);
- DefaultFields when is_list(DefaultFields) ->
- DefaultFields
- end,
- {object,defaultsyntax,NewFields};
- {object,_ObjectId} -> % This is a DefinedObject
- fixa;
- Other ->
- exit({error,{objectdefn,Other}})
+ Syntax = get_syntax(S, Syntax0, ClassFields),
+ case match_syntax(S, Syntax, Fields, []) of
+ {match,NewFields,[]} ->
+ {object,defaultsyntax,NewFields};
+ {match,_,[What|_]} ->
+ syntax_match_error(S, What);
+ {nomatch,[What|_]} ->
+ syntax_match_error(S, What);
+ {nomatch,[]} ->
+ syntax_match_error(S)
+ end
+ end.
+
+
+%%%
+%%% Pre-process the simplified syntax so that it can be more
+%%% easily matched.
+%%%
+
+get_syntax(_, {preprocessed_syntax,Syntax}, _) ->
+ Syntax;
+get_syntax(S, {'WITH SYNTAX',Syntax}, ClassFields) ->
+ preprocess_syntax(S, Syntax, ClassFields).
+
+preprocess_syntax(S, Syntax0, Cs) ->
+ Syntax = preprocess_syntax_1(S, Syntax0, Cs, true),
+ Present0 = preprocess_get_fields(Syntax, []),
+ Present1 = lists:sort(Present0),
+ Present = ordsets:from_list(Present1),
+ case Present =:= Present1 of
+ false ->
+ Dupl = Present1 -- Present,
+ asn1_error(S, {syntax_duplicated_fields,Dupl});
+ true ->
+ ok
+ end,
+ Mandatory0 = get_mandatory_class_fields(Cs),
+ Mandatory = ordsets:from_list(Mandatory0),
+ case ordsets:subtract(Mandatory, Present) of
+ [] ->
+ Syntax;
+ [_|_]=Missing ->
+ asn1_error(S, {syntax_missing_mandatory_fields,Missing})
+ end.
+
+preprocess_syntax_1(S, [H|T], Cs, Mandatory) when is_list(H) ->
+ [{optional,preprocess_syntax_1(S, H, Cs, false)}|
+ preprocess_syntax_1(S, T, Cs, Mandatory)];
+preprocess_syntax_1(S, [{valuefieldreference,Name}|T], Cs, Mandatory) ->
+ F = preprocess_check_field(S, Name, Cs, Mandatory),
+ [F|preprocess_syntax_1(S, T, Cs, Mandatory)];
+preprocess_syntax_1(S, [{typefieldreference,Name}|T], Cs, Mandatory) ->
+ F = preprocess_check_field(S, Name, Cs, Mandatory),
+ [F|preprocess_syntax_1(S, T, Cs, Mandatory)];
+preprocess_syntax_1(S,[{Token,_}|T], Cs, Mandatory) when is_atom(Token) ->
+ [{token,Token}|preprocess_syntax_1(S, T, Cs, Mandatory)];
+preprocess_syntax_1(S, [Token|T], Cs, Mandatory) when is_atom(Token) ->
+ [{token,Token}|preprocess_syntax_1(S, T, Cs, Mandatory)];
+preprocess_syntax_1(_, [], _, _) -> [].
+
+preprocess_check_field(S, Name, Cs, Mandatory) ->
+ case lists:keyfind(Name, 2, Cs) of
+ Tuple when is_tuple(Tuple) ->
+ case not Mandatory andalso is_mandatory_class_field(Tuple) of
+ true ->
+ asn1_error(S, {syntax_mandatory_in_optional_group,Name});
+ false ->
+ {field,Tuple}
+ end;
+ false ->
+ asn1_error(S, {syntax_undefined_field,Name})
end.
+preprocess_get_fields([{field,F}|T], Acc) ->
+ Name = element(2, F),
+ preprocess_get_fields(T, [Name|Acc]);
+preprocess_get_fields([{optional,L}|T], Acc) ->
+ preprocess_get_fields(T, preprocess_get_fields(L, Acc));
+preprocess_get_fields([_|T], Acc) ->
+ preprocess_get_fields(T, Acc);
+preprocess_get_fields([], Acc) ->
+ Acc.
+
+%%%
+%%% Match the actual fields in the object definition to
+%%% the pre-processed simplified syntax.
+%%%
+
+match_syntax(S, [{token,Token}|T], [A|As]=Args, Acc) ->
+ case A of
+ {word_or_setting,_,#'Externaltypereference'{type=Token}} ->
+ match_syntax(S, T, As, Acc);
+ {Token,Line} when is_integer(Line) ->
+ match_syntax(S, T, As, Acc);
+ _ ->
+ {nomatch,Args}
+ end;
+match_syntax(S, [{field,Field}|T]=Fs, [A|As0]=Args0, Acc) ->
+ try match_syntax_type(S, Field, A) of
+ {match,Match} ->
+ match_syntax(S, T, As0, lists:reverse(Match)++Acc);
+ {params,_Name,#ptypedef{args=Params}=P,Ref} ->
+ {Args,As} = lists:split(length(Params), As0),
+ Val = match_syntax_params(S, P, Ref, Args),
+ match_syntax(S, Fs, [Val|As], Acc)
+ catch
+ _:_ ->
+ {nomatch,Args0}
+ end;
+match_syntax(S, [{optional,L}|T], As0, Acc) ->
+ case match_syntax(S, L, As0, []) of
+ {match,Match,As} ->
+ match_syntax(S, T, As, lists:reverse(Match)++Acc);
+ {nomatch,As0} ->
+ match_syntax(S, T, As0, Acc);
+ {nomatch,_}=NoMatch ->
+ NoMatch
+ end;
+match_syntax(_, [_|_], [], _Acc) ->
+ {nomatch,[]};
+match_syntax(_, [], As, Acc) ->
+ {match,Acc,As}.
+
+match_syntax_type(S, Type, {value_tag,Val}) ->
+ match_syntax_type(S, Type, Val);
+match_syntax_type(S, Type, {setting,_,Val}) ->
+ match_syntax_type(S, Type, Val);
+match_syntax_type(S, Type, {word_or_setting,_,Val}) ->
+ match_syntax_type(S, Type, Val);
+match_syntax_type(_S, _Type, {Atom,Line})
+ when is_atom(Atom), is_integer(Line) ->
+ throw(nomatch);
+match_syntax_type(S, {fixedtypevaluefield,Name,#type{}=T,_,_}=Type,
+ #'Externalvaluereference'{}=ValRef0) ->
+ try get_referenced_type(S, ValRef0) of
+ {M,#valuedef{}=ValDef} ->
+ match_syntax_type(update_state(S, M), Type, ValDef)
+ catch
+ throw:{error,_} ->
+ ValRef = #valuedef{name=Name,
+ type=T,
+ value=ValRef0,
+ module=S#state.mname},
+ match_syntax_type(S, Type, ValRef)
+ end;
+match_syntax_type(S, {fixedtypevaluefield,Name,#type{},_,_}, #valuedef{}=Val0) ->
+ Val = check_value(S, Val0),
+ {match,[{Name,Val}]};
+match_syntax_type(S, {fixedtypevaluefield,Name,#type{},_,_},
+ {'ValueFromObject',{object,Object},FieldNames}) ->
+ Val = extract_field(S, Object, FieldNames),
+ {match,[{Name,Val}]};
+match_syntax_type(S, {fixedtypevaluefield,Name,#type{}=T,_,_}=Type, Any) ->
+ ValDef = #valuedef{name=Name,type=T,value=Any,module=S#state.mname},
+ match_syntax_type(S, Type, ValDef);
+match_syntax_type(_S, {fixedtypevaluesetfield,Name,#type{},_}, Any) ->
+ {match,[{Name,Any}]};
+match_syntax_type(S, {objectfield,Name,_,_,_}, #'Externalvaluereference'{}=Ref) ->
+ {M,Obj} = get_referenced_type(S, Ref),
+ check_object(S, Obj, object_to_check(S, Obj)),
+ {match,[{Name,Ref#'Externalvaluereference'{module=M}}]};
+match_syntax_type(S, {objectfield,Name,Class,_,_}, {object,_,_}=ObjDef) ->
+ InlinedObjName = list_to_atom(lists:concat([S#state.tname,
+ '_',Name])),
+ ObjSpec = #'Object'{classname=Class,def=ObjDef},
+ CheckedObj = check_object(S, #typedef{typespec=ObjSpec}, ObjSpec),
+ InlObj = #typedef{checked=true,name=InlinedObjName,typespec=CheckedObj},
+ ObjKey = {InlinedObjName, InlinedObjName},
+ insert_once(S, inlined_objects, ObjKey),
+ %% Which module to use here? Could it be other than top_module?
+ asn1_db:dbput(get(top_module), InlinedObjName, InlObj),
+ {match,[{Name,InlObj}]};
+match_syntax_type(_S, {objectfield,Name,_,_,_}, Any) ->
+ {match,[{Name,Any}]};
+match_syntax_type(S, {objectsetfield,Name,CDef0,_}, Any) ->
+ CDef = case CDef0 of
+ #type{def=CDef1} -> CDef1;
+ CDef1 -> CDef1
+ end,
+ case match_syntax_objset(S, Any, CDef) of
+ #typedef{typespec=#'ObjectSet'{}=Ts0}=Def ->
+ Ts = check_object(S, Def, Ts0),
+ {match,[{Name,Def#typedef{checked=true,typespec=Ts}}]};
+ _ ->
+ syntax_match_error(S, Any)
+ end;
+match_syntax_type(S, {typefield,Name0,_}, #type{def={pt,_,_}=Def}=Actual) ->
+ %% This is an inlined type. If constructed type, save in data base.
+ T = check_type(S, #typedef{typespec=Actual}, Actual),
+ #'Externaltypereference'{type=PtName} = element(2, Def),
+ NameList = [PtName,S#state.tname],
+ Name = list_to_atom(asn1ct_gen:list2name(NameList)),
+ NewTDef = #typedef{checked=true,name=Name,typespec=T},
+ asn1_db:dbput(S#state.mname, Name, NewTDef),
+ insert_once(S, parameterized_objects, {Name,type,NewTDef}),
+ {match,[{Name0,NewTDef}]};
+match_syntax_type(S, {typefield,Name,_}, #type{def=#'ObjectClassFieldType'{}}=Actual) ->
+ T = check_type(S, #typedef{typespec=Actual}, Actual),
+ {match,[{Name,ocft_def(T)}]};
+match_syntax_type(S, {typefield,Name,_}, #type{def=#'Externaltypereference'{}=Ref}) ->
+ match_syntax_external(S, Name, Ref);
+match_syntax_type(S, {typefield,Name,_}, #type{def=Def}=Actual) ->
+ T = check_type(S, #typedef{typespec=Actual}, Actual),
+ TypeName = asn1ct_gen:type(asn1ct_gen:get_inner(Def)),
+ {match,[{Name,#typedef{checked=true,name=TypeName,typespec=T}}]};
+match_syntax_type(S, {typefield,Name,_}, #'Externaltypereference'{}=Ref) ->
+ match_syntax_external(S, Name, Ref);
+match_syntax_type(_S, {variabletypevaluefield,Name,_,_}, Any) ->
+ {match,[{Name,Any}]};
+match_syntax_type(_S, {variabletypevaluesetfield,Name,_,_}, Any) ->
+ {match,[{Name,Any}]};
+match_syntax_type(_S, _Type, _Actual) ->
+ throw(nomatch).
+
+match_syntax_params(S0, #ptypedef{name=Name}=PtDef,
+ #'Externaltypereference'{module=M,type=N}=ERef0, Args) ->
+ S = S0#state{mname=M,module=load_asn1_module(S0, M),tname=Name},
+ Type = check_type(S, PtDef, #type{def={pt,ERef0,Args}}),
+ ERefName = new_reference_name(N),
+ ERef = #'Externaltypereference'{type=ERefName,module=S0#state.mname},
+ TDef = #typedef{checked=true,name=ERefName,typespec=Type},
+ insert_once(S0, parameterized_objects, {ERefName,type,TDef}),
+ asn1_db:dbput(S0#state.mname, ERef#'Externaltypereference'.type, TDef),
+ ERef.
+
+match_syntax_external(#state{mname=Mname}=S0, Name, Ref0) ->
+ {M,T0} = get_referenced_type(S0, Ref0),
+ Ref1 = Ref0#'Externaltypereference'{module=M},
+ case T0 of
+ #ptypedef{} ->
+ {params,Name,T0,Ref1};
+ #typedef{checked=false}=TDef0 when Mname =/= M ->
+ %% This typedef is an imported type (or maybe a set.asn
+ %% compilation).
+ S = S0#state{mname=M,module=load_asn1_module(S0, M),
+ tname=get_datastr_name(TDef0)},
+ Type = check_type(S, TDef0, TDef0#typedef.typespec),
+ TDef = TDef0#typedef{checked=true,typespec=Type},
+ asn1_db:dbput(M, get_datastr_name(TDef), TDef),
+ {match,[{Name,merged_name(S, Ref1)}]};
+ TDef ->
+ %% This might be a renamed type in a set of specs,
+ %% so rename the ref.
+ Type = asn1ct:get_name_of_def(TDef),
+ Ref = Ref1#'Externaltypereference'{type=Type},
+ {match,[{Name,Ref}]}
+ end.
+
+match_syntax_objset(_S, {element_set,_,_}=Set, ClassDef) ->
+ make_objset(ClassDef, Set);
+match_syntax_objset(S, #'Externaltypereference'{}=Ref, _) ->
+ {_,T} = get_referenced_type(S, Ref),
+ T;
+match_syntax_objset(S, #'Externalvaluereference'{}=Ref, _) ->
+ {_,T} = get_referenced_type(S, Ref),
+ T;
+match_syntax_objset(_, [_|_]=Set, ClassDef) ->
+ make_objset(ClassDef, Set);
+match_syntax_objset(S, {object,definedsyntax,Words}, ClassDef) ->
+ case Words of
+ [Word] ->
+ match_syntax_objset_1(S, Word, ClassDef);
+ [_|_] ->
+ %% More than one word does not make sense.
+ none
+ end;
+match_syntax_objset(S, #type{def=#'Externaltypereference'{}=Set}, ClassDef) ->
+ match_syntax_objset(S, Set, ClassDef);
+match_syntax_objset(_, #type{}, _) ->
+ none.
+
+match_syntax_objset_1(S, {setting,_,Set}, ClassDef) ->
+ %% Word that starts with an uppercase letter.
+ match_syntax_objset(S, Set, ClassDef);
+match_syntax_objset_1(S, {word_or_setting,_,Set}, ClassDef) ->
+ %% Word in uppercase/hyphens only.
+ match_syntax_objset(S, Set, ClassDef);
+match_syntax_objset_1(S, #type{def={'TypeFromObject', {object,Object}, FNs}},
+ ClassDef) ->
+ Set = extract_field(S, Object, FNs),
+ [_|_] = Set,
+ #typedef{checked=true,typespec=#'ObjectSet'{class=ClassDef,set=Set}};
+match_syntax_objset_1(_, #type{def=#'ObjectClassFieldType'{}}=Set, ClassDef) ->
+ make_objset(ClassDef, Set);
+match_syntax_objset_1(_, {object,_,_}=Object, ClassDef) ->
+ make_objset(ClassDef, [Object]).
+
+make_objset(ClassDef, Set) ->
+ #typedef{typespec=#'ObjectSet'{class=ClassDef,set=Set}}.
+
+-spec syntax_match_error(_) -> no_return().
+syntax_match_error(S) ->
+ asn1_error(S, syntax_nomatch).
+
+-spec syntax_match_error(_, _) -> no_return().
+syntax_match_error(S, What0) ->
+ What = printable_string(What0),
+ asn1_error(S, {syntax_nomatch,What}).
+
+printable_string(Def) ->
+ printable_string_1(Def).
+
+printable_string_1({word_or_setting,_,Def}) ->
+ printable_string_1(Def);
+printable_string_1({value_tag,V}) ->
+ printable_string_1(V);
+printable_string_1({#seqtag{val=Val1},Val2}) ->
+ atom_to_list(Val1) ++ " " ++ printable_string_1(Val2);
+printable_string_1(#type{def=Def}) ->
+ atom_to_list(asn1ct_gen:get_inner(Def));
+printable_string_1(#'Externaltypereference'{type=Type}) ->
+ atom_to_list(Type);
+printable_string_1(#'Externalvaluereference'{value=Type}) ->
+ atom_to_list(Type);
+printable_string_1({Atom,Line}) when is_atom(Atom), is_integer(Line) ->
+ q(Atom);
+printable_string_1({object,definedsyntax,L}) ->
+ q(string:join([printable_string_1(Item) || Item <- L], " "));
+printable_string_1([_|_]=Def) ->
+ case lists:all(fun is_integer/1, Def) of
+ true ->
+ lists:flatten(io_lib:format("~p", [Def]));
+ false ->
+ q(string:join([printable_string_1(Item) || Item <- Def], " "))
+ end;
+printable_string_1(Def) ->
+ lists:flatten(io_lib:format("~p", [Def])).
+
+q(S) ->
+ lists:concat(["\"",S,"\""]).
+
check_defaultfields(S, Fields, ClassFields) ->
Present = ordsets:from_list([F || {F,_} <- Fields]),
Mandatory0 = get_mandatory_class_fields(ClassFields),
Mandatory = ordsets:from_list(Mandatory0),
All = ordsets:from_list([element(2, F) || F <- ClassFields]),
- #state{type=T,tname=Obj} = S,
+ #state{tname=Obj} = S,
case ordsets:subtract(Present, All) of
[] ->
ok;
[_|_]=Invalid ->
- asn1_error(S, T, {invalid_fields,Invalid,Obj})
+ asn1_error(S, {invalid_fields,Invalid,Obj})
end,
case ordsets:subtract(Mandatory, Present) of
[] ->
check_defaultfields_1(S, Fields, ClassFields, []);
[_|_]=Missing ->
- asn1_error(S, T, {missing_mandatory_fields,Missing,Obj})
+ asn1_error(S, {missing_mandatory_fields,Missing,Obj})
end.
check_defaultfields_1(_S, [], _ClassFields, Acc) ->
{object,defaultsyntax,lists:reverse(Acc)};
check_defaultfields_1(S, [{FName,Spec}|Fields], ClassFields, Acc) ->
CField = lists:keyfind(FName, 2, ClassFields),
- {NewField,RestFields} =
- convert_to_defaultfield(S, FName, [Spec|Fields], CField),
- check_defaultfields_1(S, RestFields, ClassFields, [NewField|Acc]).
-
-convert_definedsyntax(_S,[],[],_ClassFields,Acc) ->
- lists:reverse(Acc);
-convert_definedsyntax(S,Fields,WithSyntax,ClassFields,Acc) ->
- {MatchedField,RestFields,RestWS} =
- match_field(S,Fields,WithSyntax,ClassFields),
- if
- is_list(MatchedField) ->
- convert_definedsyntax(S,RestFields,RestWS,ClassFields,
- lists:append(MatchedField,Acc));
- true ->
- convert_definedsyntax(S,RestFields,RestWS,ClassFields,
- [MatchedField|Acc])
- end.
-
-get_mandatory_class_fields([{fixedtypevaluefield,Name,_,_,'MANDATORY'}|T]) ->
- [Name|get_mandatory_class_fields(T)];
-get_mandatory_class_fields([{objectfield,Name,_,_,'MANDATORY'}|T]) ->
- [Name|get_mandatory_class_fields(T)];
-get_mandatory_class_fields([{objectsetfield,Name,_,'MANDATORY'}|T]) ->
- [Name|get_mandatory_class_fields(T)];
-get_mandatory_class_fields([{typefield,Name,'MANDATORY'}|T]) ->
- [Name|get_mandatory_class_fields(T)];
-get_mandatory_class_fields([{variabletypevaluefield,Name,_,'MANDATORY'}|T]) ->
- [Name|get_mandatory_class_fields(T)];
-get_mandatory_class_fields([{variabletypevaluesetfield,
- Name,_,'MANDATORY'}|T]) ->
- [Name|get_mandatory_class_fields(T)];
-get_mandatory_class_fields([_|T]) ->
- get_mandatory_class_fields(T);
-get_mandatory_class_fields([]) -> [].
-
-match_field(S,Fields,WithSyntax,ClassFields) ->
- match_field(S,Fields,WithSyntax,ClassFields,[]).
-
-match_field(S,Fields,[W|Ws],ClassFields,Acc) when is_list(W) ->
- case catch(match_optional_field(S,Fields,W,ClassFields,[])) of
- {'EXIT',_} ->
- match_field(Fields,Ws,ClassFields,Acc); %% add S
-%% {[Result],RestFields} ->
-%% {Result,RestFields,Ws};
- {Result,RestFields} when is_list(Result) ->
- {Result,RestFields,Ws};
- _ ->
- match_field(S,Fields,Ws,ClassFields,Acc)
- end;
-match_field(S,Fields,WithSyntax,ClassFields,_Acc) ->
- match_mandatory_field(S,Fields,WithSyntax,ClassFields,[]).
-
-match_optional_field(_S,RestFields,[],_,Ret) ->
- {Ret,RestFields};
-%% An additional optional field within an optional field
-match_optional_field(S,Fields,[W|Ws],ClassFields,Ret) when is_list(W) ->
- case catch match_optional_field(S,Fields,W,ClassFields,[]) of
- {'EXIT',_} when length(Ws) > 0 ->
- match_optional_field(S,Fields,Ws,ClassFields,Ret);
- {'EXIT',_} ->
- {Ret,Fields};
- {asn1,{optional_matcherror,_,_}} when length(Ws) > 0 ->
- match_optional_field(S,Fields,Ws,ClassFields,Ret);
- {asn1,{optional_matcherror,_,_}} ->
- {Ret,Fields};
- {OptionalField,RestFields} ->
- match_optional_field(S,RestFields,Ws,ClassFields,
- lists:append(OptionalField,Ret))
- end;
-%% identify and skip word
-match_optional_field(S,[{_,_,#'Externaltypereference'{type=WorS}}|Rest],
- [WorS|Ws],ClassFields,Ret) ->
- match_optional_field(S,Rest,Ws,ClassFields,Ret);
-match_optional_field(S,[],_,ClassFields,Ret) ->
- match_optional_field(S,[],[],ClassFields,Ret);
-%% identify and skip comma
-match_optional_field(S,[{WorS,_}|Rest],[{WorS,_}|Ws],ClassFields,Ret) ->
- match_optional_field(S,Rest,Ws,ClassFields,Ret);
-%% am optional setting inside another optional setting may be "double-listed"
-match_optional_field(S,[Setting],DefinedSyntax,ClassFields,Ret)
- when is_list(Setting) ->
- match_optional_field(S,Setting,DefinedSyntax,ClassFields,Ret);
-%% identify and save field data
-match_optional_field(S,[Setting|Rest],[{_,W}|Ws],ClassFields,Ret) ->
- ?dbg("matching optional field setting: ~p with user friendly syntax: ~p~n",[Setting,W]),
- WorS =
- case Setting of
- Type when is_record(Type,type) -> Type;
- {'ValueFromObject',_,_} -> Setting;
- {object,_,_} -> Setting;
- {_,_,WordOrSetting} -> WordOrSetting;
- Other -> Other
- end,
- case lists:keysearch(W,2,ClassFields) of
- false ->
- throw({asn1,{optional_matcherror,WorS,W}});
- {value,CField} ->
- {NewField,RestFields} =
- convert_to_defaultfield(S,W,[WorS|Rest],CField),
- match_optional_field(S,RestFields,Ws,ClassFields,[NewField|Ret])
- end;
-match_optional_field(_S,[WorS|_Rest],[W|_Ws],_ClassFields,_Ret) ->
- throw({asn1,{optional_matcherror,WorS,W}}).
-
-match_mandatory_field(_S,[],[],_,[Acc]) ->
- {Acc,[],[]};
-match_mandatory_field(_S,[],[],_,Acc) ->
- {Acc,[],[]};
-match_mandatory_field(S,[],[H|T],CF,Acc) when is_list(H) ->
- match_mandatory_field(S,[],T,CF,Acc);
-match_mandatory_field(_S,[],WithSyntax,_,_Acc) ->
- throw({asn1,{mandatory_matcherror,[],WithSyntax}});
-%match_mandatory_field(_S,Fields,WithSyntax=[W|_Ws],_ClassFields,[Acc]) when is_list(W) ->
-match_mandatory_field(_S,Fields,WithSyntax=[W|_Ws],_ClassFields,Acc) when is_list(W), length(Acc) >= 1 ->
- {Acc,Fields,WithSyntax};
-%% identify and skip word
-%%match_mandatory_field(S,[{_,_,WorS}|Rest],
-match_mandatory_field(S,[{_,_,#'Externaltypereference'{type=WorS}}|Rest],
- [WorS|Ws],ClassFields,Acc) ->
- match_mandatory_field(S,Rest,Ws,ClassFields,Acc);
-%% identify and skip comma
-match_mandatory_field(S,[{WorS,_}|Rest],[{WorS,_}|Ws],ClassFields,Ret) ->
- match_mandatory_field(S,Rest,Ws,ClassFields,Ret);
-%% identify and save field data
-match_mandatory_field(S,[Setting|Rest],[{_,W}|Ws],ClassFields,Acc) ->
- ?dbg("matching field setting: ~p with user friendly syntax: ~p~n",[Setting,W]),
- WorS =
- case Setting of
- {object,_,_} -> Setting;
- {_,_,WordOrSetting} -> WordOrSetting;
- Type when is_record(Type,type) -> Type;
- Other -> Other
- end,
- case lists:keysearch(W,2,ClassFields) of
- false ->
- throw({asn1,{mandatory_matcherror,WorS,W}});
- {value,CField} ->
- {NewField,RestFields} =
- convert_to_defaultfield(S,W,[WorS|Rest],CField),
- match_mandatory_field(S,RestFields,Ws,ClassFields,[NewField|Acc])
- end;
-
-match_mandatory_field(_S,[WorS|_Rest],[W|_Ws],_ClassFields,_Acc) ->
- throw({asn1,{mandatory_matcherror,WorS,W}}).
+ {match,Match} = match_syntax_type(S, CField, Spec),
+ check_defaultfields_1(S, Fields, ClassFields, Match++Acc).
-%% Converts a field of an object from defined syntax to default syntax
-%% A field may be a type, a fixed type value, an object, an objectset,
-%%
-convert_to_defaultfield(S,ObjFieldName,[OFS|RestOFS],CField)->
- ?dbg("convert field: ~p of type: ~p~n",[ObjFieldName,element(1,CField)]),
- CurrMod = S#state.mname,
- Strip_value_tag =
- fun({value_tag,ValueSetting}) -> ValueSetting;
- (VS) -> VS
- end,
- ObjFieldSetting = Strip_value_tag(OFS),
- RestSettings = [Strip_value_tag(X)||X <- RestOFS],
- case element(1,CField) of
- typefield ->
- TypeDef=
- case ObjFieldSetting of
- TypeRec when is_record(TypeRec,type) -> TypeRec#type.def;
- TDef when is_record(TDef,typedef) ->
- TDef#typedef{checked=true,
- typespec=check_type(S,TDef,
- TDef#typedef.typespec)};
- _ -> ObjFieldSetting
- end,
- {Type,SettingsLeft} =
- if
- is_record(TypeDef,typedef) -> {TypeDef,RestSettings};
- is_record(TypeDef,'ObjectClassFieldType') ->
- T=check_type(S,#typedef{typespec=ObjFieldSetting},ObjFieldSetting),
- {oCFT_def(S,T),RestSettings};
-% #typedef{checked=true,name=Name,typespec=IT};
- is_tuple(TypeDef), element(1,TypeDef) == pt ->
- %% this is an inlined type. If constructed
- %% type save in data base
- T=check_type(S,#typedef{typespec=ObjFieldSetting},ObjFieldSetting),
- #'Externaltypereference'{type=PtName} =
- element(2,TypeDef),
- NameList = [PtName,S#state.tname],
- NewName = list_to_atom(asn1ct_gen:list2name(NameList)),
- NewTDef=#typedef{checked=true,name=NewName,
- typespec=T},
- asn1_db:dbput(S#state.mname,NewName,NewTDef),
- %%asn1ct_gen:insert_once(parameterized_objects,{NewName,type,NewTDef}),
- insert_once(S,parameterized_objects,
- {NewName,type,NewTDef}),
- {NewTDef,RestSettings};
- is_tuple(TypeDef), element(1,TypeDef)=='SelectionType' ->
- T=check_type(S,#typedef{typespec=ObjFieldSetting},
- ObjFieldSetting),
- Name = type_name(S,T),
- {#typedef{checked=true,name=Name,typespec=T},RestSettings};
- true ->
- case asn1ct_gen:type(asn1ct_gen:get_inner(TypeDef)) of
- ERef = #'Externaltypereference'{module=CurrMod} ->
- {RefMod,T} = get_referenced_type(S,ERef),
- check_and_save(S,ERef#'Externaltypereference'{module=RefMod},T,RestSettings);
-
- ERef = #'Externaltypereference'{} ->
- {RefMod,T} = get_referenced_type(S,ERef),
- check_and_save(S,ERef#'Externaltypereference'{module=RefMod},T,RestSettings);
- Bif when Bif=={primitive,bif};Bif=={constructed,bif} ->
- T = check_type(S,#typedef{typespec=ObjFieldSetting},
- ObjFieldSetting),
- {#typedef{checked=true,name=Bif,typespec=T},RestSettings};
- _ ->
- %this case should not happen any more
- {Mod,T} =
- get_referenced_type(S,#'Externaltypereference'{module=S#state.mname,type=ObjFieldSetting}),
- case Mod of
- CurrMod ->
- {T,RestSettings};
- ExtMod ->
- #typedef{name=Name} = T,
- {T#typedef{name={ExtMod,Name}},RestSettings}
- end
- end
- end,
- {{ObjFieldName,Type},SettingsLeft};
- fixedtypevaluefield ->
- case ObjFieldName of
- Val when is_atom(Val) ->
- %% ObjFieldSetting can be a value,an objectidentifiervalue,
- %% an element in an enumeration or namednumberlist etc.
- ValRef =
- case ObjFieldSetting of
- ValSetting=#'Externalvaluereference'{} ->
- ValSetting;
- {'ValueFromObject',{_,ObjRef},FieldName} ->
- {_,Object} = get_referenced_type(S,ObjRef),
- ChObject = check_object(S,Object,
- Object#typedef.typespec),
- get_fieldname_element(S,Object#typedef{typespec=ChObject},
- FieldName);
- ValSetting = #valuedef{} ->
- ValSetting;
- ValSetting ->
- #valuedef{type=element(3,CField),
- value=ValSetting,
- module=S#state.mname}
- end,
- ?dbg("fixedtypevaluefield ValRef: ~p~n",[ValRef]),
- case ValRef of
- #valuedef{} ->
- {{ObjFieldName,check_value(S,ValRef)},RestSettings};
- _ ->
- ValDef =
- case catch get_referenced_type(S,ValRef) of
- {error,_} ->
- NewValDef =
- #valuedef{name=Val,
- type=element(3,CField),
- value=ObjFieldSetting,
- module=S#state.mname},
- check_value(S,NewValDef);
- {M,VDef} when is_record(VDef,valuedef) ->
- check_value(update_state(S,M),
- %%S#state{mname=M},
- VDef);%% XXX
- {M,VDef} ->
- check_value(update_state(S,M),
- %%S#state{mname=M},
- #valuedef{name=Val,
- type=element(3,CField),
- value=VDef,
- module=M})
- end,
- {{ObjFieldName,ValDef},RestSettings}
- end;
- Val ->
- {{ObjFieldName,Val},RestSettings}
- end;
- fixedtypevaluesetfield ->
- {{ObjFieldName,ObjFieldSetting},RestSettings};
- objectfield ->
- CheckObject =
- fun(O) ->
- O#typedef{checked=true,typespec=
- check_object(S,O,O#typedef.typespec)}
- end,
- ObjectSpec =
- case ObjFieldSetting of
- Ref when is_record(Ref,'Externalvaluereference') ->
- %% The object O might be a #valuedef{} if
- %% e.g. the definition looks like
- %% myobj SOMECLASS ::= referencedObject
- {M,O} = get_referenced_type(S,Ref),
- check_object(S,O,object_to_check(O)),
- Ref#'Externalvaluereference'{module=M};
-
- {'ValueFromObject',{_,ObjRef},FieldName} ->
- %% This is an ObjectFromObject
- {_,Object} = get_referenced_type(S,ObjRef),
- ChObject = check_object(S,Object,
- Object#typedef.typespec),
- ObjFromObj=
- get_fieldname_element(S,Object#typedef{
- typespec=ChObject},
- FieldName),
- CheckObject(ObjFromObj);
- ObjDef={object,_,_} ->
- %% An object defined inlined in another object
- %% class is an objectfield, that implies that
- %% {objectsetfield,TypeFieldName,DefinedObjecClass,
- %% OptionalitySpec}
- %% DefinedObjecClass = #'Externaltypereference'{}|
- %% 'TYPE-IDENTIFIER' | 'ABSTRACT-SYNTAX'
- ClassName = element(3,CField),
- InlinedObjName=
- list_to_atom(lists:concat([S#state.tname]++
- ['_',ObjFieldName])),
-
- ObjSpec = #'Object'{classname=ClassName,
- def=ObjDef},
- CheckedObj=
- check_object(S,#typedef{typespec=ObjSpec},ObjSpec),
- InlObj = #typedef{checked=true,name=InlinedObjName,
- typespec=CheckedObj},
- ObjKey = {InlinedObjName,InlinedObjName},
- %% asn1ct_gen:insert_once(inlined_objects,ObjKey),
- insert_once(S,inlined_objects,ObjKey),
- %% Which module to use here? Could it be other than top_module ?
- %% asn1_db:dbput(S#state.mname,InlinedObjName,InlObj),
- asn1_db:dbput(get(top_module),InlinedObjName,InlObj),
- InlObj;
- #type{def=Eref} when is_record(Eref,'Externaltypereference') ->
- {_,O} = get_referenced_type(S,Eref),
- CheckObject(O);
- Other ->
- {_,O} = get_referenced_type(S,#'Externaltypereference'{module=S#state.mname,type=Other}),
- CheckObject(O)
- end,
- {{ObjFieldName,ObjectSpec},RestSettings};
- variabletypevaluefield ->
- {{ObjFieldName,ObjFieldSetting},RestSettings};
- variabletypevaluesetfield ->
- {{ObjFieldName,ObjFieldSetting},RestSettings};
-%% objectset_or_fixedtypevalueset_field ->
-%% ok;
- objectsetfield ->
- ObjSetSpec = get_objectset_def(S,ObjFieldSetting,CField),
- ?dbg("objectsetfield, ObjSetSpec:~p~n",[ObjSetSpec]),
- {{ObjFieldName,
- ObjSetSpec#typedef{checked=true,
- typespec=check_object(S,ObjSetSpec,
- ObjSetSpec#typedef.typespec)}},RestSettings}
- end.
+get_mandatory_class_fields(ClassFields) ->
+ [element(2, F) || F <- ClassFields,
+ is_mandatory_class_field(F)].
-get_objectset_def(S,Ref,CField)
- when is_record(Ref,'Externaltypereference');
- is_record(Ref,'Externalvaluereference') ->
- {_M,T}=get_referenced_type(S,Ref),
- get_objectset_def2(S,T,CField);
-get_objectset_def(S,ObjectList,CField) when is_list(ObjectList) ->
- %% an objctset defined in the object,though maybe
- %% parsed as a SequenceOfValue
- %% The ObjectList may be a list of references to
- %% objects, a ValueFromObject
- ?dbg("objectsetfield: ~p~n",[CField]),
- get_objectset_def2(S,ObjectList,CField);
-get_objectset_def(S,'EXTENSIONMARK',CField) ->
- ?dbg("objectsetfield: ~p~n",[CField]),
- get_objectset_def2(S,['EXTENSIONMARK'],CField);
-get_objectset_def(_S,ObjFieldSetting={'SingleValue',_},CField) ->
- %% a Union of defined objects
- ?dbg("objectsetfield, SingleValue~n",[]),
- union_of_defed_objs(CField,ObjFieldSetting);
-get_objectset_def(_S,ObjFieldSetting={{'SingleValue',_},_},CField) ->
- %% a Union of defined objects
- ?dbg("objectsetfield, SingleValue~n",[]),
- union_of_defed_objs(CField,ObjFieldSetting);
-get_objectset_def(S,{object,_,[#type{def={'TypeFromObject',
- {object,RefedObj},
- FieldName}}]},_CField) ->
- %% This case occurs when an ObjectSetFromObjects
- %% production is used
- {_M,Def} = get_referenced_type(S,RefedObj),
- get_fieldname_element(S,Def,FieldName);
-get_objectset_def(S,{object,_,[{setting,_,ERef}]},CField)
- when is_record(ERef,'Externaltypereference') ->
- {_,T} = get_referenced_type(S,ERef),
- get_objectset_def2(S,T,CField);
-get_objectset_def(S,#type{def=ERef},_CField)
- when is_record(ERef,'Externaltypereference') ->
- {_,T} = get_referenced_type(S,ERef),
- T;
-get_objectset_def(S,ObjFieldSetting,CField)
- when is_atom(ObjFieldSetting) ->
- ERef = #'Externaltypereference'{module=S#state.mname,
- type=ObjFieldSetting},
- {_,T} = get_referenced_type(S,ERef),
- get_objectset_def2(S,T,CField).
-
-get_objectset_def2(_S,T = #typedef{typespec=#'Object'{}},_CField) ->
- #typedef{typespec=#'Object'{classname=Class,def=Def}} = T,
- T#typedef{typespec=#'ObjectSet'{class=Class,set=[Def]}};
-get_objectset_def2(_S,Set,CField) when is_list(Set) ->
- {_,_,Type,_} = CField,
- ClassDef = Type#type.def,
- #typedef{typespec=#'ObjectSet'{class=ClassDef,
- set=Set}};
-get_objectset_def2(_S,T = #typedef{typespec=#'ObjectSet'{}},_CField) ->
- T;
-get_objectset_def2(S,T,_CField) ->
- asn1ct:warning("get_objectset_def2: uncontrolled object set structure:~n~p~n",
- [T],S,"get_objectset_def2: uncontrolled object set structure").
-
-type_name(S,#type{def=Def}) ->
- CurrMod = S#state.mname,
- case asn1ct_gen:type(asn1ct_gen:get_inner(Def)) of
- #'Externaltypereference'{module=CurrMod,type=Name} ->
- Name;
- #'Externaltypereference'{module=Mod,type=Name} ->
- {Mod,Name};
- Bif when Bif=={primitive,bif};Bif=={constructed,bif} ->
- Bif
- end.
+is_mandatory_class_field({fixedtypevaluefield,_,_,_,'MANDATORY'}) ->
+ true;
+is_mandatory_class_field({objectfield,_,_,_,'MANDATORY'}) ->
+ true;
+is_mandatory_class_field({objectsetfield,_,_,'MANDATORY'}) ->
+ true;
+is_mandatory_class_field({typefield,_,'MANDATORY'}) ->
+ true;
+is_mandatory_class_field({variabletypevaluefield,_,_,'MANDATORY'}) ->
+ true;
+is_mandatory_class_field({variabletypevaluesetfield,_,_,'MANDATORY'}) ->
+ true;
+is_mandatory_class_field(_) ->
+ false.
merged_name(#state{inputmodules=[]},ERef) ->
ERef;
@@ -2013,38 +1652,18 @@ merged_name(S,ERef=#'Externaltypereference'{module=M}) ->
ERef
end.
-oCFT_def(S,T) ->
- case get_OCFT_inner(S,T) of
- ERef=#'Externaltypereference'{} -> ERef;
- {Name,Type} -> #typedef{checked=true,name=Name,typespec=Type};
- 'ASN1_OPEN_TYPE' ->
- #typedef{checked=true,typespec=T#type{def='ASN1_OPEN_TYPE'}}
- end.
-
-get_OCFT_inner(_S,T) ->
-% Module=S#state.mname,
- Def = T#type.def,
- case Def#'ObjectClassFieldType'.type of
+ocft_def(#type{def=#'ObjectClassFieldType'{type=OCFT}}=T) ->
+ case OCFT of
{fixedtypevaluefield,_,InnerType} ->
case asn1ct_gen:type(asn1ct_gen:get_inner(InnerType#type.def)) of
- Bif when Bif=={primitive,bif};Bif=={constructed,bif} ->
- {Bif,InnerType};
- ERef = #'Externaltypereference'{} ->
- ERef
+ Bif when Bif =:= {primitive,bif}; Bif =:= {constructed,bif} ->
+ #typedef{checked=true,name=Bif,typespec=InnerType};
+ #'Externaltypereference'{}=Ref ->
+ Ref
end;
- 'ASN1_OPEN_TYPE' -> 'ASN1_OPEN_TYPE'
+ 'ASN1_OPEN_TYPE' ->
+ #typedef{checked=true,typespec=T#type{def='ASN1_OPEN_TYPE'}}
end.
-
-
-
-union_of_defed_objs({_,_,_ObjClass=#type{def=ClassDef},_},ObjFieldSetting) ->
- #typedef{typespec=#'ObjectSet'{class = ClassDef,
- set = ObjFieldSetting}};
-union_of_defed_objs({_,_,DefObjClassRef,_},ObjFieldSetting)
- when is_record(DefObjClassRef,'Externaltypereference') ->
- #typedef{typespec=#'ObjectSet'{class = DefObjClassRef,
- set = ObjFieldSetting}}.
-
check_value(OldS,V) when is_record(V,pvaluesetdef) ->
#pvaluesetdef{checked=Checked,type=Type} = V,
@@ -2068,8 +1687,7 @@ check_value(OldS,V) when is_record(V,typedef) ->
#typedef{typespec=TS} = V,
case TS of
#'ObjectSet'{class=ClassRef} ->
- {RefM,TSDef} = get_referenced_type(OldS,ClassRef),
- %%IsObjectSet(TSDef);
+ {_RefM,TSDef} = get_referenced_type(OldS, ClassRef),
case TSDef of
#classdef{} -> throw({objectsetdef});
#typedef{typespec=#type{def=Eref}} when
@@ -2077,14 +1695,12 @@ check_value(OldS,V) when is_record(V,typedef) ->
%% This case if the class reference is a defined
%% reference to class
check_value(OldS,V#typedef{typespec=TS#'ObjectSet'{class=Eref}});
- #typedef{} ->
+ #typedef{typespec=HostType} ->
% an ordinary value set with a type in #typedef.typespec
- ValueSet = TS#'ObjectSet'.set,
- Type=check_type(OldS,TSDef,TSDef#typedef.typespec),
- Value = check_value(OldS,#valuedef{type=Type,
- value=ValueSet,
- module=RefM}),
- {valueset,Type#type{constraint=Value#valuedef.value}}
+ ValueSet0 = TS#'ObjectSet'.set,
+ Constr = check_constraints(OldS, HostType, [ValueSet0]),
+ Type = check_type(OldS,TSDef,TSDef#typedef.typespec),
+ {valueset,Type#type{constraint=Constr}}
end;
_ ->
throw({objectsetdef})
@@ -2104,11 +1720,11 @@ check_value(S, #valuedef{}=V) ->
end.
check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
- #valuedef{name=Name,type=Vtype,value=Value,module=ModName} = V0,
+ #valuedef{name=Name,type=Vtype0,value=Value,module=ModName} = V0,
V = V0#valuedef{checked=true},
+ Vtype = check_type(S0, #typedef{name=Name,typespec=Vtype0},Vtype0),
Def = Vtype#type.def,
- Constr = Vtype#type.constraint,
- S1 = S0#state{type=Vtype,tname=Def,value=V0,vname=Name},
+ S1 = S0#state{tname=Def},
SVal = update_state(S1, ModName),
case Def of
#'Externaltypereference'{type=RecName}=Ext ->
@@ -2116,9 +1732,8 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
%% If V isn't a value but an object Type is a #classdef{}
S2 = update_state(S1, RefM),
case Type of
- #classdef{} ->
- throw({objectdef});
- #typedef{typespec=TypeSpec} ->
+ #typedef{typespec=TypeSpec0}=TypeDef ->
+ TypeSpec = check_type(S2, TypeDef, TypeSpec0),
S3 = case is_contextswitchtype(Type) of
true ->
S2;
@@ -2135,7 +1750,7 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
V#valuedef{type=Type}),
V#valuedef{value=CheckedVal}
end;
- 'ANY' ->
+ 'ASN1_OPEN_TYPE' ->
{opentypefieldvalue,ANYType,ANYValue} = Value,
CheckedV = check_value(SVal,#valuedef{name=Name,
type=ANYType,
@@ -2143,19 +1758,12 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
module=ModName}),
V#valuedef{value=CheckedV#valuedef.value};
'INTEGER' ->
- ok = validate_integer(SVal, Value, [], Constr),
V#valuedef{value=normalize_value(SVal, Vtype, Value, [])};
- {'INTEGER',NamedNumberList} ->
- ok = validate_integer(SVal, Value, NamedNumberList, Constr),
+ {'INTEGER',_NamedNumberList} ->
V#valuedef{value=normalize_value(SVal, Vtype, Value, [])};
#'SEQUENCE'{} ->
- {ok,SeqVal} = convert_external(SVal, Value),
+ {ok,SeqVal} = convert_external(SVal, Vtype, Value),
V#valuedef{value=normalize_value(SVal, Vtype, SeqVal, TopName)};
- {'SelectionType',SelName,SelT} ->
- CheckedT = check_selectiontype(SVal, SelName, SelT),
- NewV = V#valuedef{type=CheckedT},
- SelVDef = check_value(S1#state{value=NewV}, NewV),
- V#valuedef{value=SelVDef#valuedef.value};
_ ->
V#valuedef{value=normalize_value(SVal, Vtype, Value, TopName)}
end.
@@ -2169,179 +1777,97 @@ is_contextswitchtype(#typedef{name='CHARACTER STRING'}) ->
is_contextswitchtype(_) ->
false.
-% validate_integer(S,{identifier,Pos,Id},NamedNumberList,Constr) ->
-% case lists:keysearch(Id,1,NamedNumberList) of
-% {value,_} -> ok;
-% false -> error({value,"unknown NamedNumber",S})
-% end;
-%% This case occurs when there is a valuereference
-%% validate_integer(S=#state{mname=M},
-%% #'Externalvaluereference'{module=M,value=Id}=Ref,
-validate_integer(S,#'Externalvaluereference'{value=Id}=Ref,
- NamedNumberList,Constr) ->
- case lists:keysearch(Id,1,NamedNumberList) of
- {value,_} -> ok;
- false -> validate_integer_ref(S,Ref,NamedNumberList,Constr)
- %%error({value,"unknown NamedNumber",S})
- end;
-validate_integer(S,Id,NamedNumberList,Constr) when is_atom(Id) ->
- case lists:keysearch(Id,1,NamedNumberList) of
- {value,_} -> ok;
- false -> validate_integer_ref(S,Id,NamedNumberList,Constr)
- %error({value,"unknown NamedNumber",S})
+%%%
+%%% Start of OBJECT IDENTFIER/RELATIVE-OID validation.
+%%%
+
+validate_objectidentifier(S, OidType, #'Externalvaluereference'{}=Id) ->
+ %% Must be an OBJECT IDENTIFIER or RELATIVE-OID depending on OidType.
+ get_oid_value(S, OidType, false, Id);
+validate_objectidentifier(S, OidType, {'ValueFromObject',{object,Obj},Fields}) ->
+ %% Must be an OBJECT IDENTIFIER/RELATIVE-OID depending on OidType.
+ case extract_field(S, Obj, Fields) of
+ #valuedef{checked=true,value=Value,type=Type} when is_tuple(Value) ->
+ _ = get_oid_type(S, OidType, Type),
+ Value;
+ _ ->
+ asn1_error(S, {illegal_oid,OidType})
end;
-validate_integer(_S,Value,_NamedNumberList,Constr) when is_integer(Value) ->
- check_integer_range(Value,Constr).
-
-validate_integer_ref(S,Id,_,_) when is_atom(Id) ->
- error({value,"unknown integer referens",S});
-validate_integer_ref(S,Ref,NamedNumberList,Constr) ->
- case get_referenced_type(S,Ref) of
- {M,V} when is_record(V,valuedef) ->
- NewS = update_state(S,M),
- case check_value(NewS,V) of
- #valuedef{type=#type{def='INTEGER'},value=Value} ->
- validate_integer(NewS,Value,NamedNumberList,Constr);
- _Err -> error({value,"unknown integer referens",S})
+validate_objectidentifier(S, OidType,
+ [{#seqtag{module=Mod,pos=Pos,val=Atom},Val}]) ->
+ %% This case is when an OBJECT IDENTIFIER value has been parsed as a
+ %% SEQUENCE value.
+ Rec = #'Externalvaluereference'{pos=Pos,
+ module=Mod,
+ value=Atom},
+ validate_oid(S, OidType, [Rec,Val], []);
+validate_objectidentifier(S, OidType, [_|_]=L0) ->
+ validate_oid(S, OidType, L0, []);
+validate_objectidentifier(S, OidType, _) ->
+ asn1_error(S, {illegal_oid,OidType}).
+
+get_oid_value(S, OidType, AllowInteger, #'Externalvaluereference'{}=Id) ->
+ case get_referenced_type(S, Id) of
+ {_,#valuedef{checked=Checked,type=Type,value=V}} ->
+ case get_oid_type(S, OidType, Type) of
+ 'INTEGER' when not AllowInteger ->
+ asn1_error(S, {illegal_oid,OidType});
+ _ when Checked ->
+ V;
+ 'INTEGER' ->
+ V;
+ _ ->
+ validate_objectidentifier(S, OidType, V)
end;
_ ->
- error({value,"unknown integer referens",S})
+ asn1_error(S, {illegal_oid,OidType})
end.
-
-
-
-check_integer_range(_Int, Constr) when is_list(Constr) ->
- ok.
-%%------------
-%% This can be removed when the old parser is removed
-%% The function removes 'space' atoms from the list
-
-is_space_list([H],Acc) ->
- lists:reverse([H|Acc]);
-is_space_list([H,space|T],Acc) ->
- is_space_list(T,[H|Acc]);
-is_space_list([],Acc) ->
- lists:reverse(Acc);
-is_space_list([H|T],Acc) ->
- is_space_list(T,[H|Acc]).
-
-validate_objectidentifier(S,OID,ERef,C)
- when is_record(ERef,'Externalvaluereference') ->
- validate_objectidentifier(S,OID,[ERef],C);
-validate_objectidentifier(S,OID,Tup,C) when is_tuple(Tup) ->
- validate_objectidentifier(S,OID,tuple_to_list(Tup),C);
-validate_objectidentifier(S,OID,L,_) ->
- NewL = is_space_list(L,[]),
- case validate_objectidentifier1(S,OID,NewL) of
- NewL2 when is_list(NewL2) ->{ok,list_to_tuple(NewL2)};
- Other -> {ok,Other}
- end.
-
-validate_objectidentifier1(S, OID, [Id|T])
- when is_record(Id,'Externalvaluereference') ->
- case catch get_referenced_type(S,Id) of
- {M,V} when is_record(V,valuedef) ->
- NewS = update_state(S,M),
- case check_value(NewS,V) of
- #valuedef{type=#type{def=ERef},checked=true,
- value=Value} when is_tuple(Value) ->
- case is_object_id(OID,NewS,ERef) of
- true ->
- %% T must be a RELATIVE-OID
- validate_oid(true,NewS, rel_oid, T, lists:reverse(tuple_to_list(Value)));
- _ ->
- error({value, {"illegal "++to_string(OID),[Id|T]}, S})
- end;
- _ ->
- error({value, {"illegal "++to_string(OID),[Id|T]}, S})
- end;
- _ ->
- validate_oid(true,S, OID, [Id|T], [])
- end;
-validate_objectidentifier1(S,OID,V) ->
- validate_oid(true,S,OID,V,[]).
-
-validate_oid(false, S, OID, V, Acc) ->
- error({value, {"illegal "++to_string(OID), V,Acc}, S});
-validate_oid(_,_, _, [], Acc) ->
- lists:reverse(Acc);
-validate_oid(_, S, OID, [Value|Vrest], Acc) when is_integer(Value) ->
- validate_oid(valid_objectid(OID,Value,Acc),S, OID, Vrest, [Value|Acc]);
-validate_oid(_, S, OID, [{'NamedNumber',_Name,Value}|Vrest], Acc)
+validate_oid(S, OidType, [], Acc) ->
+ Oid = lists:reverse(Acc),
+ validate_oid_path(S, OidType, Oid),
+ list_to_tuple(Oid);
+validate_oid(S, OidType, [Value|Vrest], Acc) when is_integer(Value) ->
+ validate_oid(S, OidType, Vrest, [Value|Acc]);
+validate_oid(S, OidType, [{'NamedNumber',_Name,Value}|Vrest], Acc)
when is_integer(Value) ->
- validate_oid(valid_objectid(OID,Value,Acc), S, OID, Vrest, [Value|Acc]);
-validate_oid(_, S, OID, [Id|Vrest], Acc)
- when is_record(Id,'Externalvaluereference') ->
- case catch get_referenced_type(S, Id) of
- {M,V} when is_record(V,valuedef) ->
- NewS = update_state(S,M),
- NewVal = case check_value(NewS, V) of
- #valuedef{checked=true,value=Value} ->
- fun(Int) when is_integer(Int) -> [Int];
- (L) when is_list(L) -> L;
- (T) when is_tuple(T) -> tuple_to_list(T)
- end (Value);
- _ ->
- error({value, {"illegal "++to_string(OID),
- [Id|Vrest],Acc}, S})
- end,
- case NewVal of
- List when is_list(List) ->
- validate_oid(valid_objectid(OID,NewVal,Acc), NewS,
- OID, Vrest,lists:reverse(NewVal)++Acc);
- _ ->
- NewVal
- end;
- _ ->
+ validate_oid(S, OidType, Vrest, [Value|Acc]);
+validate_oid(S, OidType, [#'Externalvaluereference'{}=Id|Vrest], Acc) ->
+ NeededOidType = case Acc of
+ [] -> o_id;
+ [_|_] -> rel_oid
+ end,
+ try get_oid_value(S, NeededOidType, true, Id) of
+ Val when is_integer(Val) ->
+ validate_oid(S, OidType, Vrest, [Val|Acc]);
+ Val when is_tuple(Val) ->
+ L = tuple_to_list(Val),
+ validate_oid(S, OidType, Vrest, lists:reverse(L, Acc))
+ catch
+ _:_ ->
case reserved_objectid(Id#'Externalvaluereference'.value, Acc) of
Value when is_integer(Value) ->
- validate_oid(valid_objectid(OID,Value,Acc),
- S, OID,Vrest, [Value|Acc]);
+ validate_oid(S, OidType,Vrest, [Value|Acc]);
false ->
- error({value, {"illegal "++to_string(OID),[Id,Vrest],Acc}, S})
+ asn1_error(S, {illegal_oid,OidType})
end
end;
-validate_oid(_, S, OID, [{#seqtag{module=Mod,val=Atom},Value}], [])
- when is_atom(Atom),is_integer(Value) ->
- %% this case when an OBJECT IDENTIFIER value has been parsed as a
- %% SEQUENCE value
- Rec = #'Externalvaluereference'{module=Mod,
- value=Atom},
- validate_objectidentifier1(S, OID, [Rec,Value]);
-validate_oid(_, S, OID, [{#seqtag{module=Mod,val=Atom},EVRef}], [])
- when is_atom(Atom),is_record(EVRef,'Externalvaluereference') ->
- %% this case when an OBJECT IDENTIFIER value has been parsed as a
- %% SEQUENCE value OTP-4354
- Rec = #'Externalvaluereference'{module=Mod,
- value=Atom},
- validate_objectidentifier1(S, OID, [Rec,EVRef]);
-validate_oid(_, S, OID, [#seqtag{module=Mod,val=Atom}|Rest], Acc)
- when is_atom(Atom) ->
- Rec = #'Externalvaluereference'{module=Mod,
- value=Atom},
- validate_oid(true,S, OID, [Rec|Rest],Acc);
-validate_oid(_, S, OID, V, Acc) ->
- error({value, {"illegal "++to_string(OID),V,Acc},S}).
-
-is_object_id(OID,S,ERef=#'Externaltypereference'{}) ->
- {_,OI} = get_referenced_type(S,ERef),
- is_object_id(OID,S,OI#typedef.typespec);
-is_object_id(o_id,_S,'OBJECT IDENTIFIER') ->
- true;
-is_object_id(rel_oid,_S,'RELATIVE-OID') ->
- true;
-is_object_id(_,_S,'INTEGER') ->
- true;
-is_object_id(OID,S,#type{def=Def}) ->
- is_object_id(OID,S,Def);
-is_object_id(_,_S,_) ->
- false.
-
-to_string(o_id) ->
- "OBJECT IDENTIFIER";
-to_string(rel_oid) ->
- "RELATIVE-OID".
+validate_oid(S, OidType, _V, _Acc) ->
+ asn1_error(S, {illegal_oid,OidType}).
+
+get_oid_type(S, OidType, #type{def=Def}) ->
+ get_oid_type(S, OidType, Def);
+get_oid_type(S, OidType, #'Externaltypereference'{}=Id) ->
+ {_,OI} = get_referenced_type(S, Id),
+ get_oid_type(S, OidType, OI#typedef.typespec);
+get_oid_type(_S, o_id, 'OBJECT IDENTIFIER'=T) ->
+ T;
+get_oid_type(_S, rel_oid, 'RELATIVE-OID'=T) ->
+ T;
+get_oid_type(_S, _, 'INTEGER'=T) ->
+ T;
+get_oid_type(S, OidType, _) ->
+ asn1_error(S, {illegal_oid,OidType}).
%% ITU-T Rec. X.680 Annex B - D
reserved_objectid('itu-t',[]) -> 0;
@@ -2380,7 +1906,6 @@ reserved_objectid('x',[0,0]) -> 24;
reserved_objectid('y',[0,0]) -> 25;
reserved_objectid('z',[0,0]) -> 26;
-
reserved_objectid(iso,[]) -> 1;
%% arcs below "iso", note that number 1 is not used
reserved_objectid('standard',[1]) -> 0;
@@ -2392,25 +1917,22 @@ reserved_objectid('joint-iso-ccitt',[]) -> 2;
reserved_objectid(_,_) -> false.
-valid_objectid(_OID,[],_Acc) ->
- true;
-valid_objectid(OID,[H|T],Acc) ->
- case valid_objectid(OID, H, Acc) of
- true ->
- valid_objectid(OID,T,[H|Acc]);
- _ ->
- false
- end;
-valid_objectid(o_id,I,[]) when I =:= 0; I =:= 1; I =:= 2 -> true;
-valid_objectid(o_id,_I,[]) -> false;
-valid_objectid(o_id,I,[0]) when I >= 0; I =< 4 -> true;
-valid_objectid(o_id,_I,[0]) -> false;
-valid_objectid(o_id,I,[1]) when I =:= 0; I =:= 2; I =:= 3 -> true;
-valid_objectid(o_id,_I,[1]) -> false;
-valid_objectid(o_id,_I,[2]) -> true;
-valid_objectid(_,_,_) -> true.
-
-convert_external(S=#state{type=Vtype}, Value) ->
+validate_oid_path(_, rel_oid, _) ->
+ ok;
+validate_oid_path(_, o_id, [0,I|_]) when 0 =< I, I =< 9 ->
+ ok;
+validate_oid_path(_, o_id, [1,I|_]) when 0 =< I, I =< 3 ->
+ ok;
+validate_oid_path(_, o_id, [2|_]) ->
+ ok;
+validate_oid_path(S, o_id=OidType, _) ->
+ asn1_error(S, {illegal_oid,OidType}).
+
+%%%
+%%% End of OBJECT IDENTFIER/RELATIVE-OID validation.
+%%%
+
+convert_external(S, Vtype, Value) ->
case Vtype of
#type{tag=[{tag,'UNIVERSAL',8,'IMPLICIT',32}]} ->
%% this is an 'EXTERNAL' (or INSTANCE OF)
@@ -2435,7 +1957,7 @@ to_EXTERNAL1990(S, [{#seqtag{val=identification}=T,
to_EXTERNAL1990(S, Rest, [{T#seqtag{val='indirect-reference'},PCid},
{T#seqtag{val='direct-reference'},TrStx}]);
to_EXTERNAL1990(S, _) ->
- error({value,"illegal value in EXTERNAL type",S}).
+ asn1_error(S, illegal_external_value).
to_EXTERNAL1990(S, [V={#seqtag{val='data-value-descriptor'},_}|Rest], Acc) ->
to_EXTERNAL1990(S, Rest, [V|Acc]);
@@ -2443,7 +1965,7 @@ to_EXTERNAL1990(_S, [{#seqtag{val='data-value'}=T,Val}], Acc) ->
Encoding = {T#seqtag{val=encoding},{'CHOICE',{'octet-aligned',Val}}},
lists:reverse([Encoding|Acc]);
to_EXTERNAL1990(S, _, _) ->
- error({value,"illegal value in EXTERNAL type",S}).
+ asn1_error(S, illegal_external_value).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Functions to normalize the default values of SEQUENCE
@@ -2453,17 +1975,16 @@ normalize_value(_,_,mandatory,_) ->
mandatory;
normalize_value(_,_,'OPTIONAL',_) ->
'OPTIONAL';
-normalize_value(S0, Type, {'DEFAULT',Value}, NameList) ->
- S = S0#state{value=Value},
+normalize_value(S, Type, {'DEFAULT',Value}, NameList) ->
case catch get_canonic_type(S,Type,NameList) of
{'BOOLEAN',CType,_} ->
normalize_boolean(S,Value,CType);
{'INTEGER',CType,_} ->
- normalize_integer(S,Value,CType);
+ normalize_integer(S, Value, CType);
{'BIT STRING',CType,_} ->
normalize_bitstring(S,Value,CType);
- {'OCTET STRING',CType,_} ->
- normalize_octetstring(S0, Value, CType);
+ {'OCTET STRING',_,_} ->
+ normalize_octetstring(S, Value);
{'NULL',_CType,_} ->
%%normalize_null(Value);
'NULL';
@@ -2499,39 +2020,41 @@ normalize_value(S0, Type, {'DEFAULT',Value}, NameList) ->
normalize_value(S,Type,Val,NameList) ->
normalize_value(S,Type,{'DEFAULT',Val},NameList).
-normalize_boolean(S,{Name,Bool},CType) when is_atom(Name) ->
- normalize_boolean(S,Bool,CType);
normalize_boolean(_,true,_) ->
true;
normalize_boolean(_,false,_) ->
false;
normalize_boolean(S,Bool=#'Externalvaluereference'{},CType) ->
get_normalized_value(S,Bool,CType,fun normalize_boolean/3,[]);
-normalize_boolean(_,Other,_) ->
- throw({error,{asn1,{'invalid default value',Other}}}).
+normalize_boolean(S, _, _) ->
+ asn1_error(S, {illegal_value, "BOOLEAN"}).
-normalize_integer(_S,Int,_) when is_integer(Int) ->
+normalize_integer(_S, Int, _) when is_integer(Int) ->
Int;
-normalize_integer(_S,{Name,Int},_) when is_atom(Name),is_integer(Int) ->
- Int;
-normalize_integer(S,{Name,Int=#'Externalvaluereference'{}},
- Type) when is_atom(Name) ->
- normalize_integer(S,Int,Type);
-normalize_integer(S,Int=#'Externalvaluereference'{value=Name},Type) ->
- case Type of
- NNL when is_list(NNL) ->
- case lists:keysearch(Name,1,NNL) of
- {value,{Name,Val}} ->
+normalize_integer(S, #'Externalvaluereference'{value=Name}=Ref, NNL) ->
+ case lists:keyfind(Name, 1, NNL) of
+ {Name,Val} ->
+ Val;
+ false ->
+ try get_referenced_value(S, Ref) of
+ Val when is_integer(Val) ->
Val;
- false ->
- get_normalized_value(S,Int,Type,
- fun normalize_integer/3,[])
- end;
+ _ ->
+ asn1_error(S, illegal_integer_value)
+ catch
+ throw:_ ->
+ asn1_error(S, illegal_integer_value)
+ end
+ end;
+normalize_integer(S, {'ValueFromObject',{object,Obj},FieldNames}, _) ->
+ case extract_field(S, Obj, FieldNames) of
+ #valuedef{value=Val} when is_integer(Val) ->
+ Val;
_ ->
- get_normalized_value(S,Int,Type,fun normalize_integer/3,[])
+ asn1_error(S, illegal_integer_value)
end;
-normalize_integer(_,Int,_) ->
- exit({'Unknown INTEGER value',Int}).
+normalize_integer(S, _, _) ->
+ asn1_error(S, illegal_integer_value).
%% normalize_bitstring(S, Value, Type) -> bitstring()
%% Convert a literal value for a BIT STRING to an Erlang bit string.
@@ -2543,36 +2066,34 @@ normalize_bitstring(S, Value, Type)->
{bstring,String} when is_list(String) ->
bstring_to_bitstring(String);
#'Externalvaluereference'{} ->
- get_normalized_value(S, Value, Type,
- fun normalize_bitstring/3, []);
- RecList when is_list(RecList) ->
- F = fun(#'Externalvaluereference'{value=Name}) ->
- case lists:keymember(Name, 1, Type) of
- true -> Name;
- false -> throw({error,false})
- end;
- (Name) when is_atom(Name) ->
- %% Already normalized.
- Name;
- (Other) ->
- throw({error,Other})
- end,
- try
- lists:map(F, RecList)
- catch
- throw:{error,Reason} ->
- asn1ct:warning("default value not "
- "compatible with type definition ~p~n",
- [Reason],S,
- "default value not "
- "compatible with type definition"),
- Value
+ Val = get_referenced_value(S, Value),
+ normalize_bitstring(S, Val, Type);
+ {'ValueFromObject',{object,Obj},FieldNames} ->
+ case extract_field(S, Obj, FieldNames) of
+ #valuedef{value=Val} ->
+ normalize_bitstring(S, Val, Type);
+ _ ->
+ asn1_error(S, {illegal_value, "BIT STRING"})
end;
+ RecList when is_list(RecList) ->
+ [normalize_bs_item(S, Item, Type) || Item <- RecList];
Bs when is_bitstring(Bs) ->
%% Already normalized.
- Bs
+ Bs;
+ _ ->
+ asn1_error(S, {illegal_value, "BIT STRING"})
end.
+normalize_bs_item(S, #'Externalvaluereference'{value=Name}, Type) ->
+ case lists:keymember(Name, 1, Type) of
+ true -> Name;
+ false -> asn1_error(S, {illegal_value, "BIT STRING"})
+ end;
+normalize_bs_item(_, Atom, _) when is_atom(Atom) ->
+ Atom;
+normalize_bs_item(S, _, _) ->
+ asn1_error(S, {illegal_value, "BIT STRING"}).
+
hstring_to_binary(L) ->
byte_align(hstring_to_bitstring(L)).
@@ -2600,29 +2121,35 @@ hex_to_int(D) when $A =< D, D =< $F -> D - ($A - 10).
%% {bstring,String} each element in String corresponds to one bit in an octet
%% {hstring,String} each element in String corresponds to one byte in an octet
%% #'Externalvaluereference'
-normalize_octetstring(S,Value,CType) ->
+normalize_octetstring(S, Value) ->
case Value of
{bstring,String} ->
bstring_to_binary(String);
{hstring,String} ->
hstring_to_binary(String);
- Rec when is_record(Rec,'Externalvaluereference') ->
- get_normalized_value(S,Value,CType,
- fun normalize_octetstring/3,[]);
- {Name,String} when is_atom(Name) ->
- normalize_octetstring(S,String,CType);
+ #'Externalvaluereference'{} ->
+ case get_referenced_value(S, Value) of
+ String when is_binary(String) ->
+ String;
+ Other ->
+ normalize_octetstring(S, Other)
+ end;
+ {'ValueFromObject',{object,Obj},FieldNames} ->
+ case extract_field(S, Obj, FieldNames) of
+ #valuedef{value=Val} when is_binary(Val) ->
+ Val;
+ _ ->
+ asn1_error(S, illegal_octet_string_value)
+ end;
_ ->
- Item = S#state.value,
- asn1_error(S, Item, illegal_octet_string_value)
+ asn1_error(S, illegal_octet_string_value)
end.
normalize_objectidentifier(S, Value) ->
- {ok,Val} = validate_objectidentifier(S, o_id, Value, []),
- Val.
+ validate_objectidentifier(S, o_id, Value).
-normalize_relative_oid(S,Value) ->
- {ok,Val} = validate_objectidentifier(S, rel_oid, Value, []),
- Val.
+normalize_relative_oid(S, Value) ->
+ validate_objectidentifier(S, rel_oid, Value).
normalize_objectdescriptor(Value) ->
Value.
@@ -2644,40 +2171,22 @@ lookup_enum_value(S, Id, NNL) when is_atom(Id) ->
{_,_}=Ret ->
Ret;
false ->
- asn1_error(S, S#state.value, {undefined,Id})
+ asn1_error(S, {undefined,Id})
end.
-normalize_choice(S,{'CHOICE',{C,V}},CType,NameList) when is_atom(C) ->
- case catch lists:keysearch(C,#'ComponentType'.name,CType) of
- {value,#'ComponentType'{typespec=CT,name=Name}} ->
- {C,normalize_value(S,CT,{'DEFAULT',V},
- [Name|NameList])};
- Other ->
- asn1ct:warning("Wrong format of type/value ~p/~p~n",[Other,V],S,
- "Wrong format of type/value"),
- {C,V}
+normalize_choice(S, {'CHOICE',{C,V}}, CType, NameList)
+ when is_atom(C) ->
+ case lists:keyfind(C, #'ComponentType'.name, CType) of
+ #'ComponentType'{typespec=CT,name=Name} ->
+ {C,normalize_value(S, CT, {'DEFAULT',V}, [Name|NameList])};
+ false ->
+ asn1_error(S, {illegal_id,C})
end;
-normalize_choice(S,{'DEFAULT',ValueList},CType,NameList) when is_list(ValueList) ->
- lists:map(fun(X)-> normalize_choice(S,X,CType,NameList) end, ValueList);
-normalize_choice(S,Val=#'Externalvaluereference'{},CType,NameList) ->
- {M,#valuedef{value=V}}=get_referenced_type(S,Val),
- normalize_choice(update_state(S,M),{'CHOICE',V},CType,NameList);
-% get_normalized_value(S,Val,CType,fun normalize_choice/4,[NameList]);
-normalize_choice(S,CV={Name,_ChoiceVal},CType,NameList)
+normalize_choice(S,CV={Name,_ChoiceVal},CType,NameList)
when is_atom(Name) ->
-% normalize_choice(S,ChoiceVal,CType,NameList).
normalize_choice(S,{'CHOICE',CV},CType,NameList);
-normalize_choice(_S,V,_CType,_NameList) ->
- exit({error,{bad_choice_value,V}}).
-
-%% normalize_choice(NameList,S,CVal = {'CHOICE',{_,_}},CType,_) ->
-%% normalize_choice(S,CVal,CType,NameList);
-%% normalize_choice(NameList,S,CVal={'DEFAULT',VL},CType,_) when is_list(VL)->
-%% normalize_choice(S,CVal,CType,NameList);
-%% normalize_choice(NameList,S,CV={Name,_CV},CType,_) when is_atom(Name)->
-%% normalize_choice(S,{'CHOICE',CV},CType,NameList);
-%% normalize_choice(_,_S,V,_,_) ->
-%% V.
+normalize_choice(S, V, _CType, _NameList) ->
+ asn1_error(S, {illegal_id, error_value(V)}).
normalize_sequence(S,Value,Components,NameList)
when is_tuple(Components) ->
@@ -2732,12 +2241,9 @@ normalized_record(SorS,S,Value,Components,NameList) ->
Value;
_ ->
NoComps = length(Components),
- case normalize_seq_or_set(SorS,S,Value,Components,NameList,[]) of
- ListOfVals when length(ListOfVals) == NoComps ->
- list_to_tuple([NewName|ListOfVals]);
- _ ->
- error({type,{illegal,default,value,Value},S})
- end
+ ListOfVals = normalize_seq_or_set(SorS,S,Value,Components,NameList,[]),
+ NoComps = length(ListOfVals), %% Assert
+ list_to_tuple([NewName|ListOfVals])
end.
is_record_normalized(S,Name,V = #'Externalvaluereference'{},NumComps) ->
case get_referenced_type(S,V) of
@@ -2750,10 +2256,11 @@ is_record_normalized(_S,Name,Value,NumComps) when is_tuple(Value) ->
is_record_normalized(_,_,_,_) ->
false.
-normalize_seq_or_set(SorS, S, [{#seqtag{val=Cname},V}|Vs],
+normalize_seq_or_set(SorS, S,
+ [{#seqtag{val=Cname},V}|Vs],
[#'ComponentType'{name=Cname,typespec=TS}|Cs],
NameList, Acc) ->
- NewNameList =
+ NewNameList =
case TS#type.def of
#'Externaltypereference'{type=TName} ->
[TName];
@@ -2761,24 +2268,26 @@ normalize_seq_or_set(SorS, S, [{#seqtag{val=Cname},V}|Vs],
end,
NVal = normalize_value(S,TS,{'DEFAULT',V},NewNameList),
normalize_seq_or_set(SorS,S,Vs,Cs,NameList,[NVal|Acc]);
-normalize_seq_or_set(SorS,S,Values=[{_Cname1,_V}|_Vs],
+normalize_seq_or_set(SorS, S,
+ Values=[{#seqtag{val=Cname0},_V}|_Vs],
[#'ComponentType'{prop='OPTIONAL'}|Cs],
- NameList,Acc) ->
+ NameList, Acc) ->
+ verify_valid_component(S, Cname0, Cs),
normalize_seq_or_set(SorS,S,Values,Cs,NameList,[asn1_NOVALUE|Acc]);
-normalize_seq_or_set(SorS,S,Values=[{_Cname1,_V}|_Vs],
- [#'ComponentType'{name=Cname2,typespec=TS,
- prop={'DEFAULT',Value}}|Cs],
- NameList,Acc) ->
- NewNameList =
+normalize_seq_or_set(SorS, S,
+ Values=[{#seqtag{val=Cname0},_V}|_Vs],
+ [#'ComponentType'{name=Cname,typespec=TS,
+ prop={'DEFAULT',Value}}|Cs],
+ NameList, Acc) ->
+ verify_valid_component(S, Cname0, Cs),
+ NewNameList =
case TS#type.def of
#'Externaltypereference'{type=TName} ->
[TName];
- _ -> [Cname2|NameList]
+ _ -> [Cname|NameList]
end,
NVal = normalize_value(S,TS,{'DEFAULT',Value},NewNameList),
normalize_seq_or_set(SorS,S,Values,Cs,NameList,[NVal|Acc]);
-normalize_seq_or_set(_SorS,_S,[],[],_,Acc) ->
- lists:reverse(Acc);
%% If default value is {} ComponentTypes in SEQUENCE are marked DEFAULT
%% or OPTIONAL (or the type is defined SEQUENCE{}, which is handled by
%% the previous case).
@@ -2801,9 +2310,23 @@ normalize_seq_or_set(SorS,S,Value=#'Externalvaluereference'{},
Cs,NameList,Acc) ->
get_normalized_value(S,Value,Cs,fun normalize_seq_or_set/6,
[SorS,NameList,Acc]);
-normalize_seq_or_set(_SorS,S,V,_,_,_) ->
- error({type,{illegal,default,value,V},S}).
-
+normalize_seq_or_set(_SorS, _S, [], [], _, Acc) ->
+ lists:reverse(Acc);
+normalize_seq_or_set(_SorS, S, V, Cs, _, _) ->
+ case V of
+ [{#seqtag{val=Name},_}|_] ->
+ asn1_error(S, {illegal_id,error_value(Name)});
+ [] ->
+ [#'ComponentType'{name=Name}|_] = Cs,
+ asn1_error(S, {missing_id,error_value(Name)})
+ end.
+
+verify_valid_component(S, Name, Cs) ->
+ case lists:keyfind(Name, #'ComponentType'.name, Cs) of
+ false -> asn1_error(S, {illegal_id,error_value(Name)});
+ #'ComponentType'{} -> ok
+ end.
+
normalize_seqof(S,Value,Type,NameList) ->
normalize_s_of('SEQUENCE OF',S,Value,Type,NameList).
@@ -2859,10 +2382,7 @@ normalize_restrictedstring(_S,CString,_) when is_list(CString) ->
%% definedvalue case or argument in a parameterized type
normalize_restrictedstring(S,ERef,CType) when is_record(ERef,'Externalvaluereference') ->
get_normalized_value(S,ERef,CType,
- fun normalize_restrictedstring/3,[]);
-%%
-normalize_restrictedstring(S,{Name,Val},CType) when is_atom(Name) ->
- normalize_restrictedstring(S,Val,CType).
+ fun normalize_restrictedstring/3,[]).
normalize_objectclassfieldvalue(S,{opentypefieldvalue,Type,Value},NameList) ->
%% An open type has per definition no type. Thus should the type
@@ -2910,6 +2430,8 @@ call_Func(S,Val,Type,Func,ArgList) ->
get_canonic_type(S,Type,NameList) ->
{InnerType,NewType,NewNameList} =
case Type#type.def of
+ 'INTEGER'=Name ->
+ {Name,[],NameList};
Name when is_atom(Name) ->
{Name,Type,NameList};
Ref when is_record(Ref,'Externaltypereference') ->
@@ -2964,8 +2486,8 @@ check_formal_parameter(_, {_,_}) ->
ok;
check_formal_parameter(_, #'Externaltypereference'{}) ->
ok;
-check_formal_parameter(S, #'Externalvaluereference'{value=Name}=Ref) ->
- asn1_error(S, Ref, {illegal_typereference,Name}).
+check_formal_parameter(S, #'Externalvaluereference'{value=Name}) ->
+ asn1_error(S, {illegal_typereference,Name}).
% check_type(S,Type,ObjSpec={{objectclassname,_},_}) ->
% check_class(S,ObjSpec);
@@ -2977,7 +2499,7 @@ check_type(_S,Type,Ts) when is_record(Type,typedef),
Ts;
check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
{Def,Tag,Constr,IsInlined} =
- case match_parameters(S,Ts#type.def,S#state.parameters) of
+ case match_parameter(S, Ts#type.def) of
#type{tag=PTag,constraint=_Ctmp,def=Dtmp,inlined=Inl} ->
{Dtmp,merge_tags(Ts#type.tag,PTag),Ts#type.constraint,Inl};
#typedef{typespec=#type{tag=PTag,def=Dtmp,inlined=Inl}} ->
@@ -2989,16 +2511,16 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
inlined=IsInlined},
TestFun =
fun(Tref) ->
- MaybeChoice = get_non_typedef(S, Tref),
+ {_, MaybeChoice} = get_referenced_type(S, Tref, true),
case catch((MaybeChoice#typedef.typespec)#type.def) of
{'CHOICE',_} ->
- maybe_illicit_implicit_tag(choice,Tag);
+ maybe_illicit_implicit_tag(S, choice, Tag);
'ANY' ->
- maybe_illicit_implicit_tag(open_type,Tag);
+ maybe_illicit_implicit_tag(S, open_type, Tag);
'ANY DEFINED BY' ->
- maybe_illicit_implicit_tag(open_type,Tag);
+ maybe_illicit_implicit_tag(S, open_type, Tag);
'ASN1_OPEN_TYPE' ->
- maybe_illicit_implicit_tag(open_type,Tag);
+ maybe_illicit_implicit_tag(S, open_type, Tag);
_ ->
Tag
end
@@ -3007,7 +2529,7 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
case Def of
Ext when is_record(Ext,'Externaltypereference') ->
{RefMod,RefTypeDef,IsParamDef} =
- case get_referenced_type(S,Ext) of
+ case get_referenced_type(S, Ext) of
{undefined,TmpTDef} -> %% A parameter
{get(top_module),TmpTDef,true};
{TmpRefMod,TmpRefDef} ->
@@ -3031,7 +2553,6 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
NewS = S#state{mname=RefMod,
module=load_asn1_module(S,RefMod),
tname=get_datastr_name(NewRefTypeDef1),
- type=NewRefTypeDef1,
abscomppath=[],recordtopname=[]},
RefType1 =
check_type(NewS,RefTypeDef,RefTypeDef#typedef.typespec),
@@ -3051,18 +2572,17 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
Key);
_ -> ok
end,
+ Pos = Ext#'Externaltypereference'.pos,
{RefType1,#'Externaltypereference'{module=RefMod,
+ pos=Pos,
type=TmpName}}
end,
case asn1ct_gen:prim_bif(asn1ct_gen:get_inner(RefType#type.def)) of
true ->
%% Here we expand to a built in type and inline it
- NewS2 = S#state{type=#typedef{typespec=RefType}},
- NewC =
- constraint_merge(NewS2,
- check_constraints(NewS2,Constr)++
- RefType#type.constraint),
+ NewC = check_constraints(S, RefType, Constr ++
+ RefType#type.constraint),
TempNewDef#newt{
type = RefType#type.def,
tag = merge_tags(Ct,RefType#type.tag),
@@ -3073,19 +2593,13 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
NewExt = ExtRef#'Externaltypereference'{module=merged_mod(S,RefMod,Ext)},
TempNewDef#newt{
type = check_externaltypereference(S,NewExt),
- tag = case S#state.erule of
- ber ->
- merge_tags(Ct,RefType#type.tag);
- _ ->
- Ct
- end
- }
+ tag = merge_tags(Ct,RefType#type.tag)}
end;
'ANY' ->
- Ct=maybe_illicit_implicit_tag(open_type,Tag),
+ Ct = maybe_illicit_implicit_tag(S, open_type, Tag),
TempNewDef#newt{type='ASN1_OPEN_TYPE',tag=Ct};
{'ANY_DEFINED_BY',_} ->
- Ct=maybe_illicit_implicit_tag(open_type,Tag),
+ Ct = maybe_illicit_implicit_tag(S, open_type, Tag),
TempNewDef#newt{type='ASN1_OPEN_TYPE',tag=Ct};
'INTEGER' ->
TempNewDef#newt{tag=
@@ -3132,7 +2646,7 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
{'ENUMERATED',NamedNumberList} ->
TempNewDef#newt{type=
{'ENUMERATED',
- check_enumerated(S,NamedNumberList,Constr)},
+ check_enumerated(S, NamedNumberList)},
tag=
merge_tags(Tag,?TAG_PRIMITIVE(?N_ENUMERATED)),
constraint=[]};
@@ -3235,7 +2749,7 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
tag=
merge_tags(Tag,?TAG_CONSTRUCTED(?N_SEQUENCE))};
{'CHOICE',Components} ->
- Ct = maybe_illicit_implicit_tag(choice,Tag),
+ Ct = maybe_illicit_implicit_tag(S, choice, Tag),
TempNewDef#newt{type={'CHOICE',check_choice(S,Type,Components)},tag=Ct};
Set when is_record(Set,'SET') ->
RecordName=
@@ -3258,12 +2772,6 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
TempNewDef#newt{type={'SET OF',check_setof(S,Type,Components)},
tag=
merge_tags(Tag,?TAG_CONSTRUCTED(?N_SET))};
- %% This is a temporary hack until the full Information Obj Spec
- %% in X.681 is supported
- {#'Externaltypereference'{type='TYPE-IDENTIFIER'},
- [{typefieldreference,_,'Type'}]} ->
- Ct=maybe_illicit_implicit_tag(open_type,Tag),
- TempNewDef#newt{type='ASN1_OPEN_TYPE',tag=Ct};
{pt,Ptype,ParaList} ->
%% Ptype might be a parameterized - type, object set or
@@ -3271,18 +2779,18 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
%% calling function.
{_RefMod,Ptypedef} = get_referenced_type(S,Ptype),
notify_if_not_ptype(S,Ptypedef),
- NewParaList =
- [match_parameters(S,TmpParam,S#state.parameters)||
- TmpParam <- ParaList],
+ NewParaList = match_parameters(S, ParaList),
Instance = instantiate_ptype(S,Ptypedef,NewParaList),
TempNewDef#newt{type=Instance#type.def,
tag=merge_tags(Tag,Instance#type.tag),
constraint=Instance#type.constraint,
inlined=yes};
- OCFT=#'ObjectClassFieldType'{classname=ClRef} ->
+ #'ObjectClassFieldType'{classname=ClRef0}=OCFT0 ->
%% this case occures in a SEQUENCE when
%% the type of the component is a ObjectClassFieldType
+ ClRef = match_parameter(S, ClRef0),
+ OCFT = OCFT0#'ObjectClassFieldType'{classname=ClRef},
ClassSpec = check_class(S,ClRef),
NewTypeDef =
maybe_open_type(S,ClassSpec,
@@ -3292,16 +2800,18 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
Ct =
case is_open_type(NewTypeDef) of
true ->
- maybe_illicit_implicit_tag(open_type,MergedTag);
+ maybe_illicit_implicit_tag(S, open_type, MergedTag);
_ ->
MergedTag
end,
case TopName of
[] when Type#typedef.name =/= undefined ->
%% This is a top-level type.
- #type{def=Simplified} =
- simplify_type(#type{def=NewTypeDef}),
- TempNewDef#newt{type=Simplified,tag=Ct};
+ #type{constraint=C,def=Simplified} =
+ simplify_type(#type{def=NewTypeDef,
+ constraint=Constr}),
+ TempNewDef#newt{type=Simplified,tag=Ct,
+ constraint=C};
_ ->
TempNewDef#newt{type=NewTypeDef,tag=Ct}
end;
@@ -3311,33 +2821,21 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
TempNewDef#newt{tag=merge_tags(Tag,CheckedT#type.tag),
type=CheckedT#type.def};
- {valueset,Vtype} ->
- TempNewDef#newt{type={valueset,check_type(S,Type,Vtype)}};
{'SelectionType',Name,T} ->
CheckedT = check_selectiontype(S,Name,T),
TempNewDef#newt{tag=merge_tags(Tag,CheckedT#type.tag),
type=CheckedT#type.def};
- Other ->
- exit({'cant check' ,Other})
+ 'ASN1_OPEN_TYPE' ->
+ TempNewDef
end,
#newt{type=TDef,tag=NewTags,constraint=NewConstr,inlined=Inlined} = NewDef,
Ts#type{def=TDef,
inlined=Inlined,
- constraint=check_constraints(S, NewConstr),
+ constraint=check_constraints(S, #type{def=TDef}, NewConstr),
tag=lists:map(fun(#tag{type={default,TTx}}=TempTag) ->
TempTag#tag{type=TTx};
(Other) -> Other
- end, NewTags)};
-check_type(_S,Type,Ts) ->
- exit({error,{asn1,internal_error,Type,Ts}}).
-
-get_non_typedef(S, Tref0) ->
- case get_referenced_type(S, Tref0) of
- {_,#typedef{typespec=#type{def=#'Externaltypereference'{}=Tref}}} ->
- get_non_typedef(S, Tref);
- {_,Type} ->
- Type
- end.
+ end, NewTags)}.
%%
@@ -3353,10 +2851,11 @@ simplify_comp(#'ComponentType'{typespec=Type0}=C) ->
C#'ComponentType'{typespec=Type};
simplify_comp(Other) -> Other.
-simplify_type(#type{tag=Tag,def=Inner}=T) ->
+simplify_type(#type{tag=Tag,def=Inner,constraint=Constr0}=T) ->
case Inner of
- #'ObjectClassFieldType'{type={fixedtypevaluefield,_,Type}} ->
- Type#type{tag=Tag};
+ #'ObjectClassFieldType'{type={fixedtypevaluefield,_,Type}}=OCFT ->
+ Constr = [{ocft,OCFT}|Type#type.constraint++Constr0],
+ Type#type{tag=Tag,constraint=Constr};
_ ->
T
end.
@@ -3389,29 +2888,22 @@ get_innertag(_S,#'ObjectClassFieldType'{type=Type}) ->
_ -> []
end.
-get_type_from_object(S,Object,TypeField)
- when is_record(Object,'Externaltypereference');
- is_record(Object,'Externalvaluereference') ->
- {_,ObjectDef} = get_referenced_type(S,Object),
- ObjSpec = check_object(S,ObjectDef,ObjectDef#typedef.typespec),
- get_fieldname_element(S,ObjectDef#typedef{typespec=ObjSpec},TypeField).
-
%% get_class_def(S, Type) -> #classdef{} | 'none'.
get_class_def(S, #typedef{typespec=#type{def=#'Externaltypereference'{}=Eref}}) ->
- {_,NextDef} = get_referenced_type(S, Eref),
+ {_,NextDef} = get_referenced_type(S, Eref, true),
get_class_def(S, NextDef);
get_class_def(S, #'Externaltypereference'{}=Eref) ->
- {_,NextDef} = get_referenced_type(S, Eref),
+ {_,NextDef} = get_referenced_type(S, Eref, true),
get_class_def(S, NextDef);
get_class_def(_S, #classdef{}=CD) ->
CD;
get_class_def(_S, _) ->
none.
-maybe_illicit_implicit_tag(Kind,Tag) ->
+maybe_illicit_implicit_tag(S, Kind, Tag) ->
case Tag of
[#tag{type='IMPLICIT'}|_T] ->
- throw({error,{asn1,{implicit_tag_before,Kind}}});
+ asn1_error(S, {implicit_tag_before,Kind});
[ChTag = #tag{type={default,_}}|T] ->
case Kind of
open_type ->
@@ -3438,19 +2930,24 @@ merged_mod(S,RefMod,Ext) ->
%% any UNIQUE field, so that a component relation constraint cannot specify
%% the type of a typefield, return 'ASN1_OPEN_TYPE'.
%%
-maybe_open_type(S,ClassSpec=#objectclass{fields=Fs},
- OCFT=#'ObjectClassFieldType'{fieldname=FieldRefList},
+maybe_open_type(_, _, #'ObjectClassFieldType'{fieldname={_,_}}=OCFT, _) ->
+ %% Already converted.
+ OCFT;
+maybe_open_type(S, #objectclass{fields=Fs}=ClassSpec,
+ #'ObjectClassFieldType'{fieldname=FieldRefList}=OCFT,
Constr) ->
- Type = get_ObjectClassFieldType(S,Fs,FieldRefList),
- FieldNames=get_referenced_fieldname(FieldRefList),
- case last_fieldname(FieldRefList) of
+ Type = get_OCFType(S, Fs, FieldRefList),
+ FieldNames = get_referenced_fieldname(FieldRefList),
+ case lists:last(FieldRefList) of
{valuefieldreference,_} ->
OCFT#'ObjectClassFieldType'{fieldname=FieldNames,
type=Type};
{typefieldreference,_} ->
- case {catch get_unique_fieldname(S,#classdef{typespec=ClassSpec}),
- asn1ct_gen:get_constraint(Constr,componentrelation)}of
- {Tuple,_} when tuple_size(Tuple) =:= 3 ->
+ %% Note: The constraints have not been checked yet,
+ %% so we must use a special lookup routine.
+ case {get_unique_fieldname(S, #classdef{typespec=ClassSpec}),
+ get_componentrelation(Constr)} of
+ {no_unique,_} ->
OCFT#'ObjectClassFieldType'{fieldname=FieldNames,
type='ASN1_OPEN_TYPE'};
{_,no} ->
@@ -3462,16 +2959,12 @@ maybe_open_type(S,ClassSpec=#objectclass{fields=Fs},
end
end.
-last_fieldname(FieldRefList) when is_list(FieldRefList) ->
- lists:last(FieldRefList);
-last_fieldname({FieldName,_}) when is_atom(FieldName) ->
- [A|_] = atom_to_list(FieldName),
- case is_lowercase(A) of
- true ->
- {valuefieldreference,FieldName};
- _ ->
- {typefieldreference,FieldName}
- end.
+get_componentrelation([{element_set,{componentrelation,_,_}=Cr,none}|_]) ->
+ Cr;
+get_componentrelation([_|T]) ->
+ get_componentrelation(T);
+get_componentrelation([]) ->
+ no.
is_open_type(#'ObjectClassFieldType'{type='ASN1_OPEN_TYPE'}) ->
true;
@@ -3510,35 +3003,19 @@ notify_if_not_ptype(S,#pobjectsetdef{class=Cl}) ->
_ ->
throw(pobjectsetdef)
end;
-notify_if_not_ptype(_S,PT) ->
- throw({error,{"supposed to be a parameterized type",PT}}).
-% fix me
+notify_if_not_ptype(S, PT) ->
+ asn1_error(S, {param_bad_type, error_value(PT)}).
+
instantiate_ptype(S,Ptypedef,ParaList) ->
#ptypedef{args=Args,typespec=Type} = Ptypedef,
NewType = check_ptype(S,Ptypedef,Type#type{inlined=yes}),
MatchedArgs = match_args(S,Args, ParaList, []),
OldArgs = S#state.parameters,
- NewS = S#state{type=NewType,parameters=MatchedArgs++OldArgs,abscomppath=[]},
-%% NewS = S#state{type=NewType,parameters=MatchedArgs,abscomppath=[]},
+ NewS = S#state{parameters=MatchedArgs++OldArgs,abscomppath=[]},
check_type(NewS, Ptypedef#ptypedef{typespec=NewType}, NewType).
-get_datastr_name(#typedef{name=N}) ->
- N;
-get_datastr_name(#classdef{name=N}) ->
- N;
-get_datastr_name(#valuedef{name=N}) ->
- N;
-get_datastr_name(#ptypedef{name=N}) ->
- N;
-get_datastr_name(#pvaluedef{name=N}) ->
- N;
-get_datastr_name(#pvaluesetdef{name=N}) ->
- N;
-get_datastr_name(#pobjectdef{name=N}) ->
- N;
-get_datastr_name(#pobjectsetdef{name=N}) ->
- N.
-
+get_datastr_name(Type) ->
+ asn1ct:get_name_of_def(Type).
get_pt_args(#ptypedef{args=Args}) ->
Args;
@@ -3606,8 +3083,8 @@ match_args(S,FA = [FormArg|Ft], AA = [ActArg|At], Acc) ->
end;
match_args(_S,[], [], Acc) ->
lists:reverse(Acc);
-match_args(_,_, _, _) ->
- throw({error,{asn1,{wrong_number_of_arguments}}}).
+match_args(S, _, _, _) ->
+ asn1_error(S, param_wrong_number_of_arguments).
%%%%%%%%%%%%%%%%%
%% categorize_arg(S,FormalArg,ActualArg) -> {FormalArg,CatgorizedActualArg}
@@ -3652,11 +3129,6 @@ parameter_name_style(#'Externaltypereference'{}) ->
parameter_name_style(#'Externalvaluereference'{}) ->
beginning_lowercase.
-is_lowercase(X) when X >= $A,X =< $W ->
- false;
-is_lowercase(_) ->
- true.
-
%% categorize(Parameter) -> CategorizedParameter
%% If Parameter has an abstract syntax of another category than
%% Category, transform it to a known syntax.
@@ -3705,725 +3177,503 @@ parse_objectset(Set) ->
Set.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% check_constraints/2
-%%
-check_constraints(S,C) when is_list(C) ->
- check_constraints(S, C, []).
-
-resolv_tuple_or_list(S,List) when is_list(List) ->
- lists:map(fun(X)->resolv_value(S,X) end, List);
-resolv_tuple_or_list(S,{Lb,Ub}) ->
- {resolv_value(S,Lb),resolv_value(S,Ub)}.
-
-%%%-----------------------------------------
-%% If the constraint value is a defined value the valuename
-%% is replaced by the actual value
%%
-resolv_value(S,Val) ->
- Id = match_parameters(S,Val, S#state.parameters),
- resolv_value1(S,Id).
+%% Check and simplify constraints.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-resolv_value1(S, ERef = #'Externalvaluereference'{value=Name}) ->
- case catch resolve_namednumber(S, S#state.type, Name) of
- V when is_integer(V) ->
- V;
- _ ->
- case get_referenced_type(S,ERef) of
- {Err,_Reason} when Err == error; Err == 'EXIT' ->
- throw({error,{asn1,{undefined_type_or_value,
- Name}}});
- {_M,VDef} ->
- resolv_value1(S,VDef)
- end
- end;
-resolv_value1(S, {gt,V}) ->
- case resolv_value1(S, V) of
- Int when is_integer(Int) ->
- Int + 1;
- Other ->
- throw({error,{asn1,{not_integer_value,Other}}})
- end;
-resolv_value1(S, {lt,V}) ->
- case resolv_value1(S, V) of
- Int when is_integer(Int) ->
- Int - 1;
- Other ->
- throw({error,{asn1,{not_integer_value,Other}}})
- end;
-resolv_value1(S,{'ValueFromObject',{object,Object},[{valuefieldreference,
- FieldName}]}) ->
- %% FieldName can hold either a fixed-type value or a variable-type value
- %% Object is a DefinedObject, i.e. a #'Externaltypereference'
- resolve_value_from_object(S,Object,FieldName);
-resolv_value1(_,#valuedef{checked=true,value=V}) ->
- V;
-resolv_value1(S,#valuedef{type=_T,
- value={'ValueFromObject',{object,Object},
- [{valuefieldreference,
- FieldName}]}}) ->
- resolve_value_from_object(S,Object,FieldName);
-resolv_value1(S,VDef = #valuedef{}) ->
- #valuedef{value=Val} = check_value(S,VDef),
- Val;
-resolv_value1(_,V) ->
- V.
-resolve_value_from_object(S,Object,FieldName) ->
- {_,ObjTDef} = get_referenced_type(S,Object),
- TS = check_object(S,ObjTDef,ObjTDef#typedef.typespec),
- {_,_,Components} = TS#'Object'.def,
- case lists:keysearch(FieldName,1,Components) of
- {value,{_,#valuedef{value=Val}}} ->
- Val;
- _ ->
- error({value,"illegal value in constraint",S})
+check_constraints(_S, _HostType, []) ->
+ [];
+check_constraints(S, HostType0, [_|_]=Cs0) ->
+ HostType = get_real_host_type(HostType0, Cs0),
+ Cs1 = top_level_intersections(Cs0),
+ Cs2 = [coalesce_constraints(C) || C <- Cs1],
+ {_,Cs3} = filter_extensions(Cs2),
+ Cs = simplify_element_sets(S, HostType, Cs3),
+ finish_constraints(Cs).
+
+get_real_host_type(HostType, Cs) ->
+ case lists:keyfind(ocft, 1, Cs) of
+ false -> HostType;
+ {_,OCFT} -> HostType#type{def=OCFT}
end.
+top_level_intersections([{element_set,{intersection,_,_}=C,none}]) ->
+ top_level_intersections_1(C);
+top_level_intersections(Cs) ->
+ Cs.
+
+top_level_intersections_1({intersection,A,B}) ->
+ [{element_set,A,none}|top_level_intersections_1(B)];
+top_level_intersections_1(Other) ->
+ [{element_set,Other,none}].
+
+coalesce_constraints({element_set,
+ {Tag,{element_set,A,_}},
+ {Tag,{element_set,B,_}}}) ->
+ %% (SIZE (C1), ..., (SIZE (C2)) => (SIZE (C1, ..., C2))
+ {element_set,{Tag,{element_set,A,B}},none};
+coalesce_constraints(Other) ->
+ Other.
+
+%% Remove all outermost extensions except the last.
+
+filter_extensions([H0|T0]) ->
+ case filter_extensions(T0) of
+ {true,T} ->
+ H = remove_extension(H0),
+ {true,[H|T]};
+ {false,T} ->
+ {any_extension(H0),[H0|T]}
+ end;
+filter_extensions([]) ->
+ {false,[]}.
-resolve_namednumber(S,#typedef{typespec=Type},Name) ->
- case Type#type.def of
- {'ENUMERATED',NameList} ->
- resolve_namednumber_1(S, Name, NameList, Type);
- {'INTEGER',NameList} ->
- resolve_namednumber_1(S, Name, NameList, Type);
+remove_extension({element_set,Root,_}) ->
+ {element_set,remove_extension(Root),none};
+remove_extension(Tuple) when is_tuple(Tuple) ->
+ L = [remove_extension(El) || El <- tuple_to_list(Tuple)],
+ list_to_tuple(L);
+remove_extension(Other) -> Other.
+
+any_extension({element_set,_,Ext}) when Ext =/= none ->
+ true;
+any_extension(Tuple) when is_tuple(Tuple) ->
+ any_extension_tuple(1, Tuple);
+any_extension(_) -> false.
+
+any_extension_tuple(I, T) when I =< tuple_size(T) ->
+ any_extension(element(I, T)) orelse any_extension_tuple(I+1, T);
+any_extension_tuple(_, _) -> false.
+
+simplify_element_sets(S, HostType, [{element_set,R0,E0}|T0]) ->
+ R1 = simplify_element_set(S, HostType, R0),
+ E1 = simplify_element_set(S, HostType, E0),
+ case simplify_element_sets(S, HostType, T0) of
+ [{element_set,R2,E2}] ->
+ [{element_set,cs_intersection(S, R1, R2),
+ cs_intersection(S, E1, E2)}];
+ L when is_list(L) ->
+ [{element_set,R1,E1}|L]
+ end;
+simplify_element_sets(S, HostType, [H|T]) ->
+ [H|simplify_element_sets(S, HostType, T)];
+simplify_element_sets(_, _, []) ->
+ [].
+
+simplify_element_set(_S, _HostType, empty) ->
+ {set,[]};
+simplify_element_set(S, HostType, {'SingleValue',Vs0}) when is_list(Vs0) ->
+ Vs1 = [resolve_value(S, HostType, V) || V <- Vs0],
+ Vs = make_constr_set_vs(Vs1),
+ simplify_element_set(S, HostType, Vs);
+simplify_element_set(S, HostType, {'SingleValue',V0}) ->
+ V1 = resolve_value(S, HostType, V0),
+ V = {set,[{range,V1,V1}]},
+ simplify_element_set(S, HostType, V);
+simplify_element_set(S, HostType, {'ValueRange',{Lb0,Ub0}}) ->
+ Lb = resolve_value(S, HostType, Lb0),
+ Ub = resolve_value(S, HostType, Ub0),
+ V = make_constr_set(S, Lb, Ub),
+ simplify_element_set(S, HostType, V);
+simplify_element_set(S, HostType, {'ALL-EXCEPT',Set0}) ->
+ Set = simplify_element_set(S, HostType, Set0),
+ {'ALL-EXCEPT',Set};
+simplify_element_set(S, HostType, {intersection,A0,B0}) ->
+ A = simplify_element_set(S, HostType, A0),
+ B = simplify_element_set(S, HostType, B0),
+ cs_intersection(S, A, B);
+simplify_element_set(S, HostType, {union,A0,B0}) ->
+ A = simplify_element_set(S, HostType, A0),
+ B = simplify_element_set(S, HostType, B0),
+ cs_union(S, A, B);
+simplify_element_set(S, HostType, {simpletable,{element_set,Type,_}}) ->
+ check_simpletable(S, HostType, Type);
+simplify_element_set(S, _, {componentrelation,R,Id}) ->
+ check_componentrelation(S, R, Id);
+simplify_element_set(S, HostType, {Tag,{element_set,_,_}=El0}) ->
+ [El1] = simplify_element_sets(S, HostType, [El0]),
+ {Tag,El1};
+simplify_element_set(S, HostType, #type{}=Type) ->
+ simplify_element_set_type(S, HostType, Type);
+simplify_element_set(_, _, C) ->
+ C.
+
+simplify_element_set_type(S, HostType, #type{def=Def0}=Type0) ->
+ #'Externaltypereference'{} = Def0, %Assertion.
+ case get_referenced_type(S, Def0) of
+ {_,#valuedef{checked=false,value={valueset,Vs0}}} ->
+ [Vs1] = simplify_element_sets(S, HostType, [Vs0]),
+ case Vs1 of
+ {element_set,Set,none} ->
+ Set;
+ {element_set,Set,{set,[]}} ->
+ Set
+ end;
+ {_,{valueset,#type{def=#'Externaltypereference'{}}=Type}} ->
+ simplify_element_set_type(S, HostType, Type);
_ ->
- not_enumerated
+ case HostType of
+ #type{def=#'ObjectClassFieldType'{}} ->
+ %% Open type.
+ #type{def=Def} = check_type(S, HostType, Type0),
+ Def;
+ _ ->
+ #type{constraint=Cs} = check_type(S, HostType, Type0),
+ C = convert_back(Cs),
+ simplify_element_set(S, HostType, C)
+ end
end.
-resolve_namednumber_1(S, Name, NameList, Type) ->
- NamedNumberList = check_enumerated(S, NameList, Type#type.constraint),
- {_,N} = lookup_enum_value(S, Name, NamedNumberList),
- N.
-
-check_constraints(S,[{'ContainedSubtype',Type} | Rest], Acc) ->
- {RefMod,CTDef} = get_referenced_type(S,Type#type.def),
- NewS = S#state{module=load_asn1_module(S,RefMod),mname=RefMod,
- type=CTDef,tname=get_datastr_name(CTDef)},
- CType = check_type(NewS,S#state.tname,CTDef#typedef.typespec),
- check_constraints(S,Rest,CType#type.constraint ++ Acc);
-check_constraints(S,[C | Rest], Acc) ->
- check_constraints(S,Rest,[check_constraint(S,C) | Acc]);
-check_constraints(S,[],Acc) ->
- constraint_merge(S,Acc).
-
-
-range_check(F={FixV,FixV}) ->
-% FixV;
- F;
-range_check(VR={Lb,Ub}) when Lb < Ub ->
- VR;
-range_check(Err={_,_}) ->
- throw({error,{asn1,{illegal_size_constraint,Err}}});
-range_check(Value) ->
- Value.
-
-check_constraint(S,Ext) when is_record(Ext,'Externaltypereference') ->
- check_externaltypereference(S,Ext);
-
-
-check_constraint(S,{'SizeConstraint',{Lb,Ub}})
- when is_list(Lb); tuple_size(Lb) =:= 2 ->
- NewLb = range_check(resolv_tuple_or_list(S,Lb)),
- NewUb = range_check(resolv_tuple_or_list(S,Ub)),
- {'SizeConstraint',{NewLb,NewUb}};
-check_constraint(S,{'SizeConstraint',{Lb,Ub}}) ->
- case {resolv_value(S,Lb),resolv_value(S,Ub)} of
- {FixV,FixV} ->
- {'SizeConstraint',FixV};
- {Low,High} when Low < High ->
- {'SizeConstraint',{Low,High}};
- Err ->
- throw({error,{asn1,{illegal_size_constraint,Err}}})
- end;
-check_constraint(S,{'SizeConstraint',Lb}) ->
- {'SizeConstraint',resolv_value(S,Lb)};
+convert_back([H1,H2|T]) ->
+ {intersection,H1,convert_back([H2|T])};
+convert_back([H]) ->
+ H;
+convert_back([]) ->
+ none.
-check_constraint(S,{'SingleValue', L}) when is_list(L) ->
- F = fun(A) -> resolv_value(S,A) end,
- {'SingleValue',lists:sort(lists:map(F,L))};
-
-check_constraint(S,{'SingleValue', V}) when is_integer(V) ->
- Val = resolv_value(S,V),
-%% [{'SingleValue',Val},{'ValueRange',{Val,Val}}]; % Why adding value range?
- {'SingleValue',Val};
-check_constraint(S,{'SingleValue', V}) ->
- {'SingleValue',resolv_value(S,V)};
-
-check_constraint(S,{'ValueRange', {Lb, Ub}}) ->
- {'ValueRange',{resolv_value(S,Lb),resolv_value(S,Ub)}};
-%% In case of a constraint with extension marks like (1..Ub,...)
-check_constraint(S,{VR={'ValueRange', {_Lb, _Ub}},Rest}) ->
- {check_constraint(S,VR),Rest};
-check_constraint(_S,{'PermittedAlphabet',PA}) ->
- {'PermittedAlphabet',permitted_alphabet_cnstr(PA)};
-
-check_constraint(S,{valueset,Type}) ->
- {valueset,check_type(S,S#state.tname,Type)};
-
-check_constraint(_S,ST={simpletable,Type}) when is_atom(Type) ->
- %% An already checked constraint
- ST;
-check_constraint(S,{simpletable,Type}) ->
+check_simpletable(S, HostType, Type) ->
+ case HostType of
+ #type{def=#'ObjectClassFieldType'{}} ->
+ ok;
+ _ ->
+ %% Table constraints may only be applied to
+ %% CLASS.&field constructs.
+ asn1_error(S, illegal_table_constraint)
+ end,
Def = case Type of
#type{def=D} -> D;
- {'SingleValue',ObjRef = #'Externalvaluereference'{}} ->
- ObjRef
+ {'SingleValue',#'Externalvaluereference'{}=ObjRef} ->
+ ObjRef;
+ _ ->
+ asn1_error(S, invalid_table_constraint)
end,
- C = match_parameters(S,Def,S#state.parameters),
+ C = match_parameter(S, Def),
case C of
#'Externaltypereference'{} ->
- ERef = check_externaltypereference(S,C),
- {simpletable,ERef#'Externaltypereference'.type};
- #type{def=#'Externaltypereference'{}=ExtTypeRef} ->
- ERef = check_externaltypereference(S, ExtTypeRef),
+ ERef = check_externaltypereference(S, C),
{simpletable,ERef#'Externaltypereference'.type};
- {valueset,#type{def=ERef=#'Externaltypereference'{}}} -> % this is an object set
- {_,TDef} = get_referenced_type(S,ERef),
- case TDef#typedef.typespec of
- #'ObjectSet'{} ->
- check_object(S,TDef,TDef#typedef.typespec),
- {simpletable,ERef#'Externaltypereference'.type};
- Err ->
- exit({error,{internal_error,Err}})
- end;
#'Externalvaluereference'{} ->
%% This is an object set with a referenced object
- {_,TorVDef} = get_referenced_type(S,C),
- GetObjectSet =
- fun(#typedef{typespec=O}) when is_record(O,'Object') ->
- #'ObjectSet'{class=O#'Object'.classname,
- set={'SingleValue',C}};
- (#valuedef{type=Cl,value=O})
- when is_record(O,'Externalvaluereference'),
- is_record(Cl,type) ->
- %% an object might reference another object
- #'ObjectSet'{class=Cl#type.def,
- set={'SingleValue',O}};
- (Err) ->
- exit({error,{internal_error,simpletable_constraint,Err}})
- end,
- ObjSet = GetObjectSet(TorVDef),
- {simpletable,check_object(S,Type,ObjSet)};
- #'ObjectSet'{} ->
- io:format("ALERT: simpletable forbidden case!~n",[]),
- {simpletable,check_object(S,Type,C)};
- {'ValueFromObject',{_,ORef},FieldName} ->
- %% This is an ObjectFromObject
- {_,Object} = get_referenced_type(S,ORef),
- ChObject = check_object(S,Object,
- Object#typedef.typespec),
- ObjFromObj=
- get_fieldname_element(S,Object#typedef{
- typespec=ChObject},
- FieldName),
- {simpletable,ObjFromObj};
-%% ObjFromObj#typedef{checked=true,typespec=
-%% check_object(S,ObjFromObj,
-%% ObjFromObj#typedef.typespec)}};
- _ ->
- check_type(S,S#state.tname,Type),%% this seems stupid.
- OSName = Def#'Externaltypereference'.type,
- {simpletable,OSName}
- end;
+ {_,TorVDef} = get_referenced_type(S, C),
+ Set = case TorVDef of
+ #typedef{typespec=#'Object'{classname=ClassName}} ->
+ #'ObjectSet'{class=ClassName,
+ set={'SingleValue',C}};
+ #valuedef{type=#type{def=ClassDef},
+ value=#'Externalvaluereference'{}=Obj} ->
+ %% an object might reference another object
+ #'ObjectSet'{class=ClassDef,
+ set={'SingleValue',Obj}}
+ end,
+ {simpletable,check_object(S, Type, Set)};
+ {'ValueFromObject',{_,Object},FieldNames} ->
+ %% This is an ObjectFromObject.
+ {simpletable,extract_field(S, Object, FieldNames)}
+ end.
-check_constraint(S,{componentrelation,{objectset,Opos,Objset},Id}) ->
+check_componentrelation(S, {objectset,Opos,Objset0}, Id) ->
%% Objset is an 'Externaltypereference' record, since Objset is
%% a DefinedObjectSet.
- RealObjset = match_parameters(S,Objset,S#state.parameters),
- ObjSetRef =
- case RealObjset of
- #'Externaltypereference'{} -> RealObjset;
- #type{def=#'Externaltypereference'{}} -> RealObjset#type.def;
- {valueset,OS = #type{def=#'Externaltypereference'{}}} -> OS#type.def
- end,
- Ext = check_externaltypereference(S,ObjSetRef),
- {componentrelation,{objectset,Opos,Ext},Id};
+ ObjSet = match_parameter(S, Objset0),
+ Ext = check_externaltypereference(S, ObjSet),
+ {componentrelation,{objectset,Opos,Ext},Id}.
+
+%%%
+%%% Internal set representation.
+%%%
+%%% We represent sets as a union of strictly disjoint ranges:
+%%%
+%%% {set,[Range]}
+%%%
+%%% A range is represented as:
+%%%
+%%% Range = {a_range,UpperBound} | {range,LowerBound,UpperBound}
+%%%
+%%% We don't use the atom 'MIN' to represent MIN, because atoms
+%%% compare higher than integer. Instead we use {a_range,UpperBound}
+%%% to represent MIN..UpperBound. We represent MAX as 'MAX' because
+%%% 'MAX' compares higher than any integer.
+%%%
+%%% The ranges are sorted in term order. The ranges must not overlap
+%%% or be adjacent to each other. This invariant is established when
+%%% creating sets, and maintained by the intersection and union
+%%% operators.
+%%%
+%%% Example of invalid set representaions:
+%%%
+%%% [{range,0,10},{range,5,10}] %Overlapping ranges
+%%% [{range,0,5},{range,6,10}] %Adjancent ranges
+%%% [{range,10,20},{a_range,100}] %Not sorted
+%%%
+
+make_constr_set(_, 'MIN', Ub) ->
+ {set,[{a_range,make_constr_set_val(Ub)}]};
+make_constr_set(_, Lb, Ub) when Lb =< Ub ->
+ {set,[{range,make_constr_set_val(Lb),
+ make_constr_set_val(Ub)}]};
+make_constr_set(S, _, _) ->
+ asn1_error(S, reversed_range).
+
+make_constr_set_val([C]) when is_integer(C) -> C;
+make_constr_set_val(Val) -> Val.
+
+make_constr_set_vs(Vs) ->
+ {set,make_constr_set_vs_1(Vs)}.
+
+make_constr_set_vs_1([]) ->
+ [];
+make_constr_set_vs_1([V]) ->
+ [{range,V,V}];
+make_constr_set_vs_1([V0|Vs]) ->
+ V1 = make_constr_set_vs_1(Vs),
+ range_union([{range,V0,V0}], V1).
+
+%%%
+%%% Set operators.
+%%%
+
+cs_intersection(_S, Other, none) ->
+ Other;
+cs_intersection(_S, none, Other) ->
+ Other;
+cs_intersection(_S, {set,SetA}, {set,SetB}) ->
+ {set,range_intersection(SetA, SetB)};
+cs_intersection(_S, A, B) ->
+ {intersection,A,B}.
+
+range_intersection([], []) ->
+ [];
+range_intersection([_|_], []) ->
+ [];
+range_intersection([], [_|_]) ->
+ [];
+range_intersection([H1|_]=A, [H2|_]=B) when H1 > H2 ->
+ range_intersection(B, A);
+range_intersection([H1|T1], [H2|T2]=B) ->
+ %% Now H1 =< H2.
+ case {H1,H2} of
+ {{a_range,Ub0},{a_range,Ub1}} when Ub0 < Ub1 ->
+ %% Ub0 =/= 'MAX'
+ [H1|range_intersection(T1, [{range,Ub0+1,Ub1}|T2])];
+ {{a_range,_},{a_range,_}} ->
+ %% Must be equal.
+ [H1|range_intersection(T1, T2)];
+ {{a_range,Ub0},{range,Lb1,_Ub1}} when Ub0 < Lb1 ->
+ %% No intersection.
+ range_intersection(T1, B);
+ {{a_range,Ub0},{range,Lb1,Ub1}} when Ub0 < Ub1 ->
+ %% Ub0 =/= 'MAX'
+ [{range,Lb1,Ub0}|range_intersection(T1, [{range,Ub0+1,Ub1}|T2])];
+ {{a_range,Ub},{range,_Lb1,Ub}} ->
+ %% The first range covers the second range, but does not
+ %% go beyond. We handle this case specially because Ub may
+ %% be 'MAX', and evaluating 'MAX'+1 will fail.
+ [H2|range_intersection(T1, T2)];
+ {{a_range,Ub0},{range,_Lb1,Ub1}} ->
+ %% Ub0 > Ub1, Ub1 =/= 'MAX'. The first range completely
+ %% covers and extends beyond the second range.
+ [H2|range_intersection([{range,Ub1+1,Ub0}|T1], T2)];
+ {{range,_Lb0,Ub0},{range,Lb1,_Ub1}} when Ub0 < Lb1 ->
+ %% Lb0 < Lb1. No intersection.
+ range_intersection(T1, B);
+ {{range,_Lb0,Ub0},{range,Lb1,Ub1}} when Ub0 < Ub1 ->
+ %% Ub0 >= Lb1, Ub0 =/= 'MAX'. Partial overlap.
+ [{range,Lb1,Ub0}|range_intersection(T1, [{range,Ub0+1,Ub1}|T2])];
+ {{range,_Lb0,Ub},{range,_Lb1,Ub}} ->
+ %% The first range covers the second range, but does not
+ %% go beyond. We handle this case specially because Ub may
+ %% be 'MAX', and evaluating 'MAX'+1 will fail.
+ [H2|range_intersection(T1, T2)];
+ {{range,_Lb0,Ub0},{range,_Lb1,Ub1}} ->
+ %% Ub1 =/= MAX. The first range completely covers and
+ %% extends beyond the second.
+ [H2|range_intersection([{range,Ub1+1,Ub0}|T1], T2)]
+ end.
-check_constraint(S,Type) when is_record(Type,type) ->
- #type{def=Def} = check_type(S,S#state.tname,Type),
- Def;
+cs_union(_S, {set,SetA}, {set,SetB}) ->
+ {set,range_union(SetA, SetB)};
+cs_union(_S, A, B) ->
+ {union,A,B}.
+
+range_union(A, B) ->
+ range_union_1(lists:merge(A, B)).
+
+range_union_1([{a_range,Ub0},{a_range,Ub1}|T]) ->
+ range_union_1([{a_range,max(Ub0, Ub1)}|T]);
+range_union_1([{a_range,Ub0},{range,Lb1,Ub1}|T]) when Lb1-1 =< Ub0 ->
+ range_union_1([{a_range,max(Ub0, Ub1)}|T]);
+range_union_1([{a_range,_}=H|T]) ->
+ %% Ranges are disjoint.
+ [H|range_union_1(T)];
+range_union_1([{range,Lb0,Ub0},{range,Lb1,Ub1}|T]) when Lb1-1 =< Ub0 ->
+ range_union_1([{range,Lb0,max(Ub0, Ub1)}|T]);
+range_union_1([{range,_,_}=H|T]) ->
+ %% Ranges are disjoint.
+ [H|range_union_1(T)];
+range_union_1([]) ->
+ [].
-check_constraint(S,C) when is_list(C) ->
- lists:map(fun(X)->check_constraint(S,X) end,C);
-% else keep the constraint unchanged
-check_constraint(_S,Any) ->
-% io:format("Constraint = ~p~n",[Any]),
- Any.
-
-permitted_alphabet_cnstr(T) when is_tuple(T) ->
- permitted_alphabet_cnstr([T]);
-permitted_alphabet_cnstr(L) when is_list(L) ->
- VRexpand = fun({'ValueRange',{A,B}}) ->
- {'SingleValue',expand_valuerange(A,B)};
- (Other) ->
- Other
- end,
- L2 = lists:map(VRexpand,L),
- %% first perform intersection
- L3 = permitted_alphabet_intersection(L2),
- [Res] = permitted_alphabet_union(L3),
- Res.
+%%%
+%%% Finish up constrains, making them suitable for the back-ends.
+%%%
+%%% A 'PermittedAlphabet' (FROM) constraint will be reduced to:
+%%%
+%%% {'SingleValue',[integer()]}
+%%%
+%%% A 'SizeConstraint' (SIZE) constraint will be reduced to:
+%%%
+%%% {Lb,Ub}
+%%%
+%%% All other constraints will be reduced to:
+%%%
+%%% {'SingleValue',[integer()]} | {'ValueRange',Lb,Ub}
+%%%
+
+finish_constraints(Cs) ->
+ finish_constraints_1(Cs, fun smart_collapse/1).
+
+finish_constraints_1([{element_set,{Tag,{element_set,_,_}=Set0},none}|T],
+ Collapse0) ->
+ Collapse = collapse_fun(Tag),
+ case finish_constraints_1([Set0], Collapse) of
+ [] ->
+ finish_constraints_1(T, Collapse0);
+ [Set] ->
+ [{Tag,Set}|finish_constraints_1(T, Collapse0)]
+ end;
+finish_constraints_1([{element_set,{set,[{a_range,'MAX'}]},_}|T], Collapse) ->
+ finish_constraints_1(T, Collapse);
+finish_constraints_1([{element_set,{intersection,A0,B0},none}|T], Collapse) ->
+ A = {element_set,A0,none},
+ B = {element_set,B0,none},
+ finish_constraints_1([A,B|T], Collapse);
+finish_constraints_1([{element_set,Root,Ext}|T], Collapse) ->
+ case finish_constraint(Root, Ext, Collapse) of
+ none ->
+ finish_constraints_1(T, Collapse);
+ Constr ->
+ [Constr|finish_constraints_1(T, Collapse)]
+ end;
+finish_constraints_1([H|T], Collapse) ->
+ [H|finish_constraints_1(T, Collapse)];
+finish_constraints_1([], _) ->
+ [].
-expand_valuerange([A],[A]) ->
- [A];
-expand_valuerange([A],[B]) when A < B ->
- [A|expand_valuerange([A+1],[B])].
+finish_constraint({set,Root0}, Ext, Collapse) ->
+ case Collapse(Root0) of
+ none -> none;
+ Root -> finish_constraint(Root, Ext, Collapse)
+ end;
+finish_constraint(Root, Ext, _Collapse) ->
+ case Ext of
+ none -> Root;
+ _ -> {Root,[]}
+ end.
-permitted_alphabet_intersection(C) ->
- permitted_alphabet_merge(C,intersection, []).
+collapse_fun('SizeConstraint') ->
+ fun size_constraint_collapse/1;
+collapse_fun('PermittedAlphabet') ->
+ fun single_value_collapse/1.
-permitted_alphabet_union(C) ->
- permitted_alphabet_merge(C,union, []).
+single_value_collapse(V) ->
+ {'SingleValue',ordsets:from_list(single_value_collapse_1(V))}.
-permitted_alphabet_merge([],_,Acc) ->
- lists:reverse(Acc);
-permitted_alphabet_merge([{'SingleValue',L1},
- UorI,
- {'SingleValue',L2}|Rest],UorI,Acc)
- when is_list(L1),is_list(L2) ->
- UI = ordsets:UorI([ordsets:from_list(L1),ordsets:from_list(L2)]),
- permitted_alphabet_merge([{'SingleValue',UI}|Rest],UorI,Acc);
-permitted_alphabet_merge([C1|Rest],UorI,Acc) ->
- permitted_alphabet_merge(Rest,UorI,[C1|Acc]).
-
-
-%% constraint_merge/2
-%% Compute the intersection of the outermost level of the constraint list.
-%% See Dubuisson second paragraph and fotnote on page 285.
-%% If constraints with extension are included in combined constraints. The
-%% resulting combination will have the extension of the last constraint. Thus,
-%% there will be no extension if the last constraint is without extension.
-%% The rootset of all constraints are considered in the "outermoust
-%% intersection". See section 13.1.2 in Dubuisson.
-constraint_merge(St, Cs0) ->
- Cs = constraint_merge_1(St, Cs0),
- normalize_cs(Cs).
-
-normalize_cs([{'SingleValue',[V]}|Cs]) ->
- [{'SingleValue',V}|normalize_cs(Cs)];
-normalize_cs([{'SingleValue',[_|_]=L0}|Cs]) ->
- [H|T] = L = lists:usort(L0),
- [case is_range(H, T) of
- false -> {'SingleValue',L};
- true -> {'ValueRange',{H,lists:last(T)}}
- end|normalize_cs(Cs)];
-normalize_cs([{'ValueRange',{Sv,Sv}}|Cs]) ->
- [{'SingleValue',Sv}|normalize_cs(Cs)];
-normalize_cs([{'ValueRange',{'MIN','MAX'}}|Cs]) ->
- normalize_cs(Cs);
-normalize_cs([{'SizeConstraint',C0}|Cs]) ->
- case normalize_size_constraint(C0) of
- none ->
- normalize_cs(Cs);
- C ->
- [{'SizeConstraint',C}|normalize_cs(Cs)]
- end;
-normalize_cs([H|T]) ->
- [H|normalize_cs(T)];
-normalize_cs([]) -> [].
+single_value_collapse_1([{range,Lb,Ub}|T]) when is_integer(Lb),
+ is_integer(Ub) ->
+ lists:seq(Lb, Ub) ++ single_value_collapse_1(T);
+single_value_collapse_1([]) ->
+ [].
-%% Normalize a size constraint to make it non-ambiguous and
-%% easy to interpret for the backends.
-%%
-%% Returns one of the following terms:
-%% {LowerBound,UpperBound}
-%% {{LowerBound,UpperBound},[]} % Extensible
-%% none % Remove size constraint from list
-%%
-%% where:
-%% LowerBound = integer()
-%% UpperBound = integer() | 'MAX'
-
-normalize_size_constraint(Sv) when is_integer(Sv) ->
- {Sv,Sv};
-normalize_size_constraint({Root,Ext}) when is_list(Ext) ->
- {normalize_size_constraint(Root),[]};
-normalize_size_constraint({{_,_},Ext}) when is_integer(Ext) ->
- normalize_size_constraint(Ext);
-normalize_size_constraint([H|T]) ->
- {H,lists:last(T)};
-normalize_size_constraint({0,'MAX'}) ->
+smart_collapse([{a_range,Ub}]) ->
+ {'ValueRange',{'MIN',Ub}};
+smart_collapse([{a_range,_}|T]) ->
+ {range,_,Ub} = lists:last(T),
+ {'ValueRange',{'MIN',Ub}};
+smart_collapse([{range,Lb,Ub}]) ->
+ {'ValueRange',{Lb,Ub}};
+smart_collapse([_|_]=L) ->
+ V = lists:foldr(fun({range,Lb,Ub}, A) ->
+ seq(Lb, Ub) ++ A
+ end, [], L),
+ {'SingleValue',V}.
+
+size_constraint_collapse([{range,0,'MAX'}]) ->
none;
-normalize_size_constraint({Lb,Ub}=Range)
- when is_integer(Lb), is_integer(Ub) orelse Ub =:= 'MAX' ->
- Range.
+size_constraint_collapse(Root) ->
+ [{range,Lb,_}|_] = Root,
+ {range,_,Ub} = lists:last(Root),
+ {Lb,Ub}.
-is_range(Prev, [H|T]) when Prev =:= H - 1 -> is_range(H, T);
-is_range(_, [_|_]) -> false;
-is_range(_, []) -> true.
+seq(Same, Same) ->
+ [Same];
+seq(Lb, Ub) when is_integer(Lb), is_integer(Ub) ->
+ lists:seq(Lb, Ub).
-constraint_merge_1(_S, [H]=C) when is_tuple(H) ->
- C;
-constraint_merge_1(_S, []) ->
- [];
-constraint_merge_1(S, C) ->
- %% skip all extension but the last extension
- C1 = filter_extensions(C),
- %% perform all internal level intersections, intersections first
- %% since they have precedence over unions
- C2 = lists:map(fun(X)when is_list(X)->constraint_intersection(S,X);
- (X) -> X end,
- C1),
- %% perform all internal level unions
- C3 = lists:map(fun(X)when is_list(X)->constraint_union(S,X);
- (X) -> X end,
- C2),
-
- %% now get intersection of the outermost level
- %% get the least common single value constraint
- SVs = get_constraints(C3,'SingleValue'),
- CombSV = intersection_of_sv(S,SVs),
- %% get the least common value range constraint
- VRs = get_constraints(C3,'ValueRange'),
- CombVR = intersection_of_vr(S,VRs),
- %% get the least common size constraint
- SZs = get_constraints(C3,'SizeConstraint'),
- CombSZ = intersection_of_size(S,SZs),
- RestC = ordsets:subtract(ordsets:from_list(C3),
- ordsets:from_list(SZs ++ VRs ++ SVs)),
- %% get the least common combined constraint. That is the union of each
- %% deep constraint and merge of single value and value range constraints.
- %% FIXME: Removing 'intersection' from the flattened list essentially
- %% means that intersections are converted to unions!
- Cs = combine_constraints(S, CombSV, CombVR, CombSZ++RestC),
- [X || X <- lists:flatten(Cs),
- X =/= intersection,
- X =/= union].
-
-%% constraint_union(S,C) takes a list of constraints as input and
-%% merge them to a union. Unions are performed when two
-%% constraints is found with an atom union between.
-%% The list may be nested. Fix that later !!!
-constraint_union(_S,[]) ->
- [];
-constraint_union(_S,C=[_E]) ->
- C;
-constraint_union(S,C) when is_list(C) ->
- case lists:member(union,C) of
- true ->
- constraint_union1(S,C,[]);
- _ ->
- C
- end;
-% SV = get_constraints(C,'SingleValue'),
-% SV1 = constraint_union_sv(S,SV),
-% VR = get_constraints(C,'ValueRange'),
-% VR1 = constraint_union_vr(VR),
-% RestC = ordsets:filter(fun({'SingleValue',_})->false;
-% ({'ValueRange',_})->false;
-% (_) -> true end,ordsets:from_list(C)),
-% SV1++VR1++RestC;
-constraint_union(_S,C) ->
- [C].
-
-constraint_union1(S, [{'ValueRange',{Lb1,Ub1}},union,
- {'ValueRange',{Lb2,Ub2}}|Rest], Acc) ->
- AunionB = {'ValueRange',{c_min(Lb1, Lb2),max(Ub1, Ub2)}},
- constraint_union1(S, [AunionB|Rest], Acc);
-constraint_union1(S,[A={'SingleValue',_},union,B={'SingleValue',_}|Rest],Acc) ->
- AunionB = constraint_union_sv(S,[A,B]),
- constraint_union1(S,Rest,Acc ++ AunionB);
-constraint_union1(S,[A={'SingleValue',_},union,B={'ValueRange',_}|Rest],Acc) ->
- AunionB = union_sv_vr(S,A,B),
- constraint_union1(S, AunionB++Rest, Acc);
-constraint_union1(S,[A={'ValueRange',_},union,B={'SingleValue',_}|Rest],Acc) ->
- AunionB = union_sv_vr(S,B,A),
- constraint_union1(S, AunionB++Rest, Acc);
-constraint_union1(S,[union|Rest],Acc) -> %skip when unsupported constraints
- constraint_union1(S,Rest,Acc);
-constraint_union1(S,[A|Rest],Acc) ->
- constraint_union1(S,Rest,[A|Acc]);
-constraint_union1(_S,[],Acc) ->
- Acc.
+%%%-----------------------------------------
+%% If the constraint value is a defined value the valuename
+%% is replaced by the actual value
+%%
+resolve_value(S, HostType, Val) ->
+ Id = match_parameter(S, Val),
+ resolve_value1(S, HostType, Id).
-constraint_union_sv(_S,SV) ->
- Values=lists:map(fun({_,V})->V end,SV),
- case ordsets:from_list(Values) of
- [] -> [];
- [N] -> [{'SingleValue',N}];
- L -> [{'SingleValue',L}]
- end.
-c_min('MIN', _) -> 'MIN';
-c_min(_, 'MIN') -> 'MIN';
-c_min(A, B) -> min(A, B).
-
-union_sv_vr(_S,{'SingleValue',SV},VR)
- when is_integer(SV) ->
- union_sv_vr(_S,{'SingleValue',[SV]},VR);
-union_sv_vr(_S,{'SingleValue',SV},{'ValueRange',{VLb,VUb}})
- when is_list(SV) ->
- L = lists:sort(SV++[VLb,VUb]),
- {Lb,L1} = case lists:member('MIN',L) of
- true -> {'MIN',L--['MIN']}; % remove 'MIN' so it does not disturb
- false -> {hd(L),tl(L)}
- end,
- Ub = case lists:member('MAX',L1) of
- true -> 'MAX';
- false -> lists:last(L1)
- end,
- case SV of
- [H] -> H;
- _ -> SV
- end,
- %% for now we through away the Singlevalues so that they don't disturb
- %% in the code generating phase (the effective Valuerange is already
- %% calculated. If we want to keep the Singlevalues as well for
- %% use in code gen phases we need to introduce a new representation
- %% like {'ValueRange',{Lb,Ub},[ListOfRanges|AntiValues|Singlevalues]
- %% These could be used to generate guards which allows only the specific
- %% values , not the full range
- [{'ValueRange',{Lb,Ub}}].
-
-
-%% get_constraints/2
-%% Arguments are a list of constraints, which has the format {key,value},
-%% and a constraint type
-%% Returns a list of constraints only of the requested type or the atom
-%% 'no' if no such constraints were found
-get_constraints(L=[{CType,_}],CType) ->
- L;
-get_constraints(C,CType) ->
- keysearch_allwithkey(CType,1,C).
-
-%% keysearch_allwithkey(Key,Ix,L)
-%% Types:
-%% Key = is_atom()
-%% Ix = integer()
-%% L = [TwoTuple]
-%% TwoTuple = [{atom(),term()}|...]
-%% Returns a List that contains all
-%% elements from L that has a key Key as element Ix
-keysearch_allwithkey(Key,Ix,L) ->
- lists:filter(fun(X) when is_tuple(X) ->
- case element(Ix,X) of
- Key -> true;
- _ -> false
- end;
- (_) -> false
- end, L).
-
-
-%% filter_extensions(C)
-%% takes a list of constraints as input and returns a list with the
-%% constraints and all extensions but the last are removed.
-filter_extensions([L]) when is_list(L) ->
- [filter_extensions(L)];
-filter_extensions(C=[_H]) ->
- C;
-filter_extensions(C) when is_list(C) ->
- filter_extensions(C,[], []).
-
-filter_extensions([],Acc,[]) ->
- Acc;
-filter_extensions([],Acc,[EC|ExtAcc]) ->
- CwoExt = remove_extension(ExtAcc,[]),
- CwoExt ++ [EC|Acc];
-filter_extensions([C={A,_E}|T],Acc,ExtAcc) when is_tuple(A) ->
- filter_extensions(T,Acc,[C|ExtAcc]);
-filter_extensions([C={'SizeConstraint',{A,_B}}|T],Acc,ExtAcc)
- when is_list(A);is_tuple(A) ->
- filter_extensions(T,Acc,[C|ExtAcc]);
-filter_extensions([C={'PermittedAlphabet',{{'SingleValue',_},E}}|T],Acc,ExtAcc)
- when is_tuple(E); is_list(E) ->
- filter_extensions(T,Acc,[C|ExtAcc]);
-filter_extensions([H|T],Acc,ExtAcc) ->
- filter_extensions(T,[H|Acc],ExtAcc).
-
-remove_extension([],Acc) ->
- Acc;
-remove_extension([{'SizeConstraint',{A,_B}}|R],Acc) ->
- remove_extension(R,[{'SizeConstraint',A}|Acc]);
-remove_extension([{C,_E}|R],Acc) when is_tuple(C) ->
- remove_extension(R,[C|Acc]);
-remove_extension([{'PermittedAlphabet',{A={'SingleValue',_},
- E}}|R],Acc)
- when is_tuple(E);is_list(E) ->
- remove_extension(R,[{'PermittedAlphabet',A}|Acc]).
-
-%% constraint_intersection(S,C) takes a list of constraints as input and
-%% performs intersections. Intersecions are performed when an
-%% atom intersection is found between two constraints.
-%% The list may be nested. Fix that later !!!
-constraint_intersection(_S,[]) ->
- [];
-constraint_intersection(_S,C=[_E]) ->
- C;
-constraint_intersection(S,C) when is_list(C) ->
-% io:format("constraint_intersection: ~p~n",[C]),
- case lists:member(intersection,C) of
- true ->
- constraint_intersection1(S,C,[]);
- _ ->
- C
+resolve_value1(S, HostType, #'Externalvaluereference'{value=Name}=ERef) ->
+ case resolve_namednumber(S, HostType, Name) of
+ V when is_integer(V) ->
+ V;
+ not_named ->
+ resolve_value1(S, HostType, get_referenced_value(S, ERef))
end;
-constraint_intersection(_S,C) ->
- [C].
-
-constraint_intersection1(S,[A,intersection,B|Rest],Acc) ->
- AisecB = c_intersect(S,A,B),
- constraint_intersection1(S, AisecB++Rest, Acc);
-constraint_intersection1(S,[A|Rest],Acc) ->
- constraint_intersection1(S,Rest,[A|Acc]);
-constraint_intersection1(_, [], [C]) ->
- C;
-constraint_intersection1(_,[],Acc) ->
- lists:reverse(Acc).
-
-c_intersect(S,C1={'SingleValue',_},C2={'SingleValue',_}) ->
- intersection_of_sv(S,[C1,C2]);
-c_intersect(S,C1={'ValueRange',_},C2={'ValueRange',_}) ->
- intersection_of_vr(S,[C1,C2]);
-c_intersect(S,C1={'ValueRange',_},C2={'SingleValue',_}) ->
- intersection_sv_vr(S,[C2],[C1]);
-c_intersect(S,C1={'SingleValue',_},C2={'ValueRange',_}) ->
- intersection_sv_vr(S,[C1],[C2]);
-c_intersect(_S,C1,C2) ->
- [C1,C2].
-
-%% combine_constraints(S,SV,VR,CComb)
-%% Types:
-%% S = is_record(state,S)
-%% SV = [] | [SVC]
-%% VR = [] | [VRC]
-%% CComb = [] | [Lists]
-%% SVC = {'SingleValue',integer()} | {'SingleValue',[integer(),...]}
-%% VRC = {'ValueRange',{Lb,Ub}}
-%% Lists = List of lists containing any constraint combination
-%% Lb = 'MIN' | integer()
-%% Ub = 'MAX' | integer()
-%% Returns a combination of the least common constraint among SV,VR and all
-%% elements in CComb
-combine_constraints(_S,[],VR,CComb) ->
- VR ++ CComb;
-% combine_combined_cnstr(S,VR,CComb);
-combine_constraints(_S,SV,[],CComb) ->
- SV ++ CComb;
-% combine_combined_cnstr(S,SV,CComb);
-combine_constraints(S,SV,VR,CComb) ->
- C=intersection_sv_vr(S,SV,VR),
- C ++ CComb.
-% combine_combined_cnstr(S,C,CComb).
-
-intersection_sv_vr(_S,[C1={'SingleValue',SV}],[C2={'ValueRange',{_Lb,_Ub}}])
- when is_integer(SV) ->
- case is_int_in_vr(SV,C2) of
- true -> [C1];
- _ -> %%error({type,{"asn1 illegal constraint",C1,C2},S})
- %throw({error,{"asn1 illegal constraint",C1,C2}})
- %io:format("warning: could not analyze constraint ~p~n",[[C1,C2]]),
- [C1,C2]
+resolve_value1(S, HostType, {gt,V}) ->
+ case resolve_value1(S, HostType, V) of
+ Int when is_integer(Int) ->
+ Int + 1;
+ _Other ->
+ asn1_error(S, illegal_integer_value)
end;
-intersection_sv_vr(_S,[C1={'SingleValue',SV}],[C2])
- when is_list(SV) ->
- case lists:filter(fun(X)->is_int_in_vr(X,C2) end,SV) of
- [] ->
- %%error({type,{"asn1 illegal constraint",C1,C2},S});
- %throw({error,{"asn1 illegal constraint",C1,C2}});
- %io:format("warning: could not analyze constraint ~p~n",[[C1,C2]]),
- [C1,C2];
- [V] -> [{'SingleValue',V}];
- L -> [{'SingleValue',L}]
- end.
-
-
-%% Size constraint [{'SizeConstraint',1},{'SizeConstraint',{{1,64},[]}}]
-
-intersection_of_size(_,[]) ->
- [];
-intersection_of_size(_,C=[_SZ]) ->
- C;
-intersection_of_size(S,[SZ,SZ|Rest]) ->
- intersection_of_size(S,[SZ|Rest]);
-intersection_of_size(S,C=[C1={_,Int},{_,Range}|Rest])
- when is_integer(Int),is_tuple(Range) ->
- case Range of
- {Lb,Ub} when Int >= Lb,
- Int =< Ub ->
- intersection_of_size(S,[C1|Rest]);
- {{Lb,Ub},Ext} when is_list(Ext),Int >= Lb,Int =< Ub ->
- intersection_of_size(S,[C1|Rest]);
- _ ->
- throw({error,{asn1,{illegal_size_constraint,C}}})
+resolve_value1(S, HostType, {lt,V}) ->
+ case resolve_value1(S, HostType, V) of
+ Int when is_integer(Int) ->
+ Int - 1;
+ _Other ->
+ asn1_error(S, illegal_integer_value)
end;
-intersection_of_size(S,[C1={_,Range},C2={_,Int}|Rest])
- when is_integer(Int),is_tuple(Range) ->
- intersection_of_size(S,[C2,C1|Rest]);
-intersection_of_size(S,[{_,{Lb1,Ub1}},{_,{Lb2,Ub2}}|Rest]) ->
- Lb=greatest_LB(ordsets:from_list([Lb1,Lb2])),
- Ub=smallest_UB(ordsets:from_list([Ub1,Ub2])),
- intersection_of_size(S,[{'SizeConstraint',{Lb,Ub}}|Rest]);
-intersection_of_size(_,SZ) ->
- throw({error,{asn1,{illegal_size_constraint,SZ}}}).
-
-intersection_of_vr(_,[]) ->
- [];
-intersection_of_vr(_,VR=[_C]) ->
- VR;
-intersection_of_vr(S,[{_,{Lb1,Ub1}},{_,{Lb2,Ub2}}|Rest]) ->
- Lb=greatest_LB(ordsets:from_list([Lb1,Lb2])),
- Ub=smallest_UB(ordsets:from_list([Ub1,Ub2])),
- intersection_of_vr(S,[{'ValueRange',{Lb,Ub}}|Rest]);
-intersection_of_vr(_S,VR) ->
- %%error({type,{asn1,{illegal_value_range_constraint,VR}},S});
- throw({error,{asn1,{illegal_value_range_constraint,VR}}}).
-
-intersection_of_sv(_,[]) ->
- [];
-intersection_of_sv(_,SV=[_C]) ->
- SV;
-intersection_of_sv(S,[SV,SV|Rest]) ->
- intersection_of_sv(S,[SV|Rest]);
-intersection_of_sv(S,[{_,Int},{_,SV}|Rest]) when is_integer(Int),
- is_list(SV) ->
- SV2=intersection_of_sv1(S,Int,SV),
- intersection_of_sv(S,[SV2|Rest]);
-intersection_of_sv(S,[{_,SV},{_,Int}|Rest]) when is_integer(Int),
- is_list(SV) ->
- SV2=intersection_of_sv1(S,Int,SV),
- intersection_of_sv(S,[SV2|Rest]);
-intersection_of_sv(S,[{_,SV1},{_,SV2}|Rest]) when is_list(SV1),
- is_list(SV2) ->
- SV3=common_set(SV1,SV2),
- intersection_of_sv(S,[SV3|Rest]);
-intersection_of_sv(_S,SV) ->
- %%error({type,{asn1,{illegal_single_value_constraint,SV}},S}).
- throw({error,{asn1,{illegal_single_value_constraint,SV}}}).
-
-intersection_of_sv1(_S,Int,SV) when is_integer(Int),is_list(SV) ->
- case lists:member(Int,SV) of
- true -> {'SingleValue',Int};
+resolve_value1(S, _HostType, {'ValueFromObject',{object,Object},FieldName}) ->
+ get_value_from_object(S, Object, FieldName);
+resolve_value1(_, _, #valuedef{checked=true,value=V}) ->
+ V;
+resolve_value1(S, _, #valuedef{value={'ValueFromObject',
+ {object,Object},FieldName}}) ->
+ get_value_from_object(S, Object, FieldName);
+resolve_value1(S, _HostType, #valuedef{}=VDef) ->
+ #valuedef{value=Val} = check_value(S,VDef),
+ Val;
+resolve_value1(_, _, V) ->
+ V.
+
+resolve_namednumber(S, #type{def=Def}, Name) ->
+ case Def of
+ {'ENUMERATED',NameList} ->
+ resolve_namednumber_1(S, Name, NameList);
+ {'INTEGER',NameList} ->
+ resolve_namednumber_1(S, Name, NameList);
_ ->
- %%error({type,{asn1,{illegal_single_value_constraint,Int,SV}},S})
- throw({error,{asn1,{illegal_single_value_constraint,Int,SV}}})
- end;
-intersection_of_sv1(_S,SV1,SV2) ->
- %%error({type,{asn1,{illegal_single_value_constraint,SV1,SV2}},S}).
- throw({error,{asn1,{illegal_single_value_constraint,SV1,SV2}}}).
+ not_named
+ end.
-greatest_LB([H]) ->
- H;
-greatest_LB(L) ->
- greatest_LB1(lists:reverse(L)).
-greatest_LB1(['MIN',H2|_T])->
- H2;
-greatest_LB1([H|_T]) ->
- H.
-smallest_UB(L) ->
- hd(L).
-
-common_set(SV1,SV2) ->
- lists:filter(fun(X)->lists:member(X,SV1) end,SV2).
-
-is_int_in_vr(Int,{_,{'MIN','MAX'}}) when is_integer(Int) ->
- true;
-is_int_in_vr(Int,{_,{'MIN',Ub}}) when is_integer(Int),Int =< Ub ->
- true;
-is_int_in_vr(Int,{_,{Lb,'MAX'}}) when is_integer(Int),Int >= Lb ->
- true;
-is_int_in_vr(Int,{_,{Lb,Ub}}) when is_integer(Int),Int >= Lb,Int =< Ub ->
- true;
-is_int_in_vr(_,_) ->
- false.
-
+resolve_namednumber_1(S, Name, NameList) ->
+ try
+ NamedNumberList = check_enumerated(S, NameList),
+ {_,N} = lookup_enum_value(S, Name, NamedNumberList),
+ N
+ catch _:_ ->
+ not_named
+ end.
+
+%%%
+%%% End of constraint handling.
+%%%
check_imported(S,Imodule,Name) ->
check_imported(S,Imodule,Name,false).
@@ -4510,18 +3760,28 @@ check_reference(S,#'Externaltypereference'{pos=Pos,module=Emod,type=Name}) ->
#'Externaltypereference'{pos=Pos,module=ModName,type=Name}
end.
+get_referenced_value(S, T) ->
+ case get_referenced_type(S, T) of
+ {ExtMod,#valuedef{value=#'Externalvaluereference'{}=Ref}} ->
+ get_referenced_value(update_state(S, ExtMod), Ref);
+ {_,#valuedef{value=Val}} ->
+ Val
+ end.
+
get_referenced_type(S, T) ->
+ get_referenced_type(S, T, false).
+
+get_referenced_type(S, T, Recurse) ->
case do_get_referenced_type(S, T) of
- {_,#type{def=#'Externaltypereference'{}=ERef}} ->
- get_referenced_type(S, ERef);
- {_,#type{def=#'Externalvaluereference'{}=VRef}} ->
- get_referenced_type(S, VRef);
+ {_,#typedef{typespec=#type{def=#'Externaltypereference'{}=ERef}}}
+ when Recurse ->
+ get_referenced_type(S, ERef, Recurse);
{_,_}=Res ->
Res
end.
-do_get_referenced_type(#state{parameters=Ps}=S, T0) ->
- case match_parameters(S, T0, Ps) of
+do_get_referenced_type(S, T0) ->
+ case match_parameter(S, T0) of
T0 ->
do_get_ref_type_1(S, T0);
T ->
@@ -4563,7 +3823,7 @@ get_referenced(S,Emod,Ename,Pos) ->
%% May be an imported entity in module Emod or Emod may not exist
case asn1_db:dbget(Emod,'MODULE') of
undefined ->
- throw({error,{asn1,{module_not_found,Emod}}});
+ asn1_error(S, {undefined_import, Ename, Emod});
_ ->
NewS = update_state(S,Emod),
get_imported(NewS,Ename,Emod,Pos)
@@ -4593,12 +3853,11 @@ get_imported(S,Name,Module,Pos) ->
parse_and_save(S,Imodule),
case asn1_db:dbget(Imodule,'MODULE') of
undefined ->
- throw({error,{asn1,{module_not_found,Imodule}}});
+ asn1_error(S, {undefined_import, Name, Module});
Im when is_record(Im,module) ->
case is_exported(Im,Name) of
false ->
- throw({error,
- {asn1,{not_exported,{Im,Name}}}});
+ asn1_error(S, {undefined_export, Name});
_ ->
?dbg("get_imported, is_exported ~p, ~p~n",[Imodule,Name]),
get_referenced_type(S,
@@ -4611,37 +3870,6 @@ get_imported(S,Name,Module,Pos) ->
get_renamed_reference(S,Name,Module)
end.
-check_and_save(S,#'Externaltypereference'{module=M}=ERef,#typedef{checked=false}=TDef,Settings)
- when S#state.mname /= M ->
- %% This ERef is an imported type (or maybe a set.asn compilation)
- NewS = S#state{mname=M,module=load_asn1_module(S,M),
- type=TDef,tname=get_datastr_name(TDef)},
- Type=check_type(NewS,TDef,TDef#typedef.typespec),%XXX
- CheckedTDef = TDef#typedef{checked=true,
- typespec=Type},
- asn1_db:dbput(M,get_datastr_name(TDef),CheckedTDef),
- {merged_name(S,ERef),Settings};
-check_and_save(S,#'Externaltypereference'{module=M,type=N}=Eref,
- #ptypedef{name=Name,args=Params} = PTDef,Settings) ->
- %% instantiate a parameterized type
- %% The parameterized type should be saved as a type in the module
- %% it was instantiated.
- NewS = S#state{mname=M,module=load_asn1_module(S,M),
- type=PTDef,tname=Name},
- {Args,RestSettings} = lists:split(length(Params),Settings),
- Type = check_type(NewS,PTDef,#type{def={pt,Eref,Args}}),
- ERefName = new_reference_name(N),
- ERefNew = #'Externaltypereference'{type=ERefName,module=S#state.mname},
- NewTDef=#typedef{checked=true,name=ERefName,
- typespec=Type},
- insert_once(S,parameterized_objects,{ERefName,type,NewTDef}),
- asn1_db:dbput(S#state.mname,ERefNew#'Externaltypereference'.type,
- NewTDef),
- {ERefNew,RestSettings};
-check_and_save(_S,ERef,TDef,Settings) ->
- %% This might be a renamed type in a set of specs, so rename the ERef
- {ERef#'Externaltypereference'{type=asn1ct:get_name_of_def(TDef)},Settings}.
-
save_object_set_instance(S,Name,ObjSetSpec)
when is_record(ObjSetSpec,'ObjectSet') ->
NewObjSet = #typedef{checked=true,name=Name,typespec=ObjSetSpec},
@@ -4708,18 +3936,14 @@ update_state(S,ModuleName) ->
S;
_ ->
parse_and_save(S,ModuleName),
- case asn1_db:dbget(ModuleName,'MODULE') of
- RefedMod when is_record(RefedMod,module) ->
- S#state{mname=ModuleName,module=RefedMod};
- _ -> throw({error,{asn1,{module_does_not_exist,ModuleName}}})
- end
+ Mod = #module{} = asn1_db:dbget(ModuleName,'MODULE'),
+ S#state{mname=ModuleName,module=Mod}
end.
-
get_renamed_reference(S,Name,Module) ->
case renamed_reference(S,Name,Module) of
undefined ->
- throw({error,{asn1,{undefined_type,Name}}});
+ asn1_error(S, {undefined, Name});
NewTypeName when NewTypeName =/= Name ->
get_referenced1(S,Module,NewTypeName,undefined)
end.
@@ -4770,37 +3994,49 @@ get_importmoduleoftype([I|Is],Name) ->
get_importmoduleoftype([],_) ->
undefined.
+match_parameters(S, Names) ->
+ [match_parameter(S, Name) || Name <- Names].
-match_parameters(_S,Name,[]) ->
- Name;
+match_parameter(#state{parameters=Ps}=S, Name) ->
+ match_parameter(S, Name, Ps).
-match_parameters(_S,#'Externaltypereference'{type=Name},[{#'Externaltypereference'{type=Name},NewName}|_T]) ->
+match_parameter(_S, Name, []) ->
+ Name;
+match_parameter(S, {valueset,{element_set,#type{}=Ts,none}}, Ps) ->
+ match_parameter(S, {valueset,Ts}, Ps);
+match_parameter(_S, #'Externaltypereference'{type=Name},
+ [{#'Externaltypereference'{type=Name},NewName}|_T]) ->
NewName;
-match_parameters(_S,#'Externaltypereference'{type=Name},[{{_,#'Externaltypereference'{type=Name}},NewName}|_T]) ->
+match_parameter(_S, #'Externaltypereference'{type=Name},
+ [{{_,#'Externaltypereference'{type=Name}},NewName}|_T]) ->
NewName;
-match_parameters(_S,#'Externalvaluereference'{value=Name},[{#'Externalvaluereference'{value=Name},NewName}|_T]) ->
+match_parameter(_S, #'Externalvaluereference'{value=Name},
+ [{#'Externalvaluereference'{value=Name},NewName}|_T]) ->
NewName;
-match_parameters(_S,#'Externalvaluereference'{value=Name},[{{_,#'Externalvaluereference'{value=Name}},NewName}|_T]) ->
+match_parameter(_S, #'Externalvaluereference'{value=Name},
+ [{{_,#'Externalvaluereference'{value=Name}},NewName}|_T]) ->
NewName;
-match_parameters(_S,#type{def=#'Externaltypereference'{module=M,type=Name}},
- [{#'Externaltypereference'{module=M,type=Name},Type}]) ->
+match_parameter(_S, #type{def=#'Externaltypereference'{module=M,type=Name}},
+ [{#'Externaltypereference'{module=M,type=Name},Type}]) ->
Type;
-match_parameters(_S,{valueset,#type{def=#'Externaltypereference'{type=Name}}},
- [{{_,#'Externaltypereference'{type=Name}},{valueset,#type{def=NewName}}}|_T]) ->
+match_parameter(_S, {valueset,#type{def=#'Externaltypereference'{type=Name}}},
+ [{{_,#'Externaltypereference'{type=Name}},
+ {valueset,#type{def=NewName}}}|_T]) ->
NewName;
-match_parameters(_S,{valueset,#type{def=#'Externaltypereference'{type=Name}}},
- [{{_,#'Externaltypereference'{type=Name}},
- NewName=#type{def=#'Externaltypereference'{}}}|_T]) ->
+match_parameter(_S, {valueset,#type{def=#'Externaltypereference'{type=Name}}},
+ [{{_,#'Externaltypereference'{type=Name}},
+ NewName=#type{def=#'Externaltypereference'{}}}|_T]) ->
NewName#type.def;
-match_parameters(_S,{valueset,#type{def=#'Externaltypereference'{type=Name}}},
- [{{_,#'Externaltypereference'{type=Name}},NewName}|_T]) ->
+match_parameter(_S, {valueset,#type{def=#'Externaltypereference'{type=Name}}},
+ [{{_,#'Externaltypereference'{type=Name}},NewName}|_T]) ->
NewName;
%% When a parameter is a parameterized element it has to be
%% instantiated now!
-match_parameters(S,{valueset,T=#type{def={pt,_,_Args}}},_Parameters) ->
- case catch check_type(S,#typedef{name=S#state.tname,typespec=T},T) of
- pobjectsetdef ->
-
+match_parameter(S, {valueset,T=#type{def={pt,_,_Args}}}, _Ps) ->
+ try check_type(S,#typedef{name=S#state.tname,typespec=T},T) of
+ #type{def=Ts} ->
+ Ts
+ catch pobjectsetdef ->
{_,ObjRef,_Params} = T#type.def,
{_,ObjDef}=get_referenced_type(S,ObjRef),
%%ObjDef is a pvaluesetdef where the type field holds the class
@@ -4818,17 +4054,15 @@ match_parameters(S,{valueset,T=#type{def={pt,_,_Args}}},_Parameters) ->
ObjectSet = #'ObjectSet'{class=RightClassRef,set=T},
ObjSpec = check_object(S,#typedef{typespec=ObjectSet},ObjectSet),
Name = list_to_atom(asn1ct_gen:list2name([get_datastr_name(ObjDef)|S#state.recordtopname])),
- save_object_set_instance(S,Name,ObjSpec);
- pvaluesetdef -> error({pvaluesetdef,"parameterized valueset",S});
- {error,_Reason} -> error({type,"error in parameter",S});
- Ts when is_record(Ts,type) -> Ts#type.def
+ save_object_set_instance(S,Name,ObjSpec)
end;
+
%% same as previous, only depends on order of parsing
-match_parameters(S,{valueset,{pos,{objectset,_,POSref},Args}},Parameters) ->
- match_parameters(S,{valueset,#type{def={pt,POSref,Args}}},Parameters);
-match_parameters(S,Name, [_H|T]) ->
- %%io:format("match_parameters(~p,~p)~n",[Name,[H|T]]),
- match_parameters(S,Name,T).
+match_parameter(S, {valueset,{pos,{objectset,_,POSref},Args}}, Ps) ->
+ match_parameter(S, {valueset,#type{def={pt,POSref,Args}}}, Ps);
+match_parameter(S, Name, [_H|T]) ->
+ %%io:format("match_parameter(~p,~p)~n",[Name,[H|T]]),
+ match_parameter(S, Name, T).
imported(S,Name) ->
{imports,Ilist} = (S#state.module)#module.imports,
@@ -4854,7 +4088,6 @@ check_named_number_list(_S, [{_,_}|_]=NNL) ->
NNL;
check_named_number_list(S, NNL0) ->
%% Check that the names are unique.
- T = S#state.type,
case check_unique(NNL0, 2) of
[] ->
NNL1 = [{Id,resolve_valueref(S, Val)} || {'NamedNumber',Id,Val} <- NNL0],
@@ -4863,14 +4096,14 @@ check_named_number_list(S, NNL0) ->
[] ->
NNL;
[Val|_] ->
- asn1_error(S, T, {value_reused,Val})
+ asn1_error(S, {value_reused,Val})
end;
[H|_] ->
- asn1_error(S, T, {namelist_redefinition,H})
+ asn1_error(S, {namelist_redefinition,H})
end.
-resolve_valueref(S, #'Externalvaluereference'{module=Mod,value=Name}) ->
- dbget_ex(S, Mod, Name);
+resolve_valueref(S, #'Externalvaluereference'{} = T) ->
+ get_referenced_value(S, T);
resolve_valueref(_, Val) when is_integer(Val) ->
Val.
@@ -4879,7 +4112,7 @@ check_integer(S, NNL) ->
check_bitstring(S, NNL0) ->
NNL = check_named_number_list(S, NNL0),
- _ = [asn1_error(S, S#state.type, {invalid_bit_number,Bit}) ||
+ _ = [asn1_error(S, {invalid_bit_number,Bit}) ||
{_,Bit} <- NNL, Bit < 0],
NNL.
@@ -4904,7 +4137,7 @@ check_type_identifier(S, Eref=#'Externaltypereference'{type=Class}) ->
{_,TD=#typedef{typespec=#type{def=#'Externaltypereference'{}}}} ->
check_type_identifier(S, (TD#typedef.typespec)#type.def);
_ ->
- asn1_error(S, S#state.type, {illegal_instance_of,Class})
+ asn1_error(S, {illegal_instance_of,Class})
end.
iof_associated_type(S,[]) ->
@@ -4913,12 +4146,7 @@ iof_associated_type(S,[]) ->
case get(instance_of) of
undefined ->
AssociateSeq = iof_associated_type1(S,[]),
- Tag =
- case S#state.erule of
- ber ->
- [?TAG_CONSTRUCTED(?N_INSTANCE_OF)];
- _ -> []
- end,
+ Tag = [?TAG_CONSTRUCTED(?N_INSTANCE_OF)],
TypeDef=#typedef{checked=true,
name='INSTANCE OF',
typespec=#type{tag=Tag,
@@ -4944,16 +4172,11 @@ iof_associated_type1(S,C) ->
[] -> 'ASN1_OPEN_TYPE';
_ -> {typefield,'Type'}
end,
- {ObjIdTag,C1TypeTag}=
- case S#state.erule of
- ber ->
- {[{'UNIVERSAL',8}],
- [#tag{class='UNIVERSAL',
- number=6,
- type='IMPLICIT',
- form=0}]};
- _ -> {[{'UNIVERSAL','INTEGER'}],[]}
- end,
+ ObjIdTag = [{'UNIVERSAL',8}],
+ C1TypeTag = [#tag{class='UNIVERSAL',
+ number=6,
+ type='IMPLICIT',
+ form=0}],
TypeIdentifierRef=#'Externaltypereference'{module=ModuleName,
type='TYPE-IDENTIFIER'},
ObjectIdentifier =
@@ -4992,9 +4215,13 @@ iof_associated_type1(S,C) ->
%% returns the leading attribute, the constraint of the components and
%% the tablecinf value for the second component.
-instance_of_constraints(_,[]) ->
+instance_of_constraints(_, []) ->
{false,[],[],[]};
-instance_of_constraints(S, [{simpletable,Type}]) ->
+instance_of_constraints(S, [{element_set,{simpletable,C},none}]) ->
+ {element_set,Type,none} = C,
+ instance_of_constraints_1(S, Type).
+
+instance_of_constraints_1(S, Type) ->
#type{def=#'Externaltypereference'{type=Name}} = Type,
ModuleName = S#state.mname,
ObjectSetRef=#'Externaltypereference'{module=ModuleName,
@@ -5014,93 +4241,100 @@ instance_of_constraints(S, [{simpletable,Type}]) ->
valueindex=[]},
{TableCInf,[{simpletable,Name}],CRel,[{objfun,ObjectSetRef}]}.
-%% Check ENUMERATED
-%% ****************************************
-%% Check that all values are unique
-%% assign values to un-numbered identifiers
-%% check that the constraints are allowed and correct
-%% put the updated info back into database
-check_enumerated(_S,[{Name,Number}|_Rest]= NNList,_Constr) when is_atom(Name), is_integer(Number)->
- %% already checked , just return the same list
- NNList;
-check_enumerated(_S,{[{Name,Number}|_Rest],L}= NNList,_Constr) when is_atom(Name), is_integer(Number), is_list(L)->
- %% already checked , contains extension marker, just return the same lists
- NNList;
-check_enumerated(S,NamedNumberList,_Constr) ->
- check_enum(S,NamedNumberList,[],[],[]).
-
-%% identifiers are put in Acc2
-%% returns either [{Name,Number}] or {[{Name,Number}],[{ExtName,ExtNumber}]}
-%% the latter is returned if the ENUMERATION contains EXTENSIONMARK
-check_enum(S,[{'NamedNumber',Id,Num}|T],Acc1,Acc2,Root) when is_integer(Num) ->
- check_enum(S,T,[{Id,Num}|Acc1],Acc2,Root);
-check_enum(S,['EXTENSIONMARK'|T],Acc1,Acc2,_Root) ->
- NewAcc2 = lists:keysort(2,Acc1),
- NewList = enum_number(lists:reverse(Acc2),NewAcc2,0,[],[]),
- { NewList, check_enum(S,T,[],[],enum_counts(NewList))};
-check_enum(S,[Id|T],Acc1,Acc2,Root) when is_atom(Id) ->
- check_enum(S,T,Acc1,[Id|Acc2],Root);
-check_enum(_S,[],Acc1,Acc2,Root) ->
- NewAcc2 = lists:keysort(2,Acc1),
- enum_number(lists:reverse(Acc2),NewAcc2,0,[],Root).
-
-
-% assign numbers to identifiers , numbers from 0 ... but must not
-% be the same as already assigned to NamedNumbers
-enum_number(Identifiers,NamedNumbers,Cnt,Acc,[]) ->
- enum_number(Identifiers,NamedNumbers,Cnt,Acc);
-enum_number(Identifiers,NamedNumbers,_Cnt,Acc,CountL) ->
- enum_extnumber(Identifiers,NamedNumbers,Acc,CountL).
-
-enum_number([H|T],[{Id,Num}|T2],Cnt,Acc) when Num > Cnt ->
- enum_number(T,[{Id,Num}|T2],Cnt+1,[{H,Cnt}|Acc]);
-enum_number([H|T],[{Id,Num}|T2],Cnt,Acc) when Num < Cnt -> % negative Num
- enum_number(T,T2,Cnt+1,[{H,Cnt},{Id,Num}|Acc]);
-enum_number([],L2,_Cnt,Acc) ->
- lists:append([lists:reverse(Acc),L2]);
-enum_number(L,[{Id,Num}|T2],Cnt,Acc) -> % Num == Cnt
- enum_number(L,T2,Cnt+1,[{Id,Num}|Acc]);
-enum_number([H|T],[],Cnt,Acc) ->
- enum_number(T,[],Cnt+1,[{H,Cnt}|Acc]).
-
-enum_extnumber(Identifiers,NamedNumbers,Acc,[C]) ->
- check_add_enum_numbers(NamedNumbers,[C]),
- enum_number(Identifiers,NamedNumbers,C,Acc);
-enum_extnumber([H|T],[{Id,Num}|T2],Acc,[C|Counts]) when Num > C ->
- enum_extnumber(T,[{Id,Num}|T2],[{H,C}|Acc],Counts);
-enum_extnumber([],L2,Acc,Cnt) ->
- check_add_enum_numbers(L2, Cnt),
- lists:concat([lists:reverse(Acc),L2]);
-enum_extnumber(_Identifiers,[{Id,Num}|_T2],_Acc,[C|_]) when Num < C ->
-%% enum_extnumber(Identifiers,T2,[{Id,Num}|Acc],Counts);
- exit({error,{asn1,"AdditionalEnumeration element with same number as root element",{Id,Num}}});
-enum_extnumber(Identifiers,[{Id,Num}|T2],Acc,[_C|Counts]) -> % Num =:= C
- enum_extnumber(Identifiers,T2,[{Id,Num}|Acc],Counts);
-enum_extnumber([H|T],[],Acc,[C|Counts]) ->
- enum_extnumber(T,[],[{H,C}|Acc],Counts).
-
-enum_counts([]) ->
- [0];
-enum_counts(L) ->
- Used=[I||{_,I}<-L],
- AddEnumLb = lists:max(Used) + 1,
- lists:foldl(fun(El,AccIn)->lists:delete(El,AccIn) end,
- lists:seq(0,AddEnumLb),
- Used).
-check_add_enum_numbers(L, Cnt) ->
- Max = lists:max(Cnt),
- Fun = fun({_,N}=El) when N < Max ->
- case lists:member(N,Cnt) of
- false ->
- exit({error,{asn1,"AdditionalEnumeration element with same number as root element",El}});
- _ ->
- ok
- end;
- (_) ->
- ok
- end,
- lists:foreach(Fun,L).
+%%%
+%%% Check ENUMERATED.
+%%%
+check_enumerated(_S, [{Name,Number}|_]=NNL)
+ when is_atom(Name), is_integer(Number) ->
+ %% Already checked.
+ NNL;
+check_enumerated(_S, {[{Name,Number}|_],L}=NNL)
+ when is_atom(Name), is_integer(Number), is_list(L) ->
+ %% Already checked (with extension).
+ NNL;
+check_enumerated(S, NNL) ->
+ check_enum_ids(S, NNL, gb_sets:empty()),
+ check_enum(S, NNL, gb_sets:empty(), []).
+
+check_enum_ids(S, [{'NamedNumber',Id,_}|T], Ids0) ->
+ Ids = check_enum_update_ids(S, Id, Ids0),
+ check_enum_ids(S, T, Ids);
+check_enum_ids(S, ['EXTENSIONMARK'|T], Ids) ->
+ check_enum_ids(S, T, Ids);
+check_enum_ids(S, [Id|T], Ids0) when is_atom(Id) ->
+ Ids = check_enum_update_ids(S, Id, Ids0),
+ check_enum_ids(S, T, Ids);
+check_enum_ids(_, [], _) ->
+ ok.
+
+check_enum(S, [{'NamedNumber',Id,N}|T], Used0, Acc) ->
+ Used = check_enum_update_used(S, Id, N, Used0),
+ check_enum(S, T, Used, [{Id,N}|Acc]);
+check_enum(S, ['EXTENSIONMARK'|Ext0], Used0, Acc0) ->
+ Acc = lists:reverse(Acc0),
+ {Root,Used,Cnt} = check_enum_number_root(Acc, Used0, 0, []),
+ Ext = check_enum_ext(S, Ext0, Used, Cnt, []),
+ {Root,Ext};
+check_enum(S, [Id|T], Used, Acc) when is_atom(Id) ->
+ check_enum(S, T, Used, [Id|Acc]);
+check_enum(_, [], Used, Acc0) ->
+ Acc = lists:reverse(Acc0),
+ {Root,_,_} = check_enum_number_root(Acc, Used, 0, []),
+ lists:keysort(2, Root).
+
+check_enum_number_root([Id|T]=T0, Used0, Cnt, Acc) when is_atom(Id) ->
+ case gb_sets:is_element(Cnt, Used0) of
+ false ->
+ Used = gb_sets:insert(Cnt, Used0),
+ check_enum_number_root(T, Used, Cnt+1, [{Id,Cnt}|Acc]);
+ true ->
+ check_enum_number_root(T0, Used0, Cnt+1, Acc)
+ end;
+check_enum_number_root([H|T], Used, Cnt, Acc) ->
+ check_enum_number_root(T, Used, Cnt, [H|Acc]);
+check_enum_number_root([], Used, Cnt, Acc) ->
+ {lists:keysort(2, Acc),Used,Cnt}.
+
+check_enum_ext(S, [{'NamedNumber',Id,N}|T], Used0, C, Acc) ->
+ Used = check_enum_update_used(S, Id, N, Used0),
+ if
+ N < C ->
+ asn1_error(S, {enum_not_ascending,Id,N,C-1});
+ true ->
+ ok
+ end,
+ check_enum_ext(S, T, Used, N+1, [{Id,N}|Acc]);
+check_enum_ext(S, [Id|T]=T0, Used0, C, Acc) when is_atom(Id) ->
+ case gb_sets:is_element(C, Used0) of
+ true ->
+ check_enum_ext(S, T0, Used0, C+1, Acc);
+ false ->
+ Used = gb_sets:insert(C, Used0),
+ check_enum_ext(S, T, Used, C+1, [{Id,C}|Acc])
+ end;
+check_enum_ext(_, [], _, _, Acc) ->
+ lists:keysort(2, Acc).
+
+check_enum_update_ids(S, Id, Ids) ->
+ case gb_sets:is_element(Id, Ids) of
+ false ->
+ gb_sets:insert(Id, Ids);
+ true ->
+ asn1_error(S, {enum_illegal_redefinition,Id})
+ end.
+
+check_enum_update_used(S, Id, N, Used) ->
+ case gb_sets:is_element(N, Used) of
+ false ->
+ gb_sets:insert(N, Used);
+ true ->
+ asn1_error(S, {enum_reused_value,Id,N})
+ end.
+
+%%%
+%%% End of ENUMERATED checking.
+%%%
check_boolean(_S,_Constr) ->
ok.
@@ -5145,7 +4379,7 @@ check_sequence(S,Type,Comps) ->
CompListTuple = complist_as_tuple(NewComps4),
{CRelInf,CompListTuple};
Dupl ->
- throw({error,{asn1,{duplicate_components,Dupl}}})
+ asn1_error(S, {duplicate_identifier, error_value(hd(Dupl))})
end.
complist_as_tuple(CompList) ->
@@ -5155,8 +4389,6 @@ complist_as_tuple([#'EXTENSIONMARK'{}|T], Acc, Ext, Acc2, root) ->
complist_as_tuple(T, Acc, Ext, Acc2, ext);
complist_as_tuple([#'EXTENSIONMARK'{}|T], Acc, Ext, Acc2, ext) ->
complist_as_tuple(T, Acc, Ext, Acc2, root2);
-complist_as_tuple([#'EXTENSIONMARK'{}|_T], _Acc, _Ext, _Acc2, root2) ->
- throw({error,{asn1,{too_many_extension_marks}}});
complist_as_tuple([C|T], Acc, Ext, Acc2, root) ->
complist_as_tuple(T, [C|Acc], Ext, Acc2, root);
complist_as_tuple([C|T], Acc, Ext, Acc2, ext) ->
@@ -5199,11 +4431,11 @@ expand_components2(S,{_,PT={pt,_,_}}) ->
expand_components2(S,{_,OCFT = #'ObjectClassFieldType'{}}) ->
UncheckedType = #type{def=OCFT},
Type = check_type(S,#typedef{typespec=UncheckedType},UncheckedType),
- expand_components2(S,{undefined,oCFT_def(S,Type)});
+ expand_components2(S, {undefined,ocft_def(Type)});
expand_components2(S,{_,ERef}) when is_record(ERef,'Externaltypereference') ->
expand_components2(S,get_referenced_type(S,ERef));
-expand_components2(_S,Err) ->
- throw({error,{asn1,{illegal_COMPONENTS_OF,Err}}}).
+expand_components2(S,{_, What}) ->
+ asn1_error(S, {illegal_COMPONENTS_OF, error_value(What)}).
take_only_rootset([])->
[];
@@ -5252,7 +4484,7 @@ check_sequenceof(S,Type,Component) when is_record(Component,type) ->
check_set(S,Type,Components) ->
{TableCInf,NewComponents} = check_sequence(S,Type,Components),
- check_distinct_tags(NewComponents,[]),
+ check_unique_tags(S, collect_components(NewComponents), []),
case {lists:member(der,S#state.options),S#state.erule} of
{true,_} ->
{Sorted,SortedComponents} = sort_components(der,S,NewComponents),
@@ -5264,35 +4496,21 @@ check_set(S,Type,Components) ->
{false,TableCInf,NewComponents}
end.
-
-%% check that all tags are distinct according to X.680 26.3
-check_distinct_tags({C1,C2,C3},Acc) when is_list(C1),is_list(C2),is_list(C3) ->
- check_distinct_tags(C1++C2++C3,Acc);
-check_distinct_tags({C1,C2},Acc) when is_list(C1),is_list(C2) ->
- check_distinct_tags(C1++C2,Acc);
-check_distinct_tags([#'ComponentType'{tags=[T]}|Cs],Acc) ->
- check_distinct(T,Acc),
- check_distinct_tags(Cs,[T|Acc]);
-check_distinct_tags([C=#'ComponentType'{tags=[T|Ts]}|Cs],Acc) ->
- check_distinct(T,Acc),
- check_distinct_tags([C#'ComponentType'{tags=Ts}|Cs],[T|Acc]);
-check_distinct_tags([#'ComponentType'{tags=[]}|_Cs],_Acc) ->
- throw({error,"Not distinct tags in SET"});
-check_distinct_tags([],_) ->
- ok.
-check_distinct(T,Acc) ->
- case lists:member(T,Acc) of
- true ->
- throw({error,"Not distinct tags in SET"});
- _ -> ok
- end.
+collect_components({C1,C2,C3}) ->
+ collect_components(C1++C2++C3);
+collect_components({C1,C2}) ->
+ collect_components(C1++C2);
+collect_components(Cs) ->
+ %% Assert that tags are not empty
+ [] = [EmptyTag || EmptyTag = #'ComponentType'{tags=[]} <- Cs],
+ Cs.
%% sorting in canonical order according to X.680 8.6, X.691 9.2
%% DER: all components shall be sorted in canonical order.
%% PER: only root components shall be sorted in canonical order. The
%% extension components shall remain in textual order.
%%
-sort_components(der,S=#state{tname=TypeName},Components) ->
+sort_components(der, S, Components) ->
{R1,Ext,R2} = extension(textual_order(Components)),
CompsList = case Ext of
noext -> R1;
@@ -5300,88 +4518,34 @@ sort_components(der,S=#state{tname=TypeName},Components) ->
end,
case {untagged_choice(S,CompsList),Ext} of
{false,noext} ->
- {true,sort_components1(S,TypeName,CompsList,[],[],[],[])};
+ {true,sort_components1(CompsList)};
{false,_} ->
- {true,{sort_components1(S,TypeName,CompsList,[],[],[],[]), []}};
+ {true,{sort_components1(CompsList),[]}};
{true,noext} ->
%% sort in run-time
{dynamic,R1};
_ ->
{dynamic,{R1, Ext, R2}}
end;
-sort_components(per,S=#state{tname=TypeName},Components) ->
+sort_components(per, S, Components) ->
{R1,Ext,R2} = extension(textual_order(Components)),
Root = tag_untagged_choice(S,R1++R2),
case Ext of
noext ->
- {true,sort_components1(S,TypeName,Root,[],[],[],[])};
+ {true,sort_components1(Root)};
_ ->
- {true,{sort_components1(S,TypeName,Root,[],[],[],[]),
- Ext}}
+ {true,{sort_components1(Root),Ext}}
end.
-sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'UNIVERSAL',_}|_R]}|Cs],
- UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(S,TypeName,Cs,[C|UnivAcc],ApplAcc,ContAcc,PrivAcc);
-sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'APPLICATION',_}|_R]}|Cs],
- UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(S,TypeName,Cs,UnivAcc,[C|ApplAcc],ContAcc,PrivAcc);
-sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'CONTEXT',_}|_R]}|Cs],
- UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(S,TypeName,Cs,UnivAcc,ApplAcc,[C|ContAcc],PrivAcc);
-sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'PRIVATE',_}|_R]}|Cs],
- UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(S,TypeName,Cs,UnivAcc,ApplAcc,ContAcc,[C|PrivAcc]);
-sort_components1(S,TypeName,[],UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- I = #'ComponentType'.tags,
- ascending_order_check(S,TypeName,sort_universal_type(UnivAcc)) ++
- ascending_order_check(S,TypeName,lists:keysort(I,ApplAcc)) ++
- ascending_order_check(S,TypeName,lists:keysort(I,ContAcc)) ++
- ascending_order_check(S,TypeName,lists:keysort(I,PrivAcc)).
-
-ascending_order_check(S,TypeName,Components) ->
- ascending_order_check1(S,TypeName,Components),
- Components.
-
-ascending_order_check1(S,TypeName,
- [C1 = #'ComponentType'{tags=[{_,T}|_]},
- C2 = #'ComponentType'{tags=[{_,T}|_]}|Rest]) ->
- asn1ct:warning("Indistinct tag ~p in SET ~p, components ~p and ~p~n",
- [T,TypeName,C1#'ComponentType'.name,C2#'ComponentType'.name],S,
- "Indistinct tag in SET"),
- ascending_order_check1(S,TypeName,[C2|Rest]);
-ascending_order_check1(S,TypeName,
- [C1 = #'ComponentType'{tags=[{'UNIVERSAL',T1}|_]},
- C2 = #'ComponentType'{tags=[{'UNIVERSAL',T2}|_]}|Rest]) ->
- case (decode_type(T1) == decode_type(T2)) of
- true ->
- asn1ct:warning("Indistinct tags ~p and ~p in"
- " SET ~p, components ~p and ~p~n",
- [T1,T2,TypeName,C1#'ComponentType'.name,
- C2#'ComponentType'.name],S,
- "Indistinct tags and in SET"),
- ascending_order_check1(S,TypeName,[C2|Rest]);
- _ ->
- ascending_order_check1(S,TypeName,[C2|Rest])
- end;
-ascending_order_check1(S,N,[_|Rest]) ->
- ascending_order_check1(S,N,Rest);
-ascending_order_check1(_,_,[]) ->
- ok.
-
-sort_universal_type(Components) ->
- List = lists:map(fun(C) ->
- #'ComponentType'{tags=[{_,T}|_]} = C,
- {decode_type(T),C}
- end,
- Components),
- SortedList = lists:keysort(1,List),
- lists:map(fun(X)->element(2,X) end,SortedList).
-
-decode_type(I) when is_integer(I) ->
- I;
-decode_type(T) ->
- asn1ct_gen_ber_bin_v2:decode_type(T).
+sort_components1(Cs0) ->
+ Cs1 = [{tag_key(Tag),C} || #'ComponentType'{tags=[Tag|_]}=C <- Cs0],
+ Cs = lists:sort(Cs1),
+ [C || {_,C} <- Cs].
+
+tag_key({'UNIVERSAL',Tag}) -> {0,Tag};
+tag_key({'APPLICATION',Tag}) -> {1,Tag};
+tag_key({'CONTEXT',Tag}) -> {2,Tag};
+tag_key({'PRIVATE',Tag}) -> {3,Tag}.
untagged_choice(_S,[#'ComponentType'{typespec=#type{tag=[],def={'CHOICE',_}}}|_Rest]) ->
true;
@@ -5477,35 +4641,43 @@ check_selectiontype(S,Name,#type{def=Eref})
{RefMod,TypeDef} = get_referenced_type(S,Eref),
NewS = S#state{module=load_asn1_module(S,RefMod),
mname=RefMod,
- type=TypeDef,
tname=get_datastr_name(TypeDef)},
check_selectiontype2(NewS,Name,TypeDef);
check_selectiontype(S,Name,Type=#type{def={pt,_,_}}) ->
- TName =
- case S#state.recordtopname of
- [] ->
- S#state.tname;
- N -> N
- end,
+ TName = case S#state.recordtopname of
+ [] -> S#state.tname;
+ N -> N
+ end,
TDef = #typedef{name=TName,typespec=Type},
check_selectiontype2(S,Name,TDef);
-check_selectiontype(S,Name,Type) ->
- Msg = lists:flatten(io_lib:format("SelectionType error: ~w < ~w must be a reference to a CHOICE.",[Name,Type])),
- error({type,Msg,S}).
+check_selectiontype(S, _Name, Type) ->
+ asn1_error(S, {illegal_choice_type, error_value(Type)}).
check_selectiontype2(S,Name,TypeDef) ->
NewS = S#state{recordtopname=get_datastr_name(TypeDef)},
- CheckedType = check_type(NewS,TypeDef,TypeDef#typedef.typespec),
- Components = get_choice_components(S,CheckedType#type.def),
- case lists:keysearch(Name,#'ComponentType'.name,Components) of
- {value,C} ->
- %% The selected type will have the tag of the selected type.
- _T = C#'ComponentType'.typespec;
-% T#type{tag=def_to_tag(NewS,T#type.def)};
- _ ->
- Msg = lists:flatten(io_lib:format("error checking SelectionType: ~w~n",[Name])),
- error({type,Msg,S})
+ Components =
+ try
+ CheckedType = check_type(NewS,TypeDef,TypeDef#typedef.typespec),
+ get_choice_components(S,CheckedType#type.def)
+ catch error:_ ->
+ asn1_error(S, {illegal_choice_type, error_value(TypeDef)})
+ end,
+ case lists:keyfind(Name, #'ComponentType'.name, Components) of
+ #'ComponentType'{typespec=TS} -> TS;
+ false -> asn1_error(S, {illegal_id, error_value(Name)})
end.
+
+
+get_choice_components(_S,{'CHOICE',Components}) when is_list(Components)->
+ Components;
+get_choice_components(_S,{'CHOICE',{C1,C2}}) when is_list(C1),is_list(C2) ->
+ C1++C2;
+get_choice_components(S,ERef=#'Externaltypereference'{}) ->
+ {_RefMod,TypeDef}=get_referenced_type(S,ERef),
+ #typedef{typespec=TS} = TypeDef,
+ get_choice_components(S,TS#type.def).
+
+
check_restrictedstring(_S,_Def,_Constr) ->
ok.
@@ -5538,7 +4710,7 @@ check_choice(S,Type,Components) when is_list(Components) ->
check_unique_tags(S, NewComps3),
complist_as_tuple(NewComps3);
Dupl ->
- throw({error,{asn1,{duplicate_choice_alternatives,Dupl}}})
+ asn1_error(S, {duplicate_identifier,error_value(hd(Dupl))})
end;
check_choice(_S,_,[]) ->
[].
@@ -5635,25 +4807,30 @@ check_unique_tags(S,C) ->
case (S#state.module)#module.tagdefault of
'AUTOMATIC' ->
case any_manual_tag(C) of
- false -> true;
- _ -> collect_and_sort_tags(C,[])
+ false ->
+ true;
+ true ->
+ check_unique_tags(S, C, [])
end;
_ ->
- collect_and_sort_tags(C,[])
+ check_unique_tags(S, C, [])
end.
-collect_and_sort_tags([C|Rest],Acc) when is_record(C,'ComponentType') ->
- collect_and_sort_tags(Rest,C#'ComponentType'.tags ++ Acc);
-collect_and_sort_tags([_|Rest],Acc) ->
- collect_and_sort_tags(Rest,Acc);
-collect_and_sort_tags([],Acc) ->
- {Dupl,_}= lists:mapfoldl(fun(El,El)->{{dup,El},El};(El,_Prev)-> {El,El} end,notag,lists:sort(Acc)),
- Dupl2 = [Dup|| {dup,Dup} <- Dupl],
- if
- length(Dupl2) > 0 ->
- throw({error,{asn1,{duplicates_of_the_tags,Dupl2}}});
- true ->
- true
+check_unique_tags(S, [#'ComponentType'{name=Name,tags=Tags0}|T], Acc) ->
+ Tags = [{Tag,Name} || Tag <- Tags0],
+ check_unique_tags(S, T, Tags ++ Acc);
+check_unique_tags(S, [_|T], Acc) ->
+ check_unique_tags(S, T, Acc);
+check_unique_tags(S, [], Acc) ->
+ R0 = sofs:relation(Acc),
+ R1 = sofs:relation_to_family(R0),
+ R2 = sofs:to_external(R1),
+ Dup = [Els || {_,[_,_|_]=Els} <- R2],
+ case Dup of
+ [] ->
+ ok;
+ [FirstDupl|_] ->
+ asn1_error(S, {duplicate_tags,FirstDupl})
end.
check_unique(L,Pos) ->
@@ -5795,28 +4972,18 @@ componentrelation_leadingattr(S,[C= #'ComponentType'{}|Cs],CompList,Acc,CompAcc)
{[],C};
[{ObjSet,Attr,N,ClassDef,_Path,ValueIndex}|_NewRest] ->
OS = object_set_mod_name(S,ObjSet),
- UniqueFieldName =
- case (catch get_unique_fieldname(S,#classdef{typespec=ClassDef})) of
- {error,'__undefined_',_} ->
- no_unique;
- {asn1,Msg,_} ->
- error({type,Msg,S});
- {'EXIT',Msg} ->
- error({type,{internal_error,Msg},S});
- {Other,_} -> Other
- end,
-% UsedFieldName = get_used_fieldname(S,Attr,STList),
+ UniqFN = get_unique_fieldname(S,
+ #classdef{typespec=ClassDef}),
%% Res should be done differently: even though
%% a unique field name exists it is not
%% certain that the ObjectClassFieldType of
%% the simple table constraint picks that
%% class field.
Res = #simpletableattributes{objectsetname=OS,
-%% c_name=asn1ct_gen:un_hyphen_var(Attr),
c_name=Attr,
c_index=N,
- usedclassfield=UniqueFieldName,
- uniqueclassfield=UniqueFieldName,
+ usedclassfield=UniqFN,
+ uniqueclassfield=UniqFN,
valueindex=ValueIndex},
{[Res],C#'ComponentType'{typespec=NewTSpec}}
end;
@@ -5869,7 +5036,7 @@ remove_doubles1(El,L) ->
NewL -> remove_doubles1(El,NewL)
end.
-%% get_simple_table_info searches the commponents Cs by the path from
+%% get_simple_table_info searches the components Cs by the path from
%% an at-list (third argument), and follows into a component of it if
%% necessary, to get information needed for code generating.
%%
@@ -5884,32 +5051,35 @@ remove_doubles1(El,L) ->
% %% at least one step below the outermost level, i.e. the leading
% %% information shall be on a sub level. 2) They don't have any common
% %% path.
-get_simple_table_info(S,Cs,[AtList|Rest]) ->
- [get_simple_table_info1(S,Cs,AtList,[])|get_simple_table_info(S,Cs,Rest)];
-get_simple_table_info(_,_,[]) ->
- [].
-get_simple_table_info1(S,Cs,[Cname|Cnames],Path) when is_list(Cs) ->
- case lists:keysearch(Cname,#'ComponentType'.name,Cs) of
- {value,C} ->
- get_simple_table_info1(S,C,Cnames,[Cname|Path]);
- _ ->
- error({type,"Missing expected simple table constraint",S})
- end;
-get_simple_table_info1(S,#'ComponentType'{typespec=TS},[],Path) ->
- %% In this component there must be a simple table constraint
- %% o.w. the asn1 code is wrong.
- #type{def=OCFT,constraint=Cnstr} = TS,
- case constraint_member(simpletable,Cnstr) of
- {true,{simpletable,_OSRef}} ->
- simple_table_info(S,OCFT,Path);
- _ ->
- error({type,{"missing expected simple table constraint",
- Cnstr},S})
+get_simple_table_info(S, Cs, AtLists) ->
+ [get_simple_table_info1(S, Cs, AtList, []) || AtList <- AtLists].
+
+get_simple_table_info1(S, Cs, [Cname|Cnames], Path) ->
+ #'ComponentType'{} = C =
+ lists:keyfind(Cname, #'ComponentType'.name, Cs),
+ get_simple_table_info2(S, C, Cnames, [Cname|Path]).
+
+get_simple_table_info2(S, #'ComponentType'{name=Name,typespec=TS}, [], Path) ->
+ OCFT = simple_table_get_ocft(S, Name, TS),
+ case lists:keymember(simpletable, 1, TS#type.constraint) of
+ true ->
+ simple_table_info(S, OCFT, Path);
+ false ->
+ asn1_error(S, {missing_table_constraint,Name})
end;
-get_simple_table_info1(S,#'ComponentType'{typespec=TS},Cnames,Path) ->
+get_simple_table_info2(S, #'ComponentType'{typespec=TS}, Cnames, Path) ->
Components = get_atlist_components(TS#type.def),
- get_simple_table_info1(S,Components,Cnames,Path).
-
+ get_simple_table_info1(S, Components, Cnames, Path).
+
+simple_table_get_ocft(_, _, #type{def=#'ObjectClassFieldType'{}=OCFT}) ->
+ OCFT;
+simple_table_get_ocft(S, Component, #type{constraint=Constr}) ->
+ case lists:keyfind(ocft, 1, Constr) of
+ {ocft,OCFT} ->
+ OCFT;
+ false ->
+ asn1_error(S, {missing_ocft,Component})
+ end.
simple_table_info(S,#'ObjectClassFieldType'{classname=ClRef,
class=ObjectClass,
@@ -5932,19 +5102,8 @@ simple_table_info(S,#'ObjectClassFieldType'{classname=ClRef,
CDef;
_ -> #classdef{typespec=ObjectClass}
end,
- UniqueName =
- case (catch get_unique_fieldname(S,ClassDef)) of
- {error,'__undefined_',_} -> no_unique;
- {asn1,Msg,_} ->
- error({type,Msg,S});
- {'EXIT',Msg} ->
- error({type,{internal_error,Msg},S});
- {Other,_} -> Other
- end,
- {lists:reverse(Path),ObjectClassFieldName,UniqueName};
-simple_table_info(S,Type,_) ->
- error({type,{"the type referenced by a componentrelation constraint must be a ObjectClassFieldType",Type},S}).
-
+ UniqueName = get_unique_fieldname(S, ClassDef),
+ {lists:reverse(Path),ObjectClassFieldName,UniqueName}.
%% any_component_relation searches for all component relation
%% constraints that refers to the actual level and returns a list of
@@ -5958,9 +5117,8 @@ simple_table_info(S,Type,_) ->
%% is found to check the validity of the at-list.
any_component_relation(S,[#'ComponentType'{name=CName,typespec=Type}|Cs],CNames,NamePath,Acc) ->
CRelPath =
- case constraint_member(componentrelation,Type#type.constraint) of
-%% [{componentrelation,_,AtNotation}] ->
- {true,{_,_,AtNotation}} ->
+ case lists:keyfind(componentrelation, 1, Type#type.constraint) of
+ {_,_,AtNotation} ->
%% Found component relation constraint, now check
%% whether this constraint is relevant for the level
%% where the search started
@@ -5969,7 +5127,7 @@ any_component_relation(S,[#'ComponentType'{name=CName,typespec=Type}|Cs],CNames,
%% simple table constraint from where the component
%% relation is found.
evaluate_atpath(S,NamePath,CNames,AtNot);
- _ ->
+ false ->
[]
end,
InnerAcc =
@@ -5991,11 +5149,11 @@ any_component_relation(S,[#'ComponentType'{name=CName,typespec=Type}|Cs],CNames,
any_component_relation(S,Cs,CNames,NamePath,InnerAcc++CRelPath++Acc);
any_component_relation(S,Type,CNames,NamePath,Acc) when is_record(Type,type) ->
CRelPath =
- case constraint_member(componentrelation,Type#type.constraint) of
- {true,{_,_,AtNotation}} ->
+ case lists:keyfind(componentrelation, 1, Type#type.constraint) of
+ {_,_,AtNotation} ->
AtNot = extract_at_notation(AtNotation),
evaluate_atpath(S,NamePath,CNames,AtNot);
- _ ->
+ false ->
[]
end,
InnerAcc =
@@ -6017,15 +5175,6 @@ any_component_relation(S,['ExtensionAdditionGroupEnd'|Cs],CNames,NamePath,Acc) -
any_component_relation(_,[],_,_,Acc) ->
Acc.
-constraint_member(componentrelation,[CRel={componentrelation,_,_}|_Rest]) ->
- {true,CRel};
-constraint_member(simpletable,[ST={simpletable,_}|_Rest]) ->
- {true,ST};
-constraint_member(Key,[_H|T]) ->
- constraint_member(Key,T);
-constraint_member(_,[]) ->
- false.
-
%% evaluate_atpath/4 finds out whether the at notation refers to the
%% search level. The list of referenced names in the AtNot list shall
%% begin with a name that exists on the level it refers to. If the
@@ -6059,9 +5208,7 @@ evaluate_atpath(S=#state{abscomppath=TopPath},NamePath,Cnames,{outermost,AtPath=
{_,[H|_T]} ->
case lists:member(H,Cnames) of
true -> [AtPathBelowTop];
- _ ->
- %% error({type,{asn1,"failed to analyze at-path",AtPath},S})
- throw({type,{asn1,"failed to analyze at-path",AtPath},S})
+ _ -> asn1_error(S, {invalid_at_path, AtPath})
end
end;
evaluate_atpath(_,_,_,_) ->
@@ -6098,23 +5245,8 @@ tuple2complist({R1,E,R2}) ->
tuple2complist(List) when is_list(List) ->
List.
-get_choice_components(_S,{'CHOICE',Components}) when is_list(Components)->
- Components;
-get_choice_components(_S,{'CHOICE',{C1,C2}}) when is_list(C1),is_list(C2) ->
- C1++C2;
-get_choice_components(S,ERef=#'Externaltypereference'{}) ->
- {_RefMod,TypeDef}=get_referenced_type(S,ERef),
- #typedef{typespec=TS} = TypeDef,
- get_choice_components(S,TS#type.def).
-
-extract_at_notation([{Level,[#'Externalvaluereference'{value=Name}|Rest]}]) ->
- {Level,[Name|extract_at_notation1(Rest)]};
-extract_at_notation(At) ->
- exit({error,{asn1,{at_notation,At}}}).
-extract_at_notation1([#'Externalvaluereference'{value=Name}|Rest]) ->
- [Name|extract_at_notation1(Rest)];
-extract_at_notation1([]) ->
- [].
+extract_at_notation([{Level,ValueRefs}]) ->
+ {Level,[Name || #'Externalvaluereference'{value=Name} <- ValueRefs]}.
%% componentrelation1/1 identifies all componentrelation constraints
%% that exist in C or in the substructure of C. Info about the found
@@ -6133,8 +5265,8 @@ componentrelation1(S,C = #type{def=Def,constraint=Constraint,tablecinf=TCI},
Ret =
% case Constraint of
% [{componentrelation,{_,_,ObjectSet},AtList}|_Rest] ->
- case constraint_member(componentrelation,Constraint) of
- {true,{_,{_,_,ObjectSet},AtList}} ->
+ case lists:keyfind(componentrelation, 1, Constraint) of
+ {_,{_,_,ObjectSet},AtList} ->
[{_,AL=[#'Externalvaluereference'{}|_R1]}|_R2] = AtList,
%% Note: if Path is longer than one,i.e. it is within
%% an inner type of the actual level, then the only
@@ -6145,7 +5277,7 @@ componentrelation1(S,C = #type{def=Def,constraint=Constraint,tablecinf=TCI},
lists:map(fun(#'Externalvaluereference'{value=V})->V end,
AL),
{[{ObjectSet,AtPath,ClassDef,Path}],Def};
- _ ->
+ false ->
%% check the inner type of component
innertype_comprel(S,Def,Path)
end,
@@ -6219,10 +5351,8 @@ componentlist_comprel(_,[],Acc,_,NewCL) ->
innertype_comprel1(S,T = #type{def=Def,constraint=Cons,tablecinf=TCI},Path) ->
Ret =
-% case Cons of
-% [{componentrelation,{_,_,ObjectSet},AtList}|_Rest] ->
- case constraint_member(componentrelation,Cons) of
- {true,{_,{_,_,ObjectSet},AtList}} ->
+ case lists:keyfind(componentrelation, 1, Cons) of
+ {_,{_,_,ObjectSet},AtList} ->
%% This AtList must have an "outermost" at sign to be
%% relevent here.
[{_,AL=[#'Externalvaluereference'{value=_Attr}|_R1]}|_R2]
@@ -6233,7 +5363,7 @@ innertype_comprel1(S,T = #type{def=Def,constraint=Cons,tablecinf=TCI},Path) ->
lists:map(fun(#'Externalvaluereference'{value=V})->V end,
AL),
[{ObjectSet,AtPath,ClassDef,Path}];
- _ ->
+ false ->
innertype_comprel(S,Def,Path)
end,
case Ret of
@@ -6301,8 +5431,7 @@ value_match(S,#'ComponentType'{typespec=Type},Name,[At|Ats],Acc) ->
InnerType = asn1ct_gen:get_inner(Type#type.def),
Components =
case get_atlist_components(Type#type.def) of
- [] -> error({type,{asn1,"element in at list must be a "
- "SEQUENCE, SET or CHOICE.",Name},S});
+ [] -> asn1_error(S, {invalid_element, Name});
Comps -> Comps
end,
{Index,ValueIndex} = component_value_index(S,InnerType,At,Components),
@@ -6322,29 +5451,27 @@ component_index1(_S,Name,[#'ComponentType'{name=Name}|_Cs],N) ->
component_index1(S,Name,[_C|Cs],N) ->
component_index1(S,Name,Cs,N+1);
component_index1(S,Name,[],_) ->
- error({type,{asn1,"component of at-list was not"
- " found in substructure",Name},S}).
+ asn1_error(S, {invalid_at_list, Name}).
-get_unique_fieldname(_S,ClassDef) when is_record(ClassDef,classdef) ->
-%% {_,Fields,_} = ClassDef#classdef.typespec,
- Fields = (ClassDef#classdef.typespec)#objectclass.fields,
- get_unique_fieldname1(Fields,[]);
+get_unique_fieldname(S, #classdef{typespec=TS}) ->
+ Fields = TS#objectclass.fields,
+ get_unique_fieldname1(S, Fields, []);
get_unique_fieldname(S,#typedef{typespec=#type{def=ClassRef}}) ->
%% A class definition may be referenced as
%% REFED-CLASS ::= DEFINED-CLASS and then REFED-CLASS is a typedef
{_M,ClassDef} = get_referenced_type(S,ClassRef),
get_unique_fieldname(S,ClassDef).
-get_unique_fieldname1([],[]) ->
- throw({error,'__undefined_',[]});
-get_unique_fieldname1([],[Name]) ->
- Name;
-get_unique_fieldname1([],Acc) ->
- throw({asn1,'only one UNIQUE field is allowed in CLASS',Acc});
-get_unique_fieldname1([{fixedtypevaluefield,Name,_,'UNIQUE',Opt}|Rest],Acc) ->
- get_unique_fieldname1(Rest,[{Name,Opt}|Acc]);
-get_unique_fieldname1([_H|T],Acc) ->
- get_unique_fieldname1(T,Acc).
+get_unique_fieldname1(S, [{fixedtypevaluefield,Name,_,'UNIQUE',Opt}|T], Acc) ->
+ get_unique_fieldname1(S, T, [{Name,Opt}|Acc]);
+get_unique_fieldname1(S, [_|T], Acc) ->
+ get_unique_fieldname1(S, T, Acc);
+get_unique_fieldname1(S, [], Acc) ->
+ case Acc of
+ [] -> no_unique;
+ [Name] -> Name;
+ [_|_] -> asn1_error(S, multiple_uniqs)
+ end.
get_tableconstraint_info(S,Type,{CheckedTs,EComps,CheckedTs2}) ->
{get_tableconstraint_info(S,Type,CheckedTs,[]),
@@ -6400,31 +5527,8 @@ get_tableconstraint_info(S,Type,[C|Cs],Acc) ->
get_referenced_fieldname([{_,FirstFieldname}]) ->
{FirstFieldname,[]};
-get_referenced_fieldname([{_,FirstFieldname}|Rest]) ->
- {FirstFieldname,lists:map(fun(X)->element(2,X) end,Rest)};
-get_referenced_fieldname(Def={FieldName,RestFieldName}) when is_atom(FieldName),is_list(RestFieldName)->
- Def;
-get_referenced_fieldname(Def) ->
- {no_type,Def}.
-
-%% get_ObjectClassFieldType extracts the type from the chain of
-%% objects that leads to a final type.
-get_ObjectClassFieldType(S,ERef,PrimFieldNameList) when
- is_record(ERef,'Externaltypereference') ->
- {MName,Type} = get_referenced_type(S,ERef),
- NewS = update_state(S#state{type=Type,
- tname=ERef#'Externaltypereference'.type},MName),
- ClassSpec = check_class(NewS,Type),
- Fields = ClassSpec#objectclass.fields,
- get_ObjectClassFieldType(S,Fields,PrimFieldNameList);
-get_ObjectClassFieldType(S,Fields,L=[_PrimFieldName1|_Rest]) ->
- check_PrimitiveFieldNames(S,Fields,L),
- get_OCFType(S,Fields,L);
-get_ObjectClassFieldType(S,ERef,{FieldName,Rest}) ->
- get_ObjectClassFieldType(S,ERef,Rest ++ [FieldName]).
-
-check_PrimitiveFieldNames(_S,_Fields,_) ->
- ok.
+get_referenced_fieldname([{_,FirstFieldname}|T]) ->
+ {FirstFieldname,[element(2, X) || X <- T]}.
%% get_ObjectClassFieldType_classdef gets the def of the class of the
%% ObjectClassFieldType, i.e. the objectclass record. If the type has
@@ -6445,15 +5549,13 @@ get_OCFType(S,Fields,[PrimFieldName|Rest]) ->
{fixedtypevaluefield,PrimFieldName,Type};
{value,{objectfield,_,ClassRef,_Unique,_OptSpec}} ->
{MName,ClassDef} = get_referenced_type(S,ClassRef),
- NewS = update_state(S#state{type=ClassDef,
- tname=get_datastr_name(ClassDef)},
+ NewS = update_state(S#state{tname=get_datastr_name(ClassDef)},
MName),
CheckedCDef = check_class(NewS,ClassDef),
get_OCFType(S,CheckedCDef#objectclass.fields,Rest);
{value,{objectsetfield,_,Type,_OptSpec}} ->
{MName,ClassDef} = get_referenced_type(S,Type#type.def),
- NewS = update_state(S#state{type=ClassDef,
- tname=get_datastr_name(ClassDef)},
+ NewS = update_state(S#state{tname=get_datastr_name(ClassDef)},
MName),
CheckedCDef = check_class(NewS,ClassDef),
get_OCFType(S,CheckedCDef#objectclass.fields,Rest);
@@ -6461,7 +5563,7 @@ get_OCFType(S,Fields,[PrimFieldName|Rest]) ->
{value,Other} ->
{element(1,Other),PrimFieldName};
_ ->
- throw({error,lists:flatten(io_lib:format("undefined FieldName in ObjectClassFieldType: ~w",[PrimFieldName]))})
+ asn1_error(S, {illegal_object_field, PrimFieldName})
end.
get_taglist(S,Ext) when is_record(Ext,'Externaltypereference') ->
@@ -6485,30 +5587,8 @@ get_taglist(_S,#'ObjectClassFieldType'{type={typefield,_}}) ->
[];
get_taglist(S,#'ObjectClassFieldType'{type={fixedtypevaluefield,_,Type}}) ->
get_taglist(S,Type);
-get_taglist(S,{ERef=#'Externaltypereference'{},FieldNameList})
- when is_list(FieldNameList) ->
- case get_ObjectClassFieldType(S,ERef,FieldNameList) of
- {fixedtypevaluefield,_,Type} -> get_taglist(S,Type);
- {TypeFieldName,_} when is_atom(TypeFieldName) -> []%should check if allowed
- end;
-get_taglist(S,{ObjCl,FieldNameList}) when is_record(ObjCl,objectclass),
- is_list(FieldNameList) ->
- case get_ObjectClassFieldType(S,ObjCl#objectclass.fields,FieldNameList) of
- {fixedtypevaluefield,_,Type} -> get_taglist(S,Type);
- {TypeFieldName,_} when is_atom(TypeFieldName) -> []%should check if allowed
- end;
-get_taglist(S,Def) ->
- case S#state.erule of
- ber ->
- [];
- _ ->
- case Def of
- 'ASN1_OPEN_TYPE' -> % open_type has no UNIVERSAL tag as such
- [];
- _ ->
- [asn1ct_gen:def_to_tag(Def)]
- end
- end.
+get_taglist(_, _) ->
+ [].
get_taglist1(S,[#'ComponentType'{name=_Cname,tags=TagL}|Rest]) when is_list(TagL) ->
%% tag_list has been here , just return TagL and continue with next alternative
@@ -6565,15 +5645,6 @@ get_taglist1(_S,[]) ->
%% tag_number('CHARACTER STRING') -> 29;
%% tag_number('BMPString') -> 30.
-
-dbget_ex(_S,Module,Key) ->
- case asn1_db:dbget(Module,Key) of
- undefined ->
-
- throw({error,{asn1,{undefined,{Module,Key}}}}); % this is catched on toplevel type or value
- T -> T
- end.
-
merge_tags(T1, T2) when is_list(T2) ->
merge_tags2(T1 ++ T2, []);
merge_tags(T1, T2) ->
@@ -6590,75 +5661,46 @@ merge_tags2([H|T],Acc) ->
merge_tags2([], Acc) ->
lists:reverse(Acc).
-%% merge_constraints(C1, []) ->
-%% C1;
-%% merge_constraints([], C2) ->
-%% C2;
-%% merge_constraints(C1, C2) ->
-%% {SList,VList,PAList,Rest} = splitlist(C1++C2,[],[],[],[]),
-%% SizeC = merge_constraints(SList),
-%% ValueC = merge_constraints(VList),
-%% PermAlphaC = merge_constraints(PAList),
-%% case Rest of
-%% [] ->
-%% SizeC ++ ValueC ++ PermAlphaC;
-%% _ ->
-%% throw({error,{asn1,{not_implemented,{merge_constraints,Rest}}}})
-%% end.
-
-%% merge_constraints([]) -> [];
-%% merge_constraints([C1 = {_,{Low1,High1}},{_,{Low2,High2}}|Rest]) when Low1 >= Low2,
-%% High1 =< High2 ->
-%% merge_constraints([C1|Rest]);
-%% merge_constraints([C1={'PermittedAlphabet',_},C2|Rest]) ->
-%% [C1|merge_constraints([C2|Rest])];
-%% merge_constraints([C1 = {_,{_Low1,_High1}},C2 = {_,{_Low2,_High2}}|_Rest]) ->
-%% throw({error,asn1,{conflicting_constraints,{C1,C2}}});
-%% merge_constraints([C]) ->
-%% [C].
-
-%% splitlist([C={'SizeConstraint',_}|Rest],Sacc,Vacc,PAacc,Restacc) ->
-%% splitlist(Rest,[C|Sacc],Vacc,PAacc,Restacc);
-%% splitlist([C={'ValueRange',_}|Rest],Sacc,Vacc,PAacc,Restacc) ->
-%% splitlist(Rest,Sacc,[C|Vacc],PAacc,Restacc);
-%% splitlist([C={'PermittedAlphabet',_}|Rest],Sacc,Vacc,PAacc,Restacc) ->
-%% splitlist(Rest,Sacc,Vacc,[C|PAacc],Restacc);
-%% splitlist([C|Rest],Sacc,Vacc,PAacc,Restacc) ->
-%% splitlist(Rest,Sacc,Vacc,PAacc,[C|Restacc]);
-%% splitlist([],Sacc,Vacc,PAacc,Restacc) ->
-%% {lists:reverse(Sacc),
-%% lists:reverse(Vacc),
-%% lists:reverse(PAacc),
-%% lists:reverse(Restacc)}.
-
-
-
-storeindb(S,M) when is_record(M,module) ->
- TVlist = M#module.typeorval,
- NewM = M#module{typeorval=findtypes_and_values(TVlist)},
- asn1_db:dbnew(NewM#module.name, S#state.erule),
- asn1_db:dbput(NewM#module.name,'MODULE', NewM),
- Res = storeindb(#state{mname=NewM#module.name}, TVlist, []),
- include_default_class(S,NewM#module.name),
+storeindb(S0, #module{name=ModName,typeorval=TVlist0}=M) ->
+ S = S0#state{mname=ModName},
+ TVlist1 = [{asn1ct:get_name_of_def(Def),Def} || Def <- TVlist0],
+ case check_duplicate_defs(S, TVlist1) of
+ ok ->
+ storeindb_1(S, M, TVlist0, TVlist1);
+ {error,_}=Error ->
+ Error
+ end.
+
+storeindb_1(S, #module{name=ModName}=M, TVlist0, TVlist) ->
+ NewM = M#module{typeorval=findtypes_and_values(TVlist0)},
+ asn1_db:dbnew(ModName, S#state.erule),
+ asn1_db:dbput(ModName, 'MODULE', NewM),
+ asn1_db:dbput(ModName, TVlist),
+ include_default_class(S, NewM#module.name),
include_default_type(NewM#module.name),
- Res.
+ ok.
-storeindb(#state{mname=Module}=S, [H|T], Errors) ->
- Name = asn1ct:get_name_of_def(H),
- case asn1_db:dbget(Module, Name) of
- undefined ->
- asn1_db:dbput(Module, Name, H),
- storeindb(S, T, Errors);
- Prev ->
- PrevLine = asn1ct:get_pos_of_def(Prev),
- Error = return_asn1_error(S, H, {already_defined,Name,PrevLine}),
- storeindb(S, T, [Error|Errors])
- end;
-storeindb(_, [], []) ->
- ok;
-storeindb(_, [], [_|_]=Errors) ->
- {error,Errors}.
+check_duplicate_defs(S, Defs) ->
+ Set0 = sofs:relation(Defs),
+ Set1 = sofs:relation_to_family(Set0),
+ Set = sofs:to_external(Set1),
+ case [duplicate_def(S, N, Dup) || {N,[_,_|_]=Dup} <- Set] of
+ [] ->
+ ok;
+ [_|_]=E ->
+ {error,lists:append(E)}
+ end.
+
+duplicate_def(S, Name, Dups0) ->
+ Dups1 = [{asn1ct:get_pos_of_def(Def),Def} || Def <- Dups0],
+ [{Prev,_}|Dups] = lists:sort(Dups1),
+ duplicate_def_1(S, Dups, Name, Prev).
+duplicate_def_1(S, [{_,Def}|T], Name, Prev) ->
+ E = return_asn1_error(S, Def, {already_defined,Name,Prev}),
+ [E|duplicate_def_1(S, T, Name, Prev)];
+duplicate_def_1(_, [], _, _) ->
+ [].
findtypes_and_values(TVList) ->
findtypes_and_values(TVList,[],[],[],[],[],[]).%% Types,Values,
@@ -6698,99 +5740,147 @@ findtypes_and_values([],Tacc,Vacc,Pacc,Cacc,Oacc,OSacc) ->
{lists:reverse(Tacc),lists:reverse(Vacc),lists:reverse(Pacc),
lists:reverse(Cacc),lists:reverse(Oacc),lists:reverse(OSacc)}.
+return_asn1_error(#state{error_context=Context}=S, Error) ->
+ return_asn1_error(S, Context, Error).
+
return_asn1_error(#state{mname=Where}, Item, Error) ->
Pos = asn1ct:get_pos_of_def(Item),
{structured_error,{Where,Pos},?MODULE,Error}.
-asn1_error(S, Item, Error) ->
- throw({error,return_asn1_error(S, Item, Error)}).
+-spec asn1_error(_, _) -> no_return().
+asn1_error(S, Error) ->
+ throw({error,return_asn1_error(S, Error)}).
format_error({already_defined,Name,PrevLine}) ->
io_lib:format("the name ~p has already been defined at line ~p",
[Name,PrevLine]);
+format_error({duplicate_identifier,Ids}) ->
+ io_lib:format("the identifier '~p' has already been used", [Ids]);
+format_error({duplicate_tags,Elements}) ->
+ io_lib:format("duplicate tags in the elements: ~s",
+ [format_elements(Elements)]);
+format_error({enum_illegal_redefinition,Id}) ->
+ io_lib:format("'~s' must not be redefined", [Id]);
+format_error({enum_not_ascending,Id,N,Prev}) ->
+ io_lib:format("the values for enumerations which follow '...' must "
+ "be in ascending order, but '~p(~p)' is less than the "
+ "previous value '~p'", [Id,N,Prev]);
+format_error({enum_reused_value,Id,Val}) ->
+ io_lib:format("'~s' has the value '~p' which is used more than once",
+ [Id,Val]);
+format_error({illegal_id, Id}) ->
+ io_lib:format("illegal identifier: ~p", [Id]);
+format_error({illegal_choice_type, Ref}) ->
+ io_lib:format("expecting a CHOICE type: ~p", [Ref]);
+format_error({illegal_class_name,Class}) ->
+ io_lib:format("the class name '~s' is illegal (it must start with an uppercase letter and only contain uppercase letters, digits, or hyphens)", [Class]);
+format_error({illegal_COMPONENTS_OF, Ref}) ->
+ io_lib:format("expected a SEQUENCE or SET got: ~p", [Ref]);
+format_error(illegal_external_value) ->
+ "illegal value in EXTERNAL type";
format_error({illegal_instance_of,Class}) ->
io_lib:format("using INSTANCE OF on class '~s' is illegal, "
- "because INSTANCE OF may only be used on the class TYPE-IDENTFIER",
+ "because INSTANCE OF may only be used on the class TYPE-IDENTIFIER",
[Class]);
+format_error(illegal_integer_value) ->
+ "expecting an integer value";
+format_error(illegal_object) ->
+ "expecting an object";
+format_error({illegal_object_field, Id}) ->
+ io_lib:format("expecting a class field: ~p",[Id]);
+format_error({illegal_oid,o_id}) ->
+ "illegal OBJECT IDENTIFIER";
+format_error({illegal_oid,rel_oid}) ->
+ "illegal RELATIVE-OID";
format_error(illegal_octet_string_value) ->
"expecting a bstring or an hstring as value for an OCTET STRING";
format_error({illegal_typereference,Name}) ->
io_lib:format("'~p' is used as a typereference, but does not start with an uppercase letter", [Name]);
+format_error(illegal_table_constraint) ->
+ "table constraints may only be applied to CLASS.&field constructs";
+format_error(illegal_value) ->
+ "expecting a value";
+format_error({illegal_value, TYPE}) ->
+ io_lib:format("expecting a ~s value", [TYPE]);
format_error({invalid_fields,Fields,Obj}) ->
io_lib:format("invalid ~s in ~p", [format_fields(Fields),Obj]);
format_error({invalid_bit_number,Bit}) ->
io_lib:format("the bit number '~p' is invalid", [Bit]);
+format_error(invalid_table_constraint) ->
+ "the table constraint is not an object set";
+format_error(invalid_objectset) ->
+ "expecting an object set";
+format_error({implicit_tag_before,Kind}) ->
+ "illegal implicit tag before " ++
+ case Kind of
+ choice -> "'CHOICE'";
+ open_type -> "open type"
+ end;
format_error({missing_mandatory_fields,Fields,Obj}) ->
io_lib:format("missing mandatory ~s in ~p",
[format_fields(Fields),Obj]);
+format_error({missing_table_constraint,Component}) ->
+ io_lib:format("the component '~s' is referenced by a component relation constraint using the '@field-name' notation, but does not have a table constraint",
+ [Component]);
+format_error({missing_id,Id}) ->
+ io_lib:format("expected the mandatory component '~p'", [Id]);
+format_error({missing_ocft,Component}) ->
+ io_lib:format("the component '~s' must be an ObjectClassFieldType (CLASSNAME.&field-name)", [Component]);
+format_error(multiple_uniqs) ->
+ "implementation limitation: only one UNIQUE field is allowed in CLASS";
format_error({namelist_redefinition,Name}) ->
io_lib:format("the name '~s' can not be redefined", [Name]);
+format_error({param_bad_type, Ref}) ->
+ io_lib:format("'~p' is not a parameterized type", [Ref]);
+format_error(param_wrong_number_of_arguments) ->
+ "wrong number of arguments";
+format_error(reversed_range) ->
+ "ranges must be given in increasing order";
+format_error({syntax_duplicated_fields,Fields}) ->
+ io_lib:format("~s must only occur once in the syntax list",
+ [format_fields(Fields)]);
+format_error(syntax_nomatch) ->
+ "unexpected end of object definition";
+format_error({syntax_mandatory_in_optional_group,Name}) ->
+ io_lib:format("the field '&~s' must not be within an optional group since it is not optional",
+ [Name]);
+format_error({syntax_missing_mandatory_fields,Fields}) ->
+ io_lib:format("missing mandatory ~s in the syntax list",
+ [format_fields(Fields)]);
+format_error({syntax_nomatch,Actual}) ->
+ io_lib:format("~s is not the next item allowed according to the defined syntax",
+ [Actual]);
+format_error({syntax_undefined_field,Field}) ->
+ io_lib:format("'&~s' is not a field of the class being defined",
+ [Field]);
format_error({undefined,Name}) ->
io_lib:format("'~s' is referenced, but is not defined", [Name]);
+format_error({undefined_export,Ref}) ->
+ io_lib:format("'~s' is exported but is not defined", [Ref]);
+format_error({undefined_field,FieldName}) ->
+ io_lib:format("the field '&~s' is undefined", [FieldName]);
format_error({undefined_import,Ref,Module}) ->
io_lib:format("'~s' is not exported from ~s", [Ref,Module]);
+format_error({unique_and_default,Field}) ->
+ io_lib:format("the field '&~s' must not have both 'UNIQUE' and 'DEFAULT'",
+ [Field]);
format_error({value_reused,Val}) ->
io_lib:format("the value '~p' is used more than once", [Val]);
+format_error({non_unique_object,Id}) ->
+ io_lib:format("object set with a UNIQUE field value of '~p' is used more than once", [Id]);
format_error(Other) ->
io_lib:format("~p", [Other]).
format_fields([F]) ->
- io_lib:format("field &~s", [F]);
+ io_lib:format("field '&~s'", [F]);
format_fields([H|T]) ->
- [io_lib:format("fields &~s", [H])|
- [io_lib:format(", &~s", [F]) || F <- T]].
-
-error({_,{structured_error,_,_,_}=SE,_}) ->
- SE;
-error({export,Msg,#state{mname=Mname,type=Ref,tname=Typename}}) ->
- Pos = Ref#'Externaltypereference'.pos,
- io:format("asn1error:~p:~p:~p~n~p~n",[Pos,Mname,Typename,Msg]),
- {error,{export,Pos,Mname,Typename,Msg}};
-% error({type,{Msg1,Msg2},#state{mname=Mname,type=Type,tname=Typename}})
-% when is_record(Type,typedef) ->
-% io:format("asn1error:~p:~p:~p ~p~n",
-% [Type#typedef.pos,Mname,Typename,Msg1]),
-% {error,{type,Type#typedef.pos,Mname,Typename,Msg1,Msg2}};
-error({type,Msg,#state{mname=Mname,type=Type,tname=Typename}})
- when is_record(Type,type) ->
- io:format("asn1error:~p:~p~n~p~n",
- [Mname,Typename,Msg]),
- {error,{type,Mname,Typename,Msg}};
-error({type,Msg,#state{mname=Mname,type=Type,tname=Typename}})
- when is_record(Type,typedef) ->
- io:format("asn1error:~p:~p:~p~n~p~n",
- [Type#typedef.pos,Mname,Typename,Msg]),
- {error,{type,Type#typedef.pos,Mname,Typename,Msg}};
-error({type,Msg,#state{mname=Mname,type=Type,tname=Typename}})
- when is_record(Type,ptypedef) ->
- io:format("asn1error:~p:~p:~p~n~p~n",
- [Type#ptypedef.pos,Mname,Typename,Msg]),
- {error,{type,Type#ptypedef.pos,Mname,Typename,Msg}};
-error({type,Msg,#state{mname=Mname,value=Value,vname=Valuename}})
- when is_record(Value,valuedef) ->
- io:format("asn1error:~p:~p:~p~n~p~n",[Value#valuedef.pos,Mname,Valuename,Msg]),
- {error,{type,Value#valuedef.pos,Mname,Valuename,Msg}};
-error({type,Msg,#state{mname=Mname,type=Type,tname=Typename}})
- when is_record(Type,pobjectdef) ->
- io:format("asn1error:~p:~p:~p~n~p~n",
- [Type#pobjectdef.pos,Mname,Typename,Msg]),
- {error,{type,Type#pobjectdef.pos,Mname,Typename,Msg}};
-error({value,Msg,#state{mname=Mname,value=Value,vname=Valuename}})
- when is_record(Value,valuedef) ->
- io:format("asn1error:~p:~p:~p~n~p~n",[Value#valuedef.pos,Mname,Valuename,Msg]),
- {error,{value,Value#valuedef.pos,Mname,Valuename,Msg}};
-error({Other,Msg,#state{mname=Mname,value=#valuedef{pos=Pos},vname=Valuename}}) ->
- io:format("asn1error:~p:~p:~p~n~p~n",[Pos,Mname,Valuename,Msg]),
- {error,{Other,Pos,Mname,Valuename,Msg}};
-error({Other,Msg,#state{mname=Mname,type=#typedef{pos=Pos},tname=Typename}}) ->
- io:format("asn1error:~p:~p:~p~n~p~n",[Pos,Mname,Typename,Msg]),
- {error,{Other,Pos,Mname,Typename,Msg}};
-error({Other,Msg,#state{mname=Mname,type=#classdef{pos=Pos},tname=Typename}}) ->
- io:format("asn1error:~p:~p:~p~n~p~n",[Pos,Mname,Typename,Msg]),
- {error,{Other,Pos,Mname,Typename,Msg}};
-error({Other,Msg,#state{mname=Mname,type=Type,tname=Typename}}) ->
- io:format("asn1error:~p:~p:~p~n~p~n",[asn1ct:get_pos_of_def(Type),Mname,Typename,Msg]),
- {error,{Other,asn1ct:get_pos_of_def(Type),Mname,Typename,Msg}}.
+ [io_lib:format("fields '&~s'", [H])|
+ [io_lib:format(", '&~s'", [F]) || F <- T]].
+
+format_elements([H1,H2|T]) ->
+ [io_lib:format("~p, ", [H1])|format_elements([H2|T])];
+format_elements([H]) ->
+ io_lib:format("~p", [H]).
include_default_type(Module) ->
NameAbsList = default_type_list(),
@@ -6953,62 +6043,62 @@ default_type_list() ->
].
-include_default_class(S,Module) ->
- NameAbsList = default_class_list(S),
- include_default_class1(Module,NameAbsList).
+include_default_class(S, Module) ->
+ _ = [include_default_class1(S, Module, ClassDef) ||
+ ClassDef <- default_class_list()],
+ ok.
-include_default_class1(_,[]) ->
- ok;
-include_default_class1(Module,[{Name,TS}|Rest]) ->
- case asn1_db:dbget(Module,Name) of
+include_default_class1(S, Module, {Name,Ts0}) ->
+ case asn1_db:dbget(Module, Name) of
undefined ->
- C = #classdef{checked=true,module=Module,name=Name,
- typespec=TS},
- asn1_db:dbput(Module,Name,C);
- _ -> ok
- end,
- include_default_class1(Module,Rest).
+ #objectclass{fields=Fields,
+ syntax={'WITH SYNTAX',Syntax0}} = Ts0,
+ Syntax = preprocess_syntax(S, Syntax0, Fields),
+ Ts = Ts0#objectclass{syntax={preprocessed_syntax,Syntax}},
+ C = #classdef{checked=true,module=Module,
+ name=Name,typespec=Ts},
+ asn1_db:dbput(Module, Name, C);
+ _ ->
+ ok
+ end.
-default_class_list(S) ->
+default_class_list() ->
[{'TYPE-IDENTIFIER',
- {objectclass,
- [{fixedtypevaluefield,
- id,
- #type{tag=?TAG_PRIMITIVE(?N_OBJECT_IDENTIFIER),
- def='OBJECT IDENTIFIER'},
- 'UNIQUE',
- 'MANDATORY'},
- {typefield,'Type','MANDATORY'}],
- {'WITH SYNTAX',
- [{typefieldreference,'Type'},
- 'IDENTIFIED',
- 'BY',
- {valuefieldreference,id}]}}},
+ #objectclass{fields=[{fixedtypevaluefield,
+ id,
+ #type{tag=[?TAG_PRIMITIVE(?N_OBJECT_IDENTIFIER)],
+ def='OBJECT IDENTIFIER'},
+ 'UNIQUE',
+ 'MANDATORY'},
+ {typefield,'Type','MANDATORY'}],
+ syntax={'WITH SYNTAX',
+ [{typefieldreference,'Type'},
+ 'IDENTIFIED',
+ 'BY',
+ {valuefieldreference,id}]}}},
{'ABSTRACT-SYNTAX',
- {objectclass,
- [{fixedtypevaluefield,
- id,
- #type{tag=?TAG_PRIMITIVE(?N_OBJECT_IDENTIFIER),
- def='OBJECT IDENTIFIER'},
- 'UNIQUE',
- 'MANDATORY'},
- {typefield,'Type','MANDATORY'},
- {fixedtypevaluefield,
- property,
- #type{tag=?TAG_PRIMITIVE(?N_BIT_STRING),
- def={'BIT STRING',[]}},
- undefined,
- {'DEFAULT',
- [0,1,0]}}],
- {'WITH SYNTAX',
- [{typefieldreference,'Type'},
- 'IDENTIFIED',
- 'BY',
- {valuefieldreference,id},
- ['HAS',
- 'PROPERTY',
- {valuefieldreference,property}]]}}}].
-
+ #objectclass{fields=[{fixedtypevaluefield,
+ id,
+ #type{tag=[?TAG_PRIMITIVE(?N_OBJECT_IDENTIFIER)],
+ def='OBJECT IDENTIFIER'},
+ 'UNIQUE',
+ 'MANDATORY'},
+ {typefield,'Type','MANDATORY'},
+ {fixedtypevaluefield,
+ property,
+ #type{tag=[?TAG_PRIMITIVE(?N_BIT_STRING)],
+ def={'BIT STRING',[]}},
+ undefined,
+ {'DEFAULT',
+ [0,1,0]}}],
+ syntax={'WITH SYNTAX',
+ [{typefieldreference,'Type'},
+ 'IDENTIFIED',
+ 'BY',
+ {valuefieldreference,id},
+ ['HAS',
+ 'PROPERTY',
+ {valuefieldreference,property}]]}}}].
new_reference_name(Name) ->
case get(asn1_reference) of
@@ -7037,8 +6127,9 @@ insert_once(S,Tab,Key) ->
skipped
end.
-check_fold(S, [H|T], Check) ->
- Type = asn1_db:dbget(S#state.mname, H),
+check_fold(S0, [H|T], Check) ->
+ Type = asn1_db:dbget(S0#state.mname, H),
+ S = S0#state{error_context=Type},
case Check(S, H, Type) of
ok ->
check_fold(S, T, Check);
@@ -7047,5 +6138,19 @@ check_fold(S, [H|T], Check) ->
end;
check_fold(_, [], Check) when is_function(Check, 3) -> [].
+error_value(Value) when is_integer(Value) -> Value;
+error_value(Value) when is_atom(Value) -> Value;
+error_value(#type{def=Value}) when is_atom(Value) -> Value;
+error_value(#type{def=Value}) -> error_value(Value);
+error_value(RefOrType) ->
+ try name_of_def(RefOrType) of
+ Name -> Name
+ catch _:_ ->
+ case get_datastr_name(RefOrType) of
+ undefined -> RefOrType;
+ Name -> Name
+ end
+ end.
+
name_of_def(#'Externaltypereference'{type=N}) -> N;
name_of_def(#'Externalvaluereference'{value=N}) -> N.
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
index 820d19b85c..b31f616677 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index a91404ed54..42f9bb836e 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -410,12 +411,11 @@ gen_dec_open_type(Erule, Val, {Xmod,Xtype}, LeadingAttr,
#classdef{typespec=ClassDef} = asn1_db:dbget(ClMod, ClType),
#objectclass{fields=ClassFields} = ClassDef,
Extensible = lists:member('EXTENSIONMARK', ObjSet1),
- ObjSet2 = [{Key,fix_object_code(Name, Code, ClassFields)} ||
- {_,Key,Code} <- ObjSet1],
- ObjSet = lists:sort([P || {_,B}=P <- ObjSet2, B =/= none]),
+ Typename = [Name,ClType],
+ ObjSet = index_object_set(Erule, ClType, Name,
+ ObjSet1, ClassFields),
Key = erlang:md5(term_to_binary({decode,ObjSet,RestFieldNames,
Prop,Extensible})),
- Typename = [Name,ClType],
Gen = fun(_Fd, N) ->
dec_objset_optional(N, Prop),
dec_objset(Erule, N, ObjSet, RestFieldNames, Typename),
@@ -467,46 +467,15 @@ dec_objset_2(Erule, Obj, RestFields0, Typename) ->
Imm = asn1ct_gen_per:gen_dec_imm(Erule, Type),
{Term,_} = asn1ct_imm:dec_slim_cg(Imm, 'Bytes'),
emit([com,nl,Term]);
- #typedef{name={constructed,bif},typespec=Def} ->
- InnerType = asn1ct_gen:get_inner(Def#type.def),
- case InnerType of
- 'CHOICE' ->
- asn1ct_name:start(),
- asn1ct_name:new(bytes),
- {'CHOICE',CompList} = Def#type.def,
- Ext = extensible_enc(CompList),
- emit(["{Result,_} = begin",nl]),
- gen_dec_choice(Erule, Typename, CompList, Ext),
- emit([nl,
- "end",com,nl,
- "Result"]);
- 'SET' ->
- Imm0 = gen_dec_constructed_imm(Erule, Typename, Def),
- Imm = opt_imm(Imm0),
- asn1ct_name:start(),
- emit(["{Result,_} = begin",nl]),
- emit_gen_dec_imm(Imm),
- emit([nl,
- "end",com,nl,
- "Result"]);
- 'SET OF' ->
- asn1ct_name:start(),
- do_gen_decode_sof(Erule, Typename, 'SET OF',
- Def, false);
- 'SEQUENCE' ->
- Imm0 = gen_dec_constructed_imm(Erule, Typename, Def),
- Imm = opt_imm(Imm0),
- asn1ct_name:start(),
- emit(["{Result,_} = begin",nl]),
- emit_gen_dec_imm(Imm),
- emit([nl,
- "end",com,nl,
- "Result"]);
- 'SEQUENCE OF' ->
- asn1ct_name:start(),
- do_gen_decode_sof(Erule, Typename, 'SEQUENCE OF',
- Def, false)
- end;
+ #typedef{name={constructed,bif},typespec=Type}=Def ->
+ Prefix = "dec_outlined_",
+ Key = {dec_outlined,Def},
+ Gen = fun(_Fd, Name) ->
+ gen_dec_obj(Erule, Name, Typename, Type)
+ end,
+ Func = asn1ct_func:call_gen(Prefix, Key, Gen),
+ emit(["{Term,_} = ",{asis,Func},"(Bytes)",com,nl,
+ "Term"]);
#typedef{name=Type} ->
emit(["{Result,_} = ",{asis,enc_func("dec_", Type)},"(Bytes),",nl,
"Result"]);
@@ -531,6 +500,12 @@ dec_objset_2(Erule, Obj, RestFields0, Typename) ->
end
end.
+gen_dec_obj(Erules, Name, Typename, Type) ->
+ emit([{asis,Name},"(Bytes) ->",nl]),
+ InnerType = asn1ct_gen:get_inner(Type#type.def),
+ asn1ct_gen:gen_decode_constructed(Erules, Typename,
+ InnerType, Type).
+
gen_encode_choice(Erule, TopType, D) ->
asn1ct_name:start(),
Imm = gen_encode_choice_imm(Erule, TopType, D),
@@ -595,10 +570,10 @@ gen_encode_sof_imm(Erule, Typename, SeqOrSetOf, #type{}=D) ->
gen_decode_sof(Erules, Typename, SeqOrSetOf, #type{}=D) ->
asn1ct_name:start(),
- do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D, true),
+ do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D),
emit([".",nl,nl]).
-do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D, NeedRest) ->
+do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D) ->
{_SeqOrSetOf,ComponentType} = D#type.def,
SizeConstraint = asn1ct_imm:effective_constraint(bitstring,
D#type.constraint),
@@ -610,12 +585,11 @@ do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D, NeedRest) ->
""
end,
{Num,Buf} = gen_decode_length(SizeConstraint, Erules),
- Key = erlang:md5(term_to_binary({Typename,SeqOrSetOf,
- ComponentType,NeedRest})),
+ Key = erlang:md5(term_to_binary({Typename,SeqOrSetOf,ComponentType})),
Gen = fun(_Fd, Name) ->
gen_decode_sof_components(Erules, Name,
Typename, SeqOrSetOf,
- ComponentType, NeedRest)
+ ComponentType)
end,
F = asn1ct_func:call_gen("dec_components", Key, Gen),
emit([",",nl,
@@ -629,7 +603,7 @@ gen_decode_length(Constraint, Erule) ->
Imm = asn1ct_imm:per_dec_length(Constraint, true, is_aligned(Erule)),
asn1ct_imm:dec_slim_cg(Imm, "Bytes").
-gen_decode_sof_components(Erule, Name, Typename, SeqOrSetOf, Cont, NeedRest) ->
+gen_decode_sof_components(Erule, Name, Typename, SeqOrSetOf, Cont) ->
{ObjFun,ObjFun_Var} =
case Cont#type.tablecinf of
[{objfun,_}|_R] ->
@@ -637,14 +611,8 @@ gen_decode_sof_components(Erule, Name, Typename, SeqOrSetOf, Cont, NeedRest) ->
_ ->
{"",""}
end,
- case NeedRest of
- false ->
- emit([{asis,Name},"(0, _Bytes",ObjFun_Var,", Acc) ->",nl,
- "lists:reverse(Acc);",nl]);
- true ->
- emit([{asis,Name},"(0, Bytes",ObjFun_Var,", Acc) ->",nl,
- "{lists:reverse(Acc),Bytes};",nl])
- end,
+ emit([{asis,Name},"(0, Bytes",ObjFun_Var,", Acc) ->",nl,
+ "{lists:reverse(Acc),Bytes};",nl]),
emit([{asis,Name},"(Num, Bytes",ObjFun,", Acc) ->",nl,
"{Term,Remain} = "]),
Constructed_Suffix = asn1ct_gen:constructed_suffix(SeqOrSetOf,
@@ -1024,11 +992,12 @@ enc_var_type_call(Erule, Name, RestFieldNames,
#classdef{typespec=ClassDef} = asn1_db:dbget(ClMod, ClType),
#objectclass{fields=ClassFields} = ClassDef,
Extensible = lists:member('EXTENSIONMARK', ObjSet1),
- ObjSet2 = [{Key,fix_object_code(Name, Code, ClassFields)} ||
- {_,Key,Code} <- ObjSet1],
- ObjSet = lists:sort([P || {_,B}=P <- ObjSet2, B =/= none]),
+ ObjSet = index_object_set(Erule, ClType, Name,
+ ObjSet1, ClassFields),
Key = erlang:md5(term_to_binary({encode,ObjSet,RestFieldNames,Extensible})),
- Imm = enc_objset_imm(Erule, Name, ObjSet, RestFieldNames, Extensible),
+ TypeName = [ClType,Name],
+ Imm = enc_objset_imm(Erule, TypeName, Name, ObjSet,
+ RestFieldNames, Extensible),
Lambda = {lambda,[{var,"Val"},{var,"Id"}],Imm},
Gen = fun(_Fd, N) ->
Aligned = is_aligned(Erule),
@@ -1039,11 +1008,27 @@ enc_var_type_call(Erule, Name, RestFieldNames,
Prefix = lists:concat(["enc_os_",Name]),
[{call_gen,Prefix,Key,Gen,Lambda,[Val,Fun]}].
-fix_object_code(Name, [{Name,B}|_], _ClassFields) ->
- B;
-fix_object_code(Name, [_|T], ClassFields) ->
- fix_object_code(Name, T, ClassFields);
-fix_object_code(Name, [], ClassFields) ->
+index_object_set(_Erules, _ClType, Name, Set0, ClassFields) ->
+ Set = index_object_set_1(Name, Set0, ClassFields),
+ lists:sort(Set).
+
+index_object_set_1(Name, [{_,Key,Code}|T], ClassFields) ->
+ case index_object_set_2(Name, Code, ClassFields) of
+ none ->
+ index_object_set_1(Name, T, ClassFields);
+ Type ->
+ [{Key,Type}|index_object_set_1(Name, T, ClassFields)]
+ end;
+index_object_set_1(Name, [_|T], ClassFields) ->
+ index_object_set_1(Name, T, ClassFields);
+index_object_set_1(_, [], _) ->
+ [].
+
+index_object_set_2(Name, [{Name,Type}|_], _ClassFields) ->
+ Type;
+index_object_set_2(Name, [_|T], ClassFields) ->
+ index_object_set_2(Name, T, ClassFields);
+index_object_set_2(Name, [], ClassFields) ->
case lists:keyfind(Name, 2, ClassFields) of
{typefield,Name,'OPTIONAL'} ->
none;
@@ -1059,7 +1044,8 @@ fix_object_code(Name, [], ClassFields) ->
end
end.
-enc_objset_imm(Erule, Component, ObjSet, RestFieldNames, Extensible) ->
+enc_objset_imm(Erule, TypeName, Component, ObjSet,
+ RestFieldNames, Extensible) ->
Aligned = is_aligned(Erule),
E = {error,
fun() ->
@@ -1070,7 +1056,7 @@ enc_objset_imm(Erule, Component, ObjSet, RestFieldNames, Extensible) ->
end},
[{'cond',
[[{eq,{var,"Id"},Key}|
- enc_obj(Erule, Obj, RestFieldNames, Aligned)] ||
+ enc_obj(Erule, Obj, TypeName, RestFieldNames, Aligned)] ||
{Key,Obj} <- ObjSet] ++
[['_',case Extensible of
false ->
@@ -1086,24 +1072,18 @@ enc_objset_imm(Erule, Component, ObjSet, RestFieldNames, Extensible) ->
end
end]]}].
-enc_obj(Erule, Obj, RestFieldNames0, Aligned) ->
+enc_obj(Erule, Obj, TypeName, RestFieldNames0, Aligned) ->
+ Val = {var,"Val"},
case Obj of
+ #typedef{name={constructed,bif},typespec=Type}=Def ->
+ Prefix = "enc_outlined_",
+ Key = {enc_outlined,Def},
+ Gen = fun(_Fd, Name) ->
+ gen_enc_obj(Erule, Name, TypeName, Type)
+ end,
+ [{call_gen,Prefix,Key,Gen,undefined,[Val]}];
#typedef{name={primitive,bif},typespec=Def} ->
asn1ct_gen_per:gen_encode_prim_imm({var,"Val"}, Def, Aligned);
- #typedef{name={constructed,bif},typespec=Def} ->
- InnerType = asn1ct_gen:get_inner(Def#type.def),
- case InnerType of
- 'CHOICE' ->
- gen_encode_choice_imm(Erule, name, Def);
- 'SET' ->
- gen_encode_constructed_imm(Erule, name, Def);
- 'SET OF' ->
- gen_encode_sof_imm(Erule, name, InnerType, Def);
- 'SEQUENCE' ->
- gen_encode_constructed_imm(Erule, name, Def);
- 'SEQUENCE OF' ->
- gen_encode_sof_imm(Erule, name, InnerType, Def)
- end;
#typedef{name=Type} ->
[{apply,{local,enc_func(Type),Type},[{var,"Val"}]}];
#'Externalvaluereference'{module=Mod,value=Value} ->
@@ -1112,7 +1092,8 @@ enc_obj(Erule, Obj, RestFieldNames0, Aligned) ->
{object,_,Fields} = Def,
[NextField|RestFieldNames] = RestFieldNames0,
{NextField,Typedef} = lists:keyfind(NextField, 1, Fields),
- enc_obj(Erule, Typedef, RestFieldNames, Aligned)
+ enc_obj(Erule, Typedef, TypeName,
+ RestFieldNames, Aligned)
end;
#'Externaltypereference'{module=Mod,type=Type} ->
Func = enc_func(Type),
@@ -1124,6 +1105,11 @@ enc_obj(Erule, Obj, RestFieldNames0, Aligned) ->
end
end.
+gen_enc_obj(Erules, Name, Typename, Type) ->
+ emit([{asis,Name},"(Val) ->",nl]),
+ InnerType = asn1ct_gen:get_inner(Type#type.def),
+ asn1ct_gen:gen_encode_constructed(Erules, Typename,
+ InnerType, Type).
gen_dec_components_call(Erule, TopType, {Root,ExtList},
DecInfObj, Ext, NumberOfOptionals) ->
diff --git a/lib/asn1/src/asn1ct_func.erl b/lib/asn1/src/asn1ct_func.erl
index fb94f65b32..ad1494f7af 100644
--- a/lib/asn1/src/asn1ct_func.erl
+++ b/lib/asn1/src/asn1ct_func.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 2ef8466309..6d5062a118 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -531,34 +532,30 @@ gen_part_decode_funcs({primitive,bif},_TypeName,
gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) ->
throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}).
-
-gen_types(Erules,Tname,{RootL1,ExtList,RootL2})
+%% EncDec = 'gen_encode' | 'gen_decode'
+gen_types(Erules, Tname, {RootL1,ExtList,RootL2}, EncDec)
when is_list(RootL1), is_list(RootL2) ->
- gen_types(Erules,Tname,RootL1),
+ gen_types(Erules, Tname, RootL1, EncDec),
Rtmod = ct_gen_module(Erules),
- gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList)),
- gen_types(Erules,Tname,RootL2);
-gen_types(Erules,Tname,{RootList,ExtList}) when is_list(RootList) ->
- gen_types(Erules,Tname,RootList),
+ gen_types(Erules, Tname, Rtmod:extaddgroup2sequence(ExtList), EncDec),
+ gen_types(Erules, Tname, RootL2, EncDec);
+gen_types(Erules, Tname, {RootList,ExtList}, EncDec) when is_list(RootList) ->
+ gen_types(Erules, Tname, RootList, EncDec),
Rtmod = ct_gen_module(Erules),
- gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList));
-gen_types(Erules,Tname,[{'EXTENSIONMARK',_,_}|Rest]) ->
- gen_types(Erules,Tname,Rest);
-gen_types(Erules,Tname,[ComponentType|Rest]) ->
- Rtmod = ct_gen_module(Erules),
- asn1ct_name:clear(),
- Rtmod:gen_encode(Erules,Tname,ComponentType),
+ gen_types(Erules, Tname, Rtmod:extaddgroup2sequence(ExtList), EncDec);
+gen_types(Erules, Tname, [{'EXTENSIONMARK',_,_}|T], EncDec) ->
+ gen_types(Erules, Tname, T, EncDec);
+gen_types(Erules, Tname, [ComponentType|T], EncDec) ->
asn1ct_name:clear(),
- Rtmod:gen_decode(Erules,Tname,ComponentType),
- gen_types(Erules,Tname,Rest);
-gen_types(_,_,[]) ->
- true;
-gen_types(Erules,Tname,Type) when is_record(Type,type) ->
Rtmod = ct_gen_module(Erules),
+ Rtmod:EncDec(Erules, Tname, ComponentType),
+ gen_types(Erules, Tname, T, EncDec);
+gen_types(_, _, [], _) ->
+ ok;
+gen_types(Erules, Tname, #type{}=Type, EncDec) ->
asn1ct_name:clear(),
- Rtmod:gen_encode(Erules,Tname,Type),
- asn1ct_name:clear(),
- Rtmod:gen_decode(Erules,Tname,Type).
+ Rtmod = ct_gen_module(Erules),
+ Rtmod:EncDec(Erules, Tname, Type).
%% VARIOUS GENERATOR STUFF
%% *************************************************
@@ -599,25 +596,25 @@ gen_encode_constructed(Erules,Typename,InnerType,D) when is_record(D,type) ->
'SET' ->
Rtmod:gen_encode_set(Erules,Typename,D),
#'SET'{components=Components} = D#type.def,
- gen_types(Erules,Typename,Components);
+ gen_types(Erules, Typename, Components, gen_encode);
'SEQUENCE' ->
Rtmod:gen_encode_sequence(Erules,Typename,D),
#'SEQUENCE'{components=Components} = D#type.def,
- gen_types(Erules,Typename,Components);
+ gen_types(Erules, Typename, Components, gen_encode);
'CHOICE' ->
Rtmod:gen_encode_choice(Erules,Typename,D),
{_,Components} = D#type.def,
- gen_types(Erules,Typename,Components);
+ gen_types(Erules, Typename, Components, gen_encode);
'SEQUENCE OF' ->
Rtmod:gen_encode_sof(Erules,Typename,InnerType,D),
{_,Type} = D#type.def,
NameSuffix = asn1ct_gen:constructed_suffix(InnerType,Type#type.def),
- gen_types(Erules,[NameSuffix|Typename],Type);
+ gen_types(Erules, [NameSuffix|Typename], Type, gen_encode);
'SET OF' ->
Rtmod:gen_encode_sof(Erules,Typename,InnerType,D),
{_,Type} = D#type.def,
NameSuffix = asn1ct_gen:constructed_suffix(InnerType,Type#type.def),
- gen_types(Erules,[NameSuffix|Typename],Type);
+ gen_types(Erules, [NameSuffix|Typename], Type, gen_encode);
_ ->
exit({nyi,InnerType})
end;
@@ -630,20 +627,29 @@ gen_decode_constructed(Erules,Typename,InnerType,D) when is_record(D,type) ->
asn1ct:step_in_constructed(), %% updates namelist for exclusive decode
case InnerType of
'SET' ->
- Rtmod:gen_decode_set(Erules,Typename,D);
+ Rtmod:gen_decode_set(Erules,Typename,D),
+ #'SET'{components=Components} = D#type.def,
+ gen_types(Erules, Typename, Components, gen_decode);
'SEQUENCE' ->
- Rtmod:gen_decode_sequence(Erules,Typename,D);
+ Rtmod:gen_decode_sequence(Erules,Typename,D),
+ #'SEQUENCE'{components=Components} = D#type.def,
+ gen_types(Erules, Typename, Components, gen_decode);
'CHOICE' ->
- Rtmod:gen_decode_choice(Erules,Typename,D);
+ Rtmod:gen_decode_choice(Erules,Typename,D),
+ {_,Components} = D#type.def,
+ gen_types(Erules, Typename, Components, gen_decode);
'SEQUENCE OF' ->
- Rtmod:gen_decode_sof(Erules,Typename,InnerType,D);
+ Rtmod:gen_decode_sof(Erules,Typename,InnerType,D),
+ {_,#type{def=Def}=Type} = D#type.def,
+ NameSuffix = asn1ct_gen:constructed_suffix(InnerType, Def),
+ gen_types(Erules, [NameSuffix|Typename], Type, gen_decode);
'SET OF' ->
- Rtmod:gen_decode_sof(Erules,Typename,InnerType,D);
- _ ->
- exit({nyi,InnerType})
+ Rtmod:gen_decode_sof(Erules,Typename,InnerType,D),
+ {_,#type{def=Def}=Type} = D#type.def,
+ NameSuffix = asn1ct_gen:constructed_suffix(InnerType, Def),
+ gen_types(Erules, [NameSuffix|Typename], Type, gen_decode)
end;
-
gen_decode_constructed(Erules,Typename,InnerType,D) when is_record(D,typedef) ->
gen_decode_constructed(Erules,Typename,InnerType,D#typedef.typespec).
@@ -1283,6 +1289,7 @@ gen_head(Erules,Mod,Hrl) ->
emit({"-module('",Mod,"').",nl}),
put(currmod,Mod),
emit({"-compile(nowarn_unused_vars).",nl}),
+ emit({"-dialyzer(no_improper_lists).",nl}),
case Hrl of
0 -> ok;
_ -> emit({"-include(\"",Mod,".hrl\").",nl})
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index e51b0898be..311307cf78 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,7 +25,7 @@
-include("asn1_records.hrl").
--export([decode_class/1, decode_type/1]).
+-export([decode_class/1]).
-export([gen_encode/2,gen_encode/3,gen_decode/2,gen_decode/3]).
-export([gen_encode_prim/4]).
-export([gen_dec_prim/3]).
@@ -278,8 +279,7 @@ emit_enc_enumerated_cases(L, Tags) ->
emit_enc_enumerated_cases(L, Tags, noext).
emit_enc_enumerated_cases([{EnumName,EnumVal}|T], Tags, Ext) ->
- Bytes = encode_pos_integer(EnumVal, []),
- Len = length(Bytes),
+ {Bytes,Len} = encode_integer(EnumVal),
emit([{asis,EnumName}," -> ",
{call,ber,encode_tags,[Tags,{asis,Bytes},Len]},";",nl]),
emit_enc_enumerated_cases(T, Tags, Ext);
@@ -288,10 +288,25 @@ emit_enc_enumerated_cases([], _Tags, _Ext) ->
emit([{curr,enumval}," -> exit({error,{asn1, {enumerated_not_in_range,",{curr, enumval},"}}})"]),
emit([nl,"end"]).
-encode_pos_integer(0, [B|_Acc] = L) when B < 128 ->
+encode_integer(Val) ->
+ Bytes =
+ if
+ Val >= 0 ->
+ encode_integer_pos(Val, []);
+ true ->
+ encode_integer_neg(Val, [])
+ end,
+ {Bytes,length(Bytes)}.
+
+encode_integer_pos(0, [B|_Acc]=L) when B < 128 ->
L;
-encode_pos_integer(N, Acc) ->
- encode_pos_integer(N bsr 8, [N band 255|Acc]).
+encode_integer_pos(N, Acc) ->
+ encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
+
+encode_integer_neg(-1, [B1|_T]=L) when B1 > 127 ->
+ L;
+encode_integer_neg(N, Acc) ->
+ encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
%%===============================================================================
%%===============================================================================
@@ -1179,23 +1194,25 @@ gen_objset_enc(_,_,{unique,undefined},_,_,_,_,_) ->
gen_objset_enc(Erules, ObjSetName, UniqueName,
[{ObjName,Val,Fields}|T], ClName, ClFields,
NthObj,Acc)->
- emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl]),
CurrMod = get(currmod),
{InternalFunc,NewNthObj}=
case ObjName of
{no_mod,no_name} ->
- gen_inlined_enc_funs(Fields,ClFields,ObjSetName,NthObj);
+ gen_inlined_enc_funs(Fields, ClFields, ObjSetName, Val, NthObj);
{CurrMod,Name} ->
- emit({" fun 'enc_",Name,"'/3"}),
+ emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl,
+ " fun 'enc_",Name,"'/3;",nl]),
{[],NthObj};
{ModuleName,Name} ->
+ emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl]),
emit_ext_fun(enc,ModuleName,Name),
+ emit([";",nl]),
{[],NthObj};
_ ->
- emit({" fun 'enc_",ObjName,"'/3"}),
+ emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl,
+ " fun 'enc_",ObjName,"'/3;",nl]),
{[],NthObj}
end,
- emit({";",nl}),
gen_objset_enc(Erules, ObjSetName, UniqueName, T, ClName, ClFields,
NewNthObj, InternalFunc ++ Acc);
%% See X.681 Annex E for the following case
@@ -1223,13 +1240,14 @@ emit_default_getenc(ObjSetName,UniqueName) ->
%% gen_inlined_enc_funs for each object iterates over all fields of a
%% class, and for each typefield it checks if the object has that
%% field and emits the proper code.
-gen_inlined_enc_funs(Fields, [{typefield,_,_}|_]=T, ObjSetName, NthObj) ->
- emit([indent(3),"fun(Type, Val, _RestPrimFieldName) ->",nl,
+gen_inlined_enc_funs(Fields, [{typefield,_,_}|_]=T, ObjSetName, Val, NthObj) ->
+ emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl,
+ indent(3),"fun(Type, Val, _RestPrimFieldName) ->",nl,
indent(6),"case Type of",nl]),
gen_inlined_enc_funs1(Fields, T, ObjSetName, [], NthObj, []);
-gen_inlined_enc_funs(Fields,[_|Rest],ObjSetName,NthObj) ->
- gen_inlined_enc_funs(Fields,Rest,ObjSetName,NthObj);
-gen_inlined_enc_funs(_,[],_,NthObj) ->
+gen_inlined_enc_funs(Fields, [_|Rest], ObjSetName, Val, NthObj) ->
+ gen_inlined_enc_funs(Fields, Rest, ObjSetName, Val, NthObj);
+gen_inlined_enc_funs(_, [], _, _, NthObj) ->
{[],NthObj}.
gen_inlined_enc_funs1(Fields, [{typefield,Name,_}|Rest], ObjSetName,
@@ -1276,7 +1294,7 @@ gen_inlined_enc_funs1(Fields,[_|Rest], ObjSetName, Sep, NthObj, Acc)->
gen_inlined_enc_funs1(Fields, Rest, ObjSetName, Sep, NthObj, Acc);
gen_inlined_enc_funs1(_, [], _, _, NthObj, Acc) ->
emit([nl,indent(6),"end",nl,
- indent(3),"end"]),
+ indent(3),"end;",nl]),
{Acc,NthObj}.
emit_enc_open_type(I) ->
@@ -1358,23 +1376,25 @@ gen_objset_dec(_,_,{unique,undefined},_,_,_,_) ->
ok;
gen_objset_dec(Erules, ObjSName, UniqueName, [{ObjName,Val,Fields}|T],
ClName, ClFields, NthObj)->
- emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl]),
CurrMod = get(currmod),
NewNthObj=
case ObjName of
{no_mod,no_name} ->
- gen_inlined_dec_funs(Fields,ClFields,ObjSName,NthObj);
+ gen_inlined_dec_funs(Fields,ClFields,ObjSName,Val,NthObj);
{CurrMod,Name} ->
- emit([" fun 'dec_",Name,"'/3"]),
+ emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl,
+ " fun 'dec_",Name,"'/3;", nl]),
NthObj;
{ModuleName,Name} ->
+ emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl]),
emit_ext_fun(dec,ModuleName,Name),
+ emit([";",nl]),
NthObj;
_ ->
- emit([" fun 'dec_",ObjName,"'/3"]),
+ emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl,
+ " fun 'dec_",ObjName,"'/3;", nl]),
NthObj
end,
- emit([";",nl]),
gen_objset_dec(Erules, ObjSName, UniqueName, T, ClName,
ClFields, NewNthObj);
gen_objset_dec(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
@@ -1394,10 +1414,15 @@ emit_default_getdec(ObjSetName,UniqueName) ->
emit(["'getdec_",ObjSetName,"'(ErrV) ->",nl]),
emit([indent(2), "fun(C,V,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]).
-gen_inlined_dec_funs(Fields, ClFields, ObjSetName, NthObj) ->
+gen_inlined_dec_funs(Fields, [{typefield,_,_}|_]=ClFields, ObjSetName, Val, NthObj) ->
+ emit(["'getdec_",ObjSetName,"'(",{asis,Val},") ->",nl]),
emit([indent(3),"fun(Type, Bytes, _RestPrimFieldName) ->",nl,
indent(6),"case Type of",nl]),
- gen_inlined_dec_funs1(Fields, ClFields, ObjSetName, "", NthObj).
+ gen_inlined_dec_funs1(Fields, ClFields, ObjSetName, "", NthObj);
+gen_inlined_dec_funs(Fields, [_|ClFields], ObjSetName, Val, NthObj) ->
+ gen_inlined_dec_funs(Fields, ClFields, ObjSetName, Val, NthObj);
+gen_inlined_dec_funs(_, _, _, _,NthObj) ->
+ NthObj.
gen_inlined_dec_funs1(Fields, [{typefield,Name,Prop}|Rest],
ObjSetName, Sep0, NthObj) ->
@@ -1439,7 +1464,7 @@ gen_inlined_dec_funs1(Fields, [_|Rest], ObjSetName, Sep, NthObj)->
gen_inlined_dec_funs1(Fields, Rest, ObjSetName, Sep, NthObj);
gen_inlined_dec_funs1(_, [], _, _, NthObj) ->
emit([nl,indent(6),"end",nl,
- indent(3),"end"]),
+ indent(3),"end;",nl]),
NthObj.
emit_dec_open_type(I) ->
@@ -1534,39 +1559,6 @@ decode_class('CONTEXT') ->
decode_class('PRIVATE') ->
?PRIVATE.
-decode_type('BOOLEAN') -> 1;
-decode_type('INTEGER') -> 2;
-decode_type('BIT STRING') -> 3;
-decode_type('OCTET STRING') -> 4;
-decode_type('NULL') -> 5;
-decode_type('OBJECT IDENTIFIER') -> 6;
-decode_type('ObjectDescriptor') -> 7;
-decode_type('EXTERNAL') -> 8;
-decode_type('REAL') -> 9;
-decode_type('ENUMERATED') -> 10;
-decode_type('EMBEDDED_PDV') -> 11;
-decode_type('UTF8String') -> 12;
-decode_type('RELATIVE-OID') -> 13;
-decode_type('SEQUENCE') -> 16;
-decode_type('SEQUENCE OF') -> 16;
-decode_type('SET') -> 17;
-decode_type('SET OF') -> 17;
-decode_type('NumericString') -> 18;
-decode_type('PrintableString') -> 19;
-decode_type('TeletexString') -> 20;
-decode_type('T61String') -> 20;
-decode_type('VideotexString') -> 21;
-decode_type('IA5String') -> 22;
-decode_type('UTCTime') -> 23;
-decode_type('GeneralizedTime') -> 24;
-decode_type('GraphicString') -> 25;
-decode_type('VisibleString') -> 26;
-decode_type('GeneralString') -> 27;
-decode_type('UniversalString') -> 28;
-decode_type('BMPString') -> 30;
-decode_type('CHOICE') -> 'CHOICE'; % choice gets the tag from the actual alternative
-decode_type(Else) -> exit({error,{asn1,{unrecognized_type,Else}}}).
-
mkfuncname(#'Externaltypereference'{module=Mod,type=EType}, DecOrEnc) ->
CurrMod = get(currmod),
case CurrMod of
diff --git a/lib/asn1/src/asn1ct_gen_check.erl b/lib/asn1/src/asn1ct_gen_check.erl
index d80a02dfbf..385c67d628 100644
--- a/lib/asn1/src/asn1ct_gen_check.erl
+++ b/lib/asn1/src/asn1ct_gen_check.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 39cc0536f8..ff5b19b542 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index bdd14871d1..e09256cde9 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -499,6 +500,8 @@ per_dec_enumerated_fix_list([], Tail, _) -> Tail.
per_dec_integer_1([{'SingleValue',Value}], _Aligned) ->
{value,Value};
+per_dec_integer_1([{'ValueRange',{'MIN',_}}], Aligned) ->
+ per_dec_unconstrained(Aligned);
per_dec_integer_1([{'ValueRange',{Lb,'MAX'}}], Aligned) when is_integer(Lb) ->
per_decode_semi_constrained(Lb, Aligned);
per_dec_integer_1([{'ValueRange',{Lb,Ub}}], Aligned) when is_integer(Lb),
@@ -1094,6 +1097,9 @@ per_enc_integer_1(Val0, [Constr], Aligned) ->
per_enc_integer_2(Val, {'SingleValue',Sv}, Aligned) when is_integer(Sv) ->
per_enc_constrained(Val, Sv, Sv, Aligned);
+per_enc_integer_2(Val, {'ValueRange',{'MIN',Ub}}, Aligned)
+ when is_integer(Ub) ->
+ {[],{lt,Val,Ub+1},per_enc_unconstrained(Val, Aligned)};
per_enc_integer_2(Val0, {'ValueRange',{Lb,'MAX'}}, Aligned)
when is_integer(Lb) ->
{Prefix,Val} = sub_lb(Val0, Lb),
@@ -1114,38 +1120,41 @@ per_enc_constrained(Val0, Lb, Ub, false) ->
per_enc_constrained(Val0, Lb, Ub, true) ->
{Prefix,Val} = sub_lb(Val0, Lb),
Range = Ub - Lb + 1,
+ Check = {ult,Val,Range},
if
Range < 256 ->
NumBits = per_num_bits(Range),
- Check = {ult,Val,Range},
Put = [{put_bits,Val,NumBits,[1]}],
{Prefix,Check,Put};
Range =:= 256 ->
NumBits = 8,
- Check = {ult,Val,Range},
Put = [{put_bits,Val,NumBits,[1,align]}],
{Prefix,Check,Put};
Range =< 65536 ->
- Check = {ult,Val,Range},
Put = [{put_bits,Val,16,[1,align]}],
{Prefix,Check,Put};
true ->
- {var,VarBase} = Val,
- Bin = {var,VarBase++"@bin"},
- BinSize0 = {var,VarBase++"@bin_size0"},
- BinSize = {var,VarBase++"@bin_size"},
- Check = {ult,Val,Range},
RangeOctsLen = byte_size(binary:encode_unsigned(Range - 1)),
BitsNeeded = per_num_bits(RangeOctsLen),
- Enc = [{call,binary,encode_unsigned,[Val],Bin},
- {call,erlang,byte_size,[Bin],BinSize0},
- {sub,BinSize0,1,BinSize},
- {'cond',[['_',
- {put_bits,BinSize,BitsNeeded,[1]},
- {put_bits,Bin,binary,[8,align]}]]}],
- {Prefix,Check,Enc}
+ {Prefix,Check,per_enc_constrained_huge(BitsNeeded, Val)}
end.
+per_enc_constrained_huge(BitsNeeded, {var,VarBase}=Val) ->
+ Bin = {var,VarBase++"@bin"},
+ BinSize0 = {var,VarBase++"@bin_size0"},
+ BinSize = {var,VarBase++"@bin_size"},
+ [{call,binary,encode_unsigned,[Val],Bin},
+ {call,erlang,byte_size,[Bin],BinSize0},
+ {sub,BinSize0,1,BinSize},
+ {'cond',[['_',
+ {put_bits,BinSize,BitsNeeded,[1]},
+ {put_bits,Bin,binary,[8,align]}]]}];
+per_enc_constrained_huge(BitsNeeded, Val) when is_integer(Val) ->
+ Bin = binary:encode_unsigned(Val),
+ BinSize = erlang:byte_size(Bin),
+ [{put_bits,BinSize-1,BitsNeeded,[1]},
+ {put_bits,Val,8*BinSize,[1,align]}].
+
per_enc_unconstrained(Val, Aligned) ->
case Aligned of
false -> [];
@@ -1580,7 +1589,7 @@ do_combine_put_bits(_, _, _) ->
throw(impossible).
debit(Budget0, Alternatives) ->
- case Budget0 - log2(Alternatives) of
+ case Budget0 - math:log2(Alternatives) of
Budget when Budget > 0.0 ->
Budget;
_ ->
@@ -1593,8 +1602,6 @@ num_clauses([_|T], N) ->
num_clauses(T, N+1);
num_clauses([], N) -> N.
-log2(N) ->
- math:log(N) / math:log(2.0).
collect_put_bits(Imm) ->
lists:splitwith(fun({put_bits,V,_,_}) when is_integer(V) -> true;
@@ -1919,16 +1926,7 @@ enc_opt(nil, St) ->
enc_opt({seq,H0,T0}, St0) ->
{H,St1} = enc_opt(H0, St0),
{T,St} = enc_opt(T0, St1),
- case {H,T} of
- {none,_} ->
- {T,St};
- {{list,Imm,Data},
- {seq,{call,per,complete,[Data],_},_}} ->
- %% Get rid of any explicit 'align' added by per_enc_open_type/2.
- {{seq,{list,remove_trailing_align(Imm),Data},T},St};
- {_,_} ->
- {{seq,H,T},St}
- end;
+ {enc_opt_seq(H, T),St};
enc_opt({set,_,_}=Imm, St) ->
{Imm,St#ost{t=undefined}};
enc_opt({sub,Src0,Int,Dst}, St0) ->
@@ -1962,6 +1960,28 @@ remove_trailing_align({seq,H,T}) ->
{seq,H,remove_trailing_align(T)};
remove_trailing_align(Imm) -> Imm.
+enc_opt_seq(none, T) ->
+ T;
+enc_opt_seq({list,Imm,Data}, {seq,{call,per,complete,[Data],_},_}=T) ->
+ %% Get rid of any explicit 'align' added by per_enc_open_type/2.
+ {seq,{list,remove_trailing_align(Imm),Data},T};
+enc_opt_seq({call,_,_,_,{var,_}=Dst}=H, T) ->
+ case is_var_unused(Dst, T) of
+ false -> {seq,H,T};
+ true -> T
+ end;
+enc_opt_seq(H, T) ->
+ {seq,H,T}.
+
+is_var_unused(_, align) ->
+ true;
+is_var_unused(V, {call,_,_,Args}) ->
+ not lists:member(V, Args);
+is_var_unused(V, {cons,H,T}) ->
+ is_var_unused(V, H) andalso is_var_unused(V, T);
+is_var_unused(_, _) ->
+ false.
+
bit_size_propagate(Bin, Type, St) ->
case t_range(Type) of
any ->
@@ -2423,7 +2443,8 @@ bit_string_name2pos_fun(NNL, Src) ->
gen_name2pos(Fd, Name, Names) ->
Cs0 = gen_name2pos_cs(Names, Name),
Cs = Cs0 ++ [bit_clause(Name),nil_clause(),invalid_clause()],
- F = {function,1,Name,1,Cs},
+ F0 = {function,1,Name,1,Cs},
+ F = erl_parse:new_anno(F0),
file:write(Fd, [erl_pp:function(F)]).
gen_name2pos_cs([{K,V}|T], Name) ->
diff --git a/lib/asn1/src/asn1ct_name.erl b/lib/asn1/src/asn1ct_name.erl
index ba52e66ce3..577c15c7c0 100644
--- a/lib/asn1/src/asn1ct_name.erl
+++ b/lib/asn1/src/asn1ct_name.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/src/asn1ct_parser.yrl b/lib/asn1/src/asn1ct_parser.yrl
deleted file mode 100644
index 083162f191..0000000000
--- a/lib/asn1/src/asn1ct_parser.yrl
+++ /dev/null
@@ -1,1177 +0,0 @@
-%%<copyright>
-%% <year>1997-2008</year>
-%% <holder>Ericsson AB, All Rights Reserved</holder>
-%%</copyright>
-%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% The Initial Developer of the Original Code is Ericsson AB.
-%%</legalnotice>
-%%
-Nonterminals
-ModuleDefinition ModuleIdentifier DefinitiveIdentifier DefinitiveObjIdComponentList
-DefinitiveObjIdComponent TagDefault ExtensionDefault
-ModuleBody Exports SymbolsExported Imports SymbolsImported
-SymbolsFromModuleList SymbolsFromModule GlobalModuleReference AssignedIdentifier SymbolList
-Symbol Reference AssignmentList Assignment
-ExtensionAndException
-ComponentTypeLists
-Externaltypereference Externalvaluereference DefinedType DefinedValue
-AbsoluteReference ItemSpec ItemId ComponentId TypeAssignment
-ValueAssignment
-% ValueSetTypeAssignment
-ValueSet
-Type BuiltinType NamedType ReferencedType
-Value ValueNotNull BuiltinValue ReferencedValue NamedValue
-% BooleanType
-BooleanValue IntegerType NamedNumberList NamedNumber SignedNumber
-% inlined IntegerValue
-EnumeratedType
-% inlined Enumerations
-Enumeration EnumerationItem
-% inlined EnumeratedValue
-% RealType
-RealValue NumericRealValue SpecialRealValue BitStringType
-% inlined BitStringValue
-IdentifierList
-% OctetStringType
-% inlined OctetStringValue
-% NullType NullValue
-SequenceType ComponentTypeList ComponentType
-% SequenceValue SequenceOfValue
-ComponentValueList SequenceOfType
-SAndSOfValue ValueList SetType
-% SetValue SetOfValue
-SetOfType
-ChoiceType
-% AlternativeTypeList made common with ComponentTypeList
-ChoiceValue
-AnyValue
-AnyDefBy
-SelectionType
-TaggedType Tag ClassNumber Class
-% redundant TaggedValue
-% EmbeddedPDVType EmbeddedPDVValue ExternalType ExternalValue ObjectIdentifierType
-ObjectIdentifierValue ObjIdComponentList ObjIdComponent
-% NameForm NumberForm NameAndNumberForm
-CharacterStringType
-RestrictedCharacterStringValue CharacterStringList
-% CharSyms CharsDefn
-Quadruple
-% Group Plane Row Cell
-Tuple
-% TableColumn TableRow
-% UnrestrictedCharacterString
-CharacterStringValue
-% UnrestrictedCharacterStringValue
-ConstrainedType Constraint ConstraintSpec TypeWithConstraint
-ElementSetSpecs ElementSetSpec
-%GeneralConstraint
-UserDefinedConstraint UserDefinedConstraintParameter
-UserDefinedConstraintParameters
-ExceptionSpec
-ExceptionIdentification
-Unions
-UnionMark
-UElems
-Intersections
-IntersectionElements
-IntersectionMark
-IElems
-Elements
-Elems
-SubTypeElements
-Exclusions
-LowerEndpoint
-UpperEndpoint
-LowerEndValue
-UpperEndValue
-TypeConstraints NamedConstraint PresenceConstraint
-
-ParameterizedTypeAssignment
-ParameterList
-Parameters
-Parameter
-ParameterizedType
-
-% X.681
-ObjectClassAssignment ObjectClass ObjectClassDefn
-FieldSpecs FieldSpec OptionalitySpec WithSyntaxSpec
-TokenOrGroupSpecs TokenOrGroupSpec
-SyntaxList OptionalGroup RequiredToken Word
-TypeOptionalitySpec
-ValueOrObjectOptSpec
-VSetOrOSetOptSpec
-ValueOptionalitySpec
-ObjectOptionalitySpec
-ValueSetOptionalitySpec
-ObjectSetOptionalitySpec
-% X.681 chapter 15
-InformationFromObjects
-ValueFromObject
-%ValueSetFromObjects
-TypeFromObject
-%ObjectFromObject
-%ObjectSetFromObjects
-ReferencedObjects
-FieldName
-PrimitiveFieldName
-
-ObjectAssignment
-ObjectSetAssignment
-ObjectSet
-ObjectSetElements
-Object
-ObjectDefn
-DefaultSyntax
-DefinedSyntax
-FieldSettings
-FieldSetting
-DefinedSyntaxTokens
-DefinedSyntaxToken
-Setting
-DefinedObject
-ObjectFromObject
-ObjectSetFromObjects
-ParameterizedObject
-ExternalObjectReference
-DefinedObjectSet
-DefinedObjectClass
-ExternalObjectClassReference
-
-% X.682
-TableConstraint
-ComponentRelationConstraint
-ComponentIdList
-
-% X.683
-ActualParameter
-.
-
-%UsefulType.
-
-Terminals
-'ABSENT' 'ABSTRACT-SYNTAX' 'ALL' 'ANY'
-'APPLICATION' 'AUTOMATIC' 'BEGIN' 'BIT'
-'BOOLEAN' 'BY' 'CHARACTER' 'CHOICE' 'CLASS' 'COMPONENT'
-'COMPONENTS' 'CONSTRAINED' 'DEFAULT' 'DEFINED' 'DEFINITIONS'
-'EMBEDDED' 'END' 'ENUMERATED' 'EXCEPT' 'EXPLICIT'
-'EXPORTS' 'EXTENSIBILITY' 'EXTERNAL' 'FALSE' 'FROM' 'GeneralizedTime'
-'TYPE-IDENTIFIER'
-'IDENTIFIER' 'IMPLICIT' 'IMPLIED' 'IMPORTS'
-'INCLUDES' 'INSTANCE' 'INTEGER' 'INTERSECTION'
-'MAX' 'MIN' 'MINUS-INFINITY' 'NULL'
-'OBJECT' 'ObjectDescriptor' 'OCTET' 'OF' 'OPTIONAL' 'PDV' 'PLUS-INFINITY'
-'PRESENT' 'PRIVATE' 'REAL' 'SEQUENCE' 'SET' 'SIZE'
-'STRING' 'SYNTAX' 'TAGS' 'TRUE' 'UNION'
-'UNIQUE' 'UNIVERSAL' 'UTCTime' 'WITH'
-'{' '}' '(' ')' '.' '::=' ';' ',' '@' '*' '-' '[' ']'
-'!' '..' '...' '|' '<' ':' '^'
-number identifier typereference restrictedcharacterstringtype
-bstring hstring cstring typefieldreference valuefieldreference
-objectclassreference word.
-
-Rootsymbol ModuleDefinition.
-Endsymbol '$end'.
-
-Left 300 'EXCEPT'.
-Left 200 '^'.
-Left 200 'INTERSECTION'.
-Left 100 '|'.
-Left 100 'UNION'.
-
-
-ModuleDefinition -> ModuleIdentifier
- 'DEFINITIONS'
- TagDefault
- ExtensionDefault
- '::='
- 'BEGIN'
- ModuleBody
- 'END' :
- {'ModuleBody',Ex,Im,Types} = '$7',
- {{typereference,Pos,Name},Defid} = '$1',
- #module{
- pos= Pos,
- name= Name,
- defid= Defid,
- tagdefault='$3',
- extensiondefault='$4',
- exports=Ex,
- imports=Im,
- typeorval=Types}.
-% {module, '$1','$3','$6'}.
-% Results always in a record of type module defined in asn_records.hlr
-
-ModuleIdentifier -> typereference DefinitiveIdentifier :
- put(asn1_module,'$1'#typereference.val),
- {'$1','$2'}.
-
-DefinitiveIdentifier -> '{' DefinitiveObjIdComponentList '}' : '$2' .
-DefinitiveIdentifier -> '$empty': [].
-
-DefinitiveObjIdComponentList -> DefinitiveObjIdComponent : ['$1'].
-DefinitiveObjIdComponentList -> DefinitiveObjIdComponent DefinitiveObjIdComponentList : ['$1'|'$2'].
-
-DefinitiveObjIdComponent -> identifier : '$1' . %expanded->
-% DefinitiveObjIdComponent -> NameForm : '$1' .
-DefinitiveObjIdComponent -> number : '$1' . %expanded->
-% DefinitiveObjIdComponent -> DefinitiveNumberForm : 'fix' .
-DefinitiveObjIdComponent -> identifier '(' number ')' : {'$1','$3'} . %expanded->
-% DefinitiveObjIdComponent -> DefinitiveNameAndNumberForm : {'$1','$3'} .
-
-% DefinitiveNumberForm -> number : 'fix' .
-
-% DefinitiveNameAndNumberForm -> identifier '(' DefinitiveNumberForm ')' : 'fix' .
-
-TagDefault -> 'EXPLICIT' 'TAGS' : put(tagdefault,'EXPLICIT'),'EXPLICIT' .
-TagDefault -> 'IMPLICIT' 'TAGS' : put(tagdefault,'IMPLICIT'),'IMPLICIT' .
-TagDefault -> 'AUTOMATIC' 'TAGS' : put(tagdefault,'AUTOMATIC'),'AUTOMATIC' .
-TagDefault -> '$empty': put(tagdefault,'EXPLICIT'),'EXPLICIT'. % because this is the default
-
-ExtensionDefault -> 'EXTENSIBILITY' 'IMPLIED' : 'IMPLIED'.
-ExtensionDefault -> '$empty' : 'false'. % because this is the default
-
-ModuleBody -> Exports Imports AssignmentList : {'ModuleBody','$1','$2','$3'}.
-ModuleBody -> '$empty' : {'ModuleBody',nil,nil,[]}.
-
-Exports -> 'EXPORTS' SymbolList ';' : {exports,'$2'}.
-Exports -> 'EXPORTS' ';' : {exports,[]}.
-Exports -> '$empty' : {exports,all} .
-
-% inlined above SymbolsExported -> SymbolList : '$1'.
-% inlined above SymbolsExported -> '$empty' : [].
-
-Imports -> 'IMPORTS' SymbolsFromModuleList ';' : {imports,'$2'}.
-Imports -> 'IMPORTS' ';' : {imports,[]}.
-Imports -> '$empty' : {imports,[]} .
-
-% inlined above SymbolsImported -> SymbolsFromModuleList : '$1'.
-% inlined above SymbolsImported -> '$empty' : [].
-
-SymbolsFromModuleList -> SymbolsFromModule :['$1'].
-% SymbolsFromModuleList -> SymbolsFromModuleList SymbolsFromModule :$1.%changed
-SymbolsFromModuleList -> SymbolsFromModule SymbolsFromModuleList :['$1'|'$2'].
-
-% expanded SymbolsFromModule -> SymbolList 'FROM' GlobalModuleReference : #'SymbolsFromModule'{symbols = '$1',module='$3'}.
-SymbolsFromModule -> SymbolList 'FROM' typereference : #'SymbolsFromModule'{symbols = '$1',module='$3'}.
-SymbolsFromModule -> SymbolList 'FROM' typereference '{' ValueList '}': #'SymbolsFromModule'{symbols = '$1',module='$3'}.
-%SymbolsFromModule -> SymbolList 'FROM' typereference identifier: #'SymbolsFromModule'{symbols = '$1',module='$3'}.
-%SymbolsFromModule -> SymbolList 'FROM' typereference Externalvaluereference: #'SymbolsFromModule'{symbols = '$1',module='$3'}.
-%SymbolsFromModule -> SymbolList 'FROM' typereference DefinedValue: #'SymbolsFromModule'{symbols = '$1',module='$3'}.
-
-% inlined GlobalModuleReference -> typereference AssignedIdentifier : {'$1','$2'} .
-
-% inlined above AssignedIdentifier -> '{' ValueList '}' : '$2'.
-% replaced AssignedIdentifier -> '{' DefinedValue ObjIdComponentList '}' :{'$2','$3'}.
-% not necessary , replaced by SAndSOfValue AssignedIdentifier -> ObjectIdentifierValue :'$1'.
-% AssignedIdentifier -> DefinedValue : '$1'.
-% inlined AssignedIdentifier -> '$empty' : undefined.
-
-SymbolList -> Symbol : ['$1'].
-SymbolList -> Symbol ',' SymbolList :['$1'|'$3'].
-
-Symbol -> Reference :'$1'.
-% later Symbol -> ParameterizedReference :'$1'.
-
-Reference -> typereference :'$1'.
-Reference -> identifier:'$1'.
-Reference -> typereference '{' '}':'$1'.
-Reference -> Externaltypereference '{' '}':'$1'.
-
-% later Reference -> objectclassreference :'$1'.
-% later Reference -> objectreference :'$1'.
-% later Reference -> objectsetreference :'$1'.
-
-AssignmentList -> Assignment : ['$1'].
-% modified AssignmentList -> AssignmentList Assignment : '$1'.
-AssignmentList -> Assignment AssignmentList : ['$1'|'$2'].
-
-Assignment -> TypeAssignment : '$1'.
-Assignment -> ValueAssignment : '$1'.
-% later Assignment -> ValueSetTypeAssignment : '$1'.
-Assignment -> ObjectClassAssignment : '$1'.
-% later Assignment -> ObjectAssignment : '$1'.
-% combined with ValueAssignment Assignment -> ObjectAssignment : '$1'.
-Assignment -> ObjectSetAssignment : '$1'.
-Assignment -> ParameterizedTypeAssignment : '$1'.
-%Assignment -> ParameterizedValueAssignment : '$1'.
-%Assignment -> ParameterizedValueSetTypeAssignment : '$1'.
-%Assignment -> ParameterizedObjectClassAssignment : '$1'.
-
-ObjectClassAssignment -> typereference '::=' 'CLASS' '{' FieldSpecs '}' :
-%ObjectClassAssignment -> objectclassreference '::=' 'CLASS' '{' FieldSpecs '}' :
- #typedef{pos=element(2,'$1'),name=element(3,'$1'),typespec={'CLASS','$5',[]}}.
-ObjectClassAssignment -> typereference '::=' 'CLASS' '{' FieldSpecs '}' WithSyntaxSpec :
-%ObjectClassAssignment -> objectclassreference '::=' 'CLASS' '{' FieldSpecs '}' WithSyntaxSpec :
- #typedef{pos=element(2,'$1'),name=element(3,'$1'),typespec={'CLASS','$5','$7'}}.
-
-FieldSpecs -> FieldSpec : ['$1'].
-FieldSpecs -> FieldSpec ',' FieldSpecs : ['$1'|'$3'].
-
-FieldSpec -> typefieldreference TypeOptionalitySpec : {typefield,'$1','$2'}.
-
-FieldSpec -> valuefieldreference Type 'UNIQUE' ValueOrObjectOptSpec :
- {fixedtypevaluefield,'$1','$2','UNIQUE','$4'}.
-FieldSpec -> valuefieldreference Type ValueOrObjectOptSpec :
- {fixedtypevaluefield,'$1','$2',undefined,'$3'}.
-
-FieldSpec -> valuefieldreference typefieldreference ValueOrObjectOptSpec :
- {variabletypevaluefield, '$1','$2','$3'}.
-
-FieldSpec -> typefieldreference typefieldreference VSetOrOSetOptSpec :
- {variabletypevaluesetfield, '$1','$2','$3'}.
-
-FieldSpec -> typefieldreference Type VSetOrOSetOptSpec :
- {fixedtypevaluesetfield, '$1','$2','$3'}.
-
-TypeOptionalitySpec -> 'DEFAULT' Type : {'DEFAULT','$2'}.
-TypeOptionalitySpec -> 'OPTIONAL' : 'OPTIONAL'.
-TypeOptionalitySpec -> '$empty' : 'MANDATORY'.
-
-ValueOrObjectOptSpec -> ValueOptionalitySpec : '$1'.
-ValueOrObjectOptSpec -> ObjectOptionalitySpec : '$1'.
-ValueOrObjectOptSpec -> 'OPTIONAL' : 'OPTIONAL'.
-ValueOrObjectOptSpec -> '$empty' : 'MANDATORY'.
-
-ValueOptionalitySpec -> 'DEFAULT' Value :
- case '$2' of
- {identifier,_,Id} -> {'DEFAULT',Id};
- _ -> {'DEFAULT','$2'}
- end.
-
-%ObjectOptionalitySpec -> 'DEFAULT' Object :{'DEFAULT','$1'}.
-ObjectOptionalitySpec -> 'DEFAULT' '{' FieldSetting ',' FieldSettings '}' :
- {'DEFAULT',{object,['$2'|'$4']}}.
-ObjectOptionalitySpec -> 'DEFAULT' '{' FieldSetting '}' :
- {'DEFAULT',{object, ['$2']}}.
-%ObjectOptionalitySpec -> 'DEFAULT' '{' DefinedSyntaxTokens '}' :
-% {'DEFAULT',{object, '$2'}}.
-ObjectOptionalitySpec -> 'DEFAULT' ObjectFromObject :
- {'DEFAULT',{object, '$2'}}.
-
-
-VSetOrOSetOptSpec -> ValueSetOptionalitySpec : '$1'.
-%VSetOrOSetOptSpec -> ObjectSetOptionalitySpec : '$1'.
-VSetOrOSetOptSpec -> 'OPTIONAL' : 'OPTIONAL'.
-VSetOrOSetOptSpec -> '$empty' : 'MANDATORY'.
-
-ValueSetOptionalitySpec -> 'DEFAULT' ValueSet : {'DEFAULT','$1'}.
-
-%ObjectSetOptionalitySpec -> 'DEFAULT' ObjectSet : {'DEFAULT','$1'}.
-
-OptionalitySpec -> 'DEFAULT' Type : {'DEFAULT','$2'}.
-OptionalitySpec -> 'DEFAULT' ValueNotNull :
- case '$2' of
- {identifier,_,Id} -> {'DEFAULT',Id};
- _ -> {'DEFAULT','$2'}
- end.
-OptionalitySpec -> 'OPTIONAL' : 'OPTIONAL'.
-OptionalitySpec -> '$empty' : 'MANDATORY'.
-
-WithSyntaxSpec -> 'WITH' 'SYNTAX' SyntaxList : {'WITH SYNTAX','$3'}.
-
-SyntaxList -> '{' TokenOrGroupSpecs '}' : '$2'.
-SyntaxList -> '{' '}' : [].
-
-TokenOrGroupSpecs -> TokenOrGroupSpec : ['$1'].
-TokenOrGroupSpecs -> TokenOrGroupSpec TokenOrGroupSpecs : ['$1'|'$2'].
-
-TokenOrGroupSpec -> RequiredToken : '$1'.
-TokenOrGroupSpec -> OptionalGroup : '$1'.
-
-OptionalGroup -> '[' TokenOrGroupSpecs ']' : '$2'.
-
-RequiredToken -> typereference : '$1'.
-RequiredToken -> Word : '$1'.
-RequiredToken -> ',' : '$1'.
-RequiredToken -> PrimitiveFieldName : '$1'.
-
-Word -> 'BY' : 'BY'.
-
-ParameterizedTypeAssignment -> typereference ParameterList '::=' Type :
- #ptypedef{pos=element(2,'$1'),name=element(3,'$1'),
- args='$2', typespec='$4'}.
-
-ParameterList -> '{' Parameters '}':'$2'.
-
-Parameters -> Parameter: ['$1'].
-Parameters -> Parameter ',' Parameters: ['$1'|'$3'].
-
-Parameter -> typereference: '$1'.
-Parameter -> Value: '$1'.
-Parameter -> Type ':' typereference: {'$1','$3'}.
-Parameter -> Type ':' Value: {'$1','$3'}.
-Parameter -> '{' typereference '}': {objectset,'$2'}.
-
-
-% Externaltypereference -> modulereference '.' typereference : {'$1','$3'} .
-Externaltypereference -> typereference '.' typereference : #'Externaltypereference'{pos=element(2,'$1'),module=element(3,'$1'),type=element(3,'$3')}.
-
-% Externalvaluereference -> modulereference '.' valuereference : {'$1','$3'} .
-% inlined Externalvaluereference -> typereference '.' identifier : #'Externalvaluereference'{pos=element(2,'$1'),module=element(3,'$1'),value=element(3,'$3')}.
-
-
-DefinedType -> Externaltypereference : '$1' .
-DefinedType -> typereference :
- #'Externaltypereference'{pos='$1'#typereference.pos,
- module= get(asn1_module),
- type= '$1'#typereference.val} .
-DefinedType -> typereference ParameterList : {pt,'$1','$2'}.
-DefinedType -> Externaltypereference ParameterList : {pt,'$1','$2'}.
-
-% ActualParameterList -> '{' ActualParameters '}' : '$1'.
-
-% ActualParameters -> ActualParameter : ['$1'].
-% ActualParameters -> ActualParameter ',' ActualParameters : ['$1'|'$3'].
-
-ActualParameter -> Type : '$1'.
-ActualParameter -> ValueNotNull : '$1'.
-ActualParameter -> ValueSet : '$1'.
-% later DefinedType -> ParameterizedType : '$1' .
-% later DefinedType -> ParameterizedValueSetType : '$1' .
-
-% inlined DefinedValue -> Externalvaluereference :'$1'.
-% inlined DefinedValue -> identifier :'$1'.
-% later DefinedValue -> ParameterizedValue :'$1'.
-
-% not referenced yet AbsoluteReference -> '@' GlobalModuleReference '.' ItemSpec :{'$2','$4'}.
-
-% not referenced yet ItemSpec -> typereference :'$1'.
-% not referenced yet ItemSpec -> ItemId '.' ComponentId : {'$1','$3'}.
-
-% not referenced yet ItemId -> ItemSpec : '$1'.
-
-% not referenced yet ComponentId -> identifier :'$1'.
-% not referenced yet ComponentId -> number :'$1'.
-% not referenced yet ComponentId -> '*' :'$1'.
-
-TypeAssignment -> typereference '::=' Type :
- #typedef{pos=element(2,'$1'),name=element(3,'$1'),typespec='$3'}.
-
-ValueAssignment -> identifier Type '::=' Value :
- #valuedef{pos=element(2,'$1'),name=element(3,'$1'),type='$2',value='$4'}.
-
-% later ValueSetTypeAssignment -> typereference Type '::=' ValueSet :{'ValueSetTypeAssignment','$1','$2','$4'}.
-
-
-ValueSet -> '{' ElementSetSpec '}' : {valueset,'$2'}.
-
-% record(type,{tag,def,constraint}).
-Type -> BuiltinType :#type{def='$1'}.
-Type -> 'NULL' :#type{def='NULL'}.
-Type -> TaggedType:'$1'.
-Type -> ReferencedType:#type{def='$1'}. % change notag later
-Type -> ConstrainedType:'$1'.
-
-%ANY is here for compatibility with the old ASN.1 standard from 1988
-BuiltinType -> 'ANY' AnyDefBy:
- case '$2' of
- [] -> 'ANY';
- _ -> {'ANY DEFINED BY','$2'}
- end.
-BuiltinType -> BitStringType :'$1'.
-BuiltinType -> 'BOOLEAN' :element(1,'$1').
-BuiltinType -> CharacterStringType :'$1'.
-BuiltinType -> ChoiceType :'$1'.
-BuiltinType -> 'EMBEDDED' 'PDV' :'EMBEDDED PDV'.
-BuiltinType -> EnumeratedType :'$1'.
-BuiltinType -> 'EXTERNAL' :element(1,'$1').
-% later BuiltinType -> InstanceOfType :'$1'.
-BuiltinType -> IntegerType :'$1'.
-% BuiltinType -> 'NULL' :element(1,'$1').
-% later BuiltinType -> ObjectClassFieldType :'$1'.
-BuiltinType -> 'OBJECT' 'IDENTIFIER' :'OBJECT IDENTIFIER'.
-BuiltinType -> 'OCTET' 'STRING' :'OCTET STRING'.
-BuiltinType -> 'REAL' :element(1,'$1').
-BuiltinType -> SequenceType :'$1'.
-BuiltinType -> SequenceOfType :'$1'.
-BuiltinType -> SetType :'$1'.
-BuiltinType -> SetOfType :'$1'.
-% The so called Useful types
-BuiltinType -> 'GeneralizedTime': 'GeneralizedTime'.
-BuiltinType -> 'UTCTime' :'UTCTime'.
-BuiltinType -> 'ObjectDescriptor' : 'ObjectDescriptor'.
-
-% moved BuiltinType -> TaggedType :'$1'.
-
-
-AnyDefBy -> 'DEFINED' 'BY' identifier: '$3'.
-AnyDefBy -> '$empty': [].
-
-NamedType -> identifier Type :
-%{_,Pos,Val} = '$1',
-%{'NamedType',Pos,{Val,'$2'}}.
-V1 = '$1',
-{'NamedType',V1#identifier.pos,{V1#identifier.val,'$2'}}.
-NamedType -> SelectionType :'$1'.
-
-ReferencedType -> DefinedType : '$1'.
-% redundant ReferencedType -> UsefulType : 'fix'.
-ReferencedType -> SelectionType : '$1'.
-ReferencedType -> TypeFromObject : '$1'.
-% later ReferencedType -> ValueSetFromObjects : 'fix'.
-
-% to much conflicts Value -> AnyValue :'$1'.
-Value -> ValueNotNull : '$1'.
-Value -> 'NULL' :element(1,'$1').
-
-ValueNotNull -> BuiltinValue :'$1'.
-% inlined Value -> DefinedValue :'$1'. % DefinedValue , identifier
-% inlined Externalvaluereference -> Externalvaluereference :'$1'.
-ValueNotNull -> typereference '.' identifier :
- #'Externalvaluereference'{pos=element(2,'$1'),module=element(3,'$1'),
- value=element(3,'$3')}.
-ValueNotNull -> identifier :'$1'.
-
-
-%tmp Value -> NamedNumber: '$1'. % not a value but part of ObjIdC
-% redundant BuiltinValue -> BitStringValue :'$1'.
-BuiltinValue -> BooleanValue :'$1'.
-BuiltinValue -> CharacterStringValue :'$1'.
-BuiltinValue -> ChoiceValue :'$1'.
-% BuiltinValue -> EmbeddedPDVValue :'$1'. ==SequenceValue
-% BuiltinValue -> EnumeratedValue :'$1'. identifier
-% BuiltinValue -> ExternalValue :'$1'. ==SequenceValue
-% later BuiltinValue -> InstanceOfValue :'$1'.
-BuiltinValue -> SignedNumber :'$1'.
-% BuiltinValue -> 'NULL' :'$1'.
-% later BuiltinValue -> ObjectClassFieldValue :'$1'.
-% replaced by SAndSOfValue BuiltinValue -> ObjectIdentifierValue :'$1'.
-BuiltinValue -> bstring :element(3,'$1').
-BuiltinValue -> hstring :element(3,'$1').
-% conflict BuiltinValue -> RealValue :'$1'.
-BuiltinValue -> SAndSOfValue :'$1'.
-% replaced BuiltinValue -> SequenceOfValue :'$1'.
-% replaced BuiltinValue -> SequenceValue :'$1'.
-% replaced BuiltinValue -> SetValue :'$1'.
-% replaced BuiltinValue -> SetOfValue :'$1'.
-% conflict redundant BuiltinValue -> TaggedValue :'$1'.
-
-% inlined ReferencedValue -> DefinedValue:'$1'.
-% ReferencedValue -> Externalvaluereference:'$1'.
-% ReferencedValue -> identifier :'$1'.
-% later ReferencedValue -> ValueFromObject:'$1'.
-
-% inlined BooleanType -> BOOLEAN :'BOOLEAN'.
-
-% to much conflicts AnyValue -> Type ':' Value : {'ANYVALUE',{'$1','$3'}}.
-
-BooleanValue -> TRUE :true.
-BooleanValue -> FALSE :false.
-
-IntegerType -> 'INTEGER' : 'INTEGER'.
-IntegerType -> 'INTEGER' '{' NamedNumberList '}' : {'INTEGER','$3'}.
-
-NamedNumberList -> NamedNumber :['$1'].
-% modified NamedNumberList -> NamedNumberList ',' NamedNumber :'fix'.
-NamedNumberList -> NamedNumber ',' NamedNumberList :['$1'|'$3'].
-
-NamedNumber -> identifier '(' SignedNumber ')' : {'NamedNumber',element(3,'$1'),'$3'}.
-NamedNumber -> identifier '(' typereference '.' identifier ')' : {'NamedNumber',element(3,'$1'),{'ExternalValue',element(3,'$3'),element(3,'$5')}}.
-NamedNumber -> identifier '(' identifier ')' : {'NamedNumber',element(3,'$1'),element(3,'$3')}.
-
-%NamedValue -> identifier Value :
-% {'NamedValue',element(2,'$1'),element(3,'$1'),'$2'}.
-
-
-SignedNumber -> number : element(3,'$1').
-SignedNumber -> '-' number : - element(3,'$1').
-
-% inlined IntegerValue -> SignedNumber :'$1'.
-% conflict moved to Value IntegerValue -> identifier:'$1'.
-
-EnumeratedType -> ENUMERATED '{' Enumeration '}' :{'ENUMERATED','$3'}.
-
-% inlined Enumerations -> Enumeration :{'$1','false',[]}.
-% inlined Enumerations -> Enumeration ',' '...' : {'$1','true',[]}.
-% inlined Enumerations -> Enumeration ',' '...' ',' Enumeration : {'$1','true','$5'}.
-
-Enumeration -> EnumerationItem :['$1'].
-% modified Enumeration -> EnumerationItem ',' Enumeration :'fix'.
-Enumeration -> EnumerationItem ',' Enumeration :['$1'|'$3'].
-
-EnumerationItem -> identifier:element(3,'$1').
-EnumerationItem -> NamedNumber :'$1'.
-EnumerationItem -> '...' :'EXTENSIONMARK'.
-
-% conflict moved to Value EnumeratedValue -> identifier:'$1'.
-
-% inlined RealType -> REAL:'REAL'.
-
-RealValue -> NumericRealValue :'$1'.
-RealValue -> SpecialRealValue:'$1'.
-
-% ?? NumericRealValue -> number:'$1'. % number MUST BE '0'
-NumericRealValue -> SAndSOfValue : '$1'. % Value of the associated sequence type
-
-SpecialRealValue -> 'PLUS-INFINITY' :'$1'.
-SpecialRealValue -> 'MINUS-INFINITY' :'$1'.
-
-BitStringType -> 'BIT' 'STRING' :{'BIT STRING',[]}.
-BitStringType -> 'BIT' 'STRING' '{' NamedNumberList '}' :{'BIT STRING','$4'}.
-% NamedBitList replaced by NamedNumberList to reduce the grammar
-% Must check later that all "numbers" are positive
-
-% inlined BitStringValue -> bstring:'$1'.
-% inlined BitStringValue -> hstring:'$1'.
-% redundant use SequenceValue BitStringValue -> '{' IdentifierList '}' :$2.
-% redundant use SequenceValue BitStringValue -> '{' '}' :'fix'.
-
-IdentifierList -> identifier :[element(3,'$1')].
-% modified IdentifierList -> IdentifierList ',' identifier :'$1'.
-IdentifierList -> identifier ',' IdentifierList :[element(3,'$1')|'$3'].
-
-% inlined OctetStringType -> 'OCTET' 'STRING' :'OCTET STRING'.
-
-% inlined OctetStringValue -> bstring:'$1'.
-% inlined OctetStringValue -> hstring:'$1'.
-
-% inlined NullType -> 'NULL':'NULL'.
-
-% inlined NullValue -> NULL:'NULL'.
-
-% result is {'SEQUENCE',Optionals,Extensionmark,Componenttypelist}.
-SequenceType -> SEQUENCE '{' ComponentTypeList '}' :{'SEQUENCE','$3'}.
-% SequenceType -> SEQUENCE '{' ComponentTypeLists '}' :{'SEQUENCE','$3'}.
-% SequenceType -> SEQUENCE '{' ExtensionAndException '}' :{'SEQUENCE','$3'}.
-SequenceType -> SEQUENCE '{' '}' :{'SEQUENCE',[]}.
-
-% result is {RootComponentList,ExtensionAndException,AdditionalComponentTypeList}.
-%ComponentTypeLists -> ComponentTypeList ',' ExtensionAndException :{'$1','$3',[]}.
-%ComponentTypeLists -> ComponentTypeList :{'$1','false',[]}.
-%ComponentTypeLists -> ComponentTypeList ',' ExtensionAndException
-% ',' ComponentTypeList :{'$1','$3', '$5'}.
-%ComponentTypeLists -> ExtensionAndException ',' ComponentTypeList :{[],'$1','$3'}.
-
-ComponentTypeList -> ComponentType :['$1'].
-% modified below ComponentTypeList -> ComponentTypeList ',' ComponentType :'$1'.
-ComponentTypeList -> ComponentType ',' ComponentTypeList :['$1'|'$3'].
-
-% -record('ComponentType',{pos,name,type,attrib}).
-ComponentType -> '...' ExceptionSpec :{'EXTENSIONMARK',element(2,'$1'),'$2'}.
-ComponentType -> NamedType :
- {'NamedType',Pos,{Name,Type}} = '$1',
- #'ComponentType'{pos=Pos,name=Name,typespec=Type,prop=mandatory}.
-ComponentType -> NamedType 'OPTIONAL' :
- {'NamedType',Pos,{Name,Type}} = '$1',
- #'ComponentType'{pos=Pos,name=Name,typespec=Type,prop='OPTIONAL'}.
-ComponentType -> NamedType 'DEFAULT' Value:
- {'NamedType',Pos,{Name,Type}} = '$1',
- #'ComponentType'{pos=Pos,name=Name,typespec=Type,prop={'DEFAULT','$3'}}.
-ComponentType -> 'COMPONENTS' 'OF' Type :{'COMPONENTS OF','$3'}.
-
-% redundant ExtensionAndException -> '...' : extensionmark.
-% ExtensionAndException -> '...' ExceptionSpec : {extensionmark,'$2'}.
-
-% replaced SequenceValue -> '{' ComponentValueList '}':'$2'.
-% replaced SequenceValue -> '{' '}':[].
-
-ValueList -> Value :['$1'].
-ValueList -> NamedNumber :['$1'].
-% modified ValueList -> ValueList ',' Value :'$1'.
-ValueList -> Value ',' ValueList :['$1'|'$3'].
-ValueList -> Value ',' '...' :['$1' |[]].
-ValueList -> Value ValueList : ['$1',space|'$2'].
-ValueList -> NamedNumber ValueList: ['$1',space|'$2'].
-
-%ComponentValueList -> identifier ObjIdComponent:[{'NamedValue','$1','$2'}].
-%ComponentValueList -> NamedValue :['$1'].
-%ComponentValueList -> NamedValue ',' ComponentValueList:['$1'|'$3'].
-%ComponentValueList -> identifier ObjIdComponent ',' ComponentValueList :[{'NamedValue', '$1','$2'}|'$4'].
-
-SequenceOfType -> SEQUENCE OF Type : {'SEQUENCE OF','$3'}.
-
-% replaced SequenceOfValue with SAndSOfValue
-
-SAndSOfValue -> '{' ValueList '}' :'$2'.
-%SAndSOfValue -> '{' ComponentValueList '}' :'$2'.
-SAndSOfValue -> '{' '}' :[].
-
-% save for later SetType ->
-% result is {'SET',Optionals,Extensionmark,Componenttypelist}.
-SetType -> SET '{' ComponentTypeList '}' :{'SET','$3'}.
-% SetType -> SET '{' ExtensionAndException '}' :{'SET','$3'}.
-SetType -> SET '{' '}' :{'SET',[]}.
-
-% replaced SetValue with SAndSOfValue
-
-SetOfType -> SET OF Type : {'SET OF','$3'}.
-
-% replaced SetOfValue with SAndSOfValue
-
-ChoiceType -> 'CHOICE' '{' ComponentTypeList '}' :{'CHOICE','$3'}.
-% AlternativeTypeList is replaced by ComponentTypeList
-ChoiceValue -> identifier ':' Value : {'ChoiceValue',element(3,'$1'),'$3'}.
-% save for later SelectionType ->
-
-TaggedType -> Tag Type : '$2'#type{tag=['$1'#tag{type={default,get(tagdefault)}}]}.
-TaggedType -> Tag IMPLICIT Type :'$3'#type{tag=['$1'#tag{type='IMPLICIT'}]}.
-TaggedType -> Tag EXPLICIT Type :'$3'#type{tag=['$1'#tag{type='EXPLICIT'}]}.
-
-Tag -> '[' Class ClassNumber ']': #tag{class='$2',number='$3'}.
-Tag -> '[' Class typereference '.' identifier ']':
- #tag{class='$2',number=#'Externalvaluereference'{pos=element(2,'$3'),module=element(3,'$3'),
- value=element(3,'$5')}}.
-Tag -> '[' Class number ']': #tag{class='$2',number=element(3,'$3')}.
-Tag -> '[' Class identifier ']': #tag{class='$2',number=element(3,'$3')}.
-
-ClassNumber -> number :element(3,'$1').
-% inlined above ClassNumber -> typereference '.' identifier :{'Externalvaluereference',element(3,'$1'),element(3,'$3')}.
-ClassNumber -> identifier :element(3,'$1').
-
-Class -> 'UNIVERSAL' :element(1,'$1').
-Class -> 'APPLICATION' :element(1,'$1').
-Class -> 'PRIVATE' :element(1,'$1').
-Class -> '$empty' :'CONTEXT'.
-
-% conflict redundant TaggedValue -> Value:'$1'.
-
-% inlined EmbeddedPDVType -> 'EMBEDDED' 'PDV' :'EMBEDDED PDV'.
-
-% inlined EmbeddedPDVValue -> SequenceValue:'$1'.
-
-% inlined ExternalType -> 'EXTERNAL' :'EXTERNAL'.
-
-% inlined ExternalValue -> SequenceValue :'$1'.
-
-% inlined ObjectIdentifierType -> 'OBJECT' 'IDENTIFIER' :'OBJECT IDENTIFIER'.
-
-ObjectIdentifierValue -> '{' ObjIdComponentList '}' :'$2'.
-% inlined ObjectIdentifierValue -> SequenceAndSequenceOfValue :'$1'.
-% ObjectIdentifierValue -> '{' identifier ObjIdComponentList '}' :{'ObjectIdentifierValue','$2','$3'}.
-% ObjectIdentifierValue -> '{' typereference '.' identifier ObjIdComponentList '}' :{'ObjectIdentifierValue',{'$2','$4'},'$5'}.
-
-ObjIdComponentList -> Value:'$1'.
-ObjIdComponentList -> Value ObjIdComponentList :['$1'|'$2'].
-%ObjIdComponentList -> DefinedValue:'$1'.
-%ObjIdComponentList -> number:'$1'.
-%ObjIdComponentList -> DefinedValue ObjIdComponentList :['$1'|'$2'].
-%ObjIdComponentList -> number ObjIdComponentList :['$1'|'$2'].
-%ObjIdComponentList -> ObjIdComponent ObjIdComponentList :['$1'|'$2'].
-%ObjIdComponentList -> ObjIdComponent ObjIdComponentList :['$1'|'$2'].
-
-% redundant ObjIdComponent -> NameForm :'$1'. % expanded
-% replaced by 2 ObjIdComponent -> NumberForm :'$1'.
-% ObjIdComponent -> number :'$1'.
-% ObjIdComponent -> DefinedValue :'$1'. % means DefinedValue
-% ObjIdComponent -> NameAndNumberForm :'$1'.
-% ObjIdComponent -> NamedNumber :'$1'.
-% NamedBit replaced by NamedNumber to reduce grammar
-% must check later that "number" is positive
-
-% NameForm -> identifier:'$1'.
-
-% inlined NumberForm -> number :'$1'.
-% inlined NumberForm -> DefinedValue :'$1'.
-
-% replaced by NamedBit NameAndNumberForm -> identifier '(' NumberForm ')'.
-% NameAndNumberForm -> NamedBit:'$1'.
-
-
-CharacterStringType -> restrictedcharacterstringtype :element(3,'$1').
-CharacterStringType -> 'CHARACTER' 'STRING' :'CHARACTER STRING'.
-
-RestrictedCharacterStringValue -> cstring :element(3, '$1').
-% modified below RestrictedCharacterStringValue -> CharacterStringList :'$1'.
-% conflict vs BuiltinValue RestrictedCharacterStringValue -> SequenceAndSequenceOfValue :'$1'.
-RestrictedCharacterStringValue -> Quadruple :'$1'.
-RestrictedCharacterStringValue -> Tuple :'$1'.
-
-% redundant CharacterStringList -> '{' ValueList '}' :'$2'. % modified
-
-% redundant CharSyms -> CharsDefn :'$1'.
-% redundant CharSyms -> CharSyms ',' CharsDefn :['$1'|'$3'].
-
-% redundant CharsDefn -> cstring :'$1'.
-% temporary replaced see below CharsDefn -> DefinedValue :'$1'.
-% redundant CharsDefn -> Value :'$1'.
-
-Quadruple -> '{' number ',' number ',' number ',' number '}' :{'Quadruple','$2','$4','$6','$8'}.
-% {Group,Plane,Row,Cell}
-
-Tuple -> '{' number ',' number '}' :{'Tuple', '$2','$4'}.
-% {TableColumn,TableRow}
-
-% inlined UnrestrictedCharacterString -> 'CHARACTER' 'STRING' :'CHARACTER STRING'.
-
-CharacterStringValue -> RestrictedCharacterStringValue :'$1'.
-% conflict vs BuiltinValue CharacterStringValue -> SequenceValue :'$1'. % UnrestrictedCharacterStringValue
-
-% inlined UsefulType -> typereference :'$1'.
-
-SelectionType -> identifier '<' Type : {'SelectionType',element(3,'$1'),'$3'}.
-
-ConstrainedType -> Type Constraint :
- '$1'#type{constraint=merge_constraints(['$2'])}.
-ConstrainedType -> Type Constraint Constraint :
- '$1'#type{constraint=merge_constraints(['$2','$3'])}.
-ConstrainedType -> Type Constraint Constraint Constraint:
- '$1'#type{constraint=merge_constraints(['$2','$3','$4'])}.
-ConstrainedType -> Type Constraint Constraint Constraint Constraint:
- '$1'#type{constraint=merge_constraints(['$2','$3','$4','$5'])}.
-%ConstrainedType -> Type Constraint :'$1'#type{constraint='$2'}.
-%ConstrainedType -> Type Constraint :'$1'#type{constraint='$2'}.
-ConstrainedType -> TypeWithConstraint :'$1'.
-
-TypeWithConstraint -> 'SET' Constraint 'OF' Type :
- #type{def = {'SET OF','$4'},constraint=merge_constraints(['$2'])}.
-TypeWithConstraint -> 'SET' 'SIZE' Constraint 'OF' Type :
- #type{def = {'SET OF','$5'},constraint = merge_constraints([#constraint{c={'SizeConstraint','$3'#constraint.c}}])}.
-TypeWithConstraint -> 'SEQUENCE' Constraint 'OF' Type :
- #type{def = {'SEQUENCE OF','$4'},constraint =
- merge_constraints(['$2'])}.
-TypeWithConstraint -> 'SEQUENCE' 'SIZE' Constraint 'OF' Type :
- #type{def = {'SEQUENCE OF','$5'},constraint = merge_constraints([#constraint{c={'SizeConstraint','$3'#constraint.c}}])}.
-
-
-Constraint -> '(' ConstraintSpec ExceptionSpec ')' :
- #constraint{c='$2',e='$3'}.
-
-% inlined Constraint -> SubTypeConstraint :'$1'.
-ConstraintSpec -> ElementSetSpecs :'$1'.
-ConstraintSpec -> UserDefinedConstraint :'$1'.
-ConstraintSpec -> TableConstraint :'$1'.
-
-TableConstraint -> ComponentRelationConstraint : '$1'.
-TableConstraint -> ObjectSet : '$1'.
-%TableConstraint -> '{' typereference '}' :tableconstraint.
-
-ComponentRelationConstraint -> '{' typereference '}' '{' '@' ComponentIdList '}' : componentrelation.
-ComponentRelationConstraint -> '{' typereference '}' '{' '@' '.' ComponentIdList '}' : componentrelation.
-
-ComponentIdList -> identifier: ['$1'].
-ComponentIdList -> identifier '.' ComponentIdList: ['$1'| '$3'].
-
-
-% later ConstraintSpec -> GeneralConstraint :'$1'.
-
-% from X.682
-UserDefinedConstraint -> 'CONSTRAINED' 'BY' '{' '}' : {constrained_by,[]}.
-UserDefinedConstraint -> 'CONSTRAINED' 'BY'
- '{' UserDefinedConstraintParameters '}' : {constrained_by,'$4'}.
-
-UserDefinedConstraintParameters -> UserDefinedConstraintParameter : ['$1'].
-UserDefinedConstraintParameters ->
- UserDefinedConstraintParameter ','
- UserDefinedConstraintParameters: ['$1'|'$3'].
-
-UserDefinedConstraintParameter -> Type '.' ActualParameter : {'$1','$3'}.
-UserDefinedConstraintParameter -> ActualParameter : '$1'.
-
-
-
-ExceptionSpec -> '!' ExceptionIdentification : '$1'.
-ExceptionSpec -> '$empty' : undefined.
-
-ExceptionIdentification -> SignedNumber : '$1'.
-% inlined ExceptionIdentification -> DefinedValue : '$1'.
-ExceptionIdentification -> typereference '.' identifier :
- #'Externalvaluereference'{pos=element(2,'$1'),module=element(3,'$1'),
- value=element(3,'$1')}.
-ExceptionIdentification -> identifier :'$1'.
-ExceptionIdentification -> Type ':' Value : {'$1','$3'}.
-
-% inlined SubTypeConstraint -> ElementSetSpec
-
-ElementSetSpecs -> ElementSetSpec : '$1'.
-ElementSetSpecs -> ElementSetSpec ',' '...': {'$1',[]}.
-ElementSetSpecs -> '...' ',' ElementSetSpec : {[],'$3'}.
-ElementSetSpecs -> ElementSetSpec ',' '...' ',' ElementSetSpec : {'$1','$5'}.
-
-ElementSetSpec -> Unions : '$1'.
-ElementSetSpec -> 'ALL' Exclusions : {'ALL','$2'}.
-
-Unions -> Intersections : '$1'.
-Unions -> UElems UnionMark IntersectionElements :
- case {'$1','$3'} of
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {'SingleValue',ordsets:union(to_set(V1),to_set(V2))}
- end.
-
-UElems -> Unions :'$1'.
-
-Intersections -> IntersectionElements :'$1'.
-Intersections -> IElems IntersectionMark IntersectionElements :
- case {'$1','$3'} of
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {'SingleValue',ordsets:intersection(to_set(V1),to_set(V2))};
- {V1,V2} when list(V1) ->
- V1 ++ [V2];
- {V1,V2} ->
- [V1,V2]
- end.
-%Intersections -> IElems '^' IntersectionElements :{'INTERSECTION','$1','$3'}.
-%Intersections -> IElems 'INTERSECTION' IntersectionElements :{'INTERSECTION','$1','$3'}.
-
-IElems -> Intersections :'$1'.
-
-IntersectionElements -> Elements :'$1'.
-IntersectionElements -> Elems Exclusions :{'$1','$2'}.
-
-Elems -> Elements :'$1'.
-
-Exclusions -> 'EXCEPT' Elements :{'EXCEPT','$2'}.
-
-IntersectionMark -> 'INTERSECTION':'$1'.
-IntersectionMark -> '^':'$1'.
-UnionMark -> 'UNION':'$1'.
-UnionMark -> '|':'$1'.
-
-
-Elements -> SubTypeElements : '$1'.
-%Elements -> ObjectSetElements : '$1'.
-Elements -> '(' ElementSetSpec ')' : '$2'.
-Elements -> ReferencedType : '$1'.
-
-SubTypeElements -> ValueList : {'SingleValue','$1'}. % NOTE it must be a Value
-% The rule above modifyed only because of conflicts
-SubTypeElements -> 'INCLUDES' Type : {'ContainedSubType','$2'}.
-%not lalr1 if this is activated SubTypeElements -> Type : {'TypeConstraint','$1'}.
-SubTypeElements -> LowerEndpoint '..' UpperEndpoint : {'ValueRange',{'$1','$3'}}.
-SubTypeElements -> 'FROM' Constraint : {'PermittedAlphabet','$2'#constraint.c}.
-SubTypeElements -> 'SIZE' Constraint: {'SizeConstraint','$2'#constraint.c}.
-% later will introduce conflicts related to NULL SubTypeElements -> Type : {'TypeConstraint','$1'}.
-SubTypeElements -> 'WITH' 'COMPONENT' Constraint:{'WITH COMPONENT','$3'}.
-SubTypeElements -> 'WITH' 'COMPONENTS' '{' TypeConstraints '}':{'WITH COMPONENTS',{'FullSpecification','$4'}}.
-SubTypeElements -> 'WITH' 'COMPONENTS' '{' '...' ',' TypeConstraints '}' :{'WITH COMPONENTS',{'PartialSpecification','$3'}}.
-
-% inlined above InnerTypeConstraints ::=
-% inlined above SingleTypeConstraint::= Constraint
-% inlined above MultipleTypeConstraints ::= FullSpecification | PartialSpecification
-% inlined above FullSpecification ::= "{" TypeConstraints "}"
-% inlined above PartialSpecification ::= "{" "..." "," TypeConstraints "}"
-% TypeConstraints -> identifier : [{'NamedConstraint',element(3,'$1'),undefined,undefined}]. % is this really meaningful or allowed
-TypeConstraints -> NamedConstraint : ['$1'].
-TypeConstraints -> NamedConstraint ',' TypeConstraints : ['$1'|'$3'].
-TypeConstraints -> identifier : ['$1'].
-TypeConstraints -> identifier ',' TypeConstraints : ['$1'|'$3'].
-
-NamedConstraint -> identifier Constraint PresenceConstraint :{'NamedConstraint',element(3,'$1'),'$2','$3'}.
-NamedConstraint -> identifier Constraint :{'NamedConstraint',element(3,'$1'),'$2',undefined}.
-NamedConstraint -> identifier PresenceConstraint :{'NamedConstraint',element(3,'$1'),undefined,'$2'}.
-
-PresenceConstraint -> 'PRESENT' : 'PRESENT'.
-PresenceConstraint -> 'ABSENT' : 'ABSENT'.
-PresenceConstraint -> 'OPTIONAL' : 'OPTIONAL'.
-
-
-
-LowerEndpoint -> LowerEndValue :'$1'.
-%LowerEndpoint -> LowerEndValue '<':{gt,'$1'}.
-LowerEndpoint -> LowerEndValue '<':('$1'+1).
-
-UpperEndpoint -> UpperEndValue :'$1'.
-%UpperEndpoint -> '<' UpperEndValue :{lt,'$2'}.
-UpperEndpoint -> '<' UpperEndValue :('$2'-1).
-
-LowerEndValue -> Value :'$1'.
-LowerEndValue -> 'MIN' :'MIN'.
-
-UpperEndValue -> Value :'$1'.
-UpperEndValue -> 'MAX' :'MAX'.
-
-
-% X.681
-
-
-% X.681 chap 15
-
-%TypeFromObject -> ReferencedObjects '.' FieldName : {'$1','$3'}.
-TypeFromObject -> typereference '.' FieldName : {'$1','$3'}.
-
-ReferencedObjects -> typereference : '$1'.
-%ReferencedObjects -> ParameterizedObject
-%ReferencedObjects -> DefinedObjectSet
-%ReferencedObjects -> ParameterizedObjectSet
-
-FieldName -> typefieldreference : ['$1'].
-FieldName -> valuefieldreference : ['$1'].
-FieldName -> FieldName '.' FieldName : ['$1' | '$3'].
-
-PrimitiveFieldName -> typefieldreference : '$1'.
-PrimitiveFieldName -> valuefieldreference : '$1'.
-
-%ObjectSetAssignment -> typereference DefinedObjectClass '::=' ObjectSet: null.
-ObjectSetAssignment -> typereference typereference '::=' ObjectSet :
- #typedef{pos=element(2,'$1'),name=element(3,'$1'),typespec={'ObjectSet',element(3,'$2'), '$4'}}.
-ObjectSetAssignment -> typereference typereference '.' typereference '::=' ObjectSet.
-
-ObjectSet -> '{' ElementSetSpecs '}' : '$2'.
-ObjectSet -> '{' '...' '}' : ['EXTENSIONMARK'].
-
-%ObjectSetElements -> Object.
-% ObjectSetElements -> identifier : '$1'.
-%ObjectSetElements -> DefinedObjectSet.
-%ObjectSetElements -> ObjectSetFromObjects.
-%ObjectSetElements -> ParameterizedObjectSet.
-
-%ObjectAssignment -> identifier DefinedObjectClass '::=' Object.
-ObjectAssignment -> ValueAssignment.
-%ObjectAssignment -> identifier typereference '::=' Object.
-%ObjectAssignment -> identifier typereference '.' typereference '::=' Object.
-
-%Object -> DefinedObject: '$1'.
-%Object -> ExternalObjectReference: '$1'.%Object -> DefinedObject: '$1'.
-Object -> typereference '.' identifier: '$1'.%Object -> DefinedObject: '$1'.
-Object -> identifier: '$1'.%Object -> DefinedObject: '$1'.
-
-%Object -> ObjectDefn -> DefaultSyntax: '$1'.
-Object -> '{' FieldSetting ',' FieldSettings '}' : ['$2'|'$4'].
-Object -> '{' FieldSetting '}' :['$2'].
-
-%% For User-friendly notation
-%% Object -> ObjectDefn -> DefinedSyntax
-Object -> '{' '}'.
-Object -> '{' DefinedSyntaxTokens '}'.
-
-% later Object -> ParameterizedObject: '$1'. look in x.683
-
-%DefinedObject -> ExternalObjectReference: '$1'.
-%DefinedObject -> identifier: '$1'.
-
-DefinedObjectClass -> typereference.
-%DefinedObjectClass -> objectclassreference.
-DefinedObjectClass -> ExternalObjectClassReference.
-%DefinedObjectClass -> typereference '.' objectclassreference.
-%%DefinedObjectClass -> UsefulObjectClassReference.
-
-ExternalObjectReference -> typereference '.' identifier.
-ExternalObjectClassReference -> typereference '.' typereference.
-%%ExternalObjectClassReference -> typereference '.' objectclassreference.
-
-ObjectDefn -> DefaultSyntax: '$1'.
-%ObjectDefn -> DefinedSyntax: '$1'.
-
-ObjectFromObject -> ReferencedObjects '.' FieldName : {'ObjectFromObject','$1','$3'}.
-
-% later look in x.683 ParameterizedObject ->
-
-%DefaultSyntax -> '{' '}'.
-%DefaultSyntax -> '{' FieldSettings '}': '$2'.
-DefaultSyntax -> '{' FieldSetting ',' FieldSettings '}': '$2'.
-DefaultSyntax -> '{' FieldSetting '}': '$2'.
-
-FieldSetting -> PrimitiveFieldName Setting: {'$1','$2'}.
-
-FieldSettings -> FieldSetting ',' FieldSettings: ['$1'|'$3'].
-FieldSettings -> FieldSetting ',' FieldSettings: ['$1'|'$3'].
-FieldSettings -> FieldSetting: '$1'.
-
-%DefinedSyntax -> '{' '}'.
-DefinedSyntax -> '{' DefinedSyntaxTokens '}': '$2'.
-
-DefinedSyntaxTokens -> DefinedSyntaxToken: '$1'.
-DefinedSyntaxTokens -> DefinedSyntaxToken DefinedSyntaxTokens: ['$1'|'$2'].
-
-% expanded DefinedSyntaxToken -> Literal: '$1'.
-%DefinedSyntaxToken -> typereference: '$1'.
-DefinedSyntaxToken -> word: '$1'.
-DefinedSyntaxToken -> ',': '$1'.
-DefinedSyntaxToken -> Setting: '$1'.
-%DefinedSyntaxToken -> '$empty': nil .
-
-% Setting ::= Type|Value|ValueSet|Object|ObjectSet
-Setting -> Type: '$1'.
-%Setting -> Value: '$1'.
-%Setting -> ValueNotNull: '$1'.
-Setting -> BuiltinValue: '$1'.
-Setting -> ValueSet: '$1'.
-%Setting -> Object: '$1'.
-%Setting -> ExternalObjectReference.
-Setting -> typereference '.' identifier.
-Setting -> identifier.
-Setting -> ObjectDefn.
-
-Setting -> ObjectSet: '$1'.
-
-
-Erlang code.
-%%-author('[email protected]').
--copyright('Copyright (c) 1991-99 Ericsson Telecom AB').
--vsn('$Revision: /main/release/1 $').
--include("asn1_records.hrl").
-
-to_set(V) when list(V) ->
- ordsets:list_to_set(V);
-to_set(V) ->
- ordsets:list_to_set([V]).
-
-merge_constraints({Rlist,ExtList}) -> % extensionmarker in constraint
- {merge_constraints(Rlist,[],[]),
- merge_constraints(ExtList,[],[])};
-
-merge_constraints(Clist) ->
- merge_constraints(Clist, [], []).
-
-merge_constraints([Ch|Ct],Cacc, Eacc) ->
- NewEacc = case Ch#constraint.e of
- undefined -> Eacc;
- E -> [E|Eacc]
- end,
- merge_constraints(Ct,[fixup_constraint(Ch#constraint.c)|Cacc],NewEacc);
-
-merge_constraints([],Cacc,[]) ->
- lists:flatten(Cacc);
-merge_constraints([],Cacc,Eacc) ->
- lists:flatten(Cacc) ++ [{'Errors',Eacc}].
-
-fixup_constraint(C) ->
- case C of
- {'SingleValue',V} when list(V) ->
- [C,
- {'ValueRange',{lists:min(V),lists:max(V)}}];
- {'PermittedAlphabet',{'SingleValue',V}} when list(V) ->
- V2 = {'SingleValue',
- ordsets:list_to_set(lists:flatten(V))},
- {'PermittedAlphabet',V2};
- {'PermittedAlphabet',{'SingleValue',V}} ->
- V2 = {'SingleValue',[V]},
- {'PermittedAlphabet',V2};
- {'SizeConstraint',Sc} ->
- {'SizeConstraint',fixup_size_constraint(Sc)};
-
- List when list(List) ->
- [fixup_constraint(Xc)||Xc <- List];
- Other ->
- Other
- end.
-
-fixup_size_constraint({'ValueRange',{Lb,Ub}}) ->
- {Lb,Ub};
-fixup_size_constraint({{'ValueRange',R},[]}) ->
- {R,[]};
-fixup_size_constraint({[],{'ValueRange',R}}) ->
- {[],R};
-fixup_size_constraint({{'ValueRange',R1},{'ValueRange',R2}}) ->
- {R1,R2};
-fixup_size_constraint({'SingleValue',[Sv]}) ->
- fixup_size_constraint({'SingleValue',Sv});
-fixup_size_constraint({'SingleValue',L}) when list(L) ->
- ordsets:list_to_set(L);
-fixup_size_constraint({'SingleValue',L}) ->
- {L,L};
-fixup_size_constraint({C1,C2}) ->
- {fixup_size_constraint(C1), fixup_size_constraint(C2)}.
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl
index 3891fce8d3..120ca67226 100644
--- a/lib/asn1/src/asn1ct_parser2.erl
+++ b/lib/asn1/src/asn1ct_parser2.erl
@@ -4,23 +4,24 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(asn1ct_parser2).
--export([parse/1]).
+-export([parse/2,format_error/1]).
-include("asn1_records.hrl").
%% Only used internally within this module.
@@ -28,26 +29,34 @@
-record(constraint, {c,e}).
-record(identifier, {pos,val}).
-%% parse all types in module
-parse(Tokens) ->
- case catch parse_ModuleDefinition(Tokens) of
- {'EXIT',Reason} ->
- {error,{{undefined,get(asn1_module),
- [internal,error,'when',parsing,module,definition,Reason]},
- hd(Tokens)}};
- {asn1_error,Reason} ->
- {error,{Reason,hd(Tokens)}};
- {ModuleDefinition,Rest1} ->
- {Types,Rest2} = parse_AssignmentList(Rest1),
- clean_process_dictionary(),
- case Rest2 of
- [{'END',_}|_Rest3] ->
- {ok,ModuleDefinition#module{typeorval = Types}};
- _ ->
- {error,{{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'END']},
- hd(Rest2)}}
- end
+parse(File0, Tokens0) ->
+ try do_parse(Tokens0) of
+ {ok,#module{}}=Result ->
+ Result
+ catch
+ throw:{asn1_error,Fun} when is_function(Fun, 0) ->
+ handle_parse_error(File0, Fun());
+ throw:{asn1_error,{parse_error,Tokens}} ->
+ handle_parse_error(File0, Tokens)
+ after
+ clean_process_dictionary()
+ end.
+
+handle_parse_error(File0, [Token|_]) ->
+ File = filename:basename(File0),
+ Line = get_line(Token),
+ Error = {structured_error,{File,Line},?MODULE,
+ {syntax_error,get_token(Token)}},
+ {error,[Error]}.
+
+do_parse(Tokens0) ->
+ {ModuleDefinition,Tokens1} = parse_ModuleDefinition(Tokens0),
+ {Types,Tokens2} = parse_AssignmentList(Tokens1),
+ case Tokens2 of
+ [{'END',_}|_Rest3] ->
+ {ok,ModuleDefinition#module{typeorval=Types}};
+ _ ->
+ parse_error(Tokens2)
end.
clean_process_dictionary() ->
@@ -57,6 +66,11 @@ clean_process_dictionary() ->
_ = erase(extensiondefault),
ok.
+format_error({syntax_error,Token}) when is_atom(Token) ->
+ io_lib:format("syntax error before: '~s'", [Token]);
+format_error({syntax_error,Token}) ->
+ io_lib:format("syntax error before: '~p'", [Token]).
+
parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) ->
put(asn1_module,ModuleIdentifier),
{_DefinitiveIdentifier,Rest02} =
@@ -70,9 +84,7 @@ parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) ->
[{'DEFINITIONS',_}|Rest03] ->
Rest03;
_ ->
- throw({asn1_error,{get_line(hd(Rest02)),get(asn1_module),
- [got,get_token(hd(Rest02)),
- expected,'DEFINITIONS']}})
+ parse_error(Rest02)
end,
{TagDefault,Rest2} =
case Rest of
@@ -104,12 +116,11 @@ parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) ->
extensiondefault = ExtensionDefault,
exports = Exports,
imports = {imports, Imports}}, Rest6};
- _ -> throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
- [got,get_token(hd(Rest3)),expected,"::= BEGIN"]}})
+ _ ->
+ parse_error(Rest3)
end;
parse_ModuleDefinition(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,typereference]}}).
+ parse_error(Tokens).
parse_Exports([{'EXPORTS',_L1},{';',_L2}|Rest]) ->
{{exports,[]},Rest};
@@ -122,8 +133,7 @@ parse_Exports([{'EXPORTS',_L1}|Rest]) ->
[{';',_}|Rest3] ->
{{exports,SymbolList},Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,';']}})
+ parse_error(Rest2)
end;
parse_Exports(Rest) ->
{{exports,all},Rest}.
@@ -137,29 +147,25 @@ parse_SymbolList(Tokens,Acc) ->
[{',',_L1}|Rest2] ->
parse_SymbolList(Rest2,[Symbol|Acc]);
Rest2 ->
- {lists:reverse([Symbol|Acc]),Rest2}
+ {lists:reverse(Acc, [Symbol]),Rest2}
end.
parse_Symbol(Tokens) ->
parse_Reference(Tokens).
parse_Reference([{typereference,L1,TrefName},{'{',_L2},{'}',_L3}|Rest]) ->
-% {Tref,Rest};
{tref2Exttref(L1,TrefName),Rest};
parse_Reference([Tref1 = {typereference,_,_},{'.',_},Tref2 = {typereference,_,_},
{'{',_L2},{'}',_L3}|Rest]) ->
-% {{Tref1,Tref2},Rest};
{{tref2Exttref(Tref1),tref2Exttref(Tref2)},Rest};
parse_Reference([Tref = {typereference,_L1,_TrefName}|Rest]) ->
{tref2Exttref(Tref),Rest};
-parse_Reference([Vref = {identifier,_L1,_VName},{'{',_L2},{'}',_L3}|Rest]) ->
+parse_Reference([#identifier{}=Vref,{'{',_L2},{'}',_L3}|Rest]) ->
{identifier2Extvalueref(Vref),Rest};
-parse_Reference([Vref = {identifier,_L1,_VName}|Rest]) ->
+parse_Reference([#identifier{}=Vref|Rest]) ->
{identifier2Extvalueref(Vref),Rest};
parse_Reference(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [typereference,identifier]]}}).
+ parse_error(Tokens).
parse_Imports([{'IMPORTS',_L1},{';',_L2}|Rest]) ->
{{imports,[]},Rest};
@@ -168,9 +174,8 @@ parse_Imports([{'IMPORTS',_L1}|Rest]) ->
case Rest2 of
[{';',_L2}|Rest3] ->
{{imports,SymbolsFromModuleList},Rest3};
- Rest3 ->
- throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
- [got,get_token(hd(Rest3)),expected,';']}})
+ _ ->
+ parse_error(Rest2)
end;
parse_Imports(Tokens) ->
{{imports,[]},Tokens}.
@@ -180,11 +185,12 @@ parse_SymbolsFromModuleList(Tokens) ->
parse_SymbolsFromModuleList(Tokens,Acc) ->
{SymbolsFromModule,Rest} = parse_SymbolsFromModule(Tokens),
- case (catch parse_SymbolsFromModule(Rest)) of
+ try parse_SymbolsFromModule(Rest) of
{Sl,_Rest2} when is_record(Sl,'SymbolsFromModule') ->
- parse_SymbolsFromModuleList(Rest,[SymbolsFromModule|Acc]);
- _ ->
- {lists:reverse([SymbolsFromModule|Acc]),Rest}
+ parse_SymbolsFromModuleList(Rest, [SymbolsFromModule|Acc])
+ catch
+ throw:{asn1_error,_} ->
+ {lists:reverse(Acc, [SymbolsFromModule]),Rest}
end.
parse_SymbolsFromModule(Tokens) ->
@@ -198,169 +204,154 @@ parse_SymbolsFromModule(Tokens) ->
end,
{SymbolList,Rest} = parse_SymbolList(Tokens),
case Rest of
- [{'FROM',_L1},Tref = {typereference,_,Name},Ref={identifier,_L2,_Id},C={',',_}|Rest2] ->
- NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
+ [{'FROM',_L1},{typereference,_,Name}=Tref|
+ [#identifier{},{',',_}|_]=Rest2] ->
+ NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList),
{#'SymbolsFromModule'{symbols=NewSymbolList,
- module=tref2Exttref(Tref)},[Ref,C|Rest2]};
+ module=tref2Exttref(Tref)},Rest2};
%% This a special case when there is only one Symbol imported
%% from the next module. No other way to distinguish Ref from
%% a part of the GlobalModuleReference of Name.
- [{'FROM',_L1},Tref = {typereference,_,Name},Ref = {identifier,_L2,_Id},From = {'FROM',_}|Rest2] ->
- NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
+ [{'FROM',_L1},{typereference,_,Name}=Tref|
+ [#identifier{},{'FROM',_}|_]=Rest2] ->
+ NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList),
{#'SymbolsFromModule'{symbols=NewSymbolList,
- module=tref2Exttref(Tref)},[Ref,From|Rest2]};
- [{'FROM',_L1},Tref = {typereference,_,Name},{identifier,_L2,_Id}|Rest2] ->
- NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
+ module=tref2Exttref(Tref)},Rest2};
+ [{'FROM',_L1},{typereference,_,Name}=Tref,#identifier{}|Rest2] ->
+ NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList),
{#'SymbolsFromModule'{symbols=NewSymbolList,
module=tref2Exttref(Tref)},Rest2};
- [{'FROM',_L1},Tref = {typereference,_,Name},Brace = {'{',_}|Rest2] ->
- {_ObjIdVal,Rest3} = parse_ObjectIdentifierValue([Brace|Rest2]), % value not used yet, fix me
- NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
+ [{'FROM',_L1},{typereference,_,Name}=Tref|[{'{',_}|_]=Rest2] ->
+ {_ObjIdVal,Rest3} = parse_ObjectIdentifierValue(Rest2), % value not used yet, fix me
+ NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList),
{#'SymbolsFromModule'{symbols=NewSymbolList,
module=tref2Exttref(Tref)},Rest3};
- [{'FROM',_L1},Tref = {typereference,_,Name}|Rest2] ->
- NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
+ [{'FROM',_L1},{typereference,_,Name}=Tref|Rest2] ->
+ NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList),
{#'SymbolsFromModule'{symbols=NewSymbolList,
module=tref2Exttref(Tref)},Rest2};
_ ->
- throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
- [got,get_token(hd(Rest)),expected,
- ['FROM typerefernece identifier ,',
- 'FROM typereference identifier',
- 'FROM typereference {',
- 'FROM typereference']]}})
+ parse_error(Rest)
end.
parse_ObjectIdentifierValue([{'{',_}|Rest]) ->
parse_ObjectIdentifierValue(Rest,[]).
-parse_ObjectIdentifierValue([{number,_,Num}|Rest],Acc) ->
+parse_ObjectIdentifierValue([{number,_,Num}|Rest], Acc) ->
parse_ObjectIdentifierValue(Rest,[Num|Acc]);
-parse_ObjectIdentifierValue([{identifier,_,Id},{'(',_}, {number,_,Num}, {')',_}|Rest],Acc) ->
+parse_ObjectIdentifierValue([#identifier{val=Id},{'(',_},{number,_,Num},{')',_}|Rest], Acc) ->
parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,Num}|Acc]);
-parse_ObjectIdentifierValue([{identifier,_,Id},{'(',_}, {identifier,_,Id2}, {')',_}|Rest],Acc) ->
+parse_ObjectIdentifierValue([#identifier{val=Id},{'(',_},#identifier{val=Id2},{')',_}|Rest], Acc) ->
parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,Id2}|Acc]);
-parse_ObjectIdentifierValue([{identifier,_,Id},{'(',_}, {typereference,_,Tref},{'.',_},{identifier,_,Id2}, {')',_}|Rest],Acc) ->
- parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,{'ExternalValue',Tref,Id2}}|Acc]);
-parse_ObjectIdentifierValue([Id = {identifier,_,_}|Rest],Acc) ->
- parse_ObjectIdentifierValue(Rest,[identifier2Extvalueref(Id)|Acc]);
-parse_ObjectIdentifierValue([{'}',_}|Rest],Acc) ->
+parse_ObjectIdentifierValue([#identifier{val=Id},{'(',_},{typereference,_,Tref},{'.',_},#identifier{val=Id2}, {')',_}|Rest], Acc) ->
+ parse_ObjectIdentifierValue(Rest, [{'NamedNumber',Id,{'ExternalValue',Tref,Id2}}|Acc]);
+parse_ObjectIdentifierValue([#identifier{}=Id|Rest], Acc) ->
+ parse_ObjectIdentifierValue(Rest, [identifier2Extvalueref(Id)|Acc]);
+parse_ObjectIdentifierValue([{'}',_}|Rest], Acc) ->
{lists:reverse(Acc),Rest};
-parse_ObjectIdentifierValue([H|_T],_Acc) ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,
- ['{ some of the following }',number,'identifier ( number )',
- 'identifier ( identifier )',
- 'identifier ( typereference.identifier)',identifier]]}}).
+parse_ObjectIdentifierValue(Tokens, _Acc) ->
+ parse_error(Tokens).
-parse_AssignmentList(Tokens = [{'END',_}|_Rest]) ->
- {[],Tokens};
-parse_AssignmentList(Tokens = [{'$end',_}|_Rest]) ->
- {[],Tokens};
parse_AssignmentList(Tokens) ->
- parse_AssignmentList(Tokens,[]).
+ parse_AssignmentList(Tokens, []).
-parse_AssignmentList(Tokens= [{'END',_}|_Rest],Acc) ->
+parse_AssignmentList([{'END',_}|_]=Tokens, Acc) ->
{lists:reverse(Acc),Tokens};
-parse_AssignmentList(Tokens= [{'$end',_}|_Rest],Acc) ->
+parse_AssignmentList([{'$end',_}|_]=Tokens, Acc) ->
{lists:reverse(Acc),Tokens};
-parse_AssignmentList(Tokens,Acc) ->
- case (catch parse_Assignment(Tokens)) of
- {'EXIT',Reason} ->
- exit(Reason);
- {asn1_error,R} ->
-% [H|T] = Tokens,
- throw({error,{R,hd(Tokens)}});
- {Assignment,Rest} ->
- parse_AssignmentList(Rest,[Assignment|Acc])
- end.
-
-parse_Assignment(Tokens) ->
- Flist = [fun parse_TypeAssignment/1,
- fun parse_ValueAssignment/1,
- fun parse_ObjectClassAssignment/1,
- fun parse_ObjectAssignment/1,
- fun parse_ObjectSetAssignment/1,
- fun parse_ParameterizedAssignment/1,
+parse_AssignmentList(Tokens0, Acc) ->
+ {Assignment,Tokens} = parse_Assignment(Tokens0),
+ parse_AssignmentList(Tokens, [Assignment|Acc]).
+
+parse_Assignment([{typereference,L1,Name},{'::=',_}|Tokens0]) ->
+ %% 1) Type ::= TypeDefinition
+ %% 2) CLASS-NAME ::= CLASS {...}
+ Flist = [{type,fun parse_Type/1},
+ {class,fun parse_ObjectClass/1}],
+ case parse_or_tag(Tokens0, Flist) of
+ {{type,Type},Tokens} ->
+ %% TypeAssignment
+ {#typedef{pos=L1,name=Name,typespec=Type},Tokens};
+ {{class,Type},Tokens} ->
+ %% ObjectClassAssignment
+ {#classdef{pos=L1,name=Name,module=resolve_module(Type),
+ typespec=Type},Tokens}
+ end;
+parse_Assignment([{typereference,_,_},{'{',_}|_]=Tokens) ->
+ %% 1) Type{...} ::= ...
+ %% 2) ValueSet{...} Type ::= ...
+ %% ObjectSet{...} CLASS-NAME ::= CLASS {...}
+ %% 3) CLASS-NAME{...} ::= CLASS {...}
+ %% A parameterized value set and and a parameterized object set
+ %% cannot be distinguished from each other without type information.
+ Flist = [fun parse_ParameterizedTypeAssignment/1,
+ fun parse_ParameterizedValueSetTypeAssignment/1,
+ fun parse_ParameterizedObjectClassAssignment/1],
+ parse_or(Tokens, Flist);
+parse_Assignment([{typereference,_,_}|_]=Tokens) ->
+ %% 1) ObjectSet CLASS-NAME ::= ...
+ %% 2) ValueSet Type ::= ...
+ Flist = [fun parse_ObjectSetAssignment/1,
fun parse_ValueSetTypeAssignment/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- {asn1_assignment_error,Reason} ->
- throw({asn1_error,Reason});
- Result ->
- Result
- end.
-
+ parse_or(Tokens, Flist);
+parse_Assignment([#identifier{},{'{',_}|_]=Tokens) ->
+ %% 1) value{...} Type ::= ...
+ %% 2) object{...} CLASS-NAME ::= ...
+ Flist = [fun parse_ParameterizedValueAssignment/1,
+ fun parse_ParameterizedObjectAssignment/1],
+ parse_or(Tokens, Flist);
+parse_Assignment([#identifier{}|_]=Tokens) ->
+ %% 1) value Type ::= ...
+ %% 2) object CLASS-NAME ::= ...
+ Flist = [fun parse_ValueAssignment/1,
+ fun parse_ObjectAssignment/1],
+ parse_or(Tokens, Flist);
+parse_Assignment(Tokens) ->
+ parse_error(Tokens).
parse_or(Tokens,Flist) ->
parse_or(Tokens,Flist,[]).
-parse_or(_Tokens,[],ErrList) ->
- case ErrList of
- [] ->
- throw({asn1_error,{parse_or,ErrList}});
- L when is_list(L) ->
- %% chose to throw 1) the error with the highest line no,
- %% 2) the last error which is not a asn1_assignment_error or
- %% 3) the last error.
- throw(prioritize_error(ErrList))
+parse_or(Tokens, [Fun|Funs], ErrList) when is_function(Fun, 1) ->
+ try Fun(Tokens) of
+ {_,Rest}=Result when is_list(Rest) ->
+ Result
+ catch
+ throw:{asn1_error,Error} ->
+ parse_or(Tokens, Funs, [Error|ErrList])
end;
-parse_or(Tokens,[Fun|Frest],ErrList) ->
- case (catch Fun(Tokens)) of
- Exit = {'EXIT',_Reason} ->
- parse_or(Tokens,Frest,[Exit|ErrList]);
- AsnErr = {asn1_error,_} ->
- parse_or(Tokens,Frest,[AsnErr|ErrList]);
- AsnAssErr = {asn1_assignment_error,_} ->
- parse_or(Tokens,Frest,[AsnAssErr|ErrList]);
- Result = {_,L} when is_list(L) ->
- Result;
- Error ->
- parse_or(Tokens,Frest,[Error|ErrList])
- end.
-
-parse_or_tag(Tokens,Flist) ->
- parse_or_tag(Tokens,Flist,[]).
-
-parse_or_tag(_Tokens,[],ErrList) ->
- case ErrList of
- [] ->
- throw({asn1_error,{parse_or_tag,ErrList}});
- L when is_list(L) ->
- %% chose to throw 1) the error with the highest line no,
- %% 2) the last error which is not a asn1_assignment_error or
- %% 3) the last error.
- throw(prioritize_error(ErrList))
+parse_or(_Tokens, [], ErrList) ->
+ throw({asn1_error,fun() -> prioritize_error(ErrList) end}).
+
+parse_or_tag(Tokens, Flist) ->
+ parse_or_tag(Tokens, Flist, []).
+
+parse_or_tag(Tokens, [{Tag,Fun}|Funs], ErrList) when is_function(Fun, 1) ->
+ try Fun(Tokens) of
+ {Parsed,Rest} when is_list(Rest) ->
+ {{Tag,Parsed},Rest}
+ catch
+ throw:{asn1_error,Error} ->
+ parse_or_tag(Tokens, Funs, [Error|ErrList])
end;
-parse_or_tag(Tokens,[{Tag,Fun}|Frest],ErrList) when is_function(Fun) ->
- case (catch Fun(Tokens)) of
- Exit = {'EXIT',_Reason} ->
- parse_or_tag(Tokens,Frest,[Exit|ErrList]);
- AsnErr = {asn1_error,_} ->
- parse_or_tag(Tokens,Frest,[AsnErr|ErrList]);
- AsnAssErr = {asn1_assignment_error,_} ->
- parse_or_tag(Tokens,Frest,[AsnAssErr|ErrList]);
- {ParseRes,Rest} when is_list(Rest) ->
- {{Tag,ParseRes},Rest};
- Error ->
- parse_or_tag(Tokens,Frest,[Error|ErrList])
- end.
+parse_or_tag(_Tokens, [], ErrList) ->
+ throw({asn1_error,fun() -> prioritize_error(ErrList) end}).
+
+prioritize_error(Errors0) ->
+ Errors1 = prioritize_error_1(Errors0),
+ Errors2 = [{length(L),L} || L <- Errors1],
+ Errors = lists:sort(Errors2),
+ [Res|_] = [L || {_,L} <- Errors],
+ Res.
+
+prioritize_error_1([F|T]) when is_function(F, 0) ->
+ [F()|prioritize_error_1(T)];
+prioritize_error_1([{parse_error,Tokens}|T]) ->
+ [Tokens|prioritize_error_1(T)];
+prioritize_error_1([]) ->
+ [].
-parse_TypeAssignment([{typereference,L1,Tref},{'::=',_}|Rest]) ->
- {Type,Rest2} = parse_Type(Rest),
- {#typedef{pos=L1,name=Tref,typespec=Type},Rest2};
-parse_TypeAssignment([H1,H2|_Rest]) ->
- throw({asn1_assignment_error,{get_line(H1),get(asn1_module),
- [got,[get_token(H1),get_token(H2)], expected,
- typereference,'::=']}});
-parse_TypeAssignment([H|_T]) ->
- throw({asn1_assignment_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,
- typereference]}}).
%% parse_Type(Tokens) -> Ret
%%
@@ -370,9 +361,8 @@ parse_TypeAssignment([H|_T]) ->
%%
parse_Type(Tokens) ->
{Tag,Rest3} = case Tokens of
- [Lbr= {'[',_}|Rest] ->
- parse_Tag([Lbr|Rest]);
- Rest-> {[],Rest}
+ [{'[',_}|_] -> parse_Tag(Tokens);
+ _ -> {[],Tokens}
end,
{Tag2,Rest4} = case Rest3 of
[{'IMPLICIT',_}|Rest31] when is_record(Tag,tag)->
@@ -384,31 +374,17 @@ parse_Type(Tokens) ->
Rest31 ->
{Tag,Rest31}
end,
- Flist = [fun parse_BuiltinType/1,fun parse_ReferencedType/1,fun parse_TypeWithConstraint/1],
- {Type,Rest5} = case (catch parse_or(Rest4,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_Reason} ->
- throw(AsnErr);
- Result ->
- Result
- end,
- case hd(Rest5) of
- {'(',_} ->
+ Flist = [fun parse_BuiltinType/1,
+ fun parse_ReferencedType/1,
+ fun parse_TypeWithConstraint/1],
+ {Type,Rest5} = parse_or(Rest4, Flist),
+ case Rest5 of
+ [{'(',_}|_] ->
{Constraints,Rest6} = parse_Constraints(Rest5),
- if is_record(Type,type) ->
- {Type#type{constraint=merge_constraints(Constraints),
- tag=Tag2},Rest6};
- true ->
- {#type{def=Type,constraint=merge_constraints(Constraints),
- tag=Tag2},Rest6}
- end;
- _ ->
- if is_record(Type,type) ->
- {Type#type{tag=Tag2},Rest5};
- true ->
- {#type{def=Type,tag=Tag2},Rest5}
- end
+ {Type#type{tag=Tag2,
+ constraint=merge_constraints(Constraints)},Rest6};
+ [_|_] ->
+ {Type#type{tag=Tag2},Rest5}
end.
parse_BuiltinType([{'BIT',_},{'STRING',_}|Rest]) ->
@@ -419,11 +395,10 @@ parse_BuiltinType([{'BIT',_},{'STRING',_}|Rest]) ->
[{'}',_}|Rest4] ->
{#type{def={'BIT STRING',NamedNumberList}},Rest4};
_ ->
- throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
- [got,get_token(hd(Rest3)),expected,'}']}})
+ parse_error(Rest3)
end;
_ ->
- {{'BIT STRING',[]},Rest}
+ {#type{def={'BIT STRING',[]}},Rest}
end;
parse_BuiltinType([{'BOOLEAN',_}|Rest]) ->
{#type{def='BOOLEAN'},Rest};
@@ -435,41 +410,33 @@ parse_BuiltinType([{'CHARACTER',_},{'STRING',_}|Rest]) ->
{#type{def='CHARACTER STRING'},Rest};
parse_BuiltinType([{'CHOICE',_},{'{',_}|Rest]) ->
- {AlternativeTypeLists,Rest2} = parse_AlternativeTypeLists(Rest),
- AlternativeTypeLists1 =
- lists:filter(fun(#'ExtensionAdditionGroup'{}) -> false;
- ('ExtensionAdditionGroupEnd') -> false;
- (_) -> true
- end,AlternativeTypeLists),
+ {L0,Rest2} = parse_AlternativeTypeLists(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
- AlternativeTypeLists2 =
- case {[Ext||Ext = #'EXTENSIONMARK'{} <- AlternativeTypeLists1],
- get(extensiondefault)} of
- {[],'IMPLIED'} -> AlternativeTypeLists1 ++ [#'EXTENSIONMARK'{}];
- _ -> AlternativeTypeLists1
+ NeedExt = not lists:keymember('EXTENSIONMARK', 1, L0) andalso
+ get(extensiondefault) =:= 'IMPLIED',
+ L = case NeedExt of
+ true ->
+ L0 ++ [#'EXTENSIONMARK'{}];
+ false ->
+ L0
end,
-
- {#type{def={'CHOICE',AlternativeTypeLists2}},Rest3};
+ {#type{def={'CHOICE',L}},Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ parse_error(Rest2)
end;
parse_BuiltinType([{'EMBEDDED',_},{'PDV',_}|Rest]) ->
{#type{def='EMBEDDED PDV'},Rest};
parse_BuiltinType([{'ENUMERATED',_},{'{',_}|Rest]) ->
- {Enumerations,Rest2} = parse_Enumerations(Rest,get(extensiondefault)),
+ {Enumerations,Rest2} = parse_Enumerations(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
{#type{def={'ENUMERATED',Enumerations}},Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ parse_error(Rest2)
end;
parse_BuiltinType([{'EXTERNAL',_}|Rest]) ->
{#type{def='EXTERNAL'},Rest};
-
-% InstanceOfType
parse_BuiltinType([{'INSTANCE',_},{'OF',_}|Rest]) ->
{DefinedObjectClass,Rest2} = parse_DefinedObjectClass(Rest),
case Rest2 of
@@ -480,9 +447,6 @@ parse_BuiltinType([{'INSTANCE',_},{'OF',_}|Rest]) ->
_ ->
{#type{def={'INSTANCE OF',DefinedObjectClass,[]}},Rest2}
end;
-
-% parse_BuiltinType(Tokens) ->
-
parse_BuiltinType([{'INTEGER',_}|Rest]) ->
case Rest of
[{'{',_}|Rest2] ->
@@ -491,17 +455,13 @@ parse_BuiltinType([{'INTEGER',_}|Rest]) ->
[{'}',_}|Rest4] ->
{#type{def={'INTEGER',NamedNumberList}},Rest4};
_ ->
- throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
- [got,get_token(hd(Rest3)),expected,'}']}})
+ parse_error(Rest3)
end;
_ ->
{#type{def='INTEGER'},Rest}
end;
parse_BuiltinType([{'NULL',_}|Rest]) ->
{#type{def='NULL'},Rest};
-
-% ObjectClassFieldType fix me later
-
parse_BuiltinType([{'OBJECT',_},{'IDENTIFIER',_}|Rest]) ->
{#type{def='OBJECT IDENTIFIER'},Rest};
parse_BuiltinType([{'OCTET',_},{'STRING',_}|Rest]) ->
@@ -529,18 +489,14 @@ parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
parse_ComponentTypeLists2(Rest2,[#'EXTENSIONMARK'{pos=Line}]),
case Rest3 of
[{'}',_}|Rest4] ->
- {#type{def=#'SEQUENCE'{components=ComponentTypeLists}},Rest4};
+ {#type{def=#'SEQUENCE'{components=ComponentTypeLists}},Rest4};
_ ->
- throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
- [got,get_token(hd(Rest3)),expected,'}']}})
+ parse_error(Rest3)
end
-% _ -> % Seq case 4,17-19,23-26 will fail here
-% throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
-% [got,get_token(hd(Rest2)),expected,'}']}})
end;
parse_BuiltinType([{'SEQUENCE',_},{'{',_}|Rest]) ->
{ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest),
- case Rest2 of
+ case Rest2 of
[{'}',_}|Rest3] ->
ComponentTypeLists2 =
case {[Ext||Ext = #'EXTENSIONMARK'{} <- ComponentTypeLists],
@@ -551,25 +507,19 @@ parse_BuiltinType([{'SEQUENCE',_},{'{',_}|Rest]) ->
{#type{def=#'SEQUENCE'{components = ComponentTypeLists2}},
Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ parse_error(Rest2)
end;
-
-parse_BuiltinType([{'SEQUENCE',_},{'OF',_},Id={identifier,_,_},Lt={'<',_}|Rest]) ->
-%% TODO: take care of the identifier for something useful
- {Type,Rest2} = parse_SelectionType([Id,Lt|Rest]),
- {#type{def={'SEQUENCE OF',#type{def=Type,tag=[]}}},Rest2};
-
-parse_BuiltinType([{'SEQUENCE',_},{'OF',_},{identifier,_,_} |Rest]) ->
+parse_BuiltinType([{'SEQUENCE',_},{'OF',_}|
+ [#identifier{},{'<',_}|_]=Tokens0]) ->
+ {Type,Tokens} = parse_SelectionType(Tokens0),
+ {#type{def={'SEQUENCE OF',Type}},Tokens};
+parse_BuiltinType([{'SEQUENCE',_},{'OF',_},#identifier{} |Rest]) ->
%% TODO: take care of the identifier for something useful
{Type,Rest2} = parse_Type(Rest),
{#type{def={'SEQUENCE OF',Type}},Rest2};
-
parse_BuiltinType([{'SEQUENCE',_},{'OF',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{#type{def={'SEQUENCE OF',Type}},Rest2};
-
-
parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'}',_}|Rest]) ->
{#type{def=#'SET'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest};
parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
@@ -581,12 +531,18 @@ parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
val = ExceptionIdentification}]}},
Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ {ComponentTypeLists,Rest3}=
+ parse_ComponentTypeLists2(Rest2,[#'EXTENSIONMARK'{pos=Line}]),
+ case Rest3 of
+ [{'}',_}|Rest4] ->
+ {#type{def=#'SET'{components=ComponentTypeLists}},Rest4};
+ _ ->
+ parse_error(Rest3)
+ end
end;
parse_BuiltinType([{'SET',_},{'{',_}|Rest]) ->
{ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest),
- case Rest2 of
+ case Rest2 of
[{'}',_}|Rest3] ->
ComponentTypeLists2 =
case {[Ext||Ext = #'EXTENSIONMARK'{} <- ComponentTypeLists],
@@ -597,184 +553,128 @@ parse_BuiltinType([{'SET',_},{'{',_}|Rest]) ->
{#type{def=#'SET'{components = ComponentTypeLists2}},
Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ parse_error(Rest2)
end;
-
-parse_BuiltinType([{'SET',_},{'OF',_},Id={identifier,_,_},Lt={'<',_}|Rest]) ->
-%% TODO: take care of the identifier for something useful
- {Type,Rest2} = parse_SelectionType([Id,Lt|Rest]),
- {#type{def={'SET OF',#type{def=Type,tag=[]}}},Rest2};
-
-
-parse_BuiltinType([{'SET',_},{'OF',_},{identifier,_,_}|Rest]) ->
+parse_BuiltinType([{'SET',_},{'OF',_}|
+ [#identifier{},{'<',_}|_]=Tokens0]) ->
+ {Type,Tokens} = parse_SelectionType(Tokens0),
+ {#type{def={'SET OF',Type}},Tokens};
+parse_BuiltinType([{'SET',_},{'OF',_},#identifier{}|Rest]) ->
%%TODO: take care of the identifier for something useful
{Type,Rest2} = parse_Type(Rest),
{#type{def={'SET OF',Type}},Rest2};
-
parse_BuiltinType([{'SET',_},{'OF',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{#type{def={'SET OF',Type}},Rest2};
-
-%% The so called Useful types
parse_BuiltinType([{'GeneralizedTime',_}|Rest]) ->
{#type{def='GeneralizedTime'},Rest};
parse_BuiltinType([{'UTCTime',_}|Rest]) ->
{#type{def='UTCTime'},Rest};
parse_BuiltinType([{'ObjectDescriptor',_}|Rest]) ->
{#type{def='ObjectDescriptor'},Rest};
-
-%% For compatibility with old standard
-parse_BuiltinType([{'ANY',_},{'DEFINED',_},{'BY',_},{identifier,_,Id}|Rest]) ->
+parse_BuiltinType([{'ANY',_},{'DEFINED',_},{'BY',_},#identifier{val=Id}|Rest]) ->
+ %% For compatibility with the old standard.
{#type{def={'ANY_DEFINED_BY',Id}},Rest};
parse_BuiltinType([{'ANY',_}|Rest]) ->
+ %% For compatibility with the old standard.
{#type{def='ANY'},Rest};
-
parse_BuiltinType(Tokens) ->
parse_ObjectClassFieldType(Tokens).
-% throw({asn1_error,unhandled_type}).
-parse_TypeWithConstraint([{'SEQUENCE',_},Lpar = {'(',_}|Rest]) ->
- {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
+parse_TypeWithConstraint([{'SEQUENCE',_}|[{'(',_}|_]=Rest0]) ->
+ {Constraint,Rest2} = parse_Constraint(Rest0),
Rest4 = case Rest2 of
- [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+ [{'OF',_},#identifier{}|Rest3] ->
%%% TODO: make some use of the identifier, maybe useful in the XML mapping
Rest3;
[{'OF',_}|Rest3] ->
Rest3;
_ ->
- throw({asn1_error,
- {get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
+ parse_error(Rest2)
end,
{Type,Rest5} = parse_Type(Rest4),
{#type{def = {'SEQUENCE OF',Type},
constraint = merge_constraints([Constraint])},Rest5};
-parse_TypeWithConstraint([{'SEQUENCE',_},{'SIZE',_},Lpar = {'(',_}|Rest]) ->
- {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
+parse_TypeWithConstraint([{'SEQUENCE',_},{'SIZE',_}|[{'(',_}|_]=Rest0]) ->
+ {Constraint,Rest2} = parse_Constraint(Rest0),
#constraint{c=C} = Constraint,
- Constraint2 = Constraint#constraint{c={'SizeConstraint',C}},
+ Constraint2 = Constraint#constraint{c={element_set,{'SizeConstraint',C},
+ none}},
Rest4 = case Rest2 of
- [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+ [{'OF',_},#identifier{}|Rest3] ->
%%% TODO: make some use of the identifier, maybe useful in the XML mapping
Rest3;
[{'OF',_}|Rest3] ->
Rest3;
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
+ parse_error(Rest2)
end,
{Type,Rest5} = parse_Type(Rest4),
{#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint2])},Rest5};
-parse_TypeWithConstraint([{'SET',_},Lpar = {'(',_}|Rest]) ->
- {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
+parse_TypeWithConstraint([{'SET',_}|[{'(',_}|_]=Rest0]) ->
+ {Constraint,Rest2} = parse_Constraint(Rest0),
Rest4 = case Rest2 of
- [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+ [{'OF',_},#identifier{}|Rest3] ->
%%% TODO: make some use of the identifier, maybe useful in the XML mapping
Rest3;
[{'OF',_}|Rest3] ->
Rest3;
_ ->
- throw({asn1_error,
- {get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
+ parse_error(Rest2)
end,
{Type,Rest5} = parse_Type(Rest4),
{#type{def = {'SET OF',Type},
constraint = merge_constraints([Constraint])},Rest5};
-parse_TypeWithConstraint([{'SET',_},{'SIZE',_},Lpar = {'(',_}|Rest]) ->
- {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
+parse_TypeWithConstraint([{'SET',_},{'SIZE',_}|[{'(',_}|_]=Rest0]) ->
+ {Constraint,Rest2} = parse_Constraint(Rest0),
#constraint{c=C} = Constraint,
- Constraint2 = Constraint#constraint{c={'SizeConstraint',C}},
+ Constraint2 = Constraint#constraint{c={element_set,
+ {'SizeConstraint',C},none}},
Rest4 = case Rest2 of
- [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+ [{'OF',_},#identifier{}|Rest3] ->
%%% TODO: make some use of the identifier, maybe useful in the XML mapping
Rest3;
[{'OF',_}|Rest3] ->
Rest3;
_ ->
- throw({asn1_error,
- {get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
+ parse_error(Rest2)
end,
{Type,Rest5} = parse_Type(Rest4),
{#type{def = {'SET OF',Type},
constraint = merge_constraints([Constraint2])},Rest5};
parse_TypeWithConstraint(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- ['SEQUENCE','SEQUENCE SIZE','SET','SET SIZE'],
- followed,by,a,constraint]}}).
+ parse_error(Tokens).
%% --------------------------
parse_ReferencedType(Tokens) ->
- Flist = [fun parse_DefinedType/1,
+ Flist = [fun parse_ParameterizedType/1,
+ fun parse_DefinedType/1,
fun parse_SelectionType/1,
- fun parse_TypeFromObject/1,
- fun parse_ValueSetFromObjects/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ fun parse_TypeFromObject/1],
+ parse_or(Tokens, Flist).
-parse_DefinedType(Tokens=[{typereference,_,_},{'{',_}|_Rest]) ->
- parse_ParameterizedType(Tokens);
-parse_DefinedType(Tokens=[{typereference,L1,TypeName},
- T2={typereference,_,_},T3={'{',_}|Rest]) ->
- case (catch parse_ParameterizedType(Tokens)) of
- {'EXIT',_Reason} ->
- Rest2 = [T2,T3|Rest],
- {#type{def = #'Externaltypereference'{pos=L1,
- module=resolve_module(TypeName),
- type=TypeName}},Rest2};
- {asn1_error,_} ->
- Rest2 = [T2,T3|Rest],
- {#type{def = #'Externaltypereference'{pos=L1,
- module=resolve_module(TypeName),
- type=TypeName}},Rest2};
- Result ->
- Result
- end;
-parse_DefinedType(Tokens=[{typereference,_L1,_Module},{'.',_},
- {typereference,_,_TypeName},{'{',_}|_Rest]) ->
- parse_ParameterizedType(Tokens);
-parse_DefinedType([{typereference,L1,Module},{'.',_},{typereference,_,TypeName}|Rest]) ->
- {#type{def = #'Externaltypereference'{pos=L1,module=Module,type=TypeName}},Rest};
-parse_DefinedType([{typereference,L1,TypeName}|Rest]) ->
- case is_pre_defined_class(TypeName) of
- false ->
- {#type{def = #'Externaltypereference'{pos=L1,module=resolve_module(TypeName),
- type=TypeName}},Rest};
- _ ->
- throw({asn1_error,
- {L1,get(asn1_module),
- [got,TypeName,expected,
- [typereference,'typereference.typereference',
- 'typereference typereference']]}})
- end;
+parse_DefinedType([{typereference,L1,Module},
+ {'.',_},
+ {typereference,_,TypeName}|Tokens]) ->
+ {#type{def = #'Externaltypereference'{pos=L1,module=Module,
+ type=TypeName}},Tokens};
+parse_DefinedType([{typereference,_,_}=Tr|Tokens]) ->
+ {#type{def=tref2Exttref(Tr)},Tokens};
parse_DefinedType(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [typereference,'typereference.typereference',
- 'typereference typereference']]}}).
+ parse_error(Tokens).
-parse_SelectionType([{identifier,_,Name},{'<',_}|Rest]) ->
+parse_SelectionType([#identifier{val=Name},{'<',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
- {{'SelectionType',Name,Type},Rest2};
+ {#type{def={'SelectionType',Name,Type}},Rest2};
parse_SelectionType(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'identifier <']}}).
+ parse_error(Tokens).
resolve_module(Type) ->
@@ -787,30 +687,13 @@ resolve_module(_Type, Current, undefined) ->
resolve_module(Type, Current, Imports) ->
case [Mod || #'SymbolsFromModule'{symbols = S, module = Mod} <- Imports,
#'Externaltypereference'{type = T} <- S,
- Type == T] of
+ Type =:= T] of
[#'Externaltypereference'{type = Mod}|_] -> Mod;
%% This allows the same symbol to be imported several times
%% which ought to be checked elsewhere and flagged as an error
[] -> Current
end.
-%% --------------------------
-
-
-%% This should probably be removed very soon
-% parse_ConstrainedType(Tokens) ->
-% case (catch parse_TypeWithConstraint(Tokens)) of
-% {'EXIT',Reason} ->
-% {Type,Rest} = parse_Type(Tokens),
-% {Constraint,Rest2} = parse_Constraint(Rest),
-% {Type#type{constraint=Constraint},Rest2};
-% {asn1_error,Reason2} ->
-% {Type,Rest} = parse_Type(Tokens),
-% {Constraint,Rest2} = parse_Constraint(Rest),
-% {Type#type{constraint=Constraint},Rest2};
-% Result ->
-% Result
-% end.
parse_Constraints(Tokens) ->
parse_Constraints(Tokens,[]).
@@ -819,9 +702,9 @@ parse_Constraints(Tokens,Acc) ->
{Constraint,Rest} = parse_Constraint(Tokens),
case Rest of
[{'(',_}|_Rest2] ->
- parse_Constraints(Rest,[Constraint|Acc]);
+ parse_Constraints(Rest, [Constraint|Acc]);
_ ->
- {lists:reverse([Constraint|Acc]),Rest}
+ {lists:reverse(Acc, [Constraint]),Rest}
end.
parse_Constraint([{'(',_}|Rest]) ->
@@ -830,46 +713,27 @@ parse_Constraint([{'(',_}|Rest]) ->
case Rest3 of
[{')',_}|Rest4] ->
{#constraint{c=Constraint,e=Exception},Rest4};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,')']}})
- end;
-parse_Constraint(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'(']}}).
+ [_|_] ->
+ parse_error(Rest3)
+ end.
parse_ConstraintSpec(Tokens) ->
Flist = [fun parse_GeneralConstraint/1,
fun parse_SubtypeConstraint/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- {asn1_error,Reason2} ->
- throw({asn1_error,Reason2});
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_ExceptionSpec([LPar={')',_}|Rest]) ->
{undefined,[LPar|Rest]};
parse_ExceptionSpec([{'!',_}|Rest]) ->
parse_ExceptionIdentification(Rest);
parse_ExceptionSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,[')','!']]}}).
+ parse_error(Tokens).
parse_ExceptionIdentification(Tokens) ->
Flist = [fun parse_SignedNumber/1,
fun parse_DefinedValue/1,
fun parse_TypeColonValue/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- {asn1_error,Reason2} ->
- throw({asn1_error,Reason2});
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_TypeColonValue(Tokens) ->
{Type,Rest} = parse_Type(Tokens),
@@ -877,32 +741,28 @@ parse_TypeColonValue(Tokens) ->
[{':',_}|Rest2] ->
{Value,Rest3} = parse_Value(Rest2),
{{Type,Value},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,':']}})
+ [_|_] ->
+ parse_error(Rest)
end.
parse_SubtypeConstraint(Tokens) ->
parse_ElementSetSpecs(Tokens).
-parse_ElementSetSpecs([{'...',_}|Rest]) ->
- {Elements,Rest2} = parse_ElementSetSpec(Rest),
- {{[],Elements},Rest2};
parse_ElementSetSpecs(Tokens) ->
{RootElems,Rest} = parse_ElementSetSpec(Tokens),
case Rest of
[{',',_},{'...',_},{',',_}|Rest2] ->
{AdditionalElems,Rest3} = parse_ElementSetSpec(Rest2),
- {{RootElems,AdditionalElems},Rest3};
+ {{element_set,RootElems,AdditionalElems},Rest3};
[{',',_},{'...',_}|Rest2] ->
- {{RootElems,[]},Rest2};
+ {{element_set,RootElems,empty},Rest2};
_ ->
- {RootElems,Rest}
+ {{element_set,RootElems,none},Rest}
end.
parse_ElementSetSpec([{'ALL',_},{'EXCEPT',_}|Rest]) ->
{Exclusions,Rest2} = parse_Elements(Rest),
- {{'ALL',{'EXCEPT',Exclusions}},Rest2};
+ {{'ALL-EXCEPT',Exclusions},Rest2};
parse_ElementSetSpec(Tokens) ->
parse_Unions(Tokens).
@@ -918,14 +778,8 @@ parse_Unions(Tokens) ->
case {InterSec,Unions} of
{InterSec,[]} ->
{InterSec,Rest2};
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {{'SingleValue',ordsets:union(to_set(V1),to_set(V2))},Rest2};
- {V1,V2} when is_list(V2) ->
- {[V1] ++ [union|V2],Rest2};
{V1,V2} ->
- {[V1,union,V2],Rest2}
-% Other ->
-% throw(Other)
+ {{union,V1,V2},Rest2}
end.
parse_UnionsRec([{'|',_}|Rest]) ->
@@ -934,12 +788,8 @@ parse_UnionsRec([{'|',_}|Rest]) ->
case {InterSec,URec} of
{V1,[]} ->
{V1,Rest3};
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {{'SingleValue',ordsets:union(to_set(V1),to_set(V2))},Rest3};
- {V1,V2} when is_list(V2) ->
- {[V1] ++ [union|V2],Rest3};
{V1,V2} ->
- {[V1,union,V2],Rest3}
+ {{union,V1,V2},Rest3}
end;
parse_UnionsRec([{'UNION',Info}|Rest]) ->
parse_UnionsRec([{'|',Info}|Rest]);
@@ -952,13 +802,8 @@ parse_Intersections(Tokens) ->
case {InterSec,IRec} of
{V1,[]} ->
{V1,Rest2};
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {{'SingleValue',
- ordsets:intersection(to_set(V1),to_set(V2))},Rest2};
- {V1,V2} when is_list(V2) ->
- {[V1] ++ [intersection|V2],Rest2};
{V1,V2} ->
- {[V1,intersection,V2],Rest2}
+ {{intersection,V1,V2},Rest2}
end.
%% parse_IElemsRec(Tokens) -> Result
@@ -967,15 +812,10 @@ parse_IElemsRec([{'^',_}|Rest]) ->
{InterSec,Rest2} = parse_IntersectionElements(Rest),
{IRec,Rest3} = parse_IElemsRec(Rest2),
case {InterSec,IRec} of
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {{'SingleValue',
- ordsets:intersection(to_set(V1),to_set(V2))},Rest3};
{V1,[]} ->
- {V1,Rest3};
- {V1,V2} when is_list(V2) ->
- {[V1] ++ [intersection|V2],Rest3};
+ {V1,Rest2};
{V1,V2} ->
- {[V1,intersection,V2],Rest3}
+ {{intersection,V1,V2},Rest3}
end;
parse_IElemsRec([{'INTERSECTION',Info}|Rest]) ->
parse_IElemsRec([{'^',Info}|Rest]);
@@ -992,7 +832,7 @@ parse_IntersectionElements(Tokens) ->
case Rest of
[{'EXCEPT',_}|Rest2] ->
{Exclusion,Rest3} = parse_Elements(Rest2),
- {{InterSec,{'EXCEPT',Exclusion}},Rest3};
+ {{'EXCEPT',InterSec,Exclusion},Rest3};
Rest ->
{InterSec,Rest}
end.
@@ -1006,102 +846,73 @@ parse_Elements([{'(',_}|Rest]) ->
case Rest2 of
[{')',_}|Rest3] ->
{Elems,Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,')']}})
+ [_|_] ->
+ parse_error(Rest2)
end;
parse_Elements(Tokens) ->
Flist = [fun parse_ObjectSetElements/1,
fun parse_SubtypeElements/1,
-% fun parse_Value/1,
-% fun parse_Type/1,
fun parse_Object/1,
fun parse_DefinedObjectSet/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- Err = {asn1_error,_} ->
- throw(Err);
- Result = {Val,_} when is_record(Val,type) ->
- Result;
-
- Result ->
- Result
- end.
-
-
+ parse_or(Tokens, Flist).
%% --------------------------
-parse_DefinedObjectClass([{typereference,_,_ModName},{'.',_},Tr={typereference,_,_ObjClName}|Rest]) ->
-%% {{objectclassname,ModName,ObjClName},Rest};
-% {{objectclassname,tref2Exttref(Tr)},Rest};
- {tref2Exttref(Tr),Rest};
+parse_DefinedObjectClass([{typereference,_,ModName},{'.',_},
+ {typereference,Pos,Name}|Tokens]) ->
+ Ext = #'Externaltypereference'{pos=Pos,
+ module=ModName,
+ type=Name},
+ {Ext,Tokens};
parse_DefinedObjectClass([Tr={typereference,_,_ObjClName}|Rest]) ->
-% {{objectclassname,tref2Exttref(Tr)},Rest};
{tref2Exttref(Tr),Rest};
parse_DefinedObjectClass(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- ['typereference . typereference',
- typereference,
- 'TYPE-IDENTIFIER',
- 'ABSTRACT-SYNTAX']]}}).
-
-parse_ObjectClassAssignment([{typereference,L1,ObjClName},{'::=',_}|Rest]) ->
- {Type,Rest2} = parse_ObjectClass(Rest),
- {#classdef{pos=L1,name=ObjClName,module=resolve_module(Type),
- typespec=Type},Rest2};
-parse_ObjectClassAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- 'typereference ::=']}}).
+ parse_error(Tokens).
parse_ObjectClass(Tokens) ->
- Flist = [fun parse_DefinedObjectClass/1,
- fun parse_ObjectClassDefn/1,
- fun parse_ParameterizedObjectClass/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- {asn1_error,Reason2} ->
- throw({asn1_error,Reason2});
- Result ->
- Result
- end.
+ Flist = [fun parse_ObjectClassDefn/1,
+ fun parse_DefinedObjectClass/1],
+ parse_or(Tokens, Flist).
parse_ObjectClassDefn([{'CLASS',_},{'{',_}|Rest]) ->
{Type,Rest2} = parse_FieldSpec(Rest),
{WithSyntaxSpec,Rest3} = parse_WithSyntaxSpec(Rest2),
{#objectclass{fields=Type,syntax=WithSyntaxSpec},Rest3};
parse_ObjectClassDefn(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'CLASS {']}}).
+ parse_error(Tokens).
parse_FieldSpec(Tokens) ->
parse_FieldSpec(Tokens,[]).
-parse_FieldSpec(Tokens,Acc) ->
- Flist = [fun parse_FixedTypeValueFieldSpec/1,
- fun parse_VariableTypeValueFieldSpec/1,
- fun parse_ObjectFieldSpec/1,
- fun parse_FixedTypeValueSetFieldSpec/1,
- fun parse_VariableTypeValueSetFieldSpec/1,
- fun parse_TypeFieldSpec/1,
- fun parse_ObjectSetFieldSpec/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
+parse_FieldSpec(Tokens0, Acc) ->
+ Fl = case Tokens0 of
+ [{valuefieldreference,_,_}|_] ->
+ %% 1) &field Type
+ %% &object CLASS-NAME
+ %% 2) &field &FieldName
+ %% A fixed type field cannot be distinguished from
+ %% an object field without type information.
+ [fun parse_FixedTypeValueFieldSpec/1,
+ fun parse_VariableTypeValueFieldSpec/1];
+ [{typefieldreference,_,_}|_] ->
+ %% 1) &Set Type
+ %% &ObjectSet CLASS-NAME
+ %% 2) &Set &FieldName
+ %% 3) &Type
+ %% A value set and an object cannot be distinguished
+ %% without type information.
+ [fun parse_FixedTypeValueSetFieldSpec/1,
+ fun parse_VariableTypeValueSetFieldSpec/1,
+ fun parse_TypeFieldSpec/1];
+ [_|_] ->
+ parse_error(Tokens0)
+ end,
+ case parse_or(Tokens0, Fl) of
{Type,[{'}',_}|Rest]} ->
- {lists:reverse([Type|Acc]),Rest};
+ {lists:reverse(Acc, [Type]),Rest};
{Type,[{',',_}|Rest2]} ->
- parse_FieldSpec(Rest2,[Type|Acc]);
- {_,[H|_T]} ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'}']}})
+ parse_FieldSpec(Rest2, [Type|Acc])
end.
parse_PrimitiveFieldName([{typefieldreference,_,FieldName}|Rest]) ->
@@ -1109,27 +920,19 @@ parse_PrimitiveFieldName([{typefieldreference,_,FieldName}|Rest]) ->
parse_PrimitiveFieldName([{valuefieldreference,_,FieldName}|Rest]) ->
{{valuefieldreference,FieldName},Rest};
parse_PrimitiveFieldName(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [typefieldreference,valuefieldreference]]}}).
+ parse_error(Tokens).
parse_FieldName(Tokens) ->
{Field,Rest} = parse_PrimitiveFieldName(Tokens),
parse_FieldName(Rest,[Field]).
-parse_FieldName([{'.',_}|Rest],Acc) ->
- case (catch parse_PrimitiveFieldName(Rest)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- {FieldName,Rest2} ->
- parse_FieldName(Rest2,[FieldName|Acc])
- end;
-parse_FieldName(Tokens,Acc) ->
+parse_FieldName([{'.',_}|Rest0],Acc) ->
+ {FieldName,Rest1} = parse_PrimitiveFieldName(Rest0),
+ parse_FieldName(Rest1, [FieldName|Acc]);
+parse_FieldName(Tokens, Acc) ->
{lists:reverse(Acc),Tokens}.
-parse_FixedTypeValueFieldSpec([{valuefieldreference,L1,VFieldName}|Rest]) ->
+parse_FixedTypeValueFieldSpec([{valuefieldreference,_,VFieldName}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{Unique,Rest3} =
case Rest2 of
@@ -1139,109 +942,61 @@ parse_FixedTypeValueFieldSpec([{valuefieldreference,L1,VFieldName}|Rest]) ->
{undefined,Rest2}
end,
{OptionalitySpec,Rest5} = parse_ValueOptionalitySpec(Rest3),
- case {Unique,Rest5} of
- {'UNIQUE',[{Del,_}|_]} when Del =:= ','; Del =:= '}' ->
- case OptionalitySpec of
- {'DEFAULT',_} ->
- throw({asn1_error,
- {L1,get(asn1_module),
- ['UNIQUE and DEFAULT in same field',VFieldName]}});
- _ ->
- {{fixedtypevaluefield,VFieldName,Type,Unique,OptionalitySpec},Rest5}
- end;
- {_,[{Del,_}|_]} when Del =:= ','; Del =:= '}' ->
- {{object_or_fixedtypevalue_field,VFieldName,Type,Unique,OptionalitySpec},Rest5};
- _ ->
- throw({asn1_error,{L1,get(asn1_module),
- [got,get_token(hd(Rest5)),expected,[',','}']]}})
- end;
-parse_FixedTypeValueFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,valuefieldreference]}}).
+ case is_end_delimiter(Rest5) of
+ false -> parse_error(Rest5);
+ true -> ok
+ end,
+ Tag = case Unique of
+ 'UNIQUE' -> fixedtypevaluefield;
+ _ -> object_or_fixedtypevalue_field
+ end,
+ {{Tag,VFieldName,Type,Unique,OptionalitySpec},Rest5}.
+
+parse_VariableTypeValueFieldSpec([{valuefieldreference,_,VFieldName}|Rest0]) ->
+ {FieldRef,Rest1} = parse_FieldName(Rest0),
+ {OptionalitySpec,Rest} = parse_ValueOptionalitySpec(Rest1),
+ case is_end_delimiter(Rest) of
+ true ->
+ {{variabletypevaluefield,VFieldName,FieldRef,OptionalitySpec},
+ Rest};
+ false ->
+ parse_error(Rest)
+ end.
-parse_VariableTypeValueFieldSpec([{valuefieldreference,L,VFieldName}|Rest]) ->
- {FieldRef,Rest2} = parse_FieldName(Rest),
- {OptionalitySpec,Rest3} = parse_ValueOptionalitySpec(Rest2),
- case Rest3 of
- [{Del,_}|_] when Del =:= ','; Del =:= '}' ->
- {{variabletypevaluefield,VFieldName,FieldRef,OptionalitySpec},Rest3};
- _ ->
- throw({asn1_error,{L,get(asn1_module),
- [got,get_token(hd(Rest3)),expected,[',','}']]}})
- end;
-parse_VariableTypeValueFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,valuefieldreference]}}).
+parse_TypeFieldSpec([{typefieldreference,_,Name}|Rest0]) ->
+ {OptionalitySpec,Rest} = parse_TypeOptionalitySpec(Rest0),
+ case is_end_delimiter(Rest) of
+ true ->
+ {{typefield,Name,OptionalitySpec},Rest};
+ false ->
+ parse_error(Rest)
+ end.
-parse_ObjectFieldSpec([{valuefieldreference,L,VFieldName}|Rest]) ->
- {Class,Rest2} = parse_DefinedObjectClass(Rest),
- {OptionalitySpec,Rest3} = parse_ObjectOptionalitySpec(Rest2),
- case Rest3 of
- [{Del,_}|_] when Del =:= ','; Del =:= '}' ->
- {{objectfield,VFieldName,Class,undefined,OptionalitySpec},Rest3};
- _ ->
- throw({asn1_error,{L,get(asn1_module),
- [got,get_token(hd(Rest3)),expected,[',','}']]}})
- end;
-parse_ObjectFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,valuefieldreference]}}).
+parse_FixedTypeValueSetFieldSpec([{typefieldreference,_,Name}|Rest0]) ->
+ {Type,Rest1} = parse_Type(Rest0),
+ {OptionalitySpec,Rest} = parse_ValueSetOptionalitySpec(Rest1),
+ case is_end_delimiter(Rest) of
+ true ->
+ {{objectset_or_fixedtypevalueset_field,Name,Type,
+ OptionalitySpec},Rest};
+ false ->
+ parse_error(Rest)
+ end.
-parse_TypeFieldSpec([{typefieldreference,L,TFieldName}|Rest]) ->
- {OptionalitySpec,Rest2} = parse_TypeOptionalitySpec(Rest),
- case Rest2 of
- [{Del,_}|_] when Del =:= ','; Del =:= '}' ->
- {{typefield,TFieldName,OptionalitySpec},Rest2};
- _ ->
- throw({asn1_error,{L,get(asn1_module),
- [got,get_token(hd(Rest2)),expected,[',','}']]}})
- end;
-parse_TypeFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
+parse_VariableTypeValueSetFieldSpec([{typefieldreference,_,Name}|Rest0]) ->
+ {FieldRef,Rest1} = parse_FieldName(Rest0),
+ {OptionalitySpec,Rest} = parse_ValueSetOptionalitySpec(Rest1),
+ case is_end_delimiter(Rest) of
+ true ->
+ {{variabletypevaluesetfield,Name,FieldRef,OptionalitySpec},
+ Rest};
+ false ->
+ parse_error(Rest)
+ end.
-parse_FixedTypeValueSetFieldSpec([{typefieldreference,L,TFieldName}|Rest]) ->
- {Type,Rest2} = parse_Type(Rest),
- {OptionalitySpec,Rest3} = parse_ValueSetOptionalitySpec(Rest2),
- case Rest3 of
- [{Del,_}|_] when Del =:= ','; Del =:= '}' ->
- {{objectset_or_fixedtypevalueset_field,TFieldName,Type,
- OptionalitySpec},Rest3};
- _ ->
- throw({asn1_error,{L,get(asn1_module),
- [got,get_token(hd(Rest3)),expected,[',','}']]}})
- end;
-parse_FixedTypeValueSetFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
-
-parse_VariableTypeValueSetFieldSpec([{typefieldreference,L,TFieldName}|Rest]) ->
- {FieldRef,Rest2} = parse_FieldName(Rest),
- {OptionalitySpec,Rest3} = parse_ValueSetOptionalitySpec(Rest2),
- case Rest3 of
- [{Del,_}|_] when Del =:= ','; Del =:= '}' ->
- {{variabletypevaluesetfield,TFieldName,FieldRef,OptionalitySpec},Rest3};
- _ ->
- throw({asn1_error,{L,get(asn1_module),
- [got,get_token(hd(Rest3)),expected,[',','}']]}})
- end;
-parse_VariableTypeValueSetFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
-
-parse_ObjectSetFieldSpec([{typefieldreference,L,TFieldName}|Rest]) ->
- {Class,Rest2} = parse_DefinedObjectClass(Rest),
- {OptionalitySpec,Rest3} = parse_ObjectSetOptionalitySpec(Rest2),
- case Rest3 of
- [{Del,_}|_] when Del =:= ','; Del =:= '}' ->
- {{objectsetfield,TFieldName,Class,OptionalitySpec},Rest3};
- _ ->
- throw({asn1_error,{L,get(asn1_module),
- [got,get_token(hd(Rest3)),expected,[',','}']]}})
- end;
-parse_ObjectSetFieldSpec(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
+is_end_delimiter([{',',_}|_]) -> true;
+is_end_delimiter([{'}',_}|_]) -> true;
+is_end_delimiter([_|_]) -> false.
parse_ValueOptionalitySpec(Tokens)->
case Tokens of
@@ -1252,15 +1007,6 @@ parse_ValueOptionalitySpec(Tokens)->
_ -> {'MANDATORY',Tokens}
end.
-parse_ObjectOptionalitySpec(Tokens) ->
- case Tokens of
- [{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
- [{'DEFAULT',_}|Rest] ->
- {Object,Rest2} = parse_Object(Rest),
- {{'DEFAULT',Object},Rest2};
- _ -> {'MANDATORY',Tokens}
- end.
-
parse_TypeOptionalitySpec(Tokens) ->
case Tokens of
[{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
@@ -1279,65 +1025,44 @@ parse_ValueSetOptionalitySpec(Tokens) ->
_ -> {'MANDATORY',Tokens}
end.
-parse_ObjectSetOptionalitySpec(Tokens) ->
- case Tokens of
- [{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
- [{'DEFAULT',_}|Rest] ->
- {ObjectSet,Rest2} = parse_ObjectSet(Rest),
- {{'DEFAULT',ObjectSet},Rest2};
- _ -> {'MANDATORY',Tokens}
- end.
-
parse_WithSyntaxSpec([{'WITH',_},{'SYNTAX',_}|Rest]) ->
{SyntaxList,Rest2} = parse_SyntaxList(Rest),
{{'WITH SYNTAX',SyntaxList},Rest2};
parse_WithSyntaxSpec(Tokens) ->
{[],Tokens}.
-parse_SyntaxList([{'{',_},{'}',_}|Rest]) ->
- {[],Rest};
parse_SyntaxList([{'{',_}|Rest]) ->
parse_SyntaxList(Rest,[]);
parse_SyntaxList(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,['{}','{']]}}).
+ parse_error(Tokens).
-parse_SyntaxList(Tokens,Acc) ->
+parse_SyntaxList(Tokens, Acc) ->
{SyntaxList,Rest} = parse_TokenOrGroupSpec(Tokens),
case Rest of
[{'}',_}|Rest2] ->
- {lists:reverse([SyntaxList|Acc]),Rest2};
+ {lists:reverse(Acc, [SyntaxList]),Rest2};
_ ->
- parse_SyntaxList(Rest,[SyntaxList|Acc])
+ parse_SyntaxList(Rest, [SyntaxList|Acc])
end.
parse_TokenOrGroupSpec(Tokens) ->
Flist = [fun parse_RequiredToken/1,
fun parse_OptionalGroup/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
-parse_RequiredToken([{typereference,L1,WordName}|Rest]) ->
+parse_RequiredToken([{typereference,_,WordName}|Rest]=Tokens) ->
case is_word(WordName) of
false ->
- throw({asn1_error,{L1,get(asn1_module),
- [got,WordName,expected,a,'Word']}});
+ parse_error(Tokens);
true ->
{WordName,Rest}
end;
parse_RequiredToken([{',',L1}|Rest]) ->
{{',',L1},Rest};
-parse_RequiredToken([{WordName,L1}|Rest]) ->
+parse_RequiredToken([{WordName,_}|Rest]=Tokens) ->
case is_word(WordName) of
false ->
- throw({asn1_error,{L1,get(asn1_module),
- [got,WordName,expected,a,'Word']}});
+ parse_error(Tokens);
true ->
{WordName,Rest}
end;
@@ -1347,7 +1072,9 @@ parse_RequiredToken(Tokens) ->
parse_OptionalGroup([{'[',_}|Rest]) ->
{Spec,Rest2} = parse_TokenOrGroupSpec(Rest),
{SpecList,Rest3} = parse_OptionalGroup(Rest2,[Spec]),
- {SpecList,Rest3}.
+ {SpecList,Rest3};
+parse_OptionalGroup(Tokens) ->
+ parse_error(Tokens).
parse_OptionalGroup([{']',_}|Rest],Acc) ->
{lists:reverse(Acc),Rest};
@@ -1355,82 +1082,55 @@ parse_OptionalGroup(Tokens,Acc) ->
{Spec,Rest} = parse_TokenOrGroupSpec(Tokens),
parse_OptionalGroup(Rest,[Spec|Acc]).
-parse_DefinedObject([Id={identifier,_,_ObjName}|Rest]) ->
+parse_DefinedObject([#identifier{}=Id|Rest]) ->
{{object,identifier2Extvalueref(Id)},Rest};
-parse_DefinedObject([{typereference,L1,ModName},{'.',_},{identifier,_,ObjName}|Rest]) ->
+parse_DefinedObject([{typereference,L1,ModName},{'.',_},#identifier{val=ObjName}|Rest]) ->
{{object, #'Externaltypereference'{pos=L1,module=ModName,type=ObjName}},Rest};
parse_DefinedObject(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [identifier,'typereference.identifier']]}}).
+ parse_error(Tokens).
-parse_ObjectAssignment([{identifier,L1,ObjName}|Rest]) ->
+parse_ObjectAssignment([#identifier{pos=L1,val=ObjName}|Rest]) ->
{Class,Rest2} = parse_DefinedObjectClass(Rest),
case Rest2 of
[{'::=',_}|Rest3] ->
{Object,Rest4} = parse_Object(Rest3),
{#typedef{pos=L1,name=ObjName,
typespec=#'Object'{classname=Class,def=Object}},Rest4};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}});
- Other ->
- throw({asn1_error,{L1,get(asn1_module),
- [got,Other,expected,'::=']}})
- end;
-parse_ObjectAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
-
+ _ ->
+ parse_error(Rest2)
+ end.
%% parse_Object(Tokens) -> Ret
%% Tokens = [Tok]
%% Tok = tuple()
%% Ret = {object,_} | {object, _, _}
parse_Object(Tokens) ->
- Flist=[fun parse_ObjectDefn/1,
- fun parse_ObjectFromObject/1,
- fun parse_ParameterizedObject/1,
- fun parse_DefinedObject/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ %% The ObjectFromObject production is not included here,
+ %% since it will have been catched by the ValueFromObject
+ %% before we reach this point.
+ Flist = [fun parse_ObjectDefn/1,
+ fun parse_DefinedObject/1],
+ parse_or(Tokens, Flist).
parse_ObjectDefn(Tokens) ->
Flist=[fun parse_DefaultSyntax/1,
fun parse_DefinedSyntax/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
-parse_DefaultSyntax([{'{',_},{'}',_}|Rest]) ->
- {{object,defaultsyntax,[]},Rest};
parse_DefaultSyntax([{'{',_}|Rest]) ->
parse_DefaultSyntax(Rest,[]);
parse_DefaultSyntax(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,['{}','{']]}}).
+ parse_error(Tokens).
-parse_DefaultSyntax(Tokens,Acc) ->
+parse_DefaultSyntax(Tokens, Acc) ->
{Setting,Rest} = parse_FieldSetting(Tokens),
case Rest of
[{',',_}|Rest2] ->
parse_DefaultSyntax(Rest2,[Setting|Acc]);
[{'}',_}|Rest3] ->
- {{object,defaultsyntax,lists:reverse([Setting|Acc])},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,[',','}']]}})
+ {{object,defaultsyntax,lists:reverse(Acc, [Setting])},Rest3};
+ _ ->
+ parse_error(Rest)
end.
parse_FieldSetting(Tokens) ->
@@ -1439,7 +1139,9 @@ parse_FieldSetting(Tokens) ->
{{PrimFieldName,Setting},Rest2}.
parse_DefinedSyntax([{'{',_}|Rest]) ->
- parse_DefinedSyntax(Rest,[]).
+ parse_DefinedSyntax(Rest, []);
+parse_DefinedSyntax(Tokens) ->
+ parse_error(Tokens).
parse_DefinedSyntax(Tokens,Acc) ->
case Tokens of
@@ -1455,95 +1157,70 @@ parse_DefinedSyntax(Tokens,Acc) ->
%% Literal ::= word | ','
%% Setting ::= Type | Value | ValueSet | Object | ObjectSet
%% word equals typereference, but no lower cases
-parse_DefinedSyntaxToken([{',',L1}|Rest]) ->
- {{',',L1},Rest};
+parse_DefinedSyntaxToken([{',',_}=Comma|Rest]) ->
+ {Comma,Rest};
%% ObjectClassFieldType or a defined type with a constraint.
%% Should also be able to parse a parameterized type. It may be
%% impossible to distinguish between a parameterized type and a Literal
%% followed by an object set.
-parse_DefinedSyntaxToken(Tokens=[{typereference,L1,_Name},{T,_}|_Rest])
- when T == '.'; T == '(' ->
- case catch parse_Setting(Tokens) of
- {asn1_error,_} ->
- throw({asn1_error,{L1,get(asn1_module),
- [got,hd(Tokens), expected,['Word',setting]]}});
- {'EXIT',Reason} ->
- exit(Reason);
- Result ->
- Result
- end;
-parse_DefinedSyntaxToken(Tokens=[TRef={typereference,L1,Name}|Rest]) ->
+parse_DefinedSyntaxToken([{typereference,_,_Name},{T,_}|_]=Tokens)
+ when T =:= '.'; T =:= '(' ->
+ parse_Setting(Tokens);
+parse_DefinedSyntaxToken([{typereference,L1,Name}=TRef|Rest]=Tokens) ->
case is_word(Name) of
false ->
case lookahead_definedsyntax(Rest) of
word_or_setting ->
{{setting,L1,tref2Exttref(TRef)},Rest};
- _ ->
+ setting ->
parse_Setting(Tokens)
end;
true ->
- %% {{word_or_setting,L1,Name},Rest}
{{word_or_setting,L1,tref2Exttref(TRef)},Rest}
end;
parse_DefinedSyntaxToken(Tokens) ->
- case catch parse_Setting(Tokens) of
- {asn1_error,_} ->
- parse_Word(Tokens);
- {'EXIT',Reason} ->
- exit(Reason);
- Result ->
+ try parse_Setting(Tokens) of
+ {_,_}=Result ->
Result
+ catch
+ throw:{asn1_error,_} ->
+ parse_Word(Tokens)
end.
lookahead_definedsyntax([{typereference,_,Name}|_Rest]) ->
- case is_word(Name) of
+ case is_word(Name) of
true -> word_or_setting;
- _ -> setting
+ false -> setting
end;
lookahead_definedsyntax([{'}',_}|_Rest]) ->
word_or_setting;
lookahead_definedsyntax(_) ->
setting.
-parse_Word([{Name,Pos}|Rest]) ->
+parse_Word([{Name,Pos}|Rest]=Tokens) ->
case is_word(Name) of
false ->
- throw({asn1_error,{Pos,get(asn1_module),
- [got,Name, expected,a,'Word']}});
+ parse_error(Tokens);
true ->
{{word_or_setting,Pos,tref2Exttref(Pos,Name)},Rest}
- end.
+ end;
+parse_Word(Tokens) ->
+ parse_error(Tokens).
parse_Setting(Tokens) ->
Flist = [{type_tag,fun parse_Type/1},
{value_tag,fun parse_Value/1},
{object_tag,fun parse_Object/1},
{objectset_tag,fun parse_ObjectSet/1}],
- case (catch parse_or_tag(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result = {{value_tag,_},_} ->
+ case parse_or_tag(Tokens, Flist) of
+ {{value_tag,_},_}=Result ->
+ %% Keep the value_tag.
Result;
{{Tag,Setting},Rest} when is_atom(Tag) ->
+ %% Remove all other tags.
{Setting,Rest}
end.
-%% parse_Setting(Tokens) ->
-%% Flist = [fun parse_Type/1,
-%% fun parse_Value/1,
-%% fun parse_Object/1,
-%% fun parse_ObjectSet/1],
-%% case (catch parse_or(Tokens,Flist)) of
-%% {'EXIT',Reason} ->
-%% exit(Reason);
-%% AsnErr = {asn1_error,_} ->
-%% throw(AsnErr);
-%% Result ->
-%% Result
-%% end.
-
parse_DefinedObjectSet([{typereference,L1,ModuleName},{'.',_},
{typereference,L2,ObjSetName}|Rest]) ->
{{objectset,L1,#'Externaltypereference'{pos=L2,module=ModuleName,
@@ -1552,9 +1229,7 @@ parse_DefinedObjectSet([{typereference,L1,ObjSetName}|Rest]) ->
{{objectset,L1,#'Externaltypereference'{pos=L1,module=resolve_module(ObjSetName),
type=ObjSetName}},Rest};
parse_DefinedObjectSet(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [typereference,'typereference.typereference']]}}).
+ parse_error(Tokens).
parse_ObjectSetAssignment([{typereference,L1,ObjSetName}|Rest]) ->
{Class,Rest2} = parse_DefinedObjectClass(Rest),
@@ -1564,16 +1239,9 @@ parse_ObjectSetAssignment([{typereference,L1,ObjSetName}|Rest]) ->
{#typedef{pos=L1,name=ObjSetName,
typespec=#'ObjectSet'{class=Class,
set=ObjectSet}},Rest4};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
-%%% Other ->
-%%% throw(Other)
- end;
-parse_ObjectSetAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- typereference]}}).
+ _ ->
+ parse_error(Rest2)
+ end.
%% parse_ObjectSet(Tokens) -> {Ret,Rest}
%% Tokens = [Tok]
@@ -1590,26 +1258,20 @@ parse_ObjectSet([{'{',_}|Rest]) ->
case Rest2 of
[{'}',_}|Rest3] ->
{ObjSetSpec,Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'}']}})
+ _ ->
+ parse_error(Rest2)
end;
parse_ObjectSet(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+ parse_error(Tokens).
-parse_ObjectSetSpec([{'...',_}|Rest]) ->
- case Rest of
- [{',',_}|Rest2] ->
- {Elements,Rest3}=parse_ElementSetSpecs(Rest2),
- {{[],Elements},Rest3};
- _ ->
- {['EXTENSIONMARK'],Rest}
- end;
+parse_ObjectSetSpec([{'...',_},{',',_}|Tokens0]) ->
+ {Elements,Tokens} = parse_ElementSetSpec(Tokens0),
+ {{element_set,empty,Elements},Tokens};
+parse_ObjectSetSpec([{'...',_}|Tokens]) ->
+ {{element_set,empty,empty},Tokens};
parse_ObjectSetSpec(Tokens) ->
parse_ElementSetSpecs(Tokens).
-% moved fun parse_Object/1 and fun parse_DefinedObjectSet/1 to parse_Elements
%% parse_ObjectSetElements(Tokens) -> {Result,Rest}
%% Result ::= {'ObjectSetFromObjects',Objects,Name} | {pos,ObjectSet,Params}
%% Objects ::= ReferencedObjects
@@ -1619,18 +1281,9 @@ parse_ObjectSetSpec(Tokens) ->
%% ObjectSet ::= {objectset,integer(),#'Externaltypereference'{}}
%% Params ::= list() (see parse_ActualParameterList/1)
parse_ObjectSetElements(Tokens) ->
- Flist = [%fun parse_Object/1,
- %fun parse_DefinedObjectSet/1,
- fun parse_ObjectSetFromObjects/1,
+ Flist = [fun parse_ObjectSetFromObjects/1,
fun parse_ParameterizedObjectSet/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_ObjectClassFieldType(Tokens) ->
{Class,Rest} = parse_DefinedObjectClass(Tokens),
@@ -1641,25 +1294,10 @@ parse_ObjectClassFieldType(Tokens) ->
classname=Class,
class=Class,fieldname=FieldName},
{#type{def=OCFT},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'.']}})
-%%% Other ->
-%%% throw(Other)
+ _ ->
+ parse_error(Rest)
end.
-%parse_ObjectClassFieldValue(Tokens) ->
-% Flist = [fun parse_OpenTypeFieldVal/1,
-% fun parse_FixedTypeFieldVal/1],
-% case (catch parse_or(Tokens,Flist)) of
-% {'EXIT',Reason} ->
-% throw(Reason);
-% AsnErr = {asn1_error,_} ->
-% throw(AsnErr);
-% Result ->
-% Result
-% end.
-
parse_ObjectClassFieldValue(Tokens) ->
parse_OpenTypeFieldVal(Tokens).
@@ -1669,28 +1307,10 @@ parse_OpenTypeFieldVal(Tokens) ->
[{':',_}|Rest2] ->
{Value,Rest3} = parse_Value(Rest2),
{{opentypefieldvalue,Type,Value},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,':']}})
+ _ ->
+ parse_error(Rest)
end.
-% parse_FixedTypeFieldVal(Tokens) ->
-% parse_Value(Tokens).
-
-% parse_InformationFromObjects(Tokens) ->
-% Flist = [fun parse_ValueFromObject/1,
-% fun parse_ValueSetFromObjects/1,
-% fun parse_TypeFromObject/1,
-% fun parse_ObjectFromObject/1],
-% case (catch parse_or(Tokens,Flist)) of
-% {'EXIT',Reason} ->
-% throw(Reason);
-% AsnErr = {asn1_error,_} ->
-% throw(AsnErr);
-% Result ->
-% Result
-% end.
-
%% parse_ReferencedObjects(Tokens) -> {Result,Rest}
%% Result ::= DefObject | DefObjSet |
%% {po,DefObject,Params} | {pos,DefObjSet,Params} |
@@ -1702,18 +1322,11 @@ parse_OpenTypeFieldVal(Tokens) ->
parse_ReferencedObjects(Tokens) ->
Flist = [fun parse_DefinedObject/1,
fun parse_DefinedObjectSet/1,
- fun parse_ParameterizedObject/1,
fun parse_ParameterizedObjectSet/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_ValueFromObject(Tokens) ->
+ %% This production also matches ObjectFromObject.
{Objects,Rest} = parse_ReferencedObjects(Tokens),
case Rest of
[{'.',_}|Rest2] ->
@@ -1722,35 +1335,10 @@ parse_ValueFromObject(Tokens) ->
{valuefieldreference,_} ->
{{'ValueFromObject',Objects,Name},Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,typefieldreference,expected,
- valuefieldreference]}})
+ parse_error(Rest2)
end;
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'.']}})
-%%% Other ->
-%%% throw({asn1_error,{got,Other,expected,'.'}})
- end.
-
-parse_ValueSetFromObjects(Tokens) ->
- {Objects,Rest} = parse_ReferencedObjects(Tokens),
- case Rest of
- [{'.',_}|Rest2] ->
- {Name,Rest3} = parse_FieldName(Rest2),
- case lists:last(Name) of
- {typefieldreference,_FieldName} ->
- {{'ValueSetFromObjects',Objects,Name},Rest3};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,
- typefieldreference]}})
- end;
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'.']}})
-%%% Other ->
-%%% throw({asn1_error,{got,Other,expected,'.'}})
+ _ ->
+ parse_error(Rest)
end.
parse_TypeFromObject(Tokens) ->
@@ -1760,28 +1348,12 @@ parse_TypeFromObject(Tokens) ->
{Name,Rest3} = parse_FieldName(Rest2),
case lists:last(Name) of
{typefieldreference,_FieldName} ->
- {{'TypeFromObject',Objects,Name},Rest3};
+ {#type{def={'TypeFromObject',Objects,Name}},Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,
- typefieldreference]}})
+ parse_error(Rest2)
end;
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'.']}})
-%%% Other ->
-%%% throw({asn1_error,{got,Other,expected,'.'}})
- end.
-
-parse_ObjectFromObject(Tokens) ->
- {Objects,Rest} = parse_ReferencedObjects(Tokens),
- case Rest of
- [{'.',_}|Rest2] ->
- {Name,Rest3} = parse_FieldName(Rest2),
- {{'ObjectFromObject',Objects,Name},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'.']}})
+ _ ->
+ parse_error(Rest)
end.
%% parse_ObjectSetFromObjects(Tokens) -> {Result,Rest}
@@ -1799,23 +1371,12 @@ parse_ObjectSetFromObjects(Tokens) ->
{typefieldreference,_FieldName} ->
{{'ObjectSetFromObjects',Objects,Name},Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,
- typefieldreference]}})
+ parse_error(Rest2)
end;
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'.']}})
+ _ ->
+ parse_error(Rest)
end.
-% parse_InstanceOfType([{'INSTANCE',_},{'OF',_}|Rest]) ->
-% {Class,Rest2} = parse_DefinedObjectClass(Rest),
-% {{'InstanceOfType',Class},Rest2}.
-
-% parse_InstanceOfValue(Tokens) ->
-% parse_Value(Tokens).
-
-
%% X.682 constraint specification
@@ -1823,14 +1384,7 @@ parse_GeneralConstraint(Tokens) ->
Flist = [fun parse_UserDefinedConstraint/1,
fun parse_TableConstraint/1,
fun parse_ContentsConstraint/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_UserDefinedConstraint([{'CONSTRAINED',_},{'BY',_},{'{',_},{'}',_}|Rest])->
{{constrained_by,[]},Rest};
@@ -1841,32 +1395,23 @@ parse_UserDefinedConstraint([{'CONSTRAINED',_},
case Rest2 of
[{'}',_}|Rest3] ->
{{constrained_by,Param},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'}']}})
+ _ ->
+ parse_error(Rest2)
end;
parse_UserDefinedConstraint(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- ['CONSTRAINED BY {}','CONSTRAINED BY {']]}}).
+ parse_error(Tokens).
parse_UserDefinedConstraintParameter(Tokens) ->
- parse_UserDefinedConstraintParameter(Tokens,[]).
-parse_UserDefinedConstraintParameter(Tokens,Acc) ->
+ parse_UserDefinedConstraintParameter(Tokens, []).
+
+parse_UserDefinedConstraintParameter(Tokens0, Acc) ->
Flist = [fun parse_GovernorAndActualParameter/1,
fun parse_ActualParameter/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- {Result,Rest} ->
- case Rest of
- [{',',_}|_Rest2] ->
- parse_UserDefinedConstraintParameter(Tokens,[Result|Acc]);
- _ ->
- {lists:reverse([Result|Acc]),Rest}
- end
+ case parse_or(Tokens0, Flist) of
+ {Result,[{',',_}|Tokens]} ->
+ parse_UserDefinedConstraintParameter(Tokens, [Result|Acc]);
+ {Result,Tokens} ->
+ {lists:reverse(Acc, [Result]),Tokens}
end.
parse_GovernorAndActualParameter(Tokens) ->
@@ -1875,26 +1420,18 @@ parse_GovernorAndActualParameter(Tokens) ->
[{':',_}|Rest2] ->
{Params,Rest3} = parse_ActualParameter(Rest2),
{{'Governor_Params',Governor,Params},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,':']}})
+ _ ->
+ parse_error(Rest)
end.
parse_TableConstraint(Tokens) ->
Flist = [fun parse_ComponentRelationConstraint/1,
fun parse_SimpleTableConstraint/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_SimpleTableConstraint(Tokens) ->
{ObjectSet,Rest} = parse_ObjectSet(Tokens),
- {{simpletable,ObjectSet},Rest}.
+ {{element_set,{simpletable,ObjectSet},none},Rest}.
parse_ComponentRelationConstraint([{'{',_}|Rest]) ->
{ObjectSet,Rest2} = parse_DefinedObjectSet(Rest),
@@ -1903,21 +1440,18 @@ parse_ComponentRelationConstraint([{'{',_}|Rest]) ->
{AtNot,Rest4} = parse_AtNotationList(Rest3,[]),
case Rest4 of
[{'}',_}|Rest5] ->
- {{componentrelation,ObjectSet,AtNot},Rest5};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'}']}})
+ Ret = {element_set,
+ {componentrelation,ObjectSet,AtNot},
+ none},
+ {Ret,Rest5};
+ _ ->
+ parse_error(Rest4)
end;
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,
- 'ComponentRelationConstraint',ended,with,'}']}})
-%%% Other ->
-%%% throw(Other)
+ _ ->
+ parse_error(Rest2)
end;
parse_ComponentRelationConstraint(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+ parse_error(Tokens).
parse_AtNotationList(Tokens,Acc) ->
{AtNot,Rest} = parse_AtNotation(Tokens),
@@ -1925,7 +1459,7 @@ parse_AtNotationList(Tokens,Acc) ->
[{',',_}|Rest2] ->
parse_AtNotationList(Rest2,[AtNot|Acc]);
_ ->
- {lists:reverse([AtNot|Acc]),Rest}
+ {lists:reverse(Acc, [AtNot]),Rest}
end.
parse_AtNotation([{'@',_},{'.',_}|Rest]) ->
@@ -1935,20 +1469,17 @@ parse_AtNotation([{'@',_}|Rest]) ->
{CIdList,Rest2} = parse_ComponentIdList(Rest),
{{outermost,CIdList},Rest2};
parse_AtNotation(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,['@','@.']]}}).
+ parse_error(Tokens).
parse_ComponentIdList(Tokens) ->
parse_ComponentIdList(Tokens,[]).
-parse_ComponentIdList([Id = {identifier,_,_},{'.',_}|Rest],Acc) ->
+parse_ComponentIdList([#identifier{}=Id,{'.',_}|Rest], Acc) ->
parse_ComponentIdList(Rest,[identifier2Extvalueref(Id)|Acc]);
-parse_ComponentIdList([Id = {identifier,_,_}|Rest],Acc) ->
- {lists:reverse([identifier2Extvalueref(Id)|Acc]),Rest};
+parse_ComponentIdList([#identifier{}=Id|Rest], Acc) ->
+ {lists:reverse(Acc, [identifier2Extvalueref(Id)]),Rest};
parse_ComponentIdList(Tokens,_) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [identifier,'identifier.']]}}).
+ parse_error(Tokens).
parse_ContentsConstraint([{'CONTAINING',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
@@ -1963,24 +1494,14 @@ parse_ContentsConstraint([{'ENCODED',_},{'BY',_}|Rest]) ->
{Value,Rest2} = parse_Value(Rest),
{{contentsconstraint,[],Value},Rest2};
parse_ContentsConstraint(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- 'CONTAINING','or','ENCODED BY']}}).
-
+ parse_error(Tokens).
% X.683 Parameterization of ASN.1 specifications
parse_Governor(Tokens) ->
Flist = [fun parse_Type/1,
fun parse_DefinedObjectClass/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_ActualParameter(Tokens) ->
Flist = [fun parse_Type/1,
@@ -1989,32 +1510,7 @@ parse_ActualParameter(Tokens) ->
fun parse_DefinedObjectClass/1,
fun parse_Object/1,
fun parse_ObjectSet/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
-
-parse_ParameterizedAssignment(Tokens) ->
- Flist = [fun parse_ParameterizedTypeAssignment/1,
- fun parse_ParameterizedValueAssignment/1,
- fun parse_ParameterizedValueSetTypeAssignment/1,
- fun parse_ParameterizedObjectClassAssignment/1,
- fun parse_ParameterizedObjectAssignment/1,
- fun parse_ParameterizedObjectSetAssignment/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- AsnAssErr = {asn1_assignment_error,_} ->
- throw(AsnAssErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
%% parse_ParameterizedTypeAssignment(Tokens) -> Result
%% Result = {#ptypedef{},Rest} | throw()
@@ -2025,18 +1521,13 @@ parse_ParameterizedTypeAssignment([{typereference,L1,Name}|Rest]) ->
{Type,Rest4} = parse_Type(Rest3),
{#ptypedef{pos=L1,name=Name,args=ParameterList,typespec=Type},
Rest4};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
- end;
-parse_ParameterizedTypeAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- typereference]}}).
+ _ ->
+ parse_error(Rest2)
+ end.
%% parse_ParameterizedValueAssignment(Tokens) -> Result
%% Result = {#pvaluedef{},Rest} | throw()
-parse_ParameterizedValueAssignment([{identifier,L1,Name}|Rest]) ->
+parse_ParameterizedValueAssignment([#identifier{pos=L1,val=Name}|Rest]) ->
{ParameterList,Rest2} = parse_ParameterList(Rest),
{Type,Rest3} = parse_Type(Rest2),
case Rest3 of
@@ -2044,13 +1535,9 @@ parse_ParameterizedValueAssignment([{identifier,L1,Name}|Rest]) ->
{Value,Rest5} = parse_Value(Rest4),
{#pvaluedef{pos=L1,name=Name,args=ParameterList,type=Type,
value=Value},Rest5};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
- end;
-parse_ParameterizedValueAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
+ _ ->
+ parse_error(Rest3)
+ end.
%% parse_ParameterizedValueSetTypeAssignment(Tokens) -> Result
%% Result = {#pvaluesetdef{},Rest} | throw()
@@ -2062,14 +1549,9 @@ parse_ParameterizedValueSetTypeAssignment([{typereference,L1,Name}|Rest]) ->
{ValueSet,Rest5} = parse_ValueSet(Rest4),
{#pvaluesetdef{pos=L1,name=Name,args=ParameterList,
type=Type,valueset=ValueSet},Rest5};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
- end;
-parse_ParameterizedValueSetTypeAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- typereference]}}).
+ _ ->
+ parse_error(Rest3)
+ end.
%% parse_ParameterizedObjectClassAssignment(Tokens) -> Result
%% Result = {#ptypedef{},Rest} | throw()
@@ -2080,18 +1562,13 @@ parse_ParameterizedObjectClassAssignment([{typereference,L1,Name}|Rest]) ->
{Class,Rest4} = parse_ObjectClass(Rest3),
{#ptypedef{pos=L1,name=Name,args=ParameterList,typespec=Class},
Rest4};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
- end;
-parse_ParameterizedObjectClassAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- typereference]}}).
+ _ ->
+ parse_error(Rest2)
+ end.
%% parse_ParameterizedObjectAssignment(Tokens) -> Result
%% Result = {#pobjectdef{},Rest} | throw()
-parse_ParameterizedObjectAssignment([{identifier,L1,Name}|Rest]) ->
+parse_ParameterizedObjectAssignment([#identifier{pos=L1,val=Name}|Rest]) ->
{ParameterList,Rest2} = parse_ParameterList(Rest),
{Class,Rest3} = parse_DefinedObjectClass(Rest2),
case Rest3 of
@@ -2099,36 +1576,9 @@ parse_ParameterizedObjectAssignment([{identifier,L1,Name}|Rest]) ->
{Object,Rest5} = parse_Object(Rest4),
{#pobjectdef{pos=L1,name=Name,args=ParameterList,
class=Class,def=Object},Rest5};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
-%%% Other ->
-%%% throw(Other)
- end;
-parse_ParameterizedObjectAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
-
-%% parse_ParameterizedObjectSetAssignment(Tokens) -> Result
-%% Result = {#pobjectsetdef{},Rest} | throw{}
-parse_ParameterizedObjectSetAssignment([{typereference,L1,Name}|Rest]) ->
- {ParameterList,Rest2} = parse_ParameterList(Rest),
- {Class,Rest3} = parse_DefinedObjectClass(Rest2),
- case Rest3 of
- [{'::=',_}|Rest4] ->
- {ObjectSet,Rest5} = parse_ObjectSet(Rest4),
- {#pobjectsetdef{pos=L1,name=Name,args=ParameterList,
- class=Class,def=ObjectSet},Rest5};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
-%%% Other ->
-%%% throw(Other)
- end;
-parse_ParameterizedObjectSetAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- typereference]}}).
+ _ ->
+ parse_error(Rest3)
+ end.
%% parse_ParameterList(Tokens) -> Result
%% Result = [Parameter]
@@ -2137,35 +1587,24 @@ parse_ParameterizedObjectSetAssignment(Tokens) ->
%% Type = #type{}
%% DefinedObjectClass = #'Externaltypereference'{}
%% Reference = #'Externaltypereference'{} | #'Externalvaluereference'{}
-parse_ParameterList([{'{',_}|Rest]) ->
- parse_ParameterList(Rest,[]);
-parse_ParameterList(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+parse_ParameterList([{'{',_}|Tokens]) ->
+ parse_ParameterList(Tokens, []).
parse_ParameterList(Tokens,Acc) ->
{Parameter,Rest} = parse_Parameter(Tokens),
case Rest of
[{',',_}|Rest2] ->
- parse_ParameterList(Rest2,[Parameter|Acc]);
+ parse_ParameterList(Rest2, [Parameter|Acc]);
[{'}',_}|Rest3] ->
- {lists:reverse([Parameter|Acc]),Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,[',','}']]}})
+ {lists:reverse(Acc, [Parameter]),Rest3};
+ _ ->
+ parse_error(Rest)
end.
parse_Parameter(Tokens) ->
Flist = [fun parse_ParamGovAndRef/1,
fun parse_Reference/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_ParamGovAndRef(Tokens) ->
{ParamGov,Rest} = parse_ParamGovernor(Tokens),
@@ -2173,86 +1612,54 @@ parse_ParamGovAndRef(Tokens) ->
[{':',_}|Rest2] ->
{Ref,Rest3} = parse_Reference(Rest2),
{{ParamGov,Ref},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,':']}})
+ _ ->
+ parse_error(Rest)
end.
parse_ParamGovernor(Tokens) ->
Flist = [fun parse_Governor/1,
fun parse_Reference/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
-
-% parse_ParameterizedReference(Tokens) ->
-% {Ref,Rest} = parse_Reference(Tokens),
-% case Rest of
-% [{'{',_},{'}',_}|Rest2] ->
-% {{ptref,Ref},Rest2};
-% _ ->
-% {{ptref,Ref},Rest}
-% end.
+ parse_or(Tokens, Flist).
parse_SimpleDefinedType([{typereference,L1,ModuleName},{'.',_},
{typereference,_,TypeName}|Rest]) ->
{#'Externaltypereference'{pos=L1,module=ModuleName,
type=TypeName},Rest};
parse_SimpleDefinedType([Tref={typereference,_,_}|Rest]) ->
-% {#'Externaltypereference'{pos=L2,module=get(asn1_module),
-% type=TypeName},Rest};
{tref2Exttref(Tref),Rest};
parse_SimpleDefinedType(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [typereference,'typereference.typereference']]}}).
+ parse_error(Tokens).
parse_SimpleDefinedValue([{typereference,L1,ModuleName},{'.',_},
- {identifier,_,Value}|Rest]) ->
+ #identifier{val=Value}|Rest]) ->
{{simpledefinedvalue,#'Externalvaluereference'{pos=L1,module=ModuleName,
value=Value}},Rest};
-parse_SimpleDefinedValue([Id={identifier,_,_Value}|Rest]) ->
+parse_SimpleDefinedValue([#identifier{}=Id|Rest]) ->
{{simpledefinedvalue,identifier2Extvalueref(Id)},Rest};
parse_SimpleDefinedValue(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- ['typereference.identifier',identifier]]}}).
+ parse_error(Tokens).
parse_ParameterizedType(Tokens) ->
+ %% May also be a parameterized class.
{Type,Rest} = parse_SimpleDefinedType(Tokens),
{Params,Rest2} = parse_ActualParameterList(Rest),
- {{pt,Type,Params},Rest2}.
+ {#type{def={pt,Type,Params}},Rest2}.
parse_ParameterizedValue(Tokens) ->
+ %% May also be a parameterized object.
{Value,Rest} = parse_SimpleDefinedValue(Tokens),
{Params,Rest2} = parse_ActualParameterList(Rest),
{{pv,Value,Params},Rest2}.
-parse_ParameterizedObjectClass(Tokens) ->
- {Type,Rest} = parse_DefinedObjectClass(Tokens),
- {Params,Rest2} = parse_ActualParameterList(Rest),
- {{poc,Type,Params},Rest2}.
-
parse_ParameterizedObjectSet(Tokens) ->
{ObjectSet,Rest} = parse_DefinedObjectSet(Tokens),
{Params,Rest2} = parse_ActualParameterList(Rest),
{{pos,ObjectSet,Params},Rest2}.
-parse_ParameterizedObject(Tokens) ->
- {Object,Rest} = parse_DefinedObject(Tokens),
- {Params,Rest2} = parse_ActualParameterList(Rest),
- {{po,Object,Params},Rest2}.
-
parse_ActualParameterList([{'{',_}|Rest]) ->
parse_ActualParameterList(Rest,[]);
parse_ActualParameterList(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+ parse_error(Tokens).
parse_ActualParameterList(Tokens,Acc) ->
{Parameter,Rest} = parse_ActualParameter(Tokens),
@@ -2260,43 +1667,22 @@ parse_ActualParameterList(Tokens,Acc) ->
[{',',_}|Rest2] ->
parse_ActualParameterList(Rest2,[Parameter|Acc]);
[{'}',_}|Rest3] ->
- {lists:reverse([Parameter|Acc]),Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,[',','}']]}})
-%%% Other ->
-%%% throw(Other)
+ {lists:reverse(Acc, [Parameter]),Rest3};
+ _ ->
+ parse_error(Rest)
end.
-
-
-
-
-
-
-%-------------------------
-
+%% Test whether Token is allowed in a syntax list.
is_word(Token) ->
- case not_allowed_word(Token) of
+ List = atom_to_list(Token),
+ case not_allowed_word(List) of
true -> false;
- _ ->
- if
- is_atom(Token) ->
- Item = atom_to_list(Token),
- is_word(Item);
- is_list(Token), length(Token) == 1 ->
- check_one_char_word(Token);
- is_list(Token) ->
- [A|Rest] = Token,
- case check_first(A) of
- true ->
- check_rest(Rest);
- _ ->
- false
- end
- end
+ false -> is_word_1(List)
end.
+is_word_1([H|T]) ->
+ check_first(H) andalso check_rest(T).
+
not_allowed_word(Name) ->
lists:member(Name,["BIT",
"BOOLEAN",
@@ -2321,257 +1707,123 @@ not_allowed_word(Name) ->
"TRUE",
"UNION"]).
-check_one_char_word([A]) when $A =< A, $Z >= A ->
- true;
-check_one_char_word([_]) ->
- false. %% unknown item in SyntaxList
+check_first(C) ->
+ $A =< C andalso C =< $Z.
-check_first(A) when $A =< A, $Z >= A ->
- true;
-check_first(_) ->
- false. %% unknown item in SyntaxList
-
-check_rest([R,R|_Rs]) when $- == R ->
- false; %% two consecutive hyphens are not allowed in a word
-check_rest([R]) when $- == R ->
- false; %% word cannot end with hyphen
-check_rest([R|Rs]) when $A=<R, $Z>=R; $-==R ->
+check_rest([R|Rs]) when $A =< R, R =< $Z; R =:= $- ->
check_rest(Rs);
check_rest([]) ->
true;
check_rest(_) ->
false.
+%%%
+%%% Parse alternative type lists for CHOICE.
+%%%
+
+parse_AlternativeTypeLists(Tokens0) ->
+ {Root,Tokens1} = parse_AlternativeTypeList(Tokens0),
+ case Tokens1 of
+ [{',',_}|Tokens2] ->
+ {ExtMarker,Tokens3} = parse_ExtensionAndException(Tokens2),
+ {ExtAlts,Tokens4} = parse_ExtensionAdditionAlternatives(Tokens3),
+ {_,Tokens} = parse_OptionalExtensionMarker(Tokens4, []),
+ {Root++ExtMarker++ExtAlts,Tokens};
+ Tokens ->
+ {Root,Tokens}
+ end.
+
+parse_ExtensionAndException([{'...',L}|Tokens0]) ->
+ {[#'EXTENSIONMARK'{pos=L}],
+ case Tokens0 of
+ [{'!',_}|Tokens1] ->
+ {_,Tokens} = parse_ExceptionIdentification(Tokens1),
+ Tokens;
+ _ ->
+ Tokens0
+ end}.
+
+parse_AlternativeTypeList([#identifier{}|_]=Tokens0) ->
+ {AltType,Tokens} = parse_NamedType(Tokens0),
+ parse_AlternativeTypeList_1(Tokens, [AltType]);
+parse_AlternativeTypeList(Tokens) ->
+ parse_error(Tokens).
+
+parse_AlternativeTypeList_1([{',',_}|[#identifier{}|_]=Tokens0], Acc) ->
+ {AltType,Tokens} = parse_NamedType(Tokens0),
+ parse_AlternativeTypeList_1(Tokens, [AltType|Acc]);
+parse_AlternativeTypeList_1(Tokens, Acc) ->
+ {lists:reverse(Acc),Tokens}.
-to_set(V) when is_list(V) ->
- ordsets:from_list(V);
-to_set(V) ->
- ordsets:from_list([V]).
-
-parse_AlternativeTypeLists(Tokens) ->
- parse_AlternativeTypeLists(Tokens,[]).
-
-parse_AlternativeTypeLists(Tokens = [{identifier,_,_}|_Rest0],Clist) ->
- {CompList,Rest1} = parse_AlternativeTypeList(Tokens,[]),
- parse_AlternativeTypeLists(Rest1,Clist++CompList);
-parse_AlternativeTypeLists([{'...',L1},{'!',_}|Rest02],Clist0) ->
- {_,Rest03} = parse_ExceptionIdentification(Rest02),
- %% Exception info is currently thrown away
- parse_AlternativeTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
-parse_AlternativeTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []->
- {_,Rest03} = parse_ExceptionIdentification(Rest02),
- %% Exception info is currently thrown away
- parse_AlternativeTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
-
-parse_AlternativeTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []->
- parse_AlternativeTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
-parse_AlternativeTypeLists([{'...',L1}|Rest02],Clist0) ->
- parse_AlternativeTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
-parse_AlternativeTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) ->
- {Clist0,Tokens}.
-
-parse_AlternativeTypeLists2(Tokens,Clist) ->
- {ExtAdd,Rest} = parse_ExtensionAdditionAlternatives(Tokens,Clist),
- {Clist2,Rest2} = parse_OptionalExtensionMarker(Rest,lists:flatten(ExtAdd)),
- case Rest2 of
- [{',',_}|Rest3] ->
- {CompList,Rest4} = parse_AlternativeTypeList(Rest3,[]),
- {Clist2 ++ CompList,Rest4};
- _ ->
- {Clist2,Rest2}
- end.
-
-
-
-parse_AlternativeTypeList([{',',_},Id = {identifier,_,_}|Rest],Acc) when Acc =/= [] ->
- {AlternativeType,Rest2} = parse_NamedType([Id|Rest]),
- parse_AlternativeTypeList(Rest2,[AlternativeType|Acc]);
-parse_AlternativeTypeList(Tokens = [{'}',_}|_],Acc) ->
- {lists:reverse(Acc),Tokens};
-parse_AlternativeTypeList(Tokens = [{']',_},{']',_}|_],Acc) ->
- {lists:reverse(Acc),Tokens};
-parse_AlternativeTypeList(Tokens = [{',',_},{'...',_}|_],Acc) ->
- {lists:reverse(Acc),Tokens};
-parse_AlternativeTypeList(Tokens,[]) ->
- {AlternativeType,Rest} = parse_NamedType(Tokens),
- parse_AlternativeTypeList(Rest,[AlternativeType]);
-parse_AlternativeTypeList(Tokens,_) ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
- expected,['}',', identifier']]}}).
-
-parse_ExtensionAdditionAlternatives(Tokens =[{',',_}|_],Clist) ->
- {ExtAddList,Rest2} = parse_ExtensionAdditionAlternativesList(Tokens,[]),
- {Clist++lists:flatten(ExtAddList),Rest2};
-parse_ExtensionAdditionAlternatives(Tokens,Clist) ->
- %% Empty
- {Clist,Tokens}.
+parse_ExtensionAdditionAlternatives([{',',_}|_]=Tokens0) ->
+ parse_ExtensionAdditionAlternativesList(Tokens0, []);
+parse_ExtensionAdditionAlternatives(Tokens) ->
+ {[],Tokens}.
-parse_ExtensionAdditionAlternativesList([{',',_},Id = {identifier,_,_}|Rest],Acc) ->
- {AlternativeType,Rest2} = parse_NamedType([Id|Rest]),
- parse_ExtensionAdditionAlternativesList(Rest2,[AlternativeType|Acc]);
-parse_ExtensionAdditionAlternativesList([{',',_},C1 = {'[',_},C2 = {'[',_}|Rest],Acc) ->
- {ExtAddGroup,Rest2} = parse_ExtensionAdditionAlternativesGroup([C1,C2|Rest],[]),
- parse_ExtensionAdditionAlternativesList(Rest2,[ExtAddGroup|Acc]);
-parse_ExtensionAdditionAlternativesList(Tokens = [{'}',_}|_],Acc) ->
- {lists:reverse(Acc),Tokens};
-parse_ExtensionAdditionAlternativesList(Tokens = [{',',_},{'...',_}|_],Acc) ->
- {lists:reverse(Acc),Tokens};
-parse_ExtensionAdditionAlternativesList(Tokens,_) ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
- expected,['}',', identifier']]}}).
-
-
-parse_ExtensionAdditionAlternativesGroup([ {'[',_},{'[',_},_VsnNr = {number,_,Num},{':',_}|Rest],[]) ->
- parse_ExtensionAdditionAlternativesGroup2(Rest,Num);
-parse_ExtensionAdditionAlternativesGroup([ {'[',_},{'[',_}|Rest],[]) ->
- parse_ExtensionAdditionAlternativesGroup2(Rest,undefined);
-parse_ExtensionAdditionAlternativesGroup(Tokens,_) ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
- expected,['[[']]}}).
-
-
-parse_ExtensionAdditionAlternativesGroup2(Tokens,Num) ->
- {CompTypeList,Rest} = parse_AlternativeTypeList(Tokens,[]),
- case Rest of
- [{']',_},{']',_}|Rest2] ->
- {[{'ExtensionAdditionGroup',Num}|CompTypeList] ++
- ['ExtensionAdditionGroupEnd'],Rest2};
+parse_ExtensionAdditionAlternativesList([{',',_}|Tokens1]=Tokens0, Acc) ->
+ try parse_ExtensionAdditionAlternative(Tokens1) of
+ {ExtAddAlt,Tokens2} ->
+ parse_ExtensionAdditionAlternativesList(Tokens2, [ExtAddAlt|Acc])
+ catch
+ throw:{asn1_error,_} ->
+ {lists:append(lists:reverse(Acc)),Tokens0}
+ end;
+parse_ExtensionAdditionAlternativesList(Tokens, Acc) ->
+ {lists:append(lists:reverse(Acc)),Tokens}.
+
+parse_ExtensionAdditionAlternative([#identifier{}|_]=Tokens0) ->
+ {NamedType,Tokens} = parse_NamedType(Tokens0),
+ {[NamedType],Tokens};
+parse_ExtensionAdditionAlternative([{'[',_},{'[',_}|Tokens0]) ->
+ Tokens2 = case Tokens0 of
+ [{number,_,_},{':',_}|Tokens1] -> Tokens1;
+ _ -> Tokens0
+ end,
+ {GroupList,Tokens3} = parse_AlternativeTypeList(Tokens2),
+ case Tokens3 of
+ [{']',_},{']',_}|Tokens] ->
+ {GroupList,Tokens};
_ ->
- throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
- [got,get_token(hd(Rest)),expected,[']]']]}})
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% parse_AlternativeTypeLists(Tokens,ExtensionDefault) ->
-%% {AltTypeList,Rest1} = parse_AlternativeTypeList(Tokens),
-%% {ExtensionAndException,Rest2} =
-%% case Rest1 of
-%% [{',',_},{'...',L1},{'!',_}|Rest12] ->
-%% {_,Rest13} = parse_ExceptionIdentification(Rest12),
-%% %% Exception info is currently thrown away
-%% {[#'EXTENSIONMARK'{pos=L1}],Rest13};
-%% [{',',_},{'...',L1}|Rest12] ->
-%% {[#'EXTENSIONMARK'{pos=L1}],Rest12};
-%% _ ->
-%% {[],Rest1}
-%% end,
-%% {AltTypeList2,Rest5} =
-%% case ExtensionAndException of
-%% [] ->
-%% {AltTypeList,Rest2};
-%% _ ->
-%% {ExtensionAddition,Rest3} =
-%% case Rest2 of
-%% [{',',_}|Rest23] ->
-%% parse_ExtensionAdditionAlternativeList(Rest23);
-%% _ ->
-%% {[],Rest2}
-%% end,
-%% {OptionalExtensionMarker,Rest4} =
-%% case Rest3 of
-%% [{',',_},{'...',L3}|Rest31] ->
-%% {[#'EXTENSIONMARK'{pos=L3}],Rest31};
-%% _ ->
-%% {[],Rest3}
-%% end,
-%% {AltTypeList ++ ExtensionAndException ++
-%% ExtensionAddition ++ OptionalExtensionMarker, Rest4}
-%% end,
-%% AltTypeList3 =
-%% case [X || X=#'EXTENSIONMARK'{} <- AltTypeList2] of
-%% [] when ExtensionDefault == 'IMPLIED' ->
-%% AltTypeList2 ++ [#'EXTENSIONMARK'{}];
-%% _ ->
-%% AltTypeList2
-%% end,
-%% {AltTypeList3,Rest5}.
-
-
-%% parse_AlternativeTypeList(Tokens) ->
-%% parse_AlternativeTypeList(Tokens,[]).
+ parse_error(Tokens3)
+ end;
+parse_ExtensionAdditionAlternative(Tokens) ->
+ parse_error(Tokens).
-%% parse_AlternativeTypeList(Tokens,Acc) ->
-%% {NamedType,Rest} = parse_NamedType(Tokens),
-%% case Rest of
-%% [{',',_},Id = {identifier,_,_}|Rest2] ->
-%% parse_AlternativeTypeList([Id|Rest2],[NamedType|Acc]);
-%% _ ->
-%% {lists:reverse([NamedType|Acc]),Rest}
-%% end.
+%%%
+%%% End of parsing of alternative type lists.
+%%%
-
-
-%% parse_ExtensionAdditionAlternativeList(Tokens) ->
-%% parse_ExtensionAdditionAlternativeList(Tokens,[]).
-
-%% parse_ExtensionAdditionAlternativeList([{'[[',_}|Rest],Acc) ->
-%% parse_ExtensionAdditionAlternativeList(Rest,Acc);
-%% parse_ExtensionAdditionAlternativeList(Tokens = [{identifier,_,_}|_Rest],Acc) ->
-%% {Element,Rest0} = parse_NamedType(Tokens);
-%% case Rest0 of
-%% [{',',_}|Rest01] ->
-%% parse_ExtensionAdditionAlternativeList(Rest01,[Element|Acc]);
-%% _ ->
-%% {lists:reverse([Element|Acc]),Rest0}
-%% end.
-
-%% parse_ExtensionAdditionAlternatives([{'[[',_}|Rest]) ->
-%% parse_ExtensionAdditionAlternatives(Rest,[]);
-%% parse_ExtensionAdditionAlternatives(Tokens) ->
-%% throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
-%% [got,get_token(hd(Tokens)),expected,'[[']}}).
-
-%% parse_ExtensionAdditionAlternatives([Id = {identifier,_,_}|Rest],Acc) ->
-%% {NamedType, Rest2} = parse_NamedType([Id|Rest]),
-%% case Rest2 of
-%% [{',',_}|Rest21] ->
-%% parse_ExtensionAdditionAlternatives(Rest21,[NamedType|Acc]);
-%% [{']]',_}|Rest21] ->
-%% {lists:reverse(Acc),Rest21};
-%% _ ->
-%% throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
-%% [got,get_token(hd(Rest2)),expected,[',',']]']]}})
-%% end.
-
-parse_NamedType([{identifier,L1,Idname}|Rest]) ->
+parse_NamedType([#identifier{pos=L1,val=Idname}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{#'ComponentType'{pos=L1,name=Idname,typespec=Type,prop=mandatory},Rest2};
parse_NamedType(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
+ parse_error(Tokens).
+%%%
+%%% Parse component type lists for SEQUENCE and SET.
+%%%
parse_ComponentTypeLists(Tokens) ->
- parse_ComponentTypeLists(Tokens,[]).
+ parse_ComponentTypeLists(Tokens, []).
-parse_ComponentTypeLists(Tokens = [{identifier,_,_}|_Rest0],Clist) ->
- {CompList,Rest1} = parse_ComponentTypeList(Tokens,[]),
- parse_ComponentTypeLists(Rest1,Clist++CompList);
-parse_ComponentTypeLists(Tokens = [{'COMPONENTS',_},{'OF',_}|_Rest],Clist) ->
+parse_ComponentTypeLists([#identifier{}|_Rest0]=Tokens, Clist) ->
{CompList,Rest1} = parse_ComponentTypeList(Tokens,[]),
parse_ComponentTypeLists(Rest1,Clist++CompList);
-parse_ComponentTypeLists([{'...',L1},{'!',_}|Rest02],Clist0) ->
- {_,Rest03} = parse_ExceptionIdentification(Rest02),
- %% Exception info is currently thrown away
- parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_ComponentTypeLists([{'COMPONENTS',_},{'OF',_}|_]=Tokens,Clist) ->
+ {CompList,Rest1} = parse_ComponentTypeList(Tokens, []),
+ parse_ComponentTypeLists(Rest1, Clist++CompList);
parse_ComponentTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []->
{_,Rest03} = parse_ExceptionIdentification(Rest02),
%% Exception info is currently thrown away
parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
-
- parse_ComponentTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []->
+parse_ComponentTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []->
parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
parse_ComponentTypeLists([{'...',L1}|Rest02],Clist0) ->
parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
parse_ComponentTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) ->
- {Clist0,Tokens}.
+ {Clist0,Tokens};
+parse_ComponentTypeLists(Tokens, _) ->
+ parse_error(Tokens).
parse_ComponentTypeLists2(Tokens,Clist) ->
{ExtAdd,Rest} = parse_ExtensionAdditions(Tokens,Clist),
@@ -2590,12 +1842,12 @@ parse_OptionalExtensionMarker(Tokens,Clist) ->
{Clist,Tokens}.
-parse_ComponentTypeList([{',',_},Id = {identifier,_,_}|Rest],Acc) when Acc =/= [] ->
- {ComponentType,Rest2} = parse_ComponentType([Id|Rest]),
- parse_ComponentTypeList(Rest2,[ComponentType|Acc]);
-parse_ComponentTypeList([{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest],Acc) when Acc =/= [] ->
- {ComponentType,Rest2} = parse_ComponentType([C1,C2|Rest]),
- parse_ComponentTypeList(Rest2,[ComponentType|Acc]);
+parse_ComponentTypeList([{',',_}|[#identifier{}|_]=Tokens0], Acc) when Acc =/= [] ->
+ {ComponentType,Tokens} = parse_ComponentType(Tokens0),
+ parse_ComponentTypeList(Tokens, [ComponentType|Acc]);
+parse_ComponentTypeList([{',',_}|[{'COMPONENTS',_},{'OF',_}|_]=Tokens0], Acc) when Acc =/= [] ->
+ {ComponentType,Tokens} = parse_ComponentType(Tokens0),
+ parse_ComponentTypeList(Tokens, [ComponentType|Acc]);
parse_ComponentTypeList(Tokens = [{'}',_}|_],Acc) ->
{lists:reverse(Acc),Tokens};
parse_ComponentTypeList(Tokens = [{']',_},{']',_}|_],Acc) ->
@@ -2606,10 +1858,7 @@ parse_ComponentTypeList(Tokens,[]) ->
{ComponentType,Rest} = parse_ComponentType(Tokens),
parse_ComponentTypeList(Rest,[ComponentType]);
parse_ComponentTypeList(Tokens,_) ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
- expected,['}',', identifier']]}}).
+ parse_error(Tokens).
parse_ExtensionAdditions(Tokens=[{',',_}|_],Clist) ->
{ExtAddList,Rest2} = parse_ExtensionAdditionList(Tokens,[]),
@@ -2618,46 +1867,36 @@ parse_ExtensionAdditions(Tokens,Clist) ->
%% Empty
{Clist,Tokens}.
-parse_ExtensionAdditionList([{',',_},Id = {identifier,_,_}|Rest],Acc) ->
- {ComponentType,Rest2} = parse_ComponentType([Id|Rest]),
- parse_ExtensionAdditionList(Rest2,[ComponentType|Acc]);
-parse_ExtensionAdditionList([{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest],Acc) ->
- {ComponentType,Rest2} = parse_ComponentType([C1,C2|Rest]),
- parse_ExtensionAdditionList(Rest2,[ComponentType|Acc]);
-parse_ExtensionAdditionList([{',',_},C1 = {'[',_},C2 = {'[',_}|Rest],Acc) ->
- {ExtAddGroup,Rest2} = parse_ExtensionAdditionGroup([C1,C2|Rest],[]),
+parse_ExtensionAdditionList([{',',_}|[#identifier{}|_]=Tokens0], Acc) ->
+ {ComponentType,Tokens} = parse_ComponentType(Tokens0),
+ parse_ExtensionAdditionList(Tokens, [ComponentType|Acc]);
+parse_ExtensionAdditionList([{',',_}|[{'COMPONENTS',_},{'OF',_}|_]=Tokens0], Acc) ->
+ {ComponentType,Tokens} = parse_ComponentType(Tokens0),
+ parse_ExtensionAdditionList(Tokens, [ComponentType|Acc]);
+parse_ExtensionAdditionList([{',',_},{'[',_},{'[',_}|Tokens], Acc) ->
+ {ExtAddGroup,Rest2} = parse_ExtensionAdditionGroup(Tokens),
parse_ExtensionAdditionList(Rest2,[ExtAddGroup|Acc]);
-parse_ExtensionAdditionList(Tokens = [{'}',_}|_],Acc) ->
+parse_ExtensionAdditionList([{'}',_}|_]=Tokens, Acc) ->
{lists:reverse(Acc),Tokens};
-parse_ExtensionAdditionList(Tokens = [{',',_},{'...',_}|_],Acc) ->
+parse_ExtensionAdditionList([{',',_},{'...',_}|_]=Tokens, Acc) ->
{lists:reverse(Acc),Tokens};
-parse_ExtensionAdditionList(Tokens,_) ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
- expected,['}',', identifier']]}}).
-
+parse_ExtensionAdditionList(Tokens, _) ->
+ parse_error(Tokens).
-parse_ExtensionAdditionGroup([ {'[',_},{'[',_},_VsnNr = {number,_,Num},{':',_}|Rest],[]) ->
- parse_ExtensionAdditionGroup2(Rest,Num);
-parse_ExtensionAdditionGroup([ {'[',_},{'[',_}|Rest],[]) ->
- parse_ExtensionAdditionGroup2(Rest,undefined);
-parse_ExtensionAdditionGroup(Tokens,_) ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
- expected,['[[']]}}).
+parse_ExtensionAdditionGroup([{number,_,Num},{':',_}|Tokens]) ->
+ parse_ExtensionAdditionGroup2(Tokens, Num);
+parse_ExtensionAdditionGroup(Tokens) ->
+ parse_ExtensionAdditionGroup2(Tokens, undefined).
-parse_ExtensionAdditionGroup2(Tokens,Num) ->
+parse_ExtensionAdditionGroup2(Tokens, Num) ->
{CompTypeList,Rest} = parse_ComponentTypeList(Tokens,[]),
case Rest of
[{']',_},{']',_}|Rest2] ->
{[{'ExtensionAdditionGroup',Num}|CompTypeList] ++
['ExtensionAdditionGroupEnd'],Rest2};
_ ->
- throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
- [got,get_token(hd(Rest)),expected,[']]']]}})
+ parse_error(Rest)
end.
@@ -2676,83 +1915,81 @@ parse_ComponentType(Tokens) ->
Result
end.
-
+%%%
+%%% Parse ENUMERATED.
+%%%
-parse_SignedNumber([{number,_,Value}|Rest]) ->
- {Value,Rest};
-parse_SignedNumber([{'-',_},{number,_,Value}|Rest]) ->
- {-Value,Rest};
-parse_SignedNumber(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [number,'-number']]}}).
-
-parse_Enumerations(Tokens=[{identifier,_,_}|_Rest],ExtensionDefault) ->
- parse_Enumerations(Tokens,[],ExtensionDefault);
-parse_Enumerations([H|_T],_) ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,identifier]}}).
-
-parse_Enumerations(Tokens = [{identifier,_,_},{'(',_}|_Rest], Acc, ExtensionDefault) ->
- {NamedNumber,Rest2} = parse_NamedNumber(Tokens),
- case Rest2 of
- [{',',_}|Rest3] ->
- parse_Enumerations(Rest3,[NamedNumber|Acc], ExtensionDefault);
- _ when ExtensionDefault == 'IMPLIED'->
- {lists:reverse(['EXTENSIONMARK',NamedNumber|Acc]),Rest2};
+parse_Enumerations(Tokens0) ->
+ {Root,Tokens1} = parse_Enumeration(Tokens0),
+ case Tokens1 of
+ [{',',_},{'...',_},{',',_}|Tokens2] ->
+ {Ext,Tokens} = parse_Enumeration(Tokens2),
+ {Root++['EXTENSIONMARK'|Ext],Tokens};
+ [{',',_},{'...',_}|Tokens] ->
+ {Root++['EXTENSIONMARK'],Tokens};
_ ->
- {lists:reverse([NamedNumber|Acc]),Rest2}
- end;
-parse_Enumerations([{identifier,_,Id}|Rest], Acc, ExtensionDefault) ->
- case Rest of
- [{',',_}|Rest2] ->
- parse_Enumerations(Rest2,[Id|Acc], ExtensionDefault);
- _ when ExtensionDefault == 'IMPLIED' ->
- {lists:reverse(['EXTENSIONMARK', Id |Acc]),Rest};
- _ ->
- {lists:reverse([Id|Acc]),Rest}
- end;
-parse_Enumerations([{'...',_}|Rest], Acc, _ExtensionDefault) ->
- case Rest of
- [{',',_}|Rest2] ->
- parse_Enumerations(Rest2,['EXTENSIONMARK'|Acc],undefined);
- _ ->
- {lists:reverse(['EXTENSIONMARK'|Acc]),Rest}
+ case get(extensiondefault) of
+ 'IMPLIED' ->
+ {Root++['EXTENSIONMARK'],Tokens1};
+ _ ->
+ {Root,Tokens1}
+ end
+ end.
+
+parse_Enumeration(Tokens0) ->
+ {Item,Tokens} = parse_EnumerationItem(Tokens0),
+ parse_Enumeration_1(Tokens, [Item]).
+
+parse_Enumeration_1([{',',_}|Tokens1]=Tokens0, Acc) ->
+ try parse_EnumerationItem(Tokens1) of
+ {Item,Tokens} ->
+ parse_Enumeration_1(Tokens, [Item|Acc])
+ catch
+ throw:{asn1_error,_} ->
+ {lists:reverse(Acc),Tokens0}
end;
-parse_Enumerations([H|_T],_,_) ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,identifier]}}).
+parse_Enumeration_1(Tokens, Acc) ->
+ {lists:reverse(Acc),Tokens}.
+
+parse_EnumerationItem([#identifier{},{'(',_}|_]=Tokens) ->
+ parse_NamedNumber(Tokens);
+parse_EnumerationItem([#identifier{val=Id}|Tokens]) ->
+ {Id,Tokens};
+parse_EnumerationItem(Tokens) ->
+ parse_error(Tokens).
+
+%%%
+%%% End of parsing of ENUMERATED.
+%%%
parse_NamedNumberList(Tokens) ->
- parse_NamedNumberList(Tokens,[]).
+ parse_NamedNumberList(Tokens, []).
-parse_NamedNumberList(Tokens,Acc) ->
+parse_NamedNumberList(Tokens, Acc) ->
{NamedNum,Rest} = parse_NamedNumber(Tokens),
case Rest of
[{',',_}|Rest2] ->
parse_NamedNumberList(Rest2,[NamedNum|Acc]);
_ ->
- {lists:reverse([NamedNum|Acc]),Rest}
+ {lists:reverse(Acc, [NamedNum]),Rest}
end.
-parse_NamedNumber([{identifier,_,Name},{'(',_}|Rest]) ->
+parse_NamedNumber([#identifier{val=Name},{'(',_}|Rest]) ->
Flist = [fun parse_SignedNumber/1,
fun parse_DefinedValue/1],
- case (catch parse_or(Rest,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
+ case parse_or(Rest, Flist) of
{NamedNum,[{')',_}|Rest2]} ->
{{'NamedNumber',Name,NamedNum},Rest2};
_ ->
- throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
- [got,get_token(hd(Rest)),expected,'NamedNumberList']}})
+ parse_error(Rest)
end;
parse_NamedNumber(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
+ parse_error(Tokens).
+parse_SignedNumber([{number,_,Value}|Rest]) ->
+ {Value,Rest};
+parse_SignedNumber(Tokens) ->
+ parse_error(Tokens).
parse_Tag([{'[',_}|Rest]) ->
{Class,Rest2} = parse_Class(Rest),
@@ -2767,12 +2004,8 @@ parse_Tag([{'[',_}|Rest]) ->
[{']',_}|Rest4] ->
{#tag{class=Class,number=ClassNumber},Rest4};
_ ->
- throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
- [got,get_token(hd(Rest3)),expected,']']}})
- end;
-parse_Tag(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'[']}}).
+ parse_error(Rest3)
+ end.
parse_Class([{'UNIVERSAL',_}|Rest]) ->
{'UNIVERSAL',Rest};
@@ -2791,15 +2024,7 @@ parse_Value(Tokens) ->
Flist = [fun parse_BuiltinValue/1,
fun parse_ValueFromObject/1,
fun parse_DefinedValue/1],
-
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end.
+ parse_or(Tokens, Flist).
parse_BuiltinValue([{bstring,_,Bstr}|Rest]) ->
{{bstring,Bstr},Rest};
@@ -2812,18 +2037,11 @@ parse_BuiltinValue(Tokens = [{'{',_}|_Rest]) ->
fun parse_SequenceOfValue/1,
fun parse_SequenceValue/1,
fun parse_ObjectIdentifierValue/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- Result ->
- Result
- end;
-parse_BuiltinValue([{identifier,_,IdName},{':',_}|Rest]) ->
+ parse_or(Tokens, Flist);
+parse_BuiltinValue([#identifier{val=IdName},{':',_}|Rest]) ->
{Value,Rest2} = parse_Value(Rest),
{{'CHOICE',{IdName,Value}},Rest2};
-parse_BuiltinValue(Tokens=[{'NULL',_},{':',_}|_Rest]) ->
+parse_BuiltinValue([{'NULL',_},{':',_}|_]=Tokens) ->
parse_ObjectClassFieldValue(Tokens);
parse_BuiltinValue([{'NULL',_}|Rest]) ->
{'NULL',Rest};
@@ -2839,31 +2057,29 @@ parse_BuiltinValue([{cstring,_,Cstr}|Rest]) ->
{Cstr,Rest};
parse_BuiltinValue([{number,_,Num}|Rest]) ->
{Num,Rest};
-parse_BuiltinValue([{'-',_},{number,_,Num}|Rest]) ->
- {- Num,Rest};
parse_BuiltinValue(Tokens) ->
parse_ObjectClassFieldValue(Tokens).
-parse_DefinedValue(Tokens=[{identifier,_,_},{'{',_}|_Rest]) ->
- parse_ParameterizedValue(Tokens);
-%% Externalvaluereference
-parse_DefinedValue([{typereference,L1,Tname},{'.',_},{identifier,_,Idname}|Rest]) ->
+parse_DefinedValue(Tokens) ->
+ Flist = [fun parse_ParameterizedValue/1,
+ fun parse_DefinedValue2/1],
+ parse_or(Tokens, Flist).
+
+parse_DefinedValue2([{typereference,L1,Tname},
+ {'.',_},
+ #identifier{val=Idname}|Rest]) ->
{#'Externalvaluereference'{pos=L1,module=Tname,value=Idname},Rest};
%% valuereference
-parse_DefinedValue([Id = {identifier,_,_}|Rest]) ->
+parse_DefinedValue2([#identifier{}=Id|Rest]) ->
{identifier2Extvalueref(Id),Rest};
-%% ParameterizedValue
-parse_DefinedValue(Tokens) ->
- parse_ParameterizedValue(Tokens).
+parse_DefinedValue2(Tokens) ->
+ parse_error(Tokens).
parse_SequenceValue([{'{',_}|Tokens]) ->
- parse_SequenceValue(Tokens,[]);
-parse_SequenceValue(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+ parse_SequenceValue(Tokens, []).
-parse_SequenceValue([{identifier,Pos,IdName}|Rest],Acc) ->
+parse_SequenceValue([#identifier{pos=Pos,val=IdName}|Rest],Acc) ->
{Value,Rest2} = parse_Value(Rest),
SeqTag = #seqtag{pos=Pos,module=get(asn1_module),val=IdName},
case Rest2 of
@@ -2872,18 +2088,13 @@ parse_SequenceValue([{identifier,Pos,IdName}|Rest],Acc) ->
[{'}',_}|Rest3] ->
{lists:reverse(Acc, [{SeqTag,Value}]),Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ parse_error(Rest2)
end;
parse_SequenceValue(Tokens,_Acc) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
+ parse_error(Tokens).
parse_SequenceOfValue([{'{',_}|Tokens]) ->
- parse_SequenceOfValue(Tokens,[]);
-parse_SequenceOfValue(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+ parse_SequenceOfValue(Tokens, []).
parse_SequenceOfValue(Tokens,Acc) ->
{Value,Rest2} = parse_Value(Tokens),
@@ -2891,10 +2102,9 @@ parse_SequenceOfValue(Tokens,Acc) ->
[{',',_}|Rest3] ->
parse_SequenceOfValue(Rest3,[Value|Acc]);
[{'}',_}|Rest3] ->
- {lists:reverse([Value|Acc]),Rest3};
+ {lists:reverse(Acc, [Value]),Rest3};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'}']}})
+ parse_error(Rest2)
end.
parse_ValueSetTypeAssignment([{typereference,L1,Name}|Rest]) ->
@@ -2904,49 +2114,31 @@ parse_ValueSetTypeAssignment([{typereference,L1,Name}|Rest]) ->
{ValueSet,Rest4} = parse_ValueSet(Rest3),
{#valuedef{pos=L1,name=Name,type=Type,value=ValueSet,
module=get(asn1_module)},Rest4};
- [H|_T] ->
- throw({asn1_error,{get_line(L1),get(asn1_module),
- [got,get_token(H),expected,'::=']}})
- end;
-parse_ValueSetTypeAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- typereference]}}).
+ _ ->
+ parse_error(Rest2)
+ end.
parse_ValueSet([{'{',_}|Rest]) ->
{Elems,Rest2} = parse_ElementSetSpecs(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
{{valueset,Elems},Rest3};
- [H|_T] ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,'}']}})
+ _ ->
+ parse_error(Rest2)
end;
parse_ValueSet(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'{']}}).
+ parse_error(Tokens).
-parse_ValueAssignment([{identifier,L1,IdName}|Rest]) ->
+parse_ValueAssignment([#identifier{pos=L1,val=IdName}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
case Rest2 of
[{'::=',_}|Rest3] ->
{Value,Rest4} = parse_Value(Rest3),
- case catch lookahead_assignment(Rest4) of
- ok ->
- {#valuedef{pos=L1,name=IdName,type=Type,value=Value,
- module=get(asn1_module)},Rest4};
- Error ->
- throw(Error)
-%% throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
-%% [got,get_token(hd(Rest2)),expected,'::=']}})
- end;
+ {#valuedef{pos=L1,name=IdName,type=Type,value=Value,
+ module=get(asn1_module)},Rest4};
_ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'::=']}})
- end;
-parse_ValueAssignment(Tokens) ->
- throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
+ parse_error(Rest2)
+ end.
%% SizeConstraint
parse_SubtypeElements([{'SIZE',_}|Tokens]) ->
@@ -2966,8 +2158,7 @@ parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_},{'...',_},{',',_}|Tok
[{'}',_}|Rest2] ->
{{'WITH COMPONENTS',{'PartialSpecification',Constraint}},Rest2};
_ ->
- throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
- [got,get_token(hd(Rest)),expected,'}']}})
+ parse_error(Rest)
end;
parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_}|Tokens]) ->
{Constraint,Rest} = parse_TypeConstraints(Tokens),
@@ -2975,28 +2166,18 @@ parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_}|Tokens]) ->
[{'}',_}|Rest2] ->
{{'WITH COMPONENTS',{'FullSpecification',Constraint}},Rest2};
_ ->
- throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
- [got,get_token(hd(Rest)),expected,'}']}})
+ parse_error(Rest)
end;
parse_SubtypeElements([{'PATTERN',_}|Tokens]) ->
{Value,Rest} = parse_Value(Tokens),
{{pattern,Value},Rest};
-%% SingleValue
-%% ContainedSubtype
-%% ValueRange
-%% TypeConstraint
-%% Moved fun parse_Value/1 and fun parse_Type/1 to parse_Elements
parse_SubtypeElements(Tokens) ->
Flist = [fun parse_ContainedSubtype/1,
fun parse_Value/1,
- fun([{'MIN',_}|T]) -> {'MIN',T} end,
+ fun parse_MIN/1,
fun parse_Type/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- {asn1_error,Reason} ->
- throw(Reason);
- Result = {Val,_} when is_record(Val,type) ->
+ case parse_or(Tokens, Flist) of
+ {#type{},_}=Result ->
Result;
{Lower,[{'..',_}|Rest]} ->
{Upper,Rest2} = parse_UpperEndpoint(Rest),
@@ -3014,10 +2195,7 @@ parse_ContainedSubtype([{'INCLUDES',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{{'ContainedSubtype',Type},Rest2};
parse_ContainedSubtype(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'INCLUDES']}}).
-%%parse_ContainedSubtype(Tokens) -> %this option is moved to parse_SubtypeElements
-%% parse_Type(Tokens).
+ parse_error(Tokens).
parse_UpperEndpoint([{'<',_}|Rest]) ->
parse_UpperEndpoint(lt,Rest);
@@ -3025,33 +2203,38 @@ parse_UpperEndpoint(Tokens) ->
parse_UpperEndpoint(false,Tokens).
parse_UpperEndpoint(Lt,Tokens) ->
- Flist = [ fun([{'MAX',_}|T]) -> {'MAX',T} end,
- fun parse_Value/1],
- case (catch parse_or(Tokens,Flist)) of
- {'EXIT',Reason} ->
- exit(Reason);
- AsnErr = {asn1_error,_} ->
- throw(AsnErr);
- {Value,Rest2} when Lt == lt ->
+ Flist = [fun parse_MAX/1,
+ fun parse_Value/1],
+ case parse_or(Tokens, Flist) of
+ {Value,Rest2} when Lt =:= lt ->
{{lt,Value},Rest2};
{Value,Rest2} ->
{Value,Rest2}
end.
+parse_MIN([{'MIN',_}|T]) ->
+ {'MIN',T};
+parse_MIN(Tokens) ->
+ parse_error(Tokens).
+
+parse_MAX([{'MAX',_}|T]) ->
+ {'MAX',T};
+parse_MAX(Tokens) ->
+ parse_error(Tokens).
+
parse_TypeConstraints(Tokens) ->
- parse_TypeConstraints(Tokens,[]).
+ parse_TypeConstraints(Tokens, []).
-parse_TypeConstraints([{identifier,_,_}|Rest],Acc) ->
+parse_TypeConstraints([#identifier{}|Rest], Acc) ->
{ComponentConstraint,Rest2} = parse_ComponentConstraint(Rest),
case Rest2 of
[{',',_}|Rest3] ->
- parse_TypeConstraints(Rest3,[ComponentConstraint|Acc]);
+ parse_TypeConstraints(Rest3, [ComponentConstraint|Acc]);
_ ->
- {lists:reverse([ComponentConstraint|Acc]),Rest2}
+ {lists:reverse(Acc, [ComponentConstraint]),Rest2}
end;
-parse_TypeConstraints([H|_T],_) ->
- throw({asn1_error,{get_line(H),get(asn1_module),
- [got,get_token(H),expected,identifier]}}).
+parse_TypeConstraints(Tokens, _) ->
+ parse_error(Tokens).
parse_ComponentConstraint(Tokens = [{'(',_}|_Rest]) ->
{ValueConstraint,Rest2} = parse_Constraint(Tokens),
@@ -3071,145 +2254,36 @@ parse_PresenceConstraint(Tokens) ->
{asn1_empty,Tokens}.
-% merge_constraints({Rlist,ExtList}) -> % extensionmarker in constraint
-% {merge_constraints(Rlist,[],[]),
-% merge_constraints(ExtList,[],[])};
-
-%% An arg with a constraint with extension marker will look like
-%% [#constraint{c={Root,Ext}}|Rest]
-
merge_constraints(Clist) ->
merge_constraints(Clist, [], []).
-merge_constraints([Ch|Ct],Cacc, Eacc) ->
- NewEacc = case Ch#constraint.e of
- undefined -> Eacc;
- E -> [E|Eacc]
- end,
- merge_constraints(Ct,[fixup_constraint(Ch#constraint.c)|Cacc],NewEacc);
-
-merge_constraints([],Cacc,[]) ->
-%% lists:flatten(Cacc);
+merge_constraints([#constraint{c=C,e=E}|T], Cacc0, Eacc0) ->
+ Eacc = case E of
+ undefined -> Eacc0;
+ E -> [E|Eacc0]
+ end,
+ Cacc = [C|Cacc0],
+ merge_constraints(T, Cacc, Eacc);
+merge_constraints([], Cacc, []) ->
lists:reverse(Cacc);
-merge_constraints([],Cacc,Eacc) ->
-%% lists:flatten(Cacc) ++ [{'Errors',Eacc}].
- lists:reverse(Cacc) ++ [{'Errors',Eacc}].
-
-
-fixup_constraint(C) ->
- case C of
- {'SingleValue',SubType} when element(1,SubType) == 'ContainedSubtype' ->
- SubType;
- {'SingleValue',V} when is_list(V) ->
- C;
- %% [C,{'ValueRange',{lists:min(V),lists:max(V)}}];
- %% bug, turns wrong when an element in V is a reference to a defined value
- {'PermittedAlphabet',{'SingleValue',V}} when is_list(V) ->
- %%sort and remove duplicates
- V2 = {'SingleValue',
- ordsets:from_list(lists:flatten(V))},
- {'PermittedAlphabet',V2};
- {'PermittedAlphabet',{'SingleValue',V}} ->
- V2 = {'SingleValue',[V]},
- {'PermittedAlphabet',V2};
- {'SizeConstraint',Sc} ->
- {'SizeConstraint',fixup_size_constraint(Sc)};
-
- List when is_list(List) -> %% In This case maybe a union or intersection
- [fixup_constraint(Xc)||Xc <- List];
- Other ->
- Other
- end.
+merge_constraints([], Cacc, Eacc) ->
+ lists:reverse(Cacc) ++ [{element_set,{'Errors',Eacc},none}].
-fixup_size_constraint({'ValueRange',{Lb,Ub}}) ->
- {Lb,Ub};
-fixup_size_constraint({{'ValueRange',R},[]}) ->
- {R,[]};
-fixup_size_constraint({[],{'ValueRange',R}}) ->
- {[],R};
-fixup_size_constraint({{'ValueRange',R1},{'ValueRange',R2}}) ->
- {R1,R2};
-fixup_size_constraint({'SingleValue',[Sv]}) ->
- fixup_size_constraint({'SingleValue',Sv});
-fixup_size_constraint({'SingleValue',L}) when is_list(L) ->
- ordsets:from_list(L);
-fixup_size_constraint({'SingleValue',L}) ->
- {L,L};
-fixup_size_constraint({'SizeConstraint',C}) ->
- %% this is a second SIZE
- fixup_size_constraint(C);
-fixup_size_constraint({C1,C2}) ->
- %% this is with extension marks
- {turn2vr(fixup_size_constraint(C1)), extension_size(fixup_size_constraint(C2))};
-fixup_size_constraint(CList) when is_list(CList) ->
- [fixup_constraint(Xc)||Xc <- CList].
-
-turn2vr(L) when is_list(L) ->
- L2 =[X||X<-ordsets:from_list(L),is_integer(X)],
- case L2 of
- [H|_] ->
- {H,hd(lists:reverse(L2))};
- _ ->
- L
- end;
-turn2vr(VR) ->
- VR.
-extension_size({I,I}) ->
- [I];
-extension_size({I1,I2}) ->
- [I1,I2];
-extension_size(C) ->
- C.
-
-get_line({_,Pos,Token}) when is_integer(Pos),is_atom(Token) ->
+get_line({Token,Pos,_}) when is_integer(Pos), is_atom(Token) ->
Pos;
get_line({Token,Pos}) when is_integer(Pos),is_atom(Token) ->
- Pos;
-get_line(_) ->
- undefined.
-
-get_token({_,Pos,Token}) when is_integer(Pos),is_atom(Token) ->
- Token;
+ Pos.
+
+get_token({valuefieldreference,_,FieldName}) ->
+ list_to_atom([$&|atom_to_list(FieldName)]);
+get_token({typefieldreference,_,FieldName}) ->
+ list_to_atom([$&|atom_to_list(FieldName)]);
+get_token({Token,Pos,Value}) when is_integer(Pos), is_atom(Token) ->
+ Value;
get_token({'$end',Pos}) when is_integer(Pos) ->
- undefined;
+ 'END-OF-FILE';
get_token({Token,Pos}) when is_integer(Pos),is_atom(Token) ->
- Token;
-get_token(_) ->
- undefined.
-
-prioritize_error(ErrList) ->
- case lists:keymember(asn1_error,1,ErrList) of
- false -> % only asn1_assignment_error -> take the last
- lists:last(ErrList);
- true -> % contains errors from deeper in a Type
- NewErrList = [_Err={_,_}|_RestErr] =
- lists:filter(fun({asn1_error,_})->true;(_)->false end,
- ErrList),
- SplitErrs =
- lists:splitwith(fun({_,X})->
- case element(1,X) of
- Int when is_integer(Int) -> true;
- _ -> false
- end
- end,
- NewErrList),
- case SplitErrs of
- {[],UndefPosErrs} -> % if no error with Positon exists
- lists:last(UndefPosErrs);
- {IntPosErrs,_} ->
- IntPosReasons = lists:map(fun(X)->element(2,X) end,IntPosErrs),
- SortedReasons = lists:keysort(1,IntPosReasons),
- {asn1_error,lists:last(SortedReasons)}
- end
- end.
-
-%% most_prio_error([H={_,Reason}|T],Atom,Err) when is_atom(Atom) ->
-%% most_prio_error(T,element(1,Reason),H);
-%% most_prio_error([H={_,Reason}|T],Greatest,Err) ->
-%% case element(1,Reason) of
-%% Pos when is_integer(Pos),Pos>Greatest ->
-%% most_prio_error(
-
+ Token.
tref2Exttref(#typereference{pos=Pos,val=Name}) ->
#'Externaltypereference'{pos=Pos,
@@ -3226,19 +2300,5 @@ identifier2Extvalueref(#identifier{pos=Pos,val=Name}) ->
module=resolve_module(Name),
value=Name}.
-%% lookahead_assignment/1 checks that the next sequence of tokens
-%% in Token contain a valid assignment or the
-%% 'END' token. Otherwise an exception is thrown.
-lookahead_assignment([{'END',_}|_Rest]) ->
- ok;
-lookahead_assignment(Tokens) ->
- parse_Assignment(Tokens),
- ok.
-
-is_pre_defined_class('TYPE-IDENTIFIER') ->
- true;
-is_pre_defined_class('ABSTRACT-SYNTAX') ->
- true;
-is_pre_defined_class(_) ->
- false.
-
+parse_error(Tokens) ->
+ throw({asn1_error,{parse_error,Tokens}}).
diff --git a/lib/asn1/src/asn1ct_pretty_format.erl b/lib/asn1/src/asn1ct_pretty_format.erl
index a01c1db8c5..7e28543a05 100644
--- a/lib/asn1/src/asn1ct_pretty_format.erl
+++ b/lib/asn1/src/asn1ct_pretty_format.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/src/asn1ct_table.erl b/lib/asn1/src/asn1ct_table.erl
index 2eca80eda3..b1eaf2b332 100644
--- a/lib/asn1/src/asn1ct_table.erl
+++ b/lib/asn1/src/asn1ct_table.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1ct_tok.erl b/lib/asn1/src/asn1ct_tok.erl
index 8687ed955c..5aeb8c171e 100644
--- a/lib/asn1/src/asn1ct_tok.erl
+++ b/lib/asn1/src/asn1ct_tok.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,191 +22,177 @@
%% Tokenize ASN.1 code (input to parser generated with yecc)
--export([get_name/2,tokenise/4, file/1]).
-
+-export([file/1,format_error/1]).
-file(File) ->
- case file:open(File, [read]) of
+file(File0) ->
+ case file:open(File0, [read]) of
{error, Reason} ->
- {error,{File,file:format_error(Reason)}};
+ {error,{File0,file:format_error(Reason)}};
{ok,Stream} ->
- process(Stream,0,[])
+ try
+ process(Stream, 1, [])
+ catch
+ throw:{error,Line,Reason} ->
+ File = filename:basename(File0),
+ Error = {structured_error,{File,Line},?MODULE,Reason},
+ {error,[Error]}
+ end
end.
-process(Stream,Lno,R) ->
- process(io:get_line(Stream, ''), Stream,Lno+1,R).
+process(Stream, Lno, R) ->
+ process(io:get_line(Stream, ''), Stream, Lno, R).
-process(eof, Stream,Lno,R) ->
+process(eof, Stream, Lno, Acc) ->
ok = file:close(Stream),
- lists:flatten(lists:reverse([{'$end',Lno}|R]));
-
-
-process(L, Stream,Lno,R) when is_list(L) ->
- %%io:format('read:~s',[L]),
- case catch tokenise(Stream,L,Lno,[]) of
- {'ERR',Reason} ->
- io:format("Tokeniser error on line: ~w ~w~n",[Lno,Reason]),
- exit(0);
- {NewLno,T} ->
- %%io:format('toks:~w~n',[T]),
- process(Stream,NewLno,[T|R])
- end.
-
-tokenise(Stream,[H|T],Lno,R) when $a =< H , H =< $z ->
- {X, T1} = get_name(T, [H]),
- tokenise(Stream,T1,Lno,[{identifier,Lno, list_to_atom(X)}|R]);
-
-tokenise(Stream,[$&,H|T],Lno,R) when $A =< H , H =< $Z ->
- {Y, T1} = get_name(T, [H]),
- X = list_to_atom(Y),
- tokenise(Stream,T1,Lno,[{typefieldreference, Lno, X} | R]);
-
-tokenise(Stream,[$&,H|T],Lno,R) when $a =< H , H =< $z ->
- {Y, T1} = get_name(T, [H]),
- X = list_to_atom(Y),
- tokenise(Stream,T1,Lno,[{valuefieldreference, Lno, X} | R]);
-
-tokenise(Stream,[H|T],Lno,R) when $A =< H , H =< $Z ->
- {Y, T1} = get_name(T, [H]),
- X = list_to_atom(Y),
- case reserved_word(X) of
- true ->
- tokenise(Stream,T1,Lno,[{X,Lno}|R]);
- false ->
- tokenise(Stream,T1,Lno,[{typereference,Lno,X}|R]);
- rstrtype ->
- tokenise(Stream,T1,Lno,[{restrictedcharacterstringtype,Lno,X}|R])
- end;
-
-tokenise(Stream,[$-,H|T],Lno,R) when $0 =< H , H =< $9 ->
- {X, T1} = get_number(T, [H]),
- tokenise(Stream,T1,Lno,[{number,Lno,-1 * list_to_integer(X)}|R]);
+ lists:reverse([{'$end',Lno}|Acc]);
+process(L, Stream, Lno0, Acc) when is_list(L) ->
+ try tokenise(Stream, L, Lno0, []) of
+ {Lno,[]} ->
+ process(Stream, Lno, Acc);
+ {Lno,Ts} ->
+ process(Stream, Lno, Ts++Acc)
+ catch
+ throw:{error,Reason} ->
+ throw({error,Lno0,Reason})
+ end.
-tokenise(Stream,[H|T],Lno,R) when $0 =< H , H =< $9 ->
+format_error(eof_in_comment) ->
+ "premature end of file in multi-line comment";
+format_error(eol_in_token) ->
+ "end of line in token";
+format_error({invalid_binary_number,Str}) ->
+ io_lib:format("invalid binary number: '~s'", [Str]);
+format_error({invalid_hex_number,Str}) ->
+ io_lib:format("invalid hex number: '~s'", [Str]);
+format_error(Other) ->
+ io_lib:format("~p", [Other]).
+
+tokenise(Stream, [$&,H|T], Lno, R) when $A =< H , H =< $Z ->
+ {X,T1} = get_name(T, [H]),
+ tokenise(Stream, T1, Lno, [{typefieldreference,Lno,X}|R]);
+tokenise(Stream, [$&,H|T], Lno, R) when $a =< H , H =< $z ->
+ {X,T1} = get_name(T, [H]),
+ tokenise(Stream, T1, Lno, [{valuefieldreference,Lno,X}|R]);
+
+tokenise(Stream, "--"++T, Lno, R) ->
+ tokenise(Stream, skip_comment(T), Lno, R);
+
+tokenise(Stream, [$-,H|T], Lno, R) when $0 =< H , H =< $9 ->
{X, T1} = get_number(T, [H]),
- tokenise(Stream,T1,Lno,[{number,Lno,list_to_integer(X)}|R]);
-
-tokenise(Stream,[$-,$-|T],Lno,R) ->
- tokenise(Stream,skip_comment(T),Lno,R);
+ tokenise(Stream, T1, Lno, [{number,Lno,-list_to_integer(X)}|R]);
-tokenise(Stream,[$/,$*|T],Lno,R) ->
- {NewLno,T1} = skip_multiline_comment(Stream,T,Lno,0),
- tokenise(Stream,T1,NewLno,R);
+tokenise(Stream, "/*"++T, Lno0, R) ->
+ {Lno,T1} = skip_multiline_comment(Stream, T, Lno0, 0),
+ tokenise(Stream, T1, Lno, R);
-tokenise(Stream,[$:,$:,$=|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'::=',Lno}|R]);
-
-tokenise(Stream,[$'|T],Lno,R) ->
- case catch collect_quoted(T,Lno,[]) of
- {'ERR',_} ->
- throw({'ERR','bad_quote'});
- {Thing, T1} ->
- tokenise(Stream,T1,Lno,[Thing|R])
- end;
+tokenise(Stream, "::="++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'::=',Lno}|R]);
+tokenise(Stream, ":"++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{':',Lno}|R]);
+tokenise(Stream, "'"++T0, Lno, R) ->
+ {Thing, T1} = collect_quoted(T0, Lno, []),
+ tokenise(Stream, T1, Lno, [Thing|R]);
tokenise(Stream,[$"|T],Lno,R) ->
{Str,T1} = collect_string(T,Lno),
tokenise(Stream,T1,Lno,[Str|R]);
-tokenise(Stream,[${|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'{',Lno}|R]);
-
-tokenise(Stream,[$}|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'}',Lno}|R]);
-
-%% tokenise(Stream,[$],$]|T],Lno,R) ->
-%% tokenise(Stream,T,Lno,[{']]',Lno}|R]);
+tokenise(Stream, "{"++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'{',Lno}|R]);
+tokenise(Stream, "}"++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'}',Lno}|R]);
%% Even though x.680 specify '[[' and ']]' as lexical items
-%% it does not work to have them as such since the single [ and ] can
-%% be used beside each other in the SYNTAX OF in x.681
-%% the solution chosen here , i.e. to have them as separate lexical items
+%% it does not work to have them as such since the single '[' and ']' can
+%% be used beside each other in 'WITH SYNTAX' in x.681.
+%% The solution chosen here, i.e. to have them as separate lexical items
%% will not detect the cases where there is white space between them
-%% which would be an error in the use in ExtensionAdditionGroups
-
-%% tokenise(Stream,[$[,$[|T],Lno,R) ->
-%% tokenise(Stream,T,Lno,[{'[[',Lno}|R]);
-
-tokenise(Stream,[$]|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{']',Lno}|R]);
-
-tokenise(Stream,[$[|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'[',Lno}|R]);
+%% which would be an error in the use in ExtensionAdditionGroups.
-tokenise(Stream,[$,|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{',',Lno}|R]);
+tokenise(Stream, "]"++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{']',Lno}|R]);
+tokenise(Stream, "["++T,Lno,R) ->
+ tokenise(Stream, T, Lno, [{'[',Lno}|R]);
-tokenise(Stream,[$(|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'(',Lno}|R]);
-tokenise(Stream,[$)|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{')',Lno}|R]);
+tokenise(Stream, ","++T,Lno,R) ->
+ tokenise(Stream, T, Lno, [{',',Lno}|R]);
-tokenise(Stream,[$.,$.,$.|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'...',Lno}|R]);
+tokenise(Stream, "("++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'(',Lno}|R]);
+tokenise(Stream, ")"++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{')',Lno}|R]);
-tokenise(Stream,[$.,$.|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'..',Lno}|R]);
+tokenise(Stream, "..."++T,Lno,R) ->
+ tokenise(Stream, T, Lno, [{'...',Lno}|R]);
+tokenise(Stream, ".."++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'..',Lno}|R]);
+tokenise(Stream, "."++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'.',Lno}|R]);
-tokenise(Stream,[$.|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'.',Lno}|R]);
-tokenise(Stream,[$^|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'^',Lno}|R]);
-tokenise(Stream,[$!|T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'!',Lno}|R]);
-tokenise(Stream,[$||T],Lno,R) ->
- tokenise(Stream,T,Lno,[{'|',Lno}|R]);
+tokenise(Stream, "|"++T, Lno, R) ->
+ tokenise(Stream, T, Lno, [{'|',Lno}|R]);
-tokenise(Stream,[H|T],Lno,R) ->
- case white_space(H) of
+tokenise(Stream, [H|T], Lno, R) when $A =< H , H =< $Z ->
+ {X,T1} = get_name(T, [H]),
+ case reserved_word(X) of
true ->
- tokenise(Stream,T,Lno,R);
+ tokenise(Stream, T1, Lno, [{X,Lno}|R]);
false ->
- tokenise(Stream,T,Lno,[{list_to_atom([H]),Lno}|R])
+ tokenise(Stream, T1, Lno, [{typereference,Lno,X}|R]);
+ rstrtype ->
+ tokenise(Stream, T1, Lno, [{restrictedcharacterstringtype,Lno,X}|R])
end;
-tokenise(_Stream,[],Lno,R) ->
- {Lno,lists:reverse(R)}.
+tokenise(Stream, [H|T], Lno, R) when $a =< H , H =< $z ->
+ {X, T1} = get_name(T, [H]),
+ tokenise(Stream, T1, Lno, [{identifier,Lno,X}|R]);
-collect_string(L,Lno) ->
- collect_string(L,Lno,[]).
+tokenise(Stream, [H|T], Lno, R) when $0 =< H , H =< $9 ->
+ {X, T1} = get_number(T, [H]),
+ tokenise(Stream, T1, Lno, [{number,Lno,list_to_integer(X)}|R]);
-collect_string([],_,_) ->
- throw({'ERR','bad_quote found eof'});
+tokenise(Stream, [H|T], Lno, R) when H =< $\s ->
+ tokenise(Stream, T, Lno, R);
-collect_string([H|T],Lno,Str) ->
- case H of
- $" ->
- {{cstring,1,lists:reverse(Str)},T};
- Ch ->
- collect_string(T,Lno,[Ch|Str])
- end.
-
+tokenise(Stream, [H|T], Lno, R) ->
+ tokenise(Stream, T, Lno, [{list_to_atom([H]),Lno}|R]);
+tokenise(_Stream, [], Lno, R) ->
+ {Lno+1,R}.
-% <name> is letters digits hyphens
-% hypen is not the last character. Hypen hyphen is NOT allowed
-%
-% <identifier> ::= <lowercase> <name>
+collect_string(L, Lno) ->
+ collect_string(L, Lno, []).
-get_name([$-,Char|T], L) ->
+collect_string([$"|T], _Lno, Str) ->
+ {{cstring,1,lists:reverse(Str)},T};
+collect_string([H|T], Lno, Str) ->
+ collect_string(T, Lno, [H|Str]);
+collect_string([], _, _) ->
+ throw({error,missing_quote_at_eof}).
+
+%% <name> is letters digits hyphens.
+%% Hypen is not the last character. Hypen hyphen is NOT allowed.
+%%
+%% <identifier> ::= <lowercase> <name>
+
+get_name([$-,Char|T]=T0, Acc) ->
case isalnum(Char) of
true ->
- get_name(T,[Char,$-|L]);
+ get_name(T, [Char,$-|Acc]);
false ->
- {lists:reverse(L),[$-,Char|T]}
+ {list_to_atom(lists:reverse(Acc)),T0}
end;
-get_name([$-|T], L) ->
- {lists:reverse(L),[$-|T]};
-get_name([Char|T], L) ->
+get_name([$-|_]=T, Acc) ->
+ {list_to_atom(lists:reverse(Acc)),T};
+get_name([Char|T]=T0, Acc) ->
case isalnum(Char) of
true ->
- get_name(T,[Char|L]);
+ get_name(T, [Char|Acc]);
false ->
- {lists:reverse(L),[Char|T]}
+ {list_to_atom(lists:reverse(Acc)),T0}
end;
-get_name([], L) ->
- {lists:reverse(L), []}.
-
+get_name([], Acc) ->
+ {list_to_atom(lists:reverse(Acc)),[]}.
isalnum(H) when $A =< H , H =< $Z ->
true;
@@ -221,67 +208,54 @@ isdigit(H) when $0 =< H , H =< $9 ->
isdigit(_) ->
false.
-white_space(9) -> true;
-white_space(10) -> true;
-white_space(13) -> true;
-white_space(32) -> true;
-white_space(_) -> false.
-
-
-get_number([H|T], L) ->
+get_number([H|T]=T0, L) ->
case isdigit(H) of
true ->
get_number(T, [H|L]);
false ->
- {lists:reverse(L), [H|T]}
+ {lists:reverse(L), T0}
end;
get_number([], L) ->
{lists:reverse(L), []}.
-skip_comment([]) ->
- [];
-skip_comment([$-,$-|T]) ->
- T;
-skip_comment([_|T]) ->
- skip_comment(T).
-
+skip_comment([]) -> [];
+skip_comment("--"++T) -> T;
+skip_comment([_|T]) -> skip_comment(T).
-skip_multiline_comment(Stream,[],Lno,Level) ->
- case io:get_line(Stream,'') of
+skip_multiline_comment(Stream, [], Lno, Level) ->
+ case io:get_line(Stream, '') of
eof ->
- io:format("Tokeniser error on line: ~w~n"
- "premature end of multiline comment~n",[Lno]),
- exit(0);
+ throw({error,eof_in_comment});
Line ->
- skip_multiline_comment(Stream,Line,Lno+1,Level)
+ skip_multiline_comment(Stream, Line, Lno+1, Level)
end;
-skip_multiline_comment(_Stream,[$*,$/|T],Lno,0) ->
+skip_multiline_comment(_Stream, "*/"++T, Lno, 0) ->
{Lno,T};
-skip_multiline_comment(Stream,[$*,$/|T],Lno,Level) ->
- skip_multiline_comment(Stream,T,Lno,Level - 1);
-skip_multiline_comment(Stream,[$/,$*|T],Lno,Level) ->
- skip_multiline_comment(Stream,T,Lno,Level + 1);
-skip_multiline_comment(Stream,[_|T],Lno,Level) ->
- skip_multiline_comment(Stream,T,Lno,Level).
-
-collect_quoted([$',$B|T],Lno, L) ->
+skip_multiline_comment(Stream, "*/"++T, Lno, Level) ->
+ skip_multiline_comment(Stream, T, Lno, Level - 1);
+skip_multiline_comment(Stream, "/*"++T, Lno, Level) ->
+ skip_multiline_comment(Stream, T, Lno, Level + 1);
+skip_multiline_comment(Stream, [_|T], Lno, Level) ->
+ skip_multiline_comment(Stream, T, Lno, Level).
+
+collect_quoted("'B"++T, Lno, L) ->
case check_bin(L) of
true ->
- {{bstring,Lno, lists:reverse(L)}, T};
+ {{bstring,Lno,lists:reverse(L)}, T};
false ->
- throw({'ERR',{invalid_binary_number, lists:reverse(L)}})
+ throw({error,{invalid_binary_number,lists:reverse(L)}})
end;
-collect_quoted([$',$H|T],Lno, L) ->
+collect_quoted("'H"++T, Lno, L) ->
case check_hex(L) of
true ->
- {{hstring,Lno, lists:reverse(L)}, T};
+ {{hstring,Lno,lists:reverse(L)}, T};
false ->
- throw({'ERR',{invalid_binary_number, lists:reverse(L)}})
+ throw({error,{invalid_hex_number,lists:reverse(L)}})
end;
collect_quoted([H|T], Lno, L) ->
collect_quoted(T, Lno,[H|L]);
collect_quoted([], _, _) -> % This should be allowed FIX later
- throw({'ERR',{eol_in_token}}).
+ throw({error,eol_in_token}).
check_bin([$0|T]) ->
check_bin(T);
@@ -351,7 +325,6 @@ reserved_word('INCLUDES') -> true;
reserved_word('INSTANCE') -> true;
reserved_word('INTEGER') -> true;
reserved_word('INTERSECTION') -> true;
-reserved_word('ISO646String') -> rstrtype;
reserved_word('MAX') -> true;
reserved_word('MIN') -> true;
reserved_word('MINUS-INFINITY') -> true;
diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl
index 221cd991a7..7f20d57b1e 100644
--- a/lib/asn1/src/asn1ct_value.erl
+++ b/lib/asn1/src/asn1ct_value.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -352,8 +353,9 @@ random_unnamed_bit_string(M, C) ->
%% end.
random(Upper) ->
- {A1,A2,A3} = erlang:now(),
- _ = random:seed(A1, A2, A3),
+ _ = random:seed(erlang:phash2([erlang:node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
random:uniform(Upper).
size_random(C) ->
diff --git a/lib/asn1/src/asn1rt.erl b/lib/asn1/src/asn1rt.erl
index ad8b879c38..2c38c27dd8 100644
--- a/lib/asn1/src/asn1rt.erl
+++ b/lib/asn1/src/asn1rt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/src/asn1rt_nif.erl b/lib/asn1/src/asn1rt_nif.erl
index 1a44f1a27c..6ee182ed23 100644
--- a/lib/asn1/src/asn1rt_nif.erl
+++ b/lib/asn1/src/asn1rt_nif.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl
index c4cd872368..e50b14941c 100644
--- a/lib/asn1/src/asn1rtt_ber.erl
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -738,6 +739,8 @@ encode_named_bit_string([H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
do_encode_named_bit_string(Bits, NamedBitList, TagIn);
encode_named_bit_string([{bit,_}|_]=Bits, NamedBitList, TagIn) ->
do_encode_named_bit_string(Bits, NamedBitList, TagIn);
+encode_named_bit_string([], _NamedBitList, TagIn) ->
+ encode_unnamed_bit_string(<<>>, TagIn);
encode_named_bit_string(Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
encode_unnamed_bit_string(Bits, TagIn).
@@ -745,6 +748,8 @@ encode_named_bit_string(C, [H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
do_encode_named_bit_string(C, Bits, NamedBitList, TagIn);
encode_named_bit_string(C, [{bit,_}|_]=Bits, NamedBitList, TagIn) ->
do_encode_named_bit_string(C, Bits, NamedBitList, TagIn);
+encode_named_bit_string(C, [], _NamedBitList, TagIn) ->
+ encode_unnamed_bit_string(C, <<>>, TagIn);
encode_named_bit_string(C, Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
encode_unnamed_bit_string(C, Bits, TagIn).
diff --git a/lib/asn1/src/asn1rtt_check.erl b/lib/asn1/src/asn1rtt_check.erl
index 0083867a10..4839fa98dc 100644
--- a/lib/asn1/src/asn1rtt_check.erl
+++ b/lib/asn1/src/asn1rtt_check.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1rtt_ext.erl b/lib/asn1/src/asn1rtt_ext.erl
index f3eee1cdd5..fa55ae4d85 100644
--- a/lib/asn1/src/asn1rtt_ext.erl
+++ b/lib/asn1/src/asn1rtt_ext.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1rtt_per.erl b/lib/asn1/src/asn1rtt_per.erl
index 672c84593c..a3803659b6 100644
--- a/lib/asn1/src/asn1rtt_per.erl
+++ b/lib/asn1/src/asn1rtt_per.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl
index 0290c75a28..e85dc94f4c 100644
--- a/lib/asn1/src/asn1rtt_per_common.erl
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1rtt_real_common.erl b/lib/asn1/src/asn1rtt_real_common.erl
index 12ca165ecd..7b155e5c91 100644
--- a/lib/asn1/src/asn1rtt_real_common.erl
+++ b/lib/asn1/src/asn1rtt_real_common.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/asn1rtt_uper.erl b/lib/asn1/src/asn1rtt_uper.erl
index 68a89c70e1..7a52324252 100644
--- a/lib/asn1/src/asn1rtt_uper.erl
+++ b/lib/asn1/src/asn1rtt_uper.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/src/notes_history.sgml b/lib/asn1/src/notes_history.sgml
index 107459b37d..9dccb5ff57 100644
--- a/lib/asn1/src/notes_history.sgml
+++ b/lib/asn1/src/notes_history.sgml
@@ -1,15 +1,16 @@
<!doctype chapter PUBLIC "-//Stork//DTD chapter//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/asn1/src/notes_latest.sgml b/lib/asn1/src/notes_latest.sgml
index 5a397ecbc2..641c41b843 100644
--- a/lib/asn1/src/notes_latest.sgml
+++ b/lib/asn1/src/notes_latest.sgml
@@ -1,15 +1,16 @@
<!doctype chapter PUBLIC "-//Stork//DTD chapter//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/asn1/src/prepare_templates.erl b/lib/asn1/src/prepare_templates.erl
index ccd15548d8..3e24366cdf 100644
--- a/lib/asn1/src/prepare_templates.erl
+++ b/lib/asn1/src/prepare_templates.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/External.hrl b/lib/asn1/test/External.hrl
index 14a3a059e6..dd4fa6de3a 100644
--- a/lib/asn1/test/External.hrl
+++ b/lib/asn1/test/External.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index b1b08aa9f9..9a34fa6271 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -78,6 +79,7 @@ MODULES= \
testEnumExt \
testInfObjectClass \
testInfObj \
+ testInfObjExtract \
testParameterizedInfObj \
testFragmented \
testMergeCompile \
@@ -104,14 +106,19 @@ MODULES= \
test_compile_options \
testDoubleEllipses \
test_modified_x420 \
- testX420 \
test_x691 \
testWSParamClass \
+ testValueTest \
+ testUniqueObjectSets \
+ testRfcs \
+ testImporting \
+ testExtensibilityImplied \
asn1_test_lib \
asn1_app_test \
asn1_appup_test \
asn1_SUITE \
- error_SUITE
+ error_SUITE \
+ syntax_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index 432197eec0..6dea1787a8 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -52,9 +53,7 @@ all() ->
groups() ->
Parallel = asn1_test_lib:parallel(),
[{compile, Parallel,
- [c_syntax,
- c_string,
- c_implicit_before_choice,
+ [c_string,
constraint_equivalence]},
{ber, Parallel,
@@ -89,6 +88,7 @@ groups() ->
ber_other,
der,
h323test]},
+ testExtensibilityImplied,
testChoPrim,
testChoExtension,
testChoOptional,
@@ -135,19 +135,19 @@ groups() ->
testChoiceIndefinite,
per_open_type,
testInfObjectClass,
+ testUniqueObjectSets,
+ testInfObjExtract,
testParam,
testFragmented,
testMergeCompile,
testobj,
testDeepTConstr,
- testExport,
testImport,
testDER,
testDEFAULT,
testMvrasn6,
testContextSwitchingTypes,
testOpenTypeImplicitTag,
- duplicate_tags,
testROSE,
testINSTANCE_OF,
testTCAP,
@@ -158,16 +158,19 @@ groups() ->
testNortel,
% Uses 'PKCS7', 'InformationFramework'
{group, [], [test_WS_ParamClass,
- test_modified_x420,
- testX420]},
- testTcapsystem,
- testNBAPsystem,
- testS1AP,
+ test_modified_x420]},
+ %% Don't run all these at the same time.
+ {group, [],
+ [testTcapsystem,
+ testNBAPsystem,
+ testS1AP,
+ testRfcs]},
test_compile_options,
testDoubleEllipses,
test_x691,
ticket_6143,
- test_OTP_9688]},
+ test_OTP_9688,
+ testValueTest]},
{performance, [],
[testTimer_ber,
@@ -196,7 +199,7 @@ init_per_testcase(Func, Config) ->
true = code:add_patha(CaseDir),
Dog = case Func of
- testX420 -> ct:timetrap({minutes, 90});
+ testRfcs -> ct:timetrap({minutes, 90});
_ -> ct:timetrap({minutes, 60})
end,
[{case_dir, CaseDir}, {watchdog, Dog}|Config].
@@ -374,6 +377,12 @@ testExternal(Config, Rule, Opts) ->
testSetOfTag:main(Rule),
testSetTag:main(Rule).
+testExtensibilityImplied(Config) ->
+ test(Config, fun testExtensibilityImplied/3).
+testExtensibilityImplied(Config, Rule, Opts) ->
+ asn1_test_lib:compile("ExtensibilityImplied", Config,
+ [Rule,no_ok_wrapper|Opts]),
+ testExtensibilityImplied:main().
testChoPrim(Config) -> test(Config, fun testChoPrim/3).
testChoPrim(Config, Rule, Opts) ->
@@ -561,39 +570,21 @@ testSetOfCho(Config, Rule, Opts) ->
asn1_test_lib:compile("SetOfCho", Config, [Rule|Opts]),
testSetOfCho:main(Rule).
-c_syntax(Config) ->
- DataDir = ?config(data_dir, Config),
- [{error, _} = asn1ct:compile(filename:join(DataDir, F))
- || F <-["Syntax",
- "BadTypeEnding",
- "BadValueAssignment1",
- "BadValueAssignment2",
- "BadValueSet",
- "ChoiceBadExtension",
- "EnumerationBadExtension",
- "Example",
- "Export1",
- "MissingEnd",
- "SequenceBadComma",
- "SequenceBadComponentName",
- "SequenceBadComponentType",
- "SeqBadComma"]].
-
c_string(Config) ->
test(Config, fun c_string/3).
c_string(Config, Rule, Opts) ->
asn1_test_lib:compile("String", Config, [Rule|Opts]),
asn1ct:test('String').
-c_implicit_before_choice(Config) ->
- test(Config, fun c_implicit_before_choice/3, [ber]).
-c_implicit_before_choice(Config, Rule, Opts) ->
- DataDir = ?config(data_dir, Config),
- CaseDir = ?config(case_dir, Config),
- {error, _R2} = asn1ct:compile(filename:join(DataDir, "CCSNARG3"),
- [Rule, {outdir, CaseDir}|Opts]).
-
constraint_equivalence(Config) ->
+ constraint_equivalence_abs(Config),
+ test(Config, fun constraint_equivalence/3).
+
+constraint_equivalence(Config, Rule, Opts) ->
+ M = 'ConstraintEquivalence',
+ asn1_test_lib:compile(M, Config, [Rule|Opts]).
+
+constraint_equivalence_abs(Config) ->
DataDir = ?config(data_dir, Config),
CaseDir = ?config(case_dir, Config),
Asn1Spec = "ConstraintEquivalence",
@@ -637,12 +628,22 @@ ber_other(Config, Rule, Opts) ->
der(Config) ->
asn1_test_lib:compile_all(ber_modules(), Config, [der]).
-module_test(M, Config, Rule, Opts) ->
- asn1_test_lib:compile(M, Config, [Rule|Opts]),
- case asn1ct:test(list_to_atom(M), [{i, ?config(case_dir, Config)}]) of
- ok -> ok;
- Error ->
- erlang:error({test_failed, M, Opts, Error})
+module_test(M0, Config, Rule, Opts) ->
+ asn1_test_lib:compile(M0, Config, [Rule|Opts]),
+ case list_to_atom(M0) of
+ 'LDAP' ->
+ %% Because of the recursive definition of 'Filter' in
+ %% the LDAP module, the construction of a sample
+ %% value for 'Filter' is not guaranteed to terminate.
+ ok;
+ M ->
+ TestOpts = [{i, ?config(case_dir, Config)}],
+ case asn1ct:test(M, TestOpts) of
+ ok ->
+ ok;
+ Error ->
+ erlang:error({test_failed, M, Opts, Error})
+ end
end.
@@ -765,6 +766,16 @@ testInfObjectClass(Config, Rule, Opts) ->
testInfObjectClass:main(Rule),
testInfObj:main(Rule).
+testUniqueObjectSets(Config) -> test(Config, fun testUniqueObjectSets/3).
+testUniqueObjectSets(Config, Rule, Opts) ->
+ CaseDir = ?config(case_dir, Config),
+ testUniqueObjectSets:main(CaseDir, Rule, Opts).
+
+testInfObjExtract(Config) -> test(Config, fun testInfObjExtract/3).
+testInfObjExtract(Config, Rule, Opts) ->
+ asn1_test_lib:compile("InfObjExtract", Config, [Rule|Opts]),
+ testInfObjExtract:main().
+
testParam(Config) ->
test(Config, fun testParam/3, [ber,{ber,[der]},per,uper]).
testParam(Config, Rule, Opts) ->
@@ -804,18 +815,14 @@ testDeepTConstr(Config, Rule, Opts) ->
[Rule|Opts]),
testDeepTConstr:main(Rule).
-testExport(Config) ->
- {error, _} =
- asn1ct:compile(filename:join(?config(data_dir, Config),
- "IllegalExport"),
- [{outdir, ?config(case_dir, Config)}]).
-
testImport(Config) ->
test(Config, fun testImport/3).
testImport(Config, Rule, Opts) ->
- Files = ["ImportsFrom","ImportsFrom2","ImportsFrom3"],
+ Files = ["ImportsFrom","ImportsFrom2","ImportsFrom3",
+ "Importing","Exporting"],
asn1_test_lib:compile_all(Files, Config, [Rule|Opts]),
42 = 'ImportsFrom':i(),
+ testImporting:main(),
ok.
testMegaco(Config) -> test(Config, fun testMegaco/3).
@@ -839,24 +846,20 @@ testContextSwitchingTypes(Config, Rule, Opts) ->
testTypeValueNotation(Config) -> test(Config, fun testTypeValueNotation/3).
testTypeValueNotation(Config, Rule, Opts) ->
- asn1_test_lib:compile_all(["SeqTypeRefPrim", "ValueTest"], Config,
- [Rule|Opts]),
+ asn1_test_lib:compile("SeqTypeRefPrim", Config, [Rule|Opts]),
testTypeValueNotation:main(Rule, Opts).
+testValueTest(Config) -> test(Config, fun testValueTest/3).
+testValueTest(Config, Rule, Opts) ->
+ asn1_test_lib:compile("ValueTest", Config, [Rule|Opts]),
+ testValueTest:main().
+
testOpenTypeImplicitTag(Config) ->
test(Config, fun testOpenTypeImplicitTag/3).
testOpenTypeImplicitTag(Config, Rule, Opts) ->
asn1_test_lib:compile("OpenTypeImplicitTag", Config, [Rule|Opts]),
testOpenTypeImplicitTag:main(Rule).
-duplicate_tags(Config) ->
- DataDir = ?config(data_dir, Config),
- CaseDir = ?config(case_dir, Config),
- {error, [{error, {type, _, _, 'SeqOpt1Imp',
- {asn1, {duplicates_of_the_tags, _}}}}]} =
- asn1ct:compile(filename:join(DataDir, "SeqOptional2"),
- [abs, {outdir, CaseDir}]).
-
rtUI(Config) -> test(Config, fun rtUI/3).
rtUI(Config, Rule, Opts) ->
asn1_test_lib:compile("Prim", Config, [Rule|Opts]),
@@ -990,13 +993,22 @@ testS1AP(Config, Rule, Opts) ->
ok
end.
+testRfcs(Config) -> test(Config, fun testRfcs/3, [{ber,[der]}]).
+testRfcs(Config, Rule, Opts) ->
+ case erlang:system_info(system_architecture) of
+ "sparc-sun-solaris2.10" ->
+ {skip,"Too slow for an old Sparc"};
+ _ ->
+ testRfcs:compile(Config, Rule, Opts),
+ testRfcs:test()
+ end.
+
test_compile_options(Config) ->
ok = test_compile_options:wrong_path(Config),
ok = test_compile_options:path(Config),
ok = test_compile_options:noobj(Config),
ok = test_compile_options:record_name_prefix(Config),
- ok = test_compile_options:verbose(Config),
- ok = test_compile_options:warnings_as_errors(Config).
+ ok = test_compile_options:verbose(Config).
testDoubleEllipses(Config) -> test(Config, fun testDoubleEllipses/3).
testDoubleEllipses(Config, Rule, Opts) ->
@@ -1084,6 +1096,7 @@ test_modules() ->
"CommonDataTypes",
"Constraints",
"ContextSwitchingTypes",
+ "CoverParser",
"DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
"Enum",
"From",
@@ -1118,7 +1131,9 @@ test_modules() ->
"Def",
"Opt",
"ELDAPv3",
- "LDAP"].
+ "LDAP",
+ "SeqOptional2",
+ "CCSNARG3"].
test_OTP_9688(Config) ->
PrivDir = ?config(case_dir, Config),
diff --git a/lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn b/lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn
deleted file mode 100644
index 3ccd838ac0..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn
+++ /dev/null
@@ -1,6 +0,0 @@
-BadTypeEnding DEFINITIONS ::=
-BEGIN
-
-T ::= Typ;
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn1 b/lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn1
deleted file mode 100644
index a5d4984e60..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn1
+++ /dev/null
@@ -1,8 +0,0 @@
-BadValueAssignment1 DEFINITIONS ::=
-BEGIN
-
-int INTEGER ::= 3
-
-int2 integer ::= 3
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn1 b/lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn1
deleted file mode 100644
index 7a96406001..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn1
+++ /dev/null
@@ -1,8 +0,0 @@
-BadValueAssignment2 DEFINITIONS ::=
-BEGIN
-
-int INTEGER ::= 3
-
-int2 ::= 3
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadValueSet.asn1 b/lib/asn1/test/asn1_SUITE_data/BadValueSet.asn1
deleted file mode 100644
index 68bd4380b7..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/BadValueSet.asn1
+++ /dev/null
@@ -1,9 +0,0 @@
-BadValueSet DEFINITIONS ::=
-BEGIN
-
-Int INTEGER ::= {1|2|3}
-
-Int2 INTEGER ::= {
- 1,2,3}
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn b/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn
index 23c1f32ceb..8932238adc 100644
--- a/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn
+++ b/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn
@@ -3,7 +3,7 @@ BEGIN
CallCentreServiceNotificationArg ::= SEQUENCE {
scriptInformation [0] ScriptToScriptInformation,
- eventInformation [1] IMPLICIT EventInformation OPTIONAL
+ eventInformation [1] EventInformation OPTIONAL
}
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
index f6fe18be10..18473bae30 100644
--- a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
@@ -41,10 +41,4 @@ ChoExt4 ::= CHOICE
str OCTET STRING
}
-ChoEmptyRoot ::= CHOICE {
- ...,
- bool BOOLEAN,
- int INTEGER (0..7)
-}
-
END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn1
deleted file mode 100644
index d0789d7414..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn1
+++ /dev/null
@@ -1,27 +0,0 @@
-ChoiceBadExtension DEFINITIONS ::=
-BEGIN
-
-Seq ::= SEQUENCE {
- ...,
- name PrintableString,
- location INTEGER {home(0),field(1),roving(2)},
- age INTEGER
- }
-
-Cho1 ::= CHOICE {
- name PrintableString,
- ...,
- location INTEGER {home(0),field(1),roving(2)},
- age INTEGER
- }
-
-Cho2 ::= CHOICE {
- ...,
- name PrintableString,
- location INTEGER {home(0),field(1),roving(2)},
- age INTEGER
- }
-
-END
-
-
diff --git a/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1 b/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
index 8b3d151502..648275dd66 100644
--- a/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
@@ -11,6 +11,10 @@ BEGIN
SingleValueX8 ::= INTEGER (integer42)
SingleValueX9 ::= INTEGER (integer42..integer42)
SingleValueX10 ::= INTEGER ((integer42) INTERSECTION (40..49))
+ SingleValueX11 ::= INTEGER (40..49) (integer42)
+ SingleValueX12 ::= INTEGER ((MIN..0) ^ (1..10) | integer42)
+ SingleValueX13 ::= INTEGER ((11..20) ^ (1..10) | integer42)
+ SingleValueX14 ::= INTEGER ((MIN..42) ^ (1..100) ^ (42..50))
UnconstrainedX0 ::= INTEGER
UnconstrainedX1 ::= INTEGER (MIN..MAX)
@@ -19,6 +23,10 @@ BEGIN
UnconstrainedX4 ::= INTEGER ((MIN..MAX)|9|10)
UnconstrainedX5 ::= INTEGER ((MIN..MAX)|10..20)
UnconstrainedX6 ::= INTEGER ((MIN..MAX) UNION (10..20))
+ UnconstrainedX7 ::= INTEGER ((MIN..MAX) ^ ((MIN..MAX) UNION (10..20)))
+ UnconstrainedX8 ::= INTEGER ((-100..MAX) ^ (42..MAX) | (MIN..41))
+ UnconstrainedX9 ::= INTEGER (UnconstrainedX0)
+ UnconstrainedX10 ::= INTEGER (UnconstrainedX0)(MIN..MAX)
RangeX00 ::= INTEGER (5..10)
RangeX01 ::= INTEGER (4<..<11)
@@ -38,22 +46,66 @@ BEGIN
RangeX16 ::= INTEGER ((5|6) UNION (7) UNION (7<..<11))
RangeX20 ::= INTEGER (0..20) (5..10)
- RangeX21 ::= INTEGER (0..10) (5..20)
- RangeX22 ::= INTEGER (0..10) (5..20) (MIN..MAX)
- RangeX23 ::= INTEGER ((0..10) INTERSECTION (5..20) ^ (MIN..MAX))
- RangeX24 ::= INTEGER ((5|6|7|8|9|10) INTERSECTION (5..20) ^ (MIN..MAX))
+ RangeX21 ::= INTEGER ((0..10) ^ (5..20))
+ RangeX22 ::= INTEGER ((0..10) ^ (5..20) ^ (MIN..MAX))
+ RangeX23 ::= INTEGER (MIN..MAX) (-100..20) (5..10)
+ RangeX24 ::= INTEGER (MIN..MAX) (0..100) (5..20) (5..10)
+ RangeX25 ::= INTEGER ((0..10) INTERSECTION (5..20) ^ (MIN..MAX))
+ RangeX26 ::= INTEGER ((5|6|7|8|9|10) INTERSECTION (5..20) ^ (MIN..MAX))
+
+ RangeX30 ::= INTEGER (((5|6) | (5..20)) ^ (0..10))
+ RangeX31 ::= INTEGER (((((5|6) | (5..20)) ^ (0..10))) ^ (MIN..MAX))
+ RangeX32 ::= INTEGER ((5|7) | (5..10))
+
+ Semi00 ::= INTEGER (0..MAX)
+ Semi01 ::= INTEGER (0..MAX) (MIN..MAX)
+ Semi02 ::= INTEGER ((0..100) UNION (200..MAX) UNION (50..1024))
+
+ RangeExtX00 ::= INTEGER (5..10, ...)
+ RangeExtX01 ::= INTEGER (0..20) (5..10, ...)
+ RangeExtX02 ::= INTEGER (RangeX26) (5..10, ...)
+-- RangeExtX03 ::= RangeX26 (5..10, ...)
+
+ MinRangeX00 ::= INTEGER (MIN..10)
+ MinRangeX01 ::= INTEGER ((MIN..0) | (0..10))
+ MinRangeX02 ::= INTEGER (MIN..MAX) (MIN..100) (MIN..10)
+ MinRangeX03 ::= INTEGER (((MIN..-100)|(-60..-50)) | (MIN..10))
+
+ DisjointRangeX00 ::= INTEGER (0..5 UNION 95..99)
+ DisjointRangeX01 ::= INTEGER (0|1|2|3|4|5|95|96|97|98|99)
+ DisjointRangeX02 ::= INTEGER (0..100) (0..2 UNION 95..99 UNION 3|4|5)
+ DisjointRangeX03 ::= INTEGER (MIN..MAX) (0..2 UNION 95..99 UNION 3|4|5)
+
+ MinDisjointRangeX00 ::= INTEGER (MIN..-100 UNION 100..1000)
+ MinDisjointRangeX01 ::= INTEGER (MIN..-100 UNION 100..1000 UNION (MIN..-100))
+ MinDisjointRangeX02 ::= INTEGER (MIN..-50000 UNION 100..1000 UNION (MIN..-100))
+ MinDisjointRangeX03 ::= INTEGER (MIN..-100 UNION 100..1000 UNION (MIN..-1000000))
+ MinDisjointRangeX04 ::= INTEGER (MIN..-100 UNION 100..1000 UNION (MIN..-1000000))
+ MinDisjointRangeX05 ::= INTEGER (MIN..-100 ^ (MIN..-100) UNION 100..1000)
+ MinDisjointRangeX06 ::= INTEGER (MIN..-100 ^ (MIN..0) UNION 100..1000)
UnconstrainedStringX00 ::= IA5String
UnconstrainedStringX01 ::= IA5String (SIZE (0..MAX))
+ UnconstrainedStringX02 ::= IA5String (SIZE (0..42|43..MAX))
ConstrainedStringX00 ::= IA5String (SIZE (0..5))
ConstrainedStringX01 ::= IA5String (SIZE (0|1|2|3|4|5))
+ StringExtFromX00 ::= IA5String (FROM ("AB", ..., "CD"))(SIZE (1..10, ..., 15..20))
+ StringExtFromX01 ::= IA5String (FROM ("AB", ..., "CD"))(SIZE (1..10, ..., 15..20))
+ StringExtFromX02 ::= IA5String ((FROM ("AB", ..., "CD")) ^ ((SIZE (1..10, ..., 15..20))))
+ StringExtFromX03 ::= IA5String ((FROM ("AB", ..., "CD")) ^ (SIZE (1..10, ..., 15..20)))
+ StringExtFromX04 ::= IA5String (StringExtFromX00)
+
-- Note: None of the back-ends care about the exact values
-- outside of the root range.
ExtConstrainedStringX00 ::= IA5String (SIZE (1..2, ...))
ExtConstrainedStringX01 ::= IA5String (SIZE (1|2, ..., 3))
ExtConstrainedStringX02 ::= IA5String (SIZE (1|2, ..., 3|4|5))
+ ExtConstrainedStringX03 ::= IA5String (SIZE (1|2, ..., 1|2|3|4|5))
+ ExtConstrainedStringX04 ::= IA5String (SIZE (1|2), ..., SIZE (1|2|3|4|5))
+ ExtConstrainedStringX05 ::= IA5String (SIZE (1|2, ...), ...,
+ SIZE (1|2|3|4|5, ...))
integer4 INTEGER ::= 4
integer11 INTEGER ::= 11
diff --git a/lib/asn1/test/asn1_SUITE_data/Constraints.py b/lib/asn1/test/asn1_SUITE_data/Constraints.py
index 3495cd841b..a40c513141 100644
--- a/lib/asn1/test/asn1_SUITE_data/Constraints.py
+++ b/lib/asn1/test/asn1_SUITE_data/Constraints.py
@@ -81,7 +81,7 @@ maxNrOfCellPortionsPerCell-1 INTEGER ::= 35
CellPortionID ::= INTEGER (0..maxNrOfCellPortionsPerCell-1,...)
-- OTP-6763
-T ::= IA5String (SIZE (1|2, ..., SIZE (1|2|3))) -- Dubuisson 268
+T ::= IA5String (SIZE (1|2), ..., SIZE (1|2|3)) -- Dubuisson 268
T2 ::= IA5String (SIZE (1|2, ..., 3)) -- equal with T
-- OTP-8046
@@ -144,5 +144,47 @@ NonOverlapping ::= INTEGER (7280..7560 |
23000..24000 |
24960..26900)
+--
+-- Test INTEGER constraints from fields in objects.
+--
+
+INT-HOLDER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &obj INT-HOLDER OPTIONAL
+} WITH SYNTAX {
+ ID &id
+ [OBJ &obj]
+}
+
+int-holder-1 INT-HOLDER ::= { ID 2 }
+int-holder-2 INT-HOLDER ::= { ID 4 OBJ int-holder-1 }
+
+IntObjectConstr ::= INTEGER (int-holder-2.&obj.&id..int-holder-2.&id)
+
+--
+-- INTEGER constraints defined using named INTEGERs.
+--
+
+ConstrainedNamedInt ::= INTEGER {v1(42)} (v1)
+constrainedNamedInt-1 INTEGER {v1(42)} (v1) ::= 42
+constrainedNamedInt-2 ConstrainedNamedInt ::= 100
+
+SeqWithNamedInt ::= SEQUENCE {
+ int INTEGER {v2(7)} (v2)
+}
+
+--
+-- Cover simpletable constraint checking code.
+--
+
+ContentInfo ::= SEQUENCE {
+ contentType ContentType
+}
+
+Contents TYPE-IDENTIFIER ::= {
+ {OCTET STRING IDENTIFIED BY {2 1 1 1 1 1 1}}
+}
+
+ContentType ::= TYPE-IDENTIFIER.&id({Contents})
END
diff --git a/lib/asn1/test/asn1_SUITE_data/CoverParser.asn1 b/lib/asn1/test/asn1_SUITE_data/CoverParser.asn1
new file mode 100644
index 0000000000..75d40188ca
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/CoverParser.asn1
@@ -0,0 +1,57 @@
+CoverParser DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+ Cho1 ::= CHOICE {
+ i INTEGER,
+ ... ! 42,
+ [[ b BOOLEAN ]]
+ }
+
+ Cho2 ::= CHOICE {
+ i INTEGER,
+ ...,
+ [[ b BOOLEAN,
+ s IA5String ]],
+ ...
+ }
+
+ Int1 ::= INTEGER (CONSTRAINED BY {INTEGER:1,INTEGER:2})
+
+ Seq1 ::= SEQUENCE {
+ ... ! INTEGER:1
+ }
+
+ Seq2 ::= SEQUENCE {
+ ... ! INTEGER:1,
+ i INTEGER
+ }
+
+ Seq3 ::= SEQUENCE {
+ b BOOLEAN,
+ ... ! INTEGER:1,
+ i INTEGER
+ }
+
+ Seq4 ::= SEQUENCE {
+ a INTEGER OPTIONAL,
+ b OCTET STRING OPTIONAL
+ } (WITH COMPONENTS {a ABSENT, b OPTIONAL} |
+ WITH COMPONENTS {a PRESENT, b PRESENT})
+
+ SeqOf1 ::= SEQUENCE OF INTEGER
+ SeqOf2 ::= SeqOf1 (WITH COMPONENT (0..7))
+
+ SegOf3 ::= SEQUENCE (SIZE (1..10)) OF id INTEGER
+
+ Set1 ::= SET {
+ ... ! INTEGER:1
+ }
+
+ Set2 ::= SET {
+ ... ! INTEGER:1,
+ a INTEGER
+ }
+
+ SetOf3 ::= SET (SIZE (1..10)) OF id INTEGER
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
index 74fa97e7aa..55ad5a01a1 100644
--- a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
@@ -53,5 +53,7 @@ SeqBig ::= SEQUENCE {
i INTEGER
}
+EnumSkip ::= ENUMERATED {a(2), ..., b, c, d, e, f}
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/Example.asn1 b/lib/asn1/test/asn1_SUITE_data/Example.asn1
deleted file mode 100644
index 2639f63940..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/Example.asn1
+++ /dev/null
@@ -1,20 +0,0 @@
-Example DEFINITIONS ::=
-BEGIN
-
-T ::= Typ
-
-Typ ::= SEQUENCE {
- a b,
- c Typ}
---ECLASS ::= CLASS {
--- &num INTEGER UNIQUE,
--- &Typo
--- } WITH SYNTAX {
--- &Typo DETERMINED BY &num
--- }
-
---v1 ECLASS ::= {INTEGER DETERMINED BY 12}
-
---v2 INTEGER ::= 13
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/Export1.asn b/lib/asn1/test/asn1_SUITE_data/Export1.asn
deleted file mode 100644
index 78ead8f4d2..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/Export1.asn
+++ /dev/null
@@ -1,7 +0,0 @@
-Export1 DEFINITIONS ::=
-BEGIN
-EXPORTS T
-
-T ::= Typ
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/Exporting.asn1 b/lib/asn1/test/asn1_SUITE_data/Exporting.asn1
new file mode 100644
index 0000000000..e4f32f6788
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Exporting.asn1
@@ -0,0 +1,18 @@
+Exporting DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+ Seq ::= SEQUENCE { id INTEGER, f BOOLEAN }
+ PtSeq{T} ::= SEQUENCE { a T }
+
+ CL ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type
+ } WITH SYNTAX {
+ ID &id TYPE &Type
+ }
+
+ obj CL ::= { ID 1 TYPE OCTET STRING }
+
+ pt-object{CL:ob} CL ::= {ID ob.&id TYPE OCTET STRING}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ExtensibilityImplied.asn1 b/lib/asn1/test/asn1_SUITE_data/ExtensibilityImplied.asn1
new file mode 100644
index 0000000000..d59b0edda5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ExtensibilityImplied.asn1
@@ -0,0 +1,30 @@
+ExtensibilityImplied DEFINITIONS
+AUTOMATIC TAGS
+EXTENSIBILITY IMPLIED
+::=
+BEGIN
+
+Enum1 ::= ENUMERATED { root, ..., ext }
+Enum2 ::= ENUMERATED { root }
+
+Seq1 ::= SEQUENCE {
+ b BOOLEAN,
+ ...,
+ i INTEGER
+}
+
+Seq2 ::= SEQUENCE {
+ b BOOLEAN
+}
+
+Set1 ::= SET {
+ b BOOLEAN,
+ ...,
+ i INTEGER
+}
+
+Set2 ::= SET {
+ b BOOLEAN
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
index 0e905d8839..c0315c1489 100644
--- a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
+++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
@@ -3,16 +3,17 @@
--
-- Copyright Ericsson AB 2001-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/.
+-- Licensed under the Apache License, Version 2.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
--
--- Software distributed under the License is distributed on an "AS IS"
--- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--- the License for the specific language governing rights and limitations
--- under the License.
+-- 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%
diff --git a/lib/asn1/test/asn1_SUITE_data/IllegalExport.asn1 b/lib/asn1/test/asn1_SUITE_data/IllegalExport.asn1
deleted file mode 100644
index 1b5e42ad3c..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/IllegalExport.asn1
+++ /dev/null
@@ -1,7 +0,0 @@
-IllegalExport DEFINITIONS ::=
-BEGIN
-EXPORTS T, KalleAnka;
-
-T ::= INTEGER
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/Importing.asn1 b/lib/asn1/test/asn1_SUITE_data/Importing.asn1
new file mode 100644
index 0000000000..2f2699c576
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Importing.asn1
@@ -0,0 +1,20 @@
+Importing DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+ Seq ::= Exporting.PtSeq{ INTEGER(0..7) }
+ OtherSeq ::= Exporting.Seq
+
+ seq Exporting.Seq ::= { id 42, f TRUE }
+
+ o1 Exporting.CL ::= { ID 2 TYPE INTEGER (0..63) }
+
+ ObjSet Exporting.CL ::= { o1 | Exporting.obj }
+
+ ObjSeq ::= SEQUENCE {
+ id Exporting.CL.&id ({ObjSet}),
+ type Exporting.CL.&Type ({ObjSet}{@id})
+ }
+
+ o1-cloned Exporting.CL ::= Exporting.pt-object{o1}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/InfObj.asn b/lib/asn1/test/asn1_SUITE_data/InfObj.asn
index 719119f418..3b88770d78 100644
--- a/lib/asn1/test/asn1_SUITE_data/InfObj.asn
+++ b/lib/asn1/test/asn1_SUITE_data/InfObj.asn
@@ -206,7 +206,9 @@ ConstructedDefaultSet CONSTRUCTED-DEFAULT ::= {
{ &id 4, &Type SET { a INTEGER, b BIT STRING } } |
{ &id 5, &Type CHOICE { i INTEGER, b BIT STRING } } |
{ &id 6, &Type SEQUENCE OF INTEGER (1..16) } |
- { &id 7, &Type SET OF INTEGER (1..64) }
+ { &id 7, &Type SET OF INTEGER (1..64) } |
+ { &id 8, &Type SEQUENCE OF SEQUENCE { x INTEGER, y INTEGER } } |
+ { &id 9, &Type SET OF SEQUENCE { x INTEGER, y INTEGER } }
}
ConstructedPdu ::= SEQUENCE {
@@ -288,18 +290,196 @@ OstSeq1234 ::= ObjectSetTest{ {Ost1234} }
OstSeq45 ::= ObjectSetTest{ {Ost45} }
OstSeq12345 ::= ObjectSetTest{ {Ost12345} }
+OstSeq12Except ::= ObjectSetTest{ {Ost123 EXCEPT ost3} }
+OstSeq123Except ::= ObjectSetTest{ {Ost12345 EXCEPT Ost45} }
+
+ExOst1 OBJECT-SET-TEST ::= { ost1, ... }
ExOst12 OBJECT-SET-TEST ::= { ost1, ..., ost2 }
ExOst123 OBJECT-SET-TEST ::= { ost3, ..., ExOst12 }
---ExOst1234 OBJECT-SET-TEST ::= { ExOst123, ..., ost4 }
+ExOst1234 OBJECT-SET-TEST ::= { ExOst123, ..., ost4 }
ExOst45 OBJECT-SET-TEST ::= { ost4, ..., ost5 }
ExOst12345 OBJECT-SET-TEST ::= { ExOst123, ..., ExOst45 }
+ExOstSeq1 ::= ObjectSetTest{ {ExOst1} }
ExOstSeq12 ::= ObjectSetTest{ {ExOst12} }
ExOstSeq123 ::= ObjectSetTest{ {ExOst123} }
---ExOstSeq1234 ::= ObjectSetTest{ {ExOst1234} }
+ExOstSeq1234 ::= ObjectSetTest{ {ExOst1234} }
ExOstSeq45 ::= ObjectSetTest{ {ExOst45} }
ExOstSeq12345 ::= ObjectSetTest{ {ExOst12345} }
-END
+ExOstSeq12Except ::= ObjectSetTest{ {ExOst123 EXCEPT ost3} }
+ExOstSeq123Except ::= ObjectSetTest{ {ExOst12345 EXCEPT ExOst45} }
+
+ExInlOst1 OBJECT-SET-TEST ::= {
+ { 1 IS BIT STRING },
+ ...
+}
+ExInlOst12 OBJECT-SET-TEST ::= {
+ { 1 IS BIT STRING },
+ ...,
+ { 2 IS OCTET STRING }
+}
+
+ExInlOstSeq1 ::= ObjectSetTest{ {ExInlOst1} }
+ExInlOstSeq12 ::= ObjectSetTest{ {ExInlOst12} }
+
+--
+-- Test that extensions in a simple class works.
+--
+
+ExtClassSeq ::= SEQUENCE {
+ arg EXT-CLASS.&id({Extend})
+}
+
+EXT-CLASS ::= CLASS {
+ &id INTEGER UNIQUE
+} WITH SYNTAX {
+ ID &id
+}
+
+Extend EXT-CLASS ::= { { ID alt1 } | { ID alt2 }, ... }
+
+alt1 INTEGER ::= 4
+alt2 INTEGER ::= 5
+
+
+--
+-- Test a BIT STRING which is optional in the simplified syntax.
+--
+
+PUBLIC-KEY ::= CLASS {
+ &id INTEGER UNIQUE,
+ &keyUsage KeyUsage OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [OPTIONAL-BIT-STRING &keyUsage]
+}
+
+KeyUsage ::= BIT STRING {
+ digitalSignature (0),
+ nonRepudiation (1),
+ keyEncipherment (2)
+ }
+
+object-with-optional-bit-string PUBLIC-KEY ::= {
+ IDENTIFIER 42
+ OPTIONAL-BIT-STRING {digitalSignature, nonRepudiation, keyEncipherment}
+}
+
+-- Test object identifiers from objects.
+
+CONTAINER ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &rid RELATIVE-OID OPTIONAL,
+ &Type OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIED BY &id
+ [REL-OID &rid]
+ [TYPE &Type]
+}
+
+id1 OBJECT IDENTIFIER ::= {1 2 42}
+obj1 CONTAINER ::= { IDENTIFIED BY id1 REL-OID {100 101} }
+
+value-2 OBJECT IDENTIFIER ::= { value-1 25 }
+value-1 OBJECT IDENTIFIER ::= obj1.&id
+value-3 RELATIVE-OID ::= obj1.&rid
+value-4 OBJECT IDENTIFIER ::= { 1 2 value-3 }
+
+
+-- Test an obscure issue when ATTRIBUTE.&id was not
+-- properly evaluated.
+
+Rdn ::= SingleAttribute { {SupportedAttributes} }
+
+ATTRIBUTE ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL
+}
+
+SingleAttribute{ATTRIBUTE:AttrSet} ::= SEQUENCE {
+ type ATTRIBUTE.&id({AttrSet}),
+ value ATTRIBUTE.&Type({AttrSet}{@type})
+}
+AttributeType ::= ATTRIBUTE.&id
+SupportedAttributes ATTRIBUTE ::= { at-name }
+
+id-at OBJECT IDENTIFIER ::= { 2 5 4 41 }
+id-at-name AttributeType ::= id-at
+at-name ATTRIBUTE ::= { &Type PrintableString, &id id-at-name }
+
+--
+-- Test using an alias for TYPE-IDENTIFIER.
+--
+
+TiAliasParameterized { TI-ALIAS:InfoObjectSet } ::= SEQUENCE {
+ algorithm TI-ALIAS.&id({InfoObjectSet}),
+ parameters TI-ALIAS.&Type({InfoObjectSet} {@algorithm}) OPTIONAL
+}
+
+TI-ALIAS ::= TYPE-IDENTIFIER
+
+TiAliasSeq ::= SEQUENCE {
+ prf TiAliasParameterized {{TiAliasSet}}
+}
+
+TiAliasSet TI-ALIAS ::= {
+ {NULL IDENTIFIED BY {2 1 2}},
+ ...
+}
+
+--
+-- Test using an alias for a class.
+--
+
+ALIAS-CONTAINER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &obj INDIRECT-CLASS
+}
+
+INDIRECTED-CLASS ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type
+}
+
+INDIRECT-CLASS ::= INDIRECTED-CLASS
+
+--
+-- Indirect ObjectClassFieldType in a SEQUENCE.
+--
+
+ContentInfo ::= SEQUENCE {
+ contentType ContentType, -- Indirect ObjectClassFieldType
+ content TYPE-IDENTIFIER.&Type({Contents}{@contentType})
+OPTIONAL
+}
+
+Contents TYPE-IDENTIFIER ::= {
+ {IA5String IDENTIFIED BY id-content-type}
+}
+
+ContentType ::= TYPE-IDENTIFIER.&id({Contents})
+id-content-type ContentType ::= { 2 7 8 9 }
+
+--
+-- Tricky parsing of simplified syntax.
+--
+
+TrickyType-1 ::= BIT STRING
+TrickyType-2 ::= OCTET STRING
+
+TRICKY ::= CLASS {
+ &Type1,
+ &Type2
+} WITH SYNTAX {
+ TYPE &Type1 &Type2
+}
+
+tricky-object TRICKY ::= {TYPE TrickyType-1 TrickyType-2}
+
+tricky-bit-string tricky-object.&Type1 ::= '1011'B
+tricky-octet-string tricky-object.&Type1 ::= 'CAFE'H
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1 b/lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1
new file mode 100644
index 0000000000..13981b546d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1
@@ -0,0 +1,136 @@
+InfObjExtract DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+DATA-CLASS ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type
+} WITH SYNTAX {
+ ID &id
+ TYPE &Type
+}
+
+data-object-1 DATA-CLASS ::= { ID 1 TYPE BOOLEAN }
+data-object-2 DATA-CLASS ::= { ID 2 TYPE OCTET STRING }
+data-object-3 DATA-CLASS ::= { ID 3 TYPE BIT STRING }
+
+ObjSet DATA-CLASS ::= {
+ holder-object-1.&obj |
+ data-object-2 |
+ data-object-3,
+ ...
+}
+
+OBJ-SET DATA-CLASS ::= {
+ holder-object-1.&obj |
+ data-object-2 |
+ data-object-3,
+ ...
+}
+
+SingleElementSet DATA-CLASS ::= {
+ holder-object-1.&obj
+}
+
+holder-object-1 HOLDER-CLASS ::= {
+ OBJ data-object-1
+}
+
+holder-object-2 HOLDER-CLASS ::= {
+ OBJ-SET {data-object-1}
+}
+
+holder-object-3 HOLDER-CLASS ::= {
+ OBJ-SET {holder-object-2.&ObjSet}
+}
+
+-- Note: References to object sets with names in all uppercase/hyphens
+-- may be represented differently compared to object sets with names
+-- that contain lowercase letters. CAVEAT TESTOR.
+
+HOLDER-OBJECTS HOLDER-CLASS ::= { holder-object-2 }
+HolderObjects HOLDER-CLASS ::= { holder-object-3 }
+
+holder-object-4 HOLDER-CLASS ::= {
+ OBJ-SET { HOLDER-OBJECTS.&ObjSet }
+}
+
+holder-object-5 HOLDER-CLASS ::= {
+ OBJ-SET { HolderObjects.&ObjSet }
+}
+
+holder-object-6 HOLDER-CLASS ::= {
+ OBJ-SET { OBJ-SET }
+}
+
+holder-object-7 HOLDER-CLASS ::= {
+ OBJ-SET { ObjSet }
+}
+
+HOLDER-CLASS ::= CLASS {
+ &obj DATA-CLASS OPTIONAL,
+ &ObjSet DATA-CLASS OPTIONAL
+} WITH SYNTAX {
+ [OBJ &obj]
+ [OBJ-SET &ObjSet]
+}
+
+TestSeq{DATA-CLASS:ObjectSet} ::= SEQUENCE {
+ id DATA-CLASS.&id ({ObjectSet}),
+ data DATA-CLASS.&Type ({ObjectSet}{@id})
+}
+
+DataSeq-1 ::= TestSeq{ {ObjSet} }
+DataSeq-2 ::= TestSeq{ {holder-object-3.&ObjSet} }
+
+DataSeq-3 ::= TestSeq{ {holder-object-4.&ObjSet} }
+DataSeq-4 ::= TestSeq{ {holder-object-5.&ObjSet} }
+DataSeq-5 ::= TestSeq{ {holder-object-6.&ObjSet} }
+DataSeq-6 ::= TestSeq{ {holder-object-7.&ObjSet} }
+
+DataSeqSingleSet-1 ::= TestSeq{ {SingleElementSet} }
+DataSeqSingleSet-2 ::= TestSeq{ {holder-object-1.&obj} }
+
+--
+-- Test ObjectSetFromObjects.
+--
+
+OBJ-CLASS ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Data OPTIONAL,
+ &Obj OBJ-CLASS OPTIONAL,
+ &obj OBJ-CLASS OPTIONAL
+}
+
+obj-class-obj-1 OBJ-CLASS ::= { &id 1, &Data BOOLEAN }
+
+obj-class-obj-2 OBJ-CLASS ::= { &id 2, &Data BOOLEAN,
+ &Obj {obj-class-obj-1} }
+
+obj-class-obj-3 OBJ-CLASS ::= { &id 3, &Data BOOLEAN,
+ &obj {&id 99, &Obj {obj-class-obj-1}} }
+
+obj-class-obj-4 OBJ-CLASS ::= { &id 4, &Data BOOLEAN, &obj obj-class-obj-2 }
+
+obj-class-obj-5 OBJ-CLASS ::= { &id 5, &Data BOOLEAN,
+ &Obj {obj-class-obj-4.&obj} }
+
+ObjClassSet OBJ-CLASS ::= { obj-class-obj-3.&obj.&Obj |
+ obj-class-obj-4.&Obj | -- Non-existing field
+ obj-class-obj-5.&Obj
+ }
+
+TestObjClassSeq{OBJ-CLASS:ObjectSet} ::= SEQUENCE {
+ id OBJ-CLASS.&id ({ObjectSet}),
+ data OBJ-CLASS.&Data ({ObjectSet}{@id})
+}
+
+ObjClassSeq-1 ::= TestObjClassSeq{{ObjClassSet}}
+
+--
+-- Test several levels of inlined definitions.
+--
+
+obj-class-obj-6 OBJ-CLASS ::= { &id 6, &Obj {{&id 100, &Data INTEGER}},
+ &Data INTEGER }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/MissingEnd.asn1 b/lib/asn1/test/asn1_SUITE_data/MissingEnd.asn1
deleted file mode 100644
index 66912ef693..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/MissingEnd.asn1
+++ /dev/null
@@ -1,5 +0,0 @@
-MissingEnd DEFINITIONS ::=
-BEGIN
-
-T ::= Typ
-
diff --git a/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1 b/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1
index 9368e8dceb..9193ed495c 100644
--- a/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1
@@ -50,6 +50,7 @@ itu-t-o OBJECT IDENTIFIER ::= {itu-t recommendation o}
itu-t-p OBJECT IDENTIFIER ::= {itu-t recommendation p}
itu-t-q OBJECT IDENTIFIER ::= {itu-t recommendation q}
itu-t-r OBJECT IDENTIFIER ::= {itu-t recommendation r}
+itu-t-s OBJECT IDENTIFIER ::= {itu-t recommendation s}
itu-t-t OBJECT IDENTIFIER ::= {itu-t recommendation t}
itu-t-u OBJECT IDENTIFIER ::= {itu-t recommendation u}
itu-t-v OBJECT IDENTIFIER ::= {itu-t recommendation v}
diff --git a/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1 b/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
index 68fc782f33..d203b6c816 100644
--- a/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
@@ -42,4 +42,37 @@ SIGNATURE-ALGORITHM ::= CLASS {
KEY &id CONTAINING &Type
}
+alg-seq-1 AnAlgorithm ::= { algorithm 1, type 42 }
+alg-seq-2 AnAlgorithm ::= { algorithm 2, type TRUE }
+
+--
+-- Test that indirect classes references are resolved.
+--
+
+AlgorithmIdentifier2 { ALGORITHM-IDENTIFIER:InfoObjectSet } ::= SEQUENCE {
+ algorithm ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
+ parameters ALGORITHM-IDENTIFIER.&Type({InfoObjectSet} {@algorithm}) OPTIONAL
+}
+
+ALGORITHM-IDENTIFIER ::= TYPE-IDENTIFIER
+
+Seq ::= SEQUENCE {
+ c1 AlgorithmIdentifier2 {{ObjectSet-1}},
+ c2 AlgorithmIdentifier2 {{ObjectSet-2}}
+}
+
+ObjectSet-1 ALGORITHM-IDENTIFIER ::= { {INTEGER IDENTIFIED BY {2 1 1}}, ... }
+ObjectSet-2 ALGORITHM-IDENTIFIER ::= { ... }
+
+-- Test a value that uses the instantiation of a parameterized type inline.
+-- (Adapted from PKCS-5.)
+--
+
+algid-hmacWithSHA1 AlgorithmIdentifier2 {{ObjectSet-3}} ::=
+ {algorithm id-hmacWithSHA1, parameters NULL : NULL}
+
+ObjectSet-3 TYPE-IDENTIFIER ::= { {NULL IDENTIFIED BY id-hmacWithSHA1} }
+
+id-hmacWithSHA1 OBJECT IDENTIFIER ::= {2 9 9 9 7}
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
index cc0e61422a..4fe0901683 100644
--- a/lib/asn1/test/asn1_SUITE_data/Prim.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
@@ -24,6 +24,8 @@ BEGIN
friday(5),saturday(6),sunday(7)}
SingleEnumVal ::= ENUMERATED {true}
SingleEnumValExt ::= ENUMERATED {true, ...}
+ NegEnumVal ::= ENUMERATED {neg(-1), ..., zero(0)}
+ EnumVal128 ::= ENUMERATED {val(128)}
ObjId ::= OBJECT IDENTIFIER
@@ -58,4 +60,11 @@ BEGIN
e BOOLEAN,
magic INTEGER
}
+
+ Longitude ::= INTEGER {
+ oneMicrodegreeEast(10),
+ oneMicrodegreeWest(-10),
+ unavailable(1800000001)
+ } (-1799999999..1800000001)
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/SelectionType.asn b/lib/asn1/test/asn1_SUITE_data/SelectionType.asn
index d7bfbf1788..6163f390dd 100644
--- a/lib/asn1/test/asn1_SUITE_data/SelectionType.asn
+++ b/lib/asn1/test/asn1_SUITE_data/SelectionType.asn
@@ -14,7 +14,7 @@ Element ::= CHOICE {bool BOOLEAN,
utf UTF8String,
ro RELATIVE-OID,
nums NumericString,
- symbol PrintableString,
+ symbol PrintableString,
telet TeletexString,
t61 T61String,
video VideotexString,
@@ -23,13 +23,14 @@ Element ::= CHOICE {bool BOOLEAN,
generalizedTime GeneralizedTime,
gs GraphicString,
vs VisibleString,
--- iso64 ISO646String,
generalString GeneralString,
univ UniversalString,
cs CHARACTER STRING,
bmp BMPString}
-MendeleyevTable ::= SEQUENCE OF symbol < Element
+MendeleyevTable ::= SEQUENCE OF symbol < Element
+MendeleyevSet ::= SET OF atomic-no < Element
+
BoolType ::= bool < Element
einsteinium symbol < Element ::= "Es"
@@ -51,7 +52,6 @@ utctimev utctime < Element ::= "9805281429Z"
gTime generalizedTime < Element ::= "19980528142905.1"
gsv gs < Element ::= "graphic"
vsv vs < Element ::= "visible"
---iso64v iso64 < Element ::= "iso"
gStringv generalString < Element ::= "general"
univv univ < Element ::= "Universal"
bmov bmp < Element ::= "bmp"
diff --git a/lib/asn1/test/asn1_SUITE_data/Seq.py b/lib/asn1/test/asn1_SUITE_data/Seq.py
index f345373ab5..b68f9045a6 100644
--- a/lib/asn1/test/asn1_SUITE_data/Seq.py
+++ b/lib/asn1/test/asn1_SUITE_data/Seq.py
@@ -142,7 +142,10 @@ SeqImp3 ::= SET
set Set1
}
-
+SeqCompOf ::= SEQUENCE {
+ ...,
+ COMPONENTS OF SeqS3
+}
END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn b/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn
index 7de9134096..bb85c9e418 100644
--- a/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn
@@ -15,10 +15,10 @@ SeqOpt1Imp ::= SEQUENCE
bool1 [1] BOOLEAN OPTIONAL,
int1 INTEGER,
seq1 [2] SeqIn OPTIONAL,
- seq2 [2] SeqIn OPTIONAL,
+ seq2 [3] SeqIn OPTIONAL,
...,
- int2 [3] SeqIn,
- int3 [3] SeqIn
+ int2 [4] SeqIn,
+ int3 [5] SeqIn
}
SeqOpt1Exp ::= SEQUENCE
diff --git a/lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn b/lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn
deleted file mode 100644
index 436815aa9b..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn
+++ /dev/null
@@ -1,10 +0,0 @@
-SequenceBadComma DEFINITIONS IMPLICIT TAGS ::=
-BEGIN
-EXPORTS Person;
-
-Person ::= [PRIVATE 19] SEQUENCE {,
- name PrintableString,
- location INTEGER {home(0),field(1),roving(2)},
- age INTEGER OPTIONAL
- }
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn1 b/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn1
deleted file mode 100644
index 8b2b8816db..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn1
+++ /dev/null
@@ -1,10 +0,0 @@
-SequenceBadComponentName DEFINITIONS ::=
-BEGIN
-
-T ::= Typ
-
-Typ ::= SEQUENCE {
- a INTEGER,
- C Typ}
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn1 b/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn1
deleted file mode 100644
index 0c33f48906..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn1
+++ /dev/null
@@ -1,10 +0,0 @@
-SequenceBadComponentType DEFINITIONS ::=
-BEGIN
-
-T ::= Typ
-
-Typ ::= SEQUENCE {
- a b,
- c T}
-
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/Syntax.py b/lib/asn1/test/asn1_SUITE_data/Syntax.py
deleted file mode 100644
index 867d1148e1..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/Syntax.py
+++ /dev/null
@@ -1,10 +0,0 @@
-Syntax DEFINITIONS IMPLICIT TAGS ::=
-BEGIN
-EXPORTS Person;
-
-Person ::= [PRIVATE 19] SEQUENCE {,
- name PrintableString,
- location INTEGER {home(0),field(1),roving(2)},
- age INTEGER OPTIONAL
- }
-END
diff --git a/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl b/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl
index 0bf4425263..7f7c013f30 100644
--- a/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl
+++ b/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
index dae9ae498a..b2c59d686a 100644
--- a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
+++ b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
@@ -1,4 +1,4 @@
-ValueTest DEFINITIONS ::=
+ValueTest DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
@@ -23,8 +23,15 @@ vENUMERATED RadioButton ::= button1
vBS BSNNL ::= {zero,two}
vNULL NULL ::= NULL
vOS OCTET STRING ::= '313233'H
-vOD OBJECT IDENTIFIER ::= {2 1 1}
+-- OBJECT IDENTIFIER
+vOD OBJECT IDENTIFIER ::= {2 1 1}
+one INTEGER ::= 1
+integer-first OBJECT IDENTIFIER ::= {one 2}
+rel-oid-1 RELATIVE-OID ::= {2 4 5}
+include-roid OBJECT IDENTIFIER ::= {0 rel-oid-1}
+include-oid OBJECT IDENTIFIER ::= {integer-first 1}
+include-all OBJECT IDENTIFIER ::= {integer-first 1 rel-oid-1 42}
--Character strings
numericstring NumericString ::= "01234567"
@@ -41,7 +48,6 @@ objectdescriptor ObjectDescriptor ::= "ObjectDescriptor"
graphicstring GraphicString ::= "GraphicString"
generalstring GeneralString ::= "GeneralString"
bmpstring1 BMPString ::= "BMPString"
---bmpstring2 BMPString ::= [{0,0,0,66},{0,0,0,77},{0,0,0,80},{0,0,0,115},{0,0,0,116},{0,0,0,114},{0,0,0,105},{0,0,0,110},{0,0,0,103}]
latinCapitalLetterA UniversalString ::= {0,0,0,65}
greekCapitalLetterSigma UniversalString ::= {0,0,3,145}
my-universalstring UniversalString ::= {"This is a capital A: ",
@@ -50,4 +56,88 @@ my-universalstring UniversalString ::= {"This is a capital A: ",
greekCapitalLetterSigma,
"; try and spot the difference!"}
+-- Useful parameterized SEQUENCE.
+ParamSeq{Type} ::= SEQUENCE {
+ a Type
+}
+
+-- Integer values.
+IntegerSeq ::= ParamSeq{INTEGER}
+someInteger INTEGER ::= 42
+integerSeq1 IntegerSeq ::= { a otherInteger }
+otherInteger INTEGER ::= someInteger
+
+--
+-- Values from objects.
+--
+int-from-object-1 INTEGER ::= int-holder-2.&obj.&id
+int-from-object-2 INTEGER ::= int-holder-2.&id
+
+INT-HOLDER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &obj INT-HOLDER OPTIONAL
+} WITH SYNTAX {
+ ID &id
+ [OBJ &obj]
+}
+
+int-holder-1 INT-HOLDER ::= { ID 2 }
+int-holder-2 INT-HOLDER ::= { ID 4 OBJ int-holder-1 }
+
+II ::= INTEGER (int-from-object-1..int-from-object-2)
+
+-- Recursive OCTET STRING definitions.
+
+OS-HOLDER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &os OCTET STRING
+} WITH SYNTAX {
+ ID &id OS &os
+}
+
+os-holder-1 OS-HOLDER ::= { ID 1 OS '4041FF'H }
+
+OctetStringSeq ::= ParamSeq{OCTET STRING}
+
+someOctetString OCTET STRING ::= '404142'H
+
+octetStringSeq1 OctetStringSeq ::= { a someOctetString }
+octetStringSeq2 OctetStringSeq ::= { a otherOctetString }
+octetStringSeq3 OctetStringSeq ::= { a os-holder-1.&os }
+
+otherOctetString OCTET STRING ::= someOctetString
+
+os-1 OCTET STRING ::= os-2
+os-2 OCTET STRING ::= os-holder-1.&os
+
+-- Recursive BIT STRING definitions.
+
+BS-HOLDER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &bs BIT STRING,
+ &named-bs NamedBsType
+} WITH SYNTAX {
+ ID &id BS &bs NAMED-BS &named-bs
+}
+bs-holder-1 BS-HOLDER ::= { ID 1 BS '101'B NAMED-BS {a,c} }
+
+NamedBsType ::= BIT STRING {a(0),b(1),c(2)}
+BsSeq ::= SEQUENCE {
+ a BIT STRING,
+ b NamedBsType
+}
+
+someBitString BIT STRING ::= '101101'B
+
+bsSeq1 BsSeq ::= { a someBitString, b someNamedBs }
+bsSeq2 BsSeq ::= { a otherBitString, b someOtherNamedBs }
+bsSeq3 BsSeq ::= { a bs-holder-1.&bs, b bs-holder-1.&named-bs }
+
+otherBitString BIT STRING ::= someBitString
+bsFromObjectInd BIT STRING ::= bsFromObject
+bsFromObject BIT STRING ::= bs-holder-1.&bs
+
+someOtherNamedBs NamedBsType ::= someNamedBs
+someNamedBs NamedBsType ::= {c}
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl b/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl
index c6db3fd016..e8db7231f1 100644
--- a/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl
+++ b/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl b/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl
index 3fa124c278..ba73a72132 100644
--- a/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl
+++ b/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
index a1e563f6be..3600ccac26 100644
--- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/ACSE-1.asn1
index 3f1385323a..3f1385323a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/ACSE-1.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/AlgorithmInformation-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/AlgorithmInformation-2009.asn1
new file mode 100644
index 0000000000..f912966c72
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/AlgorithmInformation-2009.asn1
@@ -0,0 +1,466 @@
+AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+DEFINITIONS EXPLICIT TAGS ::=
+BEGIN
+EXPORTS ALL;
+IMPORTS
+
+KeyUsage
+FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-implicit-02(59)} ;
+
+-- Suggested prefixes for algorithm objects are:
+--
+-- mda- Message Digest Algorithms
+-- sa- Signature Algorithms
+-- kta- Key Transport Algorithms (Asymmetric)
+-- kaa- Key Agreement Algorithms (Asymmetric)
+-- kwa- Key Wrap Algorithms (Symmetric)
+-- kda- Key Derivation Algorithms
+-- maca- Message Authentication Code Algorithms
+-- pk- Public Key
+-- cea- Content (symmetric) Encryption Algorithms
+-- cap- S/MIME Capabilities
+
+ParamOptions ::= ENUMERATED {
+ required, -- Parameters MUST be encoded in structure
+ preferredPresent, -- Parameters SHOULD be encoded in structure
+ preferredAbsent, -- Parameters SHOULD NOT be encoded in structure
+ absent, -- Parameters MUST NOT be encoded in structure
+ inheritable, -- Parameters are inherited if not present
+ optional, -- Parameters MAY be encoded in the structure
+ ...
+}
+
+-- DIGEST-ALGORITHM
+--
+-- Describes the basic information for ASN.1 and a digest
+-- algorithm.
+--
+-- &id - contains the OID identifying the digest algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+--
+-- Additional information such as the length of the hash could have
+-- been encoded. Without a clear understanding of what information
+-- is needed by applications, such extraneous information was not
+-- considered to be of sufficent importance.
+--
+-- Example:
+-- mda-sha1 DIGEST-ALGORITHM ::= {
+-- IDENTIFIER id-sha1
+-- PARAMS TYPE NULL ARE preferredAbsent
+-- }
+
+DIGEST-ALGORITHM ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence ]
+}
+
+-- SIGNATURE-ALGORITHM
+--
+-- Describes the basic properties of a signature algorithm
+--
+-- &id - contains the OID identifying the signature algorithm
+-- &Value - contains a type definition for the value structure of
+-- the signature; if absent, implies that no ASN.1
+-- encoding is performed on the value
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &HashSet - The set of hash algorithms used with this
+-- signature algorithm
+-- &PublicKeySet - the set of public key algorithms for this
+-- signature algorithm
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Example:
+-- sig-RSA-PSS SIGNATURE-ALGORITHM ::= {
+-- IDENTIFIER id-RSASSA-PSS
+-- PARAMS TYPE RSASSA-PSS-params ARE required
+-- HASHES { mda-sha1 | mda-md5, ... }
+-- PUBLIC-KEYS { pk-rsa | pk-rsa-pss }
+-- }
+
+SIGNATURE-ALGORITHM ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Value OPTIONAL,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &HashSet DIGEST-ALGORITHM OPTIONAL,
+ &PublicKeySet PUBLIC-KEY OPTIONAL,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [VALUE &Value]
+ [PARAMS [TYPE &Params] ARE &paramPresence ]
+ [HASHES &HashSet]
+ [PUBLIC-KEYS &PublicKeySet]
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- PUBLIC-KEY
+--
+-- Describes the basic properties of a public key
+--
+-- &id - contains the OID identifying the public key
+-- &KeyValue - contains the type for the key value
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &keyUsage - contains the set of bits that are legal for this
+-- key type. Note that is does not make any statement
+-- about how bits may be paired.
+-- &PrivateKey - contains a type structure for encoding the private
+-- key information.
+--
+-- Example:
+-- pk-rsa-pss PUBLIC-KEY ::= {
+-- IDENTIFIER id-RSASSA-PSS
+-- KEY RSAPublicKey
+-- PARAMS TYPE RSASSA-PSS-params ARE optional
+-- CERT-KEY-USAGE { .... }
+-- }
+
+PUBLIC-KEY ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &KeyValue OPTIONAL,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &keyUsage KeyUsage OPTIONAL,
+ &PrivateKey OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [KEY &KeyValue]
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [CERT-KEY-USAGE &keyUsage]
+ [PRIVATE-KEY &PrivateKey]
+}
+
+-- KEY-TRANSPORT
+--
+-- Describes the basic properties of a key transport algorithm
+--
+-- &id - contains the OID identifying the key transport algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &PublicKeySet - specifies which public keys are used with
+-- this algorithm
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Example:
+-- kta-rsaTransport KEY-TRANSPORT ::= {
+-- IDENTIFIER &id
+-- PARAMS TYPE NULL ARE required
+-- PUBLIC-KEYS { pk-rsa | pk-rsa-pss }
+-- }
+
+KEY-TRANSPORT ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &PublicKeySet PUBLIC-KEY OPTIONAL,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [PUBLIC-KEYS &PublicKeySet]
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- KEY-AGREE
+--
+-- Describes the basic properties of a key agreement algorithm
+--
+-- &id - contains the OID identifying the key agreement algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &PublicKeySet - specifies which public keys are used with
+-- this algorithm
+-- &Ukm - type of user keying material used
+-- &ukmPresence - specifies the requirements to define the UKM field
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Example:
+-- kaa-dh-static-ephemeral KEY-AGREE ::= {
+-- IDENTIFIER id-alg-ESDH
+-- PARAMS TYPE KeyWrapAlgorithm ARE required
+-- PUBLIC-KEYS {
+-- {IDENTIFIER dh-public-number KEY DHPublicKey
+-- PARAMS TYPE DHDomainParameters ARE inheritable }
+-- }
+-- - - UKM should be present but is not separately ASN.1-encoded
+-- UKM ARE preferredPresent
+-- }
+
+KEY-AGREE ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &PublicKeySet PUBLIC-KEY OPTIONAL,
+ &Ukm OPTIONAL,
+ &ukmPresence ParamOptions DEFAULT absent,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [PUBLIC-KEYS &PublicKeySet]
+ [UKM [TYPE &Ukm] ARE &ukmPresence]
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- KEY-WRAP
+--
+-- Describes the basic properties of a key wrap algorithm
+--
+-- &id - contains the OID identifying the key wrap algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Example:
+-- kwa-cms3DESwrap KEY-WRAP ::= {
+-- IDENTIFIER id-alg-CMS3DESwrap
+-- PARAMS TYPE NULL ARE required
+-- }
+
+KEY-WRAP ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [SMIME-CAPS &smimeCaps]
+}
+-- KEY-DERIVATION
+--
+-- Describes the basic properties of a key derivation algorithm
+--
+-- &id - contains the OID identifying the key derivation algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Example:
+-- kda-pbkdf2 KEY-DERIVATION ::= {
+-- IDENTIFIER id-PBKDF2
+-- PARAMS TYPE PBKDF2-params ARE required
+-- }
+
+KEY-DERIVATION ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- MAC-ALGORITHM
+--
+-- Describes the basic properties of a message
+-- authentication code (MAC) algorithm
+--
+-- &id - contains the OID identifying the MAC algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &keyed - MAC algorithm is a keyed MAC algorithm
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Some parameters that perhaps should have been added would be
+-- fields with the minimum and maximum MAC lengths for
+-- those MAC algorithms that allow truncations.
+--
+-- Example:
+-- maca-hmac-sha1 MAC-ALGORITHM ::= {
+-- IDENTIFIER hMAC-SHA1
+-- PARAMS TYPE NULL ARE preferredAbsent
+-- IS KEYED MAC TRUE
+-- SMIME-CAPS {IDENTIFIED BY hMAC-SHA1}
+-- }
+
+MAC-ALGORITHM ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &keyed BOOLEAN,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ IS-KEYED-MAC &keyed
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- CONTENT-ENCRYPTION
+--
+-- Describes the basic properties of a content encryption
+-- algorithm
+--
+-- &id - contains the OID identifying the content
+-- encryption algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- Example:
+-- cea-3DES-cbc CONTENT-ENCRYPTION ::= {
+-- IDENTIFIER des-ede3-cbc
+-- PARAMS TYPE IV ARE required
+-- SMIME-CAPS { IDENTIFIED BY des-ede3-cbc }
+-- }
+
+CONTENT-ENCRYPTION ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- ALGORITHM
+--
+-- Describes a generic algorithm identifier
+--
+-- &id - contains the OID identifying the algorithm
+-- &Params - if present, contains the type for the algorithm
+-- parameters; if absent, implies no parameters
+-- &paramPresence - parameter presence requirement
+-- &smimeCaps - contains the object describing how the S/MIME
+-- capabilities are presented.
+--
+-- This would be used for cases where an algorithm of an unknown
+-- type is used. In general however, one should either define
+-- a more complete algorithm structure (such as the one above)
+-- or use the TYPE-IDENTIFIER class.
+
+ALGORITHM ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Params OPTIONAL,
+ &paramPresence ParamOptions DEFAULT absent,
+ &smimeCaps SMIME-CAPS OPTIONAL
+} WITH SYNTAX {
+ IDENTIFIER &id
+ [PARAMS [TYPE &Params] ARE &paramPresence]
+ [SMIME-CAPS &smimeCaps]
+}
+
+-- AlgorithmIdentifier
+--
+-- Provides the generic structure that is used to encode algorithm
+-- identification and the parameters associated with the
+-- algorithm.
+--
+-- The first parameter represents the type of the algorithm being
+-- used.
+-- The second parameter represents an object set containing the
+-- algorithms that may occur in this situation.
+-- The initial list of required algorithms should occur to the
+-- left of an extension marker; all other algorithms should
+-- occur to the right of an extension marker.
+--
+-- The object class ALGORITHM can be used for generic unspecified
+-- items.
+-- If new ALGORITHM classes are defined, the fields &id and &Params
+-- need to be present as fields in the object in order to use
+-- this parameterized type.
+--
+-- Example:
+-- SignatureAlgorithmIdentifier ::=
+-- AlgorithmIdentifier{SIGNATURE-ALGORITHM, {SignatureAlgSet}}
+
+AlgorithmIdentifier{ALGORITHM-TYPE, ALGORITHM-TYPE:AlgorithmSet} ::=
+ SEQUENCE {
+ algorithm ALGORITHM-TYPE.&id({AlgorithmSet}),
+ parameters ALGORITHM-TYPE.
+ &Params({AlgorithmSet}{@algorithm}) OPTIONAL
+ }
+
+-- S/MIME Capabilities
+--
+-- We have moved the SMIME-CAPS from the module for RFC 3851 to here
+-- because it is used in RFC 4262 (X.509 Certificate Extension for
+-- S/MIME Capabilities)
+--
+--
+-- This class is used to represent an S/MIME capability. S/MIME
+-- capabilities are used to represent what algorithm capabilities
+-- an individual has. The classic example was the content encryption
+-- algorithm RC2 where the algorithm id and the RC2 key lengths
+-- supported needed to be advertised, but the IV used is not fixed.
+-- Thus, for RC2 we used
+--
+-- cap-RC2CBC SMIME-CAPS ::= {
+-- TYPE INTEGER ( 40 | 128 ) IDENTIFIED BY rc2-cbc }
+--
+-- where 40 and 128 represent the RC2 key length in number of bits.
+--
+-- Another example where information needs to be shown is for
+-- RSA-OAEP where only specific hash functions or mask generation
+-- functions are supported, but the saltLength is specified by the
+-- sender and not the recipient. In this case, one can either
+-- generate a number of capability items,
+-- or a new S/MIME capability type could be generated where
+-- multiple hash functions could be specified.
+--
+--
+-- SMIME-CAP
+--
+-- This class is used to associate the type that describes the
+-- capabilities with the object identifier.
+--
+
+SMIME-CAPS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL
+}
+WITH SYNTAX { [TYPE &Type] IDENTIFIED BY &id }
+
+--
+-- Generic type - this is used for defining values.
+--
+
+-- Define a single S/MIME capability encoding
+
+SMIMECapability{SMIME-CAPS:CapabilitySet} ::= SEQUENCE {
+ capabilityID SMIME-CAPS.&id({CapabilitySet}),
+ parameters SMIME-CAPS.&Type({CapabilitySet}
+ {@capabilityID}) OPTIONAL
+}
+
+-- Define a sequence of S/MIME capability values
+
+SMIMECapabilities { SMIME-CAPS:CapabilitySet } ::=
+ SEQUENCE SIZE (1..MAX) OF SMIMECapability{{CapabilitySet} }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/AttributeCertificateVersion1-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/AttributeCertificateVersion1-2009.asn1
new file mode 100644
index 0000000000..46b431af40
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/AttributeCertificateVersion1-2009.asn1
@@ -0,0 +1,59 @@
+ AttributeCertificateVersion1-2009
+ {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-v1AttrCert-02(49)}
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ SIGNATURE-ALGORITHM, ALGORITHM, AlgorithmIdentifier{}
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ AttributeSet{}, Extensions{}, EXTENSION, ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57) }
+
+ CertificateSerialNumber, UniqueIdentifier, SIGNED{}
+ FROM PKIX1Explicit-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51) }
+
+ GeneralNames
+ FROM PKIX1Implicit-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59) }
+
+ AttCertValidityPeriod, IssuerSerial
+ FROM PKIXAttributeCertificate-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-attribute-cert-02(47) } ;
+
+ -- Definition extracted from X.509-1997 [X.509-97], but
+ -- different type names are used to avoid collisions.
+
+ AttributeCertificateV1 ::= SIGNED{AttributeCertificateInfoV1}
+
+ AttributeCertificateInfoV1 ::= SEQUENCE {
+ version AttCertVersionV1 DEFAULT v1,
+ subject CHOICE {
+ baseCertificateID [0] IssuerSerial,
+ -- associated with a Public Key Certificate
+ subjectName [1] GeneralNames },
+ -- associated with a name
+ issuer GeneralNames,
+ signature AlgorithmIdentifier{SIGNATURE-ALGORITHM, {...}},
+ serialNumber CertificateSerialNumber,
+ attCertValidityPeriod AttCertValidityPeriod,
+ attributes SEQUENCE OF AttributeSet{{AttrList}},
+ issuerUniqueID UniqueIdentifier OPTIONAL,
+ extensions Extensions{{AttributeCertExtensionsV1}} OPTIONAL }
+
+ AttCertVersionV1 ::= INTEGER { v1(0) }
+
+ AttrList ATTRIBUTE ::= {...}
+ AttributeCertExtensionsV1 EXTENSION ::= {...}
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/AuthenticationFramework.asn1
index 5cfa9062f0..5cfa9062f0 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/AuthenticationFramework.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/BasicAccessControl.asn1
index d8b2b687ae..d8b2b687ae 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/BasicAccessControl.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/CertificateExtensions.asn1
index 0daf2208e9..0daf2208e9 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/CertificateExtensions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Character-Coding-Attributes.asn1
index 04060cf060..04060cf060 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Character-Coding-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Character-Presentation-Attributes.asn1
index aed48ac26b..aed48ac26b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Character-Presentation-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Character-Profile-Attributes.asn1
index 7ba5bf194a..7ba5bf194a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Character-Profile-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Colour-Attributes.asn1
index 24c7fafc38..24c7fafc38 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Colour-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntax-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntax-2009.asn1
new file mode 100644
index 0000000000..3e350294be
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntax-2009.asn1
@@ -0,0 +1,463 @@
+ CryptographicMessageSyntax-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-9(9) smime(16) modules(0) id-mod-cms-2004-02(41) }
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ ParamOptions, DIGEST-ALGORITHM, SIGNATURE-ALGORITHM,
+ PUBLIC-KEY, KEY-DERIVATION, KEY-WRAP, MAC-ALGORITHM,
+ KEY-AGREE, KEY-TRANSPORT, CONTENT-ENCRYPTION, ALGORITHM,
+ AlgorithmIdentifier
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+ SignatureAlgs, MessageDigestAlgs, KeyAgreementAlgs,
+ MessageAuthAlgs, KeyWrapAlgs, ContentEncryptionAlgs,
+ KeyTransportAlgs, KeyDerivationAlgs, KeyAgreePublicKeys
+ FROM CryptographicMessageSyntaxAlgorithms-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cmsalg-2001-02(37) }
+
+ Certificate, CertificateList, CertificateSerialNumber,
+ Name, ATTRIBUTE
+ FROM PKIX1Explicit-2009
+ { iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-explicit-02(51) }
+
+ AttributeCertificate
+ FROM PKIXAttributeCertificate-2009
+ { iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-attribute-cert-02(47) }
+
+ AttributeCertificateV1
+ FROM AttributeCertificateVersion1-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-v1AttrCert-02(49) } ;
+
+ -- Cryptographic Message Syntax
+
+ -- The following are used for version numbers using the ASN.1
+ -- idiom "[[n:"
+ -- Version 1 = PKCS #7
+ -- Version 2 = S/MIME V2
+ -- Version 3 = RFC 2630
+ -- Version 4 = RFC 3369
+ -- Version 5 = RFC 3852
+
+ CONTENT-TYPE ::= TYPE-IDENTIFIER
+ ContentType ::= CONTENT-TYPE.&id
+
+ ContentInfo ::= SEQUENCE {
+ contentType CONTENT-TYPE.
+ &id({ContentSet}),
+ content [0] EXPLICIT CONTENT-TYPE.
+ &Type({ContentSet}{@contentType})}
+
+ ContentSet CONTENT-TYPE ::= {
+ -- Define the set of content types to be recognized.
+ ct-Data | ct-SignedData | ct-EncryptedData | ct-EnvelopedData |
+ ct-AuthenticatedData | ct-DigestedData, ... }
+
+ SignedData ::= SEQUENCE {
+ version CMSVersion,
+ digestAlgorithms SET OF DigestAlgorithmIdentifier,
+ encapContentInfo EncapsulatedContentInfo,
+ certificates [0] IMPLICIT CertificateSet OPTIONAL,
+ crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
+ signerInfos SignerInfos }
+
+ SignerInfos ::= SET OF SignerInfo
+
+ EncapsulatedContentInfo ::= SEQUENCE {
+ eContentType CONTENT-TYPE.&id({ContentSet}),
+ eContent [0] EXPLICIT OCTET STRING
+ ( CONTAINING CONTENT-TYPE.
+ &Type({ContentSet}{@eContentType})) OPTIONAL }
+
+ SignerInfo ::= SEQUENCE {
+ version CMSVersion,
+ sid SignerIdentifier,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
+ signatureAlgorithm SignatureAlgorithmIdentifier,
+ signature SignatureValue,
+ unsignedAttrs [1] IMPLICIT Attributes
+ {{UnsignedAttributes}} OPTIONAL }
+
+ SignedAttributes ::= Attributes {{ SignedAttributesSet }}
+
+ SignerIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ ...,
+ [[3: subjectKeyIdentifier [0] SubjectKeyIdentifier ]] }
+
+ SignedAttributesSet ATTRIBUTE ::=
+ { aa-signingTime | aa-messageDigest | aa-contentType, ... }
+
+ UnsignedAttributes ATTRIBUTE ::= { aa-countersignature, ... }
+
+ SignatureValue ::= OCTET STRING
+
+ EnvelopedData ::= SEQUENCE {
+ version CMSVersion,
+ originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ recipientInfos RecipientInfos,
+ encryptedContentInfo EncryptedContentInfo,
+ ...,
+ [[2: unprotectedAttrs [1] IMPLICIT Attributes
+ {{ UnprotectedAttributes }} OPTIONAL ]] }
+
+ OriginatorInfo ::= SEQUENCE {
+ certs [0] IMPLICIT CertificateSet OPTIONAL,
+ crls [1] IMPLICIT RevocationInfoChoices OPTIONAL }
+
+ RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo
+
+ EncryptedContentInfo ::= SEQUENCE {
+ contentType CONTENT-TYPE.&id({ContentSet}),
+ contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL }
+
+ -- If you want to do constraints, you might use:
+ -- EncryptedContentInfo ::= SEQUENCE {
+ -- contentType CONTENT-TYPE.&id({ContentSet}),
+ -- contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ -- encryptedContent [0] IMPLICIT ENCRYPTED {CONTENT-TYPE.
+ -- &Type({ContentSet}{@contentType}) OPTIONAL }
+ -- ENCRYPTED {ToBeEncrypted} ::= OCTET STRING ( CONSTRAINED BY
+ -- { ToBeEncrypted } )
+
+ UnprotectedAttributes ATTRIBUTE ::= { ... }
+
+ RecipientInfo ::= CHOICE {
+ ktri KeyTransRecipientInfo,
+ ...,
+ [[3: kari [1] KeyAgreeRecipientInfo ]],
+ [[4: kekri [2] KEKRecipientInfo]],
+ [[5: pwri [3] PasswordRecipientInfo,
+ ori [4] OtherRecipientInfo ]] }
+
+ EncryptedKey ::= OCTET STRING
+
+ KeyTransRecipientInfo ::= SEQUENCE {
+ version CMSVersion, -- always set to 0 or 2
+ rid RecipientIdentifier,
+ keyEncryptionAlgorithm AlgorithmIdentifier
+ {KEY-TRANSPORT, {KeyTransportAlgorithmSet}},
+ encryptedKey EncryptedKey }
+
+ KeyTransportAlgorithmSet KEY-TRANSPORT ::= { KeyTransportAlgs, ... }
+
+ RecipientIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ ...,
+ [[2: subjectKeyIdentifier [0] SubjectKeyIdentifier ]] }
+ KeyAgreeRecipientInfo ::= SEQUENCE {
+ version CMSVersion, -- always set to 3
+ originator [0] EXPLICIT OriginatorIdentifierOrKey,
+ ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
+ keyEncryptionAlgorithm AlgorithmIdentifier
+ {KEY-AGREE, {KeyAgreementAlgorithmSet}},
+ recipientEncryptedKeys RecipientEncryptedKeys }
+
+ KeyAgreementAlgorithmSet KEY-AGREE ::= { KeyAgreementAlgs, ... }
+
+ OriginatorIdentifierOrKey ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [0] SubjectKeyIdentifier,
+ originatorKey [1] OriginatorPublicKey }
+
+ OriginatorPublicKey ::= SEQUENCE {
+ algorithm AlgorithmIdentifier {PUBLIC-KEY, {OriginatorKeySet}},
+ publicKey BIT STRING }
+
+ OriginatorKeySet PUBLIC-KEY ::= { KeyAgreePublicKeys, ... }
+
+ RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey
+
+ RecipientEncryptedKey ::= SEQUENCE {
+ rid KeyAgreeRecipientIdentifier,
+ encryptedKey EncryptedKey }
+
+ KeyAgreeRecipientIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ rKeyId [0] IMPLICIT RecipientKeyIdentifier }
+
+ RecipientKeyIdentifier ::= SEQUENCE {
+ subjectKeyIdentifier SubjectKeyIdentifier,
+ date GeneralizedTime OPTIONAL,
+ other OtherKeyAttribute OPTIONAL }
+
+ SubjectKeyIdentifier ::= OCTET STRING
+
+ KEKRecipientInfo ::= SEQUENCE {
+ version CMSVersion, -- always set to 4
+ kekid KEKIdentifier,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey }
+
+ KEKIdentifier ::= SEQUENCE {
+ keyIdentifier OCTET STRING,
+ date GeneralizedTime OPTIONAL,
+ other OtherKeyAttribute OPTIONAL }
+ PasswordRecipientInfo ::= SEQUENCE {
+ version CMSVersion, -- always set to 0
+ keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
+ OPTIONAL,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey }
+
+ OTHER-RECIPIENT ::= TYPE-IDENTIFIER
+
+ OtherRecipientInfo ::= SEQUENCE {
+ oriType OTHER-RECIPIENT.
+ &id({SupportedOtherRecipInfo}),
+ oriValue OTHER-RECIPIENT.
+ &Type({SupportedOtherRecipInfo}{@oriType})}
+
+ SupportedOtherRecipInfo OTHER-RECIPIENT ::= { ... }
+
+ DigestedData ::= SEQUENCE {
+ version CMSVersion,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ encapContentInfo EncapsulatedContentInfo,
+ digest Digest, ... }
+
+ Digest ::= OCTET STRING
+
+ EncryptedData ::= SEQUENCE {
+ version CMSVersion,
+ encryptedContentInfo EncryptedContentInfo,
+ ...,
+ [[2: unprotectedAttrs [1] IMPLICIT Attributes
+ {{UnprotectedAttributes}} OPTIONAL ]] }
+
+ AuthenticatedData ::= SEQUENCE {
+ version CMSVersion,
+ originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ recipientInfos RecipientInfos,
+ macAlgorithm MessageAuthenticationCodeAlgorithm,
+ digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+ encapContentInfo EncapsulatedContentInfo,
+ authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
+ mac MessageAuthenticationCode,
+ unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
+
+ AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ {{AuthAttributeSet}}
+
+ AuthAttributeSet ATTRIBUTE ::= { aa-contentType | aa-messageDigest
+ | aa-signingTime, ...}
+ MessageAuthenticationCode ::= OCTET STRING
+
+ UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ {{UnauthAttributeSet}}
+
+ UnauthAttributeSet ATTRIBUTE ::= {...}
+
+ --
+ -- General algorithm definitions
+ --
+
+ DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ {DIGEST-ALGORITHM, {DigestAlgorithmSet}}
+
+ DigestAlgorithmSet DIGEST-ALGORITHM ::= {
+ CryptographicMessageSyntaxAlgorithms-2009.MessageDigestAlgs, ... }
+
+ SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
+ {SIGNATURE-ALGORITHM, {SignatureAlgorithmSet}}
+
+ SignatureAlgorithmSet SIGNATURE-ALGORITHM ::=
+ { SignatureAlgs, ... }
+
+ KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ {KEY-WRAP, {KeyEncryptionAlgorithmSet}}
+
+ KeyEncryptionAlgorithmSet KEY-WRAP ::= { KeyWrapAlgs, ... }
+
+ ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ {CONTENT-ENCRYPTION, {ContentEncryptionAlgorithmSet}}
+
+ ContentEncryptionAlgorithmSet CONTENT-ENCRYPTION ::=
+ { ContentEncryptionAlgs, ... }
+
+ MessageAuthenticationCodeAlgorithm ::= AlgorithmIdentifier
+ {MAC-ALGORITHM, {MessageAuthenticationCodeAlgorithmSet}}
+
+ MessageAuthenticationCodeAlgorithmSet MAC-ALGORITHM ::=
+ { MessageAuthAlgs, ... }
+
+ KeyDerivationAlgorithmIdentifier ::= AlgorithmIdentifier
+ {KEY-DERIVATION, {KeyDerivationAlgs, ...}}
+
+ RevocationInfoChoices ::= SET OF RevocationInfoChoice
+
+ RevocationInfoChoice ::= CHOICE {
+ crl CertificateList,
+ ...,
+ [[5: other [1] IMPLICIT OtherRevocationInfoFormat ]] }
+
+ OTHER-REVOK-INFO ::= TYPE-IDENTIFIER
+
+ OtherRevocationInfoFormat ::= SEQUENCE {
+ otherRevInfoFormat OTHER-REVOK-INFO.
+ &id({SupportedOtherRevokInfo}),
+ otherRevInfo OTHER-REVOK-INFO.
+ &Type({SupportedOtherRevokInfo}{@otherRevInfoFormat})}
+
+ SupportedOtherRevokInfo OTHER-REVOK-INFO ::= { ... }
+
+ CertificateChoices ::= CHOICE {
+ certificate Certificate,
+ extendedCertificate [0] IMPLICIT ExtendedCertificate,
+ -- Obsolete
+ ...,
+ [[3: v1AttrCert [1] IMPLICIT AttributeCertificateV1]],
+ -- Obsolete
+ [[4: v2AttrCert [2] IMPLICIT AttributeCertificateV2]],
+ [[5: other [3] IMPLICIT OtherCertificateFormat]] }
+
+ AttributeCertificateV2 ::= AttributeCertificate
+
+ OTHER-CERT-FMT ::= TYPE-IDENTIFIER
+
+ OtherCertificateFormat ::= SEQUENCE {
+ otherCertFormat OTHER-CERT-FMT.
+ &id({SupportedCertFormats}),
+ otherCert OTHER-CERT-FMT.
+ &Type({SupportedCertFormats}{@otherCertFormat})}
+
+ SupportedCertFormats OTHER-CERT-FMT ::= { ... }
+
+ CertificateSet ::= SET OF CertificateChoices
+
+ IssuerAndSerialNumber ::= SEQUENCE {
+ issuer Name,
+ serialNumber CertificateSerialNumber }
+
+ CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4), v5(5) }
+
+ UserKeyingMaterial ::= OCTET STRING
+
+ KEY-ATTRIBUTE ::= TYPE-IDENTIFIER
+
+ OtherKeyAttribute ::= SEQUENCE {
+ keyAttrId KEY-ATTRIBUTE.
+
+ &id({SupportedKeyAttributes}),
+ keyAttr KEY-ATTRIBUTE.
+ &Type({SupportedKeyAttributes}{@keyAttrId})}
+
+ SupportedKeyAttributes KEY-ATTRIBUTE ::= { ... }
+
+ -- Content Type Object Identifiers
+
+ id-ct-contentInfo OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) ct(1) 6 }
+
+ ct-Data CONTENT-TYPE ::= {OCTET STRING IDENTIFIED BY id-data}
+
+ id-data OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 }
+
+ ct-SignedData CONTENT-TYPE ::=
+ { SignedData IDENTIFIED BY id-signedData}
+
+ id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 }
+
+ ct-EnvelopedData CONTENT-TYPE ::=
+ { EnvelopedData IDENTIFIED BY id-envelopedData}
+
+ id-envelopedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs7(7) 3 }
+
+ ct-DigestedData CONTENT-TYPE ::=
+ { DigestedData IDENTIFIED BY id-digestedData}
+
+ id-digestedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs7(7) 5 }
+
+ ct-EncryptedData CONTENT-TYPE ::=
+ { EncryptedData IDENTIFIED BY id-encryptedData}
+
+ id-encryptedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 }
+
+ ct-AuthenticatedData CONTENT-TYPE ::=
+ { AuthenticatedData IDENTIFIED BY id-ct-authData}
+
+ id-ct-authData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 2 }
+
+ --
+ -- The CMS Attributes
+ --
+
+ MessageDigest ::= OCTET STRING
+
+ SigningTime ::= Time
+
+ Time ::= CHOICE {
+ utcTime UTCTime,
+ generalTime GeneralizedTime }
+
+ Countersignature ::= SignerInfo
+
+ -- Attribute Object Identifiers
+
+ aa-contentType ATTRIBUTE ::=
+ { TYPE ContentType IDENTIFIED BY id-contentType }
+ id-contentType OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) 3 }
+
+ aa-messageDigest ATTRIBUTE ::=
+ { TYPE MessageDigest IDENTIFIED BY id-messageDigest}
+ id-messageDigest OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) 4 }
+
+ aa-signingTime ATTRIBUTE ::=
+ { TYPE SigningTime IDENTIFIED BY id-signingTime }
+ id-signingTime OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) 5 }
+
+ aa-countersignature ATTRIBUTE ::=
+ { TYPE Countersignature IDENTIFIED BY id-countersignature }
+ id-countersignature OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) 6 }
+
+ --
+ -- Obsolete Extended Certificate syntax from PKCS#6
+ --
+
+ ExtendedCertificateOrCertificate ::= CHOICE {
+ certificate Certificate,
+ extendedCertificate [0] IMPLICIT ExtendedCertificate }
+
+ ExtendedCertificate ::= SEQUENCE {
+ extendedCertificateInfo ExtendedCertificateInfo,
+ signatureAlgorithm SignatureAlgorithmIdentifier,
+ signature Signature }
+
+ ExtendedCertificateInfo ::= SEQUENCE {
+ version CMSVersion,
+ certificate Certificate,
+ attributes UnauthAttributes }
+
+ Signature ::= BIT STRING
+
+ Attribute{ ATTRIBUTE:AttrList } ::= SEQUENCE {
+ attrType ATTRIBUTE.
+ &id({AttrList}),
+ attrValues SET OF ATTRIBUTE.
+ &Type({AttrList}{@attrType}) }
+
+ Attributes { ATTRIBUTE:AttrList } ::=
+ SET SIZE (1..MAX) OF Attribute {{ AttrList }}
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntaxAlgorithms-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntaxAlgorithms-2009.asn1
new file mode 100644
index 0000000000..72e8b270db
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/CryptographicMessageSyntaxAlgorithms-2009.asn1
@@ -0,0 +1,248 @@
+ CryptographicMessageSyntaxAlgorithms-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cmsalg-2001-02(37) }
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ ParamOptions, DIGEST-ALGORITHM, SIGNATURE-ALGORITHM,
+ PUBLIC-KEY, KEY-DERIVATION, KEY-WRAP, MAC-ALGORITHM,
+ KEY-AGREE, KEY-TRANSPORT, CONTENT-ENCRYPTION, ALGORITHM,
+ AlgorithmIdentifier{}, SMIME-CAPS
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ pk-rsa, pk-dh, pk-dsa, rsaEncryption, DHPublicKey, dhpublicnumber
+ FROM PKIXAlgs-2009
+ {iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56)}
+
+ cap-RC2CBC
+ FROM SecureMimeMessageV3dot1-2009
+ {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-msg-v3dot1-02(39)};
+
+ -- 2. Hash algorithms in this document
+
+ MessageDigestAlgs DIGEST-ALGORITHM ::= {
+ -- mda-md5 | mda-sha1,
+ ... }
+
+ -- 3. Signature algorithms in this document
+
+ SignatureAlgs SIGNATURE-ALGORITHM ::= {
+ -- See RFC 3279
+ -- sa-dsaWithSHA1 | sa-rsaWithMD5 | sa-rsaWithSHA1,
+ ... }
+
+ -- 4. Key Management Algorithms
+ -- 4.1 Key Agreement Algorithms
+
+ KeyAgreementAlgs KEY-AGREE ::= { kaa-esdh | kaa-ssdh, ...}
+ KeyAgreePublicKeys PUBLIC-KEY ::= { pk-dh, ...}
+
+ -- 4.2 Key Transport Algorithms
+
+ KeyTransportAlgs KEY-TRANSPORT ::= { kt-rsa, ... }
+
+ -- 4.3 Symmetric Key-Encryption Key Algorithms
+
+ KeyWrapAlgs KEY-WRAP ::= { kwa-3DESWrap | kwa-RC2Wrap, ... }
+
+ -- 4.4 Key Derivation Algorithms
+
+ KeyDerivationAlgs KEY-DERIVATION ::= { kda-PBKDF2, ... }
+
+ -- 5. Content Encryption Algorithms
+
+ ContentEncryptionAlgs CONTENT-ENCRYPTION ::=
+ { cea-3DES-cbc | cea-RC2-cbc, ... }
+
+ -- 6. Message Authentication Code Algorithms
+
+ MessageAuthAlgs MAC-ALGORITHM ::= { maca-hMAC-SHA1, ... }
+
+ -- S/MIME Capabilities for these items
+
+ SMimeCaps SMIME-CAPS ::= {
+ kaa-esdh.&smimeCaps |
+ kaa-ssdh.&smimeCaps |
+ kt-rsa.&smimeCaps |
+ kwa-3DESWrap.&smimeCaps |
+ kwa-RC2Wrap.&smimeCaps |
+ cea-3DES-cbc.&smimeCaps |
+ cea-RC2-cbc.&smimeCaps |
+ maca-hMAC-SHA1.&smimeCaps,
+ ...}
+
+ --
+ --
+ --
+
+ -- Algorithm Identifiers
+
+ -- rsaEncryption OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ -- us(840) rsadsi(113549) pkcs(1) pkcs-1(1) 1 }
+
+ id-alg-ESDH OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 5 }
+
+ id-alg-SSDH OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 10 }
+
+ id-alg-CMS3DESwrap OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 6 }
+
+ id-alg-CMSRC2wrap OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 7 }
+
+ des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) encryptionAlgorithm(3) 7 }
+
+ rc2-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+ rsadsi(113549) encryptionAlgorithm(3) 2 }
+
+ hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) mechanisms(5) 8 1 2 }
+
+ id-PBKDF2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) pkcs-5(5) 12 }
+
+ -- Algorithm Identifier Parameter Types
+
+ KeyWrapAlgorithm ::=
+ AlgorithmIdentifier {KEY-WRAP, {KeyWrapAlgs }}
+
+ RC2wrapParameter ::= RC2ParameterVersion
+ RC2ParameterVersion ::= INTEGER
+
+ CBCParameter ::= IV
+
+ IV ::= OCTET STRING -- exactly 8 octets
+
+ RC2CBCParameter ::= SEQUENCE {
+ rc2ParameterVersion INTEGER (1..256),
+ iv OCTET STRING } -- exactly 8 octets
+
+ maca-hMAC-SHA1 MAC-ALGORITHM ::= {
+ IDENTIFIER hMAC-SHA1
+ PARAMS TYPE NULL ARE preferredAbsent
+ IS-KEYED-MAC TRUE
+ SMIME-CAPS {IDENTIFIED BY hMAC-SHA1}
+ }
+
+ PBKDF2-PRFsAlgorithmIdentifier ::= AlgorithmIdentifier{ ALGORITHM,
+ {PBKDF2-PRFs} }
+
+ alg-hMAC-SHA1 ALGORITHM ::=
+ { IDENTIFIER hMAC-SHA1 PARAMS TYPE NULL ARE required }
+
+ PBKDF2-PRFs ALGORITHM ::= { alg-hMAC-SHA1, ... }
+
+ PBKDF2-SaltSources ALGORITHM ::= { ... }
+
+ PBKDF2-SaltSourcesAlgorithmIdentifier ::=
+ AlgorithmIdentifier {ALGORITHM, {PBKDF2-SaltSources}}
+
+ defaultPBKDF2 PBKDF2-PRFsAlgorithmIdentifier ::=
+ { algorithm alg-hMAC-SHA1.&id, parameters NULL:NULL }
+
+ PBKDF2-params ::= SEQUENCE {
+ salt CHOICE {
+ specified OCTET STRING,
+ otherSource PBKDF2-SaltSourcesAlgorithmIdentifier },
+ iterationCount INTEGER (1..MAX),
+ keyLength INTEGER (1..MAX) OPTIONAL,
+ prf PBKDF2-PRFsAlgorithmIdentifier DEFAULT
+ defaultPBKDF2
+ }
+
+ --
+ -- This object is included for completeness. It should not be used
+ -- for encoding of signatures, but was sometimes used in older
+ -- versions of CMS for encoding of RSA signatures.
+ --
+ --
+ -- sa-rsa SIGNATURE-ALGORITHM ::= {
+ -- IDENTIFIER rsaEncryption
+ -- - - value is not ASN.1 encoded
+ -- PARAMS TYPE NULL ARE required
+ -- HASHES {mda-sha1 | mda-md5, ...}
+ -- PUBLIC-KEYS { pk-rsa}
+ -- }
+ --
+ -- No ASN.1 encoding is applied to the signature value
+ -- for these items
+
+ kaa-esdh KEY-AGREE ::= {
+ IDENTIFIER id-alg-ESDH
+ PARAMS TYPE KeyWrapAlgorithm ARE required
+ PUBLIC-KEYS { pk-dh }
+ -- UKM is not ASN.1 encoded
+ UKM ARE optional
+ SMIME-CAPS {TYPE KeyWrapAlgorithm IDENTIFIED BY id-alg-ESDH}
+ }
+
+ kaa-ssdh KEY-AGREE ::= {
+ IDENTIFIER id-alg-SSDH
+ PARAMS TYPE KeyWrapAlgorithm ARE required
+ PUBLIC-KEYS {pk-dh}
+ -- UKM is not ASN.1 encoded
+ UKM ARE optional
+ SMIME-CAPS {TYPE KeyWrapAlgorithm IDENTIFIED BY id-alg-SSDH}
+ }
+
+ dh-public-number OBJECT IDENTIFIER ::= dhpublicnumber
+
+ pk-originator-dh PUBLIC-KEY ::= {
+ IDENTIFIER dh-public-number
+ KEY DHPublicKey
+ PARAMS ARE absent
+ CERT-KEY-USAGE {keyAgreement, encipherOnly, decipherOnly}
+ }
+
+ kwa-3DESWrap KEY-WRAP ::= {
+ IDENTIFIER id-alg-CMS3DESwrap
+ PARAMS TYPE NULL ARE required
+ SMIME-CAPS {IDENTIFIED BY id-alg-CMS3DESwrap}
+ }
+
+ kwa-RC2Wrap KEY-WRAP ::= {
+ IDENTIFIER id-alg-CMSRC2wrap
+ PARAMS TYPE RC2wrapParameter ARE required
+ SMIME-CAPS { IDENTIFIED BY id-alg-CMSRC2wrap }
+ }
+
+ kda-PBKDF2 KEY-DERIVATION ::= {
+ IDENTIFIER id-PBKDF2
+ PARAMS TYPE PBKDF2-params ARE required
+ -- No S/MIME caps defined
+ }
+
+ cea-3DES-cbc CONTENT-ENCRYPTION ::= {
+ IDENTIFIER des-ede3-cbc
+ PARAMS TYPE IV ARE required
+ SMIME-CAPS { IDENTIFIED BY des-ede3-cbc }
+ }
+
+ cea-RC2-cbc CONTENT-ENCRYPTION ::= {
+ IDENTIFIER rc2-cbc
+ PARAMS TYPE RC2CBCParameter ARE required
+ SMIME-CAPS cap-RC2CBC
+ }
+
+ kt-rsa KEY-TRANSPORT ::= {
+ IDENTIFIER rsaEncryption
+ PARAMS TYPE NULL ARE required
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS {IDENTIFIED BY rsaEncryption}
+ }
+
+ -- S/MIME Capabilities - most have no label.
+
+ cap-3DESwrap SMIME-CAPS ::= { IDENTIFIED BY id-alg-CMS3DESwrap }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DOR-definition.asn1
index cd3330dc56..cd3330dc56 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DOR-definition.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DSAOperationalAttributeTypes.asn1
index df5e8489ea..df5e8489ea 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DSAOperationalAttributeTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Default-Value-Lists.asn1
index ef1187ba8c..ef1187ba8c 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Default-Value-Lists.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryAbstractService.asn1
index 5a5d310729..5a5d310729 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryAbstractService.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryAccessProtocol.asn1
index 10d6979f6d..10d6979f6d 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryAccessProtocol.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryInformationShadowProtocol.asn1
index 91c0a865f7..91c0a865f7 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryInformationShadowProtocol.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryOperationalBindingManagementProtocol.asn1
index e3e1f95621..e3e1f95621 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryOperationalBindingManagementProtocol.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryOperationalBindingTypes.asn1
index 9df5d2783a..9df5d2783a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryOperationalBindingTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryProtectionMappings.asn1
index 37c6cac261..37c6cac261 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryProtectionMappings.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryShadowAbstractService.asn1
index acbb692b6f..acbb692b6f 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectoryShadowAbstractService.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectorySystemProtocol.asn1
index cace79d109..cace79d109 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DirectorySystemProtocol.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/DistributedOperations.asn1
index 72e791f10c..72e791f10c 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/DistributedOperations.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Document-Profile-Descriptor.asn1
index d8c15b7afa..d8c15b7afa 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Document-Profile-Descriptor.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/EnhancedSecurity.asn1
index 9991a59454..9991a59454 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/EnhancedSecurity.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/EnrollmentMessageSyntax-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/EnrollmentMessageSyntax-2009.asn1
new file mode 100644
index 0000000000..17a45a0a6b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/EnrollmentMessageSyntax-2009.asn1
@@ -0,0 +1,543 @@
+ EnrollmentMessageSyntax-2009
+ {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0) id-mod-cmc2002-02(53)}
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ EXPORTS ALL;
+ IMPORTS
+
+ AttributeSet{}, Extension{}, EXTENSION, ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}
+ AlgorithmIdentifier{}, DIGEST-ALGORITHM, KEY-WRAP, KEY-DERIVATION,
+ MAC-ALGORITHM, SIGNATURE-ALGORITHM, PUBLIC-KEY
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ CertificateSerialNumber, GeneralName, CRLReason, ReasonFlags,
+ CertExtensions
+ FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+
+ Name, id-pkix, PublicKeyAlgorithms, SignatureAlgorithms
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)}
+
+ ContentInfo, IssuerAndSerialNumber, CONTENT-TYPE
+ FROM CryptographicMessageSyntax-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cms-2004-02(41)}
+
+ CertReqMsg, PKIPublicationInfo, CertTemplate
+ FROM PKIXCRMF-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-crmf2005-02(55)}
+
+ mda-sha1
+ FROM PKIXAlgs-2009
+ { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56)}
+
+ kda-PBKDF2, maca-hMAC-SHA1
+ FROM CryptographicMessageSyntaxAlgorithms-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cmsalg-2001-02(37) }
+
+ mda-sha256
+ FROM PKIX1-PSS-OAEP-Algorithms-2009
+ { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-rsa-pkalgs-02(54) } ;
+
+ -- CMS Content types defined in this document
+ CMC-ContentTypes CONTENT-TYPE ::= { ct-PKIData | ct-PKIResponse, ... }
+
+ -- Signature Algorithms defined in this document
+
+ SignatureAlgs SIGNATURE-ALGORITHM ::= { sa-noSignature }
+
+ -- CMS Unsigned Attributes
+
+ CMC-UnsignedAtts ATTRIBUTE ::= { aa-cmc-unsignedData }
+
+ --
+ --
+
+ id-cmc OBJECT IDENTIFIER ::= {id-pkix 7} -- CMC controls
+ id-cct OBJECT IDENTIFIER ::= {id-pkix 12} -- CMC content types
+
+ -- This is the content type for a request message in the protocol
+
+ ct-PKIData CONTENT-TYPE ::=
+ { PKIData IDENTIFIED BY id-cct-PKIData }
+ id-cct-PKIData OBJECT IDENTIFIER ::= { id-cct 2 }
+
+ PKIData ::= SEQUENCE {
+ controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute,
+ reqSequence SEQUENCE SIZE(0..MAX) OF TaggedRequest,
+ cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo,
+ otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg
+ }
+
+ BodyPartID ::= INTEGER(0..4294967295)
+
+ TaggedAttribute ::= SEQUENCE {
+ bodyPartID BodyPartID,
+ attrType CMC-CONTROL.&id({Cmc-Control-Set}),
+ attrValues SET OF CMC-CONTROL.
+ &Type({Cmc-Control-Set}{@attrType})
+ }
+
+ Cmc-Control-Set CMC-CONTROL ::= {
+ cmc-identityProof | cmc-dataReturn | cmc-regInfo |
+ cmc-responseInfo | cmc-queryPending | cmc-popLinkRandom |
+ cmc-popLinkWitness | cmc-identification | cmc-transactionId |
+ cmc-senderNonce | cmc-recipientNonce | cmc-statusInfo |
+ cmc-addExtensions | cmc-encryptedPOP | cmc-decryptedPOP |
+ cmc-lraPOPWitness | cmc-getCert | cmc-getCRL |
+ cmc-revokeRequest | cmc-confirmCertAcceptance |
+ cmc-statusInfoV2 | cmc-trustedAnchors | cmc-authData |
+ cmc-batchRequests | cmc-batchResponses | cmc-publishCert |
+ cmc-modCertTemplate | cmc-controlProcessed |
+ cmc-identityProofV2 | cmc-popLinkWitnessV2, ... }
+
+ OTHER-REQUEST ::= TYPE-IDENTIFIER
+
+ -- We do not define any other requests in this document;
+ -- examples might be attribute certification requests
+
+ OtherRequests OTHER-REQUEST ::= {...}
+
+ TaggedRequest ::= CHOICE {
+ tcr [0] TaggedCertificationRequest,
+ crm [1] CertReqMsg,
+ orm [2] SEQUENCE {
+ bodyPartID BodyPartID,
+ requestMessageType OTHER-REQUEST.&id({OtherRequests}),
+ requestMessageValue OTHER-REQUEST.&Type({OtherRequests}
+ {@.requestMessageType})
+ }
+ }
+
+ TaggedCertificationRequest ::= SEQUENCE {
+ bodyPartID BodyPartID,
+ certificationRequest CertificationRequest
+ }
+
+ AttributeList ATTRIBUTE ::= {at-extension-req, ...}
+
+ CertificationRequest ::= SEQUENCE {
+ certificationRequestInfo SEQUENCE {
+ version INTEGER,
+ subject Name,
+ subjectPublicKeyInfo SEQUENCE {
+ algorithm AlgorithmIdentifier{PUBLIC-KEY,
+ {PublicKeyAlgorithms}},
+ subjectPublicKey BIT STRING
+ },
+ attributes [0] IMPLICIT SET OF
+ AttributeSet{{AttributeList}}
+ },
+ signatureAlgorithm AlgorithmIdentifier
+ {SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ signature BIT STRING
+ }
+
+ TaggedContentInfo ::= SEQUENCE {
+ bodyPartID BodyPartID,
+ contentInfo ContentInfo
+ }
+
+ OTHER-MSG ::= TYPE-IDENTIFIER
+
+ -- No other messages currently defined
+
+ OtherMsgSet OTHER-MSG ::= {...}
+
+ OtherMsg ::= SEQUENCE {
+ bodyPartID BodyPartID,
+ otherMsgType OTHER-MSG.&id({OtherMsgSet}),
+ otherMsgValue OTHER-MSG.&Type({OtherMsgSet}{@otherMsgType}) }
+
+ -- This defines the response message in the protocol
+
+ ct-PKIResponse CONTENT-TYPE ::=
+ { PKIResponse IDENTIFIED BY id-cct-PKIResponse }
+ id-cct-PKIResponse OBJECT IDENTIFIER ::= { id-cct 3 }
+
+ ResponseBody ::= PKIResponse
+
+ PKIResponse ::= SEQUENCE {
+ controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute,
+ cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo,
+ otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg
+ }
+
+ CMC-CONTROL ::= TYPE-IDENTIFIER
+
+ -- The following controls have the type OCTET STRING
+
+ cmc-identityProof CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-identityProof }
+ id-cmc-identityProof OBJECT IDENTIFIER ::= {id-cmc 3}
+
+ cmc-dataReturn CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-dataReturn }
+ id-cmc-dataReturn OBJECT IDENTIFIER ::= {id-cmc 4}
+
+ cmc-regInfo CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-regInfo }
+ id-cmc-regInfo OBJECT IDENTIFIER ::= {id-cmc 18}
+
+ cmc-responseInfo CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-responseInfo }
+ id-cmc-responseInfo OBJECT IDENTIFIER ::= {id-cmc 19}
+
+ cmc-queryPending CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-queryPending }
+ id-cmc-queryPending OBJECT IDENTIFIER ::= {id-cmc 21}
+
+ cmc-popLinkRandom CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-popLinkRandom }
+ id-cmc-popLinkRandom OBJECT IDENTIFIER ::= {id-cmc 22}
+
+ cmc-popLinkWitness CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-popLinkWitness }
+ id-cmc-popLinkWitness OBJECT IDENTIFIER ::= {id-cmc 23}
+
+ -- The following controls have the type UTF8String
+
+ cmc-identification CMC-CONTROL ::=
+ { UTF8String IDENTIFIED BY id-cmc-identification }
+ id-cmc-identification OBJECT IDENTIFIER ::= {id-cmc 2}
+
+ -- The following controls have the type INTEGER
+
+ cmc-transactionId CMC-CONTROL ::=
+ { INTEGER IDENTIFIED BY id-cmc-transactionId }
+ id-cmc-transactionId OBJECT IDENTIFIER ::= {id-cmc 5}
+
+ -- The following controls have the type OCTET STRING
+
+ cmc-senderNonce CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-senderNonce }
+
+ id-cmc-senderNonce OBJECT IDENTIFIER ::= {id-cmc 6}
+
+ cmc-recipientNonce CMC-CONTROL ::=
+ { OCTET STRING IDENTIFIED BY id-cmc-recipientNonce }
+ id-cmc-recipientNonce OBJECT IDENTIFIER ::= {id-cmc 7}
+
+ -- Used to return status in a response
+
+ cmc-statusInfo CMC-CONTROL ::=
+ { CMCStatusInfo IDENTIFIED BY id-cmc-statusInfo }
+ id-cmc-statusInfo OBJECT IDENTIFIER ::= {id-cmc 1}
+
+ CMCStatusInfo ::= SEQUENCE {
+ cMCStatus CMCStatus,
+ bodyList SEQUENCE SIZE (1..MAX) OF BodyPartID,
+ statusString UTF8String OPTIONAL,
+ otherInfo CHOICE {
+ failInfo CMCFailInfo,
+ pendInfo PendInfo
+ } OPTIONAL
+ }
+
+ PendInfo ::= SEQUENCE {
+ pendToken OCTET STRING,
+ pendTime GeneralizedTime
+ }
+
+ CMCStatus ::= INTEGER {
+ success (0),
+ failed (2),
+ pending (3),
+ noSupport (4),
+ confirmRequired (5),
+ popRequired (6),
+ partial (7)
+ }
+
+ -- Note:
+ -- The spelling of unsupportedExt is corrected in this version.
+ -- In RFC 2797, it was unsuportedExt.
+
+ CMCFailInfo ::= INTEGER {
+ badAlg (0),
+ badMessageCheck (1),
+ badRequest (2),
+ badTime (3),
+ badCertId (4),
+ unsuportedExt (5),
+ mustArchiveKeys (6),
+ badIdentity (7),
+ popRequired (8),
+ popFailed (9),
+ noKeyReuse (10),
+ internalCAError (11),
+ tryLater (12),
+ authDataFail (13)
+ }
+
+ -- Used for RAs to add extensions to certification requests
+
+ cmc-addExtensions CMC-CONTROL ::=
+ { AddExtensions IDENTIFIED BY id-cmc-addExtensions }
+ id-cmc-addExtensions OBJECT IDENTIFIER ::= {id-cmc 8}
+
+ AddExtensions ::= SEQUENCE {
+ pkiDataReference BodyPartID,
+ certReferences SEQUENCE OF BodyPartID,
+ extensions SEQUENCE OF Extension{{CertExtensions}}
+ }
+
+ cmc-encryptedPOP CMC-CONTROL ::=
+ { EncryptedPOP IDENTIFIED BY id-cmc-encryptedPOP }
+ cmc-decryptedPOP CMC-CONTROL ::=
+ { DecryptedPOP IDENTIFIED BY id-cmc-decryptedPOP }
+ id-cmc-encryptedPOP OBJECT IDENTIFIER ::= {id-cmc 9}
+ id-cmc-decryptedPOP OBJECT IDENTIFIER ::= {id-cmc 10}
+
+ EncryptedPOP ::= SEQUENCE {
+ request TaggedRequest,
+ cms ContentInfo,
+ thePOPAlgID AlgorithmIdentifier{MAC-ALGORITHM, {POPAlgs}},
+ witnessAlgID AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {WitnessAlgs}},
+ witness OCTET STRING
+ }
+
+ POPAlgs MAC-ALGORITHM ::= {maca-hMAC-SHA1, ...}
+ WitnessAlgs DIGEST-ALGORITHM ::= {mda-sha1, ...}
+
+ DecryptedPOP ::= SEQUENCE {
+ bodyPartID BodyPartID,
+ thePOPAlgID AlgorithmIdentifier{MAC-ALGORITHM, {POPAlgs}},
+ thePOP OCTET STRING
+ }
+
+ cmc-lraPOPWitness CMC-CONTROL ::=
+ { LraPopWitness IDENTIFIED BY id-cmc-lraPOPWitness }
+
+ id-cmc-lraPOPWitness OBJECT IDENTIFIER ::= {id-cmc 11}
+
+ LraPopWitness ::= SEQUENCE {
+ pkiDataBodyid BodyPartID,
+ bodyIds SEQUENCE OF BodyPartID
+ }
+
+ --
+
+ cmc-getCert CMC-CONTROL ::=
+ { GetCert IDENTIFIED BY id-cmc-getCert }
+ id-cmc-getCert OBJECT IDENTIFIER ::= {id-cmc 15}
+
+ GetCert ::= SEQUENCE {
+ issuerName GeneralName,
+ serialNumber INTEGER }
+
+ cmc-getCRL CMC-CONTROL ::=
+ { GetCRL IDENTIFIED BY id-cmc-getCRL }
+ id-cmc-getCRL OBJECT IDENTIFIER ::= {id-cmc 16}
+ GetCRL ::= SEQUENCE {
+ issuerName Name,
+ cRLName GeneralName OPTIONAL,
+ time GeneralizedTime OPTIONAL,
+ reasons ReasonFlags OPTIONAL }
+
+ cmc-revokeRequest CMC-CONTROL ::=
+ { RevokeRequest IDENTIFIED BY id-cmc-revokeRequest}
+ id-cmc-revokeRequest OBJECT IDENTIFIER ::= {id-cmc 17}
+
+ RevokeRequest ::= SEQUENCE {
+ issuerName Name,
+ serialNumber INTEGER,
+ reason CRLReason,
+ invalidityDate GeneralizedTime OPTIONAL,
+ passphrase OCTET STRING OPTIONAL,
+ comment UTF8String OPTIONAL }
+
+ cmc-confirmCertAcceptance CMC-CONTROL ::=
+ { CMCCertId IDENTIFIED BY id-cmc-confirmCertAcceptance }
+ id-cmc-confirmCertAcceptance OBJECT IDENTIFIER ::= {id-cmc 24}
+
+ CMCCertId ::= IssuerAndSerialNumber
+
+ -- The following is used to request v3 extensions be added
+ -- to a certificate
+
+ at-extension-req ATTRIBUTE ::=
+ { TYPE ExtensionReq IDENTIFIED BY id-ExtensionReq }
+ id-ExtensionReq OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) pkcs-9(9) 14}
+
+ ExtensionReq ::= SEQUENCE SIZE (1..MAX) OF
+ Extension{{CertExtensions}}
+
+ -- The following allows Diffie-Hellman Certification Request
+ -- Messages to be well-formed
+
+ sa-noSignature SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER id-alg-noSignature
+ VALUE NoSignatureValue
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-sha1 }
+ }
+ id-alg-noSignature OBJECT IDENTIFIER ::= {id-pkix id-alg(6) 2}
+
+ NoSignatureValue ::= OCTET STRING
+ -- Unauthenticated attribute to carry removable data.
+
+ id-aa OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-aa(2)}
+
+ aa-cmc-unsignedData ATTRIBUTE ::=
+ { TYPE CMCUnsignedData IDENTIFIED BY id-aa-cmc-unsignedData }
+ id-aa-cmc-unsignedData OBJECT IDENTIFIER ::= {id-aa 34}
+
+ CMCUnsignedData ::= SEQUENCE {
+ bodyPartPath BodyPartPath,
+ identifier TYPE-IDENTIFIER.&id,
+ content TYPE-IDENTIFIER.&Type
+ }
+
+ -- Replaces CMC Status Info
+ --
+
+ cmc-statusInfoV2 CMC-CONTROL ::=
+ { CMCStatusInfoV2 IDENTIFIED BY id-cmc-statusInfoV2 }
+ id-cmc-statusInfoV2 OBJECT IDENTIFIER ::= {id-cmc 25}
+
+ EXTENDED-FAILURE-INFO ::= TYPE-IDENTIFIER
+
+ ExtendedFailures EXTENDED-FAILURE-INFO ::= {...}
+
+ CMCStatusInfoV2 ::= SEQUENCE {
+ cMCStatus CMCStatus,
+ bodyList SEQUENCE SIZE (1..MAX) OF
+ BodyPartReference,
+ statusString UTF8String OPTIONAL,
+ otherInfo CHOICE {
+ failInfo CMCFailInfo,
+ pendInfo PendInfo,
+ extendedFailInfo [1] SEQUENCE {
+ failInfoOID TYPE-IDENTIFIER.&id
+ ({ExtendedFailures}),
+ failInfoValue TYPE-IDENTIFIER.&Type
+ ({ExtendedFailures}
+ {@.failInfoOID})
+ }
+ } OPTIONAL
+ }
+
+ BodyPartReference ::= CHOICE {
+ bodyPartID BodyPartID,
+ bodyPartPath BodyPartPath
+ }
+
+ BodyPartPath ::= SEQUENCE SIZE (1..MAX) OF BodyPartID
+
+ -- Allow for distribution of trust anchors
+ --
+
+ cmc-trustedAnchors CMC-CONTROL ::=
+ { PublishTrustAnchors IDENTIFIED BY id-cmc-trustedAnchors }
+ id-cmc-trustedAnchors OBJECT IDENTIFIER ::= {id-cmc 26}
+
+ PublishTrustAnchors ::= SEQUENCE {
+ seqNumber INTEGER,
+ hashAlgorithm AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {HashAlgorithms}},
+ anchorHashes SEQUENCE OF OCTET STRING
+ }
+
+ HashAlgorithms DIGEST-ALGORITHM ::= {
+ mda-sha1 | mda-sha256, ...
+ }
+
+ cmc-authData CMC-CONTROL ::=
+ { AuthPublish IDENTIFIED BY id-cmc-authData }
+ id-cmc-authData OBJECT IDENTIFIER ::= {id-cmc 27}
+
+ AuthPublish ::= BodyPartID
+
+ -- These two items use BodyPartList
+
+ cmc-batchRequests CMC-CONTROL ::=
+ { BodyPartList IDENTIFIED BY id-cmc-batchRequests }
+ id-cmc-batchRequests OBJECT IDENTIFIER ::= {id-cmc 28}
+
+ cmc-batchResponses CMC-CONTROL ::=
+ { BodyPartList IDENTIFIED BY id-cmc-batchResponses }
+ id-cmc-batchResponses OBJECT IDENTIFIER ::= {id-cmc 29}
+
+ BodyPartList ::= SEQUENCE SIZE (1..MAX) OF BodyPartID
+
+ cmc-publishCert CMC-CONTROL ::=
+ { CMCPublicationInfo IDENTIFIED BY id-cmc-publishCert }
+ id-cmc-publishCert OBJECT IDENTIFIER ::= {id-cmc 30}
+
+ CMCPublicationInfo ::= SEQUENCE {
+ hashAlg AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {HashAlgorithms}},
+ certHashes SEQUENCE OF OCTET STRING,
+ pubInfo PKIPublicationInfo
+ }
+
+ cmc-modCertTemplate CMC-CONTROL ::=
+ { ModCertTemplate IDENTIFIED BY id-cmc-modCertTemplate }
+ id-cmc-modCertTemplate OBJECT IDENTIFIER ::= {id-cmc 31}
+
+ ModCertTemplate ::= SEQUENCE {
+ pkiDataReference BodyPartPath,
+ certReferences BodyPartList,
+ replace BOOLEAN DEFAULT TRUE,
+ certTemplate CertTemplate
+ }
+
+ -- Inform follow-on servers that one or more controls have
+ -- already been processed
+
+ cmc-controlProcessed CMC-CONTROL ::=
+ { ControlsProcessed IDENTIFIED BY id-cmc-controlProcessed }
+ id-cmc-controlProcessed OBJECT IDENTIFIER ::= {id-cmc 32}
+
+ ControlsProcessed ::= SEQUENCE {
+ bodyList SEQUENCE SIZE(1..MAX) OF BodyPartReference
+ }
+
+ -- Identity Proof control w/ algorithm agility
+
+ cmc-identityProofV2 CMC-CONTROL ::=
+ { IdentityProofV2 IDENTIFIED BY id-cmc-identityProofV2 }
+ id-cmc-identityProofV2 OBJECT IDENTIFIER ::= { id-cmc 33 }
+
+ IdentityProofV2 ::= SEQUENCE {
+ proofAlgID AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {WitnessAlgs}},
+ macAlgId AlgorithmIdentifier{MAC-ALGORITHM, {POPAlgs}},
+ witness OCTET STRING
+ }
+
+ cmc-popLinkWitnessV2 CMC-CONTROL ::=
+ { PopLinkWitnessV2 IDENTIFIED BY id-cmc-popLinkWitnessV2 }
+ id-cmc-popLinkWitnessV2 OBJECT IDENTIFIER ::= { id-cmc 34 }
+
+ PopLinkWitnessV2 ::= SEQUENCE {
+ keyGenAlgorithm AlgorithmIdentifier{KEY-DERIVATION,
+ {KeyDevAlgs}},
+ macAlgorithm AlgorithmIdentifier{MAC-ALGORITHM, {POPAlgs}},
+ witness OCTET STRING
+ }
+
+ KeyDevAlgs KEY-DERIVATION ::= {kda-PBKDF2, ...}
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/External-References.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/External-References.asn1
index 9a7d4936a6..9a7d4936a6 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/External-References.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/External-References.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/GULSProtectionMappings.asn1
index 9b6a426ca2..9b6a426ca2 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/GULSProtectionMappings.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/GenericProtectingTransferSyntax.asn1
index c59451dcdb..c59451dcdb 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/GenericProtectingTransferSyntax.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Coding-Attributes.asn1
index 60acbb3b5c..60acbb3b5c 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Coding-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Presentation-Attributes.asn1
index 84c1ee9851..84c1ee9851 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Presentation-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Profile-Attributes.asn1
index 28daa467e1..28daa467e1 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Geo-Gr-Profile-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/GulsSecurityExchanges.asn1
index 336b824174..336b824174 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/GulsSecurityExchanges.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/GulsSecurityTransformations.asn1
index db2725c37d..db2725c37d 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/GulsSecurityTransformations.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/HierarchicalOperationalBindings.asn1
index 4e0084b079..4e0084b079 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/HierarchicalOperationalBindings.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSAbstractService.asn1
index 3fec8ae64a..3fec8ae64a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSAbstractService.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSAutoActionTypes.asn1
index 8c0c8138e2..8c0c8138e2 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSAutoActionTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedBodyPartTypes.asn1
index 9805a6189d..9805a6189d 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedBodyPartTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedBodyPartTypes2.asn1
index b39e03c3b6..b39e03c3b6 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedBodyPartTypes2.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedVoiceBodyPartType.asn1
index 171f4b4223..171f4b4223 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSExtendedVoiceBodyPartType.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSFileTransferBodyPartType.asn1
index 59de6d1b04..59de6d1b04 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSFileTransferBodyPartType.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSForwardedContentBodyPartType.asn1
index 57faac6587..57faac6587 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSForwardedContentBodyPartType.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSForwardedReportBodyPartType.asn1
index 4e46c7679b..4e46c7679b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSForwardedReportBodyPartType.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSFunctionalObjects.asn1
index 09ef4de282..09ef4de282 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSFunctionalObjects.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSHeadingExtensions.asn1
index 752e8d05e1..752e8d05e1 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSHeadingExtensions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSInformationObjects.asn1
index 3fb0463ee7..3fb0463ee7 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSInformationObjects.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSMessageStoreAttributes.asn1
index 719bca4987..719bca4987 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSMessageStoreAttributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSObjectIdentifiers.asn1
index 6e5c01ab40..6e5c01ab40 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSObjectIdentifiers2.asn1
index 2b46b27b3e..2b46b27b3e 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSObjectIdentifiers2.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSSecurityExtensions.asn1
index 8c692ccb31..8c692ccb31 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSSecurityExtensions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSUpperBounds.asn1
index 27324f614f..27324f614f 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/IPMSUpperBounds.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn1
index b7efd7417e..b7efd7417e 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/ISO8571-FTAM.asn1
index a57a276704..a57a276704 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/ISO8571-FTAM.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/ISO9541-SN.asn1
index 0149602040..0149602040 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/ISO9541-SN.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Identifiers-and-Expressions.asn1
index bd1d8d3c48..bd1d8d3c48 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Identifiers-and-Expressions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/InformationFramework.asn1
index 813ac9c6a0..813ac9c6a0 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/InformationFramework.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Interchange-Data-Elements.asn1
index 2c78360b7b..2c78360b7b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Interchange-Data-Elements.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Layout-Descriptors.asn1
index 92c887bb06..92c887bb06 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Layout-Descriptors.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Link-Descriptors.asn1
index 64fc4436e4..64fc4436e4 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Link-Descriptors.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Location-Expressions.asn1
index 5de6491621..5de6491621 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Location-Expressions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Logical-Descriptors.asn1
index fab36bf12a..fab36bf12a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Logical-Descriptors.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MHSObjectIdentifiers.asn1
index 187c3c8ad4..187c3c8ad4 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MHSObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MHSProtocolObjectIdentifiers.asn1
index 40f53b9458..40f53b9458 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MHSProtocolObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSAbstractService.asn1
index 052b3b2041..052b3b2041 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSAbstractService.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSAccessProtocol.asn1
index b69d72b3ed..b69d72b3ed 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSAccessProtocol.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSGeneralAttributeTypes.asn1
index 99d34b2883..99d34b2883 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSGeneralAttributeTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSGeneralAutoActionTypes.asn1
index eceae4ab44..eceae4ab44 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSGeneralAutoActionTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSMatchingRules.asn1
index 37c894da86..37c894da86 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSMatchingRules.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSObjectIdentifiers.asn1
index df194f838c..df194f838c 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MSUpperBounds.asn1
index 6494fbd3ef..6494fbd3ef 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MSUpperBounds.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MTAAbstractService.asn1
index 38035c77ae..38035c77ae 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MTAAbstractService.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSAbstractService.asn1
index 68a5118bc8..68a5118bc8 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSAbstractService.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSAbstractService88.asn1
index f66d117f35..f66d117f35 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSAbstractService88.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSAccessProtocol.asn1
index 03181c5951..03181c5951 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSAccessProtocol.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSObjectIdentifiers.asn1
index 1615b241ee..1615b241ee 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSUpperBounds.asn1
index 10eac962cb..10eac962cb 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/MTSUpperBounds.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Notation.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Notation.asn1
index 96dfc39b6a..96dfc39b6a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Notation.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Notation.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/OCSP-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/OCSP-2009.asn1
new file mode 100644
index 0000000000..db500fe9a1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/OCSP-2009.asn1
@@ -0,0 +1,183 @@
+ OCSP-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-ocsp-02(48)}
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ Extensions{}, EXTENSION, ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}
+
+ AlgorithmIdentifier{}, DIGEST-ALGORITHM, SIGNATURE-ALGORITHM
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ AuthorityInfoAccessSyntax, GeneralName, CrlEntryExtensions
+ FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+
+ Name, CertificateSerialNumber, id-kp, id-ad-ocsp, Certificate
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)}
+
+ sa-dsaWithSHA1, sa-rsaWithMD2, sa-rsaWithMD5, sa-rsaWithSHA1
+ FROM PKIXAlgs-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56)};
+
+ OCSPRequest ::= SEQUENCE {
+ tbsRequest TBSRequest,
+ optionalSignature [0] EXPLICIT Signature OPTIONAL }
+
+ TBSRequest ::= SEQUENCE {
+ version [0] EXPLICIT Version DEFAULT v1,
+ requestorName [1] EXPLICIT GeneralName OPTIONAL,
+ requestList SEQUENCE OF Request,
+ requestExtensions [2] EXPLICIT Extensions {{re-ocsp-nonce |
+ re-ocsp-response, ...}} OPTIONAL }
+
+ Signature ::= SEQUENCE {
+ signatureAlgorithm AlgorithmIdentifier
+ { SIGNATURE-ALGORITHM, {...}},
+ signature BIT STRING,
+ certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+
+ Version ::= INTEGER { v1(0) }
+
+ Request ::= SEQUENCE {
+ reqCert CertID,
+ singleRequestExtensions [0] EXPLICIT Extensions
+ { {re-ocsp-service-locator,
+ ...}} OPTIONAL }
+
+ CertID ::= SEQUENCE {
+ hashAlgorithm AlgorithmIdentifier
+ {DIGEST-ALGORITHM, {...}},
+ issuerNameHash OCTET STRING, -- Hash of Issuer's DN
+ issuerKeyHash OCTET STRING, -- Hash of Issuer's public key
+ serialNumber CertificateSerialNumber }
+
+ OCSPResponse ::= SEQUENCE {
+ responseStatus OCSPResponseStatus,
+ responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+
+ OCSPResponseStatus ::= ENUMERATED {
+ successful (0), --Response has valid confirmations
+ malformedRequest (1), --Illegal confirmation request
+ internalError (2), --Internal error in issuer
+ tryLater (3), --Try again later
+ -- (4) is not used
+ sigRequired (5), --Must sign the request
+ unauthorized (6) --Request unauthorized
+ }
+
+ RESPONSE ::= TYPE-IDENTIFIER
+
+ ResponseSet RESPONSE ::= {basicResponse, ...}
+
+ ResponseBytes ::= SEQUENCE {
+ responseType RESPONSE.
+ &id ({ResponseSet}),
+ response OCTET STRING (CONTAINING RESPONSE.
+ &Type({ResponseSet}{@responseType}))}
+
+ basicResponse RESPONSE ::=
+ { BasicOCSPResponse IDENTIFIED BY id-pkix-ocsp-basic }
+
+ BasicOCSPResponse ::= SEQUENCE {
+ tbsResponseData ResponseData,
+ signatureAlgorithm AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ {sa-dsaWithSHA1 | sa-rsaWithSHA1 |
+ sa-rsaWithMD5 | sa-rsaWithMD2, ...}},
+ signature BIT STRING,
+ certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+
+ ResponseData ::= SEQUENCE {
+ version [0] EXPLICIT Version DEFAULT v1,
+ responderID ResponderID,
+ producedAt GeneralizedTime,
+ responses SEQUENCE OF SingleResponse,
+ responseExtensions [1] EXPLICIT Extensions
+ {{re-ocsp-nonce, ...}} OPTIONAL }
+
+ ResponderID ::= CHOICE {
+ byName [1] Name,
+ byKey [2] KeyHash }
+
+ KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ -- (excluding the tag and length fields)
+
+ SingleResponse ::= SEQUENCE {
+ certID CertID,
+ certStatus CertStatus,
+ thisUpdate GeneralizedTime,
+ nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
+ singleExtensions [1] EXPLICIT Extensions{{re-ocsp-crl |
+ re-ocsp-archive-cutoff |
+ CrlEntryExtensions, ...}
+ } OPTIONAL }
+
+ CertStatus ::= CHOICE {
+ good [0] IMPLICIT NULL,
+ revoked [1] IMPLICIT RevokedInfo,
+ unknown [2] IMPLICIT UnknownInfo }
+
+ RevokedInfo ::= SEQUENCE {
+ revocationTime GeneralizedTime,
+ revocationReason [0] EXPLICIT CRLReason OPTIONAL }
+
+ UnknownInfo ::= NULL
+
+ CRLReason ::= INTEGER
+
+ ArchiveCutoff ::= GeneralizedTime
+
+ AcceptableResponses ::= SEQUENCE OF RESPONSE.&id({ResponseSet})
+
+ ServiceLocator ::= SEQUENCE {
+ issuer Name,
+ locator AuthorityInfoAccessSyntax }
+
+ CrlID ::= SEQUENCE {
+ crlUrl [0] EXPLICIT IA5String OPTIONAL,
+ crlNum [1] EXPLICIT INTEGER OPTIONAL,
+ crlTime [2] EXPLICIT GeneralizedTime OPTIONAL }
+
+ -- Request Extensions
+
+ re-ocsp-nonce EXTENSION ::= { SYNTAX OCTET STRING IDENTIFIED
+ BY id-pkix-ocsp-nonce }
+ re-ocsp-response EXTENSION ::= { SYNTAX AcceptableResponses IDENTIFIED
+ BY id-pkix-ocsp-response }
+ re-ocsp-service-locator EXTENSION ::= { SYNTAX ServiceLocator
+ IDENTIFIED BY
+ id-pkix-ocsp-service-locator }
+
+ -- Response Extensions
+
+ re-ocsp-crl EXTENSION ::= { SYNTAX CrlID IDENTIFIED BY
+ id-pkix-ocsp-crl }
+ re-ocsp-archive-cutoff EXTENSION ::= { SYNTAX ArchiveCutoff
+ IDENTIFIED BY
+ id-pkix-ocsp-archive-cutoff }
+
+ -- Object Identifiers
+
+ id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
+ id-pkix-ocsp OBJECT IDENTIFIER ::= id-ad-ocsp
+ id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
+ id-pkix-ocsp-nonce OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 }
+ id-pkix-ocsp-crl OBJECT IDENTIFIER ::= { id-pkix-ocsp 3 }
+ id-pkix-ocsp-response OBJECT IDENTIFIER ::= { id-pkix-ocsp 4 }
+ id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
+ id-pkix-ocsp-archive-cutoff OBJECT IDENTIFIER ::= { id-pkix-ocsp 6 }
+ id-pkix-ocsp-service-locator OBJECT IDENTIFIER ::= { id-pkix-ocsp 7 }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/OLD-PKCS7.asn1
index ac449b59c7..ab555200bb 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/OLD-PKCS7.asn1
@@ -3,7 +3,7 @@
-- This Annex contains a module of PKCS#7 ASN.1 definitions conforming to current ASN.1 standards rather than the obsolescent (and now deprecated) 1988/90 version of ASN.1 used in version 1.5 of PKCS#7.
-- Extensions to PKCS#7 defined in RFC 2630 are included.
-- If differences are found between the ASN.1 in the following module and that in PKCS#7, the latter is definitive.
-PKCS7 {iso member-body usa(840) rsadsi(113549) pkcs(1) 7
+OLD-PKCS7 {iso member-body usa(840) rsadsi(113549) pkcs(1) 7
module(0) -- module not currently defined in PKCS#7 --} DEFINITIONS IMPLICIT
TAGS ::=
BEGIN
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/ObjectIdentifiers.asn1
index b4f91f50c5..b4f91f50c5 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/ObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/OperationalBindingManagement.asn1
index 2044feb155..2044feb155 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/OperationalBindingManagement.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-10.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-10.asn1
new file mode 100644
index 0000000000..a5fd0fefb9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-10.asn1
@@ -0,0 +1,56 @@
+ PKCS-10
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkcs10-2009(69)}
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ AlgorithmIdentifier{}, DIGEST-ALGORITHM, SIGNATURE-ALGORITHM,
+ PUBLIC-KEY
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ ATTRIBUTE, Name
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)};
+
+ -- Certificate requests
+ CertificationRequestInfo ::= SEQUENCE {
+ version INTEGER { v1(0) } (v1, ... ),
+ subject Name,
+ subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+ attributes [0] Attributes{{ CRIAttributes }}
+ }
+
+ SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE {
+ algorithm AlgorithmIdentifier {PUBLIC-KEY, {IOSet}},
+ subjectPublicKey BIT STRING
+ }
+
+ PKInfoAlgorithms PUBLIC-KEY ::= {
+ ... -- add any locally defined algorithms here -- }
+
+ Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
+
+ CRIAttributes ATTRIBUTE ::= {
+ ... -- add any locally defined attributes here -- }
+
+ Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
+ type ATTRIBUTE.&id({IOSet}),
+ values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
+ }
+
+ CertificationRequest ::= SEQUENCE {
+ certificationRequestInfo CertificationRequestInfo,
+ signatureAlgorithm AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ { SignatureAlgorithms }},
+ signature BIT STRING
+ }
+
+ SignatureAlgorithms SIGNATURE-ALGORITHM ::= {
+ ... -- add any locally defined algorithms here -- }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-12.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-12.asn1
new file mode 100644
index 0000000000..5b37a552f9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-12.asn1
@@ -0,0 +1,174 @@
+PKCS-12 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs-12(12) modules(0) pkcs-12(1)}
+
+-- $Revision$
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL
+-- All types and values defined in this module is exported for use in
+-- other ASN.1 modules.
+
+IMPORTS
+
+informationFramework
+ FROM UsefulDefinitions {joint-iso-itu-t(2) ds(5) module(1)
+ usefulDefinitions(0) 3}
+
+ATTRIBUTE
+ FROM InformationFramework informationFramework
+
+ContentInfo, DigestInfo
+ FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)}
+
+PrivateKeyInfo, EncryptedPrivateKeyInfo
+ FROM PKCS-8 {iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-8(8) modules(1) pkcs-8(1)}
+
+pkcs-9, friendlyName, localKeyId, certTypes, crlTypes
+ FROM PKCS-9 {iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-9(9) modules(0) pkcs-9(1)};
+
+-- Object identifiers
+
+rsadsi OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) rsadsi(113549)}
+pkcs OBJECT IDENTIFIER ::= {rsadsi pkcs(1)}
+pkcs-12 OBJECT IDENTIFIER ::= {pkcs 12}
+pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1}
+pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1}
+pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2}
+pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3}
+pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4}
+pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5}
+pbewithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6}
+
+bagtypes OBJECT IDENTIFIER ::= {pkcs-12 10 1}
+
+-- The PFX PDU
+
+PFX ::= SEQUENCE {
+ version INTEGER {v3(3)}(v3,...),
+ authSafe ContentInfo,
+ macData MacData OPTIONAL
+}
+
+MacData ::= SEQUENCE {
+ mac DigestInfo,
+ macSalt OCTET STRING,
+ iterations INTEGER DEFAULT 1
+-- Note: The default is for historical reasons and its use is
+-- deprecated. A higher value, like 1024 is recommended.
+}
+
+AuthenticatedSafe ::= SEQUENCE OF ContentInfo
+ -- Data if unencrypted
+ -- EncryptedData if password-encrypted
+ -- EnvelopedData if public key-encrypted
+
+SafeContents ::= SEQUENCE OF SafeBag
+
+SafeBag ::= SEQUENCE {
+ bagId BAG-TYPE.&id ({PKCS12BagSet}),
+ bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
+ bagAttributes SET OF PKCS12Attribute OPTIONAL
+}
+
+-- Bag types
+
+keyBag BAG-TYPE ::=
+ {KeyBag IDENTIFIED BY {bagtypes 1}}
+pkcs8ShroudedKeyBag BAG-TYPE ::=
+ {PKCS8ShroudedKeyBag IDENTIFIED BY {bagtypes 2}}
+certBag BAG-TYPE ::=
+ {CertBag IDENTIFIED BY {bagtypes 3}}
+crlBag BAG-TYPE ::=
+ {CRLBag IDENTIFIED BY {bagtypes 4}}
+secretBag BAG-TYPE ::=
+ {SecretBag IDENTIFIED BY {bagtypes 5}}
+safeContentsBag BAG-TYPE ::=
+ {SafeContents IDENTIFIED BY {bagtypes 6}}
+
+PKCS12BagSet BAG-TYPE ::= {
+ keyBag |
+ pkcs8ShroudedKeyBag |
+ certBag |
+ crlBag |
+ secretBag |
+ safeContentsBag,
+ ... -- For future extensions
+}
+
+BAG-TYPE ::= TYPE-IDENTIFIER
+
+-- KeyBag
+
+KeyBag ::= PrivateKeyInfo
+
+-- Shrouded KeyBag
+
+PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo
+
+-- CertBag
+
+CertBag ::= SEQUENCE {
+ certId BAG-TYPE.&id ({CertTypes}),
+ certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId})
+}
+
+x509Certificate BAG-TYPE ::=
+ {OCTET STRING IDENTIFIED BY {certTypes 1}}
+ -- DER-encoded X.509 certificate stored in OCTET STRING
+sdsiCertificate BAG-TYPE ::=
+ {IA5String IDENTIFIED BY {certTypes 2}}
+ -- Base64-encoded SDSI certificate stored in IA5String
+
+CertTypes BAG-TYPE ::= {
+ x509Certificate |
+ sdsiCertificate,
+ ... -- For future extensions
+}
+
+-- CRLBag
+
+CRLBag ::= SEQUENCE {
+ crlId BAG-TYPE.&id ({CRLTypes}),
+ crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId})
+}
+
+x509CRL BAG-TYPE ::=
+ {OCTET STRING IDENTIFIED BY {crlTypes 1}}
+ -- DER-encoded X.509 CRL stored in OCTET STRING
+
+CRLTypes BAG-TYPE ::= {
+ x509CRL,
+ ... -- For future extensions
+}
+
+-- Secret Bag
+
+SecretBag ::= SEQUENCE {
+ secretTypeId BAG-TYPE.&id ({SecretTypes}),
+ secretValue [0] EXPLICIT BAG-TYPE.&Type ({SecretTypes}{@secretTypeId})
+}
+
+SecretTypes BAG-TYPE ::= {
+ ... -- For future extensions
+}
+
+-- Attributes
+
+PKCS12Attribute ::= SEQUENCE {
+ attrId ATTRIBUTE.&id ({PKCS12AttrSet}),
+ attrValues SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId})
+} -- This type is compatible with the X.500 type 'Attribute'
+
+PKCS12AttrSet ATTRIBUTE ::= {
+ friendlyName |
+ localKeyId,
+ ... -- Other attributes are allowed
+}
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-5.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-5.asn1
new file mode 100644
index 0000000000..91b0dc36bf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-5.asn1
@@ -0,0 +1,202 @@
+-- PKCS #5 v2.1 ASN.1 Module
+-- Revised October 27, 2012
+
+-- This module has been checked for conformance with the
+-- ASN.1 standard by the OSS ASN.1 Tools
+
+PKCS-5 {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-5(5) modules(16)
+ pkcs5v2-1(2)}
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+-- ============================
+-- Basic object identifiers
+-- ============================
+
+nistAlgorithms OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) 4}
+oiw OBJECT IDENTIFIER ::= {iso(1) identified-organization(3) 14}
+rsadsi OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) 113549}
+pkcs OBJECT IDENTIFIER ::= {rsadsi 1}
+pkcs-5 OBJECT IDENTIFIER ::= {pkcs 5}
+
+
+-- ============================
+-- Basic types and classes
+-- ============================
+
+AlgorithmIdentifier { ALGORITHM-IDENTIFIER:InfoObjectSet } ::= SEQUENCE {
+ algorithm ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
+ parameters ALGORITHM-IDENTIFIER.&Type({InfoObjectSet} {@algorithm}) OPTIONAL
+}
+
+ALGORITHM-IDENTIFIER ::= TYPE-IDENTIFIER
+
+
+-- ============================
+-- PBKDF2
+-- ============================
+
+PBKDF2Algorithms ALGORITHM-IDENTIFIER ::=
+ { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ...}
+
+id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
+
+algid-hmacWithSHA1 AlgorithmIdentifier {{PBKDF2-PRFs}} ::=
+ {algorithm id-hmacWithSHA1, parameters NULL : NULL}
+
+PBKDF2-params ::= SEQUENCE {
+ salt CHOICE {
+ specified OCTET STRING,
+ otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
+ },
+ iterationCount INTEGER (1..MAX),
+ keyLength INTEGER (1..MAX) OPTIONAL,
+ prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
+}
+
+PBKDF2-SaltSources ALGORITHM-IDENTIFIER ::= { ... }
+
+PBKDF2-PRFs ALGORITHM-IDENTIFIER ::= {
+ {NULL IDENTIFIED BY id-hmacWithSHA1} |
+ {NULL IDENTIFIED BY id-hmacWithSHA224} |
+ {NULL IDENTIFIED BY id-hmacWithSHA256} |
+ {NULL IDENTIFIED BY id-hmacWithSHA384} |
+ {NULL IDENTIFIED BY id-hmacWithSHA512} |
+ {NULL IDENTIFIED BY id-hmacWithSHA512-224} |
+ {NULL IDENTIFIED BY id-hmacWithSHA512-256},
+ ...
+}
+
+
+-- ============================
+ -- PBES1
+-- ============================
+
+PBES1Algorithms ALGORITHM-IDENTIFIER ::= {
+ {PBEParameter IDENTIFIED BY pbeWithMD2AndDES-CBC} |
+ {PBEParameter IDENTIFIED BY pbeWithMD2AndRC2-CBC} |
+ {PBEParameter IDENTIFIED BY pbeWithMD5AndDES-CBC} |
+ {PBEParameter IDENTIFIED BY pbeWithMD5AndRC2-CBC} |
+ {PBEParameter IDENTIFIED BY pbeWithSHA1AndDES-CBC} |
+ {PBEParameter IDENTIFIED BY pbeWithSHA1AndRC2-CBC},
+ ...
+}
+
+pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1}
+pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4}
+pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3}
+pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6}
+pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10}
+pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11}
+
+PBEParameter ::= SEQUENCE {
+ salt OCTET STRING (SIZE(8)),
+ iterationCount INTEGER
+}
+
+
+-- ============================
+-- PBES2
+-- ============================
+
+PBES2Algorithms ALGORITHM-IDENTIFIER ::= {
+ {PBES2-params IDENTIFIED BY id-PBES2},
+ ...
+}
+
+id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
+
+PBES2-params ::= SEQUENCE {
+ keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+ encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
+}
+
+PBES2-KDFs ALGORITHM-IDENTIFIER ::= {
+ {PBKDF2-params IDENTIFIED BY id-PBKDF2},
+ ...
+}
+
+PBES2-Encs ALGORITHM-IDENTIFIER ::= { ... }
+
+
+-- ============================
+-- PBMAC1
+-- ============================
+
+PBMAC1Algorithms ALGORITHM-IDENTIFIER ::= {
+ {PBMAC1-params IDENTIFIED BY id-PBMAC1},
+ ...
+}
+
+id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14}
+
+PBMAC1-params ::= SEQUENCE {
+ keyDerivationFunc AlgorithmIdentifier {{PBMAC1-KDFs}},
+ messageAuthScheme AlgorithmIdentifier {{PBMAC1-MACs}}
+}
+
+PBMAC1-KDFs ALGORITHM-IDENTIFIER ::= {
+ {PBKDF2-params IDENTIFIED BY id-PBKDF2},
+ ...
+}
+
+PBMAC1-MACs ALGORITHM-IDENTIFIER ::= { ... }
+
+-- ============================
+-- Supporting techniques
+-- ============================
+
+digestAlgorithm OBJECT IDENTIFIER ::= {rsadsi 2}
+encryptionAlgorithm OBJECT IDENTIFIER ::= {rsadsi 3}
+
+SupportingAlgorithms ALGORITHM-IDENTIFIER ::= {
+ {NULL IDENTIFIED BY id-hmacWithSHA1} |
+ {OCTET STRING (SIZE(8)) IDENTIFIED BY desCBC} |
+ {OCTET STRING (SIZE(8)) IDENTIFIED BY des-EDE3-CBC} |
+ {RC2-CBC-Parameter IDENTIFIED BY rc2CBC} |
+ {RC5-CBC-Parameters IDENTIFIED BY rc5-CBC-PAD} |
+ {OCTET STRING (SIZE(16)) IDENTIFIED BY aes128-CBC-PAD} |
+ {OCTET STRING (SIZE(16)) IDENTIFIED BY aes192-CBC-PAD} |
+ {OCTET STRING (SIZE(16)) IDENTIFIED BY aes256-CBC-PAD},
+ ...
+}
+
+id-hmacWithSHA1 OBJECT IDENTIFIER ::= {digestAlgorithm 7}
+id-hmacWithSHA224 OBJECT IDENTIFIER ::= {digestAlgorithm 8}
+id-hmacWithSHA256 OBJECT IDENTIFIER ::= {digestAlgorithm 9}
+id-hmacWithSHA384 OBJECT IDENTIFIER ::= {digestAlgorithm 10}
+id-hmacWithSHA512 OBJECT IDENTIFIER ::= {digestAlgorithm 11}
+id-hmacWithSHA512-224 OBJECT IDENTIFIER ::= {digestAlgorithm 12}
+id-hmacWithSHA512-256 OBJECT IDENTIFIER ::= {digestAlgorithm 13}
+
+-- from OIW
+desCBC OBJECT IDENTIFIER ::= {oiw secsig(3) algorithms(2) 7}
+
+des-EDE3-CBC OBJECT IDENTIFIER ::= {encryptionAlgorithm 7}
+
+rc2CBC OBJECT IDENTIFIER ::= {encryptionAlgorithm 2}
+
+RC2-CBC-Parameter ::= SEQUENCE {
+ rc2ParameterVersion INTEGER OPTIONAL,
+ iv OCTET STRING (SIZE(8))
+}
+
+rc5-CBC-PAD OBJECT IDENTIFIER ::= {encryptionAlgorithm 9}
+
+RC5-CBC-Parameters ::= SEQUENCE {
+ version INTEGER {v1-0(16)} (v1-0),
+ rounds INTEGER (8..127),
+ blockSizeInBits INTEGER (64 | 128),
+ iv OCTET STRING OPTIONAL
+}
+
+aes OBJECT IDENTIFIER ::= { nistAlgorithms 1 }
+aes128-CBC-PAD OBJECT IDENTIFIER ::= { aes 2 }
+aes192-CBC-PAD OBJECT IDENTIFIER ::= { aes 22 }
+aes256-CBC-PAD OBJECT IDENTIFIER ::= { aes 42 }
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-7.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-7.asn1
new file mode 100644
index 0000000000..4cea8db240
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-7.asn1
@@ -0,0 +1,326 @@
+PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)
+ modules(0) pkcs-7(1)}
+
+DEFINITIONS EXPLICIT TAGS ::=
+BEGIN
+
+--
+-- 3. Definitions
+--
+
+-- EXPORTS All;
+
+IMPORTS
+
+informationFramework, authenticationFramework
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+
+ Name, ATTRIBUTE
+ FROM InformationFramework informationFramework
+
+ ALGORITHM, Certificate, CertificateSerialNumber,
+ CertificateList
+ FROM AuthenticationFramework authenticationFramework
+
+ contentType, messageDigest, signingTime, counterSignature
+ FROM PKCS-9 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs-9(9) modules(0) pkcs-9(1)};
+--
+-- 6. Useful types
+--
+
+-- Also defined in X.509
+-- Redeclared here as a parameterized type
+AlgorithmIdentifier {ALGORITHM:IOSet} ::= SEQUENCE {
+ algorithm ALGORITHM.&id({IOSet}),
+ parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
+}
+
+-- Also defined in X.501
+-- Redeclared here as a parameterized type
+Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
+ type ATTRIBUTE.&id({IOSet}),
+ values SET SIZE (1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
+}
+
+CertificateRevocationLists ::=
+ SET OF CertificateList
+
+Certificates ::=
+ SEQUENCE OF Certificate
+
+CRLSequence ::=
+ SEQUENCE OF CertificateList
+
+ContentEncryptionAlgorithmIdentifier ::=
+ AlgorithmIdentifier {{ContentEncryptionAlgorithms}}
+
+ContentEncryptionAlgorithms ALGORITHM ::= {
+ ... -- add any application-specific algorithms here
+}
+
+DigestAlgorithmIdentifier ::=
+ AlgorithmIdentifier {{DigestAlgorithms}}
+
+DigestAlgorithms ALGORITHM ::= {
+ ... -- add any application-specific algorithms here
+}
+
+DigestEncryptionAlgorithmIdentifier ::=
+ AlgorithmIdentifier {{DigestEncryptionAlgorithms}}
+
+DigestEncryptionAlgorithms ALGORITHM ::= {
+ ... -- add any application-specific algorithms here
+}
+
+ExtendedCertificateOrCertificate ::= CHOICE {
+ certificate Certificate, -- X.509
+ extendedCertificate [0] IMPLICIT ExtendedCertificate -- PKCS#6
+}
+
+ExtendedCertificate ::= Certificate -- cheating
+
+ExtendedCertificatesAndCertificates ::=
+ SET OF ExtendedCertificateOrCertificate
+
+IssuerAndSerialNumber ::= SEQUENCE {
+ issuer Name,
+ serialNumber CertificateSerialNumber
+}
+
+KeyEncryptionAlgorithmIdentifier ::=
+ AlgorithmIdentifier {{KeyEncryptionAlgorithms}}
+
+KeyEncryptionAlgorithms ALGORITHM ::= {
+ ... -- add any application-specific algorithms here
+}
+
+--
+-- 7. General syntax
+--
+
+ContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ content [0] EXPLICIT CONTENTS.&Type({Contents}{@contentType})
+OPTIONAL
+}
+
+CONTENTS ::= TYPE-IDENTIFIER
+
+Contents CONTENTS ::= {
+ {Data IDENTIFIED BY data} |
+ {SignedData IDENTIFIED BY signedData} |
+ {EnvelopedData IDENTIFIED BY envelopedData} |
+ {SignedAndEnvelopedData IDENTIFIED BY signedAndEnvelopedData} |
+ {DigestedData IDENTIFIED BY digestedData} |
+ {EncryptedData IDENTIFIED BY encryptedData},
+ ... -- add any application-specific types/contents here
+}
+
+ContentType ::= CONTENTS.&id({Contents})
+
+--
+-- 8. Data content type
+--
+
+Data ::= OCTET STRING
+
+--
+-- 9. Signed-data content type
+--
+
+SignedData ::= SEQUENCE {
+ version INTEGER {sdVer1(1), sdVer2(2)} (sdVer1 | sdVer2),
+ digestAlgorithms
+ DigestAlgorithmIdentifiers,
+ contentInfo ContentInfo,
+ certificates CHOICE {
+ certSet [0] IMPLICIT ExtendedCertificatesAndCertificates,
+ certSequence [2] IMPLICIT Certificates
+ } OPTIONAL,
+ crls CHOICE {
+ crlSet [1] IMPLICIT CertificateRevocationLists,
+ crlSequence [3] IMPLICIT CRLSequence
+ } OPTIONAL,
+ signerInfos SignerInfos
+} (WITH COMPONENTS { ..., version (sdVer1),
+ digestAlgorithms (WITH COMPONENTS { ..., daSet PRESENT }),
+ certificates (WITH COMPONENTS { ..., certSequence ABSENT }),
+ crls (WITH COMPONENTS { ..., crlSequence ABSENT }),
+ signerInfos (WITH COMPONENTS { ..., siSet PRESENT })
+ } |
+ WITH COMPONENTS { ..., version (sdVer2),
+ digestAlgorithms (WITH COMPONENTS { ..., daSequence PRESENT }),
+ certificates (WITH COMPONENTS { ..., certSet ABSENT }),
+ crls (WITH COMPONENTS { ..., crlSet ABSENT }),
+ signerInfos (WITH COMPONENTS { ..., siSequence PRESENT })
+})
+
+SignerInfos ::= CHOICE {
+ siSet SET OF SignerInfo,
+ siSequence SEQUENCE OF SignerInfo
+}
+
+DigestAlgorithmIdentifiers ::= CHOICE {
+ daSet SET OF DigestAlgorithmIdentifier,
+ daSequence SEQUENCE OF DigestAlgorithmIdentifier
+}
+
+SignerInfo ::= SEQUENCE {
+ version INTEGER {siVer1(1), siVer2(2)} (siVer1 | siVer2),
+ issuerAndSerialNumber
+ IssuerAndSerialNumber,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ authenticatedAttributes CHOICE {
+ aaSet [0] IMPLICIT SET OF Attribute {{Authenticated}},
+ aaSequence [2] EXPLICIT SEQUENCE OF Attribute {{Authenticated}}
+ -- Explicit because easier to compute digest on sequence of attributes and then reuse
+ -- encoded sequence in aaSequence.
+ } OPTIONAL,
+ digestEncryptionAlgorithm
+ DigestEncryptionAlgorithmIdentifier,
+ encryptedDigest EncryptedDigest,
+ unauthenticatedAttributes CHOICE {
+ uaSet [1] IMPLICIT SET OF Attribute {{Unauthenticated}},
+ uaSequence [3] IMPLICIT SEQUENCE OF Attribute {{Unauthenticated}}
+ } OPTIONAL
+} (WITH COMPONENTS { ..., version (siVer1),
+ authenticatedAttributes (WITH COMPONENTS { ..., aaSequence ABSENT }),
+ unauthenticatedAttributes (WITH COMPONENTS { ..., uaSequence ABSENT })
+} | WITH COMPONENTS { ..., version (siVer2),
+ authenticatedAttributes (WITH COMPONENTS { ..., aaSet ABSENT }),
+ unauthenticatedAttributes (WITH COMPONENTS { ..., uaSet ABSENT })
+})
+
+Authenticated ATTRIBUTE ::= {
+ contentType |
+ messageDigest,
+ ..., -- add application-specific attributes here
+ signingTime
+}
+
+Unauthenticated ATTRIBUTE ::= {
+ ..., -- add application-specific attributes here
+ counterSignature
+}
+
+EncryptedDigest ::= OCTET STRING
+
+DigestInfo ::= SEQUENCE {
+ digestAlgorithm DigestAlgorithmIdentifier,
+ digest Digest
+}
+
+Digest ::= OCTET STRING
+
+--
+-- 10. Enveloped-data content type
+--
+
+EnvelopedData ::= SEQUENCE {
+ version INTEGER {edVer0(0), edVer1(1)} (edVer0 | edVer1),
+ recipientInfos RecipientInfos,
+ encryptedContentInfo
+ EncryptedContentInfo
+} (WITH COMPONENTS { ..., version (edVer0),
+ recipientInfos (WITH COMPONENTS { ..., riSet PRESENT })
+} | WITH COMPONENTS { ..., version (edVer1),
+ recipientInfos (WITH COMPONENTS { ..., riSequence PRESENT })
+})
+
+RecipientInfos ::= CHOICE {
+ riSet SET OF RecipientInfo,
+ riSequence SEQUENCE OF RecipientInfo
+}
+
+EncryptedContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ contentEncryptionAlgorithm
+ ContentEncryptionAlgorithmIdentifier,
+ encryptedContent
+ [0] IMPLICIT EncryptedContent OPTIONAL
+}
+
+EncryptedContent ::= OCTET STRING
+
+RecipientInfo ::= SEQUENCE {
+ version INTEGER {riVer0(0)} (riVer0),
+ issuerAndSerialNumber
+ IssuerAndSerialNumber,
+ keyEncryptionAlgorithm
+ KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey
+}
+
+EncryptedKey ::= OCTET STRING
+
+--
+-- 11. Signed-and-enveloped-data content type
+--
+
+SignedAndEnvelopedData ::= SEQUENCE {
+ version INTEGER {seVer1(1), seVer2(2)} (seVer1 | seVer2),
+ recipientInfos RecipientInfos,
+ digestAlgorithms
+ DigestAlgorithmIdentifiers,
+ encryptedContentInfo
+ EncryptedContentInfo,
+ certificates CHOICE {
+ certSet [0] IMPLICIT ExtendedCertificatesAndCertificates,
+ certSequence [2] IMPLICIT Certificates
+ } OPTIONAL,
+ crls CHOICE {
+ crlSet [1] IMPLICIT CertificateRevocationLists,
+ crlSequence [3] IMPLICIT CRLSequence
+ } OPTIONAL,
+ signerInfos SignerInfos
+} (WITH COMPONENTS { ..., version (seVer1),
+ recipientInfos (WITH COMPONENTS { ..., riSet PRESENT }),
+ digestAlgorithms (WITH COMPONENTS { ..., daSet PRESENT }),
+ certificates (WITH COMPONENTS { ..., certSequence ABSENT }),
+ crls (WITH COMPONENTS { ..., crlSequence ABSENT }),
+ signerInfos (WITH COMPONENTS { ..., siSet PRESENT })
+} |
+ WITH COMPONENTS { ..., version (seVer2),
+ recipientInfos (WITH COMPONENTS { ..., riSequence PRESENT }),
+ digestAlgorithms (WITH COMPONENTS { ..., daSequence PRESENT }),
+ certificates (WITH COMPONENTS { ..., certSet ABSENT }),
+ crls (WITH COMPONENTS { ..., crlSet ABSENT }),
+ signerInfos (WITH COMPONENTS { ..., siSequence PRESENT })
+})
+
+--
+-- 12. Digested-data content type
+--
+
+DigestedData ::= SEQUENCE {
+ version INTEGER {ddVer0(0)} (ddVer0),
+ digestAlgorithm DigestAlgorithmIdentifier,
+ contentInfo ContentInfo,
+ digest Digest
+}
+
+--
+-- 13. Encrypted-data content type
+--
+
+EncryptedData ::= SEQUENCE {
+ version INTEGER {edVer0(0)} (edVer0),
+ encryptedContentInfo EncryptedContentInfo
+}
+
+--
+-- 14. Object Identifiers
+--
+
+pkcs-7 OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
+data OBJECT IDENTIFIER ::= { pkcs-7 1 }
+signedData OBJECT IDENTIFIER ::= { pkcs-7 2 }
+envelopedData OBJECT IDENTIFIER ::= { pkcs-7 3 }
+signedAndEnvelopedData OBJECT IDENTIFIER ::= { pkcs-7 4 }
+digestedData OBJECT IDENTIFIER ::= { pkcs-7 5 }
+encryptedData OBJECT IDENTIFIER ::= { pkcs-7 6 }
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-8.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-8.asn1
new file mode 100644
index 0000000000..266f90170a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-8.asn1
@@ -0,0 +1,61 @@
+PKCS-8 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-8(8)
+ modules(1) pkcs-8(1)}
+
+-- $Revision: 1.5 $
+
+-- This module has been checked for conformance with the ASN.1
+-- standard by the OSS ASN.1 Tools
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS All --
+-- All types and values defined in this module is exported for use in other
+-- ASN.1 modules.
+
+IMPORTS
+
+informationFramework
+ FROM UsefulDefinitions {joint-iso-itu-t(2) ds(5) module(1)
+ usefulDefinitions(0) 3}
+
+Attribute
+ FROM InformationFramework informationFramework
+
+AlgorithmIdentifier, ALGORITHM-IDENTIFIER
+ FROM PKCS-5 {iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-5(5) modules(16) pkcs-5(1)};
+
+-- Private-key information syntax
+
+PrivateKeyInfo ::= SEQUENCE {
+ version Version,
+ privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
+ privateKey PrivateKey,
+ attributes [0] Attributes OPTIONAL }
+
+Version ::= INTEGER {v1(0)} (v1,...)
+
+PrivateKey ::= OCTET STRING
+
+Attributes ::= SET OF Attribute
+
+-- Encrypted private-key information syntax
+
+EncryptedPrivateKeyInfo ::= SEQUENCE {
+ encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
+ encryptedData EncryptedData
+}
+
+EncryptedData ::= OCTET STRING
+
+PrivateKeyAlgorithms ALGORITHM-IDENTIFIER ::= {
+ ... -- For local profiles
+}
+
+KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
+ ... -- For local profiles
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-9.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-9.asn1
new file mode 100644
index 0000000000..cd561f4d7e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS-9.asn1
@@ -0,0 +1,391 @@
+PKCS-9 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+pkcs-9(9) modules(0) pkcs-9(1)}
+
+-- $Revision$
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS All --
+-- All types and values defined in this module is exported for use in
+-- other ASN.1 modules.
+
+IMPORTS
+
+informationFramework, authenticationFramework, selectedAttributeTypes,
+ upperBounds , id-at
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+
+ub-name
+ FROM UpperBounds upperBounds
+
+OBJECT-CLASS, ATTRIBUTE, MATCHING-RULE, Attribute, top, objectIdentifierMatch
+ FROM InformationFramework informationFramework
+
+ALGORITHM, Extensions, Time
+ FROM AuthenticationFramework authenticationFramework
+
+DirectoryString, octetStringMatch, caseIgnoreMatch, caseExactMatch,
+ generalizedTimeMatch, integerMatch, serialNumber
+ FROM SelectedAttributeTypes selectedAttributeTypes
+
+ContentInfo, SignerInfo
+ FROM CryptographicMessageSyntax-2009 {iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) modules(0) cms(1)}
+
+EncryptedPrivateKeyInfo
+ FROM PKCS-8 {iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-8(8) modules(1) pkcs-8(1)}
+
+PFX
+ FROM PKCS-12 {iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-12(12) modules(0) pkcs-12(1)}
+
+-- PKCS15Token
+-- FROM PKCS-15 {iso(1) member-body(2) us(840) rsadsi(113549)
+-- pkcs(1) pkcs-15(15) modules(1) pkcs-15(1)}
+;
+
+-- Upper bounds
+pkcs-9-ub-pkcs9String INTEGER ::= 255
+pkcs-9-ub-emailAddress INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-unstructuredName INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-unstructuredAddress INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-challengePassword INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-friendlyName INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-signingDescription INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-match INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-ub-pseudonym INTEGER ::= ub-name
+pkcs-9-ub-placeOfBirth INTEGER ::= ub-name
+
+-- Object Identifiers
+
+pkcs-9 OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840)
+ rsadsi(113549) pkcs(1) 9}
+
+ -- Main arcs
+pkcs-9-mo OBJECT IDENTIFIER ::= {pkcs-9 0} -- Modules branch
+pkcs-9-oc OBJECT IDENTIFIER ::= {pkcs-9 24} -- Object class branch
+pkcs-9-at OBJECT IDENTIFIER ::= {pkcs-9 25} -- Attribute branch, for new attributes
+pkcs-9-sx OBJECT IDENTIFIER ::= {pkcs-9 26} -- For syntaxes (RFC 2252)
+pkcs-9-mr OBJECT IDENTIFIER ::= {pkcs-9 27} -- Matching rules
+
+ -- Object classes
+pkcs-9-oc-pkcsEntity OBJECT IDENTIFIER ::= {pkcs-9-oc 1}
+pkcs-9-oc-naturalPerson OBJECT IDENTIFIER ::= {pkcs-9-oc 2}
+
+ -- Attributes
+pkcs-9-at-emailAddress OBJECT IDENTIFIER ::= {pkcs-9 1}
+pkcs-9-at-unstructuredName OBJECT IDENTIFIER ::= {pkcs-9 2}
+pkcs-9-at-contentType OBJECT IDENTIFIER ::= {pkcs-9 3}
+pkcs-9-at-messageDigest OBJECT IDENTIFIER ::= {pkcs-9 4}
+pkcs-9-at-signingTime OBJECT IDENTIFIER ::= {pkcs-9 5}
+pkcs-9-at-counterSignature OBJECT IDENTIFIER ::= {pkcs-9 6}
+pkcs-9-at-challengePassword OBJECT IDENTIFIER ::= {pkcs-9 7}
+pkcs-9-at-unstructuredAddress OBJECT IDENTIFIER ::= {pkcs-9 8}
+pkcs-9-at-extendedCertificateAttributes OBJECT IDENTIFIER ::= {pkcs-9 9}
+
+-- Obsolete (?) attribute identifiers, purportedly from "tentative
+-- PKCS #9 draft"
+-- pkcs-9-at-issuerAndSerialNumber OBJECT IDENTIFIER ::= {pkcs-9 10}
+-- pkcs-9-at-passwordCheck OBJECT IDENTIFIER ::= {pkcs-9 11}
+-- pkcs-9-at-publicKey OBJECT IDENTIFIER ::= {pkcs-9 12}
+
+pkcs-9-at-signingDescription OBJECT IDENTIFIER ::= {pkcs-9 13}
+pkcs-9-at-extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14}
+pkcs-9-at-smimeCapabilities OBJECT IDENTIFIER ::= {pkcs-9 15}
+
+-- Unused (?)
+-- pkcs-9-at-? OBJECT IDENTIFIER ::= {pkcs-9 17}
+-- pkcs-9-at-? OBJECT IDENTIFIER ::= {pkcs-9 18}
+-- pkcs-9-at-? OBJECT IDENTIFIER ::= {pkcs-9 19}
+
+pkcs-9-at-friendlyName OBJECT IDENTIFIER ::= {pkcs-9 20}
+pkcs-9-at-localKeyId OBJECT IDENTIFIER ::= {pkcs-9 21}
+pkcs-9-at-userPKCS12 OBJECT IDENTIFIER ::= {2 16 840 1 113730 3 1 216}
+pkcs-9-at-pkcs15Token OBJECT IDENTIFIER ::= {pkcs-9-at 1}
+pkcs-9-at-encryptedPrivateKeyInfo OBJECT IDENTIFIER ::= {pkcs-9-at 2}
+pkcs-9-at-randomNonce OBJECT IDENTIFIER ::= {pkcs-9-at 3}
+pkcs-9-at-sequenceNumber OBJECT IDENTIFIER ::= {pkcs-9-at 4}
+pkcs-9-at-pkcs7PDU OBJECT IDENTIFIER ::= {pkcs-9-at 5}
+
+ -- IETF PKIX Attribute branch
+ietf-at OBJECT IDENTIFIER ::= {1 3 6 1 5 5 7 9}
+
+pkcs-9-at-dateOfBirth OBJECT IDENTIFIER ::= {ietf-at 1}
+pkcs-9-at-placeOfBirth OBJECT IDENTIFIER ::= {ietf-at 2}
+pkcs-9-at-gender OBJECT IDENTIFIER ::= {ietf-at 3}
+pkcs-9-at-countryOfCitizenship OBJECT IDENTIFIER ::= {ietf-at 4}
+pkcs-9-at-countryOfResidence OBJECT IDENTIFIER ::= {ietf-at 5}
+
+ -- Syntaxes (for use with LDAP accessible directories)
+pkcs-9-sx-pkcs9String OBJECT IDENTIFIER ::= {pkcs-9-sx 1}
+pkcs-9-sx-signingTime OBJECT IDENTIFIER ::= {pkcs-9-sx 2}
+
+ -- Matching rules
+pkcs-9-mr-caseIgnoreMatch OBJECT IDENTIFIER ::= {pkcs-9-mr 1}
+pkcs-9-mr-signingTimeMatch OBJECT IDENTIFIER ::= {pkcs-9-mr 2}
+
+ -- Arcs with attributes defined elsewhere
+smime OBJECT IDENTIFIER ::= {pkcs-9 16}
+ -- Main arc for S/MIME (RFC 2633)
+certTypes OBJECT IDENTIFIER ::= {pkcs-9 22}
+ -- Main arc for certificate types defined in PKCS #12
+crlTypes OBJECT IDENTIFIER ::= {pkcs-9 23}
+ -- Main arc for crl types defined in PKCS #12
+
+ -- Other object identifiers
+id-at-pseudonym OBJECT IDENTIFIER ::= {id-at 65}
+
+-- Useful types
+
+PKCS9String {INTEGER : maxSize} ::= CHOICE {
+ ia5String IA5String (SIZE(1..maxSize)),
+ directoryString DirectoryString {maxSize}
+}
+
+-- Object classes
+
+pkcsEntity OBJECT-CLASS ::= {
+ SUBCLASS OF { top }
+ KIND auxiliary
+ MAY CONTAIN { PKCSEntityAttributeSet }
+ ID pkcs-9-oc-pkcsEntity
+}
+
+naturalPerson OBJECT-CLASS ::= {
+ SUBCLASS OF { top }
+ KIND auxiliary
+ MAY CONTAIN { NaturalPersonAttributeSet }
+ ID pkcs-9-oc-naturalPerson
+}
+
+-- Attribute sets
+
+PKCSEntityAttributeSet ATTRIBUTE ::= {
+ pKCS7PDU |
+ userPKCS12 |
+-- pKCS15Token |
+ encryptedPrivateKeyInfo,
+ ... -- For future extensions
+}
+
+NaturalPersonAttributeSet ATTRIBUTE ::= {
+ emailAddress |
+ unstructuredName |
+ unstructuredAddress |
+ dateOfBirth |
+ placeOfBirth |
+ gender |
+ countryOfCitizenship |
+ countryOfResidence |
+ pseudonym |
+ serialNumber,
+ ... -- For future extensions
+}
+
+-- Attributes
+
+pKCS7PDU ATTRIBUTE ::= {
+ WITH SYNTAX ContentInfo
+ ID pkcs-9-at-pkcs7PDU
+}
+
+userPKCS12 ATTRIBUTE ::= {
+ WITH SYNTAX PFX
+ ID pkcs-9-at-userPKCS12
+}
+
+-- pKCS15Token ATTRIBUTE ::= {
+-- WITH SYNTAX PKCS15Token
+-- ID pkcs-9-at-pkcs15Token
+-- }
+
+encryptedPrivateKeyInfo ATTRIBUTE ::= {
+ WITH SYNTAX EncryptedPrivateKeyInfo
+ ID pkcs-9-at-encryptedPrivateKeyInfo
+}
+
+emailAddress ATTRIBUTE ::= {
+ WITH SYNTAX IA5String (SIZE(1..pkcs-9-ub-emailAddress))
+ EQUALITY MATCHING RULE pkcs9CaseIgnoreMatch
+ ID pkcs-9-at-emailAddress
+}
+
+unstructuredName ATTRIBUTE ::= {
+ WITH SYNTAX PKCS9String {pkcs-9-ub-unstructuredName}
+ EQUALITY MATCHING RULE pkcs9CaseIgnoreMatch
+ ID pkcs-9-at-unstructuredName
+}
+
+unstructuredAddress ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {pkcs-9-ub-unstructuredAddress}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID pkcs-9-at-unstructuredAddress
+}
+
+dateOfBirth ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-dateOfBirth
+}
+
+placeOfBirth ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {pkcs-9-ub-placeOfBirth}
+ EQUALITY MATCHING RULE caseExactMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-placeOfBirth
+}
+
+gender ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString (SIZE(1) ^ FROM ("M" | "F" | "m" | "f"))
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-gender
+}
+
+countryOfCitizenship ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString (SIZE(2))(CONSTRAINED BY {
+ -- Must be a two-letter country acronym in accordance with
+ -- ISO/IEC 3166 --})
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID pkcs-9-at-countryOfCitizenship
+}
+
+countryOfResidence ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString (SIZE(2))(CONSTRAINED BY {
+ -- Must be a two-letter country acronym in accordance with
+ -- ISO/IEC 3166 --})
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID pkcs-9-at-countryOfResidence
+}
+
+pseudonym ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {pkcs-9-ub-pseudonym}
+ EQUALITY MATCHING RULE caseExactMatch
+ ID id-at-pseudonym
+}
+
+contentType ATTRIBUTE ::= {
+ WITH SYNTAX ContentType
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-contentType
+}
+
+ContentType ::= OBJECT IDENTIFIER
+
+messageDigest ATTRIBUTE ::= {
+ WITH SYNTAX MessageDigest
+ EQUALITY MATCHING RULE octetStringMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-messageDigest
+}
+
+MessageDigest ::= OCTET STRING
+
+signingTime ATTRIBUTE ::= {
+ WITH SYNTAX SigningTime
+ EQUALITY MATCHING RULE signingTimeMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-signingTime
+}
+
+SigningTime ::= Time -- imported from ISO/IEC 9594-8
+
+randomNonce ATTRIBUTE ::= {
+ WITH SYNTAX RandomNonce
+ EQUALITY MATCHING RULE octetStringMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-randomNonce
+}
+
+RandomNonce ::= OCTET STRING (SIZE(4..MAX)) -- At least four bytes long
+
+sequenceNumber ATTRIBUTE ::= {
+ WITH SYNTAX SequenceNumber
+ EQUALITY MATCHING RULE integerMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-sequenceNumber
+}
+
+SequenceNumber ::= INTEGER (1..MAX)
+
+counterSignature ATTRIBUTE ::= {
+ WITH SYNTAX SignerInfo
+ ID pkcs-9-at-counterSignature
+}
+
+challengePassword ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {pkcs-9-ub-challengePassword}
+ EQUALITY MATCHING RULE caseExactMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-challengePassword
+}
+
+extensionRequest ATTRIBUTE ::= {
+ WITH SYNTAX ExtensionRequest
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-extensionRequest
+}
+
+ExtensionRequest ::= Extensions
+
+extendedCertificateAttributes ATTRIBUTE ::= {
+ WITH SYNTAX SET OF Attribute
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-extendedCertificateAttributes
+}
+
+friendlyName ATTRIBUTE ::= {
+ WITH SYNTAX BMPString (SIZE(1..pkcs-9-ub-friendlyName))
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-friendlyName
+}
+
+localKeyId ATTRIBUTE ::= {
+ WITH SYNTAX OCTET STRING
+ EQUALITY MATCHING RULE octetStringMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-localKeyId
+}
+
+signingDescription ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {pkcs-9-ub-signingDescription}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-signingDescription
+}
+
+smimeCapabilities ATTRIBUTE ::= {
+ WITH SYNTAX SMIMECapabilities
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-smimeCapabilities
+}
+
+SMIMECapabilities ::= SEQUENCE OF SMIMECapability
+
+SMIMECapability ::= SEQUENCE {
+ algorithm ALGORITHM.&id ({SMIMEv3Algorithms}),
+ parameters ALGORITHM.&Type ({SMIMEv3Algorithms}{@algorithm})
+}
+
+SMIMEv3Algorithms ALGORITHM ::= {...-- See RFC 2633 --}
+
+ -- Matching rules
+
+pkcs9CaseIgnoreMatch MATCHING-RULE ::= {
+ SYNTAX PKCS9String {pkcs-9-ub-match}
+ ID pkcs-9-mr-caseIgnoreMatch
+}
+
+signingTimeMatch MATCHING-RULE ::= {
+ SYNTAX SigningTime
+ ID pkcs-9-mr-signingTimeMatch
+}
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS7BodyPartType.asn1
index 525ee3c5ec..1bcc2281a1 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKCS7BodyPartType.asn1
@@ -6,7 +6,7 @@ BEGIN
IMPORTS
-- PKCS#7
ContentInfo
- FROM PKCS7 {iso(1) member-body(2) usa(840) rsadsi(113549) pkcs(1)
+ FROM PKCS-7 {iso(1) member-body(2) usa(840) rsadsi(113549) pkcs(1)
7 module(0)}
-- module not formally defined in the PKCS#7document, therefore defined in Annex O
-- IPMS Information Objects
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-CommonTypes-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-CommonTypes-2009.asn1
new file mode 100644
index 0000000000..fde5bddbf3
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-CommonTypes-2009.asn1
@@ -0,0 +1,166 @@
+ PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}
+
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+
+ -- ATTRIBUTE
+ --
+ -- Describe the set of data associated with an attribute of some type
+ --
+ -- &id is an OID identifying the attribute
+ -- &Type is the ASN.1 type structure for the attribute; not all
+ -- attributes have a data structure, so this field is optional
+ -- &minCount contains the minimum number of times the attribute can
+ -- occur in an AttributeSet
+ -- &maxCount contains the maximum number of times the attribute can
+ -- appear in an AttributeSet
+ -- Note: this cannot be automatically enforced as the field
+ -- cannot be defaulted to MAX.
+ -- &equality-match contains information about how matching should be
+ -- done
+ --
+ -- Currently we are using two different prefixes for attributes.
+ --
+ -- at- for certificate attributes
+ -- aa- for CMS attributes
+ --
+
+ ATTRIBUTE ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL,
+ &equality-match MATCHING-RULE OPTIONAL,
+ &minCount INTEGER DEFAULT 1,
+ &maxCount INTEGER OPTIONAL
+ } WITH SYNTAX {
+ [TYPE &Type]
+ [EQUALITY MATCHING RULE &equality-match]
+ [COUNTS [MIN &minCount] [MAX &maxCount]]
+ IDENTIFIED BY &id
+ }
+
+ -- Specification of MATCHING-RULE information object class
+ --
+
+ MATCHING-RULE ::= CLASS {
+ &ParentMatchingRules MATCHING-RULE OPTIONAL,
+ &AssertionType OPTIONAL,
+ &uniqueMatchIndicator ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+ }
+ WITH SYNTAX {
+ [PARENT &ParentMatchingRules]
+ [SYNTAX &AssertionType]
+ [UNIQUE-MATCH-INDICATOR &uniqueMatchIndicator]
+ ID &id
+ }
+
+ -- AttributeSet
+ --
+ -- Used when a set of attributes is to occur.
+ --
+ -- type contains the identifier of the attribute
+ -- values contains a set of values where the structure of the ASN.1
+ -- is defined by the attribute
+ --
+ -- The parameter contains the set of objects describing
+ -- those attributes that can occur in this location.
+ --
+
+ AttributeSet{ATTRIBUTE:AttrSet} ::= SEQUENCE {
+ type ATTRIBUTE.&id({AttrSet}),
+ values SET SIZE (1..MAX) OF ATTRIBUTE.
+ &Type({AttrSet}{@type})
+ }
+
+ -- SingleAttribute
+ --
+ -- Used for a single valued attribute
+ --
+ -- The parameter contains the set of objects describing the
+ -- attributes that can occur in this location
+ --
+
+ SingleAttribute{ATTRIBUTE:AttrSet} ::= SEQUENCE {
+ type ATTRIBUTE.&id({AttrSet}),
+ value ATTRIBUTE.&Type({AttrSet}{@type})
+ }
+
+ -- EXTENSION
+ --
+ -- This class definition is used to describe the association of
+ -- object identifier and ASN.1 type structure for extensions
+ --
+ -- All extensions are prefixed with ext-
+ --
+ -- &id contains the object identifier for the extension
+ -- &ExtnType specifies the ASN.1 type structure for the extension
+ -- &Critical contains the set of legal values for the critical field.
+ -- This is normally {TRUE|FALSE} but in some instances may be
+ -- restricted to just one of these values.
+ --
+
+ EXTENSION ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &ExtnType,
+ &Critical BOOLEAN DEFAULT {TRUE | FALSE }
+ } WITH SYNTAX {
+ SYNTAX &ExtnType IDENTIFIED BY &id
+ [CRITICALITY &Critical]
+ }
+
+ -- Extensions
+ --
+ -- Used for a sequence of extensions.
+ --
+ -- The parameter contains the set of legal extensions that can
+ -- occur in this sequence.
+ --
+
+ Extensions{EXTENSION:ExtensionSet} ::=
+ SEQUENCE SIZE (1..MAX) OF Extension{{ExtensionSet}}
+
+ -- Extension
+ --
+ -- Used for a single extension
+ --
+ -- The parameter contains the set of legal extensions that can
+ -- occur in this extension.
+ --
+ -- The restriction on the critical field has been commented out
+ -- the authors are not completely sure it is correct.
+ -- The restriction could be done using custom code rather than
+ -- compiler-generated code, however.
+ --
+
+ Extension{EXTENSION:ExtensionSet} ::= SEQUENCE {
+ extnID EXTENSION.&id({ExtensionSet}),
+ critical BOOLEAN
+ -- (EXTENSION.&Critical({ExtensionSet}{@extnID}))
+ DEFAULT FALSE,
+ extnValue OCTET STRING (CONTAINING
+ EXTENSION.&ExtnType({ExtensionSet}{@extnID}))
+ -- contains the DER encoding of the ASN.1 value
+ -- corresponding to the extension type identified
+ -- by extnID
+ }
+
+ -- Security Category
+ --
+ -- Security categories are used both for specifying clearances and
+ -- for labeling objects. We move this here from RFC 3281 so that
+ -- they will use a common single object class to express this
+ -- information.
+ --
+
+ SECURITY-CATEGORY ::= TYPE-IDENTIFIER
+
+ SecurityCategory{SECURITY-CATEGORY:Supported} ::= SEQUENCE {
+ type [0] IMPLICIT SECURITY-CATEGORY.
+ &id({Supported}),
+ value [1] EXPLICIT SECURITY-CATEGORY.
+ &Type({Supported}{@type})
+ }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-X400Address-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-X400Address-2009.asn1
new file mode 100644
index 0000000000..41cbaea67e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX-X400Address-2009.asn1
@@ -0,0 +1,300 @@
+ --
+ -- This module is used to isolate all the X.400 naming information.
+ -- There is no reason to expect this to occur in a PKIX certificate.
+ --
+
+ PKIX-X400Address-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-x400address-02(60) }
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+
+ -- X.400 address syntax starts here
+
+ ORAddress ::= SEQUENCE {
+ built-in-standard-attributes BuiltInStandardAttributes,
+ built-in-domain-defined-attributes
+ BuiltInDomainDefinedAttributes OPTIONAL,
+
+ -- see also teletex-domain-defined-attributes
+ extension-attributes ExtensionAttributes OPTIONAL }
+
+ -- Built-in Standard Attributes
+
+ BuiltInStandardAttributes ::= SEQUENCE {
+ country-name CountryName OPTIONAL,
+ administration-domain-name AdministrationDomainName OPTIONAL,
+ network-address [0] IMPLICIT NetworkAddress OPTIONAL,
+ -- see also extended-network-address
+ terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL,
+ private-domain-name [2] PrivateDomainName OPTIONAL,
+ organization-name [3] IMPLICIT OrganizationName OPTIONAL,
+ -- see also teletex-organization-name
+ numeric-user-identifier [4] IMPLICIT NumericUserIdentifier
+ OPTIONAL,
+ personal-name [5] IMPLICIT PersonalName OPTIONAL,
+ -- see also teletex-personal-name
+ organizational-unit-names [6] IMPLICIT OrganizationalUnitNames
+ OPTIONAL }
+ -- see also teletex-organizational-unit-names
+
+ CountryName ::= [APPLICATION 1] CHOICE {
+ x121-dcc-code NumericString
+ (SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString
+ (SIZE (ub-country-name-alpha-length)) }
+
+ AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+ numeric NumericString (SIZE (0..ub-domain-name-length)),
+ printable PrintableString (SIZE (0..ub-domain-name-length)) }
+
+ NetworkAddress ::= X121Address -- see also extended-network-address
+
+ X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
+
+ TerminalIdentifier ::= PrintableString (SIZE
+ (1..ub-terminal-id-length))
+
+ PrivateDomainName ::= CHOICE {
+ numeric NumericString (SIZE (1..ub-domain-name-length)),
+ printable PrintableString (SIZE (1..ub-domain-name-length)) }
+
+ OrganizationName ::= PrintableString
+ (SIZE (1..ub-organization-name-length))
+ -- see also teletex-organization-name
+
+ NumericUserIdentifier ::= NumericString
+ (SIZE (1..ub-numeric-user-id-length))
+
+ PersonalName ::= SET {
+ surname [0] IMPLICIT PrintableString
+ (SIZE (1..ub-surname-length)),
+ given-name [1] IMPLICIT PrintableString
+ (SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials [2] IMPLICIT PrintableString
+ (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] IMPLICIT PrintableString
+ (SIZE (1..ub-generation-qualifier-length))
+ OPTIONAL }
+ -- see also teletex-personal-name
+
+ OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
+ OF OrganizationalUnitName
+ -- see also teletex-organizational-unit-names
+
+ OrganizationalUnitName ::= PrintableString (SIZE
+ (1..ub-organizational-unit-name-length))
+
+ -- Built-in Domain-defined Attributes
+
+ BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
+ (1..ub-domain-defined-attributes) OF
+ BuiltInDomainDefinedAttribute
+
+ BuiltInDomainDefinedAttribute ::= SEQUENCE {
+ type PrintableString (SIZE
+ (1..ub-domain-defined-attribute-type-length)),
+ value PrintableString (SIZE
+ (1..ub-domain-defined-attribute-value-length)) }
+
+ -- Extension Attributes
+
+ ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
+ ExtensionAttribute
+
+ EXTENSION-ATTRIBUTE ::= CLASS {
+ &id INTEGER (0..ub-extension-attributes) UNIQUE,
+ &Type
+ } WITH SYNTAX { &Type IDENTIFIED BY &id }
+
+ ExtensionAttribute ::= SEQUENCE {
+ extension-attribute-type [0] IMPLICIT EXTENSION-ATTRIBUTE.
+ &id({SupportedExtensionAttributes}),
+ extension-attribute-value [1] EXTENSION-ATTRIBUTE.
+ &Type({SupportedExtensionAttributes}
+ {@extension-attribute-type})}
+
+ SupportedExtensionAttributes EXTENSION-ATTRIBUTE ::= {
+ ea-commonName | ea-teletexCommonName | ea-teletexOrganizationName
+ | ea-teletexPersonalName | ea-teletexOrganizationalUnitNames |
+ ea-pDSName | ea-physicalDeliveryCountryName | ea-postalCode |
+ ea-physicalDeliveryOfficeName | ea-physicalDeliveryOfficeNumber |
+ ea-extensionORAddressComponents | ea-physicalDeliveryPersonalName
+ | ea-physicalDeliveryOrganizationName |
+ ea-extensionPhysicalDeliveryAddressComponents |
+ ea-unformattedPostalAddress | ea-streetAddress |
+ ea-postOfficeBoxAddress | ea-posteRestanteAddress |
+ ea-uniquePostalName | ea-localPostalAttributes |
+ ea-extendedNetworkAddress | ea-terminalType |
+ ea-teletexDomainDefinedAttributes, ... }
+
+ -- Extension types and attribute values
+
+ ea-commonName EXTENSION-ATTRIBUTE ::= { PrintableString
+ (SIZE (1..ub-common-name-length)) IDENTIFIED BY 1 }
+
+ ea-teletexCommonName EXTENSION-ATTRIBUTE ::= {TeletexString
+ (SIZE (1..ub-common-name-length)) IDENTIFIED BY 2 }
+
+ ea-teletexOrganizationName EXTENSION-ATTRIBUTE::= { TeletexString
+ (SIZE (1..ub-organization-name-length)) IDENTIFIED BY 3 }
+
+ ea-teletexPersonalName EXTENSION-ATTRIBUTE ::= {SET {
+ surname [0] IMPLICIT TeletexString
+ (SIZE (1..ub-surname-length)),
+ given-name [1] IMPLICIT TeletexString
+ (SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials [2] IMPLICIT TeletexString
+ (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] IMPLICIT TeletexString
+ (SIZE (1..ub-generation-qualifier-length))
+ OPTIONAL } IDENTIFIED BY 4 }
+
+ ea-teletexOrganizationalUnitNames EXTENSION-ATTRIBUTE ::=
+ { SEQUENCE SIZE (1..ub-organizational-units) OF
+ TeletexOrganizationalUnitName IDENTIFIED BY 5 }
+
+ TeletexOrganizationalUnitName ::= TeletexString
+ (SIZE (1..ub-organizational-unit-name-length))
+
+ ea-pDSName EXTENSION-ATTRIBUTE ::= {PrintableString
+ (SIZE (1..ub-pds-name-length)) IDENTIFIED BY 7 }
+
+ ea-physicalDeliveryCountryName EXTENSION-ATTRIBUTE ::= { CHOICE {
+ x121-dcc-code NumericString (SIZE
+ (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString
+ (SIZE (ub-country-name-alpha-length)) }
+ IDENTIFIED BY 8 }
+
+ ea-postalCode EXTENSION-ATTRIBUTE ::= { CHOICE {
+ numeric-code NumericString (SIZE (1..ub-postal-code-length)),
+ printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
+ IDENTIFIED BY 9 }
+
+ ea-physicalDeliveryOfficeName EXTENSION-ATTRIBUTE ::=
+ { PDSParameter IDENTIFIED BY 10 }
+
+ ea-physicalDeliveryOfficeNumber EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 11 }
+
+ ea-extensionORAddressComponents EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 12 }
+
+ ea-physicalDeliveryPersonalName EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 13}
+
+ ea-physicalDeliveryOrganizationName EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 14 }
+
+ ea-extensionPhysicalDeliveryAddressComponents EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 15 }
+
+ ea-unformattedPostalAddress EXTENSION-ATTRIBUTE ::= { SET {
+ printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines)
+ OF PrintableString (SIZE (1..ub-pds-parameter-length))
+ OPTIONAL,
+ teletex-string TeletexString
+ (SIZE (1..ub-unformatted-address-length)) OPTIONAL }
+ IDENTIFIED BY 16 }
+
+ ea-streetAddress EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 17 }
+
+ ea-postOfficeBoxAddress EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 18 }
+
+ ea-posteRestanteAddress EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 19 }
+
+ ea-uniquePostalName EXTENSION-ATTRIBUTE ::=
+ { PDSParameter IDENTIFIED BY 20 }
+
+ ea-localPostalAttributes EXTENSION-ATTRIBUTE ::=
+ {PDSParameter IDENTIFIED BY 21 }
+ PDSParameter ::= SET {
+ printable-string PrintableString
+ (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string TeletexString
+ (SIZE(1..ub-pds-parameter-length)) OPTIONAL }
+
+ ea-extendedNetworkAddress EXTENSION-ATTRIBUTE ::= {
+ CHOICE {
+ e163-4-address SEQUENCE {
+ number [0] IMPLICIT NumericString
+ (SIZE (1..ub-e163-4-number-length)),
+ sub-address [1] IMPLICIT NumericString
+ (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL
+ },
+ psap-address [0] IMPLICIT PresentationAddress
+ } IDENTIFIED BY 22
+ }
+
+ PresentationAddress ::= SEQUENCE {
+ pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
+ sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
+ tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
+ nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
+
+ ea-terminalType EXTENSION-ATTRIBUTE ::= {INTEGER {
+ telex (3),
+ teletex (4),
+ g3-facsimile (5),
+ g4-facsimile (6),
+ ia5-terminal (7),
+ videotex (8) } (0..ub-integer-options)
+ IDENTIFIED BY 23 }
+
+ -- Extension Domain-defined Attributes
+
+ ea-teletexDomainDefinedAttributes EXTENSION-ATTRIBUTE ::=
+ { SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ TeletexDomainDefinedAttribute IDENTIFIED BY 6 }
+
+ TeletexDomainDefinedAttribute ::= SEQUENCE {
+ type TeletexString
+ (SIZE (1..ub-domain-defined-attribute-type-length)),
+ value TeletexString
+ (SIZE (1..ub-domain-defined-attribute-value-length)) }
+
+ -- specifications of Upper Bounds MUST be regarded as mandatory
+ -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
+ -- Upper Bounds
+ -- Upper Bounds
+ ub-match INTEGER ::= 128
+ ub-common-name-length INTEGER ::= 64
+ ub-country-name-alpha-length INTEGER ::= 2
+ ub-country-name-numeric-length INTEGER ::= 3
+ ub-domain-defined-attributes INTEGER ::= 4
+ ub-domain-defined-attribute-type-length INTEGER ::= 8
+ ub-domain-defined-attribute-value-length INTEGER ::= 128
+ ub-domain-name-length INTEGER ::= 16
+ ub-extension-attributes INTEGER ::= 256
+ ub-e163-4-number-length INTEGER ::= 15
+ ub-e163-4-sub-address-length INTEGER ::= 40
+ ub-generation-qualifier-length INTEGER ::= 3
+ ub-given-name-length INTEGER ::= 16
+ ub-initials-length INTEGER ::= 5
+ ub-integer-options INTEGER ::= 256
+ ub-numeric-user-id-length INTEGER ::= 32
+ ub-organization-name-length INTEGER ::= 64
+ ub-organizational-unit-name-length INTEGER ::= 32
+ ub-organizational-units INTEGER ::= 4
+ ub-pds-name-length INTEGER ::= 16
+ ub-pds-parameter-length INTEGER ::= 30
+ ub-pds-physical-address-lines INTEGER ::= 6
+ ub-postal-code-length INTEGER ::= 16
+ ub-surname-length INTEGER ::= 40
+ ub-terminal-id-length INTEGER ::= 24
+ ub-unformatted-address-length INTEGER ::= 180
+ ub-x121-address-length INTEGER ::= 16
+
+ -- Note - upper bounds on string types, such as TeletexString, are
+ -- measured in characters. Excepting PrintableString or IA5String, a
+ -- significantly greater number of octets will be required to hold
+ -- such a value. As a minimum, 16 octets or twice the specified
+ -- upper bound, whichever is the larger, should be allowed for
+ -- TeletexString. For UTF8String or UniversalString, at least four
+ -- times the upper bound should be allowed.
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1-PSS-OAEP-Algorithms-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1-PSS-OAEP-Algorithms-2009.asn1
new file mode 100644
index 0000000000..b1232fb8f2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1-PSS-OAEP-Algorithms-2009.asn1
@@ -0,0 +1,308 @@
+ PKIX1-PSS-OAEP-Algorithms-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-rsa-pkalgs-02(54)}
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ AlgorithmIdentifier{}, ALGORITHM, DIGEST-ALGORITHM, KEY-TRANSPORT,
+ SIGNATURE-ALGORITHM, PUBLIC-KEY, SMIME-CAPS
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ id-sha1, mda-sha1, pk-rsa, RSAPublicKey
+ FROM PKIXAlgs-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56)};
+
+ -- ============================
+ -- Object Set exports
+ -- ============================
+ --
+ -- Define top-level symbols with all of the objects defined for
+ -- export to other modules. These objects would be included as part
+ -- of an Object Set to restrict the set of legal values.
+ --
+
+ PublicKeys PUBLIC-KEY ::= { pk-rsaSSA-PSS | pk-rsaES-OAEP, ... }
+ SignatureAlgs SIGNATURE-ALGORITHM ::= { sa-rsaSSA-PSS, ...}
+ KeyTransportAlgs KEY-TRANSPORT ::= { kta-rsaES-OAEP, ... }
+ HashAlgs DIGEST-ALGORITHM ::= { mda-sha224 | mda-sha256 | mda-sha384
+ | mda-sha512, ... }
+ SMimeCaps SMIME-CAPS ::= {
+ sa-rsaSSA-PSS.&smimeCaps |
+ kta-rsaES-OAEP.&smimeCaps,
+ ...
+ }
+
+ -- =============================
+ -- Algorithm Objects
+ -- =============================
+
+ --
+ -- Public key object for PSS signatures
+ --
+
+ pk-rsaSSA-PSS PUBLIC-KEY ::= {
+ IDENTIFIER id-RSASSA-PSS
+ KEY RSAPublicKey
+ PARAMS TYPE RSASSA-PSS-params ARE optional
+ -- Private key format not in this module --
+ CERT-KEY-USAGE { nonRepudiation, digitalSignature,
+ keyCertSign, cRLSign }
+ }
+
+ --
+ -- Signature algorithm definition for PSS signatures
+ --
+
+ sa-rsaSSA-PSS SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER id-RSASSA-PSS
+ PARAMS TYPE RSASSA-PSS-params ARE required
+ HASHES { mda-sha1 | mda-sha224 | mda-sha256 | mda-sha384
+ | mda-sha512 }
+ PUBLIC-KEYS { pk-rsa | pk-rsaSSA-PSS }
+ SMIME-CAPS { IDENTIFIED BY id-RSASSA-PSS }
+ }
+
+ --
+ -- Signature algorithm definitions for PKCS v1.5 signatures
+ --
+
+ sa-sha224WithRSAEncryption SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER sha224WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-sha224 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS { IDENTIFIED BY sha224WithRSAEncryption }
+ }
+ sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 }
+
+ sa-sha256WithRSAEncryption SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER sha256WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-sha256 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS { IDENTIFIED BY sha256WithRSAEncryption }
+ }
+ sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+
+ sa-sha384WithRSAEncryption SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER sha384WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-sha384 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS { IDENTIFIED BY sha384WithRSAEncryption }
+ }
+ sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+
+ sa-sha512WithRSAEncryption SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER sha512WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-sha512 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS { IDENTIFIED BY sha512WithRSAEncryption }
+ }
+ sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+
+ --
+ -- Public key definition for OAEP encryption
+ --
+
+ pk-rsaES-OAEP PUBLIC-KEY ::= {
+ IDENTIFIER id-RSAES-OAEP
+ KEY RSAPublicKey
+ PARAMS TYPE RSAES-OAEP-params ARE optional
+ -- Private key format not in this module --
+ CERT-KEY-USAGE {keyEncipherment, dataEncipherment}
+ }
+
+ --
+ -- Key transport key lock definition for OAEP encryption
+ --
+
+ kta-rsaES-OAEP KEY-TRANSPORT ::= {
+ IDENTIFIER id-RSAES-OAEP
+ PARAMS TYPE RSAES-OAEP-params ARE required
+ PUBLIC-KEYS { pk-rsa | pk-rsaES-OAEP }
+ SMIME-CAPS { TYPE RSAES-OAEP-params IDENTIFIED BY id-RSAES-OAEP}
+ }
+ -- ============================
+ -- Basic object identifiers
+ -- ============================
+
+ pkcs-1 OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+
+ -- When rsaEncryption is used in an AlgorithmIdentifier, the
+ -- parameters MUST be present and MUST be NULL.
+ -- rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
+
+ -- When id-RSAES-OAEP is used in an AlgorithmIdentifier,
+ -- and the parameters field is present, it MUST be
+ -- RSAES-OAEP-params.
+
+ id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 }
+
+ -- When id-mgf1 is used in an AlgorithmIdentifier, the parameters
+ -- MUST be present and MUST be a HashAlgorithm.
+
+ id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 }
+
+ -- When id-pSpecified is used in an AlgorithmIdentifier, the
+ -- parameters MUST be an OCTET STRING.
+
+ id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 }
+
+ -- When id-RSASSA-PSS is used in an AlgorithmIdentifier, and the
+ -- parameters field is present, it MUST be RSASSA-PSS-params.
+
+ id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
+
+ -- When the following OIDs are used in an AlgorithmIdentifier, the
+ -- parameters SHOULD be absent, but if the parameters are present,
+ -- they MUST be NULL.
+
+ --
+ -- id-sha1 is imported from RFC 3279. Additionally, the v1.5
+ -- signature algorithms (i.e., rsaWithSHA256) are now solely placed
+ -- in that module.
+ --
+
+ id-sha224 OBJECT IDENTIFIER ::=
+ { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
+ csor(3) nistAlgorithms(4) hashalgs(2) 4 }
+
+ mda-sha224 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-sha224
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+
+ id-sha256 OBJECT IDENTIFIER ::=
+ { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
+ csor(3) nistAlgorithms(4) hashalgs(2) 1 }
+
+ mda-sha256 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-sha256
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+ id-sha384 OBJECT IDENTIFIER ::=
+ { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
+ csor(3) nistAlgorithms(4) hashalgs(2) 2 }
+
+ mda-sha384 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-sha384
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+ id-sha512 OBJECT IDENTIFIER ::=
+ { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
+ csor(3) nistAlgorithms(4) hashalgs(2) 3 }
+
+ mda-sha512 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-sha512
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+
+ -- =============
+ -- Constants
+ -- =============
+
+ EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
+
+ nullOctetString EncodingParameters ::= ''H
+
+ nullParameters NULL ::= NULL
+
+ -- =========================
+ -- Algorithm Identifiers
+ -- =========================
+
+ HashAlgorithm ::= AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {HashAlgorithms}}
+
+ HashAlgorithms DIGEST-ALGORITHM ::= {
+ { IDENTIFIER id-sha1 PARAMS TYPE NULL ARE preferredPresent } |
+ { IDENTIFIER id-sha224 PARAMS TYPE NULL ARE preferredPresent } |
+ { IDENTIFIER id-sha256 PARAMS TYPE NULL ARE preferredPresent } |
+ { IDENTIFIER id-sha384 PARAMS TYPE NULL ARE preferredPresent } |
+ { IDENTIFIER id-sha512 PARAMS TYPE NULL ARE preferredPresent }
+ }
+
+ sha1Identifier HashAlgorithm ::= {
+ algorithm id-sha1,
+ parameters NULL : NULL
+ }
+
+ --
+ -- We have a default algorithm - create the value here
+ --
+
+ MaskGenAlgorithm ::= AlgorithmIdentifier{ALGORITHM,
+ {PKCS1MGFAlgorithms}}
+
+ mgf1SHA1 MaskGenAlgorithm ::= {
+ algorithm id-mgf1,
+ parameters HashAlgorithm : sha1Identifier
+ }
+
+ --
+ -- Define the set of mask generation functions
+ --
+ -- If the identifier is id-mgf1, any of the listed hash
+ -- algorithms may be used.
+ --
+
+ PKCS1MGFAlgorithms ALGORITHM ::= {
+ { IDENTIFIER id-mgf1 PARAMS TYPE HashAlgorithm ARE required },
+ ...
+ }
+
+ --
+ -- Define the set of known source algorithms for PSS
+ --
+
+ PSourceAlgorithm ::= AlgorithmIdentifier{ALGORITHM,
+ {PSS-SourceAlgorithms}}
+
+ PSS-SourceAlgorithms ALGORITHM ::= {
+ { IDENTIFIER id-pSpecified PARAMS TYPE EncodingParameters
+ ARE required },
+ ...
+ }
+ pSpecifiedEmpty PSourceAlgorithm ::= {
+ algorithm id-pSpecified,
+ parameters EncodingParameters : nullOctetString
+ }
+
+ -- ===================
+ -- Main structures
+ -- ===================
+
+ -- AlgorithmIdentifier parameters for id-RSASSA-PSS.
+ -- Note that the tags in this Sequence are explicit.
+ -- Note: The hash algorithm in hashAlgorithm and in
+ -- maskGenAlgorithm should be the same.
+
+ RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
+ maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ saltLength [2] INTEGER DEFAULT 20,
+ trailerField [3] INTEGER DEFAULT 1
+ }
+
+ -- AlgorithmIdentifier parameters for id-RSAES-OAEP.
+ -- Note that the tags in this Sequence are explicit.
+ -- Note: The hash algorithm in hashFunc and in
+ -- maskGenFunc should be the same.
+
+ RSAES-OAEP-params ::= SEQUENCE {
+ hashFunc [0] HashAlgorithm DEFAULT sha1Identifier,
+ maskGenFunc [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ pSourceFunc [2] PSourceAlgorithm DEFAULT
+ pSpecifiedEmpty
+ }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Explicit-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Explicit-2009.asn1
new file mode 100644
index 0000000000..613e0e9d2c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Explicit-2009.asn1
@@ -0,0 +1,415 @@
+ PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-explicit-02(51)}
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+
+ IMPORTS
+
+ Extensions{}, EXTENSION, ATTRIBUTE, SingleAttribute{}
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}
+
+ AlgorithmIdentifier{}, PUBLIC-KEY, SIGNATURE-ALGORITHM
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ CertExtensions, CrlExtensions, CrlEntryExtensions
+ FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+ SignatureAlgs, PublicKeys
+ FROM PKIXAlgs-2009
+ {iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) 56}
+
+ SignatureAlgs, PublicKeys
+ FROM PKIX1-PSS-OAEP-Algorithms-2009
+ {iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-rsa-pkalgs-02(54)}
+
+ ORAddress
+ FROM PKIX-X400Address-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-x400address-02(60)};
+
+ id-pkix OBJECT IDENTIFIER ::=
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7)}
+
+ -- PKIX arcs
+
+ id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
+ -- arc for private certificate extensions
+ id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ -- arc for policy qualifier types
+ id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
+ -- arc for extended key purpose OIDs
+ id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+ -- arc for access descriptors
+
+ -- policyQualifierIds for Internet policy qualifiers
+
+ id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ -- OID for CPS qualifier
+ id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ -- OID for user notice qualifier
+
+ -- access descriptor definitions
+
+ id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+ id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+ id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 }
+ id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 }
+
+ -- attribute data types
+ AttributeType ::= ATTRIBUTE.&id
+
+ -- Replaced by SingleAttribute{}
+ --
+ -- AttributeTypeAndValue ::= SEQUENCE {
+ -- type ATTRIBUTE.&id({SupportedAttributes}),
+ -- value ATTRIBUTE.&Type({SupportedAttributes}{@type}) }
+ --
+
+ -- Suggested naming attributes: Definition of the following
+ -- information object set may be augmented to meet local
+ -- requirements. Note that deleting members of the set may
+ -- prevent interoperability with conforming implementations.
+ -- All attributes are presented in pairs: the AttributeType
+ -- followed by the type definition for the corresponding
+ -- AttributeValue.
+
+ -- Arc for standard naming attributes
+
+ id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
+
+ -- Naming attributes of type X520name
+
+ id-at-name AttributeType ::= { id-at 41 }
+ at-name ATTRIBUTE ::= { TYPE X520name IDENTIFIED BY id-at-name }
+
+ id-at-surname AttributeType ::= { id-at 4 }
+ at-surname ATTRIBUTE ::= { TYPE X520name IDENTIFIED BY id-at-surname }
+
+ id-at-givenName AttributeType ::= { id-at 42 }
+ at-givenName ATTRIBUTE ::=
+ { TYPE X520name IDENTIFIED BY id-at-givenName }
+
+ id-at-initials AttributeType ::= { id-at 43 }
+ at-initials ATTRIBUTE ::=
+ { TYPE X520name IDENTIFIED BY id-at-initials }
+
+ id-at-generationQualifier AttributeType ::= { id-at 44 }
+ at-generationQualifier ATTRIBUTE ::=
+ { TYPE X520name IDENTIFIED BY id-at-generationQualifier }
+
+ -- Directory string type --
+
+ DirectoryString{INTEGER:maxSize} ::= CHOICE {
+ teletexString TeletexString(SIZE (1..maxSize)),
+ printableString PrintableString(SIZE (1..maxSize)),
+ bmpString BMPString(SIZE (1..maxSize)),
+ universalString UniversalString(SIZE (1..maxSize)),
+ uTF8String UTF8String(SIZE (1..maxSize))
+ }
+
+ X520name ::= DirectoryString {ub-name}
+
+ -- Naming attributes of type X520CommonName
+
+ id-at-commonName AttributeType ::= { id-at 3 }
+
+ at-x520CommonName ATTRIBUTE ::=
+ {TYPE X520CommonName IDENTIFIED BY id-at-commonName }
+
+ X520CommonName ::= DirectoryString {ub-common-name}
+
+ -- Naming attributes of type X520LocalityName
+
+ id-at-localityName AttributeType ::= { id-at 7 }
+
+ at-x520LocalityName ATTRIBUTE ::=
+ { TYPE X520LocalityName IDENTIFIED BY id-at-localityName }
+ X520LocalityName ::= DirectoryString {ub-locality-name}
+
+ -- Naming attributes of type X520StateOrProvinceName
+
+ id-at-stateOrProvinceName AttributeType ::= { id-at 8 }
+
+ at-x520StateOrProvinceName ATTRIBUTE ::=
+ { TYPE DirectoryString {ub-state-name}
+ IDENTIFIED BY id-at-stateOrProvinceName }
+ X520StateOrProvinceName ::= DirectoryString {ub-state-name}
+
+ -- Naming attributes of type X520OrganizationName
+
+ id-at-organizationName AttributeType ::= { id-at 10 }
+
+ at-x520OrganizationName ATTRIBUTE ::=
+ { TYPE DirectoryString {ub-organization-name}
+ IDENTIFIED BY id-at-organizationName }
+ X520OrganizationName ::= DirectoryString {ub-organization-name}
+
+ -- Naming attributes of type X520OrganizationalUnitName
+
+ id-at-organizationalUnitName AttributeType ::= { id-at 11 }
+
+ at-x520OrganizationalUnitName ATTRIBUTE ::=
+ { TYPE DirectoryString {ub-organizational-unit-name}
+ IDENTIFIED BY id-at-organizationalUnitName }
+ X520OrganizationalUnitName ::= DirectoryString
+ {ub-organizational-unit-name}
+
+ -- Naming attributes of type X520Title
+
+ id-at-title AttributeType ::= { id-at 12 }
+
+ at-x520Title ATTRIBUTE ::= { TYPE DirectoryString { ub-title }
+ IDENTIFIED BY id-at-title }
+
+ -- Naming attributes of type X520dnQualifier
+
+ id-at-dnQualifier AttributeType ::= { id-at 46 }
+
+ at-x520dnQualifier ATTRIBUTE ::= { TYPE PrintableString
+ IDENTIFIED BY id-at-dnQualifier }
+
+ -- Naming attributes of type X520countryName (digraph from IS 3166)
+
+ id-at-countryName AttributeType ::= { id-at 6 }
+
+ at-x520countryName ATTRIBUTE ::= { TYPE PrintableString (SIZE (2))
+ IDENTIFIED BY id-at-countryName }
+
+ -- Naming attributes of type X520SerialNumber
+
+ id-at-serialNumber AttributeType ::= { id-at 5 }
+
+ at-x520SerialNumber ATTRIBUTE ::= {TYPE PrintableString
+ (SIZE (1..ub-serial-number)) IDENTIFIED BY id-at-serialNumber }
+
+ -- Naming attributes of type X520Pseudonym
+
+ id-at-pseudonym AttributeType ::= { id-at 65 }
+
+ at-x520Pseudonym ATTRIBUTE ::= { TYPE DirectoryString {ub-pseudonym}
+ IDENTIFIED BY id-at-pseudonym }
+
+ -- Naming attributes of type DomainComponent (from RFC 2247)
+
+ id-domainComponent AttributeType ::=
+ { itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100)
+ pilotAttributeType(1) 25 }
+
+ at-domainComponent ATTRIBUTE ::= {TYPE IA5String
+ IDENTIFIED BY id-domainComponent }
+
+ -- Legacy attributes
+
+ pkcs-9 OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+ id-emailAddress AttributeType ::= { pkcs-9 1 }
+
+ at-emailAddress ATTRIBUTE ::= {TYPE IA5String
+ (SIZE (1..ub-emailaddress-length)) IDENTIFIED BY
+ id-emailAddress }
+
+ -- naming data types --
+
+ Name ::= CHOICE { -- only one possibility for now --
+ rdnSequence RDNSequence }
+
+ RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+ DistinguishedName ::= RDNSequence
+
+ RelativeDistinguishedName ::=
+ SET SIZE (1 .. MAX) OF SingleAttribute { {SupportedAttributes} }
+
+ -- These are the known name elements for a DN
+
+ SupportedAttributes ATTRIBUTE ::= {
+ at-name | at-surname | at-givenName | at-initials |
+ at-generationQualifier | at-x520CommonName |
+ at-x520LocalityName | at-x520StateOrProvinceName |
+ at-x520OrganizationName | at-x520OrganizationalUnitName |
+ at-x520Title | at-x520dnQualifier | at-x520countryName |
+ at-x520SerialNumber | at-x520Pseudonym | at-domainComponent |
+ at-emailAddress, ... }
+
+ --
+ -- Certificate- and CRL-specific structures begin here
+ --
+
+ Certificate ::= SIGNED{TBSCertificate}
+
+ TBSCertificate ::= SEQUENCE {
+ version [0] Version DEFAULT v1,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ issuer Name,
+ validity Validity,
+ subject Name,
+ subjectPublicKeyInfo SubjectPublicKeyInfo,
+ ... ,
+ [[2: -- If present, version MUST be v2
+ issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL
+ ]],
+ [[3: -- If present, version MUST be v3 --
+ extensions [3] Extensions{{CertExtensions}} OPTIONAL
+ ]], ... }
+
+ Version ::= INTEGER { v1(0), v2(1), v3(2) }
+
+ CertificateSerialNumber ::= INTEGER
+
+ Validity ::= SEQUENCE {
+ notBefore Time,
+ notAfter Time }
+
+ Time ::= CHOICE {
+ utcTime UTCTime,
+ generalTime GeneralizedTime }
+
+ UniqueIdentifier ::= BIT STRING
+
+ SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier{PUBLIC-KEY,
+ {PublicKeyAlgorithms}},
+ subjectPublicKey BIT STRING }
+
+ -- CRL structures
+
+ CertificateList ::= SIGNED{TBSCertList}
+
+ TBSCertList ::= SEQUENCE {
+ version Version OPTIONAL,
+ -- if present, MUST be v2
+ signature AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ issuer Name,
+ thisUpdate Time,
+ nextUpdate Time OPTIONAL,
+ revokedCertificates SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+ userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ ... ,
+ [[2: -- if present, version MUST be v2
+ crlEntryExtensions Extensions{{CrlEntryExtensions}}
+ OPTIONAL
+ ]], ...
+ } OPTIONAL,
+ ... ,
+ [[2: -- if present, version MUST be v2
+ crlExtensions [0] Extensions{{CrlExtensions}}
+ OPTIONAL
+ ]], ... }
+
+ -- Version, Time, CertificateSerialNumber, and Extensions were
+ -- defined earlier for use in the certificate structure
+
+ --
+ -- The two object sets below should be expanded to include
+ -- those algorithms which are supported by the system.
+ --
+ -- For example:
+ -- SignatureAlgorithms SIGNATURE-ALGORITHM ::= {
+ -- PKIXAlgs-2008.SignatureAlgs, ...,
+ -- - - RFC 3279 provides the base set
+ -- PKIX1-PSS-OAEP-ALGORITHMS.SignatureAlgs |
+ -- - - RFC 4055 provides extension algs
+ -- OtherModule.SignatureAlgs
+ -- - - RFC XXXX provides additional extension algs
+ -- }
+
+ SignatureAlgorithms SIGNATURE-ALGORITHM ::= {
+ PKIXAlgs-2009.SignatureAlgs, ...,
+ PKIX1-PSS-OAEP-Algorithms-2009.SignatureAlgs }
+
+ PublicKeyAlgorithms PUBLIC-KEY ::= {
+ PKIXAlgs-2009.PublicKeys, ...,
+ PKIX1-PSS-OAEP-Algorithms-2009.PublicKeys}
+
+ -- Upper Bounds
+
+ ub-state-name INTEGER ::= 128
+ ub-organization-name INTEGER ::= 64
+ ub-organizational-unit-name INTEGER ::= 64
+ ub-title INTEGER ::= 64
+ ub-serial-number INTEGER ::= 64
+ ub-pseudonym INTEGER ::= 128
+ ub-emailaddress-length INTEGER ::= 255
+ ub-locality-name INTEGER ::= 128
+ ub-common-name INTEGER ::= 64
+ ub-name INTEGER ::= 32768
+
+ -- Note - upper bounds on string types, such as TeletexString, are
+ -- measured in characters. Excepting PrintableString or IA5String, a
+ -- significantly greater number of octets will be required to hold
+ -- such a value. As a minimum, 16 octets or twice the specified
+ -- upper bound, whichever is the larger, should be allowed for
+ -- TeletexString. For UTF8String or UniversalString, at least four
+ -- times the upper bound should be allowed.
+
+ -- Information object classes used in the definition
+ -- of certificates and CRLs
+
+ -- Parameterized Type SIGNED
+ --
+ -- Three different versions of doing SIGNED:
+ -- 1. Simple and close to the previous version
+ --
+ -- SIGNED{ToBeSigned} ::= SEQUENCE {
+ -- toBeSigned ToBeSigned,
+ -- algorithm AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ -- {SignatureAlgorithms}},
+ -- signature BIT STRING
+ -- }
+
+ -- 2. From Authenticated Framework
+ --
+ -- SIGNED{ToBeSigned} ::= SEQUENCE {
+ -- toBeSigned ToBeSigned,
+ -- COMPONENTS OF SIGNATURE{ToBeSigned}
+ -- }
+ -- SIGNATURE{ToBeSigned} ::= SEQUENCE {
+ -- algorithmIdentifier AlgorithmIdentifier,
+ -- encrypted ENCRYPTED-HASH{ToBeSigned}
+ -- }
+ -- ENCRYPTED-HASH{ToBeSigned} ::=
+ -- BIT STRING
+ -- (CONSTRAINED BY {
+ -- shall be the result of applying a hashing procedure to
+ -- the DER-encoded (see 4.1) octets of a value of
+ -- ToBeSigned and then applying an encipherment procedure
+ -- to those octets
+ -- })
+ --
+ --
+ -- 3. A more complex version, but one that automatically ties
+ -- together both the signature algorithm and the
+ -- signature value for automatic decoding.
+ --
+ SIGNED{ToBeSigned} ::= SEQUENCE {
+ toBeSigned ToBeSigned,
+ algorithmIdentifier SEQUENCE {
+ algorithm SIGNATURE-ALGORITHM.
+ &id({SignatureAlgorithms}),
+ parameters SIGNATURE-ALGORITHM.
+ &Params({SignatureAlgorithms}
+ {@algorithmIdentifier.algorithm}) OPTIONAL
+ },
+ signature BIT STRING (CONTAINING SIGNATURE-ALGORITHM.&Value(
+ {SignatureAlgorithms}
+ {@algorithmIdentifier.algorithm}))
+ }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Implicit-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Implicit-2009.asn1
new file mode 100644
index 0000000000..3651a5249b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIX1Implicit-2009.asn1
@@ -0,0 +1,447 @@
+ PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ AttributeSet{}, EXTENSION, ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57) }
+
+ id-pe, id-kp, id-qt-unotice, id-qt-cps, ORAddress, Name,
+ RelativeDistinguishedName, CertificateSerialNumber,
+ DirectoryString{}, SupportedAttributes
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51) };
+
+ CertExtensions EXTENSION ::= {
+ ext-AuthorityKeyIdentifier | ext-SubjectKeyIdentifier |
+ ext-KeyUsage | ext-PrivateKeyUsagePeriod |
+ ext-CertificatePolicies | ext-PolicyMappings |
+ ext-SubjectAltName | ext-IssuerAltName |
+ ext-SubjectDirectoryAttributes |
+ ext-BasicConstraints | ext-NameConstraints |
+ ext-PolicyConstraints | ext-ExtKeyUsage |
+ ext-CRLDistributionPoints | ext-InhibitAnyPolicy |
+ ext-FreshestCRL | ext-AuthorityInfoAccess |
+ ext-SubjectInfoAccessSyntax, ... }
+
+ CrlExtensions EXTENSION ::= {
+ ext-AuthorityKeyIdentifier | ext-IssuerAltName |
+ ext-CRLNumber | ext-DeltaCRLIndicator |
+ ext-IssuingDistributionPoint | ext-FreshestCRL, ... }
+
+ CrlEntryExtensions EXTENSION ::= {
+ ext-CRLReason | ext-CertificateIssuer |
+ ext-HoldInstructionCode | ext-InvalidityDate, ... }
+ -- Shared arc for standard certificate and CRL extensions
+
+ id-ce OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 29 }
+
+ -- authority key identifier OID and syntax
+
+ ext-AuthorityKeyIdentifier EXTENSION ::= { SYNTAX
+ AuthorityKeyIdentifier IDENTIFIED BY
+ id-ce-authorityKeyIdentifier }
+ id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
+
+ AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ (WITH COMPONENTS {
+ ...,
+ authorityCertIssuer PRESENT,
+ authorityCertSerialNumber PRESENT
+ } |
+ WITH COMPONENTS {
+ ...,
+ authorityCertIssuer ABSENT,
+ authorityCertSerialNumber ABSENT
+ })
+
+ KeyIdentifier ::= OCTET STRING
+
+ -- subject key identifier OID and syntax
+
+ ext-SubjectKeyIdentifier EXTENSION ::= { SYNTAX
+ KeyIdentifier IDENTIFIED BY id-ce-subjectKeyIdentifier }
+ id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
+
+ -- key usage extension OID and syntax
+
+ ext-KeyUsage EXTENSION ::= { SYNTAX
+ KeyUsage IDENTIFIED BY id-ce-keyUsage }
+ id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+
+ KeyUsage ::= BIT STRING {
+ digitalSignature (0),
+ nonRepudiation (1), -- recent editions of X.509 have
+ -- renamed this bit to
+ -- contentCommitment
+ keyEncipherment (2),
+ dataEncipherment (3),
+ keyAgreement (4),
+ keyCertSign (5),
+ cRLSign (6),
+ encipherOnly (7),
+ decipherOnly (8)
+ }
+
+ -- private key usage period extension OID and syntax
+
+ ext-PrivateKeyUsagePeriod EXTENSION ::= { SYNTAX
+ PrivateKeyUsagePeriod IDENTIFIED BY id-ce-privateKeyUsagePeriod }
+ id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
+
+ PrivateKeyUsagePeriod ::= SEQUENCE {
+ notBefore [0] GeneralizedTime OPTIONAL,
+ notAfter [1] GeneralizedTime OPTIONAL }
+ (WITH COMPONENTS {..., notBefore PRESENT } |
+ WITH COMPONENTS {..., notAfter PRESENT })
+
+ -- certificate policies extension OID and syntax
+
+ ext-CertificatePolicies EXTENSION ::= { SYNTAX
+ CertificatePolicies IDENTIFIED BY id-ce-certificatePolicies}
+ id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+
+ CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+ PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ PolicyQualifierInfo OPTIONAL }
+
+ CertPolicyId ::= OBJECT IDENTIFIER
+
+ CERT-POLICY-QUALIFIER ::= TYPE-IDENTIFIER
+
+ PolicyQualifierInfo ::= SEQUENCE {
+ policyQualifierId CERT-POLICY-QUALIFIER.
+ &id({PolicyQualifierId}),
+ qualifier CERT-POLICY-QUALIFIER.
+ &Type({PolicyQualifierId}{@policyQualifierId})}
+
+ -- Implementations that recognize additional policy qualifiers MUST
+ -- augment the following definition for PolicyQualifierId
+
+ PolicyQualifierId CERT-POLICY-QUALIFIER ::=
+ { pqid-cps | pqid-unotice, ... }
+
+ pqid-cps CERT-POLICY-QUALIFIER ::= { CPSuri IDENTIFIED BY id-qt-cps }
+ pqid-unotice CERT-POLICY-QUALIFIER ::= { UserNotice
+ IDENTIFIED BY id-qt-unotice }
+
+ -- CPS pointer qualifier
+
+ CPSuri ::= IA5String
+
+ -- user notice qualifier
+
+ UserNotice ::= SEQUENCE {
+ noticeRef NoticeReference OPTIONAL,
+ explicitText DisplayText OPTIONAL}
+
+ --
+ -- This is not made explicit in the text
+ --
+ -- {WITH COMPONENTS {..., noticeRef PRESENT} |
+ -- WITH COMPONENTS {..., DisplayText PRESENT }}
+
+ NoticeReference ::= SEQUENCE {
+ organization DisplayText,
+ noticeNumbers SEQUENCE OF INTEGER }
+
+ DisplayText ::= CHOICE {
+ ia5String IA5String (SIZE (1..200)),
+ visibleString VisibleString (SIZE (1..200)),
+ bmpString BMPString (SIZE (1..200)),
+ utf8String UTF8String (SIZE (1..200)) }
+
+ -- policy mapping extension OID and syntax
+
+ ext-PolicyMappings EXTENSION ::= { SYNTAX
+ PolicyMappings IDENTIFIED BY id-ce-policyMappings }
+ id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
+
+ PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+ issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId
+ }
+
+ -- subject alternative name extension OID and syntax
+
+ ext-SubjectAltName EXTENSION ::= { SYNTAX
+ GeneralNames IDENTIFIED BY id-ce-subjectAltName }
+ id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+
+ GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+ GeneralName ::= CHOICE {
+ otherName [0] INSTANCE OF OTHER-NAME,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER
+ }
+
+ -- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
+ -- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
+
+ OTHER-NAME ::= TYPE-IDENTIFIER
+
+ EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString {ubMax} OPTIONAL,
+ partyName [1] DirectoryString {ubMax}
+ }
+
+ -- issuer alternative name extension OID and syntax
+
+ ext-IssuerAltName EXTENSION ::= { SYNTAX
+ GeneralNames IDENTIFIED BY id-ce-issuerAltName }
+ id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
+
+ ext-SubjectDirectoryAttributes EXTENSION ::= { SYNTAX
+ SubjectDirectoryAttributes IDENTIFIED BY
+ id-ce-subjectDirectoryAttributes }
+ id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
+
+ SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF
+ AttributeSet{{SupportedAttributes}}
+
+ -- basic constraints extension OID and syntax
+
+ ext-BasicConstraints EXTENSION ::= { SYNTAX
+ BasicConstraints IDENTIFIED BY id-ce-basicConstraints }
+ id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+
+ BasicConstraints ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL
+ }
+
+ -- name constraints extension OID and syntax
+ ext-NameConstraints EXTENSION ::= { SYNTAX
+ NameConstraints IDENTIFIED BY id-ce-nameConstraints }
+ id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+
+ NameConstraints ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL
+ }
+ --
+ -- This is a constraint in the issued certificates by CAs, but is
+ -- not a requirement on EEs.
+ --
+ -- (WITH COMPONENTS { ..., permittedSubtrees PRESENT} |
+ -- WITH COMPONENTS { ..., excludedSubtrees PRESENT }}
+
+ GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+ GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL
+ }
+
+ BaseDistance ::= INTEGER (0..MAX)
+
+ -- policy constraints extension OID and syntax
+
+ ext-PolicyConstraints EXTENSION ::= { SYNTAX
+ PolicyConstraints IDENTIFIED BY id-ce-policyConstraints }
+ id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+
+ PolicyConstraints ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL }
+ --
+ -- This is a constraint in the issued certificates by CAs,
+ -- but is not a requirement for EEs
+ --
+ -- (WITH COMPONENTS { ..., requireExplicitPolicy PRESENT} |
+ -- WITH COMPONENTS { ..., inhibitPolicyMapping PRESENT})
+
+ SkipCerts ::= INTEGER (0..MAX)
+
+ -- CRL distribution points extension OID and syntax
+
+ ext-CRLDistributionPoints EXTENSION ::= { SYNTAX
+ CRLDistributionPoints IDENTIFIED BY id-ce-cRLDistributionPoints}
+ id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
+ CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+ DistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ reasons [1] ReasonFlags OPTIONAL,
+ cRLIssuer [2] GeneralNames OPTIONAL
+ }
+ --
+ -- This is not a requirement in the text, but it seems as if it
+ -- should be
+ --
+ --(WITH COMPONENTS {..., distributionPoint PRESENT} |
+ -- WITH COMPONENTS {..., cRLIssuer PRESENT})
+
+ DistributionPointName ::= CHOICE {
+ fullName [0] GeneralNames,
+ nameRelativeToCRLIssuer [1] RelativeDistinguishedName
+ }
+
+ ReasonFlags ::= BIT STRING {
+ unused (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6),
+ privilegeWithdrawn (7),
+ aACompromise (8)
+ }
+
+ -- extended key usage extension OID and syntax
+
+ ext-ExtKeyUsage EXTENSION ::= { SYNTAX
+ ExtKeyUsageSyntax IDENTIFIED BY id-ce-extKeyUsage }
+ id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+
+ ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+
+ KeyPurposeId ::= OBJECT IDENTIFIER
+
+ -- permit unspecified key uses
+
+ anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
+
+ -- extended key purpose OIDs
+
+ id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
+ id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
+ id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
+ id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
+ id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
+ id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
+
+ -- inhibit any policy OID and syntax
+
+ ext-InhibitAnyPolicy EXTENSION ::= {SYNTAX
+ SkipCerts IDENTIFIED BY id-ce-inhibitAnyPolicy }
+ id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
+
+ -- freshest (delta)CRL extension OID and syntax
+
+ ext-FreshestCRL EXTENSION ::= {SYNTAX
+ CRLDistributionPoints IDENTIFIED BY id-ce-freshestCRL }
+ id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
+
+ -- authority info access
+
+ ext-AuthorityInfoAccess EXTENSION ::= { SYNTAX
+ AuthorityInfoAccessSyntax IDENTIFIED BY
+ id-pe-authorityInfoAccess }
+ id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+
+ AuthorityInfoAccessSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+ AccessDescription ::= SEQUENCE {
+ accessMethod OBJECT IDENTIFIER,
+ accessLocation GeneralName }
+
+ -- subject info access
+
+ ext-SubjectInfoAccessSyntax EXTENSION ::= { SYNTAX
+ SubjectInfoAccessSyntax IDENTIFIED BY id-pe-subjectInfoAccess }
+ id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
+
+ SubjectInfoAccessSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+ -- CRL number extension OID and syntax
+
+ ext-CRLNumber EXTENSION ::= {SYNTAX
+ INTEGER (0..MAX) IDENTIFIED BY id-ce-cRLNumber }
+ id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
+
+ CRLNumber ::= INTEGER (0..MAX)
+ -- issuing distribution point extension OID and syntax
+
+ ext-IssuingDistributionPoint EXTENSION ::= { SYNTAX
+ IssuingDistributionPoint IDENTIFIED BY
+ id-ce-issuingDistributionPoint }
+ id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
+
+ IssuingDistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ onlySomeReasons [3] ReasonFlags OPTIONAL,
+ indirectCRL [4] BOOLEAN DEFAULT FALSE,
+ onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE
+ }
+ -- at most one of onlyContainsUserCerts, onlyContainsCACerts,
+ -- or onlyContainsAttributeCerts may be set to TRUE.
+
+ ext-DeltaCRLIndicator EXTENSION ::= { SYNTAX
+ CRLNumber IDENTIFIED BY id-ce-deltaCRLIndicator }
+ id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
+
+ -- CRL reasons extension OID and syntax
+
+ ext-CRLReason EXTENSION ::= { SYNTAX
+ CRLReason IDENTIFIED BY id-ce-cRLReasons }
+ id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
+
+ CRLReason ::= ENUMERATED {
+ unspecified (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6),
+ removeFromCRL (8),
+ privilegeWithdrawn (9),
+ aACompromise (10)
+ }
+
+ -- certificate issuer CRL entry extension OID and syntax
+
+ ext-CertificateIssuer EXTENSION ::= { SYNTAX
+ GeneralNames IDENTIFIED BY id-ce-certificateIssuer }
+ id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
+
+ -- hold instruction extension OID and syntax
+ ext-HoldInstructionCode EXTENSION ::= { SYNTAX
+ OBJECT IDENTIFIER IDENTIFIED BY id-ce-holdInstructionCode }
+ id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
+
+ -- ANSI x9 holdinstructions
+
+ holdInstruction OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
+ id-holdinstruction-none OBJECT IDENTIFIER ::=
+ {holdInstruction 1} -- deprecated
+ id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
+ {holdInstruction 2}
+ id-holdinstruction-reject OBJECT IDENTIFIER ::=
+ {holdInstruction 3}
+
+ -- invalidity date CRL entry extension OID and syntax
+
+ ext-InvalidityDate EXTENSION ::= { SYNTAX
+ GeneralizedTime IDENTIFIED BY id-ce-invalidityDate }
+ id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
+ -- Upper bounds
+ ubMax INTEGER ::= 32768
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAlgs-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAlgs-2009.asn1
new file mode 100644
index 0000000000..d58bcb5b19
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAlgs-2009.asn1
@@ -0,0 +1,528 @@
+ PKIXAlgs-2009 { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56) }
+
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ PUBLIC-KEY, SIGNATURE-ALGORITHM, DIGEST-ALGORITHM, SMIME-CAPS
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ mda-sha224, mda-sha256, mda-sha384, mda-sha512
+ FROM PKIX1-PSS-OAEP-Algorithms-2009
+ {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-rsa-pkalgs-02(54)} ;
+
+ --
+ -- Public Key (pk-) Algorithms
+ --
+
+ PublicKeys PUBLIC-KEY ::= {
+ pk-rsa |
+ pk-dsa |
+ pk-dh |
+ pk-kea,
+ ...,
+ pk-ec |
+ pk-ecDH |
+ pk-ecMQV
+ }
+
+ --
+ -- Signature Algorithms (sa-)
+ --
+
+ SignatureAlgs SIGNATURE-ALGORITHM ::= {
+ sa-rsaWithMD2 |
+ sa-rsaWithMD5 |
+ sa-rsaWithSHA1 |
+ sa-dsaWithSHA1 |
+ sa-ecdsaWithSHA1,
+ ..., -- Extensible
+ sa-dsaWithSHA224 |
+ sa-dsaWithSHA256 |
+ sa-ecdsaWithSHA224 |
+ sa-ecdsaWithSHA256 |
+ sa-ecdsaWithSHA384 |
+ sa-ecdsaWithSHA512
+ }
+
+ --
+ -- S/MIME CAPS for algorithms in this document
+ --
+ -- For all of the algorithms laid out in this document, the
+ -- parameters field for the S/MIME capabilities is defined as
+ -- ABSENT as there are no specific values that need to be known
+ -- by the receiver for negotiation.
+
+ --
+
+ SMimeCaps SMIME-CAPS ::= {
+ sa-rsaWithMD2.&smimeCaps |
+ sa-rsaWithMD5.&smimeCaps |
+ sa-rsaWithSHA1.&smimeCaps |
+ sa-dsaWithSHA1.&smimeCaps |
+ sa-dsaWithSHA224.&smimeCaps |
+ sa-dsaWithSHA256.&smimeCaps |
+ sa-ecdsaWithSHA1.&smimeCaps |
+ sa-ecdsaWithSHA224.&smimeCaps |
+ sa-ecdsaWithSHA256.&smimeCaps |
+ sa-ecdsaWithSHA384.&smimeCaps |
+ sa-ecdsaWithSHA512.&smimeCaps,
+ ... }
+
+ -- RSA PK Algorithm, Parameters, and Keys
+
+ pk-rsa PUBLIC-KEY ::= {
+ IDENTIFIER rsaEncryption
+ KEY RSAPublicKey
+ PARAMS TYPE NULL ARE absent
+ -- Private key format not in this module --
+ CERT-KEY-USAGE {digitalSignature, nonRepudiation,
+ keyEncipherment, dataEncipherment, keyCertSign, cRLSign}
+ }
+
+ rsaEncryption OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs-1(1) 1 }
+
+ RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER, -- n
+ publicExponent INTEGER -- e
+ }
+
+ -- DSA PK Algorithm, Parameters, and Keys
+
+ pk-dsa PUBLIC-KEY ::= {
+ IDENTIFIER id-dsa
+ KEY DSAPublicKey
+ PARAMS TYPE DSA-Params ARE inheritable
+ -- Private key format not in this module --
+ CERT-KEY-USAGE { digitalSignature, nonRepudiation, keyCertSign,
+ cRLSign }
+ }
+
+ id-dsa OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
+
+ DSA-Params ::= SEQUENCE {
+ p INTEGER,
+ q INTEGER,
+ g INTEGER
+ }
+
+ DSAPublicKey ::= INTEGER -- public key, y
+
+ -- Diffie-Hellman PK Algorithm, Parameters, and Keys
+
+ pk-dh PUBLIC-KEY ::= {
+ IDENTIFIER dhpublicnumber
+ KEY DHPublicKey
+ PARAMS TYPE DomainParameters ARE inheritable
+ -- Private key format not in this module --
+ CERT-KEY-USAGE {keyAgreement, encipherOnly, decipherOnly }
+ }
+
+ dhpublicnumber OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-x942(10046)
+ number-type(2) 1 }
+
+ DomainParameters ::= SEQUENCE {
+ p INTEGER, -- odd prime, p=jq +1
+ g INTEGER, -- generator, g
+ q INTEGER, -- factor of p-1
+ j INTEGER OPTIONAL, -- subgroup factor, j>= 2
+ validationParams ValidationParams OPTIONAL
+ }
+
+ ValidationParams ::= SEQUENCE {
+ seed BIT STRING,
+ pgenCounter INTEGER
+ }
+
+ DiffieHellmanPublicNumber ::= INTEGER -- according to http://wikisec.free.fr/crypto/crypto.html
+
+ DHPublicKey ::= INTEGER -- public key, y = g^x mod p
+
+ -- KEA PK Algorithm and Parameters
+
+ pk-kea PUBLIC-KEY ::= {
+ IDENTIFIER id-keyExchangeAlgorithm
+ -- key is not encoded --
+ PARAMS TYPE KEA-Params-Id ARE required
+ -- Private key format not in this module --
+ CERT-KEY-USAGE {keyAgreement, encipherOnly, decipherOnly }
+ }
+ id-keyExchangeAlgorithm OBJECT IDENTIFIER ::= {
+ joint-iso-itu-t(2) country(16) us(840) organization(1)
+ gov(101) dod(2) infosec(1) algorithms(1) 22 }
+
+ KEA-Params-Id ::= OCTET STRING
+
+ -- Elliptic Curve (EC) Signatures: Unrestricted Algorithms
+ -- (Section 2.1.1 of RFC 5480)
+ --
+ -- EC Unrestricted Algorithm ID -- -- this is used for ECDSA
+
+ pk-ec PUBLIC-KEY ::= {
+ IDENTIFIER id-ecPublicKey
+ KEY ECPoint
+ PARAMS TYPE ECParameters ARE required
+ -- Private key format not in this module --
+ CERT-KEY-USAGE { digitalSignature, nonRepudiation, keyAgreement,
+ keyCertSign, cRLSign }
+ }
+
+ ECPoint ::= OCTET STRING -- see RFC 5480 for syntax and restrictions
+
+ id-ecPublicKey OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+
+ -- Elliptic Curve (EC) Signatures: Restricted Algorithms
+ -- (Section 2.1.2 of RFC 5480)
+ --
+ -- EC Diffie-Hellman Algorithm ID
+
+ pk-ecDH PUBLIC-KEY ::= {
+ IDENTIFIER id-ecDH
+ KEY ECPoint
+ PARAMS TYPE ECParameters ARE required
+ -- Private key format not in this module --
+ CERT-KEY-USAGE { keyAgreement, encipherOnly, decipherOnly }
+ }
+
+ id-ecDH OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) schemes(1)
+ ecdh(12) }
+
+ -- EC Menezes-Qu-Vanstone Algorithm ID
+
+ pk-ecMQV PUBLIC-KEY ::= {
+ IDENTIFIER id-ecMQV
+ KEY ECPoint
+ PARAMS TYPE ECParameters ARE required
+ -- Private key format not in this module --
+ CERT-KEY-USAGE { keyAgreement, encipherOnly, decipherOnly }
+ }
+
+ id-ecMQV OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) schemes(1)
+ ecmqv(13) }
+
+ -- Parameters and Keys for both Restricted and Unrestricted EC
+
+ ECParameters ::= CHOICE {
+ namedCurve CURVE.&id({NamedCurve})
+ -- implicitCurve NULL
+ -- implicitCurve MUST NOT be used in PKIX
+ -- specifiedCurve SpecifiedCurve
+ -- specifiedCurve MUST NOT be used in PKIX
+ -- Details for specifiedCurve can be found in [X9.62]
+ -- Any future additions to this CHOICE should be coordinated
+ -- with ANSI X.9.
+ }
+ -- If you need to be able to decode ANSI X.9 parameter structures,
+ -- uncomment the implicitCurve and specifiedCurve above, and also
+ -- uncomment the following:
+ --(WITH COMPONENTS {namedCurve PRESENT})
+
+ -- Sec 2.1.1.1 Named Curve
+
+ CURVE ::= CLASS { &id OBJECT IDENTIFIER UNIQUE }
+ WITH SYNTAX { ID &id }
+
+ NamedCurve CURVE ::= {
+ { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } |
+ { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } |
+ { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } |
+ { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } |
+ { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 },
+ ... -- Extensible
+ }
+
+ -- Note in [X9.62] the curves are referred to as 'ansiX9' as
+ -- opposed to 'sec'. For example, secp192r1 is the same curve as
+ -- ansix9p192r1.
+
+ -- Note that in [PKI-ALG] the secp192r1 curve was referred to as
+ -- prime192v1 and the secp256r1 curve was referred to as
+ -- prime256v1.
+
+ -- Note that [FIPS186-3] refers to secp192r1 as P-192,
+ -- secp224r1 as P-224, secp256r1 as P-256, secp384r1 as P-384,
+ -- and secp521r1 as P-521.
+
+ secp192r1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
+ prime(1) 1 }
+
+ sect163k1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 1 }
+
+ sect163r2 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 15 }
+
+ secp224r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 33 }
+
+ sect233k1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 26 }
+
+ sect233r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 27 }
+
+ secp256r1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
+ prime(1) 7 }
+
+ sect283k1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 16 }
+
+ sect283r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 17 }
+
+ secp384r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 34 }
+
+ sect409k1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 36 }
+
+ sect409r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 37 }
+
+ secp521r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 35 }
+
+ sect571k1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 38 }
+
+ sect571r1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) certicom(132) curve(0) 39 }
+
+ -- RSA with MD-2
+
+ sa-rsaWithMD2 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER md2WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-md2 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS { IDENTIFIED BY md2WithRSAEncryption }
+ }
+
+ md2WithRSAEncryption OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs-1(1) 2 }
+
+ -- RSA with MD-5
+
+ sa-rsaWithMD5 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER md5WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-md5 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS { IDENTIFIED BY md5WithRSAEncryption }
+ }
+
+ md5WithRSAEncryption OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs-1(1) 4 }
+
+ -- RSA with SHA-1
+
+ sa-rsaWithSHA1 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER sha1WithRSAEncryption
+ PARAMS TYPE NULL ARE required
+ HASHES { mda-sha1 }
+ PUBLIC-KEYS { pk-rsa }
+ SMIME-CAPS {IDENTIFIED BY sha1WithRSAEncryption }
+ }
+
+ sha1WithRSAEncryption OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs-1(1) 5 }
+
+ -- DSA with SHA-1
+
+ sa-dsaWithSHA1 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER dsa-with-sha1
+ VALUE DSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha1 }
+ PUBLIC-KEYS { pk-dsa }
+ SMIME-CAPS { IDENTIFIED BY dsa-with-sha1 }
+ }
+
+ dsa-with-sha1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 3 }
+
+ -- DSA with SHA-224
+
+ sa-dsaWithSHA224 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER dsa-with-sha224
+ VALUE DSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha224 }
+ PUBLIC-KEYS { pk-dsa }
+ SMIME-CAPS { IDENTIFIED BY dsa-with-sha224 }
+ }
+
+ dsa-with-sha224 OBJECT IDENTIFIER ::= {
+ joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
+ csor(3) algorithms(4) id-dsa-with-sha2(3) 1 }
+
+ -- DSA with SHA-256
+
+ sa-dsaWithSHA256 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER dsa-with-sha256
+ VALUE DSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha256 }
+ PUBLIC-KEYS { pk-dsa }
+ SMIME-CAPS { IDENTIFIED BY dsa-with-sha256 }
+ }
+
+ dsa-with-sha256 OBJECT IDENTIFIER ::= {
+ joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
+ csor(3) algorithms(4) id-dsa-with-sha2(3) 2 }
+
+ -- ECDSA with SHA-1
+
+ sa-ecdsaWithSHA1 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER ecdsa-with-SHA1
+ VALUE ECDSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha1 }
+ PUBLIC-KEYS { pk-ec }
+ SMIME-CAPS {IDENTIFIED BY ecdsa-with-SHA1 }
+ }
+
+ ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045)
+ signatures(4) 1 }
+
+ -- ECDSA with SHA-224
+
+ sa-ecdsaWithSHA224 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER ecdsa-with-SHA224
+ VALUE ECDSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha224 }
+ PUBLIC-KEYS { pk-ec }
+ SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA224 }
+ }
+
+ ecdsa-with-SHA224 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ ecdsa-with-SHA2(3) 1 }
+
+ -- ECDSA with SHA-256
+
+ sa-ecdsaWithSHA256 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER ecdsa-with-SHA256
+ VALUE ECDSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha256 }
+ PUBLIC-KEYS { pk-ec }
+ SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA256 }
+ }
+
+ ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ ecdsa-with-SHA2(3) 2 }
+
+ -- ECDSA with SHA-384
+
+ sa-ecdsaWithSHA384 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER ecdsa-with-SHA384
+ VALUE ECDSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha384 }
+ PUBLIC-KEYS { pk-ec }
+ SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA384 }
+ }
+ ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ ecdsa-with-SHA2(3) 3 }
+
+ -- ECDSA with SHA-512
+
+ sa-ecdsaWithSHA512 SIGNATURE-ALGORITHM ::= {
+ IDENTIFIER ecdsa-with-SHA512
+ VALUE ECDSA-Sig-Value
+ PARAMS TYPE NULL ARE absent
+ HASHES { mda-sha512 }
+ PUBLIC-KEYS { pk-ec }
+ SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA512 }
+ }
+
+ ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ ecdsa-with-SHA2(3) 4 }
+
+ --
+ -- Signature Values
+ --
+
+ -- DSA
+
+ DSA-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER
+ }
+
+ -- ECDSA
+
+ ECDSA-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER
+ }
+
+ --
+ -- Message Digest Algorithms (mda-)
+ --
+
+ HashAlgs DIGEST-ALGORITHM ::= {
+ mda-md2 |
+ mda-md5 |
+ mda-sha1,
+ ... -- Extensible
+ }
+ -- MD-2
+
+ mda-md2 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-md2
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+
+ id-md2 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549)
+ digestAlgorithm(2) 2 }
+
+ -- MD-5
+
+ mda-md5 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-md5
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+
+ id-md5 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549)
+ digestAlgorithm(2) 5 }
+
+ -- SHA-1
+
+ mda-sha1 DIGEST-ALGORITHM ::= {
+ IDENTIFIER id-sha1
+ PARAMS TYPE NULL ARE preferredAbsent
+ }
+
+ id-sha1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) oiw(14) secsig(3)
+ algorithm(2) 26 }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAttributeCertificate-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAttributeCertificate-2009.asn1
new file mode 100644
index 0000000000..3ab074643f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXAttributeCertificate-2009.asn1
@@ -0,0 +1,292 @@
+ PKIXAttributeCertificate-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-attribute-cert-02(47)}
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ AttributeSet{}, Extensions{}, SecurityCategory{},
+ EXTENSION, ATTRIBUTE, SECURITY-CATEGORY
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57) }
+
+ AlgorithmIdentifier{}, SIGNATURE-ALGORITHM, DIGEST-ALGORITHM
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ -- IMPORTed module OIDs MAY change if [PKIXPROF] changes
+ -- PKIX Certificate Extensions
+
+ CertificateSerialNumber, UniqueIdentifier, id-pkix, id-pe, id-kp,
+ id-ad, id-at, SIGNED{}, SignatureAlgorithms
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)}
+
+ GeneralName, GeneralNames, id-ce, ext-AuthorityKeyIdentifier,
+ ext-AuthorityInfoAccess, ext-CRLDistributionPoints
+ FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+
+ ContentInfo
+ FROM CryptographicMessageSyntax-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) pkcs-9(9) smime(16) modules(0) id-mod-cms-2004-02(41) };
+ -- Define the set of extensions that can appear.
+ -- Some of these are imported from PKIX Cert
+
+ AttributeCertExtensions EXTENSION ::= {
+ ext-auditIdentity | ext-targetInformation |
+ ext-AuthorityKeyIdentifier | ext-AuthorityInfoAccess |
+ ext-CRLDistributionPoints | ext-noRevAvail | ext-ac-proxying |
+ ext-aaControls, ... }
+
+ ext-auditIdentity EXTENSION ::= { SYNTAX
+ OCTET STRING IDENTIFIED BY id-pe-ac-auditIdentity}
+
+ ext-targetInformation EXTENSION ::= { SYNTAX
+ Targets IDENTIFIED BY id-ce-targetInformation }
+
+ ext-noRevAvail EXTENSION ::= { SYNTAX
+ NULL IDENTIFIED BY id-ce-noRevAvail}
+
+ ext-ac-proxying EXTENSION ::= { SYNTAX
+ ProxyInfo IDENTIFIED BY id-pe-ac-proxying}
+
+ ext-aaControls EXTENSION ::= { SYNTAX
+ AAControls IDENTIFIED BY id-pe-aaControls}
+
+ -- Define the set of attributes used here
+
+ AttributesDefined ATTRIBUTE ::= { at-authenticationInfo |
+ at-accesIdentity | at-chargingIdentity | at-group |
+ at-role | at-clearance | at-encAttrs, ...}
+
+ at-authenticationInfo ATTRIBUTE ::= { TYPE SvceAuthInfo
+ IDENTIFIED BY id-aca-authenticationInfo}
+
+ at-accesIdentity ATTRIBUTE ::= { TYPE SvceAuthInfo
+ IDENTIFIED BY id-aca-accessIdentity}
+
+ at-chargingIdentity ATTRIBUTE ::= { TYPE IetfAttrSyntax
+ IDENTIFIED BY id-aca-chargingIdentity}
+
+ at-group ATTRIBUTE ::= { TYPE IetfAttrSyntax
+ IDENTIFIED BY id-aca-group}
+
+ at-role ATTRIBUTE ::= { TYPE RoleSyntax
+ IDENTIFIED BY id-at-role}
+
+ at-clearance ATTRIBUTE ::= { TYPE Clearance
+ IDENTIFIED BY id-at-clearance}
+ at-clearance-RFC3281 ATTRIBUTE ::= {TYPE Clearance-rfc3281
+ IDENTIFIED BY id-at-clearance-rfc3281 }
+
+ at-encAttrs ATTRIBUTE ::= { TYPE ContentInfo
+ IDENTIFIED BY id-aca-encAttrs}
+
+ --
+ -- OIDs used by Attribute Certificate Extensions
+ --
+
+ id-pe-ac-auditIdentity OBJECT IDENTIFIER ::= { id-pe 4 }
+ id-pe-aaControls OBJECT IDENTIFIER ::= { id-pe 6 }
+ id-pe-ac-proxying OBJECT IDENTIFIER ::= { id-pe 10 }
+ id-ce-targetInformation OBJECT IDENTIFIER ::= { id-ce 55 }
+ id-ce-noRevAvail OBJECT IDENTIFIER ::= { id-ce 56 }
+
+ --
+ -- OIDs used by Attribute Certificate Attributes
+ --
+
+ id-aca OBJECT IDENTIFIER ::= { id-pkix 10 }
+
+ id-aca-authenticationInfo OBJECT IDENTIFIER ::= { id-aca 1 }
+ id-aca-accessIdentity OBJECT IDENTIFIER ::= { id-aca 2 }
+ id-aca-chargingIdentity OBJECT IDENTIFIER ::= { id-aca 3 }
+ id-aca-group OBJECT IDENTIFIER ::= { id-aca 4 }
+ -- { id-aca 5 } is reserved
+ id-aca-encAttrs OBJECT IDENTIFIER ::= { id-aca 6 }
+
+ id-at-role OBJECT IDENTIFIER ::= { id-at 72}
+ id-at-clearance OBJECT IDENTIFIER ::= {
+ joint-iso-ccitt(2) ds(5) attributeType(4) clearance (55) }
+
+ -- Uncomment the following declaration and comment the above line if
+ -- using the id-at-clearance attribute as defined in [RFC3281]
+ -- id-at-clearance ::= id-at-clearance-3281
+
+ id-at-clearance-rfc3281 OBJECT IDENTIFIER ::= {
+ joint-iso-ccitt(2) ds(5) module(1) selected-attribute-types(5)
+ clearance (55) }
+
+ --
+ -- The syntax of an Attribute Certificate
+ --
+
+ AttributeCertificate ::= SIGNED{AttributeCertificateInfo}
+
+ AttributeCertificateInfo ::= SEQUENCE {
+ version AttCertVersion, -- version is v2
+ holder Holder,
+ issuer AttCertIssuer,
+ signature AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ serialNumber CertificateSerialNumber,
+ attrCertValidityPeriod AttCertValidityPeriod,
+ attributes SEQUENCE OF
+ AttributeSet{{AttributesDefined}},
+ issuerUniqueID UniqueIdentifier OPTIONAL,
+ extensions Extensions{{AttributeCertExtensions}} OPTIONAL
+ }
+
+ AttCertVersion ::= INTEGER { v2(1) }
+
+ Holder ::= SEQUENCE {
+ baseCertificateID [0] IssuerSerial OPTIONAL,
+ -- the issuer and serial number of
+ -- the holder's Public Key Certificate
+ entityName [1] GeneralNames OPTIONAL,
+ -- the name of the claimant or role
+ objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ -- used to directly authenticate the
+ -- holder, for example, an executable
+ }
+
+ ObjectDigestInfo ::= SEQUENCE {
+ digestedObjectType ENUMERATED {
+ publicKey (0),
+ publicKeyCert (1),
+ otherObjectTypes (2) },
+ -- otherObjectTypes MUST NOT
+ -- be used in this profile
+ otherObjectTypeID OBJECT IDENTIFIER OPTIONAL,
+ digestAlgorithm AlgorithmIdentifier{DIGEST-ALGORITHM, {...}},
+ objectDigest BIT STRING
+ }
+
+ AttCertIssuer ::= CHOICE {
+ v1Form GeneralNames, -- MUST NOT be used in this
+ -- profile
+ v2Form [0] V2Form -- v2 only
+ }
+
+ V2Form ::= SEQUENCE {
+ issuerName GeneralNames OPTIONAL,
+ baseCertificateID [0] IssuerSerial OPTIONAL,
+ objectDigestInfo [1] ObjectDigestInfo OPTIONAL
+ -- issuerName MUST be present in this profile
+ -- baseCertificateID and objectDigestInfo MUST
+ -- NOT be present in this profile
+ }
+
+ IssuerSerial ::= SEQUENCE {
+ issuer GeneralNames,
+ serial CertificateSerialNumber,
+ issuerUID UniqueIdentifier OPTIONAL
+ }
+
+ AttCertValidityPeriod ::= SEQUENCE {
+ notBeforeTime GeneralizedTime,
+ notAfterTime GeneralizedTime
+ }
+
+ --
+ -- Syntax used by Attribute Certificate Extensions
+ --
+
+ Targets ::= SEQUENCE OF Target
+
+ Target ::= CHOICE {
+ targetName [0] GeneralName,
+ targetGroup [1] GeneralName,
+ targetCert [2] TargetCert
+ }
+
+ TargetCert ::= SEQUENCE {
+ targetCertificate IssuerSerial,
+ targetName GeneralName OPTIONAL,
+ certDigestInfo ObjectDigestInfo OPTIONAL
+ }
+
+ AAControls ::= SEQUENCE {
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL,
+ permittedAttrs [0] AttrSpec OPTIONAL,
+ excludedAttrs [1] AttrSpec OPTIONAL,
+ permitUnSpecified BOOLEAN DEFAULT TRUE
+ }
+
+ AttrSpec::= SEQUENCE OF OBJECT IDENTIFIER
+
+ ProxyInfo ::= SEQUENCE OF Targets
+
+ --
+ -- Syntax used by Attribute Certificate Attributes
+ --
+ IetfAttrSyntax ::= SEQUENCE {
+ policyAuthority[0] GeneralNames OPTIONAL,
+ values SEQUENCE OF CHOICE {
+ octets OCTET STRING,
+ oid OBJECT IDENTIFIER,
+ string UTF8String
+ }
+ }
+
+ SvceAuthInfo ::= SEQUENCE {
+ service GeneralName,
+ ident GeneralName,
+ authInfo OCTET STRING OPTIONAL
+ }
+
+ RoleSyntax ::= SEQUENCE {
+ roleAuthority [0] GeneralNames OPTIONAL,
+ roleName [1] GeneralName
+ }
+
+ Clearance ::= SEQUENCE {
+ policyId OBJECT IDENTIFIER,
+ classList ClassList DEFAULT {unclassified},
+ securityCategories SET OF SecurityCategory
+ {{SupportedSecurityCategories}} OPTIONAL
+ }
+
+ -- Uncomment the following lines to support deprecated clearance
+ -- syntax and comment out previous Clearance.
+
+ -- Clearance ::= Clearance-rfc3281
+
+ Clearance-rfc3281 ::= SEQUENCE {
+ policyId [0] OBJECT IDENTIFIER,
+ classList [1] ClassList DEFAULT {unclassified},
+ securityCategories [2] SET OF SecurityCategory-rfc3281
+ {{SupportedSecurityCategories}} OPTIONAL
+ }
+
+ ClassList ::= BIT STRING {
+ unmarked (0),
+ unclassified (1),
+ restricted (2),
+ confidential (3),
+ secret (4),
+ topSecret (5)
+ }
+ SupportedSecurityCategories SECURITY-CATEGORY ::= { ... }
+
+ SecurityCategory-rfc3281{SECURITY-CATEGORY:Supported} ::= SEQUENCE {
+ type [0] IMPLICIT SECURITY-CATEGORY.
+ &id({Supported}),
+ value [1] EXPLICIT SECURITY-CATEGORY.
+ &Type({Supported}{@type})
+ }
+
+ ACClearAttrs ::= SEQUENCE {
+ acIssuer GeneralName,
+ acSerial INTEGER,
+ attrs SEQUENCE OF AttributeSet{{AttributesDefined}}
+ }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCMP-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCMP-2009.asn1
new file mode 100644
index 0000000000..968a142f28
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCMP-2009.asn1
@@ -0,0 +1,495 @@
+ PKIXCMP-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-cmp2000-02(50) }
+ DEFINITIONS EXPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ AttributeSet{}, Extensions{}, EXTENSION, ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}
+
+ AlgorithmIdentifier{}, SIGNATURE-ALGORITHM, ALGORITHM,
+ DIGEST-ALGORITHM, MAC-ALGORITHM
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ Certificate, CertificateList
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)}
+
+ GeneralName, KeyIdentifier
+ FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+
+ CertTemplate, PKIPublicationInfo, EncryptedValue, CertId,
+ CertReqMessages
+ FROM PKIXCRMF-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-crmf2005-02(55) }
+ -- see also the behavioral clarifications to CRMF codified in
+ -- Appendix C of this specification
+
+ CertificationRequest
+ FROM PKCS-10
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkcs10-2009(69)}
+ -- (specified in RFC 2986 with 1993 ASN.1 syntax and IMPLICIT
+ -- tags). Alternatively, implementers may directly include
+ -- the [PKCS10] syntax in this module
+ ;
+
+ -- the rest of the module contains locally defined OIDs and
+ -- constructs
+
+ CMPCertificate ::= CHOICE { x509v3PKCert Certificate, ... }
+ -- This syntax, while bits-on-the-wire compatible with the
+ -- standard X.509 definition of "Certificate", allows the
+ -- possibility of future certificate types (such as X.509
+ -- attribute certificates, WAP WTLS certificates, or other kinds
+ -- of certificates) within this certificate management protocol,
+ -- should a need ever arise to support such generality. Those
+ -- implementations that do not foresee a need to ever support
+ -- other certificate types MAY, if they wish, comment out the
+ -- above structure and "uncomment" the following one prior to
+ -- compiling this ASN.1 module. (Note that interoperability
+ -- with implementations that don't do this will be unaffected by
+ -- this change.)
+
+ -- CMPCertificate ::= Certificate
+
+ PKIMessage ::= SEQUENCE {
+ header PKIHeader,
+ body PKIBody,
+ protection [0] PKIProtection OPTIONAL,
+ extraCerts [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
+ OPTIONAL }
+
+ PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
+
+ PKIHeader ::= SEQUENCE {
+ pvno INTEGER { cmp1999(1), cmp2000(2) },
+ sender GeneralName,
+ -- identifies the sender
+ recipient GeneralName,
+ -- identifies the intended recipient
+ messageTime [0] GeneralizedTime OPTIONAL,
+ -- time of production of this message (used when sender
+ -- believes that the transport will be "suitable"; i.e.,
+ -- that the time will still be meaningful upon receipt)
+ protectionAlg [1] AlgorithmIdentifier{ALGORITHM, {...}}
+ OPTIONAL,
+ -- algorithm used for calculation of protection bits
+ senderKID [2] KeyIdentifier OPTIONAL,
+ recipKID [3] KeyIdentifier OPTIONAL,
+ -- to identify specific keys used for protection
+ transactionID [4] OCTET STRING OPTIONAL,
+ -- identifies the transaction; i.e., this will be the same in
+ -- corresponding request, response, certConf, and PKIConf
+ -- messages
+ senderNonce [5] OCTET STRING OPTIONAL,
+ recipNonce [6] OCTET STRING OPTIONAL,
+ -- nonces used to provide replay protection, senderNonce
+ -- is inserted by the creator of this message; recipNonce
+ -- is a nonce previously inserted in a related message by
+ -- the intended recipient of this message
+ freeText [7] PKIFreeText OPTIONAL,
+ -- this may be used to indicate context-specific instructions
+ -- (this field is intended for human consumption)
+ generalInfo [8] SEQUENCE SIZE (1..MAX) OF
+ InfoTypeAndValue OPTIONAL
+ -- this may be used to convey context-specific information
+ -- (this field not primarily intended for human consumption)
+ }
+
+ PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+ -- text encoded as UTF-8 String [RFC3629] (note: each
+ -- UTF8String MAY include an [RFC3066] language tag
+ -- to indicate the language of the contained text;
+ -- see [RFC2482] for details)
+
+ PKIBody ::= CHOICE { -- message-specific body elements
+ ir [0] CertReqMessages, --Initialization Request
+ ip [1] CertRepMessage, --Initialization Response
+ cr [2] CertReqMessages, --Certification Request
+ cp [3] CertRepMessage, --Certification Response
+ p10cr [4] CertificationRequest, --imported from [PKCS10]
+ popdecc [5] POPODecKeyChallContent, --pop Challenge
+ popdecr [6] POPODecKeyRespContent, --pop Response
+ kur [7] CertReqMessages, --Key Update Request
+ kup [8] CertRepMessage, --Key Update Response
+ krr [9] CertReqMessages, --Key Recovery Request
+ krp [10] KeyRecRepContent, --Key Recovery Response
+ rr [11] RevReqContent, --Revocation Request
+ rp [12] RevRepContent, --Revocation Response
+ ccr [13] CertReqMessages, --Cross-Cert. Request
+ ccp [14] CertRepMessage, --Cross-Cert. Response
+ ckuann [15] CAKeyUpdAnnContent, --CA Key Update Ann.
+ cann [16] CertAnnContent, --Certificate Ann.
+ rann [17] RevAnnContent, --Revocation Ann.
+ crlann [18] CRLAnnContent, --CRL Announcement
+ pkiconf [19] PKIConfirmContent, --Confirmation
+ nested [20] NestedMessageContent, --Nested Message
+ genm [21] GenMsgContent, --General Message
+ genp [22] GenRepContent, --General Response
+ error [23] ErrorMsgContent, --Error Message
+ certConf [24] CertConfirmContent, --Certificate confirm
+ pollReq [25] PollReqContent, --Polling request
+ pollRep [26] PollRepContent --Polling response
+ }
+
+ PKIProtection ::= BIT STRING
+
+ ProtectedPart ::= SEQUENCE {
+ header PKIHeader,
+ body PKIBody }
+
+ id-PasswordBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ usa(840) nt(113533) nsn(7) algorithms(66) 13 }
+ PBMParameter ::= SEQUENCE {
+ salt OCTET STRING,
+ -- note: implementations MAY wish to limit acceptable sizes
+ -- of this string to values appropriate for their environment
+ -- in order to reduce the risk of denial-of-service attacks
+ owf AlgorithmIdentifier{DIGEST-ALGORITHM, {...}},
+ -- AlgId for a One-Way Function (SHA-1 recommended)
+ iterationCount INTEGER,
+ -- number of times the OWF is applied
+ -- note: implementations MAY wish to limit acceptable sizes
+ -- of this integer to values appropriate for their environment
+ -- in order to reduce the risk of denial-of-service attacks
+ mac AlgorithmIdentifier{MAC-ALGORITHM, {...}}
+ -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
+ -- or HMAC [RFC2104, RFC2202])
+ }
+
+ id-DHBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ usa(840) nt(113533) nsn(7) algorithms(66) 30 }
+ DHBMParameter ::= SEQUENCE {
+ owf AlgorithmIdentifier{DIGEST-ALGORITHM, {...}},
+ -- AlgId for a One-Way Function (SHA-1 recommended)
+ mac AlgorithmIdentifier{MAC-ALGORITHM, {...}}
+ -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
+ -- or HMAC [RFC2104, RFC2202])
+ }
+
+ PKIStatus ::= INTEGER {
+ accepted (0),
+ -- you got exactly what you asked for
+ grantedWithMods (1),
+ -- you got something like what you asked for; the
+ -- requester is responsible for ascertaining the differences
+ rejection (2),
+ -- you don't get it, more information elsewhere in the message
+ waiting (3),
+ -- the request body part has not yet been processed; expect to
+ -- hear more later (note: proper handling of this status
+ -- response MAY use the polling req/rep PKIMessages specified
+ -- in Section 5.3.22; alternatively, polling in the underlying
+ -- transport layer MAY have some utility in this regard)
+ revocationWarning (4),
+ -- this message contains a warning that a revocation is
+ -- imminent
+ revocationNotification (5),
+ -- notification that a revocation has occurred
+ keyUpdateWarning (6)
+ -- update already done for the oldCertId specified in
+ -- CertReqMsg
+ }
+
+ PKIFailureInfo ::= BIT STRING {
+ -- since we can fail in more than one way!
+ -- More codes may be added in the future if/when required.
+ badAlg (0),
+ -- unrecognized or unsupported Algorithm Identifier
+ badMessageCheck (1),
+ -- integrity check failed (e.g., signature did not verify)
+ badRequest (2),
+ -- transaction not permitted or supported
+ badTime (3),
+ -- messageTime was not sufficiently close to the system time,
+ -- as defined by local policy
+ badCertId (4),
+ -- no certificate could be found matching the provided criteria
+ badDataFormat (5),
+ -- the data submitted has the wrong format
+ wrongAuthority (6),
+ -- the authority indicated in the request is different from the
+ -- one creating the response token
+ incorrectData (7),
+ -- the requester's data is incorrect (for notary services)
+ missingTimeStamp (8),
+ -- when the timestamp is missing but should be there
+ -- (by policy)
+ badPOP (9),
+ -- the proof-of-possession failed
+ certRevoked (10),
+ -- the certificate has already been revoked
+ certConfirmed (11),
+ -- the certificate has already been confirmed
+ wrongIntegrity (12),
+ -- invalid integrity, password based instead of signature or
+ -- vice versa
+ badRecipientNonce (13),
+ -- invalid recipient nonce, either missing or wrong value
+ timeNotAvailable (14),
+ -- the TSA's time source is not available
+ unacceptedPolicy (15),
+ -- the requested TSA policy is not supported by the TSA
+ unacceptedExtension (16),
+ -- the requested extension is not supported by the TSA
+ addInfoNotAvailable (17),
+ -- the additional information requested could not be
+ -- understood or is not available
+ badSenderNonce (18),
+ -- invalid sender nonce, either missing or wrong size
+ badCertTemplate (19),
+ -- invalid cert. template or missing mandatory information
+ signerNotTrusted (20),
+ -- signer of the message unknown or not trusted
+ transactionIdInUse (21),
+ -- the transaction identifier is already in use
+ unsupportedVersion (22),
+ -- the version of the message is not supported
+ notAuthorized (23),
+ -- the sender was not authorized to make the preceding
+ -- request or perform the preceding action
+ systemUnavail (24),
+ -- the request cannot be handled due to system unavailability
+ systemFailure (25),
+ -- the request cannot be handled due to system failure
+ duplicateCertReq (26)
+ -- certificate cannot be issued because a duplicate
+ -- certificate already exists
+ }
+
+ PKIStatusInfo ::= SEQUENCE {
+ status PKIStatus,
+ statusString PKIFreeText OPTIONAL,
+ failInfo PKIFailureInfo OPTIONAL }
+
+ OOBCert ::= CMPCertificate
+
+ OOBCertHash ::= SEQUENCE {
+ hashAlg [0] AlgorithmIdentifier{DIGEST-ALGORITHM, {...}}
+ OPTIONAL,
+ certId [1] CertId OPTIONAL,
+ hashVal BIT STRING
+ -- hashVal is calculated over the DER encoding of the
+ -- self-signed certificate with the identifier certID.
+ }
+
+ POPODecKeyChallContent ::= SEQUENCE OF Challenge
+ -- One Challenge per encryption key certification request (in the
+ -- same order as these requests appear in CertReqMessages).
+
+ Challenge ::= SEQUENCE {
+ owf AlgorithmIdentifier{DIGEST-ALGORITHM, {...}}
+ OPTIONAL,
+ -- MUST be present in the first Challenge; MAY be omitted in
+ -- any subsequent Challenge in POPODecKeyChallContent (if
+ -- omitted, then the owf used in the immediately preceding
+ -- Challenge is to be used).
+ witness OCTET STRING,
+ -- the result of applying the one-way function (owf) to a
+ -- randomly-generated INTEGER, A. [Note that a different
+ -- INTEGER MUST be used for each Challenge.]
+ challenge OCTET STRING
+ -- the encryption (under the public key for which the cert.
+ -- request is being made) of Rand, where Rand is specified as
+ -- Rand ::= SEQUENCE {
+ -- int INTEGER,
+ -- - the randomly-generated INTEGER A (above)
+ -- sender GeneralName
+ -- - the sender's name (as included in PKIHeader)
+ -- }
+ }
+
+ POPODecKeyRespContent ::= SEQUENCE OF INTEGER
+ -- One INTEGER per encryption key certification request (in the
+ -- same order as these requests appear in CertReqMessages). The
+ -- retrieved INTEGER A (above) is returned to the sender of the
+ -- corresponding Challenge.
+
+ CertRepMessage ::= SEQUENCE {
+ caPubs [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
+ OPTIONAL,
+ response SEQUENCE OF CertResponse }
+
+ CertResponse ::= SEQUENCE {
+ certReqId INTEGER,
+ -- to match this response with the corresponding request (a value
+ -- of -1 is to be used if certReqId is not specified in the
+ -- corresponding request)
+ status PKIStatusInfo,
+ certifiedKeyPair CertifiedKeyPair OPTIONAL,
+ rspInfo OCTET STRING OPTIONAL
+ -- analogous to the id-regInfo-utf8Pairs string defined
+ -- for regInfo in CertReqMsg [RFC4211]
+ }
+
+ CertifiedKeyPair ::= SEQUENCE {
+ certOrEncCert CertOrEncCert,
+ privateKey [0] EncryptedValue OPTIONAL,
+ -- see [RFC4211] for comment on encoding
+ publicationInfo [1] PKIPublicationInfo OPTIONAL }
+
+ CertOrEncCert ::= CHOICE {
+ certificate [0] CMPCertificate,
+ encryptedCert [1] EncryptedValue }
+ KeyRecRepContent ::= SEQUENCE {
+ status PKIStatusInfo,
+ newSigCert [0] CMPCertificate OPTIONAL,
+ caCerts [1] SEQUENCE SIZE (1..MAX) OF
+ CMPCertificate OPTIONAL,
+ keyPairHist [2] SEQUENCE SIZE (1..MAX) OF
+ CertifiedKeyPair OPTIONAL }
+
+ RevReqContent ::= SEQUENCE OF RevDetails
+
+ RevDetails ::= SEQUENCE {
+ certDetails CertTemplate,
+ -- allows requester to specify as much as they can about
+ -- the cert. for which revocation is requested
+ -- (e.g., for cases in which serialNumber is not available)
+ crlEntryDetails Extensions{{...}} OPTIONAL
+ -- requested crlEntryExtensions
+ }
+
+ RevRepContent ::= SEQUENCE {
+ status SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
+ -- in same order as was sent in RevReqContent
+ revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
+ -- IDs for which revocation was requested
+ -- (same order as status)
+ crls [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL
+ -- the resulting CRLs (there may be more than one)
+ }
+
+ CAKeyUpdAnnContent ::= SEQUENCE {
+ oldWithNew CMPCertificate, -- old pub signed with new priv
+ newWithOld CMPCertificate, -- new pub signed with old priv
+ newWithNew CMPCertificate -- new pub signed with new priv
+ }
+
+ CertAnnContent ::= CMPCertificate
+
+ RevAnnContent ::= SEQUENCE {
+ status PKIStatus,
+ certId CertId,
+ willBeRevokedAt GeneralizedTime,
+ badSinceDate GeneralizedTime,
+ crlDetails Extensions{{...}} OPTIONAL
+ -- extra CRL details (e.g., crl number, reason, location, etc.)
+ }
+
+ CRLAnnContent ::= SEQUENCE OF CertificateList
+ PKIConfirmContent ::= NULL
+
+ NestedMessageContent ::= PKIMessages
+
+ INFO-TYPE-AND-VALUE ::= TYPE-IDENTIFIER
+
+ InfoTypeAndValue ::= SEQUENCE {
+ infoType INFO-TYPE-AND-VALUE.
+ &id({SupportedInfoSet}),
+ infoValue INFO-TYPE-AND-VALUE.
+ &Type({SupportedInfoSet}{@infoType}) }
+
+ SupportedInfoSet INFO-TYPE-AND-VALUE ::= { ... }
+
+ -- Example InfoTypeAndValue contents include, but are not limited
+ -- to, the following (uncomment in this ASN.1 module and use as
+ -- appropriate for a given environment):
+ --
+ -- id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1}
+ -- CAProtEncCertValue ::= CMPCertificate
+ -- id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2}
+ -- SignKeyPairTypesValue ::= SEQUENCE OF
+ -- AlgorithmIdentifier{{...}}
+ -- id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3}
+ -- EncKeyPairTypesValue ::= SEQUENCE OF
+ -- AlgorithmIdentifier{{...}}
+ -- id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
+ -- PreferredSymmAlgValue ::= AlgorithmIdentifier{{...}}
+ -- id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5}
+ -- CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent
+ -- id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6}
+ -- CurrentCRLValue ::= CertificateList
+ -- id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7}
+ -- UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER
+ -- id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10}
+ -- KeyPairParamReqValue ::= OBJECT IDENTIFIER
+ -- id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11}
+ -- KeyPairParamRepValue ::= AlgorithmIdentifer
+ -- id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12}
+ -- RevPassphraseValue ::= EncryptedValue
+ -- id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13}
+ -- ImplicitConfirmValue ::= NULL
+ -- id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14}
+ -- ConfirmWaitTimeValue ::= GeneralizedTime
+ -- id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15}
+ -- OrigPKIMessageValue ::= PKIMessages
+ -- id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16}
+ -- SuppLangTagsValue ::= SEQUENCE OF UTF8String
+ --
+ -- where
+ --
+ -- id-pkix OBJECT IDENTIFIER ::= {
+ -- iso(1) identified-organization(3)
+ -- dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
+ -- and
+ -- id-it OBJECT IDENTIFIER ::= {id-pkix 4}
+ --
+ --
+ -- This construct MAY also be used to define new PKIX Certificate
+ -- Management Protocol request and response messages, or general-
+ -- purpose (e.g., announcement) messages for future needs or for
+ -- specific environments.
+
+ GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
+
+ -- May be sent by EE, RA, or CA (depending on message content).
+ -- The OPTIONAL infoValue parameter of InfoTypeAndValue will
+ -- typically be omitted for some of the examples given above.
+ -- The receiver is free to ignore any contained OBJECT IDs that it
+ -- does not recognize. If sent from EE to CA, the empty set
+ -- indicates that the CA may send
+ -- any/all information that it wishes.
+
+ GenRepContent ::= SEQUENCE OF InfoTypeAndValue
+ -- Receiver MAY ignore any contained OIDs that it does not
+ -- recognize.
+
+ ErrorMsgContent ::= SEQUENCE {
+ pKIStatusInfo PKIStatusInfo,
+ errorCode INTEGER OPTIONAL,
+ -- implementation-specific error codes
+ errorDetails PKIFreeText OPTIONAL
+ -- implementation-specific error details
+ }
+
+ CertConfirmContent ::= SEQUENCE OF CertStatus
+
+ CertStatus ::= SEQUENCE {
+ certHash OCTET STRING,
+ -- the hash of the certificate, using the same hash algorithm
+ -- as is used to create and verify the certificate signature
+ certReqId INTEGER,
+ -- to match this confirmation with the corresponding req/rep
+ statusInfo PKIStatusInfo OPTIONAL }
+
+ PollReqContent ::= SEQUENCE OF SEQUENCE {
+ certReqId INTEGER }
+
+ PollRepContent ::= SEQUENCE OF SEQUENCE {
+ certReqId INTEGER,
+ checkAfter INTEGER, -- time in seconds
+ reason PKIFreeText OPTIONAL }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCRMF-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCRMF-2009.asn1
new file mode 100644
index 0000000000..1c0b780499
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/PKIXCRMF-2009.asn1
@@ -0,0 +1,409 @@
+ PKIXCRMF-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-crmf2005-02(55)}
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ AttributeSet{}, Extensions{}, EXTENSION, ATTRIBUTE,
+ SingleAttribute{}
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkixCommon-02(57) }
+
+ AlgorithmIdentifier{}, SIGNATURE-ALGORITHM, ALGORITHM,
+ DIGEST-ALGORITHM, MAC-ALGORITHM, PUBLIC-KEY
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ Version, Name, Time, SubjectPublicKeyInfo, UniqueIdentifier, id-pkix,
+ SignatureAlgorithms
+ FROM PKIX1Explicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)}
+
+ GeneralName, CertExtensions
+ FROM PKIX1Implicit-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}
+
+ EnvelopedData, CONTENT-TYPE
+ FROM CryptographicMessageSyntax-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cms-2004-02(41)}
+ maca-hMAC-SHA1
+ FROM CryptographicMessageSyntaxAlgorithms-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cmsalg-2001-02(37) }
+
+ mda-sha1
+ FROM PKIXAlgs-2009
+ { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56) } ;
+
+ -- arc for Internet X.509 PKI protocols and their components
+
+ id-pkip OBJECT IDENTIFIER ::= { id-pkix 5 }
+
+ id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 }
+
+ id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types
+
+ -- Core definitions for this module
+
+ CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
+
+ CertReqMsg ::= SEQUENCE {
+ certReq CertRequest,
+ popo ProofOfPossession OPTIONAL,
+ -- content depends upon key type
+ regInfo SEQUENCE SIZE(1..MAX) OF
+ SingleAttribute{{RegInfoSet}} OPTIONAL }
+
+ CertRequest ::= SEQUENCE {
+ certReqId INTEGER,
+ -- ID for matching request and reply
+ certTemplate CertTemplate,
+ -- Selected fields of cert to be issued
+ controls Controls OPTIONAL }
+ -- Attributes affecting issuance
+
+ CertTemplate ::= SEQUENCE {
+ version [0] Version OPTIONAL,
+ serialNumber [1] INTEGER OPTIONAL,
+ signingAlg [2] AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}} OPTIONAL,
+ issuer [3] Name OPTIONAL,
+ validity [4] OptionalValidity OPTIONAL,
+ subject [5] Name OPTIONAL,
+ publicKey [6] SubjectPublicKeyInfo OPTIONAL,
+ issuerUID [7] UniqueIdentifier OPTIONAL,
+ subjectUID [8] UniqueIdentifier OPTIONAL,
+ extensions [9] Extensions{{CertExtensions}} OPTIONAL }
+
+ OptionalValidity ::= SEQUENCE {
+ notBefore [0] Time OPTIONAL,
+ notAfter [1] Time OPTIONAL } -- at least one MUST be present
+
+ Controls ::= SEQUENCE SIZE(1..MAX) OF SingleAttribute
+ {{RegControlSet}}
+
+ ProofOfPossession ::= CHOICE {
+ raVerified [0] NULL,
+ -- used if the RA has already verified that the requester is in
+ -- possession of the private key
+ signature [1] POPOSigningKey,
+ keyEncipherment [2] POPOPrivKey,
+ keyAgreement [3] POPOPrivKey }
+
+ POPOSigningKey ::= SEQUENCE {
+ poposkInput [0] POPOSigningKeyInput OPTIONAL,
+ algorithmIdentifier AlgorithmIdentifier{SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ signature BIT STRING }
+ -- The signature (using "algorithmIdentifier") is on the
+ -- DER-encoded value of poposkInput. NOTE: If the CertReqMsg
+ -- certReq CertTemplate contains the subject and publicKey values,
+ -- then poposkInput MUST be omitted and the signature MUST be
+ -- computed over the DER-encoded value of CertReqMsg certReq. If
+ -- the CertReqMsg certReq CertTemplate does not contain both the
+ -- public key and subject values (i.e., if it contains only one
+ -- of these, or neither), then poposkInput MUST be present and
+ -- MUST be signed.
+
+ POPOSigningKeyInput ::= SEQUENCE {
+ authInfo CHOICE {
+ sender [0] GeneralName,
+ -- used only if an authenticated identity has been
+ -- established for the sender (e.g., a DN from a
+ -- previously-issued and currently-valid certificate)
+ publicKeyMAC PKMACValue },
+ -- used if no authenticated GeneralName currently exists for
+ -- the sender; publicKeyMAC contains a password-based MAC
+ -- on the DER-encoded value of publicKey
+ publicKey SubjectPublicKeyInfo } -- from CertTemplate
+
+ PKMACValue ::= SEQUENCE {
+ algId AlgorithmIdentifier{MAC-ALGORITHM,
+ {Password-MACAlgorithms}},
+ value BIT STRING }
+
+ --
+ -- Define the currently only acceptable MAC algorithm to be used
+ -- for the PKMACValue structure
+ --
+
+ id-PasswordBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ usa(840) nt(113533) nsn(7) algorithms(66) 13 }
+
+ Password-MACAlgorithms MAC-ALGORITHM ::= {
+ {IDENTIFIER id-PasswordBasedMac
+ PARAMS TYPE PBMParameter ARE required
+ IS-KEYED-MAC TRUE
+ }, ...
+ }
+
+ PBMParameter ::= SEQUENCE {
+ salt OCTET STRING,
+ owf AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {DigestAlgorithms}},
+ -- AlgId for a One-Way Function (SHA-1 recommended)
+ iterationCount INTEGER,
+ -- number of times the OWF is applied
+ mac AlgorithmIdentifier{MAC-ALGORITHM,
+ {MACAlgorithms}}
+ -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC, or HMAC
+ }
+
+ DigestAlgorithms DIGEST-ALGORITHM ::= {
+ mda-sha1, ...
+ }
+
+ MACAlgorithms MAC-ALGORITHM ::= {
+ -- The modules containing the ASN.1 for the DES and 3DES MAC
+ -- algorithms have not been updated at the time that this is
+ -- being published. Users of this module should define the
+ -- appropriate MAC-ALGORITHM objects and uncomment the
+ -- following lines if they support these MAC algorithms.
+ -- maca-des-mac | maca-3des-mac --
+ maca-hMAC-SHA1,
+ ...
+ }
+
+ POPOPrivKey ::= CHOICE {
+ thisMessage [0] BIT STRING, -- Deprecated
+ -- possession is proven in this message (which contains
+ -- the private key itself (encrypted for the CA))
+ subsequentMessage [1] SubsequentMessage,
+ -- possession will be proven in a subsequent message
+ dhMAC [2] BIT STRING, -- Deprecated
+ agreeMAC [3] PKMACValue,
+ encryptedKey [4] EnvelopedData }
+ -- for keyAgreement (only), possession is proven in this message
+ -- (which contains a MAC (over the DER-encoded value of the
+ -- certReq parameter in CertReqMsg, which MUST include both
+ -- subject and publicKey) based on a key derived from the end
+ -- entity's private DH key and the CA's public DH key);
+
+ SubsequentMessage ::= INTEGER {
+ encrCert (0),
+ -- requests that resulting certificate be encrypted for the
+ -- end entity (following which, POP will be proven in a
+ -- confirmation message)
+ challengeResp (1) }
+ -- requests that CA engage in challenge-response exchange with
+ -- end entity in order to prove private key possession
+
+ --
+ -- id-ct-encKeyWithID content type used as the content type for the
+ -- EnvelopedData in POPOPrivKey.
+ -- It contains both a private key and an identifier for key escrow
+ -- agents to check against recovery requestors.
+ --
+
+ ct-encKeyWithID CONTENT-TYPE ::=
+ { EncKeyWithID IDENTIFIED BY id-ct-encKeyWithID }
+
+ id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21}
+
+ EncKeyWithID ::= SEQUENCE {
+ privateKey PrivateKeyInfo,
+ identifier CHOICE {
+ string UTF8String,
+ generalName GeneralName
+ } OPTIONAL
+ }
+
+ PrivateKeyInfo ::= SEQUENCE {
+ version INTEGER,
+ privateKeyAlgorithm AlgorithmIdentifier{PUBLIC-KEY, {...}},
+ privateKey OCTET STRING,
+ -- Structure of public key is in PUBLIC-KEY.&PrivateKey
+ attributes [0] IMPLICIT Attributes OPTIONAL
+ }
+
+ Attributes ::= SET OF AttributeSet{{PrivateKeyAttributes}}
+ PrivateKeyAttributes ATTRIBUTE ::= {...}
+
+ --
+ -- 6. Registration Controls in CRMF
+ --
+
+ id-regCtrl OBJECT IDENTIFIER ::= { id-pkip 1 }
+
+ RegControlSet ATTRIBUTE ::= {
+ regCtrl-regToken | regCtrl-authenticator |
+ regCtrl-pkiPublicationInfo | regCtrl-pkiArchiveOptions |
+ regCtrl-oldCertID | regCtrl-protocolEncrKey, ... }
+
+ --
+ -- 6.1. Registration Token Control
+ --
+
+ regCtrl-regToken ATTRIBUTE ::=
+ { TYPE RegToken IDENTIFIED BY id-regCtrl-regToken }
+
+ id-regCtrl-regToken OBJECT IDENTIFIER ::= { id-regCtrl 1 }
+
+ RegToken ::= UTF8String
+
+ --
+ -- 6.2. Authenticator Control
+ --
+
+ regCtrl-authenticator ATTRIBUTE ::=
+ { TYPE Authenticator IDENTIFIED BY id-regCtrl-authenticator }
+
+ id-regCtrl-authenticator OBJECT IDENTIFIER ::= { id-regCtrl 2 }
+
+ Authenticator ::= UTF8String
+
+ --
+ -- 6.3. Publication Information Control
+ --
+
+ regCtrl-pkiPublicationInfo ATTRIBUTE ::=
+ { TYPE PKIPublicationInfo IDENTIFIED BY
+ id-regCtrl-pkiPublicationInfo }
+
+ id-regCtrl-pkiPublicationInfo OBJECT IDENTIFIER ::= { id-regCtrl 3 }
+
+ PKIPublicationInfo ::= SEQUENCE {
+ action INTEGER {
+ dontPublish (0),
+ pleasePublish (1) },
+ pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
+ -- pubInfos MUST NOT be present if action is "dontPublish"
+ -- (if action is "pleasePublish" and pubInfos is omitted,
+ -- "dontCare" is assumed)
+
+ SinglePubInfo ::= SEQUENCE {
+ pubMethod INTEGER {
+ dontCare (0),
+ x500 (1),
+ web (2),
+ ldap (3) },
+ pubLocation GeneralName OPTIONAL }
+
+ --
+ -- 6.4. Archive Options Control
+ --
+
+ regCtrl-pkiArchiveOptions ATTRIBUTE ::=
+ { TYPE PKIArchiveOptions IDENTIFIED BY
+ id-regCtrl-pkiArchiveOptions }
+
+ id-regCtrl-pkiArchiveOptions OBJECT IDENTIFIER ::= { id-regCtrl 4 }
+
+ PKIArchiveOptions ::= CHOICE {
+ encryptedPrivKey [0] EncryptedKey,
+ -- the actual value of the private key
+ keyGenParameters [1] KeyGenParameters,
+ -- parameters that allow the private key to be re-generated
+ archiveRemGenPrivKey [2] BOOLEAN }
+ -- set to TRUE if sender wishes receiver to archive the private
+ -- key of a key pair that the receiver generates in response to
+ -- this request; set to FALSE if no archive is desired.
+
+ EncryptedKey ::= CHOICE {
+ encryptedValue EncryptedValue, -- Deprecated
+ envelopedData [0] EnvelopedData }
+ -- The encrypted private key MUST be placed in the envelopedData
+ -- encryptedContentInfo encryptedContent OCTET STRING.
+
+ --
+ -- We skipped doing the full constraints here since this structure
+ -- has been deprecated in favor of EnvelopedData
+ --
+
+ EncryptedValue ::= SEQUENCE {
+ intendedAlg [0] AlgorithmIdentifier{ALGORITHM, {...}} OPTIONAL,
+ -- the intended algorithm for which the value will be used
+ symmAlg [1] AlgorithmIdentifier{ALGORITHM, {...}} OPTIONAL,
+ -- the symmetric algorithm used to encrypt the value
+ encSymmKey [2] BIT STRING OPTIONAL,
+ -- the (encrypted) symmetric key used to encrypt the value
+ keyAlg [3] AlgorithmIdentifier{ALGORITHM, {...}} OPTIONAL,
+ -- algorithm used to encrypt the symmetric key
+ valueHint [4] OCTET STRING OPTIONAL,
+ -- a brief description or identifier of the encValue content
+ -- (may be meaningful only to the sending entity, and used only
+ -- if EncryptedValue might be re-examined by the sending entity
+ -- in the future)
+ encValue BIT STRING }
+ -- the encrypted value itself
+ -- When EncryptedValue is used to carry a private key (as opposed to
+ -- a certificate), implementations MUST support the encValue field
+ -- containing an encrypted PrivateKeyInfo as defined in [PKCS11],
+ -- section 12.11. If encValue contains some other format/encoding
+ -- for the private key, the first octet of valueHint MAY be used
+ -- to indicate the format/encoding (but note that the possible values
+ -- of this octet are not specified at this time). In all cases, the
+ -- intendedAlg field MUST be used to indicate at least the OID of
+ -- the intended algorithm of the private key, unless this information
+ -- is known a priori to both sender and receiver by some other means.
+
+ KeyGenParameters ::= OCTET STRING
+
+ --
+ -- 6.5. OldCert ID Control
+ --
+
+ regCtrl-oldCertID ATTRIBUTE ::=
+ { TYPE OldCertId IDENTIFIED BY id-regCtrl-oldCertID }
+
+ id-regCtrl-oldCertID OBJECT IDENTIFIER ::= { id-regCtrl 5 }
+
+ OldCertId ::= CertId
+
+ CertId ::= SEQUENCE {
+ issuer GeneralName,
+ serialNumber INTEGER }
+
+ --
+ -- 6.6. Protocol Encryption Key Control
+ --
+
+ regCtrl-protocolEncrKey ATTRIBUTE ::=
+ { TYPE ProtocolEncrKey IDENTIFIED BY id-regCtrl-protocolEncrKey }
+ id-regCtrl-protocolEncrKey OBJECT IDENTIFIER ::= { id-regCtrl 6 }
+
+ ProtocolEncrKey ::= SubjectPublicKeyInfo
+
+ --
+ -- 7. Registration Info in CRMF
+ --
+
+ id-regInfo OBJECT IDENTIFIER ::= { id-pkip 2 }
+
+ RegInfoSet ATTRIBUTE ::=
+ { regInfo-utf8Pairs | regInfo-certReq }
+
+ --
+ -- 7.1. utf8Pairs RegInfo Control
+ --
+
+ regInfo-utf8Pairs ATTRIBUTE ::=
+ { TYPE UTF8Pairs IDENTIFIED BY id-regInfo-utf8Pairs }
+
+ id-regInfo-utf8Pairs OBJECT IDENTIFIER ::= { id-regInfo 1 }
+ --with syntax
+ UTF8Pairs ::= UTF8String
+
+ --
+ -- 7.2. certReq RegInfo Control
+ --
+
+ regInfo-certReq ATTRIBUTE ::=
+ { TYPE CertReq IDENTIFIED BY id-regInfo-certReq }
+
+ id-regInfo-certReq OBJECT IDENTIFIER ::= { id-regInfo 2 }
+ --with syntax
+ CertReq ::= CertRequest
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Protected-Part-Descriptors.asn1
index 5512f1590b..5512f1590b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Protected-Part-Descriptors.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/ProtocolObjectIdentifiers.asn1
index d6e88a2e47..d6e88a2e47 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/ProtocolObjectIdentifiers.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Coding-Attributes.asn1
index 258c5f0b23..258c5f0b23 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Coding-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Presentation-Attributes.asn1
index c8f3a2ff33..c8f3a2ff33 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Presentation-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Profile-Attributes.asn1
index 365144ff35..365144ff35 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Raster-Gr-Profile-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Reliable-Transfer-APDU.asn1
index d00570b7e7..d00570b7e7 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Reliable-Transfer-APDU.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Abstract-Syntaxes.asn1
index 4a59cc403b..4a59cc403b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Abstract-Syntaxes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Generic-ROS-PDUs.asn1
index e55ea3c05e..e55ea3c05e 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Generic-ROS-PDUs.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Information-Objects-extensions.asn1
index 671cf0e780..671cf0e780 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Information-Objects-extensions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Information-Objects.asn1
index b497e4126b..b497e4126b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Information-Objects.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Realizations.asn1
index 73b49c8d7a..73b49c8d7a 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Realizations.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Useful-Definitions.asn1
index e526ff4600..e526ff4600 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Remote-Operations-Useful-Definitions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/SCVP-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/SCVP-2009.asn1
new file mode 100644
index 0000000000..f74f76ff7c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/SCVP-2009.asn1
@@ -0,0 +1,608 @@
+ SCVP-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-scvp-02(52) }
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ Extensions{}, EXTENSION, ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57) }
+
+ AlgorithmIdentifier{}, SIGNATURE-ALGORITHM, PUBLIC-KEY, KEY-AGREE,
+ DIGEST-ALGORITHM, KEY-DERIVATION, MAC-ALGORITHM
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ Certificate, CertificateList, CertificateSerialNumber,
+ SignatureAlgorithms, SubjectPublicKeyInfo
+ FROM PKIX1Explicit-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51) }
+
+ GeneralNames, GeneralName, KeyUsage, KeyPurposeId
+ FROM PKIX1Implicit-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59) }
+
+ AttributeCertificate
+ FROM PKIXAttributeCertificate-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-attribute-cert-02(47) }
+
+ OCSPResponse
+ FROM OCSP-2009
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-ocsp-02(48) }
+
+ ContentInfo, CONTENT-TYPE
+ FROM CryptographicMessageSyntax-2009
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cms-2004-02(41) }
+
+ mda-sha1
+ FROM PKIXAlgs-2009
+ { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56) } ;
+
+ ContentTypes CONTENT-TYPE ::= {ct-scvp-certValRequest |
+ ct-scvp-certValResponse | ct-scvp-valPolRequest |
+ ct-scvp-valPolResponse, ... }
+
+ id-ct OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ id-smime(16) 1 }
+
+ ct-scvp-certValRequest CONTENT-TYPE ::=
+ { CVRequest IDENTIFIED BY id-ct-scvp-certValRequest }
+
+ id-ct-scvp-certValRequest OBJECT IDENTIFIER ::= { id-ct 10 }
+
+ -- SCVP Certificate Validation Request
+
+ CVRequest ::= SEQUENCE {
+ cvRequestVersion INTEGER DEFAULT 1,
+ query Query,
+ requestorRef [0] GeneralNames OPTIONAL,
+ requestNonce [1] OCTET STRING OPTIONAL,
+ requestorName [2] GeneralName OPTIONAL,
+ responderName [3] GeneralName OPTIONAL,
+ requestExtensions [4] Extensions{{RequestExtensions}}
+ OPTIONAL,
+ signatureAlg [5] AlgorithmIdentifier
+ {SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}}
+ OPTIONAL,
+ hashAlg [6] OBJECT IDENTIFIER OPTIONAL,
+ requestorText [7] UTF8String (SIZE (1..256)) OPTIONAL
+ }
+
+ -- Set of signature algorithms is coming from RFC 5280
+ -- SignatureAlgorithms SIGNATURE-ALGORITHM ::= {...}
+
+ -- Add supported request extensions here; all new items should
+ -- be added after the extension marker
+
+ RequestExtensions EXTENSION ::= {...}
+
+ Query ::= SEQUENCE {
+ queriedCerts CertReferences,
+ checks CertChecks,
+ wantBack [1] WantBack OPTIONAL,
+ validationPolicy ValidationPolicy,
+ responseFlags ResponseFlags OPTIONAL,
+ serverContextInfo [2] OCTET STRING OPTIONAL,
+ validationTime [3] GeneralizedTime OPTIONAL,
+ intermediateCerts [4] CertBundle OPTIONAL,
+ revInfos [5] RevocationInfos OPTIONAL,
+ producedAt [6] GeneralizedTime OPTIONAL,
+ queryExtensions [7] Extensions{{QueryExtensions}} OPTIONAL
+ }
+
+ -- Add supported query extensions here; all new items should be added
+ -- after the extension marker
+
+ QueryExtensions EXTENSION ::= {...}
+
+ CertReferences ::= CHOICE {
+ pkcRefs [0] SEQUENCE SIZE (1..MAX) OF PKCReference,
+ acRefs [1] SEQUENCE SIZE (1..MAX) OF ACReference
+ }
+
+ CertReference::= CHOICE {
+ pkc PKCReference,
+ ac ACReference
+ }
+
+ PKCReference ::= CHOICE {
+ cert [0] Certificate,
+ pkcRef [1] SCVPCertID
+ }
+
+ ACReference ::= CHOICE {
+ attrCert [2] AttributeCertificate,
+ acRef [3] SCVPCertID
+ }
+
+ HashAlgorithm ::= AlgorithmIdentifier{DIGEST-ALGORITHM,
+ {mda-sha1, ...}}
+
+ SCVPCertID ::= SEQUENCE {
+ certHash OCTET STRING,
+ issuerSerial SCVPIssuerSerial,
+ hashAlgorithm HashAlgorithm
+ DEFAULT { algorithm mda-sha1.&id }
+ }
+
+ SCVPIssuerSerial ::= SEQUENCE {
+ issuer GeneralNames,
+ serialNumber CertificateSerialNumber
+ }
+
+ ValidationPolicy ::= SEQUENCE {
+ validationPolRef ValidationPolRef,
+ validationAlg [0] ValidationAlg OPTIONAL,
+ userPolicySet [1] SEQUENCE SIZE (1..MAX) OF OBJECT
+ IDENTIFIER OPTIONAL,
+ inhibitPolicyMapping [2] BOOLEAN OPTIONAL,
+ requireExplicitPolicy [3] BOOLEAN OPTIONAL,
+ inhibitAnyPolicy [4] BOOLEAN OPTIONAL,
+ trustAnchors [5] TrustAnchors OPTIONAL,
+ keyUsages [6] SEQUENCE OF KeyUsage OPTIONAL,
+ extendedKeyUsages [7] SEQUENCE OF KeyPurposeId OPTIONAL,
+ specifiedKeyUsages [8] SEQUENCE OF KeyPurposeId OPTIONAL
+ }
+
+ CertChecks ::= SEQUENCE SIZE (1..MAX) OF
+ OBJECT IDENTIFIER (CertCheckSet | ACertCheckSet, ... )
+
+ WantBack ::= SEQUENCE SIZE (1..MAX) OF
+ WANT-BACK.&id ({AllWantBacks})
+
+ POLICY ::= ATTRIBUTE
+
+ ValidationPolRefSet POLICY ::= {
+ svp-defaultValPolicy, ...
+ }
+
+ ValidationPolRef ::= SEQUENCE {
+ valPolId POLICY.&id,
+ valPolParams POLICY.&Type OPTIONAL
+ }
+
+ ValidationAlgSet POLICY ::= {
+ svp-basicValAlg, ...
+ }
+
+ ValidationAlg ::= SEQUENCE {
+ valAlgId POLICY.&id,
+ parameters POLICY.&Type OPTIONAL
+ }
+
+ NameValidationAlgSet POLICY ::= {
+ svp-nameValAlg, ...
+ }
+
+ NameValidationAlgParams ::= SEQUENCE {
+ nameCompAlgId OBJECT IDENTIFIER (NameCompAlgSet, ... ),
+ validationNames GeneralNames
+ }
+
+ TrustAnchors ::= SEQUENCE SIZE (1..MAX) OF PKCReference
+ KeyAgreePublicKey ::= SEQUENCE {
+ algorithm AlgorithmIdentifier{KEY-AGREE,
+ {SupportedKeyAgreePublicKeys}},
+ publicKey BIT STRING,
+ macAlgorithm AlgorithmIdentifier{MAC-ALGORITHM,
+ {SupportedMACAlgorithms}},
+ kDF AlgorithmIdentifier{KEY-DERIVATION,
+ {SupportedKeyDerivationFunctions}}
+ OPTIONAL
+ }
+
+ SupportedKeyAgreePublicKeys KEY-AGREE ::= {...}
+ SupportedMACAlgorithms MAC-ALGORITHM ::= {...}
+ SupportedKeyDerivationFunctions KEY-DERIVATION ::= {...}
+
+ ResponseFlags ::= SEQUENCE {
+ fullRequestInResponse [0] BOOLEAN DEFAULT FALSE,
+ responseValidationPolByRef [1] BOOLEAN DEFAULT TRUE,
+ protectResponse [2] BOOLEAN DEFAULT TRUE,
+ cachedResponse [3] BOOLEAN DEFAULT TRUE
+ }
+
+ CertBundle ::= SEQUENCE SIZE (1..MAX) OF Certificate
+
+ RevocationInfos ::= SEQUENCE SIZE (1..MAX) OF RevocationInfo
+
+ RevocationInfo ::= CHOICE {
+ crl [0] CertificateList,
+ delta-crl [1] CertificateList,
+ ocsp [2] OCSPResponse,
+ other [3] OtherRevInfo
+ }
+
+ REV-INFO ::= TYPE-IDENTIFIER
+
+ OtherRevInfo ::= SEQUENCE {
+ riType REV-INFO.&id,
+ riValue REV-INFO.&Type
+ }
+
+ -- SCVP Certificate Validation Response
+
+ ct-scvp-certValResponse CONTENT-TYPE ::=
+ { CVResponse IDENTIFIED BY id-ct-scvp-certValResponse }
+
+ id-ct-scvp-certValResponse OBJECT IDENTIFIER ::= { id-ct 11 }
+
+ CVResponse ::= SEQUENCE {
+ cvResponseVersion INTEGER,
+ serverConfigurationID INTEGER,
+ producedAt GeneralizedTime,
+ responseStatus ResponseStatus,
+ respValidationPolicy [0] RespValidationPolicy OPTIONAL,
+ requestRef [1] RequestReference OPTIONAL,
+ requestorRef [2] GeneralNames OPTIONAL,
+ requestorName [3] GeneralNames OPTIONAL,
+ replyObjects [4] ReplyObjects OPTIONAL,
+ respNonce [5] OCTET STRING OPTIONAL,
+ serverContextInfo [6] OCTET STRING OPTIONAL,
+ cvResponseExtensions [7] Extensions{{CVResponseExtensions}}
+ OPTIONAL,
+ requestorText [8] UTF8String (SIZE (1..256)) OPTIONAL
+ }
+
+ -- This document defines no extensions
+ CVResponseExtensions EXTENSION ::= {...}
+
+ ResponseStatus ::= SEQUENCE {
+ statusCode CVStatusCode DEFAULT okay,
+ errorMessage UTF8String OPTIONAL
+ }
+
+ CVStatusCode ::= ENUMERATED {
+ okay (0),
+ skipUnrecognizedItems (1),
+ tooBusy (10),
+ invalidRequest (11),
+ internalError (12),
+ badStructure (20),
+ unsupportedVersion (21),
+ abortUnrecognizedItems (22),
+ unrecognizedSigKey (23),
+ badSignatureOrMAC (24),
+ unableToDecode (25),
+ notAuthorized (26),
+ unsupportedChecks (27),
+ unsupportedWantBacks (28),
+ unsupportedSignatureOrMAC (29),
+ invalidSignatureOrMAC (30),
+ protectedResponseUnsupported (31),
+ unrecognizedResponderName (32),
+ relayingLoop (40),
+ unrecognizedValPol (50),
+ unrecognizedValAlg (51),
+ fullRequestInResponseUnsupported (52),
+ fullPolResponseUnsupported (53),
+ inhibitPolicyMappingUnsupported (54),
+ requireExplicitPolicyUnsupported (55),
+ inhibitAnyPolicyUnsupported (56),
+ validationTimeUnsupported (57),
+ unrecognizedCritQueryExt (63),
+ unrecognizedCritRequestExt (64),
+ ...
+ }
+
+ RespValidationPolicy ::= ValidationPolicy
+
+ RequestReference ::= CHOICE {
+ requestHash [0] HashValue, -- hash of CVRequest
+ fullRequest [1] CVRequest }
+
+ HashValue ::= SEQUENCE {
+ algorithm HashAlgorithm
+ DEFAULT { algorithm mda-sha1.&id },
+ value OCTET STRING }
+
+ ReplyObjects ::= SEQUENCE SIZE (1..MAX) OF CertReply
+
+ CertReply ::= SEQUENCE {
+ cert CertReference,
+ replyStatus ReplyStatus DEFAULT success,
+ replyValTime GeneralizedTime,
+ replyChecks ReplyChecks,
+ replyWantBacks ReplyWantBacks,
+ validationErrors [0] SEQUENCE SIZE (1..MAX) OF
+ OBJECT IDENTIFIER ( BasicValidationErrorSet |
+ NameValidationErrorSet,
+ ... ) OPTIONAL,
+ nextUpdate [1] GeneralizedTime OPTIONAL,
+ certReplyExtensions [2] Extensions{{...}} OPTIONAL
+ }
+
+ ReplyStatus ::= ENUMERATED {
+ success (0),
+ malformedPKC (1),
+ malformedAC (2),
+ unavailableValidationTime (3),
+ referenceCertHashFail (4),
+ certPathConstructFail (5),
+ certPathNotValid (6),
+ certPathNotValidNow (7),
+ wantBackUnsatisfied (8)
+ }
+ ReplyChecks ::= SEQUENCE OF ReplyCheck
+
+ ReplyCheck ::= SEQUENCE {
+ check OBJECT IDENTIFIER (CertCheckSet | ACertCheckSet, ... ),
+ status INTEGER DEFAULT 0
+ }
+
+ ReplyWantBacks ::= SEQUENCE OF ReplyWantBack
+
+ ReplyWantBack::= SEQUENCE {
+ wb WANT-BACK.&id({AllWantBacks}),
+ value OCTET STRING
+ (CONTAINING WANT-BACK.&Type({AllWantBacks}{@wb}))
+ }
+
+ WANT-BACK ::= TYPE-IDENTIFIER
+
+ AllWantBacks WANT-BACK ::= {
+ WantBackSet | ACertWantBackSet | AnyWantBackSet, ...
+ }
+
+ CertBundles ::= SEQUENCE SIZE (1..MAX) OF CertBundle
+
+ RevInfoWantBack ::= SEQUENCE {
+ revocationInfo RevocationInfos,
+ extraCerts CertBundle OPTIONAL
+ }
+
+ SCVPResponses ::= SEQUENCE OF ContentInfo
+
+ -- SCVP Validation Policies Request
+
+ ct-scvp-valPolRequest CONTENT-TYPE ::=
+ { ValPolRequest IDENTIFIED BY id-ct-scvp-valPolRequest }
+
+ id-ct-scvp-valPolRequest OBJECT IDENTIFIER ::= { id-ct 12 }
+
+ ValPolRequest ::= SEQUENCE {
+ vpRequestVersion INTEGER DEFAULT 1,
+ requestNonce OCTET STRING
+ }
+
+ -- SCVP Validation Policies Response
+
+ ct-scvp-valPolResponse CONTENT-TYPE ::=
+ { ValPolResponse IDENTIFIED BY id-ct-scvp-valPolResponse }
+
+ id-ct-scvp-valPolResponse OBJECT IDENTIFIER ::= { id-ct 13 }
+ ValPolResponse ::= SEQUENCE {
+ vpResponseVersion INTEGER,
+ maxCVRequestVersion INTEGER,
+ maxVPRequestVersion INTEGER,
+ serverConfigurationID INTEGER,
+ thisUpdate GeneralizedTime,
+ nextUpdate GeneralizedTime OPTIONAL,
+ supportedChecks CertChecks,
+ supportedWantBacks WantBack,
+ validationPolicies SEQUENCE OF OBJECT IDENTIFIER,
+ validationAlgs SEQUENCE OF OBJECT IDENTIFIER,
+ authPolicies SEQUENCE OF AuthPolicy,
+ responseTypes ResponseTypes,
+ defaultPolicyValues RespValidationPolicy,
+ revocationInfoTypes RevocationInfoTypes,
+ signatureGeneration SEQUENCE OF AlgorithmIdentifier
+ {SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ signatureVerification SEQUENCE OF AlgorithmIdentifier
+ {SIGNATURE-ALGORITHM,
+ {SignatureAlgorithms}},
+ hashAlgorithms SEQUENCE SIZE (1..MAX) OF
+ OBJECT IDENTIFIER,
+ serverPublicKeys SEQUENCE OF KeyAgreePublicKey
+ OPTIONAL,
+ clockSkew INTEGER DEFAULT 10,
+ requestNonce OCTET STRING OPTIONAL
+ }
+
+ ResponseTypes ::= ENUMERATED {
+ cached-only (0),
+ non-cached-only (1),
+ cached-and-non-cached (2)
+ }
+
+ RevocationInfoTypes ::= BIT STRING {
+ fullCRLs (0),
+ deltaCRLs (1),
+ indirectCRLs (2),
+ oCSPResponses (3)
+ }
+
+ AuthPolicy ::= OBJECT IDENTIFIER
+
+ -- SCVP Check Identifiers
+
+ id-stc OBJECT IDENTIFIER ::=
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) 17 }
+
+ CertCheckSet OBJECT IDENTIFIER ::= {
+ id-stc-build-pkc-path | id-stc-build-valid-pkc-path |
+ id-stc-build-status-checked-pkc-path, ... }
+
+ id-stc-build-pkc-path OBJECT IDENTIFIER ::= { id-stc 1 }
+ id-stc-build-valid-pkc-path OBJECT IDENTIFIER ::= { id-stc 2 }
+ id-stc-build-status-checked-pkc-path
+ OBJECT IDENTIFIER ::= { id-stc 3 }
+
+ ACertCheckSet OBJECT IDENTIFIER ::= {
+ id-stc-build-aa-path | id-stc-build-valid-aa-path |
+ id-stc-build-status-checked-aa-path |
+ id-stc-status-check-ac-and-build-status-checked-aa-path
+ }
+
+ id-stc-build-aa-path OBJECT IDENTIFIER ::= { id-stc 4 }
+ id-stc-build-valid-aa-path OBJECT IDENTIFIER ::= { id-stc 5 }
+ id-stc-build-status-checked-aa-path
+ OBJECT IDENTIFIER ::= { id-stc 6 }
+ id-stc-status-check-ac-and-build-status-checked-aa-path
+ OBJECT IDENTIFIER ::= { id-stc 7 }
+
+ -- SCVP WantBack Identifiers
+
+ id-swb OBJECT IDENTIFIER ::=
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) 18 }
+
+ WantBackSet WANT-BACK ::= {
+ swb-pkc-cert | swb-pkc-best-cert-path |
+ swb-pkc-revocation-info | swb-pkc-public-key-info |
+ swb-pkc-all-cert-paths | swb-pkc-ee-revocation-info |
+ swb-pkc-CAs-revocation-info
+ }
+
+ ACertWantBackSet WANT-BACK ::= {
+ swb-ac-cert | swb-aa-cert-path |
+ swb-aa-revocation-info | swb-ac-revocation-info
+ }
+
+ AnyWantBackSet WANT-BACK ::= { swb-relayed-responses }
+
+ swb-pkc-best-cert-path WANT-BACK ::=
+ { CertBundle IDENTIFIED BY id-swb-pkc-best-cert-path }
+ id-swb-pkc-best-cert-path OBJECT IDENTIFIER ::= { id-swb 1 }
+ swb-pkc-revocation-info WANT-BACK ::=
+ { RevInfoWantBack IDENTIFIED BY id-swb-pkc-revocation-info }
+ id-swb-pkc-revocation-info OBJECT IDENTIFIER ::= { id-swb 2 }
+
+ swb-pkc-public-key-info WANT-BACK ::=
+ { SubjectPublicKeyInfo IDENTIFIED BY id-swb-pkc-public-key-info }
+ id-swb-pkc-public-key-info OBJECT IDENTIFIER ::= { id-swb 4 }
+
+ swb-aa-cert-path WANT-BACK ::=
+ {CertBundle IDENTIFIED BY id-swb-aa-cert-path }
+ id-swb-aa-cert-path OBJECT IDENTIFIER ::= { id-swb 5 }
+
+ swb-aa-revocation-info WANT-BACK ::=
+ { RevInfoWantBack IDENTIFIED BY id-swb-aa-revocation-info }
+ id-swb-aa-revocation-info OBJECT IDENTIFIER ::= { id-swb 6 }
+
+ swb-ac-revocation-info WANT-BACK ::=
+ { RevInfoWantBack IDENTIFIED BY id-swb-ac-revocation-info }
+ id-swb-ac-revocation-info OBJECT IDENTIFIER ::= { id-swb 7 }
+
+ swb-relayed-responses WANT-BACK ::=
+ {SCVPResponses IDENTIFIED BY id-swb-relayed-responses }
+
+ id-swb-relayed-responses OBJECT IDENTIFIER ::= { id-swb 9 }
+
+ swb-pkc-all-cert-paths WANT-BACK ::=
+ {CertBundles IDENTIFIED BY id-swb-pkc-all-cert-paths }
+ id-swb-pkc-all-cert-paths OBJECT IDENTIFIER ::= { id-swb 12}
+
+ swb-pkc-ee-revocation-info WANT-BACK ::=
+ { RevInfoWantBack IDENTIFIED BY id-swb-pkc-ee-revocation-info }
+ id-swb-pkc-ee-revocation-info OBJECT IDENTIFIER ::= { id-swb 13}
+
+ swb-pkc-CAs-revocation-info WANT-BACK ::=
+ { RevInfoWantBack IDENTIFIED BY id-swb-pkc-CAs-revocation-info }
+ id-swb-pkc-CAs-revocation-info OBJECT IDENTIFIER ::= { id-swb 14}
+
+ swb-pkc-cert WANT-BACK ::=
+ { Certificate IDENTIFIED BY id-swb-pkc-cert }
+ id-swb-pkc-cert OBJECT IDENTIFIER ::= { id-swb 10}
+
+ swb-ac-cert WANT-BACK ::=
+ { AttributeCertificate IDENTIFIED BY id-swb-ac-cert }
+ id-swb-ac-cert OBJECT IDENTIFIER ::= { id-swb 11}
+
+ -- SCVP Validation Policy and Algorithm Identifiers
+
+ id-svp OBJECT IDENTIFIER ::=
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) 19 }
+
+ svp-defaultValPolicy POLICY ::=
+ { IDENTIFIED BY id-svp-defaultValPolicy }
+
+ id-svp-defaultValPolicy OBJECT IDENTIFIER ::= { id-svp 1 }
+
+ -- SCVP Basic Validation Algorithm Identifier
+
+ svp-basicValAlg POLICY ::= {IDENTIFIED BY id-svp-basicValAlg }
+
+ id-svp-basicValAlg OBJECT IDENTIFIER ::= { id-svp 3 }
+
+ -- SCVP Basic Validation Algorithm Errors
+
+ id-bvae OBJECT IDENTIFIER ::= id-svp-basicValAlg
+
+ BasicValidationErrorSet OBJECT IDENTIFIER ::= {
+ id-bvae-expired | id-bvae-not-yet-valid |
+ id-bvae-wrongTrustAnchor | id-bvae-noValidCertPath |
+ id-bvae-revoked | id-bvae-invalidKeyPurpose |
+ id-bvae-invalidKeyUsage | id-bvae-invalidCertPolicy
+ }
+
+ id-bvae-expired OBJECT IDENTIFIER ::= { id-bvae 1 }
+ id-bvae-not-yet-valid OBJECT IDENTIFIER ::= { id-bvae 2 }
+ id-bvae-wrongTrustAnchor OBJECT IDENTIFIER ::= { id-bvae 3 }
+ id-bvae-noValidCertPath OBJECT IDENTIFIER ::= { id-bvae 4 }
+ id-bvae-revoked OBJECT IDENTIFIER ::= { id-bvae 5 }
+ id-bvae-invalidKeyPurpose OBJECT IDENTIFIER ::= { id-bvae 9 }
+ id-bvae-invalidKeyUsage OBJECT IDENTIFIER ::= { id-bvae 10 }
+ id-bvae-invalidCertPolicy OBJECT IDENTIFIER ::= { id-bvae 11 }
+
+ -- SCVP Name Validation Algorithm Identifier
+
+ svp-nameValAlg POLICY ::=
+ {TYPE NameValidationAlgParams IDENTIFIED BY id-svp-nameValAlg }
+
+ id-svp-nameValAlg OBJECT IDENTIFIER ::= { id-svp 2 }
+
+ -- SCVP Name Validation Algorithm DN comparison algorithm
+
+ NameCompAlgSet OBJECT IDENTIFIER ::= {
+ id-nva-dnCompAlg
+ }
+
+ id-nva-dnCompAlg OBJECT IDENTIFIER ::= { id-svp 4 }
+ -- SCVP Name Validation Algorithm Errors
+
+ id-nvae OBJECT IDENTIFIER ::= id-svp-nameValAlg
+
+ NameValidationErrorSet OBJECT IDENTIFIER ::= {
+ id-nvae-name-mismatch | id-nvae-no-name | id-nvae-unknown-alg |
+ id-nvae-bad-name | id-nvae-bad-name-type | id-nvae-mixed-names
+ }
+
+ id-nvae-name-mismatch OBJECT IDENTIFIER ::= { id-nvae 1 }
+ id-nvae-no-name OBJECT IDENTIFIER ::= { id-nvae 2 }
+ id-nvae-unknown-alg OBJECT IDENTIFIER ::= { id-nvae 3 }
+ id-nvae-bad-name OBJECT IDENTIFIER ::= { id-nvae 4 }
+ id-nvae-bad-name-type OBJECT IDENTIFIER ::= { id-nvae 5 }
+ id-nvae-mixed-names OBJECT IDENTIFIER ::= { id-nvae 6 }
+
+ -- SCVP Extended Key Usage Key Purpose Identifiers
+
+ id-kp OBJECT IDENTIFIER ::=
+ { iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) 3 }
+
+ SvcpExtKeyUsageSet OBJECT IDENTIFIER ::= {
+ id-kp-scvpServer | id-kp-scvpClient
+ }
+
+ id-kp-scvpServer OBJECT IDENTIFIER ::= { id-kp 15 }
+
+ id-kp-scvpClient OBJECT IDENTIFIER ::= { id-kp 16 }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/rfcs/SecureMimeMessageV3dot1-2009.asn1 b/lib/asn1/test/asn1_SUITE_data/rfcs/SecureMimeMessageV3dot1-2009.asn1
new file mode 100644
index 0000000000..2bd2aaa435
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/SecureMimeMessageV3dot1-2009.asn1
@@ -0,0 +1,122 @@
+ SecureMimeMessageV3dot1-2009
+ {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-msg-v3dot1-02(39)}
+ DEFINITIONS IMPLICIT TAGS ::=
+ BEGIN
+ IMPORTS
+
+ SMIME-CAPS, SMIMECapabilities{}
+ FROM AlgorithmInformation-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-algorithmInformation-02(58)}
+
+ ATTRIBUTE
+ FROM PKIX-CommonTypes-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}
+
+ SubjectKeyIdentifier, IssuerAndSerialNumber, RecipientKeyIdentifier
+ FROM CryptographicMessageSyntax-2009
+ {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cms-2004-02(41)}
+
+ rc2-cbc, SMimeCaps
+ FROM CryptographicMessageSyntaxAlgorithms-2009
+ {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) modules(0) id-mod-cmsalg-2001-02(37)}
+
+ SMimeCaps
+ FROM PKIXAlgs-2009
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms2008-02(56)}
+
+ SMimeCaps
+ FROM PKIX1-PSS-OAEP-Algorithms-2009
+ {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-rsa-pkalgs-02(54)};
+
+ SMimeAttributeSet ATTRIBUTE ::=
+ { aa-smimeCapabilities | aa-encrypKeyPref, ... }
+
+ -- id-aa is the arc with all new authenticated and unauthenticated
+ -- attributes produced by the S/MIME Working Group
+
+ id-aa OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) usa(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ smime(16) attributes(2)}
+
+ -- The S/MIME Capabilities attribute provides a method of broadcasting
+ -- the symmetric capabilities understood. Algorithms SHOULD be ordered
+ -- by preference and grouped by type
+
+ aa-smimeCapabilities ATTRIBUTE ::=
+ { TYPE SMIMECapabilities{{SMimeCapsSet}} IDENTIFIED BY
+ smimeCapabilities }
+ smimeCapabilities OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ 15 }
+
+ SMimeCapsSet SMIME-CAPS ::=
+ { cap-preferBinaryInside | cap-RC2CBC |
+ PKIXAlgs-2009.SMimeCaps |
+ CryptographicMessageSyntaxAlgorithms-2009.SMimeCaps |
+ PKIX1-PSS-OAEP-Algorithms-2009.SMimeCaps, ... }
+
+ -- Encryption Key Preference provides a method of broadcasting the
+ -- preferred encryption certificate.
+
+ aa-encrypKeyPref ATTRIBUTE ::=
+ { TYPE SMIMEEncryptionKeyPreference
+ IDENTIFIED BY id-aa-encrypKeyPref }
+
+ id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
+
+ SMIMEEncryptionKeyPreference ::= CHOICE {
+ issuerAndSerialNumber [0] IssuerAndSerialNumber,
+ receipentKeyId [1] RecipientKeyIdentifier,
+ subjectAltKeyIdentifier [2] SubjectKeyIdentifier
+ }
+
+ -- receipentKeyId is spelt incorrectly, but kept for historical
+ -- reasons.
+
+ id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 }
+
+ id-cap OBJECT IDENTIFIER ::= { id-smime 11 }
+
+ -- The preferBinaryInside indicates an ability to receive messages
+ -- with binary encoding inside the CMS wrapper
+
+ cap-preferBinaryInside SMIME-CAPS ::=
+ { -- No value -- IDENTIFIED BY id-cap-preferBinaryInside }
+
+ id-cap-preferBinaryInside OBJECT IDENTIFIER ::= { id-cap 1 }
+
+ -- The following list OIDs to be used with S/MIME V3
+
+ -- Signature Algorithms Not Found in [RFC3370]
+ --
+ -- md2WithRSAEncryption OBJECT IDENTIFIER ::=
+ -- {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
+ -- 2}
+ --
+ -- Other Signed Attributes
+ --
+ -- signingTime OBJECT IDENTIFIER ::=
+ -- {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ -- 5}
+ -- See [RFC5652] for a description of how to encode the attribute
+ -- value.
+
+ cap-RC2CBC SMIME-CAPS ::=
+ { TYPE SMIMECapabilitiesParametersForRC2CBC
+ IDENTIFIED BY rc2-cbc}
+
+ SMIMECapabilitiesParametersForRC2CBC ::= INTEGER (40 | 128, ...)
+ -- (RC2 Key Length (number of bits))
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/SelectedAttributeTypes.asn1
index 07bba30690..07bba30690 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/SelectedAttributeTypes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/SeseAPDUs.asn1
index 2917122e94..2917122e94 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/SeseAPDUs.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/SpkmGssTokens.asn1
index 02205bd64c..02205bd64c 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/SpkmGssTokens.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Style-Descriptors.asn1
index 8f033eab6f..8f033eab6f 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Style-Descriptors.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Subprofiles.asn1
index bfcd0b5dbc..bfcd0b5dbc 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Subprofiles.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Temporal-Relationships.asn1
index 9633995e3b..9633995e3b 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Temporal-Relationships.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Text-Units.asn1
index ccc64a52f5..ccc64a52f5 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Text-Units.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/UpperBounds.asn1
index c97c83a569..c97c83a569 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/UpperBounds.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/UsefulDefinitions.asn1
index d9601bb7d0..d9601bb7d0 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/UsefulDefinitions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/rfcs/Videotex-Coding-Attributes.asn1
index 18e51cbc0d..18e51cbc0d 100644
--- a/lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn
+++ b/lib/asn1/test/asn1_SUITE_data/rfcs/Videotex-Coding-Attributes.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/test_records.erl b/lib/asn1/test/asn1_SUITE_data/test_records.erl
index 1fdfbb40df..adfc98600c 100644
--- a/lib/asn1/test/asn1_SUITE_data/test_records.erl
+++ b/lib/asn1/test/asn1_SUITE_data/test_records.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/asn1_SUITE_data/testobj.erl b/lib/asn1/test/asn1_SUITE_data/testobj.erl
index 2cc909c35e..efb1cf4713 100644
--- a/lib/asn1/test/asn1_SUITE_data/testobj.erl
+++ b/lib/asn1/test/asn1_SUITE_data/testobj.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl
index d800846b3f..71aad5c62f 100644
--- a/lib/asn1/test/asn1_app_test.erl
+++ b/lib/asn1/test/asn1_app_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl
index 7391959645..7df6190f92 100644
--- a/lib/asn1/test/asn1_appup_test.erl
+++ b/lib/asn1/test/asn1_appup_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
index da07cd1118..ae2e5641ec 100644
--- a/lib/asn1/test/asn1_test_lib.erl
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,6 +22,7 @@
-export([compile/3,compile_all/3,compile_erlang/3,
hex_to_bin/1,
+ match_value/2,
parallel/0,
roundtrip/3,roundtrip/4,roundtrip_enc/3,roundtrip_enc/4]).
@@ -56,7 +58,7 @@ dialyze(Files) ->
Beams0 = [code:which(module(F)) || F <- Files],
Beams = [code:which(asn1rt_nif)|Beams0],
case dialyzer:run([{files,Beams},
- {warnings,[no_improper_lists]},
+ {warnings,[]},
{get_warnings,true}]) of
[] ->
ok;
@@ -106,6 +108,24 @@ compile_erlang(Mod, Config, Options) ->
hex_to_bin(S) ->
<< <<(hex2num(C)):4>> || C <- S, C =/= $\s >>.
+%% match_value(Pattern, Value) -> ok.
+%% Match Pattern against Value. If the Pattern contains in any
+%% position, the corresponding position in the Value can be
+%% anything. Generate an exception if the Pattern and Value don't
+%% match.
+
+match_value('_', _) ->
+ ok;
+match_value([H1|T1], [H2|T2]) ->
+ match_value(H1, H2),
+ match_value(T1, T2);
+match_value(T1, T2) when tuple_size(T1) =:= tuple_size(T2) ->
+ match_value_tuple(1, T1, T2);
+match_value(Same, Same) ->
+ ok;
+match_value(V1, V2) ->
+ error({nomatch,V1,V2}).
+
roundtrip(Mod, Type, Value) ->
roundtrip(Mod, Type, Value, Value).
@@ -132,6 +152,12 @@ hex2num(C) when $0 =< C, C =< $9 -> C - $0;
hex2num(C) when $A =< C, C =< $F -> C - $A + 10;
hex2num(C) when $a =< C, C =< $f -> C - $a + 10.
+match_value_tuple(I, T1, T2) when I =< tuple_size(T1) ->
+ match_value(element(I, T1), element(I, T2)),
+ match_value_tuple(I+1, T1, T2);
+match_value_tuple(_, _, _) ->
+ ok.
+
test_ber_indefinite(Mod, Type, Encoded, ExpectedValue) ->
case Mod:encoding_rule() of
ber ->
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
index ef11717c45..8268698b8d 100644
--- a/lib/asn1/test/ber_decode_error.erl
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl
index 1edd60f7c8..a3413d1b3d 100644
--- a/lib/asn1/test/error_SUITE.erl
+++ b/lib/asn1/test/error_SUITE.erl
@@ -3,25 +3,29 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(error_SUITE).
-export([suite/0,all/0,groups/0,
- already_defined/1,bitstrings/1,enumerated/1,
- imports/1,instance_of/1,integers/1,objects/1,
- parameterization/1,values/1]).
+ already_defined/1,bitstrings/1,
+ classes/1,constraints/1,constructed/1,enumerated/1,
+ imports_exports/1,instance_of/1,integers/1,objects/1,
+ object_field_extraction/1,oids/1,rel_oids/1,
+ object_sets/1,parameterization/1,
+ syntax/1,table_constraints/1,tags/1,values/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -34,12 +38,22 @@ groups() ->
[{p,parallel(),
[already_defined,
bitstrings,
+ classes,
+ constraints,
+ constructed,
enumerated,
- imports,
+ imports_exports,
instance_of,
integers,
objects,
+ object_field_extraction,
+ object_sets,
+ oids,
+ rel_oids,
parameterization,
+ syntax,
+ table_constraints,
+ tags,
values]}].
parallel() ->
@@ -94,6 +108,46 @@ bitstrings(Config) ->
]} = run(P, Config),
ok.
+classes(Config) ->
+ M = 'Classes',
+ P = {M,
+ <<"Classes DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " LowerCase ::= CLASS { &id INTEGER UNIQUE }\n"
+ " CL ::= CLASS { &id INTEGER UNIQUE DEFAULT 42}\n"
+ "END\n">>},
+ {error,
+ [{structured_error,{M,2},asn1ct_check,
+ {illegal_class_name,'LowerCase'}},
+ {structured_error,{M,3},asn1ct_check,
+ {unique_and_default,id}}
+ ]} = run(P, Config),
+ ok.
+
+constraints(Config) ->
+ M = 'Constraints',
+ P = {M,
+ <<"Constraints DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " II-1 ::= INTEGER (holder-1.&obj)\n"
+ " II-2 ::= INTEGER ('1234'H<..20)\n"
+ " II-3 ::= INTEGER (1..<\"abc\")\n"
+ " II-4 ::= INTEGER (10..1)\n"
+
+ " HOLDER ::= CLASS {\n"
+ " &obj HOLDER OPTIONAL\n"
+ " }\n"
+
+ " holder-1 HOLDER ::= { &obj holder-2 }\n"
+ " holder-2 HOLDER ::= { }\n"
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,2},asn1ct_check,illegal_value},
+ {structured_error,{M,3},asn1ct_check,illegal_integer_value},
+ {structured_error,{M,4},asn1ct_check,illegal_integer_value},
+ {structured_error,{M,5},asn1ct_check,reversed_range}
+ ]} = run(P, Config),
+ ok.
+
enumerated(Config) ->
M = 'Enumerated',
P = {M,
@@ -111,38 +165,77 @@ enumerated(Config) ->
" S2 ::= SEQUENCE {\n"
" e2 EnumExt DEFAULT xyz\n"
" }\n"
+
+ " BadEnum1 ::= ENUMERATED {a, b, c, b }\n"
+ " BadEnum2 ::= ENUMERATED {a(1), b(2), b(3) }\n"
+ " BadEnum3 ::= ENUMERATED {a(1), b(1) }\n"
+ " BadEnum4 ::= ENUMERATED {a, b, ..., c(0) }\n"
+ " BadEnum5 ::= ENUMERATED {a, b, ..., c(10), d(5) }\n"
"END\n">>},
{error,
[
- {structured_error,{'Enumerated',3},asn1ct_check,{undefined,d}},
- {structured_error,{'Enumerated',5},asn1ct_check,{undefined,z}},
- {structured_error,{'Enumerated',10},asn1ct_check,{undefined,aa}},
- {structured_error,{'Enumerated',13},asn1ct_check,{undefined,xyz}}
+ {structured_error,{M,3},asn1ct_check,{undefined,d}},
+ {structured_error,{M,5},asn1ct_check,{undefined,z}},
+ {structured_error,{M,6},asn1ct_check,{undefined,aa}},
+ {structured_error,{M,12},asn1ct_check,{undefined,xyz}},
+ {structured_error,{M,15},asn1ct_check,
+ {enum_illegal_redefinition,b}},
+ {structured_error,{M,16},asn1ct_check,
+ {enum_illegal_redefinition,b}},
+ {structured_error,{M,17},asn1ct_check,
+ {enum_reused_value,b,1}},
+ {structured_error,{M,18},asn1ct_check,
+ {enum_reused_value,c,0}},
+ {structured_error,{M,19},asn1ct_check,
+ {enum_not_ascending,d,5,10}}
]
} = run(P, Config),
ok.
-imports(Config) ->
+imports_exports(Config) ->
Ext = 'ExternalModule',
ExtP = {Ext,
<<"ExternalModule DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ "IMPORTS\n"
+ " Int, NonExistingImport FROM ImportsFrom;\n"
+
+ " Existing ::= INTEGER\n"
"END\n">>},
- ok = run(ExtP, Config),
+ {error,
+ [{structured_error,
+ {Ext,3},
+ asn1ct_check,
+ {undefined_import,'NonExistingImport',
+ 'ImportsFrom'}}]} = run(ExtP, Config),
M = 'Imports',
P = {M,
<<"Imports DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
- "IMPORTS NotDefined FROM ExternalModule\n"
- "X FROM UndefinedModule objid\n"
- "Y, Z FROM UndefinedModule2;\n"
+ "EXPORTS\n"
+ " T, UndefinedType;\n"
+
+ "IMPORTS\n"
+ " NotDefined, Existing, Int, NonExistingImport\n"
+ " FROM ExternalModule\n"
+ " X FROM UndefinedModule objid\n"
+ " Y, Z FROM UndefinedModule2;\n"
+
"objid OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) remote-operations(4)\n"
" notation(0)}\n"
+ "T ::= INTEGER\n"
"END\n">>},
- {error,[{structured_error,{M,2},asn1ct_check,
- {undefined_import,'NotDefined','ExternalModule'}},
- {structured_error,{M,3},asn1ct_check,{undefined_import,'X','UndefinedModule'}},
- {structured_error,{M,4},asn1ct_check,{undefined_import,'Y','UndefinedModule2'}},
- {structured_error,{M,4},asn1ct_check,{undefined_import,'Z','UndefinedModule2'}}
+ {error,[{structured_error,{M,3},asn1ct_check,
+ {undefined_export, 'UndefinedType'}},
+ {structured_error,{M,5},asn1ct_check,
+ {undefined_import,'NonExistingImport',Ext}},
+ {structured_error,{M,5},asn1ct_check,
+ {undefined_import,'NotDefined',Ext}},
+ {structured_error,{M,7},asn1ct_check,
+ {undefined_import,'X','UndefinedModule'}},
+ {structured_error,{M,8},asn1ct_check,
+ {undefined_import,'Y','UndefinedModule2'}},
+ {structured_error,{M,8},asn1ct_check,
+ {undefined_import,'Z','UndefinedModule2'}}
]} = run(P, Config),
ok.
@@ -170,11 +263,14 @@ integers(Config) ->
" Int1 ::= INTEGER {a(1), a(1)}\n"
" Int2 ::= INTEGER {a(1), b(2), a(3)}\n"
" Int3 ::= INTEGER {x(1), y(1)}\n"
+ " i0 INTEGER ::= 1\n"
+ " Int4 ::= INTEGER {x(i0), y(undef) }\n"
"END\n">>},
{error,
[{structured_error,{M,2},asn1ct_check,{namelist_redefinition,a}},
{structured_error,{M,3},asn1ct_check,{namelist_redefinition,a}},
- {structured_error,{M,4},asn1ct_check,{value_reused,1}}
+ {structured_error,{M,4},asn1ct_check,{value_reused,1}},
+ {structured_error,{M,6},asn1ct_check,{undefined,undef}}
]} = run(P, Config),
ok.
@@ -188,6 +284,11 @@ objects(Config) ->
" obj3 CL ::= { &Data OCTET STRING }\n"
" obj4 SMALL ::= { &code 42 }\n"
" InvalidSet CL ::= { obj1 }\n"
+ " obj5 CL ::= {}\n"
+ " ErrSet ::= PT{ {PT{inst}}}\n"
+ " obj6 CL ::= 7\n"
+ " obj7 CL ::= int\n"
+ " obj8 NON-CLASS ::= { &id 1 }\n"
" CL ::= CLASS {\n"
" &code INTEGER UNIQUE,\n"
@@ -203,6 +304,12 @@ objects(Config) ->
" &code INTEGER UNIQUE,\n"
" &i INTEGER\n"
" }\n"
+
+ " PT{SMALL:Small} ::= SEQUENCE { a SMALL.&code ({Small}) }\n"
+ " inst SMALL ::= {&code 42, &i 4711}\n"
+
+ " int INTEGER ::= 42\n"
+ " NON-CLASS ::= SEQUENCE { a BOOLEAN }\n"
"END\n">>},
{error,
[
@@ -216,24 +323,490 @@ objects(Config) ->
{structured_error,{M,5},asn1ct_check,
{missing_mandatory_fields,[i],obj4}},
{structured_error,{M,6},asn1ct_check,
- {invalid_fields,[wrong],'InvalidSet'}}
+ {invalid_fields,[wrong],'InvalidSet'}},
+ {structured_error,{M,7},asn1ct_check,
+ {missing_mandatory_fields,
+ ['Data','Set','VarTypeValue',code,enum,object,
+ vartypevalue],obj5}},
+ {structured_error,{M,8},asn1ct_check,invalid_objectset},
+ {structured_error,{M,9},asn1ct_check,illegal_object},
+ {structured_error,{M,10},asn1ct_check,illegal_object},
+ {structured_error,{M,11},asn1ct_check,illegal_object}
]
} = run(P, Config),
ok.
+object_field_extraction(Config) ->
+ M = 'ObjectFieldExtraction',
+ P = {M,
+ <<"ObjectFieldExtraction DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+
+ " DataObjSet DATA-CLASS ::= {\n"
+ " holder-object-1.&int,\n"
+ " ...\n"
+ " }\n"
+
+ " DataObjSetNoExt DATA-CLASS ::= {\n"
+ " holder-object-1.&int\n"
+ " }\n"
+
+ " holder-object-1 HOLDER-CLASS ::= {\n"
+ " &int 42\n"
+ " }\n"
+
+ " HOLDER-CLASS ::= CLASS {\n"
+ " &int INTEGER\n"
+ " }\n"
+
+ " DATA-CLASS ::= CLASS {\n"
+ " &id INTEGER\n"
+ " }\n"
+
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,2},asn1ct_check,illegal_object},
+ {structured_error,{M,6},asn1ct_check,illegal_object}
+ ]
+ } = run(P, Config),
+ ok.
+
+object_sets(Config) ->
+ M = 'ObjectSets',
+ P = {M, <<"ObjectSets DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ "TEST-UNIQ ::= CLASS { &id INTEGER UNIQUE, &test INTEGER }\n"
+ "UniqSet TEST-UNIQ ::= { { &id 1, &test 1 } | {&id 1, &test 2} }\n"
+
+ "DOUBLE-UNIQ ::= CLASS { &id1 INTEGER UNIQUE,"
+ " &id INTEGER UNIQUE }\n"
+ "DoubleSet DOUBLE-UNIQ ::= { {&id1 1, &id2 2} }\n"
+ "END\n">>},
+ {error,
+ [{structured_error,{M,3},asn1ct_check,{non_unique_object,1}},
+ {structured_error,{M,5},asn1ct_check,multiple_uniqs}
+ ]
+ } = run(P, Config),
+ ok.
+
+oids(Config) ->
+ M = 'OIDS',
+ P = {M,<<"OIDS DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ "CONTAINER ::= CLASS { &id OBJECT IDENTIFIER UNIQUE,\n"
+ " &int INTEGER OPTIONAL,\n"
+ " &seq SEQUENCE { a INTEGER } OPTIONAL\n"
+ "}\n"
+
+ "-- This is line 6.\n"
+ "object-1 CONTAINER ::= { &id {1 2 3}, &int 42 }\n"
+ "object-2 CONTAINER ::= { &id {1 999}, &int 0 }\n"
+ "object-3 CONTAINER ::= { &id {1 2}, &seq { a 42 } }\n"
+ "oid-1 OBJECT IDENTIFIER ::= object-1.&int\n"
+ "oid-2 OBJECT IDENTIFIER ::= object-2.&id\n"
+ "oid-3 OBJECT IDENTIFIER ::= object-3.&seq\n"
+ "-- This is line 13.\n"
+
+ "oid-5 OBJECT IDENTIFIER ::= { a 42, b 19 }\n"
+
+ "oid-6 OBJECT IDENTIFIER ::= int\n"
+ "int INTEGER ::= 42\n"
+
+ "oid-7 OBJECT IDENTIFIER ::= seq\n"
+ "seq SEQUENCE { x INTEGER } ::= { x 11 }\n"
+
+ "oid-8 OBJECT IDENTIFIER ::= os\n"
+ "os OCTET STRING ::= '1234'H\n"
+
+ "oid-9 OBJECT IDENTIFIER ::= { 1 os }\n"
+
+ "oid-10 OBJECT IDENTIFIER ::= { 1 invalid }\n"
+
+ "-- This is line 23.\n"
+ "oid-11 OBJECT IDENTIFIER ::= { 0 legal-oid }\n"
+ "legal-oid OBJECT IDENTIFIER ::= {1 2 3}\n"
+
+ "bad-root-1 OBJECT IDENTIFIER ::= {99}\n"
+ "bad-root-2 OBJECT IDENTIFIER ::= {0 42}\n"
+
+ "oid-object-ref-1 OBJECT IDENTIFIER ::= object-1\n"
+ "oid-object-ref-2 OBJECT IDENTIFIER ::= { object-1 19 } \n"
+
+ "oid-int OBJECT IDENTIFIER ::= 42\n"
+ "oid-sequence OBJECT IDENTIFIER ::= {a 42, b 35}\n"
+
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,8},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,10},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,11},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,12},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,14},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,15},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,17},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,19},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,21},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,22},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,24},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,26},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,27},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,28},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,29},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,30},asn1ct_check,{illegal_oid,o_id}},
+ {structured_error,{M,31},asn1ct_check,{illegal_oid,o_id}}
+ ]
+ } = run(P, Config),
+ ok.
+
+rel_oids(Config) ->
+ M = 'REL-OIDS',
+ P = {M,<<"REL-OIDS DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ "legal-oid OBJECT IDENTIFIER ::= {1 2}\n"
+ "legal-roid RELATIVE-OID ::= {1 2}\n"
+ "CONTAINER ::= CLASS { &oid OBJECT IDENTIFIER OPTIONAL,\n"
+ " &int INTEGER OPTIONAL,\n"
+ " &seq SEQUENCE { a INTEGER } OPTIONAL\n"
+ "}\n"
+ "object-1 CONTAINER ::= { &oid {1 2 3},\n"
+ " &int 42,\n",
+ " &seq {a 42}\n"
+ " }\n"
+
+ "wrong-type-rel-oid-1 RELATIVE-OID ::= legal-oid\n"
+ "wrong-type-rel-oid-2 RELATIVE-OID ::= object-1.&oid\n"
+ "wrong-type-rel-oid-3 RELATIVE-OID ::= object-1.&int\n"
+ "wrong-type-rel-oid-4 RELATIVE-OID ::= object-1.&seq\n"
+ "wrong-type-rel-oid-5 RELATIVE-OID ::= object-1.&undef\n"
+
+ "oid-bad-first OBJECT IDENTIFIER ::= {legal-roid 3}\n"
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,12},asn1ct_check,{illegal_oid,rel_oid}},
+ {structured_error,{M,13},asn1ct_check,{illegal_oid,rel_oid}},
+ {structured_error,{M,14},asn1ct_check,{illegal_oid,rel_oid}},
+ {structured_error,{M,15},asn1ct_check,{illegal_oid,rel_oid}},
+ {structured_error,{M,16},asn1ct_check,{undefined_field,undef}},
+ {structured_error,{M,17},asn1ct_check,{illegal_oid,o_id}}
+ ]
+ } = run(P, Config),
+ ok.
+
+
parameterization(Config) ->
M = 'Parameterization',
P = {M,
<<"Parameterization DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
" NotUppercase{lowercase} ::= INTEGER (lowercase)\n"
+
+ " P{T1,T2} ::= SEQUENCE { a T1, b T2 }\n"
+ " S ::= P{OCTET STRING}\n"
+
+ " Seq ::= SEQUENCE { a INTEGER }\n"
+ " Sbad ::= Seq{INTEGER}\n"
+
"END\n">>},
{error,
- [{structured_error,{'Parameterization',2},asn1ct_check,
- {illegal_typereference,lowercase}}
- ]
- } = run(P, Config),
+ [{structured_error,{M,2},asn1ct_check,
+ {illegal_typereference,lowercase}},
+ {structured_error,{M,4},asn1ct_check,
+ param_wrong_number_of_arguments},
+ {structured_error,{M,6},asn1ct_check,
+ {param_bad_type, 'Seq'}}
+ ]
+ } = run(P, Config),
ok.
+
+constructed(Config) ->
+ M = 'Const',
+ P = {M,
+ <<"Const DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " Seq1 ::= SEQUENCE {a INTEGER, b BIT STRING, a BOOLEAN}\n"
+ " Ch ::= CHOICE {a INTEGER, b BIT STRING, a BOOLEAN}\n"
+ " Seq2 ::= SEQUENCE {COMPONENTS OF Ch}\n"
+ " CL ::= CLASS { &id INTEGER UNIQUE, &Type }\n"
+ " Seq3 ::= SEQUENCE { id CL.&id, d CL.&foo }\n"
+
+ " Seq4 ::= SEQUENCE { a INTEGER, z INTEGER OPTIONAL, b Set1 }\n"
+ " Set1 ::= SET { c BOOLEAN, d INTEGER }\n"
+ " s1 Seq4 ::= {a 42, b {c TRUE, zz 4711}}\n"
+ " s2 Seq4 ::= {a 42, b {c TRUE, d FALSE}}\n"
+ " s3 Seq4 ::= {a 42, b {c TRUE}}\n"
+ " s4 Seq4 ::= {a 42, b {c TRUE, d 4711}, zz 4712}\n"
+ " s5 Seq4 ::= {a 42}\n"
+ " s6 Seq4 ::= {a 42, zz 4712, b {c TRUE, d 4711}}\n"
+ "END\n">>},
+ {error,
+ [{structured_error,{M,2},asn1ct_check,{duplicate_identifier,a}},
+ {structured_error,{M,3},asn1ct_check,{duplicate_identifier,a}},
+ {structured_error,{M,4},asn1ct_check,{illegal_COMPONENTS_OF,'Ch'}},
+ {structured_error,{M,6},asn1ct_check,{illegal_object_field,foo}},
+
+ {structured_error,{M,9},asn1ct_check,{illegal_id,zz}},
+ {structured_error,{M,10},asn1ct_check,illegal_integer_value},
+ {structured_error,{M,11},asn1ct_check,{missing_id,d}},
+ {structured_error,{M,12},asn1ct_check,{illegal_id,zz}},
+ {structured_error,{M,13},asn1ct_check,{missing_id,b}},
+ {structured_error,{M,14},asn1ct_check,{illegal_id,zz}}
+ ]
+ } = run(P, Config),
+ ok.
+
+syntax(Config) ->
+ M = 'Syntax',
+ P = {M,
+ <<"Syntax DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " obj1 CL ::= { WRONG }\n"
+ " obj2 CL ::= { CODE 42 AGAIN WRONG }\n"
+ " obj3 CL ::= { INTEGER }\n"
+ " obj4 CL ::= { BIT STRING }\n"
+ " obj5 CL ::= { , }\n"
+ " obj6 CL ::= { CODE , }\n"
+ " obj7 CL ::= { CODE \"abc\" }\n"
+ " obj8 CL ::= { CODE }\n"
+ " obj9 CL ::= { CODE 42 ENUM}\n"
+ " obj10 CL ::= { CODE 42 ENUM BIT STRING}\n"
+
+ " obj11 CL ::= { CODE 42 TYPE 13}\n"
+ " obj12 CL ::= { CODE 42 TYPE d}\n"
+ " obj13 CL ::= { CODE 42 TYPE bs-value}\n"
+
+ " bad-syntax-1 BAD-SYNTAX-1 ::= { BAD 42 }\n"
+
+ " obj14 CL ::= { CODE 42 OBJ-SET integer }\n"
+ " obj15 CL ::= { CODE 42 OBJ-SET { A B } }\n"
+ " obj16 CL ::= { CODE 42 OBJ-SET SEQUENCE { an INTEGER } }\n"
+
+ " obj17 CL ::= { CODE 42 OID {seqtag 42} }\n"
+ " obj18 CL ::= { CODE 42 OID {seqtag 42, seqtag-again 43} }\n"
+ " obj19 CL ::= { CODE 42 OID {one 1 two 2} }\n"
+
+ " BAD-SYNTAX-1 ::= CLASS {\n"
+ " &code INTEGER UNIQUE\n"
+ " } WITH SYNTAX {\n"
+ " BAD &bad\n"
+ " }\n"
+
+ " BAD-SYNTAX-2 ::= CLASS {\n"
+ " &code INTEGER UNIQUE\n"
+ " } WITH SYNTAX {\n"
+ " BAD &Bad\n"
+ " }\n"
+
+ " BAD-SYNTAX-3 ::= CLASS {\n"
+ " &code INTEGER UNIQUE\n"
+ " } WITH SYNTAX {\n"
+ " [ID &code]\n"
+ " }\n"
+
+ " BAD-SYNTAX-4 ::= CLASS {\n"
+ " &code INTEGER UNIQUE\n"
+ " } WITH SYNTAX {\n"
+ " ID\n"
+ " }\n"
+
+ " BAD-SYNTAX-5 ::= CLASS {\n"
+ " &code INTEGER UNIQUE,\n"
+ " &Type\n"
+ " } WITH SYNTAX {\n"
+ " ID\n"
+ " }\n"
+
+ " BAD-SYNTAX-6 ::= CLASS {\n"
+ " &code INTEGER UNIQUE\n"
+ " } WITH SYNTAX {\n"
+ " ID &code, &code\n"
+ " }\n"
+
+ " BAD-SYNTAX-7 ::= CLASS {\n"
+ " &code INTEGER UNIQUE,\n"
+ " &Type\n"
+ " } WITH SYNTAX {\n"
+ " ID &Type, &code, &code, &Type\n"
+ " }\n"
+
+ " CL ::= CLASS {\n"
+ " &code INTEGER UNIQUE,\n"
+ " &enum ENUMERATED { a, b, c} OPTIONAL,\n"
+ " &Type OPTIONAL,\n"
+ " &ObjSet CL OPTIONAL,\n"
+ " &oid OBJECT IDENTIFIER OPTIONAL\n"
+ " } WITH SYNTAX {\n"
+ " CODE &code [ENUM &enum] [TYPE &Type] [OBJ-SET &ObjSet]\n"
+ " [OID &oid]\n"
+ " }\n"
+
+ " bs-value BIT STRING ::= '1011'B\n"
+
+ " integer INTEGER ::= 42\n"
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,2},asn1ct_check,
+ {syntax_nomatch,"WRONG"}},
+ {structured_error,{M,3},asn1ct_check,
+ {syntax_nomatch,"AGAIN"}},
+ {structured_error,{M,4},asn1ct_check,
+ {syntax_nomatch,"INTEGER"}},
+ {structured_error,{M,5},asn1ct_check,
+ {syntax_nomatch,"BIT STRING"}},
+ {structured_error,{M,6},asn1ct_check,
+ {syntax_nomatch,"\",\""}},
+ {structured_error,{M,7},asn1ct_check,
+ {syntax_nomatch,"\",\""}},
+ {structured_error,{M,8},asn1ct_check,
+ {syntax_nomatch,"\"abc\""}},
+ {structured_error,{M,9},asn1ct_check,
+ syntax_nomatch},
+ {structured_error,{M,10},asn1ct_check,
+ syntax_nomatch},
+ {structured_error,{M,11},asn1ct_check,
+ {syntax_nomatch,"BIT STRING"}},
+ {structured_error,{M,12},asn1ct_check,
+ {syntax_nomatch,"13"}},
+ {structured_error,{M,13},asn1ct_check,
+ {syntax_nomatch,"d"}},
+ {structured_error,{M,14},asn1ct_check,
+ {syntax_nomatch,"bs-value"}},
+ {structured_error,{M,15},asn1ct_check,
+ {syntax_undefined_field,bad}},
+ {structured_error,{M,16},asn1ct_check,
+ {syntax_nomatch,"integer"}},
+ {structured_error,{M,17},asn1ct_check,
+ {syntax_nomatch,"\"A B\""}},
+ {structured_error,{M,18},asn1ct_check,
+ {syntax_nomatch,"SEQUENCE"}},
+ {structured_error,{M,19},asn1ct_check,
+ {syntax_nomatch,"\"seqtag 42\""}},
+ {structured_error,{M,20},asn1ct_check,
+ {syntax_nomatch,"\"seqtag 42 seqtag-again 43\""}},
+ {structured_error,{M,21},asn1ct_check,
+ {syntax_nomatch,"\"one 1 two 2\""}},
+ {structured_error,{M,22},asn1ct_check,
+ {syntax_undefined_field,bad}},
+ {structured_error,{M,27},asn1ct_check,
+ {syntax_undefined_field,'Bad'}},
+ {structured_error,{M,32},asn1ct_check,
+ {syntax_mandatory_in_optional_group,code}},
+ {structured_error,{M,37},asn1ct_check,
+ {syntax_missing_mandatory_fields,[code]}},
+ {structured_error,{M,42},asn1ct_check,
+ {syntax_missing_mandatory_fields,['Type',code]}},
+ {structured_error,{M,48},asn1ct_check,
+ {syntax_duplicated_fields,[code]}},
+ {structured_error,{M,53},asn1ct_check,
+ {syntax_duplicated_fields,['Type',code]}}
+ ]
+ } = run(P, Config),
+ ok.
+
+table_constraints(Config) ->
+ M = 'TableConstraints',
+ P = {M,
+ <<"TableConstraints DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " Seq-1 ::= SEQUENCE {\n"
+ " contentType CONTENTS.&id,\n"
+ " content CONTENTS.&Type({Contents}{@contentType})\n"
+ " }\n"
+
+ " Seq-2 ::= SEQUENCE {\n"
+ " contentType INTEGER,\n"
+ " content CONTENTS.&Type({Contents}{@contentType})\n"
+ " }\n"
+
+ " Int ::= INTEGER ({1})\n"
+
+ " Seq-3 ::= SEQUENCE {\n"
+ " contentType CONTENTS.&id({1})\n"
+ " }\n"
+
+ "Contents CONTENTS ::= {\n"
+ " {OCTET STRING IDENTIFIED BY {2 1 1}}\n"
+ "}\n"
+
+ "CONTENTS ::= TYPE-IDENTIFIER\n"
+ "END\n">>},
+ {error,
+ [{structured_error,
+ {M,2},asn1ct_check,
+ {missing_table_constraint,contentType}},
+ {structured_error,
+ {M,6},asn1ct_check,
+ {missing_ocft,contentType}},
+ {structured_error,
+ {M,10},asn1ct_check,
+ illegal_table_constraint},
+ {structured_error,
+ {M,11},asn1ct_check,
+ invalid_table_constraint}
+ ]} = run(P, Config),
+ ok.
+
+tags(Config) ->
+ M = 'Tags',
+ P = {M,
+ <<"Tags DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ "SeqOpt1 ::= SEQUENCE\n"
+ "{\n"
+ "bool1 BOOLEAN OPTIONAL,\n"
+ "int1 INTEGER,\n"
+ "seq1 SeqIn OPTIONAL\n"
+ "}\n"
+
+ "SeqOpt1Imp ::= SEQUENCE \n"
+ "{\n"
+ "bool1 [1] BOOLEAN OPTIONAL,\n"
+ "int1 INTEGER,\n"
+ "seq1 [2] SeqIn OPTIONAL,\n"
+ "seq2 [2] SeqIn OPTIONAL,\n"
+ "...,\n"
+ "int2 [3] SeqIn,\n"
+ "int3 [3] SeqIn\n"
+ "}\n"
+
+ "SeqIn ::= SEQUENCE \n"
+ "{\n"
+ "boolIn BOOLEAN,\n"
+ "intIn INTEGER\n"
+ "}\n"
+ "\n"
+
+
+ "Set1 ::= SET {\n"
+ " os [0] OCTET STRING,\n"
+ " bool [0] BOOLEAN\n"
+ "}\n"
+
+ "Seq1 ::= SEQUENCE {\n"
+ "a [0] IMPLICIT Choice OPTIONAL\n"
+ "}\n"
+ "Seq2 ::= SEQUENCE {\n"
+ "a [0] IMPLICIT ANY OPTIONAL\n"
+ "}\n"
+ "Choice ::=\n"
+ "CHOICE {\n"
+ "a [0] BOOLEAN,\n"
+ "b [1] INTEGER\n"
+ "}\n"
+
+ "END\n">>},
+ {error,
+ [{structured_error,
+ {M,8},asn1ct_check,
+ {duplicate_tags,[seq1,seq2]}},
+ {structured_error,
+ {M,24},asn1ct_check,
+ {duplicate_tags,[bool,os]}},
+ {structured_error,
+ {M,28},asn1ct_check,
+ {implicit_tag_before,choice}},
+ {structured_error,
+ {M,31},asn1ct_check,
+ {implicit_tag_before,open_type}}
+ ]} = run(P, Config),
+ ok.
+
+
values(Config) ->
M = 'Values',
P = {M,
@@ -241,6 +814,53 @@ values(Config) ->
" os1 OCTET STRING ::= \"abc\"\n"
" os2 OCTET STRING ::= 42\n"
" os3 OCTET STRING ::= { 1, 3 }\n"
+ " os4 OCTET STRING ::= '1234'H\n"
+ " Seq ::= SEQUENCE {\n"
+ " an OCTET STRING\n"
+ " }\n"
+ " seq Seq ::= { an int }\n"
+ " os5 OCTET STRING ::= holder-1.&str\n"
+ " os6 OCTET STRING ::= int\n"
+
+ " int1 INTEGER ::= \"string\"\n"
+ " int2 INTEGER ::= os4\n"
+ " int3 INTEGER ::= not-defined\n"
+ " int4 INTEGER ::= holder-1.&str\n"
+ " int5 INTEGER ::= holder-2.&obj\n"
+ " int6 INTEGER ::= holder-2.&undefined-field\n"
+ " int7 INTEGER ::= holder-2.&UndefinedField.&id\n"
+
+ " bs1 BIT STRING ::= 42\n"
+ " bs2 BIT STRING ::= {a,b}\n"
+ " bs3 BIT STRING {a(0),z(25)} ::= {a,b}\n"
+ " bs4 BIT STRING {a(0),z(25)} ::= int\n"
+ " bs5 BIT STRING ::= holder-2.&str\n"
+ " bs6 BIT STRING ::= holder-2.&obj\n"
+
+ " b1 BOOLEAN ::= 42\n"
+ " b2 BOOLEAN ::= {a,b}\n"
+
+ " HOLDER ::= CLASS {\n"
+ " &str IA5String,\n"
+ " &obj HOLDER OPTIONAL\n"
+ " }\n"
+
+ " holder-1 HOLDER ::= { &str \"xyz\" }\n"
+ " holder-2 HOLDER ::= { &str \"xyz\", &obj holder-1 }\n"
+
+ " ext-1 EXTERNAL ::= {identification bad:{1 2 3}, data-value '123'H}\n"
+ " ext-2 EXTERNAL ::= {identification syntax:{1 2 3}, data '123'H}\n"
+
+ " CH ::= CHOICE { a INTEGER, b BOOLEAN }\n"
+ " ch1 CH ::= 2344\n"
+ " ch2 CH ::= zz:34\n"
+
+ " st1 an < Seq ::= 42\n"
+ " st2 zz < CH ::= 42\n"
+ " st3 a < HOLDER ::= 42\n"
+ " st4 a < INTEGER ::= 42\n"
+
+ " int INTEGER ::= 42\n"
"END\n">>},
{error,
[
@@ -249,7 +869,59 @@ values(Config) ->
{structured_error,{M,3},asn1ct_check,
illegal_octet_string_value},
{structured_error,{M,4},asn1ct_check,
- illegal_octet_string_value}
+ illegal_octet_string_value},
+ {structured_error,{M,9},asn1ct_check,
+ illegal_octet_string_value},
+ {structured_error,{M,10},asn1ct_check,
+ illegal_octet_string_value},
+ {structured_error,{M,11},asn1ct_check,
+ illegal_octet_string_value},
+ {structured_error,{M,12},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,13},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,14},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,15},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,16},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,17},asn1ct_check,
+ {undefined_field,'undefined-field'}},
+ {structured_error,{M,18},asn1ct_check,
+ {undefined_field,'UndefinedField'}},
+ {structured_error,{M,19},asn1ct_check,
+ {illegal_value, "BIT STRING"}},
+ {structured_error,{M,20},asn1ct_check,
+ {illegal_value, "BIT STRING"}},
+ {structured_error,{M,21},asn1ct_check,
+ {illegal_value, "BIT STRING"}},
+ {structured_error,{M,22},asn1ct_check,
+ {illegal_value, "BIT STRING"}},
+ {structured_error,{M,23},asn1ct_check,
+ {illegal_value, "BIT STRING"}},
+ {structured_error,{M,24},asn1ct_check,
+ {illegal_value, "BIT STRING"}},
+ {structured_error,{M,25},asn1ct_check,
+ {illegal_value, "BOOLEAN"}},
+ {structured_error,{M,26},asn1ct_check,
+ {illegal_value, "BOOLEAN"}},
+ {structured_error,{M,33},asn1ct_check,
+ illegal_external_value},
+ {structured_error,{M,34},asn1ct_check,
+ illegal_external_value},
+ {structured_error,{M,36},asn1ct_check,
+ {illegal_id, 2344}},
+ {structured_error,{M,37},asn1ct_check,
+ {illegal_id, zz}},
+ {structured_error,{M,38},asn1ct_check,
+ {illegal_choice_type, 'Seq'}},
+ {structured_error,{M,39},asn1ct_check,
+ {illegal_id, zz}},
+ {structured_error,{M,40},asn1ct_check,
+ {illegal_choice_type, 'HOLDER'}},
+ {structured_error,{M,41},asn1ct_check,
+ {illegal_choice_type, 'INTEGER'}}
]
} = run(P, Config),
ok.
@@ -258,5 +930,7 @@ values(Config) ->
run({Mod,Spec}, Config) ->
Base = atom_to_list(Mod) ++ ".asn1",
File = filename:join(?config(priv_dir, Config), Base),
+ Include0 = filename:dirname(?config(data_dir, Config)),
+ Include = filename:join(filename:dirname(Include0), "asn1_SUITE_data"),
ok = file:write_file(File, Spec),
- asn1ct:compile(File).
+ asn1ct:compile(File, [{i, Include}]).
diff --git a/lib/asn1/test/h323test.erl b/lib/asn1/test/h323test.erl
index 7577928493..39097a9330 100644
--- a/lib/asn1/test/h323test.erl
+++ b/lib/asn1/test/h323test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/syntax_SUITE.erl b/lib/asn1/test/syntax_SUITE.erl
new file mode 100644
index 0000000000..2c23416433
--- /dev/null
+++ b/lib/asn1/test/syntax_SUITE.erl
@@ -0,0 +1,341 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(syntax_SUITE).
+-export([suite/0,all/0,groups/0,
+ assignment/1,
+ class/1,
+ constraints/1,
+ exports/1,
+ header/1,
+ imports/1,
+ objects/1,
+ sequence/1,
+ syntax/1,
+ tokenizer/1,
+ types/1,
+ values/1]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks, [ts_install_cth]}].
+
+all() ->
+ [{group,p}].
+
+groups() ->
+ [{p,parallel(),
+ [assignment,
+ class,
+ constraints,
+ exports,
+ header,
+ imports,
+ objects,
+ sequence,
+ syntax,
+ tokenizer,
+ types,
+ values]}].
+
+parallel() ->
+ case erlang:system_info(schedulers) > 1 of
+ true -> [parallel];
+ false -> []
+ end.
+
+assignment(Config) ->
+ Head = "Assignment DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n",
+ End = "\nEND\n",
+ L0 = [{"42",3,{syntax_error,42}},
+ {"i",4,{syntax_error,'END'}},
+ {"i ::=",3,{syntax_error,'::='}},
+ {"i type",4,{syntax_error,'END'}},
+ {"i type ::=",3,{syntax_error,'::='}},
+ {"i TYPE",4,{syntax_error,'END'}},
+ {"i TYPE ::= ",4,{syntax_error,'END'}},
+ {"i INTEGER ::= 42 garbage",4,{syntax_error,'END'}},
+ {"i{T} Type",4,{syntax_error,'END'}},
+ {"TYPE",4,{syntax_error,'END'}},
+ {"TYPE ::=",4,{syntax_error,'END'}},
+ {"TYPE{ ::=",3,{syntax_error,'::='}},
+ {"TYPE{P, ::=",3,{syntax_error,'::='}},
+ {"TYPE{P,} ::=",3,{syntax_error,'}'}},
+ {"TYPE{Gov:} ::=",3,{syntax_error,':'}},
+ {"TYPE{A} CL ",4,{syntax_error,'END'}},
+ {"ObjSet CL",4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Assignment", Config),
+ ok.
+
+class(Config) ->
+ Head = "Class DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " CL ::= CLASS {",
+ End = "\nEND\n",
+ L0 = [{"id",3,{syntax_error,'id'}},
+ {"&id INTEGER",4,{syntax_error,'END'}},
+ {"&id INTEGER,",4,{syntax_error,'END'}},
+ {"&id,",3,{syntax_error,','}},
+ {"&id OPTIONAL",3,{syntax_error,'OPTIONAL'}},
+ {"&id INTEGER OPTIONAL",4,{syntax_error,'END'}},
+ {"&var &Field",4,{syntax_error,'END'}},
+ {"&Type,",4,{syntax_error,'END'}},
+ {"&Type OPTIONAL",4,{syntax_error,'END'}},
+ {"&ValueSet INTEGER OPTIONAL",4,{syntax_error,'END'}},
+ {"&ValueSet INTEGER DEFAULT",4,{syntax_error,'END'}},
+ {"&ValueSet INTEGER DEFAULT {",4,{syntax_error,'END'}},
+ {"&ValueSet INTEGER DEFAULT {a",4,{syntax_error,'END'}},
+ {"&Var &Field",4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Class", Config),
+ ok.
+
+constraints(Config) ->
+ Head = "Constraints DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " Type ::= ",
+ End = "\nEND\n",
+ L0 = [{"INTEGER (",4,{syntax_error,'END'}},
+ {"INTEGER (10x",3,{syntax_error,x}},
+ {"INTEGER (10|(10y",3,{syntax_error,y}},
+ {"INTEGER (CONSTRAINED BY {}",4,{syntax_error,'END'}},
+ {"INTEGER (CONSTRAINED BY {INTEGER garbage",3,
+ {syntax_error,garbage}},
+ {"INTEGER ({ObjSet",4,{syntax_error,'END'}},
+ {"INTEGER ({ObjSet}{",3,{syntax_error,'{'}},
+ {"INTEGER ({ObjSet}{@",3,{syntax_error,'{'}},
+ {"INTEGER ({ObjSet}{@x",3,{syntax_error,'{'}},
+ {"INTEGER ({ObjSet}{@x}",4,{syntax_error,'END'}},
+ {"INTEGER (10 !BOOLEAN",4,{syntax_error,'END'}},
+ {"INTEGER (10 !BOOLEAN:",4,{syntax_error,'END'}},
+ {"INTEGER (10 !BOOLEAN:FALSE",4,{syntax_error,'END'}},
+ {"SEQUENCE {} (WITH COMPONENTS { Type })",
+ 3,{syntax_error,'Type'}},
+ {"SEQUENCE {} (WITH COMPONENTS { x (10)",
+ 4,{syntax_error,'END'}},
+ {"SEQUENCE {} (WITH COMPONENTS { ..., x (10)",
+ 4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Constraints", Config),
+ ok.
+
+exports(Config) ->
+ Head = "Exports DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " EXPORTS ",
+ End = "\nEND\n",
+ L0 = [{"Type",4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Exports", Config),
+ ok.
+
+header(Config) ->
+ L = [{"lowercase",1,{syntax_error,lowercase}},
+ {"H ",2,{syntax_error,'END-OF-FILE'}},
+ {"H-",1,{syntax_error,'-'}},
+ {"42",1,{syntax_error,42}},
+ {"H definitions",1,{syntax_error,definitions}},
+ {"H DEFINITIONS STUPID TAGS",1,{syntax_error,'STUPID'}},
+ {"H DEFINITIONS WHATEVER",1,{syntax_error,'WHATEVER'}},
+ {"H DEFINITIONS ::= BEGIN",2,{syntax_error,'END-OF-FILE'}},
+ {"BOOLEAN",1,{syntax_error,'BOOLEAN'}}
+ ],
+ run(L, "H", Config),
+ ok.
+
+imports(Config) ->
+ Head = "Imports DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " IMPORTS ",
+ End = "\nEND\n",
+ L0 = [{"Type FROM X",4,{syntax_error,'END'}},
+ {"Symbols TO Y",3,{syntax_error,'TO'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Imports", Config),
+ ok.
+
+objects(Config) ->
+ Head = "Objects DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " object CLASS-NAME ::= ",
+ End = "\nEND\n",
+ L0 = [{"{",4,{syntax_error,'END'}},
+ {"{&min 1, max 10}",3,{syntax_error,max}},
+ {"{&min 1, Max 10}",3,{syntax_error,'Max'}},
+ {"{min 1, &max 10}",3,{syntax_error,'&max'}},
+ {"{min 1, &Max 10}",3,{syntax_error,'&Max'}},
+ {"{RESERVERD WORD BIT}",3,{syntax_error,'BIT'}},
+ {"{&min 1",4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Objects", Config),
+ ok.
+
+sequence(Config) ->
+ Head = "Sequence DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " Type ::= SEQUENCE {",
+ End = "\nEND\n",
+ L0 = [{"",4,{syntax_error,'END'}},
+ {" UpperCase",3,{syntax_error,'UpperCase'}},
+ {" a b",4,{syntax_error,'END'}},
+ {" i INTEGER",4,{syntax_error,'END'}},
+ {" ...",4,{syntax_error,'END'}},
+ {" ..., [[",4,{syntax_error,'END'}},
+ {" ..., [[ a INTEGER ]",3,{syntax_error,']'}},
+ {" ..., [[ a INTEGER,",3,{syntax_error,','}},
+ {" ..., [[ a INTEGER, ... ]]",3,{syntax_error,','}},
+ {" ... !42 xxx",3,{syntax_error,'xxx'}},
+ {" ... !42, a INTEGER,",3,{syntax_error,','}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Sequence", Config),
+ ok.
+
+syntax(Config) ->
+ Head = "Syntax DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " CL ::= CLASS { &id INTEGER UNIQUE } WITH SYNTAX ",
+ End = "\nEND\n",
+ L0 = [{"{}",3,{syntax_error,'}'}},
+ {"WORD",3,{syntax_error,'WORD'}},
+ {"{ Word }",3,{syntax_error,'Word'}},
+ {"{ [ Word ] }",3,{syntax_error,'Word'}},
+ {"{ [ WORD }",3,{syntax_error,'}'}},
+ {"{ WORD;",3,{syntax_error,';'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Syntax", Config),
+ ok.
+
+tokenizer(Config) ->
+ Head = "Tokenize DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n",
+ End = "\nEND\n",
+ L0 = [{"'",3,eol_in_token},
+ {"'42'B",3,{invalid_binary_number,"42"}},
+ {"'ZZZ'H",3,{invalid_hex_number,"ZZZ"}},
+ {"\"abc",3,missing_quote_at_eof},
+ {"/*",3,eof_in_comment}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Tokenizer", Config, asn1ct_tok),
+ ok.
+
+types(Config) ->
+ Head = "Types DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " Type ::= ",
+ End = "\nEND\n",
+ L0 = [{"BIT STRING garbage",4,{syntax_error,'END'}},
+ {"BIT STRING {",4,{syntax_error,'END'}},
+ {"BIT STRING { a(42",3,{syntax_error,42}},
+ {"BIT STRING { a(0)",4,{syntax_error,'END'}},
+ {"CHOICE {",4,{syntax_error,'END'}},
+ {"CHOICE { ..., a}",3,{syntax_error,'...'}},
+ {"CHOICE { UpperCase",3,{syntax_error,'UpperCase'}},
+ {"CHOICE { i INTEGER",4,{syntax_error,'END'}},
+ {"CHOICE { ..., i INTEGER }",3,{syntax_error,'...'}},
+ {"CHOICE { b BOOLEAN, ..., i INTEGER",
+ 4,{syntax_error,'END'}},
+ {"CHOICE { b BOOLEAN, ..., [[ e BOOLEAN, ...]]}",
+ 3,{syntax_error,','}},
+ {"CHOICE { b BOOLEAN, ..., i INTEGER, ..., x BIT STRING}",
+ 3,{syntax_error,','}},
+ {"ENUMERATED {",4,{syntax_error,'END'}},
+ {"ENUMERATED { 42 }",3,{syntax_error,42}},
+ {"ENUMERATED { a, b",4,{syntax_error,'END'}},
+ {"ENUMERATED { a, }",3,{syntax_error,','}},
+ {"ENUMERATED { a, ...,\nb, ..., c }",4,{syntax_error,','}},
+ {"INTEGER {",4,{syntax_error,'END'}},
+ {"INTEGER { a(42)",4,{syntax_error,'END'}},
+ {"SEQUENCE",3,{syntax_error,'SEQUENCE'}},
+ %% More tests for SEQUENCE in sequence/1.
+ {"SEQUENCE SIZE (1..10)",4,{syntax_error,'END'}},
+ {"SEQUENCE (SIZE (1..10))",4,{syntax_error,'END'}},
+ {"SET { i INTEGER",4,{syntax_error,'END'}},
+ {"SET { ...",4,{syntax_error,'END'}},
+ {"SET SIZE (1..10)",4,{syntax_error,'END'}},
+ {"SET (SIZE (1..10))",4,{syntax_error,'END'}},
+ {"SET { ... !42 xxx",3,{syntax_error,'xxx'}},
+ {"SET { ... !42, a INTEGER,",3,{syntax_error,','}},
+ {"[",4,{syntax_error,'END'}},
+ {"[42",4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Types", Config),
+ ok.
+
+values(Config) ->
+ Head = "Values DEFINITIONS AUTOMATIC TAGS ::=\n"
+ "BEGIN\n"
+ " value Type ::= ",
+ End = "\nEND\n",
+ L0 = [{"",4,{syntax_error,'END'}}
+ ],
+ L = [{Head++S++End,Line,E} || {S,Line,E} <- L0],
+ run(L, "Values", Config),
+ ok.
+
+run(List, File, Config) ->
+ run(List, File, Config, asn1ct_parser2).
+
+run(List, File0, Config, Module) ->
+ Base = File0 ++ ".asn1",
+ File = filename:join(?config(priv_dir, Config), Base),
+ case run_1(List, Base, File, Module, 0) of
+ 0 -> ok;
+ Errors -> ?t:fail(Errors)
+ end.
+
+run_1([{Source,Line,Error}=Exp|T], Base, File, Module, N) ->
+ ok = file:write_file(File, Source),
+ io:format("~s", [Source]),
+ case asn1ct:compile(File) of
+ {error,[{structured_error,{Base,L},Module,E}]} ->
+ case {L,E} of
+ {Line,Error} ->
+ run_1(T, Base, File, Module, N);
+ {Line,OtherError} ->
+ io:format("*** Wrong error: ~p, expected ~p ***\n",
+ [OtherError,Error]),
+ run_1(T, Base, File, Module, N+1);
+ {OtherLine,Error} ->
+ io:format("*** Wrong line: ~p, expected ~p ***\n",
+ [OtherLine,Line]),
+ run_1(T, Base, File, Module, N+1);
+ {_,_} ->
+ io:format("*** Wrong line: ~p, expected ~p ***",
+ [L,Line]),
+ io:format("*** Wrong error: ~p, expected ~p ***\n",
+ [E,Error]),
+ run_1(T, Base, File, Module, N+1)
+ end;
+ Other ->
+ io:format("~p\nGOT: ~p", [Exp,Other])
+ end;
+run_1([], _, _, _, N) ->
+ N.
diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl
index 09e19ceebb..33515403d1 100644
--- a/lib/asn1/test/testChoExtension.erl
+++ b/lib/asn1/test/testChoExtension.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,11 +40,6 @@ extension(_Rules) ->
roundtrip('ChoExt3', {int,33}),
roundtrip('ChoExt4', {str,<<"abc">>}),
- roundtrip('ChoEmptyRoot', {bool,false}),
- roundtrip('ChoEmptyRoot', {bool,true}),
- roundtrip('ChoEmptyRoot', {int,0}),
- roundtrip('ChoEmptyRoot', {int,7}),
-
ok.
diff --git a/lib/asn1/test/testChoExternal.erl b/lib/asn1/test/testChoExternal.erl
index 0914d54f33..980b837475 100644
--- a/lib/asn1/test/testChoExternal.erl
+++ b/lib/asn1/test/testChoExternal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoOptional.erl b/lib/asn1/test/testChoOptional.erl
index 71a7346e3f..d573e76a89 100644
--- a/lib/asn1/test/testChoOptional.erl
+++ b/lib/asn1/test/testChoOptional.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoPrim.erl b/lib/asn1/test/testChoPrim.erl
index 4665de6989..abf3fcdb81 100644
--- a/lib/asn1/test/testChoPrim.erl
+++ b/lib/asn1/test/testChoPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testChoRecursive.erl b/lib/asn1/test/testChoRecursive.erl
index ccd60c2897..a307d448ed 100644
--- a/lib/asn1/test/testChoRecursive.erl
+++ b/lib/asn1/test/testChoRecursive.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoTypeRefCho.erl b/lib/asn1/test/testChoTypeRefCho.erl
index 636c301403..378a43fa59 100644
--- a/lib/asn1/test/testChoTypeRefCho.erl
+++ b/lib/asn1/test/testChoTypeRefCho.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoTypeRefPrim.erl b/lib/asn1/test/testChoTypeRefPrim.erl
index 747baeddd8..3541277674 100644
--- a/lib/asn1/test/testChoTypeRefPrim.erl
+++ b/lib/asn1/test/testChoTypeRefPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoTypeRefSeq.erl b/lib/asn1/test/testChoTypeRefSeq.erl
index 91d0b45e89..c582d6f0fc 100644
--- a/lib/asn1/test/testChoTypeRefSeq.erl
+++ b/lib/asn1/test/testChoTypeRefSeq.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoTypeRefSet.erl b/lib/asn1/test/testChoTypeRefSet.erl
index bd9068b53e..2d4f6cce4b 100644
--- a/lib/asn1/test/testChoTypeRefSet.erl
+++ b/lib/asn1/test/testChoTypeRefSet.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testChoiceIndefinite.erl b/lib/asn1/test/testChoiceIndefinite.erl
index 87910cf6ec..d796871620 100644
--- a/lib/asn1/test/testChoiceIndefinite.erl
+++ b/lib/asn1/test/testChoiceIndefinite.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testCompactBitString.erl b/lib/asn1/test/testCompactBitString.erl
index f74992a79e..6265e20ab2 100644
--- a/lib/asn1/test/testCompactBitString.erl
+++ b/lib/asn1/test/testCompactBitString.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl
index 3ccf883bd6..60b7994929 100644
--- a/lib/asn1/test/testConstraints.erl
+++ b/lib/asn1/test/testConstraints.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -231,6 +232,28 @@ int_constraints(Rules) ->
seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 19000),
seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 26900),
+ %%==========================================================
+ %% Constraints from object fields.
+ %%==========================================================
+ range_error(Rules, 'IntObjectConstr', 1),
+ roundtrip('IntObjectConstr', 2),
+ roundtrip('IntObjectConstr', 3),
+ roundtrip('IntObjectConstr', 4),
+ range_error(Rules, 'IntObjectConstr', 5),
+
+
+ %%==========================================================
+ %% INTEGER constraints defined using named INTEGERs.
+ %%==========================================================
+ 42 = 'Constraints':'constrainedNamedInt-1'(),
+ 100 = 'Constraints':'constrainedNamedInt-2'(),
+ range_error(Rules, 'ConstrainedNamedInt', 41),
+ roundtrip('ConstrainedNamedInt', v1),
+ range_error(Rules, 'ConstrainedNamedInt', 43),
+
+ range_error(Rules, 'SeqWithNamedInt', {'SeqWithNamedInt',-100}),
+ roundtrip('SeqWithNamedInt', {'SeqWithNamedInt',v2}),
+
ok.
%% PER: Ensure that if the lower bound is Lb, Lb+16#80 is encoded
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
index 61d1fbdd69..f1af6cf0e5 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testDER.erl b/lib/asn1/test/testDER.erl
index 3f74a16797..195d8fe5a4 100644
--- a/lib/asn1/test/testDER.erl
+++ b/lib/asn1/test/testDER.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl
index 880f15e91a..50291bf645 100644
--- a/lib/asn1/test/testDeepTConstr.erl
+++ b/lib/asn1/test/testDeepTConstr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testDef.erl b/lib/asn1/test/testDef.erl
index b8df3c4f8b..c07665d097 100644
--- a/lib/asn1/test/testDef.erl
+++ b/lib/asn1/test/testDef.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testDoubleEllipses.erl b/lib/asn1/test/testDoubleEllipses.erl
index bd6831bf1e..8dcd979d6a 100644
--- a/lib/asn1/test/testDoubleEllipses.erl
+++ b/lib/asn1/test/testDoubleEllipses.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl
index 878518be11..122d198205 100644
--- a/lib/asn1/test/testEnumExt.erl
+++ b/lib/asn1/test/testEnumExt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -78,6 +79,9 @@ common(Erule) ->
v_roundtrip(Erule, 'SeqBig', {'SeqBig',true,e40,9357}),
v_roundtrip(Erule, 'SeqBig', {'SeqBig',true,e80,9357}),
+
+ v_roundtrip(Erule, 'EnumSkip', d),
+
ok.
roundtrip(Type, Value) ->
@@ -85,11 +89,20 @@ roundtrip(Type, Value) ->
v_roundtrip(Erule, Type, Value) ->
Encoded = roundtrip(Type, Value),
- Encoded = asn1_test_lib:hex_to_bin(v(Erule, Value)).
-
-v(ber, {'SeqBig',true,e40,9357}) -> "300A8001 FF810141 8202248D";
-v(ber, {'SeqBig',true,e80,9357}) -> "300B8001 FF810200 81820224 8D";
-v(per, {'SeqBig',true,e40,9357}) -> "E0014002 248D";
-v(per, {'SeqBig',true,e80,9357}) -> "E0018002 248D";
-v(uper, {'SeqBig',true,e40,9357}) -> "E0280044 91A0";
-v(uper, {'SeqBig',true,e80,9357}) -> "E0300044 91A0".
+ Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type, Value)).
+
+v(Erule, 'SeqBig', Value) ->
+ v_seq_big(Erule, Value);
+v(Erule, 'EnumSkip', Value) ->
+ v_enum_skip(Erule, Value).
+
+v_seq_big(ber, {'SeqBig',true,e40,9357}) -> "300A8001 FF810141 8202248D";
+v_seq_big(ber, {'SeqBig',true,e80,9357}) -> "300B8001 FF810200 81820224 8D";
+v_seq_big(per, {'SeqBig',true,e40,9357}) -> "E0014002 248D";
+v_seq_big(per, {'SeqBig',true,e80,9357}) -> "E0018002 248D";
+v_seq_big(uper, {'SeqBig',true,e40,9357}) -> "E0280044 91A0";
+v_seq_big(uper, {'SeqBig',true,e80,9357}) -> "E0300044 91A0".
+
+v_enum_skip(per, d) -> "82";
+v_enum_skip(uper, d) -> "82";
+v_enum_skip(ber, d) -> "0A0103".
diff --git a/lib/asn1/test/testExtensibilityImplied.erl b/lib/asn1/test/testExtensibilityImplied.erl
new file mode 100644
index 0000000000..a039bec576
--- /dev/null
+++ b/lib/asn1/test/testExtensibilityImplied.erl
@@ -0,0 +1,30 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(testExtensibilityImplied).
+-export([main/0]).
+
+main() ->
+ M = 'ExtensibilityImplied',
+ {'Seq2',true} = M:decode('Seq2', M:encode('Seq1', {'Seq1',true,42})),
+ {'Set2',true} = M:decode('Set2', M:encode('Set1', {'Set1',true,42})),
+ {asn1_enum,_} = M:decode('Enum2', M:encode('Enum1', ext)),
+ ok.
diff --git a/lib/asn1/test/testFragmented.erl b/lib/asn1/test/testFragmented.erl
index 35b21f90a9..99867c016e 100644
--- a/lib/asn1/test/testFragmented.erl
+++ b/lib/asn1/test/testFragmented.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testINSTANCE_OF.erl b/lib/asn1/test/testINSTANCE_OF.erl
index c855ca3c06..afff05a4c5 100644
--- a/lib/asn1/test/testINSTANCE_OF.erl
+++ b/lib/asn1/test/testINSTANCE_OF.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testImporting.erl b/lib/asn1/test/testImporting.erl
new file mode 100644
index 0000000000..5eb950100d
--- /dev/null
+++ b/lib/asn1/test/testImporting.erl
@@ -0,0 +1,35 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(testImporting).
+-export([main/0]).
+
+main() ->
+ M = 'Importing',
+ roundtrip('Seq', {'Seq',5}),
+ roundtrip('OtherSeq', {'Seq',42,true}),
+ {'Seq',42,true} = M:seq(),
+ roundtrip('ObjSeq', {'ObjSeq',1,<<"XYZ">>}),
+ roundtrip('ObjSeq', {'ObjSeq',2,19}),
+ ok.
+
+roundtrip(Type, Value) ->
+ asn1_test_lib:roundtrip('Importing', Type, Value).
diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl
index 37c134b1b9..1b38d5414e 100644
--- a/lib/asn1/test/testInfObj.erl
+++ b/lib/asn1/test/testInfObj.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -74,6 +75,12 @@ main(_Erule) ->
{'ConstructedPdu',7,[]}),
roundtrip('InfObj', 'ConstructedPdu',
{'ConstructedPdu',7,[64,1,19,17,35]}),
+ {'ConstructedPdu',8,[{_,-15,35},{_,533,-70}]} =
+ enc_dec('InfObj', 'ConstructedPdu',
+ {'ConstructedPdu',8,[{'_',-15,35},{'_',533,-70}]}),
+ {'ConstructedPdu',9,[{RecTag9,-15,35},{RecTag9,533,-70}]} =
+ enc_dec('InfObj', 'ConstructedPdu',
+ {'ConstructedPdu',9,[{'_',-15,35},{'_',533,-70}]}),
roundtrip('InfObj', 'ConstructedSet',
{'ConstructedSet',1,{'CONSTRUCTED-DEFAULT_Type',-2001,true}}),
@@ -96,6 +103,12 @@ main(_Erule) ->
{'ConstructedSet',7,[]}),
roundtrip('InfObj', 'ConstructedSet',
{'ConstructedSet',7,[64,1,19,17,35]}),
+ {'ConstructedSet',8,[{_,-15,35},{_,533,-70}]} =
+ enc_dec('InfObj', 'ConstructedSet',
+ {'ConstructedSet',8,[{'_',-15,35},{'_',533,-70}]}),
+ {'ConstructedSet',9,[{_,-15,35},{_,533,-70}]} =
+ enc_dec('InfObj', 'ConstructedSet',
+ {'ConstructedSet',9,[{'_',-15,35},{'_',533,-70}]}),
roundtrip('InfObj', 'Seq2',
{'Seq2',42,[true,false,false,true],
@@ -126,12 +139,37 @@ main(_Erule) ->
test_objset('OstSeq45', [4,5]),
test_objset('OstSeq12345', [1,2,3,4,5]),
+ test_objset('OstSeq12Except', [1,2]),
+ test_objset('OstSeq123Except', [1,2]),
+
test_objset('ExOstSeq12', [1,2]),
test_objset('ExOstSeq123', [1,2,3]),
- %%test_objset('ExOstSeq1234', [1,2,3,4]),
+ test_objset('ExOstSeq1234', [1,2,3,4]),
test_objset('ExOstSeq45', [4,5]),
test_objset('ExOstSeq12345', [1,2,3,4,5]),
+ test_objset('ExOstSeq12Except', [1,2]),
+ test_objset('ExOstSeq123Except', [1,2]),
+
+ roundtrip('InfObj', 'ExtClassSeq', {'ExtClassSeq', 4}),
+
+ {1,2,42} = 'InfObj':'value-1'(),
+ {1,2,42,25} = 'InfObj':'value-2'(),
+ {100,101} = 'InfObj':'value-3'(),
+ {1,2,100,101} = 'InfObj':'value-4'(),
+
+ roundtrip('InfObj', 'Rdn', {'Rdn',{2,5,4,41},"abc"}),
+
+ roundtrip('InfObj', 'TiAliasSeq',
+ {'TiAliasSeq',{'TiAliasSeq_prf',{2,1,2},'NULL'}}),
+
+ roundtrip('InfObj', 'ContentInfo',
+ {'ContentInfo',{2,7,8,9},"string"}),
+ {2,7,8,9} = 'InfObj':'id-content-type'(),
+
+ <<2#1011:4>> = 'InfObj':'tricky-bit-string'(),
+ <<16#CAFE:16>> = 'InfObj':'tricky-octet-string'(),
+
ok.
test_objset(Type, Keys) ->
diff --git a/lib/asn1/test/testInfObjExtract.erl b/lib/asn1/test/testInfObjExtract.erl
new file mode 100644
index 0000000000..ba1d92c100
--- /dev/null
+++ b/lib/asn1/test/testInfObjExtract.erl
@@ -0,0 +1,73 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(testInfObjExtract).
+
+-export([main/0]).
+
+main() ->
+ roundtrip_data_object_13('DataSeq-1'),
+
+ roundtrip_data_object_1('DataSeq-2'),
+ roundtrip_data_object_1('DataSeq-3'),
+ roundtrip_data_object_1('DataSeq-4'),
+
+ roundtrip_data_object_13('DataSeq-5'),
+ roundtrip_data_object_13('DataSeq-6'),
+
+ roundtrip_data_object_1('DataSeqSingleSet-1'),
+ roundtrip_data_object_1('DataSeqSingleSet-2'),
+
+ roundtrip('ObjClassSeq-1', {'ObjClassSeq-1',1,true}),
+ roundtrip('ObjClassSeq-1', {'ObjClassSeq-1',2,true}),
+
+ roundtrip_error('ObjClassSeq-1', {'ObjClassSeq-1',0,false}),
+ roundtrip_error('ObjClassSeq-1', {'ObjClassSeq-1',3,true}),
+ roundtrip_error('ObjClassSeq-1', {'ObjClassSeq-1',4,false}),
+ roundtrip_error('ObjClassSeq-1', {'ObjClassSeq-1',5,true}),
+
+ ok.
+
+roundtrip_data_object_13(SeqType) ->
+ roundtrip(SeqType, {SeqType,1,true}),
+ roundtrip(SeqType, {SeqType,2,<<"abc">>}),
+ roundtrip(SeqType, {SeqType,3,<<42:5>>}),
+ roundtrip_error(SeqType, {SeqType,4,42}).
+
+roundtrip_data_object_1(SeqType) ->
+ roundtrip(SeqType, {SeqType,1,false}),
+ roundtrip(SeqType, {SeqType,1,true}),
+ roundtrip_error(SeqType, {SeqType,1,42}),
+ roundtrip_error(SeqType, {SeqType,2,<<"abc">>}),
+ roundtrip_error(SeqType, {SeqType,3,<<42:5>>}),
+ roundtrip_error(SeqType, {SeqType,999,42}).
+
+roundtrip(T, V) ->
+ asn1_test_lib:roundtrip('InfObjExtract', T, V).
+
+roundtrip_error(T, V) ->
+ try asn1_test_lib:roundtrip('InfObjExtract', T, V) of
+ ok ->
+ test_server:fail()
+ catch
+ _:_ ->
+ ok
+ end.
diff --git a/lib/asn1/test/testInfObjectClass.erl b/lib/asn1/test/testInfObjectClass.erl
index c36c05a2ea..271be63fc8 100644
--- a/lib/asn1/test/testInfObjectClass.erl
+++ b/lib/asn1/test/testInfObjectClass.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testMegaco.erl b/lib/asn1/test/testMegaco.erl
index 644042b484..b1b1c866be 100644
--- a/lib/asn1/test/testMegaco.erl
+++ b/lib/asn1/test/testMegaco.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testMergeCompile.erl b/lib/asn1/test/testMergeCompile.erl
index b21897cfc2..6bf7aaa1d6 100644
--- a/lib/asn1/test/testMergeCompile.erl
+++ b/lib/asn1/test/testMergeCompile.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testMultipleLevels.erl b/lib/asn1/test/testMultipleLevels.erl
index ff6d023440..0f465ee9da 100644
--- a/lib/asn1/test/testMultipleLevels.erl
+++ b/lib/asn1/test/testMultipleLevels.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl
index e37e22163a..e0eeb9fe0c 100644
--- a/lib/asn1/test/testNBAPsystem.erl
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testOpenTypeImplicitTag.erl b/lib/asn1/test/testOpenTypeImplicitTag.erl
index 0fbf70d037..01e0a5e07f 100644
--- a/lib/asn1/test/testOpenTypeImplicitTag.erl
+++ b/lib/asn1/test/testOpenTypeImplicitTag.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testOpt.erl b/lib/asn1/test/testOpt.erl
index a6dcccad15..1f96331966 100644
--- a/lib/asn1/test/testOpt.erl
+++ b/lib/asn1/test/testOpt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl
index 39f7947e8d..f4a696ff38 100644
--- a/lib/asn1/test/testParamBasic.erl
+++ b/lib/asn1/test/testParamBasic.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -46,6 +47,14 @@ main(Rules) ->
roundtrip('AnAlgorithm', {'AnAlgorithm',1,42}),
roundtrip('AnAlgorithm', {'AnAlgorithm',2,true}),
roundtrip('AnAlgorithm', {'AnAlgorithm',2,false}),
+ {'AnAlgorithm',1,42} = 'ParamBasic':'alg-seq-1'(),
+ {'AnAlgorithm',2,true} = 'ParamBasic':'alg-seq-2'(),
+
+ roundtrip('Seq', {'Seq',
+ {'Seq_c1',{2,1,1},42},
+ {'Seq_c2',{2,1,1,1},asn1_NOVALUE}}),
+
+ {_,{2,9,9,9,7},'NULL'} = 'ParamBasic':'algid-hmacWithSHA1'(),
ok.
roundtrip(Type, Value) ->
diff --git a/lib/asn1/test/testParameterizedInfObj.erl b/lib/asn1/test/testParameterizedInfObj.erl
index 2fe900792d..592dc693f0 100644
--- a/lib/asn1/test/testParameterizedInfObj.erl
+++ b/lib/asn1/test/testParameterizedInfObj.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl
index e07379e634..dc2e0fa2e7 100644
--- a/lib/asn1/test/testPrim.erl
+++ b/lib/asn1/test/testPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -77,8 +78,37 @@ int(Rules) ->
roundtrip('ASeq', {'ASeq',false,250,true,200,true,199,true,77788}),
roundtrip('ASeq', {'ASeq',true,0,false,0,true,0,true,68789}),
+ %%==========================================================
+ %% Longitude ::= INTEGER {
+ %% oneMicrodegreeEast(10),
+ %% oneMicrodegreeWest(-10),
+ %% unavailable(1800000001)
+ %% } (-1799999999..1800000001)
+ %%==========================================================
+
+ Enc10 = encoding(Rules, oneMicrodegreeEast),
+ Enc10 = roundtrip('Longitude', oneMicrodegreeEast),
+ Enc10 = roundtrip('Longitude', 10, oneMicrodegreeEast),
+
+ Enc20 = encoding(Rules, oneMicrodegreeWest),
+ Enc20 = roundtrip('Longitude', oneMicrodegreeWest),
+ Enc20 = roundtrip('Longitude', -10, oneMicrodegreeWest),
+
+ Enc30 = roundtrip('Longitude', unavailable),
+ Enc30 = roundtrip('Longitude', 1800000001, unavailable),
+
ok.
+encoding(Rules, Type) ->
+ asn1_test_lib:hex_to_bin(encoding_1(Rules, Type)).
+
+encoding_1(ber, oneMicrodegreeEast) -> "02010A";
+encoding_1(per, oneMicrodegreeEast) -> "C06B49D2 09";
+encoding_1(uper, oneMicrodegreeEast) -> "6B49D209";
+
+encoding_1(ber, oneMicrodegreeWest) -> "0201F6";
+encoding_1(per, oneMicrodegreeWest) -> "C06B49D1 F5";
+encoding_1(uper, oneMicrodegreeWest) -> "6B49D1F5".
enum(Rules) ->
@@ -98,6 +128,11 @@ enum(Rules) ->
ber ->
ok
end,
+
+ roundtrip('NegEnumVal', neg),
+ roundtrip('NegEnumVal', zero),
+ roundtrip('EnumVal128', val),
+
ok.
diff --git a/lib/asn1/test/testPrimExternal.erl b/lib/asn1/test/testPrimExternal.erl
index a03760976d..56252241d4 100644
--- a/lib/asn1/test/testPrimExternal.erl
+++ b/lib/asn1/test/testPrimExternal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
index 155d6f6ff5..46793c6bff 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -122,6 +123,7 @@ bit_string(Rules, Opts) ->
%% Bs2 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (7))
%%==========================================================
+ roundtrip('Bs2', []),
roundtrip('Bs2', [mo,tu,fr]),
bs_roundtrip('Bs2', <<2#0110010:7>>, [mo,tu,fr]),
bs_roundtrip('Bs2', <<2#0110011:7>>, [mo,tu,fr,sa]),
@@ -130,6 +132,7 @@ bit_string(Rules, Opts) ->
%% Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
%%==========================================================
+ roundtrip('Bs3', []),
roundtrip('Bs3', [mo,tu,fr]),
bs_roundtrip('Bs3', <<2#0110010:7>>, [mo,tu,fr]),
bs_roundtrip('Bs3', <<2#0110010:7>>, [mo,tu,fr]),
@@ -138,6 +141,13 @@ bit_string(Rules, Opts) ->
bs_roundtrip('Bs3', <<2#11:2>>, [su,mo]),
%%==========================================================
+ %% Bs4 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) }
+ %%==========================================================
+
+ roundtrip('Bs4', []),
+ roundtrip('Bs4', [mo,tu,fr,sa]),
+
+ %%==========================================================
%% Bs7 ::= BIT STRING (SIZE (24))
%%==========================================================
@@ -232,7 +242,8 @@ bit_string(Rules, Opts) ->
end.
random_bits(N) ->
- Seed = integer_to_list(erlang:phash2(erlang:now())),
+ Seed0 = {erlang:monotonic_time(),erlang:unique_integer()},
+ Seed = integer_to_list(erlang:phash2(Seed0)),
random_bits(<<>>, N, Seed).
random_bits(Bin, N, Seed) ->
diff --git a/lib/asn1/test/testRfcs.erl b/lib/asn1/test/testRfcs.erl
new file mode 100644
index 0000000000..20eaee9982
--- /dev/null
+++ b/lib/asn1/test/testRfcs.erl
@@ -0,0 +1,76 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(testRfcs).
+
+-export([compile/3,test/0]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+compile(Config, Erules, Options0) ->
+ Options = [no_ok_wrapper|Options0],
+ DataDir = ?config(data_dir, Config),
+ Specs0 = filelib:wildcard("*.asn1", filename:join(DataDir, rfcs)),
+ Specs = [filename:join(rfcs, Spec) || Spec <- Specs0],
+ 122 = length(Specs),
+ CaseDir = ?config(case_dir, Config),
+ asn1_test_lib:compile_all(Specs, Config, [Erules,{i,CaseDir}|Options]).
+
+test() ->
+ {1,3,6,1,5,5,7,48,1,2} =
+ IdPkixOcspNonce =
+ 'OCSP-2009':'id-pkix-ocsp-nonce'(),
+ roundtrip('OCSP-2009', 'OCSPRequest',
+ {'OCSPRequest',
+ {'TBSRequest',
+ 0,
+ {rfc822Name,"name string"},
+ [{'Request',
+ {'CertID',{'_',{2,9,3,4,5},asn1_NOVALUE},
+ <<"POTATOHASH">>,<<"HASHBROWN">>,42},
+ [{'_',IdPkixOcspNonce,true,<<34,159,16,57,199>>}]}],
+ asn1_NOVALUE},
+ asn1_NOVALUE}),
+ otp_7759(),
+ ok.
+
+roundtrip(Module, Type, Value0) ->
+ Enc = Module:encode(Type, Value0),
+ Value1 = Module:decode(Type, Enc),
+ asn1_test_lib:match_value(Value0, Value1),
+ ok.
+
+otp_7759() ->
+ %% The release note for asn-1.6.6 says:
+ %% Decode of an open_type when the value was empty tagged
+ %% type encoded with indefinite length failed.
+ Mod = 'OLD-PKCS7',
+ Encoded = encoded_msg(),
+ ContentInfo = Mod:decode('ContentInfo', Encoded),
+ io:format("~p\n", [ContentInfo]),
+ {'ContentInfo',_Id,PKCS7_content} = ContentInfo,
+ X = Mod:decode('SignedData', PKCS7_content),
+ io:format("~p\n", [X]),
+ io:nl(),
+ ok.
+
+encoded_msg() ->
+ <<48,128,6,9,42,134,72,134,247,13,1,7,2,160,128,48,128,2,1,1,49,11,48,9,6,5,43,14,3,2,26,5,0,48,128,6,9,42,134,72,134,247,13,1,7,1,160,128,36,128,0,0,0,0,0,0, 49,130,1,192,48,130,1,188,2,1,1,48,50,48,38,49,17,48,15,6,3,85,4,3,12,8,65,100,109,105,110,67,65,49,49,17,48,15,6,3,85,4,10,12,8,69,82,73,67,83,83,79,78,2,8,15,151,245,186,21,23,240,96,48,9,6,5,43,14,3,2,26,5,0,160,129,229,48,17,6,10,96,134,72,1,134,248,69,1,9,2,49,3,19,1,51,48,17,6,10,96,134,72,1,134,248,69,1,9,3,49,3,19,1,51,48,24,6,9,42,134,72,134,247,13,1,9,3,49,11,6,9,42,134,72,134,247,13,1,7,1,48,28,6,9,42,134,72,134,247,13,1,9,5,49,15,23,13,48,56,49,50,49,48,48,57,53,52,50,51,90,48,28,6,10,96,134,72,1,134,248,69,1,9,7,49,14,19,12,49,53,50,56,49,52,50,52,48,57,53,53,48,32,6,10,96,134,72,1,134,248,69,1,9,5,49,18,4,16,165,115,177,71,78,88,239,113,78,56,98,98,18,202,217,235,48,32,6,10,96,134,72,1,134,248,69,1,9,6,49,18,4,16,227,174,230,251,43,153,252,65,11,93,231,83,34,18,55,46,48,35,6,9,42,134,72,134,247,13,1,9,4,49,22,4,20,218,57,163,238,94,107,75,13,50,85,191,239,149,96,24,144,175,216,7,9,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,4,129,128,106,233,116,125,140,51,133,173,63,41,54,138,214,211,89,215,169,125,98,77,16,222,216,240,211,79,125,111,87,186,73,63,253,204,107,102,177,63,174,197,224,212,231,172,149,246,33,68,223,67,102,93,64,152,152,5,216,102,247,134,36,197,150,236,57,77,56,138,95,71,204,31,23,149,241,213,78,172,165,249,100,187,12,45,19,57,67,120,54,63,15,239,41,217,127,61,254,60,201,104,68,3,135,214,206,93,253,255,192,94,56,107,68,210,57,61,41,249,47,156,130,244,52,12,163,216,236,69,0,0,0,0,0,0>>.
diff --git a/lib/asn1/test/testSSLspecs.erl b/lib/asn1/test/testSSLspecs.erl
index 08da92243e..9e51021ad2 100644
--- a/lib/asn1/test/testSSLspecs.erl
+++ b/lib/asn1/test/testSSLspecs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSelectionTypes.erl b/lib/asn1/test/testSelectionTypes.erl
index 6d060321da..d33cfcc694 100644
--- a/lib/asn1/test/testSelectionTypes.erl
+++ b/lib/asn1/test/testSelectionTypes.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,10 +24,34 @@
-include_lib("test_server/include/test_server.hrl").
test() ->
- Val = ["PrintableString","PrintableString","PrintableString"],
["Es"] = Val2 = ['SelectionType':einsteinium()],
- roundtrip('MendeleyevTable', Val),
+ roundtrip('MendeleyevTable', ["fox","tree","cat","stone"]),
roundtrip('MendeleyevTable', Val2),
+ roundtrip('MendeleyevSet', [42,57,93,101]),
+
+ M = 'SelectionType',
+ true = M:boolv(),
+ 4 = M:intv(),
+ <<2#1001:4>> = M:bsv(),
+ <<16#3130:16>> = M:osv(),
+ 'NULL' = M:nullv(),
+ {2,1,1} = M:oiv(),
+ "ObjectDesc" = M:odv(),
+ "utf8" = M:utfv(),
+ {5,32767,256} = M:rov(),
+ "089" = M:numsv(),
+ "telet" = M:teletv(),
+ "t61" = M:t61v(),
+ "video" = M:videov(),
+ "ia5" = M:ia5v(),
+ "9805281429Z" = M:utctimev(),
+ "19980528142905.1" = M:gTime(),
+ "graphic" = M:gsv(),
+ "visible" = M:vsv(),
+ "general" = M:gStringv(),
+ "Universal" = M:univv(),
+ "bmp" = M:bmov(),
+
ok.
roundtrip(T, V) ->
diff --git a/lib/asn1/test/testSeq2738.erl b/lib/asn1/test/testSeq2738.erl
index 9c059f2fc9..3c9e4a744e 100644
--- a/lib/asn1/test/testSeq2738.erl
+++ b/lib/asn1/test/testSeq2738.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqDefault.erl b/lib/asn1/test/testSeqDefault.erl
index 22c1b7ee3a..db0914bf0a 100644
--- a/lib/asn1/test/testSeqDefault.erl
+++ b/lib/asn1/test/testSeqDefault.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl
index c16e9fcd4c..6b49b29047 100644
--- a/lib/asn1/test/testSeqExtension.erl
+++ b/lib/asn1/test/testSeqExtension.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqExternal.erl b/lib/asn1/test/testSeqExternal.erl
index 0b1d305054..a48794924f 100644
--- a/lib/asn1/test/testSeqExternal.erl
+++ b/lib/asn1/test/testSeqExternal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqOf.erl b/lib/asn1/test/testSeqOf.erl
index 25059d6052..898b8c1e15 100644
--- a/lib/asn1/test/testSeqOf.erl
+++ b/lib/asn1/test/testSeqOf.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqOfCho.erl b/lib/asn1/test/testSeqOfCho.erl
index f749845bb9..82ac56ac50 100644
--- a/lib/asn1/test/testSeqOfCho.erl
+++ b/lib/asn1/test/testSeqOfCho.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqOfExternal.erl b/lib/asn1/test/testSeqOfExternal.erl
index 38b9f0ce7c..560fdecb64 100644
--- a/lib/asn1/test/testSeqOfExternal.erl
+++ b/lib/asn1/test/testSeqOfExternal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqOfIndefinite.erl b/lib/asn1/test/testSeqOfIndefinite.erl
index b771405d84..4a0101834a 100644
--- a/lib/asn1/test/testSeqOfIndefinite.erl
+++ b/lib/asn1/test/testSeqOfIndefinite.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqOfTag.erl b/lib/asn1/test/testSeqOfTag.erl
index f66e29e91d..55f807199f 100644
--- a/lib/asn1/test/testSeqOfTag.erl
+++ b/lib/asn1/test/testSeqOfTag.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqOptional.erl b/lib/asn1/test/testSeqOptional.erl
index c9478105a4..db615d6e4d 100644
--- a/lib/asn1/test/testSeqOptional.erl
+++ b/lib/asn1/test/testSeqOptional.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqPrim.erl b/lib/asn1/test/testSeqPrim.erl
index 7f3ef86ac5..6af0ce9287 100644
--- a/lib/asn1/test/testSeqPrim.erl
+++ b/lib/asn1/test/testSeqPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl
index c3d9ce33b7..86ab07a4a8 100644
--- a/lib/asn1/test/testSeqSetDefaultVal.erl
+++ b/lib/asn1/test/testSeqSetDefaultVal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqSetIndefinite.erl b/lib/asn1/test/testSeqSetIndefinite.erl
index 6becf84e77..8948e10ece 100644
--- a/lib/asn1/test/testSeqSetIndefinite.erl
+++ b/lib/asn1/test/testSeqSetIndefinite.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqTag.erl b/lib/asn1/test/testSeqTag.erl
index 6bacca6808..baa79ed428 100644
--- a/lib/asn1/test/testSeqTag.erl
+++ b/lib/asn1/test/testSeqTag.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqTypeRefCho.erl b/lib/asn1/test/testSeqTypeRefCho.erl
index 1a921c6f38..372be0c637 100644
--- a/lib/asn1/test/testSeqTypeRefCho.erl
+++ b/lib/asn1/test/testSeqTypeRefCho.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqTypeRefPrim.erl b/lib/asn1/test/testSeqTypeRefPrim.erl
index d66d1ebcfe..42554e758e 100644
--- a/lib/asn1/test/testSeqTypeRefPrim.erl
+++ b/lib/asn1/test/testSeqTypeRefPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSeqTypeRefSeq.erl b/lib/asn1/test/testSeqTypeRefSeq.erl
index 3288511f0a..ee30937af5 100644
--- a/lib/asn1/test/testSeqTypeRefSeq.erl
+++ b/lib/asn1/test/testSeqTypeRefSeq.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSeqTypeRefSet.erl b/lib/asn1/test/testSeqTypeRefSet.erl
index d73423284b..ba690b4503 100644
--- a/lib/asn1/test/testSeqTypeRefSet.erl
+++ b/lib/asn1/test/testSeqTypeRefSet.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetDefault.erl b/lib/asn1/test/testSetDefault.erl
index 055dc6cecf..4e34c01a52 100644
--- a/lib/asn1/test/testSetDefault.erl
+++ b/lib/asn1/test/testSetDefault.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetExtension.erl b/lib/asn1/test/testSetExtension.erl
index 4e2463326b..67977a2a31 100644
--- a/lib/asn1/test/testSetExtension.erl
+++ b/lib/asn1/test/testSetExtension.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetExternal.erl b/lib/asn1/test/testSetExternal.erl
index 626adc5822..e265cf1f3e 100644
--- a/lib/asn1/test/testSetExternal.erl
+++ b/lib/asn1/test/testSetExternal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetOf.erl b/lib/asn1/test/testSetOf.erl
index 0f82a14625..4ff90676aa 100644
--- a/lib/asn1/test/testSetOf.erl
+++ b/lib/asn1/test/testSetOf.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSetOfCho.erl b/lib/asn1/test/testSetOfCho.erl
index 09c075e468..002fa9be0a 100644
--- a/lib/asn1/test/testSetOfCho.erl
+++ b/lib/asn1/test/testSetOfCho.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSetOfExternal.erl b/lib/asn1/test/testSetOfExternal.erl
index cc5fe10710..60bde33962 100644
--- a/lib/asn1/test/testSetOfExternal.erl
+++ b/lib/asn1/test/testSetOfExternal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSetOfTag.erl b/lib/asn1/test/testSetOfTag.erl
index 0d656f05a6..96dc9942d7 100644
--- a/lib/asn1/test/testSetOfTag.erl
+++ b/lib/asn1/test/testSetOfTag.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSetOptional.erl b/lib/asn1/test/testSetOptional.erl
index eb095fd480..a0010d203a 100644
--- a/lib/asn1/test/testSetOptional.erl
+++ b/lib/asn1/test/testSetOptional.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testSetPrim.erl b/lib/asn1/test/testSetPrim.erl
index f417f343a7..a4b8bb2f09 100644
--- a/lib/asn1/test/testSetPrim.erl
+++ b/lib/asn1/test/testSetPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetTag.erl b/lib/asn1/test/testSetTag.erl
index fa1d84f50d..b963ecb4b3 100644
--- a/lib/asn1/test/testSetTag.erl
+++ b/lib/asn1/test/testSetTag.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetTypeRefCho.erl b/lib/asn1/test/testSetTypeRefCho.erl
index 97bbd557e0..adffb646fb 100644
--- a/lib/asn1/test/testSetTypeRefCho.erl
+++ b/lib/asn1/test/testSetTypeRefCho.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetTypeRefPrim.erl b/lib/asn1/test/testSetTypeRefPrim.erl
index d441fb789d..e20b6c57ab 100644
--- a/lib/asn1/test/testSetTypeRefPrim.erl
+++ b/lib/asn1/test/testSetTypeRefPrim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetTypeRefSeq.erl b/lib/asn1/test/testSetTypeRefSeq.erl
index a2b5f5745e..0d2bd6b32d 100644
--- a/lib/asn1/test/testSetTypeRefSeq.erl
+++ b/lib/asn1/test/testSetTypeRefSeq.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testSetTypeRefSet.erl b/lib/asn1/test/testSetTypeRefSet.erl
index 80a6be58c9..85d9bf52cd 100644
--- a/lib/asn1/test/testSetTypeRefSet.erl
+++ b/lib/asn1/test/testSetTypeRefSet.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testTCAP.erl b/lib/asn1/test/testTCAP.erl
index 17511dc2b7..6c66d73feb 100644
--- a/lib/asn1/test/testTCAP.erl
+++ b/lib/asn1/test/testTCAP.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testTcapsystem.erl b/lib/asn1/test/testTcapsystem.erl
index fcc9e084e0..a050ceac61 100644
--- a/lib/asn1/test/testTcapsystem.erl
+++ b/lib/asn1/test/testTcapsystem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl
index 89bc2b463d..30e31796e2 100644
--- a/lib/asn1/test/testTimer.erl
+++ b/lib/asn1/test/testTimer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/testTypeValueNotation.erl b/lib/asn1/test/testTypeValueNotation.erl
index 2b5f3f74c1..e75cec04c9 100644
--- a/lib/asn1/test/testTypeValueNotation.erl
+++ b/lib/asn1/test/testTypeValueNotation.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/testUniqueObjectSets.erl b/lib/asn1/test/testUniqueObjectSets.erl
new file mode 100644
index 0000000000..fd82087916
--- /dev/null
+++ b/lib/asn1/test/testUniqueObjectSets.erl
@@ -0,0 +1,176 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(testUniqueObjectSets).
+-export([main/3]).
+
+%% Run-time function called by the generated code.
+seq_roundtrip(I, D0) ->
+ M = 'UniqueObjectSets',
+ try
+ {ok,Enc} = M:encode('Seq', {'Seq',I,D0}),
+ {ok,{'Seq',I,D}} = M:decode('Seq', Enc),
+ D
+ catch C:E ->
+ Stk = erlang:get_stacktrace(),
+ io:format("FAILED: ~p ~p\n", [I,D0]),
+ erlang:raise(C, E, Stk)
+ end.
+
+types() ->
+ [{"CHOICE { a INTEGER, b BIT STRING }", {b,<<42:3>>}},
+ {"INTEGER",42},
+ {"SEQUENCE {a OCTET STRING}",{'_',<<"abc">>}},
+ {"SEQUENCE {b BOOLEAN, ...}",{'_',true}},
+ {"SEQUENCE {b BOOLEAN, ..., s IA5String, ..., e ENUMERATED { x, y, z}}",
+ {'_',false,"string",y}},
+ {"SET {a BIT STRING}",{'_',<<1:17>>}},
+ {"SEQUENCE OF INTEGER",[-19,0,555,777]},
+ {"SET OF BOOLEAN",[true,false,true]},
+ {"SEQUENCE OF SEQUENCE {x INTEGER (0..7)}",[{'_',7},{'_',0}]},
+ {"SET OF SEQUENCE {x INTEGER (0..7)}",[{'_',7},{'_',0}]}
+ ].
+
+main(CaseDir, Rule, Opts) ->
+ D0 = types(),
+ {D1,_} = lists:mapfoldl(fun({T,S}, I) ->
+ {{I,T,S},I+1}
+ end, 1, D0),
+ Types = [gen_types(I, Type) || {I,Type,_} <- D1],
+ Set = [gen_set_items(I, T) || {I,T,_} <- D1],
+ Objs = [gen_obj(I) || {I,_,_} <- D1],
+ DupObjs = [gen_dup_obj(I, T) || {I,T,_} <- D1],
+ DupObjRefs0 = [gen_dup_obj_refs(I) || {I,_,_} <- D1],
+ DupObjRefs = string:join(DupObjRefs0, " |\n"),
+ Asn1Spec = 'UniqueObjectSets',
+ A = ["UniqueObjectSets DEFINITIONS AUTOMATIC TAGS ::=\n",
+ "BEGIN\n\n",
+ "TEST-UNIQUE ::= CLASS {\n"
+ " &id INTEGER UNIQUE,\n"
+ " &Type OPTIONAL\n"
+ "}\n"
+ "WITH SYNTAX {IDENTIFIED BY &id [TYPE &Type]}\n",
+ $\n,
+ "DUP-CONTAINER ::= CLASS {\n"
+ " &id INTEGER UNIQUE,\n"
+ " &data TEST-UNIQUE\n"
+ "} WITH SYNTAX {\n"
+ " ID &id, &data\n"
+ "}\n",
+ $\n,
+ Types,$\n,
+ "UniqSet TEST-UNIQUE ::= {\n",
+ Set,
+ " DupSet-1 |\n",
+ " DupSet-2, ...\n",
+ "}\n\n",
+ Objs,$\n,
+ DupObjs,$\n,
+ "DupSet-1 TEST-UNIQUE ::= {\n",
+ DupObjRefs,$\n,
+ "}\n\n",
+ "DupSet-2 TEST-UNIQUE ::= {\n",
+ DupObjRefs,",...\n",
+ "}\n\n",
+ "Seq ::= SEQUENCE {\n"
+ " id TEST-UNIQUE.&id ({UniqSet}),\n"
+ " type TEST-UNIQUE.&Type ({UniqSet}{@id})\n"
+ "}\n"
+ "END\n"],
+ Asn1File = filename:join(CaseDir, atom_to_list(Asn1Spec)++".asn1"),
+ ok = file:write_file(Asn1File, A),
+
+ TestModule = 'unique_object_sets',
+ Test0 = [gen_test(I, Data) || {I,_,Data} <- D1],
+ Test = ["-module(",atom_to_list(TestModule),").\n"
+ "-export([main/1]).\n"
+ "\n"
+ "main(SeqRoundtrip) ->\n",
+ " ",atom_to_list(Rule)," = '",atom_to_list(Asn1Spec),
+ "':encoding_rule(),\n",
+ Test0,
+ " ok.\n"
+ ],
+ ErlFile = filename:join(CaseDir, atom_to_list(TestModule)++".erl"),
+ ok = file:write_file(ErlFile, Test),
+
+ io:format("~s\n~s\n", [Asn1File,ErlFile]),
+ case Rule of
+ per ->
+ io:put_chars([A,$\n,Test,$\n]);
+ _ ->
+ ok
+ end,
+
+ ok = asn1ct:compile(Asn1File, [Rule,{outdir,CaseDir}|Opts]),
+ {ok,TestModule} = c:c(ErlFile, [{outdir,CaseDir}]),
+ TestModule:main(fun seq_roundtrip/2),
+ ok.
+
+gen_types(I, Type) ->
+ io_lib:format("AType~p ::= ~s\n", [I,Type]).
+
+gen_set_items(I, T) ->
+ io_lib:format(" {IDENTIFIED BY ~p TYPE AType~p} |\n"
+ " {IDENTIFIED BY ~p TYPE AType~p} |\n"
+ " {IDENTIFIED BY ~p TYPE ~s} |\n"
+ " obj-~p |\n\n",
+ [I,I,I,I,I,T,I]).
+
+gen_obj(I) ->
+ io_lib:format("obj-~p TEST-UNIQUE ::= {IDENTIFIED BY ~p TYPE AType~p}\n",
+ [I,I,I]).
+
+gen_dup_obj(I, T) ->
+ io_lib:format("dup-obj-~p DUP-CONTAINER ::= "
+ "{ID ~p, {IDENTIFIED BY ~p TYPE ~s}}\n",
+ [I,I,I+1000,T]).
+
+gen_dup_obj_refs(I) ->
+ io_lib:format("dup-obj-~p.&data", [I]).
+
+gen_test(I, Data) ->
+ io_lib:format(" ~s = SeqRoundtrip(~p, ~p),\n",
+ [match_term(Data),I,Data]).
+
+match_term('_') ->
+ "_";
+match_term([H|T]=L) ->
+ case is_intlist(L) of
+ true ->
+ io_lib:format("~p", [L]);
+ false ->
+ ["[",match_term(H),"|",match_term(T),"]"]
+ end;
+match_term(Tuple) when is_tuple(Tuple) ->
+ ["{",match_term_tuple(Tuple, 1),"}"];
+match_term(Other) ->
+ io_lib:format("~p", [Other]).
+
+match_term_tuple(T, I) when I =< tuple_size(T) ->
+ [match_term(element(I, T)),
+ if I < tuple_size(T) -> ",";
+ true -> "" end|match_term_tuple(T, I+1)];
+match_term_tuple(_, _) ->
+ [].
+
+is_intlist(L) ->
+ lists:all(fun is_integer/1, L).
diff --git a/lib/asn1/test/testValueTest.erl b/lib/asn1/test/testValueTest.erl
new file mode 100644
index 0000000000..1764323e93
--- /dev/null
+++ b/lib/asn1/test/testValueTest.erl
@@ -0,0 +1,115 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(testValueTest).
+
+-export([main/0]).
+
+main() ->
+ M = 'ValueTest',
+
+ %% Basic types
+ 12 = M:'vANY'(),
+ true = M:'vBOOLEAN'(),
+ 12 = M:'vINTEGER'(),
+ 0 = M:'vINTEGERNNL'(),
+ button1 = M:'vENUMERATED'(),
+ [zero,two] = M:'vBS'(),
+ 'NULL' = M:'vNULL'(),
+ <<16#31,16#32,16#33>> = M:'vOS'(),
+
+ %% OID
+ {2,1,1} = M:'vOD'(),
+ {1,2} = M:'integer-first'(),
+ {2,4,5} = M:'rel-oid-1'(),
+ {0,2,4,5} = M:'include-roid'(),
+ {1,2,1} = M:'include-oid'(),
+ {1,2,1,2,4,5,42} = M:'include-all'(),
+
+ %% Character strings
+ "01234567" = M:'numericstring'(),
+ "PrintableString" = M:'printablestring'(),
+ "VisibleString" = M:'visiblestring'(),
+ [0,13] = M:'cr'(),
+ ["First line",[0,13],"Second line"] = M:'ia5string1'(),
+ [[5,5],[4,4],[6,6]] = M:'ia5string2'(),
+ "TeletexString" = M:'teletexstring'(),
+ "VideotexString" = M:'videotexstring'(),
+ "97100211-0500" = M:'utctime'(),
+ "19971002103130.5" = M:'generalizedtime'(),
+ "ObjectDescriptor" = M:'objectdescriptor'(),
+ "GraphicString" = M:'graphicstring'(),
+ "GeneralString" = M:'generalstring'(),
+ "BMPString" = M:'bmpstring1'(),
+ [0,0,0,65] = M:'latinCapitalLetterA'(),
+ [0,0,3,145] = M:'greekCapitalLetterSigma'(),
+ ["This is a capital A: ",
+ [0,0,0,65],
+ ", and a capital sigma: ",
+ [0,0,3,145],
+ "; try and spot the difference!"] = M:'my-universalstring'(),
+
+ %% Integers
+ 42 = M:someInteger(),
+ 42 = M:otherInteger(),
+ {'IntegerSeq',42} = M:integerSeq1(),
+
+ %% Value from object
+ 2 = M:'int-from-object-1'(),
+ 4 = M:'int-from-object-2'(),
+ roundtrip_error('II', 1),
+ roundtrip('II', 2),
+ roundtrip('II', 3),
+ roundtrip('II', 4),
+ roundtrip_error('II', 5),
+
+ %% Recursive value definitions.
+ {'OctetStringSeq',<<16#40,16#41,16#42>>} = M:octetStringSeq1(),
+ <<16#40,16#41,16#42>> = M:otherOctetString(),
+ <<16#40,16#41,16#42>> = M:someOctetString(),
+ {'OctetStringSeq',<<16#40,16#41,16#42>>} = M:octetStringSeq2(),
+ {'OctetStringSeq',<<16#40,16#41,16#FF>>} = M:octetStringSeq3(),
+ <<16#40,16#41,16#FF>> = M:'os-1'(),
+ <<16#40,16#41,16#FF>> = M:'os-2'(),
+
+ %% Recursive BIT STRING definitions.
+ {'BsSeq',<<2#101101:6>>,[c]} = M:bsSeq1(),
+ {'BsSeq',<<2#101101:6>>,[c]} = M:bsSeq2(),
+ {'BsSeq',<<2#101:3>>,[a,c]} = M:bsSeq3(),
+ <<2#101101:6>> = M:someBitString(),
+ <<2#101101:6>> = M:otherBitString(),
+ <<2#101:3>> = M:bsFromObject(),
+ <<2#101:3>> = M:bsFromObjectInd(),
+ [c] = M:someNamedBs(),
+ [c] = M:someOtherNamedBs(),
+
+ ok.
+
+
+roundtrip(T, V) ->
+ asn1_test_lib:roundtrip('ValueTest', T, V).
+
+roundtrip_error(T, V) ->
+ try asn1_test_lib:roundtrip('ValueTest', T, V) of
+ ok ->
+ test_server:fail()
+ catch _:_ ->
+ ok
+ end.
diff --git a/lib/asn1/test/testX420.erl b/lib/asn1/test/testX420.erl
deleted file mode 100644
index 4ddc55dc16..0000000000
--- a/lib/asn1/test/testX420.erl
+++ /dev/null
@@ -1,93 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-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%
-%%
-%%
-%%-------------------------------------------------------------------
-
--module(testX420).
-
--export([compile/3, ticket7759/2]).
-
--include_lib("test_server/include/test_server.hrl").
-
-
-compile(Erule, Options, Config) ->
- Specs0 = specs(),
- 99 = length(Specs0),
- CaseDir = ?config(case_dir, Config),
- Specs = [filename:join(x420, Spec) || Spec <- Specs0],
- asn1_test_lib:compile_all(Specs, Config, [Erule,{i,CaseDir}|Options]).
-
-specs() ->
- ["ACSE-1", "AuthenticationFramework", "BasicAccessControl",
- "CertificateExtensions", "Character-Coding-Attributes",
- "Character-Presentation-Attributes", "Character-Profile-Attributes",
- "Colour-Attributes", "DOR-definition", "DSAOperationalAttributeTypes",
- "Default-Value-Lists", "DirectoryAbstractService",
- "DirectoryAccessProtocol", "DirectoryInformationShadowProtocol",
- "DirectoryOperationalBindingManagementProtocol",
- "DirectoryOperationalBindingTypes", "DirectoryProtectionMappings",
- "DirectoryShadowAbstractService", "DirectorySystemProtocol",
- "DistributedOperations", "Document-Profile-Descriptor",
- "EnhancedSecurity", "External-References", "GULSProtectionMappings",
- "GenericProtectingTransferSyntax", "Geo-Gr-Coding-Attributes",
- "Geo-Gr-Presentation-Attributes", "Geo-Gr-Profile-Attributes",
- "GulsSecurityExchanges", "GulsSecurityTransformations",
- "HierarchicalOperationalBindings", "IPMSAbstractService",
- "IPMSAutoActionTypes", "IPMSExtendedBodyPartTypes",
- "IPMSExtendedBodyPartTypes2", "IPMSExtendedVoiceBodyPartType",
- "IPMSFileTransferBodyPartType", "IPMSForwardedContentBodyPartType",
- "IPMSForwardedReportBodyPartType", "IPMSFunctionalObjects",
- "IPMSHeadingExtensions", "IPMSInformationObjects",
- "IPMSMessageStoreAttributes", "IPMSObjectIdentifiers",
- "IPMSObjectIdentifiers2", "IPMSSecurityExtensions", "IPMSUpperBounds",
- "ISO-STANDARD-9541-FONT-ATTRIBUTE-SET", "ISO8571-FTAM", "ISO9541-SN",
- "Identifiers-and-Expressions", "InformationFramework",
- "Interchange-Data-Elements", "Layout-Descriptors", "Link-Descriptors",
- "Location-Expressions", "Logical-Descriptors", "MHSObjectIdentifiers",
- "MHSProtocolObjectIdentifiers", "MSAbstractService",
- "MSAccessProtocol", "MSGeneralAttributeTypes",
- "MSGeneralAutoActionTypes", "MSMatchingRules", "MSObjectIdentifiers",
- "MSUpperBounds", "MTAAbstractService", "MTSAbstractService",
- "MTSAbstractService88", "MTSAccessProtocol", "MTSObjectIdentifiers",
- "MTSUpperBounds", "Notation", "ObjectIdentifiers",
- "OperationalBindingManagement", "PKCS7", "PKCS7BodyPartType",
- "Protected-Part-Descriptors", "ProtocolObjectIdentifiers",
- "Raster-Gr-Coding-Attributes", "Raster-Gr-Presentation-Attributes",
- "Raster-Gr-Profile-Attributes", "Reliable-Transfer-APDU",
- "Remote-Operations-Abstract-Syntaxes",
- "Remote-Operations-Generic-ROS-PDUs",
- "Remote-Operations-Information-Objects-extensions",
- "Remote-Operations-Information-Objects",
- "Remote-Operations-Realizations",
- "Remote-Operations-Useful-Definitions", "SelectedAttributeTypes",
- "SeseAPDUs", "SpkmGssTokens", "Style-Descriptors", "Subprofiles",
- "Temporal-Relationships", "Text-Units", "UpperBounds",
- "UsefulDefinitions", "Videotex-Coding-Attributes"].
-
-ticket7759(_Erule,_Config) ->
- Encoded = encoded_msg(),
- io:format("Testing ticket7759 ...~n",[]),
- {ok, ContentInfo} = 'PKCS7':decode('ContentInfo',Encoded),
- {'ContentInfo',_Id,PKCS7_content} = ContentInfo,
- {ok,_} = 'PKCS7':decode('SignedData',PKCS7_content),
- ok.
-
-
-encoded_msg() ->
- <<48,128,6,9,42,134,72,134,247,13,1,7,2,160,128,48,128,2,1,1,49,11,48,9,6,5,43,14,3,2,26,5,0,48,128,6,9,42,134,72,134,247,13,1,7,1,160,128,36,128,0,0,0,0,0,0, 49,130,1,192,48,130,1,188,2,1,1,48,50,48,38,49,17,48,15,6,3,85,4,3,12,8,65,100,109,105,110,67,65,49,49,17,48,15,6,3,85,4,10,12,8,69,82,73,67,83,83,79,78,2,8,15,151,245,186,21,23,240,96,48,9,6,5,43,14,3,2,26,5,0,160,129,229,48,17,6,10,96,134,72,1,134,248,69,1,9,2,49,3,19,1,51,48,17,6,10,96,134,72,1,134,248,69,1,9,3,49,3,19,1,51,48,24,6,9,42,134,72,134,247,13,1,9,3,49,11,6,9,42,134,72,134,247,13,1,7,1,48,28,6,9,42,134,72,134,247,13,1,9,5,49,15,23,13,48,56,49,50,49,48,48,57,53,52,50,51,90,48,28,6,10,96,134,72,1,134,248,69,1,9,7,49,14,19,12,49,53,50,56,49,52,50,52,48,57,53,53,48,32,6,10,96,134,72,1,134,248,69,1,9,5,49,18,4,16,165,115,177,71,78,88,239,113,78,56,98,98,18,202,217,235,48,32,6,10,96,134,72,1,134,248,69,1,9,6,49,18,4,16,227,174,230,251,43,153,252,65,11,93,231,83,34,18,55,46,48,35,6,9,42,134,72,134,247,13,1,9,4,49,22,4,20,218,57,163,238,94,107,75,13,50,85,191,239,149,96,24,144,175,216,7,9,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,4,129,128,106,233,116,125,140,51,133,173,63,41,54,138,214,211,89,215,169,125,98,77,16,222,216,240,211,79,125,111,87,186,73,63,253,204,107,102,177,63,174,197,224,212,231,172,149,246,33,68,223,67,102,93,64,152,152,5,216,102,247,134,36,197,150,236,57,77,56,138,95,71,204,31,23,149,241,213,78,172,165,249,100,187,12,45,19,57,67,120,54,63,15,239,41,217,127,61,254,60,201,104,68,3,135,214,206,93,253,255,192,94,56,107,68,210,57,61,41,249,47,156,130,244,52,12,163,216,236,69,0,0,0,0,0,0>>.
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
index 7f358e863c..8be3a29763 100644
--- a/lib/asn1/test/test_compile_options.erl
+++ b/lib/asn1/test/test_compile_options.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,7 +25,7 @@
-export([wrong_path/1,comp/2,path/1,ticket_6143/1,noobj/1,
- record_name_prefix/1,verbose/1,warnings_as_errors/1]).
+ record_name_prefix/1,verbose/1]).
%% OTP-5689
wrong_path(Config) ->
@@ -132,43 +133,6 @@ verbose(Config) when is_list(Config) ->
?line [] = test_server:capture_get(),
ok.
-warnings_as_errors(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir,Config),
- Asn1File = filename:join([PrivDir,"WERROR.asn1"]),
- OutFile = filename:join([PrivDir,"WERROR.erl"]),
- Opts = [{outdir,PrivDir},noobj,verbose],
-
- %% Generate WERR.asn to emit warning
- %% Warning: Wrong format of type/value
- %% false/{'Externalvaluereference',_,'WERR',noInvokeId}
- Warn = <<"WERROR DEFINITIONS IMPLICIT TAGS ::=\n"
- "\n"
- "BEGIN\n"
- "\n"
- "InvokeId ::= CHOICE\n"
- "{\n"
- " present INTEGER,\n"
- " absent NULL\n"
- "}\n"
- "\n"
- "noInvokeId InvokeId ::= absent:NULL\n"
- "\n"
- "NoInvokeId InvokeId ::= {noInvokeId}\n"
- "\n"
- "END -- end of useful definitions.\n">>,
- ?line ok = file:write_file(Asn1File, Warn),
-
- %% Test warnings_as_errors compile
- ?line false = filelib:is_regular(OutFile),
- ?line {error, _} = asn1ct:compile(Asn1File, [warnings_as_errors|Opts]),
- ?line false = filelib:is_regular(OutFile),
-
- %% Test normal compile
- ?line ok = asn1ct:compile(Asn1File, Opts),
- ?line true = filelib:is_regular(OutFile),
- ?line ok = file:delete(OutFile),
- ok.
-
outfiles_check(OutDir) ->
outfiles_check(OutDir,outfiles1()).
diff --git a/lib/asn1/test/test_modified_x420.erl b/lib/asn1/test/test_modified_x420.erl
index 0df72a1831..f9a29d1436 100644
--- a/lib/asn1/test/test_modified_x420.erl
+++ b/lib/asn1/test/test_modified_x420.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/asn1/test/test_partial_incomplete_decode.erl b/lib/asn1/test/test_partial_incomplete_decode.erl
index 4a8a4cd74c..d5eacc5a4d 100644
--- a/lib/asn1/test/test_partial_incomplete_decode.erl
+++ b/lib/asn1/test/test_partial_incomplete_decode.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/test_selective_decode.erl b/lib/asn1/test/test_selective_decode.erl
index f42f24e0e3..079351db19 100644
--- a/lib/asn1/test/test_selective_decode.erl
+++ b/lib/asn1/test/test_selective_decode.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/test_special_decode_performance.erl b/lib/asn1/test/test_special_decode_performance.erl
index 0f52ae4cd2..7bb324c902 100644
--- a/lib/asn1/test/test_special_decode_performance.erl
+++ b/lib/asn1/test/test_special_decode_performance.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/test_undecoded_rest.erl b/lib/asn1/test/test_undecoded_rest.erl
index 91e614d38a..6264530fff 100644
--- a/lib/asn1/test/test_undecoded_rest.erl
+++ b/lib/asn1/test/test_undecoded_rest.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/test/test_x691.erl b/lib/asn1/test/test_x691.erl
index 9b141e2389..56c1b9bf71 100644
--- a/lib/asn1/test/test_x691.erl
+++ b/lib/asn1/test/test_x691.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index d1c364c34a..ab2c127ca2 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1,2 +1 @@
-#next version number to use is 2.0
-ASN1_VSN = 3.0.4
+ASN1_VSN = 4.0.2
diff --git a/lib/common_test/Makefile b/lib/common_test/Makefile
index aecec1a50d..d47d60d1e4 100644
--- a/lib/common_test/Makefile
+++ b/lib/common_test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile
index 57233a7f6c..a0c89b1222 100644
--- a/lib/common_test/doc/src/Makefile
+++ b/lib/common_test/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -35,26 +36,24 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# Target Specs
# ----------------------------------------------------
-# REMEMBER: links to HTML files for these modules in ref_man.xml
-CT_MODULES = \
- ct \
- ct_master \
- ct_cover \
- ct_telnet \
- ct_ftp \
- ct_ssh \
- ct_rpc \
- ct_snmp \
- unix_telnet \
- ct_slave \
- ct_property_test \
- ct_netconfc
-
CT_XML_FILES = $(CT_MODULES:=.xml)
XML_APPLICATION_FILES = ref_man.xml
XML_REF1_FILES = ct_run.xml
-XML_REF3_FILES = $(CT_XML_FILES) ct_hooks.xml
+# REMEMBER: links to HTML files for these modules in ref_man.xml
+XML_REF3_FILES = ct.xml \
+ ct_master.xml \
+ ct_cover.xml \
+ ct_telnet.xml \
+ ct_ftp.xml \
+ ct_ssh.xml \
+ ct_rpc.xml \
+ ct_snmp.xml \
+ unix_telnet.xml \
+ ct_slave.xml \
+ ct_property_test.xml \
+ ct_netconfc.xml \
+ ct_hooks.xml
XML_REF6_FILES = common_test_app.xml
XML_PART_FILES = part.xml
@@ -79,8 +78,6 @@ XML_CHAPTER_FILES = \
notes.xml \
notes_history.xml
-MAKE_EDOC = make_edoc
-
BOOK_FILES = book.xml
GIF_FILES = \
@@ -91,7 +88,7 @@ GIF_FILES = \
INSTALL_NOTES = ../../notes.html
XML_FILES=$(XML_APPLICATION_FILES) $(XML_REF1_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
- $(XML_PART_FILES) $(XML_CHAPTER_FILES) $(XML_REF_FILES) $(BOOK_FILES)
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES) $(BOOK_FILES)
# ----------------------------------------------------
@@ -118,19 +115,11 @@ DVIPS_FLAGS +=
# Targets
# ----------------------------------------------------
-CT_SRC_DIR = $(ERL_TOP)/../internal_tools/common_test/src
-
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
docs: pdf html man
-$(CT_XML_FILES): %.xml: ../../src/%.erl
- escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -preprocess true -i $(XMERL_DIR)/include \
- -i ../../../test_server/include -i ../../include \
- -i ../../../../erts/lib/kernel/include -i ../../../../lib/kernel/include \
- -i ../../../../erts/lib/snmp/include -i ../../../../lib/snmp/include ../../src/$(@:%.xml=%.erl)
-
$(TOP_PDF_FILE): $(XML_FILES)
pdf: $(TOP_PDF_FILE)
@@ -145,7 +134,6 @@ man: $(MAN6_FILES) $(MAN3_FILES) $(MAN1_FILES)
debug opt:
clean clean_docs:
- rm -f $(CT_XML_FILES)
rm -rf $(HTMLDIR)/*
rm -f $(MAN1DIR)/*
rm -f $(MAN3DIR)/*
diff --git a/lib/common_test/doc/src/basics_chapter.xml b/lib/common_test/doc/src/basics_chapter.xml
index 12c6143a1a..1a5a686fa0 100644
--- a/lib/common_test/doc/src/basics_chapter.xml
+++ b/lib/common_test/doc/src/basics_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,74 +31,74 @@
</header>
<marker id="basics"></marker>
<section>
- <title>Introduction</title>
+ <title>General</title>
- <p>The <em>Common Test</em> framework (CT) is a tool which supports
- implementation and automated execution of test cases towards arbitrary
- types of target systems. The CT framework is based on the OTP Test
- Server and it's the main tool being used in all testing- and verification
- activities that are part of Erlang/OTP system development- and maintenance.
+ <p>The <c>Common Test</c> framework is a tool that supports
+ implementation and automated execution of test cases to any
+ types of target systems. <c>Common Test</c> is the main tool being used
+ in all testing- and verification activities that are part of Erlang/OTP
+ system development and maintenance.
</p>
- <p>Test cases can be executed individually or in batches. Common Test
- also features a distributed testing mode with central control and logging
- (a feature that makes it possible to test multiple systems independently in
- one common session, useful e.g. for running automated large-scale regression
- tests).
+ <p>Test cases can be executed individually or in batches. <c>Common Test</c>
+ also features a distributed testing mode with central control and logging.
+ With this feature, multiple systems can be tested independently in
+ one common session. This is useful, for example, when running automated
+ large-scale regression tests.
</p>
<p>
- The SUT (System Under Test) may consist of one or several target
- nodes. CT contains a generic test server which, together with
- other test utilities, is used to perform test case execution.
- It is possible to start the tests from a GUI or from the OS- or
+ The System Under Test (SUT) can consist of one or more target
+ nodes. <c>Common Test</c> contains a generic test server that,
+ together with other test utilities, is used to perform test case execution.
+ The tests can be started from a GUI, from the OS shell, or from an
Erlang shell. <em>Test suites</em> are files (Erlang
modules) that contain the <em>test cases</em> (Erlang functions)
to be executed. <em>Support modules</em> provide functions
- that the test cases utilize in order to carry out the tests.
+ that the test cases use to do the tests.
</p>
- <p>In a black-box testing scenario, CT based test programs connect to
- the target system(s) via standard O&amp;M and CLI protocols. CT
+ <p>In a black-box testing scenario, <c>Common Test</c>-based test programs connect to
+ the target system(s) through standard O&amp;M and CLI protocols. <c>Common Test</c>
provides implementations of, and wrapper interfaces to, some of these
- protocols (most of which exist as stand-alone components and
+ protocols (most of which exist as standalone components and
applications in OTP). The wrappers simplify configuration and add
- verbosity for logging purposes. CT will be continously extended with
- useful support modules. (Note however that it's
- a straightforward task to use any arbitrary Erlang/OTP component
- for testing purposes with Common Test, without needing a CT wrapper
- for it. It's as simple as calling Erlang functions). There
- are a number of target independent interfaces supported in CT, such as
- Generic Telnet, FTP, etc, which can be specialized or used
- directly for controlling instruments, traffic load generators, etc.
+ verbosity for logging purposes. <c>Common Test</c> is continously extended with
+ useful support modules. However, notice that it is
+ a straightforward task to use any Erlang/OTP component
+ for testing purposes with <c>Common Test</c>, without needing a <c>Common Test</c>
+ wrapper for it. It is as simple as calling Erlang functions. A number of
+ target-independent interfaces are supported in <c>Common Test</c>, such as
+ Generic Telnet and FTP. These can be specialized or used
+ directly for controlling instruments, traffic load generators, and so on.
</p>
- <p>Common Test is also a very useful tool for white-box testing Erlang
- code (e.g. module testing), since the test programs can call exported Erlang
- functions directly and there's very little overhead required for
+ <p><c>Common Test</c> is also a very useful tool for white-box testing Erlang
+ code (for example, module testing), as the test programs can call exported Erlang
+ functions directly. there is very little overhead required for
implementing basic test suites and executing simple tests. For black-box
- testing Erlang software, Erlang RPC as well as standard O&amp;M interfaces
- can for example be used.
+ testing Erlang software, Erlang RPC and standard O&amp;M interfaces
+ can be used for example.
</p>
- <p>A test case can handle several connections towards one or
- several target systems, instruments and traffic generators in
- parallel in order to perform the necessary actions for a
- test. The handling of many connections in parallel is one of
- the major strengths of Common Test (thanks to the efficient
- support for concurrency in the Erlang runtime system - which CT users
- can take great advantage of!).
+ <p>A test case can handle several connections to one or
+ more target systems, instruments, and traffic generators in
+ parallel to perform the necessary actions for a test.
+ The handling of many connections in parallel is one of
+ the major strengths of <c>Common Test</c>, thanks to the efficient
+ support for concurrency in the Erlang runtime system, which <c>Common Test</c>
+ users can take great advantage of.
</p>
</section>
<section>
<title>Test Suite Organisation</title>
<p>
- The test suites are organized in test directories and each test suite
- may have a separate data directory. Typically, these files and directories
- are version controlled similarly to other forms of source code (possibly by
- means of a version control system like GIT or Subversion). However, CT does
- not itself put any requirements on (or has any form of awareness of)
+ Test suites are organized in test directories and each test suite
+ can have a separate data directory. Typically, these files and directories
+ are version-controlled similar to other forms of source code (possibly by
+ a version control system like GIT or Subversion). However, <c>Common Test</c>
+ does not itself put any requirements on (or has any awareness of)
possible file and directory versions.
</p>
</section>
@@ -108,8 +109,8 @@
Support libraries contain functions that are useful for all test suites,
or for test suites in a specific functional area or subsystem.
In addition to the general support libraries provided by the
- CT framework, and the various libraries and applications provided by
- Erlang/OTP, there might also be a need for customized (user specific)
+ <c>Common Test</c> framework, and the various libraries and applications provided by
+ Erlang/OTP, there can also be a need for customized (user specific)
support libraries.
</p>
</section>
@@ -120,118 +121,122 @@
Testing is performed by running test suites (sets of test cases) or
individual test cases. A test suite is implemented as an Erlang module named
<c><![CDATA[<suite_name>_SUITE.erl]]></c> which contains a number of test cases.
- A test case is an Erlang function which tests one or more things.
- The test case is the smallest unit that the CT test server deals with.
+ A test case is an Erlang function that tests one or more things.
+ The test case is the smallest unit that the <c>Common Test</c> test server deals with.
</p>
<p>
- Subsets of test cases, called test case groups, may also be defined. A test case
+ Subsets of test cases, called test case groups, can also be defined. A test case
group can have execution properties associated with it. Execution properties
- specify whether the test cases in the group should be executed in
- random order, in parallel, in sequence, and if the execution of the group
- should be repeated. Test case groups may also be nested (i.e. a group may,
- besides test cases, contain sub-groups).
+ specify if the test cases in the group are to be executed in
+ random order, in parallel, or in sequence, and if the execution of the group
+ is to be repeated. Test case groups can also be nested (that is, a group can,
+ besides test cases, contain subgroups).
</p>
<p>
- Besides test cases and groups, the test suite may also contain configuration
+ Besides test cases and groups, the test suite can also contain configuration
functions. These functions are meant to be used for setting up (and verifying)
- environment and state on the SUT (and/or the CT host node), required for
- the tests to execute correctly. Examples of operations: Opening a connection
- to the SUT, initializing a database, running an installation script, etc.
- Configuration may be performed per suite, per test case group and per
- individual test case.
+ environment and state in the SUT (and/or the <c>Common Test</c> host node),
+ required for the tests to execute correctly. Examples of operations are:
+ Opening a connection to the SUT, initializing a database, running an installation
+ script, and so on. Configuration can be performed per suite, per test case group,
+ and per individual test case.
</p>
<p>
The test suite module must conform to a
<seealso marker="common_test">callback interface</seealso>
- specified by the CT test server. See the
- <seealso marker="write_test_chapter#intro">Writing Test Suites</seealso> chapter
- for more information.
+ specified by the <c>Common Test</c> test server. For details, see section
+ <seealso marker="write_test_chapter#intro">Writing Test Suites</seealso>.
</p>
<p>
A test case is considered successful if it returns to the caller, no matter
- what the returned value is. A few return values have special meaning however
- (such as <c>{skip,Reason}</c> which indicates that the test case is skipped,
- <c>{comment,Comment}</c> which prints a comment in the log for the test case and
- <c>{save_config,Config}</c> which makes the CT test server pass <c>Config</c> to
- the next test case).
+ what the returned value is. However, a few return values have special meaning
+ as follows:</p>
+ <list type="bulleted">
+ <item><c>{skip,Reason}</c> indicates that the test case is skipped.</item>
+ <item><c>{comment,Comment}</c> prints a comment in the log for the test case.</item>
+ <item><c>{save_config,Config}</c> makes the <c>Common Test</c> test server pass
+ <c>Config</c> to the next test case.</item>
+ </list>
+ <p>
A test case failure is specified as a runtime error (a crash), no matter what
the reason for termination is. If you use Erlang pattern matching effectively,
- you can take advantage of this property. The result will be concise and
+ you can take advantage of this property. The result is concise and
readable test case functions that look much more like scripts than actual programs.
- Simple example:
+ A simple example:
</p>
<pre>
- session(_Config) ->
- {started,ServerId} = my_server:start(),
- {clients,[]} = my_server:get_clients(ServerId),
- MyId = self(),
- connected = my_server:connect(ServerId, MyId),
- {clients,[MyId]} = my_server:get_clients(ServerId),
- disconnected = my_server:disconnect(ServerId, MyId),
- {clients,[]} = my_server:get_clients(ServerId),
- stopped = my_server:stop(ServerId).
- </pre>
+ session(_Config) ->
+ {started,ServerId} = my_server:start(),
+ {clients,[]} = my_server:get_clients(ServerId),
+ MyId = self(),
+ connected = my_server:connect(ServerId, MyId),
+ {clients,[MyId]} = my_server:get_clients(ServerId),
+ disconnected = my_server:disconnect(ServerId, MyId),
+ {clients,[]} = my_server:get_clients(ServerId),
+ stopped = my_server:stop(ServerId).</pre>
<p>
As a test suite runs, all information (including output to <c>stdout</c>) is
- recorded in several different log files. A minimum of information is displayed
+ recorded in many different log files. A minimum of information is displayed
in the user console (only start and stop information, plus a note
for each failed test case).
</p>
<p>
The result from each test case is recorded in a dedicated HTML log file, created
for the particular test run. An overview page displays each test case represented
- by row in a table showing total execution time, whether the case was successful,
- failed or skipped, plus an optional user comment. (For a failed test case, the
- reason for termination is also printed in the comment field). The overview page
+ by a table row showing total execution time, if the case was successful,
+ failed, or skipped, plus an optional user comment. For a failed test case, the
+ reason for termination is also printed in the comment field. The overview page
has a link to each test case log file, providing simple navigation with any standard
HTML browser.
</p>
</section>
<section>
+<marker id="External_Interfaces"></marker>
<title>External Interfaces</title>
<p>
- The CT test server requires that the test suite defines and exports the
+ The <c>Common Test</c> test server requires that the test suite defines and exports the
following mandatory or optional callback functions:
</p>
<taglist>
- <tag>all()</tag>
- <item>Returns a list of all test cases and groups in the suite. (Mandatory)</item>
- <tag>suite()</tag>
- <item>Info function used to return properties for the suite. (Optional)</item>
- <tag>groups()</tag>
- <item>For declaring test case groups. (Optional)</item>
- <tag>init_per_suite(Config)</tag>
- <item>Suite level configuration function, executed before the first
- test case. (Optional)</item>
- <tag>end_per_suite(Config)</tag>
- <item>Suite level configuration function, executed after the last
- test case. (Optional)</item>
- <tag>group(GroupName)</tag>
- <item>Info function used to return properties for a test case group. (Optional)</item>
- <tag>init_per_group(GroupName, Config)</tag>
- <item>Configuration function for a group, executed before the first
- test case. (Optional)</item>
- <tag>end_per_group(GroupName, Config)</tag>
- <item>Configuration function for a group, executed after the last
- test case. (Optional)</item>
- <tag>init_per_testcase(TestCase, Config)</tag>
- <item>Configuration function for a testcase, executed before each
- test case. (Optional)</item>
- <tag>end_per_testcase(TestCase, Config)</tag>
- <item>Configuration function for a testcase, executed after each
- test case. (Optional)</item>
+ <tag><c>all()</c></tag>
+ <item><p>Returns a list of all test cases and groups in the suite. (Mandatory)</p></item>
+ <tag><c>suite()</c></tag>
+ <item><p>Information function used to return properties for the suite. (Optional)</p></item>
+ <tag><c>groups()</c></tag>
+ <item><p>For declaring test case groups. (Optional)</p></item>
+ <tag><c>init_per_suite(Config)</c></tag>
+ <item><p>Suite level configuration function, executed before the first
+ test case. (Optional)</p></item>
+ <tag><c>end_per_suite(Config)</c></tag>
+ <item><p>Suite level configuration function, executed after the last
+ test case. (Optional)</p></item>
+ <tag><c>group(GroupName)</c></tag>
+ <item><p>Information function used to return properties for a test case group. (Optional)</p></item>
+ <tag><c>init_per_group(GroupName, Config)</c></tag>
+ <item><p>Configuration function for a group, executed before the first
+ test case. (Optional)</p></item>
+ <tag><c>end_per_group(GroupName, Config)</c></tag>
+ <item><p>Configuration function for a group, executed after the last
+ test case. (Optional)</p></item>
+ <tag><c>init_per_testcase(TestCase, Config)</c></tag>
+ <item><p>Configuration function for a testcase, executed before each
+ test case. (Optional)</p></item>
+ <tag><c>end_per_testcase(TestCase, Config)</c></tag>
+ <item><p>Configuration function for a testcase, executed after each
+ test case. (Optional)</p></item>
</taglist>
<p>
- For each test case the CT test server expects these functions:
+ For each test case, the <c>Common Test</c> test server expects the
+ following functions:
</p>
<taglist>
<tag>Testcasename()</tag>
- <item>Info function that returns a list of test case properties. (Optional)</item>
+ <item><p>Information function that returns a list of test case properties. (Optional)</p></item>
<tag>Testcasename(Config)</tag>
- <item>The actual test case function.</item>
+ <item><p>The test case function.</p></item>
</taglist>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/book.xml b/lib/common_test/doc/src/book.xml
index f3f28999d7..7fe5331aba 100644
--- a/lib/common_test/doc/src/book.xml
+++ b/lib/common_test/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml
index ea4522c40b..10c93e2ed1 100644
--- a/lib/common_test/doc/src/common_test_app.xml
+++ b/lib/common_test/doc/src/common_test_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,89 +33,84 @@
<file>common_test_app.sgml</file>
</header>
<module>common_test</module>
- <modulesummary>A framework for automated testing of arbitrary target nodes</modulesummary>
+ <modulesummary>A framework for automated testing of any target nodes.</modulesummary>
<description>
- <p>The <em>Common Test</em> framework is an environment for
+ <p>The <c>Common Test</c> framework is an environment for
implementing and performing automatic and semi-automatic execution of
- test cases.
-
- Common Test uses the OTP Test Server as engine for test case
- execution and logging.</p>
+ test cases.</p>
- <p>In brief, Common Test supports:</p>
+ <p>In brief, <c>Common Test</c> supports:</p>
<list>
- <item>Automated execution of test suites (sets of test cases).</item>
- <item>Logging of the events during execution.</item>
- <item>HTML presentation of test suite results.</item>
- <item>HTML presentation of test suite code.</item>
- <item>Support functions for test suite authors.</item>
- <item>Step by step execution of test cases.</item>
+ <item>Automated execution of test suites (sets of test cases)</item>
+ <item>Logging of events during execution</item>
+ <item>HTML presentation of test suite results</item>
+ <item>HTML presentation of test suite code</item>
+ <item>Support functions for test suite authors</item>
+ <item>Step-by-step execution of test cases</item>
</list>
-
- <p>The following sections describe the mandatory and optional test suite
- functions Common Test will call during test execution. For more details
- see <seealso marker="write_test_chapter">Common Test User's
- Guide.</seealso> </p>
-
+
+ <p>The following section describes the mandatory and optional test suite
+ functions that <c>Common Test</c> calls during test execution.
+ For more details, see section
+ <seealso marker="write_test_chapter">Writing Test Suites</seealso>
+ in the User's Guide.</p>
+
</description>
<section>
- <title>TEST CASE CALLBACK FUNCTIONS</title>
+ <title>Test Case Callback Functions</title>
<p>The following functions define the callback interface
for a test suite.</p>
</section>
-
+
<funcs>
<func>
<name>Module:all() -> Tests | {skip,Reason} </name>
<fsummary>Returns the list of all test case groups and test cases
in the module.</fsummary>
<type>
- <v>Tests = [TestCase | {group,GroupName} |
- {group,GroupName,Properties} |
- {group,GroupName,Properties,SubGroups}]</v>
+ <v>Tests = [TestCase | {group,GroupName} | {group,GroupName,Properties} | {group,GroupName,Properties,SubGroups}]</v>
<v>TestCase = atom()</v>
<v>GroupName = atom()</v>
- <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}] |
- default</v>
- <v>SubGroups = [{GroupName,Properties} |
- {GroupName,Properties,SubGroups}]</v>
+ <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}] | default</v>
+ <v>SubGroups = [{GroupName,Properties} | {GroupName,Properties,SubGroups}]</v>
<v>Shuffle = shuffle | {shuffle,Seed}</v>
<v>Seed = {integer(),integer(),integer()}</v>
- <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
- repeat_until_any_ok | repeat_until_any_fail</v>
+ <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail</v>
<v>N = integer() | forever</v>
<v>Reason = term()</v>
</type>
-
+
<desc>
- <p> MANDATORY </p>
-
- <p>This function must return the list of all test cases and test
- case groups in the test suite module that are to be executed.
- This list also specifies the order the cases and groups will
- be executed by Common Test. A test case is represented by an atom,
+ <p>MANDATORY</p>
+
+ <p>Returns the list of all test cases and test case groups in the
+ test suite module to be executed. This list also specifies the
+ order the cases and groups are executed by <c>Common Test</c>.
+ A test case is represented by an atom,
the name of the test case function. A test case group is
represented by a <c>group</c> tuple, where <c>GroupName</c>,
- an atom, is the name of the group (defined in <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>).
- Execution properties for groups may also be specified, both
- for a top level group and for any of its sub-groups.
- Group execution properties specified here, will override
- properties in the group definition (see <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>).
+ an atom, is the name of the group (defined in
+ <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>).
+ Execution properties for groups can also be specified, both
+ for a top-level group and for any of its subgroups.
+ Group execution properties specified here override
+ properties in the group definition (see
+ <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>).
(With value <c>default</c>, the group definition properties
- will be used).</p>
-
- <p> If <c>{skip,Reason}</c> is returned, all test cases
- in the module will be skipped, and the <c>Reason</c> will
- be printed on the HTML result page.</p>
-
- <p>For details on groups, see
- <seealso marker="write_test_chapter#test_case_groups">Test case
- groups</seealso> in the User's Guide.</p>
-
+ are used).</p>
+
+ <p>If <c>{skip,Reason}</c> is returned, all test cases
+ in the module are skipped and <c>Reason</c>
+ is printed on the HTML result page.</p>
+
+ <p>For details on groups, see section
+ <seealso marker="write_test_chapter#test_case_groups">Test Case
+ Groups</seealso> in the User's Guide.</p>
+
</desc>
</func>
@@ -122,25 +118,24 @@
<name>Module:groups() -> GroupDefs</name>
<fsummary>Returns a list of test case group definitions.</fsummary>
<type>
- <v>GroupDefs = [Group]</v>
- <v>Group = {GroupName,Properties,GroupsAndTestCases}</v>
- <v>GroupName = atom()</v>
- <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}]</v>
- <v>GroupsAndTestCases = [Group | {group,GroupName} | TestCase]</v>
- <v>TestCase = atom()</v>
- <v>Shuffle = shuffle | {shuffle,Seed}</v>
- <v>Seed = {integer(),integer(),integer()}</v>
- <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
- repeat_until_any_ok | repeat_until_any_fail</v>
- <v>N = integer() | forever</v>
+ <v>GroupDefs = [Group]</v>
+ <v>Group = {GroupName,Properties,GroupsAndTestCases}</v>
+ <v>GroupName = atom()</v>
+ <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}]</v>
+ <v>GroupsAndTestCases = [Group | {group,GroupName} | TestCase]</v>
+ <v>TestCase = atom()</v>
+ <v>Shuffle = shuffle | {shuffle,Seed}</v>
+ <v>Seed = {integer(),integer(),integer()}</v>
+ <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail</v>
+ <v>N = integer() | forever</v>
</type>
-
+
<desc>
- <p> OPTIONAL </p>
-
- <p>Function for defining test case groups. Please see
- <seealso marker="write_test_chapter#test_case_groups">Test case
- groups</seealso> in the User's Guide for details.</p>
+ <p>OPTIONAL</p>
+
+ <p>Defines test case groups. For details, see section
+ <seealso marker="write_test_chapter#test_case_groups">Test Case
+ Groups</seealso> in the User's Guide.</p>
</desc>
</func>
@@ -149,75 +144,71 @@
<fsummary>Test suite info function (providing default data
for the suite).</fsummary>
<type>
- <v> Info = {timetrap,Time} | {require,Required} |
- {require,Name,Required} | {userdata,UserData} |
- {silent_connections,Conns} | {stylesheet,CSSFile} |
- {ct_hooks, CTHs}</v>
- <v> Time = TimeVal | TimeFunc</v>
- <v> TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} |
- {hours,integer()}</v>
- <v> TimeFunc = {Mod,Func,Args} | Fun</v>
- <v> MilliSec = integer()</v>
- <v> Mod = atom()</v>
- <v> Func = atom()</v>
- <v> Args = list()</v>
- <v> Fun = fun()</v>
- <v> Required = Key | {Key,SubKeys} | {Key,SubKey} | {Key,SubKey,SubKeys}</v>
- <v> Key = atom()</v>
- <v> SubKeys = SubKey | [SubKey]</v>
- <v> SubKey = atom()</v>
- <v> Name = atom()</v>
- <v> UserData = term()</v>
- <v> Conns = [atom()]</v>
- <v> CSSFile = string()</v>
- <v> CTHs = [CTHModule |</v>
- <v>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs} |</v>
- <v>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs, CTHPriority}]</v>
- <v> CTHModule = atom()</v>
- <v> CTHInitArgs = term()</v>
+ <v>Info = {timetrap,Time} | {require,Required} | {require,Name,Required} | {userdata,UserData} | {silent_connections,Conns} | {stylesheet,CSSFile} | {ct_hooks, CTHs}</v>
+ <v>Time = TimeVal | TimeFunc</v>
+ <v>TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | {hours,integer()}</v>
+ <v>TimeFunc = {Mod,Func,Args} | Fun</v>
+ <v>MilliSec = integer()</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Args = list()</v>
+ <v>Fun = fun()</v>
+ <v>Required = Key | {Key,SubKeys} | {Key,SubKey} | {Key,SubKey,SubKeys}</v>
+ <v>Key = atom()</v>
+ <v>SubKeys = SubKey | [SubKey]</v>
+ <v>SubKey = atom()</v>
+ <v>Name = atom()</v>
+ <v>UserData = term()</v>
+ <v>Conns = [atom()]</v>
+ <v>CSSFile = string()</v>
+ <v>CTHs = [CTHModule |</v>
+ <v>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs} |</v>
+ <v>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs, CTHPriority}]</v>
+ <v>CTHModule = atom()</v>
+ <v>CTHInitArgs = term()</v>
</type>
<desc>
-
- <p> OPTIONAL </p>
-
- <p>This is the test suite info function. It is supposed to
- return a list of tagged tuples that specify various properties
- related to the execution of this test suite (common for all
- test cases in the suite).</p>
-
- <p>The <c>timetrap</c> tag sets the maximum time each
- test case is allowed to execute (including <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
- and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). If the timetrap time is
- exceeded, the test case fails with reason
+
+ <p>OPTIONAL</p>
+
+ <p>The test suite information function. Returns a list of tagged
+ tuples specifying various properties related to the execution of
+ this test suite (common for all test cases in the suite).</p>
+
+ <p>Tag <c>timetrap</c> sets the maximum time that each
+ test case is allowed to execute (including
+ <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
+ and
+ <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>).
+ If the timetrap time is exceeded, the test case fails with reason
<c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to
- set a new timetrap by returning a <c>TimeVal</c>. It may also be
- used to trigger a timetrap timeout by, at some point, returning a
- value other than a <c>TimeVal</c>. (See the
- <seealso marker="write_test_chapter#timetraps">User's Guide</seealso>
- for details).
- </p>
-
- <p>The <c>require</c> tag specifies configuration variables
- that are required by test cases (and/or configuration functions)
+ set a new timetrap by returning a <c>TimeVal</c>. It can also be
+ used to trigger a timetrap time-out by, at some point, returning a
+ value other than a <c>TimeVal</c>. For details, see section
+ <seealso marker="write_test_chapter#timetraps">Timetrap Time-Outs</seealso>
+ in the User's Guide.</p>
+
+ <p>Tag <c>require</c> specifies configuration variables
+ required by test cases (or configuration functions)
in the suite. If the required configuration variables are not found
- in any of the configuration files, all test cases are skipped. For more
- information about the 'require' functionality, see the
- reference manual for the function
- <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p>
+ in any of the configuration files, all test cases are skipped.
+ For details about the <c>require</c> functionality, see funtion
+ <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.</p>
- <p>With <c>userdata</c>, it is possible for the user to
- specify arbitrary test suite related information which can be
- read by calling <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p>
+ <p>With <c>userdata</c>, the user can
+ specify any test suite-related information, which can be
+ read by calling
+ <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p>
- <p>The <c>ct_hooks</c> tag specifies which
+ <p>Tag <c>ct_hooks</c> specifies the
<seealso marker="ct_hooks_chapter">Common Test Hooks</seealso>
- are to be run together with this suite.</p>
-
- <p>Other tuples than the ones defined will simply be ignored.</p>
+ to be run with this suite.</p>
+
+ <p>Other tuples than the ones defined are ignored.</p>
- <p>For more information about the test suite info function,
- see <seealso marker="write_test_chapter#suite">Test
- suite info function</seealso> in the User's Guide.</p>
+ <p>For details about the test suite information function, see section
+ <seealso marker="write_test_chapter#suite">Test
+ Suite Information Function</seealso> in the User's Guide.</p>
</desc>
</func>
@@ -226,129 +217,133 @@
{skip_and_save,Reason,SaveConfig}</name>
<fsummary>Test suite initializations.</fsummary>
<type>
- <v> Config = NewConfig = SaveConfig = [{Key,Value}]</v>
- <v> Key = atom()</v>
- <v> Value = term()</v>
- <v> Reason = term()</v>
+ <v>Config = NewConfig = SaveConfig = [{Key,Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
-
- <p> OPTIONAL </p>
-
+
+ <p>OPTIONAL</p>
+
<p>This configuration function is called as the first function in the
- suite. It typically contains initializations which are common for
- all test cases in the suite, and which shall only be done
- once. The <c>Config</c> parameter is the configuration data
- which can be modified here. Whatever is returned from this
- function is given as <c>Config</c> to all configuration functions
- and test cases in the suite. If <c>{skip,Reason}</c>
- is returned, all test cases in the suite will be skipped
- and <c>Reason</c> printed in the overview log for the suite.</p>
- <p>For information on <c>save_config</c> and <c>skip_and_save</c>,
- please see
- <seealso marker="dependencies_chapter#save_config">Dependencies
- between Test Cases and Suites</seealso> in the User's Guide.</p>
- </desc>
+ suite. It typically contains initializations that are common for
+ all test cases in the suite, and that must only be done
+ once. Parameter <c>Config</c> is the configuration data
+ that can be modified. Whatever is returned from this
+ function is specified as <c>Config</c> to all configuration functions
+ and test cases in the suite.</p>
+
+ <p>If <c>{skip,Reason}</c>
+ is returned, all test cases in the suite are skipped
+ and <c>Reason</c> is printed in the overview log for the suite.</p>
+
+ <p>For information on <c>save_config</c> and <c>skip_and_save</c>,
+ see section
+ <seealso marker="dependencies_chapter#save_config">Saving
+ Configuration Data</seealso> in the User's Guide.</p>
+ </desc>
</func>
-
+
<func>
- <name>Module:end_per_suite(Config) -> void() |
+ <name>Module:end_per_suite(Config) -> term() |
{save_config,SaveConfig}</name>
- <fsummary>Test suite finalization. </fsummary>
+ <fsummary>Test suite finalization.</fsummary>
<type>
- <v> Config = SaveConfig = [{Key,Value}]</v>
- <v> Key = atom()</v>
- <v> Value = term()</v>
+ <v>Config = SaveConfig = [{Key,Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
</type>
-
+
<desc>
- <p> OPTIONAL </p>
+ <p>OPTIONAL</p>
<p>This function is called as the last test case in the
suite. It is meant to be used for cleaning up after
- <seealso marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>.
- For information on <c>save_config</c>, please see
- <seealso marker="dependencies_chapter#save_config">Dependencies
- between Test Cases and Suites</seealso> in the User's Guide.</p>
+ <seealso marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>.</p>
+ <p>For information on <c>save_config</c>, see section
+ <seealso marker="dependencies_chapter#save_config">Saving
+ Configuration Data</seealso> in the User's Guide.</p>
</desc>
</func>
<func>
<name>Module:group(GroupName) -> [Info] </name>
- <fsummary>Test case group info function (providing default data
- for a test case group, i.e. its test cases and sub-groups).</fsummary>
+ <fsummary>Test case group information function (providing default data
+ for a test case group, that is, its test cases and
+ subgroups).</fsummary>
<type>
- <v> Info = {timetrap,Time} | {require,Required} |
- {require,Name,Required} | {userdata,UserData} |
- {silent_connections,Conns} | {stylesheet,CSSFile} |
- {ct_hooks, CTHs}</v>
- <v> Time = TimeVal | TimeFunc</v>
- <v> TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} |
- {hours,integer()}</v>
- <v> TimeFunc = {Mod,Func,Args} | Fun</v>
- <v> MilliSec = integer()</v>
- <v> Mod = atom()</v>
- <v> Func = atom()</v>
- <v> Args = list()</v>
- <v> Fun = fun()</v>
- <v> Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v>
- <v> Key = atom()</v>
- <v> SubKeys = SubKey | [SubKey]</v>
- <v> SubKey = atom()</v>
- <v> Name = atom()</v>
- <v> UserData = term()</v>
- <v> Conns = [atom()]</v>
- <v> CSSFile = string()</v>
- <v> CTHs = [CTHModule |</v>
- <v> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs} |</v>
- <v> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs, CTHPriority}]</v>
- <v> CTHModule = atom()</v>
- <v> CTHInitArgs = term()</v>
- </type>
- <desc>
-
- <p> OPTIONAL </p>
-
- <p>This is the test case group info function. It is supposed to
+ <v>Info = {timetrap,Time} | {require,Required} | {require,Name,Required} | {userdata,UserData} | {silent_connections,Conns} | {stylesheet,CSSFile} | {ct_hooks, CTHs}</v>
+ <v>Time = TimeVal | TimeFunc</v>
+ <v>TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | {hours,integer()}</v>
+ <v>TimeFunc = {Mod,Func,Args} | Fun</v>
+ <v>MilliSec = integer()</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Args = list()</v>
+ <v>Fun = fun()</v>
+ <v>Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v>
+ <v>Key = atom()</v>
+ <v>SubKeys = SubKey | [SubKey]</v>
+ <v>SubKey = atom()</v>
+ <v>Name = atom()</v>
+ <v>UserData = term()</v>
+ <v>Conns = [atom()]</v>
+ <v>CSSFile = string()</v>
+ <v>CTHs = [CTHModule |</v>
+ <v>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs} |</v>
+ <v>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{CTHModule, CTHInitArgs, CTHPriority}]</v>
+ <v>CTHModule = atom()</v>
+ <v>CTHInitArgs = term()</v>
+ </type>
+ <desc>
+
+ <p>OPTIONAL</p>
+
+ <p>The test case group information function. It is supposed to
return a list of tagged tuples that specify various properties
- related to the execution of a test case group (i.e. its test cases
- and sub-groups). Properties set by
+ related to the execution of a test case group (that is, its test
+ cases and subgroups). Properties set by
<seealso marker="#Module:group-1"><c>group/1</c></seealso> override
- properties with the same key that have been previously set by
+ properties with the same key that have been set previously by
<seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p>
- <p>The <c>timetrap</c> tag sets the maximum time each
- test case is allowed to execute (including <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
- and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). If the timetrap time is
+ <p>Tag <c>timetrap</c> sets the maximum time that each
+ test case is allowed to execute (including
+ <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
+ and
+ <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>).
+ If the timetrap time is
exceeded, the test case fails with reason
<c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to
- set a new timetrap by returning a <c>TimeVal</c>. It may also be
- used to trigger a timetrap timeout by, at some point, returning a
- value other than a <c>TimeVal</c>. (See the
- <seealso marker="write_test_chapter#timetraps">User's Guide</seealso>
- for details).</p>
+ set a new timetrap by returning a <c>TimeVal</c>. It can also be
+ used to trigger a timetrap time-out by, at some point, returning a
+ value other than a <c>TimeVal</c>. For details, see section
+ <seealso marker="write_test_chapter#timetraps">Timetrap
+ Time-Outs</seealso> in the User's Guide.</p>
- <p>The <c>require</c> tag specifies configuration variables
- that are required by test cases (and/or configuration functions)
+ <p>Tag <c>require</c> specifies configuration variables
+ required by test cases (or configuration functions)
in the suite. If the required configuration variables are not found
- in any of the configuration files, all test cases in this group are skipped.
- For more information about the 'require' functionality, see the
- reference manual for the function
- <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p>
+ in any of the configuration files, all test cases in this group are
+ skipped. For details about the <c>require</c> functionality, see
+ function
+ <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.</p>
- <p>With <c>userdata</c>, it is possible for the user to
- specify arbitrary test case group related information which can be
- read by calling <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p>
+ <p>With <c>userdata</c>, the user can
+ specify any test case group related information that can be
+ read by calling
+ <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p>
- <p>The <c>ct_hooks</c> tag specifies which
+ <p>Tag <c>ct_hooks</c> specifies the
<seealso marker="ct_hooks_chapter">Common Test Hooks</seealso>
- are to be run together with this suite.</p>
-
- <p>Other tuples than the ones defined will simply be ignored.</p>
+ to be run with this suite.</p>
+
+ <p>Other tuples than the ones defined are ignored.</p>
- <p>For more information about the test case group info function,
- see <seealso marker="write_test_chapter#suite">Test
- case group info function</seealso> in the User's Guide.</p>
+ <p>For details about the test case group information function,
+ see section <seealso marker="write_test_chapter#group_info">Group
+ Information Function</seealso> in the User's Guide.</p>
</desc>
</func>
@@ -357,59 +352,66 @@
{skip,Reason}</name>
<fsummary>Test case group initializations.</fsummary>
<type>
- <v> GroupName = atom()</v>
- <v> Config = NewConfig = [{Key,Value}]</v>
- <v> Key = atom()</v>
- <v> Value = term()</v>
- <v> Reason = term()</v>
+ <v>GroupName = atom()</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
-
- <p> OPTIONAL </p>
-
+
+ <p>OPTIONAL</p>
+
<p>This configuration function is called before execution of a
- test case group. It typically contains initializations which are
- common for all test cases and sub-groups in the group, and which
- shall only be performed once. <c>GroupName</c> is the name of the
- group, as specified in the group definition (see <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). The
- <c>Config</c> parameter is the configuration data which can be modified
- here. The return value of this function is given as <c>Config</c>
- to all test cases and sub-groups in the group. If <c>{skip,Reason}</c>
- is returned, all test cases in the group will be skipped and
- <c>Reason</c> printed in the overview log for the group.</p>
-
- <p>For information about test case groups, please see
- <seealso marker="write_test_chapter#test_case_groups">Test case
- groups</seealso> chapter in the User's Guide.</p>
+ test case group. It typically contains initializations that are
+ common for all test cases and subgroups in the group, and that
+ must only be performed once. <c>GroupName</c> is the name of the
+ group, as specified in the group definition (see
+ <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>).
+ Parameter <c>Config</c> is the configuration data that can be
+ modified.
+ The return value of this function is given as <c>Config</c>
+ to all test cases and subgroups in the group.</p>
+
+ <p>If <c>{skip,Reason}</c>
+ is returned, all test cases in the group are skipped and
+ <c>Reason</c> is printed in the overview log for the group.</p>
+
+ <p>For information about test case groups, see section
+ <seealso marker="write_test_chapter#test_case_groups">Test Case
+ Groups</seealso> in the User's Guide.</p>
</desc>
</func>
-
+
<func>
- <name>Module:end_per_group(GroupName, Config) -> void() |
+ <name>Module:end_per_group(GroupName, Config) -> term() |
{return_group_result,Status}</name>
<fsummary>Test case group finalization.</fsummary>
<type>
- <v> GroupName = atom()</v>
- <v> Config = [{Key,Value}]</v>
- <v> Key = atom()</v>
- <v> Value = term()</v>
- <v> Status = ok | skipped | failed</v>
+ <v>GroupName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Status = ok | skipped | failed</v>
</type>
-
+
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called after the execution of a test case group is finished.
- It is meant to be used for cleaning up after <seealso marker="#Module:init_per_group-2"><c>init_per_group/2</c></seealso>.
- By means of <c>{return_group_result,Status}</c>, it is possible to return a
- status value for a nested sub-group. The status can be retrieved in
- <seealso marker="#Module:end_per_group-2"><c>end_per_group/2</c></seealso> for the group on the level above. The status will also
- be used by Common Test for deciding if execution of a group should proceed in
- case the property <c>sequence</c> or <c>repeat_until_*</c> is set.</p>
-
- <p>For more information about test case groups, please see
- <seealso marker="write_test_chapter#test_case_groups">Test case
- groups</seealso> chapter in the User's Guide.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after the execution of a test case group
+ is finished. It is meant to be used for cleaning up after
+ <seealso marker="#Module:init_per_group-2"><c>init_per_group/2</c></seealso>.
+ A status value for a nested subgroup can be returned with
+ <c>{return_group_result,Status}</c>. The status can be retrieved in
+ <seealso marker="#Module:end_per_group-2"><c>end_per_group/2</c></seealso>
+ for the group on the level above. The status is also used by
+ <c>Common Test</c> for deciding if execution of a group is to
+ proceed if property <c>sequence</c> or <c>repeat_until_*</c>
+ is set.</p>
+
+ <p>For details about test case groups, see section
+ <seealso marker="write_test_chapter#test_case_groups">Test Case
+ Groups</seealso> in the User's Guide.</p>
</desc>
</func>
@@ -423,168 +425,173 @@
<v> Value = term()</v>
<v> Reason = term()</v>
</type>
- <desc>
-
+ <desc>
+
<p>OPTIONAL</p>
-
- <p>This function is called before each test case. The
- <c>TestCase</c> argument is the name of the test case, and
+
+ <p>This function is called before each test case. Argument
+ <c>TestCase</c> is the test case name, and
<c>Config</c> (list of key-value tuples) is the configuration
- data that can be modified here. The <c>NewConfig</c> list returned
+ data that can be modified. The <c>NewConfig</c> list returned
from this function is given as <c>Config</c> to the test case.
If <c>{fail,Reason}</c> is returned, the test case is
- marked as failed without being executed. If <c>{skip,Reason}</c> is
- returned, the test case will be skipped and <c>Reason</c> printed
- in the overview log for the suite.</p>
+ marked as failed without being executed.</p>
+
+ <p>If <c>{skip,Reason}</c> is returned, the test case is skipped
+ and <c>Reason</c> is printed in the overview log for the suite.</p>
</desc>
</func>
-
+
<func>
- <name>Module:end_per_testcase(TestCase, Config) -> void() | {fail,Reason} | {save_config,SaveConfig}</name>
+ <name>Module:end_per_testcase(TestCase, Config) -> term() | {fail,Reason} | {save_config,SaveConfig}</name>
<fsummary>Test case finalization.</fsummary>
<type>
- <v> TestCase = atom()</v>
- <v> Config = SaveConfig = [{Key,Value}]</v>
- <v> Key = atom()</v>
- <v> Value = term()</v>
- <v> Reason = term()</v>
+ <v>TestCase = atom()</v>
+ <v>Config = SaveConfig = [{Key,Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
-
- <p> OPTIONAL </p>
-
- <p> This function is called after each test case, and can be used
- to clean up after <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> and the test case.
- Any return value (besides <c>{fail,Reason}</c> and <c>{save_config,SaveConfig}</c>)
- is ignored. By returning <c>{fail,Reason}</c>, <c>TestCase</c> will be marked as
- failed (even though it was actually successful in the sense that it returned
- a value instead of terminating). For information on <c>save_config</c>, please see
- <seealso marker="dependencies_chapter#save_config">Dependencies between
- Test Cases and Suites</seealso> in the User's Guide</p>
+
+ <p>OPTIONAL</p>
+
+ <p>This function is called after each test case, and can be used
+ to clean up after
+ <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
+ and the test case. Any return value (besides <c>{fail,Reason}</c>
+ and <c>{save_config,SaveConfig}</c>) is ignored. By returning
+ <c>{fail,Reason}</c>, <c>TestCase</c> is marked as faulty (even
+ though it was successful in the sense that it returned
+ a value instead of terminating).</p>
+
+ <p>For information on <c>save_config</c>, see section
+ <seealso marker="dependencies_chapter#save_config">Saving
+ Configuration Data</seealso> in the User's Guide.</p>
</desc>
</func>
-
+
<func>
<name>Module:Testcase() -> [Info] </name>
- <fsummary>Test case info function. </fsummary>
+ <fsummary>Test case information function.</fsummary>
<type>
- <v> Info = {timetrap,Time} | {require,Required} |
- {require,Name,Required} | {userdata,UserData} |
- {silent_connections,Conns}</v>
- <v> Time = TimeVal | TimeFunc</v>
- <v> TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} |
- {hours,integer()}</v>
- <v> TimeFunc = {Mod,Func,Args} | Fun</v>
- <v> MilliSec = integer()</v>
- <v> Mod = atom()</v>
- <v> Func = atom()</v>
- <v> Args = list()</v>
- <v> Fun = fun()</v>
- <v> Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v>
- <v> Key = atom()</v>
- <v> SubKeys = SubKey | [SubKey]</v>
- <v> SubKey = atom()</v>
- <v> Name = atom()</v>
- <v> UserData = term()</v>
- <v> Conns = [atom()]</v>
+ <v>Info = {timetrap,Time} | {require,Required} | {require,Name,Required} | {userdata,UserData} | {silent_connections,Conns}</v>
+ <v>Time = TimeVal | TimeFunc</v>
+ <v>TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | {hours,integer()}</v>
+ <v>TimeFunc = {Mod,Func,Args} | Fun</v>
+ <v>MilliSec = integer()</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Args = list()</v>
+ <v>Fun = fun()</v>
+ <v>Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v>
+ <v>Key = atom()</v>
+ <v>SubKeys = SubKey | [SubKey]</v>
+ <v>SubKey = atom()</v>
+ <v>Name = atom()</v>
+ <v>UserData = term()</v>
+ <v>Conns = [atom()]</v>
</type>
-
- <desc>
+
+ <desc>
<p>OPTIONAL</p>
-
- <p>This is the test case info function. It is supposed to
+
+ <p>The test case information function. It is supposed to
return a list of tagged tuples that specify various properties
related to the execution of this particular test case.
- Properties set by <seealso marker="#Module:Testcase-0"><c>Testcase/0</c></seealso> override
- properties that have been previously set for the test case
- by <seealso marker="#Module:group-1"><c>group/1</c></seealso> or <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p>
-
- <p>The <c>timetrap</c> tag sets the maximum time the
+ Properties set by
+ <seealso marker="#Module:Testcase-0"><c>Testcase/0</c></seealso>
+ override properties set previously for the test case by
+ <seealso marker="#Module:group-1"><c>group/1</c></seealso> or
+ <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p>
+
+ <p>Tag <c>timetrap</c> sets the maximum time that the
test case is allowed to execute. If the timetrap time is
- exceeded, the test case fails with reason
- <c>timetrap_timeout</c>. <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
- and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso> are included in the
- timetrap time. A <c>TimeFunc</c> function can be used to
- set a new timetrap by returning a <c>TimeVal</c>. It may also be
- used to trigger a timetrap timeout by, at some point, returning a
- value other than a <c>TimeVal</c>. (See the
- <seealso marker="write_test_chapter#timetraps">User's Guide</seealso>
- for details).</p>
+ exceeded, the test case fails with reason <c>timetrap_timeout</c>.
+ <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
+ and
+ <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>
+ are included in the timetrap time.
+ A <c>TimeFunc</c> function can be used to
+ set a new timetrap by returning a <c>TimeVal</c>. It can also be
+ used to trigger a timetrap time-out by, at some point, returning a
+ value other than a <c>TimeVal</c>. For details, see section
+ <seealso marker="write_test_chapter#timetraps">Timetrap
+ Time-Outs</seealso> in the User's Guide.</p>
- <p>The <c>require</c> tag specifies configuration variables
- that are required by the test case (and/or <c>init/end_per_testcase/2</c>).
+ <p>Tag <c>require</c> specifies configuration variables
+ that are required by the test case (or <c>init_per_testcase/2</c>
+ or <c>end_per_testcase/2</c>).
If the required configuration variables are not found in any of the
- configuration files, the test case is skipped. For more
- information about the 'require' functionality, see the
- reference manual for the function
- <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p>
-
- <p>If <c>timetrap</c> and/or <c>require</c> is not set, the
- default values specified by <seealso marker="#Module:suite-0"><c>suite/0</c></seealso> (or
- <seealso marker="#Module:group-1"><c>group/1</c></seealso>) will be used.</p>
-
- <p>With <c>userdata</c>, it is possible for the user to
- specify arbitrary test case related information which can be
- read by calling <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>.</p>
-
- <p>Other tuples than the ones defined will simply be ignored.</p>
+ configuration files, the test case is skipped. For details about
+ the <c>require</c> functionality, see function
+ <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.</p>
+
+ <p>If <c>timetrap</c> or <c>require</c> is not set, the
+ default values specified by
+ <seealso marker="#Module:suite-0"><c>suite/0</c></seealso> (or
+ <seealso marker="#Module:group-1"><c>group/1</c></seealso>) are used.</p>
+
+ <p>With <c>userdata</c>, the user can specify any test case-related
+ information that can be read by calling
+ <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>.</p>
+
+ <p>Other tuples than the ones defined are ignored.</p>
- <p>For more information about the test case info function,
- see <seealso marker="write_test_chapter#info_function">Test
- case info function</seealso> in the User's Guide.</p>
+ <p>For details about the test case information function, see section
+ <seealso marker="write_test_chapter#info_function">Test
+ Case Information Function</seealso> in the User's Guide.</p>
</desc>
</func>
-
-
+
<func>
- <name>Module:Testcase(Config) -> void() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name>
- <fsummary>A test case</fsummary>
+ <name>Module:Testcase(Config) -> term() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name>
+ <fsummary>A test case.</fsummary>
<type>
- <v> Config = SaveConfig = [{Key,Value}]</v>
- <v> Key = atom()</v>
- <v> Value = term()</v>
- <v> Reason = term()</v>
- <v> Comment = string()</v>
+ <v>Config = SaveConfig = [{Key,Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ <v>Comment = string()</v>
</type>
-
+
<desc>
- <p> MANDATORY </p>
-
- <p>This is the implementation of a test case. Here you must
- call the functions you want to test, and do whatever you
- need to check the result. If something fails, make sure the
- function causes a runtime error, or call <seealso marker="ct#fail-1"><c>ct:fail/1/2</c></seealso>
+ <p>MANDATORY</p>
+
+ <p>The implementation of a test case. Call the functions to test and
+ check the result. If something fails, ensure the
+ function causes a runtime error or call
+ <seealso marker="ct#fail-1"><c>ct:fail/1,2</c></seealso>
(which also causes the test case process to terminate).</p>
-
- <p>Elements from the <c>Config</c> list can e.g. be read
- with <c>proplists:get_value/2</c> (or the macro <c>?config</c>
- defined in <c>ct.hrl</c>).</p>
- <p>You can return <c>{skip,Reason}</c> if you decide not to
- run the test case after all. <c>Reason</c> will then be
- printed in 'Comment' field on the HTML result page.</p>
-
- <p>You can return <c>{comment,Comment}</c> if you wish to
- print some information in the 'Comment' field on the HTML
- result page.</p>
-
- <p>If the function returns anything else, the test case is
- considered successful. (The return value always gets printed
- in the test case log file).</p>
+ <p>Elements from the <c>Config</c> list can, for example, be read
+ with <c>proplists:get_value/2</c> in <c>STDLIB</c>
+ (or the macro <c>?config</c> defined in <c>ct.hrl</c>).</p>
+
+ <p>If you decide not to run the test case after all, return
+ <c>{skip,Reason}</c>. <c>Reason</c> is then
+ printed in field <c>Comment</c> on the HTML result page.</p>
+
+ <p>To print some information in field <c>Comment</c> on the HTML
+ result page, return <c>{comment,Comment}</c>.</p>
- <p>For more information about test case implementation, please
- see <seealso marker="write_test_chapter#test_cases">Test
- cases</seealso> in the User's Guide.</p>
+ <p>If the function returns anything else, the test case is
+ considered successful. The return value always gets printed
+ in the test case log file.</p>
- <p>For information on <c>save_config</c> and <c>skip_and_save</c>, please see
- <seealso marker="dependencies_chapter#save_config">Dependencies between
- Test Cases and Suites</seealso> in the User's Guide.</p>
+ <p>For details about test case implementation, see section
+ <seealso marker="write_test_chapter#test_cases">Test Cases</seealso>
+ in the User's Guide.</p>
+
+ <p>For information on <c>save_config</c> and <c>skip_and_save</c>,
+ see section
+ <seealso marker="dependencies_chapter#save_config">Saving
+ Configuration Data</seealso> in the User's Guide.</p>
</desc>
</func>
-
+
</funcs>
</erlref>
-
diff --git a/lib/common_test/doc/src/config_file_chapter.xml b/lib/common_test/doc/src/config_file_chapter.xml
index d3068db17b..62ebfccb98 100644
--- a/lib/common_test/doc/src/config_file_chapter.xml
+++ b/lib/common_test/doc/src/config_file_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -34,18 +35,18 @@
<section>
<title>General</title>
- <p>To avoid hard coding data values related to the test and/or SUT (System
- Under Test) in the test suites, the data may instead be specified by means
- of configuration files or strings that Common Test reads before
+ <p>To avoid hard-coding data values related to the test and/or System
+ Under Test (SUT) in the test suites, the data can instead be specified through
+ configuration files or strings that <c>Common Test</c> reads before
the start of a test run. External configuration data makes it possible to
- change test properties without having to modify the actual test suites
- using the data. Examples of configuration data:</p>
+ change test properties without modifying the test suites
+ using the data. Examples of configuration data follows:</p>
- <list>
+ <list type="bulleted">
<item>Addresses to the test plant or other instruments</item>
<item>User login information</item>
<item>Names of files needed by the test</item>
- <item>Names of programs that should be executed during the test</item>
+ <item>Names of programs to be executed during the test</item>
<item>Any other variable needed by the test</item>
</list>
@@ -56,154 +57,150 @@
<p>A configuration file can contain any number of elements of the type:</p>
<pre>
- {CfgVarName,Value}.</pre>
+ {CfgVarName,Value}.</pre>
<p>where</p>
<pre>
- CfgVarName = atom()
- Value = term() | [{CfgVarName,Value}]</pre>
+ CfgVarName = atom()
+ Value = term() | [{CfgVarName,Value}]</pre>
</section>
<section>
- <title>Requiring and reading configuration data</title>
+ <title>Requiring and Reading Configuration Data</title>
<marker id="require_config_data"></marker>
<p>In a test suite, one must <em>require</em> that a configuration
- variable (<c>CfgVarName</c> in the definition above) exists before
- attempting to read the associated value in a test case or config function.</p>
-
- <p><c>require</c> is an assert statement that can be part of the <seealso
- marker="write_test_chapter#suite">test suite info function</seealso> or
- <seealso marker="write_test_chapter#info_function">test case info
- function</seealso>. If the required variable is not available, the
- test is skipped (unless a default value has been specified, see the
- <seealso marker="write_test_chapter#info_function">test case info
- function</seealso> chapter for details). There is also a function
- <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> which can be called from a test case
- in order to check if a specific variable is available. The return
+ variable (<c>CfgVarName</c> in the previous definition) exists before
+ attempting to read the associated value in a test case or configuration function.</p>
+
+ <p><c>require</c> is an assert statement, which can be part of the <seealso
+ marker="write_test_chapter#suite">Test Suite Information Function</seealso> or
+ <seealso marker="write_test_chapter#info_function">Test Case Information
+ Function</seealso>. If the required variable is unavailable, the
+ test is skipped (unless a default value has been specified, see section
+ <seealso marker="write_test_chapter#info_function">Test Case Information
+ Function</seealso> for details). Also, function
+ <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> can be called
+ from a test case to check if a specific variable is available. The return
value from this function must be checked explicitly and appropriate
- action be taken depending on the result (e.g. to skip the test case
- if the variable in question doesn't exist).</p>
+ action be taken depending on the result (for example, to skip the test case
+ if the variable in question does not exist).</p>
- <p>A <c>require</c> statement in the test suite info- or test case
- info-list should look like this:
+ <p>A <c>require</c> statement in the test suite information case or test case
+ information-list is to look like
<c>{require,CfgVarName}</c> or <c>{require,AliasName,CfgVarName}</c>.
The arguments <c>AliasName</c> and <c>CfgVarName</c> are the same as the
- arguments to <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> which are described in the
- reference manual for <seealso marker="ct">ct</seealso>.
+ arguments to <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.
<c>AliasName</c> becomes an alias for the configuration variable,
and can be used as reference to the configuration data value.
- The configuration variable may be associated with an
- arbitrary number of alias names, but each name must be unique within
- the same test suite. There are two main uses for alias names:</p>
- <list>
- <item>They may be introduced to identify connections (see below).</item>
- <item>They may used to help adapt configuration data to a test suite
+ The configuration variable can be associated with any
+ number of alias names, but each name must be unique within
+ the same test suite. The two main uses for alias names follows:</p>
+ <list type="bulleted">
+ <item>To identify connections (described later).</item>
+ <item>To help adapt configuration data to a test suite
(or test case) and improve readability.</item>
</list>
- <p>To read the value of a config variable, use the function
- <seealso marker="ct#get_config-1"><c>get_config/1/2/3</c></seealso>
- which is also described in the reference
- manual for <seealso marker="ct">ct</seealso>.</p>
- <p>Example:</p>
+ <p>To read the value of a configuration variable, use function
+ <seealso marker="ct#get_config-1"><c>get_config/1,2,3</c></seealso>.
+ </p>
+ <p><em>Example:</em></p>
<pre>
- suite() ->
- [{require, domain, 'CONN_SPEC_DNS_SUFFIX'}].
+ suite() ->
+ [{require, domain, 'CONN_SPEC_DNS_SUFFIX'}].
- ...
-
- testcase(Config) ->
- Domain = ct:get_config(domain),
- ...</pre>
+ ...
+
+ testcase(Config) ->
+ Domain = ct:get_config(domain),
+ ...</pre>
</section>
<section>
- <title>Using configuration variables defined in multiple files</title>
+ <title>Using Configuration Variables Defined in Multiple Files</title>
<p>If a configuration variable is defined in multiple files and you
- want to access all possible values, you may use the <seealso marker="ct#get_config-3"><c>ct:get_config/3</c></seealso>
- function and specify <c>all</c> in the options list. The values will then
- be returned in a list and the order of the elements corresponds to the order
- that the config files were specified at startup. Please see
- the <seealso marker="ct">ct</seealso> reference manual for details.</p>
+ want to access all possible values, use function
+ <seealso marker="ct#get_config-3"><c>ct:get_config/3</c></seealso>
+ and specify <c>all</c> in the options list. The values are then
+ returned in a list and the order of the elements corresponds to the order
+ that the configuration files were specified at startup.</p>
</section>
<section>
- <title>Encrypted configuration files</title>
+ <title>Encrypted Configuration Files</title>
<marker id="encrypted_config_files"></marker>
- <p>It is possible to encrypt configuration files containing sensitive data
- if these files must be stored in open and shared directories.</p>
- <p>Call <seealso marker="ct#encrypt_config_file-2"><c>ct:encrypt_config_file/2/3</c></seealso> to have Common Test encrypt a
- specified file using the DES3 function in the OTP <c>crypto</c> application.
- The encrypted file can then be used as a regular configuration file,
- in combination with other encrypted files or normal text files. The key
- for decrypting the configuration file must be provided when running the test,
- however. This can be done by means of the <c>decrypt_key</c> or
- <c>decrypt_file</c> flag/option, or a key file in a predefined location.</p>
+ <p>Configuration files containing sensitive data can be encrypted
+ if they must be stored in open and shared directories.</p>
+ <p>To have <c>Common Test</c> encrypt a
+ specified file using function <c>DES3</c> in application <c>Crypto</c>,
+ call <seealso marker="ct#encrypt_config_file-2"><c>ct:encrypt_config_file/2,3</c></seealso>
+ The encrypted file can then be used as a regular configuration file
+ in combination with other encrypted files or normal text files. However, the
+ key for decrypting the configuration file must be provided when running the test.
+ This can be done with flag/option <c>decrypt_key</c> or
+ <c>decrypt_file</c>, or a key file in a predefined location.</p>
- <p>Common Test also provides decryption functions,
- <seealso marker="ct#decrypt_config_file-2"><c>ct:decrypt_config_file/2/3</c></seealso>, for recreating the original text
- files.</p>
-
- <p>Please see the <seealso marker="ct">ct</seealso> reference manual for
- more information.</p>
+ <p><c>Common Test</c> also provides decryption functions,
+ <seealso marker="ct#decrypt_config_file-2"><c>ct:decrypt_config_file/2,3</c></seealso>,
+ for recreating the original text files.</p>
</section>
<section>
- <title>Opening connections by using configuration data</title>
- <p>There are two different methods for opening a connection
- by means of the support functions in e.g. <seealso marker="ct_ssh"><c>ct_ssh</c></seealso>, <seealso marker="ct_ftp"><c>ct_ftp</c></seealso>,
- and <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>:</p>
- <list>
+ <title>Opening Connections Using Configuration Data</title>
+ <p>Two different methods for opening a connection using the support functions
+ in, for example, <seealso marker="ct_ssh"><c>ct_ssh</c></seealso>,
+ <seealso marker="ct_ftp"><c>ct_ftp</c></seealso>, and
+ <seealso marker="ct_telnet"><c>ct_telnet</c></seealso> follows:</p>
+ <list type="bulleted">
<item>Using a configuration target name (an alias) as reference.</item>
<item>Using the configuration variable as reference.</item>
</list>
<p>When a target name is used for referencing the configuration data
- (that specifies the connection to be opened), the same name may be used
+ (that specifies the connection to be opened), the same name can be used
as connection identity in all subsequent calls related to the connection
- (also for closing it). It's only possible to have one open connection
- per target name. If attempting to open a new connection using a name
- already associated with an open connection, Common Test will
- return the already existing handle so that the previously opened connection
- will be used. This is a practical feature since it makes it possible to
+ (also for closing it). Only one open connection per target name
+ is possible. If you attempt to open a new connection using a name
+ already associated with an open connection, <c>Common Test</c>
+ returns the already existing handle so the previously opened connection
+ is used. This feature makes it possible to
call the function for opening a particular connection whenever
- useful. An action like this will not necessarily open any new
- connections unless it's required (which could be the case if e.g. the
- previous connection has been closed unexpectedly by the server).
- Another benefit of using named connections is that it's not
- necessary to pass handle references around in the suite for these
- connections.
+ useful. An action like this does not necessarily open any new
+ connections unless it is required (which could be the case if, for example,
+ the previous connection has been closed unexpectedly by the server).
+ Using named connections also removes the need to pass handle references
+ around in the suite for these connections.
</p>
<p>When a configuration variable name is used as reference to the data
specifying the connection, the handle returned as a result of opening
the connection must be used in all subsequent calls (also for closing
the connection). Repeated calls to the open function with the same
- variable name as reference will result in multiple connections
- being opened. This can be useful e.g. if a test case needs to open
+ variable name as reference results in multiple connections being opened.
+ This can be useful, for example, if a test case needs to open
multiple connections to the same server on the target node (using the
same configuration data for each connection).
</p>
</section>
<section>
- <title>User specific configuration data formats</title>
+ <title>User-Specific Configuration Data Formats</title>
- <p>It is possible for the user to specify configuration data on a
+ <p>The user can specify configuration data on a
different format than key-value tuples in a text file, as described
- so far. The data can e.g. be read from arbitrary files, fetched from
- the web over http, or requested from a user specific process.
- To support this, Common Test provides a callback module plugin
+ so far. The data can, for example, be read from any files, fetched from
+ the web over HTTP, or requested from a user-specific process.
+ To support this, <c>Common Test</c> provides a callback module plugin
mechanism to handle configuration data.</p>
<section>
- <title>Default callback modules for handling configuration data</title>
- <p>The Common Test application includes default callback modules
- for handling configuration data specified in standard config files
- (see above) and in xml files:</p>
- <list>
+ <title>Default Callback Modules for Handling Configuration Data</title>
+ <p><c>Common Test</c> includes default callback modules
+ for handling configuration data specified in standard configuration files
+ (described earlier) and in XML files as follows:</p>
+ <list type="bulleted">
<item>
<c>ct_config_plain</c> - for reading configuration files with
- key-value tuples (standard format). This handler will be used to
+ key-value tuples (standard format). This handler is used to
parse configuration files if no user callback is specified.
</item>
<item>
@@ -214,59 +211,59 @@
</section>
<section>
- <title>Using XML configuration files</title>
- <p>This is an example of an XML configuration file:</p>
- <pre><![CDATA[
-<config>
+ <title>Using XML Configuration Files</title>
+ <p>An example of an XML configuration file follows:</p>
+ <pre>
+ <![CDATA[
+ <config>
<ftp_host>
<ftp>"targethost"</ftp>
<username>"tester"</username>
<password>"letmein"</password>
</ftp_host>
<lm_directory>"/test/loadmodules"</lm_directory>
-</config>]]></pre>
+ </config>]]></pre>
- <p>This configuration file, once read, will produce the same configuration
+ <p>Once read, this file produces the same configuration
variables as the following text file:</p>
<pre>
-{ftp_host, [{ftp,"targethost"},
- {username,"tester"},
- {password,"letmein"}]}.
+ {ftp_host, [{ftp,"targethost"},
+ {username,"tester"},
+ {password,"letmein"}]}.
-{lm_directory, "/test/loadmodules"}.</pre>
+ {lm_directory, "/test/loadmodules"}.</pre>
</section>
<section>
- <title>How to implement a user specific handler</title>
+ <title>Implement a User-Specific Handler</title>
- <p>The user specific handler can be written to handle special
+ <p>The user-specific handler can be written to handle special
configuration file formats. The parameter can be either file
- name(s) or configuration string(s) (the empty list is valid).</p>
+ names or configuration strings (the empty list is valid).</p>
<p>The callback module implementing the handler is responsible for
- checking correctness of configuration strings.</p>
+ checking the correctness of configuration strings.</p>
- <p>To perform validation of the configuration strings, the callback module
- should have the following function exported:</p>
+ <p>To validate the configuration strings, the callback module
+ is to have function <c>Callback:check_parameter/1</c> exported.</p>
- <p><c>Callback:check_parameter/1</c></p>
- <p>The input argument will be passed from Common Test, as defined in the test
- specification or given as an option to <c>ct_run</c> or <c>ct:run_test</c>.</p>
+ <p>The input argument is passed from <c>Common Test</c>, as defined in the test
+ specification, or specified as an option to <c>ct_run</c> or <c>ct:run_test</c>.</p>
- <p>The return value should be any of the following values indicating if given
+ <p>The return value is to be any of the following values, indicating if the specified
configuration parameter is valid:</p>
- <list>
+ <list type="bulleted">
<item>
- <c>{ok, {file, FileName}}</c> - parameter is a file name and
- the file exists,
+ <c>{ok, {file, FileName}}</c> - the parameter is a file name and
+ the file exists.
</item>
<item>
- <c>{ok, {config, ConfigString}}</c> - parameter is a config string
- and it is correct,
+ <c>{ok, {config, ConfigString}}</c> - the parameter is a configuration string
+ and it is correct.
</item>
<item>
- <c>{error, {nofile, FileName}}</c> - there is no file with the given
- name in the current directory,
+ <c>{error, {nofile, FileName}}</c> - there is no file with the specified
+ name in the current directory.
</item>
<item>
<c>{error, {wrong_config, ConfigString}}</c> - the configuration string
@@ -274,196 +271,196 @@
</item>
</list>
- <p>To perform reading of configuration data - initially before the tests
- start, or as a result of data being reloaded during test execution -
- the following function should be exported from the callback module:</p>
-
- <p><c>Callback:read_config/1</c></p>
+ <p>The function <c>Callback:read_config/1</c> is to be exported from the
+ callback module to read configuration data, initially before the tests
+ start, or as a result of data being reloaded during test execution.
+ The input argument is the same as for function <c>check_parameter/1</c>.</p>
- <p>The input argument is the same as for the <c>check_parameter/1</c> function.</p>
- <p>The return value should be either:</p>
+ <p>The return value is to be either of the following:</p>
- <list>
+ <list type="bulleted">
<item>
- <c>{ok, Config}</c> - if the configuration variables are read successfully,
+ <c>{ok, Config}</c> - if the configuration variables are read successfully.
</item>
<item>
<c>{error, {Error, ErrorDetails}}</c> - if the callback module fails to
- proceed with the given configuration parameters.
+ proceed with the specified configuration parameters.
</item>
</list>
<p><c>Config</c> is the proper Erlang key-value list, with possible
- key-value sublists as values, like for the configuration file
- example above:</p>
+ key-value sublists as values, like the earlier configuration file
+ example:</p>
<pre>
- [{ftp_host, [{ftp, "targethost"}, {username, "tester"}, {password, "letmein"}]},
- {lm_directory, "/test/loadmodules"}]</pre>
+ [{ftp_host, [{ftp, "targethost"}, {username, "tester"}, {password, "letmein"}]},
+ {lm_directory, "/test/loadmodules"}]</pre>
</section>
</section>
<section>
- <title>Examples of configuration data handling</title>
+ <title>Examples of Configuration Data Handling</title>
- <p>A config file for using the FTP client to access files on a remote
- host could look like this:</p>
+ <p>A configuration file for using the FTP client to access files on a remote
+ host can look as follows:</p>
<pre>
- {ftp_host, [{ftp,"targethost"},
- {username,"tester"},
- {password,"letmein"}]}.
+ {ftp_host, [{ftp,"targethost"},
+ {username,"tester"},
+ {password,"letmein"}]}.
- {lm_directory, "/test/loadmodules"}.</pre>
+ {lm_directory, "/test/loadmodules"}.</pre>
- <p>The XML version shown in the chapter above can also be used, but it should be
+ <p>The XML version shown earlier can also be used, but it is to be
explicitly specified that the <c>ct_config_xml</c> callback module is to be
- used by Common Test.</p>
+ used by <c>Common Test</c>.</p>
- <p>Example of how to assert that the configuration data is available and
- use it for an FTP session:</p>
+ <p>The following is an example of how to assert that the configuration data is available
+ and can be used for an FTP session:</p>
<pre>
- init_per_testcase(ftptest, Config) ->
- {ok,_} = ct_ftp:open(ftp),
- Config.
-
- end_per_testcase(ftptest, _Config) ->
- ct_ftp:close(ftp).
-
- ftptest() ->
- [{require,ftp,ftp_host},
- {require,lm_directory}].
-
- ftptest(Config) ->
- Remote = filename:join(ct:get_config(lm_directory), "loadmodX"),
- Local = filename:join(?config(priv_dir,Config), "loadmodule"),
- ok = ct_ftp:recv(ftp, Remote, Local),
- ...</pre>
+ init_per_testcase(ftptest, Config) ->
+ {ok,_} = ct_ftp:open(ftp),
+ Config.
+
+ end_per_testcase(ftptest, _Config) ->
+ ct_ftp:close(ftp).
+
+ ftptest() ->
+ [{require,ftp,ftp_host},
+ {require,lm_directory}].
+
+ ftptest(Config) ->
+ Remote = filename:join(ct:get_config(lm_directory), "loadmodX"),
+ Local = filename:join(?config(priv_dir,Config), "loadmodule"),
+ ok = ct_ftp:recv(ftp, Remote, Local),
+ ...</pre>
- <p>An example of how the above functions could be rewritten
- if necessary to open multiple connections to the FTP server:</p>
+ <p>The following is an example of how the functions in the previous example
+ can be rewritten if it is necessary to open multiple connections to the
+ FTP server:</p>
<pre>
- init_per_testcase(ftptest, Config) ->
- {ok,Handle1} = ct_ftp:open(ftp_host),
- {ok,Handle2} = ct_ftp:open(ftp_host),
- [{ftp_handles,[Handle1,Handle2]} | Config].
-
- end_per_testcase(ftptest, Config) ->
- lists:foreach(fun(Handle) -> ct_ftp:close(Handle) end,
- ?config(ftp_handles,Config)).
-
- ftptest() ->
- [{require,ftp_host},
- {require,lm_directory}].
-
- ftptest(Config) ->
- Remote = filename:join(ct:get_config(lm_directory), "loadmodX"),
- Local = filename:join(?config(priv_dir,Config), "loadmodule"),
- [Handle | MoreHandles] = ?config(ftp_handles,Config),
- ok = ct_ftp:recv(Handle, Remote, Local),
- ...</pre>
+ init_per_testcase(ftptest, Config) ->
+ {ok,Handle1} = ct_ftp:open(ftp_host),
+ {ok,Handle2} = ct_ftp:open(ftp_host),
+ [{ftp_handles,[Handle1,Handle2]} | Config].
+
+ end_per_testcase(ftptest, Config) ->
+ lists:foreach(fun(Handle) -> ct_ftp:close(Handle) end,
+ ?config(ftp_handles,Config)).
+
+ ftptest() ->
+ [{require,ftp_host},
+ {require,lm_directory}].
+
+ ftptest(Config) ->
+ Remote = filename:join(ct:get_config(lm_directory), "loadmodX"),
+ Local = filename:join(?config(priv_dir,Config), "loadmodule"),
+ [Handle | MoreHandles] = ?config(ftp_handles,Config),
+ ok = ct_ftp:recv(Handle, Remote, Local),
+ ...</pre>
</section>
<section>
- <title>Example of user specific configuration handler</title>
- <p>A simple configuration handling driver which will ask an external server for
- configuration data can be implemented this way:</p>
+ <title>Example of User-Specific Configuration Handler</title>
+ <p>A simple configuration handling driver, asking an external server for
+ configuration data, can be implemented as follows:</p>
<pre>
--module(config_driver).
--export([read_config/1, check_parameter/1]).
-
-read_config(ServerName)->
- ServerModule = list_to_atom(ServerName),
- ServerModule:start(),
- ServerModule:get_config().
-
-check_parameter(ServerName)->
- ServerModule = list_to_atom(ServerName),
- case code:is_loaded(ServerModule) of
- {file, _}->
- {ok, {config, ServerName}};
- false->
- case code:load_file(ServerModule) of
- {module, ServerModule}->
- {ok, {config, ServerName}};
- {error, nofile}->
- {error, {wrong_config, "File not found: " ++ ServerName ++ ".beam"}}
- end
- end.</pre>
-
- <p>The configuration string for this driver may be "config_server", if the
- config_server.erl module below is compiled and exists in the code path
+ -module(config_driver).
+ -export([read_config/1, check_parameter/1]).
+
+ read_config(ServerName)->
+ ServerModule = list_to_atom(ServerName),
+ ServerModule:start(),
+ ServerModule:get_config().
+
+ check_parameter(ServerName)->
+ ServerModule = list_to_atom(ServerName),
+ case code:is_loaded(ServerModule) of
+ {file, _}->
+ {ok, {config, ServerName}};
+ false->
+ case code:load_file(ServerModule) of
+ {module, ServerModule}->
+ {ok, {config, ServerName}};
+ {error, nofile}->
+ {error, {wrong_config, "File not found: " ++ ServerName ++ ".beam"}}
+ end
+ end.</pre>
+
+ <p>The configuration string for this driver can be <c>config_server</c>, if the
+ <c>config_server.erl</c> module that follows is compiled and exists in the code path
during test execution:</p>
<pre>
--module(config_server).
--export([start/0, stop/0, init/1, get_config/0, loop/0]).
-
--define(REGISTERED_NAME, ct_test_config_server).
-
-start()->
- case whereis(?REGISTERED_NAME) of
- undefined->
- spawn(?MODULE, init, [?REGISTERED_NAME]),
- wait();
- _Pid->
- ok
- end,
- ?REGISTERED_NAME.
-
-init(Name)->
- register(Name, self()),
- loop().
-
-get_config()->
- call(self(), get_config).
-
-stop()->
- call(self(), stop).
-
-call(Client, Request)->
- case whereis(?REGISTERED_NAME) of
- undefined->
- {error, {not_started, Request}};
- Pid->
- Pid ! {Client, Request},
- receive
- Reply->
- {ok, Reply}
- after 4000->
- {error, {timeout, Request}}
- end
- end.
-
-loop()->
- receive
- {Pid, stop}->
- Pid ! ok;
- {Pid, get_config}->
- {D,T} = erlang:localtime(),
- Pid !
- [{localtime, [{date, D}, {time, T}]},
- {node, erlang:node()},
- {now, erlang:now()},
- {config_server_pid, self()},
- {config_server_vsn, ?vsn}],
- ?MODULE:loop()
- end.
-
-wait()->
- case whereis(?REGISTERED_NAME) of
- undefined->
- wait();
- _Pid->
- ok
- end.</pre>
-
- <p>In this example, the handler also provides the ability to dynamically reload
- configuration variables. If <c>ct:reload_config(localtime)</c> is called from
+ -module(config_server).
+ -export([start/0, stop/0, init/1, get_config/0, loop/0]).
+
+ -define(REGISTERED_NAME, ct_test_config_server).
+
+ start()->
+ case whereis(?REGISTERED_NAME) of
+ undefined->
+ spawn(?MODULE, init, [?REGISTERED_NAME]),
+ wait();
+ _Pid->
+ ok
+ end,
+ ?REGISTERED_NAME.
+
+ init(Name)->
+ register(Name, self()),
+ loop().
+
+ get_config()->
+ call(self(), get_config).
+
+ stop()->
+ call(self(), stop).
+
+ call(Client, Request)->
+ case whereis(?REGISTERED_NAME) of
+ undefined->
+ {error, {not_started, Request}};
+ Pid->
+ Pid ! {Client, Request},
+ receive
+ Reply->
+ {ok, Reply}
+ after 4000->
+ {error, {timeout, Request}}
+ end
+ end.
+
+ loop()->
+ receive
+ {Pid, stop}->
+ Pid ! ok;
+ {Pid, get_config}->
+ {D,T} = erlang:localtime(),
+ Pid !
+ [{localtime, [{date, D}, {time, T}]},
+ {node, erlang:node()},
+ {now, erlang:now()},
+ {config_server_pid, self()},
+ {config_server_vsn, ?vsn}],
+ ?MODULE:loop()
+ end.
+
+ wait()->
+ case whereis(?REGISTERED_NAME) of
+ undefined->
+ wait();
+ _Pid->
+ ok
+ end.</pre>
+
+ <p>Here, the handler also provides for dynamically reloading of
+ configuration variables. If
+ <seealso marker="ct#reload_config-1"><c>ct:reload_config(localtime)</c></seealso> is called from
the test case function, all variables loaded with <c>config_driver:read_config/1</c>
- will be updated with their latest values, and the new value for variable
- <c>localtime</c> will be returned.</p>
+ are updated with their latest values, and the new value for variable
+ <c>localtime</c> is returned.</p>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml
index accb94e1a9..094aa7d80c 100644
--- a/lib/common_test/doc/src/cover_chapter.xml
+++ b/lib/common_test/doc/src/cover_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,256 +33,251 @@
<section>
<marker id="cover"></marker>
<title>General</title>
- <p>Although Common Test was created primarly for the purpose of
- black box testing, nothing prevents it from working perfectly as
- a white box testing tool as well. This is especially true when
+ <p>Although <c>Common Test</c> was created primarily for
+ black-box testing, nothing prevents it from working perfectly as
+ a white-box testing tool as well. This is especially true when
the application to test is written in Erlang. Then the test
- ports are easily realized by means of Erlang function calls.</p>
+ ports are easily realized with Erlang function calls.</p>
- <p>When white box testing an Erlang application, it is useful to
- be able to measure the code coverage of the test. Common Test
+ <p>When white-box testing an Erlang application, it is useful to
+ be able to measure the code coverage of the test. <c>Common Test</c>
provides simple access to the OTP Cover tool for this
- purpose. Common Test handles all necessary communication with
- the Cover tool (starting, compiling, analysing, etc). All the
- Common Test user needs to do is to specify the extent of the
+ purpose. <c>Common Test</c> handles all necessary communication with
+ the Cover tool (starting, compiling, analysing, and so on).
+ The <c>Common Test</c> user only needs to specify the extent of the
code coverage analysis.</p>
</section>
<section>
- <title>Usage</title>
- <p>To specify what modules should be included
- in the code coverage test, you provide a cover specification
- file. Using this file you can point out specific modules or
- specify directories that contain modules which should all be
- included in the analysis. You can also, in the same fashion,
- specify modules that should be excluded from the analysis.</p>
+ <title>Use</title>
+ <p>To specify the modules to be included in the code coverage test,
+ provide a cover specification file. With this file you can point
+ out specific modules or specify directories containing modules to be
+ included in the analysis. You can also specify modules to be excluded
+ from the analysis.</p>
<p>If you are testing a distributed Erlang application, it is
likely that code you want included in the code coverage analysis
- gets executed on an Erlang node other than the one Common Test
- is running on. If this is the case you need to specify these
- other nodes in the cover specification file or add them
- dynamically to the code coverage set of nodes. See the
- <c>ct_cover</c> page in the reference manual for details on the
- latter.</p>
+ gets executed on another Erlang node than the one <c>Common Test</c>
+ is running on. If so, you must specify these other nodes in the
+ cover specification file or add them dynamically to the code coverage
+ set of nodes. For details on the latter, see module
+ <seealso marker="ct_cover"><c>ct_cover</c></seealso>.</p>
<p>In the cover specification file you can also specify your
required level of the code coverage analysis; <c>details</c> or
<c>overview</c>. In detailed mode, you get a coverage overview
- page, showing you per module and total coverage percentages, as
- well as one HTML file printed for each module included in the
- analysis that shows exactly what parts of the code have been
+ page, showing per module and total coverage percentages.
+ You also get an HTML file printed for each module included in the
+ analysis showing exactly what parts of the code have been
executed during the test. In overview mode, only the code
- coverage overview page gets printed.</p>
+ coverage overview page is printed.</p>
<p>You can choose to export and import code coverage data between
tests. If you specify the name of an export file in the cover
- specification file, Common Test will export collected coverage
- data to this file at the end of the test. You may similarly
- specify that previously exported data should be imported and
- included in the analysis for a test (you can specify multiple
- import files). This way it is possible to analyse total code coverage
- without necessarily running all tests at once.</p>
-
- <p>To activate the code coverage support, you simply specify the
- name of the cover specification file as you start Common Test.
- This you do either by using the <c>-cover</c> flag with <c>ct_run</c>.
- Example:</p>
-
- <p><c>$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</c></p>
+ specification file, <c>Common Test</c> exports collected coverage
+ data to this file at the end of the test. You can similarly
+ specify previously exported data to be imported and
+ included in the analysis for a test (multiple import files can be specified).
+ This way, the total code coverage can be analyzed without necessarily
+ running all tests at once.</p>
+
+ <p>To activate the code coverage support, specify the name of the cover
+ specification file as you start <c>Common Test</c>.
+ Do this by using flag <c>-cover</c> with
+ <seealso marker="ct_run"><c>ct_run</c></seealso>,
+ for example:</p>
+ <pre>
+ $ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</pre>
- <p>You may also pass the cover specification file name in a
- call to <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, by adding a <c>{cover,CoverSpec}</c>
- tuple to the <c>Opts</c> argument. Also, you can of course
- enable code coverage in your test specifications (read
- more in the chapter about
- <seealso marker="run_test_chapter#test_specifications">using test
- specifications</seealso>).</p>
+ <p>You can also pass the cover specification file name in a
+ call to <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>,
+ by adding a <c>{cover,CoverSpec}</c> tuple to argument <c>Opts</c>.</p>
+ <p>You can also enable code coverage in your test specifications (see section
+ <seealso marker="run_test_chapter#test_specifications">Test Specifications</seealso>
+ in section Running Tests and Analyzing Results).</p>
</section>
<section>
<marker id="cover_stop"></marker>
- <title>Stopping the cover tool when tests are completed</title>
- <p>By default the Cover tool is automatically stopped when the
- tests are completed. This causes the original (non cover
- compiled) modules to be loaded back in to the test node. If a
- process at this point is still running old code of any of the
+ <title>Stopping the Cover Tool When Tests Are Completed</title>
+ <p>By default, the Cover tool is automatically stopped when the
+ tests are completed. This causes the original (non-cover
+ compiled) modules to be loaded back into the test node. If a
+ process at this point still runs old code of any of the
modules that are cover compiled, meaning that it has not done
any fully qualified function call after the cover compilation,
- the process will now be killed. To avoid this it is possible to
- set the value of the <c>cover_stop</c> option to
- <c>false</c>. This means that the modules will stay cover
- compiled, and it is therefore only recommended if the erlang
- node(s) under test is terminated after the test is completed
- or if cover can be manually stopped.</p>
-
- <p>The option can be set by using the <c>-cover_stop</c> flag with
- <c>ct_run</c>, by adding <c>{cover_stop,true|false}</c> to the
- Opts argument to <seealso
- marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, or by adding
- a <c>cover_stop</c> term in your test specification (see chapter
- about <seealso
- marker="run_test_chapter#test_specifications">test
- specifications</seealso>).</p>
+ the process is killed. To avoid this, set the value of option
+ <c>cover_stop</c> to <c>false</c>. This means that the
+ modules stay cover compiled. Therefore, this is only recommended
+ if the Erlang nodes under test are terminated after the test is
+ completed, or if cover can be manually stopped.</p>
+
+ <p>The option can be set by using flag <c>-cover_stop</c> with
+ <c>ct_run</c>, by adding <c>{cover_stop,true|false}</c> to argument
+ <c>Opts</c> to
+ <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>,
+ or by adding a <c>cover_stop</c> term in the test specification (see section
+ <seealso marker="run_test_chapter#test_specifications">Test Specifications</seealso>
+ in section Running Tests and Analyzing Results).</p>
</section>
<section>
- <title>The cover specification file</title>
- <p>These are the terms allowed in a cover specification file:</p>
+ <title>The Cover Specification File</title>
+ <p>The following terms are allowed in a cover specification file:</p>
<pre>
- %% List of Nodes on which cover will be active during test.
- %% Nodes = [atom()]
- {nodes, Nodes}.
-
- %% Files with previously exported cover data to include in analysis.
- %% CoverDataFiles = [string()]
- {import, CoverDataFiles}.
-
- %% Cover data file to export from this session.
- %% CoverDataFile = string()
- {export, CoverDataFile}.
-
- %% Cover analysis level.
- %% Level = details | overview
- {level, Level}.
-
- %% Directories to include in cover.
- %% Dirs = [string()]
- {incl_dirs, Dirs}.
-
- %% Directories, including subdirectories, to include.
- {incl_dirs_r, Dirs}.
-
- %% Specific modules to include in cover.
- %% Mods = [atom()]
- {incl_mods, Mods}.
-
- %% Directories to exclude in cover.
- {excl_dirs, Dirs}.
-
- %% Directories, including subdirectories, to exclude.
- {excl_dirs_r, Dirs}.
-
- %% Specific modules to exclude in cover.
- {excl_mods, Mods}.
-
- %% Cross cover compilation
- %% Tag = atom(), an identifier for a test run
- %% Mod = [atom()], modules to compile for accumulated analysis
- {cross,[{Tag,Mods}]}.
- </pre>
-
- <p>The <c>incl_dirs_r</c> and <c>excl_dirs_r</c> terms tell Common
- Test to search the given directories recursively and include
- or exclude any module found during the search. The
- <c>incl_dirs</c> and <c>excl_dirs</c> terms result in a
- non-recursive search for modules (i.e. only modules found in
- the given directories are included or excluded).</p>
- <p><em>Note:</em> Directories containing Erlang modules that are
- to be included in a code coverage test must exist in the code
- server path, or the cover tool will fail to recompile the modules.
- (It is not sufficient to specify these directories in the cover
- specification file for Common Test).</p>
+ %% List of Nodes on which cover will be active during test.
+ %% Nodes = [atom()]
+ {nodes, Nodes}.
+
+ %% Files with previously exported cover data to include in analysis.
+ %% CoverDataFiles = [string()]
+ {import, CoverDataFiles}.
+
+ %% Cover data file to export from this session.
+ %% CoverDataFile = string()
+ {export, CoverDataFile}.
+
+ %% Cover analysis level.
+ %% Level = details | overview
+ {level, Level}.
+
+ %% Directories to include in cover.
+ %% Dirs = [string()]
+ {incl_dirs, Dirs}.
+
+ %% Directories, including subdirectories, to include.
+ {incl_dirs_r, Dirs}.
+
+ %% Specific modules to include in cover.
+ %% Mods = [atom()]
+ {incl_mods, Mods}.
+
+ %% Directories to exclude in cover.
+ {excl_dirs, Dirs}.
+
+ %% Directories, including subdirectories, to exclude.
+ {excl_dirs_r, Dirs}.
+
+ %% Specific modules to exclude in cover.
+ {excl_mods, Mods}.
+
+ %% Cross cover compilation
+ %% Tag = atom(), an identifier for a test run
+ %% Mod = [atom()], modules to compile for accumulated analysis
+ {cross,[{Tag,Mods}]}.</pre>
+
+ <p>The terms <c>incl_dirs_r</c> and <c>excl_dirs_r</c> tell <c>Common
+ Test</c> to search the specified directories recursively and include
+ or exclude any module found during the search. The terms
+ <c>incl_dirs</c> and <c>excl_dirs</c> result in a
+ non-recursive search for modules (that is, only modules found in
+ the specified directories are included or excluded).</p>
+ <note><p>Directories containing Erlang modules to be included in a code
+ coverage test must exist in the code server path. Otherwise,
+ the Cover tool fails to recompile the modules. It is not sufficient to
+ specify these directories in the cover specification file for
+ <c>Common Test</c>.</p></note>
</section>
<section>
<marker id="cross_cover"/>
- <title>Cross cover analysis</title>
+ <title>Cross Cover Analysis</title>
<p>The cross cover mechanism allows cover analysis of modules
- across multiple tests. It is useful if some code, e.g. a library
- module, is used by many different tests and the accumulated cover
- result is desirable.</p>
+ across multiple tests. It is useful if some code, for example, a
+ library module, is used by many different tests and the accumulated
+ cover result is desirable.</p>
- <p>This can of course also be achieved in a more customized way by
- using the <c>export</c> parameter in the cover specification and
- analysing the result off line, but the cross cover mechanism is a
- build in solution which also provides the logging.</p>
+ <p>This can also be achieved in a more customized way by
+ using parameter <c>export</c> in the cover specification and
+ analysing the result off line. However, the cross cover mechanism is a
+ built-in solution that also provides logging.</p>
- <p>The mechanism is easiest explained via an example:</p>
+ <p>The mechanism is easiest explained by an example:</p>
- <p>Let's say that there are two systems, <c>s1</c> and <c>s2</c>,
- which are tested in separate test runs. System <c>s1</c> contains
- a library module <c>m1</c> which is tested by the <c>s1</c> test
- run and is included in <c>s1</c>'s cover specification:</p>
+ <p>Assume that there are two systems, <c>s1</c> and <c>s2</c>,
+ that are tested in separate test runs. System <c>s1</c> contains
+ a library module <c>m1</c> tested by test run <c>s1</c> and
+ is included in the cover specification of <c>s1</c> as follows:</p>
<code type="none">
-s1.cover:
- {incl_mods,[m1]}.</code>
+ s1.cover:
+ {incl_mods,[m1]}.</code>
<p>When analysing code coverage, the result for <c>m1</c> can be
seen in the cover log in the <c>s1</c> test result.</p>
- <p>Now, let's imagine that since <c>m1</c> is a library module, it
- is also used quite a bit by system <c>s2</c>. The <c>s2</c> test
- run does not specifically test <c>m1</c>, but it might still be
- interesting to see which parts of <c>m1</c> is actually covered by
- the <c>s2</c> tests. To do this, <c>m1</c> could be included also
- in <c>s2</c>'s cover specification:</p>
+ <p>Now, imagine that as <c>m1</c> is a library module, it
+ is also often used by system <c>s2</c>. Test run <c>s2</c>
+ does not specifically test <c>m1</c>, but it can still be
+ interesting to see which parts of <c>m1</c> that are covered
+ by the <c>s2</c> tests. To do this, <c>m1</c> can be included also
+ in the cover specification of <c>s2</c> as follows:</p>
<code type="none">
-s2.cover:
- {incl_mods,[m1]}.</code>
+ s2.cover:
+ {incl_mods,[m1]}.</code>
- <p>This would give an entry for <c>m1</c> also in the cover log
- for the <c>s2</c> test run. The problem is that this would only
- reflect the coverage by <c>s2</c> tests, not the accumulated
- result over <c>s1</c> and <c>s2</c>. And this is where the cross
+ <p>This gives an entry for <c>m1</c> also in the cover log
+ for test run <c>s2</c>. The problem is that this only
+ reflects the coverage by <c>s2</c> tests, not the accumulated
+ result over <c>s1</c> and <c>s2</c>. This is where the cross
cover mechanism comes in handy.</p>
- <p>If instead the cover specification for <c>s2</c> was like
- this:</p>
+ <p>If instead the cover specification for <c>s2</c> is like
+ the following:</p>
<code type="none">
-s2.cover:
- {cross,[{s1,[m1]}]}.</code>
+ s2.cover:
+ {cross,[{s1,[m1]}]}.</code>
- <p>then <c>m1</c> would be cover compiled in the <c>s2</c> test
- run, but not shown in the coverage log. Instead, if
- <c>ct_cover:cross_cover_analyse/2</c> is called after both
- <c>s1</c> and <c>s2</c> test runs are completed, the accumulated
- result for <c>m1</c> would be available in the cross cover log for
- the <c>s1</c> test run.</p>
+ <p>Then <c>m1</c> is cover compiled in test run <c>s2</c>,
+ but not shown in the coverage log. Instead, if
+ <seealso marker="ct_cover#cross_cover_analyse-2"><c>ct_cover:cross_cover_analyse/2</c></seealso>
+ is called after both <c>s1</c> and <c>s2</c> test runs are completed,
+ the accumulated result for <c>m1</c> is available in the cross cover
+ log for test run <c>s1</c>.</p>
- <p>The call to the analyse function must be like this:</p>
+ <p>The call to the analyze function must be as follows:</p>
<code type="none">
-ct_cover:cross_cover_analyse(Level, [{s1,S1LogDir},{s2,S2LogDir}]).</code>
+ ct_cover:cross_cover_analyse(Level, [{s1,S1LogDir},{s2,S2LogDir}]).</code>
- <p>where <c>S1LogDir</c> and <c>S2LogDir</c> are the directories
+ <p>Here, <c>S1LogDir</c> and <c>S2LogDir</c> are the directories
named <c>&lt;TestName&gt;.logs</c> for each test respectively.</p>
- <p>Note the tags <c>s1</c> and <c>s2</c> which are used in the
+ <p>Notice the tags <c>s1</c> and <c>s2</c>, which are used in the
cover specification file and in the call to
- <c>ct_cover:cross_cover_analyse/2</c>. The point of these are only
+ <c>ct_cover:cross_cover_analyse/2</c>. The purpose of these is only
to map the modules specified in the cover specification to the log
- directory specified in the call to the analyse function. The name
- of the tag has no meaning beyond this.</p>
+ directory specified in the call to the analyze function. The tag name
+ has no meaning beyond this.</p>
</section>
<section>
<title>Logging</title>
<p>To view the result of a code coverage test, click the button
- labled "COVER LOG" in the top level index page for the test run.</p>
+ labeled "COVER LOG" in the top-level index page for the test run.</p>
- <p>Prior to Erlang/OTP 17.1, if your test run consisted of
+ <p>Before Erlang/OTP 17.1, if your test run consisted of
multiple tests, cover would be started and stopped for each test
- within the test run. Separate logs would be available via the
+ within the test run. Separate logs would be available through the
"Coverage log" link on the test suite result pages. These links
are still available, but now they all point to the same page as
- the button on the top level index page. The log contains the
- accumulated results for the complete test run. See the release
- notes for more information about this change.</p>
+ the button on the top-level index page. The log contains the
+ accumulated results for the complete test run. For details about
+ this change, see the release notes.</p>
- <p>The buttonc takes you to the code coverage overview page. If you
- have successfully performed a detailed coverage analysis, you
- find links to each individual module coverage page here.</p>
+ <p>The button takes you to the code coverage overview page. If you
+ have successfully performed a detailed coverage analysis,
+ links to each individual module coverage page are found here.</p>
- <p>If cross cover analysis has been performed, and there are
- accumulated coverage results for the current test, then the -
- "Coverdata collected over all tests" link will take you to these
+ <p>If cross cover analysis is performed, and there are
+ accumulated coverage results for the current test, the link
+ "Coverdata collected over all tests" takes you to these
results.</p>
</section>
diff --git a/lib/common_test/doc/src/ct.xml b/lib/common_test/doc/src/ct.xml
new file mode 100644
index 0000000000..b6c862c233
--- /dev/null
+++ b/lib/common_test/doc/src/ct.xml
@@ -0,0 +1,1415 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct.xml</file>
+ </header>
+ <module>ct</module>
+ <modulesummary>Main user interface for the Common Test framework.</modulesummary>
+
+ <description>
+
+ <p>Main user interface for the <c>Common Test</c> framework.</p>
+
+ <p>This module implements the command-line interface for running
+ tests and basic functions for <c>Common Test</c> case issues, such as
+ configuration and logging.</p>
+
+ <p><em>Test Suite Support Macros</em></p>
+
+ <p>The <c>config</c> macro is defined in <c>ct.hrl</c>. This macro is
+ to be used to retrieve information from the <c>Config</c> variable sent
+ to all test cases. It is used with two arguments; the first is the name
+ of the configuration variable to retrieve, the second is the
+ <c>Config</c> variable supplied to the test case.</p>
+
+ <p>Possible configuration variables include:</p>
+
+ <list type="bulleted">
+ <item><p><c>data_dir</c> - Data file directory</p></item>
+ <item><p><c>priv_dir</c> - Scratch file directory</p></item>
+ <item><p>Whatever added by
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>
+ or
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
+ in the test suite.</p></item>
+ </list>
+
+ </description>
+
+ <section>
+ <title>Data Types</title>
+ <marker id="types"/>
+ <taglist>
+
+ <tag><c>handle() = pid()</c></tag>
+ <item><marker id="type-handle"/>
+ <p>The identity (handle) of a connection.</p></item>
+
+ <tag><c>target_name() = atom()</c></tag>
+ <item><marker id="type-target_name"/>
+ <p>A name and association to configuration data introduced
+ through a require statement, or a call to
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>,
+ for example,
+ <c>ct:require(mynodename,{node,[telnet]})</c>.</p></item>
+
+ </taglist>
+ </section>
+
+ <funcs>
+ <func>
+ <name>abort_current_testcase(Reason) -&gt; ok | {error, ErrorReason}</name>
+ <fsummary>Aborts the currently executing test case.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ <v>ErrorReason = no_testcase_running | parallel_group</v>
+ </type>
+ <desc><marker id="abort_current_testcase-1"/>
+ <p>Aborts the currently executing test case. The user must know with
+ certainty which test case is currently executing. The function is
+ therefore only safe to call from a function that has been called
+ (or synchronously invoked) by the test case.</p>
+
+ <p><c>Reason</c>, the reason for aborting the test case, is printed
+ in the test case log.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>add_config(Callback, Config) -&gt; ok | {error, Reason}</name>
+ <fsummary>Loads configuration variables using the specified callback
+ module and configuration string.</fsummary>
+ <type>
+ <v>Callback = atom()</v>
+ <v>Config = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="add_config-2"/>
+ <p>Loads configuration variables using the specified callback module and
+ configuration string. The callback module is to be either loaded or
+ present in the code part. Loaded configuration variables can later
+ be removed using function
+ <seealso marker="#remove_config-2"><c>ct:remove_config/2</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>break(Comment) -&gt; ok | {error, Reason}</name>
+ <fsummary>Cancels any active timetrap and pause the execution of the
+ current test case until the user calls function continue/0.</fsummary>
+ <type>
+ <v>Comment = string()</v>
+ <v>Reason = {multiple_cases_running, TestCases} | 'enable break with release_shell option'</v>
+ <v>TestCases = [atom()]</v>
+ </type>
+ <desc><marker id="break-1"/>
+ <p>Cancels any active timetrap and pauses the execution of the
+ current test case until the user calls function <c>continue/0</c>.
+ The user can then interact with the Erlang node running the tests,
+ for example, for debugging purposes or for manually executing a
+ part of the test case. If a parallel group is executing,
+ <seealso marker="#break-2"><c>ct:break/2</c></seealso> is to be
+ called instead.</p>
+ <p>A cancelled timetrap is not automatically reactivated after the
+ break, but must be started exlicitly with
+ <seealso marker="#timetrap-1"><c>ct:timetrap/1</c></seealso>.</p>
+ <p>In order for the break/continue functionality to work, <c>Common
+ Test</c> must release the shell process controlling <c>stdin</c>.
+ This is done by setting start option <c>release_shell</c>
+ to <c>true</c>. For details, see section
+ <seealso marker="run_test_chapter#erlang_shell_or_program">Running
+ Tests from the Erlang Shell or from an Erlang Program</seealso>
+ in the User's Guide.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>break(TestCase, Comment) -&gt; ok | {error, Reason}</name>
+ <fsummary>Works the same way as break/1, only argument TestCase makes it
+ possible to pause a test case executing in a parallel group.</fsummary>
+ <type>
+ <v>TestCase = atom()</v>
+ <v>Comment = string()</v>
+ <v>Reason = 'test case not running' | 'enable break with release_shell option'</v>
+ </type>
+ <desc><marker id="break-2"/>
+ <p>Works the same way as
+ <seealso marker="#break-1"><c>ct:break/1</c></seealso>, only
+ argument <c>TestCase</c> makes it possible to pause a test case
+ executing in a parallel group. Function
+ <seealso marker="#continue-1"><c>ct:continue/1</c></seealso> is to
+ be used to resume execution of <c>TestCase</c>.</p>
+
+ <p>For details, see
+ <seealso marker="#break/1"><c>ct:break/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>capture_get() -&gt; ListOfStrings</name>
+ <fsummary>Equivalent to capture_get([default]).</fsummary>
+ <type>
+ <v>ListOfStrings = [string()]</v>
+ </type>
+ <desc><marker id="capture_get-0"/>
+ <p>Equivalent to
+ <seealso marker="#capture_get-1">ct:capture_get([default])</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>capture_get(ExclCategories) -&gt; ListOfStrings</name>
+ <fsummary>Returns and purges the list of text strings buffered during
+ the latest session of capturing printouts to stdout.</fsummary>
+ <type>
+ <v>ExclCategories = [atom()]</v>
+ <v>ListOfStrings = [string()]</v>
+ </type>
+ <desc><marker id="capture_get-1"/>
+ <p>Returns and purges the list of text strings buffered during the
+ latest session of capturing printouts to <c>stdout</c>. Log
+ categories that are to be ignored in <c>ListOfStrings</c> can be
+ specified with <c>ExclCategories</c>.
+ If <c>ExclCategories = []</c>, no filtering takes place.</p>
+
+ <p>See also
+ <seealso marker="#capture_start-0"><c>ct:capture_start/0</c></seealso>,
+ <seealso marker="#capture_stop-0"><c>ct:capture_stop/0</c></seealso>,
+ <seealso marker="#log-3"><c>ct:log/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>capture_start() -&gt; ok</name>
+ <fsummary>Starts capturing all text strings printed to stdout
+ during execution of the test case.</fsummary>
+ <desc><marker id="capture_start-0"/>
+ <p>Starts capturing all text strings printed to <c>stdout</c>
+ during execution of the test case.</p>
+
+ <p>See also
+ <seealso marker="#capture_get-1"><c>ct:capture_get/1</c></seealso>,
+ <seealso marker="#capture_stop-0"><c>ct:capture_stop/0</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>capture_stop() -&gt; ok</name>
+ <fsummary>Stops capturing text strings (a session started with
+ capture_start/0).</fsummary>
+ <desc><marker id="capture_stop-0"/>
+ <p>Stops capturing text strings (a session started with
+ <c>capture_start/0</c>).</p>
+
+ <p>See also
+ <seealso marker="#capture_get-1"><c>ct:capture_get/1</c></seealso>,
+ <seealso marker="#capture_start-0"><c>ct:capture_start/0</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>comment(Comment) -&gt; ok</name>
+ <fsummary>Prints the specified Comment in the comment field in the
+ table on the test suite result page.</fsummary>
+ <type>
+ <v>Comment = term()</v>
+ </type>
+ <desc><marker id="comment-1"/>
+ <p>Prints the specified <c>Comment</c> in the comment field in the
+ table on the test suite result page.</p>
+
+ <p>If called several times, only the last comment is printed. The
+ test case return value <c>{comment,Comment}</c> overwrites the
+ string set by this function.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>comment(Format, Args) -&gt; ok</name>
+ <fsummary>Prints the formatted string in the comment field in the
+ table on the test suite result page.</fsummary>
+ <type>
+ <v>Format = string()</v>
+ <v>Args = list()</v>
+ </type>
+ <desc><marker id="comment-2"/>
+ <p>Prints the formatted string in the comment field in the table
+ on the test suite result page.</p>
+
+ <p>Arguments <c>Format</c> and <c>Args</c> are used in a call to
+ <c>io_lib:format/2</c> to create the comment string. The behavior
+ of <c>comment/2</c> is otherwise the same as function
+ <seealso marker="#comment-1"><c>ct:comment/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>continue() -&gt; ok</name>
+ <fsummary>This function must be called to continue after a test
+ case (not executing in a parallel group) has called break/1.</fsummary>
+ <desc><marker id="continue-0"/>
+ <p>This function must be called to continue after a test case
+ (not executing in a parallel group) has called function
+ <seealso marker="#break-1"><c>ct:break/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>continue(TestCase) -&gt; ok</name>
+ <fsummary>This function must be called to continue after a test case
+ has called break/2.</fsummary>
+ <type>
+ <v>TestCase = atom()</v>
+ </type>
+ <desc><marker id="continue-1"/>
+ <p>This function must be called to continue after a test case has
+ called <seealso marker="#break-2"><c>ct:break/2</c></seealso>.
+ If the paused test case, <c>TestCase</c>, executes in a parallel
+ group, this function, rather than <c>continue/0</c>, must be used
+ to let the test case proceed.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>decrypt_config_file(EncryptFileName, TargetFileName) -&gt; ok | {error, Reason}</name>
+ <fsummary>Decrypts EncryptFileName, previously generated with
+ encrypt_config_file/2,3.</fsummary>
+ <type>
+ <v>EncryptFileName = string()</v>
+ <v>TargetFileName = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="decrypt_config_file-2"/>
+ <p>Decrypts <c>EncryptFileName</c>, previously generated with
+ <seealso marker="#encrypt_config_file-2"><c>ct:encrypt_config_file/2,3</c></seealso>.
+ The original file contents is saved in the target file. The
+ encryption key, a string, must be available in a text file named
+ <c>.ct_config.crypt</c>, either in the current directory, or the
+ home directory of the user (it is searched for in that order).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Decrypts EncryptFileName, previously generated with
+ encrypt_config_file/2,3.</fsummary>
+ <type>
+ <v>EncryptFileName = string()</v>
+ <v>TargetFileName = string()</v>
+ <v>KeyOrFile = {key, string()} | {file, string()}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="decrypt_config_file-3"/>
+ <p>Decrypts <c>EncryptFileName</c>, previously generated with
+ <seealso marker="#encrypt_config_file-2"><c>ct:encrypt_config_file/2,3</c></seealso>.
+ The original file contents is saved in the target file. The key
+ must have the same value as that used for encryption.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>encrypt_config_file(SrcFileName, EncryptFileName) -&gt; ok | {error, Reason}</name>
+ <fsummary>Encrypts the source configuration file with DES3 and saves the
+ result in file EncryptFileName.</fsummary>
+ <type>
+ <v>SrcFileName = string()</v>
+ <v>EncryptFileName = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="encrypt_config_file-2"/>
+ <p>Encrypts the source configuration file with DES3 and saves the result
+ in file <c>EncryptFileName</c>. The key, a string, must be
+ available in a text file named <c>.ct_config.crypt</c>, either
+ in the current directory, or the home directory of the user (it
+ is searched for in that order).</p>
+
+ <p>For information about using encrypted configuration files when
+ running tests, see section
+ <seealso marker="config_file_chapter#encrypted_config_files">Encrypted
+ Configuration Files</seealso> in the User's Guide.</p>
+
+ <p>For details on DES3 encryption/decryption, see application
+ <seealso marker="crypto:index"><c>Crypto</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Encrypts the source configuration file with DES3 and saves the
+ result in the target file EncryptFileName.</fsummary>
+ <type>
+ <v>SrcFileName = string()</v>
+ <v>EncryptFileName = string()</v>
+ <v>KeyOrFile = {key, string()} | {file, string()}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="encrypt_config_file-3"/>
+ <p>Encrypts the source configuration file with DES3 and saves the result
+ in the target file <c>EncryptFileName</c>. The encryption key
+ to use is either the value in <c>{key,Key}</c> or the value
+ stored in the file specified by <c>{file,File}</c>.</p>
+
+ <p>For information about using encrypted configuration files when
+ running tests, see section
+ <seealso marker="config_file_chapter#encrypted_config_files">Encrypted
+ Configuration Files</seealso> in the User's Guide.</p>
+
+ <p>For details on DES3 encryption/decryption, see application
+ <seealso marker="crypto:index"><c>Crypto</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>fail(Reason) -&gt; ok</name>
+ <fsummary>Terminates a test case with the specified error
+ Reason.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="fail-1"/>
+ <p>Terminates a test case with the specified error <c>Reason</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>fail(Format, Args) -&gt; ok</name>
+ <fsummary>Terminates a test case with an error message specified by
+ a format string and a list of values (used as arguments to
+ io_lib:format/2).</fsummary>
+ <type>
+ <v>Format = string()</v>
+ <v>Args = list()</v>
+ </type>
+ <desc><marker id="fail-2"/>
+ <p>Terminates a test case with an error message specified by a
+ format string and a list of values (used as arguments to
+ <c>io_lib:format/2</c>).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_config(Required) -&gt; Value</name>
+ <fsummary>Equivalent to get_config(Required, undefined, []).</fsummary>
+ <desc><marker id="get_config-1"/>
+ <p>Equivalent to <seealso marker="#get_config-3"><c>ct:get_config(Required,
+ undefined, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_config(Required, Default) -&gt; Value</name>
+ <fsummary>Equivalent to get_config(Required, Default, []).</fsummary>
+ <desc><marker id="get_config-2"/>
+ <p>Equivalent to <seealso marker="#get_config-3"><c>ct:get_config(Required,
+ Default, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_config(Required, Default, Opts) -&gt; ValueOrElement</name>
+ <fsummary>Reads configuration data values.</fsummary>
+ <type>
+ <v>Required = KeyOrName | {KeyOrName, SubKey} | {KeyOrName, SubKey, SubKey}</v>
+ <v>KeyOrName = atom()</v>
+ <v>SubKey = atom()</v>
+ <v>Default = term()</v>
+ <v>Opts = [Opt] | []</v>
+ <v>Opt = element | all</v>
+ <v>ValueOrElement = term() | Default</v>
+ </type>
+ <desc><marker id="get_config-3"/>
+ <p>Reads configuration data values.</p>
+
+ <p>Returns the matching values or configuration elements, given a
+ configuration variable key or its associated name (if one has been
+ specified with
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>
+ or a <c>require</c> statement).</p>
+
+ <p><em>Example:</em></p>
+
+ <p>Given the following configuration file:</p>
+
+ <pre>
+ {unix,[{telnet,IpAddr},
+ {user,[{username,Username},
+ {password,Password}]}]}.</pre>
+
+ <p>Then:</p>
+
+ <pre>
+ ct:get_config(unix,Default) -&gt; [{telnet,IpAddr},
+ {user, [{username,Username}, {password,Password}]}]
+ ct:get_config({unix,telnet},Default) -&gt; IpAddr
+ ct:get_config({unix,user,username},Default) -&gt; Username
+ ct:get_config({unix,ftp},Default) -&gt; Default
+ ct:get_config(unknownkey,Default) -&gt; Default</pre>
+
+ <p>If a configuration variable key has been associated with a name (by
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>
+ or a <c>require</c> statement), the name can be used instead
+ of the key to read the value:</p>
+
+ <pre>
+ ct:require(myuser,{unix,user}) -&gt; ok.
+ ct:get_config(myuser,Default) -&gt; [{username,Username}, {password,Password}]</pre>
+
+ <p>If a configuration variable is defined in multiple files, use option
+ <c>all</c> to access all possible values. The values are returned
+ in a list. The order of the elements corresponds to the order
+ that the configuration files were specified at startup.</p>
+
+ <p>If configuration elements (key-value tuples) are to be returned as
+ result instead of values, use option <c>element</c>. The
+ returned elements are then on the form <c>{Required,Value}</c>.</p>
+
+ <p>See also
+ <seealso marker="#get_config-1"><c>ct:get_config/1</c></seealso>,
+ <seealso marker="#get_config-2"><c>ct:get_config/2</c></seealso>,
+ <seealso marker="#require-1"><c>ct:require/1</c></seealso>,
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_event_mgr_ref() -&gt; EvMgrRef</name>
+ <fsummary>Gets a reference to the <c>Common Test</c> event manager.</fsummary>
+ <type>
+ <v>EvMgrRef = atom()</v>
+ </type>
+ <desc><marker id="get_event_mgr_ref-0"/>
+ <p>Gets a reference to the <c>Common Test</c> event manager.
+ The reference can be used to, for example, add a user-specific
+ event handler while tests are running.</p>
+
+ <p><em>Example:</em></p>
+
+ <pre>
+ gen_event:add_handler(ct:get_event_mgr_ref(), my_ev_h, [])</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_status() -&gt; TestStatus | {error, Reason} | no_tests_running</name>
+ <fsummary>Returns status of ongoing test.</fsummary>
+ <type>
+ <v>TestStatus = [StatusElem]</v>
+ <v>StatusElem = {current, TestCaseInfo} | {successful, Successful} | {failed, Failed} | {skipped, Skipped} | {total, Total}</v>
+ <v>TestCaseInfo = {Suite, TestCase} | [{Suite, TestCase}]</v>
+ <v>Suite = atom()</v>
+ <v>TestCase = atom()</v>
+ <v>Successful = integer()</v>
+ <v>Failed = integer()</v>
+ <v>Skipped = {UserSkipped, AutoSkipped}</v>
+ <v>UserSkipped = integer()</v>
+ <v>AutoSkipped = integer()</v>
+ <v>Total = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="get_status-0"/>
+ <p>Returns status of ongoing test. The returned list contains
+ information about which test case is executing (a list of cases
+ when a parallel test case group is executing), as well as
+ counters for successful, failed, skipped, and total test cases
+ so far.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_target_name(Handle) -&gt; {ok, TargetName} | {error, Reason}</name>
+ <fsummary>Returns the name of the target that the specified connection
+ belongs to.</fsummary>
+ <type>
+ <v>Handle = handle()</v>
+ <v>TargetName = target_name()</v>
+ </type>
+ <desc><marker id="get_target_name-1"/>
+ <p>Returns the name of the target that the specified connection
+ belongs to.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_testspec_terms() -&gt; TestSpecTerms | undefined</name>
+ <fsummary>Gets a list of all test specification terms used to
+ configure and run this test.</fsummary>
+ <type>
+ <v>TestSpecTerms = [{Tag, Value}]</v>
+ <v>Value = [term()]</v>
+ </type>
+ <desc><marker id="get_testspec_terms-0"/>
+ <p>Gets a list of all test specification terms used to configure
+ and run this test.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_testspec_terms(Tags) -&gt; TestSpecTerms | undefined</name>
+ <fsummary>Reads one or more terms from the test specification used to
+ configure and run this test.</fsummary>
+ <type>
+ <v>Tags = [Tag] | Tag</v>
+ <v>Tag = atom()</v>
+ <v>TestSpecTerms = [{Tag, Value}] | {Tag, Value}</v>
+ <v>Value = [{Node, term()}] | [term()]</v>
+ <v>Node = atom()</v>
+ </type>
+ <desc><marker id="get_testspec_terms-1"/>
+ <p>Reads one or more terms from the test specification used to
+ configure and run this test. <c>Tag</c> is any valid test
+ specification tag, for example, <c>label</c>, <c>config</c>, or
+ <c>logdir</c>. User-specific terms are also available to read if
+ option <c>allow_user_terms</c> is set.</p>
+ <p>All value tuples returned, except user terms, have the node
+ name as first element.</p>
+ <p>To read test terms, use <c>Tag = tests</c> (rather than
+ <c>suites</c>, <c>groups</c>, or <c>cases</c>). <c>Value</c> is
+ then the list of <em>all</em> tests on the form
+ <c>[{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...]</c>, where
+ <c>GroupsAndCases = [{Group,[Case]}] | [Case]</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_timetrap_info() -&gt; {Time, {Scaling,ScaleVal}}</name>
+ <fsummary>Reads information about the timetrap set for the current
+ test case.</fsummary>
+ <type>
+ <v>Time = integer() | infinity</v>
+ <v>Scaling = true | false</v>
+ <v>ScaleVal = integer()</v>
+ </type>
+ <desc><marker id="get_timetrap_info-0"/>
+ <p>Reads information about the timetrap set for the current test
+ case. <c>Scaling</c> indicates if <c>Common Test</c> will attempt
+ to compensate timetraps automatically for runtime delays
+ introduced by, for example, tools like cover. <c>ScaleVal</c> is
+ the value of the current scaling multipler (always 1 if scaling is
+ disabled). Note the <c>Time</c> is not the scaled result.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>install(Opts) -&gt; ok | {error, Reason}</name>
+ <fsummary>Installs configuration files and event handlers.</fsummary>
+ <type>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {config, ConfigFiles} | {event_handler, Modules} | {decrypt, KeyOrFile}</v>
+ <v>ConfigFiles = [ConfigFile]</v>
+ <v>ConfigFile = string()</v>
+ <v>Modules = [atom()]</v>
+ <v>KeyOrFile = {key, Key} | {file, KeyFile}</v>
+ <v>Key = string()</v>
+ <v>KeyFile = string()</v>
+ </type>
+ <desc><marker id="install-1"/>
+ <p>Installs configuration files and event handlers.</p>
+
+ <p>Run this function once before the first test.</p>
+
+ <p><em>Example:</em></p>
+
+ <pre>
+ install([{config,["config_node.ctc","config_user.ctc"]}])</pre>
+
+ <p>This function is automatically run by program <c>ct_run</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>listenv(Telnet) -&gt; [Env]</name>
+ <fsummary>Performs command listenv on the specified Telnet connection
+ and returns the result as a list of key-value pairs.</fsummary>
+ <type>
+ <v>Telnet = term()</v>
+ <v>Env = {Key, Value}</v>
+ <v>Key = string()</v>
+ <v>Value = string()</v>
+ </type>
+ <desc><marker id="listenv-1"/>
+ <p>Performs command <c>listenv</c> on the specified Telnet connection
+ and returns the result as a list of key-value pairs.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>log(Format) -&gt; ok</name>
+ <fsummary>Equivalent to log(default, 50, Format, [], []).</fsummary>
+ <desc><marker id="log-1"/>
+ <p>Equivalent to
+ <seealso marker="#log-5"><c>ct:log(default, 50, Format, [], [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>log(X1, X2) -&gt; ok</name>
+ <fsummary>Equivalent to log(Category, Importance, Format,
+ FormatArgs, []).</fsummary>
+ <type>
+ <v>X1 = Category | Importance | Format</v>
+ <v>X2 = Format | FormatArgs</v>
+ </type>
+ <desc><marker id="log-2"/>
+ <p>Equivalent to <seealso marker="#log-5"><c>ct:log(Category,
+ Importance, Format, FormatArgs, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>log(X1, X2, X3) -&gt; ok</name>
+ <fsummary>Equivalent to log(Category, Importance, Format,
+ FormatArgs, Opts).</fsummary>
+ <type>
+ <v>X1 = Category | Importance</v>
+ <v>X2 = Importance | Format</v>
+ <v>X3 = Format | FormatArgs | Opts</v>
+ </type>
+ <desc><marker id="log-3"/>
+ <p>Equivalent to <seealso marker="#log-5"><c>ct:log(Category,
+ Importance, Format, FormatArgs, Opts)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>log(X1, X2, X3, X4) -&gt; ok</name>
+ <fsummary>Equivalent to log(Category, Importance, Format,
+ FormatArgs, Opts).</fsummary>
+ <type>
+ <v>X1 = Category | Importance</v>
+ <v>X2 = Importance | Format</v>
+ <v>X3 = Format | FormatArgs</v>
+ <v>X4 = FormatArgs | Opts</v>
+ </type>
+ <desc><marker id="log-4"/>
+ <p>Equivalent to <seealso marker="#log-5"><c>ct:log(Category,
+ Importance, Format, FormatArgs, Opts)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>log(Category, Importance, Format, FormatArgs, Opts) -&gt; ok</name>
+ <fsummary>Prints from a test case to the log file.</fsummary>
+ <type>
+ <v>Category = atom()</v>
+ <v>Importance = integer()</v>
+ <v>Format = string()</v>
+ <v>FormatArgs = list()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = no_css | esc_chars</v>
+ </type>
+ <desc><marker id="log-5"/>
+ <p>Prints from a test case to the log file.</p>
+
+ <p>This function is meant for printing a string directly from a
+ test case to the test case log file.</p>
+
+ <p>Default <c>Category</c> is <c>default</c>,
+ default <c>Importance</c> is <c>?STD_IMPORTANCE</c>,
+ and default value for <c>FormatArgs</c> is <c>[]</c>.</p>
+
+ <p>For details on <c>Category</c>, <c>Importance</c> and the <c>no_css</c>
+ option, see section <seealso marker="write_test_chapter#logging">
+ Logging - Categories and Verbosity Levels</seealso> in the User's Guide.</p>
+
+ <p>Common Test will not escape special HTML characters (&lt;, &gt; and &amp;)
+ in the text printed with this function, unless the <c>esc_chars</c>
+ option is used.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>make_priv_dir() -&gt; ok | {error, Reason}</name>
+ <fsummary>If the test has been started with option create_priv_dir
+ set to manual_per_tc, in order for the test case to use the private
+ directory, it must first create it by calling this function.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="make_priv_dir-0"/>
+ <p>If the test is started with option <c>create_priv_dir</c>
+ set to <c>manual_per_tc</c>, in order for the test case to use
+ the private directory, it must first create it by calling this
+ function.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>notify(Name, Data) -&gt; ok</name>
+ <fsummary>Sends an asynchronous notification of type Name with Data
+ to the <c>Common Test</c> event manager.</fsummary>
+ <type>
+ <v>Name = atom()</v>
+ <v>Data = term()</v>
+ </type>
+ <desc><marker id="notify-2"/>
+ <p>Sends an asynchronous notification of type <c>Name</c> with
+ <c>Data</c>to the Common Test event manager. This can later be
+ caught by any installed event manager.</p>
+
+ <p>See also
+ <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pal(Format) -&gt; ok</name>
+ <fsummary>Equivalent to pal(default, 50, Format, []).</fsummary>
+ <desc><marker id="pal-1"/>
+ <p>Equivalent to
+ <seealso marker="#pal-4"><c>ct:pal(default, 50, Format,
+ [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pal(X1, X2) -&gt; ok</name>
+ <fsummary>Equivalent to pal(Category, Importance, Format,
+ FormatArgs).</fsummary>
+ <type>
+ <v>X1 = Category | Importance | Format</v>
+ <v>X2 = Format | FormatArgs</v>
+ </type>
+ <desc><marker id="pal-2"/>
+ <p>Equivalent to <seealso marker="#pal-4"><c>ct:pal(Category,
+ Importance, Format, FormatArgs)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pal(X1, X2, X3) -&gt; ok</name>
+ <fsummary>Equivalent to pal(Category, Importance, Format,
+ FormatArgs).</fsummary>
+ <type>
+ <v>X1 = Category | Importance</v>
+ <v>X2 = Importance | Format</v>
+ <v>X3 = Format | FormatArgs</v>
+ </type>
+ <desc><marker id="pal-3"/>
+ <p>Equivalent to <seealso marker="#pal-4"><c>ct:pal(Category,
+ Importance, Format, FormatArgs)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pal(Category, Importance, Format, FormatArgs) -&gt; ok</name>
+ <fsummary>Prints and logs from a test case.</fsummary>
+ <type>
+ <v>Category = atom()</v>
+ <v>Importance = integer()</v>
+ <v>Format = string()</v>
+ <v>FormatArgs = list()</v>
+ </type>
+ <desc><marker id="pal-4"/>
+ <p>Prints and logs from a test case.</p>
+
+ <p>This function is meant for printing a string from a test case,
+ both to the test case log file and to the console.</p>
+
+ <p>Default <c>Category</c> is <c>default</c>,
+ default <c>Importance</c> is <c>?STD_IMPORTANCE</c>,
+ and default value for <c>FormatArgs</c> is <c>[]</c>.</p>
+
+ <p>For details on <c>Category</c> and <c>Importance</c>, see section
+ <seealso marker="write_test_chapter#logging">Logging - Categories
+ and Verbosity Levels</seealso> in the User's Guide.</p>
+
+ <p>Note that special characters in the text (&lt;, &gt; and &amp;) will
+ be escaped by Common Test before the text is printed to the log
+ file.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>parse_table(Data) -&gt; {Heading, Table}</name>
+ <fsummary>Parses the printout from an SQL table and returns a list of
+ tuples.</fsummary>
+ <type>
+ <v>Data = [string()]</v>
+ <v>Heading = tuple()</v>
+ <v>Table = [tuple()]</v>
+ </type>
+ <desc><marker id="parse_table-1"/>
+ <p>Parses the printout from an SQL table and returns a list of
+ tuples.</p>
+
+ <p>The printout to parse is typically the result of a <c>select</c>
+ command in SQL. The returned <c>Table</c> is a list of tuples,
+ where each tuple is a row in the table.</p>
+
+ <p><c>Heading</c> is a tuple of strings representing the headings
+ of each column in the table.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>print(Format) -&gt; ok</name>
+ <fsummary>Equivalent to print(default, 50, Format, []).</fsummary>
+ <desc><marker id="print-1"/>
+ <p>Equivalent to <seealso marker="#print-4"><c>ct:print(default,
+ 50, Format, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>print(X1, X2) -&gt; ok</name>
+ <fsummary>Equivalent to print(Category, Importance, Format,
+ FormatArgs).</fsummary>
+ <type>
+ <v>X1 = Category | Importance | Format</v>
+ <v>X2 = Format | FormatArgs</v>
+ </type>
+ <desc><marker id="print-2"/>
+ <p>Equivalent to <seealso marker="#print-4"><c>ct:print(Category,
+ Importance, Format, FormatArgs)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>print(X1, X2, X3) -&gt; ok</name>
+ <fsummary>Equivalent to print(Category, Importance, Format,
+ FormatArgs).</fsummary>
+ <type>
+ <v>X1 = Category | Importance</v>
+ <v>X2 = Importance | Format</v>
+ <v>X3 = Format | FormatArgs</v>
+ </type>
+ <desc><marker id="print-3"/>
+ <p>Equivalent to <seealso marker="#print-4"><c>ct:print(Category,
+ Importance, Format, FormatArgs)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>print(Category, Importance, Format, FormatArgs) -&gt; ok</name>
+ <fsummary>Prints from a test case to the console.</fsummary>
+ <type>
+ <v>Category = atom()</v>
+ <v>Importance = integer()</v>
+ <v>Format = string()</v>
+ <v>FormatArgs = list()</v>
+ </type>
+ <desc><marker id="print-4"/>
+ <p>Prints from a test case to the console.</p>
+
+ <p>This function is meant for printing a string from a test case to
+ the console.</p>
+
+ <p>Default <c>Category</c> is <c>default</c>,
+ default <c>Importance</c> is <c>?STD_IMPORTANCE</c>,
+ and default value for <c>FormatArgs</c> is <c>[]</c>.</p>
+
+ <p>For details on <c>Category</c> and <c>Importance</c>, see section
+ <seealso marker="write_test_chapter#logging">Logging - Categories
+ and Verbosity Levels</seealso> in the User's Guide.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>reload_config(Required) -&gt; ValueOrElement</name>
+ <fsummary>Reloads configuration file containing specified configuration
+ key.</fsummary>
+ <type>
+ <v>Required = KeyOrName | {KeyOrName, SubKey} | {KeyOrName, SubKey, SubKey}</v>
+ <v>KeyOrName = atom()</v>
+ <v>SubKey = atom()</v>
+ <v>ValueOrElement = term()</v>
+ </type>
+ <desc><marker id="reload_config-1"/>
+ <p>Reloads configuration file containing specified configuration key.</p>
+
+ <p>This function updates the configuration data from which the
+ specified configuration variable was read, and returns the (possibly)
+ new value of this variable.</p>
+
+ <p>If some variables were present in the configuration, but are
+ not loaded using this function, they are removed from the
+ configuration table together with their aliases.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>remove_config(Callback, Config) -&gt; ok</name>
+ <fsummary>Removes configuration variables (together with
+ their aliases) that were loaded with specified callback module and
+ configuration string.</fsummary>
+ <type>
+ <v>Callback = atom()</v>
+ <v>Config = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="remove_config-2"/>
+ <p>Removes configuration variables (together wih their aliases)
+ that were loaded with specified callback module and configuration
+ string.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>require(Required) -&gt; ok | {error, Reason}</name>
+ <fsummary>Checks if the required configuration is available.</fsummary>
+ <type>
+ <v>Required = Key | {Key, SubKeys} | {Key, SubKey, SubKeys}</v>
+ <v>Key = atom()</v>
+ <v>SubKeys = SubKey | [SubKey]</v>
+ <v>SubKey = atom()</v>
+ </type>
+ <desc><marker id="require-1"/>
+ <p>Checks if the required configuration is available. Arbitrarily
+ deep tuples can be specified as <c>Required</c>. Only the last
+ element of the tuple can be a list of <c>SubKey</c>s.</p>
+
+ <p><em>Example 1.</em> Require the variable <c>myvar</c>:</p>
+
+ <pre>
+ ok = ct:require(myvar).</pre>
+
+ <p>In this case the configuration file must at least contain:</p>
+
+ <pre>
+ {myvar,Value}.</pre>
+
+ <p><em>Example 2.</em> Require key <c>myvar</c> with subkeys
+ <c>sub1</c> and <c>sub2</c>:</p>
+
+ <pre>
+ ok = ct:require({myvar,[sub1,sub2]}).</pre>
+
+ <p>In this case the configuration file must at least contain:</p>
+
+ <pre>
+ {myvar,[{sub1,Value},{sub2,Value}]}.</pre>
+
+ <p><em>Example 3.</em> Require key <c>myvar</c> with subkey
+ <c>sub1</c> with <c>subsub1</c>:</p>
+
+ <pre>
+ ok = ct:require({myvar,sub1,sub2}).</pre>
+
+ <p>In this case the configuration file must at least contain:</p>
+
+ <pre>
+ {myvar,[{sub1,[{sub2,Value}]}]}.</pre>
+
+ <p>See also
+ <seealso marker="#get_config-1"><c>ct:get_config/1</c></seealso>,
+ <seealso marker="#get_config-2"><c>ct:get_config/2</c></seealso>,
+ <seealso marker="#get_config-3"><c>ct:get_config/3</c></seealso>,
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>require(Name, Required) -&gt; ok | {error, Reason}</name>
+ <fsummary>Checks if the required configuration is available and gives
+ it a name.</fsummary>
+ <type>
+ <v>Name = atom()</v>
+ <v>Required = Key | {Key, SubKey} | {Key, SubKey, SubKey}</v>
+ <v>SubKey = Key</v>
+ <v>Key = atom()</v>
+ </type>
+ <desc><marker id="require-2"/>
+ <p>Checks if the required configuration is available and gives it a
+ name. The semantics for <c>Required</c> is the same as in
+ <seealso marker="#require-1"><c>ct:require/1</c></seealso> except
+ that a list of <c>SubKey</c>s cannot be specified.</p>
+
+ <p>If the requested data is available, the subentry is associated
+ with <c>Name</c> so that the value of the element can be read with
+ <seealso marker="#get_config-1"><c>ct:get_config/1,2</c></seealso>
+ provided <c>Name</c> is used instead of the whole <c>Required</c>
+ term.</p>
+
+ <p><em>Example:</em></p>
+
+ <p>Require one node with a Telnet connection and an FTP connection.
+ Name the node <c>a</c>:</p>
+
+ <pre>
+ ok = ct:require(a,{machine,node}).</pre>
+
+ <p>All references to this node can then use the node name. For
+ example, a file over FTP is fetched like follows:</p>
+
+ <pre>
+ ok = ct:ftp_get(a,RemoteFile,LocalFile).</pre>
+
+ <p>For this to work, the configuration file must at least contain:</p>
+
+ <pre>
+ {machine,[{node,[{telnet,IpAddr},{ftp,IpAddr}]}]}.</pre>
+
+ <note><p>The behavior of this function changed radically in
+ <c>Common Test</c> 1.6.2. To keep some backwards compatability,
+ it is still possible to do:<br/>
+ <c>ct:require(a,{node,[telnet,ftp]}).</c><br/>
+ This associates the name <c>a</c> with the top-level <c>node</c>
+ entry. For this to work, the configuration file must at least
+ contain:<br/>
+ <c>{node,[{telnet,IpAddr},{ftp,IpAddr}]}.</c></p>
+ </note>
+
+ <p>See also
+ <seealso marker="#get_config-1"><c>ct:get_config/1</c></seealso>,
+ <seealso marker="#get_config-2"><c>ct:get_config/2</c></seealso>,
+ <seealso marker="#get_config-3"><c>ct:get_config/3</c></seealso>,
+ <seealso marker="#require-1"><c>ct:require/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run(TestDirs) -&gt; Result</name>
+ <fsummary>Runs all test cases in all suites in the specified
+ directories.</fsummary>
+ <type>
+ <v>TestDirs = TestDir | [TestDir]</v>
+ </type>
+ <desc><marker id="run-1"/>
+ <p>Runs all test cases in all suites in the specified directories.</p>
+
+ <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run(TestDir, Suite) -&gt; Result</name>
+ <fsummary>Runs all test cases in the specified suite.</fsummary>
+ <desc><marker id="run-2"/>
+ <p>Runs all test cases in the specified suite.</p>
+
+ <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run(TestDir, Suite, Cases) -&gt; Result</name>
+ <fsummary>Runs the specified test cases.</fsummary>
+ <type>
+ <v>TestDir = string()</v>
+ <v>Suite = atom()</v>
+ <v>Cases = atom() | [atom()]</v>
+ <v>Result = [TestResult] | {error, Reason}</v>
+ </type>
+ <desc><marker id="run-3"/>
+ <p>Runs the specified test cases.</p>
+
+ <p>Requires that
+ <seealso marker="#install-1"><c>ct:install/1</c></seealso> has been
+ run first.</p>
+
+ <p>Suites (<c>*_SUITE.erl</c>) files must be stored in <c>TestDir</c>
+ or <c>TestDir/test</c>. All suites are compiled when the test is
+ run.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run_test(Opts) -&gt; Result</name>
+ <fsummary>Runs tests as specified by the combination of options in
+ Opts.</fsummary>
+ <type>
+ <v>Opts = [OptTuples]</v>
+ <v>OptTuples = {dir, TestDirs} | {suite, Suites} | {group, Groups} | {testcase, Cases} | {spec, TestSpecs} | {join_specs, Bool} | {label, Label} | {config, CfgFiles} | {userconfig, UserConfig} | {allow_user_terms, Bool} | {logdir, LogDir} | {silent_connections, Conns} | {stylesheet, CSSFile} | {cover, CoverSpecFile} | {cover_stop, Bool} | {step, StepOpts} | {event_handler, EventHandlers} | {include, InclDirs} | {auto_compile, Bool} | {abort_if_missing_suites, Bool} | {create_priv_dir, CreatePrivDir} | {multiply_timetraps, M} | {scale_timetraps, Bool} | {repeat, N} | {duration, DurTime} | {until, StopTime} | {force_stop, ForceStop} | {decrypt, DecryptKeyOrFile} | {refresh_logs, LogDir} | {logopts, LogOpts} | {verbosity, VLevels} | {basic_html, Bool} | {esc_chars, Bool} | {ct_hooks, CTHs} | {enable_builtin_hooks, Bool} | {release_shell, Bool}</v>
+ <v>TestDirs = [string()] | string()</v>
+ <v>Suites = [string()] | [atom()] | string() | atom()</v>
+ <v>Cases = [atom()] | atom()</v>
+ <v>Groups = GroupNameOrPath | [GroupNameOrPath]</v>
+ <v>GroupNameOrPath = [atom()] | atom() | all</v>
+ <v>TestSpecs = [string()] | string()</v>
+ <v>Label = string() | atom()</v>
+ <v>CfgFiles = [string()] | string()</v>
+ <v>UserConfig = [{CallbackMod, CfgStrings}] | {CallbackMod, CfgStrings}</v>
+ <v>CallbackMod = atom()</v>
+ <v>CfgStrings = [string()] | string()</v>
+ <v>LogDir = string()</v>
+ <v>Conns = all | [atom()]</v>
+ <v>CSSFile = string()</v>
+ <v>CoverSpecFile = string()</v>
+ <v>StepOpts = [StepOpt] | []</v>
+ <v>StepOpt = config | keep_inactive</v>
+ <v>EventHandlers = EH | [EH]</v>
+ <v>EH = atom() | {atom(), InitArgs} | {[atom()], InitArgs}</v>
+ <v>InitArgs = [term()]</v>
+ <v>InclDirs = [string()] | string()</v>
+ <v>CreatePrivDir = auto_per_run | auto_per_tc | manual_per_tc</v>
+ <v>M = integer()</v>
+ <v>N = integer()</v>
+ <v>DurTime = string(HHMMSS)</v>
+ <v>StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS)</v>
+ <v>ForceStop = skip_rest | Bool</v>
+ <v>DecryptKeyOrFile = {key, DecryptKey} | {file, DecryptFile}</v>
+ <v>DecryptKey = string()</v>
+ <v>DecryptFile = string()</v>
+ <v>LogOpts = [LogOpt]</v>
+ <v>LogOpt = no_nl | no_src</v>
+ <v>VLevels = VLevel | [{Category, VLevel}]</v>
+ <v>VLevel = integer()</v>
+ <v>Category = atom()</v>
+ <v>CTHs = [CTHModule | {CTHModule, CTHInitArgs}]</v>
+ <v>CTHModule = atom()</v>
+ <v>CTHInitArgs = term()</v>
+ <v>Result = {Ok, Failed, {UserSkipped, AutoSkipped}} | TestRunnerPid | {error, Reason}</v>
+ <v>Ok = integer()</v>
+ <v>Failed = integer()</v>
+ <v>UserSkipped = integer()</v>
+ <v>AutoSkipped = integer()</v>
+ <v>TestRunnerPid = pid()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="run_test-1"/>
+ <p>Runs tests as specified by the combination of options in
+ <c>Opts</c>. The options are the same as those used with program
+ <c>ct_run</c>, see <seealso marker="ct_run#ct_run">Run Tests from
+ Command Line</seealso> in the <c>ct_run</c> manual page.</p>
+ <p>Here a <c>TestDir</c> can be used to point out the path to a
+ <c>Suite</c>. Option <c>testcase</c> corresponds to option
+ <c>-case</c> in program <c>ct_run</c>. Configuration files
+ specified in <c>Opts</c> are installed automatically at startup.</p>
+
+ <p><c>TestRunnerPid</c> is returned if <c>release_shell == true</c>.
+ For details, see
+ <seealso marker="#break-1"><c>ct:break/1</c></seealso>.</p>
+
+ <p><c>Reason</c> indicates the type of error encountered.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run_testspec(TestSpec) -&gt; Result</name>
+ <fsummary>Runs a test specified by TestSpec.</fsummary>
+ <type>
+ <v>TestSpec = [term()]</v>
+ <v>Result = {Ok, Failed, {UserSkipped, AutoSkipped}} | {error, Reason}</v>
+ <v>Ok = integer()</v>
+ <v>Failed = integer()</v>
+ <v>UserSkipped = integer()</v>
+ <v>AutoSkipped = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="run_testspec-1"/>
+ <p>Runs a test specified by <c>TestSpec</c>. The same terms are used
+ as in test specification files.</p>
+
+ <p><c>Reason</c> indicates the type of error encountered.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>sleep(Time) -&gt; ok</name>
+ <fsummary>This function, similar to timer:sleep/1, suspends the
+ test case for a specified time.</fsummary>
+ <type>
+ <v>Time = {hours, Hours} | {minutes, Mins} | {seconds, Secs} | Millisecs | infinity</v>
+ <v>Hours = integer()</v>
+ <v>Mins = integer()</v>
+ <v>Secs = integer()</v>
+ <v>Millisecs = integer() | float()</v>
+ </type>
+ <desc><marker id="sleep-1"/>
+ <p>This function, similar to <c>timer:sleep/1</c> in <c>STDLIB</c>,
+ suspends the test case for a specified time.
+ However, this function also multiplies <c>Time</c> with the
+ <c>multiply_timetraps</c> value (if set) and under certain
+ circumstances also scales up the time automatically if
+ <c>scale_timetraps</c> is set to <c>true</c> (default is
+ <c>false</c>).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>start_interactive() -&gt; ok</name>
+ <fsummary>Starts <c>Common Test</c> in interactive mode.</fsummary>
+ <desc><marker id="start_interactive-0"/>
+ <p>Starts <c>Common Test</c> in interactive mode.</p>
+
+ <p>From this mode, all test case support functions can be executed
+ directly from the Erlang shell. The interactive mode can also be
+ started from the OS command line with <c>ct_run -shell
+ [-config File...]</c>.</p>
+
+ <p>If any functions (for example, Telnet or FTP) using
+ "required configuration data" are to be called from the Erlang shell,
+ configuration data must first be required with
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>.</p>
+
+ <p><em>Example:</em></p>
+
+ <pre>
+ &gt; ct:require(unix_telnet, unix).
+ ok
+ &gt; ct_telnet:open(unix_telnet).
+ {ok,&lt;0.105.0&gt;}
+ &gt; ct_telnet:cmd(unix_telnet, "ls .").
+ {ok,["ls","file1 ...",...]}</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name>step(TestDir, Suite, Case) -&gt; Result</name>
+ <fsummary>Steps through a test case with the debugger.</fsummary>
+ <type>
+ <v>Case = atom()</v>
+ </type>
+ <desc><marker id="step-3"/>
+ <p>Steps through a test case with the debugger.</p>
+
+ <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>step(TestDir, Suite, Case, Opts) -&gt; Result</name>
+ <fsummary>Steps through a test case with the debugger.</fsummary>
+ <type>
+ <v>Case = atom()</v>
+ <v>Opts = [Opt] | []</v>
+ <v>Opt = config | keep_inactive</v>
+ </type>
+ <desc><marker id="step-4"/>
+ <p>Steps through a test case with the debugger. If option
+ <c>config</c> has been specifed, breakpoints are also set on
+ the configuration functions in <c>Suite</c>.</p>
+
+ <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>stop_interactive() -&gt; ok</name>
+ <fsummary>Exits the interactive mode.</fsummary>
+ <desc><marker id="stop_interactive-0"/>
+ <p>Exits the interactive mode.</p>
+
+ <p>See also
+ <seealso marker="#start_interactive-0"><c>ct:start_interactive/0</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>sync_notify(Name, Data) -&gt; ok</name>
+ <fsummary>Sends a synchronous notification of type Name with Data to
+ the <c>Common Test</c> event manager.</fsummary>
+ <type>
+ <v>Name = atom()</v>
+ <v>Data = term()</v>
+ </type>
+ <desc><marker id="sync_notify-2"/>
+ <p>Sends a synchronous notification of type <c>Name</c> with
+ <c>Data</c> to the <c>Common Test</c> event manager. This can later be
+ caught by any installed event manager.</p>
+
+ <p>See also
+ <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>testcases(TestDir, Suite) -&gt; Testcases | {error, Reason}</name>
+ <fsummary>Returns all test cases in the specified suite.</fsummary>
+ <type>
+ <v>TestDir = string()</v>
+ <v>Suite = atom()</v>
+ <v>Testcases = list()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="testcases-2"/>
+ <p>Returns all test cases in the specified suite.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>timetrap(Time) -&gt; ok</name>
+ <fsummary>Sets a new timetrap for the running test case.</fsummary>
+ <type>
+ <v>Time = {hours, Hours} | {minutes, Mins} | {seconds, Secs} | Millisecs | infinity | Func</v>
+ <v>Hours = integer()</v>
+ <v>Mins = integer()</v>
+ <v>Secs = integer()</v>
+ <v>Millisecs = integer() | float()</v>
+ <v>Func = {M, F, A} | function()</v>
+ <v>M = atom()</v>
+ <v>F = atom()</v>
+ <v>A = list()</v>
+ </type>
+ <desc><marker id="timetrap-1"/>
+ <p>Sets a new timetrap for the running test case.</p>
+
+ <p>If the argument is <c>Func</c>, the timetrap is triggered when
+ this function returns. <c>Func</c> can also return a new
+ <c>Time</c> value, which in that case is the value for the new
+ timetrap.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>userdata(TestDir, Suite) -&gt; SuiteUserData | {error, Reason}</name>
+ <fsummary>Returns any data specified with tag userdata in the list of
+ tuples returned from Suite:suite/0.</fsummary>
+ <type>
+ <v>TestDir = string()</v>
+ <v>Suite = atom()</v>
+ <v>SuiteUserData = [term()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="userdata-2"/>
+ <p>Returns any data specified with tag <c>userdata</c> in the list
+ of tuples returned from
+ <seealso marker="common_test#Module:suite-0"><c>suite/0</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>userdata(TestDir, Suite, Case::GroupOrCase) -&gt; TCUserData | {error, Reason}</name>
+ <fsummary>Returns any data specified with tag userdata in the list of
+ tuples returned from Suite:group(GroupName) or Suite:Case().</fsummary>
+ <type>
+ <v>TestDir = string()</v>
+ <v>Suite = atom()</v>
+ <v>GroupOrCase = {group, GroupName} | atom()</v>
+ <v>GroupName = atom()</v>
+ <v>TCUserData = [term()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="userdata-3"/>
+ <p>Returns any data specified with tag <c>userdata</c> in the list
+ of tuples returned from <c>Suite:group(GroupName)</c> or
+ <c>Suite:Case()</c>.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_cover.xml b/lib/common_test/doc/src/ct_cover.xml
new file mode 100644
index 0000000000..be09c08a68
--- /dev/null
+++ b/lib/common_test/doc/src/ct_cover.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_cover</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_cover.xml</file>
+ </header>
+ <module>ct_cover</module>
+ <modulesummary>Common Test framework code coverage support module.
+ </modulesummary>
+
+<description>
+
+ <p><c>Common Test</c> framework code coverage support module.</p>
+
+ <p>This module exports help functions for performing code coverage
+ analysis.</p>
+
+</description>
+
+ <funcs>
+ <func>
+ <name>add_nodes(Nodes) -&gt; {ok, StartedNodes} | {error, Reason}</name>
+ <fsummary>Adds nodes to current cover test (only works if cover support
+ is active).</fsummary>
+ <type>
+ <v>Nodes = [atom()]</v>
+ <v>StartedNodes = [atom()]</v>
+ <v>Reason = cover_not_running | not_main_node</v>
+ </type>
+ <desc><marker id="add_nodes-1"/>
+ <p>Adds nodes to current cover test. Notice that this only works if
+ cover support is active.</p>
+
+ <p>To have effect, this function is to be called from
+ <c>init_per_suite/1</c> (see
+ <seealso marker="common_test"><c>common_test</c></seealso>)
+ before any tests are performed.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cross_cover_analyse(Level, Tests) -&gt; ok</name>
+ <fsummary>Accumulates cover results over multiple tests.</fsummary>
+ <type>
+ <v>Level = overview | details</v>
+ <v>Tests = [{Tag, Dir}]</v>
+ <v>Tag = atom()</v>
+ <v>Dir = string()</v>
+ </type>
+ <desc><marker id="cross_cover_analyse-2"/>
+ <p>Accumulates cover results over multiple tests. See section
+ <seealso marker="cover_chapter#cross_cover">Cross Cover
+ Analysis</seealso> in the Users's Guide.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>remove_nodes(Nodes) -&gt; ok | {error, Reason}</name>
+ <fsummary>Removes nodes from the current cover test.</fsummary>
+ <type>
+ <v>Nodes = [atom()]</v>
+ <v>Reason = cover_not_running | not_main_node</v>
+ </type>
+ <desc><marker id="remove_nodes-1"/>
+ <p>Removes nodes from the current cover test.</p>
+
+ <p>Call this function to stop cover test on nodes previously
+ added with
+ <seealso marker="#add_nodes-1"><c>ct_cover:add_nodes/1</c></seealso>.
+ Results on the remote node are transferred to the <c>Common Test</c>
+ node.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_ftp.xml b/lib/common_test/doc/src/ct_ftp.xml
new file mode 100644
index 0000000000..0598dcbe3e
--- /dev/null
+++ b/lib/common_test/doc/src/ct_ftp.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_ftp</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_ftp.xml</file>
+ </header>
+ <module>ct_ftp</module>
+ <modulesummary>FTP client module (based on the FTP support of the Inets
+ application).</modulesummary>
+
+ <description>
+
+ <p>FTP client module (based on the FTP support of the <c>Inets</c>
+ application).</p>
+
+ </description>
+
+ <section>
+ <title>Data Types</title>
+ <marker id="types"/>
+ <taglist>
+ <tag><c>connection() = handle() | target_name()</c></tag>
+ <item><marker id="type-connection"/>
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>handle() = handle()</c></tag>
+ <item><marker id="type-handle"/>
+ <p>Handle for a specific FTP connection, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+ </taglist>
+ </section>
+
+ <funcs>
+ <func>
+ <name>cd(Connection, Dir) -&gt; ok | {error, Reason}</name>
+ <fsummary>Changes directory on remote host.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Dir = string()</v>
+ </type>
+ <desc><marker id="cd-2"/>
+ <p>Changes directory on remote host.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>close(Connection) -&gt; ok | {error, Reason}</name>
+ <fsummary>Closes the FTP connection.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ </type>
+ <desc><marker id="close-1"/>
+ <p>Closes the FTP connection.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>delete(Connection, File) -&gt; ok | {error, Reason}</name>
+ <fsummary>Deletes a file on remote host.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>File = string()</v>
+ </type>
+ <desc><marker id="delete-2"/>
+ <p>Deletes a file on remote host.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get(KeyOrName, RemoteFile, LocalFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Opens an FTP connection and fetches a file from the remote
+ host.</fsummary>
+ <type>
+ <v>KeyOrName = Key | Name</v>
+ <v>Key = atom()</v>
+ <v>Name = target_name()</v>
+ <v>RemoteFile = string()</v>
+ <v>LocalFile = string()</v>
+ </type>
+ <desc><marker id="get-3"/>
+ <p>Opens an FTP connection and fetches a file from the remote
+ host.</p>
+
+ <p><c>RemoteFile</c> and <c>LocalFile</c> must be absolute paths.</p>
+
+ <p>The configuration file must be as for
+ <seealso marker="#put-3"><c>ct_ftp:put/3</c></seealso>.</p>
+
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p>
+
+ <p>See also
+ <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>ls(Connection, Dir) -&gt; {ok, Listing} | {error, Reason}</name>
+ <fsummary>Lists directory Dir.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Dir = string()</v>
+ <v>Listing = string()</v>
+ </type>
+ <desc><marker id="ls-2"/>
+ <p>Lists directory <c>Dir</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(KeyOrName) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Opens an FTP connection to the specified node.</fsummary>
+ <type>
+ <v>KeyOrName = Key | Name</v>
+ <v>Key = atom()</v>
+ <v>Name = target_name()</v>
+ <v>Handle = handle()</v>
+ </type>
+ <desc><marker id="open-1"/>
+ <p>Opens an FTP connection to the specified node.</p>
+
+ <p>You can open a connection for a particular <c>Name</c> and use the
+ same name as reference for all following subsequent operations.
+ If you want
+ the connection to be associated with <c>Handle</c> instead (if you,
+ for example, need to open multiple connections to a host), use
+ <c>Key</c>, the configuration variable name, to specify the target.
+ A connection without an associated target name can only be closed
+ with the handle value.</p>
+
+ <p>For information on how to create a new <c>Name</c>, see
+ <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p>
+
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>put(KeyOrName, LocalFile, RemoteFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Opens an FTP connection and sends a file to the remote
+ host.</fsummary>
+ <type>
+ <v>KeyOrName = Key | Name</v>
+ <v>Key = atom()</v>
+ <v>Name = target_name()</v>
+ <v>LocalFile = string()</v>
+ <v>RemoteFile = string()</v>
+ </type>
+ <desc><marker id="put-3"/>
+ <p>Opens an FTP connection and sends a file to the remote host.</p>
+
+ <p><c>LocalFile</c> and <c>RemoteFile</c> must be absolute paths.</p>
+
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p>
+
+ <p>If the target host is a "special" node, the FTP address must be
+ specified in the configuration file as follows:</p>
+
+ <pre>
+ {node,[{ftp,IpAddr}]}.</pre>
+
+ <p>If the target host is something else, for example, a UNIX host,
+ the configuration file must also include the username and password
+ (both strings):</p>
+
+ <pre>
+ {unix,[{ftp,IpAddr},
+ {username,Username},
+ {password,Password}]}.</pre>
+
+ <p>See also
+ <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>recv(Connection, RemoteFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Fetches a file over FTP.</fsummary>
+ <desc><marker id="recv-2"/>
+ <p>Fetches a file over FTP.</p>
+
+ <p>The file gets the same name on the local host.</p>
+
+ <p>See also <seealso marker="#recv-3"><c>ct_ftp:recv/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>recv(Connection, RemoteFile, LocalFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Fetches a file over FTP.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>RemoteFile = string()</v>
+ <v>LocalFile = string()</v>
+ </type>
+ <desc><marker id="recv-3"/>
+ <p>Fetches a file over FTP.</p>
+
+ <p>The file is named <c>LocalFile</c> on the local host.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(Connection, LocalFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Sends a file over FTP.</fsummary>
+ <desc><marker id="send-2"/>
+ <p>Sends a file over FTP.</p>
+
+ <p>The file gets the same name on the remote host.</p>
+
+ <p>See also
+ <seealso marker="#send-3"><c>ct_ftp:send/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(Connection, LocalFile, RemoteFile) -&gt; ok | {error, Reason}</name>
+ <fsummary>Sends a file over FTP.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>LocalFile = string()</v>
+ <v>RemoteFile = string()</v>
+ </type>
+ <desc><marker id="send-3"/>
+ <p>Sends a file over FTP.</p>
+
+ <p>The file is named <c>RemoteFile</c> on the remote host.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>type(Connection, Type) -&gt; ok | {error, Reason}</name>
+ <fsummary>Changes the file transfer type.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Type = ascii | binary</v>
+ </type>
+ <desc><marker id="type-2"/>
+ <p>Changes the file transfer type.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_hooks.xml b/lib/common_test/doc/src/ct_hooks.xml
index cab6dfea51..12ec3bcec3 100644
--- a/lib/common_test/doc/src/ct_hooks.xml
+++ b/lib/common_test/doc/src/ct_hooks.xml
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
-
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
@@ -9,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -33,539 +33,572 @@
<file>ct_hooks.sgml</file>
</header>
<module>ct_hooks</module>
- <modulesummary>A callback interface on top of Common Test</modulesummary>
+ <modulesummary>A callback interface on top of Common Test.</modulesummary>
<description>
- <p>The <em>Common Test Hook</em> (henceforth called CTH) framework allows
- extensions of the default behaviour of Common Test by means of callbacks
- before and after all test suite calls. It is meant for advanced users of
- Common Test which want to abstract out behaviour which is common to
- multiple test suites. </p>
+ <p>The <em>Common Test Hook (CTH)</em> framework allows extensions of the
+ default behavior of <c>Common Test</c> by callbacks before and after all
+ test suite calls. It is intended for advanced users of <c>Common Test</c>
+ who want to abstract out behavior that is common to multiple test suites.
+ </p>
- <p>In brief, Common Test Hooks allows you to:</p>
+ <p>In brief, CTH allows you to:</p>
- <list>
- <item>Manipulate the runtime config before each suite
- configuration call</item>
- <item>Manipulate the return of all suite configuration calls and in
- extension the result of the test themselves.</item>
+ <list type="bulleted">
+ <item><p>Manipulate the runtime configuration before each suite
+ configuration call.</p></item>
+ <item><p>Manipulate the return of all suite configuration calls and by
+ extension the result of the test themselves.</p></item>
</list>
<p>The following sections describe the mandatory and optional CTH
- functions Common Test will call during test execution. For more details
- see <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> in
- the User's Guide.</p>
+ functions that <c>Common Test</c> calls during test execution.
+ For more details, see section
+ <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> in the
+ User's Guide.</p>
- <p>For information about how to add a CTH to your suite see
- <seealso marker="ct_hooks_chapter#installing">Installing a CTH
- </seealso> in the User's Guide.</p>
+ <p>For information about how to add a CTH to your suite, see section
+ <seealso marker="ct_hooks_chapter#installing">Installing a CTH</seealso>
+ in the User's Guide.</p>
+
+ <note><p>For a minimal example of a CTH, see section
+ <seealso marker="ct_hooks_chapter#example">Example CTH</seealso>
+ in the User's Guide.</p></note>
- <note><p>See the
- <seealso marker="ct_hooks_chapter#example">Example CTH</seealso>
- in the User's Guide for a minimal example of a CTH. </p></note>
-
</description>
<section>
- <title>CALLBACK FUNCTIONS</title>
- <p>The following functions define the callback interface
- for a Common Test Hook.</p>
+ <title>Callback Functions</title>
+ <p>The following functions define the callback interface for a CTH.</p>
</section>
<funcs>
<func>
- <name>Module:init(Id, Opts) -&gt; {ok, State} |
- {ok, State, Priority}</name>
- <fsummary>Initiates the Common Test Hook</fsummary>
+ <name>Module:init(Id, Opts) -&gt; {ok, State} | {ok, State, Priority}</name>
+ <fsummary>Initiates the Common Test Hook.</fsummary>
<type>
- <v>Id = reference() | term()</v>
- <v>Opts = term()</v>
- <v>State = term()</v>
- <v>Priority = integer()</v>
+ <v>Id = reference() | term()</v>
+ <v>Opts = term()</v>
+ <v>State = term()</v>
+ <v>Priority = integer()</v>
</type>
-
<desc>
- <p> MANDATORY </p>
-
- <p>Always called before any other callback function.
- Use this to initiate any common state.
- It should return a state for this CTH.</p>
-
- <p><c>Id</c> is the return value of
- <seealso marker="#Module:id-1">id/1</seealso>, or a <c>reference</c>
- (created using
- <seealso marker="erts:erlang#make_ref-0">make_ref/0</seealso>)
- if <seealso marker="#Module:id-1">id/1</seealso> is not implemented.
- </p>
-
- <p><c>Priority</c> is the relative priority of this hook. Hooks with a
- lower priority will be executed first. If no priority is given,
- it will be set to 0. </p>
-
- <p>For details about when init is called see
- <seealso marker="ct_hooks_chapter#scope">scope</seealso>
- in the User's Guide.</p>
-
+ <p>MANDATORY</p>
+
+ <p>This function is always called before any other callback function.
+ Use it to initiate any common state. It is to return a state for
+ this CTH.</p>
+
+ <p><c>Id</c> is either the return value of
+ <seealso marker="#Module:id-1"><c>ct_hooks:id/1</c></seealso>,
+ or a <c>reference</c> (created using
+ <seealso marker="erts:erlang#make_ref-0">erlang:make_ref/0</seealso>
+ in <c>ERTS</c>) if
+ <seealso marker="#Module:id-1"><c>ct_hooks:id/1</c></seealso>
+ is not implemented.</p>
+
+ <p><c>Priority</c> is the relative priority of this hook. Hooks with a
+ lower priority are executed first. If no priority is specified, it
+ is set to <c>0</c>.</p>
+
+ <p>For details about when <c>init</c> is called, see section
+ <seealso marker="ct_hooks_chapter#scope">CTH Scope</seealso>
+ in the User's Guide.</p>
</desc>
</func>
<func>
- <name>Module:pre_init_per_suite(SuiteName, InitData, CTHState) -&gt;
- Result</name>
- <fsummary>Called before init_per_suite</fsummary>
+ <name>Module:pre_init_per_suite(SuiteName, InitData, CTHState) -&gt; Result</name>
+ <fsummary>Called before init_per_suite.</fsummary>
<type>
- <v>SuiteName = atom()</v>
- <v>InitData = Config | SkipOrFail</v>
- <v>Config = NewConfig = [{Key,Value}]</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {Return, NewCTHState}</v>
- <v>Return = NewConfig | SkipOrFail</v>
- <v>SkipOrFail = {fail, Reason} | {skip, Reason}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>SuiteName = atom()</v>
+ <v>InitData = Config | SkipOrFail</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {Return, NewCTHState}</v>
+ <v>Return = NewConfig | SkipOrFail</v>
+ <v>SkipOrFail = {fail, Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called before
- <seealso marker="common_test#Module:init_per_suite-1">
- init_per_suite</seealso> if it exists.
- It typically contains initialization/logging which needs to be done
- before init_per_suite is called.
- If <c>{skip,Reason}</c> or <c>{fail,Reason}</c> is returned,
- init_per_suite and all test cases of the suite will be skipped and
- Reason printed in the overview log of the suite.</p>
-
- <p><c>SuiteName</c> is the name of the suite to be run.</p>
-
- <p><c>InitData</c> is the original config list of the test suite, or
- a <c>SkipOrFail</c> tuple if a previous CTH has returned this.</p>
-
- <p><c>CTHState</c> is the current internal state of the CTH.</p>
-
- <p><c>Return</c> is the result of the init_per_suite function.
- If it is <c>{skip,Reason}</c> or <c>{fail,Reason}</c>
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
- </seealso> will never be called, instead the initiation is considered
- to be skipped/failed respectively. If a <c>NewConfig</c> list
- is returned, <seealso marker="common_test#Module:init_per_suite-1">
- init_per_suite</seealso> will be called with that <c>NewConfig</c> list.
- See <seealso marker="ct_hooks_chapter#pre">
- Pre Hooks</seealso> in the User's Guide for more details.</p>
-
-
- <p>Note that this function is only called if the CTH has been added
- before init_per_suite is run, see
- <seealso marker="ct_hooks_chapter#scope">CTH Scoping</seealso>
- in the User's Guide for details.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
+ if it exists. It typically contains initialization/logging that must
+ be done before <c>init_per_suite</c> is called. If
+ <c>{skip,Reason}</c> or <c>{fail,Reason}</c> is returned,
+ <c>init_per_suite</c> and all test cases of the suite are skipped
+ and <c>Reason</c> printed in the overview log of the suite.</p>
+
+ <p><c>SuiteName</c> is the name of the suite to be run.</p>
+
+ <p><c>InitData</c> is the original configuration list of the test
+ suite, or a <c>SkipOrFail</c> tuple if a previous CTH has returned
+ this.</p>
+
+ <p><c>CTHState</c> is the current internal state of the CTH.</p>
+
+ <p><c>Return</c> is the result of the <c>init_per_suite</c> function.
+ If it is <c>{skip,Reason}</c> or <c>{fail,Reason}</c>,
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
+ is never called, instead the initiation is considered to be
+ skipped or failed, respectively. If a <c>NewConfig</c> list is
+ returned,
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
+ is called with that <c>NewConfig</c> list. For more details, see
+ section <seealso marker="ct_hooks_chapter#pre">Pre Hooks</seealso>
+ in the User's Guide.</p>
+
+ <p>This function is called only if the CTH is added before
+ <c>init_per_suite is run</c>. For details, see section
+ <seealso marker="ct_hooks_chapter#scope">CTH Scope</seealso>
+ in the User's Guide.</p>
</desc>
</func>
-
+
<func>
- <name>Module:post_init_per_suite(SuiteName, Config, Return, CTHState) -&gt;
- Result</name>
- <fsummary>Called after init_per_suite</fsummary>
+ <name>Module:post_init_per_suite(SuiteName, Config, Return, CTHState) -&gt; Result</name>
+ <fsummary>Called after init_per_suite.</fsummary>
<type>
- <v>SuiteName = atom()</v>
- <v>Config = [{Key,Value}]</v>
- <v>Return = NewReturn = Config | SkipOrFail | term()</v>
- <v>SkipOrFail = {fail, Reason} | {skip, Reason} | term()</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewReturn, NewCTHState}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>SuiteName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail, Reason} | {skip, Reason} | term()</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
+ if it exists. It typically contains extra checks to ensure that all
+ the correct dependencies are started correctly.</p>
+
+ <p><c>Return</c> is what
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
+ returned, that is, <c>{fail,Reason}</c>, <c>{skip,Reason}</c>, a
+ <c>Config</c> list, or a term describing how
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
+ failed.</p>
+
+ <p><c>NewReturn</c> is the possibly modified return value of
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>.
+ To recover from a failure in
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>,
+ return <c>ConfigList</c> with the <c>tc_status</c> element removed.
+ For more details, see
+ <seealso marker="ct_hooks_chapter#post"> Post Hooks</seealso> in
+ section "Manipulating Tests" in the User's Guide.</p>
+
+ <p><c>CTHState</c> is the current internal state of the CTH.</p>
+
+ <p>This function is called only if the CTH is added before or in
+ <c>init_per_suite</c>. For details, see section
+ <seealso marker="ct_hooks_chapter#scope">CTH Scope</seealso>
+ in the User's Guide.</p>
+ </desc>
+ </func>
- <p>This function is called after
- <seealso marker="common_test#Module:init_per_suite-1">
- init_per_suite</seealso> if it exists. It typically contains extra
- checks to make sure that all the correct dependencies have
- been started correctly.</p>
-
- <p><c>Return</c> is what
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
- </seealso> returned, i.e. {fail,Reason}, {skip,Reason}, a <c>Config</c>
- list or a term describing how
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
- </seealso> failed.</p>
-
- <p><c>NewReturn</c> is the possibly modified return value of
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
- </seealso>. It is here possible to recover from a failure in
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
- </seealso> by returning the <c>ConfigList</c> with the <c>tc_status</c>
- element removed. See <seealso marker="ct_hooks_chapter#post">
- Post Hooks</seealso> in the User's Guide for more details.</p>
-
- <p><c>CTHState</c> is the current internal state of the CTH.</p>
-
- <p>Note that this function is only called if the CTH has been added
- before or in init_per_suite, see
- <seealso marker="ct_hooks_chapter#scope">CTH Scoping</seealso>
- in the User's Guide for details.</p>
+ <func>
+ <name>Module:pre_init_per_group(GroupName, InitData, CTHState) -&gt; Result</name>
+ <fsummary>Called before init_per_group.</fsummary>
+ <type>
+ <v>GroupName = atom()</v>
+ <v>InitData = Config | SkipOrFail</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>OPTIONAL</p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso>
+ instead.</p>
</desc>
</func>
-
+
<func>
- <name>Module:pre_init_per_group(GroupName, InitData, CTHState) -&gt;
- Result</name>
- <fsummary>Called before init_per_group</fsummary>
+ <name>Module:post_init_per_group(GroupName, Config, Return, CTHState) -&gt; Result</name>
+ <fsummary>Called after init_per_group.</fsummary>
<type>
- <v>GroupName = atom()</v>
- <v>InitData = Config | SkipOrFail</v>
- <v>Config = NewConfig = [{Key,Value}]</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>GroupName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called before
- <seealso marker="common_test#Module:init_per_group-2">
- init_per_group</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
- pre_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:init_per_group-2">
- init_per_group</seealso> instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso>
+ instead.</p>
</desc>
</func>
-
+
<func>
- <name>Module:post_init_per_group(GroupName, Config, Return, CTHState) -&gt;
- Result</name>
- <fsummary>Called after init_per_group</fsummary>
+ <name>Module:pre_init_per_testcase(TestcaseName, InitData, CTHState) -&gt; Result</name>
+ <fsummary>Called before init_per_testcase.</fsummary>
<type>
- <v>GroupName = atom()</v>
- <v>Config = [{Key,Value}]</v>
- <v>Return = NewReturn = Config | SkipOrFail | term()</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewReturn, NewCTHState}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>TestcaseName = atom()</v>
+ <v>InitData = Config | SkipOrFail</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called after
- <seealso marker="common_test#Module:init_per_group-2">
- init_per_group</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:post_init_per_suite-4">
- post_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:init_per_group-2">
- init_per_group</seealso> instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso>
+ instead.</p>
+
+ <p>CTHs cannot be added here right now. That feature may be added in
+ a later release, but it would right now break backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:pre_init_per_testcase(TestcaseName, InitData, CTHState) -&gt;
- Result</name>
- <fsummary>Called before init_per_testcase</fsummary>
+ <name>Module:post_init_per_testcase(TestcaseName, Config, Return, CTHState) -&gt; Result</name>
+ <fsummary>Called after init_per_testcase.</fsummary>
<type>
- <v>TestcaseName = atom()</v>
- <v>InitData = Config | SkipOrFail</v>
- <v>Config = NewConfig = [{Key,Value}]</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>TestcaseName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called before
- <seealso marker="common_test#Module:init_per_testcase-2">
- init_per_testcase</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
- pre_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:init_per_testcase-2">
- init_per_testcase</seealso> function instead.</p>
-
- <p>Note that it is not possible to add CTH's here right now,
- that feature might be added later,
- but it would right now break backwards compatibility.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso>
+ instead.</p>
</desc>
</func>
<func>
- <name>Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState)
- -&gt; Result</name>
- <fsummary>Called after end_per_testcase</fsummary>
+ <name>Module:pre_end_per_testcase(TestcaseName, InitData, CTHState) -&gt; Result</name>
+ <fsummary>Called before end_per_testcase.</fsummary>
<type>
- <v>TestcaseName = atom()</v>
- <v>Config = [{Key,Value}]</v>
- <v>Return = NewReturn = Config | SkipOrFail | term()</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewReturn, NewCTHState}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>TestcaseName = atom()</v>
+ <v>InitData = Config</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called after
- <seealso marker="common_test#Module:end_per_testcase-2">
- end_per_testcase</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:post_init_per_suite-4">
- post_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:end_per_testcase-2">
- end_per_testcase</seealso> function instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_end_per_suite-3"><c>pre_end_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>
+ instead.</p>
+
+ <p>This function can not change the result of the test case by returning skip or fail
+ tuples, but it may insert items in <c>Config</c> that can be read in
+ <c>end_per_testcase/2</c> or in <c>post_end_per_testcase/4</c>.</p>
</desc>
</func>
<func>
- <name>Module:pre_end_per_group(GroupName, EndData, CTHState) -&gt;
- Result</name>
- <fsummary>Called before end_per_group</fsummary>
+ <name>Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState) -&gt; Result</name>
+ <fsummary>Called after end_per_testcase.</fsummary>
<type>
- <v>GroupName = atom()</v>
- <v>EndData = Config | SkipOrFail</v>
- <v>Config = NewConfig = [{Key,Value}]</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>TestcaseName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called before
- <seealso marker="common_test#Module:end_per_group-2">
- end_per_group</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
- pre_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:end_per_group-2">
- end_per_group</seealso> function instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_end_per_suite-4"><c>post_end_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>
+ instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:pre_end_per_group(GroupName, EndData, CTHState) -&gt; Result</name>
+ <fsummary>Called before end_per_group.</fsummary>
+ <type>
+ <v>GroupName = atom()</v>
+ <v>EndData = Config | SkipOrFail</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>OPTIONAL</p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso>
+ instead.</p>
</desc>
</func>
<func>
- <name>Module:post_end_per_group(GroupName, Config, Return, CTHState) -&gt;
- Result</name>
- <fsummary>Called after end_per_group</fsummary>
+ <name>Module:post_end_per_group(GroupName, Config, Return, CTHState) -&gt; Result</name>
+ <fsummary>Called after end_per_group.</fsummary>
<type>
- <v>GroupName = atom()</v>
- <v>Config = [{Key,Value}]</v>
- <v>Return = NewReturn = Config | SkipOrFail | term()</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewReturn, NewCTHState}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>GroupName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called after
- <seealso marker="common_test#Module:end_per_group-2">
- end_per_group</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:post_init_per_suite-4">
- post_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:end_per_group-2">
- end_per_group</seealso> function instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:end_per_group-2">end_per_group</seealso>
+ instead.</p>
</desc>
</func>
<func>
- <name>Module:pre_end_per_suite(SuiteName, EndData, CTHState) -&gt;
- Result</name>
- <fsummary>Called before end_per_suite</fsummary>
+ <name>Module:pre_end_per_suite(SuiteName, EndData, CTHState) -&gt; Result</name>
+ <fsummary>Called before end_per_suite.</fsummary>
<type>
- <v>SuiteName = atom()</v>
- <v>EndData = Config | SkipOrFail</v>
- <v>Config = NewConfig = [{Key,Value}]</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>SuiteName = atom()</v>
+ <v>EndData = Config | SkipOrFail</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called before
- <seealso marker="common_test#Module:end_per_suite-1">
- end_per_suite</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
- pre_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:end_per_suite-1">
- end_per_suite</seealso> function instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso>
+ instead.</p>
</desc>
</func>
<func>
- <name>Module:post_end_per_suite(SuiteName, Config, Return, CTHState) -&gt;
- Result</name>
- <fsummary>Called after end_per_suite</fsummary>
+ <name>Module:post_end_per_suite(SuiteName, Config, Return, CTHState) -&gt; Result</name>
+ <fsummary>Called after end_per_suite.</fsummary>
<type>
- <v>SuiteName = atom()</v>
- <v>Config = [{Key,Value}]</v>
- <v>Return = NewReturn = Config | SkipOrFail | term()</v>
- <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
- <v>CTHState = NewCTHState = term()</v>
- <v>Result = {NewReturn, NewCTHState}</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- <v>Reason = term()</v>
+ <v>SuiteName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called after
- <seealso marker="common_test#Module:end_per_suite-1">
- end_per_suite</seealso> if it exists. It behaves the same way as
- <seealso marker="ct_hooks#Module:post_init_per_suite-4">
- post_init_per_suite</seealso>, but for the
- <seealso marker="common_test#Module:end_per_suite-1">
- end_per_suite</seealso> function instead.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso>
+ if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>,
+ but for function
+ <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso>
+ instead.</p>
</desc>
</func>
<func>
- <name>Module:on_tc_fail(TestName, Reason, CTHState) -&gt;
- NewCTHState</name>
- <fsummary>Called after the CTH scope ends</fsummary>
+ <name>Module:on_tc_fail(TestName, Reason, CTHState) -&gt; NewCTHState</name>
+ <fsummary>Called after the CTH scope ends.</fsummary>
<type>
- <v>TestName = init_per_suite | end_per_suite |
- {init_per_group,GroupName} | {end_per_group,GroupName} |
- {FuncName,GroupName} | FuncName</v>
- <v>FuncName = atom()</v>
- <v>GroupName = atom()</v>
- <v>Reason = term()</v>
- <v>CTHState = NewCTHState = term()</v>
+ <v>TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName</v>
+ <v>FuncName = atom()</v>
+ <v>GroupName = atom()</v>
+ <v>Reason = term()</v>
+ <v>CTHState = NewCTHState = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called whenever a test case (or config function)
- fails. It is called after the post function has been called for
- the failed test case. I.e. if init_per_suite fails, this function
- is called after
- <seealso marker="#Module:post_init_per_suite-4">
- post_init_per_suite</seealso>, and if a test case fails, it is called
- after <seealso marker="#Module:post_end_per_testcase-4">
- post_end_per_testcase</seealso>. If the failed test case belongs
- to a test case group, the first argument is a tuple
- <c>{FuncName,GroupName}</c>, otherwise simply the function name.</p>
-
- <p>The data which comes with the Reason follows the same format as the
- <seealso marker="event_handler_chapter#failreason">FailReason
- </seealso> in the <seealso marker="event_handler_chapter#tc_done">tc_done</seealso> event.
- See <seealso marker="event_handler_chapter#events">Event Handling
- </seealso> in the User's Guide for details.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called whenever a test case (or configuration
+ function) fails. It is called after the post function is called
+ for the failed test case, that is:</p>
+
+ <list type="bulleted">
+ <item><p>If <c>init_per_suite</c> fails, this function is called after
+ <seealso marker="#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>.</p></item>
+ <item><p>If a test case fails, this funcion is called after
+ <seealso marker="#Module:post_end_per_testcase-4"><c>post_end_per_testcase</c></seealso>.</p></item>
+ </list>
+
+ <p>If the failed test case belongs to a test case group, the first
+ argument is a tuple <c>{FuncName,GroupName}</c>, otherwise only
+ the function name.</p>
+
+ <p>The data that comes with <c>Reason</c> follows the same format as
+ <seealso marker="event_handler_chapter#failreason"><c>FailReason</c></seealso>
+ in event
+ <seealso marker="event_handler_chapter#tc_done"><c>tc_done</c></seealso>.
+ For details, see section
+ <seealso marker="event_handler_chapter#events">Event Handling</seealso>
+ in the User's Guide.</p>
</desc>
</func>
<func>
- <name>Module:on_tc_skip(TestName, Reason, CTHState) -&gt;
- NewCTHState</name>
- <fsummary>Called after the CTH scope ends</fsummary>
+ <name>Module:on_tc_skip(TestName, Reason, CTHState) -&gt; NewCTHState</name>
+ <fsummary>Called after the CTH scope ends.</fsummary>
<type>
- <v>TestName = init_per_suite | end_per_suite |
- {init_per_group,GroupName} | {end_per_group,GroupName} |
- {FuncName,GroupName} | FuncName</v>
- <v>FuncName = atom()</v>
- <v>GroupName = atom()</v>
- <v>Reason = {tc_auto_skip | tc_user_skip, term()}</v>
- <v>CTHState = NewCTHState = term()</v>
+ <v>TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName</v>
+ <v>FuncName = atom()</v>
+ <v>GroupName = atom()</v>
+ <v>Reason = {tc_auto_skip | tc_user_skip, term()}</v>
+ <v>CTHState = NewCTHState = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>This function is called whenever a test case (or config function)
- is skipped. It is called after the post function has been called
- for the skipped test case. I.e. if init_per_group is skipped, this
- function is called after
- <seealso marker="#Module:post_init_per_group-4">
- post_init_per_group</seealso>, and if a test case is skipped,
- it is called after
- <seealso marker="#Module:post_end_per_testcase-4">
- post_end_per_testcase</seealso>. If the skipped test case belongs to a
- test case group, the first argument is a tuple <c>{FuncName,GroupName}</c>,
- otherwise simply the function name.</p>
-
- <p>The data which comes with the Reason follows the same format as
- <seealso marker="event_handler_chapter#tc_auto_skip">tc_auto_skip
- </seealso> and <seealso marker="event_handler_chapter#tc_user_skip">
- tc_user_skip</seealso> events.
- See <seealso marker="event_handler_chapter#events">Event Handling
- </seealso> in the User's Guide for details.</p>
+ <p>OPTIONAL</p>
+
+ <p>This function is called whenever a test case (or configuration
+ function) is skipped. It is called after the post function is called
+ for the skipped test case, that is:</p>
+
+ <list type="bulleted">
+ <item><p>If <c>init_per_group</c> is skipped, this function is
+ called after
+ <seealso marker="#Module:post_init_per_group-4"><c>post_init_per_group</c></seealso>.</p></item>
+ <item><p>If a test case is skipped, this function is called after
+ <seealso marker="#Module:post_end_per_testcase-4"><c>post_end_per_testcase</c></seealso>.</p></item>
+ </list>
+
+ <p>If the skipped test case belongs to a test case group, the first
+ argument is a tuple <c>{FuncName,GroupName}</c>, otherwise only
+ the function name.</p>
+
+ <p>The data that comes with <c>Reason</c> follows the same format as
+ events
+ <seealso marker="event_handler_chapter#tc_auto_skip"><c>tc_auto_skip</c></seealso>
+ and
+ <seealso marker="event_handler_chapter#tc_user_skip"><c>tc_user_skip</c></seealso>
+ For details, see section
+ <seealso marker="event_handler_chapter#events">Event Handling</seealso>
+ in the User's Guide.</p>
</desc>
</func>
<func>
<name>Module:terminate(CTHState)</name>
- <fsummary>Called after the CTH scope ends</fsummary>
+ <fsummary>Called after the CTH scope ends.</fsummary>
<type>
- <v>CTHState = term()</v>
+ <v>CTHState = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
+ <p>OPTIONAL</p>
- <p>This function is called at the end of a CTH's
- <seealso marker="ct_hooks_chapter#scope">scope</seealso>.
- </p>
+ <p>This function is called at the end of a CTH
+ <seealso marker="ct_hooks_chapter#scope">scope</seealso>.</p>
</desc>
</func>
<func>
<name>Module:id(Opts) -&gt; Id</name>
- <fsummary>Called before the init function of a CTH</fsummary>
+ <fsummary>Called before the init function of a CTH.</fsummary>
<type>
- <v>Opts = term()</v>
- <v>Id = term()</v>
+ <v>Opts = term()</v>
+ <v>Id = term()</v>
</type>
-
<desc>
- <p> OPTIONAL </p>
-
- <p>The <c>Id</c> is used to uniquely identify a CTH instance,
- if two CTH's return the same <c>Id</c> the second CTH is ignored
- and subsequent calls to the CTH will only be made to the first
- instance. For more information see
- <seealso marker="ct_hooks_chapter#installing">Installing a CTH
- </seealso> in the User's Guide.
- </p>
-
- <p>This function should NOT have any side effects as it might
- be called multiple times by Common Test.</p>
+ <p>OPTIONAL</p>
- <p>If not implemented the CTH will act as if this function returned a
- call to <c>make_ref/0</c>.</p>
- </desc>
+ <p>The <c>Id</c> identifies a CTH instance uniquely. If two CTHs return
+ the same <c>Id</c>, the second CTH is ignored and subsequent calls to
+ the CTH are only made to the first instance. For details, see section
+ <seealso marker="ct_hooks_chapter#installing">Installing a CTH</seealso>
+ in the User's Guide.</p>
+
+ <p>This function is <em>not</em> to have any side effects, as it can
+ be called multiple times by <c>Common Test</c>.</p>
+
+ <p>If not implemented, the CTH acts as if this function returned a call
+ to <c>make_ref/0</c>.</p>
+ </desc>
</func>
-
</funcs>
</erlref>
diff --git a/lib/common_test/doc/src/ct_hooks_chapter.xml b/lib/common_test/doc/src/ct_hooks_chapter.xml
index 60cd9be918..3eb1945a61 100644
--- a/lib/common_test/doc/src/ct_hooks_chapter.xml
+++ b/lib/common_test/doc/src/ct_hooks_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,177 +30,181 @@
<file>ct_hooks_chapter.xml</file>
</header>
- <marker id="general"></marker>
<section>
+ <marker id="general"></marker>
<title>General</title>
<p>
- The <em>Common Test Hook</em> (henceforth called CTH) framework allows
- extensions of the default behaviour of Common Test by means of hooks
- before and after all test suite calls. CTHs allow advanced Common Test
- users to abstract out behaviour which is common to multiple test suites
- without littering all test suites with library calls. Some example
- usages are: logging, starting and monitoring external systems,
- building C files needed by the tests and much more!</p>
-
- <p>In brief, Common Test Hooks allows you to:</p>
-
- <list>
- <item>Manipulate the runtime config before each suite
- configuration call</item>
- <item>Manipulate the return of all suite configuration calls and in
- extension the result of the test themselves.</item>
+ The <em>Common Test Hook (CTH)</em> framework allows
+ extensions of the default behavior of <c>Common Test</c> using hooks
+ before and after all test suite calls. CTHs allow advanced <c>Common Test</c>
+ users to abstract out behavior that is common to multiple test suites
+ without littering all test suites with library calls. this can be used
+ for logging, starting, and monitoring external systems,
+ building C files needed by the tests, and so on.</p>
+
+ <p>In brief, CTH allows you to do the following:</p>
+
+ <list type="bulleted">
+ <item>Manipulate the runtime configuration before each suite
+ configuration call.</item>
+ <item>Manipulate the return of all suite configuration calls, and in
+ extension, the result of the tests themselves.</item>
</list>
- <p>The following sections describe how to use CTHs, when they are run
- and how to manipulate your test results in a CTH</p>
+ <p>The following sections describe how to use CTHs, when they are run,
+ and how to manipulate the test results in a CTH.</p>
- <warning><p>When executing within a CTH all timetraps are shutoff. So
- if your CTH never returns, the entire test run will be stalled!</p>
+ <warning><p>When executing within a CTH, all timetraps are shut off. So
+ if your CTH never returns, the entire test run is stalled.</p>
</warning>
</section>
- <marker id="installing"></marker>
<section>
+ <marker id="installing"></marker>
<title>Installing a CTH</title>
- <p>There are multiple ways to install a CTH in your test run. You can do it
- for all tests in a run, for specific test suites and for specific groups
+ <p>A CTH can be installed in multiple ways in your test run. You can do it
+ for all tests in a run, for specific test suites, and for specific groups
within a test suite. If you want a CTH to be present in all test suites
- within your test run there are three different ways to accomplish that.
+ within your test run, there are three ways to accomplish that, as follows:
</p>
- <list>
+ <list type="bulleted">
<item>Add <c>-ct_hooks</c> as an argument to
<seealso marker="run_test_chapter#ct_run">ct_run</seealso>.
- To add multiple CTHs using this method append them to each other
- using the keyword <c>and</c>, i.e.
+ To add multiple CTHs using this method, append them to each other
+ using the keyword <c>and</c>, that is,
<c>ct_run -ct_hooks cth1 [{debug,true}] and cth2 ...</c>.</item>
- <item>Add the <c>ct_hooks</c> tag to your
+ <item>Add tag <c>ct_hooks</c> to your
<seealso marker="run_test_chapter#test_specifications">
- Test Specification</seealso></item>
- <item>Add the <c>ct_hooks</c> tag to your call to
- <seealso marker="ct#run_test-1">ct:run_test/1</seealso></item>
+ Test Specification</seealso>.</item>
+ <item>Add tag <c>ct_hooks</c> to your call to
+ <seealso marker="ct#run_test-1">ct:run_test/1</seealso>.</item>
</list>
- <p>You can also add CTHs within a test suite. This is done by returning
- <c>{ct_hooks,[CTH]}</c> in the config list from
+ <p>CTHs can also be added within a test suite. This is done by returning
+ <c>{ct_hooks,[CTH]}</c> in the configuration list from
<seealso marker="common_test#Module:suite-0">suite/0</seealso>,
<seealso marker="common_test#Module:init_per_suite-1">
- init_per_suite/1</seealso> or
+ init_per_suite/1</seealso>, or
<seealso marker="common_test#Module:init_per_group-2">
- init_per_group/2</seealso>. <c>CTH</c> in this case can be either
- only the module name of the CTH or a tuple with the module name and the
- initial arguments and optionally the hook priority of the CTH. Eg:
- <c>{ct_hooks,[my_cth_module]}</c> or
- <c>{ct_hooks,[{my_cth_module,[{debug,true}]}]}</c> or
- <c>{ct_hooks,[{my_cth_module,[{debug,true}],500}]}</c>
- </p>
+ init_per_group/2</seealso>.</p>
+
+ <p>In this case, <c>CTH</c> can either be only the module name of the CTH
+ or a tuple with the module name and the initial arguments, and optionally
+ the hook priority of the CTH. For example, one of the following:</p>
+ <list type="bulleted">
+ <item><c>{ct_hooks,[my_cth_module]}</c></item>
+ <item><c>{ct_hooks,[{my_cth_module,[{debug,true}]}]}</c></item>
+ <item><c>{ct_hooks,[{my_cth_module,[{debug,true}],500}]}</c></item>
+ </list>
<section>
<title>Overriding CTHs</title>
- <p>By default each installation of a CTH will cause a new instance of it
- to be activated. This can cause problems if you want to be able to
- override CTHs in test specifications while still having them in the
- suite info function. The
+ <p>By default, each installation of a CTH causes a new instance of it
+ to be activated. This can cause problems if you want to override
+ CTHs in test specifications while still having them in the
+ suite information function. The
<seealso marker="ct_hooks#Module:id-1">id/1</seealso>
callback exists to address this problem. By returning the same
- <c>id</c> in both places, Common Test knows that this CTH
- has already been installed and will not try to install it again.</p>
+ <c>id</c> in both places, <c>Common Test</c> knows that this CTH
+ is already installed and does not try to install it again.</p>
</section>
<section>
- <title>CTH Execution order</title>
- <p>By default each CTH installed will be executed in the order which
+ <title>CTH Execution Order</title>
+ <p>By default, each CTH installed is executed in the order that
they are installed for init calls, and then reversed for end calls.
- This is not always wanted so common_test allows
+ This is not always desired, so <c>Common Test</c> allows
the user to specify a priority for each hook. The priority can either
- be specified in the CTH <seealso marker="ct_hooks#Module:init-2">init/2
- </seealso> function or when installing the hook. The priority given at
- installation will override the priority returned by the CTH. </p>
+ be specified in the CTH function
+ <seealso marker="ct_hooks#Module:init-2">init/2</seealso> or when
+ installing the hook. The priority specified at installation overrides the
+ priority returned by the CTH.</p>
</section>
</section>
- <marker id="scope"/>
<section>
+ <marker id="scope"/>
<title>CTH Scope</title>
- <p>Once the CTH is installed into a certain test run it will be there until
+ <p>Once the CTH is installed into a certain test run it remains there until
its scope is expired. The scope of a CTH depends on when it is
- installed.
- The <seealso marker="ct_hooks#Module:init-2">init/2</seealso> is
- called at the beginning of the scope and the
- <seealso marker="ct_hooks#Module:terminate-1">terminate/1
- </seealso> function is called when the scope ends.</p>
+ installed, see the following table.
+ Function <seealso marker="ct_hooks#Module:init-2">init/2</seealso> is
+ called at the beginning of the scope and function
+ <seealso marker="ct_hooks#Module:terminate-1">terminate/1</seealso>
+ is called when the scope ends.</p>
<table>
<row>
- <cell><em>CTH Installed in</em></cell>
+ <cell><em>CTH installed in</em></cell>
<cell><em>CTH scope begins before</em></cell>
<cell><em>CTH scope ends after</em></cell>
</row>
<row>
<cell><seealso marker="run_test_chapter#ct_run">ct_run</seealso></cell>
- <cell>the first test suite is to be run.</cell>
- <cell>the last test suite has been run.</cell>
+ <cell>the first test suite is to be run</cell>
+ <cell>the last test suite has been run</cell>
</row>
<row>
<cell><seealso marker="ct#run_test-1">ct:run_test</seealso></cell>
- <cell>the first test suite is to be run.</cell>
- <cell>the last test suite has been run.</cell>
+ <cell>the first test suite is run</cell>
+ <cell>the last test suite has been run</cell>
</row>
<row>
<cell><seealso marker="run_test_chapter#test_specifications">
Test Specification</seealso></cell>
- <cell>the first test suite is to be run.</cell>
- <cell>the last test suite has been run.</cell>
+ <cell>the first test suite is run</cell>
+ <cell>the last test suite has been run</cell>
</row>
<row>
<cell><seealso marker="common_test#Module:suite-0">suite/0
</seealso></cell>
<cell><seealso marker="ct_hooks#Module:pre_init_per_suite-3">
- pre_init_per_suite/3</seealso> is called.</cell>
+ pre_init_per_suite/3</seealso> is called</cell>
<cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
- post_end_per_suite/4</seealso> has been called for that test suite.</cell>
+ post_end_per_suite/4</seealso> has been called for that test suite</cell>
</row>
<row>
<cell><seealso marker="common_test#Module:init_per_suite-1">
init_per_suite/1</seealso></cell>
<cell><seealso marker="ct_hooks#Module:post_init_per_suite-4">
- post_init_per_suite/4</seealso> is called.</cell>
+ post_init_per_suite/4</seealso> is called</cell>
<cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
- post_end_per_suite/4</seealso> has been called for that test suite.</cell>
+ post_end_per_suite/4</seealso> has been called for that test suite</cell>
</row>
<row>
<cell><seealso marker="common_test#Module:init_per_group-2">
init_per_group/2</seealso></cell>
<cell><seealso marker="ct_hooks#Module:post_init_per_group-4">
- post_init_per_group/4</seealso> is called.</cell>
+ post_init_per_group/4</seealso> is called</cell>
<cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
- post_end_per_group/4</seealso> has been called for that group.</cell>
+ post_end_per_group/4</seealso> has been called for that group</cell>
</row>
<tcaption>Scope of a CTH</tcaption>
</table>
<section>
<title>CTH Processes and Tables</title>
- <p>CTHs are run with the same process scoping as normal test suites
- i.e. a different process will execute the init_per_suite hooks then the
- init_per_group or per_testcase hooks. So if you want to spawn a
- process in the CTH you cannot link with the CTH process as it will exit
- after the post hook ends. Also if you for some reason need an ETS
- table with your CTH, you will have to spawn a process which handles
- it.</p>
+ <p>CTHs are run with the same process scoping as normal test suites,
+ that is, a different process executes the <c>init_per_suite</c> hooks then the
+ <c>init_per_group</c> or <c>per_testcase</c> hooks. So if you want to spawn a
+ process in the CTH, you cannot link with the CTH process, as it exits
+ after the post hook ends. Also, if you for some reason need an ETS
+ table with your CTH, you must spawn a process that handles it.</p>
</section>
<section>
- <title>External configuration data and Logging</title>
- <p>It's possible in the CTH to read configuration data values
- by calling <seealso marker="ct#get_config-1"><c>ct:get_config/1/2/3</c></seealso> (as explained in the
- <seealso marker="config_file_chapter#require_config_data">
- External configuration data</seealso>
- chapter). The config variables in question must, as always, first have been
- <c>required</c> by means of a suite-, group-, or test case info function,
- or the <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> function. Note that the latter can also be used
- in CT hook functions.</p>
- <p>The CT hook functions may call any of the logging functions available
+ <title>External Configuration Data and Logging</title>
+ <p>Configuration data values in the CTH can be read
+ by calling
+ <seealso marker="ct#get_config-1"><c>ct:get_config/1,2,3</c></seealso>
+ (as explained in section
+ <seealso marker="config_file_chapter#require_config_data">Requiring and Reading Configuration Data</seealso>).
+ The configuration variables in question must, as always, first have been
+ required by a suite-, group-, or test case information function,
+ or by function <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.
+ The latter can also be used in CT hook functions.</p>
+ <p>The CT hook functions can call any logging function
in the <c>ct</c> interface to print information to the log files, or to
add comments in the suite overview page.
</p>
@@ -207,307 +212,328 @@
</section>
- <marker id="manipulating"/>
<section>
- <title>Manipulating tests</title>
- <p>It is through CTHs possible to manipulate the results of tests and
- configuration functions. The main purpose of doing this with CTHs is to
- allow common patterns to be abstracted out from test test suites and applied to
- multiple test suites without duplicating any code. All of the callback
- functions for a CTH follow a common interface, this interface is
- described below.</p>
-
- <p>Common Test will always call all available hook functions, even pre- and post
- hooks for configuration functions that are not implemented in the suite.
+ <marker id="manipulating"/>
+ <title>Manipulating Tests</title>
+ <p>Through CTHs the results of tests and configuration functions can be manipulated.
+ The main purpose to do this with CTHs is to allow common
+ patterns to be abstracted out from test suites and applied to
+ multiple test suites without duplicating any code. All the callback
+ functions for a CTH follow a common interface described hereafter.</p>
+
+ <p><c>Common Test</c> always calls all available hook functions, even pre-
+ and post hooks for configuration functions that are not implemented in the suite.
For example, <c>pre_init_per_suite(x_SUITE, ...)</c> and
- <c>post_init_per_suite(x_SUITE, ...)</c> will be called for test suite
- <c>x_SUITE</c>, even if it doesn't export <c>init_per_suite/1</c>. This feature
- makes it possible to use hooks as configuration fallbacks, or even
- completely replace all configuration functions with hook functions.</p>
+ <c>post_init_per_suite(x_SUITE, ...)</c> are called for test suite
+ <c>x_SUITE</c>, even if it does not export <c>init_per_suite/1</c>.
+ With this feature hooks can be used as configuration fallbacks, and all
+ configuration functions can be replaced with hook functions.</p>
- <marker id="pre"/>
<section>
+ <marker id="pre"/>
<title>Pre Hooks</title>
<p>
- It is possible in a CTH to hook in behaviour before
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite</seealso>,
- <seealso marker="common_test#Module:init_per_suite-1">init_per_group</seealso>,
- <seealso marker="common_test#Module:init_per_suite-1">init_per_testcase</seealso>,
- <seealso marker="common_test#Module:init_per_suite-1">end_per_group</seealso> and
- <seealso marker="common_test#Module:init_per_suite-1">end_per_suite</seealso>.
+ In a CTH, the behavior can be hooked in before the following functions:</p>
+
+ <list type="bulleted">
+ <item><seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso></item>
+ <item><seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso></item>
+ <item><seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso></item>
+ <item><seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso></item>
+ <item><seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso></item>
+ <item><seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso></item>
+ </list>
+
+ <p>
This is done in the CTH functions called pre_&lt;name of function&gt;.
- All of these functions take the same three arguments: <c>Name</c>,
- <c>Config</c> and <c>CTHState</c>. The return value of the CTH function
- is always a combination of an result for the suite/group/test and an
- updated <c>CTHState</c>. If you want the test suite to continue on
- executing you should return the config list which you want the test to
- use as the result. If you for some reason want to skip/fail the test,
- return a tuple with <c>skip</c> or <c>fail</c> and a reason as the
- result. Example:
- </p>
- <code>pre_init_per_suite(SuiteName, Config, CTHState) -&gt;
- case db:connect() of
- {error,_Reason} -&gt;
- {{fail, "Could not connect to DB"}, CTHState};
- {ok, Handle} -&gt;
- {[{db_handle, Handle} | Config], CTHState#state{ handle = Handle }}
- end.</code>
- <note><p>If using multiple CTHs, the first part of the return tuple will be
- used as input for the next CTH. So in the case above the next CTH might
+ These functions take the same three arguments, <c>Name</c>,
+ <c>Config</c>, and <c>CTHState</c>. The return value of the CTH function
+ is always a combination of a result for the suite/group/test and an
+ updated <c>CTHState</c>.</p>
+
+ <p>To let the test suite continue on executing, return the configuration
+ list that you want the test to use as the result. To skip or
+ fail the test, return a tuple with <c>skip</c> or <c>fail</c>, and a reason
+ as the result.</p>
+
+ <p><em>Example:</em></p>
+ <code>
+ pre_init_per_suite(SuiteName, Config, CTHState) -&gt;
+ case db:connect() of
+ {error,_Reason} -&gt;
+ {{fail, "Could not connect to DB"}, CTHState};
+ {ok, Handle} -&gt;
+ {[{db_handle, Handle} | Config], CTHState#state{ handle = Handle }}
+ end.</code>
+
+ <note><p>If you use multiple CTHs, the first part of the return tuple is
+ used as input for the next CTH. So in the previous example the next CTH can
get <c>{fail,Reason}</c> as the second parameter. If you have many CTHs
- which interact, it might be a good idea to not let each CTH return
- <c>fail</c> or <c>skip</c>. Instead return that an action should be taken
- through the <c>Config</c> list and implement a CTH which at the end takes
- the correct action.</p></note>
+ interacting, do not let each CTH return <c>fail</c> or <c>skip</c>.
+ Instead, return that an action is to be taken through the <c>Config</c>
+ list and implement a CTH that, at the end, takes the correct action.</p></note>
</section>
- <marker id="post"/>
<section>
+ <marker id="post"/>
<title>Post Hooks</title>
- <p>It is also possible in a CTH to hook in behaviour after
- <seealso marker="common_test#Module:init_per_suite-1">init_per_suite</seealso>,
- <seealso marker="common_test#Module:init_per_suite-1">init_per_group</seealso>,
- <seealso marker="common_test#Module:init_per_suite-1">end_per_testcase</seealso>,
- <seealso marker="common_test#Module:init_per_suite-1">end_per_group</seealso> and
- <seealso marker="common_test#Module:init_per_suite-1">end_per_suite</seealso>.
- This is done in the CTH functions called post_&lt;name of function&gt;.
- All of these function take the same four arguments: <c>Name</c>,
- <c>Config</c>, <c>Return</c> and <c>CTHState</c>. <c>Config</c> in this
+ <p>In a CTH, behavior can be hooked in after the following functions:</p>
+ <list type="bulleted">
+ <item><seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso></item>
+ <item><seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso></item>
+ <item><seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso></item>
+ <item><seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso></item>
+ <item><seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso></item>
+ <item><seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso></item>
+ </list>
+
+ <p>
+ This is done in the CTH functions called <c>post_&lt;name of function&gt;</c>.
+ These functions take the same four arguments, <c>Name</c>,
+ <c>Config</c>, <c>Return</c>, and <c>CTHState</c>. <c>Config</c> in this
case is the same <c>Config</c> as the testcase is called with.
<c>Return</c> is the value returned by the testcase. If the testcase
- failed by crashing, <c>Return</c> will be
+ fails by crashing, <c>Return</c> is
<c>{'EXIT',{{Error,Reason},Stacktrace}}</c>.</p>
- <p>The return value of the CTH function is always a combination of an
+ <p>The return value of the CTH function is always a combination of a
result for the suite/group/test and an updated <c>CTHState</c>. If
- you want the callback to not affect the outcome of the test you should
+ you do not want the callback to affect the outcome of the test,
return the <c>Return</c> data as it is given to the CTH. You can also
- modify the result of the test. By returning the <c>Config</c> list
- with the <c>tc_status</c> element removed you can recover from a test
+ modify the test result. By returning the <c>Config</c> list
+ with element <c>tc_status</c> removed, you can recover from a test
failure. As in all the pre hooks, it is also possible to fail/skip
- the test case in the post hook. Example: </p>
-
- <code>post_end_per_testcase(_TC, Config, {'EXIT',{_,_}}, CTHState) -&gt;
- case db:check_consistency() of
- true ->
- %% DB is good, pass the test.
- {proplists:delete(tc_status, Config), CTHState};
- false ->
- %% DB is not good, mark as skipped instead of failing
- {{skip, "DB is inconsisten!"}, CTHState}
- end;
-post_end_per_testcase(_TC, Config, Return, CTHState) -&gt;
- %% Do nothing if tc does not crash.
- {Return, CTHState}.</code>
-
- <note><p>Recovering from a testcase failure using CTHs should only be done as
- a last resort. If used wrongly it could become very difficult to
- determine which tests pass or fail in a test run</p></note>
+ the test case in the post hook.</p>
+
+ <p><em>Example:</em></p>
+ <code>
+ post_end_per_testcase(_TC, Config, {'EXIT',{_,_}}, CTHState) -&gt;
+ case db:check_consistency() of
+ true ->
+ %% DB is good, pass the test.
+ {proplists:delete(tc_status, Config), CTHState};
+ false ->
+ %% DB is not good, mark as skipped instead of failing
+ {{skip, "DB is inconsisten!"}, CTHState}
+ end;
+ post_end_per_testcase(_TC, Config, Return, CTHState) -&gt;
+ %% Do nothing if tc does not crash.
+ {Return, CTHState}.</code>
+
+ <note><p>Do recover from a testcase failure using CTHs only a last resort.
+ If used wrongly, it can be very difficult to determine which tests that
+ pass or fail in a test run.</p></note>
</section>
- <marker id="skip_n_fail"/>
<section>
- <title>Skip and Fail hooks</title>
+ <title>Skip and Fail Hooks</title>
<p>
After any post hook has been executed for all installed CTHs,
<seealso marker="ct_hooks#Module:on_tc_fail-3">on_tc_fail</seealso>
- or <seealso marker="ct_hooks#Module:on_tc_fail-3">on_tc_skip</seealso>
- might be called if the testcase failed or was skipped
- respectively. You cannot affect the outcome of the tests any further at
- this point.
+ or <seealso marker="ct_hooks#Module:on_tc_skip-3">on_tc_skip</seealso>
+ is called if the testcase failed or was skipped, respectively.
+ You cannot affect the outcome of the tests any further at this point.
</p>
</section>
</section>
- <marker id="synchronizing"/>
<section>
- <title>Synchronizing external user applications with Common Test</title>
+ <marker id="synchronizing"/>
+ <title>Synchronizing External User Applications with Common Test</title>
<p>CTHs can be used to synchronize test runs with external user applications.
- The init function may e.g. start and/or communicate with an application that
- has the purpose of preparing the SUT for an upcoming test run, or maybe
+ The init function can, for example, start and/or communicate with an application that
+ has the purpose of preparing the SUT for an upcoming test run, or
initialize a database for saving test data to during the test run. The
- terminate function may similarly order such an application to reset the SUT
+ terminate function can similarly order such an application to reset the SUT
after the test run, and/or tell the application to finish active sessions
and terminate.
Any system error- or progress reports generated during the init- or
- termination stage will be saved in the
- <seealso marker="run_test_chapter#pre_post_test_io_log">Pre-
- and post test I/O log</seealso>. (This is also true for any printouts made
+ termination stage are saved in the
+ <seealso marker="run_test_chapter#pre_post_test_io_log">Pre- and Post Test I/O Log</seealso>.
+ (This is also true for any printouts made
with <c>ct:log/2</c> and <c>ct:pal/2</c>).</p>
- <p>In order to ensure that Common Test doesn't start executing tests, or
+
+ <p>To ensure that <c>Common Test</c> does not start executing tests, or
closes its log files and shuts down, before the external application
- is ready for it, Common Test may be synchronized with the application.
- During startup and shutdown, Common Test can be suspended, simply by
+ is ready for it, <c>Common Test</c> can be synchronized with the application.
+ During startup and shutdown, <c>Common Test</c> can be suspended, simply by
having a CTH evaluate a <c>receive</c> expression in the init- or terminate
function. The macros <c>?CT_HOOK_INIT_PROCESS</c> (the process executing the hook
init function) and <c>?CT_HOOK_TERMINATE_PROCESS</c> (the process executing
- the hook terminate function), each specifies the name of the correct Common Test
- process to send a message to in order to return from the <c>receive</c>.
+ the hook terminate function) each specifies the name of the correct <c>Common Test</c>
+ process to send a message to. This is done to return from the <c>receive</c>.
These macros are defined in <c>ct.hrl</c>.
</p>
</section>
- <marker id="example"/>
<section>
+ <marker id="example"/>
<title>Example CTH</title>
- <p>The CTH below will log information about a test run into a format
- parseable by <seealso marker="kernel:file#consult-1">file:consult/1</seealso>.
+ <p>The following CTH logs information about a test run into a format
+ parseable by <seealso marker="kernel:file#consult-1">file:consult/1</seealso>
+ (in <c>Kernel</c>):
</p>
- <code>%%% @doc Common Test Example Common Test Hook module.
--module(example_cth).
-
-%% Callbacks
--export([id/1]).
--export([init/2]).
-
--export([pre_init_per_suite/3]).
--export([post_init_per_suite/4]).
--export([pre_end_per_suite/3]).
--export([post_end_per_suite/4]).
-
--export([pre_init_per_group/3]).
--export([post_init_per_group/4]).
--export([pre_end_per_group/3]).
--export([post_end_per_group/4]).
-
--export([pre_init_per_testcase/3]).
--export([post_end_per_testcase/4]).
-
--export([on_tc_fail/3]).
--export([on_tc_skip/3]).
-
--export([terminate/1]).
-
--record(state, { file_handle, total, suite_total, ts, tcs, data }).
-
-%% @doc Return a unique id for this CTH.
-id(Opts) ->
- proplists:get_value(filename, Opts, "/tmp/file.log").
-
-%% @doc Always called before any other callback function. Use this to initiate
-%% any common state.
-init(Id, Opts) ->
- {ok,D} = file:open(Id,[write]),
- {ok, #state{ file_handle = D, total = 0, data = [] }}.
-
-%% @doc Called before init_per_suite is called.
-pre_init_per_suite(Suite,Config,State) ->
- {Config, State#state{ suite_total = 0, tcs = [] }}.
-
-%% @doc Called after init_per_suite.
-post_init_per_suite(Suite,Config,Return,State) ->
- {Return, State}.
-
-%% @doc Called before end_per_suite.
-pre_end_per_suite(Suite,Config,State) ->
- {Config, State}.
-
-%% @doc Called after end_per_suite.
-post_end_per_suite(Suite,Config,Return,State) ->
- Data = {suites, Suite, State#state.suite_total, lists:reverse(State#state.tcs)},
- {Return, State#state{ data = [Data | State#state.data] ,
- total = State#state.total + State#state.suite_total } }.
-
-%% @doc Called before each init_per_group.
-pre_init_per_group(Group,Config,State) ->
- {Config, State}.
-
-%% @doc Called after each init_per_group.
-post_init_per_group(Group,Config,Return,State) ->
- {Return, State}.
-
-%% @doc Called after each end_per_group.
-pre_end_per_group(Group,Config,State) ->
- {Config, State}.
-
-%% @doc Called after each end_per_group.
-post_end_per_group(Group,Config,Return,State) ->
- {Return, State}.
-
-%% @doc Called before each test case.
-pre_init_per_testcase(TC,Config,State) ->
- {Config, State#state{ ts = now(), total = State#state.suite_total + 1 } }.
-
-%% @doc Called after each test case.
-post_end_per_testcase(TC,Config,Return,State) ->
- TCInfo = {testcase, TC, Return, timer:now_diff(now(), State#state.ts)},
- {Return, State#state{ ts = undefined, tcs = [TCInfo | State#state.tcs] } }.
-
-%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
-%% post_end_per_group and post_end_per_testcase if the suite, group or test case failed.
-on_tc_fail(TC, Reason, State) ->
- State.
-
-%% @doc Called when a test case is skipped by either user action
-%% or due to an init function failing.
-on_tc_skip(TC, Reason, State) ->
- State.
-
-%% @doc Called when the scope of the CTH is done
-terminate(State) ->
- io:format(State#state.file_handle, "~p.~n",
- [{test_run, State#state.total, State#state.data}]),
- file:close(State#state.file_handle),
- ok.</code>
+ <code>
+ %%% @doc Common Test Example Common Test Hook module.
+ -module(example_cth).
+
+ %% Callbacks
+ -export([id/1]).
+ -export([init/2]).
+
+ -export([pre_init_per_suite/3]).
+ -export([post_init_per_suite/4]).
+ -export([pre_end_per_suite/3]).
+ -export([post_end_per_suite/4]).
+
+ -export([pre_init_per_group/3]).
+ -export([post_init_per_group/4]).
+ -export([pre_end_per_group/3]).
+ -export([post_end_per_group/4]).
+
+ -export([pre_init_per_testcase/3]).
+ -export([post_init_per_testcase/4]).
+ -export([pre_end_per_testcase/3]).
+ -export([post_end_per_testcase/4]).
+
+ -export([on_tc_fail/3]).
+ -export([on_tc_skip/3]).
+
+ -export([terminate/1]).
+
+ -record(state, { file_handle, total, suite_total, ts, tcs, data }).
+
+ %% @doc Return a unique id for this CTH.
+ id(Opts) ->
+ proplists:get_value(filename, Opts, "/tmp/file.log").
+
+ %% @doc Always called before any other callback function. Use this to initiate
+ %% any common state.
+ init(Id, Opts) ->
+ {ok,D} = file:open(Id,[write]),
+ {ok, #state{ file_handle = D, total = 0, data = [] }}.
+
+ %% @doc Called before init_per_suite is called.
+ pre_init_per_suite(Suite,Config,State) ->
+ {Config, State#state{ suite_total = 0, tcs = [] }}.
+
+ %% @doc Called after init_per_suite.
+ post_init_per_suite(Suite,Config,Return,State) ->
+ {Return, State}.
+
+ %% @doc Called before end_per_suite.
+ pre_end_per_suite(Suite,Config,State) ->
+ {Config, State}.
+
+ %% @doc Called after end_per_suite.
+ post_end_per_suite(Suite,Config,Return,State) ->
+ Data = {suites, Suite, State#state.suite_total, lists:reverse(State#state.tcs)},
+ {Return, State#state{ data = [Data | State#state.data] ,
+ total = State#state.total + State#state.suite_total } }.
+
+ %% @doc Called before each init_per_group.
+ pre_init_per_group(Group,Config,State) ->
+ {Config, State}.
+
+ %% @doc Called after each init_per_group.
+ post_init_per_group(Group,Config,Return,State) ->
+ {Return, State}.
+
+ %% @doc Called before each end_per_group.
+ pre_end_per_group(Group,Config,State) ->
+ {Config, State}.
+
+ %% @doc Called after each end_per_group.
+ post_end_per_group(Group,Config,Return,State) ->
+ {Return, State}.
+
+ %% @doc Called before each init_per_testcase.
+ pre_init_per_testcase(TC,Config,State) ->
+ {Config, State#state{ ts = now(), total = State#state.suite_total + 1 } }.
+
+ %% Called after each init_per_testcase (immediately before the test case).
+ post_init_per_testcase(TC,Config,Return,State) ->
+ {Return, State}
+
+%% @doc Called before each end_per_testcase (immediately after the test case).
+ pre_end_per_testcase(TC,Config,State) ->
+ {Config, State}.
+
+ %% @doc Called after each end_per_testcase.
+ post_end_per_testcase(TC,Config,Return,State) ->
+ TCInfo = {testcase, TC, Return, timer:now_diff(now(), State#state.ts)},
+ {Return, State#state{ ts = undefined, tcs = [TCInfo | State#state.tcs] } }.
+
+ %% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
+ %% post_end_per_group and post_end_per_testcase if the suite, group or test case failed.
+ on_tc_fail(TC, Reason, State) ->
+ State.
+
+ %% @doc Called when a test case is skipped by either user action
+ %% or due to an init function failing.
+ on_tc_skip(TC, Reason, State) ->
+ State.
+
+ %% @doc Called when the scope of the CTH is done
+ terminate(State) ->
+ io:format(State#state.file_handle, "~p.~n",
+ [{test_run, State#state.total, State#state.data}]),
+ file:close(State#state.file_handle),
+ ok.</code>
</section>
- <marker id="builtin_cths"/>
<section>
- <title>Built-in CTHs</title>
- <p>Common Test is delivered with a couple of general purpose CTHs that
- can be enabled by the user to provide some generic testing functionality.
- Some of these are enabled by default when starting running common_test,
- they can be disabled by setting <c>enable_builtin_hooks</c> to
- <c>false</c> on the command line or in the test specification. In the
- table below there is a list of all current CTHs which are delivered with
- Common Test.</p>
-
- <table>
- <row>
- <cell align="left"><em>CTH Name</em></cell>
- <cell align="left"><em>Is Built-in</em></cell>
- <cell align="left"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left">cth_log_redirect</cell>
- <cell align="left">yes</cell>
- <cell align="left">Captures all error_logger and SASL logging events and prints them
- to the current test case log. If an event can not be associated with a
- testcase it will be printed in the common test framework log. This will
- happen for testcases which are run in parallel and events which occur
- inbetween testcases. You can configure the level of
- <seealso marker="sasl:sasl_app">SASL</seealso> events report
- using the normal SASL mechanisms. </cell>
- </row>
- <row>
- <cell align="left">cth_surefire</cell>
- <cell align="left">no</cell>
- <cell align="left"><p>Captures all test results and outputs them as surefire
- XML into a file. The file which is created is by default
- called junit_report.xml. The file name can be changed by
- setting the <c>path</c> option for this hook, e.g.</p>
-
- <code>-ct_hooks cth_surefire [{path,"/tmp/report.xml"}]</code>
-
- <p>If the <c>url_base</c> option is set, an additional
- attribute named <c>url</c> will be added to each
- <c>testsuite</c> and <c>testcase</c> XML element. The value will
- be constructed from the <c>url_base</c> and a relative path
- to the test suite or test case log respectively, e.g.</p>
-
- <code>-ct_hooks cth_surefire [{url_base, "http://myserver.com/"}]</code>
- <p>will give a url attribute value similar to</p>
-
- <code>"http://myserver.com/[email protected]_11.19.39/
-x86_64-unknown-linux-gnu.my_test.logs/run.2012-12-12_11.19.39/suite.log.html"</code>
-
- <p>Surefire XML can for instance be used by Jenkins to display test
- results.</p></cell>
- </row>
- </table>
+ <marker id="builtin_cths"/>
+ <title>Built-In CTHs</title>
+ <p><c>Common Test</c> is delivered with some general-purpose CTHs that
+ can be enabled by the user to provide generic testing functionality.
+ Some of these CTHs are enabled by default when <c>common_test</c> is started to run.
+ They can be disabled by setting <c>enable_builtin_hooks</c> to
+ <c>false</c> on the command line or in the test specification. The following
+ two CTHs are delivered with <c>Common Test</c>:</p>
+
+ <taglist>
+ <tag><c>cth_log_redirect</c></tag>
+ <item>
+ <p>Built-in</p>
+ <p>Captures all <c>error_logger</c> and <c>SASL</c> logging
+ events and prints them to the current test case log. If an event cannot be
+ associated with a test case, it is printed in the <c>Common Test</c> framework log.
+ This happens for test cases running in parallel and events occuring
+ in-between test cases. You can configure the level of
+ <seealso marker="sasl:sasl_app"><c>SASL</c></seealso> events report
+ using the normal <c>SASL</c> mechanisms.</p>
+ </item>
+ <tag><c>cth_surefire</c></tag>
+ <item>
+ <p>Not built-in</p>
+ <p>Captures all test results and outputs them as surefire
+ XML into a file. The created file is by default
+ called <c>junit_report.xml</c>. The file name can be changed by
+ setting option <c>path</c> for this hook, for example:</p>
+
+ <p><c>-ct_hooks cth_surefire [{path,"/tmp/report.xml"}]</c></p>
+
+ <p>If option <c>url_base</c> is set, an extra
+ attribute named <c>url</c> is added to each
+ <c>testsuite</c> and <c>testcase</c> XML element. The value
+ is constructed from <c>url_base</c> and a relative path
+ to the test suite or test case log, respectively, for example:</p>
+
+ <p><c>-ct_hooks cth_surefire [{url_base, "http://myserver.com/"}]</c></p>
+
+ <p>gives an URL attribute value similar to</p>
+
+ <p><c>"http://myserver.com/[email protected]_11.19.39/
+x86_64-unknown-linux-gnu.my_test.logs/run.2012-12-12_11.19.39/suite.log.html"</c></p>
+
+ <p>Surefire XML can, for example, be used by Jenkins to display test
+ results.</p>
+ </item>
+ </taglist>
</section>
diff --git a/lib/common_test/doc/src/ct_master.xml b/lib/common_test/doc/src/ct_master.xml
new file mode 100644
index 0000000000..06f9b04f1b
--- /dev/null
+++ b/lib/common_test/doc/src/ct_master.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_master</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_master.xml</file>
+ </header>
+ <module>ct_master</module>
+ <modulesummary>Distributed test execution control for Common Test.</modulesummary>
+
+<description>
+
+ <p>Distributed test execution control for <c>Common Test</c>.</p>
+
+ <p>This module exports functions for running <c>Common Test</c> nodes on
+ multiple hosts in parallel.</p>
+
+</description>
+
+ <funcs>
+ <func>
+ <name>abort() -&gt; ok</name>
+ <fsummary>Stops all running tests.</fsummary>
+ <desc><marker id="abort-0"/>
+ <p>Stops all running tests.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>abort(Nodes) -&gt; ok</name>
+ <fsummary>Stops tests on specified nodes.</fsummary>
+ <type>
+ <v>Nodes = atom() | [atom()]</v>
+ </type>
+ <desc><marker id="abort-1"/>
+ <p>Stops tests on specified nodes.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>basic_html(Bool) -&gt; ok</name>
+ <fsummary>If set to true, the ct_master logs are written on a primitive
+ HTML format, not using the <c>Common Test</c> CSS style sheet.</fsummary>
+ <type>
+ <v>Bool = true | false</v>
+ </type>
+ <desc><marker id="basic_html-1"/>
+ <p>If set to <c>true</c>, the <c>ct_master logs</c> are written on a
+ primitive HTML format, not using the <c>Common Test</c> CSS style
+ sheet.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_event_mgr_ref() -&gt; MasterEvMgrRef</name>
+ <fsummary>Gets a reference to the <c>Common Test</c> master event
+ manager.</fsummary>
+ <type>
+ <v>MasterEvMgrRef = atom()</v>
+ </type>
+ <desc><marker id="get_event_mgr_ref-0"/>
+ <p>Gets a reference to the <c>Common Test</c> master event manager.
+ The reference can be used to, for example, add a user-specific
+ event handler while tests are running.</p>
+
+ <p><em>Example:</em></p>
+
+ <pre>
+ gen_event:add_handler(ct_master:get_event_mgr_ref(), my_ev_h, [])</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name>progress() -&gt; [{Node, Status}]</name>
+ <fsummary>Returns test progress.</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ <v>Status = finished_ok | ongoing | aborted | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="progress-0"/>
+ <p>Returns test progress. If <c>Status</c> is <c>ongoing</c>, tests
+ are running on the node and are not yet finished.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run(TestSpecs) -&gt; ok</name>
+ <fsummary>Equivalent to run(TestSpecs, false, [], []).</fsummary>
+ <type>
+ <v>TestSpecs = string() | [SeparateOrMerged]</v>
+ </type>
+ <desc><marker id="run-1"/>
+ <p>Equivalent to <seealso marker="#run-4"><c>ct_master:run(TestSpecs,
+ false, [], [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run(TestSpecs, InclNodes, ExclNodes) -&gt; ok</name>
+ <fsummary>Equivalent to run(TestSpecs, false, InclNodes, ExclNodes).
+ </fsummary>
+ <type>
+ <v>TestSpecs = string() | [SeparateOrMerged]</v>
+ <v>SeparateOrMerged = string() | [string()]</v>
+ <v>InclNodes = [atom()]</v>
+ <v>ExclNodes = [atom()]</v>
+ </type>
+ <desc><marker id="run-3"/>
+ <p>Equivalent to <seealso marker="#run-4"><c>ct_master:run(TestSpecs,
+ false, InclNodes, ExclNodes)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run(TestSpecs, AllowUserTerms, InclNodes, ExclNodes) -&gt; ok</name>
+ <fsummary>Tests are spawned on the nodes as specified in TestSpecs.
+ </fsummary>
+ <type>
+ <v>TestSpecs = string() | [SeparateOrMerged]</v>
+ <v>SeparateOrMerged = string() | [string()]</v>
+ <v>AllowUserTerms = bool()</v>
+ <v>InclNodes = [atom()]</v>
+ <v>ExclNodes = [atom()]</v>
+ </type>
+ <desc><marker id="run-4"/>
+ <p>Tests are spawned on the nodes as specified in <c>TestSpecs</c>.
+ Each specification in <c>TestSpec</c> is handled separately.
+ However, it is also possible to specify a list of specifications to
+ be merged into one specification before the tests are executed. Any
+ test without a particular node specification is also executed on
+ the nodes in <c>InclNodes</c>. Nodes in the <c>ExclNodes</c> list
+ are excluded from the test.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run_on_node(TestSpecs, Node) -&gt; ok</name>
+ <fsummary>Equivalent to run_on_node(TestSpecs, false, Node).</fsummary>
+ <type>
+ <v>TestSpecs = string() | [SeparateOrMerged]</v>
+ <v>SeparateOrMerged = string() | [string()]</v>
+ <v>Node = atom()</v>
+ </type>
+ <desc><marker id="run_on_node-2"/>
+ <p>Equivalent to
+ <seealso marker="#run_on_node-3"><c>ct_master:run_on_node(TestSpecs,
+ false, Node)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run_on_node(TestSpecs, AllowUserTerms, Node) -&gt; ok</name>
+ <fsummary>Tests are spawned on Node according to TestSpecs.</fsummary>
+ <type>
+ <v>TestSpecs = string() | [SeparateOrMerged]</v>
+ <v>SeparateOrMerged = string() | [string()]</v>
+ <v>AllowUserTerms = bool()</v>
+ <v>Node = atom()</v>
+ </type>
+ <desc><marker id="run_on_node-3"/>
+ <p>Tests are spawned on <c>Node</c> according to <c>TestSpecs</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>run_test(Node, Opts) -&gt; ok</name>
+ <fsummary>Tests are spawned on Node using ct:run_test/1.</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ <v>Opts = [OptTuples]</v>
+ <v>OptTuples = {config, CfgFiles} | {dir, TestDirs} | {suite, Suites} | {testcase, Cases} | {spec, TestSpecs} | {allow_user_terms, Bool} | {logdir, LogDir} | {event_handler, EventHandlers} | {silent_connections, Conns} | {cover, CoverSpecFile} | {cover_stop, Bool} | {userconfig, UserCfgFiles}</v>
+ <v>CfgFiles = string() | [string()]</v>
+ <v>TestDirs = string() | [string()]</v>
+ <v>Suites = atom() | [atom()]</v>
+ <v>Cases = atom() | [atom()]</v>
+ <v>TestSpecs = string() | [string()]</v>
+ <v>LogDir = string()</v>
+ <v>EventHandlers = EH | [EH]</v>
+ <v>EH = atom() | {atom(), InitArgs} | {[atom()], InitArgs}</v>
+ <v>InitArgs = [term()]</v>
+ <v>Conns = all | [atom()]</v>
+ </type>
+ <desc><marker id="run_test-2"/>
+ <p>Tests are spawned on <c>Node</c> using
+ <seealso marker="ct:run_test-1"><c>ct:run_test/1</c></seealso></p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_master_chapter.xml b/lib/common_test/doc/src/ct_master_chapter.xml
index 37a0805055..99555164e0 100644
--- a/lib/common_test/doc/src/ct_master_chapter.xml
+++ b/lib/common_test/doc/src/ct_master_chapter.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Using Common Test for Large Scale Testing</title>
+ <title>Using Common Test for Large-Scale Testing</title>
<prepared>Peter Andersson</prepared>
<docno></docno>
<date></date>
@@ -32,217 +33,220 @@
<section>
<marker id="general"></marker>
<title>General</title>
- <p>Large scale automated testing requires running multiple independent
+ <p>Large-scale automated testing requires running multiple independent
test sessions in parallel. This is accomplished by running
- a number of Common Test nodes on one or more hosts, testing
- different target systems. Configuring, starting and controlling the
+ some <c>Common Test</c> nodes on one or more hosts, testing
+ different target systems. Configuring, starting, and controlling the
test nodes independently can be a cumbersome operation. To aid
- this kind of automated large scale testing, CT offers a master test
- node component, CT Master, that handles central configuration and control
- in a system of distributed CT nodes.</p>
+ this kind of automated large-scale testing, <c>Common Test</c> offers a master
+ test node component, <c>Common Test</c> Master, which handles central configuration and control
+ in a system of distributed <c>Common Test</c> nodes.</p>
- <p>The CT Master server runs on one dedicated Erlang node and uses distributed
- Erlang to communicate with any number of CT test nodes, each hosting a regular
- CT server. Test specifications are used as input to specify what to test on which
+ <p>The <c>Common Test</c> Master server runs on one dedicated Erlang node and uses distributed
+ Erlang to communicate with any number of <c>Common Test</c> test nodes, each hosting a regular
+ <c>Common Test</c> server. Test specifications are used as input to specify what to test on which
test nodes, using what configuration.</p>
- <p>The CT Master server writes progress information to HTML log files similarly
- to the regular CT server. The logs contain test statistics and links to the
- log files written by each independent CT server.</p>
+ <p>The <c>Common Test</c> Master server writes progress information to HTML log files similarly
+ to the regular <c>Common Test</c> server. The logs contain test statistics and links to the
+ log files written by each independent <c>Common Test</c> server.</p>
- <p>The CT master API is exported by the <c>ct_master</c> module.</p>
+ <p>The <c>Common Test</c> Master API is exported by module
+ <seealso marker="ct_master"><c>ct_master</c></seealso>.</p>
</section>
<section>
- <title>Usage</title>
- <p>CT Master requires all test nodes to be on the same network and share a common
- file system. As of this date, CT Master can not start test nodes
- automatically. The nodes must have been started in advance for CT Master to be
+ <title>Use</title>
+ <p><c>Common Test</c> Master requires all test nodes to be on the same network and share a common
+ file system. <c>Common Test</c> Master cannot start test nodes
+ automatically. The nodes must be started in advance for <c>Common Test</c> Master to be
able to start test sessions on them.</p>
- <p>Tests are started by calling:</p>
-
- <p><c>ct_master:run(TestSpecs)</c> or
- <c>ct_master:run(TestSpecs, InclNodes, ExclNodes)</c></p>
+ <p>Tests are started by calling
+ <seealso marker="ct_master#run-1"><c>ct_master:run(TestSpecs)</c></seealso> or
+ <seealso marker="ct_master#run-3"><c>ct_master:run(TestSpecs, InclNodes, ExclNodes)</c></seealso></p>
<p><c>TestSpecs</c> is either the name of a test specification file (string) or a list
- of test specifications. In case of a list, the specifications will be handled (and
+ of test specifications. If it is a list, the specifications are handled (and
the corresponding tests executed) in sequence. An element in a <c>TestSpecs</c> list
- can also be list of test specifications. The specifications in such a list will be
- merged into one combined specification prior to test execution. For example:</p>
-
- <p><c>ct_master:run(["ts1","ts2",["ts3","ts4"]])</c></p>
+ can also be list of test specifications. The specifications in such a list are
+ merged into one combined specification before test execution.</p>
+
+ <p><em>Example:</em></p>
+ <pre>
+ ct_master:run(["ts1","ts2",["ts3","ts4"]])</pre>
- <p>means first the tests specified by "ts1" will run, then the tests specified by "ts2"
+ <p>Here, the tests specified by "ts1" run first, then the tests specified by "ts2",
and finally the tests specified by both "ts3" and "ts4".</p>
- <p>The <c>InclNodes</c> argument to <c>run/3</c> is a list of node names. The <c>run/3</c>
- function runs the tests in <c>TestSpecs</c> just like <c>run/1</c> but will also
- take any test in <c>TestSpecs</c> that's not explicitly tagged with a particular
- node name and execute it on the nodes listed in <c>InclNodes</c>. By using <c>run/3</c>
- this way it is possible to use any test specification, with or without node information,
- in a large scale test environment! <c>ExclNodes</c> is a list of nodes that should be
- excluded from the test. I.e. tests that have been specified in the test specification
- to run on a particular node will not be performed if that node is at runtime
- listed in <c>ExclNodes</c>.</p>
-
- <p>If CT Master fails initially to connect to any of the test nodes specified in a
- test specification or in the <c>InclNodes</c> list, the operator will be prompted with
- the option to either start over again (after manually checking the status of the
- node(s) in question), to run without the missing nodes, or to abort the operation.</p>
+ <p>The <c>InclNodes</c> argument to <c>run/3</c> is a list of node names. Function
+ <c>run/3</c> runs the tests in <c>TestSpecs</c> just like <c>run/1</c>, but also
+ takes any test in <c>TestSpecs</c>, which is not explicitly tagged with a particular
+ node name, and execute it on the nodes listed in <c>InclNodes</c>. By using <c>run/3</c>
+ this way, any test specification can be used, with or without node information,
+ in a large-scale test environment.</p>
+
+ <p><c>ExclNodes</c> is a list of nodes to be
+ excluded from the test. That is, tests that are specified in the test specification
+ to run on a particular node are not performed if that node is
+ listed in <c>ExclNodes</c> at runtime.</p>
- <p>When tests start, CT Master prints information to console about the nodes that are
- involved. CT Master also reports when tests finish, successfully or unsuccessfully. If
- connection is lost to a node, the test on that node is considered finished. CT Master
- will not attempt to reestablish contact with the failing node. At any time to get the
- current status of the test nodes, call the function:</p>
+ <p>If <c>Common Test</c> Master fails initially to connect to any of the test nodes specified in a
+ test specification or in the <c>InclNodes</c> list, the operator is prompted with
+ the option to either start over again (after manually checking the status of the
+ nodes in question), to run without the missing nodes, or to abort the operation.</p>
- <p><c>ct_master:progress()</c></p>
+ <p>When tests start, <c>Common Test</c> Master displays information to console about the involved nodes.
+ <c>Common Test</c> Master also reports when tests finish, successfully or unsuccessfully. If
+ connection is lost to a node, the test on that node is considered finished. <c>Common Test</c> Master
+ does not attempt to re-establish contact with the failing node.</p>
- <p>To stop one or more tests, use:</p>
+ <p>At any time, to get the current status of the test nodes, call function
+ <seealso marker="ct_master#progress-0"><c>ct_master:progress()</c></seealso>.</p>
- <p><c>ct_master:abort()</c> (stop all) or <c>ct_master:abort(Nodes)</c></p>
+ <p>To stop one or more tests, use function
+ <seealso marker="ct_master#abort-0"><c>ct_master:abort()</c></seealso> (to stop all) or
+ <seealso marker="ct_master#abort-1"><c>ct_master:abort(Nodes)</c></seealso>.</p>
- <p>For detailed information about the <c>ct_master</c> API, please see the
- <seealso marker="ct_master">manual page</seealso> for this module.</p>
+ <p>For details about the <c>Common Test</c> Master API, see module
+ <seealso marker="ct_master"><c>ct_master</c></seealso>.</p>
</section>
<section>
<marker id="test_specifications"></marker>
<title>Test Specifications</title>
- <p>The test specifications used as input to CT Master are fully compatible with the
- specifications used as input to the regular CT server. The syntax is described in the
- <seealso marker="run_test_chapter#test_specifications">Running Test Suites</seealso>
- chapter.</p>
+ <p>The test specifications used as input to <c>Common Test</c> Master are fully compatible with the
+ specifications used as input to the regular <c>Common Test</c> server. The syntax is described in section
+ <seealso marker="run_test_chapter#test_specifications">Test Specifications</seealso>
+ in section Running Tests and Analyzing Results.</p>
<p>All test specification terms can have a <c>NodeRefs</c> element. This element
specifies which node or nodes a configuration operation or a test is to be executed
- on. <c>NodeRefs</c> is defined as:</p>
+ on. <c>NodeRefs</c> is defined as follows:</p>
<p><c>NodeRefs = all_nodes | [NodeRef] | NodeRef</c></p>
-
- <p>where</p>
<p><c>NodeRef = NodeAlias | node() | master</c></p>
<p>A <c>NodeAlias</c> (<c>atom()</c>) is used in a test specification as a
- reference to a node name (so the actual node name only needs to be declared once,
- which can of course also be achieved using constants).
- The alias is declared with a <c>node</c> term:</p>
+ reference to a node name (so the node name only needs to be declared once,
+ which also can be achieved using constants).
+ The alias is declared with a <c>node</c> term as follows:</p>
<p><c>{node, NodeAlias, NodeName}</c></p>
- <p>If <c>NodeRefs</c> has the value <c>all_nodes</c>, the operation or test will
- be performed on all given test nodes. (Declaring a term without a <c>NodeRefs</c>
- element actually has the same effect). If <c>NodeRefs</c> has the value
- <c>master</c>, the operation is only performed on the CT Master node (namely set
+ <p>If <c>NodeRefs</c> has the value <c>all_nodes</c>, the operation or test
+ is performed on all specified test nodes. (Declaring a term without a <c>NodeRefs</c>
+ element has the same effect). If <c>NodeRefs</c> has the value
+ <c>master</c>, the operation is only performed on the <c>Common Test</c> Master node (namely set
the log directory or install an event handler).</p>
- <p>Consider the example in the
- <seealso marker="run_test_chapter#test_specifications">Running Test Suites</seealso>
- chapter, now extended with node information and intended to be executed by the
- CT Master:</p>
+ <p>Consider the example in section
+ <seealso marker="run_test_chapter#test_specifications">Test Specifications</seealso>
+ in section Running Tests and Analysing Results,
+ now extended with node information and intended to be executed by
+ <c>Common Test</c> Master:</p>
<pre>
- {define, 'Top', "/home/test"}.
- {define, 'T1', "'Top'/t1"}.
- {define, 'T2', "'Top'/t2"}.
- {define, 'T3', "'Top'/t3"}.
- {define, 'CfgFile', "config.cfg"}.
- {define, 'Node', ct_node}.
-
- {node, node1, 'Node@host_x'}.
- {node, node2, 'Node@host_y'}.
-
- {logdir, master, "'Top'/master_logs"}.
- {logdir, "'Top'/logs"}.
-
- {config, node1, "'T1'/'CfgFile'"}.
- {config, node2, "'T2'/'CfgFile'"}.
- {config, "'T3'/'CfgFile'"}.
-
- {suites, node1, 'T1', all}.
- {skip_suites, node1, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
- {skip_cases, node1, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
- {skip_cases, node1, 'T1', t1C_SUITE, [test1], "Ignore"}.
-
- {suites, node2, 'T2', [t2B_SUITE,t2C_SUITE]}.
- {cases, node2, 'T2', t2A_SUITE, [test4,test1,test7]}.
-
- {skip_suites, 'T3', all, "Not implemented"}.</pre>
+ {define, 'Top', "/home/test"}.
+ {define, 'T1', "'Top'/t1"}.
+ {define, 'T2', "'Top'/t2"}.
+ {define, 'T3', "'Top'/t3"}.
+ {define, 'CfgFile', "config.cfg"}.
+ {define, 'Node', ct_node}.
+
+ {node, node1, 'Node@host_x'}.
+ {node, node2, 'Node@host_y'}.
+
+ {logdir, master, "'Top'/master_logs"}.
+ {logdir, "'Top'/logs"}.
+
+ {config, node1, "'T1'/'CfgFile'"}.
+ {config, node2, "'T2'/'CfgFile'"}.
+ {config, "'T3'/'CfgFile'"}.
+
+ {suites, node1, 'T1', all}.
+ {skip_suites, node1, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
+ {skip_cases, node1, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
+ {skip_cases, node1, 'T1', t1C_SUITE, [test1], "Ignore"}.
+
+ {suites, node2, 'T2', [t2B_SUITE,t2C_SUITE]}.
+ {cases, node2, 'T2', t2A_SUITE, [test4,test1,test7]}.
+
+ {skip_suites, 'T3', all, "Not implemented"}.</pre>
<p>This example specifies the same tests as the original example. But
- now if started with a call to <c>ct_master:run(TestSpecName)</c>, the
- t1 test will be executed on node <c>ct_node@host_x</c> (node1), the
- t2 test on <c>ct_node@host_y</c> (node2) and the t3 test on both
- node1 and node2. The t1 config file will only be read on
- node1 and the t2 config file only on node2, while the t3 config file
- will be read on both node1 and node2. Both test nodes will write log
- files to the same directory. (The CT Master node will however use a
- different log directory than the test nodes).</p>
+ now if started with a call to <c>ct_master:run(TestSpecName)</c>, test
+ <c>t1</c> is executed on node <c>ct_node@host_x</c> (<c>node1</c>), test
+ <c>t2</c> on <c>ct_node@host_y</c> (<c>node2</c>) and test <c>t3</c>
+ on both <c>node1</c> and <c>node2</c>. Configuration file <c>t1</c> is only read on
+ <c>node1</c> and configuration file <c>t2</c> only on <c>node2</c>, while the
+ configuration file <c>t3</c> is read on both <c>node1</c> and <c>node2</c>.
+ Both test nodes write log files to the same directory. (However, the <c>Common Test</c> Master
+ node uses a different log directory than the test nodes.)</p>
<p>If the test session is instead started with a call to
<c>ct_master:run(TestSpecName, [ct_node@host_z], [ct_node@host_x])</c>,
- the result is that the t1 test does not run on
- <c>ct_node@host_x</c> (or any other node) while the t3 test runs on
+ the result is that test <c>t1</c> does not run on
+ <c>ct_node@host_x</c> (or any other node) while test <c>t3</c> runs on both
<c>ct_node@host_y</c> and <c>ct_node@host_z</c>.</p>
<p>A nice feature is that a test specification that includes node
- information can still be used as input to the regular Common Test server
- (as described in the
- <seealso marker="run_test_chapter#test_specifications">Running Test Suites</seealso>
- chapter). The result is that any test specified to run on a node with the same
- name as the Common Test node in question (typically <c>ct@somehost</c> if started
- with the <c>ct_run</c> program), will be performed. Tests without explicit
- node association will always be performed too of course!</p>
+ information can still be used as input to the regular <c>Common Test</c> server
+ (as described in section
+ <seealso marker="run_test_chapter#test_specifications">Test Specifications</seealso>).
+ The result is that any test specified to run on a node with the same
+ name as the <c>Common Test</c> node in question (typically <c>ct@somehost</c> if started
+ with the <c>ct_run</c> program), is performed. Tests without explicit
+ node association are always performed too, of course.</p>
</section>
<section>
- <title>Automatic startup of test target nodes</title>
+ <title>Automatic Startup of Test Target Nodes</title>
<marker id="ct_slave"></marker>
- <p>Is is possible to automatically start, and perform initial actions, on
- test target nodes by using the test specification term <c>init</c>.</p>
- <p>Currently, two sub-terms are supported, <c>node_start</c> and <c>eval</c>.</p>
- <p>Example:</p>
+ <p>Initial actions can be started and performed automatically on
+ test target nodes using test specification term <c>init</c>.</p>
+ <p>Two subterms are supported, <c>node_start</c> and <c>eval</c>.</p>
+ <p><em>Example:</em></p>
<pre>
- {node, node1, node1@host1}.
- {node, node2, node1@host2}.
- {node, node3, node2@host2}.
- {node, node4, node1@host3}.
- {init, node1, [{node_start, [{callback_module, my_slave_callback}]}]}.
- {init, [node2, node3], {node_start, [{username, "ct_user"}, {password, "ct_password"}]}}.
- {init, node4, {eval, {module, function, []}}}.</pre>
+ {node, node1, node1@host1}.
+ {node, node2, node1@host2}.
+ {node, node3, node2@host2}.
+ {node, node4, node1@host3}.
+ {init, node1, [{node_start, [{callback_module, my_slave_callback}]}]}.
+ {init, [node2, node3], {node_start, [{username, "ct_user"}, {password, "ct_password"}]}}.
+ {init, node4, {eval, {module, function, []}}}.</pre>
<p>This test specification declares that <c>node1@host1</c> is to be started using
the user callback function <c>callback_module:my_slave_callback/0</c>, and nodes
- <c>node1@host2</c> and <c>node2@host2</c> will be started with the default callback
- module <c>ct_slave</c>. The given user name and password is used to log into remote
- host <c>host2</c>. Also, the function <c>module:function/0</c> will be evaluated on
- <c>node1@host3</c>, and the result of this call will be printed to the log.</p>
+ <c>node1@host2</c> and <c>node2@host2</c> are to be started with the default callback
+ module <c>ct_slave</c>. The specified username and password are used to log on to remote
+ host <c>host2</c>. Also, function <c>module:function/0</c> is evaluated on
+ <c>node1@host3</c>, and the result of this call is printed to the log.</p>
- <p>The default <seealso marker="ct_slave">ct_slave</seealso> callback module,
- which is part of the Common Test application, has the following features:
+ <p>The default callback module <seealso marker="ct_slave">ct_slave</seealso>,
+ has the following features:
</p>
- <list>
+ <list type="bulleted">
<item>Starting Erlang target nodes on local or remote hosts
- (ssh is used for communication).
+ (application <c>SSH</c> is used for communication).
</item>
- <item>Ability to start an Erlang emulator with additional flags
+ <item>Ability to start an Erlang emulator with more flags
(any flags supported by <c>erl</c> are supported).
</item>
- <item>Supervision of a node being started by means of internal callback
- functions. Used to prevent hanging nodes. (Configurable).
+ <item>Supervision of a node being started using internal callback
+ functions. Used to prevent hanging nodes. (Configurable.)
</item>
- <item>Monitoring of the master node by the slaves. A slave node may be
- stopped in case the master node terminates. (Configurable).
+ <item>Monitoring of the master node by the slaves. A slave node can be
+ stopped if the master node terminates. (Configurable.)
</item>
- <item>Execution of user functions after a slave node is started.
- Functions can be given as a list of {Module, Function, Arguments} tuples.
+ <item>Execution of user functions after a slave node is started. Functions can
+ be specified as a list of <c>{Module, Function, Arguments}</c> tuples.
</item>
</list>
- <p>Note that it is possible to specify an <c>eval</c> term for the node as well
- as <c>startup_functions</c> in the <c>node_start</c> options list. In this
- case first the node will be started, then the <c>startup_functions</c> are
+ <note><p>An <c>eval</c> term for the node and
+ <c>startup_functions</c> in the <c>node_start</c> options list can be specified.
+ In this case, the node is started first, then the <c>startup_functions</c> are
executed, and finally functions specified with <c>eval</c> are called.
- </p>
+ </p></note>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/ct_netconfc.xml b/lib/common_test/doc/src/ct_netconfc.xml
new file mode 100644
index 0000000000..d8c82c7f2c
--- /dev/null
+++ b/lib/common_test/doc/src/ct_netconfc.xml
@@ -0,0 +1,1039 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_netconfc</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_netconfc.xml</file>
+ </header>
+ <module>ct_netconfc</module>
+ <modulesummary>NETCONF client module.</modulesummary>
+
+<description>
+
+ <p>NETCONF client module.</p>
+
+ <p>The NETCONF client is compliant with RFC 4741 NETCONF Configuration
+ Protocol and RFC 4742 Using the NETCONF Configuration Protocol over
+ Secure SHell (SSH)..</p>
+
+ <p>For each server to test against, the following entry can be added to a
+ configuration file:</p>
+
+ <pre>
+ {server_id(),options()}.</pre>
+
+ <p>The <c>server_id()</c> or an associated <c>target_name()</c> (see
+ module <seealso marker="ct"><c>ct</c></seealso>) must then be used
+ in calls to
+ <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>.</p>
+
+ <p>If no configuration exists for a server, a session can still be
+ opened by calling
+ <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> with
+ all necessary options specified in the call. The first argument to
+ <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> can
+ then be any atom.</p>
+
+ </description>
+
+ <section>
+ <marker id="Logging"/>
+ <title>Logging</title>
+ <p>The NETCONF server uses <c>error_logger</c> for logging of NETCONF
+ traffic. A special purpose error handler is implemented in
+ <c>ct_conn_log_h</c>. To use this error handler, add the
+ <c>cth_conn_log</c> hook in the test suite, for example:</p>
+
+ <pre>
+ suite() -&gt;
+ [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].</pre>
+
+ <p><c>conn_mod()</c> is the name of the <c>Common Test</c> module
+ implementing the connection protocol, for example, <c>ct_netconfc</c>.</p>
+
+ <p>Hook option <c>log_type</c> specifies the type of logging:</p>
+
+ <taglist>
+ <tag><c>raw</c></tag>
+ <item><p>The sent and received NETCONF data is logged to a separate
+ text file "as is" without any formatting. A link to the file is
+ added to the test case HTML log.</p>.</item>
+
+ <tag><c>pretty</c></tag>
+ <item><p>The sent and received NETCONF data is logged to a separate
+ text file with XML data nicely indented. A link to the file is
+ added to the test case HTML log.</p></item>
+
+ <tag><c>html (default)</c></tag>
+ <item><p>The sent and received NETCONF traffic is pretty printed
+ directly in the test case HTML log.</p></item>
+
+ <tag><c>silent</c></tag>
+ <item><p>NETCONF traffic is not logged.</p></item>
+ </taglist>
+
+ <p>By default, all NETCONF traffic is logged in one single log file.
+ However, different connections can be logged in separate files.
+ To do this, use hook option <c>hosts</c> and list the names of the
+ servers/connections to be used in the suite. The connections
+ must be named for this to work, that is, they must be opened with
+ <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>.</p>
+
+ <p>Option <c>hosts</c> has no effect if <c>log_type</c> is set to
+ <c>html</c> or <c>silent</c>.</p>
+
+ <p>The hook options can also be specified in a configuration file with
+ configuration variable <c>ct_conn_log</c>:</p>
+
+ <pre>
+ {ct_conn_log,[{conn_mod(),hook_options()}]}.</pre>
+
+ <p>For example:</p>
+
+ <pre>
+ {ct_conn_log,[{ct_netconfc,[{log_type,pretty},
+ {hosts,[key_or_name()]}]}]}</pre>
+
+ <note>
+ <p>Hook options specified in a configuration file overwrite the
+ hard-coded hook options in the test suite.</p>
+ </note>
+
+ <p><em>Logging Example 1:</em></p>
+ <marker id="Logging_example_1"/>
+
+ <p>The following <c>ct_hooks</c> statement causes pretty printing of
+ NETCONF traffic to separate logs for the connections named
+ <c>nc_server1</c> and <c>nc_server2</c>. Any other connections are
+ logged to default NETCONF log.</p>
+
+ <pre>
+ suite() -&gt;
+ [{ct_hooks, [{cth_conn_log, [{ct_netconfc,[{log_type,pretty}},
+ {hosts,[nc_server1,nc_server2]}]}
+ ]}]}].</pre>
+
+ <p>Connections must be opened as follows:</p>
+
+ <pre>
+ open(nc_server1,[...]),
+ open(nc_server2,[...]).</pre>
+
+ <p><em>Logging Example 2:</em></p>
+ <marker id="Logging_example_2"/>
+
+ <p>The following configuration file causes raw logging of all NETCONF
+ traffic in to one single text file:</p>
+
+ <pre>
+ {ct_conn_log,[{ct_netconfc,[{log_type,raw}]}]}.</pre>
+
+ <p>The <c>ct_hooks</c> statement must look as follows:</p>
+
+ <pre>
+ suite() -&gt;
+ [{ct_hooks, [{cth_conn_log, []}]}].</pre>
+
+ <p>The same <c>ct_hooks</c> statement without the configuration file
+ would cause HTML logging of all NETCONF connections in to the test
+ case HTML log.</p>
+ </section>
+
+ <section>
+ <marker id="Notifications"/>
+ <title>Notifications</title>
+
+ <p>The NETCONF client is also compliant with RFC 5277 NETCONF Event
+ Notifications, which defines a mechanism for an asynchronous message
+ notification delivery service for the NETCONF protocol.</p>
+
+ <p>Specific functions to support this are
+ <seealso marker="#create_subscription-6"><c>ct_netconfc:create_subscription/6</c></seealso>
+ and
+ <seealso marker="#get_event_streams-3"><c>ct_netconfc:get_event_streams/3</c></seealso>.
+ (The functions also exist with other arities.)</p>
+ </section>
+
+ <section>
+ <title>Data Types</title>
+ <marker id="types"/>
+ <taglist>
+ <tag><c>client() = handle() | key_or_name()</c></tag>
+ <item><marker id="type-client"/>
+ <p>For <c>handle()</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>error_reason() = term()</c></tag>
+ <item><marker id="type-error_reason"/> </item>
+ <tag><c>event_time() = {eventTime, xml_attributes(), [xs_datetime()]}</c></tag>
+ <item><marker id="type-event_time"/> </item>
+
+ <tag><c>handle() = term()</c></tag>
+ <item><marker id="type-handle"/>
+ <p>Opaque reference for a connection (NETCONF session). For more
+ information, see module <seealso marker="ct"><c>ct</c></seealso>.</p>
+ </item>
+
+ <tag><c>host() = <seealso marker="kernel:inet#type-hostname"><c>inet:hostname()</c></seealso> | <seealso marker="kernel:inet#type-ip_address"><c>inet:ip_address()</c></seealso></c></tag>
+ <item><marker id="type-host"/></item>
+
+ <tag><c>key_or_name() = server_id() | target_name()</c></tag>
+ <item><marker id="type-key_or_name"/>
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>netconf_db() = running | startup | candidate</c></tag>
+ <item><marker id="type-netconf_db"/> </item>
+
+ <tag><c>notification() = {notification, xml_attributes(), notification_content()}</c></tag>
+ <item><marker id="type-notification"/> </item>
+
+ <tag><c>notification_content() = [event_time() | simple_xml()]</c></tag>
+ <item><marker id="type-notification_content"/> </item>
+
+ <tag><c>option() = {ssh, host()} | {port, <seealso marker="kernel:inet#type-port_number"><c>inet:port_number()</c></seealso>} | {timeout, timeout()} | SshConnectOption</c></tag>
+ <item><marker id="type-option"/>
+
+ <p><c>SshConnectOption</c> is any valid option to
+ <seealso marker="ssh:ssh#connect-3"><c>ssh:connect/3,4</c></seealso>.
+ Common options used are <c>user</c>, <c>password</c>
+ and <c>user_dir</c>. The <c>SshConnectOptions</c> are
+ verfied by the SSH application.</p></item>
+
+ <tag><c>options() = [option()]</c></tag>
+ <item><marker id="type-options"/>
+ <p>Options used for setting up an SSH connection to a NETCONF
+ server.</p></item>
+
+ <tag><c>server_id() = atom()</c></tag>
+ <item><marker id="type-server_id"/>
+ <p>The identity of a server, specified in a configuration
+ file.</p></item>
+
+ <tag><c>simple_xml() = {xml_tag(), xml_attributes(), xml_content()} | {xml_tag(), xml_content()} | xml_tag()</c></tag>
+ <item><marker id="type-simple_xml"/>
+ <p>This type is further described in application
+ <seealso marker="xmerl:index"><c>xmerl</c></seealso>.</p></item>
+
+ <tag><c>stream_data() = {description, string()} | {replaySupport, string()} | {replayLogCreationTime, string()} | {replayLogAgedTime, string()}</c></tag>
+ <item><marker id="type-stream_data"/>
+ <p>For details about the data format for the string values, see
+ "XML Schema for Event Notifications" in RFC 5277.</p></item>
+
+ <tag><c>stream_name() = string()</c></tag>
+ <item><marker id="type-stream_name"/> </item>
+
+ <tag><c>streams() = [{stream_name(), [stream_data()]}]</c></tag>
+ <item><marker id="type-streams"/> </item>
+
+ <tag><c>xml_attribute_tag() = atom()</c></tag>
+ <item><marker id="type-xml_attribute_tag"/> </item>
+
+ <tag><c>xml_attribute_value() = string()</c></tag>
+ <item><marker id="type-xml_attribute_value"/> </item>
+
+ <tag><c>xml_attributes() = [{xml_attribute_tag(), xml_attribute_value()}]</c></tag>
+ <item><marker id="type-xml_attributes"/> </item>
+
+ <tag><c>xml_content() = [simple_xml() | iolist()]</c></tag>
+ <item><marker id="type-xml_content"/> </item>
+
+ <tag><c>xml_tag() = atom()</c></tag>
+ <item><marker id="type-xml_tag"/> </item>
+
+ <tag><c>xpath() = {xpath, string()}</c></tag>
+ <item><marker id="type-xpath"/> </item>
+
+ <tag><c>xs_datetime() = string()</c></tag>
+ <item><marker id="type-xs_datetime"/>
+ <p>This date and time identifier has the same format as the XML type
+ <c>dateTime</c> and is compliant with RFC 3339 Date and Time on
+ the Internet Timestamps. The format is as follows:</p>
+ <pre>
+ [-]CCYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]</pre>
+ </item>
+ </taglist>
+ </section>
+
+ <funcs>
+ <func>
+ <name>action(Client, Action) -&gt; Result</name>
+ <fsummary>Equivalent to action(Client, Action, infinity).</fsummary>
+ <desc><marker id="action-2"/>
+ <p>Equivalent to
+ <seealso marker="#action-3"><c>ct_netconfc:action(Client, Action,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>action(Client, Action, Timeout) -&gt; Result</name>
+ <fsummary>Executes an action.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Action = simple_xml()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {ok, [simple_xml()]} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="action-3"/>
+ <p>Executes an action. If the return type is void, <c>ok</c> is
+ returned instead of <c>{ok,[simple_xml()]}</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>close_session(Client) -&gt; Result</name>
+ <fsummary>Equivalent to close_session(Client, infinity).</fsummary>
+ <desc><marker id="close_session-1"/>
+ <p>Equivalent to
+ <seealso marker="#close_session-2"><c>ct_netconfc:close_session(Client,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>close_session(Client, Timeout) -&gt; Result</name>
+ <fsummary>Requests graceful termination of the session associated with
+ the client.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="close_session-2"/>
+ <p>Requests graceful termination of the session associated with the
+ client.</p>
+
+ <p>When a NETCONF server receives a <c>close-session</c> request, it
+ gracefully closes the session. The server releases any locks and
+ resources associated with the session and gracefully closes any
+ associated connections. Any NETCONF requests received after a
+ <c>close-session</c> request are ignored.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>copy_config(Client, Source, Target) -&gt; Result</name>
+ <fsummary>Equivalent to copy_config(Client, Source, Target,
+ infinity).</fsummary>
+ <desc><marker id="copy_config-3"/>
+ <p>Equivalent to
+ <seealso marker="#copy_config-4"><c>ct_netconfc:copy_config(Client,
+ Source, Target, infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>copy_config(Client, Target, Source, Timeout) -&gt; Result</name>
+ <fsummary>Copies configuration data.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Target = netconf_db()</v>
+ <v>Source = netconf_db()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="copy_config-4"/>
+ <p>Copies configuration data.</p>
+
+ <p>Which source and target options that can be issued depends on the
+ capabilities supported by the server. That is, <c>:candidate</c>
+ and/or <c>:startup</c> are required.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>create_subscription(Client) -&gt; term()</name>
+ <fsummary>Creates a subscription for event notifications.</fsummary>
+ <desc><marker id="create_subscription-1"/></desc>
+ </func>
+
+ <func>
+ <name>create_subscription(Client, Timeout) -&gt; term()</name>
+ <fsummary>Creates a subscription for event notifications.</fsummary>
+ <desc><marker id="create_subscription-2"/></desc>
+ </func>
+
+ <func>
+ <name>create_subscription(Client, Stream, Timeout) -&gt; term()</name>
+ <fsummary>Creates a subscription for event notifications.</fsummary>
+ <desc><marker id="create_subscription-3"/></desc>
+ </func>
+
+ <func>
+ <name>create_subscription(Client, StartTime, StopTime, Timeout) -&gt; term()</name>
+ <fsummary>Creates a subscription for event notifications.</fsummary>
+ <desc><marker id="create_subscription-4"/></desc>
+ </func>
+
+ <func>
+ <name>create_subscription(Client, Stream, StartTime, StopTime, Timeout) -&gt; term()</name>
+ <fsummary>Creates a subscription for event notifications.</fsummary>
+ <desc><marker id="create_subscription-5"/></desc>
+ </func>
+
+ <func>
+ <name>create_subscription(Client, Stream, Filter, StartTime, StopTime, Timeout) -&gt; Result</name>
+ <fsummary>Creates a subscription for event notifications.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Stream = stream_name()</v>
+ <v>Filter = simple_xml() | [simple_xml()]</v>
+ <v>StartTime = xs_datetime()</v>
+ <v>StopTime = xs_datetime()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="create_subscription-6"/>
+ <p>Creates a subscription for event notifications.</p>
+
+ <p>This function sets up a subscription for NETCONF event
+ notifications of the specified stream type, matching the specified
+ filter. The calling process receives notifications as messages of
+ type <c>notification()</c>.</p>
+
+ <taglist>
+ <tag><c>Stream</c></tag>
+ <item><p>Optional parameter that indicates which stream of event
+ is of interest. If not present, events in the default NETCONF
+ stream are sent.</p></item>
+ <tag><c>Filter</c></tag>
+ <item><p>Optional parameter that indicates which subset of all
+ possible events is of interest. The parameter format is the
+ same as that of the filter parameter in the NETCONF protocol
+ operations. If not present, all events not precluded by other
+ parameters are sent.</p></item>
+ <tag><c>StartTime</c></tag>
+ <item><p>Optional parameter used to trigger the replay feature and
+ indicate that the replay is to start at the time specified.
+ If <c>StartTime</c> is not present, this is not a replay
+ subscription.</p>
+ <p>It is not valid to specify start times that are later than
+ the current time. If <c>StartTime</c> is specified earlier
+ than the log can support, the replay begins with the earliest
+ available notification.</p>
+ <p>This parameter is of type <c>dateTime</c> and compliant to
+ RFC 3339. Implementations must support time zones.</p></item>
+ <tag><c>StopTime</c></tag>
+ <item><p>Optional parameter used with the optional replay feature
+ to indicate the newest notifications of interest. If
+ <c>StopTime</c> is not present, the notifications continues
+ until the subscription is terminated.</p>
+ <p>Must be used with and be later than <c>StartTime</c>. Values
+ of <c>StopTime</c> in the future are valid. This parameter is
+ of type <c>dateTime</c> and compliant to RFC 3339.
+ Implementations must support time zones.</p></item>
+ </taglist>
+
+ <p>For more details about the event notification mechanism, see
+ RFC 5277.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>delete_config(Client, Target) -&gt; Result</name>
+ <fsummary>Equivalent to delete_config(Client, Target,
+ infinity).</fsummary>
+ <desc><marker id="delete_config-2"/>
+ <p>Equivalent to
+ <seealso marker="#delete_config-3"><c>ct_netconfc:delete_config(Client, Target, infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>delete_config(Client, Target, Timeout) -&gt; Result</name>
+ <fsummary>Deletes configuration data.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Target = startup | candidate</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="delete_config-3"/>
+ <p>Deletes configuration data.</p>
+
+ <p>The running configuration cannot be deleted and <c>:candidate</c>
+ or <c>:startup</c> must be advertised by the server.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>edit_config(Client, Target, Config) -&gt; Result</name>
+ <fsummary>Equivalent to edit_config(Client, Target, Config, [],
+ infinity).</fsummary>
+ <desc><marker id="edit_config-3"/>
+ <p>Equivalent to
+ <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client,
+ Target, Config, [], infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>edit_config(Client, Target, Config, OptParamsOrTimeout) -&gt; Result</name>
+ <fsummary>If OptParamsOrTimeout is a time-out value, this function is
+ equivalent to ct_netconfc:edit_config(Client, Target, Config, [],
+ Timeout).</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Target = netconf_db()</v>
+ <v>Config = simple_xml()</v>
+ <v>OptParamsOrTimeout = [simple_xml()] | timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="edit_config-4"/>
+ <p>If <c>OptParamsOrTimeout</c> is a time-out value, this function is
+ equivalent to
+ <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client,
+ Target, Config, [], Timeout)</c></seealso>.</p>
+
+ <p>If <c>OptParamsOrTimeout</c> is a list of simple XML, this
+ function is equivalent to
+ <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client,
+ Target, Config, OptParams, infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>edit_config(Client, Target, Config, OptParams, Timeout) -&gt; Result</name>
+ <fsummary>Edits configuration data.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Target = netconf_db()</v>
+ <v>Config = simple_xml()</v>
+ <v>OptParams = [simple_xml()]</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="edit_config-5"/>
+ <p>Edits configuration data.</p>
+
+ <p>By default only the running target is available, unless the server
+ includes <c>:candidate</c> or <c>:startup</c> in its list of
+ capabilities.</p>
+
+ <p><c>OptParams</c> can be used for specifying optional parameters
+ (<c>default-operation</c>, <c>test-option</c>, or
+ <c>error-option</c>) to be added to the <c>edit-config</c>
+ request. The value must be a list containing valid simple XML,
+ for example:</p>
+
+ <pre>
+ [{'default-operation', ["none"]},
+ {'error-option', ["rollback-on-error"]}]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name>get(Client, Filter) -&gt; Result</name>
+ <fsummary>Equivalent to get(Client, Filter, infinity).</fsummary>
+ <desc><marker id="get-2"/>
+ <p>Equivalent to
+ <seealso marker="#get-3"><c>ct_netconfc:get(Client, Filter,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get(Client, Filter, Timeout) -&gt; Result</name>
+ <fsummary>Gets data.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Filter = simple_xml() | xpath()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = {ok, [simple_xml()]} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="get-3"/>
+ <p>Gets data.</p>
+
+ <p>This operation returns both configuration and state data from the
+ server.</p>
+
+ <p>Filter type <c>xpath</c> can be used only if the server supports
+ <c>:xpath</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_capabilities(Client) -&gt; Result</name>
+ <fsummary>Equivalent to get_capabilities(Client, infinity).</fsummary>
+ <desc><marker id="get_capabilities-1"/>
+ <p>Equivalent to
+ <seealso marker="#get_capabilities-2"><c>ct_netconfc:get_capabilities(Client,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_capabilities(Client, Timeout) -&gt; Result</name>
+ <fsummary>Returns the server side capabilities.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = [string()] | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="get_capabilities-2"/>
+ <p>Returns the server side capabilities.</p>
+
+ <p>The following capability identifiers, defined in RFC 4741 NETCONF
+ Configuration Protocol, can be returned:</p>
+
+ <list>
+ <item><p><c>"urn:ietf:params:netconf:base:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:writable-running:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:candidate:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:confirmed-commit:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:rollback-on-error:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:startup:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:url:1.0"</c></p></item>
+ <item><p><c>"urn:ietf:params:netconf:capability:xpath:1.0"</c></p></item>
+ </list>
+
+ <p>More identifiers can exist, for example, server-side namespace.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_config(Client, Source, Filter) -&gt; Result</name>
+ <fsummary>Equivalent to get_config(Client, Source, Filter,
+ infinity).</fsummary>
+ <desc><marker id="get_config-3"/>
+ <p>Equivalent to
+ <seealso marker="#get_config-4"><c>ct_netconfc:get_config(Client, Source, Filter, infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_config(Client, Source, Filter, Timeout) -&gt; Result</name>
+ <fsummary>Gets configuration data.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Source = netconf_db()</v>
+ <v>Filter = simple_xml() | xpath()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = {ok, [simple_xml()]} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="get_config-4"/>
+ <p>Gets configuration data.</p>
+
+ <p>To be able to access another source than <c>running</c>, the
+ server must advertise <c>:candidate</c> and/or <c>:startup</c>.</p>
+
+ <p>Filter type <c>xpath</c> can be used only if the server supports
+ <c>:xpath</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_event_streams(Client, Timeout) -&gt; Result</name>
+ <fsummary>Equivalent to get_event_streams(Client, [], Timeout).</fsummary>
+ <desc><marker id="get_event_streams-2"/>
+ <p>Equivalent to
+ <seealso marker="#get_event_streams-3"><c>ct_netconfc:get_event_streams(Client,
+ [], Timeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_event_streams(Client, Streams, Timeout) -&gt; Result</name>
+ <fsummary>Sends a request to get the specified event streams.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Streams = [stream_name()]</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = {ok, streams()} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="get_event_streams-3"/>
+ <p>Sends a request to get the specified event streams.</p>
+
+ <p><c>Streams</c> is a list of stream names. The following filter is
+ sent to the NETCONF server in a <c>get</c> request:</p>
+
+ <pre>
+ &lt;netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"&gt;
+ &lt;streams&gt;
+ &lt;stream&gt;
+ &lt;name&gt;StreamName1&lt;/name&gt;
+ &lt;/stream&gt;
+ &lt;stream&gt;
+ &lt;name&gt;StreamName2&lt;/name&gt;
+ &lt;/stream&gt;
+ ...
+ &lt;/streams&gt;
+ &lt;/netconf&gt;</pre>
+
+ <p>If <c>Streams</c> is an empty list, <em>all</em> streams are
+ requested by sending the following filter:</p>
+
+ <pre>
+ &lt;netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"&gt;
+ &lt;streams/&gt;
+ &lt;/netconf&gt;</pre>
+
+ <p>If more complex filtering is needed, use
+ <seealso marker="#get-2"><c>ct_netconfc:get/2</c></seealso> or
+ <seealso marker="#get-3"><c>ct_netconfc:get/3</c></seealso> and
+ specify the exact filter according to "XML Schema for Event
+ Notifications" in RFC 5277.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_session_id(Client) -&gt; Result</name>
+ <fsummary>Equivalent to get_session_id(Client, infinity).</fsummary>
+ <desc><marker id="get_session_id-1"/>
+ <p>Equivalent to
+ <seealso marker="#get_session_id-2"><c>ct_netconfc:get_session_id(Client,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_session_id(Client, Timeout) -&gt; Result</name>
+ <fsummary>Returns the session Id associated with the specified
+ client.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = pos_integer() | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="get_session_id-2"/>
+ <p>Returns the session Id associated with the specified client.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>hello(Client) -&gt; Result</name>
+ <fsummary>Equivalent to hello(Client, [], infinity).</fsummary>
+ <desc><marker id="hello-1"/>
+ <p>Equivalent to
+ <seealso marker="#hello-3"><c>ct_netconfc:hello(Client, [],
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>hello(Client, Timeout) -&gt; Result</name>
+ <fsummary>Equivalent to hello(Client, [], Timeout).</fsummary>
+ <desc><marker id="hello-2"/>
+ <p>Equivalent to
+ <seealso marker="#hello-3"><c>ct_netconfc:hello(Client, [],
+ Timeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>hello(Client, Options, Timeout) -&gt; Result</name>
+ <fsummary>Exchanges hello messages with the server.</fsummary>
+ <type>
+ <v>Client = handle()</v>
+ <v>Options = [{capability, [string()]}]</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="hello-3"/>
+ <p>Exchanges <c>hello</c> messages with the server.</p>
+
+ <p>Adds optional capabilities and sends a <c>hello</c> message to the
+ server and waits for the return.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>kill_session(Client, SessionId) -&gt; Result</name>
+ <fsummary>Equivalent to kill_session(Client, SessionId,
+ infinity).</fsummary>
+ <desc><marker id="kill_session-2"/>
+ <p>Equivalent to
+ <seealso marker="#kill_session-3"><c>ct_netconfc:kill_session(Client,
+SessionId, infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>kill_session(Client, SessionId, Timeout) -&gt; Result</name>
+ <fsummary>Forces termination of the session associated with the supplied
+ session Id.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>SessionId = pos_integer()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="kill_session-3"/>
+ <p>Forces termination of the session associated with the supplied
+ session Id.</p>
+
+ <p>The server side must abort any ongoing operations, release any
+ locks and resources associated with the session, and close any
+ associated connections.</p>
+
+ <p>Only if the server is in the confirmed commit phase, the
+ configuration is restored to its state before entering the confirmed
+ commit phase. Otherwise, no configuration rollback is performed.</p>
+
+ <p>If the specified <c>SessionId</c> is equal to the current session
+ Id, an error is returned.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>lock(Client, Target) -&gt; Result</name>
+ <fsummary>Equivalent to lock(Client, Target, infinity).</fsummary>
+ <desc><marker id="lock-2"/>
+ <p>Equivalent to
+ <seealso marker="#lock-3"><c>ct_netconfc:lock(Client, Target,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>lock(Client, Target, Timeout) -&gt; Result</name>
+ <fsummary>Unlocks the configuration target.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Target = netconf_db()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="lock-3"/>
+ <p>Unlocks the configuration target.</p>
+
+ <p>Which target parameters that can be used depends on if
+ <c>:candidate</c> and/or <c>:startup</c> are supported by the
+ server. If successfull, the configuration system of the device is
+ unavailable to other clients (NETCONF, CORBA, SNMP, and so on).
+ Locks are intended to be short-lived.</p>
+
+ <p>Operation
+ <seealso marker="#kill_session-2"><c>ct_netconfc:kill_session/2</c></seealso>
+ or
+ <seealso marker="#kill_session-3"><c>ct_netconfc:kill_session/3</c></seealso>
+ can be used to force the release of a lock owned by another NETCONF
+ session. How this is achieved by the server side is
+ implementation-specific.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>only_open(Options) -&gt; Result</name>
+ <fsummary>Opens a NETCONF session, but does not send hello.</fsummary>
+ <type>
+ <v>Options = options()</v>
+ <v>Result = {ok, handle()} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="only_open-1"/>
+ <p>Opens a NETCONF session, but does not send <c>hello</c>.</p>
+
+ <p>As <seealso marker="#open-1"><c>ct_netconfc:open/1</c></seealso>,
+ but does not send a <c>hello</c> message.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>only_open(KeyOrName, ExtraOptions) -&gt; Result</name>
+ <fsummary>Opens a name NETCONF session, but does not send
+ hello.</fsummary>
+ <type>
+ <v>KeyOrName = key_or_name()</v>
+ <v>ExtraOptions = options()</v>
+ <v>Result = {ok, handle()} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="only_open-2"/>
+ <p>Opens a name NETCONF session, but does not send <c>hello</c>.</p>
+
+ <p>As <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>,
+ but does not send a <c>hello</c> message.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(Options) -&gt; Result</name>
+ <fsummary>Opens a NETCONF session and exchanges hello messages.</fsummary>
+ <type>
+ <v>Options = options()</v>
+ <v>Result = {ok, handle()} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="open-1"/>
+ <p>Opens a NETCONF session and exchanges <c>hello</c> messages.</p>
+
+ <p>If the server options are specified in a configuration file,
+ or if a named client is needed for logging purposes (see section
+ <seealso marker="#Logging">Logging</seealso> in this module), use
+ <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>
+ instead.</p>
+
+ <p>The opaque <c>handle()</c> reference returned from this
+ function is required as client identifier when calling any other
+ function in this module.</p>
+
+ <p>Option <c>timeout</c> (milliseconds) is used when setting up the
+ SSH connection and when waiting for the <c>hello</c> message from
+ the server. It is not used for any other purposes during the
+ lifetime of the connection.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(KeyOrName, ExtraOptions) -&gt; Result</name>
+ <fsummary>Opens a named NETCONF session and exchanges hello
+ messages.</fsummary>
+ <type>
+ <v>KeyOrName = key_or_name()</v>
+ <v>ExtraOptions = options()</v>
+ <v>Result = {ok, handle()} | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="open-2"/>
+ <p>Opens a named NETCONF session and exchanges <c>hello</c>
+ messages.</p>
+
+ <p>If <c>KeyOrName</c> is a configured <c>server_id()</c> or a
+ <c>target_name()</c> associated with such an Id, then the options
+ for this server are fetched from the configuration file.</p>
+
+ <p>Argument <c>ExtraOptions</c> is added to the options found in the
+ configuration file. If the same options are specified, the values
+ from the configuration file overwrite <c>ExtraOptions</c>.</p>
+
+ <p>If the server is not specified in a configuration file, use
+ <seealso marker="#open-1"><c>ct_netconfc:open/1</c></seealso>
+ instead.</p>
+
+ <p>The opaque <c>handle()</c> reference returned from this
+ function can be used as client identifier when calling any other
+ function in this module. However, if <c>KeyOrName</c> is a
+ <c>target_name()</c>, that is, if the server is named through a
+ call to <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>
+ or a <c>require</c> statement in the test suite, then this name can
+ be used instead of <c>handle()</c>.</p>
+
+ <p>Option <c>timeout</c> (milliseconds) is used when setting up the
+ SSH connection and when waiting for the <c>hello</c> message from
+ the server. It is not used for any other purposes during the
+ lifetime of the connection.</p>
+
+ <p>See also
+ <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(Client, SimpleXml) -&gt; Result</name>
+ <fsummary>Equivalent to send(Client, SimpleXml, infinity).</fsummary>
+ <desc><marker id="send-2"/>
+ <p>Equivalent to
+ <seealso marker="#send-3"><c>ct_netconfc:send(Client, SimpleXml,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(Client, SimpleXml, Timeout) -&gt; Result</name>
+ <fsummary>Sends an XML document to the server.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>SimpleXml = simple_xml()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = simple_xml() | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="send-3"/>
+ <p>Sends an XML document to the server.</p>
+
+ <p>The specified XML document is sent "as is" to the server. This
+ function can be used for sending XML documents that cannot be
+ expressed by other interface functions in this module.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send_rpc(Client, SimpleXml) -&gt; Result</name>
+ <fsummary>Equivalent to send_rpc(Client, SimpleXml, infinity).</fsummary>
+ <desc><marker id="send_rpc-2"/>
+ <p>Equivalent to
+ <seealso marker="#send_rpc-3"><c>ct_netconfc:send_rpc(Client,
+ SimpleXml, infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send_rpc(Client, SimpleXml, Timeout) -&gt; Result</name>
+ <fsummary>Sends a NETCONF rpc request to the server.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>SimpleXml = simple_xml()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = [simple_xml()] | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="send_rpc-3"/>
+ <p>Sends a NETCONF <c>rpc</c> request to the server.</p>
+
+ <p>The specified XML document is wrapped in a valid NETCONF <c>rpc</c>
+ request and sent to the server. The <c>message-id</c> and namespace
+ attributes are added to element <c>rpc</c>.</p>
+
+ <p>This function can be used for sending <c>rpc</c> requests that
+ cannot be expressed by other interface functions in this module.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unlock(Client, Target) -&gt; Result</name>
+ <fsummary>Equivalent to unlock(Client, Target, infinity).</fsummary>
+ <desc><marker id="unlock-2"/>
+ <p>Equivalent to
+ <seealso marker="#unlock-3"><c>ct_netconfc:unlock(Client, Target,
+ infinity)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unlock(Client, Target, Timeout) -&gt; Result</name>
+ <fsummary>Unlocks the configuration target.</fsummary>
+ <type>
+ <v>Client = client()</v>
+ <v>Target = netconf_db()</v>
+ <v>Timeout = timeout()</v>
+ <v>Result = ok | {error, error_reason()}</v>
+ </type>
+ <desc><marker id="unlock-3"/>
+ <p>Unlocks the configuration target.</p>
+
+ <p>If the client earlier has acquired a lock through
+ <seealso marker="#lock-2"><c>ct_netconfc:lock/2</c></seealso> or
+ <seealso marker="#lock-3"><c>ct_netconfc:lock/3</c></seealso>, this
+ operation releases the associated lock. To access another target
+ than <c>running</c>, the server must support <c>:candidate</c>
+ and/or <c>:startup</c>.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_property_test.xml b/lib/common_test/doc/src/ct_property_test.xml
new file mode 100644
index 0000000000..2e9bd1969c
--- /dev/null
+++ b/lib/common_test/doc/src/ct_property_test.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_property_test</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_property_test.xml</file>
+ </header>
+ <module>ct_property_test</module>
+ <modulesummary>EXPERIMENTAL support in Common Test for calling
+ property-based tests.</modulesummary>
+
+ <description>
+
+ <p>EXPERIMENTAL support in <c>Common Test</c> for calling property-based
+ tests.</p>
+
+ <p>This module is a first step to run property-based tests in the
+ <c>Common Test</c> framework. A property testing tool like QuickCheck
+ or PropEr is assumed to be installed.</p>
+
+ <p>The idea is to have a <c>Common Test</c> test suite calling a property
+ testing tool with special property test suites as defined by that tool.
+ The usual Erlang application directory structure is assumed. The tests
+ are collected in the <c>test</c> directory of the application. The
+ <c>test</c> directory has a subdirectory <c>property_test</c>, where
+ everything needed for the property tests is collected.</p>
+
+ <p>A typical <c>Common Test</c> test suite using <c>ct_property_test</c>
+ is organized as follows:</p>
+
+ <pre>
+ -include_lib("common_test/include/ct.hrl").
+
+ all() -&gt; [prop_ftp_case].
+
+ init_per_suite(Config) -&gt;
+ ct_property_test:init_per_suite(Config).
+
+ %%%---- test case
+ prop_ftp_case(Config) -&gt;
+ ct_property_test:quickcheck(
+ ftp_simple_client_server:prop_ftp(Config),
+ Config
+ ).</pre>
+
+ <warning>
+ <p>This is experimental code that can be changed or removed anytime
+ without any warning.</p>
+ </warning>
+
+ </description>
+
+ <funcs>
+ <func>
+ <name>init_per_suite(Config) -&gt; Config | {skip, Reason}</name>
+ <fsummary>Initializes Config for property testing.</fsummary>
+ <desc><marker id="init_per_suite-1"/>
+ <p>Initializes <c>Config</c> for property testing.</p>
+
+ <p>This function investigates if support is available for either
+ Quickcheck, PropEr, or Triq. The options
+ <c>{property_dir,AbsPath}</c> and <c>{property_test_tool,Tool}</c>
+ are set in the <c>Config</c> returned.</p>
+
+ <p>The function is intended to be called in function
+ <c>init_per_suite</c> in the test suite.</p>
+
+ <p>The property tests are assumed to be in subdirectory
+ <c>property_test</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>quickcheck(Property, Config) -&gt; true | {fail, Reason}</name>
+ <fsummary>Calls quickcheck and returns the result in a form suitable for
+ Common Test.</fsummary>
+ <desc><marker id="quickcheck-2"/>
+ <p>Calls quickcheck and returns the result in a form suitable for
+ <c>Common Test</c>.</p>
+
+ <p>This function is intended to be called in the test cases in the
+ test suite.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_rpc.xml b/lib/common_test/doc/src/ct_rpc.xml
new file mode 100644
index 0000000000..0169727581
--- /dev/null
+++ b/lib/common_test/doc/src/ct_rpc.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_rpc</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_rpc.xml</file>
+ </header>
+ <module>ct_rpc</module>
+ <modulesummary>Common Test specific layer on Erlang/OTP rpc.</modulesummary>
+
+ <description>
+
+ <p><c>Common Test</c> specific layer on Erlang/OTP <c>rpc</c>.</p>
+
+ </description>
+
+ <funcs>
+ <func>
+ <name>app_node(App, Candidates) -&gt; NodeName</name>
+ <fsummary>From a set of candidate nodes determines which of them is
+ running the application App.</fsummary>
+ <type>
+ <v>App = atom()</v>
+ <v>Candidates = [NodeName]</v>
+ <v>NodeName = atom()</v>
+ </type>
+ <desc><marker id="app_node-2"/>
+ <p>From a set of candidate nodes determines which of them is running
+ the application <c>App</c>. If none of the candidate nodes is
+ running <c>App</c>, the function makes the test case calling
+ this function to fail. This function is the same as calling
+ <c>app_node(App, Candidates, true)</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>app_node(App, Candidates, FailOnBadRPC) -&gt; NodeName</name>
+ <fsummary>Same as app_node/2, except that argument FailOnBadRPC
+ determines if the search for a candidate node is to stop if
+ badrpc is received at some point.</fsummary>
+ <type>
+ <v>App = atom()</v>
+ <v>Candidates = [NodeName]</v>
+ <v>NodeName = atom()</v>
+ <v>FailOnBadRPC = true | false</v>
+ </type>
+ <desc><marker id="app_node-3"/>
+ <p>Same as
+ <seealso marker="#app_node-2"><c>ct_rpc:app_node/2</c></seealso>,
+ except that argument <c>FailOnBadRPC</c> determines if the search
+ for a candidate node is to stop if <c>badrpc</c> is received at
+ some point.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>app_node(App, Candidates, FailOnBadRPC, Cookie) -&gt; NodeName</name>
+ <fsummary>Same as app_node/2, except that argument FailOnBadRPC
+ determines if the search for a candidate node is to stop if badrpc is
+ received at some point.</fsummary>
+ <type>
+ <v>App = atom()</v>
+ <v>Candidates = [NodeName]</v>
+ <v>NodeName = atom()</v>
+ <v>FailOnBadRPC = true | false</v>
+ <v>Cookie = atom()</v>
+ </type>
+ <desc><marker id="app_node-4"/>
+ <p>Same as
+ <seealso marker="#app_node-2"><c>ct_rpc:app_node/2</c></seealso>,
+ except that argument <c>FailOnBadRPC</c> determines if the search
+ for a candidate node is to stop if <c>badrpc</c> is received at
+ some point.</p>
+
+ <p>The cookie on the client node is set to <c>Cookie</c> for this
+ <c>rpc</c> operation (used to match the server node cookie).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>call(Node, Module, Function, Args) -&gt; term() | {badrpc, Reason}</name>
+ <fsummary>Same as call(Node, Module, Function, Args, infinity).</fsummary>
+ <desc><marker id="call-4"/>
+ <p>Same as <c>call(Node, Module, Function, Args, infinity)</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>call(Node, Module, Function, Args, TimeOut) -&gt; term() | {badrpc, Reason}</name>
+ <fsummary>Evaluates apply(Module, Function, Args) on the node
+ Node.</fsummary>
+ <type>
+ <v>Node = NodeName | {Fun, FunArgs}</v>
+ <v>Fun = function()</v>
+ <v>FunArgs = term()</v>
+ <v>NodeName = atom()</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Reason = timeout | term()</v>
+ </type>
+ <desc><marker id="call-5"/>
+ <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
+ <c>Node</c>. Returns either whatever <c>Function</c> returns, or
+ <c>{badrpc, Reason}</c> if the remote procedure call fails. If
+ <c>Node</c> is <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to
+ <c>FunArgs</c> is to return a node name.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>call(Node, Module, Function, Args, TimeOut, Cookie) -&gt; term() | {badrpc, Reason}</name>
+ <fsummary>Evaluates apply(Module, Function, Args) on the node
+ Node.</fsummary>
+ <type>
+ <v>Node = NodeName | {Fun, FunArgs}</v>
+ <v>Fun = function()</v>
+ <v>FunArgs = term()</v>
+ <v>NodeName = atom()</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Reason = timeout | term()</v>
+ <v>Cookie = atom()</v>
+ </type>
+ <desc><marker id="call-6"/>
+ <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
+ <c>Node</c>. Returns either whatever <c>Function</c> returns, or
+ <c>{badrpc, Reason}</c> if the remote procedure call fails. If
+ <c>Node</c> is <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to
+ <c>FunArgs</c> is to return a node name.</p>
+
+ <p>The cookie on the client node is set to <c>Cookie</c> for this
+ <c>rpc</c> operation (used to match the server node cookie).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cast(Node, Module, Function, Args) -&gt; ok</name>
+ <fsummary>Evaluates apply(Module, Function, Args) on the node
+ Node.</fsummary>
+ <type>
+ <v>Node = NodeName | {Fun, FunArgs}</v>
+ <v>Fun = function()</v>
+ <v>FunArgs = term()</v>
+ <v>NodeName = atom()</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Reason = timeout | term()</v>
+ </type>
+ <desc><marker id="cast-4"/>
+ <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
+ <c>Node</c>. No response is delivered and the process that makes
+ the call is not suspended until the evaluation is completed as in
+ the case of <c>call/3,4</c>. If <c>Node</c> is
+ <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to <c>FunArgs</c> is to
+ return a node name.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cast(Node, Module, Function, Args, Cookie) -&gt; ok</name>
+ <fsummary>Evaluates apply(Module, Function, Args) on the node
+ Node.</fsummary>
+ <type>
+ <v>Node = NodeName | {Fun, FunArgs}</v>
+ <v>Fun = function()</v>
+ <v>FunArgs = term()</v>
+ <v>NodeName = atom()</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Reason = timeout | term()</v>
+ <v>Cookie = atom()</v>
+ </type>
+ <desc><marker id="cast-5"/>
+ <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
+ <c>Node</c>. No response is delivered and the process that makes
+ the call is not suspended until the evaluation is completed as in
+ the case of <c>call/3,4</c>. If <c>Node</c> is
+ <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to <c>FunArgs</c> is to
+ return a node name.</p>
+
+ <p>The cookie on the client node is set to <c>Cookie</c> for this
+ <c>rpc</c> operation (used to match the server node cookie).</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_run.xml b/lib/common_test/doc/src/ct_run.xml
index d8e79ca80e..2552938346 100644
--- a/lib/common_test/doc/src/ct_run.xml
+++ b/lib/common_test/doc/src/ct_run.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -33,177 +34,192 @@
</header>
<com>ct_run</com>
<comsummary>Program used for starting Common Test from the
- OS command line.
- </comsummary>
+ OS command line.</comsummary>
<description>
<p>The <c>ct_run</c> program is automatically installed with Erlang/OTP
- and Common Test (please see the Installation chapter in the Common
- Test User's Guide for more information). The program accepts a number
- of different start flags. Some flags trigger <c>ct_run</c>
- to start the Common Test application and pass on data to it. Some
- flags start an Erlang node prepared for running Common Test in a
- particular mode.</p>
-
- <p>There is an interface function that corresponds to this program,
- called <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, for starting Common Test from the Erlang
- shell (or an Erlang program). Please see the <c>ct</c> man page for
- details.</p>
+ and the <c>Common Test</c> application (for more information, see
+ section <seealso marker="install_chapter">Installation</seealso>
+ in the User's Guide). The program accepts different start flags.
+ Some flags trigger <c>ct_run</c> to start <c>Common Test</c> and
+ pass on data to it. Some flags start an Erlang node prepared for
+ running <c>Common Test</c> in a particular mode.</p>
+
+ <p>The interface function
+ <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>,
+ corresponding to the <c>ct_run</c> program, is used for starting
+ <c>Common Test</c> from the Erlang shell (or an Erlang program).
+ For details, see the <seealso marker="ct"><c>ct</c></seealso>
+ manual page.</p>
<p><c>ct_run</c> also accepts Erlang emulator flags. These are used
- when <c>ct_run</c> calls <c>erl</c> to start the Erlang node
- (making it possible to e.g. add directories to the code server path,
- change the cookie on the node, start additional applications, etc).</p>
-
- <p>With the optional flag:</p>
- <pre>-erl_args</pre>
- <p>it's possible to divide the options on the <c>ct_run</c> command line into
- two groups, one that Common Test should process (those preceding <c>-erl_args</c>),
- and one it should completely ignore and pass on directly to the emulator
- (those following <c>-erl_args</c>). Options preceding <c>-erl_args</c> that Common Test
- doesn't recognize, also get passed on to the emulator untouched.
- By means of <c>-erl_args</c> the user may specify flags with the same name, but
+ when <c>ct_run</c> calls <c>erl</c> to start the Erlang node (this
+ makes it possible to add directories to the code server path,
+ change the cookie on the node, start more applications, and so on).</p>
+
+ <p>With the optional flag <c>-erl_args</c>, options on the <c>ct_run</c>
+ command line can be divided into two groups:</p>
+
+ <list type="bulleted">
+ <item>One group that <c>Common Test</c> is to process (those
+ preceding <c>-erl_args</c>).</item>
+ <item>One group that <c>Common Test</c> is to ignore and pass on
+ directly to the emulator (those following <c>-erl_args</c>).</item>
+ </list>
+
+ <p>Options preceding <c>-erl_args</c> that <c>Common Test</c>
+ does not recognize are also passed on to the emulator untouched.
+ By <c>-erl_args</c> the user can specify flags with the same name, but
with different destinations, on the <c>ct_run</c> command line.</p>
- <p>If <c>-pa</c> or <c>-pz</c> flags are specified in the Common Test group of options
- (preceding <c>-erl_args</c>), relative directories will be converted to
- absolute and re-inserted into the code path by Common Test (to avoid
- problems loading user modules when Common Test changes working directory
- during test runs). Common Test will however ignore <c>-pa</c> and <c>-pz</c> flags
- following <c>-erl_args</c> on the command line. These directories are added
- to the code path normally (i.e. on specified form)</p>
-
- <p>Exit status is set before the program ends. Value <c>0</c> indicates a successful
- test result, <c>1</c> indicates one or more failed or auto-skipped test cases, and
- <c>2</c> indicates test execution failure.</p>
-
- <p>If <c>ct_run</c> is called with option:</p>
- <pre>-help</pre>
- <p>it prints all valid start flags to stdout.</p>
- </description>
+ <p>If flags <c>-pa</c> or <c>-pz</c> are specified in the
+ <c>Common Test</c> group of options (preceding <c>-erl_args</c>),
+ relative directories are converted to absolute and reinserted into
+ the code path by <c>Common Test</c>. This is to avoid problems
+ loading user modules when <c>Common Test</c> changes working directory
+ during test runs. However, <c>Common Test</c> ignores flags <c>-pa</c>
+ and <c>-pz</c> following <c>-erl_args</c> on the command line. These
+ directories are added to the code path normally (that is, on specified
+ form).</p>
+
+ <p>Exit status is set before the program ends. Value <c>0</c> indicates
+ a successful test result, <c>1</c> indicates one or more failed or
+ auto-skipped test cases, and <c>2</c> indicates test execution failure.</p>
+
+ <p>If <c>ct_run</c> is called with option <c>-help</c>, it prints all
+ valid start flags to <c>stdout</c>.</p>
+ </description>
<section>
<marker id="ct_run"></marker>
- <title>Run tests from command line</title>
+ <title>Run Tests from Command Line</title>
<pre>
- ct_run [-dir TestDir1 TestDir2 .. TestDirN] |
- [[-dir TestDir] -suite Suite1 Suite2 .. SuiteN
- [[-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]]]
- [-step [config | keep_inactive]]
- [-config ConfigFile1 ConfigFile2 .. ConfigFileN]
- [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
- ConfigString2 and .. CallbackModuleN ConfigStringN]
- [-decrypt_key Key] | [-decrypt_file KeyFile]
- [-label Label]
- [-logdir LogDir]
- [-logopts LogOpts]
- [-verbosity GenVLevel | [Category1 VLevel1 and
- Category2 VLevel2 and .. CategoryN VLevelN]]
- [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]
- [-stylesheet CSSFile]
- [-cover CoverCfgFile]
- [-cover_stop Bool]
- [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |
- [-event_handler_init EvHandler1 InitArg1 and
- EvHandler2 InitArg2 and .. EvHandlerN InitArgN]
- [-include InclDir1 InclDir2 .. InclDirN]
- [-no_auto_compile]
- [-abort_if_missing_suites]
- [-muliply_timetraps Multiplier]
- [-scale_timetraps]
- [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
- [-repeat N] |
- [-duration HHMMSS [-force_stop [skip_rest]]] |
- [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]
- [-basic_html]
- [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..
- CTHModuleN CTHOptsN]
- [-exit_status ignore_config]
- </pre>
+ ct_run -dir TestDir1 TestDir2 .. TestDirN |
+ [-dir TestDir] -suite Suite1 Suite2 .. SuiteN
+ [-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]
+ [-step [config | keep_inactive]]
+ [-config ConfigFile1 ConfigFile2 .. ConfigFileN]
+ [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
+ ConfigString2 and .. CallbackModuleN ConfigStringN]
+ [-decrypt_key Key] | [-decrypt_file KeyFile]
+ [-label Label]
+ [-logdir LogDir]
+ [-logopts LogOpts]
+ [-verbosity GenVLevel | [Category1 VLevel1 and
+ Category2 VLevel2 and .. CategoryN VLevelN]]
+ [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]
+ [-stylesheet CSSFile]
+ [-cover CoverCfgFile]
+ [-cover_stop Bool]
+ [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |
+ [-event_handler_init EvHandler1 InitArg1 and
+ EvHandler2 InitArg2 and .. EvHandlerN InitArgN]
+ [-include InclDir1 InclDir2 .. InclDirN]
+ [-no_auto_compile]
+ [-abort_if_missing_suites]
+ [-muliply_timetraps Multiplier]
+ [-scale_timetraps]
+ [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
+ [-repeat N] |
+ [-duration HHMMSS [-force_stop [skip_rest]]] |
+ [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]
+ [-basic_html]
+ [-no_esc_chars]
+ [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..
+ CTHModuleN CTHOptsN]
+ [-exit_status ignore_config]
+ [-help]</pre>
</section>
+
<section>
- <title>Run tests using test specification</title>
+ <title>Run Tests using Test Specification</title>
<pre>
- ct_run -spec TestSpec1 TestSpec2 .. TestSpecN
- [-join_specs]
- [-config ConfigFile1 ConfigFile2 .. ConfigFileN]
- [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
- ConfigString2 and .. and CallbackModuleN ConfigStringN]
- [-decrypt_key Key] | [-decrypt_file KeyFile]
- [-label Label]
- [-logdir LogDir]
- [-logopts LogOpts]
- [-verbosity GenVLevel | [Category1 VLevel1 and
- Category2 VLevel2 and .. CategoryN VLevelN]]
- [-allow_user_terms]
- [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]
- [-stylesheet CSSFile]
- [-cover CoverCfgFile]
- [-cover_stop Bool]
- [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |
- [-event_handler_init EvHandler1 InitArg1 and
- EvHandler2 InitArg2 and .. EvHandlerN InitArgN]
- [-include InclDir1 InclDir2 .. InclDirN]
- [-no_auto_compile]
- [-abort_if_missing_suites]
- [-muliply_timetraps Multiplier]
- [-scale_timetraps]
- [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
- [-repeat N] |
- [-duration HHMMSS [-force_stop [skip_rest]]] |
- [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]
- [-basic_html]
- [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..
- CTHModuleN CTHOptsN]
- [-exit_status ignore_config]
- </pre>
+ ct_run -spec TestSpec1 TestSpec2 .. TestSpecN
+ [-join_specs]
+ [-config ConfigFile1 ConfigFile2 .. ConfigFileN]
+ [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
+ ConfigString2 and .. and CallbackModuleN ConfigStringN]
+ [-decrypt_key Key] | [-decrypt_file KeyFile]
+ [-label Label]
+ [-logdir LogDir]
+ [-logopts LogOpts]
+ [-verbosity GenVLevel | [Category1 VLevel1 and
+ Category2 VLevel2 and .. CategoryN VLevelN]]
+ [-allow_user_terms]
+ [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]
+ [-stylesheet CSSFile]
+ [-cover CoverCfgFile]
+ [-cover_stop Bool]
+ [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |
+ [-event_handler_init EvHandler1 InitArg1 and
+ EvHandler2 InitArg2 and .. EvHandlerN InitArgN]
+ [-include InclDir1 InclDir2 .. InclDirN]
+ [-no_auto_compile]
+ [-abort_if_missing_suites]
+ [-muliply_timetraps Multiplier]
+ [-scale_timetraps]
+ [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
+ [-repeat N] |
+ [-duration HHMMSS [-force_stop [skip_rest]]] |
+ [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]
+ [-basic_html]
+ [-no_esc_chars]
+ [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..
+ CTHModuleN CTHOptsN]
+ [-exit_status ignore_config]</pre>
</section>
+
<section>
- <title>Run tests in web based GUI</title>
+ <title>Run Tests in Web-Based GUI</title>
<pre>
- ct_run -vts [-browser Browser]
- [-dir TestDir1 TestDir2 .. TestDirN] |
- [[dir TestDir] -suite Suite [[-group Group] [-case Case]]]
- [-config ConfigFile1 ConfigFile2 .. ConfigFileN]
- [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
- ConfigString2 and .. and CallbackModuleN ConfigStringN]
- [-logopts LogOpts]
- [-verbosity GenVLevel | [Category1 VLevel1 and
- Category2 VLevel2 and .. CategoryN VLevelN]]
- [-decrypt_key Key] | [-decrypt_file KeyFile]
- [-include InclDir1 InclDir2 .. InclDirN]
- [-no_auto_compile]
- [-abort_if_missing_suites]
- [-muliply_timetraps Multiplier]
- [-scale_timetraps]
- [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
- [-basic_html]</pre>
+ ct_run -vts [-browser Browser]
+ [-dir TestDir1 TestDir2 .. TestDirN] |
+ [[dir TestDir] -suite Suite [[-group Group] [-case Case]]]
+ [-config ConfigFile1 ConfigFile2 .. ConfigFileN]
+ [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
+ ConfigString2 and .. and CallbackModuleN ConfigStringN]
+ [-logopts LogOpts]
+ [-verbosity GenVLevel | [Category1 VLevel1 and
+ Category2 VLevel2 and .. CategoryN VLevelN]]
+ [-decrypt_key Key] | [-decrypt_file KeyFile]
+ [-include InclDir1 InclDir2 .. InclDirN]
+ [-no_auto_compile]
+ [-abort_if_missing_suites]
+ [-muliply_timetraps Multiplier]
+ [-scale_timetraps]
+ [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
+ [-basic_html]
+ [-no_esc_chars]</pre>
</section>
+
<section>
- <title>Refresh the HTML index files</title>
+ <title>Refresh HTML Index Files</title>
<pre>
- ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre>
+ ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre>
</section>
+
<section>
- <title>Run CT in interactive mode</title>
+ <title>Run Common Test in Interactive Mode</title>
<pre>
- ct_run -shell
- [-config ConfigFile1 ConfigFile2 ... ConfigFileN]
- [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
- ConfigString2 and .. and CallbackModuleN ConfigStringN]
- [-decrypt_key Key] | [-decrypt_file KeyFile]</pre>
+ ct_run -shell
+ [-config ConfigFile1 ConfigFile2 ... ConfigFileN]
+ [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
+ ConfigString2 and .. and CallbackModuleN ConfigStringN]
+ [-decrypt_key Key] | [-decrypt_file KeyFile]</pre>
</section>
+
<section>
- <title>Start a Common Test Master node</title>
+ <title>Start a Common Test Master Node</title>
<pre>
- ct_run -ctmaster</pre>
+ ct_run -ctmaster</pre>
</section>
<section>
- <title>See also</title>
- <p>Please read the <seealso marker="run_test_chapter">Running Test Suites</seealso>
- chapter in the Common Test User's Guide for information about the meaning of the
- different start flags.</p>
+ <title>See Also</title>
+ <p>For information about the start flags, see section
+ <seealso marker="run_test_chapter">Running Tests and Analyzing
+ Results</seealso> in the User's Guide.</p>
</section>
</comref>
+
diff --git a/lib/common_test/doc/src/ct_slave.xml b/lib/common_test/doc/src/ct_slave.xml
new file mode 100644
index 0000000000..44a7b7873f
--- /dev/null
+++ b/lib/common_test/doc/src/ct_slave.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_slave</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_slave.xml</file>
+ </header>
+ <module>ct_slave</module>
+ <modulesummary>Common Test framework functions for starting and stopping
+ nodes for Large-Scale Testing.</modulesummary>
+
+ <description>
+
+ <p><c>Common Test</c> framework functions for starting and stopping nodes
+ for Large-Scale Testing.</p>
+
+ <p>This module exports functions used by the <c>Common Test</c>
+ Master to start and stop "slave" nodes. It is the default callback
+ module for the <c>{init, node_start}</c> term in the Test
+ Specification.</p>
+
+ </description>
+
+ <funcs>
+ <func>
+ <name>start(Node) -&gt; Result</name>
+ <fsummary>Starts an Erlang node with name Node on the local
+ host.</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v>
+ <v>Reason = already_started | started_not_connected | boot_timeout | init_timeout | startup_timeout | not_alive</v>
+ <v>NodeName = atom()</v>
+ </type>
+ <desc><marker id="start-1"/>
+ <p>Starts an Erlang node with name <c>Node</c> on the local host.</p>
+
+ <p>See also
+ <seealso marker="#start-3"><c>ct_slave:start/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>start(HostOrNode, NodeOrOpts) -&gt; Result</name>
+ <fsummary>Starts an Erlang node with default options on a specified
+ host, or on the local host with specified options.</fsummary>
+ <type>
+ <v>HostOrNode = atom()</v>
+ <v>NodeOrOpts = atom() | list()</v>
+ <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v>
+ <v>Reason = already_started | started_not_connected | boot_timeout | init_timeout | startup_timeout | not_alive</v>
+ <v>NodeName = atom()</v>
+ </type>
+ <desc><marker id="start-2"/>
+ <p>Starts an Erlang node with default options on a specified host, or
+ on the local host with specified options. That is, the call is
+ interpreted as <c>start(Host, Node)</c> when the second argument is
+ atom-valued and <c>start(Node, Opts)</c> when it is list-valued.</p>
+
+ <p>See also
+ <seealso marker="#start-3"><c>ct_slave:start/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>start(Host, Node, Opts) -&gt; Result</name>
+ <fsummary>Starts an Erlang node with name Node on host Host as
+ specified by the combination of options in Opts.</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ <v>Host = atom()</v>
+ <v>Opts = [OptTuples]</v>
+ <v>OptTuples = {username, Username} | {password, Password} | {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | {startup_timeout, StartupTimeout} | {startup_functions, StartupFunctions} | {monitor_master, Monitor} | {kill_if_fail, KillIfFail} | {erl_flags, ErlangFlags} | {env, [{EnvVar, Value}]}</v>
+ <v>Username = string()</v>
+ <v>Password = string()</v>
+ <v>BootTimeout = integer()</v>
+ <v>InitTimeout = integer()</v>
+ <v>StartupTimeout = integer()</v>
+ <v>StartupFunctions = [StartupFunctionSpec]</v>
+ <v>StartupFunctionSpec = {Module, Function, Arguments}</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Arguments = [term]</v>
+ <v>Monitor = bool()</v>
+ <v>KillIfFail = bool()</v>
+ <v>ErlangFlags = string()</v>
+ <v>EnvVar = string()</v>
+ <v>Value = string()</v>
+ <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v>
+ <v>Reason = already_started | started_not_connected | boot_timeout | init_timeout | startup_timeout | not_alive</v>
+ <v>NodeName = atom()</v>
+ </type>
+ <desc><marker id="start-3"/>
+ <p>Starts an Erlang node with name <c>Node</c> on host <c>Host</c> as
+ specified by the combination of options in <c>Opts</c>.</p>
+
+ <p>Options <c>Username</c> and <c>Password</c> are used to log on to the
+ remote host <c>Host</c>. <c>Username</c>, if omitted, defaults to
+ the current username. <c>Password</c> is empty by default.</p>
+
+ <p>A list of functions specified in option <c>Startup</c> are
+ executed after startup of the node. Notice that all used modules
+ are to be present in the code path on <c>Host</c>.</p>
+
+ <p>The time-outs are applied as follows:</p>
+
+ <taglist>
+ <tag><c>BootTimeout</c></tag>
+ <item><p>The time to start the Erlang node, in seconds. Defaults to
+ 3 seconds. If the node is not pingable within this time, the result
+ <c>{error, boot_timeout, NodeName}</c> is returned.</p></item>
+ <tag><c>InitTimeout</c></tag>
+ <item><p>The time to wait for the node until it calls the internal
+ callback function informing master about a successful startup.
+ Defaults to 1 second. In case of a timed out message, the result
+ <c>{error, init_timeout, NodeName}</c> is returned.</p></item>
+ <tag><c>StartupTimeout</c></tag>
+ <item><p>The time to wait until the node stops to run
+ <c>StartupFunctions</c>. Defaults to 1 second. If this time-out
+ occurs, the result <c>{error, startup_timeout, NodeName}</c> is
+ returned.</p></item>
+ </taglist>
+
+ <p><em>Options:</em></p>
+
+ <taglist>
+ <tag><c>monitor_master</c></tag>
+ <item><p>Specifies if the slave node is to be stopped if the
+ master node stops. Defaults to <c>false</c>.</p></item>
+ <tag><c>kill_if_fail</c></tag>
+ <item><p>Specifies if the slave node is to be killed if a time-out
+ occurs during initialization or startup. Defaults to <c>true</c>.
+ Notice that the node can also be still alive it the boot time-out
+ occurred, but it is not killed in this case.</p></item>
+ <tag><c>erlang_flags</c></tag>
+ <item><p>Specifies which flags are added to the parameters of the
+ executable <c>erl</c>.</p></item>
+ <tag><c>env</c></tag>
+ <item><p>Specifies a list of environment variables that will extend
+ the environment.</p></item>
+ </taglist>
+
+ <p><em>Special return values:</em></p>
+
+ <list type="bulleted">
+ <item><p><c>{error, already_started, NodeName}</c> if the node
+ with the specified name is already started on a specified
+ host.</p></item>
+ <item><p><c>{error, started_not_connected, NodeName}</c> if the
+ node is started, but not connected to the master node.</p></item>
+ <item><p><c>{error, not_alive, NodeName}</c> if the node on which
+ <seealso marker="#start-3"><c>ct_slave:start/3</c></seealso> is
+ called, is not alive. Notice that <c>NodeName</c> is the name of
+ the current node in this case.</p></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name>stop(Node) -&gt; Result</name>
+ <fsummary>Stops the running Erlang node with name Node on the local
+ host.</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v>
+ <v>Reason = not_started | not_connected | stop_timeout</v>
+ </type>
+ <desc><marker id="stop-1"/>
+ <p>Stops the running Erlang node with name <c>Node</c> on the local
+ host.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>stop(Host, Node) -&gt; Result</name>
+ <fsummary>Stops the running Erlang node with name Node on host
+ Host.</fsummary>
+ <type>
+ <v>Host = atom()</v>
+ <v>Node = atom()</v>
+ <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v>
+ <v>Reason = not_started | not_connected | stop_timeout</v>
+ <v>NodeName = atom()</v>
+ </type>
+ <desc><marker id="stop-2"/>
+ <p>Stops the running Erlang node with name <c>Node</c> on host
+ <c>Host</c>.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_snmp.xml b/lib/common_test/doc/src/ct_snmp.xml
new file mode 100644
index 0000000000..d001fb24ec
--- /dev/null
+++ b/lib/common_test/doc/src/ct_snmp.xml
@@ -0,0 +1,523 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_snmp</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_snmp.xml</file>
+ </header>
+ <module>ct_snmp</module>
+ <modulesummary>Common Test user interface module for the SNMP application.</modulesummary>
+
+ <description>
+
+ <p><c>Common Test</c> user interface module for the <c>SNMP</c>
+ application.</p>
+
+ <p>The purpose of this module is to simplify SNMP configuration for the
+ test case writer. Many test cases can use default values for common
+ operations and then no SNMP configuration files need to be supplied.
+ When it is necessary to change particular configuration parameters, a
+ subset of the relevant SNMP configuration files can be passed to
+ <c>ct_snmp</c> by <c>Common Test</c> configuration files. For more
+ specialized configuration parameters, a simple SNMP configuration file
+ can be placed in the test suite data directory. To simplify the test
+ suite, <c>Common Test</c> keeps track of some of the SNMP manager
+ information. This way the test suite does not have to handle as many
+ input parameters as if it had to interface wthe OTP SNMP manager
+ directly.</p>
+
+ <p><em>Configurable SNMP Manager and Agent Parameters:</em></p>
+
+ <p>Manager configuration:</p>
+
+ <taglist>
+ <tag><c>[{start_manager, boolean()}</c></tag>
+ <item><p>Optional. Default is <c>true</c>.</p></item>
+ <tag><c>{users, [{user_name(), [call_back_module(), user_data()]}]}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{usm_users, [{usm_user_name(), [usm_config()]}]}</c></tag>
+ <item><p>Optional. SNMPv3 only.</p></item>
+ <tag><c>{managed_agents,[{agent_name(), [user_name(), agent_ip(), agent_port(), [agent_config()]]}]}</c></tag>
+ <item><p><c>managed_agents</c> is optional.</p></item>
+ <tag><c>{max_msg_size, integer()}</c></tag>
+ <item><p>Optional. Default is <c>484</c>.</p></item>
+ <tag><c>{mgr_port, integer()}</c></tag>
+ <item><p>Optional. Default is <c>5000</c>.</p></item>
+ <tag><c>{engine _id, string()}</c></tag>
+ <item><p>Optional. Default is <c>"mgrEngine"</c>.</p></item>
+ </taglist>
+
+ <p>Agent configuration:</p>
+
+ <taglist>
+ <tag><c>{start_agent, boolean()}</c></tag>
+ <item><p>Optional. Default is <c>false</c>.</p></item>
+ <tag><c>{agent_sysname, string()}</c></tag>
+ <item><p>Optional. Default is <c>"ct_test"</c>.</p></item>
+ <tag><c>{agent_manager_ip, manager_ip()}</c></tag>
+ <item><p>Optional. Default is <c>localhost</c>.</p></item>
+ <tag><c>{agent_vsns, list()}</c></tag>
+ <item><p>Optional. Default is <c>[v2]</c>.</p></item>
+ <tag><c>{agent_trap_udp, integer()}</c></tag>
+ <item><p>Optional. Default is <c>5000</c>.</p></item>
+ <tag><c>{agent_udp, integer()}</c></tag>
+ <item><p>Optional. Default is <c>4000</c>.</p></item>
+ <tag><c>{agent_notify_type, atom()}</c></tag>
+ <item><p>Optional. Default is <c>trap</c>.</p></item>
+ <tag><c>{agent_sec_type, sec_type()}</c></tag>
+ <item><p>Optional. Default is <c>none</c>.</p></item>
+ <tag><c>{agent_passwd, string()}</c></tag>
+ <item><p>Optional. Default is <c>""</c>.</p></item>
+ <tag><c>{agent_engine_id, string()}</c></tag>
+ <item><p>Optional. Default is <c>"agentEngine"</c>.</p></item>
+ <tag><c>{agent_max_msg_size, string()}</c></tag>
+ <item><p>Optional. Default is <c>484</c>.</p></item>
+ </taglist>
+
+ <p>The following parameters represents the SNMP configuration files
+ <c>context.conf</c>, <c>standard.conf</c>, <c>community.conf</c>,
+ <c>vacm.conf</c>, <c>usm.conf</c>, <c>notify.conf</c>,
+ <c>target_addr.conf</c>, and <c>target_params.conf</c>. Notice that
+ all values in <c>agent.conf</c> can be modified by the parameters
+ listed above. All these configuration files have default values set by
+ the <c>SNMP</c> application. These values can be overridden by suppling
+ a list of valid configuration values or a file located in the test
+ suites data directory, which can produce a list of valid configuration
+ values if you apply function <c>file:consult/1</c> to the file.</p>
+
+ <taglist>
+ <tag><c>{agent_contexts, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_community, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_sysinfo, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_vacm, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_usm, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_notify_def, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_target_address_def, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ <tag><c>{agent_target_param_def, [term()] | {data_dir_file, rel_path()}}</c></tag>
+ <item><p>Optional.</p></item>
+ </taglist>
+
+ <p>Parameter <c>MgrAgentConfName</c> in the functions is to be a name
+ you allocate in your test suite using a <c>require</c> statement.
+ Example (where <c>MgrAgentConfName = snmp_mgr_agent</c>):</p>
+
+ <pre>
+ suite() -&gt; [{require, snmp_mgr_agent, snmp}].</pre>
+
+ <p>or</p>
+
+ <pre>
+ ct:require(snmp_mgr_agent, snmp).</pre>
+
+ <p>Notice that USM users are needed for SNMPv3 configuration and are
+ not to be confused with users.</p>
+
+ <p>SNMP traps, inform, and report messages are handled by the user
+ callback module. For details, see the
+ <seealso marker="snmp:index"><c>SNMP</c></seealso> application.</p>
+
+ <p>It is recommended to use the <c>.hrl</c> files created by the
+ Erlang/OTP MIB compiler to define the Object Identifiers (OIDs).
+ For example, to get the Erlang node name from <c>erlNodeTable</c>
+ in the OTP-MIB:</p>
+
+ <pre>
+ Oid = ?erlNodeEntry ++ [?erlNodeName, 1]</pre>
+
+ <p>Furthermore, values can be set for <c>SNMP</c> application configuration
+ parameters, <c>config</c>, <c>server</c>, <c>net_if</c>, and so on (for
+ a list of valid parameters and types, see the <seealso marker="snmp:users_guide"><c>User's Guide for the SNMP application</c></seealso>). This is
+ done by defining a configuration data variable on the following form:</p>
+
+ <pre>
+ {snmp_app, [{manager, [snmp_app_manager_params()]},
+ {agent, [snmp_app_agent_params()]}]}.</pre>
+
+ <p>A name for the data must be allocated in the suite using
+ <c>require</c> (see the example above). Pass this name as argument
+ <c>SnmpAppConfName</c> to
+ <seealso marker="#start-3"><c>ct_snmp:start/3</c></seealso>.
+ <c>ct_snmp</c> specifies default values for some <c>SNMP</c> application
+ configuration parameters (such as <c>{verbosity,trace}</c> for parameter
+ <c>config</c>). This set of defaults is merged with the parameters
+ specified by the user. The user values override <c>ct_snmp</c>
+ defaults.</p>
+
+ </description>
+
+ <section>
+ <title>Data Types</title>
+ <marker id="types"/>
+ <taglist>
+ <tag><c>agent_config() = {Item, Value}</c></tag>
+ <item><marker id="type-agent_config"/> </item>
+ <tag><c>agent_ip() = ip()</c></tag>
+ <item><marker id="type-agent_ip"/> </item>
+ <tag><c>agent_name() = atom()</c></tag>
+ <item><marker id="type-agent_name"/> </item>
+ <tag><c>agent_port() = integer()</c></tag>
+ <item><marker id="type-agent_port"/> </item>
+ <tag><c>call_back_module() = atom()</c></tag>
+ <item><marker id="type-call_back_module"/> </item>
+ <tag><c>error_index() = integer()</c></tag>
+ <item><marker id="type-error_index"/> </item>
+ <tag><c>error_status() = noError | atom()</c></tag>
+ <item><marker id="type-error_status"/> </item>
+ <tag><c>ip() = string() | {integer(), integer(), integer(), integer()}</c></tag>
+ <item><marker id="type-ip"/> </item>
+ <tag><c>manager_ip() = ip()</c></tag>
+ <item><marker id="type-manager_ip"/> </item>
+ <tag><c>oid() = [byte()]</c></tag>
+ <item><marker id="type-oid"/> </item>
+ <tag><c>oids() = [oid()]</c></tag>
+ <item><marker id="type-oids"/> </item>
+ <tag><c>rel_path() = string()</c></tag>
+ <item><marker id="type-rel_path"/> </item>
+ <tag><c>sec_type() = none | minimum | semi</c></tag>
+ <item><marker id="type-sec_type"/> </item>
+ <tag><c>snmp_app_agent_params() = term()</c></tag>
+ <item><marker id="type-snmp_app_agent_params"/> </item>
+ <tag><c>snmp_app_manager_params() = term()</c></tag>
+ <item><marker id="type-snmp_app_manager_params"/> </item>
+ <tag><c>snmpreply() = {error_status(), error_index(), varbinds()}</c></tag>
+ <item><marker id="type-snmpreply"/> </item>
+ <tag><c>user_data() = term()</c></tag>
+ <item><marker id="type-user_data"/> </item>
+ <tag><c>user_name() = atom()</c></tag>
+ <item><marker id="type-user_name"/> </item>
+ <tag><c>usm_config() = {Item, Value}</c></tag>
+ <item><marker id="type-usm_config"/> </item>
+ <tag><c>usm_user_name() = string()</c></tag>
+ <item><marker id="type-usm_user_name"/> </item>
+ <tag><c>value_type() = o('OBJECT IDENTIFIER') | i('INTEGER') | u('Unsigned32') | g('Unsigned32') | s('OCTET STRING')</c></tag>
+ <item><marker id="type-value_type"/> </item>
+ <tag><c>var_and_val() = {oid(), value_type(), value()}</c></tag>
+ <item><marker id="type-var_and_val"/> </item>
+ <tag><c>varbind() = term()</c></tag>
+ <item><marker id="type-varbind"/> </item>
+ <tag><c>varbinds() = [varbind()]</c></tag>
+ <item><marker id="type-varbinds"/> </item>
+ <tag><c>varsandvals() = [var_and_val()]</c></tag>
+ <item><marker id="type-varsandvals"/> </item>
+ </taglist>
+ <p>These data types are described in the documentation for
+ the <seealso marker="snmp:index"><c>SNMP</c></seealso> application.</p>
+ </section>
+
+ <funcs>
+ <func>
+ <name>get_next_values(Agent, Oids, MgrAgentConfName) -&gt; SnmpReply</name>
+ <fsummary>Issues a synchronous SNMP get next request.</fsummary>
+ <type>
+ <v>Agent = agent_name()</v>
+ <v>Oids = oids()</v>
+ <v>MgrAgentConfName = atom()</v>
+ <v>SnmpReply = snmpreply()</v>
+ </type>
+ <desc><marker id="get_next_values-3"/>
+ <p>Issues a synchronous SNMP <c>get next</c> request.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_values(Agent, Oids, MgrAgentConfName) -&gt; SnmpReply</name>
+ <fsummary>Issues a synchronous SNMP get request.</fsummary>
+ <type>
+ <v>Agent = agent_name()</v>
+ <v>Oids = oids()</v>
+ <v>MgrAgentConfName = atom()</v>
+ <v>SnmpReply = snmpreply()</v>
+ </type>
+ <desc><marker id="get_values-3"/>
+ <p>Issues a synchronous SNMP <c>get</c> request.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>load_mibs(Mibs) -&gt; ok | {error, Reason}</name>
+ <fsummary>Loads the MIBs into agent snmp_master_agent.</fsummary>
+ <type>
+ <v>Mibs = [MibName]</v>
+ <v>MibName = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="load_mibs-1"/>
+ <p>Loads the MIBs into agent <c>snmp_master_agent</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>register_agents(MgrAgentConfName, ManagedAgents) -&gt; ok | {error, Reason}</name>
+ <fsummary>Explicitly instructs the manager to handle this
+ agent.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>ManagedAgents = [agent()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="register_agents-2"/>
+ <p>Explicitly instructs the manager to handle this agent. Corresponds
+ to making an entry in <c>agents.conf</c>.</p>
+
+ <p>This function tries to register the specified managed agents, without
+ checking if any of them exist. To change a registered managed agent,
+ the agent must first be unregistered.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>register_users(MgrAgentConfName, Users) -&gt; ok | {error, Reason}</name>
+ <fsummary>Registers the manager entity (=user) responsible for specific
+ agent(s).</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>Users = [user()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="register_users-2"/>
+ <p>Registers the manager entity (=user) responsible for specific
+ agent(s). Corresponds to making an entry in <c>users.conf</c>.</p>
+
+ <p>This function tries to register the specified users, without checking
+ if any of them exist. To change a registered user, the user must
+ first be unregistered.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>register_usm_users(MgrAgentConfName, UsmUsers) -&gt; ok | {error, Reason}</name>
+ <fsummary>Explicitly instructs the manager to handle this USM user.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>UsmUsers = [usm_user()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="register_usm_users-2"/>
+ <p>Explicitly instructs the manager to handle this USM user.
+ Corresponds to making an entry in <c>usm.conf</c>.</p>
+
+ <p>This function tries to register the specified users, without checking
+ if any of them exist. To change a registered user, the user must
+ first be unregistered.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>set_info(Config) -&gt; [{Agent, OldVarsAndVals, NewVarsAndVals}]</name>
+ <fsummary>Returns a list of all successful set requests performed in the
+ test case in reverse order.</fsummary>
+ <type>
+ <v>Config = [{Key, Value}]</v>
+ <v>Agent = agent_name()</v>
+ <v>OldVarsAndVals = varsandvals()</v>
+ <v>NewVarsAndVals = varsandvals()</v>
+ </type>
+ <desc><marker id="set_info-1"/>
+ <p>Returns a list of all successful <c>set</c> requests performed in
+ the test case in reverse order. The list contains the involved user
+ and agent, the value before <c>set</c>, and the new value. This is
+ intended to simplify the cleanup in function <c>end_per_testcase</c>,
+ that is, the undoing of the <c>set</c> requests and their possible
+ side-effects.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -&gt; SnmpReply</name>
+ <fsummary>Issues a synchronous SNMP set request.</fsummary>
+ <type>
+ <v>Agent = agent_name()</v>
+ <v>Oids = oids()</v>
+ <v>MgrAgentConfName = atom()</v>
+ <v>Config = [{Key, Value}]</v>
+ <v>SnmpReply = snmpreply()</v>
+ </type>
+ <desc><marker id="set_values-4"/>
+ <p>Issues a synchronous SNMP <c>set</c> request.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>start(Config, MgrAgentConfName) -&gt; ok</name>
+ <fsummary>Equivalent to start(Config, MgrAgentConfName,
+ undefined).</fsummary>
+ <desc><marker id="start-2"/>
+ <p>Equivalent to
+ <seealso marker="#start-3"><c>ct_snmp:start(Config, MgrAgentConfName,
+ undefined)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>start(Config, MgrAgentConfName, SnmpAppConfName) -&gt; ok</name>
+ <fsummary>Starts an SNMP manager and/or agent.</fsummary>
+ <type>
+ <v>Config = [{Key, Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>MgrAgentConfName = atom()</v>
+ <v>SnmpConfName = atom()</v>
+ </type>
+ <desc><marker id="start-3"/>
+ <p>Starts an SNMP manager and/or agent. In the manager case,
+ registrations of users and agents, as specified by the configuration
+ <c>MgrAgentConfName</c>, are performed. When using SNMPv3, called
+ USM users are also registered. Users, <c>usm_users</c>, and
+ managed agents can also be registered later using
+ <seealso marker="#register_users-2"><c>ct_snmp:register_users/2</c></seealso>,
+ <seealso marker="#register_agents-2"><c>ct_snmp:register_agents/2</c></seealso>,
+ and
+ <seealso marker="#register_usm_users-2"><c>ct_snmp:register_usm_users/2</c></seealso>.</p>
+
+ <p>The agent started is called <c>snmp_master_agent</c>. Use
+ <seealso marker="#load_mibs-1"><c>ct_snmp:load_mibs/1</c></seealso>
+ to load MIBs into the agent.</p>
+
+ <p>With <c>SnmpAppConfName</c> SNMP applications can be configured
+ with parameters <c>config</c>, <c>mibs</c>, <c>net_if</c>, and so on.
+ The values are merged with (and possibly override) default values
+ set by <c>ct_snmp</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>stop(Config) -&gt; ok</name>
+ <fsummary>Stops the SNMP manager and/or agent, and removes all files
+ created.</fsummary>
+ <type>
+ <v>Config = [{Key, Value}]</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ </type>
+ <desc><marker id="stop-1"/>
+ <p>Stops the SNMP manager and/or agent, and removes all files
+ created.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unload_mibs(Mibs) -&gt; ok | {error, Reason}</name>
+ <fsummary>Unloads the MIBs from agent snmp_master_agent.</fsummary>
+ <type>
+ <v>Mibs = [MibName]</v>
+ <v>MibName = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unload_mibs-1"/>
+ <p>Unloads the MIBs from agent <c>snmp_master_agent</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unregister_agents(MgrAgentConfName) -&gt; ok</name>
+ <fsummary>Unregisters all managed agents.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unregister_agents-1"/>
+ <p>Unregisters all managed agents.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unregister_agents(MgrAgentConfName, ManagedAgents) -&gt; ok</name>
+ <fsummary>Unregisters the specified managed agents.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>ManagedAgents = [agent_name()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unregister_agents-2"/>
+ <p>Unregisters the specified managed agents.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unregister_users(MgrAgentConfName) -&gt; ok</name>
+ <fsummary>Unregisters all users.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unregister_users-1"/>
+ <p>Unregisters all users.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unregister_users(MgrAgentConfName, Users) -&gt; ok</name>
+ <fsummary>Unregisters the specified users.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>Users = [user_name()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unregister_users-2"/>
+ <p>Unregisters the specified users.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unregister_usm_users(MgrAgentConfName) -&gt; ok</name>
+ <fsummary>Unregisters all USM users.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unregister_usm_users-1"/>
+ <p>Unregisters all USM users.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>unregister_usm_users(MgrAgentConfName, UsmUsers) -&gt; ok</name>
+ <fsummary>Unregisters the specified USM users.</fsummary>
+ <type>
+ <v>MgrAgentConfName = atom()</v>
+ <v>UsmUsers = [usm_user_name()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="unregister_usm_users-2"/>
+ <p>Unregisters the specified USM users.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_ssh.xml b/lib/common_test/doc/src/ct_ssh.xml
new file mode 100644
index 0000000000..92b1f60b8c
--- /dev/null
+++ b/lib/common_test/doc/src/ct_ssh.xml
@@ -0,0 +1,1150 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_ssh</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_ssh.xml</file>
+ </header>
+ <module>ct_ssh</module>
+ <modulesummary>SSH/SFTP client module.</modulesummary>
+
+<description>
+
+ <p>SSH/SFTP client module.</p>
+
+ <p>This module uses application <c>SSH</c>, which provides detailed
+ information about, for example, functions, types, and options.</p>
+
+ <p>Argument <c>Server</c> in the SFTP functions is only to be used for
+ SFTP sessions that have been started on existing SSH connections
+ (that is, when the original connection type is <c>ssh</c>). Whenever
+ the connection type is <c>sftp</c>, use the SSH connection reference
+ only.</p>
+
+ <p>The following options are valid for specifying an SSH/SFTP
+ connection (that is, can be used as configuration elements):</p>
+
+ <pre>
+ [{ConnType, Addr},
+ {port, Port},
+ {user, UserName}
+ {password, Pwd}
+ {user_dir, String}
+ {public_key_alg, PubKeyAlg}
+ {connect_timeout, Timeout}
+ {key_cb, KeyCallbackMod}]</pre>
+
+ <p><c>ConnType = ssh | sftp</c>.</p>
+
+ <p>For other types, see
+ <seealso marker="ssh:ssh"><c>ssh:ssh(3)</c></seealso>.</p>
+
+ <p>All time-out parameters in <c>ct_ssh</c> functions are values in
+ milliseconds.</p>
+
+ </description>
+
+ <section>
+ <title>Data Types</title>
+ <marker id="types"/>
+ <taglist>
+ <tag><c>connection() = handle() | target_name()</c></tag>
+ <item><marker id="type-connection"/>
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>handle() = handle()</c></tag>
+ <item><marker id="type-handle"/>
+ <p>Handle for a specific SSH/SFTP connection, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>ssh_sftp_return() = term()</c></tag>
+ <item><marker id="type-ssh_sftp_return"/>
+ <p>Return value from an
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp</c></seealso>
+ function.</p></item>
+ </taglist>
+ </section>
+
+ <funcs>
+ <func>
+ <name>apread(SSH, Handle, Position, Length) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="apread-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>apread(SSH, Server, Handle, Position, Length) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="apread-5"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>apwrite(SSH, Handle, Position, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="apwrite-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>apwrite(SSH, Server, Handle, Position, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="apwrite-5"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>aread(SSH, Handle, Len) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="aread-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>aread(SSH, Server, Handle, Len) -&gt; Result</name>
+ <fsummary>For inforamtion and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="aread-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>awrite(SSH, Handle, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="awrite-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>awrite(SSH, Server, Handle, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="awrite-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>close(SSH, Handle) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="close-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>close(SSH, Server, Handle) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="close-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>connect(KeyOrName) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Equivalent to connect(KeyOrName, host, []).</fsummary>
+ <desc><marker id="connect-1"/>
+ <p>Equivalent to
+ <seealso marker="#connect-3"><c>ct_ssh:connect(KeyOrName, host,
+ [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>connect(KeyOrName, ConnType) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Equivalent to connect(KeyOrName, ConnType, []).</fsummary>
+ <desc><marker id="connect-2"/>
+ <p>Equivalent to
+ <seealso marker="#connect-3"><c>ct_ssh:connect(KeyOrName, ConnType,
+ [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>connect(KeyOrName, ConnType, ExtraOpts) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Opens an SSH or SFTP connection using the information
+ associated with KeyOrName.</fsummary>
+ <type>
+ <v>KeyOrName = Key | Name</v>
+ <v>Key = atom()</v>
+ <v>Name = target_name()</v>
+ <v>ConnType = ssh | sftp | host</v>
+ <v>ExtraOpts = ssh_connect_options()</v>
+ <v>Handle = handle()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="connect-3"/>
+ <p>Opens an SSH or SFTP connection using the information associated
+ with <c>KeyOrName</c>.</p>
+
+ <p>If <c>Name</c> (an alias name for <c>Key</c>) is used to identify
+ the connection, this name can be used as connection reference for
+ subsequent calls. Only one open connection at a time associated
+ with <c>Name</c> is possible. If <c>Key</c> is used, the returned
+ handle must be used for subsequent calls (multiple connections can
+ be opened using the configuration data specified by <c>Key</c>).</p>
+
+ <p>For information on how to create a new <c>Name</c>, see
+ <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p>
+
+ <p>For <c>target_name</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p>
+
+ <p><c>ConnType</c> always overrides the type specified in the
+ address tuple in the configuration data (and in <c>ExtraOpts</c>).
+ So it is possible to, for example, open an SFTP connection
+ directly using data originally specifying an SSH connection. Value
+ <c>host</c> means that the connection type specified by the host
+ option (either in the configuration data or in <c>ExtraOpts</c>)
+ is used.</p>
+
+ <p><c>ExtraOpts</c> (optional) are extra SSH options to be added to
+ the configuration data for <c>KeyOrName</c>. The extra options
+ override any existing options with the same key in the
+ configuration data. For details on valid SSH options, see
+ application <seealso marker="ssh:index"><c>SSH</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>del_dir(SSH, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="del_dir-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>del_dir(SSH, Server, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="del_dir-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>delete(SSH, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="delete-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>delete(SSH, Server, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="delete-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>disconnect(SSH) -&gt; ok | {error, Reason}</name>
+ <fsummary>Closes an SSH/SFTP connection.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="disconnect-1"/>
+ <p>Closes an SSH/SFTP connection.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>exec(SSH, Command) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to exec(SSH, Command, DefaultTimeout).</fsummary>
+ <desc><marker id="exec-2"/>
+ <p>Equivalent to
+ <seealso marker="#exec-3"><c>ct_ssh:exec(SSH, Command,
+ DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>exec(SSH, Command, Timeout) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Requests server to perform Command.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Command = string()</v>
+ <v>Timeout = integer()</v>
+ <v>Data = list()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="exec-3"/>
+ <p>Requests server to perform <c>Command</c>. A session channel is
+ opened automatically for the request. <c>Data</c> is received from
+ the server as a result of the command.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>exec(SSH, ChannelId, Command, Timeout) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Requests server to perform Command.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>Command = string()</v>
+ <v>Timeout = integer()</v>
+ <v>Data = list()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="exec-4"/>
+ <p>Requests server to perform <c>Command</c>. A previously opened
+ session channel is used for the request. <c>Data</c> is received
+ from the server as a result of the command.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_file_info(SSH, Handle) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="get_file_info-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_file_info(SSH, Server, Handle) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="get_file_info-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>list_dir(SSH, Path) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="list_dir-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>list_dir(SSH, Server, Path) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="list_dir-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>make_dir(SSH, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="make_dir-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>make_dir(SSH, Server, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="make_dir-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>make_symlink(SSH, Name, Target) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="make_symlink-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>make_symlink(SSH, Server, Name, Target) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="make_symlink-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(SSH, File, Mode) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="open-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(SSH, Server, File, Mode) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="open-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>opendir(SSH, Path) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="opendir-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>opendir(SSH, Server, Path) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="opendir-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>position(SSH, Handle, Location) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="position-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>position(SSH, Server, Handle, Location) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="position-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pread(SSH, Handle, Position, Length) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="pread-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pread(SSH, Server, Handle, Position, Length) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="pread-5"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pwrite(SSH, Handle, Position, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="pwrite-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pwrite(SSH, Server, Handle, Position, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="pwrite-5"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read(SSH, Handle, Len) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read(SSH, Server, Handle, Len) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_file(SSH, File) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_file-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_file(SSH, Server, File) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_file-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_file_info(SSH, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_file_info-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_file_info(SSH, Server, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_file_info-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_link(SSH, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_link-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_link(SSH, Server, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_link-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_link_info(SSH, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_link_info-2"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>read_link_info(SSH, Server, Name) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="read_link_info-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>receive_response(SSH, ChannelId) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to receive_response(SSH, ChannelId,
+ close).</fsummary>
+ <desc><marker id="receive_response-2"/>
+ <p>Equivalent to
+ <seealso marker="#receive_response-3"><c>ct_ssh:receive_response(SSH,
+ChannelId, close)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>receive_response(SSH, ChannelId, End) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to receive_response(SSH, ChannelId, End,
+ DefaultTimeout).</fsummary>
+ <desc><marker id="receive_response-3"/>
+ <p>Equivalent to
+ <seealso marker="#receive_response-4"><c>ct_ssh:receive_response(SSH,
+ChannelId, End, DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>receive_response(SSH, ChannelId, End, Timeout) -&gt; {ok, Data} | {timeout, Data} | {error, Reason}</name>
+ <fsummary>Receives expected data from server on the specified session
+ channel.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>End = Fun | close | timeout</v>
+ <v>Timeout = integer()</v>
+ <v>Data = list()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="receive_response-4"/>
+ <p>Receives expected data from server on the specified session
+ channel.</p>
+
+ <p>If <c>End == close</c>, data is returned to the caller when the
+ channel is closed by the server. If a time-out occurs before this
+ happens, the function returns <c>{timeout,Data}</c> (where
+ <c>Data</c> is the data received so far).</p>
+ <p>If <c>End == timeout</c>, a time-out is expected and
+ <c>{ok,Data}</c> is returned both in the case of a time-out and
+ when the channel is closed.</p>
+
+ <p>If <c>End</c> is a fun, this fun is called with one argument, the
+ data value in a received <c>ssh_cm</c> message (see
+ <seealso marker="ssh:ssh_connection"><c>ssh:ssh_connection(3)</c></seealso>.
+ The fun is to return either <c>true</c> to end the receiving
+ operation (and have the so far collected data returned) or
+ <c>false</c> to wait for more data from the server. Even if a fun
+ is supplied, the function returns immediately if the server closes
+ the channel).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>rename(SSH, OldName, NewName) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="rename-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>rename(SSH, Server, OldName, NewName) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="rename-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(SSH, ChannelId, Data) -&gt; ok | {error, Reason}</name>
+ <fsummary>Equivalent to send(SSH, ChannelId, 0, Data,
+ DefaultTimeout).</fsummary>
+ <desc><marker id="send-3"/>
+ <p>Equivalent to <seealso marker="#send-5"><c>ct_ssh:send(SSH,
+ ChannelId, 0, Data, DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(SSH, ChannelId, Data, Timeout) -&gt; ok | {error, Reason}</name>
+ <fsummary>Equivalent to send(SSH, ChannelId, 0, Data, Timeout).</fsummary>
+ <desc><marker id="send-4"/>
+ <p>Equivalent to <seealso marker="#send-5"><c>ct_ssh:send(SSH,
+ ChannelId, 0, Data, Timeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(SSH, ChannelId, Type, Data, Timeout) -&gt; ok | {error, Reason}</name>
+ <fsummary>Sends data to server on specified session channel.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>Type = integer()</v>
+ <v>Data = list()</v>
+ <v>Timeout = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="send-5"/>
+ <p>Sends data to server on specified session channel.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send_and_receive(SSH, ChannelId, Data) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to send_and_receive(SSH, ChannelId, Data,
+ close).</fsummary>
+ <desc><marker id="send_and_receive-3"/>
+ <p>Equivalent to
+ <seealso marker="#send_and_receive-4"><c>ct_ssh:send_and_receive(SSH,
+ ChannelId, Data, close)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send_and_receive(SSH, ChannelId, Data, End) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to send_and_receive(SSH, ChannelId, 0, Data, End,
+ DefaultTimeout).</fsummary>
+ <desc><marker id="send_and_receive-4"/>
+ <p>Equivalent to
+ <seealso marker="#send_and_receive-6"><c>ct_ssh;send_and_receive(SSH,
+ChannelId, 0, Data, End, DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send_and_receive(SSH, ChannelId, Data, End, Timeout) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to send_and_receive(SSH, ChannelId, 0, Data, End,
+ Timeout).</fsummary>
+ <desc><marker id="send_and_receive-5"/>
+ <p>Equivalent to
+ <seealso marker="#send_and_receive-6"><c>ct_ssh:send_and_receive(SSH,
+ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send_and_receive(SSH, ChannelId, Type, Data, End, Timeout) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Sends data to server on specified session channel and waits
+ to receive the server response.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>Type = integer()</v>
+ <v>Data = list()</v>
+ <v>End = Fun | close | timeout</v>
+ <v>Timeout = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="send_and_receive-6"/>
+ <p>Sends data to server on specified session channel and waits to
+ receive the server response.</p>
+
+ <p>For details on argument <c>End</c>, see
+ <seealso marker="#receive_response-4"><c>ct_ssh:receive_response/4</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>session_close(SSH, ChannelId) -&gt; ok | {error, Reason}</name>
+ <fsummary>Closes an SSH session channel.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="session_close-2"/>
+ <p>Closes an SSH session channel.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>session_open(SSH) -&gt; {ok, ChannelId} | {error, Reason}</name>
+ <fsummary>Equivalent to session_open(SSH, DefaultTimeout).</fsummary>
+ <desc><marker id="session_open-1"/>
+ <p>Equivalent to
+ <seealso marker="#session_open-2"><c>ct_ssh:session_open(SSH,
+ DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>session_open(SSH, Timeout) -&gt; {ok, ChannelId} | {error, Reason}</name>
+ <fsummary>Opens a channel for an SSH session.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Timeout = integer()</v>
+ <v>ChannelId = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="session_open-2"/>
+ <p>Opens a channel for an SSH session.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>sftp_connect(SSH) -&gt; {ok, Server} | {error, Reason}</name>
+ <fsummary>Starts an SFTP session on an already existing SSH
+ connection.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Server = pid()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="sftp_connect-1"/>
+ <p>Starts an SFTP session on an already existing SSH connection.
+ <c>Server</c> identifies the new session and must be specified
+ whenever SFTP requests are to be sent.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>subsystem(SSH, ChannelId, Subsystem) -&gt; Status | {error, Reason}</name>
+ <fsummary>Equivalent to subsystem(SSH, ChannelId, Subsystem,
+ DefaultTimeout).</fsummary>
+ <desc><marker id="subsystem-3"/>
+ <p>Equivalent to
+ <seealso marker="#subsystem-4"><c>ct_ssh:subsystem(SSH, ChannelId,
+ Subsystem, DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>subsystem(SSH, ChannelId, Subsystem, Timeout) -&gt; Status | {error, Reason}</name>
+ <fsummary>Sends a request to execute a predefined subsystem.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>Subsystem = string()</v>
+ <v>Timeout = integer()</v>
+ <v>Status = success | failure</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="subsystem-4"/>
+ <p>Sends a request to execute a predefined subsystem.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>write(SSH, Handle, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="write-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>write(SSH, Server, Handle, Data) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="write-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>write_file(SSH, File, Iolist) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="write_file-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>write_file(SSH, Server, File, Iolist) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="write_file-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>write_file_info(SSH, Name, Info) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="write_file_info-3"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>write_file_info(SSH, Server, Name, Info) -&gt; Result</name>
+ <fsummary>For information and other types, see ssh_sftp(3).</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>Result = ssh_sftp_return() | {error, Reason}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="write_file_info-4"/>
+ <p>For information and other types, see
+ <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_telnet.xml b/lib/common_test/doc/src/ct_telnet.xml
new file mode 100644
index 0000000000..1de278d30c
--- /dev/null
+++ b/lib/common_test/doc/src/ct_telnet.xml
@@ -0,0 +1,604 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>ct_telnet</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_telnet.xml</file>
+ </header>
+ <module>ct_telnet</module>
+ <modulesummary>Common Test specific layer on top of Telnet client ct_telnet_client.erl</modulesummary>
+
+ <description>
+
+ <p><c>Common Test</c> specific layer on top of Telnet client
+ <c>ct_telnet_client.erl</c>.</p>
+
+ <p>Use this module to set up Telnet connections, send commands, and
+ perform string matching on the result. For information about how to use
+ <c>ct_telnet</c> and configure connections, specifically for UNIX hosts,
+ see the
+ <seealso marker="unix_telnet"><c>unix_telnet</c></seealso> manual page.
+ </p>
+
+ <p>Default values defined in <c>ct_telnet</c>:</p>
+ <marker id="Default_values"/>
+
+ <list type="bulleted">
+ <item><p>Connection timeout (time to wait for connection) = 10
+ seconds</p></item>
+ <item><p>Command timeout (time to wait for a command to return) =
+ 10 seconds</p></item>
+ <item><p>Max number of reconnection attempts = 3</p></item>
+ <item><p>Reconnection interval (time to wait in between
+ reconnection attempts) = 5 seconds</p></item>
+ <item><p>Keep alive (sends NOP to the server every 8 sec if
+ connection is idle) = <c>true</c></p></item>
+ <item><p>Polling limit (max number of times to poll to get a
+ remaining string terminated) = 0</p></item>
+ <item><p>Polling interval (sleep time between polls) = 1 second</p>
+ </item>
+ <item><p>The TCP_NODELAY option for the telnet socket
+ is disabled (set to <c>false</c>) per default</p></item>
+ </list>
+
+ <p>These parameters can be modified by the user with the following
+ configuration term:</p>
+
+ <pre>
+ {telnet_settings, [{connect_timeout,Millisec},
+ {command_timeout,Millisec},
+ {reconnection_attempts,N},
+ {reconnection_interval,Millisec},
+ {keep_alive,Bool},
+ {poll_limit,N},
+ {poll_interval,Millisec},
+ {tcp_nodelay,Bool}]}.</pre>
+
+ <p><c>Millisec = integer(), N = integer()</c></p>
+
+ <p>Enter the <c>telnet_settings</c> term in a configuration file included
+ in the test and <c>ct_telnet</c> retrieves the information
+ automatically.</p>
+
+ <p><c>keep_alive</c> can be specified per connection, if necessary. For
+ details, see
+ <seealso marker="unix_telnet"><c>unix_telnet</c></seealso>.</p>
+
+ </description>
+
+ <section>
+ <title>Logging</title>
+ <marker id="Logging"/>
+
+ <p>The default logging behavior of <c>ct_telnet</c> is to print information
+ about performed operations, commands, and their corresponding results to
+ the test case HTML log. The following is not printed to the HTML
+ log: text strings sent from the Telnet server that are not explicitly
+ received by a <c>ct_telnet</c> function, such as <c>expect/3</c>.
+ However, <c>ct_telnet</c> can be configured to use a special purpose
+ event handler, implemented in <c>ct_conn_log_h</c>, for logging
+ <em>all</em> Telnet traffic. To use this handler, install a <c>Common
+ Test</c> hook named <c>cth_conn_log</c>. Example (using the test suite
+ information function):</p>
+
+ <pre>
+ suite() -&gt;
+ [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].</pre>
+
+ <p><c>conn_mod()</c> is the name of the <c>Common Test</c> module
+ implementing the connection protocol, that is, <c>ct_telnet</c>.</p>
+
+ <p>The <c>cth_conn_log</c> hook performs unformatted logging of Telnet
+ data to a separate text file. All Telnet communication is captured and
+ printed, including any data sent from the server. The link to
+ this text file is located at the top of the test case HTML log.</p>
+
+ <p>By default, data for all Telnet connections is logged in one common
+ file (named <c>default</c>), which can get messy, for example, if
+ multiple Telnet sessions are running in parallel. Therefore a separate
+ log file can be created for each connection. To configure this, use hook
+ option <c>hosts</c> and list the names of the servers/connections
+ to be used in the suite. The connections must be named for this to
+ work (see
+ <seealso marker="#open-1"><c>ct_telnet:open/1,2,3,4</c></seealso>).</p>
+
+ <p>Hook option <c>log_type</c> can be used to change the
+ <c>cth_conn_log</c> behavior. The default value of this option is
+ <c>raw</c>, which results in the behavior described above. If the value
+ is set to <c>html</c>, all Telnet communication is printed to the test
+ case HTML log instead.</p>
+
+ <p>All <c>cth_conn_log</c> hook options described can also be
+ specified in a configuration file with configuration variable
+ <c>ct_conn_log</c>.</p>
+
+ <p><em>Example:</em></p>
+
+ <pre>
+ {ct_conn_log, [{ct_telnet,[{log_type,raw},
+ {hosts,[key_or_name()]}]}]}</pre>
+
+ <note>
+ <p>Hook options specified in a configuration file overwrite any
+ hard-coded hook options in the test suite.</p>
+ </note>
+
+ <marker id="Logging_example"/>
+ <p><em>Logging Example:</em></p>
+
+ <p>The following <c>ct_hooks</c> statement causes printing of Telnet
+ traffic to separate logs for the connections <c>server1</c> and
+ <c>server2</c>. Traffic for any other connections is logged in the
+ default Telnet log.</p>
+
+ <pre>
+ suite() -&gt;
+ [{ct_hooks,
+ [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].</pre>
+
+ <p>As previously explained, this specification can also be provided by an
+ entry like the following in a configuration file:</p>
+
+ <pre>
+ {ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.</pre>
+
+ <p>In this case the <c>ct_hooks</c> statement in the test suite can look
+ as follows:</p>
+
+ <pre>
+ suite() -&gt;
+ [{ct_hooks, [{cth_conn_log, []}]}].</pre>
+ </section>
+
+ <section>
+ <title>Data Types</title>
+ <marker id="types"/>
+ <taglist>
+ <tag><c>connection() = handle() | {target_name(), connection_type()} | target_name()</c></tag>
+ <item><marker id="type-connection"/>
+ <p>For <c>target_name()</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>connection_type() = telnet | ts1 | ts2</c></tag>
+ <item><marker id="type-connection_type"/> </item>
+
+ <tag><c>handle() = handle()</c></tag>
+ <item><marker id="type-handle"/>
+ <p>Handle for a specific Telnet connection, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p></item>
+
+ <tag><c>prompt_regexp() = string()</c></tag>
+ <item><marker id="type-prompt_regexp"/>
+ <p>Regular expression matching all possible prompts for a specific
+ target type. <c>regexp</c> must not have any groups, that is, when
+ matching, <c>re:run/3</c> (in <c>STDLIB</c>) must return a list with
+ one single element.</p></item>
+ </taglist>
+ </section>
+
+ <funcs>
+ <func>
+ <name>close(Connection) -&gt; ok | {error, Reason}</name>
+ <fsummary>Closes the Telnet connection and stops the process managing
+ it.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="close-1"/>
+ <p>Closes the Telnet connection and stops the process managing it.</p>
+
+ <p>A connection can be associated with a target name and/or a handle.
+ If <c>Connection</c> has no associated target name, it can only
+ be closed with the handle value (see
+ <seealso marker="#open-4"><c>ct_telnet:open/4</c></seealso>).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cmd(Connection, Cmd) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to cmd(Connection, Cmd, []).</fsummary>
+ <desc><marker id="cmd-2"/>
+ <p>Equivalent to
+ <seealso marker="#cmd-3"><c>ct_telnet:cmd(Connection, Cmd,
+ [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cmd(Connection, Cmd, Opts) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Sends a command through Telnet and waits for prompt.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Cmd = string()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {timeout, timeout()} | {newline, boolean()}</v>
+ <v>Data = [string()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="cmd-3"/>
+ <p>Sends a command through Telnet and waits for prompt.</p>
+
+ <p>By default, this function adds a new line to the end of the
+ specified command. If this is not desired, use option
+ <c>{newline,false}</c>. This is necessary, for example, when
+ sending Telnet command sequences prefixed with character
+ Interprete As Command (IAC).</p>
+
+ <p>Option <c>timeout</c> specifies how long the client must wait
+ for prompt. If the time expires, the function returns
+ <c>{error,timeout}</c>. For information about the default value
+ for the command timeout, see the
+ <seealso marker="#Default_values">list of default values</seealso>
+ in the beginning of this module.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cmdf(Connection, CmdFormat, Args) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Equivalent to cmdf(Connection, CmdFormat, Args, []).</fsummary>
+ <desc><marker id="cmdf-3"/>
+ <p>Equivalent to
+ <seealso marker="#cmdf-4"><c>ct_telnet:cmdf(Connection, CmdFormat,
+ Args, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cmdf(Connection, CmdFormat, Args, Opts) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Sends a Telnet command and waits for prompt (uses a format
+ string and a list of arguments to build the command).</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>CmdFormat = string()</v>
+ <v>Args = list()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {timeout, timeout()} | {newline, boolean()}</v>
+ <v>Data = [string()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="cmdf-4"/>
+ <p>Sends a Telnet command and waits for prompt (uses a format string
+ and a list of arguments to build the command).</p>
+
+ <p>For details, see
+ <seealso marker="#cmd-3"><c>ct_telnet:cmd/3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>expect(Connection, Patterns) -&gt; term()</name>
+ <fsummary>Equivalent to expect(Connections, Patterns, []).</fsummary>
+ <desc><marker id="expect-2"/>
+ <p>Equivalent to
+ <seealso marker="#expect-3"><c>ct_telnet:expect(Connections,
+ Patterns, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>expect(Connection, Patterns, Opts) -&gt; {ok, Match} | {ok, MatchList, HaltReason} | {error, Reason}</name>
+ <fsummary>Gets data from Telnet and waits for the expected
+ pattern.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Patterns = Pattern | [Pattern]</v>
+ <v>Pattern = string() | {Tag, string()} | prompt | {prompt, Prompt}</v>
+ <v>Prompt = string()</v>
+ <v>Tag = term()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {idle_timeout, IdleTimeout} | {total_timeout, TotalTimeout} | repeat | {repeat, N} | sequence | {halt, HaltPatterns} | ignore_prompt | no_prompt_check | wait_for_prompt | {wait_for_prompt, Prompt}</v>
+ <v>IdleTimeout = infinity | integer()</v>
+ <v>TotalTimeout = infinity | integer()</v>
+ <v>N = integer()</v>
+ <v>HaltPatterns = Patterns</v>
+ <v>MatchList = [Match]</v>
+ <v>Match = RxMatch | {Tag, RxMatch} | {prompt, Prompt}</v>
+ <v>RxMatch = [string()]</v>
+ <v>HaltReason = done | Match</v>
+ <v>Reason = timeout | {prompt, Prompt}</v>
+ </type>
+ <desc><marker id="expect-3"/>
+ <p>Gets data from Telnet and waits for the expected pattern.</p>
+
+ <p><c>Pattern</c> can be a POSIX regular expression. The function
+ returns when a pattern is successfully matched (at least one, in
+ the case of multiple patterns).</p>
+
+ <p><c>RxMatch</c> is a list of matched strings. It looks as
+ follows <c>[FullMatch, SubMatch1, SubMatch2, ...]</c>, where
+ <c>FullMatch</c> is the string matched by the whole regular
+ expression, and <c>SubMatchN</c> is the string that matched
+ subexpression number <c>N</c>. Subexpressions are denoted with
+ <c>(' ')</c> in the regular expression.</p>
+
+ <p>If a <c>Tag</c> is speciifed, the returned <c>Match</c> also
+ includes the matched <c>Tag</c>. Otherwise, only <c>RxMatch</c>
+ is returned.</p>
+
+ <p><em>Options:</em></p>
+
+ <taglist>
+ <tag><c>idle_timeout</c></tag>
+ <item><p>Indicates that the function must return if the Telnet
+ client is idle (that is, if no data is received) for more than
+ <c>IdleTimeout</c> milliseconds. Default time-out is 10
+ seconds.</p></item>
+ <tag><c>total_timeout</c></tag>
+ <item><p>Sets a time limit for the complete <c>expect</c> operation.
+ After <c>TotalTimeout</c> milliseconds, <c>{error,timeout}</c>
+ is returned. Default is <c>infinity</c> (that is, no time
+ limit).</p></item>
+ <tag><c>ignore_prompt | no_prompt_check</c></tag>
+ <item><p>>The function returns when a prompt is received, even if
+ no pattern has yet been matched, and
+ <c>{error,{prompt,Prompt}}</c> is returned. However, this
+ behavior can be modified with option <c>ignore_prompt</c> or
+ option <c>no_prompt_check</c>, which tells <c>expect</c> to
+ return only when a match is found or after a time-out.</p></item>
+ <tag><c>ignore_prompt</c></tag>
+ <item><p><c>ct_telnet</c> ignores any prompt found. This option is
+ useful if data sent by the server can include a pattern
+ matching prompt <c>regexp</c> (as returned by
+ <c>TargedMod:get_prompt_regexp/0</c>), but is not to not cause
+ the function to return.</p></item>
+ <tag><c>no_prompt_check</c></tag>
+ <item><p><c>ct_telnet</c> does not search for a prompt at all. This
+ is useful if, for example, <c>Pattern</c> itself matches the
+ prompt.</p></item>
+ <tag><c>wait_for_prompt</c></tag>
+ <item><p>Forces <c>ct_telnet</c> to wait until the prompt string
+ is received before returning (even if a pattern has already been
+ matched). This is equal to calling
+ <c>expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts])</c>.
+ Notice that option <c>idle_timeout</c> and <c>total_timeout</c>
+ can abort the operation of waiting for prompt.</p></item>
+ <tag><c>repeat | repeat, N</c></tag>
+ <item><p>The pattern(s) must be matched multiple times. If <c>N</c>
+ is speciified, the pattern(s) are matched <c>N</c> times, and
+ the function returns <c>HaltReason = done</c>. This option can be
+ interrupted by one or more <c>HaltPatterns</c>. <c>MatchList</c>
+ is always returned, that is, a list of <c>Match</c> instead of
+ only one <c>Match</c>. Also <c>HaltReason</c> is returned.</p>
+ </item>
+ <tag><c>sequence</c></tag>
+ <item><p>All patterns must be matched in a sequence. A match is not
+ concluded until all patterns are matched. This option can be
+ interrupted by one or more <c>HaltPatterns</c>. <c>MatchList</c>
+ is always returned, that is, a list of <c>Match</c> instead of
+ only one <c>Match</c>. Also <c>HaltReason</c> is returned.</p>
+ </item>
+ </taglist>
+
+ <p><em>Example 1:</em></p>
+
+ <pre>
+ expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[sequence,{halt,[{nnn,"NNN"}]}])</pre>
+
+ <p>First this tries to match <c>"ABC"</c>, and then <c>"XYZ"</c>, but
+ if <c>"NNN"</c> appears, the function returns
+ <c>{error,{nnn,["NNN"]}}</c>. If both <c>"ABC"</c> and <c>"XYZ"</c>
+ are matched, the function returns <c>{ok,[AbcMatch,XyzMatch]}</c>.</p>
+
+ <p><em>Example 2:</em></p>
+
+ <pre>
+ expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[{repeat,2},{halt,[{nnn,"NNN"}]}])</pre>
+
+ <p>This tries to match <c>"ABC"</c> or <c>"XYZ"</c> twice. If
+ <c>"NNN"</c> appears, the function returns
+ <c>HaltReason = {nnn,["NNN"]}</c>.</p>
+
+ <p>Options <c>repeat</c> and <c>sequence</c> can be combined to
+ match a sequence multiple times.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_data(Connection) -&gt; {ok, Data} | {error, Reason}</name>
+ <fsummary>Gets all data received by the Telnet client since the last
+ command was sent.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Data = [string()]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="get_data-1"/>
+ <p>Gets all data received by the Telnet client since the last
+ command was sent. Only newline-terminated strings are returned.
+ If the last received string has not yet been terminated, the
+ connection can be polled automatically until the string is
+ complete.</p>
+
+ <p>The polling feature is controlled by the configuration values
+ <c>poll_limit</c> and <c>poll_interval</c> and is by default
+ disabled. This means that the function immediately returns all
+ complete strings received and saves a remaining non-terminated
+ string for a later <c>get_data</c> call.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(Name) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Equivalent to open(Name, telnet).</fsummary>
+ <desc><marker id="open-1"/>
+ <p>Equivalent to
+ <seealso marker="#open-2"><c>ct_telnet:open(Name,
+ telnet)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(Name, ConnType) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Opens a Telnet connection to the specified target
+ host.</fsummary>
+ <type>
+ <v>Name = target_name()</v>
+ <v>ConnType = connection_type()</v>
+ <v>Handle = handle()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="open-2"/>
+ <p>Opens a Telnet connection to the specified target host.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(KeyOrName, ConnType, TargetMod) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Equivalent to open(KeyOrName, ConnType, TargetMod, []).</fsummary>
+ <desc><marker id="open-3"/>
+ <p>Equivalent to
+ <seealso marker="#open-4"><c>ct_telnet:ct_telnet:open(KeyOrName,
+ ConnType, TargetMod, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(KeyOrName, ConnType, TargetMod, Extra) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Opens a Telnet connection to the specified target
+ host.</fsummary>
+ <type>
+ <v>KeyOrName = Key | Name</v>
+ <v>Key = atom()</v>
+ <v>Name = target_name()</v>
+ <v>ConnType = connection_type()</v>
+ <v>TargetMod = atom()</v>
+ <v>Extra = term()</v>
+ <v>Handle = handle()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="open-4"/>
+ <p>Opens a Telnet connection to the specified target host.</p>
+
+ <p>The target data must exist in a configuration file. The connection
+ can be associated with <c>Name</c> and/or the returned <c>Handle</c>.
+ To allocate a name for the target, use one of the following
+ alternatives:</p>
+
+ <list type="bulleted">
+ <item><p><seealso marker="ct#require-2"><c>ct:require/2</c></seealso>
+ in a test case</p></item>
+ <item><p>A <c>require</c> statement in the suite information
+ function (<c>suite/0</c>)</p></item>
+ <item><p>A <c>require</c> statement in a test case information
+ function</p></item>
+ </list>
+
+ <p>If you want the connection to be associated with <c>Handle</c> only
+ (if you, for example, need to open multiple connections to a host),
+ use <c>Key</c>, the configuration variable name, to specify the
+ target. Notice that a connection without an associated target name
+ can only be closed with the <c>Handle</c> value.</p>
+
+ <p><c>TargetMod</c> is a module that exports the functions
+ <c>connect(Ip, Port, KeepAlive, Extra)</c> and
+ <c>get_prompt_regexp()</c> for the specified <c>TargetType</c>
+ (for example, <c>unix_telnet</c>).</p>
+
+ <p>For <c>target_name()</c>, see module
+ <seealso marker="ct"><c>ct</c></seealso>.</p>
+
+ <p>See also
+ <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(Connection, Cmd) -&gt; ok | {error, Reason}</name>
+ <fsummary>Equivalent to send(Connection, Cmd, []).</fsummary>
+ <desc><marker id="send-2"/>
+ <p>Equivalent to
+ <seealso marker="#send-3"><c>ct_telnet:send(Connection, Cmd,
+ [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>send(Connection, Cmd, Opts) -&gt; ok | {error, Reason}</name>
+ <fsummary>Sends a Telnet command and returns immediately.</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>Cmd = string()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {newline, boolean()}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="send-3"/>
+ <p>Sends a Telnet command and returns immediately.</p>
+
+ <p>By default, this function adds a newline to the end of the
+ specified command. If this is not desired, option
+ <c>{newline,false}</c> can be used. This is necessary, for example,
+ when sending Telnet command sequences prefixed with character
+ Interprete As Command (IAC).</p>
+
+ <p>The resulting output from the command can be read with
+ <seealso marker="#get_data-1"><c>ct_telnet:get_data/2</c></seealso> or
+ <seealso marker="#expect-2"><c>ct_telnet:expect/2,3</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>sendf(Connection, CmdFormat, Args) -&gt; ok | {error, Reason}</name>
+ <fsummary>Equivalent to sendf(Connection, CmdFormat, Args, []).</fsummary>
+ <desc><marker id="sendf-3"/>
+ <p>Equivalent to
+ <seealso marker="#sendf-4"><c>ct_telnet:sendf(Connection, CmdFormat,
+ Args, [])</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>sendf(Connection, CmdFormat, Args, Opts) -&gt; ok | {error, Reason}</name>
+ <fsummary>Sends a Telnet command and returns immediately (uses a format
+ string and a list of arguments to build the command).</fsummary>
+ <type>
+ <v>Connection = connection()</v>
+ <v>CmdFormat = string()</v>
+ <v>Args = list()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {newline, boolean()}</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="sendf-4"/>
+ <p>Sends a Telnet command and returns immediately (uses a format
+ string and a list of arguments to build the command).</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p><seealso marker="unix_telnet"><c>unix_telnet</c></seealso></p>
+ </section>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/dependencies_chapter.xml b/lib/common_test/doc/src/dependencies_chapter.xml
index e6c7025b12..29c54e819a 100644
--- a/lib/common_test/doc/src/dependencies_chapter.xml
+++ b/lib/common_test/doc/src/dependencies_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,217 +33,220 @@
<section>
<title>General</title>
<p>When creating test suites, it is strongly recommended to not
- create dependencies between test cases, i.e. letting test cases
+ create dependencies between test cases, that is, letting test cases
depend on the result of previous test cases. There are various
- reasons for this, for example:</p>
+ reasons for this, such as, the following:</p>
- <list>
+ <list type="bulleted">
<item>It makes it impossible to run test cases individually.</item>
- <item>It makes it impossible to run test cases in different order.</item>
- <item>It makes debugging very difficult (since a fault could be
+ <item>It makes it impossible to run test cases in a different order.</item>
+ <item>It makes debugging difficult (as a fault can be
the result of a problem in a different test case than the one failing).</item>
- <item>There exists no good and explicit ways to declare dependencies, so
- it may be very difficult to see and understand these in test suite
+ <item>There are no good and explicit ways to declare dependencies, so
+ it can be difficult to see and understand these in test suite
code and in test logs.</item>
- <item>Extending, restructuring and maintaining test suites with
+ <item>Extending, restructuring, and maintaining test suites with
test case dependencies is difficult.</item>
</list>
<p>There are often sufficient means to work around the need for test
case dependencies. Generally, the problem is related to the state of
- the system under test (SUT). The action of one test case may alter the state
- of the system and for some other test case to run properly, the new state
+ the System Under Test (SUT). The action of one test case can change the
+ system state. For some other test case to run properly, this new state
must be known.</p>
<p>Instead of passing data between test cases, it is recommended
that the test cases read the state from the SUT and perform assertions
- (i.e. let the test case run if the state is as expected, otherwise reset or fail)
- and/or use the state to set variables necessary for the test case to execute
- properly. Common actions can often be implemented as library functions for
- test cases to call to set the SUT in a required state. (Such common actions
- may of course also be separately tested if necessary, to ensure they are
- working as expected). It is sometimes also possible, but not always desirable,
- to group tests together in one test case, i.e. let a test case perform a
- "scenario" test (a test that consists of subtests).</p>
-
- <p>Consider for example a server application under test. The following
+ (that is, let the test case run if the state is as expected, otherwise reset or fail).
+ It is also recommended to use the state to set variables necessary for the
+ test case to execute properly. Common actions can often be implemented as
+ library functions for test cases to call to set the SUT in a required state.
+ (Such common actions can also be separately tested, if necessary,
+ to ensure that they work as expected). It is sometimes also possible,
+ but not always desirable, to group tests together in one test case, that is,
+ let a test case perform a "scenario" test (a test consisting of subtests).</p>
+
+ <p>Consider, for example, a server application under test. The following
functionality is to be tested:</p>
- <list>
- <item>Starting the server.</item>
- <item>Configuring the server.</item>
- <item>Connecting a client to the server.</item>
- <item>Disconnecting a client from the server.</item>
- <item>Stopping the server.</item>
+ <list type="bulleted">
+ <item>Starting the server</item>
+ <item>Configuring the server</item>
+ <item>Connecting a client to the server</item>
+ <item>Disconnecting a client from the server</item>
+ <item>Stopping the server</item>
</list>
- <p>There are obvious dependencies between the listed functions. We can't configure
- the server if it hasn't first been started, we can't connect a client until
- the server has been properly configured, etc. If we want to have one test
- case for each of the functions, we might be tempted to try to always run the
+ <p>There are obvious dependencies between the listed functions. The server cannot
+ be configured if it has not first been started, a client connot be connectd until
+ the server is properly configured, and so on. If we want to have one test
+ case for each function, we might be tempted to try to always run the
test cases in the stated order and carry possible data (identities, handles,
- etc) between the cases and therefore introduce dependencies between them.
- To avoid this we could consider starting and stopping the server for every test.
- We would implement the start and stop action as common functions that may be
- called from init_per_testcase and end_per_testcase. (We would of course test
- the start and stop functionality separately). The configuration could perhaps also
- be implemented as a common function, maybe grouped with the start function.
- Finally the testing of connecting and disconnecting a client may be grouped into
- one test case. The resulting suite would look something like this:</p>
-
+ and so on) between the cases and therefore introduce dependencies between them.</p>
+
+ <p>To avoid this, we can consider starting and stopping the server for every test.
+ We can thus implement the start and stop action as common functions to be
+ called from
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso> and
+ <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>.
+ (Remember to test the start and stop functionality separately.)
+ The configuration can also be implemented as a common function, maybe grouped
+ with the start function. Finally, the testing of connecting and disconnecting a
+ client can be grouped into one test case. The resulting suite can look as
+ follows:</p>
<pre>
- -module(my_server_SUITE).
- -compile(export_all).
- -include_lib("ct.hrl").
+ -module(my_server_SUITE).
+ -compile(export_all).
+ -include_lib("ct.hrl").
+
+ %%% init and end functions...
- %%% init and end functions...
+ suite() -> [{require,my_server_cfg}].
- suite() -> [{require,my_server_cfg}].
+ init_per_testcase(start_and_stop, Config) ->
+ Config;
- init_per_testcase(start_and_stop, Config) ->
- Config;
+ init_per_testcase(config, Config) ->
+ [{server_pid,start_server()} | Config];
- init_per_testcase(config, Config) ->
- [{server_pid,start_server()} | Config];
+ init_per_testcase(_, Config) ->
+ ServerPid = start_server(),
+ configure_server(),
+ [{server_pid,ServerPid} | Config].
- init_per_testcase(_, Config) ->
- ServerPid = start_server(),
- configure_server(),
- [{server_pid,ServerPid} | Config].
+ end_per_testcase(start_and_stop, _) ->
+ ok;
- end_per_testcase(start_and_stop, _) ->
- ok;
+ end_per_testcase(_, _) ->
+ ServerPid = ?config(server_pid),
+ stop_server(ServerPid).
- end_per_testcase(_, _) ->
- ServerPid = ?config(server_pid),
- stop_server(ServerPid).
+ %%% test cases...
- %%% test cases...
+ all() -> [start_and_stop, config, connect_and_disconnect].
- all() -> [start_and_stop, config, connect_and_disconnect].
+ %% test that starting and stopping works
+ start_and_stop(_) ->
+ ServerPid = start_server(),
+ stop_server(ServerPid).
- %% test that starting and stopping works
- start_and_stop(_) ->
- ServerPid = start_server(),
- stop_server(ServerPid).
+ %% configuration test
+ config(Config) ->
+ ServerPid = ?config(server_pid, Config),
+ configure_server(ServerPid).
- %% configuration test
- config(Config) ->
- ServerPid = ?config(server_pid, Config),
- configure_server(ServerPid).
+ %% test connecting and disconnecting client
+ connect_and_disconnect(Config) ->
+ ServerPid = ?config(server_pid, Config),
+ {ok,SessionId} = my_server:connect(ServerPid),
+ ok = my_server:disconnect(ServerPid, SessionId).
- %% test connecting and disconnecting client
- connect_and_disconnect(Config) ->
- ServerPid = ?config(server_pid, Config),
- {ok,SessionId} = my_server:connect(ServerPid),
- ok = my_server:disconnect(ServerPid, SessionId).
+ %%% common functions...
- %%% common functions...
+ start_server() ->
+ {ok,ServerPid} = my_server:start(),
+ ServerPid.
- start_server() ->
- {ok,ServerPid} = my_server:start(),
- ServerPid.
+ stop_server(ServerPid) ->
+ ok = my_server:stop(),
+ ok.
- stop_server(ServerPid) ->
- ok = my_server:stop(),
- ok.
+ configure_server(ServerPid) ->
+ ServerCfgData = ct:get_config(my_server_cfg),
+ ok = my_server:configure(ServerPid, ServerCfgData),
+ ok.</pre>
- configure_server(ServerPid) ->
- ServerCfgData = ct:get_config(my_server_cfg),
- ok = my_server:configure(ServerPid, ServerCfgData),
- ok.
- </pre>
</section>
<section>
<marker id="save_config"></marker>
- <title>Saving configuration data</title>
+ <title>Saving Configuration Data</title>
- <p>There might be situations where it is impossible, or infeasible at least, to
- implement independent test cases. Maybe it is simply not possible to read the
- SUT state. Maybe resetting the SUT is impossible and it takes much too long
+ <p>Sometimes it is impossible, or infeasible, to
+ implement independent test cases. Maybe it is not possible to read the
+ SUT state. Maybe resetting the SUT is impossible and it takes too long time
to restart the system. In situations where test case dependency is necessary,
CT offers a structured way to carry data from one test case to the next. The
- same mechanism may also be used to carry data from one test suite to the next.</p>
+ same mechanism can also be used to carry data from one test suite to the next.</p>
<p>The mechanism for passing data is called <c>save_config</c>. The idea is that
- one test case (or suite) may save the current value of Config - or any list of
- key-value tuples - so that it can be read by the next executing test case
- (or test suite). The configuration data is not saved permanently but can only
- be passed from one case (or suite) to the next.</p>
+ one test case (or suite) can save the current value of <c>Config</c>, or any list of
+ key-value tuples, so that the next executing test case (or test suite) can read it.
+ The configuration data is not saved permanently but can only be passed from one
+ case (or suite) to the next.</p>
- <p>To save <c>Config</c> data, return the tuple:</p>
+ <p>To save <c>Config</c> data, return tuple <c>{save_config,ConfigList}</c>
+ from <c>end_per_testcase</c> or from the main test case function.</p>
- <p><c>{save_config,ConfigList}</c></p>
-
- <p>from <c>end_per_testcase</c> or from the main test case function. To read data
- saved by a previous test case, use the <c>config</c> macro with a
- <c>saved_config</c> key:</p>
+ <p>To read data saved by a previous test case, use macro <c>config</c> with a
+ <c>saved_config</c> key as follows:</p>
<p><c>{Saver,ConfigList} = ?config(saved_config, Config)</c></p>
<p><c>Saver</c> (<c>atom()</c>) is the name of the previous test case (where the
- data was saved). The <c>config</c> macro may be used to extract particular data
+ data was saved). The <c>config</c> macro can be used to extract particular data
also from the recalled <c>ConfigList</c>. It is strongly recommended that
<c>Saver</c> is always matched to the expected name of the saving test case.
- This way problems due to restructuring of the test suite may be avoided. Also it
- makes the dependency more explicit and the test suite easier to read and maintain.</p>
+ This way, problems because of restructuring of the test suite can be avoided.
+ Also, it makes the dependency more explicit and the test suite easier to read
+ and maintain.</p>
<p>To pass data from one test suite to another, the same mechanism is used. The data
- should be saved by the <c>end_per_suite</c> function and read by <c>init_per_suite</c>
+ is to be saved by finction
+ <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso>
+ and read by function
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>
in the suite that follows. When passing data between suites, <c>Saver</c> carries the
name of the test suite.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
- -module(server_b_SUITE).
- -compile(export_all).
- -include_lib("ct.hrl").
-
- %%% init and end functions...
-
- init_per_suite(Config) ->
- %% read config saved by previous test suite
- {server_a_SUITE,OldConfig} = ?config(saved_config, Config),
- %% extract server identity (comes from server_a_SUITE)
- ServerId = ?config(server_id, OldConfig),
- SessionId = connect_to_server(ServerId),
- [{ids,{ServerId,SessionId}} | Config].
-
- end_per_suite(Config) ->
- %% save config for server_c_SUITE (session_id and server_id)
- {save_config,Config}
-
- %%% test cases...
-
- all() -> [allocate, deallocate].
-
- allocate(Config) ->
- {ServerId,SessionId} = ?config(ids, Config),
- {ok,Handle} = allocate_resource(ServerId, SessionId),
- %% save handle for deallocation test
- NewConfig = [{handle,Handle}],
- {save_config,NewConfig}.
-
- deallocate(Config) ->
- {ServerId,SessionId} = ?config(ids, Config),
- {allocate,OldConfig} = ?config(saved_config, Config),
- Handle = ?config(handle, OldConfig),
- ok = deallocate_resource(ServerId, SessionId, Handle).
- </pre>
-
- <p>It is also possible to save <c>Config</c> data from a test case that is to be
- skipped. To accomplish this, return the following tuple:</p>
-
- <p><c>{skip_and_save,Reason,ConfigList}</c></p>
-
- <p>The result will be that the test case is skipped with <c>Reason</c> printed to
- the log file (as described in previous chapters), and <c>ConfigList</c> is saved
- for the next test case. <c>ConfigList</c> may be read by means of
- <c>?config(saved_config, Config)</c>, as described above. <c>skip_and_save</c>
- may also be returned from <c>init_per_suite</c>, in which case the saved data can
+ -module(server_b_SUITE).
+ -compile(export_all).
+ -include_lib("ct.hrl").
+
+ %%% init and end functions...
+
+ init_per_suite(Config) ->
+ %% read config saved by previous test suite
+ {server_a_SUITE,OldConfig} = ?config(saved_config, Config),
+ %% extract server identity (comes from server_a_SUITE)
+ ServerId = ?config(server_id, OldConfig),
+ SessionId = connect_to_server(ServerId),
+ [{ids,{ServerId,SessionId}} | Config].
+
+ end_per_suite(Config) ->
+ %% save config for server_c_SUITE (session_id and server_id)
+ {save_config,Config}
+
+ %%% test cases...
+
+ all() -> [allocate, deallocate].
+
+ allocate(Config) ->
+ {ServerId,SessionId} = ?config(ids, Config),
+ {ok,Handle} = allocate_resource(ServerId, SessionId),
+ %% save handle for deallocation test
+ NewConfig = [{handle,Handle}],
+ {save_config,NewConfig}.
+
+ deallocate(Config) ->
+ {ServerId,SessionId} = ?config(ids, Config),
+ {allocate,OldConfig} = ?config(saved_config, Config),
+ Handle = ?config(handle, OldConfig),
+ ok = deallocate_resource(ServerId, SessionId, Handle).</pre>
+
+ <p>To save <c>Config</c> data from a test case that is to be
+ skipped, return tuple
+ <c>{skip_and_save,Reason,ConfigList}</c>.</p>
+
+ <p>The result is that the test case is skipped with <c>Reason</c> printed to
+ the log file (as described earlier) and <c>ConfigList</c> is saved
+ for the next test case. <c>ConfigList</c> can be read using
+ <c>?config(saved_config, Config)</c>, as described earlier. <c>skip_and_save</c>
+ can also be returned from <c>init_per_suite</c>. In this case, the saved data can
be read by <c>init_per_suite</c> in the suite that follows.</p>
</section>
@@ -250,60 +254,63 @@
<marker id="sequences"></marker>
<title>Sequences</title>
- <p>It is possible that test cases depend on each other so that
- if one case fails, the following test(s) should not be executed.
+ <p>Sometimes test cases depend on each other so that
+ if one case fails, the following tests are not to be executed.
Typically, if the <c>save_config</c> facility is used and a test
case that is expected to save data crashes, the following
- case can not run. CT offers a way to declare such dependencies,
+ case cannot run. <c>Common Test</c> offers a way to declare such dependencies,
called sequences.</p>
<p>A sequence of test cases is defined as a test case group
- with a <c>sequence</c> property. Test case groups are defined by
- means of the <c>groups/0</c> function in the test suite (see the
- <seealso marker="write_test_chapter#test_case_groups">Test case groups</seealso>
- chapter for details).</p>
-
- <p>For example, if we would like to make sure that if <c>allocate</c>
- in <c>server_b_SUITE</c> (above) crashes, <c>deallocate</c> is skipped,
- we may define a sequence like this:</p>
+ with a <c>sequence</c> property. Test case groups are defined
+ through function <c>groups/0</c> in the test suite (for details, see section
+ <seealso marker="write_test_chapter#test_case_groups">Test Case Groups</seealso>.</p>
+
+ <p>For example, to ensure that if <c>allocate</c>
+ in <c>server_b_SUITE</c> crashes, <c>deallocate</c> is skipped,
+ the following sequence can be defined:</p>
<pre>
- groups() -> [{alloc_and_dealloc, [sequence], [alloc,dealloc]}].</pre>
+ groups() -> [{alloc_and_dealloc, [sequence], [alloc,dealloc]}].</pre>
- <p>Let's also assume the suite contains the test case <c>get_resource_status</c>,
- which is independent of the other two cases, then the <c>all</c> function could
- look like this:</p>
+ <p>Assume that the suite contains the test case <c>get_resource_status</c>
+ that is independent of the other two cases, then function <c>all</c> can
+ look as follows:</p>
<pre>
- all() -> [{group,alloc_and_dealloc}, get_resource_status].</pre>
+ all() -> [{group,alloc_and_dealloc}, get_resource_status].</pre>
<p>If <c>alloc</c> succeeds, <c>dealloc</c> is also executed. If <c>alloc</c> fails
- however, <c>dealloc</c> is not executed but marked as SKIPPED in the html log.
- <c>get_resource_status</c> will run no matter what happens to the <c>alloc_and_dealloc</c>
+ however, <c>dealloc</c> is not executed but marked as <c>SKIPPED</c> in the HTML log.
+ <c>get_resource_status</c> runs no matter what happens to the <c>alloc_and_dealloc</c>
cases.</p>
- <p>Test cases in a sequence will be executed in order until they have all succeeded or
- until one case fails. If one fails, all following cases in the sequence are skipped.
- The cases in the sequence that have succeeded up to that point are reported as successful
- in the log. An arbitrary number of sequences may be specified. Example:</p>
+ <p>Test cases in a sequence are executed in order until all succeed or
+ one fails. If one fails, all following cases in the sequence are skipped.
+ The cases in the sequence that have succeeded up to that point are reported as
+ successful in the log. Any number of sequences can be specified.</p>
+ <p><em>Example:</em></p>
<pre>
- groups() -> [{scenarioA, [sequence], [testA1, testA2]},
- {scenarioB, [sequence], [testB1, testB2, testB3]}].
-
- all() -> [test1,
- test2,
- {group,scenarioA},
- test3,
- {group,scenarioB},
- test4].</pre>
-
- <p>It is possible to have sub-groups in a sequence group. Such sub-groups can have
- any property, i.e. they are not required to also be sequences. If you want the status
- of the sub-group to affect the sequence on the level above, return
- <c>{return_group_result,Status}</c> from <c>end_per_group/2</c>, as described in the
- <seealso marker="write_test_chapter#repeated_groups">Repeated groups</seealso>
- chapter. A failed sub-group (<c>Status == failed</c>) will cause the execution of a
+ groups() -> [{scenarioA, [sequence], [testA1, testA2]},
+ {scenarioB, [sequence], [testB1, testB2, testB3]}].
+
+ all() -> [test1,
+ test2,
+ {group,scenarioA},
+ test3,
+ {group,scenarioB},
+ test4].</pre>
+
+ <p>A sequence group can have subgroups. Such subgroups can have
+ any property, that is, they are not required to also be sequences. If you want the
+ status of the subgroup to affect the sequence on the level above, return
+ <c>{return_group_result,Status}</c> from
+ <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group/2</c></seealso>,
+ as described in section
+ <seealso marker="write_test_chapter#repeated_groups">Repeated Groups</seealso>
+ in Writing Test Suites.
+ A failed subgroup (<c>Status == failed</c>) causes the execution of a
sequence to fail in the same way a test case does.</p>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/event_handler_chapter.xml b/lib/common_test/doc/src/event_handler_chapter.xml
index f39f391818..31128a7114 100644
--- a/lib/common_test/doc/src/event_handler_chapter.xml
+++ b/lib/common_test/doc/src/event_handler_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,144 +33,171 @@
<section>
<marker id="event_handling"></marker>
<title>General</title>
- <p>It is possible for the operator of a Common Test system to receive
- event notifications continously during a test run. It is reported e.g.
- when a test case starts and stops, what the current count of successful,
- failed and skipped cases is, etc. This information can be used for
- different purposes such as logging progress and results on
- other format than HTML, saving statistics to a database for report
- generation and test system supervision.</p>
-
- <p>Common Test has a framework for event handling which is based on
- the OTP event manager concept and gen_event behaviour. When the Common Test
- server starts, it spawns an event manager. During test execution the
- manager gets a notification from the server every time something
- of potential interest happens. Any event handler plugged into the
- event manager can match on events of interest, take action, or maybe
- simply pass the information on. Event handlers are Erlang modules
- implemented by the Common Test user according to the gen_event
- behaviour (see the OTP User's Guide and Reference Manual for more
- information).</p>
-
- <p>As already described, a Common Test server always starts an event manager.
- The server also plugs in a default event handler which has as its only
- purpose to relay notifications to a globally registered CT Master
- event manager (if a CT Master server is running in the system).
- The CT Master also spawns an event manager at startup.
- Event handlers plugged into this manager will receive the events from
- all the test nodes as well as information from the CT Master server
- itself.</p>
-
- <p>User specific event handlers may be plugged into a Common Test event
- manager, either by telling Common Test to install them before the test
- run (see below), or by adding the handlers dynamically during the test
- run by means of
- <c>gen_event:add_handler/3</c> or <c>gen_event:add_sup_handler/3</c>.
- In the latter scenario, the reference of the Common Test event manager is
- required. To get it, call <c>ct:get_event_mgr_ref/0</c> or (on the CT
- Master node) <c>ct_master:get_event_mgr_ref/0</c>.</p>
+ <p>The operator of a <c>Common Test</c> system can receive
+ event notifications continuously during a test run. For example,
+ <c>Common Test</c> reports when a test case starts and stops,
+ the current count of successful, failed, and skipped cases, and so on.
+ This information can be used for different purposes such as logging progress
+ and results in another format than HTML, saving statistics to a database
+ for report generation, and test system supervision.</p>
+
+ <p><c>Common Test</c> has a framework for event handling based on
+ the OTP event manager concept and <c>gen_event</c> behavior.
+ When the <c>Common Test</c> server starts, it spawns an event manager.
+ During test execution the manager gets a notification from the server
+ when something of potential interest happens. Any event handler plugged into
+ the event manager can match on events of interest, take action, or
+ pass the information on. The event handlers are Erlang modules
+ implemented by the <c>Common Test</c> user according to the <c>gen_event</c>
+ behavior (for details, see module
+ <seealso marker="stdlib:gen_event"><c>stdlib:gen_event</c></seealso> and
+ section
+ <seealso marker="doc/design_principles:events"><c>gen_event Behaviour</c></seealso>
+ in OTP Design Principles in the System Documentation).
+ </p>
+
+ <p>A <c>Common Test</c> server always starts an event manager.
+ The server also plugs in a default event handler, which only
+ purpose is to relay notifications to a globally registered <c>Common Test</c>
+ Master event manager (if a <c>Common Test</c> Master server is running in the system).
+ The <c>Common Test</c> Master also spawns an event manager at startup.
+ Event handlers plugged into this manager receives the events from
+ all the test nodes, plus information from the <c>Common Test</c> Master server.
+ </p>
+
+ <p>User-specific event handlers can be plugged into a <c>Common Test</c> event
+ manager, either by telling <c>Common Test</c> to install them before the test
+ run (described later), or by adding the handlers dynamically during the test
+ run using
+ <seealso marker="stdlib:gen_event#add_handler-3"><c>stdlib:gen_event:add_handler/3</c></seealso> or
+ <seealso marker="stdlib:gen_event#add_sup_handler-3"><c>stdlib:gen_event:add_sup_handler/3</c></seealso>.
+ In the latter scenario, the reference of the <c>Common Test</c> event manager is
+ required. To get it, call
+ <seealso marker="ct#get_event_mgr_ref-0"><c>ct:get_event_mgr_ref/0</c></seealso>
+ or (on the <c>Common Test</c> Master node)
+ <seealso marker="ct_master#get_event_mgr_ref-0"><c>ct_master:get_event_mgr_ref/0</c></seealso>.</p>
</section>
<section>
<marker id="usage"></marker>
- <title>Usage</title>
- <p>Event handlers may be installed by means of an <c>event_handler</c>
- start flag (<c>ct_run</c>) or option (<seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>), where the
- argument specifies the names of one or more event handler modules.
- Example:</p>
+ <title>Use</title>
+ <p>Event handlers can be installed by an <c>event_handler</c> start flag
+ (<seealso marker="ct_run"><c>ct_run</c></seealso>) or option
+ <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, where the
+ argument specifies the names of one or more event handler modules.</p>
+
+ <p><em>Example:</em></p>
<p><c>$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1
handlers/my_evh2 -pa $PWD/handlers</c></p>
- <p>Use the <c><![CDATA[ct_run -event_handler_init]]></c> option instead of
- <c><![CDATA[-event_handler]]></c> to pass start arguments to the event handler
- init function.</p>
- <p>All event handler modules must have gen_event behaviour. Note also that
- these modules must be precompiled, and that their locations must be
- added explicitly to the Erlang code server search path (like in the
- example).</p>
- <p>An event_handler tuple in the argument <c>Opts</c> has the following
- definition (see also <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> in the reference manual):</p>
+ <p>To pass start arguments to the event handler init function, use option
+ <c><![CDATA[ct_run -event_handler_init]]></c> instead of
+ <c><![CDATA[-event_handler]]></c>.</p>
+
+ <note><p>All event handler modules must have <c>gen_event</c> behavior.
+ These modules must be precompiled and their locations must be
+ added explicitly to the Erlang code server search path (as in the previous
+ example).</p></note>
+
+ <p>An event_handler tuple in argument <c>Opts</c> has the following definition
+ (see <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>):</p>
<pre>
- {event_handler,EventHandlers}
+ {event_handler,EventHandlers}
- EventHandlers = EH | [EH]
- EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs}
- InitArgs = [term()]</pre>
+ EventHandlers = EH | [EH]
+ EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs}
+ InitArgs = [term()]</pre>
- <p>Example:</p>
+ <p>In the following example, two event handlers for the <c>my_SUITE</c> test are installed:</p>
<pre>
- 1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).</pre>
- <p>This will install two event handlers for the <c>my_SUITE</c> test. Event handler
- <c>my_evh1</c> is started with <c>[]</c> as argument to the init function. Event handler
- <c>my_evh2</c> is started with the name of the current node in the init argument list.</p>
+ 1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).</pre>
+ <p>Event handler <c>my_evh1</c> is started with <c>[]</c> as argument to the init function.
+ Event handler <c>my_evh2</c> is started with the name of the current node in the init argument list.</p>
- <p>Event handlers can also be plugged in by means of
+ <p>Event handlers can also be plugged in using one of the following
<seealso marker="run_test_chapter#test_specifications">test specification</seealso>
terms:</p>
-
- <p><c>{event_handler, EventHandlers}</c>, or</p>
- <p><c>{event_handler, EventHandlers, InitArgs}</c>, or</p>
- <p><c>{event_handler, NodeRefs, EventHandlers}</c>, or</p>
- <p><c>{event_handler, NodeRefs, EventHandlers, InitArgs}</c></p>
+ <list type="bulleted">
+ <item><c>{event_handler, EventHandlers}</c></item>
+ <item><c>{event_handler, EventHandlers, InitArgs}</c></item>
+ <item><c>{event_handler, NodeRefs, EventHandlers}</c></item>
+ <item><c>{event_handler, NodeRefs, EventHandlers, InitArgs}</c></item>
+ </list>
<p><c>EventHandlers</c> is a list of module names. Before a test
session starts, the init function of each plugged in event handler
- is called (with the InitArgs list as argument or [] if
- no start arguments are given).</p>
+ is called (with the <c>InitArgs</c> list as argument or <c>[]</c> if
+ no start arguments are specified).</p>
- <p>To plug a handler into the CT Master event manager, specify
+ <p>To plug in a handler to the <c>Common Test</c> Master event manager, specify
<c>master</c> as the node in <c>NodeRefs</c>.</p>
- <p>For an event handler to be able to match on events, the module must
+ <p>To be able to match on events, the event handler module must
include the header file <c>ct_event.hrl</c>. An event is a record with the
following definition:</p>
<p><c>#event{name, node, data}</c></p>
- <p><c>name</c> is the label (type) of the event. <c>node</c> is the name of the
- node the event has originated from (only relevant for CT Master event handlers).
- <c>data</c> is specific for the particular event.</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item><p>Label (type) of the event.</p></item>
+ <tag><c>node</c></tag>
+ <item><p>Name of the node that the event originated from
+ (only relevant for <c>Common Test</c> Master event handlers).</p></item>
+ <tag><c>data</c></tag>
+ <item><p>Specific for the event.</p></item>
+ </taglist>
+
<marker id="events"></marker>
- <p><em>General events:</em></p>
+ <section>
+ <title>General Events</title>
- <list>
- <item><c>#event{name = start_logging, data = LogDir}</c>
- <p><c>LogDir = string()</c>, top level log directory for the test run.</p>
- <p>Indicates that the logging process of Common Test
- has started successfully and is ready to receive IO
+ <p>The general events are as follows:</p>
+
+ <taglist>
+ <tag><c>#event{name = start_logging, data = LogDir}</c></tag>
+ <item>
+ <p><c>LogDir = string()</c>, top-level log directory for the test run.</p>
+ <p>This event indicates that the logging process of <c>Common Test</c>
+ has started successfully and is ready to receive I/O
messages.</p></item>
- <item><c>#event{name = stop_logging, data = []}</c>
- <p>Indicates that the logging process of Common Test
- has been shut down at the end of the test run.
+ <tag><c>#event{name = stop_logging, data = []}</c></tag>
+ <item>
+ <p>This event indicates that the logging process of <c>Common Test</c>
+ was shut down at the end of the test run.
</p></item>
- <item><c>#event{name = test_start, data = {StartTime,LogDir}}</c>
+ <tag><c>#event{name = test_start, data = {StartTime,LogDir}}</c></tag>
+ <item>
<p><c>StartTime = {date(),time()}</c>, test run start date and time.</p>
- <p><c>LogDir = string()</c>, top level log directory for the test run.</p>
- <p>This event indicates that Common Test has finished initial preparations
- and will begin executing test cases.
+ <p><c>LogDir = string()</c>, top-level log directory for the test run.</p>
+ <p>This event indicates that <c>Common Test</c> has finished initial preparations
+ and begins executing test cases.
</p></item>
- <item><c>#event{name = test_done, data = EndTime}</c>
+ <tag><c>#event{name = test_done, data = EndTime}</c></tag>
+ <item>
<p><c>EndTime = {date(),time()}</c>, date and time the test run finished.</p>
- <p>This indicates that the last test case has been executed and
- Common Test is shutting down.
+ <p>This event indicates that the last test case has been executed and
+ <c>Common Test</c> is shutting down.
</p></item>
- <item><c>#event{name = start_info, data = {Tests,Suites,Cases}}</c>
- <p><c>Tests = integer()</c>, the number of tests.</p>
- <p><c>Suites = integer()</c>, the total number of suites.</p>
- <p><c>Cases = integer() | unknown</c>, the total number of test cases.</p>
- <p>Initial test run information that can be interpreted as: "This test
- run will execute <c>Tests</c> separate tests, in total containing
+ <tag><c>#event{name = start_info, data = {Tests,Suites,Cases}}</c></tag>
+ <item>
+ <p><c>Tests = integer()</c>, number of tests.</p>
+ <p><c>Suites = integer()</c>, total number of suites.</p>
+ <p><c>Cases = integer() | unknown</c>, total number of test cases.</p>
+ <p>This event gives initial test run information that can be interpreted as:
+ "This test run will execute <c>Tests</c> separate tests, in total containing
<c>Cases</c> number of test cases, in <c>Suites</c> number of suites".
- Note that if a test case group with a repeat property exists in any test,
- the total number of test cases can not be calculated (unknown).
+ However, if a test case group with a repeat property exists in any test,
+ the total number of test cases cannot be calculated (unknown).
</p></item>
- <item><c>#event{name = tc_start, data = {Suite,FuncOrGroup}}</c>
+ <tag><c>#event{name = tc_start, data = {Suite,FuncOrGroup}}</c></tag>
+ <item>
<p><c>Suite = atom()</c>, name of the test suite.</p>
<p><c>FuncOrGroup = Func | {Conf,GroupName,GroupProperties}</c></p>
<p><c>Func = atom()</c>, name of test case or configuration function.</p>
@@ -179,22 +207,24 @@
<p>This event informs about the start of a test case, or a group configuration
function. The event is sent also for <c>init_per_suite</c> and <c>end_per_suite</c>,
but not for <c>init_per_testcase</c> and <c>end_per_testcase</c>. If a group
- configuration function is starting, the group name and execution properties
- are also given.
+ configuration function starts, the group name and execution properties
+ are also specified.
</p></item>
- <item><c>#event{name = tc_logfile, data = {{Suite,Func},LogFileName}}</c>
+ <tag><c>#event{name = tc_logfile, data = {{Suite,Func},LogFileName}}</c></tag>
+ <item>
<p><c>Suite = atom()</c>, name of the test suite.</p>
<p><c>Func = atom()</c>, name of test case or configuration function.</p>
- <p><c>LogFileName = string()</c>, full name of test case log file.</p>
+ <p><c>LogFileName = string()</c>, full name of the test case log file.</p>
<p>This event is sent at the start of each test case (and configuration function
except <c>init/end_per_testcase</c>) and carries information about the
- full name (i.e. the file name including the absolute directory path) of
+ full name (that is, the file name including the absolute directory path) of
the current test case log file.
</p></item>
- <marker id="tc_done"/>
- <item><c>#event{name = tc_done, data = {Suite,FuncOrGroup,Result}}</c>
+ <tag><c>#event{name = tc_done, data = {Suite,FuncOrGroup,Result}}</c></tag>
+ <item>
+ <marker id="tc_done"/>
<p><c>Suite = atom()</c>, name of the suite.</p>
<p><c>FuncOrGroup = Func | {Conf,GroupName,GroupProperties}</c></p>
<p><c>Func = atom()</c>, name of test case or configuration function.</p>
@@ -209,34 +239,37 @@
{require_failed_in_suite0,RequireInfo} |
{failed,{Suite,init_per_testcase,FailInfo}} |
UserTerm</c>,
- the reason why the case has been skipped.</p>
+ why the case was skipped.</p>
<marker id="failreason"/>
<p><c>FailReason = {error,FailInfo} |
{error,{RunTimeError,StackTrace}} |
{timetrap_timeout,integer()} |
{failed,{Suite,end_per_testcase,FailInfo}}</c>, reason for failure.</p>
- <p><c>RequireInfo = {not_available,atom() | tuple()}</c>, why require has failed.</p>
+ <p><c>RequireInfo = {not_available,atom() | tuple()}</c>, why require failed.</p>
<p><c>FailInfo = {timetrap_timeout,integer()} |
{RunTimeError,StackTrace} |
UserTerm</c>,
- detailed information about an error.</p>
- <p><c>RunTimeError = term()</c>, a run-time error, e.g. badmatch, undef, etc.</p>
- <p><c>StackTrace = list()</c>, list of function calls preceeding a run-time error.</p>
- <p><c>UserTerm = term()</c>, arbitrary data specified by user, or <c>exit/1</c> info.</p>
- <p>This event informs about the end of a test case or a configuration function (see the
- <c>tc_start</c> event for details on the FuncOrGroup element). With this event comes the
- final result of the function in question. It is possible to determine on the top level
- of <c>Result</c> if the function was successful, skipped (by the user), or if it failed.
- It is of course possible to dig deeper and also perform pattern matching on the various
- reasons for skipped or failed. Note that <c>{'EXIT',Reason}</c> tuples have been translated into
- <c>{error,Reason}</c>. Note also that if a <c>{failed,{Suite,end_per_testcase,FailInfo}</c>
- result is received, it actually means the test case was successful, but that
+ error details.</p>
+ <p><c>RunTimeError = term()</c>, a runtime error, for example,
+ <c>badmatch</c> or <c>undef</c>.</p>
+ <p><c>StackTrace = list()</c>, list of function calls preceding a runtime error.</p>
+ <p><c>UserTerm = term()</c>, any data specified by user, or <c>exit/1</c> information.</p>
+ <p>This event informs about the end of a test case or a configuration function (see event
+ <c>tc_start</c> for details on element <c>FuncOrGroup</c>). With this event
+ comes the final result of the function in question. It is possible to determine on the
+ top level of <c>Result</c> if the function was successful, skipped (by the user),
+ or if it failed.</p>
+ <p>It is also possible to dig deeper and, for example, perform pattern matching
+ on the various reasons for skipped or failed. Notice that <c>{'EXIT',Reason}</c> tuples
+ are translated into <c>{error,Reason}</c>.
+ Notice also that if a <c>{failed,{Suite,end_per_testcase,FailInfo}</c>
+ result is received, the test case was successful, but
<c>end_per_testcase</c> for the case failed.
</p></item>
+ <tag><c>#event{name = tc_auto_skip, data = {Suite,TestName,Reason}}</c></tag>
<item>
<marker id="tc_auto_skip"></marker>
- <c>#event{name = tc_auto_skip, data = {Suite,TestName,Reason}}</c>
<p><c>Suite = atom()</c>, the name of the suite.</p>
<p><c>TestName = init_per_suite | end_per_suite |
{init_per_group,GroupName} | {end_per_group,GroupName} |
@@ -245,101 +278,116 @@
<p><c>GroupName = atom()</c>, the name of the test case group.</p>
<p><c>Reason = {failed,FailReason} |
{require_failed_in_suite0,RequireInfo}</c>,
- reason for auto skipping <c>Func</c>.</p>
+ reason for auto-skipping <c>Func</c>.</p>
<p><c>FailReason = {Suite,ConfigFunc,FailInfo}} |
{Suite,FailedCaseInSequence}</c>, reason for failure.</p>
- <p><c>RequireInfo = {not_available,atom() | tuple()}</c>, why require has failed.</p>
+ <p><c>RequireInfo = {not_available,atom() | tuple()}</c>, why require failed.</p>
<p><c>ConfigFunc = init_per_suite | init_per_group</c></p>
<p><c>FailInfo = {timetrap_timeout,integer()} |
{RunTimeError,StackTrace} |
bad_return | UserTerm</c>,
- detailed information about an error.</p>
- <p><c>FailedCaseInSequence = atom()</c>, name of a case that has failed in a sequence.</p>
- <p><c>RunTimeError = term()</c>, a run-time error, e.g. badmatch, undef, etc.</p>
- <p><c>StackTrace = list()</c>, list of function calls preceeding a run-time error.</p>
- <p><c>UserTerm = term()</c>, arbitrary data specified by user, or <c>exit/1</c> info.</p>
- <p>This event gets sent for every test case or configuration function that Common Test
+ error details.</p>
+ <p><c>FailedCaseInSequence = atom()</c>, the name of a case that failed in a sequence.</p>
+ <p><c>RunTimeError = term()</c>, a runtime error, for example <c>badmatch</c> or
+ <c>undef</c>.</p>
+ <p><c>StackTrace = list()</c>, list of function calls preceeding a runtime error.</p>
+ <p><c>UserTerm = term()</c>, any data specified by user, or <c>exit/1</c> information.</p>
+ <p>This event is sent for every test case or configuration function that <c>Common Test</c>
has skipped automatically because of either a failed <c>init_per_suite</c> or
<c>init_per_group</c>, a failed <c>require</c> in <c>suite/0</c>, or a failed test case
- in a sequence. Note that this event is never received as a result of a test case getting
- skipped because of <c>init_per_testcase</c> failing, since that information is carried with
- the <c>tc_done</c> event. If a failed test case belongs to a test case group, the second
- data element is a tuple <c>{FuncName,GroupName}</c>, otherwise simply the function name.
+ in a sequence. Notice that this event is never received as a result of a test case getting
+ skipped because of <c>init_per_testcase</c> failing, as that information is carried with
+ event <c>tc_done</c>. If a failed test case belongs to a test case group, the second
+ data element is a tuple <c>{FuncName,GroupName}</c>, otherwise only the function name.
</p></item>
+ <tag><c>#event{name = tc_user_skip, data = {Suite,TestName,Comment}}</c></tag>
<item>
- <marker id="tc_user_skip"></marker>
- <c>#event{name = tc_user_skip, data = {Suite,TestName,Comment}}</c>
+ <marker id="tc_user_skip"></marker>
<p><c>Suite = atom()</c>, the name of the suite.</p>
<p><c>TestName = init_per_suite | end_per_suite |
{init_per_group,GroupName} | {end_per_group,GroupName} |
{FuncName,GroupName} | FuncName</c></p>
<p><c>FuncName = atom()</c>, the name of the test case or configuration function.</p>
<p><c>GroupName = atom()</c>, the name of the test case group.</p>
- <p><c>Comment = string()</c>, reason for skipping the test case.</p>
- <p>This event specifies that a test case has been skipped by the user.
- It is only ever received if the skip was declared in a test specification.
+ <p><c>Comment = string()</c>, why the test case was skipped.</p>
+ <p>This event specifies that a test case was skipped by the user.
+ It is only received if the skip is declared in a test specification.
Otherwise, user skip information is received as a <c>{skipped,SkipReason}</c>
- result in the <c>tc_done</c> event for the test case. If a skipped test case belongs
+ result in event <c>tc_done</c> for the test case. If a skipped test case belongs
to a test case group, the second data element is a tuple <c>{FuncName,GroupName}</c>,
- otherwise simply the function name.
+ otherwise only the function name.
</p></item>
- <item><c>#event{name = test_stats, data = {Ok,Failed,Skipped}}</c>
- <p><c>Ok = integer()</c>, the current number of successful test cases.</p>
- <p><c>Failed = integer()</c>, the current number of failed test cases.</p>
+ <tag><c>#event{name = test_stats, data = {Ok,Failed,Skipped}}</c></tag>
+ <item>
+ <p><c>Ok = integer()</c>, current number of successful test cases.</p>
+ <p><c>Failed = integer()</c>, current number of failed test cases.</p>
<p><c>Skipped = {UserSkipped,AutoSkipped}</c></p>
- <p><c>UserSkipped = integer()</c>, the current number of user skipped test cases.</p>
- <p><c>AutoSkipped = integer()</c>, the current number of auto skipped test cases.</p>
- <p>This is a statistics event with the current count of successful, skipped
- and failed test cases so far. This event gets sent after the end of each test case,
- immediately following the <c>tc_done</c> event.
+ <p><c>UserSkipped = integer()</c>, current number of user-skipped test cases.</p>
+ <p><c>AutoSkipped = integer()</c>, current number of auto-skipped test cases.</p>
+ <p>This is a statistics event with current count of successful, skipped,
+ and failed test cases so far. This event is sent after the end of each test case,
+ immediately following event <c>tc_done</c>.
</p></item>
- </list>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Internal Events</title>
- <p><em>Internal events:</em></p>
+ <p>The internal events are as follows:</p>
- <list>
- <item><c>#event{name = start_make, data = Dir}</c>
+ <taglist>
+ <tag><c>#event{name = start_make, data = Dir}</c></tag>
+ <item>
<p><c>Dir = string()</c>, running make in this directory.</p>
- <p>An internal event saying that Common Test will start compiling
+ <p>This internal event says that <c>Common Test</c> starts compiling
modules in directory <c>Dir</c>.
</p></item>
- <item><c>#event{name = finished_make, data = Dir}</c>
+ <tag><c>#event{name = finished_make, data = Dir}</c></tag>
+ <item>
<p><c>Dir = string()</c>, finished running make in this directory.</p>
- <p>An internal event saying that Common Test is finished compiling
+ <p>This internal event says that <c>Common Test</c> is finished compiling
modules in directory <c>Dir</c>.
</p></item>
- <item><c>#event{name = start_write_file, data = FullNameFile}</c>
+ <tag><c>#event{name = start_write_file, data = FullNameFile}</c></tag>
+ <item>
<p><c>FullNameFile = string(), full name of the file.</c></p>
- <p>An internal event used by the Common Test Master process to
+ <p>This internal event is used by the <c>Common Test</c> Master process to
synchronize particular file operations.
</p></item>
- <item><c>#event{name = finished_write_file, data = FullNameFile}</c>
+ <tag><c>#event{name = finished_write_file, data = FullNameFile}</c></tag>
+ <item>
<p><c>FullNameFile = string(), full name of the file.</c></p>
- <p>An internal event used by the Common Test Master process to
+ <p>This internal event is used by the <c>Common Test</c> Master process to
synchronize particular file operations.
</p></item>
- </list>
-
+ </taglist>
+ </section>
+ <section>
+ <title>Notes</title>
+
<p>The events are also documented in <c>ct_event.erl</c>. This module
- may serve as an example of what an event handler for the CT event
+ can serve as an example of what an event handler for the <c>Common Test</c> event
manager can look like.</p>
- <note><p>To ensure that printouts to standard out (or printouts made with
- <seealso marker="ct#log-2"><c>ct:log/2/3</c></seealso> or <seealso marker="ct:pal-2"><c>ct:pal/2/3</c></seealso>) get written to the test case log
- file, and not to the Common Test framework log, you can syncronize
- with the Common Test server by matching on the <c>tc_start</c> and <c>tc_done</c>
- events. In the period between these events, all IO gets directed to the
+ <note><p>To ensure that printouts to <c>stdout</c> (or printouts made with
+ <seealso marker="ct#log-2"><c>ct:log/2,3</c></seealso> or
+ <seealso marker="ct:pal-2"><c>ct:pal,2,3</c></seealso>) get written to the test case log
+ file, and not to the <c>Common Test</c> framework log, you can synchronize
+ with the <c>Common Test</c> server by matching on evvents <c>tc_start</c> and <c>tc_done</c>.
+ In the period between these events, all I/O is directed to the
test case log file. These events are sent synchronously to avoid potential
- timing problems (e.g. that the test case log file gets closed just before
- an IO message from an external process gets through). Knowing this, you
- need to be careful that your <c>handle_event/2</c> callback function doesn't
- stall the test execution, possibly causing unexpected behaviour as a result.</p></note>
+ timing problems (for example, that the test case log file is closed just before
+ an I/O message from an external process gets through). Knowing this, you
+ need to be careful that your <c>handle_event/2</c> callback function does not
+ stall the test execution, possibly causing unexpected behavior as a result.</p></note>
+ </section>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/example_chapter.xml b/lib/common_test/doc/src/example_chapter.xml
index 36781d152c..8523c9f485 100644
--- a/lib/common_test/doc/src/example_chapter.xml
+++ b/lib/common_test/doc/src/example_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -32,476 +33,472 @@
<marker id="top"></marker>
<section>
- <title>Test suite example</title>
- <p>This example test suite shows some tests of a database server.
+ <title>Test Suite Example</title>
+ <p>The following example test suite shows some tests of a database server:
</p>
<code>
--module(db_data_type_SUITE).
-
--include_lib("common_test/include/ct.hrl").
-
-%% Test server callbacks
--export([suite/0, all/0,
- init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, end_per_testcase/2]).
-
-%% Test cases
--export([string/1, integer/1]).
-
--define(CONNECT_STR, "DSN=sqlserver;UID=alladin;PWD=sesame").
-
-%%--------------------------------------------------------------------
-%% COMMON TEST CALLBACK FUNCTIONS
-%%--------------------------------------------------------------------
-
-%%--------------------------------------------------------------------
-%% Function: suite() -> Info
-%%
-%% Info = [tuple()]
-%% List of key/value pairs.
-%%
-%% Description: Returns list of tuples to set default properties
-%% for the suite.
-%%--------------------------------------------------------------------
-suite() ->
- [{timetrap,{minutes,1}}].
-
-%%--------------------------------------------------------------------
-%% Function: init_per_suite(Config0) -> Config1
-%%
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Initialization before the suite.
-%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- {ok, Ref} = db:connect(?CONNECT_STR, []),
- TableName = db_lib:unique_table_name(),
- [{con_ref, Ref },{table_name, TableName}| Config].
-
-%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config) -> void()
-%%
-%% Config = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Cleanup after the suite.
-%%--------------------------------------------------------------------
-end_per_suite(Config) ->
- Ref = ?config(con_ref, Config),
- db:disconnect(Ref),
- ok.
+ -module(db_data_type_SUITE).
+
+ -include_lib("common_test/include/ct.hrl").
+
+ %% Test server callbacks
+ -export([suite/0, all/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
+
+ %% Test cases
+ -export([string/1, integer/1]).
+
+ -define(CONNECT_STR, "DSN=sqlserver;UID=alladin;PWD=sesame").
+
+ %%--------------------------------------------------------------------
+ %% COMMON TEST CALLBACK FUNCTIONS
+ %%--------------------------------------------------------------------
+
+ %%--------------------------------------------------------------------
+ %% Function: suite() -> Info
+ %%
+ %% Info = [tuple()]
+ %% List of key/value pairs.
+ %%
+ %% Description: Returns list of tuples to set default properties
+ %% for the suite.
+ %%--------------------------------------------------------------------
+ suite() ->
+ [{timetrap,{minutes,1}}].
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_suite(Config0) -> Config1
+ %%
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %%
+ %% Description: Initialization before the suite.
+ %%--------------------------------------------------------------------
+ init_per_suite(Config) ->
+ {ok, Ref} = db:connect(?CONNECT_STR, []),
+ TableName = db_lib:unique_table_name(),
+ [{con_ref, Ref },{table_name, TableName}| Config].
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_suite(Config) -> term()
+ %%
+ %% Config = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %%
+ %% Description: Cleanup after the suite.
+ %%--------------------------------------------------------------------
+ end_per_suite(Config) ->
+ Ref = ?config(con_ref, Config),
+ db:disconnect(Ref),
+ ok.
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, Config0) -> Config1
-%%
-%% TestCase = atom()
-%% Name of the test case that is about to run.
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Initialization before each test case.
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- Ref = ?config(con_ref, Config),
- TableName = ?config(table_name, Config),
- ok = db:create_table(Ref, TableName, table_type(Case)),
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, Config) -> void()
-%%
-%% TestCase = atom()
-%% Name of the test case that is finished.
-%% Config = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Cleanup after each test case.
-%%--------------------------------------------------------------------
-end_per_testcase(_Case, Config) ->
- Ref = ?config(con_ref, Config),
- TableName = ?config(table_name, Config),
- ok = db:delete_table(Ref, TableName),
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: all() -> GroupsAndTestCases
-%%
-%% GroupsAndTestCases = [{group,GroupName} | TestCase]
-%% GroupName = atom()
-%% Name of a test case group.
-%% TestCase = atom()
-%% Name of a test case.
-%%
-%% Description: Returns the list of groups and test cases that
-%% are to be executed.
-%%--------------------------------------------------------------------
-all() ->
- [string, integer].
-
-
-%%--------------------------------------------------------------------
-%% TEST CASES
-%%--------------------------------------------------------------------
-
-string(Config) ->
- insert_and_lookup(dummy_key, "Dummy string", Config).
-
-integer(Config) ->
- insert_and_lookup(dummy_key, 42, Config).
-
-
-insert_and_lookup(Key, Value, Config) ->
- Ref = ?config(con_ref, Config),
- TableName = ?config(table_name, Config),
- ok = db:insert(Ref, TableName, Key, Value),
- [Value] = db:lookup(Ref, TableName, Key),
- ok = db:delete(Ref, TableName, Key),
- [] = db:lookup(Ref, TableName, Key),
- ok.
-
-</code>
+ %%--------------------------------------------------------------------
+ %% Function: init_per_testcase(TestCase, Config0) -> Config1
+ %%
+ %% TestCase = atom()
+ %% Name of the test case that is about to run.
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %%
+ %% Description: Initialization before each test case.
+ %%--------------------------------------------------------------------
+ init_per_testcase(Case, Config) ->
+ Ref = ?config(con_ref, Config),
+ TableName = ?config(table_name, Config),
+ ok = db:create_table(Ref, TableName, table_type(Case)),
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_testcase(TestCase, Config) -> term()
+ %%
+ %% TestCase = atom()
+ %% Name of the test case that is finished.
+ %% Config = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %%
+ %% Description: Cleanup after each test case.
+ %%--------------------------------------------------------------------
+ end_per_testcase(_Case, Config) ->
+ Ref = ?config(con_ref, Config),
+ TableName = ?config(table_name, Config),
+ ok = db:delete_table(Ref, TableName),
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: all() -> GroupsAndTestCases
+ %%
+ %% GroupsAndTestCases = [{group,GroupName} | TestCase]
+ %% GroupName = atom()
+ %% Name of a test case group.
+ %% TestCase = atom()
+ %% Name of a test case.
+ %%
+ %% Description: Returns the list of groups and test cases that
+ %% are to be executed.
+ %%--------------------------------------------------------------------
+ all() ->
+ [string, integer].
+
+
+ %%--------------------------------------------------------------------
+ %% TEST CASES
+ %%--------------------------------------------------------------------
+
+ string(Config) ->
+ insert_and_lookup(dummy_key, "Dummy string", Config).
+
+ integer(Config) ->
+ insert_and_lookup(dummy_key, 42, Config).
+
+
+ insert_and_lookup(Key, Value, Config) ->
+ Ref = ?config(con_ref, Config),
+ TableName = ?config(table_name, Config),
+ ok = db:insert(Ref, TableName, Key, Value),
+ [Value] = db:lookup(Ref, TableName, Key),
+ ok = db:delete(Ref, TableName, Key),
+ [] = db:lookup(Ref, TableName, Key),
+ ok.</code>
</section>
<section>
- <title>Test suite templates</title>
- <p>The Erlang mode for the Emacs editor includes two Common Test test suite
- templates, one with extensive information in the function headers, and
+ <title>Test Suite Templates</title>
+ <p>The Erlang mode for the Emacs editor includes two <c>Common Test</c> test
+ suite templates, one with extensive information in the function headers, and
one with minimal information. A test suite template provides a quick start
- for implementing a suite from scratch and gives you a good overview
- of the available callback functions. Here are the templates in question:
+ for implementing a suite from scratch and gives a good overview
+ of the available callback functions. The two templates follows:
</p>
- <p><em>Large Common Test suite</em></p>
+ <p><em>Large Common Test Suite</em></p>
<code>
-%%%-------------------------------------------------------------------
-%%% File : example_SUITE.erl
-%%% Author :
-%%% Description :
-%%%
-%%% Created :
-%%%-------------------------------------------------------------------
--module(example_SUITE).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
-%%--------------------------------------------------------------------
-%% COMMON TEST CALLBACK FUNCTIONS
-%%--------------------------------------------------------------------
-
-%%--------------------------------------------------------------------
-%% Function: suite() -> Info
-%%
-%% Info = [tuple()]
-%% List of key/value pairs.
-%%
-%% Description: Returns list of tuples to set default properties
-%% for the suite.
-%%
-%% Note: The suite/0 function is only meant to be used to return
-%% default data values, not perform any other operations.
-%%--------------------------------------------------------------------
-suite() ->
- [{timetrap,{minutes,10}}].
-
-%%--------------------------------------------------------------------
-%% Function: init_per_suite(Config0) ->
-%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
-%%
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Reason = term()
-%% The reason for skipping the suite.
-%%
-%% Description: Initialization before the suite.
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
-%%
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Cleanup after the suite.
-%%--------------------------------------------------------------------
-end_per_suite(_Config) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: init_per_group(GroupName, Config0) ->
-%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
-%%
-%% GroupName = atom()
-%% Name of the test case group that is about to run.
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding configuration data for the group.
-%% Reason = term()
-%% The reason for skipping all test cases and subgroups in the group.
-%%
-%% Description: Initialization before each test case group.
-%%--------------------------------------------------------------------
-init_per_group(_GroupName, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_group(GroupName, Config0) ->
-%% void() | {save_config,Config1}
-%%
-%% GroupName = atom()
-%% Name of the test case group that is finished.
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding configuration data for the group.
-%%
-%% Description: Cleanup after each test case group.
-%%--------------------------------------------------------------------
-end_per_group(_GroupName, _Config) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, Config0) ->
-%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
-%%
-%% TestCase = atom()
-%% Name of the test case that is about to run.
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Reason = term()
-%% The reason for skipping the test case.
-%%
-%% Description: Initialization before each test case.
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, Config0) ->
-%% void() | {save_config,Config1} | {fail,Reason}
-%%
-%% TestCase = atom()
-%% Name of the test case that is finished.
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Reason = term()
-%% The reason for failing the test case.
-%%
-%% Description: Cleanup after each test case.
-%%--------------------------------------------------------------------
-end_per_testcase(_TestCase, _Config) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: groups() -> [Group]
-%%
-%% Group = {GroupName,Properties,GroupsAndTestCases}
-%% GroupName = atom()
-%% The name of the group.
-%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
-%% Group properties that may be combined.
-%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
-%% TestCase = atom()
-%% The name of a test case.
-%% Shuffle = shuffle | {shuffle,Seed}
-%% To get cases executed in random order.
-%% Seed = {integer(),integer(),integer()}
-%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
-%% repeat_until_any_ok | repeat_until_any_fail
-%% To get execution of cases repeated.
-%% N = integer() | forever
-%%
-%% Description: Returns a list of test case group definitions.
-%%--------------------------------------------------------------------
-groups() ->
- [].
-
-%%--------------------------------------------------------------------
-%% Function: all() -> GroupsAndTestCases | {skip,Reason}
-%%
-%% GroupsAndTestCases = [{group,GroupName} | TestCase]
-%% GroupName = atom()
-%% Name of a test case group.
-%% TestCase = atom()
-%% Name of a test case.
-%% Reason = term()
-%% The reason for skipping all groups and test cases.
-%%
-%% Description: Returns the list of groups and test cases that
-%% are to be executed.
-%%--------------------------------------------------------------------
-all() ->
- [my_test_case].
-
-
-%%--------------------------------------------------------------------
-%% TEST CASES
-%%--------------------------------------------------------------------
-
-%%--------------------------------------------------------------------
-%% Function: TestCase() -> Info
-%%
-%% Info = [tuple()]
-%% List of key/value pairs.
-%%
-%% Description: Test case info function - returns list of tuples to set
-%% properties for the test case.
-%%
-%% Note: This function is only meant to be used to return a list of
-%% values, not perform any other operations.
-%%--------------------------------------------------------------------
-my_test_case() ->
- [].
-
-%%--------------------------------------------------------------------
-%% Function: TestCase(Config0) ->
-%% ok | exit() | {skip,Reason} | {comment,Comment} |
-%% {save_config,Config1} | {skip_and_save,Reason,Config1}
-%%
-%% Config0 = Config1 = [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Reason = term()
-%% The reason for skipping the test case.
-%% Comment = term()
-%% A comment about the test case that will be printed in the html log.
-%%
-%% Description: Test case function. (The name of it must be specified in
-%% the all/0 list or in a test case group for the test case
-%% to be executed).
-%%--------------------------------------------------------------------
-my_test_case(_Config) ->
- ok.
-</code>
+ %%%-------------------------------------------------------------------
+ %%% File : example_SUITE.erl
+ %%% Author :
+ %%% Description :
+ %%%
+ %%% Created :
+ %%%-------------------------------------------------------------------
+ -module(example_SUITE).
+
+ %% Note: This directive should only be used in test suites.
+ -compile(export_all).
+
+ -include_lib("common_test/include/ct.hrl").
+
+ %%--------------------------------------------------------------------
+ %% COMMON TEST CALLBACK FUNCTIONS
+ %%--------------------------------------------------------------------
+
+ %%--------------------------------------------------------------------
+ %% Function: suite() -> Info
+ %%
+ %% Info = [tuple()]
+ %% List of key/value pairs.
+ %%
+ %% Description: Returns list of tuples to set default properties
+ %% for the suite.
+ %%
+ %% Note: The suite/0 function is only meant to be used to return
+ %% default data values, not perform any other operations.
+ %%--------------------------------------------------------------------
+ suite() ->
+ [{timetrap,{minutes,10}}].
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_suite(Config0) ->
+ %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+ %%
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %% Reason = term()
+ %% The reason for skipping the suite.
+ %%
+ %% Description: Initialization before the suite.
+ %%
+ %% Note: This function is free to add any key/value pairs to the Config
+ %% variable, but should NOT alter/remove any existing entries.
+ %%--------------------------------------------------------------------
+ init_per_suite(Config) ->
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_suite(Config0) -> term() | {save_config,Config1}
+ %%
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %%
+ %% Description: Cleanup after the suite.
+ %%--------------------------------------------------------------------
+ end_per_suite(_Config) ->
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_group(GroupName, Config0) ->
+ %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+ %%
+ %% GroupName = atom()
+ %% Name of the test case group that is about to run.
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding configuration data for the group.
+ %% Reason = term()
+ %% The reason for skipping all test cases and subgroups in the group.
+ %%
+ %% Description: Initialization before each test case group.
+ %%--------------------------------------------------------------------
+ init_per_group(_GroupName, Config) ->
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_group(GroupName, Config0) ->
+ %% term() | {save_config,Config1}
+ %%
+ %% GroupName = atom()
+ %% Name of the test case group that is finished.
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding configuration data for the group.
+ %%
+ %% Description: Cleanup after each test case group.
+ %%--------------------------------------------------------------------
+ end_per_group(_GroupName, _Config) ->
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_testcase(TestCase, Config0) ->
+ %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+ %%
+ %% TestCase = atom()
+ %% Name of the test case that is about to run.
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %% Reason = term()
+ %% The reason for skipping the test case.
+ %%
+ %% Description: Initialization before each test case.
+ %%
+ %% Note: This function is free to add any key/value pairs to the Config
+ %% variable, but should NOT alter/remove any existing entries.
+ %%--------------------------------------------------------------------
+ init_per_testcase(_TestCase, Config) ->
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_testcase(TestCase, Config0) ->
+ %% term() | {save_config,Config1} | {fail,Reason}
+ %%
+ %% TestCase = atom()
+ %% Name of the test case that is finished.
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %% Reason = term()
+ %% The reason for failing the test case.
+ %%
+ %% Description: Cleanup after each test case.
+ %%--------------------------------------------------------------------
+ end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: groups() -> [Group]
+ %%
+ %% Group = {GroupName,Properties,GroupsAndTestCases}
+ %% GroupName = atom()
+ %% The name of the group.
+ %% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+ %% Group properties that may be combined.
+ %% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+ %% TestCase = atom()
+ %% The name of a test case.
+ %% Shuffle = shuffle | {shuffle,Seed}
+ %% To get cases executed in random order.
+ %% Seed = {integer(),integer(),integer()}
+ %% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+ %% repeat_until_any_ok | repeat_until_any_fail
+ %% To get execution of cases repeated.
+ %% N = integer() | forever
+ %%
+ %% Description: Returns a list of test case group definitions.
+ %%--------------------------------------------------------------------
+ groups() ->
+ [].
+
+ %%--------------------------------------------------------------------
+ %% Function: all() -> GroupsAndTestCases | {skip,Reason}
+ %%
+ %% GroupsAndTestCases = [{group,GroupName} | TestCase]
+ %% GroupName = atom()
+ %% Name of a test case group.
+ %% TestCase = atom()
+ %% Name of a test case.
+ %% Reason = term()
+ %% The reason for skipping all groups and test cases.
+ %%
+ %% Description: Returns the list of groups and test cases that
+ %% are to be executed.
+ %%--------------------------------------------------------------------
+ all() ->
+ [my_test_case].
+
+
+ %%--------------------------------------------------------------------
+ %% TEST CASES
+ %%--------------------------------------------------------------------
+
+ %%--------------------------------------------------------------------
+ %% Function: TestCase() -> Info
+ %%
+ %% Info = [tuple()]
+ %% List of key/value pairs.
+ %%
+ %% Description: Test case info function - returns list of tuples to set
+ %% properties for the test case.
+ %%
+ %% Note: This function is only meant to be used to return a list of
+ %% values, not perform any other operations.
+ %%--------------------------------------------------------------------
+ my_test_case() ->
+ [].
+
+ %%--------------------------------------------------------------------
+ %% Function: TestCase(Config0) ->
+ %% ok | exit() | {skip,Reason} | {comment,Comment} |
+ %% {save_config,Config1} | {skip_and_save,Reason,Config1}
+ %%
+ %% Config0 = Config1 = [tuple()]
+ %% A list of key/value pairs, holding the test case configuration.
+ %% Reason = term()
+ %% The reason for skipping the test case.
+ %% Comment = term()
+ %% A comment about the test case that will be printed in the html log.
+ %%
+ %% Description: Test case function. (The name of it must be specified in
+ %% the all/0 list or in a test case group for the test case
+ %% to be executed).
+ %%--------------------------------------------------------------------
+ my_test_case(_Config) ->
+ ok.</code>
<br></br>
- <p><em>Small Common Test suite</em></p>
+ <p><em>Small Common Test Suite</em></p>
<code>
-%%%-------------------------------------------------------------------
-%%% File : example_SUITE.erl
-%%% Author :
-%%% Description :
-%%%
-%%% Created :
-%%%-------------------------------------------------------------------
--module(example_SUITE).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
-%%--------------------------------------------------------------------
-%% Function: suite() -> Info
-%% Info = [tuple()]
-%%--------------------------------------------------------------------
-suite() ->
- [{timetrap,{seconds,30}}].
-
-%%--------------------------------------------------------------------
-%% Function: init_per_suite(Config0) ->
-%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
-%% Config0 = Config1 = [tuple()]
-%% Reason = term()
-%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
-%% Config0 = Config1 = [tuple()]
-%%--------------------------------------------------------------------
-end_per_suite(_Config) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: init_per_group(GroupName, Config0) ->
-%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
-%% GroupName = atom()
-%% Config0 = Config1 = [tuple()]
-%% Reason = term()
-%%--------------------------------------------------------------------
-init_per_group(_GroupName, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_group(GroupName, Config0) ->
-%% void() | {save_config,Config1}
-%% GroupName = atom()
-%% Config0 = Config1 = [tuple()]
-%%--------------------------------------------------------------------
-end_per_group(_GroupName, _Config) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, Config0) ->
-%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
-%% TestCase = atom()
-%% Config0 = Config1 = [tuple()]
-%% Reason = term()
-%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, Config0) ->
-%% void() | {save_config,Config1} | {fail,Reason}
-%% TestCase = atom()
-%% Config0 = Config1 = [tuple()]
-%% Reason = term()
-%%--------------------------------------------------------------------
-end_per_testcase(_TestCase, _Config) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: groups() -> [Group]
-%% Group = {GroupName,Properties,GroupsAndTestCases}
-%% GroupName = atom()
-%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
-%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
-%% TestCase = atom()
-%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
-%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
-%% repeat_until_any_ok | repeat_until_any_fail
-%% N = integer() | forever
-%%--------------------------------------------------------------------
-groups() ->
- [].
-
-%%--------------------------------------------------------------------
-%% Function: all() -> GroupsAndTestCases | {skip,Reason}
-%% GroupsAndTestCases = [{group,GroupName} | TestCase]
-%% GroupName = atom()
-%% TestCase = atom()
-%% Reason = term()
-%%--------------------------------------------------------------------
-all() ->
- [my_test_case].
-
-%%--------------------------------------------------------------------
-%% Function: TestCase() -> Info
-%% Info = [tuple()]
-%%--------------------------------------------------------------------
-my_test_case() ->
- [].
-
-%%--------------------------------------------------------------------
-%% Function: TestCase(Config0) ->
-%% ok | exit() | {skip,Reason} | {comment,Comment} |
-%% {save_config,Config1} | {skip_and_save,Reason,Config1}
-%% Config0 = Config1 = [tuple()]
-%% Reason = term()
-%% Comment = term()
-%%--------------------------------------------------------------------
-my_test_case(_Config) ->
- ok.
-</code>
+ %%%-------------------------------------------------------------------
+ %%% File : example_SUITE.erl
+ %%% Author :
+ %%% Description :
+ %%%
+ %%% Created :
+ %%%-------------------------------------------------------------------
+ -module(example_SUITE).
+
+ -compile(export_all).
+
+ -include_lib("common_test/include/ct.hrl").
+
+ %%--------------------------------------------------------------------
+ %% Function: suite() -> Info
+ %% Info = [tuple()]
+ %%--------------------------------------------------------------------
+ suite() ->
+ [{timetrap,{seconds,30}}].
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_suite(Config0) ->
+ %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+ %% Config0 = Config1 = [tuple()]
+ %% Reason = term()
+ %%--------------------------------------------------------------------
+ init_per_suite(Config) ->
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_suite(Config0) -> term() | {save_config,Config1}
+ %% Config0 = Config1 = [tuple()]
+ %%--------------------------------------------------------------------
+ end_per_suite(_Config) ->
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_group(GroupName, Config0) ->
+ %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+ %% GroupName = atom()
+ %% Config0 = Config1 = [tuple()]
+ %% Reason = term()
+ %%--------------------------------------------------------------------
+ init_per_group(_GroupName, Config) ->
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_group(GroupName, Config0) ->
+ %% term() | {save_config,Config1}
+ %% GroupName = atom()
+ %% Config0 = Config1 = [tuple()]
+ %%--------------------------------------------------------------------
+ end_per_group(_GroupName, _Config) ->
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: init_per_testcase(TestCase, Config0) ->
+ %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+ %% TestCase = atom()
+ %% Config0 = Config1 = [tuple()]
+ %% Reason = term()
+ %%--------------------------------------------------------------------
+ init_per_testcase(_TestCase, Config) ->
+ Config.
+
+ %%--------------------------------------------------------------------
+ %% Function: end_per_testcase(TestCase, Config0) ->
+ %% term() | {save_config,Config1} | {fail,Reason}
+ %% TestCase = atom()
+ %% Config0 = Config1 = [tuple()]
+ %% Reason = term()
+ %%--------------------------------------------------------------------
+ end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+ %%--------------------------------------------------------------------
+ %% Function: groups() -> [Group]
+ %% Group = {GroupName,Properties,GroupsAndTestCases}
+ %% GroupName = atom()
+ %% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+ %% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+ %% TestCase = atom()
+ %% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+ %% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+ %% repeat_until_any_ok | repeat_until_any_fail
+ %% N = integer() | forever
+ %%--------------------------------------------------------------------
+ groups() ->
+ [].
+
+ %%--------------------------------------------------------------------
+ %% Function: all() -> GroupsAndTestCases | {skip,Reason}
+ %% GroupsAndTestCases = [{group,GroupName} | TestCase]
+ %% GroupName = atom()
+ %% TestCase = atom()
+ %% Reason = term()
+ %%--------------------------------------------------------------------
+ all() ->
+ [my_test_case].
+
+ %%--------------------------------------------------------------------
+ %% Function: TestCase() -> Info
+ %% Info = [tuple()]
+ %%--------------------------------------------------------------------
+ my_test_case() ->
+ [].
+
+ %%--------------------------------------------------------------------
+ %% Function: TestCase(Config0) ->
+ %% ok | exit() | {skip,Reason} | {comment,Comment} |
+ %% {save_config,Config1} | {skip_and_save,Reason,Config1}
+ %% Config0 = Config1 = [tuple()]
+ %% Reason = term()
+ %% Comment = term()
+ %%--------------------------------------------------------------------
+ my_test_case(_Config) ->
+ ok.</code>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/getting_started_chapter.xml b/lib/common_test/doc/src/getting_started_chapter.xml
index 445c731d01..802f9ba397 100644
--- a/lib/common_test/doc/src/getting_started_chapter.xml
+++ b/lib/common_test/doc/src/getting_started_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -30,235 +31,247 @@
</header>
<section>
- <title>Are you new around here?</title>
+ <title>Introduction for Newcomers</title>
<p>
- The purpose of this short chapter is to, with a "learning by example"
- approach, give the newcomer a chance to get started quickly writing and
- executing some first simple tests. The chapter will introduce some of the
- basics, but leave most explanations and details for the later
- chapters in this User's Guide. Hopefully though, after this chapter, you
- will be inspired and unintimidated enough to go on and get into the
- nitty-gritty that follows in this rather heavy User's Guide! If you're
- not much into "learning by example" and prefer to get into more technical
- detail right away, go ahead and skip to the next chapter. Again, the basics
- presented here will be covered in detail in later chapters.
+ The purpose of this section is to let the newcomer get started in
+ quickly writing and executing some first simple tests with a
+ "learning by example" approach. Most explanations are left for later sections.
+ If you are not much into "learning by example" and prefer more technical
+ details, go ahead and skip to the next section.
</p>
<p>
- This chapter also tries to demonstrate how dead simple it actually is
- to write a very basic (yet for many module testing purposes, often sufficiently
- complex) test suite, and execute its test cases. This is not necessarily
- obvious when you read the rest of the chapters in the User's Guide.
- </p>
- <p>
- A quick note before we start: In order to understand what's discussed and
- examplified here, it is recommended that you first read through the
- opening <seealso marker="basics_chapter#basics">Common Test Basics</seealso>
- chapter.
+ This section demonstrates how simple it is to write a basic
+ (yet for many module testing purposes, often sufficiently complex)
+ test suite and execute its test cases. This is not necessarily
+ obvious when you read the remaining sections in this User's Guide.
</p>
+ <note>
+ <p>
+ To understand what is discussed and examplified here, we recommended
+ you to first read section
+ <seealso marker="basics_chapter#basics">Common Test Basics</seealso>.
+ </p>
+ </note>
</section>
<section>
- <title>Test case execution</title>
- <p>Execution of test cases is handled this way:</p>
+ <title>Test Case Execution</title>
+ <p>Execution of test cases is handled as follows:</p>
<image file="tc_execution.gif">
<icaption>
- Successful vs unsuccessful test case execution.
+ Successful and Unsuccessful Test Case Execution
</icaption>
</image>
- <p>For each test case that Common Test is told to execute, it spawns a
- dedicated process on which the test case function in question starts
+ <p>For each test case that <c>Common Test</c> is ordered to execute, it spawns a
+ dedicated process on which the test case function starts
running. (In parallel to the test case process, an idle waiting timer
- process is started which is linked to the test case process. If the timer
+ process is started, which is linked to the test case process. If the timer
process runs out of waiting time, it sends an exit signal to terminate
- the test case process and this is what's called a <em>timetrap</em>).
+ the test case process. This is called a <em>timetrap</em>).
</p>
- <p>In scenario 1, the test case process terminates normally after case A has
- finished executing its test code without detecting any errors. The test
- case function simply returns a value and Common Test logs the test case as
- successful.
+ <p>In scenario 1, the test case process terminates normally after
+ <c>case A</c> has finished executing its test code without detecting
+ any errors. The test case function returns a value and <c>Common Test</c>
+ logs the test case as successful.
</p>
- <p>In scenario 2, an error is detected during test case execution
- which causes the test case B function to generate an exception.
- This causes the test case process to exit with reason
- other than normal, and as a result, Common Test will log this as an
- unsuccessful test case.
+ <p>In scenario 2, an error is detected during test <c>case B</c> execution.
+ This causes the test <c>case B</c> function to generate an exception
+ and, as a result, the test case process exits with reason other than normal.
+ <c>Common Test</c> logs this as an unsuccessful (Failed) test case.
</p>
- <p>As you can understand from the illustration above, Common Test requires
- that a test case generates a runtime error to indicate failure (e.g.
- by causing a bad match error or by calling <c>exit/1</c>, preferrably
- through the <seealso marker="ct#fail-1"><c>ct:fail/1,2</c></seealso> help function). A succesful execution is
- indicated by means of a normal return from the test case function.
+ <p>As you can understand from the illustration, <c>Common Test</c> requires
+ a test case to generate a runtime error to indicate failure (for example,
+ by causing a bad match error or by calling <c>exit/1</c>, preferably
+ through the help function
+ <seealso marker="ct#fail-1"><c>ct:fail/1,2</c></seealso>). A successful
+ execution is indicated by a normal return from the test case function.
</p>
</section>
<section>
- <title>A simple test suite</title>
- <p>As you've seen in the basics chapter, the test suite module implements
+ <title>A Simple Test Suite</title>
+ <p>As shown in section
+ <seealso marker="basics_chapter#External_Interfaces">Common Test Basics</seealso>,
+ the test suite module implements
<seealso marker="common_test">callback functions</seealso>
- (mandatory or optional) for various purposes, e.g:
+ (mandatory or optional) for various purposes, for example:
</p>
- <list>
+ <list type="bulleted">
<item>Init/end configuration function for the test suite</item>
<item>Init/end configuration function for a test case</item>
<item>Init/end configuration function for a test case group</item>
<item>Test cases</item>
</list>
<p>
- The configuration functions are optional and if you don't need them for
- your test, a test suite with one simple test case could look like this:
+ The configuration functions are optional. The following example is a test suite
+ without configuration functions, including one simple test case, to
+ check that module <c>mymod</c> exists (that is, can be successfully loaded by the
+ code server):
</p>
<pre>
- -module(my1st_SUITE).
- -compile(export_all).
+ -module(my1st_SUITE).
+ -compile(export_all).
- all() ->
- [mod_exists].
+ all() ->
+ [mod_exists].
- mod_exists(_) ->
- {module,mymod} = code:load_file(mymod).</pre>
+ mod_exists(_) ->
+ {module,mymod} = code:load_file(mymod).</pre>
<p>
- In this example we check that the <c>mymod</c> module exists (i.e. can be
- successfully loaded by the code server). If the operation fails, we will
- get a bad match error which terminates the test case.
+ If the operation fails, a bad match error occurs that terminates the test case.
</p>
</section>
<section>
- <title>A test suite with configuration functions</title>
+ <title>A Test Suite with Configuration Functions</title>
<p>
- If we need to perform configuration operations in order to run our test, we
- implement configuration functions in our suite. The result from a
- configuration function is configuration data, or simply <em><c>Config</c></em>.
- This is a list of key-value tuples which get passed from the configuration
+ If you need to perform configuration operations to run your test, you can
+ implement configuration functions in your suite. The result from a
+ configuration function is configuration data, or <c>Config</c>.
+ This is a list of key-value tuples that get passed from the configuration
function to the test cases (possibly through configuration functions on
- "lower level"). The data flow looks like this:
+ "lower level"). The data flow looks as follows:
</p>
<image file="config.gif">
<icaption>
- Config data flow in the suite.
+ Configuration Data Flow in a Suite
</icaption>
</image>
<p>
- Here's an example of a test suite which uses configuration functions
- to open and close a log file for the test cases (an operation that would
- be unnecessary and irrelevant to perform by each test case):
+ The following example shows a test suite that uses configuration functions
+ to open and close a log file for the test cases (an operation that is
+ unnecessary and irrelevant to perform by each test case):
</p>
<pre>
- -module(check_log_SUITE).
- -export([all/0, init_per_suite/1, end_per_suite/1]).
- -export([check_restart_result/1, check_no_errors/1]).
-
- -define(value(Key,Config), proplists:get_value(Key,Config)).
+ -module(check_log_SUITE).
+ -export([all/0, init_per_suite/1, end_per_suite/1]).
+ -export([check_restart_result/1, check_no_errors/1]).
- all() -> [check_restart_result, check_no_errors].
+ -define(value(Key,Config), proplists:get_value(Key,Config)).
- init_per_suite(InitConfigData) ->
- [{logref,open_log()} | InitConfigData].
+ all() -> [check_restart_result, check_no_errors].
- end_per_suite(ConfigData) ->
- close_log(?value(logref, ConfigData)).
+ init_per_suite(InitConfigData) ->
+ [{logref,open_log()} | InitConfigData].
- check_restart_result(ConfigData) ->
- TestData = read_log(restart, ?value(logref, ConfigData)),
- {match,_Line} = search_for("restart successful", TestData).
-
- check_no_errors(ConfigData) ->
- TestData = read_log(all, ?value(logref, ConfigData)),
- case search_for("error", TestData) of
- {match,Line} -> ct:fail({error_found_in_log,Line});
- nomatch -> ok
- end.</pre>
+ end_per_suite(ConfigData) ->
+ close_log(?value(logref, ConfigData)).
+
+ check_restart_result(ConfigData) ->
+ TestData = read_log(restart, ?value(logref, ConfigData)),
+ {match,_Line} = search_for("restart successful", TestData).
+
+ check_no_errors(ConfigData) ->
+ TestData = read_log(all, ?value(logref, ConfigData)),
+ case search_for("error", TestData) of
+ {match,Line} -> ct:fail({error_found_in_log,Line});
+ nomatch -> ok
+ end.</pre>
<p>
- In this example we have test cases that verify, by parsing a
- log file, that our SUT has performed a successful restart and
- that no unexpected errors have been printed.
+ The test cases verify, by parsing a log file, that our SUT has performed
+ a successful restart and that no unexpected errors are printed.
</p>
- <p>To execute the test cases in the test suite above, we could type this on
- the Unix/Linux command line (assuming for this example that the suite module
+ <p>To execute the test cases in the recent test suite, type the
+ following on the UNIX/Linux command line (assuming that the suite module
is in the current working directory):
</p>
<pre>
- $ ct_run -dir .</pre>
- <p>or</p>
+ $ ct_run -dir .</pre>
+ <p>or:</p>
<pre>
- $ ct_run -suite check_log_SUITE</pre>
+ $ ct_run -suite check_log_SUITE</pre>
- <p>If we want to use the Erlang shell to run our test, we could evaluate this call:
+ <p>To use the Erlang shell to run our test, you can evaluate the following call:
</p>
<pre>
- 1> ct:run_test([{dir, "."}]).</pre>
- <p>or</p>
+ 1> ct:run_test([{dir, "."}]).</pre>
+ <p>or:</p>
<pre>
- 1> ct:run_test([{suite, "check_log_SUITE"}]).</pre>
+ 1> ct:run_test([{suite, "check_log_SUITE"}]).</pre>
<p>
- The result from running our test is printed in log files in HTML format
- (stored in unique log directories on different level). This illustration
- shows the log file structure:
+ The result from running the test is printed in log files in HTML format
+ (stored in unique log directories on a different level). The following
+ illustration shows the log file structure:
</p>
<image file="html_logs.gif">
<icaption>
- HTML log file structure.
+ HTML Log File Structure
</icaption>
</image>
</section>
<section>
- <title>What happens next?</title>
+ <title>Questions and Answers</title>
- <p>Well, you might already be asking yourself questions such as:</p>
+ <p>Here follows some questions that you might have after reading this section
+ with corresponding tips and links to the answers:
+ </p>
- <list>
- <item>"How and where can I specify variable data for my tests that mustn't
- be hard-coded in the test suites (such as host names, addresses,
- user login data, etc)?" The
- <seealso marker="config_file_chapter#top">External Configuration Data</seealso>
- chapter will give you that information.
+ <list type="bulleted">
+ <item><p><em>Question:</em>
+ "How and where can I specify variable data for my tests that must not
+ be hard-coded in the test suites (such as hostnames, addresses, and
+ user login data)?"</p>
+ <p><em>Answer:</em>
+ See section <seealso marker="config_file_chapter#top">External Configuration Data</seealso>.</p>
</item>
- <item>"Is there a way to declare a number of different tests and run them
- in one session without having to write my own scripts? And can such
- declarations be used for regression testing?" The
+
+ <item><p><em>Question:</em> "Is there a way to declare different tests and run them
+ in one session without having to write my own scripts? Also, can such
+ declarations be used for regression testing?"</p>
+ <p><em>Answer:</em> See section
<seealso marker="run_test_chapter#test_specifications">Test Specifications</seealso>
- chapter answers these questions.
+ in section Running Tests and Analyzing Results.
+ </p>
</item>
- <item>"Can test cases and/or test runs be automatically repeated?" Learn more about
+
+ <item><p><em>Question:</em> "Can test cases and/or test runs be automatically repeated?"</p>
+ <p><em>Answer:</em> Learn more about
<seealso marker="write_test_chapter#test_case_groups">Test Case Groups</seealso>
- and also read about start flags/options in the
- <seealso marker="run_test_chapter#ct_run">Running Tests</seealso> chapter and
- the Reference Manual.
+ and read about start flags/options in section
+ <seealso marker="run_test_chapter#ct_run">Running Tests</seealso> and in
+ the Reference Manual.</p>
</item>
- <item>"Will Common Test execute my test cases in sequence or in parallel?" The
+
+ <item><p><em>Question:</em> "Does <c>Common Test</c> execute my test cases in sequence or in parallel?"</p>
+ <p><em>Answer:</em> See
<seealso marker="write_test_chapter#test_case_groups">Test Case Groups</seealso>
- section in the Running Tests chapter will give you the answer.
+ in section Writing Test Suites.</p>
</item>
- <item>"What's the syntax for timetraps (mentioned above), and how do I set them?"
- This is explained in the
- <seealso marker="write_test_chapter#timetraps">Timetrap Timeouts</seealso>
- part of the Writing Test Suites chapter.
+
+ <item><p><em>Question:</em> "What is the syntax for timetraps (mentioned earlier), and how do I set them?"</p>
+ <p><em>Answer:</em> This is explained in the
+ <seealso marker="write_test_chapter#timetraps">Timetrap Time-Outs</seealso>
+ part of section Writing Test Suites.</p>
</item>
- <item>"What functions are available for logging and printing?" Check the
+
+ <item><p><em>Question:</em> "What functions are available for logging and printing?"</p>
+ <p><em>Answer:</em> See
<seealso marker="write_test_chapter#logging">Logging</seealso>
- section in the Writing Test Suites chapter.
+ in section Writing Test Suites.</p>
</item>
- <item>"I need data files for my tests. Where do I store them preferrably?"
- You should read about
+
+ <item><p><em>Question:</em> "I need data files for my tests. Where do I store them preferably?"</p>
+ <p><em>Answer:</em> See
<seealso marker="write_test_chapter#data_priv_dir">Data and Private
- Directories</seealso> for information about this.
+ Directories</seealso>.</p>
</item>
- <item>"May I start with a test suite example, please?"
- <seealso marker="example_chapter#top">Sure!</seealso>
+
+ <item><p><em>Question:</em> "Can I start with a test suite example, please?"</p>
+ <p><em>Answer:</em> <seealso marker="example_chapter#top">Welcome!</seealso></p>
</item>
</list>
- <p>You will probably want to get started on your own first test suites now, while
- at the same time digging deeper into the Common Test User's Guide and Reference Manual.
- You will find that there's lots more to learn about the things that have been introduced
- in this chapter. You will of course also be presented many more useful features, such as the
- ones listed above. Have fun!
+ <p>You probably want to get started on your own first test suites now, while
+ at the same time digging deeper into the <c>Common Test</c> User's Guide and Reference Manual.
+ There are much more to learn about the things that have been introduced
+ in this section. There are also many other useful features to learn,
+ so please continue to the other sections and have fun.
</p>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/install_chapter.xml b/lib/common_test/doc/src/install_chapter.xml
index 7f8c606324..9dce1e31a4 100644
--- a/lib/common_test/doc/src/install_chapter.xml
+++ b/lib/common_test/doc/src/install_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,79 +32,23 @@
<section>
<marker id="general"></marker>
- <title>General information</title>
-
- <p>The two main interfaces for running tests with Common Test
- are an executable program named ct_run and an
- erlang module named <c>ct</c>. The ct_run program
- is compiled for the underlying operating system (e.g. Unix/Linux
- or Windows) during the build of the Erlang/OTP system, and is
- installed automatically with other executable programs in
+ <title>General Information</title>
+
+ <p>The two main interfaces for running tests with <c>Common Test</c>
+ are an executable program named
+ <seealso marker="ct_run"><c>ct_run</c></seealso> and the
+ Erlang module <seealso marker="ct"><c>ct</c></seealso>.
+ <c>ct_run</c> is compiled for the underlying operating system (for example,
+ Unix/Linux or Windows) during the build of the Erlang/OTP system,
+ and is installed automatically with other executable programs in
the top level <c>bin</c> directory of Erlang/OTP.
The <c>ct</c> interface functions can be called from the Erlang shell,
or from any Erlang function, on any supported platform.</p>
- <p>A legacy Bourne shell script - named run_test - exists,
- which may be manually generated and installed. This script may be used
- instead of the ct_run program mentioned above, e.g. if the user
- wishes to modify or customize the Common Test start flags in a simpler
- way than making changes to the ct_run C program.</p>
-
- <p>The Common Test application is installed with the Erlang/OTP
- system and no additional installation step is required to start using
- Common Test by means of the ct_run executable program, and/or the interface
- functions in the <c>ct</c> module. If you wish to use the legacy Bourne
- shell script version run_test, however, this script needs to be
- generated first, according to the instructions below.</p>
-
- <note><p>Before reading on, please note that since Common Test version
- 1.5, the run_test shell script is no longer required for starting
- tests with Common Test from the OS command line. The ct_run
- program (descibed above) is the new recommended command line interface
- for Common Test. The shell script exists mainly for legacy reasons and
- may not be updated in future releases of Common Test. It may even be removed.
- </p></note>
-
- <p>Optional step to generate a shell script for starting Common Test:</p>
- <p>To generate the run_test shell script, navigate to the
- <c><![CDATA[common_test-<vsn>]]></c> directory, located among the other
- OTP applications (under the OTP lib directory). Here execute the
- <c>install.sh</c> script with argument <c>local</c>:</p>
-
- <p><c>
- $ ./install.sh local
- </c></p>
-
- <p>This generates the executable run_test script in the
- <c><![CDATA[common_test-<vsn>/priv/bin]]></c> directory. The script
- will include absolute paths to the Common Test and Test Server
- application directories, so it's possible to copy or move the script to
- a different location on the file system, if desired, without having to
- update it. It's of course possible to leave the script under the
- <c>priv/bin</c> directory and update the PATH variable accordingly (or
- create a link or alias to it).</p>
-
- <p>If you, for any reason, have copied Common Test and Test Server
- to a different location than the default OTP lib directory, you can
- generate a run_test script with a different top level directory,
- simply by specifying the directory, instead of <c>local</c>, when running
- <c>install.sh</c>. Example:</p>
-
- <p><c>
- $ install.sh /usr/local/test_tools
- </c></p>
-
- <p>Note that the <c><![CDATA[common_test-<vsn>]]></c> and
- <c><![CDATA[test_server-<vsn>]]></c> directories must be located under the
- same top directory. Note also that the install script does not copy files
- or update environment variables. It only generates the run_test
- script.</p>
-
- <p>Whenever you install a new version of Erlang/OTP, the run_test
- script needs to be regenerated, or updated manually with new directory names
- (new version numbers), for it to "see" the latest Common Test and Test Server
- versions.</p>
-
+ <p>The <c>Common Test</c> application is installed with the Erlang/OTP
+ system. No extra installation step is required to start using
+ <c>Common Test</c> through the <c>ct_run</c> executable program,
+ and/or the interface functions in the <c>ct</c> module.</p>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/introduction.xml b/lib/common_test/doc/src/introduction.xml
new file mode 100644
index 0000000000..e2a42bfd33
--- /dev/null
+++ b/lib/common_test/doc/src/introduction.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Introduction</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2015-10-05</date>
+ <rev></rev>
+ <file>introduction.xml</file>
+ </header>
+ <section>
+ <title>Scope</title>
+ <p><c>Common Test</c> is a portable application for automated
+ testing. It is suitable for:</p>
+ <list type="bulleted">
+ <item><p>Black-box testing of target systems of any type (that
+ is, not necessarily implemented in Erlang). This is performed
+ through standard O&amp;M interfaces (such as SNMP, HTTP, CORBA,
+ and Telnet) and, if necessary, through user-specific interfaces
+ (often called test ports).</p></item>
+ <item><p>White-box testing of Erlang/OTP programs. This is easily
+ done by calling the target API functions directly from the test
+ case functions.</p></item>
+ </list>
+ <p><c>Common Test</c> also integrates use of the OTP
+ <seealso marker="tools:cover">cover</seealso> tool in application
+ <c>Tools</c> for code coverage analysis of Erlang/OTP programs.</p>
+
+ <p><c>Common Test</c> executes test suite programs automatically,
+ without operator interaction. Test progress and results are
+ printed to logs in HTML format, easily browsed with a standard
+ web browser. <c>Common Test</c> also sends notifications about progress
+ and results through an OTP event manager to event handlers plugged
+ in to the system. This way, users can integrate their own
+ programs for, for example, logging, database storing, or supervision with
+ <c>Common Test</c>.</p>
+
+ <p><c>Common Test</c> provides libraries with useful support
+ functions to fill various testing needs and requirements.
+ There is, for example, support for flexible test declarations
+ through test specifications. There is also support
+ for central configuration and control of multiple
+ independent test sessions (to different target systems)
+ running in parallel.</p>
+
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language.</p >
+ </section>
+
+</chapter>
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 472e3b7833..791be61066 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,6 +33,334 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.12.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The <c>nodelay</c> option used to be enabled
+ (<c>true</c>) by default for sockets opened by the Common
+ Test telnet client. This appeared to cause communication
+ problems with telnet servers on some systems, and
+ therefore the option is no longer used. Its value may
+ instead be specified in the telnet connection settings.
+ See the man page for <c>ct_telnet</c> for details. Please
+ note that the interface function <c>connect</c> in
+ <c>unix_telnet</c> has been updated with an extra
+ argument and is now <c>unix_telnet:connect/7</c>.</p>
+ <p>
+ Own Id: OTP-13462 Aux Id: seq13077 </p>
+ </item>
+ <item>
+ <p>
+ Fix bug in cth_surefire: When a pre_init_per_suite hook
+ fails before reaching the
+ cth_surefire:pre_init_per_suite, cth_surefire produced
+ incorrect XML.</p>
+ <p>
+ Own Id: OTP-13513</p>
+ </item>
+ <item>
+ <p>
+ The <c>ct:get_timetrap_info/0</c> function has been
+ updated to return more information about timetrap
+ scaling.</p>
+ <p>
+ Own Id: OTP-13535</p>
+ </item>
+ <item>
+ <p>
+ A problem with stylesheet HTML tags getting incorrectly
+ escaped by Common Test has been corrected.</p>
+ <p>
+ Own Id: OTP-13536</p>
+ </item>
+ <item>
+ <p>
+ The <c>ct_run</c> start flag <c>-no_esc_chars</c> and
+ <c>ct:run_test/1</c> start option <c>{esc_chars,Bool}</c>
+ have been introduced to make it possible to disable
+ automatic escaping of characters. Automatic escaping of
+ special HTML characters printed with <c>io:format/1,2</c>
+ and <c>ct:pal/1,2,3,4</c> was introduced in Common Test
+ 1.12. The new flag/option may be used to disable this
+ feature for backwards compatibility reasons. (The option
+ is also supported in test specifications).</p>
+ <p>
+ Own Id: OTP-13537</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ This update fixes the problem with generic printouts in
+ the html log file not having special characters escaped.
+ Printouts made with <c>io:format/2</c> and
+ <c>ct:pal/2</c> will now get special characters escaped
+ automatically. Common Test will not attempt to escape
+ characters printed with <c>ct:log/2</c> since it is
+ assumed that the user may want to print html tagged data
+ using this function. A new function, <c>ct:log/5</c>, has
+ been added, which offers optional escaping of characters.
+ The latter function may also be used to print text to the
+ log without headers and CSS class wrapping (analogue to
+ <c>io:format/2</c>).</p>
+ <p>
+ Own Id: OTP-13003 Aux Id: seq13005 </p>
+ </item>
+ <item>
+ <p>
+ Commit 4cf832f1ad163f5b25dd8a6f2d314c169c23c82f
+ erroneously removed logging of open and close of netconf
+ connections. This is now corrected.</p>
+ <p>
+ Own Id: OTP-13386</p>
+ </item>
+ <item>
+ <p>
+ The directory to which nodes started with
+ <c>test_server:start_node/3</c> writes their
+ erl_crash.dump is changed. The crashdumps were earlier
+ written to the directory of test_server.beam, but in
+ later versions of Microsoft Windows this is no longer
+ writable (even for administrators). The framework
+ (common_test) log directory is now used instead.</p>
+ <p>
+ Own Id: OTP-13388</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ This update makes it possible to specify multiple
+ instances of the same group or test case in one test
+ specification term in order to repeat execution. Example:
+ <c>{groups, "./", my_SUITE, [my_group, my_group], {cases,
+ all}}, or {cases, "./", my_SUITE, [my_tc, my_tc,
+ my_tc]}.</c></p>
+ <p>
+ Own Id: OTP-13241 Aux Id: seq12979 </p>
+ </item>
+ <item>
+ <p>
+ Two new CT hook functions have been added:
+ <c>post_init_per_testcase/4</c> and
+ <c>pre_end_per_testcase/3</c>. With these hook functions,
+ it is possible to perform arbitrary actions (including
+ modifications of test execution, test state and results)
+ immediately before and after the execution of the test
+ case.</p>
+ <p>
+ Own Id: OTP-13242 Aux Id: seq12991 </p>
+ </item>
+ <item>
+ <p>
+ The <c>ct_netconfc</c> was earlier very restrictive as to
+ which SSH options the user could set. This is now
+ changed, and any SSH option is now allowed. The netconf
+ client will simply pass on any option, which it does not
+ recognize, to SSH.</p>
+ <p>
+ Own Id: OTP-13338 Aux Id: seq13053,seq13069 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.11.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If a ssh package contained more than one netconf end tag,
+ then the second end tag was never detected in
+ ct_netconfc:handle_data. Instead it was included in the
+ XML data given to the xmerl parser, which then failed.
+ The problem was introduced by OTP-13007, and has now been
+ corrected.</p>
+ <p>
+ Own Id: OTP-13323</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.11.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When data from the netconf server was split into many ssh
+ packages, the netconf client performed really bad. This
+ is now improved.</p>
+ <p>
+ Own Id: OTP-13007</p>
+ </item>
+ <item>
+ <p>
+ In ct_netconfc, if a timer expired 'at the same time' as
+ the server sent the rpc-reply, the timeout message might
+ already be in the client's message queue when the client
+ removed the timer ref from its 'pending' list. This
+ caused a crash in the client since the timer ref could no
+ longer be found when handling the timeout message. This
+ problem is now fixed by always flushing the timeout
+ message from the message queue when canceling a timer.</p>
+ <p>
+ Own Id: OTP-13008</p>
+ </item>
+ <item>
+ <p>
+ The error logger handler ct_conn_log_h did not respect
+ the 'silent' option, and tried to print to an undefined
+ file descriptor. This has been corrected.</p>
+ <p>
+ Own Id: OTP-13035</p>
+ </item>
+ <item>
+ <p>
+ If the user would let the test run proceed after test
+ suite compilation failure, Common Test did not set the
+ exit status to indicate failure as expected. This has
+ been corrected. Also, the 'abort_if_missing_suites'
+ option now makes Common Test abort the test run without
+ asking the user if compilation fails, even if access to
+ stdin/stdout exists.</p>
+ <p>
+ Own Id: OTP-13173 Aux Id: seq12978 </p>
+ </item>
+ <item>
+ <p>
+ With the Common Test 'create_priv_dir' start option set
+ to 'auto_per_tc', the name of the priv directory for a
+ configuration function could clash with the name of the
+ priv directory for a test case, which would cause Test
+ Server failure. This error has been corrected.</p>
+ <p>
+ Own Id: OTP-13181</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The status of an aborted test due to test suite
+ compilation error has changed from 'auto_skipped' to
+ 'failed'. This affects both the textual log file, event
+ handling and CT hook callbacks. The logging of
+ compilation failures has also been improved, especially
+ in the case of multiple test suites failing compilation.</p>
+ <p>
+ Own Id: OTP-10816</p>
+ </item>
+ <item>
+ <p>
+ The Test Server source code parser (erl2html2) failed to
+ handle the macro tuple in the syntax tree returned by
+ epp_dodger. This error has been corrected.</p>
+ <p>
+ Own Id: OTP-12740</p>
+ </item>
+ <item>
+ <p>New options to make it possible to specify ssh_port in
+ a .spec file: [{node_start, [{ssh_port, 9999}]}].</p>
+ <p>And also to specify additional ssh options like paths
+ to public-key files: [{node_start, [{ssh_opts,
+ [{user_dir, "/home/shrek/e2/"}]}]}].</p>
+ <p>
+ Own Id: OTP-12809</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Earlier there was no way to add optional parameters like
+ default-operation to an edit-config request sent with
+ ct_netconfc:edit_config/3,4, you had to use
+ ct_netconfc:send_rpc/2,3. For simplicity and completion,
+ a new optional argument, OptParams, is now added to the
+ edit_config function.</p>
+ <p>
+ Own Id: OTP-10446 Aux Id: kunagi-266 [177] </p>
+ </item>
+ <item>
+ <p>
+ When running OTP tests using the ts interface, it is now
+ possible to specify so called test categories per OTP
+ application. A test category is represented by a CT test
+ specification and defines an arbitrary subset of existing
+ test suites, groups and cases. Examples of test
+ categories are 'smoke' (smoke tests) and 'bench'
+ (benchmarks). (Call ts:help() for more info). Also,
+ functions for reading terms from the current test
+ specification during test, ct:get_testspec_terms/0 and
+ ct:get_testspec_terms/1, have been implemented.</p>
+ <p>
+ Own Id: OTP-11962</p>
+ </item>
+ <item>
+ <p>
+ Obsolete scripts and make file operations have been
+ removed and the installation chapter in the Common Test
+ User's Guide has been updated.</p>
+ <p>
+ Own Id: OTP-12421</p>
+ </item>
+ <item>
+ <p>
+ The 'keep_alive' interval has been reduced to 8 seconds,
+ which is two seconds shorter than the default
+ 'idle_timeout' value for ct_telnet:expect/3. This way,
+ the telnet server receives a NOP message (which might
+ trigger an action) before the operation times out. Also
+ the TCP option 'nodelay' has been enabled per default for
+ all telnet connections, in order to reduce the risk for
+ communication timeouts.</p>
+ <p>
+ Own Id: OTP-12678 Aux Id: seq12818 </p>
+ </item>
+ <item>
+ <p>
+ When the ct_run program is executed without any flags,
+ "-dir ." is now used as default start flag. Similarly,
+ the option {dir,"."} is used by ct:run_test/1 if called
+ with an empty list. Also, the help text (ct_run -help)
+ has been updated, as well as the Running Tests chapter in
+ the Common Test User's Guide.</p>
+ <p>
+ Own Id: OTP-12684 Aux Id: seq12865 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.10.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -658,7 +987,7 @@
configuration function or test specification term), the
affected test cases get the status <c>user_skipped</c>
instead.</p> <p>This update has meant a few changes that
- may affect Common Test users in various ways: <list>
+ may affect Common Test users in various ways:</p> <list>
<item>The test results and statistics will be affected,
which is important to know when running regression tests
and comparing results to previous test runs.</item>
@@ -678,7 +1007,7 @@
<c>auto_skipped</c> rather than <c>user_skipped</c> as
before.</item> <item>The event messages that Common Test
generates during test runs have been affected by this
- update. For details see OTP-11524.</item> </list> </p>
+ update. For details see OTP-11524.</item> </list>
<p>
Own Id: OTP-11305 Aux Id: OTP-11524 </p>
</item>
@@ -729,7 +1058,7 @@
<item>
<p>The following modifications have been made to the
event messages that Common Test sends during test
- execution: <list> <item>For the <c>tc_auto_skip</c>
+ execution:</p> <list> <item>For the <c>tc_auto_skip</c>
event, the value of the <c>Func</c> element has changed
from <c>end_per_group</c> to
<c>{end_per_group,GroupName}</c>.</item> <item>When
@@ -741,7 +1070,7 @@
configuration name already in use, the <c>tc_done</c>
event now reports the error with a tuple (of size 2)
tagged <c>failed</c> instead of <c>skipped</c>.</item>
- </list> Please see the Event Handling chapter in the
+ </list> <p>Please see the Event Handling chapter in the
Common Test User's Guide for reference. </p>
<p>
Own Id: OTP-11524 Aux Id: OTP-11305 </p>
@@ -1145,7 +1474,6 @@
<item>
<p>
Some bugfixes in <c>ct_snmp:</c></p>
- <p>
<list> <item> ct_snmp will now use the value of the
'agent_vsns' config variable when setting the 'variables'
parameter to snmp application agent configuration.
@@ -1153,14 +1481,13 @@
supported versions had to be specified twice. </item>
<item> Snmp application failed to write notify.conf since
ct_snmp gave the notify type as a string instead of an
- atom. This has been corrected. </item> </list></p>
+ atom. This has been corrected. </item> </list>
<p>
Own Id: OTP-10432</p>
</item>
<item>
<p>
Some bugfixes in <c>ct_snmp</c>:</p>
- <p>
<list> <item> Functions <c>register_users/2</c>,
<c>register_agents/2</c> and <c>register_usm_users/2</c>,
and the corresponding <c>unregister_*/1</c> functions
@@ -1177,7 +1504,7 @@
priv_dir instead of in the configuration dir
(priv_dir/conf). This has been corrected. </item> <item>
Arguments to <c>register_usm_users/2</c> were faulty
- documented. This has been corrected. </item> </list></p>
+ documented. This has been corrected. </item> </list>
<p>
Own Id: OTP-10434 Aux Id: kunagi-264 [175] </p>
</item>
@@ -1241,7 +1568,7 @@
</item>
<item>
<p>
- Update common test modules to handle unicode <list>
+ Update common test modules to handle unicode:</p> <list>
<item> Use UTF-8 encoding for all HTML files, except the
HTML version of the test suite generated with
erl2html2:convert, which will have the same encoding as
@@ -1252,7 +1579,7 @@
unicode:characters_to_list and
unicode:characters_to_binary for conversion between
binaries and strings instead of binary_to_list and
- list_to_binary. </item> </list></p>
+ list_to_binary. </item> </list>
<p>
Own Id: OTP-10783</p>
</item>
@@ -1293,7 +1620,6 @@
<p>
The following corrections/changes are done in the
cth_surefire hook:</p>
- <p>
<list> <item> Earlier there would always be a
'properties' element under the 'testsuites' element. This
would exist even if there were no 'property' element
@@ -1326,7 +1652,7 @@
</item> <item> A new option named 'url_base' is added for
this hook. If this option is used, a new attribute named
'url' will be added to the 'testcase' and 'testsuite'
- elements. </item> </list></p>
+ elements. </item> </list>
<p>
Own Id: OTP-10589</p>
</item>
diff --git a/lib/common_test/doc/src/notes_history.xml b/lib/common_test/doc/src/notes_history.xml
index 34ac4fd15b..ecc0cab651 100644
--- a/lib/common_test/doc/src/notes_history.xml
+++ b/lib/common_test/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/common_test/doc/src/part.xml b/lib/common_test/doc/src/part.xml
index fe73918975..41e74e57c6 100644
--- a/lib/common_test/doc/src/part.xml
+++ b/lib/common_test/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,40 +31,9 @@
</header>
<description>
- <p><em>Common Test</em> is a portable application for automated
- testing. It is suitable for black-box testing of target
- systems of any type (i.e. not necessarily implemented in Erlang),
- as well as for white-box testing of Erlang/OTP programs.
- Black-box testing is performed via standard O&amp;M
- interfaces (such as SNMP, HTTP, Corba, Telnet, etc) and,
- if required, via user specific interfaces (often called test
- ports). White-box testing of Erlang/OTP programs is easily
- accomplished by calling the target API functions directly
- from the test case functions. Common Test also integrates
- usage of the OTP cover tool for code coverage analysis of
- Erlang/OTP programs.</p>
-
- <p>Common Test executes test suite programs automatically,
- without operator interaction. Test progress and results is
- printed to logs on HTML format, easily browsed with a standard
- web browser. Common Test also sends notifications about progress
- and results via an OTP event manager to event handlers plugged
- in to the system. This way users can integrate their own
- programs for e.g. logging, database storing or supervision with
- Common Test.</p>
-
- <p>Common Test provides libraries that contain useful support
- functions to fill various testing needs and requirements.
- There is for example support for flexible test declarations
- by means of so called test specifications. There is also support
- for central configuration and control of multiple
- independent test sessions (towards different target systems)
- running in parallel.</p>
-
- <p>Common Test is implemented as a framework based on the OTP Test
- Server application.</p>
</description>
+ <xi:include href="introduction.xml"/>
<xi:include href="basics_chapter.xml"/>
<xi:include href="getting_started_chapter.xml"/>
<xi:include href="install_chapter.xml"/>
diff --git a/lib/common_test/doc/src/part_notes.xml b/lib/common_test/doc/src/part_notes.xml
index 13ca499196..3d55d8152d 100644
--- a/lib/common_test/doc/src/part_notes.xml
+++ b/lib/common_test/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/common_test/doc/src/part_notes_history.xml b/lib/common_test/doc/src/part_notes_history.xml
index f995a70b7f..1e503ce536 100644
--- a/lib/common_test/doc/src/part_notes_history.xml
+++ b/lib/common_test/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/common_test/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml
index c266b70d00..19960bfea7 100644
--- a/lib/common_test/doc/src/ref_man.xml
+++ b/lib/common_test/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,43 +30,10 @@
<file>ref_man.xml</file>
</header>
<description>
- <p><em>Common Test</em> is a portable application for automated
- testing. It is suitable for black-box testing of target
- systems of any type (i.e. not necessarily implemented in Erlang),
- as well as for white-box testing of Erlang/OTP programs.
- Black-box testing is performed via standard O&amp;M
- interfaces (such as SNMP, HTTP, Corba, Telnet, etc) and,
- if required, via user specific interfaces (often called test
- ports). White-box testing of Erlang/OTP programs is easily
- accomplished by calling the target API functions directly
- from the test case functions. Common Test also integrates
- usage of the OTP cover tool for code coverage analysis of
- Erlang/OTP programs.</p>
-
- <p>Common Test executes test suite programs automatically,
- without operator interaction. Test progress and results is
- printed to logs on HTML format, easily browsed with a standard
- web browser. Common Test also sends notifications about progress
- and results via an OTP event manager to event handlers plugged
- in to the system. This way users can integrate their own
- programs for e.g. logging, database storing or supervision with
- Common Test.</p>
-
- <p>Common Test provides libraries that contain useful support
- functions to fill various testing needs and requirements.
- There is for example support for flexible test declarations
- by means of so called test specifications. There is also support
- for central configuration and control of multiple
- independent test sessions (towards different target systems)
- running in parallel.</p>
-
- <p>Common Test is implemented as a framework based on the OTP Test
- Server application.</p>
</description>
+
<xi:include href="common_test_app.xml"/>
<xi:include href="ct_run.xml"/>
- <!-- If you make modifications in the module list below,
- you also need to update CT_MODULES in Makefile. -->
<xi:include href="ct.xml"/>
<xi:include href="ct_master.xml"/>
<xi:include href="ct_cover.xml"/>
@@ -82,6 +50,3 @@
</application>
-
-
-
diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml
index 864f82cb63..e5e217ca1d 100644
--- a/lib/common_test/doc/src/run_test_chapter.xml
+++ b/lib/common_test/doc/src/run_test_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,95 +33,96 @@
<section>
<title>Using the Common Test Framework</title>
- <p>The Common Test Framework provides a high level
- operator interface for testing. It adds the following features to
- the Erlang/OTP Test Server:</p>
+ <p>The <c>Common Test</c> framework provides a high-level
+ operator interface for testing, providing the following features:</p>
- <list>
- <item>Automatic compilation of test suites (and help modules).</item>
- <item>Creation of additional HTML pages for better overview.</item>
- <item>Single command interface for running all available tests.</item>
+ <list type="bulleted">
+ <item>Automatic compilation of test suites (and help modules)</item>
+ <item>Creation of extra HTML pages for improved overview.</item>
+ <item>Single-command interface for running all available tests</item>
<item>Handling of configuration files specifying data related to
- the System Under Test (and any other variable data).</item>
+ the System Under Test (SUT) (and any other variable data)</item>
<item>Mode for running multiple independent test sessions in parallel with
- central control and configuration.</item>
+ central control and configuration</item>
</list>
</section>
<section>
- <title>Automatic compilation of test suites and help modules</title>
- <p>When Common Test starts, it will automatically attempt to compile any
+ <title>Automatic Compilation of Test Suites and Help Modules</title>
+ <p>When <c>Common Test</c> starts, it automatically attempts to compile any
suites included in the specified tests. If particular
- suites have been specified, only those suites will be compiled. If a
- particular test object directory has been specified (meaning all suites
- in this directory should be part of the test), Common Test runs
- make:all/1 in the directory to compile the suites.</p>
+ suites are specified, only those suites are compiled. If a
+ particular test object directory is specified (meaning all suites
+ in this directory are to be part of the test), <c>Common Test</c> runs
+ function <c>make:all/1</c> in the directory to compile the suites.</p>
- <p>If compilation should fail for one or more suites, the compilation errors
- are printed to tty and the operator is asked if the test run should proceed
+ <p>If compilation fails for one or more suites, the compilation errors
+ are printed to tty and the operator is asked if the test run is to proceed
without the missing suites, or be aborted. If the operator chooses to proceed,
- it is noted in the HTML log which tests have missing suites. If Common Test is
- unable to prompt the user after compilation failure (if Common Test doesn't
- control stdin), the test run will proceed automatically without the missing
- suites. This behaviour can however be modified with the
+ the tests having missing suites are noted in the HTML log. If <c>Common Test</c> is
+ unable to prompt the user after compilation failure (if <c>Common Test</c> does not
+ control <c>stdin</c>), the test run proceeds automatically without the missing
+ suites. This behavior can however be modified with the
<c><![CDATA[ct_run]]></c> flag <c><![CDATA[-abort_if_missing_suites]]></c>,
- or the <c><![CDATA[ct:run_test/1]]></c> option
+ or the <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> option
<c><![CDATA[{abort_if_missing_suites,TrueOrFalse}]]></c>. If
- <c><![CDATA[abort_if_missing_suites]]></c> is set (to true), the test run
- will stop immediately if some suites fail to compile.</p>
-
- <p>Any help module (i.e. regular Erlang module with name not ending with
- "_SUITE") that resides in the same test object directory as a suite
- which is part of the test, will also be automatically compiled. A help
- module will not be mistaken for a test suite (unless it has a "_SUITE"
- name of course). All help modules in a particular test object directory
- are compiled no matter if all or only particular suites in the directory
+ <c><![CDATA[abort_if_missing_suites]]></c> is set to <c>true</c>, the test run
+ stops immediately if some suites fail to compile.</p>
+
+ <p>Any help module (that is, regular Erlang module with name not ending with
+ "_SUITE") that resides in the same test object directory as a suite,
+ which is part of the test, is also automatically compiled. A help
+ module is not mistaken for a test suite (unless it has a "_SUITE" name).
+ All help modules in a particular test object directory
+ are compiled, no matter if all or only particular suites in the directory
are part of the test.</p>
<p>If test suites or help modules include header files stored in other
- locations than the test directory, you may specify these include directories
- by means of the <c><![CDATA[-include]]></c> flag with <c><![CDATA[ct_run]]></c>,
- or the <c><![CDATA[include]]></c> option with <c><![CDATA[ct:run_test/1]]></c>.
- In addition to this, an include path may be specified with an OS
- environment variable; <c><![CDATA[CT_INCLUDE_PATH]]></c>. Example (bash):</p>
+ locations than the test directory, these include directories can be specified
+ by using flag <c><![CDATA[-include]]></c> with
+ <seealso marker="ct_run"><c>ct_run</c></seealso>,
+ or option <c><![CDATA[include]]></c> with <c><![CDATA[ct:run_test/1]]></c>.
+ Also, an include path can be specified with an OS
+ environment variable, <c><![CDATA[CT_INCLUDE_PATH]]></c>.</p>
+ <p><em>Example (bash):</em></p>
<p><c>$ export CT_INCLUDE_PATH=~testuser/common_suite_files/include:~testuser/common_lib_files/include</c></p>
- <p>Common Test will pass all include directories (specified either with the
- <c><![CDATA[include]]></c> flag/option, or the <c><![CDATA[CT_INCLUDE_PATH]]></c>
- variable, or both) to the compiler.</p>
+ <p><c>Common Test</c> passes all include directories (specified either with flag/option
+ <c><![CDATA[include]]></c>, or variable <c><![CDATA[CT_INCLUDE_PATH]]></c>
+ , or both, to the compiler.</p>
- <p>It is also possible to specify include directories in test specifications
- (see below).</p>
+ <p>Include directories can also be specified in test specifications,
+ see <seealso marker="#test_specifications">Test Specifications</seealso>.</p>
- <p>If the user wants to run all test suites for a test object (or OTP application)
- by specifying only the top directory (e.g. with the <c>dir</c> start flag/option),
- Common Test will primarily look for test suite modules in a subdirectory named
- <c>test</c>. If this subdirectory doesn't exist, the specified top directory
- is assumed to be the actual test directory, and test suites will be read from
+ <p>If the user wants to run all test suites for a test object (or an OTP application)
+ by specifying only the top directory (for example, with start flag/option <c>dir</c>),
+ <c>Common Test</c> primarily looks for test suite modules in a subdirectory named
+ <c>test</c>. If this subdirectory does not exist, the specified top directory
+ is assumed to be the test directory, and test suites are read from
there instead.</p>
- <p>It is possible to disable the automatic compilation feature by using the
- <c><![CDATA[-no_auto_compile]]></c> flag with <c><![CDATA[ct_run]]></c>, or
- the <c><![CDATA[{auto_compile,false}]]></c> option with
+ <p>To disable the automatic compilation feature, use flag
+ <c><![CDATA[-no_auto_compile]]></c> with <c><![CDATA[ct_run]]></c>, or
+ option <c><![CDATA[{auto_compile,false}]]></c> with
<c><![CDATA[ct:run_test/1]]></c>. With automatic compilation
disabled, the user is responsible for compiling the test suite modules
- (and any help modules) before the test run. If the modules can not be loaded
- from the local file system during startup of Common Test, the user needs to
- pre-load the modules before starting the test. Common Test will only verify
- that the specified test suites exist (i.e. that they are, or can be, loaded).
- This is useful e.g. if the test suites are transferred and loaded as binaries via
- RPC from a remote node.</p>
+ (and any help modules) before the test run. If the modules cannot be loaded
+ from the local file system during startup of <c>Common Test</c>, the user must
+ preload the modules before starting the test. <c>Common Test</c> only verifies
+ that the specified test suites exist (that is, that they are, or can be, loaded).
+ This is useful, for example, if the test suites are transferred and loaded as
+ binaries through RPC from a remote node.</p>
</section>
<section>
<marker id="ct_run"></marker>
- <title>Running tests from the OS command line</title>
+ <title>Running Tests from the OS Command Line</title>
- <p>The <c>ct_run</c> program can be used for running tests from
- the OS command line, e.g.
+ <p>The <seealso marker="ct_run"><c>ct_run</c></seealso> program can be used
+ for running tests from the OS command line, for example, as follows:
</p>
- <list>
+ <list type="bulleted">
<item><c><![CDATA[ct_run -config <configfilenames> -dir <dirs>]]></c></item>
<item><c><![CDATA[ct_run -config <configfilenames> -suite <suiteswithfullpath>]]></c>
</item>
@@ -129,816 +131,924 @@
<item><c><![CDATA[ct_run -config <configfilenames> -suite <suitewithfullpath>
-group <groups> -case <casenames>]]></c></item>
</list>
- <p>Examples:</p>
- <p><c>$ ct_run -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST</c></p>
- <p><c>$ ct_run -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST</c></p>
- <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE</c></p>
- <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE -case start stop</c></p>
- <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</c></p>
+ <p><em>Examples:</em></p>
+ <pre>
+ $ ct_run -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST
+ $ ct_run -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST
+ $ ct_run -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE
+ $ ct_run -suite $SYS1_TEST/setup_SUITE -case start stop
+ $ ct_run -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</pre>
- <p>It is also possible to combine the <c>dir</c>, <c>suite</c> and <c>group/case</c> flags. E.g, to run
- <c>x_SUITE</c> and <c>y_SUITE</c> in directory <c>testdir</c>:</p>
-
- <p><c>$ ct_run -dir ./testdir -suite x_SUITE y_SUITE</c></p>
-
- <p>This has the same effect as calling:</p>
-
- <p><c>$ ct_run -suite ./testdir/x_SUITE ./testdir/y_SUITE</c></p>
-
- <p>For more details on <seealso marker="run_test_chapter#group_execution">test case group execution</seealso>, please see below.</p>
-
- <p>Other flags that may be used with <c>ct_run</c>:</p>
- <list>
- <item><c><![CDATA[-logdir <dir>]]></c>, specifies where the HTML log files are to be written.</item>
- <item><c><![CDATA[-label <name_of_test_run>]]></c>, associates the test run with a name that gets printed
- in the overview HTML log files.</item>
- <item><c>-refresh_logs</c>, refreshes the top level HTML index files.</item>
- <item><c>-vts</c>, start web based GUI (see below).</item>
- <item><c>-shell</c>, start interactive shell mode (see below).</item>
- <item><c>-step [step_opts]</c>, step through test cases using the Erlang Debugger (see below).</item>
- <item><c><![CDATA[-spec <testspecs>]]></c>, use test specification as input (see below).</item>
- <item><c>-allow_user_terms</c>, allows user specific terms in a test specification (see below).</item>
- <item><c>-silent_connections [conn_types]</c>, tells Common Test to suppress printouts for
- specified connections (see below).</item>
- <item><c><![CDATA[-stylesheet <css_file>]]></c>, points out a user HTML style sheet (see below).</item>
- <item><c><![CDATA[-cover <cover_cfg_file>]]></c>, to perform code coverage test (see
- <seealso marker="cover_chapter#cover">Code Coverage Analysis</seealso>).</item>
- <item><c><![CDATA[-cover_stop <bool>]]></c>, to specify if the cover tool shall be stopped after the test is completed (see
- <seealso marker="cover_chapter#cover_stop">Code Coverage Analysis</seealso>).</item>
- <item><c><![CDATA[-event_handler <event_handlers>]]></c>, to install
- <seealso marker="event_handler_chapter#event_handling">event handlers</seealso>.</item>
- <item><c><![CDATA[-event_handler_init <event_handlers>]]></c>, to install
- <seealso marker="event_handler_chapter#event_handling">event handlers</seealso> including start arguments.</item>
- <item><c><![CDATA[-ct_hooks <ct_hooks>]]></c>, to install
- <seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso> including start arguments.</item>
- <item><c><![CDATA[-enable_builtin_hooks <bool>]]></c>, to enable/disable
- <seealso marker="ct_hooks_chapter#builtin_cths">Built-in Common Test Hooks</seealso>. Default is <c>true</c>.</item>
- <item><c><![CDATA[-include]]></c>, specifies include directories (see above).</item>
- <item><c><![CDATA[-no_auto_compile]]></c>, disables the automatic test suite compilation feature (see above).</item>
- <item><c><![CDATA[-abort_if_missing_suites]]></c>, aborts the test run if one or more suites fail to compile (see above).</item>
- <item><c><![CDATA[-multiply_timetraps <n>]]></c>, extends <seealso marker="write_test_chapter#timetraps">timetrap
- timeout</seealso> values.</item>
- <item><c><![CDATA[-scale_timetraps <bool>]]></c>, enables automatic <seealso marker="write_test_chapter#timetraps">timetrap
- timeout</seealso> scaling.</item>
- <item><c><![CDATA[-repeat <n>]]></c>, tells Common Test to repeat the tests n times (see below).</item>
- <item><c><![CDATA[-duration <time>]]></c>, tells Common Test to repeat the tests for duration of time (see below).</item>
- <item><c><![CDATA[-until <stop_time>]]></c>, tells Common Test to repeat the tests until stop_time (see below).</item>
- <item><c>-force_stop [skip_rest]</c>, on timeout, the test run will be aborted when current test job is finished. If <c>skip_rest</c> is provided the rest of the test cases in the current test job will be skipped (see below).</item>
- <item><c><![CDATA[-decrypt_key <key>]]></c>, provides a decryption key for
- <seealso marker="config_file_chapter#encrypted_config_files">encrypted configuration files</seealso>.</item>
- <item><c><![CDATA[-decrypt_file <key_file>]]></c>, points out a file containing a decryption key for
- <seealso marker="config_file_chapter#encrypted_config_files">encrypted configuration files</seealso>.</item>
- <item><c><![CDATA[-basic_html]]></c>, switches off html enhancements that might not be compatible with older browsers.</item>
- <item><c><![CDATA[-logopts <opts>]]></c>, makes it possible to modify aspects of the logging behaviour, see
- <seealso marker="run_test_chapter#logopts">Log options</seealso> below.</item>
- <item><c><![CDATA[-verbosity <levels>]]></c>, sets <seealso marker="write_test_chapter#logging">verbosity levels
- for printouts</seealso>.</item>
- </list>
+ <p>The flags <c>dir</c>, <c>suite</c>, and <c>group/case</c> can be combined.
+ For example, to run <c>x_SUITE</c> and <c>y_SUITE</c>
+ in directory <c>testdir</c>, as follows:</p>
+ <pre>
+ $ ct_run -dir ./testdir -suite x_SUITE y_SUITE</pre>
+
+ <p>This has the same effect as the following:</p>
+ <pre>
+ $ ct_run -suite ./testdir/x_SUITE ./testdir/y_SUITE</pre>
+
+ <p>For details, see
+ <seealso marker="run_test_chapter#group_execution">Test Case Group Execution</seealso>.</p>
+
+ <p>The following flags can also be used with
+ <seealso marker="ct_run"><c>ct_run</c></seealso>:</p>
+ <taglist>
+ <tag><c><![CDATA[-help]]></c></tag>
+ <item><p>Lists all available start flags.</p></item>
+
+ <tag><c><![CDATA[-logdir <dir>]]></c></tag>
+ <item><p>Specifies where the HTML log files are to be written.</p></item>
+
+ <tag><c><![CDATA[-label <name_of_test_run>]]></c></tag>
+ <item><p>Associates the test run with a name that gets printed
+ in the overview HTML log files.</p></item>
+
+ <tag><c>-refresh_logs</c></tag>
+ <item><p>Refreshes the top-level HTML index files.</p></item>
+
+ <tag><c>-vts</c></tag>
+ <item><p>Starts web-based GUI (described later).</p></item>
+
+ <tag><c>-shell</c></tag>
+ <item><p>Starts interactive shell mode (described later).</p></item>
+
+ <tag><c>-step [step_opts]</c></tag>
+ <item><p>Steps through test cases using the Erlang Debugger (described later).</p></item>
+
+ <tag><c><![CDATA[-spec <testspecs>]]></c></tag>
+ <item><p>Uses test specification as input (described later).</p></item>
+
+ <tag><c>-allow_user_terms</c></tag>
+ <item><p>Allows user-specific terms in a test specification (described later).</p></item>
+
+ <tag><c>-silent_connections [conn_types]</c></tag>
+ <item><p>, tells <c>Common Test</c> to suppress printouts for
+ specified connections (described later).</p></item>
+
+ <tag><c><![CDATA[-stylesheet <css_file>]]></c></tag>
+ <item><p>Points out a user HTML style sheet (described later).</p></item>
+
+ <tag><c><![CDATA[-cover <cover_cfg_file>]]></c></tag>
+ <item><p>To perform code coverage test (see
+ <seealso marker="cover_chapter#cover">Code Coverage Analysis</seealso>).</p></item>
+
+ <tag><c><![CDATA[-cover_stop <bool>]]></c></tag>
+ <item><p>To specify if the <c>cover</c> tool is to be stopped
+ after the test is completed (see
+ <seealso marker="cover_chapter#cover_stop">Code Coverage Analysis</seealso>).</p></item>
+
+ <tag><c><![CDATA[-event_handler <event_handlers>]]></c></tag>
+ <item><p>To install
+ <seealso marker="event_handler_chapter#event_handling">event handlers</seealso>.</p></item>
+
+ <tag><c><![CDATA[-event_handler_init <event_handlers>]]></c></tag>
+ <item><p>To install
+ <seealso marker="event_handler_chapter#event_handling">event handlers</seealso>
+ including start arguments.</p></item>
+
+ <tag><c><![CDATA[-ct_hooks <ct_hooks>]]></c></tag>
+ <item><p>To install
+ <seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso>
+ including start arguments.</p></item>
+
+ <tag><c><![CDATA[-enable_builtin_hooks <bool>]]></c></tag>
+ <item><p>To enable or disable
+ <seealso marker="ct_hooks_chapter#builtin_cths">Built-in Common Test Hooks</seealso>.
+ Default is <c>true</c>.</p></item>
- <note><p>Directories passed to Common Test may have either relative or absolute paths.</p></note>
+ <tag><c><![CDATA[-include]]></c></tag>
+ <item><p>Specifies include directories (described earlier).</p></item>
- <note><p>Arbitrary start flags to the Erlang Runtime System may also be passed as
+ <tag><c><![CDATA[-no_auto_compile]]></c></tag>
+ <item><p>Disables the automatic test suite compilation feature (described earlier).</p></item>
+
+ <tag><c><![CDATA[-abort_if_missing_suites]]></c></tag>
+ <item><p>Aborts the test run if one or more suites fail to compile (described earlier).</p></item>
+
+ <tag><c><![CDATA[-multiply_timetraps <n>]]></c></tag>
+ <item><p>Extends <seealso marker="write_test_chapter#timetraps">timetrap
+ time-out</seealso> values.</p></item>
+
+ <tag><c><![CDATA[-scale_timetraps <bool>]]></c></tag>
+ <item><p>Enables automatic <seealso marker="write_test_chapter#timetraps">timetrap
+ time-out</seealso> scaling.</p></item>
+
+ <tag><c><![CDATA[-repeat <n>]]></c></tag>
+ <item><p>Tells <c>Common Test</c> to repeat the tests <c>n</c> times (described later).</p></item>
+
+ <tag><c><![CDATA[-duration <time>]]></c></tag>
+ <item><p>Tells <c>Common Test</c> to repeat the tests for duration of time (described later).</p></item>
+
+ <tag><c><![CDATA[-until <stop_time>]]></c></tag>
+ <item><p>Tells <c>Common Test</c> to repeat the tests until <c>stop_time</c> (described later).</p></item>
+
+ <tag><c>-force_stop [skip_rest]</c></tag>
+ <item><p>On time-out, the test run is aborted when the current test job is finished. If <c>skip_rest</c>
+ is provided, the remaining test cases in the current test job are skipped (described later).</p></item>
+
+ <tag><c><![CDATA[-decrypt_key <key>]]></c></tag>
+ <item><p>Provides a decryption key for
+ <seealso marker="config_file_chapter#encrypted_config_files">encrypted configuration files</seealso>.</p></item>
+
+ <tag><c><![CDATA[-decrypt_file <key_file>]]></c></tag>
+ <item><p>Points out a file containing a decryption key for
+ <seealso marker="config_file_chapter#encrypted_config_files">encrypted configuration files</seealso>.</p></item>
+
+ <tag><c><![CDATA[-basic_html]]></c></tag>
+ <item><p>Switches off HTML enhancements that can be incompatible with older browsers.</p></item>
+
+ <tag><c><![CDATA[-logopts <opts>]]></c></tag>
+ <item><p>Enables modification of the logging behavior, see
+ <seealso marker="run_test_chapter#logopts">Log options</seealso>.</p></item>
+
+ <tag><c><![CDATA[-verbosity <levels>]]></c></tag>
+ <item><p>Sets <seealso marker="write_test_chapter#logging">verbosity levels
+ for printouts</seealso>.</p></item>
+
+ <tag><c><![CDATA[-no_esc_chars]]></c></tag>
+ <item><p>Disables automatic escaping of special HTML characters.
+ See the <seealso marker="write_test_chapter#logging">Logging chapter</seealso>.</p></item>
+ </taglist>
+
+ <note><p>Directories passed to <c>Common Test</c> can have either relative or absolute paths.</p></note>
+
+ <note><p>Any start flags to the Erlang runtime system (application <c>ERTS</c>) can also be passed as
parameters to <c>ct_run</c>. It is, for example, useful to be able to
- pass directories that should be added to the Erlang code server search path
- with the <c>-pa</c> or <c>-pz</c> flag. If you have common help- or library
+ pass directories to be added to the Erlang code server search path
+ with flag <c>-pa</c> or <c>-pz</c>. If you have common help- or library
modules for test suites (separately compiled), stored in other directories
- than the test suite directories, these help/lib directories are preferrably
- added to the code path this way. Example:</p>
+ than the test suite directories, these <c>help/lib</c> directories are preferably
+ added to the code path this way.</p>
+ <p><em>Example:</em></p>
<p><c>$ ct_run -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin</c></p>
- <p>Note how in this example, the absolute path of the <c>chat_server/ebin</c>
- directory is passed to the code server. This is essential since relative
- paths are stored by the code server as relative, and Common Test changes
- the current working directory of the Erlang Runtime System during the test run!</p>
+ <p>The absolute path of directory <c>chat_server/ebin</c>
+ is here passed to the code server. This is essential because relative
+ paths are stored by the code server as relative, and <c>Common Test</c> changes
+ the current working directory of <c>ERTS</c> during the test run.</p>
</note>
<p>The <c>ct_run</c> program sets the exit status before shutting down. The following values
are defined:</p>
- <list>
- <item><c>0</c> indicates a successful testrun, i.e. one without failed or auto skipped test cases.</item>
- <item><c>1</c> indicates that one or more test cases have failed, or have been auto skipped.</item>
- <item><c>2</c> indicates that the test execution has failed because of e.g. compilation errors, an
- illegal return value from an info function, etc.</item>
+ <list type="bulleted">
+ <item><c>0</c> indicates a successful testrun, that is, without failed or auto-skipped test cases.</item>
+ <item><c>1</c> indicates that one or more test cases have failed, or have been auto-skipped.</item>
+ <item><c>2</c> indicates that the test execution has failed because of, for example, compilation errors, or an
+ illegal return value from an information function.</item>
</list>
- <p>If auto skipped test cases should not affect the exit status, you may change the default
- behaviour using start flag:</p>
- <pre>-exit_status ignore_config</pre>
+ <p>If auto-skipped test cases do not affect the exit status. The default
+ behavior can be changed using start flag:</p>
+ <pre>
+ -exit_status ignore_config</pre>
- <p>For more information about the <c>ct_run</c> program, see the
- <seealso marker="ct_run">Reference Manual</seealso> and the
- <seealso marker="install_chapter#general">Installation</seealso> chapter.
+ <note><p>Executing <c>ct_run</c> without start flags is equal to the command:
+ <c>ct_run -dir ./</c></p></note>
+
+ <p>For more information about the <c>ct_run</c> program, see module
+ <seealso marker="ct_run"><c>ct_run</c></seealso> and section
+ <seealso marker="install_chapter#general">Installation</seealso>.
</p>
</section>
<section>
- <title>Running tests from the Erlang shell or from an Erlang program</title>
+ <marker id="erlang_shell_or_program"></marker>
+ <title>Running Tests from the Erlang Shell or from an Erlang Program</title>
- <p>Common Test provides an Erlang API for running tests. The main (and most
- flexible) function for specifying and executing tests is called
+ <p><c>Common Test</c> provides an Erlang API for running tests. The main
+ (and most flexible) function for specifying and executing tests is
<seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>.
- This function takes the same start parameters as
- the <seealso marker="run_test_chapter#ct_run"><c>ct_run</c></seealso>
- program described above, only the flags are instead
- given as options in a list of key-value tuples. E.g. a test specified
- with <c>ct_run</c> like:</p>
+ It takes the same start parameters as
+ <seealso marker="run_test_chapter#ct_run"><c>ct_run</c></seealso>,
+ but the flags are instead specified as options in a list of key-value tuples.
+ For example, a test specified with <c>ct_run</c> as follows:</p>
<p><c>$ ct_run -suite ./my_SUITE -logdir ./results</c></p>
<p>is with <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> specified as:</p>
<p><c>1> ct:run_test([{suite,"./my_SUITE"},{logdir,"./results"}]).</c></p>
- <p>The function returns the test result, represented by the tuple:
+ <p>The function returns the test result, represented by the tuple
<c>{Ok,Failed,{UserSkipped,AutoSkipped}}</c>, where each element is an
- integer. If test execution fails, the function returns the tuple:
+ integer. If test execution fails, the function returns the tuple
<c>{error,Reason}</c>, where the term <c>Reason</c> explains the
failure.</p>
+ <p>The default start option <c>{dir,Cwd}</c> (to run all suites in the current
+ working directory) is used if the function is called with an empty
+ list of options.</p>
+
<section>
- <title>Releasing the Erlang shell</title>
- <p>During execution of tests, started with
+ <title>Releasing the Erlang Shell</title>
+ <p>During execution of tests started with
<seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>,
- the Erlang shell process, controlling stdin, will remain the top
- level process of the Common Test system of processes. The result
- is that the Erlang shell is not available for interaction during
- the test run. If this is not desirable, maybe because the shell is needed
- for debugging purposes or for interaction with the SUT during test
- execution, you may set the <c>release_shell</c> start option to
+ the Erlang shell process, controlling <c>stdin</c>, remains the top-level
+ process of the <c>Common Test</c> system of processes. Consequently,
+ the Erlang shell is not available for interaction during
+ the test run. If this is not desirable, for example, because the shell
+ is needed for debugging purposes or for interaction with the SUT during test
+ execution, set start option <c>release_shell</c> to
<c>true</c> (in the call to <c>ct:run_test/1</c> or by
- using the corresponding test specification term, see below). This will
- make Common Test release the shell immediately after the test suite
+ using the corresponding test specification term, described later). This
+ makes <c>Common Test</c> release the shell immediately after the test suite
compilation stage. To accomplish this, a test runner process
- is spawned to take control of the test execution, and the effect is that
+ is spawned to take control of the test execution. The effect is that
<c>ct:run_test/1</c> returns the pid of this process rather than the
- test result - which instead is printed to tty at the end of the test run.</p>
- <note><p>Note that in order to use the
- <seealso marker="ct#break-1"><c>ct:break/1/2</c></seealso> and
- <seealso marker="ct#continue-0"><c>ct:continue/0/1</c></seealso> functions,
+ test result, which instead is printed to tty at the end of the test run.</p>
+ <note><p>To use the functions
+ <seealso marker="ct#break-1"><c>ct:break/1,2</c></seealso> and
+ <seealso marker="ct#continue-0"><c>ct:continue/0,1</c></seealso>,
<c>release_shell</c> <em>must</em> be set to <c>true</c>.</p></note>
</section>
- <p>For detailed documentation about
- <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>,
- please see the
- <seealso marker="ct#run_test-1"><c>ct</c></seealso> manual page.</p>
+ <p>For details, see
+ <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> manual page.</p>
</section>
<section>
<marker id="group_execution"></marker>
- <title>Test case group execution</title>
+ <title>Test Case Group Execution</title>
<p>With the <c>ct_run</c> flag, or <c>ct:run_test/1</c> option <c>group</c>,
one or more test case groups can be specified, optionally in combination
- with specific test cases. The syntax for specifying groups is as follows
- (on the command line):</p>
+ with specific test cases. The syntax for specifying groups on the command line
+ is as follows:</p>
<pre>
- <![CDATA[$ ct_run -group <group_names_or_paths> [-case <cases>]]]></pre>
- <p>or (in the Erlang shell):</p>
+ <![CDATA[$ ct_run -group <group_names_or_paths> [-case <cases>]]]></pre>
+ <p>The syntax in the Erlang shell is as follows:</p>
<pre>
- <![CDATA[1> ct:run_test([{group,GroupsNamesOrPaths}, {case,Cases}]).]]></pre>
+ <![CDATA[1> ct:run_test([{group,GroupsNamesOrPaths}, {case,Cases}]).]]></pre>
- <p>The <c>group_names_or_paths</c> parameter specifies either one
- or more group names and/or one or more group paths. At start up,
- Common Test will search for matching groups in the group definitions
- tree (i.e. the list returned from <c>Suite:groups/0</c>, please see the
- <seealso marker="write_test_chapter#test_case_groups">Test case groups</seealso>
- chapter for details).
- Given a group name, say <c>g</c>, Common Test will search for all paths
- that lead to <c>g</c>. By path here we mean a sequence of nested groups,
- all of which have to be followed in order to get from the top level
- group to <c>g</c>. Actually, what Common Test needs to do in order to
- execute the test cases in group <c>g</c>, is to call the
- <c>init_per_group/2</c> function for each group in the path to
- <c>g</c>, as well as all corresponding <c>end_per_group/2</c>
- functions afterwards. The obvious reason for this is that the configuration
+ <p>Parameter <c>group_names_or_paths</c> specifies one
+ or more group names and/or one or more group paths. At startup,
+ <c>Common Test</c> searches for matching groups in the group definitions
+ tree (that is, the list returned from <c>Suite:groups/0</c>; for details, see section
+ <seealso marker="write_test_chapter#test_case_groups">Test Case Groups</seealso>.
+ </p>
+
+ <p>Given a group name, say <c>g</c>, <c>Common Test</c> searches for all paths
+ leading to <c>g</c>. By path is meant a sequence of nested groups,
+ which must be followed to get from the top-level
+ group to <c>g</c>. To execute the test cases in group <c>g</c>,
+ <c>Common Test</c> must call the <c>init_per_group/2</c> function for
+ each group in the path to <c>g</c>, and all corresponding <c>end_per_group/2</c>
+ functions afterwards. This is because the configuration
of a test case in <c>g</c> (and its <c>Config</c> input data) depends on
<c>init_per_testcase(TestCase, Config)</c> and its return value, which
in turn depends on <c>init_per_group(g, Config)</c> and its return value,
which in turn depends on <c>init_per_group/2</c> of the group above
- <c>g</c>, etc, all the way up to the top level group.</p>
+ <c>g</c>, and so on, all the way up to the top-level group.</p>
- <p>As you may have already realized, this means that if there is more than
- one way to locate a group (and its test cases) in a path, the result of the
- group search operation is a number of tests, all of which will be performed.
- Common Test actually interprets a group specification that consists of a
- single name this way:</p>
+ <p>This means that if there is more than one way to locate a group
+ (and its test cases) in a path, the result of the group search operation
+ is a number of tests, all of which are to be performed.
+ <c>Common Test</c> interprets a group specification that consists of a
+ single name as follows:</p>
<p>"Search and find all paths in the group definitions tree that lead
- to the specified group and, for each path, create a test which (1) executes
- all configuration functions in the path to the specified group, then (2)
- executes all - or all matching - test cases in this group, as well as (3)
- all - or all matching - test cases in all sub groups of the group".
- </p>
+ to the specified group and, for each path, create a test that does the following,
+ in order:</p>
+ <list type="ordered">
+ <item>Executes all configuration functions in the path to the specified group.</item>
+ <item>Executes all, or all matching, test cases in this group.</item>
+ <item>Executes all, or all matching, test cases in all subgroups of the group."</item>
+ </list>
- <p>It is also possible for the user to specify a specific group path with
- the <c>group_names_or_paths</c> parameter. With this type of specification it's
- possible to avoid execution of unwanted groups (in otherwise matching paths),
- and/or the execution of sub groups. The syntax of the group path is a list of
- group names in the path, e.g. on the command line:
+ <p>The user can specify a specific group path with
+ parameter <c>group_names_or_paths</c>. With this type of specification
+ execution of unwanted groups (in otherwise matching paths),
+ and/or the execution of subgroups can be avoided. The command line syntax of the
+ group path is a list of group names in the path, for example:
</p>
<p><c>$ ct_run -suite "./x_SUITE" -group [g1,g3,g4] -case tc1 tc5</c></p>
- <p>or similarly in the Erlang shell (requires a list within the groups list):</p>
+ <p>The syntax in the Erlang shell is as follows (requires a list within the groups list):</p>
<p><c>1> ct:run_test([{suite,"./x_SUITE"}, {group,[[g1,g3,g4]]}, {testcase,[tc1,tc5]}]).</c></p>
- <p>The last group in the specified path will be the terminating group in
- the test, i.e. no sub groups following this group will be executed. In the
- example above, <c>g4</c> is the terminating group, hence Common Test will
- execute a test that calls all init configuration functions in the path to
- <c>g4</c>, i.e. <c>g1..g3..g4</c>. It will then call test cases <c>tc1</c>
- and <c>tc5</c> in <c>g4</c> and finally all end configuration functions in order
- <c>g4..g3..g1</c>.</p>
+ <p>The last group in the specified path is the terminating group in
+ the test, that is, no subgroups following this group are executed. In the
+ previous example, <c>g4</c> is the terminating group. Hence, <c>Common Test</c>
+ executes a test that calls all <c>init</c> configuration functions in the path to
+ <c>g4</c>, that is, <c>g1..g3..g4</c>. It then calls test cases <c>tc1</c>
+ and <c>tc5</c> in <c>g4</c>, and finally all <c>end</c> configuration functions
+ in order <c>g4..g3..g1</c>.</p>
- <p>Note that the group path specification doesn't necessarily
+ <note><p>The group path specification does not necessarily
have to include <em>all</em> groups in the path to the terminating group.
- Common Test will search for all matching paths if given an incomplete group
- path.</p>
+ <c>Common Test</c> searches for all matching paths if an incomplete
+ group path is specified.</p></note>
- <p>Note also that it's possible to combine group names and group paths with the
- <c>group_names_or_paths</c> parameter. Each element is treated as
- an individual specification in combination with the <c>cases</c> parameter.
- See examples below.</p>
+ <note><p>Group names and group paths can be combined with parameter
+ <c>group_names_or_paths</c>. Each element is treated as an individual specification
+ in combination with parameter <c>cases</c>.
+ The following examples illustrates this.</p></note>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
+ <pre>
+ -module(x_SUITE).
+ ...
+ %% The group definitions:
+ groups() ->
+ [{top1,[],[tc11,tc12,
+ {sub11,[],[tc12,tc13]},
+ {sub12,[],[tc14,tc15,
+ {sub121,[],[tc12,tc16]}]}]},
+
+ {top2,[],[{group,sub21},{group,sub22}]},
+ {sub21,[],[tc21,{group,sub2X2}]},
+ {sub22,[],[{group,sub221},tc21,tc22,{group,sub2X2}]},
+ {sub221,[],[tc21,tc23]},
+ {sub2X2,[],[tc21,tc24]}].</pre>
+
+ <p>The following executes two tests, one for all cases and all subgroups
+ under <c>top1</c>, and one for all under <c>top2</c>:</p>
<pre>
- -module(x_SUITE).
- ...
- %% The group definitions:
- groups() ->
- [{top1,[],[tc11,tc12,
- {sub11,[],[tc12,tc13]},
- {sub12,[],[tc14,tc15,
- {sub121,[],[tc12,tc16]}]}]},
-
- {top2,[],[{group,sub21},{group,sub22}]},
- {sub21,[],[tc21,{group,sub2X2}]},
- {sub22,[],[{group,sub221},tc21,tc22,{group,sub2X2}]},
- {sub221,[],[tc21,tc23]},
- {sub2X2,[],[tc21,tc24]}].
- </pre>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group all</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,all}]).</c></p>
- <p>Two tests will be executed, one for all cases and all sub groups under <c>top1</c>,
- and one for all under <c>top2</c>. (We would get the same result with
- <c>-group top1 top2</c>, or <c>{group,[top1,top2]}</c>.</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group top1</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}]).</c></p>
- <p>This will execute one test for all cases and sub groups under <c>top1</c>.</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group top1 -case tc12</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc12]}]).</c></p>
- <p>This will run a test that executes <c>tc12</c> in <c>top1</c> and any sub group
- under <c>top1</c> where it can be found (<c>sub11</c> and <c>sub121</c>).</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group [top1] -case tc12</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[[top1]]}, {testcase,[tc12]}]).</c></p>
- <p>This will execute <c>tc12</c> <em>only</em> in group <c>top1</c>.</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group top1 -case tc16</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc16]}]).</c></p>
- <p>This will search <c>top1</c> and all its sub groups for <c>tc16</c> and the result
- will be that this test case executes in group <c>sub121</c>. (The specific path:
- <c>-group [sub121]</c> or <c>{group,[[sub121]]}</c>, would have given
- us the same result in this example).</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group sub12 [sub12]</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[sub12,[sub12]]}]).</c></p>
- <p>This will execute two tests, one that includes all cases and sub groups under
- <c>sub12</c>, and one with <em>only</em> the test cases in <c>sub12</c>.</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group sub2X2</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[sub2X2]}]).</c></p>
- <p>In this example, Common Test will find and execute two tests, one for the path from
- <c>top2</c> to <c>sub2X2</c> via <c>sub21</c>, and one from <c>top2</c> to <c>sub2X2</c>
- via <c>sub22</c>.</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group [sub21,sub2X2]</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub21,sub2X2]]}]).</c></p>
- <p>Here, by specifying the unique path: <c>top2 -> sub21 -> sub2X2</c>, only one test
- is executed. The second possible path from <c>top2</c> to <c>sub2X2</c> (above)
- will be discarded.</p>
- <br></br>
- <p><c>$ ct_run -suite "x_SUITE" -group [sub22] -case tc22 tc21</c></p>
- <p><c>1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub22]]}, {testcase,[tc22,tc21]}]).</c></p>
- <p>In this example only the test cases for <c>sub22</c> will be executed, and in
- reverse order compared to the group definition.</p>
- <br></br>
-
- <p>If a test case that belongs to a group (according to the group definition), is executed
- without a group specification, i.e. simply by means of (command line):</p>
+ $ ct_run -suite "x_SUITE" -group all
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,all}]).</pre>
+ <p>Using <c>-group top1 top2</c>, or <c>{group,[top1,top2]}</c> gives the same result.</p>
+
+ <p>The following executes one test for all cases and subgroups under <c>top1</c>:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group top1
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}]).</pre>
+
+ <p>The following runs a test executing <c>tc12</c> in <c>top1</c> and any subgroup
+ under <c>top1</c> where it can be found (<c>sub11</c> and <c>sub121</c>):</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group top1 -case tc12
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc12]}]).</pre>
+
+ <p>The following executes <c>tc12</c> <em>only</em> in group <c>top1</c>:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group [top1] -case tc12
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[[top1]]}, {testcase,[tc12]}]).</pre>
+
+ <p>The following searches <c>top1</c> and all its subgroups for <c>tc16</c> resulting
+ in that this test case executes in group <c>sub121</c>:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group top1 -case tc16
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc16]}]).</pre>
+ <p>Using the specific path <c>-group [sub121]</c> or <c>{group,[[sub121]]}</c> gives
+ the same result in this example.</p>
+
+ <p>The following executes two tests, one including all cases and subgroups under
+ <c>sub12</c>, and one with <em>only</em> the test cases in <c>sub12</c>:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group sub12 [sub12]
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[sub12,[sub12]]}]).</pre>
+
+ <p>In the following example, <c>Common Test</c> finds and executes two tests,
+ one for the path from <c>top2</c> to <c>sub2X2</c> through <c>sub21</c>,
+ and one from <c>top2</c> to <c>sub2X2</c> through <c>sub22</c>:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group sub2X2
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[sub2X2]}]).</pre>
+
+ <p>In the following example, by specifying the unique path <c>top2 -> sub21 -> sub2X2</c>,
+ only one test is executed. The second possible path, from <c>top2</c> to <c>sub2X2</c>
+ (from the former example) is discarded:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group [sub21,sub2X2]
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub21,sub2X2]]}]).</pre>
+
+ <p>The following executes only the test cases for <c>sub22</c> and in reverse order
+ compared to the group definition:</p>
+ <pre>
+ $ ct_run -suite "x_SUITE" -group [sub22] -case tc22 tc21
+ 1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub22]]}, {testcase,[tc22,tc21]}]).</pre>
+
+ <p>If a test case belonging to a group (according to the group definition) is executed
+ without a group specification, that is, simply by
+ (using the command line):</p>
<p><c>$ ct_run -suite "my_SUITE" -case my_tc</c></p>
- <p>or (Erlang shell):</p>
+ <p>or (using the Erlang shell):</p>
<p><c>1> ct:run_test([{suite,"my_SUITE"}, {testcase,my_tc}]).</c></p>
- <p>then Common Test ignores the group definition and executes the test case in the scope of the
- test suite only (no group configuration functions are called).</p>
+ <p>then <c>Common Test</c> ignores the group definition and executes the test case
+ in the scope of the test suite only (no group configuration functions are called).</p>
- <p>The group specification feature, exactly as it has been presented in this section, can also
+ <p>The group specification feature, as presented in this section, can also
be used in <seealso marker="run_test_chapter#test_specifications">Test
- Specifications</seealso> (with some extra features added). Please see below.</p>
+ Specifications</seealso> (with some extra features added).</p>
</section>
<section>
- <title>Running the interactive shell mode</title>
+ <title>Running the Interactive Shell Mode</title>
- <p>You can start Common Test in an interactive shell mode where no
- automatic testing is performed. Instead, in this mode, Common Test
+ <p>You can start <c>Common Test</c> in an interactive shell mode where no
+ automatic testing is performed. Instead, <c>Common Test</c>
starts its utility processes, installs configuration data (if any),
and waits for the user to call functions (typically test case support
functions) from the Erlang shell.</p>
- <p>The shell mode is useful e.g. for debugging test suites, for analysing
+ <p>The shell mode is useful, for example, for debugging test suites, analyzing
and debugging the SUT during "simulated" test case execution, and
- for trying out various operations during test suite development.</p>
-
- <p>To invoke the interactive shell mode, you can start an Erlang shell
- manually and call <seealso marker="ct#install-1"><c>ct:install/1</c></seealso> to install any configuration
- data you might need (use <c>[]</c> as argument otherwise), then
- call <seealso marker="ct#start_interactive-0"><c>ct:start_interactive/0</c></seealso> to start Common Test. If you use
- the <c>ct_run</c> program, you may start the Erlang shell and Common Test
- in the same go by using the <c>-shell</c> and, optionally, the <c>-config</c>
- and/or <c>-userconfig</c> flag. Examples:
- </p>
- <list>
+ trying out various operations during test suite development.</p>
+
+ <p>To start the interactive shell mode, start an Erlang shell
+ manually and call <seealso marker="ct#install-1"><c>ct:install/1</c></seealso>
+ to install any configuration data you might need (use <c>[]</c> as argument otherwise).
+ Then call <seealso marker="ct#start_interactive-0"><c>ct:start_interactive/0</c></seealso>
+ to start <c>Common Test</c>.</p>
+
+ <p>If you use the <c>ct_run</c> program, you can start
+ the Erlang shell and <c>Common Test</c> in one go by using the flag <c>-shell</c> and,
+ optionally, flag <c>-config</c> and/or <c>-userconfig</c>.</p>
+ <p><em>Examples:</em></p>
+ <list type="bulleted">
<item><c>ct_run -shell</c></item>
<item><c><![CDATA[ct_run -shell -config cfg/db.cfg]]></c></item>
<item><c><![CDATA[ct_run -shell -userconfig db_login testuser x523qZ]]></c></item>
</list>
- <p>If no config file is given with the <c>ct_run</c> command,
- a warning will be displayed. If Common Test has been run from the same
- directory earlier, the same config file(s) will be used
- again. If Common Test has not been run from this directory before, no
- config files will be available.</p>
-
- <p>If any functions using "required config data" (e.g. ct_telnet or
- ct_ftp functions) are to be called from the erlang shell, config
- data must first be required with <seealso marker="ct#require-1"><c>
- ct:require/1/2</c></seealso>. This is
- equivalent to a <c>require</c> statement in the <seealso
- marker="write_test_chapter#suite">Test Suite Info
- Function</seealso> or in the <seealso
- marker="write_test_chapter#info_function">Test Case Info
- Function</seealso>.</p>
+ <p>If no configuration file is specified with command <c>ct_run</c>,
+ a warning is displayed. If <c>Common Test</c> has been run from the same
+ directory earlier, the same configuration file(s) are used again. If <c>Common Test</c>
+ has not been run from this directory before, no configuration files are available.</p>
- <p>Example:</p>
+ <p>If any functions using "required configuration data" (for example, functions
+ <c>ct_telnet</c> or <c>ct_ftp</c>) are to be called from the Erlang shell, first require
+ configuration data with <seealso marker="ct#require-1"><c>
+ ct:require/1,2</c></seealso>. This is equivalent to a <c>require</c> statement
+ in the <seealso marker="write_test_chapter#suite">Test Suite Information Function</seealso>
+ or in the <seealso marker="write_test_chapter#info_function">Test Case Information Function</seealso>.</p>
+
+ <p><em>Example:</em></p>
<pre>
- 1> ct:require(unix_telnet, unix).
- ok
- 2> ct_telnet:open(unix_telnet).
- {ok,&lt;0.105.0&gt;}
- 4> ct_telnet:cmd(unix_telnet, "ls .").
- {ok,["ls .","file1 ...",...]}
- </pre>
+ 1> ct:require(unix_telnet, unix).
+ ok
+ 2> ct_telnet:open(unix_telnet).
+ {ok,&lt;0.105.0&gt;}
+ 4> ct_telnet:cmd(unix_telnet, "ls .").
+ {ok,["ls .","file1 ...",...]}</pre>
- <p>Everything that Common Test normally prints in the test case logs,
- will in the interactive mode be written to a log named
- <c>ctlog.html</c> in the <c><![CDATA[ct_run.<timestamp>]]></c>
- directory. A link to this file will be available in the file
- named <c>last_interactive.html</c> in the directory from which
- you executed <c>ct_run</c>. Currently, specifying a different
- root directory for the logs than the current working directory,
+ <p>Everything that <c>Common Test</c> normally prints in the test case logs,
+ are in the interactive mode written to a log named <c>ctlog.html</c>
+ in directory <c><![CDATA[ct_run.<timestamp>]]></c>. A link to this
+ file is available in the file named <c>last_interactive.html</c> in the
+ directory from which you execute <c>ct_run</c>. Specifying a different
+ root directory for the logs than the current working directory
is not supported.</p>
- <p>If you wish to exit the interactive mode (e.g. to start an
- automated test run with <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>), call the function
- <seealso marker="ct#stop_interactive-0"><c>ct:stop_interactive/0</c></seealso>. This shuts down the
- running <c>ct</c> application. Associations between
+ <p>If you wish to exit the interactive mode (for example, to start an automated
+ test run with <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>),
+ call function
+ <seealso marker="ct#stop_interactive-0"><c>ct:stop_interactive/0</c></seealso>.
+ This shuts down the running <c>ct</c> application. Associations between
configuration names and data created with <c>require</c> are
- consequently deleted. <seealso marker="ct#start_interactive-0"><c>ct:start_interactive/0</c></seealso> will get you
- back into interactive mode, but the previous state is not restored.</p>
+ consequently deleted. Function
+ <seealso marker="ct#start_interactive-0"><c>ct:start_interactive/0</c></seealso>
+ takes you back into interactive mode, but the previous state is not restored.</p>
</section>
<section>
- <title>Step by step execution of test cases with the Erlang Debugger</title>
+ <title>Step-by-Step Execution of Test Cases with the Erlang Debugger</title>
- <p>By means of <c>ct_run -step [opts]</c>, or by passing the
- <c>{step,Opts}</c> option to <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, it is possible
- to get the Erlang Debugger started automatically and use its
- graphical interface to investigate the state of the current test
- case and to execute it step by step and/or set execution breakpoints.</p>
- <p>If no extra options are given with the <c>step</c> flag/option,
- breakpoints will be set automatically on the test cases that
- are to be executed by Common Test, and those functions only. If
- the step option <c>config</c> is specified, breakpoints will
- also be initially set on the configuration functions in the suite, i.e.
+ <p>Using <c>ct_run -step [opts]</c>, or by passing option <c>{step,Opts}</c>
+ to <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>,
+ the following is possible:</p>
+ <list type="bulleted">
+ <item>Get the Erlang Debugger started automatically.</item>
+ <item>Use its graphical interface to investigate the state of the current test case.</item>
+ <item>Execute the test case step-by-step and/or set execution breakpoints.</item>
+ </list>
+ <p>If no extra options are specified with flag/option <c>step</c>,
+ breakpoints are set automatically on the test cases that
+ are to be executed by <c>Common Test</c>, and those functions only. If
+ step option <c>config</c> is specified, breakpoints are also initially
+ set on the configuration functions in the suite, that is,
<c>init_per_suite/1</c>, <c>end_per_suite/1</c>,
<c>init_per_group/2</c>, <c>end_per_group/2</c>,
<c>init_per_testcase/2</c> and <c>end_per_testcase/2</c>.</p>
- <p>Common Test enables the Debugger auto attach feature, which means
+ <p><c>Common Test</c> enables the Debugger auto-attach feature, which means
that for every new interpreted test case function that starts to execute,
- a new trace window will automatically pop up. (This is because each test
+ a new trace window automatically pops up (as each test
case executes on a dedicated Erlang process). Whenever a new test case starts,
- Common Test will attempt to close the inactive trace window of the previous
- test case. However, if you prefer that Common Test leaves inactive trace
- windows, use the <c>keep_inactive</c> option.</p>
- <p>The step functionality can be used together with the <c>suite</c> and
- the <c>suite</c> + <c>case/testcase</c> flag/option, but not together
- with <c>dir</c>.</p>
+ <c>Common Test</c> attempts to close the inactive trace window of the previous
+ test case. However, if you prefer <c>Common Test</c> to leave inactive trace
+ windows, use option <c>keep_inactive</c>.</p>
+ <p>The step functionality can be used together with flag/option <c>suite</c> and
+ <c>suite</c> + <c>case/testcase</c>, but not together with <c>dir</c>.</p>
</section>
<section>
<marker id="test_specifications"></marker>
<title>Test Specifications</title>
<section>
- <title>General description</title>
- <p>The most flexible way to specify what to test, is to use a so
- called test specification. A test specification is a sequence of
+ <title>General Description</title>
+ <p>The most flexible way to specify what to test, is to use a
+ test specification, which is a sequence of
Erlang terms. The terms are normally declared in one or more text files
(see <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>), but
- may also be passed to Common Test on the form of a list (see
+ can also be passed to <c>Common Test</c> on the form of a list (see
<seealso marker="ct#run_testspec-1"><c>ct:run_testspec/1</c></seealso>).
There are two general types of terms: configuration terms and test
specification terms.</p>
- <p>With configuration terms it is possible to e.g. label the test
- run (similar to <c>ct_run -label</c>), evaluate arbitrary expressions
- before starting the test, import configuration data (similar to
- <c>ct_run -config/-userconfig</c>), specify the top level HTML log
- directory (similar to <c>ct_run -logdir</c>), enable code coverage
- analysis (similar to <c>ct_run -cover</c>), install Common Test Hooks
- (similar to <c>ct_run -ch_hooks</c>), install event_handler plugins
- (similar to <c>ct_run -event_handler</c>), specify include directories
- that should be passed to the compiler for automatic compilation
- (similar to <c>ct_run -include</c>), disable the auto compilation
- feature (similar to <c>ct_run -no_auto_compile</c>), set verbosity
- levels (similar to <c>ct_run -verbosity</c>), and more.</p>
- <p>Configuration terms can be combined with <c>ct_run</c> start flags,
- or <c>ct:run_test/1</c> options. The result will for some flags/options
- and terms be that the values are merged (e.g. configuration files,
- include directories, verbosity levels, silent connections), and for
+
+ <p>With configuration terms it is, for example, possible to do the following:</p>
+ <list type="bulleted">
+ <item>Label the test run (similar to <c>ct_run -label</c>).</item>
+ <item>Evaluate any expressions before starting the test.</item>
+ <item>Import configuration data (similar to <c>ct_run -config/-userconfig</c>).</item>
+ <item>Specify the top-level HTML log directory (similar to <c>ct_run -logdir</c>).</item>
+ <item>Enable code coverage analysis (similar to <c>ct_run -cover</c>).</item>
+ <item>Install <c>Common Test Hooks</c> (similar to <c>ct_run -ch_hooks</c>).</item>
+ <item>Install <c>event_handler</c> plugins (similar to <c>ct_run -event_handler</c>).</item>
+ <item>Specify include directories to be passed to the compiler for
+ automatic compilation (similar to <c>ct_run -include</c>).</item>
+ <item>Disable the auto-compilation feature (similar to <c>ct_run -no_auto_compile</c>).</item>
+ <item>Set verbosity levels (similar to <c>ct_run -verbosity</c>).</item>
+ </list>
+
+ <p>Configuration terms can be combined with <c>ct_run</c> start flags
+ or <c>ct:run_test/1</c> options. The result is, for some flags/options
+ and terms, that the values are merged (for example, configuration files,
+ include directories, verbosity levels, and silent connections) and for
others that the start flags/options override the test specification
- terms (e.g. log directory, label, style sheet, auto compilation).</p>
- <p>With test specification terms it is possible to state exactly
- which tests should run and in which order. A test term specifies
+ terms (for example, log directory, label, style sheet, and auto-compilation).</p>
+
+ <p>With test specification terms, it is possible to state exactly
+ which tests to run and in which order. A test term specifies
either one or more suites, one or more test case groups (possibly nested),
or one or more test cases in a group (or in multiple groups) or in a suite.</p>
- <p>An arbitrary number of test terms may be declared in sequence.
- Common Test will by default compile the terms into one or more tests
- to be performed in one resulting test run. Note that a term that
- specifies a set of test cases will "swallow" one that only
- specifies a subset of these cases. E.g. the result of merging
- one term that specifies that all cases in suite S should be
+
+ <p>Any number of test terms can be declared in sequence.
+ <c>Common Test</c> compiles by default the terms into one or more tests
+ to be performed in one resulting test run. A term that
+ specifies a set of test cases "swallows" one that only
+ specifies a subset of these cases. For example, the result of merging
+ one term specifying that all cases in suite S are to be
executed, with another term specifying only test case X and Y in
S, is a test of all cases in S. However, if a term specifying
test case X and Y in S is merged with a term specifying case Z
- in S, the result is a test of X, Y and Z in S. To disable this
- behaviour, i.e. to instead perform each test sequentially in a "script-like"
- manner, the term <c>merge_tests</c> can be set to <c>false</c> in
- the test specification.</p>
+ in S, the result is a test of X, Y, and Z in S. To disable this
+ behavior, that is, to instead perform each test sequentially in a
+ "script-like" manner, set term <c>merge_tests</c> to <c>false</c>
+ in the test specification.</p>
+
<p>A test term can also specify one or more test suites, groups,
- or test cases to be skipped. Skipped suites, groups and cases
- are not executed and show up in the HTML log files as
- SKIPPED.</p>
+ or test cases to be skipped. Skipped suites, groups, and cases
+ are not executed and show up in the HTML log files as <c>SKIPPED</c>.</p>
</section>
<section>
- <title>Using multiple test specification files</title>
+ <title>Using Multiple Test Specification Files</title>
- <p>When multiple test specification files are given at startup (either
+ <p>When multiple test specification files are specified at startup (either
with <c>ct_run -spec file1 file2 ...</c> or
<c>ct:run_test([{spec, [File1,File2,...]}])</c>),
- Common Test will either execute one test run per specification file, or
- join the files and perform all tests within one single test run. The first
- behaviour is the default one. The latter requires that the start
- flag/option <c>join_specs</c> is provided, e.g.
+ <c>Common Test</c> either executes one test run per specification file,
+ or joins the files and performs all tests within one single test run.
+ The first behavior is the default one. The latter requires that start
+ flag/option <c>join_specs</c> is provided, for example,
<c>run_test -spec ./my_tests1.ts ./my_tests2.ts -join_specs</c>.</p>
<p>Joining a number of specifications, or running them separately, can
- also be accomplished with (and may be combined with) test specification
- file inclusion, described next.</p>
+ also be accomplished with (and can be combined with) test specification
+ file inclusion.</p>
</section>
<section>
- <title>Test specification file inclusion</title>
- <p>With the <c>specs</c> term (see syntax below), it's possible to have
- a test specification include other specifications. An included
- specification may either be joined with the source specification,
- or used to produce a separate test run (like with the <c>join_specs</c>
- start flag/option above). Example:</p>
+ <title>Test Specification File Inclusion</title>
+ <p>With the term <c>specs</c>, a test specification can include
+ other specifications. An included specification can either be joined
+ with the source specification or used to produce a separate test run
+ (as with start flag/option <c>join_specs</c> above).</p>
+ <p><em>Example:</em></p>
+
<pre>
- %% In specification file "a.spec"
- {specs, join, ["b.spec", "c.spec"]}.
- {specs, separate, ["d.spec", "e.spec"]}.
- %% Config and test terms follow
- ...</pre>
+ %% In specification file "a.spec"
+ {specs, join, ["b.spec", "c.spec"]}.
+ {specs, separate, ["d.spec", "e.spec"]}.
+ %% Config and test terms follow
+ ...</pre>
+
<p>In this example, the test terms defined in files "b.spec" and "c.spec"
- will be joined with the terms in the source specification "a.spec"
+ are joined with the terms in source specification "a.spec"
(if any). The inclusion of specifications "d.spec" and
- "e.spec" will result in two separate, and independent, test runs (i.e.
- one for each included specification).</p>
- <p>Note that the <c>join</c> option does not imply that the test terms
- will be merged (see <c>merge_tests</c> above), only that all tests are
- executed in one single test run.</p>
+ "e.spec" results in two separate, and independent, test runs
+ (one for each included specification).</p>
+
+ <p>Option <c>join</c> does not imply that the test terms
+ are merged, only that all tests are executed in one single test run.</p>
+
<p>Joined specifications share common configuration settings, such as
the list of <c>config</c> files or <c>include</c> directories.
- For configuration that can not be combined, such as settings for <c>logdir</c>
+ For configurations that cannot be combined, such as settings for <c>logdir</c>
or <c>verbosity</c>, it is up to the user to ensure there are no clashes
when the test specifications are joined. Specifications included with
- the <c>separate</c> option, do not share configuration settings with the
- source specification. This is useful e.g. if there are clashing
- configuration settings in included specifications, making it impossible
- to join them.</p>
+ option <c>separate</c> do not share configuration settings with the
+ source specification. This is useful, for example, if there are clashing
+ configuration settings in included specifications, making it them impossible
+ to join.</p>
+
<p>If <c>{merge_tests,true}</c> is set in the source specification
- (which is the default setting), terms in joined specifications will be
+ (which is the default setting), terms in joined specifications are
merged with terms in the source specification (according to the
- description of <c>merge_tests</c> above).</p>
- <p>Note that it is always the <c>merge_tests</c> setting in the source
+ description of <c>merge_tests</c> earlier).</p>
+
+ <p>Notice that it is always the <c>merge_tests</c> setting in the source
specification that is used when joined with other specifications.
- Say e.g. that a source specification A, with tests TA1 and TA2, has
- <c>{merge_tests,false}</c> set, and it includes another specification,
+ Say, for example, that a source specification A, with tests TA1 and TA2, has
+ <c>{merge_tests,false}</c> set, and that it includes another specification,
B, with tests TB1 and TB2, that has <c>{merge_tests,true}</c> set.
- The result will be that the test series: <c>TA1,TA2,merge(TB1,TB2)</c>,
- is executed. The opposite <c>merge_tests</c> settings would result in the
- following the test series: <c>merge(merge(TA1,TA2),TB1,TB2)</c>.</p>
- <p>The <c>specs</c> term may of course be used to nest specifications,
- i.e. have one specification include other specifications, which in turn
- include others, etc.</p>
+ The result is that the test series <c>TA1,TA2,merge(TB1,TB2)</c>
+ is executed. The opposite <c>merge_tests</c> settings would result in
+ the test series <c>merge(merge(TA1,TA2),TB1,TB2)</c>.</p>
+
+ <p>The term <c>specs</c> can be used to nest specifications,
+ that is, have one specification include other specifications, which in turn
+ include others, and so no</p>
</section>
<section>
- <title>Test case groups</title>
+ <title>Test Case Groups</title>
<p>When a test case group is specified, the resulting test
- executes the <c>init_per_group</c> function, followed by all test
- cases and sub groups (including their configuration functions), and
- finally the <c>end_per_group</c> function. Also if particular
+ executes function <c>init_per_group</c>, followed by all test
+ cases and subgroups (including their configuration functions), and
+ finally function <c>end_per_group</c>. Also, if particular
test cases in a group are specified, <c>init_per_group</c>
- and <c>end_per_group</c> for the group in question are
- called. If a group which is defined (in <c>Suite:group/0</c>) to
- be a sub group of another group, is specified (or if particular test
- cases of a sub group are), Common Test will call the configuration
- functions for the top level groups as well as for the sub group
+ and <c>end_per_group</c>, for the group in question, are
+ called. If a group defined (in <c>Suite:group/0</c>) as
+ a subgroup of another group, is specified (or if particular test
+ cases of a subgroup are), <c>Common Test</c> calls the configuration
+ functions for the top-level groups and for the subgroup
in question (making it possible to pass configuration data all
the way from <c>init_per_suite</c> down to the test cases in the
- sub group).</p>
- <p>The test specification utilizes the same mechanism for specifying
- test case groups by means of names and paths, as explained in the
- <seealso marker="run_test_chapter#group_execution">Group Execution</seealso>
- section above, with the addition of the <c>GroupSpec</c> element
- described next.</p>
- <p>The <c>GroupSpec</c> element makes it possible to specify
- group execution properties that will override those in the
- group definition (i.e. in <c>groups/0</c>). Execution properties for
- sub-groups may be overridden as well. This feature makes it possible to
+ subgroup).</p>
+
+ <p>The test specification uses the same mechanism for specifying
+ test case groups through names and paths, as explained in section
+ <seealso marker="run_test_chapter#group_execution">Test Case Group Execution</seealso>,
+ with the addition of element <c>GroupSpec</c>.</p>
+
+ <p>Element <c>GroupSpec</c> makes it possible to specify
+ group execution properties that overrides those in the
+ group definition (that is, in <c>groups/0</c>). Execution properties for
+ subgroups might be overridden as well. This feature makes it possible to
change properties of groups at the time of execution,
- without even having to edit the test suite. The very same
- feature is available for <c>group</c> elements in the <c>Suite:all/0</c>
- list. Therefore, more detailed documentation, and examples, can be
- found in the <seealso marker="write_test_chapter#test_case_groups">
- Test case groups</seealso> chapter.</p>
+ without having to edit the test suite. The same feature is available for
+ <c>group</c> elements in the <c>Suite:all/0</c> list. For details and examples,
+ see section <seealso marker="write_test_chapter#test_case_groups">
+ Test Case Groups</seealso>.</p>
</section>
<section>
- <title>Test specification syntax</title>
-
- <p>Below is the test specification syntax. Test specifications can
- be used to run tests both in a single test host environment and
- in a distributed Common Test environment (Large Scale
- Testing). The node parameters in the <c>init</c> term are only
- relevant in the latter (see the
- <seealso marker="ct_master_chapter#test_specifications">Large
- Scale Testing</seealso> chapter for information). For more information
- about the various terms, please see the corresponding sections in the
- User's Guide, such as e.g. the
- <seealso marker="run_test_chapter#ct_run"><c>ct_run</c>
+ <title>Test Specification Syntax</title>
+
+ <p>Test specifications can be used to run tests both in a single
+ test host environment and in a distributed <c>Common Test</c> environment
+ (Large Scale Testing). The node parameters in term <c>init</c> are only
+ relevant in the latter (see section
+ <seealso marker="ct_master_chapter#test_specifications">Test Specifications</seealso>
+ in Large Scale Testing). For details about the various terms, see the
+ corresponding sections in the User's Guide, for example, the following:
+ </p>
+ <list type="bulleted">
+ <item>The <seealso marker="run_test_chapter#ct_run"><c>ct_run</c>
program</seealso> for an overview of available start flags
- (since most flags have a corresponding configuration term), and
- more detailed explanation of e.g.
- <seealso marker="write_test_chapter#logging">Logging</seealso>
- (for the <c>verbosity</c>, <c>stylesheet</c> and <c>basic_html</c> terms),
- <seealso marker="config_file_chapter#top">External Configuration Data</seealso>
- (for the <c>config</c> and <c>userconfig</c> terms),
- <seealso marker="event_handler_chapter#event_handling">Event
- Handling</seealso> (for the <c>event_handler</c> term),
- <seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso>
- (for the <c>ct_hooks</c> term), etc.</p>
- </section>
-
- <p>Config terms:</p>
+ (as most flags have a corresponding configuration term)</item>
+ <item><seealso marker="write_test_chapter#logging">Logging</seealso>
+ (for terms <c>verbosity</c>, <c>stylesheet</c>, <c>basic_html</c> and <c>esc_chars</c>)</item>
+ <item><seealso marker="config_file_chapter#top">External Configuration Data</seealso>
+ (for terms <c>config</c> and <c>userconfig</c>)</item>
+ <item><seealso marker="event_handler_chapter#event_handling">Event
+ Handling</seealso> (for the <c>event_handler</c> term)</item>
+ <item><seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso>
+ (for term <c>ct_hooks</c>)</item>
+ </list>
+
+ <p><em>Configuration terms:</em></p>
<pre>
- {merge_tests, Bool}.
-
- {define, Constant, Value}.
-
- {specs, InclSpecsOption, TestSpecs}.
-
- {node, NodeAlias, Node}.
-
- {init, InitOptions}.
- {init, [NodeAlias], InitOptions}.
-
- {label, Label}.
- {label, NodeRefs, Label}.
-
- {verbosity, VerbosityLevels}.
- {verbosity, NodeRefs, VerbosityLevels}.
-
- {stylesheet, CSSFile}.
- {stylesheet, NodeRefs, CSSFile}.
-
- {silent_connections, ConnTypes}.
- {silent_connections, NodeRefs, ConnTypes}.
-
- {multiply_timetraps, N}.
- {multiply_timetraps, NodeRefs, N}.
-
- {scale_timetraps, Bool}.
- {scale_timetraps, NodeRefs, Bool}.
-
- {cover, CoverSpecFile}.
- {cover, NodeRefs, CoverSpecFile}.
-
- {cover_stop, Bool}.
- {cover_stop, NodeRefs, Bool}.
-
- {include, IncludeDirs}.
- {include, NodeRefs, IncludeDirs}.
-
- {auto_compile, Bool},
- {auto_compile, NodeRefs, Bool},
-
- {abort_if_missing_suites, Bool},
- {abort_if_missing_suites, NodeRefs, Bool},
+ {merge_tests, Bool}.
- {config, ConfigFiles}.
- {config, ConfigDir, ConfigBaseNames}.
- {config, NodeRefs, ConfigFiles}.
- {config, NodeRefs, ConfigDir, ConfigBaseNames}.
-
- {userconfig, {CallbackModule, ConfigStrings}}.
- {userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
-
- {logdir, LogDir}.
- {logdir, NodeRefs, LogDir}.
-
- {logopts, LogOpts}.
- {logopts, NodeRefs, LogOpts}.
-
- {create_priv_dir, PrivDirOption}.
- {create_priv_dir, NodeRefs, PrivDirOption}.
-
- {event_handler, EventHandlers}.
- {event_handler, NodeRefs, EventHandlers}.
- {event_handler, EventHandlers, InitArgs}.
- {event_handler, NodeRefs, EventHandlers, InitArgs}.
-
- {ct_hooks, CTHModules}.
- {ct_hooks, NodeRefs, CTHModules}.
-
- {enable_builtin_hooks, Bool}.
-
- {basic_html, Bool}.
- {basic_html, NodeRefs, Bool}.
-
- {release_shell, Bool}.</pre>
+ {define, Constant, Value}.
+
+ {specs, InclSpecsOption, TestSpecs}.
+
+ {node, NodeAlias, Node}.
+
+ {init, InitOptions}.
+ {init, [NodeAlias], InitOptions}.
+
+ {label, Label}.
+ {label, NodeRefs, Label}.
+
+ {verbosity, VerbosityLevels}.
+ {verbosity, NodeRefs, VerbosityLevels}.
+
+ {stylesheet, CSSFile}.
+ {stylesheet, NodeRefs, CSSFile}.
+
+ {silent_connections, ConnTypes}.
+ {silent_connections, NodeRefs, ConnTypes}.
+
+ {multiply_timetraps, N}.
+ {multiply_timetraps, NodeRefs, N}.
+
+ {scale_timetraps, Bool}.
+ {scale_timetraps, NodeRefs, Bool}.
+
+ {cover, CoverSpecFile}.
+ {cover, NodeRefs, CoverSpecFile}.
+
+ {cover_stop, Bool}.
+ {cover_stop, NodeRefs, Bool}.
+
+ {include, IncludeDirs}.
+ {include, NodeRefs, IncludeDirs}.
+
+ {auto_compile, Bool},
+ {auto_compile, NodeRefs, Bool},
+
+ {abort_if_missing_suites, Bool},
+ {abort_if_missing_suites, NodeRefs, Bool},
+
+ {config, ConfigFiles}.
+ {config, ConfigDir, ConfigBaseNames}.
+ {config, NodeRefs, ConfigFiles}.
+ {config, NodeRefs, ConfigDir, ConfigBaseNames}.
+
+ {userconfig, {CallbackModule, ConfigStrings}}.
+ {userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
+
+ {logdir, LogDir}.
+ {logdir, NodeRefs, LogDir}.
+
+ {logopts, LogOpts}.
+ {logopts, NodeRefs, LogOpts}.
+
+ {create_priv_dir, PrivDirOption}.
+ {create_priv_dir, NodeRefs, PrivDirOption}.
+
+ {event_handler, EventHandlers}.
+ {event_handler, NodeRefs, EventHandlers}.
+ {event_handler, EventHandlers, InitArgs}.
+ {event_handler, NodeRefs, EventHandlers, InitArgs}.
+
+ {ct_hooks, CTHModules}.
+ {ct_hooks, NodeRefs, CTHModules}.
+
+ {enable_builtin_hooks, Bool}.
+
+ {basic_html, Bool}.
+ {basic_html, NodeRefs, Bool}.
+
+ {esc_chars, Bool}.
+ {esc_chars, NodeRefs, Bool}.
+
+ {release_shell, Bool}.</pre>
- <p>Test terms:</p>
+ <p><em>Test terms:</em></p>
<pre>
- {suites, Dir, Suites}.
- {suites, NodeRefs, Dir, Suites}.
-
- {groups, Dir, Suite, Groups}.
- {groups, NodeRefs, Dir, Suite, Groups}.
-
- {groups, Dir, Suite, Groups, {cases,Cases}}.
- {groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.
-
- {cases, Dir, Suite, Cases}.
- {cases, NodeRefs, Dir, Suite, Cases}.
-
- {skip_suites, Dir, Suites, Comment}.
- {skip_suites, NodeRefs, Dir, Suites, Comment}.
-
- {skip_groups, Dir, Suite, GroupNames, Comment}.
- {skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.
-
- {skip_cases, Dir, Suite, Cases, Comment}.
- {skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.</pre>
-
- <p>Types:</p>
+ {suites, Dir, Suites}.
+ {suites, NodeRefs, Dir, Suites}.
+
+ {groups, Dir, Suite, Groups}.
+ {groups, NodeRefs, Dir, Suite, Groups}.
+
+ {groups, Dir, Suite, Groups, {cases,Cases}}.
+ {groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.
+
+ {cases, Dir, Suite, Cases}.
+ {cases, NodeRefs, Dir, Suite, Cases}.
+
+ {skip_suites, Dir, Suites, Comment}.
+ {skip_suites, NodeRefs, Dir, Suites, Comment}.
+
+ {skip_groups, Dir, Suite, GroupNames, Comment}.
+ {skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.
+
+ {skip_cases, Dir, Suite, Cases, Comment}.
+ {skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.</pre>
+
+ <marker id="types"></marker>
+ <p><em>Types:</em></p>
<pre>
- Bool = true | false
- Constant = atom()
- Value = term()
- InclSpecsOption = join | separate
- TestSpecs = string() | [string()]
- NodeAlias = atom()
- Node = node()
- NodeRef = NodeAlias | Node | master
- NodeRefs = all_nodes | [NodeRef] | NodeRef
- InitOptions = term()
- Label = atom() | string()
- VerbosityLevels = integer() | [{Category,integer()}]
- Category = atom()
- CSSFile = string()
- ConnTypes = all | [atom()]
- N = integer()
- CoverSpecFile = string()
- IncludeDirs = string() | [string()]
- ConfigFiles = string() | [string()]
- ConfigDir = string()
- ConfigBaseNames = string() | [string()]
- CallbackModule = atom()
- ConfigStrings = string() | [string()]
- LogDir = string()
- LogOpts = [term()]
- PrivDirOption = auto_per_run | auto_per_tc | manual_per_tc
- EventHandlers = atom() | [atom()]
- InitArgs = [term()]
- CTHModules = [CTHModule |
- {CTHModule, CTHInitArgs} |
- {CTHModule, CTHInitArgs, CTHPriority}]
- CTHModule = atom()
- CTHInitArgs = term()
- Dir = string()
- Suites = atom() | [atom()] | all
- Suite = atom()
- Groups = GroupPath | [GroupPath] | GroupSpec | [GroupSpec] | all
- GroupPath = [GroupName]
- GroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,GroupSpec}
- GroupName = atom()
- GroupNames = GroupName | [GroupName]
- Cases = atom() | [atom()] | all
- Comment = string() | ""</pre>
-
- <section>
- <p>The difference between the <c>config</c> terms above, is that with
+ Bool = true | false
+ Constant = atom()
+ Value = term()
+ InclSpecsOption = join | separate
+ TestSpecs = string() | [string()]
+ NodeAlias = atom()
+ Node = node()
+ NodeRef = NodeAlias | Node | master
+ NodeRefs = all_nodes | [NodeRef] | NodeRef
+ InitOptions = term()
+ Label = atom() | string()
+ VerbosityLevels = integer() | [{Category,integer()}]
+ Category = atom()
+ CSSFile = string()
+ ConnTypes = all | [atom()]
+ N = integer()
+ CoverSpecFile = string()
+ IncludeDirs = string() | [string()]
+ ConfigFiles = string() | [string()]
+ ConfigDir = string()
+ ConfigBaseNames = string() | [string()]
+ CallbackModule = atom()
+ ConfigStrings = string() | [string()]
+ LogDir = string()
+ LogOpts = [term()]
+ PrivDirOption = auto_per_run | auto_per_tc | manual_per_tc
+ EventHandlers = atom() | [atom()]
+ InitArgs = [term()]
+ CTHModules = [CTHModule |
+ {CTHModule, CTHInitArgs} |
+ {CTHModule, CTHInitArgs, CTHPriority}]
+ CTHModule = atom()
+ CTHInitArgs = term()
+ Dir = string()
+ Suites = atom() | [atom()] | all
+ Suite = atom()
+ Groups = GroupPath | [GroupPath] | GroupSpec | [GroupSpec] | all
+ GroupPath = [GroupName]
+ GroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,GroupSpec}
+ GroupName = atom()
+ GroupNames = GroupName | [GroupName]
+ Cases = atom() | [atom()] | all
+ Comment = string() | ""</pre>
+
+ <p>The difference between the <c>config</c> terms above is that with
<c>ConfigDir</c>, <c>ConfigBaseNames</c> is a list of base names,
- i.e. without directory paths. <c>ConfigFiles</c> must be full names,
- including paths. E.g, these two terms have the same meaning:</p>
+ that is, without directory paths. <c>ConfigFiles</c> must be full names,
+ including paths. For example, the following two terms have the same meaning:</p>
<pre>
- {config, ["/home/testuser/tests/config/nodeA.cfg",
- "/home/testuser/tests/config/nodeB.cfg"]}.
-
- {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.</pre>
+ {config, ["/home/testuser/tests/config/nodeA.cfg",
+ "/home/testuser/tests/config/nodeB.cfg"]}.
+
+ {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.</pre>
- <note><p>Any relative paths specified in the test specification, will be
- relative to the directory which contains the test specification file, if
+ <note><p>Any relative paths, specified in the test specification, are
+ relative to the directory containing the test specification file if
<c>ct_run -spec TestSpecFile ...</c> or
<c>ct:run:test([{spec,TestSpecFile},...])</c>
- executes the test. The path will be relative to the top level log directory, if
+ executes the test.</p>
+ <p>The path is relative to the top-level log directory if
<c>ct:run:testspec(TestSpec)</c> executes the test.</p></note>
</section>
<section>
<title>Constants</title>
- <p>The <c>define</c> term introduces a constant, which is used to
- replace the name <c>Constant</c> with <c>Value</c>, wherever it's found in
- the test specification. This replacement happens during an initial iteration
- through the test specification. Constants may be used anywhere in the test
- specification, e.g. in arbitrary lists and tuples, and even in strings
- and inside the value part of other constant definitions! A constant can
+ <p>The term <c>define</c> introduces a constant that is used to
+ replace the name <c>Constant</c> with <c>Value</c>, wherever it is found in
+ the test specification. This replacement occurs during an initial iteration
+ through the test specification. Constants can be used anywhere in the test
+ specification, for example, in any lists and tuples, and even in strings
+ and inside the value part of other constant definitions. A constant can
also be part of a node name, but that is the only place where a constant
can be part of an atom.</p>
<note><p>For the sake of readability, the name of the constant must always
- begin with an upper case letter, or a <c>$</c>, <c>?</c>, or <c>_</c>.
- This also means that it must always be single quoted (obviously, since
- the constant name is actually an atom, not text).</p></note>
+ begin with an uppercase letter, or a <c>$</c>, <c>?</c>, or <c>_</c>.
+ This means that it must always be single quoted (as the constant name is
+ an atom, not text).</p></note>
<p>The main benefit of constants is that they can be used to reduce the size
- (and avoid repetition) of long strings, such as file paths. Compare these
- terms:</p>
+ (and avoid repetition) of long strings, such as file paths.</p>
+ <p><em>Examples:</em></p>
<pre>
- %% 1a. no constant
- {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, "/home/testuser/tests/suites", all}.
-
- %% 1b. with constant
- {define, 'TESTDIR', "/home/testuser/tests"}.
- {config, "'TESTDIR'/config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, "'TESTDIR'/suites", all}.
-
- %% 2a. no constants
- {config, [testnode@host1, testnode@host2], "../config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, [testnode@host1, testnode@host2], "../suites", [x_SUITE, y_SUITE]}.
-
- %% 2b. with constants
- {define, 'NODE', testnode}.
- {define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.
- {config, 'NODES', "../config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, 'NODES', "../suites", [x_SUITE, y_SUITE]}.</pre>
+ %% 1a. no constant
+ {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, "/home/testuser/tests/suites", all}.
+
+ %% 1b. with constant
+ {define, 'TESTDIR', "/home/testuser/tests"}.
+ {config, "'TESTDIR'/config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, "'TESTDIR'/suites", all}.
+
+ %% 2a. no constants
+ {config, [testnode@host1, testnode@host2], "../config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, [testnode@host1, testnode@host2], "../suites", [x_SUITE, y_SUITE]}.
+
+ %% 2b. with constants
+ {define, 'NODE', testnode}.
+ {define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.
+ {config, 'NODES', "../config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, 'NODES', "../suites", [x_SUITE, y_SUITE]}.</pre>
<p>Constants make the test specification term <c>alias</c>, in previous
- versions of Common Test, redundant. This term has been deprecated but will
- remain supported in upcoming Common Test releases. Replacing <c>alias</c>
- terms with <c>define</c> is strongly recommended though! Here's an example
- of such a replacement:</p>
+ versions of <c>Common Test</c>, redundant. This term is deprecated but
+ remains supported in upcoming <c>Common Test</c> releases. Replacing <c>alias</c>
+ terms with <c>define</c> is strongly recommended though. An example
+ of such replacement follows:</p>
<pre>
- %% using the old alias term
- {config, "/home/testuser/tests/config/nodeA.cfg"}.
- {alias, suite_dir, "/home/testuser/tests/suites"}.
- {groups, suite_dir, x_SUITE, group1}.
-
- %% replacing with constants
- {define, 'TestDir', "/home/testuser/tests"}.
- {define, 'CfgDir', "'TestDir'/config"}.
- {define, 'SuiteDir', "'TestDir'/suites"}.
- {config, 'CfgDir', "nodeA.cfg"}.
- {groups, 'SuiteDir', x_SUITE, group1}.</pre>
+ %% using the old alias term
+ {config, "/home/testuser/tests/config/nodeA.cfg"}.
+ {alias, suite_dir, "/home/testuser/tests/suites"}.
+ {groups, suite_dir, x_SUITE, group1}.
+
+ %% replacing with constants
+ {define, 'TestDir', "/home/testuser/tests"}.
+ {define, 'CfgDir', "'TestDir'/config"}.
+ {define, 'SuiteDir', "'TestDir'/suites"}.
+ {config, 'CfgDir', "nodeA.cfg"}.
+ {groups, 'SuiteDir', x_SUITE, group1}.</pre>
- <p>Actually, constants could well replace the <c>node</c> term too, but
- this still has declarative value, mainly when used in combination
- with <c>NodeRefs == all_nodes</c> (see types above).</p>
+ <p>Constants can well replace term <c>node</c> also, but
+ this still has a declarative value, mainly when used in combination
+ with <c>NodeRefs == all_nodes</c>
+ (see <seealso marker="#types">Types</seealso>).</p>
</section>
<section>
@@ -946,79 +1056,104 @@
<p>Here follows a simple test specification example:</p>
<pre>
- {define, 'Top', "/home/test"}.
- {define, 'T1', "'Top'/t1"}.
- {define, 'T2', "'Top'/t2"}.
- {define, 'T3', "'Top'/t3"}.
- {define, 'CfgFile', "config.cfg"}.
-
- {logdir, "'Top'/logs"}.
-
- {config, ["'T1'/'CfgFile'", "'T2'/'CfgFile'", "'T3'/'CfgFile'"]}.
-
- {suites, 'T1', all}.
- {skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
- {skip_cases, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
- {skip_cases, 'T1', t1C_SUITE, [test1], "Ignore"}.
-
- {suites, 'T2', [t2B_SUITE,t2C_SUITE]}.
- {cases, 'T2', t2A_SUITE, [test4,test1,test7]}.
-
- {skip_suites, 'T3', all, "Not implemented"}.</pre>
+ {define, 'Top', "/home/test"}.
+ {define, 'T1', "'Top'/t1"}.
+ {define, 'T2', "'Top'/t2"}.
+ {define, 'T3', "'Top'/t3"}.
+ {define, 'CfgFile', "config.cfg"}.
+
+ {logdir, "'Top'/logs"}.
+
+ {config, ["'T1'/'CfgFile'", "'T2'/'CfgFile'", "'T3'/'CfgFile'"]}.
+
+ {suites, 'T1', all}.
+ {skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
+ {skip_cases, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
+ {skip_cases, 'T1', t1C_SUITE, [test1], "Ignore"}.
+
+ {suites, 'T2', [t2B_SUITE,t2C_SUITE]}.
+ {cases, 'T2', t2A_SUITE, [test4,test1,test7]}.
+
+ {skip_suites, 'T3', all, "Not implemented"}.</pre>
<p>The example specifies the following:</p>
- <list>
- <item>The specified logdir directory will be used for storing
+ <list type="bulleted">
+ <item>The specified <c>logdir</c> directory is used for storing
the HTML log files (in subdirectories tagged with node name,
- date and time).</item>
- <item>The variables in the specified test system config files will be
+ date, and time).</item>
+ <item>The variables in the specified test system configuration files are
imported for the test.</item>
- <item>The first test to run includes all suites for system t1. Excluded from
- the test are however the t1B and t1D suites. Also test cases test3 and
- test4 in t1A as well as the test1 case in t1C are excluded from
- the test.</item>
- <item>Secondly, the test for system t2 should run. The included suites are
- t2B and t2C. Included are also test cases test4, test1 and test7 in suite
- t2A. Note that the test cases will be executed in the specified order.</item>
- <item>Lastly, all suites for systems t3 are to be completely skipped and this
- should be explicitly noted in the log files.</item>
+ <item>The first test to run includes all suites for system <c>t1</c>.
+ Suites <c>t1B</c> and <c>t1D</c> are excluded from the test. Test cases
+ <c>test3</c> and <c>test4</c> in <c>t1A</c> and <c>test1</c> case in <c>t1C</c>
+ are also excluded from the test.</item>
+ <item>The second test to run is for system <c>t2</c>. The included suites are
+ <c>t2B</c> and <c>t2C</c>. Test cases <c>test4</c>, <c>test1</c>, and <c>test7</c> in suite
+ <c>t2A</c> are also included. The test cases are executed in the specified order.</item>
+ <item>The last test to run is for system <c>t3</c>. Here, all suites are skipped and this
+ is explicitly noted in the log files.</item>
</list>
</section>
<section>
- <title>The init term</title>
- <p>With the <c>init</c> term it's possible to specify initialization options
- for nodes defined in the test specification. Currently, there are options
- to start the node and/or to evaluate any function on the node.
- See the <seealso marker="ct_master_chapter#ct_slave">Automatic startup of
- the test target nodes</seealso> chapter for details.</p>
+ <title>The init Term</title>
+ <p>With term <c>init</c> it is possible to specify initialization options
+ for nodes defined in the test specification. There are options
+ to start the node and to evaluate any function on the node.
+ For details, see section <seealso marker="ct_master_chapter#ct_slave">Automatic Startup of
+ Test Target Nodes</seealso> in section Using Common Test for Large Scale Testing.</p>
</section>
<section>
- <title>User specific terms</title>
- <p>It is possible for the user to provide a test specification that
- includes (for Common Test) unrecognizable terms. If this is desired,
- the <c>-allow_user_terms</c> flag should be used when starting tests with
- <c>ct_run</c>. This forces Common Test to ignore unrecognizable terms.
- Note that in this mode, Common Test is not able to check the specification
- for errors as efficiently as if the scanner runs in default mode.
+ <title>User-Specific Terms</title>
+ <p>The user can provide a test specification including (for <c>Common Test</c>)
+ unrecognizable terms. If this is desired, use flag <c>-allow_user_terms</c>
+ when starting tests with <c>ct_run</c>. This forces <c>Common Test</c> to ignore
+ unrecognizable terms. In this mode, <c>Common Test</c> is not able to check the
+ specification for errors as efficiently as if the scanner runs in default mode.
If <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> is used
- for starting the tests, the relaxed scanner
- mode is enabled by means of the tuple: <c>{allow_user_terms,true}</c></p>
+ for starting the tests, the relaxed scanner mode is enabled by tuple
+ <c>{allow_user_terms,true}</c>.</p>
+ </section>
+ <section>
+ <title>Reading Test Specification Terms</title>
+ <p>Terms in the current test specification
+ (that is, the specification that has been used to configure and run the current test)
+ can be looked up.
+ The function <seealso marker="ct#get_testspec_terms-0"><c>get_testspec_terms()</c></seealso>
+ returns a list of all test specification terms (both configuration terms and test terms),
+ and <c>get_testspec_terms(Tags)</c> returns the term (or a list of terms) matching the
+ tag (or tags) in <c>Tags</c>.</p>
+ <p>For example, in the test specification:</p>
+ <pre>
+ ...
+ {label, my_server_smoke_test}.
+ {config, "../../my_server_setup.cfg"}.
+ {config, "../../my_server_interface.cfg"}.
+ ...</pre>
+ <p>And in, for example, a test suite or a <c>Common Test Hook</c> function:</p>
+ <pre>
+ ...
+ [{label,[{_Node,TestType}]}, {config,CfgFiles}] =
+ ct:get_testspec_terms([label,config]),
+
+ [verify_my_server_cfg(TestType, CfgFile) || {Node,CfgFile} &lt;- CfgFiles,
+ Node == node()];
+ ...</pre>
</section>
</section>
<section>
- <title>Running tests from the Web based GUI</title>
+ <title>Running Tests from the Web-Based GUI</title>
- <p>The web based GUI, VTS, is started with the
+ <p>The web-based GUI, Virtual Test Server (VTS), is started with the
<seealso marker="run_test_chapter#ct_run"><c>ct_run</c></seealso>
- program. From the GUI you can load config files, and select
- directories, suites and cases to run. You can also state the
- config files, directories, suites and cases on the command line
- when starting the web based GUI.
+ program. From the GUI, you can load configuration files and select
+ directories, suites, and cases to run. You can also state the
+ configuration files, directories, suites, and cases on the command line
+ when starting the web-based GUI.
</p>
-
- <list>
+ <p><em>Examples:</em></p>
+ <list type="bulleted">
<item><c>ct_run -vts</c></item>
<item><c><![CDATA[ct_run -vts -config <configfilename>]]></c></item>
<item><c><![CDATA[ct_run -vts -config <configfilename> -suite <suitewithfullpath>
@@ -1028,454 +1163,464 @@
<p>From the GUI you can run tests and view the result and the logs.
</p>
- <p>Note that <c>ct_run -vts</c> will try to open the Common Test start
- page in an existing web browser window or start the browser if it is
- not running. Which browser should be started may be specified with
+ <p><c>ct_run -vts</c> tries to open the <c>Common Test</c> start
+ page in an existing web browser window, or start the browser if it is
+ not running. Which browser to start can be specified with
the browser start command option:</p>
<p><c><![CDATA[ct_run -vts -browser <browser_start_cmd>]]></c></p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<p><c><![CDATA[$ ct_run -vts -browser 'firefox&']]></c></p>
- <p>Note that the browser must run as a separate OS process or VTS will hang!</p>
- <p>If no specific browser start command is specified, Firefox will
- be the default browser on Unix platforms and Internet Explorer on Windows.
- If Common Test fails to start a browser automatically, or <c>'none'</c> is
- specified as the value for -browser (i.e. <c>-browser none</c>), start your
- favourite browser manually and type in the URL that Common Test
+
+ <note><p>The browser must run as a separate OS process, otherwise VTS hangs.</p></note>
+
+ <p>If no specific browser start command is specified, Firefox is
+ the default browser on Unix platforms, and Internet Explorer on Windows.
+ If <c>Common Test</c> fails to start a browser automatically, or <c>none</c> is
+ specified as the value for <c>-browser</c> (that is, <c>-browser none</c>), start your
+ favourite browser manually and type the URL that <c>Common Test</c>
displays in the shell.</p>
</section>
<section>
<marker id="log_files"></marker>
- <title>Log files</title>
+ <title>Log Files</title>
<p>As the execution of the test suites proceed, events are logged in
- four different ways:</p>
+ the following four different ways:</p>
- <list>
- <item>Text to the operator's console.</item>
- <item>Suite related information is sent to the major log file.</item>
- <item>Case related information is sent to the minor log file.</item>
- <item>The HTML overview log file gets updated with test results.</item>
+ <list type="bulleted">
+ <item>Text to the operator console.</item>
+ <item>Suite-related information is sent to the major log file.</item>
+ <item>Case-related information is sent to the minor log file.</item>
+ <item>The HTML overview log file is updated with test results.</item>
<item>A link to all runs executed from a certain directory is written in
- the log named "all_runs.html" and direct links to all tests (the
- latest results) are written to the top level "index.html".</item>
+ the log named <c>all_runs.html</c> and direct links to all tests (the
+ latest results) are written to the top-level <c>index.html</c>.</item>
</list>
- <p>Typically the operator, who may run hundreds or thousands of
- test cases, doesn't want to fill the console with details
- about, or printouts from, the specific test cases. By default, the
- operator will only see:</p>
+ <p>Typically the operator, possibly running hundreds or thousands of
+ test cases, does not want to fill the console with details
+ about, or printouts from, specific test cases. By default, the
+ operator only sees the following:</p>
- <list>
+ <list type="bulleted">
<item>A confirmation that the test has started and information about how
- many test cases will be executed totally.</item>
+ many test cases are executed in total.</item>
<item>A small note about each failed test case.</item>
<item>A summary of all the run test cases.</item>
- <item>A confirmation that the test run is complete.</item>
- <item>Some special information like error reports and progress
- reports, printouts written with erlang:display/1, or io:format/3
+ <item>A confirmation when the test run is complete.</item>
+ <item>Some special information, such as error reports, progress
+ reports, and printouts written with <c>erlang:display/1</c>, or <c>io:format/3</c>
specifically addressed to a receiver other than <c>standard_io</c>
- (e.g. the default group leader process 'user').</item>
+ (for example, the default group leader process <c>user</c>).</item>
</list>
- <p>If/when the operator wants to dig deeper into the general results, or
- the result of a specific test case, he should do so by
- following the links in the HTML presentation and take a look in the
- major or minor log files. The "all_runs.html" page is a practical
- starting point usually. It's located in <c>logdir</c> and contains
- a link to each test run including a quick overview (date and time,
- node name, number of tests, test names and test result totals).</p>
+ <p>To dig deeper into the general results, or
+ the result of a specific test case, the operator can do so by
+ following the links in the HTML presentation and read the
+ major or minor log files. The "all_runs.html" page is a good
+ starting point. It is located in <c>logdir</c> and contains
+ a link to each test run, including a quick overview (with date and time,
+ node name, number of tests, test names, and test result totals).</p>
- <p>An "index.html" page is written for each test run (i.e. stored in
- the "ct_run" directory tagged with node name, date and time). This
- file gives a short overview of all individual tests performed in the
- same test run. The test names follow this convention:</p>
- <list>
- <item><em>TopLevelDir.TestDir</em> (all suites in TestDir executed)</item>
- <item><em>TopLevelDir.TestDir:suites</em> (specific suites were executed)</item>
- <item><em>TopLevelDir.TestDir.Suite</em> (all cases in Suite executed)</item>
- <item><em>TopLevelDir.TestDir.Suite:cases</em> (specific test cases were executed)</item>
- <item><em>TopLevelDir.TestDir.Suite.Case</em> (only Case was executed)</item>
+ <p>An "index.html" page is written for each test run (that is, stored in
+ the <c>ct_run</c> directory tagged with node name, date, and time). This
+ file provides an overview of all individual tests performed in the
+ same test run. The test names follow the following convention:</p>
+ <list type="bulleted">
+ <item><c>TopLevelDir.TestDir</c> (all suites in <c>TestDir</c> executed)</item>
+ <item><c>TopLevelDir.TestDir:suites</c> (specific suites executed)</item>
+ <item><c>TopLevelDir.TestDir.Suite</c> (all cases in <c>Suite</c> executed)</item>
+ <item><c>TopLevelDir.TestDir.Suite:cases</c> (specific test cases executed)</item>
+ <item><c>TopLevelDir.TestDir.Suite.Case</c> (only <c>Case</c> executed)</item>
</list>
- <p>On the test run index page there is a link to the Common Test
+ <p>The "test run index" page includes a link to the <c>Common Test</c>
Framework Log file in which information about imported
configuration data and general test progress is written. This
log file is useful to get snapshot information about the test
- run during execution. It can also be very helpful when
+ run during execution. It can also be helpful when
analyzing test results or debugging test suites.</p>
- <p>On the test run index page it is noted if a test has missing
- suites (i.e. suites that Common Test has failed to
+ <p>The "test run index" page indicates if a test has missing
+ suites (that is, suites that <c>Common Test</c> failed to
compile). Names of the missing suites can be found in the
- Common Test Framework Log file.</p>
+ <c>Common Test</c> Framework Log file.</p>
<p>The major log file shows a detailed report of the test run. It
includes test suite and test case names, execution time, the
- exact reason for failures etc. The information is available in both
+ exact reason for failures, and so on. The information is available in both
a file with textual and with HTML representation. The HTML file shows a
- summary which gives a good overview of the test run. It also has links
+ summary that gives a good overview of the test run. It also has links
to each individual test case log file for quick viewing with an HTML
browser.</p>
<p>The minor log files contain full details of every single test
- case, each one in a separate file. This way, it should be
+ case, each in a separate file. This way, it is
straightforward to compare the latest results to that of previous
- test runs, even if the set of test cases changes. If SASL is running,
- its logs will also be printed to the current minor log file by the
+ test runs, even if the set of test cases changes. If application <c>SASL</c>
+ is running, its logs are also printed to the current minor log file by the
<seealso marker="common_test:ct_hooks_chapter#builtin_cths">
cth_log_redirect built-in hook</seealso>.
</p>
- <p>The full name of the minor log file (i.e. the name of the file
+ <p>The full name of the minor log file (that is, the name of the file
including the absolute directory path) can be read during execution
- of the test case. It comes as value in the tuple
+ of the test case. It comes as value in tuple
<c>{tc_logfile,LogFileName}</c> in the <c>Config</c> list (which means it
- can also be read by a pre- or post Common Test hook function). Also,
+ can also be read by a pre- or post <c>Common Test Hook</c> function). Also,
at the start of a test case, this data is sent with an event
- to any installed event handler. Please see the
- <seealso marker="event_handler_chapter#event_handling">Event Handling</seealso>
- chapter for details.
+ to any installed event handler. For details, see section
+ <seealso marker="event_handler_chapter#event_handling">Event Handling</seealso>.
</p>
-
- <p>Which information goes where is user configurable via the
- test server controller. Three threshold values determine what
- comes out on screen, and in the major or minor log files. See
- the OTP Test Server manual for information. The contents that
- goes to the HTML log file is fixed however and cannot be altered.</p>
-
- <p>The log files are written continously during a test run and links are
- always created initially when a test starts. This makes it possible
- to follow test progress simply by refreshing pages in the HTML browser.
+
+ <p>The log files are written continuously during a test run and links are
+ always created initially when a test starts. Thevtest progress can therefore
+ be followed simply by refreshing pages in the HTML browser.
Statistics totals are not presented until a test is complete however.</p>
<section>
<marker id="logopts"></marker>
- <title>Log options</title>
- <p>With the <c>logopts</c> start flag, it's possible to specify
- options that modify some aspects of the logging behaviour.
- Currently, the following options are available:</p>
- <list>
- <item><c>no_src</c></item>
- <item><c>no_nl</c></item>
- </list>
- <p>With <c>no_src</c>, the html version of the test suite source
- code will not be generated during the test run (and consequently
- not be available in the log file system).</p>
- <p>With <c>no_nl</c>, Common Test will not add a newline character
- (\n) to the end of an output string that it receives from a call to e.g.
- <c>io:format/2</c>, and which it prints to the test case log.</p>
+ <title>Log Options</title>
+ <p>With start flag <c>logopts</c> options that modify some aspects
+ of the logging behavior can be specified.
+ The following options are available:</p>
+ <taglist>
+ <tag><c>no_src</c></tag>
+ <item><p>The HTML version of the test suite source code is not
+ generated during the test run (and is consequently not available
+ in the log file system).</p></item>
+ <tag><c>no_nl</c></tag>
+ <item><p><c>Common Test</c> does not add a newline character <c>(\n)</c>
+ to the end of an output string that it receives from a call to, for example,
+ <c>io:format/2</c>, and which it prints to the test case log.</p></item>
+ </taglist>
+
<p>For example, if a test is started with:</p>
<p><c>$ ct_run -suite my_SUITE -logopts no_src</c></p>
<p>then printouts during the test made by successive calls to <c>io:format("x")</c>,
- will appear in the test case log as:</p>
+ appears in the test case log as:</p>
<p><c>xxx</c></p>
- <p>instead of each <c>x</c> printed on a new line, which is the default behaviour.</p>
+ <p>instead of each <c>x</c> printed on a new line, which is the default behavior.</p>
</section>
<section>
<marker id="table_sorting"></marker>
- <title>Sorting HTML table columns</title>
- <p>By clicking the name in the column header of any table (e.g. "Ok", "Case", "Time", etc),
- the table rows are sorted in whatever order makes sense for the type of value (e.g.
- numerical for "Ok" or "Time", and alphabetical for "Case"). The sorting is performed
- by means of JavaScript code, automatically inserted into the HTML log files. Common Test
- uses the <url href="http://jquery.com">jQuery</url> library and the
- <url href="http://tablesorter.com">tablesorter</url> plugin, with customized sorting
- functions, for this implementation.</p>
+ <title>Sorting HTML Table Columns</title>
+ <p>By clicking the name in the column header of any table
+ (for example, "Ok", "Case", "Time", and so on), the table rows are sorted
+ in whatever order makes sense for the type of value (for example,
+ numerical for "Ok" or "Time", and alphabetical for "Case"). The sorting is
+ performed through JavaScript code, automatically inserted into the HTML
+ log files. <c>Common Test</c> uses the <url href="http://jquery.com">jQuery</url>
+ library and the
+ <url href="http://tablesorter.com">tablesorter</url> plugin,
+ with customized sorting functions, for this implementation.</p>
</section>
<section>
<title>The Unexpected I/O Log</title>
- <p>On the test suites overview page you find a link to the Unexpected I/O Log.
- In this log, Common Test saves printouts made with
- <c>ct:log/2</c> and <c>ct:pal/2</c>, as well as captured system error- and
- progress reports, that cannot be associated with particular test cases and
- therefore cannot be written to individual test case log files. This happens e.g.
- if a log printout is made from an external process (not a test case process),
- or if an error- or progress report comes in, during a short interval while Common
- Test is not executing a test case or configuration function, <em>or</em> while
- Common Test is currently executing a parallell test case group.</p>
+ <p>The test suites overview page includes a link to the Unexpected I/O Log.
+ In this log, <c>Common Test</c> saves printouts made with
+ <seealso marker="ct#log-2"><c>ct:log/2</c></seealso> and
+ <seealso marker="ct#pal-2"><c>ct:pal/2</c></seealso>, as well as captured system
+ error- and progress reports, which cannot be associated with particular test cases and
+ therefore cannot be written to individual test case log files. This occurs,
+ for example, if a log printout is made from an external process (not a test
+ case process), <em>or</em> if an error- or progress report comes in, during a short
+ interval while <c>Common Test</c> is not executing a test case or configuration
+ function, <em>or</em> while <c>Common Test</c> is currently executing a parallel
+ test case group.</p>
</section>
<section>
<marker id="pre_post_test_io_log"></marker>
<title>The Pre- and Post Test I/O Log</title>
- <p>On the Common Test Framework Log page you find links to the so called
- Pre- and Post Test I/O Log. In this log, Common Test saves printouts made with
- <c>ct:log/2</c> and <c>ct:pal/2</c>, as well as captured system error-
- and progress reports, that take place before - and after - the actual test run.
+ <p>The <c>Common Test</c> Framework Log page includes links to the
+ Pre- and Post Test I/O Log. In this log, <c>Common Test</c> saves printouts made
+ with <c>ct:log/2</c> and <c>ct:pal/2</c>, as well as captured system error-
+ and progress reports, which take place before, and after, the test run.
Examples of this are printouts from a CT hook init- or terminate function, or
progress reports generated when an OTP application is started from a CT hook
- init function. Another example is an error report generated due to
+ init function. Another example is an error report generated because of
a failure when an external application is stopped from a CT hook terminate function.
All information in these examples ends up in the Pre- and Post Test I/O Log.
For more information on how to synchronize test runs with external user
- applications, please see the
+ applications, see section
<seealso marker="ct_hooks_chapter#synchronizing">Synchronizing</seealso>
- section in the Common Test Hooks chapter.</p>
- <p>Note that logging to file with <c>ct:log/2</c> or <c>ct:pal/2</c>
- only works when Common Test is running. Printouts with <c>ct:pal/2</c>
- are however always displayed on screen.</p>
+ in section Common Test Hooks.</p>
+ <note><p>Logging to file with <c>ct:log/2</c> or <c>ct:pal/2</c>
+ only works when <c>Common Test</c> is running. Printouts with <c>ct:pal/2</c>
+ are however always displayed on screen.</p></note>
</section>
</section>
<section>
<marker id="html_stylesheet"></marker>
<title>HTML Style Sheets</title>
- <p>Common Test uses an HTML Style Sheet (CSS file) to control the look of
- the HTML log files generated during test runs. If, for some reason, the
- log files are not displayed correctly in the browser of your
- choice, or you prefer a more primitive ("pre Common Test v1.6") look
- of the logs, use the start flag/option:</p>
- <pre>basic_html</pre>
- <p>This disables the use of Style Sheets, as well as JavaScripts (see
- table sorting above).</p>
+ <p><c>Common Test</c> uses an HTML Style Sheet (CSS file) to control the look of
+ the HTML log files generated during test runs. If the log files are not
+ displayed correctly in the browser of your choice, or you prefer a more
+ primitive ("pre <c>Common Test</c> v1.6") look of the logs, use the start
+ flag/option:</p>
+ <pre>
+ basic_html</pre>
+ <p>This disables the use of style sheets and JavaScripts (see
+ <seealso marker="#table_sorting">Sorting HTML Table Columns</seealso>).</p>
- <p>Common Test includes an <em>optional</em> feature to allow
+ <p><c>Common Test</c> includes an <em>optional</em> feature to allow
user HTML style sheets for customizing printouts. The
functions in <c>ct</c> that print to a test case HTML log
file (<c>log/3</c> and <c>pal/3</c>) accept <c>Category</c>
- as first argument. With this argument it's possible to
- specify a category that can be mapped to a selector in a CSS
- definition. This is useful especially for coloring text
+ as first argument. With this argument a category can be specified
+ that can be mapped to a selector in a CSS
+ definition. This is useful, especially for coloring text
differently depending on the type of (or reason for) the
printout. Say you want one color for test system
configuration information, a different one for test system
- state information and finally one for errors detected by the
- test case functions. The corresponding style sheet may
- look like this:</p>
+ state information, and finally one for errors detected by the
+ test case functions. The corresponding style sheet can
+ look as follows:</p>
<pre>
- div.sys_config { background:blue; color:white }
- div.sys_state { background:yellow; color:black }
- div.error { background:red; color:white }</pre>
+ div.sys_config { background:blue; color:white }
+ div.sys_state { background:yellow; color:black }
+ div.error { background:red; color:white }</pre>
- <p>To install the CSS file (Common Test inlines the definition in the
- HTML code), the name may be provided when executing <c>ct_run</c>.
- Example:</p>
+ <p>To install the CSS file (<c>Common Test</c> inlines the definition in the
+ HTML code), the name can be provided when executing <c>ct_run</c>.</p>
+ <p><em>Example:</em></p>
<pre>
- $ ct_run -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css</pre>
+ $ ct_run -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css</pre>
- <p>Categories in a CSS file installed with the <c>-stylesheet</c> flag
+ <p>Categories in a CSS file installed with flag <c>-stylesheet</c>
are on a global test level in the sense that they can be used in any
- suite which is part of the test run.</p>
+ suite that is part of the test run.</p>
- <p>It is also possible to install style sheets on a per suite and
- per test case basis. Example:</p>
+ <p>Style sheets can also be installed on a per suite and
+ per test case basis.</p>
+ <p><em>Example:</em></p>
<pre>
- -module(my_SUITE).
- ...
- suite() -> [..., {stylesheet,"suite_categories.css"}, ...].
- ...
- my_testcase(_) ->
- ...
- ct:log(sys_config, "Test node version: ~p", [VersionInfo]),
- ...
- ct:log(sys_state, "Connections: ~p", [ConnectionInfo]),
- ...
- ct:pal(error, "Error ~p detected! Info: ~p", [SomeFault,ErrorInfo]),
- ct:fail(SomeFault).</pre>
+ -module(my_SUITE).
+ ...
+ suite() -> [..., {stylesheet,"suite_categories.css"}, ...].
+ ...
+ my_testcase(_) ->
+ ...
+ ct:log(sys_config, "Test node version: ~p", [VersionInfo]),
+ ...
+ ct:log(sys_state, "Connections: ~p", [ConnectionInfo]),
+ ...
+ ct:pal(error, "Error ~p detected! Info: ~p", [SomeFault,ErrorInfo]),
+ ct:fail(SomeFault).</pre>
<p>If the style sheet is installed as in this example, the categories are
private to the suite in question. They can be used by all test cases in the
- suite, but can not be used by other suites. A suite private style sheet,
- if specified, will be used in favour of a global style sheet (one specified
- with the <c>-stylesheet</c> flag). A stylesheet tuple (as returned by <c>suite/0</c>
- above) can also be returned from a test case info function. In this case the
+ suite, but cannot be used by other suites. A suite private style sheet,
+ if specified, is used in favor of a global style sheet (one specified
+ with flag <c>-stylesheet</c>). A stylesheet tuple (as returned by <c>suite/0</c>
+ above) can also be returned from a test case information function. In this case the
categories specified in the style sheet can only be used in that particular
- test case. A test case private style sheet is used in favour of a suite or
+ test case. A test case private style sheet is used in favor of a suite or
global level style sheet.
</p>
<p>In a tuple <c>{stylesheet,CSSFile}</c>, if <c>CSSFile</c> is specified
- with a path, e.g. <c>"$TEST/styles/categories.css"</c>, this full
- name will be used to locate the file. If only the file name is specified
- however, e.g. "categories.css", then the CSS file is assumed to be located
- in the data directory, <c>data_dir</c>, of the suite. The latter usage is
- recommended since it is portable compared to hard coding path names in the
- suite!</p>
-
- <p>The <c>Category</c> argument in the example above may have the
+ with a path, for example, <c>"$TEST/styles/categories.css"</c>, this full
+ name is used to locate the file. However, if only the file name is specified,
+ for example, <c>categories.css</c>, the CSS file is assumed to be located
+ in the data directory, <c>data_dir</c>, of the suite. The latter use is
+ recommended, as it is portable compared to hard coding path names in the
+ suite.</p>
+
+ <p>Argument <c>Category</c> in the previous example can have the
value (atom) <c>sys_config</c> (white on blue), <c>sys_state</c>
- (black on yellow) or <c>error</c> (white on red).</p>
+ (black on yellow), or <c>error</c> (white on red).</p>
</section>
<section>
<marker id="repeating_tests"></marker>
- <title>Repeating tests</title>
- <p>You can order Common Test to repeat the tests you specify. You can choose
- to repeat tests a certain number of times, repeat tests for a specific period of time,
+ <title>Repeating Tests</title>
+ <p>You can order <c>Common Test</c> to repeat the tests you specify. You can choose
+ to repeat tests a number of times, repeat tests for a specific period of time,
or repeat tests until a particular stop time is reached. If repetition is controlled by
- means of time, it is also possible to specify what action Common Test should
- take upon timeout. Either Common Test performs all tests in the current run before stopping,
- or it stops as soon as the current test job is finished. Repetition can be activated by
- means of <c>ct_run</c> start flags, or tuples in the <c>ct:run:test/1</c>
- option list argument. The flags (options in parenthesis) are:</p>
- <list>
- <item><c>-repeat N ({repeat,N})</c>, where <c>N</c> is a positive integer.</item>
- <item><c>-duration DurTime ({duration,DurTime})</c>, where <c>DurTime</c> is the duration, see below.</item>
- <item><c>-until StopTime ({until,StopTime})</c>, where <c>StopTime</c> is finish time, see below.</item>
+ time, an action for <c>Common Test</c> to take upon time-out can be specified.
+ Either <c>Common Test</c> performs all tests in the current run
+ before stopping, or it stops when the current test job is finished. Repetition
+ can be activated by <c>ct_run</c> start flags, or tuples in the <c>ct:run:test/1</c>
+ option list argument. The flags (options in parentheses) are the following:</p>
+ <list type="bulleted">
+ <item><c>-repeat N ({repeat,N})</c>, where <c>N</c> is a positive integer</item>
+ <item><c>-duration DurTime ({duration,DurTime})</c>, where <c>DurTime</c> is the duration</item>
+ <item><c>-until StopTime ({until,StopTime})</c>, where <c>StopTime</c> is finish time</item>
<item><c>-force_stop ({force_stop,true})</c></item>
<item><c>-force_stop skip_rest ({force_stop,skip_rest})</c></item>
</list>
- <p>The duration time, <c>DurTime</c>, is specified as <c>HHMMSS</c>. Example:
- <c>-duration 012030</c> or <c>{duration,"012030"}</c>, means the tests will
- be executed and (if time allows) repeated, until timeout occurs after 1 h, 20 min
- and 30 secs.
- <c>StopTime</c> can be specified as <c>HHMMSS</c> and is then interpreted as a time today
- (or possibly tomorrow). <c>StopTime</c> can also be specified as <c>YYMoMoDDHHMMSS</c>.
- Example: <c>-until 071001120000</c> or <c>{until,"071001120000"}</c>, which means the tests
- will be executed and (if time allows) repeated, until 12 o'clock on the 1st of Oct 2007.</p>
-
- <p>When timeout occurs, Common Test will never abort the ongoing test case, since
- this might leave the system under test in an undefined, and possibly bad, state.
- Instead Common Test will by default finish the current test
- run before stopping. If the <c>force_stop</c> flag is
- given, Common Test will stop as soon as the current test job
- is finished, and if the <c>force_stop</c> flag is given with
- <c>skip_rest</c> Common Test will only complete the current
- test case and skip the rest of the tests in the test job.
- Note that since Common Test always finishes off at least the
- current test case,
- the time specified with <c>duration</c> or <c>until</c> is never definitive!</p>
-
- <p>Log files from every single repeated test run is saved in normal Common Test fashion (see above).
- Common Test may later support an optional feature to only store the last (and possibly
- the first) set of logs of repeated test runs, but for now the user must be careful not
- to run out of disk space if tests are repeated during long periods of time.</p>
-
- <p>Note that for each test run that is part of a repeated session, information about the
- particular test run is printed in the Common Test Framework Log. There you can read
- the repetition number, remaining time, etc.</p>
-
- <p>Example 1:</p>
+ <taglist>
+ <tag><c>DurTime</c></tag>
+ <item><p>The duration time is specified as <c>HHMMSS</c>, for example, <c>-duration 012030</c>
+ or <c>{duration,"012030"}</c></p>, which means that the tests are executed and
+ (if time allows) repeated until time-out occurs after 1 hour, 20 minutes, and 30 seconds.
+ </item>
+ <tag><c>StopTime</c></tag>
+ <item><p>The finish time can be specified as <c>HHMMSS</c> and is then interpreted as a
+ time today (or possibly tomorrow), but can also be specified as <c>YYMoMoDDHHMMSS</c>,
+ for example, <c>-until 071001120000</c> or <c>{until,"071001120000"}</c>. This means
+ that the tests are executed and (if time allows) repeated, until 12 o'clock on the 1st
+ of October 2007.</p>
+ </item>
+ </taglist>
+
+ <p>When time-out occurs, <c>Common Test</c> never aborts the ongoing test case,
+ as this can leave the SUT in an undefined, and possibly bad, state.
+ Instead <c>Common Test</c>, by default, finishes the current test
+ run before stopping. If flag <c>force_stop</c> is
+ specified, <c>Common Test</c> stops when the current test job
+ is finished. If flag <c>force_stop</c> is specified with
+ <c>skip_rest</c>, <c>Common Test</c> only completes the current
+ test case and skips the remaining tests in the test job.</p>
+ <note><p>As <c>Common Test</c> always finishes at least the current test case,
+ the time specified with <c>duration</c> or <c>until</c> is never definitive.</p></note>
+
+ <p>Log files from every repeated test run is saved in normal <c>Common Test</c>
+ fashion (described earlier).</p>
+ <p><c>Common Test</c> might later support an optional feature to only store the last (and possibly
+ the first) set of logs of repeated test runs, but for now the user must be careful not
+ to run out of disk space if tests are repeated during long periods of time.</p>
+
+ <p>For each test run that is part of a repeated session, information about the
+ particular test run is printed in the <c>Common Test</c> Framework Log. The information
+ includes the repetition number, remaining time, and so on.</p>
+
+ <p><em>Example 1:</em></p>
<pre>
- $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop</pre>
- <p>Here the suites in test directory to1, followed by the suites in to2, will be executed
- in one test run. A timeout event will occur after 10 minutes. As long as there is time
- left, Common Test will repeat the test run (i.e. starting over with the to1 test).
- When the timeout occurs, Common Test will stop as soon as the current job is finished
- (because of the <c>force_stop</c> flag). As a result, the specified test run might be
- aborted after the to1 test and before the to2 test.</p>
-
- <p>Example 2:</p>
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop</pre>
+
+ <p>Here, the suites in test directory <c>to1</c>, followed by the suites in <c>to2</c>, are
+ executed in one test run. A time-out event occurs after 10 minutes. As long as there is
+ time left, <c>Common Test</c> repeats the test run (that is, starting over with test <c>to1</c>).
+ After time-out, <c>Common Test</c> stops when the current job is finished
+ (because of flag <c>force_stop</c>). As a result, the specified test run can be
+ aborted after test <c>to1</c> and before test <c>to2</c>.</p>
+
+ <p><em>Example 2:</em></p>
<pre>
- $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -forces_stop skip_rest</pre>
- <p>Here the same test run as in Example 1, but with the
- <c>force_stop</c> flag set to <c>skip_rest</c>. If the timeout
- occurs while executing tests in directory to1, the rest of the
- test cases in to1 will be skipped and then the test will be
- aborted without running the tests in to2 another time. If the
- timeout occurs while executing tests in directory to2, then the
- rest of the test cases in to2 will be skipped and then the test
- will be aborted.</p>
-
- <p>Example 3:</p>
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -forces_stop skip_rest</pre>
+
+ <p>Here, the same tests as in Example 1 are run, but with flag <c>force_stop</c> set to
+ <c>skip_rest</c>. If time-out occurs while executing tests in directory <c>to1</c>,
+ the remaining test cases in <c>to1</c> are skipped and the test is aborted without
+ running the tests in <c>to2</c> another time. If time-out occurs while executing
+ tests in directory <c>to2</c>, the remaining test cases in <c>to2</c> are skipped and
+ the test is aborted.</p>
+
+ <p><em>Example 3:</em></p>
<pre>
- $ date
- Fri Sep 28 15:00:00 MEST 2007
-
- $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000</pre>
- <p>Here the same test run as in the example above will be executed (and possibly repeated).
- In this example, however, the timeout will occur after 1 hour and when that happens,
- Common Test will finish the entire test run before stopping (i.e. the to1 and to2 test
- will always both be executed in the same test run).</p>
+ $ date
+ Fri Sep 28 15:00:00 MEST 2007
+
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000</pre>
+
+ <p>Here, the same test run as in the previous examples are executed (and possibly repeated).
+ However, when the time-out occurs, after 1 hour, <c>Common Test</c> finishes the entire
+ test run before stopping (that is, both <c>to1</c> and <c>to2</c> are always executed in
+ the same test run).</p>
- <p>Example 4:</p>
+ <p><em>Example 4:</em></p>
<pre>
- $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5</pre>
- <p>Here the test run, including both the to1 and the to2 test, will be repeated 5 times.</p>
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5</pre>
+
+ <p>Here, the test run, including both the <c>to1</c> and the <c>to2</c> test, is repeated
+ five times.</p>
- <note><p>This feature should not be confused with the <c>repeat</c> property of a test
+ <note><p>Do not confuse this feature with the <c>repeat</c> property of a test
case group. The options described here are used to repeat execution of entire test runs,
while the <c>repeat</c> property of a test case group makes it possible to repeat
execution of sets of test cases within a suite. For more information about the latter,
- see the <seealso marker="write_test_chapter#test_case_groups">Writing Test Suites</seealso>
- chapter.</p></note>
+ see section <seealso marker="write_test_chapter#test_case_groups">Test Case Groups </seealso>
+ in section Writing Test Suites.</p></note>
</section>
<section>
<marker id="silent_connections"></marker>
<title>Silent Connections</title>
- <p>The protocol handling processes in Common Test, implemented by ct_telnet,
- ct_ssh, ct_ftp etc, do verbose printing to the test case logs. This can be switched off
- by means of the <c>-silent_connections</c> flag:</p>
+ <p>The protocol handling processes in <c>Common Test</c>, implemented by <c>ct_telnet</c>,
+ <c>ct_ssh</c>, <c>ct_ftp</c>, and so on, do verbose printing to the test case logs.
+ This can be switched off with flag <c>-silent_connections</c>:</p>
<pre>
- ct_run -silent_connections [conn_types]
- </pre>
+ ct_run -silent_connections [conn_types]</pre>
- <p>where <c>conn_types</c> specifies <c>ssh, telnet, ftp, rpc</c> and/or <c>snmp</c>.</p>
+ <p>Here, <c>conn_types</c> specifies SSH, Telnet, FTP, RPC, and/or SNMP.</p>
- <p>Example:</p>
+ <p><em>Example 1:</em></p>
<pre>
- ct_run ... -silent_connections ssh telnet</pre>
- <p>switches off logging for ssh and telnet connections.</p>
+ ct_run ... -silent_connections ssh telnet</pre>
+ <p>This switches off logging for SSH and Telnet connections.</p>
+
+ <p><em>Example 2:</em></p>
<pre>
- ct_run ... -silent_connections</pre>
- <p>switches off logging for all connection types.</p>
+ ct_run ... -silent_connections</pre>
+ <p>This switches off logging for all connection types.</p>
- <p>Fatal communication error and reconnection attempts will always be printed even
- if logging has been suppressed for the connection type in question. However, operations
- such as sending and receiving data will be performed silently.</p>
+ <p>Fatal communication error and reconnection attempts are always printed, even if
+ logging has been suppressed for the connection type in question. However, operations
+ such as sending and receiving data are performed silently.</p>
- <p>It is possible to also specify <c>silent_connections</c> in a test suite. This is
+ <p><c>silent_connections</c> can also be specified in a test suite. This is
accomplished by returning a tuple, <c>{silent_connections,ConnTypes}</c>, in the
- <c>suite/0</c> or test case info list. If <c>ConnTypes</c> is a list of atoms
- (<c>ssh, telnet, ftp, rpc</c> and/or <c>snmp</c>), output for any corresponding connections
- will be suppressed. Full logging is per default enabled for any connection of type not
+ <c>suite/0</c> or test case information list. If <c>ConnTypes</c> is a list of atoms
+ (SSH, Telnet, FTP, RPC and/or SNMP), output for any corresponding connections
+ are suppressed. Full logging is by default enabled for any connection of type not
specified in <c>ConnTypes</c>. Hence, if <c>ConnTypes</c> is the empty list, logging
is enabled for all connections.</p>
- <p>Example:</p>
+ <p><em>Example 3:</em></p>
<pre>
-
- -module(my_SUITE).
+ -module(my_SUITE).
- suite() -> [..., {silent_connections,[telnet,ssh]}, ...].
+ suite() -> [..., {silent_connections,[telnet,ssh]}, ...].
- ...
+ ...
- my_testcase1() ->
- [{silent_connections,[ssh]}].
+ my_testcase1() ->
+ [{silent_connections,[ssh]}].
- my_testcase1(_) ->
- ...
+ my_testcase1(_) ->
+ ...
- my_testcase2(_) ->
- ...
- </pre>
+ my_testcase2(_) ->
+ ...</pre>
- <p>In this example, <c>suite/0</c> tells Common Test to suppress
- printouts from telnet and ssh connections. This is valid for
+ <p>In this example, <c>suite/0</c> tells <c>Common Test</c> to suppress
+ printouts from Telnet and SSH connections. This is valid for
all test cases. However, <c>my_testcase1/0</c> specifies that
- for this test case, only ssh should be silent. The result is
- that <c>my_testcase1</c> will get telnet info (if any) printed
- in the log, but not ssh info. <c>my_testcase2</c> will get no
- info from either connection printed.</p>
+ for this test case, only SSH is to be silent. The result is
+ that <c>my_testcase1</c> gets Telnet information (if any) printed
+ in the log, but not SSH information. <c>my_testcase2</c> gets no
+ information from either connection printed.</p>
- <p><c>silent_connections</c> may also be specified with a term
+ <p><c>silent_connections</c> can also be specified with a term
in a test specification
- (see <seealso marker="run_test_chapter#test_specifications">Test
- Specifications</seealso>). Connections provided with the
- <c>silent_connections</c> start flag/option, will be merged with
- any connections listed in the test specification.</p>
+ (see section <seealso marker="run_test_chapter#test_specifications">Test
+ Specifications</seealso> in section Running Tests and Analyzing Results).
+ Connections provided with start flag/option <c>silent_connections</c>
+ are merged with any connections listed in the test specification.</p>
- <p>The <c>silent_connections</c> start flag/option and test
- specification term, overrides any settings made by the info functions
+ <p>Start flag/option <c>silent_connections</c> and the test
+ specification term override any settings made by the information functions
inside the test suite.</p>
- <note><p>Note that in the current Common Test version, the
- <c>silent_connections</c> feature only works for telnet
- and ssh connections! Support for other connection types will be added
- in future Common Test versions.</p></note>
+ <note><p>In the current <c>Common Test</c> version, the
+ <c>silent_connections</c> feature only works for Telnet
+ and SSH connections. Support for other connection types can be added
+ in future <c>Common Test</c> versions.</p></note>
</section>
</chapter>
diff --git a/lib/common_test/doc/src/test_structure_chapter.xml b/lib/common_test/doc/src/test_structure_chapter.xml
index 3c9e159436..8076244928 100644
--- a/lib/common_test/doc/src/test_structure_chapter.xml
+++ b/lib/common_test/doc/src/test_structure_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,167 +31,167 @@
</header>
<section>
- <title>Test structure</title>
+ <title>General</title>
<p>A test is performed by running one or more test suites. A test suite
- consists of test cases (as well as configuration functions and info
- functions). Test cases may be grouped in so called test case groups.
+ consists of test cases, configuration functions, and information
+ functions. Test cases can be grouped in so called test case groups.
A test suite is an Erlang module and test cases are implemented as
Erlang functions. Test suites are stored in test directories.</p>
</section>
<section>
- <title>Skipping test cases</title>
+ <marker id="skipping_test_cases"></marker>
+ <title>Skipping Test Cases</title>
- <p>It is possible to skip certain test cases, for example if you
- know beforehand that a specific test case fails. This might be
- functionality which isn't yet implemented, a bug that is known but
- not yet fixed or some functionality which doesn't work or isn't
+ <p>Certain test cases can be skipped, for example, if you
+ know beforehand that a specific test case fails. The reason can be
+ functionality that is not yet implemented, a bug that is known but
+ not yet fixed, or some functionality that does not work or is not
applicable on a specific platform.</p>
- <p>There are several different ways to state that one or more
- test cases should be skipped:</p>
- <list>
+ <p>Test cases can be skipped in the following ways:</p>
+ <list type="bulleted">
<item>Using <c>skip_suites</c> and <c>skip_cases</c>
terms in
<seealso marker="run_test_chapter#test_specifications">test specifications</seealso>.
</item>
- <item>Returning <c>{skip,Reason}</c> from the
- <c>init_per_testcase/2</c> or <c>init_per_suite/1</c> functions.</item>
+ <item>Returning <c>{skip,Reason}</c> from function
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> or
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>.</item>
<item>Returning <c>{skip,Reason}</c> from the execution clause
- of the test case.</item>
+ of the test case. The execution clause is called, so the author
+ must ensure that the test case does not run.</item>
</list>
- <p>The latter of course means that the execution clause is
- actually called, so the author must make sure that the test case
- does not run.</p>
-
- <p>When a test case is skipped, it will be noted as <c>SKIPPED</c>
+ <p>When a test case is skipped, it is noted as <c>SKIPPED</c>
in the HTML log.</p>
</section>
<section>
- <title>Definition of terms</title>
+ <title>Definition of Terms</title>
<taglist>
- <tag><em>Auto skipped test case</em></tag>
+ <tag><em>Auto-skipped test case</em></tag>
<item>
- When a configuration function fails (i.e. terminates unexpectedly),
- the test cases that depend on the configuration function will be
- skipped automatically by Common Test. The status of the test cases
- is then "auto skipped". Test cases are also auto skipped by
- Common Test if required configuration data is not available at
- runtime.
+ <p>When a configuration function fails (that is, terminates unexpectedly),
+ the test cases depending on the configuration function are
+ skipped automatically by <c>Common Test</c>. The status of the test cases
+ is then "auto-skipped". Test cases are also "auto-skipped" by
+ <c>Common Test</c> if the required configuration data is unavailable at
+ runtime.</p>
</item>
<tag><em>Configuration function</em></tag>
<item>
- A function in a test suite that is meant to be used for
+ <p>A function in a test suite that is meant to be used for
setting up, cleaning up, and/or verifying the state and
- environment on the SUT (System Under Test) and/or the Common Test
+ environment on the System Under Test (SUT) and/or the <c>Common Test</c>
host node, so that a test case (or a set of test cases) can
- execute correctly.
+ execute correctly.</p>
</item>
<tag><em>Configuration file</em></tag>
<item>
- A file that contains data related to a test and/or an SUT
- (System Under Test), e.g. protocol server addresses, client
- login details, hardware interface addresses, etc - any data
- that should be handled as variable in the suite and not
- be hardcoded.
+ <p>A file containing data related to a test and/or an SUT,
+ for example, protocol server addresses, client
+ login details, and hardware interface addresses. That is, any data
+ that is to be handled as variable in the suite and not
+ be hard-coded.</p>
</item>
<tag><em>Configuration variable</em></tag>
<item>
- A name (an Erlang atom) associated with a data value read from
- a configuration file.
+ <p>A name (an Erlang atom) associated with a data value read from
+ a configuration file.</p>
</item>
- <tag><em>data_dir</em></tag>
+ <tag><c>data_dir</c></tag>
<item>
- Data directory for a test suite. This directory contains
- any files used by the test suite, e.g. additional Erlang
- modules, binaries or data files.
+ <p>Data directory for a test suite. This directory contains
+ any files used by the test suite, for example, extra Erlang
+ modules, binaries, or data files.</p>
</item>
- <tag><em>Info function</em></tag>
+ <tag><em>Information function</em></tag>
<item>
- A function in a test suite that returns a list of properties
- (read by the Common Test server) that describes the conditions
- for executing the test cases in the suite.
+ <p>A function in a test suite that returns a list of properties
+ (read by the <c>Common Test</c> server) that describes the conditions
+ for executing the test cases in the suite.</p>
</item>
<tag><em>Major log file</em></tag>
<item>
- An overview and summary log file for one or more test suites.
+ <p>An overview and summary log file for one or more test suites.</p>
</item>
<tag><em>Minor log file</em></tag>
<item>
- A log file for one particular test case. Also called the
- test case log file.
+ <p>A log file for one particular test case. Also called the
+ test case log file.</p>
</item>
- <tag><em>priv_dir</em></tag>
+
+ <tag><c>priv_dir</c></tag>
<item>
- Private directory for a test suite. This directory should
- be used when the test suite needs to write to files.
+ <p>Private directory for a test suite. This directory is to
+ be used when the test suite needs to write to files.</p>
</item>
- <tag><em>ct_run</em></tag>
+ <tag><c>ct_run</c></tag>
<item>
- The name of an executable program that may be
+ <p>The name of an executable program that can be
used as an interface for specifying and running
- tests with Common Test.
+ tests with <c>Common Test</c>.</p>
</item>
<tag><em>Test case</em></tag>
<item>
- A single test included in a test suite. A test case is
- implemented as a function in a test suite module.
+ <p>A single test included in a test suite. A test case is
+ implemented as a function in a test suite module.</p>
</item>
<tag><em>Test case group</em></tag>
<item>
- A set of test cases that share configuration functions and
- execution properties. The execution properties specify whether
- the test cases in the group should be executed in random order,
- in parallel, in sequence, and if the execution of the group
- should be repeated. Test case groups may also be nested (i.e. a
- group may, besides test cases, contain sub-groups).
+ <p>A set of test cases sharing configuration functions and
+ execution properties. The execution properties specify if
+ the test cases in the group are to be executed in random order,
+ in parallel, or in sequence, and if the execution of the group
+ is be repeated. Test case groups can also be nested. That is,
+ a group can, besides test cases, contain subgroups.</p>
</item>
<tag><em>Test suite</em></tag>
<item>
- An erlang module containing a collection of test cases for
- a specific functional area.
+ <p>An Erlang module containing a collection of test cases for
+ a specific functional area.</p>
</item>
<tag><em>Test directory</em></tag>
<item>
- A directory that contains one or more test suite modules, i.e.
- a group of test suites.
+ <p>A directory containing one or more test suite modules,
+ that is, a group of test suites.</p>
</item>
- <tag><em>The Config argument</em></tag>
+ <tag><em>Argument</em> <c>Config</c></tag>
<item>
- A list of key-value tuples (i.e. a property list) containing
+ <p>A list of key-value tuples (that is, a property list) containing
runtime configuration data passed from the configuration
- functions to the test cases.
+ functions to the test cases.</p>
</item>
- <tag><em>User skipped test case</em></tag>
+ <tag><em>User-skipped test case</em></tag>
<item>
- This is the status of a test case that has been explicitly
- skipped in any of the ways described in the "Skipping test cases"
- section above.
+ <p>The status of a test case explicitly skipped in any of
+ the ways described in section
+ <seealso marker="#skipping_test_cases">Skipping Test Cases</seealso>.
+ </p>
</item>
diff --git a/lib/common_test/doc/src/unix_telnet.xml b/lib/common_test/doc/src/unix_telnet.xml
new file mode 100644
index 0000000000..a064a222d6
--- /dev/null
+++ b/lib/common_test/doc/src/unix_telnet.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2012</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>unix_telnet</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>unix_telnet.xml</file>
+ </header>
+ <module>unix_telnet</module>
+ <modulesummary>Callback module for ct_telnet, for connecting to a Telnet
+ server on a UNIX host.</modulesummary>
+
+ <description>
+
+ <p>Callback module for
+ <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>,
+ for connecting to a Telnet server on a UNIX host.</p>
+
+ <p>It requires the following entry in the configuration file:</p>
+
+ <pre>
+ {unix,[{telnet,HostNameOrIpAddress},
+ {port,PortNum}, % optional
+ {username,UserName},
+ {password,Password},
+ {keep_alive,Bool}]}. % optional</pre>
+
+ <p>To communicate through Telnet to the host specified by
+ <c>HostNameOrIpAddress</c>, use the interface functions in
+ <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>, for example,
+ <c>open(Name)</c> and <c>cmd(Name,Cmd)</c>.</p>
+
+ <p><c>Name</c> is the name you allocated to the Unix host in your
+ <c>require</c> statement, for example:</p>
+
+ <pre>
+ suite() -&gt; [{require,Name,{unix,[telnet]}}].</pre>
+
+ <p>or</p>
+
+ <pre>
+ ct:require(Name,{unix,[telnet]}).</pre>
+
+ <p>The "keep alive" activity (that is, that <c>Common Test</c> sends NOP
+ to the server every 10 seconds if the connection is idle) can be
+ enabled or disabled for one particular connection as described here.
+ It can be disabled for all connections using <c>telnet_settings</c>
+ (see <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>).</p>
+
+ <p>The <c>{port,PortNum}</c> tuple is optional and if omitted, default
+ Telnet port 23 is used. Also the <c>keep_alive</c> tuple is optional,
+ and the value defauls to <c>true</c> (enabled).</p>
+ </description>
+
+ <funcs>
+ <func>
+ <name>connect(ConnName, Ip, Port, Timeout, KeepAlive, TCPNoDelay, Extra) -&gt; {ok, Handle} | {error, Reason}</name>
+ <fsummary>Callback for ct_telnet.erl.</fsummary>
+ <type>
+ <v>ConnName = target_name()</v>
+ <v>Ip = string() | {integer(), integer(), integer(), integer()}</v>
+ <v>Port = integer()</v>
+ <v>Timeout = integer()</v>
+ <v>KeepAlive = bool()</v>
+ <v>TCPNoDelay = bool()</v>
+ <v>Extra = target_name() | {Username, Password}</v>
+ <v>Username = string()</v>
+ <v>Password = string()</v>
+ <v>Handle = handle()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="connect-6"/>
+ <p>Callback for <c>ct_telnet.erl</c>.</p>
+
+ <p>Setup Telnet connection to a Unix host.</p>
+
+ <p>For <c>target_name()</c>, see
+ <seealso marker="ct"><c>ct</c></seealso>. For <c>handle()</c>, see
+ <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_prompt_regexp() -&gt; PromptRegexp</name>
+ <fsummary>Callback for ct_telnet.erl.</fsummary>
+ <type>
+ <v>PromptRegexp = prompt_regexp()</v>
+ </type>
+ <desc><marker id="get_prompt_regexp-0"/>
+ <p>Callback for <c>ct_telnet.erl</c>.</p>
+
+ <p>Returns a suitable <c>regexp</c> string matching common prompts
+ for users on Unix hosts.</p>
+
+ <p>For <c>prompt_regexp()</c>, see
+ <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p><seealso marker="ct"><c>ct</c></seealso>,
+ <seealso marker="ct_telnet"><c>ct_telnet</c></seealso></p>
+ </section>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/why_test_chapter.xml b/lib/common_test/doc/src/why_test_chapter.xml
index db94c6a6cb..ff6000628b 100644
--- a/lib/common_test/doc/src/why_test_chapter.xml
+++ b/lib/common_test/doc/src/why_test_chapter.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Some thoughts about testing</title>
+ <title>Some Thoughts about Testing</title>
<prepared>Siri Hansen</prepared>
<docno></docno>
<date></date>
@@ -33,54 +34,53 @@
<section>
<title>Goals</title>
- <p>It's not possible to prove that a program is correct by
+ <p>It is not possible to prove that a program is correct by
testing. On the contrary, it has been formally proven that it is
impossible to prove programs in general by testing. Theoretical
- program proofs or plain examination of code may be viable options
- for those that wish to certify that a program is correct. The test
+ program proofs or plain examination of code can be viable options
+ for those wishing to certify that a program is correct. The test
server, as it is based on testing, cannot be used for
certification. Its intended use is instead to (cost effectively)
<em>find bugs</em>. A successful test suite is one that reveals a
- bug. If a test suite results in Ok, then we know very little that
- we didn't know before.</p>
+ bug. If a test suite results in OK, then we know very little that
+ we did not know before.</p>
</section>
<section>
- <title>What to test?</title>
+ <title>What to Test</title>
<p>
There are many kinds of test suites. Some concentrate on
calling every function or command (in the documented way) in
a certain interface.
- Some other do the same, but uses all kinds of illegal
- parameters, and verifies that the server stays alive and rejects
+ Some others do the same, but use all kinds of illegal
+ parameters, and verify that the server stays alive and rejects
the requests with reasonable error codes. Some test suites
simulate an application (typically consisting of a few modules of
- an application), some try to do tricky requests in general, some
+ an application), some try to do tricky requests in general, and some
test suites even test internal functions with help of special
- load-modules on target.</p>
+ Load Modules on target.</p>
- <p>Another interesting category of test suites are the ones that
- check that fixed bugs don't reoccur. When a bugfix is introduced,
- a test case that checks for that specific bug should be written
- and submitted to the affected test suite(s).</p>
+ <p>Another interesting category of test suites is the one
+ checking that fixed bugs do not reoccur. When a bugfix is introduced,
+ a test case that checks for that specific bug is written
+ and submitted to the affected test suites.</p>
<p>Aim for finding bugs. Write whatever test that has the highest
probability of finding a bug, now or in the future. Concentrate
- more on the critical parts. Bugs in critical subsystems are a lot
+ more on the critical parts. Bugs in critical subsystems are much
more expensive than others.</p>
<p>Aim for functionality testing rather than implementation
details. Implementation details change quite often, and the test
- suites should be long lived. Often implementation details differ
+ suites are to be long lived. Implementation details often differ
on different platforms and versions. If implementation details
- have to be tested, try to factor them out into separate test
- cases. Later on these test cases may be rewritten, or just
- skipped.</p>
+ must be tested, try to factor them out into separate test
+ cases. These test cases can later be rewritten or skipped.</p>
- <p>Also, aim for testing everything once, no less, no more. It's
- not effective having every test case fail just because one
+ <p>Also, aim for testing everything once, no less, no more. It is
+ not effective having every test case fail only because one
function in the interface changed.</p>
</section>
diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml
index 055fb90641..a7a652d506 100644
--- a/lib/common_test/doc/src/write_test_chapter.xml
+++ b/lib/common_test/doc/src/write_test_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,84 +32,88 @@
<section>
<marker id="intro"></marker>
- <title>Support for test suite authors</title>
+ <title>Support for Test Suite Authors</title>
- <p>The <c>ct</c> module provides the main interface for writing
- test cases. This includes e.g:</p>
+ <p>The <seealso marker="ct"><c>ct</c></seealso> module provides the main
+ interface for writing test cases. This includes for example, the following:</p>
- <list>
+ <list type="bulleted">
<item>Functions for printing and logging</item>
<item>Functions for reading configuration data</item>
<item>Function for terminating a test case with error reason</item>
<item>Function for adding comments to the HTML overview page</item>
</list>
- <p>Please see the reference manual for the <c>ct</c>
- module for details about these functions.</p>
+ <p>For details about these functions, see module <seealso marker="ct"><c>ct</c></seealso>.</p>
- <p>The CT application also includes other modules named
- <c><![CDATA[ct_<component>]]></c> that
+ <p>The <c>Common Test</c> application also includes other modules named
+ <c><![CDATA[ct_<component>]]></c>, which
provide various support, mainly simplified use of communication
- protocols such as rpc, snmp, ftp, telnet, etc.</p>
+ protocols such as RPC, SNMP, FTP, Telnet, and others.</p>
</section>
<section>
- <title>Test suites</title>
+ <title>Test Suites</title>
<p>A test suite is an ordinary Erlang module that contains test
cases. It is recommended that the module has a name on the form
<c>*_SUITE.erl</c>. Otherwise, the directory and auto compilation
- function in CT will not be able to locate it (at least not per default).
+ function in <c>Common Test</c> cannot locate it (at least not by default).
</p>
<p>It is also recommended that the <c>ct.hrl</c> header file is included
in all test suite modules.
</p>
- <p>Each test suite module must export the function <c>all/0</c>
+ <p>Each test suite module must export function
+ <seealso marker="common_test#Module:all-0"><c>all/0</c></seealso>,
which returns the list of all test case groups and test cases
to be executed in that module.
</p>
- <p>The callback functions that the test suite should implement, and
- which will be described in more detail below, are
- all listed in the <seealso marker="common_test">common_test
- reference manual page</seealso>.
+ <p>The callback functions to be implemented by the test suite are
+ all listed in module <seealso marker="common_test">common_test
+ </seealso>. They are also described in more detail later in this User's Guide.
</p>
</section>
<section>
- <title>Init and end per suite</title>
+ <title>Init and End per Suite</title>
- <p>Each test suite module may contain the optional configuration functions
- <c>init_per_suite/1</c> and <c>end_per_suite/1</c>. If the init function
- is defined, so must the end function be.
+ <p>Each test suite module can contain the optional configuration functions
+ <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>
+ and <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite/1</c></seealso>.
+ If the init function is defined, so must the end function be.
</p>
- <p>If it exists, <c>init_per_suite</c> is called initially before the
- test cases are executed. It typically contains initializations that are
- common for all test cases in the suite, and that are only to be
- performed once. It is recommended to be used for setting up and
- verifying state and environment on the SUT (System Under Test) and/or
- the CT host node, so that the test cases in the suite will execute
- correctly. Examples of initial configuration operations: Opening a connection
- to the SUT, initializing a database, running an installation script, etc.
+ <p>If <c>init_per_suite</c> exists, it is called initially before the
+ test cases are executed. It typically contains initializations common
+ for all test cases in the suite, which are only to be performed once.
+ <c>init_per_suite</c> is recommended for setting up and verifying state
+ and environment on the System Under Test (SUT) or the <c>Common Test</c>
+ host node, or both, so that the test cases in the suite executes correctly.
+ The following are examples of initial configuration operations:
</p>
+ <list type="bulleted">
+ <item>Opening a connection to the SUT</item>
+ <item>Initializing a database</item>
+ <item>Running an installation script</item>
+ </list>
<p><c>end_per_suite</c> is called as the final stage of the test suite execution
(after the last test case has finished). The function is meant to be used
for cleaning up after <c>init_per_suite</c>.
</p>
- <p><c>init_per_suite</c> and <c>end_per_suite</c> will execute on dedicated
+ <p><c>init_per_suite</c> and <c>end_per_suite</c> execute on dedicated
Erlang processes, just like the test cases do. The result of these functions
- is however not included in the test run statistics of successful, failed and
+ is however not included in the test run statistics of successful, failed, and
skipped cases.
</p>
- <p>The argument to <c>init_per_suite</c> is <c>Config</c>, the
+ <p>The argument to <c>init_per_suite</c> is <c>Config</c>, that is, the
same key-value list of runtime configuration data that each test case takes
as input argument. <c>init_per_suite</c> can modify this parameter with
information that the test cases need. The possibly modified <c>Config</c>
@@ -116,671 +121,683 @@
</p>
<p>If <c>init_per_suite</c> fails, all test cases in the test
- suite will be skipped automatically (so called <em>auto skipped</em>),
+ suite are skipped automatically (so called <em>auto skipped</em>),
including <c>end_per_suite</c>.
</p>
- <p>Note that if <c>init_per_suite</c> and <c>end_per_suite</c> do not exist
- in the suite, Common Test calls dummy functions (with the same names)
- instead, so that output generated by hook functions may be saved to the log
- files for these dummies
- (see the <seealso marker="ct_hooks_chapter#manipulating">Common Test Hooks</seealso>
- chapter for more information).
+ <p>Notice that if <c>init_per_suite</c> and <c>end_per_suite</c> do not exist
+ in the suite, <c>Common Test</c> calls dummy functions (with the same names)
+ instead, so that output generated by hook functions can be saved to the log
+ files for these dummies. For details, see
+ <seealso marker="ct_hooks_chapter#manipulating">Common Test Hooks</seealso>.
</p>
</section>
<section>
<marker id="per_testcase"/>
- <title>Init and end per test case</title>
+ <title>Init and End per Test Case</title>
<p>Each test suite module can contain the optional configuration functions
- <c>init_per_testcase/2</c> and <c>end_per_testcase/2</c>. If the init function
- is defined, so must the end function be.</p>
+ <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso>
+ and <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>.
+ If the init function is defined, so must the end function be.</p>
- <p>If it exists, <c>init_per_testcase</c> is called before each
- test case in the suite. It typically contains initialization which
- must be done for each test case (analogue to <c>init_per_suite</c> for the
+ <p>If <c>init_per_testcase</c> exists, it is called before each
+ test case in the suite. It typically contains initialization that
+ must be done for each test case (analog to <c>init_per_suite</c> for the
suite).</p>
<p><c>end_per_testcase/2</c> is called after each test case has
- finished, giving the opportunity to perform clean-up after
- <c>init_per_testcase</c>.</p>
+ finished, enabling cleanup after <c>init_per_testcase</c>.</p>
<p>The first argument to these functions is the name of the test
case. This value can be used with pattern matching in function clauses
or conditional expressions to choose different initialization and cleanup
- routines for different test cases, or perform the same routine for a number of,
+ routines for different test cases, or perform the same routine for many,
or all, test cases.</p>
<p>The second argument is the <c>Config</c> key-value list of runtime
configuration data, which has the same value as the list returned by
- <c>init_per_suite</c>. <c>init_per_testcase/2</c> may modify this
- parameter or return it as is. The return value of <c>init_per_testcase/2</c>
- is passed as the <c>Config</c> parameter to the test case itself.</p>
+ <c>init_per_suite</c>. <c>init_per_testcase/2</c> can modify this
+ parameter or return it "as is". The return value of <c>init_per_testcase/2</c>
+ is passed as parameter <c>Config</c> to the test case itself.</p>
<p>The return value of <c>end_per_testcase/2</c> is ignored by the
test server, with exception of the
- <seealso marker="dependencies_chapter#save_config">save_config</seealso>
+ <seealso marker="dependencies_chapter#save_config"><c>save_config</c></seealso>
and <c>fail</c> tuple.</p>
- <p>It is possible in <c>end_per_testcase</c> to check if the
- test case was successful or not (which consequently may determine
- how cleanup should be performed). This is done by reading the value
- tagged with <c>tc_status</c> from <c>Config</c>. The value is either
- <c>ok</c>, <c>{failed,Reason}</c> (where <c>Reason</c> is <c>timetrap_timeout</c>,
- info from <c>exit/1</c>, or details of a run-time error), or
- <c>{skipped,Reason}</c> (where Reason is a user specific term).
+ <p><c>end_per_testcase</c> can check if the test case was successful.
+ (which in turn can determine how cleanup is to be performed).
+ This is done by reading the value tagged with <c>tc_status</c> from
+ <c>Config</c>. The value is one of the following:
</p>
-
- <p>The <c>end_per_testcase/2</c> function is called even after a
- test case terminates due to a call to <seealso marker="ct#abort_current_testcase-1"><c>ct:abort_current_testcase/1</c></seealso>,
- or after a timetrap timeout. However, <c>end_per_testcase</c>
- will then execute on a different process than the test case
- function, and in this situation, <c>end_per_testcase</c> will
- not be able to change the reason for test case termination by
- returning <c>{fail,Reason}</c>, nor will it be able to save data with
- <c>{save_config,Data}</c>.</p>
-
- <p>If <c>init_per_testcase</c> crashes, the test case itself gets skipped
- automatically (so called <em>auto skipped</em>). If <c>init_per_testcase</c>
- returns a tuple <c>{skip,Reason}</c>, also then the test case gets skipped
- (so called <em>user skipped</em>). It is also possible, by returning a tuple
- <c>{fail,Reason}</c> from <c>init_per_testcase</c>, to mark the test case
- as failed without actually executing it.
+ <list type="bulleted">
+ <item>
+ <p><c>ok</c></p>
+ </item>
+ <item>
+ <p><c>{failed,Reason}</c></p>
+ <p>where <c>Reason</c> is <c>timetrap_timeout</c>, information from <c>exit/1</c>,
+ or details of a runtime error</p></item>
+ <item>
+ <p><c>{skipped,Reason}</c></p>
+ <p>where <c>Reason</c> is a user-specific term</p></item>
+ </list>
+
+ <p>Function <c>end_per_testcase/2</c> is even called if a
+ test case terminates because of a call to
+ <seealso marker="ct#abort_current_testcase-1"><c>ct:abort_current_testcase/1</c></seealso>,
+ or after a timetrap time-out. However, <c>end_per_testcase</c>
+ then executes on a different process than the test case
+ function. In this situation, <c>end_per_testcase</c> cannot
+ change the reason for test case termination by returning <c>{fail,Reason}</c>
+ or save data with <c>{save_config,Data}</c>.</p>
+
+ <p>The test case is skipped in the following two cases:
</p>
+ <list type="bulleted">
+ <item>If <c>init_per_testcase</c> crashes (called <em>auto skipped</em>).</item>
+ <item>If <c>init_per_testcase</c> returns a tuple <c>{skip,Reason}</c>
+ (called <em>user skipped</em>).</item>
+ </list>
+ <p>The test case can also be marked as failed without executing it
+ by returning a tuple <c>{fail,Reason}</c> from <c>init_per_testcase</c>.</p>
+
<note><p>If <c>init_per_testcase</c> crashes, or returns <c>{skip,Reason}</c>
- or <c>{fail,Reason}</c>, the <c>end_per_testcase</c> function is not called.
+ or <c>{fail,Reason}</c>, function <c>end_per_testcase</c> is not called.
</p></note>
<p>If it is determined during execution of <c>end_per_testcase</c> that
- the status of a successful test case should be changed to failed,
- <c>end_per_testcase</c> may return the tuple: <c>{fail,Reason}</c>
+ the status of a successful test case is to be changed to failed,
+ <c>end_per_testcase</c> can return the tuple <c>{fail,Reason}</c>
(where <c>Reason</c> describes why the test case fails).</p>
- <p><c>init_per_testcase</c> and <c>end_per_testcase</c> execute on the
- same Erlang process as the test case and printouts from these
- configuration functions can be found in the test case log file.</p>
+ <p>As <c>init_per_testcase</c> and <c>end_per_testcase</c> execute on the
+ same Erlang process as the test case, printouts from these
+ configuration functions are included in the test case log file.</p>
</section>
<section>
<marker id="test_cases"></marker>
- <title>Test cases</title>
+ <title>Test Cases</title>
<p>The smallest unit that the test server is concerned with is a
- test case. Each test case can actually test many things, for
- example make several calls to the same interface function with
+ test case. Each test case can test many things, for
+ example, make several calls to the same interface function with
different parameters.
</p>
- <p>It is possible to choose to put many or few tests into each test
- case. What exactly each test case does is of course up to the
- author, but here are some things to keep in mind:
+ <p>The author can choose to put many or few tests into each test
+ case. Some things to keep in mind follows:
</p>
-
- <p>Having many small test cases tend to result in extra, and possibly
+ <list type="bulleted">
+ <item><p>Many small test cases tend to result in extra, and possibly
duplicated code, as well as slow test execution because of
- large overhead for initializations and cleanups. Duplicated
- code should be avoided, e.g. by means of common help functions, or
- the resulting suite will be difficult to read and understand, and
+ large overhead for initializations and cleanups. Avoid duplicated
+ code, for example, by using common help functions. Otherwise,
+ the resulting suite becomes difficult to read and understand, and
expensive to maintain.
- </p>
-
- <p>Larger test cases make it harder to tell what went wrong if it
- fails, and large portions of test code will potentially be skipped
- when errors occur. Furthermore, readability and maintainability suffers
- when test cases become too large and extensive. Also, the resulting log
- files may not reflect very well the number of tests that have
- actually been performed.
- </p>
+ </p></item>
+ <item><p>Larger test cases make it harder to tell what went wrong if it
+ fails. Also, large portions of test code risk being skipped
+ when errors occur.</p>
+ </item>
+ <item><p>Readability and maintainability suffer
+ when test cases become too large and extensive. It is not certain
+ that the resulting log files reflect very well the number of tests
+ performed.
+ </p></item>
+ </list>
<p>The test case function takes one argument, <c>Config</c>, which
contains configuration information such as <c>data_dir</c> and
- <c>priv_dir</c>. (See <seealso marker="#data_priv_dir">Data and
- Private Directories</seealso> for more information about these).
- The value of <c>Config</c> at the time of the call, is the same
- as the return value from <c>init_per_testcase</c>, see above.
+ <c>priv_dir</c>. (For details about these, see section
+ <seealso marker="#data_priv_dir">Data and Private Directories</seealso>.
+ The value of <c>Config</c> at the time of the call, is the same
+ as the return value from <c>init_per_testcase</c>, mentioned earlier.
</p>
- <note><p>The test case function argument <c>Config</c> should not be
- confused with the information that can be retrieved from
+ <note><p>The test case function argument <c>Config</c> is not to be
+ confused with the information that can be retrieved from the
configuration files (using <seealso marker="ct#get_config-1"><c>
- ct:get_config/1/2</c></seealso>). The Config argument
- should be used for runtime configuration of the test suite and the
- test cases, while configuration files should typically contain data
+ ct:get_config/1/2</c></seealso>). The test case argument <c>Config</c>
+ is to be used for runtime configuration of the test suite and the
+ test cases, while configuration files are to contain data
related to the SUT. These two types of configuration data are handled
- differently!</p></note>
+ differently.</p></note>
- <p>Since the <c>Config</c> parameter is a list of key-value tuples, i.e.
- a data type generally called a property list, it can be handled by means of the
- <c>proplists</c> module in the OTP <c>stdlib</c>. A value can for example
- be searched for and returned with the <c>proplists:get_value/2</c> function.
- Also, or alternatively, you might want to look in the general <c>lists</c> module,
- also in <c>stdlib</c>, for useful functions. Normally, the only operations you
- ever perform on <c>Config</c> is insert (adding a tuple to the head of the list)
- and lookup. Common Test provides a simple macro named <c>?config</c>, which returns
- a value of an item in <c>Config</c> given the key (exactly like
+ <p>As parameter <c>Config</c> is a list of key-value tuples, that is,
+ a data type called a property list, it can be handled by the
+ <seealso marker="stdlib:proplists"><c>stdlib:proplists</c></seealso> module.
+ A value can, for example, be searched for and returned with function
+ <seealso marker="stdlib:proplists#get_value-2"><c>proplists:get_value/2</c></seealso>.
+ Also, or alternatively, the general <seealso marker="stdlib:lists"><c>stdlib:lists</c></seealso>
+ module contains useful functions. Normally, the only operations
+ performed on <c>Config</c> is insert (adding a tuple to the head of the list)
+ and lookup. <c>Common Test</c> provides a simple macro named <c>?config</c>,
+ which returns a value of an item in <c>Config</c> given the key (exactly like
<c>proplists:get_value</c>). Example: <c>PrivDir = ?config(priv_dir, Config)</c>.
</p>
<p>If the test case function crashes or exits purposely, it is considered
- <em>failed</em>. If it returns a value (no matter what actual value) it is
+ <em>failed</em>. If it returns a value (no matter what value), it is
considered successful. An exception to this rule is the return value
<c>{skip,Reason}</c>. If this tuple is returned, the test case is considered
- skipped and gets logged as such.</p>
+ skipped and is logged as such.</p>
<p>If the test case returns the tuple <c>{comment,Comment}</c>, the case
- is considered successful and <c>Comment</c> is printed out in the overview
- log file. This is by the way equal to calling <c>ct:comment(Comment)</c>.
+ is considered successful and <c>Comment</c> is printed in the overview
+ log file. This is equal to calling
+ <seealso marker="ct#comment-1"><c>ct:comment(Comment)</c></seealso>.
</p>
</section>
<section>
<marker id="info_function"></marker>
- <title>Test case info function</title>
+ <title>Test Case Information Function</title>
- <p>For each test case function there can be an additional function
- with the same name but with no arguments. This is the test case
- info function. The test case info function is expected to return a
- list of tagged tuples that specifies various properties regarding the
- test case.
+ <p>For each test case function there can be an extra function
+ with the same name but without arguments. This is the test case
+ information function. It is expected to return a list of tagged
+ tuples that specifies various properties regarding the test case.
</p>
<p>The following tags have special meaning:</p>
<taglist>
- <tag><em><c>timetrap</c></em></tag>
+ <tag><c>timetrap</c></tag>
<item>
<p>
- Set the maximum time the test case is allowed to execute. If
- the timetrap time is exceeded, the test case fails with
- reason <c>timetrap_timeout</c>. Note that <c>init_per_testcase</c>
+ Sets the maximum time the test case is allowed to execute. If
+ this time is exceeded, the test case fails with
+ reason <c>timetrap_timeout</c>. Notice that <c>init_per_testcase</c>
and <c>end_per_testcase</c> are included in the timetrap time.
- Please see the <seealso marker="write_test_chapter#timetraps">Timetrap</seealso>
- section for more details.
+ For details, see section
+ <seealso marker="write_test_chapter#timetraps">Timetrap Time-Outs</seealso>.
</p>
</item>
- <tag><em><c>userdata</c></em></tag>
+ <tag><c>userdata</c></tag>
<item>
<p>
- Use this to specify arbitrary data related to the testcase. This
- data can be retrieved at any time using the <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>
+ Specifies any data related to the test case. This
+ data can be retrieved at any time using the
+ <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>
utility function.
</p>
</item>
- <tag><em><c>silent_connections</c></em></tag>
+ <tag><c>silent_connections</c></tag>
<item>
<p>
- Please see the
- <seealso marker="run_test_chapter#silent_connections">Silent Connections</seealso>
- chapter for details.
+ For details, see section
+ <seealso marker="run_test_chapter#silent_connections">Silent Connections</seealso>.
</p>
</item>
- <tag><em><c>require</c></em></tag>
+ <tag><c>require</c></tag>
<item>
<p>
- Use this to specify configuration variables that are required by the
+ Specifies configuration variables required by the
test case. If the required configuration variables are not
found in any of the test system configuration files, the test case is
skipped.</p>
<p>
- It is also possible to give a required variable a default value that will
+ A required variable can also be given a default value to
be used if the variable is not found in any configuration file. To specify
- a default value, add a tuple on the form:
- <c>{default_config,ConfigVariableName,Value}</c> to the test case info list
+ a default value, add a tuple on the form
+ <c>{default_config,ConfigVariableName,Value}</c> to the test case information list
(the position in the list is irrelevant).
- Examples:</p>
+ </p>
+ <p><em>Examples:</em></p>
<pre>
- testcase1() ->
- [{require, ftp},
- {default_config, ftp, [{ftp, "my_ftp_host"},
- {username, "aladdin"},
- {password, "sesame"}]}}].</pre>
+ testcase1() ->
+ [{require, ftp},
+ {default_config, ftp, [{ftp, "my_ftp_host"},
+ {username, "aladdin"},
+ {password, "sesame"}]}}].</pre>
<pre>
- testcase2() ->
- [{require, unix_telnet, unix},
- {require, {unix, [telnet, username, password]}},
- {default_config, unix, [{telnet, "my_telnet_host"},
- {username, "aladdin"},
- {password, "sesame"}]}}].</pre>
+ testcase2() ->
+ [{require, unix_telnet, unix},
+ {require, {unix, [telnet, username, password]}},
+ {default_config, unix, [{telnet, "my_telnet_host"},
+ {username, "aladdin"},
+ {password, "sesame"}]}}].</pre>
</item>
</taglist>
- <p>See the <seealso marker="config_file_chapter#require_config_data">Config files</seealso>
- chapter and the <seealso marker="ct#require-1"><c>
- ct:require/1/2</c></seealso> function in the
- <seealso marker="ct">ct</seealso> reference manual for more information about
- <c>require</c>.</p>
+ <p>For more information about <c>require</c>, see section
+ <seealso marker="config_file_chapter#require_config_data">
+ Requiring and Reading Configuration Data</seealso>
+ in section External Configuration Data and function
+ <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p>
<note><p>Specifying a default value for a required variable can result
- in a test case always getting executed. This might not be a desired behaviour!</p>
+ in a test case always getting executed. This might not be a desired behavior.</p>
</note>
- <p>If <c>timetrap</c> and/or <c>require</c> is not set specifically for
- a particular test case, default values specified by the <c>suite/0</c>
- function are used.
+ <p>If <c>timetrap</c> or <c>require</c>, or both, is not set specifically for
+ a particular test case, default values specified by function
+ <seealso marker="common_test#Module:suite-0"><c>suite/0</c></seealso>
+ are used.
</p>
- <p>Other tags than the ones mentioned above will simply be ignored by
- the test server.
+ <p>Tags other than the earlier mentioned are ignored by the test server.
</p>
<p>
- Example of a test case info function:
+ An example of a test case information function follows:
</p>
<pre>
- reboot_node() ->
- [
- {timetrap,{seconds,60}},
- {require,interfaces},
- {userdata,
- [{description,"System Upgrade: RpuAddition Normal RebootNode"},
- {fts,"http://someserver.ericsson.se/test_doc4711.pdf"}]}
- ].</pre>
+ reboot_node() ->
+ [
+ {timetrap,{seconds,60}},
+ {require,interfaces},
+ {userdata,
+ [{description,"System Upgrade: RpuAddition Normal RebootNode"},
+ {fts,"http://someserver.ericsson.se/test_doc4711.pdf"}]}
+ ].</pre>
</section>
<section>
<marker id="suite"></marker>
- <title>Test suite info function</title>
-
- <p>The <c>suite/0</c> function can be used in a test suite
- module to e.g. set a default <c>timetrap</c> value and to
- <c>require</c> external configuration data. If a test case-, or
- group info function also specifies any of the info tags, it
- overrides the default values set by <c>suite/0</c>. See the test
- case info function above, and group info function below, for more
- details.
+ <title>Test Suite Information Function</title>
+
+ <p>Function <seealso marker="common_test#Module:suite-0"><c>suite/0</c></seealso>
+ can, for example, be used in a test suite module to set a default
+ <c>timetrap</c> value and to <c>require</c> external configuration data.
+ If a test case, or a group information function also specifies any of the information tags, it
+ overrides the default values set by <c>suite/0</c>. For details,
+ see
+ <seealso marker="#info_function">Test Case Information Function</seealso> and
+ <seealso marker="#test_case_groups">Test Case Groups</seealso>.
</p>
- <p>Other options that may be specified with the suite info list are:</p>
- <list>
+ <p>The following options can also be specified with the suite information list:</p>
+ <list type="bulleted">
<item><c>stylesheet</c>,
- see <seealso marker="run_test_chapter#html_stylesheet">HTML Style Sheets</seealso>.</item>
+ see <seealso marker="run_test_chapter#html_stylesheet">HTML Style Sheets</seealso></item>
<item><c>userdata</c>,
- see <seealso marker="#info_function">Test case info function</seealso>.</item>
+ see <seealso marker="#info_function">Test Case Information Function</seealso></item>
<item><c>silent_connections</c>,
- see <seealso marker="run_test_chapter#silent_connections">Silent Connections</seealso>.</item>
+ see <seealso marker="run_test_chapter#silent_connections">Silent Connections</seealso></item>
</list>
<p>
- Example of the suite info function:
+ An example of the suite information function follows:
</p>
<pre>
- suite() ->
- [
- {timetrap,{minutes,10}},
- {require,global_names},
- {userdata,[{info,"This suite tests database transactions."}]},
- {silent_connections,[telnet]},
- {stylesheet,"db_testing.css"}
- ].</pre>
+ suite() ->
+ [
+ {timetrap,{minutes,10}},
+ {require,global_names},
+ {userdata,[{info,"This suite tests database transactions."}]},
+ {silent_connections,[telnet]},
+ {stylesheet,"db_testing.css"}
+ ].</pre>
</section>
<section>
<marker id="test_case_groups"></marker>
- <title>Test case groups</title>
- <p>A test case group is a set of test cases that share configuration
+ <title>Test Case Groups</title>
+ <p>A test case group is a set of test cases sharing configuration
functions and execution properties. Test case groups are defined by
- means of the <c>groups/0</c> function according to the following syntax:</p>
+ function
+ <seealso marker="common_test#Module:groups-0"><c>groups/0</c></seealso>
+ according to the following syntax:</p>
<pre>
- groups() -> GroupDefs
+ groups() -> GroupDefs
- Types:
+ Types:
- GroupDefs = [GroupDef]
- GroupDef = {GroupName,Properties,GroupsAndTestCases}
- GroupName = atom()
- GroupsAndTestCases = [GroupDef | {group,GroupName} | TestCase]
- TestCase = atom()</pre>
+ GroupDefs = [GroupDef]
+ GroupDef = {GroupName,Properties,GroupsAndTestCases}
+ GroupName = atom()
+ GroupsAndTestCases = [GroupDef | {group,GroupName} | TestCase]
+ TestCase = atom()</pre>
- <p><c>GroupName</c> is the name of the group and should be unique within
- the test suite module. Groups may be nested, and this is accomplished
- simply by including a group definition within the <c>GroupsAndTestCases</c>
- list of another group. <c>Properties</c> is the list of execution
- properties for the group. The possible values are:</p>
+ <p><c>GroupName</c> is the name of the group and must be unique within
+ the test suite module. Groups can be nested, by including a group definition
+ within the <c>GroupsAndTestCases</c> list of another group.
+ <c>Properties</c> is the list of execution
+ properties for the group. The possible values are as follows:</p>
<pre>
- Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
- Shuffle = shuffle | {shuffle,Seed}
- Seed = {integer(),integer(),integer()}
- RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
- repeat_until_any_ok | repeat_until_any_fail
- N = integer() | forever</pre>
-
- <p>If the <c>parallel</c> property is specified, Common Test will execute
- all test cases in the group in parallel. If <c>sequence</c> is specified,
- the cases will be executed in a sequence, as described in the chapter
- <seealso marker="dependencies_chapter#sequences">Dependencies between
- test cases and suites</seealso>. If <c>shuffle</c> is specified, the cases
- in the group will be executed in random order. The <c>repeat</c> property
- orders Common Test to repeat execution of the cases in the group a given
- number of times, or until any, or all, cases fail or succeed.</p>
-
- <p>Example:</p>
+ Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+ Shuffle = shuffle | {shuffle,Seed}
+ Seed = {integer(),integer(),integer()}
+ RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+ repeat_until_any_ok | repeat_until_any_fail
+ N = integer() | forever</pre>
+
+ <p><em>Explanations:</em></p>
+ <taglist>
+ <tag><c>parallel</c></tag>
+ <item><p><c>Common Test</c> executes all test cases in the group in parallel.</p></item>
+ <tag><c>sequence</c></tag>
+ <item><p>The cases are executed in a sequence as described in section
+ <seealso marker="dependencies_chapter#sequences">Sequences</seealso> in section
+ Dependencies Between Test Cases and Suites.</p></item>
+ <tag><c>shuffle</c></tag>
+ <item><p>The cases in the group are executed in random order.</p></item>
+ <tag><c>repeat</c></tag>
+ <item><p>Orders <c>Common Test</c> to repeat execution of the cases in the
+ group a given number of times, or until any, or all, cases fail or succeed.</p></item>
+ </taglist>
+
+ <p><em>Example:</em></p>
<pre>
- groups() -> [{group1, [parallel], [test1a,test1b]},
- {group2, [shuffle,sequence], [test2a,test2b,test2c]}].</pre>
+ groups() -> [{group1, [parallel], [test1a,test1b]},
+ {group2, [shuffle,sequence], [test2a,test2b,test2c]}].</pre>
- <p>To specify in which order groups should be executed (also with respect
- to test cases that are not part of any group), tuples on the form
- <c>{group,GroupName}</c> should be added to the <c>all/0</c> list. Example:</p>
+ <p>To specify in which order groups are to be executed (also with respect
+ to test cases that are not part of any group), add tuples on the form
+ <c>{group,GroupName}</c> to the <c>all/0</c> list.</p>
+ <p><em>Example:</em></p>
<pre>
- all() -> [testcase1, {group,group1}, testcase2, {group,group2}].</pre>
+ all() -> [testcase1, {group,group1}, testcase2, {group,group2}].</pre>
- <p>It is also possible to specify execution properties with a group
- tuple in <c>all/0</c>: <c>{group,GroupName,Properties}</c>. These
- properties will override those specified in the group definition (see
- <c>groups/0</c> above). This way, it's possible to run the same set of tests,
+ <p>Execution properties with a group tuple in
+ <c>all/0</c>: <c>{group,GroupName,Properties}</c> can also be specified.
+ These properties override those specified in the group definition (see
+ <c>groups/0</c> earlier). This way, the same set of tests can be run,
but with different properties, without having to make copies of the group
definition in question.</p>
- <p>If a group contains sub-groups, the execution properties for these may
+ <p>If a group contains subgroups, the execution properties for these can
also be specified in the group tuple:
- <c>{group,GroupName,Properties,SubGroups}</c>, where <c>SubGroups</c>
- is a list of tuples, <c>{GroupName,Properties}</c>, or
- <c>{GroupName,Properties,SubGroups}</c>, representing the sub-groups.
- Any sub-groups defined in <c>group/0</c> for a group, that are not specified
- in the <c>SubGroups</c> list, will simply execute with their pre-defined
+ <c>{group,GroupName,Properties,SubGroups}</c>
+ Where, <c>SubGroups</c> is a list of tuples, <c>{GroupName,Properties}</c> or
+ <c>{GroupName,Properties,SubGroups}</c> representing the subgroups.
+ Any subgroups defined in <c>group/0</c> for a group, that are not specified
+ in the <c>SubGroups</c> list, executes with their predefined
properties.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
- groups() -> {tests1, [], [{tests2, [], [t2a,t2b]},
- {tests3, [], [t31,t3b]}]}.</pre>
- <p>To execute group 'tests1' twice with different properties for 'tests2'
+ groups() -> {tests1, [], [{tests2, [], [t2a,t2b]},
+ {tests3, [], [t31,t3b]}]}.</pre>
+ <p>To execute group <c>tests1</c> twice with different properties for <c>tests2</c>
each time:</p>
<pre>
- all() ->
- [{group, tests1, default, [{tests2, [parallel]}]},
- {group, tests1, default, [{tests2, [shuffle,{repeat,10}]}]}].</pre>
- <p>Note that this is equivalent to this specification:</p>
+ all() ->
+ [{group, tests1, default, [{tests2, [parallel]}]},
+ {group, tests1, default, [{tests2, [shuffle,{repeat,10}]}]}].</pre>
+ <p>This is equivalent to the following specification:</p>
<pre>
- all() ->
- [{group, tests1, default, [{tests2, [parallel]},
- {tests3, default}]},
- {group, tests1, default, [{tests2, [shuffle,{repeat,10}]},
- {tests3, default}]}].</pre>
- <p>The value <c>default</c> states that the pre-defined properties
- should be used.</p>
- <p>Here's an example of how to override properties in a scenario
+ all() ->
+ [{group, tests1, default, [{tests2, [parallel]},
+ {tests3, default}]},
+ {group, tests1, default, [{tests2, [shuffle,{repeat,10}]},
+ {tests3, default}]}].</pre>
+ <p>Value <c>default</c> states that the predefined properties
+ are to be used.</p>
+ <p>The following example shows how to override properties in a scenario
with deeply nested groups:</p>
<pre>
- groups() ->
- [{tests1, [], [{group, tests2}]},
- {tests2, [], [{group, tests3}]},
- {tests3, [{repeat,2}], [t3a,t3b,t3c]}].
-
- all() ->
- [{group, tests1, default,
- [{tests2, default,
- [{tests3, [parallel,{repeat,100}]}]}]}].</pre>
-
- <p>The syntax described above may also be used in Test Specifications
- in order to change properties of groups at the time of execution,
- without even having to edit the test suite (please see the
- <seealso marker="run_test_chapter#test_specifications">Test
- Specifications</seealso> chapter for more info).</p>
-
- <p>As illustrated above, properties may be combined. If e.g.
- <c>shuffle</c>, <c>repeat_until_any_fail</c> and <c>sequence</c>
- are all specified, the test cases in the group will be executed
+ groups() ->
+ [{tests1, [], [{group, tests2}]},
+ {tests2, [], [{group, tests3}]},
+ {tests3, [{repeat,2}], [t3a,t3b,t3c]}].
+
+ all() ->
+ [{group, tests1, default,
+ [{tests2, default,
+ [{tests3, [parallel,{repeat,100}]}]}]}].</pre>
+
+ <p>The described syntax can also be used in test specifications
+ to change group properties at the time of execution,
+ without having to edit the test suite. For more information, see
+ section <seealso marker="run_test_chapter#test_specifications">Test
+ Specifications</seealso> in section Running Tests and Analyzing Results.</p>
+
+ <p>As illustrated, properties can be combined. If, for example,
+ <c>shuffle</c>, <c>repeat_until_any_fail</c>, and <c>sequence</c>
+ are all specified, the test cases in the group are executed
repeatedly, and in random order, until a test case fails. Then
- execution is immediately stopped and the rest of the cases skipped.</p>
+ execution is immediately stopped and the remaining cases are skipped.</p>
<p>Before execution of a group begins, the configuration function
- <c>init_per_group(GroupName, Config)</c> is called. The list of tuples
- returned from this function is passed to the test cases in the usual
- manner by means of the <c>Config</c> argument. <c>init_per_group/2</c>
- is meant to be used for initializations common for the test cases in the
- group. After execution of the group is finished, the
- <c>end_per_group(GroupName, Config</c> function is called. This function
- is meant to be used for cleaning up after <c>init_per_group/2</c>.</p>
+ <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group(GroupName, Config)</c></seealso>
+ is called. The list of tuples returned from this function is passed to the
+ test cases in the usual manner by argument <c>Config</c>.
+ <c>init_per_group/2</c> is meant to be used for initializations common
+ for the test cases in the group. After execution of the group is finished, function
+ <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group(GroupName, Config)</c></seealso>
+ is called. This function is meant to be used for cleaning up after
+ <c>init_per_group/2</c>.</p>
<p>Whenever a group is executed, if <c>init_per_group</c> and
- <c>end_per_group</c> do not exist in the suite, Common Test calls
+ <c>end_per_group</c> do not exist in the suite, <c>Common Test</c> calls
dummy functions (with the same names) instead. Output generated by
- hook functions will be saved to the log files for these dummies
- (see the <seealso marker="ct_hooks_chapter#manipulating">Common Test
- Hooks</seealso> chapter for more information).
+ hook functions are saved to the log files for these dummies.
+ For more information, see section
+ <seealso marker="ct_hooks_chapter#manipulating">Manipulating Tests</seealso>
+ in section Common Test Hooks.
</p>
<note><p><c>init_per_testcase/2</c> and <c>end_per_testcase/2</c>
are always called for each individual test case, no matter if the case
belongs to a group or not.</p></note>
- <p>The properties for a group is always printed on the top of the HTML log
- for <c>init_per_group/2</c>. Also, the total execution time for a group
- can be found at the bottom of the log for <c>end_per_group/2</c>.</p>
+ <p>The properties for a group are always printed in the top of the HTML log
+ for <c>init_per_group/2</c>. The total execution time for a group is
+ included at the bottom of the log for <c>end_per_group/2</c>.</p>
- <p>Test case groups may be nested so that sets of groups can be
+ <p>Test case groups can be nested so sets of groups can be
configured with the same <c>init_per_group/2</c> and <c>end_per_group/2</c>
- functions. Nested groups may be defined by including a group definition,
- or a group name reference, in the test case list of another group. Example:</p>
+ functions. Nested groups can be defined by including a group definition,
+ or a group name reference, in the test case list of another group.</p>
+ <p><em>Example:</em></p>
<pre>
- groups() -> [{group1, [shuffle], [test1a,
- {group2, [], [test2a,test2b]},
- test1b]},
- {group3, [], [{group,group4},
- {group,group5}]},
- {group4, [parallel], [test4a,test4b]},
- {group5, [sequence], [test5a,test5b,test5c]}].</pre>
-
- <p>In the example above, if <c>all/0</c> would return group name references
- in this order: <c>[{group,group1},{group,group3}]</c>, the order of the
- configuration functions and test cases will be the following (note that
+ groups() -> [{group1, [shuffle], [test1a,
+ {group2, [], [test2a,test2b]},
+ test1b]},
+ {group3, [], [{group,group4},
+ {group,group5}]},
+ {group4, [parallel], [test4a,test4b]},
+ {group5, [sequence], [test5a,test5b,test5c]}].</pre>
+
+ <p>In the previous example, if <c>all/0</c> returns group name references
+ in the order <c>[{group,group1},{group,group3}]</c>, the order of the
+ configuration functions and test cases becomes the following (notice that
<c>init_per_testcase/2</c> and <c>end_per_testcase/2:</c> are also
always called, but not included in this example for simplification):</p>
<pre>
-- init_per_group(group1, Config) -> Config1 (*)
-
--- test1a(Config1)
-
--- init_per_group(group2, Config1) -> Config2
-
---- test2a(Config2), test2b(Config2)
-
--- end_per_group(group2, Config2)
-
--- test1b(Config1)
-
-- end_per_group(group1, Config1)
-
-- init_per_group(group3, Config) -> Config3
-
--- init_per_group(group4, Config3) -> Config4
-
---- test4a(Config4), test4b(Config4) (**)
-
--- end_per_group(group4, Config4)
-
--- init_per_group(group5, Config3) -> Config5
-
---- test5a(Config5), test5b(Config5), test5c(Config5)
-
--- end_per_group(group5, Config5)
-
-- end_per_group(group3, Config3)
-
-
- (*) The order of test case test1a, test1b and group2 is not actually
- defined since group1 has a shuffle property.
-
- (**) These cases are not executed in order, but in parallel.</pre>
-
- <p>Properties are not inherited from top level groups to nested
- sub-groups. E.g, in the example above, the test cases in <c>group2</c>
- will not be executed in random order (which is the property of
- <c>group1</c>).</p>
+ init_per_group(group1, Config) -> Config1 (*)
+ test1a(Config1)
+ init_per_group(group2, Config1) -> Config2
+ test2a(Config2), test2b(Config2)
+ end_per_group(group2, Config2)
+ test1b(Config1)
+ end_per_group(group1, Config1)
+ init_per_group(group3, Config) -> Config3
+ init_per_group(group4, Config3) -> Config4
+ test4a(Config4), test4b(Config4) (**)
+ end_per_group(group4, Config4)
+ init_per_group(group5, Config3) -> Config5
+ test5a(Config5), test5b(Config5), test5c(Config5)
+ end_per_group(group5, Config5)
+ end_per_group(group3, Config3)</pre>
+
+ <p>(*) The order of test case <c>test1a</c>, <c>test1b</c>, and <c>group2</c> is
+ undefined, as <c>group1</c> has a shuffle property.</p>
+ <p>(**) These cases are not executed in order, but in parallel.</p>
+ <p>Properties are not inherited from top-level groups to nested
+ subgroups. For instance, in the previous example, the test cases in <c>group2</c>
+ are not executed in random order (which is the property of <c>group1</c>).</p>
</section>
<section>
- <title>The parallel property and nested groups</title>
- <p>If a group has a parallel property, its test cases will be spawned
- simultaneously and get executed in parallel. A test case is not allowed
- to execute in parallel with <c>end_per_group/2</c> however, which means
- that the time it takes to execute a parallel group is equal to the
+ <title>Parallel Property and Nested Groups</title>
+ <p>If a group has a parallel property, its test cases are spawned
+ simultaneously and get executed in parallel. However, a test case is not
+ allowed to execute in parallel with <c>end_per_group/2</c>, which means
+ that the time to execute a parallel group is equal to the
execution time of the slowest test case in the group. A negative side
effect of running test cases in parallel is that the HTML summary pages
- are not updated with links to the individual test case logs until the
- <c>end_per_group/2</c> function for the group has finished.</p>
+ are not updated with links to the individual test case logs until function
+ <c>end_per_group/2</c> for the group has finished.</p>
- <p>A group nested under a parallel group will start executing in parallel
+ <p>A group nested under a parallel group starts executing in parallel
with previous (parallel) test cases (no matter what properties the nested
- group has). Since, however, test cases are never executed in parallel with
- <c>init_per_group/2</c> or <c>end_per_group/2</c> of the same group, it's
- only after a nested group has finished that any remaining parallel cases
- in the previous group get spawned.</p>
+ group has). However, as test cases are never executed in parallel with
+ <c>init_per_group/2</c> or <c>end_per_group/2</c> of the same group, it is
+ only after a nested group has finished that remaining parallel cases
+ in the previous group become spawned.</p>
</section>
<section>
- <title>Parallel test cases and IO</title>
- <p>A parallel test case has a private IO server as its group leader.
- (Please see the Erlang Run-Time System Application documentation for
- a description of the group leader concept). The
- central IO server process that handles the output from regular test
- cases and configuration functions, does not respond to IO messages
+ <title>Parallel Test Cases and I/O</title>
+ <p>A parallel test case has a private I/O server as its group leader.
+ (For a description of the group leader concept, see
+ <seealso marker="erts:index"><c>ERTS</c></seealso>).
+ The central I/O server process, which handles the output from
+ regular test cases and configuration functions, does not respond to I/O messages
during execution of parallel groups. This is important to understand
- in order to avoid certain traps, like this one:</p>
- <p>If a process, <c>P</c>, is spawned during execution of e.g.
- <c>init_per_suite/1</c>, it will inherit the group leader of the
- <c>init_per_suite</c> process. This group leader is the central IO server
- process mentioned above. If, at a later time, <em>during parallel test case
+ to avoid certain traps, like the following:</p>
+ <p>If a process, <c>P</c>, is spawned during execution of, for example,
+ <c>init_per_suite/1</c>, it inherits the group leader of the
+ <c>init_per_suite</c> process. This group leader is the central I/O server
+ process mentioned earlier. If, at a later time, <em>during parallel test case
execution</em>, some event triggers process <c>P</c> to call
- <c>io:format/1/2</c>, that call will never return (since the group leader
- is in a non-responsive state) and cause <c>P</c> to hang.
+ <c>io:format/1/2</c>, that call never returns (as the group leader
+ is in a non-responsive state) and causes <c>P</c> to hang.
</p>
</section>
<section>
- <title>Repeated groups</title>
+ <title>Repeated Groups</title>
<marker id="repeated_groups"></marker>
- <p>A test case group may be repeated a certain number of times
+ <p>A test case group can be repeated a certain number of times
(specified by an integer) or indefinitely (specified by <c>forever</c>).
- The repetition may also be stopped prematurely if any or all cases
- fail or succeed, i.e. if the property <c>repeat_until_any_fail</c>,
+ The repetition can also be stopped too early if any or all cases
+ fail or succeed, that is, if any of the properties <c>repeat_until_any_fail</c>,
<c>repeat_until_any_ok</c>, <c>repeat_until_all_fail</c>, or
<c>repeat_until_all_ok</c> is used. If the basic <c>repeat</c>
property is used, status of test cases is irrelevant for the repeat
operation.</p>
- <p>It is possible to return the status of a sub-group (ok or
- failed), to affect the execution of the group on the level above.
+ <p>The status of a subgroup can be returned (<c>ok</c> or
+ <c>failed</c>), to affect the execution of the group on the level above.
This is accomplished by, in <c>end_per_group/2</c>, looking up the value
of <c>tc_group_properties</c> in the <c>Config</c> list and checking the
- result of the test cases in the group. If status <c>failed</c> should be
- returned from the group as a result, <c>end_per_group/2</c> should return
- the value <c>{return_group_result,failed}</c>. The status of a sub-group
- is taken into account by Common Test when evaluating if execution of a
- group should be repeated or not (unless the basic <c>repeat</c>
+ result of the test cases in the group. If status <c>failed</c> is to be
+ returned from the group as a result, <c>end_per_group/2</c> is to return
+ the value <c>{return_group_result,failed}</c>. The status of a subgroup
+ is taken into account by <c>Common Test</c> when evaluating if execution of a
+ group is to be repeated or not (unless the basic <c>repeat</c>
property is used).</p>
- <p>The <c>tc_group_properties</c> value is a list of status tuples,
- each with the key <c>ok</c>, <c>skipped</c> and <c>failed</c>. The
- value of a status tuple is a list containing names of test cases
+ <p>The value of <c>tc_group_properties</c> is a list of status tuples,
+ each with the key <c>ok</c>, <c>skipped</c>, and <c>failed</c>. The
+ value of a status tuple is a list with names of test cases
that have been executed with the corresponding status as result.</p>
- <p>Here's an example of how to return the status from a group:</p>
+ <p>The following is an example of how to return the status from a group:</p>
<pre>
- end_per_group(_Group, Config) ->
- Status = ?config(tc_group_result, Config),
- case proplists:get_value(failed, Status) of
- [] -> % no failed cases
- {return_group_result,ok};
- _Failed -> % one or more failed
- {return_group_result,failed}
- end.</pre>
-
- <p>It is also possible in <c>end_per_group/2</c> to check the status of
- a sub-group (maybe to determine what status the current group should also
- return). This is as simple as illustrated in the example above, only the
- name of the group is stored in a tuple <c>{group_result,GroupName}</c>,
- which can be searched for in the status lists. Example:</p>
+ end_per_group(_Group, Config) ->
+ Status = ?config(tc_group_result, Config),
+ case proplists:get_value(failed, Status) of
+ [] -> % no failed cases
+ {return_group_result,ok};
+ _Failed -> % one or more failed
+ {return_group_result,failed}
+ end.</pre>
+
+ <p>It is also possible, in <c>end_per_group/2</c>, to check the status of
+ a subgroup (maybe to determine what status the current group is to
+ return). This is as simple as illustrated in the previous example, only the
+ group name is stored in a tuple <c>{group_result,GroupName}</c>,
+ which can be searched for in the status lists.</p>
+ <p><em>Example:</em></p>
<pre>
- end_per_group(group1, Config) ->
- Status = ?config(tc_group_result, Config),
- Failed = proplists:get_value(failed, Status),
- case lists:member({group_result,group2}, Failed) of
- true ->
- {return_group_result,failed};
- false ->
- {return_group_result,ok}
- end;
- ...</pre>
+ end_per_group(group1, Config) ->
+ Status = ?config(tc_group_result, Config),
+ Failed = proplists:get_value(failed, Status),
+ case lists:member({group_result,group2}, Failed) of
+ true ->
+ {return_group_result,failed};
+ false ->
+ {return_group_result,ok}
+ end;
+ ...</pre>
<note><p>When a test case group is repeated, the configuration
- functions, <c>init_per_group/2</c> and <c>end_per_group/2</c>, are
+ functions <c>init_per_group/2</c> and <c>end_per_group/2</c> are
also always called with each repetition.</p></note>
</section>
<section>
- <title>Shuffled test case order</title>
- <p>The order that test cases in a group are executed, is under normal
+ <title>Shuffled Test Case Order</title>
+ <p>The order in which test cases in a group are executed is under normal
circumstances the same as the order specified in the test case list
- in the group definition. With the <c>shuffle</c> property set, however,
- Common Test will instead execute the test cases in random order.</p>
+ in the group definition. With property <c>shuffle</c> set, however,
+ <c>Common Test</c> instead executes the test cases in random order.</p>
- <p>The user may provide a seed value (a tuple of three integers) with
- the shuffle property: <c>{shuffle,Seed}</c>. This way, the same shuffling
+ <p>You can provide a seed value (a tuple of three integers) with
+ the shuffle property <c>{shuffle,Seed}</c>. This way, the same shuffling
order can be created every time the group is executed. If no seed value
- is given, Common Test creates a "random" seed for the shuffling operation
- (using the return value of <c>erlang:now()</c>). The seed value is always
+ is specified, <c>Common Test</c> creates a "random" seed for the shuffling operation
+ (using the return value of <c>erlang:timestamp/0</c>). The seed value is always
printed to the <c>init_per_group/2</c> log file so that it can be used to
recreate the same execution order in a subsequent test run.</p>
- <note><p>If a shuffled test case group is repeated, the seed will not
- be reset in between turns.</p></note>
+ <note><p>If a shuffled test case group is repeated, the seed is not
+ reset between turns.</p></note>
- <p>If a sub-group is specified in a group with a <c>shuffle</c> property,
- the execution order of this sub-group in relation to the test cases
- (and other sub-groups) in the group, is also random. The order of the
- test cases in the sub-group is however not random (unless, of course, the
- sub-group also has a <c>shuffle</c> property).</p>
+ <p>If a subgroup is specified in a group with a <c>shuffle</c> property,
+ the execution order of this subgroup in relation to the test cases
+ (and other subgroups) in the group, is random. The order of the
+ test cases in the subgroup is however not random (unless the
+ subgroup has a <c>shuffle</c> property).</p>
</section>
<section>
<marker id="group_info"></marker>
- <title>Group info function</title>
+ <title>Group Information Function</title>
- <p>The test case group info function, <c>group(GroupName)</c>,
- serves the same purpose as the suite- and test case info
- functions previously described in this chapter. The scope for
- the group info, however, is all test cases and sub-groups in the
+ <p>The test case group information function, <c>group(GroupName)</c>,
+ serves the same purpose as the suite- and test case information
+ functions previously described. However, the scope for
+ the group information function, is all test cases and subgroups in the
group in question (<c>GroupName</c>).</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
- group(connection_tests) ->
- [{require,login_data},
- {timetrap,1000}].</pre>
+ group(connection_tests) ->
+ [{require,login_data},
+ {timetrap,1000}].</pre>
- <p>The group info properties override those set with the
- suite info function, and may in turn be overridden by test
- case info properties. Please see the test case info
- function above for a list of valid info properties and more
- general information.</p>
+ <p>The group information properties override those set with the
+ suite information function, and can in turn be overridden by test
+ case information properties. For a list of valid information properties
+ and more general information, see the
+ <seealso marker="#info_function">Test Case Information Function</seealso>.
+ </p>
</section>
<section>
- <title>Info functions for init- and end-configuration</title>
- <p>It is possible to use info functions also for the <c>init_per_suite</c>,
- <c>end_per_suite</c>, <c>init_per_group</c>, and <c>end_per_group</c>
- functions, and it works the same way as with info functions
- for test cases (see above). This is useful e.g. for setting
- timetraps and requiring external configuration data relevant
- only for the configuration function in question (without
- affecting properties set for groups and test cases in the suite).</p>
-
- <p>The info function <c>init/end_per_suite()</c> is called for
- <c>init/end_per_suite(Config)</c>, and info function
+ <title>Information Functions for Init- and End-Configuration</title>
+ <p>Information functions can also be used for functions <c>init_per_suite</c>,
+ <c>end_per_suite</c>, <c>init_per_group</c>, and <c>end_per_group</c>,
+ and they work the same way as with the
+ <seealso marker="#info_function">Test Case Information Function</seealso>.
+ This is useful, for example, for setting timetraps and requiring
+ external configuration data relevant only for the configuration
+ function in question (without affecting properties set for groups
+ and test cases in the suite).</p>
+
+ <p>The information function <c>init/end_per_suite()</c> is called for
+ <c>init/end_per_suite(Config)</c>, and information function
<c>init/end_per_group(GroupName)</c> is called for
- <c>init/end_per_group(GroupName,Config)</c>. Info functions
- can not be used with <c>init/end_per_testcase(TestCase, Config)</c>,
- however, since these configuration functions execute on the test case process
- and will use the same properties as the test case (i.e. the properties
- set by the test case info function, <c>TestCase()</c>). Please see the test case
- info function above for a list of valid info properties and more
- general information.
+ <c>init/end_per_group(GroupName,Config)</c>. However, information functions
+ cannot be used with <c>init/end_per_testcase(TestCase, Config)</c>,
+ as these configuration functions execute on the test case process
+ and use the same properties as the test case (that is, the properties
+ set by the test case information function, <c>TestCase()</c>). For a list
+ of valid information properties and more general information, see the
+ <seealso marker="#info_function">Test Case Information Function</seealso>.
</p>
</section>
@@ -788,77 +805,67 @@
<marker id="data_priv_dir"></marker>
<title>Data and Private Directories</title>
- <p>The data directory, <c>data_dir</c>, is the directory where the
- test module has its own files needed for the testing. The name
- of the <c>data_dir</c> is the the name of the test suite followed
- by <c>"_data"</c>. For example,
- <c>"some_path/foo_SUITE.beam"</c> has the data directory
+ <p>In the data directory, <c>data_dir</c>, the test module has
+ its own files needed for the testing. The name of <c>data_dir</c>
+ is the the name of the test suite followed by <c>"_data"</c>.
+ For example, <c>"some_path/foo_SUITE.beam"</c> has the data directory
<c>"some_path/foo_SUITE_data/"</c>. Use this directory for portability,
- i.e. to avoid hardcoding directory names in your suite. Since the data
- directory is stored in the same directory as your test suite, you should
- be able to rely on its existence at runtime, even if the path to your
+ that is, to avoid hardcoding directory names in your suite. As the data
+ directory is stored in the same directory as your test suite, you can
+ rely on its existence at runtime, even if the path to your
test suite directory has changed between test suite implementation and
execution.
</p>
-
-<!--
- <p>
- When using the Common Test framework <c>ct</c>, automatic
- compilation of code in the data directory can be obtained by
- placing a makefile source called Makefile.src in the data
- directory. Makefile.src will be converted to a valid makefile by
- <c>ct</c> when the test suite is run. See the reference manual for
- the <c>ct</c> module for details about the syntax of Makefile.src.
- </p>
--->
<p>
<c>priv_dir</c> is the private directory for the test cases.
- This directory may be used whenever a test case (or configuration function)
+ This directory can be used whenever a test case (or configuration function)
needs to write something to file. The name of the private directory is
- generated by Common Test, which also creates the directory.
+ generated by <c>Common Test</c>, which also creates the directory.
</p>
- <p>By default, Common Test creates one central private directory
- per test run that all test cases share. This may not always be suitable,
- especially if the same test cases are executed multiple times during
- a test run (e.g. if they belong to a test case group with repeat
- property), and there's a risk that files in the private directory get
- overwritten. Under these circumstances, it's possible to configure
- Common Test to create one dedicated private directory per
- test case and execution instead. This is accomplished by means of
- the flag/option: <c>create_priv_dir</c> (to be used with the
- <c>ct_run</c> program, the <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> function, or
+ <p>By default, <c>Common Test</c> creates one central private directory
+ per test run, shared by all test cases. This is not always suitable.
+ Especially if the same test cases are executed multiple times during
+ a test run (that is, if they belong to a test case group with property
+ <c>repeat</c>) and there is a risk that files in the private directory get
+ overwritten. Under these circumstances, <c>Common Test</c> can be
+ configured to create one dedicated private directory per
+ test case and execution instead. This is accomplished with
+ the flag/option <c>create_priv_dir</c> (to be used with the
+ <seealso marker="ct_run"><c>ct_run</c></seealso> program, the
+ <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> function, or
as test specification term). There are three possible values
- for this option:
+ for this option as follows:
</p>
- <list>
+ <list type="bulleted">
<item><c>auto_per_run</c></item>
<item><c>auto_per_tc</c></item>
<item><c>manual_per_tc</c></item>
</list>
<p>
- The first value indicates the default priv_dir behaviour, i.e.
+ The first value indicates the default <c>priv_dir</c> behavior, that is,
one private directory created per test run. The two latter
- values tell Common Test to generate a unique test directory name
+ values tell <c>Common Test</c> to generate a unique test directory name
per test case and execution. If the auto version is used, <em>all</em>
- private directories will be created automatically. This can obviously
- become very inefficient for test runs with many test cases and/or
- repetitions. Therefore, in case the manual version is instead used, the
- test case must tell Common Test to create priv_dir when it needs it.
- It does this by calling the function <seealso marker="ct#make_priv_dir-0"><c>ct:make_priv_dir/0</c></seealso>.
+ private directories are created automatically. This can become very
+ inefficient for test runs with many test cases or repetitions, or both.
+ Therefore, if the manual version is used instead, the test case must tell
+ <c>Common Test</c> to create <c>priv_dir</c> when it needs it.
+ It does this by calling the function
+ <seealso marker="ct#make_priv_dir-0"><c>ct:make_priv_dir/0</c></seealso>.
</p>
- <note><p>You should not depend on current working directory for
- reading and writing data files since this is not portable. All
+ <note><p>Do not depend on the current working directory for
+ reading and writing data files, as this is not portable. All
scratch files are to be written in the <c>priv_dir</c> and all
- data files should be located in <c>data_dir</c>. Note also that
- the Common Test server sets current working directory to the test case
- log directory at the start of every case.
+ data files are to be located in <c>data_dir</c>. Also,
+ the <c>Common Test</c> server sets the current working directory to
+ the test case log directory at the start of every case.
</p></note>
</section>
<section>
- <title>Execution environment</title>
+ <title>Execution Environment</title>
<p>Each test case is executed by a dedicated Erlang process. The
process is spawned when the test case starts, and terminated when
@@ -875,236 +882,269 @@
<section>
<marker id="timetraps"></marker>
- <title>Timetrap timeouts</title>
+ <title>Timetrap Time-Outs</title>
<p>The default time limit for a test case is 30 minutes, unless a
<c>timetrap</c> is specified either by the suite-, group-,
- or test case info function. The timetrap timeout value defined by
- <c>suite/0</c> is the value that will be used for each test case
- in the suite (as well as for the configuration functions
+ or test case information function. The timetrap time-out value defined by
+ <c>suite/0</c> is the value that is used for each test case
+ in the suite (and for the configuration functions
<c>init_per_suite/1</c>, <c>end_per_suite/1</c>, <c>init_per_group/2</c>,
and <c>end_per_group/2</c>). A timetrap value defined by
<c>group(GroupName)</c> overrides one defined by <c>suite()</c>
- and will be used for each test case in group <c>GroupName</c>, and any
- of its sub-groups. If a timetrap value is defined by <c>group/1</c>
- for a sub-group, it overrides that of its higher level groups. Timetrap
- values set by individual test cases (by means of the test case info
+ and is used for each test case in group <c>GroupName</c>, and any
+ of its subgroups. If a timetrap value is defined by <c>group/1</c>
+ for a subgroup, it overrides that of its higher level groups. Timetrap
+ values set by individual test cases (by the test case information
function) override both group- and suite- level timetraps.</p>
- <p>It is also possible to dynamically set/reset a timetrap during the
- excution of a test case, or configuration function. This is done by calling
- <seealso marker="ct#timetrap-1"><c>ct:timetrap/1</c></seealso>. This function cancels the current timetrap
- and starts a new one (that stays active until timeout, or end of the
- current function).</p>
+ <p>A timetrap can also be set or reset dynamically during the
+ execution of a test case, or configuration function.
+ This is done by calling
+ <seealso marker="ct#timetrap-1"><c>ct:timetrap/1</c></seealso>.
+ This function cancels the current timetrap and starts a new one
+ (that stays active until time-out, or end of the current function).</p>
<p>Timetrap values can be extended with a multiplier value specified at
- startup with the <c>multiply_timetraps</c> option. It is also possible
- to let the test server decide to scale up timetrap timeout values
- automatically, e.g. if tools such as cover or trace are running during
- the test. This feature is disabled by default and can be enabled with
- the <c>scale_timetraps</c> start option.</p>
+ startup with option <c>multiply_timetraps</c>. It is also possible
+ to let the test server decide to scale up timetrap time-out values
+ automatically. That is, if tools such as <c>cover</c> or <c>trace</c>
+ are running during the test. This feature is disabled by default and
+ can be enabled with start option <c>scale_timetraps</c>.</p>
<p>If a test case needs to suspend itself for a time that also gets
multipled by <c>multiply_timetraps</c> (and possibly also scaled up if
- <c>scale_timetraps</c> is enabled), the function <seealso marker="ct#sleep-1"><c>ct:sleep/1</c></seealso>
- may be used (instead of e.g. <c>timer:sleep/1</c>).</p>
+ <c>scale_timetraps</c> is enabled), the function
+ <seealso marker="ct#sleep-1"><c>ct:sleep/1</c></seealso>
+ can be used (instead of, for example, <c>timer:sleep/1</c>).</p>
- <p>A function (<c>fun/0</c> or <c>MFA</c>) may be specified as
- timetrap value in the suite-, group- and test case info function, as
- well as argument to the <seealso marker="ct#timetrap-1"><c>ct:timetrap/1</c></seealso> function. Examples:</p>
+ <p>A function (<c>fun/0</c> or <c>{Mod,Func,Args}</c> (MFA) tuple) can be
+ specified as timetrap value in the suite-, group- and test case information
+ function, and as argument to function
+ <seealso marker="ct#timetrap-1"><c>ct:timetrap/1</c></seealso>.</p>
+ <p><em>Examples:</em></p>
<p><c>{timetrap,{my_test_utils,timetrap,[?MODULE,system_start]}}</c></p>
<p><c>ct:timetrap(fun() -> my_timetrap(TestCaseName, Config) end)</c></p>
- <p>The user timetrap function may be used for two things:</p>
- <list>
- <item>To act as a timetrap - the timeout is triggered when the
+ <p>The user timetrap function can be used for two things as follows:</p>
+ <list type="bulleted">
+ <item>To act as a timetrap. The time-out is triggered when the
function returns.</item>
<item>To return a timetrap time value (other than a function).</item>
</list>
<p>Before execution of the timetrap function (which is performed
- on a parallel, dedicated timetrap process), Common Test cancels
+ on a parallel, dedicated timetrap process), <c>Common Test</c> cancels
any previously set timer for the test case or configuration function.
- When the timetrap function returns, the timeout is triggered, <em>unless</em>
+ When the timetrap function returns, the time-out is triggered, <em>unless</em>
the return value is a valid timetrap time, such as an integer,
- or a <c>{SecMinOrHourTag,Time}</c> tuple (see the
- <seealso marker="common_test">common_test reference manual</seealso> for
- details). If a time value is returned, a new timetrap is started
- to generate a timeout after the specified time.</p>
+ or a <c>{SecMinOrHourTag,Time}</c> tuple (for details, see module
+ <seealso marker="common_test">common_test</seealso>). If a time value
+ is returned, a new timetrap is started to generate a time-out after
+ the specified time.</p>
- <p>The user timetrap function may of course return a time value after a delay,
- and if so, the effective timetrap time is the delay time <em>plus</em> the
+ <p>The user timetrap function can return a time value after a delay.
+ The effective timetrap time is then the delay time <em>plus</em> the
returned time.</p>
</section>
<section>
<marker id="logging"></marker>
- <title>Logging - categories and verbosity levels</title>
- <p>Common Test provides three main functions for printing strings:</p>
- <list>
- <item><c>ct:log(Category, Importance, Format, Args)</c></item>
- <item><c>ct:print(Category, Importance, Format, Args)</c></item>
- <item><c>ct:pal(Category, Importance, Format, Args)</c></item>
+ <title>Logging - Categories and Verbosity Levels</title>
+ <p><c>Common Test</c> provides the following three main functions for
+ printing strings:</p>
+ <list type="bulleted">
+ <item><c>ct:log(Category, Importance, Format, FormatArgs, Opts)</c></item>
+ <item><c>ct:print(Category, Importance, Format, FormatArgs)</c></item>
+ <item><c>ct:pal(Category, Importance, Format, FormatArgs)</c></item>
</list>
- <p>The <c>log/1/2/3/4</c> function will print a string to the test case
- log file. The <c>print/1/2/3/4</c> function will print the string to screen,
- and the <c>pal/1/2/3/4</c> function will print the same string both to file and
- screen. (The functions are documented in the <c>ct</c> reference manual).</p>
-
- <p>The optional <c>Category</c> argument may be used to categorize the
- log printout, and categories can be used for two things:</p>
- <list>
+ <p>The <seealso marker="ct#log-1"><c>log/1,2,3,4,5</c></seealso> function
+ prints a string to the test case log file.
+ The <seealso marker="ct#print-1"><c>print/1,2,3,4</c></seealso> function
+ prints the string to screen.
+ The <seealso marker="ct#pal-1"><c>pal/1,2,3,4</c></seealso> function
+ prints the same string both to file and screen. The functions are described
+ in module <seealso marker="ct">ct</seealso>.
+ </p>
+
+ <p>The optional <c>Category</c> argument can be used to categorize the
+ log printout. Categories can be used for two things as follows:</p>
+ <list type="bulleted">
<item>To compare the importance of the printout to a specific
- verbosity level, and</item>
- <item>to format the printout according to a user specific HTML
+ verbosity level.</item>
+ <item>To format the printout according to a user-specific HTML
Style Sheet (CSS).</item>
</list>
- <p>The <c>Importance</c> argument specifies a level of importance
- which, compared to a verbosity level (general and/or set per category),
- determines if the printout should be visible or not. <c>Importance</c>
- is an arbitrary integer in the range 0..99. Pre-defined constants
+ <p>Argument <c>Importance</c> specifies a level of importance
+ that, compared to a verbosity level (general and/or set per category),
+ determines if the printout is to be visible. <c>Importance</c>
+ is any integer in the range 0..99. Predefined constants
exist in the <c>ct.hrl</c> header file. The default importance level,
- <c>?STD_IMPORTANCE</c> (used if the <c>Importance</c> argument is not
- provided), is 50. This is also the importance used for standard IO, e.g.
- from printouts made with <c>io:format/2</c>, <c>io:put_chars/1</c>, etc.</p>
+ <c>?STD_IMPORTANCE</c> (used if argument <c>Importance</c> is not
+ provided), is 50. This is also the importance used for standard I/O,
+ for example, from printouts made with <c>io:format/2</c>,
+ <c>io:put_chars/1</c>, and so on.</p>
- <p><c>Importance</c> is compared to a verbosity level set by means of the
+ <p><c>Importance</c> is compared to a verbosity level set by the
<c>verbosity</c> start flag/option. The verbosity level can be set per
- category and/or generally. The default verbosity level, <c>?STD_VERBOSITY</c>,
- is 50, i.e. all standard IO gets printed. If a lower verbosity level is set,
- standard IO printouts will be ignored. Common Test performs the following test:</p>
- <pre>Importance >= (100-VerbosityLevel)</pre>
+ category or generally, or both. The default verbosity level,
+ <c>?STD_VERBOSITY</c>, is 50, that is, all standard I/O gets printed.
+ If a lower verbosity level is set, standard I/O printouts are ignored.
+ <c>Common Test</c> performs the following test:</p>
+ <pre>
+ Importance >= (100-VerbosityLevel)</pre>
<p>This also means that verbosity level 0 effectively turns all logging off
- (with the exception of printouts made by Common Test itself).</p>
+ (except from printouts made by <c>Common Test</c> itself).</p>
<p>The general verbosity level is not associated with any particular
- category. This level sets the threshold for the standard IO printouts,
- uncategorized <c>ct:log/print/pal</c> printouts, as well as
+ category. This level sets the threshold for the standard I/O printouts,
+ uncategorized <c>ct:log/print/pal</c> printouts, and
printouts for categories with undefined verbosity level.</p>
- <p>Example:</p>
- <pre>
- Some printouts during test case execution:
-
- io:format("1. Standard IO, importance = ~w~n", [?STD_IMPORTANCE]),
- ct:log("2. Uncategorized, importance = ~w", [?STD_IMPORTANCE]),
- ct:log(info, "3. Categorized info, importance = ~w", [?STD_IMPORTANCE]]),
- ct:log(info, ?LOW_IMPORTANCE, "4. Categorized info, importance = ~w", [?LOW_IMPORTANCE]),
- ct:log(error, "5. Categorized error, importance = ~w", [?HI_IMPORTANCE]),
- ct:log(error, ?HI_IMPORTANCE, "6. Categorized error, importance = ~w", [?MAX_IMPORTANCE]),
-
- If starting the test without specifying any verbosity levels:
-
- $ ct_run ...
-
- the following gets printed:
-
- 1. Standard IO, importance = 50
- 2. Uncategorized, importance = 50
- 3. Categorized info, importance = 50
- 5. Categorized error, importance = 75
- 6. Categorized error, importance = 99
-
- If starting the test with:
-
- $ ct_run -verbosity 1 and info 75
-
- the following gets printed:
-
- 3. Categorized info, importance = 50
- 4. Categorized info, importance = 25
- 6. Categorized error, importance = 99</pre>
-
- <p>How categories can be mapped to CSS tags is documented in the
- <seealso marker="run_test_chapter#html_stylesheet">Running Tests</seealso>
- chapter.</p>
-
- <p>The <c>Format</c> and <c>Args</c> arguments in <c>ct:log/print/pal</c> are
- always passed on to the <c>io:format/3</c> function in <c>stdlib</c>
- (please see the <c>io</c> manual page for details).</p>
+ <p><em>Examples:</em></p>
+ <p>Some printouts during test case execution:</p>
+ <pre>
+ io:format("1. Standard IO, importance = ~w~n", [?STD_IMPORTANCE]),
+ ct:log("2. Uncategorized, importance = ~w", [?STD_IMPORTANCE]),
+ ct:log(info, "3. Categorized info, importance = ~w", [?STD_IMPORTANCE]]),
+ ct:log(info, ?LOW_IMPORTANCE, "4. Categorized info, importance = ~w", [?LOW_IMPORTANCE]),
+ ct:log(error, "5. Categorized error, importance = ~w", [?HI_IMPORTANCE]),
+ ct:log(error, ?HI_IMPORTANCE, "6. Categorized error, importance = ~w", [?MAX_IMPORTANCE]),</pre>
+
+ <p>If starting the test without specifying any verbosity levels as follows:</p>
+ <pre>
+ $ ct_run ...</pre>
+ <p>the following is printed:</p>
+ <pre>
+ 1. Standard IO, importance = 50
+ 2. Uncategorized, importance = 50
+ 3. Categorized info, importance = 50
+ 5. Categorized error, importance = 75
+ 6. Categorized error, importance = 99</pre>
+
+ <p>If starting the test with:</p>
+ <pre>
+ $ ct_run -verbosity 1 and info 75</pre>
+ <p>the following is printed:</p>
+ <pre>
+ 3. Categorized info, importance = 50
+ 4. Categorized info, importance = 25
+ 6. Categorized error, importance = 99</pre>
+
+ <p>The arguments <c>Format</c> and <c>FormatArgs</c> in <c>ct:log/print/pal</c> are
+ always passed on to the <c>stdlib</c> function <c>io:format/3</c> (For details,
+ see the <seealso marker="stdlib:io"><c>stdlib:io</c></seealso> manual page).</p>
+
+ <p><c>ct:pal/4</c> and <c>ct:log/5</c> add headers to strings being printed to the
+ log file. The strings are also wrapped in div tags with a CSS class
+ attribute, so that stylesheet formatting can be applied. To disable this feature for
+ a printout (i.e. to get a result similar to using <c>io:format/2</c>),
+ call <c>ct:log/5</c> with the <c>no_css</c> option.</p>
+
+ <p>How categories can be mapped to CSS tags is documented in section
+ <seealso marker="run_test_chapter#html_stylesheet">HTML Style Sheets</seealso>
+ in section Running Tests and Analyzing Results.</p>
- <p>For more information about log files, please see the
- <seealso marker="run_test_chapter#log_files">Running Tests</seealso> chapter.</p>
+ <p>Common Test will escape special HTML characters (&lt;, &gt; and &amp;) in printouts
+ to the log file made with <c>ct:pal/4</c> and <c>io:format/2</c>. In order to print
+ strings with HTML tags to the log, use the <c>ct:log/3,4,5</c> function. The character
+ escaping feature is per default disabled for <c>ct:log/3,4,5</c> but can be enabled with
+ the <c>esc_chars</c> option in the <c>Opts</c> list, see <seealso marker="ct#log-5">
+ <c>ct:log/3,4,5</c></seealso>.</p>
+
+ <p>If the character escaping feature needs to be disabled (typically for backwards
+ compatibility reasons), use the <c>ct_run</c> start flag <c>-no_esc_chars</c>, or the
+ <c>ct:run_test/1</c> start option <c>{esc_chars,Bool}</c> (this start option is also
+ supported in test specifications).</p>
+
+ <p>For more information about log files, see section
+ <seealso marker="run_test_chapter#log_files">Log Files</seealso>
+ in section Running Tests and Analyzing Results.</p>
</section>
<section>
- <title>Illegal dependencies</title>
+ <title>Illegal Dependencies</title>
<p>Even though it is highly efficient to write test suites with
- the Common Test framework, there will surely be mistakes made,
- mainly due to illegal dependencies. Noted below are some of the
+ the <c>Common Test</c> framework, mistakes can be made,
+ mainly because of illegal dependencies. Some of the
more frequent mistakes from our own experience with running the
- Erlang/OTP test suites.</p>
+ Erlang/OTP test suites follows:</p>
- <list>
- <item>Depending on current directory, and writing there:<br></br>
+ <list type="bulleted">
+ <item><p>Depending on current directory, and writing there:</p>
<p>This is a common error in test suites. It is assumed that
- the current directory is the same as what the author used as
+ the current directory is the same as the author used as
current directory when the test case was developed. Many test
cases even try to write scratch files to this directory. Instead
- <c>data_dir</c> and <c>priv_dir</c> should be used to locate
+ <c>data_dir</c> and <c>priv_dir</c> are to be used to locate
data and for writing scratch files.
</p>
</item>
- <item>Depending on execution order:<br></br>
+ <item><p>Depending on execution order:</p>
- <p>During development of test suites, no assumption should preferrably
- be made about the execution order of the test cases or suites.
- E.g. a test case should not assume that a server it depends on,
- has already been started by a previous test case. There are
- several reasons for this:
- </p>
- <p>Firstly, the user/operator may specify the order at will, and maybe
- a different execution order is more relevant or efficient on
- some particular occasion. Secondly, if the user specifies a whole
- directory of test suites for his/her test, the order the suites are
- executed will depend on how the files are listed by the operating
- system, which varies between systems. Thirdly, if a user
- wishes to run only a subset of a test suite, there is no way
- one test case could successfully depend on another.
+ <p>During development of test suites, make no assumptions on the
+ execution order of the test cases or suites. For example, a test
+ case must not assume that a server it depends on is already
+ started by a previous test case. Reasons for this follows:
</p>
+ <list type="bulleted">
+ <item>The user/operator can specify the order at will, and maybe
+ a different execution order is sometimes more relevant or
+ efficient.</item>
+ <item>If the user specifies a whole directory of test suites
+ for the test, the execution order of the suites depends on
+ how the files are listed by the operating system, which varies
+ between systems.</item>
+ <item>If a user wants to run only a subset of a test suite,
+ there is no way one test case could successfully depend on
+ another.</item>
+ </list>
</item>
- <item>Depending on Unix:<br></br>
+ <item><p>Depending on Unix:</p>
- <p>Running unix commands through <c>os:cmd</c> are likely
- not to work on non-unix platforms.
+ <p>Running Unix commands through <c>os:cmd</c> are likely
+ not to work on non-Unix platforms.
</p>
</item>
- <item>Nested test cases:<br></br>
+ <item><p>Nested test cases:</p>
- <p>Invoking a test case from another not only tests the same
- thing twice, but also makes it harder to follow what exactly
- is being tested. Also, if the called test case fails for some
- reason, so will the caller. This way one error gives cause to
- several error reports, which is less than ideal.
+ <p>Starting a test case from another not only tests the same
+ thing twice, but also makes it harder to follow what is being
+ tested. Also, if the called test case fails for some
+ reason, so do the caller. This way, one error gives cause to
+ several error reports, which is to be avoided.
</p>
- <p>Functionality common for many test case functions may be implemented
- in common help functions. If these functions are useful for test cases
- across suites, put the help functions into common help modules.
+ <p>Functionality common for many test case functions can be
+ implemented in common help functions. If these functions are
+ useful for test cases across suites, put the help functions
+ into common help modules.
</p>
</item>
- <item>Failure to crash or exit when things go wrong:<br></br>
+ <item><p>Failure to crash or exit when things go wrong:</p>
<p>Making requests without checking that the return value
- indicates success may be ok if the test case will fail at a
- later stage, but it is never acceptable just to print an error
- message (into the log file) and return successfully. Such test cases
- do harm since they create a false sense of security when overviewing
- the test results.
+ indicates success can be OK if the test case fails
+ later, but it is never acceptable just to print an error
+ message (into the log file) and return successfully. Such test
+ cases do harm, as they create a false sense of security when
+ overviewing the test results.
</p>
</item>
- <item>Messing up for subsequent test cases:<br></br>
+ <item><p>Messing up for subsequent test cases:</p>
- <p>Test cases should restore as much of the execution
- environment as possible, so that the subsequent test cases will
- not crash because of execution order of the test cases.
- The function <c>end_per_testcase</c> is suitable for this.
+ <p>Test cases are to restore as much of the execution
+ environment as possible, so that subsequent test cases
+ do not crash because of their execution order.
+ The function
+ <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>
+ is suitable for this.
</p>
</item>
</list>
diff --git a/lib/common_test/include/ct.hrl b/lib/common_test/include/ct.hrl
index 44cc33f01e..53bc43fc24 100644
--- a/lib/common_test/include/ct.hrl
+++ b/lib/common_test/include/ct.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/include/ct_event.hrl b/lib/common_test/include/ct_event.hrl
index 5b782f3609..51c533297a 100644
--- a/lib/common_test/include/ct_event.hrl
+++ b/lib/common_test/include/ct_event.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/install.sh.in b/lib/common_test/install.sh.in
deleted file mode 100644
index 5108c7a259..0000000000
--- a/lib/common_test/install.sh.in
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/sh
-
-CT_ROOT=$1
-CT_VSN=@CT_VSN@
-TS_VSN=@TS_VSN@
-
-if [ -z "$CT_ROOT" ]
-then
- echo "install.sh: need CT_ROOT (absolute) directory or 'local' as argument"
- exit 1
-fi
-
-if [ $CT_ROOT = "local" ]
-then
- CT_DIR=`pwd`
- cd priv
- sed -e "s,@CTPATH@,$CT_DIR/ebin," \
- -e "s,@TSPATH@,$CT_DIR/../test_server/ebin," \
- run_test.in > bin/run_test
- chmod 775 bin/run_test
- echo "install successful, start script created in " $CT_ROOT/common_test-$CT_VSN/priv/bin
-else
-
- if [ ! -d "$CT_ROOT" ]
- then
- echo "install.sh: CT_ROOT argument must be a valid directory"
- exit 1
- fi
-
- if [ `echo $CT_ROOT | awk '{ print substr($1,1,1) }'` != "/" ]
- then
- echo "install.sh: need an absolute path to CT_ROOT"
- exit 1
- fi
-
- if [ ! -d $CT_ROOT/common_test-$CT_VSN ]
- then
- echo "install.sh: The directory $CT_ROOT/common_test-$CT_VSN does not exist"
- exit 1
- fi
-
- if [ -d $CT_ROOT/common_test-$CT_VSN/priv ]
- then
- cd $CT_ROOT/common_test-$CT_VSN/priv
- sed -e "s;@CTPATH@;$CT_ROOT/common_test-$CT_VSN/ebin;" \
- -e "s;@TSPATH@;$CT_ROOT/test_server-$TS_VSN/ebin;" \
- run_test.in > bin/run_test
- chmod 775 bin/run_test
- echo "install successful, start script created in " $CT_ROOT/common_test-$CT_VSN/priv/bin
- fi
-fi
-
-
diff --git a/lib/common_test/priv/Makefile b/lib/common_test/priv/Makefile
index f0baba07ba..c9aff91b8c 100644
--- a/lib/common_test/priv/Makefile
+++ b/lib/common_test/priv/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in
index 76baead8f6..06a4e40ee9 100644
--- a/lib/common_test/priv/Makefile.in
+++ b/lib/common_test/priv/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -66,14 +67,7 @@ JS = jquery-latest.js jquery.tablesorter.min.js
# Rules
#
-include ../../test_server/vsn.mk
-debug opt: install.sh
-
-install.sh: ../install.sh.in ../vsn.mk ../../test_server/vsn.mk
- $(V_at)sed -e 's;@CT_VSN@;$(VSN);' \
- -e 's;@TS_VSN@;$(TEST_SERVER_VSN);' \
- ../install.sh.in > install.sh
- - $(V_at)chmod -f 775 install.sh
+debug opt:
docs:
diff --git a/lib/common_test/priv/run_test.in b/lib/common_test/priv/run_test.in
deleted file mode 100644
index 1508751e4f..0000000000
--- a/lib/common_test/priv/run_test.in
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-args=""
-
-while [ $1 ]; do
- if [ $1 = "-config" ]; then
- args="$args -ct_config";
- elif [ $1 = "-decrypt_key" ]; then
- args="$args -ct_decrypt_key";
- elif [ $1 = "-decrypt_file" ]; then
- args="$args -ct_decrypt_file";
- elif [ $1 = "-vts" ]; then
- vts=1;
- args="$args $1";
- elif [ $1 = "-browser" ]; then
- browser=$2;
- args="$args $1";
- elif [ $1 = "-shell" ]; then
- shell=1;
- args="$args $1";
- elif [ $1 = "-ctname" ]; then
- ctname=$2;
- args="$args";
- elif [ $1 = "-ctmaster" ]; then
- master=1;
- args="$args";
- else
- args="$args $1"
- fi
- shift
-done
-
-if [ $vts ]; then
- erl -sname ct \
- -pa @CTPATH@ \
- -pa @TSPATH@ \
- -s webtool script_start vts $browser \
- -s ct_run script_start \
- $args;
-elif [ $shell ]; then
- erl -sname ct \
- -pa @CTPATH@ \
- -pa @TSPATH@ \
- -s ct_run script_start \
- $args;
-elif [ $ctname ]; then
- erl -sname $ctname \
- -pa @CTPATH@ \
- -pa @TSPATH@ \
- $args;
-elif [ $master ]; then
- erl -sname ct_master \
- -pa @CTPATH@ \
- -pa @TSPATH@ \
- $args;
-else
- erl -sname ct \
- -pa @CTPATH@ \
- -pa @TSPATH@ \
- -s ct_run script_start \
- -s erlang halt \
- $args
-fi
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index 449cba6c83..987345c679 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2013. All Rights Reserved.
+# Copyright Ericsson AB 2003-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -77,7 +78,8 @@ MODULES= \
ct_conn_log_h \
cth_conn_log \
ct_groups \
- ct_property_test
+ ct_property_test \
+ ct_release_test
TARGET_MODULES= $(MODULES:%=$(EBIN)/%)
BEAM_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src
index 580d5dbd7b..d847907d75 100644
--- a/lib/common_test/src/common_test.app.src
+++ b/lib/common_test/src/common_test.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -63,9 +64,10 @@
ct_master_logs]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies,["xmerl-1.3.7","webtool-0.8.10","tools-2.6.14",
- "test_server-3.7.1","stdlib-2.0","ssh-3.0.1",
- "snmp-4.25.1","sasl-2.4","runtime_tools-1.8.14",
- "kernel-3.0","inets-5.10","erts-6.0",
- "debugger-4.0","crypto-3.3","compiler-5.0"]}]}.
+ {runtime_dependencies,["xmerl-1.3.8","tools-2.8",
+ "test_server-3.9","stdlib-2.5","ssh-4.0",
+ "snmp-5.1.2","sasl-2.4.2","runtime_tools-1.8.16",
+ "kernel-4.0","inets-6.0","erts-7.0",
+ "debugger-4.1","crypto-3.6","compiler-6.0",
+ "observer-2.1"]}]}.
diff --git a/lib/common_test/src/common_test.appup.src b/lib/common_test/src/common_test.appup.src
index 4dfd9f1b0d..a657e4a3a6 100644
--- a/lib/common_test/src/common_test.appup.src
+++ b/lib/common_test/src/common_test.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index 9d8fce2789..22941668f2 100644
--- a/lib/common_test/src/ct.erl
+++ b/lib/common_test/src/ct.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -63,7 +64,8 @@
-export([require/1, require/2,
get_config/1, get_config/2, get_config/3,
reload_config/1,
- log/1, log/2, log/3, log/4,
+ escape_chars/1, escape_chars/2,
+ log/1, log/2, log/3, log/4, log/5,
print/1, print/2, print/3, print/4,
pal/1, pal/2, pal/3, pal/4,
capture_start/0, capture_stop/0, capture_get/0, capture_get/1,
@@ -79,6 +81,7 @@
%% Other interface functions
-export([get_status/0, abort_current_testcase/1,
get_event_mgr_ref/0,
+ get_testspec_terms/0, get_testspec_terms/1,
encrypt_config_file/2, encrypt_config_file/3,
decrypt_config_file/2, decrypt_config_file/3]).
@@ -158,9 +161,9 @@ run(TestDirs) ->
%%% {repeat,N} | {duration,DurTime} | {until,StopTime} |
%%% {force_stop,ForceStop} | {decrypt,DecryptKeyOrFile} |
%%% {refresh_logs,LogDir} | {logopts,LogOpts} |
-%%% {verbosity,VLevels} | {basic_html,Bool} |
-%%% {ct_hooks, CTHs} | {enable_builtin_hooks,Bool} |
-%%% {release_shell,Bool}
+%%% {verbosity,VLevels} | {basic_html,Bool} |
+%%% {esc_chars,Bool} | {ct_hooks, CTHs} |
+%%% {enable_builtin_hooks,Bool} | {release_shell,Bool}
%%% TestDirs = [string()] | string()
%%% Suites = [string()] | [atom()] | string() | atom()
%%% Cases = [atom()] | atom()
@@ -463,44 +466,132 @@ reload_config(Required)->
ct_config:reload_config(Required).
%%%-----------------------------------------------------------------
+%%% @spec get_testspec_terms() -> TestSpecTerms | undefined
+%%% TestSpecTerms = [{Tag,Value}]
+%%% Value = [term()]
+%%%
+%%% @doc Get a list of all test specification terms used to
+%%% configure and run this test.
+%%%
+get_testspec_terms() ->
+ case ct_util:get_testdata(testspec) of
+ undefined ->
+ undefined;
+ CurrSpecRec ->
+ ct_testspec:testspec_rec2list(CurrSpecRec)
+ end.
+
+%%%-----------------------------------------------------------------
+%%% @spec get_testspec_terms(Tags) -> TestSpecTerms | undefined
+%%% Tags = [Tag] | Tag
+%%% Tag = atom()
+%%% TestSpecTerms = [{Tag,Value}] | {Tag,Value}
+%%% Value = [{Node,term()}] | [term()]
+%%% Node = atom()
+%%%
+%%% @doc Read one or more terms from the test specification used
+%%% to configure and run this test. Tag is any valid test specification
+%%% tag, such as e.g. <c>label</c>, <c>config</c>, <c>logdir</c>.
+%%% User specific terms are also available to read if the
+%%% <c>allow_user_terms</c> option has been set. Note that all value tuples
+%%% returned, except user terms, will have the node name as first element.
+%%% Note also that in order to read test terms, use <c>Tag = tests</c>
+%%% (rather than <c>suites</c>, <c>groups</c> or <c>cases</c>). Value is
+%%% then the list of *all* tests on the form:
+%%% <c>[{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...], where
+%%% GroupsAndCases = [{Group,[Case]}] | [Case]</c>.
+get_testspec_terms(Tags) ->
+ case ct_util:get_testdata(testspec) of
+ undefined ->
+ undefined;
+ CurrSpecRec ->
+ ct_testspec:testspec_rec2list(Tags, CurrSpecRec)
+ end.
+
+
+%%%-----------------------------------------------------------------
+%%% @spec escape_chars(IoList1) -> IoList2 | {error,Reason}
+%%% IoList1 = iolist()
+%%% IoList2 = iolist()
+%%%
+%%% @doc Escape special characters to be printed in html log
+%%%
+escape_chars(IoList) ->
+ ct_logs:escape_chars(IoList).
+
+%%%-----------------------------------------------------------------
+%%% @spec escape_chars(Format, Args) -> IoList | {error,Reason}
+%%% Format = string()
+%%% Args = list()
+%%%
+%%% @doc Escape special characters to be printed in html log
+%%%
+escape_chars(Format, Args) ->
+ try io_lib:format(Format, Args) of
+ IoList ->
+ ct_logs:escape_chars(IoList)
+ catch
+ _:Reason ->
+ {error,Reason}
+ end.
+
+%%%-----------------------------------------------------------------
%%% @spec log(Format) -> ok
-%%% @equiv log(default,50,Format,[])
+%%% @equiv log(default,50,Format,[],[])
log(Format) ->
- log(default,?STD_IMPORTANCE,Format,[]).
+ log(default,?STD_IMPORTANCE,Format,[],[]).
%%%-----------------------------------------------------------------
%%% @spec log(X1,X2) -> ok
%%% X1 = Category | Importance | Format
%%% X2 = Format | Args
-%%% @equiv log(Category,Importance,Format,Args)
+%%% @equiv log(Category,Importance,Format,Args,[])
log(X1,X2) ->
{Category,Importance,Format,Args} =
if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]};
is_integer(X1) -> {default,X1,X2,[]};
is_list(X1) -> {default,?STD_IMPORTANCE,X1,X2}
end,
- log(Category,Importance,Format,Args).
+ log(Category,Importance,Format,Args,[]).
%%%-----------------------------------------------------------------
%%% @spec log(X1,X2,X3) -> ok
+%%% X1 = Category | Importance | Format
+%%% X2 = Importance | Format | Args
+%%% X3 = Format | Args | Opts
+%%% @equiv log(Category,Importance,Format,Args,Opts)
+log(X1,X2,X3) ->
+ {Category,Importance,Format,Args,Opts} =
+ if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]};
+ is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3,[]};
+ is_integer(X1) -> {default,X1,X2,X3,[]};
+ is_list(X1), is_list(X2) -> {default,?STD_IMPORTANCE,X1,X2,X3}
+ end,
+ log(Category,Importance,Format,Args,Opts).
+
+%%%-----------------------------------------------------------------
+%%% @spec log(X1,X2,X3,X4) -> ok
%%% X1 = Category | Importance
%%% X2 = Importance | Format
%%% X3 = Format | Args
-%%% @equiv log(Category,Importance,Format,Args)
-log(X1,X2,X3) ->
- {Category,Importance,Format,Args} =
- if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[]};
- is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3};
- is_integer(X1) -> {default,X1,X2,X3}
+%%% X4 = Args | Opts
+%%% @equiv log(Category,Importance,Format,Args,Opts)
+log(X1,X2,X3,X4) ->
+ {Category,Importance,Format,Args,Opts} =
+ if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]};
+ is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3,X4};
+ is_integer(X1) -> {default,X1,X2,X3,X4}
end,
- log(Category,Importance,Format,Args).
+ log(Category,Importance,Format,Args,Opts).
%%%-----------------------------------------------------------------
-%%% @spec log(Category,Importance,Format,Args) -> ok
+%%% @spec log(Category,Importance,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
%%% Format = string()
%%% Args = list()
+%%% Opts = [Opt]
+%%% Opt = esc_chars | no_css
%%%
%%% @doc Printout from a test case to the log file.
%%%
@@ -512,8 +603,8 @@ log(X1,X2,X3) ->
%%% and default value for <c>Args</c> is <c>[]</c>.</p>
%%% <p>Please see the User's Guide for details on <c>Category</c>
%%% and <c>Importance</c>.</p>
-log(Category,Importance,Format,Args) ->
- ct_logs:tc_log(Category,Importance,Format,Args).
+log(Category,Importance,Format,Args,Opts) ->
+ ct_logs:tc_log(Category,Importance,Format,Args,Opts).
%%%-----------------------------------------------------------------
@@ -684,7 +775,7 @@ capture_get([]) ->
test_server:capture_get().
%%%-----------------------------------------------------------------
-%%% @spec fail(Reason) -> void()
+%%% @spec fail(Reason) -> ok
%%% Reason = term()
%%%
%%% @doc Terminate a test case with the given error
@@ -702,7 +793,7 @@ fail(Reason) ->
end.
%%%-----------------------------------------------------------------
-%%% @spec fail(Format, Args) -> void()
+%%% @spec fail(Format, Args) -> ok
%%% Format = string()
%%% Args = list()
%%%
@@ -728,7 +819,7 @@ fail(Format, Args) ->
end.
%%%-----------------------------------------------------------------
-%%% @spec comment(Comment) -> void()
+%%% @spec comment(Comment) -> ok
%%% Comment = term()
%%%
%%% @doc Print the given <c>Comment</c> in the comment field in
@@ -751,7 +842,7 @@ comment(Comment) ->
send_html_comment(lists:flatten(Formatted)).
%%%-----------------------------------------------------------------
-%%% @spec comment(Format, Args) -> void()
+%%% @spec comment(Format, Args) -> ok
%%% Format = string()
%%% Args = list()
%%%
diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl
index 5c80a299f8..251204aa75 100644
--- a/lib/common_test/src/ct_config.erl
+++ b/lib/common_test/src/ct_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------------
@@ -693,8 +694,7 @@ make_crypto_key(String) ->
{[K1,K2,K3],IVec}.
random_bytes(N) ->
- {A,B,C} = now(),
- random:seed(A, B, C),
+ random:seed(os:timestamp()),
random_bytes_1(N, []).
random_bytes_1(0, Acc) -> Acc;
diff --git a/lib/common_test/src/ct_config_plain.erl b/lib/common_test/src/ct_config_plain.erl
index c6547f0a40..810dec7c76 100644
--- a/lib/common_test/src/ct_config_plain.erl
+++ b/lib/common_test/src/ct_config_plain.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_config_xml.erl b/lib/common_test/src/ct_config_xml.erl
index 6e0a016161..593ae3de52 100644
--- a/lib/common_test/src/ct_config_xml.erl
+++ b/lib/common_test/src/ct_config_xml.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl
index cff02a46d9..034906a3ba 100644
--- a/lib/common_test/src/ct_conn_log_h.erl
+++ b/lib/common_test/src/ct_conn_log_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,6 +35,8 @@
-define(WIDTH,80).
+-define(now, os:timestamp()).
+
%%%-----------------------------------------------------------------
%%% Callbacks
init({GL,ConnLogs}) ->
@@ -72,14 +75,14 @@ handle_event({_Type, GL, _Msg}, State) when node(GL) /= node() ->
handle_event({_Type,GL,{Pid,{ct_connection,Mod,Action,ConnName},Report}},
State) ->
Info = conn_info(Pid,#conn_log{name=ConnName,action=Action,module=Mod}),
- write_report(now(),Info,Report,GL,State),
+ write_report(?now,Info,Report,GL,State),
{ok, State};
handle_event({_Type,GL,{Pid,Info=#conn_log{},Report}}, State) ->
- write_report(now(),conn_info(Pid,Info),Report,GL,State),
+ write_report(?now,conn_info(Pid,Info),Report,GL,State),
{ok, State};
handle_event({error_report,GL,{Pid,_,[{ct_connection,ConnName}|R]}}, State) ->
%% Error reports from connection
- write_error(now(),conn_info(Pid,#conn_log{name=ConnName}),R,GL,State),
+ write_error(?now,conn_info(Pid,#conn_log{name=ConnName}),R,GL,State),
{ok, State};
handle_event(_What, State) ->
{ok, State}.
@@ -101,40 +104,63 @@ terminate(_,#state{logs=Logs}) ->
%%%-----------------------------------------------------------------
%%% Writing reports
write_report(_Time,#conn_log{header=false,module=ConnMod}=Info,Data,GL,State) ->
- {LogType,Fd} = get_log(Info,GL,State),
- io:format(Fd,"~n~ts",[format_data(ConnMod,LogType,Data)]);
+ case get_log(Info,GL,State) of
+ {silent,_,_} ->
+ ok;
+ {LogType,Dest,Fd} ->
+ Str = if LogType == html, Dest == gl -> ["$tc_html","~n~ts"];
+ true -> "~n~ts"
+ end,
+ io:format(Fd,Str,[format_data(ConnMod,LogType,Data)])
+ end;
write_report(Time,#conn_log{module=ConnMod}=Info,Data,GL,State) ->
- {LogType,Fd} = get_log(Info,GL,State),
- io:format(Fd,"~n~ts~ts~ts",[format_head(ConnMod,LogType,Time),
- format_title(LogType,Info),
- format_data(ConnMod,LogType,Data)]).
+ case get_log(Info,GL,State) of
+ {silent,_,_} ->
+ ok;
+ {LogType,Dest,Fd} ->
+ case format_data(ConnMod,LogType,Data) of
+ [] when Info#conn_log.action==send; Info#conn_log.action==recv ->
+ ok;
+ FormattedData ->
+ Str = if LogType == html, Dest == gl ->
+ ["$tc_html","~n~ts~ts~ts"];
+ true ->
+ "~n~ts~ts~ts"
+ end,
+ io:format(Fd,Str,[format_head(ConnMod,LogType,Time),
+ format_title(LogType,Info),
+ FormattedData])
+ end
+ end.
write_error(Time,#conn_log{module=ConnMod}=Info,Report,GL,State) ->
case get_log(Info,GL,State) of
- {html,_} ->
+ {LogType,_,_} when LogType==html; LogType==silent ->
%% The error will anyway be written in the html log by the
%% sasl error handler, so don't write it again.
ok;
- {LogType,Fd} ->
- io:format(Fd,"~n~ts~ts~ts",
- [format_head(ConnMod,LogType,Time," ERROR"),
- format_title(LogType,Info),
- format_error(LogType,Report)])
+ {LogType,Dest,Fd} ->
+ Str = if LogType == html, Dest == gl -> ["$tc_html","~n~ts~ts~ts"];
+ true -> "~n~ts~ts~ts"
+ end,
+ io:format(Fd,Str,[format_head(ConnMod,LogType,Time," ERROR"),
+ format_title(LogType,Info),
+ format_error(LogType,Report)])
end.
get_log(Info,GL,State) ->
case proplists:get_value(GL,State#state.logs) of
undefined ->
- {html,State#state.default_gl};
+ {html,gl,State#state.default_gl};
ConnLogs ->
case proplists:get_value(Info#conn_log.module,ConnLogs) of
{html,_} ->
- {html,GL};
+ {html,gl,GL};
{LogType,Fds} ->
- {LogType,get_fd(Info,Fds)};
+ {LogType,file,get_fd(Info,Fds)};
undefined ->
- {html,GL}
+ {html,gl,GL}
end
end.
diff --git a/lib/common_test/src/ct_cover.erl b/lib/common_test/src/ct_cover.erl
index b630a51835..8e5ce9b245 100644
--- a/lib/common_test/src/ct_cover.erl
+++ b/lib/common_test/src/ct_cover.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/ct_event.erl b/lib/common_test/src/ct_event.erl
index c1c1d943b9..01beabaa73 100644
--- a/lib/common_test/src/ct_event.erl
+++ b/lib/common_test/src/ct_event.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -259,8 +260,8 @@ handle_info(_Info, State) ->
{ok, State}.
%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description:Whenever an event handler is deleted from an event manager,
+%% Function: terminate(Reason, State) -> ok
+%% Description: Whenever an event handler is deleted from an event manager,
%% this function is called. It should be the opposite of Module:init/1 and
%% do any necessary cleaning up.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index 498950c9d1..19a3a51b88 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,7 +28,7 @@
-export([init_tc/3, end_tc/3, end_tc/4, get_suite/2, get_all_cases/1]).
-export([report/2, warn/1, error_notification/4]).
--export([get_logopts/0, format_comment/1, get_html_wrapper/4]).
+-export([get_log_dir/0, get_logopts/0, format_comment/1, get_html_wrapper/4]).
-export([error_in_suite/1, init_per_suite/1, end_per_suite/1,
init_per_group/2, end_per_group/2]).
@@ -51,9 +52,23 @@
%%%
%%% @doc Test server framework callback, called by the test_server
%%% when a new test case is started.
-init_tc(Mod,Func,Config) ->
+init_tc(Mod,EPTC={end_per_testcase,_},[Config]) ->
%% in case Mod == ct_framework, lookup the suite name
Suite = get_suite_name(Mod, Config),
+ case ct_hooks:init_tc(Suite,EPTC,Config) of
+ NewConfig when is_list(NewConfig) ->
+ {ok,[NewConfig]};
+ Other->
+ Other
+ end;
+
+init_tc(Mod,Func0,Args) ->
+ %% in case Mod == ct_framework, lookup the suite name
+ Suite = get_suite_name(Mod, Args),
+ {Func,HookFunc} = case Func0 of
+ {init_per_testcase,F} -> {F,Func0};
+ _ -> {Func0,Func0}
+ end,
%% check if previous testcase was interpreted and has left
%% a "dead" trace window behind - if so, kill it
@@ -85,7 +100,7 @@ init_tc(Mod,Func,Config) ->
end, [create]),
case ct_util:read_suite_data({seq,Suite,Func}) of
undefined ->
- init_tc1(Mod,Suite,Func,Config);
+ init_tc1(Mod,Suite,Func,HookFunc,Args);
Seq when is_atom(Seq) ->
case ct_util:read_suite_data({seq,Suite,Seq}) of
[Func|TCs] -> % this is the 1st case in Seq
@@ -101,26 +116,27 @@ init_tc(Mod,Func,Config) ->
_ ->
ok
end,
- init_tc1(Mod,Suite,Func,Config);
+ init_tc1(Mod,Suite,Func,HookFunc,Args);
{failed,Seq,BadFunc} ->
{auto_skip,{sequence_failed,Seq,BadFunc}}
end
end
- end.
+ end.
-init_tc1(?MODULE,_,error_in_suite,[Config0]) when is_list(Config0) ->
+init_tc1(?MODULE,_,error_in_suite,_,[Config0]) when is_list(Config0) ->
ct_logs:init_tc(false),
ct_event:notify(#event{name=tc_start,
node=node(),
data={?MODULE,error_in_suite}}),
- case ?val(error, Config0) of
+ ct_suite_init(?MODULE,error_in_suite,[],Config0),
+ case ?val(error,Config0) of
undefined ->
{fail,"unknown_error_in_suite"};
Reason ->
{fail,Reason}
end;
-init_tc1(Mod,Suite,Func,[Config0]) when is_list(Config0) ->
+init_tc1(Mod,Suite,Func,HookFunc,[Config0]) when is_list(Config0) ->
Config1 =
case ct_util:read_suite_data(last_saved_config) of
{{Suite,LastFunc},SavedConfig} -> % last testcase
@@ -154,11 +170,13 @@ init_tc1(Mod,Suite,Func,[Config0]) when is_list(Config0) ->
%% testcase info function (these should only survive the
%% testcase, not the whole suite)
FuncSpec = group_or_func(Func,Config0),
- if is_tuple(FuncSpec) -> % group
- ok;
- true ->
- ct_config:delete_default_config(testcase)
- end,
+ HookFunc1 =
+ if is_tuple(FuncSpec) -> % group
+ FuncSpec;
+ true ->
+ ct_config:delete_default_config(testcase),
+ HookFunc
+ end,
Initialize = fun() ->
ct_logs:init_tc(false),
ct_event:notify(#event{name=tc_start,
@@ -182,14 +200,15 @@ init_tc1(Mod,Suite,Func,[Config0]) when is_list(Config0) ->
Initialize(),
{fail,Reason};
_ ->
- init_tc2(Mod,Suite,Func,SuiteInfo,MergeResult,Config)
+ init_tc2(Mod,Suite,Func,HookFunc1,
+ SuiteInfo,MergeResult,Config)
end
end;
-init_tc1(_Mod,_Suite,_Func,Args) ->
+init_tc1(_Mod,_Suite,_Func,_HookFunc,Args) ->
{ok,Args}.
-init_tc2(Mod,Suite,Func,SuiteInfo,MergeResult,Config) ->
+init_tc2(Mod,Suite,Func,HookFunc,SuiteInfo,MergeResult,Config) ->
%% timetrap must be handled before require
MergedInfo = timetrap_first(MergeResult, [], []),
%% tell logger to use specified style sheet
@@ -236,7 +255,7 @@ init_tc2(Mod,Suite,Func,SuiteInfo,MergeResult,Config) ->
{ok,PostInitHook,Config1} ->
case get('$test_server_framework_test') of
undefined ->
- ct_suite_init(Suite, FuncSpec, PostInitHook, Config1);
+ ct_suite_init(Suite,HookFunc,PostInitHook,Config1);
Fun ->
PostInitHookResult = do_post_init_hook(PostInitHook,
Config1),
@@ -249,16 +268,16 @@ init_tc2(Mod,Suite,Func,SuiteInfo,MergeResult,Config) ->
end
end.
-ct_suite_init(Suite, FuncSpec, PostInitHook, Config) when is_list(Config) ->
- case ct_hooks:init_tc(Suite, FuncSpec, Config) of
+ct_suite_init(Suite,HookFunc,PostInitHook,Config) when is_list(Config) ->
+ case ct_hooks:init_tc(Suite,HookFunc,Config) of
NewConfig when is_list(NewConfig) ->
- PostInitHookResult = do_post_init_hook(PostInitHook, NewConfig),
+ PostInitHookResult = do_post_init_hook(PostInitHook,NewConfig),
{ok, [PostInitHookResult ++ NewConfig]};
Else ->
Else
end.
-do_post_init_hook(PostInitHook, Config) ->
+do_post_init_hook(PostInitHook,Config) ->
lists:flatmap(fun({Tag,Fun}) ->
case lists:keysearch(Tag,1,Config) of
{value,_} ->
@@ -635,16 +654,43 @@ try_set_default(Name,Key,Info,Where) ->
end_tc(Mod, Fun, Args) ->
%% Have to keep end_tc/3 for backwards compatibility issues
end_tc(Mod, Fun, Args, '$end_tc_dummy').
-end_tc(?MODULE,error_in_suite,_, _) -> % bad start!
+end_tc(?MODULE,error_in_suite,{Result,[Args]},Return) ->
+ %% this clause gets called if CT has encountered a suite that
+ %% can't be executed
+ FinalNotify =
+ case ct_hooks:end_tc(?MODULE, error_in_suite, Args, Result, Return) of
+ '$ct_no_change' ->
+ Result;
+ HookResult ->
+ HookResult
+ end,
+ Event = #event{name=tc_done,
+ node=node(),
+ data={?MODULE,error_in_suite,tag(FinalNotify)}},
+ ct_event:sync_notify(Event),
ok;
end_tc(Mod,Func,{TCPid,Result,[Args]}, Return) when is_pid(TCPid) ->
end_tc(Mod,Func,TCPid,Result,Args,Return);
end_tc(Mod,Func,{Result,[Args]}, Return) ->
end_tc(Mod,Func,self(),Result,Args,Return).
-end_tc(Mod,Func,TCPid,Result,Args,Return) ->
+end_tc(Mod,IPTC={init_per_testcase,_Func},_TCPid,Result,Args,Return) ->
+ %% in case Mod == ct_framework, lookup the suite name
+ Suite = get_suite_name(Mod, Args),
+ case ct_hooks:end_tc(Suite,IPTC,Args,Result,Return) of
+ '$ct_no_change' ->
+ ok;
+ HookResult ->
+ HookResult
+ end;
+
+end_tc(Mod,Func0,TCPid,Result,Args,Return) ->
%% in case Mod == ct_framework, lookup the suite name
Suite = get_suite_name(Mod, Args),
+ {EPTC,Func} = case Func0 of
+ {end_per_testcase,F} -> {true,F};
+ _ -> {false,Func0}
+ end,
test_server:timetrap_cancel(),
@@ -671,11 +717,15 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) ->
end,
ct_util:delete_suite_data(last_saved_config),
- FuncSpec = group_or_func(Func,Args),
-
+ {FuncSpec,HookFunc} =
+ if not EPTC ->
+ FS = group_or_func(Func,Args),
+ {FS,FS};
+ true ->
+ {Func,Func0}
+ end,
{Result1,FinalNotify} =
- case ct_hooks:end_tc(
- Suite, FuncSpec, Args, Result, Return) of
+ case ct_hooks:end_tc(Suite,HookFunc,Args,Result,Return) of
'$ct_no_change' ->
{ok,Result};
HookResult ->
@@ -816,13 +866,13 @@ tag(_Other) ->
%%% <code>Func</code> in suite <code>Mod</code> crashing.
%%% <code>Error</code> specifies the reason for failing.
error_notification(Mod,Func,_Args,{Error,Loc}) ->
- ErrSpec = case Error of
+ ErrorSpec = case Error of
{What={_E,_R},Trace} when is_list(Trace) ->
What;
What ->
What
end,
- ErrStr = case ErrSpec of
+ ErrorStr = case ErrorSpec of
{badmatch,Descr} ->
Descr1 = lists:flatten(io_lib:format("~P",[Descr,10])),
if length(Descr1) > 50 ->
@@ -844,7 +894,8 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
Other ->
io_lib:format("~P", [Other,5])
end,
- ErrorHtml = "<font color=\"brown\">" ++ ErrStr ++ "</font>",
+ ErrorHtml =
+ "<font color=\"brown\">" ++ ct_logs:escape_chars(ErrorStr) ++ "</font>",
case {Mod,Error} of
%% some notifications come from the main test_server process
%% and for these cases the existing comment may not be modified
@@ -872,41 +923,43 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
end
end,
- PrintErr = fun(ErrFormat, ErrArgs) ->
- Div = "~n- - - - - - - - - - - - - - - - "
- "- - - - - - - - - -~n",
- io:format(user, lists:concat([Div,ErrFormat,Div,"~n"]),
- ErrArgs),
+ PrintError = fun(ErrorFormat, ErrorArgs) ->
+ Div = "~n- - - - - - - - - - - - - - - - - - - "
+ "- - - - - - - - - - - - - - - - - - - - -~n",
+ ErrorStr2 = io_lib:format(ErrorFormat, ErrorArgs),
+ io:format(user, lists:concat([Div,ErrorStr2,Div,"~n"]),
+ []),
Link =
"\n\n<a href=\"#end\">"
"Full error description and stacktrace"
"</a>",
+ ErrorHtml2 = ct_logs:escape_chars(ErrorStr2),
ct_logs:tc_log(ct_error_notify,
?MAX_IMPORTANCE,
"CT Error Notification",
- ErrFormat++Link, ErrArgs)
+ ErrorHtml2++Link, [], [])
end,
case Loc of
[{?MODULE,error_in_suite}] ->
- PrintErr("Error in suite detected: ~ts", [ErrStr]);
+ PrintError("Error in suite detected: ~ts", [ErrorStr]);
R when R == unknown; R == undefined ->
- PrintErr("Error detected: ~ts", [ErrStr]);
+ PrintError("Error detected: ~ts", [ErrorStr]);
%% if a function specified by all/0 does not exist, we
%% pick up undef here
- [{LastMod,LastFunc}|_] when ErrStr == "undef" ->
- PrintErr("~w:~w could not be executed~nReason: ~ts",
- [LastMod,LastFunc,ErrStr]);
+ [{LastMod,LastFunc}|_] when ErrorStr == "undef" ->
+ PrintError("~w:~w could not be executed~nReason: ~ts",
+ [LastMod,LastFunc,ErrorStr]);
[{LastMod,LastFunc}|_] ->
- PrintErr("~w:~w failed~nReason: ~ts", [LastMod,LastFunc,ErrStr]);
+ PrintError("~w:~w failed~nReason: ~ts", [LastMod,LastFunc,ErrorStr]);
[{LastMod,LastFunc,LastLine}|_] ->
%% print error to console, we are only
%% interested in the last executed expression
- PrintErr("~w:~w failed on line ~w~nReason: ~ts",
- [LastMod,LastFunc,LastLine,ErrStr]),
+ PrintError("~w:~w failed on line ~w~nReason: ~ts",
+ [LastMod,LastFunc,LastLine,ErrorStr]),
case ct_util:read_suite_data({seq,Mod,Func}) of
undefined ->
@@ -1062,9 +1115,32 @@ get_all_cases1(_, []) ->
get_all(Mod, ConfTests) ->
case catch apply(Mod, all, []) of
- {'EXIT',_} ->
- Reason =
- list_to_atom(atom_to_list(Mod)++":all/0 is missing"),
+ {'EXIT',{undef,[{Mod,all,[],_} | _]}} ->
+ Reason =
+ case code:which(Mod) of
+ non_existing ->
+ list_to_atom(atom_to_list(Mod)++
+ " can not be compiled or loaded");
+ _ ->
+ list_to_atom(atom_to_list(Mod)++":all/0 is missing")
+ end,
+ %% this makes test_server call error_in_suite as first
+ %% (and only) test case so we can report Reason properly
+ [{?MODULE,error_in_suite,[[{error,Reason}]]}];
+ {'EXIT',ExitReason} ->
+ case ct_util:get_testdata({error_in_suite,Mod}) of
+ undefined ->
+ ErrStr = io_lib:format("~n*** ERROR *** "
+ "~w:all/0 failed: ~p~n",
+ [Mod,ExitReason]),
+ io:format(user, ErrStr, []),
+ %% save the error info so it doesn't get printed twice
+ ct_util:set_testdata_async({{error_in_suite,Mod},
+ ExitReason});
+ _ExitReason ->
+ ct_util:delete_testdata({error_in_suite,Mod})
+ end,
+ Reason = list_to_atom(atom_to_list(Mod)++":all/0 failed"),
%% this makes test_server call error_in_suite as first
%% (and only) test case so we can report Reason properly
[{?MODULE,error_in_suite,[[{error,Reason}]]}];
@@ -1287,6 +1363,8 @@ report(What,Data) ->
end,
ct_logs:unregister_groupleader(ReportingPid),
case {Func,Result} of
+ {error_in_suite,_} when Suite == ?MODULE ->
+ ok;
{init_per_suite,_} ->
ok;
{end_per_suite,_} ->
@@ -1440,3 +1518,8 @@ get_html_wrapper(TestName, PrintLabel, Cwd, TableCols) ->
get_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) ->
ct_logs:get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding).
+
+%%%-----------------------------------------------------------------
+%%% @spec get_log_dir() -> {ok,LogDir}
+get_log_dir() ->
+ ct_logs:get_log_dir(true).
diff --git a/lib/common_test/src/ct_ftp.erl b/lib/common_test/src/ct_ftp.erl
index 71fd8754ff..616b1a8934 100644
--- a/lib/common_test/src/ct_ftp.erl
+++ b/lib/common_test/src/ct_ftp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl
index 56082086f6..e46fd77383 100644
--- a/lib/common_test/src/ct_gen_conn.erl
+++ b/lib/common_test/src/ct_gen_conn.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,10 +25,9 @@
-module(ct_gen_conn).
--compile(export_all).
-
--export([start/4, stop/1, get_conn_pid/1]).
+-export([start/4, stop/1, get_conn_pid/1, check_opts/1]).
-export([call/2, call/3, return/2, do_within_time/2]).
+-export([log/3, start_log/1, cont_log/2, end_log/0]).
%%----------------------------------------------------------------------
%% Exported types
diff --git a/lib/common_test/src/ct_groups.erl b/lib/common_test/src/ct_groups.erl
index 14a8aab881..899d2bfb5a 100644
--- a/lib/common_test/src/ct_groups.erl
+++ b/lib/common_test/src/ct_groups.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -80,7 +81,7 @@ find(Mod, all, all, [{Name,Props,Tests} | Gs], Known, Defs, _)
find(Mod, all, TCs, [{Name,Props,Tests} | Gs], Known, Defs, _)
when is_atom(Name), is_list(Props), is_list(Tests) ->
cyclic_test(Mod, Name, Known),
- Tests1 = rm_unwanted_tcs(Tests, TCs, []),
+ Tests1 = modify_tc_list(Tests, TCs, []),
trim(make_conf(Mod, Name, Props,
find(Mod, all, TCs, Tests1, [Name | Known],
Defs, true))) ++
@@ -90,7 +91,7 @@ find(Mod, all, TCs, [{Name,Props,Tests} | Gs], Known, Defs, _)
find(Mod, [Name|GrNames]=SPath, TCs, [{Name,Props,Tests} | Gs], Known,
Defs, FindAll) when is_atom(Name), is_list(Props), is_list(Tests) ->
cyclic_test(Mod, Name, Known),
- Tests1 = rm_unwanted_tcs(Tests, TCs, GrNames),
+ Tests1 = modify_tc_list(Tests, TCs, GrNames),
trim(make_conf(Mod, Name, Props,
find(Mod, GrNames, TCs, Tests1, [Name|Known],
Defs, FindAll))) ++
@@ -132,7 +133,7 @@ find(_Mod, [_|_], _TCs, [], _Known, _Defs, _) ->
find(Mod, GrNames, TCs, [{Name,Props,Tests} | Gs], Known,
Defs, FindAll) when is_atom(Name), is_list(Props), is_list(Tests) ->
cyclic_test(Mod, Name, Known),
- Tests1 = rm_unwanted_tcs(Tests, TCs, GrNames),
+ Tests1 = modify_tc_list(Tests, TCs, GrNames),
trim(make_conf(Mod, Name, Props,
find(Mod, GrNames, TCs, Tests1, [Name|Known],
Defs, FindAll))) ++
@@ -283,70 +284,57 @@ trim_test(Test) ->
%% GrNames is [] if the terminating group has been found. From
%% that point, all specified test should be included (as well as
%% sub groups for deeper search).
-rm_unwanted_tcs(Tests, all, []) ->
- Tests;
-
-rm_unwanted_tcs(Tests, TCs, []) ->
- sort_tests(lists:flatmap(fun(Test) when is_tuple(Test),
- (size(Test) > 2) ->
- [Test];
- (Test={group,_}) ->
- [Test];
- (Test={_M,TC}) ->
- case lists:member(TC, TCs) of
- true -> [Test];
- false -> []
- end;
- (Test) when is_atom(Test) ->
- case lists:keysearch(Test, 2, TCs) of
- {value,_} ->
- [Test];
- _ ->
- case lists:member(Test, TCs) of
- true -> [Test];
- false -> []
- end
- end;
- (Test) -> [Test]
- end, Tests), TCs);
-
-rm_unwanted_tcs(Tests, _TCs, _) ->
- [Test || Test <- Tests, not is_atom(Test)].
-
-%% make sure the order of tests is according to the order in TCs
-sort_tests(Tests, TCs) when is_list(TCs)->
- lists:sort(fun(T1, T2) ->
- case {is_tc(T1),is_tc(T2)} of
- {true,true} ->
- (position(T1, TCs) =<
- position(T2, TCs));
- {false,true} ->
- (position(T2, TCs) == (length(TCs)+1));
- _ -> true
-
- end
- end, Tests);
-sort_tests(Tests, _) ->
- Tests.
-
-is_tc(T) when is_atom(T) -> true;
-is_tc({group,_}) -> false;
-is_tc({_M,T}) when is_atom(T) -> true;
-is_tc(_) -> false.
-
-position(T, TCs) ->
- position(T, TCs, 1).
-
-position(T, [T|_TCs], Pos) ->
- Pos;
-position(T, [{_,T}|_TCs], Pos) ->
- Pos;
-position({M,T}, [T|_TCs], Pos) when M /= group ->
- Pos;
-position(T, [_|TCs], Pos) ->
- position(T, TCs, Pos+1);
-position(_, [], Pos) ->
- Pos.
+modify_tc_list(GrSpecTs, all, []) ->
+ GrSpecTs;
+
+modify_tc_list(GrSpecTs, TSCs, []) ->
+ modify_tc_list1(GrSpecTs, TSCs);
+
+modify_tc_list(GrSpecTs, _TSCs, _) ->
+ [Test || Test <- GrSpecTs, not is_atom(Test)].
+
+modify_tc_list1(GrSpecTs, TSCs) ->
+ %% remove all cases in group tc list that should not be executed
+ GrSpecTs1 =
+ lists:flatmap(fun(Test) when is_tuple(Test),
+ (size(Test) > 2) ->
+ [Test];
+ (Test={group,_}) ->
+ [Test];
+ (Test={_M,TC}) ->
+ case lists:member(TC, TSCs) of
+ true -> [Test];
+ false -> []
+ end;
+ (Test) when is_atom(Test) ->
+ case lists:keysearch(Test, 2, TSCs) of
+ {value,_} ->
+ [Test];
+ _ ->
+ case lists:member(Test, TSCs) of
+ true -> [Test];
+ false -> []
+ end
+ end;
+ (Test) -> [Test]
+ end, GrSpecTs),
+ {TSCs2,GrSpecTs3} =
+ lists:foldr(
+ fun(TC, {TSCs1,GrSpecTs2}) ->
+ case lists:member(TC,GrSpecTs1) of
+ true ->
+ {[TC|TSCs1],lists:delete(TC,GrSpecTs2)};
+ false ->
+ case lists:keysearch(TC, 2, GrSpecTs) of
+ {value,Test} ->
+ {[Test|TSCs1],
+ lists:keydelete(TC, 2, GrSpecTs2)};
+ false ->
+ {TSCs1,GrSpecTs2}
+ end
+ end
+ end, {[],GrSpecTs1}, TSCs),
+ TSCs2 ++ GrSpecTs3.
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl
index df4c98d9d1..90f36cbdc2 100644
--- a/lib/common_test/src/ct_hooks.erl
+++ b/lib/common_test/src/ct_hooks.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -66,6 +67,8 @@ terminate(Hooks) ->
%% tests.
-spec init_tc(Mod :: atom(),
FuncSpec :: atom() |
+ {ConfigFunc :: init_per_testcase | end_per_testcase,
+ TestCase :: atom()} |
{ConfigFunc :: init_per_group | end_per_group,
GroupName :: atom(),
Properties :: list()},
@@ -92,13 +95,19 @@ init_tc(Mod, {init_per_group, GroupName, Properties}, Config) ->
call(fun call_generic/3, Config, [pre_init_per_group, GroupName]);
init_tc(_Mod, {end_per_group, GroupName, _}, Config) ->
call(fun call_generic/3, Config, [pre_end_per_group, GroupName]);
-init_tc(_Mod, TC, Config) ->
+init_tc(_Mod, {init_per_testcase,TC}, Config) ->
+ call(fun call_generic/3, Config, [pre_init_per_testcase, TC]);
+init_tc(_Mod, {end_per_testcase,TC}, Config) ->
+ call(fun call_generic/3, Config, [pre_end_per_testcase, TC]);
+init_tc(_Mod, TC = error_in_suite, Config) ->
call(fun call_generic/3, Config, [pre_init_per_testcase, TC]).
%% @doc Called as each test case is completed. This includes all configuration
%% tests.
-spec end_tc(Mod :: atom(),
- FuncSpec :: atom() |
+ FuncSpec :: atom() |
+ {ConfigFunc :: init_per_testcase | end_per_testcase,
+ TestCase :: atom()} |
{ConfigFunc :: init_per_group | end_per_group,
GroupName :: atom(),
Properties :: list()},
@@ -125,10 +134,17 @@ end_tc(Mod, {end_per_group, GroupName, Properties}, Config, Result, _Return) ->
[post_end_per_group, GroupName, Config], '$ct_no_change'),
maybe_stop_locker(Mod, GroupName, Properties),
Res;
-end_tc(_Mod, TC, Config, Result, _Return) ->
+end_tc(_Mod, {init_per_testcase,TC}, Config, Result, _Return) ->
+ call(fun call_generic/3, Result, [post_init_per_testcase, TC, Config],
+ '$ct_no_change');
+end_tc(_Mod, {end_per_testcase,TC}, Config, Result, _Return) ->
+ call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config],
+ '$ct_no_change');
+end_tc(_Mod, TC = error_in_suite, Config, Result, _Return) ->
call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config],
'$ct_no_change').
+
%% Case = TestCase | {TestCase,GroupName}
on_tc_skip(How, {Suite, Case, Reason}) ->
call(fun call_cleanup/3, {How, Reason}, [on_tc_skip, Suite, Case]).
@@ -243,6 +259,8 @@ remove(_, Else) ->
%% Translate scopes, i.e. init_per_group,group1 -> end_per_group,group1 etc
scope([pre_init_per_testcase, TC|_]) ->
+ [post_init_per_testcase, TC];
+scope([pre_end_per_testcase, TC|_]) ->
[post_end_per_testcase, TC];
scope([pre_init_per_group, GroupName|_]) ->
[post_end_per_group, GroupName];
@@ -316,7 +334,8 @@ get_hooks() ->
%% If we are doing a cleanup call i.e. {post,pre}_end_per_*, all priorities
%% are reversed. Probably want to make this sorting algorithm pluginable
%% as some point...
-resort(Calls,Hooks,[F|_R]) when F == post_end_per_testcase;
+resort(Calls,Hooks,[F|_R]) when F == pre_end_per_testcase;
+ F == post_end_per_testcase;
F == pre_end_per_group;
F == post_end_per_group;
F == pre_end_per_suite;
@@ -366,10 +385,10 @@ pos(Id,[_|Rest],Num) ->
catch_apply(M,F,A, Default) ->
try
- apply(M,F,A)
+ erlang:apply(M,F,A)
catch _:Reason ->
case erlang:get_stacktrace() of
- %% Return the default if it was the CTH module which did not have the function.
+ %% Return the default if it was the CTH module which did not have the function.
[{M,F,A,_}|_] when Reason == undef ->
Default;
Trace ->
diff --git a/lib/common_test/src/ct_hooks_lock.erl b/lib/common_test/src/ct_hooks_lock.erl
index e33fa278dc..1a058aa8ca 100644
--- a/lib/common_test/src/ct_hooks_lock.erl
+++ b/lib/common_test/src/ct_hooks_lock.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index fa55a9754e..a9ad571bfc 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -36,15 +37,17 @@
-export([add_external_logs/1, add_link/3]).
-export([make_last_run_index/0]).
-export([make_all_suites_index/1,make_all_runs_index/1]).
--export([get_ts_html_wrapper/5]).
+-export([get_ts_html_wrapper/5, escape_chars/1]).
-export([xhtml/2, locate_priv_file/1, make_relative/1]).
-export([insert_javascript/1]).
-export([uri/1]).
%% Logging stuff directly from testcase
--export([tc_log/3, tc_log/4, tc_log/5, tc_log_async/3, tc_log_async/5,
+-export([tc_log/3, tc_log/4, tc_log/5, tc_log/6,
+ tc_log_async/3, tc_log_async/5,
tc_print/3, tc_print/4,
- tc_pal/3, tc_pal/4, ct_log/3, basic_html/0]).
+ tc_pal/3, tc_pal/4, ct_log/3,
+ basic_html/0]).
%% Simulate logger process for use without ct environment running
-export([simulate/0]).
@@ -73,6 +76,8 @@
-define(abs(Name), filename:absname(Name)).
+-define(now, os:timestamp()).
+
-record(log_cache, {version,
all_runs = [],
tests = []}).
@@ -264,7 +269,7 @@ cast(Msg) ->
%%% <p>This function is called by ct_framework:init_tc/3</p>
init_tc(RefreshLog) ->
call({init_tc,self(),group_leader(),RefreshLog}),
- io:format(xhtml("", "<br />")),
+ io:format(["$tc_html",xhtml("", "<br />")]),
ok.
%%%-----------------------------------------------------------------
@@ -311,9 +316,10 @@ unregister_groupleader(Pid) ->
%%% data to log (as in <code>io:format(Format,Args)</code>).</p>
log(Heading,Format,Args) ->
cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE,
- [{int_header(),[log_timestamp(now()),Heading]},
+ [{hd,int_header(),[log_timestamp(?now),Heading]},
{Format,Args},
- {int_footer(),[]}]}),
+ {ft,int_footer(),[]}],
+ true}),
ok.
%%%-----------------------------------------------------------------
@@ -333,7 +339,7 @@ log(Heading,Format,Args) ->
%%% @see end_log/0
start_log(Heading) ->
cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE,
- [{int_header(),[log_timestamp(now()),Heading]}]}),
+ [{hd,int_header(),[log_timestamp(?now),Heading]}],false}),
ok.
%%%-----------------------------------------------------------------
@@ -348,7 +354,7 @@ cont_log([],[]) ->
cont_log(Format,Args) ->
maybe_log_timestamp(),
cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE,
- [{Format,Args}]}),
+ [{Format,Args}],true}),
ok.
%%%-----------------------------------------------------------------
@@ -360,7 +366,7 @@ cont_log(Format,Args) ->
%%% @see cont_log/2
end_log() ->
cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE,
- [{int_footer(), []}]}),
+ [{ft,int_footer(), []}],false}),
ok.
@@ -397,32 +403,46 @@ add_link(Heading,File,Type) ->
%%% @spec tc_log(Category,Format,Args) -> ok
%%% @equiv tc_log(Category,?STD_IMPORTANCE,Format,Args)
tc_log(Category,Format,Args) ->
- tc_log(Category,?STD_IMPORTANCE,Format,Args).
+ tc_log(Category,?STD_IMPORTANCE,"User",Format,Args,[]).
%%%-----------------------------------------------------------------
%%% @spec tc_log(Category,Importance,Format,Args) -> ok
%%% @equiv tc_log(Category,Importance,"User",Format,Args)
tc_log(Category,Importance,Format,Args) ->
- tc_log(Category,Importance,"User",Format,Args).
+ tc_log(Category,Importance,"User",Format,Args,[]).
+
+%%%-----------------------------------------------------------------
+%%% @spec tc_log(Category,Importance,Format,Args) -> ok
+%%% @equiv tc_log(Category,Importance,"User",Format,Args)
+tc_log(Category,Importance,Format,Args,Opts) ->
+ tc_log(Category,Importance,"User",Format,Args,Opts).
%%%-----------------------------------------------------------------
-%%% @spec tc_log(Category,Importance,Printer,Format,Args) -> ok
+%%% @spec tc_log(Category,Importance,Printer,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
%%% Printer = string()
%%% Format = string()
%%% Args = list()
+%%% Opts = list()
%%%
%%% @doc Printout from a testcase.
%%%
%%% <p>This function is called by <code>ct</code> when logging
%%% stuff directly from a testcase (i.e. not from within the CT
%%% framework).</p>
-tc_log(Category,Importance,Printer,Format,Args) ->
- cast({log,sync,self(),group_leader(),Category,Importance,
- [{div_header(Category,Printer),[]},
- {Format,Args},
- {div_footer(),[]}]}),
+tc_log(Category,Importance,Printer,Format,Args,Opts) ->
+ Data =
+ case lists:member(no_css, Opts) of
+ true ->
+ [{Format,Args}];
+ false ->
+ [{hd,div_header(Category,Printer),[]},
+ {Format,Args},
+ {ft,div_footer(),[]}]
+ end,
+ cast({log,sync,self(),group_leader(),Category,Importance,Data,
+ lists:member(esc_chars, Opts)}),
ok.
%%%-----------------------------------------------------------------
@@ -448,9 +468,10 @@ tc_log_async(Category,Format,Args) ->
%%% asks ct_logs for an html wrapper.</p>
tc_log_async(Category,Importance,Printer,Format,Args) ->
cast({log,async,self(),group_leader(),Category,Importance,
- [{div_header(Category,Printer),[]},
+ [{hd,div_header(Category,Printer),[]},
{Format,Args},
- {div_footer(),[]}]}),
+ {ft,div_footer(),[]}],
+ true}),
ok.
%%%-----------------------------------------------------------------
%%% @spec tc_print(Category,Format,Args)
@@ -491,11 +512,11 @@ tc_print(Category,Importance,Format,Args) ->
get_heading(default) ->
io_lib:format("\n-----------------------------"
"-----------------------\n~s\n",
- [log_timestamp(now())]);
+ [log_timestamp(?now)]);
get_heading(Category) ->
io_lib:format("\n-----------------------------"
"-----------------------\n~s ~w\n",
- [log_timestamp(now()),Category]).
+ [log_timestamp(?now),Category]).
%%%-----------------------------------------------------------------
@@ -519,53 +540,55 @@ tc_pal(Category,Format,Args) ->
tc_pal(Category,Importance,Format,Args) ->
tc_print(Category,Importance,Format,Args),
cast({log,sync,self(),group_leader(),Category,Importance,
- [{div_header(Category),[]},
+ [{hd,div_header(Category),[]},
{Format,Args},
- {div_footer(),[]}]}),
+ {ft,div_footer(),[]}],
+ true}),
ok.
%%%-----------------------------------------------------------------
-%%% @spec ct_pal(Category,Format,Args) -> ok
+%%% @spec ct_log(Category,Format,Args) -> ok
%%% Category = atom()
%%% Format = string()
%%% Args = list()
%%%
-%%% @doc Print and log to the ct framework log
+%%% @doc Print to the ct framework log
%%%
%%% <p>This function is called by internal ct functions to
%%% force logging to the ct framework log</p>
ct_log(Category,Format,Args) ->
- cast({ct_log,[{div_header(Category),[]},
+ cast({ct_log,[{hd,div_header(Category),[]},
{Format,Args},
- {div_footer(),[]}]}),
+ {ft,div_footer(),[]}],
+ true}),
ok.
%%%=================================================================
%%% Internal functions
int_header() ->
- "<div class=\"ct_internal\"><b>*** CT ~s *** ~ts</b>".
+ "</pre>\n<div class=\"ct_internal\"><pre><b>*** CT ~s *** ~ts</b>".
int_footer() ->
- "</div>".
+ "</pre></div>\n<pre>".
div_header(Class) ->
div_header(Class,"User").
div_header(Class,Printer) ->
- "\n<div class=\"" ++ atom_to_list(Class) ++ "\"><b>*** " ++ Printer ++
- " " ++ log_timestamp(now()) ++ " ***</b>".
+ "\n</pre>\n<div class=\"" ++ atom_to_list(Class) ++ "\"><pre><b>*** "
+ ++ Printer ++ " " ++ log_timestamp(?now) ++ " ***</b>".
div_footer() ->
- "</div>".
+ "</pre></div>\n<pre>".
maybe_log_timestamp() ->
- {MS,S,US} = now(),
+ {MS,S,US} = ?now,
case get(log_timestamp) of
{MS,S,_} ->
ok;
_ ->
cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE,
- [{"<i>~s</i>",[log_timestamp({MS,S,US})]}]})
+ [{hd,"<i>~s</i>",[log_timestamp({MS,S,US})]}],false})
end.
log_timestamp({MS,S,US}) ->
@@ -586,7 +609,8 @@ log_timestamp({MS,S,US}) ->
ct_log_fd,
tc_groupleaders,
stylesheet,
- async_print_jobs}).
+ async_print_jobs,
+ tc_esc_chars}).
logger(Parent, Mode, Verbosity) ->
register(?MODULE,self()),
@@ -686,7 +710,7 @@ logger(Parent, Mode, Verbosity) ->
make_last_run_index(Time),
CtLogFd = open_ctlog(?misc_io_log),
io:format(CtLogFd,int_header()++int_footer(),
- [log_timestamp(now()),"Common Test Logger started"]),
+ [log_timestamp(?now),"Common Test Logger started"]),
Parent ! {started,self(),{Time,filename:absname("")}},
set_evmgr_gl(CtLogFd),
@@ -705,14 +729,18 @@ logger(Parent, Mode, Verbosity) ->
end
end || {Cat,VLvl} <- Verbosity],
io:nl(CtLogFd),
-
+ TcEscChars = case application:get_env(common_test, esc_chars) of
+ {ok,ECBool} -> ECBool;
+ _ -> true
+ end,
logger_loop(#logger_state{parent=Parent,
log_dir=AbsDir,
start_time=Time,
orig_GL=group_leader(),
ct_log_fd=CtLogFd,
tc_groupleaders=[],
- async_print_jobs=[]}).
+ async_print_jobs=[],
+ tc_esc_chars=TcEscChars}).
copy_priv_files([SrcF | SrcFs], [DestF | DestFs]) ->
case file:copy(SrcF, DestF) of
@@ -726,7 +754,7 @@ copy_priv_files([], []) ->
logger_loop(State) ->
receive
- {log,SyncOrAsync,Pid,GL,Category,Importance,List} ->
+ {log,SyncOrAsync,Pid,GL,Category,Importance,Content,EscChars} ->
VLvl = case Category of
ct_internal ->
?MAX_VERBOSITY;
@@ -738,20 +766,21 @@ logger_loop(State) ->
end,
if Importance >= (100-VLvl) ->
CtLogFd = State#logger_state.ct_log_fd,
+ DoEscChars = State#logger_state.tc_esc_chars and EscChars,
case get_groupleader(Pid, GL, State) of
{tc_log,TCGL,TCGLs} ->
case erlang:is_process_alive(TCGL) of
true ->
State1 = print_to_log(SyncOrAsync, Pid,
- Category,
- TCGL, List, State),
+ Category, TCGL, Content,
+ DoEscChars, State),
logger_loop(State1#logger_state{
tc_groupleaders = TCGLs});
false ->
%% Group leader is dead, so write to the
%% CtLog or unexpected_io log instead
- unexpected_io(Pid,Category,Importance,
- List,CtLogFd),
+ unexpected_io(Pid, Category, Importance,
+ Content, CtLogFd, DoEscChars),
logger_loop(State)
end;
@@ -759,7 +788,8 @@ logger_loop(State) ->
%% If category is ct_internal then write
%% to ct_log, else write to unexpected_io
%% log
- unexpected_io(Pid,Category,Importance,List,CtLogFd),
+ unexpected_io(Pid, Category, Importance, Content,
+ CtLogFd, DoEscChars),
logger_loop(State#logger_state{
tc_groupleaders = TCGLs})
end;
@@ -770,7 +800,7 @@ logger_loop(State) ->
%% make sure no IO for this test case from the
%% CT logger gets rejected
test_server:permit_io(GL, self()),
- print_style(GL, State#logger_state.stylesheet),
+ print_style(GL,GL,State#logger_state.stylesheet),
set_evmgr_gl(GL),
TCGLs = add_tc_gl(TCPid,GL,State),
if not RefreshLog ->
@@ -815,10 +845,17 @@ logger_loop(State) ->
logger_loop(State);
{clear_stylesheet,_} ->
logger_loop(State#logger_state{stylesheet = undefined});
- {ct_log, List} ->
+ {ct_log,Content,EscChars} ->
+ Str = lists:map(fun({_HdOrFt,Str,Args}) ->
+ [io_lib:format(Str,Args),io_lib:nl()];
+ ({Str,Args}) when EscChars ->
+ Io = io_lib:format(Str,Args),
+ [escape_chars(Io),io_lib:nl()];
+ ({Str,Args}) ->
+ [io_lib:format(Str,Args),io_lib:nl()]
+ end, Content),
Fd = State#logger_state.ct_log_fd,
- [begin io:format(Fd,Str,Args),io:nl(Fd) end ||
- {Str,Args} <- List],
+ io:format(Fd, "~ts", [Str]),
logger_loop(State);
{'DOWN',Ref,_,_Pid,_} ->
%% there might be print jobs executing in parallel with ct_logs
@@ -835,50 +872,84 @@ logger_loop(State) ->
stop ->
io:format(State#logger_state.ct_log_fd,
int_header()++int_footer(),
- [log_timestamp(now()),"Common Test Logger finished"]),
+ [log_timestamp(?now),"Common Test Logger finished"]),
close_ctlog(State#logger_state.ct_log_fd),
ok
end.
-create_io_fun(FromPid, CtLogFd) ->
+create_io_fun(FromPid, CtLogFd, EscChars) ->
%% we have to build one io-list of all strings
%% before printing, or other io printouts (made in
%% parallel) may get printed between this header
%% and footer
- fun({Str,Args}, IoList) ->
- case catch io_lib:format(Str,Args) of
- {'EXIT',_Reason} ->
+ fun(FormatData, IoList) ->
+ {Escapable,Str,Args} =
+ case FormatData of
+ {_HdOrFt,S,A} -> {false,S,A};
+ {S,A} -> {true,S,A}
+ end,
+ try io_lib:format(Str, Args) of
+ IoStr when Escapable, EscChars, IoList == [] ->
+ escape_chars(IoStr);
+ IoStr when Escapable, EscChars ->
+ [IoList,"\n",escape_chars(IoStr)];
+ IoStr when IoList == [] ->
+ IoStr;
+ IoStr ->
+ [IoList,"\n",IoStr]
+ catch
+ _:_Reason ->
io:format(CtLogFd, "Logging fails! Str: ~p, Args: ~p~n",
[Str,Args]),
%% stop the testcase, we need to see the fault
exit(FromPid, {log_printout_error,Str,Args}),
- [];
- IoStr when IoList == [] ->
- [IoStr];
- IoStr ->
- [IoList,"\n",IoStr]
+ []
end
end.
-print_to_log(sync, FromPid, Category, TCGL, List, State) ->
+escape_chars([Bin | Io]) when is_binary(Bin) ->
+ [Bin | escape_chars(Io)];
+escape_chars([List | Io]) when is_list(List) ->
+ [escape_chars(List) | escape_chars(Io)];
+escape_chars([$< | Io]) ->
+ ["&lt;" | escape_chars(Io)];
+escape_chars([$> | Io]) ->
+ ["&gt;" | escape_chars(Io)];
+escape_chars([$& | Io]) ->
+ ["&amp;" | escape_chars(Io)];
+escape_chars([Char | Io]) when is_integer(Char) ->
+ [Char | escape_chars(Io)];
+escape_chars([]) ->
+ [];
+escape_chars(Bin) ->
+ Bin.
+
+print_to_log(sync, FromPid, Category, TCGL, Content, EscChars, State) ->
%% in some situations (exceptions), the printout is made from the
%% test server IO process and there's no valid group leader to send to
CtLogFd = State#logger_state.ct_log_fd,
if FromPid /= TCGL ->
- IoFun = create_io_fun(FromPid, CtLogFd),
- io:format(TCGL,"~ts", [lists:foldl(IoFun, [], List)]);
+ IoFun = create_io_fun(FromPid, CtLogFd, EscChars),
+ IoList = lists:foldl(IoFun, [], Content),
+ try io:format(TCGL,["$tc_html","~ts"], [IoList]) of
+ ok -> ok
+ catch
+ _:_ ->
+ io:format(TCGL,"~ts", [IoList])
+ end;
true ->
- unexpected_io(FromPid,Category,?MAX_IMPORTANCE,List,CtLogFd)
+ unexpected_io(FromPid, Category, ?MAX_IMPORTANCE, Content,
+ CtLogFd, EscChars)
end,
State;
-print_to_log(async, FromPid, Category, TCGL, List, State) ->
+print_to_log(async, FromPid, Category, TCGL, Content, EscChars, State) ->
%% in some situations (exceptions), the printout is made from the
%% test server IO process and there's no valid group leader to send to
CtLogFd = State#logger_state.ct_log_fd,
Printer =
if FromPid /= TCGL ->
- IoFun = create_io_fun(FromPid, CtLogFd),
+ IoFun = create_io_fun(FromPid, CtLogFd, EscChars),
fun() ->
test_server:permit_io(TCGL, self()),
@@ -891,25 +962,28 @@ print_to_log(async, FromPid, Category, TCGL, List, State) ->
case erlang:is_process_alive(TCGL) of
true ->
- try io:format(TCGL, "~ts",
- [lists:foldl(IoFun,[],List)]) of
+ try io:format(TCGL, ["$tc_html","~ts"],
+ [lists:foldl(IoFun,[],Content)]) of
_ -> ok
catch
_:terminated ->
unexpected_io(FromPid, Category,
?MAX_IMPORTANCE,
- List, CtLogFd)
+ Content, CtLogFd, EscChars);
+ _:_ ->
+ io:format(TCGL, "~ts",
+ [lists:foldl(IoFun,[],Content)])
end;
false ->
unexpected_io(FromPid, Category,
?MAX_IMPORTANCE,
- List, CtLogFd)
+ Content, CtLogFd, EscChars)
end
end;
true ->
fun() ->
unexpected_io(FromPid, Category, ?MAX_IMPORTANCE,
- List, CtLogFd)
+ Content, CtLogFd, EscChars)
end
end,
case State#logger_state.async_print_jobs of
@@ -1039,26 +1113,27 @@ open_ctlog(MiscIoName) ->
"View I/O logged after the test run</a></li>\n</ul>\n",
[MiscIoName,MiscIoName]),
- print_style(Fd,undefined),
+ print_style(Fd,group_leader(),undefined),
io:format(Fd,
xhtml("<br><h2>Progress Log</h2>\n<pre>\n",
"<br />\n<h4>PROGRESS LOG</h4>\n<pre>\n"), []),
Fd.
-print_style(Fd,undefined) ->
+print_style(Fd,GL,undefined) ->
case basic_html() of
true ->
- io:format(Fd,
- "<style>\n"
- "div.ct_internal { background:lightgrey; color:black; }\n"
- "div.default { background:lightgreen; color:black; }\n"
- "</style>\n",
- []);
+ Style = "<style>\n
+ div.ct_internal { background:lightgrey; color:black; }\n
+ div.default { background:lightgreen; color:black; }\n
+ </style>\n",
+ if Fd == GL -> io:format(["$tc_html",Style], []);
+ true -> io:format(Fd, Style, [])
+ end;
_ ->
ok
end;
-print_style(Fd,StyleSheet) ->
+print_style(Fd,GL,StyleSheet) ->
case file:read_file(StyleSheet) of
{ok,Bin} ->
Str = b2s(Bin,encoding(StyleSheet)),
@@ -1071,29 +1146,30 @@ print_style(Fd,StyleSheet) ->
N1 -> N1
end,
if (Pos0 == 0) and (Pos1 /= 0) ->
- print_style_error(Fd,StyleSheet,missing_style_start_tag);
+ print_style_error(Fd,GL,StyleSheet,missing_style_start_tag);
(Pos0 /= 0) and (Pos1 == 0) ->
- print_style_error(Fd,StyleSheet,missing_style_end_tag);
+ print_style_error(Fd,GL,StyleSheet,missing_style_end_tag);
Pos0 /= 0 ->
Style = string:sub_string(Str,Pos0,Pos1+7),
- io:format(Fd,"~ts\n",[Style]);
+ if Fd == GL -> io:format(Fd,["$tc_html","~ts\n"],[Style]);
+ true -> io:format(Fd,"~ts\n",[Style])
+ end;
Pos0 == 0 ->
- io:format(Fd,"<style>~ts</style>\n",[Str])
+ if Fd == GL -> io:format(Fd,["$tc_html","<style>\n~ts</style>\n"],[Str]);
+ true -> io:format(Fd,"<style>\n~ts</style>\n",[Str])
+ end
end;
{error,Reason} ->
- print_style_error(Fd,StyleSheet,Reason)
+ print_style_error(Fd,GL,StyleSheet,Reason)
end.
-%% Simple link version, doesn't work with all browsers unfortunately. :-(
-%% print_style(Fd, StyleSheet) ->
-%% io:format(Fd,
-%% "<link href=~p rel=\"stylesheet\" type=\"text/css\">",
-%% [StyleSheet]).
-
-print_style_error(Fd,StyleSheet,Reason) ->
- io:format(Fd,"\n<!-- Failed to load stylesheet ~ts: ~p -->\n",
- [StyleSheet,Reason]),
- print_style(Fd,undefined).
+print_style_error(Fd,GL,StyleSheet,Reason) ->
+ IO = io_lib:format("\n<!-- Failed to load stylesheet ~ts: ~p -->\n",
+ [StyleSheet,Reason]),
+ if Fd == GL -> io:format(Fd,["$tc_html",IO],[]);
+ true -> io:format(Fd,IO,[])
+ end,
+ print_style(Fd,GL,undefined).
close_ctlog(Fd) ->
io:format(Fd, "\n</pre>\n", []),
@@ -1361,11 +1437,11 @@ total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) ->
[xhtml("<tr valign=top>\n",
["</tbody>\n<tfoot>\n<tr class=\"",odd_or_even(),"\">\n"]),
"<td><b>Total</b></td>\n", Label, TimestampCell,
- "<td align=right><b>",integer_to_list(Success),"<b></td>\n",
- "<td align=right><b>",integer_to_list(Fail),"<b></td>\n",
+ "<td align=right><b>",integer_to_list(Success),"</b></td>\n",
+ "<td align=right><b>",integer_to_list(Fail),"</b></td>\n",
"<td align=right>",integer_to_list(AllSkip),
" (",UserSkipStr,"/",AutoSkipStr,")</td>\n",
- "<td align=right><b>",integer_to_list(NotBuilt),"<b></td>\n",
+ "<td align=right><b>",integer_to_list(NotBuilt),"</b></td>\n",
AllInfo, "</tr>\n",
xhtml("","</tfoot>\n")].
@@ -1557,10 +1633,12 @@ header1(Title, SubTitle, TableCols) ->
"<!-- autogenerated by '"++atom_to_list(?MODULE)++"' -->\n",
"<head>\n",
"<title>" ++ Title ++ " " ++ SubTitle ++ "</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
- "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\"></meta>\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; "
+ "charset=utf-8\"></meta>\n",
xhtml("",
- ["<link rel=\"stylesheet\" href=\"",uri(CSSFile),"\" type=\"text/css\">\n"]),
+ ["<link rel=\"stylesheet\" href=\"",uri(CSSFile),
+ "\" type=\"text/css\"></link>\n"]),
xhtml("",
["<script type=\"text/javascript\" src=\"",JQueryFile,
"\"></script>\n"]),
@@ -1607,7 +1685,7 @@ footer() ->
"Copyright &copy; ", year(),
" <a href=\"http://www.erlang.org\">Open Telecom Platform</a>",
xhtml("<br>\n", "<br />\n"),
- "Updated: <!date>", current_time(), "<!/date>",
+ "Updated: <!--date-->", current_time(), "<!--/date-->",
xhtml("<br>\n", "<br />\n"),
xhtml("</font></p>\n", "</div>\n"),
"</center>\n"
@@ -1982,9 +2060,9 @@ interactive_link() ->
"<!-- autogenerated by '"++atom_to_list(?MODULE)++"' -->\n",
"<head>\n",
"<title>Last interactive run</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\"></meta>\n",
"<meta http-equiv=\"content-type\" content=\"text/html; "
- "charset=utf-8\">\n",
+ "charset=utf-8\"></meta>\n",
"</head>\n",
"<body>\n",
"Log from last interactive run: <a href=\"",uri(CtLog),"\">",
@@ -2052,6 +2130,13 @@ runentry(Dir, Totals={Node,Label,Logs,
?testname_width-3)),
lists:flatten(io_lib:format("~ts...",[Trunc]))
end,
+ TotMissingStr =
+ if NotBuilt > 0 ->
+ ["<font color=\"red\">",
+ integer_to_list(NotBuilt),"</font>"];
+ true ->
+ integer_to_list(NotBuilt)
+ end,
Total = TotSucc+TotFail+AllSkip,
A = xhtml(["<td align=center><font size=\"-1\">",Node,
"</font></td>\n",
@@ -2071,7 +2156,7 @@ runentry(Dir, Totals={Node,Label,Logs,
"<td align=right>",TotFailStr,"</td>\n",
"<td align=right>",integer_to_list(AllSkip),
" (",UserSkipStr,"/",AutoSkipStr,")</td>\n",
- "<td align=right>",integer_to_list(NotBuilt),"</td>\n"],
+ "<td align=right>",TotMissingStr,"</td>\n"],
TotalsStr = A++B++C,
XHTML = [xhtml("<tr>\n", ["<tr class=\"",odd_or_even(),"\">\n"]),
@@ -2836,8 +2921,12 @@ simulate() ->
simulate_logger_loop() ->
receive
- {log,_,_,_,_,_,List} ->
- S = [[io_lib:format(Str,Args),io_lib:nl()] || {Str,Args} <- List],
+ {log,_,_,_,_,_,Content,_} ->
+ S = lists:map(fun({_,Str,Args}) ->
+ [io_lib:format(Str,Args),io_lib:nl()];
+ ({Str,Args}) ->
+ [io_lib:format(Str,Args),io_lib:nl()]
+ end, Content),
io:format("~ts",[S]),
simulate_logger_loop();
stop ->
@@ -3043,15 +3132,15 @@ get_ts_html_wrapper(TestName, Logdir, PrintLabel, Cwd, TableCols, Encoding) ->
"Copyright &copy; ", year(),
" <a href=\"http://www.erlang.org\">",
"Open Telecom Platform</a><br>\n",
- "Updated: <!date>", current_time(), "<!/date>",
+ "Updated: <!--date-->", current_time(), "<!--/date-->",
"<br>\n</font></p>\n"],
{basic_html,
["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n",
"<html>\n",
"<head><title>", TestName1, "</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\"></meta>\n",
"<meta http-equiv=\"content-type\" content=\"text/html; charset=",
- html_encoding(Encoding),"\">\n",
+ html_encoding(Encoding),"\"></meta>\n",
"</head>\n",
"<body", Bgr, " bgcolor=\"white\" text=\"black\" ",
"link=\"blue\" vlink=\"purple\" alink=\"red\">\n",
@@ -3068,7 +3157,7 @@ get_ts_html_wrapper(TestName, Logdir, PrintLabel, Cwd, TableCols, Encoding) ->
"Copyright &copy; ", year(),
" <a href=\"http://www.erlang.org\">",
"Open Telecom Platform</a><br />\n",
- "Updated: <!date>", current_time(), "<!/date>",
+ "Updated: <!--date-->", current_time(), "<!--/date-->",
"<br />\n</div>\n"],
CSSFile =
xhtml(fun() -> "" end,
@@ -3095,9 +3184,11 @@ get_ts_html_wrapper(TestName, Logdir, PrintLabel, Cwd, TableCols, Encoding) ->
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n",
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n",
"<head>\n<title>", TestName1, "</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
- "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
- "<link rel=\"stylesheet\" href=\"", uri(CSSFile), "\" type=\"text/css\">\n",
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\"></meta>\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; ",
+ "charset=utf-8\"></meta>\n",
+ "<link rel=\"stylesheet\" href=\"", uri(CSSFile),
+ "\" type=\"text/css\"></link>\n",
"<script type=\"text/javascript\" src=\"", JQueryFile, "\"></script>\n",
"<script type=\"text/javascript\" src=\"", TableSorterFile, "\"></script>\n"] ++
TableSorterScript ++ ["</head>\n","<body>\n", LabelStr, "\n"],
@@ -3223,11 +3314,11 @@ html_encoding(latin1) ->
html_encoding(utf8) ->
"utf-8".
-unexpected_io(Pid,ct_internal,_Importance,List,CtLogFd) ->
- IoFun = create_io_fun(Pid,CtLogFd),
- io:format(CtLogFd, "~ts", [lists:foldl(IoFun, [], List)]);
-unexpected_io(Pid,_Category,_Importance,List,CtLogFd) ->
- IoFun = create_io_fun(Pid,CtLogFd),
- Data = io_lib:format("~ts", [lists:foldl(IoFun, [], List)]),
+unexpected_io(Pid, ct_internal, _Importance, Content, CtLogFd, EscChars) ->
+ IoFun = create_io_fun(Pid, CtLogFd, EscChars),
+ io:format(CtLogFd, "~ts", [lists:foldl(IoFun, [], Content)]);
+unexpected_io(Pid, _Category, _Importance, Content, CtLogFd, EscChars) ->
+ IoFun = create_io_fun(Pid, CtLogFd, EscChars),
+ Data = io_lib:format("~ts", [lists:foldl(IoFun, [], Content)]),
test_server_io:print_unexpected(Data),
ok.
diff --git a/lib/common_test/src/ct_make.erl b/lib/common_test/src/ct_make.erl
index d4bd81e78d..f4b81a0ef6 100644
--- a/lib/common_test/src/ct_make.erl
+++ b/lib/common_test/src/ct_make.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl
index 2cdb259899..d24edad2eb 100644
--- a/lib/common_test/src/ct_master.erl
+++ b/lib/common_test/src/ct_master.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,7 +27,7 @@
-export([run_on_node/2,run_on_node/3]).
-export([run_test/1,run_test/2]).
-export([get_event_mgr_ref/0]).
--export([basic_html/1]).
+-export([basic_html/1,esc_chars/1]).
-export([abort/0,abort/1,progress/0]).
@@ -316,6 +317,16 @@ basic_html(Bool) ->
ok.
%%%-----------------------------------------------------------------
+%%% @spec esc_chars(Bool) -> ok
+%%% Bool = true | false
+%%%
+%%% @doc If set to false, the ct_master logs will be written without
+%%% special characters being escaped in the HTML logs.
+esc_chars(Bool) ->
+ application:set_env(common_test_master, esc_chars, Bool),
+ ok.
+
+%%%-----------------------------------------------------------------
%%% MASTER, runs on central controlling node.
%%%-----------------------------------------------------------------
start_master(NodeOptsList) ->
diff --git a/lib/common_test/src/ct_master_event.erl b/lib/common_test/src/ct_master_event.erl
index fd97ab16f7..0d7d220fd0 100644
--- a/lib/common_test/src/ct_master_event.erl
+++ b/lib/common_test/src/ct_master_event.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -168,7 +169,7 @@ handle_info(_Info,State) ->
{ok,State}.
%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
+%% Function: terminate(Reason, State) -> ok
%% Description:Whenever an event handler is deleted from an event manager,
%% this function is called. It should be the opposite of Module:init/1 and
%% do any necessary cleaning up.
diff --git a/lib/common_test/src/ct_master_logs.erl b/lib/common_test/src/ct_master_logs.erl
index 5393097f57..54190a8254 100644
--- a/lib/common_test/src/ct_master_logs.erl
+++ b/lib/common_test/src/ct_master_logs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,6 +38,8 @@
-define(details_file_name,"details.info").
-define(table_color,"lightblue").
+-define(now, os:timestamp()).
+
%%%--------------------------------------------------------------------
%%% API
%%%--------------------------------------------------------------------
@@ -54,7 +57,7 @@ start(LogDir,Nodes) ->
end.
log(Heading,Format,Args) ->
- cast({log,self(),[{int_header(),[log_timestamp(now()),Heading]},
+ cast({log,self(),[{int_header(),[log_timestamp(?now),Heading]},
{Format,Args},
{int_footer(),[]}]}),
ok.
@@ -132,7 +135,7 @@ init(Parent,LogDir,Nodes) ->
atom_to_list(N) ++ " "
end,Nodes)),
- io:format(CtLogFd,int_header(),[log_timestamp(now()),"Test Nodes\n"]),
+ io:format(CtLogFd,int_header(),[log_timestamp(?now),"Test Nodes\n"]),
io:format(CtLogFd,"~ts\n",[NodeStr]),
io:put_chars(CtLogFd,[int_footer(),"\n"]),
@@ -189,7 +192,7 @@ loop(State) ->
make_all_runs_index(State#state.logdir),
io:format(State#state.log_fd,
int_header()++int_footer(),
- [log_timestamp(now()),"Finished!"]),
+ [log_timestamp(?now),"Finished!"]),
close_ct_master_log(State#state.log_fd),
close_nodedir_index(State#state.nodedir_ix_fd),
ok
@@ -235,9 +238,9 @@ config_table1([]) ->
["</tbody>\n</table>\n"].
int_header() ->
- "<div class=\"ct_internal\"><b>*** CT MASTER ~s *** ~ts</b>".
+ "</pre>\n<div class=\"ct_internal\"><pre><b>*** CT MASTER ~s *** ~ts</b>".
int_footer() ->
- "</div>".
+ "</pre></div>\n<pre>".
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% NodeDir Index functions %%%
@@ -384,11 +387,12 @@ header(Title, TableCols) ->
"<!-- autogenerated by '"++atom_to_list(?MODULE)++"' -->\n",
"<head>\n",
"<title>" ++ Title ++ "</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
- "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\"></meta>\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; ",
+ "charset=utf-8\"></meta>\n",
xhtml("",
["<link rel=\"stylesheet\" href=\"",ct_logs:uri(CSSFile),
- "\" type=\"text/css\">"]),
+ "\" type=\"text/css\"></link>\n"]),
xhtml("",
["<script type=\"text/javascript\" src=\"",JQueryFile,
"\"></script>\n"]),
@@ -416,7 +420,7 @@ footer() ->
"Copyright &copy; ", year(),
" <a href=\"http://www.erlang.org\">Open Telecom Platform</a>",
xhtml("<br>\n", "<br />\n"),
- "Updated: <!date>", current_time(), "<!/date>",
+ "Updated: <!--date-->", current_time(), "<--!/date-->",
xhtml("<br>\n", "<br />\n"),
xhtml("</font></p>\n", "</div>\n"),
"</center>\n"
diff --git a/lib/common_test/src/ct_master_status.erl b/lib/common_test/src/ct_master_status.erl
index f9f511ecca..6a3572b261 100644
--- a/lib/common_test/src/ct_master_status.erl
+++ b/lib/common_test/src/ct_master_status.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -100,8 +101,8 @@ handle_info(_Info, State) ->
{ok, State}.
%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description:Whenever an event handler is deleted from an event manager,
+%% Function: terminate(Reason, State) -> ok
+%% Description: Whenever an event handler is deleted from an event manager,
%% this function is called. It should be the opposite of Module:init/1 and
%% do any necessary cleaning up.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl
index 80ffb51ab9..8812514ad9 100644
--- a/lib/common_test/src/ct_netconfc.erl
+++ b/lib/common_test/src/ct_netconfc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -191,6 +192,7 @@
get_config/4,
edit_config/3,
edit_config/4,
+ edit_config/5,
delete_config/2,
delete_config/3,
copy_config/3,
@@ -232,7 +234,6 @@
%% Internal defines
%%----------------------------------------------------------------------
-define(APPLICATION,?MODULE).
--define(VALID_SSH_OPTS,[user, password, user_dir]).
-define(DEFAULT_STREAM,"NETCONF").
-define(error(ConnName,Report),
@@ -262,6 +263,7 @@
session_id,
msg_id = 1,
hello_status,
+ no_end_tag_buff = <<>>,
buff = <<>>,
pending = [], % [#pending]
event_receiver}).% pid
@@ -691,15 +693,39 @@ get_config(Client, Source, Filter, Timeout) ->
%%----------------------------------------------------------------------
%% @spec edit_config(Client, Target, Config) -> Result
-%% @equiv edit_config(Client, Target, Config, infinity)
+%% @equiv edit_config(Client, Target, Config, [], infinity)
edit_config(Client, Target, Config) ->
edit_config(Client, Target, Config, ?DEFAULT_TIMEOUT).
%%----------------------------------------------------------------------
--spec edit_config(Client, Target, Config, Timeout) -> Result when
+-spec edit_config(Client, Target, Config, OptParamsOrTimeout) -> Result when
Client :: client(),
Target :: netconf_db(),
Config :: simple_xml(),
+ OptParamsOrTimeout :: [simple_xml()] | timeout(),
+ Result :: ok | {error,error_reason()}.
+%% @doc
+%%
+%% If `OptParamsOrTimeout' is a timeout value, then this is
+%% equivalent to {@link edit_config/5. edit_config(Client, Target,
+%% Config, [], Timeout)}.
+%%
+%% If `OptParamsOrTimeout' is a list of simple XML, then this is
+%% equivalent to {@link edit_config/5. edit_config(Client, Target,
+%% Config, OptParams, infinity)}.
+%%
+%% @end
+edit_config(Client, Target, Config, Timeout) when ?is_timeout(Timeout) ->
+ edit_config(Client, Target, Config, [], Timeout);
+edit_config(Client, Target, Config, OptParams) when is_list(OptParams) ->
+ edit_config(Client, Target, Config, OptParams, ?DEFAULT_TIMEOUT).
+
+%%----------------------------------------------------------------------
+-spec edit_config(Client, Target, Config, OptParams, Timeout) -> Result when
+ Client :: client(),
+ Target :: netconf_db(),
+ Config :: simple_xml(),
+ OptParams :: [simple_xml()],
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
%% @doc Edit configuration data.
@@ -708,10 +734,20 @@ edit_config(Client, Target, Config) ->
%% include `:candidate' or `:startup' in its list of
%% capabilities.
%%
+%% `OptParams' can be used for specifying optional parameters
+%% (`default-operation', `test-option' or `error-option') that will be
+%% added to the `edit-config' request. The value must be a list
+%% containing valid simple XML, for example
+%%
+%% ```
+%% [{'default-operation', ["none"]},
+%% {'error-option', ["rollback-on-error"]}]
+%%'''
+%%
%% @end
%%----------------------------------------------------------------------
-edit_config(Client, Target, Config, Timeout) ->
- call(Client, {send_rpc_op, edit_config, [Target,Config], Timeout}).
+edit_config(Client, Target, Config, OptParams, Timeout) ->
+ call(Client, {send_rpc_op, edit_config, [Target,Config,OptParams], Timeout}).
%%----------------------------------------------------------------------
@@ -1100,6 +1136,7 @@ handle_msg({get_event_streams=Op,Streams,Timeout}, From, State) ->
SimpleXml = encode_rpc_operation(get,[Filter]),
do_send_rpc(Op, SimpleXml, Timeout, From, State).
+%% @private
handle_msg({ssh_cm, CM, {data, Ch, _Type, Data}}, State) ->
ssh_connection:adjust_window(CM,Ch,size(Data)),
handle_data(Data, State);
@@ -1133,7 +1170,7 @@ handle_msg({Ref,timeout},#state{pending=Pending} = State) ->
end,
%% Halfhearted try to get in correct state, this matches
%% the implementation before this patch
- {R,State#state{pending=Pending1, buff= <<>>}}.
+ {R,State#state{pending=Pending1, no_end_tag_buff= <<>>, buff= <<>>}}.
%% @private
%% Called by ct_util_server to close registered connections before terminate.
@@ -1168,7 +1205,7 @@ call(Client, Msg, Timeout, WaitStop) ->
{error,no_such_client};
{error,{process_down,Pid,normal}} when WaitStop ->
%% This will happen when server closes connection
- %% before clien received rpc-reply on
+ %% before client received rpc-reply on
%% close-session.
ok;
{error,{process_down,Pid,normal}} ->
@@ -1219,13 +1256,11 @@ check_options([{port,Port}|T], Host, _, #options{} = Options) ->
check_options([{timeout, Timeout}|T], Host, Port, Options)
when is_integer(Timeout); Timeout==infinity ->
check_options(T, Host, Port, Options#options{timeout = Timeout});
-check_options([{X,_}=Opt|T], Host, Port, #options{ssh=SshOpts}=Options) ->
- case lists:member(X,?VALID_SSH_OPTS) of
- true ->
- check_options(T, Host, Port, Options#options{ssh=[Opt|SshOpts]});
- false ->
- {error, {invalid_option, Opt}}
- end.
+check_options([{timeout, _} = Opt|_T], _Host, _Port, _Options) ->
+ {error, {invalid_option, Opt}};
+check_options([Opt|T], Host, Port, #options{ssh=SshOpts}=Options) ->
+ %% Option verified by ssh
+ check_options(T, Host, Port, Options#options{ssh=[Opt|SshOpts]}).
%%%-----------------------------------------------------------------
set_request_timer(infinity) ->
@@ -1235,6 +1270,14 @@ set_request_timer(T) ->
{ok,TRef} = timer:send_after(T,{Ref,timeout}),
{Ref,TRef}.
+%%%-----------------------------------------------------------------
+cancel_request_timer(undefined,undefined) ->
+ ok;
+cancel_request_timer(Ref,TRef) ->
+ _ = timer:cancel(TRef),
+ receive {Ref,timeout} -> ok
+ after 0 -> ok
+ end.
%%%-----------------------------------------------------------------
client_hello(Options) when is_list(Options) ->
@@ -1254,8 +1297,8 @@ encode_rpc_operation(get,[Filter]) ->
{get,filter(Filter)};
encode_rpc_operation(get_config,[Source,Filter]) ->
{'get-config',[{source,[Source]}] ++ filter(Filter)};
-encode_rpc_operation(edit_config,[Target,Config]) ->
- {'edit-config',[{target,[Target]},{config,[Config]}]};
+encode_rpc_operation(edit_config,[Target,Config,OptParams]) ->
+ {'edit-config',[{target,[Target]}] ++ OptParams ++ [{config,[Config]}]};
encode_rpc_operation(delete_config,[Target]) ->
{'delete-config',[{target,[Target]}]};
encode_rpc_operation(copy_config,[Target,Source]) ->
@@ -1327,17 +1370,37 @@ to_xml_doc(Simple) ->
%%%-----------------------------------------------------------------
%%% Parse and handle received XML data
-handle_data(NewData,#state{connection=Connection,buff=Buff0} = State0) ->
+%%% Two buffers are used:
+%%% * 'no_end_tag_buff' contains data that is checked and does not
+%%% contain any (part of an) end tag.
+%%% * 'buff' contains all other saved data - it may or may not
+%%% include (a part of) an end tag.
+%%% The reason for this is to avoid running binary:split/3 multiple
+%%% times on the same data when it does not contain an end tag. This
+%%% can be a considerable optimation in the case when a lot of data is
+%%% received (e.g. when fetching all data from a node) and the data is
+%%% sent in multiple ssh packages.
+handle_data(NewData,#state{connection=Connection} = State0) ->
log(Connection,recv,NewData),
- Data = append_wo_initial_nl(Buff0,NewData),
- case binary:split(Data,[?END_TAG],[]) of
+ NoEndTag0 = State0#state.no_end_tag_buff,
+ Buff0 = State0#state.buff,
+ Data = <<Buff0/binary, NewData/binary>>,
+ case binary:split(Data,?END_TAG,[]) of
[_NoEndTagFound] ->
- {noreply, State0#state{buff=Data}};
- [FirstMsg,Buff1] ->
+ NoEndTagSize = case byte_size(Data) of
+ Sz when Sz<5 -> 0;
+ Sz -> Sz-5
+ end,
+ <<NoEndTag1:NoEndTagSize/binary,Buff/binary>> = Data,
+ NoEndTag = <<NoEndTag0/binary,NoEndTag1/binary>>,
+ {noreply, State0#state{no_end_tag_buff=NoEndTag, buff=Buff}};
+ [FirstMsg0,Buff1] ->
+ FirstMsg = remove_initial_nl(<<NoEndTag0/binary,FirstMsg0/binary>>),
SaxArgs = [{event_fun,fun sax_event/3}, {event_state,[]}],
case xmerl_sax_parser:stream(FirstMsg, SaxArgs) of
{ok, Simple, _Thrash} ->
- case decode(Simple, State0#state{buff=Buff1}) of
+ case decode(Simple, State0#state{no_end_tag_buff= <<>>,
+ buff=Buff1}) of
{noreply, #state{buff=Buff} = State} when Buff =/= <<>> ->
%% Recurse if we have more data in buffer
handle_data(<<>>, State);
@@ -1349,17 +1412,18 @@ handle_data(NewData,#state{connection=Connection,buff=Buff0} = State0) ->
[{parse_error,Reason},
{buffer, Buff0},
{new_data,NewData}]),
- handle_error(Reason, State0#state{buff= <<>>})
+ handle_error(Reason, State0#state{no_end_tag_buff= <<>>,
+ buff= <<>>})
end
end.
+
%% xml does not accept a leading nl and some netconf server add a nl after
%% each ?END_TAG, ignore them
-append_wo_initial_nl(<<>>,NewData) -> NewData;
-append_wo_initial_nl(<<"\n", Data/binary>>, NewData) ->
- append_wo_initial_nl(Data, NewData);
-append_wo_initial_nl(Data, NewData) ->
- <<Data/binary, NewData/binary>>.
+remove_initial_nl(<<"\n", Data/binary>>) ->
+ remove_initial_nl(Data);
+remove_initial_nl(Data) ->
+ Data.
handle_error(Reason, State) ->
Pending1 = case State#state.pending of
@@ -1367,9 +1431,9 @@ handle_error(Reason, State) ->
Pending ->
%% Assuming the first request gets the
%% first answer
- P=#pending{tref=TRef,caller=Caller} =
+ P=#pending{tref=TRef,ref=Ref,caller=Caller} =
lists:last(Pending),
- _ = timer:cancel(TRef),
+ cancel_request_timer(Ref,TRef),
Reason1 = {failed_to_parse_received_data,Reason},
ct_gen_conn:return(Caller,{error,Reason1}),
lists:delete(P,Pending)
@@ -1455,8 +1519,8 @@ decode({Tag,Attrs,_}=E, #state{connection=Connection,pending=Pending}=State) ->
{error,Reason} ->
{noreply,State#state{hello_status = {error,Reason}}}
end;
- #pending{tref=TRef,caller=Caller} ->
- _ = timer:cancel(TRef),
+ #pending{tref=TRef,ref=Ref,caller=Caller} ->
+ cancel_request_timer(Ref,TRef),
case decode_hello(E) of
{ok,SessionId,Capabilities} ->
ct_gen_conn:return(Caller,ok),
@@ -1482,9 +1546,8 @@ decode({Tag,Attrs,_}=E, #state{connection=Connection,pending=Pending}=State) ->
%% there is just one pending that matches (i.e. has
%% undefined msg_id and op)
case [P || P = #pending{msg_id=undefined,op=undefined} <- Pending] of
- [#pending{tref=TRef,
- caller=Caller}] ->
- _ = timer:cancel(TRef),
+ [#pending{tref=TRef,ref=Ref,caller=Caller}] ->
+ cancel_request_timer(Ref,TRef),
ct_gen_conn:return(Caller,E),
{noreply,State#state{pending=[]}};
_ ->
@@ -1505,8 +1568,8 @@ get_msg_id(Attrs) ->
decode_rpc_reply(MsgId,{_,Attrs,Content0}=E,#state{pending=Pending} = State) ->
case lists:keytake(MsgId,#pending.msg_id,Pending) of
- {value, #pending{tref=TRef,op=Op,caller=Caller}, Pending1} ->
- _ = timer:cancel(TRef),
+ {value, #pending{tref=TRef,ref=Ref,op=Op,caller=Caller}, Pending1} ->
+ cancel_request_timer(Ref,TRef),
Content = forward_xmlns_attr(Attrs,Content0),
{CallerReply,{ServerReply,State2}} =
do_decode_rpc_reply(Op,Content,State#state{pending=Pending1}),
@@ -1518,10 +1581,11 @@ decode_rpc_reply(MsgId,{_,Attrs,Content0}=E,#state{pending=Pending} = State) ->
%% pending that matches (i.e. has undefined msg_id and op)
case [P || P = #pending{msg_id=undefined,op=undefined} <- Pending] of
[#pending{tref=TRef,
+ ref=Ref,
msg_id=undefined,
op=undefined,
caller=Caller}] ->
- _ = timer:cancel(TRef),
+ cancel_request_timer(Ref,TRef),
ct_gen_conn:return(Caller,E),
{noreply,State#state{pending=[]}};
_ ->
@@ -1712,6 +1776,7 @@ log(#connection{host=Host,port=Port,name=Name},Action,Data) ->
%% Log callback - called from the error handler process
+%% @private
format_data(How,Data) ->
%% Assuming that the data is encoded as UTF-8. If it is not, then
%% the printout might be wrong, but the format function will not
@@ -1724,9 +1789,14 @@ format_data(How,Data) ->
do_format_data(raw,Data) ->
io_lib:format("~n~ts~n",[hide_password(Data)]);
do_format_data(pretty,Data) ->
- io_lib:format("~n~ts~n",[indent(Data)]);
+ maybe_io_lib_format(indent(Data));
do_format_data(html,Data) ->
- io_lib:format("~n~ts~n",[html_format(Data)]).
+ maybe_io_lib_format(html_format(Data)).
+
+maybe_io_lib_format(<<>>) ->
+ [];
+maybe_io_lib_format(String) ->
+ io_lib:format("~n~ts~n",[String]).
%%%-----------------------------------------------------------------
%%% Hide password elements from XML data
@@ -1765,13 +1835,21 @@ indent1("<?"++Rest1,Indent1) ->
Line++indent1(Rest2,Indent2);
indent1("</"++Rest1,Indent1) ->
%% Stop tag
- {Line,Rest2,Indent2} = indent_line1(Rest1,Indent1,[$/,$<]),
- "\n"++Line++indent1(Rest2,Indent2);
+ case indent_line1(Rest1,Indent1,[$/,$<]) of
+ {[],[],_} ->
+ [];
+ {Line,Rest2,Indent2} ->
+ "\n"++Line++indent1(Rest2,Indent2)
+ end;
indent1("<"++Rest1,Indent1) ->
%% Start- or empty tag
put(tag,get_tag(Rest1)),
- {Line,Rest2,Indent2} = indent_line(Rest1,Indent1,[$<]),
- "\n"++Line++indent1(Rest2,Indent2);
+ case indent_line(Rest1,Indent1,[$<]) of
+ {[],[],_} ->
+ [];
+ {Line,Rest2,Indent2} ->
+ "\n"++Line++indent1(Rest2,Indent2)
+ end;
indent1([H|T],Indent) ->
[H|indent1(T,Indent)];
indent1([],_Indent) ->
diff --git a/lib/common_test/src/ct_netconfc.hrl b/lib/common_test/src/ct_netconfc.hrl
index 295a61a98b..e4746fe8b7 100644
--- a/lib/common_test/src/ct_netconfc.hrl
+++ b/lib/common_test/src/ct_netconfc.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/ct_property_test.erl b/lib/common_test/src/ct_property_test.erl
index 52acda5388..5ee7435695 100644
--- a/lib/common_test/src/ct_property_test.erl
+++ b/lib/common_test/src/ct_property_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/ct_release_test.erl b/lib/common_test/src/ct_release_test.erl
new file mode 100644
index 0000000000..5d7e945cc3
--- /dev/null
+++ b/lib/common_test/src/ct_release_test.erl
@@ -0,0 +1,950 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-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.
+%%
+%% %CopyrightEnd%
+%%
+%%-----------------------------------------------------------------
+%% @doc EXPERIMENTAL support for testing of upgrade.
+%%
+%% This is a library module containing support for test of release
+%% related activities in one or more applications. Currenty it
+%% supports upgrade only.
+%%
+%% == Configuration ==
+%%
+%% In order to find version numbers of applications to upgrade from,
+%% `{@module}' needs to access and start old OTP
+%% releases. A `common_test' configuration file can be used for
+%% specifying the location of such releases, for example:
+%%
+%% ```
+%% %% old-rels.cfg
+%% {otp_releases,[{r16b,"/path/to/R16B03-1/bin/erl"},
+%% {'17',"/path/to/17.3/bin/erl"}]}.'''
+%%
+%% The configuration file should preferably point out the latest patch
+%% level on each major release.
+%%
+%% If no such configuration file is given, {@link init/1} will return
+%% `{skip,Reason}' and any attempt at running {@link upgrade/4}
+%% will fail.
+%%
+%% == Callback functions ==
+%%
+%% The following functions should be exported from a {@module}
+%% callback module.
+%%
+%% All callback functions are called on the node where the upgrade is
+%% executed.
+%%
+%% <dl>
+%% <dt>Module:upgrade_init(CtData,State) -> NewState</dt>
+%% <dd>Types:
+%%
+%% <b><code>CtData = {@link ct_data()}</code></b><br/>
+%% <b><code>State = NewState = cb_state()</code></b>
+%%
+%% Initialyze system before upgrade test starts.
+%%
+%% This function is called before the upgrade is started. All
+%% applications given in {@link upgrade/4} are already started by
+%% the boot script, so this callback is intended for additional
+%% initialization, if necessary.
+%%
+%% <code>CtData</code> is an opaque data structure which shall be used
+%% in any call to <code>ct_release_test</code> inside the callback.
+%%
+%% Example:
+%%
+%% ```
+%% upgrade_init(CtData,State) ->
+%% {ok,{FromVsn,ToVsn}} = ct_release_test:get_app_vsns(CtData,myapp),
+%% open_connection(State).'''
+%% </dd>
+%%
+%% <dt>Module:upgrade_upgraded(CtData,State) -> NewState</dt>
+%% <dd>Types:
+%%
+%% <b><code>CtData = {@link ct_data()}</code></b><br/>
+%% <b><code>State = NewState = cb_state()</code></b>
+%%
+%% Check that upgrade was successful.
+%%
+%% This function is called after the release_handler has
+%% successfully unpacked and installed the new release, and it has
+%% been made permanent. It allows application specific checks to
+%% ensure that the upgrade was successful.
+%%
+%% <code>CtData</code> is an opaque data structure which shall be used
+%% in any call to <code>ct_release_test</code> inside the callback.
+%%
+%% Example:
+%%
+%% ```
+%% upgrade_upgraded(CtData,State) ->
+%% check_connection_still_open(State).'''
+%% </dd>
+%%
+%% <dt>Module:upgrade_downgraded(CtData,State) -> NewState</dt>
+%% <dd>Types:
+%%
+%% <b><code>CtData = {@link ct_data()}</code></b><br/>
+%% <b><code>State = NewState = cb_state()</code></b>
+%%
+%% Check that downgrade was successful.
+%%
+%% This function is called after the release_handler has
+%% successfully re-installed the original release, and it has been
+%% made permanent. It allows application specific checks to ensure
+%% that the downgrade was successful.
+%%
+%% <code>CtData</code> is an opaque data structure which shall be used
+%% in any call to <code>ct_release_test</code> inside the callback.
+%%
+%% Example:
+%%
+%% ```
+%% upgrade_downgraded(CtData,State) ->
+%% check_connection_closed(State).'''
+%% </dd>
+%% </dl>
+%% @end
+%%-----------------------------------------------------------------
+-module(ct_release_test).
+
+-export([init/1, upgrade/4, cleanup/1, get_app_vsns/2, get_appup/2]).
+
+-include_lib("kernel/include/file.hrl").
+
+%%-----------------------------------------------------------------
+-define(testnode, 'ct_release_test-upgrade').
+-define(exclude_apps, [hipe, typer, dialyzer]). % never include these apps
+
+%%-----------------------------------------------------------------
+-record(ct_data, {from,to}).
+
+%%-----------------------------------------------------------------
+-type config() :: [{atom(),term()}].
+-type cb_state() :: term().
+-opaque ct_data() :: #ct_data{}.
+-export_type([ct_data/0]).
+
+-callback upgrade_init(ct_data(),cb_state()) -> cb_state().
+-callback upgrade_upgraded(ct_data(),cb_state()) -> cb_state().
+-callback upgrade_downgraded(ct_data(),cb_state()) -> cb_state().
+
+%%-----------------------------------------------------------------
+-spec init(Config) -> Result when
+ Config :: config(),
+ Result :: config() | SkipOrFail,
+ SkipOrFail :: {skip,Reason} | {fail,Reason}.
+%% @doc Initialize `{@module}'.
+%%
+%% This function can be called from any of the
+%% `init_per_*' functions in the test suite. It updates
+%% the given `Config' with data that will be
+%% used by future calls to other functions in this module. The
+%% returned configuration must therefore also be returned from
+%% the calling `init_per_*'.
+%%
+%% If the initialization fails, e.g. if a required release can
+%% not be found, the function returns `{skip,Reason}'. In
+%% this case the other test support functions in this mudule
+%% can not be used.
+%%
+%% Example:
+%%
+%% ```
+%% init_per_suite(Config) ->
+%% ct_release_test:init(Config).'''
+%%
+init(Config) ->
+ try init_upgrade_test() of
+ {Major,Minor} ->
+ [{release_test,[{major,Major},{minor,Minor}]} | Config]
+ catch throw:Thrown ->
+ Thrown
+ end.
+
+%%-----------------------------------------------------------------
+-spec upgrade(App,Level,Callback,Config) -> any() when
+ App :: atom(),
+ Level :: minor | major,
+ Callback :: {module(),InitState},
+ InitState :: cb_state(),
+ Config :: config();
+ (Apps,Level,Callback,Config) -> any() when
+ Apps :: [App],
+ App :: atom(),
+ Level :: minor | major,
+ Callback :: {module(),InitState},
+ InitState :: cb_state(),
+ Config :: config().
+%% @doc Test upgrade of the given application(s).
+%%
+%% This function can be called from a test case. It requires that
+%% `Config' has been initialized by calling {@link
+%% init/1} prior to this, for example from `init_per_suite/1'.
+%%
+%% Upgrade tests are performed as follows:
+%%
+%% <ol>
+%% <li>Figure out which OTP release to test upgrade
+%% from. Start a node running that release and find the
+%% application versions on that node. Terminate the
+%% node.</li>
+%% <li>Figure out all dependencies for the applications under
+%% test.</li>
+%% <li>Create a release containing the core
+%% applications `kernel', `stdlib' and `sasl'
+%% in addition to the application(s) under test and all
+%% dependencies of these. The versions of the applications
+%% under test will be the ones found on the OTP release to
+%% upgrade from. The versions of all other applications will
+%% be those found on the current node, i.e. the common_test
+%% node. This is the "From"-release.</li>
+%% <li>Create another release containing the same
+%% applications as in the previous step, but with all
+%% application versions taken from the current node. This is
+%% the "To"-release.</li>
+%% <li>Install the "From"-release and start a new node
+%% running this release.</li>
+%% <li>Perform the upgrade test and allow customized
+%% control by using callbacks:
+%% <ol>
+%% <li>Callback: `upgrade_init/2'</li>
+%% <li>Unpack the new release</li>
+%% <li>Install the new release</li>
+%% <li>Callback: `upgrade_upgraded/2'</li>
+%% <li>Install the original release</li>
+%% <li>Callback: `upgrade_downgraded/2'</li>
+%% </ol>
+%% </li>
+%% </ol>
+%%
+%% `App' or `Apps'
+%% specifies the applications under test, i.e. the applications
+%% which shall be upgraded. All other applications that are
+%% included have the same releases in the "From"- and
+%% "To"-releases and will therefore not be upgraded.
+%%
+%% `Level' specifies which OTP release to
+%% pick the "From" versions from.
+%% <dl>
+%% <dt>major</dt>
+%% <dd>From verions are picked from the previous major
+%% release. For example, if the test is run on an OTP-17
+%% node, `{@module}' will pick the application
+%% "From" versions from an OTP installation running OTP
+%% R16B.</dd>
+%%
+%% <dt>minor</dt>
+%% <dd>From verions are picked from the current major
+%% release. For example, if the test is run on an OTP-17
+%% node, `{@module}' will pick the application
+%% "From" versions from an OTP installation running an
+%% earlier patch level of OTP-17.</dd>
+%% </dl>
+%%
+%% The application "To" versions are allways picked from the
+%% current node, i.e. the common_test node.
+%%
+%% `Callback' specifies the module (normally the
+%% test suite) which implements the {@section Callback functions}, and
+%% the initial value of the `State' variable used in these
+%% functions.
+%%
+%% `Config' is the input argument received
+%% in the test case function.
+%%
+%% Example:
+%%
+%% ```
+%% minor_upgrade(Config) ->
+%% ct_release_test:upgrade(ssl,minor,{?MODULE,[]},Config).
+%% '''
+%%
+upgrade(App,Level,Callback,Config) when is_atom(App) ->
+ upgrade([App],Level,Callback,Config);
+upgrade(Apps,Level,Callback,Config) ->
+ Dir = proplists:get_value(priv_dir,Config),
+ CreateDir = filename:join([Dir,Level,create]),
+ InstallDir = filename:join([Dir,Level,install]),
+ ok = filelib:ensure_dir(filename:join(CreateDir,"*")),
+ ok = filelib:ensure_dir(filename:join(InstallDir,"*")),
+ try upgrade(Apps,Level,Callback,CreateDir,InstallDir,Config) of
+ ok ->
+ %%rm_rf(CreateDir),
+ Tars = filelib:wildcard(filename:join(CreateDir,"*.tar.gz")),
+ _ = [file:delete(Tar) || Tar <- Tars],
+ rm_rf(InstallDir),
+ ok
+ catch throw:{fail,Reason} ->
+ ct:fail(Reason);
+ throw:{skip,Reason} ->
+ rm_rf(CreateDir),
+ rm_rf(InstallDir),
+ {skip,Reason}
+ after
+ %% Brutally kill all nodes that erroneously survived the test.
+ %% Note, we will not reach this if the test fails with a
+ %% timetrap timeout in the test suite! Thus we can have
+ %% hanging nodes...
+ Nodes = lists:filter(fun(Node) ->
+ case atom_to_list(Node) of
+ "ct_release_test-" ++_ -> true;
+ _ -> false
+ end
+ end,
+ nodes()),
+ [rpc:call(Node,erlang,halt,[]) || Node <- Nodes]
+ end.
+
+%%-----------------------------------------------------------------
+-spec cleanup(Config) -> Result when
+ Config :: config(),
+ Result :: config().
+%% @doc Clean up after tests.
+%%
+%% This function shall be called from the `end_per_*' function
+%% complementing the `init_per_*' function where {@link init/1}
+%% is called.
+%%
+%% It cleans up after the test, for example kills hanging
+%% nodes.
+%%
+%% Example:
+%%
+%% ```
+%% end_per_suite(Config) ->
+%% ct_release_test:cleanup(Config).'''
+%%
+cleanup(Config) ->
+ AllNodes = [node_name(?testnode)|nodes()],
+ Nodes = lists:filter(fun(Node) ->
+ case atom_to_list(Node) of
+ "ct_release_test-" ++_ -> true;
+ _ -> false
+ end
+ end,
+ AllNodes),
+ [rpc:call(Node,erlang,halt,[]) || Node <- Nodes],
+ Config.
+
+%%-----------------------------------------------------------------
+-spec get_app_vsns(CtData,App) -> {ok,{From,To}} | {error,Reason} when
+ CtData :: ct_data(),
+ App :: atom(),
+ From :: string(),
+ To :: string(),
+ Reason :: {app_not_found,App}.
+%% @doc Get versions involved in this upgrade for the given application.
+%%
+%% This function can be called from inside any of the callback
+%% functions. It returns the old (From) and new (To) versions involved
+%% in the upgrade/downgrade test for the given application.
+%%
+%% <code>CtData</code> must be the first argument received in the
+%% calling callback function - an opaque data structure set by
+%% <code>ct_release_tests</code>.
+get_app_vsns(#ct_data{from=FromApps,to=ToApps},App) ->
+ case {lists:keyfind(App,1,FromApps),lists:keyfind(App,1,ToApps)} of
+ {{App,FromVsn,_},{App,ToVsn,_}} ->
+ {ok,{FromVsn,ToVsn}};
+ _ ->
+ {error,{app_not_found,App}}
+ end.
+
+%%-----------------------------------------------------------------
+-spec get_appup(CtData,App) -> {ok,Appup} | {error,Reason} when
+ CtData :: ct_data(),
+ App :: atom(),
+ Appup :: {From,To,Up,Down},
+ From :: string(),
+ To :: string(),
+ Up :: [Instr],
+ Down :: [Instr],
+ Instr :: term(),
+ Reason :: {app_not_found,App} | {vsn_not_found,{App,From}}.
+%% @doc Get appup instructions for the given application.
+%%
+%% This function can be called from inside any of the callback
+%% functions. It reads the appup file for the given application and
+%% returns the instructions for upgrade and downgrade for the versions
+%% in the test.
+%%
+%% <code>CtData</code> must be the first argument received in the
+%% calling callback function - an opaque data structure set by
+%% <code>ct_release_tests</code>.
+%%
+%% See reference manual for appup files for types definitions for the
+%% instructions.
+get_appup(#ct_data{from=FromApps,to=ToApps},App) ->
+ case lists:keyfind(App,1,ToApps) of
+ {App,ToVsn,ToDir} ->
+ Appup = filename:join([ToDir, "ebin", atom_to_list(App)++".appup"]),
+ {ok, [{ToVsn, Ups, Downs}]} = file:consult(Appup),
+ {App,FromVsn,_} = lists:keyfind(App,1,FromApps),
+ case {systools_relup:appup_search_for_version(FromVsn,Ups),
+ systools_relup:appup_search_for_version(FromVsn,Downs)} of
+ {{ok,Up},{ok,Down}} ->
+ {ok,{FromVsn,ToVsn,Up,Down}};
+ _ ->
+ {error,{vsn_not_found,{App,FromVsn}}}
+ end;
+ false ->
+ {error,{app_not_found,App}}
+ end.
+
+%%-----------------------------------------------------------------
+init_upgrade_test() ->
+ %% Check that a real release is running, not e.g. cerl
+ ok = application:ensure_started(sasl),
+ case release_handler:which_releases() of
+ [{_,_,[],_}] ->
+ %% Fake release, no applications
+ throw({skip, "Need a real release running to create other releases"});
+ _ ->
+ Major = init_upgrade_test(major),
+ Minor = init_upgrade_test(minor),
+ {Major,Minor}
+ end.
+
+init_upgrade_test(Level) ->
+ {FromVsn,ToVsn} = get_rels(Level),
+ OldRel =
+ case test_server:is_release_available(FromVsn) of
+ true ->
+ {release,FromVsn};
+ false ->
+ case ct:get_config({otp_releases,list_to_atom(FromVsn)}) of
+ undefined ->
+ false;
+ Prog0 ->
+ case os:find_executable(Prog0) of
+ false ->
+ false;
+ Prog ->
+ {prog,Prog}
+ end
+ end
+ end,
+ case OldRel of
+ false ->
+ ct:log("Release ~p is not available."
+ " Upgrade on '~p' level can not be tested.",
+ [FromVsn,Level]),
+ undefined;
+ _ ->
+ init_upgrade_test(FromVsn,ToVsn,OldRel)
+ end.
+
+get_rels(major) ->
+ %% Given that the current major release is X, then this is an
+ %% upgrade from major release X-1 to the current release.
+ Current = erlang:system_info(otp_release),
+ PreviousMajor = previous_major(Current),
+ {PreviousMajor,Current};
+get_rels(minor) ->
+ %% Given that this is a (possibly) patched version of major
+ %% release X, then this is an upgrade from major release X to the
+ %% current release.
+ CurrentMajor = erlang:system_info(otp_release),
+ Current = CurrentMajor++"_patched",
+ {CurrentMajor,Current}.
+
+init_upgrade_test(FromVsn,ToVsn,OldRel) ->
+ Name = list_to_atom("ct_release_test-otp-"++FromVsn),
+ ct:log("Starting node to fetch application versions to upgrade from"),
+ {ok,Node} = test_server:start_node(Name,peer,[{erl,[OldRel]}]),
+ {Apps,Path} = fetch_all_apps(Node),
+ test_server:stop_node(Node),
+ {FromVsn,ToVsn,Apps,Path}.
+
+fetch_all_apps(Node) ->
+ Paths = rpc:call(Node,code,get_path,[]),
+ %% Find all possible applications in the path
+ AppFiles =
+ lists:flatmap(
+ fun(P) ->
+ filelib:wildcard(filename:join(P,"*.app"))
+ end,
+ Paths),
+ %% Figure out which version of each application is running on this
+ %% node. Using application:load and application:get_key instead of
+ %% reading the .app files since there might be multiple versions
+ %% of a .app file and we only want the one that is actually
+ %% running.
+ AppVsns =
+ lists:flatmap(
+ fun(F) ->
+ A = list_to_atom(filename:basename(filename:rootname(F))),
+ _ = rpc:call(Node,application,load,[A]),
+ case rpc:call(Node,application,get_key,[A,vsn]) of
+ {ok,V} -> [{A,V}];
+ _ -> []
+ end
+ end,
+ AppFiles),
+ ErtsVsn = rpc:call(Node, erlang, system_info, [version]),
+ {[{erts,ErtsVsn}|AppVsns], Paths}.
+
+
+%%-----------------------------------------------------------------
+upgrade(Apps,Level,Callback,CreateDir,InstallDir,Config) ->
+ ct:log("Test upgrade of the following applications: ~p",[Apps]),
+ ct:log(".rel files and start scripts are created in:~n~ts",[CreateDir]),
+ ct:log("The release is installed in:~n~ts",[InstallDir]),
+ case proplists:get_value(release_test,Config) of
+ undefined ->
+ throw({fail,"ct_release_test:init/1 not run"});
+ RTConfig ->
+ case proplists:get_value(Level,RTConfig) of
+ undefined ->
+ throw({skip,"Old release not available"});
+ Data ->
+ {FromVsn,FromRel,FromAppsVsns} =
+ target_system(Apps, CreateDir, InstallDir, Data),
+ {ToVsn,ToRel,ToAppsVsns} =
+ upgrade_system(Apps, FromRel, CreateDir,
+ InstallDir, Data),
+ ct:log("Upgrade from: OTP-~ts, ~p",[FromVsn, FromAppsVsns]),
+ ct:log("Upgrade to: OTP-~ts, ~p",[ToVsn, ToAppsVsns]),
+ do_upgrade(Callback, FromVsn, FromAppsVsns, ToRel,
+ ToAppsVsns, InstallDir)
+ end
+ end.
+
+%%% This is similar to sasl/examples/src/target_system.erl, but with
+%%% the following adjustments:
+%%% - add a log directory
+%%% - use an own 'start' script
+%%% - chmod 'start' and 'start_erl'
+target_system(Apps,CreateDir,InstallDir,{FromVsn,_,AllAppsVsns,Path}) ->
+ RelName0 = "otp-"++FromVsn,
+
+ AppsVsns = [{A,V} || {A,V} <- AllAppsVsns, lists:member(A,Apps)],
+ {RelName,ErtsVsn} = create_relfile(AppsVsns,CreateDir,RelName0,FromVsn),
+
+ %% Create .script and .boot
+ ok = systools(make_script,[RelName,[{path,Path}]]),
+
+ %% Create base tar file - i.e. erts and all apps
+ ok = systools(make_tar,[RelName,[{erts,code:root_dir()},
+ {path,Path}]]),
+
+ %% Unpack the tar to complete the installation
+ erl_tar:extract(RelName ++ ".tar.gz", [{cwd, InstallDir}, compressed]),
+
+ %% Add bin and log dirs
+ BinDir = filename:join([InstallDir, "bin"]),
+ file:make_dir(BinDir),
+ file:make_dir(filename:join(InstallDir,"log")),
+
+ %% Delete start scripts - they will be added later
+ ErtsBinDir = filename:join([InstallDir, "erts-" ++ ErtsVsn, "bin"]),
+ file:delete(filename:join([ErtsBinDir, "erl"])),
+ file:delete(filename:join([ErtsBinDir, "start"])),
+ file:delete(filename:join([ErtsBinDir, "start_erl"])),
+
+ %% Copy .boot to bin/start.boot
+ copy_file(RelName++".boot",filename:join([BinDir, "start.boot"])),
+
+ %% Copy scripts from erts-xxx/bin to bin
+ copy_file(filename:join([ErtsBinDir, "epmd"]),
+ filename:join([BinDir, "epmd"]), [preserve]),
+ copy_file(filename:join([ErtsBinDir, "run_erl"]),
+ filename:join([BinDir, "run_erl"]), [preserve]),
+ copy_file(filename:join([ErtsBinDir, "to_erl"]),
+ filename:join([BinDir, "to_erl"]), [preserve]),
+
+ %% create start_erl.data, sys.config and start.src
+ StartErlData = filename:join([InstallDir, "releases", "start_erl.data"]),
+ write_file(StartErlData, io_lib:fwrite("~s ~s~n", [ErtsVsn, FromVsn])),
+ SysConfig = filename:join([InstallDir, "releases", FromVsn, "sys.config"]),
+ write_file(SysConfig, "[]."),
+ StartSrc = filename:join(ErtsBinDir,"start.src"),
+ write_file(StartSrc,start_script()),
+ ok = file:change_mode(StartSrc,8#0755),
+
+ %% Make start_erl executable
+ %% (this has been fixed in OTP 17 - it is now installed with
+ %% $INSTALL_SCRIPT instead of $INSTALL_DATA and should therefore
+ %% be executable from the start)
+ ok = file:change_mode(filename:join(ErtsBinDir,"start_erl.src"),8#0755),
+
+ %% Substitute variables in erl.src, start.src and start_erl.src
+ %% (.src found in erts-xxx/bin - result stored in bin)
+ subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir,
+ [{"FINAL_ROOTDIR", InstallDir}, {"EMU", "beam"}],
+ [preserve]),
+
+ %% Create RELEASES
+ RelFile = filename:join([InstallDir, "releases",
+ filename:basename(RelName) ++ ".rel"]),
+ release_handler:create_RELEASES(InstallDir, RelFile),
+
+ {FromVsn, RelName,AppsVsns}.
+
+systools(Func,Args) ->
+ case apply(systools,Func,Args) of
+ ok ->
+ ok;
+ error ->
+ throw({fail,{systools,Func,Args}})
+ end.
+
+%%% This is a copy of $ROOT/erts-xxx/bin/start.src, modified to add
+%%% sname and heart
+start_script() ->
+ ["#!/bin/sh\n"
+ "ROOTDIR=%FINAL_ROOTDIR%\n"
+ "\n"
+ "if [ -z \"$RELDIR\" ]\n"
+ "then\n"
+ " RELDIR=$ROOTDIR/releases\n"
+ "fi\n"
+ "\n"
+ "START_ERL_DATA=${1:-$RELDIR/start_erl.data}\n"
+ "\n"
+ "$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -sname ",atom_to_list(?testnode)," -heart\"\n"].
+
+%%% Create a release containing the current (the test node) OTP
+%%% release, including relup to allow upgrade from an earlier OTP
+%%% release.
+upgrade_system(Apps, FromRel, CreateDir, InstallDir, {_,ToVsn,_,_}) ->
+ ct:log("Generating release to upgrade to."),
+
+ RelName0 = "otp-"++ToVsn,
+
+ AppsVsns = get_vsns(Apps),
+ {RelName,_} = create_relfile(AppsVsns,CreateDir,RelName0,ToVsn),
+ FromPath = filename:join([InstallDir,lib,"*",ebin]),
+
+ ok = systools(make_script,[RelName]),
+ ok = systools(make_relup,[RelName,[FromRel],[FromRel],
+ [{path,[FromPath]},
+ {outdir,CreateDir}]]),
+ SysConfig = filename:join([CreateDir, "sys.config"]),
+ write_file(SysConfig, "[]."),
+
+ ok = systools(make_tar,[RelName,[{erts,code:root_dir()}]]),
+
+ {ToVsn, RelName,AppsVsns}.
+
+%%% Start a new node running the release from target_system/6
+%%% above. Then upgrade to the system from upgrade_system/6.
+do_upgrade({Cb,InitState},FromVsn,FromAppsVsns,ToRel,ToAppsVsns,InstallDir) ->
+ ct:log("Upgrade test attempting to start node.~n"
+ "If test fails, logs can be found in:~n~ts",
+ [filename:join(InstallDir,log)]),
+ Start = filename:join([InstallDir,bin,start]),
+ {ok,Node} = start_node(Start,FromVsn,FromAppsVsns),
+
+ %% Add path to this module, to allow calls to get_appup/2
+ Dir = filename:dirname(code:which(?MODULE)),
+ _ = rpc:call(Node,code,add_pathz,[Dir]),
+
+ ct:log("Node started: ~p",[Node]),
+ CtData = #ct_data{from = [{A,V,code:lib_dir(A)} || {A,V} <- FromAppsVsns],
+ to=[{A,V,code:lib_dir(A)} || {A,V} <- ToAppsVsns]},
+ State1 = do_callback(Node,Cb,upgrade_init,[CtData,InitState]),
+
+ [{"OTP upgrade test",FromVsn,_,permanent}] =
+ rpc:call(Node,release_handler,which_releases,[]),
+ ToRelName = filename:basename(ToRel),
+ copy_file(ToRel++".tar.gz",
+ filename:join([InstallDir,releases,ToRelName++".tar.gz"])),
+ ct:log("Unpacking new release"),
+ {ok,ToVsn} = rpc:call(Node,release_handler,unpack_release,[ToRelName]),
+ [{"OTP upgrade test",ToVsn,_,unpacked},
+ {"OTP upgrade test",FromVsn,_,permanent}] =
+ rpc:call(Node,release_handler,which_releases,[]),
+ ct:log("Installing new release"),
+ case rpc:call(Node,release_handler,install_release,[ToVsn]) of
+ {ok,FromVsn,_} ->
+ ok;
+ {continue_after_restart,FromVsn,_} ->
+ ct:log("Waiting for node restart")
+ end,
+ %% even if install_release returned {ok,...} there might be an
+ %% emulator restart (instruction restart_emulator), so we must
+ %% always make sure the node is running.
+ wait_node_up(current,ToVsn,ToAppsVsns),
+
+ [{"OTP upgrade test",ToVsn,_,current},
+ {"OTP upgrade test",FromVsn,_,permanent}] =
+ rpc:call(Node,release_handler,which_releases,[]),
+ ct:log("Permanenting new release"),
+ ok = rpc:call(Node,release_handler,make_permanent,[ToVsn]),
+ [{"OTP upgrade test",ToVsn,_,permanent},
+ {"OTP upgrade test",FromVsn,_,old}] =
+ rpc:call(Node,release_handler,which_releases,[]),
+
+ State2 = do_callback(Node,Cb,upgrade_upgraded,[CtData,State1]),
+
+ ct:log("Re-installing old release"),
+ case rpc:call(Node,release_handler,install_release,[FromVsn]) of
+ {ok,FromVsn,_} ->
+ ok;
+ {continue_after_restart,FromVsn,_} ->
+ ct:log("Waiting for node restart")
+ end,
+ %% even if install_release returned {ok,...} there might be an
+ %% emulator restart (instruction restart_emulator), so we must
+ %% always make sure the node is running.
+ wait_node_up(current,FromVsn,FromAppsVsns),
+
+ [{"OTP upgrade test",ToVsn,_,permanent},
+ {"OTP upgrade test",FromVsn,_,current}] =
+ rpc:call(Node,release_handler,which_releases,[]),
+ ct:log("Permanenting old release"),
+ ok = rpc:call(Node,release_handler,make_permanent,[FromVsn]),
+ [{"OTP upgrade test",ToVsn,_,old},
+ {"OTP upgrade test",FromVsn,_,permanent}] =
+ rpc:call(Node,release_handler,which_releases,[]),
+
+ _State3 = do_callback(Node,Cb,upgrade_downgraded,[CtData,State2]),
+
+ ct:log("Terminating node ~p",[Node]),
+ erlang:monitor_node(Node,true),
+ _ = rpc:call(Node,init,stop,[]),
+ receive {nodedown,Node} -> ok end,
+ ct:log("Node terminated"),
+
+ ok.
+
+do_callback(Node,Mod,Func,Args) ->
+ Dir = filename:dirname(code:which(Mod)),
+ _ = rpc:call(Node,code,add_path,[Dir]),
+ ct:log("Calling ~p:~p/1",[Mod,Func]),
+ R = rpc:call(Node,Mod,Func,Args),
+ ct:log("~p:~p/~w returned: ~p",[Mod,Func,length(Args),R]),
+ case R of
+ {badrpc,Error} ->
+ throw({fail,{test_upgrade_callback,Mod,Func,Args,Error}});
+ NewState ->
+ NewState
+ end.
+
+%%% Library functions
+previous_major("17") ->
+ "r16b";
+previous_major(Rel) ->
+ integer_to_list(list_to_integer(Rel)-1).
+
+create_relfile(AppsVsns,CreateDir,RelName0,RelVsn) ->
+ UpgradeAppsVsns = [{A,V,restart_type(A)} || {A,V} <- AppsVsns],
+
+ CoreAppVsns0 = get_vsns([kernel,stdlib,sasl]),
+ CoreAppVsns =
+ [{A,V,restart_type(A)} || {A,V} <- CoreAppVsns0,
+ false == lists:keymember(A,1,AppsVsns)],
+
+ Apps = [App || {App,_} <- AppsVsns],
+ StartDepsVsns = get_start_deps(Apps,CoreAppVsns),
+ StartApps = [StartApp || {StartApp,_,_} <- StartDepsVsns] ++ Apps,
+
+ {RuntimeDepsVsns,_} = get_runtime_deps(StartApps,StartApps,[],[]),
+
+ AllAppsVsns0 = StartDepsVsns ++ UpgradeAppsVsns ++ RuntimeDepsVsns,
+
+ %% Should test tools really be included? Some library functions
+ %% here could be used by callback, but not everything since
+ %% processes of these applications will not be running.
+ TestToolAppsVsns0 = get_vsns([test_server,common_test]),
+ TestToolAppsVsns =
+ [{A,V,none} || {A,V} <- TestToolAppsVsns0,
+ false == lists:keymember(A,1,AllAppsVsns0)],
+
+ AllAppsVsns1 = AllAppsVsns0 ++ TestToolAppsVsns,
+ AllAppsVsns = [AV || AV={A,_,_} <- AllAppsVsns1,
+ false == lists:member(A,?exclude_apps)],
+
+ ErtsVsn = erlang:system_info(version),
+
+ %% Create the .rel file
+ RelContent = {release,{"OTP upgrade test",RelVsn},{erts,ErtsVsn},AllAppsVsns},
+ RelName = filename:join(CreateDir,RelName0),
+ RelFile = RelName++".rel",
+ {ok,Fd} = file:open(RelFile,[write,{encoding,utf8}]),
+ io:format(Fd,"~tp.~n",[RelContent]),
+ ok = file:close(Fd),
+ {RelName,ErtsVsn}.
+
+get_vsns(Apps) ->
+ [begin
+ _ = application:load(A),
+ {ok,V} = application:get_key(A,vsn),
+ {A,V}
+ end || A <- Apps].
+
+get_start_deps([App|Apps],Acc) ->
+ _ = application:load(App),
+ {ok,StartDeps} = application:get_key(App,applications),
+ StartDepsVsns =
+ [begin
+ _ = application:load(StartApp),
+ {ok,StartVsn} = application:get_key(StartApp,vsn),
+ {StartApp,StartVsn,restart_type(StartApp)}
+ end || StartApp <- StartDeps,
+ false == lists:keymember(StartApp,1,Acc)],
+ DepsStartDeps = get_start_deps(StartDeps,Acc ++ StartDepsVsns),
+ get_start_deps(Apps,DepsStartDeps);
+get_start_deps([],Acc) ->
+ Acc.
+
+get_runtime_deps([App|Apps],StartApps,Acc,Visited) ->
+ case lists:member(App,Visited) of
+ true ->
+ get_runtime_deps(Apps,StartApps,Acc,Visited);
+ false ->
+ %% runtime_dependencies should be possible to read with
+ %% application:get_key/2, but still isn't so we need to
+ %% read the .app file...
+ AppFile = code:where_is_file(atom_to_list(App) ++ ".app"),
+ {ok,[{application,App,Attrs}]} = file:consult(AppFile),
+ RuntimeDeps =
+ lists:flatmap(
+ fun(Str) ->
+ [RuntimeAppStr,_] = string:tokens(Str,"-"),
+ RuntimeApp = list_to_atom(RuntimeAppStr),
+ case {lists:keymember(RuntimeApp,1,Acc),
+ lists:member(RuntimeApp,StartApps)} of
+ {false,false} when RuntimeApp=/=erts ->
+ [RuntimeApp];
+ _ ->
+ []
+ end
+ end,
+ proplists:get_value(runtime_dependencies,Attrs,[])),
+ RuntimeDepsVsns =
+ [begin
+ _ = application:load(RuntimeApp),
+ {ok,RuntimeVsn} = application:get_key(RuntimeApp,vsn),
+ {RuntimeApp,RuntimeVsn,none}
+ end || RuntimeApp <- RuntimeDeps],
+ {DepsRuntimeDeps,NewVisited} =
+ get_runtime_deps(RuntimeDeps,StartApps,Acc++RuntimeDepsVsns,[App|Visited]),
+ get_runtime_deps(Apps,StartApps,DepsRuntimeDeps,NewVisited)
+ end;
+get_runtime_deps([],_,Acc,Visited) ->
+ {Acc,Visited}.
+
+restart_type(App) when App==kernel; App==stdlib; App==sasl ->
+ permanent;
+restart_type(_) ->
+ temporary.
+
+copy_file(Src, Dest) ->
+ copy_file(Src, Dest, []).
+
+copy_file(Src, Dest, Opts) ->
+ {ok,_} = file:copy(Src, Dest),
+ case lists:member(preserve, Opts) of
+ true ->
+ {ok, FileInfo} = file:read_file_info(Src),
+ file:write_file_info(Dest, FileInfo);
+ false ->
+ ok
+ end.
+
+write_file(FName, Conts) ->
+ Enc = file:native_name_encoding(),
+ {ok, Fd} = file:open(FName, [write]),
+ file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)),
+ file:close(Fd).
+
+%% Substitute all occurrences of %Var% for Val in the given scripts
+subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) ->
+ lists:foreach(fun(Script) ->
+ subst_src_script(Script, SrcDir, DestDir,
+ Vars, Opts)
+ end, Scripts).
+
+subst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->
+ subst_file(filename:join([SrcDir, Script ++ ".src"]),
+ filename:join([DestDir, Script]),
+ Vars, Opts).
+
+subst_file(Src, Dest, Vars, Opts) ->
+ {ok, Bin} = file:read_file(Src),
+ Conts = binary_to_list(Bin),
+ NConts = subst(Conts, Vars),
+ write_file(Dest, NConts),
+ case lists:member(preserve, Opts) of
+ true ->
+ {ok, FileInfo} = file:read_file_info(Src),
+ file:write_file_info(Dest, FileInfo);
+ false ->
+ ok
+ end.
+
+subst(Str, [{Var,Val}|Vars]) ->
+ subst(re:replace(Str,"%"++Var++"%",Val,[{return,list}]),Vars);
+subst(Str, []) ->
+ Str.
+
+%%% Start a node by executing the given start command. This node will
+%%% be used for upgrade.
+start_node(Start,ExpVsn,ExpAppsVsns) ->
+ Port = open_port({spawn_executable, Start}, []),
+ unlink(Port),
+ erlang:port_close(Port),
+ wait_node_up(permanent,ExpVsn,ExpAppsVsns).
+
+wait_node_up(ExpStatus,ExpVsn,ExpAppsVsns) ->
+ Node = node_name(?testnode),
+ wait_node_up(Node,ExpStatus,ExpVsn,lists:keysort(1,ExpAppsVsns),60).
+
+wait_node_up(Node,ExpStatus,ExpVsn,ExpAppsVsns,0) ->
+ test_server:fail({node_not_started,app_check_failed,ExpVsn,ExpAppsVsns,
+ rpc:call(Node,release_handler,which_releases,[ExpStatus]),
+ rpc:call(Node,application,which_applications,[])});
+wait_node_up(Node,ExpStatus,ExpVsn,ExpAppsVsns,N) ->
+ case {rpc:call(Node,release_handler,which_releases,[ExpStatus]),
+ rpc:call(Node, application, which_applications, [])} of
+ {[{_,ExpVsn,_,_}],Apps} when is_list(Apps) ->
+ case [{A,V} || {A,_,V} <- lists:keysort(1,Apps),
+ lists:keymember(A,1,ExpAppsVsns)] of
+ ExpAppsVsns ->
+ {ok,Node};
+ _ ->
+ timer:sleep(2000),
+ wait_node_up(Node,ExpStatus,ExpVsn,ExpAppsVsns,N-1)
+ end;
+ _ ->
+ timer:sleep(2000),
+ wait_node_up(Node,ExpStatus,ExpVsn,ExpAppsVsns,N-1)
+ end.
+
+node_name(Sname) ->
+ {ok,Host} = inet:gethostname(),
+ list_to_atom(atom_to_list(Sname) ++ "@" ++ Host).
+
+rm_rf(Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, #file_info{type = directory}} ->
+ {ok, Content} = file:list_dir_all(Dir),
+ [rm_rf(filename:join(Dir,C)) || C <- Content],
+ ok=file:del_dir(Dir),
+ ok;
+ {ok, #file_info{}} ->
+ ok=file:delete(Dir);
+ _ ->
+ ok
+ end.
diff --git a/lib/common_test/src/ct_repeat.erl b/lib/common_test/src/ct_repeat.erl
index f4d9949776..1cb32f5bcd 100644
--- a/lib/common_test/src/ct_repeat.erl
+++ b/lib/common_test/src/ct_repeat.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/src/ct_rpc.erl b/lib/common_test/src/ct_rpc.erl
index 03d95d1408..73520b3dd5 100644
--- a/lib/common_test/src/ct_rpc.erl
+++ b/lib/common_test/src/ct_rpc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index be547b443b..a0f9f47b41 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -64,6 +65,7 @@
logdir,
logopts = [],
basic_html,
+ esc_chars = true,
verbosity = [],
config = [],
event_handlers = [],
@@ -77,12 +79,13 @@
multiply_timetraps = 1,
scale_timetraps = false,
create_priv_dir,
- testspecs = [],
+ testspec_files = [],
+ current_testspec,
tests,
starter}).
%%%-----------------------------------------------------------------
-%%% @spec script_start() -> void()
+%%% @spec script_start() -> term()
%%%
%%% @doc Start tests via the ct_run program or script.
%%%
@@ -344,6 +347,15 @@ script_start1(Parent, Args) ->
application:set_env(common_test, basic_html, true),
true
end,
+ %% esc_chars - used by ct_logs
+ EscChars = case proplists:get_value(no_esc_chars, Args) of
+ undefined ->
+ application:set_env(common_test, esc_chars, true),
+ undefined;
+ _ ->
+ application:set_env(common_test, esc_chars, false),
+ false
+ end,
%% disable_log_cache - used by ct_logs
case proplists:get_value(disable_log_cache, Args) of
undefined ->
@@ -357,6 +369,7 @@ script_start1(Parent, Args) ->
cover = Cover, cover_stop = CoverStop,
logdir = LogDir, logopts = LogOpts,
basic_html = BasicHtml,
+ esc_chars = EscChars,
verbosity = Verbosity,
event_handlers = EvHandlers,
ct_hooks = CTHooks,
@@ -492,8 +505,11 @@ execute_one_spec(TS, Opts, Args) ->
case check_and_install_configfiles(AllConfig, TheLogDir, Opts) of
ok -> % read tests from spec
{Run,Skip} = ct_testspec:prepare_tests(TS, node()),
- do_run(Run, Skip, Opts#opts{config=AllConfig,
- logdir=TheLogDir}, Args);
+ Result = do_run(Run, Skip, Opts#opts{config=AllConfig,
+ logdir=TheLogDir,
+ current_testspec=TS}, Args),
+ ct_util:delete_testdata(testspec),
+ Result;
Error ->
Error
end.
@@ -582,14 +598,26 @@ combine_test_opts(TS, Specs, Opts) ->
BHBool
end,
+ EscChars =
+ case choose_val(Opts#opts.esc_chars,
+ TSOpts#opts.esc_chars) of
+ undefined ->
+ true;
+ ECBool ->
+ application:set_env(common_test, esc_chars,
+ ECBool),
+ ECBool
+ end,
+
Opts#opts{label = Label,
profile = Profile,
- testspecs = Specs,
+ testspec_files = Specs,
cover = Cover,
cover_stop = CoverStop,
logdir = which(logdir, LogDir),
logopts = AllLogOpts,
basic_html = BasicHtml,
+ esc_chars = EscChars,
verbosity = AllVerbosity,
silent_connections = AllSilentConns,
config = TSOpts#opts.config,
@@ -683,8 +711,10 @@ script_start3(Opts, Args) ->
if Opts#opts.vts ; Opts#opts.shell ->
script_start4(Opts#opts{tests = []}, Args);
true ->
- script_usage(),
- {error,missing_start_options}
+ %% no start options, use default "-dir ./"
+ {ok,Dir} = file:get_cwd(),
+ io:format("ct_run -dir ~ts~n~n", [Dir]),
+ script_start4(Opts#opts{tests = tests([Dir])}, Args)
end
end.
@@ -709,7 +739,7 @@ script_start4(#opts{label = Label, profile = Profile,
logopts = LogOpts,
verbosity = Verbosity,
enable_builtin_hooks = EnableBuiltinHooks,
- logdir = LogDir, testspecs = Specs}, _Args) ->
+ logdir = LogDir, testspec_files = Specs}, _Args) ->
%% label - used by ct_logs
application:set_env(common_test, test_label, Label),
@@ -763,82 +793,87 @@ script_start4(Opts = #opts{tests = Tests}, Args) ->
%%% @spec script_usage() -> ok
%%% @doc Print usage information for <code>ct_run</code>.
script_usage() ->
- io:format("\n\nUsage:\n\n"),
+ io:format("\nUsage:\n\n"),
io:format("Run tests from command line:\n\n"
- "\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |"
- "\n\t[[-dir TestDir] -suite Suite1 Suite2 .. SuiteN"
- "\n\t [[-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]]]"
- "\n\t[-step [config | keep_inactive]]"
- "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
- "\n\t[-userconfig CallbackModule ConfigFile1 .. ConfigFileN]"
- "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]"
- "\n\t[-logdir LogDir]"
- "\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]"
- "\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
- "\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]"
- "\n\t[-stylesheet CSSFile]"
- "\n\t[-cover CoverCfgFile]"
- "\n\t[-cover_stop Bool]"
- "\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]"
- "\n\t[-ct_hooks CTHook1 CTHook2 .. CTHookN]"
- "\n\t[-include InclDir1 InclDir2 .. InclDirN]"
- "\n\t[-no_auto_compile]"
- "\n\t[-abort_if_missing_suites]"
- "\n\t[-multiply_timetraps N]"
- "\n\t[-scale_timetraps]"
- "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
- "\n\t[-basic_html]"
- "\n\t[-repeat N] |"
- "\n\t[-duration HHMMSS [-force_stop [skip_rest]]] |"
- "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"),
+ "\tct_run -dir TestDir1 TestDir2 .. TestDirN |"
+ "\n\t [-dir TestDir] -suite Suite1 Suite2 .. SuiteN"
+ "\n\t [-group Group1 Group2 .. GroupN] [-case Case1 Case2 .. CaseN]"
+ "\n\t [-step [config | keep_inactive]]"
+ "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
+ "\n\t [-userconfig CallbackModule ConfigFile1 .. ConfigFileN]"
+ "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]"
+ "\n\t [-logdir LogDir]"
+ "\n\t [-logopts LogOpt1 LogOpt2 .. LogOptN]"
+ "\n\t [-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
+ "\n\t [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]"
+ "\n\t [-stylesheet CSSFile]"
+ "\n\t [-cover CoverCfgFile]"
+ "\n\t [-cover_stop Bool]"
+ "\n\t [-event_handler EvHandler1 EvHandler2 .. EvHandlerN]"
+ "\n\t [-ct_hooks CTHook1 CTHook2 .. CTHookN]"
+ "\n\t [-include InclDir1 InclDir2 .. InclDirN]"
+ "\n\t [-no_auto_compile]"
+ "\n\t [-abort_if_missing_suites]"
+ "\n\t [-multiply_timetraps N]"
+ "\n\t [-scale_timetraps]"
+ "\n\t [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
+ "\n\t [-basic_html]"
+ "\n\t [-no_esc_chars]"
+ "\n\t [-repeat N] |"
+ "\n\t [-duration HHMMSS [-force_stop [skip_rest]]] |"
+ "\n\t [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]"
+ "\n\t [-exit_status ignore_config]"
+ "\n\t [-help]\n\n"),
io:format("Run tests using test specification:\n\n"
"\tct_run -spec TestSpec1 TestSpec2 .. TestSpecN"
- "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
- "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]"
- "\n\t[-logdir LogDir]"
- "\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]"
- "\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
- "\n\t[-allow_user_terms]"
- "\n\t[-join_specs]"
- "\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]"
- "\n\t[-stylesheet CSSFile]"
- "\n\t[-cover CoverCfgFile]"
- "\n\t[-cover_stop Bool]"
- "\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]"
- "\n\t[-ct_hooks CTHook1 CTHook2 .. CTHookN]"
- "\n\t[-include InclDir1 InclDir2 .. InclDirN]"
- "\n\t[-no_auto_compile]"
- "\n\t[-abort_if_missing_suites]"
- "\n\t[-multiply_timetraps N]"
- "\n\t[-scale_timetraps]"
- "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
- "\n\t[-basic_html]"
- "\n\t[-repeat N] |"
- "\n\t[-duration HHMMSS [-force_stop [skip_rest]]] |"
- "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"),
+ "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
+ "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]"
+ "\n\t [-logdir LogDir]"
+ "\n\t [-logopts LogOpt1 LogOpt2 .. LogOptN]"
+ "\n\t [-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
+ "\n\t [-allow_user_terms]"
+ "\n\t [-join_specs]"
+ "\n\t [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]"
+ "\n\t [-stylesheet CSSFile]"
+ "\n\t [-cover CoverCfgFile]"
+ "\n\t [-cover_stop Bool]"
+ "\n\t [-event_handler EvHandler1 EvHandler2 .. EvHandlerN]"
+ "\n\t [-ct_hooks CTHook1 CTHook2 .. CTHookN]"
+ "\n\t [-include InclDir1 InclDir2 .. InclDirN]"
+ "\n\t [-no_auto_compile]"
+ "\n\t [-abort_if_missing_suites]"
+ "\n\t [-multiply_timetraps N]"
+ "\n\t [-scale_timetraps]"
+ "\n\t [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
+ "\n\t [-basic_html]"
+ "\n\t [-no_esc_chars]"
+ "\n\t [-repeat N] |"
+ "\n\t [-duration HHMMSS [-force_stop [skip_rest]]] |"
+ "\n\t [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"),
io:format("Refresh the HTML index files:\n\n"
"\tct_run -refresh_logs [LogDir]"
- "[-logdir LogDir] "
- "[-basic_html]\n\n"),
+ " [-logdir LogDir] "
+ " [-basic_html]\n\n"),
io:format("Run CT in interactive mode:\n\n"
"\tct_run -shell"
- "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
- "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]\n\n"),
+ "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
+ "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]\n\n"),
io:format("Run tests in web based GUI:\n\n"
"\tct_run -vts [-browser Browser]"
- "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
- "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]"
- "\n\t[-dir TestDir1 TestDir2 .. TestDirN] |"
- "\n\t[-suite Suite [-case Case]]"
- "\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]"
- "\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
- "\n\t[-include InclDir1 InclDir2 .. InclDirN]"
- "\n\t[-no_auto_compile]"
- "\n\t[-abort_if_missing_suites]"
- "\n\t[-multiply_timetraps N]"
- "\n\t[-scale_timetraps]"
- "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
- "\n\t[-basic_html]\n\n").
+ "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
+ "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]"
+ "\n\t [-dir TestDir1 TestDir2 .. TestDirN] |"
+ "\n\t [-suite Suite [-case Case]]"
+ "\n\t [-logopts LogOpt1 LogOpt2 .. LogOptN]"
+ "\n\t [-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
+ "\n\t [-include InclDir1 InclDir2 .. InclDirN]"
+ "\n\t [-no_auto_compile]"
+ "\n\t [-abort_if_missing_suites]"
+ "\n\t [-multiply_timetraps N]"
+ "\n\t [-scale_timetraps]"
+ "\n\t [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
+ "\n\t [-basic_html]"
+ "\n\t [-no_esc_chars]\n\n").
%%%-----------------------------------------------------------------
%%% @hidden
@@ -900,7 +935,7 @@ run_test(StartOpt) when is_tuple(StartOpt) ->
run_test([StartOpt]);
run_test(StartOpts) when is_list(StartOpts) ->
- CTPid = spawn(fun() -> run_test1(StartOpts) end),
+ CTPid = spawn(run_test1_fun(StartOpts)),
Ref = monitor(process, CTPid),
receive
{'DOWN',Ref,process,CTPid,{user_error,Error}} ->
@@ -909,6 +944,11 @@ run_test(StartOpts) when is_list(StartOpts) ->
Other
end.
+-spec run_test1_fun(_) -> fun(() -> no_return()).
+
+run_test1_fun(StartOpts) ->
+ fun() -> run_test1(StartOpts) end.
+
run_test1(StartOpts) when is_list(StartOpts) ->
case proplists:get_value(refresh_logs, StartOpts) of
undefined ->
@@ -1075,7 +1115,17 @@ run_test2(StartOpts) ->
application:set_env(common_test, basic_html, BasicHtmlBool),
BasicHtmlBool
end,
-
+ %% esc_chars - used by ct_logs
+ EscChars =
+ case proplists:get_value(esc_chars, StartOpts) of
+ undefined ->
+ application:set_env(common_test, esc_chars, true),
+ undefined;
+ EscCharsBool ->
+ application:set_env(common_test, esc_chars, EscCharsBool),
+ EscCharsBool
+ end,
+ %% disable_log_cache - used by ct_logs
case proplists:get_value(disable_log_cache, StartOpts) of
undefined ->
application:set_env(common_test, disable_log_cache, false);
@@ -1090,6 +1140,7 @@ run_test2(StartOpts) ->
cover = Cover, cover_stop = CoverStop,
step = Step, logdir = LogDir,
logopts = LogOpts, basic_html = BasicHtml,
+ esc_chars = EscChars,
config = CfgFiles,
verbosity = Verbosity,
event_handlers = EvHandlers,
@@ -1110,7 +1161,7 @@ run_test2(StartOpts) ->
undefined ->
case lists:keysearch(prepared_tests, 1, StartOpts) of
{value,{_,{Run,Skip},Specs}} -> % use prepared tests
- run_prepared(Run, Skip, Opts#opts{testspecs = Specs},
+ run_prepared(Run, Skip, Opts#opts{testspec_files = Specs},
StartOpts);
false ->
run_dir(Opts, StartOpts)
@@ -1118,11 +1169,11 @@ run_test2(StartOpts) ->
Specs ->
Relaxed = get_start_opt(allow_user_terms, value, false, StartOpts),
%% using testspec(s) as input for test
- run_spec_file(Relaxed, Opts#opts{testspecs = Specs}, StartOpts)
+ run_spec_file(Relaxed, Opts#opts{testspec_files = Specs}, StartOpts)
end.
run_spec_file(Relaxed,
- Opts = #opts{testspecs = Specs},
+ Opts = #opts{testspec_files = Specs},
StartOpts) ->
Specs1 = case Specs of
[X|_] when is_integer(X) -> [Specs];
@@ -1161,7 +1212,10 @@ run_all_specs([{Specs,TS} | TSs], Opts, StartOpts, TotResult) ->
log_ts_names(Specs),
Combined = #opts{config = TSConfig} = combine_test_opts(TS, Specs, Opts),
AllConfig = merge_vals([Opts#opts.config, TSConfig]),
- try run_one_spec(TS, Combined#opts{config = AllConfig}, StartOpts) of
+ try run_one_spec(TS,
+ Combined#opts{config = AllConfig,
+ current_testspec=TS},
+ StartOpts) of
Result ->
run_all_specs(TSs, Opts, StartOpts, [Result | TotResult])
catch
@@ -1340,7 +1394,9 @@ run_dir(Opts = #opts{logdir = LogDir,
end;
{undefined,undefined,[]} ->
- exit({error,no_test_specified});
+ {ok,Dir} = file:get_cwd(),
+ %% No start options, use default {dir,CWD}
+ reformat_result(catch do_run(tests(Dir), [], Opts1, StartOpts));
{Dir,Suite,GsAndCs} ->
exit({error,{incorrect_start_options,{Dir,Suite,GsAndCs}}})
@@ -1355,7 +1411,7 @@ run_dir(Opts = #opts{logdir = LogDir,
%%% @equiv ct:run_testspec/1
%%%-----------------------------------------------------------------
run_testspec(TestSpec) ->
- CTPid = spawn(fun() -> run_testspec1(TestSpec) end),
+ CTPid = spawn(run_testspec1_fun(TestSpec)),
Ref = monitor(process, CTPid),
receive
{'DOWN',Ref,process,CTPid,{user_error,Error}} ->
@@ -1364,6 +1420,11 @@ run_testspec(TestSpec) ->
Other
end.
+-spec run_testspec1_fun(_) -> fun(() -> no_return()).
+
+run_testspec1_fun(TestSpec) ->
+ fun() -> run_testspec1(TestSpec) end.
+
run_testspec1(TestSpec) ->
{ok,Cwd} = file:get_cwd(),
io:format("~nCommon Test starting (cwd is ~ts)~n~n", [Cwd]),
@@ -1406,7 +1467,7 @@ run_testspec2(TestSpec) ->
case check_and_install_configfiles(
Opts#opts.config, LogDir1, Opts) of
ok ->
- Opts1 = Opts#opts{testspecs = [],
+ Opts1 = Opts#opts{testspec_files = [],
logdir = LogDir1,
include = AllInclude},
{Run,Skip} = ct_testspec:prepare_tests(TS, node()),
@@ -1421,6 +1482,7 @@ get_data_for_node(#testspec{label = Labels,
logdir = LogDirs,
logopts = LogOptsList,
basic_html = BHs,
+ esc_chars = EscChs,
stylesheet = SSs,
verbosity = VLvls,
silent_connections = SilentConnsList,
@@ -1448,6 +1510,7 @@ get_data_for_node(#testspec{label = Labels,
LOs -> LOs
end,
BasicHtml = proplists:get_value(Node, BHs),
+ EscChars = proplists:get_value(Node, EscChs),
Stylesheet = proplists:get_value(Node, SSs),
Verbosity = case proplists:get_value(Node, VLvls) of
undefined -> [];
@@ -1474,6 +1537,7 @@ get_data_for_node(#testspec{label = Labels,
logdir = LogDir,
logopts = LogOpts,
basic_html = BasicHtml,
+ esc_chars = EscChars,
stylesheet = Stylesheet,
verbosity = Verbosity,
silent_connections = SilentConns,
@@ -1627,11 +1691,15 @@ groups_and_cases(Gs, Cs) ->
tests(TestDir, Suites, []) when is_list(TestDir), is_integer(hd(TestDir)) ->
[{?testdir(TestDir,Suites),ensure_atom(Suites),all}];
tests(TestDir, Suite, Cases) when is_list(TestDir), is_integer(hd(TestDir)) ->
+ [{?testdir(TestDir,Suite),ensure_atom(Suite),Cases}];
+tests([TestDir], Suite, Cases) when is_list(TestDir), is_integer(hd(TestDir)) ->
[{?testdir(TestDir,Suite),ensure_atom(Suite),Cases}].
tests([{Dir,Suite}],Cases) ->
[{?testdir(Dir,Suite),ensure_atom(Suite),Cases}];
tests(TestDir, Suite) when is_list(TestDir), is_integer(hd(TestDir)) ->
- tests(TestDir, ensure_atom(Suite), all).
+ tests(TestDir, ensure_atom(Suite), all);
+tests([TestDir], Suite) when is_list(TestDir), is_integer(hd(TestDir)) ->
+ tests(TestDir, ensure_atom(Suite), all).
tests(DirSuites) when is_list(DirSuites), is_tuple(hd(DirSuites)) ->
[{?testdir(Dir,Suite),ensure_atom(Suite),all} || {Dir,Suite} <- DirSuites];
tests(TestDir) when is_list(TestDir), is_integer(hd(TestDir)) ->
@@ -1713,6 +1781,9 @@ compile_and_run(Tests, Skip, Opts, Args) ->
ct_util:set_testdata({stylesheet,Opts#opts.stylesheet}),
%% save logopts
ct_util:set_testdata({logopts,Opts#opts.logopts}),
+ %% save info about current testspec (testspec record or undefined)
+ ct_util:set_testdata({testspec,Opts#opts.current_testspec}),
+
%% enable silent connections
case Opts#opts.silent_connections of
[] ->
@@ -1727,7 +1798,7 @@ compile_and_run(Tests, Skip, Opts, Args) ->
ct_logs:log("Silent connections", "~p", [Conns])
end
end,
- log_ts_names(Opts#opts.testspecs),
+ log_ts_names(Opts#opts.testspec_files),
TestSuites = suite_tuples(Tests),
{_TestSuites1,SuiteMakeErrors,AllMakeErrors} =
@@ -1750,7 +1821,18 @@ compile_and_run(Tests, Skip, Opts, Args) ->
{Tests1,Skip1} ->
ReleaseSh = proplists:get_value(release_shell, Args),
ct_util:set_testdata({release_shell,ReleaseSh}),
- possibly_spawn(ReleaseSh == true, Tests1, Skip1, Opts)
+ TestResult =
+ possibly_spawn(ReleaseSh == true, Tests1, Skip1, Opts),
+ case TestResult of
+ {Ok,Errors,Skipped} ->
+ NoOfMakeErrors =
+ lists:foldl(fun({_,BadMods}, X) ->
+ X + length(BadMods)
+ end, 0, SuiteMakeErrors),
+ {Ok,Errors+NoOfMakeErrors,Skipped};
+ ErrorResult ->
+ ErrorResult
+ end
catch
_:BadFormat ->
{error,BadFormat}
@@ -1976,22 +2058,7 @@ final_tests(Tests, Skip, Bad) ->
final_tests1([{TestDir,Suites,_}|Tests], Final, Skip, Bad) when
is_list(Suites), is_atom(hd(Suites)) ->
-% Separate =
-% fun(S,{DoSuite,Dont}) ->
-% case lists:keymember({TestDir,S},1,Bad) of
-% false ->
-% {[S|DoSuite],Dont};
-% true ->
-% SkipIt = {TestDir,S,"Make failed"},
-% {DoSuite,Dont++[SkipIt]}
-% end
-% end,
-
-% {DoSuites,Skip1} =
-% lists:foldl(Separate,{[],Skip},Suites),
-% Do = {TestDir,lists:reverse(DoSuites),all},
-
- Skip1 = [{TD,S,"Make failed"} || {{TD,S},_} <- Bad, S1 <- Suites,
+ Skip1 = [{TD,S,make_failed} || {{TD,S},_} <- Bad, S1 <- Suites,
S == S1, TD == TestDir],
Final1 = [{TestDir,S,all} || S <- Suites],
final_tests1(Tests, lists:reverse(Final1)++Final, Skip++Skip1, Bad);
@@ -2004,7 +2071,7 @@ final_tests1([{TestDir,all,all}|Tests], Final, Skip, Bad) ->
false ->
[]
end,
- Missing = [{TestDir,S,"Make failed"} || S <- MissingSuites],
+ Missing = [{TestDir,S,make_failed} || S <- MissingSuites],
Final1 = [{TestDir,all,all}|Final],
final_tests1(Tests, Final1, Skip++Missing, Bad);
@@ -2016,7 +2083,7 @@ final_tests1([{TestDir,Suite,GrsOrCs}|Tests], Final, Skip, Bad) when
is_list(GrsOrCs) ->
case lists:keymember({TestDir,Suite}, 1, Bad) of
true ->
- Skip1 = Skip ++ [{TestDir,Suite,all,"Make failed"}],
+ Skip1 = Skip ++ [{TestDir,Suite,all,make_failed}],
final_tests1(Tests, [{TestDir,Suite,all}|Final], Skip1, Bad);
false ->
GrsOrCs1 =
@@ -2028,6 +2095,13 @@ final_tests1([{TestDir,Suite,GrsOrCs}|Tests], Final, Skip, Bad) when
({skipped,Group,TCs}) ->
[ct_groups:make_conf(TestDir, Suite,
Group, [skipped], TCs)];
+ ({skipped,TC}) ->
+ case lists:member(TC, GrsOrCs) of
+ true ->
+ [];
+ false ->
+ [TC]
+ end;
({GrSpec = {GroupName,_},TCs}) ->
Props = [{override,GrSpec}],
[ct_groups:make_conf(TestDir, Suite,
@@ -2067,7 +2141,9 @@ final_skip([], Final) ->
continue([], _) ->
true;
-continue(_MakeErrors, AbortIfMissingSuites) ->
+continue(_MakeErrors, true) ->
+ false;
+continue(_MakeErrors, _AbortIfMissingSuites) ->
io:nl(),
OldGl = group_leader(),
case set_group_leader_same_as_shell() of
@@ -2095,11 +2171,10 @@ continue(_MakeErrors, AbortIfMissingSuites) ->
true
end;
false -> % no shell process to use
- not AbortIfMissingSuites
+ true
end.
set_group_leader_same_as_shell() ->
- %%! Locate the shell process... UGLY!!!
GS2or3 = fun(P) ->
case process_info(P,initial_call) of
{initial_call,{group,server,X}} when X == 2 ; X == 3 ->
@@ -2147,10 +2222,18 @@ do_run_test(Tests, Skip, Opts0) ->
%% test_server needs to know the include path too
InclPath = case application:get_env(common_test, include) of
{ok,Incls} -> Incls;
- _ -> []
+ _ -> []
end,
application:set_env(test_server, include, InclPath),
+ %% copy the escape characters setting to test_server
+ EscChars =
+ case application:get_env(common_test, esc_chars) of
+ {ok,ECBool} -> ECBool;
+ _ -> true
+ end,
+ application:set_env(test_server, esc_chars, EscChars),
+
test_server_ctrl:start_link(local),
%% let test_server expand the test tuples and count no of cases
@@ -3036,6 +3119,10 @@ opts2args(EnvStartOpts) ->
[{basic_html,[]}];
({basic_html,false}) ->
[];
+ ({esc_chars,false}) ->
+ [{no_esc_chars,[]}];
+ ({esc_chars,true}) ->
+ [];
({event_handler,EH}) when is_atom(EH) ->
[{event_handler,[atom_to_list(EH)]}];
({event_handler,EHs}) when is_list(EHs) ->
diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl
index 872c39de04..3ad3937548 100644
--- a/lib/common_test/src/ct_slave.erl
+++ b/lib/common_test/src/ct_slave.erl
@@ -1,18 +1,19 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -37,7 +38,7 @@
-record(options, {username, password, boot_timeout, init_timeout,
startup_timeout, startup_functions, monitor_master,
- kill_if_fail, erl_flags, env}).
+ kill_if_fail, erl_flags, env, ssh_port, ssh_opts}).
%%%-----------------------------------------------------------------
%%% @spec start(Node) -> Result
@@ -133,7 +134,7 @@ start(Host, Node) ->
%%% executed after startup of the node. Note that all used modules should be
%%% present in the code path on the <code>Host</code>.</p>
%%%
-%%% <p>The timeouts are applied as follows:
+%%% <p>The timeouts are applied as follows:</p>
%%% <list>
%%% <item>
%%% <code>BootTimeout</code> - time to start the Erlang node, in seconds.
@@ -153,7 +154,7 @@ start(Host, Node) ->
%%% If this timeout occurs, the result
%%% <code>{error, startup_timeout, NodeName}</code> is returned.
%%% </item>
-%%% </list></p>
+%%% </list>
%%%
%%% <p>Option <code>monitor_master</code> specifies, if the slave node should be
%%% stopped in case of master node stop. Defaults to false.</p>
@@ -169,7 +170,7 @@ start(Host, Node) ->
%%% <p>Option <code>env</code> specifies a list of environment variables
%%% that will extended the environment.</p>
%%%
-%%% <p>Special return values are:
+%%% <p>Special return values are:</p>
%%% <list>
%%% <item><code>{error, already_started, NodeName}</code> - if the node with
%%% the given name is already started on a given host;</item>
@@ -178,7 +179,7 @@ start(Host, Node) ->
%%% <item><code>{error, not_alive, NodeName}</code> - if node on which the
%%% <code>ct_slave:start/3</code> is called, is not alive. Note that
%%% <code>NodeName</code> is the name of current node in this case.</item>
-%%% </list></p>
+%%% </list>
%%%
start(Host, Node, Opts) ->
ENode = enodename(Host, Node),
@@ -254,11 +255,13 @@ fetch_options(Options) ->
KillIfFail = get_option_value(kill_if_fail, Options, true),
ErlFlags = get_option_value(erl_flags, Options, []),
EnvVars = get_option_value(env, Options, []),
+ SSHPort = get_option_value(ssh_port, Options, []),
+ SSHOpts = get_option_value(ssh_opts, Options, []),
#options{username=UserName, password=Password,
boot_timeout=BootTimeout, init_timeout=InitTimeout,
startup_timeout=StartupTimeout, startup_functions=StartupFunctions,
monitor_master=Monitor, kill_if_fail=KillIfFail,
- erl_flags=ErlFlags, env=EnvVars}.
+ erl_flags=ErlFlags, env=EnvVars, ssh_port=SSHPort, ssh_opts=SSHOpts}.
% send a message when slave node is started
% @hidden
@@ -312,7 +315,7 @@ enodename(Host, Node) ->
do_start(Host, Node, Options) ->
ENode = enodename(Host, Node),
Functions =
- lists:concat([[{ct_slave, slave_started, [ENode, self()]}],
+ lists:append([[{ct_slave, slave_started, [ENode, self()]}],
Options#options.startup_functions,
[{ct_slave, slave_ready, [ENode, self()]}]]),
Functions2 = if
@@ -399,27 +402,18 @@ spawn_local_node(Node, Options) ->
Cmd = get_cmd(Node, ErlFlags),
open_port({spawn, Cmd}, [stream,{env,Env}]).
-% start crypto and ssh if not yet started
-check_for_ssh_running() ->
- case application:get_application(crypto) of
- undefined->
- application:start(crypto),
- case application:get_application(ssh) of
- undefined->
- application:start(ssh);
- {ok, ssh}->
- ok
- end;
- {ok, crypto}->
- ok
- end.
-
% spawn node remotely
spawn_remote_node(Host, Node, Options) ->
#options{username=Username,
password=Password,
erl_flags=ErlFlags,
- env=Env} = Options,
+ env=Env,
+ ssh_port=MaybeSSHPort,
+ ssh_opts=SSHOpts} = Options,
+ SSHPort = case MaybeSSHPort of
+ [] -> 22; % Use default SSH port
+ A -> A
+ end,
SSHOptions = case {Username, Password} of
{[], []}->
[];
@@ -427,14 +421,13 @@ spawn_remote_node(Host, Node, Options) ->
[{user, Username}];
{_, _}->
[{user, Username}, {password, Password}]
- end ++ [{silently_accept_hosts, true}],
- check_for_ssh_running(),
- {ok, SSHConnRef} = ssh:connect(atom_to_list(Host), 22, SSHOptions),
+ end ++ [{silently_accept_hosts, true}] ++ SSHOpts,
+ application:ensure_all_started(ssh),
+ {ok, SSHConnRef} = ssh:connect(atom_to_list(Host), SSHPort, SSHOptions),
{ok, SSHChannelId} = ssh_connection:session_channel(SSHConnRef, infinity),
ssh_setenv(SSHConnRef, SSHChannelId, Env),
ssh_connection:exec(SSHConnRef, SSHChannelId, get_cmd(Node, ErlFlags), infinity).
-
ssh_setenv(SSHConnRef, SSHChannelId, [{Var, Value} | Vars])
when is_list(Var), is_list(Value) ->
success = ssh_connection:setenv(SSHConnRef, SSHChannelId,
diff --git a/lib/common_test/src/ct_snmp.erl b/lib/common_test/src/ct_snmp.erl
index 71038bd4f4..bb0167eb22 100644
--- a/lib/common_test/src/ct_snmp.erl
+++ b/lib/common_test/src/ct_snmp.erl
@@ -1,25 +1,26 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
%%% @doc Common Test user interface module for the OTP snmp application
%%%
-%%% The purpose of this module is to make snmp configuration easier for
+%%% <p>The purpose of this module is to make snmp configuration easier for
%%% the test case writer. Many test cases can use default values for common
%%% operations and then no snmp configuration files need to be supplied. When
%%% it is necessary to change particular configuration parameters, a subset
@@ -30,7 +31,7 @@
%%% To simplify the test suite, Common Test keeps track
%%% of some of the snmp manager information. This way the test suite doesn't
%%% have to handle as many input parameters as it would if it had to interface the
-%%% OTP snmp manager directly.
+%%% OTP snmp manager directly.</p>
%%%
%%% <p> The following snmp manager and agent parameters are configurable: </p>
%%%
@@ -325,9 +326,9 @@ set_info(Config) ->
%%% @doc Register the manager entity (=user) responsible for specific agent(s).
%%% Corresponds to making an entry in users.conf.
%%%
-%%% This function will try to register the given users, without
+%%% <p>This function will try to register the given users, without
%%% checking if any of them already exist. In order to change an
-%%% already registered user, the user must first be unregistered.
+%%% already registered user, the user must first be unregistered.</p>
register_users(MgrAgentConfName, Users) ->
case setup_users(Users) of
ok ->
@@ -350,10 +351,10 @@ register_users(MgrAgentConfName, Users) ->
%%% @doc Explicitly instruct the manager to handle this agent.
%%% Corresponds to making an entry in agents.conf
%%%
-%%% This function will try to register the given managed agents,
+%%% <p>This function will try to register the given managed agents,
%%% without checking if any of them already exist. In order to change
%%% an already registered managed agent, the agent must first be
-%%% unregistered.
+%%% unregistered.</p>
register_agents(MgrAgentConfName, ManagedAgents) ->
case setup_managed_agents(MgrAgentConfName,ManagedAgents) of
ok ->
@@ -377,9 +378,9 @@ register_agents(MgrAgentConfName, ManagedAgents) ->
%%% @doc Explicitly instruct the manager to handle this USM user.
%%% Corresponds to making an entry in usm.conf
%%%
-%%% This function will try to register the given users, without
+%%% <p>This function will try to register the given users, without
%%% checking if any of them already exist. In order to change an
-%%% already registered user, the user must first be unregistered.
+%%% already registered user, the user must first be unregistered.</p>
register_usm_users(MgrAgentConfName, UsmUsers) ->
EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID),
case setup_usm_users(UsmUsers, EngineID) of
diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl
index 974791bd70..d19004fa2c 100644
--- a/lib/common_test/src/ct_ssh.erl
+++ b/lib/common_test/src/ct_ssh.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl
index 844f53731e..f5f4f648f4 100644
--- a/lib/common_test/src/ct_telnet.erl
+++ b/lib/common_test/src/ct_telnet.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,7 @@
%% Command timeout = 10 sec (time to wait for a command to return)
%% Max no of reconnection attempts = 3
%% Reconnection interval = 5 sek (time to wait in between reconnection attempts)
-%% Keep alive = true (will send NOP to the server every 10 sec if connection is idle)
+%% Keep alive = true (will send NOP to the server every 8 sec if connection is idle)
%% Polling limit = 0 (max number of times to poll to get a remaining string terminated)
%% Polling interval = 1 sec (sleep time between polls)</pre>
%% <p>These parameters can be altered by the user with the following
@@ -41,7 +42,8 @@
%% {reconnection_interval,Millisec},
%% {keep_alive,Bool},
%% {poll_limit,N},
-%% {poll_interval,Millisec}]}.</pre>
+%% {poll_interval,Millisec},
+%% {tcp_nodelay,Bool}]}.</pre>
%% <p><code>Millisec = integer(), N = integer()</code></p>
%% <p>Enter the <code>telnet_settings</code> term in a configuration
%% file included in the test and ct_telnet will retrieve the information
@@ -181,7 +183,8 @@
conn_to=?DEFAULT_TIMEOUT,
com_to=?DEFAULT_TIMEOUT,
reconns=?RECONNS,
- reconn_int=?RECONN_TIMEOUT}).
+ reconn_int=?RECONN_TIMEOUT,
+ tcp_nodelay=false}).
%%%-----------------------------------------------------------------
%%% @spec open(Name) -> {ok,Handle} | {error,Reason}
@@ -326,16 +329,16 @@ cmd(Connection,Cmd) ->
%%% Reason = term()
%%% @doc Send a command via telnet and wait for prompt.
%%%
-%%% This function will by default add a newline to the end of the
+%%% <p>This function will by default add a newline to the end of the
%%% given command. If this is not desired, the option
%%% `{newline,false}' can be used. This is necessary, for example,
%%% when sending telnet command sequences (prefixed with the
-%%% Interprete As Command, IAC, character).
+%%% Interprete As Command, IAC, character).</p>
%%%
-%%% The option `timeout' specifies how long the client shall wait for
+%%% <p>The option `timeout' specifies how long the client shall wait for
%%% prompt. If the time expires, the function returns
%%% `{error,timeout}'. See the module description for information
-%%% about the default value for the command timeout.
+%%% about the default value for the command timeout.</p>
cmd(Connection,Cmd,Opts) when is_list(Opts) ->
case check_cmd_opts(Opts) of
ok ->
@@ -377,7 +380,7 @@ cmdf(Connection,CmdFormat,Args) ->
%%% @doc Send a telnet command and wait for prompt
%%% (uses a format string and list of arguments to build the command).
%%%
-%%% See {@link cmd/3} further description.
+%%% <p>See {@link cmd/3} further description.</p>
cmdf(Connection,CmdFormat,Args,Opts) when is_list(Args) ->
Cmd = lists:flatten(io_lib:format(CmdFormat,Args)),
cmd(Connection,Cmd,Opts).
@@ -601,8 +604,18 @@ init(Name,{Ip,Port,Type},{TargetMod,KeepAlive,Extra}) ->
Settings ->
set_telnet_defaults(Settings,#state{})
end,
- case catch TargetMod:connect(Name,Ip,Port,S0#state.conn_to,
- KeepAlive,Extra) of
+ %% Handle old user versions of TargetMod
+ code:ensure_loaded(TargetMod),
+ try
+ case erlang:function_exported(TargetMod,connect,7) of
+ true ->
+ TargetMod:connect(Name,Ip,Port,S0#state.conn_to,
+ KeepAlive,S0#state.tcp_nodelay,Extra);
+ false ->
+ TargetMod:connect(Name,Ip,Port,S0#state.conn_to,
+ KeepAlive,Extra)
+ end
+ of
{ok,TelnPid} ->
put({ct_telnet_pid2name,TelnPid},Name),
S1 = S0#state{host=Ip,
@@ -624,15 +637,18 @@ init(Name,{Ip,Port,Type},{TargetMod,KeepAlive,Extra}) ->
"Connection timeout: ~p\n"
"Keep alive: ~w\n"
"Poll limit: ~w\n"
- "Poll interval: ~w",
+ "Poll interval: ~w\n"
+ "TCP nodelay: ~w",
[Ip,Port,S1#state.com_to,S1#state.reconns,
S1#state.reconn_int,S1#state.conn_to,KeepAlive,
- S1#state.poll_limit,S1#state.poll_interval]),
+ S1#state.poll_limit,S1#state.poll_interval,
+ S1#state.tcp_nodelay]),
{ok,TelnPid,S1};
- {'EXIT',Reason} ->
- {error,Reason};
Error ->
Error
+ catch
+ _:Reason ->
+ {error,Reason}
end.
type(telnet) -> ip;
@@ -652,6 +668,8 @@ set_telnet_defaults([{poll_limit,PL}|Ss],S) ->
set_telnet_defaults(Ss,S#state{poll_limit=PL});
set_telnet_defaults([{poll_interval,PI}|Ss],S) ->
set_telnet_defaults(Ss,S#state{poll_interval=PI});
+set_telnet_defaults([{tcp_nodelay,NoDelay}|Ss],S) ->
+ set_telnet_defaults(Ss,S#state{tcp_nodelay=NoDelay});
set_telnet_defaults([Unknown|Ss],S) ->
force_log(S,error,
"Bad element in telnet_settings: ~p",[Unknown]),
@@ -793,8 +811,17 @@ reconnect(Ip,Port,N,State=#state{name=Name,
keep_alive=KeepAlive,
extra=Extra,
conn_to=ConnTo,
- reconn_int=ReconnInt}) ->
- case TargetMod:connect(Name,Ip,Port,ConnTo,KeepAlive,Extra) of
+ reconn_int=ReconnInt,
+ tcp_nodelay=NoDelay}) ->
+ %% Handle old user versions of TargetMod
+ ConnResult =
+ case erlang:function_exported(TargetMod,connect,7) of
+ true ->
+ TargetMod:connect(Name,Ip,Port,ConnTo,KeepAlive,NoDelay,Extra);
+ false ->
+ TargetMod:connect(Name,Ip,Port,ConnTo,KeepAlive,Extra)
+ end,
+ case ConnResult of
{ok,NewPid} ->
put({ct_telnet_pid2name,NewPid},Name),
{ok, NewPid, State#state{teln_pid=NewPid}};
@@ -1021,7 +1048,7 @@ silent_teln_expect(Name,Pid,Data,Pattern,Prx,Opts) ->
put(silent,Old),
Result.
-%% teln_expect/5
+%% teln_expect/6
%%
%% This function implements the expect functionality over telnet. In
%% general there are three possible ways to go:
diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl
index 0c448e5b35..bdab456cfa 100644
--- a/lib/common_test/src/ct_telnet_client.erl
+++ b/lib/common_test/src/ct_telnet_client.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,12 +35,12 @@
%%-define(debug, true).
--export([open/2, open/3, open/4, open/5, close/1]).
+-export([open/2, open/3, open/4, open/5, open/6, close/1]).
-export([send_data/2, send_data/3, get_data/1]).
-define(TELNET_PORT, 23).
-define(OPEN_TIMEOUT,10000).
--define(IDLE_TIMEOUT,10000).
+-define(IDLE_TIMEOUT,8000).
%% telnet control characters
-define(SE, 240).
@@ -69,19 +70,22 @@
-record(state,{conn_name, get_data, keep_alive=true, log_pos=1}).
open(Server, ConnName) ->
- open(Server, ?TELNET_PORT, ?OPEN_TIMEOUT, true, ConnName).
+ open(Server, ?TELNET_PORT, ?OPEN_TIMEOUT, true, false, ConnName).
open(Server, Port, ConnName) ->
- open(Server, Port, ?OPEN_TIMEOUT, true, ConnName).
+ open(Server, Port, ?OPEN_TIMEOUT, true, false, ConnName).
open(Server, Port, Timeout, ConnName) ->
- open(Server, Port, Timeout, true, ConnName).
+ open(Server, Port, Timeout, true, false, ConnName).
open(Server, Port, Timeout, KeepAlive, ConnName) ->
+ open(Server, Port, Timeout, KeepAlive, false, ConnName).
+
+open(Server, Port, Timeout, KeepAlive, NoDelay, ConnName) ->
Self = self(),
Pid = spawn(fun() ->
init(Self, Server, Port, Timeout,
- KeepAlive, ConnName)
+ KeepAlive, NoDelay, ConnName)
end),
receive
{open,Pid} ->
@@ -113,8 +117,8 @@ get_data(Pid) ->
%%%-----------------------------------------------------------------
%%% Internal functions
-init(Parent, Server, Port, Timeout, KeepAlive, ConnName) ->
- case gen_tcp:connect(Server, Port, [list,{packet,0}], Timeout) of
+init(Parent, Server, Port, Timeout, KeepAlive, NoDelay, ConnName) ->
+ case gen_tcp:connect(Server, Port, [list,{packet,0},{nodelay,NoDelay}], Timeout) of
{ok,Sock} ->
dbg("~p connected to: ~p (port: ~w, keep_alive: ~w)\n",
[ConnName,Server,Port,KeepAlive]),
@@ -393,7 +397,7 @@ cmd_dbg(Prefix,Cmd) ->
end.
timestamp() ->
- {MS,S,US} = now(),
+ {MS,S,US} = os:timestamp(),
{{Year,Month,Day}, {Hour,Min,Sec}} =
calendar:now_to_local_time({MS,S,US}),
MilliSec = trunc(US/1000),
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index 10a9bdac67..61d8f49dcc 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,6 +28,8 @@
collect_tests_from_list/2, collect_tests_from_list/3,
collect_tests_from_file/2, collect_tests_from_file/3]).
+-export([testspec_rec2list/1, testspec_rec2list/2]).
+
-include("ct_util.hrl").
-define(testspec_fields, record_info(fields, testspec)).
@@ -67,13 +70,17 @@ prepare_tests(TestSpec) when is_record(TestSpec,testspec) ->
Tests = TestSpec#testspec.tests,
%% Sort Tests into "flat" Run and Skip lists (not sorted per node).
{Run,Skip} = get_run_and_skip(Tests,[],[]),
+
%% Create initial list of {Node,{Run,Skip}} tuples
NodeList = lists:map(fun(N) -> {N,{[],[]}} end, list_nodes(TestSpec)),
+
%% Get all Run tests sorted per node basis.
NodeList1 = run_per_node(Run,NodeList,
- TestSpec#testspec.merge_tests),
+ TestSpec#testspec.merge_tests),
+
%% Get all Skip entries sorted per node basis.
NodeList2 = skip_per_node(Skip,NodeList1),
+
%% Change representation.
Result=
lists:map(fun({Node,{Run1,Skip1}}) ->
@@ -100,7 +107,7 @@ run_per_node([{{Node,Dir},Test}|Ts],Result,MergeTests) ->
true ->
merge_tests(Dir,Test,Run)
end,
- run_per_node(Ts,insert_in_order({Node,{Run1,Skip}},Result),
+ run_per_node(Ts,insert_in_order({Node,{Run1,Skip}},Result,replace),
MergeTests);
run_per_node([],Result,_) ->
Result.
@@ -137,7 +144,7 @@ merge_suites(Dir,Test,[]) ->
skip_per_node([{{Node,Dir},Test}|Ts],Result) ->
{value,{Node,{Run,Skip}}} = lists:keysearch(Node,1,Result),
Skip1 = [{Dir,Test}|Skip],
- skip_per_node(Ts,insert_in_order({Node,{Run,Skip1}},Result));
+ skip_per_node(Ts,insert_in_order({Node,{Run,Skip1}},Result,replace));
skip_per_node([],Result) ->
Result.
@@ -153,7 +160,7 @@ skip_per_node([],Result) ->
%%
%% Skip entry: {Suites,Comment} or {Suite,Cases,Comment}
%%
-get_run_and_skip([{{Node,Dir},Suites}|Tests],Run,Skip) ->
+get_run_and_skip([{{Node,Dir},Suites}|Tests],Run,Skip) ->
TestDir = ct_util:get_testdir(Dir,catch element(1,hd(Suites))),
case lists:keysearch(all,1,Suites) of
{value,_} -> % all Suites in Dir
@@ -180,18 +187,33 @@ prepare_suites(Node,Dir,[{Suite,Cases}|Suites],Run,Skip) ->
[[{{Node,Dir},{Suite,all}}]|Run],
[Skipped|Skip]);
false ->
- {RL,SL} = prepare_cases(Node,Dir,Suite,Cases),
- prepare_suites(Node,Dir,Suites,[RL|Run],[SL|Skip])
+ {Run1,Skip1} = prepare_cases(Node,Dir,Suite,Cases,Run,Skip),
+ prepare_suites(Node,Dir,Suites,Run1,Skip1)
end;
prepare_suites(_Node,_Dir,[],Run,Skip) ->
{lists:flatten(lists:reverse(Run)),
lists:flatten(lists:reverse(Skip))}.
-prepare_cases(Node,Dir,Suite,Cases) ->
+prepare_cases(Node,Dir,Suite,Cases,Run,Skip) ->
case get_skipped_cases(Node,Dir,Suite,Cases) of
- SkipAll=[{{Node,Dir},{Suite,_Cmt}}] -> % all cases to be skipped
- %% note: this adds an 'all' test even if only skip is specified
- {[{{Node,Dir},{Suite,all}}],SkipAll};
+ [SkipAll={{Node,Dir},{Suite,_Cmt}}] -> % all cases to be skipped
+ case lists:any(fun({{N,D},{S,all}}) when N == Node,
+ D == Dir,
+ S == Suite ->
+ true;
+ ({{N,D},{S,Cs}}) when N == Node,
+ D == Dir,
+ S == Suite ->
+ lists:member(all,Cs);
+ (_) -> false
+ end, lists:flatten(Run)) of
+ true ->
+ {Run,[SkipAll|Skip]};
+ false ->
+ %% note: this adds an 'all' test even if
+ %% only skip is specified
+ {[{{Node,Dir},{Suite,all}}|Run],[SkipAll|Skip]}
+ end;
Skipped ->
%% note: this adds a test even if only skip is specified
PrepC = lists:foldr(fun({{G,Cs},{skip,_Cmt}}, Acc) when
@@ -207,11 +229,11 @@ prepare_cases(Node,Dir,Suite,Cases) ->
true ->
Acc;
false ->
- [C|Acc]
+ [{skipped,C}|Acc]
end;
(C,Acc) -> [C|Acc]
end, [], Cases),
- {{{Node,Dir},{Suite,PrepC}},Skipped}
+ {[{{Node,Dir},{Suite,PrepC}}|Run],[Skipped|Skip]}
end.
get_skipped_suites(Node,Dir,Suites) ->
@@ -428,6 +450,7 @@ collect_tests({Replace,Terms},TestSpec=#testspec{alias=As,nodes=Ns},Relaxed) ->
merge_tests = MergeTestsDef}),
TestSpec2 = get_all_nodes(Terms2,TestSpec1),
{Terms3, TestSpec3} = filter_init_terms(Terms2, [], TestSpec2),
+
add_tests(Terms3,TestSpec3).
%% replace names (atoms) in the testspec matching those in 'define' terms by
@@ -973,7 +996,8 @@ add_tests([Term={Tag,all_nodes,Data}|Ts],Spec) ->
should_be_added(Tag,Node,Data,Spec)],
add_tests(Tests++Ts,Spec);
invalid -> % ignore term
- add_tests(Ts,Spec)
+ Unknown = Spec#testspec.unknown,
+ add_tests(Ts,Spec#testspec{unknown=Unknown++[Term]})
end;
%% create one test entry per node in Nodes and reinsert
add_tests([{Tag,[],Data}|Ts],Spec) ->
@@ -1001,7 +1025,8 @@ add_tests([Term={Tag,NodeOrOther,Data}|Ts],Spec) ->
handle_data(Tag,Node,Data,Spec),
add_tests(Ts,mod_field(Spec,Tag,NodeIxData));
invalid -> % ignore term
- add_tests(Ts,Spec)
+ Unknown = Spec#testspec.unknown,
+ add_tests(Ts,Spec#testspec{unknown=Unknown++[Term]})
end;
false ->
add_tests([{Tag,all_nodes,{NodeOrOther,Data}}|Ts],Spec)
@@ -1012,13 +1037,15 @@ add_tests([Term={Tag,Data}|Ts],Spec) ->
valid ->
add_tests([{Tag,all_nodes,Data}|Ts],Spec);
invalid ->
- add_tests(Ts,Spec)
+ Unknown = Spec#testspec.unknown,
+ add_tests(Ts,Spec#testspec{unknown=Unknown++[Term]})
end;
%% some other data than a tuple
add_tests([Other|Ts],Spec) ->
case get(relaxed) of
- true ->
- add_tests(Ts,Spec);
+ true ->
+ Unknown = Spec#testspec.unknown,
+ add_tests(Ts,Spec#testspec{unknown=Unknown++[Other]});
false ->
throw({error,{undefined_term_in_spec,Other}})
end;
@@ -1119,8 +1146,9 @@ should_be_added(Tag,Node,_Data,Spec) ->
if
%% list terms *without* possible duplicates here
Tag == logdir; Tag == logopts;
- Tag == basic_html; Tag == label;
- Tag == auto_compile; Tag == abort_if_missing_suites;
+ Tag == basic_html; Tag == esc_chars;
+ Tag == label; Tag == auto_compile;
+ Tag == abort_if_missing_suites;
Tag == stylesheet; Tag == verbosity;
Tag == silent_connections ->
lists:keymember(ref2node(Node,Spec#testspec.nodes),1,
@@ -1149,6 +1177,24 @@ per_node([N|Ns],Tag,Data,Refs) ->
per_node([],_,_,_) ->
[].
+%% Change the testspec record "back" to a list of tuples
+testspec_rec2list(Rec) ->
+ {Terms,_} = lists:mapfoldl(fun(unknown, Pos) ->
+ {element(Pos, Rec),Pos+1};
+ (F, Pos) ->
+ {{F,element(Pos, Rec)},Pos+1}
+ end,2,?testspec_fields),
+ lists:flatten(Terms).
+
+%% Extract one or more values from a testspec record and
+%% return the result as a list of tuples
+testspec_rec2list(Field, Rec) when is_atom(Field) ->
+ [Term] = testspec_rec2list([Field], Rec),
+ Term;
+testspec_rec2list(Fields, Rec) ->
+ Terms = testspec_rec2list(Rec),
+ [{Field,proplists:get_value(Field, Terms)} || Field <- Fields].
+
%% read the value for FieldName in record Rec#testspec
read_field(Rec, FieldName) ->
catch lists:foldl(fun(F, Pos) when F == FieldName ->
@@ -1232,7 +1278,7 @@ insert_groups1(Suite,Groups,Suites0) ->
Suites0;
{value,{Suite,GrAndCases0}} ->
GrAndCases = insert_groups2(Groups,GrAndCases0),
- insert_in_order({Suite,GrAndCases},Suites0);
+ insert_in_order({Suite,GrAndCases},Suites0,replace);
false ->
insert_in_order({Suite,Groups},Suites0)
end.
@@ -1257,7 +1303,7 @@ insert_cases(Node,Dir,Suite,Cases,Tests,false) when is_list(Cases) ->
insert_cases(Node,Dir,Suite,Cases,Tests,true) when is_list(Cases) ->
{Tests1,Done} =
lists:foldr(fun(All={{N,D},[{all,_}]},{Merged,_}) when N == Node,
- D == Dir ->
+ D == Dir ->
{[All|Merged],true};
({{N,D},Suites0},{Merged,_}) when N == Node,
D == Dir ->
@@ -1287,7 +1333,7 @@ insert_cases1(Suite,Cases,Suites0) ->
Suites0;
{value,{Suite,Cases0}} ->
Cases1 = insert_in_order(Cases,Cases0),
- insert_in_order({Suite,Cases1},Suites0);
+ insert_in_order({Suite,Cases1},Suites0,replace);
false ->
insert_in_order({Suite,Cases},Suites0)
end.
@@ -1344,9 +1390,9 @@ skip_groups1(Suite,Groups,Cmt,Suites0) ->
case lists:keysearch(Suite,1,Suites0) of
{value,{Suite,GrAndCases0}} ->
GrAndCases1 = GrAndCases0 ++ SkipGroups,
- insert_in_order({Suite,GrAndCases1},Suites0);
+ insert_in_order({Suite,GrAndCases1},Suites0,replace);
false ->
- insert_in_order({Suite,SkipGroups},Suites0)
+ insert_in_order({Suite,SkipGroups},Suites0,replace)
end.
skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,false) when is_list(Cases) ->
@@ -1355,7 +1401,7 @@ skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,false) when is_list(Cases) ->
skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,true) when is_list(Cases) ->
{Tests1,Done} =
lists:foldr(fun({{N,D},Suites0},{Merged,_}) when N == Node,
- D == Dir ->
+ D == Dir ->
Suites1 = skip_cases1(Suite,Cases,Cmt,Suites0),
{[{{N,D},Suites1}|Merged],true};
(T,{Merged,Match}) ->
@@ -1376,32 +1422,55 @@ skip_cases1(Suite,Cases,Cmt,Suites0) ->
case lists:keysearch(Suite,1,Suites0) of
{value,{Suite,Cases0}} ->
Cases1 = Cases0 ++ SkipCases,
- insert_in_order({Suite,Cases1},Suites0);
+ insert_in_order({Suite,Cases1},Suites0,replace);
false ->
- insert_in_order({Suite,SkipCases},Suites0)
+ case Suites0 of
+ [{all,_}=All|Skips]->
+ [All|Skips++[{Suite,SkipCases}]];
+ _ ->
+ insert_in_order({Suite,SkipCases},Suites0,replace)
+ end
end.
append(Elem, List) ->
List ++ [Elem].
-insert_in_order([E|Es],List) ->
- List1 = insert_elem(E,List,[]),
- insert_in_order(Es,List1);
-insert_in_order([],List) ->
+insert_in_order(Elems,Dest) ->
+ insert_in_order1(Elems,Dest,false).
+
+insert_in_order(Elems,Dest,replace) ->
+ insert_in_order1(Elems,Dest,true).
+
+insert_in_order1([_E|Es],all,Replace) ->
+ insert_in_order1(Es,all,Replace);
+
+insert_in_order1([E|Es],List,Replace) ->
+ List1 = insert_elem(E,List,[],Replace),
+ insert_in_order1(Es,List1,Replace);
+insert_in_order1([],List,_Replace) ->
List;
-insert_in_order(E,List) ->
- insert_elem(E,List,[]).
+insert_in_order1(E,List,Replace) ->
+ insert_elem(E,List,[],Replace).
+
-%% replace an existing entry (same key) or add last in list
-insert_elem({Key,_}=E,[{Key,_}|Rest],SoFar) ->
+insert_elem({Key,_}=E,[{Key,_}|Rest],SoFar,true) ->
lists:reverse([E|SoFar]) ++ Rest;
-insert_elem({E,_},[E|Rest],SoFar) ->
+insert_elem({E,_},[E|Rest],SoFar,true) ->
lists:reverse([E|SoFar]) ++ Rest;
-insert_elem(E,[E|Rest],SoFar) ->
+insert_elem(E,[E|Rest],SoFar,true) ->
+ lists:reverse([E|SoFar]) ++ Rest;
+
+insert_elem({all,_}=E,_,SoFar,_Replace) ->
+ lists:reverse([E|SoFar]);
+insert_elem(_E,[all|_],SoFar,_Replace) ->
+ lists:reverse(SoFar);
+insert_elem(_E,[{all,_}],SoFar,_Replace) ->
+ lists:reverse(SoFar);
+insert_elem({Key,_}=E,[{Key,[]}|Rest],SoFar,_Replace) ->
lists:reverse([E|SoFar]) ++ Rest;
-insert_elem(E,[E1|Rest],SoFar) ->
- insert_elem(E,Rest,[E1|SoFar]);
-insert_elem(E,[],SoFar) ->
+insert_elem(E,[E1|Rest],SoFar,Replace) ->
+ insert_elem(E,Rest,[E1|SoFar],Replace);
+insert_elem(E,[],SoFar,_Replace) ->
lists:reverse([E|SoFar]).
ref2node(all_nodes,_Refs) ->
@@ -1476,6 +1545,8 @@ valid_terms() ->
{logopts,3},
{basic_html,2},
{basic_html,3},
+ {esc_chars,2},
+ {esc_chars,3},
{verbosity,2},
{verbosity,3},
{silent_connections,2},
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 56027586d1..3561a0a2d3 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -458,6 +459,7 @@ loop(Mode,TestData,StartDir) ->
error:badarg -> []
end,
ct_hooks:terminate(Callbacks),
+
close_connections(ets:tab2list(?conn_table)),
ets:delete(?conn_table),
ets:delete(?board_table),
@@ -484,6 +486,8 @@ loop(Mode,TestData,StartDir) ->
{'EXIT',Pid,Reason} ->
case ets:lookup(?conn_table,Pid) of
[#conn{address=A,callback=CB}] ->
+ ErrorStr = io_lib:format("~tp", [Reason]),
+ ErrorHtml = ct_logs:escape_chars(ErrorStr),
%% A connection crashed - remove the connection but don't die
ct_logs:tc_log_async(ct_error_notify,
?MAX_IMPORTANCE,
@@ -491,8 +495,8 @@ loop(Mode,TestData,StartDir) ->
"Connection process died: "
"Pid: ~w, Address: ~p, "
"Callback: ~w\n"
- "Reason: ~p\n\n",
- [Pid,A,CB,Reason]),
+ "Reason: ~ts\n\n",
+ [Pid,A,CB,ErrorHtml]),
catch CB:close(Pid),
%% in case CB:close failed to do this:
unregister_connection(Pid),
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index 845bb55486..bdfe2041a5 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -36,6 +37,7 @@
logdir=["."],
logopts=[],
basic_html=[],
+ esc_chars=[],
verbosity=[],
silent_connections=[],
cover=[],
@@ -55,6 +57,7 @@
create_priv_dir=[],
alias=[],
tests=[],
+ unknown=[],
merge_tests=true}).
-record(cover, {app=none,
diff --git a/lib/common_test/src/ct_webtool.erl b/lib/common_test/src/ct_webtool.erl
index b67a7c2a92..014487eb10 100644
--- a/lib/common_test/src/ct_webtool.erl
+++ b/lib/common_test/src/ct_webtool.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/src/ct_webtool_sup.erl b/lib/common_test/src/ct_webtool_sup.erl
index 1d612a2d18..485161c784 100644
--- a/lib/common_test/src/ct_webtool_sup.erl
+++ b/lib/common_test/src/ct_webtool_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/src/cth_conn_log.erl b/lib/common_test/src/cth_conn_log.erl
index 1e60f2751e..954b4239af 100644
--- a/lib/common_test/src/cth_conn_log.erl
+++ b/lib/common_test/src/cth_conn_log.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -131,7 +132,7 @@ pre_init_per_testcase(TestCase,Config,CthState) ->
[S,ct_logs:uri(L),filename:basename(L)])
|| {S,L} <- Ls] ++
"</table>",
- io:format(Str,[]),
+ ct:log(Str,[],[no_css]),
{ConnMod,{LogType,Ls}};
_ ->
{ConnMod,{LogType,[]}}
diff --git a/lib/common_test/src/cth_log_redirect.erl b/lib/common_test/src/cth_log_redirect.erl
index 61700a2032..780fbea79a 100644
--- a/lib/common_test/src/cth_log_redirect.erl
+++ b/lib/common_test/src/cth_log_redirect.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,8 @@
pre_init_per_suite/3, pre_end_per_suite/3, post_end_per_suite/4,
pre_init_per_group/3, post_init_per_group/4,
pre_end_per_group/3, post_end_per_group/4,
- pre_init_per_testcase/3, post_end_per_testcase/4]).
+ pre_init_per_testcase/3, post_init_per_testcase/4,
+ pre_end_per_testcase/3, post_end_per_testcase/4]).
%% Event handler Callbacks
-export([init/1,
@@ -88,6 +90,12 @@ pre_init_per_testcase(TC, Config, State) ->
set_curr_func(TC, Config),
{Config, State}.
+post_init_per_testcase(_TC, _Config, Return, State) ->
+ {Return, State}.
+
+pre_end_per_testcase(_TC, Config, State) ->
+ {Config, State}.
+
post_end_per_testcase(_TC, _Config, Result, State) ->
%% Make sure that the event queue is flushed
%% before ending this test case.
@@ -122,7 +130,14 @@ handle_event(Event, #eh_state{log_func = LogFunc} = State) ->
tag_event(Event)),
if is_list(SReport) ->
SaslHeader = format_header(State),
- ct_logs:LogFunc(sasl, ?STD_IMPORTANCE, SaslHeader, SReport, []);
+ case LogFunc of
+ tc_log ->
+ ct_logs:tc_log(sasl, ?STD_IMPORTANCE,
+ SaslHeader, SReport, [], []);
+ tc_log_async ->
+ ct_logs:tc_log_async(sasl, ?STD_IMPORTANCE,
+ SaslHeader, SReport, [])
+ end;
true -> %% Report is an atom if no logging is to be done
ignore
end
@@ -131,7 +146,14 @@ handle_event(Event, #eh_state{log_func = LogFunc} = State) ->
tag_event(Event),io_lib),
if is_list(EReport) ->
ErrHeader = format_header(State),
- ct_logs:LogFunc(error_logger, ?STD_IMPORTANCE, ErrHeader, EReport, []);
+ case LogFunc of
+ tc_log ->
+ ct_logs:tc_log(error_logger, ?STD_IMPORTANCE,
+ ErrHeader, EReport, [], []);
+ tc_log_async ->
+ ct_logs:tc_log_async(error_logger, ?STD_IMPORTANCE,
+ ErrHeader, EReport, [])
+ end;
true -> %% Report is an atom if no logging is to be done
ignore
end,
diff --git a/lib/common_test/src/cth_surefire.erl b/lib/common_test/src/cth_surefire.erl
index bb12171ea7..d6e855c02c 100644
--- a/lib/common_test/src/cth_surefire.erl
+++ b/lib/common_test/src/cth_surefire.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%--------------------------------------------------------------------
@@ -59,6 +60,8 @@
-define(default_report,"junit_report.xml").
-define(suite_log,"suite.log.html").
+-define(now, os:timestamp()).
+
%% Number of dirs from log root to testcase log file.
%% ct_run.<node>.<timestamp>/<test_name>/run.<timestamp>/<tc_log>.html
-define(log_depth,3).
@@ -77,11 +80,12 @@ init(Path, Opts) ->
axis = proplists:get_value(axis,Opts,[]),
properties = proplists:get_value(properties,Opts,[]),
url_base = proplists:get_value(url_base,Opts),
- timer = now() }.
+ timer = ?now }.
-pre_init_per_suite(Suite,SkipOrFail,State) when is_tuple(SkipOrFail) ->
+pre_init_per_suite(Suite,SkipOrFail,#state{ test_cases = [] } = State)
+ when is_tuple(SkipOrFail) ->
{SkipOrFail, init_tc(State#state{curr_suite = Suite,
- curr_suite_ts = now()},
+ curr_suite_ts = ?now},
SkipOrFail) };
pre_init_per_suite(Suite,Config,#state{ test_cases = [] } = State) ->
TcLog = proplists:get_value(tc_logfile,Config),
@@ -96,7 +100,7 @@ pre_init_per_suite(Suite,Config,#state{ test_cases = [] } = State) ->
end,
{Config, init_tc(State#state{ filepath = Path,
curr_suite = Suite,
- curr_suite_ts = now(),
+ curr_suite_ts = ?now,
curr_log_dir = CurrLogDir},
Config) };
pre_init_per_suite(Suite,Config,State) ->
@@ -169,9 +173,9 @@ do_tc_skip(Res, State) ->
State#state{ test_cases = [NewTC | tl(TCs)]}.
init_tc(State, Config) when is_list(Config) == false ->
- State#state{ timer = now(), tc_log = "" };
+ State#state{ timer = ?now, tc_log = "" };
init_tc(State, Config) ->
- State#state{ timer = now(),
+ State#state{ timer = ?now,
tc_log = proplists:get_value(tc_logfile, Config, [])}.
end_tc(Func, Config, Res, State) when is_atom(Func) ->
@@ -194,7 +198,7 @@ end_tc(Name, _Config, _Res, State = #state{ curr_suite = Suite,
ClassName = atom_to_list(Suite),
PGroup = string:join([ atom_to_list(Group)||
Group <- lists:reverse(Groups)],"."),
- TimeTakes = io_lib:format("~f",[timer:now_diff(now(),TS) / 1000000]),
+ TimeTakes = io_lib:format("~f",[timer:now_diff(?now,TS) / 1000000]),
State#state{ test_cases = [#testcase{ log = Log,
url = Url,
timestamp = now_to_string(TS),
@@ -209,7 +213,7 @@ close_suite(#state{ test_cases = [] } = State) ->
State;
close_suite(#state{ test_cases = TCs, url_base = UrlBase } = State) ->
{Total,Fail,Skip} = count_tcs(TCs,0,0,0),
- TimeTaken = timer:now_diff(now(),State#state.curr_suite_ts) / 1000000,
+ TimeTaken = timer:now_diff(?now,State#state.curr_suite_ts) / 1000000,
SuiteLog = filename:join(State#state.curr_log_dir,?suite_log),
SuiteUrl = make_url(UrlBase,SuiteLog),
Suite = #testsuite{ name = atom_to_list(State#state.curr_suite),
diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl
index 09b6fd1510..2fc585735d 100644
--- a/lib/common_test/src/unix_telnet.erl
+++ b/lib/common_test/src/unix_telnet.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,7 +27,8 @@
%%% {port,PortNum}, % optional
%%% {username,UserName},
%%% {password,Password},
-%%% {keep_alive,Bool}]}. % optional</pre>
+%%% {keep_alive,Bool}, % optional
+%%% {tcp_nodely,Bool}]} % optional</pre>
%%%
%%% <p>To communicate via telnet to the host specified by
%%% <code>HostNameOrIpAddress</code>, use the interface functions in
@@ -54,7 +56,7 @@
-compile(export_all).
%% Callbacks for ct_telnet.erl
--export([connect/6,get_prompt_regexp/0]).
+-export([connect/7,get_prompt_regexp/0]).
-import(ct_telnet,[start_gen_log/1,log/4,end_gen_log/0]).
-define(username,"login: ").
@@ -81,6 +83,7 @@ get_prompt_regexp() ->
%%% Port = integer()
%%% Timeout = integer()
%%% KeepAlive = bool()
+%%% TCPNoDelay = bool()
%%% Extra = ct:target_name() | {Username,Password}
%%% Username = string()
%%% Password = string()
@@ -90,25 +93,25 @@ get_prompt_regexp() ->
%%% @doc Callback for ct_telnet.erl.
%%%
%%% <p>Setup telnet connection to a unix host.</p>
-connect(ConnName,Ip,Port,Timeout,KeepAlive,Extra) ->
+connect(ConnName,Ip,Port,Timeout,KeepAlive,TCPNoDelay,Extra) ->
case Extra of
{Username,Password} ->
- connect1(ConnName,Ip,Port,Timeout,KeepAlive,
+ connect1(ConnName,Ip,Port,Timeout,KeepAlive,TCPNoDelay,
Username,Password);
KeyOrName ->
case get_username_and_password(KeyOrName) of
{ok,{Username,Password}} ->
- connect1(ConnName,Ip,Port,Timeout,KeepAlive,
+ connect1(ConnName,Ip,Port,Timeout,KeepAlive,TCPNoDelay,
Username,Password);
Error ->
Error
end
end.
-connect1(Name,Ip,Port,Timeout,KeepAlive,Username,Password) ->
+connect1(Name,Ip,Port,Timeout,KeepAlive,TCPNoDelay,Username,Password) ->
start_gen_log("unix_telnet connect"),
Result =
- case ct_telnet_client:open(Ip,Port,Timeout,KeepAlive,Name) of
+ case ct_telnet_client:open(Ip,Port,Timeout,KeepAlive,TCPNoDelay,Name) of
{ok,Pid} ->
case ct_telnet:silent_teln_expect(Name,Pid,[],
[prompt],?prx,[]) of
diff --git a/lib/common_test/src/vts.erl b/lib/common_test/src/vts.erl
index ab13e7d0ee..df434d62c8 100644
--- a/lib/common_test/src/vts.erl
+++ b/lib/common_test/src/vts.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index a0ac47f12a..a1cead4550 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -64,7 +65,8 @@ MODULES= \
ct_cover_nomerge_SUITE \
ct_groups_search_SUITE \
ct_surefire_SUITE \
- ct_telnet_SUITE
+ ct_telnet_SUITE \
+ ct_release_test_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/common_test/test/ct_auto_compile_SUITE.erl b/lib/common_test/test/ct_auto_compile_SUITE.erl
index cc546ed30d..f00bd46d6f 100644
--- a/lib/common_test/test/ct_auto_compile_SUITE.erl
+++ b/lib/common_test/test/ct_auto_compile_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -108,6 +109,8 @@ ac_spec(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
file:copy(filename:join(DataDir, "bad_SUITE.erl"),
filename:join(PrivDir, "bad_SUITE.erl")),
+ Suite = filename:join(DataDir, "dummy_SUITE"),
+ compile:file(Suite, [{outdir,PrivDir}]),
TestSpec = [{label,ac_spec},
{auto_compile,false},
{suites,PrivDir,all}],
@@ -160,28 +163,34 @@ events_to_check(Test, N) ->
test_events(ac_flag) ->
[
- {ct_test_support_eh,start_logging,{'DEF','RUNDIR'}},
- {ct_test_support_eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
- {ct_test_support_eh,start_info,{1,1,3}},
- {ct_test_support_eh,tc_start,{dummy_SUITE,init_per_suite}},
- {ct_test_support_eh,tc_done,{dummy_SUITE,init_per_suite,ok}},
- {ct_test_support_eh,test_stats,{1,1,{1,0}}},
- {ct_test_support_eh,tc_start,{dummy_SUITE,end_per_suite}},
- {ct_test_support_eh,tc_done,{dummy_SUITE,end_per_suite,ok}},
- {ct_test_support_eh,test_done,{'DEF','STOP_TIME'}},
- {ct_test_support_eh,stop_logging,[]}
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,3}},
+ {?eh,tc_start,{ct_framework,error_in_suite}},
+ {?eh,tc_done,{ct_framework,error_in_suite,
+ {failed,{error,'bad_SUITE can not be compiled or loaded'}}}},
+ {?eh,tc_start,{dummy_SUITE,init_per_suite}},
+ {?eh,tc_done,{dummy_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,1,{1,0}}},
+ {?eh,tc_start,{dummy_SUITE,end_per_suite}},
+ {?eh,tc_done,{dummy_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
];
test_events(ac_spec) ->
[
- {ct_test_support_eh,start_logging,{'DEF','RUNDIR'}},
- {ct_test_support_eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
- {ct_test_support_eh,start_info,{1,1,3}},
- {ct_test_support_eh,tc_start,{dummy_SUITE,init_per_suite}},
- {ct_test_support_eh,tc_done,{dummy_SUITE,init_per_suite,ok}},
- {ct_test_support_eh,test_stats,{1,1,{1,0}}},
- {ct_test_support_eh,tc_start,{dummy_SUITE,end_per_suite}},
- {ct_test_support_eh,tc_done,{dummy_SUITE,end_per_suite,ok}},
- {ct_test_support_eh,test_done,{'DEF','STOP_TIME'}},
- {ct_test_support_eh,stop_logging,[]}
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,3}},
+ {?eh,tc_start,{ct_framework,error_in_suite}},
+ {?eh,tc_done,{ct_framework,error_in_suite,
+ {failed,{error,'bad_SUITE can not be compiled or loaded'}}}},
+ {?eh,tc_start,{dummy_SUITE,init_per_suite}},
+ {?eh,tc_done,{dummy_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,1,{1,0}}},
+ {?eh,tc_start,{dummy_SUITE,end_per_suite}},
+ {?eh,tc_done,{dummy_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
].
diff --git a/lib/common_test/test/ct_auto_compile_SUITE_data/bad_SUITE.erl b/lib/common_test/test/ct_auto_compile_SUITE_data/bad_SUITE.erl
index b270c28849..ebeb4a51f6 100644
--- a/lib/common_test/test/ct_auto_compile_SUITE_data/bad_SUITE.erl
+++ b/lib/common_test/test/ct_auto_compile_SUITE_data/bad_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/common_test/test/ct_auto_compile_SUITE_data/dummy_SUITE.erl b/lib/common_test/test/ct_auto_compile_SUITE_data/dummy_SUITE.erl
index 0bb2e388c7..935fe1929f 100644
--- a/lib/common_test/test/ct_auto_compile_SUITE_data/dummy_SUITE.erl
+++ b/lib/common_test/test/ct_auto_compile_SUITE_data/dummy_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/common_test/test/ct_basic_html_SUITE.erl b/lib/common_test/test/ct_basic_html_SUITE.erl
index a5f2e6197e..e8aae9f12a 100644
--- a/lib/common_test/test/ct_basic_html_SUITE.erl
+++ b/lib/common_test/test/ct_basic_html_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_basic_html_SUITE_data/babbling_SUITE.erl b/lib/common_test/test/ct_basic_html_SUITE_data/babbling_SUITE.erl
index 7a3ccf30e0..ae408e4ace 100644
--- a/lib/common_test/test/ct_basic_html_SUITE_data/babbling_SUITE.erl
+++ b/lib/common_test/test/ct_basic_html_SUITE_data/babbling_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/common_test/test/ct_config_SUITE.erl b/lib/common_test/test/ct_config_SUITE.erl
index 284f836517..9de135d786 100644
--- a/lib/common_test/test/ct_config_SUITE.erl
+++ b/lib/common_test/test/ct_config_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl
index d93faf6ec6..98b32ece1f 100644
--- a/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl
+++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl
index c2e06d866f..e4a839d9f5 100644
--- a/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl
+++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -35,7 +36,7 @@
%% which will return the list with the following variables:
%% localtime = the erlang:localtime() result in list [{date, Date}, {time, Time}]
%% node = erlang:node() - can be compared in the testcase
-%% now = erlang:now() - easier to compare than localtime()
+%% now = os:timestamp() - easier to compare than localtime()
%% config_server_pid - pid of the config server, should NOT change!
%% config_server_vsn - .19
%% config_server_iteration - a number of iteration config_server's loop done
diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl
index 8463fea645..2061ec8d40 100644
--- a/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl
+++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -73,7 +74,7 @@ loop(Iteration)->
[{localtime, [{date, D}, {time, T}]},
{node, erlang:node()},
{config_server_iteration, Iteration},
- {now, erlang:now()},
+ {now, os:timestamp()},
{config_server_pid, self()},
{config_server_vsn, ?vsn}],
Config2 = if Iteration rem 2 == 0->
diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl
index 19f1dab4af..5e06072bcc 100644
--- a/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl
+++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_config_info_SUITE.erl b/lib/common_test/test/ct_config_info_SUITE.erl
index 9c242a41df..8ce9d9f16e 100644
--- a/lib/common_test/test/ct_config_info_SUITE.erl
+++ b/lib/common_test/test/ct_config_info_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_config_info_SUITE_data/config_info_1_SUITE.erl b/lib/common_test/test/ct_config_info_SUITE_data/config_info_1_SUITE.erl
index 53a233b7a4..ea0e463ea6 100644
--- a/lib/common_test/test/ct_config_info_SUITE_data/config_info_1_SUITE.erl
+++ b/lib/common_test/test/ct_config_info_SUITE_data/config_info_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE.erl
index 1dab425509..fcd9b15b4b 100644
--- a/lib/common_test/test/ct_cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
index 789e48bd96..bfcc914d8c 100644
--- a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE.erl
index 8e2ee1b500..5ee1eee5a0 100644
--- a/lib/common_test/test/ct_cover_nomerge_SUITE.erl
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl
index e1fe3b5fc9..dac039a0b0 100644
--- a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl
index a77ae0c2db..e52a38c6c8 100644
--- a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl
index 0b3159f2c3..7e0674f889 100644
--- a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE.erl b/lib/common_test/test/ct_error_SUITE.erl
index 8464225284..53cfbd7118 100644
--- a/lib/common_test/test/ct_error_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -727,23 +728,25 @@ test_events(lib_error) ->
{lib_error_1_SUITE,no_lines_throw,{failed,{error,{thrown,catch_me_if_u_can}}}}},
{?eh,test_stats,{0,8,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,init_tc_error}},
- {?eh,tc_done,{lib_error_1_SUITE,init_tc_error,ok}},
- {?eh,test_stats,{1,8,{0,0}}},
+ {?eh,tc_done,{ct_framework,init_tc,
+ {framework_error,{{badmatch,[1,2]},'_'}}}},
+ {?eh,test_stats,{0,9,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,init_tc_exit}},
- {?eh,tc_done,{lib_error_1_SUITE,init_tc_exit,ok}},
- {?eh,test_stats,{2,8,{0,0}}},
+ {?eh,tc_done,{ct_framework,init_tc,{framework_error,byebye}}},
+ {?eh,test_stats,{0,10,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,init_tc_throw}},
- {?eh,tc_done,{lib_error_1_SUITE,init_tc_throw,ok}},
- {?eh,test_stats,{3,8,{0,0}}},
+ {?eh,tc_done,{ct_framework,init_tc,{framework_error,catch_me_if_u_can}}},
+ {?eh,test_stats,{0,11,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,end_tc_error}},
- {?eh,tc_done,{lib_error_1_SUITE,end_tc_error,ok}},
- {?eh,test_stats,{3,9,{0,0}}},
+ {?eh,tc_done,{ct_framework,end_tc,
+ {framework_error,{{badmatch,[1,2]},'_'}}}},
+ {?eh,test_stats,{0,12,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,end_tc_exit}},
- {?eh,tc_done,{lib_error_1_SUITE,end_tc_exit,ok}},
- {?eh,test_stats,{3,10,{0,0}}},
+ {?eh,tc_done,{ct_framework,end_tc,{framework_error,byebye}}},
+ {?eh,test_stats,{0,13,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,end_tc_throw}},
- {?eh,tc_done,{lib_error_1_SUITE,end_tc_throw,ok}},
- {?eh,test_stats,{3,11,{0,0}}},
+ {?eh,tc_done,{ct_framework,end_tc,{framework_error,catch_me_if_u_can}}},
+ {?eh,test_stats,{0,14,{0,0}}},
{?eh,tc_start,{lib_error_1_SUITE,end_per_suite}},
{?eh,tc_done,{lib_error_1_SUITE,end_per_suite,ok}},
{?eh,test_done,{'DEF','STOP_TIME'}},
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl
index 9f9a90372b..27cd3ecf3c 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl
index 879561ebb9..611ce95b48 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl
index 0ff8659269..1f2e06de9d 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl
index cfc0babb68..4f9d3017b5 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl
index 54b09e78c6..d8ffd029e3 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl
index a9649be9e0..ae9edb540d 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl
index a02090a5e8..2b31ac7eff 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl
index 0d93e46501..884395bfde 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl
index aaf29df65f..cde1571a3c 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl
index b421f7d809..5fce02aaf8 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl
index 370ac0839b..becc723c75 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl
index d95f3b235b..3c4c103fac 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl
index d8f0c48034..1b98f289a1 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl
index f292985c0c..e983c0c7b1 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/config_func_error_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/config_func_error_1_SUITE.erl
index f1025213dc..ec331d3444 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/config_func_error_1_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/config_func_error_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl
index bcbf972a36..366e3d2724 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl
index 6e6f83949d..6f1b391ae6 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -151,23 +152,32 @@ no_lines_throw(_) ->
lib_no_lines:do_throw(),
ok.
-init_tc_error(_) ->
+init_tc_error() ->
put('$test_server_framework_test',
fun(init_tc, _Default) -> lib_no_lines:do_error(), ok;
(_, Default) -> Default
- end), ok.
+ end), [].
-init_tc_exit(_) ->
+init_tc_error(_) ->
+ ok.
+
+init_tc_exit() ->
put('$test_server_framework_test',
fun(init_tc, _Default) -> lib_no_lines:do_exit(), ok;
(_, Default) -> Default
- end), ok.
+ end), [].
-init_tc_throw(_) ->
+init_tc_exit(_) ->
+ ok.
+
+init_tc_throw() ->
put('$test_server_framework_test',
fun(init_tc, _Default) -> lib_no_lines:do_throw(), ok;
(_, Default) -> Default
- end), ok.
+ end), [].
+
+init_tc_throw(_) ->
+ ok.
end_tc_error(_) ->
put('$test_server_framework_test',
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/misc_error_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/misc_error_1_SUITE.erl
index 61f3fa7e59..8ba6844b27 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/misc_error_1_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/misc_error_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl
index 534a8f34af..99f8a68517 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl
index 1451a4119e..59a319503d 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl
index a77d06815e..759b050b31 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -141,12 +142,13 @@ tc3() ->
[{timetrap,{seconds,2}}].
tc3(_) ->
- T0 = now(),
+ T0 = erlang:monotonic_time(),
ct:timetrap(infinity),
N = list_to_integer(ct:get_config(multiply)),
ct:comment(io_lib:format("Sleeping for ~w sec...", [4*N])),
ct:sleep(4000),
- Diff = timer:now_diff(now(), T0),
+ T1 = erlang:monotonic_time(),
+ Diff = erlang:convert_time_unit(T1-T0, native, micro_seconds),
if ((Diff < (N*4000000)) or (Diff > (N*4500000))) ->
exit(not_expected);
true ->
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_3_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_3_SUITE.erl
index 8271b23afe..fc4fa5b2d4 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_3_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_4_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_4_SUITE.erl
index d902454f09..b7b662cec6 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_4_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_4_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_5_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_5_SUITE.erl
index 5b931c351f..ce524a706c 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_5_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_5_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_6_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_6_SUITE.erl
index 90467ff752..d67cd00318 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_6_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_6_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_7_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_7_SUITE.erl
index 922d49c086..4701c66702 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_7_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_7_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_8_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_8_SUITE.erl
index ff138f38b5..df0ce55d7b 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_8_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_8_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_utils.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_utils.erl
index 413ea342a8..2e06cd7ecf 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_utils.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_utils.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl
index 446dd8bfdf..b3e07288dc 100644
--- a/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -81,7 +82,7 @@ init(Id, Opts) ->
-spec id(Opts :: proplists:proplist()) ->
Id :: term().
id(Opts) ->
- now().
+ os:timestamp().
%% @doc Called before init_per_suite is called. Note that this callback is
%% only called if the CTH is added before init_per_suite is run (eg. in a test
diff --git a/lib/common_test/test/ct_event_handler_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE.erl
index b759424e46..683bbf4ea6 100644
--- a/lib/common_test/test/ct_event_handler_SUITE.erl
+++ b/lib/common_test/test/ct_event_handler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl
index 54cf3a22e7..28c85ee2db 100644
--- a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl
+++ b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl
index 14ea12d579..af88e6775a 100644
--- a/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl
+++ b/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_gen_conn_SUITE.erl b/lib/common_test/test/ct_gen_conn_SUITE.erl
index 49d6edca86..82f68239d7 100644
--- a/lib/common_test/test/ct_gen_conn_SUITE.erl
+++ b/lib/common_test/test/ct_gen_conn_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl b/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl
index 96dd80e4e8..3d122f1de5 100644
--- a/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl
+++ b/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl b/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl
index 1d08ce167b..a466891f81 100644
--- a/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl
+++ b/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE.erl
index 83ac7dbbcf..1c73f3244b 100644
--- a/lib/common_test/test/ct_group_info_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE_data/group_require_1_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE_data/group_require_1_SUITE.erl
index 16df897752..50d06cd245 100644
--- a/lib/common_test/test/ct_group_info_SUITE_data/group_require_1_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE_data/group_require_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE_data/group_require_2_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE_data/group_require_2_SUITE.erl
index adb53ff564..4d06ff63b2 100644
--- a/lib/common_test/test/ct_group_info_SUITE_data/group_require_2_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE_data/group_require_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE_data/group_require_3_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE_data/group_require_3_SUITE.erl
index 1f2dfd2a30..a4069e9ff4 100644
--- a/lib/common_test/test/ct_group_info_SUITE_data/group_require_3_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE_data/group_require_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_1_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_1_SUITE.erl
index 0a81edf729..888477605f 100644
--- a/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_1_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_2_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_2_SUITE.erl
index 1ebe8bd510..ea1ac39817 100644
--- a/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_2_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_3_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_3_SUITE.erl
index 66d29802e2..974a34ef62 100644
--- a/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_3_SUITE.erl
+++ b/lib/common_test/test/ct_group_info_SUITE_data/group_timetrap_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_leader_SUITE.erl b/lib/common_test/test/ct_group_leader_SUITE.erl
index 6d54a4c004..3b9f73bb28 100644
--- a/lib/common_test/test/ct_group_leader_SUITE.erl
+++ b/lib/common_test/test/ct_group_leader_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_group_leader_SUITE_data/group_leader_SUITE.erl b/lib/common_test/test/ct_group_leader_SUITE_data/group_leader_SUITE.erl
index bfdc78639e..af9fa31926 100644
--- a/lib/common_test/test/ct_group_leader_SUITE_data/group_leader_SUITE.erl
+++ b/lib/common_test/test/ct_group_leader_SUITE_data/group_leader_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_search_SUITE.erl b/lib/common_test/test/ct_groups_search_SUITE.erl
index 6b1c1f4634..ac1659e3c5 100644
--- a/lib/common_test/test/ct_groups_search_SUITE.erl
+++ b/lib/common_test/test/ct_groups_search_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_1_SUITE.erl b/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_1_SUITE.erl
index 1c5b572f92..27291e7269 100644
--- a/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_1_SUITE.erl
+++ b/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_2_SUITE.erl b/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_2_SUITE.erl
index 060012de29..7e3886b665 100644
--- a/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_2_SUITE.erl
+++ b/lib/common_test/test/ct_groups_search_SUITE_data/groups_search_dummy_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_spec_SUITE.erl b/lib/common_test/test/ct_groups_spec_SUITE.erl
index de4ab77229..363a3c6bf0 100644
--- a/lib/common_test/test/ct_groups_spec_SUITE.erl
+++ b/lib/common_test/test/ct_groups_spec_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_spec_SUITE_data/groups_spec_1_SUITE.erl b/lib/common_test/test/ct_groups_spec_SUITE_data/groups_spec_1_SUITE.erl
index ae6065bae4..909e203099 100644
--- a/lib/common_test/test/ct_groups_spec_SUITE_data/groups_spec_1_SUITE.erl
+++ b/lib/common_test/test/ct_groups_spec_SUITE_data/groups_spec_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE.erl
index d5de949554..143fe3e354 100644
--- a/lib/common_test/test/ct_groups_test_1_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl
index c69400e938..889d44c33a 100644
--- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl
index 6f49f9a957..2e2385b21a 100644
--- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl
index 42b10d1803..039517227f 100644
--- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl
index ec0adc5df0..596ae25f05 100644
--- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE.erl
index f41395e028..d8075ffc97 100644
--- a/lib/common_test/test/ct_groups_test_2_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl
index e7f48daaee..e50e131248 100644
--- a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl
index b4b9b03ca5..2b9ef5a357 100644
--- a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl
index 2533ac8e84..0138310c36 100644
--- a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl
index 80bb5ba69b..ea3db09d9e 100644
--- a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl
index d5ad8312e6..8353f5936c 100644
--- a/lib/common_test/test/ct_hooks_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -323,6 +324,8 @@ test_events(one_empty_cth) ->
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
{?eh,cth,{empty_cth,pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,[test_case,'$proplist','_',[]]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,[test_case,'$proplist',[]]}},
{?eh,cth,{empty_cth,post_end_per_testcase,[test_case,'$proplist','_',[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl
index b5541f2053..c7cda285be 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl
index 596b4fade0..023f6440c2 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl
@@ -1,34 +1,35 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(crash_init_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--export([init/2]).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts),
- exit(diediedie).
-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(crash_init_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([init/2]).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts),
+ exit(diediedie).
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl
index dcba113eab..c443700dde 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl
@@ -1,47 +1,49 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(ct_cth_empty_SUITE).
-
--suite_defaults([{timetrap, {minutes, 10}}]).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include("ct.hrl").
-
-%% Test server callback functions
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_testcase(_TestCase, Config) ->
- Config.
-
-end_per_testcase(_TestCase, _Config) ->
- ok.
-
-all() ->
- [test_case].
-
-%% Test cases starts here.
-test_case(Config) when is_list(Config) ->
- ok.
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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_cth_empty_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl
index 7b84c246ca..1761b6f8ed 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl
index 48816523c7..09cd89a217 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_prio_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_prio_SUITE.erl
index d564398cd0..3569f378c6 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_prio_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_prio_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_data_dir_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_data_dir_SUITE.erl
index 66074c20c0..f6b1eab9b6 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_data_dir_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_data_dir_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl
index 6fa77128ab..480cd32cb8 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl
index fb8c420b8e..24f1122e56 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl
index 18af37096a..1800751d71 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl
index a34474ebfd..ead7e42133 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl
index a3a8f2602f..1eef06419a 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl
index 3f643d6709..a0336be61c 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl
index 1c942937eb..71a0db3e3f 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl
index 5aa6b0132d..25523e06f4 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl
index 482e87a54f..33dbac2ed1 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl
index 7b4c9b3fab..06b256a77d 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl
index 3c1f5669e8..5e4df0b3c2 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl
@@ -1,56 +1,59 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(ct_update_config_SUITE).
-
--suite_defaults([{timetrap, {minutes, 10}}]).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include("ct.hrl").
-
-%% Test server callback functions
-init_per_suite(Config) ->
- [{init_per_suite,now()}|Config].
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_testcase(_TestCase, Config) ->
- [{init_per_testcase,now()}|Config].
-
-end_per_testcase(_TestCase, _Config) ->
- ok.
-
-init_per_group(GroupName, Config) ->
- [{init_per_group,now()}|Config].
-
-end_per_group(GroupName, Config) ->
- ok.
-
-all() ->
- [{group,group1}].
-
-groups() ->
- [{group1,[],[test_case]}].
-
-%% Test cases starts here.
-test_case(Config) when is_list(Config) ->
- ok.
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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_update_config_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+-define(now, ct_test_support:unique_timestamp()).
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ [{init_per_suite,?now}|Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ [{init_per_testcase,?now}|Config].
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+init_per_group(GroupName, Config) ->
+ [{init_per_group,?now}|Config].
+
+end_per_group(GroupName, Config) ->
+ ok.
+
+all() ->
+ [{group,group1}].
+
+groups() ->
+ [{group1,[],[test_case]}].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl
index 80ce248418..dbbee365dc 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
index 77783fccf5..8b64ff8060 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -49,6 +50,8 @@
-export([post_end_per_group/4]).
-export([pre_init_per_testcase/3]).
+-export([post_init_per_testcase/4]).
+-export([pre_end_per_testcase/3]).
-export([post_end_per_testcase/4]).
-export([on_tc_fail/3]).
@@ -87,7 +90,7 @@ id(Opts) ->
gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, id, [Opts]}}),
ct:log("~w:id called", [?MODULE]),
- now().
+ ct_test_support:unique_timestamp().
%% @doc Called before init_per_suite is called. Note that this callback is
%% only called if the CTH is added before init_per_suite is run (eg. in a test
@@ -207,7 +210,7 @@ post_end_per_group(Group,Config,Return,State) ->
ct:log("~w:post_end_per_group(~w) called", [?MODULE,Group]),
{Return, State}.
-%% @doc Called before each test case.
+%% @doc Called before init_per_testcase/2 for each test case.
%% You can change the config in this function.
-spec pre_init_per_testcase(TC :: atom(),
Config :: config(),
@@ -221,8 +224,36 @@ pre_init_per_testcase(TC,Config,State) ->
ct:log("~w:pre_init_per_testcase(~w) called", [?MODULE,TC]),
{Config, State}.
-%% @doc Called after each test case. Note that the config cannot be
-%% changed here, only the status of the test case.
+%% @doc Called after init_per_testcase/2, and before the test case.
+-spec post_init_per_testcase(TC :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_testcase(TC,Config,Return,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_init_per_testcase,
+ [TC,Config,Return,State]}}),
+ ct:log("~w:post_init_per_testcase(~w) called", [?MODULE,TC]),
+ {Return, State}.
+
+%% @doc Called before end_per_testacse/2. No skip or fail allowed here,
+%% only config additions.
+-spec pre_end_per_testcase(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config(), NewState :: #state{}}.
+pre_end_per_testcase(TC,Config,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, pre_end_per_testcase,
+ [TC,Config,State]}}),
+ ct:log("~w:pre_end_per_testcase(~w) called", [?MODULE,TC]),
+ {Config, State}.
+
+%% @doc Called after end_per_testcase/2 for each test case. Note that
+%% the config cannot be changed here, only the status of the test case.
-spec post_end_per_testcase(TC :: atom(),
Config :: config(),
Return :: term(),
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
index 5af9906df0..dc5806d23d 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
index 8227b408cd..a79f4d4541 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
@@ -1,72 +1,79 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(fail_pre_suite_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State),
- {{fail, "Test failure"}, State}.
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(fail_pre_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {{fail, "Test failure"}, State}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl
index 1e222c1dbf..8e39123fc1 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl
index b87da4e330..a084423cf3 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl
@@ -1,33 +1,34 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(minimal_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--export([init/2]).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(minimal_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([init/2]).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
index 436470f46d..7895c43aeb 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
@@ -1,42 +1,43 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(minimal_terminate_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--export([init/2]).
--export([terminate/1]).
--export([on_tc_skip/3]).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
-
-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(minimal_terminate_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([init/2]).
+-export([terminate/1]).
+-export([on_tc_skip/3]).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
+
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl
index 82511ab0d3..72d6d186ed 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl
@@ -1,74 +1,81 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(prio_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-id(Opts) ->
- empty_cth:id(Opts).
-
-init(Id, Opts) ->
- {ok, [Prio|_] = State} = empty_cth:init(Id, Opts),
- {ok, State, Prio}.
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(prio_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+id(Opts) ->
+ empty_cth:id(Opts).
+
+init(Id, Opts) ->
+ {ok, [Prio|_] = State} = empty_cth:init(Id, Opts),
+ {ok, State, Prio}.
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
index 2629448943..cf484d3cd7 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
@@ -1,74 +1,81 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(recover_post_suite_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State).
-
-post_init_per_suite(Suite,Config,{'EXIT',Reason} = Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State),
- {lists:keydelete(tc_status,1,Config),State};
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(recover_post_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,{'EXIT',Reason} = Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {lists:keydelete(tc_status,1,Config),State};
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
index 49b1b9cada..60615d97fc 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
@@ -1,75 +1,82 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(same_id_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-id(Opts) ->
- empty_cth:id(Opts),
- ?MODULE.
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(same_id_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+id(Opts) ->
+ empty_cth:id(Opts),
+ ?MODULE.
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
index 770fec0a51..56163e730c 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
@@ -1,72 +1,79 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(skip_post_suite_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State),
- {{skip, "Test skip"}, State}.
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(skip_post_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {{skip, "Test skip"}, State}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl
index ece4eb2247..deb622b316 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl
@@ -1,74 +1,81 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(skip_pre_end_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State),
- {{skip, "Test skip"}, State}.
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State),
- {{skip, "Test skip"}, State}.
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(skip_pre_end_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State),
+ {{skip, "Test skip"}, State}.
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State),
+ {{skip, "Test skip"}, State}.
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
index 60b1a558ae..ea1d485700 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
@@ -1,73 +1,80 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(skip_pre_suite_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State),
- {{skip, "Test skip"}, State}.
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(skip_pre_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {{skip, "Test skip"}, State}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
index 9da48d3a4c..c2135bbbee 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
@@ -1,83 +1,92 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(state_update_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- State = empty_cth:init(Id, Opts),
- {ok, [init|State]}.
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State),
- {Config, [pre_init_per_suite|State]}.
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State),
- {Config, [post_init_per_suite|State]}.
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State),
- {Config, [pre_end_per_suite|State]}.
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State),
- {Return, [post_end_per_suite|State]}.
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State),
- {Config, [pre_init_per_group|State]}.
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State),
- {Return, [post_init_per_group|State]}.
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State),
- {Config, [pre_end_per_group|State]}.
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State),
- {Return, [post_end_per_group|State]}.
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State),
- {Config, [pre_init_per_testcase|State]}.
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State),
- {Return, [post_end_per_testcase|State]}.
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State),
- [on_tc_fail|State].
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State),
- [on_tc_skip|State].
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(state_update_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ State = empty_cth:init(Id, Opts),
+ {ok, [init|State]}.
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {Config, [pre_init_per_suite|State]}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {Config, [post_init_per_suite|State]}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State),
+ {Config, [pre_end_per_suite|State]}.
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State),
+ {Return, [post_end_per_suite|State]}.
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State),
+ {Config, [pre_init_per_group|State]}.
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State),
+ {Return, [post_init_per_group|State]}.
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State),
+ {Config, [pre_end_per_group|State]}.
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State),
+ {Return, [post_end_per_group|State]}.
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State),
+ {Config, [pre_init_per_testcase|State]}.
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State),
+ {Return, [post_init_per_testcase|State]}.
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State),
+ {Config, [pre_end_per_testcase|State]}.
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State),
+ {Return, [post_end_per_testcase|State]}.
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State),
+ [on_tc_fail|State].
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State),
+ [on_tc_skip|State].
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
index cd561771d5..5ac4bdddf8 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
@@ -1,71 +1,78 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(undef_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-pre_init_per_suite(_Suite, _Config, _State) ->
- lists:flaten([1,2,[3,4]]).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(undef_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(_Suite, _Config, _State) ->
+ lists:flaten([1,2,[3,4]]).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
index 2ee0d7da9c..928bedfed1 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
@@ -1,82 +1,92 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
--module(update_config_cth).
-
-
--include_lib("common_test/src/ct_util.hrl").
--include_lib("common_test/include/ct_event.hrl").
-
-
-%% CT Hooks
--compile(export_all).
-
-init(Id, Opts) ->
- empty_cth:init(Id, Opts).
-
-pre_init_per_suite(Suite, Config, State) ->
- empty_cth:pre_init_per_suite(Suite,Config,State),
- {[{pre_init_per_suite,now()}|Config],State}.
-
-post_init_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_init_per_suite(Suite,Config,Return,State),
- {[{post_init_per_suite,now()}|Return],State}.
-
-pre_end_per_suite(Suite,Config,State) ->
- empty_cth:pre_end_per_suite(Suite,Config,State),
- {[{pre_end_per_suite,now()}|Config],State}.
-
-post_end_per_suite(Suite,Config,Return,State) ->
- empty_cth:post_end_per_suite(Suite,Config,Return,State),
- NewConfig = [{post_end_per_suite,now()}|Config],
- {NewConfig,NewConfig}.
-
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State),
- {[{pre_init_per_group,now()}|Config],State}.
-
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State),
- {[{post_init_per_group,now()}|Return],State}.
-
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State),
- {[{pre_end_per_group,now()}|Config],State}.
-
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State),
- {[{post_end_per_group,now()}|Config],State}.
-
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State),
- {[{pre_init_per_testcase,now()}|Config],State}.
-
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State),
- {[{post_end_per_testcase,now()}|Config],State}.
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(update_config_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(now, ct_test_support:unique_timestamp()).
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {[{pre_init_per_suite,?now}|Config],State}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {[{post_init_per_suite,?now}|Return],State}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State),
+ {[{pre_end_per_suite,?now}|Config],State}.
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State),
+ NewConfig = [{post_end_per_suite,?now}|Config],
+ {NewConfig,NewConfig}.
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State),
+ {[{pre_init_per_group,?now}|Config],State}.
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State),
+ {[{post_init_per_group,?now}|Return],State}.
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State),
+ {[{pre_end_per_group,?now}|Config],State}.
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State),
+ {[{post_end_per_group,?now}|Config],State}.
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State),
+ {[{pre_init_per_testcase,?now}|Config],State}.
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State),
+ {[{post_init_per_testcase,?now}|Config],State}.
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State),
+ {[{pre_end_per_testcase,?now}|Config],State}.
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State),
+ {[{post_end_per_testcase,?now}|Config],State}.
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl
index f6de69f321..1df212f266 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl
@@ -1,130 +1,139 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(verify_config_cth).
-
--include_lib("common_test/src/ct_util.hrl").
-
-%% CT Hooks
--compile(export_all).
-
--define(val(K, L), proplists:get_value(K, L)).
-
-id(Opts) ->
- ?MODULE.
-
-init(Id, Opts) ->
- {ok, State} = empty_cth:init(Id, Opts),
- {ok, State}.
-
-pre_init_per_suite(Suite, Config, State) ->
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- empty_cth:pre_init_per_suite(Suite,
- [{pre_init_per_suite,true} | Config],
- State).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- true = ?val(pre_init_per_suite, Return),
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- empty_cth:post_init_per_suite(Suite,
- Config,
- [{post_init_per_suite,true} | Return],
- State).
-
-pre_end_per_suite(Suite,Config,State) ->
- true = ?val(post_init_per_suite, Config),
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- empty_cth:pre_end_per_suite(Suite,
- [{pre_end_per_suite,true} | Config],
- State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- true = ?val(pre_end_per_suite, Config),
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- true = ?val(post_init_per_suite, Config),
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- test_group = ct:get_config(group_cfg),
- empty_cth:pre_init_per_group(Group,
- [{pre_init_per_group,true} | Config],
- State).
-
-post_init_per_group(Group,Config,Return,State) ->
- true = ?val(pre_init_per_group, Return),
- test_group = ct:get_config(group_cfg),
- empty_cth:post_init_per_group(Group,
- Config,
- [{post_init_per_group,true} | Return],
- State).
-
-pre_end_per_group(Group,Config,State) ->
- true = ?val(post_init_per_group, Config),
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- test_group = ct:get_config(group_cfg),
- empty_cth:pre_end_per_group(Group,
- [{pre_end_per_group,true} | Config],
- State).
-
-post_end_per_group(Group,Config,Return,State) ->
- true = ?val(pre_end_per_group, Config),
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- test_group = ct:get_config(group_cfg),
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- true = ?val(post_init_per_suite, Config),
- case ?val(name, ?val(tc_group_properties, Config)) of
- undefined ->
- ok;
- _ ->
- true = ?val(post_init_per_group, Config),
- test_group = ct:get_config(group_cfg)
- end,
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"),
- TC = ct:get_config(CfgKey),
- empty_cth:pre_init_per_testcase(TC,
- [{pre_init_per_testcase,true} | Config],
- State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- true = ?val(post_init_per_suite, Config),
- true = ?val(pre_init_per_testcase, Config),
- case ?val(name, ?val(tc_group_properties, Config)) of
- undefined ->
- ok;
- _ ->
- true = ?val(post_init_per_group, Config),
- test_group = ct:get_config(group_cfg)
- end,
- ct_no_config_SUITE = ct:get_config(suite_cfg),
- CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"),
- TC = ct:get_config(CfgKey),
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(verify_config_cth).
+
+-include_lib("common_test/src/ct_util.hrl").
+
+%% CT Hooks
+-compile(export_all).
+
+-define(val(K, L), proplists:get_value(K, L)).
+
+id(Opts) ->
+ ?MODULE.
+
+init(Id, Opts) ->
+ {ok, State} = empty_cth:init(Id, Opts),
+ {ok, State}.
+
+pre_init_per_suite(Suite, Config, State) ->
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ empty_cth:pre_init_per_suite(Suite,
+ [{pre_init_per_suite,true} | Config],
+ State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ true = ?val(pre_init_per_suite, Return),
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ empty_cth:post_init_per_suite(Suite,
+ Config,
+ [{post_init_per_suite,true} | Return],
+ State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ true = ?val(post_init_per_suite, Config),
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ empty_cth:pre_end_per_suite(Suite,
+ [{pre_end_per_suite,true} | Config],
+ State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ true = ?val(pre_end_per_suite, Config),
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ true = ?val(post_init_per_suite, Config),
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ test_group = ct:get_config(group_cfg),
+ empty_cth:pre_init_per_group(Group,
+ [{pre_init_per_group,true} | Config],
+ State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ true = ?val(pre_init_per_group, Return),
+ test_group = ct:get_config(group_cfg),
+ empty_cth:post_init_per_group(Group,
+ Config,
+ [{post_init_per_group,true} | Return],
+ State).
+
+pre_end_per_group(Group,Config,State) ->
+ true = ?val(post_init_per_group, Config),
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ test_group = ct:get_config(group_cfg),
+ empty_cth:pre_end_per_group(Group,
+ [{pre_end_per_group,true} | Config],
+ State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ true = ?val(pre_end_per_group, Config),
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ test_group = ct:get_config(group_cfg),
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ true = ?val(post_init_per_suite, Config),
+ case ?val(name, ?val(tc_group_properties, Config)) of
+ undefined ->
+ ok;
+ _ ->
+ true = ?val(post_init_per_group, Config),
+ test_group = ct:get_config(group_cfg)
+ end,
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"),
+ TC = ct:get_config(CfgKey),
+ empty_cth:pre_init_per_testcase(TC,
+ [{pre_init_per_testcase,true} | Config],
+ State).
+
+%%! TODO: Verify Config also in post_init and pre_end!
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ true = ?val(post_init_per_suite, Config),
+ true = ?val(pre_init_per_testcase, Config),
+ case ?val(name, ?val(tc_group_properties, Config)) of
+ undefined ->
+ ok;
+ _ ->
+ true = ?val(post_init_per_group, Config),
+ test_group = ct:get_config(group_cfg)
+ end,
+ ct_no_config_SUITE = ct:get_config(suite_cfg),
+ CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"),
+ TC = ct:get_config(CfgKey),
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl
index 279a04b9a9..7abcea4393 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl
@@ -1,95 +1,104 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(verify_data_dir_cth).
-
--include_lib("common_test/src/ct_util.hrl").
-
-%% CT Hooks
--compile(export_all).
-
--define(val(K, L), proplists:get_value(K, L)).
-
-check_dirs(State,Config) ->
- DataDirName = ?val(data_dir_name, State),
- %% check priv_dir
- PrivDir = proplists:get_value(priv_dir, Config),
- "log_private" = filename:basename(PrivDir),
- {ok,_} = file:list_dir(PrivDir),
-
- %% check data_dir
- DataDir = proplists:get_value(data_dir, Config),
- DataDirName = filename:basename(DataDir),
- ok.
-
-id(_Opts) ->
- ?MODULE.
-
-init(Id, _Opts) ->
- {ok, _State} = empty_cth:init(Id, []),
- {ok, [{data_dir_name,"ct_data_dir_SUITE_data"}]}.
-
-pre_init_per_suite(Suite,Config,State) ->
- check_dirs(State,Config),
- empty_cth:pre_init_per_suite(Suite,Config,State).
-
-post_init_per_suite(Suite,Config,Return,State) ->
- check_dirs(State,Return),
- empty_cth:post_init_per_suite(Suite,Config,Return,State).
-
-pre_end_per_suite(Suite,Config,State) ->
- check_dirs(State,Config),
- empty_cth:pre_end_per_suite(Suite,Config,State).
-
-post_end_per_suite(Suite,Config,Return,State) ->
- check_dirs(State,Config),
- empty_cth:post_end_per_suite(Suite,Config,Return,State).
-
-pre_init_per_group(Group,Config,State) ->
- check_dirs(State,Config),
- empty_cth:pre_init_per_group(Group,Config,State).
-
-post_init_per_group(Group,Config,Return,State) ->
- check_dirs(State,Return),
- empty_cth:post_init_per_group(Group,Config,Return,State).
-
-pre_end_per_group(Group,Config,State) ->
- check_dirs(State,Config),
- empty_cth:pre_end_per_group(Group,Config,State).
-
-post_end_per_group(Group,Config,Return,State) ->
- check_dirs(State,Config),
- empty_cth:post_end_per_group(Group,Config,Return,State).
-
-pre_init_per_testcase(TC,Config,State) ->
- check_dirs(State,Config),
- empty_cth:pre_init_per_testcase(TC,Config,State).
-
-post_end_per_testcase(TC,Config,Return,State) ->
- check_dirs(State,Config),
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
-
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
-
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
-
-terminate(State) ->
- empty_cth:terminate(State).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(verify_data_dir_cth).
+
+-include_lib("common_test/src/ct_util.hrl").
+
+%% CT Hooks
+-compile(export_all).
+
+-define(val(K, L), proplists:get_value(K, L)).
+
+check_dirs(State,Config) ->
+ DataDirName = ?val(data_dir_name, State),
+ %% check priv_dir
+ PrivDir = proplists:get_value(priv_dir, Config),
+ "log_private" = filename:basename(PrivDir),
+ {ok,_} = file:list_dir(PrivDir),
+
+ %% check data_dir
+ DataDir = proplists:get_value(data_dir, Config),
+ DataDirName = filename:basename(DataDir),
+ ok.
+
+id(_Opts) ->
+ ?MODULE.
+
+init(Id, _Opts) ->
+ {ok, _State} = empty_cth:init(Id, []),
+ {ok, [{data_dir_name,"ct_data_dir_SUITE_data"}]}.
+
+pre_init_per_suite(Suite,Config,State) ->
+ check_dirs(State,Config),
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ check_dirs(State,Return),
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ check_dirs(State,Config),
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ check_dirs(State,Config),
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ check_dirs(State,Config),
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ check_dirs(State,Return),
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ check_dirs(State,Config),
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ check_dirs(State,Config),
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ check_dirs(State,Config),
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ check_dirs(State,Config),
+ empty_cth:post_init_per_testcase(TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ check_dirs(State,Config),
+ empty_cth:pre_end_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ check_dirs(State,Config),
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_master_SUITE.erl b/lib/common_test/test/ct_master_SUITE.erl
index e90513f888..15b49c67c0 100644
--- a/lib/common_test/test/ct_master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
index df54c4419c..e16d629ecc 100644
--- a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_misc_1_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE.erl
index 9ff4e6a65f..1db8bcc794 100644
--- a/lib/common_test/test/ct_misc_1_SUITE.erl
+++ b/lib/common_test/test/ct_misc_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl
index 382bdefded..ef1defe6ef 100644
--- a/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl
+++ b/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl
index 70c1f2b471..50b2f3ed10 100644
--- a/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl
+++ b/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_netconfc_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE.erl
index c89a4cdabe..af215b72b7 100644
--- a/lib/common_test/test/ct_netconfc_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -63,7 +64,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[
- default
+ netconfc1_SUITE,
+ netconfc_remote_SUITE
].
%%--------------------------------------------------------------------
@@ -72,14 +74,21 @@ all() ->
%%%-----------------------------------------------------------------
%%%
-default(Config) when is_list(Config) ->
+netconfc1_SUITE(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
Suite = filename:join(DataDir, "netconfc1_SUITE"),
CfgFile = filename:join(DataDir, "netconfc1.cfg"),
{Opts,ERPid} = setup([{suite,Suite},{config,CfgFile},
- {label,default}], Config),
+ {label,netconfc1_SUITE}], Config),
+
+ ok = execute(netconfc1_SUITE, Opts, ERPid, Config).
+
+netconfc_remote_SUITE(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suite = filename:join(DataDir, "netconfc_remote_SUITE"),
+ {Opts,ERPid} = setup([{suite,Suite},{label,netconfc_remote_SUITE}], Config),
- ok = execute(default, Opts, ERPid, Config).
+ ok = execute(netconfc_remote_SUITE, Opts, ERPid, Config).
%%%-----------------------------------------------------------------
@@ -112,16 +121,15 @@ reformat(Events, EH) ->
%%%-----------------------------------------------------------------
%%% TEST EVENTS
%%%-----------------------------------------------------------------
-events_to_check(default,Config) ->
- {module,_} = code:load_abs(filename:join(?config(data_dir,Config),
- netconfc1_SUITE)),
- TCs = netconfc1_SUITE:all(),
- code:purge(netconfc1_SUITE),
- code:delete(netconfc1_SUITE),
+events_to_check(Suite,Config) ->
+ {module,_} = code:load_abs(filename:join(?config(data_dir,Config),Suite)),
+ TCs = Suite:all(),
+ code:purge(Suite),
+ code:delete(Suite),
OneTest =
[{?eh,start_logging,{'DEF','RUNDIR'}}] ++
- [{?eh,tc_done,{netconfc1_SUITE,TC,ok}} || TC <- TCs] ++
+ [{?eh,tc_done,{Suite,TC,ok}} || TC <- TCs] ++
[{?eh,stop_logging,[]}],
%% 2 tests (ct:run_test + script_start) is default
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
index d01211b0c6..9d4c798795 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
@@ -1,18 +1,19 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,27 +31,13 @@
-module(netconfc1_SUITE).
-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/src/ct_netconfc.hrl").
--include_lib("public_key/include/public_key.hrl").
+-include("netconfc_test_lib.hrl").
-compile(export_all).
-%% Default timetrap timeout (set in init_per_testcase).
--define(default_timeout, ?t:minutes(1)).
-
--define(NS,ns).
--define(LOCALHOST, "127.0.0.1").
--define(SSH_PORT, 2060).
-
--define(DEFAULT_SSH_OPTS,[{ssh,?LOCALHOST},
- {port,?SSH_PORT},
- {user,"xxx"},
- {password,"xxx"}]).
--define(DEFAULT_SSH_OPTS(Dir), ?DEFAULT_SSH_OPTS++[{user_dir,Dir}]).
-
--define(ok,ok).
-
suite() ->
- [{ct_hooks, [{cth_conn_log,
+ [{timetrap,?default_timeout},
+ {ct_hooks, [{cth_conn_log,
[{ct_netconfc,[{log_type,html}, %will be overwritten by config
{hosts,[my_named_connection,netconf1]}]
}]
@@ -86,11 +73,14 @@ all() ->
invalid_opt,
timeout_close_session,
get,
+ get_a_lot,
timeout_get,
+ flush_timeout_get,
get_xpath,
get_config,
get_config_xpath,
edit_config,
+ edit_config_opt_params,
copy_config,
delete_config,
lock,
@@ -109,7 +99,10 @@ all() ->
connection_crash,
get_event_streams,
create_subscription,
- receive_event
+ receive_one_event,
+ receive_multiple_events,
+ receive_event_and_rpc,
+ receive_event_and_rpc_in_chunks
]
end.
@@ -125,19 +118,16 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_Case, Config) ->
ets:delete_all_objects(ns_tab),
- Dog = test_server:timetrap(?default_timeout),
- [{watchdog, Dog}|Config].
+ Config.
-end_per_testcase(_Case, Config) ->
- Dog=?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
+end_per_testcase(_Case, _Config) ->
ok.
init_per_suite(Config) ->
case catch {crypto:start(), ssh:start()} of
{ok, ok} ->
- {ok, _} = get_id_keys(Config),
- make_dsa_files(Config),
+ {ok, _} = netconfc_test_lib:get_id_keys(Config),
+ netconfc_test_lib:make_dsa_files(Config),
Server = ?NS:start(?config(data_dir,Config)),
[{server,Server}|Config];
_ ->
@@ -148,7 +138,7 @@ end_per_suite(Config) ->
?NS:stop(?config(server,Config)),
ssh:stop(),
crypto:stop(),
- remove_id_keys(Config),
+ netconfc_test_lib:remove_id_keys(Config),
Config.
hello(Config) ->
@@ -342,7 +332,8 @@ invalid_opt(Config) ->
Opts1 = ?DEFAULT_SSH_OPTS(DataDir) ++ [{timeout,invalidvalue}],
{error,{invalid_option,{timeout,invalidvalue}}} = ct_netconfc:open(Opts1),
Opts2 = ?DEFAULT_SSH_OPTS(DataDir) ++ [{some_other_opt,true}],
- {error,{invalid_option,{some_other_opt,true}}} = ct_netconfc:open(Opts2),
+ {error,{ssh,could_not_connect_to_server,{options,_}}} =
+ ct_netconfc:open(Opts2),
ok.
timeout_close_session(Config) ->
@@ -364,6 +355,19 @@ get(Config) ->
?ok = ct_netconfc:close_session(Client),
ok.
+get_a_lot(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+ Descr = lists:append(lists:duplicate(1000,"Description of myserver! ")),
+ Server = {server,[{xmlns,"myns"}],[{name,[],["myserver"]},
+ {description,[],[Descr]}]},
+ Data = lists:duplicate(100,Server),
+ ?NS:expect_reply('get',{fragmented,{data,Data}}),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+ ok.
+
timeout_get(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
@@ -373,6 +377,28 @@ timeout_get(Config) ->
?ok = ct_netconfc:close_session(Client),
ok.
+%% Test OTP-13008 "ct_netconfc crash when receiving unknown timeout"
+%% If the timer expires "at the same time" as the rpc reply is
+%% received, the timeout message might already be sent when the timer
+%% is cancelled. This test checks that the timeout message is flushed
+%% from the message queue. If it isn't, the client crashes and the
+%% session can not be closed afterwards.
+%% Note that we can only hope that the test case triggers the problem
+%% every now and then, as it is very timing dependent...
+flush_timeout_get(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+ Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}],
+ ?NS:expect_reply('get',{data,Data}),
+ timer:sleep(1000),
+ case ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]},1) of
+ {error,timeout} -> ok; % problem not triggered
+ {ok,Data} -> ok % problem possibly triggered
+ end,
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+ ok.
+
get_xpath(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
@@ -415,6 +441,18 @@ edit_config(Config) ->
?ok = ct_netconfc:close_session(Client),
ok.
+edit_config_opt_params(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+ ?NS:expect_reply({'edit-config',{'default-operation',"none"}},ok),
+ ?ok = ct_netconfc:edit_config(Client,running,
+ {server,[{xmlns,"myns"}],
+ [{name,["myserver"]}]},
+ [{'default-operation',["none"]}]),
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+ ok.
+
copy_config(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
@@ -930,16 +968,16 @@ create_subscription(Config) ->
ok.
-receive_event(Config) ->
+receive_one_event(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
?NS:expect_reply({'create-subscription',[stream]},ok),
?ok = ct_netconfc:create_subscription(Client),
- ?NS:hupp(send_event),
+ ?NS:hupp({send_events,1}),
receive
- %% Matching ?NS:make_msg(event)
+ %% Matching ?NS:make_msg({event,_})
{notification,?NETCONF_NOTIF_NAMESPACE_ATTR,
[{eventTime,[],[_Time]},
{event,[{xmlns,"http://my.namespaces.com/event"}],
@@ -957,6 +995,187 @@ receive_event(Config) ->
ok.
+receive_multiple_events(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+ ?NS:expect_reply({'create-subscription',[stream]},ok),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ ?NS:hupp({send_events,3}),
+
+ receive
+ %% Matching ?NS:make_msg({event,_})
+ {notification,_,_} ->
+ ok;
+ Other1 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other1})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ receive
+ %% Matching ?NS:make_msg({event,_})
+ {notification,_,_} ->
+ ok;
+ Other2 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other2})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ receive
+ %% Matching ?NS:make_msg({event,_})
+ {notification,_,_} ->
+ ok;
+ Other3 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other3})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+
+ ok.
+
+receive_event_and_rpc(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+
+ ?NS:expect_reply({'create-subscription',[stream]},ok),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ %% Construct the data to return from netconf server - one
+ %% rpc-reply and one notification - to be sent in the same ssh
+ %% package.
+ Data = [{servers,[{xmlns,"myns"}],[{server,[],[{name,[],["myserver"]}]}]}],
+ Rpc = {'rpc-reply',?NETCONF_NAMESPACE_ATTR ++ [{'message-id',"2"}],
+ [{data,Data}]},
+ RpcXml = list_to_binary(xmerl:export_simple_element(Rpc,xmerl_xml)),
+
+ Notification =
+ {notification,?NETCONF_NOTIF_NAMESPACE_ATTR,
+ [{eventTime,["2012-06-14T14:50:54+02:00"]},
+ {event,[{xmlns,"http://my.namespaces.com/event"}],
+ [{severity,["major"]},
+ {description,["Something terrible happened"]}]}]},
+ NotifXml =
+ list_to_binary(xmerl:export_simple_element(Notification,xmerl_xml)),
+
+ ?NS:expect_reply('get',[RpcXml,NotifXml]),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+
+ receive
+ {notification,_,_} ->
+ ok;
+ Other1 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other1})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+
+
+ %% Then do the same again, but now send notification first then
+ %% the rpc-reply.
+ Rpc2 = {'rpc-reply',?NETCONF_NAMESPACE_ATTR ++ [{'message-id',"3"}],
+ [{data,Data}]},
+ RpcXml2 = list_to_binary(xmerl:export_simple_element(Rpc2,xmerl_xml)),
+ ?NS:expect_reply('get',[NotifXml,RpcXml2]),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+
+ receive
+ {notification,_,_} ->
+ ok;
+ Other2 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other2})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+
+ ok.
+
+
+receive_event_and_rpc_in_chunks(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+
+ ?NS:expect_reply({'create-subscription',[stream]},ok),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ %% Construct the data to return from netconf server
+ Data = [{servers,[{xmlns,"myns"}],
+ [{server,[],[{name,[],["server0"]}]},
+ {server,[],[{name,[],["server1"]}]},
+ {server,[],[{name,[],["server2"]}]},
+ {server,[],[{name,[],["server3"]}]},
+ {server,[],[{name,[],["server4"]}]},
+ {server,[],[{name,[],["server5"]}]},
+ {server,[],[{name,[],["server6"]}]},
+ {server,[],[{name,[],["server7"]}]},
+ {server,[],[{name,[],["server8"]}]},
+ {server,[],[{name,[],["server9"]}]}]
+ }],
+ Rpc = {'rpc-reply',?NETCONF_NAMESPACE_ATTR ++ [{'message-id',"2"}],
+ [{data,Data}]},
+ RpcXml = list_to_binary(xmerl:export_simple_element(Rpc,xmerl_xml)),
+
+ Notification =
+ {notification,?NETCONF_NOTIF_NAMESPACE_ATTR,
+ [{eventTime,["2012-06-14T14:50:54+02:00"]},
+ {event,[{xmlns,"http://my.namespaces.com/event"}],
+ [{severity,["major"]},
+ {description,["Something terrible happened"]}]}]},
+ NotifXml =
+ list_to_binary(xmerl:export_simple_element(Notification,xmerl_xml)),
+
+
+ %% First part contains a notif, but only parts of the end tag
+ Part1 =
+ <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
+ NotifXml/binary,"\n]]">>,
+
+ %% Second part contains rest of end tag, full rpc-reply and full
+ %% notif except end tag
+ Part2 =
+ <<">]]>\n",RpcXml/binary,"\n",?END_TAG/binary,NotifXml/binary>>,
+
+ %% Third part contains last end tag
+ Part3 = <<"\n",?END_TAG/binary,"\n">>,
+
+ %% Spawn a process which will wait a bit for the client to send
+ %% the request (below), then order the server to the chunks of the
+ %% rpc-reply one by one.
+ spawn(fun() -> ct:sleep(500),?NS:hupp(send,Part1),
+ ct:sleep(100),?NS:hupp(send,Part2),
+ ct:sleep(100),?NS:hupp(send,Part3)
+ end),
+
+ %% Order server to expect a get - then the process above will make
+ %% sure the rpc-reply is sent.
+ ?NS:expect('get'),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+
+ receive
+ {notification,_,_} ->
+ ok;
+ Other1 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other1})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ receive
+ {notification,_,_} ->
+ ok;
+ Other2 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other2})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+ ok.
+
%%%-----------------------------------------------------------------
break(_Config) ->
@@ -1011,165 +1230,3 @@ pad(I) when I<10 ->
"0"++integer_to_list(I);
pad(I) ->
integer_to_list(I).
-
-
-%%%-----------------------------------------------------------------
-%%% BEGIN SSH key management
-%% copy private keys to given dir from ~/.ssh
-get_id_keys(Config) ->
- DstDir = ?config(priv_dir, Config),
- SrcDir = filename:join(os:getenv("HOME"), ".ssh"),
- RsaOk = copyfile(SrcDir, DstDir, "id_rsa"),
- DsaOk = copyfile(SrcDir, DstDir, "id_dsa"),
- case {RsaOk, DsaOk} of
- {{ok, _}, {ok, _}} -> {ok, both};
- {{ok, _}, _} -> {ok, rsa};
- {_, {ok, _}} -> {ok, dsa};
- {Error, _} -> Error
- end.
-
-%% Remove later on. Use make_dsa_files instead.
-remove_id_keys(Config) ->
- Dir = ?config(priv_dir, Config),
- file:delete(filename:join(Dir, "id_rsa")),
- file:delete(filename:join(Dir, "id_dsa")).
-
-
-make_dsa_files(Config) ->
- make_dsa_files(Config, rfc4716_public_key).
-make_dsa_files(Config, Type) ->
- {DSA, EncodedKey} = gen_dsa(128, 20),
- PKey = DSA#'DSAPrivateKey'.y,
- P = DSA#'DSAPrivateKey'.p,
- Q = DSA#'DSAPrivateKey'.q,
- G = DSA#'DSAPrivateKey'.g,
- Dss = #'Dss-Parms'{p=P, q=Q, g=G},
- {ok, Hostname} = inet:gethostname(),
- {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
- IP = lists:concat([A, ".", B, ".", C, ".", D]),
- Attributes = [], % Could be [{comment,"user@" ++ Hostname}],
- HostNames = [{hostnames,[IP, IP]}],
- PublicKey = [{{PKey, Dss}, Attributes}],
- KnownHosts = [{{PKey, Dss}, HostNames}],
-
- KnownHostsEnc = public_key:ssh_encode(KnownHosts, known_hosts),
- KnownHosts = public_key:ssh_decode(KnownHostsEnc, known_hosts),
-
- PublicKeyEnc = public_key:ssh_encode(PublicKey, Type),
-
- SystemTmpDir = ?config(data_dir, Config),
- filelib:ensure_dir(SystemTmpDir),
- file:make_dir(SystemTmpDir),
-
- DSAFile = filename:join(SystemTmpDir, "ssh_host_dsa_key.pub"),
- file:delete(DSAFile),
-
- DSAPrivateFile = filename:join(SystemTmpDir, "ssh_host_dsa_key"),
- file:delete(DSAPrivateFile),
-
- KHFile = filename:join(SystemTmpDir, "known_hosts"),
- file:delete(KHFile),
-
- PemBin = public_key:pem_encode([EncodedKey]),
-
- file:write_file(DSAFile, PublicKeyEnc),
- file:write_file(KHFile, KnownHostsEnc),
- file:write_file(DSAPrivateFile, PemBin),
- ok.
-
-
-%%--------------------------------------------------------------------
-%% @doc Creates a dsa key (OBS: for testing only)
-%% the sizes are in bytes
-%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()}
-%% @end
-%%--------------------------------------------------------------------
-gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) ->
- Key = gen_dsa2(LSize, NSize),
- {Key, encode_key(Key)}.
-
-encode_key(Key = #'DSAPrivateKey'{}) ->
- Der = public_key:der_encode('DSAPrivateKey', Key),
- {'DSAPrivateKey', Der, not_encrypted}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% DSA key generation (OBS: for testing only)
-%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
-%% and the fips_186-3.pdf
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-gen_dsa2(LSize, NSize) ->
- Q = prime(NSize), %% Choose N-bit prime Q
- X0 = prime(LSize),
- P0 = prime((LSize div 2) +1),
-
- %% Choose L-bit prime modulus P such that p-1 is a multiple of q.
- case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of
- error ->
- gen_dsa2(LSize, NSize);
- P ->
- G = crypto:mod_pow(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q.
- %% such that This may be done by setting g = h^(p-1)/q mod p, commonly h=2 is used.
-
- X = prime(20), %% Choose x by some random method, where 0 < x < q.
- Y = crypto:mod_pow(G, X, P), %% Calculate y = g^x mod p.
-
- #'DSAPrivateKey'{version=0, p = P, q = Q,
- g = crypto:bytes_to_integer(G), y = crypto:bytes_to_integer(Y), x = X}
- end.
-
-%% See fips_186-3.pdf
-dsa_search(T, P0, Q, Iter) when Iter > 0 ->
- P = 2*T*Q*P0 + 1,
- case is_prime(P, 50) of
- true -> P;
- false -> dsa_search(T+1, P0, Q, Iter-1)
- end;
-dsa_search(_,_,_,_) ->
- error.
-
-
-%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-prime(ByteSize) ->
- Rand = odd_rand(ByteSize),
- prime_odd(Rand, 0).
-
-prime_odd(Rand, N) ->
- case is_prime(Rand, 50) of
- true ->
- Rand;
- false ->
- prime_odd(Rand+2, N+1)
- end.
-
-%% see http://en.wikipedia.org/wiki/Fermat_primality_test
-is_prime(_, 0) -> true;
-is_prime(Candidate, Test) ->
- CoPrime = odd_rand(10000, Candidate),
- Result = crypto:mod_pow(CoPrime, Candidate, Candidate) ,
- is_prime(CoPrime, crypto:bytes_to_integer(Result), Candidate, Test).
-
-is_prime(CoPrime, CoPrime, Candidate, Test) ->
- is_prime(Candidate, Test-1);
-is_prime(_,_,_,_) ->
- false.
-
-odd_rand(Size) ->
- Min = 1 bsl (Size*8-1),
- Max = (1 bsl (Size*8))-1,
- odd_rand(Min, Max).
-
-odd_rand(Min,Max) ->
- Rand = crypto:rand_uniform(Min,Max),
- case Rand rem 2 of
- 0 ->
- Rand + 1;
- _ ->
- Rand
- end.
-
-copyfile(SrcDir, DstDir, Fn) ->
- file:copy(filename:join(SrcDir, Fn),
- filename:join(DstDir, Fn)).
-
-%%% END SSH key management
-%%%-----------------------------------------------------------------
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl
new file mode 100644
index 0000000000..152d5c7cae
--- /dev/null
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl
@@ -0,0 +1,148 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(netconfc_remote_SUITE).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/src/ct_netconfc.hrl").
+-include("netconfc_test_lib.hrl").
+
+-compile(export_all).
+
+suite() ->
+ [{ct_hooks, [{cth_conn_log,[{ct_netconfc,[{log_type,html}]}]}]}].
+
+all() ->
+ case os:find_executable("ssh") of
+ false ->
+ {skip, "SSH not installed on host"};
+ _ ->
+ [remote_crash
+ ]
+ end.
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(Case, Config) ->
+ stop_node(Case),
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(Case, Config) ->
+ stop_node(Case),
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+stop_node(Case) ->
+ {ok,Host} = inet:gethostname(),
+ Node = list_to_atom("nc_" ++ atom_to_list(Case)++ "@" ++ Host),
+ rpc:call(Node,erlang,halt,[]).
+
+
+init_per_suite(Config) ->
+ case {crypto:start(),ssh:start()} of
+ {ok,ok} ->
+ {ok, _} = netconfc_test_lib:get_id_keys(Config),
+ netconfc_test_lib:make_dsa_files(Config),
+ Config;
+ _ ->
+ {skip, "Crypto and/or SSH could not be started locally!"}
+ end.
+
+end_per_suite(Config) ->
+ ssh:stop(),
+ crypto:stop(),
+ netconfc_test_lib:remove_id_keys(Config),
+ Config.
+
+%% This test case is related to seq12645
+%% Running the netconf server in a remote node, test that the client
+%% process terminates if the remote node goes down.
+remote_crash(Config) ->
+ {ok,Node} = ct_slave:start(nc_remote_crash),
+ Pa = filename:dirname(code:which(?NS)),
+ true = rpc:call(Node,code,add_patha,[Pa]),
+
+ case {rpc:call(Node,crypto,start,[]),rpc:call(Node,ssh,start,[])} of
+ {ok,ok} ->
+ Server = rpc:call(Node,?NS,start,[?config(data_dir,Config)]),
+ remote_crash(Node,Config);
+ _ ->
+ {skip, "Crypto and/or SSH could not be started remote!"}
+ end.
+
+remote_crash(Node,Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(Node,DataDir),
+
+ ns(Node,expect_reply,[{'create-subscription',[stream]},ok]),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ true = erlang:is_process_alive(Client),
+ Ref = erlang:monitor(process,Client),
+ rpc:call(Node,erlang,halt,[]), % take the node down as brutally as possible
+ receive {'DOWN',Ref,process,Client,_} ->
+ ok
+ after 10000 ->
+ ct:fail(client_still_alive)
+ end.
+
+%%%-----------------------------------------------------------------
+
+break(_Config) ->
+ test_server:break("break test case").
+
+%%%-----------------------------------------------------------------
+%% Open a netconf session which is not specified in a config file
+open_success(Node,Dir) ->
+ open_success(Node,Dir,[]).
+
+%% Open a netconf session which is not specified in a config file, and
+%% give som extra options in addition to the test defaults.
+open_success(Node,Dir,ExtraOpts) when is_list(Dir), is_list(ExtraOpts) ->
+ ns(Node,hello,[1]), % tell server to send hello with session id 1
+ ns(Node,expect,[hello]), % tell server to expect a hello message from client
+ open(Dir,ExtraOpts);
+
+%% Open a named netconf session which is not specified in a config file
+open_success(Node,KeyOrName,Dir) when is_atom(KeyOrName), is_list(Dir) ->
+ ns(Node,hello,[1]),
+ ns(Node,expect,[hello]),
+ ct_netconfc:open(KeyOrName,?DEFAULT_SSH_OPTS(Dir)).
+
+open(Dir) ->
+ open(Dir,[]).
+open(Dir,ExtraOpts) ->
+ Opts = lists:ukeymerge(1,lists:keysort(1,ExtraOpts),
+ lists:keysort(1,?DEFAULT_SSH_OPTS(Dir))),
+ ct_netconfc:open(Opts).
+
+%%%-----------------------------------------------------------------
+%%% Call server on remote node
+ns(Node,Func,Args) ->
+ rpc:call(Node,?NS,Func,Args).
+
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl
new file mode 100644
index 0000000000..e058bc7600
--- /dev/null
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl
@@ -0,0 +1,166 @@
+-module(netconfc_test_lib).
+
+-export([get_id_keys/1, remove_id_keys/1, make_dsa_files/1]).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%%-----------------------------------------------------------------
+%%% BEGIN SSH key management
+%% copy private keys to given dir from ~/.ssh
+get_id_keys(Config) ->
+ DstDir = ?config(priv_dir, Config),
+ SrcDir = filename:join(os:getenv("HOME"), ".ssh"),
+ RsaOk = copyfile(SrcDir, DstDir, "id_rsa"),
+ DsaOk = copyfile(SrcDir, DstDir, "id_dsa"),
+ case {RsaOk, DsaOk} of
+ {{ok, _}, {ok, _}} -> {ok, both};
+ {{ok, _}, _} -> {ok, rsa};
+ {_, {ok, _}} -> {ok, dsa};
+ {Error, _} -> Error
+ end.
+
+%% Remove later on. Use make_dsa_files instead.
+remove_id_keys(Config) ->
+ Dir = ?config(priv_dir, Config),
+ file:delete(filename:join(Dir, "id_rsa")),
+ file:delete(filename:join(Dir, "id_dsa")).
+
+
+make_dsa_files(Config) ->
+ make_dsa_files(Config, rfc4716_public_key).
+make_dsa_files(Config, Type) ->
+ {DSA, EncodedKey} = gen_dsa(128, 20),
+ PKey = DSA#'DSAPrivateKey'.y,
+ P = DSA#'DSAPrivateKey'.p,
+ Q = DSA#'DSAPrivateKey'.q,
+ G = DSA#'DSAPrivateKey'.g,
+ Dss = #'Dss-Parms'{p=P, q=Q, g=G},
+ {ok, Hostname} = inet:gethostname(),
+ {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
+ IP = lists:concat([A, ".", B, ".", C, ".", D]),
+ Attributes = [], % Could be [{comment,"user@" ++ Hostname}],
+ HostNames = [{hostnames,[IP, IP]}],
+ PublicKey = [{{PKey, Dss}, Attributes}],
+ KnownHosts = [{{PKey, Dss}, HostNames}],
+
+ KnownHostsEnc = public_key:ssh_encode(KnownHosts, known_hosts),
+ KnownHosts = public_key:ssh_decode(KnownHostsEnc, known_hosts),
+
+ PublicKeyEnc = public_key:ssh_encode(PublicKey, Type),
+
+ SystemTmpDir = ?config(data_dir, Config),
+ filelib:ensure_dir(SystemTmpDir),
+ file:make_dir(SystemTmpDir),
+
+ DSAFile = filename:join(SystemTmpDir, "ssh_host_dsa_key.pub"),
+ file:delete(DSAFile),
+
+ DSAPrivateFile = filename:join(SystemTmpDir, "ssh_host_dsa_key"),
+ file:delete(DSAPrivateFile),
+
+ KHFile = filename:join(SystemTmpDir, "known_hosts"),
+ file:delete(KHFile),
+
+ PemBin = public_key:pem_encode([EncodedKey]),
+
+ file:write_file(DSAFile, PublicKeyEnc),
+ file:write_file(KHFile, KnownHostsEnc),
+ file:write_file(DSAPrivateFile, PemBin),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% @doc Creates a dsa key (OBS: for testing only)
+%% the sizes are in bytes
+%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()}
+%% @end
+%%--------------------------------------------------------------------
+gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) ->
+ Key = gen_dsa2(LSize, NSize),
+ {Key, encode_key(Key)}.
+
+encode_key(Key = #'DSAPrivateKey'{}) ->
+ Der = public_key:der_encode('DSAPrivateKey', Key),
+ {'DSAPrivateKey', Der, not_encrypted}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% DSA key generation (OBS: for testing only)
+%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
+%% and the fips_186-3.pdf
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+gen_dsa2(LSize, NSize) ->
+ Q = prime(NSize), %% Choose N-bit prime Q
+ X0 = prime(LSize),
+ P0 = prime((LSize div 2) +1),
+
+ %% Choose L-bit prime modulus P such that p-1 is a multiple of q.
+ case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of
+ error ->
+ gen_dsa2(LSize, NSize);
+ P ->
+ G = crypto:mod_pow(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q.
+ %% such that This may be done by setting g = h^(p-1)/q mod p, commonly h=2 is used.
+
+ X = prime(20), %% Choose x by some random method, where 0 < x < q.
+ Y = crypto:mod_pow(G, X, P), %% Calculate y = g^x mod p.
+
+ #'DSAPrivateKey'{version=0, p = P, q = Q,
+ g = crypto:bytes_to_integer(G), y = crypto:bytes_to_integer(Y), x = X}
+ end.
+
+%% See fips_186-3.pdf
+dsa_search(T, P0, Q, Iter) when Iter > 0 ->
+ P = 2*T*Q*P0 + 1,
+ case is_prime(P, 50) of
+ true -> P;
+ false -> dsa_search(T+1, P0, Q, Iter-1)
+ end;
+dsa_search(_,_,_,_) ->
+ error.
+
+
+%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+prime(ByteSize) ->
+ Rand = odd_rand(ByteSize),
+ prime_odd(Rand, 0).
+
+prime_odd(Rand, N) ->
+ case is_prime(Rand, 50) of
+ true ->
+ Rand;
+ false ->
+ prime_odd(Rand+2, N+1)
+ end.
+
+%% see http://en.wikipedia.org/wiki/Fermat_primality_test
+is_prime(_, 0) -> true;
+is_prime(Candidate, Test) ->
+ CoPrime = odd_rand(10000, Candidate),
+ Result = crypto:mod_pow(CoPrime, Candidate, Candidate) ,
+ is_prime(CoPrime, crypto:bytes_to_integer(Result), Candidate, Test).
+
+is_prime(CoPrime, CoPrime, Candidate, Test) ->
+ is_prime(Candidate, Test-1);
+is_prime(_,_,_,_) ->
+ false.
+
+odd_rand(Size) ->
+ Min = 1 bsl (Size*8-1),
+ Max = (1 bsl (Size*8))-1,
+ odd_rand(Min, Max).
+
+odd_rand(Min,Max) ->
+ Rand = crypto:rand_uniform(Min,Max),
+ case Rand rem 2 of
+ 0 ->
+ Rand + 1;
+ _ ->
+ Rand
+ end.
+
+copyfile(SrcDir, DstDir, Fn) ->
+ file:copy(filename:join(SrcDir, Fn),
+ filename:join(DstDir, Fn)).
+
+%%% END SSH key management
+%%%-----------------------------------------------------------------
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.hrl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.hrl
new file mode 100644
index 0000000000..dcaad5ba93
--- /dev/null
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.hrl
@@ -0,0 +1,14 @@
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+-define(NS,ns). % netconf server module
+-define(LOCALHOST, "127.0.0.1").
+-define(SSH_PORT, 2060).
+
+-define(DEFAULT_SSH_OPTS,[{ssh,?LOCALHOST},
+ {port,?SSH_PORT},
+ {user,"xxx"},
+ {password,"xxx"}]).
+-define(DEFAULT_SSH_OPTS(Dir), ?DEFAULT_SSH_OPTS++[{user_dir,Dir}]).
+
+-define(ok,ok).
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
index 27da67bd1d..67827a053f 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
@@ -1,18 +1,19 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -143,8 +144,8 @@ expect_do_reply(SessionId,Expect,Do,Reply) ->
%% Hupp the server - i.e. tell it to do something -
%% e.g. hupp(send_event) will cause send_event(State) to be called on
%% the session channel process.
-hupp(send_event) ->
- hupp(send,[make_msg(event)]);
+hupp({send_events,N}) ->
+ hupp(send,[make_msg({event,N})]);
hupp(kill) ->
hupp(1,fun hupp_kill/1,[]).
@@ -276,6 +277,18 @@ hupp_kill(State = #session{connection = ConnRef}) ->
send({CM,Ch},Data) ->
ssh_connection:send(CM, Ch, Data).
+%%% Split into many small parts and send to client
+send_frag({CM,Ch},Data) ->
+ Sz = rand:uniform(2000),
+ case Data of
+ <<Chunk:Sz/binary,Rest/binary>> ->
+ ssh_connection:send(CM, Ch, Chunk),
+ send_frag({CM,Ch},Rest);
+ Chunk ->
+ ssh_connection:send(CM, Ch, Chunk)
+ end.
+
+
%%% Kill ssh connection
kill({CM,_Ch}) ->
ssh:close(CM).
@@ -293,7 +306,7 @@ table_trans(Fun,Args) ->
receive
{table_trans_done,Result} ->
Result
- after 5000 ->
+ after 20000 ->
exit(table_trans_timeout)
end
end.
@@ -382,6 +395,7 @@ event({startElement,_,Name,_,Attrs},[ignore,{se,Name,As}|Match]) ->
event({startPrefixMapping,_,Ns},[{ns,Ns}|Match]) -> Match;
event({startPrefixMapping,_,Ns},[ignore,{ns,Ns}|Match]) -> Match;
event({endPrefixMapping,_},Match) -> Match;
+event({characters,Chs},[{characters,Chs}|Match]) -> Match;
event({endElement,_,Name,_},[{ee,Name}|Match]) -> Match;
event({endElement,_,Name,_},[ignore,{ee,Name}|Match]) -> Match;
event(endDocument,Match) when Match==[]; Match==[ignore] -> ok;
@@ -422,6 +436,9 @@ do(_, undefined) ->
reply(_,undefined) ->
?dbg("no reply~n",[]),
ok;
+reply(ConnRef,{fragmented,Reply}) ->
+ ?dbg("Reply fragmented: ~p~n",[Reply]),
+ send_frag(ConnRef,make_msg(Reply));
reply(ConnRef,Reply) ->
?dbg("Reply: ~p~n",[Reply]),
send(ConnRef, make_msg(Reply)).
@@ -429,9 +446,12 @@ reply(ConnRef,Reply) ->
from_simple(Simple) ->
unicode_c2b(xmerl:export_simple_element(Simple,xmerl_xml)).
-xml(Content) ->
- <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
- Content/binary,"\n",?END_TAG/binary>>.
+xml(Content) when is_binary(Content) ->
+ xml([Content]);
+xml(Content) when is_list(Content) ->
+ Msgs = [<<Msg/binary,"\n",?END_TAG/binary>> || Msg <- Content],
+ MsgsBin = list_to_binary(Msgs),
+ <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", MsgsBin/binary>>.
rpc_reply(Content) when is_binary(Content) ->
MsgId = case erase(msg_id) of
@@ -471,14 +491,17 @@ capabilities(no_caps) ->
%%% expect_do_reply/3.
%%%
%%% match(term()) -> [Match].
-%%% Match = ignore | {se,Name} | {se,Name,Attrs} | {ee,Name} | {ns,Namespace}
+%%% Match = ignore | {se,Name} | {se,Name,Attrs} | {ee,Name} |
+%%% {ns,Namespace} | {characters,Chs}
%%% Name = string()
+%%% Chs = string()
%%% Attrs = [{atom(),string()}]
%%% Namespace = string()
%%%
%%% 'se' means start element, 'ee' means end element - i.e. to match
%%% an XML element you need one 'se' entry and one 'ee' entry with the
-%%% same name in the match list.
+%%% same name in the match list. 'characters' can be used for matching
+%%% character data (cdata) inside an element.
match(hello) ->
[ignore,{se,"hello"},ignore,{ee,"hello"},ignore];
match('close-session') ->
@@ -487,6 +510,10 @@ match('close-session') ->
match('edit-config') ->
[ignore,{se,"rpc"},{se,"edit-config"},{se,"target"},ignore,{ee,"target"},
{se,"config"},ignore,{ee,"config"},{ee,"edit-config"},{ee,"rpc"},ignore];
+match({'edit-config',{'default-operation',DO}}) ->
+ [ignore,{se,"rpc"},{se,"edit-config"},{se,"target"},ignore,{ee,"target"},
+ {se,"default-operation"},{characters,DO},{ee,"default-operation"},
+ {se,"config"},ignore,{ee,"config"},{ee,"edit-config"},{ee,"rpc"},ignore];
match('get') ->
match({get,subtree});
match({'get',FilterType}) ->
@@ -547,15 +574,17 @@ make_msg({ok,Data}) ->
make_msg({data,Data}) ->
xml(rpc_reply(from_simple({data,Data})));
-make_msg(event) ->
- xml(<<"<notification xmlns=\"",?NETCONF_NOTIF_NAMESPACE,"\">"
+make_msg({event,N}) ->
+ Notification = <<"<notification xmlns=\"",?NETCONF_NOTIF_NAMESPACE,"\">"
"<eventTime>2012-06-14T14:50:54+02:00</eventTime>"
"<event xmlns=\"http://my.namespaces.com/event\">"
"<severity>major</severity>"
"<description>Something terrible happened</description>"
"</event>"
- "</notification>">>);
-make_msg(Xml) when is_binary(Xml) ->
+ "</notification>">>,
+ xml(lists:duplicate(N,Notification));
+make_msg(Xml) when is_binary(Xml) orelse
+ (is_list(Xml) andalso is_binary(hd(Xml))) ->
xml(Xml);
make_msg(Simple) when is_tuple(Simple) ->
xml(from_simple(Simple)).
diff --git a/lib/common_test/test/ct_pre_post_test_io_SUITE.erl b/lib/common_test/test/ct_pre_post_test_io_SUITE.erl
index 1e6018f442..bf3eeee328 100644
--- a/lib/common_test/test/ct_pre_post_test_io_SUITE.erl
+++ b/lib/common_test/test/ct_pre_post_test_io_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -43,13 +44,29 @@
%% instance, the tests need to be performed on a separate node (or
%% there will be clashes with logging processes etc).
%%--------------------------------------------------------------------
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds,120}}].
+
+all() ->
+ [
+ pre_post_io
+ ].
+
init_per_suite(Config) ->
- DataDir = ?config(data_dir, Config),
- CTH = filename:join(DataDir, "cth_ctrl.erl"),
- ct:pal("Compiling ~p: ~p",
- [CTH,compile:file(CTH,[{outdir,DataDir},debug_info])]),
- ct_test_support:init_per_suite([{path_dirs,[DataDir]},
- {start_sasl,true} | Config]).
+ TTInfo = {_T,{_Scaled,ScaleVal}} = ct:get_timetrap_info(),
+ ct:pal("Timetrap info = ~w", [TTInfo]),
+ if ScaleVal > 1 ->
+ {skip,"Skip on systems running e.g. cover or debug!"};
+ ScaleVal =< 1 ->
+ DataDir = ?config(data_dir, Config),
+ CTH = filename:join(DataDir, "cth_ctrl.erl"),
+ ct:pal("Compiling ~p: ~p",
+ [CTH,compile:file(CTH,[{outdir,DataDir},
+ debug_info])]),
+ ct_test_support:init_per_suite([{path_dirs,[DataDir]},
+ {start_sasl,true} | Config])
+ end.
end_per_suite(Config) ->
ct_test_support:end_per_suite(Config).
@@ -60,13 +77,6 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [
- pre_post_io
- ].
-
%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------
@@ -89,31 +99,50 @@ pre_post_io(Config) ->
%%!--------------------------------------------------------------------
spawn(fun() ->
- ct:pal("CONTROLLER: Started!", []),
+ ct:pal("CONTROLLER: Starting test run #1...", []),
%% --- test run 1 ---
- ct:sleep(3000),
- ct:pal("CONTROLLER: Handle remote events = true", []),
- ok = ct_test_support:ct_rpc({cth_log_redirect,
- handle_remote_events,
- [true]}, Config),
- ct:sleep(2000),
- ct:pal("CONTROLLER: Proceeding with test run #1!", []),
+ try_loop(ct_test_support, ct_rpc, [{cth_log_redirect,
+ handle_remote_events,
+ [true]}, Config], 3000),
+ CTLoggerPid1 = ct_test_support:ct_rpc({erlang,whereis,
+ [ct_logs]}, Config),
+ ct:pal("CONTROLLER: Logger = ~w~nHandle remote events = true",
+ [CTLoggerPid1]),
+ ct:sleep(5000),
+ ct:pal("CONTROLLER: Proceeding with test run #1...", []),
ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config),
ct:sleep(6000),
- ct:pal("CONTROLLER: Proceeding with shutdown #1!", []),
+ ct:pal("CONTROLLER: Proceeding with shutdown #1...", []),
ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config),
+ try_loop(fun() ->
+ false = ct_test_support:ct_rpc({erlang,
+ is_process_alive,
+ [CTLoggerPid1]},
+ Config)
+ end, 3000),
+ ct:pal("CONTROLLER: Shutdown #1 complete!", []),
+ ct:pal("CONTROLLER: Starting test run #2...", []),
%% --- test run 2 ---
- ct:sleep(3000),
- ct:pal("CONTROLLER: Handle remote events = true", []),
- ok = ct_test_support:ct_rpc({cth_log_redirect,
- handle_remote_events,
- [true]}, Config),
- ct:sleep(2000),
- ct:pal("CONTROLLER: Proceeding with test run #2!", []),
+ try_loop(ct_test_support, ct_rpc, [{cth_log_redirect,
+ handle_remote_events,
+ [true]}, Config], 3000),
+ CTLoggerPid2 = ct_test_support:ct_rpc({erlang,whereis,
+ [ct_logs]}, Config),
+ ct:pal("CONTROLLER: Logger = ~w~nHandle remote events = true",
+ [CTLoggerPid2]),
+ ct:sleep(5000),
+ ct:pal("CONTROLLER: Proceeding with test run #2...", []),
ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config),
ct:sleep(6000),
- ct:pal("CONTROLLER: Proceeding with shutdown #2!", []),
- ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config)
+ ct:pal("CONTROLLER: Proceeding with shutdown #2...", []),
+ ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config),
+ try_loop(fun() ->
+ false = ct_test_support:ct_rpc({erlang,
+ is_process_alive,
+ [CTLoggerPid2]},
+ Config)
+ end, 3000),
+ ct:pal("CONTROLLER: Shutdown #2 complete!", [])
end),
ct_test_support:run(Opts, Config),
Events = ct_test_support:get_events(ERPid, Config),
@@ -156,7 +185,7 @@ pre_post_io(Config) ->
Counters
end, {pre,0,0,0,0}, Ts),
[_|Counters] = tuple_to_list(PrePostIOEntries),
- ct:log("Entries in the Pre/Post Test IO Log: ~p", [Counters]),
+ ct:pal("Entries in the Pre/Post Test IO Log: ~w", [Counters]),
case [C || C <- Counters, C < 2] of
[] ->
ok;
@@ -182,7 +211,7 @@ pre_post_io(Config) ->
[LogN,ErrN+1];
(_, Counters) -> Counters
end, [0,0], Ts),
- ct:log("Entries in the Unexpected IO Log: ~p", [UnexpIOEntries]),
+ ct:log("Entries in the Unexpected IO Log: ~w", [UnexpIOEntries]),
case [N || N <- UnexpIOEntries, N < 2] of
[] ->
ok;
@@ -207,6 +236,38 @@ setup(Test, Config) ->
reformat(Events, EH) ->
ct_test_support:reformat(Events, EH).
+try_loop(_Fun, 0) ->
+ ct:pal("WARNING! Fun never succeeded!", []),
+ gave_up;
+try_loop(Fun, N) ->
+ try Fun() of
+ {error,_} ->
+ timer:sleep(10),
+ try_loop(Fun, N-1);
+ Result ->
+ Result
+ catch
+ _:_What ->
+ timer:sleep(10),
+ try_loop(Fun, N-1)
+ end.
+
+try_loop(M, F, _A, 0) ->
+ ct:pal("WARNING! ~w:~w never succeeded!", [M,F]),
+ gave_up;
+try_loop(M, F, A, N) ->
+ try apply(M, F, A) of
+ {error,_} ->
+ timer:sleep(10),
+ try_loop(M, F, A, N-1);
+ Result ->
+ Result
+ catch
+ _:_ ->
+ timer:sleep(10),
+ try_loop(M, F, A, N-1)
+ end.
+
%%%-----------------------------------------------------------------
%%% TEST EVENTS
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl
index 2ba991fc61..66a950c178 100644
--- a/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl
+++ b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -52,8 +53,7 @@ init(_Id, _Opts) ->
receive
{?MODULE,proceed} -> ok
after
- 10000 ->
- ok
+ 10000 -> ok
end,
{ok,[],ct_last}.
@@ -65,8 +65,7 @@ terminate(_State) ->
receive
{?MODULE,proceed} -> ok
after
- 10000 ->
- ok
+ 10000 -> ok
end,
stop_external_logger(cth_logger),
stop_dispatcher(),
@@ -93,7 +92,7 @@ init_logger(Name) ->
logger_loop(N) ->
ct:log("Logger iteration: ~p", [N]),
error_logger:error_report(N),
- timer:sleep(250),
+ timer:sleep(100),
logger_loop(N+1).
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl
index ac9c4efd31..ad8beb2ae0 100644
--- a/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl
+++ b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_priv_dir_SUITE.erl b/lib/common_test/test/ct_priv_dir_SUITE.erl
index 426b2d9a55..c42be106de 100644
--- a/lib/common_test/test/ct_priv_dir_SUITE.erl
+++ b/lib/common_test/test/ct_priv_dir_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_priv_dir_SUITE_data/priv_dir_SUITE.erl b/lib/common_test/test/ct_priv_dir_SUITE_data/priv_dir_SUITE.erl
index 7704a29768..8fae6fe8ed 100644
--- a/lib/common_test/test/ct_priv_dir_SUITE_data/priv_dir_SUITE.erl
+++ b/lib/common_test/test/ct_priv_dir_SUITE_data/priv_dir_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_release_test_SUITE.erl b/lib/common_test/test/ct_release_test_SUITE.erl
new file mode 100644
index 0000000000..66d07155ac
--- /dev/null
+++ b/lib/common_test/test/ct_release_test_SUITE.erl
@@ -0,0 +1,190 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_release_test_SUITE
+%%%
+%%% Description:
+%%% Test ct_release_test module
+%%%
+%%%-------------------------------------------------------------------
+-module(ct_release_test_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+-define(suite, release_test_SUITE).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ case os:type() of
+ {win32,_} ->
+ {skipped, "Upgrade tests do currently not work on windows"};
+ _ ->
+ ct_test_support:init_per_suite(Config)
+ end.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [
+ minor,
+ major,
+ major_fail_init,
+ major_fail_upgraded,
+ major_fail_downgraded,
+ major_fail_no_init
+ ].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+minor(Config) when is_list(Config) ->
+ {Suite,Cfg} = setup1(Config),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {testcase,minor},
+ {label,minor}|Cfg], Config),
+ execute(minor, Opts, ERPid, Config).
+
+major(Config) when is_list(Config) ->
+ {Suite,Cfg} = setup1(Config),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {testcase,major},
+ {label,major}|Cfg], Config),
+ execute(major, Opts, ERPid, Config).
+
+major_fail_init(Config) when is_list(Config) ->
+ {Suite,Cfg} = setup1(Config),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {testcase,major_fail_init},
+ {label,major_fail_init}|Cfg], Config),
+ execute(major_fail_init, Opts, ERPid, Config).
+
+major_fail_upgraded(Config) when is_list(Config) ->
+ {Suite,Cfg} = setup1(Config),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {testcase,major_fail_upgraded},
+ {label,major_fail_upgraded}|Cfg], Config),
+ execute(major_fail_upgraded, Opts, ERPid, Config).
+
+major_fail_downgraded(Config) when is_list(Config) ->
+ {Suite,Cfg} = setup1(Config),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {testcase,major_fail_downgraded},
+ {label,major_fail_downgraded}|Cfg], Config),
+ execute(major_fail_downgraded, Opts, ERPid, Config).
+
+major_fail_no_init(Config) when is_list(Config) ->
+ {Suite,Cfg} = setup1(Config),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {testcase,major_fail_no_init},
+ {label,major_fail_no_init}|Cfg], Config),
+ execute(major_fail_no_init, Opts, ERPid, Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+setup1(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suite = filename:join(DataDir, atom_to_list(?suite)),
+ Cfg = case ct:get_config(otp_releases) of
+ undefined ->
+ [];
+ Rels ->
+ CfgFile = filename:join(DataDir, "release_test.cfg"),
+ file:write_file(CfgFile,
+ io_lib:format("{otp_releases,~p}.",[Rels])),
+ [{config,CfgFile}]
+ end,
+ {Suite,Cfg}.
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+execute(Name, Opts, ERPid, Config) ->
+ ok = ct_test_support:run(Opts, Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(Name,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config),
+ Opts),
+
+ verify_events(Name,Events,Config).
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+verify_events(TC,Events,Config) ->
+ Ok = expected_events(TC,ok),
+ case ct_test_support:verify_events(Ok, Events, Config) of
+ ok ->
+ ok;
+ {event_not_found,{?eh,tc_done,{_Suite,TC,ok}}}=R1 ->
+ ct:log("Did not find 'ok', checking if skipped...",[]),
+ Skipped = expected_events(TC,{skipped,"Old release not available"}),
+ case ct_test_support:verify_events(Skipped, Events, Config) of
+ ok ->
+ {skipped,"Old release not available"};
+ R2 ->
+ ct:log("Did not find skipped case either: ~n~p",[R2]),
+ exit(R1)
+ end
+ end.
+
+expected_events(TC,Result) ->
+ OneTest =
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_done,{?suite,TC,Result}},
+ {?eh,stop_logging,[]}],
+ %% 2 tests (ct:run_test + script_start) is default
+ OneTest ++ OneTest.
diff --git a/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl b/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl
new file mode 100644
index 0000000000..04c92be0d1
--- /dev/null
+++ b/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl
@@ -0,0 +1,118 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-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.
+%%
+%% %CopyrightEnd%
+%%
+%%%----------------------------------------------------------------
+%%% Purpose: Test the support for application upgrade/code_change test
+%%%-----------------------------------------------------------------
+-module(release_test_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+-define(APP,runtime_tools). % "randomly" selected 'application under test'
+
+%%
+%% all/1
+%%
+all() ->
+ [minor,
+ major,
+ major_fail_init,
+ major_fail_upgraded,
+ major_fail_downgraded,
+ major_fail_no_init].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(major_fail_no_init, Config) ->
+ Config;
+init_per_testcase(_Case, Config) ->
+ ct_release_test:init(Config).
+end_per_testcase(_Case, Config) ->
+ ct_release_test:cleanup(Config).
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+minor(Config) ->
+ ct_release_test:upgrade(?APP,minor,{?MODULE,[]},Config).
+
+major(Config) ->
+ ct_release_test:upgrade(?APP,major,{?MODULE,[]},Config).
+
+major_fail_init(Config) ->
+ try ct_release_test:upgrade(?APP,major,{?MODULE,fail_init},Config)
+ catch exit:{test_case_failed,
+ {test_upgrade_callback,_Mod,_Func,_Args,
+ {'EXIT',{test_case_failed,upgrade_init_failed}}}} ->
+ ok
+ end.
+
+major_fail_upgraded(Config) ->
+ try ct_release_test:upgrade(?APP,major,{?MODULE,fail_upgraded},Config)
+ catch exit:{test_case_failed,
+ {test_upgrade_callback,_Mod,_Func,_Args,
+ {'EXIT',{test_case_failed,upgrade_upgraded_failed}}}} ->
+ ok
+ end.
+
+major_fail_downgraded(Config) ->
+ try ct_release_test:upgrade(?APP,major,{?MODULE,fail_downgraded},Config)
+ catch exit:{test_case_failed,
+ {test_upgrade_callback,_Mod,_Func,_Args,
+ {'EXIT',{test_case_failed,upgrade_downgraded_failed}}}} ->
+ ok
+ end.
+
+major_fail_no_init(Config) ->
+ try ct_release_test:upgrade(?APP,major,[],Config)
+ catch exit:{test_case_failed,"ct_release_test:init/1 not run"} ->
+ ok
+ end.
+
+%%%-----------------------------------------------------------------
+%%% ct_release_test callbacks
+
+%% Version numbers are checked by ct_release_test, so there is nothing
+%% more to check here...
+upgrade_init(CtData,fail_init) ->
+ ct:fail(upgrade_init_failed);
+upgrade_init(CtData,State) ->
+ {ok,{FromVsn,ToVsn}} = ct_release_test:get_app_vsns(CtData,?APP),
+ case ct_release_test:get_appup(CtData,?APP) of
+ {ok,{FromVsn,ToVsn,UpInstrs,DownInstrs}} ->
+ io:format("Upgrade/downgrade ~p: ~p <--> ~p~n"
+ "Upgrade instructions: ~p~n"
+ "Downgrade instructions: ~p",
+ [?APP,FromVsn,ToVsn,UpInstrs,DownInstrs]);
+ {error,{vsn_not_found,_}} when FromVsn==ToVsn ->
+ io:format("No upgrade test for ~p, same version",[?APP])
+ end,
+ State.
+upgrade_upgraded(CtData,fail_upgraded) ->
+ ct:fail(upgrade_upgraded_failed);
+upgrade_upgraded(_CtData,State) ->
+ State.
+upgrade_downgraded(CtData,fail_downgraded) ->
+ ct:fail(upgrade_downgraded_failed);
+upgrade_downgraded(_CtData,State) ->
+ State.
diff --git a/lib/common_test/test/ct_repeat_1_SUITE.erl b/lib/common_test/test/ct_repeat_1_SUITE.erl
index 50e07608f6..7d47bdcf51 100644
--- a/lib/common_test/test/ct_repeat_1_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl b/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl
index 4c5b880e39..da00affa30 100644
--- a/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE.erl
index b6f285322d..7430ceb66d 100644
--- a/lib/common_test/test/ct_repeat_testrun_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_testrun_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl
index 3d7049a9c4..7afe526914 100644
--- a/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl
index e4f6e7dcc1..d78b1befab 100644
--- a/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_sequence_1_SUITE.erl b/lib/common_test/test/ct_sequence_1_SUITE.erl
index 4055cd789e..f13d7e32ea 100644
--- a/lib/common_test/test/ct_sequence_1_SUITE.erl
+++ b/lib/common_test/test/ct_sequence_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl b/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl
index 741b1165c1..ee0b5d7a02 100644
--- a/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl
+++ b/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_shell_SUITE.erl b/lib/common_test/test/ct_shell_SUITE.erl
index 70c0ab8127..786443e9ae 100644
--- a/lib/common_test/test/ct_shell_SUITE.erl
+++ b/lib/common_test/test/ct_shell_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE.erl b/lib/common_test/test/ct_skip_SUITE.erl
index 6fb803b928..4ed6005c65 100644
--- a/lib/common_test/test/ct_skip_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl
index b93c68e126..cf11de8147 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl
index c0a662f4b2..19cd76df62 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_12_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_12_SUITE.erl
index a168afd386..877eb6e540 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_12_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_12_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl
index 247e478fa3..cf8945c968 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl
index 3d332d2a28..dd3be8b6b5 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl
index 4ef9f50514..55b6fb254d 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl
index 89e202a404..7169517480 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl
index 2cf07928bb..560abd0a6e 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl
index c950fed6b7..f209d921c4 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl
index 6146459bf2..0497fd2785 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl
index 462d6b4e79..9b5ce06afb 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl
index e2d6bcf7d6..48c5930c5b 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl
index 60fc0f1122..a74c4601bd 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl
index 91a046a531..8f64f4fe8b 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl
index c362117bba..379a579501 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl
index 77fd5a2b5b..6d875436a4 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl
index 4bffa202d6..3575bf65e2 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_6_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_6_SUITE.erl
index 5f0e5db6f2..8a5c13d67c 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_6_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_6_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_7_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_7_SUITE.erl
index 82ce536a79..01efd31d5e 100644
--- a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_7_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_7_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_smoke_test_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE.erl
index 6077946c33..d0a1f14b8d 100644
--- a/lib/common_test/test/ct_smoke_test_SUITE.erl
+++ b/lib/common_test/test/ct_smoke_test_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl
index f33f0934cb..038c44e350 100644
--- a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl
+++ b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl
index 33d18006f9..1d3da7a245 100644
--- a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl
+++ b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_snmp_SUITE.erl b/lib/common_test/test/ct_snmp_SUITE.erl
index f8b4543770..17642c8d63 100644
--- a/lib/common_test/test/ct_snmp_SUITE.erl
+++ b/lib/common_test/test/ct_snmp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl
index 07f7bf02e4..5afd3a2dde 100644
--- a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl
+++ b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_surefire_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE.erl
index db7a0be915..922978fc4b 100644
--- a/lib/common_test/test/ct_surefire_SUITE.erl
+++ b/lib/common_test/test/ct_surefire_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,8 +49,11 @@
%% there will be clashes with logging processes etc).
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- Config1 = ct_test_support:init_per_suite(Config),
- Config1.
+ DataDir = ?config(data_dir,Config),
+ Hook = "fail_pre_init_per_suite.erl",
+ io:format("Compiling ~p: ~p~n",
+ [Hook, compile:file(Hook,[{outdir,DataDir},debug_info])]),
+ ct_test_support:init_per_suite([{path_dirs,[DataDir]}|Config]).
end_per_suite(Config) ->
ct_test_support:end_per_suite(Config).
@@ -68,7 +72,8 @@ all() ->
absolute_path,
relative_path,
url,
- logdir
+ logdir,
+ fail_pre_init_per_suite
].
%%--------------------------------------------------------------------
@@ -106,6 +111,14 @@ logdir(Config) when is_list(Config) ->
Path = "logdir.xml",
run(logdir,[{cth_surefire,[{path,Path}]}],Path,Config,[{logdir,MyLogDir}]).
+fail_pre_init_per_suite(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir,Config),
+ Suites = [filename:join(DataDir,"pass_SUITE"),
+ filename:join(DataDir,"fail_SUITE")],
+ Path = "fail_pre_init_per_suite.xml",
+ run(fail_pre_init_per_suite,[fail_pre_init_per_suite,
+ {cth_surefire,[{path,Path}]}],Path,Config,[],Suites).
+
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
@@ -114,6 +127,8 @@ run(Case,CTHs,Report,Config) ->
run(Case,CTHs,Report,Config,ExtraOpts) ->
DataDir = ?config(data_dir, Config),
Suite = filename:join(DataDir, "surefire_SUITE"),
+ run(Case,CTHs,Report,Config,ExtraOpts,Suite).
+run(Case,CTHs,Report,Config,ExtraOpts,Suite) ->
{Opts,ERPid} = setup([{suite,Suite},{ct_hooks,CTHs},{label,Case}|ExtraOpts],
Config),
ok = execute(Case, Opts, ERPid, Config),
@@ -141,7 +156,6 @@ setup(Test, Config) ->
execute(Name, Opts, ERPid, Config) ->
ok = ct_test_support:run(Opts, Config),
Events = ct_test_support:get_events(ERPid, Config),
-
ct_test_support:log_events(Name,
reformat(Events, ?eh),
?config(priv_dir, Config),
@@ -165,10 +179,30 @@ events_to_check(_, 0) ->
events_to_check(Test, N) ->
test_events(Test) ++ events_to_check(Test, N-1).
-test_events(_) ->
- [{?eh,start_logging,'_'},
- {?eh,start_info,{1,1,9}},
- {?eh,tc_start,{surefire_SUITE,init_per_suite}},
+test_suite_events(fail_SUITE, TestStat) ->
+ [{?eh,tc_start,{ct_framework,init_per_suite}},
+ {?eh,tc_done,{ct_framework,init_per_suite,
+ {failed,{error,pre_init_per_suite}}}},
+ {?eh,tc_auto_skip,
+ {fail_SUITE,test_case,
+ {failed,{ct_framework,init_per_suite,{failed,pre_init_per_suite}}}}},
+ {?eh,test_stats,TestStat},
+ {?eh,tc_auto_skip,
+ {ct_framework,end_per_suite,
+ {failed,{ct_framework,init_per_suite,{failed,pre_init_per_suite}}}}}].
+
+test_suite_events(fail_SUITE) ->
+ test_suite_events(fail_SUITE, {0,0,{0,1}});
+test_suite_events(pass_SUITE) ->
+ [{?eh,tc_start,{ct_framework,init_per_suite}},
+ {?eh,tc_done,{ct_framework,init_per_suite,ok}},
+ {?eh,tc_start,{pass_SUITE,test_case}},
+ {?eh,tc_done,{pass_SUITE,test_case,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{ct_framework,end_per_suite}},
+ {?eh,tc_done,{ct_framework,end_per_suite,ok}}];
+test_suite_events(_) ->
+ [{?eh,tc_start,{surefire_SUITE,init_per_suite}},
{?eh,tc_done,{surefire_SUITE,init_per_suite,ok}},
{?eh,tc_start,{surefire_SUITE,tc_ok}},
{?eh,tc_done,{surefire_SUITE,tc_ok,ok}},
@@ -215,9 +249,18 @@ test_events(_) ->
{surefire_SUITE,init_per_group,
{'EXIT',all_cases_should_be_skipped}}}}}],
{?eh,tc_start,{surefire_SUITE,end_per_suite}},
- {?eh,tc_done,{surefire_SUITE,end_per_suite,ok}},
- {?eh,stop_logging,[]}].
-
+ {?eh,tc_done,{surefire_SUITE,end_per_suite,ok}}].
+
+test_events(fail_pre_init_per_suite) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,start_info,{2,2,2}}] ++
+ test_suite_events(pass_SUITE) ++
+ test_suite_events(fail_SUITE, {1,0,{0,1}}) ++
+ [{?eh,stop_logging,[]}];
+test_events(Test) ->
+ [{?eh,start_logging,'_'}, {?eh,start_info,{1,1,9}}] ++
+ test_suite_events(Test) ++
+ [{?eh,stop_logging,[]}].
%%%-----------------------------------------------------------------
%%% Check generated xml log files
@@ -250,9 +293,9 @@ do_check_xml(Case,[Xml|Xmls]) ->
{E,_} = xmerl_scan:file(Xml),
Expected = events_to_result(lists:flatten(test_events(Case))),
ParseResult = testsuites(Case,E),
- ct:log("Expecting: ~p~n",[[Expected]]),
+ ct:log("Expecting: ~p~n",[Expected]),
ct:log("Actual : ~p~n",[ParseResult]),
- [Expected] = ParseResult,
+ Expected = ParseResult,
do_check_xml(Case,Xmls);
do_check_xml(_,[]) ->
ok.
@@ -264,7 +307,8 @@ testsuites(Case,#xmlElement{name=testsuites,content=TS}) ->
testsuite(Case,TS).
testsuite(Case,[#xmlElement{name=testsuite,content=TC,attributes=A}|TS]) ->
- {ET,EF,ES} = events_to_numbers(lists:flatten(test_events(Case))),
+ TestSuiteEvents = test_suite_events(get_ts_name(A)),
+ {ET,EF,ES} = events_to_numbers(lists:flatten(TestSuiteEvents)),
{T,E,F,S} = get_numbers_from_attrs(A,false,false,false,false),
ct:log("Expecting total:~p, error:~p, failure:~p, skipped:~p~n",[ET,0,EF,ES]),
ct:log("Actual total:~p, error:~p, failure:~p, skipped:~p~n",[T,E,F,S]),
@@ -317,14 +361,32 @@ failed_or_skipped([]) ->
%% Testsuites = [Testsuite]
%% Testsuite = [Testcase]
%% Testcase = [] | [f] | [s], indicating ok, failed and skipped respectively
-events_to_result([{?eh,tc_done,{_Suite,_Case,R}}|E]) ->
- [result(R)|events_to_result(E)];
-events_to_result([{?eh,tc_auto_skip,_}|E]) ->
- [[s]|events_to_result(E)];
-events_to_result([_|E]) ->
- events_to_result(E);
-events_to_result([]) ->
- [].
+events_to_result(E) ->
+ events_to_result(E, []).
+
+events_to_result([{?eh,tc_auto_skip,{_Suite,init_per_suite,_}}|E], Result) ->
+ {Suite,Rest} = events_to_result1(E),
+ events_to_result(Rest, [[[s]|Suite]|Result]);
+events_to_result([{?eh,tc_done,{_Suite,init_per_suite,R}}|E], Result) ->
+ {Suite,Rest} = events_to_result1(E),
+ events_to_result(Rest, [[result(R)|Suite]|Result]);
+events_to_result([_|E], Result) ->
+ events_to_result(E, Result);
+events_to_result([], Result) ->
+ Result.
+
+events_to_result1([{?eh,tc_auto_skip,{_Suite, end_per_suite,_}}|E]) ->
+ {[[s]],E};
+events_to_result1([{?eh,tc_done,{_Suite, end_per_suite,R}}|E]) ->
+ {[result(R)],E};
+events_to_result1([{?eh,tc_done,{_Suite,_Case,R}}|E]) ->
+ {Suite,Rest} = events_to_result1(E),
+ {[result(R)|Suite],Rest};
+events_to_result1([{?eh,tc_auto_skip,_}|E]) ->
+ {Suite,Rest} = events_to_result1(E),
+ {[[s]|Suite],Rest};
+events_to_result1([_|E]) ->
+ events_to_result1(E).
result(ok) ->[];
result({skipped,_}) -> [s];
@@ -373,3 +435,7 @@ del_files(Dir,[F0|Fs] ) ->
end;
del_files(_,[]) ->
ok.
+
+get_ts_name(Attributes) ->
+ {_,name,_,_,_,_,_,_,Name,_} = lists:keyfind(name, 2, Attributes),
+ list_to_atom(Name).
diff --git a/lib/common_test/test/ct_surefire_SUITE_data/fail_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE_data/fail_SUITE.erl
new file mode 100644
index 0000000000..3f5f42c054
--- /dev/null
+++ b/lib/common_test/test/ct_surefire_SUITE_data/fail_SUITE.erl
@@ -0,0 +1,28 @@
+%% %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%
+%%
+-module(fail_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0, test_case/1]).
+
+all() ->
+ [test_case].
+
+test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_surefire_SUITE_data/fail_pre_init_per_suite.erl b/lib/common_test/test/ct_surefire_SUITE_data/fail_pre_init_per_suite.erl
new file mode 100644
index 0000000000..ff278db378
--- /dev/null
+++ b/lib/common_test/test/ct_surefire_SUITE_data/fail_pre_init_per_suite.erl
@@ -0,0 +1,47 @@
+%%
+%% %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%
+%%
+
+%%% This tests that the correct XML is produced when pre_init_per_suite
+%%% fails in a hook
+-module(fail_pre_init_per_suite).
+
+%% CT Hooks
+-export([init/2, pre_init_per_suite/3]).
+
+-type config() :: proplists:proplist().
+-type reason() :: term().
+-type skip_or_fail() :: skip | auto_skip | fail | 'EXIT'.
+
+-record(state, {}).
+
+-spec init(Id :: term(), Opts :: proplists:proplist()) ->
+ {ok, proplists:proplist()}.
+init(_Id, Opts) ->
+ {ok, Opts}.
+
+-spec pre_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | {skip_or_fail(), reason()}, NewState :: #state{}}.
+pre_init_per_suite(fail_SUITE, _Config, State) ->
+ {{fail, pre_init_per_suite}, State};
+pre_init_per_suite(_Suite, Config, State) ->
+ {Config, State}.
+
diff --git a/lib/common_test/test/ct_surefire_SUITE_data/pass_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE_data/pass_SUITE.erl
new file mode 100644
index 0000000000..74ed5b730e
--- /dev/null
+++ b/lib/common_test/test/ct_surefire_SUITE_data/pass_SUITE.erl
@@ -0,0 +1,28 @@
+%% %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%
+%%
+-module(pass_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0, test_case/1]).
+
+all() ->
+ [test_case].
+
+test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl
index 677aee46c5..ab387c2ea4 100644
--- a/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl
+++ b/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_system_error_SUITE.erl b/lib/common_test/test/ct_system_error_SUITE.erl
index f2d6ef4b1b..f783a09553 100644
--- a/lib/common_test/test/ct_system_error_SUITE.erl
+++ b/lib/common_test/test/ct_system_error_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_system_error_SUITE_data/a_SUITE.erl b/lib/common_test/test/ct_system_error_SUITE_data/a_SUITE.erl
index c6e3ddfd5d..35efbb851f 100644
--- a/lib/common_test/test/ct_system_error_SUITE_data/a_SUITE.erl
+++ b/lib/common_test/test/ct_system_error_SUITE_data/a_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_telnet_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE.erl
index 62cb821ede..006a921fc1 100644
--- a/lib/common_test/test/ct_telnet_SUITE.erl
+++ b/lib/common_test/test/ct_telnet_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
index b6ef3062d4..4b2f4ee504 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -236,14 +237,13 @@ test_events(ts_if_1) ->
{ts_if_2_SUITE,end_per_suite,
{failed,{error,{suite0_failed,{exited,suite0_goes_boom}}}}}},
-
{?eh,tc_start,{ct_framework,error_in_suite}},
- {?eh,test_stats,{2,6,{4,7}}},
-
+ {?eh,tc_done,{ct_framework,error_in_suite,
+ {failed,{error,'ts_if_3_SUITE:all/0 is missing'}}}},
{?eh,tc_start,{ct_framework,error_in_suite}},
- {?eh,test_stats,{2,7,{4,7}}},
-
+ {?eh,tc_done,{ct_framework,error_in_suite,
+ {failed,{error,'Bad return value from ts_if_4_SUITE:all/0'}}}},
{?eh,tc_start,{ts_if_5_SUITE,init_per_suite}},
{?eh,tc_done,{ts_if_5_SUITE,init_per_suite,
@@ -252,7 +252,7 @@ test_events(ts_if_1) ->
{?eh,tc_auto_skip,
{ts_if_5_SUITE,my_test_case,
{require_failed_in_suite0,{not_available,undef_variable}}}},
- {?eh,test_stats,{2,7,{4,8}}},
+ {?eh,test_stats,{2,5,{4,8}}},
{?eh,tc_auto_skip,
{ts_if_5_SUITE,end_per_suite,
{require_failed_in_suite0,{not_available,undef_variable}}}},
@@ -264,7 +264,7 @@ test_events(ts_if_1) ->
{?eh,tc_auto_skip,
{ts_if_6_SUITE,tc1,
{failed,{error,{suite0_failed,{exited,suite0_byebye}}}}}},
- {?eh,test_stats,{2,7,{4,9}}},
+ {?eh,test_stats,{2,5,{4,9}}},
{?eh,tc_auto_skip,
{ct_framework,end_per_suite,
{failed,{error,{suite0_failed,{exited,suite0_byebye}}}}}},
@@ -274,13 +274,13 @@ test_events(ts_if_1) ->
{?eh,tc_done,{ct_framework,init_per_suite,ok}},
{?eh,tc_done,
{ts_if_7_SUITE,tc1,{auto_skipped,{testcase0_failed,bad_return_value}}}},
- {?eh,test_stats,{2,7,{4,10}}},
+ {?eh,test_stats,{2,5,{4,10}}},
{?eh,tc_done,{ts_if_7_SUITE,
{init_per_group,g1,[]},
{auto_skipped,{group0_failed,bad_return_value}}}},
{?eh,tc_auto_skip,
{ts_if_7_SUITE,{tc2,g1},{group0_failed,bad_return_value}}},
- {?eh,test_stats,{2,7,{4,11}}},
+ {?eh,test_stats,{2,5,{4,11}}},
{?eh,tc_auto_skip,
{ts_if_7_SUITE,{end_per_group,g1},{group0_failed,bad_return_value}}},
@@ -288,7 +288,7 @@ test_events(ts_if_1) ->
{?eh,tc_done,{ts_if_7_SUITE,{init_per_group,g2,[]},ok}},
{?eh,tc_done,{ts_if_7_SUITE,tc2,
{auto_skipped,{testcase0_failed,bad_return_value}}}},
- {?eh,test_stats,{2,7,{4,12}}},
+ {?eh,test_stats,{2,5,{4,12}}},
{?eh,tc_start,{ts_if_7_SUITE,{end_per_group,g2,[]}}},
{?eh,tc_done,{ts_if_7_SUITE,{end_per_group,g2,[]},ok}}],
@@ -300,17 +300,17 @@ test_events(ts_if_1) ->
{?eh,tc_done,{ct_framework,init_per_suite,ok}},
{?eh,tc_start,{ts_if_8_SUITE,tc1}},
{?eh,tc_done,{ts_if_8_SUITE,tc1,{failed,{error,failed_on_purpose}}}},
- {?eh,test_stats,{2,8,{4,12}}},
+ {?eh,test_stats,{2,6,{4,12}}},
{?eh,tc_start,{ct_framework,end_per_suite}},
{?eh,tc_done,{ct_framework,end_per_suite,ok}},
{?eh,tc_user_skip,{skipped_by_spec_1_SUITE,all,"should be skipped"}},
- {?eh,test_stats,{2,8,{5,12}}},
+ {?eh,test_stats,{2,6,{5,12}}},
{?eh,tc_start,{skipped_by_spec_2_SUITE,init_per_suite}},
{?eh,tc_done,{skipped_by_spec_2_SUITE,init_per_suite,ok}},
{?eh,tc_user_skip,{skipped_by_spec_2_SUITE,tc1,"should be skipped"}},
- {?eh,test_stats,{2,8,{6,12}}},
+ {?eh,test_stats,{2,6,{6,12}}},
{?eh,tc_start,{skipped_by_spec_2_SUITE,end_per_suite}},
{?eh,tc_done,{skipped_by_spec_2_SUITE,end_per_suite,ok}},
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl
index e77e304834..d32283c859 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl
index 384182e778..62f2bdc8d5 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl
index d30feb0bd2..c7673577ab 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl
index 386b4402e6..d25330d746 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl
index 70191d31ed..c56c684588 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl
index 4b566fea5d..eaad6d2044 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl
index c7b6b054fb..b51d76e707 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl
index 43440386e6..9bfd102409 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl
index 20e04c464b..9131874c48 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl
index 990669cd4c..e3247ed3ea 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index 6abca08452..493fa82c79 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -42,6 +43,8 @@
-export([random_error/1]).
+-export([unique_timestamp/0]).
+
-include_lib("kernel/include/file.hrl").
%%%-----------------------------------------------------------------
@@ -109,7 +112,8 @@ start_slave(NodeName, Config, Level) ->
undefined -> [];
Ds -> Ds
end,
- PathDirs = [PrivDir,TSDir | AddPathDirs],
+ TestSupDir = filename:dirname(code:which(?MODULE)),
+ PathDirs = [PrivDir,TSDir,TestSupDir | AddPathDirs],
[true = rpc:call(CTNode, code, add_patha, [D]) || D <- PathDirs],
test_server:format(Level, "Dirs added to code path (on ~w):~n",
[CTNode]),
@@ -287,10 +291,13 @@ run_ct_run_test(Opts,Config) ->
Level = proplists:get_value(trace_level, Config),
test_server:format(Level, "~n[RUN #1] Calling ct:run_test(~p) on ~p~n",
[Opts, CTNode]),
- T0 = now(),
+
+ T0 = erlang:monotonic_time(),
CtRunTestResult = rpc:call(CTNode, ct, run_test, [Opts]),
+ T1 = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(T1-T0, native, milli_seconds),
test_server:format(Level, "~n[RUN #1] Got return value ~p after ~p ms~n",
- [CtRunTestResult,trunc(timer:now_diff(now(), T0)/1000)]),
+ [CtRunTestResult,Elapsed]),
case rpc:call(CTNode, erlang, whereis, [ct_util_server]) of
undefined ->
ok;
@@ -313,10 +320,12 @@ run_ct_script_start(Opts, Config) ->
[common_test, run_test_start_opts, Opts1]),
test_server:format(Level, "[RUN #2] Calling ct_run:script_start() on ~p~n",
[CTNode]),
- T0 = now(),
+ T0 = erlang:monotonic_time(),
ExitStatus = rpc:call(CTNode, ct_run, script_start, []),
+ T1 = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(T1-T0, native, milli_seconds),
test_server:format(Level, "[RUN #2] Got exit status value ~p after ~p ms~n",
- [ExitStatus,trunc(timer:now_diff(now(), T0)/1000)]),
+ [ExitStatus,Elapsed]),
ExitStatus.
check_result({_Ok,Failed,{_UserSkipped,_AutoSkipped}},1,_Opts)
@@ -408,7 +417,7 @@ ct_rpc({M,F,A}, Config) ->
%%%-----------------------------------------------------------------
%%% random_error/1
random_error(Config) when is_list(Config) ->
- random:seed(now()),
+ random:seed(os:timestamp()),
Gen = fun(0,_) -> ok; (N,Fun) -> Fun(N-1, Fun) end,
Gen(random:uniform(100), Gen),
@@ -1222,8 +1231,8 @@ log_events(TC, Events, EvLogDir, Opts) ->
file:close(Dev),
FullLogFile = join_abs_dirs(proplists:get_value(net_dir, Opts),
LogFile),
- io:format("Events written to logfile: <a href=\"file://~s\">~s</a>~n",
- [FullLogFile,FullLogFile]),
+ ct:log("Events written to logfile: <a href=\"file://~s\">~s</a>~n",
+ [FullLogFile,FullLogFile],[no_css]),
io:format(user, "Events written to logfile: ~p~n", [LogFile]).
log_events1(Evs, Dev, "") ->
@@ -1350,12 +1359,7 @@ delete_old_logs(_, Config) ->
delete_dirs(LogDir) ->
Now = calendar:datetime_to_gregorian_seconds(calendar:local_time()),
- SaveTime = case os:getenv("CT_SAVE_OLD_LOGS") of
- false ->
- 28800;
- SaveTime0 ->
- list_to_integer(SaveTime0)
- end,
+ SaveTime = list_to_integer(os:getenv("CT_SAVE_OLD_LOGS", "28800")),
Deadline = Now - SaveTime,
Dirs = filelib:wildcard(filename:join(LogDir,"ct_run*")),
Dirs2Del =
@@ -1429,7 +1433,21 @@ rm_files([F | Fs]) ->
end;
rm_files([]) ->
ok.
-
+
+unique_timestamp() ->
+ unique_timestamp(os:timestamp(), 100000).
+
+unique_timestamp(TS, 0) ->
+ TS;
+unique_timestamp(TS0, N) ->
+ case os:timestamp() of
+ TS0 ->
+ timer:sleep(1),
+ unique_timestamp(TS0, N-1);
+ TS1 ->
+ TS1
+ end.
+
%%%-----------------------------------------------------------------
%%%
slave_stop(Node) ->
diff --git a/lib/common_test/test/ct_test_support_eh.erl b/lib/common_test/test/ct_test_support_eh.erl
index 70f73b9b81..7c3d137901 100644
--- a/lib/common_test/test/ct_test_support_eh.erl
+++ b/lib/common_test/test/ct_test_support_eh.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE.erl
index bc19283a47..6401ed181c 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl
index 4f11d8a0e8..abc53c93f5 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl
index e5de5df1a8..f55ccb0792 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl
index 2533ac8e84..0138310c36 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl
index dcd361d658..4d253dae6f 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl
index b789851134..381742278a 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl
index eb7e9cdf7b..fb646071b8 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/ct_testspec_2_SUITE.erl b/lib/common_test/test/ct_testspec_2_SUITE.erl
index 518352e87c..887b156cde 100644
--- a/lib/common_test/test/ct_testspec_2_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_3_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE.erl
index 9f8ca84e45..09c649ef78 100644
--- a/lib/common_test/test/ct_testspec_3_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_3_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl
index b8216c3596..fd66bf5423 100644
--- a/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -41,8 +42,12 @@ suite() ->
%% @end
%%--------------------------------------------------------------------
init_per_suite(Config) ->
+
+ TCName = ct:get_config(tcname),
+ CfgFiles = ct:get_config(file,undefined,[all]),
+
%% verify that expected config file can be read
- case {ct:get_config(tcname),ct:get_config(file,undefined,[all])} of
+ case {TCName,CfgFiles} of
{start_separate,[cfg11]} -> ok;
{start_join,[cfg11,cfg21]} -> ok;
{incl_separate1,[cfg11]} -> ok;
@@ -56,6 +61,28 @@ init_per_suite(Config) ->
_ -> ok
end,
+
+ %% test the get_testspec_terms functionality
+ if CfgFiles /= undefined ->
+ TSTerms = case ct:get_testspec_terms() of
+ undefined -> exit('testspec should not be undefined');
+ Result -> Result
+ end,
+ true = lists:keymember(config, 1, TSTerms),
+ {config,TSCfgFiles} = ct:get_testspec_terms(config),
+ [{config,TSCfgFiles},{tests,Tests}] =
+ ct:get_testspec_terms([config,tests]),
+ CfgNames = [list_to_atom(filename:basename(TSCfgFile)) ||
+ {Node,TSCfgFile} <- TSCfgFiles, Node == node()],
+ true = (length(CfgNames) == length(CfgFiles)),
+ [true = lists:member(CfgName,CfgFiles) || CfgName <- CfgNames],
+ true = lists:any(fun({{_Node,_Dir},Suites}) ->
+ lists:keymember(?MODULE, 1, Suites)
+ end, Tests);
+ true ->
+ ok
+ end,
+
Config.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl
index 7c51aca246..bc0cf84c8e 100644
--- a/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -55,7 +56,7 @@ init_per_suite(Config) ->
{incl_both2,[cfg11,cfg12,cfg21]} -> ok;
{incl_both2,[cfg21]} -> ok;
_ -> ok
- end,
+ end,
Config.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl
index 36c1b4279b..bcc1e5ac3d 100644
--- a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -41,8 +42,11 @@ suite() ->
%% @end
%%--------------------------------------------------------------------
init_per_suite(Config) ->
+ TCName = ct:get_config(tcname),
+ CfgFiles = ct:get_config(file,undefined,[all]),
+
%% verify that expected config file can be read
- case {ct:get_config(tcname),ct:get_config(file,undefined,[all])} of
+ case {TCName,CfgFiles} of
{start_separate,[cfg11]} -> ok;
{start_join,[cfg11,cfg21]} -> ok;
{incl_separate1,[cfg11]} -> ok;
@@ -55,6 +59,28 @@ init_per_suite(Config) ->
{incl_both2,[cfg11]} -> ok;
_ -> ok
end,
+
+ %% test the get_testspec_terms functionality
+ if CfgFiles /= undefined ->
+ TSTerms = case ct:get_testspec_terms() of
+ undefined -> exit('testspec should not be undefined');
+ Result -> Result
+ end,
+ true = lists:keymember(config, 1, TSTerms),
+ {config,TSCfgFiles} = ct:get_testspec_terms(config),
+ [{config,TSCfgFiles},{tests,Tests}] =
+ ct:get_testspec_terms([config,tests]),
+ CfgNames = [list_to_atom(filename:basename(TSCfgFile)) ||
+ {Node,TSCfgFile} <- TSCfgFiles, Node == node()],
+ true = (length(CfgNames) == length(CfgFiles)),
+ [true = lists:member(CfgName,CfgFiles) || CfgName <- CfgNames],
+ true = lists:any(fun({{_Node,_Dir},Suites}) ->
+ lists:keymember(?MODULE, 1, Suites)
+ end, Tests);
+ true ->
+ ok
+ end,
+
Config.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl
index 3f6336c7e2..2dee793c70 100644
--- a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl
index d836ab57c1..66b1d10f28 100644
--- a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_userconfig_callback.erl b/lib/common_test/test/ct_userconfig_callback.erl
index ca51bf240b..8b269c695c 100644
--- a/lib/common_test/test/ct_userconfig_callback.erl
+++ b/lib/common_test/test/ct_userconfig_callback.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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_userconfig_callback).
diff --git a/lib/common_test/test/ct_verbosity_SUITE.erl b/lib/common_test/test/ct_verbosity_SUITE.erl
index 1aa71953ec..f19322c183 100644
--- a/lib/common_test/test/ct_verbosity_SUITE.erl
+++ b/lib/common_test/test/ct_verbosity_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_verbosity_SUITE_data/io_test_SUITE.erl b/lib/common_test/test/ct_verbosity_SUITE_data/io_test_SUITE.erl
index 946e1c1989..cc799c1923 100644
--- a/lib/common_test/test/ct_verbosity_SUITE_data/io_test_SUITE.erl
+++ b/lib/common_test/test/ct_verbosity_SUITE_data/io_test_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl b/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl
index 3e744f2596..37987538b5 100644
--- a/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl
+++ b/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/common_test/test/telnet_server.erl b/lib/common_test/test/telnet_server.erl
index 2db5a9bc44..107d98d72c 100644
--- a/lib/common_test/test/telnet_server.erl
+++ b/lib/common_test/test/telnet_server.erl
@@ -290,10 +290,10 @@ send(Data,State) ->
send_loop(T,Data,State) ->
dbg("Server sending ~p in loop for ~w ms...~n",[Data,T]),
- send_loop(now(),T,Data,State).
+ send_loop(os:timestamp(),T,Data,State).
send_loop(T0,T,Data,State) ->
- ElapsedMS = trunc(timer:now_diff(now(),T0)/1000),
+ ElapsedMS = trunc(timer:now_diff(os:timestamp(),T0)/1000),
if ElapsedMS >= T ->
ok;
true ->
@@ -320,7 +320,7 @@ dbg(_F,_A) ->
io:format("[telnet_server, ~s]\n" ++ _F,[TS|_A]).
timestamp() ->
- {MS,S,US} = now(),
+ {MS,S,US} = os:timestamp(),
{{Year,Month,Day}, {Hour,Min,Sec}} =
calendar:now_to_local_time({MS,S,US}),
MilliSec = trunc(US/1000),
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index e2d921729c..f33fd658e8 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1 +1 @@
-COMMON_TEST_VSN = 1.10.1
+COMMON_TEST_VSN = 1.12.1
diff --git a/lib/compiler/Makefile b/lib/compiler/Makefile
index 1ad883b014..bd63f7031a 100644
--- a/lib/compiler/Makefile
+++ b/lib/compiler/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/compiler/doc/src/Makefile b/lib/compiler/doc/src/Makefile
index 13a73a5d31..b989325686 100644
--- a/lib/compiler/doc/src/Makefile
+++ b/lib/compiler/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/compiler/doc/src/book.xml b/lib/compiler/doc/src/book.xml
index 45b49fe46d..8de3fae69a 100644
--- a/lib/compiler/doc/src/book.xml
+++ b/lib/compiler/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index 5fccdcdcb5..db701409db 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,15 +33,15 @@
<modulesummary>Erlang Compiler</modulesummary>
<description>
<p>This module provides an interface to the standard Erlang
- compiler. It can generate either a new file which contains
- the object code, or return a binary which can be loaded directly.
+ compiler. It can generate either a new file, which contains
+ the object code, or return a binary, which can be loaded directly.
</p>
</description>
<funcs>
<func>
<name>file(File)</name>
- <fsummary>Compile a file</fsummary>
+ <fsummary>Compiles a file.</fsummary>
<desc>
<p>Is the same as
<c>file(File, [verbose,report_errors,report_warnings])</c>.
@@ -50,7 +51,7 @@
<func>
<name>file(File, Options) -> CompRet</name>
- <fsummary>Compile a file</fsummary>
+ <fsummary>Compiles a file.</fsummary>
<type>
<v>CompRet = ModRet | BinRet | ErrRet</v>
<v>ModRet = {ok,ModuleName} | {ok,ModuleName,Warnings}</v>
@@ -64,39 +65,38 @@
<p>Returns <c>{ok,ModuleName}</c> if successful, or <c>error</c>
if there are errors. An object code file is created if
- the compilation succeeds with no errors. It is considered
+ the compilation succeeds without errors. It is considered
to be an error if the module name in the source code is
not the same as the basename of the output file.</p>
- <p><marker id="type-option"/>Here follows first all elements of <c>Options</c> that in
- some way control the behavior of the compiler.</p>
+ <p><marker id="type-option"/>Available options:</p>
<taglist>
<tag><c>basic_validation</c></tag>
<item>
- <p>This option is fast way to test whether a module will
- compile successfully (mainly useful for code generators
- that want to verify the code they emit). No code will
+ <p>This option is a fast way to test whether a module will
+ compile successfully. This is useful for code generators
+ that want to verify the code that they emit. No code is
generated. If warnings are enabled, warnings generated by
the <c>erl_lint</c> module (such as warnings for unused
- variables and functions) will be returned too.</p>
+ variables and functions) are also returned.</p>
- <p>Use the <c>strong_validation</c> option to generate all
+ <p>Use option <c>strong_validation</c> to generate all
warnings that the compiler would generate.</p>
</item>
<tag><c>strong_validation</c></tag>
<item>
- <p>Similar to the <c>basic_validation</c> option, no code
- will be generated, but more compiler passes will be run
- to ensure also warnings generated by the optimization
- passes are generated (such as clauses that will not match
+ <p>Similar to option <c>basic_validation</c>. No code
+ is generated, but more compiler passes are run
+ to ensure that warnings generated by the optimization
+ passes are generated (such as clauses that will not match,
or expressions that are guaranteed to fail with an
- exception at run-time).</p>
+ exception at runtime).</p>
</item>
<tag><c>binary</c></tag>
<item>
- <p>Causes the compiler to return the object code in a
+ <p>The compiler returns the object code in a
binary instead of creating an object file. If successful,
the compiler returns <c>{ok,ModuleName,Binary}</c>.</p>
</item>
@@ -105,7 +105,9 @@
<item>
<p>The compiler will emit informational warnings about binary
matching optimizations (both successful and unsuccessful).
- See the <em>Efficiency Guide</em> for further information.</p>
+ For more information, see the section about
+ <seealso marker="doc/efficiency_guide:binaryhandling#bin_opt_info">bin_opt_info</seealso>
+ in the Efficiency Guide.</p>
</item>
<tag><c>compressed</c></tag>
@@ -117,20 +119,19 @@
<tag><c>debug_info</c></tag>
<item>
<marker id="debug_info"></marker>
- <p>Include debug information in the form of abstract code
+ <p>Includes debug information in the form of abstract code
(see
<seealso marker="erts:absform">The Abstract Format</seealso>
in ERTS User's Guide) in the compiled beam module. Tools
- such as Debugger, Xref and Cover require the debug
- information to be included.</p>
+ such as <c>Debugger</c>, <c>Xref</c>, and <c>Cover</c> require
+ the debug information to be included.</p>
<p><em>Warning</em>: Source code can be reconstructed from
the debug information. Use encrypted debug information
- (see below) to prevent this.</p>
+ (<c>encrypt_debug_info</c>) to prevent this.</p>
- <p>See
- <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>
- for details.</p>
+ <p>For details, see
+ <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
</item>
<tag><c>{debug_info_key,KeyString}</c></tag>
@@ -138,65 +139,61 @@
<tag><c>{debug_info_key,{Mode,KeyString}}</c></tag>
<item>
<marker id="debug_info_key"></marker>
- <p>Include debug information, but encrypt it, so that it
+ <p>Includes debug information, but encrypts it so that it
cannot be accessed without supplying the key. (To give
- the <c>debug_info</c> option as well is allowed, but is
+ option <c>debug_info</c> as well is allowed, but
not necessary.) Using this option is a good way to always
have the debug information available during testing, yet
- protect the source code.</p>
+ protecting the source code.</p>
<p><c>Mode</c> is the type of crypto algorithm to be used
- for encrypting the debug information. The default type --
- and currently the only type -- is <c>des3_cbc</c>.</p>
- <p>See
- <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>
- for details.</p>
+ for encrypting the debug information. The default
+ (and currently the only) type is <c>des3_cbc</c>.</p>
+ <p>For details, see
+ <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
</item>
<tag><c>encrypt_debug_info</c></tag>
<item>
<marker id="encrypt_debug_info"></marker>
- <p>Like the <c>debug_info_key</c> option above, except that
- the key will be read from an <c>.erlang.crypt</c> file.
+ <p>Similar to the <c>debug_info_key</c> option, but
+ the key is read from an <c>.erlang.crypt</c> file.
</p>
- <p>See
- <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>
- for details.</p>
+ <p>For details, see
+ <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
</item>
<tag><c>makedep</c></tag>
<item>
- <p>Produce a Makefile rule to track headers dependencies.
+ <p>Produces a Makefile rule to track headers dependencies.
No object file is produced.
</p>
<p>By default, this rule is written to
- <c><![CDATA[<File>.Pbeam]]></c>. However, if the option
+ <c><![CDATA[<File>.Pbeam]]></c>. However, if option
<c>binary</c> is set, nothing is written and the rule is
returned in <c>Binary</c>.
</p>
- <p>For instance, if one has the following module:
+ <p>For example, if you have the following module:
</p>
<code>
-module(module).
-include_lib("eunit/include/eunit.hrl").
--include("header.hrl").
- </code>
- <p>Here is the Makefile rule generated by this option:
+-include("header.hrl").</code>
+ <p>The Makefile rule generated by this option looks as follows:
</p>
<code>
module.beam: module.erl \
/usr/local/lib/erlang/lib/eunit/include/eunit.hrl \
- header.hrl
- </code>
+ header.hrl</code>
</item>
<tag><c>{makedep_output, Output}</c></tag>
<item>
- <p>Write generated rule(s) to <c>Output</c> instead of the
+ <p>Writes generated rules to <c>Output</c> instead of the
default <c><![CDATA[<File>.Pbeam]]></c>. <c>Output</c>
can be a filename or an <c>io_device()</c>. To write to
- stdout, use <c>standard_io</c>. However if <c>binary</c>
+ stdout, use <c>standard_io</c>. However, if <c>binary</c>
is set, nothing is written to <c>Output</c> and the
result is returned to the caller with
<c>{ok, ModuleName, Binary}</c>.
@@ -205,7 +202,7 @@ module.beam: module.erl \
<tag><c>{makedep_target, Target}</c></tag>
<item>
- <p>Change the name of the rule emitted to <c>Target</c>.
+ <p>Changes the name of the rule emitted to <c>Target</c>.
</p>
</item>
@@ -217,20 +214,20 @@ module.beam: module.erl \
<tag><c>makedep_add_missing</c></tag>
<item>
- <p>Consider missing headers as generated files and add them to the
+ <p>Considers missing headers as generated files and adds them to the
dependencies.
</p>
</item>
<tag><c>makedep_phony</c></tag>
<item>
- <p>Add a phony target for each dependency.
+ <p>Adds a phony target for each dependency.
</p>
</item>
<tag><c>'P'</c></tag>
<item>
- <p>Produces a listing of the parsed code after preprocessing
+ <p>Produces a listing of the parsed code, after preprocessing
and parse transforms, in the file
<c><![CDATA[<File>.P]]></c>. No object file is produced.
</p>
@@ -238,7 +235,7 @@ module.beam: module.erl \
<tag><c>'E'</c></tag>
<item>
- <p>Produces a listing of the code after all source code
+ <p>Produces a listing of the code, after all source code
transformations have been performed, in the file
<c><![CDATA[<File>.E]]></c>. No object file is produced.
</p>
@@ -258,21 +255,21 @@ module.beam: module.erl \
<tag><c>report</c></tag>
<item>
- <p>This is a short form for both <c>report_errors</c> and
+ <p>A short form for both <c>report_errors</c> and
<c>report_warnings</c>.</p>
</item>
<tag><c>return_errors</c></tag>
<item>
- <p>If this flag is set, then
+ <p>If this flag is set,
<c>{error,ErrorList,WarningList}</c> is returned when
there are errors.</p>
</item>
<tag><c>return_warnings</c></tag>
<item>
- <p>If this flag is set, then an extra field containing
- <c>WarningList</c> is added to the tuples returned on
+ <p>If this flag is set, an extra field, containing
+ <c>WarningList</c>, is added to the tuples returned on
success.</p>
</item>
@@ -284,13 +281,13 @@ module.beam: module.erl \
<tag><c>return</c></tag>
<item>
- <p>This is a short form for both <c>return_errors</c> and
+ <p>A short form for both <c>return_errors</c> and
<c>return_warnings</c>.</p>
</item>
<tag><c>verbose</c></tag>
<item>
- <p>Causes more verbose information from the compiler
+ <p>Causes more verbose information from the compiler,
describing what it is doing.</p>
</item>
@@ -314,7 +311,7 @@ module.beam: module.erl \
<tag><c>{i,Dir}</c></tag>
<item>
- <p>Add <c>Dir</c> to the list of directories to be searched
+ <p>Adds <c>Dir</c> to the list of directories to be searched
when including a file. When encountering an
<c>-include</c> or <c>-include_lib</c> directive,
the compiler searches for header files in the following
@@ -322,14 +319,14 @@ module.beam: module.erl \
<list type="ordered">
<item>
<p><c>"."</c>, the current working directory of
- the file server;</p>
+ the file server</p>
</item>
<item>
- <p>the base name of the compiled file;</p>
+ <p>The base name of the compiled file</p>
</item>
<item>
- <p>the directories specified using the <c>i</c> option.
- The directory specified last is searched first.</p>
+ <p>The directories specified using option <c>i</c>;
+ the directory specified last is searched first</p>
</item>
</list>
</item>
@@ -353,15 +350,15 @@ module.beam: module.erl \
<tag><c>from_asm</c></tag>
<item>
<p>The input file is expected to be assembler code (default
- file suffix ".S"). Note that the format of assembler files
- is not documented, and may change between releases.</p>
+ file suffix ".S"). Notice that the format of assembler files
+ is not documented, and can change between releases.</p>
</item>
<tag><c>from_core</c></tag>
<item>
<p>The input file is expected to be core code (default
- file suffix ".core"). Note that the format of core files
- is not documented, and may change between releases.</p>
+ file suffix ".core"). Notice that the format of core files
+ is not documented, and can change between releases.</p>
</item>
<tag><c>no_strict_record_tests</c></tag>
@@ -369,9 +366,9 @@ module.beam: module.erl \
<p>This option is not recommended.</p>
<p>By default, the generated code for
- the <c>Record#record_tag.field</c> operation verifies that
- the tuple <c>Record</c> is of the correct size for
- the record and that the first element is the tag
+ operation <c>Record#record_tag.field</c> verifies that
+ the tuple <c>Record</c> has the correct size for
+ the record, and that the first element is the tag
<c>record_tag</c>. Use this option to omit
the verification code.</p>
</item>
@@ -390,79 +387,87 @@ module.beam: module.erl \
<tag><c>{no_auto_import,[{F,A}, ...]}</c></tag>
<item>
<p>Makes the function <c>F/A</c> no longer being
- auto-imported from the module <c>erlang</c>, which resolves
- BIF name clashes. This option has to be used to resolve name
- clashes with BIFs auto-imported before R14A, if one wants to
+ auto-imported from the <c>erlang</c> module, which resolves
+ BIF name clashes. This option must be used to resolve name
+ clashes with BIFs auto-imported before R14A, if it is needed to
call the local function with the same name as an
auto-imported BIF without module prefix.</p>
<note>
- <p>From R14A and forward, the compiler resolves calls
+ <p>As from R14A and forward, the compiler resolves calls
without module prefix to local or imported functions before
- trying auto-imported BIFs. If the BIF is to be
+ trying with auto-imported BIFs. If the BIF is to be
called, use the <c>erlang</c> module prefix in the call, not
- <c>{ no_auto_import,[{F,A}, ...]}</c></p>
+ <c>{ no_auto_import,[{F,A}, ...]}</c>.</p>
</note>
<p>If this option is written in the source code, as a
<c>-compile</c> directive, the syntax <c>F/A</c> can be used instead
- of <c>{F,A}</c>. Example:</p>
+ of <c>{F,A}</c>, for example:</p>
<code>-compile({no_auto_import,[error/1]}).</code>
</item>
<tag><c>no_auto_import</c></tag>
<item>
- <p>Do not auto import any functions from the module <c>erlang</c>.</p>
+ <p>Do not auto-import any functions from <c>erlang</c> module.</p>
</item>
<tag><c>no_line_info</c></tag>
<item>
- <p>Omit line number information in order to produce a slightly
+ <p>Omits line number information to produce a slightly
smaller output file.
</p>
</item>
</taglist>
- <p>If warnings are turned on (the <c>report_warnings</c> option
- described above), the following options control what type of
- warnings that will be generated.
+ <p>If warnings are turned on (option <c>report_warnings</c>
+ described earlier), the following options control what type of
+ warnings that are generated.
<marker id="erl_lint_options"></marker>
- With the exception of <c>{warn_format,Verbosity}</c> all
- options below have two forms; one <c>warn_xxx</c> form to
- turn on the warning and one <c>nowarn_xxx</c> form to turn off
- the warning. In the description that follows, the form that
- is used to change the default value is listed.</p>
+ Except from <c>{warn_format,Verbosity}</c>, the following options
+ have two forms:</p>
+ <list type="bulleted">
+ <item>A <c>warn_xxx</c> form, to turn on the warning.</item>
+ <item>A <c>nowarn_xxx</c> form, to turn off the warning.</item>
+ </list>
+ <p>In the descriptions that follow, the form that is used to change
+ the default value are listed.</p>
<taglist>
<tag><c>{warn_format, Verbosity}</c></tag>
<item>
<p>Causes warnings to be emitted for malformed format
strings as arguments to <c>io:format</c> and similar
- functions. <c>Verbosity</c> selects the amount of
- warnings: 0 = no warnings; 1 = warnings for invalid
- format strings and incorrect number of arguments; 2 =
- warnings also when the validity could not be checked
- (for example, when the format string argument is a
- variable). The default verbosity is 1. Verbosity 0 can
- also be selected by the option <c>nowarn_format</c>.</p>
+ functions.</p>
+ <p><c>Verbosity</c> selects the number of warnings:</p>
+ <list type="bulleted">
+ <item><c>0</c> = No warnings</item>
+ <item><c>1</c> = Warnings for invalid format strings and incorrect
+ number of arguments</item>
+ <item><c>2</c> = Warnings also when the validity cannot
+ be checked, for example, when the format string argument is a
+ variable.</item>
+ </list>
+ <p>The default verbosity is <c>1</c>. Verbosity <c>0</c> can
+ also be selected by option <c>nowarn_format</c>.</p>
</item>
<tag><c>nowarn_bif_clash</c></tag>
<item>
- <p>This option is removed, it will generate a fatal error if used.</p>
+ <p>This option is removed, it generates a fatal error if used.</p>
<warning>
- <p>Beginning with R14A, the compiler no longer calls the
+ <p>As from beginning with R14A, the compiler no longer calls the
auto-imported BIF if the name clashes with a local or
- explicitly imported function and a call without explicit
- module name is issued. Instead the local or imported
- function is called. Still accepting <c>nowarn_bif_clash</c> would makes a
- module calling functions clashing with autoimported BIFs
+ explicitly imported function, and a call without explicit
+ module name is issued. Instead, the local or imported
+ function is called. Still accepting <c>nowarn_bif_clash</c> would
+ make a module calling functions clashing with auto-imported BIFs
compile with both the old and new compilers, but with
- completely different semantics, why the option was removed.</p>
+ completely different semantics. This is why the option is removed.</p>
- <p>The use of this option has always been strongly discouraged.
- From OTP R14A and forward it's an error to use it.</p>
+ <p>The use of this option has always been discouraged.
+ As from R14A, it is an error to use it.</p>
<p>To resolve BIF clashes, use explicit module names or the
<c>{no_auto_import,[F/A]}</c> compiler directive.</p>
</warning>
@@ -470,11 +475,11 @@ module.beam: module.erl \
<tag><c>{nowarn_bif_clash, FAs}</c></tag>
<item>
- <p>This option is removed, it will generate a fatal error if used.</p>
+ <p>This option is removed, it generates a fatal error if used.</p>
<warning>
- <p>The use of this option has always been strongly discouraged.
- From OTP R14A and forward it's an error to use it.</p>
+ <p>The use of this option has always been discouraged.
+ As from R14A, it is an error to use it.</p>
<p>To resolve BIF clashes, use explicit module names or the
<c>{no_auto_import,[F/A]}</c> compiler directive.</p>
</warning>
@@ -482,35 +487,29 @@ module.beam: module.erl \
<tag><c>warn_export_all</c></tag>
<item>
- <p>Causes a warning to be emitted if the <c>export_all</c>
- option has also been given.</p>
+ <p>Emits a warning if option <c>export_all</c> is also given.</p>
</item>
<tag><c>warn_export_vars</c></tag>
<item>
- <p>Causes warnings to be emitted for all implicitly
- exported variables referred to after the primitives
- where they were first defined. No warnings for exported
- variables unless they are referred to in some pattern,
- which is the default, can be selected by the option
- <c>nowarn_export_vars</c>.</p>
+ <p>Emits warnings for all implicitly exported variables
+ referred to after the primitives where they were first defined.
+ By default, the compiler only emits warnings for exported
+ variables referred to in a pattern.</p>
</item>
- <tag><c>warn_shadow_vars</c></tag>
+ <tag><c>nowarn_shadow_vars</c></tag>
<item>
- <p>Causes warnings to be emitted for "fresh" variables
- in functional objects or list comprehensions with the same
- name as some already defined variable. The default is to
- warn for such variables. No warnings for shadowed
- variables can be selected by the option
- <c>nowarn_shadow_vars</c>.</p>
+ <p>Turns off warnings for "fresh" variables
+ in functional objects or list comprehensions with the same
+ name as some already defined variable. Default is to
+ emit warnings for such variables.</p>
</item>
<tag><c>nowarn_unused_function</c></tag>
<item>
- <p>Turns off warnings for unused local functions.
- By default (<c>warn_unused_function</c>), warnings are
- emitted for all local functions that are not called
+ <p>Turns off warnings for unused local functions. Default
+ is to emit warnings for all local functions that are not called
directly or indirectly by an exported function.
The compiler does not include unused local functions in
the generated beam file, but the warning is still useful
@@ -519,148 +518,142 @@ module.beam: module.erl \
<tag><c>{nowarn_unused_function, FAs}</c></tag>
<item>
- <p>Turns off warnings for unused local functions as
- <c>nowarn_unused_function</c> but only for the mentioned
+ <p>Turns off warnings for unused local functions like
+ <c>nowarn_unused_function</c> does, but only for the mentioned
local functions. <c>FAs</c> is a tuple <c>{Name,Arity}</c>
or a list of such tuples.</p>
</item>
<tag><c>nowarn_deprecated_function</c></tag>
<item>
- <p>Turns off warnings for calls to deprecated functions. By
- default (<c>warn_deprecated_function</c>), warnings are
- emitted for every call to a function known by the compiler
- to be deprecated. Note that the compiler does not know
- about the <c>-deprecated()</c> attribute but uses an
+ <p>Turns off warnings for calls to deprecated functions. Default
+ is to emit warnings for every call to a function known by the
+ compiler to be deprecated. Notice that the compiler does not know
+ about attribute <c>-deprecated()</c>, but uses an
assembled list of deprecated functions in Erlang/OTP. To
- do a more general check the <c>Xref</c> tool can be used.
+ do a more general check, the <c>Xref</c> tool can be used.
See also
<seealso marker="tools:xref#deprecated_function">xref(3)</seealso>
and the function
- <seealso marker="tools:xref#m/1">xref:m/1</seealso> also
- accessible through
- the <seealso marker="stdlib:c#xm/1">c:xm/1</seealso>
- function.</p>
+ <seealso marker="tools:xref#m/1">xref:m/1</seealso>, also
+ accessible through the function
+ <seealso marker="stdlib:c#xm/1">c:xm/1</seealso>.</p>
</item>
<tag><c>{nowarn_deprecated_function, MFAs}</c></tag>
<item>
- <p>Turns off warnings for calls to deprecated functions as
- <c>nowarn_deprecated_function</c> but only for
+ <p>Turns off warnings for calls to deprecated functions like
+ <c>nowarn_deprecated_function</c> does, but only for
the mentioned functions. <c>MFAs</c> is a tuple
<c>{Module,Name,Arity}</c> or a list of such tuples.</p>
</item>
<tag><c>nowarn_deprecated_type</c></tag>
<item>
- <p>Turns off warnings for uses of deprecated types. By
- default (<c>warn_deprecated_type</c>), warnings are
- emitted for every use of a type known by the compiler
- to be deprecated.</p>
+ <p>Turns off warnings for use of deprecated types. Default
+ is to emit warnings for every use of a type known by the compiler
+ to be deprecated.</p>
</item>
<tag><c>warn_obsolete_guard</c></tag>
<item>
- <p>Causes warnings to be emitted for calls to old type
- testing BIFs such as <c>pid/1</c> and <c>list/1</c>. See
- the
- <seealso marker="doc/reference_manual:expressions#guards">Erlang Reference Manual</seealso>
+ <p>Emits warnings for calls to old type testing BIFs,
+ such as <c>pid/1</c> and <c>list/1</c>. See the
+ <seealso marker="doc/reference_manual:expressions#guards">Erlang Reference Manual</seealso>
for a complete list of type testing BIFs and their old
- equivalents. No warnings for calls to old type testing
- BIFs, which is the default, can be selected by the option
- <c>nowarn_obsolete_guard</c>.</p>
+ equivalents. Default is to emit no warnings for calls to
+ old type testing BIFs.</p>
</item>
<tag><c>warn_unused_import</c></tag>
<item>
- <p>Causes warnings to be emitted for unused imported
- functions. No warnings for unused imported functions,
- which is the default, can be selected by the option
- <c>nowarn_unused_import</c>. </p>
+ <p>Emits warnings for unused imported functions.
+ Default is to emit no warnings for unused imported functions.</p>
</item>
<tag><c>nowarn_unused_vars</c></tag>
<item>
- <p>By default, warnings are emitted for variables which
- are not used, with the exception of variables beginning
- with an underscore ("Prolog style warnings").
+ <p>By default, warnings are emitted for unused variables,
+ except for variables beginning with an underscore
+ ("Prolog style warnings").
Use this option to turn off this kind of warnings.</p>
</item>
<tag><c>nowarn_unused_record</c></tag>
<item>
- <p>Turns off warnings for unused record types. By
- default (<c>warn_unused_records</c>), warnings are
- emitted for unused locally defined record types.</p>
+ <p>Turns off warnings for unused record types. Default is to
+ emit warnings for unused locally defined record types.</p>
</item>
</taglist>
<p>Another class of warnings is generated by the compiler
during optimization and code generation. They warn about
patterns that will never match (such as <c>a=b</c>), guards
- that will always evaluate to false, and expressions that will
+ that always evaluate to false, and expressions that
always fail (such as <c>atom+42</c>).</p>
-
- <p>Note that the compiler does not warn for expressions that it
- does not attempt to optimize. For instance, the compiler tries
- to evaluate <c>1/0</c>, notices that it will cause an
- exception and emits a warning. On the other hand,
- the compiler is silent about the similar expression
- <c>X/0</c>; because of the variable in it, the compiler does
- not even try to evaluate and therefore it emits no warnings.
- </p>
-
- <p>Currently, those warnings cannot be disabled (except by
+ <p>Those warnings cannot be disabled (except by
disabling all warnings).</p>
+ <note>
+ <p>The compiler does not warn for expressions that it
+ does not attempt to optimize. For example, the compiler tries
+ to evaluate <c>1/0</c>, detects that it will cause an
+ exception, and emits a warning. However,
+ the compiler is silent about the similar expression,
+ <c>X/0</c>, because of the variable in it. Thus, the compiler does
+ not even try to evaluate and therefore it emits no warnings.</p>
+ </note>
+
<warning>
- <p>Obviously, the absence of warnings does not mean that
+ <p>The absence of warnings does not mean that
there are no remaining errors in the code.</p>
</warning>
-
- <p>Note that all the options except the include path
- (<c>{i,Dir}</c>) can also be given in the file with a
- <c>-compile([Option,...])</c>. attribute.
- The <c>-compile()</c> attribute is allowed after function
+
+ <note>
+ <p>All options, except the include path
+ (<c>{i,Dir}</c>), can also be given in the file with attribute
+ <c>-compile([Option,...])</c>.
+ Attribute <c>-compile()</c> is allowed after the function
definitions.</p>
-
- <p>Note also that the <c>{nowarn_unused_function, FAs}</c>,
+ </note>
+
+ <note>
+ <p>The options <c>{nowarn_unused_function, FAs}</c>,
<c>{nowarn_bif_clash, FAs}</c>, and
- <c>{nowarn_deprecated_function, MFAs}</c> options are only
+ <c>{nowarn_deprecated_function, MFAs}</c> are only
recognized when given in files. They are not affected by
- the <c>warn_unused_function</c>, <c>warn_bif_clash</c>, or
- <c>warn_deprecated_function</c> options.</p>
+ options <c>warn_unused_function</c>, <c>warn_bif_clash</c>, or
+ <c>warn_deprecated_function</c>.</p>
+ </note>
<p>For debugging of the compiler, or for pure curiosity,
the intermediate code generated by each compiler pass can be
inspected.
- A complete list of the options to produce list files can be
- printed by typing <c>compile:options()</c> at the Erlang
- shell prompt.
- The options will be printed in order that the passes are
+ To print a complete list of the options to produce list files,
+ type <c>compile:options()</c> at the Erlang shell prompt.
+ The options are printed in the order that the passes are
executed. If more than one listing option is used, the one
representing the earliest pass takes effect.</p>
- <p><em>Unrecognized options are ignored.</em></p>
+ <p>Unrecognized options are ignored.</p>
<p>Both <c>WarningList</c> and <c>ErrorList</c> have
the following format:</p>
<code>
-[{FileName,[ErrorInfo]}].
- </code>
-
- <p><c>ErrorInfo</c> is described below. The file name has been
- included here as the compiler uses the Erlang pre-processor
- <c>epp</c>, which allows the code to be included in other
- files. For this reason, it is important to know to
- <em>which</em> file an error or warning line number refers.
+[{FileName,[ErrorInfo]}].</code>
+
+ <p><c>ErrorInfo</c> is described later in this section.
+ The filename is included here, as the compiler uses the
+ Erlang pre-processor <c>epp</c>, which allows the code to be
+ included in other files. It is therefore important to know to
+ <em>which</em> file the line number of an error or a warning refers.
</p>
</desc>
</func>
<func>
<name>forms(Forms)</name>
- <fsummary>Compile a list of forms</fsummary>
+ <fsummary>Compiles a list of forms.</fsummary>
<desc>
<p>Is the same as
<c>forms(File, [verbose,report_errors,report_warnings])</c>.
@@ -670,7 +663,7 @@ module.beam: module.erl \
<func>
<name>forms(Forms, Options) -> CompRet</name>
- <fsummary>Compile a list of forms</fsummary>
+ <fsummary>Compiles a list of forms.</fsummary>
<type>
<v>Forms = [Form]</v>
<v>CompRet = BinRet | ErrRet</v>
@@ -681,48 +674,49 @@ module.beam: module.erl \
<desc>
<p>Analogous to <c>file/1</c>, but takes a list of forms (in
the Erlang abstract format representation) as first argument.
- The option <c>binary</c> is implicit; i.e., no object code
- file is produced. Options that would ordinarily produce a
- listing file, such as 'E', will instead cause the internal
- format for that compiler pass (an Erlang term; usually not a
- binary) to be returned instead of a binary.</p>
+ Option <c>binary</c> is implicit, that is, no object code
+ file is produced. For options that normally produce a listing
+ file, such as 'E', the internal format for that compiler pass
+ (an Erlang term, usually not a binary) is returned instead of
+ a binary.</p>
</desc>
</func>
<func>
<name>format_error(ErrorDescriptor) -> chars()</name>
- <fsummary>Format an error descriptor</fsummary>
+ <fsummary>Formats an error descriptor.</fsummary>
<type>
<v>ErrorDescriptor = errordesc()</v>
</type>
<desc>
<p>Uses an <c>ErrorDescriptor</c> and returns a deep list of
- characters which describes the error. This function is
- usually called implicitly when an <c>ErrorInfo</c> structure
- is processed. See below.</p>
+ characters that describes the error. This function is
+ usually called implicitly when an <c>ErrorInfo</c> structure
+ (described in section
+ <seealso marker="#error_information">Error Information</seealso>) is processed.</p>
</desc>
</func>
<func>
<name>output_generated(Options) -> true | false</name>
- <fsummary>Determine whether the compile will generate an output file</fsummary>
+ <fsummary>Determines whether the compiler generates an output file.</fsummary>
<type>
<v>Options = [term()]</v>
</type>
<desc>
- <p>Determines whether the compiler would generate a <c>beam</c>
+ <p>Determines whether the compiler generates a <c>beam</c>
file with the given options. <c>true</c> means that a <c>beam</c>
- file would be generated; <c>false</c> means that the compiler
- would generate some listing file, return a binary, or merely
- check the syntax of the source code.</p>
+ file is generated. <c>false</c> means that the compiler
+ generates some listing file, returns a binary, or merely
+ checks the syntax of the source code.</p>
</desc>
</func>
<func>
<name>noenv_file(File, Options) -> CompRet</name>
- <fsummary>Compile a file (ignoring ERL_COMPILER_OPTIONS)</fsummary>
+ <fsummary>Compiles a file (ignoring <c>ERL_COMPILER_OPTIONS)</c>.</fsummary>
<desc>
- <p>Works exactly like <seealso marker="#file/2">file/2</seealso>,
+ <p>Works like <seealso marker="#file/2">file/2</seealso>,
except that the environment variable <c>ERL_COMPILER_OPTIONS</c>
is not consulted.</p>
</desc>
@@ -730,9 +724,9 @@ module.beam: module.erl \
<func>
<name>noenv_forms(Forms, Options) -> CompRet</name>
- <fsummary>Compile a list of forms (ignoring ERL_COMPILER_OPTIONS)</fsummary>
+ <fsummary>Compiles a list of forms (ignoring <c>ERL_COMPILER_OPTIONS)</c>.</fsummary>
<desc>
- <p>Works exactly like <seealso marker="#forms/2">forms/2</seealso>,
+ <p>Works like <seealso marker="#forms/2">forms/2</seealso>,
except that the environment variable <c>ERL_COMPILER_OPTIONS</c>
is not consulted.</p>
</desc>
@@ -740,12 +734,13 @@ module.beam: module.erl \
<func>
<name>noenv_output_generated(Options) -> true | false</name>
- <fsummary>Determine whether the compile will generate an output file (ignoring ERL_COMPILER_OPTIONS)</fsummary>
+ <fsummary>Determines whether the compiler generates an output file
+ (ignoring <c>ERL_COMPILER_OPTIONS)</c>.</fsummary>
<type>
<v>Options = [term()]</v>
</type>
<desc>
- <p>Works exactly like
+ <p>Works like
<seealso marker="#output_generated/1">output_generated/1</seealso>,
except that the environment variable <c>ERL_COMPILER_OPTIONS</c>
is not consulted.</p>
@@ -755,14 +750,14 @@ module.beam: module.erl \
</funcs>
<section>
- <title>Default compiler options</title>
+ <title>Default Compiler Options</title>
<p>The (host operating system) environment variable
<c>ERL_COMPILER_OPTIONS</c> can be used to give default compiler
options. Its value must be a valid Erlang term. If the value is a
- list, it will be used as is. If it is not a list, it will be put
+ list, it is used as is. If it is not a list, it is put
into a list.</p>
- <p>The list will be appended to any options given to
+ <p>The list is appended to any options given to
<seealso marker="#file/2">file/2</seealso>,
<seealso marker="#forms/2">forms/2</seealso>, and
<seealso marker="#output_generated/1">output_generated/2</seealso>.
@@ -770,9 +765,9 @@ module.beam: module.erl \
<seealso marker="#noenv_file/2">noenv_file/2</seealso>,
<seealso marker="#noenv_forms/2">noenv_forms/2</seealso>, or
<seealso marker="#noenv_output_generated/1">noenv_output_generated/2</seealso>
- if you don't want the environment variable to be consulted
- (for instance, if you are calling the compiler recursively from
- inside a parse transform).</p>
+ if you do not want the environment variable to be consulted,
+ for example, if you are calling the compiler recursively from
+ inside a parse transform.</p>
</section>
<section>
@@ -781,31 +776,31 @@ module.beam: module.erl \
module. Inlining means that a call to a function is replaced with
the function body with the arguments replaced with the actual
values. The semantics are preserved, except if exceptions are
- generated in the inlined code. Exceptions will be reported as
+ generated in the inlined code. Exceptions are reported as
occurring in the function the body was inlined into. Also,
- <c>function_clause</c> exceptions will be converted to similar
+ <c>function_clause</c> exceptions are converted to similar
<c>case_clause</c> exceptions.</p>
- <p>When a function is inlined, the original function will be
+ <p>When a function is inlined, the original function is
kept if it is exported (either by an explicit export or if the
- <c>export_all</c> option was given) or if not all calls to the
- function were inlined.</p>
+ option <c>export_all</c> was given) or if not all calls to the
+ function are inlined.</p>
<p>Inlining does not necessarily improve running time.
- For instance, inlining may increase Beam stack usage which will
- probably be detrimental to performance for recursive functions.
+ For example, inlining can increase Beam stack use, which
+ probably is detrimental to performance for recursive functions.
</p>
- <p>Inlining is never default; it must be explicitly enabled with a
+ <p>Inlining is never default. It must be explicitly enabled with a
compiler option or a <c>-compile()</c> attribute in the source
module.</p>
- <p>To enable inlining, either use the <c>inline</c> option to
- let the compiler decide which functions to inline or
+ <p>To enable inlining, either use the option <c>inline</c> to
+ let the compiler decide which functions to inline, or
<c>{inline,[{Name,Arity},...]}</c> to have the compiler inline
all calls to the given functions. If the option is given inside
a <c>compile</c> directive in an Erlang module, <c>{Name,Arity}</c>
- may be written as <c>Name/Arity</c>.</p>
+ can be written as <c>Name/Arity</c>.</p>
<p>Example of explicit inlining:</p>
@@ -817,33 +812,30 @@ pi() -> 3.1416.
<p>Example of implicit inlining:</p>
<pre>
--compile(inline).
- </pre>
+-compile(inline).</pre>
- <p>The <c>{inline_size,Size}</c> option controls how large functions
- that are allowed to be inlined. Default is <c>24</c>, which will
- keep the size of the inlined code roughly the same as
- the un-inlined version (only relatively small functions will be
+ <p>The option <c>{inline_size,Size}</c> controls how large functions
+ that are allowed to be inlined. Default is <c>24</c>, which
+ keeps the size of the inlined code roughly the same as
+ the un-inlined version (only relatively small functions are
inlined).</p>
<p>Example:</p>
<pre>
%% Aggressive inlining - will increase code size.
-compile(inline).
--compile({inline_size,100}).
- </pre>
+-compile({inline_size,100}).</pre>
</section>
<section>
- <title>Inlining of list functions</title>
- <p>The compiler can also inline a variety of list manipulation functions
- from the stdlib's lists module.</p>
+ <title>Inlining of List Functions</title>
+ <p>The compiler can also inline various list manipulation functions
+ from the module <c>list</c> in <c>STDLIB</c>.</p>
<p>This feature must be explicitly enabled with a compiler option or a
<c>-compile()</c> attribute in the source module.</p>
- <p>To enable inlining of list functions, use the <c>inline_list_funcs</c>
- option.</p>
+ <p>To enable inlining of list functions, use option <c>inline_list_funcs</c>.</p>
<p>The following functions are inlined:</p>
<list type="bulleted">
@@ -869,24 +861,23 @@ pi() -> 3.1416.
</section>
<section>
+ <marker id="error_information"></marker>
<title>Error Information</title>
- <p>The <c>ErrorInfo</c> mentioned above is the standard
- <c>ErrorInfo</c> structure which is returned from all IO modules.
+ <p>The <c>ErrorInfo</c> mentioned earlier is the standard
+ <c>ErrorInfo</c> structure, which is returned from all I/O modules.
It has the following format:</p>
<code>
-{ErrorLine, Module, ErrorDescriptor}
- </code>
+{ErrorLine, Module, ErrorDescriptor}</code>
- <p><c>ErrorLine</c> will be the atom <c>none</c> if the error does
- not correspond to a specific line (e.g. if the source file does
- not exist).</p>
+ <p><c>ErrorLine</c> is the atom <c>none</c> if the error does
+ not correspond to a specific line, for example, if the source file does
+ not exist.</p>
<p>A string describing the error is obtained with the following
call:</p>
<code>
-Module:format_error(ErrorDescriptor)
- </code>
+Module:format_error(ErrorDescriptor)</code>
</section>
<section>
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 9b5b44f3e1..8ed71db54a 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,211 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 6.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An complicated guard expression in a function call could
+ crash the compiler. (Thanks to Thomas Arts for reporting
+ this bug.)</p>
+ <p>
+ Own Id: OTP-13208</p>
+ </item>
+ <item>
+ <p>Constructing a map in a guard in a catch could crash
+ the compiler. (Thanks to Thomas Arts for reporting this
+ bug.)</p>
+ <p>
+ Own Id: OTP-13223</p>
+ </item>
+ <item>
+ <p>Updating a fun as if it were a map would cause the
+ compiler to crash. (Thanks to Thomas Arts for reporting
+ this bug.)</p>
+ <p>
+ Own Id: OTP-13231</p>
+ </item>
+ <item>
+ <p>
+ Fix pretty printing of Core Maps</p>
+ <p>
+ Literal maps could cause Dialyzer to crash when pretty
+ printing the results.</p>
+ <p>
+ Own Id: OTP-13238</p>
+ </item>
+ <item>
+ <p>
+ A complex combination of bit syntax matching operations
+ would cause an internal consistency check failure during
+ compilation. (Thanks to Jose Valim for reporting this
+ bug.)</p>
+ <p>
+ Own Id: OTP-13309</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 6.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix cerl_trees:label/2 bug with map K/V swap</p>
+ <p>
+ Own Id: OTP-13091</p>
+ </item>
+ <item>
+ <p>
+ Warnings produced when the '<c>bin_opt_info</c>' option
+ was given could sometimes lack filenames and line
+ numbers. (Thanks to José Valim for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13113</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 6.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix <c>get_map_elements</c> register corruption</p>
+ <p>
+ Instruction <c>get_map_elements</c> might destroy target
+ registers when the fail-label is taken. Only seen for
+ patterns with two, and only two, target registers.
+ Specifically if we copy one register and then jump.</p>
+ <p>
+ Own Id: OTP-12967</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 6.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The compiler optimizes away building of terms that are
+ never actually used. As a result, the compiler in OTP 18
+ may produce more warnings for terms that are built but
+ not used than the compiler in OTP 17.</p>
+ <p>
+ Own Id: OTP-12453</p>
+ </item>
+ <item>
+ <p>
+ Using a map could incorrectly suppress warnings for
+ unused variables.</p>
+ <p>
+ Own Id: OTP-12515</p>
+ </item>
+ <item>
+ <p>
+ The compiler now properly reports unknown parse
+ transforms. That is, <c>undef</c> exceptions coming from
+ the parse transform itself is reported differently from
+ the absence of the parse transform.</p>
+ <p>
+ Own Id: OTP-12723</p>
+ </item>
+ <item>
+ <p>
+ Allow for 'creation of sub binary delayed' optimization
+ if maps instructions are in a clause.</p>
+ <p>
+ Own Id: OTP-12758</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The <c>cerl</c> and <c>cerl_trees</c> modules in the
+ <c>compiler</c> application are now documented.</p>
+ <p>
+ Own Id: OTP-11978</p>
+ </item>
+ <item>
+ <p>
+ The deprecated '<c>asm</c>' option has been removed.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12100</p>
+ </item>
+ <item>
+ <p>
+ Support variables as Map keys in expressions and patterns</p>
+ <p>Erlang will accept any expression as keys in Map
+ expressions and it will accept literals or bound
+ variables as keys in Map patterns.</p>
+ <p>
+ Own Id: OTP-12218</p>
+ </item>
+ <item>
+ <p>
+ Infer Map type information in beam_type compiler
+ optimization pass.</p>
+ <p>
+ Own Id: OTP-12253</p>
+ </item>
+ <item>
+ <p>
+ Compiler optimizations have been improved.</p>
+ <p>
+ Own Id: OTP-12393</p>
+ </item>
+ <item>
+ <p>
+ Five undocumented functions in the module <c>core_lib</c>
+ have been deprecated and will be removed in the next
+ major release. The functions are: <c>get_anno/{1,2}</c>,
+ <c>is_literal/1</c>, <c>is_literal_list/1</c>, and
+ <c>literal_value</c>. Use the appropriate functions in
+ the <c>cerl</c> module instead.</p>
+ <p>
+ Own Id: OTP-12497</p>
+ </item>
+ <item>
+ <p>
+ Change some internal data structures to Maps in order to
+ speed up compilation time. Measured speed up is around
+ 10%-15%.</p>
+ <p>
+ Own Id: OTP-12774</p>
+ </item>
+ <item>
+ <p>
+ Fix beam_bool pass for Maps instruction get_map_elements</p>
+ <p>
+ Before beam_split the get_map_elements instruction is
+ still in blocks and the helper function in beam_jump did
+ not reflect this.</p>
+ <p>
+ Own Id: OTP-12844 Aux Id: 17 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 5.0.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -324,22 +530,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
diff --git a/lib/compiler/doc/src/notes_history.xml b/lib/compiler/doc/src/notes_history.xml
index 9e8934f416..85216b2c66 100644
--- a/lib/compiler/doc/src/notes_history.xml
+++ b/lib/compiler/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/compiler/doc/src/part_notes.xml b/lib/compiler/doc/src/part_notes.xml
index 0c1fdd567d..5000f50dca 100644
--- a/lib/compiler/doc/src/part_notes.xml
+++ b/lib/compiler/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/compiler/doc/src/part_notes_history.xml b/lib/compiler/doc/src/part_notes_history.xml
index a4909f156e..046b4893c3 100644
--- a/lib/compiler/doc/src/part_notes_history.xml
+++ b/lib/compiler/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/compiler/doc/src/ref_man.xml b/lib/compiler/doc/src/ref_man.xml
index 6478ad4b11..d360e7963f 100644
--- a/lib/compiler/doc/src/ref_man.xml
+++ b/lib/compiler/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,7 +30,7 @@
<file>application.sgml</file>
</header>
<description>
- <p>The <em>Compiler</em> application compiles Erlang
+ <p>The <c>Compiler</c> application compiles Erlang
code to byte-code. The highly compact byte-code is executed by
the Erlang emulator.</p>
</description>
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index c6d09d85eb..299b2892fc 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -70,6 +71,7 @@ MODULES = \
cerl \
cerl_clauses \
cerl_inline \
+ cerl_sets \
cerl_trees \
compile \
core_lib \
@@ -81,6 +83,7 @@ MODULES = \
rec_env \
sys_core_dsetel \
sys_core_fold \
+ sys_core_fold_lists \
sys_core_inline \
sys_pre_attributes \
sys_pre_expand \
@@ -158,6 +161,10 @@ $(EBIN)/beam_asm.beam: $(ESRC)/beam_asm.erl $(EGEN)/beam_opcodes.hrl
$(EBIN)/cerl_inline.beam: $(ESRC)/cerl_inline.erl
$(V_ERLC) $(ERL_COMPILE_FLAGS) +nowarn_shadow_vars -o$(EBIN) $<
+# Inlining core_parse is slow and has no benefit.
+$(EBIN)/core_parse.beam: $(EGEN)/core_parse.erl
+ $(V_ERLC) $(subst +inline,,$(ERL_COMPILE_FLAGS)) -o$(EBIN) $<
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -187,6 +194,7 @@ $(EBIN)/core_parse.beam: core_parse.hrl $(EGEN)/core_parse.erl
$(EBIN)/core_pp.beam: core_parse.hrl
$(EBIN)/sys_core_dsetel.beam: core_parse.hrl
$(EBIN)/sys_core_fold.beam: core_parse.hrl
+$(EBIN)/sys_core_fold_lists.beam: core_parse.hrl
$(EBIN)/sys_core_inline.beam: core_parse.hrl
$(EBIN)/sys_pre_expand.beam: ../../stdlib/include/erl_bits.hrl
$(EBIN)/v3_codegen.beam: v3_life.hrl
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl
index fe4f473846..f0f2ee08c2 100644
--- a/lib/compiler/src/beam_a.erl
+++ b/lib/compiler/src/beam_a.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -54,6 +55,9 @@ rename_instrs([{call_only,A,F}|Is]) ->
[{call,A,F},return|rename_instrs(Is)];
rename_instrs([{call_ext_only,A,F}|Is]) ->
[{call_ext,A,F},return|rename_instrs(Is)];
+rename_instrs([{'%live',_}|Is]) ->
+ %% When compiling from old .S files.
+ rename_instrs(Is);
rename_instrs([I|Is]) ->
[rename_instr(I)|rename_instrs(Is)];
rename_instrs([]) -> [].
@@ -88,6 +92,10 @@ rename_instr({bs_private_append=I,F,Sz,U,Src,Flags,Dst}) ->
{bs_init,F,{I,U,Flags},none,[Sz,Src],Dst};
rename_instr(bs_init_writable=I) ->
{bs_init,{f,0},I,1,[{x,0}],{x,0}};
+rename_instr({test,Op,F,[Ctx,Bits,{string,Str}]}) ->
+ %% When compiling from a .S file.
+ <<Bs:Bits/bits,_/bits>> = list_to_binary(Str),
+ {test,Op,F,[Ctx,Bs]};
rename_instr({put_map_assoc,Fail,S,D,R,L}) ->
{put_map,Fail,assoc,S,D,R,L};
rename_instr({put_map_exact,Fail,S,D,R,L}) ->
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index f8cf178d2e..a3201b0f4a 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -132,10 +133,10 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) ->
LiteralChunk = case beam_dict:literal_table(Dict) of
{0,[]} -> [];
{NumLiterals,LitTab0} ->
- LitTab1 = iolist_to_binary(LitTab0),
- LitTab2 = <<NumLiterals:32,LitTab1/binary>>,
- LitTab = iolist_to_binary(zlib:compress(LitTab2)),
- chunk(<<"LitT">>, <<(byte_size(LitTab2)):32>>, LitTab)
+ LitTab1 = [<<NumLiterals:32>>,LitTab0],
+ LitTab = zlib:compress(LitTab1),
+ chunk(<<"LitT">>, <<(iolist_size(LitTab1)):32>>,
+ LitTab)
end,
%% Create the line chunk.
@@ -431,45 +432,35 @@ encode_alloc_list_1([], Dict, Acc) ->
{iolist_to_binary(Acc),Dict}.
encode(Tag, N) when N < 0 ->
- encode1(Tag, negative_to_bytes(N, []));
+ encode1(Tag, negative_to_bytes(N));
encode(Tag, N) when N < 16 ->
(N bsl 4) bor Tag;
encode(Tag, N) when N < 16#800 ->
[((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff];
encode(Tag, N) ->
- encode1(Tag, to_bytes(N, [])).
+ encode1(Tag, to_bytes(N)).
encode1(Tag, Bytes) ->
- case length(Bytes) of
+ case iolist_size(Bytes) of
Num when 2 =< Num, Num =< 8 ->
[((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes];
Num when 8 < Num ->
[2#11111000 bor Tag, encode(?tag_u, Num-9)| Bytes]
end.
-
-to_bytes(N0, Acc) ->
- Bits = 3*128,
- case N0 bsr Bits of
- 0 ->
- to_bytes_1(N0, Acc);
- N ->
- to_bytes(N, binary_to_list(<<N0:Bits>>) ++ Acc)
- end.
-
-to_bytes_1(0, [B|_]=Done) when B < 128 -> Done;
-to_bytes_1(N, Acc) -> to_bytes(N bsr 8, [N band 16#ff|Acc]).
-
-negative_to_bytes(N0, Acc) ->
- Bits = 3*128,
- case N0 bsr Bits of
- -1 ->
- negative_to_bytes_1(N0, Acc);
- N ->
- negative_to_bytes_1(N, binary_to_list(<<N0:Bits>>) ++ Acc)
+to_bytes(N) ->
+ Bin = binary:encode_unsigned(N),
+ case Bin of
+ <<0:1,_/bits>> -> Bin;
+ <<1:1,_/bits>> -> [0,Bin]
end.
-negative_to_bytes_1(-1, [B1,_B2|_]=Done) when B1 > 127 ->
- Done;
-negative_to_bytes_1(N, Acc) ->
- negative_to_bytes_1(N bsr 8, [N band 16#ff|Acc]).
+negative_to_bytes(N) when N >= -16#8000 ->
+ <<N:16>>;
+negative_to_bytes(N) ->
+ Bytes = byte_size(binary:encode_unsigned(-N)),
+ Bin = <<N:Bytes/unit:8>>,
+ case Bin of
+ <<0:1,_/bits>> -> [16#ff,Bin];
+ <<1:1,_/bits>> -> Bin
+ end.
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 7a30c68593..0321b1c07b 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -61,15 +62,6 @@ blockify(Is) ->
blockify([{loop_rec,{f,Fail},{x,0}},{loop_rec_end,_Lbl},{label,Fail}|Is], Acc) ->
%% Useless instruction sequence.
blockify(Is, Acc);
-
-%% New bit syntax matching.
-blockify([{bs_save2,R,Point}=I,{bs_restore2,R,Point}|Is], Acc) ->
- blockify([I|Is], Acc);
-blockify([{bs_save2,R,Point}=I,{test,is_eq_exact,_,_}=Test,
- {bs_restore2,R,Point}|Is], Acc) ->
- blockify([I,Test|Is], Acc);
-
-%% Do other peep-hole optimizations.
blockify([{test,is_atom,{f,Fail},[Reg]}=I|
[{select,select_val,Reg,{f,Fail},
[{atom,false},{f,_}=BrFalse,
@@ -155,7 +147,8 @@ collect(remove_message) -> {set,[],[],remove_message};
collect({put_map,F,Op,S,D,R,{list,Puts}}) ->
{set,[D],[S|Puts],{alloc,R,{put_map,Op,F}}};
collect({get_map_elements,F,S,{list,Gets}}) ->
- {set,Gets,[S],{get_map_elements,F}};
+ {Ss,Ds} = beam_utils:split_even(Gets),
+ {set,Ds,[S|Ss],{get_map_elements,F}};
collect({'catch',R,L}) -> {set,[R],[],{'catch',L}};
collect(fclearerror) -> {set,[],[],fclearerror};
collect({fcheckerror,{f,0}}) -> {set,[],[],fcheckerror};
@@ -183,7 +176,7 @@ embed_lines([], Acc) -> Acc.
opt_blocks([{block,Bl0}|Is]) ->
%% The live annotation at the beginning is not useful.
- [{'%live',_}|Bl] = Bl0,
+ [{'%live',_,_}|Bl] = Bl0,
[{block,opt_block(Bl)}|opt_blocks(Is)];
opt_blocks([I|Is]) ->
[I|opt_blocks(Is)];
@@ -251,13 +244,6 @@ combine_alloc({_,Ns,Nh1,Init}, {_,nostack,Nh2,[]}) ->
%% opt([Instruction]) -> [Instruction]
%% Optimize the instruction stream inside a basic block.
-opt([{set,[Dst],As,{bif,Bif,Fail}}=I1,
- {set,[Dst],[Dst],{bif,'not',Fail}}=I2|Is]) ->
- %% Get rid of the 'not' if the operation can be inverted.
- case inverse_comp_op(Bif) of
- none -> [I1,I2|opt(Is)];
- RevBif -> [{set,[Dst],As,{bif,RevBif,Fail}}|opt(Is)]
- end;
opt([{set,[X],[X],move}|Is]) -> opt(Is);
opt([{set,_,_,{line,_}}=Line1,
{set,[D1],[{integer,Idx1},Reg],{bif,element,{f,0}}}=I1,
@@ -265,10 +251,12 @@ opt([{set,_,_,{line,_}}=Line1,
{set,[D2],[{integer,Idx2},Reg],{bif,element,{f,0}}}=I2|Is])
when Idx1 < Idx2, D1 =/= D2, D1 =/= Reg, D2 =/= Reg ->
opt([Line2,I2,Line1,I1|Is]);
-opt([{set,Ds0,Ss,Op}|Is0]) ->
+opt([{set,[_|_],_Ss,{get_map_elements,_F}}=I|Is]) ->
+ [I|opt(Is)];
+opt([{set,Ds0,Ss,Op}|Is0]) ->
{Ds,Is} = opt_moves(Ds0, Is0),
[{set,Ds,Ss,Op}|opt(Is)];
-opt([{'%live',_}=I|Is]) ->
+opt([{'%live',_,_}=I|Is]) ->
[I|opt(Is)];
opt([]) -> [].
@@ -427,18 +415,6 @@ x_live([{x,N}|Rs], Regs) -> x_live(Rs, Regs bor (1 bsl N));
x_live([_|Rs], Regs) -> x_live(Rs, Regs);
x_live([], Regs) -> Regs.
-%% inverse_comp_op(Op) -> none|RevOp
-
-inverse_comp_op('=:=') -> '=/=';
-inverse_comp_op('=/=') -> '=:=';
-inverse_comp_op('==') -> '/=';
-inverse_comp_op('/=') -> '==';
-inverse_comp_op('>') -> '=<';
-inverse_comp_op('<') -> '>=';
-inverse_comp_op('>=') -> '<';
-inverse_comp_op('=<') -> '>';
-inverse_comp_op(_) -> none.
-
%%%
%%% Evaluation of constant bit fields.
%%%
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index a452d30b61..d14be83496 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -141,11 +142,6 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
throw:not_boolean_expr ->
failed;
- %% The block contains a 'move' instruction that could
- %% not be handled.
- throw:move ->
- failed;
-
%% The optimization is not safe. (A register
%% used by the instructions following the
%% optimized code is either not assigned a
@@ -214,37 +210,14 @@ ensure_opt_safe(Bl, NewCode, OldIs, Fail, PrecedingCode, St) ->
false -> throw(all_registers_not_killed);
true -> ok
end,
- Same = assigned_same_value(Bl, NewCode),
MustBeUnused = ordsets:subtract(ordsets:union(NotSet, NewDst),
- ordsets:union(MustBeKilled, Same)),
+ MustBeKilled),
case none_used(MustBeUnused, OldIs, Fail, St) of
false -> throw(registers_used);
true -> ok
end,
ok.
-%% assigned_same_value(OldCode, NewCodeReversed) -> [DestinationRegs]
-%% Return an ordset with a list of all y registers that are always
-%% assigned the same value in the old and new code. Currently, we
-%% are very conservative in that we only consider identical move
-%% instructions in the same order.
-%%
-assigned_same_value(Old, New) ->
- case reverse(New) of
- [{block,Bl}|_] ->
- assigned_same_value(Old, Bl, []);
- _ ->
- ordsets:new()
- end.
-
-assigned_same_value([{set,[{y,_}=D],[S],move}|T1],
- [{set,[{y,_}=D],[S],move}|T2], Acc) ->
- assigned_same_value(T1, T2, [D|Acc]);
-assigned_same_value(_, _, Acc) ->
- ordsets:from_list(Acc).
-
-update_fail_label([{set,_,_,move}=I|Is], Fail, Acc) ->
- update_fail_label(Is, Fail, [I|Acc]);
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) ->
@@ -313,8 +286,6 @@ split_block_1(Is, Fail, ProhibitFailLabel) ->
end
end.
-split_block_2([{set,_,_,move}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
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) ->
@@ -342,8 +313,6 @@ dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
-dst_regs([{set,[D],_,move}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
dst_regs([_|Is], Acc) ->
dst_regs(Is, Acc);
dst_regs([], Acc) -> ordsets:from_list(Acc).
@@ -410,13 +379,6 @@ bopt_tree([{protected,[Dst],Code,_}|Is], Forest0, Pre) ->
_Res ->
throw(not_boolean_expr)
end;
-bopt_tree([{set,[Dst],[Src],move}=Move|Is], Forest, Pre) ->
- case {Src,Dst} of
- {{tmp,_},_} -> throw(move);
- {_,{tmp,_}} -> throw(move);
- _ -> ok
- end,
- bopt_tree(Is, Forest, [Move|Pre]);
bopt_tree([{set,[Dst],As,{bif,N,_}}=Bif|Is], Forest0, Pre) ->
Ar = length(As),
case safe_bool_op(N, Ar) of
@@ -588,10 +550,6 @@ free_variables(Is) ->
E = gb_sets:empty(),
free_vars_1(Is, E, E, E).
-free_vars_1([{set,Ds,As,move}|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,{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)),
@@ -631,8 +589,6 @@ free_vars_regs(X) -> [{x,X-1}|free_vars_regs(X-1)].
rename_regs(Is, Regs) ->
rename_regs(Is, Regs, []).
-rename_regs([{set,_,_,move}=I|Is], Regs, Acc) ->
- rename_regs(Is, Regs, [I|Acc]);
rename_regs([{set,[Dst0],Ss0,{alloc,_,Info}}|Is], Regs0, Acc) ->
Live = live_regs(Regs0),
Ss = rename_sources(Ss0, Regs0),
@@ -736,8 +692,7 @@ ssa_assign({x,_}=R, #ssa{sub=Sub0}=Ssa0) ->
Sub1 = gb_trees:update(R, NewReg, Sub0),
Sub = gb_trees:insert(NewReg, NewReg, Sub1),
Ssa#ssa{sub=Sub}
- end;
-ssa_assign(_, Ssa) -> Ssa.
+ end.
ssa_sub_list(List, Sub) ->
[ssa_sub(E, Sub) || E <- List].
@@ -787,6 +742,9 @@ is_not_used(R, Is, Label, #st{ll=Ll}) ->
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) ->
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index d54c2a9fde..62356928ae 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -20,7 +21,7 @@
-module(beam_bsm).
-export([module/2,format_error/1]).
--import(lists, [member/2,foldl/3,reverse/1,sort/1,all/2,dropwhile/2]).
+-import(lists, [member/2,foldl/3,reverse/1,sort/1,all/2]).
%%%
%%% We optimize bit syntax matching where the tail end of a binary is
@@ -242,6 +243,12 @@ btb_reaches_match_2([{bif,_,{f,F},Ss,Dst}=I|Is], Regs0, D0) ->
Regs = btb_kill([Dst], Regs0),
D = btb_follow_branch(F, Regs, D0),
btb_reaches_match_1(Is, Regs, D);
+btb_reaches_match_2([{get_map_elements,{f,F},Src,{list,Ls}}=I|Is], Regs0, D0) ->
+ {Ss,Ds} = beam_utils:split_even(Ls),
+ btb_ensure_not_used([Src|Ss], I, Regs0),
+ Regs = btb_kill(Ds, Regs0),
+ D = btb_follow_branch(F, Regs, D0),
+ btb_reaches_match_1(Is, Regs, D);
btb_reaches_match_2([{test,bs_start_match2,{f,F},Live,[Ctx,_],Ctx}=I|Is],
Regs0, D0) ->
CtxRegs = btb_context_regs(Regs0),
@@ -414,7 +421,8 @@ btb_follow_branches([], _, D) -> D.
btb_follow_branch(0, _Regs, D) -> D;
btb_follow_branch(Lbl, Regs, #btb{ok_br=Br0,index=Li}=D) ->
- case gb_sets:is_member(Lbl, Br0) of
+ Key = {Lbl,Regs},
+ case gb_sets:is_member(Key, Br0) of
true ->
%% We have already followed this branch and it was OK.
D;
@@ -425,7 +433,7 @@ btb_follow_branch(Lbl, Regs, #btb{ok_br=Br0,index=Li}=D) ->
btb_reaches_match_1(Is, Regs, D),
%% Since we got back, this branch is OK.
- D#btb{ok_br=gb_sets:insert(Lbl, Br),must_not_save=MustNotSave,
+ D#btb{ok_br=gb_sets:insert(Key, Br),must_not_save=MustNotSave,
must_save=MustSave}
end.
@@ -542,16 +550,13 @@ btb_context_regs_1(Regs, N, Tag, Acc) ->
%% a binary. MustSave is true if the function may pass the match
%% context to the bs_context_to_binary instruction (in which case
%% the current position in the binary must have saved into the
-%% start position using "bs_save_2 Ctx start".
+%% start position using "bs_save_2 Ctx start").
btb_index(Fs) ->
btb_index_1(Fs, []).
btb_index_1([{function,_,_,Entry,Is0}|Fs], Acc0) ->
- [{label,Entry}|Is] =
- dropwhile(fun({label,L}) when L =:= Entry -> false;
- (_) -> true
- end, Is0),
+ Is = drop_to_label(Is0, Entry),
Acc = btb_index_2(Is, Entry, false, Acc0),
btb_index_1(Fs, Acc);
btb_index_1([], Acc) -> gb_trees:from_orddict(sort(Acc)).
@@ -566,6 +571,9 @@ btb_index_2(Is0, Entry, _, Acc) ->
throw:none -> Acc
end.
+drop_to_label([{label,L}|Is], L) -> Is;
+drop_to_label([_|Is], L) -> drop_to_label(Is, L).
+
btb_index_find_start_match([{test,_,{f,F},_},{bs_context_to_binary,_}|Is]) ->
btb_index_find_label(Is, F);
btb_index_find_start_match(_) ->
@@ -615,7 +623,7 @@ collect_warnings_instr([_|Is], D, Acc) ->
collect_warnings_instr([], _, Acc) -> Acc.
add_warning(Term, Anno, Ws) ->
- Line = abs(get_line(Anno)),
+ Line = get_line(Anno),
File = get_file(Anno),
[{File,[{Line,?MODULE,Term}]}|Ws].
diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl
index b653998252..919ee3ee7d 100644
--- a/lib/compiler/src/beam_clean.erl
+++ b/lib/compiler/src/beam_clean.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -184,14 +185,6 @@ function_replace([{function,Name,Arity,Entry,Asm0}|Fs], Dict, Acc) ->
function_replace(Fs, Dict, [{function,Name,Arity,Entry,Asm}|Acc]);
function_replace([], _, Acc) -> Acc.
-replace([{test,bs_match_string=Op,{f,Lbl},[Ctx,Bin0]}|Is], Acc, D) ->
- Bits = bit_size(Bin0),
- Bin = case Bits rem 8 of
- 0 -> Bin0;
- Rem -> <<Bin0/bitstring,0:(8-Rem)>>
- end,
- I = {test,Op,{f,label(Lbl, D)},[Ctx,Bits,{string,binary_to_list(Bin)}]},
- replace(Is, [I|Acc], D);
replace([{test,Test,{f,Lbl},Ops}|Is], Acc, D) ->
replace(Is, [{test,Test,{f,label(Lbl, D)},Ops}|Acc], D);
replace([{test,Test,{f,Lbl},Live,Ops,Dst}|Is], Acc, D) ->
@@ -234,31 +227,6 @@ replace([{bs_init,{f,Lbl},Info,Live,Ss,Dst}|Is], Acc, D) when Lbl =/= 0 ->
replace(Is, [{bs_init,{f,label(Lbl, D)},Info,Live,Ss,Dst}|Acc], D);
replace([{bs_put,{f,Lbl},Info,Ss}|Is], Acc, D) when Lbl =/= 0 ->
replace(Is, [{bs_put,{f,label(Lbl, D)},Info,Ss}|Acc], D);
-replace([{bs_init2,{f,Lbl},Sz,Words,R,F,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_init2,{f,label(Lbl, D)},Sz,Words,R,F,Dst}|Acc], D);
-replace([{bs_init_bits,{f,Lbl},Sz,Words,R,F,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_init_bits,{f,label(Lbl, D)},Sz,Words,R,F,Dst}|Acc], D);
-replace([{bs_put_integer,{f,Lbl},Bits,Unit,Fl,Val}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_put_integer,{f,label(Lbl, D)},Bits,Unit,Fl,Val}|Acc], D);
-replace([{bs_put_utf8=I,{f,Lbl},Fl,Val}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Fl,Val}|Acc], D);
-replace([{bs_put_utf16=I,{f,Lbl},Fl,Val}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Fl,Val}|Acc], D);
-replace([{bs_put_utf32=I,{f,Lbl},Fl,Val}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Fl,Val}|Acc], D);
-replace([{bs_put_binary,{f,Lbl},Bits,Unit,Fl,Val}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_put_binary,{f,label(Lbl, D)},Bits,Unit,Fl,Val}|Acc], D);
-replace([{bs_put_float,{f,Lbl},Bits,Unit,Fl,Val}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_put_float,{f,label(Lbl, D)},Bits,Unit,Fl,Val}|Acc], D);
-replace([{bs_add,{f,Lbl},Src,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_add,{f,label(Lbl, D)},Src,Dst}|Acc], D);
-replace([{bs_append,{f,Lbl},_,_,_,_,_,_,_}=I0|Is], Acc, D) when Lbl =/= 0 ->
- I = setelement(2, I0, {f,label(Lbl, D)}),
- replace(Is, [I|Acc], D);
-replace([{bs_utf8_size=I,{f,Lbl},Src,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Src,Dst}|Acc], D);
-replace([{bs_utf16_size=I,{f,Lbl},Src,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Src,Dst}|Acc], D);
replace([{put_map=I,{f,Lbl},Op,Src,Dst,Live,List}|Is], Acc, D)
when Lbl =/= 0 ->
replace(Is, [{I,{f,label(Lbl, D)},Op,Src,Dst,Live,List}|Acc], D);
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index b15adfa889..ead88b57e9 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,112 +22,10 @@
-export([module/2]).
-%%% The following optimisations are done:
-%%%
-%%% (1) In this code
-%%%
-%%% move DeadValue {x,0}
-%%% jump L2
-%%% .
-%%% .
-%%% .
-%%% L2: move Anything {x,0}
-%%% .
-%%% .
-%%% .
-%%%
-%%% the first assignment to {x,0} has no effect (is dead),
-%%% so it can be removed. Besides removing a move instruction,
-%%% if the move was preceeded by a label, the resulting code
-%%% will look this
-%%%
-%%% L1: jump L2
-%%% .
-%%% .
-%%% .
-%%% L2: move Anything {x,0}
-%%% .
-%%% .
-%%% .
-%%%
-%%% which can be further optimized by the jump optimizer (beam_jump).
-%%%
-%%% (2) In this code
-%%%
-%%% L1: move AtomLiteral {x,0}
-%%% jump L2
-%%% .
-%%% .
-%%% .
-%%% L2: test is_atom FailLabel {x,0}
-%%% select_val {x,0}, FailLabel [... AtomLiteral => L3...]
-%%% .
-%%% .
-%%% .
-%%% L3: ...
-%%%
-%%% FailLabel: ...
-%%%
-%%% the first code fragment can be changed to
-%%%
-%%% L1: move AtomLiteral {x,0}
-%%% jump L3
-%%%
-%%% If the literal is not included in the table of literals in the
-%%% select_val instruction, the first code fragment will instead be
-%%% rewritten as:
-%%%
-%%% L1: move AtomLiteral {x,0}
-%%% jump FailLabel
-%%%
-%%% The move instruction will be removed by optimization (1) above,
-%%% if the code following the L3 label overwrites {x,0}.
-%%%
-%%% The code following the L2 label will be kept, but it will be removed later
-%%% by the jump optimizer.
-%%%
-%%% (3) In this code
-%%%
-%%% test is_eq_exact ALabel Src Dst
-%%% move Src Dst
-%%%
-%%% the move instruction can be removed.
-%%% Same thing for
-%%%
-%%% test is_nil ALabel Dst
-%%% move [] Dst
-%%%
-%%%
-%%% (4) In this code
-%%%
-%%% select_val {x,Reg}, ALabel [... Literal => L1...]
-%%% .
-%%% .
-%%% .
-%%% L1: move Literal {x,Reg}
-%%%
-%%% we can remove the move instruction.
-%%%
-%%% (5) In the following code
-%%%
-%%% bif '=:=' Fail Src1 Src2 {x,0}
-%%% jump L1
-%%% .
-%%% .
-%%% .
-%%% L1: select_val {x,0}, ALabel [... true => L2..., ...false => L3...]
-%%% .
-%%% .
-%%% .
-%%% L2: .... L3: ....
-%%%
-%%% the first two instructions can be replaced with
-%%%
-%%% test is_eq_exact L3 Src1 Src2
-%%% jump L2
-%%%
-%%% provided that {x,0} is killed at both L2 and L3.
-%%%
+%%% Dead code is code that is executed but has no effect. This
+%%% optimization pass either removes dead code or jumps around it,
+%%% potentially making it unreachable and a target for the
+%%% the beam_jump pass.
-import(lists, [mapfoldl/3,reverse/1]).
@@ -173,12 +72,39 @@ move_move_into_block([I|Is], Acc) ->
move_move_into_block([], Acc) -> reverse(Acc).
%%%
-%%% Scan instructions in execution order and remove dead code.
+%%% Scan instructions in execution order and remove redundant 'move'
+%%% instructions. 'move' instructions are redundant if we know that
+%%% the register already contains the value being assigned, as in the
+%%% following code:
+%%%
+%%% test is_eq_exact SomeLabel Src Dst
+%%% move Src Dst
+%%%
+%%% or in:
+%%%
+%%% test is_nil SomeLabel Dst
+%%% move nil Dst
+%%%
+%%% or in:
+%%%
+%%% select_val Register FailLabel [... Literal => L1...]
+%%% .
+%%% .
+%%% .
+%%% L1: move Literal Register
+%%%
+%%% Also add extra labels to help the second backward pass.
%%%
forward(Is, Lc) ->
- forward(Is, gb_trees:empty(), Lc, []).
-
+ forward(Is, #{}, Lc, []).
+
+forward([{move,_,_}=Move|[{label,L}|_]=Is], D, Lc, Acc) ->
+ %% move/2 followed by jump/1 is optimized by backward/3.
+ forward([Move,{jump,{f,L}}|Is], D, Lc, Acc);
+forward([{bif,_,_,_,_}=Bif|[{label,L}|_]=Is], D, Lc, Acc) ->
+ %% bif/4 followed by jump/1 is optimized by backward/3.
+ forward([Bif,{jump,{f,L}}|Is], D, Lc, Acc);
forward([{block,[]}|Is], D, Lc, Acc) ->
%% Empty blocks can prevent optimizations.
forward(Is, D, Lc, Acc);
@@ -190,21 +116,24 @@ forward([{label,Lbl}=LblI,{block,[{set,[Dst],[Lit],move}|BlkIs]}=Blk|Is], D, Lc,
%% cannot be reached in any other way than through the select_val/3
%% instruction (i.e. there can be no fallthrough to such label and
%% it cannot be referenced by, for example, a jump/1 instruction).
- Block = case gb_trees:lookup({Lbl,Dst}, D) of
- {value,Lit} -> {block,BlkIs}; %Safe to remove move instruction.
- _ -> Blk %Must keep move instruction.
- end,
+ Key = {Lbl,Dst},
+ Block = case D of
+ #{Key := Lit} -> {block,BlkIs}; %Safe to remove move instruction.
+ _ -> Blk %Must keep move instruction.
+ end,
forward([Block|Is], D, Lc, [LblI|Acc]);
forward([{label,Lbl}=LblI|[{move,Lit,Dst}|Is1]=Is0], D, Lc, Acc) ->
%% Assumption: The target labels in a select_val/3 instruction
%% cannot be reached in any other way than through the select_val/3
%% instruction (i.e. there can be no fallthrough to such label and
%% it cannot be referenced by, for example, a jump/1 instruction).
- Is = case gb_trees:lookup({Lbl,Dst}, D) of
- {value,Lit} -> Is1; %Safe to remove move instruction.
- _ -> Is0 %Keep move instruction.
+ Is = case maps:find({Lbl,Dst}, D) of
+ {ok,Lit} -> Is1; %Safe to remove move instruction.
+ _ -> Is0 %Keep move instruction.
end,
forward(Is, D, Lc, [LblI|Acc]);
+forward([{test,is_eq_exact,_,[Same,Same]}|Is], D, Lc, Acc) ->
+ forward(Is, D, Lc, Acc);
forward([{test,is_eq_exact,_,[Dst,Src]}=I,
{block,[{set,[Dst],[Src],move}|Bl]}|Is], D, Lc, Acc) ->
forward([I,{block,Bl}|Is], D, Lc, Acc);
@@ -215,15 +144,13 @@ forward([{test,is_eq_exact,_,[Dst,Src]}=I,{move,Src,Dst}|Is], D, Lc, Acc) ->
forward([I|Is], D, Lc, Acc);
forward([{test,is_nil,_,[Dst]}=I,{move,nil,Dst}|Is], D, Lc, Acc) ->
forward([I|Is], D, Lc, Acc);
-forward([{test,is_eq_exact,_,_}=I|Is], D, Lc, Acc) ->
- case Is of
- [{label,_}|_] -> forward(Is, D, Lc, [I|Acc]);
- _ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
- end;
-forward([{test,is_ne_exact,_,_}=I|Is], D, Lc, Acc) ->
- case Is of
- [{label,_}|_] -> forward(Is, D, Lc, [I|Acc]);
- _ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
+forward([{test,_,_,_}=I|Is]=Is0, D, Lc, Acc) ->
+ %% Help the second, backward pass to by inserting labels after
+ %% relational operators so that they can be skipped if they are
+ %% known to be true.
+ case useful_to_insert_label(Is0) of
+ false -> forward(Is, D, Lc, [I|Acc]);
+ true -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
end;
forward([I|Is], D, Lc, Acc) ->
forward(Is, D, Lc, [I|Acc]);
@@ -231,17 +158,57 @@ forward([], _, Lc, Acc) -> {Acc,Lc}.
update_value_dict([Lit,{f,Lbl}|T], Reg, D0) ->
Key = {Lbl,Reg},
- D = case gb_trees:lookup(Key, D0) of
- none -> gb_trees:insert(Key, Lit, D0); %New.
- {value,inconsistent} -> D0; %Inconsistent.
- {value,_} -> gb_trees:update(Key, inconsistent, D0)
- end,
+ D = case D0 of
+ #{Key := inconsistent} -> D0;
+ #{Key := _} -> D0#{Key := inconsistent};
+ _ -> D0#{Key => Lit}
+ end,
update_value_dict(T, Reg, D);
update_value_dict([], _, D) -> D.
+useful_to_insert_label([_,{label,_}|_]) ->
+ false;
+useful_to_insert_label([{test,Op,_,_}|_]) ->
+ case Op of
+ is_lt -> true;
+ is_ge -> true;
+ is_eq_exact -> true;
+ is_ne_exact -> true;
+ _ -> false
+ end.
+
+%%%
+%%% Scan instructions in reverse execution order and try to
+%%% shortcut branch instructions.
+%%%
+%%% For example, in this code:
%%%
-%%% Scan instructions in reverse execution order and remove dead code.
+%%% move Literal Register
+%%% jump L1
+%%% .
+%%% .
+%%% .
+%%% L1: test is_{integer,atom} FailLabel Register
+%%% select_val {x,0} FailLabel [... Literal => L2...]
+%%% .
+%%% .
+%%% .
+%%% L2: ...
%%%
+%%% the 'selectval' instruction will always transfer control to L2,
+%%% so we can just as well jump to L2 directly by rewriting the
+%%% first part of the sequence like this:
+%%%
+%%% move Literal Register
+%%% jump L2
+%%%
+%%% If register Register is killed at label L2, we can remove the
+%%% 'move' instruction, leaving just the 'jump' instruction:
+%%%
+%%% jump L2
+%%%
+%%% These transformations may leave parts of the code unreachable.
+%%% The beam_jump pass will remove the unreachable code.
backward(Is, D) ->
backward(Is, D, []).
@@ -277,15 +244,8 @@ backward([{select,select_val,Reg,{f,Fail0},List0}|Is], D, Acc) ->
Fail = shortcut_bs_test(Fail1, Is, D),
Sel = {select,select_val,Reg,{f,Fail},List},
backward(Is, D, [Sel|Acc]);
-backward([{jump,{f,To0}},{move,Src,Reg}=Move0|Is], D, Acc) ->
- {To,Move} = case Src of
- {atom,Val0} ->
- To1 = shortcut_select_label(To0, Reg, Val0, D),
- {To2,Val} = shortcut_boolean_label(To1, Reg, Val0, D),
- {To2,{move,{atom,Val},Reg}};
- _ ->
- {shortcut_label(To0, D),Move0}
- end,
+backward([{jump,{f,To0}},{move,Src,Reg}=Move|Is], D, Acc) ->
+ To = shortcut_select_label(To0, Reg, Src, D),
Jump = {jump,{f,To}},
case beam_utils:is_killed_at(Reg, To, D) of
false -> backward([Move|Is], D, [Jump|Acc]);
@@ -297,32 +257,39 @@ backward([{jump,{f,To}}=J|[{bif,Op,_,Ops,Reg}|Is]=Is0], D, Acc) ->
catch
throw:not_possible -> backward(Is0, D, [J|Acc])
end;
+backward([{test,bs_start_match2,F,_,[R,_],Ctxt}=I|Is], D,
+ [{test,bs_match_string,F,[Ctxt,Bs]},
+ {test,bs_test_tail2,F,[Ctxt,0]}|Acc0]=Acc) ->
+ case beam_utils:is_killed(Ctxt, Acc0, D) of
+ true ->
+ Eq = {test,is_eq_exact,F,[R,{literal,Bs}]},
+ backward(Is, D, [Eq|Acc0]);
+ false ->
+ backward(Is, D, [I|Acc])
+ end;
backward([{test,bs_start_match2,{f,To0},Live,[Src|_]=Info,Dst}|Is], D, Acc) ->
To = shortcut_bs_start_match(To0, Src, D),
I = {test,bs_start_match2,{f,To},Live,Info,Dst},
backward(Is, D, [I|Acc]);
-backward([{test,is_eq_exact,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) ->
- To1 = shortcut_bs_test(To0, Is, D),
- To = shortcut_fail_label(To1, Reg, Val, D),
- I = combine_eqs(To, Ops, D, Acc),
- backward(Is, D, [I|Acc]);
backward([{test,Op,{f,To0},Ops0}|Is], D, Acc) ->
To1 = shortcut_bs_test(To0, Is, D),
To2 = shortcut_label(To1, D),
+ To3 = shortcut_rel_op(To2, Op, Ops0, D),
+
%% Try to shortcut a repeated test:
%%
%% test Op {f,Fail1} Operands test Op {f,Fail2} Operands
%% . . . ==> ...
%% Fail1: test Op {f,Fail2} Operands Fail1: test Op {f,Fail2} Operands
%%
- To = case beam_utils:code_at(To2, D) of
- [{test,Op,{f,To3},Ops}|_] ->
+ To = case beam_utils:code_at(To3, D) of
+ [{test,Op,{f,To4},Ops}|_] ->
case equal_ops(Ops0, Ops) of
- true -> To3;
- false -> To2
+ true -> To4;
+ false -> To3
end;
_Code ->
- To2
+ To3
end,
I = case Op of
is_eq_exact -> combine_eqs(To, Ops0, D, Acc);
@@ -367,8 +334,8 @@ equal_ops([Op|T0], [Op|T1]) ->
equal_ops([], []) -> true;
equal_ops(_, _) -> false.
-shortcut_select_list([{_,Val}=Lit,{f,To0}|T], Reg, D, Acc) ->
- To = shortcut_select_label(To0, Reg, Val, D),
+shortcut_select_list([Lit,{f,To0}|T], Reg, D, Acc) ->
+ To = shortcut_select_label(To0, Reg, Lit, D),
shortcut_select_list(T, Reg, D, [{f,To},Lit|Acc]);
shortcut_select_list([], _, _, Acc) -> reverse(Acc).
@@ -378,58 +345,29 @@ shortcut_label(To0, D) ->
_ -> To0
end.
-shortcut_select_label(To0, Reg, Val, D) ->
- case beam_utils:code_at(To0, D) of
- [{jump,{f,To}}|_] ->
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_atom,_,[Reg]},{select,select_val,Reg,{f,Fail},Map}|_] ->
- To = find_select_val(Map, Val, Fail),
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_eq_exact,{f,_},[Reg,{atom,Val}]},{label,To}|_] when is_atom(Val) ->
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_eq_exact,{f,_},[Reg,{atom,Val}]},{jump,{f,To}}|_] when is_atom(Val) ->
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_eq_exact,{f,To},[Reg,{atom,AnotherVal}]}|_]
- when is_atom(Val), Val =/= AnotherVal ->
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_ne_exact,{f,To},[Reg,{atom,Val}]}|_] when is_atom(Val) ->
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_ne_exact,{f,_},[Reg,{atom,_}]},{label,To}|_] when is_atom(Val) ->
- shortcut_select_label(To, Reg, Val, D);
- [{test,is_tuple,{f,To},[Reg]}|_] when is_atom(Val) ->
- shortcut_select_label(To, Reg, Val, D);
- _ ->
- To0
- end.
-
-shortcut_fail_label(To0, Reg, Val, D) ->
- case beam_utils:code_at(To0, D) of
- [{jump,{f,To}}|_] ->
- shortcut_fail_label(To, Reg, Val, D);
- [{test,is_eq_exact,{f,To},[Reg,{atom,Val}]}|_] when is_atom(Val) ->
- shortcut_fail_label(To, Reg, Val, D);
- _ ->
- To0
- end.
+shortcut_select_label(To, Reg, Lit, D) ->
+ shortcut_rel_op(To, is_ne_exact, [Reg,Lit], D).
-shortcut_boolean_label(To0, Reg, Bool0, D) when is_boolean(Bool0) ->
- case beam_utils:code_at(To0, D) of
- [{line,_},{bif,'not',_,[Reg],Reg},{jump,{f,To}}|_] ->
- Bool = not Bool0,
- {shortcut_select_label(To, Reg, Bool, D),Bool};
- _ ->
- {To0,Bool0}
- end;
-shortcut_boolean_label(To, _, Bool, _) -> {To,Bool}.
-
-find_select_val([{_,Val},{f,To}|_], Val, _) -> To;
-find_select_val([{_,_}, {f,_}|T], Val, Fail) ->
- find_select_val(T, Val, Fail);
-find_select_val([], _, Fail) -> Fail.
+%% Replace a comparison operator with a test instruction and a jump.
+%% For example, if we have this code:
+%%
+%% bif '=:=' Fail Src1 Src2 {x,0}
+%% jump L1
+%% .
+%% .
+%% .
+%% L1: select_val {x,0} FailLabel [... true => L2..., ...false => L3...]
+%%
+%% the first two instructions can be replaced with
+%%
+%% test is_eq_exact L3 Src1 Src2
+%% jump L2
+%%
+%% provided that {x,0} is killed at both L2 and L3.
replace_comp_op(To, Reg, Op, Ops, D) ->
- False = comp_op_find_shortcut(To, Reg, false, D),
- True = comp_op_find_shortcut(To, Reg, true, D),
+ False = comp_op_find_shortcut(To, Reg, {atom,false}, D),
+ True = comp_op_find_shortcut(To, Reg, {atom,true}, D),
[bif_to_test(Op, Ops, False),{jump,{f,True}}].
comp_op_find_shortcut(To0, Reg, Val, D) ->
@@ -461,9 +399,9 @@ not_possible() -> throw(not_possible).
%%
%% is_eq_exact F1 Reg Lit1 select_val Reg F2 [ Lit1 L1
%% L1: . Lit2 L2 ]
-%% .
-%% . ==>
-%% .
+%% .
+%% . ==>
+%% .
%% F1: is_eq_exact F2 Reg Lit2 F1: is_eq_exact F2 Reg Lit2
%% L2: .... L2:
%%
@@ -488,31 +426,26 @@ remove_from_list(Lit, [Val,{f,_}=Fail|T]) ->
[Val,Fail|remove_from_list(Lit, T)];
remove_from_list(_, []) -> [].
-%% shortcut_bs_test(TargetLabel, [Instruction], D) -> TargetLabel'
-%% Try to shortcut the failure label for a bit syntax matching.
-%% We know that the binary contains at least Bits bits after
-%% the latest save point.
+%% shortcut_bs_test(TargetLabel, ReversedInstructions, D) -> TargetLabel'
+%% Try to shortcut the failure label for bit syntax matching.
shortcut_bs_test(To, Is, D) ->
shortcut_bs_test_1(beam_utils:code_at(To, D), Is, To, D).
-shortcut_bs_test_1([{bs_restore2,Reg,SavePoint}|Is], PrevIs, To, D) ->
- shortcut_bs_test_2(Is, {Reg,SavePoint}, PrevIs, To, D);
-shortcut_bs_test_1([_|_], _, To, _) -> To.
-
-shortcut_bs_test_2([{label,_}|Is], Save, PrevIs, To, D) ->
- shortcut_bs_test_2(Is, Save, PrevIs, To, D);
-shortcut_bs_test_2([{test,bs_test_tail2,{f,To},[_,TailBits]}|_],
- {Reg,_Point} = RP, PrevIs, To0, D) ->
- case count_bits_matched(PrevIs, RP, 0) of
+shortcut_bs_test_1([{bs_restore2,Reg,SavePoint},
+ {label,_},
+ {test,bs_test_tail2,{f,To},[_,TailBits]}|_],
+ PrevIs, To0, D) ->
+ case count_bits_matched(PrevIs, {Reg,SavePoint}, 0) of
Bits when Bits > TailBits ->
%% This instruction will fail. We know because a restore has been
- %% done from the previous point SavePoint in the binary, and we also know
- %% that the binary contains at least Bits bits from SavePoint.
+ %% done from the previous point SavePoint in the binary, and we
+ %% also know that the binary contains at least Bits bits from
+ %% SavePoint.
%%
%% Since we will skip a bs_restore2 if we shortcut to label To,
- %% we must now make sure that code at To does not depend on the position
- %% in the context in any way.
+ %% we must now make sure that code at To does not depend on
+ %% the position in the context in any way.
case shortcut_bs_pos_used(To, Reg, D) of
false -> To;
true -> To0
@@ -520,15 +453,26 @@ shortcut_bs_test_2([{test,bs_test_tail2,{f,To},[_,TailBits]}|_],
_Bits ->
To0
end;
-shortcut_bs_test_2([_|_], _, _, To, _) -> To.
+shortcut_bs_test_1([_|_], _, To, _) -> To.
+%% counts_bits_matched(ReversedInstructions, SavePoint, Bits) -> Bits'
+%% Given a reversed instruction stream, determine the minimum number
+%% of bits that will be matched by bit syntax instructions up to the
+%% given save point.
+
+count_bits_matched([{test,bs_get_utf8,{f,_},_,_,_}|Is], SavePoint, Bits) ->
+ count_bits_matched(Is, SavePoint, Bits+8);
+count_bits_matched([{test,bs_get_utf16,{f,_},_,_,_}|Is], SavePoint, Bits) ->
+ count_bits_matched(Is, SavePoint, Bits+16);
+count_bits_matched([{test,bs_get_utf32,{f,_},_,_,_}|Is], SavePoint, Bits) ->
+ count_bits_matched(Is, SavePoint, Bits+32);
count_bits_matched([{test,_,_,_,[_,Sz,U,{field_flags,_}],_}|Is], SavePoint, Bits) ->
case Sz of
{integer,N} -> count_bits_matched(Is, SavePoint, Bits+N*U);
_ -> count_bits_matched(Is, SavePoint, Bits)
end;
-count_bits_matched([{test,bs_match_string,_,[_,Bits,_]}|Is], SavePoint, Bits0) ->
- count_bits_matched(Is, SavePoint, Bits0+Bits);
+count_bits_matched([{test,bs_match_string,_,[_,Bs]}|Is], SavePoint, Bits) ->
+ count_bits_matched(Is, SavePoint, Bits+bit_size(Bs));
count_bits_matched([{test,_,_,_}|Is], SavePoint, Bits) ->
count_bits_matched(Is, SavePoint, Bits);
count_bits_matched([{bs_save2,Reg,SavePoint}|_], {Reg,SavePoint}, Bits) ->
@@ -545,20 +489,332 @@ shortcut_bs_pos_used_1(Is, Reg, D) ->
not beam_utils:is_killed(Reg, Is, D).
%% shortcut_bs_start_match(TargetLabel, Reg) -> TargetLabel
-%% A failing bs_start_match2 instruction means that the source
-%% cannot be a binary, so there is no need to jump bs_context_to_binary/1
-%% or another bs_start_match2 instruction.
+%% A failing bs_start_match2 instruction means that the source (Reg)
+%% cannot be a binary. That means that it is safe to skip
+%% bs_context_to_binary instructions operating on Reg, and
+%% bs_start_match2 instructions operating on Reg.
shortcut_bs_start_match(To, Reg, D) ->
- shortcut_bs_start_match_1(beam_utils:code_at(To, D), Reg, To).
+ shortcut_bs_start_match_1(beam_utils:code_at(To, D), Reg, To, D).
+
+shortcut_bs_start_match_1([{bs_context_to_binary,Reg}|Is], Reg, To, D) ->
+ shortcut_bs_start_match_1(Is, Reg, To, D);
+shortcut_bs_start_match_1([{jump,{f,To}}|_], Reg, _, D) ->
+ Code = beam_utils:code_at(To, D),
+ shortcut_bs_start_match_1(Code, Reg, To, D);
+shortcut_bs_start_match_1([{test,bs_start_match2,{f,To},_,[Reg|_],_}|_],
+ Reg, _, D) ->
+ Code = beam_utils:code_at(To, D),
+ shortcut_bs_start_match_1(Code, Reg, To, D);
+shortcut_bs_start_match_1(_, _, To, _) ->
+ To.
+
+%% shortcut_rel_op(FailLabel, Operator, [Operand], D) -> FailLabel'
+%% Try to shortcut the given test instruction. Example:
+%%
+%% is_ge L1 {x,0} 48
+%% .
+%% .
+%% .
+%% L1: is_ge L2 {x,0} 65
+%%
+%% The first test instruction can be rewritten to "is_ge L2 {x,0} 48"
+%% since the instruction at L1 will also fail.
+%%
+%% If there are instructions between L1 and the other test instruction
+%% it may still be possible to do the shortcut. For example:
+%%
+%% L1: is_eq_exact L3 {x,0} 92
+%% is_ge L2 {x,0} 65
+%%
+%% Since the first test instruction failed, we know that {x,0} must
+%% be less than 48; therefore, we know that {x,0} cannot be equal to
+%% 92 and the jump to L3 cannot happen.
+
+shortcut_rel_op(To, Op, Ops, D) ->
+ case normalize_op({test,Op,{f,To},Ops}) of
+ {{NormOp,A,B},_} ->
+ Normalized = {negate_op(NormOp),A,B},
+ shortcut_rel_op_fp(To, Normalized, D);
+ {_,_} ->
+ To;
+ error ->
+ To
+ end.
-shortcut_bs_start_match_1([{bs_context_to_binary,Reg}|Is], Reg, To) ->
- shortcut_bs_start_match_2(Is, Reg, To);
-shortcut_bs_start_match_1(_, _, To) -> To.
+shortcut_rel_op_fp(To0, Normalized, D) ->
+ Code = beam_utils:code_at(To0, D),
+ case shortcut_any_label(Code, Normalized) of
+ error ->
+ To0;
+ To ->
+ shortcut_rel_op_fp(To, Normalized, D)
+ end.
-shortcut_bs_start_match_2([{jump,{f,To}}|_], _, _) ->
- To;
-shortcut_bs_start_match_2([{test,bs_start_match2,{f,To},_,[Reg|_],_}|_], Reg, _) ->
- To;
-shortcut_bs_start_match_2(_Is, _Reg, To) ->
- To.
+%% shortcut_any_label([Instruction], PrevCondition) -> FailLabel | error
+%% Using PrevCondition (a previous condition known to be true),
+%% try to shortcut to another failure label.
+
+shortcut_any_label([{jump,{f,Lbl}}|_], _Prev) ->
+ Lbl;
+shortcut_any_label([{label,Lbl}|_], _Prev) ->
+ Lbl;
+shortcut_any_label([{select,select_val,R,{f,Fail},L}|_], Prev) ->
+ shortcut_selectval(L, R, Fail, Prev);
+shortcut_any_label([I|Is], Prev) ->
+ case normalize_op(I) of
+ error ->
+ error;
+ {Normalized,Fail} ->
+ %% We have a relational operator.
+ case will_succeed(Prev, Normalized) of
+ no ->
+ %% This test instruction will always branch
+ %% to Fail.
+ Fail;
+ yes ->
+ %% This test instruction will never branch,
+ %% so we will look at the next instruction.
+ shortcut_any_label(Is, Prev);
+ maybe ->
+ %% May or may not branch. From now on, we can only
+ %% shortcut to the this specific failure label
+ %% Fail.
+ shortcut_specific_label(Is, Fail, Prev)
+ end
+ end.
+
+%% shortcut_specific_label([Instruction], FailLabel, PrevCondition) ->
+%% FailLabel | error
+%% We have previously encountered a test instruction that may or
+%% may not branch to FailLabel. Therefore we are only allowed
+%% to do the shortcut to the same fail label (FailLabel).
+
+shortcut_specific_label([{label,_}|Is], Fail, Prev) ->
+ shortcut_specific_label(Is, Fail, Prev);
+shortcut_specific_label([{select,select_val,R,{f,F},L}|_], Fail, Prev) ->
+ case shortcut_selectval(L, R, F, Prev) of
+ Fail -> Fail;
+ _ -> error
+ end;
+shortcut_specific_label([I|Is], Fail, Prev) ->
+ case normalize_op(I) of
+ error ->
+ error;
+ {Normalized,Fail} ->
+ case will_succeed(Prev, Normalized) of
+ no ->
+ %% Will branch to FailLabel.
+ Fail;
+ yes ->
+ %% Will definitely never branch.
+ shortcut_specific_label(Is, Fail, Prev);
+ maybe ->
+ %% May branch, but still OK since it will branch
+ %% to FailLabel.
+ shortcut_specific_label(Is, Fail, Prev)
+ end;
+ {Normalized,_} ->
+ %% This test instruction will branch to a different
+ %% fail label, if it branches at all.
+ case will_succeed(Prev, Normalized) of
+ yes ->
+ %% Still OK, since the branch will never be
+ %% taken.
+ shortcut_specific_label(Is, Fail, Prev);
+ no ->
+ %% Give up. The branch will definitely be taken
+ %% to a different fail label.
+ error;
+ maybe ->
+ %% Give up. If the branch is taken, it will be
+ %% to a different fail label.
+ error
+ end
+ end.
+
+
+%% shortcut_selectval(List, Reg, Fail, PrevCond) -> FailLabel | error
+%% Try to shortcut a selectval instruction. A selectval instruction
+%% is equivalent to the following instruction sequence:
+%%
+%% is_ne_exact L1 Reg Value1
+%% .
+%% .
+%% .
+%% is_ne_exact LN Reg ValueN
+%% jump DefaultFailLabel
+%%
+shortcut_selectval([Val,{f,Lbl}|T], R, Fail, Prev) ->
+ case will_succeed(Prev, {'=/=',R,get_literal(Val)}) of
+ yes -> shortcut_selectval(T, R, Fail, Prev);
+ no -> Lbl;
+ maybe -> error
+ end;
+shortcut_selectval([], _, Fail, _) -> Fail.
+
+%% will_succeed(PrevCondition, Condition) -> yes | no | maybe
+%% PrevCondition is a condition known to be true. This function
+%% will tell whether Condition will succeed.
+
+will_succeed({Op1,Reg,A}, {Op2,Reg,B}) ->
+ will_succeed_1(Op1, A, Op2, B);
+will_succeed({'=:=',Reg,{literal,A}}, {TypeTest,Reg}) ->
+ case erlang:TypeTest(A) of
+ false -> no;
+ true -> yes
+ end;
+will_succeed({_,_,_}, maybe) ->
+ maybe;
+will_succeed({_,_,_}, Test) when is_tuple(Test) ->
+ maybe.
+
+will_succeed_1('=:=', A, '<', B) ->
+ if
+ B =< A -> no;
+ true -> yes
+ end;
+will_succeed_1('=:=', A, '=<', B) ->
+ if
+ B < A -> no;
+ true -> yes
+ end;
+will_succeed_1('=:=', A, '=:=', B) ->
+ if
+ A =:= B -> yes;
+ true -> no
+ end;
+will_succeed_1('=:=', A, '=/=', B) ->
+ if
+ A =:= B -> no;
+ true -> yes
+ end;
+will_succeed_1('=:=', A, '>=', B) ->
+ if
+ B > A -> no;
+ true -> yes
+ end;
+will_succeed_1('=:=', A, '>', B) ->
+ if
+ B >= A -> no;
+ true -> yes
+ end;
+
+will_succeed_1('=/=', A, '=/=', B) when A =:= B -> yes;
+will_succeed_1('=/=', A, '=:=', B) when A =:= B -> no;
+
+will_succeed_1('<', A, '=:=', B) when B >= A -> no;
+will_succeed_1('<', A, '=/=', B) when B >= A -> yes;
+will_succeed_1('<', A, '<', B) when B >= A -> yes;
+will_succeed_1('<', A, '=<', B) when B > A -> yes;
+will_succeed_1('<', A, '>=', B) when B > A -> no;
+will_succeed_1('<', A, '>', B) when B >= A -> no;
+
+will_succeed_1('=<', A, '=:=', B) when B > A -> no;
+will_succeed_1('=<', A, '=/=', B) when B > A -> yes;
+will_succeed_1('=<', A, '<', B) when B > A -> yes;
+will_succeed_1('=<', A, '=<', B) when B >= A -> yes;
+will_succeed_1('=<', A, '>=', B) when B > A -> no;
+will_succeed_1('=<', A, '>', B) when B >= A -> no;
+
+will_succeed_1('>=', A, '=:=', B) when B < A -> no;
+will_succeed_1('>=', A, '=/=', B) when B < A -> yes;
+will_succeed_1('>=', A, '<', B) when B =< A -> no;
+will_succeed_1('>=', A, '=<', B) when B < A -> no;
+will_succeed_1('>=', A, '>=', B) when B =< A -> yes;
+will_succeed_1('>=', A, '>', B) when B < A -> yes;
+
+will_succeed_1('>', A, '=:=', B) when B =< A -> no;
+will_succeed_1('>', A, '=/=', B) when B =< A -> yes;
+will_succeed_1('>', A, '<', B) when B =< A -> no;
+will_succeed_1('>', A, '=<', B) when B < A -> no;
+will_succeed_1('>', A, '>=', B) when B =< A -> yes;
+will_succeed_1('>', A, '>', B) when B < A -> yes;
+
+will_succeed_1(_, _, _, _) -> maybe.
+
+%% normalize_op(Instruction) -> {Normalized,FailLabel} | error
+%% Normalized = {Operator,Register,Literal} |
+%% {TypeTest,Register} |
+%% maybe
+%% Operation = '<' | '=<' | '=:=' | '=/=' | '>=' | '>'
+%% TypeTest = is_atom | is_integer ...
+%% Literal = {literal,Term}
+%%
+%% Normalize a relational operator to facilitate further
+%% comparisons between operators. Always make the register
+%% operand the first operand. Thus the following instruction:
+%%
+%% {test,is_ge,{f,99},{integer,13},{x,0}}
+%%
+%% will be normalized to:
+%%
+%% {'=<',{x,0},{literal,13}}
+%%
+%% NOTE: Bit syntax test instructions are scary. They may change the
+%% state of match contexts and update registers, so we don't dare
+%% mess with them.
+
+normalize_op({test,is_ge,{f,Fail},Ops}) ->
+ normalize_op_1('>=', Ops, Fail);
+normalize_op({test,is_lt,{f,Fail},Ops}) ->
+ normalize_op_1('<', Ops, Fail);
+normalize_op({test,is_eq_exact,{f,Fail},Ops}) ->
+ normalize_op_1('=:=', Ops, Fail);
+normalize_op({test,is_ne_exact,{f,Fail},Ops}) ->
+ normalize_op_1('=/=', Ops, Fail);
+normalize_op({test,is_nil,{f,Fail},[R]}) ->
+ normalize_op_1('=:=', [R,nil], Fail);
+normalize_op({test,Op,{f,Fail},[R]}) ->
+ case erl_internal:new_type_test(Op, 1) of
+ true -> {{Op,R},Fail};
+ false -> {maybe,Fail}
+ end;
+normalize_op({test,_,{f,Fail},_}=I) ->
+ case beam_utils:is_pure_test(I) of
+ true -> {maybe,Fail};
+ false -> error
+ end;
+normalize_op(_) ->
+ error.
+
+normalize_op_1(Op, [Op1,Op2], Fail) ->
+ case {get_literal(Op1),get_literal(Op2)} of
+ {error,error} ->
+ %% Both operands are registers.
+ {maybe,Fail};
+ {error,Lit} ->
+ {{Op,Op1,Lit},Fail};
+ {Lit,error} ->
+ {{turn_op(Op),Op2,Lit},Fail};
+ {_,_} ->
+ %% Both operands are literals. Can probably only
+ %% happen if the Core Erlang optimizations passes were
+ %% turned off, so don't bother trying to do something
+ %% smart here.
+ {maybe,Fail}
+ end.
+
+turn_op('<') -> '>';
+turn_op('>=') -> '=<';
+turn_op('=:='=Op) -> Op;
+turn_op('=/='=Op) -> Op.
+
+negate_op('>=') -> '<';
+negate_op('<') -> '>=';
+negate_op('=<') -> '>';
+negate_op('>') -> '=<';
+negate_op('=:=') -> '=/=';
+negate_op('=/=') -> '=:='.
+
+get_literal({atom,Val}) ->
+ {literal,Val};
+get_literal({integer,Val}) ->
+ {literal,Val};
+get_literal({float,Val}) ->
+ {literal,Val};
+get_literal(nil) ->
+ {literal,[]};
+get_literal({literal,_}=Lit) ->
+ Lit;
+get_literal({_,_}) -> error.
diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl
index ea51673fa3..2b5f8c1b7f 100644
--- a/lib/compiler/src/beam_dict.erl
+++ b/lib/compiler/src/beam_dict.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -31,22 +32,22 @@
-type index() :: non_neg_integer().
--type atom_tab() :: gb_trees:tree(atom(), index()).
+-type atom_tab() :: #{atom() => index()}.
-type import_tab() :: gb_trees:tree(mfa(), index()).
--type fname_tab() :: gb_trees:tree(Name :: term(), index()).
--type line_tab() :: gb_trees:tree({Fname :: index(), Line :: term()}, index()).
+-type fname_tab() :: #{Name :: term() => index()}.
+-type line_tab() :: #{{Fname :: index(), Line :: term()} => index()}.
-type literal_tab() :: dict:dict(Literal :: term(), index()).
-record(asm,
- {atoms = gb_trees:empty() :: atom_tab(),
+ {atoms = #{} :: atom_tab(),
exports = [] :: [{label(), arity(), label()}],
locals = [] :: [{label(), arity(), label()}],
imports = gb_trees:empty() :: import_tab(),
strings = <<>> :: binary(), %String pool
lambdas = [], %[{...}]
literals = dict:new() :: literal_tab(),
- fnames = gb_trees:empty() :: fname_tab(),
- lines = gb_trees:empty() :: line_tab(),
+ fnames = #{} :: fname_tab(),
+ lines = #{} :: line_tab(),
num_lines = 0 :: non_neg_integer(), %Number of line instructions
next_import = 0 :: non_neg_integer(),
string_offset = 0 :: non_neg_integer(),
@@ -65,7 +66,7 @@ new() ->
%% Remember the highest opcode.
-spec opcode(non_neg_integer(), bdict()) -> bdict().
-opcode(Op, Dict) when Dict#asm.highest_opcode > Op -> Dict;
+opcode(Op, Dict) when Dict#asm.highest_opcode >= Op -> Dict;
opcode(Op, Dict) -> Dict#asm{highest_opcode=Op}.
%% Returns the highest opcode encountered.
@@ -77,14 +78,12 @@ highest_opcode(#asm{highest_opcode=Op}) -> Op.
%% atom(Atom, Dict) -> {Index,Dict'}
-spec atom(atom(), bdict()) -> {pos_integer(), bdict()}.
-atom(Atom, #asm{atoms=Atoms0}=Dict) when is_atom(Atom) ->
- case gb_trees:lookup(Atom, Atoms0) of
- {value,Index} ->
- {Index,Dict};
- none ->
- NextIndex = gb_trees:size(Atoms0) + 1,
- Atoms = gb_trees:insert(Atom, NextIndex, Atoms0),
- {NextIndex,Dict#asm{atoms=Atoms}}
+atom(Atom, #asm{atoms=Atoms}=Dict) when is_atom(Atom) ->
+ case Atoms of
+ #{ Atom := Index} -> {Index,Dict};
+ _ ->
+ NextIndex = maps:size(Atoms) + 1,
+ {NextIndex,Dict#asm{atoms=Atoms#{Atom=>NextIndex}}}
end.
%% Remembers an exported function.
@@ -177,26 +176,22 @@ line([], #asm{num_lines=N}=Dict) ->
%% No location available. Return the special pre-defined
%% index 0.
{0,Dict#asm{num_lines=N+1}};
-line([{location,Name,Line}], #asm{lines=Lines0,num_lines=N}=Dict0) ->
+line([{location,Name,Line}], #asm{lines=Lines,num_lines=N}=Dict0) ->
{FnameIndex,Dict1} = fname(Name, Dict0),
- case gb_trees:lookup({FnameIndex,Line}, Lines0) of
- {value,Index} ->
- {Index,Dict1#asm{num_lines=N+1}};
- none ->
- Index = gb_trees:size(Lines0) + 1,
- Lines = gb_trees:insert({FnameIndex,Line}, Index, Lines0),
- Dict = Dict1#asm{lines=Lines,num_lines=N+1},
- {Index,Dict}
+ Key = {FnameIndex,Line},
+ case Lines of
+ #{Key := Index} -> {Index,Dict1#asm{num_lines=N+1}};
+ _ ->
+ Index = maps:size(Lines) + 1,
+ {Index, Dict1#asm{lines=Lines#{Key=>Index},num_lines=N+1}}
end.
-fname(Name, #asm{fnames=Fnames0}=Dict) ->
- case gb_trees:lookup(Name, Fnames0) of
- {value,Index} ->
- {Index,Dict};
- none ->
- Index = gb_trees:size(Fnames0),
- Fnames = gb_trees:insert(Name, Index, Fnames0),
- {Index,Dict#asm{fnames=Fnames}}
+fname(Name, #asm{fnames=Fnames}=Dict) ->
+ case Fnames of
+ #{Name := Index} -> {Index,Dict};
+ _ ->
+ Index = maps:size(Fnames),
+ {Index,Dict#asm{fnames=Fnames#{Name=>Index}}}
end.
%% Returns the atom table.
@@ -204,14 +199,12 @@ fname(Name, #asm{fnames=Fnames0}=Dict) ->
-spec atom_table(bdict()) -> {non_neg_integer(), [[non_neg_integer(),...]]}.
atom_table(#asm{atoms=Atoms}) ->
- NumAtoms = gb_trees:size(Atoms),
- Sorted = lists:keysort(2, gb_trees:to_list(Atoms)),
- Fun = fun({A,_}) ->
- L = atom_to_list(A),
- [length(L)|L]
- end,
- AtomTab = lists:map(Fun, Sorted),
- {NumAtoms,AtomTab}.
+ NumAtoms = maps:size(Atoms),
+ Sorted = lists:keysort(2, maps:to_list(Atoms)),
+ {NumAtoms,[begin
+ L = atom_to_list(A),
+ [length(L)|L]
+ end || {A,_} <- Sorted]}.
%% Returns the table of local functions.
%% local_table(Dict) -> {NumLocals, [{Function, Arity, Label}...]}
@@ -273,11 +266,11 @@ my_term_to_binary(Term) ->
non_neg_integer(),[{non_neg_integer(),non_neg_integer()}]}.
line_table(#asm{fnames=Fnames0,lines=Lines0,num_lines=NumLineInstrs}) ->
- NumFnames = gb_trees:size(Fnames0),
- Fnames1 = lists:keysort(2, gb_trees:to_list(Fnames0)),
+ NumFnames = maps:size(Fnames0),
+ Fnames1 = lists:keysort(2, maps:to_list(Fnames0)),
Fnames = [Name || {Name,_} <- Fnames1],
- NumLines = gb_trees:size(Lines0),
- Lines1 = lists:keysort(2, gb_trees:to_list(Lines0)),
+ NumLines = maps:size(Lines0),
+ Lines1 = lists:keysort(2, maps:to_list(Lines0)),
Lines = [L || {L,_} <- Lines1],
{NumLineInstrs,NumFnames,Fnames,NumLines,Lines}.
diff --git a/lib/compiler/src/beam_disasm.erl b/lib/compiler/src/beam_disasm.erl
index c45596f236..84a94f09e3 100644
--- a/lib/compiler/src/beam_disasm.erl
+++ b/lib/compiler/src/beam_disasm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%=======================================================================
diff --git a/lib/compiler/src/beam_disasm.hrl b/lib/compiler/src/beam_disasm.hrl
index c2aca1199e..30e3f22665 100644
--- a/lib/compiler/src/beam_disasm.hrl
+++ b/lib/compiler/src/beam_disasm.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/src/beam_except.erl b/lib/compiler/src/beam_except.erl
index d261809765..e33655281f 100644
--- a/lib/compiler/src/beam_except.erl
+++ b/lib/compiler/src/beam_except.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl
index 46835bece1..13c243b155 100644
--- a/lib/compiler/src/beam_flatten.erl
+++ b/lib/compiler/src/beam_flatten.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -63,8 +64,7 @@ norm({set,[],[S,D],{set_tuple_element,I}}) -> {set_tuple_element,S,D,I};
norm({set,[D1,D2],[S],get_list}) -> {get_list,S,D1,D2};
norm({set,[D],[S|Puts],{alloc,R,{put_map,Op,F}}}) ->
{put_map,F,Op,S,D,R,{list,Puts}};
-norm({set,Gets,[S],{get_map_elements,F}}) ->
- {get_map_elements,F,S,{list,Gets}};
+%% get_map_elements is always handled in beam_split (moved out of block)
norm({set,[],[],remove_message}) -> remove_message;
norm({set,[],[],fclearerror}) -> fclearerror;
norm({set,[],[],fcheckerror}) -> {fcheckerror,{f,0}}.
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index b952139f2c..5e58e0f6ac 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -127,7 +128,7 @@
%%% on the program state.
%%%
--import(lists, [reverse/1,reverse/2,foldl/3,dropwhile/2]).
+-import(lists, [reverse/1,reverse/2,foldl/3]).
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
@@ -152,20 +153,26 @@ function({function,Name,Arity,CLabel,Asm0}) ->
share(Is0) ->
%% We will get more sharing if we never fall through to a label.
Is = eliminate_fallthroughs(Is0, []),
- share_1(Is, dict:new(), [], []).
+ share_1(Is, #{}, [], []).
share_1([{label,_}=Lbl|Is], Dict, [], Acc) ->
share_1(Is, Dict, [], [Lbl|Acc]);
share_1([{label,L}=Lbl|Is], Dict0, Seq, Acc) ->
- case dict:find(Seq, Dict0) of
+ case maps:find(Seq, Dict0) of
error ->
- Dict = dict:store(Seq, L, Dict0),
+ Dict = maps:put(Seq, L, Dict0),
share_1(Is, Dict, [], [Lbl|Seq ++ Acc]);
{ok,Label} ->
share_1(Is, Dict0, [], [Lbl,{jump,{f,Label}}|Acc])
end;
share_1([{func_info,_,_,_}=I|Is], _, [], Acc) ->
reverse(Is, [I|Acc]);
+share_1([{'try',_,_}=I|Is], Dict0, Seq, Acc) ->
+ Dict = clean_non_sharable(Dict0),
+ share_1(Is, Dict, [I|Seq], Acc);
+share_1([{try_case,_}=I|Is], Dict0, Seq, Acc) ->
+ Dict = clean_non_sharable(Dict0),
+ share_1(Is, Dict, [I|Seq], Acc);
share_1([I|Is], Dict, Seq, Acc) ->
case is_unreachable_after(I) of
false ->
@@ -174,6 +181,24 @@ share_1([I|Is], Dict, Seq, Acc) ->
share_1(Is, Dict, [I], Acc)
end.
+clean_non_sharable(Dict) ->
+ %% We are passing in or out of a 'try' block. Remove
+ %% sequences that should not shared over the boundaries
+ %% of a 'try' block. Since the end of the sequence must match,
+ %% the only possible match between a sequence outside and
+ %% a sequence inside the 'try' block is a sequence that ends
+ %% with an instruction that causes an exception. Any sequence
+ %% that causes an exception must contain a line/1 instruction.
+ maps:filter(fun(K, _V) -> sharable_with_try(K) end, Dict).
+
+sharable_with_try([{line,_}|_]) ->
+ %% This sequence may cause an exception and may potentially
+ %% match a sequence on the other side of the 'try' block
+ %% boundary.
+ false;
+sharable_with_try([_|Is]) ->
+ sharable_with_try(Is);
+sharable_with_try([]) -> true.
%% Eliminate all fallthroughs. Return the result reversed.
@@ -244,13 +269,13 @@ extract_seq_1(_, _) -> no.
-record(st, {fc, %Label for function class errors.
entry, %Entry label (must not be moved).
mlbl, %Moved labels.
- labels %Set of referenced labels.
+ labels :: cerl_sets:set() %Set of referenced labels.
}).
opt([{label,Fc}|_]=Is0, CLabel) ->
Lbls = initial_labels(Is0),
find_fixpoint(fun(Is) ->
- St = #st{fc=Fc,entry=CLabel,mlbl=dict:new(),
+ St = #st{fc=Fc,entry=CLabel,mlbl=#{},
labels=Lbls},
opt(Is, [], St)
end, Is0).
@@ -295,24 +320,29 @@ opt([{test,_,{f,_}=Lbl,_,_,_}=I|Is], Acc, St) ->
opt(Is, [I|Acc], label_used(Lbl, St));
opt([{select,_,_R,Fail,Vls}=I|Is], Acc, St) ->
skip_unreachable(Is, [I|Acc], label_used([Fail|Vls], St));
-opt([{label,L}=I|Is], Acc, #st{entry=L}=St) ->
- %% NEVER move the entry label.
- opt(Is, [I|Acc], St);
-opt([{label,L1},{jump,{f,L2}}=I|Is], [Prev|Acc], St0) ->
- St = St0#st{mlbl=dict:append(L2, L1, St0#st.mlbl)},
- opt([Prev,I|Is], Acc, label_used({f,L2}, St));
opt([{label,Lbl}=I|Is], Acc, #st{mlbl=Mlbl}=St0) ->
- case dict:find(Lbl, Mlbl) of
+ case maps:find(Lbl, Mlbl) of
{ok,Lbls} ->
%% Essential to remove the list of labels from the dictionary,
%% since we will rescan the inserted labels. We MUST rescan.
- St = St0#st{mlbl=dict:erase(Lbl, Mlbl)},
+ St = St0#st{mlbl=maps:remove(Lbl, Mlbl)},
insert_labels([Lbl|Lbls], Is, Acc, St);
error -> opt(Is, [I|Acc], St0)
end;
-opt([{jump,{f,Lbl}},{label,Lbl}=I|Is], Acc, St) ->
- opt([I|Is], Acc, St);
-opt([{jump,Lbl}=I|Is], Acc, St) ->
+opt([{jump,{f,_}=X}|[{label,_},{jump,X}|_]=Is], Acc, St) ->
+ opt(Is, Acc, St);
+opt([{jump,{f,Lbl}}|[{label,Lbl}|_]=Is], Acc, St) ->
+ opt(Is, Acc, St);
+opt([{jump,{f,L}=Lbl}=I|Is], Acc0, #st{mlbl=Mlbl0}=St0) ->
+ %% All labels before this jump instruction should now be
+ %% moved to the location of the jump's target.
+ {Lbls,Acc} = collect_labels(Acc0, St0),
+ St = case Lbls of
+ [] -> St0;
+ [_|_] ->
+ Mlbl = maps_append_list(L, Lbls, Mlbl0),
+ St0#st{mlbl=Mlbl}
+ end,
skip_unreachable(Is, [I|Acc], label_used(Lbl, St));
%% Optimization: quickly handle some common instructions that don't
%% have any failure labels and where is_unreachable_after(I) =:= false.
@@ -334,14 +364,20 @@ opt([I|Is], Acc, #st{labels=Used0}=St0) ->
end;
opt([], Acc, #st{fc=Fc,mlbl=Mlbl}) ->
Code = reverse(Acc),
- case dict:find(Fc, Mlbl) of
+ case maps:find(Fc, Mlbl) of
{ok,Lbls} -> insert_fc_labels(Lbls, Mlbl, Code);
error -> Code
end.
+maps_append_list(K,Vs,M) ->
+ case M of
+ #{K:=Vs0} -> M#{K:=Vs0++Vs}; % same order as dict
+ _ -> M#{K => Vs}
+ end.
+
insert_fc_labels([L|Ls], Mlbl, Acc0) ->
Acc = [{label,L}|Acc0],
- case dict:find(L, Mlbl) of
+ case maps:find(L, Mlbl) of
error ->
insert_fc_labels(Ls, Mlbl, Acc);
{ok,Lbls} ->
@@ -349,6 +385,17 @@ insert_fc_labels([L|Ls], Mlbl, Acc0) ->
end;
insert_fc_labels([], _, Acc) -> Acc.
+collect_labels(Is, #st{entry=Entry}) ->
+ collect_labels_1(Is, Entry, []).
+
+collect_labels_1([{label,Entry}|_]=Is, Entry, Acc) ->
+ %% Never move the entry label.
+ {Acc,Is};
+collect_labels_1([{label,L}|Is], Entry, Acc) ->
+ collect_labels_1(Is, Entry, [L|Acc]);
+collect_labels_1(Is, _Entry, Acc) ->
+ {Acc,Is}.
+
%% label_defined(Is, Label) -> true | false.
%% Test whether the label Label is defined at the start of the instruction
%% sequence, possibly preceeded by other label definitions.
@@ -394,7 +441,7 @@ skip_unreachable([], Acc, St) ->
%% Add one or more label to the set of used labels.
-label_used({f,L}, St) -> St#st{labels=gb_sets:add(L, St#st.labels)};
+label_used({f,L}, St) -> St#st{labels=cerl_sets:add_element(L,St#st.labels)};
label_used([H|T], St0) -> label_used(T, label_used(H, St0));
label_used([], St) -> St;
label_used(_Other, St) -> St.
@@ -402,7 +449,7 @@ label_used(_Other, St) -> St.
%% Test if label is used.
is_label_used(L, St) ->
- gb_sets:is_member(L, St#st.labels).
+ cerl_sets:is_element(L, St#st.labels).
%% is_unreachable_after(Instruction) -> boolean()
%% Test whether the code after Instruction is unreachable.
@@ -432,29 +479,29 @@ is_exit_instruction(_) -> false.
%% (including inside blocks).
is_label_used_in(Lbl, Is) ->
- is_label_used_in_1(Is, Lbl, gb_sets:empty()).
+ 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_2(I, Lbl) end, Block)
+ 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),
- gb_sets:is_member(Lbl, Used) orelse is_label_used_in_1(Is, Lbl, 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_2({set,_,_,Info}, Lbl) ->
+is_label_used_in_block({set,_,_,Info}, Lbl) ->
case Info of
- {bif,_,{f,F}} -> F =:= Lbl;
- {alloc,_,{gc_bif,_,{f,F}}} -> F =:= Lbl;
+ {bif,_,{f,F}} -> F =:= Lbl;
+ {alloc,_,{gc_bif,_,{f,F}}} -> F =:= Lbl;
{alloc,_,{put_map,_,{f,F}}} -> F =:= Lbl;
- {'catch',{f,F}} -> F =:= Lbl;
- {alloc,_,_} -> false;
- {put_tuple,_} -> false;
- {get_tuple_element,_} -> false;
- {set_tuple_element,_} -> false;
{get_map_elements,{f,F}} -> F =:= Lbl;
- {line,_} -> false;
- _ when is_atom(Info) -> false
+ {'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
@@ -467,13 +514,10 @@ remove_unused_labels(Is) ->
rem_unused(Is, Used, []).
rem_unused([{label,Lbl}=I|Is0], Used, [Prev|_]=Acc) ->
- case gb_sets:is_member(Lbl, Used) of
+ case cerl_sets:is_element(Lbl, Used) of
false ->
Is = case is_unreachable_after(Prev) of
- true ->
- dropwhile(fun({label,_}) -> false;
- (_) -> true
- end, Is0);
+ true -> drop_upto_label(Is0);
false -> Is0
end,
rem_unused(Is, Used, Acc);
@@ -492,7 +536,11 @@ initial_labels([{line,_}|Is], Acc) ->
initial_labels([{label,Lbl}|Is], Acc) ->
initial_labels(Is, [Lbl|Acc]);
initial_labels([{func_info,_,_,_},{label,Lbl}|_], Acc) ->
- gb_sets:from_list([Lbl|Acc]).
+ cerl_sets:from_list([Lbl|Acc]).
+
+drop_upto_label([{label,_}|_]=Is) -> Is;
+drop_upto_label([_|Is]) -> drop_upto_label(Is);
+drop_upto_label([]) -> [].
%% ulbl(Instruction, UsedGbSet) -> UsedGbSet'
%% Update the gb_set UsedGbSet with any function-local labels
@@ -536,10 +584,10 @@ ulbl({get_map_elements,Lbl,_Src,_List}, Used) ->
ulbl(_, Used) -> Used.
mark_used({f,0}, Used) -> Used;
-mark_used({f,L}, Used) -> gb_sets:add(L, Used).
+mark_used({f,L}, Used) -> cerl_sets:add_element(L, Used).
mark_used_list([{f,L}|T], Used) ->
- mark_used_list(T, gb_sets:add(L, Used));
+ mark_used_list(T, cerl_sets:add_element(L, Used));
mark_used_list([_|T], Used) ->
mark_used_list(T, Used);
mark_used_list([], Used) -> Used.
diff --git a/lib/compiler/src/beam_listing.erl b/lib/compiler/src/beam_listing.erl
index 50d1f3cdb1..fd5c0a042b 100644
--- a/lib/compiler/src/beam_listing.erl
+++ b/lib/compiler/src/beam_listing.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -46,8 +47,8 @@ module(Stream, {Mod,Exp,Attr,Code,NumLabels}) ->
fun ({function,Name,Arity,Entry,Asm}) ->
io:format(Stream, "\n\n{function, ~w, ~w, ~w}.\n",
[Name, Arity, Entry]),
- foreach(fun(Op) -> print_op(Stream, Op) end, Asm) end,
- Code);
+ io:put_chars(Stream, format_asm(Asm))
+ end, Code);
module(Stream, {Mod,Exp,Inter}) ->
%% Other kinds of intermediate formats.
io:fwrite(Stream, "~w.~n~p.~n", [Mod,Exp]),
@@ -56,10 +57,11 @@ module(Stream, [_|_]=Fs) ->
%% Form-based abstract format.
foreach(fun (F) -> io:format(Stream, "~p.\n", [F]) end, Fs).
-print_op(Stream, Label) when element(1, Label) == label ->
- io:format(Stream, " ~p.\n", [Label]);
-print_op(Stream, Op) ->
- io:format(Stream, " ~p.\n", [Op]).
+format_asm([{label,L}|Is]) ->
+ [" {label,",integer_to_list(L),"}.\n"|format_asm(Is)];
+format_asm([I|Is]) ->
+ [io_lib:format(" ~p", [I]),".\n"|format_asm(Is)];
+format_asm([]) -> [].
function(File, {function,Name,Arity,Args,Body,Vdb,_Anno}) ->
io:nl(File),
diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl
index 97a8c7ba70..17fd2e502a 100644
--- a/lib/compiler/src/beam_peep.erl
+++ b/lib/compiler/src/beam_peep.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -108,14 +109,14 @@ peep([{test,Op,_,Ops}=I|Is], SeenTests0, Acc) ->
%% has succeeded.
peep(Is, gb_sets:empty(), [I|Acc]);
true ->
- Test = {Op,Ops},
- case gb_sets:is_element(Test, SeenTests0) of
+ case is_test_redundant(Op, Ops, SeenTests0) of
true ->
- %% This test has already succeeded and
+ %% This test or a similar test has already succeeded and
%% is therefore redundant.
peep(Is, SeenTests0, Acc);
false ->
%% Remember that we have seen this test.
+ Test = {Op,Ops},
SeenTests = gb_sets:insert(Test, SeenTests0),
peep(Is, SeenTests, [I|Acc])
end
@@ -136,6 +137,15 @@ peep([I|Is], _, Acc) ->
peep(Is, gb_sets:empty(), [I|Acc]);
peep([], _, Acc) -> reverse(Acc).
+is_test_redundant(Op, Ops, Seen) ->
+ gb_sets:is_element({Op,Ops}, Seen) orelse
+ is_test_redundant_1(Op, Ops, Seen).
+
+is_test_redundant_1(is_boolean, [R], Seen) ->
+ gb_sets:is_element({is_eq_exact,[R,{atom,false}]}, Seen) orelse
+ gb_sets:is_element({is_eq_exact,[R,{atom,true}]}, Seen);
+is_test_redundant_1(_, _, _) -> false.
+
kill_seen(Dst, Seen0) ->
gb_sets:from_ordset(kill_seen_1(gb_sets:to_list(Seen0), Dst)).
diff --git a/lib/compiler/src/beam_receive.erl b/lib/compiler/src/beam_receive.erl
index 97a9188ee7..7276537949 100644
--- a/lib/compiler/src/beam_receive.erl
+++ b/lib/compiler/src/beam_receive.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/src/beam_split.erl b/lib/compiler/src/beam_split.erl
index 688bba9a94..3be9311080 100644
--- a/lib/compiler/src/beam_split.erl
+++ b/lib/compiler/src/beam_split.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -53,8 +54,8 @@ split_block([{set,[D],[S|Puts],{alloc,R,{put_map,Op,{f,Lbl}=Fail}}}|Is],
Bl, Acc) when Lbl =/= 0 ->
split_block(Is, [], [{put_map,Fail,Op,S,D,R,{list,Puts}}|
make_block(Bl, Acc)]);
-split_block([{set,Gets,[S],{get_map_elements,{f,Lbl}=Fail}}|Is], Bl, Acc)
- when Lbl =/= 0 ->
+split_block([{set,Ds,[S|Ss],{get_map_elements,Fail}}|Is], Bl, Acc) ->
+ Gets = beam_utils:join_even(Ss,Ds),
split_block(Is, [], [{get_map_elements,Fail,S,{list,Gets}}|make_block(Bl, Acc)]);
split_block([{set,[R],[],{'catch',L}}|Is], Bl, Acc) ->
split_block(Is, [], [{'catch',R,L}|make_block(Bl, Acc)]);
diff --git a/lib/compiler/src/beam_trim.erl b/lib/compiler/src/beam_trim.erl
index fad9c42584..509e013b62 100644
--- a/lib/compiler/src/beam_trim.erl
+++ b/lib/compiler/src/beam_trim.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -172,6 +173,10 @@ remap([{bif,Name,Fail,Ss,D}|Is], Map, Acc) ->
remap([{gc_bif,Name,Fail,Live,Ss,D}|Is], Map, Acc) ->
I = {gc_bif,Name,Fail,Live,[Map(S) || S <- Ss],Map(D)},
remap(Is, Map, [I|Acc]);
+remap([{get_map_elements,Fail,M,{list,L0}}|Is], Map, Acc) ->
+ L = [Map(E) || E <- L0],
+ I = {get_map_elements,Fail,Map(M),{list,L}},
+ remap(Is, Map, [I|Acc]);
remap([{bs_init,Fail,Info,Live,Ss0,Dst0}|Is], Map, Acc) ->
Ss = [Map(Src) || Src <- Ss0],
Dst = Map(Dst0),
@@ -275,6 +280,8 @@ frame_size([{kill,_}|Is], Safe) ->
frame_size(Is, Safe);
frame_size([{make_fun2,_,_,_,_}|Is], Safe) ->
frame_size(Is, Safe);
+frame_size([{get_map_elements,{f,L},_,_}|Is], Safe) ->
+ frame_size_branch(L, Is, Safe);
frame_size([{deallocate,N}|_], _) -> N;
frame_size([{line,_}|Is], Safe) ->
frame_size(Is, Safe);
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index 58c0f765ae..5298589f83 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -106,6 +107,20 @@ simplify_basic_1([{test,test_arity,_,[R,Arity]}=I|Is], Ts0, Acc) ->
Ts = update(I, Ts0),
simplify_basic_1(Is, Ts, [I|Acc])
end;
+simplify_basic_1([{test,is_map,_,[R]}=I|Is], Ts0, Acc) ->
+ case tdb_find(R, Ts0) of
+ map -> simplify_basic_1(Is, Ts0, Acc);
+ _Other ->
+ Ts = update(I, Ts0),
+ simplify_basic_1(Is, Ts, [I|Acc])
+ end;
+simplify_basic_1([{test,is_nonempty_list,_,[R]}=I|Is], Ts0, Acc) ->
+ case tdb_find(R, Ts0) of
+ nonempty_list -> simplify_basic_1(Is, Ts0, Acc);
+ _Other ->
+ Ts = update(I, Ts0),
+ simplify_basic_1(Is, Ts, [I|Acc])
+ end;
simplify_basic_1([{test,is_eq_exact,Fail,[R,{atom,_}=Atom]}=I|Is0], Ts0, Acc0) ->
Acc = case tdb_find(R, Ts0) of
{atom,_}=Atom -> Acc0;
@@ -135,9 +150,10 @@ simplify_basic_1([], Ts, Acc) ->
%%
simplify_float(Is0, Ts0) ->
{Is1,Ts} = simplify_float_1(Is0, Ts0, [], []),
- Is2 = flt_need_heap(Is1),
+ Is2 = opt_fmoves(Is1, []),
+ Is3 = flt_need_heap(Is2),
try
- {flt_liveness(Is2),Ts}
+ {flt_liveness(Is3),Ts}
catch
throw:not_possible -> not_possible
end.
@@ -188,14 +204,15 @@ simplify_float_1([{set,_,_,{'catch',_}}=I|Is]=Is0, _Ts, Rs0, Acc0) ->
simplify_float_1(Is, tdb_new(), Rs0, [I|Acc]);
simplify_float_1([{set,_,_,{line,_}}=I|Is], Ts, Rs, Acc) ->
simplify_float_1(Is, Ts, Rs, [I|Acc]);
+simplify_float_1([I|Is], Ts0, [], Acc) ->
+ Ts = update(I, Ts0),
+ simplify_float_1(Is, Ts, [], [I|Acc]);
simplify_float_1([I|Is]=Is0, Ts0, Rs0, Acc0) ->
Ts = update(I, Ts0),
{Rs,Acc} = flush(Rs0, Is0, Acc0),
simplify_float_1(Is, Ts, Rs, [I|checkerror(Acc)]);
-simplify_float_1([], Ts, Rs, Acc0) ->
- Acc = checkerror(Acc0),
- Is0 = reverse(flush_all(Rs, [], Acc)),
- Is = opt_fmoves(Is0, []),
+simplify_float_1([], Ts, [], Acc) ->
+ Is = reverse(Acc),
{Is,Ts}.
coerce_to_float({integer,I}=Int) ->
@@ -230,7 +247,7 @@ clearerror([], OrigIs) -> [{set,[],[],fclearerror}|OrigIs].
%% Combine two blocks and eliminate any move instructions that assign
%% to registers that are killed later in the block.
%%
-merge_blocks(B1, [{'%live',_}|B2]) ->
+merge_blocks(B1, [{'%live',_,_}|B2]) ->
merge_blocks_1(B1++[{set,[],[],stop_here}|B2]).
merge_blocks_1([{set,[],_,stop_here}|Is]) -> Is;
@@ -315,27 +332,27 @@ build_alloc(Words, Floats) -> {alloc,[{words,Words},{floats,Floats}]}.
%% flt_liveness([Instruction]) -> [Instruction]
%% (Re)calculate the number of live registers for each heap allocation
-%% function. We base liveness of the number of live registers at
-%% entry to the instruction sequence.
+%% function. We base liveness of the number of register map at the
+%% beginning of the instruction sequence.
%%
%% A 'not_possible' term will be thrown if the set of live registers
%% is not continous at an allocation function (e.g. if {x,0} and {x,2}
%% are live, but not {x,1}).
-flt_liveness([{'%live',Live}=LiveInstr|Is]) ->
- flt_liveness_1(Is, init_regs(Live), [LiveInstr]).
+flt_liveness([{'%live',_Live,Regs}=LiveInstr|Is]) ->
+ flt_liveness_1(Is, Regs, [LiveInstr]).
-flt_liveness_1([{set,Ds,Ss,{alloc,_,Alloc}}|Is], Regs0, Acc) ->
- Live = live_regs(Regs0),
+flt_liveness_1([{set,Ds,Ss,{alloc,Live0,Alloc}}|Is], Regs0, Acc) ->
+ Live = min(Live0, live_regs(Regs0)),
I = {set,Ds,Ss,{alloc,Live,Alloc}},
- Regs = foldl(fun(R, A) -> set_live(R, A) end, Regs0, Ds),
+ Regs1 = init_regs(Live),
+ Regs = x_live(Ds, Regs1),
flt_liveness_1(Is, Regs, [I|Acc]);
flt_liveness_1([{set,Ds,_,_}=I|Is], Regs0, Acc) ->
- Regs = foldl(fun(R, A) -> set_live(R, A) end, Regs0, Ds),
- flt_liveness_1(Is, Regs, [I|Acc]);
-flt_liveness_1([{'%live',_}=I|Is], Regs, Acc) ->
+ Regs = x_live(Ds, Regs0),
flt_liveness_1(Is, Regs, [I|Acc]);
-flt_liveness_1([], _Regs, Acc) -> reverse(Acc).
+flt_liveness_1([{'%live',_,_}], _Regs, Acc) ->
+ reverse(Acc).
init_regs(Live) ->
(1 bsl Live) - 1.
@@ -350,14 +367,15 @@ live_regs_1(R, N) ->
1 -> live_regs_1(R bsr 1, N+1)
end.
-set_live({x,X}, Regs) -> Regs bor (1 bsl X);
-set_live(_, Regs) -> Regs.
+x_live([{x,N}|Rs], Regs) -> x_live(Rs, Regs bor (1 bsl N));
+x_live([_|Rs], Regs) -> x_live(Rs, Regs);
+x_live([], Regs) -> Regs.
%% update(Instruction, TypeDb) -> NewTypeDb
%% Update the type database to account for executing an instruction.
%%
%% First the cases for instructions inside basic blocks.
-update({'%live',_}, Ts) -> Ts;
+update({'%live',_,_}, Ts) -> Ts;
update({set,[D],[S],move}, Ts) ->
tdb_copy(S, D, Ts);
update({set,[D],[{integer,I},Reg],{bif,element,_}}, Ts0) ->
@@ -402,6 +420,10 @@ update({test,is_float,_Fail,[Src]}, Ts0) ->
tdb_update([{Src,float}], Ts0);
update({test,test_arity,_Fail,[Src,Arity]}, Ts0) ->
tdb_update([{Src,{tuple,Arity,[]}}], Ts0);
+update({test,is_map,_Fail,[Src]}, Ts0) ->
+ tdb_update([{Src,map}], Ts0);
+update({test,is_nonempty_list,_Fail,[Src]}, Ts0) ->
+ tdb_update([{Src,nonempty_list}], Ts0);
update({test,is_eq_exact,_,[Reg,{atom,_}=Atom]}, Ts) ->
case tdb_find(Reg, Ts) of
error ->
@@ -451,6 +473,7 @@ is_math_bif(erf, 1) -> true;
is_math_bif(erfc, 1) -> true;
is_math_bif(exp, 1) -> true;
is_math_bif(log, 1) -> true;
+is_math_bif(log2, 1) -> true;
is_math_bif(log10, 1) -> true;
is_math_bif(sqrt, 1) -> true;
is_math_bif(atan2, 2) -> true;
@@ -532,10 +555,10 @@ flush(Rs, [{set,[_],[],{put_tuple,_}}|_]=Is0, Acc0) ->
Acc = flush_all(Rs, Is0, Acc0),
{[],Acc};
flush(Rs0, [{set,Ds,Ss,_Op}|_], Acc0) ->
- Save = gb_sets:from_list(Ss),
+ Save = cerl_sets:from_list(Ss),
Acc = save_regs(Rs0, Save, Acc0),
Rs1 = foldl(fun(S, A) -> mark(S, A, clean) end, Rs0, Ss),
- Kill = gb_sets:from_list(Ds),
+ Kill = cerl_sets:from_list(Ds),
Rs = kill_regs(Rs1, Kill),
{Rs,Acc};
flush(Rs0, Is, Acc0) ->
@@ -558,7 +581,7 @@ save_regs(Rs, Save, Acc) ->
foldl(fun(R, A) -> save_reg(R, Save, A) end, Acc, Rs).
save_reg({I,V,dirty}, Save, Acc) ->
- case gb_sets:is_member(V, Save) of
+ case cerl_sets:is_element(V, Save) of
true -> [{set,[V],[{fr,I}],fmove}|checkerror(Acc)];
false -> Acc
end;
@@ -568,7 +591,7 @@ kill_regs(Rs, Kill) ->
[kill_reg(R, Kill) || R <- Rs].
kill_reg({_,V,_}=R, Kill) ->
- case gb_sets:is_member(V, Kill) of
+ case cerl_sets:is_element(V, Kill) of
true -> free;
false -> R
end;
@@ -710,6 +733,8 @@ merge_type_info(NewType, _) ->
verify_type(NewType),
NewType.
+verify_type(map) -> ok;
+verify_type(nonempty_list) -> ok;
verify_type({tuple,Sz,[]}) when is_integer(Sz) -> ok;
verify_type({tuple,Sz,[_]}) when is_integer(Sz) -> ok;
verify_type({tuple_element,_,_}) -> ok;
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 8ca368c167..fbcd5de1bb 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,6 +27,8 @@
code_at/2,bif_to_test/3,is_pure_test/1,
live_opt/1,delete_live_annos/1,combine_heap_needs/2]).
+-export([join_even/2,split_even/1]).
+
-import(lists, [member/2,sort/1,reverse/1,splitwith/2]).
-record(live,
@@ -126,8 +129,7 @@ empty_label_index() ->
%% Add an index for a label.
index_label(Lbl, Is0, Acc) ->
- Is = lists:dropwhile(fun({label,_}) -> true;
- (_) -> false end, Is0),
+ Is = drop_labels(Is0),
gb_trees:enter(Lbl, Is, Acc).
@@ -185,7 +187,7 @@ is_pure_test({test,is_lt,_,[_,_]}) -> true;
is_pure_test({test,is_nil,_,[_]}) -> true;
is_pure_test({test,is_nonempty_list,_,[_]}) -> true;
is_pure_test({test,test_arity,_,[_,_]}) -> true;
-is_pure_test({test,has_map_fields,_,[_,{list,_}]}) -> true;
+is_pure_test({test,has_map_fields,_,[_|_]}) -> true;
is_pure_test({test,Op,_,Ops}) ->
erl_internal:new_type_test(Op, length(Ops)).
@@ -194,7 +196,7 @@ is_pure_test({test,Op,_,Ops}) ->
%% Go through the instruction sequence in reverse execution
%% order, keep track of liveness and remove 'move' instructions
%% whose destination is a register that will not be used.
-%% Also insert {'%live',Live} annotations at the beginning
+%% Also insert {'%live',Live,Regs} annotations at the beginning
%% and end of each block.
%%
live_opt(Is0) ->
@@ -215,7 +217,7 @@ delete_live_annos([{block,Bl0}|Is]) ->
[] -> delete_live_annos(Is);
[_|_]=Bl -> [{block,Bl}|delete_live_annos(Is)]
end;
-delete_live_annos([{'%live',_}|Is]) ->
+delete_live_annos([{'%live',_,_}|Is]) ->
delete_live_annos(Is);
delete_live_annos([I|Is]) ->
[I|delete_live_annos(Is)];
@@ -342,14 +344,10 @@ check_liveness(R, [{call_ext,Live,_}=I|Is], St) ->
false ->
check_liveness(R, Is, St);
true ->
- %% We must make sure we don't check beyond this instruction
- %% or we will fall through into random unrelated code and
- %% get stuck in a loop.
- %%
- %% We don't want to overwrite a 'catch', so consider this
- %% register in use.
- %%
- {used,St}
+ %% We must make sure we don't check beyond this
+ %% instruction or we will fall through into random
+ %% unrelated code and get stuck in a loop.
+ {killed,St}
end
end;
check_liveness(R, [{call_fun,Live}|Is], St) ->
@@ -364,11 +362,6 @@ check_liveness(R, [{apply,Args}|Is], St) ->
{x,_} -> {killed,St};
{y,_} -> check_liveness(R, Is, St)
end;
-check_liveness({x,R}, [{'%live',Live}|Is], St) ->
- if
- R < Live -> check_liveness(R, Is, St);
- true -> {killed,St}
- end;
check_liveness(R, [{bif,Op,{f,Fail},Ss,D}|Is], St0) ->
case check_liveness_fail(R, Op, Ss, Fail, St0) of
{killed,St} = Killed ->
@@ -475,6 +468,22 @@ check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) ->
check_liveness_at(R, Fail, St);
check_liveness(R, [{line,_}|Is], St) ->
check_liveness(R, Is, St);
+check_liveness(R, [{get_map_elements,{f,Fail},S,{list,L}}|Is], St0) ->
+ {Ss,Ds} = split_even(L),
+ case member(R, [S|Ss]) of
+ true ->
+ {used,St0};
+ false ->
+ case check_liveness_at(R, Fail, St0) of
+ {killed,St}=Killed ->
+ case member(R, Ds) of
+ true -> Killed;
+ false -> check_liveness(R, Is, St)
+ end;
+ Other ->
+ Other
+ end
+ end;
check_liveness(_R, Is, St) when is_list(Is) ->
%% case Is of
%% [I|_] ->
@@ -552,7 +561,7 @@ check_killed_block(R, [{set,Ds,Ss,_Op}|Is]) ->
false -> check_killed_block(R, Is)
end
end;
-check_killed_block(R, [{'%live',Live}|Is]) ->
+check_killed_block(R, [{'%live',Live,_}|Is]) ->
case R of
{x,X} when X >= Live -> killed;
_ -> check_killed_block(R, Is)
@@ -575,7 +584,7 @@ check_used_block({x,X}=R, [{set,Ds,Ss,{alloc,Live,Op}}|Is], St) ->
end;
check_used_block(R, [{set,Ds,Ss,Op}|Is], St) ->
check_used_block_1(R, Ss, Ds, Op, Is, St);
-check_used_block(R, [{'%live',Live}|Is], St) ->
+check_used_block(R, [{'%live',Live,_}|Is], St) ->
case R of
{x,X} when X >= Live -> {killed,St};
_ -> check_used_block(R, Is, St)
@@ -615,13 +624,15 @@ is_reg_used_at_1(R, Lbl, St0) ->
end.
index_labels_1([{label,Lbl}|Is0], Acc) ->
- Is = lists:dropwhile(fun({label,_}) -> true;
- (_) -> false end, Is0),
+ Is = drop_labels(Is0),
index_labels_1(Is0, [{Lbl,Is}|Acc]);
index_labels_1([_|Is], Acc) ->
index_labels_1(Is, Acc);
index_labels_1([], Acc) -> gb_trees:from_orddict(sort(Acc)).
+drop_labels([{label,_}|Is]) -> drop_labels(Is);
+drop_labels(Is) -> Is.
+
%% Help functions for combine_heap_needs.
combine_alloc_lists(Al1, Al2) ->
@@ -676,9 +687,9 @@ live_opt([{test,bs_start_match2,Fail,Live,[Src,_],_}=I|Is], _, D, Acc) ->
%% Other instructions.
live_opt([{block,Bl0}|Is], Regs0, D, Acc) ->
- Live0 = {'%live',live_regs(Regs0)},
+ Live0 = {'%live',live_regs(Regs0),Regs0},
{Bl,Regs} = live_opt_block(reverse(Bl0), Regs0, D, [Live0]),
- Live = {'%live',live_regs(Regs)},
+ Live = {'%live',live_regs(Regs),Regs},
live_opt(Is, Regs, D, [{block,[Live|Bl]}|Acc]);
live_opt([{label,L}=I|Is], Regs, D0, Acc) ->
D = gb_trees:insert(L, Regs, D0),
@@ -756,13 +767,9 @@ live_opt([{line,_}=I|Is], Regs, D, Acc) ->
live_opt(Is, Regs, D, [I|Acc]);
%% The following instructions can occur if the "compilation" has been
-%% started from a .S file using the 'asm' option.
+%% started from a .S file using the 'from_asm' option.
live_opt([{trim,_,_}=I|Is], Regs, D, Acc) ->
live_opt(Is, Regs, D, [I|Acc]);
-live_opt([{allocate,_,Live}=I|Is], _, D, Acc) ->
- live_opt(Is, live_call(Live), D, [I|Acc]);
-live_opt([{allocate_heap,_,_,Live}=I|Is], _, D, Acc) ->
- live_opt(Is, live_call(Live), D, [I|Acc]);
live_opt([{'%',_}=I|Is], Regs, D, Acc) ->
live_opt(Is, Regs, D, [I|Acc]);
live_opt([{recv_set,_}=I|Is], Regs, D, Acc) ->
@@ -832,3 +839,15 @@ x_live([_|Rs], Regs) -> x_live(Rs, Regs);
x_live([], Regs) -> Regs.
is_live(X, Regs) -> ((Regs bsr X) band 1) =:= 1.
+
+%% split_even/1
+%% [1,2,3,4,5,6] -> {[1,3,5],[2,4,6]}
+split_even(Rs) -> split_even(Rs,[],[]).
+split_even([],Ss,Ds) -> {reverse(Ss),reverse(Ds)};
+split_even([S,D|Rs],Ss,Ds) ->
+ split_even(Rs,[S|Ss],[D|Ds]).
+
+%% join_even/1
+%% {[1,3,5],[2,4,6]} -> [1,2,3,4,5,6]
+join_even([],[]) -> [];
+join_even([S|Ss],[D|Ds]) -> [S,D|join_even(Ss,Ds)].
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 9d5563d13b..6004f1974e 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -22,14 +23,13 @@
%% Avoid warning for local function error/1 clashing with autoimported BIF.
-compile({no_auto_import,[error/1]}).
--export([file/1, files/1]).
%% Interface for compiler.
-export([module/2, format_error/1]).
-include("beam_disasm.hrl").
--import(lists, [reverse/1,foldl/3,foreach/2,member/2,dropwhile/2]).
+-import(lists, [reverse/1,foldl/3,foreach/2,dropwhile/2]).
-define(MAXREG, 1024).
@@ -40,38 +40,12 @@
-define(DBG_FORMAT(F, D), ok).
-endif.
-%%%
-%%% API functions.
-%%%
-
--spec file(file:filename()) -> 'ok' | {'error', term()}.
-
-file(Name) when is_list(Name) ->
- case case filename:extension(Name) of
- ".S" -> s_file(Name);
- ".beam" -> beam_file(Name)
- end of
- [] -> ok;
- Es -> {error,Es}
- end.
-
--spec files([file:filename()]) -> 'ok'.
-
-files([F|Fs]) ->
- ?DBG_FORMAT("# Verifying: ~p~n", [F]),
- case file(F) of
- ok -> ok;
- {error,Es} ->
- io:format("~tp:~n~ts~n", [F,format_error(Es)])
- end,
- files(Fs);
-files([]) -> ok.
-
%% To be called by the compiler.
module({Mod,Exp,Attr,Fs,Lc}=Code, _Opts)
when is_atom(Mod), is_list(Exp), is_list(Attr), is_integer(Lc) ->
case validate(Mod, Fs) of
- [] -> {ok,Code};
+ [] ->
+ {ok,Code};
Es0 ->
Es = [{?MODULE,E} || E <- Es0],
{error,[{atom_to_list(Mod),Es}]}
@@ -79,12 +53,6 @@ module({Mod,Exp,Attr,Fs,Lc}=Code, _Opts)
-spec format_error(term()) -> iolist().
-format_error([]) -> [];
-format_error([{{M,F,A},{I,Off,Desc}}|Es]) ->
- [io_lib:format(" ~p:~p/~p+~p:~n ~p - ~p~n",
- [M,F,A,Off,I,Desc])|format_error(Es)];
-format_error([Error|Es]) ->
- [format_error(Error)|format_error(Es)];
format_error({{_M,F,A},{I,Off,limit}}) ->
io_lib:format(
"function ~p/~p+~p:~n"
@@ -103,8 +71,6 @@ format_error({{_M,F,A},{I,Off,Desc}}) ->
" Internal consistency check failed - please report this bug.~n"
" Instruction: ~p~n"
" Error: ~p:~n", [F,A,Off,I,Desc]);
-format_error({Module,Error}) ->
- [Module:format_error(Error)];
format_error(Error) ->
io_lib:format("~p~n", [Error]).
@@ -112,36 +78,6 @@ format_error(Error) ->
%%% Local functions follow.
%%%
-s_file(Name) ->
- {ok,Is} = file:consult(Name),
- {module,Module} = lists:keyfind(module, 1, Is),
- Fs = find_functions(Is),
- validate(Module, Fs).
-
-find_functions(Fs) ->
- find_functions_1(Fs, none, [], []).
-
-find_functions_1([{function,Name,Arity,Entry}|Is], Func, FuncAcc, Acc0) ->
- Acc = add_func(Func, FuncAcc, Acc0),
- find_functions_1(Is, {Name,Arity,Entry}, [], Acc);
-find_functions_1([I|Is], Func, FuncAcc, Acc) ->
- find_functions_1(Is, Func, [I|FuncAcc], Acc);
-find_functions_1([], Func, FuncAcc, Acc) ->
- reverse(add_func(Func, FuncAcc, Acc)).
-
-add_func(none, _, Acc) -> Acc;
-add_func({Name,Arity,Entry}, Is, Acc) ->
- [{function,Name,Arity,Entry,reverse(Is)}|Acc].
-
-beam_file(Name) ->
- try beam_disasm:file(Name) of
- {error,beam_lib,Reason} -> [{beam_lib,Reason}];
- #beam_file{module=Module, code=Code0} ->
- Code = normalize_disassembled_code(Code0),
- validate(Module, Code)
- catch _:_ -> [disassembly_failed]
- end.
-
%%%
%%% The validator follows.
%%%
@@ -196,23 +132,16 @@ validate_0(Module, [{function,Name,Ar,Entry,Code}|Fs], Ft) ->
try validate_1(Code, Name, Ar, Entry, Ft) of
_ -> validate_0(Module, Fs, Ft)
catch
- Error ->
+ throw:Error ->
+ %% Controlled error.
[Error|validate_0(Module, Fs, Ft)];
- error:Error ->
- [validate_error(Error, Module, Name, Ar)|validate_0(Module, Fs, Ft)]
+ Class:Error ->
+ %% Crash.
+ Stack = erlang:get_stacktrace(),
+ io:fwrite("Function: ~w/~w\n", [Name,Ar]),
+ erlang:raise(Class, Error, Stack)
end.
--ifdef(DEBUG).
-validate_error(Error, Module, Name, Ar) ->
- exit(validate_error_1(Error, Module, Name, Ar)).
--else.
-validate_error(Error, Module, Name, Ar) ->
- validate_error_1(Error, Module, Name, Ar).
--endif.
-validate_error_1(Error, Module, Name, Ar) ->
- {{Module,Name,Ar},
- {internal_error,'_',{Error,erlang:get_stacktrace()}}}.
-
-type index() :: non_neg_integer().
-type reg_tab() :: gb_trees:tree(index(), 'none' | {'value', _}).
@@ -225,8 +154,6 @@ validate_error_1(Error, Module, Name, Ar) ->
hf=0, %Available heap size for floats.
fls=undefined, %Floating point state.
ct=[], %List of hot catch/try labels
- bsm=undefined, %Bit syntax matching state.
- bits=undefined, %Number of bits in bit syntax binary.
setelem=false %Previous instruction was setelement/3.
}).
@@ -308,7 +235,7 @@ labels_1([{label,L}|Is], R) ->
labels_1([{line,_}|Is], R) ->
labels_1(Is, R);
labels_1(Is, R) ->
- {lists:reverse(R),Is}.
+ {reverse(R),Is}.
init_state(Arity) ->
Xs = init_regs(Arity, term),
@@ -403,10 +330,6 @@ valfun_1({init,{y,_}=Reg}, Vst) ->
set_type_y(initialized, Reg, Vst);
valfun_1({test_heap,Heap,Live}, Vst) ->
test_heap(Heap, Live, Vst);
-valfun_1({bif,_Op,nofail,Src,Dst}, Vst) ->
- %% The 'nofail' atom only occurs in disassembled code.
- validate_src(Src, Vst),
- set_type_reg(term, Dst, Vst);
valfun_1({bif,Op,{f,_},Src,Dst}=I, Vst) ->
case is_bif_safe(Op, length(Src)) of
false ->
@@ -432,18 +355,12 @@ valfun_1({put_tuple,Sz,Dst}, Vst0) when is_integer(Sz) ->
valfun_1({put,Src}, Vst) ->
assert_term(Src, Vst),
eat_heap(1, Vst);
-valfun_1({put_string,Sz,_,Dst}, Vst0) when is_integer(Sz) ->
- Vst = eat_heap(2*Sz, Vst0),
- set_type_reg(cons, Dst, Vst);
%% Instructions for optimization of selective receives.
valfun_1({recv_mark,{f,Fail}}, Vst) when is_integer(Fail) ->
Vst;
valfun_1({recv_set,{f,Fail}}, Vst) when is_integer(Fail) ->
Vst;
%% Misc.
-valfun_1({'%live',Live}, Vst) ->
- verify_live(Live, Vst),
- Vst;
valfun_1(remove_message, Vst) ->
Vst;
valfun_1({'%',_}, Vst) ->
@@ -494,37 +411,33 @@ valfun_1({'try',Dst,{f,Fail}}, Vst0) ->
Vst = #vst{current=#st{ct=Fails}=St} =
set_type_y({trytag,[Fail]}, Dst, Vst0),
Vst#vst{current=St#st{ct=[[Fail]|Fails]}};
-valfun_1({catch_end,Reg}, #vst{current=#st{ct=[Fail|Fails]}=St0}=Vst0) ->
+valfun_1({catch_end,Reg}, #vst{current=#st{ct=[Fail|Fails]}}=Vst0) ->
case get_special_y_type(Reg, Vst0) of
{catchtag,Fail} ->
- Vst = #vst{current=St} =
- set_type_y(initialized_ct, Reg,
- Vst0#vst{current=St0#st{ct=Fails}}),
+ Vst = #vst{current=St} = set_catch_end(Reg, Vst0),
Xs = gb_trees_from_list([{0,term}]),
- Vst#vst{current=St#st{x=Xs,fls=undefined}};
+ Vst#vst{current=St#st{x=Xs,ct=Fails,fls=undefined}};
Type ->
error({bad_type,Type})
end;
-valfun_1({try_end,Reg}, #vst{current=#st{ct=[Fail|Fails]}=St}=Vst0) ->
+valfun_1({try_end,Reg}, #vst{current=#st{ct=[Fail|Fails]}=St0}=Vst0) ->
case get_special_y_type(Reg, Vst0) of
{trytag,Fail} ->
Vst = case Fail of
[FailLabel] -> branch_state(FailLabel, Vst0);
_ -> Vst0
end,
- set_type_reg(initialized_ct, Reg,
- Vst#vst{current=St#st{ct=Fails,fls=undefined}});
+ St = St0#st{ct=Fails,fls=undefined},
+ set_catch_end(Reg, Vst#vst{current=St});
Type ->
error({bad_type,Type})
end;
-valfun_1({try_case,Reg}, #vst{current=#st{ct=[Fail|Fails]}=St0}=Vst0) ->
+valfun_1({try_case,Reg}, #vst{current=#st{ct=[Fail|Fails]}}=Vst0) ->
case get_special_y_type(Reg, Vst0) of
{trytag,Fail} ->
- Vst = #vst{current=St} =
- set_type_y(initialized_ct, Reg,
- Vst0#vst{current=St0#st{ct=Fails}}),
- Xs = gb_trees_from_list([{0,{atom,[]}},{1,term},{2,term}]), %XXX
- Vst#vst{current=St#st{x=Xs,fls=undefined}};
+ Vst = #vst{current=St} = set_catch_end(Reg, Vst0),
+ Xs = gb_trees_from_list([{0,{atom,[]}},{1,term},{2,term}]),
+ Vst#vst{current=St#st{x=Xs,ct=Fails,fls=undefined}};
Type ->
error({bad_type,Type})
end;
@@ -602,8 +515,6 @@ valfun_4({call_ext_last,Live,Func,StkSize},
tail_call(Func, Live, Vst);
valfun_4({call_ext_last,_,_,_}, #vst{current=#st{numy=NumY}}) ->
error({allocated,NumY});
-valfun_4({make_fun,_,_,Live}, Vst) ->
- call('fun', Live, Vst);
valfun_4({make_fun2,_,_,_,Live}, Vst) ->
call(make_fun, Live, Vst);
%% Other BIFs
@@ -620,8 +531,6 @@ valfun_4({bif,element,{f,Fail},[Pos,Tuple],Dst}, Vst0) ->
TupleType = upgrade_tuple_type({tuple,[get_tuple_size(PosType)]}, TupleType0),
Vst = set_type(TupleType, Tuple, Vst1),
set_type_reg(term, Dst, Vst);
-valfun_4({raise,{f,_}=Fail,Src,Dst}, Vst) ->
- valfun_4({bif,raise,Fail,Src,Dst}, Vst);
valfun_4({bif,Op,{f,Fail},Src,Dst}, Vst0) ->
validate_src(Src, Vst0),
Vst = branch_state(Fail, Vst0),
@@ -738,32 +647,6 @@ valfun_4({bs_save2,Ctx,SavePoint}, Vst) ->
valfun_4({bs_restore2,Ctx,SavePoint}, Vst) ->
bsm_restore(Ctx, SavePoint, Vst);
-%% Bit syntax instructions.
-valfun_4({bs_start_match,{f,_Fail}=F,Src}, Vst) ->
- valfun_4({test,bs_start_match,F,[Src]}, Vst);
-valfun_4({test,bs_start_match,{f,Fail},[Src]}, Vst) ->
- assert_term(Src, Vst),
- bs_start_match(branch_state(Fail, Vst));
-
-valfun_4({bs_save,SavePoint}, Vst) ->
- bs_assert_state(Vst),
- bs_save(SavePoint, Vst);
-valfun_4({bs_restore,SavePoint}, Vst) ->
- bs_assert_state(Vst),
- bs_assert_savepoint(SavePoint, Vst),
- Vst;
-valfun_4({test,bs_skip_bits,{f,Fail},[Src,_,_]}, Vst) ->
- bs_assert_state(Vst),
- assert_term(Src, Vst),
- branch_state(Fail, Vst);
-valfun_4({test,bs_test_tail,{f,Fail},_}, Vst) ->
- bs_assert_state(Vst),
- branch_state(Fail, Vst);
-valfun_4({test,_,{f,Fail},[_,_,_,Dst]}, Vst0) ->
- bs_assert_state(Vst0),
- Vst = branch_state(Fail, Vst0),
- set_type_reg({integer,[]}, Dst, Vst);
-
%% Other test instructions.
valfun_4({test,is_float,{f,Lbl},[Float]}, Vst) ->
assert_term(Float, Vst),
@@ -779,9 +662,17 @@ valfun_4({test,test_arity,{f,Lbl},[Tuple,Sz]}, Vst) when is_integer(Sz) ->
assert_type(tuple, Tuple, Vst),
set_type_reg({tuple,Sz}, Tuple, branch_state(Lbl, Vst));
valfun_4({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) ->
- validate_src([Src], Vst),
- assert_strict_literal_termorder(List),
+ assert_type(map, Src, Vst),
+ assert_unique_map_keys(List),
branch_state(Lbl, Vst);
+valfun_4({test,is_map,{f,Lbl},[Src]}, Vst0) ->
+ Vst = branch_state(Lbl, Vst0),
+ case Src of
+ {Tag,_} when Tag =:= x; Tag =:= y ->
+ set_type_reg(map, Src, Vst);
+ _ ->
+ Vst
+ end;
valfun_4({test,_Op,{f,Lbl},Src}, Vst) ->
validate_src(Src, Vst),
branch_state(Lbl, Vst);
@@ -795,9 +686,6 @@ valfun_4({bs_utf8_size,{f,Fail},A,Dst}, Vst) ->
valfun_4({bs_utf16_size,{f,Fail},A,Dst}, Vst) ->
assert_term(A, Vst),
set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst));
-valfun_4({bs_bits_to_bytes,{f,Fail},Src,Dst}, Vst) ->
- assert_term(Src, Vst),
- set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst));
valfun_4({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) ->
verify_live(Live, Vst0),
if
@@ -808,8 +696,7 @@ valfun_4({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) ->
end,
Vst1 = heap_alloc(Heap, Vst0),
Vst2 = branch_state(Fail, Vst1),
- Vst3 = prune_x_regs(Live, Vst2),
- Vst = bs_zero_bits(Vst3),
+ Vst = prune_x_regs(Live, Vst2),
set_type_reg(binary, Dst, Vst);
valfun_4({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) ->
verify_live(Live, Vst0),
@@ -821,8 +708,7 @@ valfun_4({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) ->
end,
Vst1 = heap_alloc(Heap, Vst0),
Vst2 = branch_state(Fail, Vst1),
- Vst3 = prune_x_regs(Live, Vst2),
- Vst = bs_zero_bits(Vst3),
+ Vst = prune_x_regs(Live, Vst2),
set_type_reg(binary, Dst, Vst);
valfun_4({bs_append,{f,Fail},Bits,Heap,Live,_Unit,Bin,_Flags,Dst}, Vst0) ->
verify_live(Live, Vst0),
@@ -830,54 +716,36 @@ valfun_4({bs_append,{f,Fail},Bits,Heap,Live,_Unit,Bin,_Flags,Dst}, Vst0) ->
assert_term(Bin, Vst0),
Vst1 = heap_alloc(Heap, Vst0),
Vst2 = branch_state(Fail, Vst1),
- Vst3 = prune_x_regs(Live, Vst2),
- Vst = bs_zero_bits(Vst3),
+ Vst = prune_x_regs(Live, Vst2),
set_type_reg(binary, Dst, Vst);
valfun_4({bs_private_append,{f,Fail},Bits,_Unit,Bin,_Flags,Dst}, Vst0) ->
assert_term(Bits, Vst0),
assert_term(Bin, Vst0),
- Vst1 = branch_state(Fail, Vst0),
- Vst = bs_zero_bits(Vst1),
+ Vst = branch_state(Fail, Vst0),
set_type_reg(binary, Dst, Vst);
valfun_4({bs_put_string,Sz,_}, Vst) when is_integer(Sz) ->
Vst;
-valfun_4({bs_put_binary,{f,Fail},Sz,_,_,Src}=I, Vst0) ->
- assert_term(Sz, Vst0),
- assert_term(Src, Vst0),
- Vst = bs_align_check(I, Vst0),
+valfun_4({bs_put_binary,{f,Fail},Sz,_,_,Src}, Vst) ->
+ assert_term(Sz, Vst),
+ assert_term(Src, Vst),
branch_state(Fail, Vst);
-valfun_4({bs_put_float,{f,Fail},Sz,_,_,Src}=I, Vst0) ->
- assert_term(Sz, Vst0),
- assert_term(Src, Vst0),
- Vst = bs_align_check(I, Vst0),
+valfun_4({bs_put_float,{f,Fail},Sz,_,_,Src}, Vst) ->
+ assert_term(Sz, Vst),
+ assert_term(Src, Vst),
branch_state(Fail, Vst);
-valfun_4({bs_put_integer,{f,Fail},Sz,_,_,Src}=I, Vst0) ->
- assert_term(Sz, Vst0),
- assert_term(Src, Vst0),
- Vst = bs_align_check(I, Vst0),
+valfun_4({bs_put_integer,{f,Fail},Sz,_,_,Src}, Vst) ->
+ assert_term(Sz, Vst),
+ assert_term(Src, Vst),
branch_state(Fail, Vst);
-valfun_4({bs_put_utf8,{f,Fail},_,Src}=I, Vst0) ->
- assert_term(Src, Vst0),
- Vst = bs_align_check(I, Vst0),
+valfun_4({bs_put_utf8,{f,Fail},_,Src}, Vst) ->
+ assert_term(Src, Vst),
branch_state(Fail, Vst);
-valfun_4({bs_put_utf16,{f,Fail},_,Src}=I, Vst0) ->
- assert_term(Src, Vst0),
- Vst = bs_align_check(I, Vst0),
+valfun_4({bs_put_utf16,{f,Fail},_,Src}, Vst) ->
+ assert_term(Src, Vst),
branch_state(Fail, Vst);
-valfun_4({bs_put_utf32,{f,Fail},_,Src}=I, Vst0) ->
- assert_term(Src, Vst0),
- Vst = bs_align_check(I, Vst0),
+valfun_4({bs_put_utf32,{f,Fail},_,Src}, Vst) ->
+ assert_term(Src, Vst),
branch_state(Fail, Vst);
-%% Old bit syntax construction (before R10B).
-valfun_4({bs_init,_,_}, Vst) ->
- bs_zero_bits(Vst);
-valfun_4({bs_need_buf,_}, Vst) -> Vst;
-valfun_4({bs_final,{f,Fail},Dst}, Vst0) ->
- Vst = branch_state(Fail, Vst0),
- set_type_reg(binary, Dst, Vst);
-valfun_4({bs_final2,Src,Dst}, Vst0) ->
- assert_term(Src, Vst0),
- set_type_reg(binary, Dst, Vst0);
%% Map instructions.
valfun_4({put_map_assoc,{f,Fail},Src,Dst,Live,{list,List}}, Vst) ->
verify_put_map(Fail, Src, Dst, Live, List, Vst);
@@ -889,11 +757,25 @@ valfun_4(_, _) ->
error(unknown_instruction).
verify_get_map(Fail, Src, List, Vst0) ->
- assert_term(Src, Vst0),
- Vst1 = branch_state(Fail, Vst0),
- Lits = mmap(fun(L,_R) -> [L] end, List),
- assert_strict_literal_termorder(Lits),
- verify_get_map_pair(List,Vst0,Vst1).
+ assert_type(map, Src, Vst0),
+ Vst1 = foldl(fun(D, Vsti) ->
+ case is_reg_defined(D,Vsti) of
+ true -> set_type_reg(term,D,Vsti);
+ false -> Vsti
+ end
+ end, Vst0, extract_map_vals(List)),
+ Vst2 = branch_state(Fail, Vst1),
+ Keys = extract_map_keys(List),
+ assert_unique_map_keys(Keys),
+ verify_get_map_pair(List,Vst0,Vst2).
+
+extract_map_vals([_Key,Val|T]) ->
+ [Val|extract_map_vals(T)];
+extract_map_vals([]) -> [].
+
+extract_map_keys([Key,_Val|T]) ->
+ [Key|extract_map_keys(T)];
+extract_map_keys([]) -> [].
verify_get_map_pair([],_,Vst) -> Vst;
verify_get_map_pair([Src,Dst|Vs],Vst0,Vsti) ->
@@ -901,14 +783,16 @@ verify_get_map_pair([Src,Dst|Vs],Vst0,Vsti) ->
verify_get_map_pair(Vs,Vst0,set_type_reg(term,Dst,Vsti)).
verify_put_map(Fail, Src, Dst, Live, List, Vst0) ->
+ assert_type(map, Src, Vst0),
verify_live(Live, Vst0),
verify_y_init(Vst0),
foreach(fun (Term) -> assert_term(Term, Vst0) end, List),
- assert_term(Src, Vst0),
Vst1 = heap_alloc(0, Vst0),
Vst2 = branch_state(Fail, Vst1),
Vst = prune_x_regs(Live, Vst2),
- set_type_reg(term, Dst, Vst).
+ Keys = extract_map_keys(List),
+ assert_unique_map_keys(Keys),
+ set_type_reg(map, Dst, Vst).
%%
%% Common code for validating bs_get* instructions.
@@ -936,9 +820,6 @@ validate_bs_skip_utf(Fail, Ctx, Live, Vst0) ->
%%
val_dsetel({move,_,_}, Vst) ->
Vst;
-val_dsetel({put_string,0,{string,""},_}, Vst) ->
- %% An empty string is OK since it doesn't build anything.
- Vst;
val_dsetel({call_ext,3,{extfunc,erlang,setelement,3}}, #vst{current=St}=Vst) ->
Vst#vst{current=St#st{setelem=true}};
val_dsetel({set_tuple_element,_,_,_}, #vst{current=#st{setelem=false}}) ->
@@ -972,7 +853,7 @@ call(Name, Live, #vst{current=St}=Vst) ->
Type when Type =/= exception ->
%% Type is never 'exception' because it has been handled earlier.
Xs = gb_trees_from_list([{0,Type}]),
- Vst#vst{current=St#st{x=Xs,f=init_fregs(),bsm=undefined}}
+ Vst#vst{current=St#st{x=Xs,f=init_fregs()}}
end.
%% Tail call.
@@ -1030,7 +911,7 @@ allocate(_, _, _, _, #vst{current=#st{numy=Numy}}) ->
error({existing_stack_frame,{size,Numy}}).
deallocate(#vst{current=St}=Vst) ->
- Vst#vst{current=St#st{y=init_regs(0, initialized),numy=none,bsm=undefined}}.
+ Vst#vst{current=St#st{y=init_regs(0, initialized),numy=none}}.
test_heap(Heap, Live, Vst0) ->
verify_live(Live, Vst0),
@@ -1038,7 +919,7 @@ test_heap(Heap, Live, Vst0) ->
heap_alloc(Heap, Vst).
heap_alloc(Heap, #vst{current=St0}=Vst) ->
- St1 = kill_heap_allocation(St0#st{bsm=undefined}),
+ St1 = kill_heap_allocation(St0),
St = heap_alloc_1(Heap, St1),
Vst#vst{current=St}.
@@ -1122,73 +1003,25 @@ assert_freg_set(Fr, _) -> error({bad_source,Fr}).
%%% Maps
-%% ensure that a list of literals has a strict
-%% ascending term order (also meaning unique literals)
-assert_strict_literal_termorder(Ls) ->
- Vs = lists:map(fun (L) -> get_literal(L) end, Ls),
- case check_strict_value_termorder(Vs) of
- true -> ok;
- false -> error({not_strict_order, Ls})
- end.
-
-%% usage:
-%% mmap(fun(A,B) -> [{A,B}] end, [1,2,3,4]),
-%% [{1,2},{3,4}]
-
-mmap(F,List) ->
- {arity,Ar} = erlang:fun_info(F,arity),
- mmap(F,Ar,List).
-mmap(_F,_,[]) -> [];
-mmap(F,Ar,List) ->
- {Hd,Tl} = lists:split(Ar,List),
- apply(F,Hd) ++ mmap(F,Ar,Tl).
-
-check_strict_value_termorder([]) -> true;
-check_strict_value_termorder([_]) -> true;
-check_strict_value_termorder([V1,V2]) ->
- erts_internal:cmp_term(V1,V2) < 0;
-check_strict_value_termorder([V1,V2|Vs]) ->
- case erts_internal:cmp_term(V1,V2) < 0 of
- true -> check_strict_value_termorder([V2|Vs]);
- false -> false
- end.
+%% A single item list may be either a list or a register.
+%%
+%% A list with more than item must contain unique literals.
+%%
+%% An empty list is not allowed.
-%%%
-%%% Binary matching.
-%%%
-%%% Possible values for the bsm field (=bit syntax matching state).
-%%%
-%%% undefined - Undefined (initial state). No matching instructions allowed.
-%%%
-%%% (gb set) - The gb set contains the defined save points.
-%%%
-%%% The bsm field is reset to 'undefined' by instructions that may cause a
-%%% a garbage collection (might move the binary) and/or context switch
-%%% (may invalidate the save points).
-
-bs_start_match(#vst{current=#st{bsm=undefined}=St}=Vst) ->
- Vst#vst{current=St#st{bsm=gb_sets:empty()}};
-bs_start_match(Vst) ->
- %% Must retain save points here - it is possible to restore back
- %% to a previous binary.
- Vst.
-
-bs_save(Reg, #vst{current=#st{bsm=Saved}=St}=Vst)
- when is_integer(Reg), Reg < ?MAXREG ->
- Vst#vst{current=St#st{bsm=gb_sets:add(Reg, Saved)}};
-bs_save(_, _) -> error(limit).
-
-bs_assert_savepoint(Reg, #vst{current=#st{bsm=Saved}}) ->
- case gb_sets:is_member(Reg, Saved) of
- false -> error({no_save_point,Reg});
- true -> ok
+assert_unique_map_keys([]) ->
+ %% There is no reason to use the get_map_elements and
+ %% has_map_fields instructions with empty lists.
+ error(empty_field_list);
+assert_unique_map_keys([_]) ->
+ ok;
+assert_unique_map_keys([_,_|_]=Ls) ->
+ Vs = [get_literal(L) || L <- Ls],
+ case length(Vs) =:= sets:size(sets:from_list(Vs)) of
+ true -> ok;
+ false -> error(keys_not_unique)
end.
-bs_assert_state(#vst{current=#st{bsm=undefined}}) ->
- error(no_bs_match_state);
-bs_assert_state(_) -> ok.
-
-
%%%
%%% New binary matching instructions.
%%%
@@ -1234,55 +1067,7 @@ bsm_restore(Reg, SavePoint, Vst) ->
end;
_ -> error({illegal_restore,SavePoint,range})
end.
-
-
-%%%
-%%% Validation of alignment in the bit syntax. (Currently, construction only.)
-%%%
-%%% We make sure that the aligned flag is only set when we can be sure of the
-%%% aligment.
-%%%
-
-bs_zero_bits(#vst{current=St}=Vst) ->
- Vst#vst{current=St#st{bits=0}}.
-
-bs_align_check({bs_put_utf8,_,Flags,_}, #vst{current=#st{}=St}=Vst) ->
- bs_verify_flags(Flags, St),
- Vst;
-bs_align_check({bs_put_utf16,_,Flags,_}, #vst{current=#st{}=St}=Vst) ->
- bs_verify_flags(Flags, St),
- Vst;
-bs_align_check({bs_put_utf32,_,Flags,_}, #vst{current=#st{}=St}=Vst) ->
- bs_verify_flags(Flags, St),
- Vst;
-bs_align_check({_,_,Sz,U,Flags,_}, #vst{current=#st{bits=Bits}=St}=Vst) ->
- bs_verify_flags(Flags, St),
- bs_update_bits(Bits, Sz, U, St, Vst).
-
-bs_update_bits(undefined, _, _, _, Vst) -> Vst;
-bs_update_bits(Bits0, {integer,Sz}, U, St, Vst) ->
- Bits = Bits0 + U*Sz,
- Vst#vst{current=St#st{bits=Bits}};
-bs_update_bits(_, {atom,all}, _, _, Vst) ->
- %% A binary will not change the alignment.
- Vst;
-bs_update_bits(_, _, U, _, Vst) when U rem 8 =:= 0 ->
- %% Units of 8, 16, and so on will not change the aligment.
- Vst;
-bs_update_bits(_, _, _, St, Vst) ->
- %% We can no longer be sure about aligment.
- Vst#vst{current=St#st{bits=undefined}}.
-
-bs_verify_flags({field_flags,Fl}, #st{bits=Bits}) ->
- case bs_is_aligned(Fl) of
- false -> ok;
- true when is_integer(Bits), Bits rem 8 =:= 0 -> ok;
- true -> error({aligned_flag_set,{bits,Bits}})
- end.
-bs_is_aligned(Fl) when is_integer(Fl) -> Fl band 1 =:= 1;
-bs_is_aligned(Fl) when is_list(Fl) -> member(aligned, Fl).
-
%%%
%%% Keeping track of types.
%%%
@@ -1298,35 +1083,37 @@ set_type_reg(Type, {x,X}, #vst{current=#st{x=Xs}=St}=Vst)
set_type_reg(Type, Reg, Vst) ->
set_type_y(Type, Reg, Vst).
-set_type_y(Type, {y,Y}=Reg, #vst{current=#st{y=Ys0,numy=NumY}=St}=Vst)
+set_type_y(Type, {y,Y}=Reg, #vst{current=#st{y=Ys0}=St}=Vst)
when is_integer(Y), 0 =< Y ->
limit_check(Y),
- case {Y,NumY} of
- {_,none} ->
- error({no_stack_frame,Reg});
- {_,_} when Y > NumY ->
- error({y_reg_out_of_range,Reg,NumY});
- {_,_} ->
- Ys = if Type =:= initialized_ct ->
- gb_trees:enter(Y, initialized, Ys0);
- true ->
- case gb_trees:lookup(Y, Ys0) of
- none ->
- gb_trees:insert(Y, Type, Ys0);
- {value,uinitialized} ->
- gb_trees:insert(Y, Type, Ys0);
- {value,{catchtag,_}=Tag} ->
- error(Tag);
- {value,{trytag,_}=Tag} ->
- error(Tag);
- {value,_} ->
- gb_trees:update(Y, Type, Ys0)
- end
- end,
- Vst#vst{current=St#st{y=Ys}}
- end;
+ Ys = case gb_trees:lookup(Y, Ys0) of
+ none ->
+ error({invalid_store,Reg,Type});
+ {value,{catchtag,_}=Tag} ->
+ error(Tag);
+ {value,{trytag,_}=Tag} ->
+ error(Tag);
+ {value,_} ->
+ gb_trees:update(Y, Type, Ys0)
+ end,
+ Vst#vst{current=St#st{y=Ys}};
set_type_y(Type, Reg, #vst{}) -> error({invalid_store,Reg,Type}).
+set_catch_end({y,Y}, #vst{current=#st{y=Ys0}=St}=Vst) ->
+ Ys = gb_trees:update(Y, initialized, Ys0),
+ Vst#vst{current=St#st{y=Ys}}.
+
+
+is_reg_defined({x,_}=Reg, Vst) -> is_type_defined_x(Reg, Vst);
+is_reg_defined({y,_}=Reg, Vst) -> is_type_defined_y(Reg, Vst);
+is_reg_defined(V, #vst{}) -> error({not_a_register, V}).
+
+is_type_defined_x({x,X}, #vst{current=#st{x=Xs}}) ->
+ gb_trees:is_defined(X,Xs).
+
+is_type_defined_y({y,Y}, #vst{current=#st{y=Ys}}) ->
+ gb_trees:is_defined(Y,Ys).
+
assert_term(Src, Vst) ->
get_term_type(Src, Vst),
ok.
@@ -1387,7 +1174,8 @@ assert_term(Src, Vst) ->
%%
%% number Integer or Float of unknown value
%%
-
+%% map Map.
+%%
assert_type(WantedType, Term, Vst) ->
assert_type(WantedType, get_term_type(Term, Vst)).
@@ -1469,6 +1257,7 @@ get_term_type_1(nil=T, _) -> T;
get_term_type_1({atom,A}=T, _) when is_atom(A) -> T;
get_term_type_1({float,F}=T, _) when is_float(F) -> T;
get_term_type_1({integer,I}=T, _) when is_integer(I) -> T;
+get_term_type_1({literal,Map}, _) when is_map(Map) -> map;
get_term_type_1({literal,_}=T, _) -> T;
get_term_type_1({x,X}=Reg, #vst{current=#st{x=Xs}}) when is_integer(X) ->
case gb_trees:lookup(X, Xs) of
@@ -1523,14 +1312,13 @@ merge_states(L, St, Branched) when L =/= 0 ->
{value,OtherSt} -> merge_states_1(St, OtherSt)
end.
-merge_states_1(#st{x=Xs0,y=Ys0,numy=NumY0,h=H0,ct=Ct0,bsm=Bsm0}=St,
- #st{x=Xs1,y=Ys1,numy=NumY1,h=H1,ct=Ct1,bsm=Bsm1}) ->
+merge_states_1(#st{x=Xs0,y=Ys0,numy=NumY0,h=H0,ct=Ct0},
+ #st{x=Xs1,y=Ys1,numy=NumY1,h=H1,ct=Ct1}) ->
NumY = merge_stk(NumY0, NumY1),
Xs = merge_regs(Xs0, Xs1),
Ys = merge_y_regs(Ys0, Ys1),
Ct = merge_ct(Ct0, Ct1),
- Bsm = merge_bsm(Bsm0, Bsm1),
- St#st{x=Xs,y=Ys,numy=NumY,h=min(H0, H1),ct=Ct,bsm=Bsm}.
+ #st{x=Xs,y=Ys,numy=NumY,h=min(H0, H1),ct=Ct}.
merge_stk(S, S) -> S;
merge_stk(_, _) -> undecided.
@@ -1560,20 +1348,24 @@ merge_regs_1([], [_|_]) -> [];
merge_regs_1([_|_], []) -> [].
merge_y_regs(Rs0, Rs1) ->
- Rs = merge_y_regs_1(gb_trees:to_list(Rs0), gb_trees:to_list(Rs1)),
- gb_trees_from_list(Rs).
+ case {gb_trees:size(Rs0),gb_trees:size(Rs1)} of
+ {Sz0,Sz1} when Sz0 < Sz1 ->
+ merge_y_regs_1(Sz0-1, Rs1, Rs0);
+ {_,Sz1} ->
+ merge_y_regs_1(Sz1-1, Rs0, Rs1)
+ end.
-merge_y_regs_1([Same|Rs1], [Same|Rs2]) ->
- [Same|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([{R1,_}|Rs1], [{R2,_}|_]=Rs2) when R1 < R2 ->
- [{R1,uninitialized}|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([{R1,_}|_]=Rs1, [{R2,_}|Rs2]) when R1 > R2 ->
- [{R2,uninitialized}|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([{R,Type1}|Rs1], [{R,Type2}|Rs2]) ->
- [{R,merge_types(Type1, Type2)}|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([], []) -> [];
-merge_y_regs_1([], [_|_]=Rs) -> Rs;
-merge_y_regs_1([_|_]=Rs, []) -> Rs.
+merge_y_regs_1(Y, S, Regs0) when Y >= 0 ->
+ Type0 = gb_trees:get(Y, Regs0),
+ case gb_trees:get(Y, S) of
+ Type0 ->
+ merge_y_regs_1(Y-1, S, Regs0);
+ Type1 ->
+ Type = merge_types(Type0, Type1),
+ Regs = gb_trees:update(Y, Type, Regs0),
+ merge_y_regs_1(Y-1, S, Regs)
+ end;
+merge_y_regs_1(_, _, Regs) -> Regs.
%% merge_types(Type1, Type2) -> Type
%% Return the most specific type possible.
@@ -1613,10 +1405,6 @@ merge_types(T1, T2) when T1 =/= T2 ->
%% Too different. All we know is that the type is a 'term'.
term.
-merge_bsm(undefined, _) -> undefined;
-merge_bsm(_, undefined) -> undefined;
-merge_bsm(Bsm0, Bsm1) -> gb_sets:intersection(Bsm0, Bsm1).
-
tuple_sz([Sz]) -> Sz;
tuple_sz(Sz) -> Sz.
@@ -1723,6 +1511,7 @@ bif_type(is_float, [_], _) -> bool;
bif_type(is_function, [_], _) -> bool;
bif_type(is_integer, [_], _) -> bool;
bif_type(is_list, [_], _) -> bool;
+bif_type(is_map, [_], _) -> bool;
bif_type(is_number, [_], _) -> bool;
bif_type(is_pid, [_], _) -> bool;
bif_type(is_port, [_], _) -> bool;
@@ -1752,6 +1541,7 @@ is_bif_safe(is_float, 1) -> true;
is_bif_safe(is_function, 1) -> true;
is_bif_safe(is_integer, 1) -> true;
is_bif_safe(is_list, 1) -> true;
+is_bif_safe(is_map, 1) -> true;
is_bif_safe(is_number, 1) -> true;
is_bif_safe(is_pid, 1) -> true;
is_bif_safe(is_port, 1) -> true;
@@ -1794,8 +1584,6 @@ return_type_1(M, F, A, _) when is_atom(M), is_atom(F), is_integer(A), A >= 0 ->
return_type_erl(exit, 1) -> exception;
return_type_erl(throw, 1) -> exception;
-return_type_erl(fault, 1) -> exception;
-return_type_erl(fault, 2) -> exception;
return_type_erl(error, 1) -> exception;
return_type_erl(error, 2) -> exception;
return_type_erl(F, A) when is_atom(F), is_integer(A), A >= 0 -> term.
@@ -1816,6 +1604,7 @@ return_type_math(erf, 1) -> {float,[]};
return_type_math(erfc, 1) -> {float,[]};
return_type_math(exp, 1) -> {float,[]};
return_type_math(log, 1) -> {float,[]};
+return_type_math(log2, 1) -> {float,[]};
return_type_math(log10, 1) -> {float,[]};
return_type_math(sqrt, 1) -> {float,[]};
return_type_math(atan2, 2) -> {float,[]};
@@ -1837,52 +1626,3 @@ error(Error) -> exit(Error).
-else.
error(Error) -> throw(Error).
-endif.
-
-
-%%%
-%%% Rewrite disassembled code to the same format as we used internally
-%%% to not have to worry later.
-%%%
-
-normalize_disassembled_code(Fs) ->
- Index = ndc_index(Fs, []),
- ndc(Fs, Index, []).
-
-ndc_index([{function,Name,Arity,Entry,_Code}|Fs], Acc) ->
- ndc_index(Fs, [{{Name,Arity},Entry}|Acc]);
-ndc_index([], Acc) ->
- gb_trees:from_orddict(lists:sort(Acc)).
-
-ndc([{function,Name,Arity,Entry,Code0}|Fs], D, Acc) ->
- Code = ndc_1(Code0, D, []),
- ndc(Fs, D, [{function,Name,Arity,Entry,Code}|Acc]);
-ndc([], _, Acc) -> reverse(Acc).
-
-ndc_1([{call=Op,A,{_,F,A}}|Is], D, Acc) ->
- ndc_1(Is, D, [{Op,A,{f,gb_trees:get({F,A}, D)}}|Acc]);
-ndc_1([{call_only=Op,A,{_,F,A}}|Is], D, Acc) ->
- ndc_1(Is, D, [{Op,A,{f,gb_trees:get({F,A}, D)}}|Acc]);
-ndc_1([{call_last=Op,A,{_,F,A},Sz}|Is], D, Acc) ->
- ndc_1(Is, D, [{Op,A,{f,gb_trees:get({F,A}, D)},Sz}|Acc]);
-ndc_1([{arithbif,Op,F,Src,Dst}|Is], D, Acc) ->
- ndc_1(Is, D, [{bif,Op,F,Src,Dst}|Acc]);
-ndc_1([{arithfbif,Op,F,Src,Dst}|Is], D, Acc) ->
- ndc_1(Is, D, [{bif,Op,F,Src,Dst}|Acc]);
-ndc_1([{test,bs_start_match2=Op,F,[A1,Live,A3,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3],Dst}|Acc]);
-ndc_1([{test,bs_get_binary2=Op,F,[A1,Live,A3,A4,A5,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3,A4,A5],Dst}|Acc]);
-ndc_1([{test,bs_get_float2=Op,F,[A1,Live,A3,A4,A5,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3,A4,A5],Dst}|Acc]);
-ndc_1([{test,bs_get_integer2=Op,F,[A1,Live,A3,A4,A5,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3,A4,A5],Dst}|Acc]);
-ndc_1([{test,bs_get_utf8=Op,F,[A1,Live,A3,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3],Dst}|Acc]);
-ndc_1([{test,bs_get_utf16=Op,F,[A1,Live,A3,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3],Dst}|Acc]);
-ndc_1([{test,bs_get_utf32=Op,F,[A1,Live,A3,Dst]}|Is], D, Acc) ->
- ndc_1(Is, D, [{test,Op,F,Live,[A1,A3],Dst}|Acc]);
-ndc_1([I|Is], D, Acc) ->
- ndc_1(Is, D, [I|Acc]);
-ndc_1([], _, Acc) ->
- reverse(Acc).
diff --git a/lib/compiler/src/beam_z.erl b/lib/compiler/src/beam_z.erl
index c2a6ef604e..8381578b68 100644
--- a/lib/compiler/src/beam_z.erl
+++ b/lib/compiler/src/beam_z.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -74,22 +75,21 @@ undo_rename({bs_init,F,{I,Extra,U,Flags},Live,[Sz,Src],Dst}) ->
{I,F,Sz,Extra,Live,U,Src,Flags,Dst};
undo_rename({bs_init,_,bs_init_writable=I,_,_,_}) ->
I;
+undo_rename({test,bs_match_string=Op,F,[Ctx,Bin0]}) ->
+ Bits = bit_size(Bin0),
+ Bin = case Bits rem 8 of
+ 0 -> Bin0;
+ Rem -> <<Bin0/bitstring,0:(8-Rem)>>
+ end,
+ {test,Op,F,[Ctx,Bits,{string,binary_to_list(Bin)}]};
undo_rename({put_map,Fail,assoc,S,D,R,L}) ->
{put_map_assoc,Fail,S,D,R,L};
undo_rename({put_map,Fail,exact,S,D,R,L}) ->
{put_map_exact,Fail,S,D,R,L};
undo_rename({test,has_map_fields,Fail,[Src|List]}) ->
- {test,has_map_fields,Fail,Src,{list,[to_typed_literal(V)||V<-List]}};
-undo_rename({get_map_elements,Fail,Src,{list, List}}) ->
- {get_map_elements,Fail,Src,{list,[to_typed_literal(V)||V<-List]}};
+ {test,has_map_fields,Fail,Src,{list,List}};
+undo_rename({get_map_elements,Fail,Src,{list,List}}) ->
+ {get_map_elements,Fail,Src,{list,List}};
undo_rename({select,I,Reg,Fail,List}) ->
{I,Reg,Fail,{list,List}};
undo_rename(I) -> I.
-
-%% to_typed_literal(Arg)
-%% transform Arg to specific literal i.e. float | integer | atom if applicable
-to_typed_literal({literal, V}) when is_float(V) -> {float, V};
-to_typed_literal({literal, V}) when is_atom(V) -> {atom, V};
-to_typed_literal({literal, V}) when is_integer(V) -> {integer, V};
-to_typed_literal({literal, []}) -> nil;
-to_typed_literal(V) -> V.
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index 9d6768b157..e7a2b8177a 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -123,11 +124,14 @@
bitstr_flags/1,
%% keep map exports here for now
+ c_map_pattern/1,
+ is_c_map/1,
map_es/1,
map_arg/1,
update_c_map/3,
c_map/1, is_c_map_empty/1,
ann_c_map/2, ann_c_map/3,
+ ann_c_map_pattern/2,
map_pair_op/1,map_pair_key/1,map_pair_val/1,
update_c_map_pair/4,
c_map_pair/2,
@@ -135,7 +139,8 @@
]).
-export_type([c_binary/0, c_bitstr/0, c_call/0, c_clause/0, c_cons/0, c_fun/0,
- c_literal/0, c_map/0, c_map_pair/0, c_module/0, c_tuple/0,
+ c_let/0, c_literal/0, c_map/0, c_map_pair/0,
+ c_module/0, c_tuple/0,
c_values/0, c_var/0, cerl/0, var_name/0]).
-include("core_parse.hrl").
@@ -252,7 +257,7 @@
%% @see c_primop/2
%% @see c_receive/1
%% @see c_seq/2
-%% @see c_try/3
+%% @see c_try/5
%% @see c_tuple/1
%% @see c_values/1
%% @see c_var/1
@@ -431,6 +436,8 @@ is_literal_term([H | T]) ->
is_literal_term(T) when is_tuple(T) ->
is_literal_term_list(tuple_to_list(T));
is_literal_term(B) when is_bitstring(B) -> true;
+is_literal_term(M) when is_map(M) ->
+ is_literal_term_list(maps:to_list(M));
is_literal_term(_) ->
false.
@@ -1450,7 +1457,7 @@ is_proper_list(_) ->
%% X4]</code>.
%%
%% @see c_cons/2
-%% @see c_nil/1
+%% @see c_nil/0
%% @see is_c_list/1
%% @see list_length/1
%% @see make_list/2
@@ -1481,7 +1488,7 @@ abstract_list([]) ->
%% efficient.</p>
%%
%% @see c_cons/2
-%% @see c_nil/1
+%% @see c_nil/0
%% @see is_c_list/1
%% @see list_elements/1
@@ -1577,20 +1584,51 @@ ann_make_list(_, [], Node) ->
%% ---------------------------------------------------------------------
%% maps
--spec map_es(c_map()) -> [c_map_pair()].
+%% @spec is_c_map(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% map constructor, otherwise <code>false</code>.
+
+-spec is_c_map(cerl()) -> boolean().
+
+is_c_map(#c_map{}) ->
+ true;
+is_c_map(#c_literal{val = V}) when is_map(V) ->
+ true;
+is_c_map(_) ->
+ false.
+
+-spec map_es(c_map() | c_literal()) -> [c_map_pair()].
+map_es(#c_literal{anno=As,val=M}) when is_map(M) ->
+ [ann_c_map_pair(As,
+ #c_literal{anno=As,val='assoc'},
+ #c_literal{anno=As,val=K},
+ #c_literal{anno=As,val=V}) || {K,V} <- maps:to_list(M)];
map_es(#c_map{es = Es}) ->
Es.
--spec map_arg(c_map()) -> c_map() | c_literal().
+-spec map_arg(c_map() | c_literal()) -> c_map() | c_literal().
+map_arg(#c_literal{anno=As,val=M}) when is_map(M) ->
+ #c_literal{anno=As,val=#{}};
map_arg(#c_map{arg=M}) ->
M.
-spec c_map([c_map_pair()]) -> c_map().
c_map(Pairs) ->
- #c_map{es=Pairs}.
+ ann_c_map([], Pairs).
+
+-spec c_map_pattern([c_map_pair()]) -> c_map().
+
+c_map_pattern(Pairs) ->
+ #c_map{es=Pairs, is_pat=true}.
+
+-spec ann_c_map_pattern([term()], [c_map_pair()]) -> c_map().
+
+ann_c_map_pattern(As, Pairs) ->
+ #c_map{anno=As, es=Pairs, is_pat=true}.
-spec is_c_map_empty(c_map() | c_literal()) -> boolean().
@@ -1598,25 +1636,13 @@ is_c_map_empty(#c_map{ es=[] }) -> true;
is_c_map_empty(#c_literal{val=M}) when is_map(M),map_size(M) =:= 0 -> true;
is_c_map_empty(_) -> false.
--spec ann_c_map([term()], [cerl()]) -> c_map() | c_literal().
+-spec ann_c_map([term()], [c_map_pair()]) -> c_map() | c_literal().
-ann_c_map(As,Es) ->
+ann_c_map(As, Es) ->
ann_c_map(As, #c_literal{val=#{}}, Es).
-spec ann_c_map([term()], c_map() | c_literal(), [c_map_pair()]) -> c_map() | c_literal().
-ann_c_map(As,#c_literal{val=Mval}=M,Es) when is_map(Mval), map_size(Mval) =:= 0 ->
- Pairs = [[Ck,Cv]||#c_map_pair{key=Ck,val=Cv}<-Es],
- IsLit = lists:foldl(fun(Pair,Res) ->
- Res andalso is_lit_list(Pair)
- end, true, Pairs),
- Fun = fun(Pair) -> [K,V] = lit_list_vals(Pair), {K,V} end,
- case IsLit of
- false ->
- #c_map{arg=M, es=Es, anno=As };
- true ->
- #c_literal{anno=As, val=maps:from_list(lists:map(Fun, Pairs))}
- end;
ann_c_map(As,#c_literal{val=M},Es) when is_map(M) ->
fold_map_pairs(As,Es,M);
ann_c_map(As,M,Es) ->
@@ -1644,14 +1670,14 @@ fold_map_pairs(As,[#c_map_pair{op=#c_literal{val=exact},key=Ck,val=Cv}=E|Es],M)
end;
false ->
#c_map{arg=#c_literal{val=M,anno=As}, es=[E|Es], anno=As }
- end;
-fold_map_pairs(As,Es,M) ->
- #c_map{arg=#c_literal{val=M,anno=As}, es=Es, anno=As }.
+ end.
-%-spec update_c_map(c_map() | c_literal(), [c_map_pair()]) -> c_map() | c_literal().
+-spec update_c_map(c_map(), cerl(), [cerl()]) -> c_map() | c_literal().
-update_c_map(Old,M,Es) ->
- #c_map{arg=M, es = Es, anno = get_ann(Old)}.
+update_c_map(#c_map{is_pat=true}=Old, M, Es) ->
+ Old#c_map{arg=M, es=Es};
+update_c_map(#c_map{is_pat=false}=Old, M, Es) ->
+ ann_c_map(get_ann(Old), M, Es).
map_pair_key(#c_map_pair{key=K}) -> K.
map_pair_val(#c_map_pair{val=V}) -> V.
@@ -1974,7 +2000,7 @@ update_c_fname(Node, Atom, Arity) ->
%%
%% @see c_fname/2
%% @see c_var/1
-%% @see c_var_name/1
+%% @see var_name/1
-spec is_c_fname(cerl()) -> boolean().
@@ -3063,10 +3089,12 @@ pat_vars(Node, Vs) ->
map ->
pat_list_vars(map_es(Node), Vs);
map_pair ->
- pat_list_vars([map_pair_op(Node),map_pair_key(Node),map_pair_val(Node)],Vs);
+ %% map_pair_key is not a pattern var, excluded
+ pat_list_vars([map_pair_op(Node),map_pair_val(Node)],Vs);
binary ->
pat_list_vars(binary_segments(Node), Vs);
bitstr ->
+ %% bitstr_size is not a pattern var, excluded
pat_vars(bitstr_val(Node), Vs);
alias ->
pat_vars(alias_pat(Node), [alias_var(Node) | Vs])
@@ -3650,7 +3678,7 @@ c_try(Expr, Vs, Body, Evs, Handler) ->
%% @spec ann_c_try(As::[term()], Expression::cerl(),
%% Variables::[cerl()], Body::cerl(),
%% EVars::[cerl()], Handler::cerl()) -> cerl()
-%% @see c_try/3
+%% @see c_try/5
-spec ann_c_try([term()], cerl(), [cerl()], cerl(), [cerl()], cerl()) ->
c_try().
@@ -3663,7 +3691,7 @@ ann_c_try(As, Expr, Vs, Body, Evs, Handler) ->
%% @spec update_c_try(Old::cerl(), Expression::cerl(),
%% Variables::[cerl()], Body::cerl(),
%% EVars::[cerl()], Handler::cerl()) -> cerl()
-%% @see c_try/3
+%% @see c_try/5
-spec update_c_try(c_try(), cerl(), [cerl()], cerl(), [cerl()], cerl()) ->
c_try().
@@ -3678,7 +3706,7 @@ update_c_try(Node, Expr, Vs, Body, Evs, Handler) ->
%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
%% try-expression, otherwise <code>false</code>.
%%
-%% @see c_try/3
+%% @see c_try/5
-spec is_c_try(cerl()) -> boolean().
@@ -3692,7 +3720,7 @@ is_c_try(_) ->
%%
%% @doc Returns the expression subtree of an abstract try-expression.
%%
-%% @see c_try/3
+%% @see c_try/5
-spec try_arg(c_try()) -> cerl().
@@ -3705,7 +3733,7 @@ try_arg(Node) ->
%% @doc Returns the list of success variable subtrees of an abstract
%% try-expression.
%%
-%% @see c_try/3
+%% @see c_try/5
-spec try_vars(c_try()) -> [cerl()].
@@ -3717,7 +3745,7 @@ try_vars(Node) ->
%%
%% @doc Returns the success body subtree of an abstract try-expression.
%%
-%% @see c_try/3
+%% @see c_try/5
-spec try_body(c_try()) -> cerl().
@@ -3730,7 +3758,7 @@ try_body(Node) ->
%% @doc Returns the list of exception variable subtrees of an abstract
%% try-expression.
%%
-%% @see c_try/3
+%% @see c_try/5
-spec try_evars(c_try()) -> [cerl()].
@@ -3743,7 +3771,7 @@ try_evars(Node) ->
%% @doc Returns the exception body subtree of an abstract
%% try-expression.
%%
-%% @see c_try/3
+%% @see c_try/5
-spec try_handler(c_try()) -> cerl().
@@ -3765,7 +3793,7 @@ try_handler(Node) ->
%% @see update_c_catch/2
%% @see is_c_catch/1
%% @see catch_body/1
-%% @see c_try/3
+%% @see c_try/5
-spec c_catch(cerl()) -> c_catch().
diff --git a/lib/compiler/src/cerl_clauses.erl b/lib/compiler/src/cerl_clauses.erl
index 87bd47c08b..4d2f1ebd1b 100644
--- a/lib/compiler/src/cerl_clauses.erl
+++ b/lib/compiler/src/cerl_clauses.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -354,29 +355,29 @@ match(P, E, Bs) ->
{false, Bs}
end
end;
- map ->
- %% The most we can do is to say "definitely no match" if a
- %% map pattern is matched against non-map data.
- case E of
- any ->
- {false, Bs};
- _ ->
- case type(E) of
- literal ->
- case is_map(concrete(E)) of
- false ->
- none;
- true ->
- {false, Bs}
- end;
- cons ->
- none;
- tuple ->
- none;
- _ ->
- {false, Bs}
- end
- end;
+ map ->
+ %% The most we can do is to say "definitely no match" if a
+ %% map pattern is matched against non-map data.
+ case E of
+ any ->
+ {false, Bs};
+ _ ->
+ case type(E) of
+ literal ->
+ case is_map(concrete(E)) of
+ false ->
+ none;
+ true ->
+ {false, Bs}
+ end;
+ cons ->
+ none;
+ tuple ->
+ none;
+ _ ->
+ {false, Bs}
+ end
+ end;
_ ->
match_1(P, E, Bs)
end.
diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl
index 75740e8b9d..cbcacf9e8e 100644
--- a/lib/compiler/src/cerl_inline.erl
+++ b/lib/compiler/src/cerl_inline.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -445,15 +446,14 @@ i_var_1(R, Opnd, Ctxt, Env, S) ->
residualize_var(R, S);
false ->
S1 = st__mark_inner_pending(L, S),
- case catch {ok, visit(Opnd, S1)} of
- {ok, {E, S2}} ->
+ try visit(Opnd, S1) of
+ {E, S2} ->
%% Note that we pass the current environment and
%% context to `copy', but not the current renaming.
S3 = st__clear_inner_pending(L, S2),
- copy(R, Opnd, E, Ctxt, Env, S3);
- {'EXIT', X} ->
- exit(X);
- X ->
+ copy(R, Opnd, E, Ctxt, Env, S3)
+ catch
+ throw:X ->
%% If we use destructive update for the
%% `inner-pending' flag, we must make sure to clear
%% it also if we make a nonlocal return.
@@ -1128,8 +1128,8 @@ i_call_3(M, F, As, E, Ctxt, Env, S) ->
%% Note that we extract the results of argument expessions here; the
%% expressions could still be sequences with side effects.
Vs = [concrete(result(A)) || A <- As],
- case catch {ok, apply(atom_val(M), atom_val(F), Vs)} of
- {ok, V} ->
+ try apply(atom_val(M), atom_val(F), Vs) of
+ V ->
%% Evaluation completed normally - try to turn the result
%% back into a syntax tree (representing a literal).
case is_literal_term(V) of
@@ -1142,8 +1142,9 @@ i_call_3(M, F, As, E, Ctxt, Env, S) ->
false ->
%% The result could not be represented as a literal.
i_call_4(M, F, As, E, Ctxt, Env, S)
- end;
- _ ->
+ end
+ catch
+ error:_ ->
%% The evaluation attempt did not complete normally.
i_call_4(M, F, As, E, Ctxt, Env, S)
end.
@@ -1341,23 +1342,23 @@ i_bitstr(E, Ren, Env, S) ->
S3 = count_size(weight(bitstr), S2),
{update_c_bitstr(E, Val, Size, Unit, Type, Flags), S3}.
-i_map(E, Ctx, Ren, Env, S) ->
+i_map(E, Ctx, Ren, Env, S0) ->
%% Visit the segments for value.
- {M1, S1} = i(map_arg(E), value, Ren, Env, S),
+ {M1, S1} = i(map_arg(E), value, Ren, Env, S0),
{Es, S2} = mapfoldl(fun (E, S) ->
i_map_pair(E, Ctx, Ren, Env, S)
end, S1, map_es(E)),
S3 = count_size(weight(map), S2),
{update_c_map(E, M1,Es), S3}.
-i_map_pair(E, Ctx, Ren, Env, S) ->
- %% It is not necessary to visit the Op and Key fields,
- %% since these are always literals.
- {Val, S1} = i(map_pair_val(E), Ctx, Ren, Env, S),
+i_map_pair(E, Ctx, Ren, Env, S0) ->
+ %% It is not necessary to visit the Op field
+ %% since it is always a literal.
+ {Key, S1} = i(map_pair_key(E), value, Ren, Env, S0),
+ {Val, S2} = i(map_pair_val(E), Ctx, Ren, Env, S1),
Op = map_pair_op(E),
- Key = map_pair_key(E),
- S2 = count_size(weight(map_pair), S1),
- {update_c_map_pair(E, Op, Key, Val), S2}.
+ S3 = count_size(weight(map_pair), S2),
+ {update_c_map_pair(E, Op, Key, Val), S3}.
%% This is a simplified version of `i_pattern', for lists of parameter
@@ -1420,15 +1421,11 @@ i_pattern(E, Ren, Env, Ren0, Env0, S) ->
S2 = count_size(weight(binary), S1),
{update_c_binary(E, Es), S2};
map ->
- %% map patterns should not have args
- M = map_arg(E),
-
{Es, S1} = mapfoldl(fun (E, S) ->
i_map_pair_pattern(E, Ren, Env, Ren0, Env0, S)
- end,
- S, map_es(E)),
+ end, S, map_es(E)),
S2 = count_size(weight(map), S1),
- {update_c_map(E, M, Es), S2};
+ {update_c_map(E, map_arg(E), Es), S2};
_ ->
case is_literal(E) of
true ->
@@ -1464,12 +1461,12 @@ i_bitstr_pattern(E, Ren, Env, Ren0, Env0, S) ->
i_map_pair_pattern(E, Ren, Env, Ren0, Env0, S) ->
%% It is not necessary to visit the Op it is always a literal.
- %% Same goes for Key
- {Val, S1} = i_pattern(map_pair_val(E), Ren, Env, Ren0, Env0, S),
+ %% Key is an expression
+ {Key, S1} = i(map_pair_key(E), value, Ren0, Env0, S),
+ {Val, S2} = i_pattern(map_pair_val(E), Ren, Env, Ren0, Env0, S1),
Op = map_pair_op(E), %% should be 'exact' literal
- Key = map_pair_key(E),
- S2 = count_size(weight(map_pair), S1),
- {update_c_map_pair(E, Op, Key, Val), S2}.
+ S3 = count_size(weight(map_pair), S2),
+ {update_c_map_pair(E, Op, Key, Val), S3}.
%% ---------------------------------------------------------------------
@@ -1740,12 +1737,11 @@ copy_1(R, Opnd, E, Ctxt, Env, S) ->
copy_inline(R, Opnd, E, Ctxt, Env, S) ->
S1 = st__mark_outer_pending(Opnd#opnd.loc, S),
- case catch {ok, copy_inline_1(R, E, Ctxt, Env, S1)} of
- {ok, {E1, S2}} ->
- {E1, st__clear_outer_pending(Opnd#opnd.loc, S2)};
- {'EXIT', X} ->
- exit(X);
- X ->
+ try copy_inline_1(R, E, Ctxt, Env, S1) of
+ {E1, S2} ->
+ {E1, st__clear_outer_pending(Opnd#opnd.loc, S2)}
+ catch
+ throw:X ->
%% If we use destructive update for the `outer-pending'
%% flag, we must make sure to clear it upon a nonlocal
%% return.
@@ -1762,19 +1758,16 @@ copy_inline_1(R, E, Ctxt, Env, S) ->
copy_inline_2(R, E, Ctxt, Env, S);
false ->
S1 = new_active_effort(get_effort_limit(S), S),
- case catch {ok, copy_inline_2(R, E, Ctxt, Env, S1)} of
- {ok, {E1, S2}} ->
+ try copy_inline_2(R, E, Ctxt, Env, S1) of
+ {E1, S2} ->
%% Revert to the old effort counter.
- {E1, revert_effort(S, S2)};
- {counter_exceeded, effort, _} ->
+ {E1, revert_effort(S, S2)}
+ catch
+ throw:{counter_exceeded, effort, _} ->
%% Aborted this inlining attempt because too much
%% effort was spent. Residualize the variable and
%% revert to the previous state.
- residualize_var(R, S);
- {'EXIT', X} ->
- exit(X);
- X ->
- throw(X)
+ residualize_var(R, S)
end
end.
@@ -1800,11 +1793,12 @@ copy_inline_2(R, E, Ctxt, Env, S) ->
%% close to zero at this point. (This is an extension to the
%% original algorithm.)
S1 = new_active_size(Limit + apply_size(length(Ctxt#app.opnds)), S),
- case catch {ok, inline(E, Ctxt, ren__identity(), Env, S1)} of
- {ok, {E1, S2}} ->
+ try inline(E, Ctxt, ren__identity(), Env, S1) of
+ {E1, S2} ->
%% Revert to the old size counter.
- {E1, revert_size(S, S2)};
- {counter_exceeded, size, S2} ->
+ {E1, revert_size(S, S2)}
+ catch
+ throw:{counter_exceeded, size, S2} ->
%% Aborted this inlining attempt because it got too big.
%% Residualize the variable and revert to the old size
%% counter. (It is important that we do not also revert the
@@ -1817,11 +1811,7 @@ copy_inline_2(R, E, Ctxt, Env, S) ->
%% must make sure to clear the flags of any nested
%% app-contexts upon aborting; see `inline' for details.
S4 = reset_nested_apps(Ctxt, S3), % for effect
- residualize_var(R, S4);
- {'EXIT', X} ->
- exit(X);
- X ->
- throw(X)
+ residualize_var(R, S4)
end.
reset_nested_apps(#app{ctxt = Ctxt, loc = L}, S) ->
diff --git a/lib/compiler/src/cerl_sets.erl b/lib/compiler/src/cerl_sets.erl
new file mode 100644
index 0000000000..0361186713
--- /dev/null
+++ b/lib/compiler/src/cerl_sets.erl
@@ -0,0 +1,207 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-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.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(cerl_sets).
+
+%% Standard interface.
+-export([new/0,is_set/1,size/1,to_list/1,from_list/1]).
+-export([is_element/2,add_element/2,del_element/2]).
+-export([union/2,union/1,intersection/2,intersection/1]).
+-export([is_disjoint/2]).
+-export([subtract/2,is_subset/2]).
+-export([fold/3,filter/2]).
+
+-export_type([set/0, set/1]).
+
+%%------------------------------------------------------------------------------
+
+-type set() :: set(_).
+-opaque set(Element) :: #{Element => 'ok'}.
+
+%%------------------------------------------------------------------------------
+
+%% new() -> Set
+-spec new() -> set().
+
+new() -> #{}.
+
+%% is_set(Set) -> boolean().
+%% Return 'true' if Set is a set of elements, else 'false'.
+-spec is_set(Set) -> boolean() when
+ Set :: term().
+
+is_set(S) when is_map(S) -> true;
+is_set(_) -> false.
+
+%% size(Set) -> int().
+%% Return the number of elements in Set.
+-spec size(Set) -> non_neg_integer() when
+ Set :: set().
+
+size(S) -> maps:size(S).
+
+%% to_list(Set) -> [Elem].
+%% Return the elements in Set as a list.
+-spec to_list(Set) -> List when
+ Set :: set(Element),
+ List :: [Element].
+
+to_list(S) -> maps:keys(S).
+
+%% from_list([Elem]) -> Set.
+%% Build a set from the elements in List.
+-spec from_list(List) -> Set when
+ List :: [Element],
+ Set :: set(Element).
+from_list(Ls) -> maps:from_list([{K,ok}||K<-Ls]).
+
+%% is_element(Element, Set) -> boolean().
+%% Return 'true' if Element is an element of Set, else 'false'.
+-spec is_element(Element, Set) -> boolean() when
+ Set :: set(Element).
+
+is_element(E,S) ->
+ case S of
+ #{E := _} -> true;
+ _ -> false
+ end.
+
+%% add_element(Element, Set) -> Set.
+%% Return Set with Element inserted in it.
+-spec add_element(Element, Set1) -> Set2 when
+ Set1 :: set(Element),
+ Set2 :: set(Element).
+
+add_element(E,S) -> S#{E=>ok}.
+
+-spec del_element(Element, Set1) -> Set2 when
+ Set1 :: set(Element),
+ Set2 :: set(Element).
+
+%% del_element(Element, Set) -> Set.
+%% Return Set but with Element removed.
+del_element(E,S) -> maps:remove(E,S).
+
+%% union(Set1, Set2) -> Set
+%% Return the union of Set1 and Set2.
+-spec union(Set1, Set2) -> Set3 when
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
+
+union(S1,S2) -> maps:merge(S1,S2).
+
+%% union([Set]) -> Set
+%% Return the union of the list of sets.
+-spec union(SetList) -> Set when
+ SetList :: [set(Element)],
+ Set :: set(Element).
+
+union([S1,S2|Ss]) ->
+ union1(union(S1, S2), Ss);
+union([S]) -> S;
+union([]) -> new().
+
+union1(S1, [S2|Ss]) ->
+ union1(union(S1, S2), Ss);
+union1(S1, []) -> S1.
+
+%% intersection(Set1, Set2) -> Set.
+%% Return the intersection of Set1 and Set2.
+-spec intersection(Set1, Set2) -> Set3 when
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
+
+intersection(S1, S2) ->
+ filter(fun (E) -> is_element(E, S1) end, S2).
+
+%% intersection([Set]) -> Set.
+%% Return the intersection of the list of sets.
+-spec intersection(SetList) -> Set when
+ SetList :: [set(Element),...],
+ Set :: set(Element).
+
+intersection([S1,S2|Ss]) ->
+ intersection1(intersection(S1, S2), Ss);
+intersection([S]) -> S.
+
+intersection1(S1, [S2|Ss]) ->
+ intersection1(intersection(S1, S2), Ss);
+intersection1(S1, []) -> S1.
+
+%% is_disjoint(Set1, Set2) -> boolean().
+%% Check whether Set1 and Set2 are disjoint.
+-spec is_disjoint(Set1, Set2) -> boolean() when
+ Set1 :: set(Element),
+ Set2 :: set(Element).
+
+is_disjoint(S1, S2) when map_size(S1) < map_size(S2) ->
+ fold(fun (_, false) -> false;
+ (E, true) -> not is_element(E, S2)
+ end, true, S1);
+is_disjoint(S1, S2) ->
+ fold(fun (_, false) -> false;
+ (E, true) -> not is_element(E, S1)
+ end, true, S2).
+
+%% subtract(Set1, Set2) -> Set.
+%% Return all and only the elements of Set1 which are not also in
+%% Set2.
+-spec subtract(Set1, Set2) -> Set3 when
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
+
+subtract(S1, S2) ->
+ filter(fun (E) -> not is_element(E, S2) end, S1).
+
+%% is_subset(Set1, Set2) -> boolean().
+%% Return 'true' when every element of Set1 is also a member of
+%% Set2, else 'false'.
+-spec is_subset(Set1, Set2) -> boolean() when
+ Set1 :: set(Element),
+ Set2 :: set(Element).
+
+is_subset(S1, S2) ->
+ fold(fun (E, Sub) -> Sub andalso is_element(E, S2) end, true, S1).
+
+%% fold(Fun, Accumulator, Set) -> Accumulator.
+%% Fold function Fun over all elements in Set and return Accumulator.
+-spec fold(Function, Acc0, Set) -> Acc1 when
+ Function :: fun((Element, AccIn) -> AccOut),
+ Set :: set(Element),
+ Acc0 :: Acc,
+ Acc1 :: Acc,
+ AccIn :: Acc,
+ AccOut :: Acc.
+
+fold(F, Init, D) ->
+ lists:foldl(fun(E,Acc) -> F(E,Acc) end,Init,maps:keys(D)).
+
+%% filter(Fun, Set) -> Set.
+%% Filter Set with Fun.
+-spec filter(Pred, Set1) -> Set2 when
+ Pred :: fun((Element) -> boolean()),
+ Set1 :: set(Element),
+ Set2 :: set(Element).
+
+filter(F, D) ->
+ maps:from_list(lists:filter(fun({K,_}) -> F(K) end, maps:to_list(D))).
diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl
index e53bdd4efb..58bb18e34a 100644
--- a/lib/compiler/src/cerl_trees.erl
+++ b/lib/compiler/src/cerl_trees.erl
@@ -3,23 +3,24 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% @doc Basic functions on Core Erlang abstract syntax trees.
%%
%% <p>Syntax trees are defined in the module <a
-%% href=""><code>cerl</code></a>.</p>
+%% href="cerl"><code>cerl</code></a>.</p>
%%
%% @type cerl() = cerl:cerl()
@@ -520,9 +521,9 @@ variables(T, S) ->
tuple ->
vars_in_list(tuple_es(T), S);
map ->
- vars_in_list(map_es(T), S);
+ vars_in_list([map_arg(T)|map_es(T)], S);
map_pair ->
- vars_in_list([map_pair_op(T),map_pair_key(T), map_pair_val(T)], S);
+ vars_in_list([map_pair_op(T),map_pair_key(T),map_pair_val(T)], S);
'let' ->
Vs = variables(let_body(T), S),
Vs1 = var_list_names(let_vars(T)),
@@ -730,8 +731,8 @@ label(T, N, Env) ->
{ann_c_map(As, M, Ts), N3};
map_pair ->
{Op, N1} = label(map_pair_op(T), N, Env),
- {Val, N2} = label(map_pair_key(T), N1, Env),
- {Key, N3} = label(map_pair_val(T), N2, Env),
+ {Key, N2} = label(map_pair_key(T), N1, Env),
+ {Val, N3} = label(map_pair_val(T), N2, Env),
{As, N4} = label_ann(T, N3),
{ann_c_map_pair(As,Op,Key,Val), N4};
'let' ->
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index c7d91070f6..e0a29fe9b1 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -41,7 +42,7 @@
-type option() :: atom() | {atom(), term()} | {'d', atom(), term()}.
--type err_info() :: {erl_scan:line() | 'none',
+-type err_info() :: {erl_anno:line() | 'none',
module(), term()}. %% ErrorDescriptor
-type errors() :: [{file:filename(), [err_info()]}].
-type warnings() :: [{file:filename(), [err_info()]}].
@@ -132,7 +133,8 @@ env_default_opts() ->
Str when is_list(Str) ->
case erl_scan:string(Str) of
{ok,Tokens,_} ->
- case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
+ Dot = {dot, erl_anno:new(1)},
+ case erl_parse:parse_term(Tokens ++ [Dot]) of
{ok,List} when is_list(List) -> List;
{ok,Term} -> [Term];
{error,_Reason} ->
@@ -285,11 +287,20 @@ internal_comp(Passes, File, Suffix, St0) ->
St1 = St0#compile{filename=File, dir=Dir, base=Base,
ifile=erlfile(Dir, Base, Suffix),
ofile=objfile(Base, St0)},
- Run = case member(time, St1#compile.options) of
- true ->
- io:format("Compiling ~tp\n", [File]),
- fun run_tc/2;
- false -> fun({_Name,Fun}, St) -> catch Fun(St) end
+ Opts = St1#compile.options,
+ Run0 = case member(time, Opts) of
+ true ->
+ io:format("Compiling ~tp\n", [File]),
+ fun run_tc/2;
+ false -> fun({_Name,Fun}, St) -> catch Fun(St) end
+ end,
+ Run = case keyfind(eprof, 1, Opts) of
+ {eprof,EprofPass} ->
+ fun(P, St) ->
+ run_eprof(P, EprofPass, St)
+ end;
+ false ->
+ Run0
end,
case fold_comp(Passes, Run, St1) of
{ok,St2} -> comp_ret_ok(St2);
@@ -320,17 +331,26 @@ fold_comp([{Name,Pass}|Ps], Run, St0) ->
fold_comp([], _Run, St) -> {ok,St}.
run_tc({Name,Fun}, St) ->
- Before0 = statistics(runtime),
+ T1 = erlang:monotonic_time(),
Val = (catch Fun(St)),
- After0 = statistics(runtime),
- {Before_c, _} = Before0,
- {After_c, _} = After0,
+ T2 = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(T2 - T1, native, milli_seconds),
Mem0 = erts_debug:flat_size(Val)*erlang:system_info(wordsize),
Mem = lists:flatten(io_lib:format("~.1f kB", [Mem0/1024])),
- io:format(" ~-30s: ~10.2f s ~12s\n",
- [Name,(After_c-Before_c) / 1000,Mem]),
+ io:format(" ~-30s: ~10.3f s ~12s\n",
+ [Name,Elapsed/1000,Mem]),
Val.
+run_eprof({Name,Fun}, Name, St) ->
+ io:format("~p: Running eprof\n", [Name]),
+ c:appcall(tools, eprof, start_profiling, [[self()]]),
+ Val = (catch Fun(St)),
+ c:appcall(tools, eprof, stop_profiling, []),
+ c:appcall(tools, eprof, analyze, []),
+ Val;
+run_eprof({_,Fun}, _, St) ->
+ catch Fun(St).
+
comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) ->
case werror(St) of
true ->
@@ -431,11 +451,6 @@ pass(from_core) ->
{".core",[?pass(parse_core)|core_passes()]};
pass(from_asm) ->
{".S",[?pass(beam_consult_asm)|asm_passes()]};
-pass(asm) ->
- %% TODO: remove 'asm' in 18.0
- io:format("compile:file/2 option 'asm' has been deprecated and will be~n"
- "removed in the 18.0 release. Use 'from_asm' instead.~n"),
- pass(from_asm);
pass(from_beam) ->
{".beam",[?pass(read_beam_file)|binary_passes()]};
pass(_) -> none.
@@ -611,7 +626,7 @@ standard_passes() ->
{iff,'to_exp',{done,"E"}},
%% Conversion to Core Erlang.
- ?pass(core_module),
+ {pass,v3_core},
{iff,'dcore',{listing,"core"}},
{iff,'to_core0',{done,"core"}}
| core_passes()].
@@ -623,7 +638,7 @@ core_passes() ->
[{unless,no_copt,
[{core_old_inliner,fun test_old_inliner/1,fun core_old_inliner/1},
{iff,doldinline,{listing,"oldinline"}},
- ?pass(core_fold_module),
+ {pass,sys_core_fold},
{iff,dcorefold,{listing,"corefold"}},
{core_inline_module,fun test_core_inliner/1,fun core_inline_module/1},
{iff,dinline,{listing,"inline"}},
@@ -636,14 +651,14 @@ core_passes() ->
kernel_passes() ->
%% Destructive setelement/3 optimization and core lint.
- [?pass(core_dsetel_module),
+ [{pass,sys_core_dsetel},
{iff,dsetel,{listing,"dsetel"}},
{iff,clint,?pass(core_lint_module)},
{iff,core,?pass(save_core_code)},
%% Kernel Erlang and code generation.
- ?pass(kernel_module),
+ {pass,v3_kernel},
{iff,dkern,{listing,"kernel"}},
{iff,'to_kernel',{done,"kernel"}},
{pass,v3_life},
@@ -906,28 +921,35 @@ transform_module(#compile{options=Opt,code=Code0}=St0) ->
foldl_transform(St, [T|Ts]) ->
Name = "transform " ++ atom_to_list(T),
- Fun = fun(S) -> T:parse_transform(S#compile.code, S#compile.options) end,
- Run = case member(time, St#compile.options) of
- true -> fun run_tc/2;
- false -> fun({_Name,F}, S) -> catch F(S) end
- end,
- case Run({Name, Fun}, St) of
- {error,Es,Ws} ->
- {error,St#compile{warnings=St#compile.warnings ++ Ws,
- errors=St#compile.errors ++ Es}};
- {'EXIT',{undef,_}} ->
- Es = [{St#compile.ifile,[{none,compile,
- {undef_parse_transform,T}}]}],
- {error,St#compile{errors=St#compile.errors ++ Es}};
- {'EXIT',R} ->
- Es = [{St#compile.ifile,[{none,compile,{parse_transform,T,R}}]}],
- {error,St#compile{errors=St#compile.errors ++ Es}};
- {warning, Forms, Ws} ->
- foldl_transform(
- St#compile{code=Forms,
- warnings=St#compile.warnings ++ Ws}, Ts);
- Forms ->
- foldl_transform(St#compile{code=Forms}, Ts)
+ case code:ensure_loaded(T) =:= {module,T} andalso
+ erlang:function_exported(T, parse_transform, 2) of
+ true ->
+ Fun = fun(S) ->
+ T:parse_transform(S#compile.code, S#compile.options)
+ end,
+ Run = case member(time, St#compile.options) of
+ true -> fun run_tc/2;
+ false -> fun({_Name,F}, S) -> catch F(S) end
+ end,
+ case Run({Name, Fun}, St) of
+ {error,Es,Ws} ->
+ {error,St#compile{warnings=St#compile.warnings ++ Ws,
+ errors=St#compile.errors ++ Es}};
+ {'EXIT',R} ->
+ Es = [{St#compile.ifile,[{none,compile,
+ {parse_transform,T,R}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}};
+ {warning, Forms, Ws} ->
+ foldl_transform(
+ St#compile{code=Forms,
+ warnings=St#compile.warnings ++ Ws}, Ts);
+ Forms ->
+ foldl_transform(St#compile{code=Forms}, Ts)
+ end;
+ false ->
+ Es = [{St#compile.ifile,[{none,compile,
+ {undef_parse_transform,T}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
end;
foldl_transform(St, []) -> {ok,St}.
@@ -1181,14 +1203,6 @@ expand_module(#compile{code=Code,options=Opts0}=St0) ->
Opts = expand_opts(Opts1),
{ok,St0#compile{module=Mod,options=Opts,code={Mod,Exp,Forms}}}.
-core_module(#compile{code=Code0,options=Opts}=St) ->
- {ok,Code,Ws} = v3_core:module(Code0, Opts),
- {ok,St#compile{code=Code,warnings=St#compile.warnings ++ Ws}}.
-
-core_fold_module(#compile{code=Code0,options=Opts,warnings=Warns}=St) ->
- {ok,Code,Ws} = sys_core_fold:module(Code0, Opts),
- {ok,St#compile{code=Code,warnings=Warns ++ Ws}}.
-
core_fold_module_after_inlining(#compile{code=Code0,options=Opts}=St) ->
%% Inlining may produce code that generates spurious warnings.
%% Ignore all warnings.
@@ -1224,14 +1238,6 @@ core_inline_module(#compile{code=Code0,options=Opts}=St) ->
Code = cerl_inline:core_transform(Code0, Opts),
{ok,St#compile{code=Code}}.
-core_dsetel_module(#compile{code=Code0,options=Opts}=St) ->
- {ok,Code} = sys_core_dsetel:module(Code0, Opts),
- {ok,St#compile{code=Code}}.
-
-kernel_module(#compile{code=Code0,options=Opts}=St) ->
- {ok,Code,Ws} = v3_kernel:module(Code0, Opts),
- {ok,St#compile{code=Code,warnings=St#compile.warnings ++ Ws}}.
-
save_abstract_code(#compile{ifile=File}=St) ->
case abstract_code(St) of
{ok,Code} ->
@@ -1240,7 +1246,8 @@ save_abstract_code(#compile{ifile=File}=St) ->
{error,St#compile{errors=St#compile.errors ++ [{File,Es}]}}
end.
-abstract_code(#compile{code=Code,options=Opts,ofile=OFile}) ->
+abstract_code(#compile{code=Code0,options=Opts,ofile=OFile}) ->
+ Code = erl_parse:anno_to_term(Code0),
Abstr = erlang:term_to_binary({raw_abstract_v1,Code}, [compressed]),
case member(encrypt_debug_info, Opts) of
true ->
@@ -1300,8 +1307,9 @@ encrypt({des3_cbc=Type,Key,IVec,BlockSize}, Bin0) ->
list_to_binary([0,length(TypeString),TypeString,Bin]).
random_bytes(N) ->
- {A,B,C} = now(),
- _ = random:seed(A, B, C),
+ _ = random:seed(erlang:time_offset(),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
random_bytes_1(N, []).
random_bytes_1(0, Acc) -> Acc;
diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src
index 8f68915f8e..afb85f4710 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -45,6 +46,7 @@
cerl,
cerl_clauses,
cerl_inline,
+ cerl_sets,
cerl_trees,
compile,
core_scan,
@@ -56,6 +58,7 @@
rec_env,
sys_core_dsetel,
sys_core_fold,
+ sys_core_fold_lists,
sys_core_inline,
sys_pre_attributes,
sys_pre_expand,
@@ -68,5 +71,5 @@
{registered, []},
{applications, [kernel, stdlib]},
{env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","hipe-3.10.3","erts-6.0",
- "crypto-3.3"]}]}.
+ {runtime_dependencies, ["stdlib-2.5","kernel-4.0","hipe-3.12","erts-7.0",
+ "crypto-3.6"]}]}.
diff --git a/lib/compiler/src/compiler.appup.src b/lib/compiler/src/compiler.appup.src
index fe273b269c..3ada2e933f 100644
--- a/lib/compiler/src/compiler.appup.src
+++ b/lib/compiler/src/compiler.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl
index 0d95971f91..3abb520485 100644
--- a/lib/compiler/src/core_lib.erl
+++ b/lib/compiler/src/core_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -20,6 +21,12 @@
-module(core_lib).
+-deprecated({get_anno,1,next_major_release}).
+-deprecated({set_anno,2,next_major_release}).
+-deprecated({is_literal,1,next_major_release}).
+-deprecated({is_literal_list,1,next_major_release}).
+-deprecated({literal_value,1,next_major_release}).
+
-export([get_anno/1,set_anno/2]).
-export([is_literal/1,is_literal_list/1]).
-export([literal_value/1]).
@@ -33,59 +40,27 @@
%%
-spec get_anno(cerl:cerl()) -> term().
-get_anno(C) -> element(2, C).
+get_anno(C) -> cerl:get_ann(C).
-spec set_anno(cerl:cerl(), term()) -> cerl:cerl().
-set_anno(C, A) -> setelement(2, C, A).
+set_anno(C, A) -> cerl:set_ann(C, A).
-spec is_literal(cerl:cerl()) -> boolean().
-is_literal(#c_literal{}) -> true;
-is_literal(#c_cons{hd=H,tl=T}) ->
- is_literal(H) andalso is_literal(T);
-is_literal(#c_tuple{es=Es}) -> is_literal_list(Es);
-is_literal(#c_binary{segments=Es}) -> is_lit_bin(Es);
-is_literal(_) -> false.
+is_literal(Cerl) ->
+ cerl:is_literal(cerl:fold_literal(Cerl)).
-spec is_literal_list([cerl:cerl()]) -> boolean().
is_literal_list(Es) -> lists:all(fun is_literal/1, Es).
-is_lit_bin(Es) ->
- lists:all(fun (#c_bitstr{val=E,size=S}) ->
- is_literal(E) andalso is_literal(S)
- end, Es).
-
%% Return the value of LitExpr.
-spec literal_value(cerl:c_literal() | cerl:c_binary() |
cerl:c_map() | cerl:c_cons() | cerl:c_tuple()) -> term().
-literal_value(#c_literal{val=V}) -> V;
-literal_value(#c_binary{segments=Es}) ->
- list_to_binary([literal_value_bin(Bit) || Bit <- Es]);
-literal_value(#c_cons{hd=H,tl=T}) ->
- [literal_value(H)|literal_value(T)];
-literal_value(#c_tuple{es=Es}) ->
- list_to_tuple(literal_value_list(Es));
-literal_value(#c_map{arg=Cm,es=Cmps}) ->
- M = literal_value(Cm),
- lists:foldl(fun(#c_map_pair{ key=Ck, val=Cv },Mi) ->
- K = literal_value(Ck),
- V = literal_value(Cv),
- maps:put(K,V,Mi)
- end, M, Cmps).
-
-literal_value_list(Vals) -> [literal_value(V) || V <- Vals].
-
-literal_value_bin(#c_bitstr{val=Val,size=Sz,unit=U,type=T,flags=Fs}) ->
- %% We will only handle literals constructed by make_literal/1.
- %% Could be made more general in the future if the need arises.
- 8 = literal_value(Sz),
- 1 = literal_value(U),
- integer = literal_value(T),
- [unsigned,big] = literal_value(Fs),
- literal_value(Val).
+literal_value(Cerl) ->
+ cerl:concrete(cerl:fold_literal(Cerl)).
%% Make a suitable values structure, expr or values, depending on Expr.
-spec make_values([cerl:cerl()] | cerl:cerl()) -> cerl:cerl().
@@ -236,10 +211,15 @@ vu_pat_seg_list(V, Ss, St) ->
end
end, St, Ss).
-vu_map_pairs(V, [#c_map_pair{val=Pat}|T], St0) ->
- case vu_pattern(V, Pat, St0) of
- {true,_}=St -> St;
- St -> vu_map_pairs(V, T, St)
+vu_map_pairs(V, [#c_map_pair{key=Key,val=Pat}|T], St0) ->
+ case vu_expr(V, Key) of
+ true ->
+ {true,false};
+ false ->
+ case vu_pattern(V, Pat, St0) of
+ {true,_}=St -> St;
+ St -> vu_map_pairs(V, T, St)
+ end
end;
vu_map_pairs(_, [], St) -> St.
diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl
index 25df33a287..cc54f6e411 100644
--- a/lib/compiler/src/core_lint.erl
+++ b/lib/compiler/src/core_lint.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -33,9 +34,6 @@
%% Values only as multiple values/variables/patterns.
%% Return same number of values as requested
%% Correct number of arguments
-%%
-%% Checks to add:
-%%
%% Consistency of values/variables
%% Consistency of function return values/calls.
%%
@@ -176,7 +174,7 @@ check_exports(Es, St) ->
end.
check_attrs(As, St) ->
- case all(fun ({#c_literal{},V}) -> core_lib:is_literal(V);
+ case all(fun ({#c_literal{},#c_literal{}}) -> true;
(_) -> false
end, As) of
true -> St;
@@ -211,7 +209,7 @@ functions(Fs, Def, St0) ->
function({#c_var{name={_,_}},B}, Def, St) ->
%% Body must be a fun!
case B of
- #c_fun{} -> expr(B, Def, any, St);
+ #c_fun{} -> expr(B, Def, 1, St);
_ -> add_error({illegal_expr,St#lint.func}, St)
end.
@@ -247,40 +245,42 @@ gbody(E, Def, Rt, St0) ->
false -> St1
end.
-gexpr(#c_var{name=N}, Def, _Rt, St) when is_atom(N); is_integer(N) ->
- expr_var(N, Def, St);
-gexpr(#c_literal{}, _Def, _Rt, St) -> St;
-gexpr(#c_cons{hd=H,tl=T}, Def, _Rt, St) ->
- gexpr_list([H,T], Def, St);
-gexpr(#c_tuple{es=Es}, Def, _Rt, St) ->
- gexpr_list(Es, Def, St);
-gexpr(#c_map{es=Es}, Def, _Rt, St) ->
- gexpr_list(Es, Def, St);
-gexpr(#c_map_pair{key=K,val=V}, Def, _Rt, St) ->
- gexpr_list([K,V], Def, St);
-gexpr(#c_binary{segments=Ss}, Def, _Rt, St) ->
- gbitstr_list(Ss, Def, St);
+gexpr(#c_var{name=N}, Def, Rt, St) when is_atom(N); is_integer(N) ->
+ return_match(Rt, 1, expr_var(N, Def, St));
+gexpr(#c_literal{}, _Def, Rt, St) ->
+ return_match(Rt, 1, St);
+gexpr(#c_cons{hd=H,tl=T}, Def, Rt, St) ->
+ return_match(Rt, 1, gexpr_list([H,T], Def, St));
+gexpr(#c_tuple{es=Es}, Def, Rt, St) ->
+ return_match(Rt, 1, gexpr_list(Es, Def, St));
+gexpr(#c_map{es=Es}, Def, Rt, St) ->
+ return_match(Rt, 1, gexpr_list(Es, Def, St));
+gexpr(#c_map_pair{key=K,val=V}, Def, Rt, St) ->
+ return_match(Rt, 1, gexpr_list([K,V], Def, St));
+gexpr(#c_binary{segments=Ss}, Def, Rt, St) ->
+ return_match(Rt, 1, gbitstr_list(Ss, Def, St));
gexpr(#c_seq{arg=Arg,body=B}, Def, Rt, St0) ->
- St1 = gexpr(Arg, Def, any, St0), %Ignore values
- gbody(B, Def, Rt, St1);
+ St1 = gexpr(Arg, Def, 1, St0),
+ return_match(Rt, 1, gbody(B, Def, Rt, St1));
gexpr(#c_let{vars=Vs,arg=Arg,body=B}, Def, Rt, St0) ->
St1 = gbody(Arg, Def, let_varcount(Vs), St0), %This is a guard body
{Lvs,St2} = variable_list(Vs, St1),
gbody(B, union(Lvs, Def), Rt, St2);
gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=is_record},
args=[Arg,#c_literal{val=Tag},#c_literal{val=Size}]},
- Def, 1, St) when is_atom(Tag), is_integer(Size) ->
- gexpr(Arg, Def, 1, St);
+ Def, Rt, St) when is_atom(Tag), is_integer(Size) ->
+ return_match(Rt, 1, gexpr(Arg, Def, 1, St));
gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=is_record}},
- _Def, 1, St) ->
- add_error({illegal_guard,St#lint.func}, St);
+ _Def, Rt, St) ->
+ return_match(Rt, 1, add_error({illegal_guard,St#lint.func}, St));
gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=Name},args=As},
- Def, 1, St) when is_atom(Name) ->
+ Def, Rt, St0) when is_atom(Name) ->
+ St1 = return_match(Rt, 1, St0),
case is_guard_bif(Name, length(As)) of
true ->
- gexpr_list(As, Def, St);
+ gexpr_list(As, Def, St1);
false ->
- add_error({illegal_guard,St#lint.func}, St)
+ add_error({illegal_guard,St1#lint.func}, St1)
end;
gexpr(#c_primop{name=#c_literal{val=A},args=As}, Def, _Rt, St0) when is_atom(A) ->
gexpr_list(As, Def, St0);
@@ -319,23 +319,25 @@ is_guard_bif(Name, Arity) ->
%% expr(Expr, Defined, RetCount, State) -> State.
-expr(#c_var{name={_,_}=FA}, Def, _Rt, St) ->
- expr_fname(FA, Def, St);
-expr(#c_var{name=N}, Def, _Rt, St) -> expr_var(N, Def, St);
-expr(#c_literal{}, _Def, _Rt, St) -> St;
-expr(#c_cons{hd=H,tl=T}, Def, _Rt, St) ->
- expr_list([H,T], Def, St);
-expr(#c_tuple{es=Es}, Def, _Rt, St) ->
- expr_list(Es, Def, St);
-expr(#c_map{es=Es}, Def, _Rt, St) ->
- expr_list(Es, Def, St);
-expr(#c_map_pair{key=K,val=V},Def,_Rt,St) ->
- expr_list([K,V],Def,St);
-expr(#c_binary{segments=Ss}, Def, _Rt, St) ->
- bitstr_list(Ss, Def, St);
+expr(#c_var{name={_,_}=FA}, Def, Rt, St) ->
+ return_match(Rt, 1, expr_fname(FA, Def, St));
+expr(#c_var{name=N}, Def, Rt, St) ->
+ return_match(Rt, 1, expr_var(N, Def, St));
+expr(#c_literal{}, _Def, Rt, St) ->
+ return_match(Rt, 1, St);
+expr(#c_cons{hd=H,tl=T}, Def, Rt, St) ->
+ return_match(Rt, 1, expr_list([H,T], Def, St));
+expr(#c_tuple{es=Es}, Def, Rt, St) ->
+ return_match(Rt, 1, expr_list(Es, Def, St));
+expr(#c_map{es=Es}, Def, Rt, St) ->
+ return_match(Rt, 1, expr_list(Es, Def, St));
+expr(#c_map_pair{key=K,val=V}, Def, Rt, St) ->
+ return_match(Rt, 1, expr_list([K,V], Def, St));
+expr(#c_binary{segments=Ss}, Def, Rt, St) ->
+ return_match(Rt, 1, bitstr_list(Ss, Def, St));
expr(#c_fun{vars=Vs,body=B}, Def, Rt, St0) ->
{Vvs,St1} = variable_list(Vs, St0),
- return_match(Rt, 1, body(B, union(Vvs, Def), any, St1));
+ return_match(Rt, 1, body(B, union(Vvs, Def), 1, St1));
expr(#c_seq{arg=Arg,body=B}, Def, Rt, St0) ->
St1 = expr(Arg, Def, 1, St0),
body(B, Def, Rt, St1);
@@ -361,15 +363,26 @@ expr(#c_receive{clauses=Cs,timeout=T,action=A}, Def, Rt, St0) ->
St1 = expr(T, Def, 1, St0),
St2 = body(A, Def, Rt, St1),
clauses(Cs, Def, 1, Rt, St2);
-expr(#c_apply{op=Op,args=As}, Def, _Rt, St0) ->
+expr(#c_apply{op=Op,args=As}, Def, Rt, St0) ->
St1 = apply_op(Op, Def, length(As), St0),
- expr_list(As, Def, St1);
+ return_match(Rt, 1, expr_list(As, Def, St1));
+expr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=Name},args=As},
+ Def, Rt, St0) when is_atom(Name) ->
+ St1 = expr_list(As, Def, St0),
+ case erl_bifs:is_exit_bif(erlang, Name, length(As)) of
+ true -> St1;
+ false -> return_match(Rt, 1, St1)
+ end;
expr(#c_call{module=M,name=N,args=As}, Def, _Rt, St0) ->
St1 = expr(M, Def, 1, St0),
St2 = expr(N, Def, 1, St1),
expr_list(As, Def, St2);
-expr(#c_primop{name=#c_literal{val=A},args=As}, Def, _Rt, St0) when is_atom(A) ->
- expr_list(As, Def, St0);
+expr(#c_primop{name=#c_literal{val=A},args=As}, Def, Rt, St0) when is_atom(A) ->
+ St1 = expr_list(As, Def, St0),
+ case A of
+ match_fail -> St1;
+ _ -> return_match(Rt, 1, St1)
+ end;
expr(#c_catch{body=B}, Def, Rt, St) ->
return_match(Rt, 1, body(B, Def, 1, St));
expr(#c_try{arg=A,vars=Vs,body=B,evars=Evs,handler=H}, Def, Rt, St0) ->
diff --git a/lib/compiler/src/core_parse.hrl b/lib/compiler/src/core_parse.hrl
index 4a00535360..ecf6cc9956 100644
--- a/lib/compiler/src/core_parse.hrl
+++ b/lib/compiler/src/core_parse.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -72,7 +73,8 @@
-record(c_map, {anno=[],
arg=#c_literal{val=#{}} :: cerl:c_var() | cerl:c_literal(),
- es :: [cerl:c_map_pair()]}).
+ es :: [cerl:c_map_pair()],
+ is_pat=false :: boolean()}).
-record(c_map_pair, {anno=[],
op :: #c_literal{val::'assoc'} | #c_literal{val::'exact'},
diff --git a/lib/compiler/src/core_parse.yrl b/lib/compiler/src/core_parse.yrl
index a66ad4235f..59cfc97ebd 100644
--- a/lib/compiler/src/core_parse.yrl
+++ b/lib/compiler/src/core_parse.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -58,7 +59,8 @@ Terminals
%% Separators
-'(' ')' '{' '}' '[' ']' '|' ',' '->' '=' '/' '<' '>' ':' '-|' '#' '~' '::'
+'(' ')' '{' '}' '[' ']' '|' ',' '->' '=' '/' '<' '>' ':' '-|' '#'
+'~' '=>' ':='
%% Keywords (atoms are assumed to always be single-quoted).
@@ -123,7 +125,7 @@ function_definition ->
{'$1','$3'}.
anno_fun -> '(' fun_expr '-|' annotation ')' :
- core_lib:set_anno('$2', '$4').
+ cerl:set_ann('$2', '$4').
anno_fun -> fun_expr : '$1'.
%% Constant terms for annotations and attributes.
@@ -162,7 +164,7 @@ tail_constant -> ',' constant tail_constant : ['$2'|'$3'].
%% ( ( V -| <anno> ) = ( {a} -| <anno> ) -| <anno> )
anno_pattern -> '(' other_pattern '-|' annotation ')' :
- core_lib:set_anno('$2', '$4').
+ cerl:set_ann('$2', '$4').
anno_pattern -> other_pattern : '$1'.
anno_pattern -> anno_variable : '$1'.
@@ -182,23 +184,24 @@ atomic_pattern -> atomic_literal : '$1'.
tuple_pattern -> '{' '}' : c_tuple([]).
tuple_pattern -> '{' anno_patterns '}' : c_tuple('$2').
-map_pattern -> '~' '{' '}' '~' : #c_map{es=[]}.
+map_pattern -> '~' '{' '}' '~' : c_map_pattern([]).
map_pattern -> '~' '{' map_pair_patterns '}' '~' :
- #c_map{es=lists:sort('$3')}.
+ c_map_pattern(lists:sort('$3')).
map_pair_patterns -> map_pair_pattern : ['$1'].
map_pair_patterns -> map_pair_pattern ',' map_pair_patterns : ['$1' | '$3'].
-map_pair_pattern -> '~' '<' anno_pattern ',' anno_pattern '>' :
- #c_map_pair{op=#c_literal{val=exact},key='$3',val='$5'}.
+map_pair_pattern -> anno_expression ':=' anno_pattern :
+ #c_map_pair{op=#c_literal{val=exact},
+ key='$1',val='$3'}.
cons_pattern -> '[' anno_pattern tail_pattern :
- #c_cons{hd='$2',tl='$3'}.
+ c_cons('$2', '$3').
tail_pattern -> ']' : #c_literal{val=[]}.
tail_pattern -> '|' anno_pattern ']' : '$2'.
tail_pattern -> ',' anno_pattern tail_pattern :
- #c_cons{hd='$2',tl='$3'}.
+ c_cons('$2', '$3').
binary_pattern -> '#' '{' '}' '#' : #c_binary{segments=[]}.
binary_pattern -> '#' '{' segment_patterns '}' '#' : #c_binary{segments='$3'}.
@@ -206,7 +209,7 @@ binary_pattern -> '#' '{' segment_patterns '}' '#' : #c_binary{segments='$3'}.
segment_patterns -> segment_pattern ',' segment_patterns : ['$1' | '$3'].
segment_patterns -> segment_pattern : ['$1'].
-segment_pattern -> '#' '<' anno_pattern '>' '(' anno_patterns ')':
+segment_pattern -> '#' '<' anno_pattern '>' '(' anno_expressions ')':
case '$6' of
[S,U,T,Fs] ->
#c_bitstr{val='$3',size=S,unit=U,type=T,flags=Fs};
@@ -222,7 +225,7 @@ anno_variables -> anno_variable : ['$1'].
anno_variable -> variable : '$1'.
anno_variable -> '(' variable '-|' annotation ')' :
- core_lib:set_anno('$2', '$4').
+ cerl:set_ann('$2', '$4').
%% Expressions
%% Must split expressions into two levels as nested value expressions
@@ -230,7 +233,7 @@ anno_variable -> '(' variable '-|' annotation ')' :
anno_expression -> expression : '$1'.
anno_expression -> '(' expression '-|' annotation ')' :
- core_lib:set_anno('$2', '$4').
+ cerl:set_ann('$2', '$4').
anno_expressions -> anno_expression ',' anno_expressions : ['$1' | '$3'].
anno_expressions -> anno_expression : ['$1'].
@@ -279,15 +282,15 @@ cons_literal -> '[' literal tail_literal : c_cons('$2', '$3').
tail_literal -> ']' : #c_literal{val=[]}.
tail_literal -> '|' literal ']' : '$2'.
-tail_literal -> ',' literal tail_literal : #c_cons{hd='$2',tl='$3'}.
+tail_literal -> ',' literal tail_literal : c_cons('$2', '$3').
tuple -> '{' '}' : c_tuple([]).
tuple -> '{' anno_expressions '}' : c_tuple('$2').
-map_expr -> '~' '{' '}' '~' : #c_map{es=[]}.
-map_expr -> '~' '{' map_pairs '}' '~' : #c_map{es='$3'}.
-map_expr -> '~' '{' map_pairs '|' variable '}' '~' : #c_map{arg='$5',es='$3'}.
-map_expr -> '~' '{' map_pairs '|' map_expr '}' '~' : #c_map{arg='$5',es='$3'}.
+map_expr -> '~' '{' '}' '~' : c_map([]).
+map_expr -> '~' '{' map_pairs '}' '~' : c_map('$3').
+map_expr -> '~' '{' map_pairs '|' variable '}' '~' : ann_c_map([], '$5', '$3').
+map_expr -> '~' '{' map_pairs '|' map_expr '}' '~' : ann_c_map([], '$5', '$3').
map_pairs -> map_pair : ['$1'].
map_pairs -> map_pair ',' map_pairs : ['$1' | '$3'].
@@ -295,10 +298,10 @@ map_pairs -> map_pair ',' map_pairs : ['$1' | '$3'].
map_pair -> map_pair_assoc : '$1'.
map_pair -> map_pair_exact : '$1'.
-map_pair_assoc -> '::' '<' anno_expression ',' anno_expression'>' :
- #c_map_pair{op=#c_literal{val=assoc},key='$3',val='$5'}.
-map_pair_exact -> '~' '<' anno_expression ',' anno_expression'>' :
- #c_map_pair{op=#c_literal{val=exact},key='$3',val='$5'}.
+map_pair_assoc -> anno_expression '=>' anno_expression :
+ #c_map_pair{op=#c_literal{val=assoc},key='$1',val='$3'}.
+map_pair_exact -> anno_expression ':=' anno_expression :
+ #c_map_pair{op=#c_literal{val=exact},key='$1',val='$3'}.
cons -> '[' anno_expression tail : c_cons('$2', '$3').
@@ -307,7 +310,7 @@ tail -> '|' anno_expression ']' : '$2'.
tail -> ',' anno_expression tail : c_cons('$2', '$3').
binary -> '#' '{' '}' '#' : #c_literal{val = <<>>}.
-binary -> '#' '{' segments '}' '#' : #c_binary{segments='$3'}.
+binary -> '#' '{' segments '}' '#' : make_binary('$3').
segments -> segment ',' segments : ['$1' | '$3'].
segments -> segment : ['$1'].
@@ -326,7 +329,7 @@ function_name -> atom '/' integer :
anno_function_name -> function_name : '$1'.
anno_function_name -> '(' function_name '-|' annotation ')' :
- core_lib:set_anno('$2', '$4').
+ cerl:set_ann('$2', '$4').
let_vars -> anno_variable : ['$1'].
let_vars -> '<' '>' : [].
@@ -354,7 +357,7 @@ anno_clauses -> anno_clause : ['$1'].
anno_clause -> clause : '$1'.
anno_clause -> '(' clause '-|' annotation ')' :
- core_lib:set_anno('$2', '$4').
+ cerl:set_ann('$2', '$4').
clause -> clause_pattern 'when' anno_expression '->' anno_expression :
#c_clause{pats='$1',guard='$3',body='$5'}.
@@ -410,9 +413,55 @@ Erlang code.
-include("core_parse.hrl").
--import(cerl, [c_cons/2,c_tuple/1]).
+-import(cerl, [ann_c_map/3,c_cons/2,c_map/1,c_map_pattern/1,c_tuple/1]).
tok_val(T) -> element(3, T).
tok_line(T) -> element(2, T).
+%% make_binary([#c_bitstr{}]) -> #c_binary{} | #c_literal{}
+%% Create either #c_binary{} or #c_literal{} from the binary segments.
+%% In certain contexts, such as keys for maps, only literals and
+%% variables are allowed, so we must not create a #c_binary{}
+%% record in those situation.
+%%
+%% To keep this function simple, we use a crude heuristic. We will
+%% assume that Core Erlang has been produced by core_pp. If the
+%% segments *could* have been output from a literal binary by
+%% core_pp, we will create a #c_literal{}. Otherwise we will create a
+%% #c_binary{} record.
+
+make_binary(Segs) ->
+ try make_lit_bin(<<>>, Segs) of
+ Bs when is_bitstring(Bs) ->
+ #c_literal{val=Bs}
+ catch
+ throw:impossible ->
+ #c_binary{segments=Segs}
+ end.
+
+make_lit_bin(Acc, [#c_bitstr{val=I0,size=Sz0,unit=U0,type=Type0,flags=F0}|T]) ->
+ I = get_lit_val(I0),
+ Sz = get_lit_val(Sz0),
+ U = get_lit_val(U0),
+ Type = get_lit_val(Type0),
+ F = get_lit_val(F0),
+ if
+ is_integer(I), U =:= 1, Type =:= integer, F =:= [unsigned,big] ->
+ ok;
+ true ->
+ throw(impossible)
+ end,
+ if
+ Sz =< 8, T =:= [] ->
+ <<Acc/binary,I:Sz>>;
+ Sz =:= 8 ->
+ make_lit_bin(<<Acc/binary,I:8>>, T);
+ true ->
+ throw(impossible)
+ end;
+make_lit_bin(Acc, []) -> Acc.
+
+get_lit_val(#c_literal{val=Val}) -> Val;
+get_lit_val(_) -> throw(impossible).
+
%% vim: syntax=erlang
diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl
index 83412ecdd7..c2a6a81d5e 100644
--- a/lib/compiler/src/core_pp.erl
+++ b/lib/compiler/src/core_pp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -45,7 +46,7 @@ format(Node) ->
format(Node, #ctxt{}).
maybe_anno(Node, Fun, Ctxt) ->
- As = core_lib:get_anno(Node),
+ As = cerl:get_ann(Node),
case get_line(As) of
none ->
maybe_anno(Node, Fun, Ctxt, As);
@@ -125,8 +126,8 @@ format_1(#c_literal{anno=A,val=M},Ctxt) when is_map(M) ->
_ -> assoc
end,
Cpairs = [#c_map_pair{op=#c_literal{val=Op},
- key=#c_literal{val=V},
- val=#c_literal{val=K}} || {K,V} <- Pairs],
+ key=#c_literal{val=K},
+ val=#c_literal{val=V}} || {K,V} <- Pairs],
format_1(#c_map{anno=A,arg=#c_literal{val=#{}},es=Cpairs},Ctxt);
format_1(#c_var{name={I,A}}, _) ->
[core_atom(I),$/,integer_to_list(A)];
@@ -183,15 +184,9 @@ format_1(#c_map{arg=Var,es=Es}, Ctxt) ->
"}~"
];
format_1(#c_map_pair{op=#c_literal{val=assoc},key=K,val=V}, Ctxt) ->
- ["::<",
- format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2),
- ">"
- ];
+ format_map_pair("=>", K, V, Ctxt);
format_1(#c_map_pair{op=#c_literal{val=exact},key=K,val=V}, Ctxt) ->
- ["~<",
- format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2),
- ">"
- ];
+ format_map_pair(":=", K, V, Ctxt);
format_1(#c_cons{hd=H,tl=T}, Ctxt) ->
Txt = ["["|format(H, add_indent(Ctxt, 1))],
[Txt|format_list_tail(T, add_indent(Ctxt, width(Txt, Ctxt)))];
@@ -201,7 +196,7 @@ format_1(#c_alias{var=V,pat=P}, Ctxt) ->
Txt = [format(V, Ctxt)|" = "],
[Txt|format(P, add_indent(Ctxt, width(Txt, Ctxt)))];
format_1(#c_let{vars=Vs0,arg=A,body=B}, Ctxt) ->
- Vs = [core_lib:set_anno(V, []) || V <- Vs0],
+ Vs = [cerl:set_ann(V, []) || V <- Vs0],
case is_simple_term(A) of
false ->
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
@@ -219,7 +214,7 @@ format_1(#c_let{vars=Vs0,arg=A,body=B}, Ctxt) ->
["let ",
format_values(Vs, add_indent(Ctxt, 4)),
" = ",
- format(core_lib:set_anno(A, []), Ctxt1),
+ format(cerl:set_ann(A, []), Ctxt1),
nl_indent(Ctxt),
"in "
| format(B, add_indent(Ctxt, 4))
@@ -448,6 +443,12 @@ format_list_tail(#c_cons{anno=[],hd=H,tl=T}, Ctxt) ->
format_list_tail(Tail, Ctxt) ->
["|",format(Tail, add_indent(Ctxt, 1)),"]"].
+format_map_pair(Op, K, V, Ctxt0) ->
+ Ctxt1 = add_indent(Ctxt0, 1),
+ Txt = format(K, set_class(Ctxt1, expr)),
+ Ctxt2 = add_indent(Ctxt0, width(Txt, Ctxt1)),
+ [Txt,Op,format(V, Ctxt2)].
+
indent(Ctxt) -> indent(Ctxt#ctxt.indent, Ctxt).
indent(N, _) when N =< 0 -> "";
diff --git a/lib/compiler/src/core_scan.erl b/lib/compiler/src/core_scan.erl
index b7799b373a..5e85bba2bd 100644
--- a/lib/compiler/src/core_scan.erl
+++ b/lib/compiler/src/core_scan.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -271,8 +272,10 @@ scan1("->" ++ Cs, Toks, Pos) ->
scan1(Cs, [{'->',Pos}|Toks], Pos);
scan1("-|" ++ Cs, Toks, Pos) ->
scan1(Cs, [{'-|',Pos}|Toks], Pos);
-scan1("::" ++ Cs, Toks, Pos) ->
- scan1(Cs, [{'::',Pos}|Toks], Pos);
+scan1(":=" ++ Cs, Toks, Pos) ->
+ scan1(Cs, [{':=',Pos}|Toks], Pos);
+scan1("=>" ++ Cs, Toks, Pos) ->
+ scan1(Cs, [{'=>',Pos}|Toks], Pos);
scan1([C|Cs], Toks, Pos) -> %Punctuation character
P = list_to_atom([C]),
scan1(Cs, [{P,Pos}|Toks], Pos);
diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl
index 6c75538194..c00f5eab70 100644
--- a/lib/compiler/src/erl_bifs.erl
+++ b/lib/compiler/src/erl_bifs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -134,6 +135,7 @@ is_pure(math, erf, 1) -> true;
is_pure(math, erfc, 1) -> true;
is_pure(math, exp, 1) -> true;
is_pure(math, log, 1) -> true;
+is_pure(math, log2, 1) -> true;
is_pure(math, log10, 1) -> true;
is_pure(math, pow, 2) -> true;
is_pure(math, sin, 1) -> true;
diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab
index 7d6bf56ccb..3a877f2403 100755
--- a/lib/compiler/src/genop.tab
+++ b/lib/compiler/src/genop.tab
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -44,7 +45,7 @@ BEAM_FORMAT_NUMBER=0
## Save the next instruction as the return address in the CP register.
4: call/2
-## @spec call_last Arity Label Dellocate
+## @spec call_last Arity Label Deallocate
## @doc Deallocate and do a tail recursive call to the function at Label.
## Do not update the CP register.
## Before the call deallocate Deallocate words of stack.
@@ -136,7 +137,7 @@ BEAM_FORMAT_NUMBER=0
# Sending & receiving.
#
## @spec send
-## @doc Send argument in x(0) as a message to the destination process in x(0).
+## @doc Send argument in x(1) as a message to the destination process in x(0).
## The message in x(1) ends up as the result of the send in x(0).
20: send/0
@@ -163,12 +164,12 @@ BEAM_FORMAT_NUMBER=0
25: wait/1
## @spec wait_timeout Lable Time
-## @doc Sets up a timeout of Time milllisecons and saves the address of the
+## @doc Sets up a timeout of Time milliseconds and saves the address of the
## following instruction as the entry point if the timeout triggers.
26: wait_timeout/2
#
-# Arithmethic opcodes.
+# Arithmetic opcodes.
#
27: -m_plus/4
28: -m_minus/4
@@ -315,7 +316,7 @@ BEAM_FORMAT_NUMBER=0
66: get_tuple_element/3
## @spec set_tuple_element NewElement Tuple Position
-## @doc Update the element at postition Position of the tuple Tuple
+## @doc Update the element at position Position of the tuple Tuple
## with the new element NewElement.
67: set_tuple_element/3
diff --git a/lib/compiler/src/rec_env.erl b/lib/compiler/src/rec_env.erl
index 555a331bd7..0e9e12d1ad 100644
--- a/lib/compiler/src/rec_env.erl
+++ b/lib/compiler/src/rec_env.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/src/sys_core_dsetel.erl b/lib/compiler/src/sys_core_dsetel.erl
index 60d83763f8..ac32db10fe 100644
--- a/lib/compiler/src/sys_core_dsetel.erl
+++ b/lib/compiler/src/sys_core_dsetel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index ed8f609082..65699ccda9 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -70,7 +71,8 @@
-export([module/2,format_error/1]).
-import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,all/2,any/2,
- reverse/1,reverse/2,member/2,nth/2,flatten/1,unzip/1]).
+ reverse/1,reverse/2,member/2,nth/2,flatten/1,
+ unzip/1,keyfind/3]).
-import(cerl, [ann_c_cons/3,ann_c_map/3,ann_c_tuple/2]).
@@ -91,10 +93,14 @@
-endif.
%% Variable value info.
--record(sub, {v=[], %Variable substitutions
- s=[], %Variables in scope
- t=[], %Types
- in_guard=false}). %In guard or not.
+-record(sub, {v=[], %Variable substitutions
+ s=cerl_sets:new() :: cerl_sets:set(), %Variables in scope
+ t=#{} :: map(), %Types
+ in_guard=false}). %In guard or not.
+
+-type type_info() :: cerl:cerl() | 'bool' | 'integer'.
+-type yes_no_maybe() :: 'yes' | 'no' | 'maybe'.
+-type sub() :: #sub{}.
-spec module(cerl:c_module(), [compile:option()]) ->
{'ok', cerl:c_module(), [_]}.
@@ -293,7 +299,8 @@ expr(#c_seq{arg=Arg0,body=B0}=Seq0, Ctxt, Sub) ->
false -> Seq0#c_seq{arg=Arg,body=B1}
end
end;
-expr(#c_let{}=Let, Ctxt, Sub) ->
+expr(#c_let{}=Let0, Ctxt, Sub) ->
+ Let = opt_case_in_let(Let0),
case simplify_let(Let, Sub) of
impossible ->
%% The argument for the let is "simple", i.e. has no
@@ -313,7 +320,7 @@ expr(#c_letrec{defs=Fs0,body=B0}=Letrec, Ctxt, Sub) ->
Fs1 = map(fun ({Name,Fb}) ->
{Name,expr(Fb, {letrec,Ctxt}, Sub)}
end, Fs0),
- B1 = body(B0, value, Sub),
+ B1 = body(B0, Ctxt, Sub),
Letrec#c_letrec{defs=Fs1,body=B1};
expr(#c_case{}=Case0, Ctxt, Sub) ->
%% Ideally, the compiler should only emit warnings when there is
@@ -462,10 +469,7 @@ is_safe_simple(#c_call{module=#c_literal{val=erlang},
case erl_internal:bool_op(Name, NumArgs) of
true ->
%% Boolean operators are safe if the arguments are boolean.
- all(fun(#c_var{name=V}) -> is_boolean_type(V, Sub);
- (#c_literal{val=Lit}) -> is_boolean(Lit);
- (_) -> false
- end, Args);
+ all(fun(C) -> is_boolean_type(C, Sub) =:= yes end, Args);
false ->
%% We need a rather complicated test to ensure that
%% we only allow safe calls that are allowed in a guard.
@@ -607,14 +611,6 @@ eval_binary_1([#c_bitstr{val=#c_literal{val=Val},size=#c_literal{val=Sz},
error:_ ->
throw(impossible)
end;
-eval_binary_1([#c_bitstr{val=#c_literal{},size=#c_literal{},
- unit=#c_literal{},type=#c_literal{},
- flags=#c_cons{}=Flags}=Bitstr|Ss], Acc0) ->
- case cerl:fold_literal(Flags) of
- #c_literal{} = Flags1 ->
- eval_binary_1([Bitstr#c_bitstr{flags=Flags1}|Ss], Acc0);
- _ -> throw(impossible)
- end;
eval_binary_1([], Acc) -> Acc;
eval_binary_1(_, _) -> throw(impossible).
@@ -688,23 +684,15 @@ count_bits_1(Int, Bits) -> count_bits_1(Int bsr 64, Bits+64).
%% a rewritten expression consisting of a sequence of
%% the arguments only is returned.
-useless_call(effect, #c_call{anno=Anno,
- module=#c_literal{val=Mod},
+useless_call(effect, #c_call{module=#c_literal{val=Mod},
name=#c_literal{val=Name},
args=Args}=Call) ->
A = length(Args),
case erl_bifs:is_safe(Mod, Name, A) of
false ->
case erl_bifs:is_pure(Mod, Name, A) of
- true ->
- case member(result_not_wanted, Anno) of
- false ->
- add_warning(Call, result_ignored);
- true ->
- ok
- end;
- false ->
- ok
+ true -> add_warning(Call, result_ignored);
+ false -> ok
end,
no;
true ->
@@ -730,385 +718,23 @@ make_effect_seq([], _) -> void().
call(#c_call{args=As}=Call, #c_literal{val=M}=M0, #c_literal{val=N}=N0, Sub) ->
case get(no_inline_list_funcs) of
true ->
- call_0(Call, M0, N0, As, Sub);
+ call_1(Call, M0, N0, As, Sub);
false ->
- call_1(Call, M, N, As, Sub)
+ case sys_core_fold_lists:call(Call, M, N, As) of
+ none ->
+ call_1(Call, M, N, As, Sub);
+ Core ->
+ expr(Core, Sub)
+ end
+
end;
call(#c_call{args=As}=Call, M, N, Sub) ->
- call_0(Call, M, N, As, Sub).
+ call_1(Call, M, N, As, Sub).
-call_0(Call, M, N, As0, Sub) ->
+call_1(Call, M, N, As0, Sub) ->
As1 = expr_list(As0, value, Sub),
fold_call(Call#c_call{args=As1}, M, N, As1, Sub).
-%% We inline some very common higher order list operations.
-%% We use the same evaluation order as the library function.
-
-call_1(#c_call{anno=Anno}, lists, all, [Arg1,Arg2], Sub) ->
- Loop = #c_var{name={'lists^all',1}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
- CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
- body=#c_apply{anno=Anno, op=Loop, args=[Xs]}},
- CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
- body=#c_literal{val=false}},
- CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
- body=match_fail(Anno, Err1)},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]},
- clauses = [CC1, CC2, CC3]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=1}]},
- body=#c_literal{val=true}},
- Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^all',1}}|Anno], Err2)},
- Fun = #c_fun{vars=[Xs],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, any, [Arg1,Arg2], Sub) ->
- Loop = #c_var{name={'lists^any',1}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
- CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
- body=#c_literal{val=true}},
- CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
- body=#c_apply{anno=Anno, op=Loop, args=[Xs]}},
- CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
- body=match_fail(Anno, Err1)},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]},
- clauses = [CC1, CC2, CC3]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=1}]},
- body=#c_literal{val=false}},
- Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^any',1}}|Anno], Err2)},
- Fun = #c_fun{vars=[Xs],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, foreach, [Arg1,Arg2], Sub) ->
- Loop = #c_var{name={'lists^foreach',1}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_seq{arg=#c_apply{anno=Anno, op=F, args=[X]},
- body=#c_apply{anno=Anno, op=Loop, args=[Xs]}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=1}]},
- body=#c_literal{val=ok}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^foreach',1}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, map, [Arg1,Arg2], Sub) ->
- Loop = #c_var{name={'lists^map',1}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- H = #c_var{name='H'},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_let{vars=[H], arg=#c_apply{anno=Anno,
- op=F,
- args=[X]},
- body=#c_cons{hd=H,
- anno=[compiler_generated],
- tl=#c_apply{anno=Anno,
- op=Loop,
- args=[Xs]}}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=1}]},
- body=#c_literal{val=[]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^map',1}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2], Sub) ->
- Loop = #c_var{name={'lists^flatmap',1}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- H = #c_var{name='H'},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_let{vars=[H],
- arg=#c_apply{anno=Anno, op=F, args=[X]},
- body=#c_call{anno=[compiler_generated|Anno],
- module=#c_literal{val=erlang},
- name=#c_literal{val='++'},
- args=[H,
- #c_apply{anno=Anno,
- op=Loop,
- args=[Xs]}]}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=1}]},
- body=#c_literal{val=[]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^flatmap',1}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) ->
- Loop = #c_var{name={'lists^filter',1}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- B = #c_var{name='B'},
- Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
- CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
- body=#c_cons{anno=[compiler_generated], hd=X, tl=Xs}},
- CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
- body=Xs},
- CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
- body=match_fail(Anno, Err1)},
- Case = #c_case{arg=B, clauses = [CC1, CC2, CC3]},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_let{vars=[B],
- arg=#c_apply{anno=Anno, op=F, args=[X]},
- body=#c_let{vars=[Xs],
- arg=#c_apply{anno=Anno,
- op=Loop,
- args=[Xs]},
- body=Case}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=1}]},
- body=#c_literal{val=[]}},
- Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^filter',1}}|Anno], Err2)},
- Fun = #c_fun{vars=[Xs],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, foldl, [Arg1,Arg2,Arg3], Sub) ->
- Loop = #c_var{name={'lists^foldl',2}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- A = #c_var{name='A'},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_apply{anno=Anno,
- op=Loop,
- args=[Xs, #c_apply{anno=Anno,
- op=F,
- args=[X, A]}]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=2}]},
- body=A},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^foldl',2}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs, A],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, A, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L, A]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, foldr, [Arg1,Arg2,Arg3], Sub) ->
- Loop = #c_var{name={'lists^foldr',2}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- A = #c_var{name='A'},
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=#c_apply{anno=Anno,
- op=F,
- args=[X, #c_apply{anno=Anno,
- op=Loop,
- args=[Xs, A]}]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=2}]},
- body=A},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^foldr',2}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs, A],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, A, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
- body=#c_letrec{defs=[{Loop,Fun}],
- body=#c_apply{anno=Anno, op=Loop, args=[L, A]}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) ->
- Loop = #c_var{name={'lists^mapfoldl',2}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- Avar = #c_var{name='A'},
- Match =
- fun (A, P, E) ->
- C1 = #c_clause{pats=[P], guard=#c_literal{val=true}, body=E},
- Err = #c_tuple{es=[#c_literal{val='badmatch'}, X]},
- C2 = #c_clause{pats=[X], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
- #c_case{arg=A, clauses=[C1, C2]}
- end,
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
- body=Match(#c_apply{anno=Anno, op=F, args=[X, Avar]},
- #c_tuple{es=[X, Avar]},
-%%% Tuple passing version
- Match(#c_apply{anno=Anno,
- op=Loop,
- args=[Xs, Avar]},
- #c_tuple{es=[Xs, Avar]},
- #c_tuple{anno=[compiler_generated],
- es=[#c_cons{anno=[compiler_generated],
- hd=X, tl=Xs},
- Avar]})
-%%% Multiple-value version
-%%% #c_let{vars=[Xs,A],
-%%% %% The tuple here will be optimised
-%%% %% away later; no worries.
-%%% arg=#c_apply{op=Loop, args=[Xs, A]},
-%%% body=#c_values{es=[#c_cons{hd=X, tl=Xs},
-%%% A]}}
- )},
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=2}]},
-%%% Tuple passing version
- body=#c_tuple{anno=[compiler_generated],
- es=[#c_literal{val=[]}, Avar]}},
-%%% Multiple-value version
-%%% body=#c_values{es=[#c_literal{val=[]}, A]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^mapfoldl',2}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs, Avar],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, Avar, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
- body=#c_letrec{defs=[{Loop,Fun}],
-%%% Tuple passing version
- body=#c_apply{anno=Anno,
- op=Loop,
- args=[L, Avar]}}},
-%%% Multiple-value version
-%%% body=#c_let{vars=[Xs, A],
-%%% arg=#c_apply{op=Loop,
-%%% args=[L, A]},
-%%% body=#c_tuple{es=[Xs, A]}}}},
- Sub);
-call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) ->
- Loop = #c_var{name={'lists^mapfoldr',2}},
- F = #c_var{name='F'},
- Xs = #c_var{name='Xs'},
- X = #c_var{name='X'},
- Avar = #c_var{name='A'},
- Match =
- fun (A, P, E) ->
- C1 = #c_clause{pats=[P], guard=#c_literal{val=true}, body=E},
- Err = #c_tuple{es=[#c_literal{val='badmatch'}, X]},
- C2 = #c_clause{pats=[X], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
- #c_case{arg=A, clauses=[C1, C2]}
- end,
- C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
-%%% Tuple passing version
- body=Match(#c_apply{anno=Anno,
- op=Loop,
- args=[Xs, Avar]},
- #c_tuple{es=[Xs, Avar]},
- Match(#c_apply{anno=Anno, op=F, args=[X, Avar]},
- #c_tuple{es=[X, Avar]},
- #c_tuple{anno=[compiler_generated],
- es=[#c_cons{anno=[compiler_generated],
- hd=X, tl=Xs}, Avar]}))
-%%% Multiple-value version
-%%% body=#c_let{vars=[Xs,A],
-%%% %% The tuple will be optimised away
-%%% arg=#c_apply{op=Loop, args=[Xs, A]},
-%%% body=Match(#c_apply{op=F, args=[X, A]},
-%%% #c_tuple{es=[X, A]},
-%%% #c_values{es=[#c_cons{hd=X, tl=Xs},
-%%% A]})}
- },
- C2 = #c_clause{pats=[#c_literal{val=[]}],
- guard=#c_call{module=#c_literal{val=erlang},
- name=#c_literal{val=is_function},
- args=[F, #c_literal{val=2}]},
-%%% Tuple passing version
- body=#c_tuple{anno=[compiler_generated],
- es=[#c_literal{val=[]}, Avar]}},
-%%% Multiple-value version
-%%% body=#c_values{es=[#c_literal{val=[]}, A]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]},
- C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail([{function_name,{'lists^mapfoldr',2}}|Anno], Err)},
- Fun = #c_fun{vars=[Xs, Avar],
- body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
- L = #c_var{name='L'},
- expr(#c_let{vars=[F, Avar, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
- body=#c_letrec{defs=[{Loop,Fun}],
-%%% Tuple passing version
- body=#c_apply{anno=Anno,
- op=Loop,
- args=[L, Avar]}}},
-%%% Multiple-value version
-%%% body=#c_let{vars=[Xs, A],
-%%% arg=#c_apply{op=Loop,
-%%% args=[L, A]},
-%%% body=#c_tuple{es=[Xs, A]}}}},
- Sub);
-call_1(#c_call{module=M, name=N}=Call, _, _, As, Sub) ->
- call_0(Call, M, N, As, Sub).
-
-match_fail(Anno, Arg) ->
- #c_primop{anno=Anno,
- name=#c_literal{val='match_fail'},
- args=[Arg]}.
-
%% fold_call(Call, Mod, Name, Args, Sub) -> Expr.
%% Try to safely evaluate the call. Just try to evaluate arguments,
%% do the call and convert return values to literals. If this
@@ -1133,29 +759,33 @@ fold_call_1(Call, Mod, Name, Args, Sub) ->
true -> fold_call_2(Call, Mod, Name, Args, Sub)
end.
-fold_call_2(Call, Module, Name, Args0, Sub) ->
- try
- Args = [core_lib:literal_value(A) || A <- Args0],
- try apply(Module, Name, Args) of
- Val ->
- case cerl:is_literal_term(Val) of
- true ->
- #c_literal{val=Val};
- false ->
- %% Successful evaluation, but it was not
- %% possible to express the computed value as a literal.
- Call
- end
- catch
- error:Reason ->
- %% Evaluation of the function failed. Warn and replace
- %% the call with a call to erlang:error/1.
- eval_failure(Call, Reason)
- end
+fold_call_2(Call, Module, Name, Args, Sub) ->
+ case all(fun cerl:is_literal/1, Args) of
+ true ->
+ %% All arguments are literals.
+ fold_lit_args(Call, Module, Name, Args);
+ false ->
+ %% At least one non-literal argument.
+ fold_non_lit_args(Call, Module, Name, Args, Sub)
+ end.
+
+fold_lit_args(Call, Module, Name, Args0) ->
+ Args = [cerl:concrete(A) || A <- Args0],
+ try apply(Module, Name, Args) of
+ Val ->
+ case cerl:is_literal_term(Val) of
+ true ->
+ cerl:abstract(Val);
+ false ->
+ %% Successful evaluation, but it was not possible
+ %% to express the computed value as a literal.
+ Call
+ end
catch
- error:_ ->
- %% There was at least one non-literal argument.
- fold_non_lit_args(Call, Module, Name, Args0, Sub)
+ error:Reason ->
+ %% Evaluation of the function failed. Warn and replace
+ %% the call with a call to erlang:error/1.
+ eval_failure(Call, Reason)
end.
%% fold_non_lit_args(Call, Module, Name, Args, Sub) -> Expr.
@@ -1194,36 +824,43 @@ fold_non_lit_args(Call, _, _, _, _) -> Call.
%% Evaluate a relational operation using type information.
eval_rel_op(Call, Op, [#c_var{name=V},#c_var{name=V}], _) ->
Bool = erlang:Op(same, same),
- #c_literal{anno=core_lib:get_anno(Call),val=Bool};
-eval_rel_op(Call, '=:=', [#c_var{name=V}=Var,#c_literal{val=true}], Sub) ->
+ #c_literal{anno=cerl:get_ann(Call),val=Bool};
+eval_rel_op(Call, '=:=', [Term,#c_literal{val=true}], Sub) ->
%% BoolVar =:= true ==> BoolVar
- case is_boolean_type(V, Sub) of
- true -> Var;
- false -> Call
+ case is_boolean_type(Term, Sub) of
+ yes -> Term;
+ maybe -> Call;
+ no -> #c_literal{val=false}
end;
-eval_rel_op(Call, '==', Ops, _Sub) ->
- case is_exact_eq_ok(Ops) of
+eval_rel_op(Call, '==', Ops, Sub) ->
+ case is_exact_eq_ok(Ops, Sub) of
true ->
- Name = #c_literal{anno=core_lib:get_anno(Call),val='=:='},
+ Name = #c_literal{anno=cerl:get_ann(Call),val='=:='},
Call#c_call{name=Name};
false ->
Call
end;
-eval_rel_op(Call, '/=', Ops, _Sub) ->
- case is_exact_eq_ok(Ops) of
+eval_rel_op(Call, '/=', Ops, Sub) ->
+ case is_exact_eq_ok(Ops, Sub) of
true ->
- Name = #c_literal{anno=core_lib:get_anno(Call),val='=/='},
+ Name = #c_literal{anno=cerl:get_ann(Call),val='=/='},
Call#c_call{name=Name};
false ->
Call
end;
eval_rel_op(Call, _, _, _) -> Call.
-is_exact_eq_ok([#c_literal{val=Lit}|_]) ->
+is_exact_eq_ok([A,B]=L, Sub) ->
+ case is_int_type(A, Sub) =:= yes andalso is_int_type(B, Sub) =:= yes of
+ true -> true;
+ false -> is_exact_eq_ok_1(L)
+ end.
+
+is_exact_eq_ok_1([#c_literal{val=Lit}|_]) ->
is_non_numeric(Lit);
-is_exact_eq_ok([_|T]) ->
- is_exact_eq_ok(T);
-is_exact_eq_ok([]) -> false.
+is_exact_eq_ok_1([_|T]) ->
+ is_exact_eq_ok_1(T);
+is_exact_eq_ok_1([]) -> false.
is_non_numeric([H|T]) ->
is_non_numeric(H) andalso is_non_numeric(T);
@@ -1247,40 +884,31 @@ is_non_numeric_tuple(_Tuple, 0) -> true.
%% there must be at least one non-literal argument (i.e.
%% there is no need to handle the case that all argments
%% are literal).
-eval_bool_op(Call, 'and', [#c_literal{val=true},#c_var{name=V}=Res], Sub) ->
- case is_boolean_type(V, Sub) of
- true -> Res;
- false-> Call
- end;
-eval_bool_op(Call, 'and', [#c_var{name=V}=Res,#c_literal{val=true}], Sub) ->
- case is_boolean_type(V, Sub) of
- true -> Res;
- false-> Call
- end;
-eval_bool_op(Call, 'and', [#c_literal{val=false}=Res,#c_var{name=V}], Sub) ->
- case is_boolean_type(V, Sub) of
- true -> Res;
- false-> Call
- end;
-eval_bool_op(Call, 'and', [#c_var{name=V},#c_literal{val=false}=Res], Sub) ->
- case is_boolean_type(V, Sub) of
- true -> Res;
- false-> Call
- end;
+
+eval_bool_op(Call, 'and', [#c_literal{val=true},Term], Sub) ->
+ eval_bool_op_1(Call, Term, Term, Sub);
+eval_bool_op(Call, 'and', [Term,#c_literal{val=true}], Sub) ->
+ eval_bool_op_1(Call, Term, Term, Sub);
+eval_bool_op(Call, 'and', [#c_literal{val=false}=Res,Term], Sub) ->
+ eval_bool_op_1(Call, Res, Term, Sub);
+eval_bool_op(Call, 'and', [Term,#c_literal{val=false}=Res], Sub) ->
+ eval_bool_op_1(Call, Res, Term, Sub);
eval_bool_op(Call, _, _, _) -> Call.
+eval_bool_op_1(Call, Res, Term, Sub) ->
+ case is_boolean_type(Term, Sub) of
+ yes -> Res;
+ no -> eval_failure(Call, badarg);
+ maybe -> Call
+ end.
+
%% Evaluate is_boolean/1 using type information.
-eval_is_boolean(Call, #c_var{name=V}, Sub) ->
- case is_boolean_type(V, Sub) of
- true -> #c_literal{val=true};
- false -> Call
- end;
-eval_is_boolean(_, #c_cons{}, _) ->
- #c_literal{val=false};
-eval_is_boolean(_, #c_tuple{}, _) ->
- #c_literal{val=false};
-eval_is_boolean(Call, _, _) ->
- Call.
+eval_is_boolean(Call, Term, Sub) ->
+ case is_boolean_type(Term, Sub) of
+ no -> #c_literal{val=false};
+ yes -> #c_literal{val=true};
+ maybe -> Call
+ end.
%% eval_length(Call, List) -> Val.
%% Evaluates the length for the prefix of List which has a known
@@ -1330,36 +958,33 @@ eval_append(Call, X, Y) ->
%% Evaluates element/2 if the position Pos is a literal and
%% the shape of the tuple Tuple is known.
%%
-eval_element(Call, #c_literal{val=Pos}, #c_tuple{es=Es}, _Types) when is_integer(Pos) ->
- if
- 1 =< Pos, Pos =< length(Es) ->
- lists:nth(Pos, Es);
- true ->
- eval_failure(Call, badarg)
- end;
-eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types)
+eval_element(Call, #c_literal{val=Pos}, Tuple, Types)
when is_integer(Pos) ->
- case orddict:find(V, Types#sub.t) of
- {ok,#c_tuple{es=Elements}} ->
+ case get_type(Tuple, Types) of
+ none ->
+ Call;
+ Type ->
+ Es = case cerl:is_c_tuple(Type) of
+ false -> [];
+ true -> cerl:tuple_es(Type)
+ end,
if
- 1 =< Pos, Pos =< length(Elements) ->
- El = lists:nth(Pos, Elements),
+ 1 =< Pos, Pos =< length(Es) ->
+ El = lists:nth(Pos, Es),
try
- pat_to_expr(El)
+ cerl:set_ann(pat_to_expr(El), [compiler_generated])
catch
throw:impossible ->
Call
end;
true ->
+ %% Index outside tuple or not a tuple.
eval_failure(Call, badarg)
- end;
- {ok,_} ->
- eval_failure(Call, badarg);
- error ->
- Call
+ end
end;
-eval_element(Call, Pos, Tuple, _Types) ->
- case is_not_integer(Pos) orelse is_not_tuple(Tuple) of
+eval_element(Call, Pos, Tuple, Sub) ->
+ case is_int_type(Pos, Sub) =:= no orelse
+ is_tuple_type(Tuple, Sub) =:= no of
true ->
eval_failure(Call, badarg);
false ->
@@ -1369,58 +994,55 @@ eval_element(Call, Pos, Tuple, _Types) ->
%% eval_is_record(Call, Var, Tag, Size, Types) -> Val.
%% Evaluates is_record/3 using type information.
%%
-eval_is_record(Call, #c_var{name=V}, #c_literal{val=NeededTag}=Lit,
+eval_is_record(Call, Term, #c_literal{val=NeededTag},
#c_literal{val=Size}, Types) ->
- case orddict:find(V, Types#sub.t) of
- {ok,#c_tuple{es=[#c_literal{val=Tag}|_]=Es}} ->
- Lit#c_literal{val=Tag =:= NeededTag andalso
- length(Es) =:= Size};
- _ ->
- Call
+ case get_type(Term, Types) of
+ none ->
+ Call;
+ Type ->
+ Es = case cerl:is_c_tuple(Type) of
+ false -> [];
+ true -> cerl:tuple_es(Type)
+ end,
+ case Es of
+ [#c_literal{val=Tag}|_] ->
+ Bool = Tag =:= NeededTag andalso
+ length(Es) =:= Size,
+ #c_literal{val=Bool};
+ _ ->
+ #c_literal{val=false}
+ end
end;
eval_is_record(Call, _, _, _, _) -> Call.
-%% is_not_integer(Core) -> true | false.
-%% Returns true if Core is definitely not an integer.
-
-is_not_integer(#c_literal{val=Val}) when not is_integer(Val) -> true;
-is_not_integer(#c_tuple{}) -> true;
-is_not_integer(#c_cons{}) -> true;
-is_not_integer(#c_map{}) -> true;
-is_not_integer(_) -> false.
-
-%% is_not_tuple(Core) -> true | false.
-%% Returns true if Core is definitely not a tuple.
-
-is_not_tuple(#c_literal{val=Val}) when not is_tuple(Val) -> true;
-is_not_tuple(#c_cons{}) -> true;
-is_not_tuple(#c_map{}) -> true;
-is_not_tuple(_) -> false.
-
%% eval_setelement(Call, Pos, Tuple, NewVal) -> Core.
%% Evaluates setelement/3 if position Pos is an integer
-%% the shape of the tuple Tuple is known.
+%% and the shape of the tuple Tuple is known.
%%
-eval_setelement(Call, Pos, Tuple, NewVal) ->
- try
- eval_setelement_1(Pos, Tuple, NewVal)
- catch
- error:_ ->
- Call
- end.
-
-eval_setelement_1(#c_literal{val=Pos}, #c_tuple{anno=A,es=Es}, NewVal)
+eval_setelement(Call, #c_literal{val=Pos}, Tuple, NewVal)
when is_integer(Pos) ->
- ann_c_tuple(A, eval_setelement_2(Pos, Es, NewVal));
-eval_setelement_1(#c_literal{val=Pos}, #c_literal{anno=A,val=Es0}, NewVal)
- when is_integer(Pos) ->
- Es = [#c_literal{anno=A,val=E} || E <- tuple_to_list(Es0)],
- ann_c_tuple(A, eval_setelement_2(Pos, Es, NewVal)).
+ case cerl:is_data(Tuple) of
+ false ->
+ Call;
+ true ->
+ Es0 = case cerl:is_c_tuple(Tuple) of
+ false -> [];
+ true -> cerl:tuple_es(Tuple)
+ end,
+ if
+ 1 =< Pos, Pos =< length(Es0) ->
+ Es = eval_setelement_1(Pos, Es0, NewVal),
+ cerl:update_c_tuple(Tuple, Es);
+ true ->
+ eval_failure(Call, badarg)
+ end
+ end;
+eval_setelement(Call, _, _, _) -> Call.
-eval_setelement_2(1, [_|T], NewVal) ->
+eval_setelement_1(1, [_|T], NewVal) ->
[NewVal|T];
-eval_setelement_2(Pos, [H|T], NewVal) when Pos > 1 ->
- [H|eval_setelement_2(Pos-1, T, NewVal)].
+eval_setelement_1(Pos, [H|T], NewVal) when Pos > 1 ->
+ [H|eval_setelement_1(Pos-1, T, NewVal)].
%% eval_failure(Call, Reason) -> Core.
%% Warn for a call that will fail and replace the call with
@@ -1500,20 +1122,32 @@ clause(#c_clause{pats=Ps0,guard=G0,body=B0}=Cl, Cexpr, Ctxt, Sub0) ->
let_substs(Vs0, As0, Sub0) ->
{Vs1,Sub1} = pattern_list(Vs0, Sub0),
{Vs2,As1,Ss} = let_substs_1(Vs1, As0, Sub1),
- Sub2 = scope_add([V || #c_var{name=V} <- Vs2], Sub1),
+ Sub2 = sub_add_scope([V || #c_var{name=V} <- Vs2], Sub1),
{Vs2,As1,
- foldl(fun ({V,S}, Sub) -> sub_set_name(V, S, Sub) end, Sub2, Ss)}.
+ foldl(fun ({V,S}, Sub) -> sub_set_name(V, S, Sub) end, Sub2, Ss)}.
let_substs_1(Vs, #c_values{es=As}, Sub) ->
let_subst_list(Vs, As, Sub);
let_substs_1([V], A, Sub) -> let_subst_list([V], [A], Sub);
let_substs_1(Vs, A, _) -> {Vs,A,[]}.
-let_subst_list([V|Vs0], [A|As0], Sub) ->
+let_subst_list([V|Vs0], [A0|As0], Sub) ->
{Vs1,As1,Ss} = let_subst_list(Vs0, As0, Sub),
- case is_subst(A) of
- true -> {Vs1,As1,sub_subst_var(V, A, Sub) ++ Ss};
- false -> {[V|Vs1],[A|As1],Ss}
+ case is_subst(A0) of
+ true ->
+ A = case is_compiler_generated(V) andalso
+ not is_compiler_generated(A0) of
+ true ->
+ %% Propagate the 'compiler_generated' annotation
+ %% along with the value.
+ Ann = [compiler_generated|cerl:get_ann(A0)],
+ cerl:set_ann(A0, Ann);
+ false ->
+ A0
+ end,
+ {Vs1,As1,sub_subst_var(V, A, Sub) ++ Ss};
+ false ->
+ {[V|Vs1],[A0|As1],Ss}
end;
let_subst_list([], [], _) -> {[],[],[]}.
@@ -1535,7 +1169,7 @@ pattern(#c_var{}=Pat, Isub, Osub) ->
true ->
V1 = make_var_name(),
Pat1 = #c_var{name=V1},
- {Pat1,sub_set_var(Pat, Pat1, scope_add([V1], Osub))};
+ {Pat1,sub_set_var(Pat, Pat1, sub_add_scope([V1], Osub))};
false ->
{Pat,sub_del_var(Pat, Osub)}
end;
@@ -1605,6 +1239,7 @@ is_subst(_) -> false.
%% sub_del_var(Var, #sub{}) -> #sub{}.
%% sub_subst_var(Var, Value, #sub{}) -> [{Name,Value}].
%% sub_is_val(Var, #sub{}) -> boolean().
+%% sub_add_scope(#sub{}) -> #sub{}
%% sub_subst_scope(#sub{}) -> #sub{}
%%
%% We use the variable name as key so as not have problems with
@@ -1615,14 +1250,15 @@ is_subst(_) -> false.
%% In addition to the list of substitutions, we also keep track of
%% all variable currently live (the scope).
%%
-%% sub_subst_scope/1 adds dummy substitutions for all variables
-%% in the scope in order to force renaming if variables in the
-%% scope occurs as pattern variables.
+%% sub_add_scope/2 adds variables to the scope. sub_subst_scope/1
+%% adds dummy substitutions for all variables in the scope in order
+%% to force renaming if variables in the scope occurs as pattern
+%% variables.
-sub_new() -> #sub{v=orddict:new(),s=gb_trees:empty(),t=[]}.
+sub_new() -> #sub{v=orddict:new(),s=cerl_sets:new(),t=#{}}.
sub_new(#sub{}=Sub) ->
- Sub#sub{v=orddict:new(),t=[]}.
+ Sub#sub{v=orddict:new(),t=#{}}.
sub_new_preserve_types(#sub{}=Sub) ->
Sub#sub{v=orddict:new()}.
@@ -1639,16 +1275,16 @@ sub_set_var(#c_var{name=V}, Val, Sub) ->
sub_set_name(V, Val, #sub{v=S,s=Scope,t=Tdb0}=Sub) ->
Tdb1 = kill_types(V, Tdb0),
Tdb = copy_type(V, Val, Tdb1),
- Sub#sub{v=orddict:store(V, Val, S),s=gb_sets:add(V, Scope),t=Tdb}.
+ Sub#sub{v=orddict:store(V, Val, S),s=cerl_sets:add_element(V, Scope),t=Tdb}.
sub_del_var(#c_var{name=V}, #sub{v=S,s=Scope,t=Tdb}=Sub) ->
%% Profiling shows that for programs with many record operations,
%% sub_del_var/2 is a bottleneck. Since the scope contains all
%% variables that are live, we know that V cannot be present in S
%% if it is not in the scope.
- case gb_sets:is_member(V, Scope) of
+ case cerl_sets:is_element(V, Scope) of
false ->
- Sub#sub{s=gb_sets:insert(V, Scope)};
+ Sub#sub{s=cerl_sets:add_element(V, Scope)};
true ->
Sub#sub{v=orddict:erase(V, S),t=kill_types(V, Tdb)}
end.
@@ -1657,8 +1293,14 @@ sub_subst_var(#c_var{name=V}, Val, #sub{v=S0}) ->
%% Fold chained substitutions.
[{V,Val}] ++ [ {K,Val} || {K,#c_var{name=V1}} <- S0, V1 =:= V].
+sub_add_scope(Vs, #sub{s=Scope0}=Sub) ->
+ Scope = foldl(fun(V, S) when is_integer(V); is_atom(V) ->
+ cerl_sets:add_element(V, S)
+ end, Scope0, Vs),
+ Sub#sub{s=Scope}.
+
sub_subst_scope(#sub{v=S0,s=Scope}=Sub) ->
- S = [{-1,#c_var{name=Sv}} || Sv <- gb_sets:to_list(Scope)]++S0,
+ S = [{-1,#c_var{name=Sv}} || Sv <- cerl_sets:to_list(Scope)]++S0,
Sub#sub{v=S}.
sub_is_val(#c_var{name=V}, #sub{v=S,s=Scope}) ->
@@ -1666,7 +1308,7 @@ sub_is_val(#c_var{name=V}, #sub{v=S,s=Scope}) ->
%% became the new bottleneck. Since the scope contains all
%% live variables, a variable V can only be the target for
%% a substitution if it is in the scope.
- gb_sets:is_member(V, Scope) andalso v_is_value(V, S).
+ cerl_sets:is_element(V, Scope) andalso v_is_value(V, S).
v_is_value(Var, [{_,#c_var{name=Var}}|_]) -> true;
v_is_value(Var, [_|T]) -> v_is_value(Var, T);
@@ -1704,7 +1346,7 @@ clauses(E, [C0|Cs], Ctxt, Sub, LitExpr) ->
{yes,yes} ->
case LitExpr of
false ->
- Line = get_line(core_lib:get_anno(C1)),
+ Line = get_line(cerl:get_ann(C1)),
shadow_warning(Cs, Line);
true ->
%% If the case expression is a literal,
@@ -1938,7 +1580,7 @@ opt_bool_case_guard(#c_case{arg=Arg,clauses=Cs0}=Case) ->
Case;
true ->
Cs = opt_bool_case_guard(Arg, Cs0),
- Case#c_case{arg=#c_values{anno=core_lib:get_anno(Arg),es=[]},
+ Case#c_case{arg=#c_values{anno=cerl:get_ann(Arg),es=[]},
clauses=Cs}
end.
@@ -1986,6 +1628,7 @@ eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0,
%% is correct, the clause will always match at run-time.
Case;
{true,Bs} ->
+ eval_case_warn(B),
{Ps,As} = unzip(Bs),
InnerLet = cerl:c_let(Ps, core_lib:make_values(As), B),
Let = cerl:c_let(Vs, E, InnerLet),
@@ -1993,6 +1636,18 @@ eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0,
end;
eval_case(Case, _) -> Case.
+eval_case_warn(#c_primop{anno=Anno,
+ name=#c_literal{val=match_fail},
+ args=[_]}=Core) ->
+ case keyfind(eval_failure, 1, Anno) of
+ false ->
+ ok;
+ {eval_failure,Reason} ->
+ %% Example: M = not_map, M#{k:=v}
+ add_warning(Core, {eval_failure,Reason})
+ end;
+eval_case_warn(_) -> ok.
+
%% case_opt(CaseArg, [Clause]) -> {CaseArg,[Clause]}.
%% Try and optimise a case by avoid building tuples or lists
%% in the case expression. Instead combine the variable parts
@@ -2048,12 +1703,31 @@ case_opt_args([], Cs, _Sub, _LitExpr, Acc) ->
%% Try to expand one argument to several arguments (if tuple/list)
%% or to remove a literal argument.
%%
-case_opt_arg(E0, Sub, Cs0, LitExpr) ->
- E = maybe_replace_var(E0, Sub),
- case cerl:is_data(E) of
+case_opt_arg(E0, Sub, Cs, LitExpr) ->
+ case cerl:is_c_var(E0) of
+ false ->
+ case_opt_arg_1(E0, Cs, LitExpr);
+ true ->
+ case case_will_var_match(Cs) of
+ true ->
+ %% All clauses will match a variable in the
+ %% current position. Don't expand this variable
+ %% (that can only make the code worse).
+ {error,Cs};
+ false ->
+ %% If possible, expand this variable to a previously
+ %% matched term.
+ E = case_expand_var(E0, Sub),
+ case_opt_arg_1(E, Cs, LitExpr)
+ end
+ end.
+
+case_opt_arg_1(E0, Cs0, LitExpr) ->
+ case cerl:is_data(E0) of
false ->
{error,Cs0};
true ->
+ E = case_opt_compiler_generated(E0),
Cs = case_opt_nomatch(E, Cs0, LitExpr),
case cerl:data_type(E) of
{atomic,_} ->
@@ -2063,20 +1737,45 @@ case_opt_arg(E0, Sub, Cs0, LitExpr) ->
end
end.
-%% maybe_replace_var(Expr0, Sub) -> Expr
+%% case_will_var_match([Clause]) -> true | false.
+%% Return if all clauses will match a variable in the
+%% current position.
+%%
+case_will_var_match(Cs) ->
+ all(fun({[P|_],_,_,_}) ->
+ case cerl_clauses:match(P, any) of
+ {true,_} -> true;
+ _ -> false
+ end
+ end, Cs).
+
+
+%% case_opt_compiler_generated(Core) -> Core'
+%% Mark Core expressions as compiler generated to ensure that
+%% no warnings are generated if they turn out to be unused.
+%% To pretty-printed Core Erlang easier to read, don't mark
+%% constructs that can't cause warnings to be emitted.
+%%
+case_opt_compiler_generated(Core) ->
+ F = fun(C) ->
+ case cerl:type(C) of
+ alias -> C;
+ var -> C;
+ _ -> cerl:set_ann(C, [compiler_generated])
+ end
+ end,
+ cerl_trees:map(F, Core).
+
+
+%% case_expand_var(Expr0, Sub) -> Expr
%% If Expr0 is a variable that has been previously matched and
%% is known to be a tuple, return the tuple instead. Otherwise
%% return Expr0 unchanged.
%%
-maybe_replace_var(E, Sub) ->
- case cerl:is_c_var(E) of
- false -> E;
- true -> maybe_replace_var_1(E, Sub)
- end.
-
-maybe_replace_var_1(E, #sub{t=Tdb}) ->
- case orddict:find(cerl:var_name(E), Tdb) of
- {ok,T0} ->
+case_expand_var(E, #sub{t=Tdb}) ->
+ Key = cerl:var_name(E),
+ case Tdb of
+ #{Key:=T0} ->
case cerl:is_c_tuple(T0) of
false ->
E;
@@ -2091,9 +1790,8 @@ maybe_replace_var_1(E, #sub{t=Tdb}) ->
%% operator will fail when used in map
%% construction (only the '=>' operator is allowed
%% when constructing a map from scratch).
- ToData = fun coerce_to_data/1,
try
- cerl_trees:map(ToData, T0)
+ cerl_trees:map(fun coerce_to_data/1, T0)
catch
throw:impossible ->
%% Something unsuitable was found (map or
@@ -2101,7 +1799,7 @@ maybe_replace_var_1(E, #sub{t=Tdb}) ->
E
end
end;
- error ->
+ _ ->
E
end.
@@ -2147,8 +1845,9 @@ case_opt_nomatch(_, [], _) -> [].
%% will match, and we can remove the corresponding pattern from
%% each clause.
%%
-%% The only complication is if the literal is a binary. Binary
-%% pattern matching is tricky, so we will give up in that case.
+%% The only complication is if the literal is a binary or map.
+%% In general, it is difficult to know whether a binary or
+%% map pattern will match, so we give up in that case.
case_opt_lit(Lit, Cs0) ->
try case_opt_lit_1(Lit, Cs0) of
@@ -2175,6 +1874,10 @@ case_opt_lit_1(E, [{[P|Ps],C,PsAcc,Bs0}|Cs]) ->
case_opt_lit_1(_, []) -> [].
%% case_opt_data(Expr, Clauses0, LitExpr) -> {ok,Exprs,Clauses}
+%% The case expression is a non-atomic data constructor (cons
+%% or tuple). We can know at compile time whether each clause
+%% will match, and we can delay the building of the data to
+%% the clauses where it is actually needed.
case_opt_data(E, Cs0) ->
Es = cerl:data_es(E),
@@ -2184,45 +1887,48 @@ case_opt_data(E, Cs0) ->
{ok,Es,Cs}
catch
throw:impossible ->
+ %% The pattern contained a binary or map.
{error,Cs0}
end.
-case_opt_data_1([{[P|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig) ->
- {ok,Ps1,Bs1} = case_data_pat(P, TypeSig),
- [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}|
- case_opt_data_1(Cs, Es, TypeSig)];
+case_opt_data_1([{[P0|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig) ->
+ P = case_opt_compiler_generated(P0),
+ BindTo = #c_var{name=dummy},
+ {Ps1,[{BindTo,_}|Bs1]} = case_data_pat_alias(P, BindTo, TypeSig, []),
+ [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}|case_opt_data_1(Cs, Es, TypeSig)];
case_opt_data_1([], _, _) -> [].
-%% case_data_pat(Pattern, Type, Arity) -> {ok,[Pattern],[{AliasVar,Pat}]} | error.
-
-case_data_pat(P, TypeSig) ->
- case cerl:is_data(P) of
- false ->
- case_data_pat_var(P, TypeSig);
- true ->
- {ok,cerl:data_es(P),[]}
- end.
-
-%% case_data_pat_var(Pattern, {DataType,ArityType}) ->
-%% {ok,[Pattern],[{AliasVar,Pat}]}
-
-case_data_pat_var(P, {Type,Arity}=TypeSig) ->
- %% If the entire case statement is evaluated in an effect
- %% context (e.g. "case {A,B} of ... end, ok"), there will
- %% be a warning that a term is constructed but never used.
- %% To avoid that warning, we must annotate the data
- %% constructor as compiler generated.
- Ann = [compiler_generated|cerl:get_ann(P)],
+case_data_pat_alias(P, BindTo0, TypeSig, Bs0) ->
case cerl:type(P) of
- var ->
- Vars = make_vars(cerl:get_ann(P), Arity),
- {ok,Vars,[{P,cerl:ann_make_data(Ann, Type, Vars)}]};
alias ->
- V = cerl:alias_var(P),
- Apat = cerl:alias_pat(P),
- {ok,Ps,Bs} = case_data_pat(Apat, TypeSig),
- {ok,Ps,[{V,cerl:ann_make_data(Ann, Type,
- pat_to_expr_list(Ps))}|Bs]}
+ %% Recursively handle the pattern and bind to
+ %% the alias variable.
+ BindTo = cerl:alias_var(P),
+ Apat0 = cerl:alias_pat(P),
+ Ann = [compiler_generated],
+ Apat = cerl:set_ann(Apat0, Ann),
+ {Ps,Bs} = case_data_pat_alias(Apat, BindTo, TypeSig, Bs0),
+ {Ps,[{BindTo0,BindTo}|Bs]};
+ var ->
+ %% Here we will need to actually build the data and bind
+ %% it to the variable.
+ {Type,Arity} = TypeSig,
+ Ann = [compiler_generated],
+ Vars = make_vars(Ann, Arity),
+ Data = cerl:ann_make_data(Ann, Type, Vars),
+ Bs = [{BindTo0,P},{P,Data}|Bs0],
+ {Vars,Bs};
+ _ ->
+ %% Since case_opt_nomatch/3 has removed all clauses that
+ %% cannot match, we KNOW that this clause must match and
+ %% that the pattern must be a data constructor.
+ %% Here we must build the data and bind it to the variable.
+ {Type,_} = TypeSig,
+ DataEs = cerl:data_es(P),
+ Vars = pat_to_expr_list(DataEs),
+ Ann = [compiler_generated],
+ Data = cerl:ann_make_data(Ann, Type, Vars),
+ {DataEs,[{BindTo0,Data}]}
end.
%% pat_to_expr(Pattern) -> Expression.
@@ -2269,58 +1975,130 @@ make_var_name() ->
list_to_atom("fol"++integer_to_list(N)).
letify(Bs, Body) ->
+ Ann = cerl:get_ann(Body),
foldr(fun({V,Val}, B) ->
- letify(V, Val, B)
+ cerl:ann_c_let(Ann, [V], Val, B)
end, Body, Bs).
-letify(#c_var{name=Vname}=Var, Val, Body) ->
- case core_lib:is_var_used(Vname, Body) of
- true ->
- A = element(2, Body),
- #c_let{anno=A,vars=[Var],arg=Val,body=Body};
- false -> Body
- end.
-
-%% opt_case_in_let(LetExpr) -> LetExpr'
+%% opt_not_in_let(Let) -> Cerl
+%% Try to optimize away a 'not' operator in a 'let'.
-opt_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let, Sub) ->
- opt_case_in_let_0(Vs, Arg, B, Let, Sub).
+-spec opt_not_in_let(cerl:c_let()) -> cerl:cerl().
-opt_case_in_let_0([#c_var{name=V}], Arg,
- #c_case{arg=#c_var{name=V},clauses=Cs}=Case, Let, Sub) ->
- case opt_case_in_let_1(V, Arg, Cs) of
- impossible ->
- case is_simple_case_arg(Arg) andalso
- not core_lib:is_var_used(V, Case#c_case{arg=#c_literal{val=nil}}) of
- true ->
- expr(opt_bool_case(Case#c_case{arg=Arg,clauses=Cs}), sub_new(Sub));
- false ->
- Let
+opt_not_in_let(#c_let{vars=[_]=Vs0,arg=Arg0,body=Body0}=Let) ->
+ case opt_not_in_let(Vs0, Arg0, Body0) of
+ {[],#c_values{es=[]},Body} ->
+ Body;
+ {Vs,Arg,Body} ->
+ Let#c_let{vars=Vs,arg=Arg,body=Body}
+ 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) ->
+ case cerl:type(Body0) of
+ call ->
+ %% let <V> = Expr in not V ==>
+ %% let <> = <> in notExpr
+ case opt_not_in_let_1(V, Body0, Arg0) of
+ no ->
+ {Vs0,Arg0,Body0};
+ {yes,Body} ->
+ {[],#c_values{es=[]},Body}
end;
- Expr -> Expr
+ 'let' ->
+ %% let <V> = Expr in let <Var> = not V in Body ==>
+ %% let <Var> = notExpr in Body
+ %% V must not be used in Body.
+ LetArg = cerl:let_arg(Body0),
+ case opt_not_in_let_1(V, LetArg, Arg0) of
+ no ->
+ {Vs0,Arg0,Body0};
+ {yes,Arg} ->
+ LetBody = cerl:let_body(Body0),
+ case core_lib:is_var_used(V, LetBody) of
+ true ->
+ {Vs0,Arg0,Body0};
+ false ->
+ LetVars = cerl:let_vars(Body0),
+ {LetVars,Arg,LetBody}
+ end
+ end;
+ _ ->
+ {Vs0,Arg0,Body0}
end;
-opt_case_in_let_0(_, _, _, Let, _) -> Let.
+opt_not_in_let(Vs, Arg, Body) ->
+ {Vs,Arg,Body}.
-opt_case_in_let_1(V, Arg, Cs) ->
- try
- opt_case_in_let_2(V, Arg, Cs)
- catch
- _:_ -> impossible
+opt_not_in_let_1(V, Call, Body) ->
+ case Call of
+ #c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val='not'},
+ args=[#c_var{name=V}]} ->
+ opt_not_in_let_2(Body);
+ _ ->
+ no
end.
-opt_case_in_let_2(V, Arg0,
- [#c_clause{pats=[#c_tuple{es=Es}],
- guard=#c_literal{val=true},body=B}|_]) ->
-
- %% In {V1,V2,...} = case E of P -> ... {Val1,Val2,...}; ... end.
- %% avoid building tuples, by converting tuples to multiple values.
- %% (The optimisation is not done if the built tuple is used or returned.)
-
- true = all(fun (#c_var{}) -> true;
- (_) -> false end, Es), %Only variables in tuple
- false = core_lib:is_var_used(V, B), %Built tuple must not be used.
- Arg1 = tuple_to_values(Arg0, length(Es)), %Might fail.
- #c_let{vars=Es,arg=Arg1,body=B}.
+opt_not_in_let_2(#c_case{clauses=Cs0}=Case) ->
+ Vars = make_vars([], 1),
+ Body = #c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val='not'},
+ args=Vars},
+ Cs = [begin
+ Let = #c_let{vars=Vars,arg=B,body=Body},
+ C#c_clause{body=opt_not_in_let(Let)}
+ end || #c_clause{body=B}=C <- Cs0],
+ {yes,Case#c_case{clauses=Cs}};
+opt_not_in_let_2(#c_call{}=Call0) ->
+ invert_call(Call0);
+opt_not_in_let_2(_) -> no.
+
+invert_call(#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=Name0},
+ args=[_,_]}=Call) ->
+ case inverse_rel_op(Name0) of
+ no -> no;
+ Name -> {yes,Call#c_call{name=#c_literal{val=Name}}}
+ end;
+invert_call(#c_call{}) -> no.
+
+%% inverse_rel_op(Op) -> no | RevOp
+
+inverse_rel_op('=:=') -> '=/=';
+inverse_rel_op('=/=') -> '=:=';
+inverse_rel_op('==') -> '/=';
+inverse_rel_op('/=') -> '==';
+inverse_rel_op('>') -> '=<';
+inverse_rel_op('<') -> '>=';
+inverse_rel_op('>=') -> '<';
+inverse_rel_op('=<') -> '>';
+inverse_rel_op(_) -> no.
+
+
+%% opt_bool_case_in_let(LetExpr, Sub) -> Core
+
+opt_bool_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let, Sub) ->
+ opt_case_in_let_1(Vs, Arg, B, Let, Sub).
+
+opt_case_in_let_1([#c_var{name=V}], Arg,
+ #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 core_lib:is_var_used(V, Case) of
+ false -> expr(Case, sub_new(Sub));
+ true -> Let
+ end;
+ false ->
+ Let
+ end;
+opt_case_in_let_1(_, _, _, Let, _) -> Let.
%% is_simple_case_arg(Expr) -> true|false
%% Determine whether the Expr is simple enough to be worth
@@ -2362,18 +2140,15 @@ is_bool_expr(#c_clause{body=B}, Sub) ->
is_bool_expr(B, Sub);
is_bool_expr(#c_let{vars=[V],arg=Arg,body=B}, Sub0) ->
Sub = case is_bool_expr(Arg, Sub0) of
- true -> update_types(V, [#c_literal{val=true}], Sub0);
+ true -> update_types(V, [bool], Sub0);
false -> Sub0
end,
is_bool_expr(B, Sub);
is_bool_expr(#c_let{body=B}, Sub) ->
%% Binding of multiple variables.
is_bool_expr(B, Sub);
-is_bool_expr(#c_literal{val=Bool}, _) when is_boolean(Bool) ->
- true;
-is_bool_expr(#c_var{name=V}, Sub) ->
- is_boolean_type(V, Sub);
-is_bool_expr(_, _) -> false.
+is_bool_expr(C, Sub) ->
+ is_boolean_type(C, Sub) =:= yes.
is_bool_expr_list([C|Cs], Sub) ->
is_bool_expr(C, Sub) andalso is_bool_expr_list(Cs, Sub);
@@ -2386,7 +2161,7 @@ is_bool_expr_list([], _) -> true.
%% functions, or is_record/2).
%%
is_safe_bool_expr(Core, Sub) ->
- is_safe_bool_expr_1(Core, Sub, gb_sets:empty()).
+ is_safe_bool_expr_1(Core, Sub, cerl_sets:new()).
is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang},
name=#c_literal{val=is_record},
@@ -2432,7 +2207,7 @@ is_safe_bool_expr_1(#c_let{vars=Vars,arg=Arg,body=B}, Sub, BoolVars) ->
true ->
case {is_safe_bool_expr_1(Arg, Sub, BoolVars),Vars} of
{true,[#c_var{name=V}]} ->
- is_safe_bool_expr_1(B, Sub, gb_sets:add(V, BoolVars));
+ is_safe_bool_expr_1(B, Sub, cerl_sets:add_element(V, BoolVars));
{false,_} ->
is_safe_bool_expr_1(B, Sub, BoolVars)
end;
@@ -2441,7 +2216,7 @@ is_safe_bool_expr_1(#c_let{vars=Vars,arg=Arg,body=B}, Sub, BoolVars) ->
is_safe_bool_expr_1(#c_literal{val=Val}, _Sub, _) ->
is_boolean(Val);
is_safe_bool_expr_1(#c_var{name=V}, _Sub, BoolVars) ->
- gb_sets:is_element(V, BoolVars);
+ cerl_sets:is_element(V, BoolVars);
is_safe_bool_expr_1(_, _, _) -> false.
is_safe_bool_expr_list([C|Cs], Sub, BoolVars) ->
@@ -2451,38 +2226,6 @@ is_safe_bool_expr_list([C|Cs], Sub, BoolVars) ->
end;
is_safe_bool_expr_list([], _, _) -> true.
-%% tuple_to_values(Expr, TupleArity) -> Expr'
-%% Convert tuples in return position of arity TupleArity to values.
-%% Throws an exception for constructs that are not handled.
-
-tuple_to_values(#c_tuple{es=Es}, Arity) when length(Es) =:= Arity ->
- core_lib:make_values(Es);
-tuple_to_values(#c_literal{val=Tuple}=Lit, Arity) when tuple_size(Tuple) =:= Arity ->
- Es = [Lit#c_literal{val=E} || E <- tuple_to_list(Tuple)],
- core_lib:make_values(Es);
-tuple_to_values(#c_case{clauses=Cs0}=Case, Arity) ->
- Cs1 = [tuple_to_values(E, Arity) || E <- Cs0],
- Case#c_case{clauses=Cs1};
-tuple_to_values(#c_seq{body=B0}=Seq, Arity) ->
- Seq#c_seq{body=tuple_to_values(B0, Arity)};
-tuple_to_values(#c_let{body=B0}=Let, Arity) ->
- Let#c_let{body=tuple_to_values(B0, Arity)};
-tuple_to_values(#c_receive{clauses=Cs0,timeout=Timeout,action=A0}=Rec, Arity) ->
- Cs = [tuple_to_values(E, Arity) || E <- Cs0],
- A = case Timeout of
- #c_literal{val=infinity} -> A0;
- _ -> tuple_to_values(A0, Arity)
- end,
- Rec#c_receive{clauses=Cs,action=A};
-tuple_to_values(#c_clause{body=B0}=Clause, Arity) ->
- B = tuple_to_values(B0, Arity),
- Clause#c_clause{body=B};
-tuple_to_values(Expr, _) ->
- case will_fail(Expr) of
- true -> Expr;
- false -> erlang:error({not_handled,Expr})
- end.
-
%% simplify_let(Let, Sub) -> Expr | impossible
%% If the argument part of an let contains a complex expression, such
%% as a let or a sequence, move the original let body into the complex
@@ -2507,9 +2250,9 @@ move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner,
%% in <InnerBody>
%%
Arg = body(Arg0, Sub0),
- ScopeSub0 = sub_subst_scope(Sub0#sub{t=[]}),
+ ScopeSub0 = sub_subst_scope(Sub0#sub{t=#{}}),
{OuterVs,ScopeSub} = pattern_list(OuterVs0, ScopeSub0),
-
+
OuterBody = body(OuterBody0, ScopeSub),
{InnerVs,Sub} = pattern_list(InnerVs0, Sub0),
@@ -2546,15 +2289,15 @@ move_let_into_expr(#c_let{vars=Lvs0,body=Lbody0}=Let,
CaVars0 = Ca0#c_clause.pats,
G0 = Ca0#c_clause.guard,
B0 = Ca0#c_clause.body,
- ScopeSub0 = sub_subst_scope(Sub0#sub{t=[]}),
+ ScopeSub0 = sub_subst_scope(Sub0#sub{t=#{}}),
{CaVars,ScopeSub} = pattern_list(CaVars0, ScopeSub0),
G = guard(G0, ScopeSub),
B1 = body(B0, ScopeSub),
{Lvs,B2,Sub1} = let_substs(Lvs0, B1, Sub0),
- Sub2 = Sub1#sub{s=gb_sets:union(ScopeSub#sub.s,
- Sub1#sub.s)},
+ Sub2 = Sub1#sub{s=cerl_sets:union(ScopeSub#sub.s,
+ Sub1#sub.s)},
Lbody = body(Lbody0, Sub2),
B = Let#c_let{vars=Lvs,arg=core_lib:make_values(B2),body=Lbody},
@@ -2587,88 +2330,257 @@ move_let_into_expr(_Let, _Expr, _Sub) -> impossible.
is_failing_clause(#c_clause{body=B}) ->
will_fail(B).
-scope_add(Vs, #sub{s=Scope0}=Sub) ->
- Scope = foldl(fun(V, S) when is_integer(V); is_atom(V) ->
- gb_sets:add(V, S)
- end, Scope0, Vs),
- Sub#sub{s=Scope}.
+%% opt_case_in_let(Let) -> Let'
+%% Try to avoid building tuples that are immediately matched.
+%% A common pattern is:
+%%
+%% {V1,V2,...} = case E of P -> ... {Val1,Val2,...}; ... end
+%%
+%% In Core Erlang the pattern would look like this:
+%%
+%% let <V> = case E of
+%% ... -> ... {Val1,Val2}
+%% ...
+%% end,
+%% in case V of
+%% {A,B} -> ... <use A and B> ...
+%% end
+%%
+%% Rewrite this to:
+%%
+%% let <V1,V2> = case E of
+%% ... -> ... <Val1,Val2>
+%% ...
+%% end,
+%% in
+%% let <V> = {V1,V2}
+%% in case V of
+%% {A,B} -> ... <use A and B> ...
+%% end
+%%
+%% Note that the second 'case' is unchanged. The other optimizations
+%% in this module will eliminate the building of the tuple and
+%% rewrite the second case to:
+%%
+%% case <V1,V2> of
+%% <A,B> -> ... <use A and B> ...
+%% end
+%%
+
+opt_case_in_let(#c_let{vars=Vs,arg=Arg0,body=B}=Let0) ->
+ case matches_data(Vs, B) of
+ {yes,TypeSig} ->
+ case delay_build(Arg0, TypeSig) of
+ no ->
+ Let0;
+ {yes,Vars,Arg,Data} ->
+ InnerLet = Let0#c_let{arg=Data},
+ Let0#c_let{vars=Vars,arg=Arg,body=InnerLet}
+ end;
+ no ->
+ Let0
+ end.
+
+matches_data([#c_var{name=V}], #c_case{arg=#c_var{name=V},
+ clauses=[#c_clause{pats=[P]}|_]}) ->
+ case cerl:is_data(P) of
+ false ->
+ no;
+ true ->
+ case cerl:data_type(P) of
+ {atomic,_} ->
+ no;
+ Type ->
+ {yes,{Type,cerl:data_arity(P)}}
+ end
+ end;
+matches_data(_, _) -> no.
+
+delay_build(Core, TypeSig) ->
+ case cerl:is_data(Core) of
+ true -> no;
+ false -> delay_build_1(Core, TypeSig)
+ end.
+
+delay_build_1(Core0, TypeSig) ->
+ try delay_build_expr(Core0, TypeSig) of
+ Core ->
+ {Type,Arity} = TypeSig,
+ Ann = [compiler_generated],
+ Vars = make_vars(Ann, Arity),
+ Data = cerl:ann_make_data(Ann, Type, Vars),
+ {yes,Vars,Core,Data}
+ catch
+ throw:impossible ->
+ no
+ end.
+
+delay_build_cs([#c_clause{body=B0}=C0|Cs], TypeSig) ->
+ B = delay_build_expr(B0, TypeSig),
+ C = C0#c_clause{body=B},
+ [C|delay_build_cs(Cs, TypeSig)];
+delay_build_cs([], _) -> [].
+
+delay_build_expr(Core, {Type,Arity}=TypeSig) ->
+ case cerl:is_data(Core) of
+ false ->
+ delay_build_expr_1(Core, TypeSig);
+ true ->
+ case {cerl:data_type(Core),cerl:data_arity(Core)} of
+ {Type,Arity} ->
+ core_lib:make_values(cerl:data_es(Core));
+ {_,_} ->
+ throw(impossible)
+ end
+ end.
+
+delay_build_expr_1(#c_case{clauses=Cs0}=Case, TypeSig) ->
+ Cs = delay_build_cs(Cs0, TypeSig),
+ Case#c_case{clauses=Cs};
+delay_build_expr_1(#c_let{body=B0}=Let, TypeSig) ->
+ B = delay_build_expr(B0, TypeSig),
+ Let#c_let{body=B};
+delay_build_expr_1(#c_receive{clauses=Cs0,
+ timeout=Timeout,
+ action=A0}=Rec, TypeSig) ->
+ Cs = delay_build_cs(Cs0, TypeSig),
+ A = case Timeout of
+ #c_literal{val=infinity} -> A0;
+ _ -> delay_build_expr(A0, TypeSig)
+ end,
+ Rec#c_receive{clauses=Cs,action=A};
+delay_build_expr_1(#c_seq{body=B0}=Seq, TypeSig) ->
+ B = delay_build_expr(B0, TypeSig),
+ Seq#c_seq{body=B};
+delay_build_expr_1(Core, _TypeSig) ->
+ case will_fail(Core) of
+ true -> Core;
+ false -> throw(impossible)
+ end.
%% opt_simple_let(#c_let{}, Context, Sub) -> CoreTerm
%% Optimize a let construct that does not contain any lets in
%% in its argument.
-opt_simple_let(#c_let{arg=Arg0}=Let, Ctxt, Sub0) ->
- Arg = body(Arg0, value, Sub0), %This is a body
+opt_simple_let(Let0, Ctxt, Sub) ->
+ case opt_not_in_let(Let0) of
+ #c_let{}=Let ->
+ opt_simple_let_0(Let, Ctxt, Sub);
+ Expr ->
+ expr(Expr, Ctxt, Sub)
+ end.
+
+opt_simple_let_0(#c_let{arg=Arg0}=Let, Ctxt, Sub) ->
+ Arg = body(Arg0, value, Sub), %This is a body
case will_fail(Arg) of
true -> Arg;
- false -> opt_simple_let_1(Let, Arg, Ctxt, Sub0)
+ false -> opt_simple_let_1(Let, Arg, Ctxt, Sub)
end.
opt_simple_let_1(#c_let{vars=Vs0,body=B0}=Let, Arg0, Ctxt, Sub0) ->
%% Optimise let and add new substitutions.
- {Vs,Args,Sub1} = let_substs(Vs0, Arg0, Sub0),
- BodySub = case {Vs,Args} of
- {[V],[A]} ->
- case is_bool_expr(A, Sub0) of
- true ->
- update_types(V, [#c_literal{val=true}], Sub1);
- false ->
- Sub1
- end;
- {_,_} -> Sub1
- end,
- B = body(B0, Ctxt, BodySub),
- Arg = core_lib:make_values(Args),
- opt_simple_let_2(Let, Vs, Arg, B, Ctxt, Sub1).
-
-opt_simple_let_2(Let0, Vs0, Arg0, Body0, effect, Sub) ->
- case {Vs0,Arg0,Body0} of
- {[],#c_values{es=[]},Body} ->
- %% No variables left (because of substitutions).
- Body;
- {[_|_],Arg,#c_literal{}} ->
- %% The body is a literal. That means that we can ignore
- %% it and that the return value is Arg revisited in
- %% effect context.
- body(Arg, effect, sub_new_preserve_types(Sub));
- {Vs,Arg,Body} ->
- %% Since we are in effect context, there is a chance
- %% that the body no longer references the variables.
- %% In that case we can construct a sequence and visit
- %% that in effect context:
- %% let <Var> = Arg in BodyWithoutVar ==> seq Arg BodyWithoutVar
- case is_any_var_used(Vs, Body) of
- false ->
- expr(#c_seq{arg=Arg,body=Body}, effect, sub_new_preserve_types(Sub));
- true ->
- Let = Let0#c_let{vars=Vs,arg=Arg,body=Body},
- opt_case_in_let_arg(opt_case_in_let(Let, Sub), effect, Sub)
- end
- end;
-opt_simple_let_2(Let, Vs0, Arg0, Body, value, Sub) ->
+ {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),
+ opt_simple_let_2(Let, Vs, Arg, B, B0, Ctxt, Sub1).
+
+opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
case {Vs0,Arg0,Body} of
- {[#c_var{name=N1}],Arg,#c_var{name=N2}} ->
+ {[#c_var{name=N1}],Arg1,#c_var{name=N2}} ->
case N1 =:= N2 of
true ->
%% let <Var> = Arg in <Var> ==> Arg
- Arg;
+ Arg1;
false ->
%% let <Var> = Arg in <OtherVar> ==> seq Arg OtherVar
- expr(#c_seq{arg=Arg,body=Body}, value, sub_new_preserve_types(Sub))
+ Arg = maybe_suppress_warnings(Arg1, Vs0, PrevBody),
+ expr(#c_seq{arg=Arg,body=Body}, Ctxt,
+ sub_new_preserve_types(Sub))
end;
{[],#c_values{es=[]},_} ->
%% No variables left.
Body;
- {_,Arg,#c_literal{}} ->
- %% The variable is not used in the body. The argument
- %% can be evaluated in effect context to simplify it.
- expr(#c_seq{arg=Arg,body=Body}, value, sub_new_preserve_types(Sub));
- {Vs,Arg,Body} ->
- opt_case_in_let_arg(
- opt_case_in_let(Let#c_let{vars=Vs,arg=Arg,body=Body}, Sub),
- value, Sub)
+ {Vs,Arg1,#c_literal{}} ->
+ Arg = maybe_suppress_warnings(Arg1, Vs, PrevBody),
+ E = case Ctxt of
+ effect ->
+ %% Throw away the literal body.
+ Arg;
+ value ->
+ %% Since the variable is not used in the body, we
+ %% can rewrite the let to a sequence.
+ %% let <Var> = Arg in Literal ==> seq Arg Literal
+ #c_seq{arg=Arg,body=Body}
+ end,
+ expr(E, Ctxt, sub_new_preserve_types(Sub));
+ {Vs,Arg1,Body} ->
+ %% If none of the variables are used in the body, we can
+ %% rewrite the let to a sequence:
+ %% let <Var> = Arg in BodyWithoutVar ==>
+ %% seq Arg BodyWithoutVar
+ case is_any_var_used(Vs, Body) of
+ false ->
+ Arg = maybe_suppress_warnings(Arg1, Vs, PrevBody),
+ expr(#c_seq{arg=Arg,body=Body}, Ctxt,
+ sub_new_preserve_types(Sub));
+ true ->
+ Let1 = Let0#c_let{vars=Vs,arg=Arg1,body=Body},
+ Let2 = opt_bool_case_in_let(Let1, Sub),
+ opt_case_in_let_arg(Let2, Ctxt, Sub)
+ end
end.
+%% maybe_suppress_warnings(Arg, [#c_var{}], PreviousBody) -> Arg'
+%% Try to suppress false warnings when a variable is not used.
+%% For instance, we don't expect a warning for useless building in:
+%%
+%% R = #r{}, %No warning expected.
+%% R#r.f %Optimization would remove the reference to R.
+%%
+%% To avoid false warnings, we will check whether the variables were
+%% referenced in the original unoptimized code. If they were, we will
+%% consider the warning false and suppress it.
+
+maybe_suppress_warnings(Arg, Vs, PrevBody) ->
+ case should_suppress_warning(Arg) of
+ true ->
+ Arg; %Already suppressed.
+ false ->
+ case is_any_var_used(Vs, PrevBody) of
+ true ->
+ suppress_warning([Arg]);
+ false ->
+ Arg
+ end
+ end.
+
+%% Suppress warnings for a Core Erlang expression whose value will
+%% be ignored.
+suppress_warning([H|T]) ->
+ case cerl:is_literal(H) of
+ true ->
+ suppress_warning(T);
+ false ->
+ case cerl:is_data(H) of
+ true ->
+ suppress_warning(cerl:data_es(H) ++ T);
+ false ->
+ %% Some other thing, such as a function call.
+ %% This cannot be the compiler's fault, so the
+ %% warning should not be suppressed. We must
+ %% be careful not to destroy tail-recursion.
+ case T of
+ [] ->
+ H;
+ [_|_] ->
+ cerl:c_seq(H, suppress_warning(T))
+ end
+ end
+ end;
+suppress_warning([]) -> void().
+
move_case_into_arg(#c_case{arg=#c_let{vars=OuterVars0,arg=OuterArg,
body=InnerArg0}=Outer,
clauses=InnerClauses}=Inner, Sub) ->
@@ -2682,7 +2594,7 @@ move_case_into_arg(#c_case{arg=#c_let{vars=OuterVars0,arg=OuterArg,
%% let <OuterVars> = <OuterArg>
%% in case <InnerArg> of <InnerClauses> end
%%
- ScopeSub0 = sub_subst_scope(Sub#sub{t=[]}),
+ ScopeSub0 = sub_subst_scope(Sub#sub{t=#{}}),
{OuterVars,ScopeSub} = pattern_list(OuterVars0, ScopeSub0),
InnerArg = body(InnerArg0, ScopeSub),
Outer#c_let{vars=OuterVars,arg=OuterArg,
@@ -2711,7 +2623,7 @@ move_case_into_arg(#c_case{arg=#c_case{arg=OuterArg,
%% <OuterCb>
%% end
%%
- ScopeSub0 = sub_subst_scope(Sub#sub{t=[]}),
+ ScopeSub0 = sub_subst_scope(Sub#sub{t=#{}}),
{OuterPats,ScopeSub} = pattern_list(OuterPats0, ScopeSub0),
OuterGuard = guard(OuterGuard0, ScopeSub),
InnerArg = body(InnerArg0, ScopeSub),
@@ -2756,7 +2668,7 @@ move_case_into_arg(_, _) ->
%% <> 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
@@ -2789,14 +2701,114 @@ is_any_var_used([#c_var{name=V}|Vs], Expr) ->
end;
is_any_var_used([], _) -> false.
-is_boolean_type(V, #sub{t=Tdb}) ->
- case orddict:find(V, Tdb) of
- {ok,bool} -> true;
- _ -> false
+%%%
+%%% Retrieving information about types.
+%%%
+
+-spec get_type(cerl:cerl(), #sub{}) -> type_info() | 'none'.
+
+get_type(#c_var{name=V}, #sub{t=Tdb}) ->
+ case Tdb of
+ #{V:=Type} -> Type;
+ _ -> none
+ end;
+get_type(C, _) ->
+ case cerl:type(C) of
+ binary -> C;
+ map -> C;
+ _ ->
+ case cerl:is_data(C) of
+ true -> C;
+ false -> none
+ end
+ end.
+
+-spec is_boolean_type(cerl:cerl(), sub()) -> yes_no_maybe().
+
+is_boolean_type(Var, Sub) ->
+ case get_type(Var, Sub) of
+ none ->
+ maybe;
+ bool ->
+ yes;
+ C ->
+ B = cerl:is_c_atom(C) andalso
+ is_boolean(cerl:atom_val(C)),
+ yes_no(B)
+ end.
+
+-spec is_int_type(cerl:cerl(), sub()) -> yes_no_maybe().
+
+is_int_type(Var, Sub) ->
+ case get_type(Var, Sub) of
+ none -> maybe;
+ integer -> yes;
+ C -> yes_no(cerl:is_c_int(C))
+ end.
+
+-spec is_tuple_type(cerl:cerl(), sub()) -> yes_no_maybe().
+
+is_tuple_type(Var, Sub) ->
+ case get_type(Var, Sub) of
+ none -> maybe;
+ C -> yes_no(cerl:is_c_tuple(C))
end.
+yes_no(true) -> yes;
+yes_no(false) -> no.
+
+%%%
+%%% Update type information.
+%%%
+
+update_let_types(Vs, Args, Sub) when is_list(Args) ->
+ update_let_types_1(Vs, Args, Sub);
+update_let_types(_Vs, _Arg, Sub) ->
+ %% The argument is a complex expression (such as a 'case')
+ %% that returns multiple values.
+ Sub.
+
+update_let_types_1([#c_var{}=V|Vs], [A|As], Sub0) ->
+ Sub = update_types_from_expr(V, A, Sub0),
+ update_let_types_1(Vs, As, Sub);
+update_let_types_1([], [], Sub) -> Sub.
+
+update_types_from_expr(V, Expr, Sub) ->
+ Type = extract_type(Expr, Sub),
+ update_types(V, [Type], Sub).
+
+extract_type(#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=Name},
+ args=Args}=Call, Sub) ->
+ case returns_integer(Name, Args) of
+ true -> integer;
+ false -> extract_type_1(Call, Sub)
+ end;
+extract_type(Expr, Sub) ->
+ extract_type_1(Expr, Sub).
+
+extract_type_1(Expr, Sub) ->
+ case is_bool_expr(Expr, Sub) of
+ false -> Expr;
+ true -> bool
+ end.
+
+returns_integer(bit_size, [_]) -> true;
+returns_integer('bsl', [_,_]) -> true;
+returns_integer('bsr', [_,_]) -> true;
+returns_integer(byte_size, [_]) -> true;
+returns_integer(length, [_]) -> true;
+returns_integer('rem', [_,_]) -> true;
+returns_integer(size, [_]) -> true;
+returns_integer(tuple_size, [_]) -> true;
+returns_integer(trunc, [_]) -> true;
+returns_integer(_, _) -> false.
+
%% update_types(Expr, Pattern, Sub) -> Sub'
%% Update the type database.
+
+-spec update_types(cerl:cerl(), [type_info()], sub()) -> sub().
+
update_types(Expr, Pat, #sub{t=Tdb0}=Sub) ->
Tdb = update_types_1(Expr, Pat, Tdb0),
Sub#sub{t=Tdb}.
@@ -2813,33 +2825,38 @@ update_types_1(#c_var{name=V,anno=Anno}, Pat, Types) ->
update_types_1(_, _, Types) -> Types.
update_types_2(V, [#c_tuple{}=P], Types) ->
- orddict:store(V, P, Types);
+ Types#{V=>P};
update_types_2(V, [#c_literal{val=Bool}], Types) when is_boolean(Bool) ->
- orddict:store(V, bool, Types);
+ Types#{V=>bool};
+update_types_2(V, [Type], Types) when is_atom(Type) ->
+ Types#{V=>Type};
update_types_2(_, _, Types) -> Types.
%% kill_types(V, Tdb) -> Tdb'
%% Kill any entries that references the variable,
%% either in the key or in the value.
-kill_types(V, [{V,_}|Tdb]) ->
- kill_types(V, Tdb);
-kill_types(V, [{_,#c_tuple{}=Tuple}=Entry|Tdb]) ->
+kill_types(V, Tdb) ->
+ maps:from_list(kill_types2(V,maps:to_list(Tdb))).
+
+kill_types2(V, [{V,_}|Tdb]) ->
+ kill_types2(V, Tdb);
+kill_types2(V, [{_,#c_tuple{}=Tuple}=Entry|Tdb]) ->
case core_lib:is_var_used(V, Tuple) of
- false -> [Entry|kill_types(V, Tdb)];
- true -> kill_types(V, Tdb)
+ false -> [Entry|kill_types2(V, Tdb)];
+ true -> kill_types2(V, Tdb)
end;
-kill_types(V, [{_,Atom}=Entry|Tdb]) when is_atom(Atom) ->
- [Entry|kill_types(V, Tdb)];
-kill_types(_, []) -> [].
+kill_types2(V, [{_,Atom}=Entry|Tdb]) when is_atom(Atom) ->
+ [Entry|kill_types2(V, Tdb)];
+kill_types2(_, []) -> [].
%% copy_type(DestVar, SrcVar, Tdb) -> Tdb'
%% If the SrcVar has a type, assign it to DestVar.
%%
copy_type(V, #c_var{name=Src}, Tdb) ->
- case orddict:find(Src, Tdb) of
- {ok,Type} -> orddict:store(V, Type, Tdb);
- error -> Tdb
+ case Tdb of
+ #{Src:=Type} -> Tdb#{V=>Type};
+ _ -> Tdb
end;
copy_type(_, _, Tdb) -> Tdb.
@@ -3074,15 +3091,15 @@ bsm_ensure_no_partition_2([#c_var{name=V}|Ps], N, G, Vstate, S) ->
bsm_ensure_no_partition_2([_|Ps], N, G, _, S) ->
bsm_ensure_no_partition_2(Ps, N-1, G, bin_argument_order, S).
-bsm_ensure_no_partition_after([#c_clause{pats=Ps}|Cs], Pos) ->
+bsm_ensure_no_partition_after([#c_clause{pats=Ps}=C|Cs], Pos) ->
case nth(Pos, Ps) of
#c_var{} ->
bsm_ensure_no_partition_after(Cs, Pos);
- P ->
- bsm_problem(P, bin_partition)
+ _ ->
+ bsm_problem(C, bin_partition)
end;
bsm_ensure_no_partition_after([], _) -> ok.
-
+
bsm_could_match_binary(#c_alias{pat=P}) -> bsm_could_match_binary(P);
bsm_could_match_binary(#c_cons{}) -> false;
bsm_could_match_binary(#c_tuple{}) -> false;
@@ -3116,11 +3133,11 @@ add_bin_opt_info(Core, Term) ->
end.
add_warning(Core, Term) ->
- case is_compiler_generated(Core) of
+ case should_suppress_warning(Core) of
true ->
ok;
false ->
- Anno = core_lib:get_anno(Core),
+ Anno = cerl:get_ann(Core),
Line = get_line(Anno),
File = get_file(Anno),
Key = {?MODULE,warnings},
@@ -3141,9 +3158,17 @@ get_file([{file,File}|_]) -> File;
get_file([_|T]) -> get_file(T);
get_file([]) -> "no_file". % should not happen
+should_suppress_warning(Core) ->
+ is_compiler_generated(Core) orelse
+ is_result_unwanted(Core).
+
is_compiler_generated(Core) ->
- Anno = core_lib:get_anno(Core),
- member(compiler_generated, Anno).
+ Ann = cerl:get_ann(Core),
+ member(compiler_generated, Ann).
+
+is_result_unwanted(Core) ->
+ Ann = cerl:get_ann(Core),
+ member(result_not_wanted, Ann).
get_warnings() ->
ordsets:from_list((erase({?MODULE,warnings}))).
@@ -3235,12 +3260,12 @@ format_error(bin_var_used_in_guard) ->
verify_scope(E, #sub{s=Scope}) ->
Free0 = cerl_trees:free_variables(E),
Free = [V || V <- Free0, not is_tuple(V)], %Ignore function names.
- case ordsets:is_subset(Free, gb_sets:to_list(Scope)) of
+ case ordsets:is_subset(Free, cerl_sets:to_list(Scope)) of
true -> true;
false ->
io:format("~p\n", [E]),
io:format("~p\n", [Free]),
- io:format("~p\n", [gb_sets:to_list(Scope)]),
+ io:format("~p\n", [cerl_sets:to_list(Scope)]),
false
end.
-endif.
diff --git a/lib/compiler/src/sys_core_fold_lists.erl b/lib/compiler/src/sys_core_fold_lists.erl
new file mode 100644
index 0000000000..9867fab46a
--- /dev/null
+++ b/lib/compiler/src/sys_core_fold_lists.erl
@@ -0,0 +1,387 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+%% Purpose : Inline high order lists functions from the lists module.
+
+-module(sys_core_fold_lists).
+
+-export([call/4]).
+
+-include("core_parse.hrl").
+
+%% We inline some very common higher order list operations.
+%% We use the same evaluation order as the library function.
+
+-spec call(cerl:c_call(), atom(), atom(), [cerl:cerl()]) ->
+ 'none' | cerl:cerl().
+
+call(#c_call{anno=Anno}, lists, all, [Arg1,Arg2]) ->
+ Loop = #c_var{name={'lists^all',1}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
+ CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
+ body=#c_apply{anno=Anno, op=Loop, args=[Xs]}},
+ CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
+ body=#c_literal{val=false}},
+ CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
+ body=match_fail(Anno, Err1)},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]},
+ clauses = [CC1, CC2, CC3]}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
+ body=#c_literal{val=true}},
+ Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^all',1}}|Anno], Err2)},
+ Fun = #c_fun{vars=[Xs],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L]}}};
+call(#c_call{anno=Anno}, lists, any, [Arg1,Arg2]) ->
+ Loop = #c_var{name={'lists^any',1}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
+ CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
+ body=#c_literal{val=true}},
+ CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
+ body=#c_apply{anno=Anno, op=Loop, args=[Xs]}},
+ CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
+ body=match_fail(Anno, Err1)},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]},
+ clauses = [CC1, CC2, CC3]}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
+ body=#c_literal{val=false}},
+ Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^any',1}}|Anno], Err2)},
+ Fun = #c_fun{vars=[Xs],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L]}}};
+call(#c_call{anno=Anno}, lists, foreach, [Arg1,Arg2]) ->
+ Loop = #c_var{name={'lists^foreach',1}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_seq{arg=#c_apply{anno=Anno, op=F, args=[X]},
+ body=#c_apply{anno=Anno, op=Loop, args=[Xs]}}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
+ body=#c_literal{val=ok}},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^foreach',1}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L]}}};
+call(#c_call{anno=Anno}, lists, map, [Arg1,Arg2]) ->
+ Loop = #c_var{name={'lists^map',1}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ H = #c_var{name='H'},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_let{vars=[H], arg=#c_apply{anno=Anno,
+ op=F,
+ args=[X]},
+ body=#c_cons{hd=H,
+ anno=[compiler_generated],
+ tl=#c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs]}}}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
+ body=#c_literal{val=[]}},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^map',1}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L]}}};
+call(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2]) ->
+ Loop = #c_var{name={'lists^flatmap',1}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ H = #c_var{name='H'},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_let{vars=[H],
+ arg=#c_apply{anno=Anno, op=F, args=[X]},
+ body=#c_call{anno=[compiler_generated|Anno],
+ module=#c_literal{val=erlang},
+ name=#c_literal{val='++'},
+ args=[H,
+ #c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs]}]}}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
+ body=#c_literal{val=[]}},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^flatmap',1}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L]}}};
+call(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2]) ->
+ Loop = #c_var{name={'lists^filter',1}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ B = #c_var{name='B'},
+ Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
+ CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
+ body=#c_cons{anno=[compiler_generated], hd=X, tl=Xs}},
+ CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
+ body=Xs},
+ CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
+ body=match_fail(Anno, Err1)},
+ Case = #c_case{arg=B, clauses = [CC1, CC2, CC3]},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_let{vars=[B],
+ arg=#c_apply{anno=Anno, op=F, args=[X]},
+ body=#c_let{vars=[Xs],
+ arg=#c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs]},
+ body=Case}}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
+ body=#c_literal{val=[]}},
+ Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^filter',1}}|Anno], Err2)},
+ Fun = #c_fun{vars=[Xs],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, L], arg=#c_values{es=[Arg1, Arg2]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L]}}};
+call(#c_call{anno=Anno}, lists, foldl, [Arg1,Arg2,Arg3]) ->
+ Loop = #c_var{name={'lists^foldl',2}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ A = #c_var{name='A'},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs, #c_apply{anno=Anno,
+ op=F,
+ args=[X, A]}]}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
+ body=A},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^foldl',2}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs, A],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, A, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L, A]}}};
+call(#c_call{anno=Anno}, lists, foldr, [Arg1,Arg2,Arg3]) ->
+ Loop = #c_var{name={'lists^foldr',2}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ A = #c_var{name='A'},
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=#c_apply{anno=Anno,
+ op=F,
+ args=[X, #c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs, A]}]}},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
+ body=A},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^foldr',2}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs, A],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, A, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+ body=#c_apply{anno=Anno, op=Loop, args=[L, A]}}};
+call(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3]) ->
+ Loop = #c_var{name={'lists^mapfoldl',2}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ Avar = #c_var{name='A'},
+ Match =
+ fun (A, P, E) ->
+ C1 = #c_clause{pats=[P], guard=#c_literal{val=true}, body=E},
+ Err = #c_tuple{es=[#c_literal{val='badmatch'}, X]},
+ C2 = #c_clause{pats=[X], guard=#c_literal{val=true},
+ body=match_fail(Anno, Err)},
+ #c_case{arg=A, clauses=[C1, C2]}
+ end,
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+ body=Match(#c_apply{anno=Anno, op=F, args=[X, Avar]},
+ #c_tuple{es=[X, Avar]},
+%%% Tuple passing version
+ Match(#c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs, Avar]},
+ #c_tuple{es=[Xs, Avar]},
+ #c_tuple{anno=[compiler_generated],
+ es=[#c_cons{anno=[compiler_generated],
+ hd=X, tl=Xs},
+ Avar]})
+%%% Multiple-value version
+%%% #c_let{vars=[Xs,A],
+%%% %% The tuple here will be optimised
+%%% %% away later; no worries.
+%%% arg=#c_apply{op=Loop, args=[Xs, A]},
+%%% body=#c_values{es=[#c_cons{hd=X, tl=Xs},
+%%% A]}}
+ )},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
+%%% Tuple passing version
+ body=#c_tuple{anno=[compiler_generated],
+ es=[#c_literal{val=[]}, Avar]}},
+%%% Multiple-value version
+%%% body=#c_values{es=[#c_literal{val=[]}, A]}},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^mapfoldl',2}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs, Avar],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, Avar, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+%%% Tuple passing version
+ body=#c_apply{anno=Anno,
+ op=Loop,
+ args=[L, Avar]}}};
+%%% Multiple-value version
+%%% body=#c_let{vars=[Xs, A],
+%%% arg=#c_apply{op=Loop,
+%%% args=[L, A]},
+%%% body=#c_tuple{es=[Xs, A]}}}};
+call(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3]) ->
+ Loop = #c_var{name={'lists^mapfoldr',2}},
+ F = #c_var{name='F'},
+ Xs = #c_var{name='Xs'},
+ X = #c_var{name='X'},
+ Avar = #c_var{name='A'},
+ Match =
+ fun (A, P, E) ->
+ C1 = #c_clause{pats=[P], guard=#c_literal{val=true}, body=E},
+ Err = #c_tuple{es=[#c_literal{val='badmatch'}, X]},
+ C2 = #c_clause{pats=[X], guard=#c_literal{val=true},
+ body=match_fail(Anno, Err)},
+ #c_case{arg=A, clauses=[C1, C2]}
+ end,
+ C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
+%%% Tuple passing version
+ body=Match(#c_apply{anno=Anno,
+ op=Loop,
+ args=[Xs, Avar]},
+ #c_tuple{es=[Xs, Avar]},
+ Match(#c_apply{anno=Anno, op=F, args=[X, Avar]},
+ #c_tuple{es=[X, Avar]},
+ #c_tuple{anno=[compiler_generated],
+ es=[#c_cons{anno=[compiler_generated],
+ hd=X, tl=Xs}, Avar]}))
+%%% Multiple-value version
+%%% body=#c_let{vars=[Xs,A],
+%%% %% The tuple will be optimised away
+%%% arg=#c_apply{op=Loop, args=[Xs, A]},
+%%% body=Match(#c_apply{op=F, args=[X, A]},
+%%% #c_tuple{es=[X, A]},
+%%% #c_values{es=[#c_cons{hd=X, tl=Xs},
+%%% A]})}
+ },
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
+%%% Tuple passing version
+ body=#c_tuple{anno=[compiler_generated],
+ es=[#c_literal{val=[]}, Avar]}},
+%%% Multiple-value version
+%%% body=#c_values{es=[#c_literal{val=[]}, A]}},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]},
+ C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
+ body=match_fail([{function_name,{'lists^mapfoldr',2}}|Anno], Err)},
+ Fun = #c_fun{vars=[Xs, Avar],
+ body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
+ L = #c_var{name='L'},
+ #c_let{vars=[F, Avar, L], arg=#c_values{es=[Arg1, Arg2, Arg3]},
+ body=#c_letrec{defs=[{Loop,Fun}],
+%%% Tuple passing version
+ body=#c_apply{anno=Anno,
+ op=Loop,
+ args=[L, Avar]}}};
+%%% Multiple-value version
+%%% body=#c_let{vars=[Xs, A],
+%%% arg=#c_apply{op=Loop,
+%%% args=[L, A]},
+%%% body=#c_tuple{es=[Xs, A]}}}};
+call(_, _, _, _) ->
+ none.
+
+match_fail(Ann, Arg) ->
+ Name = cerl:abstract(match_fail),
+ Args = [Arg],
+ cerl:ann_c_primop(Ann, Name, Args).
diff --git a/lib/compiler/src/sys_core_inline.erl b/lib/compiler/src/sys_core_inline.erl
index 9f93acb666..838dda68c6 100644
--- a/lib/compiler/src/sys_core_inline.erl
+++ b/lib/compiler/src/sys_core_inline.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -195,10 +196,10 @@ kill_id_anns(Body) ->
A = kill_id_anns_1(A0),
CFun#c_fun{anno=A};
(Expr) ->
- %% Mark everything as compiler generated to suppress
- %% bogus warnings.
- A = compiler_generated(core_lib:get_anno(Expr)),
- core_lib:set_anno(Expr, A)
+ %% Mark everything as compiler generated to
+ %% suppress bogus warnings.
+ A = compiler_generated(cerl:get_ann(Expr)),
+ cerl:set_ann(Expr, A)
end, Body).
kill_id_anns_1([{'id',_}|As]) ->
diff --git a/lib/compiler/src/sys_pre_attributes.erl b/lib/compiler/src/sys_pre_attributes.erl
index a6b7274b07..f0cb630205 100644
--- a/lib/compiler/src/sys_pre_attributes.erl
+++ b/lib/compiler/src/sys_pre_attributes.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
index 761ae8409c..d9cc4b530c 100644
--- a/lib/compiler/src/sys_pre_expand.erl
+++ b/lib/compiler/src/sys_pre_expand.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,19 +34,19 @@
-include("../include/erl_bits.hrl").
+-type fa() :: {atom(), arity()}.
+
-record(expand, {module=[], %Module name
exports=[], %Exports
imports=[], %Imports
- compile=[], %Compile flags
attributes=[], %Attributes
callbacks=[], %Callbacks
+ optional_callbacks=[] :: [fa()], %Optional callbacks
defined, %Defined functions (gb_set)
vcount=0, %Variable counter
func=[], %Current function
arity=[], %Arity for current function
- fcount=0, %Local fun count
- bitdefault,
- bittypes
+ fcount=0 %Local fun count
}).
%% module(Forms, CompileOptions)
@@ -66,15 +67,12 @@ module(Fs0, Opts0) ->
%% Build initial expand record.
St0 = #expand{exports=PreExp,
- compile=Opts,
- defined=PreExp,
- bitdefault = erl_bits:system_bitdefault(),
- bittypes = erl_bits:system_bittypes()
+ defined=PreExp
},
%% Expand the functions.
{Tfs,St1} = forms(Fs, define_functions(Fs, St0)),
%% Get the correct list of exported functions.
- Exports = case member(export_all, St1#expand.compile) of
+ Exports = case member(export_all, Opts) of
true -> gb_sets:to_list(St1#expand.defined);
false -> St1#expand.exports
end,
@@ -82,7 +80,7 @@ module(Fs0, Opts0) ->
{Ats,St3} = module_attrs(St1#expand{exports = Exports}),
{Mfs,St4} = module_predef_funcs(St3),
{St4#expand.module, St4#expand.exports, Ats ++ Tfs ++ Mfs,
- St4#expand.compile}.
+ Opts}.
compiler_options(Forms) ->
lists:flatten([C || {attribute,_,compile,C} <- Forms]).
@@ -99,28 +97,48 @@ define_functions(Forms, #expand{defined=Predef}=St) ->
module_attrs(#expand{attributes=Attributes}=St) ->
Attrs = [{attribute,Line,Name,Val} || {Name,Line,Val} <- Attributes],
Callbacks = [Callback || {_,_,callback,_}=Callback <- Attrs],
- {Attrs,St#expand{callbacks=Callbacks}}.
+ OptionalCallbacks = get_optional_callbacks(Attrs),
+ {Attrs,St#expand{callbacks=Callbacks,
+ optional_callbacks=OptionalCallbacks}}.
+
+get_optional_callbacks(Attrs) ->
+ L = [O ||
+ {attribute, _, optional_callbacks, O} <- Attrs,
+ is_fa_list(O)],
+ lists:append(L).
+
+is_fa_list([{FuncName, Arity}|L])
+ when is_atom(FuncName), is_integer(Arity), Arity >= 0 ->
+ is_fa_list(L);
+is_fa_list([]) -> true;
+is_fa_list(_) -> false.
module_predef_funcs(St) ->
{Mpf1,St1}=module_predef_func_beh_info(St),
{Mpf2,St2}=module_predef_funcs_mod_info(St1),
- {Mpf1++Mpf2,St2}.
+ Mpf = [erl_parse:new_anno(F) || F <- Mpf1++Mpf2],
+ {Mpf,St2}.
module_predef_func_beh_info(#expand{callbacks=[]}=St) ->
{[], St};
-module_predef_func_beh_info(#expand{callbacks=Callbacks,defined=Defined,
+module_predef_func_beh_info(#expand{callbacks=Callbacks,
+ optional_callbacks=OptionalCallbacks,
+ defined=Defined,
exports=Exports}=St) ->
PreDef=[{behaviour_info,1}],
PreExp=PreDef,
- {[gen_beh_info(Callbacks)],
+ {[gen_beh_info(Callbacks, OptionalCallbacks)],
St#expand{defined=gb_sets:union(gb_sets:from_list(PreDef), Defined),
exports=union(from_list(PreExp), Exports)}}.
-gen_beh_info(Callbacks) ->
+gen_beh_info(Callbacks, OptionalCallbacks) ->
List = make_list(Callbacks),
+ OptionalList = make_optional_list(OptionalCallbacks),
{function,0,behaviour_info,1,
[{clause,0,[{atom,0,callbacks}],[],
- [List]}]}.
+ [List]},
+ {clause,0,[{atom,0,optional_callbacks}],[],
+ [OptionalList]}]}.
make_list([]) -> {nil,0};
make_list([{_,_,_,[{{Name,Arity},_}]}|Rest]) ->
@@ -130,6 +148,14 @@ make_list([{_,_,_,[{{Name,Arity},_}]}|Rest]) ->
{integer,0,Arity}]},
make_list(Rest)}.
+make_optional_list([]) -> {nil,0};
+make_optional_list([{Name,Arity}|Rest]) ->
+ {cons,0,
+ {tuple,0,
+ [{atom,0,Name},
+ {integer,0,Arity}]},
+ make_optional_list(Rest)}.
+
module_predef_funcs_mod_info(St) ->
PreDef = [{module_info,0},{module_info,1}],
PreExp = PreDef,
@@ -232,9 +258,18 @@ pattern({map,Line,Ps}, St0) ->
{TPs,St1} = pattern_list(Ps, St0),
{{map,Line,TPs},St1};
pattern({map_field_exact,Line,K0,V0}, St0) ->
- {K,St1} = expr(K0, St0),
+ %% Key should be treated as an expression
+ %% but since expressions are not allowed yet,
+ %% process it through pattern .. and handle assoc
+ %% (normalise unary op integer -> integer)
+ {K,St1} = pattern(K0, St0),
{V,St2} = pattern(V0, St1),
{{map_field_exact,Line,K,V},St2};
+pattern({map_field_assoc,Line,K0,V0}, St0) ->
+ %% when keys are Maps
+ {K,St1} = pattern(K0, St0),
+ {V,St2} = pattern(V0, St1),
+ {{map_field_assoc,Line,K,V},St2};
%%pattern({struct,Line,Tag,Ps}, St0) ->
%% {TPs,TPsvs,St1} = pattern_list(Ps, St0),
%% {{tuple,Line,[{atom,Line,Tag}|TPs]},TPsvs,St1};
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl
index 47a357c23d..2a89305f4d 100644
--- a/lib/compiler/src/v3_codegen.erl
+++ b/lib/compiler/src/v3_codegen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -43,7 +44,7 @@
-export([module/2]).
-import(lists, [member/2,keymember/3,keysort/2,keydelete/3,
- append/1,map/2,flatmap/2,filter/2,foldl/3,foldr/3,mapfoldl/3,
+ append/1,flatmap/2,filter/2,foldl/3,foldr/3,mapfoldl/3,
sort/1,reverse/1,reverse/2]).
-import(v3_life, [vdb_find/2]).
@@ -57,8 +58,7 @@
break, %Break label
recv, %Receive label
is_top_block, %Boolean: top block or not
- functable=gb_trees:empty(), %Gb tree of local functions:
- % {{Name,Arity},Label}
+ functable=#{}, %Map of local functions: {Name,Arity}=>Label
in_catch=false, %Inside a catch or not.
need_frame, %Need a stack frame.
ultimate_failure %Label for ultimate match failure.
@@ -69,10 +69,8 @@
stk=[], %Stack table
res=[]}). %Reserved regs: [{reserved,I,V}]
-module({Mod,Exp,Attr,Forms}, Options) ->
- put(?MODULE, Options),
+module({Mod,Exp,Attr,Forms}, _Options) ->
{Fs,St} = functions(Forms, {atom,Mod}),
- erase(?MODULE),
{ok,{Mod,Exp,Attr,Fs,St#cg.lcount}}.
functions(Forms, AtomMod) ->
@@ -123,24 +121,15 @@ cg_fun(Les, Hvs, Vdb, AtomMod, NameArity, Anno, St0) ->
put_reg(V, Reg)
end, [], Hvs),
stk=[]}, 0, Vdb),
- {B0,_Aft,St} = cg_list(Les, 0, Vdb, Bef,
+ {B,_Aft,St} = cg_list(Les, 0, Vdb, Bef,
St3#cg{bfail=0,
ultimate_failure=UltimateMatchFail,
is_top_block=true}),
- B = fix_bs_match_strings(B0),
{Name,Arity} = NameArity,
Asm = [{label,Fi},line(Anno),{func_info,AtomMod,{atom,Name},Arity},
{label,Fl}|B++[{label,UltimateMatchFail},if_end]],
{Asm,Fl,St}.
-fix_bs_match_strings([{test,bs_match_string,F,[Ctx,BinList]}|Is])
- when is_list(BinList) ->
- I = {test,bs_match_string,F,[Ctx,list_to_bitstring(BinList)]},
- [I|fix_bs_match_strings(Is)];
-fix_bs_match_strings([I|Is]) ->
- [I|fix_bs_match_strings(Is)];
-fix_bs_match_strings([]) -> [].
-
%% cg(Lkexpr, Vdb, StackReg, State) -> {[Ainstr],StackReg,State}.
%% Generate code for a kexpr.
%% Split function into two steps for clarity, not efficiency.
@@ -210,7 +199,7 @@ need_heap_0([], H, Acc) ->
need_heap_1(#l{ke={set,_,{binary,_}},i=I}, H) ->
{need_heap_need(I, H),0};
-need_heap_1(#l{ke={set,_,{map,_,_}},i=I}, H) ->
+need_heap_1(#l{ke={set,_,{map,_,_,_}},i=I}, H) ->
{need_heap_need(I, H),0};
need_heap_1(#l{ke={set,_,Val}}, H) ->
%% Just pass through adding to needed heap.
@@ -586,7 +575,7 @@ top_level_block(Keis, Bef, MaxRegs, _St) ->
(return) ->
[{deallocate,FrameSz},return];
(Tuple) when is_tuple(Tuple) ->
- [turn_yregs(tuple_size(Tuple), Tuple, MaxY)];
+ [turn_yregs(Tuple, MaxY)];
(Other) ->
[Other]
end, Keis),
@@ -598,14 +587,49 @@ top_level_block(Keis, Bef, MaxRegs, _St) ->
%% catches work. The code generation algorithm gives a lower register
%% number to the outer catch, which is wrong.
-turn_yregs(0, Tp, _) -> Tp;
-turn_yregs(El, Tp, MaxY) ->
- turn_yregs(El-1,setelement(El,Tp,turn_yreg(element(El,Tp),MaxY)),MaxY).
-
-turn_yreg({yy,YY},MaxY) -> {y,MaxY-YY};
-turn_yreg({list,Ls},MaxY) -> {list, turn_yreg(Ls,MaxY)};
-turn_yreg(Ts,MaxY) when is_list(Ts) -> [turn_yreg(T,MaxY)||T<-Ts];
-turn_yreg(Other,_MaxY) -> Other.
+turn_yregs({call,_,_}=I, _MaxY) -> I;
+turn_yregs({call_ext,_,_}=I, _MaxY) -> I;
+turn_yregs({jump,_}=I, _MaxY) -> I;
+turn_yregs({label,_}=I, _MaxY) -> I;
+turn_yregs({line,_}=I, _MaxY) -> I;
+turn_yregs({test_heap,_,_}=I, _MaxY) -> I;
+turn_yregs({bif,Op,F,A,B}, MaxY) ->
+ {bif,Op,F,turn_yreg(A, MaxY),turn_yreg(B, MaxY)};
+turn_yregs({gc_bif,Op,F,Live,A,B}, MaxY) when is_integer(Live) ->
+ {gc_bif,Op,F,Live,turn_yreg(A, MaxY),turn_yreg(B, MaxY)};
+turn_yregs({get_tuple_element,S,N,D}, MaxY) ->
+ {get_tuple_element,turn_yreg(S, MaxY),N,turn_yreg(D, MaxY)};
+turn_yregs({put_tuple,Arity,D}, MaxY) ->
+ {put_tuple,Arity,turn_yreg(D, MaxY)};
+turn_yregs({select_val,R,F,L}, MaxY) ->
+ {select_val,turn_yreg(R, MaxY),F,L};
+turn_yregs({test,Op,F,L}, MaxY) ->
+ {test,Op,F,turn_yreg(L, MaxY)};
+turn_yregs({test,Op,F,Live,A,B}, MaxY) when is_integer(Live) ->
+ {test,Op,F,Live,turn_yreg(A, MaxY),turn_yreg(B, MaxY)};
+turn_yregs({Op,A}, MaxY) ->
+ {Op,turn_yreg(A, MaxY)};
+turn_yregs({Op,A,B}, MaxY) ->
+ {Op,turn_yreg(A, MaxY),turn_yreg(B, MaxY)};
+turn_yregs({Op,A,B,C}, MaxY) ->
+ {Op,turn_yreg(A, MaxY),turn_yreg(B, MaxY),turn_yreg(C, MaxY)};
+turn_yregs(Tuple, MaxY) ->
+ turn_yregs(tuple_size(Tuple), Tuple, MaxY).
+
+turn_yregs(1, Tp, _) ->
+ Tp;
+turn_yregs(N, Tp, MaxY) ->
+ E = turn_yreg(element(N, Tp), MaxY),
+ turn_yregs(N-1, setelement(N, Tp, E), MaxY).
+
+turn_yreg({yy,YY}, MaxY) ->
+ {y,MaxY-YY};
+turn_yreg({list,Ls},MaxY) ->
+ {list,turn_yreg(Ls, MaxY)};
+turn_yreg([_|_]=Ts, MaxY) ->
+ [turn_yreg(T, MaxY) || T <- Ts];
+turn_yreg(Other, _MaxY) ->
+ Other.
%% select_cg(Sclause, V, TypeFail, ValueFail, StackReg, State) ->
%% {Is,StackReg,State}.
@@ -643,19 +667,13 @@ select_val_cg(tuple, R, [Arity,{f,Lbl}], Tf, Vf, [{label,Lbl}|Sis]) ->
[{test,is_tuple,{f,Tf},[R]},{test,test_arity,{f,Vf},[R,Arity]}|Sis];
select_val_cg(tuple, R, Vls, Tf, Vf, Sis) ->
[{test,is_tuple,{f,Tf},[R]},{select_tuple_arity,R,{f,Vf},{list,Vls}}|Sis];
-select_val_cg(map, R, [_Val,{f,Lbl}], Fail, Fail, [{label,Lbl}|Sis]) ->
- [{test,is_map,{f,Fail},[R]}|Sis];
-select_val_cg(map, R, [_Val,{f,Lbl}|_], Tf, _Vf, [{label,Lbl}|Sis]) ->
- [{test,is_map,{f,Tf},[R]}|Sis];
select_val_cg(Type, R, [Val, {f,Lbl}], Fail, Fail, [{label,Lbl}|Sis]) ->
[{test,is_eq_exact,{f,Fail},[R,{Type,Val}]}|Sis];
select_val_cg(Type, R, [Val, {f,Lbl}], Tf, Vf, [{label,Lbl}|Sis]) ->
[{test,select_type_test(Type),{f,Tf},[R]},
{test,is_eq_exact,{f,Vf},[R,{Type,Val}]}|Sis];
select_val_cg(Type, R, Vls0, Tf, Vf, Sis) ->
- Vls1 = map(fun ({f,_Lbl} = F) -> F;
- (Value) -> {Type,Value}
- end, Vls0),
+ Vls1 = [case Value of {f,_Lbl} -> Value; _ -> {Type,Value} end || Value <- Vls0],
[{test,select_type_test(Type),{f,Tf},[R]}, {select_val,R,{f,Vf},{list,Vls1}}|Sis].
select_type_test(integer) -> is_integer;
@@ -688,22 +706,37 @@ select_nil(#l{ke={val_clause,nil,B}}, V, Tf, Vf, Bef, St0) ->
select_binary(#l{ke={val_clause,{binary,{var,V}},B},i=I,vdb=Vdb},
V, Tf, Vf, Bef, St0) ->
Int0 = clear_dead(Bef#sr{reg=Bef#sr.reg}, I, Vdb),
- {Bis,Aft,St1} = match_cg(B, Vf, Int0, St0),
+ {Bis0,Aft,St1} = match_cg(B, Vf, Int0, St0),
CtxReg = fetch_var(V, Int0),
Live = max_reg(Bef#sr.reg),
- {[{test,bs_start_match2,{f,Tf},Live,[CtxReg,V],CtxReg},
- {bs_save2,CtxReg,{V,V}}|Bis],
- Aft,St1};
+ Bis1 = [{test,bs_start_match2,{f,Tf},Live,[CtxReg,V],CtxReg},
+ {bs_save2,CtxReg,{V,V}}|Bis0],
+ Bis = finish_select_binary(Bis1),
+ {Bis,Aft,St1};
select_binary(#l{ke={val_clause,{binary,{var,Ivar}},B},i=I,vdb=Vdb},
V, Tf, Vf, Bef, St0) ->
Regs = put_reg(Ivar, Bef#sr.reg),
Int0 = clear_dead(Bef#sr{reg=Regs}, I, Vdb),
- {Bis,Aft,St1} = match_cg(B, Vf, Int0, St0),
+ {Bis0,Aft,St1} = match_cg(B, Vf, Int0, St0),
CtxReg = fetch_var(Ivar, Int0),
Live = max_reg(Bef#sr.reg),
- {[{test,bs_start_match2,{f,Tf},Live,[fetch_var(V, Bef),Ivar],CtxReg},
- {bs_save2,CtxReg,{Ivar,Ivar}}|Bis],
- Aft,St1}.
+ Bis1 = [{test,bs_start_match2,{f,Tf},Live,[fetch_var(V, Bef),Ivar],CtxReg},
+ {bs_save2,CtxReg,{Ivar,Ivar}}|Bis0],
+ Bis = finish_select_binary(Bis1),
+ {Bis,Aft,St1}.
+
+finish_select_binary([{bs_save2,R,Point}=I,{bs_restore2,R,Point}|Is]) ->
+ [I|finish_select_binary(Is)];
+finish_select_binary([{bs_save2,R,Point}=I,{test,is_eq_exact,_,_}=Test,
+ {bs_restore2,R,Point}|Is]) ->
+ [I,Test|finish_select_binary(Is)];
+finish_select_binary([{test,bs_match_string,F,[Ctx,BinList]}|Is])
+ when is_list(BinList) ->
+ I = {test,bs_match_string,F,[Ctx,list_to_bitstring(BinList)]},
+ [I|finish_select_binary(Is)];
+finish_select_binary([I|Is]) ->
+ [I|finish_select_binary(Is)];
+finish_select_binary([]) -> [].
%% New instructions for selection of binary segments.
@@ -928,7 +961,7 @@ select_extract_tuple(Src, Vs, I, Vdb, Bef, St) ->
select_map(Scs, V, Tf, Vf, Bef, St0) ->
Reg = fetch_var(V, Bef),
{Is,Aft,St1} =
- match_fmf(fun(#l{ke={val_clause,{map,_,Es},B},i=I,vdb=Vdb}, Fail, St1) ->
+ match_fmf(fun(#l{ke={val_clause,{map,exact,_,Es},B},i=I,vdb=Vdb}, Fail, St1) ->
select_map_val(V, Es, B, Fail, I, Vdb, Bef, St1)
end, Vf, St0, Scs),
{[{test,is_map,{f,Tf},[Reg]}|Is],Aft,St1}.
@@ -947,27 +980,34 @@ select_extract_map(Src, Vs, Fail, I, Vdb, Bef, St) ->
%% Assume keys are term-sorted
Rsrc = fetch_var(Src, Bef),
- {{HasKs,GetVs},Aft} = lists:foldr(fun
- ({map_pair,Key,{var,V}},{{HasKsi,GetVsi},Int0}) ->
+ {{HasKs,GetVs,HasVarKs,GetVarVs},Aft} = lists:foldr(fun
+ ({map_pair,{var,K},{var,V}},{{HasKsi,GetVsi,HasVarVsi,GetVarVsi},Int0}) ->
case vdb_find(V, Vdb) of
{V,_,L} when L =< I ->
- {{[Key|HasKsi],GetVsi},Int0};
+ RK = fetch_var(K,Int0),
+ {{HasKsi,GetVsi,[RK|HasVarVsi],GetVarVsi},Int0};
_Other ->
Reg1 = put_reg(V, Int0#sr.reg),
Int1 = Int0#sr{reg=Reg1},
- {{HasKsi,[Key,fetch_reg(V, Reg1)|GetVsi]},Int1}
+ RK = fetch_var(K,Int0),
+ RV = fetch_reg(V,Reg1),
+ {{HasKsi,GetVsi,HasVarVsi,[[RK,RV]|GetVarVsi]},Int1}
+ end;
+ ({map_pair,Key,{var,V}},{{HasKsi,GetVsi,HasVarVsi,GetVarVsi},Int0}) ->
+ case vdb_find(V, Vdb) of
+ {V,_,L} when L =< I ->
+ {{[Key|HasKsi],GetVsi,HasVarVsi,GetVarVsi},Int0};
+ _Other ->
+ Reg1 = put_reg(V, Int0#sr.reg),
+ Int1 = Int0#sr{reg=Reg1},
+ {{HasKsi,[Key,fetch_reg(V, Reg1)|GetVsi],HasVarVsi,GetVarVsi},Int1}
end
- end, {{[],[]},Bef}, Vs),
-
- Code = case {HasKs,GetVs} of
- {HasKs,[]} ->
- [{test,has_map_fields,{f,Fail},Rsrc,{list,HasKs}}];
- {[],GetVs} ->
- [{get_map_elements, {f,Fail},Rsrc,{list,GetVs}}];
- {HasKs,GetVs} ->
- [{test,has_map_fields,{f,Fail},Rsrc,{list,HasKs}},
- {get_map_elements, {f,Fail},Rsrc,{list,GetVs}}]
- end,
+ end, {{[],[],[],[]},Bef}, Vs),
+
+ Code = [{test,has_map_fields,{f,Fail},Rsrc,{list,HasKs}} || HasKs =/= []] ++
+ [{test,has_map_fields,{f,Fail},Rsrc,{list,[K]}} || K <- HasVarKs] ++
+ [{get_map_elements, {f,Fail},Rsrc,{list,GetVs}} || GetVs =/= []] ++
+ [{get_map_elements, {f,Fail},Rsrc,{list,[K,V]}} || [K,V] <- GetVarVs],
{Code, Aft, St}.
@@ -1038,7 +1078,7 @@ protected_cg(Ts, Rs, _Fail, I, Vdb, Bef, St0) ->
St2#cg{bfail=Pfail}),
%%ok = io:fwrite("cg ~w: ~p~n", [?LINE,{Rs,I,Vdb,Aft}]),
%% Set return values to false.
- Mis = map(fun ({var,V}) -> {move,{atom,false},fetch_var(V, Aft)} end, Rs),
+ Mis = [{move,{atom,false},fetch_var(V,Aft)}||{var,V} <- Rs],
{Tis ++ [{jump,{f,Psucc}},
{label,Pfail}] ++ Mis ++ [{label,Psucc}],
Aft,St3#cg{bfail=St0#cg.bfail}}.
@@ -1221,13 +1261,12 @@ enter_line(_, _, _) ->
local_func_label(Name, Arity, St) ->
local_func_label({Name,Arity}, St).
-local_func_label(Key, #cg{functable=Tab}=St0) ->
- case gb_trees:lookup(Key, Tab) of
- {value,Label} ->
- {Label,St0};
- none ->
+local_func_label(Key, #cg{functable=Map}=St0) ->
+ case Map of
+ #{Key := Label} -> {Label,St0};
+ _ ->
{Label,St} = new_label(St0),
- {Label,St#cg{functable=gb_trees:insert(Key, Label, Tab)}}
+ {Label,St#cg{functable=Map#{Key => Label}}}
end.
%% need_stack_frame(State) -> State'
@@ -1288,12 +1327,13 @@ bif_cg(Bif, As, [{var,V}], Le, Vdb, Bef, St0) ->
%% that we save any variable that will be live after this BIF call.
MayFail = not erl_bifs:is_safe(erlang, Bif, length(As)),
- {Sis,Int0} = case St0#cg.in_catch andalso
- St0#cg.bfail =:= 0 andalso
- MayFail of
- true -> adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb);
- false -> {[],Bef}
- end,
+ {Sis,Int0} =
+ case MayFail of
+ true ->
+ maybe_adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb, St0);
+ false ->
+ {[],Bef}
+ end,
Int1 = clear_dead(Int0, Le#l.i, Vdb),
Reg = put_reg(V, Int1#sr.reg),
Int = Int1#sr{reg=Reg},
@@ -1324,11 +1364,7 @@ gc_bif_cg(Bif, As, [{var,V}], Le, Vdb, Bef, St0) ->
%% Currently, we are somewhat pessimistic in
%% that we save any variable that will be live after this BIF call.
- {Sis,Int0} =
- case St0#cg.in_catch andalso St0#cg.bfail =:= 0 of
- true -> adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb);
- false -> {[],Bef}
- end,
+ {Sis,Int0} = maybe_adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb, St0),
Int1 = clear_dead(Int0, Le#l.i, Vdb),
Reg = put_reg(V, Int1#sr.reg),
@@ -1473,8 +1509,7 @@ set_cg([{var,R}], {cons,Es}, Le, Vdb, Bef, St) ->
Int1 = Int0#sr{reg=put_reg(R, Int0#sr.reg)},
Ret = fetch_reg(R, Int1#sr.reg),
{[{put_list,S1,S2,Ret}], Int1, St};
-set_cg([{var,R}], {binary,Segs}, Le, Vdb, Bef,
- #cg{in_catch=InCatch, bfail=Bfail}=St) ->
+set_cg([{var,R}], {binary,Segs}, Le, Vdb, Bef, #cg{bfail=Bfail}=St) ->
%% At run-time, binaries are constructed in three stages:
%% 1) First the size of the binary is calculated.
%% 2) Then the binary is allocated.
@@ -1493,40 +1528,60 @@ set_cg([{var,R}], {binary,Segs}, Le, Vdb, Bef,
%% First generate the code that constructs each field.
Fail = {f,Bfail},
PutCode = cg_bin_put(Segs, Fail, Bef),
- {Sis,Int1} =
- case InCatch of
- true -> adjust_stack(Int0, Le#l.i, Le#l.i+1, Vdb);
- false -> {[],Int0}
- end,
+ {Sis,Int1} = maybe_adjust_stack(Int0, Le#l.i, Le#l.i+1, Vdb, St),
MaxRegs = max_reg(Bef#sr.reg),
Aft = clear_dead(Int1, Le#l.i, Vdb),
%% Now generate the complete code for constructing the binary.
Code = cg_binary(PutCode, Target, Temp, Fail, MaxRegs, Le#l.a),
{Sis++Code,Aft,St};
-set_cg([{var,R}], {map,Op,Map,Es}, Le, Vdb, Bef,
- #cg{in_catch=InCatch,bfail=Bfail}=St) ->
+% Map single variable key
+set_cg([{var,R}], {map,Op,Map,[{map_pair,{var,_}=K,V}]}, Le, Vdb, Bef,
+ #cg{bfail=Bfail}=St) ->
Fail = {f,Bfail},
- {Sis,Int0} =
- case InCatch of
- true -> adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb);
- false -> {[],Bef}
- end,
+ {Sis,Int0} = maybe_adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb, St),
+
SrcReg = cg_reg_arg(Map,Int0),
Line = line(Le#l.a),
- %% The instruction needs to store keys in term sorted order
- %% All keys has to be unique here
- Pairs = map_pair_strip_and_termsort(Es),
+ List = [cg_reg_arg(K,Int0),cg_reg_arg(V,Int0)],
+
+ Live = max_reg(Bef#sr.reg),
+
+ %% The target register can reuse one of the source registers.
+ Aft0 = clear_dead(Int0, Le#l.i, Vdb),
+ Aft = Aft0#sr{reg=put_reg(R, Aft0#sr.reg)},
+ Target = fetch_reg(R, Aft#sr.reg),
+
+ I = case Op of
+ assoc -> put_map_assoc;
+ exact -> put_map_exact
+ end,
+ {Sis++[Line]++[{I,Fail,SrcReg,Target,Live,{list,List}}],Aft,St};
+
+% Map (possibly) multiple literal keys
+set_cg([{var,R}], {map,Op,Map,Es}, Le, Vdb, Bef,
+ #cg{bfail=Bfail}=St) ->
+
+ %% assert key literals
+ [] = [Var||{map_pair,{var,_}=Var,_} <- Es],
+
+ Fail = {f,Bfail},
+ {Sis,Int0} = maybe_adjust_stack(Bef, Le#l.i, Le#l.i+1, Vdb, St),
+ SrcReg = cg_reg_arg(Map,Int0),
+ Line = line(Le#l.a),
%% fetch registers for values to be put into the map
+ Pairs = [{K,V} || {_,K,V} <- Es],
List = flatmap(fun({K,V}) -> [K,cg_reg_arg(V,Int0)] end, Pairs),
Live = max_reg(Bef#sr.reg),
- Int1 = Int0#sr{reg=put_reg(R, Int0#sr.reg)},
- Aft = clear_dead(Int1, Le#l.i, Vdb),
- Target = fetch_reg(R, Int1#sr.reg),
+
+ %% The target register can reuse one of the source registers.
+ Aft0 = clear_dead(Int0, Le#l.i, Vdb),
+ Aft = Aft0#sr{reg=put_reg(R, Aft0#sr.reg)},
+ Target = fetch_reg(R, Aft#sr.reg),
I = case Op of
assoc -> put_map_assoc;
@@ -1545,16 +1600,6 @@ set_cg([{var,R}], Con, Le, Vdb, Bef, St) ->
end,
{Ais,clear_dead(Int, Le#l.i, Vdb),St}.
-map_pair_strip_and_termsort(Es) ->
- %% format in
- %% [{map_pair,K,V}]
- %% where K is for example {integer, 1} and we want to sort on 1.
- Ls = [{K,V}||{_,K,V}<-Es],
- lists:sort(fun ({{_,A},_}, {{_,B},_}) -> erts_internal:cmp_term(A,B) =< 0;
- ({nil,_}, {{_,B},_}) -> [] =< B;
- ({{_,A},_}, {nil,_}) -> A =< []
- end, Ls).
-
%%%
%%% Code generation for constructing binaries.
%%%
@@ -1929,25 +1974,28 @@ clear_dead(Sr, Until, Vdb) ->
stk=clear_dead_stk(Sr#sr.stk, Until, Vdb)}.
clear_dead_reg(Sr, Until, Vdb) ->
- Reg = map(fun ({_I,V} = IV) ->
- case vdb_find(V, Vdb) of
- {V,_,L} when L > Until -> IV;
- _ -> free %Remove anything else
- end;
- ({reserved,_I,_V} = Reserved) -> Reserved;
- (free) -> free
- end, Sr#sr.reg),
+ Reg = [case R of
+ {_I,V} = IV ->
+ case vdb_find(V, Vdb) of
+ {V,_,L} when L > Until -> IV;
+ _ -> free %Remove anything else
+ end;
+ {reserved,_I,_V} = Reserved -> Reserved;
+ free -> free
+ end || R <- Sr#sr.reg],
reserve(Sr#sr.res, Reg, Sr#sr.stk).
clear_dead_stk(Stk, Until, Vdb) ->
- map(fun ({V} = T) ->
- case vdb_find(V, Vdb) of
- {V,_,L} when L > Until -> T;
- _ -> dead %Remove anything else
- end;
- (free) -> free;
- (dead) -> dead
- end, Stk).
+ [case S of
+ {V} = T ->
+ case vdb_find(V, Vdb) of
+ {V,_,L} when L > Until -> T;
+ _ -> dead %Remove anything else
+ end;
+ free -> free;
+ dead -> dead
+ end || S <- Stk].
+
%% sr_merge(Sr1, Sr2) -> Sr.
%% Merge two stack/register states keeping the longest of both stack
@@ -1975,6 +2023,19 @@ trim_free([R|Rs0]) ->
end;
trim_free([]) -> [].
+%% maybe_adjust_stack(Bef, FirstBefore, LastFrom, Vdb, St) -> {[Ainstr],Aft}.
+%% Adjust the stack, but only if the code is inside a catch and not
+%% inside a guard. Use this funtion before instructions that may
+%% cause an exception.
+
+maybe_adjust_stack(Bef, Fb, Lf, Vdb, St) ->
+ case St of
+ #cg{in_catch=true,bfail=0} ->
+ adjust_stack(Bef, Fb, Lf, Vdb);
+ #cg{} ->
+ {[],Bef}
+ end.
+
%% adjust_stack(Bef, FirstBefore, LastFrom, Vdb) -> {[Ainstr],Aft}.
%% Do complete stack adjustment by compressing stack and adding
%% variables to be saved. Try to optimise ordering on stack by
@@ -2077,9 +2138,11 @@ put_stack(Val, [free|Stk]) -> [{Val}|Stk];
put_stack(Val, [NotFree|Stk]) -> [NotFree|put_stack(Val, Stk)].
put_stack_carefully(Val, Stk0) ->
- case catch put_stack_carefully1(Val, Stk0) of
- error -> error;
- Stk1 when is_list(Stk1) -> Stk1
+ try
+ put_stack_carefully1(Val, Stk0)
+ catch
+ throw:error ->
+ error
end.
put_stack_carefully1(_, []) -> throw(error);
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 59ec0d4199..7d93e2ae16 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -66,6 +67,7 @@
%% match arguments are novars
%% case arguments are novars
%% receive timeouts are novars
+%% binaries and maps are novars
%% let/set arguments are expressions
%% fun is not a safe
@@ -77,13 +79,11 @@
splitwith/2,keyfind/3,sort/1,foreach/2,droplast/1,last/1]).
-import(ordsets, [add_element/2,del_element/2,is_element/2,
union/1,union/2,intersection/2,subtract/2]).
--import(cerl, [ann_c_cons/3,ann_c_cons_skel/3,ann_c_tuple/2,c_tuple/1,
- ann_c_map/2, ann_c_map/3]).
+-import(cerl, [ann_c_cons/3,ann_c_tuple/2,c_tuple/1,
+ ann_c_map/3]).
-include("core_parse.hrl").
--define(REC_OFFSET, 100000000). % Also in erl_expand_records.
-
%% Internal core expressions and help functions.
%% N.B. annotations fields in place as normal Core expressions.
@@ -105,7 +105,9 @@
-record(iset, {anno=#a{},var,arg}).
-record(itry, {anno=#a{},args,vars,body,evars,handler}).
-record(ifilter, {anno=#a{},arg}).
--record(igen, {anno=#a{},acc_pat,acc_guard,skip_pat,tail,tail_pat,arg}).
+-record(igen, {anno=#a{},ceps=[],acc_pat,acc_guard,
+ skip_pat,tail,tail_pat,arg}).
+-record(isimple, {anno=#a{},term :: cerl:cerl()}).
-type iapply() :: #iapply{}.
-type ibinary() :: #ibinary{}.
@@ -124,11 +126,12 @@
-type itry() :: #itry{}.
-type ifilter() :: #ifilter{}.
-type igen() :: #igen{}.
+-type isimple() :: #isimple{}.
-type i() :: iapply() | ibinary() | icall() | icase() | icatch()
| iclause() | ifun() | iletrec() | imatch() | iprimop()
| iprotect() | ireceive1() | ireceive2() | iset() | itry()
- | ifilter() | igen().
+ | ifilter() | igen() | isimple().
-type warning() :: {file:filename(), [{integer(), module(), term()}]}.
@@ -166,63 +169,86 @@ form({attribute,_,file,{File,_Line}}, {Fs,As,Ws,_}, _Opts) ->
form({attribute,_,_,_}=F, {Fs,As,Ws,File}, _Opts) ->
{Fs,[attribute(F)|As],Ws,File}.
-attribute({attribute,Line,Name,Val}) ->
- {#c_literal{val=Name, anno=[Line]}, #c_literal{val=Val, anno=[Line]}}.
+attribute(Attribute) ->
+ Fun = fun(A) -> [erl_anno:location(A)] end,
+ {attribute,Line,Name,Val} = erl_parse:map_anno(Fun, Attribute),
+ {#c_literal{val=Name, anno=Line}, #c_literal{val=Val, anno=Line}}.
+
+%% function_dump(module_info,_,_,_) -> ok;
+%% function_dump(Name,Arity,Format,Terms) ->
+%% io:format("~w/~w " ++ Format,[Name,Arity]++Terms),
+%% ok.
function({function,_,Name,Arity,Cs0}, Ws0, File, Opts) ->
- %%ok = io:fwrite("~p - ", [{Name,Arity}]),
St0 = #core{vcount=0,opts=Opts,ws=Ws0,file=[{file,File}]},
{B0,St1} = body(Cs0, Name, Arity, St0),
- %%ok = io:fwrite("1", []),
- %%ok = io:fwrite("~w:~p~n", [?LINE,B0]),
+ %% ok = function_dump(Name,Arity,"body:~n~p~n",[B0]),
{B1,St2} = ubody(B0, St1),
- %%ok = io:fwrite("2", []),
- %%ok = io:fwrite("~w:~p~n", [?LINE,B1]),
+ %% ok = function_dump(Name,Arity,"ubody:~n~p~n",[B1]),
{B2,#core{ws=Ws}} = cbody(B1, St2),
- %%ok = io:fwrite("3~n", []),
- %%ok = io:fwrite("~w:~p~n", [?LINE,B2]),
+ %% ok = function_dump(Name,Arity,"cbody:~n~p~n",[B2]),
{{#c_var{name={Name,Arity}},B2},Ws}.
body(Cs0, Name, Arity, St0) ->
Anno = lineno_anno(element(2, hd(Cs0)), St0),
{Args,St1} = new_vars(Anno, Arity, St0),
- {Cs1,St2} = clauses(Cs0, St1),
- {Ps,St3} = new_vars(Arity, St2), %Need new variables here
- Fc = function_clause(Ps, Anno, {Name,Arity}),
- {#ifun{anno=#a{anno=Anno},id=[],vars=Args,clauses=Cs1,fc=Fc},St3}.
+ case clauses(Cs0, St1) of
+ {Cs1,[],St2} ->
+ {Ps,St3} = new_vars(Arity, St2), %Need new variables here
+ Fc = function_clause(Ps, Anno, {Name,Arity}),
+ {#ifun{anno=#a{anno=Anno},id=[],vars=Args,clauses=Cs1,fc=Fc},St3};
+ {Cs1,Eps,St2} ->
+ %% We have pre-expressions from patterns and
+ %% these needs to be letified before matching
+ %% since only bound variables are allowed
+ AnnoGen = #a{anno=[compiler_generated]},
+ {Ps1,St3} = new_vars(Arity, St2), %Need new variables here
+ Fc1 = function_clause(Ps1, Anno, {Name,Arity}),
+ {Ps2,St4} = new_vars(Arity, St3), %Need new variables here
+ Fc2 = function_clause(Ps2, Anno, {Name,Arity}),
+ Case = #icase{anno=AnnoGen,args=Args,
+ clauses=Cs1,
+ fc=Fc2},
+ {#ifun{anno=#a{anno=Anno},id=[],vars=Args,
+ clauses=[#iclause{anno=AnnoGen,pats=Ps1,
+ guard=[#c_literal{val=true}],
+ body=Eps ++ [Case]}],
+ fc=Fc1},St4}
+ end.
%% clause(Clause, State) -> {Cclause,State} | noclause.
%% clauses([Clause], State) -> {[Cclause],State}.
%% Convert clauses. Trap bad pattern aliases and remove clause from
%% clause list.
-clauses([C0|Cs0], St0) ->
+clauses([C0|Cs0],St0) ->
case clause(C0, St0) of
- {noclause,St} -> clauses(Cs0, St);
- {C,St1} ->
- {Cs,St2} = clauses(Cs0, St1),
- {[C|Cs],St2}
+ {noclause,_,St} -> clauses(Cs0,St);
+ {C,Eps1,St1} ->
+ {Cs,Eps2,St2} = clauses(Cs0, St1),
+ {[C|Cs],Eps1++Eps2,St2}
end;
-clauses([], St) -> {[],St}.
+clauses([],St) -> {[],[],St}.
clause({clause,Lc,H0,G0,B0}, St0) ->
try head(H0, St0) of
- H1 ->
- {G1,St1} = guard(G0, St0),
- {B1,St2} = exprs(B0, St1),
- Anno = lineno_anno(Lc, St2),
- {#iclause{anno=#a{anno=Anno},pats=H1,guard=G1,body=B1},St2}
+ {H1,Eps,St1} ->
+ {G1,St2} = guard(G0, St1),
+ {B1,St3} = exprs(B0, St2),
+ Anno = lineno_anno(Lc, St3),
+ {#iclause{anno=#a{anno=Anno},pats=H1,guard=G1,body=B1},Eps,St3}
catch
throw:nomatch ->
St = add_warning(Lc, nomatch, St0),
- {noclause,St} %Bad pattern
+ {noclause,[],St} %Bad pattern
end.
clause_arity({clause,_,H0,_,_}) -> length(H0).
-%% head([P], State) -> [P].
+%% head([P], State) -> {[P],[Cexpr],State}.
-head(Ps, St) -> pattern_list(Ps, St).
+head(Ps, St) ->
+ pattern_list(Ps, St).
%% guard([Expr], State) -> {[Cexpr],State}.
%% Build an explict and/or tree of guard alternatives, then traverse
@@ -266,13 +292,15 @@ gexpr({protect,Line,Arg}, Bools0, St0) ->
{#iprotect{anno=#a{anno=Anno},body=Eps++[E]},[],Bools0,St}
end;
gexpr({op,L,'andalso',E1,E2}, Bools, St0) ->
- {#c_var{name=V0},St} = new_var(L, St0),
+ Anno = lineno_anno(L, St0),
+ {#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
False = {atom,L,false},
E = make_bool_switch_guard(L, E1, V, E2, False),
gexpr(E, Bools, St);
gexpr({op,L,'orelse',E1,E2}, Bools, St0) ->
- {#c_var{name=V0},St} = new_var(L, St0),
+ Anno = lineno_anno(L, St0),
+ {#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
True = {atom,L,true},
E = make_bool_switch_guard(L, E1, V, True, E2),
@@ -361,33 +389,30 @@ gexpr_test(E0, Bools0, St0) ->
Lanno = Anno#a.anno,
{New,St2} = new_var(Lanno, St1),
Bools = [New|Bools0],
- {#icall{anno=Anno, %Must have an #a{}
- module=#c_literal{anno=Lanno,val=erlang},
- name=#c_literal{anno=Lanno,val='=:='},
- args=[New,#c_literal{anno=Lanno,val=true}]},
+ {icall_eq_true(New),
Eps0 ++ [#iset{anno=Anno,var=New,arg=E1}],Bools,St2}
end;
_ ->
- Anno = get_ianno(E1),
Lanno = get_lineno_anno(E1),
+ ACompGen = #a{anno=[compiler_generated]},
case is_simple(E1) of
true ->
Bools = [E1|Bools0],
- {#icall{anno=Anno, %Must have an #a{}
- module=#c_literal{anno=Lanno,val=erlang},
- name=#c_literal{anno=Lanno,val='=:='},
- args=[E1,#c_literal{anno=Lanno,val=true}]},Eps0,Bools,St1};
+ {icall_eq_true(E1),Eps0,Bools,St1};
false ->
{New,St2} = new_var(Lanno, St1),
Bools = [New|Bools0],
- {#icall{anno=Anno, %Must have an #a{}
- module=#c_literal{anno=Lanno,val=erlang},
- name=#c_literal{anno=Lanno,val='=:='},
- args=[New,#c_literal{anno=Lanno,val=true}]},
- Eps0 ++ [#iset{anno=Anno,var=New,arg=E1}],Bools,St2}
+ {icall_eq_true(New),
+ Eps0 ++ [#iset{anno=ACompGen,var=New,arg=E1}],Bools,St2}
end
end.
+icall_eq_true(Arg) ->
+ #icall{anno=#a{anno=[compiler_generated]},
+ module=#c_literal{val=erlang},
+ name=#c_literal{val='=:='},
+ args=[Arg,#c_literal{val=true}]}.
+
force_booleans(Vs0, E, Eps, St) ->
Vs1 = [set_anno(V, []) || V <- Vs0],
Vs = unforce(E, Eps, Vs1),
@@ -397,16 +422,15 @@ force_booleans_1([], E, Eps, St) ->
{E,Eps,St};
force_booleans_1([V|Vs], E0, Eps0, St0) ->
{E1,Eps1,St1} = force_safe(E0, St0),
- Lanno = element(2, V),
- Anno = #a{anno=Lanno},
- Call = #icall{anno=Anno,module=#c_literal{anno=Lanno,val=erlang},
- name=#c_literal{anno=Lanno,val=is_boolean},
+ ACompGen = #a{anno=[compiler_generated]},
+ Call = #icall{anno=ACompGen,module=#c_literal{val=erlang},
+ name=#c_literal{val=is_boolean},
args=[V]},
- {New,St} = new_var(Lanno, St1),
- Iset = #iset{anno=Anno,var=New,arg=Call},
+ {New,St} = new_var([], St1),
+ Iset = #iset{var=New,arg=Call},
Eps = Eps0 ++ Eps1 ++ [Iset],
- E = #icall{anno=Anno,
- module=#c_literal{anno=Lanno,val=erlang},name=#c_literal{anno=Lanno,val='and'},
+ E = #icall{anno=ACompGen,
+ module=#c_literal{val=erlang},name=#c_literal{val='and'},
args=[E1,New]},
force_booleans_1(Vs, E, Eps, St).
@@ -493,58 +517,32 @@ exprs([], St) -> {[],St}.
%% Generate an internal core expression.
expr({var,L,V}, St) -> {#c_var{anno=lineno_anno(L, St),name=V},[],St};
-expr({char,L,C}, St) -> {#c_literal{anno=lineno_anno(L, St),val=C},[],St};
-expr({integer,L,I}, St) -> {#c_literal{anno=lineno_anno(L, St),val=I},[],St};
-expr({float,L,F}, St) -> {#c_literal{anno=lineno_anno(L, St),val=F},[],St};
-expr({atom,L,A}, St) -> {#c_literal{anno=lineno_anno(L, St),val=A},[],St};
-expr({nil,L}, St) -> {#c_literal{anno=lineno_anno(L, St),val=[]},[],St};
-expr({string,L,S}, St) -> {#c_literal{anno=lineno_anno(L, St),val=S},[],St};
+expr({char,L,C}, St) -> {#c_literal{anno=full_anno(L, St),val=C},[],St};
+expr({integer,L,I}, St) -> {#c_literal{anno=full_anno(L, St),val=I},[],St};
+expr({float,L,F}, St) -> {#c_literal{anno=full_anno(L, St),val=F},[],St};
+expr({atom,L,A}, St) -> {#c_literal{anno=full_anno(L, St),val=A},[],St};
+expr({nil,L}, St) -> {#c_literal{anno=full_anno(L, St),val=[]},[],St};
+expr({string,L,S}, St) -> {#c_literal{anno=full_anno(L, St),val=S},[],St};
expr({cons,L,H0,T0}, St0) ->
{H1,Hps,St1} = safe(H0, St0),
{T1,Tps,St2} = safe(T0, St1),
- A = lineno_anno(L, St2),
+ A = full_anno(L, St2),
{annotate_cons(A, H1, T1, St2),Hps ++ Tps,St2};
expr({lc,L,E,Qs0}, St0) ->
{Qs1,St1} = preprocess_quals(L, Qs0, St0),
lc_tq(L, E, Qs1, #c_literal{anno=lineno_anno(L, St1),val=[]}, St1);
expr({bc,L,E,Qs}, St) ->
- bc_tq(L, E, Qs, {nil,L}, St);
+ bc_tq(L, E, Qs, St);
expr({tuple,L,Es0}, St0) ->
{Es1,Eps,St1} = safe_list(Es0, St0),
A = record_anno(L, St1),
{annotate_tuple(A, Es1, St1),Eps,St1};
expr({map,L,Es0}, St0) ->
- % erl_lint should make sure only #{ K => V } are allowed
- % in map construction.
- try map_pair_list(Es0, St0) of
- {Es1,Eps,St1} ->
- A = lineno_anno(L, St1),
- {ann_c_map(A,Es1),Eps,St1}
- catch
- throw:{bad_map,Warning} ->
- St = add_warning(L, Warning, St0),
- LineAnno = lineno_anno(L, St),
- As = [#c_literal{anno=LineAnno,val=badarg}],
- {#icall{anno=#a{anno=LineAnno}, %Must have an #a{}
- module=#c_literal{anno=LineAnno,val=erlang},
- name=#c_literal{anno=LineAnno,val=error},
- args=As},[],St}
- end;
-expr({map,L,M0,Es0}, St0) ->
- try expr_map(M0,Es0,lineno_anno(L, St0),St0) of
- {_,_,_}=Res -> Res
- catch
- throw:{bad_map,Warning} ->
- St = add_warning(L, Warning, St0),
- LineAnno = lineno_anno(L, St),
- As = [#c_literal{anno=LineAnno,val=badarg}],
- {#icall{anno=#a{anno=LineAnno}, %Must have an #a{}
- module=#c_literal{anno=LineAnno,val=erlang},
- name=#c_literal{anno=LineAnno,val=error},
- args=As},[],St}
- end;
+ map_build_pairs(#c_literal{val=#{}}, Es0, full_anno(L, St0), St0);
+expr({map,L,M,Es}, St) ->
+ expr_map(M, Es, L, St);
expr({bin,L,Es0}, St0) ->
- try expr_bin(Es0, lineno_anno(L, St0), St0) of
+ try expr_bin(Es0, full_anno(L, St0), St0) of
{_,_,_}=Res -> Res
catch
throw:bad_binary ->
@@ -562,26 +560,26 @@ expr({block,_,Es0}, St0) ->
{E1,Eps,St2} = expr(last(Es0), St1),
{E1,Es1 ++ Eps,St2};
expr({'if',L,Cs0}, St0) ->
- {Cs1,St1} = clauses(Cs0, St0),
+ {Cs1,Ceps,St1} = clauses(Cs0, St0),
Lanno = lineno_anno(L, St1),
Fc = fail_clause([], Lanno, #c_literal{val=if_clause}),
- {#icase{anno=#a{anno=Lanno},args=[],clauses=Cs1,fc=Fc},[],St1};
+ {#icase{anno=#a{anno=Lanno},args=[],clauses=Cs1,fc=Fc},Ceps,St1};
expr({'case',L,E0,Cs0}, St0) ->
{E1,Eps,St1} = novars(E0, St0),
- {Cs1,St2} = clauses(Cs0, St1),
+ {Cs1,Ceps,St2} = clauses(Cs0, St1),
{Fpat,St3} = new_var(St2),
Lanno = lineno_anno(L, St2),
Fc = fail_clause([Fpat], Lanno, c_tuple([#c_literal{val=case_clause},Fpat])),
- {#icase{anno=#a{anno=Lanno},args=[E1],clauses=Cs1,fc=Fc},Eps,St3};
+ {#icase{anno=#a{anno=Lanno},args=[E1],clauses=Cs1,fc=Fc},Eps++Ceps,St3};
expr({'receive',L,Cs0}, St0) ->
- {Cs1,St1} = clauses(Cs0, St0),
- {#ireceive1{anno=#a{anno=lineno_anno(L, St1)},clauses=Cs1}, [], St1};
+ {Cs1,Ceps,St1} = clauses(Cs0, St0),
+ {#ireceive1{anno=#a{anno=lineno_anno(L, St1)},clauses=Cs1},Ceps, St1};
expr({'receive',L,Cs0,Te0,Tes0}, St0) ->
{Te1,Teps,St1} = novars(Te0, St0),
{Tes1,St2} = exprs(Tes0, St1),
- {Cs1,St3} = clauses(Cs0, St2),
+ {Cs1,Ceps,St3} = clauses(Cs0, St2),
{#ireceive2{anno=#a{anno=lineno_anno(L, St3)},
- clauses=Cs1,timeout=Te1,action=Tes1},Teps,St3};
+ clauses=Cs1,timeout=Te1,action=Tes1},Teps++Ceps,St3};
expr({'try',L,Es0,[],Ecs,[]}, St0) ->
%% 'try ... catch ... end'
{Es1,St1} = exprs(Es0, St0),
@@ -595,7 +593,7 @@ expr({'try',L,Es0,Cs0,Ecs,[]}, St0) ->
%% 'try ... of ... catch ... end'
{Es1,St1} = exprs(Es0, St0),
{V,St2} = new_var(St1), %This name should be arbitrary
- {Cs1,St3} = clauses(Cs0, St2),
+ {Cs1,Ceps,St3} = clauses(Cs0, St2),
{Fpat,St4} = new_var(St3),
Lanno = lineno_anno(L, St4),
Fc = fail_clause([Fpat], Lanno,
@@ -604,7 +602,7 @@ expr({'try',L,Es0,Cs0,Ecs,[]}, St0) ->
{#itry{anno=#a{anno=lineno_anno(L, St5)},args=Es1,
vars=[V],body=[#icase{anno=#a{anno=Lanno},args=[V],clauses=Cs1,fc=Fc}],
evars=Evs,handler=Hs},
- [],St5};
+ Ceps,St5};
expr({'try',L,Es0,[],[],As0}, St0) ->
%% 'try ... after ... end'
{Es1,St1} = exprs(Es0, St0),
@@ -634,11 +632,11 @@ expr({'catch',L,E0}, St0) ->
Lanno = lineno_anno(L, St1),
{#icatch{anno=#a{anno=Lanno},body=Eps ++ [E1]},[],St1};
expr({'fun',L,{function,F,A},{_,_,_}=Id}, St) ->
- Lanno = lineno_anno(L, St),
+ Lanno = full_anno(L, St),
{#c_var{anno=Lanno++[{id,Id}],name={F,A}},[],St};
expr({'fun',L,{function,M,F,A}}, St0) ->
{As,Aps,St1} = safe_list([M,F,A], St0),
- Lanno = lineno_anno(L, St1),
+ Lanno = full_anno(L, St1),
{#icall{anno=#a{anno=Lanno},
module=#c_literal{val=erlang},
name=#c_literal{val=make_fun},
@@ -649,13 +647,9 @@ expr({named_fun,L,'_',Cs,Id}, St) ->
fun_tq(Id, Cs, L, St, unnamed);
expr({named_fun,L,Name,Cs,Id}, St) ->
fun_tq(Id, Cs, L, St, {named,Name});
-expr({call,L,{remote,_,M,F},As0}, #core{wanted=Wanted}=St0) ->
+expr({call,L,{remote,_,M,F},As0}, St0) ->
{[M1,F1|As1],Aps,St1} = safe_list([M,F|As0], St0),
- Lanno = lineno_anno(L, St1),
- Anno = case Wanted of
- false -> [result_not_wanted|Lanno];
- true -> Lanno
- end,
+ Anno = full_anno(L, St1),
{#icall{anno=#a{anno=Anno},module=M1,name=F1,args=As1},Aps,St1};
expr({call,Lc,{atom,Lf,F},As0}, St0) ->
{As1,Aps,St1} = safe_list(As0, St0),
@@ -673,24 +667,24 @@ expr({match,L,P0,E0}, St0) ->
{var,_,'_'} -> St0#core{wanted=false};
_ -> St0
end,
- {E2,Eps,St2} = novars(E1, St1),
+ {E2,Eps1,St2} = novars(E1, St1),
St3 = St2#core{wanted=St0#core.wanted},
- P2 = try
- pattern(P1, St3)
+ {P2,Eps2,St4} = try
+ pattern(P1, St3)
catch
throw:Thrown ->
- Thrown
+ {Thrown,[],St3}
end,
- {Fpat,St4} = new_var(St3),
- Lanno = lineno_anno(L, St4),
+ {Fpat,St5} = new_var(St4),
+ Lanno = lineno_anno(L, St5),
Fc = fail_clause([Fpat], Lanno, c_tuple([#c_literal{val=badmatch},Fpat])),
case P2 of
nomatch ->
- St = add_warning(L, nomatch, St4),
+ St = add_warning(L, nomatch, St5),
{#icase{anno=#a{anno=Lanno},
- args=[E2],clauses=[],fc=Fc},Eps,St};
+ args=[E2],clauses=[],fc=Fc},Eps1++Eps2,St};
Other when not is_atom(Other) ->
- {#imatch{anno=#a{anno=Lanno},pat=P2,arg=E2,fc=Fc},Eps,St4}
+ {#imatch{anno=#a{anno=Lanno},pat=P2,arg=E2,fc=Fc},Eps1++Eps2,St5}
end;
expr({op,_,'++',{lc,Llc,E,Qs0},More}, St0) ->
%% Optimise '++' here because of the list comprehension algorithm.
@@ -704,26 +698,28 @@ expr({op,_,'++',{lc,Llc,E,Qs0},More}, St0) ->
{Y,Yps,St} = lc_tq(Llc, E, Qs, Mc, St2),
{Y,Mps++Yps,St};
expr({op,L,'andalso',E1,E2}, St0) ->
- {#c_var{name=V0},St} = new_var(L, St0),
+ Anno = lineno_anno(L, St0),
+ {#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
False = {atom,L,false},
E = make_bool_switch(L, E1, V, E2, False, St0),
expr(E, St);
expr({op,L,'orelse',E1,E2}, St0) ->
- {#c_var{name=V0},St} = new_var(L, St0),
+ Anno = lineno_anno(L, St0),
+ {#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
True = {atom,L,true},
E = make_bool_switch(L, E1, V, True, E2, St0),
expr(E, St);
expr({op,L,Op,A0}, St0) ->
{A1,Aps,St1} = safe(A0, St0),
- LineAnno = lineno_anno(L, St1),
+ LineAnno = full_anno(L, St1),
{#icall{anno=#a{anno=LineAnno}, %Must have an #a{}
module=#c_literal{anno=LineAnno,val=erlang},
name=#c_literal{anno=LineAnno,val=Op},args=[A1]},Aps,St1};
expr({op,L,Op,L0,R0}, St0) ->
{As,Aps,St1} = safe_list([L0,R0], St0),
- LineAnno = lineno_anno(L, St1),
+ LineAnno = full_anno(L, St1),
{#icall{anno=#a{anno=LineAnno}, %Must have an #a{}
module=#c_literal{anno=LineAnno,val=erlang},
name=#c_literal{anno=LineAnno,val=Op},args=As},Aps,St1}.
@@ -734,7 +730,7 @@ make_bool_switch(L, E, V, T, F, #core{}) ->
make_bool_switch_body(L, E, V, T, F).
make_bool_switch_body(L, E, V, T, F) ->
- NegL = neg_line(abs_line(L)),
+ NegL = no_compiler_warning(L),
Error = {tuple,NegL,[{atom,NegL,badarg},V]},
{'case',NegL,E,
[{clause,NegL,[{atom,NegL,true}],[],[T]},
@@ -745,90 +741,78 @@ make_bool_switch_body(L, E, V, T, F) ->
make_bool_switch_guard(_, E, _, {atom,_,true}, {atom,_,false}) -> E;
make_bool_switch_guard(L, E, V, T, F) ->
- NegL = neg_line(abs_line(L)),
+ NegL = no_compiler_warning(L),
{'case',NegL,E,
[{clause,NegL,[{atom,NegL,true}],[],[T]},
{clause,NegL,[{atom,NegL,false}],[],[F]},
{clause,NegL,[V],[],[V]}
]}.
-expr_map(M0,Es0,A,St0) ->
- {M1,Mps,St1} = safe(M0, St0),
+expr_map(M0, Es0, L, St0) ->
+ {M1,Eps0,St1} = safe(M0, St0),
+ Badmap = badmap_term(M1, St1),
+ A = lineno_anno(L, St1),
+ Fc = fail_clause([], [{eval_failure,badmap}|A], Badmap),
case is_valid_map_src(M1) of
true ->
- case {M1,Es0} of
- {#c_var{}, []} ->
- %% transform M#{} to is_map(M)
- {Vpat,St2} = new_var(St1),
- {Fpat,St3} = new_var(St2),
- Cs = [#iclause{
- anno=A,
- pats=[Vpat],
- guard=[#icall{anno=#a{anno=A},
+ {M2,Eps1,St2} = map_build_pairs(M1, Es0, full_anno(L, St1), St1),
+ M3 = case Es0 of
+ [] -> M1;
+ [_|_] -> M2
+ end,
+ Cs = [#iclause{
+ anno=#a{anno=[compiler_generated|A]},
+ pats=[],
+ guard=[#icall{anno=#a{anno=A},
module=#c_literal{anno=A,val=erlang},
name=#c_literal{anno=A,val=is_map},
- args=[Vpat]}],
- body=[Vpat]}],
- Fc = fail_clause([Fpat], A, #c_literal{val=badarg}),
- {#icase{anno=#a{anno=A},args=[M1],clauses=Cs,fc=Fc},Mps,St3};
- {_,_} ->
- {Es1,Eps,St2} = map_pair_list(Es0, St1),
- {ann_c_map(A,M1,Es1),Mps++Eps,St2}
- end;
- false -> throw({bad_map,bad_map})
+ args=[M1]}],
+ body=[M3]}],
+ Eps = Eps0 ++ Eps1,
+ {#icase{anno=#a{anno=A},args=[],clauses=Cs,fc=Fc},Eps,St2};
+ false ->
+ %% Not a map source. The update will always fail.
+ St2 = add_warning(L, badmap, St1),
+ #iclause{body=[Fail]} = Fc,
+ {Fail,Eps0,St2}
end.
+badmap_term(_Map, #core{in_guard=true}) ->
+ %% The code generator cannot handle complex error reasons
+ %% in guards. But the exact error reason does not matter anyway
+ %% since it is not user-visible.
+ #c_literal{val=badmap};
+badmap_term(Map, #core{in_guard=false}) ->
+ #c_tuple{es=[#c_literal{val=badmap},Map]}.
+
+map_build_pairs(Map, Es0, Ann, St0) ->
+ {Es,Pre,St1} = map_build_pairs_1(Es0, St0),
+ {ann_c_map(Ann, Map, Es),Pre,St1}.
+
+map_build_pairs_1([{Op0,L,K0,V0}|Es], St0) ->
+ {K,Pre0,St1} = safe(K0, St0),
+ {V,Pre1,St2} = safe(V0, St1),
+ {Pairs,Pre2,St3} = map_build_pairs_1(Es, St2),
+ As = lineno_anno(L, St3),
+ Op = map_op(Op0),
+ Pair = cerl:ann_c_map_pair(As, Op, K, V),
+ {[Pair|Pairs],Pre0++Pre1++Pre2,St3};
+map_build_pairs_1([], St) ->
+ {[],[],St}.
+
+map_op(map_field_assoc) -> #c_literal{val=assoc};
+map_op(map_field_exact) -> #c_literal{val=exact}.
+
is_valid_map_src(#c_literal{val = M}) when is_map(M) -> true;
-is_valid_map_src(#c_map{}) -> true;
-is_valid_map_src(#c_var{}) -> true;
+is_valid_map_src(#c_var{}=Var) -> not cerl:is_c_fname(Var);
is_valid_map_src(_) -> false.
-map_pair_list(Es, St) ->
- foldr(fun
- ({map_field_assoc,L,K0,V0}, {Ces,Esp,St0}) ->
- {K1,Ep0,St1} = safe(K0, St0),
- K = ensure_valid_map_key(K1),
- {V,Ep1,St2} = safe(V0, St1),
- A = lineno_anno(L, St2),
- Pair = #c_map_pair{op=#c_literal{val=assoc},anno=A,key=K,val=V},
- {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2};
- ({map_field_exact,L,K0,V0}, {Ces,Esp,St0}) ->
- {K1,Ep0,St1} = safe(K0, St0),
- K = ensure_valid_map_key(K1),
- {V,Ep1,St2} = safe(V0, St1),
- A = lineno_anno(L, St2),
- Pair = #c_map_pair{op=#c_literal{val=exact},anno=A,key=K,val=V},
- {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2}
- end, {[],[],St}, Es).
-
-ensure_valid_map_key(K0) ->
- case coalesced_map_key(K0) of
- {ok,K1} -> K1;
- error -> throw({bad_map,bad_map_key})
- end.
-
-coalesced_map_key(#c_literal{}=K) -> {ok,K};
-%% Dialyzer hack redux
-%% DO coalesce tuples and list in maps for dialyzer
-%% Dialyzer tries to break this apart, don't let it
-coalesced_map_key(#c_tuple{}=K) ->
- case core_lib:is_literal(K) of
- true -> {ok,cerl:fold_literal(K)};
- false -> error
- end;
-coalesced_map_key(#c_cons{}=K) ->
- case core_lib:is_literal(K) of
- true -> {ok,cerl:fold_literal(K)};
- false -> error
- end;
-coalesced_map_key(_) -> error.
-
%% try_exception([ExcpClause], St) -> {[ExcpVar],Handler,St}.
try_exception(Ecs0, St0) ->
%% Note that Tag is not needed for rethrow - it is already in Info.
{Evs,St1} = new_vars(3, St0), % Tag, Value, Info
- {Ecs1,St2} = clauses(Ecs0, St1),
+ {Ecs1,Ceps,St2} = clauses(Ecs0, St1),
[_,Value,Info] = Evs,
Ec = #iclause{anno=#a{anno=[compiler_generated]},
pats=[c_tuple(Evs)],guard=[#c_literal{val=true}],
@@ -836,15 +820,15 @@ try_exception(Ecs0, St0) ->
name=#c_literal{val=raise},
args=[Info,Value]}]},
Hs = [#icase{anno=#a{},args=[c_tuple(Evs)],clauses=Ecs1,fc=Ec}],
- {Evs,Hs,St2}.
+ {Evs,Ceps++Hs,St2}.
try_after(As, St0) ->
%% See above.
- {Evs,St1} = new_vars(3, St0), % Tag, Value, Info
+ {Evs,St1} = new_vars(3, St0), % Tag, Value, Info
[_,Value,Info] = Evs,
- B = As ++ [#iprimop{anno=#a{}, %Must have an #a{}
- name=#c_literal{val=raise},
- args=[Info,Value]}],
+ B = As ++ [#iprimop{anno=#a{}, % Must have an #a{}
+ name=#c_literal{val=raise},
+ args=[Info,Value]}],
Ec = #iclause{anno=#a{anno=[compiler_generated]},
pats=[c_tuple(Evs)],guard=[#c_literal{val=true}],
body=B},
@@ -886,10 +870,10 @@ constant_bin_1(Es) ->
({float,_,F}, B) -> {value,F,B};
({atom,_,undefined}, B) -> {value,undefined,B}
end,
- case catch eval_bits:expr_grp(Es, EmptyBindings, EvalFun) of
+ try eval_bits:expr_grp(Es, EmptyBindings, EvalFun) of
{value,Bin,EmptyBindings} ->
- Bin;
- _ ->
+ Bin
+ catch error:_ ->
error
end.
@@ -936,7 +920,7 @@ verify_suitable_fields([]) -> ok.
%% (We don't need an exact result for this purpose.)
count_bits(Int) ->
- count_bits_1(abs_line(Int), 64).
+ count_bits_1(abs(Int), 64).
count_bits_1(0, Bits) -> Bits;
count_bits_1(Int, Bits) -> count_bits_1(Int bsr 64, Bits+64).
@@ -978,20 +962,21 @@ bitstr({bin_element,_,E0,Size0,[Type,{unit,Unit}|Flags]}, St0) ->
fun_tq({_,_,Name}=Id, Cs0, L, St0, NameInfo) ->
Arity = clause_arity(hd(Cs0)),
- {Cs1,St1} = clauses(Cs0, St0),
+ {Cs1,Ceps,St1} = clauses(Cs0, St0),
{Args,St2} = new_vars(Arity, St1),
{Ps,St3} = new_vars(Arity, St2), %Need new variables here
- Anno = lineno_anno(L, St3),
+ Anno = full_anno(L, St3),
Fc = function_clause(Ps, Anno, {Name,Arity}),
Fun = #ifun{anno=#a{anno=Anno},
id=[{id,Id}], %We KNOW!
vars=Args,clauses=Cs1,fc=Fc,name=NameInfo},
- {Fun,[],St3}.
+ {Fun,Ceps,St3}.
%% lc_tq(Line, Exp, [Qualifier], Mc, State) -> {LetRec,[PreExp],State}.
%% This TQ from Simon PJ pp 127-138.
-lc_tq(Line, E, [#igen{anno=GAnno,acc_pat=AccPat,acc_guard=AccGuard,
+lc_tq(Line, E, [#igen{anno=GAnno,ceps=Ceps,
+ acc_pat=AccPat,acc_guard=AccGuard,
skip_pat=SkipPat,tail=Tail,tail_pat=TailPat,
arg={Pre,Arg}}|Qs], Mc, St0) ->
{Name,St1} = new_fun_name("lc", St0),
@@ -1026,7 +1011,7 @@ lc_tq(Line, E, [#igen{anno=GAnno,acc_pat=AccPat,acc_guard=AccGuard,
Fun = #ifun{anno=LAnno,id=[],vars=[Var],clauses=Cs,fc=Fc},
{#iletrec{anno=LAnno#a{anno=[list_comprehension|LA]},defs=[{{Name,1},Fun}],
body=Pre ++ [#iapply{anno=LAnno,op=F,args=[Arg]}]},
- [],St4};
+ Ceps,St4};
lc_tq(Line, E, [#ifilter{}=Filter|Qs], Mc, St) ->
filter_tq(Line, E, Filter, Mc, St, Qs, fun lc_tq/5);
lc_tq(Line, E0, [], Mc0, St0) ->
@@ -1040,7 +1025,7 @@ lc_tq(Line, E0, [], Mc0, St0) ->
%% This TQ from Gustafsson ERLANG'05.
%% More could be transformed before calling bc_tq.
-bc_tq(Line, Exp, Qs0, _, St0) ->
+bc_tq(Line, Exp, Qs0, St0) ->
{BinVar,St1} = new_var(St0),
{Sz,SzPre,St2} = bc_initial_size(Exp, Qs0, St1),
{Qs,St3} = preprocess_quals(Line, Qs0, St2),
@@ -1051,7 +1036,8 @@ bc_tq(Line, Exp, Qs0, _, St0) ->
args=[Sz]}}] ++ BcPre,
{E,Pre,St}.
-bc_tq1(Line, E, [#igen{anno=GAnno,acc_pat=AccPat,acc_guard=AccGuard,
+bc_tq1(Line, E, [#igen{anno=GAnno,ceps=Ceps,
+ acc_pat=AccPat,acc_guard=AccGuard,
skip_pat=SkipPat,tail=Tail,tail_pat=TailPat,
arg={Pre,Arg}}|Qs], Mc, St0) ->
{Name,St1} = new_fun_name("lbc", St0),
@@ -1089,7 +1075,7 @@ bc_tq1(Line, E, [#igen{anno=GAnno,acc_pat=AccPat,acc_guard=AccGuard,
Fun = #ifun{anno=LAnno,id=[],vars=Vars,clauses=Cs,fc=Fc},
{#iletrec{anno=LAnno#a{anno=[list_comprehension|LA]},defs=[{{Name,2},Fun}],
body=Pre ++ [#iapply{anno=LAnno,op=F,args=[Arg,Mc]}]},
- [],St4};
+ Ceps,St4};
bc_tq1(Line, E, [#ifilter{}=Filter|Qs], Mc, St) ->
filter_tq(Line, E, Filter, Mc, St, Qs, fun bc_tq1/5);
bc_tq1(_, {bin,Bl,Elements}, [], AccVar, St0) ->
@@ -1153,7 +1139,7 @@ preprocess_quals(Line, [Q|Qs0], St0, Acc) ->
{Gen,St} = generator(Line, Q, Gs, St0),
preprocess_quals(Line, Qs, St, [Gen|Acc]);
false ->
- LAnno = #a{anno=lineno_anno(get_anno(Q), St0)},
+ LAnno = #a{anno=lineno_anno(get_qual_anno(Q), St0)},
case is_guard_test(Q) of
true ->
%% When a filter is a guard test, its argument in the
@@ -1178,6 +1164,11 @@ is_generator({generate,_,_,_}) -> true;
is_generator({b_generate,_,_,_}) -> true;
is_generator(_) -> false.
+%% Retrieve the annotation from an Erlang AST form.
+%% (Use get_anno/1 to retrieve the annotation from Core Erlang forms).
+
+get_qual_anno(Abstract) -> element(2, Abstract).
+
%%
%% Generators are abstracted as sextuplets:
%% - acc_pat is the accumulator pattern, e.g. [Pat|Tail] for Pat <- Expr.
@@ -1200,7 +1191,7 @@ is_generator(_) -> false.
generator(Line, {generate,Lg,P0,E}, Gs, St0) ->
LA = lineno_anno(Line, St0),
GA = lineno_anno(Lg, St0),
- {Head,St1} = list_gen_pattern(P0, Line, St0),
+ {Head,Ceps,St1} = list_gen_pattern(P0, Line, St0),
{[Tail,Skip],St2} = new_vars(2, St1),
{Cg,St3} = lc_guard_tests(Gs, St2),
{AccPat,SkipPat} = case Head of
@@ -1220,25 +1211,27 @@ generator(Line, {generate,Lg,P0,E}, Gs, St0) ->
ann_c_cons(LA, Skip, Tail)}
end,
{Ce,Pre,St4} = safe(E, St3),
- Gen = #igen{anno=#a{anno=GA},acc_pat=AccPat,acc_guard=Cg,skip_pat=SkipPat,
+ Gen = #igen{anno=#a{anno=GA},ceps=Ceps,
+ acc_pat=AccPat,acc_guard=Cg,skip_pat=SkipPat,
tail=Tail,tail_pat=#c_literal{anno=LA,val=[]},arg={Pre,Ce}},
{Gen,St4};
generator(Line, {b_generate,Lg,P,E}, Gs, St0) ->
LA = lineno_anno(Line, St0),
GA = lineno_anno(Lg, St0),
- Cp = #c_binary{segments=Segs} = pattern(P, St0),
+ {Cp = #c_binary{segments=Segs},[],St1} = pattern(P, St0),
+
%% The function append_tail_segment/2 keeps variable patterns as-is, making
%% it possible to have the same skip clause removal as with list generators.
- {AccSegs,Tail,TailSeg,St1} = append_tail_segment(Segs, St0),
+ {AccSegs,Tail,TailSeg,St2} = append_tail_segment(Segs, St1),
AccPat = Cp#c_binary{segments=AccSegs},
- {Cg,St2} = lc_guard_tests(Gs, St1),
- {SkipSegs,St3} = emasculate_segments(AccSegs, St2),
+ {Cg,St3} = lc_guard_tests(Gs, St2),
+ {SkipSegs,St4} = emasculate_segments(AccSegs, St3),
SkipPat = Cp#c_binary{segments=SkipSegs},
- {Ce,Pre,St4} = safe(E, St3),
+ {Ce,Pre,St5} = safe(E, St4),
Gen = #igen{anno=#a{anno=GA},acc_pat=AccPat,acc_guard=Cg,skip_pat=SkipPat,
tail=Tail,tail_pat=#c_binary{anno=LA,segments=[TailSeg]},
arg={Pre,Ce}},
- {Gen,St4}.
+ {Gen,St5}.
append_tail_segment(Segs, St0) ->
{Var,St} = new_var(St0),
@@ -1267,9 +1260,9 @@ lc_guard_tests(Gs0, St0) ->
list_gen_pattern(P0, Line, St) ->
try
- {pattern(P0, St),St}
+ pattern(P0,St)
catch
- nomatch -> {nomatch,add_warning(Line, nomatch, St)}
+ nomatch -> {nomatch,[],add_warning(Line, nomatch, St)}
end.
%%%
@@ -1489,9 +1482,22 @@ force_novars(#iapply{}=App, St) -> {App,[],St};
force_novars(#icall{}=Call, St) -> {Call,[],St};
force_novars(#ifun{}=Fun, St) -> {Fun,[],St}; %These are novars too
force_novars(#ibinary{}=Bin, St) -> {Bin,[],St};
+force_novars(#c_map{}=Bin, St) -> {Bin,[],St};
force_novars(Ce, St) ->
force_safe(Ce, St).
+
+%% safe_pattern_expr(Expr, State) -> {Cexpr,[PreExpr],State}.
+%% only literals and variables are safe expressions in patterns
+safe_pattern_expr(E,St0) ->
+ case safe(E,St0) of
+ {#c_var{},_,_}=Safe -> Safe;
+ {#c_literal{},_,_}=Safe -> Safe;
+ {Ce,Eps,St1} ->
+ {V,St2} = new_var(St1),
+ {V,Eps++[#iset{var=V,arg=Ce}],St2}
+ end.
+
%% safe(Expr, State) -> {Safe,[PreExpr],State}.
%% Generate an internal safe expression. These are simples without
%% binaries which can fail. At this level we do not need to do a
@@ -1566,90 +1572,90 @@ fold_match({match,L,P0,E0}, P) ->
{{match,L,P0,P1},E1};
fold_match(E, P) -> {P,E}.
-%% pattern(Pattern, State) -> CorePat.
+%% pattern(Pattern, State) -> {CorePat,[PreExp],State}.
%% Transform a pattern by removing line numbers. We also normalise
%% aliases in patterns to standard form, {alias,Pat,[Var]}.
-
-pattern({var,L,V}, St) -> #c_var{anno=lineno_anno(L, St),name=V};
-pattern({char,L,C}, St) -> #c_literal{anno=lineno_anno(L, St),val=C};
-pattern({integer,L,I}, St) -> #c_literal{anno=lineno_anno(L, St),val=I};
-pattern({float,L,F}, St) -> #c_literal{anno=lineno_anno(L, St),val=F};
-pattern({atom,L,A}, St) -> #c_literal{anno=lineno_anno(L, St),val=A};
-pattern({string,L,S}, St) -> #c_literal{anno=lineno_anno(L, St),val=S};
-pattern({nil,L}, St) -> #c_literal{anno=lineno_anno(L, St),val=[]};
+%%
+%% In patterns we may have expressions
+%% 1) Binaries -> #c_bitstr{size=Expr}
+%% 2) Maps -> #c_map_pair{key=Expr}
+%%
+%% Both of these may generate pre-expressions since only bound variables
+%% or literals are allowed for these in core patterns.
+%%
+%% Therefor, we need to drag both the state and the collection of pre-expression
+%% around in the whole pattern transformation tree.
+
+pattern({var,L,V}, St) -> {#c_var{anno=lineno_anno(L, St),name=V},[],St};
+pattern({char,L,C}, St) -> {#c_literal{anno=lineno_anno(L, St),val=C},[],St};
+pattern({integer,L,I}, St) -> {#c_literal{anno=lineno_anno(L, St),val=I},[],St};
+pattern({float,L,F}, St) -> {#c_literal{anno=lineno_anno(L, St),val=F},[],St};
+pattern({atom,L,A}, St) -> {#c_literal{anno=lineno_anno(L, St),val=A},[],St};
+pattern({string,L,S}, St) -> {#c_literal{anno=lineno_anno(L, St),val=S},[],St};
+pattern({nil,L}, St) -> {#c_literal{anno=lineno_anno(L, St),val=[]},[],St};
pattern({cons,L,H,T}, St) ->
- annotate_cons(lineno_anno(L, St), pattern(H, St), pattern(T, St), St);
+ {Ph,Eps1,St1} = pattern(H, St),
+ {Pt,Eps2,St2} = pattern(T, St1),
+ {annotate_cons(lineno_anno(L, St), Ph, Pt, St2),Eps1++Eps2,St2};
pattern({tuple,L,Ps}, St) ->
- annotate_tuple(record_anno(L, St), pattern_list(Ps, St), St);
-pattern({map,L,Ps}, St) ->
- #c_map{anno=lineno_anno(L, St), es=pattern_map_pairs(Ps, St)};
+ {Ps1,Eps,St1} = pattern_list(Ps,St),
+ {annotate_tuple(record_anno(L, St), Ps1, St),Eps,St1};
+pattern({map,L,Pairs}, St0) ->
+ {Ps,Eps,St1} = pattern_map_pairs(Pairs, St0),
+ {#c_map{anno=lineno_anno(L, St1),es=Ps,is_pat=true},Eps,St1};
pattern({bin,L,Ps}, St) ->
%% We don't create a #ibinary record here, since there is
%% no need to hold any used/new annotations in a pattern.
- #c_binary{anno=lineno_anno(L, St),segments=pat_bin(Ps, St)};
+ {#c_binary{anno=lineno_anno(L, St),segments=pat_bin(Ps, St)},[],St};
pattern({match,_,P1,P2}, St) ->
- pat_alias(pattern(P1, St), pattern(P2, St)).
+ {Cp1,Eps1,St1} = pattern(P1,St),
+ {Cp2,Eps2,St2} = pattern(P2,St1),
+ {pat_alias(Cp1,Cp2),Eps1++Eps2,St2}.
%% pattern_map_pairs([MapFieldExact],State) -> [#c_map_pairs{}]
pattern_map_pairs(Ps, St) ->
- %% check literal key uniqueness (dict is needed)
- %% pattern all pairs
- {CMapPairs, Kdb} = lists:mapfoldl(fun
- (P,Kdbi) ->
- #c_map_pair{key=Ck,val=Cv} = CMapPair = pattern_map_pair(P,St),
- K = core_lib:literal_value(Ck),
- case dict:find(K,Kdbi) of
- {ok, Vs} ->
- {CMapPair, dict:store(K,[Cv|Vs],Kdbi)};
- _ ->
- {CMapPair, dict:store(K,[Cv],Kdbi)}
- end
- end, dict:new(), Ps),
- pattern_alias_map_pairs(CMapPairs,Kdb,dict:new(),St).
-
-pattern_alias_map_pairs([],_,_,_) -> [];
-pattern_alias_map_pairs([#c_map_pair{key=Ck}=Pair|Pairs],Kdb,Kset,St) ->
- %% alias same keys if needed
- K = core_lib:literal_value(Ck),
- case dict:find(K,Kset) of
- {ok,processed} ->
- pattern_alias_map_pairs(Pairs,Kdb,Kset,St);
- _ ->
- Cvs = dict:fetch(K,Kdb),
- Cv = pattern_alias_map_pair_patterns(Cvs),
- Kset1 = dict:store(K, processed, Kset),
- [Pair#c_map_pair{val=Cv}|pattern_alias_map_pairs(Pairs,Kdb,Kset1,St)]
- end.
-
-pattern_alias_map_pair_patterns([Cv]) -> Cv;
-pattern_alias_map_pair_patterns([Cv1,Cv2|Cvs]) ->
- pattern_alias_map_pair_patterns([pat_alias(Cv1,Cv2)|Cvs]).
-
-pattern_map_pair({map_field_exact,L,K,V},St) ->
- #c_map_pair{anno=lineno_anno(L, St),
- op=#c_literal{val=exact},
- key=pattern_map_key(K,St),
- val=pattern(V, St)}.
-
-pattern_map_key(K,St) ->
- %% Throws 'nomatch' if the key can't be a literal
- %% this will be a cryptic error message but it is better than nothing
- case expr(K,St) of
- {Key0,[],_} ->
- %% Dialyzer hack redux
- case coalesced_map_key(Key0) of
- {ok,Key1} -> Key1;
- error -> throw(nomatch)
- end;
- _ -> throw(nomatch)
- end.
+ %% check literal key uniqueness
+ %% - guaranteed via aliasing map pairs
+ %% pattern all pairs in two steps
+ %% 1) Construct Core Pattern
+ %% 2) Alias Keys in Core Pattern
+ {CMapPairs, {Eps,St1}} = lists:mapfoldl(fun
+ (P,{EpsM,Sti0}) ->
+ {CMapPair,EpsP,Sti1} = pattern_map_pair(P,Sti0),
+ {CMapPair, {EpsM++EpsP,Sti1}}
+ end, {[],St}, Ps),
+ {pat_alias_map_pairs(CMapPairs),Eps,St1}.
+
+pattern_map_pair({map_field_exact,L,K,V}, St0) ->
+ {Ck,EpsK,St1} = safe_pattern_expr(K, St0),
+ {Cv,EpsV,St2} = pattern(V, St1),
+ {#c_map_pair{anno=lineno_anno(L, St2),
+ op=#c_literal{val=exact},
+ key=Ck,
+ val=Cv},EpsK++EpsV,St2}.
+
+pat_alias_map_pairs(Ps) ->
+ D = foldl(fun(#c_map_pair{key=K0}=Pair, D0) ->
+ K = cerl:set_ann(K0, []),
+ dict:append(K, Pair, D0)
+ end, dict:new(), Ps),
+ pat_alias_map_pairs_1(dict:to_list(D)).
+
+pat_alias_map_pairs_1([{_,[#c_map_pair{val=V0}=Pair|Vs]}|T]) ->
+ V = foldl(fun(#c_map_pair{val=V}, Pat) ->
+ pat_alias(V, Pat)
+ end, V0, Vs),
+ [Pair#c_map_pair{val=V}|pat_alias_map_pairs_1(T)];
+pat_alias_map_pairs_1([]) -> [].
%% pat_bin([BinElement], State) -> [BinSeg].
pat_bin(Ps, St) -> [pat_segment(P, St) || P <- Ps].
-pat_segment({bin_element,_,Term,Size,[Type,{unit,Unit}|Flags]}, St) ->
- #c_bitstr{val=pattern(Term, St),size=pattern(Size, St),
+pat_segment({bin_element,_,Val,Size,[Type,{unit,Unit}|Flags]}, St) ->
+ {Pval,[],St1} = pattern(Val,St),
+ {Psize,[],_St2} = pattern(Size,St1),
+ #c_bitstr{val=Pval,size=Psize,
unit=#c_literal{val=Unit},
type=#c_literal{val=Type},
flags=#c_literal{val=Flags}}.
@@ -1657,38 +1663,55 @@ pat_segment({bin_element,_,Term,Size,[Type,{unit,Unit}|Flags]}, St) ->
%% pat_alias(CorePat, CorePat) -> AliasPat.
%% Normalise aliases. Trap bad aliases by throwing 'nomatch'.
-pat_alias(#c_var{name=V1}, P2) -> #c_alias{var=#c_var{name=V1},pat=P2};
-pat_alias(P1, #c_var{name=V2}) -> #c_alias{var=#c_var{name=V2},pat=P1};
-pat_alias(#c_cons{}=Cons, #c_literal{anno=A,val=[H|T]}=S) ->
- pat_alias(Cons, ann_c_cons_skel(A, #c_literal{anno=A,val=H},
- S#c_literal{val=T}));
-pat_alias(#c_literal{anno=A,val=[H|T]}=S, #c_cons{}=Cons) ->
- pat_alias(ann_c_cons_skel(A, #c_literal{anno=A,val=H},
- S#c_literal{val=T}), Cons);
-pat_alias(#c_cons{anno=Anno,hd=H1,tl=T1}, #c_cons{hd=H2,tl=T2}) ->
- ann_c_cons(Anno, pat_alias(H1, H2), pat_alias(T1, T2));
-pat_alias(#c_tuple{anno=Anno,es=Es1}, #c_literal{val=T}) when is_tuple(T) ->
- Es2 = [#c_literal{val=E} || E <- tuple_to_list(T)],
- ann_c_tuple(Anno, pat_alias_list(Es1, Es2));
-pat_alias(#c_literal{anno=Anno,val=T}, #c_tuple{es=Es2}) when is_tuple(T) ->
- Es1 = [#c_literal{val=E} || E <- tuple_to_list(T)],
- ann_c_tuple(Anno, pat_alias_list(Es1, Es2));
-pat_alias(#c_tuple{anno=Anno,es=Es1}, #c_tuple{es=Es2}) ->
- ann_c_tuple(Anno, pat_alias_list(Es1, Es2));
-pat_alias(#c_alias{var=V1,pat=P1},
- #c_alias{var=V2,pat=P2}) ->
- if V1 =:= V2 -> #c_alias{var=V1,pat=pat_alias(P1, P2)};
- true -> #c_alias{var=V1,pat=#c_alias{var=V2,pat=pat_alias(P1, P2)}}
+pat_alias(#c_var{name=V1}=P, #c_var{name=V1}) -> P;
+pat_alias(#c_var{name=V1}=Var,
+ #c_alias{var=#c_var{name=V2},pat=Pat}=Alias) ->
+ if
+ V1 =:= V2 ->
+ Alias;
+ true ->
+ Alias#c_alias{pat=pat_alias(Var, Pat)}
+ end;
+pat_alias(#c_var{}=P1, P2) -> #c_alias{var=P1,pat=P2};
+
+pat_alias(#c_alias{var=#c_var{name=V1}}=Alias, #c_var{name=V1}) ->
+ Alias;
+pat_alias(#c_alias{var=#c_var{name=V1}=Var1,pat=P1},
+ #c_alias{var=#c_var{name=V2}=Var2,pat=P2}) ->
+ Pat = pat_alias(P1, P2),
+ if
+ V1 =:= V2 ->
+ #c_alias{var=Var1,pat=Pat};
+ true ->
+ pat_alias(Var1, pat_alias(Var2, Pat))
end;
-pat_alias(#c_alias{var=V1,pat=P1}, P2) ->
- #c_alias{var=V1,pat=pat_alias(P1, P2)};
-pat_alias(P1, #c_alias{var=V2,pat=P2}) ->
- #c_alias{var=V2,pat=pat_alias(P1, P2)};
+pat_alias(#c_alias{var=#c_var{}=Var,pat=P1}, P2) ->
+ #c_alias{var=Var,pat=pat_alias(P1, P2)};
+
+pat_alias(#c_map{es=Es1}=M, #c_map{es=Es2}) ->
+ M#c_map{es=pat_alias_map_pairs(Es1 ++ Es2)};
+
+pat_alias(P1, #c_var{}=Var) ->
+ #c_alias{var=Var,pat=P1};
+pat_alias(P1, #c_alias{pat=P2}=Alias) ->
+ Alias#c_alias{pat=pat_alias(P1, P2)};
+
pat_alias(P1, P2) ->
- case {set_anno(P1, []),set_anno(P2, [])} of
- {P,P} -> P;
+ %% Aliases between binaries are not allowed, so the only
+ %% legal patterns that remain are data patterns.
+ case cerl:is_data(P1) andalso cerl:is_data(P2) of
+ false -> throw(nomatch);
+ true -> ok
+ end,
+ Type = cerl:data_type(P1),
+ case cerl:data_type(P2) of
+ Type -> ok;
_ -> throw(nomatch)
- end.
+ end,
+ Es1 = cerl:data_es(P1),
+ Es2 = cerl:data_es(P2),
+ Es = pat_alias_list(Es1, Es2),
+ cerl:make_data(Type, Es).
%% pat_alias_list([A1], [A2]) -> [A].
@@ -1697,9 +1720,15 @@ pat_alias_list([A1|A1s], [A2|A2s]) ->
pat_alias_list([], []) -> [];
pat_alias_list(_, _) -> throw(nomatch).
-%% pattern_list([P], State) -> [P].
+%% pattern_list([P], State) -> {[P],Exprs,St}
+
+pattern_list([P0|Ps0], St0) ->
+ {P1,Eps,St1} = pattern(P0, St0),
+ {Ps1,Epsl,St2} = pattern_list(Ps0, St1),
+ {[P1|Ps1], Eps ++ Epsl, St2};
+pattern_list([], St) ->
+ {[],[],St}.
-pattern_list(Ps, St) -> [pattern(P, St) || P <- Ps].
%% make_vars([Name]) -> [{Var,Name}].
@@ -1721,7 +1750,7 @@ new_var_name(#core{vcount=C}=St) ->
new_var(St) ->
new_var([], St).
-new_var(Anno, St0) ->
+new_var(Anno, St0) when is_list(Anno) ->
{New,St} = new_var_name(St0),
{#c_var{anno=Anno,name=New},St}.
@@ -1779,7 +1808,7 @@ uclauses(Lcs, Ks, St0) ->
uclause(Cl0, Ks, St0) ->
{Cl1,_Pvs,Used,New,St1} = uclause(Cl0, Ks, Ks, St0),
- A0 = get_ianno(Cl1),
+ A0 = get_anno(Cl1),
A = A0#a{us=Used,ns=New},
{Cl1#iclause{anno=A},St1}.
@@ -1948,11 +1977,11 @@ uexpr(#ibinary{anno=A,segments=Ss}, _, St) ->
uexpr(#c_literal{}=Lit, _, St) ->
Anno = get_anno(Lit),
{set_anno(Lit, #a{us=[],anno=Anno}),St};
-uexpr(Lit, _, St) ->
- true = is_simple(Lit), %Sanity check!
- Vs = lit_vars(Lit),
- Anno = get_anno(Lit),
- {set_anno(Lit, #a{us=Vs,anno=Anno}),St}.
+uexpr(Simple, _, St) ->
+ true = is_simple(Simple), %Sanity check!
+ Vs = lit_vars(Simple),
+ Anno = get_anno(Simple),
+ {#isimple{anno=#a{us=Vs,anno=Anno},term=Simple},St}.
uexpr_list(Les0, Ks, St0) ->
mapfoldl(fun (Le, St) -> uexpr(Le, Ks, St) end, St0, Les0).
@@ -1966,7 +1995,7 @@ ufun_clauses(Lcs, Ks, St0) ->
ufun_clause(Cl0, Ks, St0) ->
{Cl1,Pvs,Used,_,St1} = uclause(Cl0, [], Ks, St0),
- A0 = get_ianno(Cl1),
+ A0 = get_anno(Cl1),
A = A0#a{us=subtract(intersection(Used, Ks), Pvs),ns=[]},
{Cl1#iclause{anno=A},St1}.
@@ -1999,9 +2028,14 @@ upattern(#c_tuple{es=Es0}=Tuple, Ks, St0) ->
upattern(#c_map{es=Es0}=Map, Ks, St0) ->
{Es1,Esg,Esv,Eus,St1} = upattern_list(Es0, Ks, St0),
{Map#c_map{es=Es1},Esg,Esv,Eus,St1};
-upattern(#c_map_pair{op=#c_literal{val=exact},val=V0}=MapPair, Ks, St0) ->
- {V,Vg,Vv,Vu,St1} = upattern(V0, Ks, St0),
- {MapPair#c_map_pair{val=V},Vg,Vv,Vu,St1};
+upattern(#c_map_pair{op=#c_literal{val=exact},key=K0,val=V0}=Pair,Ks,St0) ->
+ {V,Vg,Vn,Vu,St1} = upattern(V0, Ks, St0),
+ % A variable key must be considered used here
+ Ku = case K0 of
+ #c_var{name=Name} -> [Name];
+ _ -> []
+ end,
+ {Pair#c_map_pair{val=V},Vg,Vn,union(Ku,Vu),St1};
upattern(#c_binary{segments=Es0}=Bin, Ks, St0) ->
{Es1,Esg,Esv,Eus,St1} = upat_bin(Es0, Ks, St0),
{Bin#c_binary{segments=Es1},Esg,Esv,Eus,St1};
@@ -2124,7 +2158,8 @@ cguard(Gs, St0) ->
cexprs([#iset{var=#c_var{name=Name}=Var}=Iset], As, St) ->
%% Make return value explicit, and make Var true top level.
- cexprs([Iset,Var#c_var{anno=#a{us=[Name]}}], As, St);
+ Isimple = #isimple{anno=#a{us=[Name]},term=Var},
+ cexprs([Iset,Isimple], As, St);
cexprs([Le], As, St0) ->
{Ce,Es,Us,St1} = cexpr(Le, As, St0),
Exp = make_vars(As), %The export variables
@@ -2239,12 +2274,9 @@ cexpr(#c_literal{}=Lit, _As, St) ->
Anno = get_anno(Lit),
Vs = Anno#a.us,
{set_anno(Lit, Anno#a.anno),[],Vs,St};
-cexpr(Lit, _As, St) ->
- true = is_simple(Lit), %Sanity check!
- Anno = get_anno(Lit),
- Vs = Anno#a.us,
- %%Vs = lit_vars(Lit),
- {set_anno(Lit, Anno#a.anno),[],Vs,St}.
+cexpr(#isimple{anno=#a{us=Vs},term=Simple}, _As, St) ->
+ true = is_simple(Simple), %Sanity check!
+ {Simple,[],Vs,St}.
cfun(#ifun{anno=A,id=Id,vars=Args,clauses=Lcs,fc=Lfc}, _As, St0) ->
{Ccs,St1} = cclauses(Lcs, [], St0), %NEVER export!
@@ -2267,11 +2299,6 @@ lit_vars(#c_map_pair{key=K,val=V}, Vs) -> lit_vars(K, lit_vars(V, Vs));
lit_vars(#c_var{name=V}, Vs) -> add_element(V, Vs);
lit_vars(_, Vs) -> Vs. %These are atomic
-% lit_bin_vars(Segs, Vs) ->
-% foldl(fun (#c_bitstr{val=V,size=S}, Vs0) ->
-% lit_vars(V, lit_vars(S, Vs0))
-% end, Vs, Segs).
-
lit_list_vars(Ls) -> lit_list_vars(Ls, []).
lit_list_vars(Ls, Vs) ->
@@ -2285,37 +2312,26 @@ bitstr_vars(Segs, Vs) ->
lit_vars(V, lit_vars(S, Vs0))
end, Vs, Segs).
-record_anno(L, St) when L >= ?REC_OFFSET ->
- case member(dialyzer, St#core.opts) of
- true ->
- [record | lineno_anno(L - ?REC_OFFSET, St)];
- false ->
- lineno_anno(L, St)
- end;
-record_anno(L, St) when L < -?REC_OFFSET ->
- case member(dialyzer, St#core.opts) of
+record_anno(L, St) ->
+ case
+ erl_anno:record(L) andalso member(dialyzer, St#core.opts)
+ of
true ->
- [record | lineno_anno(L + ?REC_OFFSET, St)];
+ [record | lineno_anno(L, St)];
false ->
- lineno_anno(L, St)
- end;
-record_anno(L, St) ->
+ full_anno(L, St)
+ end.
+
+full_anno(L, #core{wanted=false}=St) ->
+ [result_not_wanted|lineno_anno(L, St)];
+full_anno(L, #core{wanted=true}=St) ->
lineno_anno(L, St).
lineno_anno(L, St) ->
- {line, Line} = erl_parse:get_attribute(L, line),
- if
- Line < 0 ->
- [-Line] ++ St#core.file ++ [compiler_generated];
- true ->
- [Line] ++ St#core.file
- end.
-
-get_ianno(Ce) ->
- case get_anno(Ce) of
- #a{}=A -> A;
- A when is_list(A) -> #a{anno=A}
- end.
+ Line = erl_anno:line(L),
+ Generated = erl_anno:generated(L),
+ CompilerGenerated = [compiler_generated || Generated],
+ [Line] ++ St#core.file ++ CompilerGenerated.
get_lineno_anno(Ce) ->
case get_anno(Ce) of
@@ -2323,15 +2339,8 @@ get_lineno_anno(Ce) ->
A when is_list(A) -> A
end.
-location(L) ->
- {location,Location} = erl_parse:get_attribute(L, location),
- Location.
-
-abs_line(L) ->
- erl_parse:set_line(L, fun(Line) -> abs(Line) end).
-
-neg_line(L) ->
- erl_parse:set_line(L, fun(Line) -> -abs(Line) end).
+no_compiler_warning(Anno) ->
+ erl_anno:set_generated(true, Anno).
%%
%% The following three functions are used both with cerl:cerl() and with i()'s
@@ -2372,11 +2381,13 @@ format_error(nomatch) ->
"pattern cannot possibly match";
format_error(bad_binary) ->
"binary construction will fail because of a type mismatch";
-format_error(bad_map_key) ->
- "map construction will fail because of none literal key (large binaries are not literals)";
-format_error(bad_map) ->
+format_error(badmap) ->
"map construction will fail because of a type mismatch".
-add_warning(Line, Term, #core{ws=Ws,file=[{file,File}]}=St) when Line >= 0 ->
- St#core{ws=[{File,[{location(Line),?MODULE,Term}]}|Ws]};
-add_warning(_, _, St) -> St.
+add_warning(Anno, Term, #core{ws=Ws,file=[{file,File}]}=St) ->
+ case erl_anno:generated(Anno) of
+ false ->
+ St#core{ws=[{File,[{erl_anno:location(Anno),?MODULE,Term}]}|Ws]};
+ true ->
+ St
+ end.
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index 40d2f72b4c..7ee564683b 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -114,7 +115,7 @@ copy_anno(Kdst, Ksrc) ->
ff, %Current function
vcount=0, %Variable counter
fcount=0, %Fun counter
- ds=[], %Defined variables
+ ds=cerl_sets:new() :: cerl_sets:set(), %Defined variables
funs=[], %Fun functions
free=[], %Free variables
ws=[] :: [warning()], %Warnings.
@@ -131,12 +132,12 @@ module(#c_module{anno=A,name=M,exports=Es,attrs=As,defs=Fs}, _Options) ->
{ok,#k_mdef{anno=A,name=M#c_literal.val,exports=Kes,attributes=Kas,
body=Kfs ++ St#kern.funs},lists:sort(St#kern.ws)}.
-attributes([{#c_literal{val=Name},Val}|As]) ->
+attributes([{#c_literal{val=Name},#c_literal{val=Val}}|As]) ->
case include_attribute(Name) of
false ->
attributes(As);
true ->
- [{Name,core_lib:literal_value(Val)}|attributes(As)]
+ [{Name,Val}|attributes(As)]
end;
attributes([]) -> [].
@@ -148,7 +149,7 @@ include_attribute(_) -> true.
function({#c_var{name={F,Arity}=FA},Body}, St0) ->
try
- St1 = St0#kern{func=FA,ff=undefined,vcount=0,fcount=0,ds=sets:new()},
+ St1 = St0#kern{func=FA,ff=undefined,vcount=0,fcount=0,ds=cerl_sets:new()},
{#ifun{anno=Ab,vars=Kvs,body=B0},[],St2} = expr(Body, new_sub(), St1),
{B1,_,St3} = ubody(B0, return, St2),
%%B1 = B0, St3 = St2, %Null second pass
@@ -273,17 +274,7 @@ expr(#c_tuple{anno=A,es=Ces}, Sub, St0) ->
{Kes,Ep,St1} = atomic_list(Ces, Sub, St0),
{#k_tuple{anno=A,es=Kes},Ep,St1};
expr(#c_map{anno=A,arg=Var,es=Ces}, Sub, St0) ->
- try expr_map(A,Var,Ces,Sub,St0) of
- {_,_,_}=Res -> Res
- catch
- throw:bad_map ->
- St1 = add_warning(get_line(A), bad_map, A, St0),
- Erl = #c_literal{val=erlang},
- Name = #c_literal{val=error},
- Args = [#c_literal{val=badarg}],
- Error = #c_call{anno=A,module=Erl,name=Name,args=Args},
- expr(Error, Sub, St1)
- end;
+ expr_map(A, Var, Ces, Sub, St0);
expr(#c_binary{anno=A,segments=Cv}, Sub, St0) ->
try atomic_bin(Cv, Sub, St0) of
{Kv,Ep,St1} ->
@@ -506,82 +497,87 @@ translate_fc(Args) ->
[#c_literal{val=function_clause},make_list(Args)].
expr_map(A,Var0,Ces,Sub,St0) ->
- %% An extra pass of validation of Map src because of inlining
{Var,Mps,St1} = expr(Var0, Sub, St0),
- case is_valid_map_src(Var) of
- true ->
- {Km,Eps,St2} = map_split_pairs(A, Var, Ces, Sub, St1),
- {Km,Eps++Mps,St2};
- false -> throw(bad_map)
- end.
-
-is_valid_map_src(#k_map{}) -> true;
-is_valid_map_src(#k_literal{val=M}) when is_map(M) -> true;
-is_valid_map_src(#k_var{}) -> true;
-is_valid_map_src(_) -> false.
+ {Km,Eps,St2} = map_split_pairs(A, Var, Ces, Sub, St1),
+ {Km,Eps++Mps,St2}.
map_split_pairs(A, Var, Ces, Sub, St0) ->
- %% two steps
- %% 1. force variables
- %% 2. remove multiples
- Pairs0 = [{Op,K,V} || #c_map_pair{op=#c_literal{val=Op},key=K,val=V} <- Ces],
+ %% 1. Force variables.
+ %% 2. Group adjacent pairs with literal keys.
+ %% 3. Within each such group, remove multiple assignments to the same key.
+ %% 4. Partition each group according to operator ('=>' and ':=').
+ Pairs0 = [{Op,K,V} ||
+ #c_map_pair{op=#c_literal{val=Op},key=K,val=V} <- Ces],
{Pairs,Esp,St1} = foldr(fun
({Op,K0,V0}, {Ops,Espi,Sti0}) when Op =:= assoc; Op =:= exact ->
- {K,[],Sti1} = expr(K0, Sub, Sti0),
- {V,Ep,Sti2} = atomic(V0, Sub, Sti1),
- {[{Op,K,V}|Ops],Ep ++ Espi,Sti2}
+ {K,Eps1,Sti1} = atomic(K0, Sub, Sti0),
+ {V,Eps2,Sti2} = atomic(V0, Sub, Sti1),
+ {[{Op,K,V}|Ops],Eps1 ++ Eps2 ++ Espi,Sti2}
end, {[],[],St0}, Pairs0),
-
- case map_group_pairs(Pairs) of
- {Assoc,[]} ->
- Kes = [#k_map_pair{key=K,val=V}||{_,{assoc,K,V}} <- Assoc],
- {#k_map{anno=A,op=assoc,var=Var,es=Kes},Esp,St1};
- {[],Exact} ->
- Kes = [#k_map_pair{key=K,val=V}||{_,{exact,K,V}} <- Exact],
- {#k_map{anno=A,op=exact,var=Var,es=Kes},Esp,St1};
- {Assoc,Exact} ->
- Kes1 = [#k_map_pair{key=K,val=V}||{_,{assoc,K,V}} <- Assoc],
- {Mvar,Em,St2} = force_atomic(#k_map{anno=A,op=assoc,var=Var,es=Kes1},St1),
- Kes2 = [#k_map_pair{key=K,val=V}||{_,{exact,K,V}} <- Exact],
- {#k_map{anno=A,op=exact,var=Mvar,es=Kes2},Esp ++ Em,St2}
-
+ map_split_pairs_1(A, Var, Pairs, Esp, St1).
+
+map_split_pairs_1(A, Map0, [{Op,Key,Val}|Pairs1]=Pairs0, Esp0, St0) ->
+ {Map1,Em,St1} = force_atomic(Map0, St0),
+ case Key of
+ #k_var{} ->
+ %% Don't combine variable keys with other keys.
+ Kes = [#k_map_pair{key=Key,val=Val}],
+ Map = #k_map{anno=A,op=Op,var=Map1,es=Kes},
+ map_split_pairs_1(A, Map, Pairs1, Esp0 ++ Em, St1);
+ _ ->
+ %% Literal key. Split off all literal keys.
+ {L,Pairs} = splitwith(fun({_,#k_var{},_}) -> false;
+ ({_,_,_}) -> true
+ end, Pairs0),
+ {Map,Esp,St2} = map_group_pairs(A, Map1, L, Esp0 ++ Em, St1),
+ map_split_pairs_1(A, Map, Pairs, Esp, St2)
+ end;
+map_split_pairs_1(_, Map, [], Esp, St0) ->
+ {Map,Esp,St0}.
+
+map_group_pairs(A, Var, Pairs0, Esp, St0) ->
+ Pairs = map_remove_dup_keys(Pairs0),
+ Assoc = [#k_map_pair{key=K,val=V} || {_,{assoc,K,V}} <- Pairs],
+ Exact = [#k_map_pair{key=K,val=V} || {_,{exact,K,V}} <- Pairs],
+ case {Assoc,Exact} of
+ {[_|_],[]} ->
+ {#k_map{anno=A,op=assoc,var=Var,es=Assoc},Esp,St0};
+ {[],[_|_]} ->
+ {#k_map{anno=A,op=exact,var=Var,es=Exact},Esp,St0};
+ {[_|_],[_|_]} ->
+ Map = #k_map{anno=A,op=assoc,var=Var,es=Assoc},
+ {Mvar,Em,St1} = force_atomic(Map, St0),
+ {#k_map{anno=A,op=exact,var=Mvar,es=Exact},Esp ++ Em,St1}
end.
-%% Group map by Assoc operations and Exact operations
+map_remove_dup_keys(Es) ->
+ dict:to_list(map_remove_dup_keys(Es, dict:new())).
-map_group_pairs(Es) ->
- Groups = dict:to_list(map_group_pairs(Es,dict:new())),
- partition(fun({_,{Op,_,_}}) -> Op =:= assoc end, Groups).
-
-map_group_pairs([{assoc,K,V}|Es0],Used0) ->
- Used1 = case map_key_is_used(K,Used0) of
- {ok, {assoc,_,_}} -> map_key_set_used(K,{assoc,K,V},Used0);
- {ok, {exact,_,_}} -> map_key_set_used(K,{exact,K,V},Used0);
- _ -> map_key_set_used(K,{assoc,K,V},Used0)
- end,
- map_group_pairs(Es0,Used1);
-map_group_pairs([{exact,K,V}|Es0],Used0) ->
- Used1 = case map_key_is_used(K,Used0) of
- {ok, {assoc,_,_}} -> map_key_set_used(K,{assoc,K,V},Used0);
- {ok, {exact,_,_}} -> map_key_set_used(K,{exact,K,V},Used0);
- _ -> map_key_set_used(K,{exact,K,V},Used0)
- end,
- map_group_pairs(Es0,Used1);
-map_group_pairs([],Used) ->
- Used.
-
-map_key_set_used(K,How,Used) ->
- dict:store(map_key_clean(K),How,Used).
-
-map_key_is_used(K,Used) ->
- dict:find(map_key_clean(K),Used).
+map_remove_dup_keys([{assoc,K0,V}|Es0],Used0) ->
+ K = map_key_clean(K0),
+ Op = case dict:find(K, Used0) of
+ {ok,{exact,_,_}} -> exact;
+ _ -> assoc
+ end,
+ Used1 = dict:store(K, {Op,K0,V}, Used0),
+ map_remove_dup_keys(Es0, Used1);
+map_remove_dup_keys([{exact,K0,V}|Es0],Used0) ->
+ K = map_key_clean(K0),
+ Op = case dict:find(K, Used0) of
+ {ok,{assoc,_,_}} -> assoc;
+ _ -> exact
+ end,
+ Used1 = dict:store(K, {Op,K0,V}, Used0),
+ map_remove_dup_keys(Es0, Used1);
+map_remove_dup_keys([], Used) -> Used.
-%% Be explicit instead of using set_kanno(K,[])
-map_key_clean(#k_literal{val=V}) -> {k_literal,V};
-map_key_clean(#k_int{val=V}) -> {k_int,V};
-map_key_clean(#k_float{val=V}) -> {k_float,V};
-map_key_clean(#k_atom{val=V}) -> {k_atom,V};
-map_key_clean(#k_nil{}) -> k_nil.
+%% Be explicit instead of using set_kanno(K, []).
+map_key_clean(#k_var{name=V}) -> {var,V};
+map_key_clean(#k_literal{val=V}) -> {lit,V};
+map_key_clean(#k_int{val=V}) -> {lit,V};
+map_key_clean(#k_float{val=V}) -> {lit,V};
+map_key_clean(#k_atom{val=V}) -> {lit,V};
+map_key_clean(#k_nil{}) -> {lit,[]}.
%% call_type(Module, Function, Arity) -> call | bif | apply | error.
@@ -660,12 +656,12 @@ atomic_bin([#c_bitstr{anno=A,val=E0,size=S0,unit=U0,type=T,flags=Fs0}|Es0],
{E,Ap1,St1} = atomic(E0, Sub, St0),
{S1,Ap2,St2} = atomic(S0, Sub, St1),
validate_bin_element_size(S1),
- U1 = core_lib:literal_value(U0),
- Fs1 = core_lib:literal_value(Fs0),
+ U1 = cerl:concrete(U0),
+ Fs1 = cerl:concrete(Fs0),
{Es,Ap3,St3} = atomic_bin(Es0, Sub, St2),
{#k_bin_seg{anno=A,size=S1,
unit=U1,
- type=core_lib:literal_value(T),
+ type=cerl:concrete(T),
flags=Fs1,
seg=E,next=Es},
Ap1++Ap2++Ap3,St3};
@@ -720,15 +716,15 @@ force_variable(Ke, St0) ->
%% handling.
pattern(#c_var{anno=A,name=V}, _Isub, Osub, St0) ->
- case sets:is_element(V, St0#kern.ds) of
+ case cerl_sets:is_element(V, St0#kern.ds) of
true ->
{New,St1} = new_var_name(St0),
{#k_var{anno=A,name=New},
set_vsub(V, New, Osub),
- St1#kern{ds=sets:add_element(New, St1#kern.ds)}};
+ St1#kern{ds=cerl_sets:add_element(New, St1#kern.ds)}};
false ->
{#k_var{anno=A,name=V},Osub,
- St0#kern{ds=sets:add_element(V, St0#kern.ds)}}
+ St0#kern{ds=cerl_sets:add_element(V, St0#kern.ds)}}
end;
pattern(#c_literal{anno=A,val=Val}, _Isub, Osub, St) ->
{#k_literal{anno=A,val=Val},Osub,St};
@@ -757,23 +753,22 @@ flatten_alias(#c_alias{var=V,pat=P}) ->
flatten_alias(Pat) -> {[],Pat}.
pattern_map_pairs(Ces0, Isub, Osub0, St0) ->
- %% It is assumed that all core keys are literals
- %% It is later assumed that these keys are term sorted
- %% so we need to sort them here
- Ces1 = lists:sort(fun
- (#c_map_pair{key=CkA},#c_map_pair{key=CkB}) ->
- A = core_lib:literal_value(CkA),
- B = core_lib:literal_value(CkB),
- erts_internal:cmp_term(A,B) < 0
- end, Ces0),
%% pattern the pair keys and values as normal
{Kes,{Osub1,St1}} = lists:mapfoldl(fun
(#c_map_pair{anno=A,key=Ck,val=Cv},{Osubi0,Sti0}) ->
- {Kk,Osubi1,Sti1} = pattern(Ck, Isub, Osubi0, Sti0),
- {Kv,Osubi2,Sti2} = pattern(Cv, Isub, Osubi1, Sti1),
+ {Kk,[],Sti1} = expr(Ck, Isub, Sti0),
+ {Kv,Osubi2,Sti2} = pattern(Cv, Isub, Osubi0, Sti1),
{#k_map_pair{anno=A,key=Kk,val=Kv},{Osubi2,Sti2}}
- end, {Osub0, St0}, Ces1),
- {Kes,Osub1,St1}.
+ end, {Osub0, St0}, Ces0),
+ %% It is later assumed that these keys are term sorted
+ %% so we need to sort them here
+ Kes1 = lists:sort(fun
+ (#k_map_pair{key=KkA},#k_map_pair{key=KkB}) ->
+ A = map_key_clean(KkA),
+ B = map_key_clean(KkB),
+ erts_internal:cmp_term(A,B) < 0
+ end, Kes),
+ {Kes1,Osub1,St1}.
pattern_bin(Es, Isub, Osub0, St0) ->
{Kbin,{_,Osub},St} = pattern_bin_1(Es, Isub, Osub0, St0),
@@ -793,8 +788,8 @@ pattern_bin_1([#c_bitstr{anno=A,val=E0,size=S0,unit=U,type=T,flags=Fs}|Es0],
%% problems.
#k_atom{val=bad_size}
end,
- U0 = core_lib:literal_value(U),
- Fs0 = core_lib:literal_value(Fs),
+ U0 = cerl:concrete(U),
+ Fs0 = cerl:concrete(Fs),
%%ok= io:fwrite("~w: ~p~n", [?LINE,{B0,S,U0,Fs0}]),
{E,Osub1,St2} = pattern(E0, Isub0, Osub0, St1),
Isub1 = case E0 of
@@ -805,7 +800,7 @@ pattern_bin_1([#c_bitstr{anno=A,val=E0,size=S0,unit=U,type=T,flags=Fs}|Es0],
{Es,{Isub,Osub},St3} = pattern_bin_1(Es0, Isub1, Osub1, St2),
{#k_bin_seg{anno=A,size=S,
unit=U0,
- type=core_lib:literal_value(T),
+ type=cerl:concrete(T),
flags=Fs0,
seg=E,next=Es},
{Isub,Osub},St3};
@@ -842,12 +837,23 @@ get_vsub(V, Vsub) ->
set_vsub(V, S, Vsub) ->
orddict:store(V, S, Vsub).
-subst_vsub(V, S, Vsub0) ->
- %% Fold chained substitutions.
- Vsub1 = orddict:map(fun (_, V1) when V1 =:= V -> S;
- (_, V1) -> V1
- end, Vsub0),
- orddict:store(V, S, Vsub1).
+subst_vsub(Key, New, [{K,Key}|Dict]) ->
+ %% Fold chained substitution.
+ [{K,New}|subst_vsub(Key, New, Dict)];
+subst_vsub(Key, New, [{K,_}|_]=Dict) when Key < K ->
+ %% Insert the new substitution here, and continue
+ %% look for chained substitutions.
+ [{Key,New}|subst_vsub_1(Key, New, Dict)];
+subst_vsub(Key, New, [{K,_}=E|Dict]) when Key > K ->
+ [E|subst_vsub(Key, New, Dict)];
+subst_vsub(Key, New, []) -> [{Key,New}].
+
+subst_vsub_1(V, S, [{K,V}|Dict]) ->
+ %% Fold chained substitution.
+ [{K,S}|subst_vsub_1(V, S, Dict)];
+subst_vsub_1(V, S, [E|Dict]) ->
+ [E|subst_vsub_1(V, S, Dict)];
+subst_vsub_1(_, _, []) -> [].
get_fsub(F, A, Fsub) ->
case orddict:find({F,A}, Fsub) of
@@ -892,7 +898,7 @@ new_vars(0, St, Vs) -> {Vs,St}.
make_vars(Vs) -> [ #k_var{name=V} || V <- Vs ].
add_var_def(V, St) ->
- St#kern{ds=sets:add_element(V#k_var.name, St#kern.ds)}.
+ St#kern{ds=cerl_sets:add_element(V#k_var.name, St#kern.ds)}.
%%add_vars_def(Vs, St) ->
%% Ds = foldl(fun (#k_var{name=V}, Ds) -> add_element(V, Ds) end,
@@ -1550,13 +1556,11 @@ arg_val(Arg, C) ->
{set_kanno(S, []),U,T,Fs}
end;
#k_map{op=exact,es=Es} ->
- Keys = [begin
- #k_map_pair{key=#k_literal{val=Key}} = Pair,
- Key
- end || Pair <- Es],
- %% multiple keys may have the same name
- %% do not use ordsets
- lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) < 0 end, Keys)
+ lists:sort(fun(A,B) ->
+ %% on the form K :: {'lit' | 'var', term()}
+ %% lit < var as intended
+ erts_internal:cmp_term(A,B) < 0
+ end, [map_key_clean(Key) || #k_map_pair{key=Key} <- Es])
end.
%% ubody_used_vars(Expr, State) -> [UsedVar]
@@ -1943,6 +1947,7 @@ lit_list_vars(Ps) ->
%% pat_vars(Pattern) -> {[UsedVarName],[NewVarName]}.
%% Return variables in a pattern. All variables are new variables
%% except those in the size field of binary segments.
+%% and map_pair keys
pat_vars(#k_var{name=N}) -> {[],[N]};
%%pat_vars(#k_char{}) -> {[],[]};
@@ -1967,8 +1972,10 @@ pat_vars(#k_tuple{es=Es}) ->
pat_list_vars(Es);
pat_vars(#k_map{es=Es}) ->
pat_list_vars(Es);
-pat_vars(#k_map_pair{val=V}) ->
- pat_vars(V).
+pat_vars(#k_map_pair{key=K,val=V}) ->
+ {U1,New} = pat_vars(V),
+ {[], U2} = pat_vars(K),
+ {union(U1,U2),New}.
pat_list_vars(Ps) ->
foldl(fun (P, {Used0,New0}) ->
@@ -2009,9 +2016,7 @@ format_error(nomatch_shadow) ->
format_error(bad_call) ->
"invalid module and/or function name; this call will always fail";
format_error(bad_segment_size) ->
- "binary construction will fail because of a type mismatch";
-format_error(bad_map) ->
- "map construction will fail because of a type mismatch".
+ "binary construction will fail because of a type mismatch".
add_warning(none, Term, Anno, #kern{ws=Ws}=St) ->
File = get_file(Anno),
diff --git a/lib/compiler/src/v3_kernel.hrl b/lib/compiler/src/v3_kernel.hrl
index ab66445f73..03b2eae006 100644
--- a/lib/compiler/src/v3_kernel.hrl
+++ b/lib/compiler/src/v3_kernel.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -38,7 +39,7 @@
-record(k_nil, {anno=[]}).
-record(k_tuple, {anno=[],es}).
--record(k_map, {anno=[],var,op,es}).
+-record(k_map, {anno=[],var=#k_literal{val=#{}},op,es}).
-record(k_map_pair, {anno=[],key,val}).
-record(k_cons, {anno=[],hd,tl}).
-record(k_binary, {anno=[],segs}).
diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl
index b33eba50eb..03b034ae98 100644
--- a/lib/compiler/src/v3_kernel_pp.erl
+++ b/lib/compiler/src/v3_kernel_pp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl
index cd4b5fd674..fa057ae211 100644
--- a/lib/compiler/src/v3_life.erl
+++ b/lib/compiler/src/v3_life.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -45,7 +46,7 @@
-export([vdb_find/2]).
--import(lists, [member/2,map/2,foldl/3,reverse/1,sort/1]).
+-import(lists, [member/2,map/2,reverse/1,sort/1]).
-import(ordsets, [add_element/2,intersection/2,union/2]).
-include("v3_kernel.hrl").
@@ -68,7 +69,7 @@ functions([], Acc) -> reverse(Acc).
function(#k_fdef{anno=#k{a=Anno},func=F,arity=Ar,vars=Vs,body=Kb}) ->
try
As = var_list(Vs),
- Vdb0 = foldl(fun ({var,N}, Vdb) -> new_var(N, 0, Vdb) end, [], As),
+ Vdb0 = init_vars(As),
%% Force a top-level match!
B0 = case Kb of
#k_match{} -> Kb;
@@ -94,14 +95,14 @@ function(#k_fdef{anno=#k{a=Anno},func=F,arity=Ar,vars=Vs,body=Kb}) ->
body(#k_seq{arg=Ke,body=Kb}, I, Vdb0) ->
%%ok = io:fwrite("life ~w:~p~n", [?LINE,{Ke,I,Vdb0}]),
A = get_kanno(Ke),
- Vdb1 = use_vars(A#k.us, I, new_vars(A#k.ns, I, Vdb0)),
+ Vdb1 = use_vars(union(A#k.us, A#k.ns), I, Vdb0),
{Es,MaxI,Vdb2} = body(Kb, I+1, Vdb1),
E = expr(Ke, I, Vdb2),
{[E|Es],MaxI,Vdb2};
body(Ke, I, Vdb0) ->
%%ok = io:fwrite("life ~w:~p~n", [?LINE,{Ke,I,Vdb0}]),
A = get_kanno(Ke),
- Vdb1 = use_vars(A#k.us, I, new_vars(A#k.ns, I, Vdb0)),
+ Vdb1 = use_vars(union(A#k.us, A#k.ns), I, Vdb0),
E = expr(Ke, I, Vdb1),
{[E],I,Vdb1}.
@@ -150,12 +151,12 @@ expr(#k_try_enter{anno=A,arg=Ka,vars=Vs,body=Kb,evars=Evs,handler=Kh}, I, Vdb) -
%% the body and handler. Add try tag 'variable'.
Ab = get_kanno(Kb),
Ah = get_kanno(Kh),
- Tdb1 = use_vars(Ab#k.us, I+3, use_vars(Ah#k.us, I+3, Tdb0)),
+ Tdb1 = use_vars(union(Ab#k.us, Ah#k.us), I+3, Tdb0),
Tdb2 = vdb_sub(I, I+2, Tdb1),
Vnames = fun (Kvar) -> Kvar#k_var.name end, %Get the variable names
{Aes,_,Adb} = body(Ka, I+2, add_var({catch_tag,I+1}, I+1, 1000000, Tdb2)),
- {Bes,_,Bdb} = body(Kb, I+4, new_vars(map(Vnames, Vs), I+3, Tdb2)),
- {Hes,_,Hdb} = body(Kh, I+4, new_vars(map(Vnames, Evs), I+3, Tdb2)),
+ {Bes,_,Bdb} = body(Kb, I+4, new_vars(sort(map(Vnames, Vs)), I+3, Tdb2)),
+ {Hes,_,Hdb} = body(Kh, I+4, new_vars(sort(map(Vnames, Evs)), I+3, Tdb2)),
#l{ke={try_enter,#l{ke={block,Aes},i=I+1,vdb=Adb,a=[]},
var_list(Vs),#l{ke={block,Bes},i=I+3,vdb=Bdb,a=[]},
var_list(Evs),#l{ke={block,Hes},i=I+3,vdb=Hdb,a=[]}},
@@ -171,7 +172,7 @@ expr(#k_receive{anno=A,var=V,body=Kb,timeout=T,action=Ka,ret=Rs}, I, Vdb) ->
%% Work out imported variables which need to be locked.
Rdb = vdb_sub(I, I+1, Vdb),
M = match(Kb, add_element(V#k_var.name, A#k.us), I+1, [],
- new_var(V#k_var.name, I, Rdb)),
+ new_vars([V#k_var.name], I, Rdb)),
{Tes,_,Adb} = body(Ka, I+1, Rdb),
#l{ke={receive_loop,atomic(T),variable(V),M,
#l{ke=Tes,i=I+1,vdb=Adb,a=[]},var_list(Rs)},
@@ -199,12 +200,12 @@ body_try(#k_try{anno=A,arg=Ka,vars=Vs,body=Kb,evars=Evs,handler=Kh,ret=Rs},
%% the body and handler. Add try tag 'variable'.
Ab = get_kanno(Kb),
Ah = get_kanno(Kh),
- Tdb1 = use_vars(Ab#k.us, I+3, use_vars(Ah#k.us, I+3, Tdb0)),
+ Tdb1 = use_vars(union(Ab#k.us, Ah#k.us), I+3, Tdb0),
Tdb2 = vdb_sub(I, I+2, Tdb1),
Vnames = fun (Kvar) -> Kvar#k_var.name end, %Get the variable names
{Aes,_,Adb} = body(Ka, I+2, add_var({catch_tag,I+1}, I+1, locked, Tdb2)),
- {Bes,_,Bdb} = body(Kb, I+4, new_vars(map(Vnames, Vs), I+3, Tdb2)),
- {Hes,_,Hdb} = body(Kh, I+4, new_vars(map(Vnames, Evs), I+3, Tdb2)),
+ {Bes,_,Bdb} = body(Kb, I+4, new_vars(sort(map(Vnames, Vs)), I+3, Tdb2)),
+ {Hes,_,Hdb} = body(Kh, I+4, new_vars(sort(map(Vnames, Evs)), I+3, Tdb2)),
#l{ke={'try',#l{ke={block,Aes},i=I+1,vdb=Adb,a=[]},
var_list(Vs),#l{ke={block,Bes},i=I+3,vdb=Bdb,a=[]},
var_list(Evs),#l{ke={block,Hes},i=I+3,vdb=Hdb,a=[]},
@@ -270,7 +271,7 @@ match(#k_select{anno=A,var=V,types=Kts}, Ls0, I, Ctxt, Vdb0) ->
end,
Vdb1 = use_vars(union(A#k.us, Ls1), I, Vdb0),
Ts = [type_clause(Tc, Ls1, I+1, Ctxt, Vdb1) || Tc <- Kts],
- #l{ke={select,literal2(V, Ctxt),Ts},i=I,vdb=Vdb1,a=Anno};
+ #l{ke={select,literal(V, Ctxt),Ts},i=I,vdb=Vdb1,a=Anno};
match(#k_guard{anno=A,clauses=Kcs}, Ls, I, Ctxt, Vdb0) ->
Vdb1 = use_vars(union(A#k.us, Ls), I, Vdb0),
Cs = [guard_clause(G, Ls, I+1, Ctxt, Vdb1) || G <- Kcs],
@@ -297,7 +298,7 @@ val_clause(#k_val_clause{anno=A,val=V,body=Kb}, Ls0, I, Ctxt0, Vdb0) ->
_ -> Ctxt0
end,
B = match(Kb, Ls1, I+1, Ctxt, Vdb1),
- #l{ke={val_clause,literal2(V, Ctxt),B},i=I,vdb=use_vars(Bus, I+1, Vdb1),a=A#k.a}.
+ #l{ke={val_clause,literal(V, Ctxt),B},i=I,vdb=use_vars(Bus, I+1, Vdb1),a=A#k.a}.
guard_clause(#k_guard_clause{anno=A,guard=Kg,body=Kb}, Ls, I, Ctxt, Vdb0) ->
Vdb1 = use_vars(union(A#k.us, Ls), I+2, Vdb0),
@@ -350,6 +351,7 @@ atomic_list(Ks) -> [atomic(K) || K <- Ks].
%% literal_list([Klit]) -> [Lit].
literal(#k_var{name=N}, _) -> {var,N};
+literal(#k_literal{val=I}, _) -> {literal,I};
literal(#k_int{val=I}, _) -> {integer,I};
literal(#k_float{val=F}, _) -> {float,F};
literal(#k_atom{val=N}, _) -> {atom,N};
@@ -358,58 +360,29 @@ literal(#k_nil{}, _) -> nil;
literal(#k_cons{hd=H,tl=T}, Ctxt) ->
{cons,[literal(H, Ctxt),literal(T, Ctxt)]};
literal(#k_binary{segs=V}, Ctxt) ->
- {binary,literal(V, Ctxt)};
+ {binary,literal(V, Ctxt)};
+literal(#k_bin_seg{size=S,unit=U,type=T,flags=Fs,seg=Seg,next=[]}, Ctxt) ->
+ %% Only occurs in patterns.
+ {bin_seg,Ctxt,literal(S, Ctxt),U,T,Fs,[literal(Seg, Ctxt)]};
literal(#k_bin_seg{size=S,unit=U,type=T,flags=Fs,seg=Seg,next=N}, Ctxt) ->
{bin_seg,Ctxt,literal(S, Ctxt),U,T,Fs,
[literal(Seg, Ctxt),literal(N, Ctxt)]};
+literal(#k_bin_int{size=S,unit=U,flags=Fs,val=Int,next=N}, Ctxt) ->
+ %% Only occurs in patterns.
+ {bin_int,Ctxt,literal(S, Ctxt),U,Fs,Int,
+ [literal(N, Ctxt)]};
literal(#k_bin_end{}, Ctxt) ->
{bin_end,Ctxt};
literal(#k_tuple{es=Es}, Ctxt) ->
{tuple,literal_list(Es, Ctxt)};
-literal(#k_map{op=Op,var=Var,es=Es}, Ctxt) ->
- {map,Op,literal(Var, Ctxt),literal_list(Es, Ctxt)};
+literal(#k_map{op=Op,var=Var,es=Es0}, Ctxt) ->
+ {map,Op,literal(Var, Ctxt),literal_list(Es0, Ctxt)};
literal(#k_map_pair{key=K,val=V}, Ctxt) ->
- {map_pair,literal(K, Ctxt),literal(V, Ctxt)};
-literal(#k_literal{val=V}, _Ctxt) ->
- {literal,V}.
+ {map_pair,literal(K, Ctxt),literal(V, Ctxt)}.
literal_list(Ks, Ctxt) ->
[literal(K, Ctxt) || K <- Ks].
-literal2(#k_var{name=N}, _) -> {var,N};
-literal2(#k_literal{val=I}, _) -> {literal,I};
-literal2(#k_int{val=I}, _) -> {integer,I};
-literal2(#k_float{val=F}, _) -> {float,F};
-literal2(#k_atom{val=N}, _) -> {atom,N};
-%%literal2(#k_char{val=C}, _) -> {char,C};
-literal2(#k_nil{}, _) -> nil;
-literal2(#k_cons{hd=H,tl=T}, Ctxt) ->
- {cons,[literal2(H, Ctxt),literal2(T, Ctxt)]};
-literal2(#k_binary{segs=V}, Ctxt) ->
- {binary,literal2(V, Ctxt)};
-literal2(#k_bin_seg{size=S,unit=U,type=T,flags=Fs,seg=Seg,next=[]}, Ctxt) ->
- {bin_seg,Ctxt,literal2(S, Ctxt),U,T,Fs,[literal2(Seg, Ctxt)]};
-literal2(#k_bin_seg{size=S,unit=U,type=T,flags=Fs,seg=Seg,next=N}, Ctxt) ->
- {bin_seg,Ctxt,literal2(S, Ctxt),U,T,Fs,
- [literal2(Seg, Ctxt),literal2(N, Ctxt)]};
-literal2(#k_bin_int{size=S,unit=U,flags=Fs,val=Int,next=N}, Ctxt) ->
- {bin_int,Ctxt,literal2(S, Ctxt),U,Fs,Int,
- [literal2(N, Ctxt)]};
-literal2(#k_bin_end{}, Ctxt) ->
- {bin_end,Ctxt};
-literal2(#k_tuple{es=Es}, Ctxt) ->
- {tuple,literal_list2(Es, Ctxt)};
-literal2(#k_map{op=Op,es=Es}, Ctxt) ->
- {map,Op,literal_list2(Es, Ctxt)};
-literal2(#k_map_pair{key=K,val=V}, Ctxt) ->
- {map_pair,literal2(K, Ctxt),literal2(V, Ctxt)}.
-
-literal_list2(Ks, Ctxt) ->
- [literal2(K, Ctxt) || K <- Ks].
-
-%% literal_bin(#k_bin_seg{size=S,unit=U,type=T,flags=Fs,seg=Seg,next=N}) ->
-%% {bin_seg,literal(S),U,T,Fs,[literal(Seg),literal(N)]}
-
%% is_gc_bif(Name, Arity) -> true|false
%% Determines whether the BIF Name/Arity might do a GC.
@@ -428,79 +401,78 @@ is_gc_bif(Bif, Arity) ->
erl_internal:new_type_test(Bif, Arity) orelse
erl_internal:comp_op(Bif, Arity)).
-%% new_var(VarName, I, Vdb) -> Vdb.
+%% Keep track of life time for variables.
+%%
+%% init_vars([{var,VarName}]) -> Vdb.
%% new_vars([VarName], I, Vdb) -> Vdb.
-%% use_var(VarName, I, Vdb) -> Vdb.
%% use_vars([VarName], I, Vdb) -> Vdb.
%% add_var(VarName, F, L, Vdb) -> Vdb.
+%%
+%% The list of variable names for new_vars/3 and use_vars/3
+%% must be sorted.
-new_var(V, I, Vdb) ->
- vdb_store_new(V, I, I, Vdb).
+init_vars(Vs) ->
+ vdb_new(Vs).
-new_vars(Vs, I, Vdb0) ->
- foldl(fun (V, Vdb) -> new_var(V, I, Vdb) end, Vdb0, Vs).
+new_vars([], _, Vdb) -> Vdb;
+new_vars([V], I, Vdb) -> vdb_store_new(V, {V,I,I}, Vdb);
+new_vars(Vs, I, Vdb) -> vdb_update_vars(Vs, Vdb, I).
-use_var(V, I, Vdb) ->
+use_vars([], _, Vdb) ->
+ Vdb;
+use_vars([V], I, Vdb) ->
case vdb_find(V, Vdb) of
- {V,F,L} when I > L -> vdb_update(V, F, I, Vdb);
+ {V,F,L} when I > L -> vdb_update(V, {V,F,I}, Vdb);
{V,_,_} -> Vdb;
- error -> vdb_store_new(V, I, I, Vdb)
- end.
+ error -> vdb_store_new(V, {V,I,I}, Vdb)
+ end;
+use_vars(Vs, I, Vdb) -> vdb_update_vars(Vs, Vdb, I).
-use_vars([], _, Vdb) -> Vdb;
-use_vars([V], I, Vdb) -> use_var(V, I, Vdb);
-use_vars(Vs, I, Vdb) ->
- Res = use_vars_1(sort(Vs), Vdb, I),
- %% The following line can be used as an assertion.
- %% Res = foldl(fun (V, Vdb) -> use_var(V, I, Vdb) end, Vdb, Vs),
- Res.
+add_var(V, F, L, Vdb) ->
+ vdb_store_new(V, {V,F,L}, Vdb).
-%% Measurements show that it is worthwhile having this special
-%% function that updates/inserts several variables at once.
+%% is_in_guard() -> true|false.
-use_vars_1([V|_]=Vs, [{V1,_,_}=Vd|Vdb], I) when V > V1 ->
- [Vd|use_vars_1(Vs, Vdb, I)];
-use_vars_1([V|Vs], [{V1,_,_}|_]=Vdb, I) when V < V1 ->
- %% New variable.
- [{V,I,I}|use_vars_1(Vs, Vdb, I)];
-use_vars_1([V|Vs], [{_,F,L}=Vd|Vdb], I) ->
- %% Existing variable.
- if
- I > L ->[{V,F,I}|use_vars_1(Vs, Vdb, I)];
- true -> [Vd|use_vars_1(Vs, Vdb, I)]
- end;
-use_vars_1([V|Vs], [], I) ->
- %% New variable.
- [{V,I,I}|use_vars_1(Vs, [], I)];
-use_vars_1([], Vdb, _) -> Vdb.
+is_in_guard() ->
+ get(guard_refc) > 0.
-add_var(V, F, L, Vdb) ->
- vdb_store_new(V, F, L, Vdb).
+%% vdb
+
+vdb_new(Vs) ->
+ sort([{V,0,0} || {var,V} <- Vs]).
vdb_find(V, Vdb) ->
- %% Performance note: Profiling shows that this function accounts for
- %% a lot of the execution time when huge constant terms are built.
- %% Using the BIF lists:keyfind/3 is a lot faster than the
- %% original Erlang version.
case lists:keyfind(V, 1, Vdb) of
false -> error;
Vd -> Vd
end.
-%vdb_find(V, [{V1,F,L}=Vd|Vdb]) when V < V1 -> error;
-%vdb_find(V, [{V1,F,L}=Vd|Vdb]) when V == V1 -> Vd;
-%vdb_find(V, [{V1,F,L}=Vd|Vdb]) when V > V1 -> vdb_find(V, Vdb);
-%vdb_find(V, []) -> error.
+vdb_update(V, Update, [{V,_,_}|Vdb]) ->
+ [Update|Vdb];
+vdb_update(V, Update, [Vd|Vdb]) ->
+ [Vd|vdb_update(V, Update, Vdb)].
-vdb_update(V, F, L, [{V1,_,_}=Vd|Vdb]) when V > V1 ->
- [Vd|vdb_update(V, F, L, Vdb)];
-vdb_update(V, F, L, [{V1,_,_}|Vdb]) when V == V1 ->
- [{V,F,L}|Vdb].
+vdb_store_new(V, New, [{V1,_,_}=Vd|Vdb]) when V > V1 ->
+ [Vd|vdb_store_new(V, New, Vdb)];
+vdb_store_new(V, New, [{V1,_,_}|_]=Vdb) when V < V1 ->
+ [New|Vdb];
+vdb_store_new(_, New, []) -> [New].
-vdb_store_new(V, F, L, [{V1,_,_}=Vd|Vdb]) when V > V1 ->
- [Vd|vdb_store_new(V, F, L, Vdb)];
-vdb_store_new(V, F, L, [{V1,_,_}|_]=Vdb) when V < V1 -> [{V,F,L}|Vdb];
-vdb_store_new(V, F, L, []) -> [{V,F,L}].
+vdb_update_vars([V|_]=Vs, [{V1,_,_}=Vd|Vdb], I) when V > V1 ->
+ [Vd|vdb_update_vars(Vs, Vdb, I)];
+vdb_update_vars([V|Vs], [{V1,_,_}|_]=Vdb, I) when V < V1 ->
+ %% New variable.
+ [{V,I,I}|vdb_update_vars(Vs, Vdb, I)];
+vdb_update_vars([V|Vs], [{_,F,L}=Vd|Vdb], I) ->
+ %% Existing variable.
+ if
+ I > L -> [{V,F,I}|vdb_update_vars(Vs, Vdb, I)];
+ true -> [Vd|vdb_update_vars(Vs, Vdb, I)]
+ end;
+vdb_update_vars([V|Vs], [], I) ->
+ %% New variable.
+ [{V,I,I}|vdb_update_vars(Vs, [], I)];
+vdb_update_vars([], Vdb, _) -> Vdb.
%% vdb_sub(Min, Max, Vdb) -> Vdb.
%% Extract variables which are used before and after Min. Lock
@@ -510,8 +482,3 @@ vdb_sub(Min, Max, Vdb) ->
[ if L >= Max -> {V,F,locked};
true -> Vd
end || {V,F,L}=Vd <- Vdb, F < Min, L >= Min ].
-
-%% is_in_guard() -> true|false.
-
-is_in_guard() ->
- get(guard_refc) > 0.
diff --git a/lib/compiler/src/v3_life.hrl b/lib/compiler/src/v3_life.hrl
index 541e4cf66d..29a08f8c72 100644
--- a/lib/compiler/src/v3_life.hrl
+++ b/lib/compiler/src/v3_life.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index 0b56a49cd6..6553d10077 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -11,6 +11,7 @@ MODULES= \
beam_validator_SUITE \
beam_disasm_SUITE \
beam_except_SUITE \
+ beam_utils_SUITE \
bs_bincomp_SUITE \
bs_bit_binaries_SUITE \
bs_construct_SUITE \
@@ -32,14 +33,17 @@ MODULES= \
num_bif_SUITE \
receive_SUITE \
record_SUITE \
+ regressions_SUITE \
trycatch_SUITE \
warnings_SUITE \
+ z_SUITE \
test_lib
NO_OPT= \
andor \
apply \
beam_except \
+ beam_utils \
bs_construct \
bs_match \
bs_utf \
@@ -59,6 +63,7 @@ NO_OPT= \
INLINE= \
andor \
apply \
+ beam_utils \
bs_bincomp \
bs_bit_binaries \
bs_construct \
@@ -76,12 +81,6 @@ INLINE= \
receive \
record
-CORE_MODULES = \
- bs_shadowed_size_var \
- unused_multiple_values_error \
- nested_call_in_case
-
-
NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE)
NO_OPT_ERL_FILES= $(NO_OPT_MODULES:%=%.erl)
POST_OPT_MODULES= $(NO_OPT:%=%_post_opt_SUITE)
@@ -91,8 +90,6 @@ INLINE_ERL_FILES= $(INLINE_MODULES:%=%.erl)
ERL_FILES= $(MODULES:%=%.erl)
-CORE_FILES= $(CORE_MODULES:%=%.core)
-
##TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
##INSTALL_PROGS= $(TARGET_FILES)
@@ -108,7 +105,7 @@ RELSYSDIR = $(RELEASE_PATH)/compiler_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include +clint
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include +clint +clint0
EBIN = .
@@ -159,7 +156,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) "$(RELSYSDIR)"
$(INSTALL_DATA) compiler.spec compiler.cover \
- $(EMAKEFILE) $(ERL_FILES) $(CORE_FILES) "$(RELSYSDIR)"
+ $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \
$(INLINE_ERL_FILES) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index b5408ecd8f..fae9597c8a 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,7 +34,7 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[t_case,t_and_or,t_andalso,t_orelse,inside,overlap,
combined,in_case,before_and_inside_if]}].
@@ -173,7 +174,13 @@ t_and_or(Config) when is_list(Config) ->
true = (fun (X = true) when X or true or X -> true end)(True),
- ok.
+ Tuple = id({a,b}),
+ case Tuple of
+ {_,_} ->
+ {'EXIT',{badarg,_}} = (catch true and Tuple)
+ end,
+
+ ok.
t_andalso(Config) when is_list(Config) ->
Bs = [true,false],
@@ -364,6 +371,11 @@ combined(Config) when is_list(Config) ->
?line true = ?COMB(false, blurf, true),
?line true = ?COMB(true, true, blurf),
+ false = simple_comb(false, false),
+ false = simple_comb(false, true),
+ false = simple_comb(true, false),
+ true = simple_comb(true, true),
+
ok.
-undef(COMB).
@@ -390,6 +402,13 @@ comb(A, B, C) ->
end,
id(Res).
+simple_comb(A, B) ->
+ %% Use Res twice, to ensure that a careless optimization of 'not'
+ %% doesn't leave Res as a free variable.
+ Res = A andalso B,
+ _ = id(not Res),
+ Res.
+
%% Test that a boolean expression in a case expression is properly
%% optimized (in particular, that the error behaviour is correct).
in_case(Config) when is_list(Config) ->
diff --git a/lib/compiler/test/apply_SUITE.erl b/lib/compiler/test/apply_SUITE.erl
index 25f8a8dfb5..3425553fed 100644
--- a/lib/compiler/test/apply_SUITE.erl
+++ b/lib/compiler/test/apply_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/beam_disasm_SUITE.erl b/lib/compiler/test/beam_disasm_SUITE.erl
index 62afc80ca6..4dd92e7ed9 100644
--- a/lib/compiler/test/beam_disasm_SUITE.erl
+++ b/lib/compiler/test/beam_disasm_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/test/beam_except_SUITE.erl b/lib/compiler/test/beam_except_SUITE.erl
index d088863c5c..afacb939d1 100644
--- a/lib/compiler/test/beam_except_SUITE.erl
+++ b/lib/compiler/test/beam_except_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/test/beam_utils_SUITE.erl b/lib/compiler/test/beam_utils_SUITE.erl
new file mode 100644
index 0000000000..70c00f163c
--- /dev/null
+++ b/lib/compiler/test/beam_utils_SUITE.erl
@@ -0,0 +1,237 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(beam_utils_SUITE).
+
+-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ apply_fun/1,apply_mf/1,bs_init/1,bs_save/1,
+ is_not_killed/1,is_not_used_at/1,
+ select/1,y_catch/1]).
+-export([id/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(?MODULE),
+ [{group,p}].
+
+groups() ->
+ [{p,[parallel],
+ [apply_fun,
+ apply_mf,
+ bs_init,
+ bs_save,
+ is_not_killed,
+ is_not_used_at,
+ select,
+ y_catch
+ ]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+apply_fun(_Config) ->
+ 3 = do_apply_fun(false, false),
+ 3 = do_apply_fun(false, true),
+ 3 = do_apply_fun(true, false),
+ 2 = do_apply_fun(true, true),
+ ok.
+
+do_apply_fun(X, Y) ->
+ F = fun(I) -> I+1 end,
+ Arg = case X andalso id(Y) of
+ true -> 1;
+ false -> 2
+ end,
+ F(Arg).
+
+apply_mf(_Config) ->
+ ok = do_apply_mf_used({a,b}, ?MODULE, id),
+ error = do_apply_mf_used([a], ?MODULE, id),
+ {'EXIT',{{case_clause,{[],b}},_}} = (catch do_apply_mf_used({[],b}, ?MODULE, id)),
+
+ error = do_apply_mf_killed({error,[a]}, ?MODULE, id),
+ ok = do_apply_mf_killed([b], ?MODULE, id),
+ {'EXIT',{{case_clause,{a,[b]}},_}} = (catch do_apply_mf_killed({a,[b]}, ?MODULE, id)),
+ {'EXIT',{{case_clause,{error,[]}},_}} = (catch do_apply_mf_killed({error,[]}, ?MODULE, id)),
+
+ ok.
+
+do_apply_mf_used(Arg, Mod, Func) ->
+ Res = case id(Arg) of
+ {Decoded,_} when Decoded =/= [] ->
+ ok;
+ List when is_list(List) ->
+ error
+ end,
+ Mod:Func(Res).
+
+do_apply_mf_killed(Arg, Mod, Func) ->
+ Res = case id(Arg) of
+ {Tag,Decoded} when Decoded =/= [], Tag =:= error ->
+ error;
+ List when is_list(List) ->
+ ok
+ end,
+ Mod:Func(Res).
+
+bs_init(_Config) ->
+ <<7>> = do_bs_init_1([?MODULE], 7),
+ error = do_bs_init_1([?MODULE], 0.0),
+ error = do_bs_init_1([?MODULE], -43),
+ error = do_bs_init_1([?MODULE], 42),
+
+ <<>> = do_bs_init_2([]),
+ <<0:32,((1 bsl 32)-1):32>> = do_bs_init_2([0,(1 bsl 32)-1]),
+ {'EXIT',{badarg,_}} = (catch do_bs_init_2([0.5])),
+ {'EXIT',{badarg,_}} = (catch do_bs_init_2([-1])),
+ {'EXIT',{badarg,_}} = (catch do_bs_init_2([1 bsl 32])),
+ ok.
+
+do_bs_init_1([?MODULE], Sz) ->
+ if
+ is_integer(Sz), Sz >= -42, Sz < 42 ->
+ id(<<Sz:8>>);
+ true ->
+ error
+ end.
+
+do_bs_init_2(SigNos) ->
+ << <<SigNo:32>> ||
+ SigNo <- SigNos,
+ (is_integer(SigNo) andalso SigNo >= 0 andalso SigNo < (1 bsl 32)) orelse
+ erlang:error(badarg)
+ >>.
+
+
+bs_save(_Config) ->
+ {a,30,<<>>} = do_bs_save(<<1:1,30:5>>),
+ {b,127,<<>>} = do_bs_save(<<1:1,31:5,0:1,127:7>>),
+ {c,127,<<>>} = do_bs_save(<<1:1,31:5,1:1,127:7>>),
+ {c,127,<<>>} = do_bs_save(<<0:1,31:5,1:1,127:7>>),
+ {d,1024,<<>>} = do_bs_save(<<0:1,31:5>>),
+ ok.
+
+do_bs_save(<<_:1, Tag:5, T/binary>>) when Tag < 31 ->
+ {a,Tag,T};
+do_bs_save(<<1:1, 31:5, 0:1, Tag:7, T/binary>>) ->
+ {b,Tag,T};
+do_bs_save(<<_:1, 31:5, 1:1, Tag:7, T/binary>>) ->
+ {c,Tag,T};
+do_bs_save(<<_:1, 31:5, T/binary>>) ->
+ {d,1024,T}.
+
+is_not_killed(_Config) ->
+ {Pid,Ref} = spawn_monitor(fun() -> exit(banan) end),
+ receive
+ {'DOWN', Ref, process, Pid, banan} ->
+ ok
+ end,
+ receive after 0 -> ok end.
+
+is_not_used_at(_Config) ->
+ {a,b} = do_is_not_used_at(a, [{a,b}]),
+ {a,b} = do_is_not_used_at(a, [x,{a,b}]),
+ {a,b} = do_is_not_used_at(a, [{x,y},{a,b}]),
+ none = do_is_not_used_at(z, [{a,b}]),
+ none = do_is_not_used_at(a, [x]),
+ none = do_is_not_used_at(a, [{x,y}]),
+ ok.
+
+do_is_not_used_at(Key, [P|Ps]) ->
+ if
+ tuple_size(P) >= 1, element(1, P) =:= Key ->
+ P;
+ true ->
+ do_is_not_used_at(Key, Ps)
+ end;
+do_is_not_used_at(_Key, []) -> none.
+
+-record(select, {fixed=false}).
+
+select(_Config) ->
+ a = do_select(#select{}, 0, 0),
+ b = do_select(#select{}, 0, 1),
+ c = do_select(#select{fixed=true}, 0, 0),
+ c = do_select(#select{fixed=true}, 0, 1),
+ ok.
+
+do_select(Head, OldSize, BSize) ->
+ Overwrite0 =
+ if
+ OldSize =:= BSize -> same;
+ true -> true
+ end,
+ Overwrite =
+ if
+ Head#select.fixed =/= false ->
+ false;
+ true ->
+ Overwrite0
+ end,
+ if
+ Overwrite =:= same ->
+ a;
+ Overwrite ->
+ b;
+ true ->
+ c
+ end.
+
+y_catch(_Config) ->
+ ok = try
+ do_y_catch(<<"<?xmlX">>, {state}),
+ failed
+ catch
+ throw:{<<"<?xmlX">>,{state}} ->
+ ok
+ end.
+
+do_y_catch(<<"<?xml",Rest0/binary>> = Bytes, State0) ->
+ {Rest1,State1} =
+ case do_y_catch_1(Rest0, State0) of
+ false ->
+ {Bytes,State0};
+ true ->
+ {_XmlAttributes, R, S} = do_y_catch_2(Rest0),
+ {R,S}
+ end,
+ case catch id({Rest1,State1}) of
+ Other ->
+ throw(Other)
+ end.
+
+do_y_catch_1(<<_,_/binary>>, _) ->
+ false.
+
+do_y_catch_2(_) -> {a,b,c}.
+
+
+%% The identity function.
+id(I) -> I.
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 626f89ba7a..69391b15eb 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,16 +22,17 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- beam_files/1,compiler_bug/1,stupid_but_valid/1,
+ compiler_bug/1,stupid_but_valid/1,
xrange/1,yrange/1,stack/1,call_last/1,merge_undefined/1,
uninit/1,unsafe_catch/1,
- dead_code/1,mult_labels/1,
+ dead_code/1,
overwrite_catchtag/1,overwrite_trytag/1,accessing_tags/1,bad_catch_try/1,
cons_guard/1,
freg_range/1,freg_uninit/1,freg_state/1,
- bin_match/1,bad_bin_match/1,bin_aligned/1,bad_dsetel/1,
+ bad_bin_match/1,bad_dsetel/1,
state_after_fault_in_catch/1,no_exception_in_catch/1,
- undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1]).
+ undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1,
+ map_field_lists/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -47,18 +49,19 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [beam_files,{group,p}].
+ [{group,p}].
groups() ->
[{p,test_lib:parallel(),
[compiler_bug,stupid_but_valid,xrange,
yrange,stack,call_last,merge_undefined,uninit,
- unsafe_catch,dead_code,mult_labels,
+ unsafe_catch,dead_code,
overwrite_catchtag,overwrite_trytag,accessing_tags,
bad_catch_try,cons_guard,freg_range,freg_uninit,
- freg_state,bin_match,bad_bin_match,bin_aligned,bad_dsetel,
+ freg_state,bad_bin_match,bad_dsetel,
state_after_fault_in_catch,no_exception_in_catch,
- undef_label,illegal_instruction,failing_gc_guard_bif]}].
+ undef_label,illegal_instruction,failing_gc_guard_bif,
+ map_field_lists]}].
init_per_suite(Config) ->
Config.
@@ -72,33 +75,19 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-beam_files(Config) when is_list(Config) ->
- ?line DataDir = proplists:get_value(data_dir, Config),
- ?line Wc = filename:join([DataDir,"..","..","*","*.beam"]),
- %% Must have at least two files here, or there will be
- %% a grammatical error in the output of the io:format/2 call below. ;-)
- ?line [_,_|_] = Fs = filelib:wildcard(Wc),
- ?line io:format("~p files\n", [length(Fs)]),
- test_lib:p_run(fun do_beam_file/1, Fs).
-
-
-do_beam_file(F) ->
- case beam_validator:file(F) of
- ok ->
- ok;
- {error,Es} ->
- io:format("File: ~s", [F]),
- io:format("Error: ~p\n", [Es]),
- error
- end.
-
compiler_bug(Config) when is_list(Config) ->
%% Check that the compiler returns an error if we try to
%% assemble one of the bad '.S' files.
- ?line Data = ?config(data_dir, Config),
- ?line File = filename:join(Data, "stack"),
- ?line error = compile:file(File, [asm,report_errors,binary,time]),
+ Data = ?config(data_dir, Config),
+ File = filename:join(Data, "compiler_bug"),
+ error = compile:file(File, [from_asm,report_errors,time]),
+
+ %% Make sure that the error was reported by
+ %% the beam_validator module.
+ {error,
+ [{"compiler_bug",
+ [{beam_validator,_}]}],
+ []} = compile:file(File, [from_asm,return_errors,time]),
ok.
%% The following code is stupid but it should compile.
@@ -134,7 +123,7 @@ yrange(Config) when is_list(Config) ->
{{move,{x,1},{y,-1}},5,
{invalid_store,{y,-1},term}}},
{{t,sum_2,2},
- {{bif,'+',{f,0},[{x,0},{y,1024}],{x,0}},8,
+ {{bif,'+',{f,0},[{x,0},{y,1024}],{x,0}},7,
{uninitialized_reg,{y,1024}}}},
{{t,sum_3,2},
{{move,{x,1},{y,1024}},5,limit}},
@@ -145,31 +134,31 @@ yrange(Config) when is_list(Config) ->
stack(Config) when is_list(Config) ->
Errors = do_val(stack, Config),
- ?line [{{t,a,2},{return,11,{stack_frame,2}}},
- {{t,b,2},{{deallocate,2},4,{allocated,none}}},
- {{t,c,2},{{deallocate,2},12,{allocated,none}}},
- {{t,d,2},
- {{allocate,2,2},5,{existing_stack_frame,{size,2}}}},
- {{t,e,2},{{deallocate,5},6,{allocated,2}}},
- {{t,bad_1,0},{{allocate_zero,2,10},4,{{x,9},not_live}}},
- {{t,bad_2,0},{{move,{y,0},{x,0}},5,{unassigned,{y,0}}}}] = Errors,
+ [{{t,a,2},{return,9,{stack_frame,2}}},
+ {{t,b,2},{{deallocate,2},4,{allocated,none}}},
+ {{t,bad_1,0},{{allocate_zero,2,10},4,{{x,9},not_live}}},
+ {{t,bad_2,0},{{move,{y,0},{x,0}},5,{unassigned,{y,0}}}},
+ {{t,c,2},{{deallocate,2},10,{allocated,none}}},
+ {{t,d,2},
+ {{allocate,2,2},5,{existing_stack_frame,{size,2}}}},
+ {{t,e,2},{{deallocate,5},6,{allocated,2}}}] = Errors,
ok.
call_last(Config) when is_list(Config) ->
Errors = do_val(call_last, Config),
- ?line [{{t,a,1},{{call_last,1,{f,8},2},11,{allocated,1}}},
- {{t,b,1},
- {{call_ext_last,2,{extfunc,lists,seq,2},2},
- 11,
- {allocated,1}}}] = Errors,
+ [{{t,a,1},{{call_last,1,{f,8},2},9,{allocated,1}}},
+ {{t,b,1},
+ {{call_ext_last,2,{extfunc,lists,seq,2},2},
+ 10,
+ {allocated,1}}}] = Errors,
ok.
merge_undefined(Config) when is_list(Config) ->
Errors = do_val(merge_undefined, Config),
- ?line [{{t,handle_call,2},
- {{call_ext,2,{extfunc,debug,filter,2}},
- 22,
- {uninitialized_reg,{y,0}}}}] = Errors,
+ [{{t,handle_call,2},
+ {{call_ext,2,{extfunc,debug,filter,2}},
+ 22,
+ {uninitialized_reg,{y,0}}}}] = Errors,
ok.
uninit(Config) when is_list(Config) ->
@@ -178,10 +167,10 @@ uninit(Config) when is_list(Config) ->
[{{t,sum_1,2},
{{move,{y,0},{x,0}},5,{uninitialized_reg,{y,0}}}},
{{t,sum_2,2},
- {{call,1,{f,10}},6,{uninitialized_reg,{y,0}}}},
+ {{call,1,{f,8}},5,{uninitialized_reg,{y,0}}}},
{{t,sum_3,2},
{{bif,'+',{f,0},[{x,0},{y,0}],{x,0}},
- 7,
+ 6,
{unassigned,{y,0}}}}] = Errors,
ok.
@@ -190,7 +179,7 @@ unsafe_catch(Config) when is_list(Config) ->
?line
[{{t,small,2},
{{bs_put_integer,{f,0},{integer,16},1,
- {field_flags,[aligned,unsigned,big]},{y,0}},
+ {field_flags,[unsigned,big]},{y,0}},
20,
{unassigned,{y,0}}}}] = Errors,
ok.
@@ -199,10 +188,6 @@ dead_code(Config) when is_list(Config) ->
[] = do_val(dead_code, Config),
ok.
-mult_labels(Config) when is_list(Config) ->
- [] = do_val(erl_prim_loader, Config, ".beam"),
- ok.
-
overwrite_catchtag(Config) when is_list(Config) ->
Errors = do_val(overwrite_catchtag, Config),
?line
@@ -214,34 +199,34 @@ overwrite_trytag(Config) when is_list(Config) ->
Errors = do_val(overwrite_trytag, Config),
?line
[{{overwrite_trytag,foo,1},
- {{kill,{y,2}},9,{trytag,_}}}] = Errors,
+ {{kill,{y,2}},8,{trytag,_}}}] = Errors,
ok.
accessing_tags(Config) when is_list(Config) ->
Errors = do_val(accessing_tags, Config),
- ?line
- [{{accessing_tags,foo,1},
- {{move,{y,0},{x,0}},6,{catchtag,_}}},
- {{accessing_tags,bar,1},
- {{move,{y,0},{x,0}},6,{trytag,_}}}] = Errors,
+ [{{accessing_tags,bar,1},
+ {{move,{y,0},{x,0}},6,{trytag,_}}},
+ {{accessing_tags,foo,1},
+ {{move,{y,0},{x,0}},6,{catchtag,_}}}] = Errors,
ok.
bad_catch_try(Config) when is_list(Config) ->
Errors = do_val(bad_catch_try, Config),
- ?line [{{bad_catch_try,bad_1,1},
- {{'catch',{x,0},{f,3}},
- 5,{invalid_store,{x,0},{catchtag,[3]}}}},
- {{bad_catch_try,bad_2,1},
- {{catch_end,{x,9}},
- 8,{source_not_y_reg,{x,9}}}},
- {{bad_catch_try,bad_3,1},
- {{catch_end,{y,1}},9,{bad_type,{atom,kalle}}}},
- {{bad_catch_try,bad_4,1},
- {{'try',{x,0},{f,15}},5,{invalid_store,{x,0},{trytag,[15]}}}},
- {{bad_catch_try,bad_5,1},
- {{try_case,{y,1}},12,{bad_type,term}}},
- {{bad_catch_try,bad_6,1},
- {{try_end,{y,1}},8,{bad_type,{integer,1}}}}] = Errors,
+ [{{bad_catch_try,bad_1,1},
+ {{'catch',{x,0},{f,3}},
+ 5,{invalid_store,{x,0},{catchtag,[3]}}}},
+ {{bad_catch_try,bad_2,1},
+ {{catch_end,{x,9}},
+ 8,{source_not_y_reg,{x,9}}}},
+ {{bad_catch_try,bad_3,1},
+ {{catch_end,{y,1}},9,{bad_type,{atom,kalle}}}},
+ {{bad_catch_try,bad_4,1},
+ {{'try',{x,0},{f,15}},5,{invalid_store,{x,0},{trytag,[15]}}}},
+ {{bad_catch_try,bad_5,1},
+ {{try_case,{y,1}},12,{bad_type,term}}},
+ {{bad_catch_try,bad_6,1},
+ {{move,{integer,1},{y,1}},7,
+ {invalid_store,{y,1},{integer,1}}}}] = Errors,
ok.
cons_guard(Config) when is_list(Config) ->
@@ -310,66 +295,79 @@ freg_state(Config) when is_list(Config) ->
{fclearerror,5,{bad_floating_point_state,cleared}}}] = Errors,
ok.
-bin_match(Config) when is_list(Config) ->
- Errors = do_val(bin_match, Config),
- ?line
- [{{t,t,1},{{bs_save,0},4,no_bs_match_state}},
- {{t,x,1},{{bs_restore,1},16,{no_save_point,1}}}] = Errors,
- ok.
-
bad_bin_match(Config) when is_list(Config) ->
[{{t,t,1},{return,5,{match_context,{x,0}}}}] =
do_val(bad_bin_match, Config),
ok.
-bin_aligned(Config) when is_list(Config) ->
- Errors = do_val(bin_aligned, Config),
- ?line
- [{{t,decode,1},
- {{bs_put_integer,{f,0},
- {integer,5},
- 1,
- {field_flags,[unsigned,big,aligned]},
- {integer,0}},
- 10,
- {aligned_flag_set,{bits,3}}}}] = Errors,
- ok.
-
bad_dsetel(Config) when is_list(Config) ->
Errors = do_val(bad_dsetel, Config),
?line
[{{t,t,1},
{{set_tuple_element,{x,1},{x,0},1},
- 15,
+ 17,
illegal_context_for_set_tuple_element}}] = Errors,
ok.
state_after_fault_in_catch(Config) when is_list(Config) ->
Errors = do_val(state_after_fault_in_catch, Config),
- [{{t,foo,1},
- {{move,{x,1},{x,0}},10,{uninitialized_reg,{x,1}}}},
- {{state_after_fault_in_catch,if_end,1},
+ [{{state_after_fault_in_catch,badmatch,1},
{{move,{x,1},{x,0}},9,{uninitialized_reg,{x,1}}}},
{{state_after_fault_in_catch,case_end,1},
{{move,{x,1},{x,0}},9,{uninitialized_reg,{x,1}}}},
- {{state_after_fault_in_catch,badmatch,1},
- {{move,{x,1},{x,0}},9,{uninitialized_reg,{x,1}}}}] = Errors,
+ {{state_after_fault_in_catch,if_end,1},
+ {{move,{x,1},{x,0}},9,{uninitialized_reg,{x,1}}}},
+ {{t,foo,1},
+ {{move,{x,1},{x,0}},10,{uninitialized_reg,{x,1}}}}] = Errors,
ok.
no_exception_in_catch(Config) when is_list(Config) ->
Errors = do_val(no_exception_in_catch, Config),
[{{no_exception_in_catch,nested_of_1,4},
- {{move,{x,3},{x,0}},91,{uninitialized_reg,{x,3}}}}] = Errors,
+ {{move,{x,3},{x,0}},88,{uninitialized_reg,{x,3}}}}] = Errors,
ok.
undef_label(Config) when is_list(Config) ->
- Errors = do_val(undef_label, Config),
+ M = {undef_label,
+ [{t,1}],
+ [],
+ [{function,t,1,2,
+ [{label,1},
+ {func_info,{atom,undef_label},{atom,t},1},
+ {label,2},
+ {test,is_eq_exact,{f,42},[{x,0},{atom,x}]},
+ {move,{atom,ok},{x,0}},
+ return]},
+ {function,x,1,17,
+ [{label,3},
+ {func_info,{atom,undef_label},{atom,x},1},
+ {label,4},
+ return]}],
+ 5},
+ Errors = beam_val(M),
[{{undef_label,t,1},{undef_labels,[42]}},
{{undef_label,x,1},{return,4,no_entry_label}}] = Errors,
ok.
illegal_instruction(Config) when is_list(Config) ->
- Errors = do_val(illegal_instruction, Config),
+ M = {illegal_instruction,
+ [{t,1},{x,1},{y,0}],
+ [],
+ [{function,t,1,2,
+ [{label,1},
+ {func_info,{atom,illegal_instruction},{atom,t},1},
+ {label,2},
+ {my_illegal_instruction,{x,0}},
+ return]},
+ {function,x,1,4,
+ [{label,3},
+ bad_func_info,
+ {label,4},
+ {my_illegal_instruction,{x,0}},
+ return]},
+ {function,y,0,17,[]}],
+ 5},
+ Errors = beam_val(M),
[{{illegal_instruction,t,1},
{{my_illegal_instruction,{x,0}},4,unknown_instruction}},
{{'_',x,1},{bad_func_info,1,illegal_instruction}},
@@ -407,19 +405,40 @@ process_request_foo(_) ->
process_request_bar(Pid, [Response]) when is_pid(Pid) ->
Response.
+map_field_lists(Config) ->
+ Errors = do_val(map_field_lists, Config),
+ [{{map_field_lists,x,1},
+ {{test,has_map_fields,{f,1},{x,0},
+ {list,[{atom,a},{atom,a}]}},
+ 5,
+ keys_not_unique}},
+ {{map_field_lists,y,1},
+ {{test,has_map_fields,{f,3},{x,0},{list,[]}},
+ 5,
+ empty_field_list}}
+ ] = Errors.
%%%-------------------------------------------------------------------------
-do_val(Name, Config) ->
- do_val(Name, Config, ".S").
-
-do_val(Name, Config, Type) ->
- ?line Data = ?config(data_dir, Config),
- ?line File = filename:join(Data, atom_to_list(Name)++Type),
- ?line case beam_validator:file(File) of
- {error,Errors} ->
- ?line io:format("~p:~n~s",
- [File,beam_validator:format_error(Errors)]),
- Errors;
- ok -> []
- end.
+do_val(Mod, Config) ->
+ Data = ?config(data_dir, Config),
+ Base = atom_to_list(Mod),
+ File = filename:join(Data, Base),
+ case compile:file(File, [from_asm,no_postopt,return_errors]) of
+ {error,L,[]} ->
+ [{Base,Errors0}] = L,
+ Errors = [E || {beam_validator,E} <- Errors0],
+ _ = [io:put_chars(beam_validator:format_error(E)) ||
+ E <- Errors],
+ Errors;
+ {ok,Mod} ->
+ []
+ end.
+
+beam_val(M) ->
+ Name = atom_to_list(element(1, M)),
+ {error,[{Name,Errors0}]} = beam_validator:module(M, []),
+ Errors = [E || {beam_validator,E} <- Errors0],
+ _ = [io:put_chars(beam_validator:format_error(E)) ||
+ E <- Errors],
+ Errors.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/bad_catch_try.S b/lib/compiler/test/beam_validator_SUITE_data/bad_catch_try.S
index 2a53f0dd93..6035f23506 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/bad_catch_try.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/bad_catch_try.S
@@ -63,11 +63,11 @@
{label,9}.
{func_info,{atom,bad_catch_try},{atom,bad_3},1}.
{label,10}.
- {allocate,1,1}.
+ {allocate,2,1}.
+ {move,{atom,kalle},{y,1}}.
{'catch',{y,0},{f,11}}.
{call,1,{f,26}}.
{label,11}.
- {move,{atom,kalle},{y,1}}.
{catch_end,{y,1}}.
{test,is_tuple,{f,12},[{x,0}]}.
{test,test_arity,{f,12},[{x,0},2]}.
@@ -106,7 +106,7 @@
{label,17}.
{func_info,{atom,bad_catch_try},{atom,bad_5},1}.
{label,18}.
- {allocate_zero,1,1}.
+ {allocate_zero,2,1}.
{'try',{y,0},{f,19}}.
{call,1,{f,26}}.
{try_end,{y,0}}.
@@ -131,7 +131,7 @@
{'try',{y,0},{f,23}}.
{call,1,{f,26}}.
{move,{integer,1},{y,1}}.
- {try_end,{y,1}}.
+ {try_end,{y,0}}.
{move,{atom,ok},{x,0}}.
{jump,{f,24}}.
{label,23}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/bad_dsetel.S b/lib/compiler/test/beam_validator_SUITE_data/bad_dsetel.S
index 279b2fa97f..9630d73a93 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/bad_dsetel.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/bad_dsetel.S
@@ -1,4 +1,4 @@
-{module, t}. %% version = 0
+{module, bad_dsetel}. %% version = 0
{exports, [{module_info,0},{module_info,1},{t,1}]}.
@@ -21,7 +21,9 @@
{move,{integer,3},{x,0}}.
{call_ext,3,{extfunc,erlang,setelement,3}}.
{test_heap,6,1}.
- {put_string,3,{string,"abc"},{x,1}}.
+ {put_list,{integer,99},nil,{x,1}}.
+ {put_list,{integer,98},{x,1},{x,1}}.
+ {put_list,{integer,97},{x,1},{x,1}}.
{set_tuple_element,{x,1},{x,0},1}.
{'%live',1}.
{deallocate,0}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/bin_aligned.S b/lib/compiler/test/beam_validator_SUITE_data/bin_aligned.S
deleted file mode 100644
index 2f353fbd25..0000000000
--- a/lib/compiler/test/beam_validator_SUITE_data/bin_aligned.S
+++ /dev/null
@@ -1,47 +0,0 @@
-{module, t}. %% version = 0
-
-{exports, [{decode,1},{module_info,0},{module_info,1}]}.
-
-{attributes, []}.
-
-{labels, 7}.
-
-
-{function, decode, 1, 2}.
- {label,1}.
- {func_info,{atom,t},{atom,decode},1}.
- {label,2}.
- {move,{integer,1},{x,1}}.
- {bif,size,{f,0},[{x,0}],{x,2}}.
- {bs_add,{f,0},[{x,1},{x,2},1],{x,1}}.
- {bs_init2,{f,0},{x,1},0,1,{field_flags,[]},{x,1}}.
- {bs_put_integer,{f,0},
- {integer,3},
- 1,
- {field_flags,[aligned,unsigned,big]},
- {integer,0}}.
- {bs_put_binary,{f,0},{atom,all},8,{field_flags,[unsigned,big]},{x,0}}.
- {bs_put_integer,{f,0},
- {integer,5},
- 1,
- {field_flags,[unsigned,big,aligned]},
- {integer,0}}.
- {move,{x,1},{x,0}}.
- return.
-
-
-{function, module_info, 0, 4}.
- {label,3}.
- {func_info,{atom,t},{atom,module_info},0}.
- {label,4}.
- {move,{atom,t},{x,0}}.
- {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
-
-
-{function, module_info, 1, 6}.
- {label,5}.
- {func_info,{atom,t},{atom,module_info},1}.
- {label,6}.
- {move,{x,0},{x,1}}.
- {move,{atom,t},{x,0}}.
- {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/bin_match.S b/lib/compiler/test/beam_validator_SUITE_data/bin_match.S
deleted file mode 100644
index 96df0f7933..0000000000
--- a/lib/compiler/test/beam_validator_SUITE_data/bin_match.S
+++ /dev/null
@@ -1,64 +0,0 @@
-{module, bin_match}. %% version = 0
-
-{exports, [{t,1}]}.
-
-{attributes, []}.
-
-{labels, 8}.
-
-
-{function, t, 1, 2}.
- {label,1}.
- {func_info,{atom,t},{atom,t},1}.
- {label,2}.
-%% {test,bs_start_match,{f,1},[{x,0}]}.
- {bs_save,0}.
- {test,bs_get_integer,
- {f,3},
- [{integer,8},1,{field_flags,[aligned,unsigned,big]},{x,1}]}.
- {test,bs_get_integer,
- {f,3},
- [{integer,8},1,{field_flags,[aligned,unsigned,big]},{x,2}]}.
- {test,bs_test_tail,{f,3},[0]}.
- {test_heap,3,3}.
- {put_tuple,2,{x,0}}.
- {put,{x,1}}.
- {put,{x,2}}.
- {'%live',1}.
- return.
- {label,3}.
- {bs_restore,0}.
- {test,bs_get_integer,
- {f,1},
- [{integer,32},1,{field_flags,[aligned,unsigned,big]},{x,1}]}.
- {test,bs_test_tail,{f,1},[0]}.
- {move,{x,1},{x,0}}.
- return.
-
-{function, x, 1, 5}.
- {label,4}.
- {func_info,{atom,t},{atom,x},1}.
- {label,5}.
- {test,bs_start_match,{f,4},[{x,0}]}.
- {bs_save,0}.
- {test,bs_get_integer,
- {f,6},
- [{integer,8},1,{field_flags,[aligned,unsigned,big]},{x,1}]}.
- {test,bs_get_integer,
- {f,6},
- [{integer,8},1,{field_flags,[aligned,unsigned,big]},{x,2}]}.
- {test,bs_test_tail,{f,6},[0]}.
- {test_heap,3,3}.
- {put_tuple,2,{x,0}}.
- {put,{x,1}}.
- {put,{x,2}}.
- {'%live',1}.
- return.
- {label,6}.
- {bs_restore,1}.
- {test,bs_get_integer,
- {f,4},
- [{integer,32},1,{field_flags,[aligned,unsigned,big]},{x,1}]}.
- {test,bs_test_tail,{f,4},[0]}.
- {move,{x,1},{x,0}}.
- return.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/compiler_bug.S b/lib/compiler/test/beam_validator_SUITE_data/compiler_bug.S
new file mode 100644
index 0000000000..ba27bf5c47
--- /dev/null
+++ b/lib/compiler/test/beam_validator_SUITE_data/compiler_bug.S
@@ -0,0 +1,38 @@
+{module, compiler_bug}. %% version = 0
+
+{exports, [{module_info,0},{module_info,1},{sum,2}]}.
+
+{attributes, []}.
+
+{labels, 7}.
+
+
+{function, sum, 2, 2}.
+ {label,1}.
+ {line,[{location,"compiler_bug.erl",4}]}.
+ {func_info,{atom,compiler_bug},{atom,sum},2}.
+ {label,2}.
+ {line,[{location,"compiler_bug.erl",5}]}.
+ {gc_bif,'+',{f,0},2,[{y,0},{y,1}],{x,0}}.
+ return.
+
+
+{function, module_info, 0, 4}.
+ {label,3}.
+ {line,[]}.
+ {func_info,{atom,compiler_bug},{atom,module_info},0}.
+ {label,4}.
+ {move,{atom,compiler_bug},{x,0}}.
+ {line,[]}.
+ {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
+
+
+{function, module_info, 1, 6}.
+ {label,5}.
+ {line,[]}.
+ {func_info,{atom,compiler_bug},{atom,module_info},1}.
+ {label,6}.
+ {move,{x,0},{x,1}}.
+ {move,{atom,compiler_bug},{x,0}}.
+ {line,[]}.
+ {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/dead_code.S b/lib/compiler/test/beam_validator_SUITE_data/dead_code.S
index f964f98fba..c114664ba0 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/dead_code.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/dead_code.S
@@ -1,10 +1,10 @@
{module, dead_code}. %% version = 0
-{exports, [{execute,0},{module_info,0},{module_info,1}]}.
+{exports, [{execute,0}]}.
{attributes, []}.
-{labels, 10}.
+{labels, 6}.
{function, execute, 0, 2}.
@@ -12,7 +12,6 @@
{func_info,{atom,dead_code},{atom,execute},0}.
{label,2}.
{allocate,0,0}.
- {'%live',0}.
{call_ext,0,{extfunc,foo,fie,0}}.
{test,is_ne,{f,4},[{x,0},{integer,0}]}.
{test,is_ne,{f,4},[{x,0},{integer,1}]}.
@@ -22,27 +21,7 @@
{case_end,{x,0}}.
{label,4}.
{move,{atom,ok},{x,0}}.
- {'%live',1}.
{deallocate,0}.
return.
- {'%','Moved code'}.
{label,5}.
{case_end,{x,0}}.
-
-
-{function, module_info, 0, 7}.
- {label,6}.
- {func_info,{atom,dead_code},{atom,module_info},0}.
- {label,7}.
- {move,nil,{x,0}}.
- {'%live',1}.
- return.
-
-
-{function, module_info, 1, 9}.
- {label,8}.
- {func_info,{atom,dead_code},{atom,module_info},1}.
- {label,9}.
- {move,nil,{x,0}}.
- {'%live',1}.
- return.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/erl_prim_loader.beam b/lib/compiler/test/beam_validator_SUITE_data/erl_prim_loader.beam
deleted file mode 100644
index dd58a88e42..0000000000
--- a/lib/compiler/test/beam_validator_SUITE_data/erl_prim_loader.beam
+++ /dev/null
Binary files differ
diff --git a/lib/compiler/test/beam_validator_SUITE_data/freg_range.S b/lib/compiler/test/beam_validator_SUITE_data/freg_range.S
index ee583a923e..b3ebff3ade 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/freg_range.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/freg_range.S
@@ -1,10 +1,10 @@
{module, freg_range}. %% version = 0
-{exports, [{module_info,0},{module_info,1},{prod,2},{sum,2},{sum_prod,3}]}.
+{exports, [{sum_1,2},{sum_2,2},{sum_3,2},{sum_4,2}]}.
{attributes, []}.
-{labels, 8}.
+{labels, 9}.
{function, sum_1, 2, 2}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/freg_state.S b/lib/compiler/test/beam_validator_SUITE_data/freg_state.S
index ff4d7548ae..7466763482 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/freg_state.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/freg_state.S
@@ -1,6 +1,6 @@
{module, freg_state}. %% version = 0
-{exports, []}.
+{exports, [{sum_1,2},{sum_2,2},{sum_3,2},{sum_4,2},{sum_5,2}]}.
{attributes, []}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S b/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S
index f8d805d9ec..71e833446a 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S
@@ -1,10 +1,10 @@
{module, freg_uninit}. %% version = 0
-{exports, []}.
+{exports, [{sum_1,2},{sum_2,2}]}.
{attributes, []}.
-{labels, 8}.
+{labels, 7}.
{function, sum_1, 2, 2}.
@@ -14,7 +14,6 @@
{fconv,{x,0},{fr,0}}.
fclearerror.
{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}.
- {'%live',1}.
return.
@@ -26,7 +25,12 @@
{fconv,{x,1},{fr,1}}.
fclearerror.
{fcheckerror,{f,0}}.
- {call,2,{f,8}}.
+ {call,2,{f,6}}.
{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}.
- {'%live',1}.
+ return.
+
+{function, foo, 2, 6}.
+ {label,5}.
+ {func_info,{atom,t},{atom,foo},2}.
+ {label,6}.
return.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/illegal_instruction.S b/lib/compiler/test/beam_validator_SUITE_data/illegal_instruction.S
deleted file mode 100644
index d6e92abc71..0000000000
--- a/lib/compiler/test/beam_validator_SUITE_data/illegal_instruction.S
+++ /dev/null
@@ -1,26 +0,0 @@
-{module, illegal_instruction}. %% version = 0
-
-{exports, []}.
-
-{attributes, []}.
-
-{labels, 7}.
-
-
-{function, t, 1, 2}.
- {label,1}.
- {func_info,{atom,illegal_instruction},{atom,t},1}.
- {label,2}.
- {my_illegal_instruction,{x,0}}.
- return.
-
-
-{function, x, 1, 4}.
- {label,3}.
- bad_func_info.
- {label,4}.
- {my_illegal_instruction,{x,0}}.
- return.
-
-{function, y, 0, 17}.
- \ No newline at end of file
diff --git a/lib/compiler/test/beam_validator_SUITE_data/map_field_lists.S b/lib/compiler/test/beam_validator_SUITE_data/map_field_lists.S
new file mode 100644
index 0000000000..5e7ccc1e5d
--- /dev/null
+++ b/lib/compiler/test/beam_validator_SUITE_data/map_field_lists.S
@@ -0,0 +1,29 @@
+{module, map_field_lists}. %% version = 0
+
+{exports, [{x,1},{y,1}]}.
+
+{attributes, []}.
+
+{labels, 5}.
+
+
+{function, x, 1, 2}.
+ {label,1}.
+ {line,[{location,"map_field_lists.erl",4}]}.
+ {func_info,{atom,map_field_lists},{atom,x},1}.
+ {label,2}.
+ {test,is_map,{f,1},[{x,0}]}.
+ {test,has_map_fields,{f,1},{x,0},{list,[{atom,a},{atom,a}]}}.
+ {move,{atom,ok},{x,0}}.
+ return.
+
+
+{function, y, 1, 4}.
+ {label,3}.
+ {line,[{location,"map_field_lists.erl",7}]}.
+ {func_info,{atom,map_field_lists},{atom,y},1}.
+ {label,4}.
+ {test,is_map,{f,3},[{x,0}]}.
+ {test,has_map_fields,{f,3},{x,0},{list,[]}}.
+ {move,{atom,ok},{x,0}}.
+ return.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S b/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S
index 3d76127824..481d55045d 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S
@@ -22,7 +22,8 @@
{label,4}.
{allocate_heap,1,6,2}.
{move,{x,1},{y,0}}.
- {put_string,2,{string,"~p"},{x,0}}.
+ {put_list,{integer,112},nil,{x,0}}.
+ {put_list,{integer,126},{x,0},{x,0}}.
{put_list,{y,0},nil,{x,1}}.
{'%live',2}.
{call_ext,2,{extfunc,io,format,2}}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/no_exception_in_catch.S b/lib/compiler/test/beam_validator_SUITE_data/no_exception_in_catch.S
index e08a718a39..1a5b417a5f 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/no_exception_in_catch.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/no_exception_in_catch.S
@@ -26,7 +26,7 @@
{call_ext,1,{extfunc,erlang,erase,1}}.
{move,{atom,nested},{x,0}}.
{call_ext,1,{extfunc,erlang,erase,1}}.
- {bif,self,nofail,[],{x,0}}.
+ {bif,self,{f,0},[],{x,0}}.
{'try',{y,8},{f,13}}.
{'try',{y,7},{f,11}}.
{'try',{y,6},{f,9}}.
@@ -34,7 +34,7 @@
%% Because the following instructions can't possible throw an exception,
%% label 7 used to get no state. Now the try_end itself will save the state.
{move,{x,0},{y,4}}.
- {bif,self,nofail,[],{x,0}}.
+ {bif,self,{f,0},[],{x,0}}.
{'%live',1}.
{try_end,{y,5}}.
{test,is_eq_exact,{f,15},[{x,0},{y,4}]}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/stack.S b/lib/compiler/test/beam_validator_SUITE_data/stack.S
index 244c22a2f9..e4356a9d00 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/stack.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/stack.S
@@ -1,10 +1,10 @@
{module, stack}. %% version = 0
-{exports, [{a,2},{b,2},{c,2},{d,2},{e,2}]}.
+{exports, [{a,2},{b,2},{c,2},{d,2},{e,2},{bad_1,0},{bad_2,0},{foo,0}]}.
{attributes, []}.
-{labels, 21}.
+{labels, 17}.
{function, a, 2, 2}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/state_after_fault_in_catch.S b/lib/compiler/test/beam_validator_SUITE_data/state_after_fault_in_catch.S
index 8e27347ed5..c3656d6218 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/state_after_fault_in_catch.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/state_after_fault_in_catch.S
@@ -14,7 +14,7 @@
{allocate,1,0}.
{'catch',{y,0},{f,3}}.
{move,{atom,apa},{x,0}}.
- {call_ext,1,{extfunc,erlang,fault,1}}.
+ {call_ext,1,{extfunc,erlang,error,1}}.
{label,3}.
{catch_end,{y,0}}.
{move,{x,1},{x,0}}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/undef_label.S b/lib/compiler/test/beam_validator_SUITE_data/undef_label.S
deleted file mode 100644
index dd29066bf4..0000000000
--- a/lib/compiler/test/beam_validator_SUITE_data/undef_label.S
+++ /dev/null
@@ -1,22 +0,0 @@
-{module, undef_label}. %% version = 0
-
-{exports, []}.
-
-{attributes, []}.
-
-{labels, 7}.
-
-
-{function, t, 1, 2}.
- {label,1}.
- {func_info,{atom,undef_label},{atom,t},1}.
- {label,2}.
- {test,is_eq_exact,{f,42},[{x,0},{atom,x}]}.
- {move,{atom,ok},{x,0}}.
- return.
-
-{function, x, 1, 17}.
- {label,3}.
- {func_info,{atom,undef_label},{atom,x},1}.
- {label,4}.
- return.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/uninit.S b/lib/compiler/test/beam_validator_SUITE_data/uninit.S
index 1a45c31411..9a66f4f7d6 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/uninit.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/uninit.S
@@ -1,9 +1,11 @@
{module, uninit}. %% version = 0
-{exports, []}.
+{exports, [{sum_1,2},{sum_2,2},{sum_3,2}]}.
{attributes, []}.
+{labels, 9}.
+
{function, sum_1, 2, 2}.
{label,1}.
{func_info,{atom,t},{atom,sum_1},2}.
@@ -11,7 +13,7 @@
{allocate,1,2}.
{move,{y,0},{x,0}}.
{'%live',1}.
- {call,1,{f,10}}.
+ {call,1,{f,8}}.
{bif,'+',{f,0},[{x,0},{y,0}],{x,0}}.
{'%live',1}.
{deallocate,1}.
@@ -23,7 +25,7 @@
{label,4}.
{allocate,1,2}.
{'%live',1}.
- {call,1,{f,10}}.
+ {call,1,{f,8}}.
{bif,'+',{f,0},[{x,0},{y,0}],{x,0}}.
{'%live',1}.
{deallocate,1}.
@@ -35,14 +37,14 @@
{label,6}.
{allocate_zero,1,2}.
{'%live',1}.
- {call,1,{f,10}}.
+ {call,1,{f,8}}.
{bif,'+',{f,0},[{x,0},{y,0}],{x,0}}.
{'%live',1}.
{deallocate,1}.
return.
-{function, id, 1, 10}.
- {label,9}.
+{function, id, 1, 8}.
+ {label,7}.
{func_info,{atom,t},{atom,id},1}.
- {label,10}.
+ {label,8}.
return.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/unsafe_catch.S b/lib/compiler/test/beam_validator_SUITE_data/unsafe_catch.S
index 500ac11377..f7d3f805b3 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/unsafe_catch.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/unsafe_catch.S
@@ -17,7 +17,7 @@
{bs_put_integer,{f,0},
{integer,8},
1,
- {field_flags,[aligned,unsigned,big]},
+ {field_flags,[unsigned,big]},
{x,0}}.
{move,{x,1},{y,0}}.
{move,{x,2},{x,0}}.
@@ -34,7 +34,7 @@
{bs_put_integer,{f,0},
{integer,16},
1,
- {field_flags,[aligned,unsigned,big]},
+ {field_flags,[unsigned,big]},
{y,0}}.
{move,{x,0},{y,0}}.
{move,{x,1},{x,0}}.
@@ -55,12 +55,12 @@
{bs_put_binary,{f,0},
{atom,all},
8,
- {field_flags,[aligned,unsigned,big]},
+ {field_flags,[unsigned,big]},
{y,0}}.
{bs_put_binary,{f,0},
{atom,all},
8,
- {field_flags,[aligned,unsigned,big]},
+ {field_flags,[unsigned,big]},
{x,0}}.
{move,{x,1},{x,0}}.
{deallocate,2}.
diff --git a/lib/compiler/test/beam_validator_SUITE_data/xrange.S b/lib/compiler/test/beam_validator_SUITE_data/xrange.S
index 3abbdffbc2..c6f20288f7 100644
--- a/lib/compiler/test/beam_validator_SUITE_data/xrange.S
+++ b/lib/compiler/test/beam_validator_SUITE_data/xrange.S
@@ -1,10 +1,10 @@
{module, xrange}. %% version = 0
-{exports, [{module_info,0},{module_info,1},{prod,2},{sum,2},{sum_prod,3}]}.
+{exports, [{sum_1,2},{sum_2,2},{sum_3,2},{sum_4,2}]}.
{attributes, []}.
-{labels, 8}.
+{labels, 9}.
{function, sum_1, 2, 2}.
diff --git a/lib/compiler/test/bs_bincomp_SUITE.erl b/lib/compiler/test/bs_bincomp_SUITE.erl
index 4450405695..1bf4e9d4a7 100644
--- a/lib/compiler/test/bs_bincomp_SUITE.erl
+++ b/lib/compiler/test/bs_bincomp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/bs_bit_binaries_SUITE.erl b/lib/compiler/test/bs_bit_binaries_SUITE.erl
index 8609a490f5..afee52c9b9 100644
--- a/lib/compiler/test/bs_bit_binaries_SUITE.erl
+++ b/lib/compiler/test/bs_bit_binaries_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -37,7 +38,7 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[misc,horrid_match,test_bitstr,test_bit_size,
asymmetric_tests,big_asymmetric_tests,
binary_to_and_from_list,big_binary_to_and_from_list,
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index ce39de2a82..87cfaaf73c 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -39,7 +40,7 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[two,test1,fail,float_bin,in_guard,in_catch,
nasty_literals,side_effect,opt,otp_7556,float_arith,
otp_8054]}].
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 10e3451e8f..7fb0a16540 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,7 +25,7 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
fun_shadow/1,int_float/1,otp_5269/1,null_fields/1,wiger/1,
- bin_tail/1,save_restore/1,shadowed_size_var/1,
+ bin_tail/1,save_restore/1,
partitioned_bs_match/1,function_clause/1,
unit/1,shared_sub_bins/1,bin_and_float/1,
dec_subidentifiers/1,skip_optional_tag/1,
@@ -34,7 +35,9 @@
otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1,
match_string/1,zero_width/1,bad_size/1,haystack/1,
cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1,
- no_partition/1,calling_a_binary/1,binary_in_map/1]).
+ no_partition/1,calling_a_binary/1,binary_in_map/1,
+ match_string_opt/1,map_and_binary/1,
+ unsafe_branch_caching/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -48,9 +51,9 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[fun_shadow,int_float,otp_5269,null_fields,wiger,
- bin_tail,save_restore,shadowed_size_var,
+ bin_tail,save_restore,
partitioned_bs_match,function_clause,unit,
shared_sub_bins,bin_and_float,dec_subidentifiers,
skip_optional_tag,wfbm,degenerated_match,bs_sum,
@@ -59,7 +62,9 @@ groups() ->
matching_and_andalso,otp_7188,otp_7233,otp_7240,
otp_7498,match_string,zero_width,bad_size,haystack,
cover_beam_bool,matched_out_size,follow_fail_branch,
- no_partition,calling_a_binary,binary_in_map]}].
+ no_partition,calling_a_binary,binary_in_map,
+ match_string_opt,map_and_binary,
+ unsafe_branch_caching]}].
init_per_suite(Config) ->
@@ -322,16 +327,6 @@ bad_float_unpack_match(<<F:64/float>>) -> F;
bad_float_unpack_match(<<I:64/integer-signed>>) -> I.
-shadowed_size_var(Config) when is_list(Config) ->
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Dir = filename:dirname(code:which(?MODULE)),
- ?line Core = filename:join(Dir, "bs_shadowed_size_var"),
- ?line Opts = [from_core,{outdir,PrivDir}|test_lib:opt_opts(?MODULE)],
- ?line io:format("~p", [Opts]),
- ?line {ok,Mod} = c:c(Core, Opts),
- ?line [42|<<"abcde">>] = Mod:filter_essentials([<<42:32>>|<<5:32,"abcde">>]),
- ok.
-
partitioned_bs_match(Config) when is_list(Config) ->
?line <<1,2,3>> = partitioned_bs_match(blurf, <<42,1,2,3>>),
?line error = partitioned_bs_match(10, <<7,8,15,13>>),
@@ -368,11 +363,20 @@ partitioned_bs_match_3(Var, <<_>>) -> Var;
partitioned_bs_match_3(1, 2) -> ok.
function_clause(Config) when is_list(Config) ->
- ?line ok = function_clause_1(<<0,7,0,7,42>>),
- ?line fc(function_clause_1, [<<0,1,2,3>>],
- catch function_clause_1(<<0,1,2,3>>)),
- ?line fc(function_clause_1, [<<0,1,2,3>>],
- catch function_clause_1(<<0,7,0,1,2,3>>)),
+ ok = function_clause_1(<<0,7,0,7,42>>),
+ fc(function_clause_1, [<<0,1,2,3>>],
+ catch function_clause_1(<<0,1,2,3>>)),
+ fc(function_clause_1, [<<0,1,2,3>>],
+ catch function_clause_1(<<0,7,0,1,2,3>>)),
+
+ ok = function_clause_2(<<0,7,0,7,42>>),
+ ok = function_clause_2(<<255>>),
+ ok = function_clause_2(<<13:4>>),
+ fc(function_clause_2, [<<0,1,2,3>>],
+ catch function_clause_2(<<0,1,2,3>>)),
+ fc(function_clause_2, [<<0,1,2,3>>],
+ catch function_clause_2(<<0,7,0,1,2,3>>)),
+
ok.
function_clause_1(<<0:8,7:8,T/binary>>) ->
@@ -380,6 +384,13 @@ function_clause_1(<<0:8,7:8,T/binary>>) ->
function_clause_1(<<_:8>>) ->
ok.
+function_clause_2(<<0:8,7:8,T/binary>>) ->
+ function_clause_2(T);
+function_clause_2(<<_:8>>) ->
+ ok;
+function_clause_2(<<_:4>>) ->
+ ok.
+
unit(Config) when is_list(Config) ->
?line 42 = peek1(<<42>>),
?line 43 = peek1(<<43,1,2>>),
@@ -1208,6 +1219,58 @@ match_binary_in_map(Map) ->
ok
end.
+match_string_opt(Config) when is_list(Config) ->
+ {x,<<1,2,3>>,{<<1>>,{v,<<1,2,3>>}}} =
+ do_match_string_opt({<<1>>,{v,<<1,2,3>>}}),
+ ok.
+
+do_match_string_opt({<<1>>,{v,V}}=T) ->
+ {x,V,T}.
+
+%% If 'bin_opt_info' was given the warning would lack filename
+%% and line number.
+
+map_and_binary(_Config) ->
+ {<<"10">>,<<"37">>,<<"am">>} = do_map_and_binary(<<"10:37am">>),
+ Map1 = #{time => "noon"},
+ {ok,Map1} = do_map_and_binary(Map1),
+ Map2 = #{hour => 8, min => 42},
+ {8,42,Map2} = do_map_and_binary(Map2),
+ ok.
+
+do_map_and_binary(<<Hour:2/bytes, $:, Min:2/bytes, Rest/binary>>) ->
+ {Hour, Min, Rest};
+do_map_and_binary(#{time := _} = T) ->
+ {ok, T};
+do_map_and_binary(#{hour := Hour, min := Min} = T) ->
+ {Hour, Min, T}.
+
+%% Unsafe caching of branch outcomes in beam_bsm would cause the
+%% delayed creation of sub-binaries optimization to be applied even
+%% when it was unsafe.
+
+unsafe_branch_caching(_Config) ->
+ <<>> = do_unsafe_branch_caching(<<42,1>>),
+ <<>> = do_unsafe_branch_caching(<<42,2>>),
+ <<>> = do_unsafe_branch_caching(<<42,3>>),
+ <<17,18>> = do_unsafe_branch_caching(<<42,3,17,18>>),
+ <<>> = do_unsafe_branch_caching(<<1,3,42,2>>),
+
+ ok.
+
+do_unsafe_branch_caching(<<Code/integer, Bin/binary>>) ->
+ <<C1/integer, B1/binary>> = Bin,
+ case C1 of
+ X when X =:= 1 orelse X =:= 2 ->
+ Bin2 = <<>>;
+ _ ->
+ Bin2 = B1
+ end,
+ case Code of
+ 1 -> do_unsafe_branch_caching(Bin2);
+ _ -> Bin2
+ end.
+
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/bs_shadowed_size_var.core b/lib/compiler/test/bs_shadowed_size_var.core
deleted file mode 100644
index d1d5ebba6d..0000000000
--- a/lib/compiler/test/bs_shadowed_size_var.core
+++ /dev/null
@@ -1,25 +0,0 @@
-module 'bs_shadowed_size_var' ['filter_essentials'/1]
- attributes []
-
-%% Reduced code from beam_asm inlined using the old inliner.
-
-'filter_essentials'/1 =
- fun (_cor0) ->
- case _cor0 of
- <[#{#<Sz>(32,1,'integer',['unsigned','big']) }#|T]> when 'true' ->
- let <_cor4> =
- case T of
- %% Variable 'Sz' repeated here. Should work.
- <#{#<Sz>(32,1,'integer',['unsigned','big']),
- #<Data>(Sz,8,'binary',['unsigned','big'])}#> when 'true' ->
- Data
- <_cor5> when 'true' ->
- primop 'match_fail'
- ({'case_clause',{_cor5}})
- end
- in [Sz|_cor4]
- <_cor5> when 'true' ->
- primop 'match_fail'
- ({'function_clause',_cor5})
- end
-end
diff --git a/lib/compiler/test/bs_utf_SUITE.erl b/lib/compiler/test/bs_utf_SUITE.erl
index 94549ad0d3..e6d292d9e6 100644
--- a/lib/compiler/test/bs_utf_SUITE.erl
+++ b/lib/compiler/test/bs_utf_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl
index f7b1dbdddf..2715a3aec5 100644
--- a/lib/compiler/test/compilation_SUITE.erl
+++ b/lib/compiler/test/compilation_SUITE.erl
@@ -3,19 +3,19 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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 : Compiles various modules with tough code
-module(compilation_SUITE).
@@ -309,8 +309,8 @@ load_and_call(Out, Module) ->
%% Smoke-test of beam disassembler.
?line test_lib:smoke_disasm(Module),
- ?line true = erlang:delete_module(Module),
- ?line true = erlang:purge_module(Module),
+ _ = code:delete(Module),
+ _ = code:purge(Module),
%% Restore state of trap_exit just in case. (Since the compiler
%% uses a temporary process, we will get {'EXIT',Pid,normal} messages
@@ -428,41 +428,35 @@ self_compile_old_inliner(Config) when is_list(Config) ->
self_compile_1(Config, "old", [verbose,{inline,500}]).
self_compile_1(Config, Prefix, Opts) ->
- ?line Dog = test_server:timetrap(test_server:minutes(40)),
+ Dog = test_server:timetrap(test_server:minutes(40)),
- ?line Priv = ?config(priv_dir,Config),
- ?line Version = compiler_version(),
+ Priv = ?config(priv_dir,Config),
+ Version = compiler_version(),
%% Compile the compiler. (In this node to get better coverage.)
- ?line CompA = make_compiler_dir(Priv, Prefix++"compiler_a"),
- ?line VsnA = Version ++ ".0",
- ?line compile_compiler(compiler_src(), CompA, VsnA, [clint|Opts]),
+ CompA = make_compiler_dir(Priv, Prefix++"compiler_a"),
+ VsnA = Version ++ ".0",
+ compile_compiler(compiler_src(), CompA, VsnA, [clint0,clint|Opts]),
%% Compile the compiler again using the newly compiled compiler.
%% (In another node because reloading the compiler would disturb cover.)
CompilerB = Prefix++"compiler_b",
CompB = make_compiler_dir(Priv, CompilerB),
- ?line VsnB = VsnA ++ ".0",
+ VsnB = VsnA ++ ".0",
self_compile_node(CompA, CompB, VsnB, Opts),
- %% Compare compiler directories.
- ?line compare_compilers(CompA, CompB),
-
- %% Compile and compare compiler C.
- ?line CompilerC = Prefix++"compiler_c",
- ?line CompC = make_compiler_dir(Priv, CompilerC),
- ?line VsnC = VsnB ++ ".0",
- self_compile_node(CompB, CompC, VsnC, Opts),
- ?line compare_compilers(CompB, CompC),
+ %% Compare compiler directories. The compiler directories should
+ %% be equal (except for beam_asm that contains the compiler version).
+ compare_compilers(CompA, CompB),
- ?line test_server:timetrap_cancel(Dog),
+ test_server:timetrap_cancel(Dog),
ok.
self_compile_node(CompilerDir, OutDir, Version, Opts) ->
- ?line Dog = test_server:timetrap(test_server:minutes(15)),
- ?line Pa = "-pa " ++ filename:dirname(code:which(?MODULE)) ++
+ Dog = test_server:timetrap(test_server:minutes(15)),
+ Pa = "-pa " ++ filename:dirname(code:which(?MODULE)) ++
" -pa " ++ CompilerDir,
- ?line Files = compiler_src(),
+ Files = compiler_src(),
%% We don't want the cover server started on the other node,
%% because it will load the same cover-compiled code as on this
@@ -472,7 +466,7 @@ self_compile_node(CompilerDir, OutDir, Version, Opts) ->
fun() ->
compile_compiler(Files, OutDir, Version, Opts)
end, Pa),
- ?line test_server:timetrap_cancel(Dog),
+ test_server:timetrap_cancel(Dog),
ok.
compile_compiler(Files, OutDir, Version, InlineOpts) ->
@@ -499,27 +493,22 @@ compiler_modules(Dir) ->
[list_to_atom(filename:rootname(filename:basename(F))) || F <- Files].
make_compiler_dir(Priv, Dir0) ->
- ?line Dir = filename:join(Priv, Dir0),
- ?line ok = file:make_dir(Dir),
+ Dir = filename:join(Priv, Dir0),
+ ok = file:make_dir(Dir),
Dir.
-make_current(Dir) ->
- true = code:add_patha(Dir),
- lists:foreach(fun(File) ->
- c:l(File)
- end, compiler_modules(Dir)),
- io:format("~p\n", [code:which(compile)]).
-
compiler_version() ->
- {value,{version,Version}} = lists:keysearch(version, 1,
- compile:module_info(compile)),
+ {version,Version} = lists:keyfind(version, 1,
+ compile:module_info(compile)),
Version.
compare_compilers(ADir, BDir) ->
{[],[],D} = beam_lib:cmp_dirs(ADir, BDir),
- [] = [T || {A,_}=T <- D,
- filename:basename(A) =/= "beam_asm.beam"]. %Contains compiler version.
+ %% beam_asm.beam contains compiler version and therefore it *must*
+ %% compare unequal.
+ ["beam_asm.beam"] = [filename:basename(A) || {A,_} <- D],
+ ok.
%%%
%%% The only test of the following code is that it compiles.
@@ -611,12 +600,10 @@ otp_7345(Config) when is_list(Config) ->
otp_7345(ObjRef, _RdEnv, Args) ->
Cid = ObjRef#contextId.cid,
- _DpRef =
- #dpRef{cid = Cid,
+ _ = #dpRef{cid = Cid,
ms_device_context_id = cid_id,
tlli = #ptmsi{value = 0}},
- _QosProfile =
- #qosProfileBssgp{peak_bit_rate_msb = 0,
+ _ = #qosProfileBssgp{peak_bit_rate_msb = 0,
peak_bit_rate_lsb = 80,
t_a_precedence = 49},
[Cpdu|_] = Args,
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_1.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_1.erl
index d6c9c869c8..ce72d0d0f2 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_1.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_10.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_10.erl
index a1264055bd..41c5e7b4d2 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_10.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_10.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_11.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_11.erl
index 4be32ab505..1b6cd66953 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_11.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_11.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_12.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_12.erl
index baee6b9bce..8bb6ce9e4a 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_12.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_12.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_2.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_2.erl
index 0c094d584a..66fdcae4d0 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_2.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_3.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_3.erl
index aced49b69c..adf6fa2720 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_3.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_4.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_4.erl
index 5e74d3cd3c..5ecfed52df 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_4.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_4.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_5.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_5.erl
index a23a0d518c..21bab01c82 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_5.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_5.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_6.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_6.erl
index f263fd75b2..a14c05de10 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_6.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_6.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_8.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_8.erl
index f1f4839798..d8eebc07d1 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_8.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_8.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/beam_compiler_9.erl b/lib/compiler/test/compilation_SUITE_data/beam_compiler_9.erl
index 581b908753..fecc566a95 100644
--- a/lib/compiler/test/compilation_SUITE_data/beam_compiler_9.erl
+++ b/lib/compiler/test/compilation_SUITE_data/beam_compiler_9.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/bin_syntax_1.erl b/lib/compiler/test/compilation_SUITE_data/bin_syntax_1.erl
index 7df1543d83..b381c539b7 100644
--- a/lib/compiler/test/compilation_SUITE_data/bin_syntax_1.erl
+++ b/lib/compiler/test/compilation_SUITE_data/bin_syntax_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/bin_syntax_2.erl b/lib/compiler/test/compilation_SUITE_data/bin_syntax_2.erl
index dcf7b0f8bd..b3e3785249 100644
--- a/lib/compiler/test/compilation_SUITE_data/bin_syntax_2.erl
+++ b/lib/compiler/test/compilation_SUITE_data/bin_syntax_2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/bin_syntax_3.erl b/lib/compiler/test/compilation_SUITE_data/bin_syntax_3.erl
index 93d35d5628..b881d2769e 100644
--- a/lib/compiler/test/compilation_SUITE_data/bin_syntax_3.erl
+++ b/lib/compiler/test/compilation_SUITE_data/bin_syntax_3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/bin_syntax_4.erl b/lib/compiler/test/compilation_SUITE_data/bin_syntax_4.erl
index fe0ce80270..f63eb34fb2 100644
--- a/lib/compiler/test/compilation_SUITE_data/bin_syntax_4.erl
+++ b/lib/compiler/test/compilation_SUITE_data/bin_syntax_4.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/bin_syntax_6.erl b/lib/compiler/test/compilation_SUITE_data/bin_syntax_6.erl
index 8de3a9094f..13e4bb8707 100644
--- a/lib/compiler/test/compilation_SUITE_data/bin_syntax_6.erl
+++ b/lib/compiler/test/compilation_SUITE_data/bin_syntax_6.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/catch_in_catch.erl b/lib/compiler/test/compilation_SUITE_data/catch_in_catch.erl
index c732a912f0..0abde0ff5d 100644
--- a/lib/compiler/test/compilation_SUITE_data/catch_in_catch.erl
+++ b/lib/compiler/test/compilation_SUITE_data/catch_in_catch.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/compiler_1.erl b/lib/compiler/test/compilation_SUITE_data/compiler_1.erl
index 6dbd80d962..02858ec308 100644
--- a/lib/compiler/test/compilation_SUITE_data/compiler_1.erl
+++ b/lib/compiler/test/compilation_SUITE_data/compiler_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/compiler_3.erl b/lib/compiler/test/compilation_SUITE_data/compiler_3.erl
index 47891a22b5..4b99eafc63 100644
--- a/lib/compiler/test/compilation_SUITE_data/compiler_3.erl
+++ b/lib/compiler/test/compilation_SUITE_data/compiler_3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/compiler_5.erl b/lib/compiler/test/compilation_SUITE_data/compiler_5.erl
index c2a0c2064f..63564ac938 100644
--- a/lib/compiler/test/compilation_SUITE_data/compiler_5.erl
+++ b/lib/compiler/test/compilation_SUITE_data/compiler_5.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/complex_guard.erl b/lib/compiler/test/compilation_SUITE_data/complex_guard.erl
index 961aa6a460..37b861b0b5 100644
--- a/lib/compiler/test/compilation_SUITE_data/complex_guard.erl
+++ b/lib/compiler/test/compilation_SUITE_data/complex_guard.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/const_list_256.erl b/lib/compiler/test/compilation_SUITE_data/const_list_256.erl
index 0baf427911..18f4d52d7b 100644
--- a/lib/compiler/test/compilation_SUITE_data/const_list_256.erl
+++ b/lib/compiler/test/compilation_SUITE_data/const_list_256.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/convopts.erl b/lib/compiler/test/compilation_SUITE_data/convopts.erl
index 429c683ca9..55b65d6763 100644
--- a/lib/compiler/test/compilation_SUITE_data/convopts.erl
+++ b/lib/compiler/test/compilation_SUITE_data/convopts.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/guards.erl b/lib/compiler/test/compilation_SUITE_data/guards.erl
index 84e41b8ede..f0d11fc79a 100644
--- a/lib/compiler/test/compilation_SUITE_data/guards.erl
+++ b/lib/compiler/test/compilation_SUITE_data/guards.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/live_var.erl b/lib/compiler/test/compilation_SUITE_data/live_var.erl
index 483eec0630..be79041baf 100644
--- a/lib/compiler/test/compilation_SUITE_data/live_var.erl
+++ b/lib/compiler/test/compilation_SUITE_data/live_var.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/long_string.erl b/lib/compiler/test/compilation_SUITE_data/long_string.erl
index b3cf77b13f..1624e222ab 100644
--- a/lib/compiler/test/compilation_SUITE_data/long_string.erl
+++ b/lib/compiler/test/compilation_SUITE_data/long_string.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/nested_tuples_in_case_expr.erl b/lib/compiler/test/compilation_SUITE_data/nested_tuples_in_case_expr.erl
index 62402c10b7..76401cea97 100644
--- a/lib/compiler/test/compilation_SUITE_data/nested_tuples_in_case_expr.erl
+++ b/lib/compiler/test/compilation_SUITE_data/nested_tuples_in_case_expr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/opt_crash.erl b/lib/compiler/test/compilation_SUITE_data/opt_crash.erl
index 3a1d625c28..9a88df33af 100644
--- a/lib/compiler/test/compilation_SUITE_data/opt_crash.erl
+++ b/lib/compiler/test/compilation_SUITE_data/opt_crash.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/other/vsn_1.erl b/lib/compiler/test/compilation_SUITE_data/other/vsn_1.erl
index 7cb0778b95..7acdb047fb 100644
--- a/lib/compiler/test/compilation_SUITE_data/other/vsn_1.erl
+++ b/lib/compiler/test/compilation_SUITE_data/other/vsn_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/other/vsn_3.erl b/lib/compiler/test/compilation_SUITE_data/other/vsn_3.erl
index 3870e0704d..c8c9975d9b 100644
--- a/lib/compiler/test/compilation_SUITE_data/other/vsn_3.erl
+++ b/lib/compiler/test/compilation_SUITE_data/other/vsn_3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_2141.erl b/lib/compiler/test/compilation_SUITE_data/otp_2141.erl
index 3e766546be..97daf8bffd 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_2141.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_2141.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_2173.erl b/lib/compiler/test/compilation_SUITE_data/otp_2173.erl
index 7e9d4c417b..4155e2d1ff 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_2173.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_2173.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_2330.erl b/lib/compiler/test/compilation_SUITE_data/otp_2330.erl
index f5f6717968..c9ba7c7ba5 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_2330.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_2330.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_2380.erl b/lib/compiler/test/compilation_SUITE_data/otp_2380.erl
index db2028b347..dbf44e5fb8 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_2380.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_2380.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_4790.erl b/lib/compiler/test/compilation_SUITE_data/otp_4790.erl
index 130ee44e80..3a32372cc9 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_4790.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_4790.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5076.erl b/lib/compiler/test/compilation_SUITE_data/otp_5076.erl
index f05a4e1148..7d96b5c734 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5076.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5076.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5092.erl b/lib/compiler/test/compilation_SUITE_data/otp_5092.erl
index e445e5e1e9..b675e09af6 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5092.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5092.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5151.erl b/lib/compiler/test/compilation_SUITE_data/otp_5151.erl
index 2dccb979df..c40de9e508 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5151.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5151.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5235.erl b/lib/compiler/test/compilation_SUITE_data/otp_5235.erl
index 1c918cdf9d..69a0a476fb 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5235.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5235.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5244.erl b/lib/compiler/test/compilation_SUITE_data/otp_5244.erl
index 30849c6b5e..0fc32ddd36 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5244.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5244.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5404.erl b/lib/compiler/test/compilation_SUITE_data/otp_5404.erl
index 2de147c082..66256fe33b 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5404.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5404.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5436.erl b/lib/compiler/test/compilation_SUITE_data/otp_5436.erl
index 4df8d50647..1ae564eed0 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5436.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5436.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5481.erl b/lib/compiler/test/compilation_SUITE_data/otp_5481.erl
index 5cf114ac4e..068845ac98 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5481.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5481.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5553.erl b/lib/compiler/test/compilation_SUITE_data/otp_5553.erl
index 9a7004a980..fb654dca8a 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5553.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5553.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5632.erl b/lib/compiler/test/compilation_SUITE_data/otp_5632.erl
index ebf8e47ca2..229b5197bc 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5632.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5632.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5714.erl b/lib/compiler/test/compilation_SUITE_data/otp_5714.erl
index 5aefa0a803..d90f937385 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5714.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5714.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_5872.erl b/lib/compiler/test/compilation_SUITE_data/otp_5872.erl
index cada7ad994..00d210c4c8 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_5872.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_5872.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_6121.erl b/lib/compiler/test/compilation_SUITE_data/otp_6121.erl
index c71f7806a0..898e6304d6 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_6121.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_6121.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_6121a.erl b/lib/compiler/test/compilation_SUITE_data/otp_6121a.erl
index caed631aa2..fd0a25c779 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_6121a.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_6121a.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_6121b.erl b/lib/compiler/test/compilation_SUITE_data/otp_6121b.erl
index 967f078942..0c6b511bec 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_6121b.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_6121b.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/otp_7202.erl b/lib/compiler/test/compilation_SUITE_data/otp_7202.erl
index 9dca244aa5..4437c484b4 100644
--- a/lib/compiler/test/compilation_SUITE_data/otp_7202.erl
+++ b/lib/compiler/test/compilation_SUITE_data/otp_7202.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/pattern_expr.erl b/lib/compiler/test/compilation_SUITE_data/pattern_expr.erl
index 02eacced81..da9c3c0a9a 100644
--- a/lib/compiler/test/compilation_SUITE_data/pattern_expr.erl
+++ b/lib/compiler/test/compilation_SUITE_data/pattern_expr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/trycatch_4.erl b/lib/compiler/test/compilation_SUITE_data/trycatch_4.erl
index 7ea710856f..e6f87bf01b 100644
--- a/lib/compiler/test/compilation_SUITE_data/trycatch_4.erl
+++ b/lib/compiler/test/compilation_SUITE_data/trycatch_4.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/vsn_1.erl b/lib/compiler/test/compilation_SUITE_data/vsn_1.erl
index a9e23f7c25..c3ce2f0445 100644
--- a/lib/compiler/test/compilation_SUITE_data/vsn_1.erl
+++ b/lib/compiler/test/compilation_SUITE_data/vsn_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/vsn_2.erl b/lib/compiler/test/compilation_SUITE_data/vsn_2.erl
index 4833458cf4..ced2d7ca0b 100644
--- a/lib/compiler/test/compilation_SUITE_data/vsn_2.erl
+++ b/lib/compiler/test/compilation_SUITE_data/vsn_2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compilation_SUITE_data/vsn_3.erl b/lib/compiler/test/compilation_SUITE_data/vsn_3.erl
index 7b970b2b75..8312668d27 100644
--- a/lib/compiler/test/compilation_SUITE_data/vsn_3.erl
+++ b/lib/compiler/test/compilation_SUITE_data/vsn_3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index 8cb7d1b55b..cbdd9ce8cd 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,9 @@
other_output/1, encrypted_abstr/1,
bad_record_use1/1, bad_record_use2/1, strict_record/1,
missing_testheap/1, cover/1, env/1, core/1, asm/1,
- sys_pre_attributes/1]).
+ sys_pre_attributes/1, dialyzer/1,
+ warnings/1
+ ]).
-export([init/3]).
@@ -47,7 +50,7 @@ all() ->
other_output, encrypted_abstr,
{group, bad_record_use}, strict_record,
missing_testheap, cover, env, core, asm,
- sys_pre_attributes].
+ sys_pre_attributes, dialyzer, warnings].
groups() ->
[{bad_record_use, [],
@@ -102,6 +105,8 @@ file_1(Config) when is_list(Config) ->
?line compile_and_verify(Simple, Target, [debug_info]),
?line {ok,simple} = compile:file(Simple, [no_line_info]), %Coverage
+ {ok,simple} = compile:file(Simple, [{eprof,beam_z}]), %Coverage
+
?line ok = file:set_cwd(Cwd),
?line true = exists(Target),
?line passed = run(Target, test, []),
@@ -124,7 +129,8 @@ file_1(Config) when is_list(Config) ->
forms_2(Config) when is_list(Config) ->
Src = "/foo/bar",
AbsSrc = filename:absname(Src),
- {ok,simple,Binary} = compile:forms([{attribute,1,module,simple}],
+ Anno = erl_anno:new(1),
+ {ok,simple,Binary} = compile:forms([{attribute,Anno,module,simple}],
[binary,{source,Src}]),
code:load_binary(simple, Src, Binary),
Info = simple:module_info(compile),
@@ -365,7 +371,7 @@ listings_big(Config) when is_list(Config) ->
?line do_listing(Big, TargetDir, dkern, ".kernel"),
?line Target = filename:join(TargetDir, big),
- ?line {ok,big} = compile:file(Target, [asm,{outdir,TargetDir}]),
+ {ok,big} = compile:file(Target, [from_asm,{outdir,TargetDir}]),
%% Cleanup.
?line ok = file:delete(Target ++ ".beam"),
@@ -748,42 +754,65 @@ env_1(Simple, Target) ->
%% compile the generated Core Erlang files.
core(Config) when is_list(Config) ->
- ?line Dog = test_server:timetrap(test_server:minutes(5)),
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Outdir = filename:join(PrivDir, "core"),
- ?line ok = file:make_dir(Outdir),
+ PrivDir = ?config(priv_dir, Config),
+ Outdir = filename:join(PrivDir, "core"),
+ ok = file:make_dir(Outdir),
- ?line Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
- ?line TestBeams = filelib:wildcard(Wc),
- ?line Abstr = [begin {ok,{Mod,[{abstract_code,
+ Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
+ TestBeams = filelib:wildcard(Wc),
+ Abstr = [begin {ok,{Mod,[{abstract_code,
{raw_abstract_v1,Abstr}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
{Mod,Abstr} end || Beam <- TestBeams],
- ?line Res = test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr),
- ?line test_server:timetrap_cancel(Dog),
- Res.
-
+ test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr).
do_core({M,A}, Outdir) ->
try
- {ok,M,Core} = compile:forms(A, [to_core,report]),
- CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
- CorePP = core_pp:format(Core),
- ok = file:write_file(CoreFile, CorePP),
- case compile:file(CoreFile, [clint,from_core,binary]) of
- {ok,M,_} ->
- ok = file:delete(CoreFile);
- Other ->
- io:format("*** core_lint failure '~p' for ~s\n",
- [Other,CoreFile]),
- error
- end
- catch Class:Error ->
+ do_core_1(M, A, Outdir)
+ 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.
+do_core_1(M, A, Outdir) ->
+ {ok,M,Core0} = compile:forms(A, [to_core]),
+ CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
+ CorePP = core_pp:format(Core0),
+ ok = file:write_file(CoreFile, CorePP),
+
+ %% Parse the .core file and return the result as Core Erlang Terms.
+ Core = case compile:file(CoreFile, [report_errors,from_core,no_copt,to_core,binary]) of
+ {ok,M,Core1} -> Core1;
+ Other -> throw({error,Other})
+ end,
+ ok = file:delete(CoreFile),
+
+ %% Compile as usual (including optimizations).
+ compile_forms(Core, [clint,from_core,binary]),
+
+ %% Don't optimize to test that we are not dependent
+ %% on the Core Erlang optmimization passes.
+ %% (Example of a previous bug: The core_parse pass
+ %% would not turn map literals into #c_literal{}
+ %% records; if sys_core_fold was run it would fix
+ %% that; if sys_core_fold was not run v3_kernel would
+ %% crash.)
+ compile_forms(Core, [clint,from_core,no_copt,binary]),
+
+ ok.
+
+compile_forms(Forms, Opts) ->
+ case compile:forms(Forms, [report_errors|Opts]) of
+ {ok,[],_} -> ok;
+ Other -> throw({error,Other})
+ end.
+
%% Compile to Beam assembly language (.S) and then try to
%% run .S through the compiler again.
@@ -854,6 +883,58 @@ sys_pre_attributes(Config) ->
[report,verbose]),
ok.
+%% Test the dialyzer option to cover more code.
+dialyzer(Config) ->
+ Priv = ?config(priv_dir, Config),
+ file:set_cwd(?config(data_dir, Config)),
+ Opts = [{outdir,Priv},report_errors],
+ M = dialyzer_test,
+ {ok,M} = c:c(M, [dialyzer|Opts]),
+ [{a,b,c}] = M:M(),
+
+ %% Cover huge line numbers without the 'dialyzer' option.
+ {ok,M} = c:c(M, Opts),
+ [{a,b,c}] = M:M(),
+ ok.
+
+
+%% Test that warnings contain filenames and line numbers.
+warnings(_Config) ->
+ TestDir = filename:dirname(code:which(?MODULE)),
+ Files = filelib:wildcard(filename:join(TestDir, "*.erl")),
+ test_lib:p_run(fun do_warnings/1, Files).
+
+do_warnings(F) ->
+ {ok,_,_,Ws} = compile:file(F, [binary,bin_opt_info,return]),
+ do_warnings_1(Ws, F).
+
+do_warnings_1([{"no_file",Ws}|_], F) ->
+ io:format("~s:\nMissing file for warnings: ~p\n",
+ [F,Ws]),
+ error;
+do_warnings_1([{Name,Ws}|T], F) ->
+ case filename:extension(Name) of
+ ".erl" ->
+ do_warnings_2(Ws, T, F);
+ _ ->
+ io:format("~s:\nNo .erl extension\n", [F]),
+ error
+ end;
+do_warnings_1([], _) -> ok.
+
+do_warnings_2([{Int,_,_}=W|T], Next, F) ->
+ if
+ is_integer(Int) ->
+ do_warnings_2(T, Next, F);
+ true ->
+ io:format("~s:\nMissing line number: ~p\n",
+ [F,W]),
+ error
+ end;
+do_warnings_2([], Next, F) ->
+ do_warnings_1(Next, F).
+
+
%%%
%%% Utilities.
%%%
diff --git a/lib/compiler/test/compile_SUITE_data/attributes.erl b/lib/compiler/test/compile_SUITE_data/attributes.erl
index 9c3451d272..00e635a021 100644
--- a/lib/compiler/test/compile_SUITE_data/attributes.erl
+++ b/lib/compiler/test/compile_SUITE_data/attributes.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/bad_record_use.erl b/lib/compiler/test/compile_SUITE_data/bad_record_use.erl
index c2adbfa8de..0fb6fc3045 100644
--- a/lib/compiler/test/compile_SUITE_data/bad_record_use.erl
+++ b/lib/compiler/test/compile_SUITE_data/bad_record_use.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/bad_record_use2.erl b/lib/compiler/test/compile_SUITE_data/bad_record_use2.erl
index 1de44b2df4..7c898af00f 100644
--- a/lib/compiler/test/compile_SUITE_data/bad_record_use2.erl
+++ b/lib/compiler/test/compile_SUITE_data/bad_record_use2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/big.erl b/lib/compiler/test/compile_SUITE_data/big.erl
index 4cd8e15f13..d916742770 100644
--- a/lib/compiler/test/compile_SUITE_data/big.erl
+++ b/lib/compiler/test/compile_SUITE_data/big.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/dialyzer_test.erl b/lib/compiler/test/compile_SUITE_data/dialyzer_test.erl
new file mode 100644
index 0000000000..0df737ba4c
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/dialyzer_test.erl
@@ -0,0 +1,40 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(dialyzer_test).
+-export([?MODULE/0,turtle/0,test/1,huge/1]).
+
+-record(turtle, {a,b,c}).
+-record(tortoise, {a,b,c}).
+
+?MODULE() ->
+ [{a,b,c}].
+
+turtle() ->
+ #turtle{a=1,b=2,c=3}.
+
+test(T) ->
+ {T#tortoise.a,T#tortoise.b}.
+
+-file("dialyzer_test", 100000000).
+
+huge(X) ->
+ #turtle{a=42,b=100,c=511},
+ X#tortoise.a.
diff --git a/lib/compiler/test/compile_SUITE_data/include/simple.hrl b/lib/compiler/test/compile_SUITE_data/include/simple.hrl
index cbe6e4f1a4..91398e209a 100644
--- a/lib/compiler/test/compile_SUITE_data/include/simple.hrl
+++ b/lib/compiler/test/compile_SUITE_data/include/simple.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/missing_testheap1.erl b/lib/compiler/test/compile_SUITE_data/missing_testheap1.erl
index 65ee11541d..9d88bc4afe 100644
--- a/lib/compiler/test/compile_SUITE_data/missing_testheap1.erl
+++ b/lib/compiler/test/compile_SUITE_data/missing_testheap1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/missing_testheap2.erl b/lib/compiler/test/compile_SUITE_data/missing_testheap2.erl
index 014210fa5a..b61e8d3c88 100644
--- a/lib/compiler/test/compile_SUITE_data/missing_testheap2.erl
+++ b/lib/compiler/test/compile_SUITE_data/missing_testheap2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/record_access.erl b/lib/compiler/test/compile_SUITE_data/record_access.erl
index c89f9ad7c7..9a83472da4 100644
--- a/lib/compiler/test/compile_SUITE_data/record_access.erl
+++ b/lib/compiler/test/compile_SUITE_data/record_access.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/simple.erl b/lib/compiler/test/compile_SUITE_data/simple.erl
index 0c1c70a778..37e7b508f9 100644
--- a/lib/compiler/test/compile_SUITE_data/simple.erl
+++ b/lib/compiler/test/compile_SUITE_data/simple.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/compile_SUITE_data/wrong_module_name.erl b/lib/compiler/test/compile_SUITE_data/wrong_module_name.erl
index ea437556a4..8b4db1cfa3 100644
--- a/lib/compiler/test/compile_SUITE_data/wrong_module_name.erl
+++ b/lib/compiler/test/compile_SUITE_data/wrong_module_name.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index 428ad65364..25f8564ce4 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,7 +25,9 @@
dehydrated_itracer/1,nested_tries/1,
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]).
+ map_core_test/1,eval_case/1,bad_boolean_guard/1,
+ bs_shadowed_size_var/1
+ ]).
-include_lib("test_server/include/test_server.hrl").
@@ -50,7 +53,8 @@ groups() ->
[{p,test_lib:parallel(),
[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
+ map_core_test,eval_case,bad_boolean_guard,
+ bs_shadowed_size_var
]}].
@@ -78,6 +82,8 @@ end_per_group(_GroupName, Config) ->
?comp(map_core_test).
?comp(eval_case).
?comp(bad_boolean_guard).
+?comp(bs_shadowed_size_var).
+
try_it(Mod, Conf) ->
Src = filename:join(?config(data_dir, Conf), atom_to_list(Mod)),
@@ -87,4 +93,7 @@ try_it(Mod, Conf) ->
compile_and_load(Src, Opts) ->
{ok,Mod,Bin} = compile:file(Src, [from_core,report,time,binary|Opts]),
{module,Mod} = code:load_binary(Mod, Mod, Bin),
- ok = Mod:Mod().
+ ok = Mod:Mod(),
+ _ = code:delete(Mod),
+ _ = code:purge(Mod),
+ ok.
diff --git a/lib/compiler/test/core_SUITE_data/bs_shadowed_size_var.core b/lib/compiler/test/core_SUITE_data/bs_shadowed_size_var.core
new file mode 100644
index 0000000000..0ade037e05
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/bs_shadowed_size_var.core
@@ -0,0 +1,66 @@
+module 'bs_shadowed_size_var'
+ ['filter_essentials'/1,
+ 'bs_shadowed_size_var'/0]
+ attributes []
+
+%% bs_shadowed_size_var() ->
+%% [42|<<"abcde">>] = Mod:filter_essentials([<<42:32>>|<<5:32,"abcde">>]),
+%% ok.
+
+'bs_shadowed_size_var'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ case apply 'filter_essentials'/1
+ ([#{#<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<42>(8,1,'integer',['unsigned'|['big']])}#|#{#<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<5>(8,1,'integer',['unsigned'|['big']]),
+ #<97>(8,1,'integer',['unsigned'|['big']]),
+ #<98>(8,1,'integer',['unsigned'|['big']]),
+ #<99>(8,1,'integer',['unsigned'|['big']]),
+ #<100>(8,1,'integer',['unsigned'|['big']]),
+ #<101>(8,1,'integer',['unsigned'|['big']])}#]) of
+ <[42|#{#<97>(8,1,'integer',['unsigned'|['big']]),
+ #<98>(8,1,'integer',['unsigned'|['big']]),
+ #<99>(8,1,'integer',['unsigned'|['big']]),
+ #<100>(8,1,'integer',['unsigned'|['big']]),
+ #<101>(8,1,'integer',['unsigned'|['big']])}#]> when 'true' ->
+ 'ok'
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'bs_shadowed_size_var',0}}] )
+ -| ['compiler_generated'] )
+ end
+
+%% Reduced code from beam_asm inlined using the old inliner.
+
+'filter_essentials'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <[#{#<Sz>(32,1,'integer',['unsigned','big']) }#|T]> when 'true' ->
+ let <_cor4> =
+ case T of
+ %% Variable 'Sz' repeated here. Should work.
+ <#{#<Sz>(32,1,'integer',['unsigned','big']),
+ #<Data>(Sz,8,'binary',['unsigned','big'])}#> when 'true' ->
+ Data
+ <_cor5> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',{_cor5}})
+ end
+ in [Sz|_cor4]
+ <_cor5> when 'true' ->
+ primop 'match_fail'
+ ({'function_clause',_cor5})
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/map_core_test.core b/lib/compiler/test/core_SUITE_data/map_core_test.core
index 2aa853d450..a75f6cf24f 100644
--- a/lib/compiler/test/core_SUITE_data/map_core_test.core
+++ b/lib/compiler/test/core_SUITE_data/map_core_test.core
@@ -7,11 +7,11 @@ module 'map_core_test' ['map_core_test'/0,
fun () ->
let <_cor0> =
%% Line 15
- ~{::<'check','ok'>,::<1337,#{#<104>(8,1,'integer',['unsigned'|['big']]),
+ ~{'check'=>'ok',1337=>#{#<104>(8,1,'integer',['unsigned'|['big']]),
#<101>(8,1,'integer',['unsigned'|['big']]),
#<108>(8,1,'integer',['unsigned'|['big']]),
#<108>(8,1,'integer',['unsigned'|['big']]),
- #<111>(8,1,'integer',['unsigned'|['big']])}#>,::<'val',0>}~
+ #<111>(8,1,'integer',['unsigned'|['big']])}#,'val'=>0}~
in let <M> =
%% Line 15
apply 'id'/1
@@ -23,7 +23,7 @@ module 'map_core_test' ['map_core_test'/0,
in %% Line 16
case apply 'call'/2
(M, _cor2) of
- <~{~<1337,#{#<104>(8,1,'integer',['unsigned'|['big']]),
+ <~{1337:=#{#<104>(8,1,'integer',['unsigned'|['big']]),
#<101>(8,1,'integer',['unsigned'|['big']]),
#<108>(8,1,'integer',['unsigned'|['big']]),
#<108>(8,1,'integer',['unsigned'|['big']]),
@@ -39,7 +39,7 @@ module 'map_core_test' ['map_core_test'/0,
#<32>(8,1,'integer',['unsigned'|['big']]),
#<53>(8,1,'integer',['unsigned'|['big']]),
#<32>(8,1,'integer',['unsigned'|['big']]),
- #<54>(8,1,'integer',['unsigned'|['big']])}#>,~<'check','ok'>,~<'val',21>}~> when 'true' ->
+ #<54>(8,1,'integer',['unsigned'|['big']])}#,'check':='ok','val':=21}~> when 'true' ->
%% Line 17
'ok'
( <_cor3> when 'true' ->
@@ -51,7 +51,7 @@ module 'map_core_test' ['map_core_test'/0,
%% Line 20
fun (_cor1,_cor0) ->
case <_cor1,_cor0> of
- <M = ~{~<1337,Bin>,~<'check',_cor8>,~<'val',Val>}~,[V|Vs]> when 'true' ->
+ <M = ~{1337:=Bin,'check':=_cor8,'val':=Val}~,[V|Vs]> when 'true' ->
let <_cor3> =
%% Line 21
call 'erlang':'+'
@@ -67,7 +67,7 @@ module 'map_core_test' ['map_core_test'/0,
(Val, V)
in let <_cor5> =
%% Line 21
- ~{~<1337,_cor4>,~<'val',_cor2>|M}~
+ ~{1337:=_cor4,'val':=_cor2|M}~
in %% Line 21
apply 'call'/2
(_cor5, Vs)
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 2de17e7653..016ea9d0d9 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -23,7 +24,8 @@
t_element/1,setelement/1,t_length/1,append/1,t_apply/1,bifs/1,
eq/1,nested_call_in_case/1,guard_try_catch/1,coverage/1,
unused_multiple_values_error/1,unused_multiple_values/1,
- multiple_aliases/1,redundant_boolean_clauses/1,mixed_matching_clauses/1]).
+ multiple_aliases/1,redundant_boolean_clauses/1,
+ mixed_matching_clauses/1,unnecessary_building/1]).
-export([foo/0,foo/1,foo/2,foo/3]).
@@ -36,11 +38,12 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[t_element,setelement,t_length,append,t_apply,bifs,
eq,nested_call_in_case,guard_try_catch,coverage,
unused_multiple_values_error,unused_multiple_values,
- multiple_aliases,redundant_boolean_clauses,mixed_matching_clauses]}].
+ multiple_aliases,redundant_boolean_clauses,
+ mixed_matching_clauses,unnecessary_building]}].
init_per_suite(Config) ->
@@ -86,6 +89,7 @@ t_element(Config) when is_list(Config) ->
{_,_,_}=Tup ->
?line {'EXIT',{badarg,_}} = (catch element(4, Tup))
end,
+ {'EXIT',{badarg,_}} = (catch element(1, tuple_size(Tuple))),
ok.
@@ -104,6 +108,7 @@ setelement(Config) when is_list(Config) ->
?line error = setelement_crash_2({a,b,c,d,e,f}, <<42>>),
{'EXIT',{badarg,_}} = (catch setelement(1, not_a_tuple, New)),
+ {'EXIT',{badarg,_}} = (catch setelement(3, {a,b}, New)),
ok.
@@ -195,7 +200,10 @@ foo(A, B, C) ->
A + B + C.
bifs(Config) when is_list(Config) ->
- ?line <<1,2,3,4>> = id(list_to_binary([1,2,3,4])),
+ <<1,2,3,4>> = id(list_to_binary([1,2,3,4])),
+ K = {a,key},
+ V = {a,value},
+ {ok,#{K:=V}} = id(list_to_tuple([ok,#{K=>V}])),
ok.
-define(CMP_SAME(A0, B), (fun(A) -> true = A == B, false = A /= B end)(id(A0))).
@@ -224,15 +232,17 @@ eq(Config) when is_list(Config) ->
%% OTP-7117.
nested_call_in_case(Config) when is_list(Config) ->
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Dir = filename:dirname(code:which(?MODULE)),
- ?line Core = filename:join(Dir, "nested_call_in_case"),
- ?line Opts = [from_core,{outdir,PrivDir}|test_lib:opt_opts(?MODULE)],
- ?line io:format("~p", [Opts]),
- ?line {ok,Mod} = c:c(Core, Opts),
- ?line yes = Mod:a([1,2,3], 2),
- ?line no = Mod:a([1,2,3], 4),
- ?line {'EXIT',_} = (catch Mod:a(not_a_list, 42)),
+ PrivDir = ?config(priv_dir, Config),
+ Dir = test_lib:get_data_dir(Config),
+ Core = filename:join(Dir, "nested_call_in_case"),
+ Opts = [from_core,{outdir,PrivDir}|test_lib:opt_opts(?MODULE)],
+ io:format("~p", [Opts]),
+ {ok,Mod} = c:c(Core, Opts),
+ yes = Mod:a([1,2,3], 2),
+ no = Mod:a([1,2,3], 4),
+ {'EXIT',_} = (catch Mod:a(not_a_list, 42)),
+ _ = code:delete(Mod),
+ _ = code:purge(Mod),
ok.
guard_try_catch(_Config) ->
@@ -252,6 +262,8 @@ do_guard_try_catch(K, V) ->
false
end.
+-record(cover_opt_guard_try, {list=[]}).
+
coverage(Config) when is_list(Config) ->
?line {'EXIT',{{case_clause,{a,b,c}},_}} =
(catch cover_will_match_list_type({a,b,c})),
@@ -261,6 +273,9 @@ coverage(Config) when is_list(Config) ->
?line error = cover_will_match_lit_list(),
{ok,[a]} = cover_is_safe_bool_expr(a),
+ ok = cover_opt_guard_try(#cover_opt_guard_try{list=[a]}),
+ error = cover_opt_guard_try(#cover_opt_guard_try{list=[]}),
+
%% Make sure that we don't attempt to make literals
%% out of pids. (Putting a pid into a #c_literal{}
%% would crash later compiler passes.)
@@ -273,6 +288,12 @@ coverage(Config) when is_list(Config) ->
error = bsm_an_inlined(<<1,2,3>>, Config),
error = bsm_an_inlined([], Config),
+ %% Cover eval_rel_op/4.
+ Tuple = id({a,b}),
+ false = case Tuple of
+ {_,_} ->
+ Tuple =:= true
+ end,
ok.
cover_will_match_list_type(A) ->
@@ -314,12 +335,20 @@ cover_is_safe_bool_expr(X) ->
false
end.
+cover_opt_guard_try(Msg) ->
+ if
+ length(Msg#cover_opt_guard_try.list) =/= 1 ->
+ error;
+ true ->
+ ok
+ end.
+
bsm_an_inlined(<<_:8>>, _) -> ok;
bsm_an_inlined(_, _) -> error.
unused_multiple_values_error(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
- Dir = filename:dirname(code:which(?MODULE)),
+ Dir = test_lib:get_data_dir(Config),
Core = filename:join(Dir, "unused_multiple_values_error"),
Opts = [no_copt,clint,return,from_core,{outdir,PrivDir}
|test_lib:opt_opts(?MODULE)],
@@ -400,4 +429,29 @@ mixed_matching_clauses(Config) when is_list(Config) ->
end,
ok.
+unnecessary_building(Config) when is_list(Config) ->
+ Term1 = do_unnecessary_building_1(test_lib:id(a)),
+ [{a,a},{a,a}] = Term1,
+ 7 = erts_debug:size(Term1),
+
+ %% The Input term should not be rebuilt (thus, it should
+ %% only be counted once in the size of the combined term).
+ Input = test_lib:id({a,b,c}),
+ Term2 = test_lib:id(do_unnecessary_building_2(Input)),
+ {b,[{a,b,c},none],x} = Term2,
+ 4+4+4+2 = erts_debug:size([Term2|Input]),
+
+ ok.
+
+do_unnecessary_building_1(S) ->
+ %% The tuple must only be built once.
+ F0 = F1 = {S,S},
+ [F0,F1].
+
+do_unnecessary_building_2({a,_,_}=T) ->
+ %% The T term should not be rebuilt.
+ {b,
+ [_,_] = [T,none],
+ x}.
+
id(I) -> I.
diff --git a/lib/compiler/test/nested_call_in_case.core b/lib/compiler/test/core_fold_SUITE_data/nested_call_in_case.core
index 5c6b6909bd..c46906b2ed 100644
--- a/lib/compiler/test/nested_call_in_case.core
+++ b/lib/compiler/test/core_fold_SUITE_data/nested_call_in_case.core
@@ -16,6 +16,3 @@ module 'nested_call_in_case' ['a'/2]
-| ['compiler_generated'] )
end
end
-
-
-
diff --git a/lib/compiler/test/unused_multiple_values_error.core b/lib/compiler/test/core_fold_SUITE_data/unused_multiple_values_error.core
index e06587c936..e06587c936 100644
--- a/lib/compiler/test/unused_multiple_values_error.core
+++ b/lib/compiler/test/core_fold_SUITE_data/unused_multiple_values_error.core
diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index bd877bb528..2962e3ff77 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -3,19 +3,19 @@
%%
%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% http://www.apache.org/licenses/LICENSE-2.0
%%
-%% %CopyrightEnd%
+%% 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(error_SUITE).
-include_lib("test_server/include/test_server.hrl").
@@ -23,7 +23,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1,
- transforms/1,forbidden_maps/1,bad_utf8/1]).
+ transforms/1,maps_warnings/1,bad_utf8/1]).
%% Used by transforms/1 test case.
-export([parse_transform/2]).
@@ -37,7 +37,7 @@ all() ->
groups() ->
[{p,test_lib:parallel(),
[head_mismatch_line,warnings_as_errors,bif_clashes,
- transforms,forbidden_maps,bad_utf8]}].
+ transforms,maps_warnings,bad_utf8]}].
init_per_suite(Config) ->
Config.
@@ -235,23 +235,44 @@ transforms(Config) ->
">>,
{error,[{none,compile,{parse_transform,?MODULE,{too_bad,_}}}],[]} =
run_test(Ts2, test_filename(Config), [], dont_write_beam),
+ Ts3 = <<"
+ -compile({parse_transform,",?MODULE_STRING,"}).
+ ">>,
+ {error,[{none,compile,{parse_transform,?MODULE,{undef,_}}}],[]} =
+ run_test(Ts3, test_filename(Config), [call_undef], dont_write_beam),
ok.
-parse_transform(_, _) ->
- error(too_bad).
+parse_transform(_, Opts) ->
+ case lists:member(call_undef, Opts) of
+ false -> error(too_bad);
+ true -> camembert:délicieux()
+ end.
-forbidden_maps(Config) when is_list(Config) ->
- Ts1 = [{map_illegal_use_of_pattern,
+maps_warnings(Config) when is_list(Config) ->
+ Ts1 = [{map_ok_use_of_pattern,
<<"
- -export([t/0]).
+ -export([t/1]).
+ t(K) ->
+ #{K := 1 = V} = id(#{<<\"hi all\">> => 1}),
+ V.
+ id(I) -> I.
+ ">>,
+ [return],
+ []},
+ {map_illegal_use_of_pattern,
+ <<"
+ -export([t/0,t/2]).
+ t(K,#{ K := V }) -> V.
t() ->
V = 32,
#{<<\"hi\",V,\"all\">> := 1} = id(#{<<\"hi all\">> => 1}).
id(I) -> I.
">>,
[return],
- {error,[{5,erl_lint,{illegal_map_key_variable,'V'}}], []}}],
+ {error,[{3,erl_lint,{unbound_var,'K'}},
+ {6,erl_lint,illegal_map_key}],[]}}
+ ],
[] = run2(Config, Ts1),
ok.
diff --git a/lib/compiler/test/error_SUITE_data/head_mismatch_line.erl b/lib/compiler/test/error_SUITE_data/head_mismatch_line.erl
index 619c1329a4..090f2fb829 100644
--- a/lib/compiler/test/error_SUITE_data/head_mismatch_line.erl
+++ b/lib/compiler/test/error_SUITE_data/head_mismatch_line.erl
@@ -3,19 +3,19 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(head_mismatch_line).
-export([foo/1, bar/2]).
diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl
index afc04fd440..1b313ad021 100644
--- a/lib/compiler/test/float_SUITE.erl
+++ b/lib/compiler/test/float_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -118,6 +119,7 @@ math_functions(Config) when is_list(Config) ->
?line 0.0 = math:sinh(0),
?line 1.0 = math:cosh(0),
?line 0.0 = math:tanh(0),
+ 1.0 = math:log2(2),
?line 1.0 = math:log10(10),
?line -1.0 = math:cos(math:pi()),
?line 1.0 = math:exp(0),
@@ -136,6 +138,7 @@ math_functions(Config) when is_list(Config) ->
?line 0.0 = math:sinh(id(0)),
?line 1.0 = math:cosh(id(0)),
?line 0.0 = math:tanh(id(0)),
+ 1.0 = math:log2(id(2)),
?line 1.0 = math:log10(id(10)),
?line 1.0 = math:exp(id(0)),
?line 0.0 = math:log(id(1)),
diff --git a/lib/compiler/test/fun_SUITE.erl b/lib/compiler/test/fun_SUITE.erl
index a3e9b7fe4e..36a4d6fce2 100644
--- a/lib/compiler/test/fun_SUITE.erl
+++ b/lib/compiler/test/fun_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 34bfdeb1e5..47eb1ba78b 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,10 +31,11 @@
old_guard_tests/1,
build_in_guard/1,gbif/1,
t_is_boolean/1,is_function_2/1,
- tricky/1,rel_ops/1,literal_type_tests/1,
+ tricky/1,rel_ops/1,rel_op_combinations/1,literal_type_tests/1,
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]).
+ bad_constants/1,bad_guards/1,scotland/1,
+ guard_in_catch/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -42,15 +44,16 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[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,
+ t_is_boolean,is_function_2,tricky,
+ 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]}].
+ bad_constants,bad_guards,scotland,guard_in_catch]}].
init_per_suite(Config) ->
Config.
@@ -330,7 +333,15 @@ complex_semicolon(Config) when is_list(Config) ->
?line ok = csemi6({a,b}, 0),
?line ok = csemi6({}, 3),
?line ok = csemi6({a,b,c}, 3),
-
+
+ %% 7
+ error = csemi7(#{a=>1}, 1, 0),
+ error = csemi7(<<>>, 1, 0),
+ ok = csemi7(#{a=>1}, 3, 0),
+ ok = csemi7(#{a=>1}, 0, 3),
+ ok = csemi7(#{a=>1}, 3, 3),
+ ok = csemi7(#{a=>1, b=>3}, 0, 0),
+
ok.
csemi1(Type, Val) when is_list(Val), Type == float;
@@ -442,6 +453,9 @@ csemi5(_, _) -> error.
csemi6(A, B) when hd([tuple_size(A)]) > 1; abs(B) > 2 -> ok;
csemi6(_, _) -> error.
+csemi7(A, B, C) when A#{a:=B} > #{a=>1}; abs(C) > 2 -> ok;
+csemi7(_, _, _) -> error.
+
comma(Config) when is_list(Config) ->
%% ',' combinations of literal true/false.
@@ -1122,6 +1136,231 @@ rel_ops(Config) when is_list(Config) ->
-undef(TestOp).
+rel_op_combinations(Config) when is_list(Config) ->
+ Digits0 = lists:seq(16#0030, 16#0039) ++
+ lists:seq(16#0660, 16#0669) ++
+ lists:seq(16#06F0, 16#06F9),
+ Digits = gb_sets:from_list(Digits0),
+ rel_op_combinations_1(16#0700, Digits),
+
+ BrokenRange0 = lists:seq(3, 5) ++
+ lists:seq(10, 12) ++ lists:seq(14, 20),
+ BrokenRange = gb_sets:from_list(BrokenRange0),
+ rel_op_combinations_2(30, BrokenRange),
+
+ Red0 = [{I,2*I} || I <- lists:seq(0, 50)] ++
+ [{I,5*I} || I <- lists:seq(51, 80)],
+ Red = gb_trees:from_orddict(Red0),
+ rel_op_combinations_3(100, Red).
+
+rel_op_combinations_1(0, _) ->
+ ok;
+rel_op_combinations_1(N, Digits) ->
+ Bool = gb_sets:is_member(N, Digits),
+ Bool = is_digit_1(N),
+ Bool = is_digit_2(N),
+ Bool = is_digit_3(N),
+ Bool = is_digit_4(N),
+ Bool = is_digit_5(N),
+ Bool = is_digit_6(N),
+ Bool = is_digit_7(N),
+ Bool = is_digit_8(N),
+ rel_op_combinations_1(N-1, Digits).
+
+is_digit_1(X) when 16#0660 =< X, X =< 16#0669 -> true;
+is_digit_1(X) when 16#0030 =< X, X =< 16#0039 -> true;
+is_digit_1(X) when 16#06F0 =< X, X =< 16#06F9 -> true;
+is_digit_1(_) -> false.
+
+is_digit_2(X) when (16#0030-1) < X, X =< 16#0039 -> true;
+is_digit_2(X) when (16#0660-1) < X, X =< 16#0669 -> true;
+is_digit_2(X) when (16#06F0-1) < X, X =< 16#06F9 -> true;
+is_digit_2(_) -> false.
+
+is_digit_3(X) when 16#0660 =< X, X < (16#0669+1) -> true;
+is_digit_3(X) when 16#0030 =< X, X < (16#0039+1) -> true;
+is_digit_3(X) when 16#06F0 =< X, X < (16#06F9+1) -> true;
+is_digit_3(_) -> false.
+
+is_digit_4(X) when (16#0660-1) < X, X < (16#0669+1) -> true;
+is_digit_4(X) when (16#0030-1) < X, X < (16#0039+1) -> true;
+is_digit_4(X) when (16#06F0-1) < X, X < (16#06F9+1) -> true;
+is_digit_4(_) -> false.
+
+is_digit_5(X) when X >= 16#0660, X =< 16#0669 -> true;
+is_digit_5(X) when X >= 16#0030, X =< 16#0039 -> true;
+is_digit_5(X) when X >= 16#06F0, X =< 16#06F9 -> true;
+is_digit_5(_) -> false.
+
+is_digit_6(X) when X > (16#0660-1), X =< 16#0669 -> true;
+is_digit_6(X) when X > (16#0030-1), X =< 16#0039 -> true;
+is_digit_6(X) when X > (16#06F0-1), X =< 16#06F9 -> true;
+is_digit_6(_) -> false.
+
+is_digit_7(X) when 16#0660 =< X, X =< 16#0669 -> true;
+is_digit_7(X) when 16#0030 =< X, X =< 16#003A, X =/= 16#003A -> true;
+is_digit_7(X) when 16#06F0 =< X, X =< 16#06F9 -> true;
+is_digit_7(_) -> false.
+
+is_digit_8(X) when X =< 16#0039, X > (16#0030-1) -> true;
+is_digit_8(X) when X =< 16#06F9, X > (16#06F0-1) -> true;
+is_digit_8(X) when X =< 16#0669, X > (16#0660-1) -> true;
+is_digit_8(16#0670) -> false;
+is_digit_8(_) -> false.
+
+rel_op_combinations_2(0, _) ->
+ ok;
+rel_op_combinations_2(N, Range) ->
+ Bool = gb_sets:is_member(N, Range),
+ Bool = broken_range_1(N),
+ Bool = broken_range_2(N),
+ Bool = broken_range_3(N),
+ Bool = broken_range_4(N),
+ Bool = broken_range_5(N),
+ Bool = broken_range_6(N),
+ Bool = broken_range_7(N),
+ Bool = broken_range_8(N),
+ Bool = broken_range_9(N),
+ Bool = broken_range_10(N),
+ Bool = broken_range_11(N),
+ Bool = broken_range_12(N),
+ Bool = broken_range_13(N),
+ rel_op_combinations_2(N-1, Range).
+
+broken_range_1(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_1(X) when X >= 3, X =< 5 -> true;
+broken_range_1(_) -> false.
+
+broken_range_2(X) when X >= 10, X =< 12 -> true;
+broken_range_2(X) when X >= 14, X =< 20 -> true;
+broken_range_2(X) when X >= 3, X =< 5 -> true;
+broken_range_2(_) -> false.
+
+broken_range_3(X) when X >= 10, X =< 12 -> true;
+broken_range_3(X) when X >= 14, X < 21 -> true;
+broken_range_3(3) -> true;
+broken_range_3(4) -> true;
+broken_range_3(5) -> true;
+broken_range_3(_) -> false.
+
+broken_range_4(X) when X =< 5, X >= 3 -> true;
+broken_range_4(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_4(X) when X =< 100 -> false;
+broken_range_4(_) -> false.
+
+broken_range_5(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_5(X) when X > 2, X =< 5 -> true;
+broken_range_5(_) -> false.
+
+broken_range_6(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_6(X) when X > 2, X < 6 -> true;
+broken_range_6(_) -> false.
+
+broken_range_7(X) when X > 2, X < 6 -> true;
+broken_range_7(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_7(X) when X > 30 -> false;
+broken_range_7(_) -> false.
+
+broken_range_8(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_8(X) when X =:= 3 -> true;
+broken_range_8(X) when X >= 3, X =< 5 -> true;
+broken_range_8(_) -> false.
+
+broken_range_9(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_9(X) when X =:= 13 -> false;
+broken_range_9(X) when X >= 3, X =< 5 -> true;
+broken_range_9(_) -> false.
+
+broken_range_10(X) when X >= 3, X =< 5 -> true;
+broken_range_10(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_10(X) when X =/= 13 -> false;
+broken_range_10(_) -> false.
+
+broken_range_11(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_11(X) when is_tuple(X), X =:= 10 -> true;
+broken_range_11(X) when X >= 3, X =< 5 -> true;
+broken_range_11(_) -> false.
+
+broken_range_12(X) when X >= 3, X =< 5 -> true;
+broken_range_12(X) when X >= 10, X =< 20, X =/= 13 -> true;
+broken_range_12(X) when X < 30, X > 20 -> false;
+broken_range_12(_) -> false.
+
+broken_range_13(X) when X >= 10, X =< 20, 13 =/= X -> true;
+broken_range_13(X) when X >= 3, X =< 5 -> true;
+broken_range_13(_) -> false.
+
+rel_op_combinations_3(0, _) ->
+ ok;
+rel_op_combinations_3(N, Red) ->
+ Val = case gb_trees:lookup(N, Red) of
+ none -> none;
+ {value,V} -> V
+ end,
+ Val = redundant_1(N),
+ Val = redundant_2(N),
+ Val = redundant_3(N),
+ Val = redundant_4(N),
+ Val = redundant_5(N),
+ Val = redundant_6(N),
+ Val = redundant_7(N),
+ Val = redundant_8(N),
+ Val = redundant_9(N),
+ Val = redundant_10(N),
+ Val = redundant_11(N),
+ rel_op_combinations_3(N-1, Red).
+
+redundant_1(X) when X >= 51, X =< 80 -> 5*X;
+redundant_1(X) when X < 51 -> 2*X;
+redundant_1(_) -> none.
+
+redundant_2(X) when X < 51 -> 2*X;
+redundant_2(X) when X >= 51, X =< 80 -> 5*X;
+redundant_2(_) -> none.
+
+redundant_3(X) when X < 51 -> 2*X;
+redundant_3(X) when X =< 80, X >= 51 -> 5*X;
+redundant_3(X) when X =/= 100 -> none;
+redundant_3(_) -> none.
+
+redundant_4(X) when X < 51 -> 2*X;
+redundant_4(X) when X =< 80, X > 50 -> 5*X;
+redundant_4(X) when X =/= 100 -> none;
+redundant_4(_) -> none.
+
+redundant_5(X) when X < 51 -> 2*X;
+redundant_5(X) when X > 50, X < 81 -> 5*X;
+redundant_5(X) when X =< 10 -> none;
+redundant_5(_) -> none.
+
+redundant_6(X) when X > 50, X =< 80 -> 5*X;
+redundant_6(X) when X < 51 -> 2*X;
+redundant_6(_) -> none.
+
+redundant_7(X) when is_integer(X), X >= 51, X =< 80 -> 5*X;
+redundant_7(X) when is_integer(X), X < 51 -> 2*X;
+redundant_7(_) -> none.
+
+redundant_8(X) when X >= 51, X =< 80 -> 5*X;
+redundant_8(X) when X < 51 -> 2*X;
+redundant_8(_) -> none.
+
+redundant_9(X) when X >= 51, X =< 80 -> 5*X;
+redundant_9(X) when X < 51 -> 2*X;
+redundant_9(90) -> none;
+redundant_9(X) when X =/= 90 -> none;
+redundant_9(_) -> none.
+
+redundant_10(X) when X >= 51, X =< 80 -> 5*X;
+redundant_10(X) when X < 51 -> 2*X;
+redundant_10(90) -> none;
+redundant_10(X) when X =:= 90 -> none;
+redundant_10(_) -> none.
+
+redundant_11(X) when X < 51 -> 2*X;
+redundant_11(X) when X =:= 10 -> 2*X;
+redundant_11(X) when X >= 51, X =< 80 -> 5*X;
+redundant_11(_) -> none.
%% Test type tests on literal values. (From emulator test suites.)
literal_type_tests(Config) when is_list(Config) ->
@@ -1136,10 +1375,11 @@ literal_type_tests_1(Config) ->
[{is_function,L1,L2} ||
L1 <- literals(), L2 <- literals()]),
?line Mod = literal_test,
- ?line Func = {function, 0, test, 0, [{clause,0,[],[],Tests}]},
- ?line Form = [{attribute,0,module,Mod},
- {attribute,0,compile,export_all},
- Func, {eof,0}],
+ Anno = erl_anno:new(0),
+ Func = {function, Anno, test, 0, [{clause,Anno,[],[],Tests}]},
+ Form = [{attribute,Anno,module,Mod},
+ {attribute,Anno,compile,export_all},
+ Func, {eof,Anno}],
%% Print generated code for inspection.
?line lists:foreach(fun (F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Form),
@@ -1174,7 +1414,8 @@ test(T, L) ->
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
- {match,0,{atom,0,Val},hd(E)}.
+ Anno = erl_anno:new(0),
+ {match,Anno,{atom,Anno,Val},hd(E)}.
test(T, L1, L2) ->
S0 = io_lib:format("begin io:format(\"~~p~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ", [T,L1,L2,T,L1,L2]),
@@ -1182,7 +1423,8 @@ test(T, L1, L2) ->
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
- {match,0,{atom,0,Val},hd(E)}.
+ Anno = erl_anno:new(0),
+ {match,Anno,{atom,Anno,Val},hd(E)}.
smoke_disasm(Config, Mod, Bin) ->
Priv = ?config(priv_dir, Config),
@@ -1377,6 +1619,8 @@ t_tuple_size(Config) when is_list(Config) ->
?line {ok,Mod,Code} = compile:file(File, [from_asm,binary]),
?line code:load_binary(Mod, File, Code),
?line 14 = Mod:t({1,2,3,4}),
+ _ = code:delete(Mod),
+ _ = code:purge(Mod),
ok.
@@ -1565,6 +1809,12 @@ bad_guards(Config) when is_list(Config) ->
fc(catch bad_guards_2(#{a=>0,b=>0}, [x])),
fc(catch bad_guards_2(not_a_map, [x])),
fc(catch bad_guards_2(42, [x])),
+
+ fc(catch bad_guards_3(#{a=>0,b=>0}, [])),
+ fc(catch bad_guards_3(#{a=>0,b=>0}, [x])),
+ fc(catch bad_guards_3(not_a_map, [x])),
+ fc(catch bad_guards_3(42, [x])),
+
ok.
%% beam_bool used to produce GC BIF instructions whose
@@ -1576,6 +1826,86 @@ bad_guards_1(X, [_]) when {{X}}, -X ->
bad_guards_2(M, [_]) when M#{a := 0, b => 0}, map_size(M) ->
ok.
+%% beam_type used to produce an GC BIF instruction whose Live operand
+%% included uninitialized registers.
+
+bad_guards_3(M, [_]) when is_map(M) andalso M#{a := 0, b => 0}, length(M) ->
+ ok.
+
+%% 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.
+
+%% Building maps in a guard in a 'catch' would crash v3_codegen.
+
+guard_in_catch(_Config) ->
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(#{}),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(#{a=>b}),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(atom),
+
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(#{}),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(#{a=>b}),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(atom),
+
+ {'EXIT',{if_clause,_}} = (catch do_guard_in_catch_map_3()),
+
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(42),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(<<1,2,3>>),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(atom),
+ {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(#{}),
+
+ ok.
+
+do_guard_in_catch_map_1(From) ->
+ catch
+ if
+ From#{[] => sufficient} ->
+ saint
+ end.
+
+do_guard_in_catch_map_2(From) ->
+ catch
+ if
+ From#{From => sufficient} ->
+ saint
+ end.
+
+do_guard_in_catch_map_3() ->
+ try
+ if [] -> solo end
+ catch
+ Friendly when Friendly#{0 => []} -> minutes
+ after
+ membership
+ end.
+
+do_guard_in_catch_bin(From) ->
+ %% Would not crash v3_codegen, but there would be an unnecessary
+ %% 'move' to a Y register.
+ catch
+ if
+ <<From:32>> ->
+ saint
+ end.
+
+
%% Call this function to turn off constant propagation.
id(I) -> I.
diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl
index 47851e680b..0b92a784de 100644
--- a/lib/compiler/test/inline_SUITE.erl
+++ b/lib/compiler/test/inline_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/attribute.erl b/lib/compiler/test/inline_SUITE_data/attribute.erl
index 961086a888..08ef230c47 100644
--- a/lib/compiler/test/inline_SUITE_data/attribute.erl
+++ b/lib/compiler/test/inline_SUITE_data/attribute.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/bsdecode.erl b/lib/compiler/test/inline_SUITE_data/bsdecode.erl
index ae134ad02e..e72d5ec73d 100644
--- a/lib/compiler/test/inline_SUITE_data/bsdecode.erl
+++ b/lib/compiler/test/inline_SUITE_data/bsdecode.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/bsdes.erl b/lib/compiler/test/inline_SUITE_data/bsdes.erl
index 8d2d1a8287..a9717219d1 100644
--- a/lib/compiler/test/inline_SUITE_data/bsdes.erl
+++ b/lib/compiler/test/inline_SUITE_data/bsdes.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/decode1.erl b/lib/compiler/test/inline_SUITE_data/decode1.erl
index 9b4fc071a3..e89b5305a5 100644
--- a/lib/compiler/test/inline_SUITE_data/decode1.erl
+++ b/lib/compiler/test/inline_SUITE_data/decode1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/fname.erl b/lib/compiler/test/inline_SUITE_data/fname.erl
index 7ad4446bf3..90da1d17ac 100644
--- a/lib/compiler/test/inline_SUITE_data/fname.erl
+++ b/lib/compiler/test/inline_SUITE_data/fname.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/itracer.erl b/lib/compiler/test/inline_SUITE_data/itracer.erl
index 93f24e9bb1..66122e33b5 100644
--- a/lib/compiler/test/inline_SUITE_data/itracer.erl
+++ b/lib/compiler/test/inline_SUITE_data/itracer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/inline_SUITE_data/maps_inline_test.erl b/lib/compiler/test/inline_SUITE_data/maps_inline_test.erl
index d9762e2647..83ac8b2084 100644
--- a/lib/compiler/test/inline_SUITE_data/maps_inline_test.erl
+++ b/lib/compiler/test/inline_SUITE_data/maps_inline_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl
index 398398a397..d10839ccf2 100644
--- a/lib/compiler/test/lc_SUITE.erl
+++ b/lib/compiler/test/lc_SUITE.erl
@@ -3,27 +3,28 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(lc_SUITE).
--author('[email protected]').
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
basic/1,deeply_nested/1,no_generator/1,
- empty_generator/1,no_export/1]).
+ empty_generator/1,no_export/1,shadow/1,
+ effect/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -31,10 +32,18 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [basic, deeply_nested, no_generator, empty_generator, no_export].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [basic,
+ deeply_nested,
+ no_generator,
+ empty_generator,
+ no_export,
+ shadow,
+ effect
+ ]}].
init_per_suite(Config) ->
Config.
@@ -59,34 +68,34 @@ end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
ok.
basic(Config) when is_list(Config) ->
- ?line L0 = lists:seq(1, 10),
- ?line L1 = my_map(fun(X) -> {x,X} end, L0),
- ?line L1 = [{x,X} || X <- L0],
- ?line L0 = my_map(fun({x,X}) -> X end, L1),
- ?line [1,2,3,4,5] = [X || X <- L0, X < 6],
- ?line [4,5,6] = [X || X <- L0, X > 3, X < 7],
- ?line [] = [X || X <- L0, X > 32, X < 7],
- ?line [1,3,5,7,9] = [X || X <- L0, odd(X)],
- ?line [2,4,6,8,10] = [X || X <- L0, not odd(X)],
- ?line [1,3,5,9] = [X || X <- L0, odd(X), X =/= 7],
- ?line [2,4,8,10] = [X || X <- L0, not odd(X), X =/= 6],
+ L0 = lists:seq(1, 10),
+ L1 = my_map(fun(X) -> {x,X} end, L0),
+ L1 = [{x,X} || X <- L0],
+ L0 = my_map(fun({x,X}) -> X end, L1),
+ [1,2,3,4,5] = [X || X <- L0, X < 6],
+ [4,5,6] = [X || X <- L0, X > 3, X < 7],
+ [] = [X || X <- L0, X > 32, X < 7],
+ [1,3,5,7,9] = [X || X <- L0, odd(X)],
+ [2,4,6,8,10] = [X || X <- L0, not odd(X)],
+ [1,3,5,9] = [X || X <- L0, odd(X), X =/= 7],
+ [2,4,8,10] = [X || X <- L0, not odd(X), X =/= 6],
%% Append is specially handled.
- ?line [1,3,5,9,2,4,8,10] = [X || X <- L0, odd(X), X =/= 7] ++
+ [1,3,5,9,2,4,8,10] = [X || X <- L0, odd(X), X =/= 7] ++
[X || X <- L0, not odd(X), X =/= 6],
%% Guards BIFs are evaluated in guard context. Weird, but true.
- ?line [{a,b,true},{x,y,true,true}] = [X || X <- tuple_list(), element(3, X)],
+ [{a,b,true},{x,y,true,true}] = [X || X <- tuple_list(), element(3, X)],
%% Filter expressions with andalso/orelse.
- ?line "abc123" = alphanum("?abc123.;"),
+ "abc123" = alphanum("?abc123.;"),
%% Error cases.
- ?line [] = [{xx,X} || X <- L0, element(2, X) == no_no_no],
- ?line {'EXIT',_} = (catch [X || X <- L1, list_to_atom(X) == dum]),
- ?line [] = [X || X <- L1, X+1 < 2],
- ?line {'EXIT',_} = (catch [X || X <- L1, odd(X)]),
- ?line fc([x], catch [E || E <- id(x)]),
+ [] = [{xx,X} || X <- L0, element(2, X) == no_no_no],
+ {'EXIT',_} = (catch [X || X <- L1, list_to_atom(X) == dum]),
+ [] = [X || X <- L1, X+1 < 2],
+ {'EXIT',_} = (catch [X || X <- L1, odd(X)]),
+ fc([x], catch [E || E <- id(x)]),
ok.
tuple_list() ->
@@ -116,12 +125,12 @@ deeply_nested_1() ->
X16 <- [4],X17 <- [3],X18 <- [fun() -> X16+X17 end],X19 <- [2],X20 <- [1]].
no_generator(Config) when is_list(Config) ->
- ?line Seq = lists:seq(-10, 17),
- ?line [no_gen_verify(no_gen(A, B), A, B) || A <- Seq, B <- Seq],
+ Seq = lists:seq(-10, 17),
+ [no_gen_verify(no_gen(A, B), A, B) || A <- Seq, B <- Seq],
%% Literal expression, for coverage.
- ?line [a] = [a || true],
- ?line [a,b,c] = [a || true] ++ [b,c],
+ [a] = [a || true],
+ [a,b,c] = [a || true] ++ [b,c],
ok.
no_gen(A, B) ->
@@ -174,13 +183,51 @@ no_gen_eval(Fun, Res) ->
no_gen_one_more(A, B) -> A + 1 =:= B.
empty_generator(Config) when is_list(Config) ->
- ?line [] = [X || {X} <- [], (false or (X/0 > 3))],
+ [] = [X || {X} <- [], (false or (X/0 > 3))],
ok.
no_export(Config) when is_list(Config) ->
[] = [ _X = a || false ] ++ [ _X = a || false ],
ok.
+%% Test that variables in list comprehensions are
+%% correctly shadowed.
+
+shadow(Config) when is_list(Config) ->
+ Shadowed = nomatch,
+ _ = id(Shadowed), %Eliminate warning.
+ L = [{Shadowed,Shadowed+1} || Shadowed <- lists:seq(7, 9)],
+ [{7,8},{8,9},{9,10}] = id(L),
+ [8,9] = id([Shadowed || {_,Shadowed} <- id(L),
+ Shadowed < 10]),
+ ok.
+
+effect(Config) when is_list(Config) ->
+ [{42,{a,b,c}}] =
+ do_effect(fun(F, L) ->
+ [F({V1,V2}) ||
+ #{<<1:500>>:=V1,<<2:301>>:=V2} <- L],
+ ok
+ end, id([#{},x,#{<<1:500>>=>42,<<2:301>>=>{a,b,c}}])),
+
+ %% Will trigger the time-trap timeout if not tail-recursive.
+ case ?MODULE of
+ lc_SUITE ->
+ _ = [{'EXIT',{badarg,_}} =
+ (catch binary_to_atom(<<C/utf8>>, utf8)) ||
+ C <- lists:seq(16#10000, 16#FFFFF)];
+ _ ->
+ ok
+ end,
+
+ ok.
+
+do_effect(Lc, L) ->
+ put(?MODULE, []),
+ F = fun(V) -> put(?MODULE, [V|get(?MODULE)]) end,
+ ok = Lc(F, L),
+ lists:reverse(erase(?MODULE)).
+
id(I) -> I.
fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Args,_}|_]}}) -> ok;
diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl
index 403b7e8405..cff3b5deb4 100644
--- a/lib/compiler/test/map_SUITE.erl
+++ b/lib/compiler/test/map_SUITE.erl
@@ -2,16 +2,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -21,16 +22,32 @@
]).
-export([
- t_build_and_match_literals/1,
- t_update_literals/1,t_match_and_update_literals/1,
+ %% literals
+ t_build_and_match_literals/1, t_build_and_match_literals_large/1,
+ t_update_literals/1, t_update_literals_large/1,
+ t_match_and_update_literals/1, t_match_and_update_literals_large/1,
t_update_map_expressions/1,
- t_update_assoc/1,t_update_exact/1,
- t_guard_bifs/1, t_guard_sequence/1, t_guard_update/1,
- t_guard_receive/1, t_guard_fun/1,
+ t_update_assoc/1, t_update_assoc_large/1,
+ t_update_exact/1, t_update_exact_large/1,
+ t_guard_bifs/1,
+ t_guard_sequence/1, t_guard_sequence_large/1,
+ t_guard_update/1, t_guard_update_large/1,
+ t_guard_receive/1, t_guard_receive_large/1,
+ t_guard_fun/1,
t_list_comprehension/1,
t_map_sort_literals/1,
t_map_size/1,
t_build_and_match_aliasing/1,
+ t_is_map/1,
+
+ %% variables
+ t_build_and_match_variables/1,
+ t_update_assoc_variables/1,t_update_exact_variables/1,
+ t_nested_pattern_expressions/1,
+ t_guard_update_variables/1,
+ t_guard_sequence_variables/1,
+ t_guard_sequence_mixed/1,
+ t_frequency_table/1,
%% warnings
t_warn_useless_build/1,
@@ -46,21 +63,42 @@
%% errors in 17.0-rc1
t_update_values/1,
t_expand_map_update/1,
- t_export/1
+ t_export/1,
+
+ %% errors in 18
+ t_register_corruption/1
]).
suite() -> [].
-all() -> [
- t_build_and_match_literals,
- t_update_literals, t_match_and_update_literals,
+all() ->
+ test_lib:recompile(?MODULE),
+ [
+ %% literals
+ t_build_and_match_literals, t_build_and_match_literals_large,
+ t_update_literals, t_update_literals_large,
+ t_match_and_update_literals, t_match_and_update_literals_large,
t_update_map_expressions,
- t_update_assoc,t_update_exact,
- t_guard_bifs, t_guard_sequence, t_guard_update,
- t_guard_receive,t_guard_fun, t_list_comprehension,
+ t_update_assoc, t_update_assoc_large,
+ t_update_exact, t_update_exact_large,
+ t_guard_bifs,
+ t_guard_sequence, t_guard_sequence_large,
+ t_guard_update, t_guard_update_large,
+ t_guard_receive, t_guard_receive_large,
+ t_guard_fun, t_list_comprehension,
t_map_sort_literals,
t_map_size,
t_build_and_match_aliasing,
+ t_is_map,
+
+ %% variables
+ t_build_and_match_variables,
+ t_update_assoc_variables,t_update_exact_variables,
+ t_nested_pattern_expressions,
+ t_guard_update_variables,
+ t_guard_sequence_variables,
+ t_guard_sequence_mixed,
+ t_frequency_table,
%% warnings
t_warn_useless_build,
@@ -76,7 +114,10 @@ all() -> [
%% errors in 17.0-rc1
t_update_values,
t_expand_map_update,
- t_export
+ t_export,
+
+ %% errors in 18
+ t_register_corruption
].
groups() -> [].
@@ -119,6 +160,11 @@ t_build_and_match_literals(Config) when is_list(Config) ->
%% nil key
#{[]:=ok,1:=2} = id(#{[]=>ok,1=>2}),
+ #{1:=2,[]:=ok,1:=2} = id(#{[]=>ok,1=>2}),
+
+ %% pseudo literals
+ #{ -3 := yep } = id(#{ -3 => yep }),
+ #{ <<0:358>> := "three" } = id(#{<<0:358>> =>"three"}),
%% error case
{'EXIT',{{badmatch,_},_}} = (catch (#{x:=3,x:=2} = id(#{x=>3}))),
@@ -126,10 +172,465 @@ t_build_and_match_literals(Config) when is_list(Config) ->
{'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = id({a,b,c}))),
{'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = id(#{y=>3}))),
{'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = id(#{x=>"three"}))),
- {'EXIT',{badarg,_}} = (catch id(#{<<0:258>> =>"three"})),
{'EXIT',{{badmatch,_},_}} = (catch (#{#{"a"=>42} := 3}=id(#{#{"a"=>3}=>42}))),
ok.
+t_build_and_match_literals_large(Config) when is_list(Config) ->
+ % normal non-repeating
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M0,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M0,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M0,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M0,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M0,
+
+ 60 = map_size(M0),
+ 60 = maps:size(M0),
+
+ % with repeating
+ M1 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 10=>na0,20=>nb0,30=>"nc0","40"=>"nd0",<<"50">>=>"ne0",{["00"]}=>"n10",
+ 11=>na1,21=>nb1,31=>"nc1","41"=>"nd1",<<"51">>=>"ne1",{["01"]}=>"n11",
+ 12=>na2,22=>nb2,32=>"nc2","42"=>"nd2",<<"52">>=>"ne2",{["02"]}=>"n12",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+
+ 13=>na3,23=>nb3,33=>"nc3","43"=>"nd3",<<"53">>=>"ne3",{["03"]}=>"n13",
+ 14=>na4,24=>nb4,34=>"nc4","44"=>"nd4",<<"54">>=>"ne4",{["04"]}=>"n14",
+
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }),
+
+ #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1,
+ #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1,
+ #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1,
+ #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1,
+ #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1,
+
+ 60 = map_size(M1),
+ 60 = maps:size(M1),
+
+ % with floats
+
+ M2 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9"}),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ 90 = map_size(M2),
+ 90 = maps:size(M2),
+
+ % with bignums
+ M3 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ 36893488147419103232=>big1, 73786976294838206464=>big2,
+ 147573952589676412928=>big3, 18446744073709551616=>big4,
+ 4294967296=>big5, 8589934592=>big6,
+ 4294967295=>big7, 67108863=>big8
+ }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+
+ 98 = map_size(M3),
+ 98 = maps:size(M3),
+
+ %% with maps
+
+ M4 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M4,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M4,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M4,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M4,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M4,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M4,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M4,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M4,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M4,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M4,
+
+ #{ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := "small map key 2",
+ #{ third => small, map => key } := "small map key 3" } = M4,
+
+ #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M4,
+
+
+ #{ 15:=V1,25:=b5,35:=V2,"45":="d5",<<"55">>:=V3,{["05"]}:="15",
+ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := V4,
+ #{ third => small, map => key } := "small map key 3",
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := V5 } = M4,
+
+ a5 = V1,
+ "c5" = V2,
+ "e5" = V3,
+ "small map key 2" = V4,
+ "large map key 1" = V5,
+
+ 95 = map_size(M4),
+ 95 = maps:size(M4),
+
+ % call for value
+
+ M5 = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ #{ one => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M5,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M5,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M5,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M5,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M5,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M5,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M5,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M5,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M5,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M5,
+
+ #{ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := "small map key 2",
+ #{ third => small, map => key } := "small map key 3" } = M5,
+
+ #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M5,
+
+ 95 = map_size(M5),
+ 95 = maps:size(M5),
+
+ %% remember
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0,
+
+ #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1,
+ #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1,
+ #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1,
+ #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1,
+ #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+
+ ok.
+
+
t_build_and_match_aliasing(Config) when is_list(Config) ->
M1 = id(#{a=>1,b=>2,c=>3,d=>4}),
#{c:=C1=_=_=C2} = M1,
@@ -143,6 +644,19 @@ t_build_and_match_aliasing(Config) when is_list(Config) ->
M2 = id(#{"a"=>1,"b"=>2,"c"=>3,"d"=>4}),
#{"a":=A2,"a":=A2,"a":=A2,"b":=B2,"b":=B2,"b":=2} = M2,
#{"a":=_,"a":=_,"a":=_,"b":=_,"b":=_,"b":=2} = M2,
+
+ #{a:=A1,a:=A1,a:=A1,b:=B1,b:=B1} = #{a:=A1,a:=A1,a:=A1,b:=B1,b:=B1,b:=2} = M1,
+ #{"a":=A3,"b":=B3} = #{"a":=A3,"a":=A3} = #{"b":=B3,"b":=2} = M2,
+
+ #{"a":=1,"b":=2,"c":=3,"d":=4} = #{"a":=A4,"b":=B4} = #{"a":=A4,"a":=A4} = #{"b":=B4,"d":=4} = M2,
+ #{"a":=A5,"b":=B5} = #{"a":=A5,"a":=A5} = #{"b":=B5,"d":=4} = #{"a":=1,"b":=2,"c":=3,"d":=4} = M2,
+ #{"a":=_,"b":=_} = #{"a":=_,"a":=_} = #{"b":=_,"d":=4} = #{"a":=1,"b":=2,"c":=3,"d":=4} = M2,
+
+ M3 = id(#{<<12:300>>=>1,<<13:300>>=>2}),
+ #{<<12:300>> := V1, <<13:300>> := V2} = #{<<13:300>> := V2, <<12:300>> := V1} = M3,
+ #{<<12:300>> := 1, <<13:300>> := 2} = #{<<13:300>> := _, <<12:300>> := _} = M3,
+ #{<<13:300>> := _, <<12:300>> := _} = #{<<12:300>> := 1, <<13:300>> := 2} = M3,
+
ok.
t_map_size(Config) when is_list(Config) ->
@@ -161,14 +675,25 @@ t_map_size(Config) when is_list(Config) ->
false = map_is_size(M#{ "c" => 2}, 2),
%% Error cases.
- {'EXIT',{badarg,_}} = (catch map_size([])),
- {'EXIT',{badarg,_}} = (catch map_size(<<1,2,3>>)),
- {'EXIT',{badarg,_}} = (catch map_size(1)),
+ {'EXIT',{{badmap,[]},_}} = (catch map_size([])),
+ {'EXIT',{{badmap,<<1,2,3>>},_}} = (catch map_size(<<1,2,3>>)),
+ {'EXIT',{{badmap,1},_}} = (catch map_size(1)),
ok.
map_is_size(M,N) when map_size(M) =:= N -> true;
map_is_size(_,_) -> false.
+t_is_map(Config) when is_list(Config) ->
+ true = is_map(#{}),
+ true = is_map(#{a=>1}),
+ false = is_map({a,b}),
+ false = is_map(x),
+ if is_map(#{}) -> ok end,
+ if is_map(#{b=>1}) -> ok end,
+ if not is_map([1,2,3]) -> ok end,
+ if not is_map(x) -> ok end,
+ ok.
+
% test map updates without matching
t_update_literals(Config) when is_list(Config) ->
Map = #{x=>1,y=>2,z=>3,q=>4},
@@ -177,13 +702,75 @@ t_update_literals(Config) when is_list(Config) ->
]),
ok.
+t_update_literals_large(Config) when is_list(Config) ->
+ Map = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ #{ one => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{x:="d",q:="4"} = loop_update_literals_x_q(Map, [
+ {"a","1"},{"b","2"},{"c","3"},{"d","4"}
+ ]),
+ ok.
+
+
+
loop_update_literals_x_q(Map, []) -> Map;
loop_update_literals_x_q(Map, [{X,Q}|Vs]) ->
loop_update_literals_x_q(Map#{q=>Q,x=>X},Vs).
% test map updates with matching
t_match_and_update_literals(Config) when is_list(Config) ->
- Map = #{x=>0,y=>"untouched",z=>"also untouched",q=>1},
+ Map = #{ x=>0,y=>"untouched",z=>"also untouched",q=>1,
+ #{ "one" => small, map => key } => "small map key 1" },
+
#{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [
{1,2},{3,4},{5,6},{7,8}
]),
@@ -197,8 +784,77 @@ t_match_and_update_literals(Config) when is_list(Config) ->
#{ 4 := another_number, int := 3 } = M2#{ 4 => another_number },
ok.
+t_match_and_update_literals_large(Config) when is_list(Config) ->
+ Map = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ x=>0,y=>"untouched",z=>"also untouched",q=>1,
+
+ #{ "one" => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [
+ {1,2},{3,4},{5,6},{7,8}
+ ]),
+ M0 = id(Map#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat}),
+ M1 = id(Map#{}),
+ M2 = M1#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat},
+ M0 = M2,
+
+ #{ 4 := another_number, int := 3 } = M2#{ 4 => another_number },
+ ok.
+
loop_match_and_update_literals_x_q(Map, []) -> Map;
-loop_match_and_update_literals_x_q(#{q:=Q0,x:=X0} = Map, [{X,Q}|Vs]) ->
+loop_match_and_update_literals_x_q(#{ q:=Q0, x:=X0,
+ #{ "one" => small, map => key } := "small map key 1" } = Map, [{X,Q}|Vs]) ->
loop_match_and_update_literals_x_q(Map#{q=>Q0+Q,x=>X0+X},Vs).
@@ -224,9 +880,12 @@ t_update_map_expressions(Config) when is_list(Config) ->
#{ "a" := b } = F(),
- %% Error cases, FIXME: should be 'badmap'?
- {'EXIT',{badarg,_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
- {'EXIT',{badarg,_}} = (catch (id([]))#{ a := 42, b => 2 }),
+ %% Error cases.
+ {'EXIT',{{badmap,<<>>},_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
+ {'EXIT',{{badmap,[]},_}} = (catch (id([]))#{ a := 42, b => 2 }),
+ {'EXIT',{{badmap,_},_}} =
+ (catch (fun t_update_map_expressions/1)#{u => 42}),
+
ok.
@@ -241,13 +900,92 @@ t_update_assoc(Config) when is_list(Config) ->
#{1:=a,2:=b,3.0:=new,4:=d,5:=e} = M2,
M2 = M0#{3.0:=wrong,3.0=>new},
+ % Can't handle directly yet
+ Bin = <<0:257>>,
+ #{ Bin := val } = id(M0#{<<0:257>> => val}), %% binary limitation
+
%% Errors cases.
BadMap = id(badmap),
- {'EXIT',{badarg,_}} = (catch BadMap#{nonexisting=>val}),
- {'EXIT',{badarg,_}} = (catch <<>>#{nonexisting=>val}),
- {'EXIT',{badarg,_}} = (catch M0#{<<0:257>> => val}), %% limitation
+ {'EXIT',{{badmap,BadMap},_}} = (catch BadMap#{nonexisting=>val}),
+ {'EXIT',{{badmap,<<>>},_}} = (catch <<>>#{nonexisting=>val}),
+
+ %% Evaluation order.
+ {'EXIT',{blurf,_}} =
+ (catch BadMap#{whatever=>id(error(blurf))}),
+ {'EXIT',{blurf,_}} =
+ (catch BadMap#{id(error(blurf))=>whatever}),
ok.
+t_update_assoc_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ M1 = M0#{1=>42,2=>100,4=>[a,b,c]},
+ #{1:=42,2:=100,10.0:=fa0,4:=[a,b,c],25:=b5} = M1,
+ #{ 10:=43, 24:=b4, 15:=a5, 35:="c5", 2.0:=100, 13.0:=fa3, 4.0:=[a,b,c]} =
+ M0#{1.0=>float,10:=43,2.0=>wrong,2.0=>100,4.0=>[a,b,c]},
+
+ M2 = M0#{13.0=>new},
+ #{10:=a0,20:=b0,13.0:=new,"40":="d0",<<"50">>:="e0"} = M2,
+ M2 = M0#{13.0:=wrong,13.0=>new},
+
+ %% Errors cases.
+ BadMap = id({no,map}),
+ {'EXIT',{{badmap,BadMap},_}} = (catch BadMap#{nonexisting=>M0}),
+ ok.
+
+
+
t_update_exact(Config) when is_list(Config) ->
M0 = id(#{1=>a,2=>b,3.0=>c,4=>d,5=>e}),
@@ -268,21 +1006,121 @@ t_update_exact(Config) when is_list(Config) ->
1.0 => new_val4 },
%% Errors cases.
- {'EXIT',{badarg,_}} = (catch ((id(nil))#{ a := b })),
- {'EXIT',{badarg,_}} = (catch M0#{nonexisting:=val}),
- {'EXIT',{badarg,_}} = (catch M0#{1.0:=v,1.0=>v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42.0:=v,42:=v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
- {'EXIT',{badarg,_}} = (catch <<>>#{nonexisting:=val}),
- {'EXIT',{badarg,_}} = (catch M0#{<<0:257>> := val}), %% limitation
+ {'EXIT',{{badmap,nil},_}} = (catch ((id(nil))#{ a := b })),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ {'EXIT',{{badmap,<<>>},_}} = (catch <<>>#{nonexisting:=val}),
+ {'EXIT',{{badkey,<<0:257>>},_}} =
+ (catch M0#{<<0:257>> := val}), %limitation
+
+ %% A workaround for a bug allowed an empty map to be updated.
+ {'EXIT',{{badkey,a},_}} = (catch (id(#{}))#{a:=1}),
+ {'EXIT',{{badkey,a},_}} = (catch #{}#{a:=1}),
+ Empty = #{},
+ {'EXIT',{{badkey,a},_}} = (catch Empty#{a:=1}),
+
+ %% Evaluation order.
+ BadMap = id([no,map]),
+ {'EXIT',{blurf,_}} =
+ (catch BadMap#{whatever:=id(error(blurf))}),
+ {'EXIT',{blurf,_}} =
+ (catch BadMap#{id(error(blurf)):=whatever}),
+ {'EXIT',{{badmap,BadMap},_}} =
+ (catch BadMap#{id(nonexisting):=whatever}),
+ ok.
+
+t_update_exact_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ M1 = M0#{10:=42,<<"55">>:=100,10.0:=[a,b,c]},
+ #{ 10:=42,<<"55">>:=100,{["05"]}:="15",10.0:=[a,b,c],
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1" } = M1,
+
+ M1 = M0#{10:=wrong,10=>42,<<"55">>=>wrong,<<"55">>:=100,10.0:=[a,b,c]},
+
+ M2 = M0#{13.0:=new},
+ #{10:=a0,20:=b0,13.0:=new} = M2,
+ M2 = M0#{13.0=>wrong,13.0:=new},
+
+ %% Errors cases.
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+
ok.
t_update_values(Config) when is_list(Config) ->
V0 = id(1337),
M0 = #{ a => 1, val => V0},
V1 = get_val(M0),
- M1 = M0#{ val := [V0,V1], "wazzup" => 42 },
+ M1 = id(M0#{ val := [V0,V1], "wazzup" => 42 }),
[1337, {some_val, 1337}] = get_val(M1),
+ M2 = id(M1#{ <<42:333>> => 1337 }),
+ {bin_key,1337} = get_val(M2),
N = 110,
List = [{[I,1,2,3,I],{1,2,3,"wat",I}}|| I <- lists:seq(1,N)],
@@ -308,6 +1146,7 @@ t_export(Config) when is_list(Config) ->
check_val(#{val1:=V1, val2:=V2},V1,V2) -> ok.
+get_val(#{ <<42:333>> := V }) -> {bin_key, V};
get_val(#{ "wazzup" := _, val := V}) -> V;
get_val(#{ val := V }) -> {some_val, V}.
@@ -358,6 +1197,75 @@ t_guard_sequence(Config) when is_list(Config) ->
{'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(#{b=>5})),
ok.
+t_guard_sequence_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+ {1, "a"} = map_guard_sequence_1(M0#{seq=>1,val=>id("a")}),
+ {2, "b"} = map_guard_sequence_1(M0#{seq=>2,val=>id("b")}),
+ {3, "c"} = map_guard_sequence_1(M0#{seq=>3,val=>id("c")}),
+ {4, "d"} = map_guard_sequence_1(M0#{seq=>4,val=>id("d")}),
+ {5, "e"} = map_guard_sequence_1(M0#{seq=>5,val=>id("e")}),
+
+ {1,M1} = map_guard_sequence_2(M1 = id(M0#{a=>3})),
+ {2,M2} = map_guard_sequence_2(M2 = id(M0#{a=>4, b=>4})),
+ {3,gg,M3} = map_guard_sequence_2(M3 = id(M0#{a=>gg, b=>4})),
+ {4,sc,sc,M4} = map_guard_sequence_2(M4 = id(M0#{a=>sc, b=>3, c=>sc2})),
+ {5,kk,kk,M5} = map_guard_sequence_2(M5 = id(M0#{a=>kk, b=>other, c=>sc2})),
+
+ {'EXIT',{function_clause,_}} = (catch map_guard_sequence_1(M0#{seq=>6,val=>id("e")})),
+ {'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(M0#{b=>5})),
+ ok.
+
map_guard_sequence_1(#{seq:=1=Seq, val:=Val}) -> {Seq,Val};
map_guard_sequence_1(#{seq:=2=Seq, val:=Val}) -> {Seq,Val};
map_guard_sequence_1(#{seq:=3=Seq, val:=Val}) -> {Seq,Val};
@@ -378,6 +1286,65 @@ t_guard_update(Config) when is_list(Config) ->
third = map_guard_update(#{x=>old,y=>old}, #{x=>third,y=>old}),
ok.
+t_guard_update_large(Config) when is_list(Config) ->
+ M0 = id(#{ 70=>a0,80=>b0,90=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10",
+ 71=>a1,81=>b1,91=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11",
+ 72=>a2,82=>b2,92=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12",
+ 73=>a3,83=>b3,93=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13",
+ 74=>a4,84=>b4,94=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14",
+
+ 75=>a5,85=>b5,95=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15",
+ 76=>a6,86=>b6,96=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16",
+ 77=>a7,87=>b7,97=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17",
+ 78=>a8,88=>b8,98=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18",
+ 79=>a9,89=>b9,99=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19",
+
+ 70.0=>fa0,80.0=>fb0,90.0=>"fc0",
+ 71.0=>fa1,81.0=>fb1,91.0=>"fc1",
+ 72.0=>fa2,82.0=>fb2,92.0=>"fc2",
+ 73.0=>fa3,83.0=>fb3,93.0=>"fc3",
+ 74.0=>fa4,84.0=>fb4,94.0=>"fc4",
+
+ 75.0=>fa5,85.0=>fb5,95.0=>"fc5",
+ 76.0=>fa6,86.0=>fb6,96.0=>"fc6",
+ 77.0=>fa7,87.0=>fb7,97.0=>"fc7",
+ 78.0=>fa8,88.0=>fb8,98.0=>"fc8",
+ 79.0=>fa9,89.0=>fb9,99.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ error = map_guard_update(M0#{},M0#{}),
+ first = map_guard_update(M0#{},M0#{x=>first}),
+ second = map_guard_update(M0#{y=>old}, M0#{x=>second,y=>old}),
+ ok.
+
map_guard_update(M1, M2) when M1#{x=>first} =:= M2 -> first;
map_guard_update(M1, M2) when M1#{x=>second} =:= M2 -> second;
map_guard_update(M1, M2) when M1#{x:=third} =:= M2 -> third;
@@ -408,6 +1375,43 @@ t_guard_receive(Config) when is_list(Config) ->
done = call(Pid, done),
ok.
+-define(t_guard_receive_large_procs, 1500).
+
+t_guard_receive_large(Config) when is_list(Config) ->
+ M = lists:foldl(fun(_,#{procs := Ps } = M) ->
+ M#{ procs := Ps#{ spawn_link(fun() -> grecv_loop() end) => 0 }}
+ end, #{procs => #{}, done => 0}, lists:seq(1,?t_guard_receive_large_procs)),
+ lists:foreach(fun(Pid) ->
+ Pid ! {self(), hello}
+ end, maps:keys(maps:get(procs,M))),
+ ok = guard_receive_large_loop(M),
+ ok.
+
+guard_receive_large_loop(#{done := ?t_guard_receive_large_procs}) ->
+ ok;
+guard_receive_large_loop(M) ->
+ receive
+ #{pid := Pid, msg := hello} ->
+ case M of
+ #{done := Count, procs := #{Pid := 150}} ->
+ Pid ! {self(), done},
+ guard_receive_large_loop(M#{done := Count + 1});
+ #{procs := #{Pid := Count} = Ps} ->
+ Pid ! {self(), hello},
+ guard_receive_large_loop(M#{procs := Ps#{Pid := Count + 1}})
+ end
+ end.
+
+grecv_loop() ->
+ receive
+ {_, done} ->
+ ok;
+ {Pid, hello} ->
+ Pid ! #{pid=>self(), msg=>hello},
+ grecv_loop()
+ end.
+
+
call(Pid, M) ->
Pid ! {self(), M}, receive {Pid, Res} -> Res end.
@@ -437,7 +1441,15 @@ guard_receive_loop() ->
t_list_comprehension(Config) when is_list(Config) ->
- [#{k:=1},#{k:=2},#{k:=3}] = [#{k=>I} || I <- [1,2,3]],
+ [#{k:=1},#{k:=2},#{k:=3}] = id([#{k=>I} || I <- [1,2,3]]),
+ Ls = id([#{<<2:301>> => I, "wat" => I + 1} || I <- [1,2,3]]),
+ [#{<<2:301>>:=1,"wat":=2},#{<<2:301>>:=2,"wat":=3},#{<<2:301>>:=3,"wat":=4}] = Ls,
+ [{1,2},{2,3},{3,4}] = id([{I2,I1} || #{"wat" := I1, <<2:301>> := I2} <- Ls]),
+
+ Ks = lists:seq($a,$z),
+ Ms = [#{[K1,K2]=>{K1,K2}} || K1 <- Ks, K2 <- Ks],
+ [#{"aa" := {$a,$a}},#{"ab":={$a,$b}}|_] = Ms,
+ [#{"zz" := {$z,$z}},#{"zy":={$z,$y}}|_] = lists:reverse(Ms),
ok.
t_guard_fun(Config) when is_list(Config) ->
@@ -487,7 +1499,7 @@ t_map_sort_literals(Config) when is_list(Config) ->
true = id(#{ c => 1, b => 1, a => 1 }) < id(#{ b => 1, c => 1, d => 1}),
true = id(#{ "a" => 1 }) < id(#{ <<"a">> => 1}),
false = id(#{ <<"a">> => 1 }) < id(#{ "a" => 1}),
- false = id(#{ 1 => 1 }) < id(#{ 1.0 => 1}),
+ true = id(#{ 1 => 1 }) < id(#{ 1.0 => 1}),
false = id(#{ 1.0 => 1 }) < id(#{ 1 => 1}),
%% value order
@@ -585,6 +1597,7 @@ t_build_and_match_nil(Config) when is_list(Config) ->
"treat" => V2,
[] => V1 }),
#{ [] := V3, [] := V3 } = id(#{ [] => V1, [] => V3 }),
+ #{ <<1>> := V3, [] := V1 } = id(#{ [] => V1, <<1>> => V3 }),
ok.
t_build_and_match_structure(Config) when is_list(Config) ->
@@ -601,5 +1614,373 @@ t_build_and_match_structure(Config) when is_list(Config) ->
end,
ok.
+%% simple build and match variables
+t_build_and_match_variables(Config) when is_list(Config) ->
+ K0 = id(#{}),
+ K1 = id(1), V1 = id(a),
+ K2 = id(2), V2 = id(b),
+ K3 = id(3), V3 = id("c"),
+ K4 = id("4"), V4 = id("d"),
+ K5 = id(<<"5">>), V5 = id(<<"e">>),
+ K6 = id({"6",7}), V6 = id("f"),
+ K7 = id(#{ "a" => 3 }),
+ #{K1:=V1} = id(#{K1=>V1}),
+ #{K1:=V1,K2:=V2} = id(#{K1=>V1,K2=>V2}),
+ #{K1:=V1,K2:=V2,K3:=V3} = id(#{K1=>V1,K2=>V2,K3=>V3}),
+ #{K1:=V1,K2:=V2,K3:=V3,K4:=V4} = id(#{K1=>V1,K2=>V2,K3=>V3,K4=>V4}),
+ #{K1:=V1,K2:=V2,K3:=V3,K4:=V4,K5:=V5} = id(#{K1=>V1,K2=>V2,K3=>V3,K4=>V4,K5=>V5}),
+ #{K1:=V1,K2:=V2,K3:=V3,K4:=V4,K5:=V5,K6:=V6} = id(#{K1=>V1,K2=>V2,K3=>V3,K4=>V4,K5=>V5,K6=>V6}),
+
+ #{K5:=X,K5:=X=3,K4:=4} = id(#{K5=>3,K4=>4}),
+ #{K5:=X,<<"5">>:=X=3,K4:=4} = id(#{K5=>3,K4=>4}),
+ #{K5:=X,<<"5">>:=X=3,K4:=4} = id(#{<<"5">>=>3,K4=>4}),
+
+ #{ K4:=#{ K3:=#{K1:=V1, K2:=V2}}, K5:=V5} =
+ id(#{ K5=>V5, K4=>#{ K3=>#{K2 => V2, K1 => V1}}}),
+ #{ K4 := #{ K5 := Res }, K6 := Res} = id(#{K4=>#{K5 => 99}, K6 => 99}),
+
+ %% has keys
+ #{a :=_,b :=_,K1:=_,K2:=_,K3:=V3,K4:=ResKey,K4:=ResKey,"4":=ResKey,"4":="ok"} =
+ id(#{ a=>1, b=>1, K1=>V1, K2=>V2, K3=>V3, K4=>"nope", "4"=>"ok" }),
+
+ %% function
+ ok = match_function_map_neg_keys(#{ -1 => a, -2 => b, -3 => c }),
+
+ %% map key
+ #{ K0 := 42 } = id(#{ K0 => 42 }),
+ #{ K7 := 42 } = id(#{ K7 => 42 }),
+
+ %% nil key
+ KNIL = id([]),
+ #{KNIL:=ok,1:=2} = id(#{KNIL=>ok,1=>2}),
+
+ Bin = <<0:258>>,
+ #{ Bin := "three" } = id(#{<<0:258>> =>"three"}),
+
+ %% error case
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3,x:=2} = id(#{K5=>3}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=2} = id(#{K5=>3}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3} = id({a,b,c}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3} = id(#{K6=>3}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3} = id(K7))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K7:=3} = id(#{K7=>42}))),
+ ok.
+
+
+match_function_map_neg_keys(#{ -1 := a, -2 := b, -3 := c }) -> ok.
+
+t_update_assoc_variables(Config) when is_list(Config) ->
+ K1 = id(1),
+ K2 = id(2),
+ K3 = id(3.0),
+ K4 = id(4),
+ K5 = id(5),
+ K6 = id(2.0),
+
+ M0 = #{K1=>a,K2=>b,K3=>c,K4=>d,K5=>e},
+
+ M1 = M0#{K1=>42,K2=>100,K4=>[a,b,c]},
+ #{1:=42,2:=100,3.0:=c,4:=[a,b,c],5:=e} = M1,
+ #{1:=42,2:=b,4:=d,5:=e,2.0:=100,K3:=c,4.0:=[a,b,c]} = M0#{1.0=>float,1:=42,2.0=>wrong,K6=>100,4.0=>[a,b,c]},
+
+ M2 = M0#{K3=>new},
+ #{1:=a,2:=b,K3:=new,4:=d,5:=e} = M2,
+ M2 = M0#{3.0:=wrong,K3=>new},
+
+ #{ <<0:258>> := val } = id(M0#{<<0:258>> => val}), %% binary limitation
+
+ %% Errors cases.
+ BadMap = id(badmap),
+ {'EXIT',{{badmap,BadMap},_}} = (catch BadMap#{nonexisting=>val}),
+ {'EXIT',{{badmap,<<>>},_}} = (catch <<>>#{nonexisting=>val}),
+ ok.
+
+t_update_exact_variables(Config) when is_list(Config) ->
+ K1 = id(1),
+ K2 = id(2),
+ K3 = id(3.0),
+ K4 = id(4),
+
+ M0 = id(#{1=>a,2=>b,3.0=>c,4=>d,5=>e}),
+
+ M1 = M0#{K1:=42,K2:=100,K4:=[a,b,c]},
+ #{1:=42,2:=100,3.0:=c,K4:=[a,b,c],5:=e} = M1,
+ M1 = M0#{K1:=wrong,1:=also_wrong,K1=>42,2=>wrong,K2:=100,4:=[a,b,c]},
+
+ M2 = M0#{K3:=new},
+ #{1:=a,K2:=b,3.0:=new,K4:=d,5:=e} = M2,
+ M2 = M0#{3.0=>wrong,K3:=new},
+ true = M2 =/= M0#{3=>right,3.0:=new},
+ #{ 3 := right, 3.0 := new } = M0#{3=>right,K3:=new},
+
+ M3 = id(#{ 1 => val}),
+ #{1 := update2,1.0 := new_val4} = M3#{
+ 1.0 => new_val1, K1 := update, K1=> update3,
+ K1 := update2, 1.0 := new_val2, 1.0 => new_val3,
+ 1.0 => new_val4 },
+
+ #{ "wat" := 3, 2 := a } = id(#{ "wat" => 1, K2 => 2 }#{ K2 := a, "wat" := 3 }),
+
+ %% Errors cases.
+ {'EXIT',{{badmap,nil},_}} = (catch ((id(nil))#{ a := b })),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ {'EXIT',{{badmap,<<>>},_}} = (catch <<>>#{nonexisting:=val}),
+ {'EXIT',{{badkey,<<0:257>>},_}} =
+ (catch M0#{<<0:257>> := val}), %limitation
+ ok.
+
+t_nested_pattern_expressions(Config) when is_list(Config) ->
+ K1 = id("hello"),
+ %K2 = id({ok}),
+ [_,_,#{ <<"hi">> := wat, K1 := 42 }|_] = id([k,k,#{<<"hi">> => wat, K1 => 42}]),
+ [_,_,#{ -1 := wat, K1 := 42 }|_] = id([k,k,#{-1 => wat, K1 => 42}]),
+ [_,_,{#{ -1 := #{ {-3,<<0:300>>} := V1 }, K1 := 42 },3}|_] = id([k,k,{#{-1 => #{{-3,<<0:300>>}=>"hi"}, K1 => 42},3}]),
+ "hi" = V1,
+ %[k,#{ {-1,K1,[]} := {wat,K1}, K2 := 42 }|_] = id([k,#{{-1,K1,[]} => {wat,K1}, K2 => 42}]),
+ %[k,#{ [-1,K2,[]] := {wat,K1}, K1 := 42 }|_] = id([k,#{[-1,K2,[]] => {wat,K1}, K1 => 42}]),
+
+ M0 = id(#{ <<33:333>> => 1, <<332:333>> => ok, a => ok, wat => yep, watzor => ok }),
+ F0 = map_nested_pattern_funs(M0),
+ F1 = F0(wat),
+ F2 = F1(watzor),
+ {yep,ok} = F2(M0),
+ ok.
+
+map_nested_pattern_funs(M) ->
+ K0 = id(a),
+ fun(K1) ->
+ case M of
+ #{ K0 := ok, K1 := yep, <<33:333>> := 1 } ->
+ fun(K2) ->
+ case M of
+ #{ K2 := ok, K1 := yep, <<33:333>> := 1 } ->
+ fun
+ (#{ <<332:333>> := ok, K1 := V1, K2 := V2 }) ->
+ {V1,V2}
+ end
+ end
+ end
+ end
+ end.
+
+t_guard_update_variables(Config) when is_list(Config) ->
+ error = map_guard_update_variables(n,#{},#{}),
+ first = map_guard_update_variables(x,#{}, #{x=>first}),
+ second = map_guard_update_variables(x,#{y=>old}, #{x=>second,y=>old}),
+ third = map_guard_update_variables(x,#{x=>old,y=>old}, #{x=>third,y=>old}),
+ fourth = map_guard_update_variables(x,#{x=>old,y=>old}, #{x=>4,y=>new}),
+ ok.
+
+map_guard_update_variables(K,M1,M2) when M1#{K=>first} =:= M2 -> first;
+map_guard_update_variables(K,M1,M2) when M1#{K=>second} =:= M2 -> second;
+map_guard_update_variables(K,M1,M2) when M1#{K:=third} =:= M2 -> third;
+map_guard_update_variables(K,M1,M2) when M1#{K:=4,y=>new} =:= M2 -> fourth;
+map_guard_update_variables(_,_,_) -> error.
+
+t_guard_sequence_variables(Config) when is_list(Config) ->
+ {1,"a"} = map_guard_sequence_var_1(a,#{seq=>1,a=>id("a"),b=>no}),
+ {2,"b"} = map_guard_sequence_var_1(b,#{seq=>2,b=>id("b"),a=>no}),
+ {3,"c"} = map_guard_sequence_var_1(a,#{seq=>3,a=>id("c"),b=>no}),
+ {4,"d"} = map_guard_sequence_var_1(b,#{seq=>4,b=>id("d"),a=>no}),
+ {4,4} = map_guard_sequence_var_1(seq,#{seq=>4}),
+ {4,4,y} = map_guard_sequence_var_1(seq,#{seq=>4,b=>id("d"),a=>y}),
+ {5,"d"} = map_guard_sequence_var_1(b,#{seq=>5,b=>id("d"),a=>y}),
+
+ %% error case
+ {'EXIT',{{case_clause,_},_}} = (catch map_guard_sequence_var_1("a",#{seq=>4,val=>id("e")})),
+ ok.
+
+
+map_guard_sequence_var_1(K,M) ->
+ case M of
+ #{seq:=1=Seq, K:=Val} -> {Seq,Val};
+ #{seq:=2=Seq, K:=Val} -> {Seq,Val};
+ #{seq:=3=Seq, K:=Val} -> {Seq,Val};
+ #{K:=4=Seq, K:=Val1,a:=Val2} -> {Seq,Val1,Val2};
+ #{seq:=4=Seq, K:=Val} -> {Seq,Val};
+ #{K:=4=Seq, K:=Val} -> {Seq,Val};
+ #{seq:=5=Seq, K:=Val} -> {Seq,Val}
+ end.
+
+
+t_guard_sequence_mixed(Config) when is_list(Config) ->
+ M0 = id(#{ a=>1, b=>1, c=>1, d=>1, e=>1, f=>1, g=>1, h=>1 }),
+ M1 = id(M0#{ d := 3 }),
+ 1 = map_guard_sequence_mixed(a,d,M1),
+ M2 = id(M1#{ b := 2, d := 4, h := 2 }),
+ 2 = map_guard_sequence_mixed(a,d,M2),
+ M3 = id(M2#{ b := 3, e := 5, g := 3 }),
+ 3 = map_guard_sequence_mixed(a,e,M3),
+ M4 = id(M3#{ c := 4, e := 6, h := 1 }),
+ 4 = map_guard_sequence_mixed(a,e,M4),
+ M5 = id(M4#{ c := 5, f := 7, g := 2 }),
+ 5 = map_guard_sequence_mixed(a,f,M5),
+ M6 = id(M5#{ c := 6, f := 8, h := 3 }),
+ 6 = map_guard_sequence_mixed(a,f,M6),
+
+ %% error case
+ {'EXIT',{{case_clause,_},_}} = (catch map_guard_sequence_mixed(a,b,M0)),
+ ok.
+
+map_guard_sequence_mixed(K1,K2,M) ->
+ case M of
+ #{ K1 := 1, b := 1, K2 := 3, g := 1} -> 1;
+ #{ K1 := 1, b := 2, K2 := 4, h := 2} -> 2;
+ #{ K1 := 1, b := 3, K2 := 5, g := 3} -> 3;
+ #{ K1 := 1, c := 4, K2 := 6, h := 1} -> 4;
+ #{ K1 := 1, c := 5, K2 := 7, g := 2} -> 5;
+ #{ K1 := 1, c := 6, K2 := 8, h := 3} -> 6
+ end.
+
+%% register corruption discovered in 18 due to
+%% get_map_elements might destroys registers when fail-label is taken.
+%% Only seen when patterns have two targets,
+%% specifically: we copy one register, and then jump.
+%% {test,is_map,{f,5},[{x,1}]}.
+%%
+%% {get_map_elements,{f,7},{x,1},{list,[{atom,a},{x,1},{atom,b},{x,2}]}}.
+%% %% if 'a' exists but not 'b' {x,1} is overwritten, jump {f,7}
+%%
+%% {move,{integer,1},{x,0}}.
+%% {call_only,3,{f,10}}.
+%%
+%% {label,7}.
+%% {get_map_elements,{f,8},{x,1},{list,[{atom,b},{x,2}]}}.
+%% %% {x,1} (src) is now corrupt
+%%
+%% {move,{x,0},{x,1}}.
+%% {move,{integer,2},{x,0}}.
+%% {call_only,3,{f,10}}.
+%%
+%% Only happens in beam_block opt_move pass with two destinations.
+
+t_register_corruption(Config) when is_list(Config) ->
+ M = #{a=> <<"value">>, c=>3},
+ {3,wanted,<<"value">>} = register_corruption_bar(M,wanted),
+ {3,wanted,<<"value">>} = register_corruption_foo(wanted,M),
+ ok.
+
+register_corruption_foo(A,#{a := V1, b := V2}) ->
+ register_corruption_dummy_call(1,V1,V2);
+register_corruption_foo(A,#{b := V}) ->
+ register_corruption_dummy_call(2,A,V);
+register_corruption_foo(A,#{a := V}) ->
+ register_corruption_dummy_call(3,A,V).
+
+register_corruption_bar(M,A) ->
+ case M of
+ #{a := V1, b := V2} ->
+ register_corruption_dummy_call(1,V1,V2);
+ #{b := V} ->
+ register_corruption_dummy_call(2,A,V);
+ #{a := V} ->
+ register_corruption_dummy_call(3,A,V)
+ end.
+
+
+register_corruption_dummy_call(A,B,C) -> {A,B,C}.
+
+
+t_frequency_table(Config) when is_list(Config) ->
+ random:seed({13,1337,54}), % pseudo random
+ N = 100000,
+ Ts = rand_terms(N),
+ #{ n:=N, tf := Tf } = frequency_table(Ts,#{ n=>0, tf => #{}}),
+ ok = check_frequency(Ts,Tf),
+ ok.
+
+
+frequency_table([T|Ts], M) ->
+ case M of
+ #{ n := N, tf := #{ T := C } = F } ->
+ frequency_table(Ts,M#{ n := N + 1, tf := F#{ T := C + 1 }});
+ #{ n := N, tf := F } ->
+ frequency_table(Ts,M#{ n := N + 1, tf := F#{ T => 1 }})
+ end;
+frequency_table([], M) -> M.
+
+
+check_frequency(Ts,Tf) ->
+ check_frequency(Ts,Tf,dict:new()).
+
+check_frequency([T|Ts],Tf,D) ->
+ case dict:find(T,D) of
+ error -> check_frequency(Ts,Tf,dict:store(T,1,D));
+ {ok,C} -> check_frequency(Ts,Tf,dict:store(T,C+1,D))
+ end;
+check_frequency([],Tf,D) ->
+ validate_frequency(dict:to_list(D),Tf).
+
+validate_frequency([{T,C}|Fs],Tf) ->
+ case Tf of
+ #{ T := C } -> validate_frequency(Fs,Tf);
+ _ -> error
+ end;
+validate_frequency([], _) -> ok.
+
+
+%% aux
+
+rand_terms(0) -> [];
+rand_terms(N) -> [rand_term()|rand_terms(N-1)].
+
+rand_term() ->
+ case random:uniform(6) of
+ 1 -> rand_binary();
+ 2 -> rand_number();
+ 3 -> rand_atom();
+ 4 -> rand_tuple();
+ 5 -> rand_list();
+ 6 -> rand_map()
+ end.
+
+rand_binary() ->
+ case random:uniform(3) of
+ 1 -> <<>>;
+ 2 -> <<"hi">>;
+ 3 -> <<"message text larger than 64 bytes. yep, message text larger than 64 bytes.">>
+ end.
+
+rand_number() ->
+ case random:uniform(3) of
+ 1 -> random:uniform(5);
+ 2 -> float(random:uniform(5));
+ 3 -> 1 bsl (63 + random:uniform(3))
+ end.
+
+rand_atom() ->
+ case random:uniform(3) of
+ 1 -> hi;
+ 2 -> some_atom;
+ 3 -> some_other_atom
+ end.
+
+
+rand_tuple() ->
+ case random:uniform(3) of
+ 1 -> {ok, rand_term()}; % careful
+ 2 -> {1, 2, 3};
+ 3 -> {<<"yep">>, 1337}
+ end.
+
+rand_list() ->
+ case random:uniform(3) of
+ 1 -> "hi";
+ 2 -> [1,rand_term()]; % careful
+ 3 -> [improper|list]
+ end.
+
+rand_map() ->
+ case random:uniform(3) of
+ 1 -> #{ hi => 3 };
+ 2 -> #{ wat => rand_term(), other => 3 }; % careful
+ 3 -> #{ hi => 42, other => 42, yet_anoter => 1337 }
+ end.
+
+
+
%% Use this function to avoid compile-time evaluation of an expression.
id(I) -> I.
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index 1e778dca24..67d668f650 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,7 +23,8 @@
init_per_group/2,end_per_group/2,
pmatch/1,mixed/1,aliases/1,match_in_call/1,
untuplify/1,shortcut_boolean/1,letify_guard/1,
- selectify/1,underscore/1,match_map/1,coverage/1]).
+ selectify/1,underscore/1,match_map/1,map_vars_used/1,
+ coverage/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -33,10 +35,10 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[pmatch,mixed,aliases,match_in_call,untuplify,
shortcut_boolean,letify_guard,selectify,
- underscore,match_map,coverage]}].
+ underscore,match_map,map_vars_used,coverage]}].
init_per_suite(Config) ->
@@ -140,6 +142,13 @@ aliases(Config) when is_list(Config) ->
?line {a,b} = list_alias2([a,b]),
?line {a,b} = list_alias3([a,b]),
+ %% Non-matching aliases.
+ none = mixed_aliases(<<42>>),
+ none = mixed_aliases([b]),
+ none = mixed_aliases([d]),
+ none = mixed_aliases({a,42}),
+ none = mixed_aliases(42),
+
ok.
str_alias(V) ->
@@ -243,6 +252,12 @@ list_alias2([X,Y]=[a,b]) ->
list_alias3([X,b]=[a,Y]) ->
{X,Y}.
+mixed_aliases(<<X:8>> = x) -> {a,X};
+mixed_aliases([b] = <<X:8>>) -> {b,X};
+mixed_aliases(<<X:8>> = {a,X}) -> {c,X};
+mixed_aliases([X] = <<X:8>>) -> {d,X};
+mixed_aliases(_) -> none.
+
%% OTP-7018.
match_in_call(Config) when is_list(Config) ->
@@ -419,6 +434,18 @@ do_match_map_2(Map) ->
Tuple
end.
+map_vars_used(Config) when is_list(Config) ->
+ {some,value} = do_map_vars_used(a, b, #{{a,b}=>42,v=>{some,value}}),
+ ok.
+
+do_map_vars_used(X, Y, Map) ->
+ case {X,Y} of
+ T ->
+ %% core_lib:is_var_used/2 would not consider T used.
+ #{T:=42,v:=Val} = Map,
+ Val
+ end.
+
coverage(Config) when is_list(Config) ->
%% Cover beam_dead.
ok = coverage_1(x, a),
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index 44c7161530..8606935504 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -60,7 +61,7 @@ all() ->
[{group,p}].
groups() ->
- [{p,[],%%test_lib:parallel(),
+ [{p,[],
[tobias,empty_string,md5,silly_coverage,
confused_literals,integer_encoding,override_bif]}].
@@ -225,14 +226,15 @@ silly_coverage(Config) when is_list(Config) ->
{label,2}|non_proper_list]}],99},
?line expect_error(fun() -> beam_bool:module(BoolInput, []) end),
- %% beam_dead
+ %% 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}],[],
[{function,foo,0,2,
[{label,1},
{func_info,{atom,?MODULE},{atom,foo},0},
{label,2},
- {jump,bad}]}],99},
- ?line expect_error(fun() -> beam_block:module(DeadInput, []) end),
+ {test,is_eq_exact,{f,1},[bad,operands]}]}],99},
+ expect_error(fun() -> beam_dead:module(DeadInput, []) end),
%% beam_clean
CleanInput = {?MODULE,[{foo,0}],[],
@@ -279,6 +281,14 @@ silly_coverage(Config) when is_list(Config) ->
{label,2}|non_proper_list]}],99},
expect_error(fun() -> beam_z:module(BeamZInput, []) end),
+ %% beam_validator.
+ BeamValInput = {?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_validator:module(BeamValInput, []) end),
+
ok.
expect_error(Fun) ->
@@ -329,8 +339,16 @@ integer_encoding_1(Config) ->
?line do_integer_encoding(-(id(1) bsl 10000), Src, Data),
?line do_integer_encoding(id(1) bsl 10000, Src, Data),
- ?line do_integer_encoding(2048, 0, Src, Data),
-
+ do_integer_encoding(1024, 0, Src, Data),
+ _ = [begin
+ B = 1 bsl I,
+ do_integer_encoding(-B-1, Src, Data),
+ do_integer_encoding(-B, Src, Data),
+ do_integer_encoding(-B+1, Src, Data),
+ do_integer_encoding(B-1, Src, Data),
+ do_integer_encoding(B, Src, Data),
+ do_integer_encoding(B+1, Src, Data)
+ end || I <- lists:seq(1, 128)],
io:put_chars(Src, "Last].\n\n"),
?line ok = file:close(Src),
io:put_chars(Data, "0].\n\n"),
@@ -363,11 +381,9 @@ do_integer_encoding(N, I0, Src, Data) ->
do_integer_encoding(I, Src, Data) ->
Str = integer_to_list(I),
- io:put_chars(Src, Str),
- io:put_chars(Src, ", \n"),
- io:put_chars(Data, Str),
- io:put_chars(Data, ", \n").
-
+ io:put_chars(Src, [Str,",\n"]),
+ io:put_chars(Data, [Str,",\n"]).
+
id(I) -> I.
diff --git a/lib/compiler/test/num_bif_SUITE.erl b/lib/compiler/test/num_bif_SUITE.erl
index 3479cf5425..d54fa203f0 100644
--- a/lib/compiler/test/num_bif_SUITE.erl
+++ b/lib/compiler/test/num_bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 00a6e900d4..4016fac0b5 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -187,12 +188,13 @@ ref_opt(Config) when is_list(Config) ->
end.
ref_opt_1(Config) ->
- ?line DataDir = ?config(data_dir, Config),
- ?line PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
Sources = filelib:wildcard(filename:join([DataDir,"ref_opt","*.{erl,S}"])),
- ?line test_lib:p_run(fun(Src) ->
- do_ref_opt(Src, PrivDir)
- end, Sources),
+ test_lib:p_run(fun(Src) ->
+ do_ref_opt(Src, PrivDir)
+ end, Sources),
+ cover_recv_instructions(),
ok.
do_ref_opt(Source, PrivDir) ->
@@ -202,9 +204,9 @@ do_ref_opt(Source, PrivDir) ->
{outdir,PrivDir}] ++
[from_asm || Ext =:= ".S" ]),
Base = filename:rootname(filename:basename(Source), Ext),
- code:purge(list_to_atom(Base)),
- BeamFile = filename:join(PrivDir, Base),
- code:load_abs(BeamFile),
+ code:purge(list_to_atom(Base)),
+ BeamFile = filename:join(PrivDir, Base),
+ code:load_abs(BeamFile),
ok = Mod:Mod(),
{beam_file,Mod,_,_,_,Code} = beam_disasm:file(BeamFile),
case Base of
@@ -232,6 +234,27 @@ collect_recv_opt_instrs(Code) ->
end] || {function,_,_,_,Is} <- Code],
lists:append(L).
+cover_recv_instructions() ->
+ %% We want to cover the handling of recv_mark and recv_set in beam_utils.
+ %% Since those instructions are introduced in a late optimization pass,
+ %% beam_utils:live_opt() will not see them unless the compilation is
+ %% started from a .S file. The compile_SUITE:asm/1 test case will
+ %% compile all test suite files to .S and then run them through the
+ %% compiler again.
+ %%
+ %% Here will we will ensure that this modules contains recv_mark
+ %% and recv_set instructions.
+ Pid = spawn_link(fun() ->
+ receive {Parent,Ref} ->
+ Parent ! Ref
+ end
+ end),
+ Ref = make_ref(),
+ Pid ! {self(),Ref},
+ receive
+ Ref -> ok
+ end.
+
export(Config) when is_list(Config) ->
Ref = make_ref(),
?line self() ! {result,Ref,42},
diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl
index f736e14bf6..2ef379e43f 100644
--- a/lib/compiler/test/record_SUITE.erl
+++ b/lib/compiler/test/record_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -246,6 +247,14 @@ record_test_2(Config) when is_list(Config) ->
?line Barf = update_barf(Barf0),
?line #barf{a="abc",b=1} = id(Barf),
+ %% Test optimization of is_record/3.
+ false = case id({a,b}) of
+ {_,_}=Tuple -> is_record(Tuple, foo)
+ end,
+ false = case id(true) of
+ true=Bool -> is_record(Bool, foo)
+ end,
+
ok.
record_test_3(Config) when is_list(Config) ->
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 c2b3ec2f34..fb3d7d3ae4 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
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/compiler/test/regressions_SUITE.erl b/lib/compiler/test/regressions_SUITE.erl
new file mode 100644
index 0000000000..716a9693ed
--- /dev/null
+++ b/lib/compiler/test/regressions_SUITE.erl
@@ -0,0 +1,98 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+
+%% Test specific code snippets that has crashed the compiler in the past.
+-module(regressions_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+
+-export([all/0, groups/0, init_per_testcase/2,end_per_testcase/2]).
+
+-export([maps/1]).
+
+groups() ->
+ [{p,test_lib:parallel(),
+ [maps]}].
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(2)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all() ->
+ test_lib:recompile(?MODULE),
+ [{group,p}].
+
+%%% test cases
+
+maps(Config) when is_list(Config) ->
+ Ts = [{beam_bool_get_elements,
+ <<"century(#{ron := operator}, _century) ->
+ if 0.0; _century, _century, _century -> _century end.
+ ">>}],
+ ok = run(Config, Ts),
+ ok.
+
+%% aux
+
+run(Config, Tests) ->
+ F = fun({N,P}) ->
+ io:format("Compiling test for: ~w~n", [N]),
+ case catch run_test(Config, P) of
+ {'EXIT', Reason} ->
+ ?t:format("~nTest ~p failed.~nReason: ~p~n", [N, Reason]),
+ fail();
+ _ -> ok
+ end
+ end,
+ lists:foreach(F, Tests).
+
+
+run_test(Conf, Test0) ->
+ Module = "regressions_"++test_lib:uniq(),
+ Filename = Module ++ ".erl",
+ DataDir = ?config(priv_dir, Conf),
+ Test = ["-module(", Module, "). ", Test0],
+ File = filename:join(DataDir, Filename),
+ Def = [binary,export_all,return],
+ Opts = [ Opt ++ Def ||
+ Opt <- [ [no_postopt],
+ [no_copt],
+ [no_postopt,no_copt],
+ [inline],
+ [inline,no_postopt],
+ []
+ ]],
+ ok = file:write_file(File, Test),
+ lists:foreach(fun(Opt) ->
+ io:format(" - compiling with ~p~n", [Opt]),
+ {ok,_M,_Bin,_} = compile:file(File,Opt)
+ end, Opts),
+ file:delete(File),
+ ok.
+
+fail() ->
+ io:format("failed~n"),
+ ?t:fail().
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index a8befbecd9..09ec8f3c81 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -3,26 +3,29 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(test_lib).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile({no_auto_import,[binary_part/2]}).
--export([recompile/1,parallel/0,uniq/0,opt_opts/1,get_data_dir/1,
+-export([id/1,recompile/1,parallel/0,uniq/0,opt_opts/1,get_data_dir/1,
smoke_disasm/1,p_run/2,binary_part/2]).
+id(I) -> I.
+
recompile(Mod) when is_atom(Mod) ->
case whereis(cover_server) of
undefined -> ok;
@@ -44,6 +47,10 @@ smoke_disasm(File) when is_list(File) ->
Res = beam_disasm:file(File),
{beam_file,_Mod} = {element(1, Res),element(2, Res)}.
+%% If we are running cover, we don't want to run test cases that
+%% invokes the compiler in parallel, as doing so would probably
+%% be slower than running them sequentially.
+
parallel() ->
case ?t:is_cover() orelse erlang:system_info(schedulers) =:= 1 of
true -> [];
@@ -51,10 +58,8 @@ parallel() ->
end.
uniq() ->
- U0 = erlang:ref_to_list(make_ref()),
- U1 = re:replace(U0, "^#Ref", ""),
- U = re:replace(U1, "[^[A-Za-z0-9_]+", "_", [global]),
- re:replace(U, "_*$", "", [{return,list}]).
+ U = erlang:unique_integer([positive]),
+ "_" ++ integer_to_list(U).
%% Retrieve the "interesting" compiler options (options for optimization
%% and compatibility) for the given module.
@@ -90,13 +95,18 @@ get_data_dir(Config) ->
%% Will fail the test case if there were any errors.
p_run(Test, List) ->
+ S = erlang:system_info(schedulers),
N = case ?t:is_cover() of
false ->
- erlang:system_info(schedulers);
+ S + 1;
true ->
- %% Cover is running. Using more than one process
- %% will probably only slow down compilation.
- 1
+ %% Cover is running. Using too many processes
+ %% could slow us down. Measurements on my computer
+ %% showed that using 4 parallel processes was
+ %% slightly faster than using 3. Using more than
+ %% 4 would not buy us much and could actually be
+ %% slower.
+ max(S, 4)
end,
p_run_loop(Test, List, N, [], 0, 0).
diff --git a/lib/compiler/test/trycatch_SUITE.erl b/lib/compiler/test/trycatch_SUITE.erl
index 4530d08c77..adcab8ef67 100644
--- a/lib/compiler/test/trycatch_SUITE.erl
+++ b/lib/compiler/test/trycatch_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,7 +25,8 @@
catch_oops/1,after_oops/1,eclectic/1,rethrow/1,
nested_of/1,nested_catch/1,nested_after/1,
nested_horrid/1,last_call_optimization/1,bool/1,
- plain_catch_coverage/1,andalso_orelse/1,get_in_try/1]).
+ plain_catch_coverage/1,andalso_orelse/1,get_in_try/1,
+ hockey/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -35,11 +37,12 @@ all() ->
[{group,p}].
groups() ->
- [{p,test_lib:parallel(),
+ [{p,[parallel],
[basic,lean_throw,try_of,try_after,catch_oops,
after_oops,eclectic,rethrow,nested_of,nested_catch,
nested_after,nested_horrid,last_call_optimization,
- bool,plain_catch_coverage,andalso_orelse,get_in_try]}].
+ bool,plain_catch_coverage,andalso_orelse,get_in_try,
+ hockey]}].
init_per_suite(Config) ->
@@ -790,7 +793,6 @@ nested_after_1({X1,C1,V1},
nested_horrid(Config) when is_list(Config) ->
- _V = {make_ref(),nested_horrid,4.711},
{[true,true],{[true,1.0],1.0}} =
nested_horrid_1({true,void,void}, 1.0),
ok.
@@ -944,3 +946,14 @@ get_valid_line([_|T]=Path, Annotations) ->
_:not_found ->
get_valid_line(T, Annotations)
end.
+
+hockey(_) ->
+ {'EXIT',{{badmatch,_},[_|_]}} = (catch hockey()),
+ ok.
+
+hockey() ->
+ %% beam_jump used to generate a call into the try block.
+ %% beam_validator disapproved.
+ receive _ -> (b = fun() -> ok end)
+ + hockey, +x after 0 -> ok end, try (a = fun() -> ok end) + hockey, +
+ y catch _ -> ok end.
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index 0637041873..a964afe5a1 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -38,8 +39,9 @@
-export([pattern/1,pattern2/1,pattern3/1,pattern4/1,
guard/1,bad_arith/1,bool_cases/1,bad_apply/1,
files/1,effect/1,bin_opt_info/1,bin_construction/1,
- comprehensions/1,maps/1,redundant_boolean_clauses/1,
- latin1_fallback/1]).
+ comprehensions/1,maps/1,maps_bin_opt_info/1,
+ redundant_boolean_clauses/1,
+ latin1_fallback/1,underscore/1,no_warnings/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(2)).
@@ -64,7 +66,9 @@ groups() ->
[pattern,pattern2,pattern3,pattern4,guard,
bad_arith,bool_cases,bad_apply,files,effect,
bin_opt_info,bin_construction,comprehensions,maps,
- redundant_boolean_clauses,latin1_fallback]}].
+ maps_bin_opt_info,
+ redundant_boolean_clauses,latin1_fallback,
+ underscore,no_warnings]}].
init_per_suite(Config) ->
Config.
@@ -280,11 +284,12 @@ 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}}
] }}],
- ?line [] = run(Config, Ts),
+ [] = run(Config, Ts),
ok.
bool_cases(Config) when is_list(Config) ->
@@ -368,7 +373,7 @@ files(Config) when is_list(Config) ->
%% Test warnings for term construction and BIF calls in effect context.
effect(Config) when is_list(Config) ->
- Ts = [{lc,
+ Ts = [{effect,
<<"
t(X) ->
case X of
@@ -474,6 +479,19 @@ effect(Config) when is_list(Config) ->
m9(Bs) ->
[{B,ok} = {B,foo:bar(B)} || B <- Bs],
ok.
+
+ m10(ConfigTableSize) ->
+ case ConfigTableSize of
+ apa ->
+ CurrentConfig = {id(camel_phase3),id(sms)},
+ case CurrentConfig of
+ {apa, bepa} -> ok;
+ _ -> ok
+ end
+ end,
+ ok.
+
+ id(I) -> I.
">>,
[],
{warnings,[{5,sys_core_fold,{no_effect,{erlang,is_integer,1}}},
@@ -578,11 +596,11 @@ maps(Config) when is_list(Config) ->
<<"
t() ->
M = {a,[]},
- {'EXIT',{badarg,_}} = (catch(M#{ a => 1})),
+ {'EXIT',{badarg,_}} = (catch(M#{ a => 1 })),
ok.
">>,
[],
- {warnings,[{4,v3_kernel,bad_map}]}},
+ {warnings,[{4,sys_core_fold,{eval_failure,badmap}}]}},
{bad_map_src2,
<<"
t() ->
@@ -592,7 +610,7 @@ maps(Config) when is_list(Config) ->
id(I) -> I.
">>,
[inline],
- {warnings,[{4,v3_kernel,bad_map}]}},
+ []},
{bad_map_src3,
<<"
t() ->
@@ -600,8 +618,8 @@ maps(Config) when is_list(Config) ->
ok.
">>,
[],
- {warnings,[{3,v3_core,bad_map}]}},
- {bad_map_literal_key,
+ {warnings,[{3,v3_core,badmap}]}},
+ {ok_map_literal_key,
<<"
t() ->
V = id(1),
@@ -614,10 +632,23 @@ maps(Config) when is_list(Config) ->
id(I) -> I.
">>,
[],
- {warnings,[{6,v3_core,nomatch}]}}],
+ []}],
run(Config, Ts),
ok.
+maps_bin_opt_info(Config) when is_list(Config) ->
+ Ts = [{map_bsm,
+ <<"
+ t1(<<0:8,7:8,T/binary>>,#{val := I}=M) ->
+ t1(T, M#{val := I+1});
+ t1(<<_:8>>,M) ->
+ M.
+ ">>,
+ [bin_opt_info],
+ {warnings,[{2,beam_bsm,bin_opt}]}}],
+ [] = run(Config, Ts),
+ ok.
+
redundant_boolean_clauses(Config) when is_list(Config) ->
Ts = [{redundant_boolean_clauses,
<<"
@@ -678,6 +709,80 @@ latin1_fallback(Conf) when is_list(Conf) ->
ok.
+underscore(Config) when is_list(Config) ->
+ S0 = <<"f(A) ->
+ _VAR1 = <<A>>,
+ _VAR2 = {ok,A},
+ _VAR3 = [A],
+ ok.
+ g(A) ->
+ _VAR1 = A/0,
+ _VAR2 = date(),
+ ok.
+ h() ->
+ _VAR1 = fun() -> ok end,
+ ok.
+ i(A) ->
+ _VAR1 = #{A=>42},
+ ok.
+ ">>,
+ Ts0 = [{underscore0,
+ S0,
+ [],
+ {warnings,[{2,sys_core_fold,useless_building},
+ {3,sys_core_fold,useless_building},
+ {4,sys_core_fold,useless_building},
+ {7,sys_core_fold,result_ignored},
+ {8,sys_core_fold,{no_effect,{erlang,date,0}}},
+ {11,sys_core_fold,useless_building},
+ {14,sys_core_fold,useless_building}
+ ]}}],
+ [] = run(Config, Ts0),
+
+ %% Replace all "_VAR<digit>" variables with a plain underscore.
+ %% Now there should be no warnings.
+ S1 = re:replace(S0, "_VAR\\d+", "_", [global]),
+ io:format("~s\n", [S1]),
+ Ts1 = [{underscore1,S1,[],[]}],
+ [] = run(Config, Ts1),
+
+ ok.
+
+no_warnings(Config) when is_list(Config) ->
+ Ts = [{no_warnings,
+ <<"-record(r, {s=ordsets:new(),a,b}).
+
+ a() ->
+ R = #r{}, %No warning expected.
+ {R#r.a,R#r.b}.
+
+ b(X) ->
+ T = true,
+ Var = [X], %No warning expected.
+ case T of
+ false -> Var;
+ true -> []
+ end.
+
+ c() ->
+ R0 = {r,\"abc\",undefined,os:timestamp()}, %No warning.
+ case R0 of
+ {r,V1,_V2,V3} -> {r,V1,\"def\",V3}
+ end.
+
+ d(In0, Bool) ->
+ {In1,Int} = case id(Bool) of
+ false -> {In0,0}
+ end,
+ [In1,Int].
+
+ id(I) -> I.
+ ">>,
+ [],
+ []}],
+ run(Config, Ts),
+ ok.
+
%%%
%%% End of test cases.
%%%
@@ -699,10 +804,10 @@ run(Config, Tests) ->
%% Compiles a test module and returns the list of errors and warnings.
run_test(Conf, Test0, Warnings) ->
- Mod = "warnings_"++test_lib:uniq(),
- Filename = Mod ++ ".erl",
+ Module = "warnings_"++test_lib:uniq(),
+ Filename = Module ++ ".erl",
?line DataDir = ?privdir,
- Test = ["-module(", Mod, "). ", Test0],
+ Test = ["-module(", Module, "). ", Test0],
?line File = filename:join(DataDir, Filename),
?line Opts = [binary,export_all,return|Warnings],
?line ok = file:write_file(File, Test),
diff --git a/lib/compiler/test/z_SUITE.erl b/lib/compiler/test/z_SUITE.erl
new file mode 100644
index 0000000000..d864184f4c
--- /dev/null
+++ b/lib/compiler/test/z_SUITE.erl
@@ -0,0 +1,63 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(z_SUITE).
+
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ loaded/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(?MODULE),
+ [loaded].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+loaded(_Config) ->
+ 0 = do_loaded(code:all_loaded(), 0),
+ ok.
+
+do_loaded([{M,_}|Ms], E0) ->
+ E = try
+ _ = M:module_info(),
+ _ = M:module_info(functions),
+ E0
+ catch
+ C:Error ->
+ Stk = erlang:get_stacktrace(),
+ io:format("~p:~p\n~p\n", [C,Error,Stk]),
+ E0 + 1
+ end,
+ do_loaded(Ms, E);
+do_loaded([], E) -> E.
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 05e682c893..c83455240d 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 5.0.4
+COMPILER_VSN = 6.0.3
diff --git a/lib/configure.in.src b/lib/configure.in.src
index fea3c7bffa..7ac52f8a97 100644
--- a/lib/configure.in.src
+++ b/lib/configure.in.src
@@ -3,16 +3,17 @@ dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 1999-2011. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
dnl
diff --git a/lib/cosEvent/Makefile b/lib/cosEvent/Makefile
index 4fa0b49ab7..4c13a8ce01 100644
--- a/lib/cosEvent/Makefile
+++ b/lib/cosEvent/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin.xml
index 73456845fc..1e82dd684a 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml
index 4cf079ce09..1903812e5e 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml
index cdbcd0e146..159c0b87e2 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml
index 420e4b289c..de18f047a9 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml
index 8dbf7804ac..212372b4c2 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml
index 2c448f1f54..58127cac95 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml
index d3b548636a..650a303d7e 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml
index 7a2d874aab..f29bb5994b 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/Makefile b/lib/cosEvent/doc/src/Makefile
index 1b867852e4..ed69d70d47 100644
--- a/lib/cosEvent/doc/src/Makefile
+++ b/lib/cosEvent/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEvent/doc/src/book.xml b/lib/cosEvent/doc/src/book.xml
index 1b025351f8..f7c4e853c7 100644
--- a/lib/cosEvent/doc/src/book.xml
+++ b/lib/cosEvent/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/ch_contents.xml b/lib/cosEvent/doc/src/ch_contents.xml
index e65c7e53bc..1fe0f772e6 100644
--- a/lib/cosEvent/doc/src/ch_contents.xml
+++ b/lib/cosEvent/doc/src/ch_contents.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/ch_event_service.xml b/lib/cosEvent/doc/src/ch_event_service.xml
index 5148b77ab1..60d948b323 100644
--- a/lib/cosEvent/doc/src/ch_event_service.xml
+++ b/lib/cosEvent/doc/src/ch_event_service.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/ch_introduction.xml b/lib/cosEvent/doc/src/ch_introduction.xml
index 01ce5c4231..b3d26f23f6 100644
--- a/lib/cosEvent/doc/src/ch_introduction.xml
+++ b/lib/cosEvent/doc/src/ch_introduction.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/cosEventApp.xml b/lib/cosEvent/doc/src/cosEventApp.xml
index 3b9a38ea93..5b911fec4f 100644
--- a/lib/cosEvent/doc/src/cosEventApp.xml
+++ b/lib/cosEvent/doc/src/cosEventApp.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/notes.xml b/lib/cosEvent/doc/src/notes.xml
index 8f519447fc..3af3a9e141 100644
--- a/lib/cosEvent/doc/src/notes.xml
+++ b/lib/cosEvent/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,7 +33,23 @@
<file>notes.xml</file>
</header>
- <section><title>cosEvent 2.1.15</title>
+ <section><title>cosEvent 2.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosEvent 2.1.15</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosEvent/doc/src/part.xml b/lib/cosEvent/doc/src/part.xml
index a21579bc0a..43ed8e9184 100644
--- a/lib/cosEvent/doc/src/part.xml
+++ b/lib/cosEvent/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/part_notes.xml b/lib/cosEvent/doc/src/part_notes.xml
index d9a5e610c6..e406f16a70 100644
--- a/lib/cosEvent/doc/src/part_notes.xml
+++ b/lib/cosEvent/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEvent/doc/src/ref_man.xml b/lib/cosEvent/doc/src/ref_man.xml
index 26dbf2b2ef..38a52c1b61 100644
--- a/lib/cosEvent/doc/src/ref_man.xml
+++ b/lib/cosEvent/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer_impl.erl b/lib/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer_impl.erl
index 26269ad4f7..424b86e956 100644
--- a/lib/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer_impl.erl
+++ b/lib/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer_impl.erl b/lib/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer_impl.erl
index 969beb1d04..bf00399429 100644
--- a/lib/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer_impl.erl
+++ b/lib/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/CosEventChannelAdmin_SupplierAdmin_impl.erl b/lib/cosEvent/src/CosEventChannelAdmin_SupplierAdmin_impl.erl
index c7cf0bd869..52b18fc824 100644
--- a/lib/cosEvent/src/CosEventChannelAdmin_SupplierAdmin_impl.erl
+++ b/lib/cosEvent/src/CosEventChannelAdmin_SupplierAdmin_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/Makefile b/lib/cosEvent/src/Makefile
index 2864ee0538..b79f0ec1e5 100644
--- a/lib/cosEvent/src/Makefile
+++ b/lib/cosEvent/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEvent/src/cosEvent.app.src b/lib/cosEvent/src/cosEvent.app.src
index 66b0d2e168..5ffd12bc6b 100644
--- a/lib/cosEvent/src/cosEvent.app.src
+++ b/lib/cosEvent/src/cosEvent.app.src
@@ -39,7 +39,7 @@
{applications, [orber, stdlib, kernel]},
{env, []},
{mod, {cosEventApp, []}},
- {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-6.0"]}
+ {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-7.0"]}
]}.
diff --git a/lib/cosEvent/src/cosEventApp.erl b/lib/cosEvent/src/cosEventApp.erl
index 143c241448..065032d933 100644
--- a/lib/cosEvent/src/cosEventApp.erl
+++ b/lib/cosEvent/src/cosEventApp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/cosEventApp.hrl b/lib/cosEvent/src/cosEventApp.hrl
index ef72277bd6..6b7f23c827 100644
--- a/lib/cosEvent/src/cosEventApp.hrl
+++ b/lib/cosEvent/src/cosEventApp.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/oe_CosEventComm_CAdmin_impl.erl b/lib/cosEvent/src/oe_CosEventComm_CAdmin_impl.erl
index 976c6dbab5..d1e4c9c758 100644
--- a/lib/cosEvent/src/oe_CosEventComm_CAdmin_impl.erl
+++ b/lib/cosEvent/src/oe_CosEventComm_CAdmin_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/oe_CosEventComm_Channel_impl.erl b/lib/cosEvent/src/oe_CosEventComm_Channel_impl.erl
index 531edaa0af..61d96a51e0 100644
--- a/lib/cosEvent/src/oe_CosEventComm_Channel_impl.erl
+++ b/lib/cosEvent/src/oe_CosEventComm_Channel_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/src/oe_CosEventComm_PullerS_impl.erl b/lib/cosEvent/src/oe_CosEventComm_PullerS_impl.erl
index 5f2733e72d..b431296624 100644
--- a/lib/cosEvent/src/oe_CosEventComm_PullerS_impl.erl
+++ b/lib/cosEvent/src/oe_CosEventComm_PullerS_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -251,7 +252,8 @@ send_sync(_OE_This, _OE_From, State, Any) ->
store_event(DB, Max, Event) ->
case ets:info(DB, size) of
CurrentSize when CurrentSize < Max ->
- ets:insert(DB, {now(), Event});
+ ets:insert(DB, {{erlang:system_time(), erlang:unique_integer([positive])},
+ Event});
_ ->
orber:dbg("[~p] oe_CosEventComm_PullerS:store_event(~p); DB full drop event.",
[?LINE, Event], ?DEBUG_LEVEL),
diff --git a/lib/cosEvent/src/oe_CosEventComm_PusherS_impl.erl b/lib/cosEvent/src/oe_CosEventComm_PusherS_impl.erl
index c64b01ea1d..e9482e77d6 100644
--- a/lib/cosEvent/src/oe_CosEventComm_PusherS_impl.erl
+++ b/lib/cosEvent/src/oe_CosEventComm_PusherS_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/test/Makefile b/lib/cosEvent/test/Makefile
index c5afcdb7e4..2d29afd20d 100644
--- a/lib/cosEvent/test/Makefile
+++ b/lib/cosEvent/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEvent/test/event_channel_SUITE.erl b/lib/cosEvent/test/event_channel_SUITE.erl
index 9017f489bf..0d67a94520 100644
--- a/lib/cosEvent/test/event_channel_SUITE.erl
+++ b/lib/cosEvent/test/event_channel_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/test/event_test_PullC_impl.erl b/lib/cosEvent/test/event_test_PullC_impl.erl
index 4b81572cad..e1824dceae 100644
--- a/lib/cosEvent/test/event_test_PullC_impl.erl
+++ b/lib/cosEvent/test/event_test_PullC_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/test/event_test_PullS_impl.erl b/lib/cosEvent/test/event_test_PullS_impl.erl
index 81685980fb..2bfb86d4c3 100644
--- a/lib/cosEvent/test/event_test_PullS_impl.erl
+++ b/lib/cosEvent/test/event_test_PullS_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/test/event_test_PushC_impl.erl b/lib/cosEvent/test/event_test_PushC_impl.erl
index c2be1d4c08..e035f7cf0a 100644
--- a/lib/cosEvent/test/event_test_PushC_impl.erl
+++ b/lib/cosEvent/test/event_test_PushC_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/test/event_test_PushS_impl.erl b/lib/cosEvent/test/event_test_PushS_impl.erl
index 35cfc66e6b..b60c634d05 100644
--- a/lib/cosEvent/test/event_test_PushS_impl.erl
+++ b/lib/cosEvent/test/event_test_PushS_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/test/event_test_server.idl b/lib/cosEvent/test/event_test_server.idl
index 1719401ccd..74bab08444 100644
--- a/lib/cosEvent/test/event_test_server.idl
+++ b/lib/cosEvent/test/event_test_server.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 2001-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// 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%
//
diff --git a/lib/cosEvent/test/generated_SUITE.erl b/lib/cosEvent/test/generated_SUITE.erl
index e1e4e719b0..40fe94386a 100644
--- a/lib/cosEvent/test/generated_SUITE.erl
+++ b/lib/cosEvent/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk
index 40bf1ba49d..3149020d7c 100644
--- a/lib/cosEvent/vsn.mk
+++ b/lib/cosEvent/vsn.mk
@@ -1,3 +1,2 @@
-
-COSEVENT_VSN = 2.1.15
+COSEVENT_VSN = 2.2
diff --git a/lib/cosEventDomain/Makefile b/lib/cosEventDomain/Makefile
index 566141cefd..f74d77bd2e 100644
--- a/lib/cosEventDomain/Makefile
+++ b/lib/cosEventDomain/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEventDomain/doc/src/CosEventDomainAdmin.xml b/lib/cosEventDomain/doc/src/CosEventDomainAdmin.xml
index fba39e5bd2..ca7ec31969 100644
--- a/lib/cosEventDomain/doc/src/CosEventDomainAdmin.xml
+++ b/lib/cosEventDomain/doc/src/CosEventDomainAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml
index 12ab034f8f..143d448089 100644
--- a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml
+++ b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml
index 16d297ddab..b6d64299b8 100644
--- a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml
+++ b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/Makefile b/lib/cosEventDomain/doc/src/Makefile
index f820ee5dc0..8b2450e64d 100644
--- a/lib/cosEventDomain/doc/src/Makefile
+++ b/lib/cosEventDomain/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEventDomain/doc/src/book.xml b/lib/cosEventDomain/doc/src/book.xml
index 8023ac8755..3dde504cfd 100644
--- a/lib/cosEventDomain/doc/src/book.xml
+++ b/lib/cosEventDomain/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/ch_QoS.xml b/lib/cosEventDomain/doc/src/ch_QoS.xml
index ff46824074..bdc9a8dcfb 100644
--- a/lib/cosEventDomain/doc/src/ch_QoS.xml
+++ b/lib/cosEventDomain/doc/src/ch_QoS.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/ch_contents.xml b/lib/cosEventDomain/doc/src/ch_contents.xml
index 8de9aa06d2..4e98e21948 100644
--- a/lib/cosEventDomain/doc/src/ch_contents.xml
+++ b/lib/cosEventDomain/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/ch_event_domain_service.xml b/lib/cosEventDomain/doc/src/ch_event_domain_service.xml
index af08182bf5..f1d2405e9f 100644
--- a/lib/cosEventDomain/doc/src/ch_event_domain_service.xml
+++ b/lib/cosEventDomain/doc/src/ch_event_domain_service.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/ch_introduction.xml b/lib/cosEventDomain/doc/src/ch_introduction.xml
index 68048a5caa..59034ca84a 100644
--- a/lib/cosEventDomain/doc/src/ch_introduction.xml
+++ b/lib/cosEventDomain/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/cosEventDomainApp.xml b/lib/cosEventDomain/doc/src/cosEventDomainApp.xml
index ff444c75d6..2efba82094 100644
--- a/lib/cosEventDomain/doc/src/cosEventDomainApp.xml
+++ b/lib/cosEventDomain/doc/src/cosEventDomainApp.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/notes.xml b/lib/cosEventDomain/doc/src/notes.xml
index 2c3bf16411..d4af1b66f0 100644
--- a/lib/cosEventDomain/doc/src/notes.xml
+++ b/lib/cosEventDomain/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,7 +32,23 @@
<file>notes.xml</file>
</header>
- <section><title>cosEventDomain 1.1.14</title>
+ <section><title>cosEventDomain 1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosEventDomain 1.1.14</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosEventDomain/doc/src/part.xml b/lib/cosEventDomain/doc/src/part.xml
index 20d6a8539b..2d8512fc87 100644
--- a/lib/cosEventDomain/doc/src/part.xml
+++ b/lib/cosEventDomain/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/part_notes.xml b/lib/cosEventDomain/doc/src/part_notes.xml
index 88fe24a5ae..55d4d21c3a 100644
--- a/lib/cosEventDomain/doc/src/part_notes.xml
+++ b/lib/cosEventDomain/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/doc/src/ref_man.xml b/lib/cosEventDomain/doc/src/ref_man.xml
index cee6394af2..8ad8366e5b 100644
--- a/lib/cosEventDomain/doc/src/ref_man.xml
+++ b/lib/cosEventDomain/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory_impl.erl b/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory_impl.erl
index 1729402026..21024913c1 100644
--- a/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory_impl.erl
+++ b/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl b/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl
index f5dd6d5c14..50b076df65 100644
--- a/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl
+++ b/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEventDomain/src/Makefile b/lib/cosEventDomain/src/Makefile
index b4b74bd192..da8dcf08b6 100644
--- a/lib/cosEventDomain/src/Makefile
+++ b/lib/cosEventDomain/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEventDomain/src/cosEventDomain.app.src b/lib/cosEventDomain/src/cosEventDomain.app.src
index 60114b6a91..f218ac853e 100644
--- a/lib/cosEventDomain/src/cosEventDomain.app.src
+++ b/lib/cosEventDomain/src/cosEventDomain.app.src
@@ -28,6 +28,6 @@
{applications, [orber, stdlib, kernel]},
{env, []},
{mod, {cosEventDomainApp, []}},
- {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-6.0",
+ {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-7.0",
"cosNotification-1.1.21"]}
]}.
diff --git a/lib/cosEventDomain/src/cosEventDomainApp.erl b/lib/cosEventDomain/src/cosEventDomainApp.erl
index 734e4deccb..be7c2f518a 100644
--- a/lib/cosEventDomain/src/cosEventDomainApp.erl
+++ b/lib/cosEventDomain/src/cosEventDomainApp.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -36,9 +37,6 @@
%%--------------- EXPORTS ------------------------------------
%% External MISC
-export([get_option/3,
- create_name/2,
- create_name/1,
- create_id/0,
create_id/1,
is_debug_compiled/0,
install/0,
@@ -222,31 +220,10 @@ get_option(Key, OptionList, DefaultList) ->
{error, "Invalid option"}
end
end.
-%%-----------------------------------------------------------%
-%% function : create_name/2
-%% Arguments:
-%% Returns :
-%% Exception:
-%% Effect :
-%%------------------------------------------------------------
-create_name(Name,Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',Name,'_',MSec, '_', Sec, '_', USec]).
-
-%%-----------------------------------------------------------%
-%% function : create_name/1
-%% Arguments:
-%% Returns :
-%% Exception:
-%% Effect :
-%%------------------------------------------------------------
-create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
%%------------------------------------------------------------
-%% function : create_id/0
-%% Arguments: -
+%% function : create_id/1
+%% Arguments: CosEventDomainAdmin::DomainID (long)
%% Returns : CosEventDomainAdmin::DomainID (long)
%% Exception:
%% Purpose :
@@ -256,10 +233,6 @@ create_id(2147483647) ->
create_id(OldID) ->
OldID+1.
-
-create_id() ->
- {_A,_B,C}=now(),
- C.
%%------------------------------------------------------------
%% function : get_qos
%% Arguments:
diff --git a/lib/cosEventDomain/src/cosEventDomainApp.hrl b/lib/cosEventDomain/src/cosEventDomainApp.hrl
index 340bbc52d2..ff8b004fb9 100644
--- a/lib/cosEventDomain/src/cosEventDomainApp.hrl
+++ b/lib/cosEventDomain/src/cosEventDomainApp.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEventDomain/test/Makefile b/lib/cosEventDomain/test/Makefile
index 5b59cca401..1bbd1f1693 100644
--- a/lib/cosEventDomain/test/Makefile
+++ b/lib/cosEventDomain/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosEventDomain/test/event_domain_SUITE.erl b/lib/cosEventDomain/test/event_domain_SUITE.erl
index d568708429..75835b03a0 100644
--- a/lib/cosEventDomain/test/event_domain_SUITE.erl
+++ b/lib/cosEventDomain/test/event_domain_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEventDomain/test/generated_SUITE.erl b/lib/cosEventDomain/test/generated_SUITE.erl
index e8dbafbe75..553516bed1 100644
--- a/lib/cosEventDomain/test/generated_SUITE.erl
+++ b/lib/cosEventDomain/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosEventDomain/vsn.mk b/lib/cosEventDomain/vsn.mk
index 6317ed3c22..bdde1f6ab2 100644
--- a/lib/cosEventDomain/vsn.mk
+++ b/lib/cosEventDomain/vsn.mk
@@ -1,3 +1,2 @@
-
-COSEVENTDOMAIN_VSN = 1.1.14
+COSEVENTDOMAIN_VSN = 1.2
diff --git a/lib/cosFileTransfer/Makefile b/lib/cosFileTransfer/Makefile
index 02df603530..c811d7be8f 100644
--- a/lib/cosFileTransfer/Makefile
+++ b/lib/cosFileTransfer/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml
index 991ce19f58..3d5e4f024f 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml
index 252d14cf5e..97ea054c46 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml
index 01a9671ba5..c26449a4dd 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml
index 0c69eb3687..19caace060 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml
index 4c898e5459..67a9fa72fd 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/Makefile b/lib/cosFileTransfer/doc/src/Makefile
index d1c6616f94..96cb983ff2 100644
--- a/lib/cosFileTransfer/doc/src/Makefile
+++ b/lib/cosFileTransfer/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosFileTransfer/doc/src/book.xml b/lib/cosFileTransfer/doc/src/book.xml
index c34dd92390..c6b8e05b33 100644
--- a/lib/cosFileTransfer/doc/src/book.xml
+++ b/lib/cosFileTransfer/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/ch_contents.xml b/lib/cosFileTransfer/doc/src/ch_contents.xml
index c75b0db2c5..79b39308ab 100644
--- a/lib/cosFileTransfer/doc/src/ch_contents.xml
+++ b/lib/cosFileTransfer/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/ch_example.xml b/lib/cosFileTransfer/doc/src/ch_example.xml
index ad0d94f76b..79e47d73f4 100644
--- a/lib/cosFileTransfer/doc/src/ch_example.xml
+++ b/lib/cosFileTransfer/doc/src/ch_example.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/ch_install.xml b/lib/cosFileTransfer/doc/src/ch_install.xml
index d125d331c5..260fb14d65 100644
--- a/lib/cosFileTransfer/doc/src/ch_install.xml
+++ b/lib/cosFileTransfer/doc/src/ch_install.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/ch_introduction.xml b/lib/cosFileTransfer/doc/src/ch_introduction.xml
index 0c92d0db20..24f64cfa49 100644
--- a/lib/cosFileTransfer/doc/src/ch_introduction.xml
+++ b/lib/cosFileTransfer/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/ch_system.xml b/lib/cosFileTransfer/doc/src/ch_system.xml
index 986728a614..18f4e84e56 100644
--- a/lib/cosFileTransfer/doc/src/ch_system.xml
+++ b/lib/cosFileTransfer/doc/src/ch_system.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/cosFileTransferApp.xml b/lib/cosFileTransfer/doc/src/cosFileTransferApp.xml
index ab968f168f..b9c6ec8aad 100644
--- a/lib/cosFileTransfer/doc/src/cosFileTransferApp.xml
+++ b/lib/cosFileTransfer/doc/src/cosFileTransferApp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/notes.xml b/lib/cosFileTransfer/doc/src/notes.xml
index 1d0c826d40..9f5b7ae6e5 100644
--- a/lib/cosFileTransfer/doc/src/notes.xml
+++ b/lib/cosFileTransfer/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,7 +31,23 @@
<file>notes.xml</file>
</header>
- <section><title>cosFileTransfer 1.1.16</title>
+ <section><title>cosFileTransfer 1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosFileTransfer 1.1.16</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosFileTransfer/doc/src/part.xml b/lib/cosFileTransfer/doc/src/part.xml
index 0170bb3e31..22fa434c08 100644
--- a/lib/cosFileTransfer/doc/src/part.xml
+++ b/lib/cosFileTransfer/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/part_notes.xml b/lib/cosFileTransfer/doc/src/part_notes.xml
index cc93603331..6d383099c2 100644
--- a/lib/cosFileTransfer/doc/src/part_notes.xml
+++ b/lib/cosFileTransfer/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/doc/src/ref_man.xml b/lib/cosFileTransfer/doc/src/ref_man.xml
index 29e190b8e7..884ba809b9 100644
--- a/lib/cosFileTransfer/doc/src/ref_man.xml
+++ b/lib/cosFileTransfer/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl
index cecc42ecc1..a63cad4c6d 100644
--- a/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl
+++ b/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl
index 2800c19d46..93890629bf 100644
--- a/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl
+++ b/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl
index b7643fb30d..01281f8056 100644
--- a/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl
+++ b/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl
index 7ee189f05b..b87583976c 100644
--- a/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl
+++ b/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl
index 7a775f2b13..919aa3f2ad 100644
--- a/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl
+++ b/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/src/Makefile b/lib/cosFileTransfer/src/Makefile
index 9d3abb9bba..f9107ff48f 100644
--- a/lib/cosFileTransfer/src/Makefile
+++ b/lib/cosFileTransfer/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosFileTransfer/src/cosFileTransfer.app.src b/lib/cosFileTransfer/src/cosFileTransfer.app.src
index 21226b0c6b..033eec9700 100644
--- a/lib/cosFileTransfer/src/cosFileTransfer.app.src
+++ b/lib/cosFileTransfer/src/cosFileTransfer.app.src
@@ -38,6 +38,6 @@
{env, []},
{mod, {cosFileTransferApp, []}},
{runtime_dependencies, ["stdlib-2.0","ssl-5.3.4","orber-3.6.27","kernel-3.0",
- "inets-5.10","erts-6.0","cosProperty-1.1.17"]}
+ "inets-5.10","erts-7.0","cosProperty-1.1.17"]}
]}.
diff --git a/lib/cosFileTransfer/src/cosFileTransferApp.erl b/lib/cosFileTransfer/src/cosFileTransferApp.erl
index 443c917a97..29a7237d70 100644
--- a/lib/cosFileTransfer/src/cosFileTransferApp.erl
+++ b/lib/cosFileTransfer/src/cosFileTransferApp.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -208,8 +209,9 @@ type_check(Obj, Mod) ->
%% Effect :
%%------------------------------------------------------------
create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]).
%%-----------------------------------------------------------%
diff --git a/lib/cosFileTransfer/src/cosFileTransferApp.hrl b/lib/cosFileTransfer/src/cosFileTransferApp.hrl
index 36700a6e97..97ef8a2bde 100644
--- a/lib/cosFileTransfer/src/cosFileTransferApp.hrl
+++ b/lib/cosFileTransfer/src/cosFileTransferApp.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl b/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl
index 634dfd4b8a..0a374749ff 100644
--- a/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl
+++ b/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosFileTransfer/test/Makefile b/lib/cosFileTransfer/test/Makefile
index 35f6cc1ac2..39512d83bd 100644
--- a/lib/cosFileTransfer/test/Makefile
+++ b/lib/cosFileTransfer/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
index dfe6fabfab..3fb08dbcdd 100644
--- a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
+++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -732,8 +733,9 @@ create_file_on_source_node({'NATIVE', _}, _Config, Host, FileName, Path, Data) -
?match(ok, file:write_file(FileName, list_to_binary(Data))).
create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat([Type,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat([Type, '_', Time, '_', Unique]).
diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk
index f52a1bd800..00bfdb3087 100644
--- a/lib/cosFileTransfer/vsn.mk
+++ b/lib/cosFileTransfer/vsn.mk
@@ -1 +1 @@
-COSFILETRANSFER_VSN = 1.1.16
+COSFILETRANSFER_VSN = 1.2
diff --git a/lib/cosNotification/Makefile b/lib/cosNotification/Makefile
index 980f36191f..e04a837483 100644
--- a/lib/cosNotification/Makefile
+++ b/lib/cosNotification/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosNotification/doc/src/CosNotification.xml b/lib/cosNotification/doc/src/CosNotification.xml
index d3003ee538..8c89b8830f 100644
--- a/lib/cosNotification/doc/src/CosNotification.xml
+++ b/lib/cosNotification/doc/src/CosNotification.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml b/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
index be2314ea84..f5ffd4cdf1 100644
--- a/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml b/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml
index 7dede0ebb8..034c86fb9f 100644
--- a/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
index c31bc8668c..b06ddcc61e 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
index f242cd5a30..4bd3e7bd30 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
index 487cc8365e..7f9e980433 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
index 8655704239..f0367c2d10 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
index fca52d25b9..df93aade22 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
index 938614dd24..9305b4aed1 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
index aeac8754b6..e9dea15bcc 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
index fbece27728..9333c89cd0 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
index ee9d34e556..1638d1192e 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
index 02aaff133e..1cbb5ec491 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
index d1534f0766..d367736a62 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
index 9400f771b0..db6d273dd1 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
index 0aa08faa7f..9d0f1ee3fa 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
index a4a8f91f00..cf9d97e2d0 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
index f779820977..0b56d1b7af 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
index a9ebdca27e..ecbcc08e63 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
index 0d5df4800b..2e9d925d0d 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
index 70ee36e18f..4b6bc29aba 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml b/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml
index 403359d08f..7c128cf102 100644
--- a/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml
+++ b/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml b/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
index e2cdb49a15..fd8cba1f2d 100644
--- a/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
+++ b/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml b/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml
index 09740b0d1b..7dc522d4a5 100644
--- a/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml b/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml
index e4afb9b6c7..32467ed07e 100644
--- a/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml b/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml
index 04fdf9d7eb..c4294572df 100644
--- a/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml b/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml
index 72720f21ea..6fa16dc363 100644
--- a/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/Makefile b/lib/cosNotification/doc/src/Makefile
index 800d633909..d0d3ec6bdf 100644
--- a/lib/cosNotification/doc/src/Makefile
+++ b/lib/cosNotification/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosNotification/doc/src/book.xml b/lib/cosNotification/doc/src/book.xml
index da21f23f7f..80515f9654 100644
--- a/lib/cosNotification/doc/src/book.xml
+++ b/lib/cosNotification/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_BNF.xml b/lib/cosNotification/doc/src/ch_BNF.xml
index 127069dff3..b9f411d34f 100644
--- a/lib/cosNotification/doc/src/ch_BNF.xml
+++ b/lib/cosNotification/doc/src/ch_BNF.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_QoS.xml b/lib/cosNotification/doc/src/ch_QoS.xml
index 2ed35f8d68..147761d37a 100644
--- a/lib/cosNotification/doc/src/ch_QoS.xml
+++ b/lib/cosNotification/doc/src/ch_QoS.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_contents.xml b/lib/cosNotification/doc/src/ch_contents.xml
index dc94a067ef..bfa2cebb07 100644
--- a/lib/cosNotification/doc/src/ch_contents.xml
+++ b/lib/cosNotification/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_example.xml b/lib/cosNotification/doc/src/ch_example.xml
index 2710acc04d..2d368730d3 100644
--- a/lib/cosNotification/doc/src/ch_example.xml
+++ b/lib/cosNotification/doc/src/ch_example.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_install.xml b/lib/cosNotification/doc/src/ch_install.xml
index 4b10ea5ffa..41e9461d20 100644
--- a/lib/cosNotification/doc/src/ch_install.xml
+++ b/lib/cosNotification/doc/src/ch_install.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_introduction.xml b/lib/cosNotification/doc/src/ch_introduction.xml
index 82a4a2d66f..fcd15fd2bc 100644
--- a/lib/cosNotification/doc/src/ch_introduction.xml
+++ b/lib/cosNotification/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ch_system.xml b/lib/cosNotification/doc/src/ch_system.xml
index 2efda9e5cd..a9a444afdc 100644
--- a/lib/cosNotification/doc/src/ch_system.xml
+++ b/lib/cosNotification/doc/src/ch_system.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/cosNotificationApp.xml b/lib/cosNotification/doc/src/cosNotificationApp.xml
index a11de06a11..e2f7f2f2f2 100644
--- a/lib/cosNotification/doc/src/cosNotificationApp.xml
+++ b/lib/cosNotification/doc/src/cosNotificationApp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml
index 2e4f922142..f896d219b5 100644
--- a/lib/cosNotification/doc/src/notes.xml
+++ b/lib/cosNotification/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,7 +32,37 @@
<file>notes.xml</file>
</header>
- <section><title>cosNotification 1.1.21</title>
+ <section><title>cosNotification 1.2.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Suppress Dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-12862</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosNotification 1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosNotification 1.1.21</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosNotification/doc/src/part.xml b/lib/cosNotification/doc/src/part.xml
index 99770639c0..2f3d45e63d 100644
--- a/lib/cosNotification/doc/src/part.xml
+++ b/lib/cosNotification/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/part_notes.xml b/lib/cosNotification/doc/src/part_notes.xml
index 83fadb868e..22ede75ca1 100644
--- a/lib/cosNotification/doc/src/part_notes.xml
+++ b/lib/cosNotification/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/doc/src/ref_man.xml b/lib/cosNotification/doc/src/ref_man.xml
index 0e729be80a..65197fac37 100644
--- a/lib/cosNotification/doc/src/ref_man.xml
+++ b/lib/cosNotification/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosNotification/src/CosNotification_Common.erl b/lib/cosNotification/src/CosNotification_Common.erl
index af9b2d4368..530641b7a5 100644
--- a/lib/cosNotification/src/CosNotification_Common.erl
+++ b/lib/cosNotification/src/CosNotification_Common.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -39,8 +40,9 @@
%%--------------- EXPORTS ------------------------------------
%% External MISC
-export([get_option/3,
- create_name/2,
+ create_name/0,
create_name/1,
+ create_name/2,
create_id/0,
create_id/1,
is_debug_compiled/0,
@@ -110,17 +112,20 @@ get_option(Key, OptionList, DefaultList) ->
{error, "Invalid option"}
end
end.
-%%-----------------------------------------------------------%
-%% function : create_name/2
+
+%%------------------------------------------------------------
+%% function : create_name
%% Arguments:
%% Returns :
-%% Exception:
-%% Effect :
+%% Effect : Create a unique name to use when, for eaxmple, starting
+%% a new server.
%%------------------------------------------------------------
-create_name(Name,Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',Name,'_',MSec, '_', Sec, '_', USec]).
-
+create_name() ->
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Time,'_',Unique]).
+
+
%%-----------------------------------------------------------%
%% function : create_name/1
%% Arguments:
@@ -129,8 +134,21 @@ create_name(Name,Type) ->
%% Effect :
%%------------------------------------------------------------
create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]).
+
+%%-----------------------------------------------------------%
+%% function : create_name/2
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+create_name(Name,Type) ->
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Name,'_',Time,'_',Unique]).
%%------------------------------------------------------------
%% function : create_id/0
@@ -146,16 +164,16 @@ create_name(Type) ->
%%------------------------------------------------------------
create_id(-1) ->
1;
-create_id( 2147483647) ->
+create_id(2147483647) ->
-2147483648;
create_id(OldID) ->
OldID+1.
create_id() ->
- {_A,_B,C}=now(),
+ {_A,_B,C}=erlang:timestamp(),
C.
-%%-----------------------------------------------------------%
+%%------------------------------------------------------------
%% function : type_check
%% Arguments: Obj - objectrefernce to test.
%% Mod - Module which contains typeID/0.
diff --git a/lib/cosNotification/src/CosNotification_Definitions.hrl b/lib/cosNotification/src/CosNotification_Definitions.hrl
index 8325b5aa5e..5d85c77a22 100644
--- a/lib/cosNotification/src/CosNotification_Definitions.hrl
+++ b/lib/cosNotification/src/CosNotification_Definitions.hrl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -315,7 +316,9 @@
{tty, false},
{logfile, false},
{server_options, []}]).
--define(not_CreateDBKey, term_to_binary({now(), node()})).
+-define(not_CreateDBKey, term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()})).
-define(DEBUG_LEVEL, 3).
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl
index 5ac8c810ea..c7cecd87d4 100644
--- a/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl
index 872a786f92..ea09e7ff82 100644
--- a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
index f37a97c4a7..064c356171 100644
--- a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl
index 1c3f3d8d0b..f85f52e9df 100644
--- a/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl b/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl
index 9a7b431513..bb82eee525 100644
--- a/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl
+++ b/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl b/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl
index 042e180170..0f997049e0 100644
--- a/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl
+++ b/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -335,6 +336,7 @@ match_structured(_,_,What) ->
%% Returns : boolean() |
%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
%%-----------------------------------------------------------
+-spec match_typed(_, _, _) -> no_return().
match_typed(_OE_THIS, _State, _Data) ->
corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}).
diff --git a/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl b/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl
index f9103001f1..03c0e03be6 100644
--- a/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl
+++ b/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -297,6 +298,7 @@ match_structured(_,_,_) ->
%% Returns : boolean() , #any{} (out-type) |
%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
%%-----------------------------------------------------------
+-spec match_typed(_, _, _) -> no_return().
match_typed(_OE_THIS, _State, _Data) ->
corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}).
diff --git a/lib/cosNotification/src/Makefile b/lib/cosNotification/src/Makefile
index 13153bd7a1..72b063fd1c 100644
--- a/lib/cosNotification/src/Makefile
+++ b/lib/cosNotification/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosNotification/src/PullerConsumer_impl.erl b/lib/cosNotification/src/PullerConsumer_impl.erl
index fe6f9f8968..3f8ec5c7c5 100644
--- a/lib/cosNotification/src/PullerConsumer_impl.erl
+++ b/lib/cosNotification/src/PullerConsumer_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/PullerSupplier_impl.erl b/lib/cosNotification/src/PullerSupplier_impl.erl
index 9f12f9c742..e1956cff28 100644
--- a/lib/cosNotification/src/PullerSupplier_impl.erl
+++ b/lib/cosNotification/src/PullerSupplier_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -887,7 +888,7 @@ callAny(_OE_THIS, OE_FROM, State, EventIn, Status) ->
%% Start timers which send a message each time we should push events. Only used
%% when this objects is defined to supply sequences.
start_timer(State) ->
- TS = now(),
+ TS = erlang:timestamp(),
case catch timer:send_after(timer:seconds(?get_PacingInterval(State)),
{pacing, TS}) of
{ok,PacTRef} ->
diff --git a/lib/cosNotification/src/PusherConsumer_impl.erl b/lib/cosNotification/src/PusherConsumer_impl.erl
index 195e81ec58..c99c7ea434 100644
--- a/lib/cosNotification/src/PusherConsumer_impl.erl
+++ b/lib/cosNotification/src/PusherConsumer_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/PusherSupplier_impl.erl b/lib/cosNotification/src/PusherSupplier_impl.erl
index 51949b8c46..df0b5b77b3 100644
--- a/lib/cosNotification/src/PusherSupplier_impl.erl
+++ b/lib/cosNotification/src/PusherSupplier_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/cosNotification.app.src b/lib/cosNotification/src/cosNotification.app.src
index ad02eb4421..52ce164d46 100644
--- a/lib/cosNotification/src/cosNotification.app.src
+++ b/lib/cosNotification/src/cosNotification.app.src
@@ -117,6 +117,6 @@
{applications, [orber, stdlib, kernel]},
{env, []},
{mod, {cosNotificationApp, []}},
- {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-6.0",
+ {runtime_dependencies, ["stdlib-2.5","orber-3.6.27","kernel-3.0","erts-7.0",
"cosTime-1.1.14","cosEvent-2.1.15"]}
]}.
diff --git a/lib/cosNotification/src/cosNotificationApp.erl b/lib/cosNotification/src/cosNotificationApp.erl
index ba44163272..f6231ed47e 100644
--- a/lib/cosNotification/src/cosNotificationApp.erl
+++ b/lib/cosNotification/src/cosNotificationApp.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -221,7 +222,7 @@ start_global_factory() ->
start_global_factory(Args) when is_list(Args) ->
SO = 'CosNotification_Common':get_option(server_options, Args, ?not_DEFAULT_SETTINGS),
- Name = create_name(),
+ Name = 'CosNotification_Common':create_name(),
SPEC = ['CosNotifyChannelAdmin_EventChannelFactory',Args,
[{sup_child, true},
{regname, {global, Name}}|SO]],
@@ -432,16 +433,4 @@ init(app_init) ->
'CosNotifyChannelAdmin_EventChannel_impl']}]}}.
-
-%%------------------------------------------------------------
-%% function : create_name
-%% Arguments:
-%% Returns :
-%% Effect : Create a unique name to use when, for eaxmple, starting
-%% a new server.
-%%------------------------------------------------------------
-create_name() ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',MSec, '_', Sec, '_', USec]).
-
%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/cosNotification_Filter.erl b/lib/cosNotification/src/cosNotification_Filter.erl
index 7201f7d6e2..40e7cf02ae 100644
--- a/lib/cosNotification/src/cosNotification_Filter.erl
+++ b/lib/cosNotification/src/cosNotification_Filter.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/cosNotification_Grammar.yrl b/lib/cosNotification/src/cosNotification_Grammar.yrl
index 98233bf92d..2650efcdfe 100644
--- a/lib/cosNotification/src/cosNotification_Grammar.yrl
+++ b/lib/cosNotification/src/cosNotification_Grammar.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -135,16 +136,17 @@ Erlang code.
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/cosNotification_Scanner.erl b/lib/cosNotification/src/cosNotification_Scanner.erl
index e9c54319f0..e79f0380b0 100644
--- a/lib/cosNotification/src/cosNotification_Scanner.erl
+++ b/lib/cosNotification/src/cosNotification_Scanner.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/src/cosNotification_eventDB.erl b/lib/cosNotification/src/cosNotification_eventDB.erl
index 89332d53f2..cd3c74d617 100644
--- a/lib/cosNotification/src/cosNotification_eventDB.erl
+++ b/lib/cosNotification/src/cosNotification_eventDB.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -71,10 +72,8 @@
%% that the first and last Key change place. {K1,K2}<->{K2,K1} and
%% {K1,K2,K3}<->{K3,K2,K1}.
%%----------------------------------------------------------------------
-
-module(cosNotification_eventDB).
-
%%--------------- INCLUDES -----------------------------------
-include_lib("orber/include/corba.hrl").
-include_lib("orber/include/ifr_types.hrl").
@@ -221,16 +220,16 @@ gc_events(DBRef, _Priority) when ?is_TimeoutNotUsed(DBRef) ->
gc_events(DBRef, _Priority) when ?is_StopTNotSupported(DBRef) ->
ok;
gc_events(DBRef, Priority) ->
- {M,S,U} = now(),
+ TS = erlang:monotonic_time(),
+ {resolution, TR} = lists:keyfind(resolution, 1, erlang:system_info(os_monotonic_time_source)),
case get(oe_GC_timestamp) of
- Num when {M,S,U} > Num ->
- put(oe_GC_timestamp, {M,S+?get_GCTime(DBRef),U}),
+ Num when TS > Num ->
+ put(oe_GC_timestamp, TS + ?get_GCTime(DBRef) * TR),
spawn_link(?MODULE, gc_start, [DBRef, Priority]);
_->
ok
end.
-
%%------------------------------------------------------------
%% function : gc_start
%% Arguments:
@@ -266,13 +265,13 @@ gc_discard_DB({Key1, Key2, Key3}, DRef) ->
%% Returns :
%%------------------------------------------------------------
create_FIFO_Key() ->
- {M, S, U} = erlang:now(),
+ {M, S, U} = erlang:timestamp(),
-M*1000000000000 - S*1000000 - U.
%%------------------------------------------------------------
%% function : convert_FIFO_Key
%% Arguments:
-%% Returns : A now tuple
+%% Returns : A timestamp tuple
%% Comment : Used when we must reuse a timestamp, i.e., only
%% when we must reorder the DB.
%%------------------------------------------------------------
@@ -322,7 +321,7 @@ extract_start_time(#'CosNotification_StructuredEvent'
_ ->
false
end,
- convert_time(ST, TRef, now());
+ convert_time(ST, TRef, erlang:timestamp());
extract_start_time(_, _, _) ->
false.
@@ -337,12 +336,12 @@ extract_start_time(_, _, _) ->
%% - undefined eq. value needed but no filter associated.
%% Now - used when we want to reuse old TimeStamp which
%% must be done when changing QoS.
-%% Returns : A modified return from now().
+%% Returns : A modified return from erlang:timestamp().
%%------------------------------------------------------------
extract_deadline(_, _, _, _, false) ->
false;
extract_deadline(Event, DefaultT, StopTSupported, TRef, MappingVal) ->
- extract_deadline(Event, DefaultT, StopTSupported, TRef, MappingVal, now()).
+ extract_deadline(Event, DefaultT, StopTSupported, TRef, MappingVal, erlang:timestamp()).
extract_deadline(_, _, _, _, false, _) ->
false;
@@ -403,14 +402,14 @@ get_time_diff(UTC, TRef) ->
UB-LB.
check_deadline(DL) when is_tuple(DL) ->
- {M,S,U} = now(),
+ {M,S,U} = erlang:timestamp(),
DL >= {-M,-S,-U};
check_deadline(_DL) ->
%% This case will cover if no timeout is set.
false.
check_start_time(ST) when is_tuple(ST) ->
- {M,S,U} = now(),
+ {M,S,U} = erlang:timestamp(),
ST >= {-M,-S,-U};
check_start_time(_ST) ->
%% This case will cover if no earliest delivery time is set.
@@ -1139,8 +1138,10 @@ create_db(QoS, GCTime, GCLimit, TimeRef) ->
?is_TimeoutNotUsed(DBRef), ?is_StopTNotSupported(DBRef) ->
ok;
true ->
- {M,S,U} = now(),
- put(oe_GC_timestamp, {M,S+GCTime,U})
+ TS = erlang:monotonic_time(),
+ {resolution, TR} = lists:keyfind(resolution, 1,
+ erlang:system_info(os_monotonic_time_source)),
+ put(oe_GC_timestamp, TS+GCTime*TR)
end,
DBRef.
diff --git a/lib/cosNotification/test/Makefile b/lib/cosNotification/test/Makefile
index 8c18ae7956..1db6d2bc14 100644
--- a/lib/cosNotification/test/Makefile
+++ b/lib/cosNotification/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosNotification/test/eventDB_SUITE.erl b/lib/cosNotification/test/eventDB_SUITE.erl
index 64b8b712a9..0f0faed065 100644
--- a/lib/cosNotification/test/eventDB_SUITE.erl
+++ b/lib/cosNotification/test/eventDB_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/test/generated_SUITE.erl b/lib/cosNotification/test/generated_SUITE.erl
index fcf0d3967a..fe186f24e8 100644
--- a/lib/cosNotification/test/generated_SUITE.erl
+++ b/lib/cosNotification/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/test/grammar_SUITE.erl b/lib/cosNotification/test/grammar_SUITE.erl
index 2e63924b93..eb0741ce04 100644
--- a/lib/cosNotification/test/grammar_SUITE.erl
+++ b/lib/cosNotification/test/grammar_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/test/notification_SUITE.erl b/lib/cosNotification/test/notification_SUITE.erl
index 876a82d4a5..b3884e7968 100644
--- a/lib/cosNotification/test/notification_SUITE.erl
+++ b/lib/cosNotification/test/notification_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosNotification/test/notify_test_impl.erl b/lib/cosNotification/test/notify_test_impl.erl
index dae7777089..76973db04b 100644
--- a/lib/cosNotification/test/notify_test_impl.erl
+++ b/lib/cosNotification/test/notify_test_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -289,10 +290,10 @@ disconnect_pull_supplier(_Self, State) ->
%%--------------- LOCAL FUNCTIONS ----------------------------
delay(Obj, Event, Time, Mod, F) ->
- io:format("notify_test:delay(~p) TIME: ~p~n",[Event, now()]),
+ io:format("notify_test:delay(~p) TIME: ~p~n",[Event, erlang:timestamp()]),
timer:sleep(Time),
Mod:F(Obj, Event),
- io:format("notify_test:delay() DONE: ~p~n",[now()]),
+ io:format("notify_test:delay() DONE: ~p~n",[erlang:timestamp()]),
ok.
%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/test/notify_test_server.cfg b/lib/cosNotification/test/notify_test_server.cfg
index 8621327b57..87ef97873c 100644
--- a/lib/cosNotification/test/notify_test_server.cfg
+++ b/lib/cosNotification/test/notify_test_server.cfg
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/cosNotification/test/notify_test_server.idl b/lib/cosNotification/test/notify_test_server.idl
index 4dc0202890..e7f3bccf4c 100644
--- a/lib/cosNotification/test/notify_test_server.idl
+++ b/lib/cosNotification/test/notify_test_server.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1999-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// 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%
//
diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk
index 28d6ec71bf..07b9bf474b 100644
--- a/lib/cosNotification/vsn.mk
+++ b/lib/cosNotification/vsn.mk
@@ -1,2 +1,2 @@
-COSNOTIFICATION_VSN = 1.1.21
+COSNOTIFICATION_VSN = 1.2.1
diff --git a/lib/cosProperty/Makefile b/lib/cosProperty/Makefile
index e8ec803004..da3718e99c 100644
--- a/lib/cosProperty/Makefile
+++ b/lib/cosProperty/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml
index 925b63e657..9f5b79ce08 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml
index 758af6396c..f95e98b1af 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml
index 1babf7776b..8a204d536c 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml
index 78629d6702..5c5000858f 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml
index 607cb791ae..39b2548f5d 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml
index e9761181e2..a8e843ca95 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/Makefile b/lib/cosProperty/doc/src/Makefile
index 1624479808..5fd117c01a 100644
--- a/lib/cosProperty/doc/src/Makefile
+++ b/lib/cosProperty/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosProperty/doc/src/book.xml b/lib/cosProperty/doc/src/book.xml
index 4d249a3753..4ed3c57edf 100644
--- a/lib/cosProperty/doc/src/book.xml
+++ b/lib/cosProperty/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/ch_contents.xml b/lib/cosProperty/doc/src/ch_contents.xml
index 80eee4affe..e054a2aa12 100644
--- a/lib/cosProperty/doc/src/ch_contents.xml
+++ b/lib/cosProperty/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/ch_example.xml b/lib/cosProperty/doc/src/ch_example.xml
index fab5cfaa5f..f4e990b876 100644
--- a/lib/cosProperty/doc/src/ch_example.xml
+++ b/lib/cosProperty/doc/src/ch_example.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/ch_install.xml b/lib/cosProperty/doc/src/ch_install.xml
index c7f1734b94..9df82bc794 100644
--- a/lib/cosProperty/doc/src/ch_install.xml
+++ b/lib/cosProperty/doc/src/ch_install.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/ch_introduction.xml b/lib/cosProperty/doc/src/ch_introduction.xml
index f2064785c5..7e79e58f18 100644
--- a/lib/cosProperty/doc/src/ch_introduction.xml
+++ b/lib/cosProperty/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/cosProperty.xml b/lib/cosProperty/doc/src/cosProperty.xml
index 67116292d5..e0eaca4f1d 100644
--- a/lib/cosProperty/doc/src/cosProperty.xml
+++ b/lib/cosProperty/doc/src/cosProperty.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml
index 739f41617f..fe6983c10f 100644
--- a/lib/cosProperty/doc/src/notes.xml
+++ b/lib/cosProperty/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,7 +32,23 @@
<file>notes.xml</file>
</header>
- <section><title>cosProperty 1.1.17</title>
+ <section><title>cosProperty 1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosProperty 1.1.17</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosProperty/doc/src/part.xml b/lib/cosProperty/doc/src/part.xml
index c726c68e8b..6be119f0cc 100644
--- a/lib/cosProperty/doc/src/part.xml
+++ b/lib/cosProperty/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/part_notes.xml b/lib/cosProperty/doc/src/part_notes.xml
index 74a1641e67..07af5dac14 100644
--- a/lib/cosProperty/doc/src/part_notes.xml
+++ b/lib/cosProperty/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/doc/src/ref_man.xml b/lib/cosProperty/doc/src/ref_man.xml
index 9a1fd13758..55502ecb9b 100644
--- a/lib/cosProperty/doc/src/ref_man.xml
+++ b/lib/cosProperty/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl
index a7769cea4d..3c930ecc2c 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl
index fc5cddd7c3..976ecda89f 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl
index 202df42b61..29093b8ad6 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
index 157b243c53..bf046530d8 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -128,7 +129,9 @@
%% {stop, Reason}
%%----------------------------------------------------------------------
init({DefMode, AllowedTypes, AllowedProperties, InitProperties, MyType}) ->
- Key = term_to_binary({now(), node()}),
+ Key = term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}),
_F = ?write_function(#oe_CosPropertyService{key=Key,
properties=InitProperties}),
write_result(mnesia:transaction(_F)),
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl
index 4bc29b99ac..8b4b5a2769 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/src/Makefile b/lib/cosProperty/src/Makefile
index d7b75d8bc5..cd559e168f 100644
--- a/lib/cosProperty/src/Makefile
+++ b/lib/cosProperty/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosProperty/src/cosProperty.app.src b/lib/cosProperty/src/cosProperty.app.src
index b977bb5984..7fad7a602a 100644
--- a/lib/cosProperty/src/cosProperty.app.src
+++ b/lib/cosProperty/src/cosProperty.app.src
@@ -43,5 +43,5 @@
{env, []},
{mod, {cosProperty, []}},
{runtime_dependencies, ["stdlib-2.0","orber-3.6.27","mnesia-4.12",
- "kernel-3.0","erts-6.0"]}
+ "kernel-3.0","erts-7.0"]}
]}.
diff --git a/lib/cosProperty/src/cosProperty.erl b/lib/cosProperty/src/cosProperty.erl
index 2368ee3db6..e94d200c2f 100644
--- a/lib/cosProperty/src/cosProperty.erl
+++ b/lib/cosProperty/src/cosProperty.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -406,8 +407,9 @@ type_check(Obj, Mod) ->
%% Effect :
%%------------------------------------------------------------
create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]).
%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosProperty/src/cosProperty.hrl b/lib/cosProperty/src/cosProperty.hrl
index 2755b890c8..4bc71e5465 100644
--- a/lib/cosProperty/src/cosProperty.hrl
+++ b/lib/cosProperty/src/cosProperty.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/test/Makefile b/lib/cosProperty/test/Makefile
index ba634c77cf..ec928a9789 100644
--- a/lib/cosProperty/test/Makefile
+++ b/lib/cosProperty/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosProperty/test/generated_SUITE.erl b/lib/cosProperty/test/generated_SUITE.erl
index 1007ee2180..0422e0d018 100644
--- a/lib/cosProperty/test/generated_SUITE.erl
+++ b/lib/cosProperty/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/test/property_SUITE.erl b/lib/cosProperty/test/property_SUITE.erl
index f440ffc2a1..94765e7479 100644
--- a/lib/cosProperty/test/property_SUITE.erl
+++ b/lib/cosProperty/test/property_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk
index 0f546a2da8..d96508c2d2 100644
--- a/lib/cosProperty/vsn.mk
+++ b/lib/cosProperty/vsn.mk
@@ -1,2 +1,2 @@
-COSPROPERTY_VSN = 1.1.17
+COSPROPERTY_VSN = 1.2
diff --git a/lib/cosTime/Makefile b/lib/cosTime/Makefile
index b8628ac3c4..8f17b0249d 100644
--- a/lib/cosTime/Makefile
+++ b/lib/cosTime/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTime/doc/src/CosTime_TIO.xml b/lib/cosTime/doc/src/CosTime_TIO.xml
index edc3324e0f..622b2eaeaf 100644
--- a/lib/cosTime/doc/src/CosTime_TIO.xml
+++ b/lib/cosTime/doc/src/CosTime_TIO.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTime/doc/src/CosTime_TimeService.xml b/lib/cosTime/doc/src/CosTime_TimeService.xml
index a432f6ba10..076eb2a73c 100644
--- a/lib/cosTime/doc/src/CosTime_TimeService.xml
+++ b/lib/cosTime/doc/src/CosTime_TimeService.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTime/doc/src/CosTime_UTO.xml b/lib/cosTime/doc/src/CosTime_UTO.xml
index 9c29f8552d..eb41a2133a 100644
--- a/lib/cosTime/doc/src/CosTime_UTO.xml
+++ b/lib/cosTime/doc/src/CosTime_UTO.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml b/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml
index 8ce741334f..d5b45f4280 100644
--- a/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml
+++ b/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml b/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml
index b1c1c5400d..0620acd0af 100644
--- a/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml
+++ b/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTime/doc/src/Makefile b/lib/cosTime/doc/src/Makefile
index 2ed55a3bfa..ec2692e538 100644
--- a/lib/cosTime/doc/src/Makefile
+++ b/lib/cosTime/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTime/doc/src/book.xml b/lib/cosTime/doc/src/book.xml
index b6c332d469..93cf36acdf 100644
--- a/lib/cosTime/doc/src/book.xml
+++ b/lib/cosTime/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/ch_contents.xml b/lib/cosTime/doc/src/ch_contents.xml
index 78d148eaaf..d016e3404a 100644
--- a/lib/cosTime/doc/src/ch_contents.xml
+++ b/lib/cosTime/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/ch_example.xml b/lib/cosTime/doc/src/ch_example.xml
index f0196cd465..efea0814c9 100644
--- a/lib/cosTime/doc/src/ch_example.xml
+++ b/lib/cosTime/doc/src/ch_example.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/ch_install.xml b/lib/cosTime/doc/src/ch_install.xml
index e4a8476fcf..982845ea6f 100644
--- a/lib/cosTime/doc/src/ch_install.xml
+++ b/lib/cosTime/doc/src/ch_install.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/ch_introduction.xml b/lib/cosTime/doc/src/ch_introduction.xml
index d6de5df38c..c0c62e7b09 100644
--- a/lib/cosTime/doc/src/ch_introduction.xml
+++ b/lib/cosTime/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/cosTime.xml b/lib/cosTime/doc/src/cosTime.xml
index dfb2c68602..f052191c03 100644
--- a/lib/cosTime/doc/src/cosTime.xml
+++ b/lib/cosTime/doc/src/cosTime.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTime/doc/src/notes.xml b/lib/cosTime/doc/src/notes.xml
index f218f19a6b..bf75f7f617 100644
--- a/lib/cosTime/doc/src/notes.xml
+++ b/lib/cosTime/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,7 +33,37 @@
<file>notes.xml</file>
</header>
- <section><title>cosTime 1.1.14</title>
+ <section><title>cosTime 1.2.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Suppress Dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-12862</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosTime 1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosTime 1.1.14</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosTime/doc/src/part.xml b/lib/cosTime/doc/src/part.xml
index cae3232e8d..3a3e3fcf6e 100644
--- a/lib/cosTime/doc/src/part.xml
+++ b/lib/cosTime/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/part_notes.xml b/lib/cosTime/doc/src/part_notes.xml
index b0667abb38..f441961b7c 100644
--- a/lib/cosTime/doc/src/part_notes.xml
+++ b/lib/cosTime/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/doc/src/ref_man.xml b/lib/cosTime/doc/src/ref_man.xml
index 1f4fb06c2c..be44a80b91 100644
--- a/lib/cosTime/doc/src/ref_man.xml
+++ b/lib/cosTime/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTime/src/CosTime_TIO_impl.erl b/lib/cosTime/src/CosTime_TIO_impl.erl
index d6d4ee894b..7dc3c743bd 100644
--- a/lib/cosTime/src/CosTime_TIO_impl.erl
+++ b/lib/cosTime/src/CosTime_TIO_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTime/src/CosTime_TimeService_impl.erl b/lib/cosTime/src/CosTime_TimeService_impl.erl
index bac4ae087c..72c65757ad 100644
--- a/lib/cosTime/src/CosTime_TimeService_impl.erl
+++ b/lib/cosTime/src/CosTime_TimeService_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -106,6 +107,7 @@ universal_time(OE_THIS, State) ->
%% Arguments:
%% Returns : {'EXCEPTION", #'CosTime_TimeUnavailable'{}}
%%-----------------------------------------------------------
+-spec secure_universal_time(_, _) -> no_return().
secure_universal_time(_OE_THIS, _State) ->
corba:raise(#'CosTime_TimeUnavailable'{}).
@@ -166,7 +168,7 @@ new_interval(_, _, _, _) ->
create_universal_time() ->
%% Time is supposed to be #100 nano-secs passed.
%% We add micro secs for a greater precision.
- {MS,S,US} = now(),
+ {MS,S,US} = erlang:timestamp(),
case catch calendar:datetime_to_gregorian_seconds(
calendar:now_to_universal_time({MS,S,US})) of
Secs when is_integer(Secs) ->
diff --git a/lib/cosTime/src/CosTime_UTO_impl.erl b/lib/cosTime/src/CosTime_UTO_impl.erl
index b35e215e90..9453881c65 100644
--- a/lib/cosTime/src/CosTime_UTO_impl.erl
+++ b/lib/cosTime/src/CosTime_UTO_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl b/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
index 5885691e87..6ebcafef77 100644
--- a/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
+++ b/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl b/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl
index b324ecbecd..fe9b2013b8 100644
--- a/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl
+++ b/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTime/src/Makefile b/lib/cosTime/src/Makefile
index 0ab2b414ce..7a14db6974 100644
--- a/lib/cosTime/src/Makefile
+++ b/lib/cosTime/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTime/src/cosTime.app.src b/lib/cosTime/src/cosTime.app.src
index cd01de35cb..ac71fe1b29 100644
--- a/lib/cosTime/src/cosTime.app.src
+++ b/lib/cosTime/src/cosTime.app.src
@@ -27,6 +27,6 @@
{applications, [orber, stdlib, kernel]},
{env, []},
{mod, {cosTime, []}},
- {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-6.0",
+ {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-7.0",
"cosEvent-2.1.15"]}
]}.
diff --git a/lib/cosTime/src/cosTime.erl b/lib/cosTime/src/cosTime.erl
index f7d03650af..afb611beff 100644
--- a/lib/cosTime/src/cosTime.erl
+++ b/lib/cosTime/src/cosTime.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -333,8 +334,9 @@ type_check(Obj, Mod) ->
%%------------------------------------------------------------
create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]).
%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosTime/src/cosTimeApp.hrl b/lib/cosTime/src/cosTimeApp.hrl
index f3082816f7..74c9bcca5d 100644
--- a/lib/cosTime/src/cosTimeApp.hrl
+++ b/lib/cosTime/src/cosTimeApp.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -41,7 +42,7 @@
-define(max_TimeT, 18446744073709551616).
%% The calendar module uses year 0 as base for gregorian functions.
-%% 'ABSOULTE_TIME_DIFF' is #seconfs from year 0 until 15 october 1582, 00:00.
+%% 'ABSOULTE_TIME_DIFF' is #seconds from year 0 until 15 october 1582, 00:00.
-define(ABSOLUTE_TIME_DIFF, 49947926400).
%% As above but diff year 0 to 00:00 GMT, January 1, 1970
-define(STANDARD_TIME_DIFF, 62167219200).
diff --git a/lib/cosTime/test/Makefile b/lib/cosTime/test/Makefile
index 89d5a4a38e..aabf855af5 100644
--- a/lib/cosTime/test/Makefile
+++ b/lib/cosTime/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTime/test/generated_SUITE.erl b/lib/cosTime/test/generated_SUITE.erl
index 119a5e322c..2e63b6f50e 100644
--- a/lib/cosTime/test/generated_SUITE.erl
+++ b/lib/cosTime/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTime/test/time_SUITE.erl b/lib/cosTime/test/time_SUITE.erl
index c92095eba5..0e805aed05 100644
--- a/lib/cosTime/test/time_SUITE.erl
+++ b/lib/cosTime/test/time_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTime/vsn.mk b/lib/cosTime/vsn.mk
index 9e9e5c0250..39b457b53b 100644
--- a/lib/cosTime/vsn.mk
+++ b/lib/cosTime/vsn.mk
@@ -1,3 +1,2 @@
-COSTIME_VSN = 1.1.14
-
+COSTIME_VSN = 1.2.1
diff --git a/lib/cosTransactions/Makefile b/lib/cosTransactions/Makefile
index fddfa63db5..459fc8b271 100644
--- a/lib/cosTransactions/Makefile
+++ b/lib/cosTransactions/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTransactions/doc/src/CosTransactions_Control.xml b/lib/cosTransactions/doc/src/CosTransactions_Control.xml
index 998821c5d8..2092ca42dd 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_Control.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_Control.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_Coordinator.xml b/lib/cosTransactions/doc/src/CosTransactions_Coordinator.xml
index 4b76ae19b8..64b1f0dd0f 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_Coordinator.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_Coordinator.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml b/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml
index 339adac638..5888f1ada9 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_Resource.xml b/lib/cosTransactions/doc/src/CosTransactions_Resource.xml
index cee0829710..3e6e0eb7d6 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_Resource.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_Resource.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml b/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml
index 12115036bc..fec970db33 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_Synchronization.xml b/lib/cosTransactions/doc/src/CosTransactions_Synchronization.xml
index 89a0eb97c4..2181134086 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_Synchronization.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_Synchronization.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_Terminator.xml b/lib/cosTransactions/doc/src/CosTransactions_Terminator.xml
index 6f35235114..ef92e327c5 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_Terminator.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_Terminator.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml b/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml
index e2e5b63bca..00919d3e5a 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_TransactionalObject.xml b/lib/cosTransactions/doc/src/CosTransactions_TransactionalObject.xml
index a249a89c71..f7db880f31 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_TransactionalObject.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_TransactionalObject.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/Makefile b/lib/cosTransactions/doc/src/Makefile
index 7247c0dec7..4aaba44f96 100644
--- a/lib/cosTransactions/doc/src/Makefile
+++ b/lib/cosTransactions/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTransactions/doc/src/book.xml b/lib/cosTransactions/doc/src/book.xml
index 460b7cce9a..723c5199cb 100644
--- a/lib/cosTransactions/doc/src/book.xml
+++ b/lib/cosTransactions/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/ch_contents.xml b/lib/cosTransactions/doc/src/ch_contents.xml
index bf11e0137e..d8d9395e65 100644
--- a/lib/cosTransactions/doc/src/ch_contents.xml
+++ b/lib/cosTransactions/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/ch_example.xml b/lib/cosTransactions/doc/src/ch_example.xml
index 64fdf7293f..6e1ec1d600 100644
--- a/lib/cosTransactions/doc/src/ch_example.xml
+++ b/lib/cosTransactions/doc/src/ch_example.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/ch_install.xml b/lib/cosTransactions/doc/src/ch_install.xml
index 0de5db539b..2b518c8678 100644
--- a/lib/cosTransactions/doc/src/ch_install.xml
+++ b/lib/cosTransactions/doc/src/ch_install.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/ch_introduction.xml b/lib/cosTransactions/doc/src/ch_introduction.xml
index 7edd2a57d5..e1fade751c 100644
--- a/lib/cosTransactions/doc/src/ch_introduction.xml
+++ b/lib/cosTransactions/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/ch_skeletons.xml b/lib/cosTransactions/doc/src/ch_skeletons.xml
index 451db4ae70..8c7e07ed59 100644
--- a/lib/cosTransactions/doc/src/ch_skeletons.xml
+++ b/lib/cosTransactions/doc/src/ch_skeletons.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/cosTransactions.xml b/lib/cosTransactions/doc/src/cosTransactions.xml
index 9b1bc5c428..e0adb7fead 100644
--- a/lib/cosTransactions/doc/src/cosTransactions.xml
+++ b/lib/cosTransactions/doc/src/cosTransactions.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/notes.xml b/lib/cosTransactions/doc/src/notes.xml
index 4b20f23efb..76d14962b7 100644
--- a/lib/cosTransactions/doc/src/notes.xml
+++ b/lib/cosTransactions/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,7 +33,37 @@
<file>notes.xml</file>
</header>
- <section><title>cosTransactions 1.2.14</title>
+ <section><title>cosTransactions 1.3.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Suppress Dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-12862</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosTransactions 1.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>cosTransactions 1.2.14</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/cosTransactions/doc/src/part.xml b/lib/cosTransactions/doc/src/part.xml
index a5331ceb05..934b27311d 100644
--- a/lib/cosTransactions/doc/src/part.xml
+++ b/lib/cosTransactions/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/part_notes.xml b/lib/cosTransactions/doc/src/part_notes.xml
index 8ccf52b17c..05f98e653a 100644
--- a/lib/cosTransactions/doc/src/part_notes.xml
+++ b/lib/cosTransactions/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/doc/src/ref_man.xml b/lib/cosTransactions/doc/src/ref_man.xml
index 663ccb06bc..bcc489ed0f 100644
--- a/lib/cosTransactions/doc/src/ref_man.xml
+++ b/lib/cosTransactions/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/cosTransactions/examples/Makefile b/lib/cosTransactions/examples/Makefile
index 348f506e2e..1289f4c845 100644
--- a/lib/cosTransactions/examples/Makefile
+++ b/lib/cosTransactions/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTransactions/src/CosTransactions_Terminator_impl.erl b/lib/cosTransactions/src/CosTransactions_Terminator_impl.erl
index 768e63950c..9b8a0d93e2 100644
--- a/lib/cosTransactions/src/CosTransactions_Terminator_impl.erl
+++ b/lib/cosTransactions/src/CosTransactions_Terminator_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/src/CosTransactions_TransactionFactory_impl.erl b/lib/cosTransactions/src/CosTransactions_TransactionFactory_impl.erl
index 36e37e2d5f..e24bcb9a04 100644
--- a/lib/cosTransactions/src/CosTransactions_TransactionFactory_impl.erl
+++ b/lib/cosTransactions/src/CosTransactions_TransactionFactory_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -145,8 +146,8 @@ create(_Self, State, TimeOut) when is_integer(TimeOut) ->
_ ->
if
TimeOut > 0 ->
- {MegaSecs, Secs, _Microsecs} = erlang:now(),
- EState2 = ?tr_set_alarm(EState, MegaSecs*1000000+Secs+TimeOut),
+ TimeStampSec = erlang:monotonic_time(seconds),
+ EState2 = ?tr_set_alarm(EState, TimeStampSec+TimeOut),
EState3 = ?tr_set_timeout(EState2, TimeOut*1000),
ETraP = ?tr_start_child(?SUP_ETRAP(EState3)),
{reply, ETraP, State};
@@ -168,6 +169,7 @@ create(_Self, _State, _TimeOut) ->
%% Effect :
%%------------------------------------------------------------
+-spec recreate(_, _, _) -> no_return().
recreate(_Self, _State, #'CosTransactions_PropagationContext'{current = _C}) ->
corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_YES}).
%recreate(Self, State, #'CosTransactions_PropagationContext'{current = C}) ->
diff --git a/lib/cosTransactions/src/ETraP_Common.erl b/lib/cosTransactions/src/ETraP_Common.erl
index dd68e9b038..a5f2bf4831 100644
--- a/lib/cosTransactions/src/ETraP_Common.erl
+++ b/lib/cosTransactions/src/ETraP_Common.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -86,8 +87,9 @@ get_option(Key, OptionList, DefaultList) ->
%%------------------------------------------------------------
create_name(Name,Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',Name,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Name,'_',Time,'_',Unique]).
%%------------------------------------------------------------
%% function : create_name/1
@@ -98,8 +100,9 @@ create_name(Name,Type) ->
%%------------------------------------------------------------
create_name(Type) ->
- {MSec, Sec, USec} = erlang:now(),
- lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+ Time = erlang:system_time(),
+ Unique = erlang:unique_integer([positive]),
+ lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]).
%%------------------------------------------------------------
%% function : try_timeout
@@ -114,10 +117,9 @@ try_timeout(TimeoutAt) ->
infinity ->
false;
_->
- {MegaSecs, Secs, _Microsecs} = erlang:now(),
- Time = MegaSecs*1000000+Secs,
+ TimeSec = erlang:monotonic_time(seconds),
if
- Time < TimeoutAt ->
+ TimeSec < TimeoutAt ->
false;
true ->
true
diff --git a/lib/cosTransactions/src/ETraP_Common.hrl b/lib/cosTransactions/src/ETraP_Common.hrl
index 97e88244a3..971aef669a 100644
--- a/lib/cosTransactions/src/ETraP_Common.hrl
+++ b/lib/cosTransactions/src/ETraP_Common.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/cosTransactions/src/ETraP_Server_impl.erl b/lib/cosTransactions/src/ETraP_Server_impl.erl
index e2c5d88f9d..5c7b5f6350 100644
--- a/lib/cosTransactions/src/ETraP_Server_impl.erl
+++ b/lib/cosTransactions/src/ETraP_Server_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -38,7 +39,8 @@
%% Log files are created in the current directory, which is why the
%% application requires read/write rights for current directory. The
%% file name looks like:
-%% "oe_nonode@nohost_subc_939_383117_295538" (the last part is now())
+%% "oe_nonode@nohost_subc_1429872479809947099_438" (the two last parts are
+%% erlang:system_time() and erlang:unique_integer([positive]))
%% It is equal to what the object is started as, i.e., {regname, {global, X}}.
%%
%% If the application is unable to read the log it will exit and the
@@ -673,6 +675,7 @@ is_same_transaction(Self, {Env, Local}, Coordinator) ->
%% Effect :
%%------------------------------------------------------------
+-spec is_related_transaction(_, _, _) -> no_return().
is_related_transaction(_Self, {_Env, _Local}, _Coordinator) ->
corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_YES}).
% type_check(?tr_get_typeCheck(Env), ?tr_Coordinator,
@@ -687,6 +690,7 @@ is_related_transaction(_Self, {_Env, _Local}, _Coordinator) ->
%% Effect :
%%------------------------------------------------------------
+-spec is_ancestor_transaction(_, _, _) -> no_return().
is_ancestor_transaction(_Self, {_Env, _Local}, _Coordinator) ->
corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_YES}).
% type_check(?tr_get_typeCheck(Env), ?tr_Coordinator,
@@ -824,6 +828,7 @@ register_subtran_aware(Self, {Env, Local}, SubTrAwareResource) ->
%% Effect :
%%------------------------------------------------------------
+-spec register_synchronization(_, _, _) -> no_return().
register_synchronization(_Self, {_Env, _Local}, _Synchronization) ->
corba:raise(#'CosTransactions_SynchronizationUnavailable'{}).
@@ -948,6 +953,7 @@ create_subtransaction(Self, {Env, Local}) ->
%% Effect :
%%------------------------------------------------------------
+-spec get_txcontext(_, _) -> no_return().
get_txcontext(_Self, {_Env, _Local}) ->
corba:raise(#'CosTransactions_Unavailable'{}).
diff --git a/lib/cosTransactions/src/Makefile b/lib/cosTransactions/src/Makefile
index 7b4a9cf858..90e1e5130f 100644
--- a/lib/cosTransactions/src/Makefile
+++ b/lib/cosTransactions/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTransactions/src/cosTransactions.app.src b/lib/cosTransactions/src/cosTransactions.app.src
index 6b99915ad6..074d82f487 100644
--- a/lib/cosTransactions/src/cosTransactions.app.src
+++ b/lib/cosTransactions/src/cosTransactions.app.src
@@ -40,5 +40,5 @@
{applications, [orber, stdlib, kernel]},
{env, []},
{mod, {cosTransactions, []}},
- {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-6.0"]}
+ {runtime_dependencies, ["stdlib-2.0","orber-3.6.27","kernel-3.0","erts-7.0"]}
]}.
diff --git a/lib/cosTransactions/src/cosTransactions.erl b/lib/cosTransactions/src/cosTransactions.erl
index ffc01f50a4..6284b8abd1 100644
--- a/lib/cosTransactions/src/cosTransactions.erl
+++ b/lib/cosTransactions/src/cosTransactions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/src/etrap_logmgr.erl b/lib/cosTransactions/src/etrap_logmgr.erl
index a418d782e3..188cc27d35 100644
--- a/lib/cosTransactions/src/etrap_logmgr.erl
+++ b/lib/cosTransactions/src/etrap_logmgr.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/test/Makefile b/lib/cosTransactions/test/Makefile
index 53ff93ba16..3cdb05e7ef 100644
--- a/lib/cosTransactions/test/Makefile
+++ b/lib/cosTransactions/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/cosTransactions/test/etrap_test.cfg b/lib/cosTransactions/test/etrap_test.cfg
index 4f2b9e125d..a047a6fb1b 100644
--- a/lib/cosTransactions/test/etrap_test.cfg
+++ b/lib/cosTransactions/test/etrap_test.cfg
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/cosTransactions/test/etrap_test.idl b/lib/cosTransactions/test/etrap_test.idl
index 7573cc1a36..6b1dbbc8f8 100644
--- a/lib/cosTransactions/test/etrap_test.idl
+++ b/lib/cosTransactions/test/etrap_test.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1999-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// 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%
//
diff --git a/lib/cosTransactions/test/etrap_test_lib.erl b/lib/cosTransactions/test/etrap_test_lib.erl
index 18a1cda35b..9774222531 100644
--- a/lib/cosTransactions/test/etrap_test_lib.erl
+++ b/lib/cosTransactions/test/etrap_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/test/etrap_test_lib.hrl b/lib/cosTransactions/test/etrap_test_lib.hrl
index 127d803515..01e507d5ac 100644
--- a/lib/cosTransactions/test/etrap_test_lib.hrl
+++ b/lib/cosTransactions/test/etrap_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/test/etrap_test_server_impl.erl b/lib/cosTransactions/test/etrap_test_server_impl.erl
index 69c823f3ca..e5d360808f 100644
--- a/lib/cosTransactions/test/etrap_test_server_impl.erl
+++ b/lib/cosTransactions/test/etrap_test_server_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/cosTransactions/test/generated_SUITE.erl b/lib/cosTransactions/test/generated_SUITE.erl
index 23ba631b69..9d5cfb154a 100644
--- a/lib/cosTransactions/test/generated_SUITE.erl
+++ b/lib/cosTransactions/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/test/transactions_SUITE.erl b/lib/cosTransactions/test/transactions_SUITE.erl
index 6480b956b3..0f06c3d262 100644
--- a/lib/cosTransactions/test/transactions_SUITE.erl
+++ b/lib/cosTransactions/test/transactions_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/cosTransactions/vsn.mk b/lib/cosTransactions/vsn.mk
index 7aed212523..3a18cae384 100644
--- a/lib/cosTransactions/vsn.mk
+++ b/lib/cosTransactions/vsn.mk
@@ -1 +1 @@
-COSTRANSACTIONS_VSN = 1.2.14
+COSTRANSACTIONS_VSN = 1.3.1
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index e893c914e6..24db75bf91 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in
index 8c92b5ba1b..e66c0ca916 100644
--- a/lib/crypto/c_src/Makefile.in
+++ b/lib/crypto/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 26e2486dc2..4966701e41 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -54,6 +55,10 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+#include <openssl/modes.h>
+#endif
+
#include "crypto_callback.h"
#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_SHA224) && defined(NID_sha224)\
@@ -85,13 +90,32 @@
# define HAVE_AES_IGE
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL
+# define HAVE_GCM
+#endif
+
+#if defined(NID_chacha20) && !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+# define HAVE_CHACHA20_POLY1305
+#endif
+
#if defined(HAVE_EC)
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#endif
+#if defined(HAVE_CHACHA20_POLY1305)
+#include <openssl/chacha.h>
+#include <openssl/poly1305.h>
+
+#if !defined(CHACHA20_NONCE_LEN)
+# define CHACHA20_NONCE_LEN 8
+#endif
+#if !defined(POLY1305_TAG_LEN)
+# define POLY1305_TAG_LEN 16
+#endif
+#endif
#ifdef VALGRIND
# include <valgrind/memcheck.h>
@@ -219,6 +243,7 @@ static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_ecb_crypt(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 rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -257,6 +282,11 @@ static ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF
static ERL_NIF_TERM rand_seed_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+
+static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
/* helpers */
static void init_algorithms_types(ErlNifEnv*);
@@ -351,6 +381,7 @@ static ErlNifFunc nif_funcs[] = {
{"aes_ctr_decrypt", 3, aes_ctr_encrypt},
{"aes_ctr_stream_encrypt", 2, aes_ctr_stream_encrypt},
{"aes_ctr_stream_decrypt", 2, aes_ctr_stream_encrypt},
+ {"aes_ecb_crypt", 3, aes_ecb_crypt},
{"rand_bytes", 1, rand_bytes_1},
{"strong_rand_bytes_nif", 1, strong_rand_bytes_nif},
{"rand_bytes", 3, rand_bytes_3},
@@ -382,12 +413,20 @@ static ErlNifFunc nif_funcs[] = {
{"bf_ecb_crypt", 3, bf_ecb_crypt},
{"blowfish_ofb64_encrypt", 3, blowfish_ofb64_encrypt},
- {"ec_key_generate", 1, ec_key_generate},
+ {"ec_key_generate", 2, ec_key_generate},
{"ecdsa_sign_nif", 4, ecdsa_sign_nif},
{"ecdsa_verify_nif", 5, ecdsa_verify_nif},
{"ecdh_compute_key_nif", 3, ecdh_compute_key_nif},
- {"rand_seed_nif", 1, rand_seed_nif}
+ {"rand_seed_nif", 1, rand_seed_nif},
+
+ {"aes_gcm_encrypt", 4, aes_gcm_encrypt},
+ {"aes_gcm_decrypt", 5, aes_gcm_decrypt},
+
+ {"chacha20_poly1305_encrypt", 4, chacha20_poly1305_encrypt},
+ {"chacha20_poly1305_decrypt", 5, chacha20_poly1305_decrypt}
+
+
};
ERL_NIF_INIT(crypto,nif_funcs,load,NULL,upgrade,unload)
@@ -725,7 +764,7 @@ static ERL_NIF_TERM algo_hash[8]; /* increase when extending the list */
static int algo_pubkey_cnt;
static ERL_NIF_TERM algo_pubkey[3]; /* increase when extending the list */
static int algo_cipher_cnt;
-static ERL_NIF_TERM algo_cipher[2]; /* increase when extending the list */
+static ERL_NIF_TERM algo_cipher[4]; /* increase when extending the list */
static void init_algorithms_types(ErlNifEnv* env)
{
@@ -763,6 +802,12 @@ static void init_algorithms_types(ErlNifEnv* env)
#ifdef HAVE_AES_IGE
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_ige256");
#endif
+#if defined(HAVE_GCM)
+ algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_gcm");
+#endif
+#if defined(HAVE_CHACHA20_POLY1305)
+ algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"chacha20_poly1305");
+#endif
ASSERT(algo_hash_cnt <= sizeof(algo_hash)/sizeof(ERL_NIF_TERM));
ASSERT(algo_pubkey_cnt <= sizeof(algo_pubkey)/sizeof(ERL_NIF_TERM));
@@ -1762,6 +1807,271 @@ static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_N
return ret;
}
+static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key,Iv,AAD,In) */
+#if defined(HAVE_GCM)
+ GCM128_CONTEXT *ctx = NULL;
+ ErlNifBinary key, iv, aad, in;
+ AES_KEY aes_key;
+ unsigned char *outp;
+ ERL_NIF_TERM out, out_tag;
+
+ CHECK_OSE_CRYPTO();
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
+ || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
+ || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0
+ || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[3], &in)) {
+ return enif_make_badarg(env);
+ }
+
+ if (!(ctx = CRYPTO_gcm128_new(&aes_key, (block128_f)AES_encrypt)))
+ return atom_error;
+
+ CRYPTO_gcm128_setiv(ctx, iv.data, iv.size);
+
+ if (CRYPTO_gcm128_aad(ctx, aad.data, aad.size))
+ goto out_err;
+
+ outp = enif_make_new_binary(env, in.size, &out);
+
+ /* encrypt */
+ if (CRYPTO_gcm128_encrypt(ctx, in.data, outp, in.size))
+ goto out_err;
+
+ /* calculate the tag */
+ CRYPTO_gcm128_tag(ctx, enif_make_new_binary(env, EVP_GCM_TLS_TAG_LEN, &out_tag), EVP_GCM_TLS_TAG_LEN);
+ CRYPTO_gcm128_release(ctx);
+
+ CONSUME_REDS(env, in);
+
+ return enif_make_tuple2(env, out, out_tag);
+
+out_err:
+ CRYPTO_gcm128_release(ctx);
+ return atom_error;
+
+#else
+ return atom_notsup;
+#endif
+}
+
+static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key,Iv,AAD,In,Tag) */
+#if defined(HAVE_GCM)
+ GCM128_CONTEXT *ctx;
+ ErlNifBinary key, iv, aad, in, tag;
+ AES_KEY aes_key;
+ unsigned char *outp;
+ ERL_NIF_TERM out;
+
+ CHECK_OSE_CRYPTO();
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
+ || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
+ || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0
+ || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[3], &in)
+ || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != EVP_GCM_TLS_TAG_LEN) {
+ return enif_make_badarg(env);
+ }
+
+ if (!(ctx = CRYPTO_gcm128_new(&aes_key, (block128_f)AES_encrypt)))
+ return atom_error;
+
+ CRYPTO_gcm128_setiv(ctx, iv.data, iv.size);
+
+ if (CRYPTO_gcm128_aad(ctx, aad.data, aad.size))
+ goto out_err;
+
+ outp = enif_make_new_binary(env, in.size, &out);
+
+ /* decrypt */
+ if (CRYPTO_gcm128_decrypt(ctx, in.data, outp, in.size))
+ goto out_err;
+
+ /* calculate and check the tag */
+ if (CRYPTO_gcm128_finish(ctx, tag.data, EVP_GCM_TLS_TAG_LEN))
+ goto out_err;
+
+ CRYPTO_gcm128_release(ctx);
+ CONSUME_REDS(env, in);
+
+ return out;
+
+out_err:
+ CRYPTO_gcm128_release(ctx);
+ return atom_error;
+#else
+ return atom_notsup;
+#endif
+}
+
+#if defined(HAVE_CHACHA20_POLY1305)
+static void
+poly1305_update_with_length(poly1305_state *poly1305,
+ const unsigned char *data, size_t data_len)
+{
+ size_t j = data_len;
+ unsigned char length_bytes[8];
+ unsigned i;
+
+ for (i = 0; i < sizeof(length_bytes); i++) {
+ length_bytes[i] = j;
+ j >>= 8;
+ }
+
+ CRYPTO_poly1305_update(poly1305, data, data_len);
+ CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
+}
+#endif
+
+static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key,Iv,AAD,In) */
+#if defined(HAVE_CHACHA20_POLY1305)
+ ErlNifBinary key, iv, aad, in;
+ unsigned char *outp;
+ ERL_NIF_TERM out, out_tag;
+ ErlNifUInt64 in_len_64;
+ unsigned char poly1305_key[32];
+ poly1305_state poly1305;
+
+ CHECK_OSE_CRYPTO();
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32
+ || !enif_inspect_binary(env, argv[1], &iv) || iv.size != CHACHA20_NONCE_LEN
+ || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[3], &in)) {
+ return enif_make_badarg(env);
+ }
+
+ /* Take from OpenSSL patch set/LibreSSL:
+ *
+ * The underlying ChaCha implementation may not overflow the block
+ * counter into the second counter word. Therefore we disallow
+ * individual operations that work on more than 2TB at a time.
+ * in_len_64 is needed because, on 32-bit platforms, size_t is only
+ * 32-bits and this produces a warning because it's always false.
+ * Casting to uint64_t inside the conditional is not sufficient to stop
+ * the warning. */
+ in_len_64 = in.size;
+ if (in_len_64 >= (1ULL << 32) * 64 - 64)
+ return enif_make_badarg(env);
+
+ memset(poly1305_key, 0, sizeof(poly1305_key));
+ CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key.data, iv.data, 0);
+
+ outp = enif_make_new_binary(env, in.size, &out);
+
+ CRYPTO_poly1305_init(&poly1305, poly1305_key);
+ poly1305_update_with_length(&poly1305, aad.data, aad.size);
+ CRYPTO_chacha_20(outp, in.data, in.size, key.data, iv.data, 1);
+ poly1305_update_with_length(&poly1305, outp, in.size);
+
+ CRYPTO_poly1305_finish(&poly1305, enif_make_new_binary(env, POLY1305_TAG_LEN, &out_tag));
+
+ CONSUME_REDS(env, in);
+
+ return enif_make_tuple2(env, out, out_tag);
+
+#else
+ return atom_notsup;
+#endif
+}
+
+static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key,Iv,AAD,In,Tag) */
+#if defined(HAVE_CHACHA20_POLY1305)
+ ErlNifBinary key, iv, aad, in, tag;
+ unsigned char *outp;
+ ERL_NIF_TERM out;
+ ErlNifUInt64 in_len_64;
+ unsigned char poly1305_key[32];
+ unsigned char mac[POLY1305_TAG_LEN];
+ poly1305_state poly1305;
+
+ CHECK_OSE_CRYPTO();
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32
+ || !enif_inspect_binary(env, argv[1], &iv) || iv.size != CHACHA20_NONCE_LEN
+ || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[3], &in)
+ || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != POLY1305_TAG_LEN) {
+ return enif_make_badarg(env);
+ }
+
+ /* Take from OpenSSL patch set/LibreSSL:
+ *
+ * The underlying ChaCha implementation may not overflow the block
+ * counter into the second counter word. Therefore we disallow
+ * individual operations that work on more than 2TB at a time.
+ * in_len_64 is needed because, on 32-bit platforms, size_t is only
+ * 32-bits and this produces a warning because it's always false.
+ * Casting to uint64_t inside the conditional is not sufficient to stop
+ * the warning. */
+ in_len_64 = in.size;
+ if (in_len_64 >= (1ULL << 32) * 64 - 64)
+ return enif_make_badarg(env);
+
+ memset(poly1305_key, 0, sizeof(poly1305_key));
+ CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key.data, iv.data, 0);
+
+ CRYPTO_poly1305_init(&poly1305, poly1305_key);
+ poly1305_update_with_length(&poly1305, aad.data, aad.size);
+ poly1305_update_with_length(&poly1305, in.data, in.size);
+ CRYPTO_poly1305_finish(&poly1305, mac);
+
+ if (memcmp(mac, tag.data, POLY1305_TAG_LEN) != 0)
+ return atom_error;
+
+ outp = enif_make_new_binary(env, in.size, &out);
+
+ CRYPTO_chacha_20(outp, in.data, in.size, key.data, iv.data, 1);
+
+ CONSUME_REDS(env, in);
+
+ return out;
+#else
+ return atom_notsup;
+#endif
+}
+
+static ERL_NIF_TERM aes_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key, Data, IsEncrypt) */
+ ErlNifBinary key_bin, data_bin;
+ AES_KEY aes_key;
+ int i;
+ int j;
+ unsigned char* ret_ptr;
+ ERL_NIF_TERM ret;
+
+ CHECK_OSE_CRYPTO();
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
+ || (key_bin.size != 16 && key_bin.size != 32)
+ || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)
+ || data_bin.size % 16 != 0) {
+ return enif_make_badarg(env);
+ }
+
+ if (argv[2] == atom_true) {
+ i = AES_ENCRYPT;
+ AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key);
+ }
+ else {
+ i = AES_DECRYPT;
+ AES_set_decrypt_key(key_bin.data, key_bin.size*8, &aes_key);
+ }
+
+ ret_ptr = enif_make_new_binary(env, data_bin.size, &ret);
+ for (j = 0; j < data_bin.size; j += 16) {
+ AES_ecb_encrypt(data_bin.data+j, ret_ptr+j, &aes_key, i);
+ }
+ CONSUME_REDS(env,data_bin);
+ return ret;
+}
+
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
unsigned bytes;
@@ -2194,11 +2504,12 @@ done:
static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key, IVec, Data, IsEncrypt) */
ErlNifBinary key_bin, ivec_bin, data_bin;
- AES_KEY aes_key;
unsigned char ivec[16];
- int i;
+ int enc, i = 0, outlen = 0;
+ EVP_CIPHER_CTX ctx;
+ const EVP_CIPHER *cipher = NULL;
unsigned char* ret_ptr;
- ERL_NIF_TERM ret;
+ ERL_NIF_TERM ret;
CHECK_OSE_CRYPTO();
@@ -2212,20 +2523,43 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
return enif_make_badarg(env);
}
- if (argv[3] == atom_true) {
- i = AES_ENCRYPT;
- AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key);
- }
- else {
- i = AES_DECRYPT;
- AES_set_decrypt_key(key_bin.data, key_bin.size*8, &aes_key);
- }
+ if (argv[3] == atom_true)
+ enc = 1;
+ else
+ enc = 0;
+
+ EVP_CIPHER_CTX_init(&ctx);
+
+ if (key_bin.size == 16)
+ cipher = EVP_aes_128_cbc();
+ else if (key_bin.size == 32)
+ cipher = EVP_aes_256_cbc();
+
+ memcpy(ivec, ivec_bin.data, 16); /* writeable copy */
+
+ /* openssl docs say we need to leave at least 3 blocks available
+ at the end of the buffer for EVP calls. let's be safe */
+ ret_ptr = enif_make_new_binary(env, data_bin.size + 16*3, &ret);
+
+ if (EVP_CipherInit_ex(&ctx, cipher, NULL, key_bin.data, ivec, enc) != 1)
+ return enif_make_badarg(env);
+
+ /* disable padding, we only handle whole blocks */
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ if (EVP_CipherUpdate(&ctx, ret_ptr, &i, data_bin.data, data_bin.size) != 1)
+ return enif_make_badarg(env);
+ outlen += i;
+ if (EVP_CipherFinal_ex(&ctx, ret_ptr + outlen, &i) != 1)
+ return enif_make_badarg(env);
+ outlen += i;
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
- ret_ptr = enif_make_new_binary(env, data_bin.size, &ret);
- memcpy(ivec, ivec_bin.data, 16); /* writable copy */
- AES_cbc_encrypt(data_bin.data, ret_ptr, data_bin.size, &aes_key, ivec, i);
CONSUME_REDS(env,data_bin);
- return ret;
+
+ /* the garbage collector is going to love this */
+ return enif_make_sub_binary(env, ret, 0, outlen);
}
static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -3235,6 +3569,9 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg)
} else
goto out_err;
+ if (!group)
+ goto out_err;
+
if (enif_inspect_binary(env, prime[2], &seed)) {
EC_GROUP_set_seed(group, seed.data, seed.size);
}
@@ -3419,32 +3756,37 @@ out:
static ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
#if defined(HAVE_EC)
- EC_KEY *key = ec_key_new(env, argv[0]);
+ EC_KEY *key = NULL;
+ const EC_GROUP *group;
+ const EC_POINT *public_key;
+ ERL_NIF_TERM priv_key;
+ ERL_NIF_TERM pub_key = atom_undefined;
CHECK_OSE_CRYPTO();
- if (key && EC_KEY_generate_key(key)) {
- const EC_GROUP *group;
- const EC_POINT *public_key;
- ERL_NIF_TERM priv_key;
- ERL_NIF_TERM pub_key = atom_undefined;
-
- group = EC_KEY_get0_group(key);
- public_key = EC_KEY_get0_public_key(key);
+ if (!get_ec_key(env, argv[0], argv[1], atom_undefined, &key))
+ goto badarg;
- if (group && public_key) {
- pub_key = point2term(env, group, public_key,
- EC_KEY_get_conv_form(key));
- }
- priv_key = bn2term(env, EC_KEY_get0_private_key(key));
- EC_KEY_free(key);
- return enif_make_tuple2(env, pub_key, priv_key);
+ if (argv[1] == atom_undefined) {
+ if (!EC_KEY_generate_key(key))
+ goto badarg;
}
- else {
- if (key)
- EC_KEY_free(key);
- return enif_make_badarg(env);
+
+ group = EC_KEY_get0_group(key);
+ public_key = EC_KEY_get0_public_key(key);
+
+ if (group && public_key) {
+ pub_key = point2term(env, group, public_key,
+ EC_KEY_get_conv_form(key));
}
+ priv_key = bn2term(env, EC_KEY_get0_private_key(key));
+ EC_KEY_free(key);
+ return enif_make_tuple2(env, pub_key, priv_key);
+
+badarg:
+ if (key)
+ EC_KEY_free(key);
+ return enif_make_badarg(env);
#else
return atom_notsup;
#endif
diff --git a/lib/crypto/c_src/crypto_callback.c b/lib/crypto/c_src/crypto_callback.c
index b4c175ae43..e0de16074c 100644
--- a/lib/crypto/c_src/crypto_callback.c
+++ b/lib/crypto/c_src/crypto_callback.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/crypto/c_src/crypto_callback.h b/lib/crypto/c_src/crypto_callback.h
index 23ecba3e5d..df5c99d4d3 100644
--- a/lib/crypto/c_src/crypto_callback.h
+++ b/lib/crypto/c_src/crypto_callback.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile
index 00ae70fb4a..e55242d255 100644
--- a/lib/crypto/doc/src/Makefile
+++ b/lib/crypto/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/crypto/doc/src/book.xml b/lib/crypto/doc/src/book.xml
index c477791bf2..43ed49113f 100644
--- a/lib/crypto/doc/src/book.xml
+++ b/lib/crypto/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 98384978a5..563a090e98 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -41,7 +42,7 @@
</item>
<item>
<p>Block ciphers - <url href="http://csrc.nist.gov/groups/ST/toolkit/block_ciphers.html"> </url> DES and AES in
- Block Cipher Modes - <url href="http://csrc.nist.gov/groups/ST/toolkit/BCM/index.html"> ECB, CBC, CFB, OFB and CTR </url></p>
+ Block Cipher Modes - <url href="http://csrc.nist.gov/groups/ST/toolkit/BCM/index.html"> ECB, CBC, CFB, OFB, CTR and GCM </url></p>
</item>
<item>
<p><url href="http://www.ietf.org/rfc/rfc1321.txt"> RSA encryption RFC 1321 </url> </p>
@@ -53,35 +54,41 @@
<item>
<p><url href="http://www.ietf.org/rfc/rfc2945.txt"> Secure Remote Password Protocol (SRP - RFC 2945) </url></p>
</item>
+ <item>
+ <p>gcm: Dworkin, M., "Recommendation for Block Cipher Modes of
+ Operation: Galois/Counter Mode (GCM) and GMAC",
+ National Institute of Standards and Technology SP 800-
+ 38D, November 2007.</p>
+ </item>
</list>
</description>
<section>
<title>DATA TYPES </title>
- <p><code>key_value() = integer() | binary() </code></p>
+ <code>key_value() = integer() | binary() </code>
<p>Always <c>binary()</c> when used as return value</p>
- <p><code>rsa_public() = [key_value()] = [E, N] </code></p>
+ <code>rsa_public() = [key_value()] = [E, N] </code>
<p> Where E is the public exponent and N is public modulus. </p>
- <p><code>rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] </code></p>
+ <code>rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] </code>
<p>Where E is the public exponent, N is public modulus and D is
the private exponent.The longer key format contains redundant
information that will make the calculation faster. P1,P2 are first
and second prime factors. E1,E2 are first and second exponents. C
is the CRT coefficient. Terminology is taken from <url href="http://www.ietf.org/rfc/rfc3477.txt"> RFC 3447</url>.</p>
- <p><code>dss_public() = [key_value()] = [P, Q, G, Y] </code></p>
+ <code>dss_public() = [key_value()] = [P, Q, G, Y] </code>
<p>Where P, Q and G are the dss parameters and Y is the public key.</p>
- <p><code>dss_private() = [key_value()] = [P, Q, G, X] </code></p>
+ <code>dss_private() = [key_value()] = [P, Q, G, X] </code>
<p>Where P, Q and G are the dss parameters and X is the private key.</p>
- <p><code>srp_public() = key_value() </code></p>
+ <code>srp_public() = key_value() </code>
<p>Where is <c>A</c> or <c>B</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
- <p><code>srp_private() = key_value() </code></p>
+ <code>srp_private() = key_value() </code>
<p>Where is <c>a</c> or <c>b</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
<p>Where Verifier is <c>v</c>, Generator is <c>g</c> and Prime is<c> N</c>, DerivedKey is <c>X</c>, and Scrambler is
@@ -89,29 +96,29 @@
Version = '3' | '6' | '6a'
</p>
- <p><code>dh_public() = key_value() </code></p>
+ <code>dh_public() = key_value() </code>
- <p><code>dh_private() = key_value() </code></p>
+ <code>dh_private() = key_value() </code>
- <p><code>dh_params() = [key_value()] = [P, G] </code></p>
+ <code>dh_params() = [key_value()] = [P, G] </code>
- <p><code>ecdh_public() = key_value() </code></p>
+ <code>ecdh_public() = key_value() </code>
- <p><code>ecdh_private() = key_value() </code></p>
+ <code>ecdh_private() = key_value() </code>
- <p><code>ecdh_params() = ec_named_curve() | ec_explicit_curve()</code></p>
+ <code>ecdh_params() = ec_named_curve() | ec_explicit_curve()</code>
- <p><code>ec_explicit_curve() =
- {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), CoFactor :: none | integer()} </code></p>
+ <code>ec_explicit_curve() =
+ {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), CoFactor :: none | integer()} </code>
- <p><code>ec_field() = {prime_field, Prime :: integer()} |
- {characteristic_two_field, M :: integer(), Basis :: ec_basis()}</code></p>
+ <code>ec_field() = {prime_field, Prime :: integer()} |
+ {characteristic_two_field, M :: integer(), Basis :: ec_basis()}</code>
- <p><code>ec_basis() = {tpbasis, K :: non_neg_integer()} |
+ <code>ec_basis() = {tpbasis, K :: non_neg_integer()} |
{ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} |
- onbasis</code></p>
+ onbasis</code>
- <p><code>ec_named_curve() ->
+ <code>ec_named_curve() ->
sect571r1| sect571k1| sect409r1| sect409k1| secp521r1| secp384r1| secp224r1| secp224k1|
secp192k1| secp160r2| secp128r2| secp128r1| sect233r1| sect233k1| sect193r2| sect193r1|
sect131r2| sect131r1| sect283r1| sect283k1| sect163r2| secp256k1| secp160k1| secp160r1|
@@ -121,58 +128,95 @@
brainpoolP224t1| brainpoolP256r1| brainpoolP256t1| brainpoolP320r1| brainpoolP320t1|
brainpoolP384r1| brainpoolP384t1| brainpoolP512r1| brainpoolP512t1
</code>
- Note that the <em>sect</em> curves are GF2m (characteristic two) curves and are only supported if the
+ <p>Note that the <em>sect</em> curves are GF2m (characteristic two) curves and are only supported if the
underlying OpenSSL has support for them.
See also <seealso marker="#supports-0">crypto:supports/0</seealso>
</p>
- <p><code>stream_cipher() = rc4 | aes_ctr </code></p>
+ <code>stream_cipher() = rc4 | aes_ctr </code>
- <p><code>block_cipher() = aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc |
+ <code>block_cipher() = aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc |
blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cbf
- | des_ede3 | rc2_cbc </code></p>
+ | des_ede3 | rc2_cbc </code>
- <p><code>stream_key() = aes_key() | rc4_key() </code></p>
+ <code>aead_cipher() = aes_gcm | chacha20_poly1305 </code>
- <p><code>block_key() = aes_key() | blowfish_key() | des_key()| des3_key() </code></p>
+ <code>stream_key() = aes_key() | rc4_key() </code>
- <p><code>aes_key() = iodata() </code> Key length is 128, 192 or 256 bits</p>
+ <code>block_key() = aes_key() | blowfish_key() | des_key()| des3_key() </code>
- <p><code>rc4_key() = iodata() </code> Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)</p>
+ <code>aes_key() = iodata() </code> <p>Key length is 128, 192 or 256 bits</p>
- <p><code>blowfish_key() = iodata() </code> Variable key length from 32 bits up to 448 bits</p>
+ <code>rc4_key() = iodata() </code> <p>Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)</p>
- <p><code>des_key() = iodata() </code> Key length is 64 bits (in CBC mode only 8 bits are used)</p>
+ <code>blowfish_key() = iodata() </code> <p>Variable key length from 32 bits up to 448 bits</p>
- <p><code>des3_key() = [binary(), binary(), binary()] </code> Each key part is 64 bits (in CBC mode only 8 bits are used)</p>
+ <code>des_key() = iodata() </code> <p>Key length is 64 bits (in CBC mode only 8 bits are used)</p>
- <p><code>digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512</code></p>
+ <code>des3_key() = [binary(), binary(), binary()] </code> <p>Each key part is 64 bits (in CBC mode only 8 bits are used)</p>
- <p><code> hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 </code> md4 is also supported for hash_init/1 and hash/2.
+ <code>digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512</code>
+
+ <code> hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 </code> <p>md4 is also supported for hash_init/1 and hash/2.
Note that both md4 and md5 are recommended only for compatibility with existing applications.
</p>
- <p><code> cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 |
- blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb8 | aes_cfb128| aes_cbc256 | aes_ige256 | rc2_cbc | aes_ctr| rc4 </code> </p>
- <p><code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code>
- Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported
+ <code> cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 |
+ blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb8 | aes_cfb128| aes_cbc256 | aes_ige256 | aes_gcm | chacha20_poly1305 | rc2_cbc | aes_ctr| rc4 </code>
+ <code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code>
+ <p>Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported
with ecdsa and ecdh.
</p>
</section>
<funcs>
- <func>
+ <func>
+ <name>block_encrypt(Type, Key, PlainText) -> CipherText</name>
+ <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
+ <type>
+ <v>Type = des_ecb | blowfish_ecb | aes_ecb </v>
+ <v>Key = block_key() </v>
+ <v>PlainText = iodata() </v>
+ </type>
+ <desc>
+ <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.</p>
+ <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
+ is not supported by the underlying OpenSSL implementation.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>block_decrypt(Type, Key, CipherText) -> PlainText</name>
+ <fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary>
+ <type>
+ <v>Type = des_ecb | blowfish_ecb | aes_ecb </v>
+ <v>Key = block_key() </v>
+ <v>PlainText = iodata() </v>
+ </type>
+ <desc>
+ <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.</p>
+ <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
+ is not supported by the underlying OpenSSL implementation.</p>
+ </desc>
+ </func>
+
+ <func>
<name>block_encrypt(Type, Key, Ivec, PlainText) -> CipherText</name>
- <fsummary>Encrypt <c>PlainText</c>according to <c>Type</c> block cipher</fsummary>
+ <name>block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag}</name>
+ <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
<type>
<v>Type = block_cipher() </v>
+ <v>AeadType = aead_cipher() </v>
<v>Key = block_key() </v>
<v>PlainText = iodata() </v>
- <v>IVec = CipherText = binary()</v>
+ <v>AAD = IVec = CipherText = CipherTag = binary()</v>
</type>
<desc>
- <p>Encrypt <c>PlainText</c>according to <c>Type</c> block cipher.
+ <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.
<c>IVec</c> is an arbitrary initializing vector.</p>
+ <p>In AEAD (Authenticated Encryption with Associated Data) mode, encrypt
+ <c>PlainText</c>according to <c>Type</c> block cipher and calculate
+ <c>CipherTag</c> that also authenticates the <c>AAD</c> (Associated Authenticated Data).</p>
<p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
is not supported by the underlying OpenSSL implementation.</p>
</desc>
@@ -180,16 +224,22 @@
<func>
<name>block_decrypt(Type, Key, Ivec, CipherText) -> PlainText</name>
- <fsummary>Decrypt <c>CipherText</c>according to <c>Type</c> block cipher</fsummary>
+ <name>block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | error</name>
+ <fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary>
<type>
<v>Type = block_cipher() </v>
+ <v>AeadType = aead_cipher() </v>
<v>Key = block_key() </v>
<v>PlainText = iodata() </v>
- <v>IVec = CipherText = binary()</v>
+ <v>AAD = IVec = CipherText = CipherTag = binary()</v>
</type>
<desc>
- <p>Decrypt <c>CipherText</c>according to <c>Type</c> block cipher.
+ <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.
<c>IVec</c> is an arbitrary initializing vector.</p>
+ <p>In AEAD (Authenticated Encryption with Associated Data) mode, decrypt
+ <c>CipherText</c>according to <c>Type</c> block cipher and check the authenticity
+ the <c>PlainText</c> and <c>AAD</c> (Associated Authenticated Data) using the
+ <c>CipherTag</c>. May return <c>error</c> if the decryption or validation fail's</p>
<p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
is not supported by the underlying OpenSSL implementation.</p>
</desc>
@@ -250,7 +300,7 @@
<v>SrpUserParams = {user, [Generator::binary(), Prime::binary(), Version::atom()]}</v>
<v>SrpHostParams = {host, [Verifier::binary(), Generator::binary(), Prime::binary(), Version::atom()]}</v>
<v>PublicKey = dh_public() | ecdh_public() | srp_public() </v>
- <v>PrivKeyIn = undefined | dh_private() | srp_private() </v>
+ <v>PrivKeyIn = undefined | dh_private() | ecdh_private() | srp_private() </v>
<v>PrivKeyOut = dh_private() | ecdh_private() | srp_private() </v>
</type>
<desc>
@@ -331,8 +381,8 @@
</type>
<desc>
<p>Computes a HMAC of type <c>Type</c> from <c>Data</c> using
- <c>Key</c> as the authentication key.</p> <c>MacLength</c>
- will limit the size of the resultant <c>Mac</c>.
+ <c>Key</c> as the authentication key.</p> <p><c>MacLength</c>
+ will limit the size of the resultant <c>Mac</c>.</p>
</desc>
</func>
@@ -551,8 +601,11 @@
</type>
<desc>
<p>Generates N bytes randomly uniform 0..255, and returns the
- result in a binary. Uses the <c>crypto</c> library pseudo-random
- number generator.</p>
+ result in a binary. Uses the <c>crypto</c> library pseudo-random
+ number generator.</p>
+ <p>This function is not recommended for cryptographic purposes.
+ Please use <seealso marker="#strong_rand_bytes/1">
+ strong_rand_bytes/1</seealso> instead.</p>
</desc>
</func>
@@ -567,7 +620,7 @@
RAND_seed function from openssl. Only use this if the system
you are running on does not have enough "randomness" built in.
Normally this is when <seealso marker="#strong_rand_bytes/1">
- stong_rand_bytes/1</seealso> returns <c>low_entropy</c></p>
+ strong_rand_bytes/1</seealso> returns <c>low_entropy</c></p>
</desc>
</func>
@@ -600,7 +653,7 @@
<p>Creates a digital signature.</p>
<p>Algorithm <c>dss</c> can only be used together with digest type
<c>sha</c>.</p>
- See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso>
+ <p>See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso>.</p>
</desc>
</func>
@@ -660,7 +713,7 @@
</type>
<desc>
<p>Initializes the state for use in streaming AES encryption using Counter mode (CTR).
- <c>Key</c> is the AES key and must be either 128, 192, or 256 bts long. <c>IVec</c> is
+ <c>Key</c> is the AES key and must be either 128, 192, or 256 bits long. <c>IVec</c> is
an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with
<seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and
<seealso marker="#stream_decrypt-2">stream_decrypt</seealso>.</p>
@@ -752,7 +805,7 @@
<p>Algorithm <c>dss</c> can only be used together with digest type
<c>sha</c>.</p>
- See also <seealso marker="public_key:public_key#verify-4">public_key:verify/4</seealso>
+ <p>See also <seealso marker="public_key:public_key#verify-4">public_key:verify/4</seealso>.</p>
</desc>
</func>
diff --git a/lib/crypto/doc/src/crypto_app.xml b/lib/crypto/doc/src/crypto_app.xml
index 1d10773401..4ba2d34934 100644
--- a/lib/crypto/doc/src/crypto_app.xml
+++ b/lib/crypto/doc/src/crypto_app.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/crypto/doc/src/licenses.xml b/lib/crypto/doc/src/licenses.xml
index 1c77d1f115..57d78f7bd9 100644
--- a/lib/crypto/doc/src/licenses.xml
+++ b/lib/crypto/doc/src/licenses.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index a0ebc4b3dd..0138eb6ad2 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,103 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 3.6.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix bug for <c>aes_ecb</c> block crypto when data is
+ larger than 16 bytes.</p>
+ <p>
+ Own Id: OTP-13249</p>
+ </item>
+ <item>
+ <p>
+ Improve portability of ECC tests in Crypto and SSL for
+ "exotic" OpenSSL versions.</p>
+ <p>
+ Own Id: OTP-13311</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Small documentation fixes</p>
+ <p>
+ Own Id: OTP-13017</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make <c>crypto:ec_curves/0</c> return empty list if
+ elliptic curve is not supported at all.</p>
+ <p>
+ Own Id: OTP-12944</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Enhance crypto:generate_key to calculate ECC public keys
+ from private key.</p>
+ <p>
+ Own Id: OTP-12394</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in <c>crypto:generate_key</c> for <c>ecdh</c>
+ that could cause VM crash for faulty input.</p>
+ <p>
+ Own Id: OTP-12733</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Use the EVP API for AES-CBC crypto to enables the use of
+ hardware acceleration for AES-CBC crypto on newer Intel
+ CPUs (AES-NI), among other platforms.</p>
+ <p>
+ Own Id: OTP-12380</p>
+ </item>
+ <item>
+ <p>
+ Add AES ECB block encryption.</p>
+ <p>
+ Own Id: OTP-12403</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 3.5</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/crypto/doc/src/ref_man.xml b/lib/crypto/doc/src/ref_man.xml
index d14ff053c9..ccdb5afb9b 100644
--- a/lib/crypto/doc/src/ref_man.xml
+++ b/lib/crypto/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/crypto/doc/src/release_notes.xml b/lib/crypto/doc/src/release_notes.xml
index 4f9d448ad1..5253027b9c 100644
--- a/lib/crypto/doc/src/release_notes.xml
+++ b/lib/crypto/doc/src/release_notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml
index e6fd291974..469ab10cc8 100644
--- a/lib/crypto/doc/src/usersguide.xml
+++ b/lib/crypto/doc/src/usersguide.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/crypto/priv/Makefile b/lib/crypto/priv/Makefile
index 0989f14c94..ff9d3e1dc9 100644
--- a/lib/crypto/priv/Makefile
+++ b/lib/crypto/priv/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile
index c185c159e5..6e4008e434 100644
--- a/lib/crypto/src/Makefile
+++ b/lib/crypto/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/crypto/src/crypto.app.src b/lib/crypto/src/crypto.app.src
index 823a27ee39..70611bb637 100644
--- a/lib/crypto/src/crypto.app.src
+++ b/lib/crypto/src/crypto.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/crypto/src/crypto.appup.src b/lib/crypto/src/crypto.appup.src
index 42816773c1..ce13746a07 100644
--- a/lib/crypto/src/crypto.appup.src
+++ b/lib/crypto/src/crypto.appup.src
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index e1fbbf9ab8..38e71591f3 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -211,7 +212,7 @@ supports()->
[{hashs, Hashs},
{ciphers, [des_cbc, des_cfb, des3_cbc, des_ede3, blowfish_cbc,
blowfish_cfb64, blowfish_ofb64, blowfish_ecb, aes_cbc128, aes_cfb8, aes_cfb128,
- aes_cbc256, rc2_cbc, aes_ctr, rc4] ++ Ciphers},
+ aes_cbc256, rc2_cbc, aes_ctr, rc4, aes_ecb] ++ Ciphers},
{public_keys, [rsa, dss, dh, srp] ++ PubKeys}
].
@@ -282,7 +283,8 @@ hmac_final_n(_Context, _HashLen) -> ? nif_stub.
-spec block_encrypt(des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | blowfish_cbc |
blowfish_cfb64 | aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | rc2_cbc,
- Key::iodata(), Ivec::binary(), Data::iodata()) -> binary().
+ Key::iodata(), Ivec::binary(), Data::iodata()) -> binary();
+ (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata()}) -> {binary(), binary()}.
block_encrypt(des_cbc, Key, Ivec, Data) ->
des_cbc_encrypt(Key, Ivec, Data);
@@ -310,14 +312,25 @@ block_encrypt(aes_cfb8, Key, Ivec, Data) ->
aes_cfb_8_encrypt(Key, Ivec, Data);
block_encrypt(aes_cfb128, Key, Ivec, Data) ->
aes_cfb_128_encrypt(Key, Ivec, Data);
+block_encrypt(aes_gcm, Key, Ivec, {AAD, Data}) ->
+ case aes_gcm_encrypt(Key, Ivec, AAD, Data) of
+ notsup -> erlang:error(notsup);
+ Return -> Return
+ end;
+block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, Data}) ->
+ case chacha20_poly1305_encrypt(Key, Ivec, AAD, Data) of
+ notsup -> erlang:error(notsup);
+ Return -> Return
+ end;
block_encrypt(rc2_cbc, Key, Ivec, Data) ->
rc2_cbc_encrypt(Key, Ivec, Data).
-spec block_decrypt(des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | blowfish_cbc |
- blowfish_cfb64 | blowfish_ofb64 | aes_cbc128 | aes_cbc256 | aes_ige256 |
- aes_cfb8 | aes_cfb128 | rc2_cbc,
- Key::iodata(), Ivec::binary(), Data::iodata()) -> binary().
-
+ blowfish_cfb64 | blowfish_ofb64 | aes_cbc128 | aes_cbc256 | aes_ige256 |
+ aes_cfb8 | aes_cfb128 | rc2_cbc,
+ Key::iodata(), Ivec::binary(), Data::iodata()) -> binary();
+ (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(),
+ {AAD::binary(), Data::iodata(), Tag::binary()}) -> binary() | error.
block_decrypt(des_cbc, Key, Ivec, Data) ->
des_cbc_decrypt(Key, Ivec, Data);
block_decrypt(des_cfb, Key, Ivec, Data) ->
@@ -344,22 +357,36 @@ block_decrypt(aes_cfb8, Key, Ivec, Data) ->
aes_cfb_8_decrypt(Key, Ivec, Data);
block_decrypt(aes_cfb128, Key, Ivec, Data) ->
aes_cfb_128_decrypt(Key, Ivec, Data);
+block_decrypt(aes_gcm, Key, Ivec, {AAD, Data, Tag}) ->
+ case aes_gcm_decrypt(Key, Ivec, AAD, Data, Tag) of
+ notsup -> erlang:error(notsup);
+ Return -> Return
+ end;
+block_decrypt(chacha20_poly1305, Key, Ivec, {AAD, Data, Tag}) ->
+ case chacha20_poly1305_decrypt(Key, Ivec, AAD, Data, Tag) of
+ notsup -> erlang:error(notsup);
+ Return -> Return
+ end;
block_decrypt(rc2_cbc, Key, Ivec, Data) ->
rc2_cbc_decrypt(Key, Ivec, Data).
--spec block_encrypt(des_ecb | blowfish_ecb, Key::iodata(), Data::iodata()) -> binary().
+-spec block_encrypt(des_ecb | blowfish_ecb | aes_ecb, Key::iodata(), Data::iodata()) -> binary().
block_encrypt(des_ecb, Key, Data) ->
des_ecb_encrypt(Key, Data);
block_encrypt(blowfish_ecb, Key, Data) ->
- blowfish_ecb_encrypt(Key, Data).
+ blowfish_ecb_encrypt(Key, Data);
+block_encrypt(aes_ecb, Key, Data) ->
+ aes_ecb_encrypt(Key, Data).
--spec block_decrypt(des_ecb | blowfish_ecb, Key::iodata(), Data::iodata()) -> binary().
+-spec block_decrypt(des_ecb | blowfish_ecb | aes_ecb, Key::iodata(), Data::iodata()) -> binary().
block_decrypt(des_ecb, Key, Data) ->
des_ecb_decrypt(Key, Data);
block_decrypt(blowfish_ecb, Key, Data) ->
- blowfish_ecb_decrypt(Key, Data).
+ blowfish_ecb_decrypt(Key, Data);
+block_decrypt(aes_ecb, Key, Data) ->
+ aes_ecb_decrypt(Key, Data).
-spec next_iv(des_cbc | des3_cbc | aes_cbc | aes_ige, Data::iodata()) -> binary().
@@ -567,9 +594,8 @@ generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg)
end,
user_srp_gen_key(Private, Generator, Prime);
-generate_key(ecdh, Curve, undefined) ->
- ec_key_generate(nif_curve_params(Curve)).
-
+generate_key(ecdh, Curve, PrivKey) ->
+ ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)).
compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
@@ -1190,6 +1216,17 @@ aes_cfb_128_decrypt(Key, IVec, Data) ->
aes_cfb_128_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub.
+%%
+%% AES - in Galois/Counter Mode (GCM)
+%%
+aes_gcm_encrypt(_Key, _Ivec, _AAD, _In) -> ?nif_stub.
+aes_gcm_decrypt(_Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub.
+
+%%
+%% Chacha20/Ppoly1305
+%%
+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)
@@ -1361,6 +1398,18 @@ aes_ctr_encrypt(_Key, _IVec, _Data) -> ?nif_stub.
aes_ctr_decrypt(_Key, _IVec, _Cipher) -> ?nif_stub.
%%
+%% AES - in electronic codebook mode (ECB)
+%%
+aes_ecb_encrypt(Key, Data) ->
+ aes_ecb_crypt(Key, Data, true).
+
+aes_ecb_decrypt(Key, Data) ->
+ aes_ecb_crypt(Key, Data, false).
+
+aes_ecb_crypt(_Key, __Data, _IsEncrypt) -> ?nif_stub.
+
+
+%%
%% AES - in counter mode (CTR) with state maintained for multi-call streaming
%%
-type ctr_state() :: { iodata(), binary(), binary(), integer() }.
@@ -1523,7 +1572,7 @@ dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) ->
dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
-ec_key_generate(_Key) -> ?nif_stub.
+ec_key_generate(_Curve, _Key) -> ?nif_stub.
ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.
diff --git a/lib/crypto/src/crypto_ec_curves.erl b/lib/crypto/src/crypto_ec_curves.erl
index fe17643d96..002b03b80c 100644
--- a/lib/crypto/src/crypto_ec_curves.erl
+++ b/lib/crypto/src/crypto_ec_curves.erl
@@ -4,11 +4,13 @@
curves() ->
CryptoSupport = crypto:supports(),
- HasGF2m = proplists:get_bool(ec_gf2m, proplists:get_value(public_keys, CryptoSupport)),
- prime_curves() ++ characteristic_two_curves(HasGF2m).
+ PubKeys = proplists:get_value(public_keys, CryptoSupport),
+ HasEC = proplists:get_bool(ecdh, PubKeys),
+ HasGF2m = proplists:get_bool(ec_gf2m, PubKeys),
+ prime_curves(HasEC) ++ characteristic_two_curves(HasGF2m).
-prime_curves() ->
+prime_curves(true) ->
[secp112r1,secp112r2,secp128r1,secp128r2,secp160k1,secp160r1,secp160r2,
secp192r1,secp192k1,secp224k1,secp224r1,secp256k1,secp256r1,secp384r1,
secp521r1,prime192v1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3,
@@ -16,7 +18,9 @@ prime_curves() ->
brainpoolP160r1,brainpoolP160t1,brainpoolP192r1,brainpoolP192t1,
brainpoolP224r1,brainpoolP224t1,brainpoolP256r1,brainpoolP256t1,
brainpoolP320r1,brainpoolP320t1,brainpoolP384r1,brainpoolP384t1,
- brainpoolP512r1,brainpoolP512t1].
+ brainpoolP512r1,brainpoolP512t1];
+prime_curves(_) ->
+ [].
characteristic_two_curves(true) ->
[sect113r1,sect113r2,sect131r1,sect131r2,sect163k1,sect163r1,
diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl
index a7a2c25467..b0d6954820 100644
--- a/lib/crypto/test/blowfish_SUITE.erl
+++ b/lib/crypto/test/blowfish_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 53e29af338..307fc4b019 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -58,10 +59,13 @@ all() ->
{group, aes_cfb8},
{group, aes_cfb128},
{group, aes_cbc256},
+ {group, aes_ecb},
{group, aes_ige256},
{group, rc2_cbc},
{group, rc4},
{group, aes_ctr},
+ {group, aes_gcm},
+ {group, chacha20_poly1305},
mod_pow,
exor,
rand_uniform
@@ -82,7 +86,7 @@ groups() ->
{dss, [], [sign_verify]},
{ecdsa, [], [sign_verify]},
{dh, [], [generate_compute]},
- {ecdh, [], [compute]},
+ {ecdh, [], [compute, generate]},
{srp, [], [generate_compute]},
{des_cbc, [], [block]},
{des_cfb, [], [block]},
@@ -94,13 +98,16 @@ groups() ->
{aes_cfb8,[], [block]},
{aes_cfb128,[], [block]},
{aes_cbc256,[], [block]},
+ {aes_ecb,[], [block]},
{aes_ige256,[], [block]},
{blowfish_cbc, [], [block]},
{blowfish_ecb, [], [block]},
{blowfish_cfb64, [], [block]},
{blowfish_ofb64,[], [block]},
{rc4, [], [stream]},
- {aes_ctr, [], [stream]}
+ {aes_ctr, [], [stream]},
+ {aes_gcm, [], [aead]},
+ {chacha20_poly1305, [], [aead]}
].
%%-------------------------------------------------------------------
@@ -203,6 +210,14 @@ stream(Config) when is_list(Config) ->
lists:foreach(fun stream_cipher/1, stream_iolistify(Streams)),
lists:foreach(fun stream_cipher_incment/1, stream_iolistify(Streams)).
+%%--------------------------------------------------------------------
+aead() ->
+ [{doc, "Test AEAD ciphers"}].
+aead(Config) when is_list(Config) ->
+ AEADs = lazy_eval(proplists:get_value(aead, Config)),
+
+ lists:foreach(fun aead_cipher/1, AEADs).
+
%%--------------------------------------------------------------------
sign_verify() ->
[{doc, "Sign/verify digital signatures"}].
@@ -231,6 +246,12 @@ compute(Config) when is_list(Config) ->
Gen = proplists:get_value(compute, Config),
lists:foreach(fun do_compute/1, Gen).
%%--------------------------------------------------------------------
+generate() ->
+ [{doc, " Test crypto:generate_key"}].
+generate(Config) when is_list(Config) ->
+ Gen = proplists:get_value(generate, Config),
+ lists:foreach(fun do_generate/1, Gen).
+%%--------------------------------------------------------------------
mod_pow() ->
[{doc, "mod_pow testing (A ^ M % P with bignums)"}].
mod_pow(Config) when is_list(Config) ->
@@ -406,7 +427,22 @@ stream_cipher_incment(_State, OrigState, [], Acc, Plain) ->
stream_cipher_incment(State0, OrigState, [PlainText | PlainTexts], Acc, Plain) ->
{State, CipherText} = crypto:stream_encrypt(State0, PlainText),
stream_cipher_incment(State, OrigState, PlainTexts, [CipherText | Acc], Plain).
-
+
+aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag}) ->
+ Plain = iolist_to_binary(PlainText),
+ case crypto:block_encrypt(Type, Key, IV, {AAD, Plain}) of
+ {CipherText, CipherTag} ->
+ ok;
+ Other0 ->
+ ct:fail({{crypto, block_encrypt, [Plain, PlainText]}, {expected, {CipherText, CipherTag}}, {got, Other0}})
+ end,
+ case crypto:block_decrypt(Type, Key, IV, {AAD, CipherText, CipherTag}) of
+ Plain ->
+ ok;
+ Other1 ->
+ ct:fail({{crypto, block_decrypt, [CipherText]}, {expected, Plain}, {got, Other1}})
+ end.
+
do_sign_verify({Type, Hash, Public, Private, Msg}) ->
Signature = crypto:sign(Type, Hash, Msg, Private),
case crypto:verify(Type, Hash, Msg, Signature, Public) of
@@ -467,6 +503,14 @@ do_compute({ecdh = Type, Pub, Priv, Curve, SharedSecret}) ->
ct:fail({{crypto, compute_key, [Type, Pub, Priv, Curve]}, {expected, SharedSecret}, {got, Other}})
end.
+do_generate({ecdh = Type, Curve, Priv, Pub}) ->
+ case crypto:generate_key(Type, Curve, Priv) of
+ {Pub, _} ->
+ ok;
+ {Other, _} ->
+ ct:fail({{crypto, generate_key, [Type, Priv, Curve]}, {expected, Pub}, {got, Other}})
+ end.
+
hexstr2point(X, Y) ->
<<4:8, (hexstr2bin(X))/binary, (hexstr2bin(Y))/binary>>.
@@ -694,7 +738,8 @@ group_config(srp, Config) ->
[{generate_compute, GenerateCompute} | Config];
group_config(ecdh, Config) ->
Compute = ecdh(),
- [{compute, Compute} | Config];
+ Generate = ecc(),
+ [{compute, Compute}, {generate, Generate} | Config];
group_config(dh, Config) ->
GenerateCompute = [dh()],
[{generate_compute, GenerateCompute} | Config];
@@ -722,6 +767,9 @@ group_config(aes_cbc128, Config) ->
group_config(aes_cbc256, Config) ->
Block = aes_cbc256(),
[{block, Block} | Config];
+group_config(aes_ecb, Config) ->
+ Block = aes_ecb(),
+ [{block, Block} | Config];
group_config(aes_ige256, Config) ->
Block = aes_ige256(),
[{block, Block} | Config];
@@ -749,6 +797,12 @@ group_config(rc4, Config) ->
group_config(aes_ctr, Config) ->
Stream = aes_ctr(),
[{stream, Stream} | Config];
+group_config(aes_gcm, Config) ->
+ AEAD = aes_gcm(),
+ [{aead, AEAD} | Config];
+group_config(chacha20_poly1305, Config) ->
+ AEAD = chacha20_poly1305(),
+ [{aead, AEAD} | Config];
group_config(_, Config) ->
Config.
@@ -1150,6 +1204,122 @@ aes_cbc256() ->
hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
].
+aes_ecb() ->
+ [
+ {aes_ecb,
+ <<"YELLOW SUBMARINE">>,
+ <<"YELLOW SUBMARINE">>},
+ {aes_ecb,
+ <<"0000000000000000">>,
+ <<"0000000000000000">>},
+ {aes_ecb,
+ <<"FFFFFFFFFFFFFFFF">>,
+ <<"FFFFFFFFFFFFFFFF">>},
+ {aes_ecb,
+ <<"3000000000000000">>,
+ <<"1000000000000001">>},
+ {aes_ecb,
+ <<"1111111111111111">>,
+ <<"1111111111111111">>},
+ {aes_ecb,
+ <<"0123456789ABCDEF">>,
+ <<"1111111111111111">>},
+ {aes_ecb,
+ <<"0000000000000000">>,
+ <<"0000000000000000">>},
+ {aes_ecb,
+ <<"FEDCBA9876543210">>,
+ <<"0123456789ABCDEF">>},
+ {aes_ecb,
+ <<"7CA110454A1A6E57">>,
+ <<"01A1D6D039776742">>},
+ {aes_ecb,
+ <<"0131D9619DC1376E">>,
+ <<"5CD54CA83DEF57DA">>},
+ {aes_ecb,
+ <<"07A1133E4A0B2686">>,
+ <<"0248D43806F67172">>},
+ {aes_ecb,
+ <<"3849674C2602319E">>,
+ <<"51454B582DDF440A">>},
+ {aes_ecb,
+ <<"04B915BA43FEB5B6">>,
+ <<"42FD443059577FA2">>},
+ {aes_ecb,
+ <<"0113B970FD34F2CE">>,
+ <<"059B5E0851CF143A">>},
+ {aes_ecb,
+ <<"0170F175468FB5E6">>,
+ <<"0756D8E0774761D2">>},
+ {aes_ecb,
+ <<"43297FAD38E373FE">>,
+ <<"762514B829BF486A">>},
+ {aes_ecb,
+ <<"07A7137045DA2A16">>,
+ <<"3BDD119049372802">>},
+ {aes_ecb,
+ <<"04689104C2FD3B2F">>,
+ <<"26955F6835AF609A">>},
+ {aes_ecb,
+ <<"37D06BB516CB7546">>,
+ <<"164D5E404F275232">>},
+ {aes_ecb,
+ <<"1F08260D1AC2465E">>,
+ <<"6B056E18759F5CCA">>},
+ {aes_ecb,
+ <<"584023641ABA6176">>,
+ <<"004BD6EF09176062">>},
+ {aes_ecb,
+ <<"025816164629B007">>,
+ <<"480D39006EE762F2">>},
+ {aes_ecb,
+ <<"49793EBC79B3258F">>,
+ <<"437540C8698F3CFA">>},
+ {aes_ecb,
+ <<"018310DC409B26D6">>,
+ <<"1D9D5C5018F728C2">>},
+ {aes_ecb,
+ <<"1C587F1C13924FEF">>,
+ <<"305532286D6F295A">>},
+ {aes_ecb,
+ <<"0101010101010101">>,
+ <<"0123456789ABCDEF">>},
+ {aes_ecb,
+ <<"1F1F1F1F0E0E0E0E">>,
+ <<"0123456789ABCDEF">>},
+ {aes_ecb,
+ <<"E0FEE0FEF1FEF1FE">>,
+ <<"0123456789ABCDEF">>},
+ {aes_ecb,
+ <<"0000000000000000">>,
+ <<"FFFFFFFFFFFFFFFF">>},
+ {aes_ecb,
+ <<"FFFFFFFFFFFFFFFF">>,
+ <<"0000000000000000">>},
+ {aes_ecb,
+ <<"0123456789ABCDEF">>,
+ <<"0000000000000000">>},
+ {aes_ecb,
+ <<"FEDCBA9876543210">>,
+ <<"FFFFFFFFFFFFFFFF">>},
+ %% AES ECB test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ %% F.1.1 ECB-AES128.Encrypt, F.1.2 ECB-AES128.Decrypt
+ {aes_ecb,
+ hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
+ hexstr2bin("6bc1bee22e409f96e93d7e117393172a"
+ "ae2d8a571e03ac9c9eb76fac45af8e51"
+ "30c81c46a35ce411e5fbc1191a0a52ef"
+ "f69f2445df4f9b17ad2b417be66c3710")},
+ %% F.1.5 ECB-AES256.Encrypt, F.1.6 ECB-AES256.Decrypt
+ {aes_ecb,
+ hexstr2bin("603deb1015ca71be2b73aef0857d7781"
+ "1f352c073b6108d72d9810a30914dff4"),
+ hexstr2bin("6bc1bee22e409f96e93d7e117393172a"
+ "ae2d8a571e03ac9c9eb76fac45af8e51"
+ "30c81c46a35ce411e5fbc1191a0a52ef"
+ "f69f2445df4f9b17ad2b417be66c3710")}
+ ].
+
aes_ige256() ->
[{aes_ige256,
hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
@@ -1442,6 +1612,269 @@ aes_ctr() ->
long_msg()}
].
+
+%% AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
+aes_gcm() ->
+ [
+ %% Test Case 1
+ {aes_gcm, hexstr2bin("00000000000000000000000000000000"), %% Key
+ hexstr2bin(""), %% PlainText
+ hexstr2bin("000000000000000000000000"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin(""), %% CipherText
+ hexstr2bin("58e2fccefa7e3061367f1d57a4e7455a")}, %% CipherTag
+
+ %% Test Case 2
+ {aes_gcm, hexstr2bin("00000000000000000000000000000000"), %% Key
+ hexstr2bin("00000000000000000000000000000000"), %% PlainText
+ hexstr2bin("000000000000000000000000"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin("0388dace60b6a392f328c2b971b2fe78"), %% CipherText
+ hexstr2bin("ab6e47d42cec13bdf53a67b21257bddf")}, %% CipherTag
+
+ %% Test Case 3
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b391aafd255"),
+ hexstr2bin("cafebabefacedbaddecaf888"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin("42831ec2217774244b7221b784d0d49c" %% CipherText
+ "e3aa212f2c02a4e035c17e2329aca12e"
+ "21d514b25466931c7d8f6a5aac84aa05"
+ "1ba30b396a0aac973d58e091473f5985"),
+ hexstr2bin("4d5c2af327cd64a62cf35abd2ba6fab4")}, %% CipherTag
+
+ %% Test Case 4
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("cafebabefacedbaddecaf888"), %% IV
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("42831ec2217774244b7221b784d0d49c" %% CipherText
+ "e3aa212f2c02a4e035c17e2329aca12e"
+ "21d514b25466931c7d8f6a5aac84aa05"
+ "1ba30b396a0aac973d58e091"),
+ hexstr2bin("5bc94fbc3221a5db94fae95ae7121a47")}, %% CipherTag
+
+ %% Test Case 5
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("cafebabefacedbad"), %% IV
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("61353b4c2806934a777ff51fa22a4755" %% CipherText
+ "699b2a714fcdc6f83766e5f97b6c7423"
+ "73806900e49f24b22b097544d4896b42"
+ "4989b5e1ebac0f07c23f4598"),
+ hexstr2bin("3612d2e79e3b0785561be14aaca2fccb")}, %% CipherTag
+
+ %% Test Case 6"
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
+ "6a7a9538534f7da1e4c303d2a318a728"
+ "c3c0c95156809539fcf0e2429a6b5254"
+ "16aedbf5a0de6a57a637b39b"),
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("8ce24998625615b603a033aca13fb894" %% CipherText
+ "be9112a5c3a211a8ba262a3cca7e2ca7"
+ "01e4a9a4fba43c90ccdcb281d48c7c6f"
+ "d62875d2aca417034c34aee5"),
+ hexstr2bin("619cc5aefffe0bfa462af43c1699d050")}, %% CipherTag
+
+ %% Test Case 7
+ {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
+ "0000000000000000"),
+ hexstr2bin(""), %% PlainText
+ hexstr2bin("000000000000000000000000"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin(""), %% CipherText
+ hexstr2bin("cd33b28ac773f74ba00ed1f312572435")}, %% CipherTag
+
+ %% Test Case 8
+ {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
+ "0000000000000000"),
+ hexstr2bin("00000000000000000000000000000000"), %% PlainText
+ hexstr2bin("000000000000000000000000"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin("98e7247c07f0fe411c267e4384b0f600"), %% CipherText
+ hexstr2bin("2ff58d80033927ab8ef4d4587514f0fb")}, %% CipherTag
+
+ %% Test Case 9
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b391aafd255"),
+ hexstr2bin("cafebabefacedbaddecaf888"), %% IV
+ hexstr2bin(""), %% ADD
+ hexstr2bin("3980ca0b3c00e841eb06fac4872a2757" %% CipherText
+ "859e1ceaa6efd984628593b40ca1e19c"
+ "7d773d00c144c525ac619d18c84a3f47"
+ "18e2448b2fe324d9ccda2710acade256"),
+ hexstr2bin("9924a7c8587336bfb118024db8674a14")}, %% CipherTag
+
+ %% Test Case 10
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("cafebabefacedbaddecaf888"), %% IV
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("3980ca0b3c00e841eb06fac4872a2757" %% CipherText
+ "859e1ceaa6efd984628593b40ca1e19c"
+ "7d773d00c144c525ac619d18c84a3f47"
+ "18e2448b2fe324d9ccda2710"),
+ hexstr2bin("2519498e80f1478f37ba55bd6d27618c")}, %% CipherTag
+
+ %% Test Case 11
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("cafebabefacedbad"), %% IV
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("0f10f599ae14a154ed24b36e25324db8" %% CipherText
+ "c566632ef2bbb34f8347280fc4507057"
+ "fddc29df9a471f75c66541d4d4dad1c9"
+ "e93a19a58e8b473fa0f062f7"),
+ hexstr2bin("65dcc57fcf623a24094fcca40d3533f8")}, %% CipherTag
+
+ %% Test Case 12
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
+ "6a7a9538534f7da1e4c303d2a318a728"
+ "c3c0c95156809539fcf0e2429a6b5254"
+ "16aedbf5a0de6a57a637b39b"),
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("d27e88681ce3243c4830165a8fdcf9ff" %% CipherText
+ "1de9a1d8e6b447ef6ef7b79828666e45"
+ "81e79012af34ddd9e2f037589b292db3"
+ "e67c036745fa22e7e9b7373b"),
+ hexstr2bin("dcf566ff291c25bbb8568fc3d376a6d9")}, %% CipherTag
+
+ %% Test Case 13
+ {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
+ "00000000000000000000000000000000"),
+ hexstr2bin(""), %% PlainText
+ hexstr2bin("000000000000000000000000"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin(""), %% CipherText
+ hexstr2bin("530f8afbc74536b9a963b4f1c4cb738b")}, %% CipherTag
+
+ %% Test Case 14
+ {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
+ "00000000000000000000000000000000"),
+ hexstr2bin("00000000000000000000000000000000"), %% PlainText
+ hexstr2bin("000000000000000000000000"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin("cea7403d4d606b6e074ec5d3baf39d18"), %% CipherText
+ hexstr2bin("d0d1c8a799996bf0265b98b5d48ab919")}, %% CipherTag
+
+ %% Test Case 15
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c6d6a8f9467308308"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b391aafd255"),
+ hexstr2bin("cafebabefacedbaddecaf888"), %% IV
+ hexstr2bin(""), %% AAD
+ hexstr2bin("522dc1f099567d07f47f37a32a84427d" %% CipherText
+ "643a8cdcbfe5c0c97598a2bd2555d1aa"
+ "8cb08e48590dbb3da7b08b1056828838"
+ "c5f61e6393ba7a0abcc9f662898015ad"),
+ hexstr2bin("b094dac5d93471bdec1a502270e3cc6c")}, %% CipherTag
+
+ %% Test Case 16
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c6d6a8f9467308308"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("cafebabefacedbaddecaf888"), %% IV
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("522dc1f099567d07f47f37a32a84427d" %% CipherText
+ "643a8cdcbfe5c0c97598a2bd2555d1aa"
+ "8cb08e48590dbb3da7b08b1056828838"
+ "c5f61e6393ba7a0abcc9f662"),
+ hexstr2bin("76fc6ece0f4e1768cddf8853bb2d551b")}, %% CipherTag
+
+ %% Test Case 17
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c6d6a8f9467308308"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("cafebabefacedbad"), %% IV
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("c3762df1ca787d32ae47c13bf19844cb" %% CipherText
+ "af1ae14d0b976afac52ff7d79bba9de0"
+ "feb582d33934a4f0954cc2363bc73f78"
+ "62ac430e64abe499f47c9b1f"),
+ hexstr2bin("3a337dbf46a792c45e454913fe2ea8f2")}, %% CipherTag
+
+ %% Test Case 18
+ {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
+ "feffe9928665731c6d6a8f9467308308"),
+ hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
+ "86a7a9531534f7da2e4c303d8a318a72"
+ "1c3c0c95956809532fcf0e2449a6b525"
+ "b16aedf5aa0de657ba637b39"),
+ hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
+ "6a7a9538534f7da1e4c303d2a318a728"
+ "c3c0c95156809539fcf0e2429a6b5254"
+ "16aedbf5a0de6a57a637b39b"),
+ hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
+ "abaddad2"),
+ hexstr2bin("5a8def2f0c9e53f1f75d7853659e2a20" %% CipherText
+ "eeb2b22aafde6419a058ab4f6f746bf4"
+ "0fc0c3b780f244452da3ebf1c5d82cde"
+ "a2418997200ef82e44ae7e3f"),
+ hexstr2bin("a44a8266ee1c8eb0c8b5d4cf5ae9f19a")} %% CipherTag
+ ].
+
+%% http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
+chacha20_poly1305() ->
+ [
+ {chacha20_poly1305, hexstr2bin("4290bcb154173531f314af57f3be3b500" %% Key
+ "6da371ece272afa1b5dbdd1100a1007"),
+ hexstr2bin("86d09974840bded2a5ca"), %% PlainText
+ hexstr2bin("cd7cf67be39c794a"), %% Nonce
+ hexstr2bin("87e229d4500845a079c0"), %% AAD
+ hexstr2bin("e3e446f7ede9a19b62a4"), %% CipherText
+ hexstr2bin("677dabf4e3d24b876bb284753896e1d6")} %% CipherTag
+ ].
+
rsa_plain() ->
<<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
"09812312908312378623487263487623412039812 huagasd">>.
@@ -1468,8 +1901,9 @@ dss_params() ->
18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669].
ec_key_named() ->
- {D2_pub, D2_priv} = crypto:generate_key(ecdh, sect113r2),
- {[D2_priv, sect113r2], [D2_pub, sect113r2]}.
+ Curve = hd(crypto:ec_curves()),
+ {D2_pub, D2_priv} = crypto:generate_key(ecdh, Curve),
+ {[D2_priv, Curve], [D2_pub, Curve]}.
ec_msg() ->
<<99,234,6,64,190,237,201,99,80,248,58,40,70,45,149,218,5,246,242,63>>.
@@ -1636,88 +2070,94 @@ srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPriv
SessionKey}.
ecdh() ->
%% http://csrc.nist.gov/groups/STM/cavp/
- [{ecdh, hexstr2point("42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0", "dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523"),
- hexstr2bin("f17d3fea367b74d340851ca4270dcb24c271f445bed9d527"),
- secp192r1,
- hexstr2bin("803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0")},
- {ecdh, hexstr2point("deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7", "7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125"),
- hexstr2bin("56e853349d96fe4c442448dacb7cf92bb7a95dcf574a9bd5"),
- secp192r1,
- hexstr2bin("c208847568b98835d7312cef1f97f7aa298283152313c29d")},
- {ecdh, hexstr2point("af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280", "882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7"),
- hexstr2bin("8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd"),
- secp224r1,
- hexstr2bin("7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8")},
- {ecdh, hexstr2point("13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46", "eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4"),
- hexstr2bin("043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d"),
- secp224r1,
- hexstr2bin("ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09")},
- {ecdh, hexstr2point("700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287", "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"),
- hexstr2bin("7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"),
- secp256r1,
- hexstr2bin("46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b")},
- {ecdh, hexstr2point("809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae", "b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3"),
- hexstr2bin("38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5"),
- secp256r1,
- hexstr2bin("057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67")},
- {ecdh, hexstr2point("a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066", "ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a"),
- hexstr2bin("3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1"),
- secp384r1,
- hexstr2bin("5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1")},
- {ecdh, hexstr2point("30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0", "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757"),
- hexstr2bin("92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783"),
- secp384r1,
- hexstr2bin("a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff")},
- {ecdh, hexstr2point("00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d", "01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676"),
- hexstr2bin("017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47"),
- secp521r1,
- hexstr2bin("005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831")},
- {ecdh, hexstr2point("01df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a", "013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0"),
- hexstr2bin("00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc872f95d05d07ad50f621ceb620cd905cfb8"),
- secp521r1,
- hexstr2bin("000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759")},
-
- %% RFC-6954, Appendix A
- {ecdh, hexstr2point("A9C21A569759DA95E0387041184261440327AFE33141CA04B82DC92E",
- "98A0F75FBBF61D8E58AE5511B2BCDBE8E549B31E37069A2825F590C1"),
- hexstr2bin("6060552303899E2140715816C45B57D9B42204FB6A5BF5BEAC10DB00"),
- brainpoolP224r1,
- hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
- {ecdh, hexstr2point("034A56C550FF88056144E6DD56070F54B0135976B5BF77827313F36B",
- "75165AD99347DC86CAAB1CBB579E198EAF88DC35F927B358AA683681"),
- hexstr2bin("39F155483CEE191FBECFE9C81D8AB1A03CDA6790E7184ACE44BCA161"),
- brainpoolP224r1,
- hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
- {ecdh, hexstr2point("44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5",
- "8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC"),
- hexstr2bin("55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3"),
- brainpoolP256r1,
- hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
- {ecdh, hexstr2point("8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B",
- "990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A"),
- hexstr2bin("81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D"),
- brainpoolP256r1,
- hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
- {ecdh, hexstr2point("68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068",
- "55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59"),
- hexstr2bin("032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670"),
- brainpoolP384r1,
- hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
- {ecdh, hexstr2point("4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4",
- "62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48"),
- hexstr2bin("1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042"),
- brainpoolP384r1,
- hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
- {ecdh, hexstr2point("0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD",
- "72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7"),
- hexstr2bin("230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429"),
- brainpoolP512r1,
- hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")},
- {ecdh, hexstr2point("9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F",
- "2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA"),
- hexstr2bin("16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422"),
- brainpoolP512r1,
- hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")}].
+ Curves = crypto:ec_curves(),
+ TestCases =
+ [{ecdh, hexstr2point("42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0", "dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523"),
+ hexstr2bin("f17d3fea367b74d340851ca4270dcb24c271f445bed9d527"),
+ secp192r1,
+ hexstr2bin("803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0")},
+ {ecdh, hexstr2point("deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7", "7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125"),
+ hexstr2bin("56e853349d96fe4c442448dacb7cf92bb7a95dcf574a9bd5"),
+ secp192r1,
+ hexstr2bin("c208847568b98835d7312cef1f97f7aa298283152313c29d")},
+ {ecdh, hexstr2point("af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280", "882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7"),
+ hexstr2bin("8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd"),
+ secp224r1,
+ hexstr2bin("7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8")},
+ {ecdh, hexstr2point("13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46", "eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4"),
+ hexstr2bin("043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d"),
+ secp224r1,
+ hexstr2bin("ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09")},
+ {ecdh, hexstr2point("700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287", "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"),
+ hexstr2bin("7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"),
+ secp256r1,
+ hexstr2bin("46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b")},
+ {ecdh, hexstr2point("809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae", "b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3"),
+ hexstr2bin("38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5"),
+ secp256r1,
+ hexstr2bin("057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67")},
+ {ecdh, hexstr2point("a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066", "ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a"),
+ hexstr2bin("3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1"),
+ secp384r1,
+ hexstr2bin("5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1")},
+ {ecdh, hexstr2point("30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0", "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757"),
+ hexstr2bin("92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783"),
+ secp384r1,
+ hexstr2bin("a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff")},
+ {ecdh, hexstr2point("00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d", "01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676"),
+ hexstr2bin("017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47"),
+ secp521r1,
+ hexstr2bin("005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831")},
+ {ecdh, hexstr2point("01df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a", "013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0"),
+ hexstr2bin("00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc872f95d05d07ad50f621ceb620cd905cfb8"),
+ secp521r1,
+ hexstr2bin("000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759")},
+
+ %% RFC-6954, Appendix A
+ {ecdh, hexstr2point("A9C21A569759DA95E0387041184261440327AFE33141CA04B82DC92E",
+ "98A0F75FBBF61D8E58AE5511B2BCDBE8E549B31E37069A2825F590C1"),
+ hexstr2bin("6060552303899E2140715816C45B57D9B42204FB6A5BF5BEAC10DB00"),
+ brainpoolP224r1,
+ hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
+ {ecdh, hexstr2point("034A56C550FF88056144E6DD56070F54B0135976B5BF77827313F36B",
+ "75165AD99347DC86CAAB1CBB579E198EAF88DC35F927B358AA683681"),
+ hexstr2bin("39F155483CEE191FBECFE9C81D8AB1A03CDA6790E7184ACE44BCA161"),
+ brainpoolP224r1,
+ hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
+ {ecdh, hexstr2point("44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5",
+ "8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC"),
+ hexstr2bin("55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3"),
+ brainpoolP256r1,
+ hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
+ {ecdh, hexstr2point("8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B",
+ "990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A"),
+ hexstr2bin("81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D"),
+ brainpoolP256r1,
+ hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
+ {ecdh, hexstr2point("68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068",
+ "55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59"),
+ hexstr2bin("032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670"),
+ brainpoolP384r1,
+ hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
+ {ecdh, hexstr2point("4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4",
+ "62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48"),
+ hexstr2bin("1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042"),
+ brainpoolP384r1,
+ hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
+ {ecdh, hexstr2point("0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD",
+ "72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7"),
+ hexstr2bin("230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429"),
+ brainpoolP512r1,
+ hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")},
+ {ecdh, hexstr2point("9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F",
+ "2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA"),
+ hexstr2bin("16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422"),
+ brainpoolP512r1,
+ hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")}],
+ lists:filter(fun ({_Type, _Pub, _Priv, Curve, _SharedSecret}) ->
+ lists:member(Curve, Curves)
+ end,
+ TestCases).
dh() ->
{dh, 0087761979513264537414556992123116644042638206717762626089877284926656954974893442000747478454809111207351620687968672207938731607963470779396984752680274820156266685080223616226905101126463253150237669547023934604953898814222890239130021414026118792251620881355456432549881723310342870016961804255746630219, 2}.
@@ -1736,6 +2176,33 @@ rsa_oaep() ->
Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
{rsa, Public, Private, Msg, rsa_pkcs1_oaep_padding}.
+ecc() ->
+%% http://point-at-infinity.org/ecc/nisttv
+%%
+%% Test vectors for the NIST elliptic curves P192, P224, P256, P384, P521,
+%% B163, B233, B283, B409, B571, K163, K233, K283, K409 and K571. For more
+%% information about the curves see
+%% http://csrc.nist.gov/encryption/dss/ecdsa/NISTReCur.pdf
+%%
+ Curves = crypto:ec_curves(),
+ TestCases =
+ [{ecdh,secp192r1,1,
+ hexstr2point("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")},
+ {ecdh,secp192r1,2,
+ hexstr2point("DAFEBF5828783F2AD35534631588A3F629A70FB16982A888",
+ "DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB")},
+ {ecdh,secp192r1,3,
+ hexstr2point("76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA",
+ "782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD")},
+ {ecdh,secp192r1,4,
+ hexstr2point("35433907297CC378B0015703374729D7A4FE46647084E4BA",
+ "A2649984F2135C301EA3ACB0776CD4F125389B311DB3BE32")}],
+ lists:filter(fun ({_Type, Curve, _Priv, _Pub}) ->
+ lists:member(Curve, Curves)
+ end,
+ TestCases).
+
no_padding() ->
Public = [_, Mod] = rsa_public(),
Private = rsa_private(),
diff --git a/lib/crypto/test/old_crypto_SUITE.erl b/lib/crypto/test/old_crypto_SUITE.erl
index 040edbf092..1e7f3a1438 100644
--- a/lib/crypto/test/old_crypto_SUITE.erl
+++ b/lib/crypto/test/old_crypto_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1887,48 +1888,12 @@ ec(Config) when is_list(Config) ->
ec_do() ->
%% test for a name curve
- {D2_pub, D2_priv} = crypto:generate_key(ecdh, sect113r2),
- PrivECDH = [D2_priv, sect113r2],
- PubECDH = [D2_pub, sect113r2],
+ 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
- %% test for a full specified curve and public key,
- %% taken from csca-germany_013_self_signed_cer.pem
- PubKey = <<16#04, 16#4a, 16#94, 16#49, 16#81, 16#77, 16#9d, 16#df,
- 16#1d, 16#a5, 16#e7, 16#c5, 16#27, 16#e2, 16#7d, 16#24,
- 16#71, 16#a9, 16#28, 16#eb, 16#4d, 16#7b, 16#67, 16#75,
- 16#ae, 16#09, 16#0a, 16#51, 16#45, 16#19, 16#9b, 16#d4,
- 16#7e, 16#a0, 16#81, 16#e5, 16#5e, 16#d4, 16#a4, 16#3f,
- 16#60, 16#7c, 16#6a, 16#50, 16#ee, 16#36, 16#41, 16#8a,
- 16#87, 16#ff, 16#cd, 16#a6, 16#10, 16#39, 16#ca, 16#95,
- 16#76, 16#7d, 16#ae, 16#ca, 16#c3, 16#44, 16#3f, 16#e3, 16#2c>>,
- <<P:264/integer>> = <<16#00, 16#a9, 16#fb, 16#57, 16#db, 16#a1, 16#ee, 16#a9,
- 16#bc, 16#3e, 16#66, 16#0a, 16#90, 16#9d, 16#83, 16#8d,
- 16#72, 16#6e, 16#3b, 16#f6, 16#23, 16#d5, 16#26, 16#20,
- 16#28, 16#20, 16#13, 16#48, 16#1d, 16#1f, 16#6e, 16#53, 16#77>>,
- <<A:256/integer>> = <<16#7d, 16#5a, 16#09, 16#75, 16#fc, 16#2c, 16#30, 16#57,
- 16#ee, 16#f6, 16#75, 16#30, 16#41, 16#7a, 16#ff, 16#e7,
- 16#fb, 16#80, 16#55, 16#c1, 16#26, 16#dc, 16#5c, 16#6c,
- 16#e9, 16#4a, 16#4b, 16#44, 16#f3, 16#30, 16#b5, 16#d9>>,
- <<B:256/integer>> = <<16#26, 16#dc, 16#5c, 16#6c, 16#e9, 16#4a, 16#4b, 16#44,
- 16#f3, 16#30, 16#b5, 16#d9, 16#bb, 16#d7, 16#7c, 16#bf,
- 16#95, 16#84, 16#16, 16#29, 16#5c, 16#f7, 16#e1, 16#ce,
- 16#6b, 16#cc, 16#dc, 16#18, 16#ff, 16#8c, 16#07, 16#b6>>,
- BasePoint = <<16#04, 16#8b, 16#d2, 16#ae, 16#b9, 16#cb, 16#7e, 16#57,
- 16#cb, 16#2c, 16#4b, 16#48, 16#2f, 16#fc, 16#81, 16#b7,
- 16#af, 16#b9, 16#de, 16#27, 16#e1, 16#e3, 16#bd, 16#23,
- 16#c2, 16#3a, 16#44, 16#53, 16#bd, 16#9a, 16#ce, 16#32,
- 16#62, 16#54, 16#7e, 16#f8, 16#35, 16#c3, 16#da, 16#c4,
- 16#fd, 16#97, 16#f8, 16#46, 16#1a, 16#14, 16#61, 16#1d,
- 16#c9, 16#c2, 16#77, 16#45, 16#13, 16#2d, 16#ed, 16#8e,
- 16#54, 16#5c, 16#1d, 16#54, 16#c7, 16#2f, 16#04, 16#69, 16#97>>,
- <<Order:264/integer>> = <<16#00, 16#a9, 16#fb, 16#57, 16#db, 16#a1, 16#ee, 16#a9,
- 16#bc, 16#3e, 16#66, 16#0a, 16#90, 16#9d, 16#83, 16#8d,
- 16#71, 16#8c, 16#39, 16#7a, 16#a3, 16#b5, 16#61, 16#a6,
- 16#f7, 16#90, 16#1e, 16#0e, 16#82, 16#97, 16#48, 16#56, 16#a7>>,
- CoFactor = 1,
- Curve = {{prime_field,P},{A,B,none},BasePoint, Order,CoFactor},
-
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),
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index 8489b59562..6dcb28ec8a 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 3.5
+CRYPTO_VSN = 3.6.3
diff --git a/lib/debugger/Makefile b/lib/debugger/Makefile
index b464c5de3e..9c761d216b 100644
--- a/lib/debugger/Makefile
+++ b/lib/debugger/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile
index 9a1eec20c1..e3f757ed2d 100644
--- a/lib/debugger/doc/src/Makefile
+++ b/lib/debugger/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/debugger/doc/src/book.xml b/lib/debugger/doc/src/book.xml
index 82ae6b5b94..5424ef2c04 100644
--- a/lib/debugger/doc/src/book.xml
+++ b/lib/debugger/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -46,4 +47,3 @@
<index/>
</book>
-
diff --git a/lib/debugger/doc/src/debugger.xml b/lib/debugger/doc/src/debugger.xml
index a04dce92d2..1ecdbcd064 100644
--- a/lib/debugger/doc/src/debugger.xml
+++ b/lib/debugger/doc/src/debugger.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2013</year>
+ <year>2002</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,7 +29,7 @@
<rev></rev>
</header>
<module>debugger</module>
- <modulesummary>Erlang Debugger</modulesummary>
+ <modulesummary>Erlang Debugger.</modulesummary>
<description>
<p>Erlang Debugger for debugging and testing of Erlang programs.</p>
</description>
@@ -47,14 +48,14 @@
<desc>
<p>Starts Debugger.</p>
- <p>If given a file name as argument, Debugger will try to load
- its settings from this file. Refer to Debugger User's Guide
- for more information about settings.</p>
+ <p>If a filename is specified as argument, Debugger tries to load
+ its settings from this file. For details about settings, see
+ the User's Guide.</p>
- <p>If given <c>local</c> as argument, Debugger will interpret
- code only at the current node. If given <c>global</c> as
- argument, Debugger will interpret code at all known nodes,
- this is the default.</p>
+ <p>If <c>local</c> is specified as argument, Debugger interprets
+ code only at the current node. If <c>global</c> is specified as
+ argument, Debugger interprets code at all known nodes, this
+ is the default.</p>
</desc>
</func>
@@ -66,11 +67,9 @@
<v>Args = [term()]</v>
</type>
<desc>
- <p>This function can be used to debug a single process.
- The module <c>Module</c> is interpreted and
- <c>apply(Module,Name,Args)</c> is called. This will open an
- Attach Process window, refer to Debugger User's Guide for
- more information.</p>
+ <p>Debugs a single process. The module <c>Module</c> is interpreted
+ and <c>apply(Module,Name,Args)</c> is called. This opens an
+ Attach Process window. For details, see the User's Guide.</p>
</desc>
</func>
</funcs>
diff --git a/lib/debugger/doc/src/debugger_chapter.xml b/lib/debugger/doc/src/debugger_chapter.xml
index 99b6d07355..45dfdb3776 100644
--- a/lib/debugger/doc/src/debugger_chapter.xml
+++ b/lib/debugger/doc/src/debugger_chapter.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,97 +31,92 @@
</header>
<section>
- <title>Introduction</title>
+ <title>Getting Started</title>
- <p><em>Debugger</em> is a graphical user interface for the Erlang
- interpreter, which can be used for debugging and testing of
- Erlang programs. For example, breakpoints can be set, code can be
- single stepped and variable values can be displayed and changed.
- </p>
+ <p>To use Debugger, the basic steps are as follows:</p>
- <p>The Erlang interpreter can also be accessed via the interface
- module <c>int</c>, see <seealso marker="int">int(3)</seealso>.
- </p>
+ <p><em>Step 1.</em> Start Debugger by calling
+ <c>debugger:start()</c>.</p>
- <p><em>Warning:</em> Note that the Debugger at some point might
- start tracing on the processes which execute the interpreted
- code. This means that a conflict will occur if tracing by other
- means is started on any of these processes.</p>
- </section>
+ <p>The <seealso marker="#monitor">Monitor window</seealso> is
+ displayed with information about all debugged processes,
+ interpreted modules, and selected options. Initially there are
+ normally no debugged processes. First, it must be specified which
+ modules that are to be <em>debugged</em> (also called
+ <em>interpreted</em>). Proceed as follows:</p>
- <section>
- <title>Getting Started with Debugger</title>
+ <p><em>Step 2.</em> Select <em>Module > Interpret...</em> in the
+ Monitor window.</p>
- <p>Start Debugger by calling <c>debugger:start()</c>. It will start
- the <seealso marker="#monitor">Monitor window</seealso> showing
- information about all debugged processes, interpreted modules and
- selected options.</p>
+ <p>The <seealso marker="#interpret">Interpret Modules window</seealso>
+ is displayed.</p>
- <p>Initially there are normally no debugged processes. First, it
- must be specified which modules should be <em>debugged</em>, or
- <em>interpreted</em> as it is also called. This is done by
- choosing <em>Module->Interpret...</em> in the Monitor window and
- then selecting the appropriate modules from the
- <seealso marker="#interpret">Interpret Dialog window</seealso>.
- </p>
+ <p><em>Step 3.</em> Select the appropriate modules from the Interpret
+ Dialog window.</p>
<note>
- <p>Only modules compiled with the option <c>debug_info</c> set
- can be interpreted. Non-interpretable modules are shown within
- parenthesis in the Interpret Dialog window.</p>
+ <p>Only modules compiled with option <c>debug_info</c> set can be
+ interpreted. Non-interpretable modules are displayed within
+ parenthesis in the Interpret Modules window.</p>
</note>
- <p>When a module is interpreted, it can be viewed in a
- <seealso marker="#view">View Module window</seealso>. This is done
- by selecting the module from the <em>Module->module->View</em>
- menu. The contents of the source file is shown and it is possible
- to set <seealso marker="#breakpoints">breakpoints</seealso>.</p>
-
- <p>Now the program that should be debugged can be started. This is
- done the normal way from the Erlang shell. All processes executing
- code in interpreted modules will be displayed in the Monitor
- window. It is possible to <em>attach</em> to one of these
- processes, by double-clicking it, or by selecting the process and
- then choosing <em>Process->Attach</em>.</p>
-
- <p>Attaching to a process will result in a
- <seealso marker="#attach">Attach Process window</seealso> being
- opened for this process. From the Attach Process window, it is
- possible to control the process execution, inspect variable
- values, set breakpoints etc.</p>
+ <p><em>Step 4.</em> In the Monitor window, select
+ <em>Module > the module to be interpreted > View</em>.</p>
+
+ <p>The contents of the source file is displayed in the
+ <seealso marker="#view">View Module window</seealso>.</p>
+
+ <p><em>Step 5.</em> Set the
+ <seealso marker="#breakpoints">breakpoints</seealso>, if any.</p>
+
+ <p><em>Step 6.</em> Start the program to be debugged. This is done
+ the normal way from the Erlang shell.</p>
+
+ <p>All processes executing code in interpreted modules are displayed
+ in the Monitor window.</p>
+
+ <p><em>Step 7.</em> To <em>attach</em> to one of these processes,
+ double-click it, or select the process and then choose
+ <em>Process > Attach</em>. Attaching to a process opens an
+ <seealso marker="#attach">Attach Process window</seealso> for this
+ process.</p>
+
+ <p><em>Step 8.</em> From the Attach Process window, you can control
+ the process execution, inspect variable values, set breakpoints,
+ and so on.</p>
</section>
<section>
<marker id="breakpoints"/>
- <title>Breakpoints and Break Dialogue Windows</title>
+ <title>Breakpoints and Break Dialog Windows</title>
<p>Once the appropriate modules are interpreted, breakpoints can
be set at relevant locations in the source code. Breakpoints are
specified on a line basis. When a process reaches a breakpoint,
- it stops and waits for commands (step, skip, continue,...) from
- the user.</p>
+ it stops and waits for commands (<em>Step</em>, <em>Skip</em>,
+ <em>Continue</em> ...) from the user.</p>
<note>
<p>When a process reaches a breakpoint, only that process is
- stopped. Other processes are not affected.</p>
+ stopped. Other processes are not affected.</p>
</note>
- <p>Breakpoints are created and deleted using the Break menu of
- the Monitor window, View Module window and Attach Process window.
- </p>
+ <p>Breakpoints are created and deleted using the <em>Break</em> menu of
+ either the Monitor window, View Module window, or Attach Process
+ window.</p>
<section>
<title>Executable Lines</title>
- <p>To have effect, a breakpoint must be set at an
- <em>executable line</em>, which is a line of code containing an
- executable expression such as a matching or a function call.
- A blank line or a line containing a comment, function head or
- pattern in a <c>case</c>- or <c>receive</c> statement is not
- executable.</p>
+ <p>To have an effect, a breakpoint must be set at an
+ <em>executable line</em>, which is a line of code containing an
+ executable expression such as a matching or a function call.
+ A blank line or a line containing a comment, function head, or
+ pattern in a <c>case</c> statement or <c>receive</c> statement is not
+ executable.</p>
- <p>In the example below, lines number 2, 4, 6, 8 and 11 are
- executable lines:</p>
+ <p>In the following example, lines 2, 4, 6, 8, and 11 are
+ executable lines:</p>
<pre>
1: is_loaded(Module,Compiled) ->
2: case get_file(Module,Compiled) of
@@ -140,17 +136,15 @@
<title>Status and Trigger Action</title>
<p>A breakpoint can be either <em>active</em> or
- <em>inactive</em>. Inactive breakpoints are ignored.</p>
-
- <p>Each breakpoint has a <em>trigger action</em> which specifies
- what should happen when a process has reached it (and stopped):
- </p>
- <list>
- <item><em>enable</em> Breakpoint should remain active (default).
- </item>
- <item><em>disable</em> Breakpoint should be made inactive.
- </item>
- <item><em>delete</em> Breakpoint should be deleted.</item>
+ <em>inactive</em>. Inactive breakpoints are ignored.</p>
+
+ <p>Each breakpoint has a <em>trigger action</em> that specifies
+ what is to happen when a process has reached it (and stopped):</p>
+ <list type="bulleted">
+ <item><em>Enable</em> - Breakpoint is to remain active (default).
+ </item>
+ <item><em>Disable</em> - Breakpoint is to be made inactive.</item>
+ <item><em>Delete</em> - Breakpoint is to be deleted.</item>
</list>
</section>
@@ -160,54 +154,56 @@
<p>A line breakpoint is created at a certain line in a module.</p>
<image file="images/line_break_dialog.jpg">
- <icaption>The Line Break Dialog Window.</icaption>
+ <icaption>Line Break Dialog Window</icaption>
</image>
- <p>Right-clicking the Module entry will open a popup menu from
- which the appropriate module can be selected.</p>
+ <p>Right-click the <em>Module</em> entry to open a popup menu from
+ which the appropriate module can be selected.</p>
- <p>A line breakpoint can also be created (and deleted) by
- double-clicking the line when the module is displayed in
- the View Module or Attach Process window.</p>
+ <p>A line breakpoint can also be created (and deleted) by
+ double-clicking the line when the module is displayed in
+ the View Module window or Attach Process window.</p>
</section>
<section>
<title>Conditional Breakpoints</title>
<p>A conditional breakpoint is created at a certain line in
- the module, but a process reaching the breakpoint will stop
- only if a given condition is true.</p>
+ the module, but a process reaching the breakpoint stops
+ only if a specified condition is true.</p>
<p>The condition is specified by the user as a module name
- <c>CModule</c> and a function name <c>CFunction</c>. When a
- process reaches the breakpoint,
- <c>CModule:CFunction(Bindings)</c> will be evaluated. If and
- only if this function call returns <c>true</c>, the process
- will stop. If the function call returns <c>false</c>,
- the breakpoint will be silently ignored.</p>
-
- <p><c>Bindings</c> is a list of variable bindings. Use
- the function <c>int:get_binding(Variable,Bindings)</c> to
- retrieve the value of <c>Variable</c> (given as an atom).
- The function returns <c>unbound</c> or <c>{value,Value}</c>.</p>
+ <c>CModule</c> and a function name <c>CFunction</c>. When a
+ process reaches the breakpoint,
+ <c>CModule:CFunction(Bindings)</c> is evaluated. If and
+ only if this function call returns <c>true</c>, the process
+ stops. If the function call returns <c>false</c>,
+ the breakpoint is silently ignored.</p>
+
+ <p><c>Bindings</c> is a list of variable bindings. To retrieve the
+ value of <c>Variable</c> (given as an atom), use function
+ <seealso marker="int#get_binding/2"><c>int:get_binding(Variable,Bindings)</c></seealso>.
+ The function returns <c>unbound</c> or <c>{value,Value}</c>.</p>
<image file="images/cond_break_dialog.jpg">
- <icaption>The Conditional Break Dialog Window.</icaption>
+ <icaption>Conditional Break Dialog Window</icaption>
</image>
- <p>Right-clicking the Module entry will open a popup menu from
- which the appropriate module can be selected.</p>
+ <p>Right-click the <em>Module</em> entry to open a popup menu from
+ which the appropriate module can be selected.</p>
+
+ <p><em>Example:</em></p>
- <p>Example: A conditional breakpoint calling
- <c>c_test:c_break/1</c> is added at line 6 in the module
+ <p>A conditional breakpoint calling
+ <c>c_test:c_break/1</c> is added at line 6 in module
<c>fact</c>. Each time the breakpoint is reached, the function is
- called, and when <c>N</c> is equal to 3 it returns <c>true</c>,
- and the process stops.</p>
-
+ called. When <c>N</c> is equal to 3, the function returns
+ <c>true</c> and the process stops.</p>
+
<p>Extract from <c>fact.erl</c>:</p>
<pre>
-5. fac(0) -> 1;
-6. fac(N) when N > 0, is_integer(N) -> N * fac(N-1).</pre>
+5. fac(0) -> 1;
+6. fac(N) when N > 0, is_integer(N) -> N * fac(N-1).</pre>
<p>Definition of <c>c_test:c_break/1</c>:</p>
<pre>
@@ -227,18 +223,18 @@ c_break(Bindings) ->
<title>Function Breakpoints</title>
<p>A function breakpoint is a set of line breakpoints, one at
- the first line of each clause in the given function.</p>
+ the first line of each clause in the specified function.</p>
<image file="images/function_break_dialog.jpg">
- <icaption>The Function Break Dialog Window.</icaption>
+ <icaption>Function Break Dialog Window</icaption>
</image>
- <p>Right-clicking the Module entry will open a popup menu from
- which the appropriate module can be selected.</p>
+ <p>To open a popup menu from which the appropriate module can be
+ selected, right-click the <em>Module</em> entry.</p>
- <p>Clicking the Ok button (or 'Return' or 'Tab') when a module
- name has been given, will bring up all functions of the module
- in the listbox.</p>
+ <p>To bring up all functions of the module in the listbox,
+ click the <em>OK</em> button (or press the <em>Return</em>
+ or <em>Tab</em> key) when a module name has been specified,.</p>
</section>
</section>
@@ -248,7 +244,7 @@ c_break(Bindings) ->
<p>The Erlang emulator keeps track of a <em>stack trace</em>,
information about recent function calls. This information is
- used, for example, if an error occurs:</p>
+ used if an error occurs, for example:</p>
<pre>
1> <input>catch a+1.</input>
{'EXIT',{badarith,[{erlang,'+',[a,1],[]},
@@ -258,602 +254,597 @@ c_break(Bindings) ->
{shell,eval_exprs,7,[{file,"shell.erl"},{line,629}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,614}]}]}}</pre>
- <p>See the Erlang Reference Manual,
- <seealso marker="doc/reference_manual:errors">
- Errors and Error Handling</seealso>,
- for more information about the stack trace.</p>
+ <p>For details about the stack trace, see section
+ <seealso marker="doc/reference_manual:errors">Errors and Error Handling</seealso>
+ in the Erlang Reference Manual.</p>
- <p>The Debugger emulates the stack trace by keeping track of recently
+ <p>Debugger emulates the stack trace by keeping track of recently
called interpreted functions. (The real stack trace cannot be
- used, as it shows which functions of the Debugger have been
- called, rather than which interpreted functions).</p>
+ used, as it shows which functions of Debugger have been
+ called, rather than which interpreted functions.)</p>
<p>This information can be used to traverse the chain of function
- calls, using the 'Up' and 'Down' buttons of
- <seealso marker="#attach">the Attach Process window</seealso>.
- </p>
+ calls, using the <em>Up</em> and <em>Down</em> buttons in the
+ <seealso marker="#attach">Attach Process window</seealso>.</p>
- <p>By default, the Debugger only saves information about recursive
+ <p>By default, Debugger only saves information about recursive
function calls, that is, function calls that have not yet returned
- a value (option 'Stack On, No Tail').</p>
+ a value (option <em>Stack On, No Tail</em>).</p>
<p>Sometimes, however, it can be useful to save all calls, even
- tail-recursive calls. That can be done with the 'Stack On, Tail'
- option. Note that this option will consume more memory and slow
- down execution of interpreted functions when there are many
- tail-recursive calls.
- </p>
-
- <p>It is also possible to turn off the Debugger stack trace
- facility ('Stack Off'). <em>Note:</em> If an error occurs, in this
- case the stack trace will be empty.</p>
-
- <p>See the section about <seealso marker="#monitor">the Monitor
- Window</seealso> for information about how to change the stack
- trace option.</p>
+ tail-recursive calls. This is done with option
+ <em>Stack On, Tail</em>. Notice that this option consumes more
+ memory and slows down execution of interpreted functions when there
+ are many tail-recursive calls.</p>
+
+ <p>To turn off the Debugger stack trace facility, select option
+ <em>Stack Off</em>.</p>
+
+ <note>
+ <p>If an error occurs, the stack trace becomes empty in this
+ case.</p>
+ </note>
+
+ <p>For information about how to change the stack trace option, see
+ section <seealso marker="#monitor">Monitor Window</seealso>.</p>
</section>
<section>
<marker id="monitor"/>
- <title>The Monitor Window</title>
+ <title>Monitor Window</title>
+
+ <p>The Monitor window is the main window of Debugger and displays the
+ following:</p>
- <p>The Monitor window is the main window of Debugger and shows a
- listbox containing the names of all interpreted modules
- (double-clicking a module brings up the View Module window),
- which options are selected, and information about all debugged
- processes, that is all processes which have been/are executing
- code in interpreted modules.</p>
+ <list type="bulleted">
+ <item><p>A listbox containing the names of all interpreted
+ modules</p>
+ <p>Double-clicking a module brings up the View Module window.</p>
+ </item>
+ <item><p>Which options are selected</p></item>
+ <item><p>Information about all debugged processes, that is, all
+ processes that have been or are executing code in interpreted
+ modules</p></item>
+ </list>
<image file="images/monitor.jpg">
- <icaption>The Monitor Window.</icaption>
+ <icaption>Monitor Window</icaption>
</image>
- <p>The Auto Attach buttons, Stack Trace label, Back Trace Size
- label, and Strings button show some options set, see
- <seealso marker="#options">Options Menu</seealso> for further
- information about these options.</p>
+ <p>The <em>Auto Attach</em> boxes, <em>Stack Trace</em> label,
+ <em>Back Trace Size</em> label, and <em>Strings</em> box display
+ some options set. For details about these options, see section
+ <seealso marker="#options">Options Menu</seealso>.</p>
<section>
<title>Process Grid</title>
-
<taglist>
<tag><em>Pid</em></tag>
<item><p>The process identifier.</p></item>
-
+
<tag><em>Initial Call</em></tag>
<item><p>The first call to an interpreted function by this
- process. (<c>Module:Function/Arity</c>)</p></item>
+ process. (<c>Module:Function/Arity</c>)</p></item>
<tag><em>Name</em></tag>
- <item><p>The registered name, if any. If a registered name does
- not show up, it may be that the Debugger received
- information about the process before the name had been
- registered. Try selecting <em>Edit->Refresh</em>.</p></item>
+ <item><p>The registered name, if any. If a registered name is not
+ displayed, it can be that Debugger received information about
+ the process before the name was registered. Try selecting
+ <em>Edit > Refresh</em>.</p></item>
<tag><em>Status</em></tag>
<item><p>The current status, one of the following:</p>
<taglist>
<tag><em>idle</em></tag>
- <item><p>The interpreted function call has returned a value,
- and the process is no longer executing interpreted code.
- </p></item>
+ <item><p>The interpreted function call has returned a value, and
+ the process is no longer executing interpreted code.</p></item>
<tag><em>running</em></tag>
<item><p>The process is running.</p></item>
-
+
<tag><em>waiting</em></tag>
<item><p>The process is waiting in a <c>receive</c>
- statement.</p></item>
-
+ statement.</p></item>
+
<tag><em>break</em></tag>
<item><p>The process is stopped at a breakpoint.</p></item>
-
+
<tag><em>exit</em></tag>
<item><p>The process has terminated.</p></item>
-
+
<tag><em>no_conn</em></tag>
<item><p>There is no connection to the node where
- the process is located.</p></item>
+ the process is located.</p></item>
</taglist>
</item>
<tag><em>Information</em></tag>
- <item><p>Additional information, if any. If the process is
- stopped at a breakpoint, the field contains information
- about the location <c>{Module,Line}</c>. If the process has
- terminated, the field contains the exit reason.</p></item>
+ <item><p>More information, if any. If the process is
+ stopped at a breakpoint, the field contains information
+ about the location <c>{Module,Line}</c>. If the process has
+ terminated, the field contains the exit reason.</p></item>
</taglist>
</section>
<section>
- <title>The File Menu</title>
-
+ <title>File Menu</title>
+
<taglist>
<tag><em>Load Settings...</em></tag>
- <item>
- <p>Try to load and restore Debugger settings from a file
- previously saved using <em>Save Settings...</em>, see below.
- Any errors are silently ignored.
- <em>Note:</em> Settings saved by Erlang R16B01 or later
- cannot be read by Erlang R16B or earlier.</p>
+ <item><p>Tries to load and restore Debugger settings from a file
+ previously saved using <em>Save Settings...</em> (see below).
+ Any errors are silently ignored.</p>
+ <p>Notice that settings saved by Erlang/OTP R16B01 or later
+ cannot be read by Erlang/OTP R16B or earlier.</p>
</item>
-
+
<tag><em>Save Settings...</em></tag>
- <item><p>Save Debugger settings to a file. The settings include
- the set of interpreted files, breakpoints, and the selected
- options. The settings can be restored in a later Debugger
- session using <em>Load Settings...</em>, see above.
- Any errors are silently ignored.</p>
+ <item><p>Saves Debugger settings to a file. The settings include
+ the set of interpreted files, breakpoints, and the selected
+ options. The settings can be restored in a later Debugger
+ session using <em>Load Settings...</em> (see above).
+ Any errors are silently ignored.</p>
</item>
-
+
<tag><em>Exit</em></tag>
- <item><p>Stop Debugger.</p></item>
+ <item><p>Stops Debugger.</p></item>
</taglist>
</section>
<section>
- <title>The Edit Menu</title>
+ <title>Edit Menu</title>
<taglist>
<tag><em>Refresh</em></tag>
- <item><p>Update information about debugged processes. Removes
- information about all terminated processes from the window,
- and also closes all Attach Process windows for terminated
- processes.</p></item>
+ <item><p>Updates information about debugged processes. Information
+ about all terminated processes are removed from the window. All
+ Attach Process windows for terminated processes are closed.</p></item>
<tag><em>Kill All</em></tag>
- <item><p>Terminate all processes listed in the window using
- <c>exit(Pid,kill)</c>.</p></item>
+ <item><p>Terminates all processes listed in the window using
+ <c>exit(Pid,kill)</c>.</p></item>
</taglist>
</section>
<section>
- <title>The Module Menu</title>
+ <title>Module Menu</title>
<taglist>
<tag><em>Interpret...</em></tag>
- <item><p>Open the <seealso marker="#interpret">Interpret Dialog
- window</seealso> where new modules to be interpreted can
- be specified.</p></item>
-
+ <item><p>Opens the
+ <seealso marker="#interpret">Interpret Modules window</seealso>,
+ where new modules to be interpreted can be specified.</p></item>
+
<tag><em>Delete All</em></tag>
- <item><p>Stop interpreting all modules. Processes executing in
- interpreted modules will terminate.</p></item>
+ <item><p>Stops interpreting all modules. Processes executing in
+ interpreted modules terminate.</p></item>
</taglist>
<p>For each interpreted module, a corresponding entry is added to
- the Module menu, with the following submenu:</p>
+ the <em>Module</em> menu, with the following submenu:</p>
<taglist>
<tag><em>Delete</em></tag>
- <item><p>Stop interpreting the selected module. Processes
- executing in this module will terminate.</p></item>
-
+ <item><p>Stops interpreting the selected module. Processes
+ executing in this module terminate.</p></item>
+
<tag><em>View</em></tag>
- <item><p>Open a <seealso marker="#view">View Module
- window</seealso> showing the contents of the selected
- module.</p></item>
+ <item><p>Opens a
+ <seealso marker="#view">View Module window</seealso>, displaying the
+ contents of the selected module.</p></item>
</taglist>
</section>
<section>
- <title>The Process Menu</title>
+ <title>Process Menu</title>
<p>The following menu items apply to the currently selected
- process, provided it is stopped at a breakpoint. See the chapter
- about the <seealso marker="#attach">Attach Process
- window</seealso> for more information.</p>
+ process, provided it is stopped at a breakpoint (for details, see
+ section
+ <seealso marker="#attach">Attach Process window</seealso>):</p>
<taglist>
<tag><em>Step</em></tag><item></item>
<tag><em>Next</em></tag><item></item>
<tag><em>Continue</em></tag><item></item>
<tag><em>Finish</em></tag><item></item>
</taglist>
+
<p>The following menu items apply to the currently selected
- process.</p>
+ process:</p>
<taglist>
<tag><em>Attach</em></tag>
- <item><p>Attach to the process and open a
- <seealso marker="#attach">Attach Process window</seealso>.
- </p></item>
-
+ <item><p>Attaches to the process and open an
+ <seealso marker="#attach">Attach Process window</seealso>.</p></item>
+
<tag><em>Kill</em></tag>
- <item><p>Terminate the process using <c>exit(Pid,kill)</c>.</p>
- </item>
+ <item><p>Terminates the process using <c>exit(Pid,kill)</c>.</p></item>
</taglist>
</section>
- <section>
- <title>The Break Menu</title>
- <p>The items in this menu are used to create and delete
- breakpoints.
- See the <seealso marker="#breakpoints">Breakpoints</seealso>
- chapter for more information.</p>
+ <section>
+ <title>Break Menu</title>
+ <p>The items in this menu are used to create and delete breakpoints.
+ For details, see section
+ <seealso marker="#breakpoints">Breakpoints</seealso>.</p>
+
<taglist>
<tag><em>Line Break...</em></tag>
- <item><p>Set a line breakpoint.</p></item>
+ <item><p>Sets a line breakpoint.</p></item>
<tag><em>Conditional Break...</em></tag>
- <item><p>Set a conditional breakpoint.</p></item>
+ <item><p>Sets a conditional breakpoint.</p></item>
<tag><em>Function Break...</em></tag>
- <item><p>Set a function breakpoint.</p></item>
+ <item><p>Sets a function breakpoint.</p></item>
<tag><em>Enable All</em></tag>
- <item><p>Enable all breakpoints.</p></item>
+ <item><p>Enables all breakpoints.</p></item>
<tag><em>Disable All</em></tag>
- <item><p>Disable all breakpoints.</p></item>
+ <item><p>Disables all breakpoints.</p></item>
- <tag><em>Delete All</em></tag>
- <item><p>Remove all breakpoints.</p></item>
+ <tag><em>Delete All</em></tag>
+ <item><p>Removes all breakpoints.</p></item>
</taglist>
- <p>For each breakpoint, a corresponding entry is added to
- the Break
- menu, from which it is possible to disable/enable or delete
- the breakpoint, and to change its trigger action.</p>
+ <p>For each breakpoint, a corresponding entry is added to the
+ <em>Break</em> menu, from which it is possible to disable, enable,
+ or delete the breakpoint, and to change its trigger action.</p>
</section>
<section>
<marker id="options"/>
- <title>The Options Menu</title>
+ <title>Options Menu</title>
<taglist>
<tag><em>Trace Window</em></tag>
- <item><p>Set which areas should be visible in
- an <seealso marker="#attach">Attach Process
- window</seealso>. Does not affect already existing
- Attach Process windows.</p>
+ <item><p>Sets the areas to be visible in an
+ <seealso marker="#attach">Attach Process window</seealso>.
+ Does not affect existing Attach Process windows.</p>
</item>
<tag><em>Auto Attach</em></tag>
- <item><p>Set at which events a debugged process should be
- automatically attached to. Affects existing debugged
- processes.</p>
- <list>
- <item><em>First Call</em> - the first time a process calls a
- function in an interpreted module.</item>
- <item><em>On Exit</em> - at process termination.</item>
- <item><em>On Break</em> - when a process reaches a
- breakpoint.</item>
+ <item><p>Sets the events a debugged process is to be attached
+ to automatically. Affects existing debugged processes.</p>
+ <list type="bulleted">
+ <item><p><em>First Call</em> - The first time a process calls
+ a function in an interpreted module.</p></item>
+ <item><p><em>On Exit</em> - At process termination.</p></item>
+ <item><p><em>On Break</em> - When a process reaches a
+ breakpoint.</p></item>
</list>
</item>
<tag><em>Stack Trace</em></tag>
- <item><p>Set stack trace option, see section
+ <item><p>Sets the stack trace option, see section
<seealso marker="#stack_trace">Stack Trace</seealso>. Does not
- affect already existing debugged processes.</p>
- <list>
- <item><em>Stack On, Tail</em> - save information about all
- current calls.</item>
- <item><em>Stack On, No Tail</em> - save information about
+ affect existing debugged processes.</p>
+ <list type="bulleted">
+ <item><p><em>Stack On, Tail</em> - Saves information about all
+ current calls.</p></item>
+ <item><p><em>Stack On, No Tail</em> - Saves information about
current calls, discarding previous information when a tail
- recursive call is made.</item>
- <item><em>Stack Off</em> - do not save any information about
- current calls.</item>
+ recursive call is made.</p></item>
+ <item><p><em>Stack Off</em> - Does not save any information about
+ current calls.</p></item>
</list>
</item>
<tag><em>Strings</em></tag>
- <item><p>Set which integer lists should be printed as strings.
- Does not affect already existing debugged processes.</p>
- <list>
-
- <item><em>Use range of +pc flag</em> - use the printable
- character range set by the
- <seealso marker="erts:erl#printable_character_range">
- <c>erl(1)</c></seealso> flag <c>+pc</c>.
- </item>
+ <item><p>Sets the integer lists to be printed as strings.
+ Does not affect existing debugged processes.</p>
+ <list type="bulleted">
+ <item><p><em>Use range of +pc flag</em> - Uses the printable
+ character range set by the <c>erl(1)</c> flag
+ <seealso marker="erts:erl#printable_character_range"><c>+pc</c></seealso>.</p>
+ </item>
</list>
</item>
<tag><em>Back Trace Size...</em></tag>
- <item><p>Set how many call frames should be fetched when
- inspecting the call stack from the Attach Process window.
- Does not affect already existing Attach Process windows.</p>
+ <item><p>Sets how many call frames to be fetched when
+ inspecting the call stack from the Attach Process window.
+ Does not affect existing Attach Process windows.</p>
</item>
</taglist>
</section>
<section>
- <title>The Windows Menu</title>
+ <title>Windows Menu</title>
<p>Contains a menu item for each open Debugger window. Selecting
- one of the items will raise the corresponding window.</p>
+ one of the items raises the corresponding window.</p>
</section>
<section>
- <title>The Help Menu</title>
+ <title>Help Menu</title>
<taglist>
<tag><em>Help</em></tag>
- <item><p>View the Debugger documentation. Currently this
- function requires a web browser to be up and running.</p></item>
+ <item><p>Shows the Debugger documentation. This function requires a
+ web browser.</p></item>
</taglist>
</section>
</section>
-
+
<section>
<marker id="interpret"/>
- <title>The Interpret Dialog Window</title>
+ <title>Interpret Modules Window</title>
- <p>The interpret dialog module is used for selecting which modules
- to interpret. Initially, the window shows the modules (<c>erl</c>
- files) and subdirectories of the current working directory.</p>
+ <p>The Interpret Modules window is used for selecting which modules
+ to interpret. Initially, the window displays the modules (<c>erl</c>
+ files) and subdirectories of the current working directory.</p>
- <p>Interpretable modules are modules for which a BEAM file, compiled
- with the option <c>debug_info</c> set, can be found in the same
+ <p>Interpretable modules are modules for which a <c>.beam</c> file,
+ compiled with option <c>debug_info</c> set, is located in the same
directory as the source code, or in an <c>ebin</c> directory next
to it.</p>
- <p>Modules, for which the above requirements are not fulfilled, are
- not interpretable and are therefore displayed within parentheses.
- </p>
+ <p>Modules for which these requirements are not fulfilled are
+ not interpretable and are therefore displayed within parentheses.</p>
- <p>The <c>debug_info</c> option causes <em>debug information</em> or
- <em>abstract code</em> to be added to the BEAM file. This will
- increase the size of the file, and also makes it possible to
+ <p>Option <c>debug_info</c> causes <em>debug information</em> or
+ <em>abstract code</em> to be added to the <c>.beam</c> file.
+ This increases the file size and makes it possible to
reconstruct the source code. It is therefore recommended not to
include debug information in code aimed for target systems.</p>
<p>An example of how to compile code with debug information using
- <c>erlc</c>:<br/>
- <c>% erlc +debug_info module.erl</c></p>
-
+ <c>erlc</c>:</p>
+ <pre>
+% erlc +debug_info module.erl</pre>
+
<p>An example of how to compile code with debug information from
- the Erlang shell:<br/>
- <c>4> c(module, debug_info).</c></p>
-
+ the Erlang shell:</p>
+ <pre>
+4> c(module, debug_info).</pre>
+
<image file="images/interpret.jpg">
- <icaption>The Interpret Dialog Window.</icaption>
+ <icaption>Interpret Modules Window</icaption>
</image>
- <p>Browse the file hierarchy and interpret the appropriate modules
- by selecting a module name and pressing <em>Choose</em> (or
- carriage return), or by double clicking the module name.
- Interpreted modules have the type <c>erl src</c>.
- </p>
+ <p>To browse the file hierarchy and interpret the appropriate modules,
+ either select a module name and click <em>Choose</em> (or
+ press carriage return), or double-click the module name.
+ Interpreted modules have the type <c>erl src</c>.</p>
- <p>Pressing <em>All</em> will interpret all displayed modules in
- the chosen directory.</p>
+ <p>To interpret all displayed modules in the chosen directory, click
+ <em>All</em>.</p>
- <p>Pressing <em>Done</em> will close the window.</p>
+ <p>To close the window, click <em>Done</em>.</p>
<note>
- <p>When the Debugger is started in global mode (which is
- the default, see
- <seealso marker="debugger:debugger#start/0">debugger:start/0</seealso>),
- modules added (or deleted) for interpretation will be added (or
- deleted) on all known Erlang nodes.</p>
+ <p>When Debugger is started in global mode (which is the default, see
+ <seealso marker="debugger#start/0">debugger:start/0</seealso>),
+ modules added (or deleted) for interpretation are added (or
+ deleted) on all known Erlang nodes.</p>
</note>
</section>
<section>
<marker id="attach"/>
- <title>The Attach Process Window</title>
+ <title>Attach Process Window</title>
- <p>From an Attach Process window the user can interact with a
+ <p>From an Attach Process window, you can interact with a
debugged process. One window is opened for each process that has
- been attached to. Note that when attaching to a process, its
- execution is automatically stopped.
- </p>
+ been attached to. Notice that when attaching to a process, its
+ execution is automatically stopped.</p>
<image file="images/attach.jpg">
- <icaption>The Attach Process Window.</icaption>
+ <icaption>Attach Process Window</icaption>
</image>
- <p>The window is divided into five parts:</p>
- <list>
- <item><p>The Code area, showing the code being executed. The code
- is indented and each line is prefixed with its line number.
- If the process execution is stopped, the current line is
- marked with <em>--></em>. An existing break point at a line
- is marked with a stop symbol. In the example above,
- the execution has been stopped at line 6, before
- the execution of <c>fac/1</c>.</p>
- <p>Active breakpoints are shown in red, while inactive
- breakpoints are shown in blue.</p>
+ <p>The window is divided into the following five parts:</p>
+ <list type="bulleted">
+ <item><p>The Code area, displaying the code being executed. The code
+ is indented and each line is prefixed with its line number.
+ If the process execution is stopped, the current line is
+ marked with <c>--></c>. An existing break point at a line
+ is marked with a stop symbol. In the example shown in the
+ illustration, the execution stopped at line 6, before
+ the execution of <c>fac/1</c>.</p>
+
+ <p>Active breakpoints are displayed in red and inactive
+ breakpoints in blue.</p>
</item>
- <item>The Button area, with buttons for quick access to frequently
- used functions in the Process menu.</item>
- <item>The Evaluator area, where the user can evaluate functions
- within the context of the debugged process, provided that
- process execution has been stopped.</item>
- <item>The Bindings area, showing all variables bindings.
- Clicking on a variable name will result in the value being
- displayed in the Evaluator area.
- Double-clicking on a variable name will open a window where
- the variable value may be edited. Note however that pid,
- reference, binary or port values can not be edited.
+
+ <item><p>The Button area, with buttons for quick access to frequently
+ used functions in the <em>Process</em> menu.</p></item>
+
+ <item><p>The Evaluator area, where you can evaluate functions
+ within the context of the debugged process, if that
+ process execution is stopped.</p></item>
+
+ <item><p>The Bindings area, displaying all variables bindings. If you
+ click a variable name, the value is displayed in the Evaluator area.
+ Double-click a variable name to open a window where
+ the variable value can be edited. Notice however that pid,
+ reference, binary, or port values cannot be edited.</p>
</item>
- <item><p>The Trace area, showing a trace output for the process.
- </p>
+
+ <item><p>The Trace area, which displays a trace output for the
+ process.</p>
<taglist>
- <tag><c>++ (N) &lt;L&gt;</c></tag>
- <item>Function call, where <c>N</c> is the call level and
- <c>L</c> the line number.</item>
+ <tag><c>++ (N) &lt;L&gt;</c></tag>
+ <item><p>Function call, where <c>N</c> is the call level and
+ <c>L</c> the line number.</p></item>
- <tag><c>-- (N)</c></tag>
- <item>Function return value.</item>
+ <tag><c>-- (N)</c></tag>
+ <item><p>Function return value</p>.</item>
- <tag><c>==> Pid : Msg</c></tag>
- <item>The message <c>Msg</c> is sent to process <c>Pid</c>.
- </item>
+ <tag><c>==> Pid : Msg</c></tag>
+ <item><p>The message <c>Msg</c> is sent to process
+ <c>Pid</c>.</p></item>
- <tag><c><![CDATA[<== Msg]]></c></tag>
- <item>The message <c>Msg</c> is received.</item>
+ <tag><c><![CDATA[<== Msg]]></c></tag>
+ <item><p>The message <c>Msg</c> is received.</p></item>
- <tag><c>++ (N) receive</c></tag>
- <item>Waiting in a <c>receive</c>.</item>
+ <tag><c>++ (N) receive</c></tag>
+ <item><p>Waiting in a <c>receive</c>.</p></item>
- <tag><c>++ (N) receive with timeout</c></tag>
- <item>Waiting in a <c>receive...after</c>.</item>
- </taglist>
+ <tag><c>++ (N) receive with timeout</c></tag>
+ <item><p>Waiting in a <c>receive...after</c>.</p></item>
+ </taglist>
- <p>Also the back trace, a summary of the current function calls
- on the stack, is displayed in the Trace area.</p>
+ <p>The Trace area also displays Back Trace, a summary of the
+ current function calls on the stack.</p>
</item>
</list>
- <p>It is configurable using the Options menu which areas should
- be shown or hidden. By default, all areas except the Trace area
- are shown.</p>
+ <p>Using the <em>Options</em> menu, you can set which areas to be
+ displayed. By default, all areas except the Trace area are displayed.</p>
<section>
- <title>The File Menu</title>
+ <title>File Menu</title>
<taglist>
<tag><em>Close</em></tag>
- <item><p>Close this window and detach from the process.</p>
+ <item><p>Closes this window and detach from the process.</p>
</item>
</taglist>
</section>
<section>
- <title>The Edit Menu</title>
+ <title>Edit Menu</title>
<taglist>
<tag><em>Go to line...</em></tag>
- <item><p>Go to a specified line number.</p></item>
+ <item><p>Goes to a specified line number.</p></item>
<tag><em>Search...</em></tag>
- <item><p>Search for a specified string.</p></item>
+ <item><p>Searches for a specified string.</p></item>
</taglist>
</section>
<section>
- <title>The Process Menu</title>
+ <title>Process Menu</title>
<taglist>
<tag><em>Step</em></tag>
- <item><p>Execute the current line of code, stepping into any
+ <item><p>Executes the current code line, stepping into any
(interpreted) function calls.</p></item>
<tag><em>Next</em></tag>
- <item><p>Execute the current line of code and stop at the next
+ <item><p>Executes the current code line and stop at the next
line.</p></item>
<tag><em>Continue</em></tag>
- <item><p>Continue the execution.</p></item>
+ <item><p>Continues the execution.</p></item>
<tag><em>Finish</em></tag>
- <item><p>Continue the execution until the current function
+ <item><p>Continues the execution until the current function
returns.</p></item>
<tag><em>Skip</em></tag>
- <item><p>Skip the current line of code and stop at the next
+ <item><p>Skips the current code line and stop at the next
line. If used on the last line in a function body,
- the function will return <c>skipped</c>.</p></item>
+ the function returns <c>skipped</c>.</p></item>
<tag><em>Time Out</em></tag>
- <item><p>Simulate a timeout when executing a
+ <item><p>Simulates a time-out when executing a
<c>receive...after</c> statement.</p></item>
<tag><em>Stop</em></tag>
- <item><p>Stop the execution of a running process, that is, make
- the process stop as at a breakpoint. The command will take
+ <item><p>Stops the execution of a running process, that is, make
+ the process stop at a breakpoint. The command takes
effect (visibly) the next time the process receives a
message.</p></item>
<tag><em>Where</em></tag>
- <item><p>Make sure the current location of the execution is
+ <item><p>Verifies that the current location of the execution is
visible in the code area.</p></item>
<tag><em>Kill</em></tag>
- <item><p>Terminate the process using <c>exit(Pid,kill)</c>.</p>
+ <item><p>Terminates the process using <c>exit(Pid,kill)</c>.</p>
</item>
<tag><em>Messages</em></tag>
- <item><p>Inspect the message queue of the process. The queue is
- printed in the evaluator area.</p></item>
+ <item><p>Inspects the message queue of the process. The queue is
+ displayed in the Evaluator area.</p></item>
<tag><em>Back Trace</em></tag>
- <item><p>Display the back trace of the process, a summary of
- the current function calls on the stack, in the trace area.
- Requires that the Trace area is visible and that the stack
- trace option is 'Stack On, Tail' or 'Stack On, No Tail'.</p>
+ <item><p>Displays the back trace of the process, a summary of
+ the current function calls on the stack, in the Trace area.
+ Requires that the Trace area is visible and that the Stack
+ Trace option is <em>Stack On, Tail</em> or
+ <em>Stack On, No Tail</em>.</p>
</item>
<tag><em>Up</em></tag>
- <item><p>Inspect the previous function call on the stack,
+ <item><p>Inspects the previous function call on the stack,
showing the location and variable bindings.</p></item>
<tag><em>Down</em></tag>
- <item><p>Inspect the next function call on the stack, showing
+ <item><p>Inspects the next function call on the stack, showing
the location and variable bindings.</p></item>
</taglist>
</section>
<section>
- <title>The Options Menu</title>
+ <title>Options Menu</title>
<taglist>
<tag><em>Trace Window</em></tag>
- <item><p>Set which areas should be visible. Does not affect
- other Attach Process windows.</p>
- </item>
+ <item><p>Sets which areas are to be visible. Does not affect
+ other Attach Process windows.</p></item>
<tag><em>Stack Trace</em></tag>
- <item><p>Same as in <seealso marker="#monitor">the Monitor
- window</seealso>, but only affects the debugged
- process the window is attached to.</p>
- </item>
+ <item><p>Same as in the <seealso marker="#monitor">Monitor
+ window</seealso>, but only affects the debugged
+ process the window is attached to.</p></item>
<tag><em>Strings</em></tag>
- <item><p>Same as in <seealso marker="#monitor">the Monitor
- window</seealso>, but only affects the debugged
- process the window is attached to.</p>
- </item>
+ <item><p>Same as in the <seealso marker="#monitor">Monitor
+ window</seealso>, but only affects the debugged
+ process the window is attached to.</p></item>
<tag><em>Back Trace Size...</em></tag>
- <item><p>Set how many call frames should be fetched when
+ <item><p>Sets how many call frames are to be fetched when
inspecting the call stack. Does not affect other Attach
- Process windows.</p>
- </item>
+ Process windows.</p></item>
</taglist>
</section>
<section>
- <title>Break, Windows and Help Menus</title>
+ <title>Break, Windows, and Help Menus</title>
- <p>The Break, Windows and Help menus look the same as in
- the Monitor window, see the chapter
- <seealso marker="#monitor">The Monitor Window</seealso>, except
- that the Breaks menu apply to the local breakpoints only.</p>
+ <p>The <em>Break</em>, <em>Windows</em>, and <em>Help</em> menus
+ are the same as in the
+ <seealso marker="#monitor">Monitor Window</seealso>, except
+ that the <em>Breaks</em> menu applies only to local
+ breakpoints.</p>
</section>
</section>
<section>
<marker id="view"/>
- <title>The View Module Window</title>
+ <title>View Module Window</title>
- <p>The View Module window shows the contents of an interpreted
+ <p>The View Module window displays the contents of an interpreted
module and makes it possible to set breakpoints.</p>
<image file="images/view.jpg">
- <icaption>The View Module Window.</icaption>
+ <icaption>View Module Window</icaption>
</image>
<p>The source code is indented and each line is prefixed with its
line number.</p>
- <p>Clicking a line will highlight it and select it to be the target
- of the breakpoint functions available from the Break menu.
- Doubleclicking a line will set a line breakpoint on that line.
- Doubleclicking a line with an existing breakpoint will remove
- the breakpoint.</p>
+ <p>Clicking a line highlights it and selects it to be the target
+ of the breakpoint functions available from the <em>Break</em> menu.
+ To set a line breakpoint on a line, double-click it.
+ To remove the breakpoint, double-click the line with an existing
+ breakpoint.</p>
<p>Breakpoints are marked with a stop symbol.</p>
<section>
<title>File and Edit Menus</title>
- <p>The File and Edit menus look the same as in the Attach Process
- window, see the chapter <seealso marker="#attach">The Attach
- Process Window</seealso>.</p>
+ <p>The <em>File</em> and <em>Edit</em> menus are the same as in the
+ <seealso marker="#attach">Attach Process Window</seealso>.</p>
</section>
<section>
- <title>Break, Windows and Help Menus</title>
+ <title>Break, Windows, and Help Menus</title>
- <p>The Break, Windows and Help menus look the same as in
- the Monitor window, see the chapter
- <seealso marker="#monitor">The Monitor Window</seealso>, except
- that the Breaks menu apply to the local breakpoints only.</p>
+ <p>The <em>Break</em>, <em>Windows</em>, and <em>Help</em> menus
+ are the same as in the
+ <seealso marker="#monitor">Monitor Window</seealso>, except
+ that the <em>Break</em> menu applies only to local breakpoints.</p>
</section>
</section>
@@ -861,14 +852,14 @@ c_break(Bindings) ->
<title>Performance</title>
<p>Execution of interpreted code is naturally slower than for
- regularly compiled modules. Using the Debugger also increases
+ regularly compiled modules. Using Debugger also increases
the number of processes in the system, as for each debugged
process another process (the meta process) is created.</p>
- <p>It is also worth to keep in mind that programs with timers may
+ <p>It is also worth to keep in mind that programs with timers can
behave differently when debugged. This is especially true when
- stopping the execution of a process, for example at a
- breakpoint. Timeouts can then occur in other processes that
+ stopping the execution of a process (for example, at a
+ breakpoint). Time-outs can then occur in other processes that
continue execution as normal.</p>
</section>
@@ -877,8 +868,8 @@ c_break(Bindings) ->
<p>Code loading works almost as usual, except that interpreted
modules are also stored in a database and debugged processes
- uses only this stored code. Re-interpreting an interpreted
- module will result in the new version being stored as well, but
+ use only this stored code. Reinterpreting an interpreted
+ module results in the new version being stored as well, but
does not affect existing processes executing an older version
of the code. This means that the code replacement mechanism of
Erlang does not work for debugged processes.</p>
@@ -887,22 +878,24 @@ c_break(Bindings) ->
<section>
<title>Debugging Remote Nodes</title>
- <p>By using <c>debugger:start/1</c>, it can be specified if Debugger
- should be started in local or global mode.</p>
+ <p>By using
+ <seealso marker="debugger#start/1">debugger:start/1</seealso>,
+ you can specify if Debugger is to be started in local or global
+ mode:</p>
<pre>
debugger:start(local | global)</pre>
- <p>If no argument is provided, Debugger is started in global mode.
- </p>
+
+ <p>If no argument is provided, Debugger starts in global mode.</p>
<p>In local mode, code is interpreted only at the current node.
In global mode, code is interpreted at all known nodes. Processes
- at other nodes executing interpreted code will automatically be
- shown in the Monitor window and can be attached to like any other
+ at other nodes executing interpreted code are automatically
+ displayed in the Monitor window and can be attached to like any other
debugged process.</p>
- <p>It is possible, but definitely not recommended to start Debugger
- in global mode on more than one node in a network, as they will
- interfere with each other leading to inconsistent behaviour.</p>
+ <p>It is possible, but definitely not recommended, to start Debugger
+ in global mode on more than one node in a network, as the nodes
+ interfere with each other, leading to inconsistent behavior.</p>
</section>
</chapter>
diff --git a/lib/debugger/doc/src/i.xml b/lib/debugger/doc/src/i.xml
index 7564da79b3..db89f23494 100644
--- a/lib/debugger/doc/src/i.xml
+++ b/lib/debugger/doc/src/i.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2013</year>
+ <year>1998</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,35 +29,36 @@
<rev></rev>
</header>
<module>i</module>
- <modulesummary>Debugger/Interpreter Interface</modulesummary>
+ <modulesummary>Debugger/Interpreter Interface.</modulesummary>
<description>
- <p>The module <c>i</c> provides short forms for some of
+ <p>The <c>i</c> module provides short forms for some of
the functions used by the graphical Debugger and some of
- the functions in the <c>int</c> module, the Erlang interpreter.
- </p>
+ the functions in module
+ <seealso marker="int"><c>int</c></seealso>, the Erlang interpreter.</p>
<p>This module also provides facilities for displaying status
information about interpreted processes and break points.</p>
<p>It is possible to attach to interpreted processes by giving
the corresponding process identity only. By default, an attachment
- window pops up. Processes at other Erlang nodes can be
+ window is displayed. Processes at other Erlang nodes can be
attached manually or automatically.</p>
- <p>By preference, these functions can be included in the module
- <c>shell_default</c>. By default, they are.</p>
+ <p>By preference, these functions can be included in module
+ <seealso marker="stdlib:shell_default"><c>stdlib:shell_default</c></seealso>.
+ By default, they are included in that module.</p>
</description>
<funcs>
<func>
<name>im() -> pid()</name>
- <fsummary>Start a graphical monitor</fsummary>
+ <fsummary>Start a graphical monitor.</fsummary>
<desc>
<p>Starts a new graphical monitor. This is the Monitor window,
- the main window of the Debugger. All of the Debugger and
+ the main window of Debugger. All the Debugger and
interpreter functionality is accessed from the Monitor window.
- The Monitor window displays the status of all processes that
- have been/are executing interpreted modules.</p>
+ This window displays the status of all processes that
+ have been or are executing interpreted modules.</p>
</desc>
</func>
@@ -65,7 +67,7 @@
<name>ii(AbsModule) -> {module, Module} | error</name>
<name>ini(AbsModules) -> ok</name>
<name>ini(AbsModule) -> {module, Module} | error</name>
- <fsummary>Interpret a module</fsummary>
+ <fsummary>Interpret a module.</fsummary>
<type>
<v>AbsModules = [AbsModule]</v>
<v>AbsModule = Module | File</v>
@@ -84,7 +86,7 @@
<func>
<name>iq(AbsModule) -> ok</name>
<name>inq(AbsModule) -> ok</name>
- <fsummary>Stop interpreting a module</fsummary>
+ <fsummary>Stop interpreting a module.</fsummary>
<type>
<v>AbsModule = Module | File</v>
<v>&nbsp;Module = atom()</v>
@@ -109,28 +111,27 @@
<func>
<name>ip() -> ok</name>
- <fsummary>Make a printout of the current status of all interpreted
- processes</fsummary>
+ <fsummary>Print the current status of all interpreted
+ processes.</fsummary>
<desc>
- <p>Makes a printout of the current status of all interpreted
- processes.</p>
+ <p>Prints the current status of all interpreted processes.</p>
</desc>
</func>
<func>
<name>ic() -> ok</name>
<fsummary>Clear information about processes executing interpreted
- code</fsummary>
+ code.</fsummary>
<desc>
<p>Clears information about processes executing interpreted code
- byt removing all information about terminated processes.</p>
+ by removing all information about terminated processes.</p>
</desc>
</func>
<func>
<name>iaa(Flags) -> true</name>
<name>iaa(Flags, Function) -> true</name>
- <fsummary>Set when and how to attach to a process</fsummary>
+ <fsummary>Set when and how to attach to a process.</fsummary>
<type>
<v>Flags = [init | break | exit]</v>
<v>Function = {Module,Name,Args}</v>
@@ -138,42 +139,41 @@
<v>&nbsp;Args = [term()]</v>
</type>
<desc>
- <p>Sets when and how to automatically attach to a debugged
- process, see
+ <p>Sets when and how to attach to a debugged process
+ automatically, see
<seealso marker="int#auto_attach/0">int:auto_attach/2</seealso>.
<c>Function</c> defaults to the standard function used by
- the Debugger.</p>
+ Debugger.</p>
</desc>
</func>
<func>
<name>ist(Flag) -> true</name>
- <fsummary>Set how to save call frames</fsummary>
+ <fsummary>Set how to save call frames.</fsummary>
<type>
<v>Flag = all | no_tail | false</v>
</type>
<desc>
<p>Sets how to save call frames in the stack, see
- <seealso marker="int#stack_trace/0">int:stack_trace/1</seealso>.
- </p>
+ <seealso marker="int#stack_trace/0">int:stack_trace/1</seealso>.</p>
</desc>
</func>
<func>
<name>ia(Pid) -> ok | no_proc</name>
- <fsummary>Attach to a process</fsummary>
+ <fsummary>Attache to a process.</fsummary>
<type>
<v>Pid = pid()</v>
</type>
<desc>
- <p>Attaches to the debugged process <c>Pid</c>. A Debugger
+ <p>Attaches to the debugged process <c>Pid</c>. An
Attach Process window is opened for the process.</p>
</desc>
</func>
<func>
<name>ia(X,Y,Z) -> ok | no_proc</name>
- <fsummary>Attach to a process</fsummary>
+ <fsummary>Attache to a process.</fsummary>
<type>
<v>X = Y = Z = int()</v>
</type>
@@ -185,7 +185,7 @@
<func>
<name>ia(Pid, Function) -> ok | no_proc</name>
- <fsummary>Attach to a process</fsummary>
+ <fsummary>Attache to a process.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Function = {Module,Name}</v>
@@ -193,14 +193,14 @@
</type>
<desc>
<p>Attaches to the debugged process <c>Pid</c>. The interpreter
- will call <c>spawn(Module, Name, [Pid])</c> (and ignore
+ calls <c>spawn(Module, Name, [Pid])</c> (and ignores
the result).</p>
</desc>
</func>
<func>
<name>ia(X,Y,Z, Function) -> ok | no_proc</name>
- <fsummary>Attach to a process</fsummary>
+ <fsummary>Attache to a process.</fsummary>
<type>
<v>X = Y = Z = int()</v>
<v>Function = {Module,Name}</v>
@@ -210,15 +210,15 @@
<p>Same as <c>ia(Pid, Function)</c>, where <c>Pid</c> is
the result of calling the shell function <c>pid(X,Y,Z)</c>.
An attached process is expected to call the unofficial
- <c>int:attached(Pid)</c> function and to be able to handle
- messages from the interpreter, see <c>dbg_wx_trace.erl</c> for
- an example.</p>
+ function <c>int:attached(Pid)</c> and to be able to handle
+ messages from the interpreter. For an example, see
+ <c>dbg_wx_trace.erl</c>.</p>
</desc>
</func>
<func>
<name>ib(Module, Line) -> ok | {error, break_exists}</name>
- <fsummary>Create a breakpoint</fsummary>
+ <fsummary>Create a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
@@ -231,20 +231,20 @@
<func>
<name>ib(Module, Name, Arity) -> ok | {error, function_not_found}
</name>
- <fsummary>Create breakpoints in the specified function</fsummary>
+ <fsummary>Create breakpoints in the specified function.</fsummary>
<type>
<v>Module = Name = atom()</v>
<v>Arity = int()</v>
</type>
<desc>
<p>Creates breakpoints at the first line of every clause of
- the <c>Module:Name/Arity</c> function.</p>
+ function <c>Module:Name/Arity</c>.</p>
</desc>
</func>
<func>
<name>ir() -> ok</name>
- <fsummary>Delete all breakpoints</fsummary>
+ <fsummary>Delete all breakpoints.</fsummary>
<desc>
<p>Deletes all breakpoints.</p>
</desc>
@@ -252,7 +252,7 @@
<func>
<name>ir(Module) -> ok</name>
- <fsummary>Delete all breakpoints in a module</fsummary>
+ <fsummary>Delete all breakpoints in a module.</fsummary>
<type>
<v>Module = atom()</v>
</type>
@@ -263,61 +263,57 @@
<func>
<name>ir(Module, Line) -> ok</name>
- <fsummary>Delete a breakpoint</fsummary>
+ <fsummary>Delete a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
</type>
<desc>
- <p>Deletes the breakpoint located at <c>Line</c> in
- <c>Module</c>.</p>
+ <p>Deletes the breakpoint at <c>Line</c> in <c>Module</c>.</p>
</desc>
</func>
<func>
<name>ir(Module, Name, Arity) -> ok | {error, function_not_found}
</name>
- <fsummary>Delete breakpoints from the specified function
- </fsummary>
+ <fsummary>Delete breakpoints from the specified function.</fsummary>
<type>
<v>Module = Name = atom()</v>
<v>Arity = int()</v>
</type>
<desc>
<p>Deletes the breakpoints at the first line of every clause of
- the <c>Module:Name/Arity</c> function.</p>
+ function <c>Module:Name/Arity</c>.</p>
</desc>
</func>
<func>
<name>ibd(Module, Line) -> ok</name>
- <fsummary>Make a breakpoint inactive</fsummary>
+ <fsummary>Make a breakpoint inactive.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
</type>
<desc>
- <p>Makes the breakpoint at <c>Line</c> in <c>Module</c>
- inactive.</p>
+ <p>Makes the breakpoint at <c>Line</c> in <c>Module</c> inactive.</p>
</desc>
</func>
<func>
<name>ibe(Module, Line) -> ok</name>
- <fsummary>Make a breakpoint active</fsummary>
+ <fsummary>Make a breakpoint active.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
</type>
<desc>
- <p>Makes the breakpoint at <c>Line</c> in <c>Module</c> active.
- </p>
+ <p>Makes the breakpoint at <c>Line</c> in <c>Module</c> active.</p>
</desc>
</func>
<func>
<name>iba(Module, Line, Action) -> ok</name>
- <fsummary>Set the trigger action of a breakpoint</fsummary>
+ <fsummary>Set the trigger action of a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
@@ -331,7 +327,7 @@
<func>
<name>ibc(Module, Line, Function) -> ok</name>
- <fsummary>Set the conditional test of a breakpoint</fsummary>
+ <fsummary>Set the conditional test of a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
@@ -345,46 +341,44 @@
<p>The conditional test is performed by calling
<c>Module:Name(Bindings)</c>, where <c>Bindings</c> is
the current variable bindings. The function must return
- <c>true</c> (break) or <c>false</c> (do not break). Use
- <c>int:get_binding(Var, Bindings)</c> to retrieve the value
- of a variable <c>Var</c>.</p>
+ <c>true</c> (break) or <c>false</c> (do not break).
+ To retrieve the value of a variable <c>Var</c>, use
+ <seealso marker="int#get_binding/2">int:get_binding(Var, Bindings)</seealso>.</p>
</desc>
</func>
<func>
<name>ipb() -> ok</name>
- <fsummary>Make a printout of all existing breakpoints</fsummary>
+ <fsummary>Print all existing breakpoints.</fsummary>
<desc>
- <p>Makes a printout of all existing breakpoints.</p>
+ <p>Prints all existing breakpoints.</p>
</desc>
</func>
<func>
<name>ipb(Module) -> ok</name>
- <fsummary>Make a printout of all breakpoints in a module
- </fsummary>
+ <fsummary>Print all existing breakpoints in a module.</fsummary>
<type>
<v>Module = atom()</v>
</type>
<desc>
- <p>Makes a printout of all existing breakpoints in
- <c>Module</c>.</p>
+ <p>Prints all existing breakpoints in <c>Module</c>.</p>
</desc>
</func>
<func>
<name>iv() -> atom()</name>
- <fsummary>Current version number of the interpreter</fsummary>
+ <fsummary>Return the current version number of the interpreter.
+ </fsummary>
<desc>
<p>Returns the current version number of the interpreter.
- The same as the version number of the Debugger application.
- </p>
+ Same as the version number of the <c>Debugger</c> application.</p>
</desc>
</func>
<func>
<name>help() -> ok</name>
- <fsummary>Print help text</fsummary>
+ <fsummary>Print help text.</fsummary>
<desc>
<p>Prints help text.</p>
</desc>
@@ -392,15 +386,8 @@
</funcs>
<section>
- <title>Usage</title>
-
- <p>Refer to the Debugger User's Guide for information about
- the Debugger.</p>
- </section>
-
- <section>
<title>See Also</title>
- <p><c>int(3)</c></p>
+ <p><seealso marker="int"><c>int(3)</c></seealso></p>
</section>
</erlref>
diff --git a/lib/debugger/doc/src/int.xml b/lib/debugger/doc/src/int.xml
index 96d0d7f83d..31e9dfe923 100644
--- a/lib/debugger/doc/src/int.xml
+++ b/lib/debugger/doc/src/int.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2013</year>
+ <year>1998</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,16 +29,16 @@
<rev></rev>
</header>
<module>int</module>
- <modulesummary>Interpreter Interface</modulesummary>
+ <modulesummary>Interpreter Interface.</modulesummary>
<description>
<p>The Erlang interpreter provides mechanisms for breakpoints and
- stepwise execution of code. It is mainly intended to be used by
- the <em>Debugger</em>, see Debugger User's Guide and
- <c>debugger(3)</c>.</p>
+ stepwise execution of code. It is primarily intended to be used by
+ Debugger, see the User's Guide and
+ <seealso marker="debugger"><c>debugger(3)</c></seealso>.</p>
- <p>From the shell, it is possible to:</p>
- <list>
- <item>Specify which modules should be interpreted.</item>
+ <p>The following can be done from the shell:</p>
+ <list type="bulleted">
+ <item>Specify the modules to be interpreted.</item>
<item>Specify breakpoints.</item>
<item>Monitor the current status of all processes executing code
in interpreted modules, also processes at other Erlang nodes.
@@ -47,45 +48,48 @@
<p>By <em>attaching to</em> a process executing interpreted code, it
is possible to examine variable bindings and order stepwise
execution. This is done by sending and receiving information
- to/from the process via a third process, called the meta process.
- It is possible to implement your own attached process. See
+ to/from the process through a third process, called the meta
+ process. You can implement your own attached process. See
<c>int.erl</c> for available functions and <c>dbg_wx_trace.erl</c>
for possible messages.</p>
- <p>The interpreter depends on the Kernel, STDLIB and GS
- applications, which means modules belonging to any of these
- applications are not allowed to be interpreted as it could lead
+ <p>The interpreter depends on the Kernel, STDLIB, and
+ GS applications. This means that modules belonging to any of
+ these applications are not allowed to be interpreted, as it could lead
to a deadlock or emulator crash. This also applies to modules
- belonging to the Debugger application itself.</p>
+ belonging to the Debugger application.</p>
</description>
<section>
+ <marker id="int_breakpoints"/>
<title>Breakpoints</title>
<p>Breakpoints are specified on a line basis. When a process
executing code in an interpreted module reaches a breakpoint, it
- will stop. This means that that a breakpoint must be set at an
- executable line, that is, a line of code containing an executable
+ stops. This means that a breakpoint must be set at an
+ executable line, that is, a code line containing an executable
expression.</p>
- <p>A breakpoint have a status, a trigger action and may have a
- condition associated with it. The status is either <em>active</em>
- or <em>inactive</em>. An inactive breakpoint is ignored. When a
- breakpoint is reached, the trigger action specifies if
- the breakpoint should continue to be active (<em>enable</em>), if
- it should become inactive (<em>disable</em>), or if it should be
- removed (<em>delete</em>). A condition is a tuple
- <c>{Module,Name}</c>. When the breakpoint is reached,
- <c>Module:Name(Bindings)</c> is called. If this evaluates to
- <c>true</c>, execution will stop. If this evaluates to
- <c>false</c>, the breakpoint is ignored. <c>Bindings</c> contains
- the current variable bindings, use <c>get_binding</c> to retrieve
- the value for a given variable.</p>
+ <p>A breakpoint has the following:</p>
+ <list type="bulleted">
+ <item>A status, which is <em>active</em> or <em>inactive</em>. An
+ inactive breakpoint is ignored.</item>
+ <item>A trigger action. When a breakpoint is reached, the trigger
+ action specifies if the breakpoint is to continue as active
+ (<em>enable</em>), or to become inactive (<em>disable</em>), or
+ to be removed (<em>delete</em>).</item>
+ <item>Optionally an associated condition. A condition is a tuple
+ <c>{Module,Name}</c>. When the breakpoint is reached,
+ <c>Module:Name(Bindings)</c> is called. If it evaluates to
+ <c>true</c>, execution stops. If it evaluates to <c>false</c>,
+ the breakpoint is ignored. <c>Bindings</c> contains the current
+ variable bindings. To retrieve the value for a specified variable,
+ use <c>get_binding</c>.</item>
+ </list>
<p>By default, a breakpoint is active, has trigger action
- <c>enable</c> and has no condition associated with it. For more
- detailed information about breakpoints, refer to Debugger User's
- Guide.</p>
+ <c>enable</c>, and has no associated condition. For details
+ about breakpoints, see the User's Guide.</p>
</section>
<funcs>
@@ -94,7 +98,7 @@
<name>i(AbsModules) -> ok</name>
<name>ni(AbsModule) -> {module,Module} | error</name>
<name>ni(AbsModules) -> ok</name>
- <fsummary>Interpret a module</fsummary>
+ <fsummary>Interpret a module.</fsummary>
<type>
<v>AbsModules = [AbsModule]</v>
<v>AbsModule = Module | File | [Module | File]</v>
@@ -106,41 +110,43 @@
the module only at the current node. <c>ni/1</c> interprets
the module at all known nodes.</p>
- <p>A module may be given by its module name (atom) or by its
- file name. If given by its module name, the object code
+ <p>A module can be specified by its module name (atom) or
+ filename.</p>
+
+ <p>If specified by its module name, the object code
<c>Module.beam</c> is searched for in the current path.
The source code <c>Module.erl</c> is searched for first in
- the same directory as the object code, then in a <c>src</c>
+ the same directory as the object code, then in an <c>src</c>
directory next to it.</p>
- <p>If given by its file name, the file name may include a path
- and the <c>.erl</c> extension may be omitted. The object code
+ <p>If specified by its filename, the filename can include a path
+ and the <c>.erl</c> extension can be omitted. The object code
<c>Module.beam</c> is searched for first in the same directory
as the source code, then in an <c>ebin</c> directory next to
it, and then in the current path.</p>
<note>
- <p>The interpreter needs both the source code and the object
- code, and the object code <em>must</em> include debug
- information. That is, only modules compiled with the option
+ <p>The interpreter requires both the source code and the object
+ code. The object code <em>must</em> include debug
+ information, that is, only modules compiled with option
<c>debug_info</c> set can be interpreted.</p>
</note>
<p>The functions returns <c>{module,Module}</c> if the module
- was interpreted, or <c>error</c> if it was not.</p>
+ was interpreted, otherwise <c>error</c> is returned.</p>
- <p>The argument may also be a list of modules/file names, in
+ <p>The argument can also be a list of modules or filenames, in
which case the function tries to interpret each module as
- specified above. The function then always returns <c>ok</c>,
- but prints some information to stdout if a module could not be
- interpreted.</p>
+ specified earlier. The function then always returns <c>ok</c>,
+ but prints some information to <c>stdout</c> if a module
+ cannot be interpreted.</p>
</desc>
</func>
<func>
<name>n(AbsModule) -> ok</name>
<name>nn(AbsModule) -> ok</name>
- <fsummary>Stop interpreting a module</fsummary>
+ <fsummary>Stop interpreting a module.</fsummary>
<type>
<v>AbsModule = Module | File | [Module | File]</v>
<v>&nbsp;Module = atom()</v>
@@ -151,14 +157,14 @@
interpreting the module only at the current node. <c>nn/1</c>
stops interpreting the module at all known nodes.</p>
- <p>As for <c>i/1</c> and <c>ni/1</c>, a module may be given by
- either its module name or its file name.</p>
+ <p>As for <c>i/1</c> and <c>ni/1</c>, a module can be specified by
+ its module name or filename.</p>
</desc>
</func>
<func>
<name>interpreted() -> [Module]</name>
- <fsummary>Get all interpreted modules</fsummary>
+ <fsummary>Get all interpreted modules.</fsummary>
<type>
<v>Module = atom()</v>
</type>
@@ -169,20 +175,20 @@
<func>
<name>file(Module) -> File | {error,not_loaded}</name>
- <fsummary>Get the file name for an interpreted module</fsummary>
+ <fsummary>Get the filename for an interpreted module.</fsummary>
<type>
<v>Module = atom()</v>
<v>File = string()</v>
</type>
<desc>
- <p>Returns the source code file name <c>File</c> for an
+ <p>Returns the source code filename <c>File</c> for an
interpreted module <c>Module</c>.</p>
</desc>
</func>
<func>
<name>interpretable(AbsModule) -> true | {error,Reason}</name>
- <fsummary>Check if a module is possible to interpret</fsummary>
+ <fsummary>Check if a module can be interpreted.</fsummary>
<type>
<v>AbsModule = Module | File</v>
<v>&nbsp;Module = atom()</v>
@@ -192,45 +198,59 @@
<v>&nbsp;App = atom()</v>
</type>
<desc>
- <p>Checks if a module is possible to interpret. The module can
- be given by its module name <c>Module</c> or its source file
- name <c>File</c>. If given by a module name, the module is
- searched for in the code path.</p>
-
- <p>The function returns <c>true</c> if both source code and
- object code for the module is found, the module has been
- compiled with the option <c>debug_info</c> set and does not
- belong to any of the applications Kernel, STDLIB, GS or
- Debugger itself.</p>
-
- <p>The function returns <c>{error,Reason}</c> if the module for
- some reason is not possible to interpret.</p>
-
- <p><c>Reason</c> is <c>no_src</c> if no source code is found or
- <c>no_beam</c> if no object code is found. It is assumed that
- the source- and object code are located either in the same
- directory, or in <c>src</c> and <c>ebin</c> directories next
- to each other.</p>
-
- <p><c>Reason</c> is <c>no_debug_info</c> if the module has not
- been compiled with the option <c>debug_info</c> set.</p>
-
- <p><c>Reason</c> is <c>badarg</c> if <c>AbsModule</c> is not
- found. This could be because the specified file does not
- exist, or because <c>code:which/1</c> does not return a
- beam file name, which is the case not only for non-existing
- modules but also for modules which are preloaded or cover
- compiled.</p>
-
- <p><c>Reason</c> is <c>{app,App}</c> where <c>App</c> is
- <c>kernel</c>, <c>stdlib</c>, <c>gs</c> or <c>debugger</c> if
- <c>AbsModule</c> belongs to one of these applications.</p>
-
- <p>Note that the function can return <c>true</c> for a module
- which in fact is not interpretable in the case where
+ <p>Checks if a module can be interpreted. The module can be
+ specified by its module name <c>Module</c> or its source
+ filename <c>File</c>. If specified by a module name, the module
+ is searched for in the code path.</p>
+
+ <p>The function returns <c>true</c> if all of the following
+ apply:</p>
+ <list type="bulleted">
+ <item>Both source code and object code for the module is
+ found.</item>
+ <item>The module has been compiled with option <c>debug_info</c>
+ set.</item>
+ <item>The module does not belong to any of the applications
+ Kernel, STDLIB, GS, or Debugger.</item>
+ </list>
+
+ <p>The function returns <c>{error,Reason}</c> if the module cannot
+ be interpreted. <c>Reason</c> can have the following values:</p>
+ <taglist>
+ <tag><c>no_src</c></tag>
+ <item><p>No source code is found.
+ It is assumed that the source code and object code are located
+ either in the same directory, or in <c>src</c> and <c>ebin</c>
+ directories next to each other.</p></item>
+
+ <tag><c>no_beam</c></tag>
+ <item><p>No object code is found.
+ It is assumed that the source code and object code are located
+ either in the same directory, or in <c>src</c> and <c>ebin</c>
+ directories next to each other.</p></item>
+
+ <tag><c>no_debug_info</c></tag>
+ <item><p>The module has not been compiled with option
+ <c>debug_info</c> set.</p></item>
+
+ <tag><c>badarg</c></tag>
+ <item><p><c>AbsModule</c> is not found. This could be because
+ the specified file does not exist, or because
+ <c>code:which/1</c> does not return a BEAM filename,
+ which is the case not only for non-existing modules but also
+ for modules that are preloaded or cover-compiled.</p></item>
+
+ <tag><c>{app,App}</c></tag>
+ <item><p><c>App</c> is <c>kernel</c>, <c>stdlib</c>, <c>gs</c>,
+ or <c>debugger</c> if <c>AbsModule</c> belongs to one of these
+ applications.</p></item>
+ </taglist>
+
+ <p>Notice that the function can return <c>true</c> for a module
+ that in fact is not interpretable in the case where
the module is marked as sticky or resides in a directory
- marked as sticky, as this is not discovered until
- the interpreter actually tries to load the module.</p>
+ marked as sticky. The reason is that this is not discovered
+ until the interpreter tries to load the module.</p>
</desc>
</func>
@@ -238,7 +258,7 @@
<name>auto_attach() -> false | {Flags,Function}</name>
<name>auto_attach(false)</name>
<name>auto_attach(Flags, Function)</name>
- <fsummary>Get/set when and how to attach to a process</fsummary>
+ <fsummary>Get and set when and how to attach to a process.</fsummary>
<type>
<v>Flags = [init | break | exit]</v>
<v>Function = {Module,Name,Args}</v>
@@ -246,24 +266,24 @@
<v>&nbsp;Args = [term()]</v>
</type>
<desc>
- <p>Gets and sets when and how to automatically attach to a
+ <p>Gets and sets when and how to attach automatically to a
process executing code in interpreted modules. <c>false</c>
- means never automatically attach, this is the default.
+ means never attach automatically, this is the default.
Otherwise automatic attach is defined by a list of flags and
- a function. The following flags may be specified:</p>
- <list>
- <item><c>init</c> - attach when a process for the very first
+ a function. The following flags can be specified:</p>
+ <list type="bulleted">
+ <item><c>init</c> - Attach when a process for the first
time calls an interpreted function.</item>
- <item><c>break</c> - attach whenever a process reaches a
+ <item><c>break</c> - Attach whenever a process reaches a
breakpoint.</item>
- <item><c>exit</c> - attach when a process terminates.</item>
+ <item><c>exit</c> - Attach when a process terminates.</item>
</list>
<p>When the specified event occurs, the function <c>Function</c>
- will be called as:</p>
+ is called as:</p>
<pre>
-spawn(Module, Name, [Pid | Args])
- </pre>
+spawn(Module, Name, [Pid | Args])</pre>
+
<p><c>Pid</c> is the pid of the process executing interpreted
code.</p>
</desc>
@@ -272,7 +292,7 @@ spawn(Module, Name, [Pid | Args])
<func>
<name>stack_trace() -> Flag</name>
<name>stack_trace(Flag)</name>
- <fsummary>Get/set if and how to save call frames</fsummary>
+ <fsummary>Get and set if and how to save call frames.</fsummary>
<type>
<v>Flag = all | no_tail | false</v>
</type>
@@ -280,25 +300,30 @@ spawn(Module, Name, [Pid | Args])
<p>Gets and sets how to save call frames in the stack. Saving
call frames makes it possible to inspect the call chain of a
process, and is also used to emulate the stack trace if an
- error (an exception of class error) occurs.</p>
- <list>
- <item><c>all</c> - save information about all current calls,
- that is, function calls that have not yet returned a value.
- </item>
- <item><c>no_tail</c> - save information about current calls,
+ error (an exception of class error) occurs. The following
+ flags can be specified:</p>
+ <taglist>
+ <tag><c>all</c></tag>
+ <item><p>Save information about all current calls,
+ that is, function calls that have not yet returned a value.</p>
+ </item>
+
+ <tag><c>no_tail</c></tag>
+ <item><p>Save information about current calls,
but discard previous information when a tail recursive call
- is made. This option consumes less memory and may be
+ is made. This option consumes less memory and can be
necessary to use for processes with long lifetimes and many
- tail recursive calls. This is the default.</item>
- <item><c>false</c> - do not save any information about current
- calls.</item>
- </list>
+ tail recursive calls. This is the default.</p></item>
+
+ <tag><c>false</c></tag>
+ <item><p>Save no information about currentcalls.</p></item>
+ </taglist>
</desc>
</func>
<func>
<name>break(Module, Line) -> ok | {error,break_exists}</name>
- <fsummary>Create a breakpoint</fsummary>
+ <fsummary>Create a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
@@ -310,86 +335,80 @@ spawn(Module, Name, [Pid | Args])
<func>
<name>delete_break(Module, Line) -> ok</name>
- <fsummary>Delete a breakpoint</fsummary>
+ <fsummary>Delete a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
</type>
<desc>
- <p>Deletes the breakpoint located at <c>Line</c> in
- <c>Module</c>.</p>
+ <p>Deletes the breakpoint at <c>Line</c> in <c>Module</c>.</p>
</desc>
</func>
<func>
<name>break_in(Module, Name, Arity) -> ok
| {error,function_not_found}</name>
- <fsummary>Create breakpoints in the specified function</fsummary>
+ <fsummary>Create breakpoints in the specified function.</fsummary>
<type>
<v>Module = Name = atom()</v>
<v>Arity = int()</v>
</type>
<desc>
<p>Creates a breakpoint at the first line of every clause of
- the <c>Module:Name/Arity</c> function.</p>
+ function <c>Module:Name/Arity</c>.</p>
</desc>
</func>
<func>
<name>del_break_in(Module, Name, Arity) -> ok
| {error,function_not_found}</name>
- <fsummary>Delete breakpoints from the specified function
- </fsummary>
+ <fsummary>Delete breakpoints from the specified function.</fsummary>
<type>
<v>Module = Name = atom()</v>
<v>Arity = int()</v>
</type>
<desc>
<p>Deletes the breakpoints at the first line of every clause of
- the <c>Module:Name/Arity</c> function.
- </p>
+ function <c>Module:Name/Arity</c>.</p>
</desc>
</func>
<func>
<name>no_break() -> ok</name>
<name>no_break(Module) -> ok</name>
- <fsummary>Delete all breakpoints</fsummary>
+ <fsummary>Delete all breakpoints.</fsummary>
<desc>
- <p>Deletes all breakpoints, or all breakpoints in <c>Module</c>.
- </p>
+ <p>Deletes all breakpoints, or all breakpoints in <c>Module</c>.</p>
</desc>
</func>
<func>
<name>disable_break(Module, Line) -> ok</name>
- <fsummary>Make a breakpoint inactive</fsummary>
+ <fsummary>Make a breakpoint inactive.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
</type>
<desc>
- <p>Makes the breakpoint at <c>Line</c> in <c>Module</c>
- inactive.</p>
+ <p>Makes the breakpoint at <c>Line</c> in <c>Module</c> inactive.</p>
</desc>
</func>
<func>
<name>enable_break(Module, Line) -> ok</name>
- <fsummary>Make a breakpoint active</fsummary>
+ <fsummary>Make a breakpoint active.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
</type>
<desc>
- <p>Makes the breakpoint at <c>Line</c> in <c>Module</c> active.
- </p>
+ <p>Makes the breakpoint at <c>Line</c> in <c>Module</c> active.</p>
</desc>
</func>
<func>
<name>action_at_break(Module, Line, Action) -> ok</name>
- <fsummary>Set the trigger action of a breakpoint</fsummary>
+ <fsummary>Set the trigger action of a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
@@ -403,7 +422,7 @@ spawn(Module, Name, [Pid | Args])
<func>
<name>test_at_break(Module, Line, Function) -> ok</name>
- <fsummary>Set the conditional test of a breakpoint</fsummary>
+ <fsummary>Set the conditional test of a breakpoint.</fsummary>
<type>
<v>Module = atom()</v>
<v>Line = int()</v>
@@ -413,14 +432,14 @@ spawn(Module, Name, [Pid | Args])
<desc>
<p>Sets the conditional test of the breakpoint at <c>Line</c> in
<c>Module</c> to <c>Function</c>. The function must
- fulfill the requirements specified in the section
- <em>Breakpoints</em> above.</p>
+ fulfill the requirements specified in section
+ <seealso marker="#int_breakpoints">Breakpoints</seealso>.</p>
</desc>
</func>
<func>
<name>get_binding(Var, Bindings) -> {value,Value} | unbound</name>
- <fsummary>Retrieve a variable binding</fsummary>
+ <fsummary>Retrieve a variable binding.</fsummary>
<type>
<v>Var = atom()</v>
<v>Bindings = term()</v>
@@ -436,7 +455,7 @@ spawn(Module, Name, [Pid | Args])
<func>
<name>all_breaks() -> [Break]</name>
<name>all_breaks(Module) -> [Break]</name>
- <fsummary>Get all breakpoints</fsummary>
+ <fsummary>Get all breakpoints.</fsummary>
<type>
<v>Break = {Point,Options}</v>
<v>&nbsp;Point = {Module,Line}</v>
@@ -450,15 +469,14 @@ spawn(Module, Name, [Pid | Args])
<v>&nbsp;&nbsp;&nbsp;&nbsp;Name = atom()</v>
</type>
<desc>
- <p>Gets all breakpoints, or all breakpoints in <c>Module</c>.
- </p>
+ <p>Gets all breakpoints, or all breakpoints in <c>Module</c>.</p>
</desc>
</func>
<func>
<name>snapshot() -> [Snapshot]</name>
<fsummary>Get information about all processes executing interpreted
- code</fsummary>
+ code.</fsummary>
<type>
<v>Snapshot = {Pid, Function, Status, Info}</v>
<v>&nbsp;Pid = pid()</v>
@@ -474,26 +492,27 @@ spawn(Module, Name, [Pid | Args])
<desc>
<p>Gets information about all processes executing interpreted code.
</p>
- <list>
- <item><c>Pid</c> - process identifier.</item>
- <item><c>Function</c> - first interpreted function called by
+ <list type="bulleted">
+ <item><c>Pid</c> - Process identifier.</item>
+ <item><c>Function</c> - First interpreted function called by
the process.</item>
- <item><c>Status</c> - current status of the process.</item>
- <item><c>Info</c> - additional information.</item>
+ <item><c>Status</c> - Current status of the process.</item>
+ <item><c>Info</c> - More information.</item>
</list>
- <p><c>Status</c> is one of:</p>
- <list>
- <item><c>idle</c> - the process is no longer executing
+
+ <p><c>Status</c> is one of the following:</p>
+ <list type="bulleted">
+ <item><c>idle</c> - The process is no longer executing
interpreted code. <c>Info={}</c>.</item>
- <item><c>running</c> - the process is running. <c>Info={}</c>.
+ <item><c>running</c> - The process is running. <c>Info={}</c>.
</item>
- <item><c>waiting</c> - the process is waiting at a
+ <item><c>waiting</c> - The process is waiting at a
<c>receive</c>. <c>Info={}</c>.</item>
- <item><c>break</c> - process execution has been stopped,
+ <item><c>break</c> - Process execution is stopped,
normally at a breakpoint. <c>Info={Module,Line}</c>.</item>
- <item><c>exit</c> - the process has terminated.
+ <item><c>exit</c> - The process is terminated.
<c>Info=ExitReason</c>.</item>
- <item><c>no_conn</c> - the connection is down to the node
+ <item><c>no_conn</c> - The connection is down to the node
where the process is running. <c>Info={}</c>.</item>
</list>
</desc>
@@ -502,7 +521,7 @@ spawn(Module, Name, [Pid | Args])
<func>
<name>clear() -> ok</name>
<fsummary>Clear information about processes executing interpreted
- code</fsummary>
+ code.</fsummary>
<desc>
<p>Clears information about processes executing interpreted code
by removing all information about terminated processes.</p>
@@ -512,13 +531,13 @@ spawn(Module, Name, [Pid | Args])
<func>
<name>continue(Pid) -> ok | {error,not_interpreted}</name>
<name>continue(X,Y,Z) -> ok | {error,not_interpreted}</name>
- <fsummary>Resume process execution</fsummary>
+ <fsummary>Resume process execution.</fsummary>
<type>
<v>Pid = pid()</v>
<v>X = Y = Z = int()</v>
</type>
<desc>
- <p>Resume process execution for <c>Pid</c>, or for
+ <p>Resumes process execution for <c>Pid</c> or
<c>c:pid(X,Y,Z)</c>.</p>
</desc>
</func>
diff --git a/lib/debugger/doc/src/introduction.xml b/lib/debugger/doc/src/introduction.xml
new file mode 100644
index 0000000000..9f5f279bb0
--- /dev/null
+++ b/lib/debugger/doc/src/introduction.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+<header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Introduction</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>introduction.xml</file>
+ </header>
+
+ <section>
+ <title>Scope</title>
+ <p>Debugger is a graphical user interface for the Erlang
+ interpreter, which can be used for debugging and testing of
+ Erlang programs. For example, breakpoints can be set, code can be
+ single-stepped and variable values can be displayed and changed.
+ </p>
+
+ <p>The Erlang interpreter can also be accessed through the interface
+ module <seealso marker="int"><c>int(3)</c></seealso>.
+ </p>
+
+ <warning>
+ <p>Debugger might at some point
+ start tracing on the processes that execute the interpreted
+ code. This means that a conflict occurs if tracing by other
+ means is started on any of these processes.</p>
+ </warning>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language.</p>
+ <p>Modules to be debugged must include debug information,
+ for example, <c>erlc +debug_info MODULE.erl</c>.</p>
+ </section>
+
+</chapter>
+
+
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 7384189a6f..6e8cf54ae4 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,6 +33,55 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 4.1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Documentation corrections.</p>
+ <p>
+ Own Id: OTP-12994</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Debugger 4.1.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix crash when starting a quick debugging session. Thanks
+ Alan Duffield.</p>
+ <p>
+ Own Id: OTP-12911 Aux Id: seq12906 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Debugger 4.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Support variables as Map keys in expressions and patterns</p>
+ <p>Erlang will accept any expression as keys in Map
+ expressions and it will accept literals or bound
+ variables as keys in Map patterns.</p>
+ <p>
+ Own Id: OTP-12218</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Debugger 4.0.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/debugger/doc/src/part.xml b/lib/debugger/doc/src/part.xml
index 0c90feab66..ce1edbd978 100644
--- a/lib/debugger/doc/src/part.xml
+++ b/lib/debugger/doc/src/part.xml
@@ -4,20 +4,21 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -26,14 +27,10 @@
<docno></docno>
<date>1998-05-12</date>
<rev>B</rev>
- <file>part.sgml</file>
+ <file>part.xml</file>
</header>
- <description>
- <p><em>Debugger</em> is a graphical tool which can be used for
- debugging and testing of Erlang programs. For example, breakpoints
- can be set, code can be single stepped and variable values can be
- displayed and changed.</p>
- </description>
+ <description></description>
+ <xi:include href="introduction.xml"/>
<xi:include href="debugger_chapter.xml"/>
</part>
diff --git a/lib/debugger/doc/src/ref_man.xml b/lib/debugger/doc/src/ref_man.xml
index 9ecc1f8879..c44f07f912 100644
--- a/lib/debugger/doc/src/ref_man.xml
+++ b/lib/debugger/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -27,12 +28,7 @@
<date></date>
<rev></rev>
</header>
- <description>
- <p><em>Debugger</em> is a graphical tool which can be used for
- debugging and testing of Erlang programs. For example, breakpoints
- can be set, code can be single stepped and variable values can be
- displayed and changed.</p>
- </description>
+ <description></description>
<xi:include href="debugger.xml"/>
<xi:include href="i.xml"/>
<xi:include href="int.xml"/>
diff --git a/lib/debugger/priv/Makefile b/lib/debugger/priv/Makefile
index cc19aceaf6..77c114fa35 100644
--- a/lib/debugger/priv/Makefile
+++ b/lib/debugger/priv/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/debugger/src/Makefile b/lib/debugger/src/Makefile
index d61519f1ad..f115f49d98 100644
--- a/lib/debugger/src/Makefile
+++ b/lib/debugger/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/debugger/src/dbg_debugged.erl b/lib/debugger/src/dbg_debugged.erl
index d8285d7288..99bed6f01b 100644
--- a/lib/debugger/src/dbg_debugged.erl
+++ b/lib/debugger/src/dbg_debugged.erl
@@ -3,19 +3,19 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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(dbg_debugged).
%% External exports
diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl
index ce12c1beb3..1b274e20ae 100644
--- a/lib/debugger/src/dbg_icmd.erl
+++ b/lib/debugger/src/dbg_icmd.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -266,7 +267,7 @@ handle_int_msg({old_code,Mod}, Status, Bs,
#ieval{level=Le,module=M}=Ieval) ->
if
Status =:= idle, Le =:= 1 ->
- erase([Mod|db]),
+ erase(?DB_REF_KEY(Mod)),
put(cache, []);
true ->
case dbg_istk:in_use_p(Mod, M) of
@@ -276,7 +277,7 @@ handle_int_msg({old_code,Mod}, Status, Bs,
exit(get(self), kill),
dbg_ieval:exception(exit, old_code, Bs, Ieval);
false ->
- erase([Mod|db]),
+ erase(?DB_REF_KEY(Mod)),
put(cache, [])
end
end;
diff --git a/lib/debugger/src/dbg_idb.erl b/lib/debugger/src/dbg_idb.erl
index 50ed2bb7ce..9ce3ec3ef2 100644
--- a/lib/debugger/src/dbg_idb.erl
+++ b/lib/debugger/src/dbg_idb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index 96f9f91808..f5e079ef7e 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -559,7 +560,7 @@ get_function(Mod, Name, Args, extern) ->
end.
db_ref(Mod) ->
- case get([Mod|db]) of
+ case get(?DB_REF_KEY(Mod)) of
undefined ->
case dbg_iserver:call(get(int),
{get_module_db, Mod, get(self)}) of
@@ -571,7 +572,7 @@ db_ref(Mod) ->
Node =/= node() -> {Node,ModDb};
true -> ModDb
end,
- put([Mod|db], DbRef),
+ put(?DB_REF_KEY(Mod), DbRef),
DbRef
end;
DbRef ->
@@ -650,24 +651,19 @@ expr({tuple,Line,Es0}, Bs0, Ieval) ->
{value,list_to_tuple(Vs),Bs};
%% Map
-expr({map,Line,Fs0}, Bs0, Ieval) ->
- {Fs,Bs} = eval_map_fields(Fs0, Bs0, Ieval#ieval{line=Line,top=false}),
- Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi) end,
- #{}, Fs),
- {value,Value,Bs};
+expr({map,Line,Fs}, Bs0, Ieval) ->
+ {Map,Bs} = eval_new_map_fields(Fs, Bs0, Ieval#ieval{line=Line,top=false},
+ fun expr/3),
+ {value,Map,Bs};
expr({map,Line,E0,Fs0}, Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line,top=false},
{value,E,Bs1} = expr(E0, Bs0, Ieval),
- case E of
- #{} ->
- {Fs,Bs2} = eval_map_fields(Fs0, Bs0, Ieval),
- Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi);
- ({map_exact,K,V}, Mi) -> maps:update(K,V,Mi)
- end, E, Fs),
- {value,Value,merge_bindings(Bs2, Bs1, Ieval)};
- _ ->
- exception(error, {badarg,E}, Bs1, Ieval)
- end;
+ {Fs,Bs2} = eval_map_fields(Fs0, Bs0, Ieval),
+ _ = maps:put(k, v, E), %Validate map.
+ Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi);
+ ({map_exact,K,V}, Mi) -> maps:update(K,V,Mi)
+ end, E, Fs),
+ {value,Value,merge_bindings(Bs2, Bs1, Ieval)};
%% A block of statements
expr({block,Line,Es},Bs,Ieval) ->
seq(Es, Bs, Ieval#ieval{line=Line});
@@ -1477,11 +1473,13 @@ guard_expr({cons,_,H0,T0}, Bs) ->
guard_expr({tuple,_,Es0}, Bs) ->
{values,Es} = guard_exprs(Es0, Bs),
{value,list_to_tuple(Es)};
-guard_expr({map,_,Fs0}, Bs) ->
- Fs = eval_map_fields_guard(Fs0, Bs),
- Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi) end,
- #{}, Fs),
- {value,Value};
+guard_expr({map,_,Fs}, Bs0) ->
+ F = fun (G0, B0, _) ->
+ {value,G} = guard_expr(G0, B0),
+ {value,G,B0}
+ end,
+ {Map,_} = eval_new_map_fields(Fs, Bs0, #ieval{top=false}, F),
+ {value,Map};
guard_expr({map,_,E0,Fs0}, Bs) ->
{value,E} = guard_expr(E0, Bs),
Fs = eval_map_fields_guard(Fs0, Bs),
@@ -1530,6 +1528,17 @@ eval_map_fields([{map_field_exact,Line,K0,V0}|Fs], Bs0, Ieval0, F, Acc) ->
eval_map_fields([], Bs, _Ieval, _F, Acc) ->
{lists:reverse(Acc),Bs}.
+eval_new_map_fields(Fs, Bs0, Ieval, F) ->
+ eval_new_map_fields(Fs, Bs0, Ieval, F, []).
+
+eval_new_map_fields([{Line,K0,V0}|Fs], Bs0, Ieval0, F, Acc) ->
+ Ieval = Ieval0#ieval{line=Line},
+ {value,K,Bs1} = F(K0, Bs0, Ieval),
+ {value,V,Bs2} = F(V0, Bs1, Ieval),
+ eval_new_map_fields(Fs, Bs2, Ieval0, F, [{K,V}|Acc]);
+eval_new_map_fields([], Bs, _, _, Acc) ->
+ {maps:from_list(lists:reverse(Acc)),Bs}.
+
%% match(Pattern,Term,Bs) -> {match,Bs} | nomatch
match(Pat, Term, Bs) ->
try match1(Pat, Term, Bs, Bs)
diff --git a/lib/debugger/src/dbg_ieval.hrl b/lib/debugger/src/dbg_ieval.hrl
index 1abf39d247..ad422a9e4a 100644
--- a/lib/debugger/src/dbg_ieval.hrl
+++ b/lib/debugger/src/dbg_ieval.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -26,3 +27,5 @@
%% (i.e. the next call will leave interpreted code).
top = false
}).
+
+-define(DB_REF_KEY(Mod), {Mod,db}).
diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl
index ad05a7c529..2a8bcd32d8 100644
--- a/lib/debugger/src/dbg_iload.erl
+++ b/lib/debugger/src/dbg_iload.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -163,11 +164,11 @@ clauses([C0|Cs]) ->
[C1|clauses(Cs)];
clauses([]) -> [].
-clause({clause,Line,H0,G0,B0}, Lc) ->
+clause({clause,Anno,H0,G0,B0}, Lc) ->
H1 = head(H0),
G1 = guard(G0),
B1 = exprs(B0, Lc),
- {clause,Line,H1,G1,B1}.
+ {clause,ln(Anno),H1,G1,B1}.
head(Ps) -> patterns(Ps).
@@ -181,46 +182,46 @@ patterns([]) -> [].
%% N.B. Only valid patterns are included here.
-pattern({var,Line,V}) -> {var,Line,V};
-pattern({char,Line,I}) -> {value,Line,I};
-pattern({integer,Line,I}) -> {value,Line,I};
-pattern({match,Line,Pat1,Pat2}) ->
- {match,Line,pattern(Pat1),pattern(Pat2)};
-pattern({float,Line,F}) -> {value,Line,F};
-pattern({atom,Line,A}) -> {value,Line,A};
-pattern({string,Line,S}) -> {value,Line,S};
-pattern({nil,Line}) -> {value,Line,[]};
-pattern({cons,Line,H0,T0}) ->
+pattern({var,Anno,V}) -> {var,ln(Anno),V};
+pattern({char,Anno,I}) -> {value,ln(Anno),I};
+pattern({integer,Anno,I}) -> {value,ln(Anno),I};
+pattern({match,Anno,Pat1,Pat2}) ->
+ {match,ln(Anno),pattern(Pat1),pattern(Pat2)};
+pattern({float,Anno,F}) -> {value,ln(Anno),F};
+pattern({atom,Anno,A}) -> {value,ln(Anno),A};
+pattern({string,Anno,S}) -> {value,ln(Anno),S};
+pattern({nil,Anno}) -> {value,ln(Anno),[]};
+pattern({cons,Anno,H0,T0}) ->
H1 = pattern(H0),
T1 = pattern(T0),
- {cons,Line,H1,T1};
-pattern({tuple,Line,Ps0}) ->
+ {cons,ln(Anno),H1,T1};
+pattern({tuple,Anno,Ps0}) ->
Ps1 = pattern_list(Ps0),
- {tuple,Line,Ps1};
-pattern({map,Line,Fs0}) ->
+ {tuple,ln(Anno),Ps1};
+pattern({map,Anno,Fs0}) ->
Fs1 = lists:map(fun ({map_field_exact,L,K,V}) ->
{map_field_exact,L,expr(K, false),pattern(V)}
end, Fs0),
- {map,Line,Fs1};
-pattern({op,_,'-',{integer,Line,I}}) ->
- {value,Line,-I};
-pattern({op,_,'+',{integer,Line,I}}) ->
- {value,Line,I};
-pattern({op,_,'-',{char,Line,I}}) ->
- {value,Line,-I};
-pattern({op,_,'+',{char,Line,I}}) ->
- {value,Line,I};
-pattern({op,_,'-',{float,Line,I}}) ->
- {value,Line,-I};
-pattern({op,_,'+',{float,Line,I}}) ->
- {value,Line,I};
-pattern({bin,Line,Grp}) ->
+ {map,ln(Anno),Fs1};
+pattern({op,_,'-',{integer,Anno,I}}) ->
+ {value,ln(Anno),-I};
+pattern({op,_,'+',{integer,Anno,I}}) ->
+ {value,ln(Anno),I};
+pattern({op,_,'-',{char,Anno,I}}) ->
+ {value,ln(Anno),-I};
+pattern({op,_,'+',{char,Anno,I}}) ->
+ {value,ln(Anno),I};
+pattern({op,_,'-',{float,Anno,I}}) ->
+ {value,ln(Anno),-I};
+pattern({op,_,'+',{float,Anno,I}}) ->
+ {value,ln(Anno),I};
+pattern({bin,Anno,Grp}) ->
Grp1 = pattern_list(Grp),
- {bin,Line,Grp1};
-pattern({bin_element,Line,Expr,Size,Type}) ->
+ {bin,ln(Anno),Grp1};
+pattern({bin_element,Anno,Expr,Size,Type}) ->
Expr1 = pattern(Expr),
Size1 = expr(Size, false),
- {bin_element,Line,Expr1,Size1,Type}.
+ {bin_element,ln(Anno),Expr1,Size1,Type}.
%% These patterns are processed "in parallel" for purposes of variable
%% definition etc.
@@ -240,90 +241,89 @@ and_guard([G0|Gs]) ->
[G1|and_guard(Gs)];
and_guard([]) -> [].
-guard_test({call,Line,{remote,_,{atom,_,erlang},{atom,_,F}},As0}) ->
+guard_test({call,Anno,{remote,_,{atom,_,erlang},{atom,_,F}},As0}) ->
As = gexpr_list(As0),
- {safe_bif,Line,erlang,F,As};
-guard_test({op,Line,Op,L0}) ->
+ {safe_bif,ln(Anno),erlang,F,As};
+guard_test({op,Anno,Op,L0}) ->
true = erl_internal:arith_op(Op, 1) orelse %Assertion.
erl_internal:bool_op(Op, 1),
L1 = gexpr(L0),
- {safe_bif,Line,erlang,Op,[L1]};
-guard_test({op,Line,Op,L0,R0}) when Op =:= 'andalso'; Op =:= 'orelse' ->
+ {safe_bif,ln(Anno),erlang,Op,[L1]};
+guard_test({op,Anno,Op,L0,R0}) when Op =:= 'andalso'; Op =:= 'orelse' ->
L1 = gexpr(L0),
R1 = gexpr(R0), %They see the same variables
- {Op,Line,L1,R1};
-guard_test({op,Line,Op,L0,R0}) ->
+ {Op,ln(Anno),L1,R1};
+guard_test({op,Anno,Op,L0,R0}) ->
true = erl_internal:comp_op(Op, 2) orelse %Assertion.
erl_internal:bool_op(Op, 2) orelse
erl_internal:arith_op(Op, 2),
L1 = gexpr(L0),
R1 = gexpr(R0), %They see the same variables
- {safe_bif,Line,erlang,Op,[L1,R1]};
+ {safe_bif,ln(Anno),erlang,Op,[L1,R1]};
guard_test({var,_,_}=V) ->V; % Boolean var
-guard_test({atom,Line,true}) -> {value,Line,true};
+guard_test({atom,Anno,true}) -> {value,ln(Anno),true};
%% All other constants at this level means false.
-guard_test({atom,Line,_}) -> {value,Line,false};
-guard_test({integer,Line,_}) -> {value,Line,false};
-guard_test({char,Line,_}) -> {value,Line,false};
-guard_test({float,Line,_}) -> {value,Line,false};
-guard_test({string,Line,_}) -> {value,Line,false};
-guard_test({nil,Line}) -> {value,Line,false};
-guard_test({cons,Line,_,_}) -> {value,Line,false};
-guard_test({tuple,Line,_}) -> {value,Line,false};
-guard_test({map,Line,_}) -> {value,Line,false};
-guard_test({map,Line,_,_}) -> {value,Line,false};
-guard_test({bin,Line,_}) -> {value,Line,false}.
-
-gexpr({var,Line,V}) -> {var,Line,V};
-gexpr({integer,Line,I}) -> {value,Line,I};
-gexpr({char,Line,I}) -> {value,Line,I};
-gexpr({float,Line,F}) -> {value,Line,F};
-gexpr({atom,Line,A}) -> {value,Line,A};
-gexpr({string,Line,S}) -> {value,Line,S};
-gexpr({nil,Line}) -> {value,Line,[]};
-gexpr({cons,Line,H0,T0}) ->
+guard_test({atom,Anno,_}) -> {value,ln(Anno),false};
+guard_test({integer,Anno,_}) -> {value,ln(Anno),false};
+guard_test({char,Anno,_}) -> {value,ln(Anno),false};
+guard_test({float,Anno,_}) -> {value,ln(Anno),false};
+guard_test({string,Anno,_}) -> {value,ln(Anno),false};
+guard_test({nil,Anno}) -> {value,ln(Anno),false};
+guard_test({cons,Anno,_,_}) -> {value,ln(Anno),false};
+guard_test({tuple,Anno,_}) -> {value,ln(Anno),false};
+guard_test({map,Anno,_}) -> {value,ln(Anno),false};
+guard_test({map,Anno,_,_}) -> {value,ln(Anno),false};
+guard_test({bin,Anno,_}) -> {value,ln(Anno),false}.
+
+gexpr({var,Anno,V}) -> {var,ln(Anno),V};
+gexpr({integer,Anno,I}) -> {value,ln(Anno),I};
+gexpr({char,Anno,I}) -> {value,ln(Anno),I};
+gexpr({float,Anno,F}) -> {value,ln(Anno),F};
+gexpr({atom,Anno,A}) -> {value,ln(Anno),A};
+gexpr({string,Anno,S}) -> {value,ln(Anno),S};
+gexpr({nil,Anno}) -> {value,ln(Anno),[]};
+gexpr({cons,Anno,H0,T0}) ->
case {gexpr(H0),gexpr(T0)} of
{{value,Line,H1},{value,Line,T1}} -> {value,Line,[H1|T1]};
- {H1,T1} -> {cons,Line,H1,T1}
+ {H1,T1} -> {cons,ln(Anno),H1,T1}
end;
-gexpr({tuple,Line,Es0}) ->
+gexpr({tuple,Anno,Es0}) ->
Es1 = gexpr_list(Es0),
- {tuple,Line,Es1};
-gexpr({map,Line,Fs0}) ->
- Fs1 = map_fields(Fs0, fun gexpr/1),
- {map,Line,Fs1};
-gexpr({map,Line,E0,Fs0}) ->
+ {tuple,ln(Anno),Es1};
+gexpr({map,Anno,Fs0}) ->
+ new_map(Fs0, Anno, fun gexpr/1);
+gexpr({map,Anno,E0,Fs0}) ->
E1 = gexpr(E0),
Fs1 = map_fields(Fs0, fun gexpr/1),
- {map,Line,E1,Fs1};
-gexpr({bin,Line,Flds0}) ->
+ {map,ln(Anno),E1,Fs1};
+gexpr({bin,Anno,Flds0}) ->
Flds = gexpr_list(Flds0),
- {bin,Line,Flds};
-gexpr({bin_element,Line,Expr0,Size0,Type}) ->
+ {bin,ln(Anno),Flds};
+gexpr({bin_element,Anno,Expr0,Size0,Type}) ->
Expr = gexpr(Expr0),
Size = gexpr(Size0),
- {bin_element,Line,Expr,Size,Type};
+ {bin_element,ln(Anno),Expr,Size,Type};
%%% The previous passes have added the module name 'erlang' to
%%% all BIF calls, even in guards.
-gexpr({call,Line,{remote,_,{atom,_,erlang},{atom,_,self}},[]}) ->
- {dbg, Line, self, []};
-gexpr({call,Line,{remote,_,{atom,_,erlang},{atom,_,F}},As0}) ->
+gexpr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,self}},[]}) ->
+ {dbg,ln(Anno),self,[]};
+gexpr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,F}},As0}) ->
As = gexpr_list(As0),
- {safe_bif,Line,erlang,F,As};
-gexpr({op,Line,Op,A0}) ->
+ {safe_bif,ln(Anno),erlang,F,As};
+gexpr({op,Anno,Op,A0}) ->
erl_internal:arith_op(Op, 1),
A1 = gexpr(A0),
- {safe_bif,Line,erlang,Op,[A1]};
-gexpr({op,Line,Op,L0,R0}) when Op =:= 'andalso'; Op =:= 'orelse' ->
+ {safe_bif,ln(Anno),erlang,Op,[A1]};
+gexpr({op,Anno,Op,L0,R0}) when Op =:= 'andalso'; Op =:= 'orelse' ->
L1 = gexpr(L0),
R1 = gexpr(R0), %They see the same variables
- {Op,Line,L1,R1};
-gexpr({op,Line,Op,L0,R0}) ->
+ {Op,ln(Anno),L1,R1};
+gexpr({op,Anno,Op,L0,R0}) ->
true = erl_internal:arith_op(Op, 2) orelse erl_internal:comp_op(Op, 2)
orelse erl_internal:bool_op(Op, 2),
L1 = gexpr(L0),
R1 = gexpr(R0), %They see the same variables
- {safe_bif,Line,erlang,Op,[L1,R1]}.
+ {safe_bif,ln(Anno),erlang,Op,[L1,R1]}.
%% These expressions are processed "in parallel" for purposes of variable
%% definition etc.
@@ -343,175 +343,175 @@ exprs([E0|Es], Lc) ->
[E1|exprs(Es, Lc)];
exprs([], _Lc) -> [].
-expr({var,Line,V}, _Lc) -> {var,Line,V};
-expr({integer,Line,I}, _Lc) -> {value,Line,I};
-expr({char,Line,I}, _Lc) -> {value,Line,I};
-expr({float,Line,F}, _Lc) -> {value,Line,F};
-expr({atom,Line,A}, _Lc) -> {value,Line,A};
-expr({string,Line,S}, _Lc) -> {value,Line,S};
-expr({nil,Line}, _Lc) -> {value,Line,[]};
-expr({cons,Line,H0,T0}, _Lc) ->
+expr({var,Anno,V}, _Lc) -> {var,ln(Anno),V};
+expr({integer,Anno,I}, _Lc) -> {value,ln(Anno),I};
+expr({char,Anno,I}, _Lc) -> {value,ln(Anno),I};
+expr({float,Anno,F}, _Lc) -> {value,ln(Anno),F};
+expr({atom,Anno,A}, _Lc) -> {value,ln(Anno),A};
+expr({string,Anno,S}, _Lc) -> {value,ln(Anno),S};
+expr({nil,Anno}, _Lc) -> {value,ln(Anno),[]};
+expr({cons,Anno,H0,T0}, _Lc) ->
case {expr(H0, false),expr(T0, false)} of
{{value,Line,H1},{value,Line,T1}} -> {value,Line,[H1|T1]};
- {H1,T1} -> {cons,Line,H1,T1}
+ {H1,T1} -> {cons,ln(Anno),H1,T1}
end;
-expr({tuple,Line,Es0}, _Lc) ->
+expr({tuple,Anno,Es0}, _Lc) ->
Es1 = expr_list(Es0),
- {tuple,Line,Es1};
-expr({map,Line,Fs0}, _Lc) ->
- Fs1 = map_fields(Fs0),
- {map,Line,Fs1};
-expr({map,Line,E0,Fs0}, _Lc) ->
+ {tuple,ln(Anno),Es1};
+expr({map,Anno,Fs}, _Lc) ->
+ new_map(Fs, Anno, fun (E) -> expr(E, false) end);
+expr({map,Anno,E0,Fs0}, _Lc) ->
E1 = expr(E0, false),
Fs1 = map_fields(Fs0),
- {map,Line,E1,Fs1};
-expr({block,Line,Es0}, Lc) ->
+ {map,ln(Anno),E1,Fs1};
+expr({block,Anno,Es0}, Lc) ->
%% Unfold block into a sequence.
Es1 = exprs(Es0, Lc),
- {block,Line,Es1};
-expr({'if',Line,Cs0}, Lc) ->
+ {block,ln(Anno),Es1};
+expr({'if',Anno,Cs0}, Lc) ->
Cs1 = icr_clauses(Cs0, Lc),
- {'if',Line,Cs1};
-expr({'case',Line,E0,Cs0}, Lc) ->
+ {'if',ln(Anno),Cs1};
+expr({'case',Anno,E0,Cs0}, Lc) ->
E1 = expr(E0, false),
Cs1 = icr_clauses(Cs0, Lc),
- {'case',Line,E1,Cs1};
-expr({'receive',Line,Cs0}, Lc) ->
+ {'case',ln(Anno),E1,Cs1};
+expr({'receive',Anno,Cs0}, Lc) ->
Cs1 = icr_clauses(Cs0, Lc),
- {'receive',Line,Cs1};
-expr({'receive',Line,Cs0,To0,ToEs0}, Lc) ->
+ {'receive',ln(Anno),Cs1};
+expr({'receive',Anno,Cs0,To0,ToEs0}, Lc) ->
To1 = expr(To0, false),
ToEs1 = exprs(ToEs0, Lc),
Cs1 = icr_clauses(Cs0, Lc),
- {'receive',Line,Cs1,To1,ToEs1};
-expr({'fun',Line,{clauses,Cs0},{_,_,Name}}, _Lc) when is_atom(Name) ->
+ {'receive',ln(Anno),Cs1,To1,ToEs1};
+expr({'fun',Anno,{clauses,Cs0},{_,_,Name}}, _Lc) when is_atom(Name) ->
%% New R10B-2 format (abstract_v2).
Cs = fun_clauses(Cs0),
- {make_fun,Line,Name,Cs};
-expr({'fun',Line,{function,F,A},{_Index,_OldUniq,Name}}, _Lc) ->
+ {make_fun,ln(Anno),Name,Cs};
+expr({'fun',Anno,{function,F,A},{_Index,_OldUniq,Name}}, _Lc) ->
%% New R8 format (abstract_v2).
+ Line = ln(Anno),
As = new_vars(A, Line),
Cs = [{clause,Line,As,[],[{local_call,Line,F,As,true}]}],
{make_fun,Line,Name,Cs};
-expr({named_fun,Line,FName,Cs0,{_,_,Name}}, _Lc) when is_atom(Name) ->
+expr({named_fun,Anno,FName,Cs0,{_,_,Name}}, _Lc) when is_atom(Name) ->
Cs = fun_clauses(Cs0),
- {make_named_fun,Line,Name,FName,Cs};
-expr({'fun',Line,{function,{atom,_,M},{atom,_,F},{integer,_,A}}}, _Lc)
+ {make_named_fun,ln(Anno),Name,FName,Cs};
+expr({'fun',Anno,{function,{atom,_,M},{atom,_,F},{integer,_,A}}}, _Lc)
when 0 =< A, A =< 255 ->
%% New format in R15 for fun M:F/A (literal values).
- {value,Line,erlang:make_fun(M, F, A)};
-expr({'fun',Line,{function,M,F,A}}, _Lc) ->
+ {value,ln(Anno),erlang:make_fun(M, F, A)};
+expr({'fun',Anno,{function,M,F,A}}, _Lc) ->
%% New format in R15 for fun M:F/A (one or more variables).
MFA = expr_list([M,F,A]),
- {make_ext_fun,Line,MFA};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,self}},[]}, _Lc) ->
- {dbg,Line,self,[]};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,get_stacktrace}},[]}, _Lc) ->
- {dbg,Line,get_stacktrace,[]};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,throw}},[_]=As}, _Lc) ->
- {dbg,Line,throw,expr_list(As)};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,error}},[_]=As}, _Lc) ->
- {dbg,Line,error,expr_list(As)};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,exit}},[_]=As}, _Lc) ->
- {dbg,Line,exit,expr_list(As)};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,raise}},[_,_,_]=As}, _Lc) ->
- {dbg,Line,raise,expr_list(As)};
-expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,apply}},[_,_,_]=As0}, Lc) ->
+ {make_ext_fun,ln(Anno),MFA};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,self}},[]}, _Lc) ->
+ {dbg,ln(Anno),self,[]};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,get_stacktrace}},[]}, _Lc) ->
+ {dbg,ln(Anno),get_stacktrace,[]};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,throw}},[_]=As}, _Lc) ->
+ {dbg,ln(Anno),throw,expr_list(As)};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,error}},[_]=As}, _Lc) ->
+ {dbg,ln(Anno),error,expr_list(As)};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,exit}},[_]=As}, _Lc) ->
+ {dbg,ln(Anno),exit,expr_list(As)};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,raise}},[_,_,_]=As}, _Lc) ->
+ {dbg,ln(Anno),raise,expr_list(As)};
+expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,apply}},[_,_,_]=As0}, Lc) ->
As = expr_list(As0),
- {apply,Line,As,Lc};
-expr({call,Line,{remote,_,{atom,_,Mod},{atom,_,Func}},As0}, Lc) ->
+ {apply,ln(Anno),As,Lc};
+expr({call,Anno,{remote,_,{atom,_,Mod},{atom,_,Func}},As0}, Lc) ->
As = expr_list(As0),
case erlang:is_builtin(Mod, Func, length(As)) of
false ->
- {call_remote,Line,Mod,Func,As,Lc};
+ {call_remote,ln(Anno),Mod,Func,As,Lc};
true ->
case bif_type(Mod, Func, length(As0)) of
- safe -> {safe_bif,Line,Mod,Func,As};
- unsafe ->{bif,Line,Mod,Func,As}
+ safe -> {safe_bif,ln(Anno),Mod,Func,As};
+ unsafe ->{bif,ln(Anno),Mod,Func,As}
end
end;
-expr({call,Line,{remote,_,Mod0,Func0},As0}, Lc) ->
+expr({call,Anno,{remote,_,Mod0,Func0},As0}, Lc) ->
%% New R8 format (abstract_v2).
Mod = expr(Mod0, false),
Func = expr(Func0, false),
As = consify(expr_list(As0)),
- {apply,Line,[Mod,Func,As],Lc};
-expr({call,Line,{atom,_,Func},As0}, Lc) ->
+ {apply,ln(Anno),[Mod,Func,As],Lc};
+expr({call,Anno,{atom,_,Func},As0}, Lc) ->
As = expr_list(As0),
- {local_call,Line,Func,As,Lc};
-expr({call,Line,Fun0,As0}, Lc) ->
+ {local_call,ln(Anno),Func,As,Lc};
+expr({call,Anno,Fun0,As0}, Lc) ->
Fun = expr(Fun0, false),
As = expr_list(As0),
- {apply_fun,Line,Fun,As,Lc};
-expr({'catch',Line,E0}, _Lc) ->
+ {apply_fun,ln(Anno),Fun,As,Lc};
+expr({'catch',Anno,E0}, _Lc) ->
%% No new variables added.
E1 = expr(E0, false),
- {'catch',Line,E1};
-expr({'try',Line,Es0,CaseCs0,CatchCs0,As0}, Lc) ->
+ {'catch',ln(Anno),E1};
+expr({'try',Anno,Es0,CaseCs0,CatchCs0,As0}, Lc) ->
%% No new variables added.
Es = expr_list(Es0),
CaseCs = icr_clauses(CaseCs0, Lc),
CatchCs = icr_clauses(CatchCs0, Lc),
As = expr_list(As0),
- {'try',Line,Es,CaseCs,CatchCs,As};
-expr({lc,Line,E0,Gs0}, _Lc) -> %R8.
+ {'try',ln(Anno),Es,CaseCs,CatchCs,As};
+expr({lc,Anno,E0,Gs0}, _Lc) -> %R8.
Gs = lists:map(fun ({generate,L,P0,Qs}) ->
- {generate,L,expr(P0, false),expr(Qs, false)};
+ {generate,L,pattern(P0),expr(Qs, false)};
({b_generate,L,P0,Qs}) -> %R12.
- {b_generate,L,expr(P0, false),expr(Qs, false)};
+ {b_generate,L,pattern(P0),expr(Qs, false)};
(Expr) ->
case erl_lint:is_guard_test(Expr) of
true -> {guard,guard([[Expr]])};
false -> expr(Expr, false)
end
end, Gs0),
- {lc,Line,expr(E0, false),Gs};
-expr({bc,Line,E0,Gs0}, _Lc) -> %R12.
+ {lc,ln(Anno),expr(E0, false),Gs};
+expr({bc,Anno,E0,Gs0}, _Lc) -> %R12.
Gs = lists:map(fun ({generate,L,P0,Qs}) ->
- {generate,L,expr(P0, false),expr(Qs, false)};
+ {generate,L,pattern(P0),expr(Qs, false)};
({b_generate,L,P0,Qs}) -> %R12.
- {b_generate,L,expr(P0, false),expr(Qs, false)};
+ {b_generate,L,pattern(P0),expr(Qs, false)};
(Expr) ->
case erl_lint:is_guard_test(Expr) of
true -> {guard,guard([[Expr]])};
false -> expr(Expr, false)
end
end, Gs0),
- {bc,Line,expr(E0, false),Gs};
-expr({match,Line,P0,E0}, _Lc) ->
+ {bc,ln(Anno),expr(E0, false),Gs};
+expr({match,Anno,P0,E0}, _Lc) ->
E1 = expr(E0, false),
P1 = pattern(P0),
- {match,Line,P1,E1};
-expr({op,Line,Op,A0}, _Lc) ->
+ {match,ln(Anno),P1,E1};
+expr({op,Anno,Op,A0}, _Lc) ->
A1 = expr(A0, false),
- {op,Line,Op,[A1]};
-expr({op,Line,'++',L0,R0}, _Lc) ->
+ {op,ln(Anno),Op,[A1]};
+expr({op,Anno,'++',L0,R0}, _Lc) ->
L1 = expr(L0, false),
R1 = expr(R0, false), %They see the same variables
- {op,Line,append,[L1,R1]};
-expr({op,Line,'--',L0,R0}, _Lc) ->
+ {op,ln(Anno),append,[L1,R1]};
+expr({op,Anno,'--',L0,R0}, _Lc) ->
L1 = expr(L0, false),
R1 = expr(R0, false), %They see the same variables
- {op,Line,subtract,[L1,R1]};
-expr({op,Line,'!',L0,R0}, _Lc) ->
+ {op,ln(Anno),subtract,[L1,R1]};
+expr({op,Anno,'!',L0,R0}, _Lc) ->
L1 = expr(L0, false),
R1 = expr(R0, false), %They see the same variables
- {send,Line,L1,R1};
-expr({op,Line,Op,L0,R0}, _Lc) when Op =:= 'andalso'; Op =:= 'orelse' ->
+ {send,ln(Anno),L1,R1};
+expr({op,Anno,Op,L0,R0}, _Lc) when Op =:= 'andalso'; Op =:= 'orelse' ->
L1 = expr(L0, false),
R1 = expr(R0, false), %They see the same variables
- {Op,Line,L1,R1};
-expr({op,Line,Op,L0,R0}, _Lc) ->
+ {Op,ln(Anno),L1,R1};
+expr({op,Anno,Op,L0,R0}, _Lc) ->
L1 = expr(L0, false),
R1 = expr(R0, false), %They see the same variables
- {op,Line,Op,[L1,R1]};
-expr({bin,Line,Grp}, _Lc) ->
+ {op,ln(Anno),Op,[L1,R1]};
+expr({bin,Anno,Grp}, _Lc) ->
Grp1 = expr_list(Grp),
- {bin,Line,Grp1};
-expr({bin_element,Line,Expr,Size,Type}, _Lc) ->
+ {bin,ln(Anno),Grp1};
+expr({bin_element,Anno,Expr,Size,Type}, _Lc) ->
Expr1 = expr(Expr, false),
Size1 = expr(Size, false),
- {bin_element,Line,Expr1,Size1,Type};
+ {bin_element,ln(Anno),Expr1,Size1,Type};
expr(Other, _Lc) ->
exit({?MODULE,{unknown_expr,Other}}).
@@ -519,7 +519,6 @@ consify([A|As]) ->
{cons,0,A,consify(As)};
consify([]) -> {value,0,[]}.
-
%% -type expr_list([Expression]) -> [Expression].
%% These expressions are processed "in parallel" for purposes of variable
%% definition etc.
@@ -534,17 +533,35 @@ icr_clauses([C0|Cs], Lc) ->
[C1|icr_clauses(Cs, Lc)];
icr_clauses([], _) -> [].
-fun_clauses([{clause,L,H,G,B}|Cs]) ->
- [{clause,L,head(H),guard(G),exprs(B, true)}|fun_clauses(Cs)];
+fun_clauses([{clause,A,H,G,B}|Cs]) ->
+ [{clause,ln(A),head(H),guard(G),exprs(B, true)}|fun_clauses(Cs)];
fun_clauses([]) -> [].
+
+new_map(Fs0, Anno, F) ->
+ Line = ln(Anno),
+ Fs1 = map_fields(Fs0, F),
+ Fs2 = [{ln(A),K,V} || {map_field_assoc,A,K,V} <- Fs1],
+ try
+ {value,Line,map_literal(Fs2, #{})}
+ catch
+ throw:not_literal ->
+ {map,Line,Fs2}
+ end.
+
+map_literal([{_,{value,_,K},{value,_,V}}|T], M) ->
+ map_literal(T, maps:put(K, V, M));
+map_literal([_|_], _) ->
+ throw(not_literal);
+map_literal([], M) -> M.
+
map_fields(Fs) ->
map_fields(Fs, fun (E) -> expr(E, false) end).
-map_fields([{map_field_assoc,L,N,V}|Fs], F) ->
- [{map_field_assoc,L,F(N),F(V)}|map_fields(Fs)];
-map_fields([{map_field_exact,L,N,V}|Fs], F) ->
- [{map_field_exact,L,F(N),F(V)}|map_fields(Fs)];
+map_fields([{map_field_assoc,A,N,V}|Fs], F) ->
+ [{map_field_assoc,ln(A),F(N),F(V)}|map_fields(Fs)];
+map_fields([{map_field_exact,A,N,V}|Fs], F) ->
+ [{map_field_exact,ln(A),F(N),F(V)}|map_fields(Fs)];
map_fields([], _) -> [].
%% new_var_name() -> VarName.
@@ -564,6 +581,9 @@ new_vars(N, L, Vs) when N > 0 ->
new_vars(N-1, L, [V|Vs]);
new_vars(0, _, Vs) -> Vs.
+ln(Anno) ->
+ erl_anno:line(Anno).
+
bif_type(erlang, Name, Arity) ->
case erl_internal:guard_bif(Name, Arity) of
true ->
diff --git a/lib/debugger/src/dbg_iserver.erl b/lib/debugger/src/dbg_iserver.erl
index 31a856545f..28e8012f71 100644
--- a/lib/debugger/src/dbg_iserver.erl
+++ b/lib/debugger/src/dbg_iserver.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_istk.erl b/lib/debugger/src/dbg_istk.erl
index d8f83eef3d..d6c512bdf8 100644
--- a/lib/debugger/src/dbg_istk.erl
+++ b/lib/debugger/src/dbg_istk.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/src/dbg_wx_break.erl b/lib/debugger/src/dbg_wx_break.erl
index a19203f7d0..b577cfdaec 100644
--- a/lib/debugger/src/dbg_wx_break.erl
+++ b/lib/debugger/src/dbg_wx_break.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_break_win.erl b/lib/debugger/src/dbg_wx_break_win.erl
index 062da3937a..c9464f1e07 100644
--- a/lib/debugger/src/dbg_wx_break_win.erl
+++ b/lib/debugger/src/dbg_wx_break_win.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_code.erl b/lib/debugger/src/dbg_wx_code.erl
index 9853a5dbae..a0e6c94d60 100644
--- a/lib/debugger/src/dbg_wx_code.erl
+++ b/lib/debugger/src/dbg_wx_code.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_filedialog_win.erl b/lib/debugger/src/dbg_wx_filedialog_win.erl
index ea34295067..910eda7fad 100644
--- a/lib/debugger/src/dbg_wx_filedialog_win.erl
+++ b/lib/debugger/src/dbg_wx_filedialog_win.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/src/dbg_wx_filedialog_win.hrl b/lib/debugger/src/dbg_wx_filedialog_win.hrl
index aa739ad49e..96a6fb2ae9 100644
--- a/lib/debugger/src/dbg_wx_filedialog_win.hrl
+++ b/lib/debugger/src/dbg_wx_filedialog_win.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_interpret.erl b/lib/debugger/src/dbg_wx_interpret.erl
index 67bcbb1203..f93a9089d7 100644
--- a/lib/debugger/src/dbg_wx_interpret.erl
+++ b/lib/debugger/src/dbg_wx_interpret.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_mon.erl b/lib/debugger/src/dbg_wx_mon.erl
index aed86f5232..cd09dd1273 100644
--- a/lib/debugger/src/dbg_wx_mon.erl
+++ b/lib/debugger/src/dbg_wx_mon.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/src/dbg_wx_mon_win.erl b/lib/debugger/src/dbg_wx_mon_win.erl
index d94eb14937..5377ef83af 100644
--- a/lib/debugger/src/dbg_wx_mon_win.erl
+++ b/lib/debugger/src/dbg_wx_mon_win.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/src/dbg_wx_settings.erl b/lib/debugger/src/dbg_wx_settings.erl
index 2c332c0a54..e45d74f67e 100644
--- a/lib/debugger/src/dbg_wx_settings.erl
+++ b/lib/debugger/src/dbg_wx_settings.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_src_view.erl b/lib/debugger/src/dbg_wx_src_view.erl
index 5337ec2aac..43c36a4d8e 100644
--- a/lib/debugger/src/dbg_wx_src_view.erl
+++ b/lib/debugger/src/dbg_wx_src_view.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl
index 4438466bb0..f9c60f9b72 100644
--- a/lib/debugger/src/dbg_wx_trace.erl
+++ b/lib/debugger/src/dbg_wx_trace.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -72,6 +73,10 @@ start(Pid, TraceWin, BackTrace) ->
start(Pid, TraceWin, BackTrace, Strings) ->
case whereis(dbg_wx_mon) of
+ undefined ->
+ Parent = wx:new(),
+ Env = wx:get_env(),
+ start(Pid, Env, Parent, TraceWin, BackTrace, Strings);
Monitor when is_pid(Monitor) ->
Monitor ! {?MODULE, self(), get_env},
receive
@@ -140,7 +145,7 @@ init(Pid, Parent, Meta, TraceWin, BackTrace, Strings) ->
int:meta(Meta, trace, State3#state.trace),
- gui_enable_updown(stack_trace, {1,1}),
+ gui_enable_updown(State3#state.stack_trace, {1,1}),
gui_enable_btrace(false, false),
dbg_wx_trace_win:display(Win,idle),
@@ -806,7 +811,7 @@ gui_show_module(Win, Mod, Line, Mod, _Pid, How) ->
dbg_wx_trace_win:mark_line(Win, Line, How);
gui_show_module(Win, Mod, Line, _Cm, Pid, How) ->
Win2 = case dbg_wx_trace_win:is_shown(Win, Mod) of
- {true, Win3} -> Win3;
+ %% {true, Win3} -> Win3;
false -> gui_load_module(Win, Mod, Pid)
end,
dbg_wx_trace_win:mark_line(Win2, Line, How).
diff --git a/lib/debugger/src/dbg_wx_trace_win.erl b/lib/debugger/src/dbg_wx_trace_win.erl
index 48935c66a5..232d61b1db 100644
--- a/lib/debugger/src/dbg_wx_trace_win.erl
+++ b/lib/debugger/src/dbg_wx_trace_win.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/src/dbg_wx_view.erl b/lib/debugger/src/dbg_wx_view.erl
index fc7ffc0d56..9715a9c17b 100644
--- a/lib/debugger/src/dbg_wx_view.erl
+++ b/lib/debugger/src/dbg_wx_view.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/dbg_wx_win.erl b/lib/debugger/src/dbg_wx_win.erl
index 65b2a0ebea..63f74392b5 100644
--- a/lib/debugger/src/dbg_wx_win.erl
+++ b/lib/debugger/src/dbg_wx_win.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/src/dbg_wx_winman.erl b/lib/debugger/src/dbg_wx_winman.erl
index 79dcc47f6f..0045948d2f 100644
--- a/lib/debugger/src/dbg_wx_winman.erl
+++ b/lib/debugger/src/dbg_wx_winman.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/debugger.app.src b/lib/debugger/src/debugger.app.src
index f102385d39..446f2b9882 100644
--- a/lib/debugger/src/debugger.app.src
+++ b/lib/debugger/src/debugger.app.src
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -47,5 +48,5 @@
]},
{registered, [dbg_iserver, dbg_wx_mon, dbg_wx_winman]},
{applications, [kernel, stdlib]},
- {runtime_dependencies, ["wx-1.2","stdlib-2.0","kernel-3.0","erts-6.0",
+ {runtime_dependencies, ["wx-1.2","stdlib-2.5","kernel-3.0","erts-6.0",
"compiler-5.0"]}]}.
diff --git a/lib/debugger/src/debugger.appup.src b/lib/debugger/src/debugger.appup.src
index 81d2fab05a..2fa3f5de5f 100644
--- a/lib/debugger/src/debugger.appup.src
+++ b/lib/debugger/src/debugger.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/debugger/src/debugger.erl b/lib/debugger/src/debugger.erl
index 77fd0acb70..c188663668 100644
--- a/lib/debugger/src/debugger.erl
+++ b/lib/debugger/src/debugger.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/i.erl b/lib/debugger/src/i.erl
index 0afb998097..f8f6a3b245 100644
--- a/lib/debugger/src/i.erl
+++ b/lib/debugger/src/i.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl
index 908390ce50..4f54beb45b 100644
--- a/lib/debugger/src/int.erl
+++ b/lib/debugger/src/int.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -365,7 +366,7 @@ stop() ->
%% function will receive the following messages:
%% {int, {interpret, Mod}}
%% {int, {no_interpret, Mod}}
-%% {int, {new_process, Pid, Function, Status, Info}}
+%% {int, {new_process, {Pid, Function, Status, Info}}}
%% {int, {new_status, Pid, Status, Info}}
%% {int, {new_break, {Point, Options}}}
%% {int, {delete_break, Point}}
diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile
index 9a0ce14ecd..82f49c155f 100644
--- a/lib/debugger/test/Makefile
+++ b/lib/debugger/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/debugger/test/andor_SUITE.erl b/lib/debugger/test/andor_SUITE.erl
index 13a6e3da1e..384b6c7c77 100644
--- a/lib/debugger/test/andor_SUITE.erl
+++ b/lib/debugger/test/andor_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_bincomp_SUITE.erl b/lib/debugger/test/bs_bincomp_SUITE.erl
index 6c2fd255a1..0750c6793d 100644
--- a/lib/debugger/test/bs_bincomp_SUITE.erl
+++ b/lib/debugger/test/bs_bincomp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_construct_SUITE.erl b/lib/debugger/test/bs_construct_SUITE.erl
index 8a6798c6ad..f62512568f 100644
--- a/lib/debugger/test/bs_construct_SUITE.erl
+++ b/lib/debugger/test/bs_construct_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_match_bin_SUITE.erl b/lib/debugger/test/bs_match_bin_SUITE.erl
index 5a7c30f16b..a61b56501c 100644
--- a/lib/debugger/test/bs_match_bin_SUITE.erl
+++ b/lib/debugger/test/bs_match_bin_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_match_int_SUITE.erl b/lib/debugger/test/bs_match_int_SUITE.erl
index bff5f8ff65..fd77530dd5 100644
--- a/lib/debugger/test/bs_match_int_SUITE.erl
+++ b/lib/debugger/test/bs_match_int_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_match_misc_SUITE.erl b/lib/debugger/test/bs_match_misc_SUITE.erl
index 54fa9a59df..2221cfe08b 100644
--- a/lib/debugger/test/bs_match_misc_SUITE.erl
+++ b/lib/debugger/test/bs_match_misc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_match_tail_SUITE.erl b/lib/debugger/test/bs_match_tail_SUITE.erl
index 9f7519cf3a..9ec93978ed 100644
--- a/lib/debugger/test/bs_match_tail_SUITE.erl
+++ b/lib/debugger/test/bs_match_tail_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bs_utf_SUITE.erl b/lib/debugger/test/bs_utf_SUITE.erl
index 7a1d3baaca..90c4d6c7b9 100644
--- a/lib/debugger/test/bs_utf_SUITE.erl
+++ b/lib/debugger/test/bs_utf_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bug_SUITE.erl b/lib/debugger/test/bug_SUITE.erl
index 1a7e876329..542db3f41e 100644
--- a/lib/debugger/test/bug_SUITE.erl
+++ b/lib/debugger/test/bug_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/bug_SUITE_data/Makefile.src b/lib/debugger/test/bug_SUITE_data/Makefile.src
index 792b3299e1..244c9025f0 100644
--- a/lib/debugger/test/bug_SUITE_data/Makefile.src
+++ b/lib/debugger/test/bug_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/debugger/test/bug_SUITE_data/otp2163.erl b/lib/debugger/test/bug_SUITE_data/otp2163.erl
index 4e3c487ef7..6b6dcffa8c 100644
--- a/lib/debugger/test/bug_SUITE_data/otp2163.erl
+++ b/lib/debugger/test/bug_SUITE_data/otp2163.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/test/bug_SUITE_data/otp4845.erl b/lib/debugger/test/bug_SUITE_data/otp4845.erl
index 18ca08b977..ffb038cc9e 100644
--- a/lib/debugger/test/bug_SUITE_data/otp4845.erl
+++ b/lib/debugger/test/bug_SUITE_data/otp4845.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/test/cleanup.erl b/lib/debugger/test/cleanup.erl
index 5f1ea71d2e..b40ae5f82c 100644
--- a/lib/debugger/test/cleanup.erl
+++ b/lib/debugger/test/cleanup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/test/dbg_ui_SUITE.erl b/lib/debugger/test/dbg_ui_SUITE.erl
index 86156ebbf5..f0f4e09aa8 100644
--- a/lib/debugger/test/dbg_ui_SUITE.erl
+++ b/lib/debugger/test/dbg_ui_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl
index db84ee5fc8..c26ccfceda 100644
--- a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl
+++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl
index ea72150bca..63224fc493 100644
--- a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl
+++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl
@@ -3,19 +3,19 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% http://www.apache.org/licenses/LICENSE-2.0
%%
-%% %CopyrightEnd%
+%% 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 : Functions for manipulating sets as ordered lists.
diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl
index a48a7e112f..d7af58e573 100644
--- a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl
+++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/debugger_SUITE.erl b/lib/debugger/test/debugger_SUITE.erl
index c74550be86..9207df38e4 100644
--- a/lib/debugger/test/debugger_SUITE.erl
+++ b/lib/debugger/test/debugger_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/debugger_test.erl b/lib/debugger/test/debugger_test.erl
index a64bed5db1..9a5fb11b8c 100644
--- a/lib/debugger/test/debugger_test.erl
+++ b/lib/debugger/test/debugger_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/erl_eval_SUITE.erl b/lib/debugger/test/erl_eval_SUITE.erl
index ba60ed6fb3..af9b0a6e6e 100644
--- a/lib/debugger/test/erl_eval_SUITE.erl
+++ b/lib/debugger/test/erl_eval_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/debugger/test/exception_SUITE.erl b/lib/debugger/test/exception_SUITE.erl
index 86554ab2d4..f42dbc7776 100644
--- a/lib/debugger/test/exception_SUITE.erl
+++ b/lib/debugger/test/exception_SUITE.erl
@@ -3,20 +3,20 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(exception_SUITE).
diff --git a/lib/debugger/test/fun_SUITE.erl b/lib/debugger/test/fun_SUITE.erl
index 8425f973e6..fabee16cee 100644
--- a/lib/debugger/test/fun_SUITE.erl
+++ b/lib/debugger/test/fun_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/guard_SUITE.erl b/lib/debugger/test/guard_SUITE.erl
index bf5fa82749..880c89532b 100644
--- a/lib/debugger/test/guard_SUITE.erl
+++ b/lib/debugger/test/guard_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl
index fc309acf9b..5f2e4dd84d 100644
--- a/lib/debugger/test/int_SUITE.erl
+++ b/lib/debugger/test/int_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/int_SUITE_data/Makefile.src b/lib/debugger/test/int_SUITE_data/Makefile.src
index 95b96b5d00..0bbb90734f 100644
--- a/lib/debugger/test/int_SUITE_data/Makefile.src
+++ b/lib/debugger/test/int_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/debugger/test/int_SUITE_data/guards.erl b/lib/debugger/test/int_SUITE_data/guards.erl
index c847bb6a8c..d148974e53 100644
--- a/lib/debugger/test/int_SUITE_data/guards.erl
+++ b/lib/debugger/test/int_SUITE_data/guards.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/int_SUITE_data/lists1.erl b/lib/debugger/test/int_SUITE_data/lists1.erl
index db84ee5fc8..c26ccfceda 100644
--- a/lib/debugger/test/int_SUITE_data/lists1.erl
+++ b/lib/debugger/test/int_SUITE_data/lists1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/int_SUITE_data/my_lists.erl b/lib/debugger/test/int_SUITE_data/my_lists.erl
index f9399b1085..0ec2a7585f 100644
--- a/lib/debugger/test/int_SUITE_data/my_lists.erl
+++ b/lib/debugger/test/int_SUITE_data/my_lists.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/int_SUITE_data/ordsets1.erl b/lib/debugger/test/int_SUITE_data/ordsets1.erl
index a01d35eb51..349921b951 100644
--- a/lib/debugger/test/int_SUITE_data/ordsets1.erl
+++ b/lib/debugger/test/int_SUITE_data/ordsets1.erl
@@ -3,20 +3,20 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
-
%%
%% Copyright (C) 1991, Ellemtel Telecommunications Systems Laboratories
%% File : ordsets.erl
diff --git a/lib/debugger/test/int_SUITE_data/test.erl b/lib/debugger/test/int_SUITE_data/test.erl
index 679b266380..b29394302b 100644
--- a/lib/debugger/test/int_SUITE_data/test.erl
+++ b/lib/debugger/test/int_SUITE_data/test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/int_SUITE_data/test1.erl b/lib/debugger/test/int_SUITE_data/test1.erl
index a93416cbac..cb60c67bc4 100644
--- a/lib/debugger/test/int_SUITE_data/test1.erl
+++ b/lib/debugger/test/int_SUITE_data/test1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/debugger/test/int_break_SUITE.erl b/lib/debugger/test/int_break_SUITE.erl
index 7bb0fc2018..21b53a8d30 100644
--- a/lib/debugger/test/int_break_SUITE.erl
+++ b/lib/debugger/test/int_break_SUITE.erl
@@ -3,20 +3,20 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(int_break_SUITE).
diff --git a/lib/debugger/test/int_break_SUITE_data/Makefile.src b/lib/debugger/test/int_break_SUITE_data/Makefile.src
index 0d1ee35a67..7b79aec4aa 100644
--- a/lib/debugger/test/int_break_SUITE_data/Makefile.src
+++ b/lib/debugger/test/int_break_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/debugger/test/int_break_SUITE_data/ordsets1.erl b/lib/debugger/test/int_break_SUITE_data/ordsets1.erl
index 6300c6097c..b2c7221eea 100644
--- a/lib/debugger/test/int_break_SUITE_data/ordsets1.erl
+++ b/lib/debugger/test/int_break_SUITE_data/ordsets1.erl
@@ -3,20 +3,20 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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 : Functions for manipulating sets as ordered lists.
diff --git a/lib/debugger/test/int_eval_SUITE.erl b/lib/debugger/test/int_eval_SUITE.erl
index 9d7ef238e3..f30d386de9 100644
--- a/lib/debugger/test/int_eval_SUITE.erl
+++ b/lib/debugger/test/int_eval_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -293,7 +294,7 @@ stacktrace(Config) when is_list(Config) ->
maps(Config) when is_list(Config) ->
Fun = fun () -> ?IM:empty_map_update([camembert]) end,
- {'EXIT',{{badarg,[camembert]},_}} = spawn_eval(Fun),
+ {'EXIT',{{badmap,[camembert]},_}} = spawn_eval(Fun),
[#{hello := 0, price := 0}] = spawn_eval(fun () -> ?IM:update_in_fun() end),
ok.
diff --git a/lib/debugger/test/int_eval_SUITE_data/Makefile.src b/lib/debugger/test/int_eval_SUITE_data/Makefile.src
index 28a1432157..bc2eb9a37d 100644
--- a/lib/debugger/test/int_eval_SUITE_data/Makefile.src
+++ b/lib/debugger/test/int_eval_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
index 7f55360f48..b0ff4ce752 100644
--- a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
+++ b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/lc_SUITE.erl b/lib/debugger/test/lc_SUITE.erl
index 2f05eb7fca..aca4c4de7c 100644
--- a/lib/debugger/test/lc_SUITE.erl
+++ b/lib/debugger/test/lc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/line_number_SUITE.erl b/lib/debugger/test/line_number_SUITE.erl
index d1f56d3493..6ec5ef5d5a 100644
--- a/lib/debugger/test/line_number_SUITE.erl
+++ b/lib/debugger/test/line_number_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -65,7 +66,6 @@ end_per_suite(Config) when is_list(Config) ->
-
%%
%% === Make sure that this is always line 70 ===
%%
diff --git a/lib/debugger/test/map_SUITE.erl b/lib/debugger/test/map_SUITE.erl
index 0076193725..0ef634f7aa 100644
--- a/lib/debugger/test/map_SUITE.erl
+++ b/lib/debugger/test/map_SUITE.erl
@@ -2,16 +2,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,17 +25,43 @@
]).
-export([
- t_build_and_match_literals/1,
- t_update_literals/1,t_match_and_update_literals/1,
+ t_build_and_match_literals/1, t_build_and_match_literals_large/1,
+ t_update_literals/1, t_update_literals_large/1,
+ t_match_and_update_literals/1, t_match_and_update_literals_large/1,
t_update_map_expressions/1,
- t_update_assoc/1,t_update_exact/1,
- t_guard_bifs/1, t_guard_sequence/1, t_guard_update/1,
- t_guard_receive/1, t_guard_fun/1,
+ t_update_assoc/1, t_update_assoc_large/1,
+ t_update_exact/1, t_update_exact_large/1,
+ t_guard_bifs/1,
+ t_guard_sequence/1, t_guard_sequence_large/1,
+ t_guard_update/1, t_guard_update_large/1,
+ t_guard_receive/1, t_guard_receive_large/1,
+ t_guard_fun/1,
t_list_comprehension/1,
t_map_sort_literals/1,
- %t_size/1,
t_map_size/1,
-
+ t_build_and_match_aliasing/1,
+
+ %% variables
+ t_build_and_match_variables/1,
+ t_update_assoc_variables/1,t_update_exact_variables/1,
+ t_nested_pattern_expressions/1,
+ t_guard_update_variables/1,
+ t_guard_sequence_variables/1,
+ t_guard_sequence_mixed/1,
+ t_frequency_table/1,
+
+ %% not covered in 17.0-rc1
+ t_build_and_match_over_alloc/1,
+ t_build_and_match_empty_val/1,
+ t_build_and_match_val/1,
+ t_build_and_match_nil/1,
+ t_build_and_match_structure/1,
+
+ %% errors in 17.0-rc1
+ t_update_values/1,
+ t_expand_map_update/1,
+ t_export/1,
+
%% Specific Map BIFs
t_bif_map_get/1,
t_bif_map_find/1,
@@ -61,8 +88,7 @@
%% misc
t_pdict/1,
- t_ets/1,
- t_dets/1
+ t_ets/1
]).
-include_lib("stdlib/include/ms_transform.hrl").
@@ -70,14 +96,42 @@
suite() -> [].
all() -> [
- t_build_and_match_literals,
- t_update_literals, t_match_and_update_literals,
+ t_build_and_match_literals, t_build_and_match_literals_large,
+ t_update_literals, t_update_literals_large,
+ t_match_and_update_literals, t_match_and_update_literals_large,
t_update_map_expressions,
- t_update_assoc,t_update_exact,
- t_guard_bifs, t_guard_sequence, t_guard_update,
- t_guard_receive,t_guard_fun, t_list_comprehension,
+ t_update_assoc, t_update_assoc_large,
+ t_update_exact, t_update_exact_large,
+ t_guard_bifs,
+ t_guard_sequence, t_guard_sequence_large,
+ t_guard_update, t_guard_update_large,
+ t_guard_receive, t_guard_receive_large,
+ t_guard_fun, t_list_comprehension,
t_map_sort_literals,
-
+ t_build_and_match_aliasing,
+
+ %% variables
+ t_build_and_match_variables,
+ t_update_assoc_variables,t_update_exact_variables,
+ t_nested_pattern_expressions,
+ t_guard_update_variables,
+ t_guard_sequence_variables,
+ t_guard_sequence_mixed,
+ t_frequency_table,
+
+ %% not covered in 17.0-rc1
+ t_build_and_match_over_alloc,
+ t_build_and_match_empty_val,
+ t_build_and_match_val,
+ t_build_and_match_nil,
+ t_build_and_match_structure,
+
+
+ %% errors in 17.0-rc1
+ t_update_values,
+ t_expand_map_update,
+ t_export,
+
%% Specific Map BIFs
t_bif_map_get,t_bif_map_find,t_bif_map_is_key,
t_bif_map_keys, t_bif_map_merge, t_bif_map_new,
@@ -94,7 +148,6 @@ all() -> [
t_maps_fold, t_maps_map,
t_maps_size, t_maps_without,
-
%% Other functions
t_pdict,
t_ets
@@ -147,17 +200,461 @@ t_build_and_match_literals(Config) when is_list(Config) ->
{'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = id(#{x=>"three"}))),
ok.
+t_build_and_match_literals_large(Config) when is_list(Config) ->
+ % normal non-repeating
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M0,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M0,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M0,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M0,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M0,
+
+ 60 = map_size(M0),
+ 60 = maps:size(M0),
+
+ % with repeating
+ M1 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 10=>na0,20=>nb0,30=>"nc0","40"=>"nd0",<<"50">>=>"ne0",{["00"]}=>"n10",
+ 11=>na1,21=>nb1,31=>"nc1","41"=>"nd1",<<"51">>=>"ne1",{["01"]}=>"n11",
+ 12=>na2,22=>nb2,32=>"nc2","42"=>"nd2",<<"52">>=>"ne2",{["02"]}=>"n12",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+
+ 13=>na3,23=>nb3,33=>"nc3","43"=>"nd3",<<"53">>=>"ne3",{["03"]}=>"n13",
+ 14=>na4,24=>nb4,34=>"nc4","44"=>"nd4",<<"54">>=>"ne4",{["04"]}=>"n14",
+
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }),
+
+ #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1,
+ #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1,
+ #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1,
+ #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1,
+ #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1,
+
+ 60 = map_size(M1),
+ 60 = maps:size(M1),
+
+ % with floats
+
+ M2 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9"}),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ 90 = map_size(M2),
+ 90 = maps:size(M2),
+
+ % with bignums
+ M3 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ 36893488147419103232=>big1, 73786976294838206464=>big2,
+ 147573952589676412928=>big3, 18446744073709551616=>big4,
+ 4294967296=>big5, 8589934592=>big6,
+ 4294967295=>big7, 67108863=>big8
+ }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+
+ 98 = map_size(M3),
+ 98 = maps:size(M3),
+
+ %% with maps
+
+ M4 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M4,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M4,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M4,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M4,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M4,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M4,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M4,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M4,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M4,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M4,
+
+ #{ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := "small map key 2",
+ #{ third => small, map => key } := "small map key 3" } = M4,
+
+ #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M4,
+
+
+ #{ 15:=V1,25:=b5,35:=V2,"45":="d5",<<"55">>:=V3,{["05"]}:="15",
+ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := V4,
+ #{ third => small, map => key } := "small map key 3",
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := V5 } = M4,
+
+ a5 = V1,
+ "c5" = V2,
+ "e5" = V3,
+ "small map key 2" = V4,
+ "large map key 1" = V5,
+
+ 95 = map_size(M4),
+ 95 = maps:size(M4),
+
+ % call for value
+
+ M5 = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ #{ one => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M5,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M5,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M5,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M5,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M5,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M5,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M5,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M5,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M5,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M5,
+
+ #{ #{ one => small, map => key } := "small map key 1",
+ #{ second => small, map => key } := "small map key 2",
+ #{ third => small, map => key } := "small map key 3" } = M5,
+
+ #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M5,
+
+ 95 = map_size(M5),
+ 95 = maps:size(M5),
+
+ %% remember
+
+ #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0,
+ #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0,
+ #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0,
+ #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0,
+ #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0,
+
+ #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1,
+ #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1,
+ #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1,
+ #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1,
+ #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2,
+
+ #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3,
+ #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3,
+ #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3,
+ #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3,
+ #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3,
+
+ #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
+ #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3,
+
+ #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3,
+ #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3,
+ #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3,
+ #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3,
-%% Tests size(Map).
-%% not implemented, perhaps it shouldn't be either
+ ok.
-%t_size(Config) when is_list(Config) ->
-% 0 = size(#{}),
-% 1 = size(#{a=>1}),
-% 1 = size(#{a=>#{a=>1}}),
-% 2 = size(#{a=>1, b=>2}),
-% 3 = size(#{a=>1, b=>2, b=>"3"}),
-% ok.
t_map_size(Config) when is_list(Config) ->
0 = map_size(id(#{})),
@@ -175,9 +672,10 @@ t_map_size(Config) when is_list(Config) ->
false = map_is_size(M#{ "c" => 2}, 2),
%% Error cases.
- {'EXIT',{badarg,_}} = (catch map_size([])),
- {'EXIT',{badarg,_}} = (catch map_size(<<1,2,3>>)),
- {'EXIT',{badarg,_}} = (catch map_size(1)),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},_}} =
+ (catch map_size(T))
+ end),
ok.
map_is_size(M,N) when map_size(M) =:= N -> true;
@@ -191,13 +689,72 @@ t_update_literals(Config) when is_list(Config) ->
]),
ok.
+t_update_literals_large(Config) when is_list(Config) ->
+ Map = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ #{ one => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{x:="d",q:="4"} = loop_update_literals_x_q(Map, [
+ {"a","1"},{"b","2"},{"c","3"},{"d","4"}
+ ]),
+ ok.
+
loop_update_literals_x_q(Map, []) -> Map;
loop_update_literals_x_q(Map, [{X,Q}|Vs]) ->
loop_update_literals_x_q(Map#{q=>Q,x=>X},Vs).
% test map updates with matching
t_match_and_update_literals(Config) when is_list(Config) ->
- Map = #{x=>0,y=>"untouched",z=>"also untouched",q=>1},
+ Map = #{ x=>0,y=>"untouched",z=>"also untouched",q=>1,
+ #{ "one" => small, map => key } => "small map key 1" },
#{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [
{1,2},{3,4},{5,6},{7,8}
]),
@@ -211,8 +768,77 @@ t_match_and_update_literals(Config) when is_list(Config) ->
#{ 4 := another_number, int := 3 } = M2#{ 4 => another_number },
ok.
+t_match_and_update_literals_large(Config) when is_list(Config) ->
+ Map = id(#{ 10=>id(a0),20=>b0,30=>id("c0"),"40"=>"d0",<<"50">>=>id("e0"),{["00"]}=>"10",
+ 11=>id(a1),21=>b1,31=>id("c1"),"41"=>"d1",<<"51">>=>id("e1"),{["01"]}=>"11",
+ 12=>id(a2),22=>b2,32=>id("c2"),"42"=>"d2",<<"52">>=>id("e2"),{["02"]}=>"12",
+ 13=>id(a3),23=>b3,33=>id("c3"),"43"=>"d3",<<"53">>=>id("e3"),{["03"]}=>"13",
+ 14=>id(a4),24=>b4,34=>id("c4"),"44"=>"d4",<<"54">>=>id("e4"),{["04"]}=>"14",
+
+ 15=>id(a5),25=>b5,35=>id("c5"),"45"=>"d5",<<"55">>=>id("e5"),{["05"]}=>"15",
+ 16=>id(a6),26=>b6,36=>id("c6"),"46"=>"d6",<<"56">>=>id("e6"),{["06"]}=>"16",
+ 17=>id(a7),27=>b7,37=>id("c7"),"47"=>"d7",<<"57">>=>id("e7"),{["07"]}=>"17",
+ 18=>id(a8),28=>b8,38=>id("c8"),"48"=>"d8",<<"58">>=>id("e8"),{["08"]}=>"18",
+ 19=>id(a9),29=>b9,39=>id("c9"),"49"=>"d9",<<"59">>=>id("e9"),{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>id(fb0),30.0=>id("fc0"),
+ 11.0=>fa1,21.0=>id(fb1),31.0=>id("fc1"),
+ 12.0=>fa2,22.0=>id(fb2),32.0=>id("fc2"),
+ 13.0=>fa3,23.0=>id(fb3),33.0=>id("fc3"),
+ 14.0=>fa4,24.0=>id(fb4),34.0=>id("fc4"),
+
+ 15.0=>fa5,25.0=>id(fb5),35.0=>id("fc5"),
+ 16.0=>fa6,26.0=>id(fb6),36.0=>id("fc6"),
+ 17.0=>fa7,27.0=>id(fb7),37.0=>id("fc7"),
+ 18.0=>fa8,28.0=>id(fb8),38.0=>id("fc8"),
+ 19.0=>fa9,29.0=>id(fb9),39.0=>id("fc9"),
+
+ x=>0,y=>"untouched",z=>"also untouched",q=>1,
+
+ #{ "one" => small, map => key } => id("small map key 1"),
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => id("large map key 2") }),
+
+ #{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [
+ {1,2},{3,4},{5,6},{7,8}
+ ]),
+ M0 = id(Map#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat}),
+ M1 = id(Map#{}),
+ M2 = M1#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat},
+ M0 = M2,
+
+ #{ 4 := another_number, int := 3 } = M2#{ 4 => another_number },
+ ok.
+
loop_match_and_update_literals_x_q(Map, []) -> Map;
-loop_match_and_update_literals_x_q(#{q:=Q0,x:=X0} = Map, [{X,Q}|Vs]) ->
+loop_match_and_update_literals_x_q(#{ q:=Q0, x:=X0,
+ #{ "one" => small, map => key } := "small map key 1" } = Map, [{X,Q}|Vs]) ->
loop_match_and_update_literals_x_q(Map#{q=>Q0+Q,x=>X0+X},Vs).
@@ -225,9 +851,9 @@ t_update_map_expressions(Config) when is_list(Config) ->
#{ a :=42, b:=42, c:=42 } = (maps:from_list([{a,1},{b,2},{c,3}]))#{ a := 42, b := 42, c := 42 },
#{ "a" :=1, "b":=42, "c":=42 } = (maps:from_list([{"a",1},{"b",2}]))#{ "b" := 42, "c" => 42 },
- %% Error cases, FIXME: should be 'badmap'?
- {'EXIT',{{badarg,<<>>},_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
- {'EXIT',{{badarg,[]},_}} = (catch (id([]))#{ a := 42, b => 2 }),
+ %% Error cases.
+ {'EXIT',{{badmap,<<>>},_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
+ {'EXIT',{{badmap,[]},_}} = (catch (id([]))#{ a := 42, b => 2 }),
ok.
@@ -243,11 +869,80 @@ t_update_assoc(Config) when is_list(Config) ->
M2 = M0#{3.0:=wrong,3.0=>new},
%% Errors cases.
- BadMap = id(badmap),
- {'EXIT',{{badarg,BadMap},_}} = (catch BadMap#{nonexisting=>val}),
+ BadMap = id(not_a_good_map),
+ {'EXIT',{{badmap,BadMap},_}} = (catch BadMap#{nonexisting=>val}),
ok.
+t_update_assoc_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ M1 = M0#{1=>42,2=>100,4=>[a,b,c]},
+ #{1:=42,2:=100,10.0:=fa0,4:=[a,b,c],25:=b5} = M1,
+ #{ 10:=43, 24:=b4, 15:=a5, 35:="c5", 2.0:=100, 13.0:=fa3, 4.0:=[a,b,c]} =
+ M0#{1.0=>float,10:=43,2.0=>wrong,2.0=>100,4.0=>[a,b,c]},
+
+ M2 = M0#{13.0=>new},
+ #{10:=a0,20:=b0,13.0:=new,"40":="d0",<<"50">>:="e0"} = M2,
+ M2 = M0#{13.0:=wrong,13.0=>new},
+
+ %% Errors cases.
+ BadMap = id(a_bad_map),
+ {'EXIT',{{badmap,BadMap},_}} = (catch BadMap#{nonexisting=>M0}),
+ ok.
+
+
t_update_exact(Config) when is_list(Config) ->
M0 = id(#{1=>a,2=>b,3.0=>c,4=>d,5=>e}),
@@ -261,13 +956,148 @@ t_update_exact(Config) when is_list(Config) ->
%% M2 = M0#{3=>wrong,3.0:=new}, %% FIXME
%% Errors cases.
- {'EXIT',{badarg,_}} = (catch M0#{nonexisting:=val}),
- {'EXIT',{badarg,_}} = (catch M0#{1.0:=v,1.0=>v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42.0:=v,42:=v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ do_badmap(fun(T) ->
+ {'EXIT',{{badmap,T},_}} =
+ (catch T#{nonexisting=>val})
+ end),
+ Empty = id(#{}),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch Empty#{nonexisting:=val}),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+
+ %% Evaluation order.
+ BadMap = id([no,map]),
+ {'EXIT',{blurf,_}} =
+ (catch BadMap#{whatever:=id(error(blurf))}),
+ {'EXIT',{blurf,_}} =
+ (catch BadMap#{id(error(blurf)):=whatever}),
+ {'EXIT',{{badmap,BadMap},_}} =
+ (catch BadMap#{nonexisting:=whatever}),
+ ok.
+
+t_update_exact_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ M1 = M0#{10:=42,<<"55">>:=100,10.0:=[a,b,c]},
+ #{ 10:=42,<<"55">>:=100,{["05"]}:="15",10.0:=[a,b,c],
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1" } = M1,
+
+ M1 = M0#{10:=wrong,10=>42,<<"55">>=>wrong,<<"55">>:=100,10.0:=[a,b,c]},
+
+ M2 = M0#{13.0:=new},
+ #{10:=a0,20:=b0,13.0:=new} = M2,
+ M2 = M0#{13.0=>wrong,13.0:=new},
+
+ %% Errors cases.
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+
+ ok.
+
+t_update_values(Config) when is_list(Config) ->
+ V0 = id(1337),
+ M0 = #{ a => 1, val => V0},
+ V1 = get_val(M0),
+ M1 = id(M0#{ val := [V0,V1], "wazzup" => 42 }),
+ [1337, {some_val, 1337}] = get_val(M1),
+ M2 = id(M1#{ <<42:333>> => 1337 }),
+ {bin_key,1337} = get_val(M2),
+
+ N = 110,
+ List = [{[I,1,2,3,I],{1,2,3,"wat",I}}|| I <- lists:seq(1,N)],
+
+ {_,_,#{val2 := {1,2,3,"wat",N}, val1 := [N,1,2,3,N]}} = lists:foldl(fun
+ ({V2,V3},{Old2,Old3,Mi}) ->
+ ok = check_val(Mi,Old2,Old3),
+ #{ val1 := Old2, val2 := Old3 } = Mi,
+ {V2,V3, Mi#{ val1 := id(V2), val2 := V1, val2 => id(V3)}}
+ end, {none, none, #{val1=>none,val2=>none}},List),
+ ok.
+
+t_expand_map_update(Config) when is_list(Config) ->
+ M = #{<<"hello">> => <<"world">>}#{<<"hello">> := <<"les gens">>},
+ #{<<"hello">> := <<"les gens">>} = M,
ok.
+t_export(Config) when is_list(Config) ->
+ Raclette = id(#{}),
+ case brie of brie -> Fromage = Raclette end,
+ Raclette = Fromage#{},
+ ok.
+
+check_val(#{val1:=V1, val2:=V2},V1,V2) -> ok.
+
+get_val(#{ <<42:333>> := V }) -> {bin_key, V};
+get_val(#{ "wazzup" := _, val := V}) -> V;
+get_val(#{ val := V }) -> {some_val, V}.
+
+
t_guard_bifs(Config) when is_list(Config) ->
true = map_guard_head(#{a=>1}),
false = map_guard_head([]),
@@ -303,6 +1133,75 @@ t_guard_sequence(Config) when is_list(Config) ->
{'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(#{b=>5})),
ok.
+t_guard_sequence_large(Config) when is_list(Config) ->
+ M0 = id(#{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19",
+
+ 10.0=>fa0,20.0=>fb0,30.0=>"fc0",
+ 11.0=>fa1,21.0=>fb1,31.0=>"fc1",
+ 12.0=>fa2,22.0=>fb2,32.0=>"fc2",
+ 13.0=>fa3,23.0=>fb3,33.0=>"fc3",
+ 14.0=>fa4,24.0=>fb4,34.0=>"fc4",
+
+ 15.0=>fa5,25.0=>fb5,35.0=>"fc5",
+ 16.0=>fa6,26.0=>fb6,36.0=>"fc6",
+ 17.0=>fa7,27.0=>fb7,37.0=>"fc7",
+ 18.0=>fa8,28.0=>fb8,38.0=>"fc8",
+ 19.0=>fa9,29.0=>fb9,39.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+ {1, "a"} = map_guard_sequence_1(M0#{seq=>1,val=>id("a")}),
+ {2, "b"} = map_guard_sequence_1(M0#{seq=>2,val=>id("b")}),
+ {3, "c"} = map_guard_sequence_1(M0#{seq=>3,val=>id("c")}),
+ {4, "d"} = map_guard_sequence_1(M0#{seq=>4,val=>id("d")}),
+ {5, "e"} = map_guard_sequence_1(M0#{seq=>5,val=>id("e")}),
+
+ {1,M1} = map_guard_sequence_2(M1 = id(M0#{a=>3})),
+ {2,M2} = map_guard_sequence_2(M2 = id(M0#{a=>4, b=>4})),
+ {3,gg,M3} = map_guard_sequence_2(M3 = id(M0#{a=>gg, b=>4})),
+ {4,sc,sc,M4} = map_guard_sequence_2(M4 = id(M0#{a=>sc, b=>3, c=>sc2})),
+ {5,kk,kk,M5} = map_guard_sequence_2(M5 = id(M0#{a=>kk, b=>other, c=>sc2})),
+
+ {'EXIT',{function_clause,_}} = (catch map_guard_sequence_1(M0#{seq=>6,val=>id("e")})),
+ {'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(M0#{b=>5})),
+ ok.
+
map_guard_sequence_1(#{seq:=1=Seq, val:=Val}) -> {Seq,Val};
map_guard_sequence_1(#{seq:=2=Seq, val:=Val}) -> {Seq,Val};
map_guard_sequence_1(#{seq:=3=Seq, val:=Val}) -> {Seq,Val};
@@ -322,6 +1221,65 @@ t_guard_update(Config) when is_list(Config) ->
second = map_guard_update(#{y=>old}, #{x=>second,y=>old}),
ok.
+t_guard_update_large(Config) when is_list(Config) ->
+ M0 = id(#{ 70=>a0,80=>b0,90=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10",
+ 71=>a1,81=>b1,91=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11",
+ 72=>a2,82=>b2,92=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12",
+ 73=>a3,83=>b3,93=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13",
+ 74=>a4,84=>b4,94=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14",
+
+ 75=>a5,85=>b5,95=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15",
+ 76=>a6,86=>b6,96=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16",
+ 77=>a7,87=>b7,97=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17",
+ 78=>a8,88=>b8,98=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18",
+ 79=>a9,89=>b9,99=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19",
+
+ 70.0=>fa0,80.0=>fb0,90.0=>"fc0",
+ 71.0=>fa1,81.0=>fb1,91.0=>"fc1",
+ 72.0=>fa2,82.0=>fb2,92.0=>"fc2",
+ 73.0=>fa3,83.0=>fb3,93.0=>"fc3",
+ 74.0=>fa4,84.0=>fb4,94.0=>"fc4",
+
+ 75.0=>fa5,85.0=>fb5,95.0=>"fc5",
+ 76.0=>fa6,86.0=>fb6,96.0=>"fc6",
+ 77.0=>fa7,87.0=>fb7,97.0=>"fc7",
+ 78.0=>fa8,88.0=>fb8,98.0=>"fc8",
+ 79.0=>fa9,89.0=>fb9,99.0=>"fc9",
+
+ #{ one => small, map => key } => "small map key 1",
+ #{ second => small, map => key } => "small map key 2",
+ #{ third => small, map => key } => "small map key 3",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1",
+
+ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10",
+ 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11",
+ 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12",
+ 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13",
+ 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14",
+
+ 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15",
+ k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16",
+ 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17",
+ 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18",
+ 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }),
+
+
+ error = map_guard_update(M0#{},M0#{}),
+ first = map_guard_update(M0#{},M0#{x=>first}),
+ second = map_guard_update(M0#{y=>old}, M0#{x=>second,y=>old}),
+ ok.
+
map_guard_update(M1, M2) when M1#{x=>first} =:= M2 -> first;
map_guard_update(M1, M2) when M1#{x=>second} =:= M2 -> second;
map_guard_update(_, _) -> error.
@@ -351,6 +1309,42 @@ t_guard_receive(Config) when is_list(Config) ->
done = call(Pid, done),
ok.
+-define(t_guard_receive_large_procs, 50).
+
+t_guard_receive_large(Config) when is_list(Config) ->
+ M = lists:foldl(fun(_,#{procs := Ps } = M) ->
+ M#{ procs := Ps#{ spawn_link(fun() -> grecv_loop() end) => 0 }}
+ end, #{procs => #{}, done => 0}, lists:seq(1,?t_guard_receive_large_procs)),
+ lists:foreach(fun(Pid) ->
+ Pid ! {self(), hello}
+ end, maps:keys(maps:get(procs,M))),
+ ok = guard_receive_large_loop(M),
+ ok.
+
+guard_receive_large_loop(#{done := ?t_guard_receive_large_procs}) ->
+ ok;
+guard_receive_large_loop(M) ->
+ receive
+ #{pid := Pid, msg := hello} ->
+ case M of
+ #{done := Count, procs := #{Pid := 15}} ->
+ Pid ! {self(), done},
+ guard_receive_large_loop(M#{done := Count + 1});
+ #{procs := #{Pid := Count} = Ps} ->
+ Pid ! {self(), hello},
+ guard_receive_large_loop(M#{procs := Ps#{Pid := Count + 1}})
+ end
+ end.
+
+grecv_loop() ->
+ receive
+ {_, done} ->
+ ok;
+ {Pid, hello} ->
+ Pid ! #{pid=>self(), msg=>hello},
+ grecv_loop()
+ end.
+
call(Pid, M) ->
Pid ! {self(), M}, receive {Pid, Res} -> Res end.
@@ -381,6 +1375,14 @@ guard_receive_loop() ->
t_list_comprehension(Config) when is_list(Config) ->
[#{k:=1},#{k:=2},#{k:=3}] = [#{k=>I} || I <- [1,2,3]],
+ Ls = id([#{<<2:301>> => I, "wat" => I + 1} || I <- [1,2,3]]),
+ [#{<<2:301>>:=1,"wat":=2},#{<<2:301>>:=2,"wat":=3},#{<<2:301>>:=3,"wat":=4}] = Ls,
+ [{1,2},{2,3},{3,4}] = id([{I2,I1} || #{"wat" := I1, <<2:301>> := I2} <- Ls]),
+
+ Ks = lists:seq($a,$z),
+ Ms = [#{[K1,K2]=>{K1,K2}} || K1 <- Ks, K2 <- Ks],
+ [#{"aa" := {$a,$a}},#{"ab":={$a,$b}}|_] = Ms,
+ [#{"zz" := {$z,$z}},#{"zy":={$z,$y}}|_] = lists:reverse(Ms),
ok.
t_guard_fun(Config) when is_list(Config) ->
@@ -426,7 +1428,7 @@ t_map_sort_literals(Config) when is_list(Config) ->
true = #{ c => 1, b => 1, a => 1 } < id(#{ b => 1, c => 1, d => 1}),
true = #{ "a" => 1 } < id(#{ <<"a">> => 1}),
false = #{ <<"a">> => 1 } < id(#{ "a" => 1}),
- false = #{ 1 => 1 } < id(#{ 1.0 => 1}),
+ true = #{ 1 => 1 } < id(#{ 1.0 => 1}),
false = #{ 1.0 => 1 } < id(#{ 1 => 1}),
%% value order
@@ -458,11 +1460,11 @@ t_bif_map_get(Config) when is_list(Config) ->
"v4" = maps:get(<<"k2">>, M#{ <<"k2">> => "v4" }),
%% error case
- {'EXIT',{badarg, [{maps,get,_,_}|_]}} = (catch maps:get(a,[])),
- {'EXIT',{badarg, [{maps,get,_,_}|_]}} = (catch maps:get(a,<<>>)),
- {'EXIT',{bad_key,[{maps,get,_,_}|_]}} = (catch maps:get({1,1}, #{{1,1.0} => "tuple"})),
- {'EXIT',{bad_key,[{maps,get,_,_}|_]}} = (catch maps:get(a,#{})),
- {'EXIT',{bad_key,[{maps,get,_,_}|_]}} = (catch maps:get(a,#{ b=>1, c=>2})),
+ {'EXIT',{{badmap,[]},[{maps,get,_,_}|_]}} = (catch maps:get(a, [])),
+ {'EXIT',{{badmap,<<>>},[{maps,get,_,_}|_]}} = (catch maps:get(a, <<>>)),
+ {'EXIT',{{badkey,{1,1}},[{maps,get,_,_}|_]}} = (catch maps:get({1,1}, #{{1,1.0} => "tuple"})),
+ {'EXIT',{{badkey,a},[{maps,get,_,_}|_]}} = (catch maps:get(a, #{})),
+ {'EXIT',{{badkey,a},[{maps,get,_,_}|_]}} = (catch maps:get(a, #{ b=>1, c=>2})),
ok.
t_bif_map_find(Config) when is_list(Config) ->
@@ -486,8 +1488,10 @@ t_bif_map_find(Config) when is_list(Config) ->
error = maps:find({1.0,1}, #{ a=>a, {1,1.0} => "tuple hi"}), % reverse types in tuple key
- {'EXIT',{badarg,[{maps,find,_,_}|_]}} = (catch maps:find(a,id([]))),
- {'EXIT',{badarg,[{maps,find,_,_}|_]}} = (catch maps:find(a,id(<<>>))),
+ {'EXIT',{{badmap,[]},[{maps,find,_,_}|_]}} =
+ (catch maps:find(a, id([]))),
+ {'EXIT',{{badmap,<<>>},[{maps,find,_,_}|_]}} =
+ (catch maps:find(a, id(<<>>))),
ok.
@@ -512,26 +1516,26 @@ t_bif_map_is_key(Config) when is_list(Config) ->
false = maps:is_key(1.0, maps:put(1, "number", M1)),
%% error case
- {'EXIT',{badarg,[{maps,is_key,_,_}|_]}} = (catch maps:is_key(a,id([]))),
- {'EXIT',{badarg,[{maps,is_key,_,_}|_]}} = (catch maps:is_key(a,id(<<>>))),
+ {'EXIT',{{badmap,[]},[{maps,is_key,_,_}|_]}} = (catch maps:is_key(a, id([]))),
+ {'EXIT',{{badmap,<<>>},[{maps,is_key,_,_}|_]}} = (catch maps:is_key(a, id(<<>>))),
ok.
t_bif_map_keys(Config) when is_list(Config) ->
[] = maps:keys(#{}),
- [1,2,3,4,5] = maps:keys(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e}),
- [1,2,3,4,5] = maps:keys(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c}),
+ [1,2,3,4,5] = lists:sort(maps:keys(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e})),
+ [1,2,3,4,5] = lists:sort(maps:keys(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c})),
- % values in key order: [4,int,"hi",<<"key">>]
M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number},
- [4,int,"hi",<<"key">>] = maps:keys(M1),
+ [4,int,"hi",<<"key">>] = lists:sort(maps:keys(M1)),
%% error case
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(154)),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(atom)),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys([])),
- {'EXIT',{badarg,[{maps,keys,_,_}|_]}} = (catch maps:keys(<<>>)),
+ BigNum = 1 bsl 65 + 3,
+ {'EXIT',{{badmap,BigNum},[{maps,keys,_,_}|_]}} = (catch maps:keys(BigNum)),
+ {'EXIT',{{badmap,154},[{maps,keys,_,_}|_]}} = (catch maps:keys(154)),
+ {'EXIT',{{badmap,atom},[{maps,keys,_,_}|_]}} = (catch maps:keys(atom)),
+ {'EXIT',{{badmap,[]},[{maps,keys,_,_}|_]}} = (catch maps:keys([])),
+ {'EXIT',{{badmap,<<>>},[{maps,keys,_,_}|_]}} = (catch maps:keys(<<>>)),
ok.
t_bif_map_new(Config) when is_list(Config) ->
@@ -560,93 +1564,64 @@ t_bif_map_merge(Config) when is_list(Config) ->
{1,2} := "tuple", "hi" := "hello again", <<"key">> := <<"value">>} = maps:merge(M0,M1),
%% error case
- {'EXIT',{badarg,[{maps,merge,_,_}|_]}} = (catch maps:merge((1 bsl 65 + 3), <<>>)),
- {'EXIT',{badarg,[{maps,merge,_,_}|_]}} = (catch maps:merge(<<>>, id(#{ a => 1}))),
- {'EXIT',{badarg,[{maps,merge,_,_}|_]}} = (catch maps:merge(id(#{ a => 2}), <<>> )),
+ BigNum = 1 bsl 65 + 3,
+ {'EXIT',{{badmap,BigNum},[{maps,merge,_,_}|_]}} = (catch maps:merge(BigNum, <<>>)),
+ {'EXIT',{{badmap,<<>>},[{maps,merge,_,_}|_]}} = (catch maps:merge(<<>>, id(#{ a => 1}))),
+ {'EXIT',{{badmap,<<>>},[{maps,merge,_,_}|_]}} = (catch maps:merge(id(#{ a => 2}), <<>> )),
ok.
-
t_bif_map_put(Config) when is_list(Config) ->
M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
4 => number, 18446744073709551629 => wat},
M1 = #{ "hi" := "hello"} = maps:put("hi", "hello", #{}),
- ["hi"] = maps:keys(M1),
- ["hello"] = maps:values(M1),
+ true = is_members(["hi"],maps:keys(M1)),
+ true = is_members(["hello"],maps:values(M1)),
M2 = #{ int := 3 } = maps:put(int, 3, M1),
- [int,"hi"] = maps:keys(M2),
- [3,"hello"] = maps:values(M2),
+ true = is_members([int,"hi"],maps:keys(M2)),
+ true = is_members([3,"hello"],maps:values(M2)),
M3 = #{ <<"key">> := <<"value">> } = maps:put(<<"key">>, <<"value">>, M2),
- [int,"hi",<<"key">>] = maps:keys(M3),
- [3,"hello",<<"value">>] = maps:values(M3),
+ true = is_members([int,"hi",<<"key">>],maps:keys(M3)),
+ true = is_members([3,"hello",<<"value">>],maps:values(M3)),
M4 = #{ 18446744073709551629 := wat } = maps:put(18446744073709551629, wat, M3),
- [18446744073709551629,int,"hi",<<"key">>] = maps:keys(M4),
- [wat,3,"hello",<<"value">>] = maps:values(M4),
+ true = is_members([18446744073709551629,int,"hi",<<"key">>],maps:keys(M4)),
+ true = is_members([wat,3,"hello",<<"value">>],maps:values(M4)),
M0 = #{ 4 := number } = M5 = maps:put(4, number, M4),
- [4,18446744073709551629,int,"hi",<<"key">>] = maps:keys(M5),
- [number,wat,3,"hello",<<"value">>] = maps:values(M5),
+ true = is_members([4,18446744073709551629,int,"hi",<<"key">>],maps:keys(M5)),
+ true = is_members([number,wat,3,"hello",<<"value">>],maps:values(M5)),
M6 = #{ <<"key">> := <<"other value">> } = maps:put(<<"key">>, <<"other value">>, M5),
- [4,18446744073709551629,int,"hi",<<"key">>] = maps:keys(M6),
- [number,wat,3,"hello",<<"other value">>] = maps:values(M6),
+ true = is_members([4,18446744073709551629,int,"hi",<<"key">>],maps:keys(M6)),
+ true = is_members([number,wat,3,"hello",<<"other value">>],maps:values(M6)),
%% error case
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,154)),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,atom)),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,[])),
- {'EXIT',{badarg,[{maps,put,_,_}|_]}} = (catch maps:put(1,a,<<>>)),
- ok.
-
-t_bif_map_remove(Config) when is_list(Config) ->
- 0 = erlang:map_size(maps:remove(some_key, #{})),
-
- M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
- 4 => number, 18446744073709551629 => wat},
-
- M1 = maps:remove("hi", M0),
- [4,18446744073709551629,int,<<"key">>] = maps:keys(M1),
- [number,wat,3,<<"value">>] = maps:values(M1),
-
- M2 = maps:remove(int, M1),
- [4,18446744073709551629,<<"key">>] = maps:keys(M2),
- [number,wat,<<"value">>] = maps:values(M2),
-
- M3 = maps:remove(<<"key">>, M2),
- [4,18446744073709551629] = maps:keys(M3),
- [number,wat] = maps:values(M3),
-
- M4 = maps:remove(18446744073709551629, M3),
- [4] = maps:keys(M4),
- [number] = maps:values(M4),
-
- M5 = maps:remove(4, M4),
- [] = maps:keys(M5),
- [] = maps:values(M5),
+ BigNum = 1 bsl 65 + 3,
+ {'EXIT',{{badmap,BigNum},[{maps,put,_,_}|_]}} = (catch maps:put(1, a, BigNum)),
+ {'EXIT',{{badmap,154},[{maps,put,_,_}|_]}} = (catch maps:put(1, a, 154)),
+ {'EXIT',{{badmap,atom},[{maps,put,_,_}|_]}} = (catch maps:put(1, a, atom)),
+ {'EXIT',{{badmap,[]},[{maps,put,_,_}|_]}} = (catch maps:put(1, a, [])),
+ {'EXIT',{{badmap,<<>>},[{maps,put,_,_}|_]}} = (catch maps:put(1, a, <<>>)),
+ ok.
- M0 = maps:remove(5,M0),
- M0 = maps:remove("hi there",M0),
+is_members(Ks,Ls) when length(Ks) =/= length(Ls) -> false;
+is_members(Ks,Ls) -> is_members_do(Ks,Ls).
- #{ "hi" := "hello", int := 3, 4 := number} = maps:remove(18446744073709551629,maps:remove(<<"key">>,M0)),
+is_members_do([],[]) -> true;
+is_members_do([],_) -> false;
+is_members_do([K|Ks],Ls) ->
+ is_members_do(Ks, lists:delete(K,Ls)).
- %% error case
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(a,1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(1,154)),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(a,atom)),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(1,[])),
- {'EXIT',{badarg,[{maps,remove,_,_}|_]}} = (catch maps:remove(a,<<>>)),
- ok.
t_bif_map_update(Config) when is_list(Config) ->
M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
@@ -668,103 +1643,142 @@ t_bif_map_update(Config) when is_list(Config) ->
4 := number, 18446744073709551629 := wazzup} = maps:update(18446744073709551629, wazzup, M0),
%% error case
- {'EXIT',{badarg,[{maps,update,_,_}|_]}} = (catch maps:update(1,none,{})),
- {'EXIT',{badarg,[{maps,update,_,_}|_]}} = (catch maps:update(1,none,<<"value">>)),
- {'EXIT',{badarg,[{maps,update,_,_}|_]}} = (catch maps:update(5,none,M0)),
+ {'EXIT',{{badmap,{}},[{maps,update,_,_}|_]}} = (catch maps:update(1, none, {})),
+ {'EXIT',{{badmap,<<"value">>},[{maps,update,_,_}|_]}} =
+ (catch maps:update(1, none, <<"value">>)),
+ {'EXIT',{{badkey,5},[{maps,update,_,_}|_]}} = (catch maps:update(5, none, M0)),
ok.
+t_bif_map_remove(Config) when is_list(Config) ->
+ 0 = erlang:map_size(maps:remove(some_key, #{})),
+
+ M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>,
+ 4 => number, 18446744073709551629 => wat},
+
+ M1 = maps:remove("hi", M0),
+ true = is_members([4,18446744073709551629,int,<<"key">>],maps:keys(M1)),
+ true = is_members([number,wat,3,<<"value">>],maps:values(M1)),
+
+ M2 = maps:remove(int, M1),
+ true = is_members([4,18446744073709551629,<<"key">>],maps:keys(M2)),
+ true = is_members([number,wat,<<"value">>],maps:values(M2)),
+
+ M3 = maps:remove(<<"key">>, M2),
+ true = is_members([4,18446744073709551629],maps:keys(M3)),
+ true = is_members([number,wat],maps:values(M3)),
+
+ M4 = maps:remove(18446744073709551629, M3),
+ true = is_members([4],maps:keys(M4)),
+ true = is_members([number],maps:values(M4)),
+ M5 = maps:remove(4, M4),
+ [] = maps:keys(M5),
+ [] = maps:values(M5),
+
+ M0 = maps:remove(5,M0),
+ M0 = maps:remove("hi there",M0),
+
+ #{ "hi" := "hello", int := 3, 4 := number} = maps:remove(18446744073709551629,maps:remove(<<"key">>,M0)),
+
+ %% error case
+ BigNum = 1 bsl 65 + 3,
+ {'EXIT',{{badmap,BigNum},[{maps,remove,_,_}|_]}} = (catch maps:remove(a, BigNum)),
+ {'EXIT',{{badmap,154},[{maps,remove,_,_}|_]}} = (catch maps:remove(1, 154)),
+ {'EXIT',{{badmap,atom},[{maps,remove,_,_}|_]}} = (catch maps:remove(a, atom)),
+ {'EXIT',{{badmap,[]},[{maps,remove,_,_}|_]}} = (catch maps:remove(1, [])),
+ {'EXIT',{{badmap,<<>>},[{maps,remove,_,_}|_]}} = (catch maps:remove(a, <<>>)),
+ ok.
t_bif_map_values(Config) when is_list(Config) ->
[] = maps:values(#{}),
+ [1] = maps:values(#{a=>1}),
- [a,b,c,d,e] = maps:values(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e}),
- [a,b,c,d,e] = maps:values(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c}),
+ true = is_members([a,b,c,d,e],maps:values(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e})),
+ true = is_members([a,b,c,d,e],maps:values(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c})),
- % values in key order: [4,int,"hi",<<"key">>]
M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number},
M2 = M1#{ "hi" => "hello2", <<"key">> => <<"value2">> },
- [number,3,"hello2",<<"value2">>] = maps:values(M2),
- [number,3,"hello",<<"value">>] = maps:values(M1),
+ true = is_members([number,3,"hello2",<<"value2">>],maps:values(M2)),
+ true = is_members([number,3,"hello",<<"value">>],maps:values(M1)),
%% error case
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values(1 bsl 65 + 3)),
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values(atom)),
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values([])),
- {'EXIT',{badarg,[{maps,values,_,_}|_]}} = (catch maps:values(<<>>)),
+ BigNum = 1 bsl 65 + 3,
+ {'EXIT',{{badmap,BigNum},[{maps,values,_,_}|_]}} = (catch maps:values(BigNum)),
+ {'EXIT',{{badmap,atom},[{maps,values,_,_}|_]}} = (catch maps:values(atom)),
+ {'EXIT',{{badmap,[]},[{maps,values,_,_}|_]}} = (catch maps:values([])),
+ {'EXIT',{{badmap,<<>>},[{maps,values,_,_}|_]}} = (catch maps:values(<<>>)),
ok.
+
+
t_erlang_hash(Config) when is_list(Config) ->
ok = t_bif_erlang_phash2(),
ok = t_bif_erlang_phash(),
ok = t_bif_erlang_hash(),
-
ok.
t_bif_erlang_phash2() ->
-
39679005 = erlang:phash2(#{}),
- 78942764 = erlang:phash2(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 }),
- 37338230 = erlang:phash2(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} }),
- 14363616 = erlang:phash2(#{ 1 => a }),
- 51612236 = erlang:phash2(#{ a => 1 }),
+ 33667975 = erlang:phash2(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 }), % 78942764
+ 95332690 = erlang:phash2(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} }), % 37338230
+ 108954384 = erlang:phash2(#{ 1 => a }), % 14363616
+ 59617982 = erlang:phash2(#{ a => 1 }), % 51612236
- 37468437 = erlang:phash2(#{{} => <<>>}),
- 44049159 = erlang:phash2(#{<<>> => {}}),
+ 42770201 = erlang:phash2(#{{} => <<>>}), % 37468437
+ 71687700 = erlang:phash2(#{<<>> => {}}), % 44049159
M0 = #{ a => 1, "key" => <<"value">> },
M1 = maps:remove("key",M0),
M2 = M1#{ "key" => <<"value">> },
- 118679416 = erlang:phash2(M0),
- 51612236 = erlang:phash2(M1),
- 118679416 = erlang:phash2(M2),
+ 70249457 = erlang:phash2(M0), % 118679416
+ 59617982 = erlang:phash2(M1), % 51612236
+ 70249457 = erlang:phash2(M2), % 118679416
ok.
t_bif_erlang_phash() ->
Sz = 1 bsl 32,
- 268440612 = erlang:phash(#{},Sz),
- 1196461908 = erlang:phash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz),
- 3944426064 = erlang:phash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz),
- 1394238263 = erlang:phash(#{ 1 => a },Sz),
- 4066388227 = erlang:phash(#{ a => 1 },Sz),
+ 1113425985 = erlang:phash(#{},Sz), % 268440612
+ 1510068139 = erlang:phash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 1196461908
+ 3182345590 = erlang:phash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 3944426064
+ 2927531828 = erlang:phash(#{ 1 => a },Sz), % 1394238263
+ 1670235874 = erlang:phash(#{ a => 1 },Sz), % 4066388227
- 1578050717 = erlang:phash(#{{} => <<>>},Sz),
- 1578050717 = erlang:phash(#{<<>> => {}},Sz), % yep, broken
+ 3935089469 = erlang:phash(#{{} => <<>>},Sz), % 1578050717
+ 71692856 = erlang:phash(#{<<>> => {}},Sz), % 1578050717
M0 = #{ a => 1, "key" => <<"value">> },
M1 = maps:remove("key",M0),
M2 = M1#{ "key" => <<"value">> },
- 3590546636 = erlang:phash(M0,Sz),
- 4066388227 = erlang:phash(M1,Sz),
- 3590546636 = erlang:phash(M2,Sz),
+ 2620391445 = erlang:phash(M0,Sz), % 3590546636
+ 1670235874 = erlang:phash(M1,Sz), % 4066388227
+ 2620391445 = erlang:phash(M2,Sz), % 3590546636
ok.
t_bif_erlang_hash() ->
Sz = 1 bsl 27 - 1,
- 5158 = erlang:hash(#{},Sz),
- 71555838 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz),
- 5497225 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz),
- 126071654 = erlang:hash(#{ 1 => a },Sz),
- 126426236 = erlang:hash(#{ a => 1 },Sz),
+ 39684169 = erlang:hash(#{},Sz), % 5158
+ 33673142 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 71555838
+ 95337869 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 5497225
+ 108959561 = erlang:hash(#{ 1 => a },Sz), % 126071654
+ 59623150 = erlang:hash(#{ a => 1 },Sz), % 126426236
- 101655720 = erlang:hash(#{{} => <<>>},Sz),
- 101655720 = erlang:hash(#{<<>> => {}},Sz), % yep, broken
+ 42775386 = erlang:hash(#{{} => <<>>},Sz), % 101655720
+ 71692856 = erlang:hash(#{<<>> => {}},Sz), % 101655720
M0 = #{ a => 1, "key" => <<"value">> },
M1 = maps:remove("key",M0),
M2 = M1#{ "key" => <<"value">> },
- 38260486 = erlang:hash(M0,Sz),
- 126426236 = erlang:hash(M1,Sz),
- 38260486 = erlang:hash(M2,Sz),
+ 70254632 = erlang:hash(M0,Sz), % 38260486
+ 59623150 = erlang:hash(M1,Sz), % 126426236
+ 70254632 = erlang:hash(M2,Sz), % 38260486
ok.
-
t_map_encode_decode(Config) when is_list(Config) ->
<<131,116,0,0,0,0>> = erlang:term_to_binary(#{}),
Pairs = [
@@ -827,43 +1841,46 @@ t_map_encode_decode(Config) when is_list(Config) ->
map_encode_decode_and_match([{K,V}|Pairs], EncodedPairs, M0) ->
M1 = maps:put(K,V,M0),
B0 = erlang:term_to_binary(M1),
- Ls = lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) < 0 end, [{K, erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs]),
- %% sort Ks and Vs according to term spec, then match it
- KVbins = lists:foldr(fun({_,Kbin,Vbin}, Acc) -> [Kbin,Vbin | Acc] end, [], Ls),
- ok = match_encoded_map(B0, length(Ls), KVbins),
+ Ls = [{erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs],
+ ok = match_encoded_map(B0, length(Ls), Ls),
%% decode and match it
M1 = erlang:binary_to_term(B0),
map_encode_decode_and_match(Pairs,Ls,M1);
map_encode_decode_and_match([],_,_) -> ok.
match_encoded_map(<<131,116,Size:32,Encoded/binary>>,Size,Items) ->
- match_encoded_map(Encoded,Items);
+ match_encoded_map_stripped_size(Encoded,Items,Items);
match_encoded_map(_,_,_) -> no_match_size.
-match_encoded_map(<<>>,[]) -> ok;
-match_encoded_map(Bin,[<<131,Item/binary>>|Items]) ->
- Size = erlang:byte_size(Item),
- <<EncodedTerm:Size/binary, Bin1/binary>> = Bin,
- EncodedTerm = Item, %% Asssert
- match_encoded_map(Bin1,Items).
+match_encoded_map_stripped_size(<<>>,_,_) -> ok;
+match_encoded_map_stripped_size(B0,[{<<131,K/binary>>,<<131,V/binary>>}|Items],Ls) ->
+ Ksz = byte_size(K),
+ Vsz = byte_size(V),
+ case B0 of
+ <<K:Ksz/binary,V:Vsz/binary,B1/binary>> ->
+ match_encoded_map_stripped_size(B1,Ls,Ls);
+ _ ->
+ match_encoded_map_stripped_size(B0,Items,Ls)
+ end;
+match_encoded_map_stripped_size(_,[],_) -> fail.
t_bif_map_to_list(Config) when is_list(Config) ->
[] = maps:to_list(#{}),
- [{a,1},{b,2}] = maps:to_list(#{a=>1,b=>2}),
- [{a,1},{b,2},{c,3}] = maps:to_list(#{c=>3,a=>1,b=>2}),
- [{a,1},{b,2},{g,3}] = maps:to_list(#{g=>3,a=>1,b=>2}),
- [{a,1},{b,2},{g,3},{"c",4}] = maps:to_list(#{g=>3,a=>1,b=>2,"c"=>4}),
- [{3,v2},{hi,v4},{{hi,3},v5},{"hi",v3},{<<"hi">>,v1}] = maps:to_list(#{
- <<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5}),
+ [{a,1},{b,2}] = lists:sort(maps:to_list(#{a=>1,b=>2})),
+ [{a,1},{b,2},{c,3}] = lists:sort(maps:to_list(#{c=>3,a=>1,b=>2})),
+ [{a,1},{b,2},{g,3}] = lists:sort(maps:to_list(#{g=>3,a=>1,b=>2})),
+ [{a,1},{b,2},{g,3},{"c",4}] = lists:sort(maps:to_list(#{g=>3,a=>1,b=>2,"c"=>4})),
+ [{3,v2},{hi,v4},{{hi,3},v5},{"hi",v3},{<<"hi">>,v1}] =
+ lists:sort(maps:to_list(#{<<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5})),
- [{3,v7},{hi,v9},{{hi,3},v10},{"hi",v8},{<<"hi">>,v6}] = maps:to_list(#{
- <<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5,
- <<"hi">>=>v6,3=>v7,"hi"=>v8,hi=>v9,{hi,3}=>v10}),
+ [{3,v7},{hi,v9},{{hi,3},v10},{"hi",v8},{<<"hi">>,v6}] =
+ lists:sort(maps:to_list(#{<<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5,
+ <<"hi">>=>v6,3=>v7,"hi"=>v8,hi=>v9,{hi,3}=>v10})),
%% error cases
- {'EXIT', {badarg,_}} = (catch maps:to_list(id(a))),
- {'EXIT', {badarg,_}} = (catch maps:to_list(id(42))),
+ {'EXIT', {{badmap,a},_}} = (catch maps:to_list(id(a))),
+ {'EXIT', {{badmap,42},_}} = (catch maps:to_list(id(42))),
ok.
@@ -988,16 +2005,390 @@ t_ets(_Config) ->
ets:delete(Tid),
ok.
-t_dets(_Config) ->
+t_build_and_match_aliasing(Config) when is_list(Config) ->
+ M1 = id(#{a=>1,b=>2,c=>3,d=>4}),
+ #{c:=C1=_=_=C2} = M1,
+ true = C1 =:= C2,
+ #{a:=A,a:=A,a:=A,b:=B,b:=B} = M1,
+ #{a:=A,a:=A,a:=A,b:=B,b:=B,b:=2} = M1,
+ #{a:=A=1,a:=A,a:=A,b:=B=2,b:=B,b:=2} = M1,
+ #{c:=C1, c:=_, c:=3, c:=_, c:=C2} = M1,
+ #{c:=C=_=3=_=C} = M1,
+
+ M2 = id(#{"a"=>1,"b"=>2,"c"=>3,"d"=>4}),
+ #{"a":=A2,"a":=A2,"a":=A2,"b":=B2,"b":=B2,"b":=2} = M2,
+ #{"a":=_,"a":=_,"a":=_,"b":=_,"b":=_,"b":=2} = M2,
+ ok.
+
+%% simple build and match variables
+t_build_and_match_variables(Config) when is_list(Config) ->
+ K0 = id(#{}),
+ K1 = id(1), V1 = id(a),
+ K2 = id(2), V2 = id(b),
+ K3 = id(3), V3 = id("c"),
+ K4 = id("4"), V4 = id("d"),
+ K5 = id(<<"5">>), V5 = id(<<"e">>),
+ K6 = id({"6",7}), V6 = id("f"),
+ K7 = id(#{ "a" => 3 }),
+ #{K1:=V1} = id(#{K1=>V1}),
+ #{K1:=V1,K2:=V2} = id(#{K1=>V1,K2=>V2}),
+ #{K1:=V1,K2:=V2,K3:=V3} = id(#{K1=>V1,K2=>V2,K3=>V3}),
+ #{K1:=V1,K2:=V2,K3:=V3,K4:=V4} = id(#{K1=>V1,K2=>V2,K3=>V3,K4=>V4}),
+ #{K1:=V1,K2:=V2,K3:=V3,K4:=V4,K5:=V5} = id(#{K1=>V1,K2=>V2,K3=>V3,K4=>V4,K5=>V5}),
+ #{K1:=V1,K2:=V2,K3:=V3,K4:=V4,K5:=V5,K6:=V6} = id(#{K1=>V1,K2=>V2,K3=>V3,K4=>V4,K5=>V5,K6=>V6}),
+
+ #{K5:=X,K5:=X=3,K4:=4} = id(#{K5=>3,K4=>4}),
+ #{K5:=X,<<"5">>:=X=3,K4:=4} = id(#{K5=>3,K4=>4}),
+ #{K5:=X,<<"5">>:=X=3,K4:=4} = id(#{<<"5">>=>3,K4=>4}),
+
+ #{ K4:=#{ K3:=#{K1:=V1, K2:=V2}}, K5:=V5} =
+ id(#{ K5=>V5, K4=>#{ K3=>#{K2 => V2, K1 => V1}}}),
+ #{ K4 := #{ K5 := Res }, K6 := Res} = id(#{K4=>#{K5 => 99}, K6 => 99}),
+
+ %% has keys
+ #{a :=_,b :=_,K1:=_,K2:=_,K3:=V3,K4:=ResKey,K4:=ResKey,"4":=ResKey,"4":="ok"} =
+ id(#{ a=>1, b=>1, K1=>V1, K2=>V2, K3=>V3, K4=>"nope", "4"=>"ok" }),
+
+ %% function
+ ok = match_function_map_neg_keys(#{ -1 => a, -2 => b, -3 => c }),
+
+ %% map key
+ #{ K0 := 42 } = id(#{ K0 => 42 }),
+ #{ K7 := 42 } = id(#{ K7 => 42 }),
+
+ %% nil key
+ KNIL = id([]),
+ #{KNIL:=ok,1:=2} = id(#{KNIL=>ok,1=>2}),
+
+ Bin = <<0:258>>,
+ #{ Bin := "three" } = id(#{<<0:258>> =>"three"}),
+
+ %% error case
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3,x:=2} = id(#{K5=>3}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=2} = id(#{K5=>3}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3} = id({a,b,c}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3} = id(#{K6=>3}))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K5:=3} = id(K7))),
+ {'EXIT',{{badmatch,_},_}} = (catch (#{K7:=3} = id(#{K7=>42}))),
+ ok.
+
+
+match_function_map_neg_keys(#{ -1 := a, -2 := b, -3 := c }) -> ok.
+
+t_update_assoc_variables(Config) when is_list(Config) ->
+ K1 = id(1),
+ K2 = id(2),
+ K3 = id(3.0),
+ K4 = id(4),
+ K5 = id(5),
+ K6 = id(2.0),
+
+ M0 = #{K1=>a,K2=>b,K3=>c,K4=>d,K5=>e},
+
+ M1 = M0#{K1=>42,K2=>100,K4=>[a,b,c]},
+ #{1:=42,2:=100,3.0:=c,4:=[a,b,c],5:=e} = M1,
+ #{1:=42,2:=b,4:=d,5:=e,2.0:=100,K3:=c,4.0:=[a,b,c]} = M0#{1.0=>float,1:=42,2.0=>wrong,K6=>100,4.0=>[a,b,c]},
+
+ M2 = M0#{K3=>new},
+ #{1:=a,2:=b,K3:=new,4:=d,5:=e} = M2,
+ M2 = M0#{3.0:=wrong,K3=>new},
+
+ #{ <<0:258>> := val } = id(M0#{<<0:258>> => val}), %% binary limitation
+
+ %% Errors cases.
+ BadMap = id(a_bad_map),
+ {'EXIT',{{badmap,BadMap},_}} = (catch BadMap#{nonexisting=>val}),
+ {'EXIT',{{badmap,<<>>},_}} = (catch <<>>#{nonexisting=>val}),
+ ok.
+
+t_update_exact_variables(Config) when is_list(Config) ->
+ K1 = id(1),
+ K2 = id(2),
+ K3 = id(3.0),
+ K4 = id(4),
+
+ M0 = id(#{1=>a,2=>b,3.0=>c,4=>d,5=>e}),
+
+ M1 = M0#{K1:=42,K2:=100,K4:=[a,b,c]},
+ #{1:=42,2:=100,3.0:=c,K4:=[a,b,c],5:=e} = M1,
+ M1 = M0#{K1:=wrong,1:=also_wrong,K1=>42,2=>wrong,K2:=100,4:=[a,b,c]},
+
+ M2 = M0#{K3:=new},
+ #{1:=a,K2:=b,3.0:=new,K4:=d,5:=e} = M2,
+ M2 = M0#{3.0=>wrong,K3:=new},
+ true = M2 =/= M0#{3=>right,3.0:=new},
+ #{ 3 := right, 3.0 := new } = M0#{3=>right,K3:=new},
+
+ M3 = id(#{ 1 => val}),
+ #{1 := update2,1.0 := new_val4} = M3#{
+ 1.0 => new_val1, K1 := update, K1=> update3,
+ K1 := update2, 1.0 := new_val2, 1.0 => new_val3,
+ 1.0 => new_val4 },
+
+ %% Errors cases.
+ {'EXIT',{{badmap,_},_}} = (catch ((id(nil))#{ a := b })),
+ {'EXIT',{{badmap,_},_}} = (catch <<>>#{nonexisting:=val}),
+
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{<<0:257>> := val}), %% limitation
+ ok.
+
+t_nested_pattern_expressions(Config) when is_list(Config) ->
+ K1 = id("hello"),
+ %K2 = id({ok}),
+ [_,_,#{ <<"hi">> := wat, K1 := 42 }|_] = id([k,k,#{<<"hi">> => wat, K1 => 42}]),
+ [_,_,#{ -1 := wat, K1 := 42 }|_] = id([k,k,#{-1 => wat, K1 => 42}]),
+ [_,_,{#{ -1 := #{ {-3,<<0:300>>} := V1 }, K1 := 42 },3}|_] = id([k,k,{#{-1 => #{{-3,<<0:300>>}=>"hi"}, K1 => 42},3}]),
+ "hi" = V1,
+ %[k,#{ {-1,K1,[]} := {wat,K1}, K2 := 42 }|_] = id([k,#{{-1,K1,[]} => {wat,K1}, K2 => 42}]),
+ %[k,#{ [-1,K2,[]] := {wat,K1}, K1 := 42 }|_] = id([k,#{[-1,K2,[]] => {wat,K1}, K1 => 42}]),
+ ok.
+
+t_guard_update_variables(Config) when is_list(Config) ->
+ error = map_guard_update_variables(n,#{},#{}),
+ first = map_guard_update_variables(x,#{}, #{x=>first}),
+ second = map_guard_update_variables(x,#{y=>old}, #{x=>second,y=>old}),
+ third = map_guard_update_variables(x,#{x=>old,y=>old}, #{x=>third,y=>old}),
+ fourth = map_guard_update_variables(x,#{x=>old,y=>old}, #{x=>4,y=>new}),
+ ok.
+
+map_guard_update_variables(K,M1,M2) when M1#{K=>first} =:= M2 -> first;
+map_guard_update_variables(K,M1,M2) when M1#{K=>second} =:= M2 -> second;
+map_guard_update_variables(K,M1,M2) when M1#{K:=third} =:= M2 -> third;
+map_guard_update_variables(K,M1,M2) when M1#{K:=4,y=>new} =:= M2 -> fourth;
+map_guard_update_variables(_,_,_) -> error.
+
+t_guard_sequence_variables(Config) when is_list(Config) ->
+ {1,"a"} = map_guard_sequence_var_1(a,#{seq=>1,a=>id("a"),b=>no}),
+ {2,"b"} = map_guard_sequence_var_1(b,#{seq=>2,b=>id("b"),a=>no}),
+ {3,"c"} = map_guard_sequence_var_1(a,#{seq=>3,a=>id("c"),b=>no}),
+ {4,"d"} = map_guard_sequence_var_1(b,#{seq=>4,b=>id("d"),a=>no}),
+ {4,4} = map_guard_sequence_var_1(seq,#{seq=>4}),
+ {4,4,y} = map_guard_sequence_var_1(seq,#{seq=>4,b=>id("d"),a=>y}),
+ {5,"d"} = map_guard_sequence_var_1(b,#{seq=>5,b=>id("d"),a=>y}),
+
+ %% error case
+ {'EXIT',{{case_clause,_},_}} = (catch map_guard_sequence_var_1("a",#{seq=>4,val=>id("e")})),
+ ok.
+
+
+map_guard_sequence_var_1(K,M) ->
+ case M of
+ #{seq:=1=Seq, K:=Val} -> {Seq,Val};
+ #{seq:=2=Seq, K:=Val} -> {Seq,Val};
+ #{seq:=3=Seq, K:=Val} -> {Seq,Val};
+ #{K:=4=Seq, K:=Val1,a:=Val2} -> {Seq,Val1,Val2};
+ #{seq:=4=Seq, K:=Val} -> {Seq,Val};
+ #{K:=4=Seq, K:=Val} -> {Seq,Val};
+ #{seq:=5=Seq, K:=Val} -> {Seq,Val}
+ end.
+
+
+t_guard_sequence_mixed(Config) when is_list(Config) ->
+ M0 = id(#{ a=>1, b=>1, c=>1, d=>1, e=>1, f=>1, g=>1, h=>1 }),
+ M1 = id(M0#{ d := 3 }),
+ 1 = map_guard_sequence_mixed(a,d,M1),
+ M2 = id(M1#{ b := 2, d := 4, h := 2 }),
+ 2 = map_guard_sequence_mixed(a,d,M2),
+ M3 = id(M2#{ b := 3, e := 5, g := 3 }),
+ 3 = map_guard_sequence_mixed(a,e,M3),
+ M4 = id(M3#{ c := 4, e := 6, h := 1 }),
+ 4 = map_guard_sequence_mixed(a,e,M4),
+ M5 = id(M4#{ c := 5, f := 7, g := 2 }),
+ 5 = map_guard_sequence_mixed(a,f,M5),
+ M6 = id(M5#{ c := 6, f := 8, h := 3 }),
+ 6 = map_guard_sequence_mixed(a,f,M6),
+
+ %% error case
+ {'EXIT',{{case_clause,_},_}} = (catch map_guard_sequence_mixed(a,b,M0)),
+ ok.
+
+map_guard_sequence_mixed(K1,K2,M) ->
+ case M of
+ #{ K1 := 1, b := 1, K2 := 3, g := 1} -> 1;
+ #{ K1 := 1, b := 2, K2 := 4, h := 2} -> 2;
+ #{ K1 := 1, b := 3, K2 := 5, g := 3} -> 3;
+ #{ K1 := 1, c := 4, K2 := 6, h := 1} -> 4;
+ #{ K1 := 1, c := 5, K2 := 7, g := 2} -> 5;
+ #{ K1 := 1, c := 6, K2 := 8, h := 3} -> 6
+ end.
+
+
+
+t_frequency_table(Config) when is_list(Config) ->
+ random:seed({13,1337,54}), % pseudo random
+ N = 1000,
+ Ts = rand_terms(N),
+ #{ n:=N, tf := Tf } = frequency_table(Ts,#{ n=>0, tf => #{}}),
+ ok = check_frequency(Ts,Tf),
+ ok.
+
+
+frequency_table([T|Ts], M) ->
+ case M of
+ #{ n := N, tf := #{ T := C } = F } ->
+ frequency_table(Ts,M#{ n := N + 1, tf := F#{ T := C + 1 }});
+ #{ n := N, tf := F } ->
+ frequency_table(Ts,M#{ n := N + 1, tf := F#{ T => 1 }})
+ end;
+frequency_table([], M) -> M.
+
+
+check_frequency(Ts,Tf) ->
+ check_frequency(Ts,Tf,dict:new()).
+
+check_frequency([T|Ts],Tf,D) ->
+ case dict:find(T,D) of
+ error -> check_frequency(Ts,Tf,dict:store(T,1,D));
+ {ok,C} -> check_frequency(Ts,Tf,dict:store(T,C+1,D))
+ end;
+check_frequency([],Tf,D) ->
+ validate_frequency(dict:to_list(D),Tf).
+
+validate_frequency([{T,C}|Fs],Tf) ->
+ case Tf of
+ #{ T := C } -> validate_frequency(Fs,Tf);
+ _ -> error
+ end;
+validate_frequency([], _) -> ok.
+
+
+%% aux
+
+rand_terms(0) -> [];
+rand_terms(N) -> [rand_term()|rand_terms(N-1)].
+
+rand_term() ->
+ case random:uniform(6) of
+ 1 -> rand_binary();
+ 2 -> rand_number();
+ 3 -> rand_atom();
+ 4 -> rand_tuple();
+ 5 -> rand_list();
+ 6 -> rand_map()
+ end.
+
+rand_binary() ->
+ case random:uniform(3) of
+ 1 -> <<>>;
+ 2 -> <<"hi">>;
+ 3 -> <<"message text larger than 64 bytes. yep, message text larger than 64 bytes.">>
+ end.
+
+rand_number() ->
+ case random:uniform(3) of
+ 1 -> random:uniform(5);
+ 2 -> float(random:uniform(5));
+ 3 -> 1 bsl (63 + random:uniform(3))
+ end.
+
+rand_atom() ->
+ case random:uniform(3) of
+ 1 -> hi;
+ 2 -> some_atom;
+ 3 -> some_other_atom
+ end.
+
+
+rand_tuple() ->
+ case random:uniform(3) of
+ 1 -> {ok, rand_term()}; % careful
+ 2 -> {1, 2, 3};
+ 3 -> {<<"yep">>, 1337}
+ end.
+
+rand_list() ->
+ case random:uniform(3) of
+ 1 -> "hi";
+ 2 -> [1,rand_term()]; % careful
+ 3 -> [improper|list]
+ end.
+
+rand_map() ->
+ case random:uniform(3) of
+ 1 -> #{ hi => 3 };
+ 2 -> #{ wat => rand_term(), other => 3 }; % careful
+ 3 -> #{ hi => 42, other => 42, yet_anoter => 1337 }
+ end.
+
+
+t_build_and_match_over_alloc(Config) when is_list(Config) ->
+ Ls = id([1,2,3]),
+ V0 = [a|Ls],
+ M0 = id(#{ "a" => V0 }),
+ #{ "a" := V1 } = M0,
+ V2 = id([c|Ls]),
+ M2 = id(#{ "a" => V2 }),
+ #{ "a" := V3 } = M2,
+ {[a,1,2,3],[c,1,2,3]} = id({V1,V3}),
+ ok.
+
+t_build_and_match_empty_val(Config) when is_list(Config) ->
+ F = fun(#{ "hi":=_,{1,2}:=_,1337:=_}) -> ok end,
+ ok = F(id(#{"hi"=>ok,{1,2}=>ok,1337=>ok})),
+
+ %% error case
+ case (catch (F(id(#{"hi"=>ok})))) of
+ {'EXIT',{function_clause,_}} -> ok;
+ {'EXIT', {{case_clause,_},_}} -> {comment,inlined};
+ Other ->
+ test_server:fail({no_match, Other})
+ end.
+
+t_build_and_match_val(Config) when is_list(Config) ->
+ F = fun
+ (#{ "hi" := first, v := V}) -> {1,V};
+ (#{ "hi" := second, v := V}) -> {2,V}
+ end,
+
+
+ {1,"hello"} = F(id(#{"hi"=>first,v=>"hello"})),
+ {2,"second"} = F(id(#{"hi"=>second,v=>"second"})),
+
+ %% error case
+ case (catch (F(id(#{"hi"=>ok})))) of
+ {'EXIT',{function_clause,_}} -> ok;
+ {'EXIT', {{case_clause,_},_}} -> {comment,inlined};
+ Other ->
+ test_server:fail({no_match, Other})
+ end.
+
+t_build_and_match_nil(Config) when is_list(Config) ->
+ %% literals removed the coverage
+ V1 = id(cookie),
+ V2 = id(cake),
+ V3 = id(crisps),
+
+ #{ [] := V1, "treat" := V2, {your,treat} := V3 } = id(#{
+ {your,treat} => V3,
+ "treat" => V2,
+ [] => V1 }),
+ #{ [] := V3, [] := V3 } = id(#{ [] => V1, [] => V3 }),
+ ok.
+
+t_build_and_match_structure(Config) when is_list(Config) ->
+ V2 = id("it"),
+ S = id([42,{"hi", "=)", #{ "a" => 42, any => any, val => "get_" ++ V2}}]),
+
+ %% match deep map values
+ V2 = case S of
+ [42,{"hi",_, #{ "a" := 42, val := "get_" ++ V1, any := _ }}] -> V1
+ end,
+ %% match deep map
+ ok = case S of
+ [42,{"hi",_, #{ }}] -> ok
+ end,
ok.
-getmsg(_Tracer) ->
- receive V -> V after 100 -> timeout end.
-trace_collector(Msg,Parent) ->
- io:format("~p~n",[Msg]),
- Parent ! Msg,
- Parent.
+do_badmap(Test) ->
+ Terms = [Test,fun erlang:abs/1,make_ref(),self(),0.0/id(-1),
+ <<1:1>>,<<>>,<<1,2,3>>,
+ [],{a,b,c},[a,b],atom,10.0,42,(1 bsl 65) + 3],
+ [Test(T) || T <- Terms].
%% Use this function to avoid compile-time evaluation of an expression.
id(I) -> I.
diff --git a/lib/debugger/test/record_SUITE.erl b/lib/debugger/test/record_SUITE.erl
index 873bbdb4bc..2f663e2dfc 100644
--- a/lib/debugger/test/record_SUITE.erl
+++ b/lib/debugger/test/record_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/test_lib.erl b/lib/debugger/test/test_lib.erl
index 29b26343e8..2d3e772fc8 100644
--- a/lib/debugger/test/test_lib.erl
+++ b/lib/debugger/test/test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/test/trycatch_SUITE.erl b/lib/debugger/test/trycatch_SUITE.erl
index 470d46d915..7fdd98fc71 100644
--- a/lib/debugger/test/trycatch_SUITE.erl
+++ b/lib/debugger/test/trycatch_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index b82f0f4e37..cf8ffd3272 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 4.0.3
+DEBUGGER_VSN = 4.1.2
diff --git a/lib/dialyzer/Makefile b/lib/dialyzer/Makefile
index 287867d7be..0e59376240 100644
--- a/lib/dialyzer/Makefile
+++ b/lib/dialyzer/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/dialyzer/doc/src/Makefile b/lib/dialyzer/doc/src/Makefile
index a827281cc5..77d0a6fc68 100644
--- a/lib/dialyzer/doc/src/Makefile
+++ b/lib/dialyzer/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/doc/src/book.xml b/lib/dialyzer/doc/src/book.xml
index 61b873fb5b..4cc2a9db7c 100644
--- a/lib/dialyzer/doc/src/book.xml
+++ b/lib/dialyzer/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml
index e482b1e6f8..3fd34241b2 100644
--- a/lib/dialyzer/doc/src/dialyzer.xml
+++ b/lib/dialyzer/doc/src/dialyzer.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2014</year>
+ <year>2006</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -70,7 +71,7 @@
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
[--dump_callgraph file] [--no_native] [--fullpath]
- [--statistics]</code>
+ [--statistics] [--no_native_cache]</code>
<p>Options:</p>
<taglist>
<tag><c><![CDATA[files_or_dirs]]></c> (for backwards compatibility also
@@ -139,7 +140,11 @@
<tag><c><![CDATA[-Wwarn]]></c></tag>
<item>A family of options which selectively turn on/off warnings
(for help on the names of warnings use
- <c><![CDATA[dialyzer -Whelp]]></c>).</item>
+ <c><![CDATA[dialyzer -Whelp]]></c>).
+ Note that the options can also be given in the file with a
+ <c>-dialyzer()</c> attribute. See <seealso
+ marker="#suppression">Requesting or Suppressing Warnings in
+ Source Files</seealso> below for details.</item>
<tag><c><![CDATA[--shell]]></c></tag>
<item>Do not disable the Erlang shell while running the GUI.</item>
<tag><c><![CDATA[--version]]></c> (or <c><![CDATA[-v]]></c>)</tag>
@@ -194,6 +199,11 @@
heuristically performs when dialyzing many files; this avoids the
compilation time but it may result in (much) longer analysis
time.</item>
+ <tag><c><![CDATA[--no_native_cache]]></c></tag>
+ <item>By default, Dialyzer caches the results of native compilation in the
+ <c>$XDG_CACHE_HOME/erlang/dialyzer_hipe_cache</c> directory.
+ <c>XDG_CACHE_HOME</c> defaults to <c>$HOME/.cache</c>.
+ Use this option to disable caching.</item>
<tag><c><![CDATA[--fullpath]]></c></tag>
<item>Display the full path names of files for which warnings are emitted.</item>
<tag><c><![CDATA[--gui]]></c></tag>
@@ -227,6 +237,8 @@
<tag><c><![CDATA[-Wno_behaviours]]></c></tag>
<item>Suppress warnings about behaviour callbacks which drift from the
published recommended interfaces.</item>
+ <tag><c><![CDATA[-Wno_missing_calls]]></c></tag>
+ <item>Suppress warnings about calls to missing functions.</item>
<tag><c><![CDATA[-Wno_undefined_callbacks]]></c></tag>
<item>Suppress warnings about behaviours that have no
<c>-callback</c> attributes for their callbacks.</item>
@@ -242,9 +254,16 @@
analysis that finds data races performs intra-procedural data flow analysis
and can sometimes explode in time. Enable it at your own risk.
</item>
- <tag><c><![CDATA[-Wunderspecs]]></c>***</tag>
+i <tag><c><![CDATA[-Wunderspecs]]></c>***</tag>
<item>Warn about underspecified functions
(the -spec is strictly more allowing than the success typing).</item>
+ <tag><c><![CDATA[-Wunknown]]></c>***</tag>
+ <item>Let warnings about unknown functions and types affect the
+ exit status of the command line version. The default is to ignore
+ warnings about unknown functions and types when setting the exit
+ status. When using the Dialyzer from Erlang, warnings about unknown
+ functions and types are returned; the default is not to return
+ these warnings.</item>
</taglist>
<p>The following options are also available but their use is not
recommended: (they are mostly for Dialyzer developers and internal
@@ -269,6 +288,71 @@
given from the command line, so please refer to the sections above for
a description of these.</p>
</section>
+
+ <section>
+ <marker id="suppression"></marker>
+ <title>Requesting or Suppressing Warnings in Source Files</title>
+ <p>
+ The <c>-dialyzer()</c> attribute can be used for turning off
+ warnings in a module by specifying functions or warning options.
+ For example, to turn off all warnings for the function
+ <c>f/0</c>, include the following line:
+ </p>
+<code type="none">
+-dialyzer({nowarn_function, f/0}).
+</code>
+ <p>To turn off warnings for improper lists, add the following line
+ to the source file:
+ </p>
+<code type="none">
+-dialyzer(no_improper_lists).
+</code>
+ <p>The <c>-dialyzer()</c> attribute is allowed after function
+ declarations. Lists of warning options or functions are allowed:
+ </p>
+<code type="none">
+-dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).
+</code>
+ <p>
+ Warning options can be restricted to functions:
+ </p>
+<code type="none">
+-dialyzer({no_improper_lists, g/0}).
+</code>
+<code type="none">
+-dialyzer({[no_return, no_match], [g/0, h/0]}).
+</code>
+ <p>
+ For help on the warning options use <c>dialyzer -Whelp</c>. The
+ options are also enumerated <seealso
+ marker="#gui/1">below</seealso> (<c>WarnOpts</c>).
+ </p>
+ <note>
+ <p>
+ The <c>-dialyzer()</c> attribute is not checked by the Erlang
+ Compiler, but by the Dialyzer itself.
+ </p>
+ </note>
+ <note>
+ <p>
+ The warning option <c>-Wrace_conditions</c> has no effect when
+ set in source files.
+ </p>
+ </note>
+ <p>
+ The <c>-dialyzer()</c> attribute can also be used for turning on
+ warnings. For instance, if a module has been fixed regarding
+ unmatched returns, adding the line
+ </p>
+<code type="none">
+-dialyzer(unmatched_returns).
+</code>
+ <p>
+ can help in assuring that no new unmatched return warnings are
+ introduced.
+ </p>
+ </section>
+
<funcs>
<func>
<name>gui() -> ok | {error, Msg}</name>
@@ -283,13 +367,14 @@
OptList :: [Option]
Option :: {files, [Filename :: string()]}
| {files_rec, [DirName :: string()]}
- | {defines, [{Macro: atom(), Value : term()}]}
+ | {defines, [{Macro :: atom(), Value :: term()}]}
| {from, src_code | byte_code} %% Defaults to byte_code
| {init_plt, FileName :: string()} %% If changed from default
| {plts, [FileName :: string()]} %% If changed from default
| {include_dirs, [DirName :: string()]}
| {output_file, FileName :: string()}
| {output_plt, FileName :: string()}
+ | {check_plt, boolean()},
| {analysis_type, 'succ_typings' |
'plt_add' |
'plt_build' |
@@ -313,7 +398,8 @@ WarnOpts :: no_return
| race_conditions
| overspecs
| underspecs
- | specdiffs</code>
+ | specdiffs
+ | unknown</code>
</desc>
</func>
<func>
@@ -347,6 +433,7 @@ Tag :: 'warn_behaviour'
| 'warn_return_only_exit'
| 'warn_umatched_return'
| 'warn_undefined_callbacks'
+ | 'warn_unknown'
Id = {File :: string(), Line :: integer()}
Msg = msg() -- Undefined</code>
</desc>
diff --git a/lib/dialyzer/doc/src/dialyzer_chapter.xml b/lib/dialyzer/doc/src/dialyzer_chapter.xml
index 2626e19050..9bfb7ea2e1 100644
--- a/lib/dialyzer/doc/src/dialyzer_chapter.xml
+++ b/lib/dialyzer/doc/src/dialyzer_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 8976679c1d..4202730eed 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,247 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Dialyzer no longer asserts that files and directories
+ to be removed from a PLT exist. </p>
+ <p>
+ Own Id: OTP-13103 Aux Id: ERL-40 </p>
+ </item>
+ <item>
+ <p> Fix a bug concerning parameterized opaque types. </p>
+ <p>
+ Own Id: OTP-13237</p>
+ </item>
+ <item>
+ <p>
+ Fix pretty printing of Core Maps</p>
+ <p>
+ Literal maps could cause Dialyzer to crash when pretty
+ printing the results.</p>
+ <p>
+ Own Id: OTP-13238</p>
+ </item>
+ <item>
+ <p>
+ If a behavior module contains an non-exported function
+ with the same name as one of the behavior's callbacks,
+ the callback info was inadvertently deleted from the PLT
+ as the <c>dialyzer_plt:delete_list/2</c> function was
+ cleaning up the callback table.</p>
+ <p>
+ Own Id: OTP-13287</p>
+ </item>
+ <item>
+ <p> Correct the contract for <c>erlang:byte_size/1</c>
+ </p> <p> Correct the handling of comparison operators for
+ map and bit string operands. </p>
+ <p>
+ Own Id: OTP-13312</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Dialyzer recognizes calls to <c>M:F/A</c> where <c>M</c>,
+ <c>F</c>, and <c>A</c> are all literals.</p>
+ <p>
+ Own Id: OTP-13217</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 2.8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Reintroduce the <c>erlang:make_fun/3</c> BIF in
+ erl_bif_types.</p>
+ <p>
+ Own Id: OTP-13068</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 2.8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Improve the translation of forms to types. </p>
+ <p>
+ Own Id: OTP-12865</p>
+ </item>
+ <item>
+ <p> Fix a bug concerning parameterized opaque types. </p>
+ <p>
+ Own Id: OTP-12866</p>
+ </item>
+ <item>
+ <p> Fix a bug concerning parameterized opaque types. </p>
+ <p>
+ Own Id: OTP-12940</p>
+ </item>
+ <item>
+ <p> Fix bugs concerning <c>erlang:abs/1</c>. </p>
+ <p>
+ Own Id: OTP-12948</p>
+ </item>
+ <item>
+ <p> Fix a bug concerning <c>lists:keydelete/3</c> with
+ union and opaque types. </p>
+ <p>
+ Own Id: OTP-12949</p>
+ </item>
+ <item>
+ <p>
+ Use new function <c>hipe:erts_checksum</c> to get correct
+ runtime checksum for cached beam files.</p>
+ <p>
+ Own Id: OTP-12964 Aux Id: OTP-12963, OTP-12962 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 2.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The translation of Erlang forms to the type
+ representation used by Dialyzer has been improved in
+ several ways. The most important change is that deeply
+ nested records can be handled. </p>
+ <p>
+ Own Id: OTP-12350</p>
+ </item>
+ <item>
+ <p> Fix a bug that could cause bogus warnings for opaque
+ types. </p> <p>In Erlang/OTP 18 two parameterized types
+ declared in the same module always result in a
+ contradiction (<c>none()</c>) when combined outside of
+ the module where they are declared, unless they have the
+ same number of parameters. </p> <p> The behaviour is
+ different from Erlang/OTP 17 where, for instance,
+ <c>dict:dict()</c> and <c>dict:dict(_, _)</c>, which are
+ both opaque, can be combined outside of the <c>dict</c>
+ module. </p> <p> In Erlang/OTP 18, <c>dict:dict()</c> and
+ <c>dict:dict(_, _)</c> can still be combined outside of
+ the <c>dict</c> module. That has been made possible by
+ not declaring <c>dict:dict()</c> as opaque. </p>
+ <p>
+ Own Id: OTP-12493</p>
+ </item>
+ <item>
+ <p> Update the PLT properly when a module is changed.
+ (Thanks to James Fish for the bug report, and to Stavros
+ Aronis for fixing the bug.) </p>
+ <p>
+ Own Id: OTP-12637</p>
+ </item>
+ <item>
+ <p>
+ An argument of '*'/2 is not constraind if the other
+ operand can be zero.</p>
+ <p>
+ Own Id: OTP-12725</p>
+ </item>
+ <item>
+ <p> Mention the option <c>check_plt</c> among the
+ <c>dialyzer:gui()</c> options. (Thanks to James Fish.)
+ </p>
+ <p>
+ Own Id: OTP-12750</p>
+ </item>
+ <item>
+ <p>Fix a bug which could cause an infinite loop in
+ Dialyzer.</p>
+ <p>
+ Own Id: OTP-12826</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The <c>-dialyzer()</c> attribute can be used for
+ suppressing warnings in a module by specifying functions
+ or warning options. It can also be used for requesting
+ warnings in a module. </p>
+ <p>
+ Own Id: OTP-10280</p>
+ </item>
+ <item>
+ <p> The pre-defined types <c>array()</c>, <c>dict()</c>,
+ <c>digraph()</c>, <c>gb_set()</c>, <c>gb_tree()</c>,
+ <c>queue()</c>, <c>set()</c>, and <c>tid()</c> have been
+ removed. </p>
+ <p>
+ Own Id: OTP-11445 Aux Id: OTP-10342, OTP-9352 </p>
+ </item>
+ <item>
+ <p> A few type names that have been used for representing
+ certain predefined types can now be used for user-defined
+ types. This affects the types <c>product/_</c>,
+ <c>union/_</c>, and <c>range/2</c> as well as
+ <c>tuple/N</c> (N > 0), <c>map/N</c> (N > 0),
+ <c>atom/1</c>, <c>integer/1</c>, <c>binary/2</c>,
+ <c>record/_,</c> and <c>'fun'/_</c>. A consequence is
+ that, for example, it is no longer possible to refer to a
+ record type with <c>record(r)</c>; instead the usual
+ record notation, <c>#r{}</c>, is to be used. </p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-11851</p>
+ </item>
+ <item>
+ <p> When implementing user-defined behaviours it is now
+ possible to specify optional callback functions. See OTP
+ Design Principles User's Guide, Sys and Proc_Lib,
+ User-Defined Behaviours, for details. </p>
+ <p>
+ Own Id: OTP-11861</p>
+ </item>
+ <item>
+ <p>Add two options to the Dialyzer:
+ <c>no_missing_calls</c> suppresses warnings about calls
+ to missing or unexported functions; <c>unknown</c> lets
+ warnings about unknown functions or types affect the exit
+ status. See also dialyzer(3). </p>
+ <p>
+ Own Id: OTP-12682</p>
+ </item>
+ <item>
+ <p>By default, dialyzer will now cache native versions of
+ dialyzer modules to avoid having to re-compile them each
+ time dialyzer is started. Caching can be disabled using
+ the option <c>--no_native_cache</c>.</p>
+ <p>
+ Own Id: OTP-12779</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 2.7.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -280,22 +522,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -609,19 +857,17 @@
Own Id: OTP-9731</p>
</item>
<item>
- <p>
<list> <item><p>No warnings for underspecs with remote
types</p></item> <item><p> Fix crash in Typer</p></item>
<item><p>Fix Dialyzer's warning for its own
code</p></item> <item><p>Fix Dialyzer's warnings in
HiPE</p></item> <item><p>Add file/line info in a
particular Dialyzer crash</p></item> <item><p>Update
- inets test results</p></item> </list></p>
+ inets test results</p></item> </list>
<p>
Own Id: OTP-9758</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -632,7 +878,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/dialyzer/doc/src/part.xml b/lib/dialyzer/doc/src/part.xml
index 83289206f9..eff8e05257 100644
--- a/lib/dialyzer/doc/src/part.xml
+++ b/lib/dialyzer/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/dialyzer/doc/src/part_notes.xml b/lib/dialyzer/doc/src/part_notes.xml
index 3798d25315..ba8d30e1be 100644
--- a/lib/dialyzer/doc/src/part_notes.xml
+++ b/lib/dialyzer/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/dialyzer/doc/src/ref_man.xml b/lib/dialyzer/doc/src/ref_man.xml
index 23e7b6f57d..9c3887b599 100644
--- a/lib/dialyzer/doc/src/ref_man.xml
+++ b/lib/dialyzer/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile
index 91fbdca5bd..770af2140f 100644
--- a/lib/dialyzer/src/Makefile
+++ b/lib/dialyzer/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/dialyzer/src/dialyzer.app.src b/lib/dialyzer/src/dialyzer.app.src
index 1756800c4f..8ac6dc1367 100644
--- a/lib/dialyzer/src/dialyzer.app.src
+++ b/lib/dialyzer/src/dialyzer.app.src
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -45,6 +46,6 @@
{registered, []},
{applications, [compiler, gs, hipe, kernel, stdlib, wx]},
{env, []},
- {runtime_dependencies, ["wx-1.2","syntax_tools-1.6.14","stdlib-2.0",
- "kernel-3.0","hipe-3.10.3","erts-6.0",
+ {runtime_dependencies, ["wx-1.2","syntax_tools-1.6.14","stdlib-2.5",
+ "kernel-3.0","hipe-3.13","erts-7.0",
"compiler-5.0"]}]}.
diff --git a/lib/dialyzer/src/dialyzer.appup.src b/lib/dialyzer/src/dialyzer.appup.src
index 1e293e407a..727e961629 100644
--- a/lib/dialyzer/src/dialyzer.appup.src
+++ b/lib/dialyzer/src/dialyzer.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index cec94a49fd..9f51dfe356 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -162,14 +163,7 @@ run(Opts) ->
{error, Msg} ->
throw({dialyzer_error, Msg});
OptsRecord ->
- case OptsRecord#options.check_plt of
- true ->
- case cl_check_init(OptsRecord) of
- {ok, ?RET_NOTHING_SUSPICIOUS} -> ok;
- {error, ErrorMsg1} -> throw({dialyzer_error, ErrorMsg1})
- end;
- false -> ok
- end,
+ ok = check_init(OptsRecord),
case dialyzer_cl:start(OptsRecord) of
{?RET_DISCREPANCIES, Warnings} -> Warnings;
{?RET_NOTHING_SUSPICIOUS, _} -> []
@@ -179,6 +173,16 @@ run(Opts) ->
erlang:error({dialyzer_error, lists:flatten(ErrorMsg)})
end.
+check_init(#options{analysis_type = plt_check}) ->
+ ok;
+check_init(#options{check_plt = true} = OptsRecord) ->
+ case cl_check_init(OptsRecord) of
+ {ok, _} -> ok;
+ {error, Msg} -> throw({dialyzer_error, Msg})
+ end;
+check_init(#options{check_plt = false}) ->
+ ok.
+
internal_gui(OptsRecord) ->
F = fun() ->
dialyzer_gui_wx:start(OptsRecord),
@@ -199,17 +203,13 @@ gui(Opts) ->
throw({dialyzer_error, Msg});
OptsRecord ->
ok = check_gui_options(OptsRecord),
- case cl_check_init(OptsRecord) of
- {ok, ?RET_NOTHING_SUSPICIOUS} ->
- F = fun() ->
- dialyzer_gui_wx:start(OptsRecord)
- end,
- case doit(F) of
- {ok, _} -> ok;
- {error, Msg} -> throw({dialyzer_error, Msg})
- end;
- {error, ErrorMsg1} ->
- throw({dialyzer_error, ErrorMsg1})
+ ok = check_init(OptsRecord),
+ F = fun() ->
+ dialyzer_gui_wx:start(OptsRecord)
+ end,
+ case doit(F) of
+ {ok, _} -> ok;
+ {error, Msg} -> throw({dialyzer_error, Msg})
end
catch
throw:{dialyzer_error, ErrorMsg} ->
@@ -282,15 +282,17 @@ cl_check_log(none) ->
cl_check_log(Output) ->
io:format(" Check output file `~s' for details\n", [Output]).
--spec format_warning(dial_warning()) -> string().
+-spec format_warning(raw_warning()) -> string().
format_warning(W) ->
format_warning(W, basename).
--spec format_warning(dial_warning(), fopt()) -> string().
+-spec format_warning(raw_warning() | dial_warning(), fopt()) -> string().
+format_warning({Tag, {File, Line, _MFA}, Msg}, FOpt) ->
+ format_warning({Tag, {File, Line}, Msg}, FOpt);
format_warning({_Tag, {File, Line}, Msg}, FOpt) when is_list(File),
- is_integer(Line) ->
+ is_integer(Line) ->
F = case FOpt of
fullpath -> File;
basename -> filename:basename(File)
diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl
index 9a25f86512..de236f91ab 100644
--- a/lib/dialyzer/src/dialyzer.hrl
+++ b/lib/dialyzer/src/dialyzer.hrl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% 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%
%%%
@@ -84,6 +85,15 @@
-type dial_warning() :: {dial_warn_tag(), file_line(), {atom(), [term()]}}.
%%
+%% This is the representation of each warning before suppressions have
+%% been applied
+%%
+-type m_or_mfa() :: module() % warnings not associated with any function
+ | mfa().
+-type warning_info() :: {file:filename(), non_neg_integer(), m_or_mfa()}.
+-type raw_warning() :: {dial_warn_tag(), warning_info(), {atom(), [term()]}}.
+
+%%
%% This is the representation of dialyzer's internal errors
%%
-type dial_error() :: any(). %% XXX: underspecified
@@ -103,6 +113,7 @@
-type fopt() :: 'basename' | 'fullpath'.
-type format() :: 'formatted' | 'raw'.
-type label() :: non_neg_integer().
+-type dial_warn_tags():: ordsets:ordset(dial_warn_tag()).
-type rep_mode() :: 'quiet' | 'normal' | 'verbose'.
-type start_from() :: 'byte_code' | 'src_code'.
-type mfa_or_funlbl() :: label() | mfa().
@@ -138,7 +149,7 @@
init_plts = [] :: [file:filename()],
include_dirs = [] :: [file:filename()],
output_plt = none :: 'none' | file:filename(),
- legal_warnings = ordsets:new() :: ordsets:ordset(dial_warn_tag()),
+ legal_warnings = ordsets:new() :: dial_warn_tags(),
report_mode = normal :: rep_mode(),
erlang_mode = false :: boolean(),
use_contracts = true :: boolean(),
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index af1c2b7e3a..8537878dfc 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -2,18 +2,19 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,8 +40,6 @@
one_file_result/0,
compile_result/0]).
--export_type([no_warn_unused/0]).
-
-include("dialyzer.hrl").
-record(analysis_state,
@@ -50,8 +49,9 @@
defines = [] :: [dial_define()],
doc_plt :: dialyzer_plt:plt(),
include_dirs = [] :: [file:filename()],
- no_warn_unused :: no_warn_unused(),
parent :: pid(),
+ legal_warnings :: % command line options
+ [dial_warn_tag()],
plt :: dialyzer_plt:plt(),
start_from = byte_code :: start_from(),
use_contracts = true :: boolean(),
@@ -59,9 +59,10 @@
solvers :: [solver()]
}).
--record(server_state, {parent :: pid(), legal_warnings :: [dial_warn_tag()]}).
-
--type no_warn_unused() :: sets:set(mfa()).
+-record(server_state,
+ {
+ parent :: pid()
+ }).
%%--------------------------------------------------------------------
%% Main
@@ -75,48 +76,36 @@ start(Parent, LegalWarnings, Analysis) ->
Analysis0 =
Analysis#analysis{race_detection = RacesOn, timing_server = TimingServer},
Analysis1 = expand_files(Analysis0),
- Analysis2 = run_analysis(Analysis1),
- State = #server_state{parent = Parent, legal_warnings = LegalWarnings},
+ Analysis2 = run_analysis(Analysis1, LegalWarnings),
+ State = #server_state{parent = Parent},
loop(State, Analysis2, none),
dialyzer_timing:stop(TimingServer).
-run_analysis(Analysis) ->
+run_analysis(Analysis, LegalWarnings) ->
Self = self(),
- Fun = fun() -> analysis_start(Self, Analysis) end,
+ Fun = fun() -> analysis_start(Self, Analysis, LegalWarnings) end,
Analysis#analysis{analysis_pid = spawn_link(Fun)}.
-loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State,
+loop(#server_state{parent = Parent} = State,
#analysis{analysis_pid = AnalPid} = Analysis, ExtCalls) ->
receive
{AnalPid, log, LogMsg} ->
send_log(Parent, LogMsg),
loop(State, Analysis, ExtCalls);
{AnalPid, warnings, Warnings} ->
- case filter_warnings(LegalWarnings, Warnings) of
- [] -> ok;
- SendWarnings ->
- send_warnings(Parent, SendWarnings)
- end,
+ send_warnings(Parent, Warnings),
loop(State, Analysis, ExtCalls);
{AnalPid, cserver, CServer, Plt} ->
send_codeserver_plt(Parent, CServer, Plt),
loop(State, Analysis, ExtCalls);
{AnalPid, done, Plt, DocPlt} ->
- case ExtCalls =:= none of
- true ->
- send_analysis_done(Parent, Plt, DocPlt);
- false ->
- send_ext_calls(Parent, ExtCalls),
- send_analysis_done(Parent, Plt, DocPlt)
- end;
+ send_ext_calls(Parent, ExtCalls),
+ send_analysis_done(Parent, Plt, DocPlt);
{AnalPid, ext_calls, NewExtCalls} ->
loop(State, Analysis, NewExtCalls);
{AnalPid, ext_types, ExtTypes} ->
send_ext_types(Parent, ExtTypes),
loop(State, Analysis, ExtCalls);
- {AnalPid, unknown_behaviours, UnknownBehaviour} ->
- send_unknown_behaviours(Parent, UnknownBehaviour),
- loop(State, Analysis, ExtCalls);
{AnalPid, mod_deps, ModDeps} ->
send_mod_deps(Parent, ModDeps),
loop(State, Analysis, ExtCalls);
@@ -129,7 +118,7 @@ loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State,
%% The Analysis
%%--------------------------------------------------------------------
-analysis_start(Parent, Analysis) ->
+analysis_start(Parent, Analysis, LegalWarnings) ->
CServer = dialyzer_codeserver:new(),
Plt = Analysis#analysis.plt,
State = #analysis_state{codeserver = CServer,
@@ -139,13 +128,14 @@ analysis_start(Parent, Analysis) ->
include_dirs = Analysis#analysis.include_dirs,
plt = Plt,
parent = Parent,
+ legal_warnings = LegalWarnings,
start_from = Analysis#analysis.start_from,
use_contracts = Analysis#analysis.use_contracts,
timing_server = Analysis#analysis.timing_server,
solvers = Analysis#analysis.solvers
},
Files = ordsets:from_list(Analysis#analysis.files),
- {Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State),
+ {Callgraph, TmpCServer0} = compile_and_store(Files, State),
%% Remote type postprocessing
NewCServer =
try
@@ -165,9 +155,12 @@ analysis_start(Parent, Analysis) ->
TmpCServer2 =
dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes,
TmpCServer1),
- TmpCServer3 = dialyzer_utils:process_record_remote_types(TmpCServer2),
?timing(State#analysis_state.timing_server, "remote",
- dialyzer_contracts:process_contract_remote_types(TmpCServer3))
+ begin
+ TmpCServer3 =
+ dialyzer_utils:process_record_remote_types(TmpCServer2),
+ dialyzer_contracts:process_contract_remote_types(TmpCServer3)
+ end)
catch
throw:{error, _ErrorMsg} = Error -> exit(Error)
end,
@@ -177,7 +170,6 @@ analysis_start(Parent, Analysis) ->
State0 = State#analysis_state{plt = NewPlt1},
dump_callgraph(Callgraph, State0, Analysis),
State1 = State0#analysis_state{codeserver = NewCServer},
- State2 = State1#analysis_state{no_warn_unused = NoWarn},
%% Remove all old versions of the files being analyzed
AllNodes = dialyzer_callgraph:all_nodes(Callgraph),
Plt1 = dialyzer_plt:delete_list(NewPlt1, AllNodes),
@@ -187,14 +179,14 @@ analysis_start(Parent, Analysis) ->
true -> dialyzer_callgraph:put_race_detection(true, Callgraph);
false -> Callgraph
end,
- State3 = analyze_callgraph(NewCallgraph, State2#analysis_state{plt = Plt1}),
+ State2 = analyze_callgraph(NewCallgraph, State1#analysis_state{plt = Plt1}),
dialyzer_callgraph:dispose_race_server(NewCallgraph),
rcv_and_send_ext_types(Parent),
NonExports = sets:subtract(sets:from_list(AllNodes), Exports),
NonExportsList = sets:to_list(NonExports),
- Plt2 = dialyzer_plt:delete_list(State3#analysis_state.plt, NonExportsList),
- send_codeserver_plt(Parent, CServer, State3#analysis_state.plt),
- send_analysis_done(Parent, Plt2, State3#analysis_state.doc_plt).
+ Plt2 = dialyzer_plt:delete_list(State2#analysis_state.plt, NonExportsList),
+ send_codeserver_plt(Parent, CServer, State2#analysis_state.plt),
+ send_analysis_done(Parent, Plt2, State2#analysis_state.doc_plt).
analyze_callgraph(Callgraph, #analysis_state{codeserver = Codeserver,
doc_plt = DocPlt,
@@ -210,11 +202,11 @@ analyze_callgraph(Callgraph, #analysis_state{codeserver = Codeserver,
TimingServer, Solvers, Parent),
{NewPlt0, DocPlt};
succ_typings ->
- NoWarn = State#analysis_state.no_warn_unused,
{Warnings, NewPlt0, NewDocPlt0} =
dialyzer_succ_typings:get_warnings(Callgraph, Plt, DocPlt, Codeserver,
- NoWarn, TimingServer, Solvers, Parent),
- send_warnings(State#analysis_state.parent, Warnings),
+ TimingServer, Solvers, Parent),
+ Warnings1 = filter_warnings(Warnings, Codeserver),
+ send_warnings(State#analysis_state.parent, Warnings1),
{NewPlt0, NewDocPlt0}
end,
dialyzer_callgraph:delete(Callgraph),
@@ -230,19 +222,22 @@ analyze_callgraph(Callgraph, #analysis_state{codeserver = Codeserver,
defines = [] :: [dial_define()],
include_dirs = [] :: [file:filename()],
start_from = byte_code :: start_from(),
- use_contracts = true :: boolean()
+ use_contracts = true :: boolean(),
+ legal_warnings :: [dial_warn_tag()]
}).
make_compile_init(#analysis_state{codeserver = Codeserver,
defines = Defs,
include_dirs = Dirs,
use_contracts = UseContracts,
+ legal_warnings = LegalWarnings,
start_from = StartFrom}, Callgraph) ->
#compile_init{callgraph = Callgraph,
codeserver = Codeserver,
defines = [{d, Macro, Val} || {Macro, Val} <- Defs],
include_dirs = [{i, D} || D <- Dirs],
use_contracts = UseContracts,
+ legal_warnings = LegalWarnings,
start_from = StartFrom}.
compile_and_store(Files, #analysis_state{codeserver = CServer,
@@ -252,7 +247,7 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
{T1, _} = statistics(wall_clock),
Callgraph = dialyzer_callgraph:new(),
CompileInit = make_compile_init(State, Callgraph),
- {{Failed, NoWarn, Modules}, NextLabel} =
+ {{Failed, Modules}, NextLabel} =
?timing(Timing, "compile", _C1,
dialyzer_coordinator:parallel_job(compile, Files,
CompileInit, Timing)),
@@ -281,34 +276,34 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
{T3, _} = statistics(wall_clock),
Msg2 = io_lib:format("done in ~.2f secs\n", [(T3-T2)/1000]),
send_log(Parent, Msg2),
- {Callgraph, sets:from_list(NoWarn), CServer2}.
+ {Callgraph, CServer2}.
-type compile_init_data() :: #compile_init{}.
-type error_reason() :: string().
--type compile_result() :: {[{file:filename(), error_reason()}], [mfa()],
+-type compile_result() :: {[{file:filename(), error_reason()}],
[module()]}. %%opaque
-type one_file_result() :: {error, error_reason()} |
{ok, [dialyzer_callgraph:callgraph_edge()],
- [mfa_or_funlbl()], [mfa()], module()}. %%opaque
--type compile_mid_data() :: {module(), cerl:cerl(), [mfa()],
+ [mfa_or_funlbl()], module()}. %%opaque
+-type compile_mid_data() :: {module(), cerl:cerl(),
dialyzer_callgraph:callgraph(),
dialyzer_codeserver:codeserver()}.
-spec compile_init_result() -> compile_result().
-compile_init_result() -> {[], [], []}.
+compile_init_result() -> {[], []}.
-spec add_to_result(file:filename(), one_file_result(), compile_result(),
compile_init_data()) -> compile_result().
-add_to_result(File, NewData, {Failed, NoWarn, Mods}, InitData) ->
+add_to_result(File, NewData, {Failed, Mods}, InitData) ->
case NewData of
{error, Reason} ->
- {[{File, Reason}|Failed], NoWarn, Mods};
- {ok, V, E, NewNoWarn, Mod} ->
+ {[{File, Reason}|Failed], Mods};
+ {ok, V, E, Mod} ->
Callgraph = InitData#compile_init.callgraph,
dialyzer_callgraph:add_edges(E, V, Callgraph),
- {Failed, NewNoWarn ++ NoWarn, [Mod|Mods]}
+ {Failed, [Mod|Mods]}
end.
-spec start_compilation(file:filename(), compile_init_data()) ->
@@ -318,12 +313,14 @@ start_compilation(File,
#compile_init{callgraph = Callgraph, codeserver = Codeserver,
defines = Defines, include_dirs = IncludeD,
use_contracts = UseContracts,
+ legal_warnings = LegalWarnings,
start_from = StartFrom}) ->
case StartFrom of
src_code ->
- compile_src(File, IncludeD, Defines, Callgraph, Codeserver, UseContracts);
+ compile_src(File, IncludeD, Defines, Callgraph, Codeserver,
+ UseContracts, LegalWarnings);
byte_code ->
- compile_byte(File, Callgraph, Codeserver, UseContracts)
+ compile_byte(File, Callgraph, Codeserver, UseContracts, LegalWarnings)
end.
cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
@@ -357,88 +354,86 @@ cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
end,
Callgraph1.
-compile_src(File, Includes, Defines, Callgraph, CServer, UseContracts) ->
+compile_src(File, Includes, Defines, Callgraph, CServer, UseContracts,
+ LegalWarnings) ->
DefaultIncludes = default_includes(filename:dirname(File)),
SrcCompOpts = dialyzer_utils:src_compiler_opts(),
CompOpts = SrcCompOpts ++ Includes ++ Defines ++ DefaultIncludes,
case dialyzer_utils:get_abstract_code_from_src(File, CompOpts) of
{error, _Msg} = Error -> Error;
{ok, AbstrCode} ->
- compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts)
+ compile_common(File, AbstrCode, CompOpts, Callgraph, CServer,
+ UseContracts, LegalWarnings)
end.
-compile_byte(File, Callgraph, CServer, UseContracts) ->
+compile_byte(File, Callgraph, CServer, UseContracts, LegalWarnings) ->
case dialyzer_utils:get_abstract_code_from_beam(File) of
error ->
{error, " Could not get abstract code for: " ++ File ++ "\n" ++
" Recompile with +debug_info or analyze starting from source code"};
{ok, AbstrCode} ->
- compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts)
+ compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts,
+ LegalWarnings)
end.
-compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts) ->
+compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts,
+ LegalWarnings) ->
case dialyzer_utils:get_compile_options_from_beam(File) of
error ->
{error, " Could not get compile options for: " ++ File ++ "\n" ++
" Recompile or analyze starting from source code"};
{ok, CompOpts} ->
- compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts)
+ compile_common(File, AbstrCode, CompOpts, Callgraph, CServer,
+ UseContracts, LegalWarnings)
end.
-compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts) ->
+compile_common(File, AbstrCode, CompOpts, Callgraph, CServer,
+ UseContracts, LegalWarnings) ->
case dialyzer_utils:get_core_from_abstract_code(AbstrCode, CompOpts) of
error -> {error, " Could not get core Erlang code for: " ++ File};
{ok, Core} ->
Mod = cerl:concrete(cerl:module_name(Core)),
- NoWarn = abs_get_nowarn(AbstrCode, Mod),
case dialyzer_utils:get_record_and_type_info(AbstrCode) of
{error, _} = Error -> Error;
{ok, RecInfo} ->
CServer1 =
dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer),
+ MetaFunInfo =
+ dialyzer_utils:get_fun_meta_info(Mod, AbstrCode, LegalWarnings),
+ CServer2 =
+ dialyzer_codeserver:insert_fun_meta_info(MetaFunInfo, CServer1),
case UseContracts of
true ->
case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of
{error, _} = Error -> Error;
{ok, SpecInfo, CallbackInfo} ->
- CServer2 =
+ CServer3 =
dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo,
CallbackInfo,
- CServer1),
- store_core(Mod, Core, NoWarn, Callgraph, CServer2)
+ CServer2),
+ store_core(Mod, Core, Callgraph, CServer3)
end;
false ->
- store_core(Mod, Core, NoWarn, Callgraph, CServer1)
+ store_core(Mod, Core, Callgraph, CServer2)
end
end
end.
-store_core(Mod, Core, NoWarn, Callgraph, CServer) ->
+store_core(Mod, Core, Callgraph, CServer) ->
Exp = get_exports_from_core(Core),
ExpTypes = get_exported_types_from_core(Core),
CServer = dialyzer_codeserver:insert_exports(Exp, CServer),
CServer = dialyzer_codeserver:insert_temp_exported_types(ExpTypes, CServer),
CoreTree = cerl:from_records(Core),
- {ok, cerl_trees:size(CoreTree), {Mod, CoreTree, NoWarn, Callgraph, CServer}}.
+ CoreSize = cerl_trees:size(CoreTree),
+ {ok, CoreSize, {Mod, CoreTree, Callgraph, CServer}}.
-spec continue_compilation(integer(), compile_mid_data()) -> one_file_result().
-continue_compilation(NextLabel, {Mod, CoreTree, NoWarn, Callgraph, CServer}) ->
+continue_compilation(NextLabel, {Mod, CoreTree, Callgraph, CServer}) ->
{LabeledTree, _NewNextLabel} = cerl_trees:label(CoreTree, NextLabel),
LabeledCore = cerl:to_records(LabeledTree),
- store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, NoWarn, CServer).
-
-abs_get_nowarn(Abs, M) ->
- Opts = lists:flatten([C || {attribute, _, compile, C} <- Abs]),
- Warn = erl_lint:bool_option(warn_unused_function, nowarn_unused_function,
- true, Opts),
- case Warn of
- false ->
- [{M, F, A} || {function, _, F, A, _} <- Abs]; % all functions
- true ->
- [{M, F, A} || {nowarn_unused_function, FAs} <- Opts,
- {F, A} <- lists:flatten([FAs])]
- end.
+ store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, CServer).
get_exported_types_from_core(Core) ->
Attrs = cerl:module_attrs(Core),
@@ -456,11 +451,11 @@ get_exports_from_core(Core) ->
M = cerl:atom_val(cerl:module_name(Tree)),
[{M, F, A} || {F, A} <- Exports2].
-store_code_and_build_callgraph(Mod, Core, Callgraph, NoWarn, CServer) ->
+store_code_and_build_callgraph(Mod, Core, Callgraph, CServer) ->
CoreTree = cerl:from_records(Core),
{Vertices, Edges} = dialyzer_callgraph:scan_core_tree(CoreTree, Callgraph),
CServer = dialyzer_codeserver:insert(Mod, CoreTree, CServer),
- {ok, Vertices, Edges, NoWarn, Mod}.
+ {ok, Vertices, Edges, Mod}.
%%--------------------------------------------------------------------
%% Utilities
@@ -548,14 +543,25 @@ send_warnings(Parent, Warnings) ->
Parent ! {self(), warnings, Warnings},
ok.
-filter_warnings(LegalWarnings, Warnings) ->
- [TIW || {Tag, _Id, _Warning} = TIW <- Warnings,
- ordsets:is_element(Tag, LegalWarnings)].
+filter_warnings(Warnings, Codeserver) ->
+ [TWW || {Tag, WarningInfo, _Warning} = TWW <- Warnings,
+ is_ok_fun(WarningInfo, Codeserver),
+ is_ok_tag(Tag, WarningInfo, Codeserver)].
+
+is_ok_fun({_F, _L, Module}, _Codeserver) when is_atom(Module) ->
+ true;
+is_ok_fun({_Filename, _Line, {_M, _F, _A} = MFA}, Codeserver) ->
+ not dialyzer_utils:is_suppressed_fun(MFA, Codeserver).
+is_ok_tag(Tag, {_F, _L, MorMFA}, Codeserver) ->
+ not dialyzer_utils:is_suppressed_tag(MorMFA, Tag, Codeserver).
+
send_analysis_done(Parent, Plt, DocPlt) ->
Parent ! {self(), done, Plt, DocPlt},
ok.
+send_ext_calls(_Parent, none) ->
+ ok;
send_ext_calls(Parent, ExtCalls) ->
Parent ! {self(), ext_calls, ExtCalls},
ok.
@@ -564,16 +570,14 @@ send_ext_types(Parent, ExtTypes) ->
Parent ! {self(), ext_types, ExtTypes},
ok.
-send_unknown_behaviours(Parent, UnknownBehaviours) ->
- Parent ! {self(), unknown_behaviours, UnknownBehaviours},
- ok.
-
send_codeserver_plt(Parent, CServer, Plt ) ->
Parent ! {self(), cserver, CServer, Plt},
ok.
send_bad_calls(Parent, BadCalls, CodeServer) ->
- send_warnings(Parent, format_bad_calls(BadCalls, CodeServer, [])).
+ FormatedBadCalls = format_bad_calls(BadCalls, CodeServer, []),
+ Warnings = filter_warnings(FormatedBadCalls, CodeServer),
+ send_warnings(Parent, Warnings).
send_mod_deps(Parent, ModuleDeps) ->
Parent ! {self(), mod_deps, ModuleDeps},
@@ -585,8 +589,9 @@ format_bad_calls([{{_, _, _}, {_, module_info, A}}|Left], CodeServer, Acc)
format_bad_calls([{FromMFA, {M, F, A} = To}|Left], CodeServer, Acc) ->
{_Var, FunCode} = dialyzer_codeserver:lookup_mfa_code(FromMFA, CodeServer),
Msg = {call_to_missing, [M, F, A]},
- FileLine = find_call_file_and_line(FunCode, To),
- NewAcc = [{?WARN_CALLGRAPH, FileLine, Msg}|Acc],
+ {File, Line} = find_call_file_and_line(FunCode, To),
+ WarningInfo = {File, Line, FromMFA},
+ NewAcc = [{?WARN_CALLGRAPH, WarningInfo, Msg}|Acc],
format_bad_calls(Left, CodeServer, NewAcc);
format_bad_calls([], _CodeServer, Acc) ->
Acc.
@@ -605,6 +610,28 @@ find_call_file_and_line(Tree, MFA) ->
MFA ->
Ann = cerl:get_ann(SubTree),
[{get_file(Ann), get_line(Ann)}|Acc];
+ {erlang, make_fun, 3} ->
+ [CA1, CA2, CA3] = cerl:call_args(SubTree),
+ case
+ cerl:is_c_atom(CA1) andalso
+ cerl:is_c_atom(CA2) andalso
+ cerl:is_c_int(CA3)
+ of
+ true ->
+ case
+ {cerl:concrete(CA1),
+ cerl:concrete(CA2),
+ cerl:concrete(CA3)}
+ of
+ MFA ->
+ Ann = cerl:get_ann(SubTree),
+ [{get_file(Ann), get_line(Ann)}|Acc];
+ _ ->
+ Acc
+ end;
+ false ->
+ Acc
+ end;
_ -> Acc
end;
false -> Acc
diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl
index 1d458b49fc..b6f15fdc0e 100644
--- a/lib/dialyzer/src/dialyzer_behaviours.erl
+++ b/lib/dialyzer/src/dialyzer_behaviours.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -52,7 +53,7 @@
-spec check_callbacks(module(), [{cerl:cerl(), cerl:cerl()}], rectab(),
dialyzer_plt:plt(),
- dialyzer_codeserver:codeserver()) -> [dial_warning()].
+ dialyzer_codeserver:codeserver()) -> [raw_warning()].
check_callbacks(Module, Attrs, Records, Plt, Codeserver) ->
{Behaviours, BehLines} = get_behaviours(Attrs),
@@ -65,7 +66,7 @@ check_callbacks(Module, Attrs, Records, Plt, Codeserver) ->
State = #state{plt = Plt, filename = File, behlines = BehLines,
codeserver = Codeserver, records = Records},
Warnings = get_warnings(Module, Behaviours, State),
- [add_tag_file_line(Module, W, State) || W <- Warnings]
+ [add_tag_warning_info(Module, W, State) || W <- Warnings]
end.
%%--------------------------------------------------------------------
@@ -102,14 +103,18 @@ check_all_callbacks(Module, Behaviour, [Cb|Rest],
#state{plt = Plt, codeserver = Codeserver,
records = Records} = State, Acc) ->
{{Behaviour, Function, Arity},
- {{_BehFile, _BehLine}, Callback}} = Cb,
+ {{_BehFile, _BehLine}, Callback, Xtra}} = Cb,
CbMFA = {Module, Function, Arity},
CbReturnType = dialyzer_contracts:get_contract_return(Callback),
CbArgTypes = dialyzer_contracts:get_contract_args(Callback),
Acc0 = Acc,
Acc1 =
case dialyzer_plt:lookup(Plt, CbMFA) of
- 'none' -> [{callback_missing, [Behaviour, Function, Arity]}|Acc0];
+ 'none' ->
+ case lists:member(optional_callback, Xtra) of
+ true -> Acc0;
+ false -> [{callback_missing, [Behaviour, Function, Arity]}|Acc0]
+ end;
{'value', RetArgTypes} ->
Acc00 = Acc0,
{ReturnType, ArgTypes} = RetArgTypes,
@@ -137,7 +142,7 @@ check_all_callbacks(Module, Behaviour, [Cb|Rest],
Acc2 =
case dialyzer_codeserver:lookup_mfa_contract(CbMFA, Codeserver) of
'error' -> Acc1;
- {ok, {{File, Line}, Contract}} ->
+ {ok, {{File, Line}, Contract, _Xtra}} ->
Acc10 = Acc1,
SpecReturnType0 = dialyzer_contracts:get_contract_return(Contract),
SpecArgTypes0 = dialyzer_contracts:get_contract_args(Contract),
@@ -189,7 +194,7 @@ find_mismatching_args(Kind, [Type|Rest], [CbType|CbRest], Behaviour,
Arity, Records, N+1, NewAcc)
end.
-add_tag_file_line(_Module, {Tag, [B|_R]} = Warn, State)
+add_tag_warning_info(Module, {Tag, [B|_R]} = Warn, State)
when Tag =:= callback_missing;
Tag =:= callback_info_missing ->
{B, Line} = lists:keyfind(B, 1, State#state.behlines),
@@ -198,18 +203,18 @@ add_tag_file_line(_Module, {Tag, [B|_R]} = Warn, State)
callback_missing -> ?WARN_BEHAVIOUR;
callback_info_missing -> ?WARN_UNDEFINED_CALLBACK
end,
- {Category, {State#state.filename, Line}, Warn};
-add_tag_file_line(_Module, {Tag, [File, Line|R]}, _State)
+ {Category, {State#state.filename, Line, Module}, Warn};
+add_tag_warning_info(Module, {Tag, [File, Line|R]}, _State)
when Tag =:= callback_spec_type_mismatch;
Tag =:= callback_spec_arg_type_mismatch ->
- {?WARN_BEHAVIOUR, {File, Line}, {Tag, R}};
-add_tag_file_line(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) ->
+ {?WARN_BEHAVIOUR, {File, Line, Module}, {Tag, R}};
+add_tag_warning_info(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) ->
{_A, FunCode} =
dialyzer_codeserver:lookup_mfa_code({Module, Fun, Arity},
State#state.codeserver),
Anns = cerl:get_ann(FunCode),
- FileLine = {get_file(Anns), get_line(Anns)},
- {?WARN_BEHAVIOUR, FileLine, Warn}.
+ WarningInfo = {get_file(Anns), get_line(Anns), {Module, Fun, Arity}},
+ {?WARN_BEHAVIOUR, WarningInfo, Warn}.
get_line([Line|_]) when is_integer(Line) -> Line;
get_line([_|Tail]) -> get_line(Tail);
diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl
index 00b01fbd36..9e53e171c0 100644
--- a/lib/dialyzer/src/dialyzer_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_callgraph.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -477,14 +478,37 @@ scan_one_core_fun(TopTree, FunName) ->
call ->
CalleeM = cerl:call_module(Tree),
CalleeF = cerl:call_name(Tree),
- A = length(cerl:call_args(Tree)),
+ CalleeArgs = cerl:call_args(Tree),
+ A = length(CalleeArgs),
case (cerl:is_c_atom(CalleeM) andalso
cerl:is_c_atom(CalleeF)) of
true ->
M = cerl:atom_val(CalleeM),
F = cerl:atom_val(CalleeF),
case erl_bif_types:is_known(M, F, A) of
- true -> Acc;
+ true ->
+ case {M, F, A} of
+ {erlang, make_fun, 3} ->
+ [CA1, CA2, CA3] = CalleeArgs,
+ case
+ cerl:is_c_atom(CA1) andalso
+ cerl:is_c_atom(CA2) andalso
+ cerl:is_c_int(CA3)
+ of
+ true ->
+ MM = cerl:atom_val(CA1),
+ FF = cerl:atom_val(CA2),
+ AA = cerl:int_val(CA3),
+ case erl_bif_types:is_known(MM, FF, AA) of
+ true -> Acc;
+ false -> [{FunName, {MM, FF, AA}}|Acc]
+ end;
+ false ->
+ Acc
+ end;
+ _ ->
+ Acc
+ end;
false -> [{FunName, {M, F, A}}|Acc]
end;
false ->
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index 3e7d9dfa99..9354b8007e 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -2,18 +2,19 @@
%%-------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,8 +49,7 @@
plt_info = none :: 'none' | dialyzer_plt:plt_info(),
report_mode = normal :: rep_mode(),
return_status= ?RET_NOTHING_SUSPICIOUS :: dial_ret(),
- stored_warnings = [] :: [dial_warning()],
- unknown_behaviours = [] :: [dialyzer_behaviours:behaviour()]
+ stored_warnings = [] :: [raw_warning()]
}).
%%--------------------------------------------------------------------
@@ -469,7 +469,7 @@ expand_dependent_modules(Md5, DiffMd5, ModDeps) ->
Mod = list_to_atom(filename:basename(File, ".beam")),
sets:is_element(Mod, AnalyzeMods)
end,
- {[F || {F, _} <- Md5, FilterFun(F)], RemovedMods, NewModDeps}.
+ {[F || {F, _} <- Md5, FilterFun(F)], BigSet, NewModDeps}.
expand_dependent_modules_1([Mod|Mods], Included, ModDeps) ->
case dict:find(Mod, ModDeps) of
@@ -512,32 +512,82 @@ hipe_compile(Files, #options{erlang_mode = ErlangMode} = Options) ->
dialyzer_worker],
report_native_comp(Options),
{T1, _} = statistics(wall_clock),
- native_compile(Mods),
+ Cache = (get(dialyzer_options_native_cache) =/= false),
+ native_compile(Mods, Cache),
{T2, _} = statistics(wall_clock),
report_elapsed_time(T1, T2, Options)
end
end.
-native_compile(Mods) ->
+native_compile(Mods, Cache) ->
case dialyzer_utils:parallelism() > ?MIN_PARALLELISM of
true ->
Parent = self(),
- Pids = [spawn(fun () -> Parent ! {self(), hc(M)} end) || M <- Mods],
+ Pids = [spawn(fun () -> Parent ! {self(), hc(M, Cache)} end) || M <- Mods],
lists:foreach(fun (Pid) -> receive {Pid, Res} -> Res end end, Pids);
false ->
- lists:foreach(fun (Mod) -> hc(Mod) end, Mods)
+ lists:foreach(fun (Mod) -> hc(Mod, Cache) end, Mods)
end.
-hc(Mod) ->
+hc(Mod, Cache) ->
{module, Mod} = code:ensure_loaded(Mod),
case code:is_module_native(Mod) of
true -> ok;
false ->
%% io:format(" ~w", [Mod]),
- {ok, Mod} = hipe:c(Mod),
- ok
+ case Cache of
+ false ->
+ {ok, Mod} = hipe:c(Mod),
+ ok;
+ true ->
+ hc_cache(Mod)
+ end
end.
+hc_cache(Mod) ->
+ CacheBase = cache_base_dir(),
+ %% Use HiPE architecture, version and erts checksum in directory name,
+ %% to avoid clashes between incompatible binaries.
+ HipeArchVersion =
+ lists:concat(
+ [erlang:system_info(hipe_architecture), "-",
+ hipe:version(), "-",
+ hipe:erts_checksum()]),
+ CacheDir = filename:join(CacheBase, HipeArchVersion),
+ OrigBeamFile = code:which(Mod),
+ {ok, {Mod, <<Checksum:128>>}} = beam_lib:md5(OrigBeamFile),
+ CachedBeamFile = filename:join(CacheDir, lists:concat([Mod, "-", Checksum, ".beam"])),
+ ok = filelib:ensure_dir(CachedBeamFile),
+ ModBin =
+ case filelib:is_file(CachedBeamFile) of
+ true ->
+ {ok, BinFromFile} = file:read_file(CachedBeamFile),
+ BinFromFile;
+ false ->
+ {ok, Mod, CompiledBin} = compile:file(OrigBeamFile, [from_beam, native, binary]),
+ ok = file:write_file(CachedBeamFile, CompiledBin),
+ CompiledBin
+ end,
+ code:unstick_dir(filename:dirname(OrigBeamFile)),
+ {module, Mod} = code:load_binary(Mod, CachedBeamFile, ModBin),
+ true = code:is_module_native(Mod),
+ ok.
+
+cache_base_dir() ->
+ %% http://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
+ %% If XDG_CACHE_HOME is set to an absolute path, use it as base.
+ XdgCacheHome = os:getenv("XDG_CACHE_HOME"),
+ CacheHome =
+ case is_list(XdgCacheHome) andalso filename:pathtype(XdgCacheHome) =:= absolute of
+ true ->
+ XdgCacheHome;
+ false ->
+ %% Otherwise, the default is $HOME/.cache.
+ {ok, [[Home]]} = init:get_argument(home),
+ filename:join(Home, ".cache")
+ end,
+ filename:join([CacheHome, "dialyzer_hipe_cache"]).
+
new_state() ->
#cl_state{}.
@@ -587,9 +637,6 @@ cl_loop(State, LogCache) ->
{BackendPid, warnings, Warnings} ->
NewState = store_warnings(State, Warnings),
cl_loop(NewState, LogCache);
- {BackendPid, unknown_behaviours, Behaviours} ->
- NewState = store_unknown_behaviours(State, Behaviours),
- cl_loop(NewState, LogCache);
{BackendPid, done, NewPlt, _NewDocPlt} ->
return_value(State, NewPlt);
{BackendPid, ext_calls, ExtCalls} ->
@@ -627,16 +674,11 @@ format_log_cache(LogCache) ->
Str = lists:append(lists:reverse(LogCache)),
string:join(string:tokens(Str, "\n"), "\n ").
--spec store_warnings(#cl_state{}, [dial_warning()]) -> #cl_state{}.
+-spec store_warnings(#cl_state{}, [raw_warning()]) -> #cl_state{}.
store_warnings(#cl_state{stored_warnings = StoredWarnings} = St, Warnings) ->
St#cl_state{stored_warnings = StoredWarnings ++ Warnings}.
--spec store_unknown_behaviours(#cl_state{}, [dialyzer_behaviours:behaviour()]) -> #cl_state{}.
-
-store_unknown_behaviours(#cl_state{unknown_behaviours = Behs} = St, Beh) ->
- St#cl_state{unknown_behaviours = Beh ++ Behs}.
-
-spec cl_error(string()) -> no_return().
cl_error(Msg) ->
@@ -656,15 +698,15 @@ return_value(State = #cl_state{erlang_mode = ErlangMode,
mod_deps = ModDeps,
output_plt = OutputPlt,
plt_info = PltInfo,
- stored_warnings = StoredWarnings,
- legal_warnings = LegalWarnings},
+ stored_warnings = StoredWarnings},
Plt) ->
case OutputPlt =:= none of
true -> ok;
false -> dialyzer_plt:to_file(OutputPlt, Plt, ModDeps, PltInfo)
end,
+ UnknownWarnings = unknown_warnings(State),
RetValue =
- case StoredWarnings =:= [] of
+ case StoredWarnings =:= [] andalso UnknownWarnings =:= [] of
true -> ?RET_NOTHING_SUSPICIOUS;
false -> ?RET_DISCREPANCIES
end,
@@ -673,37 +715,39 @@ return_value(State = #cl_state{erlang_mode = ErlangMode,
print_warnings(State),
print_ext_calls(State),
print_ext_types(State),
- print_unknown_behaviours(State),
maybe_close_output_file(State),
{RetValue, []};
true ->
- Unknown =
- case ordsets:is_element(?WARN_UNKNOWN, LegalWarnings) of
- true ->
- unknown_functions(State) ++
- unknown_types(State) ++
- unknown_behaviours(State);
- false -> []
- end,
- UnknownWarnings =
- [{?WARN_UNKNOWN, {_Filename = "", _Line = 0}, W} || W <- Unknown],
AllWarnings =
UnknownWarnings ++ process_warnings(StoredWarnings),
- {RetValue, AllWarnings}
+ {RetValue, set_warning_id(AllWarnings)}
end.
+unknown_warnings(State = #cl_state{legal_warnings = LegalWarnings}) ->
+ Unknown = case ordsets:is_element(?WARN_UNKNOWN, LegalWarnings) of
+ true ->
+ unknown_functions(State) ++
+ unknown_types(State);
+ false -> []
+ end,
+ WarningInfo = {_Filename = "", _Line = 0, _MorMFA = ''},
+ [{?WARN_UNKNOWN, WarningInfo, W} || W <- Unknown].
+
unknown_functions(#cl_state{external_calls = Calls}) ->
[{unknown_function, MFA} || MFA <- Calls].
+set_warning_id(Warnings) ->
+ lists:map(fun({Tag, {File, Line, _MorMFA}, Msg}) ->
+ {Tag, {File, Line}, Msg}
+ end, Warnings).
+
print_ext_calls(#cl_state{report_mode = quiet}) ->
ok;
print_ext_calls(#cl_state{output = Output,
external_calls = Calls,
stored_warnings = Warnings,
- output_format = Format,
- legal_warnings = LegalWarnings}) ->
- case not ordsets:is_element(?WARN_UNKNOWN, LegalWarnings)
- orelse Calls =:= [] of
+ output_format = Format}) ->
+ case Calls =:= [] of
true -> ok;
false ->
case Warnings =:= [] of
@@ -735,10 +779,8 @@ print_ext_types(#cl_state{output = Output,
external_calls = Calls,
external_types = Types,
stored_warnings = Warnings,
- output_format = Format,
- legal_warnings = LegalWarnings}) ->
- case not ordsets:is_element(?WARN_UNKNOWN, LegalWarnings)
- orelse Types =:= [] of
+ output_format = Format}) ->
+ case Types =:= [] of
true -> ok;
false ->
case Warnings =:= [] andalso Calls =:= [] of
@@ -761,48 +803,6 @@ do_print_ext_types(Output, [{M,F,A}|T], Before) ->
do_print_ext_types(_, [], _) ->
ok.
-unknown_behaviours(#cl_state{unknown_behaviours = DupBehaviours,
- legal_warnings = LegalWarnings}) ->
- case ordsets:is_element(?WARN_BEHAVIOUR, LegalWarnings) of
- false -> [];
- true ->
- Behaviours = lists:usort(DupBehaviours),
- [{unknown_behaviour, B} || B <- Behaviours]
- end.
-
-%%print_unknown_behaviours(#cl_state{report_mode = quiet}) ->
-%% ok;
-print_unknown_behaviours(#cl_state{output = Output,
- external_calls = Calls,
- external_types = Types,
- stored_warnings = Warnings,
- unknown_behaviours = DupBehaviours,
- legal_warnings = LegalWarnings,
- output_format = Format}) ->
- case ordsets:is_element(?WARN_BEHAVIOUR, LegalWarnings)
- andalso DupBehaviours =/= [] of
- false -> ok;
- true ->
- Behaviours = lists:usort(DupBehaviours),
- case Warnings =:= [] andalso Calls =:= [] andalso Types =:= [] of
- true -> io:nl(Output); %% Need to do a newline first
- false -> ok
- end,
- {Prompt, Prefix} =
- case Format of
- formatted -> {"Unknown behaviours:\n"," "};
- raw -> {"%% Unknown behaviours:\n","%% "}
- end,
- io:put_chars(Output, Prompt),
- do_print_unknown_behaviours(Output, Behaviours, Prefix)
- end.
-
-do_print_unknown_behaviours(Output, [B|T], Before) ->
- io:format(Output, "~s~p\n", [Before,B]),
- do_print_unknown_behaviours(Output, T, Before);
-do_print_unknown_behaviours(_, [], _) ->
- ok.
-
print_warnings(#cl_state{stored_warnings = []}) ->
ok;
print_warnings(#cl_state{output = Output,
@@ -817,15 +817,16 @@ print_warnings(#cl_state{output = Output,
formatted ->
[dialyzer:format_warning(W, FOpt) || W <- PrWarnings];
raw ->
- [io_lib:format("~p. \n", [W]) || W <- PrWarnings]
+ [io_lib:format("~p. \n",
+ [W]) || W <- set_warning_id(PrWarnings)]
end,
io:format(Output, "\n~s", [S])
end.
--spec process_warnings([dial_warning()]) -> [dial_warning()].
+-spec process_warnings([raw_warning()]) -> [raw_warning()].
process_warnings(Warnings) ->
- Warnings1 = lists:keysort(2, Warnings), %% Sort on file/line
+ Warnings1 = lists:keysort(2, Warnings), %% Sort on file/line (and m/mfa..)
remove_duplicate_warnings(Warnings1, []).
remove_duplicate_warnings([Duplicate, Duplicate|Left], Acc) ->
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index 04ce0e8bc3..934351aeeb 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -75,6 +76,9 @@ cl(["-nn"|T]) ->
cl(["--no_native"|T]) ->
put(dialyzer_options_native, false),
cl(T);
+cl(["--no_native_cache"|T]) ->
+ put(dialyzer_options_native_cache, false),
+ cl(T);
cl(["--plt_info"|T]) ->
put(dialyzer_options_analysis_type, plt_info),
cl(T);
@@ -363,7 +367,7 @@ help_message() ->
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
[--dump_callgraph file] [--no_native] [--fullpath]
- [--statistics]
+ [--statistics] [--no_native_cache]
Options:
files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
Use Dialyzer from the command line to detect defects in the
@@ -468,6 +472,11 @@ Options:
Bypass the native code compilation of some key files that Dialyzer
heuristically performs when dialyzing many files; this avoids the
compilation time but it may result in (much) longer analysis time.
+ --no_native_cache
+ By default, Dialyzer caches the results of native compilation in the
+ $XDG_CACHE_HOME/erlang/dialyzer_hipe_cache directory.
+ XDG_CACHE_HOME defaults to $HOME/.cache. Use this option to disable
+ caching.
--fullpath
Display the full path names of files for which warnings are emitted.
--gui
@@ -509,6 +518,8 @@ warning_options_msg() ->
-Wno_behaviours
Suppress warnings about behaviour callbacks which drift from the published
recommended interfaces.
+ -Wno_missing_calls
+ Suppress warnings about calls to missing functions.
-Wno_undefined_callbacks
Suppress warnings about behaviours that have no -callback attributes for
their callbacks.
@@ -522,6 +533,13 @@ warning_options_msg() ->
-Wunderspecs ***
Warn about underspecified functions
(those whose -spec is strictly more allowing than the success typing).
+ -Wunknown ***
+ Let warnings about unknown functions and types affect the
+ exit status of the command line version. The default is to ignore
+ warnings about unknown functions and types when setting the exit
+ status. When using the Dialyzer from Erlang, warnings about unknown
+ functions and types are returned; the default is not to return
+ such warnings.
The following options are also available but their use is not recommended:
(they are mostly for Dialyzer developers and internal debugging)
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index aab3d6add6..978ecd3843 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -43,19 +44,21 @@
insert/3,
insert_exports/2,
insert_temp_exported_types/2,
+ insert_fun_meta_info/2,
is_exported/2,
lookup_mod_code/2,
lookup_mfa_code/2,
lookup_mod_records/2,
lookup_mod_contracts/2,
lookup_mfa_contract/2,
+ lookup_meta_info/2,
new/0,
set_next_core_label/2,
set_temp_records/2,
store_temp_records/3,
store_temp_contracts/4]).
--export_type([codeserver/0]).
+-export_type([codeserver/0, fun_meta_info/0]).
-include("dialyzer.hrl").
@@ -70,12 +73,19 @@
-type contracts() :: dict:dict(mfa(),dialyzer_contracts:file_contract()).
-type mod_contracts() :: dict:dict(module(), contracts()).
+%% A property-list of data compiled from -compile and -dialyzer attributes.
+-type meta_info() :: [{{'nowarn_function' | dial_warn_tag()},
+ 'mod' | 'func'}].
+-type fun_meta_info() :: [{mfa(), meta_info()}
+ | {module(), [dial_warn_tag()]}].
+
-record(codeserver, {next_core_label = 0 :: label(),
code :: dict_ets(),
exported_types :: set_ets(), % set(mfa())
records :: dict_ets(),
contracts :: dict_ets(),
callbacks :: dict_ets(),
+ fun_meta_info :: dict_ets(), % {mfa(), meta_info()}
exports :: 'clean' | set_ets(), % set(mfa())
temp_exported_types :: 'clean' | set_ets(), % set(mfa())
temp_records :: 'clean' | dict_ets(),
@@ -129,14 +139,17 @@ new() ->
CodeOptions = [compressed, public, {read_concurrency, true}],
Code = ets:new(dialyzer_codeserver_code, CodeOptions),
TempOptions = [public, {write_concurrency, true}],
- [Exports, TempExportedTypes, TempRecords, TempContracts, TempCallbacks] =
+ [Exports, FunMetaInfo, TempExportedTypes, TempRecords, TempContracts,
+ TempCallbacks] =
[ets:new(Name, TempOptions) ||
Name <-
- [dialyzer_codeserver_exports, dialyzer_codeserver_temp_exported_types,
+ [dialyzer_codeserver_exports, dialyzer_codeserver_fun_meta_info,
+ dialyzer_codeserver_temp_exported_types,
dialyzer_codeserver_temp_records, dialyzer_codeserver_temp_contracts,
dialyzer_codeserver_temp_callbacks]],
#codeserver{code = Code,
exports = Exports,
+ fun_meta_info = FunMetaInfo,
temp_exported_types = TempExportedTypes,
temp_records = TempRecords,
temp_contracts = TempContracts,
@@ -184,6 +197,12 @@ insert_exports(List, #codeserver{exports = Exports} = CS) ->
true = ets_set_insert_list(List, Exports),
CS.
+-spec insert_fun_meta_info(fun_meta_info(), codeserver()) -> codeserver().
+
+insert_fun_meta_info(List, #codeserver{fun_meta_info = FunMetaInfo} = CS) ->
+ true = ets:insert(FunMetaInfo, List),
+ CS.
+
-spec is_exported(mfa(), codeserver()) -> boolean().
is_exported(MFA, #codeserver{exports = Exports}) ->
@@ -278,10 +297,10 @@ lookup_mod_contracts(Mod, #codeserver{contracts = ContDict})
case ets_dict_find(Mod, ContDict) of
error -> dict:new();
{ok, Keys} ->
- dict:from_list([get_contract_pair(Key, ContDict)|| Key <- Keys])
+ dict:from_list([get_file_contract(Key, ContDict)|| Key <- Keys])
end.
-get_contract_pair(Key, ContDict) ->
+get_file_contract(Key, ContDict) ->
{Key, ets:lookup_element(ContDict, Key, 2)}.
-spec lookup_mfa_contract(mfa(), codeserver()) ->
@@ -290,6 +309,14 @@ get_contract_pair(Key, ContDict) ->
lookup_mfa_contract(MFA, #codeserver{contracts = ContDict}) ->
ets_dict_find(MFA, ContDict).
+-spec lookup_meta_info(module() | mfa(), codeserver()) -> meta_info().
+
+lookup_meta_info(MorMFA, #codeserver{fun_meta_info = FunMetaInfo}) ->
+ case ets_dict_find(MorMFA, FunMetaInfo) of
+ error -> [];
+ {ok, PropList} -> PropList
+ end.
+
-spec get_contracts(codeserver()) -> mod_contracts().
get_contracts(#codeserver{contracts = ContDict}) ->
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index f27fc1a842..7251de8b10 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -43,9 +44,9 @@
%% Types used in other parts of the system below
%%-----------------------------------------------------------------------
--type file_contract() :: {file_line(), #contract{}}.
+-type file_contract() :: {file_line(), #contract{}, Extra :: [_]}.
--type plt_contracts() :: [{mfa(), #contract{}}]. % actually, an orddict()
+-type plt_contracts() :: orddict:orddict(mfa(), #contract{}).
%%-----------------------------------------------------------------------
%% Internal record for contracts whose components have not been processed
@@ -146,10 +147,10 @@ process_contract_remote_types(CodeServer) ->
ExpTypes = dialyzer_codeserver:get_exported_types(CodeServer),
RecordDict = dialyzer_codeserver:get_records(CodeServer),
ContractFun =
- fun({_M, _F, _A}, {File, #tmp_contract{contract_funs = CFuns, forms = Forms}}) ->
+ fun({_M, _F, _A}, {File, #tmp_contract{contract_funs = CFuns, forms = Forms}, Xtra}) ->
NewCs = [CFun(ExpTypes, RecordDict) || CFun <- CFuns],
Args = general_domain(NewCs),
- {File, #contract{contracts = NewCs, args = Args, forms = Forms}}
+ {File, #contract{contracts = NewCs, args = Args, forms = Forms}, Xtra}
end,
ModuleFun =
fun(_ModuleName, ContractDict) ->
@@ -175,7 +176,7 @@ check_contracts(Contracts, Callgraph, FunTypes, FindOpaques) ->
case dialyzer_callgraph:lookup_name(Label, Callgraph) of
{ok, {M,F,A} = MFA} ->
case orddict:find(MFA, Contracts) of
- {ok, {_FileLine, Contract}} ->
+ {ok, {_FileLine, Contract, _Xtra}} ->
Opaques = FindOpaques(M),
case check_contract(Contract, Type, Opaques) of
ok ->
@@ -351,7 +352,7 @@ solve_constraints(Contract, Call, Constraints) ->
%% Checks the contracts for functions that are not implemented
-spec contracts_without_fun(contracts(), [_], dialyzer_callgraph:callgraph()) ->
- [dial_warning()].
+ [raw_warning()].
contracts_without_fun(Contracts, AllFuns0, Callgraph) ->
AllFuns1 = [{dialyzer_callgraph:lookup_name(Label, Callgraph), Arity}
@@ -362,8 +363,9 @@ contracts_without_fun(Contracts, AllFuns0, Callgraph) ->
[warn_spec_missing_fun(MFA, Contracts) || MFA <- ErrorContractMFAs].
warn_spec_missing_fun({M, F, A} = MFA, Contracts) ->
- {FileLine, _Contract} = dict:fetch(MFA, Contracts),
- {?WARN_CONTRACT_SYNTAX, FileLine, {spec_missing_fun, [M, F, A]}}.
+ {{File, Line}, _Contract, _Xtra} = dict:fetch(MFA, Contracts),
+ WarningInfo = {File, Line, MFA},
+ {?WARN_CONTRACT_SYNTAX, WarningInfo, {spec_missing_fun, [M, F, A]}}.
%% This treats the "when" constraints. It will be extended, we hope.
insert_constraints([{subtype, Type1, Type2}|Left], Dict) ->
@@ -386,26 +388,28 @@ insert_constraints([], Dict) -> Dict.
-type types() :: erl_types:type_table().
--spec store_tmp_contract(mfa(), file_line(), [_], contracts(), types()) ->
+-type spec_data() :: {TypeSpec :: [_], Xtra:: [_]}.
+
+-spec store_tmp_contract(mfa(), file_line(), spec_data(), contracts(), types()) ->
contracts().
-store_tmp_contract(MFA, FileLine, TypeSpec, SpecDict, RecordsDict) ->
+store_tmp_contract(MFA, FileLine, {TypeSpec, Xtra}, SpecDict, RecordsDict) ->
%% io:format("contract from form: ~p\n", [TypeSpec]),
- TmpContract = contract_from_form(TypeSpec, RecordsDict, FileLine),
+ TmpContract = contract_from_form(TypeSpec, MFA, RecordsDict, FileLine),
%% io:format("contract: ~p\n", [TmpContract]),
- dict:store(MFA, {FileLine, TmpContract}, SpecDict).
+ dict:store(MFA, {FileLine, TmpContract, Xtra}, SpecDict).
-contract_from_form(Forms, RecDict, FileLine) ->
- {CFuns, Forms1} = contract_from_form(Forms, RecDict, FileLine, [], []),
+contract_from_form(Forms, MFA, RecDict, FileLine) ->
+ {CFuns, Forms1} = contract_from_form(Forms, MFA, RecDict, FileLine, [], []),
#tmp_contract{contract_funs = CFuns, forms = Forms1}.
-contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], RecDict,
+contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], MFA, RecDict,
FileLine, TypeAcc, FormAcc) ->
TypeFun =
fun(ExpTypes, AllRecords) ->
- Type =
+ NewType =
try
- erl_types:t_from_form(Form, RecDict)
+ from_form_with_check(Form, ExpTypes, MFA, AllRecords)
catch
throw:{error, Msg} ->
{File, Line} = FileLine,
@@ -413,61 +417,60 @@ contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], RecDict,
Line, Msg]),
throw({error, NewMsg})
end,
- NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords),
NewTypeNoVars = erl_types:subst_all_vars_to_any(NewType),
{NewTypeNoVars, []}
end,
NewTypeAcc = [TypeFun | TypeAcc],
NewFormAcc = [{Form, []} | FormAcc],
- contract_from_form(Left, RecDict, FileLine, NewTypeAcc, NewFormAcc);
+ contract_from_form(Left, MFA, RecDict, FileLine, NewTypeAcc, NewFormAcc);
contract_from_form([{type, _L1, bounded_fun,
[{type, _L2, 'fun', [_, _]} = Form, Constr]}| Left],
- RecDict, FileLine, TypeAcc, FormAcc) ->
+ MFA, RecDict, FileLine, TypeAcc, FormAcc) ->
TypeFun =
fun(ExpTypes, AllRecords) ->
{Constr1, VarDict} =
- process_constraints(Constr, RecDict, ExpTypes, AllRecords),
- Type = erl_types:t_from_form(Form, RecDict, VarDict),
- NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords),
+ process_constraints(Constr, MFA, RecDict, ExpTypes, AllRecords),
+ NewType = from_form_with_check(Form, ExpTypes, MFA, AllRecords,
+ VarDict),
NewTypeNoVars = erl_types:subst_all_vars_to_any(NewType),
{NewTypeNoVars, Constr1}
end,
NewTypeAcc = [TypeFun | TypeAcc],
NewFormAcc = [{Form, Constr} | FormAcc],
- contract_from_form(Left, RecDict, FileLine, NewTypeAcc, NewFormAcc);
-contract_from_form([], _RecDict, _FileLine, TypeAcc, FormAcc) ->
+ contract_from_form(Left, MFA, RecDict, FileLine, NewTypeAcc, NewFormAcc);
+contract_from_form([], _MFA, _RecDict, _FileLine, TypeAcc, FormAcc) ->
{lists:reverse(TypeAcc), lists:reverse(FormAcc)}.
-process_constraints(Constrs, RecDict, ExpTypes, AllRecords) ->
- Init0 = initialize_constraints(Constrs, RecDict, ExpTypes, AllRecords),
+process_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords) ->
+ Init0 = initialize_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords),
Init = remove_cycles(Init0),
- constraints_fixpoint(Init, RecDict, ExpTypes, AllRecords).
+ constraints_fixpoint(Init, MFA, RecDict, ExpTypes, AllRecords).
-initialize_constraints(Constrs, RecDict, ExpTypes, AllRecords) ->
- initialize_constraints(Constrs, RecDict, ExpTypes, AllRecords, []).
+initialize_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords) ->
+ initialize_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords, []).
-initialize_constraints([], _RecDict, _ExpTypes, _AllRecords, Acc) ->
+initialize_constraints([], _MFA, _RecDict, _ExpTypes, _AllRecords, Acc) ->
Acc;
-initialize_constraints([Constr|Rest], RecDict, ExpTypes, AllRecords, Acc) ->
+initialize_constraints([Constr|Rest], MFA, RecDict, ExpTypes, AllRecords, Acc) ->
case Constr of
{type, _, constraint, [{atom, _, is_subtype}, [Type1, Type2]]} ->
- T1 = final_form(Type1, RecDict, ExpTypes, AllRecords, dict:new()),
+ T1 = final_form(Type1, ExpTypes, MFA, AllRecords, dict:new()),
Entry = {T1, Type2},
- initialize_constraints(Rest, RecDict, ExpTypes, AllRecords, [Entry|Acc]);
+ initialize_constraints(Rest, MFA, RecDict, ExpTypes, AllRecords, [Entry|Acc]);
{type, _, constraint, [{atom,_,Name}, List]} ->
N = length(List),
throw({error,
io_lib:format("Unsupported type guard ~w/~w\n", [Name, N])})
end.
-constraints_fixpoint(Constrs, RecDict, ExpTypes, AllRecords) ->
+constraints_fixpoint(Constrs, MFA, RecDict, ExpTypes, AllRecords) ->
VarDict =
- constraints_to_dict(Constrs, RecDict, ExpTypes, AllRecords, dict:new()),
- constraints_fixpoint(VarDict, Constrs, RecDict, ExpTypes, AllRecords).
+ constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, dict:new()),
+ constraints_fixpoint(VarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords).
-constraints_fixpoint(OldVarDict, Constrs, RecDict, ExpTypes, AllRecords) ->
+constraints_fixpoint(OldVarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords) ->
NewVarDict =
- constraints_to_dict(Constrs, RecDict, ExpTypes, AllRecords, OldVarDict),
+ constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, OldVarDict),
case NewVarDict of
OldVarDict ->
DictFold =
@@ -477,25 +480,33 @@ constraints_fixpoint(OldVarDict, Constrs, RecDict, ExpTypes, AllRecords) ->
FinalConstrs = dict:fold(DictFold, [], NewVarDict),
{FinalConstrs, NewVarDict};
_Other ->
- constraints_fixpoint(NewVarDict, Constrs, RecDict, ExpTypes, AllRecords)
+ constraints_fixpoint(NewVarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords)
end.
-final_form(Form, RecDict, ExpTypes, AllRecords, VarDict) ->
- T1 = erl_types:t_from_form(Form, RecDict, VarDict),
- erl_types:t_solve_remote(T1, ExpTypes, AllRecords).
+final_form(Form, ExpTypes, MFA, AllRecords, VarDict) ->
+ from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarDict).
+
+from_form_with_check(Form, ExpTypes, MFA, AllRecords) ->
+ from_form_with_check(Form, ExpTypes, MFA, AllRecords, dict:new()).
+
+from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarDict) ->
+ Site = {spec, MFA},
+ erl_types:t_check_record_fields(Form, ExpTypes, Site, AllRecords,
+ VarDict),
+ erl_types:t_from_form(Form, ExpTypes, Site, AllRecords, VarDict).
-constraints_to_dict(Constrs, RecDict, ExpTypes, AllRecords, VarDict) ->
+constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, VarDict) ->
Subtypes =
- constraints_to_subs(Constrs, RecDict, ExpTypes, AllRecords, VarDict, []),
+ constraints_to_subs(Constrs, MFA, RecDict, ExpTypes, AllRecords, VarDict, []),
insert_constraints(Subtypes, dict:new()).
-constraints_to_subs([], _RecDict, _ExpTypes, _AllRecords, _VarDict, Acc) ->
+constraints_to_subs([], _MFA, _RecDict, _ExpTypes, _AllRecords, _VarDict, Acc) ->
Acc;
-constraints_to_subs([C|Rest], RecDict, ExpTypes, AllRecords, VarDict, Acc) ->
+constraints_to_subs([C|Rest], MFA, RecDict, ExpTypes, AllRecords, VarDict, Acc) ->
{T1, Form2} = C,
- T2 = final_form(Form2, RecDict, ExpTypes, AllRecords, VarDict),
+ T2 = final_form(Form2, ExpTypes, MFA, AllRecords, VarDict),
NewAcc = [{subtype, T1, T2}|Acc],
- constraints_to_subs(Rest, RecDict, ExpTypes, AllRecords, VarDict, NewAcc).
+ constraints_to_subs(Rest, MFA, RecDict, ExpTypes, AllRecords, VarDict, NewAcc).
%% Replaces variables with '_' when necessary to break up cycles among
%% the constraints.
@@ -583,7 +594,7 @@ general_domain([], AccSig) ->
-spec get_invalid_contract_warnings([module()],
dialyzer_codeserver:codeserver(),
dialyzer_plt:plt(),
- opaques_fun()) -> [dial_warning()].
+ opaques_fun()) -> [raw_warning()].
get_invalid_contract_warnings(Modules, CodeServer, Plt, FindOpaques) ->
get_invalid_contract_warnings_modules(Modules, CodeServer, Plt, FindOpaques, []).
@@ -597,7 +608,7 @@ get_invalid_contract_warnings_modules([Mod|Mods], CodeServer, Plt, FindOpaques,
get_invalid_contract_warnings_modules([], _CodeServer, _Plt, _FindOpaques, Acc) ->
Acc.
-get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
+get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left],
Plt, RecDict, FindOpaques, Acc) ->
case dialyzer_plt:lookup(Plt, MFA) of
none ->
@@ -607,16 +618,18 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
Sig = erl_types:t_fun(Args, Ret),
{M, _F, _A} = MFA,
Opaques = FindOpaques(M),
+ {File, Line} = FileLine,
+ WarningInfo = {File, Line, MFA},
NewAcc =
case check_contract(Contract, Sig, Opaques) of
{error, invalid_contract} ->
- [invalid_contract_warning(MFA, FileLine, Sig, RecDict)|Acc];
+ [invalid_contract_warning(MFA, WarningInfo, Sig, RecDict)|Acc];
{error, {overlapping_contract, []}} ->
- [overlapping_contract_warning(MFA, FileLine)|Acc];
+ [overlapping_contract_warning(MFA, WarningInfo)|Acc];
{error, {extra_range, ExtraRanges, STRange}} ->
Warn =
case t_from_forms_without_remote(Contract#contract.forms,
- RecDict) of
+ MFA, RecDict) of
{ok, NoRemoteType} ->
CRet = erl_types:t_fun_range(NoRemoteType),
erl_types:t_is_subtype(ExtraRanges, CRet);
@@ -625,12 +638,12 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
end,
case Warn of
true ->
- [extra_range_warning(MFA, FileLine, ExtraRanges, STRange)|Acc];
+ [extra_range_warning(MFA, WarningInfo, ExtraRanges, STRange)|Acc];
false ->
Acc
end;
{error, Msg} ->
- [{?WARN_CONTRACT_SYNTAX, FileLine, Msg}|Acc];
+ [{?WARN_CONTRACT_SYNTAX, WarningInfo, Msg}|Acc];
ok ->
{M, F, A} = MFA,
CSig0 = get_contract_signature(Contract),
@@ -644,14 +657,14 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
BifSig = erl_types:t_fun(BifArgs, BifRet),
case check_contract(Contract, BifSig, Opaques) of
{error, _} ->
- [invalid_contract_warning(MFA, FileLine, BifSig, RecDict)
+ [invalid_contract_warning(MFA, WarningInfo, BifSig, RecDict)
|Acc];
ok ->
- picky_contract_check(CSig, BifSig, MFA, FileLine,
+ picky_contract_check(CSig, BifSig, MFA, WarningInfo,
Contract, RecDict, Acc)
end;
false ->
- picky_contract_check(CSig, Sig, MFA, FileLine, Contract,
+ picky_contract_check(CSig, Sig, MFA, WarningInfo, Contract,
RecDict, Acc)
end
end,
@@ -660,20 +673,20 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
get_invalid_contract_warnings_funs([], _Plt, _RecDict, _FindOpaques, Acc) ->
Acc.
-invalid_contract_warning({M, F, A}, FileLine, SuccType, RecDict) ->
+invalid_contract_warning({M, F, A}, WarningInfo, SuccType, RecDict) ->
SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
- {?WARN_CONTRACT_TYPES, FileLine, {invalid_contract, [M, F, A, SuccTypeStr]}}.
+ {?WARN_CONTRACT_TYPES, WarningInfo, {invalid_contract, [M, F, A, SuccTypeStr]}}.
-overlapping_contract_warning({M, F, A}, FileLine) ->
- {?WARN_CONTRACT_TYPES, FileLine, {overlapping_contract, [M, F, A]}}.
+overlapping_contract_warning({M, F, A}, WarningInfo) ->
+ {?WARN_CONTRACT_TYPES, WarningInfo, {overlapping_contract, [M, F, A]}}.
-extra_range_warning({M, F, A}, FileLine, ExtraRanges, STRange) ->
+extra_range_warning({M, F, A}, WarningInfo, ExtraRanges, STRange) ->
ERangesStr = erl_types:t_to_string(ExtraRanges),
STRangeStr = erl_types:t_to_string(STRange),
- {?WARN_CONTRACT_SUPERTYPE, FileLine,
+ {?WARN_CONTRACT_SUPERTYPE, WarningInfo,
{extra_range, [M, F, A, ERangesStr, STRangeStr]}}.
-picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) ->
+picky_contract_check(CSig0, Sig0, MFA, WarningInfo, Contract, RecDict, Acc) ->
CSig = erl_types:t_abstract_records(CSig0, RecDict),
Sig = erl_types:t_abstract_records(Sig0, RecDict),
case erl_types:t_is_equal(CSig, Sig) of
@@ -683,7 +696,7 @@ picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) ->
erl_types:t_is_unit(erl_types:t_fun_range(CSig))) of
true -> Acc;
false ->
- case extra_contract_warning(MFA, FileLine, Contract,
+ case extra_contract_warning(MFA, WarningInfo, Contract,
CSig0, Sig0, RecDict) of
no_warning -> Acc;
{warning, Warning} -> [Warning|Acc]
@@ -691,7 +704,7 @@ picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) ->
end
end.
-extra_contract_warning({M, F, A}, FileLine, Contract, CSig, Sig, RecDict) ->
+extra_contract_warning(MFA, WarningInfo, Contract, CSig, Sig, RecDict) ->
%% We do not want to depend upon erl_types:t_to_string() possibly
%% hiding the contents of opaque types.
SigUnopaque = erl_types:t_unopaque(Sig),
@@ -703,11 +716,12 @@ extra_contract_warning({M, F, A}, FileLine, Contract, CSig, Sig, RecDict) ->
%% The only difference is in record fields containing 'undefined' or not.
IsUndefRecordFieldsRelated = SigString0 =:= ContractString0,
{IsRemoteTypesRelated, SubtypeRelation} =
- is_remote_types_related(Contract, CSig, Sig, RecDict),
+ is_remote_types_related(Contract, CSig, Sig, MFA, RecDict),
case IsUndefRecordFieldsRelated orelse IsRemoteTypesRelated of
true ->
no_warning;
false ->
+ {M, F, A} = MFA,
SigString = lists:flatten(dialyzer_utils:format_sig(Sig, RecDict)),
ContractString = contract_to_string(Contract),
{Tag, Msg} =
@@ -722,17 +736,18 @@ extra_contract_warning({M, F, A}, FileLine, Contract, CSig, Sig, RecDict) ->
{?WARN_CONTRACT_NOT_EQUAL,
{contract_diff, [M, F, A, ContractString, SigString]}}
end,
- {warning, {Tag, FileLine, Msg}}
+ {warning, {Tag, WarningInfo, Msg}}
end.
-is_remote_types_related(Contract, CSig, Sig, RecDict) ->
+is_remote_types_related(Contract, CSig, Sig, MFA, RecDict) ->
case erl_types:t_is_subtype(CSig, Sig) of
true ->
{false, contract_is_subtype};
false ->
case erl_types:t_is_subtype(Sig, CSig) of
true ->
- case t_from_forms_without_remote(Contract#contract.forms, RecDict) of
+ case t_from_forms_without_remote(Contract#contract.forms, MFA,
+ RecDict) of
{ok, NoRemoteTypeSig} ->
case blame_remote(CSig, NoRemoteTypeSig, Sig) of
true ->
@@ -748,14 +763,14 @@ is_remote_types_related(Contract, CSig, Sig, RecDict) ->
end
end.
-t_from_forms_without_remote([{FType, []}], RecDict) ->
- Type0 = erl_types:t_from_form(FType, RecDict),
- Type1 = erl_types:subst_all_remote(Type0, erl_types:t_none()),
+t_from_forms_without_remote([{FType, []}], MFA, RecDict) ->
+ Site = {spec, MFA},
+ Type1 = erl_types:t_from_form_without_remote(FType, Site, RecDict),
{ok, erl_types:subst_all_vars_to_any(Type1)};
-t_from_forms_without_remote([{_FType, _Constrs}], _RecDict) ->
+t_from_forms_without_remote([{_FType, _Constrs}], _MFA, _RecDict) ->
%% 'When' constraints
unsupported;
-t_from_forms_without_remote(_Forms, _RecDict) ->
+t_from_forms_without_remote(_Forms, _MFA, _RecDict) ->
%% Lots of forms
unsupported.
diff --git a/lib/dialyzer/src/dialyzer_coordinator.erl b/lib/dialyzer/src/dialyzer_coordinator.erl
index c3b7ce29af..612f379d32 100644
--- a/lib/dialyzer/src/dialyzer_coordinator.erl
+++ b/lib/dialyzer/src/dialyzer_coordinator.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index 3cdbf3569a..cabc5e9e0d 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -2,18 +2,19 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,14 +29,15 @@
-module(dialyzer_dataflow).
--export([get_fun_types/4, get_warnings/5, format_args/3]).
+-export([get_fun_types/5, get_warnings/5, format_args/3]).
%% Data structure interfaces.
-export([state__add_warning/2, state__cleanup/1,
state__duplicate/1, dispose_state/1,
state__get_callgraph/1, state__get_races/1,
state__get_records/1, state__put_callgraph/2,
- state__put_races/2, state__records_only/1]).
+ state__put_races/2, state__records_only/1,
+ state__find_function/2]).
-export_type([state/0]).
@@ -89,6 +91,8 @@
-type type() :: erl_types:erl_type().
-type types() :: erl_types:type_table().
+-type curr_fun() :: 'undefined' | 'top' | mfa_or_funlbl().
+
-define(no_arg, no_arg).
-define(TYPE_LIMIT, 3).
@@ -96,17 +100,20 @@
-define(BITS, 128).
-record(state, {callgraph :: dialyzer_callgraph:callgraph(),
+ codeserver :: dialyzer_codeserver:codeserver(),
envs :: env_tab(),
fun_tab :: fun_tab(),
+ fun_homes :: dict:dict(label(), mfa()),
plt :: dialyzer_plt:plt(),
opaques :: [type()],
races = dialyzer_races:new() :: dialyzer_races:races(),
records = dict:new() :: types(),
tree_map :: dict:dict(label(), cerl:cerl()),
warning_mode = false :: boolean(),
- warnings = [] :: [dial_warning()],
+ warnings = [] :: [raw_warning()],
work :: {[_], [_], sets:set()},
- module :: module()
+ module :: module(),
+ curr_fun :: curr_fun()
}).
-record(map, {dict = dict:new() :: type_tab(),
@@ -115,7 +122,6 @@
modified_stack = [] :: [{[Key :: term()],reference()}],
ref = undefined :: reference() | undefined}).
--type nowarn() :: dialyzer_analysis_callgraph:no_warn_unused().
-type env_tab() :: dict:dict(label(), #map{}).
-type fun_entry() :: {Args :: [type()], RetType :: type()}.
-type fun_tab() :: dict:dict('top' | label(),
@@ -133,22 +139,24 @@
-type fun_types() :: dict:dict(label(), type()).
-spec get_warnings(cerl:c_module(), dialyzer_plt:plt(),
- dialyzer_callgraph:callgraph(), types(), nowarn()) ->
- {[dial_warning()], fun_types()}.
-
-get_warnings(Tree, Plt, Callgraph, Records, NoWarnUnused) ->
- State1 = analyze_module(Tree, Plt, Callgraph, Records, true),
- State2 =
- state__renew_warnings(state__get_warnings(State1, NoWarnUnused), State1),
+ dialyzer_callgraph:callgraph(),
+ dialyzer_codeserver:codeserver(),
+ types()) ->
+ {[raw_warning()], fun_types()}.
+
+get_warnings(Tree, Plt, Callgraph, Codeserver, Records) ->
+ State1 = analyze_module(Tree, Plt, Callgraph, Codeserver, Records, true),
+ State2 = state__renew_warnings(state__get_warnings(State1), State1),
State3 = state__get_race_warnings(State2),
{State3#state.warnings, state__all_fun_types(State3)}.
-spec get_fun_types(cerl:c_module(), dialyzer_plt:plt(),
dialyzer_callgraph:callgraph(),
+ dialyzer_codeserver:codeserver(),
types()) -> fun_types().
-get_fun_types(Tree, Plt, Callgraph, Records) ->
- State = analyze_module(Tree, Plt, Callgraph, Records, false),
+get_fun_types(Tree, Plt, Callgraph, Codeserver, Records) ->
+ State = analyze_module(Tree, Plt, Callgraph, Codeserver, Records, false),
state__all_fun_types(State).
%%% ===========================================================================
@@ -157,11 +165,11 @@ get_fun_types(Tree, Plt, Callgraph, Records) ->
%%%
%%% ===========================================================================
-analyze_module(Tree, Plt, Callgraph, Records, GetWarnings) ->
+analyze_module(Tree, Plt, Callgraph, Codeserver, Records, GetWarnings) ->
debug_pp(Tree, false),
Module = cerl:atom_val(cerl:module_name(Tree)),
TopFun = cerl:ann_c_fun([{label, top}], [], Tree),
- State = state__new(Callgraph, TopFun, Plt, Module, Records),
+ State = state__new(Callgraph, Codeserver, TopFun, Plt, Module, Records),
State1 = state__race_analysis(not GetWarnings, State),
State2 = analyze_loop(State1),
case GetWarnings of
@@ -175,25 +183,26 @@ analyze_module(Tree, Plt, Callgraph, Records, GetWarnings) ->
analyze_loop(State) ->
case state__get_work(State) of
- none -> State;
- {Fun, NewState1} ->
+ none -> state__set_curr_fun(undefined, State);
+ {Fun, NewState0} ->
+ NewState1 = state__set_curr_fun(get_label(Fun), NewState0),
{ArgTypes, IsCalled} = state__get_args_and_status(Fun, NewState1),
case not IsCalled of
true ->
?debug("Not handling (not called) ~w: ~s\n",
- [state__lookup_name(get_label(Fun), State),
+ [NewState1#state.curr_fun,
t_to_string(t_product(ArgTypes))]),
analyze_loop(NewState1);
false ->
case state__fun_env(Fun, NewState1) of
none ->
?debug("Not handling (no env) ~w: ~s\n",
- [state__lookup_name(get_label(Fun), State),
+ [NewState1#state.curr_fun,
t_to_string(t_product(ArgTypes))]),
analyze_loop(NewState1);
Map ->
?debug("Handling fun ~p: ~s\n",
- [state__lookup_name(get_label(Fun), State),
+ [NewState1#state.curr_fun,
t_to_string(state__fun_type(Fun, NewState1))]),
Vars = cerl:fun_vars(Fun),
Map1 = enter_type_lists(Vars, ArgTypes, Map),
@@ -212,7 +221,7 @@ analyze_loop(State) ->
{NewState4, _Map2, BodyType} =
traverse(Body, Map1, NewState3),
?debug("Done analyzing: ~w:~s\n",
- [state__lookup_name(get_label(Fun), State),
+ [NewState1#state.curr_fun,
t_to_string(t_fun(ArgTypes, BodyType))]),
NewState5 =
case IsRaceAnalysisEnabled of
@@ -2780,10 +2789,9 @@ filter_match_fail([]) ->
%%%
%%% ===========================================================================
-state__new(Callgraph, Tree, Plt, Module, Records) ->
- Opaques = erl_types:module_builtin_opaques(Module) ++
- erl_types:t_opaque_from_records(Records),
- TreeMap = build_tree_map(Tree),
+state__new(Callgraph, Codeserver, Tree, Plt, Module, Records) ->
+ Opaques = erl_types:t_opaque_from_records(Records),
+ {TreeMap, FunHomes} = build_tree_map(Tree, Callgraph),
Funs = dict:fetch_keys(TreeMap),
FunTab = init_fun_tab(Funs, dict:new(), TreeMap, Callgraph, Plt),
ExportedFuns =
@@ -2791,7 +2799,8 @@ state__new(Callgraph, Tree, Plt, Module, Records) ->
Work = init_work(ExportedFuns),
Env = lists:foldl(fun(Fun, Env) -> dict:store(Fun, map__new(), Env) end,
dict:new(), Funs),
- #state{callgraph = Callgraph, envs = Env, fun_tab = FunTab, opaques = Opaques,
+ #state{callgraph = Callgraph, codeserver = Codeserver,
+ envs = Env, fun_tab = FunTab, fun_homes = FunHomes, opaques = Opaques,
plt = Plt, races = dialyzer_races:new(), records = Records,
warning_mode = false, warnings = [], work = Work, tree_map = TreeMap,
module = Module}.
@@ -2830,7 +2839,7 @@ state__renew_race_list(RaceList, RaceListSize,
state__renew_warnings(Warnings, State) ->
State#state{warnings = Warnings}.
--spec state__add_warning(dial_warning(), state()) -> state().
+-spec state__add_warning(raw_warning(), state()) -> state().
state__add_warning(Warn, #state{warnings = Warnings} = State) ->
State#state{warnings = [Warn|Warnings]}.
@@ -2845,29 +2854,45 @@ state__add_warning(#state{warnings = Warnings, warning_mode = true} = State,
Ann = cerl:get_ann(Tree),
case Force of
true ->
- Warn = {Tag, {get_file(Ann), abs(get_line(Ann))}, Msg},
+ WarningInfo = {get_file(Ann),
+ abs(get_line(Ann)),
+ State#state.curr_fun},
+ Warn = {Tag, WarningInfo, Msg},
?debug("MSG ~s\n", [dialyzer:format_warning(Warn)]),
State#state{warnings = [Warn|Warnings]};
false ->
case is_compiler_generated(Ann) of
- true -> State;
- false ->
- Warn = {Tag, {get_file(Ann), get_line(Ann)}, Msg},
+ true -> State;
+ false ->
+ WarningInfo = {get_file(Ann), get_line(Ann), State#state.curr_fun},
+ Warn = {Tag, WarningInfo, Msg},
?debug("MSG ~s\n", [dialyzer:format_warning(Warn)]),
- State#state{warnings = [Warn|Warnings]}
+ State#state{warnings = [Warn|Warnings]}
end
end.
+-spec state__set_curr_fun(curr_fun(), state()) -> state().
+
+state__set_curr_fun(undefined, State) ->
+ State#state{curr_fun = undefined};
+state__set_curr_fun(FunLbl, State) ->
+ State#state{curr_fun = find_function(FunLbl, State)}.
+
+-spec state__find_function(mfa_or_funlbl(), state()) -> mfa_or_funlbl().
+
+state__find_function(FunLbl, State) ->
+ find_function(FunLbl, State).
+
state__get_race_warnings(#state{races = Races} = State) ->
{Races1, State1} = dialyzer_races:get_race_warnings(Races, State),
State1#state{races = Races1}.
state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab,
- callgraph = Callgraph, plt = Plt} = State,
- NoWarnUnused) ->
+ callgraph = Callgraph, plt = Plt} = State) ->
FoldFun =
fun({top, _}, AccState) -> AccState;
({FunLbl, Fun}, AccState) ->
+ AccState1 = state__set_curr_fun(FunLbl, AccState),
{NotCalled, Ret} =
case dict:fetch(get_label(Fun), FunTab) of
{not_handled, {_Args0, Ret0}} -> {true, Ret0};
@@ -2875,17 +2900,12 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab,
end,
case NotCalled of
true ->
- {Warn, Msg} =
- case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
- error -> {false, {}};
- {ok, {_M, F, A} = MFA} ->
- {not sets:is_element(MFA, NoWarnUnused),
- {unused_fun, [F, A]}}
- end,
- case Warn of
- true -> state__add_warning(AccState, ?WARN_NOT_CALLED, Fun, Msg);
- false -> AccState
- end;
+ case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
+ error -> AccState1;
+ {ok, {_M, F, A}} ->
+ Msg = {unused_fun, [F, A]},
+ state__add_warning(AccState1, ?WARN_NOT_CALLED, Fun, Msg)
+ end;
false ->
{Name, Contract} =
case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
@@ -2898,7 +2918,7 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab,
%% Check if the function has a contract that allows this.
Warn =
case Contract of
- none -> not parent_allows_this(FunLbl, State);
+ none -> not parent_allows_this(FunLbl, AccState1);
{value, C} ->
GenRet = dialyzer_contracts:get_contract_return(C),
not t_is_unit(GenRet)
@@ -2908,19 +2928,19 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab,
case classify_returns(Fun) of
no_match ->
Msg = {no_return, [no_match|Name]},
- state__add_warning(AccState, ?WARN_RETURN_NO_RETURN,
+ state__add_warning(AccState1, ?WARN_RETURN_NO_RETURN,
Fun, Msg);
only_explicit ->
Msg = {no_return, [only_explicit|Name]},
- state__add_warning(AccState, ?WARN_RETURN_ONLY_EXIT,
+ state__add_warning(AccState1, ?WARN_RETURN_ONLY_EXIT,
Fun, Msg);
only_normal ->
Msg = {no_return, [only_normal|Name]},
- state__add_warning(AccState, ?WARN_RETURN_NO_RETURN,
+ state__add_warning(AccState1, ?WARN_RETURN_NO_RETURN,
Fun, Msg);
both ->
Msg = {no_return, [both|Name]},
- state__add_warning(AccState, ?WARN_RETURN_NO_RETURN,
+ state__add_warning(AccState1, ?WARN_RETURN_NO_RETURN,
Fun, Msg)
end;
false ->
@@ -2958,8 +2978,10 @@ state__lookup_name(Fun, #state{callgraph = Callgraph}) ->
state__lookup_record(Tag, Arity, #state{records = Records}) ->
case erl_types:lookup_record(Tag, Arity, Records) of
{ok, Fields} ->
- {ok, t_tuple([t_atom(Tag)|
- [FieldType || {_FieldName, FieldType} <- Fields]])};
+ RecType =
+ t_tuple([t_atom(Tag)|
+ [FieldType || {_FieldName, _Abstr, FieldType} <- Fields]]),
+ {ok, RecType};
error ->
error
end.
@@ -2971,17 +2993,31 @@ state__get_args_and_status(Tree, #state{fun_tab = FunTab}) ->
{ok, {ArgTypes, _}} -> {ArgTypes, true}
end.
-build_tree_map(Tree) ->
+build_tree_map(Tree, Callgraph) ->
Fun =
- fun(T, Dict) ->
+ fun(T, {Dict, Homes, FunLbls} = Acc) ->
case cerl:is_c_fun(T) of
true ->
- dict:store(get_label(T), T, Dict);
+ FunLbl = get_label(T),
+ Dict1 = dict:store(FunLbl, T, Dict),
+ case catch dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
+ {ok, MFA} ->
+ F2 =
+ fun(Lbl, Dict0) ->
+ dict:store(Lbl, MFA, Dict0)
+ end,
+ Homes1 = lists:foldl(F2, Homes, [FunLbl|FunLbls]),
+ {Dict1, Homes1, []};
+ _ ->
+ {Dict1, Homes, [FunLbl|FunLbls]}
+ end;
false ->
- Dict
+ Acc
end
end,
- cerl_trees:fold(Fun, dict:new(), Tree).
+ Dict0 = dict:new(),
+ {Dict, Homes, _} = cerl_trees:fold(Fun, {Dict0, Dict0, []}, Tree),
+ {Dict, Homes}.
init_fun_tab([top|Left], Dict, TreeMap, Callgraph, Plt) ->
NewDict = dict:store(top, {[], t_none()}, Dict),
@@ -3439,6 +3475,13 @@ parent_allows_this(FunLbl, #state{callgraph = Callgraph, plt = Plt} =State) ->
end
end.
+find_function({_, _, _} = MFA, _State) ->
+ MFA;
+find_function(top, _State) ->
+ top;
+find_function(FunLbl, #state{fun_homes = Homes}) ->
+ dict:fetch(FunLbl, Homes).
+
classify_returns(Tree) ->
case find_terminals(cerl:fun_body(Tree)) of
{false, false} -> no_match;
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl
index 572e60278d..a7bc074d02 100644
--- a/lib/dialyzer/src/dialyzer_dep.erl
+++ b/lib/dialyzer/src/dialyzer_dep.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/dialyzer/src/dialyzer_explanation.erl b/lib/dialyzer/src/dialyzer_explanation.erl
index afc2c1965f..20fbcfed35 100644
--- a/lib/dialyzer/src/dialyzer_explanation.erl
+++ b/lib/dialyzer/src/dialyzer_explanation.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl
index 868857d675..ff54a91ce1 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.erl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.erl
@@ -4,16 +4,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl
index a92b8b1958..dd81dd01ed 100644
--- a/lib/dialyzer/src/dialyzer_options.erl
+++ b/lib/dialyzer/src/dialyzer_options.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,7 +29,7 @@
-module(dialyzer_options).
--export([build/1]).
+-export([build/1, build_warnings/2]).
-include("dialyzer.hrl").
@@ -46,13 +47,11 @@ build(Opts) ->
?WARN_CALLGRAPH,
?WARN_FAILING_CALL,
?WARN_BIN_CONSTRUCTION,
- ?WARN_CALLGRAPH,
?WARN_CONTRACT_RANGE,
?WARN_CONTRACT_TYPES,
?WARN_CONTRACT_SYNTAX,
?WARN_BEHAVIOUR,
- ?WARN_UNDEFINED_CALLBACK,
- ?WARN_UNKNOWN],
+ ?WARN_UNDEFINED_CALLBACK],
DefaultWarns1 = ordsets:from_list(DefaultWarns),
InitPlt = dialyzer_plt:get_default_plt(),
DefaultOpts = #options{},
@@ -73,9 +72,15 @@ preprocess_opts([Opt|Opts]) ->
[Opt|preprocess_opts(Opts)].
postprocess_opts(Opts = #options{}) ->
+ check_file_existence(Opts),
Opts1 = check_output_plt(Opts),
adapt_get_warnings(Opts1).
+check_file_existence(#options{analysis_type = plt_remove}) -> ok;
+check_file_existence(#options{files = Files, files_rec = FilesRec}) ->
+ assert_filenames_exist(Files),
+ assert_filenames_exist(FilesRec).
+
check_output_plt(Opts = #options{analysis_type = Mode, from = From,
output_plt = OutPLT}) ->
case is_plt_mode(Mode) of
@@ -127,14 +132,14 @@ build_options([{OptionName, Value} = Term|Rest], Options) ->
apps ->
OldValues = Options#options.files_rec,
AppDirs = get_app_dirs(Value),
- assert_filenames(Term, AppDirs),
+ assert_filenames_form(Term, AppDirs),
build_options(Rest, Options#options{files_rec = AppDirs ++ OldValues});
files ->
- assert_filenames(Term, Value),
+ assert_filenames_form(Term, Value),
build_options(Rest, Options#options{files = Value});
files_rec ->
OldValues = Options#options.files_rec,
- assert_filenames(Term, Value),
+ assert_filenames_form(Term, Value),
build_options(Rest, Options#options{files_rec = Value ++ OldValues});
analysis_type ->
NewOptions =
@@ -211,16 +216,26 @@ get_app_dirs(Apps) when is_list(Apps) ->
get_app_dirs(Apps) ->
bad_option("Use a list of otp applications", Apps).
-assert_filenames(Term, [FileName|Left]) when length(FileName) >= 0 ->
+assert_filenames(Term, Files) ->
+ assert_filenames_form(Term, Files),
+ assert_filenames_exist(Files).
+
+assert_filenames_form(Term, [FileName|Left]) when length(FileName) >= 0 ->
+ assert_filenames_form(Term, Left);
+assert_filenames_form(_Term, []) ->
+ ok;
+assert_filenames_form(Term, [_|_]) ->
+ bad_option("Malformed or non-existing filename", Term).
+
+assert_filenames_exist([FileName|Left]) ->
case filelib:is_file(FileName) orelse filelib:is_dir(FileName) of
true -> ok;
- false -> bad_option("No such file, directory or application", FileName)
+ false ->
+ bad_option("No such file, directory or application", FileName)
end,
- assert_filenames(Term, Left);
-assert_filenames(_Term, []) ->
- ok;
-assert_filenames(Term, [_|_]) ->
- bad_option("Malformed or non-existing filename", Term).
+ assert_filenames_exist(Left);
+assert_filenames_exist([]) ->
+ ok.
assert_filename(FileName) when length(FileName) >= 0 ->
ok;
@@ -270,7 +285,7 @@ assert_solvers([v2|Terms]) ->
assert_solvers([Term|_]) ->
bad_option("Illegal value for solver", Term).
--spec build_warnings([atom()], [dial_warning()]) -> [dial_warning()].
+-spec build_warnings([atom()], dial_warn_tags()) -> dial_warn_tags().
build_warnings([Opt|Opts], Warnings) ->
NewWarnings =
@@ -302,6 +317,8 @@ build_warnings([Opt|Opts], Warnings) ->
ordsets:add_element(?WARN_RETURN_ONLY_EXIT, Warnings);
race_conditions ->
ordsets:add_element(?WARN_RACE_CONDITION, Warnings);
+ no_missing_calls ->
+ ordsets:del_element(?WARN_CALLGRAPH, Warnings);
specdiffs ->
S = ordsets:from_list([?WARN_CONTRACT_SUBTYPE,
?WARN_CONTRACT_SUPERTYPE,
@@ -311,8 +328,8 @@ build_warnings([Opt|Opts], Warnings) ->
ordsets:add_element(?WARN_CONTRACT_SUBTYPE, Warnings);
underspecs ->
ordsets:add_element(?WARN_CONTRACT_SUPERTYPE, Warnings);
- no_unknown ->
- ordsets:del_element(?WARN_UNKNOWN, Warnings);
+ unknown ->
+ ordsets:add_element(?WARN_UNKNOWN, Warnings);
OtherAtom ->
bad_option("Unknown dialyzer warning option", OtherAtom)
end,
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index 63798f44b1..769f26a3df 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -136,7 +137,7 @@ delete_list(#plt{info = Info, types = Types,
#plt{info = table_delete_list(Info, List),
types = Types,
contracts = table_delete_list(Contracts, List),
- callbacks = table_delete_list(Callbacks, List),
+ callbacks = Callbacks,
exported_types = ExpTypes}.
-spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt().
@@ -158,9 +159,7 @@ lookup_contract(#mini_plt{contracts = ETSContracts},
ets_table_lookup(ETSContracts, MFA).
-spec lookup_callbacks(plt(), module()) ->
- 'none' | {'value', [{mfa(), {{Filename::string(),
- Line::pos_integer()},
- #contract{}}}]}.
+ 'none' | {'value', [{mfa(), dialyzer_contracts:file_contract()}]}.
lookup_callbacks(#mini_plt{callbacks = ETSCallbacks}, Mod) when is_atom(Mod) ->
ets_table_lookup(ETSCallbacks, Mod).
@@ -618,9 +617,7 @@ table_insert_list(Plt, [{Key, Val}|Left]) ->
table_insert_list(Plt, []) ->
Plt.
-table_insert(Plt, Key, {_Ret, _Arg} = Obj) ->
- dict:store(Key, Obj, Plt);
-table_insert(Plt, Key, #contract{} = C) ->
+table_insert(Plt, Key, {_File, #contract{}, _Xtra} = C) ->
dict:store(Key, C, Plt).
table_lookup(Plt, Obj) ->
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index 2a8aba5d8f..39de071bde 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -85,9 +86,9 @@
-type race_tag() :: 'whereis_register' | 'whereis_unregister'
| 'ets_lookup_insert' | 'mnesia_dirty_read_write'.
-%% The following type is similar to the dial_warning() type but has a
+%% The following type is similar to the raw_warning() type but has a
%% tag which is local to this module and is not propagated to outside
--type dial_race_warning() :: {race_warn_tag(), file_line(), {atom(), [term()]}}.
+-type dial_race_warning() :: {race_warn_tag(), warning_info(), {atom(), [term()]}}.
-type race_warn_tag() :: ?WARN_WHEREIS_REGISTER | ?WARN_WHEREIS_UNREGISTER
| ?WARN_ETS_LOOKUP_INSERT | ?WARN_MNESIA_DIRTY_READ_WRITE.
@@ -312,10 +313,13 @@ race(State) ->
DepList = fixup_race_list(RaceWarnTag, VarArgs, State1),
{State2, RaceWarn} =
get_race_warn(Fun, Args, ArgTypes, DepList, State),
+ {File, Line} = FileLine,
+ CurrMFA = dialyzer_dataflow:state__find_function(CurrFun, State),
+ WarningInfo = {File, Line, CurrMFA},
race(
state__add_race_warning(
state__renew_race_tags(T, State2), RaceWarn, RaceWarnTag,
- FileLine))
+ WarningInfo))
end,
state__renew_race_tags([], RetState).
@@ -2324,7 +2328,7 @@ get_race_warnings_helper(Warnings, State) ->
[] ->
{dialyzer_dataflow:state__get_races(State), State};
[H|T] ->
- {RaceWarnTag, FileLine, {race_condition, [M, F, A, AT, S, DepList]}} = H,
+ {RaceWarnTag, WarningInfo, {race_condition, [M, F, A, AT, S, DepList]}} = H,
Reason =
case RaceWarnTag of
?WARN_WHEREIS_REGISTER ->
@@ -2347,7 +2351,7 @@ get_race_warnings_helper(Warnings, State) ->
"caused by its combination with ")
end,
W =
- {?WARN_RACE_CONDITION, FileLine,
+ {?WARN_RACE_CONDITION, WarningInfo,
{race_condition,
[M, F, dialyzer_dataflow:format_args(A, AT, S), Reason]}},
get_race_warnings_helper(T,
@@ -2377,12 +2381,12 @@ get_reason(DependencyList, Reason) ->
end
end.
-state__add_race_warning(State, RaceWarn, RaceWarnTag, FileLine) ->
+state__add_race_warning(State, RaceWarn, RaceWarnTag, WarningInfo) ->
case RaceWarn of
no_race -> State;
_Else ->
Races = dialyzer_dataflow:state__get_races(State),
- Warn = {RaceWarnTag, FileLine, RaceWarn},
+ Warn = {RaceWarnTag, WarningInfo, RaceWarn},
dialyzer_dataflow:state__put_races(add_race_warning(Warn, Races), State)
end.
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index ef9b00e203..18f02e6742 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,7 @@
-export([analyze_callgraph/3,
analyze_callgraph/6,
- get_warnings/8
+ get_warnings/7
]).
-export([
@@ -69,10 +70,8 @@
-type scc() :: [mfa_or_funlbl()] | [module()].
-
-record(st, {callgraph :: dialyzer_callgraph:callgraph(),
codeserver :: dialyzer_codeserver:codeserver(),
- no_warn_unused :: sets:set(mfa()),
parent = none :: parent(),
timing_server :: dialyzer_timing:timing_server(),
solvers :: [solver()],
@@ -137,18 +136,17 @@ get_refined_success_typings(SCCs, #st{callgraph = Callgraph,
-type doc_plt() :: 'undefined' | dialyzer_plt:plt().
-spec get_warnings(dialyzer_callgraph:callgraph(), dialyzer_plt:plt(),
- doc_plt(), dialyzer_codeserver:codeserver(), sets:set(mfa()),
+ doc_plt(), dialyzer_codeserver:codeserver(),
dialyzer_timing:timing_server(), [solver()], pid()) ->
- {[dial_warning()], dialyzer_plt:plt(), doc_plt()}.
+ {[raw_warning()], dialyzer_plt:plt(), doc_plt()}.
get_warnings(Callgraph, Plt, DocPlt, Codeserver,
- NoWarnUnused, TimingServer, Solvers, Parent) ->
+ TimingServer, Solvers, Parent) ->
InitState =
init_state_and_get_success_typings(Callgraph, Plt, Codeserver,
TimingServer, Solvers, Parent),
- NewState = InitState#st{no_warn_unused = NoWarnUnused},
- Mods = dialyzer_callgraph:modules(NewState#st.callgraph),
- MiniPlt = NewState#st.plt,
+ Mods = dialyzer_callgraph:modules(InitState#st.callgraph),
+ MiniPlt = InitState#st.plt,
FindOpaques = lookup_and_find_opaques_fun(Codeserver),
CWarns =
dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver,
@@ -156,31 +154,30 @@ get_warnings(Callgraph, Plt, DocPlt, Codeserver,
MiniDocPlt = dialyzer_plt:get_mini_plt(DocPlt),
ModWarns =
?timing(TimingServer, "warning",
- get_warnings_from_modules(Mods, NewState, MiniDocPlt)),
+ get_warnings_from_modules(Mods, InitState, MiniDocPlt)),
{postprocess_warnings(CWarns ++ ModWarns, Codeserver),
dialyzer_plt:restore_full_plt(MiniPlt, Plt),
dialyzer_plt:restore_full_plt(MiniDocPlt, DocPlt)}.
get_warnings_from_modules(Mods, State, DocPlt) ->
#st{callgraph = Callgraph, codeserver = Codeserver,
- no_warn_unused = NoWarnUnused, plt = Plt,
- timing_server = TimingServer} = State,
- Init = {Codeserver, Callgraph, NoWarnUnused, Plt, DocPlt},
+ plt = Plt, timing_server = TimingServer} = State,
+ Init = {Codeserver, Callgraph, Plt, DocPlt},
dialyzer_coordinator:parallel_job(warnings, Mods, Init, TimingServer).
--spec collect_warnings(module(), warnings_init_data()) -> [dial_warning()].
+-spec collect_warnings(module(), warnings_init_data()) -> [raw_warning()].
-collect_warnings(M, {Codeserver, Callgraph, NoWarnUnused, Plt, DocPlt}) ->
+collect_warnings(M, {Codeserver, Callgraph, Plt, DocPlt}) ->
ModCode = dialyzer_codeserver:lookup_mod_code(M, Codeserver),
Records = dialyzer_codeserver:lookup_mod_records(M, Codeserver),
Contracts = dialyzer_codeserver:lookup_mod_contracts(M, Codeserver),
AllFuns = collect_fun_info([ModCode]),
%% Check if there are contracts for functions that do not exist
- Warnings1 =
+ Warnings1 =
dialyzer_contracts:contracts_without_fun(Contracts, AllFuns, Callgraph),
{Warnings2, FunTypes} =
- dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph,
- Records, NoWarnUnused),
+ dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph, Codeserver,
+ Records),
Attrs = cerl:module_attrs(ModCode),
Warnings3 =
dialyzer_behaviours:check_callbacks(M, Attrs, Records, Plt, Codeserver),
@@ -197,17 +194,19 @@ postprocess_warnings(RawWarnings, Codeserver) ->
postprocess_dataflow_warns([], _Callgraph, WAcc, Acc) ->
lists:reverse(Acc, WAcc);
-postprocess_dataflow_warns([{?WARN_CONTRACT_RANGE, {CallF, CallL}, Msg}|Rest],
+postprocess_dataflow_warns([{?WARN_CONTRACT_RANGE, WarningInfo, Msg}|Rest],
Codeserver, WAcc, Acc) ->
+ {CallF, CallL, _CallMFA} = WarningInfo,
{contract_range, [Contract, M, F, A, ArgStrings, CRet]} = Msg,
case dialyzer_codeserver:lookup_mfa_contract({M,F,A}, Codeserver) of
- {ok, {{ContrF, _ContrL} = FileLine, _C}} ->
+ {ok, {{ContrF, ContrL}, _C, _X}} ->
case CallF =:= ContrF of
true ->
NewMsg = {contract_range, [Contract, M, F, ArgStrings, CallL, CRet]},
- W = {?WARN_CONTRACT_RANGE, FileLine, NewMsg},
+ WarningInfo2 = {ContrF, ContrL, {M, F, A}},
+ W = {?WARN_CONTRACT_RANGE, WarningInfo2, NewMsg},
Filter =
- fun({?WARN_CONTRACT_TYPES, FL, _}) when FL =:= FileLine -> false;
+ fun({?WARN_CONTRACT_TYPES, WI, _}) when WI =:= WarningInfo2 -> false;
(_) -> true
end,
FilterWAcc = lists:filter(Filter, WAcc),
@@ -219,7 +218,7 @@ postprocess_dataflow_warns([{?WARN_CONTRACT_RANGE, {CallF, CallL}, Msg}|Rest],
%% The contract is not in a module that is currently under analysis.
%% We display the warning in the file/line of the call.
NewMsg = {contract_range, [Contract, M, F, ArgStrings, CallL, CRet]},
- W = {?WARN_CONTRACT_RANGE, {CallF, CallL}, NewMsg},
+ W = {?WARN_CONTRACT_RANGE, WarningInfo, NewMsg},
postprocess_dataflow_warns(Rest, Codeserver, WAcc, [W|Acc])
end.
@@ -262,7 +261,7 @@ refine_one_module(M, {CodeServer, Callgraph, Plt, _Solvers}) ->
Records = dialyzer_codeserver:lookup_mod_records(M, CodeServer),
FunTypes = get_fun_types_from_plt(AllFuns, Callgraph, Plt),
NewFunTypes =
- dialyzer_dataflow:get_fun_types(ModCode, Plt, Callgraph, Records),
+ dialyzer_dataflow:get_fun_types(ModCode, Plt, Callgraph, CodeServer, Records),
Contracts1 = dialyzer_codeserver:lookup_mod_contracts(M, CodeServer),
Contracts = orddict:from_list(dict:to_list(Contracts1)),
FindOpaques = find_opaques_fun(Records),
@@ -401,7 +400,7 @@ decorate_succ_typings(Contracts, Callgraph, FunTypes, FindOpaques) ->
case dialyzer_callgraph:lookup_name(Label, Callgraph) of
{ok, MFA} ->
case orddict:find(MFA, Contracts) of
- {ok, {_FileLine, Contract}} ->
+ {ok, {_FileLine, Contract, _Xtra}} ->
Args = dialyzer_contracts:get_contract_args(Contract),
Ret = dialyzer_contracts:get_contract_return(Contract),
C = erl_types:t_fun(Args, Ret),
@@ -422,10 +421,7 @@ lookup_and_find_opaques_fun(Codeserver) ->
end.
find_opaques_fun(Records) ->
- fun(Module) ->
- erl_types:module_builtin_opaques(Module) ++
- erl_types:t_opaque_from_records(Records)
- end.
+ fun(_Module) -> erl_types:t_opaque_from_records(Records) end.
get_fun_types_from_plt(FunList, Callgraph, Plt) ->
get_fun_types_from_plt(FunList, Callgraph, Plt, dict:new()).
diff --git a/lib/dialyzer/src/dialyzer_timing.erl b/lib/dialyzer/src/dialyzer_timing.erl
index b1a4bdc07c..33fd008732 100644
--- a/lib/dialyzer/src/dialyzer_timing.erl
+++ b/lib/dialyzer/src/dialyzer_timing.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -38,7 +39,7 @@ init(Active) ->
case Active of
true ->
io:format("\n"),
- spawn_link(fun() -> loop(now(), 0, "") end);
+ spawn_link(fun() -> loop(erlang:monotonic_time(), 0, "") end);
debug ->
io:format("\n"),
spawn_link(fun() -> debug_loop("") end);
@@ -105,14 +106,14 @@ debug_loop(Phase) ->
start_stamp(none, _) -> ok;
start_stamp(Pid, Msg) ->
- Pid ! {stamp, Msg, now()},
+ Pid ! {stamp, Msg, erlang:monotonic_time()},
ok.
-spec end_stamp(timing_server()) -> ok.
end_stamp(none) -> ok;
end_stamp(Pid) ->
- Pid ! {stamp, now()},
+ Pid ! {stamp, erlang:monotonic_time()},
ok.
-spec send_size_info(timing_server(), integer(), string()) -> ok.
@@ -126,8 +127,8 @@ send_size_info(Pid, Size, Unit) ->
stop(none) -> ok;
stop(Pid) ->
- Pid ! {self(), stop, now()},
+ Pid ! {self(), stop, erlang:monotonic_time()},
receive ok -> ok end.
diff(T2, T1) ->
- timer:now_diff(T2,T1) / 1000000.
+ (T2-T1) / erlang:convert_time_unit(1, seconds, native).
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index 3d03ed3ab3..0b8b244cc9 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1579,11 +1580,11 @@ get_bif_constr({M, F, A} = _BIF, Dst, Args, _State) ->
eval_inv_arith('+', _Pos, Dst, Arg) ->
bif_return(erlang, '-', 2, [Dst, Arg]);
eval_inv_arith('*', _Pos, Dst, Arg) ->
- case t_number_vals(Arg) of
- [0] -> t_integer();
- _ ->
+ Zero = t_from_term(0),
+ case t_is_none(t_inf(Arg, Zero)) of
+ false -> t_integer();
+ true ->
TmpRet = bif_return(erlang, 'div', 2, [Dst, Arg]),
- Zero = t_from_term(0),
%% If 0 is not part of the result, it cannot be part of the argument.
case t_is_subtype(Zero, Dst) of
false -> t_subtract(TmpRet, Zero);
@@ -3264,7 +3265,7 @@ lookup_record(Records, Tag, Arity) ->
{ok, Fields} ->
RecType =
t_tuple([t_from_term(Tag)|
- [FieldType || {_FieldName, FieldType} <- Fields]]),
+ [FieldType || {_FieldName, _Abstr, FieldType} <- Fields]]),
{ok, RecType};
error ->
error
@@ -3275,7 +3276,7 @@ is_literal_record(Tree) ->
lists:member(record, Ann).
family(L) ->
- sofs:to_external(sofs:rel2fam(sofs:relation(L))).
+ dialyzer_utils:family(L).
%% ============================================================================
%%
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 5297a3a7b4..7fe982a992 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,12 +41,16 @@
get_core_from_src/2,
get_record_and_type_info/1,
get_spec_info/3,
+ get_fun_meta_info/3,
+ is_suppressed_fun/2,
+ is_suppressed_tag/3,
merge_records/2,
pp_hook/0,
process_record_remote_types/1,
sets_filter/2,
src_compiler_opts/0,
- parallelism/0
+ parallelism/0,
+ family/1
]).
-include("dialyzer.hrl").
@@ -59,16 +64,16 @@ print_types(RecDict) ->
print_types1([], _) ->
ok;
-print_types1([{type, _Name} = Key|T], RecDict) ->
- {ok, {_Mod, Form, _Args}} = dict:find(Key, RecDict),
- io:format("\n~w: ~w\n", [Key, erl_types:t_from_form(Form, RecDict)]),
+print_types1([{type, _Name, _NArgs} = Key|T], RecDict) ->
+ {ok, {{_Mod, _FileLine, _Form, _Args}, Type}} = dict:find(Key, RecDict),
+ io:format("\n~w: ~w\n", [Key, Type]),
print_types1(T, RecDict);
-print_types1([{opaque, _Name} = Key|T], RecDict) ->
- {ok, {_Mod, Form, _Args}} = dict:find(Key, RecDict),
- io:format("\n~w: ~w\n", [Key, erl_types:t_from_form(Form, RecDict)]),
+print_types1([{opaque, _Name, _NArgs} = Key|T], RecDict) ->
+ {ok, {{_Mod, _FileLine, _Form, _Args}, Type}} = dict:find(Key, RecDict),
+ io:format("\n~w: ~w\n", [Key, Type]),
print_types1(T, RecDict);
print_types1([{record, _Name} = Key|T], RecDict) ->
- {ok, [{_Arity, _Fields} = AF]} = dict:find(Key, RecDict),
+ {ok, {_FileLine, [{_Arity, _Fields} = AF]}} = dict:find(Key, RecDict),
io:format("~w: ~w\n\n", [Key, AF]),
print_types1(T, RecDict).
-define(debug(D_), print_types(D_)).
@@ -80,7 +85,9 @@ print_types1([{record, _Name} = Key|T], RecDict) ->
-type abstract_code() :: [tuple()]. %% XXX: import from somewhere
-type comp_options() :: [compile:option()].
--type mod_or_fname() :: atom() | file:filename().
+-type mod_or_fname() :: module() | file:filename().
+-type fa() :: {atom(), arity()}.
+-type codeserver() :: dialyzer_codeserver:codeserver().
%% ============================================================================
%%
@@ -197,71 +204,74 @@ get_record_and_type_info(AbstractCode) ->
{'ok', dict:dict()} | {'error', string()}.
get_record_and_type_info(AbstractCode, Module, RecDict) ->
- get_record_and_type_info(AbstractCode, Module, [], RecDict).
+ get_record_and_type_info(AbstractCode, Module, RecDict, "nofile").
-get_record_and_type_info([{attribute, _, record, {Name, Fields0}}|Left],
- Module, Records, RecDict) ->
+get_record_and_type_info([{attribute, A, record, {Name, Fields0}}|Left],
+ Module, RecDict, File) ->
{ok, Fields} = get_record_fields(Fields0, RecDict),
Arity = length(Fields),
- NewRecDict = dict:store({record, Name}, [{Arity, Fields}], RecDict),
- get_record_and_type_info(Left, Module, [{record, Name}|Records], NewRecDict);
-get_record_and_type_info([{attribute, _, type, {{record, Name}, Fields0, []}}
- |Left], Module, Records, RecDict) ->
+ FN = {File, erl_anno:line(A)},
+ NewRecDict = dict:store({record, Name}, {FN, [{Arity,Fields}]}, RecDict),
+ get_record_and_type_info(Left, Module, NewRecDict, File);
+get_record_and_type_info([{attribute, A, type, {{record, Name}, Fields0, []}}
+ |Left], Module, RecDict, File) ->
%% This overrides the original record declaration.
{ok, Fields} = get_record_fields(Fields0, RecDict),
Arity = length(Fields),
- NewRecDict = dict:store({record, Name}, [{Arity, Fields}], RecDict),
- get_record_and_type_info(Left, Module, Records, NewRecDict);
-get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm}}|Left],
- Module, Records, RecDict) when Attr =:= 'type';
- Attr =:= 'opaque' ->
- try
- NewRecDict = add_new_type(Attr, Name, TypeForm, [], Module, RecDict),
- get_record_and_type_info(Left, Module, Records, NewRecDict)
+ FN = {File, erl_anno:line(A)},
+ NewRecDict = dict:store({record, Name}, {FN, [{Arity, Fields}]}, RecDict),
+ get_record_and_type_info(Left, Module, NewRecDict, File);
+get_record_and_type_info([{attribute, A, Attr, {Name, TypeForm}}|Left],
+ Module, RecDict, File)
+ when Attr =:= 'type'; Attr =:= 'opaque' ->
+ FN = {File, erl_anno:line(A)},
+ try add_new_type(Attr, Name, TypeForm, [], Module, FN, RecDict) of
+ NewRecDict ->
+ get_record_and_type_info(Left, Module, NewRecDict, File)
catch
throw:{error, _} = Error -> Error
end;
-get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm, Args}}|Left],
- Module, Records, RecDict) when Attr =:= 'type';
- Attr =:= 'opaque' ->
- try
- NewRecDict = add_new_type(Attr, Name, TypeForm, Args, Module, RecDict),
- get_record_and_type_info(Left, Module, Records, NewRecDict)
+get_record_and_type_info([{attribute, A, Attr, {Name, TypeForm, Args}}|Left],
+ Module, RecDict, File)
+ when Attr =:= 'type'; Attr =:= 'opaque' ->
+ FN = {File, erl_anno:line(A)},
+ try add_new_type(Attr, Name, TypeForm, Args, Module, FN, RecDict) of
+ NewRecDict ->
+ get_record_and_type_info(Left, Module, NewRecDict, File)
catch
throw:{error, _} = Error -> Error
end;
-get_record_and_type_info([_Other|Left], Module, Records, RecDict) ->
- get_record_and_type_info(Left, Module, Records, RecDict);
-get_record_and_type_info([], _Module, Records, RecDict) ->
- case type_record_fields(lists:reverse(Records), RecDict) of
- {ok, _NewRecDict} = Ok ->
- ?debug(_NewRecDict),
- Ok;
- {error, Name, Error} ->
- {error, flat_format(" Error while parsing #~w{}: ~s\n", [Name, Error])}
- end.
-
-add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, RecDict) ->
+get_record_and_type_info([{attribute, _, file, {IncludeFile, _}}|Left],
+ Module, RecDict, _File) ->
+ get_record_and_type_info(Left, Module, RecDict, IncludeFile);
+get_record_and_type_info([_Other|Left], Module, RecDict, File) ->
+ get_record_and_type_info(Left, Module, RecDict, File);
+get_record_and_type_info([], _Module, RecDict, _File) ->
+ {ok, RecDict}.
+
+add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, FN,
+ RecDict) ->
Arity = length(ArgForms),
case erl_types:type_is_defined(TypeOrOpaque, Name, Arity, RecDict) of
true ->
Msg = flat_format("Type ~s/~w already defined\n", [Name, Arity]),
throw({error, Msg});
false ->
- ArgTypes = [erl_types:t_from_form(X) || X <- ArgForms],
- case lists:all(fun erl_types:t_is_var/1, ArgTypes) of
- true ->
- ArgNames = [erl_types:t_var_name(X) || X <- ArgTypes],
+ try erl_types:t_var_names(ArgForms) of
+ ArgNames ->
dict:store({TypeOrOpaque, Name, Arity},
- {Module, TypeForm, ArgNames}, RecDict);
- false ->
+ {{Module, FN, TypeForm, ArgNames},
+ erl_types:t_any()}, RecDict)
+ catch
+ _:_ ->
throw({error, flat_format("Type declaration for ~w does not "
"have variables as parameters", [Name])})
end
end.
get_record_fields(Fields, RecDict) ->
- get_record_fields(Fields, RecDict, []).
+ Fs = get_record_fields(Fields, RecDict, []),
+ {ok, [{Name, Form, erl_types:t_any()} || {Name, Form} <- Fs]}.
get_record_fields([{typed_record_field, OrdRecField, TypeForm}|Left],
RecDict, Acc) ->
@@ -270,63 +280,122 @@ get_record_fields([{typed_record_field, OrdRecField, TypeForm}|Left],
{record_field, _Line, Name0} -> erl_parse:normalise(Name0);
{record_field, _Line, Name0, _Init} -> erl_parse:normalise(Name0)
end,
- get_record_fields(Left, RecDict, [{Name, TypeForm}|Acc]);
+ get_record_fields(Left, RecDict, [{Name, TypeForm}|Acc]);
get_record_fields([{record_field, _Line, Name}|Left], RecDict, Acc) ->
- NewAcc = [{erl_parse:normalise(Name), {var, -1, '_'}}|Acc],
+ A = erl_anno:set_generated(true, erl_anno:new(1)),
+ NewAcc = [{erl_parse:normalise(Name), {var, A, '_'}}|Acc],
get_record_fields(Left, RecDict, NewAcc);
get_record_fields([{record_field, _Line, Name, _Init}|Left], RecDict, Acc) ->
- NewAcc = [{erl_parse:normalise(Name), {var, -1, '_'}}|Acc],
+ A = erl_anno:set_generated(true, erl_anno:new(1)),
+ NewAcc = [{erl_parse:normalise(Name), {var, A, '_'}}|Acc],
get_record_fields(Left, RecDict, NewAcc);
get_record_fields([], _RecDict, Acc) ->
- {ok, lists:reverse(Acc)}.
-
-type_record_fields([], RecDict) ->
- {ok, RecDict};
-type_record_fields([RecKey|Recs], RecDict) ->
- {ok, [{Arity, Fields}]} = dict:find(RecKey, RecDict),
- try
- TypedFields =
- [{FieldName, erl_types:t_from_form(FieldTypeForm, RecDict)}
- || {FieldName, FieldTypeForm} <- Fields],
- RecDict1 = dict:store(RecKey, [{Arity, TypedFields}], RecDict),
- Fun = fun(OldOrdDict) ->
- orddict:store(Arity, TypedFields, OldOrdDict)
- end,
- RecDict2 = dict:update(RecKey, Fun, RecDict1),
- type_record_fields(Recs, RecDict2)
- catch
- throw:{error, Error} ->
- {record, Name} = RecKey,
- {error, Name, Error}
- end.
+ lists:reverse(Acc).
--spec process_record_remote_types(dialyzer_codeserver:codeserver()) -> dialyzer_codeserver:codeserver().
+-spec process_record_remote_types(codeserver()) -> codeserver().
+%% The field types are cached. Used during analysis when handling records.
process_record_remote_types(CServer) ->
TempRecords = dialyzer_codeserver:get_temp_records(CServer),
TempExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer),
- RecordFun =
- fun(Key, Value) ->
- case Key of
- {record, _Name} ->
- FieldFun =
- fun(_Arity, Fields) ->
- [{Name, erl_types:t_solve_remote(Field, TempExpTypes,
- TempRecords)}
- || {Name, Field} <- Fields]
- end,
- orddict:map(FieldFun, Value);
- _Other -> Value
- end
- end,
+ TempRecords1 = process_opaque_types0(TempRecords, TempExpTypes),
ModuleFun =
- fun(_Module, Record) ->
+ fun(Module, Record) ->
+ RecordFun =
+ fun(Key, Value) ->
+ case Key of
+ {record, Name} ->
+ FieldFun =
+ fun(Arity, Fields) ->
+ Site = {record, {Module, Name, Arity}},
+ [{FieldName, Field,
+ erl_types:t_from_form(Field,
+ TempExpTypes,
+ Site,
+ TempRecords1)}
+ || {FieldName, Field, _} <- Fields]
+ end,
+ {FileLine, Fields} = Value,
+ {FileLine, orddict:map(FieldFun, Fields)};
+ _Other -> Value
+ end
+ end,
dict:map(RecordFun, Record)
end,
- NewRecords = dict:map(ModuleFun, TempRecords),
+ NewRecords = dict:map(ModuleFun, TempRecords1),
+ ok = check_record_fields(NewRecords, TempExpTypes),
CServer1 = dialyzer_codeserver:finalize_records(NewRecords, CServer),
dialyzer_codeserver:finalize_exported_types(TempExpTypes, CServer1).
+%% erl_types:t_from_form() substitutes the declaration of opaque types
+%% for the expanded type in some cases. To make sure the initial type,
+%% any(), is not used, the expansion is done twice.
+%% XXX: Recursive opaque types are not handled well.
+process_opaque_types0(TempRecords0, TempExpTypes) ->
+ TempRecords1 = process_opaque_types(TempRecords0, TempExpTypes),
+ process_opaque_types(TempRecords1, TempExpTypes).
+
+process_opaque_types(TempRecords, TempExpTypes) ->
+ ModuleFun =
+ fun(Module, Record) ->
+ RecordFun =
+ fun(Key, Value) ->
+ case Key of
+ {opaque, Name, NArgs} ->
+ {{_Module, _FileLine, Form, _ArgNames}=F, _Type} = Value,
+ Site = {type, {Module, Name, NArgs}},
+ Type = erl_types:t_from_form(Form, TempExpTypes, Site,
+ TempRecords),
+ {F, Type};
+ _Other -> Value
+ end
+ end,
+ dict:map(RecordFun, Record)
+ end,
+ dict:map(ModuleFun, TempRecords).
+
+check_record_fields(Records, TempExpTypes) ->
+ CheckFun =
+ fun({Module, Element}) ->
+ CheckForm = fun(Form, Site) ->
+ erl_types:t_check_record_fields(Form, TempExpTypes,
+ Site, Records)
+ end,
+ ElemFun =
+ fun({Key, Value}) ->
+ case Key of
+ {record, Name} ->
+ FieldFun =
+ fun({Arity, Fields}) ->
+ Site = {record, {Module, Name, Arity}},
+ _ = [ok = CheckForm(Field, Site) ||
+ {_, Field, _} <- Fields],
+ ok
+ end,
+ {FileLine, Fields} = Value,
+ Fun = fun() -> lists:foreach(FieldFun, Fields) end,
+ msg_with_position(Fun, FileLine);
+ {_OpaqueOrType, Name, NArgs} ->
+ Site = {type, {Module, Name, NArgs}},
+ {{_Module, FileLine, Form, _ArgNames}, _Type} = Value,
+ Fun = fun() -> ok = CheckForm(Form, Site) end,
+ msg_with_position(Fun, FileLine)
+ end
+ end,
+ lists:foreach(ElemFun, dict:to_list(Element))
+ end,
+ lists:foreach(CheckFun, dict:to_list(Records)).
+
+msg_with_position(Fun, FileLine) ->
+ try Fun()
+ catch
+ throw:{error, Msg} ->
+ {File, Line} = FileLine,
+ BaseName = filename:basename(File),
+ NewMsg = io_lib:format("~s:~p: ~s", [BaseName, Line, Msg]),
+ throw({error, NewMsg})
+ end.
+
-spec merge_records(dict:dict(), dict:dict()) -> dict:dict().
merge_records(NewRecords, OldRecords) ->
@@ -341,12 +410,23 @@ merge_records(NewRecords, OldRecords) ->
-type spec_dict() :: dict:dict().
-type callback_dict() :: dict:dict().
--spec get_spec_info(atom(), abstract_code(), dict:dict()) ->
+-spec get_spec_info(module(), abstract_code(), dict:dict()) ->
{'ok', spec_dict(), callback_dict()} | {'error', string()}.
get_spec_info(ModName, AbstractCode, RecordsDict) ->
+ OptionalCallbacks0 = get_optional_callbacks(AbstractCode, ModName),
+ OptionalCallbacks = gb_sets:from_list(OptionalCallbacks0),
get_spec_info(AbstractCode, dict:new(), dict:new(),
- RecordsDict, ModName, "nofile").
+ RecordsDict, ModName, OptionalCallbacks, "nofile").
+
+get_optional_callbacks(Abs, ModName) ->
+ [{ModName, F, A} || {F, A} <- get_optional_callbacks(Abs)].
+
+get_optional_callbacks(Abs) ->
+ L = [O ||
+ {attribute, _, optional_callbacks, O} <- Abs,
+ is_fa_list(O)],
+ lists:append(L).
%% TypeSpec is a list of conditional contracts for a function.
%% Each contract is of the form {[Argument], Range, [Constraint]} where
@@ -354,14 +434,16 @@ get_spec_info(ModName, AbstractCode, RecordsDict) ->
%% - Constraint is of the form {subtype, T1, T2} where T1 and T2
%% are erl_types:erl_type()
-get_spec_info([{attribute, Ln, Contract, {Id, TypeSpec}}|Left],
- SpecDict, CallbackDict, RecordsDict, ModName, File)
+get_spec_info([{attribute, Anno, Contract, {Id, TypeSpec}}|Left],
+ SpecDict, CallbackDict, RecordsDict, ModName, OptCb, File)
when ((Contract =:= 'spec') or (Contract =:= 'callback')),
is_list(TypeSpec) ->
+ Ln = erl_anno:line(Anno),
MFA = case Id of
{_, _, _} = T -> T;
{F, A} -> {ModName, F, A}
end,
+ Xtra = [optional_callback || gb_sets:is_member(MFA, OptCb)],
ActiveDict =
case Contract of
spec -> SpecDict;
@@ -369,8 +451,9 @@ get_spec_info([{attribute, Ln, Contract, {Id, TypeSpec}}|Left],
end,
try dict:find(MFA, ActiveDict) of
error ->
+ SpecData = {TypeSpec, Xtra},
NewActiveDict =
- dialyzer_contracts:store_tmp_contract(MFA, {File, Ln}, TypeSpec,
+ dialyzer_contracts:store_tmp_contract(MFA, {File, Ln}, SpecData,
ActiveDict, RecordsDict),
{NewSpecDict, NewCallbackDict} =
case Contract of
@@ -378,8 +461,8 @@ get_spec_info([{attribute, Ln, Contract, {Id, TypeSpec}}|Left],
callback -> {SpecDict, NewActiveDict}
end,
get_spec_info(Left, NewSpecDict, NewCallbackDict,
- RecordsDict, ModName,File);
- {ok, {{OtherFile, L},_C}} ->
+ RecordsDict, ModName, OptCb, File);
+ {ok, {{OtherFile, L}, _D}} ->
{Mod, Fun, Arity} = MFA,
Msg = flat_format(" Contract/callback for function ~w:~w/~w "
"already defined in ~s:~w\n",
@@ -391,15 +474,137 @@ get_spec_info([{attribute, Ln, Contract, {Id, TypeSpec}}|Left],
[Ln, Error])}
end;
get_spec_info([{attribute, _, file, {IncludeFile, _}}|Left],
- SpecDict, CallbackDict, RecordsDict, ModName, _File) ->
+ SpecDict, CallbackDict, RecordsDict, ModName, OptCb, _File) ->
get_spec_info(Left, SpecDict, CallbackDict,
- RecordsDict, ModName, IncludeFile);
+ RecordsDict, ModName, OptCb, IncludeFile);
get_spec_info([_Other|Left], SpecDict, CallbackDict,
- RecordsDict, ModName, File) ->
- get_spec_info(Left, SpecDict, CallbackDict, RecordsDict, ModName, File);
-get_spec_info([], SpecDict, CallbackDict, _RecordsDict, _ModName, _File) ->
+ RecordsDict, ModName, OptCb, File) ->
+ get_spec_info(Left, SpecDict, CallbackDict,
+ RecordsDict, ModName, OptCb, File);
+get_spec_info([], SpecDict, CallbackDict,
+ _RecordsDict, _ModName, _OptCb, _File) ->
{ok, SpecDict, CallbackDict}.
+-spec get_fun_meta_info(module(), abstract_code(), [dial_warn_tag()]) ->
+ dialyzer_codeserver:fun_meta_info().
+
+get_fun_meta_info(M, Abs, LegalWarnings) ->
+ NoWarn = get_nowarn_unused_function(M, Abs),
+ FuncSupp = get_func_suppressions(M, Abs),
+ Warnings0 = get_options(Abs, LegalWarnings),
+ Warnings = ordsets:to_list(Warnings0),
+ ModuleWarnings = [{M, W} || W <- Warnings],
+ RawProps = lists:append([NoWarn, FuncSupp, ModuleWarnings]),
+ process_options(dialyzer_utils:family(RawProps), Warnings0).
+
+process_options([{M, _}=Mod|Left], Warnings) when is_atom(M) ->
+ [Mod|process_options(Left, Warnings)];
+process_options([{{_M, _F, _A}=MFA, Opts}|Left], Warnings) ->
+ WL = case lists:member(nowarn_function, Opts) of
+ true -> [{nowarn_function, func}]; % takes precedence
+ false ->
+ Ws = dialyzer_options:build_warnings(Opts, Warnings),
+ ModOnly = [{W, mod} || W <- ordsets:subtract(Warnings, Ws)],
+ FunOnly = [{W, func} || W <- ordsets:subtract(Ws, Warnings)],
+ ordsets:union(ModOnly, FunOnly)
+ end,
+ case WL of
+ [] -> process_options(Left, Warnings);
+ _ -> [{MFA, WL}|process_options(Left, Warnings)]
+ end;
+process_options([], _Warnings) -> [].
+
+-spec get_nowarn_unused_function(module(), abstract_code()) ->
+ [{mfa(), 'no_unused'}].
+
+get_nowarn_unused_function(M, Abs) ->
+ Opts = get_options_with_tag(compile, Abs),
+ Warn = erl_lint:bool_option(warn_unused_function, nowarn_unused_function,
+ true, Opts),
+ Functions = [{F, A} || {function, _, F, A, _} <- Abs],
+ AttrFile = collect_attribute(Abs, compile),
+ TagsFaList = check_fa_list(AttrFile, nowarn_unused_function, Functions),
+ FAs = case Warn of
+ false -> Functions;
+ true ->
+ [FA || {{nowarn_unused_function,_L,_File}, FA} <- TagsFaList]
+ end,
+ [{{M, F, A}, no_unused} || {F, A} <- FAs].
+
+-spec get_func_suppressions(module(), abstract_code()) ->
+ [{mfa(), 'nowarn_function' | dial_warn_tag()}].
+
+get_func_suppressions(M, Abs) ->
+ Functions = [{F, A} || {function, _, F, A, _} <- Abs],
+ AttrFile = collect_attribute(Abs, dialyzer),
+ TagsFAs = check_fa_list(AttrFile, '*', Functions),
+ %% Check the options:
+ Fun = fun({{nowarn_function, _L, _File}, _FA}) -> ok;
+ ({OptLFile, _FA}) ->
+ _ = get_options1([OptLFile], ordsets:new())
+ end,
+ lists:foreach(Fun, TagsFAs),
+ [{{M, F, A}, W} || {{W, _L, _File}, {F, A}} <- TagsFAs].
+
+-spec get_options(abstract_code(), [dial_warn_tag()]) ->
+ ordsets:ordset(dial_warn_tag()).
+
+get_options(Abs, LegalWarnings) ->
+ AttrFile = collect_attribute(Abs, dialyzer),
+ get_options1(AttrFile, LegalWarnings).
+
+get_options1([{Args, L, File}|Left], Warnings) ->
+ Opts = [O ||
+ O <- lists:flatten([Args]),
+ is_atom(O)],
+ try dialyzer_options:build_warnings(Opts, Warnings) of
+ NewWarnings ->
+ get_options1(Left, NewWarnings)
+ catch
+ throw:{dialyzer_options_error, Msg} ->
+ Msg1 = flat_format(" ~s:~w: ~s", [File, L, Msg]),
+ throw({error, Msg1})
+ end;
+get_options1([], Warnings) ->
+ Warnings.
+
+-type collected_attribute() ::
+ {Args :: term(), erl_anno:line(), file:filename()}.
+
+collect_attribute(Abs, Tag) ->
+ collect_attribute(Abs, Tag, "nofile").
+
+collect_attribute([{attribute, L, Tag, Args}|Left], Tag, File) ->
+ CollAttr = {Args, L, File},
+ [CollAttr | collect_attribute(Left, Tag, File)];
+collect_attribute([{attribute, _, file, {IncludeFile, _}}|Left], Tag, _) ->
+ collect_attribute(Left, Tag, IncludeFile);
+collect_attribute([_Other|Left], Tag, File) ->
+ collect_attribute(Left, Tag, File);
+collect_attribute([], _Tag, _File) -> [].
+
+-spec is_suppressed_fun(mfa(), codeserver()) -> boolean().
+
+is_suppressed_fun(MFA, CodeServer) ->
+ lookup_fun_property(MFA, nowarn_function, CodeServer).
+
+-spec is_suppressed_tag(mfa() | module(), dial_warn_tag(), codeserver()) ->
+ boolean().
+
+is_suppressed_tag(MorMFA, Tag, Codeserver) ->
+ not lookup_fun_property(MorMFA, Tag, Codeserver).
+
+lookup_fun_property({M, _F, _A}=MFA, Property, CodeServer) ->
+ MFAPropList = dialyzer_codeserver:lookup_meta_info(MFA, CodeServer),
+ case proplists:get_value(Property, MFAPropList, no) of
+ mod -> false; % suppressed in function
+ func -> true; % requested in function
+ no -> lookup_fun_property(M, Property, CodeServer)
+ end;
+lookup_fun_property(M, Property, CodeServer) when is_atom(M) ->
+ MPropList = dialyzer_codeserver:lookup_meta_info(M, CodeServer),
+ proplists:is_defined(Property, MPropList).
+
%% ============================================================================
%%
%% Exported types
@@ -449,7 +654,6 @@ cleanup_compile_options(Opts) ->
%% Using abstract, not asm or core.
keep_compile_option(from_asm) -> false;
-keep_compile_option(asm) -> false;
keep_compile_option(from_core) -> false;
%% The parse transform will already have been applied, may cause
%% problems if it is re-applied.
@@ -482,6 +686,57 @@ format_sig(Type, RecDict) ->
flat_format(Fmt, Lst) ->
lists:flatten(io_lib:format(Fmt, Lst)).
+-spec get_options_with_tag(atom(), abstract_code()) -> [term()].
+
+get_options_with_tag(Tag, Abs) ->
+ lists:flatten([O || {attribute, _, Tag0, O} <- Abs, Tag =:= Tag0]).
+
+%% Check F/A, and collect (unchecked) warning tags with line and file.
+-spec check_fa_list([collected_attribute()], atom(), [fa()]) ->
+ [{{atom(), erl_anno:line(), file:filename()},fa()}].
+
+check_fa_list(AttrFile, Tag, Functions) ->
+ FuncTab = gb_sets:from_list(Functions),
+ check_fa_list1(AttrFile, Tag, FuncTab).
+
+check_fa_list1([{Args, L, File}|Left], Tag, Funcs) ->
+ TermsL = [{{Tag0, L, File}, Term} ||
+ {Tags, Terms0} <- lists:flatten([Args]),
+ Tag0 <- lists:flatten([Tags]),
+ Tag =:= '*' orelse Tag =:= Tag0,
+ Term <- lists:flatten([Terms0])],
+ case lists:dropwhile(fun({_, T}) -> is_fa(T) end, TermsL) of
+ [] -> ok;
+ [{_, Bad}|_] ->
+ Msg1 = flat_format(" Bad function ~w in line ~s:~w",
+ [Bad, File, L]),
+ throw({error, Msg1})
+ end,
+ case lists:dropwhile(fun({_, FA}) -> is_known(FA, Funcs) end, TermsL) of
+ [] -> ok;
+ [{_, {F, A}}|_] ->
+ Msg2 = flat_format(" Unknown function ~w/~w in line ~s:~w",
+ [F, A, File, L]),
+ throw({error, Msg2})
+ end,
+ TermsL ++ check_fa_list1(Left, Tag, Funcs);
+check_fa_list1([], _Tag, _Funcs) -> [].
+
+is_known(FA, Funcs) ->
+ gb_sets:is_element(FA, Funcs).
+
+-spec is_fa_list(term()) -> boolean().
+
+is_fa_list([E|L]) -> is_fa(E) andalso is_fa_list(L);
+is_fa_list([]) -> true;
+is_fa_list(_) -> false.
+
+-spec is_fa(term()) -> boolean().
+
+is_fa({FuncName, Arity})
+ when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> true;
+is_fa(_) -> false.
+
%%-------------------------------------------------------------------
%% Author : Per Gustafsson <[email protected]>
%% Description : Provides better printing of binaries.
@@ -586,3 +841,8 @@ parallelism() ->
CPUs = erlang:system_info(logical_processors_available),
Schedulers = erlang:system_info(schedulers),
min(CPUs, Schedulers).
+
+-spec family([{K,V}]) -> [{K,[V]}].
+
+family(L) ->
+ sofs:to_external(sofs:rel2fam(sofs:relation(L))).
diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl
index 1338997899..4be93c75bf 100644
--- a/lib/dialyzer/src/dialyzer_worker.erl
+++ b/lib/dialyzer/src/dialyzer_worker.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return
index e89caf3cf7..4103a2d8b4 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return
@@ -1,2 +1,2 @@
-supervisor_incorrect_return.erl:14: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),non_neg_integer()} | {'one_for_one',non_neg_integer(),non_neg_integer()} | {'rest_for_one',non_neg_integer(),non_neg_integer()} | {'simple_one_for_one',non_neg_integer(),non_neg_integer()},[{_,{atom() | tuple(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom() | tuple()]}]}}, which is the expected return type for the callback of supervisor behaviour
+supervisor_incorrect_return.erl:14: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{},[{_,{atom() | tuple(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom() | tuple()]} | #{}]}}, which is the expected return type for the callback of supervisor behaviour
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/custom_sup.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/custom_sup.erl
index 76da1fda70..401ee88eab 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/src/custom_sup.erl
+++ b/lib/dialyzer/test/behaviour_SUITE_data/src/custom_sup.erl
@@ -13,7 +13,7 @@
-export([init/1]).
-spec init(atom()) ->
- {ok, {{supervisor:strategy(), non_neg_integer(), non_neg_integer()},
+ {ok, {{supervisor:strategy(), non_neg_integer(), pos_integer()},
[supervisor:child_spec()]}} | ignore.
init(StorageName) ->
diff --git a/lib/dialyzer/test/dialyzer_SUITE.erl b/lib/dialyzer/test/dialyzer_SUITE.erl
index 8507525597..80f4508ec6 100644
--- a/lib/dialyzer/test/dialyzer_SUITE.erl
+++ b/lib/dialyzer/test/dialyzer_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014. All Rights Reserved.
+%% Copyright Ericsson AB 2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,12 +31,12 @@
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
--export([app_test/1, appup_test/1, beam_tests/1]).
+-export([app_test/1, appup_test/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test, appup_test, beam_tests].
+ [app_test, appup_test].
groups() ->
[].
@@ -75,38 +76,3 @@ app_test(Config) when is_list(Config) ->
%% Test that the .appup file does not contain any `basic' errors
appup_test(Config) when is_list(Config) ->
ok = ?t:appup_test(dialyzer).
-
-beam_tests(Config) when is_list(Config) ->
- Prog = <<"
- -module(no_auto_import).
-
- %% Copied from erl_lint_SUITE.erl, clash6
-
- -export([size/1]).
-
- size([]) ->
- 0;
- size({N,_}) ->
- N;
- size([_|T]) ->
- 1+size(T).
- ">>,
- Opts = [no_auto_import],
- {ok, BeamFile} = compile(Config, Prog, no_auto_import, Opts),
- [] = run_dialyzer([BeamFile]),
- ok.
-
-compile(Config, Prog, Module, CompileOpts) ->
- Source = lists:concat([Module, ".erl"]),
- PrivDir = ?config(priv_dir,Config),
- Filename = filename:join([PrivDir, Source]),
- ok = file:write_file(Filename, Prog),
- Opts = [{outdir, PrivDir}, debug_info | CompileOpts],
- {ok, Module} = compile:file(Filename, Opts),
- {ok, filename:join([PrivDir, lists:concat([Module, ".beam"])])}.
-
-run_dialyzer(Files) ->
- dialyzer:run([{analysis_type, plt_build},
- {files, Files},
- {from, byte_code},
- {check_plt, false}]).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options b/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options
index 44a65f6e90..3ff26b87db 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options
@@ -1 +1 @@
-{dialyzer_options, [{warnings, [no_unused, no_return, no_unknown]}]}.
+{dialyzer_options, [{warnings, [no_unused, no_return]}]}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/para b/lib/dialyzer/test/opaque_SUITE_data/results/para
index 3aaa238de6..8fe67e39ad 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/para
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/para
@@ -7,15 +7,27 @@ para1.erl:38: Attempt to test for equality between a term of type para1_adt:t(in
para1.erl:43: Attempt to test for equality between a term of type para1_adt:t() and a term of opaque type para1_adt:t(atom())
para1.erl:48: Attempt to test for equality between a term of type para1_adt:t(integer()) and a term of opaque type para1_adt:t()
para1.erl:53: The test {3,2} =:= {'a','b'} can never evaluate to 'true'
-para2.erl:103: Attempt to test for equality between a term of type para2_adt:circ({{integer(),integer()},{integer(),integer()}},{{integer(),integer()},{integer(),integer()}}) and a term of opaque type para2_adt:circ({{integer(),integer()},{integer(),integer()}})
+para2.erl:103: Attempt to test for equality between a term of type para2_adt:circ(integer(),integer()) and a term of opaque type para2_adt:circ(integer())
para2.erl:117: Attempt to test for equality between a term of type para2_adt:un(atom(),integer()) and a term of opaque type para2_adt:un(integer(),atom())
para2.erl:31: The test 'a' =:= 'b' can never evaluate to 'true'
para2.erl:61: Attempt to test for equality between a term of type para2_adt:c2() and a term of opaque type para2_adt:c1()
para2.erl:66: The test 'a' =:= 'b' can never evaluate to 'true'
-para2.erl:88: The test para2:circ({{integer(),integer()},{integer(),integer()}}) =:= para2:circ({{integer(),integer()},{integer(),integer()}},{{integer(),integer()},{integer(),integer()}}) can never evaluate to 'true'
+para2.erl:88: The test para2:circ(integer()) =:= para2:circ(integer(),integer()) can never evaluate to 'true'
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: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
+para4.erl:21: Invalid type specification for function para4:a/1. The success typing is (dict:dict(atom() | integer(),atom() | integer()) | para4:d_all()) -> [{atom() | integer(),atom() | integer()}]
+para4.erl:26: Invalid type specification for function para4:i/1. The success typing is (dict:dict(atom() | integer(),atom() | integer()) | para4:d_all()) -> [{atom() | integer(),atom() | integer()}]
+para4.erl:31: Invalid type specification for function para4:t/1. The success typing is (dict:dict(atom() | integer(),atom() | integer()) | para4:d_all()) -> [{atom() | integer(),atom() | integer()}]
+para4.erl:59: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(integer())
+para4.erl:64: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(atom())
+para4.erl:69: Attempt to test for equality between a term of type para4_adt:int(1 | 2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2)
+para4.erl:74: Attempt to test for equality between a term of type para4_adt:int(2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2)
+para4.erl:79: Attempt to test for equality between a term of type para4_adt:int(2 | 3 | 4) and a term of opaque type para4_adt:int(5 | 6 | 7)
+para4.erl:84: Attempt to test for equality between a term of type para4_adt:un(3 | 4) and a term of opaque type para4_adt:un(1 | 2)
+para4.erl:89: Attempt to test for equality between a term of type para4_adt:tup({_,_}) and a term of opaque type para4_adt:tup(tuple())
+para5.erl:13: Attempt to test for inequality between a term of type para5_adt:dd(atom()) and a term of opaque type para5_adt:d()
+para5.erl:8: The test para5_adt:d() =:= para5_adt:d() can never evaluate to 'true'
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/simple b/lib/dialyzer/test/opaque_SUITE_data/results/simple
index 29864d6065..1a7a139d6e 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/simple
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/simple
@@ -28,11 +28,11 @@ rec_api.erl:99: Record construction #r2{f1::10} violates the declared type of fi
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
simple1_api.erl:142: Attempt to test for equality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1()
-simple1_api.erl:148: Guard test simple1_adt:o2() =:= A::simple1_adt:o1() contains an opaque term as 1st argument
+simple1_api.erl:148: Guard test simple1_adt:o2() =:= A::simple1_adt:o1() contains opaque terms as 1st and 2nd arguments
simple1_api.erl:154: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1()
simple1_api.erl:160: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1()
simple1_api.erl:165: Attempt to test for equality between a term of type simple1_adt:c2() and a term of opaque type simple1_adt:c1()
-simple1_api.erl:181: Guard test A::simple1_adt:d1() =< B::simple1_adt:d2() contains an opaque term as 1st argument
+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()
@@ -72,12 +72,12 @@ simple1_api.erl:499: The call 'foo':A(A::simple1_api:i()) requires that A is of
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() | tuple() not simple1_api:i()
simple1_api.erl:511: The call A:'foo'(A::simple1_adt:i()) requires that A is of type atom() | tuple() not simple1_adt:i()
-simple1_api.erl:519: Guard test A::simple1_adt:d2() == B::simple1_adt:d1() contains an opaque term as 1st argument
+simple1_api.erl:519: Guard test A::simple1_adt:d2() == B::simple1_adt:d1() contains opaque terms as 1st and 2nd arguments
simple1_api.erl:534: Guard test A::simple1_adt:d1() >= 3 contains an opaque term as 1st argument
simple1_api.erl:536: Guard test A::simple1_adt:d1() == 3 contains an opaque term as 1st argument
simple1_api.erl:538: Guard test A::simple1_adt:d1() =:= 3 contains an opaque term as 1st argument
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 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'}
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
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/big_external_type.erl b/lib/dialyzer/test/opaque_SUITE_data/src/big_external_type.erl
new file mode 100644
index 0000000000..d286a378ed
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/big_external_type.erl
@@ -0,0 +1,526 @@
+%%
+%% %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
+%%
+%% 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%
+%%
+
+%%% A copy of small_SUITE_data/src/big_external_type.erl, where
+%%% abstract_expr() is opaque. The transformation of forms to types is
+%%% now much faster than it used to be, for this module.
+
+-module(big_external_type).
+
+-export([parse_form/1,parse_exprs/1,parse_term/1]).
+-export([normalise/1,tokens/1,tokens/2]).
+-export([inop_prec/1,preop_prec/1,func_prec/0,max_prec/0]).
+
+-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
+ error_info/0]).
+
+%% Start of Abstract Format
+
+-type line() :: erl_anno:line().
+
+-export_type([af_record_index/0, af_record_field/1, af_record_name/0,
+ af_field_name/0, af_function_decl/0]).
+
+-export_type([af_module/0, af_export/0, af_import/0, af_fa_list/0,
+ af_compile/0, af_file/0, af_record_decl/0,
+ af_field_decl/0, af_wild_attribute/0,
+ af_record_update/1, af_catch/0, af_local_call/0,
+ af_remote_call/0, af_args/0, af_local_function/0,
+ af_remote_function/0, af_list_comprehension/0,
+ af_binary_comprehension/0, af_template/0,
+ af_qualifier_seq/0, af_qualifier/0, af_generator/0,
+ af_filter/0, af_block/0, af_if/0, af_case/0, af_try/0,
+ af_clause_seq/0, af_catch_clause_seq/0, af_receive/0,
+ af_local_fun/0, af_remote_fun/0, af_fun/0, af_query/0,
+ af_query_access/0, af_clause/0,
+ af_catch_clause/0, af_catch_pattern/0, af_catch_class/0,
+ af_body/0, af_guard_seq/0, af_guard/0, af_guard_test/0,
+ af_record_access/1, af_guard_call/0,
+ af_remote_guard_call/0, af_pattern/0, af_literal/0,
+ af_atom/0, af_lit_atom/1, af_integer/0, af_float/0,
+ af_string/0, af_match/1, af_variable/0,
+ af_anon_variable/0, af_tuple/1, af_nil/0, af_cons/1,
+ af_bin/1, af_binelement/1, af_binelement_size/0,
+ af_binary_op/1, af_binop/0, af_unary_op/1, af_unop/0]).
+
+-type abstract_form() :: ?MODULE:af_module()
+ | ?MODULE:af_export()
+ | ?MODULE:af_import()
+ | ?MODULE:af_compile()
+ | ?MODULE:af_file()
+ | ?MODULE:af_record_decl()
+ | ?MODULE:af_wild_attribute()
+ | ?MODULE:af_function_decl().
+
+-type af_module() :: {attribute, line(), module, module()}.
+
+-type af_export() :: {attribute, line(), export, ?MODULE:af_fa_list()}.
+
+-type af_import() :: {attribute, line(), import, ?MODULE:af_fa_list()}.
+
+-type af_fa_list() :: [{function(), arity()}].
+
+-type af_compile() :: {attribute, line(), compile, any()}.
+
+-type af_file() :: {attribute, line(), file, {string(), line()}}.
+
+-type af_record_decl() ::
+ {attribute, line(), record, ?MODULE:af_record_name(), [?MODULE:af_field_decl()]}.
+
+-type af_field_decl() :: {record_field, line(), ?MODULE:af_atom()}
+ | {record_field, line(), ?MODULE:af_atom(), ?MODULE:abstract_expr()}.
+
+%% Types and specs, among other things...
+-type af_wild_attribute() :: {attribute, line(), ?MODULE:af_atom(), any()}.
+
+-type af_function_decl() ::
+ {function, line(), function(), arity(), ?MODULE:af_clause_seq()}.
+
+-opaque abstract_expr() :: ?MODULE:af_literal()
+ | ?MODULE:af_match(?MODULE:abstract_expr())
+ | ?MODULE:af_variable()
+ | ?MODULE:af_tuple(?MODULE:abstract_expr())
+ | ?MODULE:af_nil()
+ | ?MODULE:af_cons(?MODULE:abstract_expr())
+ | ?MODULE:af_bin(?MODULE:abstract_expr())
+ | ?MODULE:af_binary_op(?MODULE:abstract_expr())
+ | ?MODULE:af_unary_op(?MODULE:abstract_expr())
+ | ?MODULE:af_record_access(?MODULE:abstract_expr())
+ | ?MODULE:af_record_update(?MODULE:abstract_expr())
+ | ?MODULE:af_record_index()
+ | ?MODULE:af_record_field(?MODULE:abstract_expr())
+ | ?MODULE:af_catch()
+ | ?MODULE:af_local_call()
+ | ?MODULE:af_remote_call()
+ | ?MODULE:af_list_comprehension()
+ | ?MODULE:af_binary_comprehension()
+ | ?MODULE:af_block()
+ | ?MODULE:af_if()
+ | ?MODULE:af_case()
+ | ?MODULE:af_try()
+ | ?MODULE:af_receive()
+ | ?MODULE:af_local_fun()
+ | ?MODULE:af_remote_fun()
+ | ?MODULE:af_fun()
+ | ?MODULE:af_query()
+ | ?MODULE:af_query_access().
+
+-type af_record_update(T) :: {record,
+ line(),
+ ?MODULE:abstract_expr(),
+ ?MODULE:af_record_name(),
+ [?MODULE:af_record_field(T)]}.
+
+-type af_catch() :: {'catch', line(), ?MODULE:abstract_expr()}.
+
+-type af_local_call() :: {call, line(), ?MODULE:af_local_function(), ?MODULE:af_args()}.
+
+-type af_remote_call() :: {call, line(), ?MODULE:af_remote_function(), ?MODULE:af_args()}.
+
+-type af_args() :: [?MODULE:abstract_expr()].
+
+-type af_local_function() :: ?MODULE:abstract_expr().
+
+-type af_remote_function() ::
+ {remote, line(), ?MODULE:abstract_expr(), ?MODULE:abstract_expr()}.
+
+-type af_list_comprehension() ::
+ {lc, line(), ?MODULE:af_template(), ?MODULE:af_qualifier_seq()}.
+
+-type af_binary_comprehension() ::
+ {bc, line(), ?MODULE:af_template(), ?MODULE:af_qualifier_seq()}.
+
+-type af_template() :: ?MODULE:abstract_expr().
+
+-type af_qualifier_seq() :: [?MODULE:af_qualifier()].
+
+-type af_qualifier() :: ?MODULE:af_generator() | ?MODULE:af_filter().
+
+-type af_generator() :: {generate, line(), ?MODULE:af_pattern(), ?MODULE:abstract_expr()}
+ | {b_generate, line(), ?MODULE:af_pattern(), ?MODULE:abstract_expr()}.
+
+-type af_filter() :: ?MODULE:abstract_expr().
+
+-type af_block() :: {block, line(), ?MODULE:af_body()}.
+
+-type af_if() :: {'if', line(), ?MODULE:af_clause_seq()}.
+
+-type af_case() :: {'case', line(), ?MODULE:abstract_expr(), ?MODULE:af_clause_seq()}.
+
+-type af_try() :: {'try',
+ line(),
+ ?MODULE:af_body(),
+ ?MODULE:af_clause_seq(),
+ ?MODULE:af_catch_clause_seq(),
+ ?MODULE:af_body()}.
+
+-type af_clause_seq() :: [?MODULE:af_clause(), ...].
+
+-type af_catch_clause_seq() :: [?MODULE:af_clause(), ...].
+
+-type af_receive() ::
+ {'receive', line(), ?MODULE:af_clause_seq()}
+ | {'receive', line(), ?MODULE:af_clause_seq(), ?MODULE:abstract_expr(), ?MODULE:af_body()}.
+
+-type af_local_fun() :: {'fun', line(), {function, function(), arity()}}.
+
+-type af_remote_fun() ::
+ {'fun', line(), {function, module(), function(), arity()}}
+ | {'fun', line(), {function, ?MODULE:af_atom(), ?MODULE:af_atom(), ?MODULE:af_integer()}}.
+
+-type af_fun() :: {'fun', line(), {clauses, ?MODULE:af_clause_seq()}}.
+
+-type af_query() :: {'query', line(), ?MODULE:af_list_comprehension()}.
+
+-type af_query_access() ::
+ {record_field, line(), ?MODULE:abstract_expr(), ?MODULE:af_field_name()}.
+
+-type abstract_clause() :: ?MODULE:af_clause() | ?MODULE:af_catch_clause().
+
+-type af_clause() ::
+ {clause, line(), [?MODULE:af_pattern()], ?MODULE:af_guard_seq(), ?MODULE:af_body()}.
+
+-type af_catch_clause() ::
+ {clause, line(), [?MODULE:af_catch_pattern()], ?MODULE:af_guard_seq(), ?MODULE:af_body()}.
+
+-type af_catch_pattern() ::
+ {?MODULE:af_catch_class(), ?MODULE:af_pattern(), ?MODULE:af_anon_variable()}.
+
+-type af_catch_class() ::
+ ?MODULE:af_variable()
+ | ?MODULE:af_lit_atom(throw) | ?MODULE:af_lit_atom(error) | ?MODULE:af_lit_atom(exit).
+
+-type af_body() :: [?MODULE:abstract_expr(), ...].
+
+-type af_guard_seq() :: [?MODULE:af_guard()].
+
+-type af_guard() :: [?MODULE:af_guard_test(), ...].
+
+-type af_guard_test() :: ?MODULE:af_literal()
+ | ?MODULE:af_variable()
+ | ?MODULE:af_tuple(?MODULE:af_guard_test())
+ | ?MODULE:af_nil()
+ | ?MODULE:af_cons(?MODULE:af_guard_test())
+ | ?MODULE:af_bin(?MODULE:af_guard_test())
+ | ?MODULE:af_binary_op(?MODULE:af_guard_test())
+ | ?MODULE:af_unary_op(?MODULE:af_guard_test())
+ | ?MODULE:af_record_access(?MODULE:af_guard_test())
+ | ?MODULE:af_record_index()
+ | ?MODULE:af_record_field(?MODULE:af_guard_test())
+ | ?MODULE:af_guard_call()
+ | ?MODULE:af_remote_guard_call().
+
+-type af_record_access(T) ::
+ {record, line(), ?MODULE:af_record_name(), [?MODULE:af_record_field(T)]}.
+
+-type af_guard_call() :: {call, line(), function(), [?MODULE:af_guard_test()]}.
+
+-type af_remote_guard_call() ::
+ {call, line(), atom(), ?MODULE:af_lit_atom(erlang), [?MODULE:af_guard_test()]}.
+
+-type af_pattern() :: ?MODULE:af_literal()
+ | ?MODULE:af_match(?MODULE:af_pattern())
+ | ?MODULE:af_variable()
+ | ?MODULE:af_anon_variable()
+ | ?MODULE:af_tuple(?MODULE:af_pattern())
+ | ?MODULE:af_nil()
+ | ?MODULE:af_cons(?MODULE:af_pattern())
+ | ?MODULE:af_bin(?MODULE:af_pattern())
+ | ?MODULE:af_binary_op(?MODULE:af_pattern())
+ | ?MODULE:af_unary_op(?MODULE:af_pattern())
+ | ?MODULE:af_record_index()
+ | ?MODULE:af_record_field(?MODULE:af_pattern()).
+
+-type af_literal() :: ?MODULE:af_atom() | ?MODULE:af_integer() | ?MODULE:af_float() | ?MODULE:af_string().
+
+-type af_atom() :: ?MODULE:af_lit_atom(atom()).
+
+-type af_lit_atom(A) :: {atom, line(), A}.
+
+-type af_integer() :: {integer, line(), non_neg_integer()}.
+
+-type af_float() :: {float, line(), float()}.
+
+-type af_string() :: {string, line(), [byte()]}.
+
+-type af_match(T) :: {match, line(), T, T}.
+
+-type af_variable() :: {var, line(), atom()}.
+
+-type af_anon_variable() :: {var, line(), '_'}.
+
+-type af_tuple(T) :: {tuple, line(), [T]}.
+
+-type af_nil() :: {nil, line()}.
+
+-type af_cons(T) :: {cons, line, T, T}.
+
+-type af_bin(T) :: {bin, line(), [?MODULE:af_binelement(T)]}.
+
+-type af_binelement(T) :: {bin_element,
+ line(),
+ T,
+ ?MODULE:af_binelement_size(),
+ type_specifier_list()}.
+
+-type af_binelement_size() :: default | ?MODULE:abstract_expr().
+
+-type af_binary_op(T) :: {op, line(), T, ?MODULE:af_binop(), T}.
+
+-type af_binop() :: '/' | '*' | 'div' | 'rem' | 'band' | 'and' | '+' | '-'
+ | 'bor' | 'bxor' | 'bsl' | 'bsr' | 'or' | 'xor' | '++'
+ | '--' | '==' | '/=' | '=<' | '<' | '>=' | '>' | '=:='
+ | '=/='.
+
+-type af_unary_op(T) :: {op, line(), ?MODULE:af_unop(), T}.
+
+-type af_unop() :: '+' | '*' | 'bnot' | 'not'.
+
+%% See also lib/stdlib/{src/erl_bits.erl,include/erl_bits.hrl}.
+-type type_specifier_list() :: default | [type_specifier(), ...].
+
+-type type_specifier() :: af_type()
+ | af_signedness()
+ | af_endianness()
+ | af_unit().
+
+-type af_type() :: integer
+ | float
+ | binary
+ | bytes
+ | bitstring
+ | bits
+ | utf8
+ | utf16
+ | utf32.
+
+-type af_signedness() :: signed | unsigned.
+
+-type af_endianness() :: big | little | native.
+
+-type af_unit() :: {unit, 1..256}.
+
+-type af_record_index() ::
+ {record_index, line(), af_record_name(), af_field_name()}.
+
+-type af_record_field(T) :: {record_field, line(), af_field_name(), T}.
+
+-type af_record_name() :: atom().
+
+-type af_field_name() :: atom().
+
+%% End of Abstract Format
+
+-type error_description() :: term().
+-type error_info() :: {erl_anno:line(), module(), error_description()}.
+-type token() :: {Tag :: atom(), Line :: erl_anno:line()}.
+
+%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
+%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
+
+-define(mkop2(L, OpPos, R),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,L,R}
+ end).
+
+-define(mkop1(OpPos, A),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,A}
+ end).
+
+%% keep track of line info in tokens
+-define(line(Tup), element(2, Tup)).
+
+%% Entry points compatible to old erl_parse.
+%% These really suck and are only here until Calle gets multiple
+%% entry points working.
+
+-spec parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ AbsForm :: abstract_form(),
+ ErrorInfo :: error_info().
+parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
+ parse([{'-',L1},{'spec',L2}|Tokens]);
+parse_form([{'-',L1},{atom,L2,callback}|Tokens]) ->
+ parse([{'-',L1},{'callback',L2}|Tokens]);
+parse_form(Tokens) ->
+ parse(Tokens).
+
+-spec parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ ExprList :: [abstract_expr()],
+ ErrorInfo :: error_info().
+parse_exprs(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
+ {ok,Exprs};
+ {error,_} = Err -> Err
+ end.
+
+-spec parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ Term :: term(),
+ ErrorInfo :: error_info().
+parse_term(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[Expr]}]}} ->
+ try normalise(Expr) of
+ Term -> {ok,Term}
+ catch
+ _:_R -> {error,{?line(Expr),?MODULE,"bad term"}}
+ end;
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[_E1,E2|_Es]}]}} ->
+ {error,{?line(E2),?MODULE,"bad term"}};
+ {error,_} = Err -> Err
+ end.
+
+%% Convert between the abstract form of a term and a term.
+
+-spec normalise(AbsTerm) -> Data when
+ AbsTerm :: abstract_expr(),
+ Data :: term().
+normalise({char,_,C}) -> C;
+normalise({integer,_,I}) -> I;
+normalise({float,_,F}) -> F;
+normalise({atom,_,A}) -> A;
+normalise({string,_,S}) -> S;
+normalise({nil,_}) -> [];
+normalise({bin,_,Fs}) ->
+ {value, B, _} =
+ eval_bits:expr_grp(Fs, [],
+ fun(E, _) ->
+ {value, normalise(E), []}
+ end, [], true),
+ B;
+normalise({cons,_,Head,Tail}) ->
+ [normalise(Head)|normalise(Tail)];
+normalise({tuple,_,Args}) ->
+ list_to_tuple(normalise_list(Args));
+%% Atom dot-notation, as in 'foo.bar.baz'
+%% Special case for unary +/-.
+normalise({op,_,'+',{char,_,I}}) -> I;
+normalise({op,_,'+',{integer,_,I}}) -> I;
+normalise({op,_,'+',{float,_,F}}) -> F;
+normalise({op,_,'-',{char,_,I}}) -> -I; %Weird, but compatible!
+normalise({op,_,'-',{integer,_,I}}) -> -I;
+normalise({op,_,'-',{float,_,F}}) -> -F;
+normalise(X) -> erlang:error({badarg, X}).
+
+normalise_list([H|T]) ->
+ [normalise(H)|normalise_list(T)];
+normalise_list([]) ->
+ [].
+
+%% Generate a list of tokens representing the abstract term.
+
+-spec tokens(AbsTerm) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ Tokens :: [token()].
+tokens(Abs) ->
+ tokens(Abs, []).
+
+-spec tokens(AbsTerm, MoreTokens) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ MoreTokens :: [token()],
+ Tokens :: [token()].
+tokens({char,L,C}, More) -> [{char,L,C}|More];
+tokens({integer,L,N}, More) -> [{integer,L,N}|More];
+tokens({float,L,F}, More) -> [{float,L,F}|More];
+tokens({atom,L,A}, More) -> [{atom,L,A}|More];
+tokens({var,L,V}, More) -> [{var,L,V}|More];
+tokens({string,L,S}, More) -> [{string,L,S}|More];
+tokens({nil,L}, More) -> [{'[',L},{']',L}|More];
+tokens({cons,L,Head,Tail}, More) ->
+ [{'[',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens({tuple,L,[]}, More) ->
+ [{'{',L},{'}',L}|More];
+tokens({tuple,L,[E|Es]}, More) ->
+ [{'{',L}|tokens(E, tokens_tuple(Es, ?line(E), More))].
+
+tokens_tail({cons,L,Head,Tail}, More) ->
+ [{',',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens_tail({nil,L}, More) ->
+ [{']',L}|More];
+tokens_tail(Other, More) ->
+ L = ?line(Other),
+ [{'|',L}|tokens(Other, [{']',L}|More])].
+
+tokens_tuple([E|Es], Line, More) ->
+ [{',',Line}|tokens(E, tokens_tuple(Es, ?line(E), More))];
+tokens_tuple([], Line, More) ->
+ [{'}',Line}|More].
+
+%% Give the relative precedences of operators.
+
+inop_prec('=') -> {150,100,100};
+inop_prec('!') -> {150,100,100};
+inop_prec('orelse') -> {160,150,150};
+inop_prec('andalso') -> {200,160,160};
+inop_prec('==') -> {300,200,300};
+inop_prec('/=') -> {300,200,300};
+inop_prec('=<') -> {300,200,300};
+inop_prec('<') -> {300,200,300};
+inop_prec('>=') -> {300,200,300};
+inop_prec('>') -> {300,200,300};
+inop_prec('=:=') -> {300,200,300};
+inop_prec('=/=') -> {300,200,300};
+inop_prec('++') -> {400,300,300};
+inop_prec('--') -> {400,300,300};
+inop_prec('+') -> {400,400,500};
+inop_prec('-') -> {400,400,500};
+inop_prec('bor') -> {400,400,500};
+inop_prec('bxor') -> {400,400,500};
+inop_prec('bsl') -> {400,400,500};
+inop_prec('bsr') -> {400,400,500};
+inop_prec('or') -> {400,400,500};
+inop_prec('xor') -> {400,400,500};
+inop_prec('*') -> {500,500,600};
+inop_prec('/') -> {500,500,600};
+inop_prec('div') -> {500,500,600};
+inop_prec('rem') -> {500,500,600};
+inop_prec('band') -> {500,500,600};
+inop_prec('and') -> {500,500,600};
+inop_prec('#') -> {800,700,800};
+inop_prec(':') -> {900,800,900};
+inop_prec('.') -> {900,900,1000}.
+
+-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'.
+
+-spec preop_prec(pre_op()) -> {0 | 600 | 700, 100 | 700 | 800}.
+
+preop_prec('catch') -> {0,100};
+preop_prec('+') -> {600,700};
+preop_prec('-') -> {600,700};
+preop_prec('bnot') -> {600,700};
+preop_prec('not') -> {600,700};
+preop_prec('#') -> {700,800}.
+
+-spec func_prec() -> {800,700}.
+
+func_prec() -> {800,700}.
+
+-spec max_prec() -> 1000.
+
+max_prec() -> 1000.
+
+parse(T) ->
+ bar:foo(T).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/big_local_type.erl b/lib/dialyzer/test/opaque_SUITE_data/src/big_local_type.erl
new file mode 100644
index 0000000000..7daceb5260
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/big_local_type.erl
@@ -0,0 +1,523 @@
+%%
+%% %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
+%%
+%% 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%
+%%
+
+%%% A copy of small_SUITE_data/src/big_local_type.erl, where
+%%% abstract_expr() is opaque. The transformation of forms to types is
+%%% now much faster than it used to be, for this module.
+
+-module(big_local_type).
+
+-export([parse_form/1,parse_exprs/1,parse_term/1]).
+-export([normalise/1,tokens/1,tokens/2]).
+-export([inop_prec/1,preop_prec/1,func_prec/0,max_prec/0]).
+
+-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
+ error_info/0]).
+
+%% Start of Abstract Format
+
+-type line() :: erl_anno:line().
+
+-export_type([af_module/0, af_export/0, af_import/0, af_fa_list/0,
+ af_compile/0, af_file/0, af_record_decl/0,
+ af_field_decl/0, af_wild_attribute/0,
+ af_record_update/1, af_catch/0, af_local_call/0,
+ af_remote_call/0, af_args/0, af_local_function/0,
+ af_remote_function/0, af_list_comprehension/0,
+ af_binary_comprehension/0, af_template/0,
+ af_qualifier_seq/0, af_qualifier/0, af_generator/0,
+ af_filter/0, af_block/0, af_if/0, af_case/0, af_try/0,
+ af_clause_seq/0, af_catch_clause_seq/0, af_receive/0,
+ af_local_fun/0, af_remote_fun/0, af_fun/0, af_query/0,
+ af_query_access/0, af_clause/0,
+ af_catch_clause/0, af_catch_pattern/0, af_catch_class/0,
+ af_body/0, af_guard_seq/0, af_guard/0, af_guard_test/0,
+ af_record_access/1, af_guard_call/0,
+ af_remote_guard_call/0, af_pattern/0, af_literal/0,
+ af_atom/0, af_lit_atom/1, af_integer/0, af_float/0,
+ af_string/0, af_match/1, af_variable/0,
+ af_anon_variable/0, af_tuple/1, af_nil/0, af_cons/1,
+ af_bin/1, af_binelement/1, af_binelement_size/0,
+ af_binary_op/1, af_binop/0, af_unary_op/1, af_unop/0]).
+
+-type abstract_form() :: af_module()
+ | af_export()
+ | af_import()
+ | af_compile()
+ | af_file()
+ | af_record_decl()
+ | af_wild_attribute()
+ | af_function_decl().
+
+-type af_module() :: {attribute, line(), module, module()}.
+
+-type af_export() :: {attribute, line(), export, af_fa_list()}.
+
+-type af_import() :: {attribute, line(), import, af_fa_list()}.
+
+-type af_fa_list() :: [{function(), arity()}].
+
+-type af_compile() :: {attribute, line(), compile, any()}.
+
+-type af_file() :: {attribute, line(), file, {string(), line()}}.
+
+-type af_record_decl() ::
+ {attribute, line(), record, af_record_name(), [af_field_decl()]}.
+
+-type af_field_decl() :: {record_field, line(), af_atom()}
+ | {record_field, line(), af_atom(), abstract_expr()}.
+
+%% Types and specs, among other things...
+-type af_wild_attribute() :: {attribute, line(), af_atom(), any()}.
+
+-type af_function_decl() ::
+ {function, line(), function(), arity(), af_clause_seq()}.
+
+-opaque abstract_expr() :: af_literal()
+ | af_match(abstract_expr())
+ | af_variable()
+ | af_tuple(abstract_expr())
+ | af_nil()
+ | af_cons(abstract_expr())
+ | af_bin(abstract_expr())
+ | af_binary_op(abstract_expr())
+ | af_unary_op(abstract_expr())
+ | af_record_access(abstract_expr())
+ | af_record_update(abstract_expr())
+ | af_record_index()
+ | af_record_field(abstract_expr())
+ | af_catch()
+ | af_local_call()
+ | af_remote_call()
+ | af_list_comprehension()
+ | af_binary_comprehension()
+ | af_block()
+ | af_if()
+ | af_case()
+ | af_try()
+ | af_receive()
+ | af_local_fun()
+ | af_remote_fun()
+ | af_fun()
+ | af_query()
+ | af_query_access().
+
+-type af_record_update(T) :: {record,
+ line(),
+ abstract_expr(),
+ af_record_name(),
+ [af_record_field(T)]}.
+
+-type af_catch() :: {'catch', line(), abstract_expr()}.
+
+-type af_local_call() :: {call, line(), af_local_function(), af_args()}.
+
+-type af_remote_call() :: {call, line(), af_remote_function(), af_args()}.
+
+-type af_args() :: [abstract_expr()].
+
+-type af_local_function() :: abstract_expr().
+
+-type af_remote_function() ::
+ {remote, line(), abstract_expr(), abstract_expr()}.
+
+-type af_list_comprehension() ::
+ {lc, line(), af_template(), af_qualifier_seq()}.
+
+-type af_binary_comprehension() ::
+ {bc, line(), af_template(), af_qualifier_seq()}.
+
+-type af_template() :: abstract_expr().
+
+-type af_qualifier_seq() :: [af_qualifier()].
+
+-type af_qualifier() :: af_generator() | af_filter().
+
+-type af_generator() :: {generate, line(), af_pattern(), abstract_expr()}
+ | {b_generate, line(), af_pattern(), abstract_expr()}.
+
+-type af_filter() :: abstract_expr().
+
+-type af_block() :: {block, line(), af_body()}.
+
+-type af_if() :: {'if', line(), af_clause_seq()}.
+
+-type af_case() :: {'case', line(), abstract_expr(), af_clause_seq()}.
+
+-type af_try() :: {'try',
+ line(),
+ af_body(),
+ af_clause_seq(),
+ af_catch_clause_seq(),
+ af_body()}.
+
+-type af_clause_seq() :: [af_clause(), ...].
+
+-type af_catch_clause_seq() :: [af_clause(), ...].
+
+-type af_receive() ::
+ {'receive', line(), af_clause_seq()}
+ | {'receive', line(), af_clause_seq(), abstract_expr(), af_body()}.
+
+-type af_local_fun() :: {'fun', line(), {function, function(), arity()}}.
+
+-type af_remote_fun() ::
+ {'fun', line(), {function, module(), function(), arity()}}
+ | {'fun', line(), {function, af_atom(), af_atom(), af_integer()}}.
+
+-type af_fun() :: {'fun', line(), {clauses, af_clause_seq()}}.
+
+-type af_query() :: {'query', line(), af_list_comprehension()}.
+
+-type af_query_access() ::
+ {record_field, line(), abstract_expr(), af_field_name()}.
+
+-type abstract_clause() :: af_clause() | af_catch_clause().
+
+-type af_clause() ::
+ {clause, line(), [af_pattern()], af_guard_seq(), af_body()}.
+
+-type af_catch_clause() ::
+ {clause, line(), [af_catch_pattern()], af_guard_seq(), af_body()}.
+
+-type af_catch_pattern() ::
+ {af_catch_class(), af_pattern(), af_anon_variable()}.
+
+-type af_catch_class() ::
+ af_variable()
+ | af_lit_atom(throw) | af_lit_atom(error) | af_lit_atom(exit).
+
+-type af_body() :: [abstract_expr(), ...].
+
+-type af_guard_seq() :: [af_guard()].
+
+-type af_guard() :: [af_guard_test(), ...].
+
+-type af_guard_test() :: af_literal()
+ | af_variable()
+ | af_tuple(af_guard_test())
+ | af_nil()
+ | af_cons(af_guard_test())
+ | 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_index()
+ | af_record_field(af_guard_test())
+ | af_guard_call()
+ | af_remote_guard_call().
+
+-type af_record_access(T) ::
+ {record, line(), af_record_name(), [af_record_field(T)]}.
+
+-type af_guard_call() :: {call, line(), function(), [af_guard_test()]}.
+
+-type af_remote_guard_call() ::
+ {call, line(), atom(), af_lit_atom(erlang), [af_guard_test()]}.
+
+-type af_pattern() :: af_literal()
+ | af_match(af_pattern())
+ | af_variable()
+ | af_anon_variable()
+ | af_tuple(af_pattern())
+ | af_nil()
+ | af_cons(af_pattern())
+ | af_bin(af_pattern())
+ | af_binary_op(af_pattern())
+ | af_unary_op(af_pattern())
+ | af_record_index()
+ | af_record_field(af_pattern()).
+
+-type af_literal() :: af_atom() | af_integer() | af_float() | af_string().
+
+-type af_atom() :: af_lit_atom(atom()).
+
+-type af_lit_atom(A) :: {atom, line(), A}.
+
+-type af_integer() :: {integer, line(), non_neg_integer()}.
+
+-type af_float() :: {float, line(), float()}.
+
+-type af_string() :: {string, line(), [byte()]}.
+
+-type af_match(T) :: {match, line(), T, T}.
+
+-type af_variable() :: {var, line(), atom()}.
+
+-type af_anon_variable() :: {var, line(), '_'}.
+
+-type af_tuple(T) :: {tuple, line(), [T]}.
+
+-type af_nil() :: {nil, line()}.
+
+-type af_cons(T) :: {cons, line, T, T}.
+
+-type af_bin(T) :: {bin, line(), [af_binelement(T)]}.
+
+-type af_binelement(T) :: {bin_element,
+ line(),
+ T,
+ af_binelement_size(),
+ type_specifier_list()}.
+
+-type af_binelement_size() :: default | abstract_expr().
+
+-type af_binary_op(T) :: {op, line(), T, af_binop(), T}.
+
+-type af_binop() :: '/' | '*' | 'div' | 'rem' | 'band' | 'and' | '+' | '-'
+ | 'bor' | 'bxor' | 'bsl' | 'bsr' | 'or' | 'xor' | '++'
+ | '--' | '==' | '/=' | '=<' | '<' | '>=' | '>' | '=:='
+ | '=/='.
+
+-type af_unary_op(T) :: {op, line(), af_unop(), T}.
+
+-type af_unop() :: '+' | '*' | 'bnot' | 'not'.
+
+%% See also lib/stdlib/{src/erl_bits.erl,include/erl_bits.hrl}.
+-type type_specifier_list() :: default | [type_specifier(), ...].
+
+-type type_specifier() :: af_type()
+ | af_signedness()
+ | af_endianness()
+ | af_unit().
+
+-type af_type() :: integer
+ | float
+ | binary
+ | bytes
+ | bitstring
+ | bits
+ | utf8
+ | utf16
+ | utf32.
+
+-type af_signedness() :: signed | unsigned.
+
+-type af_endianness() :: big | little | native.
+
+-type af_unit() :: {unit, 1..256}.
+
+-type af_record_index() ::
+ {record_index, line(), af_record_name(), af_field_name()}.
+
+-type af_record_field(T) :: {record_field, line(), af_field_name(), T}.
+
+-type af_record_name() :: atom().
+
+-type af_field_name() :: atom().
+
+%% End of Abstract Format
+
+-type error_description() :: term().
+-type error_info() :: {erl_anno:line(), module(), error_description()}.
+-type token() :: {Tag :: atom(), Line :: erl_anno:line()}.
+
+%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
+%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
+
+-define(mkop2(L, OpPos, R),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,L,R}
+ end).
+
+-define(mkop1(OpPos, A),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,A}
+ end).
+
+%% keep track of line info in tokens
+-define(line(Tup), element(2, Tup)).
+
+%% Entry points compatible to old erl_parse.
+%% These really suck and are only here until Calle gets multiple
+%% entry points working.
+
+-spec parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ AbsForm :: abstract_form(),
+ ErrorInfo :: error_info().
+parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
+ parse([{'-',L1},{'spec',L2}|Tokens]);
+parse_form([{'-',L1},{atom,L2,callback}|Tokens]) ->
+ parse([{'-',L1},{'callback',L2}|Tokens]);
+parse_form(Tokens) ->
+ parse(Tokens).
+
+-spec parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ ExprList :: [abstract_expr()],
+ ErrorInfo :: error_info().
+parse_exprs(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
+ {ok,Exprs};
+ {error,_} = Err -> Err
+ end.
+
+-spec parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ Term :: term(),
+ ErrorInfo :: error_info().
+parse_term(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[Expr]}]}} ->
+ try normalise(Expr) of
+ Term -> {ok,Term}
+ catch
+ _:_R -> {error,{?line(Expr),?MODULE,"bad term"}}
+ end;
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[_E1,E2|_Es]}]}} ->
+ {error,{?line(E2),?MODULE,"bad term"}};
+ {error,_} = Err -> Err
+ end.
+
+%% Convert between the abstract form of a term and a term.
+
+-spec normalise(AbsTerm) -> Data when
+ AbsTerm :: abstract_expr(),
+ Data :: term().
+normalise({char,_,C}) -> C;
+normalise({integer,_,I}) -> I;
+normalise({float,_,F}) -> F;
+normalise({atom,_,A}) -> A;
+normalise({string,_,S}) -> S;
+normalise({nil,_}) -> [];
+normalise({bin,_,Fs}) ->
+ {value, B, _} =
+ eval_bits:expr_grp(Fs, [],
+ fun(E, _) ->
+ {value, normalise(E), []}
+ end, [], true),
+ B;
+normalise({cons,_,Head,Tail}) ->
+ [normalise(Head)|normalise(Tail)];
+normalise({tuple,_,Args}) ->
+ list_to_tuple(normalise_list(Args));
+%% Atom dot-notation, as in 'foo.bar.baz'
+%% Special case for unary +/-.
+normalise({op,_,'+',{char,_,I}}) -> I;
+normalise({op,_,'+',{integer,_,I}}) -> I;
+normalise({op,_,'+',{float,_,F}}) -> F;
+normalise({op,_,'-',{char,_,I}}) -> -I; %Weird, but compatible!
+normalise({op,_,'-',{integer,_,I}}) -> -I;
+normalise({op,_,'-',{float,_,F}}) -> -F;
+normalise(X) -> erlang:error({badarg, X}).
+
+normalise_list([H|T]) ->
+ [normalise(H)|normalise_list(T)];
+normalise_list([]) ->
+ [].
+
+%% Generate a list of tokens representing the abstract term.
+
+-spec tokens(AbsTerm) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ Tokens :: [token()].
+tokens(Abs) ->
+ tokens(Abs, []).
+
+-spec tokens(AbsTerm, MoreTokens) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ MoreTokens :: [token()],
+ Tokens :: [token()].
+tokens({char,L,C}, More) -> [{char,L,C}|More];
+tokens({integer,L,N}, More) -> [{integer,L,N}|More];
+tokens({float,L,F}, More) -> [{float,L,F}|More];
+tokens({atom,L,A}, More) -> [{atom,L,A}|More];
+tokens({var,L,V}, More) -> [{var,L,V}|More];
+tokens({string,L,S}, More) -> [{string,L,S}|More];
+tokens({nil,L}, More) -> [{'[',L},{']',L}|More];
+tokens({cons,L,Head,Tail}, More) ->
+ [{'[',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens({tuple,L,[]}, More) ->
+ [{'{',L},{'}',L}|More];
+tokens({tuple,L,[E|Es]}, More) ->
+ [{'{',L}|tokens(E, tokens_tuple(Es, ?line(E), More))].
+
+tokens_tail({cons,L,Head,Tail}, More) ->
+ [{',',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens_tail({nil,L}, More) ->
+ [{']',L}|More];
+tokens_tail(Other, More) ->
+ L = ?line(Other),
+ [{'|',L}|tokens(Other, [{']',L}|More])].
+
+tokens_tuple([E|Es], Line, More) ->
+ [{',',Line}|tokens(E, tokens_tuple(Es, ?line(E), More))];
+tokens_tuple([], Line, More) ->
+ [{'}',Line}|More].
+
+%% Give the relative precedences of operators.
+
+inop_prec('=') -> {150,100,100};
+inop_prec('!') -> {150,100,100};
+inop_prec('orelse') -> {160,150,150};
+inop_prec('andalso') -> {200,160,160};
+inop_prec('==') -> {300,200,300};
+inop_prec('/=') -> {300,200,300};
+inop_prec('=<') -> {300,200,300};
+inop_prec('<') -> {300,200,300};
+inop_prec('>=') -> {300,200,300};
+inop_prec('>') -> {300,200,300};
+inop_prec('=:=') -> {300,200,300};
+inop_prec('=/=') -> {300,200,300};
+inop_prec('++') -> {400,300,300};
+inop_prec('--') -> {400,300,300};
+inop_prec('+') -> {400,400,500};
+inop_prec('-') -> {400,400,500};
+inop_prec('bor') -> {400,400,500};
+inop_prec('bxor') -> {400,400,500};
+inop_prec('bsl') -> {400,400,500};
+inop_prec('bsr') -> {400,400,500};
+inop_prec('or') -> {400,400,500};
+inop_prec('xor') -> {400,400,500};
+inop_prec('*') -> {500,500,600};
+inop_prec('/') -> {500,500,600};
+inop_prec('div') -> {500,500,600};
+inop_prec('rem') -> {500,500,600};
+inop_prec('band') -> {500,500,600};
+inop_prec('and') -> {500,500,600};
+inop_prec('#') -> {800,700,800};
+inop_prec(':') -> {900,800,900};
+inop_prec('.') -> {900,900,1000}.
+
+-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'.
+
+-spec preop_prec(pre_op()) -> {0 | 600 | 700, 100 | 700 | 800}.
+
+preop_prec('catch') -> {0,100};
+preop_prec('+') -> {600,700};
+preop_prec('-') -> {600,700};
+preop_prec('bnot') -> {600,700};
+preop_prec('not') -> {600,700};
+preop_prec('#') -> {700,800}.
+
+-spec func_prec() -> {800,700}.
+
+func_prec() -> {800,700}.
+
+-spec max_prec() -> 1000.
+
+max_prec() -> 1000.
+
+parse(T) ->
+ bar:foo(T).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_macros.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_macros.hrl
new file mode 100644
index 0000000000..07243f8d23
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_macros.hrl
@@ -0,0 +1,215 @@
+%% -*- erlang-indent-level: 2 -*-
+%%------------------------------------------------------------------------------
+
+%%====================================================================
+%% Types
+%%====================================================================
+
+%% Code and Monitor servers' info.
+-record(svs, {
+ code :: pid(),
+ monitor :: pid()
+}).
+
+%% Tags of an AST's node.
+-record(tags, {
+ this = undefined :: cuter_cerl:tag() | undefined,
+ next = undefined :: cuter_cerl:tag() | undefined
+}).
+
+-type loaded_ret_atoms() :: cover_compiled | preloaded | non_existing.
+-type servers() :: #svs{}.
+-type ast_tags() :: #tags{}.
+
+%%====================================================================
+%% Directories
+%%====================================================================
+
+-define(RELATIVE_TMP_DIR, "temp").
+-define(PYTHON_CALL, ?PYTHON_PATH ++ " -u " ++ ?PRIV ++ "/cuter_interface.py").
+
+%%====================================================================
+%% Prefixes
+%%====================================================================
+
+-define(DEPTH_PREFIX, '__conc_depth').
+-define(EXECUTION_PREFIX, '__conc_prefix').
+-define(SYMBOLIC_PREFIX, '__s').
+-define(CONCOLIC_PREFIX_MSG, '__concm').
+-define(ZIPPED_VALUE_PREFIX, '__czip').
+-define(CONCOLIC_PREFIX_PDICT, '__concp').
+-define(FUNCTION_PREFIX, '__cfunc').
+-define(UNBOUND_VAR_PREFIX, '__uboundvar').
+-define(BRANCH_TAG_PREFIX, '__branch_tag').
+-define(VISITED_TAGS_PREFIX, '__visited_tags').
+-define(EXECUTION_COUNTER_PREFIX, '__exec_counter').
+
+%%====================================================================
+%% Flags & Default Values
+%%====================================================================
+
+-define(LOGGING_FLAG, ok).
+-define(DELETE_TRACE, ok).
+-define(LOG_UNSUPPORTED_MFAS, ok).
+%%-define(VERBOSE_SCHEDULER, ok).
+%%-define(VERBOSE_FILE_DELETION, ok).
+%%-define(VERBOSE_SOLVING, ok).
+%%-define(VERBOSE_MERGING, ok).
+%%-define(VERBOSE_REPORTING, ok).
+-define(USE_SPECS, ok).
+
+%%====================================================================
+%% Solver Responses
+%%====================================================================
+
+-define(RSP_MODEL_DELIMITER_START, <<"model_start">>).
+-define(RSP_MODEL_DELIMITER_END, <<"model_end">>).
+
+%%====================================================================
+%% OpCodes for types in JSON objects
+%%====================================================================
+
+-define(JSON_TYPE_ANY, 0).
+-define(JSON_TYPE_INT, 1).
+-define(JSON_TYPE_FLOAT, 2).
+-define(JSON_TYPE_ATOM, 3).
+-define(JSON_TYPE_LIST, 4).
+-define(JSON_TYPE_TUPLE, 5).
+-define(JSON_TYPE_PID, 6).
+-define(JSON_TYPE_REF, 7).
+
+%%====================================================================
+%% OpCodes for the commands to the solver
+%%====================================================================
+
+-define(JSON_CMD_LOAD_TRACE_FILE, 1).
+-define(JSON_CMD_SOLVE, 2).
+-define(JSON_CMD_GET_MODEL, 3).
+-define(JSON_CMD_ADD_AXIOMS, 4).
+-define(JSON_CMD_FIX_VARIABLE, 5).
+-define(JSON_CMD_RESET_SOLVER, 6).
+-define(JSON_CMD_STOP, 42).
+
+%%====================================================================
+%% OpCodes for constraint types
+%%====================================================================
+
+-define(CONSTRAINT_TRUE, 1).
+-define(CONSTRAINT_FALSE, 2).
+-define(NOT_CONSTRAINT, 3).
+
+-define(CONSTRAINT_TRUE_REPR, 84). %% $T
+-define(CONSTRAINT_FALSE_REPR, 70). %% $F
+
+%%====================================================================
+%% OpCodes of constraints & built-in operations
+%%====================================================================
+
+%% Empty tag ID
+-define(EMPTY_TAG_ID, 0).
+
+%% MFA's Parameters & Spec definitions.
+-define(OP_PARAMS, 1).
+-define(OP_SPEC, 2).
+%% Constraints.
+-define(OP_GUARD_TRUE, 3).
+-define(OP_GUARD_FALSE, 4).
+-define(OP_MATCH_EQUAL_TRUE, 5).
+-define(OP_MATCH_EQUAL_FALSE, 6).
+-define(OP_TUPLE_SZ, 7).
+-define(OP_TUPLE_NOT_SZ, 8).
+-define(OP_TUPLE_NOT_TPL, 9).
+-define(OP_LIST_NON_EMPTY, 10).
+-define(OP_LIST_EMPTY, 11).
+-define(OP_LIST_NOT_LST, 12).
+%% Information used for syncing & merging the traces of many processes.
+-define(OP_SPAWN, 13).
+-define(OP_SPAWNED, 14).
+-define(OP_MSG_SEND, 15).
+-define(OP_MSG_RECEIVE, 16).
+-define(OP_MSG_CONSUME, 17).
+%% Necessary operations for the evaluation of Core Erlang.
+-define(OP_UNFOLD_TUPLE, 18).
+-define(OP_UNFOLD_LIST, 19).
+%% Bogus operation (operations interpreted as the identity function).
+-define(OP_BOGUS, 48).
+%% Type conversions.
+-define(OP_FLOAT, 47).
+-define(OP_LIST_TO_TUPLE, 52).
+-define(OP_TUPLE_TO_LIST, 53).
+%% Query types.
+-define(OP_IS_INTEGER, 27).
+-define(OP_IS_ATOM, 28).
+-define(OP_IS_FLOAT, 29).
+-define(OP_IS_LIST, 30).
+-define(OP_IS_TUPLE, 31).
+-define(OP_IS_BOOLEAN, 32).
+-define(OP_IS_NUMBER, 33).
+%% Arithmetic operations.
+-define(OP_PLUS, 34).
+-define(OP_MINUS, 35).
+-define(OP_TIMES, 36).
+-define(OP_RDIV, 37).
+-define(OP_IDIV_NAT, 38).
+-define(OP_REM_NAT, 39).
+-define(OP_UNARY, 40).
+%% Operations on atoms.
+-define(OP_ATOM_NIL, 49).
+-define(OP_ATOM_HEAD, 50).
+-define(OP_ATOM_TAIL, 51).
+%% Operations on lists.
+-define(OP_HD, 25).
+-define(OP_TL, 26).
+-define(OP_CONS, 56).
+%% Operations on tuples.
+-define(OP_TCONS, 57).
+%% Comparisons.
+-define(OP_EQUAL, 41).
+-define(OP_UNEQUAL, 42).
+-define(OP_LT_INT, 54).
+-define(OP_LT_FLOAT, 55).
+
+%% Maps MFAs to their JSON Opcodes
+-define(OPCODE_MAPPING,
+ dict:from_list([ %% Simulated built-in operations
+ { {cuter_erlang, atom_to_list_bogus, 1}, ?OP_BOGUS }
+ , { {cuter_erlang, is_atom_nil, 1}, ?OP_ATOM_NIL }
+ , { {cuter_erlang, safe_atom_head, 1}, ?OP_ATOM_HEAD }
+ , { {cuter_erlang, safe_atom_tail, 1}, ?OP_ATOM_TAIL }
+ , { {cuter_erlang, safe_pos_div, 2}, ?OP_IDIV_NAT }
+ , { {cuter_erlang, safe_pos_rem, 2}, ?OP_REM_NAT }
+ , { {cuter_erlang, lt_int, 2}, ?OP_LT_INT }
+ , { {cuter_erlang, lt_float, 2}, ?OP_LT_FLOAT }
+ , { {cuter_erlang, safe_plus, 2}, ?OP_PLUS }
+ , { {cuter_erlang, safe_minus, 2}, ?OP_MINUS }
+ , { {cuter_erlang, safe_times, 2}, ?OP_TIMES }
+ , { {cuter_erlang, safe_rdiv, 2}, ?OP_RDIV }
+ , { {cuter_erlang, safe_float, 1}, ?OP_FLOAT }
+ , { {cuter_erlang, safe_list_to_tuple, 1}, ?OP_LIST_TO_TUPLE }
+ , { {cuter_erlang, safe_tuple_to_list, 1}, ?OP_TUPLE_TO_LIST }
+ , { {bogus_erlang, cons, 2}, ?OP_CONS }
+ %% Actual erlang BIFs
+ , { {erlang, hd, 1}, ?OP_HD }
+ , { {erlang, tl, 1}, ?OP_TL }
+ , { {erlang, is_integer, 1}, ?OP_IS_INTEGER }
+ , { {erlang, is_atom, 1}, ?OP_IS_ATOM }
+ , { {erlang, is_boolean, 1}, ?OP_IS_BOOLEAN }
+ , { {erlang, is_float, 1}, ?OP_IS_FLOAT }
+ , { {erlang, is_list, 1}, ?OP_IS_LIST }
+ , { {erlang, is_tuple, 1}, ?OP_IS_TUPLE }
+ , { {erlang, is_number, 1}, ?OP_IS_NUMBER }
+ , { {erlang, '-', 1}, ?OP_UNARY }
+ , { {erlang, '=:=', 2}, ?OP_EQUAL }
+ , { {erlang, '=/=', 2}, ?OP_UNEQUAL }
+ ])).
+
+%% All the MFAs that are supported for symbolic evaluation.
+-define(SUPPORTED_MFAS, gb_sets:from_list(dict:fetch_keys(?OPCODE_MAPPING))).
+
+-define(UNSUPPORTED_MFAS,
+ gb_sets:from_list([ {cuter_erlang, unsupported_lt, 2} ])).
+
+%% The set of all the built-in operations that the solver can try to reverse.
+-define (REVERSIBLE_OPERATIONS,
+ gb_sets:from_list([ ?OP_HD, ?OP_TL
+ ])).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.erl b/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.erl
new file mode 100644
index 0000000000..e9561374cc
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.erl
@@ -0,0 +1,607 @@
+%% -*- erlang-indent-level: 2 -*-
+%%------------------------------------------------------------------------------
+-module(cuter_types).
+
+-export([parse_spec/3, retrieve_types/1, retrieve_specs/1, find_spec/2, get_kind/1]).
+
+-export([params_of_t_function_det/1, ret_of_t_function_det/1, atom_of_t_atom_lit/1, integer_of_t_integer_lit/1,
+ elements_type_of_t_list/1, elements_type_of_t_nonempty_list/1, elements_types_of_t_tuple/1,
+ elements_types_of_t_union/1, bounds_of_t_range/1, segment_size_of_bitstring/1]).
+
+-export_type([erl_type/0, erl_spec_clause/0, erl_spec/0, stored_specs/0, stored_types/0, stored_spec_value/0, t_range_limit/0]).
+
+-include("cuter_macros.hrl").
+-include("cuter_types.hrl").
+
+
+%% Define tags
+-define(type_variable, vart).
+-define(type_var, tvar).
+-define(max_char, 16#10ffff).
+
+%% Pre-processed types.
+
+-type type_name() :: atom().
+-type type_arity() :: byte().
+-type type_var() :: {?type_var, atom()}.
+-type remote_type() :: {module(), type_name(), type_arity()}.
+-type record_name() :: atom().
+-type record_field_name() :: atom().
+-type record_field_type() :: {record_field_name(), raw_type()}.
+-type dep() :: remote_type().
+-type deps() :: ordsets:ordset(remote_type()).
+-record(t, {
+ kind,
+ rep,
+ deps = ordsets:new() :: deps()
+}).
+-type erl_type() :: t_any() % any()
+ | t_nil() % []
+ | t_atom() % atom()
+ | t_atom_lit() % Erlang_Atom
+ | t_integer() % integer(), +infinity, -inifinity
+ | t_integer_lit() % Erlang_Integer
+ | t_float() % float()
+ | t_tuple() % tuple(), {TList}
+ | t_list() % list(Type)
+ | t_nonempty_list() % nonempty_list(Type)
+ | t_union() % Type1 | ... | TypeN
+ | t_range() % Erlang_Integer..Erlang_Integer
+ | t_bitstring() % <<_:M>>
+ | t_function() % function() | Fun | BoundedFun
+ .
+-type raw_type() :: erl_type()
+ | t_local() % Local Type Usage
+ | t_remote() % Remote Type Usage
+ | t_record() % Record Usage
+ | t_type_var() % Type Variable
+ .
+
+-type t_any() :: #t{kind :: ?any_tag}.
+-type t_nil() :: #t{kind :: ?nil_tag}.
+-type t_atom() :: #t{kind :: ?atom_tag}.
+-type t_atom_lit() :: #t{kind :: ?atom_lit_tag, rep :: atom()}.
+-type t_integer() :: #t{kind :: ?integer_tag}.
+-type t_integer_lit() :: #t{kind :: ?integer_lit_tag, rep :: integer()}.
+-type t_float() :: #t{kind :: ?float_tag}.
+-type t_tuple() :: #t{kind :: ?tuple_tag, rep :: [raw_type()]}.
+-type t_list() :: #t{kind :: ?list_tag, rep :: raw_type()}.
+-type t_nonempty_list() :: #t{kind :: ?nonempty_list_tag, rep :: raw_type()}.
+-type t_union() :: #t{kind :: ?union_tag, rep :: [raw_type()]}.
+-type t_range() :: #t{kind :: ?range_tag, rep :: {t_range_limit(), t_range_limit()}}.
+-type t_range_limit() :: t_integer_lit() | t_integer_inf().
+-type t_integer_inf() :: t_integer_pos_inf() | t_integer_neg_inf().
+-type t_integer_pos_inf() :: #t{kind :: ?pos_inf}.
+-type t_integer_neg_inf() :: #t{kind :: ?neg_inf}.
+-type t_bitstring() :: #t{kind :: ?bitstring_tag, rep :: 1|8}.
+-type t_function() :: #t{kind :: ?function_tag} | t_function_det().
+-type t_function_det() :: #t{kind :: ?function_tag, rep :: {[raw_type()], raw_type(), [t_constraint()]}, deps :: deps()}.
+-type t_constraint() :: {t_type_var(), raw_type()}.
+-type t_local() :: #t{kind :: ?local_tag, rep :: {type_name(), [raw_type()]}}.
+-type t_remote() :: #t{kind :: ?remote_tag, rep :: {module(), type_name(), [raw_type()]}}.
+-type t_record() :: #t{kind :: ?record_tag, rep :: {record_name(), [record_field_type()]}}.
+-type t_type_var() :: #t{kind :: ?type_variable, rep :: type_var()}.
+
+%% How pre-processed types are stored.
+-type stored_type_key() :: {record, record_name()} | {type, type_name(), type_arity()}.
+-type stored_type_value() :: [record_field_type()] | {any(), [type_var()]}. % raw_type()
+-type stored_types() :: dict:dict(stored_type_key(), stored_type_value()).
+
+-type stored_spec_key() :: {type_name(), type_arity()}.
+-type stored_spec_value() :: [t_function_det()].
+-type stored_specs() :: dict:dict(stored_spec_key(), stored_spec_value()).
+
+-type type_var_env() :: dict:dict(type_var(), raw_type()).
+-type erl_spec_clause() :: t_function_det().
+-type erl_spec() :: [erl_spec_clause()].
+
+%% Pre-process the type & record declarations of a module.
+-spec retrieve_types([cuter_cerl:cerl_attr_type()]) -> stored_types().
+retrieve_types(TypeAttrs) ->
+ lists:foldl(fun process_type_attr/2, dict:new(), TypeAttrs).
+
+-spec process_type_attr(cuter_cerl:cerl_recdef() | cuter_cerl:cerl_typedef(), stored_types()) -> stored_types().
+%% Declaration of a record.
+process_type_attr({{record, Name}, Fields, []}, Processed) ->
+ Fs = [t_field_from_form(Field) || Field <- Fields],
+ Record = t_record(Name, Fs),
+ dict:store({record, Name}, Record, Processed);
+%% Declaration of a type.
+process_type_attr({Name, Repr, Vars}, Processed) ->
+ Type = safe_t_from_form(Repr),
+ Vs = [{?type_var, Var} || {var, _, Var} <- Vars],
+ dict:store({type, Name, length(Vs)}, {Type, Vs}, Processed).
+
+%% The fields of a declared record.
+-spec t_field_from_form(cuter_cerl:cerl_record_field()) -> record_field_type().
+t_field_from_form({record_field, _, {atom, _, Name}}) ->
+ {Name, t_any()};
+t_field_from_form({record_field, _, {atom, _, Name}, _Default}) ->
+ {Name, t_any()};
+t_field_from_form({typed_record_field, {record_field, _, {atom, _, Name}}, Type}) ->
+ {Name, safe_t_from_form(Type)};
+t_field_from_form({typed_record_field, {record_field, _, {atom, _, Name}, _Default}, Type}) ->
+ {Name, safe_t_from_form(Type)}.
+
+%% Provision for unsupported types.
+safe_t_from_form(Form) ->
+ try t_from_form(Form)
+ catch throw:{unsupported, Info} ->
+ cuter_pp:form_has_unsupported_type(Info),
+ t_any()
+ end.
+
+%% Parse a type.
+
+-spec t_from_form(cuter_cerl:cerl_type()) -> raw_type().
+%% Erlang_Atom
+t_from_form({atom, _, Atom}) ->
+ t_atom_lit(Atom);
+%% Erlang_Integer
+t_from_form({integer, _, Integer}) ->
+ t_integer_lit(Integer);
+%% integer()
+t_from_form({type, _, integer, []}) ->
+ t_integer();
+%% nil
+t_from_form({type, _, nil, []}) ->
+ t_nil();
+%% any()
+t_from_form({type, _, any, []}) ->
+ t_any();
+%% term()
+t_from_form({type, _, term, []}) ->
+ t_any();
+%% atom()
+t_from_form({type, _, atom, []}) ->
+ t_atom();
+%% module()
+t_from_form({type, _, module, []}) ->
+ t_module();
+%% float()
+t_from_form({type, _, float, []}) ->
+ t_float();
+%% tuple()
+t_from_form({type, _, tuple, any}) ->
+ t_tuple();
+%% {TList}
+t_from_form({type, _, tuple, Types}) ->
+ Ts = [t_from_form(T) || T <- Types],
+ t_tuple(Ts);
+%% list()
+t_from_form({type, _, list, []}) ->
+ t_list();
+%% list(Type)
+t_from_form({type, _, list, [Type]}) ->
+ T = t_from_form(Type),
+ t_list(T);
+%% Type1 | ... | TypeN
+t_from_form({type, _, union, Types}) ->
+ Ts = [t_from_form(T) || T <- Types],
+ t_union(Ts);
+%% boolean()
+t_from_form({type, _, boolean, []}) ->
+ t_union([t_atom_lit(true), t_atom_lit(false)]);
+%% number()
+t_from_form({type, _, number, []}) ->
+ t_union([t_integer(), t_float()]);
+%% Erlang_Integer..Erlang_Integer
+t_from_form({type, _, range, [{integer, _, I1}, {integer, _, I2}]}) ->
+ t_range(t_integer_lit(I1), t_integer_lit(I2));
+%% non_neg_integer()
+t_from_form({type, _, non_neg_integer, []}) ->
+ t_range(t_integer_lit(0), t_pos_inf());
+%% pos_integer()
+t_from_form({type, _, pos_integer, []}) ->
+ t_range(t_integer_lit(1), t_pos_inf());
+%% neg_integer()
+t_from_form({type, _, neg_integer, []}) ->
+ t_range(t_neg_inf(), t_integer_lit(-1));
+%% char()
+t_from_form({type, _, char, []}) ->
+ t_char();
+%% byte()
+t_from_form({type, _, byte, []}) ->
+ t_byte();
+%% mfa()
+t_from_form({type, _, mfa, []}) ->
+ t_tuple([t_module(), t_atom(), t_byte()]);
+%% string()
+t_from_form({type, _, string, []}) ->
+ t_list(t_char());
+%% nonempty_list()
+t_from_form({type, _, nonempty_list, []}) ->
+ t_nonempty_list();
+%% nonempty_list(Type)
+t_from_form({type, _, nonempty_list, [Type]}) ->
+ T = t_from_form(Type),
+ t_nonempty_list(T);
+%% binary()
+t_from_form({type, _, binary, []}) ->
+ t_bitstring(8);
+%% bitstring()
+t_from_form({type, _, bitstring, []}) ->
+ t_bitstring(1);
+%% function()
+t_from_form({type, _, function, []}) ->
+ t_function();
+%% fun((TList) -> Type)
+t_from_form({type, _, 'fun', [_Product, _RetType]}=Fun) ->
+ t_function_from_form(Fun);
+%% fun((TList) -> Type) (bounded_fun)
+t_from_form({type, _, 'bounded_fun', [_Fun, _Cs]}=BoundedFun) ->
+ t_bounded_function_from_form(BoundedFun);
+%% ann_type
+t_from_form({ann_type, _, [_Var, Type]}) ->
+ t_from_form(Type);
+%% paren_type
+t_from_form({paren_type, _, [Type]}) ->
+ t_from_form(Type);
+%% remote_type
+t_from_form({remote_type, _, [{atom, _, M}, {atom, _, Name}, Types]}) ->
+ Ts = [t_from_form(T) || T <- Types],
+ t_remote(M, Name, Ts);
+%% Record
+t_from_form({type, _, record, [{atom, _, Name} | FieldTypes]}) ->
+ Fields = [t_bound_field_from_form(F) || F <- FieldTypes],
+ t_record(Name, Fields);
+%% Map
+t_from_form({type, _, map, _}=X) ->
+ throw({unsupported, X});
+%% local type
+t_from_form({type, _, Name, Types}) ->
+ Ts = [t_from_form(T) || T <- Types],
+ t_local(Name, Ts);
+%% Type Variable
+t_from_form({var, _, Var}) ->
+ t_var(Var);
+%% Unsupported forms
+t_from_form(Type) ->
+ throw({unsupported, Type}).
+
+-spec t_bound_field_from_form(cuter_cerl:cerl_type_record_field()) -> record_field_type().
+%% Record Field.
+t_bound_field_from_form({type, _, field_type, [{atom, _, Name}, Type]}) ->
+ {Name, t_from_form(Type)}.
+
+-spec t_function_from_form(cuter_cerl:cerl_func()) -> t_function_det().
+t_function_from_form({type, _, 'fun', [{type, _, 'product', Types}, RetType]}) ->
+ Ret = t_from_form(RetType),
+ Ts = [t_from_form(T) || T <- Types],
+ t_function(Ts, Ret).
+
+-spec t_bounded_function_from_form(cuter_cerl:cerl_bounded_func()) -> t_function_det().
+t_bounded_function_from_form({type, _, 'bounded_fun', [Fun, Constraints]}) ->
+ {type, _, 'fun', [{type, _, 'product', Types}, RetType]} = Fun,
+ Ret = t_from_form(RetType),
+ Ts = [t_from_form(T) || T <- Types],
+ Cs = [t_constraint_from_form(C) || C <- Constraints],
+ t_function(Ts, Ret, Cs).
+
+-spec t_constraint_from_form(cuter_cerl:cerl_constraint()) -> t_constraint().
+t_constraint_from_form({type, _, constraint, [{atom, _, is_subtype}, [{var, _, Var}, Type]]}) ->
+ {t_var(Var), t_from_form(Type)}.
+
+
+%% Type constructors.
+
+-spec t_any() -> t_any().
+t_any() ->
+ #t{kind = ?any_tag}.
+
+-spec t_atom_lit(atom()) -> t_atom_lit().
+t_atom_lit(Atom) ->
+ #t{kind = ?atom_lit_tag, rep = Atom}.
+
+-spec t_atom() -> t_atom().
+t_atom() ->
+ #t{kind = ?atom_tag}.
+
+-spec t_module() -> t_atom().
+t_module() -> t_atom().
+
+-spec t_integer_lit(integer()) -> t_integer_lit().
+t_integer_lit(Integer) ->
+ #t{kind = ?integer_lit_tag, rep = Integer}.
+
+-spec t_integer() -> t_integer().
+t_integer() ->
+ #t{kind = ?integer_tag}.
+
+-spec t_range(t_range_limit(), t_range_limit()) -> t_range().
+t_range(Int1, Int2) ->
+ #t{kind = ?range_tag, rep = {Int1, Int2}}.
+
+-spec t_pos_inf() -> t_integer_pos_inf().
+t_pos_inf() ->
+ #t{kind = ?pos_inf}.
+
+-spec t_neg_inf() -> t_integer_neg_inf().
+t_neg_inf() ->
+ #t{kind = ?neg_inf}.
+
+-spec t_char() -> t_range().
+t_char() ->
+ t_range(t_integer_lit(0), t_integer_lit(?max_char)).
+
+-spec t_nil() -> t_nil().
+t_nil() ->
+ #t{kind = ?nil_tag}.
+
+-spec t_float() -> t_float().
+t_float() ->
+ #t{kind = ?float_tag}.
+
+-spec t_list() -> t_list().
+t_list() ->
+ #t{kind = ?list_tag, rep = t_any()}.
+
+-spec t_list(raw_type()) -> t_list().
+t_list(Type) ->
+ #t{kind = ?list_tag, rep = Type, deps = get_deps(Type)}.
+
+-spec t_nonempty_list() -> t_nonempty_list().
+t_nonempty_list() ->
+ #t{kind = ?nonempty_list_tag, rep = t_any()}.
+
+-spec t_nonempty_list(raw_type()) -> t_nonempty_list().
+t_nonempty_list(Type) ->
+ #t{kind = ?nonempty_list_tag, rep = Type, deps = get_deps(Type)}.
+
+-spec t_tuple() -> t_tuple().
+t_tuple() ->
+ #t{kind = ?tuple_tag, rep = []}.
+
+-spec t_tuple([raw_type()]) -> t_tuple().
+t_tuple(Types) ->
+ #t{kind = ?tuple_tag, rep = Types, deps = unify_deps(Types)}.
+
+-spec t_union([raw_type()]) -> t_union().
+t_union(Types) ->
+ #t{kind = ?union_tag, rep = Types, deps = unify_deps(Types)}.
+
+-spec t_byte() -> t_range().
+t_byte() ->
+ t_range(t_integer_lit(0), t_integer_lit(255)).
+
+-spec t_local(type_name(), [raw_type()]) -> t_local().
+t_local(Name, Types) ->
+ Rep = {Name, Types},
+ #t{kind = ?local_tag, rep = Rep, deps = unify_deps(Types)}.
+
+-spec t_remote(module(), type_name(), [raw_type()]) -> t_remote().
+t_remote(Mod, Name, Types) ->
+ Rep = {Mod, Name, Types},
+ Dep = {Mod, Name, length(Types)},
+ #t{kind = ?remote_tag, rep = Rep, deps = add_dep(Dep, unify_deps(Types))}.
+
+-spec t_var(atom()) -> t_type_var().
+t_var(Var) ->
+ #t{kind = ?type_variable, rep = {?type_var, Var}}.
+
+-spec t_record(record_name(), [record_field_type()]) -> t_record().
+t_record(Name, Fields) ->
+ Rep = {Name, Fields},
+ Ts = [T || {_, T} <- Fields],
+ #t{kind = ?record_tag, rep = Rep, deps = unify_deps(Ts)}.
+
+-spec fields_of_t_record(t_record()) -> [record_field_type()].
+fields_of_t_record(Record) ->
+ Rep = Record#t.rep,
+ element(2, Rep).
+
+-spec t_bitstring(1 | 8) -> t_bitstring().
+t_bitstring(N) ->
+ #t{kind = ?bitstring_tag, rep = N}.
+
+-spec t_function() -> t_function().
+t_function() ->
+ #t{kind = ?function_tag}.
+
+-spec t_function([raw_type()], raw_type()) -> t_function_det().
+t_function(Types, Ret) ->
+ Rep = {Types, Ret, []},
+ #t{kind = ?function_tag, rep = Rep, deps = unify_deps([Ret|Types])}.
+
+-spec t_function([raw_type()], raw_type(), [t_constraint()]) -> t_function_det().
+t_function(Types, Ret, Constraints) ->
+ Rep = {Types, Ret, Constraints},
+ Ts = [T || {_V, T} <- Constraints],
+ #t{kind = ?function_tag, rep = Rep, deps = unify_deps([Ret|Types] ++ Ts)}.
+
+%% Accessors of representations.
+
+-spec params_of_t_function_det(t_function_det()) -> [raw_type()].
+params_of_t_function_det(#t{kind = ?function_tag, rep = {Params, _Ret, _Constraints}}) ->
+ Params.
+
+-spec ret_of_t_function_det(t_function_det()) -> raw_type().
+ret_of_t_function_det(#t{kind = ?function_tag, rep = {_Params, Ret, _Constraints}}) ->
+ Ret.
+
+-spec atom_of_t_atom_lit(t_atom_lit()) -> atom().
+atom_of_t_atom_lit(#t{kind = ?atom_lit_tag, rep = Atom}) ->
+ Atom.
+
+-spec integer_of_t_integer_lit(t_integer_lit()) -> integer().
+integer_of_t_integer_lit(#t{kind = ?integer_lit_tag, rep = Integer}) ->
+ Integer.
+
+-spec elements_type_of_t_list(t_list()) -> raw_type().
+elements_type_of_t_list(#t{kind = ?list_tag, rep = Type}) ->
+ Type.
+
+-spec elements_type_of_t_nonempty_list(t_nonempty_list()) -> raw_type().
+elements_type_of_t_nonempty_list(#t{kind = ?nonempty_list_tag, rep = Type}) ->
+ Type.
+
+-spec elements_types_of_t_tuple(t_tuple()) -> [raw_type()].
+elements_types_of_t_tuple(#t{kind = ?tuple_tag, rep = Types}) ->
+ Types.
+
+-spec elements_types_of_t_union(t_union()) -> [raw_type()].
+elements_types_of_t_union(#t{kind = ?union_tag, rep = Types}) ->
+ Types.
+
+-spec bounds_of_t_range(t_range()) -> {t_range_limit(), t_range_limit()}.
+bounds_of_t_range(#t{kind = ?range_tag, rep = Limits}) ->
+ Limits.
+
+-spec segment_size_of_bitstring(t_bitstring()) -> integer().
+segment_size_of_bitstring(#t{kind = ?bitstring_tag, rep = Sz}) ->
+ Sz.
+
+-spec is_tvar_wild_card(t_type_var()) -> boolean().
+is_tvar_wild_card(#t{kind = ?type_variable, rep = {?type_var, Var}}) ->
+ Var =:= '_'.
+
+%% Helper functions for kinds.
+
+-spec get_kind(raw_type()) -> atom().
+get_kind(Type) ->
+ Type#t.kind.
+
+%% Helper functions for dependencies.
+
+-spec get_deps(raw_type()) -> deps().
+get_deps(Type) ->
+ Type#t.deps.
+
+-spec has_deps(raw_type()) -> boolean().
+has_deps(Type) ->
+ get_deps(Type) =/= ordsets:new().
+
+-spec add_dep(dep(), deps()) -> deps().
+add_dep(Dep, Deps) ->
+ ordsets:add_element(Dep, Deps).
+
+-spec unify_deps([raw_type()]) -> deps().
+unify_deps(Types) ->
+ ordsets:union([T#t.deps || T <- Types]).
+
+%% Deal with specs.
+
+-spec retrieve_specs([cuter_cerl:cerl_attr_spec()]) -> stored_specs().
+retrieve_specs(SpecAttrs) ->
+ lists:foldl(fun process_spec_attr/2, dict:new(), SpecAttrs).
+
+-spec process_spec_attr(cuter_cerl:cerl_attr_spec(), stored_specs()) -> stored_specs().
+process_spec_attr({FA, Specs}, Processed) ->
+ Xs = [t_spec_from_form(Spec) || Spec <- Specs],
+ dict:store(FA, Xs, Processed).
+
+-spec t_spec_from_form(cuter_cerl:cerl_spec_func()) -> t_function_det().
+t_spec_from_form({type, _, 'fun', _}=Fun) ->
+ t_function_from_form(Fun);
+t_spec_from_form({type, _, 'bounded_fun', _}=Fun) ->
+ t_bounded_function_from_form(Fun).
+
+-spec find_spec(stored_spec_key(), stored_specs()) -> {'ok', stored_spec_value()} | 'error'.
+find_spec(FA, Specs) ->
+ dict:find(FA, Specs).
+
+%% Parse the spec of an MFA.
+
+-type spec_parse_reply() :: {error, has_remote_types | recursive_type}
+ | {error, unsupported_type, type_name()}
+ | {ok, erl_spec()}.
+
+-spec parse_spec(stored_spec_key(), stored_spec_value(), stored_types()) -> spec_parse_reply().
+parse_spec(FA, Spec, Types) ->
+ try parse_spec_clauses(FA, Spec, Types, []) of
+ {error, has_remote_types}=E -> E;
+ Parsed -> {ok, Parsed}
+ catch
+ throw:remote_type -> {error, has_remote_types};
+ throw:recursive_type -> {error, recursive_type};
+ throw:{unsupported, Name} -> {error, unsupported_type, Name}
+ end.
+
+
+parse_spec_clauses(_FA, [], _Types, Acc) ->
+ lists:reverse(Acc);
+parse_spec_clauses(FA, [Clause|Clauses], Types, Acc) ->
+ case has_deps(Clause) of
+ true -> {error, has_remote_types};
+ false ->
+ Visited = ordsets:add_element(FA, ordsets:new()),
+ Simplified = simplify(Clause, Types, dict:new(), Visited),
+ parse_spec_clauses(FA, Clauses, Types, [Simplified|Acc])
+ end.
+
+add_constraints_to_env([], Env) ->
+ Env;
+add_constraints_to_env([{Var, Type}|Cs], Env) ->
+ F = fun(StoredTypes, E, Visited) -> simplify(Type, StoredTypes, E, Visited) end,
+ Env1 = dict:store(Var#t.rep, F, Env),
+ add_constraints_to_env(Cs, Env1).
+
+bind_parameters([], [], Env) ->
+ Env;
+bind_parameters([P|Ps], [A|As], Env) ->
+ F = fun(StoredTypes, E, Visited) -> simplify(A, StoredTypes, E, Visited) end,
+ Env1 = dict:store(P, F, Env),
+ bind_parameters(Ps, As, Env1).
+
+-spec simplify(raw_type(), stored_types(), type_var_env(), ordsets:ordset(stored_spec_key())) -> raw_type().
+%% fun
+simplify(#t{kind = ?function_tag, rep = {Params, Ret, Constraints}}=Raw, StoredTypes, Env, Visited) ->
+ Env1 = add_constraints_to_env(Constraints, Env),
+ ParamsSimplified = [simplify(P, StoredTypes, Env1, Visited) || P <- Params],
+ RetSimplified = simplify(Ret, StoredTypes, Env1, Visited),
+ Rep = {ParamsSimplified, RetSimplified, []},
+ Raw#t{rep = Rep};
+%% tuple
+simplify(#t{kind = ?tuple_tag, rep = Types}=Raw, StoredTypes, Env, Visited) ->
+ Rep = [simplify(T, StoredTypes, Env, Visited) || T <- Types],
+ Raw#t{rep = Rep};
+%% list / nonempty_list
+simplify(#t{kind = Tag, rep = Type}=Raw, StoredTypes, Env, Visited) when Tag =:= ?list_tag; Tag =:= ?nonempty_list_tag ->
+ Rep = simplify(Type, StoredTypes, Env, Visited),
+ Raw#t{rep = Rep};
+%% union
+simplify(#t{kind = ?union_tag, rep = Types}=Raw, StoredTypes, Env, Visited) ->
+ Rep = [simplify(T, StoredTypes, Env, Visited) || T <- Types],
+ Raw#t{rep = Rep};
+%% local type
+simplify(#t{kind = ?local_tag, rep = {Name, Args}}, StoredTypes, Env, Visited) ->
+ Arity = length(Args),
+ TA = {Name, Arity},
+ case ordsets:is_element(TA, Visited) of
+ true -> throw(recursive_type);
+ false ->
+ case dict:find({type, Name, Arity}, StoredTypes) of
+ error -> throw({unsupported, Name});
+ {ok, {Type, Params}} ->
+ Env1 = bind_parameters(Params, Args, Env),
+ simplify(Type, StoredTypes, Env1, [TA|Visited])
+ end
+ end;
+%% type variable
+simplify(#t{kind = ?type_variable, rep = TVar}=T, StoredTypes, Env, Visited) ->
+ case is_tvar_wild_card(T) of
+ true -> t_any();
+ false ->
+ V = dict:fetch(TVar, Env),
+ V(StoredTypes, Env, Visited)
+ end;
+simplify(#t{kind = ?remote_tag}, _StoredTypes, _Env, _Visited) ->
+ throw(remote_type);
+%% record
+simplify(#t{kind = ?record_tag, rep = {Name, OverridenFields}}, StoredTypes, Env, Visited) ->
+ RecordDecl = dict:fetch({record, Name}, StoredTypes),
+ Fields = fields_of_t_record(RecordDecl),
+ ActualFields = replace_record_fields(Fields, OverridenFields),
+ FinalFields = [{N, simplify(T, StoredTypes, Env, Visited)} || {N, T} <- ActualFields],
+ Simplified = [T || {_, T} <- FinalFields],
+ t_tuple([t_atom_lit(Name)|Simplified]);
+%% all others
+simplify(Raw, _StoredTypes, _Env, _Visited) ->
+ Raw.
+
+-spec replace_record_fields([record_field_type()], [record_field_type()]) -> [record_field_type()].
+replace_record_fields(Fields, []) ->
+ Fields;
+replace_record_fields(Fields, [{Name, Type}|Rest]) ->
+ Replaced = lists:keyreplace(Name, 1, Fields, {Name, Type}),
+ replace_record_fields(Replaced, Rest).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.hrl
new file mode 100644
index 0000000000..4172184709
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/cuter/cuter_types.hrl
@@ -0,0 +1,26 @@
+%% -*- erlang-indent-level: 2 -*-
+%%------------------------------------------------------------------------------
+
+%%====================================================================
+%% Tags for the kind of encoded types.
+%%====================================================================
+
+-define(atom_lit_tag, atom_lit).
+-define(integer_lit_tag, integer_lit).
+-define(integer_tag, integer).
+-define(nil_tag, nil).
+-define(any_tag, any).
+-define(atom_tag, atom).
+-define(float_tag, float).
+-define(tuple_tag, tuple).
+-define(list_tag, list).
+-define(nonempty_list_tag, nonempty_list).
+-define(union_tag, union).
+-define(range_tag, range).
+-define(bitstring_tag, bitstring).
+-define(neg_inf, neg_inf).
+-define(pos_inf, pos_inf).
+-define(remote_tag, remote).
+-define(local_tag, local).
+-define(record_tag, record).
+-define(function_tag, function).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_digraph.erl b/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_digraph.erl
index 09d4229e28..47185dc99d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_digraph.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_digraph.erl
@@ -3,21 +3,21 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
-
%%% The Erlang scanner. All types are opaque, which puts some stress
%%% on Dialyzer.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_erl_scan.erl b/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_erl_scan.erl
index 24d0793a7c..d6b3a730bb 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_erl_scan.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/modules/opaque_erl_scan.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue.erl
new file mode 100644
index 0000000000..0f76680464
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue.erl
@@ -0,0 +1,17 @@
+-module(myqueue).
+
+-export([new/0, in/2]).
+
+-record(myqueue, {queue = queue:new() :: queue:queue({integer(), _})}).
+
+-opaque myqueue(Item) :: #myqueue{queue :: queue:queue({integer(), Item})}.
+
+-export_type([myqueue/1]).
+
+-spec new() -> myqueue(_).
+new() ->
+ #myqueue{queue=queue:new()}.
+
+-spec in(Item, myqueue(Item)) -> myqueue(Item).
+in(Item, #myqueue{queue=Q}) ->
+ #myqueue{queue=queue:in({1, Item}, Q)}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue_params.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue_params.erl
new file mode 100644
index 0000000000..8d766b7804
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/myqueue_params.erl
@@ -0,0 +1,15 @@
+-module(myqueue_params).
+
+-export([new/0, in/2]).
+
+-record(myqueue_params, {myqueue = myqueue:new() :: myqueue:myqueue(integer())}).
+
+-type myqueue_params() :: #myqueue_params{myqueue ::
+ myqueue:myqueue(integer())}.
+-spec new() -> myqueue_params().
+new() ->
+ #myqueue_params{myqueue=myqueue:new()}.
+
+-spec in(integer(), myqueue_params()) -> myqueue_params().
+in(Item, #myqueue_params{myqueue=Q} = P) when is_integer(Item) ->
+ P#myqueue_params{myqueue=myqueue:in(Item, Q)}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl
index 09b2235fa5..4461ff291c 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl
@@ -85,7 +85,7 @@ ct2_adt() ->
tcirc() ->
A = circ1(),
B = circ2(),
- A =:= B. % can never evaluate to 'true' (but the types are not OK, or?)
+ A =:= B. % can never evaluate to 'true'
-spec circ1() -> circ(integer()).
@@ -100,7 +100,7 @@ circ2() ->
tcirc_adt() ->
A = circ1_adt(),
B = circ2_adt(),
- A =:= B. % opaque attempt (one would expect them to be the same...)
+ A =:= B. % opaque attempt (number of parameters differs)
circ1_adt() ->
para2_adt:circ1().
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 792ae40d39..102215b28d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
@@ -71,7 +71,7 @@ t2_adt() ->
-type exp() :: para3_adt:exp1(para3_adt:exp2()).
--spec exp_adt() -> exp().
+-spec exp_adt() -> exp(). % invalid type spec
exp_adt() ->
3.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para4.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para4.erl
new file mode 100644
index 0000000000..b9794672a9
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para4.erl
@@ -0,0 +1,134 @@
+-module(para4).
+
+-compile(export_all).
+
+-export_type([d_atom/0, d_integer/0, d_tuple/0, d_all/0]).
+
+-export_type([t/1]).
+
+-type ai() :: atom() | integer().
+
+-type d(T) :: dict:dict(T, T).
+
+-opaque d_atom() :: d(atom()).
+-opaque d_integer() :: d(integer()).
+-opaque d_tuple() :: d(tuple()).
+-opaque d_all() :: d(ai()).
+
+b(D) ->
+ a(D) ++ i(D).
+
+-spec a(d_atom()) -> [{atom(), atom()}]. % Invalid type spec
+
+a(D) ->
+ c(D).
+
+-spec i(d_integer()) -> [{integer(), integer()}]. % Invalid type spec
+
+i(D) ->
+ c(D).
+
+-spec t(d_tuple()) -> [{tuple(), tuple()}]. % Invalid type spec.
+
+t(D) ->
+ c(D).
+
+-spec c(d_all()) -> [{ai(), ai()}].
+
+c(D) ->
+ dict:to_list(D).
+
+
+
+
+-opaque t(A) :: {A, A}.
+
+adt_tt5() ->
+ I1 = adt_y1(),
+ I2 = adt_y3(),
+ I1 =:= I2.
+
+adt_tt6() ->
+ I1 = adt_y2(),
+ I2 = adt_y3(),
+ I1 =:= I2.
+
+adt_tt7() ->
+ I1 = adt_t1(),
+ I2 = adt_t3(),
+ I1 =:= I2. % opaque attempt
+
+adt_tt8() ->
+ I1 = adt_t2(),
+ I2 = adt_t3(),
+ I1 =:= I2. % opaque attempt
+
+adt_tt9() ->
+ I1 = adt_int2(),
+ I2 = adt_int4(),
+ I1 =:= I2. % opaque attempt
+
+adt_tt10() ->
+ I1 = adt_int2(),
+ I2 = adt_int2_4(),
+ I1 =:= I2. % opaque attempt
+
+adt_tt11() ->
+ I1 = adt_int5_7(),
+ I2 = adt_int2_4(),
+ I1 =:= I2. % opaque attempt
+
+adt_tt12() ->
+ I1 = adt_un1_2(),
+ I2 = adt_un3_4(),
+ I1 =:= I2. % opaque attempt
+
+adt_tt13() ->
+ I1 = adt_tup(),
+ I2 = adt_tup2(),
+ I1 =:= I2. % opaque attempt
+
+y3() ->
+ {a, 3}.
+
+adt_t1() ->
+ para4_adt:t1().
+
+adt_t2() ->
+ para4_adt:t2().
+
+adt_t3() ->
+ para4_adt:t3().
+
+adt_y1() ->
+ para4_adt:y1().
+
+adt_y2() ->
+ para4_adt:y2().
+
+adt_y3() ->
+ para4_adt:y3().
+
+adt_int2() ->
+ para4_adt:int2().
+
+adt_int4() ->
+ para4_adt:int4().
+
+adt_int2_4() ->
+ para4_adt:int2_4().
+
+adt_int5_7() ->
+ para4_adt:int5_7().
+
+adt_un1_2() ->
+ para4_adt:un1_2().
+
+adt_un3_4() ->
+ para4_adt:un3_4().
+
+adt_tup() ->
+ para4_adt:tup().
+
+adt_tup2() ->
+ para4_adt:tup2().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para4_adt.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para4_adt.erl
new file mode 100644
index 0000000000..407dd198a7
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para4_adt.erl
@@ -0,0 +1,108 @@
+-module(para4_adt).
+
+-export([t1/0, t2/0, t3/0, y1/0, y2/0, y3/0]).
+
+-export([int2/0, int4/0, int2_4/0, int5_7/0]).
+
+-export([un1_2/0, un3_4/0]).
+
+-export([tup/0, tup2/0]).
+
+-export_type([t/1, y/1, int/1, tup/1, un/1]).
+
+-type ai() :: atom() | integer().
+
+-opaque t(A) :: {A, A}.
+
+-type y(A) :: {A, A}.
+
+-opaque int(I) :: I.
+
+-opaque un(I) :: atom() | I.
+
+-opaque tup(T) :: T.
+
+-spec t1() -> t(integer()).
+
+t1() ->
+ {i(), i()}.
+
+-spec t2() -> t(atom()).
+
+t2() ->
+ {a(), a()}.
+
+-spec t3() -> t(ai()).
+
+t3() ->
+ {ai(), ai()}.
+
+-spec y1() -> y(integer()).
+
+y1() ->
+ {i(), i()}.
+
+-spec y2() -> y(atom()).
+
+y2() ->
+ {a(), a()}.
+
+-spec y3() -> y(ai()).
+
+y3() ->
+ {ai(), ai()}.
+
+-spec a() -> atom().
+
+a() ->
+ foo:a().
+
+-spec i() -> integer().
+
+i() ->
+ foo:i().
+
+-spec ai() -> ai().
+
+ai() ->
+ foo:ai().
+
+-spec int2() -> int(1..2).
+
+int2() ->
+ foo:int2().
+
+-spec int4() -> int(1..4).
+
+int4() ->
+ foo:int4().
+
+-spec int2_4() -> int(2..4).
+
+int2_4() ->
+ foo:int2_4().
+
+-spec int5_7() -> int(5..7).
+
+int5_7() ->
+ foo:int5_7().
+
+-spec un1_2() -> un(1..2).
+
+un1_2() ->
+ foo:un1_2().
+
+-spec un3_4() -> un(3..4).
+
+un3_4() ->
+ foo:un3_4().
+
+-spec tup() -> tup(tuple()).
+
+tup() ->
+ foo:tup().
+
+-spec tup2() -> tup({_, _}).
+
+tup2() ->
+ foo:tup2().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para5.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para5.erl
new file mode 100644
index 0000000000..76ea3e76b5
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para5.erl
@@ -0,0 +1,33 @@
+-module(para5).
+
+-export([d/0, dd/0, da1/0]).
+
+d() ->
+ I1 = adt_d1(),
+ I2 = adt_d2(),
+ I1 =:= I2. % can never evaluate to true
+
+dd() ->
+ I1 = adt_d1(),
+ I2 = adt_dd(),
+ I1 =/= I2. % incompatible opaque types
+
+da1() ->
+ I1 = adt_da1(),
+ I2 = adt_da2(),
+ I1 =:= I2.
+
+adt_d1() ->
+ para5_adt:d1().
+
+adt_d2() ->
+ para5_adt:d2().
+
+adt_dd() ->
+ para5_adt:dd().
+
+adt_da1() ->
+ para5_adt:da1().
+
+adt_da2() ->
+ para5_adt:da2().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para5_adt.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para5_adt.erl
new file mode 100644
index 0000000000..a62e0488e0
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para5_adt.erl
@@ -0,0 +1,36 @@
+-module(para5_adt).
+
+-export([d1/0, d2/0, dd/0, da1/0, da2/0]).
+
+-export_type([d/0, dd/1, da/2]).
+
+-opaque d() :: 1 | 2.
+
+-spec d1() -> d().
+
+d1() ->
+ 1.
+
+-spec d2() -> d().
+
+d2() ->
+ 2.
+
+-opaque dd(A) :: A.
+
+-spec dd() -> dd(atom()).
+
+dd() ->
+ foo:atom().
+
+-opaque da(A, B) :: {A, B}.
+
+-spec da1() -> da(any(), atom()).
+
+da1() ->
+ {3, a}.
+
+-spec da2() -> da(integer(), any()).
+
+da2() ->
+ {3, a}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_common.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_common.hrl
new file mode 100644
index 0000000000..c10626c5cc
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_common.hrl
@@ -0,0 +1,55 @@
+%%% Copyright 2010-2013 Manolis Papadakis <[email protected]>,
+%%% Eirini Arvaniti <[email protected]>
+%%% and Kostis Sagonas <[email protected]>
+%%%
+%%% This file is part of PropEr.
+%%%
+%%% PropEr is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% PropEr 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>.
+
+%%% @copyright 2010-2013 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
+%%% @version {@version}
+%%% @author Manolis Papadakis
+%%% @doc Common parts of user and internal header files
+
+
+%%------------------------------------------------------------------------------
+%% Test generation macros
+%%------------------------------------------------------------------------------
+
+-define(FORALL(X,RawType,Prop), proper:forall(RawType,fun(X) -> Prop end)).
+-define(IMPLIES(Pre,Prop), proper:implies(Pre,?DELAY(Prop))).
+-define(WHENFAIL(Action,Prop), proper:whenfail(?DELAY(Action),?DELAY(Prop))).
+-define(TRAPEXIT(Prop), proper:trapexit(?DELAY(Prop))).
+-define(TIMEOUT(Limit,Prop), proper:timeout(Limit,?DELAY(Prop))).
+%% TODO: -define(ALWAYS(Tests,Prop), proper:always(Tests,?DELAY(Prop))).
+%% TODO: -define(SOMETIMES(Tests,Prop), proper:sometimes(Tests,?DELAY(Prop))).
+
+
+%%------------------------------------------------------------------------------
+%% Generator macros
+%%------------------------------------------------------------------------------
+
+-define(FORCE(X), (X)()).
+-define(DELAY(X), fun() -> X end).
+-define(LAZY(X), proper_types:lazy(?DELAY(X))).
+-define(SIZED(SizeArg,Gen), proper_types:sized(fun(SizeArg) -> Gen end)).
+-define(LET(X,RawType,Gen), proper_types:bind(RawType,fun(X) -> Gen end,false)).
+-define(SHRINK(Gen,AltGens),
+ proper_types:shrinkwith(?DELAY(Gen),?DELAY(AltGens))).
+-define(LETSHRINK(Xs,RawType,Gen),
+ proper_types:bind(RawType,fun(Xs) -> Gen end,true)).
+-define(SUCHTHAT(X,RawType,Condition),
+ proper_types:add_constraint(RawType,fun(X) -> Condition end,true)).
+-define(SUCHTHATMAYBE(X,RawType,Condition),
+ proper_types:add_constraint(RawType,fun(X) -> Condition end,false)).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_gen.erl b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_gen.erl
new file mode 100644
index 0000000000..bf627d1373
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_gen.erl
@@ -0,0 +1,624 @@
+%%% Copyright 2010-2013 Manolis Papadakis <[email protected]>,
+%%% Eirini Arvaniti <[email protected]>
+%%% and Kostis Sagonas <[email protected]>
+%%%
+%%% This file is part of PropEr.
+%%%
+%%% PropEr is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% PropEr 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>.
+
+%%% @copyright 2010-2013 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
+%%% @version {@version}
+%%% @author Manolis Papadakis
+
+%%% @doc Generator subsystem and generators for basic types.
+%%%
+%%% You can use <a href="#index">these</a> functions to try out the random
+%%% instance generation and shrinking subsystems.
+%%%
+%%% CAUTION: These functions should never be used inside properties. They are
+%%% meant for demonstration purposes only.
+
+-module(proper_gen).
+-export([pick/1, pick/2, pick/3, sample/1, sample/3, sampleshrink/1, sampleshrink/2]).
+
+-export([safe_generate/1]).
+-export([generate/1, normal_gen/1, alt_gens/1, clean_instance/1,
+ get_ret_type/1]).
+-export([integer_gen/3, float_gen/3, atom_gen/1, atom_rev/1, binary_gen/1,
+ binary_rev/1, binary_len_gen/1, bitstring_gen/1, bitstring_rev/1,
+ bitstring_len_gen/1, list_gen/2, distlist_gen/3, vector_gen/2,
+ union_gen/1, weighted_union_gen/1, tuple_gen/1, loose_tuple_gen/2,
+ loose_tuple_rev/2, exactly_gen/1, fixed_list_gen/1, function_gen/2,
+ any_gen/1, native_type_gen/2, safe_weighted_union_gen/1,
+ safe_union_gen/1]).
+
+-export_type([instance/0, imm_instance/0, sized_generator/0, nosize_generator/0,
+ generator/0, reverse_gen/0, combine_fun/0, alt_gens/0]).
+
+-include("proper_internal.hrl").
+
+
+%%-----------------------------------------------------------------------------
+%% Types
+%%-----------------------------------------------------------------------------
+
+%% TODO: update imm_instance() when adding more types: be careful when reading
+%% anything that returns it
+%% @private_type
+-type imm_instance() :: proper_types:raw_type()
+ | instance()
+ | {'$used', imm_instance(), imm_instance()}
+ | {'$to_part', imm_instance()}.
+-type instance() :: term().
+%% A value produced by the random instance generator.
+-type error_reason() :: 'arity_limit' | 'cant_generate' | {'typeserver',term()}.
+
+%% @private_type
+-type sized_generator() :: fun((size()) -> imm_instance()).
+%% @private_type
+-type typed_sized_generator() :: {'typed',
+ fun((proper_types:type(),size()) ->
+ imm_instance())}.
+%% @private_type
+-type nosize_generator() :: fun(() -> imm_instance()).
+%% @private_type
+-type typed_nosize_generator() :: {'typed',
+ fun((proper_types:type()) ->
+ imm_instance())}.
+%% @private_type
+-type generator() :: sized_generator()
+ | typed_sized_generator()
+ | nosize_generator()
+ | typed_nosize_generator().
+%% @private_type
+-type plain_reverse_gen() :: fun((instance()) -> imm_instance()).
+%% @private_type
+-type typed_reverse_gen() :: {'typed',
+ fun((proper_types:type(),instance()) ->
+ imm_instance())}.
+%% @private_type
+-type reverse_gen() :: plain_reverse_gen() | typed_reverse_gen().
+%% @private_type
+-type combine_fun() :: fun((instance()) -> imm_instance()).
+%% @private_type
+-type alt_gens() :: fun(() -> [imm_instance()]).
+%% @private_type
+-type fun_seed() :: {non_neg_integer(),non_neg_integer()}.
+
+
+%%-----------------------------------------------------------------------------
+%% Instance generation functions
+%%-----------------------------------------------------------------------------
+
+%% @private
+-spec safe_generate(proper_types:raw_type()) ->
+ {'ok',imm_instance()} | {'error',error_reason()}.
+safe_generate(RawType) ->
+ try generate(RawType) of
+ ImmInstance -> {ok, ImmInstance}
+ catch
+ throw:'$arity_limit' -> {error, arity_limit};
+ throw:'$cant_generate' -> {error, cant_generate};
+ throw:{'$typeserver',SubReason} -> {error, {typeserver,SubReason}}
+ end.
+
+%% @private
+-spec generate(proper_types:raw_type()) -> imm_instance().
+generate(RawType) ->
+ Type = proper_types:cook_outer(RawType),
+ ok = add_parameters(Type),
+ Instance = generate(Type, get('$constraint_tries'), none),
+ ok = remove_parameters(Type),
+ Instance.
+
+-spec add_parameters(proper_types:type()) -> 'ok'.
+add_parameters(Type) ->
+ case proper_types:find_prop(parameters, Type) of
+ {ok, Params} ->
+ OldParams = erlang:get('$parameters'),
+ case OldParams of
+ undefined ->
+ erlang:put('$parameters', Params);
+ _ ->
+ erlang:put('$parameters', Params ++ OldParams)
+ end,
+ ok;
+ _ ->
+ ok
+ end.
+
+-spec remove_parameters(proper_types:type()) -> 'ok'.
+remove_parameters(Type) ->
+ case proper_types:find_prop(parameters, Type) of
+ {ok, Params} ->
+ AllParams = erlang:get('$parameters'),
+ case AllParams of
+ Params->
+ erlang:erase('$parameters');
+ _ ->
+ erlang:put('$parameters', AllParams -- Params)
+ end,
+ ok;
+ _ ->
+ ok
+ end.
+
+-spec generate(proper_types:type(), non_neg_integer(),
+ 'none' | {'ok',imm_instance()}) -> imm_instance().
+generate(_Type, 0, none) ->
+ throw('$cant_generate');
+generate(_Type, 0, {ok,Fallback}) ->
+ Fallback;
+generate(Type, TriesLeft, Fallback) ->
+ ImmInstance =
+ case proper_types:get_prop(kind, Type) of
+ constructed ->
+ PartsType = proper_types:get_prop(parts_type, Type),
+ Combine = proper_types:get_prop(combine, Type),
+ ImmParts = generate(PartsType),
+ Parts = clean_instance(ImmParts),
+ ImmInstance1 = Combine(Parts),
+ %% TODO: We can just generate the internal type: if it's not
+ %% a type, it will turn into an exactly.
+ ImmInstance2 =
+ case proper_types:is_raw_type(ImmInstance1) of
+ true -> generate(ImmInstance1);
+ false -> ImmInstance1
+ end,
+ {'$used',ImmParts,ImmInstance2};
+ _ ->
+ ImmInstance1 = normal_gen(Type),
+ case proper_types:is_raw_type(ImmInstance1) of
+ true -> generate(ImmInstance1);
+ false -> ImmInstance1
+ end
+ end,
+ case proper_types:satisfies_all(clean_instance(ImmInstance), Type) of
+ {_,true} -> ImmInstance;
+ {true,false} -> generate(Type, TriesLeft - 1, {ok,ImmInstance});
+ {false,false} -> generate(Type, TriesLeft - 1, Fallback)
+ end.
+
+%% @equiv pick(Type, 10)
+-spec pick(Type::proper_types:raw_type()) -> {'ok',instance()} | 'error'.
+pick(RawType) ->
+ pick(RawType, 10).
+
+%% @equiv pick(Type, Size, now())
+-spec pick(Type::proper_types:raw_type(), size()) -> {'ok', instance()} | 'error'.
+pick(RawType, Size) ->
+ pick(RawType, Size, now()).
+
+%% @doc Generates a random instance of `Type', of size `Size' with seed `Seed'.
+-spec pick(Type::proper_types:raw_type(), size(), seed()) ->
+ {'ok',instance()} | 'error'.
+pick(RawType, Size, Seed) ->
+ proper:global_state_init_size_seed(Size, Seed),
+ case clean_instance(safe_generate(RawType)) of
+ {ok,Instance} = Result ->
+ Msg = "WARNING: Some garbage has been left in the process registry "
+ "and the code server~n"
+ "to allow for the returned function(s) to run normally.~n"
+ "Please run proper:global_state_erase() when done.~n",
+ case contains_fun(Instance) of
+ true -> io:format(Msg, []);
+ false -> proper:global_state_erase()
+ end,
+ Result;
+ {error,Reason} ->
+ proper:report_error(Reason, fun io:format/2),
+ proper:global_state_erase(),
+ error
+ end.
+
+%% @equiv sample(Type, 10, 20)
+-spec sample(Type::proper_types:raw_type()) -> 'ok'.
+sample(RawType) ->
+ sample(RawType, 10, 20).
+
+%% @doc Generates and prints one random instance of `Type' for each size from
+%% `StartSize' up to `EndSize'.
+-spec sample(Type::proper_types:raw_type(), size(), size()) -> 'ok'.
+sample(RawType, StartSize, EndSize) when StartSize =< EndSize ->
+ Tests = EndSize - StartSize + 1,
+ Prop = ?FORALL(X, RawType, begin io:format("~p~n",[X]), true end),
+ Opts = [quiet,{start_size,StartSize},{max_size,EndSize},{numtests,Tests}],
+ _ = proper:quickcheck(Prop, Opts),
+ ok.
+
+%% @equiv sampleshrink(Type, 10)
+-spec sampleshrink(Type::proper_types:raw_type()) -> 'ok'.
+sampleshrink(RawType) ->
+ sampleshrink(RawType, 10).
+
+%% @doc Generates a random instance of `Type', of size `Size', then shrinks it
+%% as far as it goes. The value produced on each step of the shrinking process
+%% is printed on the screen.
+-spec sampleshrink(Type::proper_types:raw_type(), size()) -> 'ok'.
+sampleshrink(RawType, Size) ->
+ proper:global_state_init_size(Size),
+ Type = proper_types:cook_outer(RawType),
+ case safe_generate(Type) of
+ {ok,ImmInstance} ->
+ Shrunk = keep_shrinking(ImmInstance, [], Type),
+ PrintInst = fun(I) -> io:format("~p~n",[clean_instance(I)]) end,
+ lists:foreach(PrintInst, Shrunk);
+ {error,Reason} ->
+ proper:report_error(Reason, fun io:format/2)
+ end,
+ proper:global_state_erase(),
+ ok.
+
+-spec keep_shrinking(imm_instance(), [imm_instance()], proper_types:type()) ->
+ [imm_instance(),...].
+keep_shrinking(ImmInstance, Acc, Type) ->
+ case proper_shrink:shrink(ImmInstance, Type, init) of
+ {[], _NewState} ->
+ lists:reverse([ImmInstance|Acc]);
+ {[Shrunk|_Rest], _NewState} ->
+ keep_shrinking(Shrunk, [ImmInstance|Acc], Type)
+ end.
+
+-spec contains_fun(term()) -> boolean().
+contains_fun(List) when is_list(List) ->
+ proper_arith:safe_any(fun contains_fun/1, List);
+contains_fun(Tuple) when is_tuple(Tuple) ->
+ contains_fun(tuple_to_list(Tuple));
+contains_fun(Fun) when is_function(Fun) ->
+ true;
+contains_fun(_Term) ->
+ false.
+
+
+%%-----------------------------------------------------------------------------
+%% Utility functions
+%%-----------------------------------------------------------------------------
+
+%% @private
+-spec normal_gen(proper_types:type()) -> imm_instance().
+normal_gen(Type) ->
+ case proper_types:get_prop(generator, Type) of
+ {typed, Gen} ->
+ if
+ is_function(Gen, 1) -> Gen(Type);
+ is_function(Gen, 2) -> Gen(Type, proper:get_size(Type))
+ end;
+ Gen ->
+ if
+ is_function(Gen, 0) -> Gen();
+ is_function(Gen, 1) -> Gen(proper:get_size(Type))
+ end
+ end.
+
+%% @private
+-spec alt_gens(proper_types:type()) -> [imm_instance()].
+alt_gens(Type) ->
+ case proper_types:find_prop(alt_gens, Type) of
+ {ok, AltGens} -> ?FORCE(AltGens);
+ error -> []
+ end.
+
+%% @private
+-spec clean_instance(imm_instance()) -> instance().
+clean_instance({'$used',_ImmParts,ImmInstance}) ->
+ clean_instance(ImmInstance);
+clean_instance({'$to_part',ImmInstance}) ->
+ clean_instance(ImmInstance);
+clean_instance(ImmInstance) ->
+ if
+ is_list(ImmInstance) ->
+ %% CAUTION: this must handle improper lists
+ proper_arith:safe_map(fun clean_instance/1, ImmInstance);
+ is_tuple(ImmInstance) ->
+ proper_arith:tuple_map(fun clean_instance/1, ImmInstance);
+ true ->
+ ImmInstance
+ end.
+
+
+%%-----------------------------------------------------------------------------
+%% Basic type generators
+%%-----------------------------------------------------------------------------
+
+%% @private
+-spec integer_gen(size(), proper_types:extint(), proper_types:extint()) ->
+ integer().
+integer_gen(Size, inf, inf) ->
+ proper_arith:rand_int(Size);
+integer_gen(Size, inf, High) ->
+ High - proper_arith:rand_non_neg_int(Size);
+integer_gen(Size, Low, inf) ->
+ Low + proper_arith:rand_non_neg_int(Size);
+integer_gen(Size, Low, High) ->
+ proper_arith:smart_rand_int(Size, Low, High).
+
+%% @private
+-spec float_gen(size(), proper_types:extnum(), proper_types:extnum()) ->
+ float().
+float_gen(Size, inf, inf) ->
+ proper_arith:rand_float(Size);
+float_gen(Size, inf, High) ->
+ High - proper_arith:rand_non_neg_float(Size);
+float_gen(Size, Low, inf) ->
+ Low + proper_arith:rand_non_neg_float(Size);
+float_gen(_Size, Low, High) ->
+ proper_arith:rand_float(Low, High).
+
+%% @private
+-spec atom_gen(size()) -> proper_types:type().
+%% We make sure we never clash with internal atoms by checking that the first
+%% character is not '$'.
+atom_gen(Size) ->
+ ?LET(Str,
+ ?SUCHTHAT(X,
+ proper_types:resize(Size,
+ proper_types:list(proper_types:byte())),
+ X =:= [] orelse hd(X) =/= $$),
+ list_to_atom(Str)).
+
+%% @private
+-spec atom_rev(atom()) -> imm_instance().
+atom_rev(Atom) ->
+ {'$used', atom_to_list(Atom), Atom}.
+
+%% @private
+-spec binary_gen(size()) -> proper_types:type().
+binary_gen(Size) ->
+ ?LET(Bytes,
+ proper_types:resize(Size,
+ proper_types:list(proper_types:byte())),
+ list_to_binary(Bytes)).
+
+%% @private
+-spec binary_rev(binary()) -> imm_instance().
+binary_rev(Binary) ->
+ {'$used', binary_to_list(Binary), Binary}.
+
+%% @private
+-spec binary_len_gen(length()) -> proper_types:type().
+binary_len_gen(Len) ->
+ ?LET(Bytes,
+ proper_types:vector(Len, proper_types:byte()),
+ list_to_binary(Bytes)).
+
+%% @private
+-spec bitstring_gen(size()) -> proper_types:type().
+bitstring_gen(Size) ->
+ ?LET({BytesHead, NumBits, TailByte},
+ {proper_types:resize(Size,proper_types:binary()),
+ proper_types:range(0,7), proper_types:range(0,127)},
+ <<BytesHead/binary, TailByte:NumBits>>).
+
+%% @private
+-spec bitstring_rev(bitstring()) -> imm_instance().
+bitstring_rev(BitString) ->
+ List = bitstring_to_list(BitString),
+ {BytesList, BitsTail} = lists:splitwith(fun erlang:is_integer/1, List),
+ {NumBits, TailByte} = case BitsTail of
+ [] -> {0, 0};
+ [Bits] -> N = bit_size(Bits),
+ <<Byte:N>> = Bits,
+ {N, Byte}
+ end,
+ {'$used',
+ {{'$used',BytesList,list_to_binary(BytesList)}, NumBits, TailByte},
+ BitString}.
+
+%% @private
+-spec bitstring_len_gen(length()) -> proper_types:type().
+bitstring_len_gen(Len) ->
+ BytesLen = Len div 8,
+ BitsLen = Len rem 8,
+ ?LET({BytesHead, NumBits, TailByte},
+ {proper_types:binary(BytesLen), BitsLen,
+ proper_types:range(0, 1 bsl BitsLen - 1)},
+ <<BytesHead/binary, TailByte:NumBits>>).
+
+%% @private
+-spec list_gen(size(), proper_types:type()) -> [imm_instance()].
+list_gen(Size, ElemType) ->
+ Len = proper_arith:rand_int(0, Size),
+ vector_gen(Len, ElemType).
+
+%% @private
+-spec distlist_gen(size(), sized_generator(), boolean()) -> [imm_instance()].
+distlist_gen(RawSize, Gen, NonEmpty) ->
+ Len = case NonEmpty of
+ true -> proper_arith:rand_int(1, erlang:max(1,RawSize));
+ false -> proper_arith:rand_int(0, RawSize)
+ end,
+ Size = case Len of
+ 1 -> RawSize - 1;
+ _ -> RawSize
+ end,
+ %% TODO: this produces a lot of types: maybe a simple 'div' is sufficient?
+ Sizes = proper_arith:distribute(Size, Len),
+ InnerTypes = [Gen(S) || S <- Sizes],
+ fixed_list_gen(InnerTypes).
+
+%% @private
+-spec vector_gen(length(), proper_types:type()) -> [imm_instance()].
+vector_gen(Len, ElemType) ->
+ vector_gen_tr(Len, ElemType, []).
+
+-spec vector_gen_tr(length(), proper_types:type(), [imm_instance()]) ->
+ [imm_instance()].
+vector_gen_tr(0, _ElemType, AccList) ->
+ AccList;
+vector_gen_tr(Left, ElemType, AccList) ->
+ vector_gen_tr(Left - 1, ElemType, [generate(ElemType) | AccList]).
+
+%% @private
+-spec union_gen([proper_types:type(),...]) -> imm_instance().
+union_gen(Choices) ->
+ {_Choice,Type} = proper_arith:rand_choose(Choices),
+ generate(Type).
+
+%% @private
+-spec weighted_union_gen([{frequency(),proper_types:type()},...]) ->
+ imm_instance().
+weighted_union_gen(FreqChoices) ->
+ {_Choice,Type} = proper_arith:freq_choose(FreqChoices),
+ generate(Type).
+
+%% @private
+-spec safe_union_gen([proper_types:type(),...]) -> imm_instance().
+safe_union_gen(Choices) ->
+ {Choice,Type} = proper_arith:rand_choose(Choices),
+ try generate(Type)
+ catch
+ error:_ ->
+ safe_union_gen(proper_arith:list_remove(Choice, Choices))
+ end.
+
+%% @private
+-spec safe_weighted_union_gen([{frequency(),proper_types:type()},...]) ->
+ imm_instance().
+safe_weighted_union_gen(FreqChoices) ->
+ {Choice,Type} = proper_arith:freq_choose(FreqChoices),
+ try generate(Type)
+ catch
+ error:_ ->
+ safe_weighted_union_gen(proper_arith:list_remove(Choice,
+ FreqChoices))
+ end.
+
+%% @private
+-spec tuple_gen([proper_types:type()]) -> tuple().
+tuple_gen(Fields) ->
+ list_to_tuple(fixed_list_gen(Fields)).
+
+%% @private
+-spec loose_tuple_gen(size(), proper_types:type()) -> proper_types:type().
+loose_tuple_gen(Size, ElemType) ->
+ ?LET(L,
+ proper_types:resize(Size, proper_types:list(ElemType)),
+ list_to_tuple(L)).
+
+%% @private
+-spec loose_tuple_rev(tuple(), proper_types:type()) -> imm_instance().
+loose_tuple_rev(Tuple, ElemType) ->
+ CleanList = tuple_to_list(Tuple),
+ List = case proper_types:find_prop(reverse_gen, ElemType) of
+ {ok,{typed, ReverseGen}} ->
+ [ReverseGen(ElemType,X) || X <- CleanList];
+ {ok,ReverseGen} -> [ReverseGen(X) || X <- CleanList];
+ error -> CleanList
+ end,
+ {'$used', List, Tuple}.
+
+%% @private
+-spec exactly_gen(T) -> T.
+exactly_gen(X) ->
+ X.
+
+%% @private
+-spec fixed_list_gen([proper_types:type()]) -> imm_instance()
+ ; ({[proper_types:type()],proper_types:type()}) ->
+ maybe_improper_list(imm_instance(), imm_instance() | []).
+fixed_list_gen({ProperHead,ImproperTail}) ->
+ [generate(F) || F <- ProperHead] ++ generate(ImproperTail);
+fixed_list_gen(ProperFields) ->
+ [generate(F) || F <- ProperFields].
+
+%% @private
+-spec function_gen(arity(), proper_types:type()) -> function().
+function_gen(Arity, RetType) ->
+ FunSeed = {proper_arith:rand_int(0, ?SEED_RANGE - 1),
+ proper_arith:rand_int(0, ?SEED_RANGE - 1)},
+ create_fun(Arity, RetType, FunSeed).
+
+%% @private
+-spec any_gen(size()) -> imm_instance().
+any_gen(Size) ->
+ case get('$any_type') of
+ undefined -> real_any_gen(Size);
+ {type,AnyType} -> generate(proper_types:resize(Size, AnyType))
+ end.
+
+-spec real_any_gen(size()) -> imm_instance().
+real_any_gen(0) ->
+ SimpleTypes = [proper_types:integer(), proper_types:float(),
+ proper_types:atom()],
+ union_gen(SimpleTypes);
+real_any_gen(Size) ->
+ FreqChoices = [{?ANY_SIMPLE_PROB,simple}, {?ANY_BINARY_PROB,binary},
+ {?ANY_EXPAND_PROB,expand}],
+ case proper_arith:freq_choose(FreqChoices) of
+ {_,simple} ->
+ real_any_gen(0);
+ {_,binary} ->
+ generate(proper_types:resize(Size, proper_types:bitstring()));
+ {_,expand} ->
+ %% TODO: statistics of produced terms?
+ NumElems = proper_arith:rand_int(0, Size - 1),
+ ElemSizes = proper_arith:distribute(Size - 1, NumElems),
+ ElemTypes = [?LAZY(real_any_gen(S)) || S <- ElemSizes],
+ case proper_arith:rand_int(1,2) of
+ 1 -> fixed_list_gen(ElemTypes);
+ 2 -> tuple_gen(ElemTypes)
+ end
+ end.
+
+%% @private
+-spec native_type_gen(mod_name(), string()) -> proper_types:type().
+native_type_gen(Mod, TypeStr) ->
+ case proper_typeserver:translate_type({Mod,TypeStr}) of
+ {ok,Type} -> Type;
+ {error,Reason} -> throw({'$typeserver',Reason})
+ end.
+
+
+%%------------------------------------------------------------------------------
+%% Function-generation functions
+%%------------------------------------------------------------------------------
+
+-spec create_fun(arity(), proper_types:type(), fun_seed()) -> function().
+create_fun(Arity, RetType, FunSeed) ->
+ Handler = fun(Args) -> function_body(Args, RetType, FunSeed) end,
+ Err = fun() -> throw('$arity_limit') end,
+ case Arity of
+ 0 -> fun() -> Handler([]) end;
+ _ -> Err()
+ end.
+
+%% @private
+-spec get_ret_type(function()) -> proper_types:type().
+get_ret_type(Fun) ->
+ {arity,Arity} = erlang:fun_info(Fun, arity),
+ put('$get_ret_type', true),
+ RetType = apply(Fun, lists:duplicate(Arity,dummy)),
+ erase('$get_ret_type'),
+ RetType.
+-spec function_body([term()], proper_types:type(), fun_seed()) ->
+ proper_types:type() | instance().
+function_body(Args, RetType, {Seed1,Seed2}) ->
+ case get('$get_ret_type') of
+ true ->
+ RetType;
+ _ ->
+ SavedSeed = get(?SEED_NAME),
+ update_seed({Seed1,Seed2,erlang:phash2(Args,?SEED_RANGE)}),
+ Ret = clean_instance(generate(RetType)),
+ put(?SEED_NAME, SavedSeed),
+ proper_symb:internal_eval(Ret)
+ end.
+
+-ifdef(USE_SFMT).
+update_seed(Seed) ->
+ sfmt:seed(Seed).
+-else.
+update_seed(Seed) ->
+ put(random_seed, Seed).
+-endif.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_internal.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_internal.hrl
new file mode 100644
index 0000000000..c790d7d4db
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_internal.hrl
@@ -0,0 +1,92 @@
+%%% Copyright 2010-2013 Manolis Papadakis <[email protected]>,
+%%% Eirini Arvaniti <[email protected]>
+%%% and Kostis Sagonas <[email protected]>
+%%%
+%%% This file is part of PropEr.
+%%%
+%%% PropEr is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% PropEr 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>.
+
+%%% @copyright 2010-2013 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
+%%% @version {@version}
+%%% @author Manolis Papadakis
+%%% @doc Internal header file: This header is included in all PropEr source
+%%% files.
+
+-include("proper_common.hrl").
+
+
+%%------------------------------------------------------------------------------
+%% Activate strip_types parse transform
+%%------------------------------------------------------------------------------
+
+-ifdef(NO_TYPES).
+-compile({parse_transform, strip_types}).
+-endif.
+
+%%------------------------------------------------------------------------------
+%% Random generator selection
+%%------------------------------------------------------------------------------
+
+-ifdef(USE_SFMT).
+-define(RANDOM_MOD, sfmt).
+-define(SEED_NAME, sfmt_seed).
+-else.
+-define(RANDOM_MOD, random).
+-define(SEED_NAME, random_seed).
+-endif.
+
+%%------------------------------------------------------------------------------
+%% Macros
+%%------------------------------------------------------------------------------
+
+-define(PROPERTY_PREFIX, "prop_").
+
+
+%%------------------------------------------------------------------------------
+%% Constants
+%%------------------------------------------------------------------------------
+
+-define(SEED_RANGE, 4294967296).
+-define(MAX_ARITY, 20).
+-define(MAX_TRIES_FACTOR, 5).
+-define(ANY_SIMPLE_PROB, 3).
+-define(ANY_BINARY_PROB, 1).
+-define(ANY_EXPAND_PROB, 8).
+-define(SMALL_RANGE_THRESHOLD, 16#FFFF).
+
+
+%%------------------------------------------------------------------------------
+%% Common type aliases
+%%------------------------------------------------------------------------------
+
+%% TODO: Perhaps these should be moved inside modules.
+-type mod_name() :: atom().
+-type fun_name() :: atom().
+-type size() :: non_neg_integer().
+-type length() :: non_neg_integer().
+-type position() :: pos_integer().
+-type frequency() :: pos_integer().
+-type seed() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
+
+-type abs_form() :: erl_parse:abstract_form().
+-type abs_expr() :: erl_parse:abstract_expr().
+-type abs_clause() :: erl_parse:abstract_clause().
+
+%% TODO: Replace these with the appropriate types from stdlib.
+-type abs_type() :: term().
+-type abs_rec_field() :: term().
+
+-type loose_tuple(T) :: {} | {T} | {T,T} | {T,T,T} | {T,T,T,T} | {T,T,T,T,T}
+ | {T,T,T,T,T,T} | {T,T,T,T,T,T,T} | {T,T,T,T,T,T,T,T}
+ | {T,T,T,T,T,T,T,T,T} | {T,T,T,T,T,T,T,T,T,T} | tuple().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_types.erl b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_types.erl
new file mode 100644
index 0000000000..fe83a0ba11
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_types.erl
@@ -0,0 +1,1349 @@
+%%% Copyright 2010-2013 Manolis Papadakis <[email protected]>,
+%%% Eirini Arvaniti <[email protected]>
+%%% and Kostis Sagonas <[email protected]>
+%%%
+%%% This file is part of PropEr.
+%%%
+%%% PropEr is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% PropEr 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>.
+
+%%% @copyright 2010-2013 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
+%%% @version {@version}
+%%% @author Manolis Papadakis
+
+%%% @doc Type manipulation functions and predefined types.
+%%%
+%%% == Basic types ==
+%%% This module defines all the basic types of the PropEr type system as
+%%% functions. See the <a href="#index">function index</a> for an overview.
+%%%
+%%% Types can be combined in tuples or lists to produce other types. Exact
+%%% values (such as exact numbers, atoms, binaries and strings) can be combined
+%%% with types inside such structures, like in this example of the type of a
+%%% tagged tuple: ``{'result', integer()}''.
+%%%
+%%% When including the PropEr header file, all
+%%% <a href="#index">API functions</a> of this module are automatically
+%%% imported, unless `PROPER_NO_IMPORTS' is defined.
+%%%
+%%% == Customized types ==
+%%% The following operators can be applied to basic types in order to produce
+%%% new ones:
+%%%
+%%% <dl>
+%%% <dt>`?LET(<Xs>, <Xs_type>, <In>)'</dt>
+%%% <dd>To produce an instance of this type, all appearances of the variables
+%%% in `<Xs>' are replaced inside `<In>' by their corresponding values in a
+%%% randomly generated instance of `<Xs_type>'. It's OK for the `<In>' part to
+%%% evaluate to a type - in that case, an instance of the inner type is
+%%% generated recursively.</dd>
+%%% <dt>`?SUCHTHAT(<X>, <Type>, <Condition>)'</dt>
+%%% <dd>This produces a specialization of `<Type>', which only includes those
+%%% members of `<Type>' that satisfy the constraint `<Condition>' - that is,
+%%% those members for which the function `fun(<X>) -> <Condition> end' returns
+%%% `true'. If the constraint is very strict - that is, only a small
+%%% percentage of instances of `<Type>' pass the test - it will take a lot of
+%%% tries for the instance generation subsystem to randomly produce a valid
+%%% instance. This will result in slower testing, and testing may even be
+%%% stopped short, in case the `constraint_tries' limit is reached (see the
+%%% "Options" section in the documentation of the {@link proper} module). If
+%%% this is the case, it would be more appropriate to generate valid instances
+%%% of the specialized type using the `?LET' macro. Also make sure that even
+%%% small instances can satisfy the constraint, since PropEr will only try
+%%% small instances at the start of testing. If this is not possible, you can
+%%% instruct PropEr to start at a larger size, by supplying a suitable value
+%%% for the `start_size' option (see the "Options" section in the
+%%% documentation of the {@link proper} module).</dd>
+%%% <dt>`?SUCHTHATMAYBE(<X>, <Type>, <Condition>)'</dt>
+%%% <dd>Equivalent to the `?SUCHTHAT' macro, but the constraint `<Condition>'
+%%% is considered non-strict: if the `constraint_tries' limit is reached, the
+%%% generator will just return an instance of `<Type>' instead of failing,
+%%% even if that instance doesn't satisfy the constraint.</dd>
+%%% <dt>`?SHRINK(<Generator>, <List_of_alt_gens>)'</dt>
+%%% <dd>This creates a type whose instances are generated by evaluating the
+%%% statement block `<Generator>' (this may evaluate to a type, which will
+%%% then be generated recursively). If an instance of such a type is to be
+%%% shrunk, the generators in `<List_of_alt_gens>' are first run to produce
+%%% hopefully simpler instances of the type. Thus, the generators in the
+%%% second argument should be simpler than the default. The simplest ones
+%%% should be at the front of the list, since those are the generators
+%%% preferred by the shrinking subsystem. Like the main `<Generator>', the
+%%% alternatives may also evaluate to a type, which is generated recursively.
+%%% </dd>
+%%% <dt>`?LETSHRINK(<List_of_variables>, <List_of_types>, <Generator>)'</dt>
+%%% <dd>This is created by combining a `?LET' and a `?SHRINK' macro. Instances
+%%% are generated by applying a randomly generated list of values inside
+%%% `<Generator>' (just like a `?LET', with the added constraint that the
+%%% variables and types must be provided in a list - alternatively,
+%%% `<List_of_types>' may be a list or vector type). When shrinking instances
+%%% of such a type, the sub-instances that were combined to produce it are
+%%% first tried in place of the failing instance.</dd>
+%%% <dt>`?LAZY(<Generator>)'</dt>
+%%% <dd>This construct returns a type whose only purpose is to delay the
+%%% evaluation of `<Generator>' (`<Generator>' can return a type, which will
+%%% be generated recursively). Using this, you can simulate the lazy
+%%% generation of instances:
+%%% ``` stream() -> ?LAZY(frequency([ {1,[]}, {3,[0|stream()]} ])). '''
+%%% The above type produces lists of zeroes with an average length of 3. Note
+%%% that, had we not enclosed the generator with a `?LAZY' macro, the
+%%% evaluation would continue indefinitely, due to the eager evaluation of
+%%% the Erlang language.</dd>
+%%% <dt>`non_empty(<List_or_binary_type>)'</dt>
+%%% <dd>See the documentation for {@link non_empty/1}.</dd>
+%%% <dt>`noshrink(<Type>)'</dt>
+%%% <dd>See the documentation for {@link noshrink/1}.</dd>
+%%% <dt>`default(<Default_value>, <Type>)'</dt>
+%%% <dd>See the documentation for {@link default/2}.</dd>
+%%% <dt>`with_parameter(<Parameter>, <Value>, <Type>)'</dt>
+%%% <dd>See the documentation for {@link with_parameter/3}.</dd>
+%%% <dt>`with_parameters(<Param_value_pairs>, <Type>)'</dt>
+%%% <dd>See the documentation for {@link with_parameters/2}.</dd>
+%%% </dl>
+%%%
+%%% == Size manipulation ==
+%%% The following operators are related to the `size' parameter, which controls
+%%% the maximum size of produced instances. The actual size of a produced
+%%% instance is chosen randomly, but can never exceed the value of the `size'
+%%% parameter at the moment of generation. A more accurate definition is the
+%%% following: the maximum instance of `size S' can never be smaller than the
+%%% maximum instance of `size S-1'. The actual size of an instance is measured
+%%% differently for each type: the actual size of a list is its length, while
+%%% the actual size of a tree may be the number of its internal nodes. Some
+%%% types, e.g. unions, have no notion of size, thus their generation is not
+%%% influenced by the value of `size'. The `size' parameter starts at 1 and
+%%% grows automatically during testing.
+%%%
+%%% <dl>
+%%% <dt>`?SIZED(<S>, <Generator>)'</dt>
+%%% <dd>Creates a new type, whose instances are produced by replacing all
+%%% appearances of the `<S>' parameter inside the statement block
+%%% `<Generator>' with the value of the `size' parameter. It's OK for the
+%%% `<Generator>' to return a type - in that case, an instance of the inner
+%%% type is generated recursively.</dd>
+%%% <dt>`resize(<New_size>, <Type>)'</dt>
+%%% <dd>See the documentation for {@link resize/2}.</dd>
+%%% </dl>
+
+-module(proper_types).
+-export([is_inst/2, is_inst/3]).
+
+-export([integer/2, float/2, atom/0, binary/0, binary/1, bitstring/0,
+ bitstring/1, list/1, vector/2, union/1, weighted_union/1, tuple/1,
+ loose_tuple/1, exactly/1, fixed_list/1, function/2, any/0,
+ shrink_list/1, safe_union/1, safe_weighted_union/1]).
+-export([integer/0, non_neg_integer/0, pos_integer/0, neg_integer/0, range/2,
+ float/0, non_neg_float/0, number/0, boolean/0, byte/0, char/0,
+ list/0, tuple/0, string/0, wunion/1, term/0, timeout/0, arity/0]).
+-export([int/0, nat/0, largeint/0, real/0, bool/0, choose/2, elements/1,
+ oneof/1, frequency/1, return/1, default/2, orderedlist/1, function0/1,
+ function1/1, function2/1, function3/1, function4/1,
+ weighted_default/2]).
+-export([resize/2, non_empty/1, noshrink/1]).
+
+-export([cook_outer/1, is_type/1, equal_types/2, is_raw_type/1, to_binary/1,
+ from_binary/1, get_prop/2, find_prop/2, safe_is_instance/2,
+ is_instance/2, unwrap/1, weakly/1, strongly/1, satisfies_all/2,
+ new_type/2, subtype/2]).
+-export([lazy/1, sized/1, bind/3, shrinkwith/2, add_constraint/3,
+ native_type/2, distlist/3, with_parameter/3, with_parameters/2,
+ parameter/1, parameter/2]).
+-export([le/2]).
+
+-export_type([type/0, raw_type/0, extint/0, extnum/0]).
+
+-include("proper_internal.hrl").
+
+
+%%------------------------------------------------------------------------------
+%% Comparison with erl_types
+%%------------------------------------------------------------------------------
+
+%% Missing types
+%% -------------------
+%% will do:
+%% records, maybe_improper_list(T,S), nonempty_improper_list(T,S)
+%% maybe_improper_list(), maybe_improper_list(T), iolist, iodata
+%% don't need:
+%% nonempty_{list,string,maybe_improper_list}
+%% won't do:
+%% pid, port, ref, identifier, none, no_return, module, mfa, node
+%% array, dict, digraph, set, gb_tree, gb_set, queue, tid
+
+%% Missing type information
+%% ------------------------
+%% bin types:
+%% other unit sizes? what about size info?
+%% functions:
+%% generally some fun, unspecified number of arguments but specified
+%% return type
+%% any:
+%% doesn't cover functions and improper lists
+
+
+%%------------------------------------------------------------------------------
+%% Type declaration macros
+%%------------------------------------------------------------------------------
+
+-define(BASIC(PropList), new_type(PropList,basic)).
+-define(WRAPPER(PropList), new_type(PropList,wrapper)).
+-define(CONSTRUCTED(PropList), new_type(PropList,constructed)).
+-define(CONTAINER(PropList), new_type(PropList,container)).
+-define(SUBTYPE(Type,PropList), subtype(PropList,Type)).
+
+
+%%------------------------------------------------------------------------------
+%% Types
+%%------------------------------------------------------------------------------
+
+-type type_kind() :: 'basic' | 'wrapper' | 'constructed' | 'container' | atom().
+-type instance_test() :: fun((proper_gen:imm_instance()) -> boolean())
+ | {'typed',
+ fun((proper_types:type(),
+ proper_gen:imm_instance()) -> boolean())}.
+-type index() :: pos_integer().
+%% @alias
+-type value() :: term().
+%% @private_type
+%% @alias
+-type extint() :: integer() | 'inf'.
+%% @private_type
+%% @alias
+-type extnum() :: number() | 'inf'.
+-type constraint_fun() :: fun((proper_gen:instance()) -> boolean()).
+
+-opaque type() :: {'$type', [type_prop()]}.
+%% A type of the PropEr type system
+%% @type raw_type(). You can consider this as an equivalent of {@type type()}.
+-type raw_type() :: type() | [raw_type()] | loose_tuple(raw_type()) | term().
+-type type_prop_name() :: 'kind' | 'generator' | 'reverse_gen' | 'parts_type'
+ | 'combine' | 'alt_gens' | 'shrink_to_parts'
+ | 'size_transform' | 'is_instance' | 'shrinkers'
+ | 'noshrink' | 'internal_type' | 'internal_types'
+ | 'get_length' | 'split' | 'join' | 'get_indices'
+ | 'remove' | 'retrieve' | 'update' | 'constraints'
+ | 'parameters' | 'env' | 'subenv'.
+
+-type type_prop_value() :: term().
+-type type_prop() ::
+ {'kind', type_kind()}
+ | {'generator', proper_gen:generator()}
+ | {'reverse_gen', proper_gen:reverse_gen()}
+ | {'parts_type', type()}
+ | {'combine', proper_gen:combine_fun()}
+ | {'alt_gens', proper_gen:alt_gens()}
+ | {'shrink_to_parts', boolean()}
+ | {'size_transform', fun((size()) -> size())}
+ | {'is_instance', instance_test()}
+ | {'shrinkers', [proper_shrink:shrinker()]}
+ | {'noshrink', boolean()}
+ | {'internal_type', raw_type()}
+ | {'internal_types', tuple() | maybe_improper_list(type(),type() | [])}
+ %% The items returned by 'remove' must be of this type.
+ | {'get_length', fun((proper_gen:imm_instance()) -> length())}
+ %% If this is a container type, this should return the number of elements
+ %% it contains.
+ | {'split', fun((proper_gen:imm_instance()) -> [proper_gen:imm_instance()])
+ | fun((length(),proper_gen:imm_instance()) ->
+ {proper_gen:imm_instance(),proper_gen:imm_instance()})}
+ %% If present, the appropriate form depends on whether get_length is
+ %% defined: if get_length is undefined, this must be in the one-argument
+ %% form (e.g. a tree should be split into its subtrees), else it must be
+ %% in the two-argument form (e.g. a list should be split in two at the
+ %% index provided).
+ | {'join', fun((proper_gen:imm_instance(),proper_gen:imm_instance()) ->
+ proper_gen:imm_instance())}
+ | {'get_indices', fun((proper_types:type(),
+ proper_gen:imm_instance()) -> [index()])}
+ %% If this is a container type, this should return a list of indices we
+ %% can use to remove or insert elements from the given instance.
+ | {'remove', fun((index(),proper_gen:imm_instance()) ->
+ proper_gen:imm_instance())}
+ | {'retrieve', fun((index(), proper_gen:imm_instance() | tuple()
+ | maybe_improper_list(type(),type() | [])) ->
+ value() | type())}
+ | {'update', fun((index(),value(),proper_gen:imm_instance()) ->
+ proper_gen:imm_instance())}
+ | {'constraints', [{constraint_fun(), boolean()}]}
+ %% A list of constraints on instances of this type: each constraint is a
+ %% tuple of a fun that must return 'true' for each valid instance and a
+ %% boolean field that specifies whether the condition is strict.
+ | {'parameters', [{atom(),value()}]}
+ | {'env', term()}
+ | {'subenv', term()}.
+
+
+%%------------------------------------------------------------------------------
+%% Type manipulation functions
+%%------------------------------------------------------------------------------
+
+%% TODO: We shouldn't need the fully qualified type name in the range of these
+%% functions.
+
+%% @private
+%% TODO: just cook/1 ?
+-spec cook_outer(raw_type()) -> proper_types:type().
+cook_outer(Type = {'$type',_Props}) ->
+ Type;
+cook_outer(RawType) ->
+ if
+ is_tuple(RawType) -> tuple(tuple_to_list(RawType));
+ %% CAUTION: this must handle improper lists
+ is_list(RawType) -> fixed_list(RawType);
+ %% default case (covers integers, floats, atoms, binaries, ...):
+ true -> exactly(RawType)
+ end.
+
+%% @private
+-spec is_type(term()) -> boolean().
+is_type({'$type',_Props}) ->
+ true;
+is_type(_) ->
+ false.
+
+%% @private
+-spec equal_types(proper_types:type(), proper_types:type()) -> boolean().
+equal_types(SameType, SameType) ->
+ true;
+equal_types(_, _) ->
+ false.
+
+%% @private
+-spec is_raw_type(term()) -> boolean().
+is_raw_type({'$type',_TypeProps}) ->
+ true;
+is_raw_type(X) ->
+ if
+ is_tuple(X) -> is_raw_type_list(tuple_to_list(X));
+ is_list(X) -> is_raw_type_list(X);
+ true -> false
+ end.
+
+-spec is_raw_type_list(maybe_improper_list()) -> boolean().
+%% CAUTION: this must handle improper lists
+is_raw_type_list(List) ->
+ proper_arith:safe_any(fun is_raw_type/1, List).
+
+%% @private
+-spec to_binary(proper_types:type()) -> binary().
+to_binary(Type) ->
+ term_to_binary(Type).
+
+%% @private
+%% TODO: restore: -spec from_binary(binary()) -> proper_types:type().
+from_binary(Binary) ->
+ binary_to_term(Binary).
+
+-spec type_from_list([type_prop()]) -> proper_types:type().
+type_from_list(KeyValueList) ->
+ {'$type',KeyValueList}.
+
+-spec add_prop(type_prop_name(), type_prop_value(), proper_types:type()) ->
+ proper_types:type().
+add_prop(PropName, Value, {'$type',Props}) ->
+ {'$type',lists:keystore(PropName, 1, Props, {PropName, Value})}.
+
+-spec add_props([type_prop()], proper_types:type()) -> proper_types:type().
+add_props(PropList, {'$type',OldProps}) ->
+ {'$type', lists:foldl(fun({N,_}=NV,Acc) ->
+ lists:keystore(N, 1, Acc, NV)
+ end, OldProps, PropList)}.
+
+-spec append_to_prop(type_prop_name(), type_prop_value(),
+ proper_types:type()) -> proper_types:type().
+append_to_prop(PropName, Value, {'$type',Props}) ->
+ Val = case lists:keyfind(PropName, 1, Props) of
+ {PropName, V} ->
+ V;
+ _ ->
+ []
+ end,
+ {'$type', lists:keystore(PropName, 1, Props,
+ {PropName, lists:reverse([Value|Val])})}.
+
+-spec append_list_to_prop(type_prop_name(), [type_prop_value()],
+ proper_types:type()) -> proper_types:type().
+append_list_to_prop(PropName, List, {'$type',Props}) ->
+ {PropName, Val} = lists:keyfind(PropName, 1, Props),
+ {'$type', lists:keystore(PropName, 1, Props, {PropName, Val++List})}.
+
+%% @private
+-spec get_prop(type_prop_name(), proper_types:type()) -> type_prop_value().
+get_prop(PropName, {'$type',Props}) ->
+ {_PropName, Val} = lists:keyfind(PropName, 1, Props),
+ Val.
+
+%% @private
+-spec find_prop(type_prop_name(), proper_types:type()) ->
+ {'ok',type_prop_value()} | 'error'.
+find_prop(PropName, {'$type',Props}) ->
+ case lists:keyfind(PropName, 1, Props) of
+ {PropName, Value} ->
+ {ok, Value};
+ _ ->
+ error
+ end.
+
+%% @private
+-spec new_type([type_prop()], type_kind()) -> proper_types:type().
+new_type(PropList, Kind) ->
+ Type = type_from_list(PropList),
+ add_prop(kind, Kind, Type).
+
+%% @private
+-spec subtype([type_prop()], proper_types:type()) -> proper_types:type().
+%% TODO: should the 'is_instance' function etc. be reset for subtypes?
+subtype(PropList, Type) ->
+ add_props(PropList, Type).
+
+%% @private
+-spec is_inst(proper_gen:instance(), raw_type()) ->
+ boolean() | {'error',{'typeserver',term()}}.
+is_inst(Instance, RawType) ->
+ is_inst(Instance, RawType, 10).
+
+%% @private
+-spec is_inst(proper_gen:instance(), raw_type(), size()) ->
+ boolean() | {'error',{'typeserver',term()}}.
+is_inst(Instance, RawType, Size) ->
+ proper:global_state_init_size(Size),
+ Result = safe_is_instance(Instance, RawType),
+ proper:global_state_erase(),
+ Result.
+
+%% @private
+-spec safe_is_instance(proper_gen:imm_instance(), raw_type()) ->
+ boolean() | {'error',{'typeserver',term()}}.
+safe_is_instance(ImmInstance, RawType) ->
+ try is_instance(ImmInstance, RawType) catch
+ throw:{'$typeserver',SubReason} -> {error, {typeserver,SubReason}}
+ end.
+
+%% @private
+-spec is_instance(proper_gen:imm_instance(), raw_type()) -> boolean().
+%% TODO: If the second argument is not a type, let it pass (don't even check for
+%% term equality?) - if it's a raw type, don't cook it, instead recurse
+%% into it.
+is_instance(ImmInstance, RawType) ->
+ CleanInstance = proper_gen:clean_instance(ImmInstance),
+ Type = cook_outer(RawType),
+ (case get_prop(kind, Type) of
+ wrapper -> wrapper_test(ImmInstance, Type);
+ constructed -> constructed_test(ImmInstance, Type);
+ _ -> false
+ end
+ orelse
+ case find_prop(is_instance, Type) of
+ {ok,{typed, IsInstance}} -> IsInstance(Type, ImmInstance);
+ {ok,IsInstance} -> IsInstance(ImmInstance);
+ error -> false
+ end)
+ andalso weakly(satisfies_all(CleanInstance, Type)).
+
+-spec wrapper_test(proper_gen:imm_instance(), proper_types:type()) -> boolean().
+wrapper_test(ImmInstance, Type) ->
+ %% TODO: check if it's actually a raw type that's returned?
+ lists:any(fun(T) -> is_instance(ImmInstance, T) end, unwrap(Type)).
+
+%% @private
+%% TODO: restore:-spec unwrap(proper_types:type()) -> [proper_types:type(),...].
+%% TODO: check if it's actually a raw type that's returned?
+unwrap(Type) ->
+ RawInnerTypes = proper_gen:alt_gens(Type) ++ [proper_gen:normal_gen(Type)],
+ [cook_outer(T) || T <- RawInnerTypes].
+
+-spec constructed_test(proper_gen:imm_instance(), proper_types:type()) ->
+ boolean().
+constructed_test({'$used',ImmParts,ImmInstance}, Type) ->
+ PartsType = get_prop(parts_type, Type),
+ Combine = get_prop(combine, Type),
+ is_instance(ImmParts, PartsType) andalso
+ begin
+ %% TODO: check if it's actually a raw type that's returned?
+ %% TODO: move construction code to proper_gen
+ %% TODO: non-type => should we check for strict term equality?
+ RawInnerType = Combine(proper_gen:clean_instance(ImmParts)),
+ is_instance(ImmInstance, RawInnerType)
+ end;
+constructed_test({'$to_part',ImmInstance}, Type) ->
+ PartsType = get_prop(parts_type, Type),
+ get_prop(shrink_to_parts, Type) =:= true andalso
+ %% TODO: we reject non-container types
+ get_prop(kind, PartsType) =:= container andalso
+ case {find_prop(internal_type,PartsType),
+ find_prop(internal_types,PartsType)} of
+ {{ok,EachPartType},error} ->
+ %% The parts are in a list or a vector.
+ is_instance(ImmInstance, EachPartType);
+ {error,{ok,PartTypesList}} ->
+ %% The parts are in a fixed list.
+ %% TODO: It should always be a proper list.
+ lists:any(fun(T) -> is_instance(ImmInstance,T) end, PartTypesList)
+ end;
+constructed_test(_CleanInstance, _Type) ->
+ %% TODO: can we do anything better?
+ false.
+
+%% @private
+-spec weakly({boolean(),boolean()}) -> boolean().
+weakly({B1,_B2}) -> B1.
+
+%% @private
+-spec strongly({boolean(),boolean()}) -> boolean().
+strongly({_B1,B2}) -> B2.
+
+-spec satisfies(proper_gen:instance(), {constraint_fun(),boolean()})
+ -> {boolean(),boolean()}.
+satisfies(Instance, {Test,false}) ->
+ {true,Test(Instance)};
+satisfies(Instance, {Test,true}) ->
+ Result = Test(Instance),
+ {Result,Result}.
+
+%% @private
+-spec satisfies_all(proper_gen:instance(), proper_types:type()) ->
+ {boolean(),boolean()}.
+satisfies_all(Instance, Type) ->
+ case find_prop(constraints, Type) of
+ {ok, Constraints} ->
+ L = [satisfies(Instance, C) || C <- Constraints],
+ {L1,L2} = lists:unzip(L),
+ {lists:all(fun(B) -> B end, L1), lists:all(fun(B) -> B end, L2)};
+ error ->
+ {true,true}
+ end.
+
+
+%%------------------------------------------------------------------------------
+%% Type definition functions
+%%------------------------------------------------------------------------------
+
+%% @private
+-spec lazy(proper_gen:nosize_generator()) -> proper_types:type().
+lazy(Gen) ->
+ ?WRAPPER([
+ {generator, Gen}
+ ]).
+
+%% @private
+-spec sized(proper_gen:sized_generator()) -> proper_types:type().
+sized(Gen) ->
+ ?WRAPPER([
+ {generator, Gen}
+ ]).
+
+%% @private
+-spec bind(raw_type(), proper_gen:combine_fun(), boolean()) ->
+ proper_types:type().
+bind(RawPartsType, Combine, ShrinkToParts) ->
+ PartsType = cook_outer(RawPartsType),
+ ?CONSTRUCTED([
+ {parts_type, PartsType},
+ {combine, Combine},
+ {shrink_to_parts, ShrinkToParts}
+ ]).
+
+%% @private
+-spec shrinkwith(proper_gen:nosize_generator(), proper_gen:alt_gens()) ->
+ proper_types:type().
+shrinkwith(Gen, DelaydAltGens) ->
+ ?WRAPPER([
+ {generator, Gen},
+ {alt_gens, DelaydAltGens}
+ ]).
+
+%% @private
+-spec add_constraint(raw_type(), constraint_fun(), boolean()) ->
+ proper_types:type().
+add_constraint(RawType, Condition, IsStrict) ->
+ Type = cook_outer(RawType),
+ append_to_prop(constraints, {Condition,IsStrict}, Type).
+
+%% @private
+-spec native_type(mod_name(), string()) -> proper_types:type().
+native_type(Mod, TypeStr) ->
+ ?WRAPPER([
+ {generator, fun() -> proper_gen:native_type_gen(Mod,TypeStr) end}
+ ]).
+
+
+%%------------------------------------------------------------------------------
+%% Basic types
+%%------------------------------------------------------------------------------
+
+%% @doc All integers between `Low' and `High', bounds included.
+%% `Low' and `High' must be Erlang expressions that evaluate to integers, with
+%% `Low =< High'. Additionally, `Low' and `High' may have the value `inf', in
+%% which case they represent minus infinity and plus infinity respectively.
+%% Instances shrink towards 0 if `Low =< 0 =< High', or towards the bound with
+%% the smallest absolute value otherwise.
+-spec integer(extint(), extint()) -> proper_types:type().
+integer(Low, High) ->
+ ?BASIC([
+ {env, {Low, High}},
+ {generator, {typed, fun integer_gen/2}},
+ {is_instance, {typed, fun integer_is_instance/2}},
+ {shrinkers, [fun number_shrinker/3]}
+ ]).
+
+integer_gen(Type, Size) ->
+ {Low, High} = get_prop(env, Type),
+ proper_gen:integer_gen(Size, Low, High).
+
+integer_is_instance(Type, X) ->
+ {Low, High} = get_prop(env, Type),
+ is_integer(X) andalso le(Low, X) andalso le(X, High).
+
+number_shrinker(X, Type, S) ->
+ {Low, High} = get_prop(env, Type),
+ proper_shrink:number_shrinker(X, Low, High, S).
+
+%% @doc All floats between `Low' and `High', bounds included.
+%% `Low' and `High' must be Erlang expressions that evaluate to floats, with
+%% `Low =< High'. Additionally, `Low' and `High' may have the value `inf', in
+%% which case they represent minus infinity and plus infinity respectively.
+%% Instances shrink towards 0.0 if `Low =< 0.0 =< High', or towards the bound
+%% with the smallest absolute value otherwise.
+-spec float(extnum(), extnum()) -> proper_types:type().
+float(Low, High) ->
+ ?BASIC([
+ {env, {Low, High}},
+ {generator, {typed, fun float_gen/2}},
+ {is_instance, {typed, fun float_is_instance/2}},
+ {shrinkers, [fun number_shrinker/3]}
+ ]).
+
+float_gen(Type, Size) ->
+ {Low, High} = get_prop(env, Type),
+ proper_gen:float_gen(Size, Low, High).
+
+float_is_instance(Type, X) ->
+ {Low, High} = get_prop(env, Type),
+ is_float(X) andalso le(Low, X) andalso le(X, High).
+
+%% @private
+-spec le(extnum(), extnum()) -> boolean().
+le(inf, _B) -> true;
+le(_A, inf) -> true;
+le(A, B) -> A =< B.
+
+%% @doc All atoms. All atoms used internally by PropEr start with a '`$'', so
+%% such atoms will never be produced as instances of this type. You should also
+%% refrain from using such atoms in your code, to avoid a potential clash.
+%% Instances shrink towards the empty atom, ''.
+-spec atom() -> proper_types:type().
+atom() ->
+ ?WRAPPER([
+ {generator, fun proper_gen:atom_gen/1},
+ {reverse_gen, fun proper_gen:atom_rev/1},
+ {size_transform, fun(Size) -> erlang:min(Size,255) end},
+ {is_instance, fun atom_is_instance/1}
+ ]).
+
+atom_is_instance(X) ->
+ is_atom(X)
+ %% We return false for atoms starting with '$', since these are
+ %% atoms used internally and never produced by the atom generator.
+ andalso (X =:= '' orelse hd(atom_to_list(X)) =/= $$).
+
+%% @doc All binaries. Instances shrink towards the empty binary, `<<>>'.
+-spec binary() -> proper_types:type().
+binary() ->
+ ?WRAPPER([
+ {generator, fun proper_gen:binary_gen/1},
+ {reverse_gen, fun proper_gen:binary_rev/1},
+ {is_instance, fun erlang:is_binary/1}
+ ]).
+
+%% @doc All binaries with a byte size of `Len'.
+%% `Len' must be an Erlang expression that evaluates to a non-negative integer.
+%% Instances shrink towards binaries of zeroes.
+-spec binary(length()) -> proper_types:type().
+binary(Len) ->
+ ?WRAPPER([
+ {env, Len},
+ {generator, {typed, fun binary_len_gen/1}},
+ {reverse_gen, fun proper_gen:binary_rev/1},
+ {is_instance, {typed, fun binary_len_is_instance/2}}
+ ]).
+
+binary_len_gen(Type) ->
+ Len = get_prop(env, Type),
+ proper_gen:binary_len_gen(Len).
+
+binary_len_is_instance(Type, X) ->
+ Len = get_prop(env, Type),
+ is_binary(X) andalso byte_size(X) =:= Len.
+
+%% @doc All bitstrings. Instances shrink towards the empty bitstring, `<<>>'.
+-spec bitstring() -> proper_types:type().
+bitstring() ->
+ ?WRAPPER([
+ {generator, fun proper_gen:bitstring_gen/1},
+ {reverse_gen, fun proper_gen:bitstring_rev/1},
+ {is_instance, fun erlang:is_bitstring/1}
+ ]).
+
+%% @doc All bitstrings with a bit size of `Len'.
+%% `Len' must be an Erlang expression that evaluates to a non-negative integer.
+%% Instances shrink towards bitstrings of zeroes
+-spec bitstring(length()) -> proper_types:type().
+bitstring(Len) ->
+ ?WRAPPER([
+ {env, Len},
+ {generator, {typed, fun bitstring_len_gen/1}},
+ {reverse_gen, fun proper_gen:bitstring_rev/1},
+ {is_instance, {typed, fun bitstring_len_is_instance/2}}
+ ]).
+
+bitstring_len_gen(Type) ->
+ Len = get_prop(env, Type),
+ proper_gen:bitstring_len_gen(Len).
+
+bitstring_len_is_instance(Type, X) ->
+ Len = get_prop(env, Type),
+ is_bitstring(X) andalso bit_size(X) =:= Len.
+
+%% @doc All lists containing elements of type `ElemType'.
+%% Instances shrink towards the empty list, `[]'.
+-spec list(ElemType::raw_type()) -> proper_types:type().
+% TODO: subtyping would be useful here (list, vector, fixed_list)
+list(RawElemType) ->
+ ElemType = cook_outer(RawElemType),
+ ?CONTAINER([
+ {generator, {typed, fun list_gen/2}},
+ {is_instance, {typed, fun list_is_instance/2}},
+ {internal_type, ElemType},
+ {get_length, fun erlang:length/1},
+ {split, fun lists:split/2},
+ {join, fun lists:append/2},
+ {get_indices, fun list_get_indices/2},
+ {remove, fun proper_arith:list_remove/2},
+ {retrieve, fun lists:nth/2},
+ {update, fun proper_arith:list_update/3}
+ ]).
+
+list_gen(Type, Size) ->
+ ElemType = get_prop(internal_type, Type),
+ proper_gen:list_gen(Size, ElemType).
+
+list_is_instance(Type, X) ->
+ ElemType = get_prop(internal_type, Type),
+ list_test(X, ElemType).
+
+%% @doc A type that generates exactly the list `List'. Instances shrink towards
+%% shorter sublists of the original list.
+-spec shrink_list([term()]) -> proper_types:type().
+shrink_list(List) ->
+ ?CONTAINER([
+ {env, List},
+ {generator, {typed, fun shrink_list_gen/1}},
+ {is_instance, {typed, fun shrink_list_is_instance/2}},
+ {get_length, fun erlang:length/1},
+ {split, fun lists:split/2},
+ {join, fun lists:append/2},
+ {get_indices, fun list_get_indices/2},
+ {remove, fun proper_arith:list_remove/2}
+ ]).
+
+shrink_list_gen(Type) ->
+ get_prop(env, Type).
+
+shrink_list_is_instance(Type, X) ->
+ List = get_prop(env, Type),
+ is_sublist(X, List).
+
+-spec is_sublist([term()], [term()]) -> boolean().
+is_sublist([], _) -> true;
+is_sublist(_, []) -> false;
+is_sublist([H|T1], [H|T2]) -> is_sublist(T1, T2);
+is_sublist(Slice, [_|T2]) -> is_sublist(Slice, T2).
+
+-spec list_test(proper_gen:imm_instance(), proper_types:type()) -> boolean().
+list_test(X, ElemType) ->
+ is_list(X) andalso lists:all(fun(E) -> is_instance(E, ElemType) end, X).
+
+%% @private
+-spec list_get_indices(proper_gen:generator(), list()) -> [position()].
+list_get_indices(_, List) ->
+ lists:seq(1, length(List)).
+
+%% @private
+%% This assumes that:
+%% - instances of size S are always valid instances of size >S
+%% - any recursive calls inside Gen are lazy
+-spec distlist(size(), proper_gen:sized_generator(), boolean()) ->
+ proper_types:type().
+distlist(Size, Gen, NonEmpty) ->
+ ParentType = case NonEmpty of
+ true -> non_empty(list(Gen(Size)));
+ false -> list(Gen(Size))
+ end,
+ ?SUBTYPE(ParentType, [
+ {subenv, {Size, Gen, NonEmpty}},
+ {generator, {typed, fun distlist_gen/1}}
+ ]).
+
+distlist_gen(Type) ->
+ {Size, Gen, NonEmpty} = get_prop(subenv, Type),
+ proper_gen:distlist_gen(Size, Gen, NonEmpty).
+
+%% @doc All lists of length `Len' containing elements of type `ElemType'.
+%% `Len' must be an Erlang expression that evaluates to a non-negative integer.
+-spec vector(length(), ElemType::raw_type()) -> proper_types:type().
+vector(Len, RawElemType) ->
+ ElemType = cook_outer(RawElemType),
+ ?CONTAINER([
+ {env, Len},
+ {generator, {typed, fun vector_gen/1}},
+ {is_instance, {typed, fun vector_is_instance/2}},
+ {internal_type, ElemType},
+ {get_indices, fun vector_get_indices/2},
+ {retrieve, fun lists:nth/2},
+ {update, fun proper_arith:list_update/3}
+ ]).
+
+vector_gen(Type) ->
+ Len = get_prop(env, Type),
+ ElemType = get_prop(internal_type, Type),
+ proper_gen:vector_gen(Len, ElemType).
+
+vector_is_instance(Type, X) ->
+ Len = get_prop(env, Type),
+ ElemType = get_prop(internal_type, Type),
+ is_list(X)
+ andalso length(X) =:= Len
+ andalso lists:all(fun(E) -> is_instance(E, ElemType) end, X).
+
+vector_get_indices(Type, _X) ->
+ lists:seq(1, get_prop(env, Type)).
+
+%% @doc The union of all types in `ListOfTypes'. `ListOfTypes' can't be empty.
+%% The random instance generator is equally likely to choose any one of the
+%% types in `ListOfTypes'. The shrinking subsystem will always try to shrink an
+%% instance of a type union to an instance of the first type in `ListOfTypes',
+%% thus you should write the simplest case first.
+-spec union(ListOfTypes::[raw_type(),...]) -> proper_types:type().
+union(RawChoices) ->
+ Choices = [cook_outer(C) || C <- RawChoices],
+ ?BASIC([
+ {env, Choices},
+ {generator, {typed, fun union_gen/1}},
+ {is_instance, {typed, fun union_is_instance/2}},
+ {shrinkers, [fun union_shrinker_1/3, fun union_shrinker_2/3]}
+ ]).
+
+union_gen(Type) ->
+ Choices = get_prop(env,Type),
+ proper_gen:union_gen(Choices).
+
+union_is_instance(Type, X) ->
+ Choices = get_prop(env, Type),
+ lists:any(fun(C) -> is_instance(X, C) end, Choices).
+
+union_shrinker_1(X, Type, S) ->
+ Choices = get_prop(env, Type),
+ proper_shrink:union_first_choice_shrinker(X, Choices, S).
+
+union_shrinker_2(X, Type, S) ->
+ Choices = get_prop(env, Type),
+ proper_shrink:union_recursive_shrinker(X, Choices, S).
+
+%% @doc A specialization of {@link union/1}, where each type in `ListOfTypes' is
+%% assigned a frequency. Frequencies must be Erlang expressions that evaluate to
+%% positive integers. Types with larger frequencies are more likely to be chosen
+%% by the random instance generator. The shrinking subsystem will ignore the
+%% frequencies and try to shrink towards the first type in the list.
+-spec weighted_union(ListOfTypes::[{frequency(),raw_type()},...]) ->
+ proper_types:type().
+weighted_union(RawFreqChoices) ->
+ CookFreqType = fun({Freq,RawType}) -> {Freq,cook_outer(RawType)} end,
+ FreqChoices = lists:map(CookFreqType, RawFreqChoices),
+ Choices = [T || {_F,T} <- FreqChoices],
+ ?SUBTYPE(union(Choices), [
+ {subenv, FreqChoices},
+ {generator, {typed, fun weighted_union_gen/1}}
+ ]).
+
+weighted_union_gen(Gen) ->
+ FreqChoices = get_prop(subenv, Gen),
+ proper_gen:weighted_union_gen(FreqChoices).
+
+%% @private
+-spec safe_union([raw_type(),...]) -> proper_types:type().
+safe_union(RawChoices) ->
+ Choices = [cook_outer(C) || C <- RawChoices],
+ subtype(
+ [{subenv, Choices},
+ {generator, {typed, fun safe_union_gen/1}}],
+ union(Choices)).
+
+safe_union_gen(Type) ->
+ Choices = get_prop(subenv, Type),
+ proper_gen:safe_union_gen(Choices).
+
+%% @private
+-spec safe_weighted_union([{frequency(),raw_type()},...]) ->
+ proper_types:type().
+safe_weighted_union(RawFreqChoices) ->
+ CookFreqType = fun({Freq,RawType}) ->
+ {Freq,cook_outer(RawType)} end,
+ FreqChoices = lists:map(CookFreqType, RawFreqChoices),
+ Choices = [T || {_F,T} <- FreqChoices],
+ subtype([{subenv, FreqChoices},
+ {generator, {typed, fun safe_weighted_union_gen/1}}],
+ union(Choices)).
+
+safe_weighted_union_gen(Type) ->
+ FreqChoices = get_prop(subenv, Type),
+ proper_gen:safe_weighted_union_gen(FreqChoices).
+
+%% @doc All tuples whose i-th element is an instance of the type at index i of
+%% `ListOfTypes'. Also written simply as a tuple of types.
+-spec tuple(ListOfTypes::[raw_type()]) -> proper_types:type().
+tuple(RawFields) ->
+ Fields = [cook_outer(F) || F <- RawFields],
+ ?CONTAINER([
+ {env, Fields},
+ {generator, {typed, fun tuple_gen/1}},
+ {is_instance, {typed, fun tuple_is_instance/2}},
+ {internal_types, list_to_tuple(Fields)},
+ {get_indices, fun tuple_get_indices/2},
+ {retrieve, fun erlang:element/2},
+ {update, fun tuple_update/3}
+ ]).
+
+tuple_gen(Type) ->
+ Fields = get_prop(env, Type),
+ proper_gen:tuple_gen(Fields).
+
+tuple_is_instance(Type, X) ->
+ Fields = get_prop(env, Type),
+ is_tuple(X) andalso fixed_list_test(tuple_to_list(X), Fields).
+
+tuple_get_indices(Type, _X) ->
+ lists:seq(1, length(get_prop(env, Type))).
+
+-spec tuple_update(index(), value(), tuple()) -> tuple().
+tuple_update(Index, NewElem, Tuple) ->
+ setelement(Index, Tuple, NewElem).
+
+%% @doc Tuples whose elements are all of type `ElemType'.
+%% Instances shrink towards the 0-size tuple, `{}'.
+-spec loose_tuple(ElemType::raw_type()) -> proper_types:type().
+loose_tuple(RawElemType) ->
+ ElemType = cook_outer(RawElemType),
+ ?WRAPPER([
+ {env, ElemType},
+ {generator, {typed, fun loose_tuple_gen/2}},
+ {reverse_gen, {typed, fun loose_tuple_rev/2}},
+ {is_instance, {typed, fun loose_tuple_is_instance/2}}
+ ]).
+
+loose_tuple_gen(Type, Size) ->
+ ElemType = get_prop(env, Type),
+ proper_gen:loose_tuple_gen(Size, ElemType).
+
+loose_tuple_rev(Type, X) ->
+ ElemType = get_prop(env, Type),
+ proper_gen:loose_tuple_rev(X, ElemType).
+
+loose_tuple_is_instance(Type, X) ->
+ ElemType = get_prop(env, Type),
+ is_tuple(X) andalso list_test(tuple_to_list(X), ElemType).
+
+%% @doc Singleton type consisting only of `E'. `E' must be an evaluated term.
+%% Also written simply as `E'.
+-spec exactly(term()) -> proper_types:type().
+exactly(E) ->
+ ?BASIC([
+ {env, E},
+ {generator, {typed, fun exactly_gen/1}},
+ {is_instance, {typed, fun exactly_is_instance/2}}
+ ]).
+
+exactly_gen(Type) ->
+ E = get_prop(env, Type),
+ proper_gen:exactly_gen(E).
+
+exactly_is_instance(Type, X) ->
+ E = get_prop(env, Type),
+ X =:= E.
+
+%% @doc All lists whose i-th element is an instance of the type at index i of
+%% `ListOfTypes'. Also written simply as a list of types.
+-spec fixed_list(ListOfTypes::maybe_improper_list(raw_type(),raw_type()|[])) ->
+ proper_types:type().
+fixed_list(MaybeImproperRawFields) ->
+ %% CAUTION: must handle improper lists
+ {Fields, Internal, Len, Retrieve, Update} =
+ case proper_arith:cut_improper_tail(MaybeImproperRawFields) of
+ % TODO: have cut_improper_tail return the length and use it in test?
+ {ProperRawHead, ImproperRawTail} ->
+ HeadLen = length(ProperRawHead),
+ CookedHead = [cook_outer(F) || F <- ProperRawHead],
+ CookedTail = cook_outer(ImproperRawTail),
+ {{CookedHead,CookedTail},
+ CookedHead ++ CookedTail,
+ HeadLen + 1,
+ fun(I,L) -> improper_list_retrieve(I, L, HeadLen) end,
+ fun(I,V,L) -> improper_list_update(I, V, L, HeadLen) end};
+ ProperRawFields ->
+ LocalFields = [cook_outer(F) || F <- ProperRawFields],
+ {LocalFields,
+ LocalFields,
+ length(ProperRawFields),
+ fun lists:nth/2,
+ fun proper_arith:list_update/3}
+ end,
+ ?CONTAINER([
+ {env, {Fields, Len}},
+ {generator, {typed, fun fixed_list_gen/1}},
+ {is_instance, {typed, fun fixed_list_is_instance/2}},
+ {internal_types, Internal},
+ {get_indices, fun fixed_list_get_indices/2},
+ {retrieve, Retrieve},
+ {update, Update}
+ ]).
+
+fixed_list_gen(Type) ->
+ {Fields, _} = get_prop(env, Type),
+ proper_gen:fixed_list_gen(Fields).
+
+fixed_list_is_instance(Type, X) ->
+ {Fields, _} = get_prop(env, Type),
+ fixed_list_test(X, Fields).
+
+fixed_list_get_indices(Type, _X) ->
+ {_, Len} = get_prop(env, Type),
+ lists:seq(1, Len).
+
+-spec fixed_list_test(proper_gen:imm_instance(),
+ [proper_types:type()] | {[proper_types:type()],
+ proper_types:type()}) ->
+ boolean().
+fixed_list_test(X, {ProperHead,ImproperTail}) ->
+ is_list(X) andalso
+ begin
+ ProperHeadLen = length(ProperHead),
+ proper_arith:head_length(X) >= ProperHeadLen andalso
+ begin
+ {XHead,XTail} = lists:split(ProperHeadLen, X),
+ fixed_list_test(XHead, ProperHead)
+ andalso is_instance(XTail, ImproperTail)
+ end
+ end;
+fixed_list_test(X, ProperFields) ->
+ is_list(X)
+ andalso length(X) =:= length(ProperFields)
+ andalso lists:all(fun({E,T}) -> is_instance(E, T) end,
+ lists:zip(X, ProperFields)).
+
+%% TODO: Move these 2 functions to proper_arith?
+-spec improper_list_retrieve(index(), nonempty_improper_list(value(),value()),
+ pos_integer()) -> value().
+improper_list_retrieve(Index, List, HeadLen) ->
+ case Index =< HeadLen of
+ true -> lists:nth(Index, List);
+ false -> lists:nthtail(HeadLen, List)
+ end.
+
+-spec improper_list_update(index(), value(),
+ nonempty_improper_list(value(),value()),
+ pos_integer()) ->
+ nonempty_improper_list(value(),value()).
+improper_list_update(Index, Value, List, HeadLen) ->
+ case Index =< HeadLen of
+ %% TODO: This happens to work, but is not implied by list_update's spec.
+ true -> proper_arith:list_update(Index, Value, List);
+ false -> lists:sublist(List, HeadLen) ++ Value
+ end.
+
+%% @doc All pure functions that map instances of `ArgTypes' to instances of
+%% `RetType'. The syntax `function(Arity, RetType)' is also acceptable.
+-spec function(ArgTypes::[raw_type()] | arity(), RetType::raw_type()) ->
+ proper_types:type().
+function(Arity, RawRetType) when is_integer(Arity), Arity >= 0, Arity =< 255 ->
+ RetType = cook_outer(RawRetType),
+ ?BASIC([
+ {env, {Arity, RetType}},
+ {generator, {typed, fun function_gen/1}},
+ {is_instance, {typed, fun function_is_instance/2}}
+ ]);
+function(RawArgTypes, RawRetType) ->
+ function(length(RawArgTypes), RawRetType).
+
+function_gen(Type) ->
+ {Arity, RetType} = get_prop(env, Type),
+ proper_gen:function_gen(Arity, RetType).
+
+function_is_instance(Type, X) ->
+ {Arity, RetType} = get_prop(env, Type),
+ is_function(X, Arity)
+ %% TODO: what if it's not a function we produced?
+ andalso equal_types(RetType, proper_gen:get_ret_type(X)).
+
+%% @doc All Erlang terms (that PropEr can produce). For reasons of efficiency,
+%% functions are never produced as instances of this type.<br />
+%% CAUTION: Instances of this type are expensive to produce, shrink and instance-
+%% check, both in terms of processing time and consumed memory. Only use this
+%% type if you are certain that you need it.
+-spec any() -> proper_types:type().
+any() ->
+ AllTypes = [integer(),float(),atom(),bitstring(),?LAZY(loose_tuple(any())),
+ ?LAZY(list(any()))],
+ ?SUBTYPE(union(AllTypes), [
+ {generator, fun proper_gen:any_gen/1}
+ ]).
+
+
+%%------------------------------------------------------------------------------
+%% Type aliases
+%%------------------------------------------------------------------------------
+
+%% @equiv integer(inf, inf)
+-spec integer() -> proper_types:type().
+integer() -> integer(inf, inf).
+
+%% @equiv integer(0, inf)
+-spec non_neg_integer() -> proper_types:type().
+non_neg_integer() -> integer(0, inf).
+
+%% @equiv integer(1, inf)
+-spec pos_integer() -> proper_types:type().
+pos_integer() -> integer(1, inf).
+
+%% @equiv integer(inf, -1)
+-spec neg_integer() -> proper_types:type().
+neg_integer() -> integer(inf, -1).
+
+%% @equiv integer(Low, High)
+-spec range(extint(), extint()) -> proper_types:type().
+range(Low, High) -> integer(Low, High).
+
+%% @equiv float(inf, inf)
+-spec float() -> proper_types:type().
+float() -> float(inf, inf).
+
+%% @equiv float(0.0, inf)
+-spec non_neg_float() -> proper_types:type().
+non_neg_float() -> float(0.0, inf).
+
+%% @equiv union([integer(), float()])
+-spec number() -> proper_types:type().
+number() -> union([integer(), float()]).
+
+%% @doc The atoms `true' and `false'. Instances shrink towards `false'.
+-spec boolean() -> proper_types:type().
+boolean() -> union(['false', 'true']).
+
+%% @equiv integer(0, 255)
+-spec byte() -> proper_types:type().
+byte() -> integer(0, 255).
+
+%% @equiv integer(0, 16#10ffff)
+-spec char() -> proper_types:type().
+char() -> integer(0, 16#10ffff).
+
+%% @equiv list(any())
+-spec list() -> proper_types:type().
+list() -> list(any()).
+
+%% @equiv loose_tuple(any())
+-spec tuple() -> proper_types:type().
+tuple() -> loose_tuple(any()).
+
+%% @equiv list(char())
+-spec string() -> proper_types:type().
+string() -> list(char()).
+
+%% @equiv weighted_union(FreqChoices)
+-spec wunion([{frequency(),raw_type()},...]) -> proper_types:type().
+wunion(FreqChoices) -> weighted_union(FreqChoices).
+
+%% @equiv any()
+-spec term() -> proper_types:type().
+term() -> any().
+
+%% @equiv union([non_neg_integer() | infinity])
+-spec timeout() -> proper_types:type().
+timeout() -> union([non_neg_integer(), 'infinity']).
+
+%% @equiv integer(0, 255)
+-spec arity() -> proper_types:type().
+arity() -> integer(0, 255).
+
+
+%%------------------------------------------------------------------------------
+%% QuickCheck compatibility types
+%%------------------------------------------------------------------------------
+
+%% @doc Small integers (bound by the current value of the `size' parameter).
+%% Instances shrink towards `0'.
+-spec int() -> proper_types:type().
+int() -> ?SIZED(Size, integer(-Size,Size)).
+
+%% @doc Small non-negative integers (bound by the current value of the `size'
+%% parameter). Instances shrink towards `0'.
+-spec nat() -> proper_types:type().
+nat() -> ?SIZED(Size, integer(0,Size)).
+
+%% @equiv integer()
+-spec largeint() -> proper_types:type().
+largeint() -> integer().
+
+%% @equiv float()
+-spec real() -> proper_types:type().
+real() -> float().
+
+%% @equiv boolean()
+-spec bool() -> proper_types:type().
+bool() -> boolean().
+
+%% @equiv integer(Low, High)
+-spec choose(extint(), extint()) -> proper_types:type().
+choose(Low, High) -> integer(Low, High).
+
+%% @equiv union(Choices)
+-spec elements([raw_type(),...]) -> proper_types:type().
+elements(Choices) -> union(Choices).
+
+%% @equiv union(Choices)
+-spec oneof([raw_type(),...]) -> proper_types:type().
+oneof(Choices) -> union(Choices).
+
+%% @equiv weighted_union(Choices)
+-spec frequency([{frequency(),raw_type()},...]) -> proper_types:type().
+frequency(FreqChoices) -> weighted_union(FreqChoices).
+
+%% @equiv exactly(E)
+-spec return(term()) -> proper_types:type().
+return(E) -> exactly(E).
+
+%% @doc Adds a default value, `Default', to `Type'.
+%% The default serves as a primary shrinking target for instances, while it
+%% is also chosen by the random instance generation subsystem half the time.
+-spec default(raw_type(), raw_type()) -> proper_types:type().
+default(Default, Type) ->
+ union([Default, Type]).
+
+%% @doc All sorted lists containing elements of type `ElemType'.
+%% Instances shrink towards the empty list, `[]'.
+-spec orderedlist(ElemType::raw_type()) -> proper_types:type().
+orderedlist(RawElemType) ->
+ ?LET(L, list(RawElemType), lists:sort(L)).
+
+%% @equiv function(0, RetType)
+-spec function0(raw_type()) -> proper_types:type().
+function0(RetType) ->
+ function(0, RetType).
+
+%% @equiv function(1, RetType)
+-spec function1(raw_type()) -> proper_types:type().
+function1(RetType) ->
+ function(1, RetType).
+
+%% @equiv function(2, RetType)
+-spec function2(raw_type()) -> proper_types:type().
+function2(RetType) ->
+ function(2, RetType).
+
+%% @equiv function(3, RetType)
+-spec function3(raw_type()) -> proper_types:type().
+function3(RetType) ->
+ function(3, RetType).
+
+%% @equiv function(4, RetType)
+-spec function4(raw_type()) -> proper_types:type().
+function4(RetType) ->
+ function(4, RetType).
+
+%% @doc A specialization of {@link default/2}, where `Default' and `Type' are
+%% assigned weights to be considered by the random instance generator. The
+%% shrinking subsystem will ignore the weights and try to shrink using the
+%% default value.
+-spec weighted_default({frequency(),raw_type()}, {frequency(),raw_type()}) ->
+ proper_types:type().
+weighted_default(Default, Type) ->
+ weighted_union([Default, Type]).
+
+
+%%------------------------------------------------------------------------------
+%% Additional type specification functions
+%%------------------------------------------------------------------------------
+
+%% @doc Overrides the `size' parameter used when generating instances of
+%% `Type' with `NewSize'. Has no effect on size-less types, such as unions.
+%% Also, this will not affect the generation of any internal types contained in
+%% `Type', such as the elements of a list - those will still be generated
+%% using the test-wide value of `size'. One use of this function is to modify
+%% types to produce instances that grow faster or slower, like so:
+%% ```?SIZED(Size, resize(Size * 2, list(integer()))'''
+%% The above specifies a list type that grows twice as fast as normal lists.
+-spec resize(size(), Type::raw_type()) -> proper_types:type().
+resize(NewSize, RawType) ->
+ Type = cook_outer(RawType),
+ case find_prop(size_transform, Type) of
+ {ok,Transform} ->
+ add_prop(size_transform, fun(_S) -> Transform(NewSize) end, Type);
+ error ->
+ add_prop(size_transform, fun(_S) -> NewSize end, Type)
+ end.
+
+%% @doc This is a predefined constraint that can be applied to random-length
+%% list and binary types to ensure that the produced values are never empty.
+%%
+%% e.g. {@link list/0}, {@link string/0}, {@link binary/0})
+-spec non_empty(ListType::raw_type()) -> proper_types:type().
+non_empty(RawListType) ->
+ ?SUCHTHAT(L, RawListType, L =/= [] andalso L =/= <<>>).
+
+%% @doc Creates a new type which is equivalent to `Type', but whose instances
+%% are never shrunk by the shrinking subsystem.
+-spec noshrink(Type::raw_type()) -> proper_types:type().
+noshrink(RawType) ->
+ add_prop(noshrink, true, cook_outer(RawType)).
+
+%% @doc Associates the atom key `Parameter' with the value `Value' while
+%% generating instances of `Type'.
+-spec with_parameter(atom(), value(), Type::raw_type()) -> proper_types:type().
+with_parameter(Parameter, Value, RawType) ->
+ with_parameters([{Parameter,Value}], RawType).
+
+%% @doc Similar to {@link with_parameter/3}, but accepts a list of
+%% `{Parameter, Value}' pairs.
+-spec with_parameters([{atom(),value()}], Type::raw_type()) ->
+ proper_types:type().
+with_parameters(PVlist, RawType) ->
+ Type = cook_outer(RawType),
+ case find_prop(parameters, Type) of
+ {ok,Params} when is_list(Params) ->
+ append_list_to_prop(parameters, PVlist, Type);
+ error ->
+ add_prop(parameters, PVlist, Type)
+ end.
+
+%% @doc Returns the value associated with `Parameter', or `Default' in case
+%% `Parameter' is not associated with any value.
+-spec parameter(atom(), value()) -> value().
+parameter(Parameter, Default) ->
+ Parameters =
+ case erlang:get('$parameters') of
+ undefined -> [];
+ List -> List
+ end,
+ proplists:get_value(Parameter, Parameters, Default).
+
+%% @equiv parameter(Parameter, undefined)
+-spec parameter(atom()) -> value().
+parameter(Parameter) ->
+ parameter(Parameter, undefined).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl
new file mode 100644
index 0000000000..b6cab5e24b
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl
@@ -0,0 +1,2401 @@
+%%% Copyright 2010-2015 Manolis Papadakis <[email protected]>,
+%%% Eirini Arvaniti <[email protected]>
+%%% and Kostis Sagonas <[email protected]>
+%%%
+%%% This file is part of PropEr.
+%%%
+%%% PropEr is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% PropEr 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>.
+
+%%% @copyright 2010-2015 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
+%%% @version {@version}
+%%% @author Manolis Papadakis
+
+%%% @doc Erlang type system - PropEr type system integration module.
+%%%
+%%% PropEr can parse types expressed in Erlang's type language and convert them
+%%% to its own type format. Such expressions can be used instead of regular type
+%%% constructors in the second argument of `?FORALL's. No extra notation is
+%%% required; PropEr will detect which calls correspond to native types by
+%%% applying a parse transform during compilation. This parse transform is
+%%% automatically applied to any module that includes the `proper.hrl' header
+%%% file. You can disable this feature by compiling your modules with
+%%% `-DPROPER_NO_TRANS'. Note that this will currently also disable the
+%%% automatic exporting of properties.
+%%%
+%%% The use of native types in properties is subject to the following usage
+%%% rules:
+%%% <ul>
+%%% <li>Native types cannot be used outside of `?FORALL's.</li>
+%%% <li>Inside `?FORALL's, native types can be combined with other native
+%%% types, and even with PropEr types, inside tuples and lists (the constructs
+%%% `[...]', `{...}' and `++' are all allowed).</li>
+%%% <li>All other constructs of Erlang's built-in type system (e.g. `|' for
+%%% union, `_' as an alias of `any()', `<<_:_>>' binary type syntax and
+%%% `fun((...) -> ...)' function type syntax) are not allowed in `?FORALL's,
+%%% because they are rejected by the Erlang parser.</li>
+%%% <li>Anything other than a tuple constructor, list constructor, `++'
+%%% application, local or remote call will automatically be considered a
+%%% PropEr type constructor and not be processed further by the parse
+%%% transform.</li>
+%%% <li>Parametric native types are fully supported; of course, they can only
+%%% appear instantiated in a `?FORALL'. The arguments of parametric native
+%%% types are always interpreted as native types.</li>
+%%% <li>Parametric PropEr types, on the other hand, can take any kind of
+%%% argument. You can even mix native and PropEr types in the arguments of a
+%%% PropEr type. For example, assuming that the following declarations are
+%%% present:
+%%% ``` my_proper_type() -> ?LET(...).
+%%% -type my_native_type() :: ... .'''
+%%% Then the following expressions are all legal:
+%%% ``` vector(2, my_native_type())
+%%% function(0, my_native_type())
+%%% union([my_proper_type(), my_native_type()])''' </li>
+%%% <li>Some type constructors can take native types as arguments (but only
+%%% inside `?FORALL's):
+%%% <ul>
+%%% <li>`?SUCHTHAT', `?SUCHTHATMAYBE', `non_empty', `noshrink': these work
+%%% with native types too</li>
+%%% <li>`?LAZY', `?SHRINK', `resize', `?SIZED': these don't work with native
+%%% types</li>
+%%% <li>`?LET', `?LETSHRINK': only the top-level base type can be a native
+%%% type</li>
+%%% </ul></li>
+%%% <li>Native type declarations in the `?FORALL's of a module can reference any
+%%% custom type declared in a `-type' or `-opaque' attribute of the same
+%%% module, as long as no module identifier is used.</li>
+%%% <li>Typed records cannot be referenced inside `?FORALL's using the
+%%% `#rec_name{}' syntax. To use a typed record in a `?FORALL', enclose the
+%%% record in a custom type like so:
+%%% ``` -type rec_name() :: #rec_name{}. '''
+%%% and use the custom type instead.</li>
+%%% <li>`?FORALL's may contain references to self-recursive or mutually
+%%% recursive native types, so long as each type in the hierarchy has a clear
+%%% base case.
+%%% Currently, PropEr requires that the toplevel of any recursive type
+%%% declaration is either a (maybe empty) list or a union containing at least
+%%% one choice that doesn't reference the type directly (it may, however,
+%%% reference any of the types that are mutually recursive with it). This
+%%% means, for example, that some valid recursive type declarations, such as
+%%% this one:
+%%% ``` ?FORALL(..., a(), ...) '''
+%%% where:
+%%% ``` -type a() :: {'a','none' | a()}. '''
+%%% are not accepted by PropEr. However, such types can be rewritten in a way
+%%% that allows PropEr to parse them:
+%%% ``` ?FORALL(..., a(), ...) '''
+%%% where:
+%%% ``` -type a() :: {'a','none'} | {'a',a()}. '''
+%%% This also means that recursive record declarations are not allowed:
+%%% ``` ?FORALL(..., rec(), ...) '''
+%%% where:
+%%% ``` -type rec() :: #rec{}.
+%%% -record(rec, {a = 0 :: integer(), b = 'nil' :: 'nil' | #rec{}}). '''
+%%% A little rewritting can usually remedy this problem as well:
+%%% ``` ?FORALL(..., rec(), ...) '''
+%%% where:
+%%% ``` -type rec() :: #rec{b :: 'nil'} | #rec{b :: rec()}.
+%%% -record(rec, {a = 0 :: integer(), b = 'nil' :: 'nil' | #rec{}}). '''
+%%% </li>
+%%% <li>Remote types may be referenced in a `?FORALL', so long as they are
+%%% exported from the remote module. Currently, PropEr requires that any
+%%% remote modules whose types are directly referenced from within properties
+%%% are present in the code path at compile time, either compiled with
+%%% `debug_info' enabled or in source form. If PropEr cannot find a remote
+%%% module at all, finds only a compiled object file with no debug
+%%% information or fails to compile the source file, all calls to that module
+%%% will automatically be considered calls to PropEr type constructors.</li>
+%%% <li>For native types to be translated correctly, both the module that
+%%% contains the `?FORALL' declaration as well as any module that contains
+%%% the declaration of a type referenced (directly or indirectly) from inside
+%%% a `?FORALL' must be present in the code path at runtime, either compiled
+%%% with `debug_info' enabled or in source form.</li>
+%%% <li>Local types with the same name as an auto-imported BIF are not accepted
+%%% by PropEr, unless the BIF in question has been declared in a
+%%% `no_auto_import' option.</li>
+%%% <li>When an expression can be interpreted both as a PropEr type and as a
+%%% native type, the former takes precedence. This means that a function
+%%% `foo()' will shadow a type `foo()' if they are both present in the module.
+%%% The same rule applies to remote functions and types as well.</li>
+%%% <li>The above may cause some confusion when list syntax is used:
+%%% <ul>
+%%% <li>The expression `[integer()]' can be interpreted both ways, so the
+%%% PropEr way applies. Therefore, instances of this type will always be
+%%% lists of length 1, not arbitrary integer lists, as would be expected
+%%% when interpreting the expression as a native type.</li>
+%%% <li>Assuming that a custom type foo/1 has been declared, the expression
+%%% `foo([integer()])' can only be interpreted as a native type declaration,
+%%% which means that the generic type of integer lists will be passed to
+%%% `foo/1'.</li>
+%%% </ul></li>
+%%% <li>Currently, PropEr does not detect the following mistakes:
+%%% <ul>
+%%% <li>inline record-field specializations that reference non-existent
+%%% fields</li>
+%%% <li>type parameters that are not present in the RHS of a `-type'
+%%% declaration</li>
+%%% <li>using `_' as a type variable in the LHS of a `-type' declaration</li>
+%%% <li>using the same variable in more than one position in the LHS of a
+%%% `-type' declaration</li>
+%%% </ul>
+%%% </li>
+%%% </ul>
+%%%
+%%% You can use <a href="#index">these</a> functions to try out the type
+%%% translation subsystem.
+%%%
+%%% CAUTION: These functions should never be used inside properties. They are
+%%% meant for demonstration purposes only.
+
+-module(proper_typeserver).
+-behaviour(gen_server).
+-export([demo_translate_type/2, demo_is_instance/3]).
+
+-export([start/0, restart/0, stop/0, create_spec_test/3, get_exp_specced/1,
+ is_instance/3, translate_type/1]).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
+ code_change/3]).
+-export([get_exp_info/1, match/2]).
+
+-export_type([imm_type/0, mod_exp_types/0, mod_exp_funs/0]).
+
+-include("proper_internal.hrl").
+
+
+%%------------------------------------------------------------------------------
+%% Macros
+%%------------------------------------------------------------------------------
+
+-define(SRC_FILE_EXT, ".erl").
+
+%% CAUTION: all these must be sorted
+-define(STD_TYPES_0,
+ [any,arity,atom,binary,bitstring,bool,boolean,byte,char,float,integer,
+ list,neg_integer,non_neg_integer,number,pos_integer,string,term,
+ timeout]).
+-define(HARD_ADTS,
+ %% gb_trees:iterator and gb_sets:iterator are NOT hardcoded
+ [{{array,0},array}, {{array,1},proper_array},
+ {{dict,0},dict}, {{dict,2},proper_dict},
+ {{gb_set,0},gb_sets}, {{gb_set,1},proper_gb_sets},
+ {{gb_tree,0},gb_trees}, {{gb_tree,2},proper_gb_trees},
+ {{orddict,2},proper_orddict},
+ {{ordset,1},proper_ordsets},
+ {{queue,0},queue}, {{queue,1},proper_queue},
+ {{set,0},sets}, {{set,1},proper_sets}]).
+-define(HARD_ADT_MODS,
+ [{array, [{{array,0},
+ {{type,0,record,[{atom,0,array}]},[]}}]},
+ {dict, [{{dict,0},
+ {{type,0,record,[{atom,0,dict}]},[]}}]},
+ {gb_sets, [{{gb_set,0},
+ {{type,0,tuple,[{type,0,non_neg_integer,[]},
+ {type,0,gb_set_node,[]}]},[]}}]},
+ {gb_trees, [{{gb_tree,0},
+ {{type,0,tuple,[{type,0,non_neg_integer,[]},
+ {type,0,gb_tree_node,[]}]},[]}}]},
+ %% Our parametric ADTs are already declared as normal types, we just
+ %% need to change them to opaques.
+ {proper_array, [{{array,1},already_declared}]},
+ {proper_dict, [{{dict,2},already_declared}]},
+ {proper_gb_sets, [{{gb_set,1},already_declared},
+ {{iterator,1},already_declared}]},
+ {proper_gb_trees, [{{gb_tree,2},already_declared},
+ {{iterator,2},already_declared}]},
+ {proper_orddict, [{{orddict,2},already_declared}]},
+ {proper_ordsets, [{{ordset,1},already_declared}]},
+ {proper_queue, [{{queue,1},already_declared}]},
+ {proper_sets, [{{set,1},already_declared}]},
+ {queue, [{{queue,0},
+ {{type,0,tuple,[{type,0,list,[]},{type,0,list,[]}]},[]}}]},
+ {sets, [{{set,0},
+ {{type,0,record,[{atom,0,set}]},[]}}]}]).
+
+
+%%------------------------------------------------------------------------------
+%% Types
+%%------------------------------------------------------------------------------
+
+-type type_name() :: atom().
+-type var_name() :: atom(). %% TODO: also integers?
+-type field_name() :: atom().
+
+-type type_kind() :: 'type' | 'record'.
+-type type_ref() :: {type_kind(),type_name(),arity()}.
+-ifdef(NO_MODULES_IN_OPAQUES).
+-type substs_dict() :: dict(). %% dict(field_name(),ret_type())
+-else.
+-type substs_dict() :: dict:dict(field_name(),ret_type()).
+-endif.
+-type full_type_ref() :: {mod_name(),type_kind(),type_name(),
+ [ret_type()] | substs_dict()}.
+-type symb_info() :: 'not_symb' | {'orig_abs',abs_type()}.
+-type type_repr() :: {'abs_type',abs_type(),[var_name()],symb_info()}
+ | {'cached',fin_type(),abs_type(),symb_info()}
+ | {'abs_record',[{field_name(),abs_type()}]}.
+-type gen_fun() :: fun((size()) -> fin_type()).
+-type rec_fun() :: fun(([gen_fun()],size()) -> fin_type()).
+-type rec_arg() :: {boolean() | {'list',boolean(),rec_fun()},full_type_ref()}.
+-type rec_args() :: [rec_arg()].
+-type ret_type() :: {'simple',fin_type()} | {'rec',rec_fun(),rec_args()}.
+-type rec_fun_info() :: {pos_integer(),pos_integer(),[arity(),...],
+ [rec_fun(),...]}.
+
+-type imm_type_ref() :: {type_name(),arity()}.
+-type hard_adt_repr() :: {abs_type(),[var_name()]} | 'already_declared'.
+-type fun_ref() :: {fun_name(),arity()}.
+-type fun_repr() :: fun_clause_repr().
+-type fun_clause_repr() :: {[abs_type()],abs_type()}.
+-type proc_fun_ref() :: {fun_name(),[abs_type()],abs_type()}.
+-type full_imm_type_ref() :: {mod_name(),type_name(),arity()}.
+-type imm_stack() :: [full_imm_type_ref()].
+-type pat_field() :: 0 | 1 | atom().
+-type pattern() :: loose_tuple(pat_field()).
+-type next_step() :: 'none' | 'take_head' | {'match_with',pattern()}.
+
+-ifdef(NO_MODULES_IN_OPAQUES).
+%% @private_type
+-type mod_exp_types() :: set(). %% set(imm_type_ref())
+-type mod_types() :: dict(). %% dict(type_ref(),type_repr())
+%% @private_type
+-type mod_exp_funs() :: set(). %% set(fun_ref())
+-type mod_specs() :: dict(). %% dict(fun_ref(),fun_repr())
+-else.
+%% @private_type
+-type mod_exp_types() :: sets:set(imm_type_ref()).
+-type mod_types() :: dict:dict(type_ref(),type_repr()).
+%% @private_type
+-type mod_exp_funs() :: sets:set(fun_ref()).
+-type mod_specs() :: dict:dict(fun_ref(),fun_repr()).
+-endif.
+
+-ifdef(NO_MODULES_IN_OPAQUES).
+-record(state,
+ {cached = dict:new() :: dict(), %% dict(imm_type(),fin_type())
+ exp_types = dict:new() :: dict(), %% dict(mod_name(),mod_exp_types())
+ types = dict:new() :: dict(), %% dict(mod_name(),mod_types())
+ exp_specs = dict:new() :: dict()}). %% dict(mod_name(),mod_specs())
+-else.
+-record(state,
+ {cached = dict:new() :: dict:dict(), %% dict(imm_type(),fin_type())
+ exp_types = dict:new() :: dict:dict(), %% dict(mod_name(),mod_exp_types())
+ types = dict:new() :: dict:dict(), %% dict(mod_name(),mod_types())
+ exp_specs = dict:new() :: dict:dict()}). %% dict(mod_name(),mod_specs())
+%% {cached = dict:new() :: dict:dict(imm_type(),fin_type()),
+%% exp_types = dict:new() :: dict:dict(mod_name(),mod_exp_types()),
+%% types = dict:new() :: dict:dict(mod_name(),mod_types()),
+%% exp_specs = dict:new() :: dict:dict(mod_name(),mod_specs())}).
+-endif.
+-type state() :: #state{}.
+
+-record(mod_info,
+ {mod_exp_types = sets:new() :: mod_exp_types(),
+ mod_types = dict:new() :: mod_types(),
+ mod_opaques = sets:new() :: mod_exp_types(),
+ mod_exp_funs = sets:new() :: mod_exp_funs(),
+ mod_specs = dict:new() :: mod_specs()}).
+-type mod_info() :: #mod_info{}.
+
+-type stack() :: [full_type_ref() | 'tuple' | 'list' | 'union' | 'fun'].
+-ifdef(NO_MODULES_IN_OPAQUES).
+-type var_dict() :: dict(). %% dict(var_name(),ret_type())
+-else.
+-type var_dict() :: dict:dict(var_name(),ret_type()).
+-endif.
+%% @private_type
+-type imm_type() :: {mod_name(),string()}.
+%% @alias
+-type fin_type() :: proper_types:type().
+-type tagged_result(T) :: {'ok',T} | 'error'.
+-type tagged_result2(T,S) :: {'ok',T,S} | 'error'.
+%% @alias
+-type rich_result(T) :: {'ok',T} | {'error',term()}.
+-type rich_result2(T,S) :: {'ok',T,S} | {'error',term()}.
+-type false_positive_mfas() :: proper:false_positive_mfas().
+
+-type server_call() :: {'create_spec_test',mfa(),timeout(),false_positive_mfas()}
+ | {'get_exp_specced',mod_name()}
+ | {'get_type_repr',mod_name(),type_ref(),boolean()}
+ | {'translate_type',imm_type()}.
+-type server_response() :: rich_result(proper:test())
+ | rich_result([mfa()])
+ | rich_result(type_repr())
+ | rich_result(fin_type()).
+
+
+%%------------------------------------------------------------------------------
+%% Server interface functions
+%%------------------------------------------------------------------------------
+
+%% @private
+-spec start() -> 'ok'.
+start() ->
+ {ok,TypeserverPid} = gen_server:start_link(?MODULE, dummy, []),
+ put('$typeserver_pid', TypeserverPid),
+ ok.
+
+%% @private
+-spec restart() -> 'ok'.
+restart() ->
+ TypeserverPid = get('$typeserver_pid'),
+ case (TypeserverPid =:= undefined orelse not is_process_alive(TypeserverPid)) of
+ true -> start();
+ false -> ok
+ end.
+
+%% @private
+-spec stop() -> 'ok'.
+stop() ->
+ TypeserverPid = get('$typeserver_pid'),
+ erase('$typeserver_pid'),
+ gen_server:cast(TypeserverPid, stop).
+
+%% @private
+-spec create_spec_test(mfa(), timeout(), false_positive_mfas()) -> rich_result(proper:test()).
+create_spec_test(MFA, SpecTimeout, FalsePositiveMFAs) ->
+ TypeserverPid = get('$typeserver_pid'),
+ gen_server:call(TypeserverPid, {create_spec_test,MFA,SpecTimeout,FalsePositiveMFAs}).
+
+%% @private
+-spec get_exp_specced(mod_name()) -> rich_result([mfa()]).
+get_exp_specced(Mod) ->
+ TypeserverPid = get('$typeserver_pid'),
+ gen_server:call(TypeserverPid, {get_exp_specced,Mod}).
+
+-spec get_type_repr(mod_name(), type_ref(), boolean()) ->
+ rich_result(type_repr()).
+get_type_repr(Mod, TypeRef, IsRemote) ->
+ TypeserverPid = get('$typeserver_pid'),
+ gen_server:call(TypeserverPid, {get_type_repr,Mod,TypeRef,IsRemote}).
+
+%% @private
+-spec translate_type(imm_type()) -> rich_result(fin_type()).
+translate_type(ImmType) ->
+ TypeserverPid = get('$typeserver_pid'),
+ gen_server:call(TypeserverPid, {translate_type,ImmType}).
+
+%% @doc Translates the native type expression `TypeExpr' (which should be
+%% provided inside a string) into a PropEr type, which can then be passed to any
+%% of the demo functions defined in the {@link proper_gen} module. PropEr acts
+%% as if it found this type expression inside the code of module `Mod'.
+-spec demo_translate_type(mod_name(), string()) -> rich_result(fin_type()).
+demo_translate_type(Mod, TypeExpr) ->
+ start(),
+ Result = translate_type({Mod,TypeExpr}),
+ stop(),
+ Result.
+
+%% @doc Checks if `Term' is a valid instance of native type `TypeExpr' (which
+%% should be provided inside a string). PropEr acts as if it found this type
+%% expression inside the code of module `Mod'.
+-spec demo_is_instance(term(), mod_name(), string()) ->
+ boolean() | {'error',term()}.
+demo_is_instance(Term, Mod, TypeExpr) ->
+ case parse_type(TypeExpr) of
+ {ok,TypeForm} ->
+ start(),
+ Result =
+ %% Force the typeserver to load the module.
+ case translate_type({Mod,"integer()"}) of
+ {ok,_FinType} ->
+ try is_instance(Term, Mod, TypeForm)
+ catch
+ throw:{'$typeserver',Reason} -> {error, Reason}
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end,
+ stop(),
+ Result;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+
+%%------------------------------------------------------------------------------
+%% Implementation of gen_server interface
+%%------------------------------------------------------------------------------
+
+%% @private
+-spec init(_) -> {'ok',state()}.
+init(_) ->
+ {ok, #state{}}.
+
+%% @private
+-spec handle_call(server_call(), _, state()) ->
+ {'reply',server_response(),state()}.
+handle_call({create_spec_test,MFA,SpecTimeout,FalsePositiveMFAs}, _From, State) ->
+ case create_spec_test(MFA, SpecTimeout, FalsePositiveMFAs, State) of
+ {ok,Test,NewState} ->
+ {reply, {ok,Test}, NewState};
+ {error,_Reason} = Error ->
+ {reply, Error, State}
+ end;
+handle_call({get_exp_specced,Mod}, _From, State) ->
+ case get_exp_specced(Mod, State) of
+ {ok,MFAs,NewState} ->
+ {reply, {ok,MFAs}, NewState};
+ {error,_Reason} = Error ->
+ {reply, Error, State}
+ end;
+handle_call({get_type_repr,Mod,TypeRef,IsRemote}, _From, State) ->
+ case get_type_repr(Mod, TypeRef, IsRemote, State) of
+ {ok,TypeRepr,NewState} ->
+ {reply, {ok,TypeRepr}, NewState};
+ {error,_Reason} = Error ->
+ {reply, Error, State}
+ end;
+handle_call({translate_type,ImmType}, _From, State) ->
+ case translate_type(ImmType, State) of
+ {ok,FinType,NewState} ->
+ {reply, {ok,FinType}, NewState};
+ {error,_Reason} = Error ->
+ {reply, Error, State}
+ end.
+
+%% @private
+-spec handle_cast('stop', state()) -> {'stop','normal',state()}.
+handle_cast(stop, State) ->
+ {stop, normal, State}.
+
+%% @private
+-spec handle_info(term(), state()) -> {'stop',{'received_info',term()},state()}.
+handle_info(Info, State) ->
+ {stop, {received_info,Info}, State}.
+
+%% @private
+-spec terminate(term(), state()) -> 'ok'.
+terminate(_Reason, _State) ->
+ ok.
+
+%% @private
+-spec code_change(term(), state(), _) -> {'ok',state()}.
+code_change(_OldVsn, State, _) ->
+ {ok, State}.
+
+
+%%------------------------------------------------------------------------------
+%% Top-level interface
+%%------------------------------------------------------------------------------
+
+-spec create_spec_test(mfa(), timeout(), false_positive_mfas(), state()) ->
+ rich_result2(proper:test(),state()).
+create_spec_test(MFA, SpecTimeout, FalsePositiveMFAs, State) ->
+ case get_exp_spec(MFA, State) of
+ {ok,FunRepr,NewState} ->
+ make_spec_test(MFA, FunRepr, SpecTimeout, FalsePositiveMFAs, NewState);
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec get_exp_spec(mfa(), state()) -> rich_result2(fun_repr(),state()).
+get_exp_spec({Mod,Fun,Arity} = MFA, State) ->
+ case add_module(Mod, State) of
+ {ok,#state{exp_specs = ExpSpecs} = NewState} ->
+ ModExpSpecs = dict:fetch(Mod, ExpSpecs),
+ case dict:find({Fun,Arity}, ModExpSpecs) of
+ {ok,FunRepr} ->
+ {ok, FunRepr, NewState};
+ error ->
+ {error, {function_not_exported_or_specced,MFA}}
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec make_spec_test(mfa(), fun_repr(), timeout(), false_positive_mfas(), state()) ->
+ rich_result2(proper:test(),state()).
+make_spec_test({Mod,_Fun,_Arity}=MFA, {Domain,_Range}=FunRepr, SpecTimeout, FalsePositiveMFAs, State) ->
+ case convert(Mod, {type,0,'$fixed_list',Domain}, State) of
+ {ok,FinType,NewState} ->
+ Test = ?FORALL(Args, FinType, apply_spec_test(MFA, FunRepr, SpecTimeout, FalsePositiveMFAs, Args)),
+ {ok, Test, NewState};
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec apply_spec_test(mfa(), fun_repr(), timeout(), false_positive_mfas(), term()) -> proper:test().
+apply_spec_test({Mod,Fun,_Arity}=MFA, {_Domain,Range}, SpecTimeout, FalsePositiveMFAs, Args) ->
+ ?TIMEOUT(SpecTimeout,
+ begin
+ %% NOTE: only call apply/3 inside try/catch (do not trust ?MODULE:is_instance/3)
+ Result =
+ try apply(Mod,Fun,Args) of
+ X -> {ok, X}
+ catch
+ X:Y -> {X, Y}
+ end,
+ case Result of
+ {ok, Z} ->
+ case ?MODULE:is_instance(Z,Mod,Range) of
+ true ->
+ true;
+ false when is_function(FalsePositiveMFAs) ->
+ FalsePositiveMFAs(MFA, Args, {fail, Z});
+ false ->
+ false
+ end;
+ Exception when is_function(FalsePositiveMFAs) ->
+ case FalsePositiveMFAs(MFA, Args, Exception) of
+ true ->
+ true;
+ false ->
+ error(Exception, erlang:get_stacktrace())
+ end;
+ Exception ->
+ error(Exception, erlang:get_stacktrace())
+ end
+ end).
+
+-spec get_exp_specced(mod_name(), state()) -> rich_result2([mfa()],state()).
+get_exp_specced(Mod, State) ->
+ case add_module(Mod, State) of
+ {ok,#state{exp_specs = ExpSpecs} = NewState} ->
+ ModExpSpecs = dict:fetch(Mod, ExpSpecs),
+ ExpSpecced = [{Mod,F,A} || {F,A} <- dict:fetch_keys(ModExpSpecs)],
+ {ok, ExpSpecced, NewState};
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec get_type_repr(mod_name(), type_ref(), boolean(), state()) ->
+ rich_result2(type_repr(),state()).
+get_type_repr(Mod, {type,Name,Arity} = TypeRef, true, State) ->
+ case prepare_for_remote(Mod, Name, Arity, State) of
+ {ok,NewState} ->
+ get_type_repr(Mod, TypeRef, false, NewState);
+ {error,_Reason} = Error ->
+ Error
+ end;
+get_type_repr(Mod, TypeRef, false, #state{types = Types} = State) ->
+ ModTypes = dict:fetch(Mod, Types),
+ case dict:find(TypeRef, ModTypes) of
+ {ok,TypeRepr} ->
+ {ok, TypeRepr, State};
+ error ->
+ {error, {missing_type,Mod,TypeRef}}
+ end.
+
+-spec prepare_for_remote(mod_name(), type_name(), arity(), state()) ->
+ rich_result(state()).
+prepare_for_remote(RemMod, Name, Arity, State) ->
+ case add_module(RemMod, State) of
+ {ok,#state{exp_types = ExpTypes} = NewState} ->
+ RemModExpTypes = dict:fetch(RemMod, ExpTypes),
+ case sets:is_element({Name,Arity}, RemModExpTypes) of
+ true -> {ok, NewState};
+ false -> {error, {type_not_exported,{RemMod,Name,Arity}}}
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec translate_type(imm_type(), state()) -> rich_result2(fin_type(),state()).
+translate_type({Mod,Str} = ImmType, #state{cached = Cached} = State) ->
+ case dict:find(ImmType, Cached) of
+ {ok,Type} ->
+ {ok, Type, State};
+ error ->
+ case parse_type(Str) of
+ {ok,TypeForm} ->
+ case add_module(Mod, State) of
+ {ok,NewState} ->
+ case convert(Mod, TypeForm, NewState) of
+ {ok,FinType,
+ #state{cached = Cached} = FinalState} ->
+ NewCached = dict:store(ImmType, FinType,
+ Cached),
+ {ok, FinType,
+ FinalState#state{cached = NewCached}};
+ {error,_Reason} = Error ->
+ Error
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end;
+ {error,Reason} ->
+ {error, {parse_error,Str,Reason}}
+ end
+ end.
+
+-spec parse_type(string()) -> rich_result(abs_type()).
+parse_type(Str) ->
+ TypeStr = "-type mytype() :: " ++ Str ++ ".",
+ case erl_scan:string(TypeStr) of
+ {ok,Tokens,_EndLocation} ->
+ case erl_parse:parse_form(Tokens) of
+ {ok,{attribute,_Line,type,{mytype,TypeExpr,[]}}} ->
+ {ok, TypeExpr};
+ {error,_ErrorInfo} = Error ->
+ Error
+ end;
+ {error,ErrorInfo,_EndLocation} ->
+ {error, ErrorInfo}
+ end.
+
+-spec add_module(mod_name(), state()) -> rich_result(state()).
+add_module(Mod, #state{exp_types = ExpTypes} = State) ->
+ case dict:is_key(Mod, ExpTypes) of
+ true ->
+ {ok, State};
+ false ->
+ case get_code_and_exports(Mod) of
+ {ok,AbsCode,ModExpFuns} ->
+ RawModInfo = get_mod_info(Mod, AbsCode, ModExpFuns),
+ ModInfo = process_adts(Mod, RawModInfo),
+ {ok, store_mod_info(Mod,ModInfo,State)};
+ {error,Reason} ->
+ {error, {cant_load_code,Mod,Reason}}
+ end
+ end.
+
+%% @private
+-spec get_exp_info(mod_name()) -> rich_result2(mod_exp_types(),mod_exp_funs()).
+get_exp_info(Mod) ->
+ case get_code_and_exports(Mod) of
+ {ok,AbsCode,ModExpFuns} ->
+ RawModInfo = get_mod_info(Mod, AbsCode, ModExpFuns),
+ {ok, RawModInfo#mod_info.mod_exp_types, ModExpFuns};
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec get_code_and_exports(mod_name()) ->
+ rich_result2([abs_form()],mod_exp_funs()).
+get_code_and_exports(Mod) ->
+ case code:get_object_code(Mod) of
+ {Mod, ObjBin, _ObjFileName} ->
+ case get_chunks(ObjBin) of
+ {ok,_AbsCode,_ModExpFuns} = Result ->
+ Result;
+ {error,Reason} ->
+ get_code_and_exports_from_source(Mod, Reason)
+ end;
+ error ->
+ get_code_and_exports_from_source(Mod, cant_find_object_file)
+ end.
+
+-spec get_code_and_exports_from_source(mod_name(), term()) ->
+ rich_result2([abs_form()],mod_exp_funs()).
+get_code_and_exports_from_source(Mod, ObjError) ->
+ SrcFileName = atom_to_list(Mod) ++ ?SRC_FILE_EXT,
+ case code:where_is_file(SrcFileName) of
+ FullSrcFileName when is_list(FullSrcFileName) ->
+ Opts = [binary,debug_info,return_errors,{d,'PROPER_REMOVE_PROPS'}],
+ case compile:file(FullSrcFileName, Opts) of
+ {ok,Mod,Binary} ->
+ get_chunks(Binary);
+ {error,Errors,_Warnings} ->
+ {error, {ObjError,{cant_compile_source_file,Errors}}}
+ end;
+ non_existing ->
+ {error, {ObjError,cant_find_source_file}}
+ end.
+
+-spec get_chunks(string() | binary()) ->
+ rich_result2([abs_form()],mod_exp_funs()).
+get_chunks(ObjFile) ->
+ case beam_lib:chunks(ObjFile, [abstract_code,exports]) of
+ {ok,{_Mod,[{abstract_code,AbsCodeChunk},{exports,ExpFunsList}]}} ->
+ case AbsCodeChunk of
+ {raw_abstract_v1,AbsCode} ->
+ %% HACK: Add a declaration for iolist() to every module
+ {ok, add_iolist(AbsCode), sets:from_list(ExpFunsList)};
+ no_abstract_code ->
+ {error, no_abstract_code};
+ _ ->
+ {error, unsupported_abstract_code_format}
+ end;
+ {error,beam_lib,Reason} ->
+ {error, Reason}
+ end.
+
+-spec add_iolist([abs_form()]) -> [abs_form()].
+add_iolist(Forms) ->
+ IOListDef =
+ {type,0,maybe_improper_list,
+ [{type,0,union,[{type,0,byte,[]},{type,0,binary,[]},
+ {type,0,iolist,[]}]},
+ {type,0,binary,[]}]},
+ IOListDecl = {attribute,0,type,{iolist,IOListDef,[]}},
+ [IOListDecl | Forms].
+
+-spec get_mod_info(mod_name(), [abs_form()], mod_exp_funs()) -> mod_info().
+get_mod_info(Mod, AbsCode, ModExpFuns) ->
+ StartModInfo = #mod_info{mod_exp_funs = ModExpFuns},
+ ImmModInfo = lists:foldl(fun add_mod_info/2, StartModInfo, AbsCode),
+ #mod_info{mod_specs = AllModSpecs} = ImmModInfo,
+ IsExported = fun(FunRef,_FunRepr) -> sets:is_element(FunRef,ModExpFuns) end,
+ ModExpSpecs = dict:filter(IsExported, AllModSpecs),
+ ModInfo = ImmModInfo#mod_info{mod_specs = ModExpSpecs},
+ case orddict:find(Mod, ?HARD_ADT_MODS) of
+ {ok,ModADTs} ->
+ #mod_info{mod_exp_types = ModExpTypes, mod_types = ModTypes,
+ mod_opaques = ModOpaques} = ModInfo,
+ ModADTsSet =
+ sets:from_list([ImmTypeRef
+ || {ImmTypeRef,_HardADTRepr} <- ModADTs]),
+ NewModExpTypes = sets:union(ModExpTypes, ModADTsSet),
+ NewModTypes = lists:foldl(fun store_hard_adt/2, ModTypes, ModADTs),
+ NewModOpaques = sets:union(ModOpaques, ModADTsSet),
+ ModInfo#mod_info{mod_exp_types = NewModExpTypes,
+ mod_types = NewModTypes,
+ mod_opaques = NewModOpaques};
+ error ->
+ ModInfo
+ end.
+
+-spec store_hard_adt({imm_type_ref(),hard_adt_repr()}, mod_types()) ->
+ mod_types().
+store_hard_adt({_ImmTypeRef,already_declared}, ModTypes) ->
+ ModTypes;
+store_hard_adt({{Name,Arity},{TypeForm,VarNames}}, ModTypes) ->
+ TypeRef = {type,Name,Arity},
+ TypeRepr = {abs_type,TypeForm,VarNames,not_symb},
+ dict:store(TypeRef, TypeRepr, ModTypes).
+
+-spec add_mod_info(abs_form(), mod_info()) -> mod_info().
+add_mod_info({attribute,_Line,export_type,TypesList},
+ #mod_info{mod_exp_types = ModExpTypes} = ModInfo) ->
+ NewModExpTypes = sets:union(sets:from_list(TypesList), ModExpTypes),
+ ModInfo#mod_info{mod_exp_types = NewModExpTypes};
+add_mod_info({attribute,_Line,type,{{record,RecName},Fields,[]}},
+ #mod_info{mod_types = ModTypes} = ModInfo) ->
+ FieldInfo = [process_rec_field(F) || F <- Fields],
+ NewModTypes = dict:store({record,RecName,0}, {abs_record,FieldInfo},
+ ModTypes),
+ ModInfo#mod_info{mod_types = NewModTypes};
+add_mod_info({attribute,_Line,record,{RecName,Fields}},
+ #mod_info{mod_types = ModTypes} = ModInfo) ->
+ case dict:is_key(RecName, ModTypes) of
+ true ->
+ ModInfo;
+ false ->
+ TypedRecord = {attribute,0,type,{{record,RecName},Fields,[]}},
+ add_mod_info(TypedRecord, ModInfo)
+ end;
+add_mod_info({attribute,_Line,Kind,{Name,TypeForm,VarForms}},
+ #mod_info{mod_types = ModTypes,
+ mod_opaques = ModOpaques} = ModInfo)
+ when Kind =:= type; Kind =:= opaque ->
+ Arity = length(VarForms),
+ VarNames = [V || {var,_,V} <- VarForms],
+ %% TODO: No check whether variables are different, or non-'_'.
+ NewModTypes = dict:store({type,Name,Arity},
+ {abs_type,TypeForm,VarNames,not_symb}, ModTypes),
+ NewModOpaques =
+ case Kind of
+ type -> ModOpaques;
+ opaque -> sets:add_element({Name,Arity}, ModOpaques)
+ end,
+ ModInfo#mod_info{mod_types = NewModTypes, mod_opaques = NewModOpaques};
+add_mod_info({attribute,_Line,spec,{RawFunRef,[RawFirstClause | _Rest]}},
+ #mod_info{mod_specs = ModSpecs} = ModInfo) ->
+ FunRef = case RawFunRef of
+ {_Mod,Name,Arity} -> {Name,Arity};
+ {_Name,_Arity} = F -> F
+ end,
+ %% TODO: We just take the first function clause.
+ FirstClause = process_fun_clause(RawFirstClause),
+ NewModSpecs = dict:store(FunRef, FirstClause, ModSpecs),
+ ModInfo#mod_info{mod_specs = NewModSpecs};
+add_mod_info(_Form, ModInfo) ->
+ ModInfo.
+
+-spec process_rec_field(abs_rec_field()) -> {field_name(),abs_type()}.
+process_rec_field({record_field,_,{atom,_,FieldName}}) ->
+ {FieldName, {type,0,any,[]}};
+process_rec_field({record_field,_,{atom,_,FieldName},_Initialization}) ->
+ {FieldName, {type,0,any,[]}};
+process_rec_field({typed_record_field,RecField,FieldType}) ->
+ {FieldName,_} = process_rec_field(RecField),
+ {FieldName, FieldType}.
+
+-spec process_fun_clause(abs_type()) -> fun_clause_repr().
+process_fun_clause({type,_,'fun',[{type,_,product,Domain},Range]}) ->
+ {Domain, Range};
+process_fun_clause({type,_,bounded_fun,[MainClause,Constraints]}) ->
+ {RawDomain,RawRange} = process_fun_clause(MainClause),
+ VarSubsts = [{V,T} || {type,_,constraint,
+ [{atom,_,is_subtype},[{var,_,V},T]]} <- Constraints,
+ V =/= '_'],
+ VarSubstsDict = dict:from_list(VarSubsts),
+ Domain = [update_vars(A, VarSubstsDict, false) || A <- RawDomain],
+ Range = update_vars(RawRange, VarSubstsDict, false),
+ {Domain, Range}.
+
+-spec store_mod_info(mod_name(), mod_info(), state()) -> state().
+store_mod_info(Mod, #mod_info{mod_exp_types = ModExpTypes, mod_types = ModTypes,
+ mod_specs = ImmModExpSpecs},
+ #state{exp_types = ExpTypes, types = Types,
+ exp_specs = ExpSpecs} = State) ->
+ NewExpTypes = dict:store(Mod, ModExpTypes, ExpTypes),
+ NewTypes = dict:store(Mod, ModTypes, Types),
+ ModExpSpecs = dict:map(fun unbound_to_any/2, ImmModExpSpecs),
+ NewExpSpecs = dict:store(Mod, ModExpSpecs, ExpSpecs),
+ State#state{exp_types = NewExpTypes, types = NewTypes,
+ exp_specs = NewExpSpecs}.
+
+-spec unbound_to_any(fun_ref(), fun_repr()) -> fun_repr().
+unbound_to_any(_FunRef, {Domain,Range}) ->
+ EmptySubstsDict = dict:new(),
+ NewDomain = [update_vars(A,EmptySubstsDict,true) || A <- Domain],
+ NewRange = update_vars(Range, EmptySubstsDict, true),
+ {NewDomain, NewRange}.
+
+
+%%------------------------------------------------------------------------------
+%% ADT translation functions
+%%------------------------------------------------------------------------------
+
+-spec process_adts(mod_name(), mod_info()) -> mod_info().
+process_adts(Mod,
+ #mod_info{mod_exp_types = ModExpTypes, mod_opaques = ModOpaques,
+ mod_specs = ModExpSpecs} = ModInfo) ->
+ %% TODO: No warning on unexported opaques.
+ case sets:to_list(sets:intersection(ModExpTypes,ModOpaques)) of
+ [] ->
+ ModInfo;
+ ModADTs ->
+ %% TODO: No warning on unexported API functions.
+ ModExpSpecsList = [{Name,Domain,Range}
+ || {{Name,_Arity},{Domain,Range}}
+ <- dict:to_list(ModExpSpecs)],
+ AddADT = fun(ADT,Acc) -> add_adt(Mod,ADT,Acc,ModExpSpecsList) end,
+ lists:foldl(AddADT, ModInfo, ModADTs)
+ end.
+
+-spec add_adt(mod_name(), imm_type_ref(), mod_info(), [proc_fun_ref()]) ->
+ mod_info().
+add_adt(Mod, {Name,Arity}, #mod_info{mod_types = ModTypes} = ModInfo,
+ ModExpFunSpecs) ->
+ ADTRef = {type,Name,Arity},
+ {abs_type,InternalRepr,VarNames,not_symb} = dict:fetch(ADTRef, ModTypes),
+ FullADTRef = {Mod,Name,Arity},
+ %% TODO: No warning on unsuitable range.
+ SymbCalls1 = [get_symb_call(FullADTRef,Spec) || Spec <- ModExpFunSpecs],
+ %% TODO: No warning on bad use of variables.
+ SymbCalls2 = [fix_vars(FullADTRef,Call,RangeVars,VarNames)
+ || {ok,Call,RangeVars} <- SymbCalls1],
+ case [Call || {ok,Call} <- SymbCalls2] of
+ [] ->
+ %% TODO: No warning on no acceptable spec.
+ ModInfo;
+ SymbCalls3 ->
+ NewADTRepr = {abs_type,{type,0,union,SymbCalls3},VarNames,
+ {orig_abs,InternalRepr}},
+ NewModTypes = dict:store(ADTRef, NewADTRepr, ModTypes),
+ ModInfo#mod_info{mod_types = NewModTypes}
+ end.
+
+-spec get_symb_call(full_imm_type_ref(), proc_fun_ref()) ->
+ tagged_result2(abs_type(),[var_name()]).
+get_symb_call({Mod,_TypeName,_Arity} = FullADTRef, {FunName,Domain,Range}) ->
+ BaseCall = {type,0,tuple,[{atom,0,'$call'},{atom,0,Mod},{atom,0,FunName},
+ {type,0,'$fixed_list',Domain}]},
+ unwrap_range(FullADTRef, BaseCall, Range, false).
+
+-spec unwrap_range(full_imm_type_ref(), abs_type() | next_step(), abs_type(),
+ boolean()) ->
+ tagged_result2(abs_type() | next_step(),[var_name()]).
+unwrap_range(FullADTRef, Call, {paren_type,_,[Type]}, TestRun) ->
+ unwrap_range(FullADTRef, Call, Type, TestRun);
+unwrap_range(FullADTRef, Call, {ann_type,_,[_Var,Type]}, TestRun) ->
+ unwrap_range(FullADTRef, Call, Type, TestRun);
+unwrap_range(FullADTRef, Call, {type,_,list,[ElemType]}, TestRun) ->
+ unwrap_list(FullADTRef, Call, ElemType, TestRun);
+unwrap_range(FullADTRef, Call, {type,_,maybe_improper_list,[Cont,_Term]},
+ TestRun) ->
+ unwrap_list(FullADTRef, Call, Cont, TestRun);
+unwrap_range(FullADTRef, Call, {type,_,nonempty_list,[ElemType]}, TestRun) ->
+ unwrap_list(FullADTRef, Call, ElemType, TestRun);
+unwrap_range(FullADTRef, Call, {type,_,nonempty_improper_list,[Cont,_Term]},
+ TestRun) ->
+ unwrap_list(FullADTRef, Call, Cont, TestRun);
+unwrap_range(FullADTRef, Call,
+ {type,_,nonempty_maybe_improper_list,[Cont,_Term]}, TestRun) ->
+ unwrap_list(FullADTRef, Call, Cont, TestRun);
+unwrap_range(_FullADTRef, _Call, {type,_,tuple,any}, _TestRun) ->
+ error;
+unwrap_range(FullADTRef, Call, {type,_,tuple,FieldForms}, TestRun) ->
+ Translates = fun(T) -> unwrap_range(FullADTRef,none,T,true) =/= error end,
+ case proper_arith:find_first(Translates, FieldForms) of
+ none ->
+ error;
+ {TargetPos,TargetElem} ->
+ Pattern = get_pattern(TargetPos, FieldForms),
+ case TestRun of
+ true ->
+ NewCall =
+ case Call of
+ none -> {match_with,Pattern};
+ _ -> Call
+ end,
+ {ok, NewCall, []};
+ false ->
+ AbsPattern = term_to_singleton_type(Pattern),
+ NewCall =
+ {type,0,tuple,
+ [{atom,0,'$call'},{atom,0,?MODULE},{atom,0,match},
+ {type,0,'$fixed_list',[AbsPattern,Call]}]},
+ unwrap_range(FullADTRef, NewCall, TargetElem, TestRun)
+ end
+ end;
+unwrap_range(FullADTRef, Call, {type,_,union,Choices}, TestRun) ->
+ TestedChoices = [unwrap_range(FullADTRef,none,C,true) || C <- Choices],
+ NotError = fun(error) -> false; (_) -> true end,
+ case proper_arith:find_first(NotError, TestedChoices) of
+ none ->
+ error;
+ {_ChoicePos,{ok,none,_RangeVars}} ->
+ error;
+ {ChoicePos,{ok,NextStep,_RangeVars}} ->
+ {A, [ChoiceElem|B]} = lists:split(ChoicePos-1, Choices),
+ OtherChoices = A ++ B,
+ DistinctChoice =
+ case NextStep of
+ take_head ->
+ fun cant_have_head/1;
+ {match_with,Pattern} ->
+ fun(C) -> cant_match(Pattern, C) end
+ end,
+ case {lists:all(DistinctChoice,OtherChoices), TestRun} of
+ {true,true} ->
+ {ok, NextStep, []};
+ {true,false} ->
+ unwrap_range(FullADTRef, Call, ChoiceElem, TestRun);
+ {false,_} ->
+ error
+ end
+ end;
+unwrap_range({_Mod,SameName,Arity}, Call, {type,_,SameName,ArgForms},
+ _TestRun) ->
+ RangeVars = [V || {var,_,V} <- ArgForms, V =/= '_'],
+ case length(ArgForms) =:= Arity andalso length(RangeVars) =:= Arity of
+ true -> {ok, Call, RangeVars};
+ false -> error
+ end;
+unwrap_range({SameMod,SameName,_Arity} = FullADTRef, Call,
+ {remote_type,_,[{atom,_,SameMod},{atom,_,SameName},ArgForms]},
+ TestRun) ->
+ unwrap_range(FullADTRef, Call, {type,0,SameName,ArgForms}, TestRun);
+unwrap_range(_FullADTRef, _Call, _Range, _TestRun) ->
+ error.
+
+-spec unwrap_list(full_imm_type_ref(), abs_type() | next_step(), abs_type(),
+ boolean()) ->
+ tagged_result2(abs_type() | next_step(),[var_name()]).
+unwrap_list(FullADTRef, Call, HeadType, TestRun) ->
+ NewCall =
+ case TestRun of
+ true ->
+ case Call of
+ none -> take_head;
+ _ -> Call
+ end;
+ false ->
+ {type,0,tuple,[{atom,0,'$call'},{atom,0,erlang},{atom,0,hd},
+ {type,0,'$fixed_list',[Call]}]}
+ end,
+ unwrap_range(FullADTRef, NewCall, HeadType, TestRun).
+
+-spec fix_vars(full_imm_type_ref(), abs_type(), [var_name()], [var_name()]) ->
+ tagged_result(abs_type()).
+fix_vars(FullADTRef, Call, RangeVars, VarNames) ->
+ NotAnyVar = fun(V) -> V =/= '_' end,
+ case no_duplicates(VarNames) andalso lists:all(NotAnyVar,VarNames) of
+ true ->
+ RawUsedVars =
+ collect_vars(FullADTRef, Call, [[V] || V <- RangeVars]),
+ UsedVars = [lists:usort(L) || L <- RawUsedVars],
+ case correct_var_use(UsedVars) of
+ true ->
+ PairAll = fun(L,Y) -> [{X,{var,0,Y}} || X <- L] end,
+ VarSubsts =
+ lists:flatten(lists:zipwith(PairAll,UsedVars,VarNames)),
+ VarSubstsDict = dict:from_list(VarSubsts),
+ {ok, update_vars(Call,VarSubstsDict,true)};
+ false ->
+ error
+ end;
+ false ->
+ error
+ end.
+
+-spec no_duplicates(list()) -> boolean().
+no_duplicates(L) ->
+ length(lists:usort(L)) =:= length(L).
+
+-spec correct_var_use([[var_name() | 0]]) -> boolean().
+correct_var_use(UsedVars) ->
+ NoNonVarArgs = fun([0|_]) -> false; (_) -> true end,
+ lists:all(NoNonVarArgs, UsedVars)
+ andalso no_duplicates(lists:flatten(UsedVars)).
+
+-spec collect_vars(full_imm_type_ref(), abs_type(), [[var_name() | 0]]) ->
+ [[var_name() | 0]].
+collect_vars(FullADTRef, {paren_type,_,[Type]}, UsedVars) ->
+ collect_vars(FullADTRef, Type, UsedVars);
+collect_vars(FullADTRef, {ann_type,_,[_Var,Type]}, UsedVars) ->
+ collect_vars(FullADTRef, Type, UsedVars);
+collect_vars(_FullADTRef, {type,_,tuple,any}, UsedVars) ->
+ UsedVars;
+collect_vars({_Mod,SameName,Arity} = FullADTRef, {type,_,SameName,ArgForms},
+ UsedVars) ->
+ case length(ArgForms) =:= Arity of
+ true ->
+ VarArgs = [V || {var,_,V} <- ArgForms, V =/= '_'],
+ case length(VarArgs) =:= Arity of
+ true ->
+ AddToList = fun(X,L) -> [X | L] end,
+ lists:zipwith(AddToList, VarArgs, UsedVars);
+ false ->
+ [[0|L] || L <- UsedVars]
+ end;
+ false ->
+ multi_collect_vars(FullADTRef, ArgForms, UsedVars)
+ end;
+collect_vars(FullADTRef, {type,_,_Name,ArgForms}, UsedVars) ->
+ multi_collect_vars(FullADTRef, ArgForms, UsedVars);
+collect_vars({SameMod,SameName,_Arity} = FullADTRef,
+ {remote_type,_,[{atom,_,SameMod},{atom,_,SameName},ArgForms]},
+ UsedVars) ->
+ collect_vars(FullADTRef, {type,0,SameName,ArgForms}, UsedVars);
+collect_vars(FullADTRef, {remote_type,_,[_RemModForm,_NameForm,ArgForms]},
+ UsedVars) ->
+ multi_collect_vars(FullADTRef, ArgForms, UsedVars);
+collect_vars(_FullADTRef, _Call, UsedVars) ->
+ UsedVars.
+
+-spec multi_collect_vars(full_imm_type_ref(), [abs_type()],
+ [[var_name() | 0]]) -> [[var_name() | 0]].
+multi_collect_vars({_Mod,_Name,Arity} = FullADTRef, Forms, UsedVars) ->
+ NoUsedVars = lists:duplicate(Arity, []),
+ MoreUsedVars = [collect_vars(FullADTRef,T,NoUsedVars) || T <- Forms],
+ CombineVars = fun(L1,L2) -> lists:zipwith(fun erlang:'++'/2, L1, L2) end,
+ lists:foldl(CombineVars, UsedVars, MoreUsedVars).
+
+-ifdef(NO_MODULES_IN_OPAQUES).
+-type var_substs_dict() :: dict().
+-else.
+-type var_substs_dict() :: dict:dict(var_name(),abs_type()).
+-endif.
+-spec update_vars(abs_type(), var_substs_dict(), boolean()) -> abs_type().
+update_vars({paren_type,Line,[Type]}, VarSubstsDict, UnboundToAny) ->
+ {paren_type, Line, [update_vars(Type,VarSubstsDict,UnboundToAny)]};
+update_vars({ann_type,Line,[Var,Type]}, VarSubstsDict, UnboundToAny) ->
+ {ann_type, Line, [Var,update_vars(Type,VarSubstsDict,UnboundToAny)]};
+update_vars({var,Line,VarName} = Call, VarSubstsDict, UnboundToAny) ->
+ case dict:find(VarName, VarSubstsDict) of
+ {ok,SubstType} ->
+ SubstType;
+ error when UnboundToAny =:= false ->
+ Call;
+ error when UnboundToAny =:= true ->
+ {type,Line,any,[]}
+ end;
+update_vars({remote_type,Line,[RemModForm,NameForm,ArgForms]}, VarSubstsDict,
+ UnboundToAny) ->
+ NewArgForms = [update_vars(A,VarSubstsDict,UnboundToAny) || A <- ArgForms],
+ {remote_type, Line, [RemModForm,NameForm,NewArgForms]};
+update_vars({type,_,tuple,any} = Call, _VarSubstsDict, _UnboundToAny) ->
+ Call;
+update_vars({type,Line,Name,ArgForms}, VarSubstsDict, UnboundToAny) ->
+ {type, Line, Name, [update_vars(A,VarSubstsDict,UnboundToAny)
+ || A <- ArgForms]};
+update_vars(Call, _VarSubstsDict, _UnboundToAny) ->
+ Call.
+
+
+%%------------------------------------------------------------------------------
+%% Match-related functions
+%%------------------------------------------------------------------------------
+
+-spec get_pattern(position(), [abs_type()]) -> pattern().
+get_pattern(TargetPos, FieldForms) ->
+ {0,RevPattern} = lists:foldl(fun add_field/2, {TargetPos,[]}, FieldForms),
+ list_to_tuple(lists:reverse(RevPattern)).
+
+-spec add_field(abs_type(), {non_neg_integer(),[pat_field()]}) ->
+ {non_neg_integer(),[pat_field(),...]}.
+add_field(_Type, {1,Acc}) ->
+ {0, [1|Acc]};
+add_field({atom,_,Tag}, {Left,Acc}) ->
+ {erlang:max(0,Left-1), [Tag|Acc]};
+add_field(_Type, {Left,Acc}) ->
+ {erlang:max(0,Left-1), [0|Acc]}.
+
+%% @private
+-spec match(pattern(), tuple()) -> term().
+match(Pattern, Term) when tuple_size(Pattern) =:= tuple_size(Term) ->
+ match(tuple_to_list(Pattern), tuple_to_list(Term), none, false);
+match(_Pattern, _Term) ->
+ throw(no_match).
+
+-spec match([pat_field()], [term()], 'none' | {'ok',T}, boolean()) -> T.
+match([], [], {ok,Target}, _TypeMode) ->
+ Target;
+match([0|PatRest], [_|ToMatchRest], Acc, TypeMode) ->
+ match(PatRest, ToMatchRest, Acc, TypeMode);
+match([1|PatRest], [Target|ToMatchRest], none, TypeMode) ->
+ match(PatRest, ToMatchRest, {ok,Target}, TypeMode);
+match([Tag|PatRest], [X|ToMatchRest], Acc, TypeMode) when is_atom(Tag) ->
+ MatchesTag =
+ case TypeMode of
+ true -> can_be_tag(Tag, X);
+ false -> Tag =:= X
+ end,
+ case MatchesTag of
+ true -> match(PatRest, ToMatchRest, Acc, TypeMode);
+ false -> throw(no_match)
+ end.
+
+%% CAUTION: these must be sorted
+-define(NON_ATOM_TYPES,
+ [arity,binary,bitstring,byte,char,float,'fun',function,integer,iodata,
+ iolist,list,maybe_improper_list,mfa,neg_integer,nil,no_return,
+ non_neg_integer,none,nonempty_improper_list,nonempty_list,
+ nonempty_maybe_improper_list,nonempty_string,number,pid,port,
+ pos_integer,range,record,reference,string,tuple]).
+-define(NON_TUPLE_TYPES,
+ [arity,atom,binary,bitstring,bool,boolean,byte,char,float,'fun',
+ function,identifier,integer,iodata,iolist,list,maybe_improper_list,
+ neg_integer,nil,no_return,node,non_neg_integer,none,
+ nonempty_improper_list,nonempty_list,nonempty_maybe_improper_list,
+ nonempty_string,number,pid,port,pos_integer,range,reference,string,
+ timeout]).
+-define(NO_HEAD_TYPES,
+ [arity,atom,binary,bitstring,bool,boolean,byte,char,float,'fun',
+ function,identifier,integer,mfa,module,neg_integer,nil,no_return,node,
+ non_neg_integer,none,number,pid,port,pos_integer,range,record,
+ reference,timeout,tuple]).
+
+-spec can_be_tag(atom(), abs_type()) -> boolean().
+can_be_tag(Tag, {ann_type,_,[_Var,Type]}) ->
+ can_be_tag(Tag, Type);
+can_be_tag(Tag, {paren_type,_,[Type]}) ->
+ can_be_tag(Tag, Type);
+can_be_tag(Tag, {atom,_,Atom}) ->
+ Tag =:= Atom;
+can_be_tag(_Tag, {integer,_,_Int}) ->
+ false;
+can_be_tag(_Tag, {op,_,_Op,_Arg}) ->
+ false;
+can_be_tag(_Tag, {op,_,_Op,_Arg1,_Arg2}) ->
+ false;
+can_be_tag(Tag, {type,_,BName,[]}) when BName =:= bool; BName =:= boolean ->
+ is_boolean(Tag);
+can_be_tag(Tag, {type,_,timeout,[]}) ->
+ Tag =:= infinity;
+can_be_tag(Tag, {type,_,union,Choices}) ->
+ lists:any(fun(C) -> can_be_tag(Tag,C) end, Choices);
+can_be_tag(_Tag, {type,_,Name,_Args}) ->
+ not ordsets:is_element(Name, ?NON_ATOM_TYPES);
+can_be_tag(_Tag, _Type) ->
+ true.
+
+-spec cant_match(pattern(), abs_type()) -> boolean().
+cant_match(Pattern, {ann_type,_,[_Var,Type]}) ->
+ cant_match(Pattern, Type);
+cant_match(Pattern, {paren_type,_,[Type]}) ->
+ cant_match(Pattern, Type);
+cant_match(_Pattern, {atom,_,_Atom}) ->
+ true;
+cant_match(_Pattern, {integer,_,_Int}) ->
+ true;
+cant_match(_Pattern, {op,_,_Op,_Arg}) ->
+ true;
+cant_match(_Pattern, {op,_,_Op,_Arg1,_Arg2}) ->
+ true;
+cant_match(Pattern, {type,_,mfa,[]}) ->
+ cant_match(Pattern, {type,0,tuple,[{type,0,atom,[]},{type,0,atom,[]},
+ {type,0,arity,[]}]});
+cant_match(Pattern, {type,_,union,Choices}) ->
+ lists:all(fun(C) -> cant_match(Pattern,C) end, Choices);
+cant_match(_Pattern, {type,_,tuple,any}) ->
+ false;
+cant_match(Pattern, {type,_,tuple,Fields}) ->
+ tuple_size(Pattern) =/= length(Fields) orelse
+ try match(tuple_to_list(Pattern), Fields, none, true) of
+ _ -> false
+ catch
+ throw:no_match -> true
+ end;
+cant_match(_Pattern, {type,_,Name,_Args}) ->
+ ordsets:is_element(Name, ?NON_TUPLE_TYPES);
+cant_match(_Pattern, _Type) ->
+ false.
+
+-spec cant_have_head(abs_type()) -> boolean().
+cant_have_head({ann_type,_,[_Var,Type]}) ->
+ cant_have_head(Type);
+cant_have_head({paren_type,_,[Type]}) ->
+ cant_have_head(Type);
+cant_have_head({atom,_,_Atom}) ->
+ true;
+cant_have_head({integer,_,_Int}) ->
+ true;
+cant_have_head({op,_,_Op,_Arg}) ->
+ true;
+cant_have_head({op,_,_Op,_Arg1,_Arg2}) ->
+ true;
+cant_have_head({type,_,union,Choices}) ->
+ lists:all(fun cant_have_head/1, Choices);
+cant_have_head({type,_,Name,_Args}) ->
+ ordsets:is_element(Name, ?NO_HEAD_TYPES);
+cant_have_head(_Type) ->
+ false.
+
+%% Only covers atoms, integers and tuples, i.e. those that can be specified
+%% through singleton types.
+-spec term_to_singleton_type(atom() | integer()
+ | loose_tuple(atom() | integer())) -> abs_type().
+term_to_singleton_type(Atom) when is_atom(Atom) ->
+ {atom,0,Atom};
+term_to_singleton_type(Int) when is_integer(Int), Int >= 0 ->
+ {integer,0,Int};
+term_to_singleton_type(Int) when is_integer(Int), Int < 0 ->
+ {op,0,'-',{integer,0,-Int}};
+term_to_singleton_type(Tuple) when is_tuple(Tuple) ->
+ Fields = tuple_to_list(Tuple),
+ {type,0,tuple,[term_to_singleton_type(F) || F <- Fields]}.
+
+
+%%------------------------------------------------------------------------------
+%% Instance testing functions
+%%------------------------------------------------------------------------------
+
+%% CAUTION: this must be sorted
+-define(EQUIV_TYPES,
+ [{arity, {type,0,range,[{integer,0,0},{integer,0,255}]}},
+ {bool, {type,0,boolean,[]}},
+ {byte, {type,0,range,[{integer,0,0},{integer,0,255}]}},
+ {char, {type,0,range,[{integer,0,0},{integer,0,16#10ffff}]}},
+ {function, {type,0,'fun',[]}},
+ {identifier, {type,0,union,[{type,0,pid,[]},{type,0,port,[]},
+ {type,0,reference,[]}]}},
+ {iodata, {type,0,union,[{type,0,binary,[]},{type,0,iolist,[]}]}},
+ {iolist, {type,0,maybe_improper_list,
+ [{type,0,union,[{type,0,byte,[]},{type,0,binary,[]},
+ {type,0,iolist,[]}]},
+ {type,0,binary,[]}]}},
+ {list, {type,0,list,[{type,0,any,[]}]}},
+ {maybe_improper_list, {type,0,maybe_improper_list,[{type,0,any,[]},
+ {type,0,any,[]}]}},
+ {mfa, {type,0,tuple,[{type,0,atom,[]},{type,0,atom,[]},
+ {type,0,arity,[]}]}},
+ {node, {type,0,atom,[]}},
+ {nonempty_list, {type,0,nonempty_list,[{type,0,any,[]}]}},
+ {nonempty_maybe_improper_list, {type,0,nonempty_maybe_improper_list,
+ [{type,0,any,[]},{type,0,any,[]}]}},
+ {nonempty_string, {type,0,nonempty_list,[{type,0,char,[]}]}},
+ {string, {type,0,list,[{type,0,char,[]}]}},
+ {term, {type,0,any,[]}},
+ {timeout, {type,0,union,[{atom,0,infinity},
+ {type,0,non_neg_integer,[]}]}}]).
+
+%% @private
+%% TODO: Most of these functions accept an extended form of abs_type(), namely
+%% the addition of a custom wrapper: {'from_mod',mod_name(),...}
+-spec is_instance(term(), mod_name(), abs_type()) -> boolean().
+is_instance(X, Mod, TypeForm) ->
+ is_instance(X, Mod, TypeForm, []).
+
+-spec is_instance(term(), mod_name(), abs_type(), imm_stack()) -> boolean().
+is_instance(X, _Mod, {from_mod,OrigMod,Type}, Stack) ->
+ is_instance(X, OrigMod, Type, Stack);
+is_instance(_X, _Mod, {var,_,'_'}, _Stack) ->
+ true;
+is_instance(_X, _Mod, {var,_,Name}, _Stack) ->
+ %% All unconstrained spec vars have been replaced by 'any()' and we always
+ %% replace the variables on the RHS of types before recursing into them.
+ %% Provided that '-type' declarations contain no unbound variables, we
+ %% don't expect to find any non-'_' variables while recursing.
+ throw({'$typeserver',{unbound_var_in_type_declaration,Name}});
+is_instance(X, Mod, {ann_type,_,[_Var,Type]}, Stack) ->
+ is_instance(X, Mod, Type, Stack);
+is_instance(X, Mod, {paren_type,_,[Type]}, Stack) ->
+ is_instance(X, Mod, Type, Stack);
+is_instance(X, Mod, {remote_type,_,[{atom,_,RemMod},{atom,_,Name},ArgForms]},
+ Stack) ->
+ is_custom_instance(X, Mod, RemMod, Name, ArgForms, true, Stack);
+is_instance(SameAtom, _Mod, {atom,_,SameAtom}, _Stack) ->
+ true;
+is_instance(SameInt, _Mod, {integer,_,SameInt}, _Stack) ->
+ true;
+is_instance(X, _Mod, {op,_,_Op,_Arg} = Expr, _Stack) ->
+ is_int_const(X, Expr);
+is_instance(X, _Mod, {op,_,_Op,_Arg1,_Arg2} = Expr, _Stack) ->
+ is_int_const(X, Expr);
+is_instance(_X, _Mod, {type,_,any,[]}, _Stack) ->
+ true;
+is_instance(X, _Mod, {type,_,atom,[]}, _Stack) ->
+ is_atom(X);
+is_instance(X, _Mod, {type,_,binary,[]}, _Stack) ->
+ is_binary(X);
+is_instance(X, _Mod, {type,_,binary,[BaseExpr,UnitExpr]}, _Stack) ->
+ %% <<_:X,_:_*Y>> means "bitstrings of X + k*Y bits, k >= 0"
+ case eval_int(BaseExpr) of
+ {ok,Base} when Base >= 0 ->
+ case eval_int(UnitExpr) of
+ {ok,Unit} when Unit >= 0 ->
+ case is_bitstring(X) of
+ true ->
+ BitSizeX = bit_size(X),
+ case Unit =:= 0 of
+ true ->
+ BitSizeX =:= Base;
+ false ->
+ BitSizeX >= Base
+ andalso
+ (BitSizeX - Base) rem Unit =:= 0
+ end;
+ false -> false
+ end;
+ _ ->
+ abs_expr_error(invalid_unit, UnitExpr)
+ end;
+ _ ->
+ abs_expr_error(invalid_base, BaseExpr)
+ end;
+is_instance(X, _Mod, {type,_,bitstring,[]}, _Stack) ->
+ is_bitstring(X);
+is_instance(X, _Mod, {type,_,boolean,[]}, _Stack) ->
+ is_boolean(X);
+is_instance(X, _Mod, {type,_,float,[]}, _Stack) ->
+ is_float(X);
+is_instance(X, _Mod, {type,_,'fun',[]}, _Stack) ->
+ is_function(X);
+%% TODO: how to check range type? random inputs? special case for 0-arity?
+is_instance(X, _Mod, {type,_,'fun',[{type,_,any,[]},_Range]}, _Stack) ->
+ is_function(X);
+is_instance(X, _Mod, {type,_,'fun',[{type,_,product,Domain},_Range]}, _Stack) ->
+ is_function(X, length(Domain));
+is_instance(X, _Mod, {type,_,integer,[]}, _Stack) ->
+ is_integer(X);
+is_instance(X, Mod, {type,_,list,[Type]}, _Stack) ->
+ list_test(X, Mod, Type, dummy, true, true, false);
+is_instance(X, Mod, {type,_,maybe_improper_list,[Cont,Term]}, _Stack) ->
+ list_test(X, Mod, Cont, Term, true, true, true);
+is_instance(X, _Mod, {type,_,module,[]}, _Stack) ->
+ is_atom(X) orelse
+ is_tuple(X) andalso X =/= {} andalso is_atom(element(1,X));
+is_instance([], _Mod, {type,_,nil,[]}, _Stack) ->
+ true;
+is_instance(X, _Mod, {type,_,neg_integer,[]}, _Stack) ->
+ is_integer(X) andalso X < 0;
+is_instance(X, _Mod, {type,_,non_neg_integer,[]}, _Stack) ->
+ is_integer(X) andalso X >= 0;
+is_instance(X, Mod, {type,_,nonempty_list,[Type]}, _Stack) ->
+ list_test(X, Mod, Type, dummy, false, true, false);
+is_instance(X, Mod, {type,_,nonempty_improper_list,[Cont,Term]}, _Stack) ->
+ list_test(X, Mod, Cont, Term, false, false, true);
+is_instance(X, Mod, {type,_,nonempty_maybe_improper_list,[Cont,Term]},
+ _Stack) ->
+ list_test(X, Mod, Cont, Term, false, true, true);
+is_instance(X, _Mod, {type,_,number,[]}, _Stack) ->
+ is_number(X);
+is_instance(X, _Mod, {type,_,pid,[]}, _Stack) ->
+ is_pid(X);
+is_instance(X, _Mod, {type,_,port,[]}, _Stack) ->
+ is_port(X);
+is_instance(X, _Mod, {type,_,pos_integer,[]}, _Stack) ->
+ is_integer(X) andalso X > 0;
+is_instance(_X, _Mod, {type,_,product,_Elements}, _Stack) ->
+ throw({'$typeserver',{internal,product_in_is_instance}});
+is_instance(X, _Mod, {type,_,range,[LowExpr,HighExpr]}, _Stack) ->
+ case {eval_int(LowExpr),eval_int(HighExpr)} of
+ {{ok,Low},{ok,High}} when Low =< High ->
+ X >= Low andalso X =< High;
+ _ ->
+ abs_expr_error(invalid_range, LowExpr, HighExpr)
+ end;
+is_instance(X, Mod, {type,_,record,[{atom,_,Name} = NameForm | RawSubsts]},
+ Stack) ->
+ Substs = [{N,T} || {type,_,field_type,[{atom,_,N},T]} <- RawSubsts],
+ SubstsDict = dict:from_list(Substs),
+ case get_type_repr(Mod, {record,Name,0}, false) of
+ {ok,{abs_record,OrigFields}} ->
+ Fields = [case dict:find(FieldName, SubstsDict) of
+ {ok,NewFieldType} -> NewFieldType;
+ error -> OrigFieldType
+ end
+ || {FieldName,OrigFieldType} <- OrigFields],
+ is_instance(X, Mod, {type,0,tuple,[NameForm|Fields]}, Stack);
+ {error,Reason} ->
+ throw({'$typeserver',Reason})
+ end;
+is_instance(X, _Mod, {type,_,reference,[]}, _Stack) ->
+ is_reference(X);
+is_instance(X, _Mod, {type,_,tuple,any}, _Stack) ->
+ is_tuple(X);
+is_instance(X, Mod, {type,_,tuple,Fields}, _Stack) ->
+ is_tuple(X) andalso tuple_test(tuple_to_list(X), Mod, Fields);
+is_instance(X, Mod, {type,_,union,Choices}, Stack) ->
+ IsInstance = fun(Choice) -> is_instance(X,Mod,Choice,Stack) end,
+ lists:any(IsInstance, Choices);
+is_instance(X, Mod, {type,_,Name,[]}, Stack) ->
+ case orddict:find(Name, ?EQUIV_TYPES) of
+ {ok,EquivType} ->
+ is_instance(X, Mod, EquivType, Stack);
+ error ->
+ is_maybe_hard_adt(X, Mod, Name, [], Stack)
+ end;
+is_instance(X, Mod, {type,_,Name,ArgForms}, Stack) ->
+ is_maybe_hard_adt(X, Mod, Name, ArgForms, Stack);
+is_instance(_X, _Mod, _Type, _Stack) ->
+ false.
+
+-spec is_int_const(term(), abs_expr()) -> boolean().
+is_int_const(X, Expr) ->
+ case eval_int(Expr) of
+ {ok,Int} ->
+ X =:= Int;
+ error ->
+ abs_expr_error(invalid_int_const, Expr)
+ end.
+
+%% TODO: We implicitly add the '| []' at the termination of maybe_improper_list.
+%% TODO: We ignore a '[]' termination in improper_list.
+-spec list_test(term(), mod_name(), abs_type(), 'dummy' | abs_type(), boolean(),
+ boolean(), boolean()) -> boolean().
+list_test(X, Mod, Content, Termination, CanEmpty, CanProper, CanImproper) ->
+ is_list(X) andalso
+ list_rec(X, Mod, Content, Termination, CanEmpty, CanProper, CanImproper).
+
+-spec list_rec(term(), mod_name(), abs_type(), 'dummy' | abs_type(), boolean(),
+ boolean(), boolean()) -> boolean().
+list_rec([], _Mod, _Content, _Termination, CanEmpty, CanProper, _CanImproper) ->
+ CanEmpty andalso CanProper;
+list_rec([X | Rest], Mod, Content, Termination, _CanEmpty, CanProper,
+ CanImproper) ->
+ is_instance(X, Mod, Content, []) andalso
+ list_rec(Rest, Mod, Content, Termination, true, CanProper, CanImproper);
+list_rec(X, Mod, _Content, Termination, _CanEmpty, _CanProper, CanImproper) ->
+ CanImproper andalso is_instance(X, Mod, Termination, []).
+
+-spec tuple_test([term()], mod_name(), [abs_type()]) -> boolean().
+tuple_test([], _Mod, []) ->
+ true;
+tuple_test([X | XTail], Mod, [T | TTail]) ->
+ is_instance(X, Mod, T, []) andalso tuple_test(XTail, Mod, TTail);
+tuple_test(_, _Mod, _) ->
+ false.
+
+-spec is_maybe_hard_adt(term(), mod_name(), type_name(), [abs_type()],
+ imm_stack()) -> boolean().
+is_maybe_hard_adt(X, Mod, Name, ArgForms, Stack) ->
+ case orddict:find({Name,length(ArgForms)}, ?HARD_ADTS) of
+ {ok,ADTMod} ->
+ is_custom_instance(X, Mod, ADTMod, Name, ArgForms, true, Stack);
+ error ->
+ is_custom_instance(X, Mod, Mod, Name, ArgForms, false, Stack)
+ end.
+
+-spec is_custom_instance(term(), mod_name(), mod_name(), type_name(),
+ [abs_type()], boolean(), imm_stack()) -> boolean().
+is_custom_instance(X, Mod, RemMod, Name, RawArgForms, IsRemote, Stack) ->
+ ArgForms = case Mod =/= RemMod of
+ true -> [{from_mod,Mod,A} || A <- RawArgForms];
+ false -> RawArgForms
+ end,
+ Arity = length(ArgForms),
+ FullTypeRef = {RemMod,Name,Arity},
+ case lists:member(FullTypeRef, Stack) of
+ true ->
+ throw({'$typeserver',{self_reference,FullTypeRef}});
+ false ->
+ TypeRef = {type,Name,Arity},
+ AbsType = get_abs_type(RemMod, TypeRef, ArgForms, IsRemote),
+ is_instance(X, RemMod, AbsType, [FullTypeRef|Stack])
+ end.
+
+-spec get_abs_type(mod_name(), type_ref(), [abs_type()], boolean()) ->
+ abs_type().
+get_abs_type(RemMod, TypeRef, ArgForms, IsRemote) ->
+ case get_type_repr(RemMod, TypeRef, IsRemote) of
+ {ok,TypeRepr} ->
+ {FinalAbsType,SymbInfo,VarNames} =
+ case TypeRepr of
+ {cached,_FinType,FAT,SI} -> {FAT,SI,[]};
+ {abs_type,FAT,VN,SI} -> {FAT,SI,VN}
+ end,
+ AbsType =
+ case SymbInfo of
+ not_symb -> FinalAbsType;
+ {orig_abs,OrigAbsType} -> OrigAbsType
+ end,
+ VarSubstsDict = dict:from_list(lists:zip(VarNames,ArgForms)),
+ update_vars(AbsType, VarSubstsDict, false);
+ {error,Reason} ->
+ throw({'$typeserver',Reason})
+ end.
+
+-spec abs_expr_error(atom(), abs_expr()) -> no_return().
+abs_expr_error(ImmReason, Expr) ->
+ {error,Reason} = expr_error(ImmReason, Expr),
+ throw({'$typeserver',Reason}).
+
+-spec abs_expr_error(atom(), abs_expr(), abs_expr()) -> no_return().
+abs_expr_error(ImmReason, Expr1, Expr2) ->
+ {error,Reason} = expr_error(ImmReason, Expr1, Expr2),
+ throw({'$typeserver',Reason}).
+
+
+%%------------------------------------------------------------------------------
+%% Type translation functions
+%%------------------------------------------------------------------------------
+
+-spec convert(mod_name(), abs_type(), state()) ->
+ rich_result2(fin_type(),state()).
+convert(Mod, TypeForm, State) ->
+ case convert(Mod, TypeForm, State, [], dict:new()) of
+ {ok,{simple,Type},NewState} ->
+ {ok, Type, NewState};
+ {ok,{rec,_RecFun,_RecArgs},_NewState} ->
+ {error, {internal,rec_returned_to_toplevel}};
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert(mod_name(), abs_type(), state(), stack(), var_dict()) ->
+ rich_result2(ret_type(),state()).
+convert(Mod, {paren_type,_,[Type]}, State, Stack, VarDict) ->
+ convert(Mod, Type, State, Stack, VarDict);
+convert(Mod, {ann_type,_,[_Var,Type]}, State, Stack, VarDict) ->
+ convert(Mod, Type, State, Stack, VarDict);
+convert(_Mod, {var,_,'_'}, State, _Stack, _VarDict) ->
+ {ok, {simple,proper_types:any()}, State};
+convert(_Mod, {var,_,VarName}, State, _Stack, VarDict) ->
+ case dict:find(VarName, VarDict) of
+ %% TODO: do we need to check if we are at toplevel of a recursive?
+ {ok,RetType} -> {ok, RetType, State};
+ error -> {error, {unbound_var,VarName}}
+ end;
+convert(Mod, {remote_type,_,[{atom,_,RemMod},{atom,_,Name},ArgForms]}, State,
+ Stack, VarDict) ->
+ case prepare_for_remote(RemMod, Name, length(ArgForms), State) of
+ {ok,NewState} ->
+ convert_custom(Mod,RemMod,Name,ArgForms,NewState,Stack,VarDict);
+ {error,_Reason} = Error ->
+ Error
+ end;
+convert(_Mod, {atom,_,Atom}, State, _Stack, _VarDict) ->
+ {ok, {simple,proper_types:exactly(Atom)}, State};
+convert(_Mod, {integer,_,_Int} = IntExpr, State, _Stack, _VarDict) ->
+ convert_integer(IntExpr, State);
+convert(_Mod, {op,_,_Op,_Arg} = OpExpr, State, _Stack, _VarDict) ->
+ convert_integer(OpExpr, State);
+convert(_Mod, {op,_,_Op,_Arg1,_Arg2} = OpExpr, State, _Stack, _VarDict) ->
+ convert_integer(OpExpr, State);
+convert(_Mod, {type,_,binary,[BaseExpr,UnitExpr]}, State, _Stack, _VarDict) ->
+ %% <<_:X,_:_*Y>> means "bitstrings of X + k*Y bits, k >= 0"
+ case eval_int(BaseExpr) of
+ {ok,0} ->
+ case eval_int(UnitExpr) of
+ {ok,0} -> {ok, {simple,proper_types:exactly(<<>>)}, State};
+ {ok,1} -> {ok, {simple,proper_types:bitstring()}, State};
+ {ok,8} -> {ok, {simple,proper_types:binary()}, State};
+ {ok,N} when N > 0 ->
+ Gen = ?LET(L, proper_types:list(proper_types:bitstring(N)),
+ concat_bitstrings(L)),
+ {ok, {simple,Gen}, State};
+ _ -> expr_error(invalid_unit, UnitExpr)
+ end;
+ {ok,Base} when Base > 0 ->
+ Head = proper_types:bitstring(Base),
+ case eval_int(UnitExpr) of
+ {ok,0} -> {ok, {simple,Head}, State};
+ {ok,1} ->
+ Tail = proper_types:bitstring(),
+ {ok, {simple,concat_binary_gens(Head, Tail)}, State};
+ {ok,8} ->
+ Tail = proper_types:binary(),
+ {ok, {simple,concat_binary_gens(Head, Tail)}, State};
+ {ok,N} when N > 0 ->
+ Tail =
+ ?LET(L, proper_types:list(proper_types:bitstring(N)),
+ concat_bitstrings(L)),
+ {ok, {simple,concat_binary_gens(Head, Tail)}, State};
+ _ -> expr_error(invalid_unit, UnitExpr)
+ end;
+ _ ->
+ expr_error(invalid_base, BaseExpr)
+ end;
+convert(_Mod, {type,_,range,[LowExpr,HighExpr]}, State, _Stack, _VarDict) ->
+ case {eval_int(LowExpr),eval_int(HighExpr)} of
+ {{ok,Low},{ok,High}} when Low =< High ->
+ {ok, {simple,proper_types:integer(Low,High)}, State};
+ _ ->
+ expr_error(invalid_range, LowExpr, HighExpr)
+ end;
+convert(_Mod, {type,_,nil,[]}, State, _Stack, _VarDict) ->
+ {ok, {simple,proper_types:exactly([])}, State};
+convert(Mod, {type,_,list,[ElemForm]}, State, Stack, VarDict) ->
+ convert_list(Mod, false, ElemForm, State, Stack, VarDict);
+convert(Mod, {type,_,nonempty_list,[ElemForm]}, State, Stack, VarDict) ->
+ convert_list(Mod, true, ElemForm, State, Stack, VarDict);
+convert(_Mod, {type,_,nonempty_list,[]}, State, _Stack, _VarDict) ->
+ {ok, {simple,proper_types:non_empty(proper_types:list())}, State};
+convert(_Mod, {type,_,nonempty_string,[]}, State, _Stack, _VarDict) ->
+ {ok, {simple,proper_types:non_empty(proper_types:string())}, State};
+convert(_Mod, {type,_,tuple,any}, State, _Stack, _VarDict) ->
+ {ok, {simple,proper_types:tuple()}, State};
+convert(Mod, {type,_,tuple,ElemForms}, State, Stack, VarDict) ->
+ convert_tuple(Mod, ElemForms, false, State, Stack, VarDict);
+convert(Mod, {type,_,'$fixed_list',ElemForms}, State, Stack, VarDict) ->
+ convert_tuple(Mod, ElemForms, true, State, Stack, VarDict);
+convert(Mod, {type,_,record,[{atom,_,Name}|FieldForms]}, State, Stack,
+ VarDict) ->
+ convert_record(Mod, Name, FieldForms, State, Stack, VarDict);
+convert(Mod, {type,_,union,ChoiceForms}, State, Stack, VarDict) ->
+ convert_union(Mod, ChoiceForms, State, Stack, VarDict);
+convert(Mod, {type,_,'fun',[{type,_,product,Domain},Range]}, State, Stack,
+ VarDict) ->
+ convert_fun(Mod, length(Domain), Range, State, Stack, VarDict);
+%% TODO: These types should be replaced with accurate types.
+%% TODO: Add support for nonempty_improper_list/2.
+convert(Mod, {type,_,maybe_improper_list,[]}, State, Stack, VarDict) ->
+ convert(Mod, {type,0,list,[]}, State, Stack, VarDict);
+convert(Mod, {type,_,maybe_improper_list,[Cont,_Ter]}, State, Stack, VarDict) ->
+ convert(Mod, {type,0,list,[Cont]}, State, Stack, VarDict);
+convert(Mod, {type,_,nonempty_maybe_improper_list,[]}, State, Stack, VarDict) ->
+ convert(Mod, {type,0,nonempty_list,[]}, State, Stack, VarDict);
+convert(Mod, {type,_,nonempty_maybe_improper_list,[Cont,_Term]}, State, Stack,
+ VarDict) ->
+ convert(Mod, {type,0,nonempty_list,[Cont]}, State, Stack, VarDict);
+convert(Mod, {type,_,iodata,[]}, State, Stack, VarDict) ->
+ RealType = {type,0,union,[{type,0,binary,[]},{type,0,iolist,[]}]},
+ convert(Mod, RealType, State, Stack, VarDict);
+convert(Mod, {type,_,Name,[]}, State, Stack, VarDict) ->
+ case ordsets:is_element(Name, ?STD_TYPES_0) of
+ true ->
+ {ok, {simple,proper_types:Name()}, State};
+ false ->
+ convert_maybe_hard_adt(Mod, Name, [], State, Stack, VarDict)
+ end;
+convert(Mod, {type,_,Name,ArgForms}, State, Stack, VarDict) ->
+ convert_maybe_hard_adt(Mod, Name, ArgForms, State, Stack, VarDict);
+convert(_Mod, TypeForm, _State, _Stack, _VarDict) ->
+ {error, {unsupported_type,TypeForm}}.
+
+-spec concat_bitstrings([bitstring()]) -> bitstring().
+concat_bitstrings(BitStrings) ->
+ concat_bitstrings_tr(BitStrings, <<>>).
+
+-spec concat_bitstrings_tr([bitstring()], bitstring()) -> bitstring().
+concat_bitstrings_tr([], Acc) ->
+ Acc;
+concat_bitstrings_tr([BitString | Rest], Acc) ->
+ concat_bitstrings_tr(Rest, <<Acc/bits,BitString/bits>>).
+
+-spec concat_binary_gens(fin_type(), fin_type()) -> fin_type().
+concat_binary_gens(HeadType, TailType) ->
+ ?LET({H,T}, {HeadType,TailType}, <<H/bits,T/bits>>).
+
+-spec convert_fun(mod_name(), arity(), abs_type(), state(), stack(),
+ var_dict()) -> rich_result2(ret_type(),state()).
+convert_fun(Mod, Arity, Range, State, Stack, VarDict) ->
+ case convert(Mod, Range, State, ['fun' | Stack], VarDict) of
+ {ok,{simple,RangeType},NewState} ->
+ {ok, {simple,proper_types:function(Arity,RangeType)}, NewState};
+ {ok,{rec,RecFun,RecArgs},NewState} ->
+ case at_toplevel(RecArgs, Stack) of
+ true -> base_case_error(Stack);
+ false -> convert_rec_fun(Arity, RecFun, RecArgs, NewState)
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert_rec_fun(arity(), rec_fun(), rec_args(), state()) ->
+ {'ok',ret_type(),state()}.
+convert_rec_fun(Arity, RecFun, RecArgs, State) ->
+ %% We bind the generated value by size.
+ NewRecFun =
+ fun(GenFuns,Size) ->
+ proper_types:function(Arity, RecFun(GenFuns,Size))
+ end,
+ NewRecArgs = clean_rec_args(RecArgs),
+ {ok, {rec,NewRecFun,NewRecArgs}, State}.
+
+-spec convert_list(mod_name(), boolean(), abs_type(), state(), stack(),
+ var_dict()) -> rich_result2(ret_type(),state()).
+convert_list(Mod, NonEmpty, ElemForm, State, Stack, VarDict) ->
+ case convert(Mod, ElemForm, State, [list | Stack], VarDict) of
+ {ok,{simple,ElemType},NewState} ->
+ InnerType = proper_types:list(ElemType),
+ FinType = case NonEmpty of
+ true -> proper_types:non_empty(InnerType);
+ false -> InnerType
+ end,
+ {ok, {simple,FinType}, NewState};
+ {ok,{rec,RecFun,RecArgs},NewState} ->
+ case {at_toplevel(RecArgs,Stack), NonEmpty} of
+ {true,true} ->
+ base_case_error(Stack);
+ {true,false} ->
+ NewRecFun =
+ fun(GenFuns,Size) ->
+ ElemGen = fun(S) -> ?LAZY(RecFun(GenFuns,S)) end,
+ proper_types:distlist(Size, ElemGen, false)
+ end,
+ NewRecArgs = clean_rec_args(RecArgs),
+ {ok, {rec,NewRecFun,NewRecArgs}, NewState};
+ {false,_} ->
+ {NewRecFun,NewRecArgs} =
+ convert_rec_list(RecFun, RecArgs, NonEmpty),
+ {ok, {rec,NewRecFun,NewRecArgs}, NewState}
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert_rec_list(rec_fun(), rec_args(), boolean()) ->
+ {rec_fun(),rec_args()}.
+convert_rec_list(RecFun, [{true,FullTypeRef}] = RecArgs, NonEmpty) ->
+ {NewRecFun,_NormalRecArgs} =
+ convert_normal_rec_list(RecFun, RecArgs, NonEmpty),
+ AltRecFun =
+ fun([InstListGen],Size) ->
+ InstTypesList =
+ proper_types:get_prop(internal_types, InstListGen(Size)),
+ proper_types:fixed_list([RecFun([fun(_Size) -> I end],0)
+ || I <- InstTypesList])
+ end,
+ NewRecArgs = [{{list,NonEmpty,AltRecFun},FullTypeRef}],
+ {NewRecFun, NewRecArgs};
+convert_rec_list(RecFun, RecArgs, NonEmpty) ->
+ convert_normal_rec_list(RecFun, RecArgs, NonEmpty).
+
+-spec convert_normal_rec_list(rec_fun(), rec_args(), boolean()) ->
+ {rec_fun(),rec_args()}.
+convert_normal_rec_list(RecFun, RecArgs, NonEmpty) ->
+ NewRecFun = fun(GenFuns,Size) ->
+ ElemGen = fun(S) -> RecFun(GenFuns, S) end,
+ proper_types:distlist(Size, ElemGen, NonEmpty)
+ end,
+ NewRecArgs = clean_rec_args(RecArgs),
+ {NewRecFun, NewRecArgs}.
+
+-spec convert_tuple(mod_name(), [abs_type()], boolean(), state(), stack(),
+ var_dict()) -> rich_result2(ret_type(),state()).
+convert_tuple(Mod, ElemForms, ToList, State, Stack, VarDict) ->
+ case process_list(Mod, ElemForms, State, [tuple | Stack], VarDict) of
+ {ok,RetTypes,NewState} ->
+ case combine_ret_types(RetTypes, {tuple,ToList}) of
+ {simple,_FinType} = RetType ->
+ {ok, RetType, NewState};
+ {rec,_RecFun,RecArgs} = RetType ->
+ case at_toplevel(RecArgs, Stack) of
+ true -> base_case_error(Stack);
+ false -> {ok, RetType, NewState}
+ end
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert_union(mod_name(), [abs_type()], state(), stack(), var_dict()) ->
+ rich_result2(ret_type(),state()).
+convert_union(Mod, ChoiceForms, State, Stack, VarDict) ->
+ case process_list(Mod, ChoiceForms, State, [union | Stack], VarDict) of
+ {ok,RawChoices,NewState} ->
+ ProcessChoice = fun(T,A) -> process_choice(T,A,Stack) end,
+ {RevSelfRecs,RevNonSelfRecs,RevNonRecs} =
+ lists:foldl(ProcessChoice, {[],[],[]}, RawChoices),
+ case {lists:reverse(RevSelfRecs),lists:reverse(RevNonSelfRecs),
+ lists:reverse(RevNonRecs)} of
+ {_SelfRecs,[],[]} ->
+ base_case_error(Stack);
+ {[],NonSelfRecs,NonRecs} ->
+ {ok, combine_ret_types(NonRecs ++ NonSelfRecs, union),
+ NewState};
+ {SelfRecs,NonSelfRecs,NonRecs} ->
+ {BCaseRecFun,BCaseRecArgs} =
+ case combine_ret_types(NonRecs ++ NonSelfRecs, union) of
+ {simple,BCaseType} ->
+ {fun([],_Size) -> BCaseType end,[]};
+ {rec,BCRecFun,BCRecArgs} ->
+ {BCRecFun,BCRecArgs}
+ end,
+ NumBCaseGens = length(BCaseRecArgs),
+ [ParentRef | _Upper] = Stack,
+ FallbackRecFun = fun([SelfGen],_Size) -> SelfGen(0) end,
+ FallbackRecArgs = [{false,ParentRef}],
+ FallbackRetType = {rec,FallbackRecFun,FallbackRecArgs},
+ {rec,RCaseRecFun,RCaseRecArgs} =
+ combine_ret_types([FallbackRetType] ++ SelfRecs
+ ++ NonSelfRecs, wunion),
+ NewRecFun =
+ fun(AllGens,Size) ->
+ {BCaseGens,RCaseGens} =
+ lists:split(NumBCaseGens, AllGens),
+ case Size of
+ 0 -> BCaseRecFun(BCaseGens,0);
+ _ -> RCaseRecFun(RCaseGens,Size)
+ end
+ end,
+ NewRecArgs = BCaseRecArgs ++ RCaseRecArgs,
+ {ok, {rec,NewRecFun,NewRecArgs}, NewState}
+ end;
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec process_choice(ret_type(), {[ret_type()],[ret_type()],[ret_type()]},
+ stack()) -> {[ret_type()],[ret_type()],[ret_type()]}.
+process_choice({simple,_} = RetType, {SelfRecs,NonSelfRecs,NonRecs}, _Stack) ->
+ {SelfRecs, NonSelfRecs, [RetType | NonRecs]};
+process_choice({rec,RecFun,RecArgs}, {SelfRecs,NonSelfRecs,NonRecs}, Stack) ->
+ case at_toplevel(RecArgs, Stack) of
+ true ->
+ case partition_by_toplevel(RecArgs, Stack, true) of
+ {[],[],_,_} ->
+ NewRecArgs = clean_rec_args(RecArgs),
+ {[{rec,RecFun,NewRecArgs} | SelfRecs], NonSelfRecs,
+ NonRecs};
+ {SelfRecArgs,SelfPos,OtherRecArgs,_OtherPos} ->
+ NumInstances = length(SelfRecArgs),
+ IsListInst = fun({true,_FTRef}) -> false
+ ; ({{list,_NE,_AltRecFun},_FTRef}) -> true
+ end,
+ NewRecFun =
+ case proper_arith:filter(IsListInst,SelfRecArgs) of
+ {[],[]} ->
+ no_list_inst_rec_fun(RecFun,NumInstances,
+ SelfPos);
+ {[{{list,NonEmpty,AltRecFun},_}],[ListInstPos]} ->
+ list_inst_rec_fun(AltRecFun,NumInstances,
+ SelfPos,NonEmpty,ListInstPos)
+ end,
+ [{_B,SelfRef} | _] = SelfRecArgs,
+ NewRecArgs =
+ [{false,SelfRef} | clean_rec_args(OtherRecArgs)],
+ {[{rec,NewRecFun,NewRecArgs} | SelfRecs], NonSelfRecs,
+ NonRecs}
+ end;
+ false ->
+ NewRecArgs = clean_rec_args(RecArgs),
+ {SelfRecs, [{rec,RecFun,NewRecArgs} | NonSelfRecs], NonRecs}
+ end.
+
+-spec no_list_inst_rec_fun(rec_fun(), pos_integer(), [position()]) -> rec_fun().
+no_list_inst_rec_fun(RecFun, NumInstances, SelfPos) ->
+ fun([SelfGen|OtherGens], Size) ->
+ ?LETSHRINK(
+ Instances,
+ %% Size distribution will be a little off if both normal and
+ %% instance-accepting generators are present.
+ lists:duplicate(NumInstances, SelfGen(Size div NumInstances)),
+ begin
+ InstGens = [fun(_Size) -> proper_types:exactly(I) end
+ || I <- Instances],
+ AllGens = proper_arith:insert(InstGens, SelfPos, OtherGens),
+ RecFun(AllGens, Size)
+ end)
+ end.
+
+-spec list_inst_rec_fun(rec_fun(), pos_integer(), [position()], boolean(),
+ position()) -> rec_fun().
+list_inst_rec_fun(AltRecFun, NumInstances, SelfPos, NonEmpty, ListInstPos) ->
+ fun([SelfGen|OtherGens], Size) ->
+ ?LETSHRINK(
+ AllInsts,
+ lists:duplicate(NumInstances - 1, SelfGen(Size div NumInstances))
+ ++ proper_types:distlist(Size div NumInstances, SelfGen, NonEmpty),
+ begin
+ {Instances,InstList} = lists:split(NumInstances - 1, AllInsts),
+ InstGens = [fun(_Size) -> proper_types:exactly(I) end
+ || I <- Instances],
+ InstTypesList = [proper_types:exactly(I) || I <- InstList],
+ InstListGen =
+ fun(_Size) -> proper_types:fixed_list(InstTypesList) end,
+ AllInstGens = proper_arith:list_insert(ListInstPos, InstListGen,
+ InstGens),
+ AllGens = proper_arith:insert(AllInstGens, SelfPos, OtherGens),
+ AltRecFun(AllGens, Size)
+ end)
+ end.
+
+-spec convert_maybe_hard_adt(mod_name(), type_name(), [abs_type()], state(),
+ stack(), var_dict()) ->
+ rich_result2(ret_type(),state()).
+convert_maybe_hard_adt(Mod, Name, ArgForms, State, Stack, VarDict) ->
+ Arity = length(ArgForms),
+ case orddict:find({Name,Arity}, ?HARD_ADTS) of
+ {ok,Mod} ->
+ convert_custom(Mod, Mod, Name, ArgForms, State, Stack, VarDict);
+ {ok,ADTMod} ->
+ ADT = {remote_type,0,[{atom,0,ADTMod},{atom,0,Name},ArgForms]},
+ convert(Mod, ADT, State, Stack, VarDict);
+ error ->
+ convert_custom(Mod, Mod, Name, ArgForms, State, Stack, VarDict)
+ end.
+
+-spec convert_custom(mod_name(), mod_name(), type_name(), [abs_type()], state(),
+ stack(), var_dict()) -> rich_result2(ret_type(),state()).
+convert_custom(Mod, RemMod, Name, ArgForms, State, Stack, VarDict) ->
+ case process_list(Mod, ArgForms, State, Stack, VarDict) of
+ {ok,Args,NewState} ->
+ Arity = length(Args),
+ TypeRef = {type,Name,Arity},
+ FullTypeRef = {RemMod,type,Name,Args},
+ convert_type(TypeRef, FullTypeRef, NewState, Stack);
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert_record(mod_name(), type_name(), [abs_type()], state(), stack(),
+ var_dict()) -> rich_result2(ret_type(),state()).
+convert_record(Mod, Name, RawSubsts, State, Stack, VarDict) ->
+ Substs = [{N,T} || {type,_,field_type,[{atom,_,N},T]} <- RawSubsts],
+ {SubstFields,SubstTypeForms} = lists:unzip(Substs),
+ case process_list(Mod, SubstTypeForms, State, Stack, VarDict) of
+ {ok,SubstTypes,NewState} ->
+ SubstsDict = dict:from_list(lists:zip(SubstFields, SubstTypes)),
+ TypeRef = {record,Name,0},
+ FullTypeRef = {Mod,record,Name,SubstsDict},
+ convert_type(TypeRef, FullTypeRef, NewState, Stack);
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert_type(type_ref(), full_type_ref(), state(), stack()) ->
+ rich_result2(ret_type(),state()).
+convert_type(TypeRef, {Mod,_Kind,_Name,_Spec} = FullTypeRef, State, Stack) ->
+ case stack_position(FullTypeRef, Stack) of
+ none ->
+ case get_type_repr(Mod, TypeRef, false, State) of
+ {ok,TypeRepr,NewState} ->
+ convert_new_type(TypeRef, FullTypeRef, TypeRepr, NewState,
+ Stack);
+ {error,_Reason} = Error ->
+ Error
+ end;
+ 1 ->
+ base_case_error(Stack);
+ _Pos ->
+ {ok, {rec,fun([Gen],Size) -> Gen(Size) end,[{true,FullTypeRef}]},
+ State}
+ end.
+
+-spec convert_new_type(type_ref(), full_type_ref(), type_repr(), state(),
+ stack()) -> rich_result2(ret_type(),state()).
+convert_new_type(_TypeRef, {_Mod,type,_Name,[]},
+ {cached,FinType,_TypeForm,_SymbInfo}, State, _Stack) ->
+ {ok, {simple,FinType}, State};
+convert_new_type(TypeRef, {Mod,type,_Name,Args} = FullTypeRef,
+ {abs_type,TypeForm,Vars,SymbInfo}, State, Stack) ->
+ VarDict = dict:from_list(lists:zip(Vars, Args)),
+ case convert(Mod, TypeForm, State, [FullTypeRef | Stack], VarDict) of
+ {ok, {simple,ImmFinType}, NewState} ->
+ FinType = case SymbInfo of
+ not_symb ->
+ ImmFinType;
+ {orig_abs,_OrigAbsType} ->
+ proper_symb:internal_well_defined(ImmFinType)
+ end,
+ FinalState = case Vars of
+ [] -> cache_type(Mod, TypeRef, FinType, TypeForm,
+ SymbInfo, NewState);
+ _ -> NewState
+ end,
+ {ok, {simple,FinType}, FinalState};
+ {ok, {rec,RecFun,RecArgs}, NewState} ->
+ convert_maybe_rec(FullTypeRef, SymbInfo, RecFun, RecArgs, NewState,
+ Stack);
+ {error,_Reason} = Error ->
+ Error
+ end;
+convert_new_type(_TypeRef, {Mod,record,Name,SubstsDict} = FullTypeRef,
+ {abs_record,OrigFields}, State, Stack) ->
+ Fields = [case dict:find(FieldName, SubstsDict) of
+ {ok,NewFieldType} -> NewFieldType;
+ error -> OrigFieldType
+ end
+ || {FieldName,OrigFieldType} <- OrigFields],
+ case convert_tuple(Mod, [{atom,0,Name} | Fields], false, State,
+ [FullTypeRef | Stack], dict:new()) of
+ {ok, {simple,_FinType}, _NewState} = Result ->
+ Result;
+ {ok, {rec,RecFun,RecArgs}, NewState} ->
+ convert_maybe_rec(FullTypeRef, not_symb, RecFun, RecArgs, NewState,
+ Stack);
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec cache_type(mod_name(), type_ref(), fin_type(), abs_type(), symb_info(),
+ state()) -> state().
+cache_type(Mod, TypeRef, FinType, TypeForm, SymbInfo,
+ #state{types = Types} = State) ->
+ TypeRepr = {cached,FinType,TypeForm,SymbInfo},
+ ModTypes = dict:fetch(Mod, Types),
+ NewModTypes = dict:store(TypeRef, TypeRepr, ModTypes),
+ NewTypes = dict:store(Mod, NewModTypes, Types),
+ State#state{types = NewTypes}.
+
+-spec convert_maybe_rec(full_type_ref(), symb_info(), rec_fun(), rec_args(),
+ state(), stack()) -> rich_result2(ret_type(),state()).
+convert_maybe_rec(FullTypeRef, SymbInfo, RecFun, RecArgs, State, Stack) ->
+ case at_toplevel(RecArgs, Stack) of
+ true -> base_case_error(Stack);
+ false -> safe_convert_maybe_rec(FullTypeRef, SymbInfo, RecFun, RecArgs,
+ State)
+ end.
+
+-spec safe_convert_maybe_rec(full_type_ref(),symb_info(),rec_fun(),rec_args(),
+ state()) -> rich_result2(ret_type(),state()).
+safe_convert_maybe_rec(FullTypeRef, SymbInfo, RecFun, RecArgs, State) ->
+ case partition_rec_args(FullTypeRef, RecArgs, false) of
+ {[],[],_,_} ->
+ {ok, {rec,RecFun,RecArgs}, State};
+ {MyRecArgs,MyPos,OtherRecArgs,_OtherPos} ->
+ case lists:all(fun({B,_T}) -> B =:= false end, MyRecArgs) of
+ true -> convert_rec_type(SymbInfo, RecFun, MyPos, OtherRecArgs,
+ State);
+ false -> {error, {internal,true_rec_arg_reached_type}}
+ end
+ end.
+
+-spec convert_rec_type(symb_info(), rec_fun(), [position()], rec_args(),
+ state()) -> {ok, ret_type(), state()}.
+convert_rec_type(SymbInfo, RecFun, MyPos, [], State) ->
+ NumRecArgs = length(MyPos),
+ M = fun(GenFun) ->
+ fun(Size) ->
+ GenFuns = lists:duplicate(NumRecArgs, GenFun),
+ RecFun(GenFuns, erlang:max(0,Size - 1))
+ end
+ end,
+ SizedGen = y(M),
+ ImmFinType = ?SIZED(Size,SizedGen(Size + 1)),
+ FinType = case SymbInfo of
+ not_symb ->
+ ImmFinType;
+ {orig_abs,_OrigAbsType} ->
+ proper_symb:internal_well_defined(ImmFinType)
+ end,
+ {ok, {simple,FinType}, State};
+convert_rec_type(_SymbInfo, RecFun, MyPos, OtherRecArgs, State) ->
+ NumRecArgs = length(MyPos),
+ NewRecFun =
+ fun(OtherGens,TopSize) ->
+ M = fun(GenFun) ->
+ fun(Size) ->
+ GenFuns = lists:duplicate(NumRecArgs, GenFun),
+ AllGens =
+ proper_arith:insert(GenFuns, MyPos, OtherGens),
+ RecFun(AllGens, erlang:max(0,Size - 1))
+ end
+ end,
+ (y(M))(TopSize)
+ end,
+ NewRecArgs = clean_rec_args(OtherRecArgs),
+ {ok, {rec,NewRecFun,NewRecArgs}, State}.
+
+%% Y Combinator: Read more at http://bc.tech.coop/blog/070611.html.
+-spec y(fun((fun((T) -> S)) -> fun((T) -> S))) -> fun((T) -> S).
+y(M) ->
+ G = fun(F) ->
+ M(fun(A) -> (F(F))(A) end)
+ end,
+ G(G).
+
+-spec process_list(mod_name(), [abs_type() | ret_type()], state(), stack(),
+ var_dict()) -> rich_result2([ret_type()],state()).
+process_list(Mod, RawTypes, State, Stack, VarDict) ->
+ Process = fun({simple,_FinType} = Type, {ok,Types,State1}) ->
+ {ok, [Type|Types], State1};
+ ({rec,_RecFun,_RecArgs} = Type, {ok,Types,State1}) ->
+ {ok, [Type|Types], State1};
+ (TypeForm, {ok,Types,State1}) ->
+ case convert(Mod, TypeForm, State1, Stack, VarDict) of
+ {ok,Type,State2} -> {ok,[Type|Types],State2};
+ {error,_} = Err -> Err
+ end;
+ (_RawType, {error,_} = Err) ->
+ Err
+ end,
+ case lists:foldl(Process, {ok,[],State}, RawTypes) of
+ {ok,RevTypes,NewState} ->
+ {ok, lists:reverse(RevTypes), NewState};
+ {error,_Reason} = Error ->
+ Error
+ end.
+
+-spec convert_integer(abs_expr(), state()) -> rich_result2(ret_type(),state()).
+convert_integer(Expr, State) ->
+ case eval_int(Expr) of
+ {ok,Int} -> {ok, {simple,proper_types:exactly(Int)}, State};
+ error -> expr_error(invalid_int_const, Expr)
+ end.
+
+-spec eval_int(abs_expr()) -> tagged_result(integer()).
+eval_int(Expr) ->
+ NoBindings = erl_eval:new_bindings(),
+ try erl_eval:expr(Expr, NoBindings) of
+ {value,Value,_NewBindings} when is_integer(Value) ->
+ {ok, Value};
+ _ ->
+ error
+ catch
+ error:_ ->
+ error
+ end.
+
+-spec expr_error(atom(), abs_expr()) -> {'error',term()}.
+expr_error(Reason, Expr) ->
+ {error, {Reason,lists:flatten(erl_pp:expr(Expr))}}.
+
+-spec expr_error(atom(), abs_expr(), abs_expr()) -> {'error',term()}.
+expr_error(Reason, Expr1, Expr2) ->
+ Str1 = lists:flatten(erl_pp:expr(Expr1)),
+ Str2 = lists:flatten(erl_pp:expr(Expr2)),
+ {error, {Reason,Str1,Str2}}.
+
+-spec base_case_error(stack()) -> {'error',term()}.
+%% TODO: This might confuse, since it doesn't record the arguments to parametric
+%% types or the type subsitutions of a record.
+base_case_error([{Mod,type,Name,Args} | _Upper]) ->
+ Arity = length(Args),
+ {error, {no_base_case,{Mod,type,Name,Arity}}};
+base_case_error([{Mod,record,Name,_SubstsDict} | _Upper]) ->
+ {error, {no_base_case,{Mod,record,Name}}}.
+
+
+%%------------------------------------------------------------------------------
+%% Helper datatypes handling functions
+%%------------------------------------------------------------------------------
+
+-spec stack_position(full_type_ref(), stack()) -> 'none' | pos_integer().
+stack_position(FullTypeRef, Stack) ->
+ SameType = fun(A) -> same_full_type_ref(A,FullTypeRef) end,
+ case proper_arith:find_first(SameType, Stack) of
+ {Pos,_} -> Pos;
+ none -> none
+ end.
+
+-spec partition_by_toplevel(rec_args(), stack(), boolean()) ->
+ {rec_args(),[position()],rec_args(),[position()]}.
+partition_by_toplevel(RecArgs, [], _OnlyInstanceAccepting) ->
+ {[],[],RecArgs,lists:seq(1,length(RecArgs))};
+partition_by_toplevel(RecArgs, [_Parent | _Upper], _OnlyInstanceAccepting)
+ when is_atom(_Parent) ->
+ {[],[],RecArgs,lists:seq(1,length(RecArgs))};
+partition_by_toplevel(RecArgs, [Parent | _Upper], OnlyInstanceAccepting) ->
+ partition_rec_args(Parent, RecArgs, OnlyInstanceAccepting).
+
+-spec at_toplevel(rec_args(), stack()) -> boolean().
+at_toplevel(RecArgs, Stack) ->
+ case partition_by_toplevel(RecArgs, Stack, false) of
+ {[],[],_,_} -> false;
+ _ -> true
+ end.
+
+-spec partition_rec_args(full_type_ref(), rec_args(), boolean()) ->
+ {rec_args(),[position()],rec_args(),[position()]}.
+partition_rec_args(FullTypeRef, RecArgs, OnlyInstanceAccepting) ->
+ SameType =
+ case OnlyInstanceAccepting of
+ true -> fun({false,_T}) -> false
+ ; ({_B,T}) -> same_full_type_ref(T,FullTypeRef) end;
+ false -> fun({_B,T}) -> same_full_type_ref(T,FullTypeRef) end
+ end,
+ proper_arith:partition(SameType, RecArgs).
+
+%% Tuples can be of 0 arity, unions of 1 and wunions at least of 2.
+-spec combine_ret_types([ret_type()], {'tuple',boolean()} | 'union'
+ | 'wunion') -> ret_type().
+combine_ret_types(RetTypes, EnclosingType) ->
+ case lists:all(fun is_simple_ret_type/1, RetTypes) of
+ true ->
+ %% This should never happen for wunion.
+ Combine = case EnclosingType of
+ {tuple,false} -> fun proper_types:tuple/1;
+ {tuple,true} -> fun proper_types:fixed_list/1;
+ union -> fun proper_types:union/1
+ end,
+ FinTypes = [T || {simple,T} <- RetTypes],
+ {simple, Combine(FinTypes)};
+ false ->
+ NumTypes = length(RetTypes),
+ {RevRecFuns,RevRecArgsList,NumRecs} =
+ lists:foldl(fun add_ret_type/2, {[],[],0}, RetTypes),
+ RecFuns = lists:reverse(RevRecFuns),
+ RecArgsList = lists:reverse(RevRecArgsList),
+ RecArgLens = [length(RecArgs) || RecArgs <- RecArgsList],
+ RecFunInfo = {NumTypes,NumRecs,RecArgLens,RecFuns},
+ FlatRecArgs = lists:flatten(RecArgsList),
+ {NewRecFun,NewRecArgs} =
+ case EnclosingType of
+ {tuple,ToList} ->
+ {tuple_rec_fun(RecFunInfo,ToList),
+ soft_clean_rec_args(FlatRecArgs,RecFunInfo,ToList)};
+ union ->
+ {union_rec_fun(RecFunInfo),clean_rec_args(FlatRecArgs)};
+ wunion ->
+ {wunion_rec_fun(RecFunInfo),
+ clean_rec_args(FlatRecArgs)}
+ end,
+ {rec, NewRecFun, NewRecArgs}
+ end.
+
+-spec tuple_rec_fun(rec_fun_info(), boolean()) -> rec_fun().
+tuple_rec_fun({_NumTypes,NumRecs,RecArgLens,RecFuns}, ToList) ->
+ Combine = case ToList of
+ true -> fun proper_types:fixed_list/1;
+ false -> fun proper_types:tuple/1
+ end,
+ fun(AllGFs,TopSize) ->
+ Size = TopSize div NumRecs,
+ GFsList = proper_arith:unflatten(AllGFs, RecArgLens),
+ ArgsList = [[GenFuns,Size] || GenFuns <- GFsList],
+ ZipFun = fun erlang:apply/2,
+ Combine(lists:zipwith(ZipFun, RecFuns, ArgsList))
+ end.
+
+-spec union_rec_fun(rec_fun_info()) -> rec_fun().
+union_rec_fun({_NumTypes,_NumRecs,RecArgLens,RecFuns}) ->
+ fun(AllGFs,Size) ->
+ GFsList = proper_arith:unflatten(AllGFs, RecArgLens),
+ ArgsList = [[GenFuns,Size] || GenFuns <- GFsList],
+ ZipFun = fun(F,A) -> ?LAZY(apply(F,A)) end,
+ proper_types:union(lists:zipwith(ZipFun, RecFuns, ArgsList))
+ end.
+
+-spec wunion_rec_fun(rec_fun_info()) -> rec_fun().
+wunion_rec_fun({NumTypes,_NumRecs,RecArgLens,RecFuns}) ->
+ fun(AllGFs,Size) ->
+ GFsList = proper_arith:unflatten(AllGFs, RecArgLens),
+ ArgsList = [[GenFuns,Size] || GenFuns <- GFsList],
+ ZipFun = fun(W,F,A) -> {W,?LAZY(apply(F,A))} end,
+ RecWeight = erlang:max(1, Size div (NumTypes - 1)),
+ Weights = [1 | lists:duplicate(NumTypes - 1, RecWeight)],
+ WeightedChoices = lists:zipwith3(ZipFun, Weights, RecFuns, ArgsList),
+ proper_types:wunion(WeightedChoices)
+ end.
+
+-spec add_ret_type(ret_type(), {[rec_fun()],[rec_args()],non_neg_integer()}) ->
+ {[rec_fun()],[rec_args()],non_neg_integer()}.
+add_ret_type({simple,FinType}, {RecFuns,RecArgsList,NumRecs}) ->
+ {[fun([],_) -> FinType end | RecFuns], [[] | RecArgsList], NumRecs};
+add_ret_type({rec,RecFun,RecArgs}, {RecFuns,RecArgsList,NumRecs}) ->
+ {[RecFun | RecFuns], [RecArgs | RecArgsList], NumRecs + 1}.
+
+-spec is_simple_ret_type(ret_type()) -> boolean().
+is_simple_ret_type({simple,_FinType}) ->
+ true;
+is_simple_ret_type({rec,_RecFun,_RecArgs}) ->
+ false.
+
+-spec clean_rec_args(rec_args()) -> rec_args().
+clean_rec_args(RecArgs) ->
+ [{false,F} || {_B,F} <- RecArgs].
+
+-spec soft_clean_rec_args(rec_args(), rec_fun_info(), boolean()) -> rec_args().
+soft_clean_rec_args(RecArgs, RecFunInfo, ToList) ->
+ soft_clean_rec_args_tr(RecArgs, [], RecFunInfo, ToList, false, 1).
+
+-spec soft_clean_rec_args_tr(rec_args(), rec_args(), rec_fun_info(), boolean(),
+ boolean(), position()) -> rec_args().
+soft_clean_rec_args_tr([], Acc, _RecFunInfo, _ToList, _FoundListInst, _Pos) ->
+ lists:reverse(Acc);
+soft_clean_rec_args_tr([{{list,_NonEmpty,_AltRecFun},FTRef} | Rest], Acc,
+ RecFunInfo, ToList, true, Pos) ->
+ NewArg = {false,FTRef},
+ soft_clean_rec_args_tr(Rest, [NewArg|Acc], RecFunInfo, ToList, true, Pos+1);
+soft_clean_rec_args_tr([{{list,NonEmpty,AltRecFun},FTRef} | Rest], Acc,
+ RecFunInfo, ToList, false, Pos) ->
+ {NumTypes,NumRecs,RecArgLens,RecFuns} = RecFunInfo,
+ AltRecFunPos = get_group(Pos, RecArgLens),
+ AltRecFuns = proper_arith:list_update(AltRecFunPos, AltRecFun, RecFuns),
+ AltRecFunInfo = {NumTypes,NumRecs,RecArgLens,AltRecFuns},
+ NewArg = {{list,NonEmpty,tuple_rec_fun(AltRecFunInfo,ToList)},FTRef},
+ soft_clean_rec_args_tr(Rest, [NewArg|Acc], RecFunInfo, ToList, true, Pos+1);
+soft_clean_rec_args_tr([Arg | Rest], Acc, RecFunInfo, ToList, FoundListInst,
+ Pos) ->
+ soft_clean_rec_args_tr(Rest, [Arg | Acc], RecFunInfo, ToList, FoundListInst,
+ Pos+1).
+
+-spec get_group(pos_integer(), [non_neg_integer()]) -> pos_integer().
+get_group(Pos, AllMembers) ->
+ get_group_tr(Pos, AllMembers, 1).
+
+-spec get_group_tr(pos_integer(), [non_neg_integer()], pos_integer()) ->
+ pos_integer().
+get_group_tr(Pos, [Members | Rest], GroupNum) ->
+ case Pos =< Members of
+ true -> GroupNum;
+ false -> get_group_tr(Pos - Members, Rest, GroupNum + 1)
+ end.
+
+-spec same_full_type_ref(full_type_ref(), term()) -> boolean().
+same_full_type_ref({SameMod,type,SameName,Args1},
+ {SameMod,type,SameName,Args2}) ->
+ length(Args1) =:= length(Args2)
+ andalso lists:all(fun({A,B}) -> same_ret_type(A,B) end,
+ lists:zip(Args1, Args2));
+same_full_type_ref({SameMod,record,SameName,SubstsDict1},
+ {SameMod,record,SameName,SubstsDict2}) ->
+ same_substs_dict(SubstsDict1, SubstsDict2);
+same_full_type_ref(_, _) ->
+ false.
+
+-spec same_ret_type(ret_type(), ret_type()) -> boolean().
+same_ret_type({simple,FinType1}, {simple,FinType2}) ->
+ same_fin_type(FinType1, FinType2);
+same_ret_type({rec,RecFun1,RecArgs1}, {rec,RecFun2,RecArgs2}) ->
+ NumRecArgs = length(RecArgs1),
+ length(RecArgs2) =:= NumRecArgs
+ andalso lists:all(fun({A1,A2}) -> same_rec_arg(A1,A2,NumRecArgs) end,
+ lists:zip(RecArgs1,RecArgs2))
+ andalso same_rec_fun(RecFun1, RecFun2, NumRecArgs);
+same_ret_type(_, _) ->
+ false.
+
+%% TODO: Is this too strict?
+-spec same_rec_arg(rec_arg(), rec_arg(), arity()) -> boolean().
+same_rec_arg({{list,SameBool,AltRecFun1},FTRef1},
+ {{list,SameBool,AltRecFun2},FTRef2}, NumRecArgs) ->
+ same_rec_fun(AltRecFun1, AltRecFun2, NumRecArgs)
+ andalso same_full_type_ref(FTRef1, FTRef2);
+same_rec_arg({true,FTRef1}, {true,FTRef2}, _NumRecArgs) ->
+ same_full_type_ref(FTRef1, FTRef2);
+same_rec_arg({false,FTRef1}, {false,FTRef2}, _NumRecArgs) ->
+ same_full_type_ref(FTRef1, FTRef2);
+same_rec_arg(_, _, _NumRecArgs) ->
+ false.
+
+-spec same_substs_dict(substs_dict(), substs_dict()) -> boolean().
+same_substs_dict(SubstsDict1, SubstsDict2) ->
+ SameKVPair = fun({{_K,V1},{_K,V2}}) -> same_ret_type(V1,V2);
+ (_) -> false
+ end,
+ SubstsKVList1 = lists:sort(dict:to_list(SubstsDict1)),
+ SubstsKVList2 = lists:sort(dict:to_list(SubstsDict2)),
+ length(SubstsKVList1) =:= length(SubstsKVList2)
+ andalso lists:all(SameKVPair, lists:zip(SubstsKVList1,SubstsKVList2)).
+
+-spec same_fin_type(fin_type(), fin_type()) -> boolean().
+same_fin_type(Type1, Type2) ->
+ proper_types:equal_types(Type1, Type2).
+
+-spec same_rec_fun(rec_fun(), rec_fun(), arity()) -> boolean().
+same_rec_fun(RecFun1, RecFun2, NumRecArgs) ->
+ %% It's ok that we return a type, even if there's a 'true' for use of
+ %% an instance.
+ GenFun = fun(_Size) -> proper_types:exactly('$dummy') end,
+ GenFuns = lists:duplicate(NumRecArgs,GenFun),
+ same_fin_type(RecFun1(GenFuns,0), RecFun2(GenFuns,0)).
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 eef2074e0c..7db1100597 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
@@ -145,7 +145,7 @@ adt_t4() ->
A = simple1_adt:n1(),
B = simple1_adt:n2(),
A = A, % OK
- A = B. % opaque term
+ A = B. % opaque terms
adt_t7() ->
A = simple1_adt:n1(),
@@ -178,7 +178,7 @@ c2(A, B) ->
c2() ->
A = simple1_adt:d1(),
B = simple1_adt:d2(),
- if A =< B -> ok end. % opaque term
+ if A =< B -> ok end. % opaque terms
c3() ->
B = simple1_adt:d2(),
@@ -516,7 +516,7 @@ eq1() ->
A = simple1_adt:d2(),
B = simple1_adt:d1(),
if
- A == B -> % opaque term
+ A == B -> % opaque terms
0;
A == A ->
1;
@@ -555,7 +555,7 @@ c6(A, B) ->
c7(A, B) ->
A = simple1_adt:d1(),
B = simple1_adt:d2(),
- A =< B. % opaque term
+ A =< B. % opaque terms
c8() ->
D = digraph:new(),
diff --git a/lib/dialyzer/test/options1_SUITE_data/dialyzer_options b/lib/dialyzer/test/options1_SUITE_data/dialyzer_options
index 65d233ac0d..c612e77d3e 100644
--- a/lib/dialyzer/test/options1_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/options1_SUITE_data/dialyzer_options
@@ -1,2 +1,2 @@
-{dialyzer_options, [{include_dirs, ["my_include"]}, {defines, [{'COMPILER_VSN', 42}]}, {warnings, [no_improper_lists, no_unknown]}]}.
+{dialyzer_options, [{include_dirs, ["my_include"]}, {defines, [{'COMPILER_VSN', 42}]}, {warnings, [no_improper_lists]}]}.
{time_limit, 30}.
diff --git a/lib/dialyzer/test/options1_SUITE_data/my_include/erl_bits.hrl b/lib/dialyzer/test/options1_SUITE_data/my_include/erl_bits.hrl
index 45045ebb33..9c1526dd98 100644
--- a/lib/dialyzer/test/options1_SUITE_data/my_include/erl_bits.hrl
+++ b/lib/dialyzer/test/options1_SUITE_data/my_include/erl_bits.hrl
@@ -1,12 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.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.erlang.org/EPL1_0.txt
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Original Code is Erlang-4.7.3, December, 1998.
%%
diff --git a/lib/dialyzer/test/options1_SUITE_data/my_include/erl_compile.hrl b/lib/dialyzer/test/options1_SUITE_data/my_include/erl_compile.hrl
index c10ffa235c..1e7f9097d1 100644
--- a/lib/dialyzer/test/options1_SUITE_data/my_include/erl_compile.hrl
+++ b/lib/dialyzer/test/options1_SUITE_data/my_include/erl_compile.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_asm.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_asm.erl
index e3746f3fb6..0bd6e5b537 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_asm.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_asm.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: beam_asm.erl,v 1.1 2008/12/17 09:53:40 mikpe Exp $
-%%
%% Purpose : Assembler for threaded Beam.
-module(beam_asm).
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_block.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_block.erl
index 0e3589cdf5..c909490be6 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_block.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_block.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_bool.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_bool.erl
index b7b28a41a5..4bc598cc6f 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_bool.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_bool.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: beam_bool.erl,v 1.1 2008/12/17 09:53:41 mikpe Exp $
-%%
%% Purpose: Optimizes booleans in guards.
-module(beam_bool).
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl
index 4fc4e89ce9..88d0ea83bf 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_dict.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_dict.erl
index 08eca2fc00..b35167aa77 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_dict.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_dict.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_flatten.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_flatten.erl
index 5c08c6a797..7895e391a6 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_flatten.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_flatten.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_jump.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_jump.erl
index b3c234c7bb..3faeba1e55 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_jump.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_jump.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_listing.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_listing.erl
index 5def6816b2..fec8da2d31 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_listing.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_listing.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl
index f59cc897d6..65a30d3066 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: beam_type.erl,v 1.1 2008/12/17 09:53:41 mikpe Exp $
-%%
%% Purpose : Type-based optimisations.
-module(beam_type).
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl
index 87c1c54d0f..8fe43163f6 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl
@@ -1,18 +1,18 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: beam_validator.erl,v 1.1 2008/12/17 09:53:41 mikpe Exp $
-module(beam_validator).
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl.erl
index e4bdfc7dbe..c71b835123 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Richard Carlsson.
%% Copyright (C) 1999-2002 Richard Carlsson.
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_clauses.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_clauses.erl
index 16e4b37a10..0fd623527d 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_clauses.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_clauses.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Richard Carlsson.
%% Copyright (C) 1999-2002 Richard Carlsson.
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl
index cd332279d1..95d2076ccf 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Richard Carlsson.
%% Copyright (C) 1999-2002 Richard Carlsson.
@@ -17,7 +18,6 @@
%% $Id: cerl_inline.erl,v 1.1 2008/12/17 09:53:41 mikpe Exp $
%%
%% Core Erlang inliner.
-
%% =====================================================================
%%
%% This is an implementation of the algorithm by Waddell and Dybvig
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_trees.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_trees.erl
index afe7c8708b..e8d5d3c9dc 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_trees.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_trees.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Richard Carlsson.
%% Copyright (C) 1999-2002 Richard Carlsson.
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl
index 9b56d384ab..7e5ccde2fd 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: compile.erl,v 1.1 2008/12/17 09:53:42 mikpe Exp $
-%%
%% Purpose: Run the Erlang compiler.
-module(compile).
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lib.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lib.erl
index 1fe45d5308..f78a79cdc4 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lib.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lib.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lint.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lint.erl
index 773d1e53c8..1a037c0d1b 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lint.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_lint.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: core_lint.erl,v 1.1 2008/12/17 09:53:42 mikpe Exp $
-%%
%% Purpose : Do necessary checking of Core Erlang code.
%% Check Core module for errors. Seeing this module is used in the
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.erl
index 77c33c561b..4e5badcf95 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.erl
@@ -19,16 +19,17 @@ abstract(Term) -> core_lib:make_literal(Term).
normalise(Core) -> core_lib:literal_value(Core).
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.hrl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.hrl
index 3d60360f47..b7ac40379c 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.hrl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_parse.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_pp.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_pp.erl
index 2bfbcb85e2..cb8d847e6d 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_pp.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_pp.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl
index 2f9f6a2bcc..639e64c74b 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/erl_bifs.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/erl_bifs.erl
index 1dbeefb5ac..c41b1cb707 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/erl_bifs.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/erl_bifs.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_expand_pmod.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_expand_pmod.erl
index cd13f468b2..d9233007b9 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_expand_pmod.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_expand_pmod.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_attributes.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_attributes.erl
index 21d28868f0..98a37991a6 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_attributes.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_attributes.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl
index 590cc682c9..49a95a95e5 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl
index 6b787e8c95..33a322b466 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: v3_codegen.erl,v 1.1 2008/12/17 09:53:42 mikpe Exp $
-%%
%% Purpose : Code generator for Beam.
%% The following assumptions have been made:
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl
index 45a8bc4ad9..6d3bc8622d 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: v3_core.erl,v 1.1 2008/12/17 09:53:42 mikpe Exp $
-%%
%% Purpose : Transform normal Erlang to Core Erlang
%% At this stage all preprocessing has been done. All that is left are
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl
index ecba19b1d1..35e3c59d0a 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.hrl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.hrl
index 6e97d4d66a..f6688a66e2 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.hrl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel_pp.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel_pp.erl
index 41f59b7a81..df5be895b3 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel_pp.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel_pp.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.erl
index 9579b5f46a..d4dd6a8cfd 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.hrl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.hrl
index 4d183b7234..4bb8389273 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.hrl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_life.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/options2_SUITE_data/src/kernel/global.erl b/lib/dialyzer/test/options2_SUITE_data/src/kernel/global.erl
index 4778a39a3c..302adaae96 100644
--- a/lib/dialyzer/test/options2_SUITE_data/src/kernel/global.erl
+++ b/lib/dialyzer/test/options2_SUITE_data/src/kernel/global.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/plt_SUITE.erl b/lib/dialyzer/test/plt_SUITE.erl
index aee9f449a6..6ebe23b54b 100644
--- a/lib/dialyzer/test/plt_SUITE.erl
+++ b/lib/dialyzer/test/plt_SUITE.erl
@@ -1,17 +1,20 @@
%% This suite is the only hand made and simply
-%% checks if we can build a plt.
+%% checks if we can build and update a plt.
-module(plt_SUITE).
-include_lib("common_test/include/ct.hrl").
-include("dialyzer_test_constants.hrl").
--export([suite/0, all/0, build_plt/1]).
+-export([suite/0, all/0, build_plt/1, beam_tests/1, update_plt/1,
+ local_fun_same_as_callback/1,
+ remove_plt/1, run_plt_check/1, run_succ_typings/1]).
suite() ->
[{timetrap, ?plt_timeout}].
-all() -> [build_plt].
+all() -> [build_plt, beam_tests, update_plt, run_plt_check,
+ remove_plt, run_succ_typings, local_fun_same_as_callback].
build_plt(Config) ->
OutDir = ?config(priv_dir, Config),
@@ -19,3 +22,244 @@ build_plt(Config) ->
ok -> ok;
fail -> ct:fail(plt_build_fail)
end.
+
+beam_tests(Config) when is_list(Config) ->
+ Prog = <<"
+ -module(no_auto_import).
+
+ %% Copied from erl_lint_SUITE.erl, clash6
+
+ -export([size/1]).
+
+ size([]) ->
+ 0;
+ size({N,_}) ->
+ N;
+ size([_|T]) ->
+ 1+size(T).
+ ">>,
+ Opts = [no_auto_import],
+ {ok, BeamFile} = compile(Config, Prog, no_auto_import, Opts),
+ [] = run_dialyzer(plt_build, [BeamFile], []),
+ ok.
+
+run_plt_check(Config) when is_list(Config) ->
+ Mod1 = <<"
+ -module(run_plt_check1).
+ ">>,
+
+ Mod2A = <<"
+ -module(run_plt_check2).
+ ">>,
+
+ {ok, BeamFile1} = compile(Config, Mod1, run_plt_check1, []),
+ {ok, BeamFile2} = compile(Config, Mod2A, run_plt_check2, []),
+ [] = run_dialyzer(plt_build, [BeamFile1, BeamFile2], []),
+
+ Mod2B = <<"
+ -module(run_plt_check2).
+
+ -export([call/1]).
+
+ call(X) -> run_plt_check1:call(X).
+ ">>,
+
+ {ok, BeamFile2} = compile(Config, Mod2B, run_plt_check2, []),
+
+ % callgraph warning as run_plt_check2:call/1 makes a call to unexported
+ % function run_plt_check1:call/1.
+ [_] = run_dialyzer(plt_check, [], []),
+
+ ok.
+
+run_succ_typings(Config) when is_list(Config) ->
+ Mod1A = <<"
+ -module(run_succ_typings1).
+
+ -export([call/0]).
+
+ call() -> a.
+ ">>,
+
+ {ok, BeamFile1} = compile(Config, Mod1A, run_succ_typings1, []),
+ [] = run_dialyzer(plt_build, [BeamFile1], []),
+
+ Mod1B = <<"
+ -module(run_succ_typings1).
+
+ -export([call/0]).
+
+ call() -> b.
+ ">>,
+
+ Mod2 = <<"
+ -module(run_succ_typings2).
+
+ -export([call/0]).
+
+ -spec call() -> b.
+ call() -> run_succ_typings1:call().
+ ">>,
+
+ {ok, BeamFile1} = compile(Config, Mod1B, run_succ_typings1, []),
+ {ok, BeamFile2} = compile(Config, Mod2, run_succ_typings2, []),
+ % contract types warning as run_succ_typings2:call/0 makes a call to
+ % run_succ_typings1:call/0, which returns a (not b) in the PLT.
+ [_] = run_dialyzer(succ_typings, [BeamFile2], [{check_plt, false}]),
+ % warning not returned as run_succ_typings1 is updated in the PLT.
+ [] = run_dialyzer(succ_typings, [BeamFile2], [{check_plt, true}]),
+
+ ok.
+
+%%% [James Fish:]
+%%% If a function is removed from a module and the module has previously
+%%% been added to a PLT, the function will not be removed from PLT when
+%%% the PLT is checked. This results in dialyzer failing to produce a
+%%% callgraph warning when doing success typings analysis if the remove
+%%% function is still called in another module
+%%% As the function is not removed from the PLT a prior warning, such as a
+%%% contract types warning, might be emitted when the removed function
+%%% nolonger exists.
+update_plt(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Prog1 = <<"-module(plt_gc).
+ -export([one/0]).
+ one() ->
+ one.">>,
+ {ok, Beam} = compile(Config, Prog1, plt_gc, []),
+
+ ErlangBeam = case code:where_is_file("erlang.beam") of
+ non_existing ->
+ filename:join([code:root_dir(),
+ "erts", "preloaded", "ebin",
+ "erlang.beam"]);
+ EBeam ->
+ EBeam
+ end,
+ Plt = filename:join(PrivDir, "plt_gc.plt"),
+ Opts = [{check_plt, true}, {from, byte_code}],
+ [] = dialyzer:run([{analysis_type, plt_build},
+ {files, [Beam, ErlangBeam]},
+ {output_plt, Plt}] ++ Opts),
+
+ Prog2 = <<"-module(plt_gc).
+ -export([two/0]).
+ two() ->
+ two.">>,
+ {ok, Beam} = compile(Config, Prog2, plt_gc, []),
+
+ Test = <<"-module(test).
+ -export([test/0]).
+ -spec test() -> test.
+ test() ->
+ plt_gc:one().">>,
+ {ok, TestBeam} = compile(Config, Test, test, []),
+ [{warn_callgraph, _, {call_to_missing, [plt_gc, one, 0]}}] =
+ dialyzer:run([{analysis_type, succ_typings},
+ {files, [TestBeam]},
+ {init_plt, Plt}] ++ Opts),
+ ok.
+
+%%% If a behaviour module contains an non-exported function with the same name
+%%% as one of the behaviour's callbacks, the callback info was inadvertently
+%%% deleted from the PLT as the dialyzer_plt:delete_list/2 function was cleaning
+%%% up the callback table. This bug was reported by Brujo Benavides.
+
+local_fun_same_as_callback(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Prog1 =
+ <<"-module(bad_behaviour).
+ -callback bad() -> bad.
+ -export([publicly_bad/0]).
+
+ %% @doc This function is here just to avoid the 'unused' warning for bad/0
+ publicly_bad() -> bad().
+
+ %% @doc This function overlaps with the callback with the same name, and
+ %% that was an issue for dialyzer since it's a private function.
+ bad() -> bad.">>,
+ {ok, Beam} = compile(Config, Prog1, bad_behaviour, []),
+
+ ErlangBeam = case code:where_is_file("erlang.beam") of
+ non_existing ->
+ filename:join([code:root_dir(),
+ "erts", "preloaded", "ebin",
+ "erlang.beam"]);
+ EBeam ->
+ EBeam
+ end,
+ Plt = filename:join(PrivDir, "plt_bad_behaviour.plt"),
+ Opts = [{check_plt, true}, {from, byte_code}],
+ [] = dialyzer:run([{analysis_type, plt_build},
+ {files, [Beam, ErlangBeam]},
+ {output_plt, Plt}] ++ Opts),
+
+ Prog2 =
+ <<"-module(bad_child).
+ -behaviour(bad_behaviour).
+
+ -export([bad/0]).
+
+ %% @doc This function incorreclty implements bad_behaviour.
+ bad() -> not_bad.">>,
+ {ok, TestBeam} = compile(Config, Prog2, bad_child, []),
+
+ [{warn_behaviour, _,
+ {callback_type_mismatch,
+ [bad_behaviour,bad,0,"'not_bad'","'bad'"]}}] =
+ dialyzer:run([{analysis_type, succ_typings},
+ {files, [TestBeam]},
+ {init_plt, Plt}] ++ Opts),
+ ok.
+
+%%% [James Fish:]
+%%% Dialyzer always asserts that files and directories passed in its
+%%% options exist. Therefore it is not possible to remove a beam/module
+%%% from a PLT when the beam file no longer exists. Dialyzer should not to
+%%% check files exist on disk when removing from the PLT.
+remove_plt(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Prog1 = <<"-module(m1).
+ -export([t/0]).
+ t() ->
+ m2:a(a).">>,
+ {ok, Beam1} = compile(Config, Prog1, m1, []),
+
+ Prog2 = <<"-module(m2).
+ -export([a/1]).
+ a(A) when is_integer(A) -> A.">>,
+ {ok, Beam2} = compile(Config, Prog2, m2, []),
+
+ Plt = filename:join(PrivDir, "remove.plt"),
+ Opts = [{check_plt, true}, {from, byte_code}],
+
+ [{warn_return_no_exit, _, {no_return,[only_normal,t,0]}},
+ {warn_failing_call, _, {call, [m2,a,"('a')",_,_,_,_,_]}}] =
+ dialyzer:run([{analysis_type, plt_build},
+ {files, [Beam1, Beam2]},
+ {get_warnings, true},
+ {output_plt, Plt}] ++ Opts),
+
+ [] = dialyzer:run([{init_plt, Plt},
+ {files, [Beam2]},
+ {analysis_type, plt_remove}]),
+
+ [] = dialyzer:run([{analysis_type, succ_typings},
+ {files, [Beam1]},
+ {init_plt, Plt}] ++ Opts),
+ ok.
+
+compile(Config, Prog, Module, CompileOpts) ->
+ Source = lists:concat([Module, ".erl"]),
+ PrivDir = ?config(priv_dir,Config),
+ Filename = filename:join([PrivDir, Source]),
+ ok = file:write_file(Filename, Prog),
+ Opts = [{outdir, PrivDir}, debug_info | CompileOpts],
+ {ok, Module} = compile:file(Filename, Opts),
+ {ok, filename:join([PrivDir, lists:concat([Module, ".beam"])])}.
+
+run_dialyzer(Analysis, Files, Opts) ->
+ dialyzer:run([{analysis_type, Analysis},
+ {files, Files},
+ {from, byte_code} |
+ Opts]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/dialyzer_options b/lib/dialyzer/test/r9c_SUITE_data/dialyzer_options
index ba0e6b1ad7..e00e23bb66 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/r9c_SUITE_data/dialyzer_options
@@ -1,2 +1,2 @@
-{dialyzer_options, [{defines, [{vsn, 42}]}, {warnings, [no_unknown]}]}.
+{dialyzer_options, [{defines, [{vsn, 42}]}]}.
{time_limit, 20}.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_db.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_db.erl
index d5ddb9582b..87bd1343ee 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_db.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_db.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_records.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_records.hrl
index 6ba4877523..596746f57f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_records.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1_records.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl
index fd36f1657e..ed38b2f915 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct).
%% Compile Time functions for ASN.1 (e.g ASN.1 compiler).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl
index 4335d8efae..c26b8f851b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_check.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct_check).
%% Main Module for ASN.1 compile time functions
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl
index 695f648924..392896932a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_constructed_ber.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct_constructed_ber).
-export([gen_encode_sequence/3]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl
index 991240731e..9725da4d11 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_constructed_ber_bin_v2.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct_constructed_ber_bin_v2).
-export([gen_encode_sequence/3]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_per.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_per.erl
index a21c38f8a8..9731b7900b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_per.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_per.erl
@@ -1,13 +1,14 @@
-% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen.erl
index 5b33be9eff..85fa3da3b2 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_gen.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct_gen).
-include("asn1_records.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber.erl
index 765745dc13..1d065b3723 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_gen_ber.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct_gen_ber).
%% Generate erlang module which handles (PER) encode and decode for
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber_bin_v2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber_bin_v2.erl
index 89530d4017..9164ec6551 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_ber_bin_v2.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_gen_ber_bin_v2.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
-%%
-module(asn1ct_gen_ber_bin_v2).
%% Generate erlang module which handles (PER) encode and decode for
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per.erl
index b5c70fd856..b49ae07b6d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_gen_per.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1ct_gen_per).
%% Generate erlang module which handles (PER) encode and decode for
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per_rt2ct.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per_rt2ct.erl
index ddfa124048..bef1e328dd 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per_rt2ct.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_gen_per_rt2ct.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_gen_per_rt2ct.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1ct_gen_per_rt2ct).
%% Generate erlang module which handles (PER) encode and decode for
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_name.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_name.erl
index 1c7769998c..7904723f17 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_name.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_name.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser.yrl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser.yrl
index b2c1d70f6e..b81167e55e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser.yrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser.yrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl
index 07dacb73c8..5f8c7a0de8 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 2000, Ericsson Utvecklings
%% AB. All Rights Reserved.''
%%
%% $Id: asn1ct_parser2.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1ct_parser2).
-export([parse/1]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_pretty_format.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_pretty_format.erl
index 99dd246d5c..a573614418 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_pretty_format.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_pretty_format.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_tok.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_tok.erl
index b5ccc4a5d2..993bb1d08d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_tok.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_tok.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_value.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_value.erl
index 3d366a1a27..81968b9f92 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_value.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_value.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1ct_value.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1ct_value).
%% Generate Erlang values for ASN.1 types.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt.erl
index efac8daf6b..1455674c82 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl
index b0786200fc..5854f8edbd 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_ber_bin.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1rt_ber_bin).
%% encoding / decoding of BER
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl
index 2f25e35cd3..0457425445 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_ber_bin_v2.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1rt_ber_bin_v2).
%% encoding / decoding of BER
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_check.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_check.erl
index cfda8a2a88..1606352fad 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_check.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_check.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_check.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1rt_check).
-include("asn1_records.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_driver_handler.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_driver_handler.erl
index 5200f9d2d9..bf865be1f8 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_driver_handler.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_driver_handler.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_driver_handler.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
-%%
-module(asn1rt_driver_handler).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl
index 4999dde2cc..b163aa24ac 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_per.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
-%%
-module(asn1rt_per).
%% encoding / decoding of PER aligned
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl
index 8b4512b58e..15986cc217 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_per_bin.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
-%%
-module(asn1rt_per_bin).
%% encoding / decoding of PER aligned
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl
index 4781c81955..43d9bef54e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_per_bin_rt2ct.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
-%%
-module(asn1rt_per_bin_rt2ct).
%% encoding / decoding of PER aligned
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_v1.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_v1.erl
index 90ffb0cb1c..45cee55c8a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_v1.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_v1.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: asn1rt_per_v1.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
-%%
-module(asn1rt_per_v1).
%% encoding / decoding of PER aligned
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_history.sgml b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_history.sgml
index 3b50c1b73f..19516ca300 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_history.sgml
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_history.sgml
@@ -1,15 +1,16 @@
<!doctype chapter PUBLIC "-//Stork//DTD chapter//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
+ ``Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_latest.sgml b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_latest.sgml
index ff1f5adfa2..ff1c315697 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_latest.sgml
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/notes_latest.sgml
@@ -1,15 +1,16 @@
<!doctype chapter PUBLIC "-//Stork//DTD chapter//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
+ ``Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/Makefile b/lib/dialyzer/test/r9c_SUITE_data/src/inets/Makefile
index be63eb73b2..2a4ae21c1e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/Makefile
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
+# ``Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl
index 312bb3a5c8..4f0ca99cce 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: ftp.erl,v 1.2 2009/03/03 01:55:01 kostis Exp $
-%%
-module(ftp).
-behaviour(gen_server).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl
index a732f23aec..cf05431f5a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl
@@ -1,19 +1,19 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
%% All Rights Reserved.''
%%
-%%
%%% This version of the HTTP/1.1 client implements:
%%% - RFC 2616 HTTP 1.1 client part
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.hrl
index 6904a2379f..cf5101ff82 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl
index 4f6c43710b..ebefcd7ad7 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl
@@ -1,19 +1,19 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
%% All Rights Reserved.''
%%
-%%
%%% File : http_lib.erl
%%% Author : Johan Blom <[email protected]>
%%% Description : Generic, HTTP specific helper functions
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_handler.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_handler.erl
index 8e5e1c709a..920948164e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_handler.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_handler.erl
@@ -1,19 +1,19 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
%% All Rights Reserved.''
%%
-%%
%%% TODO:
%%% - If an error is returned when sending a request, don't use this
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl
index 29659ce1ce..45beaa84f7 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl
@@ -1,19 +1,19 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
%% All Rights Reserved.''
%%
-%%
%% Created : 18 Dec 2001 by Johan Blom <[email protected]>
%%
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.erl
index 3199e4430d..34be2c72b9 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.hrl
index 015c1b1e2d..ddee087253 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor.erl
index 7bf2d5d868..66f5055c19 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: httpd_acceptor.erl,v 1.1 2008/12/17 09:53:33 mikpe Exp $
-%%
-module(httpd_acceptor).
-include("httpd.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor_sup.erl
index 86c31ad5df..e8b232788b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_acceptor_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_conf.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_conf.erl
index 69419b1eb3..271f5822cf 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_conf.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_conf.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_example.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_example.erl
index 4aec440db3..3c3fb6cea3 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_example.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_example.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl
index 704cb1f319..85e06f43b6 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: httpd_manager.erl,v 1.1 2008/12/17 09:53:34 mikpe Exp $
-%%
-module(httpd_manager).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_misc_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_misc_sup.erl
index e671f05206..25027b8384 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_misc_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_misc_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl
index 2f4163de00..d7a698d65a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_request_handler.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_request_handler.erl
index b2d375ceff..ebda5c6562 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_request_handler.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_request_handler.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: httpd_request_handler.erl,v 1.1 2008/12/17 09:53:34 mikpe Exp $
-%%
-module(httpd_request_handler).
%% app internal api
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl
index 1685cbc129..47c7fc1b8d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_socket.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_socket.erl
index 375b43784b..fff28b7ac4 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_socket.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_socket.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_sup.erl
index e7a3557c9d..fb361e1dcd 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_sup.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: httpd_sup.erl,v 1.1 2008/12/17 09:53:34 mikpe Exp $
-%%
%%----------------------------------------------------------------------
%% Purpose: The top supervisor for the inets application
%%----------------------------------------------------------------------
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_util.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_util.erl
index 045e6f6516..7c78673be2 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_util.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_util.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.erl
index f676eb4c99..62c428c0d5 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.hrl
index cecaf693d3..f6dc211879 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_verbosity.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/inets_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/inets_sup.erl
index 878fa2c54b..9f2c85a117 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/inets_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/inets_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl
index 0a96560c92..6b872d7c95 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_actions.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_actions.erl
index 47395d4c12..658209ddbd 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_actions.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_actions.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_alias.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_alias.erl
index 6b8f7210c4..8a96c55f17 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_alias.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_alias.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.erl
index 9f3289c826..51c51a4691 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_auth.erl,v 1.1 2008/12/17 09:53:34 mikpe Exp $
-%%
-module(mod_auth).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.hrl
index 2b8ea6657f..889b81bc6f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_dets.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_dets.erl
index d947d6cf49..994ccae4cf 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_dets.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_dets.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_auth_dets.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_auth_dets).
%% dets authentication storage
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl
index ea2f0cb905..e42494ff76 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_plain.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_plain.erl
index 75cc60f288..6148cf21f0 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_plain.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_plain.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_auth_plain.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_auth_plain).
-include("httpd.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_server.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_server.erl
index 59402ac169..ec0aaa38b7 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_server.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_server.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_browser.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_browser.erl
index 1153a5fc47..93f539624b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_browser.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_browser.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl
index 8c91b6f430..0f63f4f032 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_cgi.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_cgi).
-export([do/1,env/3,status_code/1,load/2]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_dir.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_dir.erl
index 9dda6d9119..b84d2eec62 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_dir.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_dir.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_dir.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_dir).
-export([do/1]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_disk_log.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_disk_log.erl
index bb175f24b0..857c49faf2 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_disk_log.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_disk_log.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
index cb211749da..1203aeaa4c 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_get.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_get.erl
index 4136d31669..d493e1955e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_get.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_get.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_get.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_get).
-export([do/1]).
-include("httpd.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_head.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_head.erl
index ce71e6532e..269c0ecf35 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_head.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_head.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_head.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_head).
-export([do/1]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl
index 3806ce2e06..f600c65e92 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_htaccess.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_htaccess).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_include.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_include.erl
index eedbf4a669..0caf54af2e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_include.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_include.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mod_include.erl,v 1.1 2008/12/17 09:53:35 mikpe Exp $
-%%
-module(mod_include).
-export([do/1,parse/2,config/6,include/6,echo/6,fsize/6,flastmod/6,exec/6]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_log.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_log.erl
index a24ac425e6..495b6e0010 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_log.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_log.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl
index f623dc3ec8..4e6030d5e2 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl
index b818a15f32..76168f3890 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security.erl
index b4d52d1599..6c9ff3edc2 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security_server.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security_server.erl
index 81156c24e8..2bff313461 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security_server.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_security_server.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -38,7 +39,6 @@
%% to decide when such an operation should occur.
%%
-
-module(mod_security_server).
-include("httpd.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_trace.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_trace.erl
index 9f4d331d82..c09f2714c4 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_trace.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_trace.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/uri.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/uri.erl
index 9a4f77f87b..6dea6570ed 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/uri.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/uri.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Mobile Arts AB
%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB
@@ -19,7 +20,6 @@
%% Implements various scheme dependent subsets (e.g. HTTP, FTP etc) based on
%% RFC 2396, Uniform Resource Identifiers (URI): Generic Syntax
%% Created : 27 Jul 2001 by Johan Blom <[email protected]>
-%%
-module(uri).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/Makefile b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/Makefile
index 8b57868117..7417e9bd4b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/Makefile
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
+# ``Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
index 17cc9a953d..19b571ac47 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia.erl,v 1.2 2010/03/04 13:54:19 maria Exp $
-%%
%% This module exports the public interface of the Mnesia DBMS engine
-module(mnesia).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.hrl
index cd3cee974b..962dd15544 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_backup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_backup.erl
index f01310530e..17ffc1d0c7 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_backup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_backup.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_backup.erl,v 1.1 2008/12/17 09:53:37 mikpe Exp $
-%%
%0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl
index eb636a8447..fdbf3e4481 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_bup.erl,v 1.1 2008/12/17 09:53:37 mikpe Exp $
-%%
-module(mnesia_bup).
-export([
%% Public interface
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl
index 60a7a29861..2b5c77b3ba 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_checkpoint.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%
-module(mnesia_checkpoint).
%% TM callback interface
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint_sup.erl
index 36425537eb..55204816bd 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_controller.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_controller.erl
index 1d7f29bfbd..cf6a4c19cf 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_controller.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_controller.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_controller.erl,v 1.3 2010/03/04 13:54:19 maria Exp $
-%%
%% The mnesia_init process loads tables from local disc or from
%% another nodes. It also coordinates updates of the info about
%% where we can read and write tables.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_dumper.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_dumper.erl
index 116823a779..e76822743e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_dumper.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_dumper.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_event.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_event.erl
index 6053179194..fea2cdec02 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_event.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_event.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_event.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%
-module(mnesia_event).
-behaviour(gen_event).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag.erl
index 92ac51a0dc..04b9c1ea2f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag.erl
@@ -1,20 +1,20 @@
-%%% ``The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved via the world wide web at http://www.erlang.org/.
+%%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% 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.
%%%
%%% 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: mnesia_frag.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%%
%%%----------------------------------------------------------------------
%%% Purpose : Support tables so large that they need
%%% to be divided into several fragments.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_hash.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_hash.erl
index 591f2ce9c8..7f2165f58f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_hash.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_hash.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_frag_hash.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%
%%%----------------------------------------------------------------------
%%% Purpose : Implements hashing functionality for fragmented tables
%%%----------------------------------------------------------------------
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_old_hash.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_old_hash.erl
index 8dc128a42e..a9ecc48f4a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_old_hash.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_frag_old_hash.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_frag_old_hash.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%
%%%----------------------------------------------------------------------
%%% Purpose : Implements hashing functionality for fragmented tables
%%%----------------------------------------------------------------------
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_index.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_index.erl
index 650a2d1d3c..f4bcf961be 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_index.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_index.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_index.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%
%% Purpose: Handles index functionality in mnesia
-module(mnesia_index).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_kernel_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_kernel_sup.erl
index 015a42c749..2059f60949 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_kernel_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_kernel_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_late_loader.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_late_loader.erl
index b49cf22fd9..4008b9f4fc 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_late_loader.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_late_loader.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_lib.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_lib.erl
index 29a54936d4..4008f8d789 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_lib.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_lib.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_lib.erl,v 1.3 2009/07/01 15:45:40 kostis Exp $
-%%
%% This module contains all sorts of various which doesn't fit
%% anywhere else. Basically everything is exported.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl
index f21a8240aa..70fee1741e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_loader.erl,v 1.2 2010/03/04 13:54:19 maria Exp $
-%%
%%% Purpose : Loads tables from local disc or from remote node
-module(mnesia_loader).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl
index c24ccc5518..701aa8f598 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_locker.erl,v 1.2 2009/07/01 15:45:40 kostis Exp $
-%%
-module(mnesia_locker).
-export([
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_log.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_log.erl
index 47e8be32c0..8cea8c6ab2 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_log.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_log.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_log.erl,v 1.2 2009/07/01 15:45:40 kostis Exp $
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% This module administers three kinds of log files:
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
index a1c25b5120..d1ff09ce29 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_monitor.erl,v 1.1 2008/12/17 09:53:38 mikpe Exp $
-%%
-module(mnesia_monitor).
-behaviour(gen_server).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_recover.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_recover.erl
index cbb110fa6c..4dabd667f7 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_recover.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_recover.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_recover.erl,v 1.1 2008/12/17 09:53:39 mikpe Exp $
-%%
-module(mnesia_recover).
-behaviour(gen_server).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_registry.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_registry.erl
index a7e65506fa..e9f36be16b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_registry.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_registry.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl
index 395532e91b..ec07e1c1ab 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_schema.erl,v 1.2 2010/03/04 13:54:20 maria Exp $
-%%
%% In this module we provide a number of explicit functions
%% to maninpulate the schema. All these functions are called
%% within a special schema transaction.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_hook.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_hook.erl
index ad88bc6e6a..c3319251a6 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_hook.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_hook.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_sup.erl
index 227eec060f..3bd2b74642 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_snmp_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sp.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sp.erl
index bc52ad7f84..662785ad50 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sp.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sp.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_subscr.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_subscr.erl
index dc66451206..33333e8fea 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_subscr.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_subscr.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl
index 970e0e5f47..5bc93f6c4f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_text.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_text.erl
index d74f3bf07b..c831138f2d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_text.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_text.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_text.erl,v 1.2 2010/03/04 13:54:20 maria Exp $
-%%
-module(mnesia_text).
-export([parse/1, file/1, load_textfile/1, dump_to_textfile/1]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
index ac11087fa0..3e08354b5a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
@@ -1,20 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% 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: mnesia_tm.erl,v 1.2 2010/03/04 13:54:20 maria Exp $
-%%
-module(mnesia_tm).
-export([
diff --git a/lib/dialyzer/test/race_SUITE_data/dialyzer_options b/lib/dialyzer/test/race_SUITE_data/dialyzer_options
index 6992fc6c40..44e1720715 100644
--- a/lib/dialyzer/test/race_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/race_SUITE_data/dialyzer_options
@@ -1 +1 @@
-{dialyzer_options, [{warnings, [race_conditions, no_unknown]}]}.
+{dialyzer_options, [{warnings, [race_conditions]}]}.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1_suppressed.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1_suppressed.erl
new file mode 100644
index 0000000000..5134cc6f0b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1_suppressed.erl
@@ -0,0 +1,19 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args1_suppressed).
+-export([start/0]).
+
+-dialyzer({nowarn_function,start/0}).
+
+start() ->
+ F = fun(T) -> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, [{counter, N+1}])
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/small_SUITE_data/dialyzer_options b/lib/dialyzer/test/small_SUITE_data/dialyzer_options
index 0d91699e4d..50991c9bc5 100644
--- a/lib/dialyzer/test/small_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/small_SUITE_data/dialyzer_options
@@ -1 +1 @@
-{dialyzer_options, [{warnings, [no_unknown]}]}.
+{dialyzer_options, []}.
diff --git a/lib/dialyzer/test/small_SUITE_data/results/abs b/lib/dialyzer/test/small_SUITE_data/results/abs
new file mode 100644
index 0000000000..f229a6d036
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/abs
@@ -0,0 +1,9 @@
+
+abs.erl:12: Function i1/0 has no local return
+abs.erl:16: The pattern 'true' can never match the type 'false'
+abs.erl:23: Function i2/0 has no local return
+abs.erl:27: The pattern 'true' can never match the type 'false'
+abs.erl:34: Function i3/0 has no local return
+abs.erl:37: The pattern 'true' can never match the type 'false'
+abs.erl:45: Function i4/0 has no local return
+abs.erl:49: The pattern 'true' can never match the type 'false'
diff --git a/lib/dialyzer/test/small_SUITE_data/results/behaviour_info b/lib/dialyzer/test/small_SUITE_data/results/behaviour_info
new file mode 100644
index 0000000000..2da4d26acb
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/behaviour_info
@@ -0,0 +1,2 @@
+
+with_bad_format_status.erl:12: The inferred type for the 1st argument of format_status/2 ('bad_arg') is not a supertype of 'normal' | 'terminate', which is expected type for this argument in the callback of the gen_server behaviour
diff --git a/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed b/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed
new file mode 100644
index 0000000000..40733434f6
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed
@@ -0,0 +1,2 @@
+
+blame_contract_range_suppressed.erl:8: Function foo/0 has no local return
diff --git a/lib/dialyzer/test/small_SUITE_data/results/comparisons b/lib/dialyzer/test/small_SUITE_data/results/comparisons
index 642585d25e..5083d2695a 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/comparisons
+++ b/lib/dialyzer/test/small_SUITE_data/results/comparisons
@@ -1,50 +1,43 @@
comparisons.erl:100: The pattern 'true' can never match the type 'false'
-comparisons.erl:101: The pattern 'true' can never match the type 'false'
+comparisons.erl:101: The pattern 'false' can never match the type 'true'
comparisons.erl:102: The pattern 'false' can never match the type 'true'
-comparisons.erl:103: The pattern 'false' can never match the type 'true'
+comparisons.erl:103: The pattern 'true' can never match the type 'false'
comparisons.erl:104: The pattern 'true' can never match the type 'false'
-comparisons.erl:105: The pattern 'true' can never match the type 'false'
-comparisons.erl:107: The pattern 'true' can never match the type 'false'
-comparisons.erl:108: The pattern 'true' can never match the type 'false'
-comparisons.erl:109: The pattern 'false' can never match the type 'true'
-comparisons.erl:110: The pattern 'false' can never match the type 'true'
-comparisons.erl:111: The pattern 'true' can never match the type 'false'
-comparisons.erl:112: The pattern 'true' can never match the type 'false'
-comparisons.erl:113: The pattern 'false' can never match the type 'true'
-comparisons.erl:114: The pattern 'false' can never match the type 'true'
-comparisons.erl:115: The pattern 'true' can never match the type 'false'
-comparisons.erl:116: The pattern 'true' can never match the type 'false'
-comparisons.erl:117: The pattern 'false' can never match the type 'true'
comparisons.erl:118: The pattern 'false' can never match the type 'true'
+comparisons.erl:119: The pattern 'false' can never match the type 'true'
+comparisons.erl:120: The pattern 'true' can never match the type 'false'
+comparisons.erl:121: The pattern 'true' can never match the type 'false'
+comparisons.erl:122: The pattern 'false' can never match the type 'true'
comparisons.erl:123: The pattern 'false' can never match the type 'true'
-comparisons.erl:124: The pattern 'false' can never match the type 'true'
+comparisons.erl:124: The pattern 'true' can never match the type 'false'
comparisons.erl:125: The pattern 'true' can never match the type 'false'
-comparisons.erl:126: The pattern 'true' can never match the type 'false'
+comparisons.erl:126: The pattern 'false' can never match the type 'true'
comparisons.erl:127: The pattern 'false' can never match the type 'true'
-comparisons.erl:128: The pattern 'false' can never match the type 'true'
+comparisons.erl:128: The pattern 'true' can never match the type 'false'
comparisons.erl:129: The pattern 'true' can never match the type 'false'
-comparisons.erl:130: The pattern 'true' can never match the type 'false'
+comparisons.erl:130: The pattern 'false' can never match the type 'true'
+comparisons.erl:131: The pattern 'false' can never match the type 'true'
comparisons.erl:132: The pattern 'true' can never match the type 'false'
comparisons.erl:133: The pattern 'true' can never match the type 'false'
comparisons.erl:134: The pattern 'false' can never match the type 'true'
comparisons.erl:135: The pattern 'false' can never match the type 'true'
comparisons.erl:136: The pattern 'true' can never match the type 'false'
comparisons.erl:137: The pattern 'true' can never match the type 'false'
-comparisons.erl:138: The pattern 'false' can never match the type 'true'
-comparisons.erl:139: The pattern 'false' can never match the type 'true'
+comparisons.erl:139: The pattern 'true' can never match the type 'false'
comparisons.erl:140: The pattern 'true' can never match the type 'false'
-comparisons.erl:141: The pattern 'true' can never match the type 'false'
+comparisons.erl:141: The pattern 'false' can never match the type 'true'
comparisons.erl:142: The pattern 'false' can never match the type 'true'
-comparisons.erl:143: The pattern 'false' can never match the type 'true'
+comparisons.erl:143: The pattern 'true' can never match the type 'false'
comparisons.erl:144: The pattern 'true' can never match the type 'false'
-comparisons.erl:145: The pattern 'true' can never match the type 'false'
+comparisons.erl:145: The pattern 'false' can never match the type 'true'
comparisons.erl:146: The pattern 'false' can never match the type 'true'
-comparisons.erl:147: The pattern 'false' can never match the type 'true'
-comparisons.erl:152: The pattern 'false' can never match the type 'true'
-comparisons.erl:153: The pattern 'false' can never match the type 'true'
-comparisons.erl:154: The pattern 'true' can never match the type 'false'
-comparisons.erl:155: The pattern 'true' can never match the type 'false'
+comparisons.erl:147: The pattern 'true' can never match the type 'false'
+comparisons.erl:148: The pattern 'true' can never match the type 'false'
+comparisons.erl:149: The pattern 'false' can never match the type 'true'
+comparisons.erl:150: The pattern 'false' can never match the type 'true'
+comparisons.erl:155: The pattern 'false' can never match the type 'true'
+comparisons.erl:156: The pattern 'false' can never match the type 'true'
comparisons.erl:157: The pattern 'true' can never match the type 'false'
comparisons.erl:158: The pattern 'true' can never match the type 'false'
comparisons.erl:159: The pattern 'false' can never match the type 'true'
@@ -59,36 +52,62 @@ comparisons.erl:167: The pattern 'false' can never match the type 'true'
comparisons.erl:168: The pattern 'false' can never match the type 'true'
comparisons.erl:169: The pattern 'true' can never match the type 'false'
comparisons.erl:170: The pattern 'true' can never match the type 'false'
-comparisons.erl:171: The pattern 'false' can never match the type 'true'
-comparisons.erl:172: The pattern 'false' can never match the type 'true'
+comparisons.erl:172: The pattern 'true' can never match the type 'false'
comparisons.erl:173: The pattern 'true' can never match the type 'false'
-comparisons.erl:174: The pattern 'true' can never match the type 'false'
+comparisons.erl:174: The pattern 'false' can never match the type 'true'
comparisons.erl:175: The pattern 'false' can never match the type 'true'
-comparisons.erl:176: The pattern 'false' can never match the type 'true'
+comparisons.erl:176: The pattern 'true' can never match the type 'false'
+comparisons.erl:177: The pattern 'true' can never match the type 'false'
+comparisons.erl:178: The pattern 'false' can never match the type 'true'
+comparisons.erl:179: The pattern 'false' can never match the type 'true'
+comparisons.erl:180: The pattern 'true' can never match the type 'false'
+comparisons.erl:181: The pattern 'true' can never match the type 'false'
+comparisons.erl:182: The pattern 'false' can never match the type 'true'
+comparisons.erl:183: The pattern 'false' can never match the type 'true'
+comparisons.erl:184: The pattern 'true' can never match the type 'false'
+comparisons.erl:185: The pattern 'true' can never match the type 'false'
comparisons.erl:186: The pattern 'false' can never match the type 'true'
comparisons.erl:187: The pattern 'false' can never match the type 'true'
-comparisons.erl:188: The pattern 'true' can never match the type 'false'
-comparisons.erl:189: The pattern 'true' can never match the type 'false'
-comparisons.erl:190: The pattern 'false' can never match the type 'true'
-comparisons.erl:191: The pattern 'false' can never match the type 'true'
-comparisons.erl:192: The pattern 'true' can never match the type 'false'
-comparisons.erl:193: The pattern 'true' can never match the type 'false'
-comparisons.erl:203: The pattern 'false' can never match the type 'true'
-comparisons.erl:204: The pattern 'false' can never match the type 'true'
+comparisons.erl:192: The pattern 'false' can never match the type 'true'
+comparisons.erl:193: The pattern 'false' can never match the type 'true'
+comparisons.erl:194: The pattern 'true' can never match the type 'false'
+comparisons.erl:195: The pattern 'true' can never match the type 'false'
+comparisons.erl:196: The pattern 'false' can never match the type 'true'
+comparisons.erl:197: The pattern 'false' can never match the type 'true'
+comparisons.erl:198: The pattern 'true' can never match the type 'false'
+comparisons.erl:199: The pattern 'true' can never match the type 'false'
+comparisons.erl:200: The pattern 'false' can never match the type 'true'
+comparisons.erl:201: The pattern 'false' can never match the type 'true'
+comparisons.erl:202: The pattern 'true' can never match the type 'false'
+comparisons.erl:203: The pattern 'true' can never match the type 'false'
comparisons.erl:205: The pattern 'true' can never match the type 'false'
comparisons.erl:206: The pattern 'true' can never match the type 'false'
-comparisons.erl:208: The pattern 'true' can never match the type 'false'
+comparisons.erl:207: The pattern 'false' can never match the type 'true'
+comparisons.erl:208: The pattern 'false' can never match the type 'true'
comparisons.erl:209: The pattern 'true' can never match the type 'false'
-comparisons.erl:210: The pattern 'false' can never match the type 'true'
+comparisons.erl:210: The pattern 'true' can never match the type 'false'
comparisons.erl:211: The pattern 'false' can never match the type 'true'
+comparisons.erl:212: The pattern 'false' can never match the type 'true'
+comparisons.erl:213: The pattern 'true' can never match the type 'false'
+comparisons.erl:214: The pattern 'true' can never match the type 'false'
+comparisons.erl:215: The pattern 'false' can never match the type 'true'
+comparisons.erl:216: The pattern 'false' can never match the type 'true'
+comparisons.erl:217: The pattern 'true' can never match the type 'false'
+comparisons.erl:218: The pattern 'true' can never match the type 'false'
+comparisons.erl:219: The pattern 'false' can never match the type 'true'
+comparisons.erl:220: The pattern 'false' can never match the type 'true'
comparisons.erl:221: The pattern 'true' can never match the type 'false'
comparisons.erl:222: The pattern 'true' can never match the type 'false'
comparisons.erl:223: The pattern 'false' can never match the type 'true'
comparisons.erl:224: The pattern 'false' can never match the type 'true'
-comparisons.erl:225: The pattern 'true' can never match the type 'false'
-comparisons.erl:226: The pattern 'true' can never match the type 'false'
-comparisons.erl:227: The pattern 'false' can never match the type 'true'
-comparisons.erl:228: The pattern 'false' can never match the type 'true'
+comparisons.erl:229: The pattern 'true' can never match the type 'false'
+comparisons.erl:230: The pattern 'true' can never match the type 'false'
+comparisons.erl:231: The pattern 'false' can never match the type 'true'
+comparisons.erl:232: The pattern 'false' can never match the type 'true'
+comparisons.erl:233: The pattern 'false' can never match the type 'true'
+comparisons.erl:234: The pattern 'false' can never match the type 'true'
+comparisons.erl:235: The pattern 'true' can never match the type 'false'
+comparisons.erl:236: The pattern 'true' can never match the type 'false'
comparisons.erl:242: The pattern 'false' can never match the type 'true'
comparisons.erl:243: The pattern 'false' can never match the type 'true'
comparisons.erl:244: The pattern 'true' can never match the type 'false'
@@ -97,57 +116,86 @@ comparisons.erl:246: The pattern 'false' can never match the type 'true'
comparisons.erl:247: The pattern 'false' can never match the type 'true'
comparisons.erl:248: The pattern 'true' can never match the type 'false'
comparisons.erl:249: The pattern 'true' can never match the type 'false'
-comparisons.erl:251: The pattern 'true' can never match the type 'false'
-comparisons.erl:252: The pattern 'true' can never match the type 'false'
-comparisons.erl:253: The pattern 'false' can never match the type 'true'
-comparisons.erl:254: The pattern 'false' can never match the type 'true'
-comparisons.erl:263: The pattern 'false' can never match the type 'true'
-comparisons.erl:264: The pattern 'false' can never match the type 'true'
+comparisons.erl:259: The pattern 'false' can never match the type 'true'
+comparisons.erl:260: The pattern 'false' can never match the type 'true'
+comparisons.erl:261: The pattern 'true' can never match the type 'false'
+comparisons.erl:262: The pattern 'true' can never match the type 'false'
+comparisons.erl:264: The pattern 'true' can never match the type 'false'
comparisons.erl:265: The pattern 'true' can never match the type 'false'
-comparisons.erl:266: The pattern 'true' can never match the type 'false'
-comparisons.erl:268: The pattern 'true' can never match the type 'false'
-comparisons.erl:269: The pattern 'true' can never match the type 'false'
-comparisons.erl:270: The pattern 'false' can never match the type 'true'
-comparisons.erl:271: The pattern 'false' can never match the type 'true'
-comparisons.erl:272: The pattern 'true' can never match the type 'false'
-comparisons.erl:273: The pattern 'true' can never match the type 'false'
-comparisons.erl:274: The pattern 'false' can never match the type 'true'
-comparisons.erl:275: The pattern 'false' can never match the type 'true'
-comparisons.erl:293: The pattern 'false' can never match the type 'true'
-comparisons.erl:294: The pattern 'false' can never match the type 'true'
-comparisons.erl:295: The pattern 'true' can never match the type 'false'
-comparisons.erl:296: The pattern 'true' can never match the type 'false'
-comparisons.erl:311: The pattern 'true' can never match the type 'false'
-comparisons.erl:312: The pattern 'true' can never match the type 'false'
-comparisons.erl:313: The pattern 'false' can never match the type 'true'
-comparisons.erl:314: The pattern 'false' can never match the type 'true'
-comparisons.erl:44: The pattern 'false' can never match the type 'true'
-comparisons.erl:45: The pattern 'false' can never match the type 'true'
-comparisons.erl:46: The pattern 'true' can never match the type 'false'
-comparisons.erl:47: The pattern 'true' can never match the type 'false'
-comparisons.erl:48: The pattern 'false' can never match the type 'true'
-comparisons.erl:49: The pattern 'false' can never match the type 'true'
-comparisons.erl:50: The pattern 'true' can never match the type 'false'
-comparisons.erl:51: The pattern 'true' can never match the type 'false'
+comparisons.erl:266: The pattern 'false' can never match the type 'true'
+comparisons.erl:267: The pattern 'false' can never match the type 'true'
+comparisons.erl:277: The pattern 'true' can never match the type 'false'
+comparisons.erl:278: The pattern 'true' can never match the type 'false'
+comparisons.erl:279: The pattern 'false' can never match the type 'true'
+comparisons.erl:280: The pattern 'false' can never match the type 'true'
+comparisons.erl:281: The pattern 'true' can never match the type 'false'
+comparisons.erl:282: The pattern 'true' can never match the type 'false'
+comparisons.erl:283: The pattern 'false' can never match the type 'true'
+comparisons.erl:284: The pattern 'false' can never match the type 'true'
+comparisons.erl:298: The pattern 'false' can never match the type 'true'
+comparisons.erl:299: The pattern 'false' can never match the type 'true'
+comparisons.erl:300: The pattern 'true' can never match the type 'false'
+comparisons.erl:301: The pattern 'true' can never match the type 'false'
+comparisons.erl:302: The pattern 'false' can never match the type 'true'
+comparisons.erl:303: The pattern 'false' can never match the type 'true'
+comparisons.erl:304: The pattern 'true' can never match the type 'false'
+comparisons.erl:305: The pattern 'true' can never match the type 'false'
+comparisons.erl:307: The pattern 'true' can never match the type 'false'
+comparisons.erl:308: The pattern 'true' can never match the type 'false'
+comparisons.erl:309: The pattern 'false' can never match the type 'true'
+comparisons.erl:310: The pattern 'false' can never match the type 'true'
+comparisons.erl:319: The pattern 'false' can never match the type 'true'
+comparisons.erl:320: The pattern 'false' can never match the type 'true'
+comparisons.erl:321: The pattern 'true' can never match the type 'false'
+comparisons.erl:322: The pattern 'true' can never match the type 'false'
+comparisons.erl:324: The pattern 'true' can never match the type 'false'
+comparisons.erl:325: The pattern 'true' can never match the type 'false'
+comparisons.erl:326: The pattern 'false' can never match the type 'true'
+comparisons.erl:327: The pattern 'false' can never match the type 'true'
+comparisons.erl:328: The pattern 'true' can never match the type 'false'
+comparisons.erl:329: The pattern 'true' can never match the type 'false'
+comparisons.erl:330: The pattern 'false' can never match the type 'true'
+comparisons.erl:331: The pattern 'false' can never match the type 'true'
+comparisons.erl:349: The pattern 'false' can never match the type 'true'
+comparisons.erl:350: The pattern 'false' can never match the type 'true'
+comparisons.erl:351: The pattern 'true' can never match the type 'false'
+comparisons.erl:352: The pattern 'true' can never match the type 'false'
+comparisons.erl:367: The pattern 'true' can never match the type 'false'
+comparisons.erl:368: The pattern 'true' can never match the type 'false'
+comparisons.erl:369: The pattern 'false' can never match the type 'true'
+comparisons.erl:370: The pattern 'false' can never match the type 'true'
comparisons.erl:52: The pattern 'false' can never match the type 'true'
comparisons.erl:53: The pattern 'false' can never match the type 'true'
comparisons.erl:54: The pattern 'true' can never match the type 'false'
comparisons.erl:55: The pattern 'true' can never match the type 'false'
+comparisons.erl:56: The pattern 'false' can never match the type 'true'
+comparisons.erl:57: The pattern 'false' can never match the type 'true'
+comparisons.erl:58: The pattern 'true' can never match the type 'false'
+comparisons.erl:59: The pattern 'true' can never match the type 'false'
+comparisons.erl:60: The pattern 'false' can never match the type 'true'
+comparisons.erl:61: The pattern 'false' can never match the type 'true'
+comparisons.erl:62: The pattern 'true' can never match the type 'false'
+comparisons.erl:63: The pattern 'true' can never match the type 'false'
+comparisons.erl:64: The pattern 'false' can never match the type 'true'
+comparisons.erl:65: The pattern 'false' can never match the type 'true'
+comparisons.erl:66: The pattern 'true' can never match the type 'false'
+comparisons.erl:67: The pattern 'true' can never match the type 'false'
+comparisons.erl:68: The pattern 'false' can never match the type 'true'
comparisons.erl:69: The pattern 'false' can never match the type 'true'
-comparisons.erl:70: The pattern 'false' can never match the type 'true'
+comparisons.erl:70: The pattern 'true' can never match the type 'false'
comparisons.erl:71: The pattern 'true' can never match the type 'false'
-comparisons.erl:72: The pattern 'true' can never match the type 'false'
-comparisons.erl:73: The pattern 'false' can never match the type 'true'
-comparisons.erl:74: The pattern 'false' can never match the type 'true'
-comparisons.erl:75: The pattern 'true' can never match the type 'false'
-comparisons.erl:76: The pattern 'true' can never match the type 'false'
-comparisons.erl:77: The pattern 'false' can never match the type 'true'
-comparisons.erl:78: The pattern 'false' can never match the type 'true'
-comparisons.erl:79: The pattern 'true' can never match the type 'false'
-comparisons.erl:80: The pattern 'true' can never match the type 'false'
+comparisons.erl:85: The pattern 'false' can never match the type 'true'
+comparisons.erl:86: The pattern 'false' can never match the type 'true'
+comparisons.erl:87: The pattern 'true' can never match the type 'false'
+comparisons.erl:88: The pattern 'true' can never match the type 'false'
+comparisons.erl:89: The pattern 'false' can never match the type 'true'
+comparisons.erl:90: The pattern 'false' can never match the type 'true'
+comparisons.erl:91: The pattern 'true' can never match the type 'false'
+comparisons.erl:92: The pattern 'true' can never match the type 'false'
+comparisons.erl:93: The pattern 'false' can never match the type 'true'
comparisons.erl:94: The pattern 'false' can never match the type 'true'
-comparisons.erl:95: The pattern 'false' can never match the type 'true'
+comparisons.erl:95: The pattern 'true' can never match the type 'false'
comparisons.erl:96: The pattern 'true' can never match the type 'false'
-comparisons.erl:97: The pattern 'true' can never match the type 'false'
+comparisons.erl:97: The pattern 'false' can never match the type 'true'
comparisons.erl:98: The pattern 'false' can never match the type 'true'
-comparisons.erl:99: The pattern 'false' can never match the type 'true'
+comparisons.erl:99: The pattern 'true' can never match the type 'false'
diff --git a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes
index fbdd182358..a9fbfb6068 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes
+++ b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes
@@ -6,23 +6,27 @@ contracts_with_subtypes.erl:135: The call contracts_with_subtypes:rec2({'a','b'}
contracts_with_subtypes.erl:136: The call contracts_with_subtypes:rec2({'b','a'}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
contracts_with_subtypes.erl:137: The call contracts_with_subtypes:rec2({'a',{'b','a'}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
contracts_with_subtypes.erl:138: The call contracts_with_subtypes:rec2({'b',{'a','b'}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
-contracts_with_subtypes.erl:171: The pattern 1 can never match the type string()
-contracts_with_subtypes.erl:174: The pattern 'alpha' can never match the type {'ok',_} | {'ok',_,string()}
-contracts_with_subtypes.erl:176: The pattern 42 can never match the type {'ok',_} | {'ok',_,string()}
-contracts_with_subtypes.erl:192: The pattern 'alpha' can never match the type {'ok',_}
-contracts_with_subtypes.erl:194: The pattern 42 can never match the type {'ok',_}
-contracts_with_subtypes.erl:212: The pattern 'alpha' can never match the type {'ok',_}
-contracts_with_subtypes.erl:214: The pattern 42 can never match the type {'ok',_}
-contracts_with_subtypes.erl:231: The pattern 1 can never match the type string()
-contracts_with_subtypes.erl:234: The pattern {'ok', _} can never match the type {'ok',_,string()}
-contracts_with_subtypes.erl:235: The pattern 'alpha' can never match the type {'ok',_,string()}
-contracts_with_subtypes.erl:236: The pattern {'ok', 42} can never match the type {'ok',_,string()}
-contracts_with_subtypes.erl:237: The pattern 42 can never match the type {'ok',_,string()}
+contracts_with_subtypes.erl:139: The call contracts_with_subtypes:rec2({'a',{'b',{'a','b'}}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
+contracts_with_subtypes.erl:140: The call contracts_with_subtypes:rec2({'b',{'a',{'b','a'}}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
+contracts_with_subtypes.erl:141: The call contracts_with_subtypes:rec2({'a',{'b',{'a',{'b','a'}}}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
+contracts_with_subtypes.erl:142: The call contracts_with_subtypes:rec2({'b',{'a',{'b',{'a','b'}}}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,ab())
+contracts_with_subtypes.erl:175: The pattern 1 can never match the type string()
+contracts_with_subtypes.erl:178: The pattern 'alpha' can never match the type {'ok',_} | {'ok',_,string()}
+contracts_with_subtypes.erl:180: The pattern 42 can never match the type {'ok',_} | {'ok',_,string()}
+contracts_with_subtypes.erl:196: The pattern 'alpha' can never match the type {'ok',_}
+contracts_with_subtypes.erl:198: The pattern 42 can never match the type {'ok',_}
+contracts_with_subtypes.erl:216: The pattern 'alpha' can never match the type {'ok',_}
+contracts_with_subtypes.erl:218: The pattern 42 can never match the type {'ok',_}
+contracts_with_subtypes.erl:235: The pattern 1 can never match the type string()
+contracts_with_subtypes.erl:238: The pattern {'ok', _} can never match the type {'ok',_,string()}
+contracts_with_subtypes.erl:239: The pattern 'alpha' can never match the type {'ok',_,string()}
contracts_with_subtypes.erl:23: Invalid type specification for function contracts_with_subtypes:extract2/0. The success typing is () -> 'something'
-contracts_with_subtypes.erl:263: Function flat_ets_new_t/0 has no local return
-contracts_with_subtypes.erl:264: The call contracts_with_subtypes:flat_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when is_subtype(Name,atom()), is_subtype(Options,[Option]), is_subtype(Option,'set' | 'ordered_set' | 'bag' | 'duplicate_bag' | 'public' | 'protected' | 'private' | 'named_table' | {'keypos',integer()} | {'heir',pid(),term()} | {'heir','none'} | {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed')
-contracts_with_subtypes.erl:290: Function factored_ets_new_t/0 has no local return
-contracts_with_subtypes.erl:291: The call contracts_with_subtypes:factored_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when is_subtype(Name,atom()), is_subtype(Options,[Option]), is_subtype(Option,Type | Access | 'named_table' | {'keypos',Pos} | {'heir',Pid::pid(),HeirData} | {'heir','none'} | Tweaks), is_subtype(Type,type()), is_subtype(Access,access()), is_subtype(Tweaks,{'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed'), is_subtype(Pos,pos_integer()), is_subtype(HeirData,term())
+contracts_with_subtypes.erl:240: The pattern {'ok', 42} can never match the type {'ok',_,string()}
+contracts_with_subtypes.erl:241: The pattern 42 can never match the type {'ok',_,string()}
+contracts_with_subtypes.erl:267: Function flat_ets_new_t/0 has no local return
+contracts_with_subtypes.erl:268: The call contracts_with_subtypes:flat_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when is_subtype(Name,atom()), is_subtype(Options,[Option]), is_subtype(Option,'set' | 'ordered_set' | 'bag' | 'duplicate_bag' | 'public' | 'protected' | 'private' | 'named_table' | {'keypos',integer()} | {'heir',pid(),term()} | {'heir','none'} | {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed')
+contracts_with_subtypes.erl:294: Function factored_ets_new_t/0 has no local return
+contracts_with_subtypes.erl:295: The call contracts_with_subtypes:factored_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when is_subtype(Name,atom()), is_subtype(Options,[Option]), is_subtype(Option,Type | Access | 'named_table' | {'keypos',Pos} | {'heir',Pid::pid(),HeirData} | {'heir','none'} | Tweaks), is_subtype(Type,type()), is_subtype(Access,access()), is_subtype(Tweaks,{'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed'), is_subtype(Pos,pos_integer()), is_subtype(HeirData,term())
contracts_with_subtypes.erl:77: The call contracts_with_subtypes:foo1(5) breaks the contract (Arg1) -> Res when is_subtype(Arg1,atom()), is_subtype(Res,atom())
contracts_with_subtypes.erl:78: The call contracts_with_subtypes:foo2(5) breaks the contract (Arg1) -> Res when is_subtype(Arg1,Arg2), is_subtype(Arg2,atom()), is_subtype(Res,atom())
contracts_with_subtypes.erl:79: The call contracts_with_subtypes:foo3(5) breaks the contract (Arg1) -> Res when is_subtype(Arg2,atom()), is_subtype(Arg1,Arg2), is_subtype(Res,atom())
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
new file mode 100644
index 0000000000..cc9db65152
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
@@ -0,0 +1,37 @@
+
+fun_arity.erl:100: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:100: Function 'Mfa_0_ko'/1 has no local return
+fun_arity.erl:104: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:104: Function 'Mfa_1_ko'/1 has no local return
+fun_arity.erl:111: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:111: Function mFa_0_ko/1 has no local return
+fun_arity.erl:115: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:115: Function mFa_1_ko/1 has no local return
+fun_arity.erl:122: Fun application will fail since _cor2 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:122: Function 'MFa_0_ko'/2 has no local return
+fun_arity.erl:126: Fun application will fail since _cor2 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:126: Function 'MFa_1_ko'/2 has no local return
+fun_arity.erl:35: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:35: Function f_0_ko/0 has no local return
+fun_arity.erl:39: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:39: Function f_1_ko/0 has no local return
+fun_arity.erl:48: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:48: Function fa_0_ko/0 has no local return
+fun_arity.erl:53: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:53: Function fa_1_ko/0 has no local return
+fun_arity.erl:63: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:63: Function mfa_0_ko/0 has no local return
+fun_arity.erl:68: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:68: Function mfa_1_ko/0 has no local return
+fun_arity.erl:76: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:76: Function mfa_ne_0_ko/0 has no local return
+fun_arity.erl:78: Function mf_ne/0 will never be called
+fun_arity.erl:81: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return
+fun_arity.erl:83: Function mf_ne/1 will never be called
+fun_arity.erl:89: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return
+fun_arity.erl:90: Call to missing or unexported function fun_arity:mf_nd/0
+fun_arity.erl:93: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return
+fun_arity.erl:94: Call to missing or unexported function fun_arity:mf_nd/1
diff --git a/lib/dialyzer/test/small_SUITE_data/results/maps1 b/lib/dialyzer/test/small_SUITE_data/results/maps1
new file mode 100644
index 0000000000..5a78d66a92
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/maps1
@@ -0,0 +1,4 @@
+
+maps1.erl:43: Function t3/0 has no local return
+maps1.erl:44: The call maps1:foo(~{'greger'=>3, ~{'arne'=>'anka'}~=>45}~,1) will never return since it differs in the 2nd argument from the success typing arguments: (#{},'b')
+maps1.erl:52: The call Mod:'function'(~{'literal'=>'map'}~,'another_arg') requires that Mod is of type atom() | tuple() not #{}
diff --git a/lib/dialyzer/test/small_SUITE_data/results/maps_sum b/lib/dialyzer/test/small_SUITE_data/results/maps_sum
new file mode 100644
index 0000000000..a19c0bba96
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/maps_sum
@@ -0,0 +1,4 @@
+
+maps_sum.erl:15: Invalid type specification for function maps_sum:wrong1/1. The success typing is (#{}) -> any()
+maps_sum.erl:26: Function wrong2/1 has no local return
+maps_sum.erl:27: The call lists:foldl(fun((_,_,_) -> any()),0,Data::any()) will never return since it differs in the 1st argument from the success typing arguments: (fun((_,_) -> any()),any(),[any()])
diff --git a/lib/dialyzer/test/small_SUITE_data/results/non_existing b/lib/dialyzer/test/small_SUITE_data/results/non_existing
index 58da2bfc8b..b0da5998c7 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/non_existing
+++ b/lib/dialyzer/test/small_SUITE_data/results/non_existing
@@ -1,2 +1,3 @@
+non_existing.erl:12: Call to missing or unexported function lists:non_existing_fun/1
non_existing.erl:9: Call to missing or unexported function lists:non_existing_call/1
diff --git a/lib/dialyzer/test/small_SUITE_data/results/request1 b/lib/dialyzer/test/small_SUITE_data/results/request1
new file mode 100644
index 0000000000..0cf4017403
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/request1
@@ -0,0 +1,2 @@
+
+request1.erl:8: Expression produces a value of type {'a','b'}, but this value is unmatched
diff --git a/lib/dialyzer/test/small_SUITE_data/results/suppress_request b/lib/dialyzer/test/small_SUITE_data/results/suppress_request
new file mode 100644
index 0000000000..18e82b7972
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/suppress_request
@@ -0,0 +1,6 @@
+
+suppress_request.erl:21: Expression produces a value of type {'a','b'}, but this value is unmatched
+suppress_request.erl:25: Expression produces a value of type {'a','b'}, but this value is unmatched
+suppress_request.erl:35: Function test3_b/0 has no local return
+suppress_request.erl:39: Guard test 2 =:= A::fun((none()) -> no_return()) can never succeed
+suppress_request.erl:7: Type specification suppress_request:test1('a' | 'b') -> 'ok' is a subtype of the success typing: suppress_request:test1('a' | 'b' | 'c') -> 'ok'
diff --git a/lib/dialyzer/test/small_SUITE_data/src/abs.erl b/lib/dialyzer/test/small_SUITE_data/src/abs.erl
new file mode 100644
index 0000000000..251e24cdfc
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/abs.erl
@@ -0,0 +1,71 @@
+-module(abs).
+
+%% OTP-12948. erlang:abs/1 bug fix.
+
+-export([t/0]).
+
+t() ->
+ Fs = [fun i1/0, fun i2/0, fun i3/0, fun i4/0, fun f1/0],
+ _ = [catch F() || F <- Fs],
+ ok.
+
+i1() ->
+ A = int(),
+ I1 = i1(A),
+ true = I1 < 2,
+ true = I1 < 1. % can never match
+
+-spec i1(neg_integer()) -> non_neg_integer().
+
+i1(A) when is_integer(A), A < 0 ->
+ abs(A).
+
+i2() ->
+ A = int(),
+ I2 = i2(A),
+ true = I2 < 1,
+ true = I2 < 0. % can never match
+
+-spec i2(non_neg_integer()) -> non_neg_integer().
+
+i2(A) when is_integer(A), A >= 0 ->
+ abs(A).
+
+i3() ->
+ A = int(),
+ I3 = i3(A),
+ true = I3 < -1,
+ true = I3 < 0. % can never match
+
+-spec i3(integer()) -> non_neg_integer().
+
+i3(A) when is_integer(A) ->
+ abs(A).
+
+i4() ->
+ A = int(),
+ I4 = i4(A),
+ true = I4 =:= 0 orelse I4 =:= 1,
+ true = I4 < 0 orelse I4 > 1. % can never match
+
+-spec i4(integer()) -> number().
+
+i4(A) when A =:= -1; A =:= 0; A =:= 1 ->
+ abs(A).
+
+f1() ->
+ F1 = f1(float()),
+ math:sqrt(F1).
+
+f1(A) ->
+ abs(A).
+
+-spec int() -> integer().
+
+int() ->
+ foo:bar().
+
+-spec float() -> float().
+
+float() ->
+ math:sqrt(1.0).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_bad_format_status.erl b/lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_bad_format_status.erl
new file mode 100644
index 0000000000..24591e08fa
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_bad_format_status.erl
@@ -0,0 +1,12 @@
+-module(with_bad_format_status).
+
+-behaviour(gen_server).
+-export([handle_call/3,handle_cast/2,handle_info/2,
+ code_change/3, init/1, terminate/2, format_status/2]).
+handle_call(_, _, S) -> {noreply, S}.
+handle_cast(_, S) -> {noreply, S}.
+handle_info(_, S) -> {noreply, S}.
+code_change(_, _, _) -> {error, not_implemented}.
+init(_) -> {ok, state}.
+terminate(_, _) -> ok.
+format_status(bad_arg, _) -> ok. % optional callback
diff --git a/lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_format_status.erl b/lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_format_status.erl
new file mode 100644
index 0000000000..a56ff63d1d
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/behaviour_info/with_format_status.erl
@@ -0,0 +1,13 @@
+-module(with_format_status).
+
+-behaviour(gen_server).
+-export([handle_call/3,handle_cast/2,handle_info/2,
+ code_change/3, init/1, terminate/2, format_status/2]).
+-export([handle_call/3,handle_cast/2,handle_info/2]).
+handle_call(_, _, S) -> {noreply, S}.
+handle_cast(_, S) -> {noreply, S}.
+handle_info(_, S) -> {noreply, S}.
+code_change(_, _, _) -> {error, not_implemented}.
+init(_) -> {ok, state}.
+terminate(_, _) -> ok.
+format_status(normal, _) -> ok. % optional callback
diff --git a/lib/dialyzer/test/small_SUITE_data/src/big_external_type.erl b/lib/dialyzer/test/small_SUITE_data/src/big_external_type.erl
new file mode 100644
index 0000000000..ab84e94106
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/big_external_type.erl
@@ -0,0 +1,529 @@
+%%
+%% %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
+%%
+%% 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%
+%%
+
+%%% A stripped version of erl_parse.yrl.
+%%%
+%%% A type for the abstract format with *external* types has been added.
+%%% The type of the abstract format is not up-to-date, but it does not
+%%% matter since the purpose of the type is to stress the conversion
+%%% of type forms to erl_type().
+
+-module(big_external_type).
+
+-export([parse_form/1,parse_exprs/1,parse_term/1]).
+-export([normalise/1,tokens/1,tokens/2]).
+-export([inop_prec/1,preop_prec/1,func_prec/0,max_prec/0]).
+
+-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
+ error_info/0]).
+
+%% Start of Abstract Format
+
+-type line() :: erl_scan:line().
+
+-export_type([af_record_index/0, af_record_field/1, af_record_name/0,
+ af_field_name/0, af_function_decl/0]).
+
+-export_type([af_module/0, af_export/0, af_import/0, af_fa_list/0,
+ af_compile/0, af_file/0, af_record_decl/0,
+ af_field_decl/0, af_wild_attribute/0,
+ af_record_update/1, af_catch/0, af_local_call/0,
+ af_remote_call/0, af_args/0, af_local_function/0,
+ af_remote_function/0, af_list_comprehension/0,
+ af_binary_comprehension/0, af_template/0,
+ af_qualifier_seq/0, af_qualifier/0, af_generator/0,
+ af_filter/0, af_block/0, af_if/0, af_case/0, af_try/0,
+ af_clause_seq/0, af_catch_clause_seq/0, af_receive/0,
+ af_local_fun/0, af_remote_fun/0, af_fun/0, af_query/0,
+ af_query_access/0, af_clause/0,
+ af_catch_clause/0, af_catch_pattern/0, af_catch_class/0,
+ af_body/0, af_guard_seq/0, af_guard/0, af_guard_test/0,
+ af_record_access/1, af_guard_call/0,
+ af_remote_guard_call/0, af_pattern/0, af_literal/0,
+ af_atom/0, af_lit_atom/1, af_integer/0, af_float/0,
+ af_string/0, af_match/1, af_variable/0,
+ af_anon_variable/0, af_tuple/1, af_nil/0, af_cons/1,
+ af_bin/1, af_binelement/1, af_binelement_size/0,
+ af_binary_op/1, af_binop/0, af_unary_op/1, af_unop/0]).
+
+-type abstract_form() :: ?MODULE:af_module()
+ | ?MODULE:af_export()
+ | ?MODULE:af_import()
+ | ?MODULE:af_compile()
+ | ?MODULE:af_file()
+ | ?MODULE:af_record_decl()
+ | ?MODULE:af_wild_attribute()
+ | ?MODULE:af_function_decl().
+
+-type af_module() :: {attribute, line(), module, module()}.
+
+-type af_export() :: {attribute, line(), export, ?MODULE:af_fa_list()}.
+
+-type af_import() :: {attribute, line(), import, ?MODULE:af_fa_list()}.
+
+-type af_fa_list() :: [{function(), arity()}].
+
+-type af_compile() :: {attribute, line(), compile, any()}.
+
+-type af_file() :: {attribute, line(), file, {string(), line()}}.
+
+-type af_record_decl() ::
+ {attribute, line(), record, ?MODULE:af_record_name(), [?MODULE:af_field_decl()]}.
+
+-type af_field_decl() :: {record_field, line(), ?MODULE:af_atom()}
+ | {record_field, line(), ?MODULE:af_atom(), ?MODULE:abstract_expr()}.
+
+%% Types and specs, among other things...
+-type af_wild_attribute() :: {attribute, line(), ?MODULE:af_atom(), any()}.
+
+-type af_function_decl() ::
+ {function, line(), function(), arity(), ?MODULE:af_clause_seq()}.
+
+-type abstract_expr() :: ?MODULE:af_literal()
+ | ?MODULE:af_match(?MODULE:abstract_expr())
+ | ?MODULE:af_variable()
+ | ?MODULE:af_tuple(?MODULE:abstract_expr())
+ | ?MODULE:af_nil()
+ | ?MODULE:af_cons(?MODULE:abstract_expr())
+ | ?MODULE:af_bin(?MODULE:abstract_expr())
+ | ?MODULE:af_binary_op(?MODULE:abstract_expr())
+ | ?MODULE:af_unary_op(?MODULE:abstract_expr())
+ | ?MODULE:af_record_access(?MODULE:abstract_expr())
+ | ?MODULE:af_record_update(?MODULE:abstract_expr())
+ | ?MODULE:af_record_index()
+ | ?MODULE:af_record_field(?MODULE:abstract_expr())
+ | ?MODULE:af_catch()
+ | ?MODULE:af_local_call()
+ | ?MODULE:af_remote_call()
+ | ?MODULE:af_list_comprehension()
+ | ?MODULE:af_binary_comprehension()
+ | ?MODULE:af_block()
+ | ?MODULE:af_if()
+ | ?MODULE:af_case()
+ | ?MODULE:af_try()
+ | ?MODULE:af_receive()
+ | ?MODULE:af_local_fun()
+ | ?MODULE:af_remote_fun()
+ | ?MODULE:af_fun()
+ | ?MODULE:af_query()
+ | ?MODULE:af_query_access().
+
+-type af_record_update(T) :: {record,
+ line(),
+ ?MODULE:abstract_expr(),
+ ?MODULE:af_record_name(),
+ [?MODULE:af_record_field(T)]}.
+
+-type af_catch() :: {'catch', line(), ?MODULE:abstract_expr()}.
+
+-type af_local_call() :: {call, line(), ?MODULE:af_local_function(), ?MODULE:af_args()}.
+
+-type af_remote_call() :: {call, line(), ?MODULE:af_remote_function(), ?MODULE:af_args()}.
+
+-type af_args() :: [?MODULE:abstract_expr()].
+
+-type af_local_function() :: ?MODULE:abstract_expr().
+
+-type af_remote_function() ::
+ {remote, line(), ?MODULE:abstract_expr(), ?MODULE:abstract_expr()}.
+
+-type af_list_comprehension() ::
+ {lc, line(), ?MODULE:af_template(), ?MODULE:af_qualifier_seq()}.
+
+-type af_binary_comprehension() ::
+ {bc, line(), ?MODULE:af_template(), ?MODULE:af_qualifier_seq()}.
+
+-type af_template() :: ?MODULE:abstract_expr().
+
+-type af_qualifier_seq() :: [?MODULE:af_qualifier()].
+
+-type af_qualifier() :: ?MODULE:af_generator() | ?MODULE:af_filter().
+
+-type af_generator() :: {generate, line(), ?MODULE:af_pattern(), ?MODULE:abstract_expr()}
+ | {b_generate, line(), ?MODULE:af_pattern(), ?MODULE:abstract_expr()}.
+
+-type af_filter() :: ?MODULE:abstract_expr().
+
+-type af_block() :: {block, line(), ?MODULE:af_body()}.
+
+-type af_if() :: {'if', line(), ?MODULE:af_clause_seq()}.
+
+-type af_case() :: {'case', line(), ?MODULE:abstract_expr(), ?MODULE:af_clause_seq()}.
+
+-type af_try() :: {'try',
+ line(),
+ ?MODULE:af_body(),
+ ?MODULE:af_clause_seq(),
+ ?MODULE:af_catch_clause_seq(),
+ ?MODULE:af_body()}.
+
+-type af_clause_seq() :: [?MODULE:af_clause(), ...].
+
+-type af_catch_clause_seq() :: [?MODULE:af_clause(), ...].
+
+-type af_receive() ::
+ {'receive', line(), ?MODULE:af_clause_seq()}
+ | {'receive', line(), ?MODULE:af_clause_seq(), ?MODULE:abstract_expr(), ?MODULE:af_body()}.
+
+-type af_local_fun() :: {'fun', line(), {function, function(), arity()}}.
+
+-type af_remote_fun() ::
+ {'fun', line(), {function, module(), function(), arity()}}
+ | {'fun', line(), {function, ?MODULE:af_atom(), ?MODULE:af_atom(), ?MODULE:af_integer()}}.
+
+-type af_fun() :: {'fun', line(), {clauses, ?MODULE:af_clause_seq()}}.
+
+-type af_query() :: {'query', line(), ?MODULE:af_list_comprehension()}.
+
+-type af_query_access() ::
+ {record_field, line(), ?MODULE:abstract_expr(), ?MODULE:af_field_name()}.
+
+-type abstract_clause() :: ?MODULE:af_clause() | ?MODULE:af_catch_clause().
+
+-type af_clause() ::
+ {clause, line(), [?MODULE:af_pattern()], ?MODULE:af_guard_seq(), ?MODULE:af_body()}.
+
+-type af_catch_clause() ::
+ {clause, line(), [?MODULE:af_catch_pattern()], ?MODULE:af_guard_seq(), ?MODULE:af_body()}.
+
+-type af_catch_pattern() ::
+ {?MODULE:af_catch_class(), ?MODULE:af_pattern(), ?MODULE:af_anon_variable()}.
+
+-type af_catch_class() ::
+ ?MODULE:af_variable()
+ | ?MODULE:af_lit_atom(throw) | ?MODULE:af_lit_atom(error) | ?MODULE:af_lit_atom(exit).
+
+-type af_body() :: [?MODULE:abstract_expr(), ...].
+
+-type af_guard_seq() :: [?MODULE:af_guard()].
+
+-type af_guard() :: [?MODULE:af_guard_test(), ...].
+
+-type af_guard_test() :: ?MODULE:af_literal()
+ | ?MODULE:af_variable()
+ | ?MODULE:af_tuple(?MODULE:af_guard_test())
+ | ?MODULE:af_nil()
+ | ?MODULE:af_cons(?MODULE:af_guard_test())
+ | ?MODULE:af_bin(?MODULE:af_guard_test())
+ | ?MODULE:af_binary_op(?MODULE:af_guard_test())
+ | ?MODULE:af_unary_op(?MODULE:af_guard_test())
+ | ?MODULE:af_record_access(?MODULE:af_guard_test())
+ | ?MODULE:af_record_index()
+ | ?MODULE:af_record_field(?MODULE:af_guard_test())
+ | ?MODULE:af_guard_call()
+ | ?MODULE:af_remote_guard_call().
+
+-type af_record_access(T) ::
+ {record, line(), ?MODULE:af_record_name(), [?MODULE:af_record_field(T)]}.
+
+-type af_guard_call() :: {call, line(), function(), [?MODULE:af_guard_test()]}.
+
+-type af_remote_guard_call() ::
+ {call, line(), atom(), ?MODULE:af_lit_atom(erlang), [?MODULE:af_guard_test()]}.
+
+-type af_pattern() :: ?MODULE:af_literal()
+ | ?MODULE:af_match(?MODULE:af_pattern())
+ | ?MODULE:af_variable()
+ | ?MODULE:af_anon_variable()
+ | ?MODULE:af_tuple(?MODULE:af_pattern())
+ | ?MODULE:af_nil()
+ | ?MODULE:af_cons(?MODULE:af_pattern())
+ | ?MODULE:af_bin(?MODULE:af_pattern())
+ | ?MODULE:af_binary_op(?MODULE:af_pattern())
+ | ?MODULE:af_unary_op(?MODULE:af_pattern())
+ | ?MODULE:af_record_index()
+ | ?MODULE:af_record_field(?MODULE:af_pattern()).
+
+-type af_literal() :: ?MODULE:af_atom() | ?MODULE:af_integer() | ?MODULE:af_float() | ?MODULE:af_string().
+
+-type af_atom() :: ?MODULE:af_lit_atom(atom()).
+
+-type af_lit_atom(A) :: {atom, line(), A}.
+
+-type af_integer() :: {integer, line(), non_neg_integer()}.
+
+-type af_float() :: {float, line(), float()}.
+
+-type af_string() :: {string, line(), [byte()]}.
+
+-type af_match(T) :: {match, line(), T, T}.
+
+-type af_variable() :: {var, line(), atom()}.
+
+-type af_anon_variable() :: {var, line(), '_'}.
+
+-type af_tuple(T) :: {tuple, line(), [T]}.
+
+-type af_nil() :: {nil, line()}.
+
+-type af_cons(T) :: {cons, line, T, T}.
+
+-type af_bin(T) :: {bin, line(), [?MODULE:af_binelement(T)]}.
+
+-type af_binelement(T) :: {bin_element,
+ line(),
+ T,
+ ?MODULE:af_binelement_size(),
+ type_specifier_list()}.
+
+-type af_binelement_size() :: default | ?MODULE:abstract_expr().
+
+-type af_binary_op(T) :: {op, line(), T, ?MODULE:af_binop(), T}.
+
+-type af_binop() :: '/' | '*' | 'div' | 'rem' | 'band' | 'and' | '+' | '-'
+ | 'bor' | 'bxor' | 'bsl' | 'bsr' | 'or' | 'xor' | '++'
+ | '--' | '==' | '/=' | '=<' | '<' | '>=' | '>' | '=:='
+ | '=/='.
+
+-type af_unary_op(T) :: {op, line(), ?MODULE:af_unop(), T}.
+
+-type af_unop() :: '+' | '*' | 'bnot' | 'not'.
+
+%% See also lib/stdlib/{src/erl_bits.erl,include/erl_bits.hrl}.
+-type type_specifier_list() :: default | [type_specifier(), ...].
+
+-type type_specifier() :: af_type()
+ | af_signedness()
+ | af_endianness()
+ | af_unit().
+
+-type af_type() :: integer
+ | float
+ | binary
+ | bytes
+ | bitstring
+ | bits
+ | utf8
+ | utf16
+ | utf32.
+
+-type af_signedness() :: signed | unsigned.
+
+-type af_endianness() :: big | little | native.
+
+-type af_unit() :: {unit, 1..256}.
+
+-type af_record_index() ::
+ {record_index, line(), af_record_name(), af_field_name()}.
+
+-type af_record_field(T) :: {record_field, line(), af_field_name(), T}.
+
+-type af_record_name() :: atom().
+
+-type af_field_name() :: atom().
+
+%% End of Abstract Format
+
+-type error_description() :: term().
+-type error_info() :: {erl_scan:line(), module(), error_description()}.
+-type token() :: {Tag :: atom(), Line :: erl_scan:line()}.
+
+%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
+%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
+
+-define(mkop2(L, OpPos, R),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,L,R}
+ end).
+
+-define(mkop1(OpPos, A),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,A}
+ end).
+
+%% keep track of line info in tokens
+-define(line(Tup), element(2, Tup)).
+
+%% Entry points compatible to old erl_parse.
+%% These really suck and are only here until Calle gets multiple
+%% entry points working.
+
+-spec parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ AbsForm :: abstract_form(),
+ ErrorInfo :: error_info().
+parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
+ parse([{'-',L1},{'spec',L2}|Tokens]);
+parse_form([{'-',L1},{atom,L2,callback}|Tokens]) ->
+ parse([{'-',L1},{'callback',L2}|Tokens]);
+parse_form(Tokens) ->
+ parse(Tokens).
+
+-spec parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ ExprList :: [abstract_expr()],
+ ErrorInfo :: error_info().
+parse_exprs(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
+ {ok,Exprs};
+ {error,_} = Err -> Err
+ end.
+
+-spec parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ Term :: term(),
+ ErrorInfo :: error_info().
+parse_term(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[Expr]}]}} ->
+ try normalise(Expr) of
+ Term -> {ok,Term}
+ catch
+ _:_R -> {error,{?line(Expr),?MODULE,"bad term"}}
+ end;
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[_E1,E2|_Es]}]}} ->
+ {error,{?line(E2),?MODULE,"bad term"}};
+ {error,_} = Err -> Err
+ end.
+
+%% Convert between the abstract form of a term and a term.
+
+-spec normalise(AbsTerm) -> Data when
+ AbsTerm :: abstract_expr(),
+ Data :: term().
+normalise({char,_,C}) -> C;
+normalise({integer,_,I}) -> I;
+normalise({float,_,F}) -> F;
+normalise({atom,_,A}) -> A;
+normalise({string,_,S}) -> S;
+normalise({nil,_}) -> [];
+normalise({bin,_,Fs}) ->
+ {value, B, _} =
+ eval_bits:expr_grp(Fs, [],
+ fun(E, _) ->
+ {value, normalise(E), []}
+ end, [], true),
+ B;
+normalise({cons,_,Head,Tail}) ->
+ [normalise(Head)|normalise(Tail)];
+normalise({tuple,_,Args}) ->
+ list_to_tuple(normalise_list(Args));
+%% Atom dot-notation, as in 'foo.bar.baz'
+%% Special case for unary +/-.
+normalise({op,_,'+',{char,_,I}}) -> I;
+normalise({op,_,'+',{integer,_,I}}) -> I;
+normalise({op,_,'+',{float,_,F}}) -> F;
+normalise({op,_,'-',{char,_,I}}) -> -I; %Weird, but compatible!
+normalise({op,_,'-',{integer,_,I}}) -> -I;
+normalise({op,_,'-',{float,_,F}}) -> -F;
+normalise(X) -> erlang:error({badarg, X}).
+
+normalise_list([H|T]) ->
+ [normalise(H)|normalise_list(T)];
+normalise_list([]) ->
+ [].
+
+%% Generate a list of tokens representing the abstract term.
+
+-spec tokens(AbsTerm) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ Tokens :: [token()].
+tokens(Abs) ->
+ tokens(Abs, []).
+
+-spec tokens(AbsTerm, MoreTokens) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ MoreTokens :: [token()],
+ Tokens :: [token()].
+tokens({char,L,C}, More) -> [{char,L,C}|More];
+tokens({integer,L,N}, More) -> [{integer,L,N}|More];
+tokens({float,L,F}, More) -> [{float,L,F}|More];
+tokens({atom,L,A}, More) -> [{atom,L,A}|More];
+tokens({var,L,V}, More) -> [{var,L,V}|More];
+tokens({string,L,S}, More) -> [{string,L,S}|More];
+tokens({nil,L}, More) -> [{'[',L},{']',L}|More];
+tokens({cons,L,Head,Tail}, More) ->
+ [{'[',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens({tuple,L,[]}, More) ->
+ [{'{',L},{'}',L}|More];
+tokens({tuple,L,[E|Es]}, More) ->
+ [{'{',L}|tokens(E, tokens_tuple(Es, ?line(E), More))].
+
+tokens_tail({cons,L,Head,Tail}, More) ->
+ [{',',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens_tail({nil,L}, More) ->
+ [{']',L}|More];
+tokens_tail(Other, More) ->
+ L = ?line(Other),
+ [{'|',L}|tokens(Other, [{']',L}|More])].
+
+tokens_tuple([E|Es], Line, More) ->
+ [{',',Line}|tokens(E, tokens_tuple(Es, ?line(E), More))];
+tokens_tuple([], Line, More) ->
+ [{'}',Line}|More].
+
+%% Give the relative precedences of operators.
+
+inop_prec('=') -> {150,100,100};
+inop_prec('!') -> {150,100,100};
+inop_prec('orelse') -> {160,150,150};
+inop_prec('andalso') -> {200,160,160};
+inop_prec('==') -> {300,200,300};
+inop_prec('/=') -> {300,200,300};
+inop_prec('=<') -> {300,200,300};
+inop_prec('<') -> {300,200,300};
+inop_prec('>=') -> {300,200,300};
+inop_prec('>') -> {300,200,300};
+inop_prec('=:=') -> {300,200,300};
+inop_prec('=/=') -> {300,200,300};
+inop_prec('++') -> {400,300,300};
+inop_prec('--') -> {400,300,300};
+inop_prec('+') -> {400,400,500};
+inop_prec('-') -> {400,400,500};
+inop_prec('bor') -> {400,400,500};
+inop_prec('bxor') -> {400,400,500};
+inop_prec('bsl') -> {400,400,500};
+inop_prec('bsr') -> {400,400,500};
+inop_prec('or') -> {400,400,500};
+inop_prec('xor') -> {400,400,500};
+inop_prec('*') -> {500,500,600};
+inop_prec('/') -> {500,500,600};
+inop_prec('div') -> {500,500,600};
+inop_prec('rem') -> {500,500,600};
+inop_prec('band') -> {500,500,600};
+inop_prec('and') -> {500,500,600};
+inop_prec('#') -> {800,700,800};
+inop_prec(':') -> {900,800,900};
+inop_prec('.') -> {900,900,1000}.
+
+-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'.
+
+-spec preop_prec(pre_op()) -> {0 | 600 | 700, 100 | 700 | 800}.
+
+preop_prec('catch') -> {0,100};
+preop_prec('+') -> {600,700};
+preop_prec('-') -> {600,700};
+preop_prec('bnot') -> {600,700};
+preop_prec('not') -> {600,700};
+preop_prec('#') -> {700,800}.
+
+-spec func_prec() -> {800,700}.
+
+func_prec() -> {800,700}.
+
+-spec max_prec() -> 1000.
+
+max_prec() -> 1000.
+
+parse(T) ->
+ bar:foo(T).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/big_local_type.erl b/lib/dialyzer/test/small_SUITE_data/src/big_local_type.erl
new file mode 100644
index 0000000000..fc7c5241a8
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/big_local_type.erl
@@ -0,0 +1,526 @@
+%%
+%% %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
+%%
+%% 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%
+%%
+
+%%% A stripped version of erl_parse.yrl.
+%%%
+%%% A type for the abstract format with *local* types has been added.
+%%% The type of the abstract format is not up-to-date, but it does not
+%%% matter since the purpose of the type is to stress the conversion
+%%% of type forms to erl_type().
+
+-module(big_local_type).
+
+-export([parse_form/1,parse_exprs/1,parse_term/1]).
+-export([normalise/1,tokens/1,tokens/2]).
+-export([inop_prec/1,preop_prec/1,func_prec/0,max_prec/0]).
+
+-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
+ error_info/0]).
+
+%% Start of Abstract Format
+
+-type line() :: erl_scan:line().
+
+-export_type([af_module/0, af_export/0, af_import/0, af_fa_list/0,
+ af_compile/0, af_file/0, af_record_decl/0,
+ af_field_decl/0, af_wild_attribute/0,
+ af_record_update/1, af_catch/0, af_local_call/0,
+ af_remote_call/0, af_args/0, af_local_function/0,
+ af_remote_function/0, af_list_comprehension/0,
+ af_binary_comprehension/0, af_template/0,
+ af_qualifier_seq/0, af_qualifier/0, af_generator/0,
+ af_filter/0, af_block/0, af_if/0, af_case/0, af_try/0,
+ af_clause_seq/0, af_catch_clause_seq/0, af_receive/0,
+ af_local_fun/0, af_remote_fun/0, af_fun/0, af_query/0,
+ af_query_access/0, af_clause/0,
+ af_catch_clause/0, af_catch_pattern/0, af_catch_class/0,
+ af_body/0, af_guard_seq/0, af_guard/0, af_guard_test/0,
+ af_record_access/1, af_guard_call/0,
+ af_remote_guard_call/0, af_pattern/0, af_literal/0,
+ af_atom/0, af_lit_atom/1, af_integer/0, af_float/0,
+ af_string/0, af_match/1, af_variable/0,
+ af_anon_variable/0, af_tuple/1, af_nil/0, af_cons/1,
+ af_bin/1, af_binelement/1, af_binelement_size/0,
+ af_binary_op/1, af_binop/0, af_unary_op/1, af_unop/0]).
+
+-type abstract_form() :: af_module()
+ | af_export()
+ | af_import()
+ | af_compile()
+ | af_file()
+ | af_record_decl()
+ | af_wild_attribute()
+ | af_function_decl().
+
+-type af_module() :: {attribute, line(), module, module()}.
+
+-type af_export() :: {attribute, line(), export, af_fa_list()}.
+
+-type af_import() :: {attribute, line(), import, af_fa_list()}.
+
+-type af_fa_list() :: [{function(), arity()}].
+
+-type af_compile() :: {attribute, line(), compile, any()}.
+
+-type af_file() :: {attribute, line(), file, {string(), line()}}.
+
+-type af_record_decl() ::
+ {attribute, line(), record, af_record_name(), [af_field_decl()]}.
+
+-type af_field_decl() :: {record_field, line(), af_atom()}
+ | {record_field, line(), af_atom(), abstract_expr()}.
+
+%% Types and specs, among other things...
+-type af_wild_attribute() :: {attribute, line(), af_atom(), any()}.
+
+-type af_function_decl() ::
+ {function, line(), function(), arity(), af_clause_seq()}.
+
+-type abstract_expr() :: af_literal()
+ | af_match(abstract_expr())
+ | af_variable()
+ | af_tuple(abstract_expr())
+ | af_nil()
+ | af_cons(abstract_expr())
+ | af_bin(abstract_expr())
+ | af_binary_op(abstract_expr())
+ | af_unary_op(abstract_expr())
+ | af_record_access(abstract_expr())
+ | af_record_update(abstract_expr())
+ | af_record_index()
+ | af_record_field(abstract_expr())
+ | af_catch()
+ | af_local_call()
+ | af_remote_call()
+ | af_list_comprehension()
+ | af_binary_comprehension()
+ | af_block()
+ | af_if()
+ | af_case()
+ | af_try()
+ | af_receive()
+ | af_local_fun()
+ | af_remote_fun()
+ | af_fun()
+ | af_query()
+ | af_query_access().
+
+-type af_record_update(T) :: {record,
+ line(),
+ abstract_expr(),
+ af_record_name(),
+ [af_record_field(T)]}.
+
+-type af_catch() :: {'catch', line(), abstract_expr()}.
+
+-type af_local_call() :: {call, line(), af_local_function(), af_args()}.
+
+-type af_remote_call() :: {call, line(), af_remote_function(), af_args()}.
+
+-type af_args() :: [abstract_expr()].
+
+-type af_local_function() :: abstract_expr().
+
+-type af_remote_function() ::
+ {remote, line(), abstract_expr(), abstract_expr()}.
+
+-type af_list_comprehension() ::
+ {lc, line(), af_template(), af_qualifier_seq()}.
+
+-type af_binary_comprehension() ::
+ {bc, line(), af_template(), af_qualifier_seq()}.
+
+-type af_template() :: abstract_expr().
+
+-type af_qualifier_seq() :: [af_qualifier()].
+
+-type af_qualifier() :: af_generator() | af_filter().
+
+-type af_generator() :: {generate, line(), af_pattern(), abstract_expr()}
+ | {b_generate, line(), af_pattern(), abstract_expr()}.
+
+-type af_filter() :: abstract_expr().
+
+-type af_block() :: {block, line(), af_body()}.
+
+-type af_if() :: {'if', line(), af_clause_seq()}.
+
+-type af_case() :: {'case', line(), abstract_expr(), af_clause_seq()}.
+
+-type af_try() :: {'try',
+ line(),
+ af_body(),
+ af_clause_seq(),
+ af_catch_clause_seq(),
+ af_body()}.
+
+-type af_clause_seq() :: [af_clause(), ...].
+
+-type af_catch_clause_seq() :: [af_clause(), ...].
+
+-type af_receive() ::
+ {'receive', line(), af_clause_seq()}
+ | {'receive', line(), af_clause_seq(), abstract_expr(), af_body()}.
+
+-type af_local_fun() :: {'fun', line(), {function, function(), arity()}}.
+
+-type af_remote_fun() ::
+ {'fun', line(), {function, module(), function(), arity()}}
+ | {'fun', line(), {function, af_atom(), af_atom(), af_integer()}}.
+
+-type af_fun() :: {'fun', line(), {clauses, af_clause_seq()}}.
+
+-type af_query() :: {'query', line(), af_list_comprehension()}.
+
+-type af_query_access() ::
+ {record_field, line(), abstract_expr(), af_field_name()}.
+
+-type abstract_clause() :: af_clause() | af_catch_clause().
+
+-type af_clause() ::
+ {clause, line(), [af_pattern()], af_guard_seq(), af_body()}.
+
+-type af_catch_clause() ::
+ {clause, line(), [af_catch_pattern()], af_guard_seq(), af_body()}.
+
+-type af_catch_pattern() ::
+ {af_catch_class(), af_pattern(), af_anon_variable()}.
+
+-type af_catch_class() ::
+ af_variable()
+ | af_lit_atom(throw) | af_lit_atom(error) | af_lit_atom(exit).
+
+-type af_body() :: [abstract_expr(), ...].
+
+-type af_guard_seq() :: [af_guard()].
+
+-type af_guard() :: [af_guard_test(), ...].
+
+-type af_guard_test() :: af_literal()
+ | af_variable()
+ | af_tuple(af_guard_test())
+ | af_nil()
+ | af_cons(af_guard_test())
+ | 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_index()
+ | af_record_field(af_guard_test())
+ | af_guard_call()
+ | af_remote_guard_call().
+
+-type af_record_access(T) ::
+ {record, line(), af_record_name(), [af_record_field(T)]}.
+
+-type af_guard_call() :: {call, line(), function(), [af_guard_test()]}.
+
+-type af_remote_guard_call() ::
+ {call, line(), atom(), af_lit_atom(erlang), [af_guard_test()]}.
+
+-type af_pattern() :: af_literal()
+ | af_match(af_pattern())
+ | af_variable()
+ | af_anon_variable()
+ | af_tuple(af_pattern())
+ | af_nil()
+ | af_cons(af_pattern())
+ | af_bin(af_pattern())
+ | af_binary_op(af_pattern())
+ | af_unary_op(af_pattern())
+ | af_record_index()
+ | af_record_field(af_pattern()).
+
+-type af_literal() :: af_atom() | af_integer() | af_float() | af_string().
+
+-type af_atom() :: af_lit_atom(atom()).
+
+-type af_lit_atom(A) :: {atom, line(), A}.
+
+-type af_integer() :: {integer, line(), non_neg_integer()}.
+
+-type af_float() :: {float, line(), float()}.
+
+-type af_string() :: {string, line(), [byte()]}.
+
+-type af_match(T) :: {match, line(), T, T}.
+
+-type af_variable() :: {var, line(), atom()}.
+
+-type af_anon_variable() :: {var, line(), '_'}.
+
+-type af_tuple(T) :: {tuple, line(), [T]}.
+
+-type af_nil() :: {nil, line()}.
+
+-type af_cons(T) :: {cons, line, T, T}.
+
+-type af_bin(T) :: {bin, line(), [af_binelement(T)]}.
+
+-type af_binelement(T) :: {bin_element,
+ line(),
+ T,
+ af_binelement_size(),
+ type_specifier_list()}.
+
+-type af_binelement_size() :: default | abstract_expr().
+
+-type af_binary_op(T) :: {op, line(), T, af_binop(), T}.
+
+-type af_binop() :: '/' | '*' | 'div' | 'rem' | 'band' | 'and' | '+' | '-'
+ | 'bor' | 'bxor' | 'bsl' | 'bsr' | 'or' | 'xor' | '++'
+ | '--' | '==' | '/=' | '=<' | '<' | '>=' | '>' | '=:='
+ | '=/='.
+
+-type af_unary_op(T) :: {op, line(), af_unop(), T}.
+
+-type af_unop() :: '+' | '*' | 'bnot' | 'not'.
+
+%% See also lib/stdlib/{src/erl_bits.erl,include/erl_bits.hrl}.
+-type type_specifier_list() :: default | [type_specifier(), ...].
+
+-type type_specifier() :: af_type()
+ | af_signedness()
+ | af_endianness()
+ | af_unit().
+
+-type af_type() :: integer
+ | float
+ | binary
+ | bytes
+ | bitstring
+ | bits
+ | utf8
+ | utf16
+ | utf32.
+
+-type af_signedness() :: signed | unsigned.
+
+-type af_endianness() :: big | little | native.
+
+-type af_unit() :: {unit, 1..256}.
+
+-type af_record_index() ::
+ {record_index, line(), af_record_name(), af_field_name()}.
+
+-type af_record_field(T) :: {record_field, line(), af_field_name(), T}.
+
+-type af_record_name() :: atom().
+
+-type af_field_name() :: atom().
+
+%% End of Abstract Format
+
+-type error_description() :: term().
+-type error_info() :: {erl_scan:line(), module(), error_description()}.
+-type token() :: {Tag :: atom(), Line :: erl_scan:line()}.
+
+%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
+%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
+
+-define(mkop2(L, OpPos, R),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,L,R}
+ end).
+
+-define(mkop1(OpPos, A),
+ begin
+ {Op,Pos} = OpPos,
+ {op,Pos,Op,A}
+ end).
+
+%% keep track of line info in tokens
+-define(line(Tup), element(2, Tup)).
+
+%% Entry points compatible to old erl_parse.
+%% These really suck and are only here until Calle gets multiple
+%% entry points working.
+
+-spec parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ AbsForm :: abstract_form(),
+ ErrorInfo :: error_info().
+parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
+ parse([{'-',L1},{'spec',L2}|Tokens]);
+parse_form([{'-',L1},{atom,L2,callback}|Tokens]) ->
+ parse([{'-',L1},{'callback',L2}|Tokens]);
+parse_form(Tokens) ->
+ parse(Tokens).
+
+-spec parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ ExprList :: [abstract_expr()],
+ ErrorInfo :: error_info().
+parse_exprs(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
+ {ok,Exprs};
+ {error,_} = Err -> Err
+ end.
+
+-spec parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ Term :: term(),
+ ErrorInfo :: error_info().
+parse_term(Tokens) ->
+ case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[Expr]}]}} ->
+ try normalise(Expr) of
+ Term -> {ok,Term}
+ catch
+ _:_R -> {error,{?line(Expr),?MODULE,"bad term"}}
+ end;
+ {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[_E1,E2|_Es]}]}} ->
+ {error,{?line(E2),?MODULE,"bad term"}};
+ {error,_} = Err -> Err
+ end.
+
+%% Convert between the abstract form of a term and a term.
+
+-spec normalise(AbsTerm) -> Data when
+ AbsTerm :: abstract_expr(),
+ Data :: term().
+normalise({char,_,C}) -> C;
+normalise({integer,_,I}) -> I;
+normalise({float,_,F}) -> F;
+normalise({atom,_,A}) -> A;
+normalise({string,_,S}) -> S;
+normalise({nil,_}) -> [];
+normalise({bin,_,Fs}) ->
+ {value, B, _} =
+ eval_bits:expr_grp(Fs, [],
+ fun(E, _) ->
+ {value, normalise(E), []}
+ end, [], true),
+ B;
+normalise({cons,_,Head,Tail}) ->
+ [normalise(Head)|normalise(Tail)];
+normalise({tuple,_,Args}) ->
+ list_to_tuple(normalise_list(Args));
+%% Atom dot-notation, as in 'foo.bar.baz'
+%% Special case for unary +/-.
+normalise({op,_,'+',{char,_,I}}) -> I;
+normalise({op,_,'+',{integer,_,I}}) -> I;
+normalise({op,_,'+',{float,_,F}}) -> F;
+normalise({op,_,'-',{char,_,I}}) -> -I; %Weird, but compatible!
+normalise({op,_,'-',{integer,_,I}}) -> -I;
+normalise({op,_,'-',{float,_,F}}) -> -F;
+normalise(X) -> erlang:error({badarg, X}).
+
+normalise_list([H|T]) ->
+ [normalise(H)|normalise_list(T)];
+normalise_list([]) ->
+ [].
+
+%% Generate a list of tokens representing the abstract term.
+
+-spec tokens(AbsTerm) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ Tokens :: [token()].
+tokens(Abs) ->
+ tokens(Abs, []).
+
+-spec tokens(AbsTerm, MoreTokens) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ MoreTokens :: [token()],
+ Tokens :: [token()].
+tokens({char,L,C}, More) -> [{char,L,C}|More];
+tokens({integer,L,N}, More) -> [{integer,L,N}|More];
+tokens({float,L,F}, More) -> [{float,L,F}|More];
+tokens({atom,L,A}, More) -> [{atom,L,A}|More];
+tokens({var,L,V}, More) -> [{var,L,V}|More];
+tokens({string,L,S}, More) -> [{string,L,S}|More];
+tokens({nil,L}, More) -> [{'[',L},{']',L}|More];
+tokens({cons,L,Head,Tail}, More) ->
+ [{'[',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens({tuple,L,[]}, More) ->
+ [{'{',L},{'}',L}|More];
+tokens({tuple,L,[E|Es]}, More) ->
+ [{'{',L}|tokens(E, tokens_tuple(Es, ?line(E), More))].
+
+tokens_tail({cons,L,Head,Tail}, More) ->
+ [{',',L}|tokens(Head, tokens_tail(Tail, More))];
+tokens_tail({nil,L}, More) ->
+ [{']',L}|More];
+tokens_tail(Other, More) ->
+ L = ?line(Other),
+ [{'|',L}|tokens(Other, [{']',L}|More])].
+
+tokens_tuple([E|Es], Line, More) ->
+ [{',',Line}|tokens(E, tokens_tuple(Es, ?line(E), More))];
+tokens_tuple([], Line, More) ->
+ [{'}',Line}|More].
+
+%% Give the relative precedences of operators.
+
+inop_prec('=') -> {150,100,100};
+inop_prec('!') -> {150,100,100};
+inop_prec('orelse') -> {160,150,150};
+inop_prec('andalso') -> {200,160,160};
+inop_prec('==') -> {300,200,300};
+inop_prec('/=') -> {300,200,300};
+inop_prec('=<') -> {300,200,300};
+inop_prec('<') -> {300,200,300};
+inop_prec('>=') -> {300,200,300};
+inop_prec('>') -> {300,200,300};
+inop_prec('=:=') -> {300,200,300};
+inop_prec('=/=') -> {300,200,300};
+inop_prec('++') -> {400,300,300};
+inop_prec('--') -> {400,300,300};
+inop_prec('+') -> {400,400,500};
+inop_prec('-') -> {400,400,500};
+inop_prec('bor') -> {400,400,500};
+inop_prec('bxor') -> {400,400,500};
+inop_prec('bsl') -> {400,400,500};
+inop_prec('bsr') -> {400,400,500};
+inop_prec('or') -> {400,400,500};
+inop_prec('xor') -> {400,400,500};
+inop_prec('*') -> {500,500,600};
+inop_prec('/') -> {500,500,600};
+inop_prec('div') -> {500,500,600};
+inop_prec('rem') -> {500,500,600};
+inop_prec('band') -> {500,500,600};
+inop_prec('and') -> {500,500,600};
+inop_prec('#') -> {800,700,800};
+inop_prec(':') -> {900,800,900};
+inop_prec('.') -> {900,900,1000}.
+
+-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'.
+
+-spec preop_prec(pre_op()) -> {0 | 600 | 700, 100 | 700 | 800}.
+
+preop_prec('catch') -> {0,100};
+preop_prec('+') -> {600,700};
+preop_prec('-') -> {600,700};
+preop_prec('bnot') -> {600,700};
+preop_prec('not') -> {600,700};
+preop_prec('#') -> {700,800}.
+
+-spec func_prec() -> {800,700}.
+
+func_prec() -> {800,700}.
+
+-spec max_prec() -> 1000.
+
+max_prec() -> 1000.
+
+parse(T) ->
+ bar:foo(T).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/blame_contract_range_suppressed.erl b/lib/dialyzer/test/small_SUITE_data/src/blame_contract_range_suppressed.erl
new file mode 100644
index 0000000000..8b66d35083
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/blame_contract_range_suppressed.erl
@@ -0,0 +1,15 @@
+%%-----------------------------------------------------------------------
+%% Like ./blame_contract_range.erl, but warning is suppressed.
+%%-----------------------------------------------------------------------
+-module(blame_contract_range_suppressed).
+
+-export([foo/0]).
+
+foo() ->
+ bar(b).
+
+-dialyzer({nowarn_function, bar/1}).
+
+-spec bar(atom()) -> a.
+bar(a) -> a;
+bar(b) -> b.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comparisons.erl b/lib/dialyzer/test/small_SUITE_data/src/comparisons.erl
index 70e3cb6af4..64927c6c91 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/comparisons.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/comparisons.erl
@@ -19,12 +19,20 @@ tuple(X) when is_tuple(X) -> X.
list() -> list(?r).
list(X) when is_list(X) -> X.
+map() -> map(?r).
+map(X) when is_map(X) -> #{}.
+
+bitstring() -> bitstring(?r).
+bitstring(X) when is_bitstring(X) -> <<0:63>>.
+
i() -> integer().
f() -> mfloat().
n() -> case ?r of 1 -> i(); 2 -> f() end.
a() -> atom().
t() -> tuple().
l() -> list().
+m() -> map().
+b() -> bitstring().
na() -> case ?r of 1 -> n(); 2 -> a() end.
at() -> case ?r of 1 -> t(); 2 -> a() end.
tl() -> case ?r of 1 -> t(); 2 -> l() end.
@@ -53,6 +61,14 @@ test_i_ll_l() -> case i() < l() of true -> always; false -> never end.
test_i_le_l() -> case i() =< l() of true -> always; false -> never end.
test_i_gg_l() -> case i() > l() of true -> never; false -> always end.
test_i_ge_l() -> case i() >= l() of true -> never; false -> always end.
+test_i_ll_m() -> case i() < m() of true -> always; false -> never end.
+test_i_le_m() -> case i() =< m() of true -> always; false -> never end.
+test_i_gg_m() -> case i() > m() of true -> never; false -> always end.
+test_i_ge_m() -> case i() >= m() of true -> never; false -> always end.
+test_i_ll_b() -> case i() < b() of true -> always; false -> never end.
+test_i_le_b() -> case i() =< b() of true -> always; false -> never end.
+test_i_gg_b() -> case i() > b() of true -> never; false -> always end.
+test_i_ge_b() -> case i() >= b() of true -> never; false -> always end.
test_f_ll_i() -> case f() < i() of true -> maybe; false -> maybe_too end.
test_f_le_i() -> case f() =< i() of true -> maybe; false -> maybe_too end.
@@ -78,6 +94,14 @@ test_f_ll_l() -> case f() < l() of true -> always; false -> never end.
test_f_le_l() -> case f() =< l() of true -> always; false -> never end.
test_f_gg_l() -> case f() > l() of true -> never; false -> always end.
test_f_ge_l() -> case f() >= l() of true -> never; false -> always end.
+test_f_ll_m() -> case f() < m() of true -> always; false -> never end.
+test_f_le_m() -> case f() =< m() of true -> always; false -> never end.
+test_f_gg_m() -> case f() > m() of true -> never; false -> always end.
+test_f_ge_m() -> case f() >= m() of true -> never; false -> always end.
+test_f_ll_b() -> case f() < b() of true -> always; false -> never end.
+test_f_le_b() -> case f() =< b() of true -> always; false -> never end.
+test_f_gg_b() -> case f() > b() of true -> never; false -> always end.
+test_f_ge_b() -> case f() >= b() of true -> never; false -> always end.
test_n_ll_i() -> case n() < i() of true -> maybe; false -> maybe_too end.
test_n_le_i() -> case n() =< i() of true -> maybe; false -> maybe_too end.
@@ -103,6 +127,14 @@ test_n_ll_l() -> case n() < l() of true -> always; false -> never end.
test_n_le_l() -> case n() =< l() of true -> always; false -> never end.
test_n_gg_l() -> case n() > l() of true -> never; false -> always end.
test_n_ge_l() -> case n() >= l() of true -> never; false -> always end.
+test_n_ll_m() -> case n() < m() of true -> always; false -> never end.
+test_n_le_m() -> case n() =< m() of true -> always; false -> never end.
+test_n_gg_m() -> case n() > m() of true -> never; false -> always end.
+test_n_ge_m() -> case n() >= m() of true -> never; false -> always end.
+test_n_ll_b() -> case n() < b() of true -> always; false -> never end.
+test_n_le_b() -> case n() =< b() of true -> always; false -> never end.
+test_n_gg_b() -> case n() > b() of true -> never; false -> always end.
+test_n_ge_b() -> case n() >= b() of true -> never; false -> always end.
test_a_ll_i() -> case a() < i() of true -> never; false -> always end.
test_a_le_i() -> case a() =< i() of true -> never; false -> always end.
@@ -128,6 +160,14 @@ test_a_ll_l() -> case a() < l() of true -> always; false -> never end.
test_a_le_l() -> case a() =< l() of true -> always; false -> never end.
test_a_gg_l() -> case a() > l() of true -> never; false -> always end.
test_a_ge_l() -> case a() >= l() of true -> never; false -> always end.
+test_a_ll_m() -> case a() < m() of true -> always; false -> never end.
+test_a_le_m() -> case a() =< m() of true -> always; false -> never end.
+test_a_gg_m() -> case a() > m() of true -> never; false -> always end.
+test_a_ge_m() -> case a() >= m() of true -> never; false -> always end.
+test_a_ll_b() -> case a() < b() of true -> always; false -> never end.
+test_a_le_b() -> case a() =< b() of true -> always; false -> never end.
+test_a_gg_b() -> case a() > b() of true -> never; false -> always end.
+test_a_ge_b() -> case a() >= b() of true -> never; false -> always end.
test_t_ll_i() -> case t() < i() of true -> never; false -> always end.
test_t_le_i() -> case t() =< i() of true -> never; false -> always end.
@@ -153,6 +193,14 @@ test_t_ll_l() -> case t() < l() of true -> always; false -> never end.
test_t_le_l() -> case t() =< l() of true -> always; false -> never end.
test_t_gg_l() -> case t() > l() of true -> never; false -> always end.
test_t_ge_l() -> case t() >= l() of true -> never; false -> always end.
+test_t_ll_m() -> case t() < m() of true -> always; false -> never end.
+test_t_le_m() -> case t() =< m() of true -> always; false -> never end.
+test_t_gg_m() -> case t() > m() of true -> never; false -> always end.
+test_t_ge_m() -> case t() >= m() of true -> never; false -> always end.
+test_t_ll_b() -> case t() < b() of true -> always; false -> never end.
+test_t_le_b() -> case t() =< b() of true -> always; false -> never end.
+test_t_gg_b() -> case t() > b() of true -> never; false -> always end.
+test_t_ge_b() -> case t() >= b() of true -> never; false -> always end.
test_l_ll_i() -> case l() < i() of true -> never; false -> always end.
test_l_le_i() -> case l() =< i() of true -> never; false -> always end.
@@ -178,6 +226,14 @@ test_l_ll_l() -> case l() < l() of true -> maybe; false -> maybe_too end.
test_l_le_l() -> case l() =< l() of true -> maybe; false -> maybe_too end.
test_l_gg_l() -> case l() > l() of true -> maybe; false -> maybe_too end.
test_l_ge_l() -> case l() >= l() of true -> maybe; false -> maybe_too end.
+test_l_ll_m() -> case l() < m() of true -> never; false -> always end.
+test_l_le_m() -> case l() =< m() of true -> never; false -> always end.
+test_l_gg_m() -> case l() > m() of true -> always; false -> never end.
+test_l_ge_m() -> case l() >= m() of true -> always; false -> never end.
+test_l_ll_b() -> case l() < b() of true -> always; false -> never end.
+test_l_le_b() -> case l() =< b() of true -> always; false -> never end.
+test_l_gg_b() -> case l() > b() of true -> never; false -> always end.
+test_l_ge_b() -> case l() >= b() of true -> never; false -> always end.
test_n_ll_na() -> case n() < na() of true -> maybe; false -> maybe_too end.
test_n_le_na() -> case n() =< na() of true -> maybe; false -> maybe_too end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl b/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl
index d7dfd9752e..dbabd904c2 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl
@@ -136,10 +136,14 @@ q(ab) -> rec2({a, b}); % breaks the contract
q(ba) -> rec2({b, a}); % breaks the contract
q(aba) -> rec2({a, {b, a}}); % breaks the contract
q(bab) -> rec2({b, {a, b}}); % breaks the contract
-q(abab) -> rec2({a, {b, {a, b}}});
-q(baba) -> rec2({b, {a, {b, a}}});
-q(ababa) -> rec2({a, {b, {a, {b, a}}}});
-q(babab) -> rec2({b, {a, {b, {a, b}}}}).
+q(abab) -> rec2({a, {b, {a, b}}}); % breaks the contract
+q(baba) -> rec2({b, {a, {b, a}}}); % breaks the contract
+q(ababa) -> rec2({a, {b, {a, {b, a}}}}); % breaks the contract
+q(babab) -> rec2({b, {a, {b, {a, b}}}}); % breaks the contract
+q(ababab) -> rec2({a, {b, {a, {b, {a, b}}}}});
+q(bababa) -> rec2({b, {a, {b, {a, {b, a}}}}});
+q(abababa) -> rec2({a, {b, {a, {b, {a, {b, a}}}}}});
+q(bababab) -> rec2({b, {a, {b, {a, {b, {a, b}}}}}}).
%===============================================================================
diff --git a/lib/dialyzer/test/small_SUITE_data/src/ditrap.erl b/lib/dialyzer/test/small_SUITE_data/src/ditrap.erl
new file mode 100644
index 0000000000..2d75f25bd5
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/ditrap.erl
@@ -0,0 +1,47 @@
+%% A bug reported by Tail-f Systems. The problem is that record types
+%% are included without properly limiting their depth.
+
+-module(ditrap).
+
+-define(tref(T), ?MODULE:T).
+-define(fref(T), ?MODULE:T).
+
+-export_type([ module_rec/0
+ , typedef_rec/0
+ , type_spec_fun/0
+ ]).
+
+-record(type, {
+ base :: 'builtin' | external:random_type() | ?tref(typedef_rec()),
+ type_spec_fun :: ?fref(type_spec_fun())
+ }).
+
+-record(typedef, {type :: #type{}}).
+
+-record(typedefs, {
+ map :: ?tref(typedef_rec()),
+ parent :: 'undefined' | #typedefs{}
+ }).
+
+-record(sn, {
+ module :: ?tref(module_rec()),
+ typedefs :: #typedefs{},
+ type :: 'undefined' | #type{},
+ keys :: 'undefined' | [#sn{}],
+ children = [] :: [#sn{}]
+ }).
+
+-record(augment, {children = [] :: [#sn{}]}).
+
+-record(module, {
+ submodules = [] :: [{#module{}, external:pos()}],
+ typedefs = #typedefs{} :: #typedefs{},
+ children = [] :: [#sn{}],
+ remote_augments = [] :: [{ModuleName :: atom(), [#augment{}]}],
+ local_augments = [] :: [#augment{}]
+ }).
+
+-type typedef_rec() :: #typedef{}.
+-type module_rec() :: #module{}.
+
+-type type_spec_fun() :: undefined | fun((#type{}, #module{}) -> any()).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl b/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl
new file mode 100644
index 0000000000..850d2fd331
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl
@@ -0,0 +1,127 @@
+%%--------------------------------------------------------------------------
+%% Module which contains calls to funs of different arity.
+%%--------------------------------------------------------------------------
+-module(fun_arity).
+
+-export([f_0_ok/0, f_0_ko/0]).
+-export([f_1_ok/0, f_1_ko/0]).
+
+-export([fa_0_ok/0, fa_0_ko/0]).
+-export([fa_1_ok/0, fa_1_ko/0]).
+
+-export([mfa_0_ok/0, mfa_0_ko/0, mf/0]).
+-export([mfa_1_ok/0, mfa_1_ko/0, mf/1]).
+
+-export([mfa_ne_0_ok/0, mfa_ne_0_ko/0]).
+-export([mfa_ne_1_ok/0, mfa_ne_1_ko/0]).
+
+-export([mfa_nd_0_ok/0, mfa_nd_0_ko/0]).
+-export([mfa_nd_1_ok/0, mfa_nd_1_ko/0]).
+
+-export(['Mfa_0_ok'/1, 'Mfa_0_ko'/1]).
+-export(['Mfa_1_ok'/1, 'Mfa_1_ko'/1]).
+
+-export(['mFa_0_ok'/1, 'mFa_0_ko'/1]).
+-export(['mFa_1_ok'/1, 'mFa_1_ko'/1]).
+
+-export(['MFa_0_ok'/2, 'MFa_0_ko'/2]).
+-export(['MFa_1_ok'/2, 'MFa_1_ko'/2]).
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun(...) -> ... end".
+
+f_0_ok() -> (fun_f_0())().
+f_0_ko() -> (fun_f_0())(1).
+fun_f_0() -> fun() -> ok end.
+
+f_1_ok() -> (fun_f_1())(1).
+f_1_ko() -> (fun_f_1())().
+fun_f_1() -> fun(_) -> ok end .
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun F/A" when F is literal atom and A is literal
+%% non-negative integer.
+
+fa_0_ok() -> (fun_fa_0())().
+fa_0_ko() -> (fun_fa_0())(1).
+fun_fa_0() -> fun f/0.
+f() -> ok.
+
+fa_1_ok() -> (fun_fa_1())(1).
+fa_1_ko() -> (fun_fa_1())().
+fun_fa_1() -> fun f/1.
+f(_) -> ok.
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is (defined and) exported.
+
+mfa_0_ok() -> (fun_mfa_0())().
+mfa_0_ko() -> (fun_mfa_0())(1).
+fun_mfa_0() -> fun ?MODULE:mf/0.
+mf() -> ok.
+
+mfa_1_ok() -> (fun_mfa_1())(1).
+mfa_1_ko() -> (fun_mfa_1())().
+fun_mfa_1() -> fun ?MODULE:mf/1.
+mf(_) -> ok.
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is defined but not exported.
+
+mfa_ne_0_ok() -> (fun_mfa_ne_0())().
+mfa_ne_0_ko() -> (fun_mfa_ne_0())(1).
+fun_mfa_ne_0() -> fun ?MODULE:mf_ne/0.
+mf_ne() -> ok.
+
+mfa_ne_1_ok() -> (fun_mfa_ne_1())(1).
+mfa_ne_1_ko() -> (fun_mfa_ne_1())().
+fun_mfa_ne_1() -> fun ?MODULE:mf_ne/1.
+mf_ne(_) -> ok.
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is not defined.
+
+mfa_nd_0_ok() -> (fun_mfa_nd_0())().
+mfa_nd_0_ko() -> (fun_mfa_nd_0())(1).
+fun_mfa_nd_0() -> fun ?MODULE:mf_nd/0.
+
+mfa_nd_1_ok() -> (fun_mfa_nd_1())(1).
+mfa_nd_1_ko() -> (fun_mfa_nd_1())().
+fun_mfa_nd_1() -> fun ?MODULE:mf_nd/1.
+
+%% Funs like "fun M:F/A" when M is variable, F is literal atoms and A
+%% is literal non-negative integer.
+
+'Mfa_0_ok'(M) -> ('fun_Mfa_0'(M))().
+'Mfa_0_ko'(M) -> ('fun_Mfa_0'(M))(1).
+'fun_Mfa_0'(M) -> fun M:f/0.
+
+'Mfa_1_ok'(M) -> ('fun_Mfa_1'(M))(1).
+'Mfa_1_ko'(M) -> ('fun_Mfa_1'(M))().
+'fun_Mfa_1'(M) -> fun M:f/1.
+
+%% Funs like "fun M:F/A" when M is literal atom, F is variable and A
+%% is literal non-negative integer.
+
+'mFa_0_ok'(F) -> ('fun_mFa_0'(F))().
+'mFa_0_ko'(F) -> ('fun_mFa_0'(F))(1).
+'fun_mFa_0'(F) -> fun ?MODULE:F/0.
+
+'mFa_1_ok'(F) -> ('fun_mFa_1'(F))(1).
+'mFa_1_ko'(F) -> ('fun_mFa_1'(F))().
+'fun_mFa_1'(F) -> fun ?MODULE:F/1.
+
+%% Funs like "fun M:F/A" when M and F are variables and A is literal
+%% non-negative integer.
+
+'MFa_0_ok'(M, F) -> ('fun_MFa_0'(M, F))().
+'MFa_0_ko'(M, F) -> ('fun_MFa_0'(M, F))(1).
+'fun_MFa_0'(M, F) -> fun M:F/0.
+
+'MFa_1_ok'(M, F) -> ('fun_MFa_1'(M, F))(1).
+'MFa_1_ko'(M, F) -> ('fun_MFa_1'(M, F))().
+'fun_MFa_1'(M, F) -> fun M:F/1.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/gs_make.erl b/lib/dialyzer/test/small_SUITE_data/src/gs_make.erl
index 2842e773c4..a942ebe374 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/gs_make.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/gs_make.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/dialyzer/test/small_SUITE_data/src/inv_mult.erl b/lib/dialyzer/test/small_SUITE_data/src/inv_mult.erl
new file mode 100644
index 0000000000..3413556813
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/inv_mult.erl
@@ -0,0 +1,15 @@
+%% Dialyzer was too constraining when checking the relation between the
+%% arguments and result of a multiplication. We should not constrain an argument
+%% if the other operand *may* be zero.
+%%
+%% Bug found by Kostis Sagonas, fixed by Stavros Aronis
+
+-module(inv_mult).
+-compile(export_all).
+
+main(L) ->
+ N = -1 * length(L),
+ fact(N).
+
+fact(0) -> 1;
+fact(N) -> N * fact(N-1).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/keydel.erl b/lib/dialyzer/test/small_SUITE_data/src/keydel.erl
new file mode 100644
index 0000000000..18a5c0670c
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/keydel.erl
@@ -0,0 +1,29 @@
+-module(keydel).
+
+-export([store/3]).
+
+-record(att, {f}).
+
+-type attachment() :: list().
+
+-opaque att() :: #att{} | attachment().
+
+-spec store(atom(), any(), att()) -> att().
+store(Field, undefined, Att) when is_list(Att) ->
+ lists:keydelete(Field, 1, Att);
+store(Field, Value, Att) when is_list(Att) ->
+ lists:keystore(Field, 1, Att, {Field, Value});
+store(Field, Value, Att) ->
+ store(Field, Value, upgrade(Att)).
+
+
+-spec upgrade(#att{}) -> attachment().
+upgrade(#att{} = Att) ->
+ Map = lists:zip(
+ record_info(fields, att),
+ lists:seq(2, record_info(size, att))
+ ),
+ %% Don't store undefined elements since that is default
+ [{F, element(I, Att)} || {F, I} <- Map, element(I, Att) /= undefined];
+upgrade(Att) ->
+ Att.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/maps1.erl b/lib/dialyzer/test/small_SUITE_data/src/maps1.erl
index 228ffe2c22..bb2f66a498 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/maps1.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/maps1.erl
@@ -10,7 +10,6 @@
-export([recv/3, decode/1]).
--export([get_my_map/0,is_my_map/1]).
%-record(can_pkt, {id, data :: binary(), timestamp}).
@@ -41,37 +40,14 @@ t2() -> ok.
update(#{ id := Id, val := Val } = M, X) when is_integer(Id) ->
M#{ val := [Val,X] }.
-%% key coalescing
-
--spec get_my_map() -> map().
-
-get_my_map() ->
- #{labels => [one, two],
- number => 27,
- [1,2,3] => wer,
- {4,5,6} => sdf,
- kvok => #{
- <<"wat">> => v,
- a => qwe,
- 2 => asd,
- [1,2,3] => wer,
- {4,5,6} => sdf,
- "abc" => zxc
- }
- }.
-
--spec is_my_map(map()) -> 'ok'.
-
-is_my_map(#{labels := [one, two],
- number := 27,
- [1,2,3] := wer,
- {4,5,6} := sdf,
- kvok := #{
- <<"wat">> := v,
- a := qwe,
- 2 := asd,
- [1,2,3] := wer,
- {4,5,6} := sdf,
- "abc" := zxc
- }
- }) -> ok.
+t3() ->
+ foo(#{greger => 3, #{arne=>anka} => 45}, 1).
+
+foo(#{} = M, b) -> %% Error
+ M#{alfa => 42, beta := 1337}.
+
+t4() ->
+ case #{} of
+ #{} -> ok;
+ Mod -> Mod:function(#{literal => map}, another_arg) %% Error
+ end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/maps_sum.erl b/lib/dialyzer/test/small_SUITE_data/src/maps_sum.erl
new file mode 100644
index 0000000000..a73ac555c9
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/maps_sum.erl
@@ -0,0 +1,31 @@
+-module(maps_sum).
+-export([correct1/1,
+ wrong1/1,
+ wrong2/1]).
+
+-spec correct1(#{atom() => term()}) -> integer().
+
+correct1(Data) ->
+ maps:fold(fun (_Key, Value, Acc) when is_integer(Value) ->
+ Acc + Value;
+ (_Key, _Value, Acc) ->
+ Acc
+ end, 0, Data).
+
+-spec wrong1([{atom(),term()}]) -> integer().
+
+wrong1(Data) ->
+ maps:fold(fun (_Key, Value, Acc) when is_integer(Value) ->
+ Acc + Value;
+ (_Key, _Value, Acc) ->
+ Acc
+ end, 0, Data).
+
+-spec wrong2(#{atom() => term()}) -> integer().
+
+wrong2(Data) ->
+ lists:foldl(fun (_Key, Value, Acc) when is_integer(Value) ->
+ Acc + Value;
+ (_Key, _Value, Acc) ->
+ Acc
+ end, 0, Data).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/predef2.erl b/lib/dialyzer/test/small_SUITE_data/src/predef2.erl
deleted file mode 100644
index b1d941a49a..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/predef2.erl
+++ /dev/null
@@ -1,56 +0,0 @@
--module(predef2).
-
--export([array/1, dict/1, digraph/1, digraph2/1, gb_set/1, gb_tree/1,
- queue/1, set/1, tid/0, tid2/0]).
-
--export_type([array/0, digraph/0, gb_set/0]).
-
--spec array(array()) -> array:array().
-
-array(A) ->
- array:relax(A).
-
--spec dict(dict()) -> dict:dict().
-
-dict(D) ->
- dict:store(1, a, D).
-
--spec digraph(digraph()) -> [digraph:edge()].
-
-digraph(G) ->
- digraph:edges(G).
-
--spec digraph2(digraph:graph()) -> [digraph:edge()].
-
-digraph2(G) ->
- digraph:edges(G).
-
--spec gb_set(gb_set()) -> gb_sets:set().
-
-gb_set(S) ->
- gb_sets:balance(S).
-
--spec gb_tree(gb_tree()) -> gb_trees:tree().
-
-gb_tree(S) ->
- gb_trees:balance(S).
-
--spec queue(queue()) -> queue:queue().
-
-queue(Q) ->
- queue:reverse(Q).
-
--spec set(set()) -> sets:set().
-
-set(S) ->
- sets:union([S]).
-
--spec tid() -> tid().
-
-tid() ->
- ets:new(tid, []).
-
--spec tid2() -> ets:tid().
-
-tid2() ->
- ets:new(tid, []).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/remote_field.erl b/lib/dialyzer/test/small_SUITE_data/src/remote_field.erl
index c34fa1b9dd..d83f2e3234 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/remote_field.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/remote_field.erl
@@ -3,7 +3,7 @@
-type f(T) :: {ssl:sslsocket(), T}.
-record(r1, { f1 :: f(_) }).
--type r1(T) :: #r1{ f1 :: fun((ssl:sslsocket(), T) -> any()) }.
+-type r1(T) :: #r1{ f1 :: {ssl:sslsocket(), T} }.
-record(state, {
r :: r1(T),
diff --git a/lib/dialyzer/test/small_SUITE_data/src/request1.erl b/lib/dialyzer/test/small_SUITE_data/src/request1.erl
new file mode 100644
index 0000000000..a6c4ab8dbd
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/request1.erl
@@ -0,0 +1,12 @@
+-module(request1).
+
+-export([a/0]).
+
+-dialyzer(unmatched_returns).
+
+a() ->
+ b(),
+ 1.
+
+b() ->
+ {a, b}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/suppress_request.erl b/lib/dialyzer/test/small_SUITE_data/src/suppress_request.erl
new file mode 100644
index 0000000000..c4275fa110
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/suppress_request.erl
@@ -0,0 +1,50 @@
+-module(suppress_request).
+
+-export([test1/1, test1_b/1, test2/0, test2_b/0,
+ test3/0, test3_b/0, test4/0, test4_b/0]).
+
+-dialyzer({[specdiffs], test1/1}).
+-spec test1(a | b) -> ok. % spec is subtype
+test1(A) ->
+ ok = test1_1(A).
+
+-spec test1_b(a | b) -> ok. % spec is subtype (suppressed by default)
+test1_b(A) ->
+ ok = test1_1(A).
+
+-spec test1_1(a | b | c) -> ok.
+test1_1(_) ->
+ ok.
+
+-dialyzer(unmatched_returns).
+test2() ->
+ tuple(), % unmatched
+ ok.
+
+test2_b() ->
+ tuple(), % unmatched
+ ok.
+
+-dialyzer({[no_return, no_match], [test3/0]}).
+test3() -> % no local return (suppressed)
+ A = fun(_) ->
+ 1
+ end,
+ A = 2. % can never succeed (suppressed)
+
+test3_b() -> % no local return (requested by default)
+ A = fun(_) ->
+ 1
+ end,
+ A = 2. % can never succeed (requested by default)
+
+-dialyzer(no_improper_lists).
+test4() ->
+ [1 | 2]. % improper list (suppressed)
+
+-dialyzer({no_improper_lists, test4_b/0}).
+test4_b() ->
+ [1 | 2]. % improper list (suppressed)
+
+tuple() ->
+ {a, b}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/suppression1.erl b/lib/dialyzer/test/small_SUITE_data/src/suppression1.erl
new file mode 100644
index 0000000000..00534704c3
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/suppression1.erl
@@ -0,0 +1,33 @@
+-module(suppression1).
+
+-export([a/1, b/1, c/0]).
+
+-dialyzer({nowarn_function, a/1}).
+
+-spec a(_) -> integer().
+
+a(_) ->
+ A = fun(_) ->
+ B = fun(_) ->
+ x = 7
+ end,
+ B = 1
+ end,
+ A.
+
+-spec b(_) -> integer().
+
+-dialyzer({nowarn_function, b/1}).
+
+b(_) ->
+ A = fun(_) ->
+ 1
+ end,
+ A = 2.
+
+-record(r, {a = a :: integer()}).
+
+-dialyzer({nowarn_function, c/0}).
+
+c() ->
+ #r{}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/suppression2.erl b/lib/dialyzer/test/small_SUITE_data/src/suppression2.erl
new file mode 100644
index 0000000000..4cba53fdce
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/suppression2.erl
@@ -0,0 +1,32 @@
+-module(suppression2).
+
+-export([a/1, b/1, c/0]).
+
+-dialyzer({nowarn_function, [a/1, b/1, c/0]}).
+-dialyzer([no_undefined_callbacks]).
+
+-behaviour(not_a_behaviour).
+
+-spec a(_) -> integer().
+
+a(_) ->
+ A = fun(_) ->
+ B = fun(_) ->
+ x = 7
+ end,
+ B = 1
+ end,
+ A.
+
+-spec b(_) -> integer().
+
+b(_) ->
+ A = fun(_) ->
+ 1
+ end,
+ A = 2.
+
+-record(r, {a = a :: integer()}).
+
+c() ->
+ #r{}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/suppression3.erl b/lib/dialyzer/test/small_SUITE_data/src/suppression3.erl
new file mode 100644
index 0000000000..4a745cffc2
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/suppression3.erl
@@ -0,0 +1,17 @@
+-module(suppression3).
+
+-export([a/1, b/1]).
+
+-dialyzer({nowarn_function, a/1}).
+
+-spec a(_) -> integer().
+
+a(A) ->
+ ?MODULE:missing(A).
+
+-dialyzer({no_missing_calls, b/1}).
+
+-spec b(_) -> integer().
+
+b(A) ->
+ ?MODULE:missing(A).
diff --git a/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options b/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options
index 6843119b9d..f7197ac30f 100644
--- a/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options
@@ -1 +1 @@
-{dialyzer_options, [{warnings, [underspecs, no_unknown]}]}.
+{dialyzer_options, [{warnings, [underspecs]}]}.
diff --git a/lib/dialyzer/test/user_SUITE_data/dialyzer_options b/lib/dialyzer/test/user_SUITE_data/dialyzer_options
index d20ecd389f..513ed7752b 100644
--- a/lib/dialyzer/test/user_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/user_SUITE_data/dialyzer_options
@@ -1,2 +1,2 @@
-{dialyzer_options, [{warnings, [no_unknown]}]}.
+{dialyzer_options, []}.
{time_limit, 3}. \ No newline at end of file
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 527afaf4ef..44982ab46d 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 2.7.4
+DIALYZER_VSN = 2.9
diff --git a/lib/diameter/Makefile b/lib/diameter/Makefile
index aa1c9f7f20..111530c75f 100644
--- a/lib/diameter/Makefile
+++ b/lib/diameter/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/bin/diameterc b/lib/diameter/bin/diameterc
index 2c9a8f555c..90588dadb5 100755
--- a/lib/diameter/bin/diameterc
+++ b/lib/diameter/bin/diameterc
@@ -6,16 +6,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/doc/src/Makefile b/lib/diameter/doc/src/Makefile
index 229812fd08..ae621c3e11 100644
--- a/lib/diameter/doc/src/Makefile
+++ b/lib/diameter/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/doc/src/book.xml b/lib/diameter/doc/src/book.xml
index 7b606c84d0..dd5a5ea30c 100644
--- a/lib/diameter/doc/src/book.xml
+++ b/lib/diameter/doc/src/book.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/depend.sed b/lib/diameter/doc/src/depend.sed
index 42de597f15..a878460b00 100644
--- a/lib/diameter/doc/src/depend.sed
+++ b/lib/diameter/doc/src/depend.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index ea175a58b8..5cb29c80e3 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -25,16 +25,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -466,7 +467,7 @@ Matches only those peers whose Origin-Host has the
specified value, or all peers if the atom <c>any</c>.</p>
</item>
-<tag><c>{realm, any|&dict_DiameterIdentity;</c></tag>
+<tag><c>{realm, any|&dict_DiameterIdentity;}</c></tag>
<item>
<p>
Matches only those peers whose Origin-Realm has the
@@ -499,18 +500,22 @@ Matches only those peers matched by each filter in the specified list.</p>
<item>
<p>
Matches only those peers matched by at least one filter in the
-specified list.</p>
+specified list.
+The resulting list will be in match order, peers matching the
+first filter of the list sorting before those matched by the second,
+and so on.</p>
+</item>
+<tag><c>{first, [&peer_filter;]}</c></tag>
+<item>
<p>
-The resulting peer list will be in match order, peers matching the
-first filter of the list sorting before those matched by the second,
-and so on.
-For example, the following filter causes peers matching both the host
-and realm filters to be presented before those matching only the realm
-filter.</p>
+Like <c>any</c>, but stops at the first filter for which there are
+matches, which can be much more efficient when there are many peers.
+For example, the following filter causes only peers best matching
+both the host and realm filters to be presented.</p>
<pre>
-{any, [{all, [host, realm]}, realm]}
+{first, [{all, [host, realm]}, realm]}
</pre>
</item>
@@ -794,14 +799,6 @@ Messages larger than the specified number of bytes are discarded.</p>
Defaults to <c>16777215</c>, the maximum value of the 24-bit Message
Length field in a Diameter Header.</p>
-<warning>
-<p>
-This option should be set to as low a value as is sufficient for the
-Diameter applications and peers in question, since decoding incoming
-messages from a malicious peer can otherwise generate significant
-load.</p>
-</warning>
-
</item>
<tag><c>{restrict_connections, false
@@ -920,6 +917,49 @@ Options <c>monitor</c> and <c>link</c> are ignored.</p>
Defaults to the empty list.</p>
</item>
+<marker id="strict_mbit"/>
+<tag><c>{strict_mbit, boolean()}</c></tag>
+<item>
+<p>
+Whether or not to regard an AVP setting the M-bit as erroneous when
+the command grammar in question does not explicitly allow the AVP.
+If <c>true</c> then such AVPs are regarded as 5001 errors,
+DIAMETER_AVP_UNSUPPORTED.
+If <c>false</c> then the M-bit is ignored and policing
+it becomes the receiver's responsibility.</p>
+
+<p>
+Defaults to <c>true</c>.</p>
+
+<warning>
+<p>
+RFC 6733 is unclear about the semantics of the M-bit.
+One the one hand, the CCF specification in section 3.2 documents AVP
+in a command grammar as meaning <b>any</b> arbitrary AVP; on the
+other hand, 1.3.4 states that AVPs setting the M-bit cannot be added
+to an existing command: the modified command must instead be
+placed in a new Diameter application.</p>
+<p>
+The reason for the latter is presumably interoperability:
+allowing arbitrary AVPs setting the M-bit in a command makes its
+interpretation implementation-dependent, since there's no
+guarantee that all implementations will understand the same set of
+arbitrary AVPs in the context of a given command.
+However, interpreting <c>AVP</c> in a command grammar as <b>any</b>
+AVP, regardless of M-bit, renders 1.3.4 meaningless, since the receiver
+can simply ignore any AVP it thinks isn't relevant, regardless of the
+sender's intent.</p>
+<p>
+Beware of confusing mandatory in the sense of the M-bit with mandatory
+in the sense of the command grammar.
+The former is a semantic requirement: that the receiver understand the
+semantics of the AVP in the context in question.
+The latter is a syntactic requirement: whether or not the AVP must
+occur in the message in question.</p>
+</warning>
+
+</item>
+
<marker id="string_decode"/>
<tag><c>{string_decode, boolean()}</c></tag>
<item>
@@ -1231,9 +1271,7 @@ is not the length of the message in question, as received over the
transport interface documented in &man_transport;.</p>
<p>
-If <c>exit</c> then a warning report is emitted and the parent of the
-transport process in question exits, which causes the transport
-process itself to exit as described in &man_transport;.
+If <c>exit</c> then the transport process in question exits.
If <c>handle</c> then the message is processed as usual, a resulting
&app_handle_request; or &app_handle_answer; callback (if one takes
place) indicating the <c>5015</c> error (DIAMETER_INVALID_MESSAGE_LENGTH).
diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml
index 67c430c40a..4cd25c18c2 100644
--- a/lib/diameter/doc/src/diameter_app.xml
+++ b/lib/diameter/doc/src/diameter_app.xml
@@ -17,16 +17,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_codec.xml b/lib/diameter/doc/src/diameter_codec.xml
index 308a56fab7..e2ebe7acf6 100644
--- a/lib/diameter/doc/src/diameter_codec.xml
+++ b/lib/diameter/doc/src/diameter_codec.xml
@@ -17,16 +17,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_dict.xml b/lib/diameter/doc/src/diameter_dict.xml
index 5cf1b174a0..087b24fb87 100644
--- a/lib/diameter/doc/src/diameter_dict.xml
+++ b/lib/diameter/doc/src/diameter_dict.xml
@@ -20,16 +20,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_examples.xml b/lib/diameter/doc/src/diameter_examples.xml
index 7808d64b8d..ba3b42b88d 100644
--- a/lib/diameter/doc/src/diameter_examples.xml
+++ b/lib/diameter/doc/src/diameter_examples.xml
@@ -10,16 +10,17 @@
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_intro.xml b/lib/diameter/doc/src/diameter_intro.xml
index 93293f2d8e..1718d1c612 100644
--- a/lib/diameter/doc/src/diameter_intro.xml
+++ b/lib/diameter/doc/src/diameter_intro.xml
@@ -12,16 +12,17 @@
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
+Licensed under the Apache License, Version 2.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
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_make.xml b/lib/diameter/doc/src/diameter_make.xml
index 0c7e6b794d..f53ad434ae 100644
--- a/lib/diameter/doc/src/diameter_make.xml
+++ b/lib/diameter/doc/src/diameter_make.xml
@@ -20,16 +20,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_sctp.xml b/lib/diameter/doc/src/diameter_sctp.xml
index 6302cb1435..09c5c33004 100644
--- a/lib/diameter/doc/src/diameter_sctp.xml
+++ b/lib/diameter/doc/src/diameter_sctp.xml
@@ -20,16 +20,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_soc.xml b/lib/diameter/doc/src/diameter_soc.xml
index d9159f84b5..2ba93bf452 100644
--- a/lib/diameter/doc/src/diameter_soc.xml
+++ b/lib/diameter/doc/src/diameter_soc.xml
@@ -14,16 +14,17 @@
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_soc_rfc6733.xml b/lib/diameter/doc/src/diameter_soc_rfc6733.xml
index 34ec902632..61931c6b5a 100644
--- a/lib/diameter/doc/src/diameter_soc_rfc6733.xml
+++ b/lib/diameter/doc/src/diameter_soc_rfc6733.xml
@@ -8,16 +8,17 @@
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_tcp.xml b/lib/diameter/doc/src/diameter_tcp.xml
index f6bbe7dd23..5fafec283c 100644
--- a/lib/diameter/doc/src/diameter_tcp.xml
+++ b/lib/diameter/doc/src/diameter_tcp.xml
@@ -31,16 +31,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_transport.xml b/lib/diameter/doc/src/diameter_transport.xml
index 1618d05c47..fd89fbc344 100644
--- a/lib/diameter/doc/src/diameter_transport.xml
+++ b/lib/diameter/doc/src/diameter_transport.xml
@@ -18,16 +18,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/diameter_using.xml b/lib/diameter/doc/src/diameter_using.xml
index 4427d29c3c..596a6861a1 100644
--- a/lib/diameter/doc/src/diameter_using.xml
+++ b/lib/diameter/doc/src/diameter_using.xml
@@ -10,16 +10,17 @@
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/files.mk b/lib/diameter/doc/src/files.mk
index 6e8b1f9068..72f26c769e 100644
--- a/lib/diameter/doc/src/files.mk
+++ b/lib/diameter/doc/src/files.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2010-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index c5df63a7f0..5052515d6a 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -15,16 +15,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -42,6 +43,249 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>diameter 1.11.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make peer handling more efficient.</p>
+ <p>
+ Inefficient lookup and manipulation of peer lists could
+ result in poor performance when many outgoing requests
+ were sent simultaneously, or when many peers connected
+ simultaneously. Filtering peer lists on realm/host is now
+ also more efficient in many cases.</p>
+ <p>
+ Own Id: OTP-13164</p>
+ </item>
+ <item>
+ <p>
+ Fix handling of shared peer connections in watchdog state
+ SUSPECT.</p>
+ <p>
+ A peer connection shared from a remote node was regarded
+ as being up for the lifetime of the connection, ignoring
+ watchdog transitions into state SUSPECT.</p>
+ <p>
+ Own Id: OTP-13342</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>diameter 1.11.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix request table leaks</p>
+ <p>
+ The End-to-End and Hop-by-Hop identifiers of outgoing
+ Diameter requests are stored in a table in order for the
+ caller to be located when the corresponding answer
+ message is received. Entries were orphaned if the handler
+ was terminated by an exit signal as a consequence of
+ actions taken by callback functions, or if callbacks
+ modified identifiers in retransmission cases.</p>
+ <p>
+ Own Id: OTP-13137</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>diameter 1.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix relay encode of nested, Grouped AVPs.</p>
+ <p>
+ A fault in OTP-12475 caused encode to fail if the first
+ AVP in a Grouped AVP was itself Grouped.</p>
+ <p>
+ Own Id: OTP-12879 Aux Id: OTP-12475 </p>
+ </item>
+ <item>
+ <p>
+ Match acceptable peer addresses case insensitively.</p>
+ <p>
+ Regular expressions passed in an 'accept' tuple to
+ diameter_tcp or diameter_sctp inappropriately matched
+ case.</p>
+ <p>
+ Own Id: OTP-12902</p>
+ </item>
+ <item>
+ <p>
+ Fix diameter_watchdog function clause.</p>
+ <p>
+ OTP-12912 introduced an error with accepting transports
+ setting <c>{restrict_connections, false}</c>, causing
+ processes to fail when peer connections were terminated.</p>
+ <p>
+ Own Id: OTP-12969</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Don't report 5005 (DIAMETER_AVP_MISSING) errors
+ unnecessarily.</p>
+ <p>
+ An AVP whose decode failed was reported as missing,
+ despite having been reported with another error as a
+ consequence of the failure.</p>
+ <p>
+ Own Id: OTP-12871</p>
+ </item>
+ <item>
+ <p>
+ Improve decode performance.</p>
+ <p>
+ The time required to decode a message increased
+ quadratically with the number of AVPs in the worst case,
+ leading to extremely long execution times.</p>
+ <p>
+ Own Id: OTP-12891</p>
+ </item>
+ <item>
+ <p>
+ Improve watchdog and statistics performance.</p>
+ <p>
+ Inefficient use of timers contributed to poor performance
+ at high load, as did ordering of the table statistics are
+ written to.</p>
+ <p>
+ Own Id: OTP-12912</p>
+ </item>
+ <item>
+ <p>
+ Add service_opt() strict_mbit.</p>
+ <p>
+ There are differing opinions on whether or not reception
+ of an arbitrary AVP setting the M-bit is an error. The
+ default interpretation is strict: if a command grammar
+ doesn't explicitly allow an AVP setting the M-bit then
+ reception of such an AVP is regarded as an error. Setting
+ <c>{strict_mbit, false}</c> disables this check.</p>
+ <p>
+ Own Id: OTP-12947</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>diameter 1.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix decode of Grouped AVPs containing errors.</p>
+ <p>
+ RFC 6733 says this of Failed-AVP in 7.5:</p>
+ <p>
+ <taglist><item><p><c> In the case where the offending AVP
+ is embedded within a Grouped AVP, the Failed-AVP MAY
+ contain the grouped AVP, which in turn contains the
+ single offending AVP. The same method MAY be employed if
+ the grouped AVP itself is embedded in yet another grouped
+ AVP and so on. In this case, the Failed-AVP MAY contain
+ the grouped AVP hierarchy up to the single offending AVP.
+ This enables the recipient to detect the location of the
+ offending AVP when embedded in a
+ group.</c></p></item></taglist></p>
+ <p>
+ It says this of DIAMETER_INVALID_AVP_LENGTH in 7.1.5:</p>
+ <p>
+ <taglist><item><p><c> The request contained an AVP with
+ an invalid length. A Diameter message indicating this
+ error MUST include the offending AVPs within a Failed-AVP
+ AVP. In cases where the erroneous AVP length value
+ exceeds the message length or is less than the minimum
+ AVP header length, it is sufficient to include the
+ offending AVP header and a zero filled payload of the
+ minimum required length for the payloads data type. If
+ the AVP is a Grouped AVP, the Grouped AVP header with an
+ empty payload would be sufficient to indicate the
+ offending AVP. In the case where the offending AVP header
+ cannot be fully decoded when the AVP length is less than
+ the minimum AVP header length, it is sufficient to
+ include an offending AVP header that is formulated by
+ padding the incomplete AVP header with zero up to the
+ minimum AVP header length.</c></p></item></taglist></p>
+ <p>
+ The AVPs placed in the errors field of a diameter_packet
+ record are intended to be appropriate for inclusion in a
+ Failed-AVP, but neither of the above paragraphs has been
+ followed in the Grouped case: the entire faulty AVP
+ (non-faulty components and all) has been included. This
+ made it difficult to identify the actual faulty AVP in
+ all but simple cases.</p>
+ <p>
+ The decode is now adapted to the RFC, and implements the
+ suggested single faulty AVP, nested in as many Grouped
+ containers as required.</p>
+ <p>
+ Own Id: OTP-12721</p>
+ </item>
+ <item>
+ <p>
+ Fix SCTP problems on Solaris.</p>
+ <p>
+ The allocation of association ids in Solaris was in
+ conflict with an assumption made in diameter_sctp,
+ resulting in failures when accepting multiple peer
+ connections.</p>
+ <p>
+ Own Id: OTP-12768</p>
+ </item>
+ <item>
+ <p>
+ Fix start order of alternate transports.</p>
+ <p>
+ A transport configured with diameter:add_transport/2 can
+ be passed multiple transport_module/transport_config
+ tuples in order to specify alternate configuration,
+ modules being attempted in order until one succeeds. This
+ is primarily for the connecting case; for example, to
+ allow a transport to be configured to first attempt
+ connection over SCTP, and then TCP in case SCTP fails.
+ Multiple module tuples can be paired with a single config
+ tuple, but in this case the start order was reversed
+ relative to the order in which the modules were specifed.</p>
+ <p>
+ Own Id: OTP-12851</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2.</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>diameter 1.9.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -87,7 +331,7 @@ first.</p>
</item>
<item>
<p>
- Don't confuse Result-Code and Experimental-Result</p>
+ Don't confuse Result-Code and Experimental-Result.</p>
<p>
The errors field of a decoded diameter_packet record was
populated with a Result-Code AVP when an
diff --git a/lib/diameter/doc/src/ref_man.xml b/lib/diameter/doc/src/ref_man.xml
index 62ba02b0b5..4781878fbb 100644
--- a/lib/diameter/doc/src/ref_man.xml
+++ b/lib/diameter/doc/src/ref_man.xml
@@ -10,16 +10,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/doc/src/seealso.ent b/lib/diameter/doc/src/seealso.ent
index 4e205ffad7..e5c284c6e8 100644
--- a/lib/diameter/doc/src/seealso.ent
+++ b/lib/diameter/doc/src/seealso.ent
@@ -6,16 +6,17 @@
Copyright Ericsson AB 2012-2015. All Rights Reserved.
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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%
diff --git a/lib/diameter/doc/src/seehere.sed b/lib/diameter/doc/src/seehere.sed
index c62a783d40..56932c4178 100644
--- a/lib/diameter/doc/src/seehere.sed
+++ b/lib/diameter/doc/src/seehere.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/diameter/doc/src/user_man.xml b/lib/diameter/doc/src/user_man.xml
index f915fa5a66..ac5bef95f5 100644
--- a/lib/diameter/doc/src/user_man.xml
+++ b/lib/diameter/doc/src/user_man.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/diameter/examples/code/GNUmakefile b/lib/diameter/examples/code/GNUmakefile
index 81f1da5a39..f5c2e5f869 100644
--- a/lib/diameter/examples/code/GNUmakefile
+++ b/lib/diameter/examples/code/GNUmakefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/diameter/examples/code/client.erl b/lib/diameter/examples/code/client.erl
index 844c9cdbdd..6fb90b1c09 100644
--- a/lib/diameter/examples/code/client.erl
+++ b/lib/diameter/examples/code/client.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/client_cb.erl b/lib/diameter/examples/code/client_cb.erl
index 843cdd9262..213c0b8bc6 100644
--- a/lib/diameter/examples/code/client_cb.erl
+++ b/lib/diameter/examples/code/client_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/node.erl b/lib/diameter/examples/code/node.erl
index 4fe9007059..246be4194b 100644
--- a/lib/diameter/examples/code/node.erl
+++ b/lib/diameter/examples/code/node.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/redirect.erl b/lib/diameter/examples/code/redirect.erl
index d4d94ab23a..393e30fe1b 100644
--- a/lib/diameter/examples/code/redirect.erl
+++ b/lib/diameter/examples/code/redirect.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/redirect_cb.erl b/lib/diameter/examples/code/redirect_cb.erl
index 8d98b0d2df..021d061e6d 100644
--- a/lib/diameter/examples/code/redirect_cb.erl
+++ b/lib/diameter/examples/code/redirect_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/relay.erl b/lib/diameter/examples/code/relay.erl
index 7bc46dc68d..3846b1d161 100644
--- a/lib/diameter/examples/code/relay.erl
+++ b/lib/diameter/examples/code/relay.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/relay_cb.erl b/lib/diameter/examples/code/relay_cb.erl
index 68798014e6..dba0f302ec 100644
--- a/lib/diameter/examples/code/relay_cb.erl
+++ b/lib/diameter/examples/code/relay_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/sctp.erl b/lib/diameter/examples/code/sctp.erl
index 08de023571..e0fed17fe3 100644
--- a/lib/diameter/examples/code/sctp.erl
+++ b/lib/diameter/examples/code/sctp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/server.erl b/lib/diameter/examples/code/server.erl
index f32cec594c..a91be70664 100644
--- a/lib/diameter/examples/code/server.erl
+++ b/lib/diameter/examples/code/server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/code/server_cb.erl b/lib/diameter/examples/code/server_cb.erl
index 071e152493..a2fb8fbda6 100644
--- a/lib/diameter/examples/code/server_cb.erl
+++ b/lib/diameter/examples/code/server_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/examples/dict/GNUmakefile b/lib/diameter/examples/dict/GNUmakefile
index 60c95c08f9..3f4178aa49 100644
--- a/lib/diameter/examples/dict/GNUmakefile
+++ b/lib/diameter/examples/dict/GNUmakefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/diameter/examples/dict/depend.sed b/lib/diameter/examples/dict/depend.sed
index fd9a38479c..1b91c493f0 100644
--- a/lib/diameter/examples/dict/depend.sed
+++ b/lib/diameter/examples/dict/depend.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/diameter/examples/dict/rfc4004_mip.dia b/lib/diameter/examples/dict/rfc4004_mip.dia
index 0595cfe9ef..61b2b6eec8 100644
--- a/lib/diameter/examples/dict/rfc4004_mip.dia
+++ b/lib/diameter/examples/dict/rfc4004_mip.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/examples/dict/rfc4005_nas.dia b/lib/diameter/examples/dict/rfc4005_nas.dia
index 6f0e7c1ce5..f5619259f0 100644
--- a/lib/diameter/examples/dict/rfc4005_nas.dia
+++ b/lib/diameter/examples/dict/rfc4005_nas.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/examples/dict/rfc4006_cc.dia b/lib/diameter/examples/dict/rfc4006_cc.dia
index b45ffc8090..2a9428fc84 100644
--- a/lib/diameter/examples/dict/rfc4006_cc.dia
+++ b/lib/diameter/examples/dict/rfc4006_cc.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/examples/dict/rfc4072_eap.dia b/lib/diameter/examples/dict/rfc4072_eap.dia
index 676b1b8b9b..53be6f445e 100644
--- a/lib/diameter/examples/dict/rfc4072_eap.dia
+++ b/lib/diameter/examples/dict/rfc4072_eap.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/examples/dict/rfc4590_digest.dia b/lib/diameter/examples/dict/rfc4590_digest.dia
index de68a6ef7e..3db91a21a7 100644
--- a/lib/diameter/examples/dict/rfc4590_digest.dia
+++ b/lib/diameter/examples/dict/rfc4590_digest.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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.
+;; Licensed under the Apache License, Version 2.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%
;;
diff --git a/lib/diameter/examples/dict/rfc4740_sip.dia b/lib/diameter/examples/dict/rfc4740_sip.dia
index cada3ac826..90f4d025e8 100644
--- a/lib/diameter/examples/dict/rfc4740_sip.dia
+++ b/lib/diameter/examples/dict/rfc4740_sip.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/include/diameter.hrl b/lib/diameter/include/diameter.hrl
index c2c271a9a3..91ddd56cd6 100644
--- a/lib/diameter/include/diameter.hrl
+++ b/lib/diameter/include/diameter.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,7 +40,7 @@
%%
-record(diameter_event,
{service, %% name
- info}). %% tuple()
+ info}). %% term()
%% diameter_packet records are passed through the encode/decode
%% interface supplied by a dictionary module configured on a Diameter
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index e8ffe7f92c..611ad796a9 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,10 @@
%% Key to a value in the process dictionary that determines whether or
%% not an unrecognized AVP setting the M-bit should be regarded as an
-%% error or not. See is_strict/0.
+%% error or not. See is_strict/0. This is only used to relax M-bit
+%% interpretation inside Grouped AVPs not setting the M-bit. The
+%% service_opt() strict_mbit can be used to disable the check
+%% globally.
-define(STRICT_KEY, strict).
%% Key that says whether or not we should do a best-effort decode
@@ -185,9 +189,10 @@ decode_avps(Name, Recs) ->
= lists:foldl(fun(T,A) -> decode(Name, T, A) end,
{[], {newrec(Name), []}},
Recs),
- {Rec, Avps, Failed ++ missing(Rec, Name)}.
-%% Append 5005 errors so that a 5014 for the same AVP will take
-%% precedence in a Result-Code/Failed-AVP setting.
+ {Rec, Avps, Failed ++ missing(Rec, Name, Failed)}.
+%% Append 5005 errors so that errors are reported in the order
+%% encountered. Failed-AVP should typically contain the first
+%% encountered error accordg to the RFC.
newrec(Name) ->
'#new-'(name2rec(Name)).
@@ -200,20 +205,36 @@ newrec(Name) ->
%% Failed-AVP AVP SHOULD be included in the message. The Failed-AVP
%% AVP MUST contain an example of the missing AVP complete with the
%% Vendor-Id if applicable. The value field of the missing AVP
-%% should be of correct minimum length and contain zeroes.
-
-missing(Rec, Name) ->
- [{5005, empty_avp(F)} || F <- '#info-'(element(1, Rec), fields),
- A <- [avp_arity(Name, F)],
- false <- [have_arity(A, '#get-'(F, Rec))]].
+%% should be of correct minimum length and contain zeros.
+
+missing(Rec, Name, Failed) ->
+ Avps = lists:foldl(fun({_, #diameter_avp{code = C, vendor_id = V}}, A) ->
+ sets:add_element({C,V}, A)
+ end,
+ sets:new(),
+ Failed),
+ [{5005, A} || F <- '#info-'(element(1, Rec), fields),
+ not has_arity(avp_arity(Name, F), '#get-'(F, Rec)),
+ #diameter_avp{code = C, vendor_id = V}
+ = A <- [empty_avp(F)],
+ not sets:is_element({C,V}, Avps)].
%% Maximum arities have already been checked in building the record.
-have_arity({Min, _}, L) ->
- Min =< length(L);
-have_arity(N, V) ->
+has_arity({Min, _}, L) ->
+ has_prefix(Min, L);
+has_arity(N, V) ->
N /= 1 orelse V /= undefined.
+%% Compare a non-negative integer and the length of a list without
+%% computing the length.
+has_prefix(0, _) ->
+ true;
+has_prefix(_, []) ->
+ false;
+has_prefix(N, L) ->
+ has_prefix(N-1, tl(L)).
+
%% empty_avp/1
empty_avp(Name) ->
@@ -333,16 +354,10 @@ d(Name, Avp, Acc) ->
{H, A} = ungroup(V, Avp),
{[H | Avps], pack_avp(Name, A, T)}
catch
- throw: {?TAG, {grouped, RC, ComponentAvps}} ->
- {Avps, {Rec, Errors}} = Acc,
- A = trim(Avp),
- {[[A | trim(ComponentAvps)] | Avps], {Rec, [{RC, A} | Errors]}};
+ throw: {?TAG, {grouped, Error, ComponentAvps}} ->
+ g(is_failed(), Error, Name, trim(Avp), Acc, ComponentAvps);
error: Reason ->
- d(undefined == Failed orelse is_failed(),
- Reason,
- Name,
- trim(Avp),
- Acc)
+ d(is_failed(), Reason, Name, trim(Avp), Acc)
after
reset(?STRICT_KEY, Strict),
reset(?FAILED_KEY, Failed)
@@ -380,6 +395,27 @@ dict(true) ->
dict(_) ->
?MODULE.
+%% g/5
+
+%% Ignore decode errors within Failed-AVP (best-effort) ...
+g(true, [_Error | Rec], Name, Avp, Acc, _ComponentAvps) ->
+ decode_AVP(Name, Avp#diameter_avp{value = Rec}, Acc);
+g(true, _Error, Name, Avp, Acc, _ComponentAvps) ->
+ decode_AVP(Name, Avp, Acc);
+
+%% ... or not.
+g(false, [Error | _Rec], _Name, Avp, Acc, ComponentAvps) ->
+ g(Error, Avp, Acc, ComponentAvps);
+g(false, Error, _Name, Avp, Acc, ComponentAvps) ->
+ g(Error, Avp, Acc, ComponentAvps).
+
+%% g/4
+
+g({RC, ErrorData}, Avp, Acc, ComponentAvps) ->
+ {Avps, {Rec, Errors}} = Acc,
+ E = Avp#diameter_avp{data = [ErrorData]},
+ {[[Avp | trim(ComponentAvps)] | Avps], {Rec, [{RC, E} | Errors]}}.
+
%% d/5
%% Ignore a decode error within Failed-AVP ...
@@ -415,7 +451,8 @@ relax(_, _) ->
false.
is_strict() ->
- false /= getr(?STRICT_KEY).
+ diameter_codec:getopt(strict_mbit)
+ andalso false /= getr(?STRICT_KEY).
%% relax/1
%%
@@ -424,14 +461,26 @@ is_strict() ->
%% Strictly, this doesn't need to be the case.
relax('Failed-AVP') ->
- is_failed() orelse putr(?FAILED_KEY, true);
+ putr(?FAILED_KEY, true);
relax(_) ->
is_failed().
-
+
+%% is_failed/0
+%%
+%% Is the AVP currently being decoded nested within Failed-AVP? Note
+%% that this is only true when Failed-AVP is the parent. In
+%% particular, it's not true when Failed-AVP itself is being decoded
+%% (unless nested).
+
is_failed() ->
true == getr(?FAILED_KEY).
+%% is_failed/1
+
+is_failed(Name) ->
+ 'Failed-AVP' == Name orelse is_failed().
+
%% reset/2
reset(Key, undefined) ->
@@ -451,8 +500,8 @@ decode_AVP(Name, Avp, {Avps, Acc}) ->
%% diameter_types will raise an error of this form to communicate
%% DIAMETER_INVALID_AVP_LENGTH (5014). A module specified to a
-%% @custom_types tag in a spec file can also raise an error of this
-%% form.
+%% @custom_types tag in a dictionary file can also raise an error of
+%% this form.
rc({'DIAMETER', 5014 = RC, _}, #diameter_avp{name = AvpName} = Avp) ->
{RC, Avp#diameter_avp{data = empty_value(AvpName)}};
@@ -528,17 +577,16 @@ pack_AVP(Name, #diameter_avp{is_mandatory = M, name = AvpName} = Avp, Acc) ->
%% allow for Failed-AVP in an answer-message.
pack_arity(Name, AvpName, M) ->
- IsFailed = Name == 'Failed-AVP' orelse is_failed(),
%% Not testing just Name /= 'Failed-AVP' means we're changing the
%% packing of AVPs nested within Failed-AVP, but the point of
%% ignoring errors within Failed-AVP is to decode as much as
%% possible, and failing because a mandatory AVP couldn't be
- %% packed into a dedicated field defeats that point. Note that we
- %% can't just test not is_failed() since this will be 'true' when
- %% packing an unknown AVP directly within Failed-AVP.
+ %% packed into a dedicated field defeats that point. Note
+ %% is_failed/1 since is_failed/0 will return false when packing
+ %% 'AVP' within Failed-AVP.
- pack_arity(IsFailed
+ pack_arity(is_failed(Name)
orelse {Name, AvpName} == {'answer-message', 'Failed-AVP'}
orelse not M
orelse not is_strict(),
@@ -581,14 +629,17 @@ pack(undefined, 1, FieldName, Avp, Acc) ->
%% AVP MUST be included and contain a copy of the first instance of
%% the offending AVP that exceeded the maximum number of occurrences
%%
+
pack(_, 1, _, Avp, {Rec, Failed}) ->
{Rec, [{5009, Avp} | Failed]};
-pack(L, {_, Max}, _, Avp, {Rec, Failed})
- when length(L) == Max ->
- {Rec, [{5009, Avp} | Failed]};
-
-pack(L, _, FieldName, Avp, Acc) ->
- p(FieldName, fun(V) -> [V|L] end, Avp, Acc).
+pack(L, {_, Max}, FieldName, Avp, Acc) ->
+ case '*' /= Max andalso has_prefix(Max, L) of
+ true ->
+ {Rec, Failed} = Acc,
+ {Rec, [{5009, Avp} | Failed]};
+ false ->
+ p(FieldName, fun(V) -> [V|L] end, Avp, Acc)
+ end.
%% p/4
@@ -610,9 +661,12 @@ value(_, Avp) ->
-> binary()
| no_return().
-%% Length error induced by diameter_codec:collect_avps/1.
+%% Length error induced by diameter_codec:collect_avps/1: the AVP
+%% length in the header was too short (insufficient for the extracted
+%% header) or too long (past the end of the message). An empty payload
+%% is sufficient according to the RFC text for 5014.
grouped_avp(decode, _Name, <<0:1, _/binary>>) ->
- throw({?TAG, {grouped, 5014, []}});
+ throw({?TAG, {grouped, {5014, []}, []}});
grouped_avp(decode, Name, Data) ->
grouped_decode(Name, diameter_codec:collect_avps(Data));
@@ -626,13 +680,28 @@ grouped_avp(encode, Name, Data) ->
%% decoded value, also returning the list of component diameter_avp
%% records.
+%% Length error in trailing component AVP.
grouped_decode(_Name, {Error, Acc}) ->
- {RC, Avp} = Error,
- throw({?TAG, {grouped, RC, [Avp | Acc]}});
-
+ {5014, Avp} = Error,
+ throw({?TAG, {grouped, Error, [Avp | Acc]}});
+
+%% 7.5. Failed-AVP AVP
+
+%% In the case where the offending AVP is embedded within a Grouped AVP,
+%% the Failed-AVP MAY contain the grouped AVP, which in turn contains
+%% the single offending AVP. The same method MAY be employed if the
+%% grouped AVP itself is embedded in yet another grouped AVP and so on.
+%% In this case, the Failed-AVP MAY contain the grouped AVP hierarchy up
+%% to the single offending AVP. This enables the recipient to detect
+%% the location of the offending AVP when embedded in a group.
+
+%% An error in decoding a component AVP throws the first fauly
+%% component, which the catch in d/3 wraps in the Grouped AVP in
+%% question. A partially decoded record is only used when ignoring
+%% errors in Failed-AVP.
grouped_decode(Name, ComponentAvps) ->
{Rec, Avps, Es} = decode_avps(Name, ComponentAvps),
- [] == Es orelse throw({?TAG, {grouped, 5004, Avps}}), %% decode failure
+ [] == Es orelse throw({?TAG, {grouped, [{_,_} = hd(Es) | Rec], Avps}}),
{Rec, Avps}.
%% ---------------------------------------------------------------------------
diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile
index 9afccf298c..e0bbbdfe63 100644
--- a/lib/diameter/src/Makefile
+++ b/lib/diameter/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/src/app.sed b/lib/diameter/src/app.sed
index 7916f65002..78e5bd2bad 100644
--- a/lib/diameter/src/app.sed
+++ b/lib/diameter/src/app.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl
index 010f977b97..de88f6befd 100644
--- a/lib/diameter/src/base/diameter.erl
+++ b/lib/diameter/src/base/diameter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -311,6 +312,7 @@ call(SvcName, App, Message) ->
| {sequence, sequence() | evaluable()}
| {share_peers, remotes()}
| {string_decode, boolean()}
+ | {strict_mbit, boolean()}
| {incoming_maxlen, message_length()}
| {use_shared_peers, remotes()}
| {spawn_opt, list()}.
diff --git a/lib/diameter/src/base/diameter_app.erl b/lib/diameter/src/base/diameter_app.erl
index 600f7ff04d..6f0c78094a 100644
--- a/lib/diameter/src/base/diameter_app.erl
+++ b/lib/diameter/src/base/diameter_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/base/diameter_callback.erl b/lib/diameter/src/base/diameter_callback.erl
index 90431099b0..70c70fb5bd 100644
--- a/lib/diameter/src/base/diameter_callback.erl
+++ b/lib/diameter/src/base/diameter_callback.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/base/diameter_capx.erl b/lib/diameter/src/base/diameter_capx.erl
index 7dc61f229f..07a678c617 100644
--- a/lib/diameter/src/base/diameter_capx.erl
+++ b/lib/diameter/src/base/diameter_capx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index bf2fe8e7ca..1ea5357924 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -76,9 +77,10 @@ setopts(Opts)
when is_list(Opts) ->
lists:foreach(fun setopt/1, Opts).
-%% Decode stringish types to string()? The default true is for
-%% backwards compatibility.
-setopt({string_decode = K, false = B}) ->
+%% The default string_decode true is for backwards compatibility.
+setopt({K, false = B})
+ when K == string_decode;
+ K == strict_mbit ->
setopt(K, B);
%% Regard anything but the generated RFC 3588 dictionary as modern.
@@ -96,7 +98,8 @@ setopt(Key, Value) ->
getopt(Key) ->
case get({diameter, Key}) of
- undefined when Key == string_decode ->
+ undefined when Key == string_decode;
+ Key == strict_mbit ->
true;
undefined when Key == rfc ->
6733;
@@ -590,6 +593,7 @@ split_head(<<Code:32, 0:1, M:1, P:1, _:5, Len:24, _/binary>>) ->
%% Header is truncated.
split_head(Bin) ->
?THROW({5014, #diameter_avp{data = Bin}}).
+%% Note that pack_avp/1 will pad this at encode if sent in a Failed-AVP.
%% 3588:
%%
@@ -619,7 +623,7 @@ split_head(Bin) ->
%% AVP header with zero up to the minimum AVP header length.
%%
%% The underlined clause must be in error since (1) a header less than
-%% the minimum value mean we don't know the identity of the AVP and
+%% the minimum value mean we might not know the identity of the AVP and
%% (2) the last sentence covers this case.
%% split_data/3
@@ -655,16 +659,23 @@ split_data(Bin, Len) ->
%% The normal case here is data as an #diameter_avp{} list or an
%% iolist, which are the cases that generated codec modules use. The
-%% other case is as a convenience in the relay case in which the
+%% other cases are a convenience in the relay case in which the
%% dictionary doesn't know about specific AVP's.
-%% Grouped AVP whose components need packing ...
-pack_avp([#diameter_avp{} = A | Avps]) ->
- pack_avp(A#diameter_avp{data = Avps});
-pack_avp(#diameter_avp{data = [#diameter_avp{} | _] = Avps} = A) ->
- pack_avp(A#diameter_avp{data = encode_avps(Avps)});
+%% Decoded Grouped AVP with decoded components: ignore components
+%% since they're already encoded in the Grouped AVP.
+pack_avp([#diameter_avp{} = Grouped | _Components]) ->
+ pack_avp(Grouped);
+
+%% Grouped AVP whose components need packing. It's intentional that
+%% this isn't equivalent to [Grouped | Components]: here the
+%% components need to be encoded before wrapping with the Grouped AVP,
+%% and the list is flat, nesting being accomplished in the data
+%% fields.
+pack_avp(#diameter_avp{data = [#diameter_avp{} | _] = Components} = Grouped) ->
+ pack_avp(Grouped#diameter_avp{data = encode_avps(Components)});
-%% ... data as a type/value tuple ...
+%% Data as a type/value tuple ...
pack_avp(#diameter_avp{data = {Type, Value}} = A)
when is_atom(Type) ->
pack_avp(A#diameter_avp{data = diameter_types:Type(encode, Value)});
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index 8ac3b9d6ca..702f11593a 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,8 +38,7 @@
-module(diameter_config).
-behaviour(gen_server).
--compile({no_auto_import, [monitor/2, now/0]}).
--import(diameter_lib, [now/0]).
+-compile({no_auto_import, [monitor/2]}).
-export([start_service/2,
stop_service/1,
@@ -69,7 +69,7 @@
-include("diameter_internal.hrl").
%% Server state.
--record(state, {id = now()}).
+-record(state, {id = diameter_lib:now()}).
%% Registered name of the server.
-define(SERVER, ?MODULE).
@@ -647,6 +647,7 @@ make_config(SvcName, Opts) ->
{?NOMASK, sequence},
{nodes, restrict_connections},
{16#FFFFFF, incoming_maxlen},
+ {true, strict_mbit},
{true, string_decode},
{[], spawn_opt}]),
@@ -685,12 +686,14 @@ opt(K, false = B)
K == use_shared_peers;
K == monitor;
K == restrict_connections;
+ K == strict_mbit;
K == string_decode ->
B;
opt(K, true = B)
when K == share_peers;
K == use_shared_peers;
+ K == strict_mbit;
K == string_decode ->
B;
diff --git a/lib/diameter/src/base/diameter_dict.erl b/lib/diameter/src/base/diameter_dict.erl
index 3b9ba00a3f..1013690a5b 100644
--- a/lib/diameter/src/base/diameter_dict.erl
+++ b/lib/diameter/src/base/diameter_dict.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/base/diameter_internal.hrl b/lib/diameter/src/base/diameter_internal.hrl
index 4b672aa071..518c0b9b1f 100644
--- a/lib/diameter/src/base/diameter_internal.hrl
+++ b/lib/diameter/src/base/diameter_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/base/diameter_lib.erl b/lib/diameter/src/base/diameter_lib.erl
index 3f327f3653..43b0ca24ab 100644
--- a/lib/diameter/src/base/diameter_lib.erl
+++ b/lib/diameter/src/base/diameter_lib.erl
@@ -3,22 +3,24 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(diameter_lib).
-compile({no_auto_import, [now/0]}).
+-compile({nowarn_deprecated_function, [{erlang, now, 0}]}).
-export([info_report/2,
error_report/2,
@@ -101,32 +103,18 @@ fmt(T) ->
%% # now/0
%% ---------------------------------------------------------------------------
--type timestamp() :: {non_neg_integer(), 0..999999, 0..999999}.
--type now() :: integer() %% monotonic time
- | timestamp().
-
-spec now()
- -> now().
-
-%% Use monotonic time if it exists, fall back to erlang:now()
-%% otherwise.
+ -> integer().
now() ->
- try
- erlang:monotonic_time()
- catch
- error: undef -> erlang:now()
- end.
+ erlang:monotonic_time().
%% ---------------------------------------------------------------------------
%% # timestamp/1
%% ---------------------------------------------------------------------------
--spec timestamp(NowT :: now())
- -> timestamp().
-
-timestamp({_,_,_} = T) -> %% erlang:now()
- T;
+-spec timestamp(integer())
+ -> erlang:timestamp().
timestamp(MonoT) -> %% monotonic time
MicroSecs = monotonic_to_microseconds(MonoT + erlang:time_offset()),
@@ -140,30 +128,27 @@ monotonic_to_microseconds(MonoT) ->
%% # now_diff/1
%% ---------------------------------------------------------------------------
--spec now_diff(NowT :: now())
+-spec now_diff(T0 :: integer())
-> {Hours, Mins, Secs, MicroSecs}
when Hours :: non_neg_integer(),
Mins :: 0..59,
Secs :: 0..59,
MicroSecs :: 0..999999.
-%% Return timer:now_diff(now(), NowT) as an {H, M, S, MicroS} tuple
-%% instead of as integer microseconds.
+%% Return time difference as an {H, M, S, MicroS} tuple instead of as
+%% integer microseconds.
-now_diff(Time) ->
- time(micro_diff(Time)).
+now_diff(T0) ->
+ time(micro_diff(T0)).
%% ---------------------------------------------------------------------------
%% # micro_diff/1
%% ---------------------------------------------------------------------------
--spec micro_diff(NowT :: now())
+-spec micro_diff(T0 :: integer())
-> MicroSecs
when MicroSecs :: non_neg_integer().
-micro_diff({_,_,_} = T0) ->
- timer:now_diff(erlang:now(), T0);
-
micro_diff(T0) -> %% monotonic time
monotonic_to_microseconds(erlang:monotonic_time() - T0).
@@ -171,16 +156,12 @@ micro_diff(T0) -> %% monotonic time
%% # micro_diff/2
%% ---------------------------------------------------------------------------
--spec micro_diff(T1 :: now(), T0 :: now())
+-spec micro_diff(T1 :: integer(), T0 :: integer())
-> MicroSecs
when MicroSecs :: non_neg_integer().
-micro_diff(T1, T0)
- when is_integer(T1), is_integer(T0) -> %% monotonic time
- monotonic_to_microseconds(T1 - T0);
-
-micro_diff(T1, T0) -> %% at least one erlang:now()
- timer:now_diff(timestamp(T1), timestamp(T0)).
+micro_diff(T1, T0) -> %% monotonic time
+ monotonic_to_microseconds(T1 - T0).
%% ---------------------------------------------------------------------------
%% # time/1
@@ -188,19 +169,13 @@ micro_diff(T1, T0) -> %% at least one erlang:now()
%% Return an elapsed time as an {H, M, S, MicroS} tuple.
%% ---------------------------------------------------------------------------
--spec time(NowT | Diff)
+-spec time(Diff :: non_neg_integer())
-> {Hours, Mins, Secs, MicroSecs}
- when NowT :: timestamp(),
- Diff :: non_neg_integer(),
- Hours :: non_neg_integer(),
+ when Hours :: non_neg_integer(),
Mins :: 0..59,
Secs :: 0..59,
MicroSecs :: 0..999999.
-time({_,_,_} = NowT) -> %% time of day
- %% 24 hours = 24*60*60*1000000 = 86400000000 microsec
- time(timer:now_diff(NowT, {0,0,0}) rem 86400000000);
-
time(Micro) -> %% elapsed time
Seconds = Micro div 1000000,
H = Seconds div 3600,
@@ -213,7 +188,7 @@ time(Micro) -> %% elapsed time
%% ---------------------------------------------------------------------------
-spec seed()
- -> {timestamp(), {integer(), integer(), integer()}}.
+ -> {erlang:timestamp(), {integer(), integer(), integer()}}.
%% Return an argument for random:seed/1.
@@ -223,9 +198,6 @@ seed() ->
%% seed/1
-seed({_,_,_} = T) ->
- T;
-
seed(T) -> %% monotonic time
{erlang:phash2(node()), T, erlang:unique_integer()}.
diff --git a/lib/diameter/src/base/diameter_misc_sup.erl b/lib/diameter/src/base/diameter_misc_sup.erl
index 4e40476f14..2054ea7831 100644
--- a/lib/diameter/src/base/diameter_misc_sup.erl
+++ b/lib/diameter/src/base/diameter_misc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/base/diameter_peer.erl b/lib/diameter/src/base/diameter_peer.erl
index 89b63c8a92..2759f17e64 100644
--- a/lib/diameter/src/base/diameter_peer.erl
+++ b/lib/diameter/src/base/diameter_peer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -20,9 +21,6 @@
-module(diameter_peer).
-behaviour(gen_server).
--compile({no_auto_import, [now/0]}).
--import(diameter_lib, [now/0]).
-
%% Interface towards transport modules ...
-export([recv/2,
up/1,
@@ -59,7 +57,7 @@
-define(SERVER, ?MODULE).
%% Server state.
--record(state, {id = now()}).
+-record(state, {id = diameter_lib:now()}).
%% Default transport_module/config.
-define(DEFAULT_TMOD, diameter_tcp).
@@ -121,7 +119,7 @@ pair([{transport_module, M} | Rest], Mods, Acc) ->
pair([{transport_config = T, C} | Rest], Mods, Acc) ->
pair([{T, C, ?DEFAULT_TTMO} | Rest], Mods, Acc);
pair([{transport_config, C, Tmo} | Rest], Mods, Acc) ->
- pair(Rest, [], acc({Mods, C, Tmo}, Acc));
+ pair(Rest, [], acc({lists:reverse(Mods), C, Tmo}, Acc));
pair([_ | Rest], Mods, Acc) ->
pair(Rest, Mods, Acc);
@@ -130,13 +128,16 @@ pair([_ | Rest], Mods, Acc) ->
pair([], [], []) ->
[{[?DEFAULT_TMOD], ?DEFAULT_TCFG, ?DEFAULT_TTMO}];
-%% One transport_module, one transport_config.
-pair([], [M], [{[], Cfg, Tmo}]) ->
- [{[M], Cfg, Tmo}];
+%% One transport_module, one transport_config: ignore option order.
+%% That is, interpret [{transport_config, _}, {transport_module, _}]
+%% as if the order was reversed, not as config with default module and
+%% module with default config.
+pair([], [_] = Mods, [{[], Cfg, Tmo}]) ->
+ [{Mods, Cfg, Tmo}];
%% Trailing transport_module: default transport_config.
pair([], [_|_] = Mods, Acc) ->
- lists:reverse(acc({Mods, ?DEFAULT_TCFG, ?DEFAULT_TTMO}, Acc));
+ pair([{transport_config, ?DEFAULT_TCFG}], Mods, Acc);
pair([], [], Acc) ->
lists:reverse(def(Acc)).
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index 2255d0a76b..2b23183d18 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -119,7 +120,6 @@
service :: #diameter_service{},
dpr = false :: false
| true %% DPR received, DPA sent
- | {uint32(), uint32()} %% set in old code
| {boolean(), uint32(), uint32()},
%% hop by hop and end to end identifiers in
%% outgoing DPR; boolean says whether or not
@@ -155,8 +155,7 @@
%% # start/3
%% ---------------------------------------------------------------------------
--spec start(T, [Opt], {[diameter:service_opt()]
- | diameter:sequence(), %% from old code
+-spec start(T, [Opt], {[diameter:service_opt()],
[node()],
module(),
#diameter_service{}})
@@ -195,9 +194,6 @@ init(T) ->
proc_lib:init_ack({ok, self()}),
gen_server:enter_loop(?MODULE, [], i(T)).
-i({Ack, WPid, T, Opts, {{_,_} = Mask, Nodes, Dict0, Svc}}) -> %% from old code
- i({Ack, WPid, T, Opts, {[{sequence, Mask}], Nodes, Dict0, Svc}});
-
i({Ack, WPid, {M, Ref} = T, Opts, {SvcOpts, Nodes, Dict0, Svc}}) ->
erlang:monitor(process, WPid),
wait(Ack, WPid),
@@ -319,7 +315,7 @@ handle_info(T, #state{} = State) ->
?LOG(stop, Reason),
{stop, {shutdown, Reason}, State};
stop ->
- ?LOG(stop, T),
+ ?LOG(stop, truncate(T)),
{stop, {shutdown, T}, State}
catch
exit: {diameter_codec, encode, T} = Reason ->
@@ -329,14 +325,11 @@ handle_info(T, #state{} = State) ->
{?MODULE, Tag, Reason} ->
?LOG(stop, Tag),
{stop, {shutdown, Reason}, State}
- end;
+ end.
%% The form of the throw caught here is historical. It's
%% significant that it's not a 2-tuple, as in ?FAILURE(Reason),
%% since these are caught elsewhere.
-handle_info(T, S) -> %% started in old code
- handle_info(T, #state{} = erlang:append_element(S, infinity)).
-
%% Note that there's no guarantee that the service and transport
%% capabilities are good enough to build a CER/CEA that can be
%% succesfully encoded. It's not checked at diameter:add_transport/2
@@ -355,6 +348,11 @@ code_change(_, State, _) ->
%% ---------------------------------------------------------------------------
%% ---------------------------------------------------------------------------
+truncate({'DOWN' = T, _, process, Pid, _}) ->
+ {T, Pid};
+truncate(T) ->
+ T.
+
putr(Key, Val) ->
put({?MODULE, Key}, Val).
@@ -366,9 +364,6 @@ eraser(Key) ->
%% transition/2
-transition(T, #state{dpr = {Hid, Eid}} = S) -> %% DPR sent from old code
- transition(T, S#state{dpr = {false, Hid, Eid}});
-
%% Connection to peer.
transition({diameter, {TPid, connected, Remote}},
#state{transport = TPid,
@@ -1296,25 +1291,15 @@ dpa_timer(Tmo) ->
erlang:send_after(Tmo, self(), dpa_timeout).
dpa_timeout() ->
- dpa_timeout(getr(?DPA_KEY)).
-
-dpa_timeout({_, Tmo}) ->
- Tmo;
-dpa_timeout(undefined) -> %% set in old code
- ?DPA_TIMEOUT;
-dpa_timeout(Tmo) -> %% ditto
+ {_, Tmo} = getr(?DPA_KEY),
Tmo.
dpr_timer() ->
dpa_timer(dpr_timeout()).
dpr_timeout() ->
- dpr_timeout(getr(?DPA_KEY)).
-
-dpr_timeout({Tmo, _}) ->
- Tmo;
-dpr_timeout(_) -> %% set in old code
- ?DPR_TIMEOUT.
+ {Tmo, _} = getr(?DPA_KEY),
+ Tmo.
%% register_everywhere/1
%%
diff --git a/lib/diameter/src/base/diameter_peer_fsm_sup.erl b/lib/diameter/src/base/diameter_peer_fsm_sup.erl
index 995eaf74d0..54bd06929d 100644
--- a/lib/diameter/src/base/diameter_peer_fsm_sup.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/base/diameter_reg.erl b/lib/diameter/src/base/diameter_reg.erl
index f785777874..7f198080ba 100644
--- a/lib/diameter/src/base/diameter_reg.erl
+++ b/lib/diameter/src/base/diameter_reg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,8 +25,7 @@
-module(diameter_reg).
-behaviour(gen_server).
--compile({no_auto_import, [monitor/2, now/0]}).
--import(diameter_lib, [now/0]).
+-compile({no_auto_import, [monitor/2]}).
-export([add/1,
add_new/1,
@@ -67,7 +67,7 @@
%% Table entry containing the Term -> Pid mapping.
-define(MAPPING(Term, Pid), {Term, Pid}).
--record(state, {id = now(),
+-record(state, {id = diameter_lib:now(),
q = []}). %% [{From, Pat}]
%% ===========================================================================
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 86e744dfbe..87ef2e522d 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,9 +25,6 @@
-module(diameter_service).
-behaviour(gen_server).
--compile({no_auto_import, [now/0]}).
--import(diameter_lib, [now/0]).
-
%% towards diameter_service_sup
-export([start_link/1]).
@@ -85,16 +83,8 @@
-define(DEFAULT_TC, 30000). %% RFC 3588 ch 2.1
-define(RESTART_TC, 1000). %% if restart was this recent
-%% Used to be able to swap this with anything else dict-like but now
-%% rely on the fact that a service's #state{} record does not change
-%% in storing in it ?STATE table and not always going through the
-%% service process. In particular, rely on the fact that operations on
-%% a ?Dict don't change the handle to it.
--define(Dict, diameter_dict).
-
-%% Maintains state in a table. In contrast to previously, a service's
-%% stat is not constant and is accessed outside of the service
-%% process.
+%% Maintain state in a table since a service's state is accessed
+%% outside of the service process.
-define(STATE_TABLE, ?MODULE).
%% The default sequence mask.
@@ -114,23 +104,23 @@
%% to determine whether or not we need to call the process for a
%% pick_peer callback in the statefull case.
-record(state,
- {id = now(),
+ {id = diameter_lib:now(),
service_name :: diameter:service_name(), %% key in ?STATE_TABLE
service :: #diameter_service{},
watchdogT = ets_new(watchdogs) %% #watchdog{} at start
:: ets:tid(),
- peerT = ets_new(peers) %% #peer{pid = TPid} at okay/reopen
- :: ets:tid(),
- shared_peers = ?Dict:new() %% Alias -> [{TPid, Caps}, ...]
- :: ets:tid(),
- local_peers = ?Dict:new() %% Alias -> [{TPid, Caps}, ...]
- :: ets:tid(),
+ peerT, %% undefined in new code, but remain for upgrade
+ shared_peers, %% reasons. Replaced by local/remote.
+ local_peers, %%
+ local :: {ets:tid(), ets:tid(), ets:tid()},
+ remote :: {ets:tid(), ets:tid(), ets:tid()},
monitor = false :: false | pid(), %% process to die with
options
:: [{sequence, diameter:sequence()} %% sequence mask
| {share_peers, diameter:remotes()} %% broadcast to
| {use_shared_peers, diameter:remotes()} %% use from
| {restrict_connections, diameter:restriction()}
+ | {strict_mbit, boolean()}
| {string_decode, boolean()}
| {incoming_maxlen, diameter:message_length()}]}).
%% shared_peers reflects the peers broadcast from remote nodes.
@@ -143,18 +133,20 @@
ref :: match(reference()), %% key into diameter_config
options :: match([diameter:transport_opt()]),%% from start_transport
state = ?WD_INITIAL :: match(wd_state()),
- started = now(), %% at process start
+ started = diameter_lib:now(),%% at process start
peer = false :: match(boolean() | pid())}).
%% true at accepted, pid() at okay/reopen
-%% Record representing an Peer State Machine processes implemented by
+%% Record representing a Peer State Machine processes implemented by
%% diameter_peer_fsm.
-record(peer,
- {pid :: pid(),
- apps :: [{0..16#FFFFFFFF, diameter:app_alias()}], %% {Id, Alias}
- caps :: #diameter_caps{},
- started = now(), %% at process start
- watchdog :: pid()}). %% key into watchdogT
+ {pid :: pid(),
+ apps :: match([{0..16#FFFFFFFF, diameter:app_alias()}] %% {Id, Alias}
+ | [diameter:app_alias()]), %% remote
+ caps :: match(#diameter_caps{}),
+ started = diameter_lib:now(), %% at process start or sharing
+ watchdog :: match(pid() %% key into watchdogT
+ | undefined)}). %% undefined if remote
%% ---------------------------------------------------------------------------
%% # start/1
@@ -182,7 +174,7 @@ stop(SvcName) ->
end.
stop(ok, Pid) ->
- MRef = erlang:monitor(process, Pid),
+ MRef = monitor(process, Pid),
receive {'DOWN', MRef, process, _, _} -> ok end;
stop(No, _) ->
No.
@@ -209,7 +201,7 @@ stop_transport(SvcName, [_|_] = Refs) ->
info(SvcName, Item) ->
case lookup_state(SvcName) of
- [#state{} = S] ->
+ [S] ->
service_info(Item, S);
[] ->
undefined
@@ -218,7 +210,12 @@ info(SvcName, Item) ->
%% lookup_state/1
lookup_state(SvcName) ->
- ets:lookup(?STATE_TABLE, SvcName).
+ case ets:lookup(?STATE_TABLE, SvcName) of
+ [#state{}] = L ->
+ L;
+ _ ->
+ []
+ end.
%% ---------------------------------------------------------------------------
%% # subscribe/1
@@ -491,6 +488,9 @@ transition({service, Pid}, S) ->
transition({peer, TPid, Aliases, Caps}, S) ->
remote_peer_up(TPid, Aliases, Caps, S),
ok;
+transition({peer, TPid}, S) ->
+ remote_peer_down(TPid, S),
+ ok;
%% Remote peer process has died.
transition({'DOWN', _, process, TPid, _}, S) ->
@@ -510,7 +510,7 @@ transition(Req, S) ->
%% # terminate/2
%% ---------------------------------------------------------------------------
-terminate(Reason, #state{service_name = Name, peerT = PeerT} = S) ->
+terminate(Reason, #state{service_name = Name, local = {PeerT, _, _}} = S) ->
send_event(Name, stop),
ets:delete(?STATE_TABLE, Name),
@@ -532,23 +532,80 @@ terminate(Reason, #state{service_name = Name, peerT = PeerT} = S) ->
%% # code_change/3
%% ---------------------------------------------------------------------------
-code_change(FromVsn,
- #state{service_name = SvcName,
- service = #diameter_service{applications = Apps}}
- = S,
- Extra) ->
- lists:foreach(fun(A) ->
- code_change(FromVsn, SvcName, Extra, A)
- end,
- Apps),
+code_change(_FromVsn, #state{} = S, _Extra) ->
+ {ok, S};
+
+%% Don't support downgrade since we won't in appup.
+code_change({down = T, _}, _, _Extra) ->
+ {error, T};
+
+%% Upgrade local/shared peers dicts populated in old code. Don't
+code_change(_FromVsn, S0, _Extra) ->
+ {state, Id, SvcName, Svc, WT, PeerT, SDict, LDict, Monitor, Opts}
+ = S0,
+
+ init_peers(LT = setelement(1, {PT, _, _} = init_peers(), PeerT),
+ fun({_,A}) -> A end),
+ init_peers(init_peers(RT = init_peers(), SDict),
+ fun(A) -> A end),
+
+ S = #state{id = Id,
+ service_name = SvcName,
+ service = Svc,
+ watchdogT = WT,
+ peerT = PT, %% empty
+ shared_peers = SDict,
+ local_peers = LDict,
+ local = LT,
+ remote = RT,
+ monitor = Monitor,
+ options = Opts},
+
+ %% Replacing the table entry and deleting the old shared tables
+ %% can make outgoing requests return {error, no_connection} until
+ %% everyone is running new code. Don't delete the tables to avoid
+ %% crashing request processes.
+ ets:delete_all_objects(SDict),
+ ets:delete_all_objects(LDict),
+ ets:insert(?STATE_TABLE, S),
{ok, S}.
-code_change(FromVsn, SvcName, Extra, #diameter_app{alias = Alias} = A) ->
- {ok, S} = cb(A, code_change, [FromVsn,
- mod_state(Alias),
- Extra,
- SvcName]),
- mod_state(Alias, S).
+%% init_peers/2
+
+%% Populate app and identity bags from a new-style #peer{} sets.
+init_peers({PeerT, _, _} = T, F)
+ when is_function(F) ->
+ ets:foldl(fun(#peer{pid = P, apps = As, caps = C}, N) ->
+ insert_peer(P, lists:map(F, As), C, T),
+ N+1
+ end,
+ 0,
+ PeerT);
+
+%% Populate #peer{} table given a shared peers dict.
+init_peers({PeerT, _, _}, SDict) ->
+ dict:fold(fun(P, As, N) ->
+ ets:update_element(PeerT, P, {#peer.apps, As}),
+ N+1
+ end,
+ 0,
+ diameter_dict:fold(fun(A, Ps, D) ->
+ init_peers(A, Ps, PeerT, D)
+ end,
+ dict:new(),
+ SDict)).
+
+%% init_peers/4
+
+init_peers(App, TCs, PeerT, Dict) ->
+ lists:foldl(fun({P,C}, D) ->
+ ets:insert(PeerT, #peer{pid = P,
+ apps = [],
+ caps = C}),
+ dict:append(P, App, D)
+ end,
+ Dict,
+ TCs).
%% ===========================================================================
%% ===========================================================================
@@ -556,9 +613,6 @@ code_change(FromVsn, SvcName, Extra, #diameter_app{alias = Alias} = A) ->
unexpected(F, A, #state{service_name = Name}) ->
?UNEXPECTED(F, A ++ [Name]).
-cb(#diameter_app{module = [_|_] = M}, F, A) ->
- eval(M, F, A).
-
eval([M|X], F, A) ->
apply(M, F, A ++ X).
@@ -578,10 +632,6 @@ choose(false, _, X) -> X.
ets_new(Tbl) ->
ets:new(Tbl, [{keypos, 2}]).
-insert(Tbl, Rec) ->
- ets:insert(Tbl, Rec),
- Rec.
-
%% Using the process dictionary for the callback state was initially
%% just a way to make what was horrendous trace (big state record and
%% much else everywhere) somewhat more readable. There's not as much
@@ -682,6 +732,8 @@ cfg_acc({SvcName, #diameter_service{applications = Apps} = Rec, Opts},
lists:foreach(fun init_mod/1, Apps),
S = #state{service_name = SvcName,
service = Rec#diameter_service{pid = self()},
+ local = init_peers(),
+ remote = init_peers(),
monitor = mref(get_value(monitor, Opts)),
options = service_options(Opts)},
{S, Acc};
@@ -691,6 +743,13 @@ cfg_acc({_Ref, Type, _Opts} = T, {S, Acc})
Type == listen ->
{S, [T | Acc]}.
+init_peers() ->
+ {ets_new(caps), %% #peer{}
+ ets:new(apps, [bag]), %% {Alias, TPid}
+ ets:new(idents, [bag])}. %% {{host, OH} | {realm, OR} | {OR, OH},
+ %% Alias,
+ %% TPid}
+
service_options(Opts) ->
[{sequence, proplists:get_value(sequence, Opts, ?NOMASK)},
{share_peers, get_value(share_peers, Opts)},
@@ -700,13 +759,14 @@ service_options(Opts) ->
?RESTRICT)},
{spawn_opt, proplists:get_value(spawn_opt, Opts, [])},
{string_decode, proplists:get_value(string_decode, Opts, true)},
- {incoming_maxlen, proplists:get_value(incoming_maxlen, Opts, 16#FFFFFF)}].
+ {incoming_maxlen, proplists:get_value(incoming_maxlen, Opts, 16#FFFFFF)},
+ {strict_mbit, proplists:get_value(strict_mbit, Opts, true)}].
%% The order of options is significant since we match against the list.
mref(false = No) ->
No;
mref(P) ->
- erlang:monitor(process, P).
+ monitor(process, P).
init_shared(#state{options = [_, _, {_,T} | _],
service_name = Svc}) ->
@@ -805,7 +865,7 @@ start(Ref, Type, Opts, State) ->
%% start/5
start(Ref, Type, Opts, N, #state{watchdogT = WatchdogT,
- peerT = PeerT,
+ local = {PeerT, _, _},
options = SvcOpts,
service_name = SvcName,
service = Svc0})
@@ -836,7 +896,7 @@ binary_caps(#diameter_service{capabilities = Caps} = Svc, false) ->
wd(Type, Ref, T, WatchdogT, Rec) ->
Pid = start_watchdog(Type, Ref, T),
- insert(WatchdogT, Rec#watchdog{pid = Pid}),
+ ets:insert(WatchdogT, Rec#watchdog{pid = Pid}),
Pid.
%% Note that the service record passed into the watchdog is the merged
@@ -893,8 +953,8 @@ accepted(Pid, _TPid, #state{watchdogT = WatchdogT} = S) ->
#watchdog{ref = Ref, type = accept = T, peer = false, options = Opts}
= Wd
= fetch(WatchdogT, Pid),
- insert(WatchdogT, Wd#watchdog{peer = true}),%% mark replacement as started
- start(Ref, T, Opts, S). %% start new watchdog
+ ets:insert(WatchdogT, Wd#watchdog{peer = true}),%% mark replacement started
+ start(Ref, T, Opts, S). %% start new watchdog
fetch(Tid, Key) ->
[T] = ets:lookup(Tid, Key),
@@ -920,13 +980,14 @@ watchdog(TPid, [], ?WD_SUSPECT, ?WD_OKAY, Wd, State) ->
#watchdog{peer = TPid} = Wd, %% assert
connection_up(Wd, State);
-%% Watchdog has an unresponsive connection.
+%% Watchdog has an unresponsive connection. Note that the peer table
+%% entry isn't removed until DOWN.
watchdog(TPid, [], ?WD_OKAY, ?WD_SUSPECT = To, Wd, State) ->
#watchdog{peer = TPid} = Wd, %% assert
watchdog_down(Wd, To, State);
%% Watchdog has lost its connection.
-watchdog(TPid, [], _, ?WD_DOWN = To, Wd, #state{peerT = PeerT} = S) ->
+watchdog(TPid, [], _, ?WD_DOWN = To, Wd, #state{local = {PeerT, _, _}} = S) ->
close(Wd),
watchdog_down(Wd, To, S),
ets:delete(PeerT, TPid);
@@ -935,7 +996,7 @@ watchdog(_, [], _, _, _, _) ->
ok.
watchdog_down(Wd, To, #state{watchdogT = WatchdogT} = S) ->
- insert(WatchdogT, Wd#watchdog{state = To}),
+ ets:insert(WatchdogT, Wd#watchdog{state = To}),
connection_down(Wd, To, S).
%% ---------------------------------------------------------------------------
@@ -947,14 +1008,14 @@ watchdog_down(Wd, To, #state{watchdogT = WatchdogT} = S) ->
connection_up({TPid, {Caps, SupportedApps, Pkt}},
#watchdog{pid = Pid}
= Wd,
- #state{peerT = PeerT}
+ #state{local = {PeerT, _, _}}
= S) ->
- Pr = #peer{pid = TPid,
- apps = SupportedApps,
- caps = Caps,
- watchdog = Pid},
- insert(PeerT, Pr),
- connection_up([Pkt], Wd#watchdog{peer = TPid}, Pr, S).
+ Rec = #peer{pid = TPid,
+ apps = SupportedApps,
+ caps = Caps,
+ watchdog = Pid},
+ ets:insert(PeerT, Rec),
+ connection_up([Pkt], Wd#watchdog{peer = TPid}, Rec, S).
%% ---------------------------------------------------------------------------
%% # reopen/3
@@ -964,22 +1025,23 @@ reopen({TPid, {Caps, SupportedApps, _Pkt}},
#watchdog{pid = Pid}
= Wd,
#state{watchdogT = WatchdogT,
- peerT = PeerT}) ->
- insert(PeerT, #peer{pid = TPid,
- apps = SupportedApps,
- caps = Caps,
- watchdog = Pid}),
- insert(WatchdogT, Wd#watchdog{state = ?WD_REOPEN,
- peer = TPid}).
+ local = {PeerT, _, _}}) ->
+ ets:insert(PeerT, #peer{pid = TPid,
+ apps = SupportedApps,
+ caps = Caps,
+ watchdog = Pid}),
+ ets:insert(WatchdogT, Wd#watchdog{state = ?WD_REOPEN,
+ peer = TPid}).
%% ---------------------------------------------------------------------------
%% # connection_up/2
%% ---------------------------------------------------------------------------
-%% Watchdog has recovered as suspect connection. Note that there has
+%% Watchdog has recovered a suspect connection. Note that there has
%% been no new capabilties exchange in this case.
-connection_up(#watchdog{peer = TPid} = Wd, #state{peerT = PeerT} = S) ->
+connection_up(#watchdog{peer = TPid} = Wd, #state{local = {PeerT, _, _}}
+ = S) ->
connection_up([], Wd, fetch(PeerT, TPid), S).
%% connection_up/4
@@ -990,23 +1052,23 @@ connection_up(Extra,
#peer{apps = SApps, caps = Caps}
= Pr,
#state{watchdogT = WatchdogT,
- local_peers = LDict,
+ local = LT,
service_name = SvcName,
service = #diameter_service{applications = Apps}}
= S) ->
- insert(WatchdogT, Wd#watchdog{state = ?WD_OKAY}),
+ ets:insert(WatchdogT, Wd#watchdog{state = ?WD_OKAY}),
diameter_traffic:peer_up(TPid),
- insert_local_peer(SApps, {{TPid, Caps}, {SvcName, Apps}}, LDict),
+ local_peer_up(SApps, {TPid, Caps}, {SvcName, Apps}, LT),
report_status(up, Wd, Pr, S, Extra).
-insert_local_peer(SApps, T, LDict) ->
- lists:foldl(fun(A,D) -> ilp(A, T, D) end, LDict, SApps).
+local_peer_up(SApps, {TPid, Caps} = TC, SA, LT) ->
+ insert_peer(TPid, [A || {_,A} <- SApps], Caps, LT),
+ lists:foreach(fun(A) -> peer_up(A, TC, SA) end, SApps).
-ilp({Id, Alias}, {TC, SA}, LDict) ->
- init_conn(Id, Alias, TC, SA),
- ?Dict:append(Alias, TC, LDict).
+peer_up({Id, Alias}, TC, SA) ->
+ peer_up(Id, Alias, TC, SA).
-init_conn(Id, Alias, {TPid, _} = TC, {SvcName, Apps}) ->
+peer_up(Id, Alias, {TPid, _} = TC, {SvcName, Apps}) ->
#diameter_app{id = Id} %% assert
= App
= find_app(Alias, Apps),
@@ -1104,17 +1166,17 @@ connection_down(#watchdog{state = ?WD_OKAY,
= Pr,
#state{service_name = SvcName,
service = #diameter_service{applications = Apps},
- local_peers = LDict}
+ local = LT}
= S) ->
report_status(down, Wd, Pr, S, []),
- remove_local_peer(SApps, {{TPid, Caps}, {SvcName, Apps}}, LDict),
+ local_peer_down(SApps, {TPid, Caps}, {SvcName, Apps}, LT),
diameter_traffic:peer_down(TPid);
connection_down(#watchdog{state = ?WD_OKAY,
peer = TPid}
= Wd,
To,
- #state{peerT = PeerT}
+ #state{local = {PeerT, _, _}}
= S)
when is_atom(To) ->
connection_down(Wd, #peer{} = fetch(PeerT, TPid), S);
@@ -1122,15 +1184,14 @@ connection_down(#watchdog{state = ?WD_OKAY,
connection_down(#watchdog{}, _, _) ->
ok.
-remove_local_peer(SApps, T, LDict) ->
- lists:foldl(fun(A,D) -> rlp(A, T, D) end, LDict, SApps).
+local_peer_down(SApps, {TPid, _Caps} = TC, SA, LT) ->
+ delete_peer(TPid, LT),
+ lists:foreach(fun(A) -> peer_down(A, TC, SA) end, SApps).
-rlp({Id, Alias}, {TC, SA}, LDict) ->
- L = ?Dict:fetch(Alias, LDict),
- down_conn(Id, Alias, TC, SA),
- ?Dict:store(Alias, lists:delete(TC, L), LDict).
+peer_down({Id, Alias}, TC, SA) ->
+ peer_down(Id, Alias, TC, SA).
-down_conn(Id, Alias, TC, {SvcName, Apps}) ->
+peer_down(Id, Alias, TC, {SvcName, Apps}) ->
#diameter_app{id = Id} %% assert
= App
= find_app(Alias, Apps),
@@ -1155,7 +1216,7 @@ wd_down(#watchdog{peer = B}, _)
ok;
%% ... or maybe it has.
-wd_down(#watchdog{peer = TPid} = Wd, #state{peerT = PeerT} = S) ->
+wd_down(#watchdog{peer = TPid} = Wd, #state{local = {PeerT, _, _}} = S) ->
connection_down(Wd, ?WD_DOWN, S),
ets:delete(PeerT, TPid).
@@ -1363,19 +1424,37 @@ share_peer(up, Caps, Apps, TPid, #state{options = [_, {_,T} | _],
service_name = Svc}) ->
notify(T, Svc, {peer, TPid, [A || {_,A} <- Apps], Caps});
-share_peer(_, _, _, _, _) ->
- ok.
+share_peer(down, _Caps, _Apps, TPid, #state{options = [_, {_,T} | _],
+ service_name = Svc}) ->
+ notify(T, Svc, {peer, TPid}).
%% ---------------------------------------------------------------------------
%% # share_peers/2
%% ---------------------------------------------------------------------------
-share_peers(Pid, #state{options = [_, {_,T} | _], local_peers = PDict}) ->
- is_remote(Pid, T)
- andalso ?Dict:fold(fun(A,Ps,ok) -> sp(Pid, A, Ps), ok end, ok, PDict).
-
-sp(Pid, Alias, Peers) ->
- lists:foreach(fun({P,C}) -> Pid ! {peer, P, [Alias], C} end, Peers).
+share_peers(Pid, #state{options = [_, {_,SP} | _],
+ local = {PeerT, AppT, _}}) ->
+ is_remote(Pid, SP)
+ andalso ets:foldl(fun(T, N) -> N + sp(Pid, AppT, T) end,
+ 0,
+ PeerT).
+
+%% An entry in the peer table doesn't mean the watchdog state is OKAY,
+%% an entry in the app table does.
+
+sp(Pid, AppT, #peer{pid = TPid,
+ apps = [{_, Alias} | _] = Apps,
+ caps = Caps}) ->
+ Spec = [{{'$1', TPid},
+ [{'==', '$1', {const, Alias}}],
+ ['$_']}],
+ case ets:select(AppT, Spec, 1) of
+ '$end_of_table' ->
+ 0;
+ _ ->
+ Pid ! {peer, TPid, [A || {_,A} <- Apps], Caps},
+ 1
+ end.
is_remote(Pid, T) ->
Node = node(Pid),
@@ -1385,32 +1464,49 @@ is_remote(Pid, T) ->
%% # remote_peer_up/4
%% ---------------------------------------------------------------------------
-remote_peer_up(Pid, Aliases, Caps, #state{options = [_, _, {_,T} | _]} = S) ->
- is_remote(Pid, T)
- andalso rpu(Pid, Aliases, Caps, S).
+remote_peer_up(TPid, Aliases, Caps, #state{options = [_, _, {_,T} | _]} = S) ->
+ is_remote(TPid, T) andalso rpu(TPid, Aliases, Caps, S).
-rpu(Pid, Aliases, Caps, #state{service = Svc, shared_peers = PDict}) ->
+rpu(TPid, Aliases, Caps, #state{service = Svc, remote = RT}) ->
#diameter_service{applications = Apps} = Svc,
Key = #diameter_app.alias,
F = fun(A) -> lists:keymember(A, Key, Apps) end,
- rpu(Pid, lists:filter(F, Aliases), Caps, PDict);
+ rpu(TPid, lists:filter(F, Aliases), Caps, RT);
rpu(_, [] = No, _, _) ->
No;
-rpu(Pid, Aliases, Caps, PDict) ->
- erlang:monitor(process, Pid),
- T = {Pid, Caps},
- lists:foreach(fun(A) -> ?Dict:append(A, T, PDict) end, Aliases).
+rpu(TPid, Aliases, Caps, {PeerT, _, _} = RT) ->
+ monitor(process, TPid),
+ ets:insert(PeerT, #peer{pid = TPid,
+ apps = Aliases,
+ caps = Caps}),
+ insert_peer(TPid, Aliases, Caps, RT).
+
+%% insert_peer/4
+
+insert_peer(TPid, Aliases, Caps, {_PeerT, AppT, IdentT}) ->
+ #diameter_caps{origin_host = {_, OH},
+ origin_realm = {_, OR}}
+ = Caps,
+ ets:insert(AppT, [{A, TPid} || A <- Aliases]),
+ H = iolist_to_binary(OH),
+ R = iolist_to_binary(OR),
+ ets:insert(IdentT, [{T, A, TPid} || T <- [{host, H}, {realm, R}, {R, H}],
+ A <- Aliases]).
%% ---------------------------------------------------------------------------
%% # remote_peer_down/2
%% ---------------------------------------------------------------------------
-remote_peer_down(Pid, #state{shared_peers = PDict}) ->
- lists:foreach(fun(A) -> rpd(Pid, A, PDict) end, ?Dict:fetch_keys(PDict)).
+remote_peer_down(TPid, #state{remote = {PeerT, _, _} = RT}) ->
+ ets:delete(PeerT, TPid),
+ delete_peer(TPid, RT).
+
+%% delete_peer/2
-rpd(Pid, Alias, PDict) ->
- ?Dict:update(Alias, fun(Ps) -> lists:keydelete(Pid, 1, Ps) end, PDict).
+delete_peer(TPid, {_PeerT, AppT, IdentT}) ->
+ ets:select_delete(AppT, [{{'_', TPid}, [], [true]}]),
+ ets:select_delete(IdentT, [{{'_', '_', TPid}, [], [true]}]).
%% ---------------------------------------------------------------------------
%% pick_peer/4
@@ -1420,12 +1516,12 @@ pick_peer(#diameter_app{alias = Alias}
= App,
RealmAndHost,
Filter,
- #state{local_peers = L,
- shared_peers = S,
+ #state{local = LT,
+ remote = RT,
service_name = SvcName,
service = #diameter_service{pid = Pid}}) ->
- pick_peer(peers(Alias, RealmAndHost, Filter, L),
- peers(Alias, RealmAndHost, Filter, S),
+ pick_peer(peers(Alias, RealmAndHost, Filter, LT),
+ peers(Alias, RealmAndHost, Filter, RT),
Pid,
SvcName,
App).
@@ -1490,54 +1586,196 @@ pick_peer(Local,
%% peers/4
-peers(Alias, RH, Filter, Peers) ->
- case ?Dict:find(Alias, Peers) of
- {ok, L} ->
- filter(L, RH, Filter);
- error ->
+peers(Alias, RH, Filter, T) ->
+ filter(Alias, RH, Filter, T, true).
+
+%% filter/5
+%%
+%% Try to limit the peers list by starting with a host/realm lookup.
+
+filter(Alias, RH, {neg, F}, T, B) ->
+ filter(Alias, RH, F, T, not B);
+
+filter(_, _, none, _, false) ->
+ [];
+
+filter(Alias, _, none, T, true) ->
+ all_peers(Alias, T);
+
+filter(Alias, [DR,DH] = RH, K, T, B)
+ when K == realm, DR == undefined;
+ K == host, DH == undefined ->
+ filter(Alias, RH, none, T, B);
+
+filter(Alias, [DR,_] = RH, realm = K, T, B) ->
+ filter(Alias, RH, {K, DR}, T, B);
+
+filter(Alias, [_,DH] = RH, host = K, T, B) ->
+ filter(Alias, RH, {K, DH}, T, B);
+
+filter(Alias, _, {K, D}, {PeerT, _AppT, IdentT}, true)
+ when K == host;
+ K == realm ->
+ try iolist_to_binary(D) of
+ B ->
+ caps(PeerT, ets:select(IdentT, [{{{K, B}, '$1', '$2'},
+ [{'==', '$1', {const, Alias}}],
+ ['$2']}]))
+ catch
+ error:_ ->
[]
- end.
+ end;
-%% filter/3
+filter(Alias, RH, {all, Filters}, T, B)
+ when is_list(Filters) ->
+ fltr_all(Alias, RH, Filters, T, B);
+
+filter(Alias, RH, {first, Filters}, T, B)
+ when is_list(Filters) ->
+ fltr_first(Alias, RH, Filters, T, B);
+
+filter(Alias, RH, Filter, T, B) ->
+ {Ts, Fs} = filter(all_peers(Alias, T), RH, Filter),
+ choose(B, Ts, Fs).
+
+%% fltr_all/5
+
+fltr_all(Alias, RH, [{K, any} | Filters], T, B)
+ when K == host;
+ K == realm ->
+ fltr_all(Alias, RH, Filters, T, B);
+
+fltr_all(Alias, RH, [{host, _} = H, {realm, _} = R | Filters], T, B) ->
+ fltr_all(Alias, RH, [R, H | Filters], T, B);
+
+fltr_all(Alias, RH, [{realm, _} = R, {host, any} | Filters], T, B) ->
+ fltr_all(Alias, RH, [R | Filters], T, B);
+
+fltr_all(Alias, RH, [{realm, OR}, {host, OH} | Filters], T, true) ->
+ {PeerT, _AppT, IdentT} = T,
+ try {iolist_to_binary(OR), iolist_to_binary(OH)} of
+ BT ->
+ Peers = caps(PeerT,
+ ets:select(IdentT, [{{BT, '$1', '$2'},
+ [{'==', '$1', {const, Alias}}],
+ ['$2']}])),
+ {Ts, _} = filter(Peers, RH, {all, Filters}),
+ Ts
+ catch
+ error:_ ->
+ []
+ end;
+
+fltr_all(Alias, [undefined,_] = RH, [realm | Filters], T, B) ->
+ fltr_all(Alias, RH, Filters, T, B);
+
+fltr_all(Alias, [DR,_] = RH, [realm | Filters], T, B) ->
+ fltr_all(Alias, RH, [{realm, DR} | Filters], T, B);
+
+fltr_all(Alias, [_,undefined] = RH, [host | Filters], T, B) ->
+ fltr_all(Alias, RH, Filters, T, B);
+
+fltr_all(Alias, [_,DH] = RH, [host | Filters], T, B) ->
+ fltr_all(Alias, RH, [{host, DH} | Filters], T, B);
+
+fltr_all(Alias, RH, [{K, _} = KT, KA | Filters], T, B)
+ when K == host, KA == realm;
+ K == realm, KA == host ->
+ fltr_all(Alias, RH, [KA, KT | Filters], T, B);
+
+fltr_all(Alias, RH, [F | Filters], T, B) ->
+ {Ts, Fs} = filter(filter(Alias, RH, F, T, B), RH, {all, Filters}),
+ choose(B, Ts, Fs);
+
+fltr_all(Alias, RH, [], T, B) ->
+ filter(Alias, RH, none, T, B).
+
+%% fltr_first/5
%%
-%% Return peers in match order.
+%% Like any, but stop at the first filter with any matches.
+
+fltr_first(Alias, RH, [F | Filters], T, B) ->
+ case filter(Alias, RH, F, T, B) of
+ [] ->
+ fltr_first(Alias, RH, Filters, T, B);
+ [_|_] = Ts ->
+ Ts
+ end;
-filter(Peers, RH, Filter) ->
- {Ts, _} = fltr(Peers, RH, Filter),
- Ts.
+fltr_first(Alias, RH, [], T, B) ->
+ filter(Alias, RH, none, T, not B).
-%% fltr/4
+%% all_peers/2
-fltr(Peers, _, none) ->
+all_peers(Alias, {PeerT, AppT, _}) ->
+ ets:select(PeerT, [{#peer{pid = P, caps = '$1', _ = '_'},
+ [],
+ [{{P, '$1'}}]}
+ || {_,P} <- ets:lookup(AppT, Alias)]).
+
+%% caps/2
+
+caps(PeerT, Pids) ->
+ ets:select(PeerT, [{#peer{pid = P, caps = '$1', _ = '_'},
+ [],
+ [{{P, '$1'}}]}
+ || P <- Pids]).
+
+%% filter/3
+%%
+%% Return peers in match order.
+
+filter(Peers, _, none) ->
{Peers, []};
-fltr(Peers, RH, {neg, F}) ->
- {Ts, Fs} = fltr(Peers, RH, F),
+filter(Peers, RH, {neg, F}) ->
+ {Ts, Fs} = filter(Peers, RH, F),
{Fs, Ts};
-fltr(Peers, RH, {all, L})
+filter(Peers, RH, {all, L})
when is_list(L) ->
lists:foldl(fun(F,A) -> fltr_all(F, A, RH) end,
{Peers, []},
L);
-fltr(Peers, RH, {any, L})
+filter(Peers, RH, {any, L})
when is_list(L) ->
lists:foldl(fun(F,A) -> fltr_any(F, A, RH) end,
{[], Peers},
L);
-fltr(Peers, RH, F) ->
+filter(Peers, RH, {first, L})
+ when is_list(L) ->
+ fltr_first(Peers, RH, L);
+
+filter(Peers, RH, F) ->
lists:partition(fun({_,C}) -> caps_filter(C, RH, F) end, Peers).
+%% fltr_all/3
+
fltr_all(F, {Ts0, Fs0}, RH) ->
- {Ts1, Fs1} = fltr(Ts0, RH, F),
+ {Ts1, Fs1} = filter(Ts0, RH, F),
{Ts1, Fs0 ++ Fs1}.
+%% fltr_any/3
+
fltr_any(F, {Ts0, Fs0}, RH) ->
- {Ts1, Fs1} = fltr(Fs0, RH, F),
+ {Ts1, Fs1} = filter(Fs0, RH, F),
{Ts0 ++ Ts1, Fs1}.
+%% fltr_first/3
+
+fltr_first(Peers, _, []) ->
+ {[], Peers};
+
+fltr_first(Peers, RH, [F | Filters]) ->
+ case filter(Peers, RH, F) of
+ {[], _} ->
+ fltr_first(Peers, RH, Filters);
+ {_, _} = T ->
+ T
+ end.
+
%% caps_filter/3
caps_filter(#diameter_caps{origin_host = {_,OH}}, [_,DH], host) ->
@@ -1581,8 +1819,8 @@ eq(Any, Id, PeerId) ->
transports(#state{watchdogT = WatchdogT}) ->
ets:select(WatchdogT, [{#watchdog{peer = '$1', _ = '_'},
- [{'is_pid', '$1'}],
- ['$1']}]).
+ [{'is_pid', '$1'}],
+ ['$1']}]).
%% ---------------------------------------------------------------------------
%% # service_info/2
@@ -1635,7 +1873,7 @@ tagged_info(Item, S)
undefined
end;
-tagged_info(TPid, #state{watchdogT = WatchdogT, peerT = PeerT})
+tagged_info(TPid, #state{watchdogT = WatchdogT, local = {PeerT, _, _}})
when is_pid(TPid) ->
try
[#peer{watchdog = Pid}] = ets:lookup(PeerT, TPid),
@@ -1785,7 +2023,7 @@ keys(connect = T, Opts) ->
keys(_, _) ->
[{listen, accept}].
-peer_dict(#state{watchdogT = WatchdogT, peerT = PeerT}, Dict0) ->
+peer_dict(#state{watchdogT = WatchdogT, local = {PeerT, _, _}}, Dict0) ->
try ets:tab2list(WatchdogT) of
L -> lists:foldl(fun(T,A) -> peer_acc(PeerT, A, T) end, Dict0, L)
catch
diff --git a/lib/diameter/src/base/diameter_service_sup.erl b/lib/diameter/src/base/diameter_service_sup.erl
index e3177f0083..369e403fff 100644
--- a/lib/diameter/src/base/diameter_service_sup.erl
+++ b/lib/diameter/src/base/diameter_service_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/base/diameter_session.erl b/lib/diameter/src/base/diameter_session.erl
index c5ea0428b5..4cd76ed1f1 100644
--- a/lib/diameter/src/base/diameter_session.erl
+++ b/lib/diameter/src/base/diameter_session.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/base/diameter_stats.erl b/lib/diameter/src/base/diameter_stats.erl
index 64ea082be0..8c10464e98 100644
--- a/lib/diameter/src/base/diameter_stats.erl
+++ b/lib/diameter/src/base/diameter_stats.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,9 +25,6 @@
-module(diameter_stats).
-behaviour(gen_server).
--compile({no_auto_import, [now/0]}).
--import(diameter_lib, [now/0]).
-
-export([reg/2, reg/1,
incr/3, incr/1,
read/1,
@@ -60,7 +58,7 @@
-define(SERVER, ?MODULE).
%% Server state.
--record(state, {id = now()}).
+-record(state, {id = diameter_lib:now()}).
-type counter() :: any().
-type ref() :: any().
@@ -142,9 +140,14 @@ read(Refs, B) ->
L.
to_refdict(L) ->
- lists:foldl(fun({{C,R}, N}, D) -> orddict:append(R, {C,N}, D) end,
- orddict:new(),
- L).
+ lists:foldl(fun append/2, orddict:new(), L).
+
+%% Order both references and counters in the returned list.
+append({{Ctr, Ref}, N}, Dict) ->
+ orddict:update(Ref,
+ fun(D) -> orddict:store(Ctr, N, D) end,
+ [{Ctr, N}],
+ Dict).
%% ---------------------------------------------------------------------------
%% # sum(Refs)
@@ -220,7 +223,7 @@ uptime() ->
%% ----------------------------------------------------------
init([]) ->
- ets:new(?TABLE, [named_table, ordered_set, public]),
+ ets:new(?TABLE, [named_table, set, public, {write_concurrency, true}]),
{ok, #state{}}.
%% ----------------------------------------------------------
diff --git a/lib/diameter/src/base/diameter_sup.erl b/lib/diameter/src/base/diameter_sup.erl
index 4ede4086d8..e89ede9843 100644
--- a/lib/diameter/src/base/diameter_sup.erl
+++ b/lib/diameter/src/base/diameter_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/base/diameter_sync.erl b/lib/diameter/src/base/diameter_sync.erl
index 90eabece3d..7fb6888e21 100644
--- a/lib/diameter/src/base/diameter_sync.erl
+++ b/lib/diameter/src/base/diameter_sync.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,9 +28,6 @@
-module(diameter_sync).
-behaviour(gen_server).
--compile({no_auto_import, [now/0]}).
--import(diameter_lib, [now/0]).
-
-export([call/4, call/5,
cast/4, cast/5,
carp/1, carp/2]).
@@ -72,7 +70,7 @@
%% Server state.
-record(state,
- {time = now(),
+ {time = diameter_lib:now(),
pending = 0 :: non_neg_integer(), %% outstanding requests
monitor = new() :: ets:tid(), %% MonitorRef -> {Name, From}
queue = new() :: ets:tid()}). %% Name -> queue of {Pid, Ref}
diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl
index eb4bbae931..c169d3fc2c 100644
--- a/lib/diameter/src/base/diameter_traffic.erl
+++ b/lib/diameter/src/base/diameter_traffic.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,7 +41,6 @@
-export([make_recvdata/1,
peer_up/1,
peer_down/1,
- failover/1,
pending/1]).
%% towards ?MODULE
@@ -79,6 +79,7 @@
apps :: [#diameter_app{}],
sequence :: diameter:sequence(),
codec :: [{string_decode, boolean()}
+ | {strict_mbit, boolean()}
| {incoming_maxlen, diameter:message_length()}]}).
%% Note that incoming_maxlen is currently handled in diameter_peer_fsm,
%% so that any message exceeding the maximum is discarded. Retain the
@@ -97,9 +98,6 @@
%% # make_recvdata/1
%% ---------------------------------------------------------------------------
-make_recvdata([SvcName, PeerT, Apps, {_,_} = Mask | _]) -> %% from old code
- make_recvdata([SvcName, PeerT, Apps, [{sequence, Mask}]]);
-
make_recvdata([SvcName, PeerT, Apps, SvcOpts | _]) ->
{_,_} = Mask = proplists:get_value(sequence, SvcOpts),
#recvdata{service_name = SvcName,
@@ -108,7 +106,8 @@ make_recvdata([SvcName, PeerT, Apps, SvcOpts | _]) ->
sequence = Mask,
codec = [T || {K,_} = T <- SvcOpts,
lists:member(K, [string_decode,
- incoming_maxlen])]}.
+ incoming_maxlen,
+ strict_mbit])]}.
%% ---------------------------------------------------------------------------
%% peer_up/1
@@ -169,7 +168,7 @@ incr_error(Dir, Id, TPid, _) ->
incr_error(Dir, Id, TPid) ->
incr(TPid, {Id, Dir, error}).
-
+
%% ---------------------------------------------------------------------------
%% incr_rc/4
%% ---------------------------------------------------------------------------
@@ -261,7 +260,8 @@ recv(false, #request{ref = Ref, handler = Pid} = Req, _, Pkt, Dict0, _) ->
%% any others are discarded.
%% ... or not.
-recv(false, false, TPid, _, _, _) ->
+recv(false, false, TPid, Pkt, _, _) ->
+ ?LOG(discarded, Pkt#diameter_packet.header),
incr(TPid, {{unknown, 0}, recv, discarded}),
ok.
@@ -300,13 +300,7 @@ recv_request(TPid,
RecvData),
TPid,
Dict0,
- RecvData);
-
-recv_request(TPid, Pkt, Dict0, RecvData) -> %% from old code
- recv_request(TPid,
- Pkt,
- Dict0,
- #recvdata{} = erlang:append_element(RecvData, [])).
+ RecvData).
%% recv_R/5
@@ -1490,16 +1484,12 @@ send_R(Pkt0,
caps = Caps,
packet = Pkt0},
- try
- incr(send, Pkt, TPid, AppDict),
- TRef = send_request(TPid, Pkt, Req, SvcName, Timeout),
- Pid ! Ref, %% tell caller a send has been attempted
- handle_answer(SvcName,
- App,
- recv_A(Timeout, SvcName, App, Opts, {TRef, Req}))
- after
- erase_requests(Pkt)
- end.
+ incr(send, Pkt, TPid, AppDict),
+ TRef = send_request(TPid, Pkt, Req, SvcName, Timeout),
+ Pid ! Ref, %% tell caller a send has been attempted
+ handle_answer(SvcName,
+ App,
+ recv_A(Timeout, SvcName, App, Opts, {TRef, Req})).
%% recv_A/5
@@ -1575,6 +1565,8 @@ answer(Pkt,
Req) ->
a(Pkt, SvcName, ModX, AE, Req).
+-spec a(_, _, _) -> no_return(). %% silence dialyzer
+
a(#diameter_packet{errors = Es}
= Pkt,
SvcName,
@@ -1641,9 +1633,6 @@ pick_peer(SvcName,
Filter,
Xtra})).
-pick({{_,_,_} = Transport, Mask}) -> %% from old code; dialyzer complains
- {Transport, Mask, []}; %% about this
-
pick(false) ->
{error, no_connection};
@@ -1702,9 +1691,18 @@ encode(_, _, #diameter_packet{} = Pkt) ->
send_request(TPid, #diameter_packet{bin = Bin} = Pkt, Req, _SvcName, Timeout)
when node() == node(TPid) ->
- %% Store the outgoing request before sending to avoid a race with
- %% reply reception.
- TRef = store_request(TPid, Bin, Req, Timeout),
+ Seqs = diameter_codec:sequence_numbers(Bin),
+ TRef = erlang:start_timer(Timeout, self(), TPid),
+ Entry = {Seqs, Req, TRef},
+
+ %% Ensure that request table is cleaned even if we receive an exit
+ %% signal. An alternative would be to simply trap exits, but
+ %% callbacks are applied in this process, and these could possibly
+ %% be expecting the prevailing behaviour.
+ Self = self(),
+ spawn(fun() -> diameter_lib:wait([Self]), erase_request(Entry) end),
+
+ store_request(Entry, TPid),
send(TPid, Pkt),
TRef;
@@ -1719,31 +1717,21 @@ send_request(TPid, #diameter_packet{} = Pkt, Req, SvcName, Timeout) ->
%% send/1
send({TPid, Pkt, #request{handler = Pid} = Req0, SvcName, Timeout, TRef}) ->
- Seqs = diameter_codec:sequence_numbers(Pkt),
Req = Req0#request{handler = self()},
- Ref = send_request(TPid, Pkt, Req, SvcName, Timeout),
-
- try
- recv(TPid, Pid, TRef, Ref)
- after
- %% Remove only the entry for this specific send since a resend
- %% from the originating node can pick another transport on
- %% this one.
- ets:delete_object(?REQUEST_TABLE, {Seqs, Req, Ref})
- end.
+ recv(TPid, Pid, TRef, send_request(TPid, Pkt, Req, SvcName, Timeout)).
%% recv/4
%%
%% Relay an answer from a remote node.
-recv(TPid, Pid, TRef, Ref) ->
+recv(TPid, Pid, TRef, LocalTRef) ->
receive
{answer, _, _, _, _} = A ->
Pid ! A;
- {failover = T, Ref} ->
+ {failover = T, LocalTRef} ->
Pid ! {T, TRef};
T ->
- exit({timeout, Ref, TPid} = T)
+ exit({timeout, LocalTRef, TPid} = T)
end.
%% send/2
@@ -1820,17 +1808,21 @@ resend_request(Pkt0,
TRef = send_request(TPid, Pkt, Req, SvcName, Tmo),
{TRef, Req}.
-%% store_request/4
+%% store_request/2
-store_request(TPid, Bin, Req, Timeout) ->
- Seqs = diameter_codec:sequence_numbers(Bin),
- TRef = erlang:start_timer(Timeout, self(), TPid),
- ets:insert(?REQUEST_TABLE, {Seqs, Req, TRef}),
+store_request(T, TPid) ->
+ ets:insert(?REQUEST_TABLE, T),
ets:member(?REQUEST_TABLE, TPid)
- orelse (self() ! {failover, TRef}), %% failover/1 may have missed
- TRef.
+ orelse begin
+ {_Seqs, _Req, TRef} = T,
+ self() ! {failover, TRef} %% failover/1 may have missed
+ end.
%% lookup_request/2
+%%
+%% Note the match on both the key and transport pid. The latter is
+%% necessary since the same Hop-by-Hop and End-to-End identifiers are
+%% reused in the case of retransmission.
lookup_request(Msg, TPid) ->
Seqs = diameter_codec:sequence_numbers(Msg),
@@ -1844,10 +1836,10 @@ lookup_request(Msg, TPid) ->
false
end.
-%% erase_requests/1
+%% erase_request/1
-erase_requests(Pkt) ->
- ets:delete(?REQUEST_TABLE, diameter_codec:sequence_numbers(Pkt)).
+erase_request(T) ->
+ ets:delete_object(?REQUEST_TABLE, T).
%% match_requests/1
@@ -1870,10 +1862,10 @@ failover(TPid)
when is_pid(TPid) ->
lists:foreach(fun failover/1, match_requests(TPid));
%% Note that a request process can store its request after failover
-%% notifications are sent here: store_request/4 sends the notification
+%% notifications are sent here: store_request/2 sends the notification
%% in that case.
-%% Failover as a consequence of request_peer_down/1: inform the
+%% Failover as a consequence of peer_down/1: inform the
%% request process.
failover({_, Req, TRef}) ->
#request{handler = Pid,
diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl
index 87a0f0663d..6ecf385239 100644
--- a/lib/diameter/src/base/diameter_types.erl
+++ b/lib/diameter/src/base/diameter_types.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index de9c4bca33..ea8b2fdb0e 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -65,7 +66,9 @@
%% end PCB
parent = self() :: pid(), %% service process
transport :: pid() | undefined, %% peer_fsm process
- tref :: reference(), %% reference for current watchdog timer
+ tref :: reference() %% reference for current watchdog timer
+ | integer() %% monotonic time
+ | undefined,
dictionary :: module(), %% common dictionary
receive_data :: term(),
%% term passed into diameter_service with incoming message
@@ -93,7 +96,7 @@ start({_,_} = Type, T) ->
Ack = make_ref(),
{ok, Pid} = diameter_watchdog_sup:start_child({Ack, Type, self(), T}),
try
- {erlang:monitor(process, Pid), Pid}
+ {monitor(process, Pid), Pid}
after
send(Pid, Ack)
end.
@@ -120,7 +123,7 @@ i({Ack, T, Pid, {RecvData,
#diameter_service{applications = Apps,
capabilities = Caps}
= Svc}}) ->
- erlang:monitor(process, Pid),
+ monitor(process, Pid),
wait(Ack, Pid),
{_, Seed} = diameter_lib:seed(),
random:seed(Seed),
@@ -245,11 +248,16 @@ handle_info(T, #watchdog{} = State) ->
event(T, State, S), %% before 'watchdog'
{noreply, S};
stop ->
- ?LOG(stop, T),
+ ?LOG(stop, truncate(T)),
event(T, State, State#watchdog{status = down}),
{stop, {shutdown, T}, State}
end.
+truncate({'DOWN' = T, _, process, Pid, _}) ->
+ {T, Pid};
+truncate(T) ->
+ T.
+
close({'DOWN', _, process, TPid, {shutdown, Reason}},
#watchdog{transport = TPid,
parent = Pid}) ->
@@ -446,11 +454,12 @@ transition({recv, TPid, Name, Pkt}, #watchdog{transport = TPid} = S) ->
%% Current watchdog has timed out.
transition({timeout, TRef, tw}, #watchdog{tref = TRef} = S) ->
- set_watchdog(timeout(S));
+ set_watchdog(0, timeout(S));
-%% Timer was canceled after message was already sent.
-transition({timeout, _, tw}, #watchdog{}) ->
- ok;
+%% Message has arrived since the timer was started: subtract time
+%% already elapsed from new timer.
+transition({timeout, _, tw}, #watchdog{tref = T0} = S) ->
+ set_watchdog(diameter_lib:micro_diff(T0) div 1000, S);
%% State query.
transition({state, Pid}, #watchdog{status = S}) ->
@@ -526,18 +535,27 @@ role() ->
%% set_watchdog/1
-set_watchdog(#watchdog{tw = TwInit,
- tref = TRef}
- = S) ->
- cancel(TRef),
- S#watchdog{tref = erlang:start_timer(tw(TwInit), self(), tw)};
-set_watchdog(stop = No) ->
- No.
+%% Timer not yet set.
+set_watchdog(#watchdog{tref = undefined} = S) ->
+ set_watchdog(0, S);
-cancel(undefined) ->
- ok;
-cancel(TRef) ->
- erlang:cancel_timer(TRef).
+%% Timer already set: start at new one only at expiry.
+set_watchdog(#watchdog{} = S) ->
+ S#watchdog{tref = diameter_lib:now()}.
+
+%% set_watchdog/2
+
+set_watchdog(_, stop = No) ->
+ No;
+
+set_watchdog(Ms, #watchdog{tw = TwInit} = S) ->
+ S#watchdog{tref = erlang:start_timer(tw(TwInit, Ms), self(), tw)}.
+
+%% A callback could return anything, so ensure the result isn't
+%% negative. Don't prevent abuse, even though the smallest valid
+%% timeout is 4000.
+tw(TwInit, Ms) ->
+ max(tw(TwInit) - Ms, 0).
tw(T)
when is_integer(T), T >= 6000 ->
@@ -810,9 +828,6 @@ restart(S) -> %% reconnect has won race with timeout
%% state down rather then initial when receiving notification of an
%% open connection.
-restart({T, Opts, Svc}, S) -> %% put in old code
- restart({T, Opts, Svc, []}, S);
-
restart({{connect, _} = T, Opts, Svc, SvcOpts},
#watchdog{parent = Pid,
restrict = {R,_},
@@ -827,7 +842,7 @@ restart({{connect, _} = T, Opts, Svc, SvcOpts},
%% die. Note that a state machine never enters state REOPEN in this
%% case.
restart({{accept, _}, _, _, _}, #watchdog{restrict = {_, false}}) ->
- stop; %% 'DOWN' was in old code: 'close' was not sent
+ stop;
%% Otherwise hang around until told to die, either by the service or
%% by another watchdog.
diff --git a/lib/diameter/src/base/diameter_watchdog_sup.erl b/lib/diameter/src/base/diameter_watchdog_sup.erl
index fc837fe4ef..5d24e12f19 100644
--- a/lib/diameter/src/base/diameter_watchdog_sup.erl
+++ b/lib/diameter/src/base/diameter_watchdog_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/compiler/diameter_codegen.erl b/lib/diameter/src/compiler/diameter_codegen.erl
index d91a776321..cdaa9aa7f9 100644
--- a/lib/diameter/src/compiler/diameter_codegen.erl
+++ b/lib/diameter/src/compiler/diameter_codegen.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -183,7 +184,7 @@ erl_forms(Mod, ParseD) ->
f_enumerated_avp(ParseD),
f_empty_value(ParseD),
f_dict(ParseD),
- {eof, ?LINE}]],
+ {eof, erl_anno:new(?LINE)}]],
lists:append(Forms).
diff --git a/lib/diameter/src/compiler/diameter_dict_parser.yrl b/lib/diameter/src/compiler/diameter_dict_parser.yrl
index 6fd4cedd23..ef8d58d63b 100644
--- a/lib/diameter/src/compiler/diameter_dict_parser.yrl
+++ b/lib/diameter/src/compiler/diameter_dict_parser.yrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/compiler/diameter_dict_scanner.erl b/lib/diameter/src/compiler/diameter_dict_scanner.erl
index 45189376fb..aeedc89d83 100644
--- a/lib/diameter/src/compiler/diameter_dict_scanner.erl
+++ b/lib/diameter/src/compiler/diameter_dict_scanner.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/compiler/diameter_dict_util.erl b/lib/diameter/src/compiler/diameter_dict_util.erl
index cf4741e563..9525393128 100644
--- a/lib/diameter/src/compiler/diameter_dict_util.erl
+++ b/lib/diameter/src/compiler/diameter_dict_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/compiler/diameter_exprecs.erl b/lib/diameter/src/compiler/diameter_exprecs.erl
index 9e32f53724..2a04917995 100644
--- a/lib/diameter/src/compiler/diameter_exprecs.erl
+++ b/lib/diameter/src/compiler/diameter_exprecs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/compiler/diameter_forms.hrl b/lib/diameter/src/compiler/diameter_forms.hrl
index dd03401b9e..370f89b01f 100644
--- a/lib/diameter/src/compiler/diameter_forms.hrl
+++ b/lib/diameter/src/compiler/diameter_forms.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,8 +29,10 @@
[],
[?APPLY(erlang, error, [?ATOM(badarg)])]}).
+-define(ANNO(L), erl_anno:new(L)).
+
%% Form tag with line number.
--define(F(T), T, ?LINE).
+-define(F(T), T, ?ANNO(?LINE)).
%% Yes, that's right. The replacement is to the first unmatched ')'.
-define(attribute, ?F(attribute)).
@@ -47,10 +50,10 @@
-define(record_index, ?F(record_index)).
-define(tuple, ?F(tuple)).
--define(ATOM(T), {atom, ?LINE, T}).
--define(INTEGER(N), {integer, ?LINE, N}).
--define(VAR(V), {var, ?LINE, V}).
--define(NIL, {nil, ?LINE}).
+-define(ATOM(T), {atom, ?ANNO(?LINE), T}).
+-define(INTEGER(N), {integer, ?ANNO(?LINE), N}).
+-define(VAR(V), {var, ?ANNO(?LINE), V}).
+-define(NIL, {nil, ?ANNO(?LINE)}).
-define(CALL(F,A), {?call, ?ATOM(F), A}).
-define(APPLY(M,F,A), {?call, {?remote, ?ATOM(M), ?ATOM(F)}, A}).
diff --git a/lib/diameter/src/compiler/diameter_make.erl b/lib/diameter/src/compiler/diameter_make.erl
index 72f5d36da4..d9709029ae 100644
--- a/lib/diameter/src/compiler/diameter_make.erl
+++ b/lib/diameter/src/compiler/diameter_make.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/compiler/diameter_vsn.hrl b/lib/diameter/src/compiler/diameter_vsn.hrl
index 024d047adc..2efac98bff 100644
--- a/lib/diameter/src/compiler/diameter_vsn.hrl
+++ b/lib/diameter/src/compiler/diameter_vsn.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/depend.sed b/lib/diameter/src/depend.sed
index 8f999f646f..5adf7f05d5 100644
--- a/lib/diameter/src/depend.sed
+++ b/lib/diameter/src/depend.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/diameter/src/diameter.app.src b/lib/diameter/src/diameter.app.src
index ac1d847753..49bfd803e7 100644
--- a/lib/diameter/src/diameter.app.src
+++ b/lib/diameter/src/diameter.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src
index b89859ed24..a3e21db012 100644
--- a/lib/diameter/src/diameter.appup.src
+++ b/lib/diameter/src/diameter.appup.src
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,42 +38,19 @@
{"1.5", [{restart_application, diameter}]}, %% R16B03
{"1.6", [{restart_application, diameter}]}, %% 17.0
{"1.7", [{restart_application, diameter}]}, %% 17.[12]
- {<<"^1\\.(7\\.1|8)$">>, %% 17.[34]
- [{load_module, diameter_lib},
- {load_module, diameter_peer},
- {load_module, diameter_reg},
- {load_module, diameter_session},
- {load_module, diameter_stats},
- {load_module, diameter_sync},
- {load_module, diameter_capx},
- {load_module, diameter_codec},
- {load_module, diameter_types},
- {load_module, diameter_traffic},
- {load_module, diameter_service},
- {load_module, diameter_peer_fsm},
- {load_module, diameter_watchdog},
- {load_module, diameter_tcp},
- {load_module, diameter_sctp},
- {load_module, diameter_config},
- {load_module, diameter},
- {load_module, diameter_gen_base_rfc6733},
- {load_module, diameter_gen_acct_rfc6733},
- {load_module, diameter_gen_base_rfc3588},
- {load_module, diameter_gen_base_accounting},
- {load_module, diameter_gen_relay},
- {update, diameter_transport_sup, supervisor},
- {update, diameter_service_sup, supervisor},
- {update, diameter_sup, supervisor}]},
- {"1.9", [{load_module, diameter_codec}, %% 17.5
- {load_module, diameter_traffic},
- {load_module, diameter_sctp},
- {load_module, diameter_gen_base_rfc6733},
- {load_module, diameter_gen_acct_rfc6733},
- {load_module, diameter_gen_base_rfc3588},
- {load_module, diameter_gen_base_accounting},
- {load_module, diameter_gen_relay}]},
- {"1.9.1", [{load_module, diameter_traffic}, %% 17.5.3
- {load_module, diameter_sctp}]}
+ {"1.7.1", [{restart_application, diameter}]}, %% 17.3
+ {"1.8", [{restart_application, diameter}]}, %% 17.4
+ {"1.9", [{restart_application, diameter}]}, %% 17.5
+ {"1.9.1", [{restart_application, diameter}]}, %% 17.5.3
+ {"1.9.2", [{restart_application, diameter}]}, %% 17.5.5
+ {"1.9.2.1", [{restart_application, diameter}]}, %% 17.5.6.3
+ {"1.9.2.2", [{restart_application, diameter}]}, %% 17.5.6.7
+ {"1.9.2.3", [{restart_application, diameter}]}, %% 17.5.6.8
+ {"1.10", [{restart_application, diameter}]}, %% 18.0
+ {"1.11", [{load_module, diameter_traffic}, %% 18.1
+ {update, diameter_service, {advanced, []}}]},
+ {"1.11.1", [{load_module, diameter_traffic}, %% 18.2
+ {update, diameter_service, {advanced, []}}]}
],
[
{"0.9", [{restart_application, diameter}]},
@@ -92,41 +70,16 @@
{"1.5", [{restart_application, diameter}]},
{"1.6", [{restart_application, diameter}]},
{"1.7", [{restart_application, diameter}]},
- {<<"^1\\.(7\\.1|8)$">>,
- [{update, diameter_sup, supervisor},
- {update, diameter_service_sup, supervisor},
- {update, diameter_transport_sup, supervisor},
- {load_module, diameter_gen_relay},
- {load_module, diameter_gen_base_accounting},
- {load_module, diameter_gen_base_rfc3588},
- {load_module, diameter_gen_acct_rfc6733},
- {load_module, diameter_gen_base_rfc6733},
- {load_module, diameter},
- {load_module, diameter_config},
- {load_module, diameter_sctp},
- {load_module, diameter_tcp},
- {load_module, diameter_watchdog},
- {load_module, diameter_peer_fsm},
- {load_module, diameter_service},
- {load_module, diameter_traffic},
- {load_module, diameter_types},
- {load_module, diameter_codec},
- {load_module, diameter_capx},
- {load_module, diameter_sync},
- {load_module, diameter_stats},
- {load_module, diameter_session},
- {load_module, diameter_reg},
- {load_module, diameter_peer},
- {load_module, diameter_lib}]},
- {"1.9", [{load_module, diameter_gen_relay},
- {load_module, diameter_gen_base_accounting},
- {load_module, diameter_gen_base_rfc3588},
- {load_module, diameter_gen_acct_rfc6733},
- {load_module, diameter_gen_base_rfc6733},
- {load_module, diameter_sctp},
- {load_module, diameter_traffic},
- {load_module, diameter_codec}]},
- {"1.9.1", [{load_module, diameter_sctp},
- {load_module, diameter_traffic}]}
+ {"1.7.1", [{restart_application, diameter}]},
+ {"1.8", [{restart_application, diameter}]},
+ {"1.9", [{restart_application, diameter}]},
+ {"1.9.1", [{restart_application, diameter}]},
+ {"1.9.2", [{restart_application, diameter}]},
+ {"1.9.2.1", [{restart_application, diameter}]},
+ {"1.9.2.2", [{restart_application, diameter}]},
+ {"1.9.2.3", [{restart_application, diameter}]},
+ {"1.10", [{restart_application, diameter}]},
+ {"1.11", [{restart_application, diameter}]},
+ {"1.11.1", [{restart_application, diameter}]}
]
}.
diff --git a/lib/diameter/src/dict/acct_rfc6733.dia b/lib/diameter/src/dict/acct_rfc6733.dia
index 7d6d11a71e..4eb326ce88 100644
--- a/lib/diameter/src/dict/acct_rfc6733.dia
+++ b/lib/diameter/src/dict/acct_rfc6733.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/src/dict/base_accounting.dia b/lib/diameter/src/dict/base_accounting.dia
index ced324078c..839add8764 100644
--- a/lib/diameter/src/dict/base_accounting.dia
+++ b/lib/diameter/src/dict/base_accounting.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-2011. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/src/dict/base_rfc3588.dia b/lib/diameter/src/dict/base_rfc3588.dia
index 43a417b8dc..f7316208a6 100644
--- a/lib/diameter/src/dict/base_rfc3588.dia
+++ b/lib/diameter/src/dict/base_rfc3588.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/src/dict/base_rfc6733.dia b/lib/diameter/src/dict/base_rfc6733.dia
index e1d1f18d86..d92760711c 100644
--- a/lib/diameter/src/dict/base_rfc6733.dia
+++ b/lib/diameter/src/dict/base_rfc6733.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/src/dict/capup_rfc6737.dia b/lib/diameter/src/dict/capup_rfc6737.dia
index 35d2a9f218..396c7de9ac 100644
--- a/lib/diameter/src/dict/capup_rfc6737.dia
+++ b/lib/diameter/src/dict/capup_rfc6737.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/src/dict/relay.dia b/lib/diameter/src/dict/relay.dia
index 294014b093..23772fedf8 100644
--- a/lib/diameter/src/dict/relay.dia
+++ b/lib/diameter/src/dict/relay.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-2011. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/src/info/diameter_dbg.erl b/lib/diameter/src/info/diameter_dbg.erl
index b536e5e80b..4f5c91d24f 100644
--- a/lib/diameter/src/info/diameter_dbg.erl
+++ b/lib/diameter/src/info/diameter_dbg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/info/diameter_info.erl b/lib/diameter/src/info/diameter_info.erl
index 10972f3231..59a3b94ee4 100644
--- a/lib/diameter/src/info/diameter_info.erl
+++ b/lib/diameter/src/info/diameter_info.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -51,8 +52,6 @@
p/1,
p/3]).
--compile({no_auto_import,[max/2]}).
-
-export([collect/2]).
-define(LONG_TIMEOUT, 30000).
@@ -683,9 +682,6 @@ pt(T) ->
recsplit(SFun, Rec) ->
fun(Fs,Vs) -> SFun(element(1, Rec), Fs, Vs) end.
-max(A, B) ->
- if A > B -> A; true -> B end.
-
keyfetch(Key, List) ->
{Key,V} = lists:keyfind(Key, 1, List),
V.
diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk
index c9dd4e683a..3b223ea391 100644
--- a/lib/diameter/src/modules.mk
+++ b/lib/diameter/src/modules.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/src/transport/diameter_etcp.erl b/lib/diameter/src/transport/diameter_etcp.erl
index cd62cf34fa..9db198ff86 100644
--- a/lib/diameter/src/transport/diameter_etcp.erl
+++ b/lib/diameter/src/transport/diameter_etcp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/transport/diameter_etcp_sup.erl b/lib/diameter/src/transport/diameter_etcp_sup.erl
index bd089cf041..48794d4fe1 100644
--- a/lib/diameter/src/transport/diameter_etcp_sup.erl
+++ b/lib/diameter/src/transport/diameter_etcp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl
index f80de0a816..678dc9b5d6 100644
--- a/lib/diameter/src/transport/diameter_sctp.erl
+++ b/lib/diameter/src/transport/diameter_sctp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -20,9 +21,6 @@
-module(diameter_sctp).
-behaviour(gen_server).
--compile({no_auto_import, [now/0]}).
--import(diameter_lib, [now/0]).
-
%% interface
-export([start/3]).
@@ -103,15 +101,11 @@
{ref :: reference(),
socket :: gen_sctp:sctp_socket(),
count = 0 :: uint(), %% attached transport processes
- tmap = ets:new(?MODULE, []) :: ets:tid(),
- %% {MRef, Pid|AssocId}, {AssocId, Pid}
- pending = {0, ets:new(?MODULE, [ordered_set])},
+ pending = {0, queue:new()},
tref :: reference(),
accept :: [match()]}).
-%% Field tmap is used to map an incoming message or event to the
-%% relevant transport process. Field pending implements two queues:
-%% the first of transport-to-be processes to which an association has
-%% been assigned (at comm_up and written into tmap) but for which
+%% Field pending implements two queues: the first of transport-to-be
+%% processes to which an association has been assigned but for which
%% diameter hasn't yet spawned a transport process, a short-lived
%% state of affairs as a new transport is spawned as a consequence of
%% a peer being taken up, transport processes being spawned by the
@@ -125,8 +119,7 @@
%% queue or spawned and placed in the first queue. Thus, there are
%% only elements in one queue at a time, so share an ets table queue
%% and tag it with a positive length if it contains the first queue, a
-%% negative length if it contains the second queue. The case -1 is
-%% handled differently for backwards compatibility reasons.
+%% negative length if it contains the second queue.
%% ---------------------------------------------------------------------------
%% # start/3
@@ -228,7 +221,7 @@ i({listen, Ref, {Opts, Addrs}}) ->
proc_lib:init_ack({ok, self(), LAs}),
start_timer(#listener{ref = Ref,
socket = Sock,
- accept = accept(Matches)});
+ accept = [[M] || {accept, M} <- Matches]});
%% A connecting transport.
i({connect, Pid, Opts, Addrs, Ref}) ->
@@ -243,43 +236,49 @@ i({connect, Pid, Opts, Addrs, Ref}) ->
mode = {connect, connect(Sock, RAs, RP, [])},
socket = Sock};
-%% An accepting transport spawned by diameter.
-i({accept, Pid, LPid, Sock, Ref})
+%% An accepting transport spawned by diameter, not yet owning an
+%% association.
+i({accept, Ref, LPid, Pid})
when is_pid(Pid) ->
putr(?REF_KEY, Ref),
proc_lib:init_ack({ok, self()}),
monitor(process, Pid),
- monitor(process, LPid),
- #transport{parent = Pid,
- mode = {accept, LPid},
- socket = Sock};
+ MRef = monitor(process, LPid),
+ wait([{peeloff, MRef}], #transport{parent = Pid,
+ mode = {accept, LPid}});
-%% An accepting transport spawned at association establishment.
-i({accept, Ref, LPid, Sock, Id}) ->
+%% An accepting transport spawned at association establishment, whose
+%% parent is not yet known.
+i({accept, Ref, LPid}) ->
putr(?REF_KEY, Ref),
proc_lib:init_ack({ok, self()}),
+ erlang:send_after(?ACCEPT_TIMEOUT, self(), accept_timeout),
MRef = monitor(process, LPid),
- %% Wait for a signal that the transport has been started before
- %% processing other messages.
+ wait([{parent, Ref}, {peeloff, MRef}], #transport{mode = {accept, LPid}}).
+
+%% wait/2
+%%
+%% Wait for diameter to start the transport process and for the
+%% association to be peeled off before processing other messages.
+
+wait(Keys, S) ->
+ lists:foldl(fun i/2, S, Keys).
+
+i({K, Ref}, #transport{mode = {accept, _}} = S) ->
receive
- {Ref, Pid} -> %% transport started
- #transport{parent = Pid,
- mode = {accept, LPid},
- socket = Sock};
- {'DOWN', MRef, process, _, _} = T -> %% listener down
- close(Sock, Id),
+ {Ref, Pid} when K == parent -> %% transport process started
+ S#transport{parent = Pid};
+ {K, T, Matches} when K == peeloff -> %% association
+ {sctp, Sock, _RA, _RP, _Data} = T,
+ ok = accept_peer(Sock, Matches),
+ demonitor(Ref, [flush]),
+ t(T, S#transport{socket = Sock});
+ accept_timeout = T ->
+ x(T);
+ {'DOWN', _, process, _, _} = T ->
x(T)
- after ?ACCEPT_TIMEOUT ->
- close(Sock, Id),
- x(timeout)
end.
-%% close/2
-
-close(Sock, Id) ->
- gen_sctp:eof(Sock, #sctp_assoc_change{assoc_id = Id}).
-%% Having to pass a record here is hokey.
-
%% listener/2
%% Accepting processes can be started concurrently: ensure only one
@@ -297,7 +296,7 @@ listener({LRef, T}) ->
l([{{?MODULE, listener, {_, AS}}, LPid}], _, _) ->
{LAs, _Sock} = AS,
{LPid, LAs};
-
+
%% ... or not.
l([], LRef, T) ->
{ok, LPid, LAs} = diameter_sctp_sup:start_child({listen, LRef, T}),
@@ -367,17 +366,11 @@ type(T) ->
%% # handle_call/3
%% ---------------------------------------------------------------------------
-handle_call(T, From, #listener{pending = L} = S)
- when is_list(L) ->
- handle_call(T, From, upgrade(S));
-
handle_call({{accept, Ref}, Pid}, _, #listener{ref = Ref,
- pending = {N,Q},
count = K}
= S) ->
- TPid = accept(Ref, Pid, S),
- {reply, {ok, TPid}, downgrade(S#listener{pending = {N-1,Q},
- count = K+1})};
+ {TPid, NewS} = accept(Ref, Pid, S),
+ {reply, {ok, TPid}, NewS#listener{count = K+1}};
handle_call(_, _, State) ->
{reply, nok, State}.
@@ -396,18 +389,9 @@ handle_cast(_, State) ->
handle_info(T, #transport{} = S) ->
{noreply, #transport{} = t(T,S)};
-handle_info(T, #listener{pending = L} = S)
- when is_list(L) ->
- handle_info(T, upgrade(S));
-
handle_info(T, #listener{} = S) ->
- {noreply, downgrade(#listener{} = l(T,S))}.
-
-%% upgrade/1
+ {noreply, #listener{} = l(T,S)}.
-upgrade(#listener{pending = [TPid | {0,Q}]} = S) ->
- ets:insert(Q, {TPid, now()}),
- S#listener{pending = {-1,Q}}.
%% Prior to the possiblity of setting pool_size on in transport
%% configuration, a new accepting transport was only started following
%% the death of a predecessor, so that there was only at most one
@@ -416,26 +400,6 @@ upgrade(#listener{pending = [TPid | {0,Q}]} = S) ->
%% several accepting transports are started concurrently. Deal with
%% this by placing the started transports in a new queue of transport
%% processes waiting for an association.
-%%
-%% Since only one of this queue and the existing queue of controlling
-%% processes waiting for a transport to be started can be non-empty at
-%% any given time, implement both queues in the same ets table. The
-%% absolute value of the first element of the 2-tuple is the queue
-%% length, the sign says which queue it is.
-
-%% downgrade/1
-%%
-%% Revert to the pre-pool_size representation when possible, for
-%% backwards compatibility in the case that the pool_size option
-%% hasn't been used.
-
-downgrade(#listener{pending = {-1,Q}} = S) ->
- TPid = ets:first(Q),
- ets:delete(Q, TPid),
- S#listener{pending = [TPid | {0,Q}]};
-
-downgrade(S) ->
- S.
%% ---------------------------------------------------------------------------
%% # code_change/3
@@ -451,16 +415,6 @@ code_change(_, State, _) ->
terminate(_, #transport{assoc_id = undefined}) ->
ok;
-terminate(_, #transport{socket = Sock,
- mode = accept,
- assoc_id = Id}) ->
- close(Sock, Id);
-
-terminate(_, #transport{socket = Sock,
- mode = {accept, _},
- assoc_id = Id}) ->
- close(Sock, Id);
-
terminate(_, #transport{socket = Sock}) ->
gen_sctp:close(Sock);
@@ -487,21 +441,17 @@ start_timer(S) ->
%% Transition listener state.
%% Incoming message from SCTP.
-l({sctp, Sock, _RA, _RP, Data} = Msg, #listener{socket = Sock} = S) ->
+l({sctp, Sock, _RA, _RP, Data} = T, #listener{socket = Sock,
+ accept = Matches}
+ = S) ->
Id = assoc_id(Data),
+ {TPid, NewS} = accept(S),
+ TPid ! {peeloff, setelement(2, T, peeloff(Sock, Id, TPid)), Matches},
+ setopts(Sock),
+ NewS;
- try find(Id, Data, S) of
- {TPid, NewS} ->
- TPid ! {peeloff, peeloff(Sock, Id, TPid), Msg, S#listener.accept},
- NewS;
- false ->
- S
- after
- setopts(Sock)
- end;
-
-l({'DOWN', MRef, process, TPid, _}, #listener{pending = {_,Q}} = S) ->
- down(ets:member(Q, TPid), MRef, TPid, S);
+l({'DOWN', _MRef, process, TPid, _}, #listener{pending = {_,Q}} = S) ->
+ down(queue:member(TPid, Q), TPid, S);
%% Timeout after the last accepting process has died.
l({timeout, TRef, close = T}, #listener{tref = TRef,
@@ -510,36 +460,25 @@ l({timeout, TRef, close = T}, #listener{tref = TRef,
l({timeout, _, close}, #listener{} = S) ->
S.
-%% down/4
+%% down/3
+%%
+%% Accepting transport has died.
+
+%% One that's waiting for transport start in the pending queue ...
+down(true, TPid, #listener{pending = {N,Q},
+ count = K}
+ = S) ->
+ NQ = queue:filter(fun(P) -> P /= TPid end, Q),
+ if N < 0 -> %% awaiting an association ...
+ start_timer(S#listener{count = K-1,
+ pending = {N+1, NQ}});
+ true -> %% ... or one has been assigned
+ S#listener{pending = {N-1, NQ}}
+ end;
-%% Accepting transport has died. One that's awaiting an association ...
-down(true, MRef, TPid, #listener{pending = {N,Q},
- tmap = T,
- count = K}
- = S)
- when N < 0 ->
- ets:delete(Q, TPid),
- ets:delete(T, MRef),
- ets:delete(T, TPid),
- start_timer(S#listener{count = K-1,
- pending = {N+1,Q}});
-
-%% ... or one that already has one.
-down(B, MRef, TPid, #listener{socket = Sock,
- tmap = T,
- count = K,
- pending = {N,Q}}
- = S) ->
- [{MRef, Id}] = ets:lookup(T, MRef), %% Id = TPid | AssocId
- ets:delete(T, MRef),
- ets:delete(T, Id),
- Id == TPid orelse close(Sock, Id),
- if B -> %% Waiting for attachment in the pending queue ...
- ets:delete(Q, TPid),
- S#listener{pending = {N-1,Q}};
- true -> %% ... or already attached
- start_timer(S#listener{count = K-1})
- end.
+%% ... or one that's already attached.
+down(false, _TPid, #listener{count = K} = S) ->
+ start_timer(S#listener{count = K-1}).
%% t/2
%%
@@ -557,20 +496,10 @@ t(T,S) ->
%% transition/2
-%% Listening process is transfering ownership of an association.
-transition({peeloff, Sock, {sctp, LSock, _RA, _RP, _Data} = Msg, Matches},
- #transport{mode = {accept, _},
- socket = LSock}
- = S) ->
- ok = accept_peer(Sock, Matches),
- transition(Msg, S#transport{socket = Sock});
-
%% Incoming message.
-transition({sctp, _Sock, _RA, _RP, Data}, #transport{socket = Sock} = S) ->
+transition({sctp, Sock, _RA, _RP, Data}, #transport{socket = Sock} = S) ->
setopts(Sock),
recv(Data, S);
-%% Don't match on Sock since in R15B01 it can be the listening socket
-%% in the (peeled-off) accept case, which is likely a bug.
%% Outgoing message.
transition({diameter, {send, Msg}}, S) ->
@@ -592,13 +521,8 @@ transition({diameter, {tls, _Ref, _Type, _Bool}}, _) ->
transition({'DOWN', _, process, Pid, _}, #transport{parent = Pid}) ->
stop;
-%% Listener process has died.
-transition({'DOWN', _, process, Pid, _}, #transport{mode = {accept, Pid}}) ->
- stop;
-
-%% Ditto but we have ownership of the association. It might be that
-%% we'll go down anyway though.
-transition({'DOWN', _, process, _Pid, _}, #transport{mode = accept}) ->
+%% Timeout after transport process has been started.
+transition(accept_timeout, _) ->
ok;
%% Request for the local port number.
@@ -625,37 +549,27 @@ accept_peer(Sock, Matches) ->
orelse x({accept, RAddrs, Matches}),
ok.
-%% accept/1
-
-accept(Opts) ->
- [[M] || {accept, M} <- Opts].
-
%% accept/3
%%
%% Start a new transport process or use one that's already been
-%% started as a consequence of association establishment.
+%% started as a consequence of diameter requesting a transport
+%% process.
-%% No pending associations: spawn a new transport.
-accept(Ref, Pid, #listener{socket = Sock,
- tmap = T,
- pending = {N,Q}})
- when N =< 0 ->
- Arg = {accept, Pid, self(), Sock, Ref},
- {ok, TPid} = diameter_sctp_sup:start_child(Arg),
- MRef = monitor(process, TPid),
- ets:insert(T, [{MRef, TPid}, {TPid, MRef}]),
- ets:insert(Q, {TPid, now()}),
- TPid;
-%% Placing the transport in the second pending table makes it
-%% available to the next association.
+accept(Ref, Pid, #listener{pending = {N,_}} = S) ->
+ {TPid, NQ} = q(Ref, Pid, S),
+ {TPid, S#listener{pending = {N-1, NQ}}}.
%% Pending associations: attach to the first in the queue.
-accept(_, Pid, #listener{ref = Ref,
- pending = {_,Q}}) ->
- TPid = ets:first(Q),
+q(_, Pid, #listener{ref = Ref,
+ pending = {N,Q}})
+ when 0 < N ->
+ {TPid, _} = T = dq(Q),
TPid ! {Ref, Pid},
- ets:delete(Q, TPid),
- TPid.
+ T;
+
+%% No pending associations: spawn a new transport.
+q(Ref, Pid, #listener{pending = {_,Q}}) ->
+ nq({accept, Ref, self(), Pid}, Q).
%% send/2
@@ -716,7 +630,7 @@ recv({_, #sctp_assoc_change{} = E},
= S) ->
S#transport{mode = {C, connect(Sock, RAs, RP, [{RA,E} | Es])}};
-%% Lost association after establishment.
+%% Association failure.
recv({_, #sctp_assoc_change{}}, _) ->
stop;
@@ -727,8 +641,10 @@ recv({[#sctp_sndrcvinfo{stream = Id}], Bin}, #transport{parent = Pid})
bin = Bin}),
ok;
-recv({_, #sctp_shutdown_event{assoc_id = Id}},
- #transport{assoc_id = Id}) ->
+recv({_, #sctp_shutdown_event{assoc_id = A}},
+ #transport{assoc_id = Id})
+ when A == Id;
+ A == 0 ->
stop;
%% Note that diameter_sctp(3) documents that sctp_events cannot be
@@ -764,52 +680,49 @@ up(#transport{parent = Pid,
diameter_peer:up(Pid),
S#transport{mode = A}.
-%% find/3
-
-find(Id, Data, #listener{tmap = T} = S) ->
- f(ets:lookup(T, Id), Data, S).
-
-%% New association ...
-f([],
- {_, #sctp_assoc_change{state = comm_up, assoc_id = Id}},
- #listener{pending = {N,Q}}
- = S) ->
- {find(Id, S), S#listener{pending = {N+1,Q}}};
-
-%% Known association ...
-f([{_, TPid}], _, S) ->
- {TPid, S};
-
-%% ... or not: discard.
-f([], _, _) ->
- false.
+%% accept/1
+%%
+%% Start a new transport process or use one that's already been
+%% started as a consequence of an event to a listener process.
-%% find/2
+accept(#listener{pending = {N,_}} = S) ->
+ {TPid, NQ} = q(S),
+ {TPid, S#listener{pending = {N+1, NQ}}}.
%% Transport waiting for an association: use it.
-find(Id, #listener{tmap = T,
- pending = {N,Q}})
+q(#listener{pending = {N,Q}})
when N < 0 ->
- TPid = ets:first(Q),
- [{TPid, MRef}] = ets:lookup(T, TPid),
- ets:insert(T, [{MRef, Id}, {Id, TPid}]),
- ets:delete(T, TPid),
- ets:delete(Q, TPid),
- TPid;
+ dq(Q);
%% No transport start yet: spawn one and queue.
-find(Id, #listener{ref = Ref,
- socket = Sock,
- tmap = T,
- pending = {_,Q}}) ->
- Arg = {accept, Ref, self(), Sock, Id},
+q(#listener{ref = Ref,
+ pending = {_,Q}}) ->
+ nq({accept, Ref, self()}, Q).
+
+%% nq/2
+%%
+%% Place a transport process in the second pending queue to make it
+%% available to the next association.
+
+nq(Arg, Q) ->
{ok, TPid} = diameter_sctp_sup:start_child(Arg),
- MRef = monitor(process, TPid),
- ets:insert(T, [{MRef, Id}, {Id, TPid}]),
- ets:insert(Q, {TPid, now()}),
- TPid.
+ monitor(process, TPid),
+ {TPid, queue:in(TPid, Q)}.
+
+%% dq/1
+%%
+%% Remove a transport process from the first pending queue to assign
+%% it to an existing association.
+
+dq(Q) ->
+ {{value, TPid}, NQ} = queue:out(Q),
+ {TPid, NQ}.
%% assoc_id/1
+%%
+%% It's unclear if this is needed, or if the first message on an
+%% association is always sctp_assoc_change, but don't assume since
+%% SCTP behaviour differs between operating systems.
assoc_id({[#sctp_sndrcvinfo{assoc_id = Id}], _}) ->
Id;
diff --git a/lib/diameter/src/transport/diameter_sctp_sup.erl b/lib/diameter/src/transport/diameter_sctp_sup.erl
index 3bdae02d68..48df975ae9 100644
--- a/lib/diameter/src/transport/diameter_sctp_sup.erl
+++ b/lib/diameter/src/transport/diameter_sctp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl
index 0b26f429fb..005b2442c0 100644
--- a/lib/diameter/src/transport/diameter_tcp.erl
+++ b/lib/diameter/src/transport/diameter_tcp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/transport/diameter_tcp_sup.erl b/lib/diameter/src/transport/diameter_tcp_sup.erl
index 1016fa2d9b..a7bdb49968 100644
--- a/lib/diameter/src/transport/diameter_tcp_sup.erl
+++ b/lib/diameter/src/transport/diameter_tcp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/src/transport/diameter_transport.erl b/lib/diameter/src/transport/diameter_transport.erl
index ff4b6bbc6d..5a7c59b4dc 100644
--- a/lib/diameter/src/transport/diameter_transport.erl
+++ b/lib/diameter/src/transport/diameter_transport.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/src/transport/diameter_transport_sup.erl b/lib/diameter/src/transport/diameter_transport_sup.erl
index 284a41a752..bf09504087 100644
--- a/lib/diameter/src/transport/diameter_transport_sup.erl
+++ b/lib/diameter/src/transport/diameter_transport_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/subdirs.mk b/lib/diameter/subdirs.mk
index d80c97d57a..1246d4fb91 100644
--- a/lib/diameter/subdirs.mk
+++ b/lib/diameter/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2010-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile
index aff1b18cf8..f9e0a61215 100644
--- a/lib/diameter/test/Makefile
+++ b/lib/diameter/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/test/coverspec.sed b/lib/diameter/test/coverspec.sed
index 5e81621593..3f573e29a2 100644
--- a/lib/diameter/test/coverspec.sed
+++ b/lib/diameter/test/coverspec.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/diameter/test/depend.sed b/lib/diameter/test/depend.sed
index 602d1ab497..58680a0c1b 100644
--- a/lib/diameter/test/depend.sed
+++ b/lib/diameter/test/depend.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/diameter/test/diameter_3xxx_SUITE.erl b/lib/diameter/test/diameter_3xxx_SUITE.erl
index 44cb0cc484..856244a691 100644
--- a/lib/diameter/test/diameter_3xxx_SUITE.erl
+++ b/lib/diameter/test/diameter_3xxx_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl
index 84f8a66a8a..71256020f5 100644
--- a/lib/diameter/test/diameter_app_SUITE.erl
+++ b/lib/diameter/test/diameter_app_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_capx_SUITE.erl b/lib/diameter/test/diameter_capx_SUITE.erl
index 02501ce779..ed6641b9fb 100644
--- a/lib/diameter/test/diameter_capx_SUITE.erl
+++ b/lib/diameter/test/diameter_capx_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -378,10 +379,14 @@ dict(N) ->
%% id's, failing with app_not_configured if it can't.
load_dict(N) ->
Mod = dict(N),
- Forms = [{attribute, 1, module, Mod},
- {attribute, 2, compile, [export_all]},
- {function, 3, id, 0,
- [{clause, 4, [], [], [{integer, 4, N}]}]}],
+ A1 = erl_anno:new(1),
+ A2 = erl_anno:new(2),
+ A3 = erl_anno:new(3),
+ A4 = erl_anno:new(4),
+ Forms = [{attribute, A1, module, Mod},
+ {attribute, A2, compile, [export_all]},
+ {function, A3, id, 0,
+ [{clause, A4, [], [], [{integer, A4, N}]}]}],
{ok, Mod, Bin, []} = compile:forms(Forms, [return]),
{module, Mod} = code:load_binary(Mod, Mod, Bin),
N = Mod:id().
diff --git a/lib/diameter/test/diameter_codec_SUITE.erl b/lib/diameter/test/diameter_codec_SUITE.erl
index 64ea90554d..558ba3b848 100644
--- a/lib/diameter/test/diameter_codec_SUITE.erl
+++ b/lib/diameter/test/diameter_codec_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_codec_SUITE_data/avps.dia b/lib/diameter/test/diameter_codec_SUITE_data/avps.dia
index c9d80a37a9..d8fa7ac02e 100644
--- a/lib/diameter/test/diameter_codec_SUITE_data/avps.dia
+++ b/lib/diameter/test/diameter_codec_SUITE_data/avps.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-2011. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl b/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl
index cdf0cf55e1..248fb66f40 100644
--- a/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl
+++ b/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_codec_SUITE_data/recv.dia b/lib/diameter/test/diameter_codec_SUITE_data/recv.dia
index 15fec5a5dd..7302f8cec2 100644
--- a/lib/diameter/test/diameter_codec_SUITE_data/recv.dia
+++ b/lib/diameter/test/diameter_codec_SUITE_data/recv.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-2011. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/test/diameter_codec_SUITE_data/send.dia b/lib/diameter/test/diameter_codec_SUITE_data/send.dia
index 1472f146ae..2b6478e4b6 100644
--- a/lib/diameter/test/diameter_codec_SUITE_data/send.dia
+++ b/lib/diameter/test/diameter_codec_SUITE_data/send.dia
@@ -3,16 +3,17 @@
;;
;; Copyright Ericsson AB 2010-2011. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
diff --git a/lib/diameter/test/diameter_codec_test.erl b/lib/diameter/test/diameter_codec_test.erl
index 5f1dbfbd61..78308856ac 100644
--- a/lib/diameter/test/diameter_codec_test.erl
+++ b/lib/diameter/test/diameter_codec_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_compiler_SUITE.erl b/lib/diameter/test/diameter_compiler_SUITE.erl
index 20c9275808..8807f19f09 100644
--- a/lib/diameter/test/diameter_compiler_SUITE.erl
+++ b/lib/diameter/test/diameter_compiler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_config_SUITE.erl b/lib/diameter/test/diameter_config_SUITE.erl
index 4bcaa8119f..31a6b49041 100644
--- a/lib/diameter/test/diameter_config_SUITE.erl
+++ b/lib/diameter/test/diameter_config_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_ct.erl b/lib/diameter/test/diameter_ct.erl
index 85c502ea7f..551771392d 100644
--- a/lib/diameter/test/diameter_ct.erl
+++ b/lib/diameter/test/diameter_ct.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/test/diameter_ct.hrl b/lib/diameter/test/diameter_ct.hrl
index b6bd2ca9da..0b5a999de6 100644
--- a/lib/diameter/test/diameter_ct.hrl
+++ b/lib/diameter/test/diameter_ct.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_dict_SUITE.erl b/lib/diameter/test/diameter_dict_SUITE.erl
index 3cc65c0257..f1d69be33e 100644
--- a/lib/diameter/test/diameter_dict_SUITE.erl
+++ b/lib/diameter/test/diameter_dict_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_distribution_SUITE.erl b/lib/diameter/test/diameter_distribution_SUITE.erl
index f069abbe2f..d32d5bbd49 100644
--- a/lib/diameter/test/diameter_distribution_SUITE.erl
+++ b/lib/diameter/test/diameter_distribution_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_dpr_SUITE.erl b/lib/diameter/test/diameter_dpr_SUITE.erl
index 81178e2bda..55702fbf78 100644
--- a/lib/diameter/test/diameter_dpr_SUITE.erl
+++ b/lib/diameter/test/diameter_dpr_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_enum.erl b/lib/diameter/test/diameter_enum.erl
index dfb6d04e3c..ab1b76e5fe 100644
--- a/lib/diameter/test/diameter_enum.erl
+++ b/lib/diameter/test/diameter_enum.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl
index bfe160203c..b450c9ea59 100644
--- a/lib/diameter/test/diameter_event_SUITE.erl
+++ b/lib/diameter/test/diameter_event_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-15. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl
index ef8e459175..e4ed2b227d 100644
--- a/lib/diameter/test/diameter_examples_SUITE.erl
+++ b/lib/diameter/test/diameter_examples_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -298,7 +299,7 @@ slave(_) ->
T0 = diameter_lib:now(),
{ok, Node} = ct_slave:start(?MODULE, ?TIMEOUTS),
T1 = diameter_lib:now(),
- T2 = rpc:call(Node, erlang, now, []),
+ T2 = rpc:call(Node, diameter_lib, now, []),
{ok, Node} = ct_slave:stop(?MODULE),
now_diff([T0, T1, T2, diameter_lib:now()]).
diff --git a/lib/diameter/test/diameter_failover_SUITE.erl b/lib/diameter/test/diameter_failover_SUITE.erl
index c1494dcdb1..1f345423cf 100644
--- a/lib/diameter/test/diameter_failover_SUITE.erl
+++ b/lib/diameter/test/diameter_failover_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_gen_sctp_SUITE.erl b/lib/diameter/test/diameter_gen_sctp_SUITE.erl
index 4ea5e80095..cbd7fc8ec5 100644
--- a/lib/diameter/test/diameter_gen_sctp_SUITE.erl
+++ b/lib/diameter/test/diameter_gen_sctp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,7 +34,7 @@
%% testcases
-export([send_not_from_controlling_process/1,
- send_from_multiple_clients/1,
+ send_from_multiple_clients/1, send_from_multiple_clients/0,
receive_what_was_sent/1]).
-include_lib("kernel/include/inet_sctp.hrl").
@@ -58,7 +59,7 @@
%% ===========================================================================
suite() ->
- [{timetrap, {minutes, 2}}].
+ [{timetrap, {seconds, 10}}].
all() ->
[send_not_from_controlling_process,
@@ -167,6 +168,9 @@ send(Sock, Id) ->
%%
%% Demonstrates sluggish delivery of messages.
+send_from_multiple_clients() ->
+ [{timetrap, {seconds, 60}}].
+
send_from_multiple_clients(_) ->
{S, Rs} = T = send_from_multiple_clients(8, 1024),
Max = ?FOREVER*1000,
@@ -296,10 +300,10 @@ connect2(Pid, PortNr, Bin) ->
%% T2 = time after listening process received our message
%% T3 = time after reply is received
- T1 = diameter_util:timestamp(),
+ T1 = diameter_lib:now(),
ok = send(Sock, Id, Bin),
T2 = unmark(recv(Sock, Id)),
- T3 = diameter_util:timestamp(),
+ T3 = diameter_lib:now(),
{diameter_lib:micro_diff(T2, T1), %% Outbound
diameter_lib:micro_diff(T3, T2)}. %% Inbound
@@ -326,13 +330,13 @@ send(Sock, Id, Bin) ->
%% mark/1
mark(Bin) ->
- Info = term_to_binary(diameter_util:timestamp()),
+ Info = term_to_binary(diameter_lib:now()),
<<Info/binary, Bin/binary>>.
%% unmark/1
unmark(Bin) ->
- {_,_,_} = binary_to_term(Bin).
+ binary_to_term(Bin).
%% ===========================================================================
diff --git a/lib/diameter/test/diameter_gen_tcp_SUITE.erl b/lib/diameter/test/diameter_gen_tcp_SUITE.erl
index 4b542e0156..2be2cf4b35 100644
--- a/lib/diameter/test/diameter_gen_tcp_SUITE.erl
+++ b/lib/diameter/test/diameter_gen_tcp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,7 +40,7 @@
%% ===========================================================================
suite() ->
- [{timetrap, {minutes, 2}}].
+ [{timetrap, {seconds, 10}}].
all() ->
[connect, %% Appears to fail only when run first.
diff --git a/lib/diameter/test/diameter_length_SUITE.erl b/lib/diameter/test/diameter_length_SUITE.erl
index ffb19d2288..0f98b08585 100644
--- a/lib/diameter/test/diameter_length_SUITE.erl
+++ b/lib/diameter/test/diameter_length_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_pool_SUITE.erl b/lib/diameter/test/diameter_pool_SUITE.erl
index a59cd66a2e..eadb354a1d 100644
--- a/lib/diameter/test/diameter_pool_SUITE.erl
+++ b/lib/diameter/test/diameter_pool_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_reg_SUITE.erl b/lib/diameter/test/diameter_reg_SUITE.erl
index 4939019f7a..2945235ecc 100644
--- a/lib/diameter/test/diameter_reg_SUITE.erl
+++ b/lib/diameter/test/diameter_reg_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_relay_SUITE.erl b/lib/diameter/test/diameter_relay_SUITE.erl
index 7142239bbb..f766f54a80 100644
--- a/lib/diameter/test/diameter_relay_SUITE.erl
+++ b/lib/diameter/test/diameter_relay_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -333,13 +334,39 @@ realm(Host) ->
call(Server) ->
Realm = realm(Server),
+ %% Include some arbitrary AVPs to exercise encode/decode, that
+ %% are received back in the STA.
+ Avps = [#diameter_avp{code = 111,
+ data = [#diameter_avp{code = 222,
+ data = <<222:24>>},
+ #diameter_avp{code = 333,
+ data = <<333:16>>}]},
+ #diameter_avp{code = 444,
+ data = <<444:24>>},
+ #diameter_avp{code = 555,
+ data = [#diameter_avp{code = 666,
+ data = [#diameter_avp
+ {code = 777,
+ data = <<7>>}]},
+ #diameter_avp{code = 888,
+ data = <<8>>},
+ #diameter_avp{code = 999,
+ data = <<9>>}]}],
+
Req = ['STR', {'Destination-Realm', Realm},
{'Destination-Host', [Server]},
{'Termination-Cause', ?LOGOUT},
- {'Auth-Application-Id', ?APP_ID}],
+ {'Auth-Application-Id', ?APP_ID},
+ {'AVP', Avps}],
+
#diameter_base_STA{'Result-Code' = ?SUCCESS,
'Origin-Host' = Server,
- 'Origin-Realm' = Realm}
+ 'Origin-Realm' = Realm,
+ %% Unknown AVPs can't be decoded as Grouped since
+ %% types aren't known.
+ 'AVP' = [#diameter_avp{code = 111},
+ #diameter_avp{code = 444},
+ #diameter_avp{code = 555}]}
= call(Req, [{filter, realm}]).
call(Req, Opts) ->
@@ -433,9 +460,18 @@ request(_Pkt, #diameter_caps{origin_host = {OH, _}})
request(#diameter_packet{msg = #diameter_base_STR{'Session-Id' = SId,
'Origin-Host' = Host,
'Origin-Realm' = Realm,
- 'Route-Record' = Route}},
+ 'Route-Record' = Route,
+ 'AVP' = Avps}},
#diameter_caps{origin_host = {OH, _},
origin_realm = {OR, _}}) ->
+
+ %% Payloads of unknown AVPs aren't decoded, so we don't know that
+ %% some types here are Grouped.
+ [#diameter_avp{code = 111, vendor_id = undefined},
+ #diameter_avp{code = 444, vendor_id = undefined, data = <<444:24>>},
+ #diameter_avp{code = 555, vendor_id = undefined}]
+ = Avps,
+
%% The request should have the Origin-Host/Realm of the original
%% sender.
R = realm(?CLIENT),
@@ -446,4 +482,5 @@ request(#diameter_packet{msg = #diameter_base_STR{'Session-Id' = SId,
{reply, #diameter_base_STA{'Result-Code' = ?SUCCESS,
'Session-Id' = SId,
'Origin-Host' = OH,
- 'Origin-Realm' = OR}}.
+ 'Origin-Realm' = OR,
+ 'AVP' = Avps}}.
diff --git a/lib/diameter/test/diameter_stats_SUITE.erl b/lib/diameter/test/diameter_stats_SUITE.erl
index 76ff764671..4716082394 100644
--- a/lib/diameter/test/diameter_stats_SUITE.erl
+++ b/lib/diameter/test/diameter_stats_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -95,7 +96,7 @@ read(_) ->
7 = ?stat:incr(C1, Ref, 7),
Self = self(),
[{Ref, [{C1,7}]}, {Self, [{C1,2}, {C2,1}]}]
- = lists:sort(?stat:read([self(), Ref, make_ref()])),
+ = ?stat:read([self(), Ref, make_ref()]),
[] = ?stat:read([]),
[] = ?stat:read([make_ref()]),
?stat:flush([self(), Ref, make_ref()]).
@@ -115,7 +116,7 @@ sum(_) ->
[{Self, [{C1,1}, {C2,2}]}]
= ?stat:sum([self()]),
[{Ref, [{C1,7}]}, {Self, [{C1,1}, {C2,2}]}]
- = lists:sort(?stat:flush([self(), Ref])).
+ = ?stat:flush([self(), Ref]).
flush(_) ->
Ref = make_ref(),
diff --git a/lib/diameter/test/diameter_sync_SUITE.erl b/lib/diameter/test/diameter_sync_SUITE.erl
index 457efab8ae..f913389f65 100644
--- a/lib/diameter/test/diameter_sync_SUITE.erl
+++ b/lib/diameter/test/diameter_sync_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_tls_SUITE.erl b/lib/diameter/test/diameter_tls_SUITE.erl
index e5bbda9c91..5cadbbc17e 100644
--- a/lib/diameter/test/diameter_tls_SUITE.erl
+++ b/lib/diameter/test/diameter_tls_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/diameter/test/diameter_tls_SUITE_data/Makefile.ca b/lib/diameter/test/diameter_tls_SUITE_data/Makefile.ca
index 3f2645add0..d9c0753d0d 100644
--- a/lib/diameter/test/diameter_tls_SUITE_data/Makefile.ca
+++ b/lib/diameter/test/diameter_tls_SUITE_data/Makefile.ca
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index 17faf30a9b..967a0bf591 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,6 +49,7 @@
send_unknown_mandatory/1,
send_unknown_short_mandatory/1,
send_noreply/1,
+ send_grouped_error/1,
send_unsupported/1,
send_unsupported_app/1,
send_error_bit/1,
@@ -268,15 +270,15 @@ groups() ->
SD <- ?STRING_DECODES,
CD <- ?STRING_DECODES]
++
- [{traffic, [parallel], [{group, ?util:name([T,R,D,A,C,SD,CD])}
- || T <- ?TRANSPORTS,
- T /= sctp orelse Sctp,
- R <- ?ENCODINGS,
- D <- ?RFCS,
- A <- ?ENCODINGS,
- C <- ?CONTAINERS,
- SD <- ?STRING_DECODES,
- CD <- ?STRING_DECODES]}].
+ [{traffic, [], [{group, ?util:name([T,R,D,A,C,SD,CD])}
+ || T <- ?TRANSPORTS,
+ T /= sctp orelse Sctp,
+ R <- ?ENCODINGS,
+ D <- ?RFCS,
+ A <- ?ENCODINGS,
+ C <- ?CONTAINERS,
+ SD <- ?STRING_DECODES,
+ CD <- ?STRING_DECODES]}].
init_per_group(Name, Config) ->
case ?util:name(Name) of
@@ -329,6 +331,7 @@ tc() ->
send_unknown_mandatory,
send_unknown_short_mandatory,
send_noreply,
+ send_grouped_error,
send_unsupported,
send_unsupported_app,
send_error_bit,
@@ -573,7 +576,7 @@ send_unknown_mandatory(Config) ->
send_unknown_short_mandatory(Config) ->
send_unknown_short(Config, true, ?INVALID_AVP_LENGTH).
-%% Send an ACR containing an unexpected mandatory Session-Timeout.
+%% Send an ASR containing an unexpected mandatory Session-Timeout.
%% Expect 5001, and check that the value in Failed-AVP was decoded.
send_unexpected_mandatory_decode(Config) ->
Req = ['ASR', {'AVP', [#diameter_avp{code = 27, %% Session-Timeout
@@ -589,6 +592,25 @@ send_unexpected_mandatory_decode(Config) ->
data = <<12:32>>}]
= As.
+%% Send an containing a faulty Grouped AVP (empty Proxy-Host in
+%% Proxy-Info) and expect that only the faulty AVP is sent in
+%% Failed-AVP. The encoded values of Proxy-Host and Proxy-State are
+%% swapped in prepare_request since an empty Proxy-Host is an encode
+%% error.
+send_grouped_error(Config) ->
+ Req = ['ASR', {'Proxy-Info', [[{'Proxy-Host', "abcd"},
+ {'Proxy-State', ""}]]}],
+ ['ASA', {'Session-Id', _}, {'Result-Code', ?INVALID_AVP_LENGTH} | Avps]
+ = call(Config, Req),
+ [#'diameter_base_Failed-AVP'{'AVP' = As}]
+ = proplists:get_value('Failed-AVP', Avps),
+ [#diameter_avp{name = 'Proxy-Info',
+ value = #'diameter_base_Proxy-Info'
+ {'Proxy-Host' = Empty,
+ 'Proxy-State' = undefined}}]
+ = As,
+ <<0>> = iolist_to_binary(Empty).
+
%% Send an STR that the server ignores.
send_noreply(Config) ->
Req = ['STR', {'Termination-Cause', ?BAD_ANSWER}],
@@ -703,7 +725,8 @@ send_any_2(Config) ->
Req = ['STR', {'Termination-Cause', ?LOGOUT},
{'Destination-Host', [?HOST(SN, "unknown.org")]}],
?answer_message(?UNABLE_TO_DELIVER)
- = call(Config, Req, [{filter, {any, [host, realm]}}]).
+ = call(Config, Req, [{filter, {first, [{all, [host, realm]},
+ realm]}}]).
%% Send with a conjunctive filter.
send_all_1(Config) ->
@@ -1069,6 +1092,38 @@ prepare(Pkt, Caps, send_unexpected_mandatory, #group{client_dict0 = Dict0}
Avp = <<Code:32, Flags, 8:24>>,
E#diameter_packet{bin = <<V, (Len+8):24, T/binary, Avp/binary>>};
+prepare(Pkt, Caps, send_grouped_error, #group{client_dict0 = Dict0}
+ = Group) ->
+ Req = prepare(Pkt, Caps, Group),
+ #diameter_packet{bin = Bin}
+ = E
+ = diameter_codec:encode(Dict0, Pkt#diameter_packet{msg = Req}),
+ {Code, Flags, undefined} = Dict0:avp_header('Proxy-Info'),
+ %% Find Proxy-Info by looking for its header.
+ Pattern = <<Code:32, Flags, 28:24>>,
+ {Offset, 8} = binary:match(Bin, Pattern),
+
+ %% Extract and swap Proxy-Host/State payloads.
+
+ <<H:Offset/binary,
+ PI:8/binary,
+ PH:5/binary,
+ 12:24,
+ Payload:4/binary,
+ PS:5/binary,
+ 8:24,
+ T/binary>>
+ = Bin,
+
+ E#diameter_packet{bin = <<H/binary,
+ PI/binary,
+ PH/binary,
+ 8:24,
+ PS:5/binary,
+ 12:24,
+ Payload/binary,
+ T/binary>>};
+
prepare(Pkt, Caps, send_unsupported, #group{client_dict0 = Dict0} = Group) ->
Req = prepare(Pkt, Caps, Group),
#diameter_packet{bin = <<H:5/binary, _CmdCode:3/binary, T/binary>>}
@@ -1175,7 +1230,7 @@ answer(Pkt, Req, _Peer, Name, #group{client_dict0 = Dict0}) ->
[R | Vs] = Dict:'#get-'(answer(Ans, Es, Name)),
[Dict:rec2msg(R) | Vs].
-%% Missing Result-Codec and inapproriate Experimental-Result-Code.
+%% Missing Result-Code and inappropriate Experimental-Result-Code.
answer(Rec, Es, send_experimental_result) ->
[{5004, #diameter_avp{name = 'Experimental-Result'}},
{5005, #diameter_avp{name = 'Result-Code'}}]
diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl
index 78bddbd1cf..53d2d6660e 100644
--- a/lib/diameter/test/diameter_transport_SUITE.erl
+++ b/lib/diameter/test/diameter_transport_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -53,7 +54,7 @@
%% Receive a message.
-define(RECV(Pat, Ret), receive Pat -> Ret end).
--define(RECV(Pat), ?RECV(Pat, diameter_util:timestamp())).
+-define(RECV(Pat), ?RECV(Pat, diameter_lib:now())).
%% Sockets are opened on the loopback address.
-define(ADDR, {127,0,0,1}).
@@ -416,8 +417,7 @@ gen_accept(tcp, LSock) ->
gen_send(sctp, Sock, Bin) ->
{OS, _IS, Id} = getr(assoc),
- {_, _, Us} = diameter_util:timestamp(),
- gen_sctp:send(Sock, Id, Us rem OS, Bin);
+ gen_sctp:send(Sock, Id, erlang:unique_integer([positive]) rem OS, Bin);
gen_send(tcp, Sock, Bin) ->
gen_tcp:send(Sock, Bin).
diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl
index df7d268429..52b747e99c 100644
--- a/lib/diameter/test/diameter_util.erl
+++ b/lib/diameter/test/diameter_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,6 @@
fold/3,
foldl/3,
scramble/1,
- timestamp/0,
seed/0,
unique_string/0,
have_sctp/0]).
@@ -188,12 +188,6 @@ s(Acc, L) ->
s([T|Acc], H ++ Rest).
%% ---------------------------------------------------------------------------
-%% timestamp/0
-
-timestamp() ->
- diameter_lib:timestamp(diameter_lib:now()).
-
-%% ---------------------------------------------------------------------------
%% seed/0
seed() ->
@@ -204,14 +198,7 @@ seed() ->
%% unique_string/0
unique_string() ->
- try erlang:unique_integer() of
- N ->
- integer_to_list(N)
- catch
- error: undef -> %% OTP < 18
- {M,S,U} = timestamp(),
- tl(lists:append(["-" ++ integer_to_list(N) || N <- [M,S,U]]))
- end.
+ integer_to_list(erlang:unique_integer()).
%% ---------------------------------------------------------------------------
%% have_sctp/0
@@ -380,12 +367,38 @@ tmod(any) ->
[diameter_sctp, diameter_tcp].
opts(Prot, T) ->
- [{transport_module, M} || M <- tmod(Prot)]
- ++ [{transport_config, [{ip, ?ADDR}, {port, 0} | opts(T)]}].
-
-opts(listen) ->
+ tmo(T, lists:append([[{transport_module, M}, {transport_config, C}]
+ || M <- tmod(Prot),
+ C <- [cfg(M,T) ++ cfg(M) ++ cfg(T)]])).
+
+tmo(listen, Opts) ->
+ Opts;
+tmo(_, Opts) ->
+ tmo(Opts).
+
+%% Timeout on all but the last alternative.
+tmo([_,_] = Opts) ->
+ Opts;
+tmo([M, C | Opts]) ->
+ {transport_config = K, Cfg} = C,
+ [M, {K, Cfg, 5000} | tmo(Opts)].
+
+%% Listening SCTP socket need larger-than-default buffers to avoid
+%% resends on some platforms (eg. SLES 11).
+cfg(diameter_sctp, listen) ->
+ [{recbuf, 1 bsl 16}, {sndbuf, 1 bsl 16}];
+
+cfg(_, _) ->
+ [].
+
+cfg(M)
+ when M == diameter_tcp;
+ M == diameter_sctp ->
+ [{ip, ?ADDR}, {port, 0}];
+
+cfg(listen) ->
[{accept, M} || M <- [{256,0,0,1}, ["256.0.0.1", ["^.+$"]]]];
-opts(PortNr) ->
+cfg(PortNr) ->
[{raddr, ?ADDR}, {rport, PortNr}].
%% ---------------------------------------------------------------------------
diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl
index f39e12686e..6d22ddcc18 100644
--- a/lib/diameter/test/diameter_watchdog_SUITE.erl
+++ b/lib/diameter/test/diameter_watchdog_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,7 +49,8 @@
accept/1,
connect/3,
send/2,
- setopts/2]).
+ setopts/2,
+ close/1]).
-include("diameter.hrl").
-include("diameter_ct.hrl").
@@ -420,7 +422,6 @@ suspect(TRef, false, SvcName, N) ->
%% abuse/1
abuse(F) ->
-
[] = run([[abuse, F, T] || T <- [listen, connect]]).
abuse(F, [_,_,_|_] = Args) ->
@@ -545,6 +546,9 @@ setopts(Sock, Opts) ->
send(Sock, Bin) ->
send(getr(config), Sock, Bin).
+close(Sock) ->
+ gen_tcp:close(Sock).
+
%% send/3
%% First outgoing message from a new transport process is CER/CEA.
diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk
index 6da96bd676..80d0f8d59c 100644
--- a/lib/diameter/test/modules.mk
+++ b/lib/diameter/test/modules.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/diameter/test/release.sed b/lib/diameter/test/release.sed
index 2720b778f2..c4124046bc 100644
--- a/lib/diameter/test/release.sed
+++ b/lib/diameter/test/release.sed
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk
index c278e74dca..836def8447 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -2,19 +2,20 @@
#
# Copyright Ericsson AB 2010-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
APPLICATION = diameter
-DIAMETER_VSN = 1.9.2
+DIAMETER_VSN = 1.11.2
APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)
diff --git a/lib/edoc/Makefile b/lib/edoc/Makefile
index 1add669398..70bf1f3d48 100644
--- a/lib/edoc/Makefile
+++ b/lib/edoc/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/edoc/doc/Makefile b/lib/edoc/doc/Makefile
index 7a59809d9b..c635f07d78 100644
--- a/lib/edoc/doc/Makefile
+++ b/lib/edoc/doc/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/edoc/doc/overview.edoc b/lib/edoc/doc/overview.edoc
index 2af425272e..d2bba9d744 100644
--- a/lib/edoc/doc/overview.edoc
+++ b/lib/edoc/doc/overview.edoc
@@ -76,11 +76,9 @@ The following are the main functions for running EDoc:
<ul>
<li>{@link edoc:application/2}: Creates documentation for a
typical Erlang application.</li>
- <li>{@link edoc:packages/2}: Creates documentation for one or
- more packages, automatically locating source files.</li>
<li>{@link edoc:files/2}: Creates documentation for a
specified set of source files.</li>
- <li>{@link edoc:run/3}: General interface function; the common
+ <li>{@link edoc:run/2}: General interface function; the common
back-end for the above functions. Options are documented here.</li>
</ul>
@@ -184,7 +182,7 @@ The following tags can be used anywhere within a module:
path (see {@link edoc:read_source/2}).</dd>
<dt><a name="gtag-todo">`@todo' (or `@TODO')</a></dt>
- <dd>Attaches a To-Do note to a function, module, package, or
+ <dd>Attaches a To-Do note to a function, module or
overview-page. The content can be any XHTML text describing
the issue, e.g.:
```%% @TODO Finish writing the documentation.'''
@@ -338,7 +336,7 @@ The following tags can be used before a module declaration:
<dt><a name="mtag-since">`@since'</a></dt>
<dd>Specifies when the module was introduced, with respect to
- the application, package, release or distribution it is part
+ the application, release or distribution it is part
of. The content can be arbitrary text.</dd>
<dt><a name="mtag-version">`@version'</a></dt>
@@ -445,7 +443,6 @@ possible formats for references are:
<table border="1" summary="reference syntax">
<tr><th>Reference syntax</th><th>Example</th><th>Scope</th></tr>
<tr><td>`Module'</td><td>{@link edoc_run}, `erl.lang.list'</td><td>Global</td></tr>
- <tr><td>`Package.*'</td><td>`erl.lang.*'</td><td>Global</td></tr>
<tr><td>`Function/Arity'</td><td>`file/2'</td><td>Within module</td></tr>
<tr><td>`Module:Function/Arity'</td><td>{@link edoc:application/2}</td><td>Global</td></tr>
<tr><td>`Type()'</td><td>`filename()'</td><td>Within module</td></tr>
@@ -531,7 +528,7 @@ after the empty line into separate paragraphs. For example:
```%% @doc This will all be part of the first paragraph.
%% It can stretch over several lines and contain <em>any
%% XHTML markup</em>.
- %%
+ %%
%% This is the second paragraph. The above line is
%% regarded as "empty" by EDoc, even though it ends with
%% a space.'''
@@ -685,17 +682,6 @@ information. User-defined macros override predefined macros.
<dd>Expands to the current date, as "<tt>Month Day Year</tt>",
e.g. "{@date}".</dd>
- <dt><a name="predefmacro-docRoot"><code>@{@docRoot}</code></a></dt>
- <dd>Expands to the relative URL path (such as
- `"../../.."') from the current page to the root
- directory of the generated documentation. This can be used to
- create XHTML references such as `<img
- src="@{@docRoot}/images/logo.jpeg">' that are independent of how
- deep down in a package structure they occur. If packages are not
- used (i.e., if all modules are in the "empty" package),
- <code>@{@docRoot}</code> will always resolve to the empty
- string.</dd>
-
<dt><a name="predefmacro-link"><code>@{@link <em>reference</em>.
<em>description</em>}</code></a></dt>
<dd>This creates a hypertext link; cf. the
@@ -710,9 +696,6 @@ information. User-defined macros override predefined macros.
<dd>Expands to the name of the current module. Only defined when a
module is being processed.</dd>
- <dt><a name="predefmacro-package"><code>@{@package}</code></a></dt>
- <dd>Expands to the name of the current package.</dd>
-
<dt><a name="predefmacro-section"><code>@{@section
<em>heading</em>}</code></a></dt>
<dd>Expands to a hypertext link to the specified section heading;
@@ -772,7 +755,7 @@ following escape sequences may be used: <dl>
=== Function specifications ===
-<note>Although the syntax described in the following can still be used
+Note that although the syntax described in the following can still be used
for specifying functions we recommend that Erlang specifications as
described in <seealso marker="doc/reference_manual:typespec"> Types
and Function Specification</seealso> should be added to the source
@@ -781,7 +764,6 @@ marker="dialyzer:dialyzer">Dialyzer</seealso>'s can be utilized in the
process of keeping the documentation consistent and up-to-date.
Erlang specifications will be used unless there is also a function
specification (a `@spec' tag followed by a type) with the same name.
-</note>
The following grammar describes the form of the specifications following
a `@spec' tag. A '`?'' suffix implies that the element is optional.
@@ -990,12 +972,12 @@ contain any annotations at all.
=== Type definitions ===
-<note>Although the syntax described in the following can still be used
+Note that although the syntax described in the following can still be used
for specifying types we recommend that Erlang types as described in
<seealso marker="doc/reference_manual:typespec"> Types and Function
Specification</seealso> should be added to the source code instead.
Erlang types will be used unless there is a type alias with the same
-name.</note>
+name.
The following grammar (see above for auxiliary definitions) describes
the form of the definitions that may follow a `@type' tag:
diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile
index 1f92d36f12..ce7945a1bb 100644
--- a/lib/edoc/doc/src/Makefile
+++ b/lib/edoc/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/edoc/doc/src/book.xml b/lib/edoc/doc/src/book.xml
index 1a11629e6d..002bf27b94 100644
--- a/lib/edoc/doc/src/book.xml
+++ b/lib/edoc/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index e350adb540..3f9d26796a 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,48 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.18</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Assign correct names to list arguments. </p>
+ <p>
+ Own Id: OTP-13234 Aux Id: ERL-63 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Unless the <c>sort_functions</c> option is <c>true</c>,
+ <c>edoc_layout</c> does not sort functions.</p>
+ <p>
+ Own Id: OTP-13302</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Edoc 0.7.17</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Remove functionality related to packages</p>
+ <p>
+ Own Id: OTP-12431</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.16</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/edoc/doc/src/part.xml b/lib/edoc/doc/src/part.xml
index 876ae858f9..b55916823a 100644
--- a/lib/edoc/doc/src/part.xml
+++ b/lib/edoc/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/edoc/doc/src/part_notes.xml b/lib/edoc/doc/src/part_notes.xml
index 41e6c1c7f7..da3d7299f4 100644
--- a/lib/edoc/doc/src/part_notes.xml
+++ b/lib/edoc/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/edoc/doc/src/ref_man.xml b/lib/edoc/doc/src/ref_man.xml
index a71b35d118..abe400d4d5 100644
--- a/lib/edoc/doc/src/ref_man.xml
+++ b/lib/edoc/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/edoc/include/Makefile b/lib/edoc/include/Makefile
index cf2e051632..6318253c27 100644
--- a/lib/edoc/include/Makefile
+++ b/lib/edoc/include/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/edoc/include/edoc_doclet.hrl b/lib/edoc/include/edoc_doclet.hrl
index 60ec7f44e4..ac6763fb33 100644
--- a/lib/edoc/include/edoc_doclet.hrl
+++ b/lib/edoc/include/edoc_doclet.hrl
@@ -1,6 +1,6 @@
%% =====================================================================
%% Header file for EDoc doclet modules.
-%%
+%%
%% Copyright (C) 2001-2004 Richard Carlsson
%%
%% This library is free software; you can redistribute it and/or modify
@@ -43,16 +43,11 @@
%% @type doclet_gen() = #doclet_gen{sources = [string()],
%% app = no_app() | atom(),
-%% packages = [atom()],
-%% modules = [atom()],
-%% modules = [atom()],
-%% filemap = function()}
+%% modules = [atom()]}
-record(doclet_gen, {sources = [],
app = ?NO_APP,
- packages = [],
- modules = [],
- filemap
+ modules = []
}).
%% @type doclet_toc() = #doclet_gen{paths = [string()],
diff --git a/lib/edoc/priv/edoc.dtd b/lib/edoc/priv/edoc.dtd
index ba4ac0db28..4278a9e643 100644
--- a/lib/edoc/priv/edoc.dtd
+++ b/lib/edoc/priv/edoc.dtd
@@ -2,20 +2,13 @@
<!-- EDoc DTD Version 0.3 -->
<!ELEMENT overview (title, description?, author*, copyright?, version?,
- since?, see*, reference*, todo?, packages, modules)>
+ since?, see*, reference*, todo?, modules)>
<!ATTLIST overview
root CDATA #IMPLIED
encoding CDATA #IMPLIED>
<!ELEMENT title (#PCDATA)>
-<!ELEMENT package (description?, author*, copyright?, version?,
- since?, deprecated?, see*, reference*, todo?,
- modules)>
-<!ATTLIST package
- name CDATA #REQUIRED
- root CDATA #IMPLIED>
-
<!ELEMENT modules (module+)>
diff --git a/lib/edoc/priv/edoc_generate.src b/lib/edoc/priv/edoc_generate.src
index 7ec89207b0..eeaa20f959 100644
--- a/lib/edoc/priv/edoc_generate.src
+++ b/lib/edoc/priv/edoc_generate.src
@@ -1,14 +1,15 @@
#!/bin/sh
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999-2000, Ericsson
diff --git a/lib/edoc/priv/stylesheet.css b/lib/edoc/priv/stylesheet.css
index e426a90483..ab170c091f 100644
--- a/lib/edoc/priv/stylesheet.css
+++ b/lib/edoc/priv/stylesheet.css
@@ -27,10 +27,10 @@ div.spec {
margin-left: 2em;
background-color: #eeeeee;
}
-a.module,a.package {
+a.module {
text-decoration:none
}
-a.module:hover,a.package:hover {
+a.module:hover {
background-color: #eeeeee;
}
ul.definitions {
diff --git a/lib/edoc/src/edoc.app.src b/lib/edoc/src/edoc.app.src
index 9e1155d3e8..e4b9040c78 100644
--- a/lib/edoc/src/edoc.app.src
+++ b/lib/edoc/src/edoc.app.src
@@ -23,5 +23,5 @@
{registered,[]},
{applications, [compiler,kernel,stdlib,syntax_tools]},
{env, []},
- {runtime_dependencies, ["xmerl-1.3.7","syntax_tools-1.6.14","stdlib-2.0",
+ {runtime_dependencies, ["xmerl-1.3.7","syntax_tools-1.6.14","stdlib-2.5",
"kernel-3.0","inets-5.10","erts-6.0"]}]}.
diff --git a/lib/edoc/src/edoc.appup.src b/lib/edoc/src/edoc.appup.src
index 45b4046ed8..6d21891a36 100644
--- a/lib/edoc/src/edoc.appup.src
+++ b/lib/edoc/src/edoc.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/edoc/src/edoc.erl b/lib/edoc/src/edoc.erl
index 983f04e8b6..d2494b69fe 100644
--- a/lib/edoc/src/edoc.erl
+++ b/lib/edoc/src/edoc.erl
@@ -24,12 +24,11 @@
%% TODO: option for ignoring functions matching some pattern ('..._test_'/0)
%% TODO: @private_type tag, opaque unless generating private docs?
%% TODO: document the record type syntax
-%% TODO: some 'skip' option for ignoring particular modules/packages?
-%% TODO: intermediate-level packages: document even if no local sources.
+%% TODO: some 'skip' option for ignoring particular modules?
%% TODO: multiline comment support (needs modified comment representation)
%% TODO: config-file for default settings
%% TODO: config: locations of all local docdirs; generate local doc-index page
-%% TODO: config: URL:s of offline packages/apps
+%% TODO: config: URL:s of offline apps
%% TODO: config: default stylesheet
%% TODO: config: default header/footer, etc.
%% TODO: offline linkage
@@ -45,10 +44,10 @@
-module(edoc).
--export([packages/1, packages/2, files/1, files/2,
+-export([files/1, files/2,
application/1, application/2, application/3,
toc/1, toc/2, toc/3,
- run/3,
+ run/2,
file/1, file/2,
read/1, read/2,
layout/1, layout/2,
@@ -68,15 +67,15 @@
file(Name) ->
file(Name, []).
-%% @spec file(filename(), proplist()) -> ok
+%% @spec file(filename(), proplist()) -> ok
%%
%% @type filename() = //kernel/file:filename()
%% @type proplist() = [term()]
%%
%% @deprecated This is part of the old interface to EDoc and is mainly
%% kept for backwards compatibility. The preferred way of generating
-%% documentation is through one of the functions {@link application/2},
-%% {@link packages/2} and {@link files/2}.
+%% documentation is through one of the functions {@link application/2}
+%% and {@link files/2}.
%%
%% @doc Reads a source code file and outputs formatted documentation to
%% a corresponding file.
@@ -121,44 +120,24 @@ file(Name, Options) ->
?DEFAULT_FILE_SUFFIX),
Dir = proplists:get_value(dir, Options, filename:dirname(Name)),
Encoding = [{encoding, edoc_lib:read_encoding(Name, [])}],
- edoc_lib:write_file(Text, Dir, BaseName ++ Suffix, '', Encoding).
+ edoc_lib:write_file(Text, Dir, BaseName ++ Suffix, Encoding).
-%% TODO: better documentation of files/1/2, packages/1/2, application/1/2/3
+%% TODO: better documentation of files/1/2, application/1/2/3
-%% @spec (Files::[filename() | {package(), [filename()]}]) -> ok
-%% @equiv packages(Packages, [])
+%% @spec (Files::[filename()]) -> ok
files(Files) ->
files(Files, []).
-%% @spec (Files::[filename() | {package(), [filename()]}],
+%% @spec (Files::[filename()],
%% Options::proplist()) -> ok
-%% @doc Runs EDoc on a given set of source files. See {@link run/3} for
+%% @doc Runs EDoc on a given set of source files. See {@link run/2} for
%% details, including options.
%% @equiv run([], Files, Options)
files(Files, Options) ->
- run([], Files, Options).
-
-%% @spec (Packages::[package()]) -> ok
-%% @equiv packages(Packages, [])
-
-packages(Packages) ->
- packages(Packages, []).
-
-%% @spec (Packages::[package()], Options::proplist()) -> ok
-%% @type package() = atom() | string()
-%%
-%% @doc Runs EDoc on a set of packages. The `source_path' option is used
-%% to locate the files; see {@link run/3} for details, including
-%% options. This function automatically appends the current directory to
-%% the source path.
-%%
-%% @equiv run(Packages, [], Options)
-
-packages(Packages, Options) ->
- run(Packages, [], Options ++ [{source_path, [?CURRENT_DIR]}]).
+ run(Files, Options).
%% @spec (Application::atom()) -> ok
%% @equiv application(Application, [])
@@ -194,7 +173,7 @@ application(App, Options) when is_atom(App) ->
%% subdirectory, if it exists, or otherwise in the application
%% directory itself.
%% </li>
-%% <li>The {@link run/3. `subpackages'} option is turned on. All found
+%% <li>The {@link run/2. `subpackages'} option is turned on. All found
%% source files will be processed.
%% </li>
%% <li>The `include' subdirectory is automatically added to the
@@ -203,7 +182,7 @@ application(App, Options) when is_atom(App) ->
%% </li>
%% </ul>
%%
-%% See {@link run/3} for details, including options.
+%% See {@link run/2} for details, including options.
%%
%% @see application/2
@@ -219,7 +198,7 @@ application(App, Dir, Options) when is_atom(App) ->
{includes, [filename:join(Dir, "include")]}],
Opts1 = set_app_default(App, Dir, Opts),
%% Recursively document all subpackages of '' - i.e., everything.
- run([''], [], [{application, App} | Opts1]).
+ run([], [{application, App} | Opts1]).
%% Try to set up a default application base URI in a smart way if the
%% user has not specified it explicitly.
@@ -240,31 +219,20 @@ set_app_default(App, Dir0, Opts) ->
Opts
end.
-%% If no source files are found for a (specified) package, no package
-%% documentation will be generated either (even if there is a
-%% package-documentation file). This is the way it should be. For
-%% specified files, use empty package (unless otherwise specified). The
-%% assumed package is always used for creating the output. If the actual
-%% module or package of the source differs from the assumption gathered
-%% from the path and file name, a warning should be issued (since links
-%% are likely to be incorrect).
-
opt_defaults() ->
- [packages].
+ [].
opt_negations() ->
[{no_preprocess, preprocess},
{no_subpackages, subpackages},
- {no_report_missing_types, report_missing_types},
- {no_packages, packages}].
+ {no_report_missing_types, report_missing_types}].
-%% @spec run(Packages::[package()],
-%% Files::[filename() | {package(), [filename()]}],
+%% @spec run(Files::[filename()],
%% Options::proplist()) -> ok
-%% @doc Runs EDoc on a given set of source files and/or packages. Note
+%% @doc Runs EDoc on a given set of source files. Note
%% that the doclet plugin module has its own particular options; see the
%% `doclet' option below.
-%%
+%%
%% Also see {@link layout/2} for layout-related options, and
%% {@link get_doc/2} for options related to reading source
%% files.
@@ -298,11 +266,6 @@ opt_negations() ->
%% The default doclet module is {@link edoc_doclet}; see {@link
%% edoc_doclet:run/2} for doclet-specific options.
%% </dd>
-%% <dt>{@type {exclude_packages, [package()]@}}
-%% </dt>
-%% <dd>Lists packages to be excluded from the documentation. Typically
-%% used in conjunction with the `subpackages' option.
-%% </dd>
%% <dt>{@type {file_suffix, string()@}}
%% </dt>
%% <dd>Specifies the suffix used for output files. The default value is
@@ -314,22 +277,6 @@ opt_negations() ->
%% target directory will be ignored and overwritten. The default
%% value is `false'.
%% </dd>
-%% <dt>{@type {packages, boolean()@}}
-%% </dt>
-%% <dd>If the value is `true', it it assumed that packages (module
-%% namespaces) are being used, and that the source code directory
-%% structure reflects this. The default value is `true'. (Usually,
-%% this does the right thing even if all the modules belong to the
-%% top-level "empty" package.) `no_packages' is an alias for
-%% `{packages, false}'. See the `subpackages' option below for
-%% further details.
-%%
-%% If the source code is organized in a hierarchy of
-%% subdirectories although it does not use packages, use
-%% `no_packages' together with the recursive-search `subpackages'
-%% option (on by default) to automatically generate documentation
-%% for all the modules.
-%% </dd>
%% <dt>{@type {source_path, [filename()]@}}
%% </dt>
%% <dd>Specifies a list of file system paths used to locate the source
@@ -345,7 +292,7 @@ opt_negations() ->
%% <dd>If the value is `true', all subpackages of specified packages
%% will also be included in the documentation. The default value is
%% `false'. `no_subpackages' is an alias for `{subpackages,
-%% false}'. See also the `exclude_packages' option.
+%% false}'.
%%
%% Subpackage source files are found by recursively searching
%% for source code files in subdirectories of the known source code
@@ -358,38 +305,31 @@ opt_negations() ->
%% </dl>
%%
%% @see files/2
-%% @see packages/2
%% @see application/2
%% NEW-OPTIONS: source_path, application
%% INHERIT-OPTIONS: init_context/1
%% INHERIT-OPTIONS: expand_sources/2
%% INHERIT-OPTIONS: target_dir_info/5
-%% INHERIT-OPTIONS: edoc_lib:find_sources/3
+%% INHERIT-OPTIONS: edoc_lib:find_sources/2
%% INHERIT-OPTIONS: edoc_lib:run_doclet/2
-%% INHERIT-OPTIONS: edoc_lib:get_doc_env/4
+%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3
-run(Packages, Files, Opts0) ->
+run(Files, Opts0) ->
Opts = expand_opts(Opts0),
Ctxt = init_context(Opts),
Dir = Ctxt#context.dir,
Path = proplists:append_values(source_path, Opts),
- Ss = sources(Path, Packages, Opts),
+ Ss = sources(Path, Opts),
{Ss1, Ms} = expand_sources(expand_files(Files) ++ Ss, Opts),
- Ps = [P || {_, P, _, _} <- Ss1],
App = proplists:get_value(application, Opts, ?NO_APP),
- {App1, Ps1, Ms1} = target_dir_info(Dir, App, Ps, Ms, Opts),
- %% The "empty package" is never included in the list of packages.
- Ps2 = edoc_lib:unique(lists:sort(Ps1)) -- [''],
+ {App1, Ms1} = target_dir_info(Dir, App, Ms, Opts),
Ms2 = edoc_lib:unique(lists:sort(Ms1)),
- Fs = package_files(Path, Ps2),
- Env = edoc_lib:get_doc_env(App1, Ps2, Ms2, Opts),
+ Env = edoc_lib:get_doc_env(App1, Ms2, Opts),
Ctxt1 = Ctxt#context{env = Env},
Cmd = #doclet_gen{sources = Ss1,
app = App1,
- packages = Ps2,
- modules = Ms2,
- filemap = Fs
+ modules = Ms2
},
F = fun (M) ->
M:run(Cmd, Ctxt1)
@@ -401,42 +341,22 @@ expand_opts(Opts0) ->
Opts0 ++ opt_defaults()).
%% NEW-OPTIONS: dir
-%% DEFER-OPTIONS: run/3
+%% DEFER-OPTIONS: run/2
init_context(Opts) ->
#context{dir = proplists:get_value(dir, Opts, ?CURRENT_DIR),
opts = Opts
}.
-%% INHERIT-OPTIONS: edoc_lib:find_sources/3
-
-sources(Path, Packages, Opts) ->
- lists:foldl(fun (P, Xs) ->
- edoc_lib:find_sources(Path, P, Opts) ++ Xs
- end,
- [], Packages).
-
-package_files(Path, Packages) ->
- Name = ?PACKAGE_FILE, % this is hard-coded for now
- D = lists:foldl(fun (P, D) ->
- F = edoc_lib:find_file(Path, P, Name),
- dict:store(P, F, D)
- end,
- dict:new(), Packages),
- fun (P) ->
- case dict:find(P, D) of
- {ok, F} -> F;
- error -> ""
- end
- end.
+%% INHERIT-OPTIONS: edoc_lib:find_sources/2
+
+sources(Path, Opts) ->
+ edoc_lib:find_sources(Path, Opts).
%% Expand user-specified sets of files.
-expand_files([{P, Fs1} | Fs]) ->
- [{P, filename:basename(F), filename:dirname(F)} || F <- Fs1]
- ++ expand_files(Fs);
expand_files([F | Fs]) ->
- [{'', filename:basename(F), filename:dirname(F)} |
+ [{filename:basename(F), filename:dirname(F)} |
expand_files(Fs)];
expand_files([]) ->
[].
@@ -444,26 +364,23 @@ expand_files([]) ->
%% Create the (assumed) full module names. Keep only the first source
%% for each module, but preserve the order of the list.
-%% NEW-OPTIONS: source_suffix, packages
-%% DEFER-OPTIONS: run/3
+%% NEW-OPTIONS: source_suffix
+%% DEFER-OPTIONS: run/2
expand_sources(Ss, Opts) ->
Suffix = proplists:get_value(source_suffix, Opts,
?DEFAULT_SOURCE_SUFFIX),
- Ss1 = case proplists:get_bool(packages, Opts) of
- true -> Ss;
- false -> [{'',F,D} || {_P,F,D} <- Ss]
- end,
+ Ss1 = [{F,D} || {F,D} <- Ss],
expand_sources(Ss1, Suffix, sets:new(), [], []).
-expand_sources([{'', F, D} | Fs], Suffix, S, As, Ms) ->
+expand_sources([{F, D} | Fs], Suffix, S, As, Ms) ->
M = list_to_atom(filename:rootname(F, Suffix)),
case sets:is_element(M, S) of
true ->
expand_sources(Fs, Suffix, S, As, Ms);
false ->
S1 = sets:add_element(M, S),
- expand_sources(Fs, Suffix, S1, [{M, '', F, D} | As],
+ expand_sources(Fs, Suffix, S1, [{M, F, D} | As],
[M | Ms])
end;
expand_sources([], _Suffix, _S, As, Ms) ->
@@ -471,16 +388,15 @@ expand_sources([], _Suffix, _S, As, Ms) ->
%% NEW-OPTIONS: new
-target_dir_info(Dir, App, Ps, Ms, Opts) ->
+target_dir_info(Dir, App, Ms, Opts) ->
case proplists:get_bool(new, Opts) of
true ->
- {App, Ps, Ms};
+ {App, Ms};
false ->
- {App1, Ps1, Ms1} = edoc_lib:read_info_file(Dir),
+ {App1, Ms1} = edoc_lib:read_info_file(Dir),
{if App == ?NO_APP -> App1;
true -> App
end,
- Ps ++ Ps1,
Ms ++ Ms1}
end.
@@ -505,12 +421,12 @@ toc(Dir, Opts) ->
%% INHERIT-OPTIONS: init_context/1
%% INHERIT-OPTIONS: edoc_lib:run_doclet/2
-%% INHERIT-OPTIONS: edoc_lib:get_doc_env/4
+%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3
toc(Dir, Paths, Opts0) ->
Opts = expand_opts(Opts0 ++ [{dir, Dir}]),
Ctxt = init_context(Opts),
- Env = edoc_lib:get_doc_env('', [], [], Opts),
+ Env = edoc_lib:get_doc_env('', [], Opts),
Ctxt1 = Ctxt#context{env = Env},
F = fun (M) ->
M:run(#doclet_toc{paths=Paths}, Ctxt1)
@@ -562,7 +478,7 @@ layout(Doc) ->
%% </dl>
%%
%% @see layout/1
-%% @see run/3
+%% @see run/2
%% @see read/2
%% @see file/2
@@ -639,7 +555,6 @@ read_source(Name) ->
%% <dd>Specifies a list of pre-defined Erlang preprocessor (`epp')
%% macro definitions, used if the `preprocess' option is turned on.
%% The default value is the empty list.</dd>
-%% </dl>
%% <dt>{@type {report_missing_types, boolean()@}}
%% </dt>
%% <dd>If the value is `true', warnings are issued for missing types.
@@ -647,6 +562,7 @@ read_source(Name) ->
%% `no_report_missing_types' is an alias for
%% `{report_missing_types, false}'.
%% </dd>
+%% </dl>
%%
%% @see get_doc/2
%% @see //syntax_tools/erl_syntax
@@ -773,13 +689,12 @@ scan_and_parse(Epp) ->
fix_last_line(Toks0) ->
Toks1 = lists:reverse(Toks0),
- {line, LastLine} = erl_scan:token_info(hd(Toks1), line),
+ LastLine = erl_scan:line(hd(Toks1)),
fll(Toks1, LastLine, []).
-fll([{Category, Attributes0, Symbol} | L], LastLine, Ts) ->
- F = fun(_OldLine) -> LastLine end,
- Attributes = erl_scan:set_attribute(line, Attributes0, F),
- lists:reverse(L, [{Category, Attributes, Symbol} | Ts]);
+fll([{Category, Anno0, Symbol} | L], LastLine, Ts) ->
+ Anno = erl_anno:set_line(LastLine, Anno0),
+ lists:reverse(L, [{Category, Anno, Symbol} | Ts]);
fll([T | L], LastLine, Ts) ->
fll(L, LastLine, [T | Ts]);
fll(L, _LastLine, Ts) ->
@@ -853,16 +768,16 @@ get_doc(File) ->
%% </dl>
%%
%% See {@link read_source/2}, {@link read_comments/2} and {@link
-%% edoc_lib:get_doc_env/4} for further options.
+%% edoc_lib:get_doc_env/3} for further options.
%%
%% @see get_doc/3
-%% @see run/3
+%% @see run/2
%% @see edoc_extract:source/5
%% @see read/2
%% @see layout/2
%% INHERIT-OPTIONS: get_doc/3
-%% INHERIT-OPTIONS: edoc_lib:get_doc_env/4
+%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3
get_doc(File, Opts) ->
Env = edoc_lib:get_doc_env(Opts),
@@ -874,7 +789,7 @@ get_doc(File, Opts) ->
%%
%% @doc Like {@link get_doc/2}, but for a given environment
%% parameter. `Env' is an environment created by {@link
-%% edoc_lib:get_doc_env/4}.
+%% edoc_lib:get_doc_env/3}.
%% INHERIT-OPTIONS: read_source/2, read_comments/2, edoc_extract:source/5
%% DEFER-OPTIONS: get_doc/2
diff --git a/lib/edoc/src/edoc.hrl b/lib/edoc/src/edoc.hrl
index 44c5d6fef4..5b0fb68cf9 100644
--- a/lib/edoc/src/edoc.hrl
+++ b/lib/edoc/src/edoc.hrl
@@ -1,6 +1,6 @@
%% =====================================================================
%% Header file for EDoc
-%%
+%%
%% Copyright (C) 2001-2004 Richard Carlsson
%%
%% This library is free software; you can redistribute it and/or modify
@@ -25,9 +25,7 @@
-define(APPLICATION, edoc).
-define(INFO_FILE, "edoc-info").
--define(PACKAGE_FILE, "package.edoc").
-define(OVERVIEW_FILE, "overview.edoc").
--define(PACKAGE_SUMMARY, "package-summary").
-define(DEFAULT_SOURCE_SUFFIX, ".erl").
-define(DEFAULT_FILE_SUFFIX, ".html").
-define(DEFAULT_DOCLET, edoc_doclet).
@@ -65,13 +63,10 @@
%% Environment for generating documentation data
-record(env, {module = [],
- package = [],
root = "",
file_suffix,
- package_summary,
apps,
modules,
- packages,
app_default,
macros = [],
includes = []
diff --git a/lib/edoc/src/edoc_data.erl b/lib/edoc/src/edoc_data.erl
index f88ba05f4b..b797d74a71 100644
--- a/lib/edoc/src/edoc_data.erl
+++ b/lib/edoc/src/edoc_data.erl
@@ -26,7 +26,7 @@
-module(edoc_data).
--export([module/4, package/4, overview/4, type/2]).
+-export([module/4, overview/4, type/2]).
-export([hidden_filter/2, get_all_tags/1]).
@@ -173,21 +173,34 @@ callbacks(Es, Module, Env, Opts) ->
lists:keymember(callback, 1, Module#module.attributes)
of
true ->
- try (Module#module.name):behaviour_info(callbacks) of
- Fs ->
- Fs1 = [{F,A} || {F,A} <- Fs, is_atom(F), is_integer(A)],
- if Fs1 =:= [] ->
- [];
- true ->
- [{callbacks,
- [callback(F, Env, Opts) || F <- Fs1]}]
- end
- catch
- _:_ -> []
- end;
+ M = Module#module.name,
+ Fs = get_callback_functions(M, callbacks),
+ Os1 = get_callback_functions(M, optional_callbacks),
+ Fs1 = [FA || FA <- Fs, not lists:member(FA, Os1)],
+ Req = if Fs1 =:= [] ->
+ [];
+ true ->
+ [{callbacks,
+ [callback(FA, Env, Opts) || FA <- Fs1]}]
+ end,
+ Opt = if Os1 =:= [] ->
+ [];
+ true ->
+ [{optional_callbacks,
+ [callback(FA, Env, Opts) || FA <- Os1]}]
+ end,
+ Req ++ Opt;
false -> []
end.
+get_callback_functions(M, Callbacks) ->
+ try
+ [FA || {F, A} = FA <- M:behaviour_info(Callbacks),
+ is_atom(F), is_integer(A), A >= 0]
+ catch
+ _:_ -> []
+ end.
+
%% <!ELEMENT callback EMPTY>
%% <!ATTLIST callback
%% name CDATA #REQUIRED
@@ -497,41 +510,14 @@ get_tags(_, []) -> [].
type(T, Env) ->
xmerl_lib:expand_element({type, [edoc_types:to_xml(T, Env)]}).
-%% <!ELEMENT package (description?, author*, copyright?, version?,
-%% since?, deprecated?, see*, reference*, todo?,
-%% modules)>
-%% <!ATTLIST package
-%% name CDATA #REQUIRED
-%% root CDATA #IMPLIED>
-%% <!ELEMENT modules (module+)>
-
-package(Package, Tags, Env, Opts) ->
- Env1 = Env#env{package = Package,
- root = edoc_refs:relative_package_path('', Package)},
- xmerl_lib:expand_element(package_1(Package, Tags, Env1, Opts)).
-
-package_1(Package, Tags, Env, Opts) ->
- {package, [{root, Env#env.root}],
- ([{packageName, [atom_to_list(Package)]}]
- ++ get_doc(Tags)
- ++ authors(Tags)
- ++ get_copyright(Tags)
- ++ get_version(Tags)
- ++ get_since(Tags)
- ++ get_deprecated(Tags)
- ++ sees(Tags, Env)
- ++ references(Tags)
- ++ todos(Tags, Opts))
- }.
-
%% <!ELEMENT overview (title, description?, author*, copyright?, version?,
-%% since?, see*, reference*, todo?, packages, modules)>
+%% since?, see*, reference*, todo?, modules)>
%% <!ATTLIST overview
%% root CDATA #IMPLIED>
%% <!ELEMENT title (#PCDATA)>
overview(Title, Tags, Env, Opts) ->
- Env1 = Env#env{package = '',
+ Env1 = Env#env{
root = ""},
xmerl_lib:expand_element(overview_1(Title, Tags, Env1, Opts)).
diff --git a/lib/edoc/src/edoc_doclet.erl b/lib/edoc/src/edoc_doclet.erl
index 5653b5894b..5961ca8cc0 100644
--- a/lib/edoc/src/edoc_doclet.erl
+++ b/lib/edoc/src/edoc_doclet.erl
@@ -42,9 +42,7 @@
-define(DEFAULT_FILE_SUFFIX, ".html").
-define(INDEX_FILE, "index.html").
-define(OVERVIEW_FILE, "overview.edoc").
--define(PACKAGE_SUMMARY, "package-summary.html").
-define(OVERVIEW_SUMMARY, "overview-summary.html").
--define(PACKAGES_FRAME, "packages-frame.html").
-define(MODULES_FRAME, "modules-frame.html").
-define(STYLESHEET, "stylesheet.css").
-define(IMAGE, "erlang.png").
@@ -52,11 +50,10 @@
-include_lib("xmerl/include/xmerl.hrl").
-%% Sources is the list of inputs in the order they were found. Packages
-%% and Modules are sorted lists of atoms without duplicates. (They
+%% Sources is the list of inputs in the order they were found.
+%% Modules are sorted lists of atoms without duplicates. (They
%% usually include the data from the edoc-info file in the target
-%% directory, if it exists.) Note that the "empty package" is never
-%% included in Packages!
+%% directory, if it exists.)
%% @spec (Command::doclet_gen() | doclet_toc(), edoc_context()) -> ok
%% @doc Main doclet entry point. See the file <a
@@ -117,14 +114,12 @@
run(#doclet_gen{}=Cmd, Ctxt) ->
gen(Cmd#doclet_gen.sources,
Cmd#doclet_gen.app,
- Cmd#doclet_gen.packages,
Cmd#doclet_gen.modules,
- Cmd#doclet_gen.filemap,
Ctxt);
run(#doclet_toc{}=Cmd, Ctxt) ->
toc(Cmd#doclet_toc.paths, Ctxt).
-gen(Sources, App, Packages, Modules, FileMap, Ctxt) ->
+gen(Sources, App, Modules, Ctxt) ->
Dir = Ctxt#context.dir,
Env = Ctxt#context.env,
Options = Ctxt#context.opts,
@@ -132,11 +127,9 @@ gen(Sources, App, Packages, Modules, FileMap, Ctxt) ->
CSS = stylesheet(Options),
{Modules1, Error} = sources(Sources, Dir, Modules, Env, Options),
modules_frame(Dir, Modules1, Title, CSS),
- packages(Packages, Dir, FileMap, Env, Options),
- packages_frame(Dir, Packages, Title, CSS),
overview(Dir, Title, Env, Options),
- index_file(Dir, length(Packages) > 1, Title),
- edoc_lib:write_info_file(App, Packages, Modules1, Dir),
+ index_file(Dir, Title),
+ edoc_lib:write_info_file(App, Modules1, Dir),
copy_stylesheet(Dir, Options),
copy_image(Dir),
%% handle postponed error during processing of source files
@@ -182,19 +175,19 @@ sources(Sources, Dir, Modules, Env, Options) ->
%% set if it was successful. Errors are just flagged at this stage,
%% allowing all source files to be processed even if some of them fail.
-source({M, P, Name, Path}, Dir, Suffix, Env, Set, Private, Hidden,
+source({M, Name, Path}, Dir, Suffix, Env, Set, Private, Hidden,
Error, Options) ->
File = filename:join(Path, Name),
case catch {ok, edoc:get_doc(File, Env, Options)} of
{ok, {Module, Doc}} ->
- check_name(Module, M, P, File),
+ check_name(Module, M, File),
case ((not is_private(Doc)) orelse Private)
andalso ((not is_hidden(Doc)) orelse Hidden) of
true ->
Text = edoc:layout(Doc, Options),
Name1 = atom_to_list(M) ++ Suffix,
Encoding = [{encoding,encoding(Doc)}],
- edoc_lib:write_file(Text, Dir, Name1, P, Encoding),
+ edoc_lib:write_file(Text, Dir, Name1, Encoding),
{sets:add_element(Module, Set), Error};
false ->
{Set, Error}
@@ -204,8 +197,7 @@ source({M, P, Name, Path}, Dir, Suffix, Env, Set, Private, Hidden,
{Set, true}
end.
-check_name(M, M0, P0, File) ->
- P = '',
+check_name(M, M0, File) ->
N = M,
N0 = M0,
case N of
@@ -222,47 +214,12 @@ check_name(M, M0, P0, File) ->
ok
end
end,
- if P =/= P0 ->
- warning("file '~ts' belongs to package '~s', not '~s'.",
- [File, P, P0]);
- true ->
- ok
- end.
-
-
-%% Generating the summary files for packages.
-
-%% INHERIT-OPTIONS: read_file/4
-%% INHERIT-OPTIONS: edoc_lib:run_layout/2
-
-packages(Packages, Dir, FileMap, Env, Options) ->
- lists:foreach(fun (P) ->
- package(P, Dir, FileMap, Env, Options)
- end,
- Packages).
-
-package(P, Dir, FileMap, Env, Opts) ->
- Tags = case FileMap(P) of
- "" ->
- [];
- File ->
- read_file(File, package, Env, Opts)
- end,
- Data = edoc_data:package(P, Tags, Env, Opts),
- F = fun (M) ->
- M:package(Data, Opts)
- end,
- Text = edoc_lib:run_layout(F, Opts),
- edoc_lib:write_file(Text, Dir, ?PACKAGE_SUMMARY, P).
-
+ ok.
%% Creating an index file, with some frames optional.
%% TODO: get rid of frames, or change doctype to Frameset
-index_file(Dir, Packages, Title) ->
- Frame1 = {frame, [{src,?PACKAGES_FRAME},
- {name,"packagesFrame"},{title,""}],
- []},
+index_file(Dir, Title) ->
Frame2 = {frame, [{src,?MODULES_FRAME},
{name,"modulesFrame"},{title,""}],
[]},
@@ -270,16 +227,7 @@ index_file(Dir, Packages, Title) ->
{name,"overviewFrame"},{title,""}],
[]},
Frameset = {frameset, [{cols,"20%,80%"}],
- case Packages of
- true ->
- [?NL,
- {frameset, [{rows,"30%,70%"}],
- [?NL, Frame1, ?NL, Frame2, ?NL]}
- ];
- false ->
- [?NL, Frame2, ?NL]
- end
- ++ [?NL, Frame3, ?NL,
+ [?NL, Frame2, ?NL, ?NL, Frame3, ?NL,
{noframes,
[?NL,
{h2, ["This page uses frames"]},
@@ -296,24 +244,6 @@ index_file(Dir, Packages, Title) ->
Text = xmerl:export_simple([XML], xmerl_html, []),
edoc_lib:write_file(Text, Dir, ?INDEX_FILE).
-packages_frame(Dir, Ps, Title, CSS) ->
- Body = [?NL,
- {h2, [{class, "indextitle"}], ["Packages"]},
- ?NL,
- {table, [{width, "100%"}, {border, 0},
- {summary, "list of packages"}],
- lists:concat(
- [[?NL,
- {tr, [{td, [], [{a, [{href, package_ref(P)},
- {target,"overviewFrame"},
- {class, "package"}],
- [atom_to_list(P)]}]}]}]
- || P <- Ps])},
- ?NL],
- XML = xhtml(Title, CSS, Body),
- Text = xmerl:export_simple([XML], xmerl_html, []),
- edoc_lib:write_file(Text, Dir, ?PACKAGES_FRAME).
-
modules_frame(Dir, Ms, Title, CSS) ->
Body = [?NL,
{h2, [{class, "indextitle"}], ["Modules"]},
@@ -334,11 +264,7 @@ modules_frame(Dir, Ms, Title, CSS) ->
edoc_lib:write_file(Text, Dir, ?MODULES_FRAME).
module_ref(M) ->
- edoc_refs:relative_package_path(M, '') ++ ?DEFAULT_FILE_SUFFIX.
-
-package_ref(P) ->
- edoc_lib:join_uri(edoc_refs:relative_package_path(P, ''),
- ?PACKAGE_SUMMARY).
+ atom_to_list(M) ++ ?DEFAULT_FILE_SUFFIX.
xhtml(Title, CSS, Content) ->
xhtml_1(Title, CSS, {body, [{bgcolor, "white"}], Content}).
@@ -372,7 +298,7 @@ overview(Dir, Title, Env, Opts) ->
end,
Text = edoc_lib:run_layout(F, Opts),
EncOpts = [{encoding,Encoding}],
- edoc_lib:write_file(Text, Dir, ?OVERVIEW_SUMMARY, '', EncOpts).
+ edoc_lib:write_file(Text, Dir, ?OVERVIEW_SUMMARY, EncOpts).
copy_image(Dir) ->
case code:priv_dir(?EDOC_APP) of
@@ -505,7 +431,7 @@ app_index_file(Paths, Dir, Env, Options) ->
% Priv = proplists:get_bool(private, Options),
CSS = stylesheet(Options),
Apps1 = [{filename:dirname(A),filename:basename(A)} || A <- Paths],
- index_file(Dir, false, Title),
+ index_file(Dir, Title),
application_frame(Dir, Apps1, Title, CSS),
modules_frame(Dir, [], Title, CSS),
overview(Dir, Title, Env, Options),
diff --git a/lib/edoc/src/edoc_extract.erl b/lib/edoc/src/edoc_extract.erl
index 67a95e80aa..758750083d 100644
--- a/lib/edoc/src/edoc_extract.erl
+++ b/lib/edoc/src/edoc_extract.erl
@@ -91,7 +91,7 @@ source(Forms, Comments, File, Env, Opts) ->
%% type `form_list', or a list of syntax trees representing
%% "program forms" (cf. {@link edoc:read_source/2}.
%% `Env' is an environment created by {@link
-%% edoc_lib:get_doc_env/4}. The `File' argument is used for
+%% edoc_lib:get_doc_env/3}. The `File' argument is used for
%% error reporting and output file name generation only.
%%
%% See {@link edoc:get_doc/2} for descriptions of the `def',
@@ -121,10 +121,8 @@ source1(Tree, File0, Env, Opts, TypeDocs) ->
Module = get_module_info(Tree, File),
{Header, Footer, Entries} = collect(Forms, Module),
Name = Module#module.name,
- Package = '',
Env1 = Env#env{module = Name,
- package = Package,
- root = edoc_refs:relative_package_path('', Package)},
+ root = ""},
Env2 = add_macro_defs(module_macros(Env1), Opts, Env1),
Entries1 = get_tags([Header, Footer | Entries], Env2, File, TypeDocs),
Entries2 = edoc_specs:add_data(Entries1, Opts, File, Module),
@@ -218,13 +216,13 @@ add_macro_defs(Defs0, Opts, Env) ->
%% @spec file(File::filename(), Context, Env::edoc_env(),
%% Options::proplist()) -> {ok, Tags} | {error, Reason}
-%% Context = overview | package
+%% Context = overview
%% Tags = [term()]
%% Reason = term()
%%
%% @doc Reads a text file and returns the list of tags in the file. Any
%% lines of text before the first tag are ignored. `Env' is an
-%% environment created by {@link edoc_lib:get_doc_env/4}. Upon error,
+%% environment created by {@link edoc_lib:get_doc_env/3}. Upon error,
%% `Reason' is an atom returned from the call to {@link
%% //kernel/file:read_file/1} or the atom 'invalid_unicode'.
%%
@@ -249,12 +247,12 @@ file(File, Context, Env, Opts) ->
%% @spec (Text::string(), Context, Env::edoc_env(),
%% Options::proplist()) -> Tags
-%% Context = overview | package
+%% Context = overview
%% Tags = [term()]
%%
%% @doc Returns the list of tags in the text. Any lines of text before
%% the first tag are ignored. `Env' is an environment created by {@link
-%% edoc_lib:get_doc_env/4}.
+%% edoc_lib:get_doc_env/3}.
%%
%% See {@link source/4} for a description of the `def' option.
@@ -353,8 +351,6 @@ preprocess_forms_2(F, Fs) ->
[F | preprocess_forms_1(Fs)];
{function, _} ->
[F | preprocess_forms_1(Fs)];
- {rule, _} ->
- [F | preprocess_forms_1(Fs)];
{attribute, {module, _}} ->
[F | preprocess_forms_1(Fs)];
text ->
@@ -392,15 +388,6 @@ collect([F | Fs], Cs, Ss, Ts, As, Header, Mod) ->
export = Export,
data = {comment_text(Cs),Ss,Ts}} | As],
Header, Mod);
- {rule, Name} ->
- L = erl_syntax:get_pos(F),
- Export = ordsets:is_element(Name, Mod#module.exports),
- Args = parameters(erl_syntax:rule_clauses(F)),
- collect(Fs, [], [], [],
- [#entry{name = Name, args = Args, line = L,
- export = Export,
- data = {comment_text(Cs),Ss,Ts}} | As],
- Header, Mod);
{attribute, {module, _}} when Header =:= undefined ->
L = erl_syntax:get_pos(F),
collect(Fs, [], [], [], As,
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index a102d432bc..f723cd8373 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -27,7 +27,7 @@
-module(edoc_layout).
--export([module/2, package/2, overview/2, type/1]).
+-export([module/2, overview/2, type/1]).
-import(edoc_report, [report/2]).
@@ -180,7 +180,9 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) ->
FullDesc = get_content(fullDescription, Desc),
Functions = [{function_name(E), E} || E <- get_content(functions, Es)],
Types = [{type_name(E), E} || E <- get_content(typedecls, Es)],
- SortedFs = lists:sort(Functions),
+ SortedFs = if Opts#opts.sort_functions -> lists:sort(Functions);
+ true -> Functions
+ end,
Body = (navigation("top")
++ [?NL, hr, ?NL, ?NL, {h1, Title}, ?NL]
++ doc_index(FullDesc, Functions, Types)
@@ -204,9 +206,7 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) ->
end
++ types(lists:sort(Types), Opts)
++ function_index(SortedFs, Opts#opts.index_columns)
- ++ if Opts#opts.sort_functions -> functions(SortedFs, Opts);
- true -> functions(Functions, Opts)
- end
+ ++ functions(SortedFs, Opts)
++ [hr, ?NL]
++ navigation("bottom")
++ timestamp()),
@@ -520,7 +520,7 @@ format_spec(Name, Type, Defs, #opts{pretty_printer = erl_pp}=Opts) ->
{R, ".\n"} = etypef(L, O),
[{pre, R}]
catch _:_ ->
- %% Example: "@spec ... -> record(a)"
+ %% Should not happen.
format_spec(Name, Type, Defs, Opts#opts{pretty_printer=''})
end;
format_spec(Sep, Type, Defs, _Opts) ->
@@ -535,7 +535,8 @@ t_clause(Name, Type) ->
pp_clause(Pre, Type) ->
Types = ot_utype([Type]),
Atom = lists:duplicate(iolist_size(Pre), $a),
- L1 = erl_pp:attribute({attribute,0,spec,{{list_to_atom(Atom),0},[Types]}}),
+ Attr = {attribute,0,spec,{{list_to_atom(Atom),0},[Types]}},
+ L1 = erl_pp:attribute(erl_parse:new_anno(Attr)),
"-spec " ++ L2 = lists:flatten(L1),
L3 = Pre ++ lists:nthtail(length(Atom), L2),
re:replace(L3, "\n ", "\n", [{return,list},global]).
@@ -555,7 +556,8 @@ format_type(Prefix, _Name, Type, Last, _Opts) ->
pp_type(Prefix, Type) ->
Atom = list_to_atom(lists:duplicate(iolist_size(Prefix), $a)),
- L1 = erl_pp:attribute({attribute,0,type,{Atom,ot_utype(Type),[]}}),
+ Attr = {attribute,0,type,{Atom,ot_utype(Type),[]}},
+ L1 = erl_pp:attribute(erl_parse:new_anno(Attr)),
{L2,N} = case lists:dropwhile(fun(C) -> C =/= $: end, lists:flatten(L1)) of
":: " ++ L3 -> {L3,9}; % compensation for extra "()" and ":"
"::\n" ++ L3 -> {"\n"++L3,6}
@@ -701,6 +703,8 @@ deprecated(Es, S) ->
end.
behaviours(Es, Name) ->
+ CBs = get_content(callbacks, Es),
+ OCBs = get_content(optional_callbacks, Es),
(case get_elem(behaviour, Es) of
[] -> [];
Es1 ->
@@ -709,13 +713,24 @@ behaviours(Es, Name) ->
?NL]
end
++
- case get_content(callbacks, Es) of
- [] -> [];
- Es1 ->
+ if CBs =:= [], OCBs =:= [] ->
+ [];
+ true ->
+ Req = if CBs =:= [] ->
+ [];
+ true ->
+ [br, " Required callback functions: "]
+ ++ seq(fun callback/1, CBs, ["."])
+ end,
+ Opt = if OCBs =:= [] ->
+ [];
+ true ->
+ [br, " Optional callback functions: "]
+ ++ seq(fun callback/1, OCBs, ["."])
+ end,
[{p, ([{b, ["This module defines the ", {tt, [Name]},
- " behaviour."]},
- br, " Required callback functions: "]
- ++ seq(fun callback/1, Es1, ["."]))},
+ " behaviour."]}]
+ ++ Req ++ Opt)},
?NL]
end).
@@ -965,9 +980,6 @@ get_text(Name, Es) ->
local_label(R) ->
"#" ++ R.
-xhtml(Title, CSS, Body) ->
- xhtml(Title, CSS, Body, "latin1").
-
xhtml(Title, CSS, Body, Encoding) ->
EncString = case Encoding of
"latin1" -> "ISO-8859-1";
@@ -997,27 +1009,6 @@ type(E, Ds) ->
xmerl:export_simple_content(t_utype_elem(E) ++ local_defs(Ds, Opts),
?HTML_EXPORT).
-package(E=#xmlElement{name = package, content = Es}, Options) ->
- Opts = init_opts(E, Options),
- Name = get_text(packageName, Es),
- Title = ["Package ", Name],
- Desc = get_content(description, Es),
-% ShortDesc = get_content(briefDescription, Desc),
- FullDesc = get_content(fullDescription, Desc),
- Body = ([?NL, {h1, [Title]}, ?NL]
-% ++ ShortDesc
- ++ copyright(Es)
- ++ deprecated(Es, "package")
- ++ version(Es)
- ++ since(Es)
- ++ authors(Es)
- ++ references(Es)
- ++ sees(Es)
- ++ todos(Es)
- ++ FullDesc),
- XML = xhtml(Title, stylesheet(Opts), Body),
- xmerl:export_simple(XML, ?HTML_EXPORT, []).
-
overview(E=#xmlElement{name = overview, content = Es}, Options) ->
Opts = init_opts(E, Options),
Title = [get_text(title, Es)],
@@ -1096,8 +1087,8 @@ ot_var(E) ->
{var,0,list_to_atom(get_attrval(name, E))}.
ot_atom(E) ->
- {ok, [Atom], _} = erl_scan:string(get_attrval(value, E), 0),
- Atom.
+ {ok, [{atom,A,Name}], _} = erl_scan:string(get_attrval(value, E), 0),
+ {atom,erl_anno:line(A),Name}.
ot_integer(E) ->
{integer,0,list_to_integer(get_attrval(value, E))}.
diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl
index c46338a2e1..dcc239f6b4 100644
--- a/lib/edoc/src/edoc_lib.erl
+++ b/lib/edoc/src/edoc_lib.erl
@@ -29,9 +29,9 @@
get_first_sentence/1, is_space/1, strip_space/1, parse_expr/2,
parse_contact/2, escape_uri/1, join_uri/2, is_relative_uri/1,
is_name/1, to_label/1, find_doc_dirs/0, find_sources/2,
- find_sources/3, find_file/3, try_subdir/2, unique/1,
- write_file/3, write_file/4, write_file/5, write_info_file/4,
- read_info_file/1, get_doc_env/1, get_doc_env/4, copy_file/2,
+ find_file/2, try_subdir/2, unique/1,
+ write_file/3, write_file/4, write_info_file/3,
+ read_info_file/1, get_doc_env/1, get_doc_env/3, copy_file/2,
uri_get/1, run_doclet/2, run_layout/2,
simplify_path/1, timestr/1, datestr/1, read_encoding/2]).
@@ -266,13 +266,6 @@ is_name_1([$_ | Cs]) ->
is_name_1([]) -> true;
is_name_1(_) -> false.
-to_atom(A) when is_atom(A) -> A;
-to_atom(S) when is_list(S) -> list_to_atom(S).
-
-to_list(A) when is_atom(A) -> atom_to_list(A);
-to_list(S) when is_list(S) -> S.
-
-
%% @private
unique([X | Xs]) -> [X | unique(Xs, X)];
unique([]) -> [].
@@ -674,7 +667,7 @@ simplify_path(P) ->
try_subdir(Dir, Subdir) ->
D = filename:join(Dir, Subdir),
case filelib:is_dir(D) of
- true -> D;
+ true -> D;
false -> Dir
end.
@@ -686,19 +679,10 @@ try_subdir(Dir, Subdir) ->
%% @private
write_file(Text, Dir, Name) ->
- write_file(Text, Dir, Name, '').
-
-%% @spec (Text::deep_string(), Dir::edoc:filename(),
-%% Name::edoc:filename(), Package::atom()|string()) -> ok
-%% @doc Like {@link write_file/3}, but adds path components to the target
-%% directory corresponding to the specified package.
-%% @private
+ write_file(Text, Dir, Name, [{encoding,latin1}]).
-write_file(Text, Dir, Name, Package) ->
- write_file(Text, Dir, Name, Package, [{encoding,latin1}]).
-
-write_file(Text, Dir, Name, Package, Options) ->
- File = filename:join([Dir, to_list(Package), Name]),
+write_file(Text, Dir, Name, Options) ->
+ File = filename:join([Dir, Name]),
ok = filelib:ensure_dir(File),
case file:open(File, [write] ++ Options) of
{ok, FD} ->
@@ -711,15 +695,14 @@ write_file(Text, Dir, Name, Package, Options) ->
end.
%% @private
-write_info_file(App, Packages, Modules, Dir) ->
- Ts = [{packages, Packages},
- {modules, Modules}],
+write_info_file(App, Modules, Dir) ->
+ Ts = [{modules, Modules}],
Ts1 = if App =:= ?NO_APP -> Ts;
true -> [{application, App} | Ts]
end,
S0 = [io_lib:fwrite("~p.\n", [T]) || T <- Ts1],
S = ["%% encoding: UTF-8\n" | S0],
- write_file(S, Dir, ?INFO_FILE, '', [{encoding,unicode}]).
+ write_file(S, Dir, ?INFO_FILE, [{encoding,unicode}]).
%% @spec (Name::edoc:filename()) -> {ok, string()} | {error, Reason}
%%
@@ -744,9 +727,8 @@ read_file(File) ->
info_file_data(Ts) ->
App = proplists:get_value(application, Ts, ?NO_APP),
- Ps = proplists:append_values(packages, Ts),
Ms = proplists:append_values(modules, Ts),
- {App, Ps, Ms}.
+ {App, Ms}.
%% Local file access - don't complain if file does not exist.
@@ -761,10 +743,10 @@ read_info_file(Dir) ->
{error, R} ->
R1 = file:format_error(R),
warning("could not read '~ts': ~ts.", [File, R1]),
- {?NO_APP, [], []}
- end;
+ {?NO_APP, []}
+ end;
false ->
- {?NO_APP, [], []}
+ {?NO_APP, []}
end.
%% URI access
@@ -776,7 +758,7 @@ uri_get_info_file(Base) ->
parse_info_file(Text, URI);
{error, Msg} ->
warning("could not read '~ts': ~ts.", [URI, Msg]),
- {?NO_APP, [], []}
+ {?NO_APP, []}
end.
parse_info_file(Text, Name) ->
@@ -785,10 +767,10 @@ parse_info_file(Text, Name) ->
info_file_data(Vs);
{error, eof} ->
warning("unexpected end of file in '~ts'.", [Name]),
- {?NO_APP, [], []};
+ {?NO_APP, []};
{error, {_Line,Module,R}} ->
warning("~ts: ~ts.", [Module:format_error(R), Name]),
- {?NO_APP, [], []}
+ {?NO_APP, []}
end.
parse_terms(Text) ->
@@ -815,82 +797,67 @@ parse_terms_1([], _As, _Vs) ->
%% ---------------------------------------------------------------------
-%% Source files and packages
+%% Source files
+%% @doc See {@link edoc:run/2} for a description of the options
+%% `subpackages', `source_suffix'.
%% @private
-find_sources(Path, Opts) ->
- find_sources(Path, "", Opts).
-%% @doc See {@link edoc:run/3} for a description of the options
-%% `subpackages', `source_suffix' and `exclude_packages'.
-%% @private
+%% NEW-OPTIONS: subpackages, source_suffix
+%% DEFER-OPTIONS: edoc:run/2
-%% NEW-OPTIONS: subpackages, source_suffix, exclude_packages
-%% DEFER-OPTIONS: edoc:run/3
-
-find_sources(Path, Pkg, Opts) ->
+find_sources(Path, Opts) ->
Rec = proplists:get_bool(subpackages, Opts),
Ext = proplists:get_value(source_suffix, Opts, ?DEFAULT_SOURCE_SUFFIX),
- find_sources(Path, Pkg, Rec, Ext, Opts).
+ find_sources(Path, Rec, Ext, Opts).
-find_sources(Path, Pkg, Rec, Ext, Opts) ->
- Skip = proplists:get_value(exclude_packages, Opts, []),
- lists:flatten(find_sources_1(Path, to_atom(Pkg), Rec, Ext, Skip)).
+find_sources(Path, Rec, Ext, _Opts) ->
+ lists:flatten(find_sources_1(Path, Rec, Ext)).
-find_sources_1([P | Ps], Pkg, Rec, Ext, Skip) ->
- Dir = filename:join(P, atom_to_list(Pkg)),
- Fs1 = find_sources_1(Ps, Pkg, Rec, Ext, Skip),
+find_sources_1([P | Ps], Rec, Ext) ->
+ Dir = P,
+ Fs1 = find_sources_1(Ps, Rec, Ext),
case filelib:is_dir(Dir) of
true ->
- [find_sources_2(Dir, Pkg, Rec, Ext, Skip) | Fs1];
+ [find_sources_2(Dir, Rec, Ext) | Fs1];
false ->
Fs1
end;
-find_sources_1([], _Pkg, _Rec, _Ext, _Skip) ->
+find_sources_1([], _Rec, _Ext) ->
[].
-find_sources_2(Dir, Pkg, Rec, Ext, Skip) ->
- case lists:member(Pkg, Skip) of
- false ->
- Es = list_dir(Dir, false), % just warn if listing fails
- Es1 = [{Pkg, E, Dir} || E <- Es, is_source_file(E, Ext)],
- case Rec of
+find_sources_2(Dir, Rec, Ext) ->
+ Es = list_dir(Dir, false), % just warn if listing fails
+ Es1 = [{E, Dir} || E <- Es, is_source_file(E, Ext)],
+ case Rec of
true ->
- [find_sources_3(Es, Dir, Pkg, Rec, Ext, Skip) | Es1];
+ [find_sources_3(Es, Dir, Rec, Ext) | Es1];
false ->
- Es1
- end;
- true ->
- []
- end.
+ Es1
+ end.
-find_sources_3(Es, Dir, Pkg, Rec, Ext, Skip) ->
+find_sources_3(Es, Dir, Rec, Ext) ->
[find_sources_2(filename:join(Dir, E),
- to_atom(join(Pkg, E)), Rec, Ext, Skip)
- || E <- Es, is_package_dir(E, Dir)].
-
-join('', E) -> E;
-join(Pkg, E) -> filename:join(Pkg, E).
+ Rec, Ext)
+ || E <- Es, is_source_dir(E, Dir)].
is_source_file(Name, Ext) ->
(filename:extension(Name) == Ext)
andalso is_name(filename:rootname(Name, Ext)).
-is_package_dir(Name, Dir) ->
- is_name(filename:rootname(filename:basename(Name)))
- andalso filelib:is_dir(filename:join(Dir, Name)).
+is_source_dir(Name, Dir) ->
+ filelib:is_dir(filename:join(Dir, Name)).
%% @private
-find_file([P | Ps], []=Pkg, Name) ->
- Pkg = [],
+find_file([P | Ps], Name) ->
File = filename:join(P, Name),
case filelib:is_file(File) of
true ->
- File;
+ File;
false ->
- find_file(Ps, Pkg, Name)
- end;
-find_file([], [], _Name) ->
+ find_file(Ps, Name)
+ end;
+find_file([], _Name) ->
"".
%% @private
@@ -909,7 +876,7 @@ find_doc_dirs([P0 | Ps]) ->
File = filename:join(Dir, ?INFO_FILE),
case filelib:is_file(File) of
true ->
- [Dir | find_doc_dirs(Ps)];
+ [Dir | find_doc_dirs(Ps)];
false ->
find_doc_dirs(Ps)
end;
@@ -921,24 +888,23 @@ find_doc_dirs([]) ->
%% implies that we use the default app-path.
%% NEW-OPTIONS: doc_path
-%% DEFER-OPTIONS: get_doc_env/4
+%% DEFER-OPTIONS: get_doc_env/3
-get_doc_links(App, Packages, Modules, Opts) ->
+get_doc_links(App, Modules, Opts) ->
Path = proplists:append_values(doc_path, Opts) ++ find_doc_dirs(),
Ds = [{P, uri_get_info_file(P)} || P <- Path],
- Ds1 = [{"", {App, Packages, Modules}} | Ds],
+ Ds1 = [{"", {App, Modules}} | Ds],
D = dict:new(),
- make_links(Ds1, D, D, D).
+ make_links(Ds1, D, D).
-make_links([{Dir, {App, Ps, Ms}} | Ds], A, P, M) ->
+make_links([{Dir, {App, Ms}} | Ds], A, M) ->
A1 = if App == ?NO_APP -> A;
true -> add_new(App, Dir, A)
end,
F = fun (K, D) -> add_new(K, Dir, D) end,
- P1 = lists:foldl(F, P, Ps),
M1 = lists:foldl(F, M, Ms),
- make_links(Ds, A1, P1, M1);
-make_links([], A, P, M) ->
+ make_links(Ds, A1, M1);
+make_links([], A, M) ->
F = fun (D) ->
fun (K) ->
case dict:find(K, D) of
@@ -947,7 +913,7 @@ make_links([], A, P, M) ->
end
end
end,
- {F(A), F(P), F(M)}.
+ {F(A), F(M)}.
add_new(K, V, D) ->
case dict:is_key(K, D) of
@@ -958,15 +924,14 @@ add_new(K, V, D) ->
end.
%% @spec (Options::proplist()) -> edoc_env()
-%% @equiv get_doc_env([], [], [], Opts)
+%% @equiv get_doc_env([], [], Opts)
%% @private
get_doc_env(Opts) ->
- get_doc_env([], [], [], Opts).
+ get_doc_env([], [], Opts).
-%% @spec (App, Packages, Modules, Options::proplist()) -> edoc_env()
+%% @spec (App, Modules, Options::proplist()) -> edoc_env()
%% App = [] | atom()
-%% Packages = [atom()]
%% Modules = [atom()]
%% proplist() = [term()]
%%
@@ -975,7 +940,7 @@ get_doc_env(Opts) ->
%% generating references. The data representation is not documented.
%%
%% @doc Creates an environment data structure used by parts of EDoc for
-%% generating references, etc. See {@link edoc:run/3} for a description
+%% generating references, etc. See {@link edoc:run/2} for a description
%% of the options `file_suffix', `app_default' and `doc_path'.
%%
%% @see edoc_extract:source/4
@@ -983,19 +948,17 @@ get_doc_env(Opts) ->
%% NEW-OPTIONS: file_suffix, app_default
%% INHERIT-OPTIONS: get_doc_links/4
-%% DEFER-OPTIONS: edoc:run/3
+%% DEFER-OPTIONS: edoc:run/2
-get_doc_env(App, Packages, Modules, Opts) ->
+get_doc_env(App, Modules, Opts) ->
Suffix = proplists:get_value(file_suffix, Opts,
?DEFAULT_FILE_SUFFIX),
AppDefault = proplists:get_value(app_default, Opts, ?APP_DEFAULT),
Includes = proplists:append_values(includes, Opts),
- {A, P, M} = get_doc_links(App, Packages, Modules, Opts),
+ {A, M} = get_doc_links(App, Modules, Opts),
#env{file_suffix = Suffix,
- package_summary = ?PACKAGE_SUMMARY ++ Suffix,
apps = A,
- packages = P,
modules = M,
app_default = AppDefault,
includes = Includes
@@ -1004,10 +967,10 @@ get_doc_env(App, Packages, Modules, Opts) ->
%% ---------------------------------------------------------------------
%% Plug-in modules
-%% @doc See {@link edoc:run/3} for a description of the `doclet' option.
+%% @doc See {@link edoc:run/2} for a description of the `doclet' option.
%% NEW-OPTIONS: doclet
-%% DEFER-OPTIONS: edoc:run/3
+%% DEFER-OPTIONS: edoc:run/2
%% @private
run_doclet(Fun, Opts) ->
@@ -1049,7 +1012,7 @@ get_plugin(Key, Default, Opts) ->
%% ---------------------------------------------------------------------
%% Error handling
--type line() :: erl_scan:line().
+-type line() :: erl_anno:line().
-type err() :: 'eof'
| {'missing', char()}
| {line(), atom(), string()}
diff --git a/lib/edoc/src/edoc_macros.erl b/lib/edoc/src/edoc_macros.erl
index 8efbfd00c7..e1a54d5090 100644
--- a/lib/edoc/src/edoc_macros.erl
+++ b/lib/edoc/src/edoc_macros.erl
@@ -40,10 +40,6 @@ std_macros(Env) ->
true -> [{module, atom_to_list(Env#env.module)}]
end
++
- if Env#env.package =:= [] -> [];
- true -> [{package, atom_to_list(Env#env.package)}]
- end
- ++
[{date, fun date_macro/3},
{docRoot, Env#env.root},
{link, fun link_macro/3},
@@ -315,7 +311,7 @@ macro_content([C | Cs], As, L, N) ->
macro_content([], _As, _L, _N) ->
throw('end').
--type line() :: erl_scan:line().
+-type line() :: erl_anno:line().
-type err() :: 'unterminated_macro'
| 'macro_name'
| {'macro_name', string()}
diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl
index c6f8a04775..835e7ccaa6 100644
--- a/lib/edoc/src/edoc_parser.yrl
+++ b/lib/edoc/src/edoc_parser.yrl
@@ -28,7 +28,7 @@
Nonterminals
start spec func_type utype_list utype_tuple utypes utype ptypes ptype
nutype function_name where_defs defs defs2 def typedef etype
-throws qname ref aref mref lref pref var_list vars fields field
+throws qname ref aref mref lref var_list vars fields field
utype_map utype_map_fields utype_map_field
futype_list bin_base_type bin_unit_type.
@@ -207,14 +207,11 @@ typedef -> atom var_list '=' utype where_defs:
ref -> aref: '$1'.
ref -> mref: '$1'.
ref -> lref: '$1'.
-ref -> pref: '$1'.
aref -> '//' atom:
edoc_refs:app(tok_val('$2')).
aref -> '//' atom '/' mref:
edoc_refs:app(tok_val('$2'), '$4').
-aref -> '//' atom '/' pref:
- edoc_refs:app(tok_val('$2'), '$4').
mref -> qname ':' atom '/' integer:
edoc_refs:function(qname('$1'), tok_val('$3'), tok_val('$5')).
@@ -223,9 +220,6 @@ mref -> qname ':' atom '(' ')':
mref -> qname:
edoc_refs:module(qname('$1')).
-pref -> qname '.' '*':
- edoc_refs:package(qname('$1')).
-
lref -> atom '/' integer:
edoc_refs:function(tok_val('$1'), tok_val('$3')).
lref -> atom '(' ')':
@@ -344,7 +338,7 @@ build_def(S, P, As, T) ->
args = lists:reverse(As)},
type = T};
false ->
- return_error(element(2, P), "variable expected after '('")
+ return_error(tok_line(P), "variable expected after '('")
end.
all_vars([#t_var{} | As]) ->
@@ -399,7 +393,7 @@ parse_typedef_1(S, L) ->
%% @doc Parses a <a
%% href="overview-summary.html#References">reference</a> to a module,
-%% package, function, type, or application
+%% function, type, or application
parse_ref(S, L) ->
case edoc_scanner:string(S, L) of
@@ -458,7 +452,7 @@ parse_throws(S, L) ->
%% ---------------------------------------------------------------------
--spec throw_error(term(), erl_scan:line()) -> no_return().
+-spec throw_error(term(), erl_anno:line()) -> no_return().
throw_error({parse_spec, E}, L) ->
throw_error({"specification", E}, L);
diff --git a/lib/edoc/src/edoc_refs.erl b/lib/edoc/src/edoc_refs.erl
index ea439490ed..b9a9391053 100644
--- a/lib/edoc/src/edoc_refs.erl
+++ b/lib/edoc/src/edoc_refs.erl
@@ -27,10 +27,9 @@
-module(edoc_refs).
--export([app/1, app/2, package/1, module/1, module/2, module/3,
+-export([app/1, app/2, module/1, module/2, module/3,
function/2, function/3, function/4, type/1, type/2, type/3,
- to_string/1, to_label/1, get_uri/2, is_top/2,
- relative_module_path/2, relative_package_path/2]).
+ to_string/1, to_label/1, get_uri/2, is_top/2]).
-import(edoc_lib, [join_uri/2, escape_uri/1]).
@@ -56,9 +55,6 @@ module(M, Ref) ->
module(App, M, Ref) ->
app(App, module(M, Ref)).
-package(P) ->
- {package, P}.
-
function(F, A) ->
{function, F, A}.
@@ -88,8 +84,6 @@ to_string({module, M}) ->
atom_to_list(M) ;
to_string({module, M, Ref}) ->
atom_to_list(M) ++ ":" ++ to_string(Ref);
-to_string({package, P}) ->
- atom_to_list(P) ++ ".*";
to_string({function, F, A}) ->
atom_to_list(F) ++ "/" ++ integer_to_list(A);
to_string({type, T}) ->
@@ -111,24 +105,19 @@ get_uri({module, M, Ref}, Env) ->
module_ref(M, Env) ++ "#" ++ to_label(Ref);
get_uri({module, M}, Env) ->
module_ref(M, Env);
-get_uri({package, P}, Env) ->
- package_ref(P, Env);
get_uri(Ref, _Env) ->
"#" ++ to_label(Ref).
abs_uri({module, M}, Env) ->
module_absref(M, Env);
abs_uri({module, M, Ref}, Env) ->
- module_absref(M, Env) ++ "#" ++ to_label(Ref);
-abs_uri({package, P}, Env) ->
- package_absref(P, Env).
+ module_absref(M, Env) ++ "#" ++ to_label(Ref).
module_ref(M, Env) ->
case (Env#env.modules)(M) of
"" ->
File = atom_to_list(M) ++ Env#env.file_suffix,
- Path = relative_module_path(M, Env#env.package),
- join_uri(Path, escape_uri(File));
+ escape_uri(File);
Base ->
join_uri(Base, module_absref(M, Env))
end.
@@ -136,19 +125,6 @@ module_ref(M, Env) ->
module_absref(M, Env) ->
escape_uri(atom_to_list(M)) ++ escape_uri(Env#env.file_suffix).
-package_ref(P, Env) ->
- case (Env#env.packages)(P) of
- "" ->
- join_uri(relative_package_path(P, Env#env.package),
- escape_uri(Env#env.package_summary));
- Base ->
- join_uri(Base, package_absref(P, Env))
- end.
-
-package_absref(P, Env) ->
- join_uri(escape_uri(atom_to_list(P)),
- escape_uri(Env#env.package_summary)).
-
app_ref(A, Env) ->
case (Env#env.apps)(A) of
"" ->
@@ -166,43 +142,3 @@ is_top({app, _App}, _Env) ->
is_top(_Ref, _Env) ->
false.
-%% Each segment of a path must be separately escaped before joining.
-
-join_segments([S]) ->
- escape_uri(S);
-join_segments([S | Ss]) ->
- join_uri(escape_uri(S), join_segments(Ss)).
-
-%% 'From' is always the "current package" here:
-
-%% The empty string is returned if the To module has only one segment,
-%% implying a local reference.
-
-relative_module_path(_To, _From) ->
- "".
-
-relative_package_path(To, From) ->
- relative_path([atom_to_list(To)], [atom_to_list(From)]).
-
-%% This takes two lists of path segments (From, To). Note that an empty
-%% string will be returned if the paths are the same. Empty leading
-%% segments are stripped from both paths.
-
-relative_path(Ts, ["" | Fs]) ->
- relative_path(Ts, Fs);
-relative_path(["" | Ts], Fs) ->
- relative_path(Ts, Fs);
-relative_path(Ts, Fs) ->
- relative_path_1(Ts, Fs).
-
-relative_path_1([T | Ts], [F | Fs]) when F == T ->
- relative_path_1(Ts, Fs);
-relative_path_1(Ts, Fs) ->
- relative_path_2(Fs, Ts).
-
-relative_path_2([_F | Fs], Ts) ->
- relative_path_2(Fs, [".." | Ts]);
-relative_path_2([], []) ->
- "";
-relative_path_2([], Ts) ->
- join_segments(Ts).
diff --git a/lib/edoc/src/edoc_run.erl b/lib/edoc/src/edoc_run.erl
index b5a1ef713d..9a569d0879 100644
--- a/lib/edoc/src/edoc_run.erl
+++ b/lib/edoc/src/edoc_run.erl
@@ -17,7 +17,7 @@
%% @copyright 2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @see edoc
-%% @end
+%% @end
%% =====================================================================
%% @doc Interface for calling EDoc from Erlang startup options.
@@ -38,7 +38,7 @@
-module(edoc_run).
--export([file/1, application/1, packages/1, files/1, toc/1]).
+-export([file/1, application/1, files/1, toc/1]).
-compile({no_auto_import,[error/1]}).
@@ -92,28 +92,6 @@ files(Args) ->
end,
run(F).
-%% @spec packages([string()]) -> none()
-%%
-%% @doc Calls {@link edoc:application/2} with the corresponding
-%% arguments. The strings in the list are parsed as Erlang constant
-%% terms. The list can be either `[Packages]' or `[Packages, Options]'.
-%% In the first case {@link edoc:application/1} is called instead.
-%%
-%% The function call never returns; instead, the emulator is
-%% automatically terminated when the call has completed, signalling
-%% success or failure to the operating system.
-
-packages(Args) ->
- F = fun () ->
- case parse_args(Args) of
- [Packages] -> edoc:packages(Packages);
- [Packages, Opts] -> edoc:packages(Packages, Opts);
- _ ->
- invalid_args("edoc_run:packages/1", Args)
- end
- end,
- run(F).
-
%% @hidden Not official yet
toc(Args) ->
F = fun () ->
@@ -131,8 +109,8 @@ toc(Args) ->
%%
%% @deprecated This is part of the old interface to EDoc and is mainly
%% kept for backwards compatibility. The preferred way of generating
-%% documentation is through one of the functions {@link application/1},
-%% {@link packages/1} and {@link files/1}.
+%% documentation is through one of the functions {@link application/1}
+%% and {@link files/1}.
%%
%% @doc Calls {@link edoc:file/2} with the corresponding arguments. The
%% strings in the list are parsed as Erlang constant terms. The list can
diff --git a/lib/edoc/src/edoc_scanner.erl b/lib/edoc/src/edoc_scanner.erl
index 6ff97a134c..36423d63f8 100644
--- a/lib/edoc/src/edoc_scanner.erl
+++ b/lib/edoc/src/edoc_scanner.erl
@@ -1,12 +1,13 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings
diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl
index 211a354c74..f2e5891c2e 100644
--- a/lib/edoc/src/edoc_specs.erl
+++ b/lib/edoc/src/edoc_specs.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -58,7 +59,7 @@ type(Form, TypeDocs) ->
end,
{#t_name{name = N}, T, As, Doc0}
end,
- #tag{name = type, line = element(2, Type),
+ #tag{name = type, line = get_line(element(2, Type)),
origin = code,
data = {#t_typedef{name = TypeName,
args = d2e(Args),
@@ -71,7 +72,7 @@ type(Form, TypeDocs) ->
spec(Form, Clause) ->
{Name, _Arity, TypeSpecs} = get_spec(Form),
TypeSpec = lists:nth(Clause, TypeSpecs),
- #tag{name = spec, line = element(2, TypeSpec),
+ #tag{name = spec, line = get_line(element(2, TypeSpec)),
origin = code,
data = aspec(d2e(TypeSpec), Name)}.
@@ -83,7 +84,7 @@ dummy_spec(Form) ->
{#t_name{name = Name}, Arity, TypeSpecs} = get_spec(Form),
As = string:join(lists:duplicate(Arity, "_X"), ","),
S = lists:flatten(io_lib:format("~p(~s) -> true\n", [Name, As])),
- #tag{name = spec, line = element(2, hd(TypeSpecs)),
+ #tag{name = spec, line = get_line(element(2, hd(TypeSpecs))),
origin = code, data = S}.
-spec docs(Forms::[syntaxTree()],
@@ -140,7 +141,7 @@ find_type_docs([F | Fs], Cs, Fun) ->
%% Postcomments before the dot after the typespec are ignored.
C2 = [C1 | [C ||
C <- erl_syntax:get_postcomments(F),
- get_line(erl_syntax:get_pos(C)) >= LastTypeLine]],
+ erl_syntax:get_pos(C) >= LastTypeLine]],
C3 = collect_comments(Fs, LastTypeLine),
#tag{data = Doc0} = Fun(lists:reverse(C2 ++ C3), LastTypeLine),
case strip(Doc0) of % Strip away "f(). \n"
@@ -157,7 +158,7 @@ find_type_docs([F | Fs], Cs, Fun) ->
collect_comments([], _Line) ->
[];
collect_comments([F | Fs], Line) ->
- L1 = get_line(erl_syntax:get_pos(F)),
+ L1 = erl_syntax:get_pos(F),
if
L1 =:= Line + 1;
L1 =:= Line -> % a separate postcomment
@@ -190,29 +191,26 @@ get_name_and_last_line(F) ->
{Name, Data} = erl_syntax_lib:analyze_wild_attribute(F),
type = edoc_specs:tag(Name),
Attr = {attribute, erl_syntax:get_pos(F), Name, Data},
- Ref = make_ref(),
- Fun = fun(L) -> {Ref, get_line(L)} end,
+ Fun = fun(A) ->
+ Line = get_line(A),
+ case get('$max_line') of
+ Max when Max < Line ->
+ _ = put('$max_line', Line);
+ _ ->
+ ok
+ end
+ end,
+ undefined = put('$max_line', 0),
+ _ = erl_parse:map_anno(Fun, Attr),
+ Line = erase('$max_line'),
TypeName = case Data of
{N, _T, As} when is_atom(N) -> % skip records
{N, length(As)}
end,
- Line = gll(erl_lint:modify_line(Attr, Fun), Ref),
{TypeName, Line}.
-gll({Ref, Line}, Ref) ->
- Line;
-gll([], _Ref) ->
- 0;
-gll(List, Ref) when is_list(List) ->
- lists:max([gll(E, Ref) || E <- List]);
-gll(Tuple, Ref) when is_tuple(Tuple) ->
- gll(tuple_to_list(Tuple), Ref);
-gll(_, _) ->
- 0.
-
-get_line(Pos) ->
- {line, Line} = erl_scan:attributes_info(Pos, line),
- Line.
+get_line(Anno) ->
+ erl_anno:line(Anno).
%% Collect all Erlang types. Types in comments (@type) shadow Erlang
%% types (-spec/-opaque).
@@ -272,12 +270,8 @@ parms([], []) ->
parms([A | As], [D | Ds]) ->
[param(A, D) | parms(As, Ds)].
-param(#t_list{type = Type}, Default) ->
- param(Type, Default);
param(#t_paren{type = Type}, Default) ->
param(Type, Default);
-param(#t_nonempty_list{type = Type}, Default) ->
- param(Type, Default);
param(#t_record{name = #t_atom{val = Name}}, _Default) ->
list_to_atom(capitalize(atom_to_list(Name)));
param(T, Default) ->
@@ -298,47 +292,54 @@ arg_name([A | As], Default) ->
is_name(A) ->
is_atom(A).
-d2e({ann_type,_,[V, T0]}) ->
+d2e(T) ->
+ d2e(T, 0).
+
+d2e({ann_type,_,[V, T0]}, Prec) ->
%% Note: the -spec/-type syntax allows annotations everywhere, but
%% EDoc does not. The fact that the annotation is added to the
%% type here does not necessarily mean that it will be used by the
%% layout module.
- T = d2e(T0),
- ?add_t_ann(T, element(3, V));
-d2e({remote_type,_,[{atom,_,M},{atom,_,F},Ts0]}) ->
+ {_L,P,R} = erl_parse:type_inop_prec('::'),
+ T1 = d2e(T0, R),
+ T = ?add_t_ann(T1, element(3, V)),
+ maybe_paren(P, Prec, T); % the only necessary call to maybe_paren()
+d2e({remote_type,_,[{atom,_,M},{atom,_,F},Ts0]}, _Prec) ->
Ts = d2e(Ts0),
typevar_anno(#t_type{name = #t_name{module = M, name = F}, args = Ts}, Ts);
-d2e({type,_,'fun',[{type,_,product,As0},Ran0]}) ->
+d2e({type,_,'fun',[{type,_,product,As0},Ran0]}, _Prec) ->
Ts = [Ran|As] = d2e([Ran0|As0]),
%% Assume that the linter has checked type variables.
typevar_anno(#t_fun{args = As, range = Ran}, Ts);
-d2e({type,_,'fun',[A0={type,_,any},Ran0]}) ->
+d2e({type,_,'fun',[A0={type,_,any},Ran0]}, _Prec) ->
Ts = [A, Ran] = d2e([A0, Ran0]),
typevar_anno(#t_fun{args = [A], range = Ran}, Ts);
-d2e({type,_,'fun',[]}) ->
+d2e({type,_,'fun',[]}, _Prec) ->
#t_type{name = #t_name{name = function}, args = []};
-d2e({type,_,any}) ->
+d2e({type,_,any}, _Prec) ->
#t_var{name = '...'}; % Kludge... not a type variable!
-d2e({type,_,nil,[]}) ->
+d2e({type,_,nil,[]}, _Prec) ->
#t_nil{};
-d2e({paren_type,_,[T]}) ->
- #t_paren{type = d2e(T)};
-d2e({type,_,list,[T0]}) ->
+d2e({paren_type,_,[T]}, Prec) ->
+ d2e(T, Prec);
+d2e({type,_,list,[T0]}, _Prec) ->
T = d2e(T0),
typevar_anno(#t_list{type = T}, [T]);
-d2e({type,_,nonempty_list,[T0]}) ->
+d2e({type,_,nonempty_list,[T0]}, _Prec) ->
T = d2e(T0),
typevar_anno(#t_nonempty_list{type = T}, [T]);
-d2e({type,_,bounded_fun,[T,Gs]}) ->
+d2e({type,_,bounded_fun,[T,Gs]}, _Prec) ->
[F0|Defs] = d2e([T|Gs]),
F = ?set_t_ann(F0, lists:keydelete(type_variables, 1, ?t_ann(F0))),
%% Assume that the linter has checked type variables.
#t_spec{type = typevar_anno(F, [F0]), defs = Defs};
-d2e({type,_,range,[V1,V2]}) ->
+d2e({type,_,range,[V1,V2]}, Prec) ->
+ {_L,P,_R} = erl_parse:type_inop_prec('..'),
{integer,_,I1} = erl_eval:partial_eval(V1),
{integer,_,I2} = erl_eval:partial_eval(V2),
- #t_integer_range{from = I1, to = I2};
-d2e({type,_,constraint,[Sub,Ts0]}) ->
+ T0 = #t_integer_range{from = I1, to = I2},
+ maybe_paren(P, Prec, T0);
+d2e({type,_,constraint,[Sub,Ts0]}, _Prec) ->
case {Sub,Ts0} of
{{atom,_,is_subtype},[{var,_,N},T0]} ->
Ts = [T] = d2e([T0]),
@@ -348,49 +349,62 @@ d2e({type,_,constraint,[Sub,Ts0]}) ->
Ts = [ST,T] = d2e([ST0,T0]),
#t_def{name = ST, type = typevar_anno(T, Ts)};
_ ->
- throw_error(element(2, Sub), "cannot handle guard", [])
+ throw_error(get_line(element(2, Sub)), "cannot handle guard", [])
end;
-d2e({type,_,union,Ts0}) ->
- Ts = d2e(Ts0),
- typevar_anno(#t_union{types = Ts}, Ts);
-d2e({type,_,tuple,any}) ->
+d2e({type,_,union,Ts0}, Prec) ->
+ {_L,P,R} = erl_parse:type_inop_prec('|'),
+ Ts = d2e(Ts0, R),
+ T = maybe_paren(P, Prec, #t_union{types = Ts}),
+ typevar_anno(T, Ts);
+d2e({type,_,tuple,any}, _Prec) ->
#t_type{name = #t_name{name = tuple}, args = []};
-d2e({type,_,binary,[Base,Unit]}) ->
- #t_binary{base_size = element(3, Base),
- unit_size = element(3, Unit)};
-d2e({type,_,map,any}) ->
- #t_map{ types = []};
-d2e({type,_,map,Es}) ->
- #t_map{ types = d2e(Es) };
-d2e({type,_,map_field_assoc,K,V}) ->
- #t_map_field{ k_type = d2e(K), v_type=d2e(V) };
-d2e({type,_,map_field_exact,K,V}) ->
- #t_map_field{ k_type = d2e(K), v_type=d2e(V) };
-d2e({type,_,tuple,Ts0}) ->
+d2e({type,_,binary,[Base,Unit]}, _Prec) ->
+ {integer,_,B} = erl_eval:partial_eval(Base),
+ {integer,_,U} = erl_eval:partial_eval(Unit),
+ #t_binary{base_size = B, unit_size = U};
+d2e({type,_,map,any}, _Prec) ->
+ #t_map{types = []};
+d2e({type,_,map,Es}, _Prec) ->
+ #t_map{types = d2e(Es) };
+d2e({type,_,map_field_assoc,[K,V]}, Prec) ->
+ T = #t_map_field{k_type = d2e(K), v_type=d2e(V) },
+ {P,_R} = erl_parse:type_preop_prec('#'),
+ maybe_paren(P, Prec, T);
+d2e({type,_,map_field_exact,K,V}, Prec) ->
+ T = #t_map_field{k_type = d2e(K), v_type=d2e(V) },
+ {P,_R} = erl_parse:type_preop_prec('#'),
+ maybe_paren(P, Prec, T);
+d2e({type,_,tuple,Ts0}, _Prec) ->
Ts = d2e(Ts0),
typevar_anno(#t_tuple{types = Ts}, Ts);
-d2e({type,_,record,[Name|Fs0]}) ->
+d2e({type,_,record,[Name|Fs0]}, Prec) ->
Atom = #t_atom{val = element(3, Name)},
Fs = d2e(Fs0),
- typevar_anno(#t_record{name = Atom, fields = Fs}, Fs);
-d2e({type,_,field_type,[Name,Type0]}) ->
- Type = d2e(Type0),
- typevar_anno(#t_field{name = #t_atom{val = element(3, Name)}, type = Type},
- [Type]);
-d2e({typed_record_field,{record_field,L,Name},Type}) ->
- d2e({type,L,field_type,[Name,Type]});
-d2e({typed_record_field,{record_field,L,Name,_E},Type}) ->
- d2e({type,L,field_type,[Name,Type]});
-d2e({record_field,L,_Name,_E}=F) ->
- d2e({typed_record_field,F,{type,L,any,[]}}); % Maybe skip...
-d2e({record_field,L,_Name}=F) ->
- d2e({typed_record_field,F,{type,L,any,[]}}); % Maybe skip...
-d2e({type,_,Name,Types0}) ->
+ {P,_R} = erl_parse:type_preop_prec('#'),
+ T = maybe_paren(P, Prec, #t_record{name = Atom, fields = Fs}),
+ typevar_anno(T, Fs);
+d2e({type,_,field_type,[Name,Type0]}, Prec) ->
+ {_L,P,R} = erl_parse:type_inop_prec('::'),
+ Type = maybe_paren(P, Prec, d2e(Type0, R)),
+ T = #t_field{name = #t_atom{val = element(3, Name)}, type = Type},
+ typevar_anno(T, [Type]);
+d2e({typed_record_field,{record_field,L,Name},Type}, Prec) ->
+ d2e({type,L,field_type,[Name,Type]}, Prec);
+d2e({typed_record_field,{record_field,L,Name,_E},Type}, Prec) ->
+ d2e({type,L,field_type,[Name,Type]}, Prec);
+d2e({record_field,L,_Name,_E}=F, Prec) ->
+ d2e({typed_record_field,F,{type,L,any,[]}}, Prec); % Maybe skip...
+d2e({record_field,L,_Name}=F, Prec) ->
+ d2e({typed_record_field,F,{type,L,any,[]}}, Prec); % Maybe skip...
+d2e({type,_,Name,Types0}, _Prec) ->
+ Types = d2e(Types0),
+ typevar_anno(#t_type{name = #t_name{name = Name}, args = Types}, Types);
+d2e({user_type,_,Name,Types0}, _Prec) ->
Types = d2e(Types0),
typevar_anno(#t_type{name = #t_name{name = Name}, args = Types}, Types);
-d2e({var,_,'_'}) ->
+d2e({var,_,'_'}, _Prec) ->
#t_type{name = #t_name{name = ?TOP_TYPE}};
-d2e({var,_,TypeName}) ->
+d2e({var,_,TypeName}, _Prec) ->
TypeVar = ordsets:from_list([TypeName]),
T = #t_var{name = TypeName},
%% Annotate type variables with the name of the variable.
@@ -398,13 +412,13 @@ d2e({var,_,TypeName}) ->
%% from using the argument name from the source or to invent a new name.
T1 = ?add_t_ann(T, {type_variables, TypeVar}),
?add_t_ann(T1, TypeName);
-d2e(L) when is_list(L) ->
- [d2e(T) || T <- L];
-d2e({atom,_,A}) ->
+d2e(L, Prec) when is_list(L) ->
+ [d2e(T, Prec) || T <- L];
+d2e({atom,_,A}, _Prec) ->
#t_atom{val = A};
-d2e(undefined = U) -> % opaque
+d2e(undefined = U, _Prec) -> % opaque
U;
-d2e(Expr) ->
+d2e(Expr, _Prec) ->
{integer,_,I} = erl_eval:partial_eval(Expr),
#t_integer{val = I}.
@@ -422,6 +436,11 @@ typevars(Ts) ->
get_typevars(Ts) ->
[Vs || T <- Ts, T =/= undefined, {type_variables, Vs} <- ?t_ann(T)].
+maybe_paren(P, Prec, T) when P < Prec ->
+ #t_paren{type = T};
+maybe_paren(_P, _Prec, T) ->
+ T.
+
-record(parms, {tab, warn, file, line}).
%% Expands record references. Explicitly given record fields are kept,
@@ -484,11 +503,11 @@ xrecs(#t_fun{args = Args0, range = Range0}=T, P) ->
Args = xrecs(Args0, P),
Range = xrecs(Range0, P),
T#t_fun{args = Args, range = Range};
-xrecs(#t_map{ types = Ts0 }=T,P) ->
+xrecs(#t_map{types = Ts0 }=T,P) ->
Ts = xrecs(Ts0, P),
- T#t_map{ types = Ts };
-xrecs(#t_map_field{ k_type=Kt, v_type=Vt}=T, P) ->
- T#t_map_field{ k_type=xrecs(Kt,P), v_type=xrecs(Vt,P)};
+ T#t_map{types = Ts };
+xrecs(#t_map_field{k_type=Kt, v_type=Vt}=T, P) ->
+ T#t_map_field{k_type=xrecs(Kt,P), v_type=xrecs(Vt,P)};
xrecs(#t_tuple{types = Types0}=T, P) ->
Types = xrecs(Types0, P),
T#t_tuple{types = Types};
diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl
index 264a533a52..9e2e41e902 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -42,7 +42,7 @@
%% Name = atom()
%% Parser = text | xml | (Text,Line,Where) -> term()
%% Flags = [Flag]
-%% Flag = module | function | package | overview | single
+%% Flag = module | function | overview | single
%%
%% Note that the pseudo-tag '@clear' is not listed here.
%% (Cf. the function 'filter_tags'.)
@@ -57,11 +57,11 @@
%% - @category (useless; superseded by keywords or free text search)
tags() ->
- All = [module,footer,function,package,overview],
- [{author, fun parse_contact/4, [module,package,overview]},
- {copyright, text, [module,package,overview,single]},
- {deprecated, xml, [module,function,package,single]},
- {doc, xml, [module,function,package,overview,single]},
+ All = [module,footer,function,overview],
+ [{author, fun parse_contact/4, [module,overview]},
+ {copyright, text, [module,overview,single]},
+ {deprecated, xml, [module,function,single]},
+ {doc, xml, [module,function,overview,single]},
{docfile, fun parse_file/4, All},
{'end', text, All},
{equiv, fun parse_expr/4, [function,single]},
@@ -69,17 +69,17 @@ tags() ->
{hidden, text, [module,function,single]},
{param, fun parse_param/4, [function]},
{private, text, [module,function,single]},
- {reference, xml, [module,footer,package,overview]},
+ {reference, xml, [module,footer,overview]},
{returns, xml, [function,single]},
- {see, fun parse_see/4, [module,function,package,overview]},
- {since, text, [module,function,package,overview,single]},
+ {see, fun parse_see/4, [module,function,overview]},
+ {since, text, [module,function,overview,single]},
{spec, fun parse_spec/4, [function,single]},
{throws, fun parse_throws/4, [function,single]},
{title, text, [overview,single]},
{'TODO', xml, All},
{todo, xml, All},
{type, fun parse_typedef/4, [module,footer,function]},
- {version, text, [module,package,overview,single]}].
+ {version, text, [module,overview,single]}].
aliases('TODO') -> todo;
aliases(return) -> returns;
@@ -329,10 +329,7 @@ parse_typedef(Data, Line, _Env, Where) ->
NAs = length(As),
case edoc_types:is_predefined(T, NAs) of
true ->
- case
- edoc_types:is_new_predefined(T, NAs)
- orelse edoc_types:is_predefined_otp_type(T, NAs)
- of
+ case edoc_types:is_new_predefined(T, NAs) of
false ->
throw_error(Line, {"redefining built-in type '~w'.",
[T]});
@@ -345,7 +342,7 @@ parse_typedef(Data, Line, _Env, Where) ->
Def
end.
--type line() :: erl_scan:line().
+-type line() :: erl_anno:line().
-spec parse_file(_, line(), _, _) -> no_return().
@@ -372,7 +369,7 @@ parse_header(Data, Line, Env, Where) when is_list(Where) ->
{string, _, File} ->
Dir = filename:dirname(Where),
Path = Env#env.includes ++ [Dir],
- case edoc_lib:find_file(Path, "", File) of
+ case edoc_lib:find_file(Path, File) of
"" ->
throw_error(Line, {file_not_found, File});
File1 ->
@@ -499,7 +496,6 @@ check_used_type(#t_name{name = N, module = Mod}=Name, Args, P, LocalTypes) ->
Mod =/= []
orelse lists:member(TypeName, ets:lookup(DT, Name))
orelse edoc_types:is_predefined(N, NArgs)
- orelse edoc_types:is_predefined_otp_type(N, NArgs)
orelse lists:member(TypeName, LocalTypes)
of
true ->
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index 8a6c8eb33e..65fba61a72 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -25,7 +25,7 @@
-module(edoc_types).
--export([is_predefined/2, is_new_predefined/2, is_predefined_otp_type/2,
+-export([is_predefined/2, is_new_predefined/2,
to_ref/1, to_xml/2, to_label/1, arg_names/1, set_arg_names/2,
arg_descs/1, range_desc/1]).
@@ -34,67 +34,13 @@
-include("edoc_types.hrl").
-include_lib("xmerl/include/xmerl.hrl").
-
-is_predefined(any, 0) -> true;
-is_predefined(atom, 0) -> true;
-is_predefined(binary, 0) -> true;
-is_predefined(bool, 0) -> true; % kept for backwards compatibility
-is_predefined(char, 0) -> true;
is_predefined(cons, 2) -> true;
is_predefined(deep_string, 0) -> true;
-is_predefined(float, 0) -> true;
-is_predefined(function, 0) -> true;
-is_predefined(integer, 0) -> true;
-is_predefined(list, 0) -> true;
-is_predefined(list, 1) -> true;
-is_predefined(nil, 0) -> true;
-is_predefined(none, 0) -> true;
-is_predefined(no_return, 0) -> true;
-is_predefined(number, 0) -> true;
-is_predefined(pid, 0) -> true;
-is_predefined(port, 0) -> true;
-is_predefined(reference, 0) -> true;
-is_predefined(string, 0) -> true;
-is_predefined(term, 0) -> true;
-is_predefined(tuple, 0) -> true;
-is_predefined(F, A) -> is_new_predefined(F, A).
+is_predefined(F, A) -> erl_internal:is_type(F, A).
-%% Should eventually be coalesced with is_predefined/2.
-is_new_predefined(arity, 0) -> true;
-is_new_predefined(bitstring, 0) -> true;
-is_new_predefined(boolean, 0) -> true;
-is_new_predefined(byte, 0) -> true;
-is_new_predefined(iodata, 0) -> true;
-is_new_predefined(iolist, 0) -> true;
is_new_predefined(map, 0) -> true;
-is_new_predefined(maybe_improper_list, 0) -> true;
-is_new_predefined(maybe_improper_list, 2) -> true;
-is_new_predefined(mfa, 0) -> true;
-is_new_predefined(module, 0) -> true;
-is_new_predefined(neg_integer, 0) -> true;
-is_new_predefined(node, 0) -> true;
-is_new_predefined(non_neg_integer, 0) -> true;
-is_new_predefined(nonempty_improper_list, 2) -> true;
-is_new_predefined(nonempty_list, 0) -> true;
-is_new_predefined(nonempty_list, 1) -> true;
-is_new_predefined(nonempty_maybe_improper_list, 0) -> true;
-is_new_predefined(nonempty_maybe_improper_list, 2) -> true;
-is_new_predefined(nonempty_string, 0) -> true;
-is_new_predefined(pos_integer, 0) -> true;
-is_new_predefined(timeout, 0) -> true;
is_new_predefined(_, _) -> false.
-%% The following types will be removed later, but they are currently
-%% kind of built-in.
-is_predefined_otp_type(array, 0) -> true;
-is_predefined_otp_type(dict, 0) -> true;
-is_predefined_otp_type(digraph, 0) -> true;
-is_predefined_otp_type(gb_set, 0) -> true;
-is_predefined_otp_type(gb_tree, 0) -> true;
-is_predefined_otp_type(queue, 0) -> true;
-is_predefined_otp_type(set, 0) -> true;
-is_predefined_otp_type(_, _) -> false.
-
to_ref(#t_typedef{name = N}) ->
to_ref(N);
to_ref(#t_def{name = N}) ->
@@ -129,8 +75,7 @@ to_xml(#t_type{name = N, args = As}, Env) ->
Predef = case N of
#t_name{module = [], name = T} ->
NArgs = length(As),
- (is_predefined(T, NArgs)
- orelse is_predefined_otp_type(T, NArgs));
+ is_predefined(T, NArgs);
_ ->
false
end,
diff --git a/lib/edoc/src/otpsgml_layout.erl b/lib/edoc/src/otpsgml_layout.erl
index 2c4cd919bb..052c75b9d4 100644
--- a/lib/edoc/src/otpsgml_layout.erl
+++ b/lib/edoc/src/otpsgml_layout.erl
@@ -28,7 +28,7 @@
-module(otpsgml_layout).
--export([module/2, package/2, overview/2,type/1]).
+-export([module/2, overview/2,type/1]).
-import(edoc_report, [report/2]).
@@ -811,27 +811,6 @@ xml(Title, CSS, Body) ->
xmerl:export_simple_content(t_utype_elem(E) ++ local_defs(Ds),
?SGML_EXPORT).
-
-package(E=#xmlElement{name = package, content = Es}, Options) ->
- Opts = init_opts(E, Options),
- Name = get_text(packageName, Es),
- Title = io_lib:fwrite("Package ~s", [Name]),
- Desc = get_content(description, Es),
-% ShortDesc = get_content(briefDescription, Desc),
- FullDesc = get_content(fullDescription, Desc),
- Body = ([?NL, {h1, [Title]}, ?NL]
-% ++ ShortDesc
- ++ copyright(Es)
- ++ deprecated(Es, "package")
- ++ version(Es)
- ++ since(Es)
- ++ authors(Es)
- ++ references(Es)
- ++ sees(Es)
- ++ FullDesc),
- XML = xml(Title, stylesheet(Opts), Body),
- xmerl:export_simple([XML], ?SGML_EXPORT, []).
-
overview(E=#xmlElement{name = overview, content = Es}, Options) ->
Opts = init_opts(E, Options),
Title = get_text(title, Es),
@@ -843,6 +822,7 @@ overview(E=#xmlElement{name = overview, content = Es}, Options) ->
++ copyright(Es)
++ version(Es)
++ since(Es)
+ ++ deprecated(Es, "application")
++ authors(Es)
++ references(Es)
++ sees(Es)
diff --git a/lib/edoc/test/edoc_SUITE.erl b/lib/edoc/test/edoc_SUITE.erl
index c63660c8c0..2e2d5584f0 100644
--- a/lib/edoc/test/edoc_SUITE.erl
+++ b/lib/edoc/test/edoc_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -22,12 +23,12 @@
init_per_group/2,end_per_group/2]).
%% Test cases
--export([app/1,appup/1,build_std/1,build_map_module/1,otp_12008/1]).
+-export([app/1,appup/1,build_std/1,build_map_module/1,otp_12008/1, build_app/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app,appup,build_std,build_map_module,otp_12008].
+ [app,appup,build_std,build_map_module,otp_12008, build_app].
groups() ->
[].
@@ -95,3 +96,20 @@ otp_12008(Config) when is_list(Config) ->
ok = edoc:files([Un2], Opts2),
{'EXIT', error} = (catch edoc:files([Un3], Opts2)),
ok.
+
+build_app(suite) -> [];
+build_app(doc) -> ["Build a local app with nested source directories"];
+build_app(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ OutDir = filename:join(PrivDir, "myapp"),
+ Src = filename:join(DataDir, "myapp"),
+
+ ok = edoc:application(myapp, Src, [{dir, OutDir}, {subpackages, false}]),
+ true = filelib:is_regular(filename:join(OutDir, "a.html")),
+ false = filelib:is_regular(filename:join(OutDir, "b.html")),
+
+ ok = edoc:application(myapp, Src, [{dir, OutDir}]),
+ true = filelib:is_regular(filename:join(OutDir, "a.html")),
+ true = filelib:is_regular(filename:join(OutDir, "b.html")),
+ ok.
diff --git a/lib/common_test/priv/bin/.gitignore b/lib/edoc/test/edoc_SUITE_data/myapp/doc/.dummy
index e69de29bb2..e69de29bb2 100644
--- a/lib/common_test/priv/bin/.gitignore
+++ b/lib/edoc/test/edoc_SUITE_data/myapp/doc/.dummy
diff --git a/lib/edoc/test/edoc_SUITE_data/myapp/src/a.erl b/lib/edoc/test/edoc_SUITE_data/myapp/src/a.erl
new file mode 100644
index 0000000000..1b5b704551
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/myapp/src/a.erl
@@ -0,0 +1 @@
+-module(a).
diff --git a/lib/edoc/test/edoc_SUITE_data/myapp/src/src_1/b.erl b/lib/edoc/test/edoc_SUITE_data/myapp/src/src_1/b.erl
new file mode 100644
index 0000000000..6d6f15dfe5
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/myapp/src/src_1/b.erl
@@ -0,0 +1 @@
+-module(b).
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index 24cfbf16d5..83514ac94f 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.16
+EDOC_VSN = 0.7.18
diff --git a/lib/eldap/Makefile b/lib/eldap/Makefile
index 3635ec759d..4b12717692 100644
--- a/lib/eldap/Makefile
+++ b/lib/eldap/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/eldap/asn1/ELDAPv3.asn1 b/lib/eldap/asn1/ELDAPv3.asn1
index 72b87d7221..3fe7e815cc 100644
--- a/lib/eldap/asn1/ELDAPv3.asn1
+++ b/lib/eldap/asn1/ELDAPv3.asn1
@@ -274,5 +274,17 @@ IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
responseName [0] LDAPOID OPTIONAL,
responseValue [1] OCTET STRING OPTIONAL }
+-- Extended syntax for Password Modify (RFC 3062, Section 2)
+
+-- passwdModifyOID OBJECT IDENTIFIER ::= 1.3.6.1.4.1.4203.1.11.1
+
+PasswdModifyRequestValue ::= SEQUENCE {
+ userIdentity [0] OCTET STRING OPTIONAL,
+ oldPasswd [1] OCTET STRING OPTIONAL,
+ newPasswd [2] OCTET STRING OPTIONAL }
+
+PasswdModifyResponseValue ::= SEQUENCE {
+ genPasswd [0] OCTET STRING OPTIONAL }
+
END
diff --git a/lib/eldap/doc/src/Makefile b/lib/eldap/doc/src/Makefile
index a4827793f4..ac869e446f 100644
--- a/lib/eldap/doc/src/Makefile
+++ b/lib/eldap/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/eldap/doc/src/book.xml b/lib/eldap/doc/src/book.xml
index 0056d99d9b..2d938fb074 100644
--- a/lib/eldap/doc/src/book.xml
+++ b/lib/eldap/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index 945379d5d2..43873e44e2 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2012</year><year>2013</year>
+ <year>2012</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -28,7 +29,7 @@
<rev>B</rev>
</header>
<module>eldap</module>
- <modulesummary>Eldap Functions</modulesummary>
+ <modulesummary>LDAP Client</modulesummary>
<description>
<p>This module provides a client api to the Lightweight Directory Access Protocol (LDAP).
</p>
@@ -39,20 +40,67 @@
</list>
<p>The above publications can be found at <url href="http://www.ietf.org">IETF</url>.
</p>
- <p><em>Types</em></p>
- <pre>
-handle() Connection handle
-attribute() {Type = string(), Values=[string()]}
-modify_op() See mod_add/2, mod_delete/2, mod_replace/2
-scope() See baseObject/0, singleLevel/0, wholeSubtree/0
-dereference() See neverDerefAliases/0, derefInSearching/0, derefFindingBaseObj/0, derefAlways/0
-filter() See present/1, substrings/2,
- equalityMatch/2, greaterOrEqual/2, lessOrEqual/2,
- approxMatch/2, extensibleMatch/2,
- 'and'/1, 'or'/1, 'not'/1.
- </pre>
- <p></p>
</description>
+
+ <section>
+ <title>DATA TYPES</title>
+ <p>Type definitions that are used more than once in this module:
+ </p>
+ <taglist>
+ <tag><c>handle()</c></tag>
+ <item><p>Connection handle</p></item>
+
+ <tag><c>attribute() =</c></tag>
+ <item><p><c>{Type = string(), Values=[string()]}</c></p></item>
+
+ <tag><c>modify_op()</c></tag>
+ <item><p>See
+ <seealso marker="#mod_add/2">mod_add/2</seealso>,
+ <seealso marker="#mod_delete/2">mod_delete/2</seealso>,
+ <seealso marker="#mod_replace/2">mod_replace/2</seealso>
+ </p></item>
+
+ <tag><c>scope()</c></tag>
+ <item><p>See
+ <seealso marker="#baseObject/0">baseObject/0</seealso>,
+ <seealso marker="#singleLevel/0">singleLevel/0</seealso>,
+ <seealso marker="#wholeSubtree/0">wholeSubtree/0</seealso>
+ </p></item>
+
+ <tag><c>dereference()</c></tag>
+ <item><p>See
+ <seealso marker="#neverDerefAliases/0">neverDerefAliases/0</seealso>,
+ <seealso marker="#derefInSearching/0">derefInSearching/0</seealso>,
+ <seealso marker="#derefFindingBaseObj/0">derefFindingBaseObj/0</seealso>,
+ <seealso marker="#derefAlways/0">derefAlways/0</seealso>
+ </p></item>
+
+ <tag><c>filter()</c></tag>
+ <item><p>See
+ <seealso marker="#present/1">present/1</seealso>,
+ <seealso marker="#substrings/2">substrings/2</seealso>,
+ <seealso marker="#equalityMatch/2">equalityMatch/2</seealso>,
+ <seealso marker="#greaterOrEqual/2">greaterOrEqual/2</seealso>,
+ <seealso marker="#lessOrEqual/2">lessOrEqual/2</seealso>,
+ <seealso marker="#approxMatch/2">approxMatch/2</seealso>,
+ <seealso marker="#extensibleMatch/2">extensibleMatch/2</seealso>,
+ <seealso marker="#'and'/1">'and'/1</seealso>,
+ <seealso marker="#'or'/1">'or'/1</seealso>,
+ <seealso marker="#'not'/1">'not'/1</seealso>
+ </p></item>
+
+ <tag><c>return_value() = </c></tag>
+ <item><p><c>ok | {ok, {referral,referrals()}} | {error,Error}</c>
+ </p></item>
+
+ <tag><c>referrals() =</c></tag>
+ <item><p><c>[Address = string()]</c> The contents of <c>Address</c> is server dependent.
+ </p></item>
+
+ </taglist>
+ </section>
+
+
<funcs>
<func>
<name>open([Host]) -> {ok, Handle} | {error, Reason}</name>
@@ -87,18 +135,19 @@ filter() See present/1, substrings/2,
<v>Handle = handle()</v>
</type>
<desc>
- <p>Shutdown the connection.</p>
+ <p>Shutdown the connection after sending an unbindRequest to the server. If the connection is tls the connection
+ will be closed with <c>ssl:close/1</c>, otherwise with <c>gen_tcp:close/1</c>.</p>
</desc>
</func>
<func>
- <name>start_tls(Handle, Options) -> ok | {error,Error}</name>
+ <name>start_tls(Handle, Options) -> return_value()</name>
<fsummary>Upgrade a connection to TLS.</fsummary>
<desc>
<p>Same as start_tls(Handle, Options, infinity)</p>
</desc>
</func>
<func>
- <name>start_tls(Handle, Options, Timeout) -> ok | {error,Error}</name>
+ <name>start_tls(Handle, Options, Timeout) -> return_value()</name>
<fsummary>Upgrade a connection to TLS.</fsummary>
<type>
<v>Handle = handle()</v>
@@ -121,13 +170,13 @@ filter() See present/1, substrings/2,
<item>Any error responded from ssl:connect/3</item>
</taglist>
<p>The <c>Timeout</c> parameter is for the actual tls upgrade (phase 2) while the timeout in
- <seealso marker="#open/2">erl_tar:open/2</seealso> is used for the initial negotiation about
+ <seealso marker="#open/2">eldap:open/2</seealso> is used for the initial negotiation about
upgrade (phase 1).
</p>
</desc>
</func>
<func>
- <name>simple_bind(Handle, Dn, Password) -> ok | {error, Reason}</name>
+ <name>simple_bind(Handle, Dn, Password) -> return_value()</name>
<fsummary>Authenticate the connection.</fsummary>
<type>
<v>Handle = handle()</v>
@@ -139,7 +188,7 @@ filter() See present/1, substrings/2,
</desc>
</func>
<func>
- <name>add(Handle, Dn, [Attribute]) -> ok | {error, Reason}</name>
+ <name>add(Handle, Dn, [Attribute]) -> return_value()</name>
<fsummary>Add an entry.</fsummary>
<type>
<v>Handle = handle()</v>
@@ -160,7 +209,7 @@ filter() See present/1, substrings/2,
</desc>
</func>
<func>
- <name>delete(Handle, Dn) -> ok | {error, Reason}</name>
+ <name>delete(Handle, Dn) -> return_value()</name>
<fsummary>Delete an entry.</fsummary>
<type>
<v>Dn = string()</v>
@@ -202,7 +251,7 @@ filter() See present/1, substrings/2,
</func>
<func>
- <name>modify(Handle, Dn, [ModifyOp]) -> ok | {error, Reason}</name>
+ <name>modify(Handle, Dn, [ModifyOp]) -> return_value()</name>
<fsummary>Modify an entry.</fsummary>
<type>
<v>Dn = string()</v>
@@ -218,7 +267,47 @@ filter() See present/1, substrings/2,
</desc>
</func>
<func>
- <name>modify_dn(Handle, Dn, NewRDN, DeleteOldRDN, NewSupDN) -> ok | {error, Reason}</name>
+ <name>modify_password(Handle, Dn, NewPasswd) -> return_value() | {ok, GenPasswd}</name>
+ <fsummary>Modify the password of a user.</fsummary>
+ <type>
+ <v>Dn = string()</v>
+ <v>NewPasswd = string()</v>
+ </type>
+ <desc>
+ <p>Modify the password of a user. See <seealso marker="#modify_password/4">modify_password/4</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>modify_password(Handle, Dn, NewPasswd, OldPasswd) -> return_value() | {ok, GenPasswd}</name>
+ <fsummary>Modify the password of a user.</fsummary>
+ <type>
+ <v>Dn = string()</v>
+ <v>NewPasswd = string()</v>
+ <v>OldPasswd = string()</v>
+ <v>GenPasswd = string()</v>
+ </type>
+ <desc>
+ <p>Modify the password of a user.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>Dn</c>. The user to modify. Should be "" if the
+ modify request is for the user of the LDAP session.</p>
+ </item>
+ <item>
+ <p><c>NewPasswd</c>. The new password to set. Should be ""
+ if the server is to generate the password. In this case,
+ the result will be <c>{ok, GenPasswd}</c>.</p>
+ </item>
+ <item>
+ <p><c>OldPasswd</c>. Sometimes required by server policy
+ for a user to change their password. If not required, use
+ <seealso marker="#modify_password/3">modify_password/3</seealso>.</p>
+ </item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name>modify_dn(Handle, Dn, NewRDN, DeleteOldRDN, NewSupDN) -> return_value()</name>
<fsummary>Modify the DN of an entry.</fsummary>
<type>
<v>Dn = string()</v>
@@ -238,7 +327,7 @@ filter() See present/1, substrings/2,
</desc>
</func>
<func>
- <name>search(Handle, SearchOptions) -> {ok, #eldap_search_result{}} | {error, Reason}</name>
+ <name>search(Handle, SearchOptions) -> {ok, #eldap_search_result{}} | {ok, {referral,referrals()}} | {error, Reason}</name>
<fsummary>Search the Directory</fsummary>
<type>
<v>SearchOptions = #eldap_search{} | [SearchOption]</v>
@@ -258,7 +347,7 @@ filter() See present/1, substrings/2,
search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]),
</pre>
<p>The <c>timeout</c> option in the <c>SearchOptions</c> is for the ldap server, while
- the timeout in <seealso marker="#open/2">erl_tar:open/2</seealso> is used for each
+ the timeout in <seealso marker="#open/2">eldap:open/2</seealso> is used for each
individual request in the search operation.
</p>
</desc>
@@ -363,7 +452,11 @@ filter() See present/1, substrings/2,
<v>OptionalAttrs = [Attr]</v>
<v>Attr = {matchingRule,string()} | {type,string()} | {dnAttributes,boolean()}</v>
</type>
- <desc> <p>Creates an extensible match filter. For example, <c>eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}]))</c> 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>
+ <desc> <p>Creates an extensible match filter. For example, </p>
+ <code>
+ 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>
<func>
<name>'and'([Filter]) -> filter()</name>
diff --git a/lib/eldap/doc/src/notes.xml b/lib/eldap/doc/src/notes.xml
index e76101c30e..04b75f9e31 100644
--- a/lib/eldap/doc/src/notes.xml
+++ b/lib/eldap/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,53 @@
</header>
<p>This document describes the changes made to the Eldap application.</p>
+<section><title>Eldap 1.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ ELDAP did not send an <c>'unBind'</c> request before
+ closing the connection.</p>
+ <p>
+ Own Id: OTP-13327</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Handles the <c>referral</c> result code from LDAP
+ servers. Adds the return value <c>{ok,
+ {referral,UrlList}}</c> to some functions. See the Eldap
+ reference manual for details.</p>
+ <p>
+ Own Id: OTP-12272</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eldap 1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Support added for LDAP Password Modify Extended Operation
+ (RFC 3062). Thanks to danielwhite.</p>
+ <p>
+ Own Id: OTP-12282</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eldap 1.1.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/eldap/doc/src/ref_man.xml b/lib/eldap/doc/src/ref_man.xml
index 8af5030c58..b70529635f 100644
--- a/lib/eldap/doc/src/ref_man.xml
+++ b/lib/eldap/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/eldap/doc/src/release_notes.xml b/lib/eldap/doc/src/release_notes.xml
index e29a0ffce7..65a277b657 100644
--- a/lib/eldap/doc/src/release_notes.xml
+++ b/lib/eldap/doc/src/release_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/eldap/doc/src/usersguide.xml b/lib/eldap/doc/src/usersguide.xml
index 3a9a8e1060..38190c5a7b 100644
--- a/lib/eldap/doc/src/usersguide.xml
+++ b/lib/eldap/doc/src/usersguide.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/eldap/src/Makefile b/lib/eldap/src/Makefile
index 2e1110ec2c..cd3c102f55 100644
--- a/lib/eldap/src/Makefile
+++ b/lib/eldap/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2012-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/eldap/src/eldap.appup.src b/lib/eldap/src/eldap.appup.src
index 9d77faf740..f2a57fa945 100644
--- a/lib/eldap/src/eldap.appup.src
+++ b/lib/eldap/src/eldap.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index 80718bc106..0c03021bd0 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -10,15 +10,23 @@
%%% See MIT-LICENSE at the top dir for licensing information.
%%% --------------------------------------------------------------------
-vc('$Id$ ').
--export([open/1,open/2,simple_bind/3,controlling_process/2,
- start_tls/2, start_tls/3,
+-export([open/1, open/2,
+ simple_bind/3, simple_bind/4,
+ controlling_process/2,
+ start_tls/2, start_tls/3, start_tls/4,
+ modify_password/3, modify_password/4, modify_password/5,
getopts/2,
baseObject/0,singleLevel/0,wholeSubtree/0,close/1,
equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
extensibleMatch/2,
- approxMatch/2,search/2,substrings/2,present/1,
- 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,
- mod_replace/2, add/3, delete/2, modify_dn/5,parse_dn/1,
+ search/2, search/3,
+ approxMatch/2,substrings/2,present/1,
+ 'and'/1,'or'/1,'not'/1,mod_add/2, mod_delete/2,
+ mod_replace/2,
+ modify/3, modify/4,
+ add/3, add/4,
+ delete/2, delete/3,
+ modify_dn/5,parse_dn/1,
parse_ldap_url/1]).
-export([neverDerefAliases/0, derefInSearching/0,
@@ -90,7 +98,31 @@ start_tls(Handle, TlsOptions) ->
start_tls(Handle, TlsOptions, infinity).
start_tls(Handle, TlsOptions, Timeout) ->
- send(Handle, {start_tls,TlsOptions,Timeout}),
+ start_tls(Handle, TlsOptions, Timeout, asn1_NOVALUE).
+
+start_tls(Handle, TlsOptions, Timeout, Controls) ->
+ send(Handle, {start_tls,TlsOptions,Timeout,Controls}),
+ recv(Handle).
+
+%%% --------------------------------------------------------------------
+%%% Modify the password of a user.
+%%%
+%%% Dn - Name of the entry to modify. If empty, the session user.
+%%% NewPasswd - New password. If empty, the server returns a new password.
+%%% OldPasswd - Original password for server verification, may be empty.
+%%%
+%%% Returns: ok | {ok, GenPasswd} | {error, term()}
+%%% --------------------------------------------------------------------
+modify_password(Handle, Dn, NewPasswd) ->
+ modify_password(Handle, Dn, NewPasswd, []).
+
+modify_password(Handle, Dn, NewPasswd, OldPasswd)
+ when is_pid(Handle), is_list(Dn), is_list(NewPasswd), is_list(OldPasswd) ->
+ modify_password(Handle, Dn, NewPasswd, OldPasswd, asn1_NOVALUE).
+
+modify_password(Handle, Dn, NewPasswd, OldPasswd, Controls)
+ when is_pid(Handle), is_list(Dn), is_list(NewPasswd), is_list(OldPasswd) ->
+ send(Handle, {passwd_modify,optional(Dn),optional(NewPasswd),optional(OldPasswd),Controls}),
recv(Handle).
%%% --------------------------------------------------------------------
@@ -129,7 +161,10 @@ controlling_process(Handle, Pid) when is_pid(Handle), is_pid(Pid) ->
%%% Returns: ok | {error, Error}
%%% --------------------------------------------------------------------
simple_bind(Handle, Dn, Passwd) when is_pid(Handle) ->
- send(Handle, {simple_bind, Dn, Passwd}),
+ simple_bind(Handle, Dn, Passwd, asn1_NOVALUE).
+
+simple_bind(Handle, Dn, Passwd, Controls) when is_pid(Handle) ->
+ send(Handle, {simple_bind, Dn, Passwd, Controls}),
recv(Handle).
%%% --------------------------------------------------------------------
@@ -146,7 +181,10 @@ simple_bind(Handle, Dn, Passwd) when is_pid(Handle) ->
%%% )
%%% --------------------------------------------------------------------
add(Handle, Entry, Attributes) when is_pid(Handle),is_list(Entry),is_list(Attributes) ->
- send(Handle, {add, Entry, add_attrs(Attributes)}),
+ add(Handle, Entry, Attributes, asn1_NOVALUE).
+
+add(Handle, Entry, Attributes, Controls) when is_pid(Handle),is_list(Entry),is_list(Attributes) ->
+ send(Handle, {add, Entry, add_attrs(Attributes), Controls}),
recv(Handle).
%%% Do sanity check !
@@ -170,7 +208,10 @@ add_attrs(Attrs) ->
%%% )
%%% --------------------------------------------------------------------
delete(Handle, Entry) when is_pid(Handle), is_list(Entry) ->
- send(Handle, {delete, Entry}),
+ delete(Handle, Entry, asn1_NOVALUE).
+
+delete(Handle, Entry, Controls) when is_pid(Handle), is_list(Entry) ->
+ send(Handle, {delete, Entry, Controls}),
recv(Handle).
%%% --------------------------------------------------------------------
@@ -185,7 +226,10 @@ delete(Handle, Entry) when is_pid(Handle), is_list(Entry) ->
%%% )
%%% --------------------------------------------------------------------
modify(Handle, Object, Mods) when is_pid(Handle), is_list(Object), is_list(Mods) ->
- send(Handle, {modify, Object, Mods}),
+ modify(Handle, Object, Mods, asn1_NOVALUE).
+
+modify(Handle, Object, Mods, Controls) when is_pid(Handle), is_list(Object), is_list(Mods) ->
+ send(Handle, {modify, Object, Mods, Controls}),
recv(Handle).
%%%
@@ -218,8 +262,12 @@ m(Operation, Type, Values) ->
%%% --------------------------------------------------------------------
modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup)
when is_pid(Handle),is_list(Entry),is_list(NewRDN),is_atom(DelOldRDN),is_list(NewSup) ->
+ modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup, asn1_NOVALUE).
+
+modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup, Controls)
+ when is_pid(Handle),is_list(Entry),is_list(NewRDN),is_atom(DelOldRDN),is_list(NewSup) ->
send(Handle, {modify_dn, Entry, NewRDN,
- bool_p(DelOldRDN), optional(NewSup)}),
+ bool_p(DelOldRDN), optional(NewSup), Controls}),
recv(Handle).
%%% Sanity checks !
@@ -254,16 +302,19 @@ optional(Value) -> Value.
%%% []}}
%%%
%%% --------------------------------------------------------------------
-search(Handle, A) when is_pid(Handle), is_record(A, eldap_search) ->
- call_search(Handle, A);
-search(Handle, L) when is_pid(Handle), is_list(L) ->
+search(Handle, X) when is_pid(Handle), is_record(X,eldap_search) ; is_list(X) ->
+ search(Handle, X, asn1_NOVALUE).
+
+search(Handle, A, Controls) when is_pid(Handle), is_record(A, eldap_search) ->
+ call_search(Handle, A, Controls);
+search(Handle, L, Controls) when is_pid(Handle), is_list(L) ->
case catch parse_search_args(L) of
{error, Emsg} -> {error, Emsg};
- A when is_record(A, eldap_search) -> call_search(Handle, A)
+ A when is_record(A, eldap_search) -> call_search(Handle, A, Controls)
end.
-call_search(Handle, A) ->
- send(Handle, {search, A}),
+call_search(Handle, A, Controls) ->
+ send(Handle, {search, A, Controls}),
recv(Handle).
parse_search_args(Args) ->
@@ -466,33 +517,33 @@ do_connect(Host, Data, Opts) when Data#eldap.ldaps == true ->
loop(Cpid, Data) ->
receive
- {From, {search, A}} ->
- {Res,NewData} = do_search(Data, A),
+ {From, {search, A, Controls}} ->
+ {Res,NewData} = do_search(Data, A, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
- {From, {modify, Obj, Mod}} ->
- {Res,NewData} = do_modify(Data, Obj, Mod),
+ {From, {modify, Obj, Mod, Controls}} ->
+ {Res,NewData} = do_modify(Data, Obj, Mod, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
- {From, {modify_dn, Obj, NewRDN, DelOldRDN, NewSup}} ->
- {Res,NewData} = do_modify_dn(Data, Obj, NewRDN, DelOldRDN, NewSup),
+ {From, {modify_dn, Obj, NewRDN, DelOldRDN, NewSup, Controls}} ->
+ {Res,NewData} = do_modify_dn(Data, Obj, NewRDN, DelOldRDN, NewSup, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
- {From, {add, Entry, Attrs}} ->
- {Res,NewData} = do_add(Data, Entry, Attrs),
+ {From, {add, Entry, Attrs, Controls}} ->
+ {Res,NewData} = do_add(Data, Entry, Attrs, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
- {From, {delete, Entry}} ->
- {Res,NewData} = do_delete(Data, Entry),
+ {From, {delete, Entry, Controls}} ->
+ {Res,NewData} = do_delete(Data, Entry, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
- {From, {simple_bind, Dn, Passwd}} ->
- {Res,NewData} = do_simple_bind(Data, Dn, Passwd),
+ {From, {simple_bind, Dn, Passwd, Controls}} ->
+ {Res,NewData} = do_simple_bind(Data, Dn, Passwd, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
@@ -502,12 +553,18 @@ loop(Cpid, Data) ->
?PRINT("New Cpid is: ~p~n",[NewCpid]),
?MODULE:loop(NewCpid, Data);
- {From, {start_tls,TlsOptions,Timeout}} ->
- {Res,NewData} = do_start_tls(Data, TlsOptions, Timeout),
+ {From, {start_tls,TlsOptions,Timeout,Controls}} ->
+ {Res,NewData} = do_start_tls(Data, TlsOptions, Timeout, Controls),
send(From,Res),
?MODULE:loop(Cpid, NewData);
+ {From, {passwd_modify,Dn,NewPasswd,OldPasswd,Controls}} ->
+ {Res,NewData} = do_passwd_modify(Data, Dn, NewPasswd, OldPasswd, Controls),
+ send(From, Res),
+ ?MODULE:loop(Cpid, NewData);
+
{_From, close} ->
+ {no_reply,_NewData} = do_unbind(Data),
unlink(Cpid),
exit(closed);
@@ -555,11 +612,10 @@ loop(Cpid, Data) ->
%%% --------------------------------------------------------------------
%%% startTLS Request
%%% --------------------------------------------------------------------
-
-do_start_tls(Data=#eldap{using_tls=true}, _, _) ->
+do_start_tls(Data=#eldap{using_tls=true}, _, _, _) ->
{{error,tls_already_started}, Data};
-do_start_tls(Data=#eldap{fd=FD} , TlsOptions, Timeout) ->
- case catch exec_start_tls(Data) of
+do_start_tls(Data=#eldap{fd=FD} , TlsOptions, Timeout, Controls) ->
+ case catch exec_start_tls(Data, Controls) of
{ok,NewData} ->
case ssl:connect(FD,TlsOptions,Timeout) of
{ok, SslSocket} ->
@@ -570,15 +626,16 @@ do_start_tls(Data=#eldap{fd=FD} , TlsOptions, Timeout) ->
{error,Error} ->
{{error,Error}, Data}
end;
- {error,Error} -> {{error,Error},Data};
- Else -> {{error,Else},Data}
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
+ {error,Error} -> {{error,Error},Data};
+ Else -> {{error,Else},Data}
end.
-define(START_TLS_OID, "1.3.6.1.4.1.1466.20037").
-exec_start_tls(Data) ->
+exec_start_tls(Data, Controls) ->
Req = #'ExtendedRequest'{requestName = ?START_TLS_OID},
- Reply = request(Data#eldap.fd, Data, Data#eldap.id, {extendedReq, Req}),
+ Reply = request(Data#eldap.fd, Data, Data#eldap.id, {extendedReq, Req, Controls}),
exec_extended_req_reply(Data, Reply).
exec_extended_req_reply(Data, {ok,Msg}) when
@@ -588,6 +645,8 @@ exec_extended_req_reply(Data, {ok,Msg}) when
case Result#'ExtendedResponse'.resultCode of
success ->
{ok,Data};
+ referral ->
+ {{ok, {referral,Result#'ExtendedResponse'.referral}}, Data};
Error ->
{error, {response,Error}}
end;
@@ -603,30 +662,32 @@ exec_extended_req_reply(_, Error) ->
%%% Authenticate ourselves to the directory using
%%% simple authentication.
-do_simple_bind(Data, anon, anon) -> %% For testing
- do_the_simple_bind(Data, "", "");
-do_simple_bind(Data, Dn, _Passwd) when Dn=="",Data#eldap.anon_auth==false ->
+do_simple_bind(Data, anon, anon, Controls) -> %% For testing
+ do_the_simple_bind(Data, "", "", Controls);
+do_simple_bind(Data, Dn, _Passwd,_) when Dn=="",Data#eldap.anon_auth==false ->
{{error,anonymous_auth},Data};
-do_simple_bind(Data, _Dn, Passwd) when Passwd=="",Data#eldap.anon_auth==false ->
+do_simple_bind(Data, _Dn, Passwd,_) when Passwd=="",Data#eldap.anon_auth==false ->
{{error,anonymous_auth},Data};
-do_simple_bind(Data, Dn, Passwd) ->
- do_the_simple_bind(Data, Dn, Passwd).
+do_simple_bind(Data, Dn, Passwd, Controls) ->
+ do_the_simple_bind(Data, Dn, Passwd, Controls).
-do_the_simple_bind(Data, Dn, Passwd) ->
+do_the_simple_bind(Data, Dn, Passwd, Controls) ->
case catch exec_simple_bind(Data#eldap{binddn = Dn,
passwd = Passwd,
- id = bump_id(Data)}) of
- {ok,NewData} -> {ok,NewData};
- {error,Emsg} -> {{error,Emsg},Data};
- Else -> {{error,Else},Data}
+ id = bump_id(Data)},
+ Controls) of
+ {ok,NewData} -> {ok,NewData};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
+ {error,Emsg} -> {{error,Emsg},Data};
+ Else -> {{error,Else},Data}
end.
-exec_simple_bind(Data) ->
+exec_simple_bind(Data, Controls) ->
Req = #'BindRequest'{version = Data#eldap.version,
name = Data#eldap.binddn,
authentication = {simple, Data#eldap.passwd}},
log2(Data, "bind request = ~p~n", [Req]),
- Reply = request(Data#eldap.fd, Data, Data#eldap.id, {bindRequest, Req}),
+ Reply = request(Data#eldap.fd, Data, Data#eldap.id, {bindRequest, Req, Controls}),
log2(Data, "bind reply = ~p~n", [Reply]),
exec_simple_bind_reply(Data, Reply).
@@ -636,6 +697,7 @@ exec_simple_bind_reply(Data, {ok,Msg}) when
{bindResponse, Result} ->
case Result#'BindResponse'.resultCode of
success -> {ok,Data};
+ referral -> {{ok, {referral,Result#'BindResponse'.referral}}, Data};
Error -> {error, Error}
end;
Other -> {error, Other}
@@ -648,10 +710,11 @@ exec_simple_bind_reply(_, Error) ->
%%% searchRequest
%%% --------------------------------------------------------------------
-do_search(Data, A) ->
- case catch do_search_0(Data, A) of
+do_search(Data, A, Controls) ->
+ case catch do_search_0(Data, A, Controls) of
{error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
{'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
{ok,Res,Ref,NewData} -> {{ok,polish(Res, Ref)},NewData};
{{error,Reason},NewData} -> {{error,Reason},NewData};
Else -> {ldap_closed_p(Data, Else),Data}
@@ -677,7 +740,7 @@ polish_result([H|T]) when is_record(H, 'SearchResultEntry') ->
polish_result([]) ->
[].
-do_search_0(Data, A) ->
+do_search_0(Data, A, Controls) ->
Req = #'SearchRequest'{baseObject = A#eldap_search.base,
scope = v_scope(A#eldap_search.scope),
derefAliases = v_deref(A#eldap_search.deref),
@@ -688,15 +751,15 @@ do_search_0(Data, A) ->
attributes = v_attributes(A#eldap_search.attributes)
},
Id = bump_id(Data),
- collect_search_responses(Data#eldap{id=Id}, Req, Id).
+ collect_search_responses(Data#eldap{id=Id}, Req, Id, Controls).
%%% The returned answers cames in one packet per entry
%%% mixed with possible referals
-collect_search_responses(Data, Req, ID) ->
+collect_search_responses(Data, Req, ID, Controls) ->
S = Data#eldap.fd,
log2(Data, "search request = ~p~n", [Req]),
- send_request(S, Data, ID, {searchRequest, Req}),
+ send_request(S, Data, ID, {searchRequest, Req, Controls}),
Resp = recv_response(S, Data),
log2(Data, "search reply = ~p~n", [Resp]),
collect_search_responses(Data, S, ID, Resp, [], []).
@@ -709,6 +772,8 @@ collect_search_responses(Data, S, ID, {ok,Msg}, Acc, Ref)
success ->
log2(Data, "search reply = searchResDone ~n", []),
{ok,Acc,Ref,Data};
+ referral ->
+ {{ok, {referral,R#'LDAPResult'.referral}}, Data};
Reason ->
{{error,Reason},Data}
end;
@@ -733,21 +798,22 @@ collect_search_responses(_, _, _, Else, _, _) ->
%%% addRequest
%%% --------------------------------------------------------------------
-do_add(Data, Entry, Attrs) ->
- case catch do_add_0(Data, Entry, Attrs) of
+do_add(Data, Entry, Attrs, Controls) ->
+ case catch do_add_0(Data, Entry, Attrs, Controls) of
{error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
{'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
{ok,NewData} -> {ok,NewData};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
Else -> {ldap_closed_p(Data, Else),Data}
end.
-do_add_0(Data, Entry, Attrs) ->
+do_add_0(Data, Entry, Attrs, Controls) ->
Req = #'AddRequest'{entry = Entry,
attributes = Attrs},
S = Data#eldap.fd,
Id = bump_id(Data),
log2(Data, "add request = ~p~n", [Req]),
- Resp = request(S, Data, Id, {addRequest, Req}),
+ Resp = request(S, Data, Id, {addRequest, Req, Controls}),
log2(Data, "add reply = ~p~n", [Resp]),
check_reply(Data#eldap{id = Id}, Resp, addResponse).
@@ -756,19 +822,20 @@ do_add_0(Data, Entry, Attrs) ->
%%% deleteRequest
%%% --------------------------------------------------------------------
-do_delete(Data, Entry) ->
- case catch do_delete_0(Data, Entry) of
+do_delete(Data, Entry, Controls) ->
+ case catch do_delete_0(Data, Entry, Controls) of
{error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
{'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
{ok,NewData} -> {ok,NewData};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
Else -> {ldap_closed_p(Data, Else),Data}
end.
-do_delete_0(Data, Entry) ->
+do_delete_0(Data, Entry, Controls) ->
S = Data#eldap.fd,
Id = bump_id(Data),
log2(Data, "del request = ~p~n", [Entry]),
- Resp = request(S, Data, Id, {delRequest, Entry}),
+ Resp = request(S, Data, Id, {delRequest, Entry, Controls}),
log2(Data, "del reply = ~p~n", [Resp]),
check_reply(Data#eldap{id = Id}, Resp, delResponse).
@@ -777,38 +844,97 @@ do_delete_0(Data, Entry) ->
%%% modifyRequest
%%% --------------------------------------------------------------------
-do_modify(Data, Obj, Mod) ->
- case catch do_modify_0(Data, Obj, Mod) of
+do_modify(Data, Obj, Mod, Controls) ->
+ case catch do_modify_0(Data, Obj, Mod, Controls) of
{error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
{'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
{ok,NewData} -> {ok,NewData};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
Else -> {ldap_closed_p(Data, Else),Data}
end.
-do_modify_0(Data, Obj, Mod) ->
+do_modify_0(Data, Obj, Mod, Controls) ->
v_modifications(Mod),
Req = #'ModifyRequest'{object = Obj,
changes = Mod},
S = Data#eldap.fd,
Id = bump_id(Data),
log2(Data, "modify request = ~p~n", [Req]),
- Resp = request(S, Data, Id, {modifyRequest, Req}),
+ Resp = request(S, Data, Id, {modifyRequest, Req, Controls}),
log2(Data, "modify reply = ~p~n", [Resp]),
check_reply(Data#eldap{id = Id}, Resp, modifyResponse).
%%% --------------------------------------------------------------------
+%%% PasswdModifyRequest
+%%% --------------------------------------------------------------------
+
+-define(PASSWD_MODIFY_OID, "1.3.6.1.4.1.4203.1.11.1").
+
+do_passwd_modify(Data, Dn, NewPasswd, OldPasswd, Controls) ->
+ case catch do_passwd_modify_0(Data, Dn, NewPasswd, OldPasswd, Controls) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,NewData} -> {ok,NewData};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
+ {ok,Passwd,NewData} -> {{ok, Passwd},NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+do_passwd_modify_0(Data, Dn, NewPasswd, OldPasswd, Controls) ->
+ Req = #'PasswdModifyRequestValue'{userIdentity = Dn,
+ oldPasswd = OldPasswd,
+ newPasswd = NewPasswd},
+ log2(Data, "modify password request = ~p~n", [Req]),
+ {ok, Bytes} = 'ELDAPv3':encode('PasswdModifyRequestValue', Req),
+ ExtReq = #'ExtendedRequest'{requestName = ?PASSWD_MODIFY_OID,
+ requestValue = Bytes},
+ Id = bump_id(Data),
+ log2(Data, "extended request = ~p~n", [ExtReq]),
+ Reply = request(Data#eldap.fd, Data, Id, {extendedReq, ExtReq, Controls}),
+ log2(Data, "modify password reply = ~p~n", [Reply]),
+ exec_passwd_modify_reply(Data#eldap{id = Id}, Reply).
+
+exec_passwd_modify_reply(Data, {ok,Msg}) when
+ Msg#'LDAPMessage'.messageID == Data#eldap.id ->
+ case Msg#'LDAPMessage'.protocolOp of
+ {extendedResp, Result} ->
+ case Result#'ExtendedResponse'.resultCode of
+ success ->
+ case Result#'ExtendedResponse'.responseValue of
+ asn1_NOVALUE ->
+ {ok, Data};
+ Value ->
+ case 'ELDAPv3':decode('PasswdModifyResponseValue', Value) of
+ {ok,#'PasswdModifyResponseValue'{genPasswd = Passwd}} ->
+ {ok, Passwd, Data};
+ Error ->
+ throw(Error)
+ end
+ end;
+ referral ->
+ {{ok, {referral,Result#'ExtendedResponse'.referral}}, Data};
+ Error ->
+ {error, {response,Error}}
+ end;
+ Other -> {error, Other}
+ end;
+exec_passwd_modify_reply(_, Error) ->
+ {error, Error}.
+
+%%% --------------------------------------------------------------------
%%% modifyDNRequest
%%% --------------------------------------------------------------------
-do_modify_dn(Data, Entry, NewRDN, DelOldRDN, NewSup) ->
- case catch do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) of
+do_modify_dn(Data, Entry, NewRDN, DelOldRDN, NewSup, Controls) ->
+ case catch do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup, Controls) of
{error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
{'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
{ok,NewData} -> {ok,NewData};
+ {{ok,Val},NewData} -> {{ok,Val},NewData};
Else -> {ldap_closed_p(Data, Else),Data}
end.
-do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) ->
+do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup, Controls) ->
Req = #'ModifyDNRequest'{entry = Entry,
newrdn = NewRDN,
deleteoldrdn = DelOldRDN,
@@ -816,22 +942,51 @@ do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) ->
S = Data#eldap.fd,
Id = bump_id(Data),
log2(Data, "modify DN request = ~p~n", [Req]),
- Resp = request(S, Data, Id, {modDNRequest, Req}),
+ Resp = request(S, Data, Id, {modDNRequest, Req, Controls}),
log2(Data, "modify DN reply = ~p~n", [Resp]),
check_reply(Data#eldap{id = Id}, Resp, modDNResponse).
+%%%--------------------------------------------------------------------
+%%% unbindRequest
+%%%--------------------------------------------------------------------
+do_unbind(Data) ->
+ Req = "",
+ log2(Data, "unbind request = ~p (has no reply)~n", [Req]),
+ send_request(Data#eldap.fd, Data, Data#eldap.id, {unbindRequest, Req}),
+ case Data#eldap.using_tls of
+ true -> ssl:close(Data#eldap.fd);
+ false -> gen_tcp:close(Data#eldap.fd)
+ end,
+ {no_reply, Data#eldap{binddn = (#eldap{})#eldap.binddn,
+ passwd = (#eldap{})#eldap.passwd,
+ fd = (#eldap{})#eldap.fd,
+ using_tls = false
+ }}.
+
+
%%% --------------------------------------------------------------------
%%% Send an LDAP request and receive the answer
%%% --------------------------------------------------------------------
-
request(S, Data, ID, Request) ->
send_request(S, Data, ID, Request),
recv_response(S, Data).
-send_request(S, Data, ID, Request) ->
- Message = #'LDAPMessage'{messageID = ID,
- protocolOp = Request},
- {ok,Bytes} = 'ELDAPv3':encode('LDAPMessage', Message),
+send_request(S, Data, Id, {T,P}) ->
+ send_the_LDAPMessage(S, Data, #'LDAPMessage'{messageID = Id,
+ protocolOp = {T,P}});
+send_request(S, Data, Id, {T,P,asn1_NOVALUE}) ->
+ send_the_LDAPMessage(S, Data, #'LDAPMessage'{messageID = Id,
+ protocolOp = {T,P}});
+send_request(S, Data, Id, {T,P,Controls0}) ->
+ Controls = [#'Control'{controlType=F1,
+ criticality=F2,
+ controlValue=F3} || {control,F1,F2,F3} <- Controls0],
+ send_the_LDAPMessage(S, Data, #'LDAPMessage'{messageID = Id,
+ protocolOp = {T,P},
+ controls = Controls}).
+
+send_the_LDAPMessage(S, Data, LDAPMessage) ->
+ {ok,Bytes} = 'ELDAPv3':encode('LDAPMessage', LDAPMessage),
case do_send(S, Data, Bytes) of
{error,Reason} -> throw({gen_tcp_error,Reason});
Else -> Else
@@ -865,6 +1020,7 @@ check_reply(Data, {ok,Msg}, Op) when
{Op, Result} ->
case Result#'LDAPResult'.resultCode of
success -> {ok,Data};
+ referral -> {{ok, {referral,Result#'LDAPResult'.referral}}, Data};
Error -> {error, Error}
end;
Other -> {error, Other}
diff --git a/lib/eldap/test/Makefile b/lib/eldap/test/Makefile
index 28a7a107e1..b8598546c4 100644
--- a/lib/eldap/test/Makefile
+++ b/lib/eldap/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index 137c61b2d9..8414ca6e46 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,6 +30,11 @@
-define(TIMEOUT, 120000). % 2 min
+
+%% Control to delete a referral object:
+-define(manageDsaIT, {control,"2.16.840.1.113730.3.4.2",false,asn1_NOVALUE}).
+
+
all() ->
[app,
appup,
@@ -58,6 +64,7 @@ groups() ->
{api_bound, [], [add_when_bound,
add_already_exists,
more_add,
+ add_referral,
search_filter_equalityMatch,
search_filter_substring_any,
search_filter_initial,
@@ -66,8 +73,11 @@ groups() ->
search_filter_or,
search_filter_and_not,
search_two_hits,
+ search_referral,
modify,
+ modify_referral,
delete,
+ delete_referral,
modify_dn_delete_old,
modify_dn_keep_old]},
{v4_connections, [], connection_tests()},
@@ -91,11 +101,16 @@ connection_tests() ->
init_per_suite(Config) ->
SSL_available = init_ssl_certs_et_al(Config),
- LDAP_server = find_first_server(false, [{config,eldap_server}, {config,ldap_server}, {"localhost",9876}]),
+ LDAP_server = find_first_server(false, [{config,eldap_server},
+ {config,ldap_server},
+ {"localhost",9876},
+ {"aramis.otp.ericsson.se",9876}]),
LDAPS_server =
case SSL_available of
true ->
- find_first_server(true, [{config,ldaps_server}, {"localhost",9877}]);
+ find_first_server(true, [{config,ldaps_server},
+ {"localhost",9877},
+ {"aramis.otp.ericsson.se",9877}]);
false ->
undefined
end,
@@ -453,6 +468,16 @@ more_add(Config) ->
[{"objectclass", ["organizationalUnit"]},
{"ou", ["Team"]}]).
+%%%----------------------------------------------------------------
+add_referral(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ {ok,{referral,["ldap://nowhere.example.com"++_]}} =
+ eldap:add(H, "cn=Foo Bar,dc=notHere," ++ BasePath,
+ [{"objectclass", ["person"]},
+ {"cn", ["Foo Bar"]},
+ {"sn", ["Bar"]},
+ {"telephoneNumber", ["555-1232", "555-5432"]}]).
%%%----------------------------------------------------------------
search_filter_equalityMatch(Config) ->
@@ -568,6 +593,16 @@ search_two_hits(Config) ->
[ok=eldap:delete(H,DN) || DN <- ExpectedDNs].
%%%----------------------------------------------------------------
+search_referral(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ DN = "cn=Santa Claus,dc=notHere," ++ BasePath,
+ {ok,{referral,["ldap://nowhere.example.com"++_]}} =
+ eldap:search(H, #eldap_search{base = DN,
+ filter = eldap:present("description"),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
modify(Config) ->
H = ?config(handle, Config),
BasePath = ?config(eldap_path, Config),
@@ -601,6 +636,19 @@ modify(Config) ->
restore_original_object(H, DN, OriginalAttrs).
%%%----------------------------------------------------------------
+modify_referral(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ %% The object to modify
+ DN = "cn=Foo Bar,dc=notHere," ++ BasePath,
+
+ %% Do a change
+ Mod = [eldap:mod_replace("telephoneNumber", ["555-12345"]),
+ eldap:mod_add("description", ["Nice guy"])],
+ {ok,{referral,["ldap://nowhere.example.com"++_]}} =
+ eldap:modify(H, DN, Mod).
+
+%%%----------------------------------------------------------------
delete(Config) ->
H = ?config(handle, Config),
BasePath = ?config(eldap_path, Config),
@@ -619,6 +667,14 @@ delete(Config) ->
restore_original_object(H, DN, OriginalAttrs).
%%%----------------------------------------------------------------
+delete_referral(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ %% The element to play with:
+ DN = "cn=Jonas Jonsson,dc=notHere," ++ BasePath,
+ {ok,{referral,["ldap://nowhere.example.com"++_]}} = eldap:delete(H, DN).
+
+%%%----------------------------------------------------------------
modify_dn_delete_old(Config) ->
H = ?config(handle, Config),
BasePath = ?config(eldap_path, Config),
@@ -816,25 +872,44 @@ delete_old_contents(H, Path) ->
{filter, eldap:present("objectclass")},
{scope, eldap:wholeSubtree()}])
of
- {ok, #eldap_search_result{entries=Entries}} ->
+ {ok, _R=#eldap_search_result{entries=Entries}} ->
+ case eldap:delete(H, "dc=notHere,"++Path, [?manageDsaIT]) of
+ ok -> ok;
+ {error,noSuchObject} -> ok;
+ Other -> ct:fail("eldap:delete notHere ret ~p",[Other])
+ end,
[ok = eldap:delete(H,DN) || #eldap_entry{object_name=DN} <- Entries];
_Res ->
ignore
end.
+
+-define(ok(X), ok(?MODULE,?LINE,X)).
+
add_new_contents(H, Path, MyHost) ->
- ok(eldap:add(H,"dc=ericsson,dc=se",
+ ?ok(eldap:add(H,"dc=ericsson,dc=se",
[{"objectclass", ["dcObject", "organization"]},
{"dc", ["ericsson"]},
{"o", ["Testing"]}])),
- ok(eldap:add(H,Path,
+ ?ok(eldap:add(H,Path,
[{"objectclass", ["dcObject", "organization"]},
{"dc", [MyHost]},
- {"o", ["Test machine"]}])).
+ {"o", ["Test machine"]}])),
+ ?ok(eldap:add(H, "dc=notHere,"++Path,
+ [{"objectclass", ["referral",
+ "dcObject"
+ ]},
+ {"ref", ["ldap://nowhere.example.com/notHere,"++Path]},
+ {"dc", ["notHere"]}
+ ])).
+
-ok({error,entryAlreadyExists}) -> ok;
-ok(X) -> ok=X.
+ok(_, _, {error,entryAlreadyExists}) -> ok;
+ok(_, _, ok) -> ok;
+ok(MODULE, LINE, X) ->
+ ct:pal("~p:~p add_new_contents: ret from eldap:add = ~p",[MODULE,LINE,X]),
+ X.
@@ -896,9 +971,9 @@ client_timeout(Fun, Config) ->
T = 1000,
case eldap:open([Host], [{timeout,T},{port,Port}|Opts]) of
{ok,H} ->
- T0 = now(),
+ T0 = erlang:monotonic_time(),
{error,{gen_tcp_error,timeout}} = Fun(H),
- T_op = diff(T0,now()),
+ T_op = ms_passed(T0),
ct:log("Time = ~p, Timeout spec = ~p",[T_op,T]),
if
T_op < T ->
@@ -910,8 +985,12 @@ client_timeout(Fun, Config) ->
Other -> ct:fail("eldap:open failed: ~p",[Other])
end.
-diff({M1,S1,U1},{M2,S2,U2}) ->
- ( ((M2-M1)*1000 + (S2-S1))*1000 + (U2-U1) ).
+%% Help function, elapsed milliseconds since T0
+ms_passed(T0) ->
+ %% OTP 18
+ erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native,
+ micro_seconds) / 1000.
%%%----------------------------------------------------------------
init_ssl_certs_et_al(Config) ->
diff --git a/lib/eldap/test/make_certs.erl b/lib/eldap/test/make_certs.erl
index 15a7e118ff..74ee04a361 100644
--- a/lib/eldap/test/make_certs.erl
+++ b/lib/eldap/test/make_certs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/eldap/vsn.mk b/lib/eldap/vsn.mk
index adca41ed63..99c474d588 100644
--- a/lib/eldap/vsn.mk
+++ b/lib/eldap/vsn.mk
@@ -1 +1 @@
-ELDAP_VSN = 1.1.1
+ELDAP_VSN = 1.2.1
diff --git a/lib/erl_docgen/Makefile b/lib/erl_docgen/Makefile
index 19b129fd5d..2f62db3442 100644
--- a/lib/erl_docgen/Makefile
+++ b/lib/erl_docgen/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/doc/src/Makefile b/lib/erl_docgen/doc/src/Makefile
index 8d8dd0dd55..3a6d3d04c6 100644
--- a/lib/erl_docgen/doc/src/Makefile
+++ b/lib/erl_docgen/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2011-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/erl_docgen/doc/src/block_tags.xml b/lib/erl_docgen/doc/src/block_tags.xml
index 9048d89e87..cf8c425bc2 100644
--- a/lib/erl_docgen/doc/src/block_tags.xml
+++ b/lib/erl_docgen/doc/src/block_tags.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/book.xml b/lib/erl_docgen/doc/src/book.xml
index 2ff26ba5a1..2fa02e359a 100644
--- a/lib/erl_docgen/doc/src/book.xml
+++ b/lib/erl_docgen/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/character_entities.xml b/lib/erl_docgen/doc/src/character_entities.xml
index f484ac2201..e189d7cb6c 100644
--- a/lib/erl_docgen/doc/src/character_entities.xml
+++ b/lib/erl_docgen/doc/src/character_entities.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/doc-build.xml b/lib/erl_docgen/doc/src/doc-build.xml
index 95cfd367aa..76129128eb 100644
--- a/lib/erl_docgen/doc/src/doc-build.xml
+++ b/lib/erl_docgen/doc/src/doc-build.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>How to Build OTP like documentation</title>
diff --git a/lib/erl_docgen/doc/src/docgen_xml_check.xml b/lib/erl_docgen/doc/src/docgen_xml_check.xml
index 04ff25c8af..2351463770 100644
--- a/lib/erl_docgen/doc/src/docgen_xml_check.xml
+++ b/lib/erl_docgen/doc/src/docgen_xml_check.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/erl_docgen_app.xml b/lib/erl_docgen/doc/src/erl_docgen_app.xml
index bf12f69534..58c2a24f4b 100644
--- a/lib/erl_docgen/doc/src/erl_docgen_app.xml
+++ b/lib/erl_docgen/doc/src/erl_docgen_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,7 +32,7 @@
<description>
<p>
- The application consists of the following parts
+ The application consists of the following parts:</p>
<taglist>
<tag>XSL</tag>
<item>
@@ -58,7 +59,6 @@
</p>
</item>
</taglist>
- </p>
</description>
</appref>
diff --git a/lib/erl_docgen/doc/src/fasc_dtds.xml b/lib/erl_docgen/doc/src/fasc_dtds.xml
index a00def1644..a212d58ef5 100644
--- a/lib/erl_docgen/doc/src/fasc_dtds.xml
+++ b/lib/erl_docgen/doc/src/fasc_dtds.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/header_tags.xml b/lib/erl_docgen/doc/src/header_tags.xml
index 70f7588675..76472b5cce 100644
--- a/lib/erl_docgen/doc/src/header_tags.xml
+++ b/lib/erl_docgen/doc/src/header_tags.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/inline_tags.xml b/lib/erl_docgen/doc/src/inline_tags.xml
index 2aff8bae68..187c6c308a 100644
--- a/lib/erl_docgen/doc/src/inline_tags.xml
+++ b/lib/erl_docgen/doc/src/inline_tags.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index c2f81dfcc1..f70b3c8404 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,7 +31,54 @@
</header>
<p>This document describes the changes made to the <em>erl_docgen</em> application.</p>
- <section><title>Erl_Docgen 0.3.7</title>
+ <section><title>Erl_Docgen 0.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correctly generate anno tags for maps keys</p>
+ <p>
+ Own Id: OTP-12955</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.4.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Updated the xmllint target to just check the xml
+ files with real documentation content.<br/> Corrected
+ some errors and added some missing target in the DTD's.
+ </p>
+ <p>
+ Own Id: OTP-13026</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Add possibility to add extra information on
+ documentation front pages. </p>
+ <p>
+ Own Id: OTP-12722</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.3.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/erl_docgen/doc/src/overview.xml b/lib/erl_docgen/doc/src/overview.xml
index 9985141e75..860eb02028 100644
--- a/lib/erl_docgen/doc/src/overview.xml
+++ b/lib/erl_docgen/doc/src/overview.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Overview OTP DTDs</title>
diff --git a/lib/erl_docgen/doc/src/part.xml b/lib/erl_docgen/doc/src/part.xml
index 36d0baabd0..aeed47b8c7 100644
--- a/lib/erl_docgen/doc/src/part.xml
+++ b/lib/erl_docgen/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Erl_Docgen User's Guide</title>
diff --git a/lib/erl_docgen/doc/src/ref_man.xml b/lib/erl_docgen/doc/src/ref_man.xml
index 735fb7d1c9..da05f3f1d2 100644
--- a/lib/erl_docgen/doc/src/ref_man.xml
+++ b/lib/erl_docgen/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/refman_dtds.xml b/lib/erl_docgen/doc/src/refman_dtds.xml
index 86d4272e8c..e92539d301 100644
--- a/lib/erl_docgen/doc/src/refman_dtds.xml
+++ b/lib/erl_docgen/doc/src/refman_dtds.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/doc/src/user_guide_dtds.xml b/lib/erl_docgen/doc/src/user_guide_dtds.xml
index e533fbd96c..01df6b62cb 100644
--- a/lib/erl_docgen/doc/src/user_guide_dtds.xml
+++ b/lib/erl_docgen/doc/src/user_guide_dtds.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_docgen/priv/Makefile b/lib/erl_docgen/priv/Makefile
index 18cf7b90dd..d126cafa54 100644
--- a/lib/erl_docgen/priv/Makefile
+++ b/lib/erl_docgen/priv/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/erl_docgen/priv/bin/Makefile b/lib/erl_docgen/priv/bin/Makefile
index d6d0ad2260..20c2dac936 100644
--- a/lib/erl_docgen/priv/bin/Makefile
+++ b/lib/erl_docgen/priv/bin/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
index 592b3985e4..129c5c287a 100755
--- a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
+++ b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
@@ -4,16 +4,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------------
diff --git a/lib/erl_docgen/priv/bin/specs_gen.escript b/lib/erl_docgen/priv/bin/specs_gen.escript
index 156311565c..988262e7a1 100644
--- a/lib/erl_docgen/priv/bin/specs_gen.escript
+++ b/lib/erl_docgen/priv/bin/specs_gen.escript
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -97,7 +98,7 @@ read_file(File, Opts) ->
edoc:read_source(File, Opts).
extract(File, Forms, Opts) ->
- Env = edoc_lib:get_doc_env([], [], [], _Opts=[]),
+ Env = edoc_lib:get_doc_env([], [], _Opts=[]),
{_Module, Doc} = edoc_extract:source(Forms, File, Env, Opts),
Doc.
diff --git a/lib/erl_docgen/priv/bin/xml_from_edoc.escript b/lib/erl_docgen/priv/bin/xml_from_edoc.escript
index 65a580dca2..c09bf0f91c 100755
--- a/lib/erl_docgen/priv/bin/xml_from_edoc.escript
+++ b/lib/erl_docgen/priv/bin/xml_from_edoc.escript
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------------
@@ -117,7 +118,7 @@ users_guide(File, Args) ->
Text = edoc_lib:run_layout(F, Opts),
OutFile = "chapter" ++ Args#args.suffix,
- edoc_lib:write_file(Text, ".", OutFile, '', Encoding);
+ edoc_lib:write_file(Text, ".", OutFile, Encoding);
false ->
io:format("~s: not a regular file\n", [File]),
usage()
diff --git a/lib/erl_docgen/priv/bin/xref_mod_app.escript b/lib/erl_docgen/priv/bin/xref_mod_app.escript
index c2bd62f9e0..f754d4f2e0 100755
--- a/lib/erl_docgen/priv/bin/xref_mod_app.escript
+++ b/lib/erl_docgen/priv/bin/xref_mod_app.escript
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/erl_docgen/priv/css/Makefile b/lib/erl_docgen/priv/css/Makefile
index 24abc4fa9c..4dde562337 100644
--- a/lib/erl_docgen/priv/css/Makefile
+++ b/lib/erl_docgen/priv/css/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/css/otp_doc.css b/lib/erl_docgen/priv/css/otp_doc.css
index c56de378f4..0b531db701 100644
--- a/lib/erl_docgen/priv/css/otp_doc.css
+++ b/lib/erl_docgen/priv/css/otp_doc.css
@@ -66,7 +66,7 @@ a:visited { color: blue; text-decoration: none }
span.bold_code { font-family: Courier, monospace; font-weight: bold }
span.code { font-family: Courier, monospace; font-weight: normal }
-.note, .warning {
+.note, .warning, .do, .dont {
border: solid black 1px;
margin: 1em 3em;
}
@@ -96,10 +96,41 @@ span.code { font-family: Courier, monospace; font-weight: normal }
font-size: 90%;
padding: 5px 10px;
}
+.do .label {
+ background: #30d42a;
+ color: white;
+ font-weight: bold;
+ padding: 5px 10px;
+}
+.do .content {
+ background: #eafeea;
+ color: black;
+ line-height: 120%;
+ font-size: 90%;
+ padding: 5px 10px;
+}
+.dont .label {
+ background: #C00;
+ color: white;
+ font-weight: bold;
+ padding: 5px 10px;
+}
+.dont .content {
+ background: #FFF0F0;
+ color: black;
+ line-height: 120%;
+ font-size: 90%;
+ padding: 5px 10px;
+}
.example {
background-color:#eeeeff;
padding: 0px 10px;
}
+.extrafrontpageinfo {
+ color: #C00;
+ font-weight: bold;
+ font-size: 120%;
+}
pre { font-family: Courier, monospace; font-weight: normal }
diff --git a/lib/erl_docgen/priv/dtd/Makefile b/lib/erl_docgen/priv/dtd/Makefile
index 4538b7f8e6..6ea7d6bec0 100644
--- a/lib/erl_docgen/priv/dtd/Makefile
+++ b/lib/erl_docgen/priv/dtd/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/dtd/application.dtd b/lib/erl_docgen/priv/dtd/application.dtd
index 8a1e8832ec..25ef0d1261 100644
--- a/lib/erl_docgen/priv/dtd/application.dtd
+++ b/lib/erl_docgen/priv/dtd/application.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -24,6 +25,6 @@
%common.header;
<!ELEMENT application (header,description?,include+) >
-<!ELEMENT description (%block;|quote|br|marker|warning|note)* >
+<!ELEMENT description (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT include EMPTY >
<!ATTLIST include file CDATA #REQUIRED>
diff --git a/lib/erl_docgen/priv/dtd/appref.dtd b/lib/erl_docgen/priv/dtd/appref.dtd
index 70a5ff37af..2fc1d83a30 100644
--- a/lib/erl_docgen/priv/dtd/appref.dtd
+++ b/lib/erl_docgen/priv/dtd/appref.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/book.dtd b/lib/erl_docgen/priv/dtd/book.dtd
index bb89a6d255..aa07d38658 100644
--- a/lib/erl_docgen/priv/dtd/book.dtd
+++ b/lib/erl_docgen/priv/dtd/book.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -38,7 +39,7 @@
<!ELEMENT pagetext (#PCDATA) >
<!ELEMENT preamble (contents?,preface?) >
-<!ELEMENT preface (title?,(%block;|quote|br|marker|warning|note|table)*) >
+<!ELEMENT preface (title?,(%block;|quote|br|marker|warning|note|dont|do|table)*) >
<!ELEMENT insidecover (#PCDATA|br|theheader|vfill|vspace|tt|bold|
include)* >
@@ -67,7 +68,7 @@
<!ELEMENT onepart (title?,description?,include+) >
<!ATTLIST onepart lift (yes|no) "no" >
-<!ELEMENT description (%block;|quote|br|marker|warning|note)* >
+<!ELEMENT description (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT include EMPTY >
<!ATTLIST include file CDATA #REQUIRED>
diff --git a/lib/erl_docgen/priv/dtd/bookinsidecover.dtd b/lib/erl_docgen/priv/dtd/bookinsidecover.dtd
index d6efbef6a4..ae22c45884 100644
--- a/lib/erl_docgen/priv/dtd/bookinsidecover.dtd
+++ b/lib/erl_docgen/priv/dtd/bookinsidecover.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/chapter.dtd b/lib/erl_docgen/priv/dtd/chapter.dtd
index eb2c96b04f..a4c9e4040d 100644
--- a/lib/erl_docgen/priv/dtd/chapter.dtd
+++ b/lib/erl_docgen/priv/dtd/chapter.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -29,8 +30,8 @@
<!-- Structure -->
-<!ELEMENT chapter (header,(%block;|quote|warning|note|br|
+<!ELEMENT chapter (header,(%block;|quote|warning|note|dont|do|br|
image|marker|table)*,section+) >
<!ELEMENT section (marker*,title,
- (%block;|quote|warning|note|br|image|marker|
+ (%block;|quote|warning|note|dont|do|br|image|marker|
table|section)*) >
diff --git a/lib/erl_docgen/priv/dtd/cites.dtd b/lib/erl_docgen/priv/dtd/cites.dtd
index 334574bff9..4558947db0 100644
--- a/lib/erl_docgen/priv/dtd/cites.dtd
+++ b/lib/erl_docgen/priv/dtd/cites.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -29,7 +30,7 @@
<!ELEMENT cite (id, shortdef, def, resp?) >
<!ELEMENT id (#PCDATA) >
<!ELEMENT shortdef (#PCDATA) >
-<!ELEMENT def (#PCDATA|c|em)* >
+<!ELEMENT def (#PCDATA|c|i|em)* >
<!ELEMENT resp (#PCDATA) >
<!ELEMENT c (#PCDATA) >
<!ELEMENT em (#PCDATA|c)* >
diff --git a/lib/erl_docgen/priv/dtd/common.dtd b/lib/erl_docgen/priv/dtd/common.dtd
index f999ef8ea4..961bcd3fc2 100644
--- a/lib/erl_docgen/priv/dtd/common.dtd
+++ b/lib/erl_docgen/priv/dtd/common.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -23,19 +24,23 @@
<!ENTITY % block "p|pre|code|list|taglist|codeinclude|
erleval" >
-<!ENTITY % inline "#PCDATA|c|em|term|cite|br|path|seealso|
- url|marker" >
+<!ENTITY % inline "#PCDATA|c|i|em|term|cite|br|path|seealso|
+ url|marker|anno" >
<!-- XXX -->
<!ELEMENT p (%inline;)* >
-<!ELEMENT pre (#PCDATA|seealso|url|input)* >
-<!ELEMENT input (#PCDATA|seealso|url)* >
-<!ELEMENT code (#PCDATA) >
+<!ELEMENT pre (#PCDATA|seealso|url|input|anno)* >
+<!ELEMENT input (#PCDATA|seealso|url|anno)* >
+<!ELEMENT code (#PCDATA|anno)* >
<!ATTLIST code type (erl|c|none) "none" >
<!ELEMENT quote (p)* >
<!ELEMENT warning (%block;|quote|br|marker)* >
<!ELEMENT note (%block;|quote|br|marker)* >
-<!ELEMENT c (#PCDATA) >
-<!ELEMENT em (#PCDATA|c)* >
+<!ELEMENT dont (%block;|quote|br|marker)* >
+<!ELEMENT do (%block;|quote|br|marker)* >
+<!ELEMENT c (#PCDATA|anno)* >
+<!ELEMENT i (#PCDATA|c|anno)* >
+<!ELEMENT em (#PCDATA|c|anno)* >
+<!ELEMENT anno (#PCDATA) >
<!-- XXX -->
<!ELEMENT term (termdef?) >
@@ -61,13 +66,13 @@
<!ELEMENT list (item+) >
<!ATTLIST list type (ordered|bulleted) "bulleted" >
-<!ELEMENT taglist (tag,item)+ >
-<!ELEMENT tag (#PCDATA|c|em|seealso|url|marker)* >
-<!ELEMENT item (%inline;|%block;)* >
+<!ELEMENT taglist (tag,item+)+ >
+<!ELEMENT tag (#PCDATA|c|i|em|br|seealso|url|marker|anno)* >
+<!ELEMENT item (%inline;|%block;|warning|note|dont|do)* >
<!-- References -->
-<!ELEMENT seealso (#PCDATA|c|em)* >
+<!ELEMENT seealso (#PCDATA|c|i|em|anno)* >
<!ATTLIST seealso marker CDATA #REQUIRED >
<!ELEMENT url (#PCDATA) >
<!ATTLIST url href CDATA #REQUIRED >
diff --git a/lib/erl_docgen/priv/dtd/common.entities.dtd b/lib/erl_docgen/priv/dtd/common.entities.dtd
index f893ecd070..b3b35ce049 100644
--- a/lib/erl_docgen/priv/dtd/common.entities.dtd
+++ b/lib/erl_docgen/priv/dtd/common.entities.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/common.header.dtd b/lib/erl_docgen/priv/dtd/common.header.dtd
index d422a89693..eb27dc8f97 100644
--- a/lib/erl_docgen/priv/dtd/common.header.dtd
+++ b/lib/erl_docgen/priv/dtd/common.header.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -17,8 +18,8 @@
$Id$
-->
<!ELEMENT header (copyright?,legalnotice?,title,shorttitle?,
- prepared,responsible?,docno,approved?,
- checked?,date,rev,file?) >
+ prepared?,responsible?,docno?,approved?,
+ checked?,date?,rev?,file?) >
<!--
The titlestyle attribute is only defined to make all the book.xml files
diff --git a/lib/erl_docgen/priv/dtd/common.image.dtd b/lib/erl_docgen/priv/dtd/common.image.dtd
index fc95a669dd..d97057590e 100644
--- a/lib/erl_docgen/priv/dtd/common.image.dtd
+++ b/lib/erl_docgen/priv/dtd/common.image.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/common.refs.dtd b/lib/erl_docgen/priv/dtd/common.refs.dtd
index 93592607df..4f87007a09 100644
--- a/lib/erl_docgen/priv/dtd/common.refs.dtd
+++ b/lib/erl_docgen/priv/dtd/common.refs.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -24,23 +25,25 @@
<!ENTITY % common.header SYSTEM "common.header.dtd" >
%common.header;
-<!ELEMENT description (%block;|quote|br|marker|warning|note)* >
+<!ELEMENT description (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT funcs (func)+ >
-<!ELEMENT func (name+,type_desc*,fsummary,type?,desc?) >
+<!ELEMENT func (name+,fsummary,(type|type_desc)*,desc?) >
<!-- ELEMENT name is defined in each ref dtd -->
-<!ELEMENT fsummary (#PCDATA|c|em)* >
+<!ELEMENT fsummary (#PCDATA|c|i|em|anno)* >
<!ELEMENT type (v,d?)* >
<!ATTLIST type variable CDATA #IMPLIED
+ name CDATA #IMPLIED
name_i CDATA #IMPLIED>
-<!ELEMENT v (#PCDATA) >
-<!ELEMENT d (#PCDATA|c|em)* >
-<!ELEMENT desc (%block;|quote|br|marker|warning|note|anno)* >
+<!ELEMENT v (#PCDATA|seealso)* >
+<!ELEMENT d (#PCDATA|seealso|c|i|em)* >
+<!ELEMENT desc (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT authors (aname,email)+ >
<!ELEMENT aname (#PCDATA) >
<!ELEMENT email (#PCDATA) >
<!ELEMENT section (marker*,title,(%block;|quote|br|marker|
- warning|note)*) >
+ warning|note|dont|do|section)*) >
<!ELEMENT datatypes (datatype)+ >
<!ELEMENT datatype (name+,desc?) >
-<!ELEMENT type_desc (#PCDATA) >
-<!ATTLIST type_desc variable CDATA #REQUIRED>
+<!ELEMENT type_desc (#PCDATA|anno|c|seealso)* >
+<!ATTLIST type_desc variable CDATA #IMPLIED
+ name CDATA #IMPLIED>
diff --git a/lib/erl_docgen/priv/dtd/common.table.dtd b/lib/erl_docgen/priv/dtd/common.table.dtd
index 7741da1018..59fb45dee2 100644
--- a/lib/erl_docgen/priv/dtd/common.table.dtd
+++ b/lib/erl_docgen/priv/dtd/common.table.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/comref.dtd b/lib/erl_docgen/priv/dtd/comref.dtd
index fcdea625d5..ae887d7cc9 100644
--- a/lib/erl_docgen/priv/dtd/comref.dtd
+++ b/lib/erl_docgen/priv/dtd/comref.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/cref.dtd b/lib/erl_docgen/priv/dtd/cref.dtd
index e43bb2bf51..5ccd98ed89 100644
--- a/lib/erl_docgen/priv/dtd/cref.dtd
+++ b/lib/erl_docgen/priv/dtd/cref.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/erlref.dtd b/lib/erl_docgen/priv/dtd/erlref.dtd
index 0cc5cfa06d..835407520a 100644
--- a/lib/erl_docgen/priv/dtd/erlref.dtd
+++ b/lib/erl_docgen/priv/dtd/erlref.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -31,4 +32,5 @@
<!ELEMENT name (#PCDATA) >
<!ATTLIST name name CDATA #IMPLIED
arity CDATA #IMPLIED
- clause_i CDATA #IMPLIED>
+ clause_i CDATA #IMPLIED
+ n_vars CDATA #IMPLIED>
diff --git a/lib/erl_docgen/priv/dtd/fascicules.dtd b/lib/erl_docgen/priv/dtd/fascicules.dtd
index b14276a2c0..073d0cc1d9 100644
--- a/lib/erl_docgen/priv/dtd/fascicules.dtd
+++ b/lib/erl_docgen/priv/dtd/fascicules.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/fileref.dtd b/lib/erl_docgen/priv/dtd/fileref.dtd
index 5a1cc54afe..8bfa13d4af 100644
--- a/lib/erl_docgen/priv/dtd/fileref.dtd
+++ b/lib/erl_docgen/priv/dtd/fileref.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
diff --git a/lib/erl_docgen/priv/dtd/part.dtd b/lib/erl_docgen/priv/dtd/part.dtd
index 3f97199042..6329413f0e 100644
--- a/lib/erl_docgen/priv/dtd/part.dtd
+++ b/lib/erl_docgen/priv/dtd/part.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -24,6 +25,6 @@
%common.header;
<!ELEMENT part (header,description?,include+) >
-<!ELEMENT description (%block;|quote|br|marker|warning|note)* >
+<!ELEMENT description (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT include EMPTY >
<!ATTLIST include file CDATA #REQUIRED>
diff --git a/lib/erl_docgen/priv/dtd/report.dtd b/lib/erl_docgen/priv/dtd/report.dtd
index 3d07e6e5a7..3dd1c3d347 100644
--- a/lib/erl_docgen/priv/dtd/report.dtd
+++ b/lib/erl_docgen/priv/dtd/report.dtd
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -48,7 +49,7 @@
<!ELEMENT file (#PCDATA) >
<!ELEMENT section (marker*,title,
- (%block;|quote|warning|note|br|image|marker|
+ (%block;|quote|warning|note|dont|do|br|image|marker|
table|section)*) >
<!ELEMENT p (%inline;|index)* >
<!ELEMENT pre (#PCDATA|seealso|url|input)* >
@@ -58,6 +59,8 @@
<!ELEMENT quote (p)* >
<!ELEMENT warning (%block;|quote|br|image|marker|table)* >
<!ELEMENT note (%block;|quote|br|image|marker|table)* >
+<!ELEMENT dont (%block;|quote|br|image|marker|table)* >
+<!ELEMENT do (%block;|quote|br|image|marker|table)* >
<!ELEMENT i (#PCDATA|b|c|em)* >
<!ELEMENT b (#PCDATA|i|c|em)* >
<!ELEMENT c (#PCDATA) >
diff --git a/lib/erl_docgen/priv/dtd/terms.dtd b/lib/erl_docgen/priv/dtd/terms.dtd
index 6105ec593e..c2965eb61c 100644
--- a/lib/erl_docgen/priv/dtd/terms.dtd
+++ b/lib/erl_docgen/priv/dtd/terms.dtd
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
Portions created by Ericsson are Copyright 1999-2007, Ericsson AB.
@@ -29,7 +30,7 @@
<!ELEMENT term (id, shortdef, def, resp?) >
<!ELEMENT id (#PCDATA) >
<!ELEMENT shortdef (#PCDATA) >
-<!ELEMENT def (#PCDATA|c|em)* >
+<!ELEMENT def (#PCDATA|c|i|em)* >
<!ELEMENT resp (#PCDATA) >
<!ELEMENT c (#PCDATA) >
<!ELEMENT em (#PCDATA|c)* >
diff --git a/lib/erl_docgen/priv/dtd_html_entities/Makefile b/lib/erl_docgen/priv/dtd_html_entities/Makefile
index f8a10973b2..8a853ba279 100644
--- a/lib/erl_docgen/priv/dtd_html_entities/Makefile
+++ b/lib/erl_docgen/priv/dtd_html_entities/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/dtd_man_entities/Makefile b/lib/erl_docgen/priv/dtd_man_entities/Makefile
index da4998dcbc..991a1a20c7 100644
--- a/lib/erl_docgen/priv/dtd_man_entities/Makefile
+++ b/lib/erl_docgen/priv/dtd_man_entities/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/fop.xconf b/lib/erl_docgen/priv/fop.xconf
index 70ecd608c3..1a07af5c64 100644
--- a/lib/erl_docgen/priv/fop.xconf
+++ b/lib/erl_docgen/priv/fop.xconf
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
- # The contents of this file are subject to the Erlang Public License,
- # Version 1.1, (the "License"); you may not use this file except in
- # compliance with the License. You should have received a copy of the
- # Erlang Public License along with this software. If not, it can be
- # retrieved online at http://www.erlang.org/.
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
#
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # 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%
diff --git a/lib/erl_docgen/priv/images/Makefile b/lib/erl_docgen/priv/images/Makefile
index 61016e927c..664505fa9a 100644
--- a/lib/erl_docgen/priv/images/Makefile
+++ b/lib/erl_docgen/priv/images/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/js/flipmenu/Makefile b/lib/erl_docgen/priv/js/flipmenu/Makefile
index 7933752532..287aeb3dd2 100644
--- a/lib/erl_docgen/priv/js/flipmenu/Makefile
+++ b/lib/erl_docgen/priv/js/flipmenu/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/xsl/Makefile b/lib/erl_docgen/priv/xsl/Makefile
index 58589672b8..80b3a59592 100644
--- a/lib/erl_docgen/priv/xsl/Makefile
+++ b/lib/erl_docgen/priv/xsl/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_docgen/priv/xsl/db_eix.xsl b/lib/erl_docgen/priv/xsl/db_eix.xsl
index 249e6950f7..3ca6f73bd6 100644
--- a/lib/erl_docgen/priv/xsl/db_eix.xsl
+++ b/lib/erl_docgen/priv/xsl/db_eix.xsl
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2009-2011. All Rights Reserved.
#
- # The contents of this file are subject to the Erlang Public License,
- # Version 1.1, (the "License"); you may not use this file except in
- # compliance with the License. You should have received a copy of the
- # Erlang Public License along with this software. If not, it can be
- # retrieved online at http://www.erlang.org/.
- #
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # Licensed under the Apache License, Version 2.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%
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index ab5f24c406..c2325fbee9 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
- # The contents of this file are subject to the Erlang Public License,
- # Version 1.1, (the "License"); you may not use this file except in
- # compliance with the License. You should have received a copy of the
- # Erlang Public License along with this software. If not, it can be
- # retrieved online at http://www.erlang.org/.
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
#
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # 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%
@@ -952,6 +953,36 @@
</div>
</xsl:template>
+ <!-- Do -->
+ <xsl:template match="do">
+ <xsl:param name="chapnum"/>
+ <div class="do">
+ <div class="label">Do</div>
+ <div class="content">
+ <p>
+ <xsl:apply-templates>
+ <xsl:with-param name="chapnum" select="$chapnum"/>
+ </xsl:apply-templates>
+ </p>
+ </div>
+ </div>
+ </xsl:template>
+
+ <!-- Dont -->
+ <xsl:template match="dont">
+ <xsl:param name="chapnum"/>
+ <div class="dont">
+ <div class="label">Don't</div>
+ <div class="content">
+ <p>
+ <xsl:apply-templates>
+ <xsl:with-param name="chapnum" select="$chapnum"/>
+ </xsl:apply-templates>
+ </p>
+ </div>
+ </div>
+ </xsl:template>
+
<!-- Paragraph -->
<xsl:template match="p">
<p>
@@ -959,12 +990,15 @@
</p>
</xsl:template>
-
<!-- Inline elements -->
<xsl:template match="b">
<strong><xsl:apply-templates/></strong>
</xsl:template>
+ <xsl:template match="i">
+ <i><xsl:apply-templates/></i>
+ </xsl:template>
+
<xsl:template match="br">
<br/>
</xsl:template>
@@ -1102,6 +1136,9 @@
<center><h4>Version <xsl:value-of select="$appver"/></h4></center>
<center><h4><xsl:value-of select="$gendate"/></h4></center>
+ <div class="extrafrontpageinfo">
+ <center><xsl:value-of select="$extra_front_page_info"/></center>
+ </div>
<xsl:apply-templates select="chapter"/>
@@ -1267,6 +1304,9 @@
<center><h4>Version <xsl:value-of select="$appver"/></h4></center>
<center><h4><xsl:value-of select="$gendate"/></h4></center>
+ <div class="extrafrontpageinfo">
+ <center><xsl:value-of select="$extra_front_page_info"/></center>
+ </div>
<xsl:apply-templates select="erlref|cref|comref|fileref|appref"/>
@@ -2089,6 +2129,9 @@
<center><h4>Version <xsl:value-of select="$appver"/></h4></center>
<center><h4><xsl:value-of select="$gendate"/></h4></center>
+ <div class="extrafrontpageinfo">
+ <center><xsl:value-of select="$extra_front_page_info"/></center>
+ </div>
<xsl:apply-templates select="chapter"/>
diff --git a/lib/erl_docgen/priv/xsl/db_html_params.xsl b/lib/erl_docgen/priv/xsl/db_html_params.xsl
index 2373200702..2949dbfef0 100644
--- a/lib/erl_docgen/priv/xsl/db_html_params.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html_params.xsl
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
- # The contents of this file are subject to the Erlang Public License,
- # Version 1.1, (the "License"); you may not use this file except in
- # compliance with the License. You should have received a copy of the
- # Erlang Public License along with this software. If not, it can be
- # retrieved online at http://www.erlang.org/.
- #
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # Licensed under the Apache License, Version 2.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%
diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl
index 3bcdd11c35..5201465e42 100644
--- a/lib/erl_docgen/priv/xsl/db_man.xsl
+++ b/lib/erl_docgen/priv/xsl/db_man.xsl
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
- # The contents of this file are subject to the Erlang Public License,
- # Version 1.1, (the "License"); you may not use this file except in
- # compliance with the License. You should have received a copy of the
- # Erlang Public License along with this software. If not, it can be
- # retrieved online at http://www.erlang.org/.
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
#
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # 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%
@@ -543,7 +544,29 @@
<xsl:text>&#10;</xsl:text>
</xsl:template>
- <xsl:template match="warning/p | note/p">
+ <!-- Do -->
+ <xsl:template match="do">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
+ <xsl:text>&#10;.RS -4</xsl:text>
+ <xsl:text>&#10;.B&#10;</xsl:text>
+ <xsl:text>Do:</xsl:text>
+ <xsl:text>&#10;.RE</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- Dont -->
+ <xsl:template match="dont">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
+ <xsl:text>&#10;.RS -4</xsl:text>
+ <xsl:text>&#10;.B&#10;</xsl:text>
+ <xsl:text>Dont:</xsl:text>
+ <xsl:text>&#10;.RE</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="warning/p | note/p | dont/p | do/p">
<xsl:variable name="content">
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates/>
@@ -572,6 +595,12 @@
<xsl:text>\fR\&amp; </xsl:text>
</xsl:template>
+ <xsl:template match="i">
+ <xsl:text>\fI</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>\fR\&amp; </xsl:text>
+ </xsl:template>
+
<xsl:template match="br">
<xsl:choose>
<xsl:when test="ancestor::head">
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index c15b16eb5b..37a2d55274 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -5,16 +5,17 @@
#
# 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/.
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
#
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # 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%
@@ -671,6 +672,10 @@
<fo:block xsl:use-attribute-sets="cover.version">
<xsl:value-of select="$gendate"/>
</fo:block>
+ <fo:block xsl:use-attribute-sets="cover.extrainfo">
+ <xsl:value-of select="$extra_front_page_info"/>
+ </fo:block>
+
<!-- Inner cover (copyright notice) -->
<fo:block break-before="page"
@@ -682,16 +687,18 @@
<fo:block xsl:use-attribute-sets="cover.inner.copyrightnotice">
<xsl:value-of select="/book/header/legalnotice"/>
- <!-- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ <!--
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is
-->
@@ -1138,6 +1145,31 @@
</fo:block>
</xsl:template>
+ <!-- Do -->
+ <xsl:template match="do">
+ <xsl:param name="partnum"/>
+ <fo:block xsl:use-attribute-sets="do">
+ <fo:block xsl:use-attribute-sets="note-warning-title">
+ <xsl:text>Do:</xsl:text>
+ </fo:block>
+ <xsl:apply-templates>
+ <xsl:with-param name="partnum" select="$partnum"/>
+ </xsl:apply-templates>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Dont -->
+ <xsl:template match="dont">
+ <xsl:param name="partnum"/>
+ <fo:block xsl:use-attribute-sets="dont">
+ <fo:block xsl:use-attribute-sets="note-warning-title">
+ <xsl:text>Don't:</xsl:text>
+ </fo:block>
+ <xsl:apply-templates>
+ <xsl:with-param name="partnum" select="$partnum"/>
+ </xsl:apply-templates>
+ </fo:block>
+ </xsl:template>
<!-- Paragraph -->
<xsl:template match="p">
@@ -1154,6 +1186,12 @@
</fo:inline>
</xsl:template>
+ <xsl:template match="i">
+ <fo:inline font-weight="italic">
+ <xsl:apply-templates/>
+ </fo:inline>
+ </xsl:template>
+
<xsl:template match="br">
<fo:block/>
</xsl:template>
diff --git a/lib/erl_docgen/priv/xsl/db_pdf_params.xsl b/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
index 2e3b22acf4..61c8ff75aa 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
- # The contents of this file are subject to the Erlang Public License,
- # Version 1.1, (the "License"); you may not use this file except in
- # compliance with the License. You should have received a copy of the
- # Erlang Public License along with this software. If not, it can be
- # retrieved online at http://www.erlang.org/.
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
#
- # Software distributed under the License is distributed on an "AS IS"
- # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- # the License for the specific language governing rights and limitations
- # under the License.
+ # 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%
@@ -98,6 +99,14 @@
<xsl:attribute name="text-align">end</xsl:attribute>
</xsl:attribute-set>
+ <xsl:attribute-set name="cover.extrainfo">
+ <xsl:attribute name="padding-before">2.5em</xsl:attribute>
+ <xsl:attribute name="font-size">1.33em</xsl:attribute>
+ <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <xsl:attribute name="color">#C00</xsl:attribute>
+ <xsl:attribute name="text-align">end</xsl:attribute>
+ </xsl:attribute-set>
+
<xsl:attribute-set name="cover.inner.copyright">
<xsl:attribute name="border-before-style">solid</xsl:attribute>
<xsl:attribute name="border-before-width">1pt</xsl:attribute>
@@ -289,6 +298,33 @@
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
</xsl:attribute-set>
+<xsl:attribute-set name="do">
+ <xsl:attribute name="background-color">#d0fed0</xsl:attribute>
+ <xsl:attribute name="space-after">1em</xsl:attribute>
+ <xsl:attribute name="space-before">2em</xsl:attribute>
+ <xsl:attribute name="text-align">justify</xsl:attribute>
+ <xsl:attribute name="padding-before">1em</xsl:attribute>
+ <xsl:attribute name="padding-after">0.3em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
+ <xsl:attribute name="keep-together.within-page">always</xsl:attribute>
+ </xsl:attribute-set>
+
+<xsl:attribute-set name="dont">
+ <xsl:attribute name="background-color">#ffd6d6</xsl:attribute>
+ <xsl:attribute name="space-after">1em</xsl:attribute>
+ <xsl:attribute name="space-before">2em</xsl:attribute>
+ <xsl:attribute name="text-align">justify</xsl:attribute>
+ <xsl:attribute name="padding-before">1em</xsl:attribute>
+ <xsl:attribute name="padding-after">0.3em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
+ <xsl:attribute name="keep-together.within-page">always</xsl:attribute>
+ </xsl:attribute-set>
<xsl:attribute-set name="note-warning-title">
<xsl:attribute name="font-size">1.33em</xsl:attribute>
diff --git a/lib/erl_docgen/src/Makefile b/lib/erl_docgen/src/Makefile
index ef96f5dbf2..7d41506dbd 100644
--- a/lib/erl_docgen/src/Makefile
+++ b/lib/erl_docgen/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
index e6bf9ce20e..0ac7985a48 100644
--- a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
+++ b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -351,8 +352,8 @@ otp_xmlify_e(#xmlElement{name=code} = E) -> % 4)
end;
otp_xmlify_e(#xmlElement{name=Tag} = E) % 5a
when Tag==h1; Tag==h2; Tag==h3; Tag==h4; Tag==h5 ->
- Content = text_and_a_name_only(E#xmlElement.content),
- [E#xmlElement{name=b, content=Content}];
+ {Name, Text} = text_and_a_name_only(E#xmlElement.content),
+ [Name, E#xmlElement{name=b, content=Text}];
otp_xmlify_e(#xmlElement{name=Tag} = E) % 5b-c)
when Tag==center;
Tag==font ->
@@ -1189,17 +1190,13 @@ get_text(#xmlElement{content=[#xmlText{value=Text}]}) ->
get_text(#xmlElement{content=[E]}) ->
get_text(E).
-%% text_and_name_only(Es) -> Ts
-text_and_a_name_only([#xmlElement{
- name = a,
- attributes = [#xmlAttribute{name=name}]} = Name|Es]) ->
- [Name|text_and_a_name_only(Es)];
-text_and_a_name_only([#xmlElement{content = Content}|Es]) ->
- text_and_a_name_only(Content) ++ text_and_a_name_only(Es);
-text_and_a_name_only([#xmlText{} = E |Es]) ->
- [E | text_and_a_name_only(Es)];
-text_and_a_name_only([]) ->
- [].
+%% text_and_name_only(Es) -> {N, Ts}
+text_and_a_name_only(Es) ->
+ [Name|_] = [Name ||
+ #xmlElement{
+ name = a,
+ attributes = [#xmlAttribute{name=name}]}=Name <- Es],
+ {Name#xmlElement{content = []}, text_only(Es)}.
%% text_only(Es) -> Ts
%% Takes a list of xmlElement and xmlText and return a lists of xmlText.
diff --git a/lib/erl_docgen/src/docgen_otp_specs.erl b/lib/erl_docgen/src/docgen_otp_specs.erl
index 1075c47801..e154323f07 100644
--- a/lib/erl_docgen/src/docgen_otp_specs.erl
+++ b/lib/erl_docgen/src/docgen_otp_specs.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -202,7 +203,8 @@ t_clause(Name, Type) ->
pp_clause(Pre, Type) ->
Types = ot_utype([Type]),
Atom = lists:duplicate(iolist_size(Pre), $a),
- L1 = erl_pp:attribute({attribute,0,spec,{{list_to_atom(Atom),0},[Types]}}),
+ Attr = {attribute,0,spec,{{list_to_atom(Atom),0},[Types]}},
+ L1 = erl_pp:attribute(erl_parse:new_anno(Attr)),
"-spec " ++ L2 = lists:flatten(L1),
L3 = Pre ++ lists:nthtail(length(Atom), L2),
re:replace(L3, "\n ", "\n", [{return,list},global]).
@@ -222,7 +224,8 @@ format_type(_Name, Type, _Opts) ->
pp_type(Prefix, Type) ->
Atom = list_to_atom(lists:duplicate(iolist_size(Prefix), $a)),
- L1 = erl_pp:attribute({attribute,0,type,{Atom,ot_utype(Type),[]}}),
+ Attr = {attribute,0,type,{Atom,ot_utype(Type),[]}},
+ L1 = erl_pp:attribute(erl_parse:new_anno(Attr)),
{L2,N} = case lists:dropwhile(fun(C) -> C =/= $: end, lists:flatten(L1)) of
":: " ++ L3 -> {L3,9}; % compensation for extra "()" and ":"
"::\n" ++ L3 -> {"\n"++L3,6}
@@ -569,8 +572,8 @@ ot_var(E) ->
{var,0,list_to_atom(get_attrval(name, E))}.
ot_atom(E) ->
- {ok, [Atom], _} = erl_scan:string(get_attrval(value, E), 0),
- Atom.
+ {ok, [{atom,A,Name}], _} = erl_scan:string(get_attrval(value, E), 0),
+ {atom,erl_anno:line(A),Name}.
ot_integer(E) ->
{integer,0,list_to_integer(get_attrval(value, E))}.
@@ -616,7 +619,7 @@ ot_map(Es) ->
{type,0,map,[ot_map_field(E) || E <- get_elem(map_field,Es)]}.
ot_map_field(#xmlElement{content=[K,V]}) ->
- {type,0,map_field_assoc, ot_utype_elem(K), ot_utype_elem(V)}.
+ {type,0,map_field_assoc,[ot_utype_elem(K),ot_utype_elem(V)]}.
ot_fun(Es) ->
Range = ot_utype(get_elem(type, Es)),
@@ -726,5 +729,9 @@ annos_type([E=#xmlElement{name = typevar}]) ->
annos_elem(E);
annos_type([#xmlElement{name = paren, content = Es}]) ->
annos(get_elem(type, Es));
+annos_type([#xmlElement{name = map, content = Es}]) ->
+ lists:flatmap(fun(E) -> annos_type([E]) end, Es);
+annos_type([#xmlElement{name = map_field, content = Es}]) ->
+ lists:flatmap(fun annos_elem/1, get_elem(type,Es));
annos_type(_) ->
[].
diff --git a/lib/erl_docgen/src/docgen_xmerl_xml_cb.erl b/lib/erl_docgen/src/docgen_xmerl_xml_cb.erl
index d713b61c0a..f6e003aa14 100644
--- a/lib/erl_docgen/src/docgen_xmerl_xml_cb.erl
+++ b/lib/erl_docgen/src/docgen_xmerl_xml_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/erl_docgen/src/docgen_xml_check.erl b/lib/erl_docgen/src/docgen_xml_check.erl
index 892a880269..73e90eed88 100644
--- a/lib/erl_docgen/src/docgen_xml_check.erl
+++ b/lib/erl_docgen/src/docgen_xml_check.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999-2000, Ericsson
diff --git a/lib/erl_docgen/src/erl_docgen.app.src b/lib/erl_docgen/src/erl_docgen.app.src
index e2830b2692..d63d880d89 100644
--- a/lib/erl_docgen/src/erl_docgen.app.src
+++ b/lib/erl_docgen/src/erl_docgen.app.src
@@ -9,6 +9,6 @@
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["xmerl-1.3.7","stdlib-2.0","edoc-0.7.13","erts-6.0"]}
+ {runtime_dependencies, ["xmerl-1.3.7","stdlib-2.5","edoc-0.7.13","erts-6.0"]}
]
}.
diff --git a/lib/erl_docgen/src/erl_docgen.appup.src b/lib/erl_docgen/src/erl_docgen.appup.src
index 972a881c41..58cde75395 100644
--- a/lib/erl_docgen/src/erl_docgen.appup.src
+++ b/lib/erl_docgen/src/erl_docgen.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/erl_docgen/test/erl_docgen_SUITE.erl b/lib/erl_docgen/test/erl_docgen_SUITE.erl
index 20fbc1229b..a202fefa9d 100644
--- a/lib/erl_docgen/test/erl_docgen_SUITE.erl
+++ b/lib/erl_docgen/test/erl_docgen_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 8957d6ac40..3188b926ff 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1 +1 @@
-ERL_DOCGEN_VSN = 0.3.7
+ERL_DOCGEN_VSN = 0.4.2
diff --git a/lib/erl_interface/Makefile b/lib/erl_interface/Makefile
index 256b0309cd..56edcdfabc 100644
--- a/lib/erl_interface/Makefile
+++ b/lib/erl_interface/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in
index ef78f0f87b..7a3b5ce378 100644
--- a/lib/erl_interface/configure.in
+++ b/lib/erl_interface/configure.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -250,7 +251,7 @@ case "$threads_disabled" in
;;
win32_threads)
EI_THREADS="true"
- THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0500 -DWINVER=0x0500"
+ THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600"
;;
pthread)
EI_THREADS="true"
diff --git a/lib/erl_interface/doc/src/Makefile b/lib/erl_interface/doc/src/Makefile
index b8e638ed24..53dadec5a3 100644
--- a/lib/erl_interface/doc/src/Makefile
+++ b/lib/erl_interface/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/doc/src/book.xml b/lib/erl_interface/doc/src/book.xml
index e6a00012d5..cf7323f3a2 100644
--- a/lib/erl_interface/doc/src/book.xml
+++ b/lib/erl_interface/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 90495eebd6..8ef433d10f 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -202,6 +203,9 @@ typedef enum {
<desc>
<p>Encodes a double-precision (64 bit) floating point number in
the binary format.</p>
+ <p>
+ The function returns <c><![CDATA[-1]]></c> if the floating point number is not finite.
+ </p>
</desc>
</func>
<func>
@@ -260,9 +264,9 @@ typedef enum {
<fsummary>Encode an atom</fsummary>
<desc>
<p>Encodes an atom in the binary format with character encoding
- <c><seealso marker="#erlang_char_encoding">to_enc</seealso></c> (latin1 or utf8).
+ <seealso marker="#erlang_char_encoding"><c>to_enc</c></seealso> (latin1 or utf8).
The <c>p</c> parameter is the name of the atom with character encoding
- <c><seealso marker="#erlang_char_encoding">from_enc</seealso></c> (ascii, latin1 or utf8).
+ <seealso marker="#erlang_char_encoding"><c>from_enc</c></seealso> (ascii, latin1 or utf8).
The name must either be zero-terminated or a function variant with a <c>len</c>
parameter must be used. If <c>to_enc</c> is set to the bitwise-or'd combination
<c>(ERLANG_LATIN1|ERLANG_UTF8)</c>, utf8 encoding is only used if the atom string
@@ -565,8 +569,8 @@ ei_x_encode_string(&amp;x, "Banana");
<p>This function decodes an atom from the binary format. The
null terminated name of the atom is placed in buffer at <c>p</c> of length
<c>plen</c> bytes.</p>
- <p>The wanted string encoding is specified by <c><seealso marker="#erlang_char_encoding">
- want</seealso></c>. The original encoding used in the
+ <p>The wanted string encoding is specified by <seealso marker="#erlang_char_encoding">
+ <c>want</c></seealso>. The original encoding used in the
binary format (latin1 or utf8) can be obtained from <c>*was</c>. The actual encoding of the resulting string
(7-bit ascii, latin1 or utf8) can be obtained from <c>*result</c>. Both <c>was</c> and <c>result</c> can be <c>NULL</c>.
diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml
index e8838da004..a06013ed6a 100644
--- a/lib/erl_interface/doc/src/ei_connect.xml
+++ b/lib/erl_interface/doc/src/ei_connect.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/ei_users_guide.xml b/lib/erl_interface/doc/src/ei_users_guide.xml
index b6d3cc3209..cdf3a912bb 100644
--- a/lib/erl_interface/doc/src/ei_users_guide.xml
+++ b/lib/erl_interface/doc/src/ei_users_guide.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_call.xml b/lib/erl_interface/doc/src/erl_call.xml
index 4ab5153d30..e982bf89e1 100644
--- a/lib/erl_interface/doc/src/erl_call.xml
+++ b/lib/erl_interface/doc/src/erl_call.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -177,7 +178,7 @@ erl_call -s -a 'erlang halt' -n madonna
<code type="none"><![CDATA[
erl_call -s -a 'lists map [{math,sqrt},[1,4,9,16,25]]' -n madonna
]]></code>
- <p>Evaluates a couple of expressions. <b>The input ends with EOF (Control-D)</b>.</p>
+ <p>Evaluates a couple of expressions. <em>The input ends with EOF (Control-D)</em>.</p>
<code type="none"><![CDATA[
erl_call -s -e -n madonna
statistics(runtime),
@@ -188,7 +189,7 @@ Y=2,
^D
{ok,{3,0}}
]]></code>
- <p>Compiles a module and runs it. <b>Again, the input ends with EOF (Control-D)</b>. (In the example shown, the output has been formatted afterwards).</p>
+ <p>Compiles a module and runs it. <em>Again, the input ends with EOF (Control-D)</em>. (In the example shown, the output has been formatted afterwards).</p>
<code type="none"><![CDATA[
erl_call -s -m -a lolita -n madonna
-module(lolita).
diff --git a/lib/erl_interface/doc/src/erl_connect.xml b/lib/erl_interface/doc/src/erl_connect.xml
index c8dc43fcc8..86b2648918 100644
--- a/lib/erl_interface/doc/src/erl_connect.xml
+++ b/lib/erl_interface/doc/src/erl_connect.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_error.xml b/lib/erl_interface/doc/src/erl_error.xml
index ee21c640e9..8b8c2e95d8 100644
--- a/lib/erl_interface/doc/src/erl_error.xml
+++ b/lib/erl_interface/doc/src/erl_error.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml
index 429f77501c..713a90a390 100644
--- a/lib/erl_interface/doc/src/erl_eterm.xml
+++ b/lib/erl_interface/doc/src/erl_eterm.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -77,10 +78,12 @@
</p>
<taglist>
<tag><c><![CDATA[char *ERL_ATOM_PTR(t)]]></c></tag>
+ <item/>
<tag><c><![CDATA[char *ERL_ATOM_PTR_UTF8(t)]]></c></tag>
<item>A string representing atom <c><![CDATA[t]]></c>.
</item>
<tag><c><![CDATA[int ERL_ATOM_SIZE(t)]]></c></tag>
+ <item/>
<tag><c><![CDATA[int ERL_ATOM_SIZE_UTF8(t)]]></c></tag>
<item>The length (in bytes) of atom t.</item>
<tag><c><![CDATA[void *ERL_BIN_PTR(t)]]></c></tag>
@@ -94,6 +97,7 @@
<tag><c><![CDATA[double ERL_FLOAT_VALUE(t)]]></c></tag>
<item>The floating point value of <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[ETERM *ERL_PID_NODE(t)]]></c></tag>
+ <item/>
<tag><c><![CDATA[ETERM *ERL_PID_NODE_UTF8(t)]]></c></tag>
<item>The Node in pid <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[int ERL_PID_NUMBER(t)]]></c></tag>
@@ -107,6 +111,7 @@
<tag><c><![CDATA[int ERL_PORT_CREATION(t)]]></c></tag>
<item>The creation number in port <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[ETERM *ERL_PORT_NODE(t)]]></c></tag>
+ <item/>
<tag><c><![CDATA[ETERM *ERL_PORT_NODE_UTF8(t)]]></c></tag>
<item>The node in port <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[int ERL_REF_NUMBER(t)]]></c></tag>
@@ -371,9 +376,11 @@ iohead ::= Binary
<p><c><![CDATA[f]]></c> is a value to be converted to an Erlang float.</p>
<p></p>
<p>The function returns an Erlang float object with the value
- specified in <c><![CDATA[f]]></c>.</p>
+ specified in <c><![CDATA[f]]></c> or <c><![CDATA[NULL]]></c> if
+ <c><![CDATA[f]]></c> is not finite.
+ </p>
<p><c><![CDATA[ERL_FLOAT_VALUE(t)]]></c> can be used to retrieve the
- value from an Erlang float.</p>
+ value from an Erlang float.</p>
</desc>
</func>
<func>
diff --git a/lib/erl_interface/doc/src/erl_format.xml b/lib/erl_interface/doc/src/erl_format.xml
index ff3274047a..2918cb8b84 100644
--- a/lib/erl_interface/doc/src/erl_format.xml
+++ b/lib/erl_interface/doc/src/erl_format.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_global.xml b/lib/erl_interface/doc/src/erl_global.xml
index 71c7feb9cc..ec5e51a0b6 100644
--- a/lib/erl_interface/doc/src/erl_global.xml
+++ b/lib/erl_interface/doc/src/erl_global.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_interface.xml b/lib/erl_interface/doc/src/erl_interface.xml
index 5c3d8bc218..3a01cba74e 100644
--- a/lib/erl_interface/doc/src/erl_interface.xml
+++ b/lib/erl_interface/doc/src/erl_interface.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_malloc.xml b/lib/erl_interface/doc/src/erl_malloc.xml
index f387a887cb..0a9830f612 100644
--- a/lib/erl_interface/doc/src/erl_malloc.xml
+++ b/lib/erl_interface/doc/src/erl_malloc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/erl_marshal.xml b/lib/erl_interface/doc/src/erl_marshal.xml
index 173e609b83..9b9622dcc2 100644
--- a/lib/erl_interface/doc/src/erl_marshal.xml
+++ b/lib/erl_interface/doc/src/erl_marshal.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index 29a9d71041..37266d9354 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,72 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix Erl_Interface build error on Debian/Hurd and
+ Debian/kFreeBSD. (Thanks to Sergei Golovan)</p>
+ <p>
+ Own Id: OTP-13328</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ EPMD supports both IPv4 and IPv6</p>
+ <p>
+ Also affects oldest supported windows version.</p>
+ <p>
+ Own Id: OTP-13364</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.8.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix the conditional selection of gethostbyname_r and
+ gethostbyaddr_r.</p>
+ <p>
+ Own Id: OTP-13188</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Do not accept Nan and Infinity values</p>
+ <p>
+ Erlang does not accept these values, so we return an
+ error in the C interface rather than letting them through
+ to the Erlang VM, which rejects the message with a
+ somewhat cryptic "bad external term".</p>
+ <p>
+ Own Id: OTP-12801</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.7.20</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/doc/src/notes_history.xml b/lib/erl_interface/doc/src/notes_history.xml
index 3aec9d051a..f3cf8d01ae 100644
--- a/lib/erl_interface/doc/src/notes_history.xml
+++ b/lib/erl_interface/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/part.xml b/lib/erl_interface/doc/src/part.xml
index b3cee31720..ec598f0339 100644
--- a/lib/erl_interface/doc/src/part.xml
+++ b/lib/erl_interface/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/part_erl_interface.xml b/lib/erl_interface/doc/src/part_erl_interface.xml
index c382dce447..08225133e0 100644
--- a/lib/erl_interface/doc/src/part_erl_interface.xml
+++ b/lib/erl_interface/doc/src/part_erl_interface.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/part_notes.xml b/lib/erl_interface/doc/src/part_notes.xml
index 79dc973d5e..f2d5bd962b 100644
--- a/lib/erl_interface/doc/src/part_notes.xml
+++ b/lib/erl_interface/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/part_notes_history.xml b/lib/erl_interface/doc/src/part_notes_history.xml
index 95f8c773cf..7cf1b25f54 100644
--- a/lib/erl_interface/doc/src/part_notes_history.xml
+++ b/lib/erl_interface/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/ref_man.xml b/lib/erl_interface/doc/src/ref_man.xml
index 354313127d..2e115dba5b 100644
--- a/lib/erl_interface/doc/src/ref_man.xml
+++ b/lib/erl_interface/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Erl_Interface Command Reference</title>
diff --git a/lib/erl_interface/doc/src/ref_man_ei.xml b/lib/erl_interface/doc/src/ref_man_ei.xml
index b4fbc4b2c6..bbb2b402cd 100644
--- a/lib/erl_interface/doc/src/ref_man_ei.xml
+++ b/lib/erl_interface/doc/src/ref_man_ei.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/ref_man_erl_interface.xml b/lib/erl_interface/doc/src/ref_man_erl_interface.xml
index 2641475415..c5836c11c3 100644
--- a/lib/erl_interface/doc/src/ref_man_erl_interface.xml
+++ b/lib/erl_interface/doc/src/ref_man_erl_interface.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/doc/src/registry.xml b/lib/erl_interface/doc/src/registry.xml
index d06ceb095a..cd7e5d976d 100644
--- a/lib/erl_interface/doc/src/registry.xml
+++ b/lib/erl_interface/doc/src/registry.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index 3f3435977d..c1dbc8470d 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/include/ei_connect.h b/lib/erl_interface/include/ei_connect.h
index 02880e197c..c8eeba7ae0 100644
--- a/lib/erl_interface/include/ei_connect.h
+++ b/lib/erl_interface/include/ei_connect.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/include/eicode.h b/lib/erl_interface/include/eicode.h
index c35489e890..1077528d3c 100644
--- a/lib/erl_interface/include/eicode.h
+++ b/lib/erl_interface/include/eicode.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/include/erl_interface.h b/lib/erl_interface/include/erl_interface.h
index 7f44cb83bd..3f9804da7d 100644
--- a/lib/erl_interface/include/erl_interface.h
+++ b/lib/erl_interface/include/erl_interface.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/Makefile b/lib/erl_interface/src/Makefile
index a069aa07ab..868407a23f 100644
--- a/lib/erl_interface/src/Makefile
+++ b/lib/erl_interface/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in
index 7c09b605fa..777d709b1e 100644
--- a/lib/erl_interface/src/Makefile.in
+++ b/lib/erl_interface/src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 45c000ef76..7b1b2810bb 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/src/connect/ei_connect_int.h b/lib/erl_interface/src/connect/ei_connect_int.h
index 8fab47a787..efb6719a1d 100644
--- a/lib/erl_interface/src/connect/ei_connect_int.h
+++ b/lib/erl_interface/src/connect/ei_connect_int.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c
index cffcac801c..414cb8be3e 100644
--- a/lib/erl_interface/src/connect/ei_resolve.c
+++ b/lib/erl_interface/src/connect/ei_resolve.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -615,7 +616,7 @@ struct hostent *ei_gethostbyaddr_r(const char *addr,
#ifndef HAVE_GETHOSTBYNAME_R
return my_gethostbyaddr_r(addr,length,type,hostp,buffer,buflen,h_errnop);
#else
-#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__))
+#if (defined(__GLIBC__) || defined(__linux__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__))
struct hostent *result;
gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, &result,
@@ -642,7 +643,7 @@ struct hostent *ei_gethostbyname_r(const char *name,
#ifndef HAVE_GETHOSTBYNAME_R
return my_gethostbyname_r(name,hostp,buffer,buflen,h_errnop);
#else
-#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__) || defined(__ANDROID__))
+#if (defined(__GLIBC__) || defined(__linux__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__) || defined(__ANDROID__))
struct hostent *result;
gethostbyname_r(name, hostp, buffer, buflen, &result, h_errnop);
diff --git a/lib/erl_interface/src/connect/ei_resolve.h b/lib/erl_interface/src/connect/ei_resolve.h
index 4cb8aff338..71ebeab20b 100644
--- a/lib/erl_interface/src/connect/ei_resolve.h
+++ b/lib/erl_interface/src/connect/ei_resolve.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c
index 1821de3844..b036c8969e 100644
--- a/lib/erl_interface/src/connect/eirecv.c
+++ b/lib/erl_interface/src/connect/eirecv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/connect/eirecv.h b/lib/erl_interface/src/connect/eirecv.h
index b66eaeeb56..d56f36b286 100644
--- a/lib/erl_interface/src/connect/eirecv.h
+++ b/lib/erl_interface/src/connect/eirecv.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/connect/eisend.h b/lib/erl_interface/src/connect/eisend.h
index d83caf1352..6762c4cf40 100644
--- a/lib/erl_interface/src/connect/eisend.h
+++ b/lib/erl_interface/src/connect/eisend.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/connect/send.c b/lib/erl_interface/src/connect/send.c
index 2fb487d7e8..826bc1f22a 100644
--- a/lib/erl_interface/src/connect/send.c
+++ b/lib/erl_interface/src/connect/send.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/connect/send_exit.c b/lib/erl_interface/src/connect/send_exit.c
index c5beb358b0..f71acfa155 100644
--- a/lib/erl_interface/src/connect/send_exit.c
+++ b/lib/erl_interface/src/connect/send_exit.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/connect/send_reg.c b/lib/erl_interface/src/connect/send_reg.c
index b011142e76..dac3877d2a 100644
--- a/lib/erl_interface/src/connect/send_reg.c
+++ b/lib/erl_interface/src/connect/send_reg.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c
index 44fd4df12c..df1e5b9350 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c
index 477880b331..5739d159bf 100644
--- a/lib/erl_interface/src/decode/decode_big.c
+++ b/lib/erl_interface/src/decode/decode_big.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -150,27 +151,6 @@ int ei_big_comp(erlang_big *x, erlang_big *y)
#define INLINED_FP_CONVERSION 1
#endif
-#ifdef USE_ISINF_ISNAN /* simulate finite() */
-# define isfinite(f) (!isinf(f) && !isnan(f))
-# define HAVE_ISFINITE
-#elif defined(__GNUC__) && defined(HAVE_FINITE)
-/* We use finite in gcc as it emits assembler instead of
- the function call that isfinite emits. The assembler is
- significantly faster. */
-# ifdef isfinite
-# undef isfinite
-# endif
-# define isfinite finite
-# ifndef HAVE_ISFINITE
-# define HAVE_ISFINITE
-# endif
-#elif defined(isfinite) && !defined(HAVE_ISFINITE)
-# define HAVE_ISFINITE
-#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE)
-# define isfinite finite
-# define HAVE_ISFINITE
-#endif
-
#ifdef NO_FPE_SIGNALS
# define ERTS_FP_CHECK_INIT() do {} while (0)
# define ERTS_FP_ERROR(f, Action) if (!isfinite(f)) { Action; } else {}
diff --git a/lib/erl_interface/src/decode/decode_bignum.c b/lib/erl_interface/src/decode/decode_bignum.c
index f10052f9fe..9d09aefd76 100644
--- a/lib/erl_interface/src/decode/decode_bignum.c
+++ b/lib/erl_interface/src/decode/decode_bignum.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_binary.c b/lib/erl_interface/src/decode/decode_binary.c
index 713e621e60..66014181b5 100644
--- a/lib/erl_interface/src/decode/decode_binary.c
+++ b/lib/erl_interface/src/decode/decode_binary.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_boolean.c b/lib/erl_interface/src/decode/decode_boolean.c
index 8c44a1ccfc..edaf1486d4 100644
--- a/lib/erl_interface/src/decode/decode_boolean.c
+++ b/lib/erl_interface/src/decode/decode_boolean.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_char.c b/lib/erl_interface/src/decode/decode_char.c
index 0f9b3f6cff..0290c71988 100644
--- a/lib/erl_interface/src/decode/decode_char.c
+++ b/lib/erl_interface/src/decode/decode_char.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_double.c b/lib/erl_interface/src/decode/decode_double.c
index ed6e39655e..413d575b1a 100644
--- a/lib/erl_interface/src/decode/decode_double.c
+++ b/lib/erl_interface/src/decode/decode_double.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/src/decode/decode_fun.c b/lib/erl_interface/src/decode/decode_fun.c
index 0857874c89..c2e321c067 100644
--- a/lib/erl_interface/src/decode/decode_fun.c
+++ b/lib/erl_interface/src/decode/decode_fun.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_intlist.c b/lib/erl_interface/src/decode/decode_intlist.c
index 65552a4ed4..68f38075e2 100644
--- a/lib/erl_interface/src/decode/decode_intlist.c
+++ b/lib/erl_interface/src/decode/decode_intlist.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_list_header.c b/lib/erl_interface/src/decode/decode_list_header.c
index dda711f9fd..e198f52d52 100644
--- a/lib/erl_interface/src/decode/decode_list_header.c
+++ b/lib/erl_interface/src/decode/decode_list_header.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_long.c b/lib/erl_interface/src/decode/decode_long.c
index b4138247e0..15bfb28cf0 100644
--- a/lib/erl_interface/src/decode/decode_long.c
+++ b/lib/erl_interface/src/decode/decode_long.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_longlong.c b/lib/erl_interface/src/decode/decode_longlong.c
index 8ec9f76995..22f2a63d2e 100644
--- a/lib/erl_interface/src/decode/decode_longlong.c
+++ b/lib/erl_interface/src/decode/decode_longlong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c
index cd5ae2ab20..7fbb818b31 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c
index 8fbdc5f3d3..e039b5b845 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c
index 78db118172..a6b87e5a21 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_skip.c b/lib/erl_interface/src/decode/decode_skip.c
index 2260394da1..d49ae0007f 100644
--- a/lib/erl_interface/src/decode/decode_skip.c
+++ b/lib/erl_interface/src/decode/decode_skip.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/src/decode/decode_skip.h b/lib/erl_interface/src/decode/decode_skip.h
index b6c7b09fe4..a0934fdf35 100644
--- a/lib/erl_interface/src/decode/decode_skip.h
+++ b/lib/erl_interface/src/decode/decode_skip.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_string.c b/lib/erl_interface/src/decode/decode_string.c
index bcbdca0438..98b7384dc5 100644
--- a/lib/erl_interface/src/decode/decode_string.c
+++ b/lib/erl_interface/src/decode/decode_string.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_trace.c b/lib/erl_interface/src/decode/decode_trace.c
index d192c7f8b1..bcc53bce96 100644
--- a/lib/erl_interface/src/decode/decode_trace.c
+++ b/lib/erl_interface/src/decode/decode_trace.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_tuple_header.c b/lib/erl_interface/src/decode/decode_tuple_header.c
index 698be1b97a..ea60a03ddc 100644
--- a/lib/erl_interface/src/decode/decode_tuple_header.c
+++ b/lib/erl_interface/src/decode/decode_tuple_header.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_ulong.c b/lib/erl_interface/src/decode/decode_ulong.c
index dcf3703be7..dbd86f5022 100644
--- a/lib/erl_interface/src/decode/decode_ulong.c
+++ b/lib/erl_interface/src/decode/decode_ulong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_ulonglong.c b/lib/erl_interface/src/decode/decode_ulonglong.c
index 17ecea848d..e579df41aa 100644
--- a/lib/erl_interface/src/decode/decode_ulonglong.c
+++ b/lib/erl_interface/src/decode/decode_ulonglong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/decode/decode_version.c b/lib/erl_interface/src/decode/decode_version.c
index 124d7272f4..b2146d3280 100644
--- a/lib/erl_interface/src/decode/decode_version.c
+++ b/lib/erl_interface/src/decode/decode_version.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/eidefs.mk.in b/lib/erl_interface/src/eidefs.mk.in
index 05f61236c3..4f6c4e5a3c 100644
--- a/lib/erl_interface/src/eidefs.mk.in
+++ b/lib/erl_interface/src/eidefs.mk.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/src/encode/eicode.h b/lib/erl_interface/src/encode/eicode.h
index cf008b7fa9..351e88cf2b 100644
--- a/lib/erl_interface/src/encode/eicode.h
+++ b/lib/erl_interface/src/encode/eicode.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_atom.c b/lib/erl_interface/src/encode/encode_atom.c
index 46d34c3bf0..372122f3eb 100644
--- a/lib/erl_interface/src/encode/encode_atom.c
+++ b/lib/erl_interface/src/encode/encode_atom.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_big.c b/lib/erl_interface/src/encode/encode_big.c
index 25abf424b7..f758070d8c 100644
--- a/lib/erl_interface/src/encode/encode_big.c
+++ b/lib/erl_interface/src/encode/encode_big.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_bignum.c b/lib/erl_interface/src/encode/encode_bignum.c
index 6850cb86a6..ebd1853b21 100644
--- a/lib/erl_interface/src/encode/encode_bignum.c
+++ b/lib/erl_interface/src/encode/encode_bignum.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_binary.c b/lib/erl_interface/src/encode/encode_binary.c
index 67a4dc1219..91dab32c29 100644
--- a/lib/erl_interface/src/encode/encode_binary.c
+++ b/lib/erl_interface/src/encode/encode_binary.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_boolean.c b/lib/erl_interface/src/encode/encode_boolean.c
index 51a166bea5..d98cb5ad09 100644
--- a/lib/erl_interface/src/encode/encode_boolean.c
+++ b/lib/erl_interface/src/encode/encode_boolean.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_char.c b/lib/erl_interface/src/encode/encode_char.c
index a7d27c5261..87fdef7bdd 100644
--- a/lib/erl_interface/src/encode/encode_char.c
+++ b/lib/erl_interface/src/encode/encode_char.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_double.c b/lib/erl_interface/src/encode/encode_double.c
index 148a49f73a..8943cefa11 100644
--- a/lib/erl_interface/src/encode/encode_double.c
+++ b/lib/erl_interface/src/encode/encode_double.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -21,12 +22,24 @@
#include "eidef.h"
#include "eiext.h"
#include "putget.h"
+#if defined(HAVE_ISFINITE)
+#include <math.h>
+#endif
int ei_encode_double(char *buf, int *index, double p)
{
char *s = buf + *index;
char *s0 = s;
+ /* Erlang does not handle Inf and NaN, so we return an error rather
+ * than letting the Erlang VM complain about a bad external
+ * term. */
+#if defined(HAVE_ISFINITE)
+ if(!isfinite(p)) {
+ return -1;
+ }
+#endif
+
if (!buf)
s += 9;
else {
diff --git a/lib/erl_interface/src/encode/encode_fun.c b/lib/erl_interface/src/encode/encode_fun.c
index 455d8a5a94..14f66dcde1 100644
--- a/lib/erl_interface/src/encode/encode_fun.c
+++ b/lib/erl_interface/src/encode/encode_fun.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_list_header.c b/lib/erl_interface/src/encode/encode_list_header.c
index 27da70ae15..0ddca107d7 100644
--- a/lib/erl_interface/src/encode/encode_list_header.c
+++ b/lib/erl_interface/src/encode/encode_list_header.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_long.c b/lib/erl_interface/src/encode/encode_long.c
index d616bb6e47..cf99a7488c 100644
--- a/lib/erl_interface/src/encode/encode_long.c
+++ b/lib/erl_interface/src/encode/encode_long.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_longlong.c b/lib/erl_interface/src/encode/encode_longlong.c
index aff24e2478..fff170c32d 100644
--- a/lib/erl_interface/src/encode/encode_longlong.c
+++ b/lib/erl_interface/src/encode/encode_longlong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_pid.c b/lib/erl_interface/src/encode/encode_pid.c
index 86d0f393e5..7b01b7045f 100644
--- a/lib/erl_interface/src/encode/encode_pid.c
+++ b/lib/erl_interface/src/encode/encode_pid.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_port.c b/lib/erl_interface/src/encode/encode_port.c
index a206de56c7..a7468e5917 100644
--- a/lib/erl_interface/src/encode/encode_port.c
+++ b/lib/erl_interface/src/encode/encode_port.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_ref.c b/lib/erl_interface/src/encode/encode_ref.c
index 9855231848..0f27a086f0 100644
--- a/lib/erl_interface/src/encode/encode_ref.c
+++ b/lib/erl_interface/src/encode/encode_ref.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_string.c b/lib/erl_interface/src/encode/encode_string.c
index d00d2f3e81..180fe3f1da 100644
--- a/lib/erl_interface/src/encode/encode_string.c
+++ b/lib/erl_interface/src/encode/encode_string.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_trace.c b/lib/erl_interface/src/encode/encode_trace.c
index de46f7fae8..95b49a04e6 100644
--- a/lib/erl_interface/src/encode/encode_trace.c
+++ b/lib/erl_interface/src/encode/encode_trace.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_tuple_header.c b/lib/erl_interface/src/encode/encode_tuple_header.c
index 5b11e60447..254840a3d1 100644
--- a/lib/erl_interface/src/encode/encode_tuple_header.c
+++ b/lib/erl_interface/src/encode/encode_tuple_header.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_ulong.c b/lib/erl_interface/src/encode/encode_ulong.c
index c4ff34e493..98b26fed40 100644
--- a/lib/erl_interface/src/encode/encode_ulong.c
+++ b/lib/erl_interface/src/encode/encode_ulong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_ulonglong.c b/lib/erl_interface/src/encode/encode_ulonglong.c
index 2f136abf96..069138a458 100644
--- a/lib/erl_interface/src/encode/encode_ulonglong.c
+++ b/lib/erl_interface/src/encode/encode_ulonglong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/encode/encode_version.c b/lib/erl_interface/src/encode/encode_version.c
index 3fd9fdabd4..1694697260 100644
--- a/lib/erl_interface/src/encode/encode_version.c
+++ b/lib/erl_interface/src/encode/encode_version.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/epmd/ei_epmd.h b/lib/erl_interface/src/epmd/ei_epmd.h
index ccacfed244..50974b89c5 100644
--- a/lib/erl_interface/src/epmd/ei_epmd.h
+++ b/lib/erl_interface/src/epmd/ei_epmd.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c
index a433815eb7..dedc21e679 100644
--- a/lib/erl_interface/src/epmd/epmd_port.c
+++ b/lib/erl_interface/src/epmd/epmd_port.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c
index d45fe644c0..6370a5ab37 100644
--- a/lib/erl_interface/src/epmd/epmd_publish.c
+++ b/lib/erl_interface/src/epmd/epmd_publish.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/epmd/epmd_unpublish.c b/lib/erl_interface/src/epmd/epmd_unpublish.c
index 3afa89ab1d..ef84938e5b 100644
--- a/lib/erl_interface/src/epmd/epmd_unpublish.c
+++ b/lib/erl_interface/src/epmd/epmd_unpublish.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/erl_interface.app.src b/lib/erl_interface/src/erl_interface.app.src
index 11f884c36b..8ab3e1012f 100644
--- a/lib/erl_interface/src/erl_interface.app.src
+++ b/lib/erl_interface/src/erl_interface.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/src/erl_interface.appup.src b/lib/erl_interface/src/erl_interface.appup.src
index d267e3d3d5..eee7be1540 100644
--- a/lib/erl_interface/src/erl_interface.appup.src
+++ b/lib/erl_interface/src/erl_interface.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%", [], []}.
diff --git a/lib/erl_interface/src/legacy/decode_term.c b/lib/erl_interface/src/legacy/decode_term.c
index 796cebdfef..fabbee19a9 100644
--- a/lib/erl_interface/src/legacy/decode_term.c
+++ b/lib/erl_interface/src/legacy/decode_term.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/src/legacy/encode_term.c b/lib/erl_interface/src/legacy/encode_term.c
index c377d7b699..47837214e8 100644
--- a/lib/erl_interface/src/legacy/encode_term.c
+++ b/lib/erl_interface/src/legacy/encode_term.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_config.h b/lib/erl_interface/src/legacy/erl_config.h
index 166aa7013c..1da150bdbd 100644
--- a/lib/erl_interface/src/legacy/erl_config.h
+++ b/lib/erl_interface/src/legacy/erl_config.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c
index d70d914b79..4b1004ae2b 100644
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ b/lib/erl_interface/src/legacy/erl_connect.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_connect.h b/lib/erl_interface/src/legacy/erl_connect.h
index d9d6c4e453..eb3292b679 100644
--- a/lib/erl_interface/src/legacy/erl_connect.h
+++ b/lib/erl_interface/src/legacy/erl_connect.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_error.c b/lib/erl_interface/src/legacy/erl_error.c
index 18dc2423bf..d3309d2863 100644
--- a/lib/erl_interface/src/legacy/erl_error.c
+++ b/lib/erl_interface/src/legacy/erl_error.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_error.h b/lib/erl_interface/src/legacy/erl_error.h
index 931c639c30..27a8d13d0f 100644
--- a/lib/erl_interface/src/legacy/erl_error.h
+++ b/lib/erl_interface/src/legacy/erl_error.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c
index 636d26b24b..f2f35ab693 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ b/lib/erl_interface/src/legacy/erl_eterm.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -26,6 +27,9 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#if defined(HAVE_ISFINITE)
+#include <math.h>
+#endif
#include "ei_locking.h"
#include "ei_resolve.h"
@@ -125,6 +129,15 @@ ETERM *erl_mk_float (double d)
{
ETERM *ep;
+#if defined(HAVE_ISFINITE)
+ /* Erlang does not handle Inf and NaN, so we return an error
+ * rather than letting the Erlang VM complain about a bad external
+ * term. */
+ if(!isfinite(d)) {
+ return NULL;
+ }
+#endif
+
ep = erl_alloc_eterm(ERL_FLOAT);
ERL_COUNT(ep) = 1;
ERL_FLOAT_VALUE(ep) = d;
diff --git a/lib/erl_interface/src/legacy/erl_eterm.h b/lib/erl_interface/src/legacy/erl_eterm.h
index ca4ec7925a..d9a26b2541 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.h
+++ b/lib/erl_interface/src/legacy/erl_eterm.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_fix_alloc.c b/lib/erl_interface/src/legacy/erl_fix_alloc.c
index 2ed0dd1470..70d592bfe1 100644
--- a/lib/erl_interface/src/legacy/erl_fix_alloc.c
+++ b/lib/erl_interface/src/legacy/erl_fix_alloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_fix_alloc.h b/lib/erl_interface/src/legacy/erl_fix_alloc.h
index 16d2f4217a..af86202ae7 100644
--- a/lib/erl_interface/src/legacy/erl_fix_alloc.h
+++ b/lib/erl_interface/src/legacy/erl_fix_alloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_format.c b/lib/erl_interface/src/legacy/erl_format.c
index fda05cbdb8..c5ef47236d 100644
--- a/lib/erl_interface/src/legacy/erl_format.c
+++ b/lib/erl_interface/src/legacy/erl_format.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_format.h b/lib/erl_interface/src/legacy/erl_format.h
index 90801e4892..388267f859 100644
--- a/lib/erl_interface/src/legacy/erl_format.h
+++ b/lib/erl_interface/src/legacy/erl_format.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_global.h b/lib/erl_interface/src/legacy/erl_global.h
index ef09eab0b0..3c99b2fe40 100644
--- a/lib/erl_interface/src/legacy/erl_global.h
+++ b/lib/erl_interface/src/legacy/erl_global.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_internal.h b/lib/erl_interface/src/legacy/erl_internal.h
index e79c815946..22160d8911 100644
--- a/lib/erl_interface/src/legacy/erl_internal.h
+++ b/lib/erl_interface/src/legacy/erl_internal.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_malloc.c b/lib/erl_interface/src/legacy/erl_malloc.c
index c320a00bfe..cad7f75261 100644
--- a/lib/erl_interface/src/legacy/erl_malloc.c
+++ b/lib/erl_interface/src/legacy/erl_malloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_malloc.h b/lib/erl_interface/src/legacy/erl_malloc.h
index 787d3bb98f..cfbd190b61 100644
--- a/lib/erl_interface/src/legacy/erl_malloc.h
+++ b/lib/erl_interface/src/legacy/erl_malloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index 9558dc134b..a4216c9541 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_marshal.h b/lib/erl_interface/src/legacy/erl_marshal.h
index 8b3c3b6fa1..c7fe2139a6 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.h
+++ b/lib/erl_interface/src/legacy/erl_marshal.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_resolve.c b/lib/erl_interface/src/legacy/erl_resolve.c
index 7dfebb78ed..cc6558471a 100644
--- a/lib/erl_interface/src/legacy/erl_resolve.c
+++ b/lib/erl_interface/src/legacy/erl_resolve.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_timeout.c b/lib/erl_interface/src/legacy/erl_timeout.c
index 146a106e7c..1651131dff 100644
--- a/lib/erl_interface/src/legacy/erl_timeout.c
+++ b/lib/erl_interface/src/legacy/erl_timeout.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/erl_timeout.h b/lib/erl_interface/src/legacy/erl_timeout.h
index 4ef6d21a72..17d45915f5 100644
--- a/lib/erl_interface/src/legacy/erl_timeout.h
+++ b/lib/erl_interface/src/legacy/erl_timeout.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/global_names.c b/lib/erl_interface/src/legacy/global_names.c
index 3a437df3a3..bf717bb32b 100644
--- a/lib/erl_interface/src/legacy/global_names.c
+++ b/lib/erl_interface/src/legacy/global_names.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/global_register.c b/lib/erl_interface/src/legacy/global_register.c
index cce60f25da..9905977514 100644
--- a/lib/erl_interface/src/legacy/global_register.c
+++ b/lib/erl_interface/src/legacy/global_register.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/global_unregister.c b/lib/erl_interface/src/legacy/global_unregister.c
index 593a8a7860..ace7343503 100644
--- a/lib/erl_interface/src/legacy/global_unregister.c
+++ b/lib/erl_interface/src/legacy/global_unregister.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/global_whereis.c b/lib/erl_interface/src/legacy/global_whereis.c
index 589c9d17de..23be4a1055 100644
--- a/lib/erl_interface/src/legacy/global_whereis.c
+++ b/lib/erl_interface/src/legacy/global_whereis.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/legacy/portability.h b/lib/erl_interface/src/legacy/portability.h
index 5f984b08e1..d544c63c99 100644
--- a/lib/erl_interface/src/legacy/portability.h
+++ b/lib/erl_interface/src/legacy/portability.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/misc/ei_compat.c b/lib/erl_interface/src/misc/ei_compat.c
index 45ea6e3a72..ceb597e970 100644
--- a/lib/erl_interface/src/misc/ei_compat.c
+++ b/lib/erl_interface/src/misc/ei_compat.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c
index 2e7317f781..0ec67dde09 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/erl_interface/src/misc/ei_decode_term.h b/lib/erl_interface/src/misc/ei_decode_term.h
index 76a71ae0a6..1f7cedff02 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.h
+++ b/lib/erl_interface/src/misc/ei_decode_term.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index 07499213cd..191f4ec7b5 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_format.h b/lib/erl_interface/src/misc/ei_format.h
index e94d0531f5..5fa3247d60 100644
--- a/lib/erl_interface/src/misc/ei_format.h
+++ b/lib/erl_interface/src/misc/ei_format.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_internal.h b/lib/erl_interface/src/misc/ei_internal.h
index f7805efebf..56cdb53fbf 100644
--- a/lib/erl_interface/src/misc/ei_internal.h
+++ b/lib/erl_interface/src/misc/ei_internal.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_locking.c b/lib/erl_interface/src/misc/ei_locking.c
index e3f57d5ba2..c4c4a8e735 100644
--- a/lib/erl_interface/src/misc/ei_locking.c
+++ b/lib/erl_interface/src/misc/ei_locking.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_locking.h b/lib/erl_interface/src/misc/ei_locking.h
index f97683e40d..99b88ead3b 100644
--- a/lib/erl_interface/src/misc/ei_locking.h
+++ b/lib/erl_interface/src/misc/ei_locking.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_malloc.c b/lib/erl_interface/src/misc/ei_malloc.c
index b122c0f7b8..347973bbd6 100644
--- a/lib/erl_interface/src/misc/ei_malloc.c
+++ b/lib/erl_interface/src/misc/ei_malloc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_malloc.h b/lib/erl_interface/src/misc/ei_malloc.h
index ef8efaf9ea..b02811101b 100644
--- a/lib/erl_interface/src/misc/ei_malloc.h
+++ b/lib/erl_interface/src/misc/ei_malloc.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c
index f879c4e2f9..d4fa2c30e7 100644
--- a/lib/erl_interface/src/misc/ei_portio.c
+++ b/lib/erl_interface/src/misc/ei_portio.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_portio.h b/lib/erl_interface/src/misc/ei_portio.h
index f2c92278db..24dcee4780 100644
--- a/lib/erl_interface/src/misc/ei_portio.h
+++ b/lib/erl_interface/src/misc/ei_portio.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index 95369db15a..702ee9566d 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/erl_interface/src/misc/ei_printterm.h b/lib/erl_interface/src/misc/ei_printterm.h
index 13350e3ecd..cb9e12c2dd 100644
--- a/lib/erl_interface/src/misc/ei_printterm.h
+++ b/lib/erl_interface/src/misc/ei_printterm.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_pthreads.c b/lib/erl_interface/src/misc/ei_pthreads.c
index a741dfd5c2..1d86fdb736 100644
--- a/lib/erl_interface/src/misc/ei_pthreads.c
+++ b/lib/erl_interface/src/misc/ei_pthreads.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_trace.c b/lib/erl_interface/src/misc/ei_trace.c
index fb183c8be4..b341f38105 100644
--- a/lib/erl_interface/src/misc/ei_trace.c
+++ b/lib/erl_interface/src/misc/ei_trace.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_trace.h b/lib/erl_interface/src/misc/ei_trace.h
index d3513c9353..0105a0c1f1 100644
--- a/lib/erl_interface/src/misc/ei_trace.h
+++ b/lib/erl_interface/src/misc/ei_trace.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_x_encode.c b/lib/erl_interface/src/misc/ei_x_encode.c
index 10542c88a5..4cd882235f 100644
--- a/lib/erl_interface/src/misc/ei_x_encode.c
+++ b/lib/erl_interface/src/misc/ei_x_encode.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/ei_x_encode.h b/lib/erl_interface/src/misc/ei_x_encode.h
index 3eab23ce0a..f11d750b28 100644
--- a/lib/erl_interface/src/misc/ei_x_encode.h
+++ b/lib/erl_interface/src/misc/ei_x_encode.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/eidef.h b/lib/erl_interface/src/misc/eidef.h
index bd3d0bf631..9ac49434e6 100644
--- a/lib/erl_interface/src/misc/eidef.h
+++ b/lib/erl_interface/src/misc/eidef.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
@@ -41,6 +42,27 @@
typedef int socklen_t;
#endif
+#ifdef USE_ISINF_ISNAN /* simulate finite() */
+# define isfinite(f) (!isinf(f) && !isnan(f))
+# define HAVE_ISFINITE
+#elif defined(__GNUC__) && defined(HAVE_FINITE)
+/* We use finite in gcc as it emits assembler instead of
+ the function call that isfinite emits. The assembler is
+ significantly faster. */
+# ifdef isfinite
+# undef isfinite
+# endif
+# define isfinite finite
+# ifndef HAVE_ISFINITE
+# define HAVE_ISFINITE
+# endif
+#elif defined(isfinite) && !defined(HAVE_ISFINITE)
+# define HAVE_ISFINITE
+#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE)
+# define isfinite finite
+# define HAVE_ISFINITE
+#endif
+
typedef unsigned char uint8; /* FIXME use configure */
typedef unsigned short uint16;
typedef unsigned int uint32;
diff --git a/lib/erl_interface/src/misc/eiext.h b/lib/erl_interface/src/misc/eiext.h
index 85ed9e0d50..caf98c8e70 100644
--- a/lib/erl_interface/src/misc/eiext.h
+++ b/lib/erl_interface/src/misc/eiext.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c
index 2bd992bd56..6b95c1f470 100644
--- a/lib/erl_interface/src/misc/get_type.c
+++ b/lib/erl_interface/src/misc/get_type.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/erl_interface/src/misc/putget.h b/lib/erl_interface/src/misc/putget.h
index c751e03093..f7b42b6efa 100644
--- a/lib/erl_interface/src/misc/putget.h
+++ b/lib/erl_interface/src/misc/putget.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c
index 935a9a3287..b08b17aea4 100644
--- a/lib/erl_interface/src/misc/show_msg.c
+++ b/lib/erl_interface/src/misc/show_msg.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/erl_interface/src/misc/show_msg.h b/lib/erl_interface/src/misc/show_msg.h
index fac51f3278..1f1bd9cb17 100644
--- a/lib/erl_interface/src/misc/show_msg.h
+++ b/lib/erl_interface/src/misc/show_msg.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/not_used/ei_send.c b/lib/erl_interface/src/not_used/ei_send.c
index 2701b4404c..437b62cc5d 100644
--- a/lib/erl_interface/src/not_used/ei_send.c
+++ b/lib/erl_interface/src/not_used/ei_send.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/not_used/ei_send_reg.c b/lib/erl_interface/src/not_used/ei_send_reg.c
index af68549c6d..f6b66e155c 100644
--- a/lib/erl_interface/src/not_used/ei_send_reg.c
+++ b/lib/erl_interface/src/not_used/ei_send_reg.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/not_used/send_link.c b/lib/erl_interface/src/not_used/send_link.c
index 4b43b2f0cc..3c907897e0 100644
--- a/lib/erl_interface/src/not_used/send_link.c
+++ b/lib/erl_interface/src/not_used/send_link.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/not_used/whereis.c b/lib/erl_interface/src/not_used/whereis.c
index a4dd73e952..3b7cfb0ee7 100644
--- a/lib/erl_interface/src/not_used/whereis.c
+++ b/lib/erl_interface/src/not_used/whereis.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/prog/ei_fake_prog.c b/lib/erl_interface/src/prog/ei_fake_prog.c
index 56d4eb7db4..2d149aec0c 100644
--- a/lib/erl_interface/src/prog/ei_fake_prog.c
+++ b/lib/erl_interface/src/prog/ei_fake_prog.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index 4182ab2d5e..d36742c4f6 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/prog/erl_fake_prog.c b/lib/erl_interface/src/prog/erl_fake_prog.c
index a2b49a0ed9..80d72eb933 100644
--- a/lib/erl_interface/src/prog/erl_fake_prog.c
+++ b/lib/erl_interface/src/prog/erl_fake_prog.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/src/prog/erl_start.c b/lib/erl_interface/src/prog/erl_start.c
index a53aab9ac7..b7816f3ad4 100644
--- a/lib/erl_interface/src/prog/erl_start.c
+++ b/lib/erl_interface/src/prog/erl_start.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/prog/erl_start.h b/lib/erl_interface/src/prog/erl_start.h
index 05f34864a7..a78dd16edb 100644
--- a/lib/erl_interface/src/prog/erl_start.h
+++ b/lib/erl_interface/src/prog/erl_start.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash.h b/lib/erl_interface/src/registry/hash.h
index 3886e8664b..69882a79d9 100644
--- a/lib/erl_interface/src/registry/hash.h
+++ b/lib/erl_interface/src/registry/hash.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_dohash.c b/lib/erl_interface/src/registry/hash_dohash.c
index f672dce9b3..0be54e0d3d 100644
--- a/lib/erl_interface/src/registry/hash_dohash.c
+++ b/lib/erl_interface/src/registry/hash_dohash.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_foreach.c b/lib/erl_interface/src/registry/hash_foreach.c
index 77afc7ade1..2fe8eebfbc 100644
--- a/lib/erl_interface/src/registry/hash_foreach.c
+++ b/lib/erl_interface/src/registry/hash_foreach.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_freetab.c b/lib/erl_interface/src/registry/hash_freetab.c
index cd428e55cf..e509af4a69 100644
--- a/lib/erl_interface/src/registry/hash_freetab.c
+++ b/lib/erl_interface/src/registry/hash_freetab.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_insert.c b/lib/erl_interface/src/registry/hash_insert.c
index dbe76282ae..d1b27ee6fe 100644
--- a/lib/erl_interface/src/registry/hash_insert.c
+++ b/lib/erl_interface/src/registry/hash_insert.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_isprime.c b/lib/erl_interface/src/registry/hash_isprime.c
index cdef2591ab..18fd74fbc7 100644
--- a/lib/erl_interface/src/registry/hash_isprime.c
+++ b/lib/erl_interface/src/registry/hash_isprime.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_lookup.c b/lib/erl_interface/src/registry/hash_lookup.c
index 0a466cc519..3a6643ad69 100644
--- a/lib/erl_interface/src/registry/hash_lookup.c
+++ b/lib/erl_interface/src/registry/hash_lookup.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_newtab.c b/lib/erl_interface/src/registry/hash_newtab.c
index b900de1f69..08ecc60f8a 100644
--- a/lib/erl_interface/src/registry/hash_newtab.c
+++ b/lib/erl_interface/src/registry/hash_newtab.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_remove.c b/lib/erl_interface/src/registry/hash_remove.c
index cebe00da1c..63484daff6 100644
--- a/lib/erl_interface/src/registry/hash_remove.c
+++ b/lib/erl_interface/src/registry/hash_remove.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_resize.c b/lib/erl_interface/src/registry/hash_resize.c
index 9c34a0d41c..c556ab7b68 100644
--- a/lib/erl_interface/src/registry/hash_resize.c
+++ b/lib/erl_interface/src/registry/hash_resize.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/hash_rlookup.c b/lib/erl_interface/src/registry/hash_rlookup.c
index 5d401555d8..d774089e36 100644
--- a/lib/erl_interface/src/registry/hash_rlookup.c
+++ b/lib/erl_interface/src/registry/hash_rlookup.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg.h b/lib/erl_interface/src/registry/reg.h
index cb7685506c..92798f02c8 100644
--- a/lib/erl_interface/src/registry/reg.h
+++ b/lib/erl_interface/src/registry/reg.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_close.c b/lib/erl_interface/src/registry/reg_close.c
index b699e59ac8..1ac9e623a7 100644
--- a/lib/erl_interface/src/registry/reg_close.c
+++ b/lib/erl_interface/src/registry/reg_close.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_delete.c b/lib/erl_interface/src/registry/reg_delete.c
index 8e84e205ee..b1fb7a1fac 100644
--- a/lib/erl_interface/src/registry/reg_delete.c
+++ b/lib/erl_interface/src/registry/reg_delete.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_dirty.c b/lib/erl_interface/src/registry/reg_dirty.c
index 730b4445c6..a128136054 100644
--- a/lib/erl_interface/src/registry/reg_dirty.c
+++ b/lib/erl_interface/src/registry/reg_dirty.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_dump.c b/lib/erl_interface/src/registry/reg_dump.c
index d2854c10b5..d1347491e5 100644
--- a/lib/erl_interface/src/registry/reg_dump.c
+++ b/lib/erl_interface/src/registry/reg_dump.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_free.c b/lib/erl_interface/src/registry/reg_free.c
index e3245577a5..aff6782925 100644
--- a/lib/erl_interface/src/registry/reg_free.c
+++ b/lib/erl_interface/src/registry/reg_free.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_get.c b/lib/erl_interface/src/registry/reg_get.c
index d1909b3fed..e3f111e746 100644
--- a/lib/erl_interface/src/registry/reg_get.c
+++ b/lib/erl_interface/src/registry/reg_get.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_getf.c b/lib/erl_interface/src/registry/reg_getf.c
index faed2f2df9..20071d6d95 100644
--- a/lib/erl_interface/src/registry/reg_getf.c
+++ b/lib/erl_interface/src/registry/reg_getf.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_geti.c b/lib/erl_interface/src/registry/reg_geti.c
index b746a4a92b..14c8a17b51 100644
--- a/lib/erl_interface/src/registry/reg_geti.c
+++ b/lib/erl_interface/src/registry/reg_geti.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_getp.c b/lib/erl_interface/src/registry/reg_getp.c
index bacfdc05c4..b60aa9d37f 100644
--- a/lib/erl_interface/src/registry/reg_getp.c
+++ b/lib/erl_interface/src/registry/reg_getp.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_gets.c b/lib/erl_interface/src/registry/reg_gets.c
index d6e6d67ebe..32d34197c2 100644
--- a/lib/erl_interface/src/registry/reg_gets.c
+++ b/lib/erl_interface/src/registry/reg_gets.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_make.c b/lib/erl_interface/src/registry/reg_make.c
index 179cb8bf47..11373afab9 100644
--- a/lib/erl_interface/src/registry/reg_make.c
+++ b/lib/erl_interface/src/registry/reg_make.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_open.c b/lib/erl_interface/src/registry/reg_open.c
index 0c2031707d..9965416599 100644
--- a/lib/erl_interface/src/registry/reg_open.c
+++ b/lib/erl_interface/src/registry/reg_open.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_purge.c b/lib/erl_interface/src/registry/reg_purge.c
index 329fd32f23..b585a43a64 100644
--- a/lib/erl_interface/src/registry/reg_purge.c
+++ b/lib/erl_interface/src/registry/reg_purge.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_resize.c b/lib/erl_interface/src/registry/reg_resize.c
index 8e4794ccf7..18a2c2670e 100644
--- a/lib/erl_interface/src/registry/reg_resize.c
+++ b/lib/erl_interface/src/registry/reg_resize.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_restore.c b/lib/erl_interface/src/registry/reg_restore.c
index 7bc1c758af..49e8f2740d 100644
--- a/lib/erl_interface/src/registry/reg_restore.c
+++ b/lib/erl_interface/src/registry/reg_restore.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_set.c b/lib/erl_interface/src/registry/reg_set.c
index 70ade09ffa..0519246a7f 100644
--- a/lib/erl_interface/src/registry/reg_set.c
+++ b/lib/erl_interface/src/registry/reg_set.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_setf.c b/lib/erl_interface/src/registry/reg_setf.c
index 1021174074..abbe409f10 100644
--- a/lib/erl_interface/src/registry/reg_setf.c
+++ b/lib/erl_interface/src/registry/reg_setf.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_seti.c b/lib/erl_interface/src/registry/reg_seti.c
index 430a3b6d47..afb3b1fee7 100644
--- a/lib/erl_interface/src/registry/reg_seti.c
+++ b/lib/erl_interface/src/registry/reg_seti.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_setp.c b/lib/erl_interface/src/registry/reg_setp.c
index a994c14c78..dd8038a811 100644
--- a/lib/erl_interface/src/registry/reg_setp.c
+++ b/lib/erl_interface/src/registry/reg_setp.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_sets.c b/lib/erl_interface/src/registry/reg_sets.c
index 14bdb2699d..7f0e64162f 100644
--- a/lib/erl_interface/src/registry/reg_sets.c
+++ b/lib/erl_interface/src/registry/reg_sets.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_stat.c b/lib/erl_interface/src/registry/reg_stat.c
index c3f669fd4f..e876aa566c 100644
--- a/lib/erl_interface/src/registry/reg_stat.c
+++ b/lib/erl_interface/src/registry/reg_stat.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/src/registry/reg_tabstat.c b/lib/erl_interface/src/registry/reg_tabstat.c
index edfb19fa00..2c5d185ec1 100644
--- a/lib/erl_interface/src/registry/reg_tabstat.c
+++ b/lib/erl_interface/src/registry/reg_tabstat.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
index 1ed34c74a0..800573e8e4 100644
--- a/lib/erl_interface/test/Makefile
+++ b/lib/erl_interface/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/Makefile.src b/lib/erl_interface/test/Makefile.src
index 4f11b5675e..f105a1a3d1 100644
--- a/lib/erl_interface/test/Makefile.src
+++ b/lib/erl_interface/test/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.first b/lib/erl_interface/test/all_SUITE_data/Makefile.first
index b9ce689057..fe295b5e5c 100644
--- a/lib/erl_interface/test/all_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/all_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.src b/lib/erl_interface/test/all_SUITE_data/Makefile.src
index 5efe7d42db..476784230b 100644
--- a/lib/erl_interface/test/all_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/all_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.c b/lib/erl_interface/test/all_SUITE_data/ei_runner.c
index 196a77dce5..3a0de22df4 100644
--- a/lib/erl_interface/test/all_SUITE_data/ei_runner.c
+++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.h b/lib/erl_interface/test/all_SUITE_data/ei_runner.h
index a037341d57..62997d00a0 100644
--- a/lib/erl_interface/test/all_SUITE_data/ei_runner.h
+++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.c b/lib/erl_interface/test/all_SUITE_data/gccifier.c
index 7e4ffc7281..ca022eb390 100644
--- a/lib/erl_interface/test/all_SUITE_data/gccifier.c
+++ b/lib/erl_interface/test/all_SUITE_data/gccifier.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.sh b/lib/erl_interface/test/all_SUITE_data/gccifier.sh
index 42253213b1..594608df9f 100755
--- a/lib/erl_interface/test/all_SUITE_data/gccifier.sh
+++ b/lib/erl_interface/test/all_SUITE_data/gccifier.sh
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2005-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/all_SUITE_data/init_tc.erl b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
index 5245173260..74d32d9ea4 100644
--- a/lib/erl_interface/test/all_SUITE_data/init_tc.erl
+++ b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/all_SUITE_data/reclaim.h b/lib/erl_interface/test/all_SUITE_data/reclaim.h
index 00fdfc38dc..eb0f7ce9fa 100644
--- a/lib/erl_interface/test/all_SUITE_data/reclaim.h
+++ b/lib/erl_interface/test/all_SUITE_data/reclaim.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/test/all_SUITE_data/runner.c b/lib/erl_interface/test/all_SUITE_data/runner.c
index 038d651275..47d918308d 100644
--- a/lib/erl_interface/test/all_SUITE_data/runner.c
+++ b/lib/erl_interface/test/all_SUITE_data/runner.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/all_SUITE_data/runner.h b/lib/erl_interface/test/all_SUITE_data/runner.h
index fb29d5166d..2af267ecb9 100644
--- a/lib/erl_interface/test/all_SUITE_data/runner.h
+++ b/lib/erl_interface/test/all_SUITE_data/runner.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl
index 642809ea7a..144ec99e0a 100644
--- a/lib/erl_interface/test/ei_accept_SUITE.erl
+++ b/lib/erl_interface/test/ei_accept_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first
index d7ec976cd0..8153368870 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
index d6e58559cd..d900b4aa8f 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
index 5f898b5944..ad68ba9bb5 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
index af58f75963..6a3d2bc157 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl
index 432437d3b8..3385d1eb6c 100644
--- a/lib/erl_interface/test/ei_connect_SUITE.erl
+++ b/lib/erl_interface/test/ei_connect_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first
index 8bf22e366e..feee049795 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
index c2db6436f3..49e5e8f8e2 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
index 88a9950994..cfad73fd07 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
index bafe8bd5bd..f151f6d2d6 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl
index ccdc19dbbd..0abcf50fb5 100644
--- a/lib/erl_interface/test/ei_decode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first
index 0791b54109..74a49dbdab 100644
--- a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src
index 0b2b0560bf..54c40e52a4 100644
--- a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
index 3f6cbbe186..a0bafe543d 100644
--- a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
index 7caec6ac04..3c7e4bf70d 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first
index 168a21b10e..6edcc0c5ed 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src
index d9464f3b75..03db2ae9f2 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
index fcf546105b..4b0201ca0b 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl
index 50dc8b6a3c..6213916314 100644
--- a/lib/erl_interface/test/ei_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_encode_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -174,7 +175,7 @@ test_ei_encode_ulonglong(Config) when is_list(Config) ->
%% ######################################################################## %%
-%% A "character" for us is an 8 bit integer, alwasy positive, i.e.
+%% A "character" for us is an 8 bit integer, always positive, i.e.
%% it is unsigned.
%% FIXME maybe the API should change to use "unsigned char" to be clear?!
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first
index 19a6f4c0aa..26ba7f475e 100644
--- a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src
index 6e98bb968b..753700d7e2 100644
--- a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
index 50fcaace8d..ace368f8e6 100644
--- a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl
index 2a26ed142b..11cbae31db 100644
--- a/lib/erl_interface/test/ei_format_SUITE.erl
+++ b/lib/erl_interface/test/ei_format_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first
index 1247ce08c7..d655cd13e6 100644
--- a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src
index de062914c5..bfcb8ae840 100644
--- a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
index 2f53effd78..d3ca91db5a 100644
--- a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
+++ b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl
index 6305302e28..4309b883bb 100644
--- a/lib/erl_interface/test/ei_print_SUITE.erl
+++ b/lib/erl_interface/test/ei_print_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first
index e36d4364dc..987dbc27a9 100644
--- a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src
index 469b49a581..266fcfcb10 100644
--- a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
index 8ce89e237a..2db5450b77 100644
--- a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
+++ b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl
index c33beecbe9..689499f42f 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE.erl
+++ b/lib/erl_interface/test/ei_tmo_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first
index 6eb9f2ce71..a19eabb64a 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
index 4e8018b515..c6798a6644 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
index db90b1810e..1104f642a2 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl
index c8becc760c..f621310a1c 100644
--- a/lib/erl_interface/test/erl_connect_SUITE.erl
+++ b/lib/erl_interface/test/erl_connect_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
index 09c00e7b8c..f0b8eef6bd 100644
--- a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
index dad2b5ea90..57db6f6024 100644
--- a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c b/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
index 02304260b8..11c0daa4c5 100644
--- a/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
+++ b/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl
index 100e9b6f68..8fbef35309 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE.erl
+++ b/lib/erl_interface/test/erl_eterm_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
index 0f25fcc0a9..4a8664429e 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
index 8f27e5495b..31584ff686 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
index 133f35f4bd..df40a4414e 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
index 94959187b9..0a2ecf9dcc 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c b/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
index fd91373c3e..e474e8f7ab 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/erl_ext_SUITE.erl b/lib/erl_interface/test/erl_ext_SUITE.erl
index fc3e823d42..f73c15e15f 100644
--- a/lib/erl_interface/test/erl_ext_SUITE.erl
+++ b/lib/erl_interface/test/erl_ext_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first
index cb7b12cc79..ddff1ba13f 100644
--- a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src
index 7a532ea0ed..6f3fdec8a4 100644
--- a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
index a4a8da6347..65d5f0d2e0 100644
--- a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/erl_interface/test/erl_format_SUITE.erl b/lib/erl_interface/test/erl_format_SUITE.erl
index c722bd050f..8c01a9914f 100644
--- a/lib/erl_interface/test/erl_format_SUITE.erl
+++ b/lib/erl_interface/test/erl_format_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
index 2cd313a324..9fc4e742bd 100644
--- a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
index 73f4b1c685..4f5f780f31 100644
--- a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/format_test.c b/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
index 75e73b6df5..179327ede0 100644
--- a/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
+++ b/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/erl_global_SUITE.erl
index a27cb0664c..b719ad5c6a 100644
--- a/lib/erl_interface/test/erl_global_SUITE.erl
+++ b/lib/erl_interface/test/erl_global_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
index 8e3fcb924e..ec77ef3dc2 100644
--- a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
index ec159b0be0..4cbf51713b 100644
--- a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
index dc0d8a0091..5a17069751 100644
--- a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
+++ b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2000-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl
index 2cf4fafe82..d8f7bd89b4 100644
--- a/lib/erl_interface/test/erl_match_SUITE.erl
+++ b/lib/erl_interface/test/erl_match_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
index 12141d210c..867c59802f 100644
--- a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
index dd5ea98d71..5753a417fb 100644
--- a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/match_test.c b/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
index 153a528b0b..c508786ba8 100644
--- a/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
+++ b/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/port_call_SUITE.erl b/lib/erl_interface/test/port_call_SUITE.erl
index 1ce5b0b748..b0f5ed4fe9 100644
--- a/lib/erl_interface/test/port_call_SUITE.erl
+++ b/lib/erl_interface/test/port_call_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
index 7672b3dcd2..12b9fcae76 100644
--- a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c b/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
index abc76085de..ac23a650c1 100644
--- a/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
+++ b/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/erl_interface/test/runner.erl b/lib/erl_interface/test/runner.erl
index e41440708a..ae2598abf8 100644
--- a/lib/erl_interface/test/runner.erl
+++ b/lib/erl_interface/test/runner.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index c809d5421e..56dbdbac9f 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1,2 +1,2 @@
-EI_VSN = 3.7.20
+EI_VSN = 3.8.2
ERL_INTERFACE_VSN = $(EI_VSN)
diff --git a/lib/et/Makefile b/lib/et/Makefile
index 1b3476897e..b93ebef902 100644
--- a/lib/et/Makefile
+++ b/lib/et/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/et/doc/src/Makefile b/lib/et/doc/src/Makefile
index 249d45fa52..532e28f5d3 100644
--- a/lib/et/doc/src/Makefile
+++ b/lib/et/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/et/doc/src/book.xml b/lib/et/doc/src/book.xml
index 6c78f2ca07..d3fef1752c 100644
--- a/lib/et/doc/src/book.xml
+++ b/lib/et/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/doc/src/et.xml b/lib/et/doc/src/et.xml
index f1f74df1b1..0ba858cc08 100644
--- a/lib/et/doc/src/et.xml
+++ b/lib/et/doc/src/et.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/et/doc/src/et_collector.xml b/lib/et/doc/src/et_collector.xml
index 8b4592ac63..e879a119a5 100644
--- a/lib/et/doc/src/et_collector.xml
+++ b/lib/et/doc/src/et_collector.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/et/doc/src/et_desc.xmlsrc b/lib/et/doc/src/et_desc.xmlsrc
index a4240db2ba..cbb41f700c 100644
--- a/lib/et/doc/src/et_desc.xmlsrc
+++ b/lib/et/doc/src/et_desc.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/doc/src/et_examples.xmlsrc b/lib/et/doc/src/et_examples.xmlsrc
index 3bd95bcb06..42e484a241 100644
--- a/lib/et/doc/src/et_examples.xmlsrc
+++ b/lib/et/doc/src/et_examples.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/doc/src/et_intro.xml b/lib/et/doc/src/et_intro.xml
index 62cc291d4c..cfc879e43d 100644
--- a/lib/et/doc/src/et_intro.xml
+++ b/lib/et/doc/src/et_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/doc/src/et_selector.xml b/lib/et/doc/src/et_selector.xml
index 72392fdfe4..af62401287 100644
--- a/lib/et/doc/src/et_selector.xml
+++ b/lib/et/doc/src/et_selector.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/doc/src/et_tutorial.xmlsrc b/lib/et/doc/src/et_tutorial.xmlsrc
index 02c303f66e..6e3b327ee7 100644
--- a/lib/et/doc/src/et_tutorial.xmlsrc
+++ b/lib/et/doc/src/et_tutorial.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/doc/src/et_viewer.xml b/lib/et/doc/src/et_viewer.xml
index 695725f281..c7917b41ce 100644
--- a/lib/et/doc/src/et_viewer.xml
+++ b/lib/et/doc/src/et_viewer.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/et/doc/src/files.mk b/lib/et/doc/src/files.mk
index 41fffb83f1..c8721c61fe 100644
--- a/lib/et/doc/src/files.mk
+++ b/lib/et/doc/src/files.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml
index e122187cf3..6599025d52 100644
--- a/lib/et/doc/src/notes.xml
+++ b/lib/et/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -36,6 +37,24 @@
one section in this document. The title of each section is the
version number of <c>Event Tracer (ET)</c>.</p>
+<section><title>ET 1.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The <c>et</c> application must continue to use
+ <c>erlang:now/0</c> in order to obtain timestamps that
+ are consistent with timestamps obtained from tracing. The
+ application has been updated to suppress the warning for
+ <c>erlang:now/0</c>.</p>
+ <p>
+ Own Id: OTP-12780</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>ET 1.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/et/doc/src/part.xml b/lib/et/doc/src/part.xml
index 7048e3a401..d8e5e76685 100644
--- a/lib/et/doc/src/part.xml
+++ b/lib/et/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/et/doc/src/ref_man.xml b/lib/et/doc/src/ref_man.xml
index 47706339b6..68ed5a8756 100644
--- a/lib/et/doc/src/ref_man.xml
+++ b/lib/et/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/et/examples/Makefile b/lib/et/examples/Makefile
index 3edbebc2e4..215ce6e4cd 100644
--- a/lib/et/examples/Makefile
+++ b/lib/et/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/et/examples/et_demo.erl b/lib/et/examples/et_demo.erl
index e439e6882c..e2a604b451 100644
--- a/lib/et/examples/et_demo.erl
+++ b/lib/et/examples/et_demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/et/include/et.hrl b/lib/et/include/et.hrl
index b2cb7d17c3..450044df42 100644
--- a/lib/et/include/et.hrl
+++ b/lib/et/include/et.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/et/src/Makefile b/lib/et/src/Makefile
index 377e593712..461a52d480 100644
--- a/lib/et/src/Makefile
+++ b/lib/et/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -65,7 +66,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/et/ebin -I../include
+ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/et/ebin -I../include -Werror
# ----------------------------------------------------
# Special Build Targets
diff --git a/lib/et/src/et.app.src b/lib/et/src/et.app.src
index c26d9320d8..ddf86beea3 100644
--- a/lib/et/src/et.app.src
+++ b/lib/et/src/et.app.src
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/et/src/et.appup.src b/lib/et/src/et.appup.src
index 5f15b00386..0fbde99762 100644
--- a/lib/et/src/et.appup.src
+++ b/lib/et/src/et.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/et/src/et.erl b/lib/et/src/et.erl
index c9ba4f6816..d38fe917c8 100644
--- a/lib/et/src/et.erl
+++ b/lib/et/src/et.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/et/src/et_collector.erl b/lib/et/src/et_collector.erl
index e05c67be60..56e59461b2 100644
--- a/lib/et/src/et_collector.erl
+++ b/lib/et/src/et_collector.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -64,6 +65,8 @@
-export([init/1,terminate/2, code_change/3,
handle_call/3, handle_cast/2, handle_info/2]).
+-compile([{nowarn_deprecated_function,[{erlang,now,0}]}]).
+
-include("et_internal.hrl").
-include("../include/et.hrl").
diff --git a/lib/et/src/et_internal.hrl b/lib/et/src/et_internal.hrl
index 419d35afcd..01c7303d0b 100644
--- a/lib/et/src/et_internal.hrl
+++ b/lib/et/src/et_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/et/src/et_selector.erl b/lib/et/src/et_selector.erl
index c8e9c907b2..708a0b4cd8 100644
--- a/lib/et/src/et_selector.erl
+++ b/lib/et/src/et_selector.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,6 +29,8 @@
parse_event/2
]).
+-compile([{nowarn_deprecated_function,[{erlang,now,0}]}]).
+
-include("../include/et.hrl").
%%----------------------------------------------------------------------
diff --git a/lib/et/src/et_viewer.erl b/lib/et/src/et_viewer.erl
index ead5639da6..1a962df147 100644
--- a/lib/et/src/et_viewer.erl
+++ b/lib/et/src/et_viewer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/et/src/et_wx_contents_viewer.erl b/lib/et/src/et_wx_contents_viewer.erl
index b559da8807..46898c6fbf 100644
--- a/lib/et/src/et_wx_contents_viewer.erl
+++ b/lib/et/src/et_wx_contents_viewer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/et/src/et_wx_viewer.erl b/lib/et/src/et_wx_viewer.erl
index 386f8fc86b..1e71880b79 100644
--- a/lib/et/src/et_wx_viewer.erl
+++ b/lib/et/src/et_wx_viewer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/et/src/modules.mk b/lib/et/src/modules.mk
index b2d2f0b481..0568306b65 100644
--- a/lib/et/src/modules.mk
+++ b/lib/et/src/modules.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/et/subdirs.mk b/lib/et/subdirs.mk
index d6382463e3..6568459be1 100644
--- a/lib/et/subdirs.mk
+++ b/lib/et/subdirs.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/et/test/Makefile b/lib/et/test/Makefile
index 1be5aac3fd..0434d4ebfd 100644
--- a/lib/et/test/Makefile
+++ b/lib/et/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/et/test/et_SUITE.erl b/lib/et/test/et_SUITE.erl
index e0bce41e15..4a26b46439 100644
--- a/lib/et/test/et_SUITE.erl
+++ b/lib/et/test/et_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/et/test/et_test_lib.erl b/lib/et/test/et_test_lib.erl
index c1bfeb9fc0..6e252de4e5 100644
--- a/lib/et/test/et_test_lib.erl
+++ b/lib/et/test/et_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/et/test/et_test_lib.hrl b/lib/et/test/et_test_lib.hrl
index 0d75318d99..9f2a432e04 100644
--- a/lib/et/test/et_test_lib.hrl
+++ b/lib/et/test/et_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/et/test/et_wx_SUITE.erl b/lib/et/test/et_wx_SUITE.erl
index b5f98f8616..165a2bca49 100644
--- a/lib/et/test/et_wx_SUITE.erl
+++ b/lib/et/test/et_wx_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/et/test/ett b/lib/et/test/ett
index da2443df61..53aaeada55 100755
--- a/lib/et/test/ett
+++ b/lib/et/test/ett
@@ -3,16 +3,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/et/test/ett.erl b/lib/et/test/ett.erl
index 1896e65842..e78f6c392e 100644
--- a/lib/et/test/ett.erl
+++ b/lib/et/test/ett.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk
index a47be678ca..0af7bf75e1 100644
--- a/lib/et/vsn.mk
+++ b/lib/et/vsn.mk
@@ -1 +1 @@
-ET_VSN = 1.5
+ET_VSN = 1.5.1
diff --git a/lib/eunit/Makefile b/lib/eunit/Makefile
index cd85dff06a..15dae19896 100644
--- a/lib/eunit/Makefile
+++ b/lib/eunit/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/eunit/doc/overview.edoc b/lib/eunit/doc/overview.edoc
index 872a017440..12ea02f442 100644
--- a/lib/eunit/doc/overview.edoc
+++ b/lib/eunit/doc/overview.edoc
@@ -569,6 +569,9 @@ Examples:
```?assertMatch({found, {fred, _}}, lookup(bloggs, Table))'''
```?assertMatch([X|_] when X > 0, binary_to_list(B))'''
</dd>
+<dt>`assertNotMatch(GuardedPattern, Expr)'</dt>
+<dd>The inverse case of assertMatch, for convenience.
+</dd>
<dt>`assertEqual(Expect, Expr)'</dt>
<dd>Evaluates the expressions `Expect' and `Expr' and compares the
results for equality, if testing is enabled. If the values are not
@@ -583,6 +586,9 @@ Examples:
```?assertEqual("b" ++ "a", lists:reverse("ab"))'''
```?assertEqual(foo(X), bar(Y))'''
</dd>
+<dt>`assertNotEqual(Unexpected, Expr)'</dt>
+<dd>The inverse case of assertEqual, for convenience.
+</dd>
<dt>`assertException(ClassPattern, TermPattern, Expr)'</dt>
<dt>`assertError(TermPattern, Expr)'</dt>
<dt>`assertExit(TermPattern, Expr)'</dt>
@@ -879,7 +885,7 @@ the timeout is exceeded, the unfinished tests will be forced to
terminate. Note that if a timeout is set around a fixture, it includes
the time for setup and cleanup, and if the timeout is triggered, the
entire fixture is abruptly terminated (without running the
-cleanup).</dd>
+cleanup). The default timeout for an individual test is 5 seconds.</dd>
<dt>`{inorder, Tests}'</dt>
<dd>Runs the specified tests in strict order. Also see `{inparallel,
Tests}'. By default, tests are neither marked as `inorder' or
@@ -901,7 +907,6 @@ the test set is finished, regardless of the outcome (success, failures,
timeouts, etc.).
To make the descriptions simpler, we first list some definitions:
-<center>
<table border="0" cellspacing="4">
<tr>
<td>`Setup'</td><td>`() -> (R::any())'</td>
@@ -922,7 +927,6 @@ To make the descriptions simpler, we first list some definitions:
<td>`Where'</td><td>`local | spawn | {spawn, Node::atom()}'</td>
</tr>
</table>
-</center>
(these are explained in more detail further below.)
The following representations specify fixture handling for test sets:
diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile
index cbcd4c1507..f1491eb873 100644
--- a/lib/eunit/doc/src/Makefile
+++ b/lib/eunit/doc/src/Makefile
@@ -3,16 +3,17 @@
# <holder>Ericsson AB, All Rights Reserved</holder>
#</copyright>
#<legalnotice>
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# The Initial Developer of the Original Code is Ericsson AB.
#</legalnotice>
diff --git a/lib/eunit/doc/src/book.xml b/lib/eunit/doc/src/book.xml
index c9bd320d5a..6cd2b93c68 100644
--- a/lib/eunit/doc/src/book.xml
+++ b/lib/eunit/doc/src/book.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index 6b76e097b6..398729217b 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -32,6 +33,64 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
+<section><title>Eunit 2.2.13</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Suppress Dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-12862</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eunit 2.2.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Small documentation fixes</p>
+ <p>
+ Own Id: OTP-13017</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eunit 2.2.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Improve success message when 2 tests have passed</p>
+ <p>
+ Own Id: OTP-12952</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eunit 2.2.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The <c>eunit</c> application is now unicode safe.</p>
+ <p>
+ Own Id: OTP-11660</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eunit 2.2.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/eunit/doc/src/part.xml b/lib/eunit/doc/src/part.xml
index 4ce63f7a94..a4484c2c23 100644
--- a/lib/eunit/doc/src/part.xml
+++ b/lib/eunit/doc/src/part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/eunit/doc/src/part_notes.xml b/lib/eunit/doc/src/part_notes.xml
index 149a4f79f0..fbecfe3f11 100644
--- a/lib/eunit/doc/src/part_notes.xml
+++ b/lib/eunit/doc/src/part_notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/eunit/doc/src/ref_man.xml b/lib/eunit/doc/src/ref_man.xml
index 1e59ad1c7d..c573df2a4f 100644
--- a/lib/eunit/doc/src/ref_man.xml
+++ b/lib/eunit/doc/src/ref_man.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/eunit/examples/Makefile b/lib/eunit/examples/Makefile
index cfa0a7a645..01620746f5 100644
--- a/lib/eunit/examples/Makefile
+++ b/lib/eunit/examples/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/eunit/include/eunit.hrl b/lib/eunit/include/eunit.hrl
index 9e8d34567a..8f678b0290 100644
--- a/lib/eunit/include/eunit.hrl
+++ b/lib/eunit/include/eunit.hrl
@@ -15,11 +15,14 @@
%%
%% Copyright (C) 2004-2006 Mickaël Rémond, Richard Carlsson
+-ifndef(EUNIT_HRL).
+-define(EUNIT_HRL, true).
+
%% Including this file turns on testing and defines TEST, unless NOTEST
%% is defined before the file is included. If both NOTEST and TEST are
%% already defined, then TEST takes precedence, and NOTEST will become
%% undefined.
-%%
+%%
%% If NODEBUG is defined before this file is included, the debug macros
%% are disabled, unless DEBUG is also defined, in which case NODEBUG
%% will become undefined. NODEBUG also implies NOASSERT, unless testing
@@ -31,14 +34,10 @@
%% even if NODEBUG is defined. If both ASSERT and NOASSERT are defined
%% before the file is included, then ASSERT takes precedence, and NOASSERT
%% will become undefined regardless of TEST.
-%%
+%%
%% After including this file, EUNIT will be defined if and only if TEST
%% is defined.
--ifndef(EUNIT_HRL).
--define(EUNIT_HRL, true).
-
-
%% allow defining TEST to override NOTEST
-ifdef(TEST).
-undef(NOTEST).
@@ -49,13 +48,6 @@
-undef(NODEBUG).
-endif.
-%% allow NODEBUG to imply NOASSERT, unless overridden below
--ifdef(NODEBUG).
--ifndef(NOASSERT).
--define(NOASSERT, true).
--endif.
--endif.
-
%% note that the main switch used within this file is NOTEST; however,
%% both TEST and EUNIT may be used to check whether testing is enabled
-ifndef(NOTEST).
@@ -70,10 +62,8 @@
-undef(EUNIT).
-endif.
-%% allow ASSERT to override NOASSERT (regardless of TEST/NOTEST)
--ifdef(ASSERT).
--undef(NOASSERT).
--endif.
+%% include the assert macros; ASSERT overrides NOASSERT if defined
+-include_lib("stdlib/include/assert.hrl").
%% Parse transforms for automatic exporting/stripping of test functions.
%% (Note that although automatic stripping is convenient, it will make
@@ -91,7 +81,7 @@
%% All macros should be available even if testing is turned off, and
%% should preferably not require EUnit to be present at runtime.
-%%
+%%
%% We must use fun-call wrappers ((fun () -> ... end)()) to avoid
%% exporting local variables, and furthermore we only use variable names
%% prefixed with "__", that hopefully will not be bound outside the fun.
@@ -128,209 +118,21 @@
current_function)))).
-endif.
-%% The plain assert macro should be defined to do nothing if this file
-%% is included when debugging/testing is turned off.
--ifdef(NOASSERT).
--ifndef(assert).
--define(assert(BoolExpr),ok).
--endif.
--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.
--undef(assert).
--define(assert(BoolExpr),
- begin
- ((fun () ->
- case (BoolExpr) of
- true -> ok;
- __V -> erlang:error({assertion_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??BoolExpr)},
- {expected, true},
- {value, case __V of false -> __V;
- _ -> {not_a_boolean,__V}
- end}]})
- end
- end)())
- end).
--endif.
--define(assertNot(BoolExpr), ?assert(not (BoolExpr))).
+%% General test macros
-define(_test(Expr), {?LINE, fun () -> (Expr) end}).
-
-define(_assert(BoolExpr), ?_test(?assert(BoolExpr))).
-
-define(_assertNot(BoolExpr), ?_assert(not (BoolExpr))).
-
-%% 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).
--else.
--define(assertMatch(Guard, Expr),
- begin
- ((fun () ->
- case (Expr) of
- Guard -> ok;
- __V -> erlang:error({assertMatch_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern, (??Guard)},
- {value, __V}]})
- end
- end)())
- end).
--endif.
-define(_assertMatch(Guard, Expr), ?_test(?assertMatch(Guard, Expr))).
-
-%% This is the inverse case of assertMatch, for convenience.
--ifdef(NOASSERT).
--define(assertNotMatch(Guard, Expr), ok).
--else.
--define(assertNotMatch(Guard, Expr),
- begin
- ((fun () ->
- __V = (Expr),
- case __V of
- Guard -> erlang:error({assertNotMatch_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern, (??Guard)},
- {value, __V}]});
- _ -> ok
- end
- end)())
- end).
--endif.
-define(_assertNotMatch(Guard, Expr), ?_test(?assertNotMatch(Guard, Expr))).
-
-%% 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).
--else.
--define(assertEqual(Expect, Expr),
- begin
- ((fun (__X) ->
- case (Expr) of
- __X -> ok;
- __V -> erlang:error({assertEqual_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {expected, __X},
- {value, __V}]})
- end
- end)(Expect))
- end).
--endif.
-define(_assertEqual(Expect, Expr), ?_test(?assertEqual(Expect, Expr))).
-
-%% This is the inverse case of assertEqual, for convenience.
--ifdef(NOASSERT).
--define(assertNotEqual(Unexpected, Expr), ok).
--else.
--define(assertNotEqual(Unexpected, Expr),
- begin
- ((fun (__X) ->
- case (Expr) of
- __X -> erlang:error({assertNotEqual_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {value, __X}]});
- _ -> ok
- end
- end)(Unexpected))
- end).
--endif.
-define(_assertNotEqual(Unexpected, Expr),
?_test(?assertNotEqual(Unexpected, Expr))).
-
-%% 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).
--else.
--define(assertException(Class, Term, Expr),
- begin
- ((fun () ->
- try (Expr) of
- __V -> erlang:error({assertException_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern,
- "{ "++(??Class)++" , "++(??Term)
- ++" , [...] }"},
- {unexpected_success, __V}]})
- catch
- Class:Term -> ok;
- __C:__T ->
- erlang:error({assertException_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {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(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
--define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
-
-define(_assertException(Class, Term, Expr),
?_test(?assertException(Class, Term, Expr))).
-define(_assertError(Term, Expr), ?_assertException(error, Term, Expr)).
-define(_assertExit(Term, Expr), ?_assertException(exit, Term, Expr)).
-define(_assertThrow(Term, Expr), ?_assertException(throw, Term, Expr)).
-
-%% 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).
--else.
--define(assertNotException(Class, Term, Expr),
- begin
- ((fun () ->
- try (Expr) of
- _ -> ok
- catch
- __C:__T ->
- case __C of
- Class ->
- case __T of
- Term ->
- erlang:error({assertNotException_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern,
- "{ "++(??Class)++" , "
- ++(??Term)++" , [...] }"},
- {unexpected_exception,
- {__C, __T,
- erlang:get_stacktrace()
- }}]});
- _ -> ok
- end;
- _ -> ok
- end
- end
- end)())
- end).
--endif.
-define(_assertNotException(Class, Term, Expr),
?_test(?assertNotException(Class, Term, Expr))).
@@ -364,18 +166,18 @@
-else.
-define(assertCmdStatus(N, Cmd),
begin
- ((fun () ->
- case ?_cmd_(Cmd) of
- {(N), _} -> ok;
- {__N, _} -> erlang:error({assertCmd_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {command, (Cmd)},
- {expected_status,(N)},
- {status,__N}]})
- end
- end)())
- end).
+ ((fun () ->
+ case ?_cmd_(Cmd) of
+ {(N), _} -> ok;
+ {__N, _} -> erlang:error({assertCmd_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {command, (Cmd)},
+ {expected_status,(N)},
+ {status,__N}]})
+ end
+ end)())
+ end).
-endif.
-define(assertCmd(Cmd), ?assertCmdStatus(0, Cmd)).
@@ -384,17 +186,17 @@
-else.
-define(assertCmdOutput(T, Cmd),
begin
- ((fun () ->
- case ?_cmd_(Cmd) of
- {_, (T)} -> ok;
- {_, __T} -> erlang:error({assertCmdOutput_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {command,(Cmd)},
- {expected_output,(T)},
- {output,__T}]})
- end
- end)())
+ ((fun () ->
+ case ?_cmd_(Cmd) of
+ {_, (T)} -> ok;
+ {_, __T} -> erlang:error({assertCmdOutput_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {command,(Cmd)},
+ {expected_output,(T)},
+ {output,__T}]})
+ end
+ end)())
end).
-endif.
@@ -414,7 +216,7 @@
-else.
-define(debugMsg(S),
begin
- io:fwrite(user, <<"~s:~w:~w: ~s\n">>,
+ io:fwrite(user, <<"~ts:~w:~w: ~ts\n">>,
[?FILE, ?LINE, self(), S]),
ok
end).
@@ -423,7 +225,7 @@
-define(debugVal(E),
begin
((fun (__V) ->
- ?debugFmt(<<"~s = ~P">>, [(??E), __V, 15]),
+ ?debugFmt(<<"~ts = ~tP">>, [(??E), __V, 15]),
__V
end)(E))
end).
@@ -433,11 +235,10 @@
{__T0, _} = statistics(wall_clock),
__V = (E),
{__T1, _} = statistics(wall_clock),
- ?debugFmt(<<"~s: ~.3f s">>, [(S), (__T1-__T0)/1000]),
+ ?debugFmt(<<"~ts: ~.3f s">>, [(S), (__T1-__T0)/1000]),
__V
end)())
end).
-endif.
-
-endif. % EUNIT_HRL
diff --git a/lib/eunit/src/Makefile b/lib/eunit/src/Makefile
index 47aef104ff..86a6d8831e 100644
--- a/lib/eunit/src/Makefile
+++ b/lib/eunit/src/Makefile
@@ -24,7 +24,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/eunit-$(VSN)
EBIN = ../ebin
INCLUDE=../include
-ERL_COMPILE_FLAGS += -pa $(EBIN) -I$(INCLUDE) +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
+ERL_COMPILE_FLAGS += -pa $(EBIN) -pa ../../stdlib/ebin -I$(INCLUDE) +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
PARSE_TRANSFORM = eunit_autoexport.erl
diff --git a/lib/eunit/src/eunit.app.src b/lib/eunit/src/eunit.app.src
index 7a3978e200..b4ff6c9242 100644
--- a/lib/eunit/src/eunit.app.src
+++ b/lib/eunit/src/eunit.app.src
@@ -19,4 +19,4 @@
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}]}.
+ {runtime_dependencies, ["stdlib-2.5","kernel-3.0","erts-6.0"]}]}.
diff --git a/lib/eunit/src/eunit.appup.src b/lib/eunit/src/eunit.appup.src
index 18934d44c2..12dff80521 100644
--- a/lib/eunit/src/eunit.appup.src
+++ b/lib/eunit/src/eunit.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl
index 9c589dfa86..fbfd123c43 100644
--- a/lib/eunit/src/eunit.erl
+++ b/lib/eunit/src/eunit.erl
@@ -231,7 +231,7 @@ event_logger(LogFile) ->
event_logger_loop(Reference, FD) ->
receive
{status, _Id, _Info}=Msg ->
- io:fwrite(FD, "~p.\n", [Msg]),
+ io:fwrite(FD, "~tp.\n", [Msg]),
event_logger_loop(Reference, FD);
{stop, Reference, _ReplyTo} ->
%% no need to reply, just exit
diff --git a/lib/eunit/src/eunit_autoexport.erl b/lib/eunit/src/eunit_autoexport.erl
index 36ae3b71d7..7bb78f5ea8 100644
--- a/lib/eunit/src/eunit_autoexport.erl
+++ b/lib/eunit/src/eunit_autoexport.erl
@@ -79,11 +79,12 @@ rewrite([{function,_,test,0,_}=F | Fs], As, Module, _Test) ->
rewrite([F | Fs], As, Module, Test) ->
rewrite(Fs, [F | As], Module, Test);
rewrite([], As, Module, Test) ->
+ L = erl_anno:new(0),
{if Test ->
- [{function,0,test,0,
- [{clause,0,[],[],
- [{call,0,{remote,0,{atom,0,eunit},{atom,0,test}},
- [{atom,0,Module}]}]}]}
+ [{function,L,test,0,
+ [{clause,L,[],[],
+ [{call,L,{remote,L,{atom,L,eunit},{atom,L,test}},
+ [{atom,L,Module}]}]}]}
| As];
true ->
As
@@ -96,4 +97,4 @@ module_decl(Name, M, Fs, Exports) ->
Es = if Test -> [{test,0} | Exports];
true -> Exports
end,
- [M, {attribute,0,export,Es} | lists:reverse(Fs1)].
+ [M, {attribute,erl_anno:new(0),export,Es} | lists:reverse(Fs1)].
diff --git a/lib/eunit/src/eunit_data.erl b/lib/eunit/src/eunit_data.erl
index cbbc6fbc15..cc002cb449 100644
--- a/lib/eunit/src/eunit_data.erl
+++ b/lib/eunit/src/eunit_data.erl
@@ -391,7 +391,7 @@ parse({with, X, As}=T) when is_list(As) ->
parse({S, T1} = T) when is_list(S) ->
case eunit_lib:is_string(S) of
true ->
- group(#group{tests = T1, desc = list_to_binary(S)});
+ group(#group{tests = T1, desc = unicode:characters_to_binary(S)});
false ->
bad_test(T)
end;
@@ -761,6 +761,7 @@ lazy_test_() ->
lazy_gen(7),
?_assertMatch(7, get(count))]}.
+-dialyzer({no_improper_lists, lazy_gen/1}).
lazy_gen(N) ->
{generator,
fun () ->
diff --git a/lib/eunit/src/eunit_internal.hrl b/lib/eunit/src/eunit_internal.hrl
index 92694ec39b..8e1e27811f 100644
--- a/lib/eunit/src/eunit_internal.hrl
+++ b/lib/eunit/src/eunit_internal.hrl
@@ -14,8 +14,8 @@
-define(DEFAULT_MODULE_WRAPPER_NAME, eunit_wrapper_).
-ifdef(DEBUG).
--define(debugmsg(S),io:fwrite("\n* ~s: ~s\n", [?MODULE,S])).
--define(debugmsg1(S,As),io:fwrite("\n* ~s: " ++ S ++ "\n", [?MODULE] ++ As)).
+-define(debugmsg(S),io:fwrite("\n* ~ts: ~ts\n", [?MODULE,S])).
+-define(debugmsg1(S,As),io:fwrite("\n* ~ts: " ++ S ++ "\n", [?MODULE] ++ As)).
-else.
-define(debugmsg(S),ok).
-define(debugmsg1(S,As),ok).
diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl
index 40bae93298..4dbe023257 100644
--- a/lib/eunit/src/eunit_lib.erl
+++ b/lib/eunit/src/eunit_lib.erl
@@ -57,7 +57,7 @@ format_exception({Class,Term,Trace}, Depth)
when is_atom(Class), is_list(Trace) ->
case is_stacktrace(Trace) of
true ->
- io_lib:format("~s**~w:~s",
+ io_lib:format("~ts**~w:~ts",
[format_stacktrace(Trace), Class,
format_term(Term, Depth)]);
false ->
@@ -67,11 +67,11 @@ format_exception(Term, Depth) ->
format_term(Term, Depth).
format_term(Term, Depth) ->
- io_lib:format("~P\n", [Term, Depth]).
+ io_lib:format("~tP\n", [Term, Depth]).
format_exit_term(Term) ->
{Reason, Trace} = analyze_exit_term(Term),
- io_lib:format("~P~s", [Reason, 15, Trace]).
+ io_lib:format("~tP~ts", [Reason, 15, Trace]).
analyze_exit_term({Reason, [_|_]=Trace}=Term) ->
case is_stacktrace(Trace) of
@@ -102,7 +102,7 @@ format_stacktrace(Trace) ->
format_stacktrace(Trace, "in function", "in call from").
format_stacktrace([{M,F,A,L}|Fs], Pre, Pre1) when is_integer(A) ->
- [io_lib:fwrite("~s ~w:~w/~w~s\n",
+ [io_lib:fwrite("~ts ~w:~w/~w~ts\n",
[Pre, M, F, A, format_stacktrace_location(L)])
| format_stacktrace(Fs, Pre1, Pre1)];
format_stacktrace([{M,F,As,L}|Fs], Pre, Pre1) when is_list(As) ->
@@ -110,15 +110,15 @@ format_stacktrace([{M,F,As,L}|Fs], Pre, Pre1) when is_list(As) ->
C = case is_op(M,F,A) of
true when A =:= 1 ->
[A1] = As,
- io_lib:fwrite("~s ~s", [F,format_arg(A1)]);
+ io_lib:fwrite("~ts ~ts", [F,format_arg(A1)]);
true when A =:= 2 ->
[A1, A2] = As,
- io_lib:fwrite("~s ~s ~s",
+ io_lib:fwrite("~ts ~ts ~ts",
[format_arg(A1),F,format_arg(A2)]);
false ->
- io_lib:fwrite("~w(~s)", [F,format_arglist(As)])
+ io_lib:fwrite("~w(~ts)", [F,format_arglist(As)])
end,
- [io_lib:fwrite("~s ~w:~w/~w~s\n called as ~s\n",
+ [io_lib:fwrite("~ts ~w:~w/~w~ts\n called as ~ts\n",
[Pre,M,F,A,format_stacktrace_location(L),C])
| format_stacktrace(Fs,Pre1,Pre1)];
format_stacktrace([{M,F,As}|Fs], Pre, Pre1) ->
@@ -130,18 +130,18 @@ format_stacktrace_location(Location) ->
File = proplists:get_value(file, Location),
Line = proplists:get_value(line, Location),
if File =/= undefined, Line =/= undefined ->
- io_lib:format(" (~s, line ~w)", [File, Line]);
+ io_lib:format(" (~ts, line ~w)", [File, Line]);
true ->
""
end.
format_arg(A) ->
- io_lib:format("~P",[A,15]).
+ io_lib:format("~tP",[A,15]).
format_arglist([A]) ->
format_arg(A);
format_arglist([A|As]) ->
- [io_lib:format("~P,",[A,15]) | format_arglist(As)];
+ [io_lib:format("~tP,",[A,15]) | format_arglist(As)];
format_arglist([]) ->
"".
@@ -155,43 +155,44 @@ is_op(_M, _F, _A) ->
false.
format_error({bad_test, Term}) ->
- error_msg("bad test descriptor", "~P", [Term, 15]);
+ error_msg("bad test descriptor", "~tP", [Term, 15]);
format_error({bad_generator, {{M,F,A}, Term}}) ->
error_msg(io_lib:format("result from generator ~w:~w/~w is not a test",
[M,F,A]),
- "~P", [Term, 15]);
+ "~tP", [Term, 15]);
format_error({generator_failed, {{M,F,A}, Exception}}) ->
error_msg(io_lib:format("test generator ~w:~w/~w failed",[M,F,A]),
- "~s", [format_exception(Exception)]);
+ "~ts", [format_exception(Exception)]);
format_error({no_such_function, {M,F,A}})
when is_atom(M), is_atom(F), is_integer(A) ->
error_msg(io_lib:format("no such function: ~w:~w/~w", [M,F,A]),
"", []);
format_error({module_not_found, M}) ->
- error_msg("test module not found", "~p", [M]);
+ error_msg("test module not found", "~tp", [M]);
format_error({application_not_found, A}) when is_atom(A) ->
error_msg("application not found", "~w", [A]);
format_error({file_read_error, {_R, Msg, F}}) ->
- error_msg("error reading file", "~s: ~s", [Msg, F]);
+ error_msg("error reading file", "~ts: ~ts", [Msg, F]);
format_error({setup_failed, Exception}) ->
- error_msg("context setup failed", "~s",
+ error_msg("context setup failed", "~ts",
[format_exception(Exception)]);
format_error({cleanup_failed, Exception}) ->
- error_msg("context cleanup failed", "~s",
+ error_msg("context cleanup failed", "~ts",
[format_exception(Exception)]);
format_error({{bad_instantiator, {{M,F,A}, Term}}, _DummyException}) ->
error_msg(io_lib:format("result from instantiator ~w:~w/~w is not a test",
[M,F,A]),
- "~P", [Term, 15]);
+ "~tP", [Term, 15]);
format_error({instantiation_failed, Exception}) ->
- error_msg("instantiation of subtests failed", "~s",
+ error_msg("instantiation of subtests failed", "~ts",
[format_exception(Exception)]).
error_msg(Title, Fmt, Args) ->
Msg = io_lib:format("**"++Fmt, Args), % gets indentation right
- io_lib:fwrite("*** ~s ***\n~s\n\n", [Title, Msg]).
+ io_lib:fwrite("*** ~ts ***\n~ts\n\n", [Title, Msg]).
-ifdef(TEST).
+-dialyzer({no_match, format_exception_test_/0}).
format_exception_test_() ->
[?_assertMatch(
"\nymmud:rorre"++_,
@@ -273,6 +274,7 @@ dlist_next([], Xs) ->
-ifdef(TEST).
+-dialyzer({no_match, dlist_test_/0}).
dlist_test_() ->
{"deep list traversal",
[{"non-list term -> singleton list",
@@ -338,6 +340,7 @@ is_nonempty_string([]) -> false;
is_nonempty_string(Cs) -> is_string(Cs).
-ifdef(TEST).
+-dialyzer({no_match, is_string_test_/0}).
is_string_test_() ->
{"is_string",
[{"no non-lists", ?_assert(not is_string($A))},
@@ -399,6 +402,7 @@ uniq([X | Xs]) -> [X | uniq(Xs)];
uniq([]) -> [].
-ifdef(TEST).
+-dialyzer({[no_match, no_fail_call, no_improper_lists], uniq_test_/0}).
uniq_test_() ->
{"uniq",
[?_assertError(function_clause, uniq(ok)),
@@ -459,6 +463,7 @@ normalize([]) ->
-ifdef(TEST).
+-dialyzer({no_match, cmd_test_/0}).
cmd_test_() ->
([?_test({0, "hello\n"} = ?_cmd_("echo hello"))]
++ case os:type() of
@@ -576,6 +581,7 @@ trie_match([], _T) ->
-ifdef(TEST).
+-dialyzer({no_match, trie_test_/0}).
trie_test_() ->
[{"basic representation",
[?_assert(trie_new() =:= gb_trees:empty()),
diff --git a/lib/eunit/src/eunit_listener.erl b/lib/eunit/src/eunit_listener.erl
index ecaac424a2..c34eacb1d6 100644
--- a/lib/eunit/src/eunit_listener.erl
+++ b/lib/eunit/src/eunit_listener.erl
@@ -27,14 +27,11 @@
-export([start/1, start/2]).
--export([behaviour_info/1]).
-
-
-behaviour_info(callbacks) ->
- [{init,1},{handle_begin,3},{handle_end,3},{handle_cancel,3},
- {terminate,2}];
-behaviour_info(_Other) ->
- undefined.
+-callback init(_) -> _.
+-callback handle_begin(_, _, _) -> _.
+-callback handle_end(_, _, _) -> _.
+-callback handle_cancel(_, _, _) -> _.
+-callback terminate(_, _) -> _.
-record(state, {callback, % callback module
@@ -50,18 +47,22 @@ start(Callback) ->
start(Callback, Options) ->
St = #state{callback = Callback},
- spawn_opt(fun () -> init(St, Options) end,
+ spawn_opt(init_fun(St, Options),
proplists:get_all_values(spawn, Options)).
-init(St0, Options) ->
- St1 = call(init, [Options], St0),
- St2 = expect([], undefined, St1),
- Data = [{pass, St2#state.pass},
- {fail, St2#state.fail},
- {skip, St2#state.skip},
- {cancel, St2#state.cancel}],
- call(terminate, [{ok, Data}, St2#state.state], St2),
- exit(normal).
+-spec init_fun(_, _) -> fun(() -> no_return()).
+
+init_fun(St0, Options) ->
+ fun () ->
+ St1 = call(init, [Options], St0),
+ St2 = expect([], undefined, St1),
+ Data = [{pass, St2#state.pass},
+ {fail, St2#state.fail},
+ {skip, St2#state.skip},
+ {cancel, St2#state.cancel}],
+ call(terminate, [{ok, Data}, St2#state.state], St2),
+ exit(normal)
+ end.
expect(Id, ParentId, St) ->
case wait_for(Id, 'begin', ParentId) of
diff --git a/lib/eunit/src/eunit_proc.erl b/lib/eunit/src/eunit_proc.erl
index 03d1a18321..8bdf94c877 100644
--- a/lib/eunit/src/eunit_proc.erl
+++ b/lib/eunit/src/eunit_proc.erl
@@ -230,7 +230,7 @@ insulator_wait(Child, Parent, Buf, St) ->
message_super(Id, {progress, 'begin', {Type, Data}}, St),
insulator_wait(Child, Parent, [[] | Buf], St);
{child, Child, Id, {'end', Status, Time}} ->
- Data = [{time, Time}, {output, buffer_to_binary(hd(Buf))}],
+ Data = [{time, Time}, {output, lists:reverse(hd(Buf))}],
message_super(Id, {progress, 'end', {Status, Data}}, St),
insulator_wait(Child, Parent, tl(Buf), St);
{child, Child, Id, {skipped, Reason}} ->
@@ -268,13 +268,12 @@ insulator_wait(Child, Parent, Buf, St) ->
kill_task(Child, St)
end.
+-spec kill_task(_, _) -> no_return().
+
kill_task(Child, St) ->
exit(Child, kill),
terminate_insulator(St).
-buffer_to_binary([B]) when is_binary(B) -> B; % avoid unnecessary copying
-buffer_to_binary(Buf) -> list_to_binary(lists:reverse(Buf)).
-
%% Unlinking before exit avoids polluting the parent process with exit
%% signals from the insulator. The child process is already dead here.
@@ -597,7 +596,7 @@ group_leader_loop(Runner, Wait, Buf) ->
%% no more messages and nothing to wait for; we ought to
%% have collected all immediately pending output now
process_flag(priority, normal),
- Runner ! {self(), buffer_to_binary(Buf)}
+ Runner ! {self(), lists:reverse(Buf)}
end.
group_leader_sync(G) ->
diff --git a/lib/eunit/src/eunit_serial.erl b/lib/eunit/src/eunit_serial.erl
index 1a0179a5df..da76064a53 100644
--- a/lib/eunit/src/eunit_serial.erl
+++ b/lib/eunit/src/eunit_serial.erl
@@ -61,14 +61,16 @@
messages = dict:new() :: dict:dict()}).
start(Pids) ->
- spawn(fun () -> serializer(Pids) end).
-
-serializer(Pids) ->
- St = #state{listeners = sets:from_list(Pids),
- cancelled = eunit_lib:trie_new(),
- messages = dict:new()},
- expect([], undefined, 0, St),
- exit(normal).
+ spawn(serializer_fun(Pids)).
+
+serializer_fun(Pids) ->
+ fun () ->
+ St = #state{listeners = sets:from_list(Pids),
+ cancelled = eunit_lib:trie_new(),
+ messages = dict:new()},
+ expect([], undefined, 0, St),
+ exit(normal)
+ end.
%% collect beginning and end of an expected item; return {Done, NewSt}
%% where Done is true if there are no more items of this group
diff --git a/lib/eunit/src/eunit_server.erl b/lib/eunit/src/eunit_server.erl
index 2002930abb..387976eba1 100644
--- a/lib/eunit/src/eunit_server.erl
+++ b/lib/eunit/src/eunit_server.erl
@@ -200,7 +200,7 @@ server_command(From, stop, St) ->
server(St#state{stopped = true});
server_command(From, {watch, Target, _Opts}, St) ->
%% the code watcher is only started on demand
- %% FIXME: this is disabled for now in the OTP distribution
+ %% TODO: this is disabled for now
%%code_monitor:monitor(self()),
%% TODO: propagate options to testing stage
St1 = add_watch(Target, St),
diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl
index 2d1f0b1497..f3e58a3d1c 100644
--- a/lib/eunit/src/eunit_surefire.erl
+++ b/lib/eunit/src/eunit_surefire.erl
@@ -203,9 +203,9 @@ handle_cancel(test, Data, St) ->
testcases=[TestCase|TestSuite#testsuite.testcases] },
St#state{testsuites=store_suite(NewTestSuite, TestSuites)}.
-format_name({Module, Function, Arity}, Line) ->
- lists:flatten([atom_to_list(Module), ":", atom_to_list(Function), "/",
- integer_to_list(Arity), "_", integer_to_list(Line)]).
+format_name({Module, Function, _Arity}, Line) ->
+ lists:flatten([atom_to_list(Module), ":", integer_to_list(Line), " ",
+ atom_to_list(Function)]).
format_desc(undefined) ->
"";
format_desc(Desc) when is_binary(Desc) ->
@@ -279,7 +279,7 @@ write_report_to(TestSuite, FileDescriptor) ->
%% Write the XML header.
%% ----------------------------------------------------------------------------
write_header(FileDescriptor) ->
- file:write(FileDescriptor, [<<"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>">>, ?NEWLINE]).
+ io:format(FileDescriptor, "~ts~ts", [<<"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>">>, ?NEWLINE]).
%% ----------------------------------------------------------------------------
%% Write the testsuite start tag, with attributes describing the statistics
@@ -303,7 +303,7 @@ write_start_tag(
<<"\" time=\"">>, format_time(Time),
<<"\" name=\"">>, escape_attr(Name),
<<"\">">>, ?NEWLINE],
- file:write(FileDescriptor, StartTag).
+ io:format(FileDescriptor, "~ts", [StartTag]).
%% ----------------------------------------------------------------------------
%% Recursive function to write the test cases.
@@ -317,7 +317,7 @@ write_testcases([TestCase| Tail], FileDescriptor) ->
%% Write the testsuite end tag.
%% ----------------------------------------------------------------------------
write_end_tag(FileDescriptor) ->
- file:write(FileDescriptor, [<<"</testsuite>">>, ?NEWLINE]).
+ io:format(FileDescriptor, "~ts~ts", [<<"</testsuite>">>, ?NEWLINE]).
%% ----------------------------------------------------------------------------
%% Write a test case, as a testcase tag.
@@ -334,17 +334,16 @@ write_testcase(
FileDescriptor) ->
DescriptionAttr = case Description of
[] -> [];
- _ -> [<<" description=\"">>, escape_attr(Description), <<"\"">>]
+ _ -> [<<" (">>, escape_attr(Description), <<")">>]
end,
StartTag = [
?INDENT, <<"<testcase time=\"">>, format_time(Time),
- <<"\" name=\"">>, escape_attr(Name), <<"\"">>,
- DescriptionAttr],
+ <<"\" name=\"">>, escape_attr(Name), DescriptionAttr, <<"\"">>],
ContentAndEndTag = case {Result, Output} of
{ok, <<>>} -> [<<"/>">>, ?NEWLINE];
_ -> [<<">">>, ?NEWLINE, format_testcase_result(Result), format_testcase_output(Output), ?INDENT, <<"</testcase>">>, ?NEWLINE]
end,
- file:write(FileDescriptor, [StartTag, ContentAndEndTag]).
+ io:format(FileDescriptor, "~ts~ts", [StartTag, ContentAndEndTag]).
%% ----------------------------------------------------------------------------
%% Format the result of the test.
@@ -427,7 +426,7 @@ escape_suitename([Char | Tail], Acc) -> escape_suitename(Tail, [Char | Acc]).
%% Replace < with &lt;, > with &gt; and & with &amp;
%% ----------------------------------------------------------------------------
escape_text(Text) when is_binary(Text) -> escape_text(binary_to_list(Text));
-escape_text(Text) -> escape_xml(lists:flatten(Text), [], false).
+escape_text(Text) -> escape_xml(to_utf8(lists:flatten(Text)), [], false).
%% ----------------------------------------------------------------------------
@@ -435,7 +434,7 @@ escape_text(Text) -> escape_xml(lists:flatten(Text), [], false).
%% Replace < with &lt;, > with &gt; and & with &amp;
%% ----------------------------------------------------------------------------
escape_attr(Text) when is_binary(Text) -> escape_attr(binary_to_list(Text));
-escape_attr(Text) -> escape_xml(lists:flatten(Text), [], true).
+escape_attr(Text) -> escape_xml(to_utf8(lists:flatten(Text)), [], true).
escape_xml([], Acc, _ForAttr) -> lists:reverse(Acc);
escape_xml([$< | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $l, $& | Acc], ForAttr);
@@ -443,3 +442,17 @@ escape_xml([$> | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $g, $& | Acc]
escape_xml([$& | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $p, $m, $a, $& | Acc], ForAttr);
escape_xml([$" | Tail], Acc, true) -> escape_xml(Tail, [$;, $t, $o, $u, $q, $& | Acc], true); % "
escape_xml([Char | Tail], Acc, ForAttr) when is_integer(Char) -> escape_xml(Tail, [Char | Acc], ForAttr).
+
+%% the input may be utf8 or latin1; the resulting list is unicode
+to_utf8(Desc) when is_binary(Desc) ->
+ case unicode:characters_to_list(Desc) of
+ {_,_,_} -> unicode:characters_to_list(Desc, latin1);
+ X -> X
+ end;
+to_utf8(Desc) when is_list(Desc) ->
+ try
+ to_utf8(list_to_binary(Desc))
+ catch
+ _:_ ->
+ Desc
+ end.
diff --git a/lib/eunit/src/eunit_test.erl b/lib/eunit/src/eunit_test.erl
index 9cf40a738d..62d30b1930 100644
--- a/lib/eunit/src/eunit_test.erl
+++ b/lib/eunit/src/eunit_test.erl
@@ -40,6 +40,7 @@ get_stacktrace() ->
get_stacktrace(Ts) ->
eunit_lib:uniq(prune_trace(erlang:get_stacktrace(), Ts)).
+-dialyzer({no_match, prune_trace/2}).
prune_trace([{eunit_data, _, _} | Rest], Tail) ->
prune_trace(Rest, Tail);
prune_trace([{eunit_data, _, _, _} | Rest], Tail) ->
@@ -75,6 +76,7 @@ run_testfun(F) ->
-ifdef(TEST).
+-dialyzer({[no_match, no_fail_call, no_return], macro_test_/0}).
macro_test_() ->
{"macro definitions",
[{?LINE, fun () ->
@@ -301,6 +303,7 @@ wrapper_test_() ->
]}.
%% this must be exported (done automatically by the autoexport transform)
+-dialyzer({no_missing_calls, wrapper_test_exported_/0}).
wrapper_test_exported_() ->
{ok, ?MODULE:nonexisting_function()}.
-endif.
diff --git a/lib/eunit/src/eunit_tests.erl b/lib/eunit/src/eunit_tests.erl
index 47ea0aaf46..5dee1cb49e 100644
--- a/lib/eunit/src/eunit_tests.erl
+++ b/lib/eunit/src/eunit_tests.erl
@@ -23,6 +23,8 @@
-include("eunit.hrl").
+-dialyzer(no_match).
+
-ifdef(TEST).
id(X) -> X. % for suppressing compiler warnings
-endif.
diff --git a/lib/eunit/src/eunit_tty.erl b/lib/eunit/src/eunit_tty.erl
index f21b2da3d3..f604ca5ba3 100644
--- a/lib/eunit/src/eunit_tty.erl
+++ b/lib/eunit/src/eunit_tty.erl
@@ -67,6 +67,8 @@ terminate({ok, Data}, St) ->
end,
if Pass =:= 1 ->
fwrite(" Test passed.\n");
+ Pass =:= 2 ->
+ fwrite(" 2 tests passed.\n");
true ->
fwrite(" All ~w tests passed.\n", [Pass])
end
@@ -83,7 +85,7 @@ terminate({ok, Data}, St) ->
sync_end(error)
end;
terminate({error, Reason}, _St) ->
- fwrite("Internal error: ~P.\n", [Reason, 25]),
+ fwrite("Internal error: ~tP.\n", [Reason, 25]),
sync_end(error).
sync_end(Result) ->
@@ -177,7 +179,7 @@ indent(_N) ->
print_group_start(I, Desc) ->
indent(I),
- fwrite("~s\n", [Desc]).
+ fwrite("~ts\n", [Desc]).
print_group_end(I, Time) ->
if Time > 0 ->
@@ -195,13 +197,13 @@ print_test_begin(I, Data) ->
true -> io_lib:fwrite("~w:", [Line])
end,
D = if Desc =:= "" ; Desc =:= undefined -> "";
- true -> io_lib:fwrite(" (~s)", [Desc])
+ true -> io_lib:fwrite(" (~ts)", [Desc])
end,
case proplists:get_value(source, Data) of
{Module, Name, _Arity} ->
- fwrite("~s:~s ~s~s...", [Module, L, Name, D]);
+ fwrite("~ts:~ts ~ts~ts...", [Module, L, Name, D]);
_ ->
- fwrite("~s~s...", [L, D])
+ fwrite("~ts~ts...", [L, D])
end.
print_test_end(Data) ->
@@ -209,21 +211,21 @@ print_test_end(Data) ->
T = if Time > 0 -> io_lib:fwrite("[~.3f s] ", [Time/1000]);
true -> ""
end,
- fwrite("~sok\n", [T]).
+ fwrite("~tsok\n", [T]).
print_test_error({error, Exception}, Data) ->
Output = proplists:get_value(output, Data),
- fwrite("*failed*\n~s", [eunit_lib:format_exception(Exception)]),
+ fwrite("*failed*\n~ts", [eunit_lib:format_exception(Exception)]),
case Output of
<<>> ->
fwrite("\n\n");
<<Text:800/binary, _:1/binary, _/binary>> ->
- fwrite(" output:<<\"~s\">>...\n\n", [Text]);
+ fwrite(" output:<<\"~ts\">>...\n\n", [Text]);
_ ->
- fwrite(" output:<<\"~s\">>\n\n", [Output])
+ fwrite(" output:<<\"~ts\">>\n\n", [Output])
end;
print_test_error({skipped, Reason}, _) ->
- fwrite("*did not run*\n::~s\n", [format_skipped(Reason)]).
+ fwrite("*did not run*\n::~ts\n", [format_skipped(Reason)]).
format_skipped({module_not_found, M}) ->
io_lib:fwrite("missing module: ~w", [M]);
@@ -244,12 +246,12 @@ format_cancel(undefined) ->
format_cancel(timeout) ->
"*timed out*\n";
format_cancel({startup, Reason}) ->
- io_lib:fwrite("*could not start test process*\n::~P\n\n",
+ io_lib:fwrite("*could not start test process*\n::~tP\n\n",
[Reason, 15]);
format_cancel({blame, _SubId}) ->
"*cancelled because of subtask*\n";
format_cancel({exit, Reason}) ->
- io_lib:fwrite("*unexpected termination of test process*\n::~P\n\n",
+ io_lib:fwrite("*unexpected termination of test process*\n::~tP\n\n",
[Reason, 15]);
format_cancel({abort, Reason}) ->
eunit_lib:format_error(Reason).
diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile
index e4ddf4e42c..8721bacf89 100644
--- a/lib/eunit/test/Makefile
+++ b/lib/eunit/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -20,7 +21,9 @@ include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
MODULES = \
- eunit_SUITE
+ eunit_SUITE \
+ tlatin \
+ tutf8
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/eunit/test/eunit_SUITE.erl b/lib/eunit/test/eunit_SUITE.erl
index d13dc73923..9897d5ae2b 100644
--- a/lib/eunit/test/eunit_SUITE.erl
+++ b/lib/eunit/test/eunit_SUITE.erl
@@ -1,35 +1,36 @@
%%
%% %CopyrightBegin%
-%%
+%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
+%%
+%% Licensed under the Apache License, Version 2.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(eunit_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,
- app_test/1,appup_test/1,eunit_test/1]).
-
+ app_test/1,appup_test/1,eunit_test/1,surefire_utf8_test/1,surefire_latin_test/1]).
+
-include_lib("common_test/include/ct.hrl").
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
- [app_test, appup_test, eunit_test].
+all() ->
+ [app_test, appup_test, eunit_test, surefire_utf8_test, surefire_latin_test].
-groups() ->
+groups() ->
[].
init_per_suite(Config) ->
@@ -54,3 +55,21 @@ eunit_test(Config) when is_list(Config) ->
ok = file:set_cwd(code:lib_dir(eunit)),
ok = eunit:test(eunit).
+surefire_latin_test(Config) when is_list(Config) ->
+ ok = file:set_cwd(proplists:get_value(priv_dir, Config, ".")),
+ check_surefire(tlatin),
+ ok.
+
+surefire_utf8_test(Config) when is_list(Config) ->
+ ok = file:set_cwd(proplists:get_value(priv_dir, Config, ".")),
+ check_surefire(tutf8),
+ ok.
+
+check_surefire(Module) ->
+ File = "TEST-"++atom_to_list(Module)++".xml",
+ file:delete(File),
+ % ignore test result, some fail on purpose
+ eunit:test(Module, [{report,{eunit_surefire,[{dir,"."}]}}]),
+ {ok, Bin} = file:read_file(File),
+ [_|_] = unicode:characters_to_list(Bin, unicode),
+ ok. \ No newline at end of file
diff --git a/lib/eunit/test/tlatin.erl b/lib/eunit/test/tlatin.erl
new file mode 100644
index 0000000000..a42e67d581
--- /dev/null
+++ b/lib/eunit/test/tlatin.erl
@@ -0,0 +1,15 @@
+% coding: latin-1
+
+-module(tlatin).
+
+-include_lib("eunit/include/eunit.hrl").
+
+'foo_�_test_'() ->
+ [
+ {"1�1", fun() -> io:format("1�1 ~s ~w",[<<"a�">>, 'Z�k']), io:format([128,64,255,255]), ?assert("g�"=="g�") end}
+ ,{<<"2�2">>, fun() -> io:format("2�2 ~s",[<<"b�">>]), io:format([128,64]), ?assert("g�"=="g�") end}
+ ,{<<"3�3"/utf8>>, fun() -> io:format("3�3 ~ts",[<<"c�"/utf8>>]), io:format([128,64]), ?assert("g�"=="g�") end}
+ ,{"1�1", fun() -> io:format("1�1 ~s ~w",[<<"a�">>,'Zb�d']), io:format([128,64,255,255]), ?assert("w�"=="w�") end}
+ ,{<<"2�2">>, fun() -> io:format("2�2 ~s",[<<"b�">>]), io:format([128,64]), ?assert("w�"=="w�") end}
+ ,{<<"3�3"/utf8>>, fun() -> io:format("3�3 ~ts",[<<"c�"/utf8>>]), io:format([128,64]), ?assert("w�"=="w�") end}
+ ].
diff --git a/lib/eunit/test/tutf8.erl b/lib/eunit/test/tutf8.erl
new file mode 100644
index 0000000000..c902f3ad18
--- /dev/null
+++ b/lib/eunit/test/tutf8.erl
@@ -0,0 +1,15 @@
+%% coding: utf-8
+
+-module(tutf8).
+
+-include_lib("eunit/include/eunit.hrl").
+
+'foo_ö_test_'() ->
+ [
+ {"1ö汉1", fun() -> io:format("1å汉1 ~s ~w",[<<"aö汉">>, 'Zök']), io:format([128,64,255,255]), ?assert("gö汉"=="gö汉") end}
+ ,{<<"2ö汉2">>, fun() -> io:format("2å汉2 ~s",[<<"bö汉">>]), io:format([128,64]), ?assert("gö汉"=="gö汉") end}
+ ,{<<"3ö汉3"/utf8>>, fun() -> io:format("3å汉3 ~ts",[<<"cö汉"/utf8>>]), io:format([128,64]), ?assert("gö汉"=="gö汉") end}
+ ,{"1ä汉1", fun() -> io:format("1ä汉1 ~s ~w",[<<"aä汉">>, 'Zbäd']), io:format([128,64,255,255]), ?assert("wå汉"=="wä汉") end}
+ ,{<<"2ä汉2">>, fun() -> io:format("2ä汉2 ~s",[<<"bä汉">>]), io:format([128,64]), ?assert("wå汉"=="wä汉") end}
+ ,{<<"3ä汉"/utf8>>, fun() -> io:format("3ä汉3 ~ts",[<<"cä汉"/utf8>>]), io:format([128,64]), ?assert("wå汉"=="wä汉") end}
+ ].
diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk
index dca8b3ece0..dcb7fad699 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.2.9
+EUNIT_VSN = 2.2.13
diff --git a/lib/gs/Makefile b/lib/gs/Makefile
index f4d876fe1a..02c8fc3467 100644
--- a/lib/gs/Makefile
+++ b/lib/gs/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/contribs/Makefile b/lib/gs/contribs/Makefile
index 9aecaff44f..061fae86c1 100644
--- a/lib/gs/contribs/Makefile
+++ b/lib/gs/contribs/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/contribs/bonk/Makefile b/lib/gs/contribs/bonk/Makefile
index d160ca8b73..b7508a97c9 100644
--- a/lib/gs/contribs/bonk/Makefile
+++ b/lib/gs/contribs/bonk/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/contribs/bonk/bonk.erl b/lib/gs/contribs/bonk/bonk.erl
index 3d1e8ce34b..bbbc656b34 100644
--- a/lib/gs/contribs/bonk/bonk.erl
+++ b/lib/gs/contribs/bonk/bonk.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/gs/contribs/bonk/bonk_sound.erl b/lib/gs/contribs/bonk/bonk_sound.erl
index d89ca63e7c..9a0db80e5d 100644
--- a/lib/gs/contribs/bonk/bonk_sound.erl
+++ b/lib/gs/contribs/bonk/bonk_sound.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/bonk/bonk_square.erl b/lib/gs/contribs/bonk/bonk_square.erl
index 2f6c533079..98af91944b 100644
--- a/lib/gs/contribs/bonk/bonk_square.erl
+++ b/lib/gs/contribs/bonk/bonk_square.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/bonk/sounder.erl b/lib/gs/contribs/bonk/sounder.erl
index e6f69a1616..aabcaa1950 100644
--- a/lib/gs/contribs/bonk/sounder.erl
+++ b/lib/gs/contribs/bonk/sounder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/cols/Makefile b/lib/gs/contribs/cols/Makefile
index 3036e9565e..34a900e5ab 100644
--- a/lib/gs/contribs/cols/Makefile
+++ b/lib/gs/contribs/cols/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/contribs/cols/cols.erl b/lib/gs/contribs/cols/cols.erl
index d1a1b791c3..265f2b6ee8 100644
--- a/lib/gs/contribs/cols/cols.erl
+++ b/lib/gs/contribs/cols/cols.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/cols/highscore.erl b/lib/gs/contribs/cols/highscore.erl
index 7f80debb07..94f68a043a 100644
--- a/lib/gs/contribs/cols/highscore.erl
+++ b/lib/gs/contribs/cols/highscore.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/mandel/Makefile b/lib/gs/contribs/mandel/Makefile
index 308ba0cbb0..b806cc7801 100644
--- a/lib/gs/contribs/mandel/Makefile
+++ b/lib/gs/contribs/mandel/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/contribs/mandel/mandel.erl b/lib/gs/contribs/mandel/mandel.erl
index a4feaa87ec..e6061ba77d 100644
--- a/lib/gs/contribs/mandel/mandel.erl
+++ b/lib/gs/contribs/mandel/mandel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/mandel/mandel.html b/lib/gs/contribs/mandel/mandel.html
index afd6ad151f..f69cfa3c6a 100644
--- a/lib/gs/contribs/mandel/mandel.html
+++ b/lib/gs/contribs/mandel/mandel.html
@@ -1,15 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/gs/contribs/othello/Makefile b/lib/gs/contribs/othello/Makefile
index f9d131c315..8a66e17ec5 100644
--- a/lib/gs/contribs/othello/Makefile
+++ b/lib/gs/contribs/othello/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/contribs/othello/othello.erl b/lib/gs/contribs/othello/othello.erl
index c66c9c2e79..c6ad0a76ec 100644
--- a/lib/gs/contribs/othello/othello.erl
+++ b/lib/gs/contribs/othello/othello.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/contribs/othello/othello_adt.erl b/lib/gs/contribs/othello/othello_adt.erl
index fb60c30b89..e69c1c4d72 100644
--- a/lib/gs/contribs/othello/othello_adt.erl
+++ b/lib/gs/contribs/othello/othello_adt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/gs/contribs/othello/othello_board.erl b/lib/gs/contribs/othello/othello_board.erl
index aaa4062ba8..cc055b1fa1 100644
--- a/lib/gs/contribs/othello/othello_board.erl
+++ b/lib/gs/contribs/othello/othello_board.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/doc/src/Makefile b/lib/gs/doc/src/Makefile
index a7121e997b..1e950e0493 100644
--- a/lib/gs/doc/src/Makefile
+++ b/lib/gs/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/doc/src/book.xml b/lib/gs/doc/src/book.xml
index dbc869751a..2e83697bdd 100644
--- a/lib/gs/doc/src/book.xml
+++ b/lib/gs/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs.xml b/lib/gs/doc/src/gs.xml
index 7b589d002d..0927902f75 100644
--- a/lib/gs/doc/src/gs.xml
+++ b/lib/gs/doc/src/gs.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter1.xml b/lib/gs/doc/src/gs_chapter1.xml
index 71f213b34d..fea29dccbc 100644
--- a/lib/gs/doc/src/gs_chapter1.xml
+++ b/lib/gs/doc/src/gs_chapter1.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter2.xmlsrc b/lib/gs/doc/src/gs_chapter2.xmlsrc
index d37065d954..20c8a8bd81 100644
--- a/lib/gs/doc/src/gs_chapter2.xmlsrc
+++ b/lib/gs/doc/src/gs_chapter2.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter3.xml b/lib/gs/doc/src/gs_chapter3.xml
index a124354e7d..47967d466a 100644
--- a/lib/gs/doc/src/gs_chapter3.xml
+++ b/lib/gs/doc/src/gs_chapter3.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter4.xmlsrc b/lib/gs/doc/src/gs_chapter4.xmlsrc
index 9747382655..99d4fcd124 100644
--- a/lib/gs/doc/src/gs_chapter4.xmlsrc
+++ b/lib/gs/doc/src/gs_chapter4.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter5.xmlsrc b/lib/gs/doc/src/gs_chapter5.xmlsrc
index f2ccedae2d..56e69bfb2e 100644
--- a/lib/gs/doc/src/gs_chapter5.xmlsrc
+++ b/lib/gs/doc/src/gs_chapter5.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter6.xmlsrc b/lib/gs/doc/src/gs_chapter6.xmlsrc
index 807d82589d..74790ae6a3 100644
--- a/lib/gs/doc/src/gs_chapter6.xmlsrc
+++ b/lib/gs/doc/src/gs_chapter6.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter7.xmlsrc b/lib/gs/doc/src/gs_chapter7.xmlsrc
index 63ee4c472c..d27bd67673 100644
--- a/lib/gs/doc/src/gs_chapter7.xmlsrc
+++ b/lib/gs/doc/src/gs_chapter7.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/gs_chapter8.xmlsrc b/lib/gs/doc/src/gs_chapter8.xmlsrc
index db69395102..b5959d972b 100644
--- a/lib/gs/doc/src/gs_chapter8.xmlsrc
+++ b/lib/gs/doc/src/gs_chapter8.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/notes.xml b/lib/gs/doc/src/notes.xml
index e40310d36e..02d4f1cec3 100644
--- a/lib/gs/doc/src/notes.xml
+++ b/lib/gs/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,7 +31,23 @@
</header>
<p>This document describes the changes made to the GS application.</p>
- <section><title>GS 1.5.16</title>
+ <section><title>GS 1.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>GS 1.5.16</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/gs/doc/src/part.xml b/lib/gs/doc/src/part.xml
index ac8e40ecde..6ae945a9db 100644
--- a/lib/gs/doc/src/part.xml
+++ b/lib/gs/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/part_notes.xml b/lib/gs/doc/src/part_notes.xml
index 23ef749bff..a829534bfb 100644
--- a/lib/gs/doc/src/part_notes.xml
+++ b/lib/gs/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/doc/src/ref_man.xml b/lib/gs/doc/src/ref_man.xml
index b57ad7db3b..1c48ee1f31 100644
--- a/lib/gs/doc/src/ref_man.xml
+++ b/lib/gs/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/gs/examples/Makefile b/lib/gs/examples/Makefile
index ee77990191..eab10d125b 100644
--- a/lib/gs/examples/Makefile
+++ b/lib/gs/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/examples/ball.erl b/lib/gs/examples/ball.erl
index 42e3522fc7..ccd76619a9 100644
--- a/lib/gs/examples/ball.erl
+++ b/lib/gs/examples/ball.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/browser.erl b/lib/gs/examples/browser.erl
index dd01e0299b..2037b1bf0d 100644
--- a/lib/gs/examples/browser.erl
+++ b/lib/gs/examples/browser.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/calc.erl b/lib/gs/examples/calc.erl
index 9ed8ed4dbd..d3bcda4732 100644
--- a/lib/gs/examples/calc.erl
+++ b/lib/gs/examples/calc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/calc2.erl b/lib/gs/examples/calc2.erl
index 51f9c31d28..89d1c00527 100644
--- a/lib/gs/examples/calc2.erl
+++ b/lib/gs/examples/calc2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/color_demo.erl b/lib/gs/examples/color_demo.erl
index 5ebfe36d75..8c9fd98753 100644
--- a/lib/gs/examples/color_demo.erl
+++ b/lib/gs/examples/color_demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/color_demo2.erl b/lib/gs/examples/color_demo2.erl
index 1c8db7a851..918d451f5d 100644
--- a/lib/gs/examples/color_demo2.erl
+++ b/lib/gs/examples/color_demo2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/distrib_draw.erl b/lib/gs/examples/distrib_draw.erl
index fc821c6df4..94177946a1 100644
--- a/lib/gs/examples/distrib_draw.erl
+++ b/lib/gs/examples/distrib_draw.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/entry_demo.erl b/lib/gs/examples/entry_demo.erl
index 4cdbe7e279..923784658c 100644
--- a/lib/gs/examples/entry_demo.erl
+++ b/lib/gs/examples/entry_demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/event_test.erl b/lib/gs/examples/event_test.erl
index 3231df00e1..03408a3ef6 100644
--- a/lib/gs/examples/event_test.erl
+++ b/lib/gs/examples/event_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/file_dialog.erl b/lib/gs/examples/file_dialog.erl
index 37b19a322c..b47c525592 100644
--- a/lib/gs/examples/file_dialog.erl
+++ b/lib/gs/examples/file_dialog.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/focus_demo.erl b/lib/gs/examples/focus_demo.erl
index 990140d9bc..ea4700e63b 100644
--- a/lib/gs/examples/focus_demo.erl
+++ b/lib/gs/examples/focus_demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/frac.erl b/lib/gs/examples/frac.erl
index be77c8f5d4..748837b6ce 100644
--- a/lib/gs/examples/frac.erl
+++ b/lib/gs/examples/frac.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/line_demo.erl b/lib/gs/examples/line_demo.erl
index 32c2920878..da759a9684 100644
--- a/lib/gs/examples/line_demo.erl
+++ b/lib/gs/examples/line_demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/man.erl b/lib/gs/examples/man.erl
index 093ce854f8..35c70838b6 100644
--- a/lib/gs/examples/man.erl
+++ b/lib/gs/examples/man.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/menu_demo.erl b/lib/gs/examples/menu_demo.erl
index 60e335c40b..2fe96de132 100644
--- a/lib/gs/examples/menu_demo.erl
+++ b/lib/gs/examples/menu_demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/examples/rubber.erl b/lib/gs/examples/rubber.erl
index a9fe403b12..12622e5d94 100644
--- a/lib/gs/examples/rubber.erl
+++ b/lib/gs/examples/rubber.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/Makefile b/lib/gs/src/Makefile
index f0200caf01..ff3080e20e 100644
--- a/lib/gs/src/Makefile
+++ b/lib/gs/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/src/gs.appup.src b/lib/gs/src/gs.appup.src
index 2cb3b547e8..a2e87ee777 100644
--- a/lib/gs/src/gs.appup.src
+++ b/lib/gs/src/gs.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/gs/src/gs.erl b/lib/gs/src/gs.erl
index c25c75766e..7dd7eb60e3 100644
--- a/lib/gs/src/gs.erl
+++ b/lib/gs/src/gs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gs_frontend.erl b/lib/gs/src/gs_frontend.erl
index 37f91cf37c..2ebeb6c592 100644
--- a/lib/gs/src/gs_frontend.erl
+++ b/lib/gs/src/gs_frontend.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gs_make.erl b/lib/gs/src/gs_make.erl
index 9acffcd62e..029bfc09ce 100644
--- a/lib/gs/src/gs_make.erl
+++ b/lib/gs/src/gs_make.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gs_packer.erl b/lib/gs/src/gs_packer.erl
index a06ec37e5b..cbbc003e7e 100644
--- a/lib/gs/src/gs_packer.erl
+++ b/lib/gs/src/gs_packer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gs_widgets.erl b/lib/gs/src/gs_widgets.erl
index ffd4530eb4..23cece9997 100644
--- a/lib/gs/src/gs_widgets.erl
+++ b/lib/gs/src/gs_widgets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gse.erl b/lib/gs/src/gse.erl
index b63841bc20..03d7f4d81a 100644
--- a/lib/gs/src/gse.erl
+++ b/lib/gs/src/gse.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk.erl b/lib/gs/src/gstk.erl
index 04ca9b4722..3a3f3fa536 100644
--- a/lib/gs/src/gstk.erl
+++ b/lib/gs/src/gstk.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk.hrl b/lib/gs/src/gstk.hrl
index 2754f74b9b..c3649867ce 100644
--- a/lib/gs/src/gstk.hrl
+++ b/lib/gs/src/gstk.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_arc.erl b/lib/gs/src/gstk_arc.erl
index 1441bb0b32..91ca4353ef 100644
--- a/lib/gs/src/gstk_arc.erl
+++ b/lib/gs/src/gstk_arc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_button.erl b/lib/gs/src/gstk_button.erl
index 0ef6f877b4..4885ee8a1c 100644
--- a/lib/gs/src/gstk_button.erl
+++ b/lib/gs/src/gstk_button.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_canvas.erl b/lib/gs/src/gstk_canvas.erl
index 34e4be0667..90239455cd 100644
--- a/lib/gs/src/gstk_canvas.erl
+++ b/lib/gs/src/gstk_canvas.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_checkbutton.erl b/lib/gs/src/gstk_checkbutton.erl
index 14e1e8ad01..34246d67f8 100644
--- a/lib/gs/src/gstk_checkbutton.erl
+++ b/lib/gs/src/gstk_checkbutton.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_db.erl b/lib/gs/src/gstk_db.erl
index 849784574f..f0eb6f55d4 100644
--- a/lib/gs/src/gstk_db.erl
+++ b/lib/gs/src/gstk_db.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_editor.erl b/lib/gs/src/gstk_editor.erl
index cb422aef95..959e17a365 100644
--- a/lib/gs/src/gstk_editor.erl
+++ b/lib/gs/src/gstk_editor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_entry.erl b/lib/gs/src/gstk_entry.erl
index b10b6460f2..be72c6a1f2 100644
--- a/lib/gs/src/gstk_entry.erl
+++ b/lib/gs/src/gstk_entry.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_font.erl b/lib/gs/src/gstk_font.erl
index ac91e8a92a..f108b2f765 100644
--- a/lib/gs/src/gstk_font.erl
+++ b/lib/gs/src/gstk_font.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_frame.erl b/lib/gs/src/gstk_frame.erl
index 1fca8aac14..a1ebb94407 100644
--- a/lib/gs/src/gstk_frame.erl
+++ b/lib/gs/src/gstk_frame.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_generic.erl b/lib/gs/src/gstk_generic.erl
index 573b4e05bb..eb9adbdc05 100644
--- a/lib/gs/src/gstk_generic.erl
+++ b/lib/gs/src/gstk_generic.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_grid.erl b/lib/gs/src/gstk_grid.erl
index 5f4f4a24f0..155aa071e4 100644
--- a/lib/gs/src/gstk_grid.erl
+++ b/lib/gs/src/gstk_grid.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_gridline.erl b/lib/gs/src/gstk_gridline.erl
index 914a7f1c6d..6b22980835 100644
--- a/lib/gs/src/gstk_gridline.erl
+++ b/lib/gs/src/gstk_gridline.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_gs.erl b/lib/gs/src/gstk_gs.erl
index eac894759e..0f07c1da04 100644
--- a/lib/gs/src/gstk_gs.erl
+++ b/lib/gs/src/gstk_gs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_image.erl b/lib/gs/src/gstk_image.erl
index 7dbcce3cf9..797489bcf8 100644
--- a/lib/gs/src/gstk_image.erl
+++ b/lib/gs/src/gstk_image.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_label.erl b/lib/gs/src/gstk_label.erl
index c5d111d51a..99c817aed8 100644
--- a/lib/gs/src/gstk_label.erl
+++ b/lib/gs/src/gstk_label.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_line.erl b/lib/gs/src/gstk_line.erl
index 19f36f7636..4a9c02c53a 100644
--- a/lib/gs/src/gstk_line.erl
+++ b/lib/gs/src/gstk_line.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_listbox.erl b/lib/gs/src/gstk_listbox.erl
index 4b5dd76b24..351c1a12b2 100644
--- a/lib/gs/src/gstk_listbox.erl
+++ b/lib/gs/src/gstk_listbox.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_menu.erl b/lib/gs/src/gstk_menu.erl
index 09f3208299..4e372bda2a 100644
--- a/lib/gs/src/gstk_menu.erl
+++ b/lib/gs/src/gstk_menu.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_menubar.erl b/lib/gs/src/gstk_menubar.erl
index eb2806e14b..27c472e218 100644
--- a/lib/gs/src/gstk_menubar.erl
+++ b/lib/gs/src/gstk_menubar.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_menubutton.erl b/lib/gs/src/gstk_menubutton.erl
index 6c5abf600f..7025d6b179 100644
--- a/lib/gs/src/gstk_menubutton.erl
+++ b/lib/gs/src/gstk_menubutton.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_menuitem.erl b/lib/gs/src/gstk_menuitem.erl
index 03aca75b80..ddc8dd64f7 100644
--- a/lib/gs/src/gstk_menuitem.erl
+++ b/lib/gs/src/gstk_menuitem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_oval.erl b/lib/gs/src/gstk_oval.erl
index 708986235b..31174354e6 100644
--- a/lib/gs/src/gstk_oval.erl
+++ b/lib/gs/src/gstk_oval.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_polygon.erl b/lib/gs/src/gstk_polygon.erl
index 83d032901f..92ec18198e 100644
--- a/lib/gs/src/gstk_polygon.erl
+++ b/lib/gs/src/gstk_polygon.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_port_handler.erl b/lib/gs/src/gstk_port_handler.erl
index 3ecc6ac5d6..72297032c7 100644
--- a/lib/gs/src/gstk_port_handler.erl
+++ b/lib/gs/src/gstk_port_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_radiobutton.erl b/lib/gs/src/gstk_radiobutton.erl
index fac150e010..d24c5a81ae 100644
--- a/lib/gs/src/gstk_radiobutton.erl
+++ b/lib/gs/src/gstk_radiobutton.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_rectangle.erl b/lib/gs/src/gstk_rectangle.erl
index e26db2ed15..fe16fa7c67 100644
--- a/lib/gs/src/gstk_rectangle.erl
+++ b/lib/gs/src/gstk_rectangle.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_scale.erl b/lib/gs/src/gstk_scale.erl
index 7a929eef94..4afd8f61ff 100644
--- a/lib/gs/src/gstk_scale.erl
+++ b/lib/gs/src/gstk_scale.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_text.erl b/lib/gs/src/gstk_text.erl
index 1e7101d834..b8e6f53f00 100644
--- a/lib/gs/src/gstk_text.erl
+++ b/lib/gs/src/gstk_text.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_widgets.erl b/lib/gs/src/gstk_widgets.erl
index d16c0f7fea..b4e4b970d3 100644
--- a/lib/gs/src/gstk_widgets.erl
+++ b/lib/gs/src/gstk_widgets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/gstk_window.erl b/lib/gs/src/gstk_window.erl
index d9ab16df37..8a9ef47100 100644
--- a/lib/gs/src/gstk_window.erl
+++ b/lib/gs/src/gstk_window.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/tcl2erl.erl b/lib/gs/src/tcl2erl.erl
index d93f589656..f10d5b46b9 100644
--- a/lib/gs/src/tcl2erl.erl
+++ b/lib/gs/src/tcl2erl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/tool_file_dialog.erl b/lib/gs/src/tool_file_dialog.erl
index f47b4b9e3f..c42f6af17c 100644
--- a/lib/gs/src/tool_file_dialog.erl
+++ b/lib/gs/src/tool_file_dialog.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/gs/src/tool_utils.erl b/lib/gs/src/tool_utils.erl
index c6b75466be..9f2caa3eac 100644
--- a/lib/gs/src/tool_utils.erl
+++ b/lib/gs/src/tool_utils.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/gs/tcl/Makefile b/lib/gs/tcl/Makefile
index 53d7e97f7b..9a8a00905d 100644
--- a/lib/gs/tcl/Makefile
+++ b/lib/gs/tcl/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/tcl/Makefile.in b/lib/gs/tcl/Makefile.in
index c22a7037e8..f9e5a5db16 100644
--- a/lib/gs/tcl/Makefile.in
+++ b/lib/gs/tcl/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/gs/test/gs_SUITE.erl b/lib/gs/test/gs_SUITE.erl
index 01ce90df0b..3f36019728 100644
--- a/lib/gs/test/gs_SUITE.erl
+++ b/lib/gs/test/gs_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/gs/vsn.mk b/lib/gs/vsn.mk
index 96786b300c..345f0f37f2 100644
--- a/lib/gs/vsn.mk
+++ b/lib/gs/vsn.mk
@@ -1,2 +1,2 @@
-GS_VSN = 1.5.16
+GS_VSN = 1.6
diff --git a/lib/hipe/Makefile b/lib/hipe/Makefile
index 46cbc33ae2..f32faa9086 100644
--- a/lib/hipe/Makefile
+++ b/lib/hipe/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/amd64/Makefile b/lib/hipe/amd64/Makefile
index 50cd024d72..29aabea17c 100644
--- a/lib/hipe/amd64/Makefile
+++ b/lib/hipe/amd64/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/amd64/hipe_amd64_assemble.erl b/lib/hipe/amd64/hipe_amd64_assemble.erl
index db3cfcc6bd..1bc2fd0c1f 100644
--- a/lib/hipe/amd64/hipe_amd64_assemble.erl
+++ b/lib/hipe/amd64/hipe_amd64_assemble.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_defuse.erl b/lib/hipe/amd64/hipe_amd64_defuse.erl
index c48e80f3f1..7f3ba6a466 100644
--- a/lib/hipe/amd64/hipe_amd64_defuse.erl
+++ b/lib/hipe/amd64/hipe_amd64_defuse.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_encode.erl b/lib/hipe/amd64/hipe_amd64_encode.erl
index cbdab25b25..c10e6b68a7 100644
--- a/lib/hipe/amd64/hipe_amd64_encode.erl
+++ b/lib/hipe/amd64/hipe_amd64_encode.erl
@@ -3,16 +3,17 @@
%%%
%%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/amd64/hipe_amd64_frame.erl b/lib/hipe/amd64/hipe_amd64_frame.erl
index 2bc319f40f..412c021fec 100644
--- a/lib/hipe/amd64/hipe_amd64_frame.erl
+++ b/lib/hipe/amd64/hipe_amd64_frame.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_liveness.erl b/lib/hipe/amd64/hipe_amd64_liveness.erl
index be878773cb..9d8b80f337 100644
--- a/lib/hipe/amd64/hipe_amd64_liveness.erl
+++ b/lib/hipe/amd64/hipe_amd64_liveness.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_main.erl b/lib/hipe/amd64/hipe_amd64_main.erl
index 4de7364170..e95d6fec00 100644
--- a/lib/hipe/amd64/hipe_amd64_main.erl
+++ b/lib/hipe/amd64/hipe_amd64_main.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_pp.erl b/lib/hipe/amd64/hipe_amd64_pp.erl
index 93ed7b9073..bb10086865 100644
--- a/lib/hipe/amd64/hipe_amd64_pp.erl
+++ b/lib/hipe/amd64/hipe_amd64_pp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra.erl b/lib/hipe/amd64/hipe_amd64_ra.erl
index b9ac0338f0..79e915fbe2 100644
--- a/lib/hipe/amd64/hipe_amd64_ra.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra_finalise.erl b/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
index a6a787c340..721fe20a26 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra_ls.erl b/lib/hipe/amd64/hipe_amd64_ra_ls.erl
index 7ff2a7c082..6a8034305b 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_ls.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_ls.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra_naive.erl b/lib/hipe/amd64/hipe_amd64_ra_naive.erl
index 194ea8b597..f73c67f5c7 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_naive.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_naive.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
index ef3c284c45..35244aa484 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
index 9ed3d01a56..0568a46942 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl b/lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl
index 267f3335aa..89852ed3d8 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_registers.erl b/lib/hipe/amd64/hipe_amd64_registers.erl
index 4c49eeb00a..c2af44982c 100644
--- a/lib/hipe/amd64/hipe_amd64_registers.erl
+++ b/lib/hipe/amd64/hipe_amd64_registers.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_spill_restore.erl b/lib/hipe/amd64/hipe_amd64_spill_restore.erl
index 56e3ffd24d..b5c4de2613 100644
--- a/lib/hipe/amd64/hipe_amd64_spill_restore.erl
+++ b/lib/hipe/amd64/hipe_amd64_spill_restore.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_amd64_x87.erl b/lib/hipe/amd64/hipe_amd64_x87.erl
index e7bf1c1866..f206205307 100644
--- a/lib/hipe/amd64/hipe_amd64_x87.erl
+++ b/lib/hipe/amd64/hipe_amd64_x87.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/amd64/hipe_rtl_to_amd64.erl b/lib/hipe/amd64/hipe_rtl_to_amd64.erl
index 17aef0eeac..5d09bdb877 100644
--- a/lib/hipe/amd64/hipe_rtl_to_amd64.erl
+++ b/lib/hipe/amd64/hipe_rtl_to_amd64.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/Makefile b/lib/hipe/arm/Makefile
index 651b82f1ed..889c6a13e4 100644
--- a/lib/hipe/arm/Makefile
+++ b/lib/hipe/arm/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/arm/hipe_arm.erl b/lib/hipe/arm/hipe_arm.erl
index 391f84ca47..2ac3ca81b4 100644
--- a/lib/hipe/arm/hipe_arm.erl
+++ b/lib/hipe/arm/hipe_arm.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm.hrl b/lib/hipe/arm/hipe_arm.hrl
index 9ee2cb3d06..a15c366065 100644
--- a/lib/hipe/arm/hipe_arm.hrl
+++ b/lib/hipe/arm/hipe_arm.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_assemble.erl b/lib/hipe/arm/hipe_arm_assemble.erl
index e9de96a927..5f98c6593e 100644
--- a/lib/hipe/arm/hipe_arm_assemble.erl
+++ b/lib/hipe/arm/hipe_arm_assemble.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -47,7 +48,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
DataRelocs = hipe_pack_constants:mk_data_relocs(RefsFromConsts, LabelMap),
SSE = hipe_pack_constants:slim_sorted_exportmap(ExportMap,Closures,Exports),
SlimRefs = hipe_pack_constants:slim_refs(AccRefs),
- Bin = term_to_binary([{?VERSION_STRING(),?HIPE_SYSTEM_CRC},
+ Bin = term_to_binary([{?VERSION_STRING(),?HIPE_ERTS_CHECKSUM},
ConstAlign, ConstSize,
SC,
DataRelocs, % nee LM, LabelMap
diff --git a/lib/hipe/arm/hipe_arm_cfg.erl b/lib/hipe/arm/hipe_arm_cfg.erl
index 984a3ccf9e..f30fa5a0b6 100644
--- a/lib/hipe/arm/hipe_arm_cfg.erl
+++ b/lib/hipe/arm/hipe_arm_cfg.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_defuse.erl b/lib/hipe/arm/hipe_arm_defuse.erl
index 8d6efebc21..8f194c4b48 100644
--- a/lib/hipe/arm/hipe_arm_defuse.erl
+++ b/lib/hipe/arm/hipe_arm_defuse.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_encode.erl b/lib/hipe/arm/hipe_arm_encode.erl
index 19e507fdbd..05ded31657 100644
--- a/lib/hipe/arm/hipe_arm_encode.erl
+++ b/lib/hipe/arm/hipe_arm_encode.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/arm/hipe_arm_finalise.erl b/lib/hipe/arm/hipe_arm_finalise.erl
index 38e3efd223..f4c8f8cfbc 100644
--- a/lib/hipe/arm/hipe_arm_finalise.erl
+++ b/lib/hipe/arm/hipe_arm_finalise.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_frame.erl b/lib/hipe/arm/hipe_arm_frame.erl
index 316aa2ef82..2f0d4c3c50 100644
--- a/lib/hipe/arm/hipe_arm_frame.erl
+++ b/lib/hipe/arm/hipe_arm_frame.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_liveness_gpr.erl b/lib/hipe/arm/hipe_arm_liveness_gpr.erl
index cab81c47a1..25265b25ea 100644
--- a/lib/hipe/arm/hipe_arm_liveness_gpr.erl
+++ b/lib/hipe/arm/hipe_arm_liveness_gpr.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_main.erl b/lib/hipe/arm/hipe_arm_main.erl
index 5243b3579e..46cd71d89f 100644
--- a/lib/hipe/arm/hipe_arm_main.erl
+++ b/lib/hipe/arm/hipe_arm_main.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_pp.erl b/lib/hipe/arm/hipe_arm_pp.erl
index c4dde31188..744d06d16d 100644
--- a/lib/hipe/arm/hipe_arm_pp.erl
+++ b/lib/hipe/arm/hipe_arm_pp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/arm/hipe_arm_ra.erl b/lib/hipe/arm/hipe_arm_ra.erl
index bdd9e228e0..5824fcb8d8 100644
--- a/lib/hipe/arm/hipe_arm_ra.erl
+++ b/lib/hipe/arm/hipe_arm_ra.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_ra_finalise.erl b/lib/hipe/arm/hipe_arm_ra_finalise.erl
index 9edc362e90..b67c7407a2 100644
--- a/lib/hipe/arm/hipe_arm_ra_finalise.erl
+++ b/lib/hipe/arm/hipe_arm_ra_finalise.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_ra_ls.erl b/lib/hipe/arm/hipe_arm_ra_ls.erl
index 53bfd5b2a3..500256e0e3 100644
--- a/lib/hipe/arm/hipe_arm_ra_ls.erl
+++ b/lib/hipe/arm/hipe_arm_ra_ls.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/arm/hipe_arm_ra_naive.erl b/lib/hipe/arm/hipe_arm_ra_naive.erl
index 786895f2ca..b244acd3fe 100644
--- a/lib/hipe/arm/hipe_arm_ra_naive.erl
+++ b/lib/hipe/arm/hipe_arm_ra_naive.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_ra_postconditions.erl b/lib/hipe/arm/hipe_arm_ra_postconditions.erl
index 96b0d5733f..1ac2521928 100644
--- a/lib/hipe/arm/hipe_arm_ra_postconditions.erl
+++ b/lib/hipe/arm/hipe_arm_ra_postconditions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_arm_registers.erl b/lib/hipe/arm/hipe_arm_registers.erl
index ff6a163e9c..31579c4ecb 100644
--- a/lib/hipe/arm/hipe_arm_registers.erl
+++ b/lib/hipe/arm/hipe_arm_registers.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/arm/hipe_rtl_to_arm.erl b/lib/hipe/arm/hipe_rtl_to_arm.erl
index a4dc5db978..3455c753d6 100644
--- a/lib/hipe/arm/hipe_rtl_to_arm.erl
+++ b/lib/hipe/arm/hipe_rtl_to_arm.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/cerl/Makefile b/lib/hipe/cerl/Makefile
index d13dfb33c2..0938010577 100644
--- a/lib/hipe/cerl/Makefile
+++ b/lib/hipe/cerl/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/cerl/cerl_cconv.erl b/lib/hipe/cerl/cerl_cconv.erl
index cf4d317b0d..0fc28be5f3 100644
--- a/lib/hipe/cerl/cerl_cconv.erl
+++ b/lib/hipe/cerl/cerl_cconv.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/cerl/cerl_closurean.erl b/lib/hipe/cerl/cerl_closurean.erl
index 1b325703ae..7080ff4f3b 100644
--- a/lib/hipe/cerl/cerl_closurean.erl
+++ b/lib/hipe/cerl/cerl_closurean.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/cerl/cerl_hipe_primops.hrl b/lib/hipe/cerl/cerl_hipe_primops.hrl
index a777cd0108..361227540a 100644
--- a/lib/hipe/cerl/cerl_hipe_primops.hrl
+++ b/lib/hipe/cerl/cerl_hipe_primops.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/cerl/cerl_hipeify.erl b/lib/hipe/cerl/cerl_hipeify.erl
index 3351be77f2..8691e80cac 100644
--- a/lib/hipe/cerl/cerl_hipeify.erl
+++ b/lib/hipe/cerl/cerl_hipeify.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/cerl/cerl_lib.erl b/lib/hipe/cerl/cerl_lib.erl
index 83bb20e047..52a5c987e0 100644
--- a/lib/hipe/cerl/cerl_lib.erl
+++ b/lib/hipe/cerl/cerl_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/cerl/cerl_messagean.erl b/lib/hipe/cerl/cerl_messagean.erl
index 7911b875a9..5e23015cbc 100644
--- a/lib/hipe/cerl/cerl_messagean.erl
+++ b/lib/hipe/cerl/cerl_messagean.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/cerl/cerl_pmatch.erl b/lib/hipe/cerl/cerl_pmatch.erl
index 3bc93e80dd..ce76d244b6 100644
--- a/lib/hipe/cerl/cerl_pmatch.erl
+++ b/lib/hipe/cerl/cerl_pmatch.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -31,7 +32,7 @@
-module(cerl_pmatch).
--define(NO_UNUSED, true).
+%%-define(NO_UNUSED, true).
-export([clauses/2]).
-ifndef(NO_UNUSED).
@@ -59,6 +60,8 @@
%% @see transform/2
-ifndef(NO_UNUSED).
+-spec core_transform(cerl:c_module(), [_]) -> cerl:c_module().
+
core_transform(M, Opts) ->
cerl:to_records(transform(cerl:from_records(M), Opts)).
-endif. % NO_UNUSED
@@ -76,6 +79,8 @@ core_transform(M, Opts) ->
%% @see core_transform/2
-ifndef(NO_UNUSED).
+-spec transform(cerl:cerl(), [_]) -> cerl:cerl().
+
transform(M, _Opts) ->
expr(M, env__empty()).
-endif. % NO_UNUSED
@@ -109,7 +114,7 @@ transform(M, _Opts) ->
%% @see expr/2
%% @see transform/2
--spec clauses([cerl:cerl()], rec_env:environment()) ->
+-spec clauses([cerl:cerl(),...], rec_env:environment()) ->
{cerl:cerl(), [cerl:cerl()]}.
clauses(Cs, Env) ->
@@ -406,6 +411,8 @@ make_let(Vs, A, B) ->
%% @see rec_env
-ifndef(NO_UNUSED).
+-spec expr(cerl:cerl(), rec_env:environment()) -> cerl:cerl().
+
expr(E, Env) ->
case cerl:type(E) of
literal ->
diff --git a/lib/hipe/cerl/cerl_prettypr.erl b/lib/hipe/cerl/cerl_prettypr.erl
index f4a67439d6..1a6e6999fe 100644
--- a/lib/hipe/cerl/cerl_prettypr.erl
+++ b/lib/hipe/cerl/cerl_prettypr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -63,8 +64,8 @@
seq_arg/1, seq_body/1, string_lit/1, try_arg/1,
try_body/1, try_vars/1, try_evars/1, try_handler/1,
tuple_es/1, type/1, values_es/1, var_name/1,
- c_map/1, map_arg/1, map_es/1, is_c_map_empty/1,
- c_map_pair/2, map_pair_key/1, map_pair_val/1, map_pair_op/1
+ map_arg/1, map_es/1, is_c_map_empty/1,
+ map_pair_key/1, map_pair_val/1, map_pair_op/1
]).
-define(PAPER, 76).
@@ -498,12 +499,8 @@ lay_literal(Node, Ctxt) ->
lay_cons(Node, Ctxt);
V when is_tuple(V) ->
lay_tuple(Node, Ctxt);
- M when is_map(M), map_size(M) =:= 0 ->
- text("~{}~");
M when is_map(M) ->
- lay_map(c_map([c_map_pair(abstract(K),abstract(V))
- || {K,V} <- maps:to_list(M)]),
- Ctxt)
+ lay_map(Node, Ctxt)
end.
lay_var(Node, Ctxt) ->
@@ -626,12 +623,10 @@ lay_map_pair(Node, Ctxt) ->
K = map_pair_key(Node),
V = map_pair_val(Node),
OpTxt = case concrete(map_pair_op(Node)) of
- assoc -> "::<";
- exact -> "~<"
+ assoc -> "=>";
+ exact -> ":="
end,
- beside(floating(text(OpTxt)),
- beside(lay(K,Ctxt),beside(floating(text(",")), beside(lay(V,Ctxt),
- floating(text(">")))))).
+ beside(lay(K,Ctxt),beside(floating(text(OpTxt)),lay(V,Ctxt))).
lay_let(Node, Ctxt) ->
V = lay_value_list(let_vars(Node), Ctxt),
diff --git a/lib/hipe/cerl/cerl_to_icode.erl b/lib/hipe/cerl/cerl_to_icode.erl
index 2645056be1..ab131c2d01 100644
--- a/lib/hipe/cerl/cerl_to_icode.erl
+++ b/lib/hipe/cerl/cerl_to_icode.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -110,7 +111,7 @@
effect = false :: boolean(),
fail = [], % [] or fail-to label
class = expr :: 'expr' | 'guard',
- line = 0 :: erl_scan:line(), % current line number
+ line = 0 :: erl_anno:line(), % current line number
'receive' :: 'undefined' | #'receive'{}
}).
@@ -793,9 +794,9 @@ bitstr_gen_op([V], #ctxt{fail=FL, class=guard}, SizeInfo, ConstInfo,
Type, Flags, Base, Offset) ->
SL = new_label(),
case SizeInfo of
- {all,_NewUnit, NewAlign, S1} ->
+ {all, NewUnit, NewAlign, S1} ->
Type = binary,
- Name = {bs_put_binary_all, Flags},
+ Name = {bs_put_binary_all, NewUnit, Flags},
Primop = {hipe_bs_primop, Name},
{add_code([icode_guardop([Offset], Primop,
[V, Base, Offset], SL, FL),
@@ -818,9 +819,9 @@ bitstr_gen_op([V], #ctxt{fail=FL, class=guard}, SizeInfo, ConstInfo,
bitstr_gen_op([V], _Ctxt, SizeInfo, ConstInfo, Type, Flags, Base,
Offset) ->
case SizeInfo of
- {all, _NewUnit, NewAlign, S} ->
+ {all, NewUnit, NewAlign, S} ->
Type = binary,
- Name = {bs_put_binary_all, Flags},
+ Name = {bs_put_binary_all, NewUnit, Flags},
Primop = {hipe_bs_primop, Name},
{add_code([icode_call_primop([Offset], Primop,
[V, Base, Offset])], S),
diff --git a/lib/hipe/cerl/cerl_typean.erl b/lib/hipe/cerl/cerl_typean.erl
index f694c07c82..13ee19c82a 100644
--- a/lib/hipe/cerl/cerl_typean.erl
+++ b/lib/hipe/cerl/cerl_typean.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 74e93bf098..9f23b6a9b3 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -92,7 +93,7 @@
t_list/0,
t_list/1,
t_list_elements/2,
- t_list_termination/1,
+ t_list_termination/2,
t_mfa/0,
t_module/0,
t_nil/0,
@@ -513,14 +514,15 @@ type(erlang, 'bsl', 2, Xs, Opaques) ->
type(erlang, 'bnot', 1, Xs, Opaques) ->
strict(erlang, 'bnot', 1, Xs,
fun ([X1]) ->
- case arith('bnot', X1, Opaques) of
+ case arith_bnot(X1, Opaques) of
error -> t_integer();
{ok, T} -> T
end
end, Opaques);
%% Guard bif, needs to be here.
type(erlang, abs, 1, Xs, Opaques) ->
- strict(erlang, abs, 1, Xs, fun ([X]) -> X end, Opaques);
+ strict(erlang, abs, 1, Xs,
+ fun ([X1]) -> arith_abs(X1, Opaques) end, Opaques);
%% This returns (-X)-1, so it often gives a negative result.
%% strict(erlang, 'bnot', 1, Xs, fun (_) -> t_integer() end, Opaques);
type(erlang, append, 2, Xs, _Opaques) -> type(erlang, '++', 2, Xs); % alias
@@ -766,6 +768,18 @@ type(erlang, length, 1, Xs, Opaques) ->
%% Guard bif, needs to be here.
type(erlang, map_size, 1, Xs, Opaques) ->
strict(erlang, map_size, 1, Xs, fun (_) -> t_non_neg_integer() end, Opaques);
+type(erlang, make_fun, 3, Xs, Opaques) ->
+ strict(erlang, make_fun, 3, Xs,
+ fun ([_, _, Arity]) ->
+ case t_number_vals(Arity, Opaques) of
+ [N] ->
+ case is_integer(N) andalso 0 =< N andalso N =< 255 of
+ true -> t_fun(N, t_any());
+ false -> t_none()
+ end;
+ _Other -> t_fun()
+ end
+ end, Opaques);
type(erlang, make_tuple, 2, Xs, Opaques) ->
strict(erlang, make_tuple, 2, Xs,
fun ([Int, _]) ->
@@ -1070,9 +1084,6 @@ type(hipe_bifs, find_na_or_make_stub, 2, Xs, Opaques) ->
type(hipe_bifs, fun_to_address, 1, Xs, Opaques) ->
strict(hipe_bifs, fun_to_address, 1, Xs,
fun (_) -> t_integer() end, Opaques);
-%% type(hipe_bifs, get_emu_address, 1, Xs, Opaques) ->
-%% strict(hipe_bifs, get_emu_address, 1, Xs,
-%% fun (_) -> t_integer() end, Opaques); % address
type(hipe_bifs, get_fe, 2, Xs, Opaques) ->
strict(hipe_bifs, get_fe, 2, Xs, fun (_) -> t_integer() end, Opaques);
type(hipe_bifs, get_rts_param, 1, Xs, Opaques) ->
@@ -1081,9 +1092,6 @@ type(hipe_bifs, get_rts_param, 1, Xs, Opaques) ->
type(hipe_bifs, invalidate_funinfo_native_addresses, 1, Xs, Opaques) ->
strict(hipe_bifs, invalidate_funinfo_native_addresses, 1, Xs,
fun (_) -> t_nil() end, Opaques);
-%% type(hipe_bifs, make_native_stub, 2, Xs, Opaques) ->
-%% strict(hipe_bifs, make_native_stub, 2, Xs,
-%% fun (_) -> t_integer() end, Opaques); % address
type(hipe_bifs, mark_referred_from, 1, Xs, Opaques) ->
strict(hipe_bifs, mark_referred_from, 1, Xs,
fun (_) -> t_nil() end, Opaques);
@@ -1119,8 +1127,8 @@ type(hipe_bifs, set_native_address, 3, Xs, Opaques) ->
type(hipe_bifs, set_native_address_in_fe, 2, Xs, Opaques) ->
strict(hipe_bifs, set_native_address_in_fe, 2, Xs,
fun (_) -> t_atom('true') end, Opaques);
-type(hipe_bifs, system_crc, 1, Xs, Opaques) ->
- strict(hipe_bifs, system_crc, 1, Xs, fun (_) -> t_crc32() end, Opaques);
+type(hipe_bifs, system_crc, 0, _, _Opaques) ->
+ t_crc32();
type(hipe_bifs, term_to_word, 1, Xs, Opaques) ->
strict(hipe_bifs, term_to_word, 1, Xs,
fun (_) -> t_integer() end, Opaques);
@@ -1341,8 +1349,8 @@ type(lists, foldr, 3, Xs, _Opaques) -> type(lists, foldl, 3, Xs); % same
type(lists, keydelete, 3, Xs, Opaques) ->
strict(lists, keydelete, 3, Xs,
fun ([_, _, L]) ->
- Term = t_list_termination(L),
- t_sup(Term, erl_types:lift_list_to_pos_empty(L))
+ Term = t_list_termination(L, Opaques),
+ t_sup(Term, erl_types:lift_list_to_pos_empty(L, Opaques))
end, Opaques);
type(lists, keyfind, 3, Xs, Opaques) ->
strict(lists, keyfind, 3, Xs,
@@ -1932,7 +1940,7 @@ negwidth(X, N) ->
false -> negwidth(X, N+1)
end.
-arith('bnot', X1, Opaques) ->
+arith_bnot(X1, Opaques) ->
case t_is_integer(X1, Opaques) of
false -> error;
true ->
@@ -1942,6 +1950,28 @@ arith('bnot', X1, Opaques) ->
infinity_add(infinity_inv(Min1), -1))}
end.
+arith_abs(X1, Opaques) ->
+ case t_is_integer(X1, Opaques) of
+ false ->
+ case t_is_float(X1, Opaques) of
+ true -> t_float();
+ false -> t_number()
+ end;
+ true ->
+ Min1 = number_min(X1, Opaques),
+ Max1 = number_max(X1, Opaques),
+ {NewMin, NewMax} =
+ case infinity_geq(Min1, 0) of
+ true -> {Min1, Max1};
+ false ->
+ case infinity_geq(Max1, 0) of
+ true -> {0, infinity_inv(Min1)};
+ false -> {infinity_inv(Max1), infinity_inv(Min1)}
+ end
+ end,
+ t_from_range(NewMin, NewMax)
+ end.
+
arith_mult(Min1, Max1, Min2, Max2) ->
Tmp_list = [infinity_mult(Min1, Min2), infinity_mult(Min1, Max2),
infinity_mult(Max1, Min2), infinity_mult(Max1, Max2)],
@@ -2170,7 +2200,7 @@ type_ranks(Type, I, Min, Max, [TypeClass|Rest], Opaques) ->
type_order() ->
[t_number(), t_atom(), t_reference(), t_fun(), t_port(), t_pid(), t_tuple(),
- t_list(), t_binary()].
+ t_map(), t_list(), t_bitstr()].
key_comparisons_fail(X0, KeyPos, TupleList, Opaques) ->
X = case t_is_number(t_inf(X0, t_number(), Opaques), Opaques) of
@@ -2270,7 +2300,7 @@ arg_types(erlang, bit_size, 1) ->
[t_bitstr()];
%% Guard bif, needs to be here.
arg_types(erlang, byte_size, 1) ->
- [t_binary()];
+ [t_bitstr()];
arg_types(erlang, disconnect_node, 1) ->
[t_node()];
arg_types(erlang, halt, 0) ->
@@ -2343,6 +2373,8 @@ arg_types(erlang, length, 1) ->
%% Guard bif, needs to be here.
arg_types(erlang, map_size, 1) ->
[t_map()];
+arg_types(erlang, make_fun, 3) ->
+ [t_atom(), t_atom(), t_arity()];
arg_types(erlang, make_tuple, 2) ->
[t_non_neg_fixnum(), t_any()]; % the value 0 is OK as first argument
arg_types(erlang, make_tuple, 3) ->
@@ -2462,16 +2494,12 @@ arg_types(hipe_bifs, find_na_or_make_stub, 2) ->
[t_mfa(), t_boolean()];
arg_types(hipe_bifs, fun_to_address, 1) ->
[t_mfa()];
-%% arg_types(hipe_bifs, get_emu_address, 1) ->
-%% [t_mfa()];
arg_types(hipe_bifs, get_fe, 2) ->
[t_atom(), t_tuple([t_integer(), t_integer(), t_integer()])];
arg_types(hipe_bifs, get_rts_param, 1) ->
[t_fixnum()];
arg_types(hipe_bifs, invalidate_funinfo_native_addresses, 1) ->
[t_list(t_mfa())];
-%% arg_types(hipe_bifs, make_native_stub, 2) ->
-%% [t_integer(), t_arity()];
arg_types(hipe_bifs, mark_referred_from, 1) ->
[t_mfa()];
arg_types(hipe_bifs, merge_term, 1) ->
@@ -2500,8 +2528,8 @@ arg_types(hipe_bifs, set_native_address, 3) ->
[t_mfa(), t_integer(), t_boolean()];
arg_types(hipe_bifs, set_native_address_in_fe, 2) ->
[t_integer(), t_integer()];
-arg_types(hipe_bifs, system_crc, 1) ->
- [t_crc32()];
+arg_types(hipe_bifs, system_crc, 0) ->
+ [];
arg_types(hipe_bifs, term_to_word, 1) ->
[t_any()];
arg_types(hipe_bifs, update_code_size, 3) ->
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 4215448c61..7a2abc226f 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,7 +41,6 @@
any_none_or_unit/1,
lookup_record/3,
max/2,
- module_builtin_opaques/1,
min/2,
number_max/1, number_max/2,
number_min/1, number_min/2,
@@ -68,7 +68,6 @@
t_cons/2,
t_cons_hd/1, t_cons_hd/2,
t_cons_tl/1, t_cons_tl/2,
- t_constant/0,
t_contains_opaque/1, t_contains_opaque/2,
t_decorate_with_opaque/3,
t_elements/1,
@@ -79,10 +78,13 @@
t_non_neg_fixnum/0,
t_pos_fixnum/0,
t_float/0,
+ t_var_names/1,
t_form_to_string/1,
- t_from_form/1,
- t_from_form/2,
- t_from_form/3,
+ t_from_form/4,
+ t_from_form/5,
+ t_from_form_without_remote/3,
+ t_check_record_fields/4,
+ t_check_record_fields/5,
t_from_range/2,
t_from_range_unsafe/2,
t_from_term/1,
@@ -118,7 +120,6 @@
%% t_is_byte/1,
%% t_is_char/1,
t_is_cons/1, t_is_cons/2,
- t_is_constant/1,
t_is_equal/2,
t_is_fixnum/1,
t_is_float/1, t_is_float/2,
@@ -149,7 +150,7 @@
t_list/0,
t_list/1,
t_list_elements/1, t_list_elements/2,
- t_list_termination/1,
+ t_list_termination/1, t_list_termination/2,
t_map/0,
t_map/1,
t_matchstate/0,
@@ -182,13 +183,11 @@
t_remote/3,
t_string/0,
t_struct_from_opaque/2,
- t_solve_remote/3,
t_subst/2,
t_subtract/2,
t_subtract_list/2,
t_sup/1,
t_sup/2,
- t_tid/0,
t_timeout/0,
t_to_string/1,
t_to_string/2,
@@ -210,7 +209,7 @@
record_field_diffs_to_string/2,
subst_all_vars_to_any/1,
subst_all_remote/2,
- lift_list_to_pos_empty/1,
+ lift_list_to_pos_empty/1, lift_list_to_pos_empty/2,
is_opaque_type/2,
is_erl_type/1,
atom_to_string/1
@@ -250,6 +249,8 @@
%%
-define(REC_TYPE_LIMIT, 2).
+-define(EXPAND_DEPTH, 16).
+-define(EXPAND_LIMIT, 10000).
-define(TUPLE_TAG_LIMIT, 5).
-define(TUPLE_ARITY_LIMIT, 8).
@@ -368,7 +369,7 @@
-type record_key() :: {'record', atom()}.
-type type_key() :: {'type' | 'opaque', atom(), arity()}.
--type record_value() :: orddict:orddict(). % XXX. To be refined
+-type record_value() :: [{atom(), erl_parse:abstract_expr(), erl_type()}].
-type type_value() :: {module(), erl_type(), atom()}.
-type type_table() :: dict:dict(record_key(), record_value())
| dict:dict(type_key(), type_value()).
@@ -466,16 +467,6 @@ has_opaque_subtype(T) ->
t_opaque_structure(?opaque(Elements)) ->
t_sup([Struct || #opaque{struct = Struct} <- ordsets:to_list(Elements)]).
--spec t_opaque_modules(erl_type()) -> [module()].
-
-t_opaque_modules(?opaque(Elements)) ->
- case ordsets:size(Elements) of
- 1 ->
- [#opaque{mod = Mod}] = set_to_list(Elements),
- [Mod];
- _ -> throw({error, "Unexpected multiple opaque types"})
- end.
-
-spec t_contains_opaque(erl_type()) -> boolean().
t_contains_opaque(Type) ->
@@ -593,13 +584,11 @@ t_find_opaque_mismatch_list([H|T]) ->
%% calling t_contains_opaque/2 is that the traversal stops when
%% there is a mismatch which means that unknown opaque types "below"
%% the mismatch are not found.
-%% XXX. Returns one element even if both oparands contain opaque types.
-%% XXX. Slow since t_inf() is called but the results are ignored.
t_find_unknown_opaque(_T1, _T2, 'universe') -> [];
t_find_unknown_opaque(T1, T2, Opaques) ->
try t_inf(T1, T2, {match, Opaques}) of
_ -> []
- catch throw:N when is_integer(N) -> [N]
+ catch throw:{pos, Ns} -> Ns
end.
-spec t_decorate_with_opaque(erl_type(), erl_type(), [erl_type()]) -> erl_type().
@@ -759,14 +748,15 @@ t_opaque_from_records(RecDict) ->
end
end, RecDict),
OpaqueTypeDict =
- dict:map(fun({opaque, Name, _Arity}, {Module, _Type, ArgNames}) ->
+ dict:map(fun({opaque, Name, _Arity},
+ {{Module, _FileLine, _Form, ArgNames}, _Type}) ->
%% Args = args_to_types(ArgNames),
%% List = lists:zip(ArgNames, Args),
%% TmpVarDict = dict:from_list(List),
%% Rep = t_from_form(Type, RecDict, TmpVarDict),
- Rep = t_none(), % not used for anything right now
+ Rep = t_any(), % not used for anything right now
Args = [t_any() || _ <- ArgNames],
- skip_opaque_alias(Rep, Module, Name, Args)
+ t_opaque(Module, Name, Args, Rep)
end, OpaqueRecDict),
[OpaqueType || {_Key, OpaqueType} <- dict:to_list(OpaqueTypeDict)].
@@ -801,11 +791,6 @@ t_struct_from_opaque(Type, _Opaques) -> Type.
list_struct_from_opaque(Types, Opaques) ->
[t_struct_from_opaque(Type, Opaques) || Type <- Types].
--spec module_builtin_opaques(module()) -> [erl_type()].
-
-module_builtin_opaques(Module) ->
- [O || O <- all_opaque_builtins(), lists:member(Module, t_opaque_modules(O))].
-
%%-----------------------------------------------------------------------------
%% Remote types: these types are used for preprocessing;
%% they should never reach the analysis stage.
@@ -825,134 +810,6 @@ is_remote(_) -> false.
-type mod_records() :: dict:dict(module(), type_table()).
--spec t_solve_remote(erl_type(), sets:set(mfa()), mod_records()) -> erl_type().
-
-t_solve_remote(Type, ExpTypes, Records) ->
- {RT, _RR} = t_solve_remote(Type, ExpTypes, Records, []),
- RT.
-
-t_solve_remote(?function(Domain, Range), ET, R, C) ->
- {RT1, RR1} = t_solve_remote(Domain, ET, R, C),
- {RT2, RR2} = t_solve_remote(Range, ET, R, C),
- {?function(RT1, RT2), RR1 ++ RR2};
-t_solve_remote(?list(Types, Term, Size), ET, R, C) ->
- {RT1, RR1} = t_solve_remote(Types, ET, R, C),
- {RT2, RR2} = t_solve_remote(Term, ET, R, C),
- {?list(RT1, RT2, Size), RR1 ++ RR2};
-t_solve_remote(?product(Types), ET, R, C) ->
- {RL, RR} = list_solve_remote(Types, ET, R, C),
- {?product(RL), RR};
-t_solve_remote(?opaque(Set), ET, R, C) ->
- List = ordsets:to_list(Set),
- {NewList, RR} = opaques_solve_remote(List, ET, R, C),
- {?opaque(ordsets:from_list(NewList)), RR};
-t_solve_remote(?tuple(?any, _, _) = T, _ET, _R, _C) -> {T, []};
-t_solve_remote(?tuple(Types, _Arity, _Tag), ET, R, C) ->
- {RL, RR} = list_solve_remote(Types, ET, R, C),
- {t_tuple(RL), RR};
-t_solve_remote(?tuple_set(Set), ET, R, C) ->
- {NewTuples, RR} = tuples_solve_remote(Set, ET, R, C),
- {t_sup(NewTuples), RR};
-t_solve_remote(?remote(Set), ET, R, C) ->
- RemoteList = ordsets:to_list(Set),
- {RL, RR} = list_solve_remote_type(RemoteList, ET, R, C),
- {t_sup(RL), RR};
-t_solve_remote(?union(List), ET, R, C) ->
- {RL, RR} = list_solve_remote(List, ET, R, C),
- {t_sup(RL), RR};
-t_solve_remote(T, _ET, _R, _C) -> {T, []}.
-
-t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args0} = RemType,
- ET, R, C) ->
- Args = lists:map(fun(A) ->
- {Arg, _} = t_solve_remote(A, ET, R, C),
- Arg
- end, Args0),
- ArgsLen = length(Args),
- case dict:find(RemMod, R) of
- error ->
- self() ! {self(), ext_types, {RemMod, Name, ArgsLen}},
- {t_any(), []};
- {ok, RemDict} ->
- MFA = {RemMod, Name, ArgsLen},
- case sets:is_element(MFA, ET) of
- true ->
- case lookup_type(Name, ArgsLen, RemDict) of
- {type, {_Mod, Type, ArgNames}} ->
- {NewType, NewCycle, NewRR} =
- case can_unfold_more(RemType, C) of
- true ->
- List = lists:zip(ArgNames, Args),
- TmpVarDict = dict:from_list(List),
- {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []};
- false ->
- {t_any(), C, [RemType]}
- end,
- {RT, RR} = t_solve_remote(NewType, ET, R, NewCycle),
- RetRR = NewRR ++ RR,
- RT1 =
- case lists:member(RemType, RetRR) of
- true -> t_limit(RT, ?REC_TYPE_LIMIT);
- false -> RT
- end,
- {RT1, RetRR};
- {opaque, {Mod, Type, ArgNames}} ->
- List = lists:zip(ArgNames, Args),
- TmpVarDict = dict:from_list(List),
- {Rep, NewCycle, NewRR} =
- case can_unfold_more(RemType, C) of
- true ->
- {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []};
- false ->
- {t_any(), C, [RemType]}
- end,
- {NewRep, RR} = t_solve_remote(Rep, ET, R, NewCycle),
- RetRR = NewRR ++ RR,
- RT1 =
- case lists:member(RemType, RetRR) of
- true -> t_limit(NewRep, ?REC_TYPE_LIMIT);
- false -> NewRep
- end,
- {skip_opaque_alias(RT1, Mod, Name, Args), RetRR};
- error ->
- Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
- [RemMod, Name]),
- throw({error, Msg})
- end;
- false ->
- self() ! {self(), ext_types, {RemMod, Name, ArgsLen}},
- {t_any(), []}
- end
- end.
-
-list_solve_remote([], _ET, _R, _C) ->
- {[], []};
-list_solve_remote([Type|Types], ET, R, C) ->
- {RT, RR1} = t_solve_remote(Type, ET, R, C),
- {RL, RR2} = list_solve_remote(Types, ET, R, C),
- {[RT|RL], RR1 ++ RR2}.
-
-list_solve_remote_type([], _ET, _R, _C) ->
- {[], []};
-list_solve_remote_type([Type|Types], ET, R, C) ->
- {RT, RR1} = t_solve_remote_type(Type, ET, R, C),
- {RL, RR2} = list_solve_remote_type(Types, ET, R, C),
- {[RT|RL], RR1 ++ RR2}.
-
-opaques_solve_remote([], _ET, _R, _C) ->
- {[], []};
-opaques_solve_remote([#opaque{struct = Struct} = Remote|Tail], ET, R, C) ->
- {RT, RR1} = t_solve_remote(Struct, ET, R, C),
- {LOp, RR2} = opaques_solve_remote(Tail, ET, R, C),
- {[Remote#opaque{struct = RT}|LOp], RR1 ++ RR2}.
-
-tuples_solve_remote([], _ET, _R, _C) ->
- {[], []};
-tuples_solve_remote([{_Sz, Tuples}|Tail], ET, R, C) ->
- {RL, RR1} = list_solve_remote(Tuples, ET, R, C),
- {LSzTpls, RR2} = tuples_solve_remote(Tail, ET, R, C),
- {RL ++ LSzTpls, RR1 ++ RR2}.
-
%%-----------------------------------------------------------------------------
%% Unit type. Signals non termination.
%%
@@ -1653,6 +1510,11 @@ t_list_elements(Type, Opaques) ->
list_elements(?list(Contents, _, _)) -> Contents;
list_elements(?nil) -> ?none.
+-spec t_list_termination(erl_type(), opaques()) -> erl_type().
+
+t_list_termination(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun t_list_termination/1).
+
-spec t_list_termination(erl_type()) -> erl_type().
t_list_termination(?nil) -> ?nil;
@@ -1728,6 +1590,11 @@ is_maybe_improper_list(_) -> false.
%% %% false = t_is_subtype(t_nil(), Termination),
%% ?list(Content, Termination, ?any).
+-spec lift_list_to_pos_empty(erl_type(), opaques()) -> erl_type().
+
+lift_list_to_pos_empty(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun lift_list_to_pos_empty/1).
+
-spec lift_list_to_pos_empty(erl_type()) -> erl_type().
lift_list_to_pos_empty(?nil) -> ?nil;
@@ -1891,17 +1758,6 @@ is_tuple1(_) -> false.
t_bitstrlist() ->
t_iolist(1, t_bitstr()).
-%% XXX. To be removed.
--spec t_constant() -> erl_type().
-
-t_constant() ->
- t_sup([t_number(), t_identifier(), t_atom(), t_fun(), t_binary()]).
-
--spec t_is_constant(erl_type()) -> boolean().
-
-t_is_constant(X) ->
- t_is_subtype(X, t_constant()).
-
-spec t_arity() -> erl_type().
t_arity() ->
@@ -1987,82 +1843,6 @@ t_parameterized_module() ->
t_timeout() ->
t_sup(t_non_neg_integer(), t_atom('infinity')).
-%%-----------------------------------------------------------------------------
-%% Some built-in opaque types
-%%
-
--spec t_array() -> erl_type().
-
-t_array() ->
- t_opaque(array, array, [t_any()],
- t_tuple([t_atom('array'),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_any(),
- t_any()])).
-
--spec t_dict() -> erl_type().
-
-t_dict() ->
- t_opaque(dict, dict, [t_any(), t_any()],
- t_tuple([t_atom('dict'),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_non_neg_integer()]),
- t_sup([t_atom('undefined'), t_tuple()]),
- t_sup([t_atom('undefined'), t_tuple()])])).
-
--spec t_digraph() -> erl_type().
-
-t_digraph() ->
- t_opaque(digraph, digraph, [],
- t_tuple([t_atom('digraph'),
- t_sup(t_atom(), t_tid()),
- t_sup(t_atom(), t_tid()),
- t_sup(t_atom(), t_tid()),
- t_boolean()])).
-
--spec t_gb_set() -> erl_type().
-
-t_gb_set() ->
- t_opaque(gb_sets, gb_set, [],
- t_tuple([t_non_neg_integer(), t_sup(t_atom('nil'), t_tuple(3))])).
-
--spec t_gb_tree() -> erl_type().
-
-t_gb_tree() ->
- t_opaque(gb_trees, gb_tree, [],
- t_tuple([t_non_neg_integer(), t_sup(t_atom('nil'), t_tuple(4))])).
-
--spec t_queue() -> erl_type().
-
-t_queue() ->
- t_opaque(queue, queue, [t_any()], t_tuple([t_list(), t_list()])).
-
--spec t_set() -> erl_type().
-
-t_set() ->
- t_opaque(sets, set, [t_any()],
- t_tuple([t_atom('set'), t_non_neg_integer(), t_non_neg_integer(),
- t_pos_integer(), t_non_neg_integer(), t_non_neg_integer(),
- t_non_neg_integer(),
- t_sup([t_atom('undefined'), t_tuple()]),
- t_sup([t_atom('undefined'), t_tuple()])])).
-
--spec t_tid() -> erl_type().
-
-t_tid() ->
- t_opaque(ets, tid, [], t_integer()).
-
--spec all_opaque_builtins() -> [erl_type(),...].
-
-all_opaque_builtins() ->
- [t_array(), t_dict(), t_digraph(), t_gb_set(),
- t_gb_tree(), t_queue(), t_set(), t_tid()].
-
%%------------------------------------
%% ?none is allowed in products. A product of size 1 is not a product.
@@ -2357,14 +2137,19 @@ expand_range_from_set(Range = ?int_range(From, To), Set) ->
-spec t_sup([erl_type()]) -> erl_type().
-t_sup([?any|_]) ->
- ?any;
-t_sup([H1, H2|T]) ->
- t_sup([t_sup(H1, H2)|T]);
-t_sup([H]) ->
- subst_all_vars_to_any(H);
-t_sup([]) ->
- ?none.
+t_sup([]) -> ?none;
+t_sup(Ts) ->
+ case lists:any(fun is_any/1, Ts) of
+ true -> ?any;
+ false ->
+ t_sup1(Ts, [])
+ end.
+
+t_sup1([H1, H2|T], L) ->
+ t_sup1(T, [t_sup(H1, H2)|L]);
+t_sup1([T], []) -> subst_all_vars_to_any(T);
+t_sup1(Ts, L) ->
+ t_sup1(Ts++L, []).
-spec t_sup(erl_type(), erl_type()) -> erl_type().
@@ -2832,7 +2617,7 @@ inf_opaque1(T1, ?opaque(Set2)=T2, Pos, Opaques) ->
end.
inf_is_opaque_type(T, Pos, {match, Opaques}) ->
- is_opaque_type(T, Opaques) orelse throw(Pos);
+ is_opaque_type(T, Opaques) orelse throw({pos, [Pos]});
inf_is_opaque_type(T, _Pos, Opaques) ->
is_opaque_type(T, Opaques).
@@ -2850,28 +2635,32 @@ inf_collect(_T1, [], _Opaques, OpL) ->
combine(S, T1, T2) ->
#opaque{mod = Mod1, name = Name1, args = Args1} = T1,
#opaque{mod = Mod2, name = Name2, args = Args2} = T2,
- case is_same_type_name({Mod1, Name1, Args1}, {Mod2, Name2, Args2}) of
- true -> [comb(Mod1, Name1, Args1, S, T1)];
- false -> [comb(Mod1, Name1, Args1, S, T1), comb(Mod2, Name2, Args2, S, T2)]
+ Comb1 = comb(Mod1, Name1, Args1, S, T1),
+ case is_compat_opaque_names({Mod1, Name1, Args1}, {Mod2, Name2, Args2}) of
+ true -> Comb1;
+ false -> Comb1 ++ comb(Mod2, Name2, Args2, S, T2)
end.
comb(Mod, Name, Args, S, T) ->
- case is_same_name(Mod, Name, Args, S) of
- true -> S;
- false -> T#opaque{struct = S}
+ case can_combine_opaque_names(Mod, Name, Args, S) of
+ true ->
+ ?opaque(Set) = S,
+ Set;
+ false ->
+ [T#opaque{struct = S}]
end.
-is_same_name(Mod1, Name1, Args1,
- ?opaque([#opaque{mod = Mod2, name = Name2, args = Args2}])) ->
- is_same_type_name({Mod1, Name1, Args1}, {Mod2, Name2, Args2});
-is_same_name(_, _, _, _) -> false.
+can_combine_opaque_names(Mod1, Name1, Args1,
+ ?opaque([#opaque{mod = Mod2, name = Name2, args = Args2}])) ->
+ is_compat_opaque_names({Mod1, Name1, Args1}, {Mod2, Name2, Args2});
+can_combine_opaque_names(_, _, _, _) -> false.
%% Combining two lists this way can be very time consuming...
%% Note: two parameterized opaque types are not the same if their
%% actual parameters differ
inf_opaque(Set1, Set2, Opaques) ->
- List1 = inf_look_up(Set1, 1, Opaques),
- List2 = inf_look_up(Set2, 2, Opaques),
+ List1 = inf_look_up(Set1, Opaques),
+ List2 = inf_look_up(Set2, Opaques),
List0 = [combine(Inf, T1, T2) ||
{Is1, ModNameArgs1, T1} <- List1,
{Is2, ModNameArgs2, T2} <- List2,
@@ -2882,14 +2671,14 @@ inf_opaque(Set1, Set2, Opaques) ->
sup_opaque(List).
%% Optimization: do just one lookup.
-inf_look_up(Set, Pos, Opaques) ->
- [{Opaques =:= 'universe' orelse inf_is_opaque_type2(T, Pos, Opaques),
+inf_look_up(Set, Opaques) ->
+ [{Opaques =:= 'universe' orelse inf_is_opaque_type2(T, Opaques),
{M, N, Args}, T} ||
#opaque{mod = M, name = N, args = Args} = T <- set_to_list(Set)].
-inf_is_opaque_type2(T, Pos, {match, Opaques}) ->
- is_opaque_type2(T, Opaques) orelse throw(Pos);
-inf_is_opaque_type2(T, _Pos, Opaques) ->
+inf_is_opaque_type2(T, {match, Opaques}) ->
+ is_opaque_type2(T, Opaques);
+inf_is_opaque_type2(T, Opaques) ->
is_opaque_type2(T, Opaques).
inf_opaque_types(IsOpaque1, ModNameArgs1, T1,
@@ -2898,18 +2687,119 @@ inf_opaque_types(IsOpaque1, ModNameArgs1, T1,
#opaque{struct = S2}=T2,
case
Opaques =:= 'universe' orelse
- is_same_type_name(ModNameArgs1, ModNameArgs2)
+ is_compat_opaque_names(ModNameArgs1, ModNameArgs2)
of
true -> t_inf(S1, S2, Opaques);
false ->
case {IsOpaque1, IsOpaque2} of
- {true, true} -> t_inf(S1, S2, Opaques);
- {true, false} -> t_inf(S1, ?opaque(set_singleton(T2)), Opaques);
- {false, true} -> t_inf(?opaque(set_singleton(T1)), S2, Opaques);
+ {true, true} -> t_inf(S1, S2, Opaques);
+ {true, false} -> t_inf(S1, ?opaque(set_singleton(T2)), Opaques);
+ {false, true} -> t_inf(?opaque(set_singleton(T1)), S2, Opaques);
+ {false, false} when element(1, Opaques) =:= match ->
+ throw({pos, [1, 2]});
{false, false} -> t_none()
end
end.
+is_compat_opaque_names(ModNameArgs, ModNameArgs) -> true;
+is_compat_opaque_names({Mod,Name,Args1}, {Mod,Name,Args2}) ->
+ is_compat_args(Args1, Args2);
+is_compat_opaque_names(_, _) -> false.
+
+is_compat_args([A1|Args1], [A2|Args2]) ->
+ is_compat_arg(A1, A2) andalso is_compat_args(Args1, Args2);
+is_compat_args([], []) -> true;
+is_compat_args(_, _) -> false.
+
+is_compat_arg(A1, A2) ->
+ is_specialization(A1, A2) orelse is_specialization(A2, A1).
+
+-spec is_specialization(erl_type(), erl_type()) -> boolean().
+
+%% Returns true if the first argument is a specialization of the
+%% second argument in the sense that every type is a specialization of
+%% any(). For example, {_,_} is a specialization of any(), but not of
+%% tuple(). Does not handle variables, but any() and unions (sort of).
+
+is_specialization(T, T) -> true;
+is_specialization(_, ?any) -> true;
+is_specialization(?any, _) -> false;
+is_specialization(?function(Domain1, Range1), ?function(Domain2, Range2)) ->
+ (is_specialization(Domain1, Domain2) andalso
+ is_specialization(Range1, Range2));
+is_specialization(?list(Contents1, Termination1, Size1),
+ ?list(Contents2, Termination2, Size2)) ->
+ (Size1 =:= Size2 andalso
+ is_specialization(Contents1, Contents2) andalso
+ is_specialization(Termination1, Termination2));
+is_specialization(?product(Types1), ?product(Types2)) ->
+ specialization_list(Types1, Types2);
+is_specialization(?tuple(?any, ?any, ?any), ?tuple(_, _, _)) -> false;
+is_specialization(?tuple(_, _, _), ?tuple(?any, ?any, ?any)) -> false;
+is_specialization(?tuple(Elements1, Arity, _),
+ ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
+ specialization_list(Elements1, Elements2);
+is_specialization(?tuple_set([{Arity, List}]),
+ ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
+ specialization_list(sup_tuple_elements(List), Elements2);
+is_specialization(?tuple(Elements1, Arity, _),
+ ?tuple_set([{Arity, List}])) when Arity =/= ?any ->
+ specialization_list(Elements1, sup_tuple_elements(List));
+is_specialization(?tuple_set(List1), ?tuple_set(List2)) ->
+ try
+ specialization_list_list([sup_tuple_elements(T) || {_Arity, T} <- List1],
+ [sup_tuple_elements(T) || {_Arity, T} <- List2])
+ catch _:_ -> false
+ end;
+is_specialization(?union(List1)=T1, ?union(List2)=T2) ->
+ case specialization_union2(T1, T2) of
+ {yes, Type1, Type2} -> is_specialization(Type1, Type2);
+ no -> specialization_list(List1, List2)
+ end;
+is_specialization(?union(List), T2) ->
+ case unify_union(List) of
+ {yes, Type} -> is_specialization(Type, T2);
+ no -> false
+ end;
+is_specialization(T1, ?union(List)) ->
+ case unify_union(List) of
+ {yes, Type} -> is_specialization(T1, Type);
+ no -> false
+ end;
+is_specialization(?opaque(_) = T1, T2) ->
+ is_specialization(t_opaque_structure(T1), T2);
+is_specialization(T1, ?opaque(_) = T2) ->
+ is_specialization(T1, t_opaque_structure(T2));
+is_specialization(?var(_), _) -> exit(error);
+is_specialization(_, ?var(_)) -> exit(error);
+is_specialization(?none, _) -> false;
+is_specialization(_, ?none) -> false;
+is_specialization(?unit, _) -> false;
+is_specialization(_, ?unit) -> false;
+is_specialization(#c{}, #c{}) -> false.
+
+specialization_list_list(LL1, LL2) ->
+ length(LL1) =:= length(LL2) andalso specialization_list_list1(LL1, LL2).
+
+specialization_list_list1([], []) -> true;
+specialization_list_list1([L1|LL1], [L2|LL2]) ->
+ specialization_list(L1, L2) andalso specialization_list_list1(LL1, LL2).
+
+specialization_list(L1, L2) ->
+ length(L1) =:= length(L2) andalso specialization_list1(L1, L2).
+
+specialization_list1([], []) -> true;
+specialization_list1([T1|L1], [T2|L2]) ->
+ is_specialization(T1, T2) andalso specialization_list1(L1, L2).
+
+specialization_union2(?union(List1)=T1, ?union(List2)=T2) ->
+ case {unify_union(List1), unify_union(List2)} of
+ {{yes, Type1}, {yes, Type2}} -> {yes, Type1, Type2};
+ {{yes, Type1}, no} -> {yes, Type1, T2};
+ {no, {yes, Type2}} -> {yes, T1, Type2};
+ {no, no} -> no
+ end.
+
-spec t_inf_lists([erl_type()], [erl_type()]) -> [erl_type()].
t_inf_lists(L1, L2) ->
@@ -3008,7 +2898,7 @@ inf_union(U1, U2, Opaques) ->
{Union, ThrowList3} = inf_union(U1, U2, 0, [], [], Opaques),
ThrowList = lists:merge3(ThrowList1, ThrowList2, ThrowList3),
case t_sup([O1, O2, Union]) of
- ?none when ThrowList =/= [] -> throw(hd(ThrowList));
+ ?none when ThrowList =/= [] -> throw({pos, lists:usort(ThrowList)});
Sup -> Sup
end.
@@ -3020,8 +2910,8 @@ inf_union_collect([E|L], Opaque, InfFun, InfList, ThrowList) ->
try InfFun(E, Opaque)of
Inf ->
inf_union_collect(L, Opaque, InfFun, [Inf|InfList], ThrowList)
- catch throw:N when is_integer(N) ->
- inf_union_collect(L, Opaque, InfFun, InfList, [N|ThrowList])
+ catch throw:{pos, Ns} ->
+ inf_union_collect(L, Opaque, InfFun, InfList, Ns ++ ThrowList)
end.
inf_union([?none|Left1], [?none|Left2], N, Acc, ThrowList, Opaques) ->
@@ -3030,8 +2920,8 @@ inf_union([T1|Left1], [T2|Left2], N, Acc, ThrowList, Opaques) ->
try t_inf(T1, T2, Opaques) of
?none -> inf_union(Left1, Left2, N, [?none|Acc], ThrowList, Opaques);
T -> inf_union(Left1, Left2, N+1, [T|Acc], ThrowList, Opaques)
- catch throw:N when is_integer(N) ->
- inf_union(Left1, Left2, N, [?none|Acc], [N|ThrowList], Opaques)
+ catch throw:{pos, Ns} ->
+ inf_union(Left1, Left2, N, [?none|Acc], Ns ++ ThrowList, Opaques)
end;
inf_union([], [], N, Acc, ThrowList, _Opaques) ->
if N =:= 0 -> {?none, ThrowList};
@@ -3182,12 +3072,12 @@ t_subst_aux(T, _VarMap) ->
subst_all_remote(Type0, Substitute) ->
Map =
fun(Type) ->
- case erl_types:t_is_remote(Type) of
+ case t_is_remote(Type) of
true -> Substitute;
false -> Type
end
end,
- erl_types:t_map(Map, Type0).
+ t_map(Map, Type0).
%%-----------------------------------------------------------------------------
%% Unification
@@ -3317,8 +3207,8 @@ is_opaque_type2(#opaque{mod = Mod1, name = Name1, args = Args1}, Opaques) ->
is_type_name(Mod, Name, Args1, Mod, Name, Args2) ->
length(Args1) =:= length(Args2);
-is_type_name(Mod1, Name1, Args1, Mod2, Name2, Args2) ->
- is_same_type_name2(Mod1, Name1, Args1, Mod2, Name2, Args2).
+is_type_name(_Mod1, _Name1, _Args1, _Mod2, _Name2, _Args2) ->
+ false.
%% Two functions since t_unify is not symmetric.
unify_tuple_set_and_tuple1(?tuple_set([{Arity, List}]),
@@ -3869,7 +3759,7 @@ t_abstract_records(?tuple(Elements, Arity, ?atom(_) = Tag), RecDict) ->
[TagAtom] = atom_vals(Tag),
case lookup_record(TagAtom, Arity - 1, RecDict) of
error -> t_tuple([t_abstract_records(E, RecDict) || E <- Elements]);
- {ok, Fields} -> t_tuple([Tag|[T || {_Name, T} <- Fields]])
+ {ok, Fields} -> t_tuple([Tag|[T || {_Name, _Abstr, T} <- Fields]])
end;
t_abstract_records(?tuple(Elements, _Arity, _Tag), RecDict) ->
t_tuple([t_abstract_records(E, RecDict) || E <- Elements]);
@@ -4090,7 +3980,8 @@ record_to_string(Tag, [_|Fields], FieldNames, RecDict) ->
FieldStrings = record_fields_to_string(Fields, FieldNames, RecDict, []),
"#" ++ atom_to_string(Tag) ++ "{" ++ string:join(FieldStrings, ",") ++ "}".
-record_fields_to_string([F|Fs], [{FName, _DefType}|FDefs], RecDict, Acc) ->
+record_fields_to_string([F|Fs], [{FName, _Abstr, _DefType}|FDefs],
+ RecDict, Acc) ->
NewAcc =
case t_is_equal(F, t_any()) orelse t_is_any_atom('undefined', F) of
true -> Acc;
@@ -4116,7 +4007,7 @@ record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) ->
FieldDiffs = field_diffs(Fs, FieldNames, RecDict, []),
string:join(FieldDiffs, " and ").
-field_diffs([F|Fs], [{FName, DefType}|FDefs], RecDict, Acc) ->
+field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], RecDict, Acc) ->
%% Don't care about opaqueness for now.
NewAcc =
case not t_is_none(t_inf(F, DefType)) of
@@ -4156,15 +4047,7 @@ opaque_name(Mod, Name, Extra) ->
flat_format("~s(~s)", [S, Extra]).
mod_name(Mod, Name) ->
- case is_obsolete_opaque_builtin(Mod, Name) of
- true -> flat_format("~w", [Name]);
- false -> flat_format("~w:~w", [Mod, Name])
- end.
-
-is_obsolete_opaque_builtin(digraph, digraph) -> true;
-is_obsolete_opaque_builtin(gb_sets, gb_set) -> true;
-is_obsolete_opaque_builtin(gb_trees, gb_tree) -> true;
-is_obsolete_opaque_builtin(_, _) -> false.
+ flat_format("~w:~w", [Mod, Name]).
%%=============================================================================
%%
@@ -4172,374 +4055,581 @@ is_obsolete_opaque_builtin(_, _) -> false.
%%
%%=============================================================================
--spec t_from_form(parse_form()) -> erl_type().
+-type type_names() :: [type_key() | record_key()].
-t_from_form(Form) ->
- t_from_form(Form, dict:new()).
+-type mta() :: {module(), atom(), arity()}.
+-type mra() :: {module(), atom(), arity()}.
+-type site() :: {'type', mta()} | {'spec', mfa()} | {'record', mra()}.
--spec t_from_form(parse_form(), type_table()) -> erl_type().
+-spec t_from_form(parse_form(), sets:set(mfa()),
+ site(), mod_records()) -> erl_type().
-t_from_form(Form, RecDict) ->
- t_from_form(Form, RecDict, dict:new()).
+t_from_form(Form, ExpTypes, Site, RecDict) ->
+ t_from_form(Form, ExpTypes, Site, RecDict, dict:new()).
--spec t_from_form(parse_form(), type_table(), var_table()) -> erl_type().
+-spec t_from_form(parse_form(), sets:set(mfa()),
+ site(), mod_records(), var_table()) -> erl_type().
-t_from_form(Form, RecDict, VarDict) ->
- {T, _R} = t_from_form(Form, [], RecDict, VarDict),
+t_from_form(Form, ExpTypes, Site, RecDict, VarDict) ->
+ {T, _} = t_from_form1(Form, ExpTypes, Site, RecDict, VarDict),
T.
--type type_names() :: [type_key() | record_key()].
+%% Replace external types with with none().
+-spec t_from_form_without_remote(parse_form(), site(), type_table()) ->
+ erl_type().
+
+t_from_form_without_remote(Form, Site, TypeTable) ->
+ Module = site_module(Site),
+ RecDict = dict:from_list([{Module, TypeTable}]),
+ ExpTypes = replace_by_none,
+ {T, _} = t_from_form1(Form, ExpTypes, Site, RecDict, dict:new()),
+ T.
+
+%% REC_TYPE_LIMIT is used for limiting the depth of recursive types.
+%% EXPAND_LIMIT is used for limiting the size of types by
+%% limiting the number of elements of lists within one type form.
+%% EXPAND_DEPTH is used in conjunction with EXPAND_LIMIT to make the
+%% types balanced (unions will otherwise collapse to any()) by limiting
+%% the depth the same way as t_limit/2 does.
+
+-type expand_limit() :: integer().
+
+-type expand_depth() :: integer().
+
+-spec t_from_form1(parse_form(), sets:set(mfa()) | 'replace_by_none',
+ site(), mod_records(), var_table()) ->
+ {erl_type(), expand_limit()}.
--spec t_from_form(parse_form(), type_names(), type_table(), var_table()) ->
- {erl_type(), type_names()}.
+t_from_form1(Form, ET, Site, MR, V) ->
+ TypeNames = initial_typenames(Site),
+ t_from_form1(Form, TypeNames, ET, Site, MR, V, ?EXPAND_DEPTH).
-t_from_form({var, _L, '_'}, _TypeNames, _RecDict, _VarDict) ->
- {t_any(), []};
-t_from_form({var, _L, Name}, _TypeNames, _RecDict, VarDict) ->
- case dict:find(Name, VarDict) of
- error -> {t_var(Name), []};
- {ok, Val} -> {Val, []}
+initial_typenames({type, _MTA}=Site) -> [Site];
+initial_typenames({spec, _MFA}) -> [];
+initial_typenames({record, _MRA}) -> [].
+
+t_from_form1(Form, TypeNames, ET, Site, MR, V, D) ->
+ L = ?EXPAND_LIMIT,
+ {T, L1} = t_from_form(Form, TypeNames, ET, Site, MR, V, D, L),
+ if
+ L1 =< 0, D > 1 ->
+ D1 = D div 2,
+ t_from_form1(Form, TypeNames, ET, Site, MR, V, D1);
+ true ->
+ {T, L1}
+ end.
+
+-spec t_from_form(parse_form(), type_names(),
+ sets:set(mfa()) | 'replace_by_none',
+ site(), mod_records(), var_table(),
+ expand_depth(), expand_limit())
+ -> {erl_type(), expand_limit()}.
+
+%% If there is something wrong with parse_form()
+%% throw({error, io_lib:chars()} is called;
+%% for unknown remote types
+%% self() ! {self(), ext_types, {RemMod, Name, ArgsLen}}
+%% is called, unless 'replace_by_none' is given.
+%%
+%% It is assumed that site_module(S) can be found in MR.
+
+t_from_form(_, _TypeNames, _ET, _S, _MR, _V, D, L) when D =< 0 ; L =< 0 ->
+ {t_any(), L};
+t_from_form({var, _L, '_'}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_any(), L};
+t_from_form({var, _L, Name}, _TypeNames, _ET, _S, _MR, V, _D, L) ->
+ case dict:find(Name, V) of
+ error -> {t_var(Name), L};
+ {ok, Val} -> {Val, L}
end;
-t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, RecDict, VarDict) ->
- t_from_form(Type, TypeNames, RecDict, VarDict);
-t_from_form({paren_type, _L, [Type]}, TypeNames, RecDict, VarDict) ->
- t_from_form(Type, TypeNames, RecDict, VarDict);
+t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, ET, S, MR, V, D, L) ->
+ t_from_form(Type, TypeNames, ET, S, MR, V, D, L);
+t_from_form({paren_type, _L, [Type]}, TypeNames, ET, S, MR, V, D, L) ->
+ t_from_form(Type, TypeNames, ET, S, MR, V, D, L);
t_from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]},
- TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
- {t_remote(Module, Type, L), R};
-t_from_form({atom, _L, Atom}, _TypeNames, _RecDict, _VarDict) ->
- {t_atom(Atom), []};
-t_from_form({integer, _L, Int}, _TypeNames, _RecDict, _VarDict) ->
- {t_integer(Int), []};
-t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _RecDict, _VarDict) ->
+ TypeNames, ET, S, MR, V, D, L) ->
+ remote_from_form(Module, Type, Args, TypeNames, ET, S, MR, V, D, L);
+t_from_form({atom, _L, Atom}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_atom(Atom), L};
+t_from_form({integer, _L, Int}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_integer(Int), L};
+t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
case erl_eval:partial_eval(Op) of
{integer, _, Val} ->
- {t_integer(Val), []};
+ {t_integer(Val), L};
_ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
end;
t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames,
- _RecDict, _VarDict) ->
+ _ET, _S, _MR, _V, _D, L) ->
case erl_eval:partial_eval(Op) of
{integer, _, Val} ->
- {t_integer(Val), []};
+ {t_integer(Val), L};
_ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
end;
-t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_any(), []};
-t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_arity(), []};
-t_from_form({type, _L, array, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(array, t_array(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_atom(), []};
-t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_binary(), []};
+t_from_form({type, _L, any, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_any(), L};
+t_from_form({type, _L, arity, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_arity(), L};
+t_from_form({type, _L, atom, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_atom(), L};
+t_from_form({type, _L, binary, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_binary(), L};
t_from_form({type, _L, binary, [Base, Unit]} = Type,
- _TypeNames, _RecDict, _VarDict) ->
+ _TypeNames, _ET, _S, _MR, _V, _D, L) ->
case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of
{{integer, _, B}, {integer, _, U}} when B >= 0, U >= 0 ->
- {t_bitstr(U, B), []};
+ {t_bitstr(U, B), L};
_ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
end;
-t_from_form({type, _L, bitstring, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_bitstr(), []};
-t_from_form({type, _L, bool, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_boolean(), []}; % XXX: Temporarily
-t_from_form({type, _L, boolean, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_boolean(), []};
-t_from_form({type, _L, byte, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_byte(), []};
-t_from_form({type, _L, char, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_char(), []};
-t_from_form({type, _L, dict, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(dict, t_dict(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, digraph, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(digraph, t_digraph(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, float, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_float(), []};
-t_from_form({type, _L, function, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_fun(), []};
-t_from_form({type, _L, 'fun', []}, _TypeNames, _RecDict, _VarDict) ->
- {t_fun(), []};
+t_from_form({type, _L, bitstring, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_bitstr(), L};
+t_from_form({type, _L, bool, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_boolean(), L}; % XXX: Temporarily
+t_from_form({type, _L, boolean, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_boolean(), L};
+t_from_form({type, _L, byte, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_byte(), L};
+t_from_form({type, _L, char, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_char(), L};
+t_from_form({type, _L, float, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_float(), L};
+t_from_form({type, _L, function, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_fun(), L};
+t_from_form({type, _L, 'fun', []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_fun(), L};
t_from_form({type, _L, 'fun', [{type, _, any}, Range]}, TypeNames,
- RecDict, VarDict) ->
- {T, R} = t_from_form(Range, TypeNames, RecDict, VarDict),
- {t_fun(T), R};
+ ET, S, MR, V, D, L) ->
+ {T, L1} = t_from_form(Range, TypeNames, ET, S, MR, V, D - 1, L - 1),
+ {t_fun(T), L1};
t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
- TypeNames, RecDict, VarDict) ->
- {L, R1} = list_from_form(Domain, TypeNames, RecDict, VarDict),
- {T, R2} = t_from_form(Range, TypeNames, RecDict, VarDict),
- {t_fun(L, T), R1 ++ R2};
-t_from_form({type, _L, gb_set, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(gb_set, t_gb_set(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, gb_tree, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(gb_tree, t_gb_tree(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, identifier, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_identifier(), []};
-t_from_form({type, _L, integer, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_integer(), []};
-t_from_form({type, _L, iodata, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_iodata(), []};
-t_from_form({type, _L, iolist, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_iolist(), []};
-t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_list(), []};
-t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) ->
- {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
- {t_list(T), R};
-t_from_form({type, _L, map, As0}, TypeNames, RecDict, VarDict) ->
- As = case is_list(As0) of
- true -> As0;
- false -> []
- end,
- builtin_type(map, t_map([]), As, TypeNames, RecDict, VarDict);
-t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_mfa(), []};
-t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_module(), []};
-t_from_form({type, _L, nil, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_nil(), []};
-t_from_form({type, _L, neg_integer, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_neg_integer(), []};
-t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _RecDict,
- _VarDict) ->
- {t_non_neg_integer(), []};
-t_from_form({type, _L, no_return, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_unit(), []};
-t_from_form({type, _L, node, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_node(), []};
-t_from_form({type, _L, none, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_none(), []};
-t_from_form({type, _L, nonempty_list, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_nonempty_list(), []};
-t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, RecDict, VarDict) ->
- {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
- {t_nonempty_list(T), R};
+ TypeNames, ET, S, MR, V, D, L) ->
+ {Dom1, L1} = list_from_form(Domain, TypeNames, ET, S, MR, V, D, L),
+ {Ran1, L2} = t_from_form(Range, TypeNames, ET, S, MR, V, D - 1, L1),
+ {t_fun(Dom1, Ran1), L2};
+t_from_form({type, _L, identifier, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_identifier(), L};
+t_from_form({type, _L, integer, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_integer(), L};
+t_from_form({type, _L, iodata, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_iodata(), L};
+t_from_form({type, _L, iolist, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_iolist(), L};
+t_from_form({type, _L, list, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_list(), L};
+t_from_form({type, _L, list, [Type]}, TypeNames, ET, S, MR, V, D, L) ->
+ {T, L1} = t_from_form(Type, TypeNames, ET, S, MR, V, D - 1, L - 1),
+ {t_list(T), L1};
+t_from_form({type, _L, map, _}, TypeNames, ET, S, MR, V, D, L) ->
+ builtin_type(map, t_map([]), TypeNames, ET, S, MR, V, D, L);
+t_from_form({type, _L, mfa, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_mfa(), L};
+t_from_form({type, _L, module, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_module(), L};
+t_from_form({type, _L, nil, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_nil(), L};
+t_from_form({type, _L, neg_integer, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_neg_integer(), L};
+t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _ET, _S, _MR,
+ _V, _D, L) ->
+ {t_non_neg_integer(), L};
+t_from_form({type, _L, no_return, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_unit(), L};
+t_from_form({type, _L, node, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_node(), L};
+t_from_form({type, _L, none, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_none(), L};
+t_from_form({type, _L, nonempty_list, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_nonempty_list(), L};
+t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, ET, S, MR, V, D, L) ->
+ {T, L1} = t_from_form(Type, TypeNames, ET, S, MR, V, D, L - 1),
+ {t_nonempty_list(T), L1};
t_from_form({type, _L, nonempty_improper_list, [Cont, Term]}, TypeNames,
- RecDict, VarDict) ->
- {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict),
- {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict),
- {t_cons(T1, T2), R1 ++ R2};
+ ET, S, MR, V, D, L) ->
+ {T1, L1} = t_from_form(Cont, TypeNames, ET, S, MR, V, D, L - 1),
+ {T2, L2} = t_from_form(Term, TypeNames, ET, S, MR, V, D, L1),
+ {t_cons(T1, T2), L2};
t_from_form({type, _L, nonempty_maybe_improper_list, []}, _TypeNames,
- _RecDict, _VarDict) ->
- {t_cons(?any, ?any), []};
+ _ET, _S, _MR, _V, _D, L) ->
+ {t_cons(?any, ?any), L};
t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]},
- TypeNames, RecDict, VarDict) ->
- {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict),
- {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict),
- {t_cons(T1, T2), R1 ++ R2};
-t_from_form({type, _L, nonempty_string, []}, _TypeNames, _RecDict,
- _VarDict) ->
- {t_nonempty_string(), []};
-t_from_form({type, _L, number, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_number(), []};
-t_from_form({type, _L, pid, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_pid(), []};
-t_from_form({type, _L, port, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_port(), []};
-t_from_form({type, _L, pos_integer, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_pos_integer(), []};
+ TypeNames, ET, S, MR, V, D, L) ->
+ {T1, L1} = t_from_form(Cont, TypeNames, ET, S, MR, V, D, L - 1),
+ {T2, L2} = t_from_form(Term, TypeNames, ET, S, MR, V, D, L1),
+ {t_cons(T1, T2), L2};
+t_from_form({type, _L, nonempty_string, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_nonempty_string(), L};
+t_from_form({type, _L, number, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_number(), L};
+t_from_form({type, _L, pid, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_pid(), L};
+t_from_form({type, _L, port, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_port(), L};
+t_from_form({type, _L, pos_integer, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_pos_integer(), L};
t_from_form({type, _L, maybe_improper_list, []}, _TypeNames,
- _RecDict, _VarDict) ->
- {t_maybe_improper_list(), []};
+ _ET, _S, _MR, _V, _D, L) ->
+ {t_maybe_improper_list(), L};
t_from_form({type, _L, maybe_improper_list, [Content, Termination]},
- TypeNames, RecDict, VarDict) ->
- {T1, R1} = t_from_form(Content, TypeNames, RecDict, VarDict),
- {T2, R2} = t_from_form(Termination, TypeNames, RecDict, VarDict),
- {t_maybe_improper_list(T1, T2), R1 ++ R2};
-t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Elements, TypeNames, RecDict, VarDict),
- {t_product(L), R};
-t_from_form({type, _L, queue, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(queue, t_queue(), [], TypeNames, RecDict, VarDict);
+ TypeNames, ET, S, MR, V, D, L) ->
+ {T1, L1} = t_from_form(Content, TypeNames, ET, S, MR, V, D, L - 1),
+ {T2, L2} = t_from_form(Termination, TypeNames, ET, S, MR, V, D, L1),
+ {t_maybe_improper_list(T1, T2), L2};
+t_from_form({type, _L, product, Elements}, TypeNames, ET, S, MR, V, D, L) ->
+ {Lst, L1} = list_from_form(Elements, TypeNames, ET, S, MR, V, D - 1, L),
+ {t_product(Lst), L1};
t_from_form({type, _L, range, [From, To]} = Type,
- _TypeNames, _RecDict, _VarDict) ->
+ _TypeNames, _ET, _S, _MR, _V, _D, L) ->
case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
{{integer, _, FromVal}, {integer, _, ToVal}} ->
- {t_from_range(FromVal, ToVal), []};
+ {t_from_range(FromVal, ToVal), L};
_ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
end;
-t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) ->
- record_from_form(Name, Fields, TypeNames, RecDict, VarDict);
-t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_reference(), []};
-t_from_form({type, _L, set, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(set, t_set(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, string, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_string(), []};
-t_from_form({type, _L, term, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_any(), []};
-t_from_form({type, _L, tid, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(tid, t_tid(), [], TypeNames, RecDict, VarDict);
-t_from_form({type, _L, timeout, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_timeout(), []};
-t_from_form({type, _L, tuple, any}, _TypeNames, _RecDict, _VarDict) ->
- {t_tuple(), []};
-t_from_form({type, _L, tuple, Args}, TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
- {t_tuple(L), R};
-t_from_form({type, _L, union, Args}, TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
- {t_sup(L), R};
-t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) ->
- type_from_form(Name, Args, TypeNames, RecDict, VarDict);
+t_from_form({type, _L, record, [Name|Fields]}, TypeNames, ET, S, MR, V, D, L) ->
+ record_from_form(Name, Fields, TypeNames, ET, S, MR, V, D, L);
+t_from_form({type, _L, reference, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_reference(), L};
+t_from_form({type, _L, string, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_string(), L};
+t_from_form({type, _L, term, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_any(), L};
+t_from_form({type, _L, timeout, []}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_timeout(), L};
+t_from_form({type, _L, tuple, any}, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {t_tuple(), L};
+t_from_form({type, _L, tuple, Args}, TypeNames, ET, S, MR, V, D, L) ->
+ {Lst, L1} = list_from_form(Args, TypeNames, ET, S, MR, V, D - 1, L),
+ {t_tuple(Lst), L1};
+t_from_form({type, _L, union, Args}, TypeNames, ET, S, MR, V, D, L) ->
+ {Lst, L1} = list_from_form(Args, TypeNames, ET, S, MR, V, D, L),
+ {t_sup(Lst), L1};
+t_from_form({user_type, _L, Name, Args}, TypeNames, ET, S, MR, V, D, L) ->
+ type_from_form(Name, Args, TypeNames, ET, S, MR, V, D, L);
+t_from_form({type, _L, Name, Args}, TypeNames, ET, S, MR, V, D, L) ->
+ %% Compatibility: modules compiled before Erlang/OTP 18.0.
+ type_from_form(Name, Args, TypeNames, ET, S, MR, V, D, L);
t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames,
- _RecDict, _VarDict) ->
- {t_opaque(Mod, Name, Args, Rep), []}.
-
-builtin_type(Name, Type, Args, TypeNames, RecDict, VarDict) ->
- case lookup_type(Name, length(Args), RecDict) of
- {_, {_M, _T, _A}} ->
- type_from_form(Name, Args, TypeNames, RecDict, VarDict);
+ _ET, _S, _MR, _V, _D, L) ->
+ %% XXX. To be removed.
+ {t_opaque(Mod, Name, Args, Rep), L}.
+
+builtin_type(Name, Type, TypeNames, ET, Site, MR, V, D, L) ->
+ M = site_module(Site),
+ case dict:find(M, MR) of
+ {ok, R} ->
+ case lookup_type(Name, 0, R) of
+ {_, {{_M, _FL, _F, _A}, _T}} ->
+ type_from_form(Name, [], TypeNames, ET, Site, MR, V, D, L);
+ error ->
+ {Type, L}
+ end;
error ->
- {Type, []}
+ {Type, L}
end.
-type_from_form(Name, Args, TypeNames, RecDict, VarDict) ->
+type_from_form(Name, Args, TypeNames, ET, Site0, MR, V, D, L) ->
ArgsLen = length(Args),
- ArgTypes = forms_to_types(Args, TypeNames, RecDict, VarDict),
- case lookup_type(Name, ArgsLen, RecDict) of
- {type, {_Module, Type, ArgNames}} ->
- TypeName = {type, Name, ArgsLen},
+ Module = site_module(Site0),
+ {ok, R} = dict:find(Module, MR),
+ TypeName = {type, {Module, Name, ArgsLen}},
+ case lookup_type(Name, ArgsLen, R) of
+ {type, {{Module, _FileName, Form, ArgNames}, _Type}} ->
case can_unfold_more(TypeName, TypeNames) of
true ->
+ NewTypeNames = [TypeName|TypeNames],
+ {ArgTypes, L1} =
+ list_from_form(Args, TypeNames, ET, Site0, MR, V, D, L),
List = lists:zip(ArgNames, ArgTypes),
- TmpVarDict = dict:from_list(List),
- {T, R} = t_from_form(Type, [TypeName|TypeNames],
- RecDict, TmpVarDict),
- case lists:member(TypeName, R) of
- true -> {t_limit(T, ?REC_TYPE_LIMIT), R};
- false -> {T, R}
- end;
- false -> {t_any(), [TypeName]}
+ TmpV = dict:from_list(List),
+ Site = TypeName,
+ t_from_form(Form, NewTypeNames, ET, Site, MR, TmpV, D, L1);
+ false ->
+ {t_any(), L}
+ end;
+ {opaque, {{Module, _FileName, Form, ArgNames}, Type}} ->
+ case can_unfold_more(TypeName, TypeNames) of
+ true ->
+ NewTypeNames = [TypeName|TypeNames],
+ {ArgTypes, L1} =
+ list_from_form(Args, NewTypeNames, ET, Site0, MR, V, D, L),
+ List = lists:zip(ArgNames, ArgTypes),
+ TmpV = dict:from_list(List),
+ Site = TypeName,
+ {Rep, L2} =
+ t_from_form(Form, NewTypeNames, ET, Site, MR, TmpV, D, L1),
+ Rep1 = choose_opaque_type(Rep, Type),
+ Rep2 = case cannot_have_opaque(Rep1, TypeName, TypeNames) of
+ true -> Rep1;
+ false ->
+ ArgTypes2 = subst_all_vars_to_any_list(ArgTypes),
+ t_opaque(Module, Name, ArgTypes2, Rep1)
+ end,
+ {Rep2, L2};
+ false -> {t_any(), L}
end;
- {opaque, {Module, Type, ArgNames}} ->
- TypeName = {opaque, Name, ArgsLen},
- {Rep, Rret} =
- case can_unfold_more(TypeName, TypeNames) of
- true ->
- List = lists:zip(ArgNames, ArgTypes),
- TmpVarDict = dict:from_list(List),
- {T, R} = t_from_form(Type, [TypeName|TypeNames],
- RecDict, TmpVarDict),
- case lists:member(TypeName, R) of
- true -> {t_limit(T, ?REC_TYPE_LIMIT), R};
- false -> {T, R}
- end;
- false -> {t_any(), [TypeName]}
- end,
- Args2 = [subst_all_vars_to_any(ArgType) || ArgType <- ArgTypes],
- {skip_opaque_alias(Rep, Module, Name, Args2), Rret};
error ->
Msg = io_lib:format("Unable to find type ~w/~w\n", [Name, ArgsLen]),
throw({error, Msg})
end.
-forms_to_types(Forms, TypeNames, RecDict, VarDict) ->
- {Types, _} = list_from_form(Forms, TypeNames, RecDict, VarDict),
- Types.
+remote_from_form(RemMod, Name, Args, TypeNames, ET, S, MR, V, D, L) ->
+ if
+ ET =:= replace_by_none ->
+ {t_none(), L};
+ true ->
+ ArgsLen = length(Args),
+ MFA = {RemMod, Name, ArgsLen},
+ case dict:find(RemMod, MR) of
+ error ->
+ self() ! {self(), ext_types, MFA},
+ {t_any(), L};
+ {ok, RemDict} ->
+ RemType = {type, MFA},
+ case sets:is_element(MFA, ET) of
+ true ->
+ case lookup_type(Name, ArgsLen, RemDict) of
+ {type, {{_Mod, _FileLine, Form, ArgNames}, _Type}} ->
+ case can_unfold_more(RemType, TypeNames) of
+ true ->
+ NewTypeNames = [RemType|TypeNames],
+ {ArgTypes, L1} = list_from_form(Args, TypeNames,
+ ET, S, MR, V, D, L),
+ List = lists:zip(ArgNames, ArgTypes),
+ TmpVarDict = dict:from_list(List),
+ Site = RemType,
+ t_from_form(Form, NewTypeNames, ET,
+ Site, MR, TmpVarDict, D, L1);
+ false ->
+ {t_any(), L}
+ end;
+ {opaque, {{Mod, _FileLine, Form, ArgNames}, Type}} ->
+ case can_unfold_more(RemType, TypeNames) of
+ true ->
+ NewTypeNames = [RemType|TypeNames],
+ {ArgTypes, L1} = list_from_form(Args, NewTypeNames,
+ ET, S, MR, V, D, L),
+ List = lists:zip(ArgNames, ArgTypes),
+ TmpVarDict = dict:from_list(List),
+ Site = RemType,
+ {NewRep, L2} =
+ t_from_form(Form, NewTypeNames, ET, Site, MR,
+ TmpVarDict, D, L1),
+ NewRep1 = choose_opaque_type(NewRep, Type),
+ NewRep2 =
+ case
+ cannot_have_opaque(NewRep1, RemType, TypeNames)
+ of
+ true -> NewRep1;
+ false ->
+ ArgTypes2 = subst_all_vars_to_any_list(ArgTypes),
+ t_opaque(Mod, Name, ArgTypes2, NewRep1)
+ end,
+ {NewRep2, L2};
+ false ->
+ {t_any(), L}
+ end;
+ error ->
+ Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
+ [RemMod, Name]),
+ throw({error, Msg})
+ end;
+ false ->
+ self() ! {self(), ext_types, {RemMod, Name, ArgsLen}},
+ {t_any(), L}
+ end
+ end
+ end.
-skip_opaque_alias(?opaque(_) = T, _Mod, _Name, _Args) -> T;
-skip_opaque_alias(T, Module, Name, Args) ->
- t_opaque(Module, Name, Args, T).
+subst_all_vars_to_any_list(Types) ->
+ [subst_all_vars_to_any(Type) || Type <- Types].
-record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) ->
+%% Opaque types (both local and remote) are problematic when it comes
+%% to the limits (TypeNames, D, and L). The reason is that if any() is
+%% substituted for a more specialized subtype of an opaque type, the
+%% property stated along with decorate_with_opaque() (the type has to
+%% be a subtype of the declared type) no longer holds.
+%%
+%% The less than perfect remedy: if the opaque type created from a
+%% form is not a subset of the declared type, the declared type is
+%% used instead, effectively bypassing the limits, and potentially
+%% resulting in huge types.
+choose_opaque_type(Type, DeclType) ->
+ case
+ t_is_subtype(subst_all_vars_to_any(Type),
+ subst_all_vars_to_any(DeclType))
+ of
+ true -> Type;
+ false -> DeclType
+ end.
+
+record_from_form({atom, _, Name}, ModFields, TypeNames, ET, S, MR, V, D, L) ->
case can_unfold_more({record, Name}, TypeNames) of
true ->
- case lookup_record(Name, RecDict) of
+ M = site_module(S),
+ {ok, R} = dict:find(M, MR),
+ case lookup_record(Name, R) of
{ok, DeclFields} ->
- TypeNames1 = [{record, Name}|TypeNames],
- AreTyped = [is_erl_type(FieldType)
- || {_FieldName, FieldType} <- DeclFields],
- {DeclFields1, R1} =
- case lists:all(fun(Elem) -> Elem end, AreTyped) of
- true -> {DeclFields, []};
- false -> fields_from_form(DeclFields, TypeNames1,
- RecDict, dict:new())
- end,
- {GetModRec, R2} = get_mod_record(ModFields, DeclFields1,
- TypeNames1,
- RecDict, VarDict),
+ NewTypeNames = [{record, Name}|TypeNames],
+ S1 = {record, {M, Name, length(DeclFields)}},
+ {GetModRec, L1} = get_mod_record(ModFields, DeclFields,
+ NewTypeNames, ET, S1, MR, V, D, L),
case GetModRec of
{error, FieldName} ->
throw({error, io_lib:format("Illegal declaration of #~w{~w}\n",
[Name, FieldName])});
{ok, NewFields} ->
- {t_tuple(
- [t_atom(Name)|[Type || {_FieldName, Type} <- NewFields]]),
- R1 ++ R2}
+ {NewFields1, L2} =
+ fields_from_form(NewFields, NewTypeNames, ET, S1, MR,
+ dict:new(), D, L1),
+ Rec = t_tuple(
+ [t_atom(Name)|[Type
+ || {_FieldName, Type} <- NewFields1]]),
+ {Rec, L2}
end;
error ->
throw({error, io_lib:format("Unknown record #~w{}\n", [Name])})
end;
- false -> {t_any(), []}
+ false ->
+ {t_any(), L}
end.
-get_mod_record([], DeclFields, _TypeNames, _RecDict, _VarDict) ->
- {{ok, DeclFields}, []};
-get_mod_record(ModFields, DeclFields, TypeNames, RecDict, VarDict) ->
- DeclFieldsDict = orddict:from_list(DeclFields),
- {ModFieldsDict, R} = build_field_dict(ModFields, TypeNames,
- RecDict, VarDict),
- case get_mod_record(DeclFieldsDict, ModFieldsDict, []) of
- {error, _FieldName} = Error -> {Error, R};
- {ok, FinalOrdDict} ->
- {{ok, [{FieldName, orddict:fetch(FieldName, FinalOrdDict)}
- || {FieldName, _} <- DeclFields]},
- R}
+get_mod_record([], DeclFields, _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {{ok, DeclFields}, L};
+get_mod_record(ModFields, DeclFields, TypeNames, ET, S, MR, V, D, L) ->
+ DeclFieldsDict = lists:keysort(1, DeclFields),
+ {ModFieldsDict, L1} =
+ build_field_dict(ModFields, TypeNames, ET, S, MR, V, D, L),
+ case get_mod_record_types(DeclFieldsDict, ModFieldsDict, []) of
+ {error, _FieldName} = Error -> {Error, L1};
+ {ok, FinalKeyDict} ->
+ Fields = [lists:keyfind(FieldName, 1, FinalKeyDict)
+ || {FieldName, _, _} <- DeclFields],
+ {{ok, Fields}, L1}
end.
-build_field_dict(FieldTypes, TypeNames, RecDict, VarDict) ->
- build_field_dict(FieldTypes, TypeNames, RecDict, VarDict, []).
-
-build_field_dict([{type, _, field_type, [{atom, _, Name}, Type]}|Left],
- TypeNames, RecDict, VarDict, Acc) ->
- {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict),
- NewAcc = [{Name, T}|Acc],
- {D, R2} = build_field_dict(Left, TypeNames, RecDict, VarDict, NewAcc),
- {D, R1 ++ R2};
-build_field_dict([], _TypeNames, _RecDict, _VarDict, Acc) ->
- {orddict:from_list(Acc), []}.
-
-get_mod_record([{FieldName, DeclType}|Left1],
- [{FieldName, ModType}|Left2], Acc) ->
- ModTypeNoVars = subst_all_vars_to_any(ModType),
- case
- contains_remote(ModTypeNoVars)
- orelse contains_remote(DeclType)
- orelse t_is_subtype(ModTypeNoVars, DeclType)
- of
- false -> {error, FieldName};
- true -> get_mod_record(Left1, Left2, [{FieldName, ModType}|Acc])
- end;
-get_mod_record([{FieldName1, _DeclType} = DT|Left1],
- [{FieldName2, _ModType}|_] = List2,
- Acc) when FieldName1 < FieldName2 ->
- get_mod_record(Left1, List2, [DT|Acc]);
-get_mod_record(DeclFields, [], Acc) ->
- {ok, orddict:from_list(Acc ++ DeclFields)};
-get_mod_record(_, [{FieldName2, _ModType}|_], _Acc) ->
+build_field_dict(FieldTypes, TypeNames, ET, S, MR, V, D, L) ->
+ build_field_dict(FieldTypes, TypeNames, ET, S, MR, V, D, L, []).
+
+build_field_dict([{type, _, field_type, [{atom, _, Name}, Type]}|Left],
+ TypeNames, ET, S, MR, V, D, L, Acc) ->
+ {T, L1} = t_from_form(Type, TypeNames, ET, S, MR, V, D, L - 1),
+ NewAcc = [{Name, Type, T}|Acc],
+ {Dict, L2} =
+ build_field_dict(Left, TypeNames, ET, S, MR, V, D, L1, NewAcc),
+ {Dict, L2};
+build_field_dict([], _TypeNames, _ET, _S, _MR, _V, _D, L, Acc) ->
+ {lists:keysort(1, Acc), L}.
+
+get_mod_record_types([{FieldName, _Abstr, _DeclType}|Left1],
+ [{FieldName, TypeForm, ModType}|Left2],
+ Acc) ->
+ get_mod_record_types(Left1, Left2, [{FieldName, TypeForm, ModType}|Acc]);
+get_mod_record_types([{FieldName1, _Abstr, _DeclType} = DT|Left1],
+ [{FieldName2, _FormType, _ModType}|_] = List2,
+ Acc) when FieldName1 < FieldName2 ->
+ get_mod_record_types(Left1, List2, [DT|Acc]);
+get_mod_record_types(Left1, [], Acc) ->
+ {ok, lists:keysort(1, Left1++Acc)};
+get_mod_record_types(_, [{FieldName2, _FormType, _ModType}|_], _Acc) ->
{error, FieldName2}.
-contains_remote(Type) ->
- TypeNoRemote = subst_all_remote(Type, t_none()),
- not t_is_equal(Type, TypeNoRemote).
-
-fields_from_form([], _TypeNames, _RecDict, _VarDict) ->
- {[], []};
-fields_from_form([{Name, Type}|Tail], TypeNames, RecDict,
- VarDict) ->
- {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict),
- {F, R2} = fields_from_form(Tail, TypeNames, RecDict, VarDict),
- {[{Name, T}|F], R1 ++ R2}.
-
-list_from_form([], _TypeNames, _RecDict, _VarDict) ->
- {[], []};
-list_from_form([H|Tail], TypeNames, RecDict, VarDict) ->
- {T, R1} = t_from_form(H, TypeNames, RecDict, VarDict),
- {L, R2} = list_from_form(Tail, TypeNames, RecDict, VarDict),
- {[T|L], R1 ++ R2}.
+%% It is important to create a limited version of the record type
+%% since nested record types can otherwise easily result in huge
+%% terms.
+fields_from_form([], _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {[], L};
+fields_from_form([{Name, Abstr, _Type}|Tail], TypeNames, ET, S, MR,
+ V, D, L) ->
+ {T, L1} = t_from_form(Abstr, TypeNames, ET, S, MR, V, D, L),
+ {F, L2} = fields_from_form(Tail, TypeNames, ET, S, MR, V, D, L1),
+ {[{Name, T}|F], L2}.
+
+list_from_form([], _TypeNames, _ET, _S, _MR, _V, _D, L) ->
+ {[], L};
+list_from_form([H|Tail], TypeNames, ET, S, MR, V, D, L) ->
+ {H1, L1} = t_from_form(H, TypeNames, ET, S, MR, V, D, L - 1),
+ {T1, L2} = list_from_form(Tail, TypeNames, ET, S, MR, V, D, L1),
+ {[H1|T1], L2}.
+
+-spec t_check_record_fields(parse_form(), sets:set(mfa()), site(),
+ mod_records()) -> ok.
+
+t_check_record_fields(Form, ExpTypes, Site, RecDict) ->
+ t_check_record_fields(Form, ExpTypes, Site, RecDict, dict:new()).
+
+-spec t_check_record_fields(parse_form(), sets:set(mfa()), site(),
+ mod_records(), var_table()) -> ok.
+
+%% If there is something wrong with parse_form()
+%% throw({error, io_lib:chars()} is called.
+
+t_check_record_fields({var, _L, _}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({ann_type, _L, [_Var, Type]}, ET, S, MR, V) ->
+ t_check_record_fields(Type, ET, S, MR, V);
+t_check_record_fields({paren_type, _L, [Type]}, ET, S, MR, V) ->
+ t_check_record_fields(Type, ET, S, MR, V);
+t_check_record_fields({remote_type, _L, [{atom, _, _}, {atom, _, _}, Args]},
+ ET, S, MR, V) ->
+ list_check_record_fields(Args, ET, S, MR, V);
+t_check_record_fields({atom, _L, _}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({integer, _L, _}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({op, _L, _Op, _Arg}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({op, _L, _Op, _Arg1, _Arg2}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({type, _L, tuple, any}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({type, _L, map, any}, _ET, _S, _MR, _V) -> ok;
+t_check_record_fields({type, _L, binary, [_Base, _Unit]}, _ET, _S, _MR, _V) ->
+ ok;
+t_check_record_fields({type, _L, 'fun', [{type, _, any}, Range]},
+ ET, S, MR, V) ->
+ t_check_record_fields(Range, ET, S, MR, V);
+t_check_record_fields({type, _L, range, [_From, _To]}, _ET, _S, _MR, _V) ->
+ ok;
+t_check_record_fields({type, _L, record, [Name|Fields]}, ET, S, MR, V) ->
+ check_record(Name, Fields, ET, S, MR, V);
+t_check_record_fields({type, _L, _, Args}, ET, S, MR, V) ->
+ list_check_record_fields(Args, ET, S, MR, V);
+t_check_record_fields({user_type, _L, _Name, Args}, ET, S, MR, V) ->
+ list_check_record_fields(Args, ET, S, MR, V).
+
+check_record({atom, _, Name}, ModFields, ET, Site, MR, V) ->
+ M = site_module(Site),
+ {ok, R} = dict:find(M, MR),
+ {ok, DeclFields} = lookup_record(Name, R),
+ case check_fields(Name, ModFields, DeclFields, ET, Site, MR, V) of
+ {error, FieldName} ->
+ throw({error, io_lib:format("Illegal declaration of #~w{~w}\n",
+ [Name, FieldName])});
+ ok -> ok
+ end.
+
+check_fields(RecName, [{type, _, field_type, [{atom, _, Name}, Abstr]}|Left],
+ DeclFields, ET, Site0, MR, V) ->
+ M = site_module(Site0),
+ Site = {record, {M, RecName, length(DeclFields)}},
+ Type = t_from_form(Abstr, ET, Site, MR, V),
+ {Name, _, DeclType} = lists:keyfind(Name, 1, DeclFields),
+ TypeNoVars = subst_all_vars_to_any(Type),
+ case t_is_subtype(TypeNoVars, DeclType) of
+ false -> {error, Name};
+ true -> check_fields(RecName, Left, DeclFields, ET, Site0, MR, V)
+ end;
+check_fields(_RecName, [], _Decl, _ET, _Site, _MR, _V) ->
+ ok.
+
+list_check_record_fields([], _ET, _S, _MR, _V) ->
+ ok;
+list_check_record_fields([H|Tail], ET, S, MR, V) ->
+ ok = t_check_record_fields(H, ET, S, MR, V),
+ list_check_record_fields(Tail, ET, S, MR, V).
+
+site_module({_, {Module, _, _}}) ->
+ Module.
+
+-spec t_var_names([erl_type()]) -> [atom()].
+
+t_var_names([{var, _, Name}|L]) when L =/= '_' ->
+ [Name|t_var_names(L)];
+t_var_names([]) ->
+ [].
-spec t_form_to_string(parse_form()) -> string().
@@ -4592,7 +4682,7 @@ t_form_to_string({type, _L, iodata, []}) -> "iodata()";
t_form_to_string({type, _L, iolist, []}) -> "iolist()";
t_form_to_string({type, _L, list, [Type]}) ->
"[" ++ t_form_to_string(Type) ++ "]";
-t_form_to_string({type, _L, map, Args}) when not is_list(Args) ->
+t_form_to_string({type, _L, map, _}) ->
"#{}";
t_form_to_string({type, _L, mfa, []}) -> "mfa()";
t_form_to_string({type, _L, module, []}) -> "module()";
@@ -4623,12 +4713,22 @@ t_form_to_string({type, _L, tuple, Args}) ->
t_form_to_string({type, _L, union, Args}) ->
string:join(t_form_to_string_list(Args), " | ");
t_form_to_string({type, _L, Name, []} = T) ->
- try t_to_string(t_from_form(T))
+ try
+ M = mod,
+ D0 = dict:new(),
+ MR = dict:from_list([{M, D0}]),
+ S = {type, {M,Name,0}},
+ {T1, _} =
+ t_from_form(T, [], sets:new(), S, MR, D0, _Deep=1000, _ALot=100000),
+ t_to_string(T1)
catch throw:{error, _} -> atom_to_string(Name) ++ "()"
end;
-t_form_to_string({type, _L, Name, List}) ->
+t_form_to_string({user_type, _L, Name, List}) ->
flat_format("~w(~s)",
- [Name, string:join(t_form_to_string_list(List), ",")]).
+ [Name, string:join(t_form_to_string_list(List), ",")]);
+t_form_to_string({type, L, Name, List}) ->
+ %% Compatibility: modules compiled before Erlang/OTP 18.0.
+ t_form_to_string({user_type, L, Name, List}).
t_form_to_string_list(List) ->
t_form_to_string_list(List, []).
@@ -4671,13 +4771,13 @@ is_erl_type(#c{}) -> true;
is_erl_type(_) -> false.
-spec lookup_record(atom(), type_table()) ->
- 'error' | {'ok', [{atom(), parse_form() | erl_type()}]}.
+ 'error' | {'ok', [{atom(), parse_form(), erl_type()}]}.
lookup_record(Tag, RecDict) when is_atom(Tag) ->
case dict:find({record, Tag}, RecDict) of
- {ok, [{_Arity, Fields}]} ->
+ {ok, {_FileLine, [{_Arity, Fields}]}} ->
{ok, Fields};
- {ok, List} when is_list(List) ->
+ {ok, {_FileLine, List}} when is_list(List) ->
%% This will have to do, since we do not know which record we
%% are looking for.
error;
@@ -4686,12 +4786,12 @@ lookup_record(Tag, RecDict) when is_atom(Tag) ->
end.
-spec lookup_record(atom(), arity(), type_table()) ->
- 'error' | {'ok', [{atom(), erl_type()}]}.
+ 'error' | {'ok', [{atom(), parse_form(), erl_type()}]}.
lookup_record(Tag, Arity, RecDict) when is_atom(Tag) ->
case dict:find({record, Tag}, RecDict) of
- {ok, [{Arity, Fields}]} -> {ok, Fields};
- {ok, OrdDict} -> orddict:find(Arity, OrdDict);
+ {ok, {_FileLine, [{Arity, Fields}]}} -> {ok, Fields};
+ {ok, {_FileLine, OrdDict}} -> orddict:find(Arity, OrdDict);
error -> error
end.
@@ -4711,6 +4811,12 @@ lookup_type(Name, Arity, RecDict) ->
type_is_defined(TypeOrOpaque, Name, Arity, RecDict) ->
dict:is_key({TypeOrOpaque, Name, Arity}, RecDict).
+cannot_have_opaque(Type, TypeName, TypeNames) ->
+ t_is_none(Type) orelse is_recursive(TypeName, TypeNames).
+
+is_recursive(TypeName, TypeNames) ->
+ lists:member(TypeName, TypeNames).
+
can_unfold_more(TypeName, TypeNames) ->
Fun = fun(E, Acc) -> case E of TypeName -> Acc + 1; _ -> Acc end end,
lists:foldl(Fun, 0, TypeNames) < ?REC_TYPE_LIMIT.
@@ -4738,30 +4844,6 @@ do_opaque(?union(List) = Type, Opaques, Pred) ->
do_opaque(Type, _Opaques, Pred) ->
Pred(Type).
-is_same_type_name(ModNameArgs, ModNameArgs) -> true;
-is_same_type_name({Mod, Name, Args1}, {Mod, Name, Args2}) ->
- all_any(Args1) orelse all_any(Args2);
-is_same_type_name({Mod1, Name1, Args1}, {Mod2, Name2, Args2}) ->
- is_same_type_name2(Mod1, Name1, Args1, Mod2, Name2, Args2).
-
-all_any([]) -> true;
-all_any([T|L]) ->
- t_is_any(T) andalso all_any(L);
-all_any(_) -> false.
-
-%% Compatibility. In Erlang/OTP 17 the pre-defined opaque types
-%% digraph() and so on can be used, but there are also new types such
-%% as digraph:graph() with the exact same meaning. In Erlang/OTP R18.0
-%% all but the last clause can be removed.
-
-is_same_type_name2(digraph, digraph, [], digraph, graph, []) -> true;
-is_same_type_name2(digraph, graph, [], digraph, digraph, []) -> true;
-is_same_type_name2(gb_sets, gb_set, [], gb_sets, set, [_]) -> true;
-is_same_type_name2(gb_sets, set, [_], gb_sets, gb_set, []) -> true;
-is_same_type_name2(gb_trees, gb_tree, [], gb_trees, tree, [_, _]) -> true;
-is_same_type_name2(gb_trees, tree, [_, _], gb_trees, gb_tree, []) -> true;
-is_same_type_name2(_, _, _, _, _, _) -> false.
-
map_keys(?map(Pairs)) ->
[K || {K, _} <- Pairs].
diff --git a/lib/hipe/doc/Makefile b/lib/hipe/doc/Makefile
index 4ea0137202..822f8f5d03 100644
--- a/lib/hipe/doc/Makefile
+++ b/lib/hipe/doc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/doc/src/Makefile b/lib/hipe/doc/src/Makefile
index fbfd4ca327..25f80ebafb 100644
--- a/lib/hipe/doc/src/Makefile
+++ b/lib/hipe/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/doc/src/book.xml b/lib/hipe/doc/src/book.xml
index 438be134a2..bd912dd760 100644
--- a/lib/hipe/doc/src/book.xml
+++ b/lib/hipe/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/hipe/doc/src/hipe_app.xml b/lib/hipe/doc/src/hipe_app.xml
index 2ddce664cc..bf4bdbb3b3 100644
--- a/lib/hipe/doc/src/hipe_app.xml
+++ b/lib/hipe/doc/src/hipe_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -36,15 +37,14 @@
<description>
<p>
The normal way to native-compile an Erlang module using HiPE is to include the atom native
- in the Erlang compiler options, as in:
- <code>
- 1> <input>c(my_module, [native]).</input></code>
- Options to the HiPE compiler are then passed as follows:
- <code>
- 1> <input>c(my_module, [native,{hipe,Options}]).</input></code>
- For on-line help in the Erlang shell, call <c>hipe:help()</c>.
- Details on HiPE compiler options are given by <c>hipe:help_options()</c>.
- </p>
+ in the Erlang compiler options, as in:</p>
+ <pre>
+ 1> <input>c(my_module, [native]).</input></pre>
+ <p>Options to the HiPE compiler are then passed as follows:</p>
+ <pre>
+ 1> <input>c(my_module, [native,{hipe,Options}]).</input></pre>
+ <p>For on-line help in the Erlang shell, call <c>hipe:help()</c>.
+ Details on HiPE compiler options are given by <c>hipe:help_options()</c>.</p>
</description>
<section>
<title>SEE ALSO</title>
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 8d3358533b..761b4d9f90 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,207 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix pretty printing of Core Maps</p>
+ <p>
+ Literal maps could cause Dialyzer to crash when pretty
+ printing the results.</p>
+ <p>
+ Own Id: OTP-13238</p>
+ </item>
+ <item>
+ <p>
+ Dialyzer warnings removed.</p>
+ <p>
+ Own Id: OTP-13379</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix HiPE ErLLVM code generation for pattern matching with
+ UTF binaries.</p>
+ <p>
+ Own Id: OTP-13269</p>
+ </item>
+ <item>
+ <p>
+ Fix various binary construction inconsistencies for hipe
+ compiled code. <list> <item>Passing bad field sizes to
+ binary constructions would throw <c>badarith</c> rather
+ than <c>badarg</c>. Worse, in guards, when the unit size
+ of the field was 1, the exception would leak rather than
+ failing the function clause match.</item> <item>Passing
+ bignums as field sizes to binary constructions would
+ always fail (and always with <c>badarg</c>).</item>
+ <item>A bug in bs_init_bits that cased binary
+ constructions to fail with system_limit if they were at
+ least 1/8th of the actual limit.</item> <item>Compiler
+ crashes when matches against an integer literal whose
+ size fits an unsigned word, but not a signed word or
+ matches against an integer literal that whose size is
+ larger than the largest allowed bignum.</item> <item>Very
+ large binary constructions that should fail with
+ system_limit could instead fail with <c>badarg</c> or
+ even succeed with a faulty result.</item> <item>Add
+ missing check for unit size match when inserting a
+ binary. For example, a faulty expression like
+ <c>&lt;&lt;&lt;&lt;1:7&gt;&gt;/binary&gt;&gt;</c> would
+ succeed.</item> </list></p>
+ <p>
+ Own Id: OTP-13272</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.14</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix hipe bug causing segfaults when native code
+ constructs binaries starting with a zero-length integer
+ field.</p>
+ <p>
+ Own Id: OTP-13048</p>
+ </item>
+ <item>
+ <p>
+ Reintroduce the <c>erlang:make_fun/3</c> BIF in
+ erl_bif_types.</p>
+ <p>
+ Own Id: OTP-13068</p>
+ </item>
+ <item>
+ <p>
+ In certain cases of matching with very big binaries, the
+ HiPE compiler generated code that would fail the match,
+ even in cases that the matching was successful. The
+ problem was more quite noticeable on 32-bit platforms.</p>
+ <p>
+ Own Id: OTP-13092</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ mikpe/hipe_x86_signal-musl-support</p>
+ <p>
+ Own Id: OTP-13159</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix bugs concerning <c>erlang:abs/1</c>. </p>
+ <p>
+ Own Id: OTP-12948</p>
+ </item>
+ <item>
+ <p> Fix a bug concerning <c>lists:keydelete/3</c> with
+ union and opaque types. </p>
+ <p>
+ Own Id: OTP-12949</p>
+ </item>
+ <item>
+ <p>
+ A beam file compiled by hipe for an incompatible runtime
+ system was sometimes not rejected by the loader, which
+ could lead to vm crash. This fix will also allow the same
+ hipe compiler to be used by both normal and debug-built
+ vm.</p>
+ <p>
+ Own Id: OTP-12962</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New function <c>hipe:erts_checksum/0</c> which returns a
+ value identifying the target runtime system for the
+ compiler. Used by dialyzer for its beam cache directory.</p>
+ <p>
+ Own Id: OTP-12963 Aux Id: OTP-12962, OTP-12964 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix a minor bug in the handling of opaque types. </p>
+ <p>
+ Own Id: OTP-12666</p>
+ </item>
+ <item>
+ <p>
+ Fix hipe bug when matching a "writable" binary. The bug
+ has been seen to sometimes cause a failed binary matching
+ of a correct utf8 character, but other symptoms are also
+ possible.</p>
+ <p>
+ Own Id: OTP-12667</p>
+ </item>
+ <item>
+ <p>
+ Optimizations and code cleanup in hipe code loader.</p>
+ <p>
+ Own Id: OTP-12816</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved error handling when memory allocation for HiPE
+ code fails.</p>
+ <p>
+ Own Id: OTP-12448</p>
+ </item>
+ <item>
+ <p>
+ Allow use of complete interface of cerl_pmatch module</p>
+ <p>
+ Own Id: OTP-12794</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.11.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -226,22 +428,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -509,19 +717,17 @@
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
- <p>
<list> <item><p>No warnings for underspecs with remote
types</p></item> <item><p> Fix crash in Typer</p></item>
<item><p>Fix Dialyzer's warning for its own
code</p></item> <item><p>Fix Dialyzer's warnings in
HiPE</p></item> <item><p>Add file/line info in a
particular Dialyzer crash</p></item> <item><p>Update
- inets test results</p></item> </list></p>
+ inets test results</p></item> </list>
<p>
Own Id: OTP-9758</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -532,7 +738,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/hipe/doc/src/part_notes.xml b/lib/hipe/doc/src/part_notes.xml
index f912fcfcdb..f745a2dd42 100644
--- a/lib/hipe/doc/src/part_notes.xml
+++ b/lib/hipe/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/hipe/doc/src/ref_man.xml b/lib/hipe/doc/src/ref_man.xml
index 0e1288b4c4..76d5f0a22a 100644
--- a/lib/hipe/doc/src/ref_man.xml
+++ b/lib/hipe/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/hipe/flow/Makefile b/lib/hipe/flow/Makefile
index 75e156b542..f0af6ac166 100644
--- a/lib/hipe/flow/Makefile
+++ b/lib/hipe/flow/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/flow/cfg.hrl b/lib/hipe/flow/cfg.hrl
index 1f7a162f27..f79fff4efe 100644
--- a/lib/hipe/flow/cfg.hrl
+++ b/lib/hipe/flow/cfg.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/flow/cfg.inc b/lib/hipe/flow/cfg.inc
index f0b1a75737..b39a89dbd4 100644
--- a/lib/hipe/flow/cfg.inc
+++ b/lib/hipe/flow/cfg.inc
@@ -6,16 +6,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/flow/ebb.inc b/lib/hipe/flow/ebb.inc
index 42d7ff3793..a08528154a 100644
--- a/lib/hipe/flow/ebb.inc
+++ b/lib/hipe/flow/ebb.inc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/flow/hipe_bb.erl b/lib/hipe/flow/hipe_bb.erl
index 16730f1dce..7a39d99e71 100644
--- a/lib/hipe/flow/hipe_bb.erl
+++ b/lib/hipe/flow/hipe_bb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/flow/hipe_bb.hrl b/lib/hipe/flow/hipe_bb.hrl
index f4d426dad1..13cad16174 100644
--- a/lib/hipe/flow/hipe_bb.hrl
+++ b/lib/hipe/flow/hipe_bb.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/flow/hipe_dominators.erl b/lib/hipe/flow/hipe_dominators.erl
index 50d45c7c72..2fb277b914 100644
--- a/lib/hipe/flow/hipe_dominators.erl
+++ b/lib/hipe/flow/hipe_dominators.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/flow/hipe_gen_cfg.erl b/lib/hipe/flow/hipe_gen_cfg.erl
index f9fb1f70c8..99f33699bd 100644
--- a/lib/hipe/flow/hipe_gen_cfg.erl
+++ b/lib/hipe/flow/hipe_gen_cfg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/flow/liveness.inc b/lib/hipe/flow/liveness.inc
index 6f161fb269..d420495f5a 100644
--- a/lib/hipe/flow/liveness.inc
+++ b/lib/hipe/flow/liveness.inc
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/Makefile b/lib/hipe/icode/Makefile
index 87015aa51c..a82e28c7d9 100644
--- a/lib/hipe/icode/Makefile
+++ b/lib/hipe/icode/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 4691662f9f..37c6ba9c60 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -880,6 +881,15 @@ trans_fun([{bs_init_bits,{f,Lbl},Size,_Words,_LiveRegs,{field_flags,Flags0},X}|
trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
Dst = mk_var(Res),
Temp = mk_var(new),
+ {FailLblName, FailCode} =
+ if Lbl =:= 0 ->
+ FailLbl = mk_label(new),
+ {hipe_icode:label_name(FailLbl),
+ [FailLbl,
+ hipe_icode:mk_fail([hipe_icode:mk_const(badarg)], error)]};
+ true ->
+ {map_label(Lbl), []}
+ end,
MultIs =
case {New,Unit} of
{{integer, NewInt}, _} ->
@@ -889,40 +899,26 @@ trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
[hipe_icode:mk_move(Temp, NewVar)];
_ ->
NewVar = mk_var(New),
- if Lbl =:= 0 ->
- [hipe_icode:mk_primop([Temp], '*',
- [NewVar, hipe_icode:mk_const(Unit)])];
- true ->
- Succ = mk_label(new),
- [hipe_icode:mk_primop([Temp], '*',
- [NewVar, hipe_icode:mk_const(Unit)],
- hipe_icode:label_name(Succ), map_label(Lbl)),
- Succ]
- end
+ Succ = mk_label(new),
+ [hipe_icode:mk_primop([Temp], '*',
+ [NewVar, hipe_icode:mk_const(Unit)],
+ hipe_icode:label_name(Succ), FailLblName),
+ Succ]
end,
Succ2 = mk_label(new),
- {FailLblName, FailCode} =
- if Lbl =:= 0 ->
- FailLbl = mk_label(new),
- {hipe_icode:label_name(FailLbl),
- [FailLbl,
- hipe_icode:mk_fail([hipe_icode:mk_const(badarg)], error)]};
- true ->
- {map_label(Lbl), []}
- end,
IsPos =
[hipe_icode:mk_if('>=', [Temp, hipe_icode:mk_const(0)],
hipe_icode:label_name(Succ2), FailLblName)] ++
- FailCode ++ [Succ2],
- AddI =
+ FailCode ++ [Succ2],
+ AddRhs =
case Old of
- {integer,OldInt} ->
- hipe_icode:mk_primop([Dst], '+', [Temp, hipe_icode:mk_const(OldInt)]);
- _ ->
- OldVar = mk_var(Old),
- hipe_icode:mk_primop([Dst], '+', [Temp, OldVar])
+ {integer,OldInt} -> hipe_icode:mk_const(OldInt);
+ _ -> mk_var(Old)
end,
- MultIs ++ IsPos ++ [AddI|trans_fun(Instructions, Env)];
+ Succ3 = mk_label(new),
+ AddI = hipe_icode:mk_primop([Dst], '+', [Temp, AddRhs],
+ hipe_icode:label_name(Succ3), FailLblName),
+ MultIs ++ IsPos ++ [AddI,Succ3|trans_fun(Instructions, Env)];
%%--------------------------------------------------------------------
%% Bit syntax instructions added in R12B-5 (Fall 2008)
%%--------------------------------------------------------------------
@@ -1305,7 +1301,7 @@ trans_bin([{bs_put_binary,{f,Lbl},Size,Unit,{field_flags,Flags},Source}|
{Name, Args, Env2} =
case Size of
{atom,all} -> %% put all bits
- {{bs_put_binary_all, Flags}, [Src,Base,Offset], Env};
+ {{bs_put_binary_all, Unit, Flags}, [Src,Base,Offset], Env};
{integer,NoBits} when is_integer(NoBits), NoBits >= 0 ->
%% Create a N*Unit bits subbinary
{{bs_put_binary, NoBits*Unit, Flags}, [Src,Base,Offset], Env};
@@ -1584,11 +1580,7 @@ gen_put_map_instrs(exists, Op, TempMapVar, Dst, FailLbl, Pairs, Env) ->
end,
{[IsMapCode, TrueLabel, PutInstructions, ReturnLbl], Env1};
gen_put_map_instrs(new, Op, TempMapVar, Dst, new, Pairs, Env) ->
- TrueLabel = mk_label(new),
FailLbl = mk_label(new),
- IsMapCode = hipe_icode:mk_type([TempMapVar], map,
- hipe_icode:label_name(TrueLabel),
- hipe_icode:label_name(FailLbl)),
DstMapVar = mk_var(Dst),
{ReturnLbl, PutInstructions, Env1}
= case Op of
@@ -1596,10 +1588,10 @@ gen_put_map_instrs(new, Op, TempMapVar, Dst, new, Pairs, Env) ->
trans_put_map_assoc(TempMapVar, DstMapVar, Pairs, Env, []);
exact ->
trans_put_map_exact(TempMapVar, DstMapVar,
- hipe_icode:label_name(FailLbl), Pairs, Env, [])
+ none, Pairs, Env, [])
end,
Fail = hipe_icode:mk_fail([hipe_icode:mk_const(badarg)], error),
- {[IsMapCode, TrueLabel, PutInstructions, FailLbl, Fail, ReturnLbl], Env1}.
+ {[PutInstructions, FailLbl, Fail, ReturnLbl], Env1}.
%%-----------------------------------------------------------------------
%% This function generates the instructions needed to insert several
@@ -1629,6 +1621,13 @@ trans_put_map_exact(MapVar, DestMapVar, _FLbl, [], Env, Acc) ->
ReturnLbl = mk_label(new),
GotoReturn = hipe_icode:mk_goto(hipe_icode:label_name(ReturnLbl)),
{ReturnLbl, lists:reverse([GotoReturn, MoveToReturnVar | Acc]), Env};
+trans_put_map_exact(MapVar, DestMapVar, none, [Key, Value | Rest], Env, Acc) ->
+ {MoveKey, KeyVar, Env1} = mk_move_and_var(Key, Env),
+ {MoveVal, ValVar, Env2} = mk_move_and_var(Value, Env1),
+ BifCallPut = hipe_icode:mk_call([MapVar], maps, update,
+ [KeyVar, ValVar, MapVar], remote),
+ Acc1 = [BifCallPut, MoveVal, MoveKey | Acc],
+ trans_put_map_exact(MapVar, DestMapVar, none, Rest, Env2, Acc1);
trans_put_map_exact(MapVar, DestMapVar, FLbl, [Key, Value | Rest], Env, Acc) ->
SuccLbl = mk_label(new),
{MoveKey, KeyVar, Env1} = mk_move_and_var(Key, Env),
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl
index 7b3d087e2d..5c7003b0ed 100644
--- a/lib/hipe/icode/hipe_icode.erl
+++ b/lib/hipe/icode/hipe_icode.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode.hrl b/lib/hipe/icode/hipe_icode.hrl
index 46c04beb40..9b24c4914e 100644
--- a/lib/hipe/icode/hipe_icode.hrl
+++ b/lib/hipe/icode/hipe_icode.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_bincomp.erl b/lib/hipe/icode/hipe_icode_bincomp.erl
index 6f694f2bce..c765f1926b 100644
--- a/lib/hipe/icode/hipe_icode_bincomp.erl
+++ b/lib/hipe/icode/hipe_icode_bincomp.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl
index ccf97ecc17..27dc49a178 100644
--- a/lib/hipe/icode/hipe_icode_callgraph.erl
+++ b/lib/hipe/icode/hipe_icode_callgraph.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_cfg.erl b/lib/hipe/icode/hipe_icode_cfg.erl
index f6c2b0600b..dfc3f316b3 100644
--- a/lib/hipe/icode/hipe_icode_cfg.erl
+++ b/lib/hipe/icode/hipe_icode_cfg.erl
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_coordinator.erl b/lib/hipe/icode/hipe_icode_coordinator.erl
index c69db9afa9..1150f31abf 100644
--- a/lib/hipe/icode/hipe_icode_coordinator.erl
+++ b/lib/hipe/icode/hipe_icode_coordinator.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_ebb.erl b/lib/hipe/icode/hipe_icode_ebb.erl
index 966c4d7564..8d0ea94d92 100644
--- a/lib/hipe/icode/hipe_icode_ebb.erl
+++ b/lib/hipe/icode/hipe_icode_ebb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_exceptions.erl b/lib/hipe/icode/hipe_icode_exceptions.erl
index 6191c536ad..41556ab80f 100644
--- a/lib/hipe/icode/hipe_icode_exceptions.erl
+++ b/lib/hipe/icode/hipe_icode_exceptions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_fp.erl b/lib/hipe/icode/hipe_icode_fp.erl
index 38b3881a77..5ae0395b72 100644
--- a/lib/hipe/icode/hipe_icode_fp.erl
+++ b/lib/hipe/icode/hipe_icode_fp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_heap_test.erl b/lib/hipe/icode/hipe_icode_heap_test.erl
index 92d5f023fa..72d3574122 100644
--- a/lib/hipe/icode/hipe_icode_heap_test.erl
+++ b/lib/hipe/icode/hipe_icode_heap_test.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_inline_bifs.erl b/lib/hipe/icode/hipe_icode_inline_bifs.erl
index 6ef15b9a18..4841b56f41 100644
--- a/lib/hipe/icode/hipe_icode_inline_bifs.erl
+++ b/lib/hipe/icode/hipe_icode_inline_bifs.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_instruction_counter.erl b/lib/hipe/icode/hipe_icode_instruction_counter.erl
index f44adfe149..183198e5eb 100644
--- a/lib/hipe/icode/hipe_icode_instruction_counter.erl
+++ b/lib/hipe/icode/hipe_icode_instruction_counter.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_liveness.erl b/lib/hipe/icode/hipe_icode_liveness.erl
index 5816e59032..2d12bacc36 100644
--- a/lib/hipe/icode/hipe_icode_liveness.erl
+++ b/lib/hipe/icode/hipe_icode_liveness.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_mulret.erl b/lib/hipe/icode/hipe_icode_mulret.erl
index 99522f6430..d0a0530ef5 100644
--- a/lib/hipe/icode/hipe_icode_mulret.erl
+++ b/lib/hipe/icode/hipe_icode_mulret.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_pp.erl b/lib/hipe/icode/hipe_icode_pp.erl
index de29b6f779..749f32e87c 100644
--- a/lib/hipe/icode/hipe_icode_pp.erl
+++ b/lib/hipe/icode/hipe_icode_pp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index b0113fc556..a0deb31c42 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -115,7 +116,7 @@ is_safe({hipe_bs_primop, {bs_init, _, _}}) -> false;
is_safe({hipe_bs_primop, {bs_init_bits, _}}) -> false;
is_safe({hipe_bs_primop, {bs_init_bits, _, _}}) -> false;
is_safe({hipe_bs_primop, {bs_put_binary, _, _}}) -> false;
-is_safe({hipe_bs_primop, {bs_put_binary_all, _}}) -> false;
+is_safe({hipe_bs_primop, {bs_put_binary_all, _, _}}) -> false;
is_safe({hipe_bs_primop, {bs_put_float, _, _, _}}) -> false;
is_safe({hipe_bs_primop, {bs_put_integer, _, _, _}}) -> false;
is_safe({hipe_bs_primop, {bs_put_string, _, _}}) -> false;
@@ -218,7 +219,7 @@ fails({hipe_bs_primop, {bs_init, _, _}}) -> true;
fails({hipe_bs_primop, {bs_init_bits, _}}) -> true;
fails({hipe_bs_primop, {bs_init_bits, _, _}}) -> true;
fails({hipe_bs_primop, {bs_put_binary, _, _}}) -> true;
-fails({hipe_bs_primop, {bs_put_binary_all, _}}) -> true;
+fails({hipe_bs_primop, {bs_put_binary_all, _, _}}) -> true;
fails({hipe_bs_primop, {bs_put_float, _, _, _}}) -> true;
fails({hipe_bs_primop, {bs_put_integer, _, _, _}}) -> true;
fails({hipe_bs_primop, {bs_put_string, _, _}}) -> true;
@@ -264,8 +265,8 @@ pp(Dev, Op) ->
io:format(Dev, "gc_test<~w>", [N]);
{hipe_bs_primop, BsOp} ->
case BsOp of
- {bs_put_binary_all, Flags} ->
- io:format(Dev, "bs_put_binary_all<~w>", [Flags]);
+ {bs_put_binary_all, Unit, Flags} ->
+ io:format(Dev, "bs_put_binary_all<~w, ~w>", [Unit,Flags]);
{bs_put_binary, Size} ->
io:format(Dev, "bs_put_binary<~w>", [Size]);
{bs_put_binary, Flags, Size} ->
@@ -503,14 +504,16 @@ type(Primop, Args) ->
NewBinType = match_bin(erl_types:t_bitstr(0, Size), BinType),
NewMatchState =
erl_types:t_matchstate_update_present(NewBinType, MatchState),
- if Signed =:= 0 ->
- erl_types:t_product([erl_types:t_from_range(0, 1 bsl Size - 1),
- NewMatchState]);
- Signed =:= 4 ->
- erl_types:t_product([erl_types:t_from_range(- (1 bsl (Size-1)),
- (1 bsl (Size-1)) - 1),
- NewMatchState])
- end;
+ Range =
+ case Signed of
+ 0 ->
+ UpperBound = inf_add(safe_bsl_1(Size), -1),
+ erl_types:t_from_range(0, UpperBound);
+ 4 ->
+ Bound = safe_bsl_1(Size - 1),
+ erl_types:t_from_range(inf_inv(Bound), inf_add(Bound, -1))
+ end,
+ erl_types:t_product([Range, NewMatchState]);
[_Arg] ->
NewBinType = match_bin(erl_types:t_bitstr(Size, 0), BinType),
NewMatchState =
@@ -627,8 +630,9 @@ type(Primop, Args) ->
[_SrcType, _BitsType, _Base, Type] ->
erl_types:t_bitstr_concat(Type, erl_types:t_bitstr(Size, 0))
end;
- {hipe_bs_primop, {bs_put_binary_all, _Flags}} ->
- [SrcType, _Base, Type] = Args,
+ {hipe_bs_primop, {bs_put_binary_all, Unit, _Flags}} ->
+ [SrcType0, _Base, Type] = Args,
+ SrcType = erl_types:t_inf(erl_types:t_bitstr(Unit, 0), SrcType0),
erl_types:t_bitstr_concat(SrcType,Type);
{hipe_bs_primop, {bs_put_string, _, Size}} ->
[_Base, Type] = Args,
@@ -964,3 +968,20 @@ check_fun_args(_, _) ->
match_bin(Pattern, Match) ->
erl_types:t_bitstr_match(Pattern, Match).
+
+-spec safe_bsl_1(non_neg_integer()) -> non_neg_integer() | 'pos_inf'.
+
+safe_bsl_1(Shift) when Shift =< 128 -> 1 bsl Shift;
+safe_bsl_1(_Shift) -> pos_inf.
+
+%%
+%% The following two functions are stripped-down versions of more
+%% general functions that exist in hipe_icode_range.erl
+%%
+
+inf_inv(pos_inf) -> neg_inf;
+inf_inv(Number) when is_integer(Number) -> -Number.
+
+inf_add(pos_inf, _Number) -> pos_inf;
+inf_add(Number1, Number2) when is_integer(Number1), is_integer(Number2) ->
+ Number1 + Number2.
diff --git a/lib/hipe/icode/hipe_icode_primops.hrl b/lib/hipe/icode/hipe_icode_primops.hrl
index 8a65c5ece0..7cfc8389ff 100644
--- a/lib/hipe/icode/hipe_icode_primops.hrl
+++ b/lib/hipe/icode/hipe_icode_primops.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index fbc58f3568..9a20527a83 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1201,11 +1202,11 @@ basic_type(#unsafe_update_element{}) -> not_analysed.
analyse_bs_get_integer(Size, Flags, true) ->
Signed = Flags band 4,
if Signed =:= 0 ->
- Max = 1 bsl Size - 1,
+ Max = inf_add(inf_bsl(1, Size), -1),
Min = 0;
true ->
- Max = 1 bsl (Size-1) - 1,
- Min = -(1 bsl (Size-1))
+ Max = inf_add(inf_bsl(1, Size-1), -1),
+ Min = inf_inv(inf_bsl(1, Size-1))
end,
{Min, Max};
analyse_bs_get_integer(Size, Flags, false) when is_integer(Size),
diff --git a/lib/hipe/icode/hipe_icode_split_arith.erl b/lib/hipe/icode/hipe_icode_split_arith.erl
index d59f9247fa..4f6a79411b 100644
--- a/lib/hipe/icode/hipe_icode_split_arith.erl
+++ b/lib/hipe/icode/hipe_icode_split_arith.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_ssa.erl b/lib/hipe/icode/hipe_icode_ssa.erl
index 2c4b6d9409..3d8f18867d 100644
--- a/lib/hipe/icode/hipe_icode_ssa.erl
+++ b/lib/hipe/icode/hipe_icode_ssa.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_ssa_const_prop.erl b/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
index f1640b1cee..bfa4c0fc61 100644
--- a/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl b/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
index 1899c09715..ae2f32fd2c 100644
--- a/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
index 772e30eada..e350a6ff18 100644
--- a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/icode/hipe_icode_type.erl b/lib/hipe/icode/hipe_icode_type.erl
index ebeb5e2c10..fd81915f9f 100644
--- a/lib/hipe/icode/hipe_icode_type.erl
+++ b/lib/hipe/icode/hipe_icode_type.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/icode/hipe_icode_type.hrl b/lib/hipe/icode/hipe_icode_type.hrl
index dd69c1e8b2..ba2b51e4f5 100644
--- a/lib/hipe/icode/hipe_icode_type.hrl
+++ b/lib/hipe/icode/hipe_icode_type.hrl
@@ -3,16 +3,17 @@
%%%
%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/llvm/Makefile b/lib/hipe/llvm/Makefile
index 92f378924a..f6f6f6be1c 100644
--- a/lib/hipe/llvm/Makefile
+++ b/lib/hipe/llvm/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/llvm/hipe_llvm_main.erl b/lib/hipe/llvm/hipe_llvm_main.erl
index 0e50c9539b..3c24425828 100644
--- a/lib/hipe/llvm/hipe_llvm_main.erl
+++ b/lib/hipe/llvm/hipe_llvm_main.erl
@@ -465,7 +465,7 @@ remove_temp_folder(Dir, Options) ->
end.
unique_id(FunName, Arity) ->
- integer_to_list(erlang:phash2({FunName, Arity, now()})).
+ integer_to_list(erlang:phash2({FunName, Arity, erlang:unique_integer()})).
unique_folder(FunName, Arity, Options) ->
DirName = "llvm_" ++ unique_id(FunName, Arity) ++ "/",
diff --git a/lib/hipe/llvm/hipe_llvm_merge.erl b/lib/hipe/llvm/hipe_llvm_merge.erl
index 3ababfc21a..6e891ac3b0 100644
--- a/lib/hipe/llvm/hipe_llvm_merge.erl
+++ b/lib/hipe/llvm/hipe_llvm_merge.erl
@@ -27,7 +27,7 @@ finalize(CompiledCode, Closures, Exports) ->
DataRelocs = hipe_pack_constants:mk_data_relocs(RefsFromConsts, LabelMap),
SSE = hipe_pack_constants:slim_sorted_exportmap(ExportMap, Closures, Exports),
SlimRefs = hipe_pack_constants:slim_refs(AccRefs),
- term_to_binary([{?VERSION_STRING(),?HIPE_SYSTEM_CRC},
+ term_to_binary([{?VERSION_STRING(),?HIPE_ERTS_CHECKSUM},
ConstAlign, ConstSize,
SC, % ConstMap
DataRelocs, % LabelMap
diff --git a/lib/hipe/main/Makefile b/lib/hipe/main/Makefile
index 66e4c3e39a..d44be2d9fa 100644
--- a/lib/hipe/main/Makefile
+++ b/lib/hipe/main/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src
index e81212d4dc..aa86b6dc5b 100644
--- a/lib/hipe/main/hipe.app.src
+++ b/lib/hipe/main/hipe.app.src
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -223,5 +224,5 @@
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["syntax_tools-1.6.14","stdlib-2.0","kernel-3.0",
- "erts-6.0","compiler-5.0"]}]}.
+ {runtime_dependencies, ["syntax_tools-1.6.14","stdlib-2.5","kernel-3.0",
+ "erts-7.1","compiler-5.0"]}]}.
diff --git a/lib/hipe/main/hipe.appup.src b/lib/hipe/main/hipe.appup.src
index 02679fab21..599fd3179e 100644
--- a/lib/hipe/main/hipe.appup.src
+++ b/lib/hipe/main/hipe.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%", [], []}.
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index 539ce883c0..1a4bbf179f 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -207,7 +208,8 @@
help_options/0,
help_option/1,
help_debug_options/0,
- version/0]).
+ version/0,
+ erts_checksum/0]).
-ifndef(DEBUG).
-define(DEBUG,true).
@@ -215,6 +217,7 @@
-include("hipe.hrl").
-include("../../compiler/src/beam_disasm.hrl").
+-include("../rtl/hipe_literals.hrl").
%%-------------------------------------------------------------------
%% Basic type declaration for exported functions of the 'hipe' module
@@ -649,8 +652,9 @@ run_compiler_1(DisasmFun, IcodeFun, Options) ->
%% The full option expansion is not done
%% until the DisasmFun returns.
{Code, CompOpts} = DisasmFun(Options),
- Opts0 = expand_options(Options ++ CompOpts),
- Opts =
+ Opts0 = expand_options(Options ++ CompOpts,
+ get(hipe_target_arch)),
+ Opts =
case proplists:get_bool(to_llvm, Opts0) andalso
not llvm_support_available() of
true ->
@@ -895,8 +899,7 @@ do_load(Mod, Bin, BeamBinOrPath) when is_binary(BeamBinOrPath);
code:load_native_sticky(Mod, Bin, Beam);
false ->
%% Normal loading of a whole module
- Architecture = erlang:system_info(hipe_architecture),
- ChunkName = hipe_unified_loader:chunk_name(Architecture),
+ ChunkName = hipe_unified_loader:chunk_name(HostArch),
{ok, _, Chunks0} = beam_lib:all_chunks(BeamBinOrPath),
Chunks = [{ChunkName, Bin}|lists:keydelete(ChunkName, 1, Chunks0)],
{ok, BeamPlusNative} = beam_lib:build_module(Chunks),
@@ -933,9 +936,9 @@ assemble(CompiledCode, Closures, Exports, Options) ->
%% but can be overridden by passing an option {target, Target}.
set_architecture(Options) ->
- put(hipe_host_arch, erlang:system_info(hipe_architecture)),
- put(hipe_target_arch,
- proplists:get_value(target, Options, get(hipe_host_arch))),
+ HostArch = erlang:system_info(hipe_architecture),
+ put(hipe_host_arch, HostArch),
+ put(hipe_target_arch, proplists:get_value(target, Options, HostArch)),
ok.
%% This sets up some globally accessed stuff that are needed by the
@@ -943,7 +946,7 @@ set_architecture(Options) ->
%% Therefore, this expands the current set of options for local use.
pre_init(Opts) ->
- Options = expand_options(Opts),
+ Options = expand_options(Opts, get(hipe_target_arch)),
%% Initialise some counters used for measurements and benchmarking. If
%% the option 'measure_regalloc' is given the compilation will return
%% a keylist with the counter values.
@@ -1031,6 +1034,12 @@ post(Res, Icode, Options) ->
version() ->
?VERSION_STRING().
+%% @doc Returns checksum identifying the target runtime system.
+-spec erts_checksum() -> integer().
+
+erts_checksum() ->
+ ?HIPE_ERTS_CHECKSUM.
+
%% --------------------------------------------------------------------
%% D O C U M E N T A T I O N - H E L P
%% --------------------------------------------------------------------
@@ -1061,6 +1070,8 @@ help() ->
" Prints a description of debug options.\n" ++
" version() ->\n" ++
" Returns the HiPE version as a string'.\n" ++
+ " erts_checksum() ->\n" ++
+ " Returns a checksum identifying the target runtime system.\n" ++
"\n" ++
" For HiPE developers only:\n" ++
" Use `help_hiper()' for information about HiPE's low-level interface\n",
@@ -1105,10 +1116,10 @@ help_hiper() ->
-spec help_options() -> 'ok'.
help_options() ->
- set_architecture([]), %% needed for target-specific option expansion
- O1 = expand_options([o1]),
- O2 = expand_options([o2]),
- O3 = expand_options([o3]),
+ HostArch = erlang:system_info(hipe_architecture),
+ O1 = expand_options([o1], HostArch),
+ O2 = expand_options([o2], HostArch),
+ O3 = expand_options([o3], HostArch),
io:format("HiPE Compiler Options\n" ++
" Boolean-valued options generally have corresponding " ++
"aliases `no_...',\n" ++
@@ -1134,7 +1145,7 @@ help_options() ->
[ordsets:from_list([verbose, debug, time, load, pp_beam,
pp_icode, pp_rtl, pp_native, pp_asm,
timeout]),
- expand_options([pp_all]),
+ expand_options([pp_all], HostArch),
O1 -- [o1],
(O2 -- O1) -- [o2],
(O3 -- O2) -- [o3]]),
@@ -1232,8 +1243,8 @@ option_text(Opt) when is_atom(Opt) ->
-spec help_option(comp_option()) -> 'ok'.
help_option(Opt) ->
- set_architecture([]), %% needed for target-specific option expansion
- case expand_options([Opt]) of
+ HostArch = erlang:system_info(hipe_architecture),
+ case expand_options([Opt], HostArch) of
[Opt] ->
Name = if is_atom(Opt) -> Opt;
tuple_size(Opt) =:= 2 -> element(1, Opt)
@@ -1364,11 +1375,11 @@ opt_keys() ->
%% verbose_spills,
x87].
-%% Definitions:
+%% Definitions:
-o1_opts() ->
+o1_opts(TargetArch) ->
Common = [inline_fp, pmatch, peephole],
- case get(hipe_target_arch) of
+ case TargetArch of
ultrasparc ->
Common;
powerpc ->
@@ -1385,48 +1396,22 @@ o1_opts() ->
?EXIT({executing_on_an_unsupported_architecture,Arch})
end.
-o2_opts() ->
+o2_opts(TargetArch) ->
Common = [icode_ssa_const_prop, icode_ssa_copy_prop, % icode_ssa_struct_reuse,
icode_type, icode_inline_bifs, rtl_lcm,
rtl_ssa, rtl_ssa_const_prop,
- spillmin_color, use_indexing, remove_comments,
- concurrent_comp, binary_opt | o1_opts()],
- case get(hipe_target_arch) of
- ultrasparc ->
- Common;
- powerpc ->
- Common;
- ppc64 ->
- Common;
- arm ->
- Common;
- x86 ->
- Common;
- % [rtl_ssapre | Common];
- amd64 ->
- [icode_range | Common]; % range analysis is effective on 64 bits
- Arch ->
- ?EXIT({executing_on_an_unsupported_architecture,Arch})
- end.
-
-o3_opts() ->
- Common = [icode_range, {regalloc,coalescing} | o2_opts()],
- case get(hipe_target_arch) of
- ultrasparc ->
- Common;
- powerpc ->
- Common;
- ppc64 ->
- Common;
- arm ->
- Common;
- x86 ->
- Common;
- amd64 ->
- Common;
- Arch ->
- ?EXIT({executing_on_an_unsupported_architecture,Arch})
- end.
+ spillmin_color, use_indexing, remove_comments,
+ concurrent_comp, binary_opt | o1_opts(TargetArch)],
+ case TargetArch of
+ T when T =:= amd64 orelse T =:= ppc64 -> % 64-bit targets
+ [icode_range | Common];
+ _ -> % T \in [arm, powerpc, ultrasparc, x86]
+ Common % [rtl_ssapre | Common];
+ end.
+
+o3_opts(TargetArch) ->
+ %% no point checking for target architecture since this is checked in 'o1'
+ [icode_range, {regalloc,coalescing} | o2_opts(TargetArch)].
%% Note that in general, the normal form for options should be positive.
%% This is a good programming convention, so that tests in the code say
@@ -1489,18 +1474,18 @@ opt_aliases() ->
opt_basic_expansions() ->
[{pp_all, [pp_beam, pp_icode, pp_rtl, pp_native]}].
-opt_expansions() ->
- [{o1, o1_opts()},
- {o2, o2_opts()},
- {o3, o3_opts()},
+opt_expansions(TargetArch) ->
+ [{o1, o1_opts(TargetArch)},
+ {o2, o2_opts(TargetArch)},
+ {o3, o3_opts(TargetArch)},
{to_llvm, llvm_opts(o3)},
{{to_llvm, o0}, llvm_opts(o0)},
{{to_llvm, o1}, llvm_opts(o1)},
{{to_llvm, o2}, llvm_opts(o2)},
{{to_llvm, o3}, llvm_opts(o3)},
{x87, [x87, inline_fp]},
- {inline_fp, case get(hipe_target_arch) of %% XXX: Temporary until x86
- x86 -> [x87, inline_fp]; %% has sse2
+ {inline_fp, case TargetArch of %% XXX: Temporary until x86 has sse2
+ x86 -> [x87, inline_fp];
_ -> [inline_fp] end}].
llvm_opts(O) ->
@@ -1523,18 +1508,18 @@ expand_kt2(Opts) ->
[{use_callgraph, fixpoint}, core,
{core_transform, cerl_typean}]}]}]).
-%% Note that set_architecture/1 must be called first, and that the given
+%% Note that the given
%% list should contain the total set of options, since things like 'o2'
%% are expanded here. Basic expansions are processed here also, since
%% this function is called from the help functions.
--spec expand_options(comp_options()) -> comp_options().
+-spec expand_options(comp_options(), hipe_architecture()) -> comp_options().
-expand_options(Opts) ->
+expand_options(Opts, TargetArch) ->
proplists:normalize(Opts, [{negations, opt_negations()},
{aliases, opt_aliases()},
{expand, opt_basic_expansions()},
- {expand, opt_expansions()}]).
+ {expand, opt_expansions(TargetArch)}]).
-spec check_options(comp_options()) -> 'ok'.
diff --git a/lib/hipe/main/hipe.hrl.src b/lib/hipe/main/hipe.hrl.src
index e74f31b19d..ba27878a84 100644
--- a/lib/hipe/main/hipe.hrl.src
+++ b/lib/hipe/main/hipe.hrl.src
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl
index 89b79998be..5753169961 100644
--- a/lib/hipe/main/hipe_main.erl
+++ b/lib/hipe/main/hipe_main.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/misc/Makefile b/lib/hipe/misc/Makefile
index 16166f552c..be5c9bc2b6 100644
--- a/lib/hipe/misc/Makefile
+++ b/lib/hipe/misc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/misc/hipe_consttab.erl b/lib/hipe/misc/hipe_consttab.erl
index 2b02f54b5c..fd4c2e2f27 100644
--- a/lib/hipe/misc/hipe_consttab.erl
+++ b/lib/hipe/misc/hipe_consttab.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/misc/hipe_consttab.hrl b/lib/hipe/misc/hipe_consttab.hrl
index aea3c5bc88..8f3bc8e337 100644
--- a/lib/hipe/misc/hipe_consttab.hrl
+++ b/lib/hipe/misc/hipe_consttab.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/misc/hipe_data_pp.erl b/lib/hipe/misc/hipe_data_pp.erl
index 0f206e8ade..fbb247fd96 100644
--- a/lib/hipe/misc/hipe_data_pp.erl
+++ b/lib/hipe/misc/hipe_data_pp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/misc/hipe_gensym.erl b/lib/hipe/misc/hipe_gensym.erl
index 4d2a237188..aea53b137b 100644
--- a/lib/hipe/misc/hipe_gensym.erl
+++ b/lib/hipe/misc/hipe_gensym.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/misc/hipe_pack_constants.erl b/lib/hipe/misc/hipe_pack_constants.erl
index 300f9ae43a..6706b4b023 100644
--- a/lib/hipe/misc/hipe_pack_constants.erl
+++ b/lib/hipe/misc/hipe_pack_constants.erl
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/misc/hipe_sdi.erl b/lib/hipe/misc/hipe_sdi.erl
index 9a2ff78ecf..00d30e553b 100644
--- a/lib/hipe/misc/hipe_sdi.erl
+++ b/lib/hipe/misc/hipe_sdi.erl
@@ -5,16 +5,17 @@
%%%
%%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/misc/hipe_sdi.hrl b/lib/hipe/misc/hipe_sdi.hrl
index f89cae1529..f697f9d9dd 100644
--- a/lib/hipe/misc/hipe_sdi.hrl
+++ b/lib/hipe/misc/hipe_sdi.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/Makefile b/lib/hipe/opt/Makefile
index a21c543574..76191bc48d 100644
--- a/lib/hipe/opt/Makefile
+++ b/lib/hipe/opt/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/opt/hipe_schedule.erl b/lib/hipe/opt/hipe_schedule.erl
index 4f153e17ad..59b3e4e5e9 100644
--- a/lib/hipe/opt/hipe_schedule.erl
+++ b/lib/hipe/opt/hipe_schedule.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_schedule_prio.erl b/lib/hipe/opt/hipe_schedule_prio.erl
index 4d078b007d..34e2c03950 100644
--- a/lib/hipe/opt/hipe_schedule_prio.erl
+++ b/lib/hipe/opt/hipe_schedule_prio.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_spillmin.erl b/lib/hipe/opt/hipe_spillmin.erl
index df885a7dff..d338ea1b34 100644
--- a/lib/hipe/opt/hipe_spillmin.erl
+++ b/lib/hipe/opt/hipe_spillmin.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_spillmin_color.erl b/lib/hipe/opt/hipe_spillmin_color.erl
index 11a281100b..6c87bad142 100644
--- a/lib/hipe/opt/hipe_spillmin_color.erl
+++ b/lib/hipe/opt/hipe_spillmin_color.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_spillmin_scan.erl b/lib/hipe/opt/hipe_spillmin_scan.erl
index c58906c389..c24dd6d394 100644
--- a/lib/hipe/opt/hipe_spillmin_scan.erl
+++ b/lib/hipe/opt/hipe_spillmin_scan.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_target_machine.erl b/lib/hipe/opt/hipe_target_machine.erl
index be9f095429..6f5befb5e2 100644
--- a/lib/hipe/opt/hipe_target_machine.erl
+++ b/lib/hipe/opt/hipe_target_machine.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_ultra_mod2.erl b/lib/hipe/opt/hipe_ultra_mod2.erl
index b039eaee80..5720e56bcb 100644
--- a/lib/hipe/opt/hipe_ultra_mod2.erl
+++ b/lib/hipe/opt/hipe_ultra_mod2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/opt/hipe_ultra_prio.erl b/lib/hipe/opt/hipe_ultra_prio.erl
index 9e2c1a0489..67612a66f0 100644
--- a/lib/hipe/opt/hipe_ultra_prio.erl
+++ b/lib/hipe/opt/hipe_ultra_prio.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/Makefile b/lib/hipe/ppc/Makefile
index 8bd2a8226c..1687308bd2 100644
--- a/lib/hipe/ppc/Makefile
+++ b/lib/hipe/ppc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/ppc/hipe_ppc.erl b/lib/hipe/ppc/hipe_ppc.erl
index 4014fc1561..c7902b0688 100644
--- a/lib/hipe/ppc/hipe_ppc.erl
+++ b/lib/hipe/ppc/hipe_ppc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc.hrl b/lib/hipe/ppc/hipe_ppc.hrl
index 25e7ae0b5f..343b90ea7f 100644
--- a/lib/hipe/ppc/hipe_ppc.hrl
+++ b/lib/hipe/ppc/hipe_ppc.hrl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/ppc/hipe_ppc_assemble.erl b/lib/hipe/ppc/hipe_ppc_assemble.erl
index 3ad91f4051..00f28d60e4 100644
--- a/lib/hipe/ppc/hipe_ppc_assemble.erl
+++ b/lib/hipe/ppc/hipe_ppc_assemble.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -49,7 +50,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
DataRelocs = hipe_pack_constants:mk_data_relocs(RefsFromConsts, LabelMap),
SSE = hipe_pack_constants:slim_sorted_exportmap(ExportMap,Closures,Exports),
SlimRefs = hipe_pack_constants:slim_refs(AccRefs),
- Bin = term_to_binary([{?VERSION_STRING(),?HIPE_SYSTEM_CRC},
+ Bin = term_to_binary([{?VERSION_STRING(),?HIPE_ERTS_CHECKSUM},
ConstAlign, ConstSize,
SC,
DataRelocs, % nee LM, LabelMap
diff --git a/lib/hipe/ppc/hipe_ppc_cfg.erl b/lib/hipe/ppc/hipe_ppc_cfg.erl
index 13a7754831..7e96654817 100644
--- a/lib/hipe/ppc/hipe_ppc_cfg.erl
+++ b/lib/hipe/ppc/hipe_ppc_cfg.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_defuse.erl b/lib/hipe/ppc/hipe_ppc_defuse.erl
index 03a8f82abf..7cea60450a 100644
--- a/lib/hipe/ppc/hipe_ppc_defuse.erl
+++ b/lib/hipe/ppc/hipe_ppc_defuse.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_encode.erl b/lib/hipe/ppc/hipe_ppc_encode.erl
index 97cb0bf635..52ad53f66c 100644
--- a/lib/hipe/ppc/hipe_ppc_encode.erl
+++ b/lib/hipe/ppc/hipe_ppc_encode.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/ppc/hipe_ppc_finalise.erl b/lib/hipe/ppc/hipe_ppc_finalise.erl
index c4b9526fec..cc83282e31 100644
--- a/lib/hipe/ppc/hipe_ppc_finalise.erl
+++ b/lib/hipe/ppc/hipe_ppc_finalise.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_frame.erl b/lib/hipe/ppc/hipe_ppc_frame.erl
index 8a4d1906c0..2c2a09e3f6 100644
--- a/lib/hipe/ppc/hipe_ppc_frame.erl
+++ b/lib/hipe/ppc/hipe_ppc_frame.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_all.erl b/lib/hipe/ppc/hipe_ppc_liveness_all.erl
index c9234e8100..6a86dd3433 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_all.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_all.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl b/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
index ff9db21e2b..1b10227be9 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl b/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
index a55052b944..ca420b9f12 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_main.erl b/lib/hipe/ppc/hipe_ppc_main.erl
index 1d84f6db11..2336fdeaef 100644
--- a/lib/hipe/ppc/hipe_ppc_main.erl
+++ b/lib/hipe/ppc/hipe_ppc_main.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_pp.erl b/lib/hipe/ppc/hipe_ppc_pp.erl
index f88e922808..9233c666e3 100644
--- a/lib/hipe/ppc/hipe_ppc_pp.erl
+++ b/lib/hipe/ppc/hipe_ppc_pp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_ra.erl b/lib/hipe/ppc/hipe_ppc_ra.erl
index 3de7f48de1..e3b9617d82 100644
--- a/lib/hipe/ppc/hipe_ppc_ra.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_ra_finalise.erl b/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
index 53f8b739c2..168723d8a6 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_ra_ls.erl b/lib/hipe/ppc/hipe_ppc_ra_ls.erl
index 0b5d915ee8..f99c063655 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_ls.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_ls.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/ppc/hipe_ppc_ra_naive.erl b/lib/hipe/ppc/hipe_ppc_ra_naive.erl
index f0ca41b49e..7f66862d30 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_naive.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_naive.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl b/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
index 142bce39cc..26e0bba682 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl b/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
index 889c5681ac..ad8a5320fb 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_ppc_registers.erl b/lib/hipe/ppc/hipe_ppc_registers.erl
index 74aeab3df4..e8301cb244 100644
--- a/lib/hipe/ppc/hipe_ppc_registers.erl
+++ b/lib/hipe/ppc/hipe_ppc_registers.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ppc/hipe_rtl_to_ppc.erl b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
index a55fc137c3..998eefc922 100644
--- a/lib/hipe/ppc/hipe_rtl_to_ppc.erl
+++ b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% 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%
%%%
diff --git a/lib/hipe/regalloc/Makefile b/lib/hipe/regalloc/Makefile
index d4be79ea85..0442d1e07e 100644
--- a/lib/hipe/regalloc/Makefile
+++ b/lib/hipe/regalloc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/regalloc/hipe_adj_list.erl b/lib/hipe/regalloc/hipe_adj_list.erl
index b55b22cb22..c6c41f370f 100644
--- a/lib/hipe/regalloc/hipe_adj_list.erl
+++ b/lib/hipe/regalloc/hipe_adj_list.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_amd64_specific.erl b/lib/hipe/regalloc/hipe_amd64_specific.erl
index 91a8c7253a..5a3b52191a 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
index 5654455b44..656fc23a72 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_x87.erl b/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
index b5e8253ae1..0a06199909 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_arm_specific.erl b/lib/hipe/regalloc/hipe_arm_specific.erl
index 246095e926..f24171deab 100644
--- a/lib/hipe/regalloc/hipe_arm_specific.erl
+++ b/lib/hipe/regalloc/hipe_arm_specific.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
index e231098e0a..dd4960f255 100644
--- a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
index 6ba4ac814e..ddd4ab431d 100644
--- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_ig.erl b/lib/hipe/regalloc/hipe_ig.erl
index 4991e73e53..25d4cb0441 100644
--- a/lib/hipe/regalloc/hipe_ig.erl
+++ b/lib/hipe/regalloc/hipe_ig.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_ig_moves.erl b/lib/hipe/regalloc/hipe_ig_moves.erl
index ebc6ebc20d..c18eedbd16 100644
--- a/lib/hipe/regalloc/hipe_ig_moves.erl
+++ b/lib/hipe/regalloc/hipe_ig_moves.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_ls_regalloc.erl b/lib/hipe/regalloc/hipe_ls_regalloc.erl
index 7a00a0534a..b3a2668a09 100644
--- a/lib/hipe/regalloc/hipe_ls_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_ls_regalloc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_moves.erl b/lib/hipe/regalloc/hipe_moves.erl
index afec4aa4ce..644d731861 100644
--- a/lib/hipe/regalloc/hipe_moves.erl
+++ b/lib/hipe/regalloc/hipe_moves.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_node_sets.erl b/lib/hipe/regalloc/hipe_node_sets.erl
index be43ff2bfd..ca36f2d591 100644
--- a/lib/hipe/regalloc/hipe_node_sets.erl
+++ b/lib/hipe/regalloc/hipe_node_sets.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
index 0278a896d2..c996d9c285 100644
--- a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_ppc_specific.erl b/lib/hipe/regalloc/hipe_ppc_specific.erl
index dd2855208b..9e9be64fb4 100644
--- a/lib/hipe/regalloc/hipe_ppc_specific.erl
+++ b/lib/hipe/regalloc/hipe_ppc_specific.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_ppc_specific_fp.erl b/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
index 35623e7994..b1e3440fb0 100644
--- a/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
+++ b/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_reg_worklists.erl b/lib/hipe/regalloc/hipe_reg_worklists.erl
index 897bf0ef77..6e0770caa7 100644
--- a/lib/hipe/regalloc/hipe_reg_worklists.erl
+++ b/lib/hipe/regalloc/hipe_reg_worklists.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-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.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/regalloc/hipe_regalloc_loop.erl b/lib/hipe/regalloc/hipe_regalloc_loop.erl
index 428a82c87b..4b01d714c3 100644
--- a/lib/hipe/regalloc/hipe_regalloc_loop.erl
+++ b/lib/hipe/regalloc/hipe_regalloc_loop.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/regalloc/hipe_sparc_specific.erl b/lib/hipe/regalloc/hipe_sparc_specific.erl
index 7b8c62e802..460d89c342 100644
--- a/lib/hipe/regalloc/hipe_sparc_specific.erl
+++ b/lib/hipe/regalloc/hipe_sparc_specific.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
index 8a27f84e67..df10b2ee73 100644
--- a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
+++ b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_spillcost.erl b/lib/hipe/regalloc/hipe_spillcost.erl
index 04b25f6339..27ce6515ef 100644
--- a/lib/hipe/regalloc/hipe_spillcost.erl
+++ b/lib/hipe/regalloc/hipe_spillcost.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_spillcost.hrl b/lib/hipe/regalloc/hipe_spillcost.hrl
index e736a561d7..c1a3cbb550 100644
--- a/lib/hipe/regalloc/hipe_spillcost.hrl
+++ b/lib/hipe/regalloc/hipe_spillcost.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_temp_map.erl b/lib/hipe/regalloc/hipe_temp_map.erl
index 85678edd54..d9b9162e48 100644
--- a/lib/hipe/regalloc/hipe_temp_map.erl
+++ b/lib/hipe/regalloc/hipe_temp_map.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_x86_specific.erl b/lib/hipe/regalloc/hipe_x86_specific.erl
index 0f490ba14d..7c76fcc796 100644
--- a/lib/hipe/regalloc/hipe_x86_specific.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/regalloc/hipe_x86_specific_x87.erl b/lib/hipe/regalloc/hipe_x86_specific_x87.erl
index 7fd80b63d8..c4ab1ecef0 100644
--- a/lib/hipe/regalloc/hipe_x86_specific_x87.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific_x87.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile
index 751e87636a..1bf52fe312 100644
--- a/lib/hipe/rtl/Makefile
+++ b/lib/hipe/rtl/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -74,7 +75,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
include ../native.mk
-ERL_COMPILE_FLAGS += +inline +warn_unused_import +warn_exported_vars
+ERL_COMPILE_FLAGS += -Werror +inline +warn_unused_import +warn_exported_vars
# ----------------------------------------------------
# Targets
diff --git a/lib/hipe/rtl/hipe_icode2rtl.erl b/lib/hipe/rtl/hipe_icode2rtl.erl
index 483d0b37f7..d809f9ac20 100644
--- a/lib/hipe/rtl/hipe_icode2rtl.erl
+++ b/lib/hipe/rtl/hipe_icode2rtl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index 2f62dd79ad..6e27daeedf 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl.hrl b/lib/hipe/rtl/hipe_rtl.hrl
index fbdf9ac524..eaa2d20ac8 100644
--- a/lib/hipe/rtl/hipe_rtl.hrl
+++ b/lib/hipe/rtl/hipe_rtl.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl
index 99eb80f3d1..4b4ce396c4 100644
--- a/lib/hipe/rtl/hipe_rtl_arch.erl
+++ b/lib/hipe/rtl/hipe_rtl_arch.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc
index 1d13e59420..1dff56b074 100644
--- a/lib/hipe/rtl/hipe_rtl_arith.inc
+++ b/lib/hipe/rtl/hipe_rtl_arith.inc
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2004-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -29,13 +30,13 @@
%% Returns a tuple
%% {Res, Sign, Zero, Overflow, Carry}
%% Res will be a number in the range
-%% MAX_SIGNED_INT >= Res >= MIN_SIGNED_INT
+%% MAX_UNSIGNED_INT >= Res >= 0
%% The other four values are flags that are either true or false
%%
eval_alu(Op, Arg1, Arg2)
- when Arg1 =< ?MAX_SIGNED_INT,
+ when Arg1 =< ?MAX_UNSIGNED_INT,
Arg1 >= ?MIN_SIGNED_INT,
- Arg2 =< ?MAX_SIGNED_INT,
+ Arg2 =< ?MAX_UNSIGNED_INT,
Arg2 >= ?MIN_SIGNED_INT ->
Sign1 = sign_bit(Arg1),
@@ -110,7 +111,7 @@ eval_alu(Op, Arg1, Arg2)
Res = N = Z = V = C = 0,
?EXIT({"unknown alu op", Op})
end,
- {two_comp_to_erl(Res), N, Z, V, C};
+ {Res, N, Z, V, C};
eval_alu(Op, Arg1, Arg2) ->
?EXIT({argument_overflow,Op,Arg1,Arg2}).
@@ -161,16 +162,9 @@ eval_cond(Cond, Arg1, Arg2) ->
sign_bit(Val) ->
((Val bsr ?SIGN_BIT) band 1) =:= 1.
-two_comp_to_erl(V) ->
- if V > ?MAX_SIGNED_INT ->
- - ((?MAX_UNSIGNED_INT + 1) - V);
- true -> V
- end.
-
shiftmask(Arg) ->
Setbits = ?BITS - Arg,
(1 bsl Setbits) - 1.
zero(Val) ->
Val =:= 0.
-
diff --git a/lib/hipe/rtl/hipe_rtl_arith_32.erl b/lib/hipe/rtl/hipe_rtl_arith_32.erl
index a8a6043cda..d790a8b981 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_32.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_32.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -23,7 +24,8 @@
%% Filename : hipe_rtl_arith_32.erl
%% Module : hipe_rtl_arith_32
%% Purpose : To implement 32-bit RTL-arithmetic
-%% Notes : The arithmetic works on 32-bit signed integers.
+%% Notes : The arithmetic works on 32-bit signed and unsigned
+%% integers.
%% The implementation is taken from the implementation
%% of arithmetic on SPARC.
%% XXX: This code is seldom used, and hence also
diff --git a/lib/hipe/rtl/hipe_rtl_arith_64.erl b/lib/hipe/rtl/hipe_rtl_arith_64.erl
index d0d576b65e..d1566973ff 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_64.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_64.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_binary.erl b/lib/hipe/rtl/hipe_rtl_binary.erl
index 5ea51acedb..9cbab08ee2 100644
--- a/lib/hipe/rtl/hipe_rtl_binary.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary.erl
@@ -1,18 +1,20 @@
+%% -*- erlang-indent-level: 2 -*-
%%%
%%% %CopyrightBegin%
%%%
%%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
@@ -27,11 +29,20 @@
-export([gen_rtl/7]).
+-export([floorlog2/1, get_word_integer/4, make_size/3, make_size/4]).
+
+%%--------------------------------------------------------------------
+
+-define(BYTE_SHIFT, 3). %% Turn bits into bytes or vice versa
+-define(BYTE_SIZE, 8).
+
+%%--------------------------------------------------------------------
+
gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SysLimName, ConstTab) ->
case type_of_operation(BsOP) of
match ->
{hipe_rtl_binary_match:gen_rtl(
- BsOP, Dst, Args, TrueLblName, FalseLblName),ConstTab};
+ BsOP, Dst, Args, TrueLblName, FalseLblName),ConstTab};
construct ->
hipe_rtl_binary_construct:gen_rtl(
BsOP, Dst, Args, TrueLblName, FalseLblName, SysLimName, ConstTab)
@@ -61,7 +72,7 @@ type_of_operation({bs_init,_,_}) -> construct;
type_of_operation({bs_init_bits,_}) -> construct;
type_of_operation({bs_init_bits,_,_}) -> construct;
type_of_operation({bs_put_binary,_,_}) -> construct;
-type_of_operation({bs_put_binary_all,_}) -> construct;
+type_of_operation({bs_put_binary_all,_,_}) -> construct;
type_of_operation({bs_put_float,_,_,_}) -> construct;
type_of_operation({bs_put_integer,_,_,_}) -> construct;
type_of_operation({bs_put_string,_,_}) -> construct;
@@ -78,3 +89,133 @@ type_of_operation(bs_final) -> construct;
type_of_operation({bs_append,_,_,_,_}) -> construct;
type_of_operation({bs_private_append,_,_}) -> construct;
type_of_operation(bs_init_writable) -> construct.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Small utility functions:
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+create_lbls(X) when X > 0 ->
+ [hipe_rtl:mk_new_label()|create_lbls(X-1)];
+create_lbls(0) ->
+ [].
+
+%%------------------------------------------------------------------------------
+%% Utilities used by both hipe_rtl_binary_construct and hipe_rtl_binary_match
+%%------------------------------------------------------------------------------
+
+get_word_integer(Var, Register, SystemLimitLblName, FalseLblName) ->
+ [EndLbl] = create_lbls(1),
+ EndName = hipe_rtl:label_name(EndLbl),
+ get_word_integer(Var, Register,SystemLimitLblName, FalseLblName, EndName, EndName,
+ [EndLbl]).
+
+get_word_integer(Var, Register, SystemLimitLblName, FalseLblName, TrueLblName,
+ BigLblName, Tail) ->
+ [FixnumLbl, NotFixnumLbl, BignumLbl, SuccessLbl] = create_lbls(4),
+ [hipe_tagscheme:test_fixnum(Var, hipe_rtl:label_name(FixnumLbl),
+ hipe_rtl:label_name(NotFixnumLbl), 0.99),
+ FixnumLbl,
+ hipe_tagscheme:fixnum_ge(Var, hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(0)),
+ hipe_rtl:label_name(SuccessLbl), FalseLblName,
+ 0.99),
+ SuccessLbl,
+ hipe_tagscheme:untag_fixnum(Register, Var),
+ hipe_rtl:mk_goto(TrueLblName),
+ NotFixnumLbl,
+ hipe_tagscheme:test_pos_bignum_arity(Var, 1, hipe_rtl:label_name(BignumLbl),
+ FalseLblName, SystemLimitLblName, 0.99),
+ BignumLbl,
+ hipe_tagscheme:unsafe_get_one_word_pos_bignum(Register, Var),
+ hipe_rtl:mk_goto(BigLblName) | Tail].
+
+make_size(UnitImm, BitsVar, FailLblName) ->
+ make_size(UnitImm, BitsVar, FailLblName, FailLblName).
+
+make_size(1, BitsVar, OverflowLblName, FalseLblName) ->
+ DstReg = hipe_rtl:mk_new_reg_gcsafe(),
+ {get_word_integer(BitsVar, DstReg, OverflowLblName, FalseLblName), DstReg};
+make_size(?BYTE_SIZE, BitsVar, OverflowLblName, FalseLblName) ->
+ DstReg = hipe_rtl:mk_new_reg_gcsafe(),
+ [FixnumLbl, BignumLbl] = create_lbls(2),
+ WordBits = hipe_rtl_arch:word_size() * ?BYTE_SIZE,
+ FixnumLblName = hipe_rtl:label_name(FixnumLbl),
+ Tail = [BignumLbl,
+ hipe_rtl:mk_branch(DstReg, 'ltu',
+ hipe_rtl:mk_imm(1 bsl (WordBits - ?BYTE_SHIFT)),
+ FixnumLblName, OverflowLblName, 0.99),
+ FixnumLbl,
+ hipe_rtl:mk_alu(DstReg, DstReg, sll, hipe_rtl:mk_imm(?BYTE_SHIFT))],
+ Code = get_word_integer(BitsVar, DstReg, OverflowLblName, FalseLblName,
+ FixnumLblName, hipe_rtl:label_name(BignumLbl), Tail),
+ {Code, DstReg};
+make_size(UnitImm, BitsVar, OverflowLblName, FalseLblName) ->
+ DstReg = hipe_rtl:mk_new_reg_gcsafe(),
+ UnitList = number2list(UnitImm),
+ Code = multiply_code(UnitList, BitsVar, DstReg, OverflowLblName, FalseLblName),
+ {Code, DstReg}.
+
+multiply_code(List=[Head|_Tail], Variable, Result, OverflowLblName,
+ FalseLblName) ->
+ Test = set_high(Head),
+ Tmp1 = hipe_rtl:mk_new_reg(),
+ SuccessLbl = hipe_rtl:mk_new_label(),
+ Register = hipe_rtl:mk_new_reg(),
+ Code = [hipe_rtl:mk_move(Result, hipe_rtl:mk_imm(0))|
+ get_word_integer(Variable, Register, OverflowLblName, FalseLblName)]
+ ++
+ [hipe_rtl:mk_alub(Tmp1, Register, 'and', hipe_rtl:mk_imm(Test),
+ eq, hipe_rtl:label_name(SuccessLbl),
+ OverflowLblName, 0.99),
+ SuccessLbl],
+ multiply_code(List, Register, Result, OverflowLblName, Tmp1, Code).
+
+multiply_code([ShiftSize|Rest], Register, Result, OverflowLblName, Tmp1,
+ OldCode) ->
+ SuccessLbl = hipe_rtl:mk_new_label(),
+ Code =
+ OldCode ++
+ [hipe_rtl:mk_alu(Tmp1, Register, sll, hipe_rtl:mk_imm(ShiftSize)),
+ hipe_rtl:mk_alub(Result, Tmp1, 'add', Result, not_overflow,
+ hipe_rtl:label_name(SuccessLbl), OverflowLblName, 0.99),
+ SuccessLbl],
+ multiply_code(Rest, Register, Result, OverflowLblName, Tmp1, Code);
+multiply_code([], _Register, _Result, _OverflowLblName, _Tmp1, Code) ->
+ Code.
+
+set_high(X) ->
+ WordBits = hipe_rtl_arch:word_size() * ?BYTE_SIZE,
+ set_high(min(X, WordBits), WordBits, 0).
+
+set_high(0, _, Y) ->
+ Y;
+set_high(X, WordBits, Y) ->
+ set_high(X-1, WordBits, Y+(1 bsl (WordBits-X))).
+
+
+number2list(X) when is_integer(X), X >= 0 ->
+ number2list(X, []).
+
+number2list(1, Acc) ->
+ lists:reverse([0|Acc]);
+number2list(0, Acc) ->
+ lists:reverse(Acc);
+number2list(X, Acc) ->
+ F = floorlog2(X),
+ number2list(X-(1 bsl F), [F|Acc]).
+
+floorlog2(X) ->
+ %% Double-precision floats do not have enough precision to make floorlog2
+ %% exact for integers larger than 2^47.
+ Approx = round(math:log(X)/math:log(2)-0.5),
+ floorlog2_refine(X, Approx).
+
+floorlog2_refine(X, Approx) ->
+ if (1 bsl Approx) > X ->
+ floorlog2_refine(X, Approx - 1);
+ (1 bsl (Approx+1)) > X ->
+ Approx;
+ true ->
+ floorlog2_refine(X, Approx + 1)
+ end.
diff --git a/lib/hipe/rtl/hipe_rtl_binary_construct.erl b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
index 29993b9715..4403aa552f 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_construct.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -33,6 +34,10 @@
get_field_from_term/3,
set_field_from_pointer/3,
get_field_from_pointer/3]).
+
+-import(hipe_rtl_binary, [floorlog2/1,
+ get_word_integer/4,
+ make_size/4]).
%%-------------------------------------------------------------------------
-include("../main/hipe.hrl").
@@ -93,10 +98,11 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
var_init_bits(Size, Dst0, Base, Offset, TrueLblName,
SystemLimitLblName, FalseLblName);
- {bs_put_binary_all, _Flags} ->
+ {bs_put_binary_all, Unit, _Flags} ->
[Src, Base, Offset] = Args,
[NewOffset] = get_real(Dst),
- put_binary_all(NewOffset, Src, Base, Offset, TrueLblName, FalseLblName);
+ put_binary_all(NewOffset, Src, Base, Offset, Unit,
+ TrueLblName, FalseLblName);
{bs_put_binary, Size, _Flags} ->
case is_illegal_const(Size) of
@@ -109,7 +115,9 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
put_static_binary(NewOffset, Src, Size, Base, Offset,
TrueLblName, FalseLblName);
[Src, Bits, Base, Offset] ->
- {SizeCode, SizeReg} = make_size(Size, Bits, FalseLblName),
+ {SizeCode, SizeReg} = make_size(Size, Bits,
+ SystemLimitLblName,
+ FalseLblName),
InCode = put_dynamic_binary(NewOffset, Src, SizeReg, Base,
Offset, TrueLblName, FalseLblName),
SizeCode ++ InCode
@@ -131,7 +139,9 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
put_float(NewOffset, Src, Base, Offset, Size, CCode, Aligned,
LittleEndian, ConstInfo, TrueLblName);
[Src, Bits, Base, Offset] ->
- {SizeCode, SizeReg} = make_size(Size, Bits, FalseLblName),
+ {SizeCode, SizeReg} = make_size(Size, Bits,
+ SystemLimitLblName,
+ FalseLblName),
InCode = float_c_code(NewOffset, Src, Base, Offset, SizeReg,
Flags, TrueLblName, FalseLblName),
SizeCode ++ InCode
@@ -160,6 +170,7 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
CCode, Aligned, LittleEndian, TrueLblName);
[Src, Bits, Base, Offset] ->
{SizeCode, SizeReg} = make_size(Size, Bits,
+ SystemLimitLblName,
FalseLblName),
CCode = int_c_code(NewOffset, Src, Base,
Offset, SizeReg, Flags,
@@ -208,6 +219,7 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
TrueLblName);
[Src, Bits, Base, Offset] ->
{SizeCode, SizeReg} = make_size(Size, Bits,
+ SystemLimitLblName,
FalseLblName),
CCode = int_c_code(NewOffset, Src, Base,
Offset, SizeReg, Flags,
@@ -292,7 +304,7 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
[SizeReg] = create_regs(1),
[Base] = create_unsafe_regs(1),
[hipe_rtl:mk_gctest(?PROC_BIN_WORDSIZE + ?SUB_BIN_WORDSIZE),
- check_and_untag_fixnum(Size, SizeReg, FalseLblName),
+ get_word_integer(Size, SizeReg, SystemLimitLblName, FalseLblName),
allocate_writable(DstVar, Base, SizeReg, Zero, Zero),
hipe_rtl:mk_goto(TrueLblName)];
@@ -304,7 +316,7 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
SubBinSize = {sub_binary, binsize},
[get_field_from_term({sub_binary, orig}, Bin, ProcBin),
get_field_from_term(SubBinSize, Bin, SubSize),
- check_and_untag_fixnum(Size, SizeReg, FalseLblName),
+ get_word_integer(Size, SizeReg, SystemLimitLblName, FalseLblName),
realloc_binary(SizeReg, ProcBin, Base),
calculate_sizes(Bin, SizeReg, Offset, EndSubSize, EndSubBitSize),
set_field_from_term(SubBinSize, Bin, EndSubSize),
@@ -312,20 +324,21 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
hipe_rtl:mk_move(DstVar, Bin),
hipe_rtl:mk_goto(TrueLblName)];
- {bs_append, _U, _F, _B, _Bla} ->
+ {bs_append, _U, _F, Unit, _Bla} ->
[Size, Bin] = Args,
[DstVar, Base, Offset] = Dst,
[ProcBin] = create_vars(1),
[Flags, SizeReg, IsWritable, EndSubSize, EndSubBitSize] =
create_regs(5),
- [ContLbl,ContLbl2,ContLbl3,WritableLbl,NotWritableLbl] = Lbls =
- create_lbls(5),
- [ContLblName, ContLbl2Name, ContLbl3Name, Writable, NotWritable] =
+ [ContLbl,ContLbl2,ContLbl3,ContLbl4,WritableLbl,NotWritableLbl] =
+ Lbls = create_lbls(6),
+ [ContLblName, ContLbl2Name, ContLbl3Name, ContLbl4Name,
+ Writable, NotWritable] =
[hipe_rtl:label_name(Lbl) || Lbl <- Lbls],
Zero = hipe_rtl:mk_imm(0),
SubIsWritable = {sub_binary, is_writable},
[hipe_rtl:mk_gctest(?SUB_BIN_WORDSIZE + ?PROC_BIN_WORDSIZE),
- check_and_untag_fixnum(Size, SizeReg, FalseLblName),
+ get_word_integer(Size, SizeReg, SystemLimitLblName, FalseLblName),
hipe_tagscheme:test_bitstr(Bin, ContLblName, FalseLblName, 0.99),
ContLbl,
hipe_tagscheme:test_subbinary(Bin,ContLbl2Name, NotWritable),
@@ -338,17 +351,19 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
get_field_from_term({proc_bin, flags}, ProcBin, Flags),
hipe_rtl:mk_alub(Flags, Flags, 'and',
hipe_rtl:mk_imm(?PB_IS_WRITABLE),
- eq, NotWritable, Writable, 0.01),
+ eq, NotWritable, ContLbl4Name, 0.01),
+ ContLbl4,
+ calculate_sizes(Bin, SizeReg, Offset, EndSubSize, EndSubBitSize),
+ is_divisible(Offset, Unit, Writable, FalseLblName),
WritableLbl,
set_field_from_term(SubIsWritable, Bin, Zero),
realloc_binary(SizeReg, ProcBin, Base),
- calculate_sizes(Bin, SizeReg, Offset, EndSubSize, EndSubBitSize),
hipe_tagscheme:mk_sub_binary(DstVar, EndSubSize, Zero,
EndSubBitSize, Zero,
hipe_rtl:mk_imm(1), ProcBin),
hipe_rtl:mk_goto(TrueLblName),
NotWritableLbl,
- not_writable_code(Bin, SizeReg, DstVar, Base, Offset,
+ not_writable_code(Bin, SizeReg, DstVar, Base, Offset, Unit,
TrueLblName, FalseLblName)]
end,
{Code, ConstTab}
@@ -360,7 +375,7 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-not_writable_code(Bin, SizeReg, Dst, Base, Offset,
+not_writable_code(Bin, SizeReg, Dst, Base, Offset, Unit,
TrueLblName, FalseLblName) ->
[SrcBase] = create_unsafe_regs(1),
[SrcOffset, SrcSize, TotSize, TotBytes, UsedBytes] = create_regs(5),
@@ -371,13 +386,13 @@ not_writable_code(Bin, SizeReg, Dst, Base, Offset,
hipe_rtl:mk_alu(TotBytes, TotSize, add, ?LOW_BITS),
hipe_rtl:mk_alu(TotBytes, TotBytes, srl, ?BYTE_SHIFT),
hipe_rtl:mk_alu(UsedBytes, TotBytes, sll, hipe_rtl:mk_imm(1)),
- hipe_rtl:mk_branch(UsedBytes, ge, hipe_rtl:mk_imm(256),
+ hipe_rtl:mk_branch(UsedBytes, geu, hipe_rtl:mk_imm(256),
AllLblName, IncLblName),
IncLbl,
hipe_rtl:mk_move(UsedBytes, hipe_rtl:mk_imm(256)),
AllLbl,
allocate_writable(Dst, Base, UsedBytes, TotBytes, TotSize),
- put_binary_all(Offset, Bin, Base, hipe_rtl:mk_imm(0),
+ put_binary_all(Offset, Bin, Base, hipe_rtl:mk_imm(0), Unit,
TrueLblName, FalseLblName)].
allocate_writable(Dst, Base, UsedBytes, TotBytes, TotSize) ->
@@ -396,16 +411,6 @@ allocate_writable(Dst, Base, UsedBytes, TotBytes, TotSize) ->
hipe_tagscheme:mk_sub_binary(Dst, EndSubSize, Zero, EndSubBitSize,
Zero, hipe_rtl:mk_imm(1), ProcBin)].
-check_and_untag_fixnum(Size, SizeReg, FalseLblName) ->
- [ContLbl,NextLbl] = Lbls = create_lbls(2),
- [ContLblName,NextLblName] = get_label_names(Lbls),
- [hipe_tagscheme:test_fixnum(Size, ContLblName, FalseLblName, 0.99),
- ContLbl,
- hipe_tagscheme:untag_fixnum(SizeReg,Size),
- hipe_rtl:mk_branch(SizeReg, ge, hipe_rtl:mk_imm(0), NextLblName,
- FalseLblName),
- NextLbl].
-
realloc_binary(SizeReg, ProcBin, Base) ->
[NoReallocLbl, ReallocLbl, NextLbl, ContLbl] = Lbls = create_lbls(4),
[NoReallocLblName, ReallocLblName, NextLblName, ContLblName] =
@@ -427,7 +432,7 @@ realloc_binary(SizeReg, ProcBin, Base) ->
set_field_from_term(ProcBinFlagsTag, ProcBin, Flags),
get_field_from_term(ProcBinValTag, ProcBin, BinPointer),
get_field_from_pointer(BinOrigSizeTag, BinPointer, OrigSize),
- hipe_rtl:mk_branch(OrigSize, 'lt', ResultingSize,
+ hipe_rtl:mk_branch(OrigSize, 'ltu', ResultingSize,
ReallocLblName, NoReallocLblName),
NoReallocLbl,
get_field_from_term(ProcBinBytesTag, ProcBin, Base),
@@ -668,14 +673,14 @@ var_init2(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLblName
WordSize = hipe_rtl_arch:word_size(),
[ContLbl,HeapLbl,REFCLbl,NextLbl] = create_lbls(4),
[USize,Tmp] = create_unsafe_regs(2),
- [get_32_bit_value(Size, USize, SystemLimitLblName, FalseLblName),
- hipe_rtl:mk_branch(USize, le, hipe_rtl:mk_imm(?MAX_BINSIZE),
- hipe_rtl:label_name(ContLbl),
- SystemLimitLblName),
+ [get_word_integer(Size, USize, SystemLimitLblName, FalseLblName),
+ hipe_rtl:mk_branch(USize, leu, hipe_rtl:mk_imm(?MAX_BINSIZE),
+ hipe_rtl:label_name(ContLbl),
+ SystemLimitLblName),
ContLbl,
hipe_rtl:mk_move(Offset, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_branch(USize, le, hipe_rtl:mk_imm(?MAX_HEAP_BIN_SIZE),
- hipe_rtl:label_name(HeapLbl),
+ hipe_rtl:mk_branch(USize, leu, hipe_rtl:mk_imm(?MAX_HEAP_BIN_SIZE),
+ hipe_rtl:label_name(HeapLbl),
hipe_rtl:label_name(REFCLbl)),
HeapLbl,
hipe_rtl:mk_alu(Tmp, USize, add, hipe_rtl:mk_imm(3*WordSize-1)),
@@ -693,8 +698,8 @@ var_init2(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLblName
hipe_rtl:mk_goto(TrueLblName)].
var_init_bits(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLblName) ->
- [HeapLbl,REFCLbl,NextLbl,NoSubLbl,SubLbl,ContLbl,
- NoCreateSubBin, CreateSubBin, JoinLbl, JoinLbl2] = create_lbls(10),
+ [HeapLbl,REFCLbl,NextLbl,NoSubLbl,SubLbl,
+ NoCreateSubBin, CreateSubBin, JoinLbl, JoinLbl2] = create_lbls(9),
[USize,ByteSize,TotByteSize,OffsetBits] = create_regs(4),
[TmpDst] = create_unsafe_regs(1),
Log2WordSize = hipe_rtl_arch:log2_word_size(),
@@ -704,7 +709,7 @@ var_init_bits(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLbl
?PROC_BIN_WORDSIZE) + ?SUB_BIN_WORDSIZE,
Zero = hipe_rtl:mk_imm(0),
[hipe_rtl:mk_gctest(MaximumWords),
- get_32_bit_value(Size, USize, SystemLimitLblName, FalseLblName),
+ get_word_integer(Size, USize, SystemLimitLblName, FalseLblName),
hipe_rtl:mk_alu(ByteSize, USize, srl, ?BYTE_SHIFT),
hipe_rtl:mk_alub(OffsetBits, USize, 'and', ?LOW_BITS, eq,
hipe_rtl:label_name(NoSubLbl),
@@ -715,11 +720,7 @@ var_init_bits(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLbl
SubLbl,
hipe_rtl:mk_alu(TotByteSize, ByteSize, 'add', hipe_rtl:mk_imm(1)),
JoinLbl,
- hipe_rtl:mk_branch(USize, le, hipe_rtl:mk_imm(?MAX_BINSIZE),
- hipe_rtl:label_name(ContLbl),
- SystemLimitLblName),
- ContLbl,
- hipe_rtl:mk_branch(TotByteSize, 'le', hipe_rtl:mk_imm(?MAX_HEAP_BIN_SIZE),
+ hipe_rtl:mk_branch(TotByteSize, 'leu', hipe_rtl:mk_imm(?MAX_HEAP_BIN_SIZE),
hipe_rtl:label_name(HeapLbl),
hipe_rtl:label_name(REFCLbl)),
HeapLbl,
@@ -742,13 +743,16 @@ var_init_bits(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLbl
hipe_rtl:mk_move(Dst, TmpDst),
hipe_rtl:mk_goto(TrueLblName)].
-put_binary_all(NewOffset, Src, Base, Offset, TLName, FLName) ->
+put_binary_all(NewOffset, Src, Base, Offset, Unit, TLName, FLName) ->
[SrcBase,SrcOffset,NumBits] = create_regs(3),
+ [ContLbl] = create_lbls(1),
CCode = binary_c_code(NewOffset, Src, Base, Offset, NumBits, TLName),
AlignedCode = copy_aligned_bytes(SrcBase, SrcOffset, NumBits, Base, Offset,
NewOffset, TLName),
- get_base_offset_size(Src, SrcBase, SrcOffset, NumBits,FLName) ++
- test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode).
+ [get_base_offset_size(Src, SrcBase, SrcOffset, NumBits,FLName),
+ is_divisible(NumBits, Unit, hipe_rtl:label_name(ContLbl), FLName),
+ ContLbl
+ |test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode)].
test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode) ->
[Tmp] = create_regs(1),
@@ -975,7 +979,7 @@ copy_string(StringBase, StringSize, BinBase, BinOffset, NewOffset, TrueLblName)
small_check(SizeVar, CopySize, FalseLblName) ->
SuccessLbl = hipe_rtl:mk_new_label(),
- [hipe_rtl:mk_branch(SizeVar, le, CopySize,
+ [hipe_rtl:mk_branch(SizeVar, leu, CopySize,
hipe_rtl:label_name(SuccessLbl), FalseLblName),
SuccessLbl].
@@ -1191,7 +1195,10 @@ copy_little_word(Base, Offset, NewOffset, Word) ->
hipe_rtl:mk_store(Base, TmpOffset, Word, byte),
hipe_rtl:mk_alu(NewOffset, Offset, 'add', hipe_rtl:mk_imm(32))].
-copy_offset_int_big(Base, Offset, NewOffset, Size, Tmp1) when is_integer(Size) ->
+copy_offset_int_big(_Base, Offset, NewOffset, 0, _Tmp1) ->
+ [hipe_rtl:mk_move(NewOffset, Offset)];
+copy_offset_int_big(Base, Offset, NewOffset, Size, Tmp1)
+ when is_integer(Size), Size > 0 ->
Tmp2 = hipe_rtl:mk_new_reg(),
Tmp3 = hipe_rtl:mk_new_reg(),
Tmp4 = hipe_rtl:mk_new_reg(),
@@ -1202,7 +1209,7 @@ copy_offset_int_big(Base, Offset, NewOffset, Size, Tmp1) when is_integer(Size) -
Tmp9 = hipe_rtl:mk_new_reg(),
OldByte = hipe_rtl:mk_new_reg(),
TmpOffset = hipe_rtl:mk_new_reg(),
- BranchLbl = hipe_rtl:mk_new_label(),
+ BranchLbl = hipe_rtl:mk_new_label(),
BodyLbl = hipe_rtl:mk_new_label(),
EndLbl = hipe_rtl:mk_new_label(),
NextLbl = hipe_rtl:mk_new_label(),
@@ -1275,89 +1282,18 @@ copy_float_big(Base, Offset, NewOffset, Src, FalseLblName, TrueLblName, var) ->
hipe_tagscheme:test_flonum(Src, hipe_rtl:label_name(SuccessLbl), FalseLblName, 0.99) ++
[SuccessLbl|copy_float_big(Base, Offset, NewOffset, Src, FalseLblName, TrueLblName, pass)].
-make_size(1, BitsVar, FalseLblName) ->
- [DstReg] = create_regs(1),
- {first_part(BitsVar, DstReg, FalseLblName), DstReg};
-make_size(?BYTE_SIZE, BitsVar, FalseLblName) ->
- [DstReg] = create_regs(1),
- Code =
- first_part(BitsVar, DstReg, FalseLblName) ++
- [hipe_rtl:mk_alu(DstReg, DstReg, 'sll', ?BYTE_SHIFT)],
- {Code, DstReg};
-make_size(UnitImm, BitsVar, FalseLblName) ->
- [DstReg] = create_regs(1),
- UnitList = number2list(UnitImm),
- Code = multiply_code(UnitList, BitsVar, DstReg, FalseLblName),
- {Code, DstReg}.
-
-multiply_code(List=[Head|_Tail], Variable, Result, FalseLblName) ->
- Test = set_high(Head),
- Tmp1 = hipe_rtl:mk_new_reg(),
- SuccessLbl = hipe_rtl:mk_new_label(),
- Register = hipe_rtl:mk_new_reg(),
- Code = [hipe_rtl:mk_move(Result, hipe_rtl:mk_imm(0))|
- first_part(Variable, Register, FalseLblName)]
- ++
- [hipe_rtl:mk_alub(Tmp1, Register, 'and', hipe_rtl:mk_imm(Test),
- 'eq', hipe_rtl:label_name(SuccessLbl),
- FalseLblName, 0.99),
- SuccessLbl],
- multiply_code(List, Register, Result, FalseLblName, Tmp1, Code).
-
-multiply_code([ShiftSize|Rest], Register, Result, FalseLblName, Tmp1, OldCode) ->
- SuccessLbl = hipe_rtl:mk_new_label(),
- Code = OldCode ++ [hipe_rtl:mk_alu(Tmp1, Register, 'sll',
- hipe_rtl:mk_imm(ShiftSize)),
- hipe_rtl:mk_alub(Result, Tmp1, 'add', Result, not_overflow, hipe_rtl:label_name(SuccessLbl), FalseLblName, 0.99),
- SuccessLbl],
- multiply_code(Rest, Register, Result, FalseLblName, Tmp1, Code);
-multiply_code([], _Register, _Result, _FalseLblName, _Tmp1, Code) ->
- Code.
-
-number2list(X) when is_integer(X), X >= 0 ->
- number2list(X, []).
-
-number2list(1, Acc) ->
- lists:reverse([0|Acc]);
-number2list(0, Acc) ->
- lists:reverse(Acc);
-number2list(X, Acc) ->
- F = floorlog2(X),
- number2list(X-(1 bsl F), [F|Acc]).
-
-floorlog2(X) ->
- round(math:log(X)/math:log(2)-0.5).
-
-set_high(X) ->
- set_high(X, 0).
-
-set_high(0, Y) ->
- Y;
-set_high(X, Y) ->
- set_high(X-1, Y+(1 bsl (27-X))).
-
-get_32_bit_value(Size, USize, SystemLimitLblName, NegLblName) ->
- Lbls = [FixLbl, BigLbl, OkLbl, PosBigLbl] = create_lbls(4),
- [FixLblName, BigLblName, OkLblName, PosBigLblName] = [hipe_rtl:label_name(Lbl) || Lbl <- Lbls],
- [hipe_tagscheme:test_fixnum(Size, FixLblName, BigLblName, 0.99),
- FixLbl,
- hipe_tagscheme:untag_fixnum(USize, Size),
- hipe_rtl:mk_branch(USize, ge, hipe_rtl:mk_imm(0), OkLblName, NegLblName),
- BigLbl,
- hipe_tagscheme:test_pos_bignum(Size, PosBigLblName, NegLblName, 0.99),
- PosBigLbl,
- hipe_tagscheme:get_one_word_pos_bignum(USize, Size, SystemLimitLblName),
- OkLbl].
-
-
-first_part(Var, Register, FalseLblName) ->
- [SuccessLbl1, SuccessLbl2] = create_lbls(2),
- [hipe_tagscheme:test_fixnum(Var, hipe_rtl:label_name(SuccessLbl1),
- FalseLblName, 0.99),
- SuccessLbl1,
- hipe_tagscheme:fixnum_ge(Var, hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(0)),
- hipe_rtl:label_name(SuccessLbl2), FalseLblName, 0.99),
- SuccessLbl2,
- hipe_tagscheme:untag_fixnum(Register, Var)].
-
-
+is_divisible(_Dividend, 1, SuccLbl, _FailLbl) ->
+ [hipe_rtl:mk_goto(SuccLbl)];
+is_divisible(Dividend, Divisor, SuccLbl, FailLbl) ->
+ Log2 = floorlog2(Divisor),
+ case Divisor =:= 1 bsl Log2 of
+ 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)];
+ false ->
+ %% We need division, fall back to a primop
+ [hipe_rtl:mk_call([], is_divisible, [Dividend, hipe_rtl:mk_imm(Divisor)],
+ SuccLbl, FailLbl, not_remote)]
+ end.
diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl
index af8903904b..be4c35dae0 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_match.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl
@@ -2,18 +2,19 @@
%%%
%%% %CopyrightBegin%
%%%
-%%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
@@ -30,11 +31,12 @@
-import(hipe_tagscheme, [set_field_from_term/3, get_field_from_term/3]).
+-import(hipe_rtl_binary, [make_size/3]).
+
-include("hipe_literals.hrl").
%%--------------------------------------------------------------------
--define(MAX_BINSIZE, trunc(?MAX_HEAP_BIN_SIZE / hipe_rtl_arch:word_size()) + 2).
-define(BYTE_SHIFT, 3). %% Turn bits into bytes or vice versa
-define(LOW_BITS, 7). %% Three lowest bits set
-define(BYTE_SIZE, 8).
@@ -180,17 +182,20 @@ gen_rtl({bs_get_binary, Size, Flags}, [Dst, NewMs], Args,
[hipe_rtl:mk_goto(FalseLblName)];
false ->
Unsafe = unsafe(Flags),
- case Args of
- [Ms] ->
- SizeReg = hipe_rtl:mk_new_reg(),
- SizeCode = [hipe_rtl:mk_move(SizeReg, hipe_rtl:mk_imm(Size))];
- [Ms, BitsVar] ->
- {SizeCode, SizeReg} = make_size(Size, BitsVar, FalseLblName)
- end,
- InCode = get_binary(Dst, Ms, SizeReg, Unsafe,
+ {OldMs, SizeReg, SizeCode} =
+ case Args of
+ [Ms] ->
+ SzReg = hipe_rtl:mk_new_reg(),
+ SzCode = [hipe_rtl:mk_move(SzReg, hipe_rtl:mk_imm(Size))],
+ {Ms, SzReg, SzCode};
+ [Ms, BitsVar] ->
+ {SzCode, SzReg} = make_size(Size, BitsVar, FalseLblName),
+ {Ms, SzReg, SzCode}
+ end,
+ InCode = get_binary(Dst, OldMs, SizeReg, Unsafe,
TrueLblName, FalseLblName),
[hipe_rtl:mk_gctest(?SUB_BIN_WORDSIZE)] ++
- update_ms(NewMs, Ms) ++ SizeCode ++ InCode
+ update_ms(NewMs, OldMs) ++ SizeCode ++ InCode
end;
%% ----- bs_get_utf8 -----
gen_rtl(bs_get_utf8, [Dst, NewMs], [Ms], TrueLblName, FalseLblName) ->
@@ -229,14 +234,26 @@ gen_rtl({bs_skip_bits_all, Unit, _Flags}, Dst, [Ms],
skip_bits_all(Unit, Ms, TrueLblName, FalseLblName);
%% ----- bs_skip_bits -----
gen_rtl({bs_skip_bits, Bits}, Dst, [Ms|Args], TrueLblName, FalseLblName) ->
+ MaxValue = (1 bsl (hipe_rtl_arch:word_size() * ?BYTE_SIZE)),
opt_update_ms(Dst, Ms) ++
- case Args of
- [] ->
- skip_bits2(Ms, hipe_rtl:mk_imm(Bits), TrueLblName, FalseLblName);
- [Arg] ->
- {SizeCode, SizeReg} = make_size(Bits, Arg, FalseLblName),
- InCode = skip_bits2(Ms, SizeReg, TrueLblName, FalseLblName),
- SizeCode ++ InCode
+ case Bits < MaxValue of
+ true ->
+ case Args of
+ [] ->
+ skip_bits2(Ms, hipe_rtl:mk_imm(Bits), TrueLblName, FalseLblName);
+ [Arg] ->
+ {SizeCode, SizeReg} = make_size(Bits, Arg, FalseLblName),
+ InCode = skip_bits2(Ms, SizeReg, TrueLblName, FalseLblName),
+ SizeCode ++ InCode
+ end;
+ false -> % handle overflow case
+ case Args of
+ [] ->
+ [hipe_rtl:mk_goto(FalseLblName)];
+ [Arg] ->
+ [hipe_rtl:mk_branch(Arg, 'eq', hipe_tagscheme:mk_fixnum(0),
+ TrueLblName, FalseLblName, 0.5)]
+ end
end;
%% ----- bs_restore -----
gen_rtl({bs_restore, Slot}, [NewMs], [Ms], TrueLblName, _FalseLblName) ->
@@ -317,32 +334,50 @@ float_get_c_code(Dst1, Ms, Size, Flags, TrueLblName, FalseLblName) ->
get_c_code(Func, Dst1, Ms, Size, Flags, TrueLblName, FalseLblName) ->
SizeReg = hipe_rtl:mk_new_reg_gcsafe(),
FlagsReg = hipe_rtl:mk_new_reg_gcsafe(),
+ RetReg = hipe_rtl:mk_new_reg_gcsafe(),
MatchBuf = hipe_rtl:mk_new_reg(),
RetLabel = hipe_rtl:mk_new_label(),
+ OkLabel = hipe_rtl:mk_new_label(),
NonVal = hipe_rtl:mk_imm(hipe_tagscheme:mk_non_value()),
[hipe_rtl:mk_move(SizeReg, Size),
hipe_rtl:mk_move(FlagsReg, hipe_rtl:mk_imm(Flags)),
hipe_tagscheme:extract_matchbuffer(MatchBuf, Ms),
- hipe_rtl_arch:call_bif([Dst1], Func, [SizeReg, FlagsReg, MatchBuf],
+ hipe_rtl_arch:call_bif([RetReg], Func, [SizeReg, FlagsReg, MatchBuf],
hipe_rtl:label_name(RetLabel), FalseLblName),
RetLabel,
- hipe_rtl:mk_branch(Dst1, eq, NonVal, FalseLblName, TrueLblName, 0.01)].
+ hipe_rtl:mk_branch(RetReg, eq, NonVal, FalseLblName,
+ hipe_rtl:label_name(OkLabel), 0.01),
+ OkLabel,
+ hipe_rtl:mk_move(Dst1, RetReg),
+ hipe_rtl:mk_goto(TrueLblName)].
utf8_get_c_code(Dst, Ms, TrueLblName, FalseLblName) ->
+ RetReg = hipe_rtl:mk_new_reg_gcsafe(),
+ OkLabel = hipe_rtl:mk_new_label(),
MatchBuf = hipe_rtl:mk_new_reg(),
NonVal = hipe_rtl:mk_imm(hipe_tagscheme:mk_non_value()),
[hipe_tagscheme:extract_matchbuffer(MatchBuf, Ms),
- hipe_rtl_arch:call_bif([Dst], bs_get_utf8, [MatchBuf], [], []),
- hipe_rtl:mk_branch(Dst, eq, NonVal, FalseLblName, TrueLblName, 0.01)].
+ hipe_rtl_arch:call_bif([RetReg], bs_get_utf8, [MatchBuf], [], []),
+ hipe_rtl:mk_branch(RetReg, eq, NonVal, FalseLblName,
+ hipe_rtl:label_name(OkLabel), 0.01),
+ OkLabel,
+ hipe_rtl:mk_move(Dst, RetReg),
+ hipe_rtl:mk_goto(TrueLblName)].
utf16_get_c_code(Flags, Dst, Ms, TrueLblName, FalseLblName) ->
+ RetReg = hipe_rtl:mk_new_reg_gcsafe(),
+ OkLabel = hipe_rtl:mk_new_label(),
MatchBuf = hipe_rtl:mk_new_reg(),
NonVal = hipe_rtl:mk_imm(hipe_tagscheme:mk_non_value()),
FlagsReg = hipe_rtl:mk_new_reg_gcsafe(),
[hipe_tagscheme:extract_matchbuffer(MatchBuf, Ms),
hipe_rtl:mk_move(FlagsReg, hipe_rtl:mk_imm(Flags)),
- hipe_rtl_arch:call_bif([Dst], bs_get_utf16, [MatchBuf, FlagsReg], [], []),
- hipe_rtl:mk_branch(Dst, eq, NonVal, FalseLblName, TrueLblName, 0.01)].
+ hipe_rtl_arch:call_bif([RetReg], bs_get_utf16, [MatchBuf, FlagsReg], [], []),
+ hipe_rtl:mk_branch(RetReg, eq, NonVal, FalseLblName,
+ hipe_rtl:label_name(OkLabel), 0.01),
+ OkLabel,
+ hipe_rtl:mk_move(Dst, RetReg),
+ hipe_rtl:mk_goto(TrueLblName)].
validate_unicode_retract_c_code(Src, Ms, TrueLblName, FalseLblName) ->
MatchBuf = hipe_rtl:mk_new_reg(),
@@ -697,13 +732,22 @@ get_binary_bytes(Binary, BinSize, Base, Offset, Orig,
%%%%%%%%%%%%%%%%%%%%%%%%% UTILS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_base(Orig,Base) ->
- [HeapLbl,REFCLbl,EndLbl] = create_lbls(3),
+ [HeapLbl,REFCLbl,WritableLbl,NotWritableLbl,EndLbl] = create_lbls(5),
+ Flags = hipe_rtl:mk_new_reg_gcsafe(),
+
[hipe_tagscheme:test_heap_binary(Orig, hipe_rtl:label_name(HeapLbl),
hipe_rtl:label_name(REFCLbl)),
HeapLbl,
hipe_rtl:mk_alu(Base, Orig, 'add', hipe_rtl:mk_imm(?HEAP_BIN_DATA-2)),
hipe_rtl:mk_goto(hipe_rtl:label_name(EndLbl)),
REFCLbl,
+ get_field_from_term({proc_bin, flags}, Orig, Flags),
+ hipe_rtl:mk_branch(Flags, 'ne', hipe_rtl:mk_imm(0),
+ hipe_rtl:label_name(WritableLbl),
+ hipe_rtl:label_name(NotWritableLbl)),
+ WritableLbl,
+ hipe_rtl:mk_call([], emasculate_binary, [Orig], [], [], 'not_remote'),
+ NotWritableLbl,
hipe_rtl:mk_load(Base, Orig, hipe_rtl:mk_imm(?PROC_BIN_BYTES-2)),
EndLbl].
@@ -792,10 +836,10 @@ create_lbls(0) ->
create_lbls(X) when X > 0 ->
[hipe_rtl:mk_new_label()|create_lbls(X-1)].
-make_dyn_prep(SizeReg, CCode) ->
+make_dyn_prep(SizeReg, CCode) ->
[CLbl, SuccessLbl] = create_lbls(2),
- Init = [hipe_rtl:mk_branch(SizeReg, le, hipe_rtl:mk_imm(?MAX_SMALL_BITS),
- hipe_rtl:label_name(SuccessLbl),
+ Init = [hipe_rtl:mk_branch(SizeReg, leu, hipe_rtl:mk_imm(?MAX_SMALL_BITS),
+ hipe_rtl:label_name(SuccessLbl),
hipe_rtl:label_name(CLbl)),
SuccessLbl],
End = [CLbl|CCode],
@@ -840,8 +884,8 @@ get_unaligned_int_to_reg(Reg, Size, Base, Offset, LowBits, Shiftr, Type) ->
hipe_rtl:mk_imm((WordSize-MinLoad)*?BYTE_SIZE))];
{_, WordSize} ->
UnsignedBig = {unsigned, big},
- [hipe_rtl:mk_branch(TotBits, le, hipe_rtl:mk_imm(MinLoad*?BYTE_SIZE),
- hipe_rtl:label_name(LessLbl),
+ [hipe_rtl:mk_branch(TotBits, leu, hipe_rtl:mk_imm(MinLoad*?BYTE_SIZE),
+ hipe_rtl:label_name(LessLbl),
hipe_rtl:label_name(MoreLbl)),
LessLbl,
load_bytes(LoadDst, Base, ByteOffset, Type, MinLoad),
@@ -901,7 +945,7 @@ get_big_unknown_int(Dst1, Base, Offset, NewOffset,
hipe_rtl:mk_alu(ByteOffset, Offset, srl, hipe_rtl:mk_imm(?BYTE_SHIFT)),
load_bytes(LoadDst, Base, ByteOffset, Type, 1),
BackLbl,
- hipe_rtl:mk_branch(ByteOffset, le, Limit, hipe_rtl:label_name(LoopLbl),
+ hipe_rtl:mk_branch(ByteOffset, leu, Limit, hipe_rtl:label_name(LoopLbl),
hipe_rtl:label_name(EndLbl)),
LoopLbl,
load_bytes(Tmp, Base, ByteOffset, {unsigned, big}, 1),
@@ -930,8 +974,8 @@ get_little_unknown_int(Dst1, Base, Offset, NewOffset,
hipe_rtl:mk_alu(Limit, Tmp, srl, hipe_rtl:mk_imm(?BYTE_SHIFT)),
hipe_rtl:mk_move(ShiftReg, hipe_rtl:mk_imm(0)),
BackLbl,
- hipe_rtl:mk_branch(ByteOffset, lt, Limit,
- hipe_rtl:label_name(LoopLbl),
+ hipe_rtl:mk_branch(ByteOffset, ltu, Limit,
+ hipe_rtl:label_name(LoopLbl),
hipe_rtl:label_name(DoneLbl)),
LoopLbl,
load_bytes(Tmp, Base, ByteOffset, {unsigned, big}, 1),
@@ -1047,7 +1091,7 @@ load_bytes(Dst, Base, Offset, {Signedness, Endianness}, X) when X > 1 ->
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1)),
hipe_rtl:mk_alu(Dst, Dst, sll, hipe_rtl:mk_imm(8)),
hipe_rtl:mk_alu(Dst, Dst, 'or', Tmp1),
- hipe_rtl:mk_branch(Offset, lt, Limit, hipe_rtl:label_name(LoopLbl),
+ hipe_rtl:mk_branch(Offset, ltu, Limit, hipe_rtl:label_name(LoopLbl),
hipe_rtl:label_name(EndLbl)),
EndLbl];
little ->
@@ -1059,7 +1103,7 @@ load_bytes(Dst, Base, Offset, {Signedness, Endianness}, X) when X > 1 ->
hipe_rtl:mk_load(Tmp1, Base, TmpOffset, byte, Signedness),
hipe_rtl:mk_alu(Dst, Dst, sll, hipe_rtl:mk_imm(8)),
hipe_rtl:mk_alu(Dst, Dst, 'or', Tmp1),
- hipe_rtl:mk_branch(Offset, lt, TmpOffset, hipe_rtl:label_name(LoopLbl),
+ hipe_rtl:mk_branch(Offset, ltu, TmpOffset, hipe_rtl:label_name(LoopLbl),
hipe_rtl:label_name(EndLbl)),
EndLbl,
hipe_rtl:mk_move(Offset, Limit)]
@@ -1075,78 +1119,5 @@ create_gcsafe_regs(X) when X > 0 ->
create_gcsafe_regs(0) ->
[].
-first_part(Var, Register, FalseLblName) ->
- [SuccessLbl1, SuccessLbl2] = create_lbls(2),
- [hipe_tagscheme:test_fixnum(Var, hipe_rtl:label_name(SuccessLbl1),
- FalseLblName, 0.99),
- SuccessLbl1,
- hipe_tagscheme:fixnum_ge(Var, hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(0)),
- hipe_rtl:label_name(SuccessLbl2), FalseLblName, 0.99),
- SuccessLbl2,
- hipe_tagscheme:untag_fixnum(Register, Var)].
-
-make_size(1, BitsVar, FalseLblName) ->
- [DstReg] = create_regs(1),
- {first_part(BitsVar, DstReg, FalseLblName), DstReg};
-make_size(?BYTE_SIZE, BitsVar, FalseLblName) ->
- [DstReg] = create_regs(1),
- Code =
- first_part(BitsVar, DstReg, FalseLblName) ++
- [hipe_rtl:mk_alu(DstReg, DstReg, sll, hipe_rtl:mk_imm(?BYTE_SHIFT))],
- {Code, DstReg};
-make_size(UnitImm, BitsVar, FalseLblName) ->
- [DstReg] = create_regs(1),
- UnitList = number2list(UnitImm),
- Code = multiply_code(UnitList, BitsVar, DstReg, FalseLblName),
- {Code, DstReg}.
-
-multiply_code(List=[Head|_Tail], Variable, Result, FalseLblName) ->
- Test = set_high(Head),
- Tmp1 = hipe_rtl:mk_new_reg(),
- SuccessLbl = hipe_rtl:mk_new_label(),
- Register = hipe_rtl:mk_new_reg(),
- Code = [hipe_rtl:mk_move(Result, hipe_rtl:mk_imm(0))|
- first_part(Variable, Register, FalseLblName)]
- ++
- [hipe_rtl:mk_alub(Tmp1, Register, 'and', hipe_rtl:mk_imm(Test),
- eq, hipe_rtl:label_name(SuccessLbl),
- FalseLblName, 0.99),
- SuccessLbl],
- multiply_code(List, Register, Result, FalseLblName, Tmp1, Code).
-
-multiply_code([ShiftSize|Rest], Register, Result, FalseLblName, Tmp1, OldCode) ->
- SuccessLbl = hipe_rtl:mk_new_label(),
- Code =
- OldCode ++
- [hipe_rtl:mk_alu(Tmp1, Register, sll, hipe_rtl:mk_imm(ShiftSize)),
- hipe_rtl:mk_alub(Result, Tmp1, 'add', Result, not_overflow,
- hipe_rtl:label_name(SuccessLbl), FalseLblName, 0.99),
- SuccessLbl],
- multiply_code(Rest, Register, Result, FalseLblName, Tmp1, Code);
-multiply_code([], _Register, _Result, _FalseLblName, _Tmp1, Code) ->
- Code.
-
-number2list(X) when is_integer(X), X >= 0 ->
- number2list(X, []).
-
-number2list(1, Acc) ->
- lists:reverse([0|Acc]);
-number2list(0, Acc) ->
- lists:reverse(Acc);
-number2list(X, Acc) ->
- F = floorlog2(X),
- number2list(X-(1 bsl F), [F|Acc]).
-
-floorlog2(X) ->
- round(math:log(X)/math:log(2)-0.5).
-
-set_high(X) ->
- set_high(X, 0).
-
-set_high(0, Y) ->
- Y;
-set_high(X, Y) ->
- set_high(X-1, Y+(1 bsl (27-X))).
-
is_illegal_const(Const) ->
Const >= 1 bsl (hipe_rtl_arch:word_size() * ?BYTE_SIZE) orelse Const < 0.
diff --git a/lib/hipe/rtl/hipe_rtl_cfg.erl b/lib/hipe/rtl/hipe_rtl_cfg.erl
index b6c1d63262..8b2bc93bc5 100644
--- a/lib/hipe/rtl/hipe_rtl_cfg.erl
+++ b/lib/hipe/rtl/hipe_rtl_cfg.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_cleanup_const.erl b/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
index d3e71a56c1..579ba11f7d 100644
--- a/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
+++ b/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/rtl/hipe_rtl_exceptions.erl b/lib/hipe/rtl/hipe_rtl_exceptions.erl
index 879b84c0b0..243e06c196 100644
--- a/lib/hipe/rtl/hipe_rtl_exceptions.erl
+++ b/lib/hipe/rtl/hipe_rtl_exceptions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl
index 262aedb409..1f65d870e4 100644
--- a/lib/hipe/rtl/hipe_rtl_lcm.erl
+++ b/lib/hipe/rtl/hipe_rtl_lcm.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_liveness.erl b/lib/hipe/rtl/hipe_rtl_liveness.erl
index 0c4b6b2e11..46c02506a2 100644
--- a/lib/hipe/rtl/hipe_rtl_liveness.erl
+++ b/lib/hipe/rtl/hipe_rtl_liveness.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_mk_switch.erl b/lib/hipe/rtl/hipe_rtl_mk_switch.erl
index c14fa5628e..0c13b9ffcb 100644
--- a/lib/hipe/rtl/hipe_rtl_mk_switch.erl
+++ b/lib/hipe/rtl/hipe_rtl_mk_switch.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_primops.erl b/lib/hipe/rtl/hipe_rtl_primops.erl
index d9d08356ce..b5a43b6b7e 100644
--- a/lib/hipe/rtl/hipe_rtl_primops.erl
+++ b/lib/hipe/rtl/hipe_rtl_primops.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_ssa.erl b/lib/hipe/rtl/hipe_rtl_ssa.erl
index f55cc0dd5c..b9be73d6ac 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl b/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
index cae6da542f..ffb63c48e2 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
@@ -3,16 +3,17 @@
%%%
%%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
index 2f594333c1..f80f9bc7d2 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_ssapre.erl b/lib/hipe/rtl/hipe_rtl_ssapre.erl
index 2ebebb5197..94533e5bdd 100644
--- a/lib/hipe/rtl/hipe_rtl_ssapre.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssapre.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_symbolic.erl b/lib/hipe/rtl/hipe_rtl_symbolic.erl
index bc8640dec9..d0055faece 100644
--- a/lib/hipe/rtl/hipe_rtl_symbolic.erl
+++ b/lib/hipe/rtl/hipe_rtl_symbolic.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_varmap.erl b/lib/hipe/rtl/hipe_rtl_varmap.erl
index 9bd5e88611..cb6327af1a 100644
--- a/lib/hipe/rtl/hipe_rtl_varmap.erl
+++ b/lib/hipe/rtl/hipe_rtl_varmap.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index c27c682915..8825a3ade3 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -2,25 +2,26 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
%%========================================================================
%%
%% Filename : hipe_tagscheme.erl
-%% Note : This is specific to Erlang 5.* (i.e. starting with R9).
+%% Note : This is specific to Erlang >= 5.* (i.e. starting with R9).
%%
%% Modifications:
%% 020904: Happi - added support for external pids and ports.
@@ -40,7 +41,8 @@
test_any_pid/4, test_any_port/4,
test_ref/4, test_fun/4, test_fun2/5, test_matchstate/4,
test_binary/4, test_bitstr/4, test_list/4, test_map/4,
- test_integer/4, test_number/4, test_tuple_N/5]).
+ test_integer/4, test_number/4, test_tuple_N/5,
+ test_pos_bignum_arity/6]).
-export([realtag_fixnum/2, tag_fixnum/2, realuntag_fixnum/2, untag_fixnum/2]).
-export([test_two_fixnums/3, test_fixnums/4, unsafe_fixnum_add/3,
unsafe_fixnum_sub/3,
@@ -52,9 +54,10 @@
-export([unsafe_closure_element/3]).
-export([mk_fun_header/0, tag_fun/2]).
-export([unsafe_untag_float/2, unsafe_tag_float/2]).
--export([mk_sub_binary/6,mk_sub_binary/7]).
+-export([mk_sub_binary/6, mk_sub_binary/7]).
-export([unsafe_mk_big/3, unsafe_load_float/3]).
--export([bignum_sizeneed/1,bignum_sizeneed_code/2, get_one_word_pos_bignum/3]).
+-export([bignum_sizeneed/1, bignum_sizeneed_code/2, get_one_word_pos_bignum/3,
+ unsafe_get_one_word_pos_bignum/2]).
-export([test_subbinary/3, test_heap_binary/3]).
-export([create_heap_binary/3, create_refc_binary/3, create_refc_binary/4]).
-export([create_matchstate/6, convert_matchstate/1, compare_matchstate/4]).
@@ -141,7 +144,7 @@ mk_non_value() -> ?THE_NON_VALUE.
-spec is_fixnum(integer()) -> boolean().
is_fixnum(N) when is_integer(N) ->
Bits = ?bytes_to_bits(hipe_rtl_arch:word_size()) - ?TAG_IMMED1_SIZE,
- (N =< ((1 bsl (Bits - 1)) - 1)) and (N >= -(1 bsl (Bits - 1))).
+ (N =< ((1 bsl (Bits - 1)) - 1)) andalso (N >= -(1 bsl (Bits - 1))).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -348,6 +351,24 @@ test_pos_bignum(X, TrueLab, FalseLab, Pred) ->
mask_and_compare(Tmp, BigMask, ?TAG_HEADER_POS_BIG,
TrueLab, FalseLab, Pred)].
+test_pos_bignum_arity(X, Arity, TrueLab, NotPosBignumLab, FalseLab, Pred) ->
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ BoxedLab = hipe_rtl:mk_new_label(),
+ HeaderImm = hipe_rtl:mk_imm(mk_header(Arity, ?TAG_HEADER_POS_BIG)),
+ [test_is_boxed(X, hipe_rtl:label_name(BoxedLab), NotPosBignumLab, Pred),
+ BoxedLab,
+ get_header(Tmp, X)] ++
+ case NotPosBignumLab =:= FalseLab of
+ true -> [];
+ false ->
+ BignumLab = hipe_rtl:mk_new_label(),
+ BigMask = ?TAG_HEADER_MASK,
+ [mask_and_compare(Tmp, BigMask, ?TAG_HEADER_POS_BIG,
+ hipe_rtl:label_name(BignumLab), NotPosBignumLab, Pred),
+ BignumLab]
+ end ++
+ [hipe_rtl:mk_branch(Tmp, 'eq', HeaderImm, TrueLab, FalseLab, Pred)].
+
test_matchstate(X, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
HalfTrueLab = hipe_rtl:mk_new_label(),
@@ -962,22 +983,25 @@ get_one_word_pos_bignum(USize, Size, Fail) ->
Header = hipe_rtl:mk_new_reg(),
HalfLbl = hipe_rtl:mk_new_label(),
HalfLblName = hipe_rtl:label_name(HalfLbl),
- WordSize = hipe_rtl_arch:word_size(),
PosHead = hipe_rtl:mk_imm(mk_header(1, ?TAG_HEADER_POS_BIG)),
[get_header(Header, Size),
hipe_rtl:mk_branch(Header, eq, PosHead, HalfLblName, Fail),
- HalfLbl,
- hipe_rtl:mk_load(USize, Size, hipe_rtl:mk_imm(1*WordSize
- -?TAG_PRIMARY_BOXED))].
+ HalfLbl |
+ unsafe_get_one_word_pos_bignum(USize, Size)].
+
+unsafe_get_one_word_pos_bignum(USize, Size) ->
+ WordSize = hipe_rtl_arch:word_size(),
+ Imm = hipe_rtl:mk_imm(1*WordSize-?TAG_PRIMARY_BOXED),
+ [hipe_rtl:mk_load(USize, Size, Imm)].
-spec bignum_sizeneed(non_neg_integer()) -> non_neg_integer().
bignum_sizeneed(Size) ->
- WordSizeBits = hipe_rtl_arch:word_size() * 8,
case is_fixnum(1 bsl Size) of
true ->
0;
false ->
+ WordSizeBits = hipe_rtl_arch:word_size() * 8,
((Size + (WordSizeBits-1)) div WordSizeBits) + 1
end.
@@ -1116,14 +1140,11 @@ get_field_offset({matchbuffer, binsize}) ->
?MB_SIZE.
get_field_size(Field) ->
- size_to_atom(get_field_size1(Field)).
-
-size_to_atom(Bytes) ->
WordSize = hipe_rtl_arch:word_size(),
- case Bytes of
+ case get_field_size1(Field) of
WordSize -> word;
- 4 -> int32;
- %%2 -> int16; So far there are no 2 byte fields
+ %% 4 -> int32; Seems not needed: covered by the previous case
+ %% 2 -> int16; So far there are no 2 byte fields
1 -> byte
end.
diff --git a/lib/hipe/sparc/Makefile b/lib/hipe/sparc/Makefile
index eb40117691..a193e6a853 100644
--- a/lib/hipe/sparc/Makefile
+++ b/lib/hipe/sparc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/sparc/hipe_rtl_to_sparc.erl b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
index fd21be3ae7..297b693b42 100644
--- a/lib/hipe/sparc/hipe_rtl_to_sparc.erl
+++ b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc.erl b/lib/hipe/sparc/hipe_sparc.erl
index 9fcb94afb6..b376a6da53 100644
--- a/lib/hipe/sparc/hipe_sparc.erl
+++ b/lib/hipe/sparc/hipe_sparc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc.hrl b/lib/hipe/sparc/hipe_sparc.hrl
index 107541f96a..5fb9dfc23f 100644
--- a/lib/hipe/sparc/hipe_sparc.hrl
+++ b/lib/hipe/sparc/hipe_sparc.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_assemble.erl b/lib/hipe/sparc/hipe_sparc_assemble.erl
index 68a4e1b349..0e27c78416 100644
--- a/lib/hipe/sparc/hipe_sparc_assemble.erl
+++ b/lib/hipe/sparc/hipe_sparc_assemble.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -48,7 +49,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
DataRelocs = hipe_pack_constants:mk_data_relocs(RefsFromConsts, LabelMap),
SSE = hipe_pack_constants:slim_sorted_exportmap(ExportMap,Closures,Exports),
SlimRefs = hipe_pack_constants:slim_refs(AccRefs),
- Bin = term_to_binary([{?VERSION_STRING(),?HIPE_SYSTEM_CRC},
+ Bin = term_to_binary([{?VERSION_STRING(),?HIPE_ERTS_CHECKSUM},
ConstAlign, ConstSize,
SC,
DataRelocs, % nee LM, LabelMap
diff --git a/lib/hipe/sparc/hipe_sparc_cfg.erl b/lib/hipe/sparc/hipe_sparc_cfg.erl
index d938a3bdf1..65f7ce310c 100644
--- a/lib/hipe/sparc/hipe_sparc_cfg.erl
+++ b/lib/hipe/sparc/hipe_sparc_cfg.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_defuse.erl b/lib/hipe/sparc/hipe_sparc_defuse.erl
index d59ad436b5..ae529bed31 100644
--- a/lib/hipe/sparc/hipe_sparc_defuse.erl
+++ b/lib/hipe/sparc/hipe_sparc_defuse.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_encode.erl b/lib/hipe/sparc/hipe_sparc_encode.erl
index 8a28f33ab9..07d5d67fd5 100644
--- a/lib/hipe/sparc/hipe_sparc_encode.erl
+++ b/lib/hipe/sparc/hipe_sparc_encode.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/sparc/hipe_sparc_finalise.erl b/lib/hipe/sparc/hipe_sparc_finalise.erl
index b44a21f7c0..af234993b1 100644
--- a/lib/hipe/sparc/hipe_sparc_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_finalise.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_frame.erl b/lib/hipe/sparc/hipe_sparc_frame.erl
index f7d7f40df3..c86dfcc7a8 100644
--- a/lib/hipe/sparc/hipe_sparc_frame.erl
+++ b/lib/hipe/sparc/hipe_sparc_frame.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_all.erl b/lib/hipe/sparc/hipe_sparc_liveness_all.erl
index c6f78f9f7a..0b1cb7d5ae 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_all.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_all.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl b/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
index ac67e499ad..699a311f8c 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl b/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
index 0b07ae5c9d..8f2edd7239 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_main.erl b/lib/hipe/sparc/hipe_sparc_main.erl
index 2e5c8e0494..e09a0bf661 100644
--- a/lib/hipe/sparc/hipe_sparc_main.erl
+++ b/lib/hipe/sparc/hipe_sparc_main.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_pp.erl b/lib/hipe/sparc/hipe_sparc_pp.erl
index 6b49acdd11..bdc868a518 100644
--- a/lib/hipe/sparc/hipe_sparc_pp.erl
+++ b/lib/hipe/sparc/hipe_sparc_pp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_ra.erl b/lib/hipe/sparc/hipe_sparc_ra.erl
index 40360e97fe..7551b3b7bc 100644
--- a/lib/hipe/sparc/hipe_sparc_ra.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
index 3403636118..02e86794f6 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_ra_ls.erl b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
index cdb15e738c..c44fd495bf 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_ls.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_ra_naive.erl b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
index 8c378c4850..0fcd8b0f0b 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_naive.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
index f7fdae0491..d79d63eb2a 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
index 17dc0f88d5..a474e0ec6a 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/sparc/hipe_sparc_registers.erl b/lib/hipe/sparc/hipe_sparc_registers.erl
index adb01a65ca..59aef46bff 100644
--- a/lib/hipe/sparc/hipe_sparc_registers.erl
+++ b/lib/hipe/sparc/hipe_sparc_registers.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ssa/hipe_ssa.inc b/lib/hipe/ssa/hipe_ssa.inc
index 2766c10e4f..86c036cd10 100644
--- a/lib/hipe/ssa/hipe_ssa.inc
+++ b/lib/hipe/ssa/hipe_ssa.inc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ssa/hipe_ssa_const_prop.inc b/lib/hipe/ssa/hipe_ssa_const_prop.inc
index 0876fca34a..664faf9737 100644
--- a/lib/hipe/ssa/hipe_ssa_const_prop.inc
+++ b/lib/hipe/ssa/hipe_ssa_const_prop.inc
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/ssa/hipe_ssa_copy_prop.inc b/lib/hipe/ssa/hipe_ssa_copy_prop.inc
index 311940a1fc..f14abd869a 100644
--- a/lib/hipe/ssa/hipe_ssa_copy_prop.inc
+++ b/lib/hipe/ssa/hipe_ssa_copy_prop.inc
@@ -5,16 +5,17 @@
%%%
%%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/ssa/hipe_ssa_liveness.inc b/lib/hipe/ssa/hipe_ssa_liveness.inc
index 05c8a88059..e454b71798 100644
--- a/lib/hipe/ssa/hipe_ssa_liveness.inc
+++ b/lib/hipe/ssa/hipe_ssa_liveness.inc
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/test/Makefile b/lib/hipe/test/Makefile
index 009f503abb..d781e4f9be 100644
--- a/lib/hipe/test/Makefile
+++ b/lib/hipe/test/Makefile
@@ -10,8 +10,10 @@ MODULES= \
# .erl files for these modules are automatically generated
GEN_MODULES= \
+ basic_SUITE \
bs_SUITE \
- maps_SUITE
+ maps_SUITE \
+ sanity_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/hipe/test/basic_SUITE_data/basic_arith.erl b/lib/hipe/test/basic_SUITE_data/basic_arith.erl
new file mode 100644
index 0000000000..28e99be053
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_arith.erl
@@ -0,0 +1,72 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%---------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests cases for compilation of arithmetic.
+%%%---------------------------------------------------------------------
+-module(basic_arith).
+
+-export([test/0]).
+
+test() ->
+ ok = test_rem(),
+ ok = test_bit_ops(),
+ ok = test_uplus(),
+ ok = test_bsl_errors(),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Tests the remainder operator.
+
+test_rem() ->
+ 2 = ret_rem(42, 20),
+ -2 = ret_rem(-42, 20),
+ -2 = ret_rem(-42, -20),
+ {'EXIT', {badarith, _}} = ret_rem(3.14, 2),
+ {'EXIT', {badarith, _}} = ret_rem(42, 3.14),
+ ok.
+
+ret_rem(X, Y) ->
+ catch X rem Y.
+
+%%----------------------------------------------------------------------
+%%
+
+test_bit_ops() ->
+ 2 = bbb(11, 2, 16#3ff),
+ ok.
+
+bbb(X, Y, Z) ->
+ ((1 bsl X) bor Y) band Z.
+
+%%----------------------------------------------------------------------
+%% Tests unary plus: it used to be the identity function but not anymore
+
+test_uplus() ->
+ badarith = try uplus(gazonk) catch error:Err -> Err end,
+ 42 = uplus(42),
+ ok.
+
+uplus(X) -> +(X).
+
+%%----------------------------------------------------------------------
+%% The first part of this test triggered a bug in the emulator as one
+%% of the arguments to bsl is not an integer.
+%%
+%% The second part triggered a compilation crash since an arithmetic
+%% expression resulting in a 'system_limit' exception was statically
+%% evaluated and an arithmetic result was expected.
+
+test_bsl_errors() ->
+ {'EXIT', {'badarith', _}} = (catch (t1(0, pad, 0))),
+ badarith = try t2(0, pad, 0) catch error:Err1 -> Err1 end,
+ system_limit = try (id(1) bsl 100000000) catch error:Err2 -> Err2 end,
+ ok.
+
+t1(_, X, _) ->
+ (1 bsl X) + 1.
+
+t2(_, X, _) ->
+ (X bsl 1) + 1.
+
+id(I) -> I.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_beam_instrs.erl b/lib/hipe/test/basic_SUITE_data/basic_beam_instrs.erl
new file mode 100644
index 0000000000..6fafea3b09
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_beam_instrs.erl
@@ -0,0 +1,102 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Tests for correct translation of various BEAM instructions.
+%%%-------------------------------------------------------------------
+-module(basic_beam_instrs).
+
+-export([test/0]).
+
+test() ->
+ ok = test_make_fun(),
+ ok = test_switch_val(),
+ ok = test_put_literal(),
+ ok = test_set_tuple_element(),
+ ok = test_unguarded_unsafe_element(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests whether the translation of make_fun works.
+
+test_make_fun() ->
+ {F, G} = double_the_fun(),
+ ok = F(),
+ {ok, 42} = G(42),
+ FV1 = {ok, free_var1},
+ FV2 = {also, {free, var2}},
+ {FV1, {ok, [bv]}, FV2} = contains_fun(FV1, ignored, FV2),
+ ok.
+
+double_the_fun() ->
+ {fun () -> ok end, fun (V) -> {ok, V} end}.
+
+contains_fun(X, _IGNORED_ARG, Y) ->
+ calls_fun(fun(Term) -> {X, Term, Y} end).
+
+calls_fun(F) ->
+ F({ok, [bv]}).
+
+%%--------------------------------------------------------------------
+%% Tests whether the translation of switch_val works.
+
+test_switch_val() ->
+ 'A' = sv(a),
+ 'B' = sv(b),
+ 'C' = sv(c),
+ foo = sv(d),
+ ok.
+
+sv(a) -> 'A';
+sv(b) -> 'B';
+sv(c) -> 'C';
+sv(_) -> foo.
+
+%%--------------------------------------------------------------------
+%% Tests correct handling of literals (statically constant terms)
+
+-define(QUADRUPLE, {a,b,c,42}).
+-define(DEEP_LIST, [42,[42,[42]]]).
+
+test_put_literal() ->
+ ?QUADRUPLE = mk_literal_quadruple(),
+ ?DEEP_LIST = mk_literal_deep_list(),
+ ok.
+
+mk_literal_quadruple() ->
+ ?QUADRUPLE.
+
+mk_literal_deep_list() ->
+ ?DEEP_LIST.
+
+%%--------------------------------------------------------------------
+%% Tests whether the translation of set_tuple_element works.
+
+-record(rec, {f1, f2, f3, f4, f5}).
+
+test_set_tuple_element() ->
+ F2 = [a,b,c], F4 = {a,b},
+ State0 = init_rec(F2, F4),
+ State1 = simple_set(State0, 42),
+ #rec{f1 = foo, f2 = F2, f3 = 42, f4 = F4, f5 = 42.0} = odd_set(State1, 21),
+ ok.
+
+init_rec(F2, F4) ->
+ #rec{f1 = bar, f2 = F2, f3 = 10, f4 = F4, f5 = 3.14}.
+
+simple_set(State, Val) -> %% f3 = Val is the one used in set_element;
+ State#rec{f3 = Val, f5 = Val*2}. %% this checks the case of variable
+
+odd_set(State, Val) -> %% f3 = foo is the one used in set_element;
+ State#rec{f1 = foo, f5 = Val*2.0}. %% this checks the case of constant
+
+%%--------------------------------------------------------------------
+%% Tests the handling of unguarded unsafe_element operations that BEAM
+%% can sometimes construct on records (when it has enough context).
+
+test_unguarded_unsafe_element() ->
+ {badrecord, rec} = try unguarded_unsafe_element(42) catch error:E -> E end,
+ ok.
+
+unguarded_unsafe_element(X) ->
+ X#rec{f1 = X#rec.f3}.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bifs.erl b/lib/hipe/test/basic_SUITE_data/basic_bifs.erl
new file mode 100644
index 0000000000..e7ee2f3678
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_bifs.erl
@@ -0,0 +1,257 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests for handling of BIFs in guards and body calls.
+%%%-------------------------------------------------------------------
+-module(basic_bifs).
+
+-export([test/0]).
+
+-define(BIG, 1398479237498374913984792374983749).
+
+test() ->
+ ok = test_abs(),
+ ok = test_binary_part(),
+ ok = test_element(),
+ ok = test_float(),
+ ok = test_float_to_list(),
+ ok = test_integer_to_list(),
+ ok = test_list_to_float(),
+ ok = test_list_to_integer(),
+ ok = test_round(),
+ ok = test_trunc(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_abs() ->
+ t_abs(5.5, 0.0, -100.0, 5, 0, -100, ?BIG).
+
+t_abs(F1, F2, F3, I1, I2, I3, BigNum) ->
+ %% Floats.
+ 5.5 = abs(F1),
+ 0.0 = abs(F2),
+ 100.0 = abs(F3),
+ %% Integers.
+ 5 = abs(I1),
+ 0 = abs(I2),
+ 100 = abs(I3),
+ %% Bignums.
+ BigNum = abs(BigNum),
+ BigNum = abs(-BigNum),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Checks that 2-ary and 3-ary BIFs can be compiled to native code.
+
+test_binary_part() ->
+ Bin = <<1,2,3,4,5,6,7,8,9,10>>,
+ BinPart = bp3(Bin),
+ <<7,8>> = bp2(BinPart),
+ ok.
+
+bp2(Bin) ->
+ binary_part(Bin, {1, 2}).
+
+bp3(Bin) ->
+ binary_part(Bin, byte_size(Bin), -5).
+
+%%--------------------------------------------------------------------
+
+test_element() ->
+ true = elem({a, b}),
+ false = elem({a, c}),
+ other = elem(gazonk),
+ ok.
+
+elem(T) when element(1, T) == a -> element(2, T) == b;
+elem(_) -> other.
+
+%%--------------------------------------------------------------------
+
+test_float() ->
+ t_float(0, 42, -100, 2.5, 0.0, -100.42, ?BIG, -?BIG).
+
+t_float(I1, I2, I3, F1, F2, F3, B1, B2) ->
+ 0.0 = float(I1),
+ 2.5 = float(F1),
+ 0.0 = float(F2),
+ -100.42 = float(F3),
+ 42.0 = float(I2),
+ -100.0 = float(I3),
+ %% Bignums.
+ 1398479237498374913984792374983749.0 = float(B1),
+ -1398479237498374913984792374983749.0 = float(B2),
+ %% Extremly big bignums.
+ Big = list_to_integer(duplicate(2000, $1)),
+ {'EXIT', _} = (catch float(Big)),
+ %% Invalid types and lists.
+ {'EXIT', _} = (catch my_list_to_integer(atom)),
+ {'EXIT', _} = (catch my_list_to_integer(123)),
+ {'EXIT', _} = (catch my_list_to_integer([$1, [$2]])),
+ {'EXIT', _} = (catch my_list_to_integer("1.2")),
+ {'EXIT', _} = (catch my_list_to_integer("a")),
+ {'EXIT', _} = (catch my_list_to_integer("")),
+ ok.
+
+my_list_to_integer(X) ->
+ list_to_integer(X).
+
+%%--------------------------------------------------------------------
+
+test_float_to_list() ->
+ test_ftl("0.0e+0", 0.0),
+ test_ftl("2.5e+1", 25.0),
+ test_ftl("2.5e+0", 2.5),
+ test_ftl("2.5e-1", 0.25),
+ test_ftl("-3.5e+17", -350.0e15),
+ ok.
+
+test_ftl(Expect, Float) ->
+ %% No \n on the next line -- we want the line number from t_float_to_list.
+ Expect = remove_zeros(lists:reverse(float_to_list(Float)), []).
+
+%% Removes any non-significant zeros in a floating point number.
+%% Example: 2.500000e+01 -> 2.5e+1
+
+remove_zeros([$+, $e|Rest], [$0, X|Result]) ->
+ remove_zeros([$+, $e|Rest], [X|Result]);
+remove_zeros([$-, $e|Rest], [$0, X|Result]) ->
+ remove_zeros([$-, $e|Rest], [X|Result]);
+remove_zeros([$0, $.|Rest], [$e|Result]) ->
+ remove_zeros(Rest, [$., $0, $e|Result]);
+remove_zeros([$0|Rest], [$e|Result]) ->
+ remove_zeros(Rest, [$e|Result]);
+remove_zeros([Char|Rest], Result) ->
+ remove_zeros(Rest, [Char|Result]);
+remove_zeros([], Result) ->
+ Result.
+
+%%--------------------------------------------------------------------
+
+test_integer_to_list() ->
+ t_integer_to_list(0, 42, 32768, 268435455, 123456932798748738738).
+
+t_integer_to_list(I1, I2, I3, I4, BIG) ->
+ "0" = integer_to_list(I1),
+ "42" = integer_to_list(I2),
+ "-42" = integer_to_list(-I2),
+ "-42" = integer_to_list(-I2),
+ "32768" = integer_to_list(I3),
+ "268435455" = integer_to_list(I4),
+ "-268435455" = integer_to_list(-I4),
+ "123456932798748738738" = integer_to_list(BIG),
+ BigList = duplicate(2000, $1),
+ Big = list_to_integer(BigList),
+ BigList = integer_to_list(Big),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_list_to_float() ->
+ ok = t_list_to_float_safe(),
+ ok = t_list_to_float_risky().
+
+t_list_to_float_safe() ->
+ 0.0 = my_list_to_float("0.0"),
+ 0.0 = my_list_to_float("-0.0"),
+ 0.5 = my_list_to_float("0.5"),
+ -0.5 = my_list_to_float("-0.5"),
+ 100.0 = my_list_to_float("1.0e2"),
+ 127.5 = my_list_to_float("127.5"),
+ -199.5 = my_list_to_float("-199.5"),
+ {'EXIT', _} = (catch my_list_to_float("0")),
+ {'EXIT', _} = (catch my_list_to_float("0..0")),
+ {'EXIT', _} = (catch my_list_to_float("0e12")),
+ {'EXIT', _} = (catch my_list_to_float("--0.0")),
+ ok.
+
+my_list_to_float(X) ->
+ list_to_float(X).
+
+%% This might crash the emulator. (Used to crash Erlang 4.4.1 on Unix.)
+
+t_list_to_float_risky() ->
+ Many_Ones = duplicate(25000, $1),
+ ok = case list_to_float("2." ++ Many_Ones) of
+ F when is_float(F), 0.0 < F, F =< 3.14 -> ok
+ end,
+ {'EXIT', _} = (catch list_to_float("2" ++ Many_Ones)),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_list_to_integer() ->
+ ok = t_list_to_integer_small("0", "00", "-0", "1", "-1", "42", "-12",
+ "32768", "268435455", "-268435455"),
+ ok = t_list_to_integer_bignum("123456932798748738738666"),
+ ok.
+
+t_list_to_integer_small(S1, S2, S3, S4, S5, S6, S7, S8, S9, S10) ->
+ 0 = list_to_integer(S1),
+ 0 = list_to_integer(S2),
+ 0 = list_to_integer(S3),
+ 1 = list_to_integer(S4),
+ -1 = list_to_integer(S5),
+ 42 = list_to_integer(S6),
+ -12 = list_to_integer(S7),
+ 32768 = list_to_integer(S8),
+ 268435455 = list_to_integer(S9),
+ -268435455 = list_to_integer(S10),
+ ok.
+
+t_list_to_integer_bignum(S) ->
+ 123456932798748738738666 = list_to_integer(S),
+ case list_to_integer(duplicate(2000, $1)) of
+ I when is_integer(I), I > 123456932798748738738666 -> ok
+ end.
+
+%%--------------------------------------------------------------------
+
+test_round() ->
+ ok = t_round_small(0.0, 0.4, 0.5, -0.4, -0.5, 255.3, 255.6, -1033.3, -1033.6),
+ ok = t_round_big(4294967296.1, 4294967296.9),
+ ok.
+
+t_round_small(F1, F2, F3, F4, F5, F6, F7, F8, F9) ->
+ 0 = round(F1),
+ 0 = round(F2),
+ 1 = round(F3),
+ 0 = round(F4),
+ -1 = round(F5),
+ 255 = round(F6),
+ 256 = round(F7),
+ -1033 = round(F8),
+ -1034 = round(F9),
+ ok.
+
+t_round_big(B1, B2) ->
+ 4294967296 = round(B1),
+ 4294967297 = round(B2),
+ -4294967296 = round(-B1),
+ -4294967297 = round(-B2),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_trunc() ->
+ t_trunc(0.0, 5.3333, -10.978987, 4294967305.7).
+
+t_trunc(F1, F2, F3, B) ->
+ 0 = trunc(F1),
+ 5 = trunc(F2),
+ -10 = trunc(F3),
+ %% Bignums.
+ 4294967305 = trunc(B),
+ -4294967305 = trunc(-B),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Auxiliary functions below
+
+duplicate(N, X) when is_integer(N), N >= 0 ->
+ duplicate(N, X, []).
+
+duplicate(0, _, L) -> L;
+duplicate(N, X, L) -> duplicate(N-1, X, [X|L]).
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bignums.erl b/lib/hipe/test/basic_SUITE_data/basic_bignums.erl
new file mode 100644
index 0000000000..e3b523b3f5
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_bignums.erl
@@ -0,0 +1,143 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples that test bignum arithmetic and matching.
+%%%-------------------------------------------------------------------
+-module(basic_bignums).
+
+-export([test/0, test_bsl/0]).
+
+test() ->
+ ok = test_ops(),
+ ok = test_big_fac(),
+ ok = test_int_overfl_32(),
+ ok = test_int_overfl_64(),
+ ok = test_int_overfl_32_guard(),
+ ok = test_int_overfl_64_guard(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Define some constants for the tests of arithmetic operators
+
+-define(X, 68719476736).
+-define(Y, 98765432101234).
+-define(Z, 4722366482869645213696).
+-define(W, 339254531512339254531512).
+
+-define(B1, 4398046511104).
+-define(B5, 1645504557321206042154969182557350504982735865633579863348609024).
+-define(B17, 86182066610968551542636378241108028056376767329454880514019834315878107616003372189510312530372009184902888961739623919010110377987011442493486117202360415845666384627768436296772219009176743399772868636439042064384).
+
+%%--------------------------------------------------------------------
+
+test_ops() ->
+ ok = test_mult(),
+ ok = test_div(),
+ ok = test_round(),
+ ok = test_trunc(),
+ ok = test_bsl(),
+ ok.
+
+test_mult() ->
+ ?Z = mult(?X, ?X),
+ ok.
+
+mult(X, Y) -> X * Y.
+
+test_div() ->
+ 4 = div_f(339254531512, ?X),
+ 0 = div_f(?Y, ?Y+1),
+ 64 = div_f(?B1, ?X),
+ ?X = div_f(?Z, ?X),
+ 1073741824 = div_f(?Z, ?B1),
+ ok.
+
+div_f(X, Y) -> X div Y.
+
+test_round() ->
+ 0 = round_f(?Z, ?W),
+ 1 = round_f(?Y, ?Y),
+ 71 = round_f(?W, ?Z),
+ 1437 = round_f(?Y, ?X),
+ 47813960 = round_f(?Z, ?Y),
+ 4936803183406 = round_f(?W, ?X),
+ ok.
+
+trunc_f(X, Y) -> round(X/Y).
+
+test_trunc() ->
+ 0 = trunc_f(?Z, ?W),
+ 1 = trunc_f(?Y, ?Y),
+ 72 = trunc_f(?W, ?Z),
+ 1437 = trunc_f(?Y, ?X),
+ 47813961 = trunc_f(?Z, ?Y),
+ 4936803183407 = trunc_f(?W, ?X),
+ ok.
+
+round_f(X, Y) -> trunc(X/Y).
+
+test_bsl() ->
+ ?B1 = bsl_f(1, 42),
+ ?B5 = n(5, fun erlang:'bsl'/2, 1, 42), % use the operator
+ ?B17 = n(17, fun bsl_f/2, 1, 42), % use the local function
+ ok.
+
+bsl_f(X, Y) -> X bsl Y.
+
+%% applies a binary function N times
+n(1, F, X, Y) -> F(X, Y);
+n(N, F, X, Y) when N > 1 -> n(N-1, F, F(X, Y), Y).
+
+%%--------------------------------------------------------------------
+
+-define(FAC42, 1405006117752879898543142606244511569936384000000000).
+
+test_big_fac() ->
+ ?FAC42 = fac(42),
+ ok.
+
+fac(0) -> 1;
+fac(N) -> N * fac(N-1).
+
+%%--------------------------------------------------------------------
+%% Tests for correct handling of integer overflow
+
+test_int_overfl_32() ->
+ 16#7FFFFFF = add(16#7FFFFFF, 0),
+ 16#8000000 = add(16#8000000, 0),
+ 16#8000001 = add(16#8000000, 1),
+ case add(16#7FFFFFF, 1) of
+ 16#8000000 -> ok;
+ -16#7FFFFFF -> error
+ end.
+
+test_int_overfl_64() ->
+ 16#7FFFFFFFFFFFFFF = add(16#7FFFFFFFFFFFFFF, 0),
+ 16#800000000000000 = add(16#800000000000000, 0),
+ 16#800000000000001 = add(16#800000000000000, 1),
+ case add(16#7FFFFFFFFFFFFFF, 1) of
+ 16#800000000000000 -> ok;
+ -16#7FFFFFFFFFFFFFF -> error
+ end.
+
+add(X, Y) -> X + Y.
+
+%%--------------------------------------------------------------------
+%% Tests for correct handling of integer overflow in guards
+
+test_int_overfl_32_guard() ->
+ ok = overfl_in_guard(16#7ffffff, 0),
+ ok = overfl_in_guard(16#7ffffff, 16#7ffffff),
+ ok.
+
+test_int_overfl_64_guard() ->
+ ok = overfl_in_guard(16#7ffffffffffffff, 0),
+ ok = overfl_in_guard(16#7ffffffffffffff, 16#7ffffffffffffff),
+ ok.
+
+overfl_in_guard(X, Y) ->
+ case ok of
+ V when X+Y > 12 -> V;
+ _ -> bad
+ end.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_boolean.erl b/lib/hipe/test/basic_SUITE_data/basic_boolean.erl
new file mode 100644
index 0000000000..e4a91ef5af
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_boolean.erl
@@ -0,0 +1,47 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Tests for correct translation of booleans and their primitives.
+%%%-------------------------------------------------------------------
+-module(basic_boolean).
+
+-export([test/0]).
+
+test() ->
+ ok = test_boolean_ops(false, true),
+ ok = test_orelse_redundant(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_boolean_ops(F, T) ->
+ true = T and T,
+ false = T and F,
+ false = F and T,
+ false = F and F,
+ true = T or T,
+ true = T or F,
+ true = F or T,
+ false = F or F,
+ true = T andalso T,
+ false = T andalso F,
+ false = F andalso T,
+ false = F andalso F,
+ true = T orelse T,
+ true = T orelse F,
+ true = F orelse T,
+ false = F orelse F,
+ ok.
+
+%%--------------------------------------------------------------------
+%% Redundant test in BEAM code will generate type warning.
+
+test_orelse_redundant() ->
+ true = test_orelse(true, true, true),
+ ok.
+
+test_orelse(A, B, C) ->
+ A andalso B orelse C.
+
+%%--------------------------------------------------------------------
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bugs_beam.erl b/lib/hipe/test/basic_SUITE_data/basic_bugs_beam.erl
new file mode 100644
index 0000000000..964b0f423a
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_bugs_beam.erl
@@ -0,0 +1,138 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples that exhibited bugs in the BEAM compiler.
+%%%-------------------------------------------------------------------
+-module(basic_bugs_beam).
+
+-export([test/0]).
+
+%% the following is needed for the test_weird_message
+-export([loop/1]).
+%% the following are needed for the test_catch_bug
+-behaviour(gen_server).
+-export([start_link/1]).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+test() ->
+ ok = test_fp_basic_blocks(),
+ ok = test_weird_message(),
+ ok = test_catch_bug(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Test which shows that BEAM's splitting of basic blocks should take
+%% into account that arithmetic operations implemented as BIFs can
+%% also cause exceptions and thus calls to BIFs should end basic blocks.
+%%
+%% Investigated and fixed in the beginning of April 2004.
+%%--------------------------------------------------------------------
+
+test_fp_basic_blocks() ->
+ ok = t1(),
+ ok = t2().
+
+t1() ->
+ X = (catch bad_arith1(2.0, 1.7)),
+ case X of
+ {'EXIT', {badarith, _}} ->
+ ok;
+ _ ->
+ error
+ end.
+
+bad_arith1(X, Y) when is_float(X) ->
+ X1 = X * 1.7e+308,
+ X2 = X1 + 1.0,
+ Y1 = Y * 2,
+ {X2, Y1}.
+
+%% Similarly, it is not kosher to have anything that can fail inside
+%% the fp block since it will throw the exception before the fp
+%% exception and we will get the same problems.
+
+t2() ->
+ case catch bad_arith2(2.0, []) of
+ {'EXIT', {badarith, _}} ->
+ ok;
+ _ ->
+ error
+ end.
+
+bad_arith2(X, Y) when is_float(X) ->
+ X1 = X * 1.7e+308,
+ Y1 = element(1, Y),
+ {X1 + 1.0, Y1}.
+
+%%--------------------------------------------------------------------
+%% Sending 'test' to this process should return 'ok'. But:
+%%
+%% 1> MOD:test().
+%% Weird: received true
+%% timeout
+%%
+%% Surprisingly, the message has been bound to the value of 'ena'
+%% in the record! The problem was visible in the .S file.
+%%--------------------------------------------------------------------
+
+-record(state, {ena = true}).
+
+test_weird_message() ->
+ P = spawn_link(?MODULE, loop, [#state{}]),
+ P ! {msg, self()},
+ receive
+ What -> What
+ after 42 -> timeout
+ end.
+
+loop(S) ->
+ receive
+ _ when S#state.ena == false ->
+ io:format("Weird: ena is false\n");
+ % loop(S);
+ {msg, Pid} ->
+ Pid ! ok;
+ % loop(S);
+ Other ->
+ io:format("Weird: received ~p\n", [Other])
+ % loop(S)
+ end.
+
+%%--------------------------------------------------------------------
+%% This was posted on the Erlang mailing list as a question:
+%%
+%% Given the module below and the function call
+%% "catch_bug:start_link(foo)."
+%% from the Erlang shell, why does Erlang crash with "Catch not found"?
+%%
+%% The BEAM compiler was generating wrong code for this case;
+%% this was fixed in R9C-0. Native code generation was OK.
+%%--------------------------------------------------------------------
+
+test_catch_bug() ->
+ ignore = start_link(foo),
+ ok.
+
+start_link(Param) ->
+ gen_server:start_link(?MODULE, Param, []).
+
+init(Param) ->
+ process_flag(trap_exit, true),
+ (catch begin
+ dummy(Param),
+ (catch exit(bar))
+ end
+ ),
+ ignore.
+
+dummy(_) -> ok.
+
+%% gen_server callbacks below
+handle_call(_Call, _From, State) -> {noreply, State}.
+handle_cast(_Msg, State) -> {noreply, State}.
+handle_info(_Msg, State) -> {noreply, State}.
+terminate(_Reason, _State) -> ok.
+code_change(_OldVsn, State, _Extra) -> {ok, State}.
+
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
new file mode 100644
index 0000000000..caa0e71d0b
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
@@ -0,0 +1,463 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%----------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples that exhibited bugs in the HiPE compiler.
+%%%----------------------------------------------------------------------
+-module(basic_bugs_hipe).
+
+-export([test/0]).
+
+test() ->
+ ok = test_ets_bifs(),
+ ok = test_szar_bug(),
+ ok = test_bit_shift(),
+ ok = test_match_big_list(),
+ ok = test_unsafe_bsl(),
+ ok = test_unsafe_bsr(),
+ ok = test_R12B5_seg_fault(),
+ ok = test_switch_neg_int(),
+ ok = test_icode_range_anal(),
+ ok.
+
+%%-----------------------------------------------------------------------
+%% From: Bjorn Gustavsson
+%%
+%% This code, if HiPE compiled, crashed like this (on SPARC)
+%%
+%% (gdb) where
+%% #0 fullsweep_heap (p=0x2c60dc, new_sz=610, objv=0xffbee8b4, nobj=3)
+%% at beam/ggc.c:1060
+%% #1 0x7ff24 in erts_garbage_collect (p=0x2c60dc, need=2, objv=0x1128fc, ...)
+%% at beam/ggc.c:1648
+%% #2 0xab6fc in hipe_mode_switch (p=0x2c60dc, cmd=704512, reg=0x1128fc)
+%% at hipe/hipe_mode_switch.c:180
+%% #3 0x8e27c in process_main () at beam/beam_emu.c:3314
+%% #4 0x31338 in erl_start (argc=9, argv=0xffbeed5c) at beam/erl_init.c:936
+%% #5 0x2d9f4 in main (argc=9, argv=0xffbeed5c) at sys/unix/erl_main.c:28
+%%
+%% A guess at what could be the problem: From R8, many ets BIFs trap
+%% to other ets BIFs with a *different* arity (i.e. they have more or
+%% less arguments). I have probably forgotten to mention that subtle
+%% change.
+%%-----------------------------------------------------------------------
+
+test_ets_bifs() ->
+ Seed = {1032, 15890, 22716},
+ put(random_seed, Seed),
+ do_random_test().
+
+do_random_test() ->
+ OrdSet = ets:new(xxx, [ordered_set]),
+ Set = ets:new(xxx, []),
+ do_n_times(fun() ->
+ Key = create_random_string(25),
+ Value = create_random_tuple(25),
+ ets:insert(OrdSet, {Key, Value}),
+ ets:insert(Set, {Key, Value})
+ end, 5000),
+ %% io:format("~nData inserted~n"),
+ do_n_times(fun() ->
+ I = random:uniform(25),
+ Key = create_random_string(I) ++ '_',
+ L1 = ets_match_object(OrdSet, {Key, '_'}),
+ L2 = lists:sort(ets_match_object(Set, {Key, '_'})),
+ case L1 == L2 of
+ false ->
+ %% io:format("~p != ~p~n", [L1, L2]),
+ exit({not_eq, L1, L2});
+ true ->
+ ok
+ end
+ end, 2000),
+ %% io:format("~nData matched~n"),
+ ets:match_delete(OrdSet, '_'),
+ ets:match_delete(Set, '_'),
+ ok.
+
+create_random_string(0) ->
+ [];
+create_random_string(OfLength) ->
+ C = case random:uniform(2) of
+ 1 -> (random:uniform($Z - $A + 1) - 1) + $A;
+ _ -> (random:uniform($z - $a + 1) - 1) + $a
+ end,
+ [C | create_random_string(OfLength - 1)].
+
+create_random_tuple(OfLength) ->
+ list_to_tuple([list_to_atom([X]) || X <- create_random_string(OfLength)]).
+
+ets_match_object(Tab,Expr) ->
+ case random:uniform(2) of
+ 1 -> ets:match_object(Tab,Expr);
+ _ -> match_object_chunked(Tab,Expr)
+ end.
+
+match_object_chunked(Tab,Expr) ->
+ match_object_chunked_collect(ets:match_object(Tab, Expr,
+ random:uniform(1999) + 1)).
+
+match_object_chunked_collect('$end_of_table') ->
+ [];
+match_object_chunked_collect({Results, Continuation}) ->
+ Results ++ match_object_chunked_collect(ets:match_object(Continuation)).
+
+do_n_times(_, 0) ->
+ ok;
+do_n_times(Fun, N) ->
+ Fun(),
+ case N rem 1000 of
+ 0 -> ok; %% WAS: io:format(".");
+ _ -> ok
+ end,
+ do_n_times(Fun, N - 1).
+
+%%-----------------------------------------------------------------------
+%% From: Jozsef Berces (PR/ECZ)
+%% Date: Feb 19, 2004
+%%
+%% Program which was added to the testsuite as a result of another bug
+%% report involving tuples as funs. Thanks God, these are no longer
+%% supported, but the following is a good test for testing calling
+%% native code funs from BEAM code (lists:map, lists:filter, ...).
+%%-----------------------------------------------------------------------
+
+test_szar_bug() ->
+ ["A","B","C"] = smartconcat([], "H'A, H'B, H'C"),
+ ok.
+
+smartconcat(B, L) ->
+ LL = tokenize(L, $,),
+ NewlineDel = fun (X) -> killcontrol(X) end,
+ StripFun = fun (X) -> string:strip(X) end,
+ LL2 = lists:map(NewlineDel, lists:map(StripFun, LL)),
+ EmptyDel = fun(X) ->
+ case string:len(X) of
+ 0 -> false;
+ _ -> true
+ end
+ end,
+ LL3 = lists:filter(EmptyDel, LL2),
+ HexFormat = fun(X, Acc) ->
+ case string:str(X, "H'") of
+ 1 ->
+ case checkhex(string:substr(X, 3)) of
+ {ok, Y} ->
+ {Y, Acc};
+ _ ->
+ {X, Acc + 1}
+ end;
+ _ ->
+ {X, Acc + 1}
+ end
+ end,
+ {LL4,_Ret} = lists:mapfoldl(HexFormat, 0, LL3),
+ lists:append(B, lists:sublist(LL4, lists:max([0, 25 - length(B)]))).
+
+checkhex(L) ->
+ checkhex(L, "").
+
+checkhex([H | T], N) when H >= $0, H =< $9 ->
+ checkhex(T, [H | N]);
+checkhex([H | T], N) when H >= $A, H =< $F ->
+ checkhex(T, [H | N]);
+checkhex([H | T], N) when H =< 32 ->
+ checkhex(T, N);
+checkhex([_ | _], _) ->
+ {error, ""};
+checkhex([], N) ->
+ {ok, lists:reverse(N)}.
+
+killcontrol([C | S]) when C < 32 ->
+ killcontrol(S);
+killcontrol([C | S]) ->
+ [C | killcontrol(S)];
+killcontrol([]) ->
+ [].
+
+tokenize(L, C) ->
+ tokenize(L, C, [], []).
+
+tokenize([C | T], C, A, B) ->
+ case A of
+ [] ->
+ tokenize(T, C, [], B);
+ _ ->
+ tokenize(T, C, [], [lists:reverse(A) | B])
+ end;
+tokenize([H | T], C, A, B) ->
+ tokenize(T, C, [H | A], B);
+tokenize(_, _, [], B) ->
+ lists:reverse(B);
+tokenize(_, _, A, B) ->
+ lists:reverse([lists:reverse(A) | B]).
+
+%%-----------------------------------------------------------------------
+%% From: Niclas Pehrsson
+%% Date: Apr 20, 2006
+%%
+%% We found something weird with the bit shifting in HiPE. It seems
+%% that bsr in some cases shifts the bits in the wrong way...
+%%
+%% Fixed about 10 mins afterwards; was a bug in constant propagation.
+%%-----------------------------------------------------------------------
+
+test_bit_shift() ->
+ 1 = plain_shift(), % 1
+ 6 = length_list_plus(), % 6
+ 0 = shift_length_list(), % 0
+ 1 = shift_length_list_plus(), % 1
+ 1 = shift_length_list_plus2(), % 1
+ 24 = shift_length_list_plus_bsl(), % 24
+ 1 = shift_fun(), % 1
+ %% {1, 6, 0, 1, 1, 24, 1} = {A, B, C, D, E, F, G},
+ ok.
+
+plain_shift() ->
+ 6 bsr 2.
+
+length_list() ->
+ length([0,0]).
+
+length_list_plus() ->
+ length([0,0]) + 4.
+
+shift_length_list() ->
+ length([0,0]) bsr 2.
+
+shift_length_list_plus() ->
+ (length([0,0]) + 4) bsr 2.
+
+shift_length_list_plus_bsl() ->
+ (length([0,0]) + 4) bsl 2.
+
+shift_length_list_plus2() ->
+ N = length([0,0]) + 4,
+ N bsr 2.
+
+shift_fun() ->
+ (length_list() + 4) bsr 2.
+
+%%-----------------------------------------------------------------------
+%% From: Igor Goryachev
+%% Date: June 15, 2006
+%%
+%% I have experienced a different behaviour and possibly a weird result
+%% while playing with matching a big list on x86 and x86_64 machines.
+%%-----------------------------------------------------------------------
+
+-define(BIG_LIST,
+ ["uid", "nickname", "n_family", "n_given", "email_pref",
+ "tel_home_number", "tel_cellular_number", "adr_home_country",
+ "adr_home_locality", "adr_home_region", "url", "gender", "bday",
+ "constitution", "height", "weight", "hair", "routine", "smoke",
+ "maritalstatus", "children", "independence", "school_number",
+ "school_locality", "school_title", "school_period", "org_orgname",
+ "title", "adr_work_locality", "photo_type", "photo_binval"]).
+
+test_match_big_list() ->
+ case create_tuple_with_big_const_list() of
+ {selected, ?BIG_LIST, _} -> ok;
+ _ -> weird
+ end.
+
+create_tuple_with_big_const_list() ->
+ {selected, ?BIG_LIST, [{"test"}]}.
+
+%%-----------------------------------------------------------------------
+%% In October 2006 the HiPE compiler acquired more type-driven
+%% optimisations of arithmetic operations. One of these, the
+%% transformation of bsl to a pure fixnum bsl fixnum -> fixnum version
+%% (unsafe_bsl), was incorrectly performed even when the result
+%% wouldn't be a fixnum. The error occurred for all backends, but the
+%% only place known to break was hipe_arm:imm_to_am1/2. Some
+%% immediates got broken on ARM, causing segmentation faults in
+%% compiler_tests when HiPE recompiled itself.
+%%-----------------------------------------------------------------------
+
+test_unsafe_bsl() ->
+ ok = bsl_check(bsl_test_cases()).
+
+bsl_test_cases() ->
+ [{16#FF, {16#FF, 0}},
+ {16#F000000F, {16#FF, 2}}].
+
+bsl_check([]) -> ok;
+bsl_check([{X, Y}|Rest]) ->
+ case imm_to_am1(X) of
+ Y -> bsl_check(Rest);
+ _ -> 'hipe_broke_bsl'
+ end.
+
+imm_to_am1(Imm) ->
+ imm_to_am1(Imm band 16#FFFFFFFF, 16).
+imm_to_am1(Imm, RotCnt) ->
+ if Imm >= 0, Imm =< 255 -> {Imm, RotCnt band 15};
+ true ->
+ NewRotCnt = RotCnt - 1,
+ if NewRotCnt =:= 0 -> []; % full circle, no joy
+ true ->
+ NewImm = (Imm bsr 2) bor ((Imm band 3) bsl 30),
+ imm_to_am1(NewImm, NewRotCnt)
+ end
+ end.
+
+%%-----------------------------------------------------------------------
+%% Another transformation, namely that of bsr to a pure fixnum bsr
+%% fixnum -> fixnum version (unsafe_bsr), failed to check for shifts
+%% larger than the number of bits in fixnums. Such shifts should
+%% return zero, but instead they became plain machine-level shift
+%% instructions. Machines often only consider the low-order bits of
+%% the shift count, so machine-level shifts larger than the word size
+%% do not match the Erlang semantics.
+%%-----------------------------------------------------------------------
+
+test_unsafe_bsr() ->
+ ok = bsr_check(bsr_test_cases()).
+
+bsr_test_cases() ->
+ [{16#FF, 4, 16#0F},
+ {16#FF, 64, 0}].
+
+bsr_check([]) -> ok;
+bsr_check([{X, Y, Z}|Rest]) ->
+ case do_bsr(X, Y) of
+ Z -> bsr_check(Rest);
+ _ -> 'hipe_broke_bsr'
+ end.
+
+do_bsr(X, Y) ->
+ (X band 16#FFFF) bsr (Y band 16#FFFF).
+
+%%-----------------------------------------------------------------------
+%% From: Sergey S, mid January 2009.
+%%
+%% While I was playing with +native option, I run into a bug in HiPE
+%% which leads to segmentation fault using +native and Erlang R12B-5.
+%%
+%% Eshell V5.6.5
+%% 1> crash:test().
+%% # Some message to be printed here each loop iteration
+%% Segmentation fault
+%%
+%% Diagnosed and fixed by Mikael Pettersson (22 Jan 2009):
+%%
+%% I've analysed the recently posted HiPE bug report on erlang-bugs
+%% <http://www.erlang.org/pipermail/erlang-bugs/2009-January/001162.html>.
+%% The segfault is caused by memory corruption, which in turn is caused
+%% by RTL removing an update of the HP (heap pointer) register due to
+%% what looks like broken liveness information.
+%%-----------------------------------------------------------------------
+
+test_R12B5_seg_fault() ->
+ _ = spawn(fun() -> init() end),
+ ok.
+
+init() ->
+ repeat(5, fun() -> void end),
+ receive after infinity -> ok end.
+
+repeat(0, _) ->
+ ok;
+repeat(N, Fun) ->
+ %% io:format("# Some message to be printed here each loop iteration\n"),
+ Fun(),
+ repeat(N - 1, Fun).
+
+%%-----------------------------------------------------------------------
+%% From: Jon Meredith
+%% Date: July 9, 2009
+%%
+%% Binary search key tables are sorted by the loader based on the
+%% runtime representations of the keys as unsigned words. However,
+%% the code generated for the binary search used signed comparisons.
+%% That worked for atoms and non-negative fixnums, but not for
+%% negative fixnums. Fixed by Mikael Pettersson July 10, 2009.
+%%-----------------------------------------------------------------------
+
+test_switch_neg_int() ->
+ ok = f(-80, 8).
+
+f(10, -1) -> ok;
+f(X, Y) ->
+ Y = g(X),
+ f(X + 10, Y - 1).
+
+g(X) -> % g(0) should be 0 but became -1
+ case X of
+ 0 -> 0;
+ -10 -> 1;
+ -20 -> 2;
+ -30 -> 3;
+ -40 -> 4;
+ -50 -> 5;
+ -60 -> 6;
+ -70 -> 7;
+ -80 -> 8;
+ _ -> -1
+ end.
+
+%%-----------------------------------------------------------------------
+%% From: Paul Guyot
+%% Date: Jan 31, 2011
+%%
+%% There is a bug in HiPE compilation with the comparison of floats
+%% with integers. This bug happens in functions f/1 and g/2 below.
+%% BEAM will evaluate f_eq(42) and f_eq(42.0) to true, while HiPE
+%% will evaluate them to false.
+%%
+%% The culprit was the Icode range analysis which was buggy. (On the
+%% other hand, HiPE properly evaluated these calls to true if passed
+%% the option 'no_icode_range'.) Fixed by Kostis Sagonas.
+%% --------------------------------------------------------------------
+
+test_icode_range_anal() ->
+ true = f_eq(42),
+ true = f_eq(42.0),
+ false = f_ne(42),
+ false = f_ne(42.0),
+ false = f_eq_ex(42),
+ false = f_eq_ex(42.0),
+ true = f_ne_ex(42),
+ true = f_ne_ex(42.0),
+ false = f_gt(42),
+ false = f_gt(42.0),
+ true = f_le(42),
+ true = f_le(42.0),
+ zero_test = g(0, test),
+ zero_test = g(0.0, test),
+ non_zero_test = g(42, test),
+ other = g(42, other),
+ ok.
+
+f_eq(X) ->
+ Y = X / 2,
+ Y == 21.
+
+f_ne(X) ->
+ Y = X / 2,
+ Y /= 21.
+
+f_eq_ex(X) ->
+ Y = X / 2,
+ Y =:= 21.
+
+f_ne_ex(X) ->
+ Y = X / 2,
+ Y =/= 21.
+
+f_gt(X) ->
+ Y = X / 2,
+ Y > 21.
+
+f_le(X) ->
+ Y = X / 2,
+ Y =< 21.
+
+g(X, Z) ->
+ Y = X / 2,
+ case Z of
+ test when Y == 0 -> zero_test;
+ test -> non_zero_test;
+ other -> other
+ end.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_comparisons.erl b/lib/hipe/test/basic_SUITE_data/basic_comparisons.erl
new file mode 100644
index 0000000000..8dab2cab1f
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_comparisons.erl
@@ -0,0 +1,157 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests for correct execution of comparison operators.
+%%%-------------------------------------------------------------------
+-module(basic_comparisons).
+
+-export([test/0]).
+
+test() ->
+ Ns = [0, 0.0, 42, 42.0, gazonk],
+ T1F4 = [true, false, false, false, false],
+ T2F3 = [true, true, false, false, false],
+ F1T4 = [false, true, true, true, true],
+ F2T3 = [false, false, true, true, true],
+ %% tests for calls
+ T1F4 = [eq_exact_call(0, N) || N <- Ns],
+ F1T4 = [ne_exact_call(0, N) || N <- Ns],
+ T2F3 = [eq_call(0, N) || N <- Ns],
+ F2T3 = [ne_call(0, N) || N <- Ns],
+ %% tests for guards
+ T1F4 = [eq_exact_guard(0, N) || N <- Ns],
+ F1T4 = [ne_exact_guard(0, N) || N <- Ns],
+ T2F3 = [eq_guard(0, N) || N <- Ns],
+ F2T3 = [ne_guard(0, N) || N <- Ns],
+ %% some more tests
+ ok = test_against_zero(),
+ ok = test_against_other_terms(),
+ ok = test_sofs_func(),
+ ok.
+
+test_against_zero() ->
+ Xs = [0, 1, 0.0],
+ [true, false, false] = [is_zero_int(X) || X <- Xs],
+ [true, false, true] = [is_zero_num(X) || X <- Xs],
+ [false, true, true] = [is_nonzero_int(X) || X <- Xs],
+ [false, true, false] = [is_nonzero_num(X) || X <- Xs],
+ ok.
+
+test_against_other_terms() ->
+ TTT = {true, true, true},
+ FFF = {false, false, false},
+ TTT = {is_foo_exact(foo), is_foo_term1(foo), is_foo_term2(foo)},
+ FFF = {is_foo_exact(bar), is_foo_term1(bar), is_foo_term2(bar)},
+ FFF = {is_nonfoo_exact(foo), is_nonfoo_term1(foo), is_nonfoo_term2(foo)},
+ TTT = {is_nonfoo_exact(bar), is_nonfoo_term1(bar), is_nonfoo_term2(bar)},
+ Tup = {a, {42}, [c]},
+ TTT = {is_tuple_skel(Tup), is_tuple_exact(Tup), is_tuple_term(Tup)},
+ BNi = <<42>>,
+ TTT = {is_bin_exact(BNi), is_bin_term1(BNi), is_bin_term2(BNi)},
+ BNf = <<42/float>>,
+ FFF = {is_bin_exact(BNf), is_bin_term1(BNf), is_bin_term2(BNf)},
+ ok.
+
+test_sofs_func() ->
+ L = [0, 0.0],
+ ok = sofs_func(L, L, L).
+
+%%--------------------------------------------------------------------
+%% Test for comparison operators used in body calls
+
+eq_exact_call(X, Y) -> X =:= Y.
+
+ne_exact_call(X, Y) -> X =/= Y.
+
+eq_call(X, Y) -> X == Y.
+
+ne_call(X, Y) -> X /= Y.
+
+%%--------------------------------------------------------------------
+%% Tests for comparison operators used as guards
+
+eq_exact_guard(X, Y) when X =:= Y -> true;
+eq_exact_guard(_, _) -> false.
+
+ne_exact_guard(X, Y) when X =/= Y -> true;
+ne_exact_guard(_, _) -> false.
+
+eq_guard(X, Y) when X == Y -> true;
+eq_guard(_, _) -> false.
+
+ne_guard(X, Y) when X /= Y -> true;
+ne_guard(_, _) -> false.
+
+%%--------------------------------------------------------------------
+
+is_zero_int(N) when N =:= 0 -> true;
+is_zero_int(_) -> false.
+
+is_nonzero_int(N) when N =/= 0 -> true;
+is_nonzero_int(_) -> false.
+
+is_zero_num(N) when N == 0 -> true;
+is_zero_num(_) -> false.
+
+is_nonzero_num(N) when N /= 0 -> true;
+is_nonzero_num(_) -> false.
+
+%%--------------------------------------------------------------------
+%% There should not really be any difference in the generated code
+%% for the following three functions.
+
+is_foo_exact(A) when A =:= foo -> true;
+is_foo_exact(_) -> false.
+
+is_foo_term1(A) when A == foo -> true;
+is_foo_term1(_) -> false.
+
+is_foo_term2(A) when foo == A -> true;
+is_foo_term2(_) -> false.
+
+%%--------------------------------------------------------------------
+%% Same for these cases
+
+is_nonfoo_exact(A) when A =/= foo -> true;
+is_nonfoo_exact(_) -> false.
+
+is_nonfoo_term1(A) when A /= foo -> true;
+is_nonfoo_term1(_) -> false.
+
+is_nonfoo_term2(A) when foo /= A -> true;
+is_nonfoo_term2(_) -> false.
+
+%%--------------------------------------------------------------------
+
+is_tuple_skel({A,{B},[C]}) when is_atom(A), is_integer(B), is_atom(C) -> true;
+is_tuple_skel(T) when is_tuple(T) -> false.
+
+is_tuple_exact(T) when T =:= {a,{42},[c]} -> true;
+is_tuple_exact(T) when is_tuple(T) -> false.
+
+is_tuple_term(T) when T == {a,{42.0},[c]} -> true;
+is_tuple_term(T) when is_tuple(T) -> false.
+
+%%--------------------------------------------------------------------
+%% But for binaries the treatment has to be different, due to the need
+%% for construction of the binary in the guard.
+
+is_bin_exact(B) when B =:= <<42>> -> true;
+is_bin_exact(_) -> false.
+
+is_bin_term1(B) when B == <<42>> -> true;
+is_bin_term1(_) -> false.
+
+is_bin_term2(B) when <<42>> == B -> true;
+is_bin_term2(_) -> false.
+
+%%--------------------------------------------------------------------
+%% a test from sofs.erl which failed at some point
+
+sofs_func([X | Ts], X0, L) when X /= X0 ->
+ sofs_func(Ts, X, L);
+sofs_func([X | _Ts], X0, _L) when X == X0 ->
+ ok;
+sofs_func([], _X0, L) ->
+ L.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl b/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl
new file mode 100644
index 0000000000..229a0516dc
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl
@@ -0,0 +1,465 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that raise exceptions and catch them.
+%%%-------------------------------------------------------------------
+-module(basic_exceptions).
+
+-export([test/0, test_catches/0]).
+
+%% functions used as arguments to spawn/3
+-export([bad_guy/2]).
+
+test() ->
+ ok = test_catch_exit(42),
+ ok = test_catch_throw(42),
+ ok = test_catch_element(),
+ ok = test_catch_crash(),
+ ok = test_catch_empty(),
+ ok = test_catch_merge(),
+ ok = test_catches_merged(),
+ ok = test_pending_errors(),
+ ok = test_bad_fun_call(),
+ ok = test_guard_bif(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Written in 2001 by Erik Johansson.
+
+test_catches() ->
+ ExitBar = {'EXIT', bar},
+ L1 = [ExitBar, ok, ExitBar, {ok, ExitBar}],
+ L1 = [t1(), t2(), t3(), t4()],
+ badarith = (catch element(1, element(2, t5(a, b)))),
+ L2 = [42, ExitBar, ExitBar, {no_exception, ok}],
+ L2 = [t5(21, 21), t6(), t7(), t8()],
+ ok.
+
+t1() ->
+ catch foo().
+
+t2() ->
+ V = (catch ok()),
+ s(),
+ V.
+
+t3() ->
+ V = (catch foo()),
+ V.
+
+t4() ->
+ V1 = ok(),
+ V2 = (catch foo()),
+ {V1, V2}.
+
+t5(A, B) ->
+ catch A + B.
+
+t6() ->
+ catch {no_exception, ok(), foo()}.
+
+t7() ->
+ catch {no_exception, foo(), ok()}.
+
+t8() ->
+ catch {no_exception, ok()}.
+
+foo() ->
+ s(),
+ exit(bar).
+
+ok() -> s(), ok.
+
+s() -> nada.
+
+%%--------------------------------------------------------------------
+
+test_catch_exit(N) ->
+ {'EXIT', N} = (catch exit(N)),
+ {'EXIT', 42} = (catch exit(42)),
+ 42 = try exit(N) catch exit:R1 -> R1 end,
+ 42 = try exit(42) catch exit:R2 -> R2 end,
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_catch_throw(N) ->
+ N = (catch throw(N)),
+ 42 = (catch throw(42)),
+ 42 = try throw(N) catch throw:R1 -> R1 end,
+ 42 = try throw(42) catch throw:R2 -> R2 end,
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_catch_element() ->
+ 'EXIT' = test_catch_element([]),
+ 'EXIT' = test_catch_element(42),
+ ok.
+
+test_catch_element(N) ->
+ element(1, catch element(N, {1,2,3,4,5,6,7,8,9,10,11})).
+
+%%--------------------------------------------------------------------
+
+-define(try_match(E),
+ catch ?MODULE:non_existing(),
+ {'EXIT', {{badmatch, nomatch}, _}} = (catch E = no_match())).
+
+test_catch_crash() ->
+ ?try_match(a),
+ ?try_match(42),
+ ?try_match({a, b, c}),
+ ?try_match([]),
+ ?try_match(1.0),
+ ok.
+
+no_match() -> nomatch.
+
+%% small_test() ->
+%% catch ?MODULE:non_existing(),
+%% io:format("Before\n",[]),
+%% hipe_bifs:show_nstack(self()),
+%% io:format("After\n",[]),
+%% garbage_collect().
+
+%%--------------------------------------------------------------------
+%% Tests whether the HiPE compiler optimizes catches in a way that
+%% does not result in an infinite loop.
+%%--------------------------------------------------------------------
+
+test_catch_empty() ->
+ badmatch().
+
+badmatch() ->
+ Big = ret_big(),
+ Float = ret_float(),
+ catch a = Big,
+ catch b = Float,
+ ok = case Big of Big -> ok end,
+ ok = case Float of Float -> ok end,
+ ok.
+
+ret_big() ->
+ 329847987298478924982978248748729829487298292982972978239874.
+
+ret_float() ->
+ 3.1415927.
+
+%%--------------------------------------------------------------------
+%% Test that shows how BEAM can merge catch-end blocks that belong to
+%% different catch-start instructions. Written by Richard Carlsson.
+%%--------------------------------------------------------------------
+
+test_catch_merge() ->
+ merge(get(whatever)).
+
+merge(foo=X) ->
+ catch f(X),
+ catch g(X);
+merge(X) ->
+ catch f(X),
+ catch g(X).
+
+f(_) -> ok.
+
+g(_) -> ok.
+
+%%--------------------------------------------------------------------
+%% Written by Tobias Lindahl.
+
+test_catches_merged() ->
+ {'EXIT', _} = merged_catches(foo),
+ {'EXIT', {badarith, _}} = merged_catches(bar),
+ {'EXIT', _} = merged_catches(baz),
+ ok.
+
+merged_catches(X) ->
+ case X of
+ foo -> catch fail1(0);
+ bar -> catch {catch(1 = X), fail2(0)};
+ baz -> catch fail3(0)
+ end.
+
+fail1(X) -> 1/X.
+
+fail2(X) -> 1/X.
+
+fail3(X) -> 1/X.
+
+%%--------------------------------------------------------------------
+%% Taken from exception_SUITE.erl
+%%--------------------------------------------------------------------
+
+test_pending_errors() ->
+ error_logger:tty(false), % disable printouts of error reports
+ pending_errors().
+
+%% Test various exceptions, in the presence of a previous error
+%% suppressed in a guard.
+pending_errors() ->
+ pending(e_badmatch, {badmatch, b}),
+ pending(x, function_clause),
+ pending(e_case, {case_clause, xxx}),
+ pending(e_if, if_clause),
+ %% pending(e_badarith, badarith),
+ %% pending(e_undef, undef),
+ pending(e_timeoutval, timeout_value),
+ %% pending(e_badarg, badarg),
+ %% pending(e_badarg_spawn, badarg),
+ ok.
+
+bad_guy(pe_badarith, Other) when Other+1 =:= 0 -> % badarith (suppressed)
+ ok;
+bad_guy(pe_badarg, Other) when length(Other) > 0 -> % badarg (suppressed)
+ ok;
+bad_guy(_, e_case) ->
+ case xxx() of
+ ok -> ok
+ end; % case_clause
+bad_guy(_, e_if) ->
+ B = b(),
+ if
+ a == B -> ok
+ end; % if_clause
+%% bad_guy(_, e_badarith) ->
+%% 1+b; % badarith
+bad_guy(_, e_undef) ->
+ non_existing_module:foo(); % undef
+bad_guy(_, e_timeoutval) ->
+ receive
+ after gazonk -> ok % timeout_value
+ end;
+bad_guy(_, e_badarg) ->
+ node(xxx); % badarg
+bad_guy(_, e_badarg_spawn) ->
+ spawn({}, {}, {}); % badarg
+bad_guy(_, e_badmatch) ->
+ a = b(). % badmatch
+
+xxx() -> xxx.
+
+b() -> b.
+
+pending(Arg, Expected) ->
+ pending(pe_badarith, Arg, Expected),
+ pending(pe_badarg, Arg, Expected).
+
+pending(First, Second, Expected) ->
+ pending_catched(First, Second, Expected),
+ pending_exit_message([First, Second], Expected).
+
+pending_catched(First, Second, Expected) ->
+ %% ok = io:format("Catching bad_guy(~p, ~p)\n", [First, Second]),
+ case catch bad_guy(First, Second) of
+ {'EXIT', Reason} ->
+ pending(Reason, bad_guy, [First, Second], Expected);
+ Other ->
+ exit({not_exit, Other})
+ end.
+
+pending_exit_message(Args, Expected) ->
+ %% ok = io:format("Trapping exits from spawn_link(~p, ~p, ~p)\n",
+ %% [?MODULE, bad_guy, Args]),
+ process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, bad_guy, Args),
+ receive
+ {'EXIT', Pid, Reason} ->
+ pending(Reason, bad_guy, Args, Expected);
+ Other ->
+ exit({unexpected_message, Other})
+ after 10000 ->
+ exit(timeout)
+ end,
+ process_flag(trap_exit, false).
+
+%% pending({badarg, [{erlang,Bif,BifArgs},{?MODULE,Func,Arity}|_]},
+%% Func, Args, _Code)
+%% when atom(Bif), list(BifArgs), length(Args) =:= Arity ->
+%% ok;
+pending({badarg,Trace}, _, _, _) when is_list(Trace) ->
+ ok;
+%% pending({undef,[{non_existing_module,foo,[]}|_]}, _, _, _) ->
+%% ok;
+pending({undef,Trace}, _, _, _) when is_list(Trace) ->
+ ok;
+%% pending({function_clause,[{?MODULE,Func,Args}|_]}, Func, Args, _Code) ->
+%% ok;
+pending({function_clause,Trace}, _, _, _) when is_list(Trace) ->
+ ok;
+%% pending({Code,[{?MODULE,Func,Arity}|_]}, Func, Args, Code)
+%% when length(Args) =:= Arity ->
+%% ok;
+pending({Code,Trace}, _, _, Code) when is_list(Trace) ->
+ ok;
+pending(Reason, _Function, _Args, _Code) ->
+ exit({bad_exit_reason, Reason}).
+
+%%--------------------------------------------------------------------
+%% Taken from fun_SUITE.erl
+%%
+%% Checks correct exception throwing when calling a bad fun.
+%%--------------------------------------------------------------------
+
+test_bad_fun_call() ->
+ ok = bad_call_fc(42),
+ ok = bad_call_fc(xx),
+ ok = bad_call_fc({}),
+ ok = bad_call_fc({1}),
+ ok = bad_call_fc({1,2,3}),
+ ok = bad_call_fc({1,2,3}),
+ ok = bad_call_fc({1,2,3,4}),
+ ok = bad_call_fc({1,2,3,4,5,6}),
+ ok = bad_call_fc({1,2,3,4,5}),
+ ok = bad_call_fc({1,2}),
+ ok.
+
+bad_call_fc(Fun) ->
+ Args = [some, stupid, args],
+ Res = (catch Fun(Fun(Args))),
+ case Res of
+ {'EXIT', {{badfun, Fun} ,_Where}} ->
+ ok; %% = io:format("~p(~p) -> ~p\n", [Fun, Args, Res]);
+ Other ->
+ io:format("~p(~p) -> ~p\n", [Fun, Args, Res]),
+ exit({bad_result, Other})
+ end.
+
+%%--------------------------------------------------------------------
+%% Taken from guard_SUITE.erl
+%%
+%% Tests correct handling of exceptions by calling guard BIFs with
+%% nasty (but legal arguments).
+%%--------------------------------------------------------------------
+
+test_guard_bif() ->
+ Big = -237849247829874297658726487367328971246284736473821617265433,
+ Float = 387924.874,
+
+ %% Succeding use of guard bifs.
+
+ try_gbif('abs/1', Big, -Big),
+ try_gbif('float/1', Big, float(Big)),
+ try_gbif('trunc/1', Float, 387924.0),
+ try_gbif('round/1', Float, 387925.0),
+ try_gbif('length/1', [], 0),
+
+ try_gbif('length/1', [a], 1),
+ try_gbif('length/1', [a, b], 2),
+ try_gbif('length/1', lists:seq(0, 31), 32),
+
+ try_gbif('hd/1', [a], a),
+ try_gbif('hd/1', [a, b], a),
+
+ try_gbif('tl/1', [a], []),
+ try_gbif('tl/1', [a, b], [b]),
+ try_gbif('tl/1', [a, b, c], [b, c]),
+
+ try_gbif('size/1', {}, 0),
+ try_gbif('size/1', {a}, 1),
+ try_gbif('size/1', {a, b}, 2),
+ try_gbif('size/1', {a, b, c}, 3),
+ try_gbif('size/1', list_to_binary([]), 0),
+ try_gbif('size/1', list_to_binary([1]), 1),
+ try_gbif('size/1', list_to_binary([1, 2]), 2),
+ try_gbif('size/1', list_to_binary([1, 2, 3]), 3),
+
+ try_gbif('element/2', {x}, {1, x}),
+ try_gbif('element/2', {x, y}, {1, x}),
+ try_gbif('element/2', {x, y}, {2, y}),
+
+ try_gbif('self/0', 0, self()),
+ try_gbif('node/0', 0, node()),
+ try_gbif('node/1', self(), node()),
+
+ %% Failing use of guard bifs.
+
+ try_fail_gbif('abs/1', Big, 1),
+ try_fail_gbif('abs/1', [], 1),
+
+ try_fail_gbif('float/1', Big, 42),
+ try_fail_gbif('float/1', [], 42),
+
+ try_fail_gbif('trunc/1', Float, 0.0),
+ try_fail_gbif('trunc/1', [], 0.0),
+
+ try_fail_gbif('round/1', Float, 1.0),
+ try_fail_gbif('round/1', [], a),
+
+ try_fail_gbif('length/1', [], 1),
+ try_fail_gbif('length/1', [a], 0),
+ try_fail_gbif('length/1', a, 0),
+ try_fail_gbif('length/1', {a}, 0),
+
+ try_fail_gbif('hd/1', [], 0),
+ try_fail_gbif('hd/1', [a], x),
+ try_fail_gbif('hd/1', x, x),
+
+ try_fail_gbif('tl/1', [], 0),
+ try_fail_gbif('tl/1', [a], x),
+ try_fail_gbif('tl/1', x, x),
+
+ try_fail_gbif('size/1', {}, 1),
+ try_fail_gbif('size/1', [], 0),
+ try_fail_gbif('size/1', [a], 1),
+ try_fail_gbif('size/1', fun() -> 1 end, 0),
+ try_fail_gbif('size/1', fun() -> 1 end, 1),
+
+ try_fail_gbif('element/2', {}, {1, x}),
+ try_fail_gbif('element/2', {x}, {1, y}),
+ try_fail_gbif('element/2', [], {1, z}),
+
+ try_fail_gbif('self/0', 0, list_to_pid("<0.0.0>")),
+ try_fail_gbif('node/0', 0, xxxx),
+ try_fail_gbif('node/1', self(), xxx),
+ try_fail_gbif('node/1', yyy, xxx),
+ ok.
+
+try_gbif(Id, X, Y) ->
+ case guard_bif(Id, X, Y) of
+ {Id, X, Y} ->
+ %% io:format("guard_bif(~p, ~p, ~p) -- ok\n", [Id, X, Y]);
+ ok;
+ Other ->
+ ok = io:format("guard_bif(~p, ~p, ~p) -- bad result: ~p\n",
+ [Id, X, Y, Other]),
+ exit({bad_result,try_gbif})
+ end.
+
+try_fail_gbif(Id, X, Y) ->
+ case catch guard_bif(Id, X, Y) of
+ %% {'EXIT', {function_clause,[{?MODULE,guard_bif,[Id,X,Y]}|_]}} ->
+ {'EXIT', {function_clause,_}} -> % in HiPE, a trace is not generated
+ %% io:format("guard_bif(~p, ~p, ~p) -- ok\n", [Id,X,Y]);
+ ok;
+ Other ->
+ ok = io:format("guard_bif(~p, ~p, ~p) -- bad result: ~p\n",
+ [Id, X, Y, Other]),
+ exit({bad_result,try_fail_gbif})
+ end.
+
+guard_bif('abs/1', X, Y) when abs(X) == Y ->
+ {'abs/1', X, Y};
+guard_bif('float/1', X, Y) when float(X) == Y ->
+ {'float/1', X, Y};
+guard_bif('trunc/1', X, Y) when trunc(X) == Y ->
+ {'trunc/1', X, Y};
+guard_bif('round/1', X, Y) when round(X) == Y ->
+ {'round/1', X, Y};
+guard_bif('length/1', X, Y) when length(X) == Y ->
+ {'length/1', X, Y};
+guard_bif('hd/1', X, Y) when hd(X) == Y ->
+ {'hd/1', X, Y};
+guard_bif('tl/1', X, Y) when tl(X) == Y ->
+ {'tl/1', X, Y};
+guard_bif('size/1', X, Y) when size(X) == Y ->
+ {'size/1', X, Y};
+guard_bif('element/2', X, {Pos, Expected}) when element(Pos, X) == Expected ->
+ {'element/2', X, {Pos, Expected}};
+guard_bif('self/0', X, Y) when self() == Y ->
+ {'self/0', X, Y};
+guard_bif('node/0', X, Y) when node() == Y ->
+ {'node/0', X, Y};
+guard_bif('node/1', X, Y) when node(X) == Y ->
+ {'node/1', X, Y}.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_floats.erl b/lib/hipe/test/basic_SUITE_data/basic_floats.erl
new file mode 100644
index 0000000000..eec175075a
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_floats.erl
@@ -0,0 +1,180 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that manipulate floating point numbers.
+%%%-------------------------------------------------------------------
+-module(basic_floats).
+
+-export([test/0]).
+-export([test_fmt_double_fpe_leak/0]). % suppress the unused warning
+
+test() ->
+ ok = test_arith_ops(),
+ ok = test_fp_ebb(),
+ ok = test_fp_phi(),
+ ok = test_big_bad_float(),
+ ok = test_catch_bad_fp_arith(),
+ ok = test_catch_fp_conv(),
+ ok = test_fp_with_fp_exceptions(),
+ %% ok = test_fmt_double_fpe_leak(), % this requires printing
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_arith_ops() ->
+ E = 2.5617,
+ 5.703200000000001 = add(E),
+ 0.5798000000000001 = sub(E),
+ 8.047580550000001 = mult(E),
+ -6.023e23 = negate(6.023e23),
+ ok.
+
+add(X) ->
+ 3.1415 + X.
+
+sub(X) ->
+ 3.1415 - X.
+
+mult(X) ->
+ 3.1415 * X.
+
+%% tests the translation of the fnegate BEAM instruction.
+negate(X) ->
+ - (X + 0.0).
+
+%%--------------------------------------------------------------------
+%% Test the construction of overlapping extended basic blocks where
+%% BEAM has constructed one and hipe_icode_fp constructs the other.
+%%--------------------------------------------------------------------
+
+test_fp_ebb() ->
+ 1.0 = foo(2 * math:pi()),
+ 1.0 = bar(2 * math:pi()),
+ ok.
+
+foo(X) ->
+ X / (2 * math:pi()).
+
+bar(X) ->
+ F = float_two(),
+ case F < 3.0 of
+ true -> (X * F) / ((2 * F) * math:pi());
+ false -> weird
+ end.
+
+float_two() ->
+ 2.0.
+
+%%--------------------------------------------------------------------
+
+test_fp_phi() ->
+ 10 = fp_phi(10, 100),
+ undefined = fp_phi(1.1e302, 0.000000001),
+ ok.
+
+fp_phi(A, B) ->
+ case catch A / B of
+ {'EXIT', _Reason} -> undefined;
+ _ -> round(100 * (A / B))
+ end.
+
+%%--------------------------------------------------------------------
+
+-define(BS, "93904329458954829589425849258998492384932849328493284932849328493284932389248329432932483294832949245827588578423578435783475834758375837580745807304258924584295924588459834958349589348589345934859384958349583945893458934859438593485995348594385943859438593458934589345938594385934859483958348934589435894859485943859438594594385938459438595034950439504395043950495043593485943758.0").
+
+test_big_bad_float() ->
+ ok = try f2l(?BS) catch error:badarg -> ok end,
+ ok = case catch f2l(?BS) of {'EXIT', {badarg, _}} -> ok end,
+ ok.
+
+f2l(F) ->
+ float_to_list(list_to_float(F)).
+
+%%--------------------------------------------------------------------
+%% Tests catching of floating point bad arithmetic.
+
+test_catch_bad_fp_arith() ->
+ 5.7 = f(2.56),
+ {'EXIT', {badarith, _}} = bad_arith(9.9),
+ ok.
+
+f(F) when is_float(F) -> F + 3.14.
+
+bad_arith(F) when is_float(F) ->
+ catch F * 1.70000e+308.
+
+%%--------------------------------------------------------------------
+%% Tests proper catching of exceptions due to illegal convertion of
+%% bignums to floating point numbers.
+
+test_catch_fp_conv() ->
+ F = 1.7e308, %% F is a number very close to a maximum float.
+ ok = big_arith(F),
+ ok = big_const_float(F),
+ ok.
+
+big_arith(F) ->
+ I = trunc(F),
+ {'EXIT', {badarith, _}} = big_int_arith(I),
+ ok.
+
+big_int_arith(I) when is_integer(I) ->
+ catch(3.0 + 2*I).
+
+big_const_float(F) ->
+ I = trunc(F),
+ badarith = try (1/(2*I)) catch error:Err -> Err end,
+ _ = 2/I,
+ {'EXIT', _} = (catch 4/(2*I)),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Forces floating point exceptions and tests that subsequent, legal,
+%% operations are calculated correctly.
+
+test_fp_with_fp_exceptions() ->
+ 0.0 = math:log(1.0),
+ badarith = try math:log(float_minus_one()) catch error:E1 -> E1 end,
+ 0.0 = math:log(1.0),
+ badarith = try math:log(float_zero()) catch error:E2 -> E2 end,
+ 0.0 = math:log(1.0),
+ %% An old-fashioned exception here just so as to test this case also
+ {'EXIT', _} = (catch fp_mult(3.23e133, 3.57e257)),
+ 0.0 = math:log(1.0),
+ badarith = try fp_div(5.0, 0.0) catch error:E3 -> E3 end,
+ 0.0 = math:log(1.0),
+ ok.
+
+fp_mult(X, Y) -> X * Y.
+
+fp_div(X, Y) -> X / Y.
+
+%% The following two function definitions appear here just to shut
+%% off 'expression will fail with a badarg' warnings from the compiler
+
+float_zero() -> 0.0.
+
+float_minus_one() -> -1.0.
+
+%%--------------------------------------------------------------------
+%% Test that erl_printf_format.c:fmt_double() does not leak pending FP
+%% exceptions to subsequent code. This used to break x87 FP code on
+%% 32-bit x86. Based on a problem report from Richard Carlsson.
+
+test_fmt_double_fpe_leak() ->
+ test_fmt_double_fpe_leak(float_zero(), int_two()),
+ ok.
+
+%% We need the specific sequence of erlang:display/1 on a float that
+%% triggers faulting ops in fmt_double() followed by a simple FP BIF.
+%% We also need to repeat this at least three times.
+test_fmt_double_fpe_leak(X, Y) ->
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X),
+ math:log10(Y).
+
+int_two() -> 2.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_fun.erl b/lib/hipe/test/basic_SUITE_data/basic_fun.erl
new file mode 100644
index 0000000000..18ba7fdb3f
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_fun.erl
@@ -0,0 +1,124 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Tests for correct handling of funs.
+%%%-------------------------------------------------------------------
+-module(basic_fun).
+
+-export([test/0]).
+
+-export([dummy_foo/4, add1/1, test_fun03/0]).
+
+test() ->
+ ok = test_calls(),
+ ok = test_is_function(),
+ ok = test_is_function2(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests function and fun calls.
+
+test_calls() ->
+ ok = test_apply_call(?MODULE, dummy_foo),
+ ok = test_fun_call(fun dummy_foo/4),
+ ok = test_fun_call(fun ?MODULE:dummy_foo/4),
+ ok.
+
+test_apply_call(M, F) ->
+ M:F(bar, 42, foo, 17).
+
+test_fun_call(Fun) ->
+ Fun(bar, 42, foo, 17).
+
+dummy_foo(_, _, foo, _) -> ok.
+
+%%--------------------------------------------------------------------
+%% Tests handling of funs out of exported functions and 2-tuple funs.
+
+test_fun03() ->
+ MFPair = add1_as_2tuple(),
+ 4712 = do_call(add1_as_export(), 4711),
+ {badfun, MFPair} = try do_call(MFPair, 88) catch error:Err -> Err end,
+ true = do_guard(add1_as_export()),
+ false = do_guard(MFPair), % 2-tuples do not satisfy is_function/1
+ ok.
+
+do_call(F, X) -> F(X).
+
+do_guard(F) when is_function(F) -> true;
+do_guard(_) -> false.
+
+add1_as_export() -> fun ?MODULE:add1/1.
+
+add1_as_2tuple() -> {?MODULE, add1}.
+
+add1(X) -> X+1.
+
+%%--------------------------------------------------------------------
+%% Tests the is_function guard and BIF.
+
+test_is_function() ->
+ Fun = fun (X, foo) -> dummy_foo(X, mnesia_lib, foo, [X]) end,
+ ok = test_when_guard(Fun),
+ ok = test_if_guard(Fun),
+ ok.
+
+test_when_guard(X) when is_function(X) -> ok.
+
+test_if_guard(X) ->
+ if is_function(X) -> ok;
+ true -> weird
+ end.
+
+%%--------------------------------------------------------------------
+%% Tests the is_function2 guard and BIF.
+
+test_is_function2() ->
+ ok = test_guard(),
+ ok = test_guard2(),
+ ok = test_call(),
+ ok.
+
+test_guard() ->
+ zero_fun = test_f2(fun () -> ok end),
+ unary_fun = test_f2(fun(X) -> X end),
+ binary_fun = test_f2(fun (X, Y) -> {X, Y} end),
+ no_fun = test_f2(gazonk),
+ ok.
+
+test_f2(Fun) when is_function(Fun, 0) ->
+ zero_fun;
+test_f2(Fun) when is_function(Fun, 1) ->
+ unary_fun;
+test_f2(Fun) when is_function(Fun, 2) ->
+ binary_fun;
+test_f2(_) ->
+ no_fun.
+
+test_guard2() ->
+ zero_fun = test_f2_n(fun () -> ok end, 0),
+ unary_fun = test_f2_n(fun (X) -> X end, 1),
+ binary_fun = test_f2_n(fun (X, Y) -> {X, Y} end, 2),
+ no_fun = test_f2_n(gazonk, 0),
+ ok.
+
+test_f2_n(F, N) when is_function(F, N) ->
+ case N of
+ 0 -> zero_fun;
+ 1 -> unary_fun;
+ 2 -> binary_fun
+ end;
+test_f2_n(_, _) ->
+ no_fun.
+
+test_call() ->
+ true = test_fn2(fun (X, Y) -> {X,Y} end, 2),
+ false = test_fn2(fun (X, Y) -> {X,Y} end, 3),
+ false = test_fn2(gazonk, 2),
+ {'EXIT', {badarg, _TR1}} = (catch test_fn2(gazonk, gazonk)),
+ {'EXIT', {badarg, _TR2}} = (catch test_fn2(fun (X, Y) -> {X, Y} end, gazonk)),
+ ok.
+
+test_fn2(F, N) ->
+ is_function(F, N).
diff --git a/lib/hipe/test/basic_SUITE_data/basic_guards.erl b/lib/hipe/test/basic_SUITE_data/basic_guards.erl
new file mode 100644
index 0000000000..81eeed7c3b
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_guards.erl
@@ -0,0 +1,164 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests for correct handling of guards and guard BIFs.
+%%%-------------------------------------------------------------------
+-module(basic_guards).
+
+-export([test/0]).
+%% Prevent the inlining of the following functions
+-export([bad_arith/0, bad_tuple/0, is_strange_guard/0]).
+
+test() ->
+ ok = guard0(4.2),
+ ok = guard1([foo]),
+ ok = test_guard2(),
+ ok = test_guard3(),
+ ok = test_guard4(),
+ ok = test_is_boolean(),
+ ok = test_bad_guards(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+guard0(X) when X /= 0, is_float(X) ->
+ ok.
+
+guard1(X) when is_atom(X) orelse is_float(X) ->
+ error1;
+guard1(X) when is_reference(hd(X)) ->
+ error2;
+guard1(X) when is_integer(hd(X)) ->
+ error3;
+guard1(X) when hd(X) == foo ->
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_guard2() ->
+ ok1 = guard2(true),
+ not_boolean = guard2(42),
+ ok2 = guard2(false),
+ ok.
+
+guard2(X) when X -> % gets transformed to: is_boolean(X), X =:= true
+ ok1;
+guard2(X) when X =:= false ->
+ ok2;
+guard2(_) ->
+ not_boolean.
+
+%%--------------------------------------------------------------------
+
+-define(is_foo(X), (is_atom(X) or (is_tuple(X) and (element(1, X) =:= 'foo')))).
+
+test_guard3() ->
+ no = f('foo'),
+ yes = f({'foo', 42}),
+ no = f(42),
+ ok.
+
+f(X) when ?is_foo(X) -> yes;
+f(_) -> no.
+
+%%--------------------------------------------------------------------
+
+-define(EXT_REF, <<131,114,0,3,100,0,19,114,101,102,95,116,101,115,116,95,98,117,103,64,103,111,114,98,97,103,2,0,0,0,125,0,0,0,0,0,0,0,0>>).
+
+test_guard4() ->
+ yes = is_ref(make_ref()),
+ no = is_ref(gazonk),
+ yes = is_ref(an_external_ref(?EXT_REF)),
+ ok.
+
+is_ref(Ref) when is_reference(Ref) -> yes;
+is_ref(_Ref) -> no.
+
+an_external_ref(Bin) ->
+ binary_to_term(Bin).
+
+%%--------------------------------------------------------------------
+
+test_is_boolean() ->
+ ok = is_boolean_in_if(),
+ ok = is_boolean_in_guard().
+
+is_boolean_in_if() ->
+ ok1 = tif(true),
+ ok2 = tif(false),
+ not_bool = tif(other),
+ ok.
+
+is_boolean_in_guard() ->
+ ok = tg(true),
+ ok = tg(false),
+ not_bool = tg(other),
+ ok.
+
+tif(V) ->
+ Yes = yes(), %% just to prevent the optimizer removing this
+ if
+ %% the following line generates an is_boolean instruction
+ V, Yes == yes ->
+ %% while the following one does not (?!)
+ %% Yes == yes, V ->
+ ok1;
+ not(not(not(V))) ->
+ ok2;
+ V ->
+ ok3;
+ true ->
+ not_bool
+ end.
+
+tg(V) when is_boolean(V) ->
+ ok;
+tg(_) ->
+ not_bool.
+
+yes() -> yes.
+
+%%--------------------------------------------------------------------
+%% original test by Bjorn G
+
+test_bad_guards() ->
+ ok = bad_arith(),
+ ok = bad_tuple(),
+ ok = is_strange_guard(),
+ ok.
+
+bad_arith() ->
+ 13 = bad_arith1(1, 12),
+ 42 = bad_arith1(1, infinity),
+ 42 = bad_arith1(infinity, 1),
+ 42 = bad_arith2(infinity, 1),
+ 42 = bad_arith3(inf),
+ 42 = bad_arith4(infinity, 1),
+ ok.
+
+bad_arith1(T1, T2) when (T1 + T2) < 17 -> T1 + T2;
+bad_arith1(_, _) -> 42.
+
+bad_arith2(T1, T2) when (T1 * T2) < 17 -> T1 * T2;
+bad_arith2(_, _) -> 42.
+
+bad_arith3(T) when (bnot T) < 17 -> T;
+bad_arith3(_) -> 42.
+
+bad_arith4(T1, T2) when (T1 bsr T2) < 10 -> T1 bsr T2;
+bad_arith4(_, _) -> 42.
+
+bad_tuple() ->
+ error = bad_tuple1(a),
+ error = bad_tuple1({a, b}),
+ x = bad_tuple1({x, b}),
+ y = bad_tuple1({a, b, y}),
+ ok.
+
+bad_tuple1(T) when element(1, T) =:= x -> x;
+bad_tuple1(T) when element(3, T) =:= y -> y;
+bad_tuple1(_) -> error.
+
+is_strange_guard() when is_tuple({1, bar, length([1, 2, 3, 4]), self()}) -> ok;
+is_strange_guard() -> error.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_inline_function.erl b/lib/hipe/test/basic_SUITE_data/basic_inline_function.erl
new file mode 100644
index 0000000000..4c08064670
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_inline_function.erl
@@ -0,0 +1,73 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that depend on the compiler inliner being turned on.
+%%%-------------------------------------------------------------------
+-module(basic_inline_function).
+
+-export([test/0]).
+
+-compile({inline, [{to_objects, 3}]}).
+
+test() ->
+ ok = test_inline_match(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_inline_match() ->
+ bad_object = test1(a, {binary, foo, set}, c),
+ bad_object = test2(a, {binary, foo, set}, c),
+ bad_object = test3(a, {binary, foo, set}, c),
+ ok.
+
+%% Inlined
+test1(KeysObjs, C, Ts) ->
+ case catch to_objects(KeysObjs, C, Ts) of
+ {'EXIT', _} ->
+ bad_object;
+ ok ->
+ ok
+ end.
+
+%% "Inlined" by hand
+test2(KeysObjs, C, _Ts) ->
+ case catch (case C of
+ {binary, _, set} ->
+ <<_ObjSz0:32, _T/binary>> = KeysObjs;
+ _ -> ok
+ end) of
+ {'EXIT', _} ->
+ bad_object;
+ ok ->
+ ok
+ end.
+
+%% Not inlined
+test3(KeysObjs, C, Ts) ->
+ case catch fto_objects(KeysObjs, C, Ts) of
+ {'EXIT', _} ->
+ bad_object;
+ ok ->
+ ok
+ end.
+
+%% Inlined.
+to_objects(Bin, {binary, _, set}, _Ts) ->
+ <<_ObjSz0:32, _T/binary>> = Bin,
+ ok;
+to_objects(<<_ObjSz0:32, _T/binary>> ,_, _) ->
+ ok;
+to_objects(_Bin, _, _Ts) ->
+ ok.
+
+%% Not Inlined.
+fto_objects(Bin, {binary, _, set}, _Ts) ->
+ <<_ObjSz0:32, _T/binary>> = Bin,
+ ok;
+fto_objects(<<_ObjSz0:32, _T/binary>> ,_,_) ->
+ ok;
+fto_objects(_Bin, _, _Ts) ->
+ ok.
+
diff --git a/lib/hipe/test/basic_SUITE_data/basic_inline_module.erl b/lib/hipe/test/basic_SUITE_data/basic_inline_module.erl
new file mode 100644
index 0000000000..306c6a39ce
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_inline_module.erl
@@ -0,0 +1,31 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that depend on the compiler inliner being turned on.
+%%%-------------------------------------------------------------------
+-module(basic_inline_module).
+
+-export([test/0]).
+
+-compile([inline]). %% necessary for these tests
+
+test() ->
+ ok = test_case_end_atom(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests whether the translation of a case_end instruction works even
+%% when an exception (no matching case pattern) is to be raised.
+
+test_case_end_atom() ->
+ {'EXIT',{{case_clause,some_atom},_Trace}} = (catch test_case_stm_inlining()),
+ ok.
+
+test_case_stm_inlining() ->
+ case some_atom() of
+ another_atom -> strange_result
+ end.
+
+some_atom() ->
+ some_atom.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_issues_beam.erl b/lib/hipe/test/basic_SUITE_data/basic_issues_beam.erl
new file mode 100644
index 0000000000..73367c5c45
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_issues_beam.erl
@@ -0,0 +1,326 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples, mostly taken from the mailing list, that
+%%% crashed the BEAM compiler or gave an internal error at some point.
+%%%-------------------------------------------------------------------
+-module(basic_issues_beam).
+
+-export([test/0]).
+
+test() ->
+ ok = test_crash_R10_hinde(),
+ ok = test_error_R10_mander(),
+ ok = test_error_R11_bjorklund(),
+ ok = test_error_R11_rath(),
+ ok = test_error_R12_empty_bin_rec(),
+ ok = test_bug_R12_cornish(),
+ ok = test_crash_R12_morris(),
+ ok = test_error_R13_almeida(),
+ ok = test_error_R13B01_fisher(),
+ ok = test_error_R13B01_sawatari(),
+ ok = test_error_R13B01_whongo(),
+ ok = test_error_R16B03_norell(),
+ ok = test_error_try_wings(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Fisher R10 compiler crash
+%%--------------------------------------------------------------------
+
+-record(r, {a, b, c}).
+
+test_crash_R10_hinde() ->
+ rec_R10_hinde(#r{}).
+
+rec_R10_hinde(As) ->
+ case As of
+ A when A#r.b == ""; A#r.b == undefined -> ok;
+ _ -> error
+ end.
+
+%%--------------------------------------------------------------------
+%% From: Peter-Henry Mander
+%% Date: 27 Jan, 2005
+%%
+%% I managed to isolate a non-critical BEAM compilation error
+%% (internal error in v3_codegen) when compiling the following code:
+%%--------------------------------------------------------------------
+
+test_error_R10_mander() ->
+ try just_compile_me_R10() catch _:_ -> ok end.
+
+just_compile_me_R10() ->
+ URI_Before =
+ {absoluteURI,
+ {scheme, fun() -> nil end},
+ {hier_part,
+ {net_path,
+ {srvr,
+ {userinfo, nil},
+ fun() -> nil end},
+ nil},
+ {port, nil}}},
+ {absoluteURI,
+ {scheme, _},
+ {hier_part,
+ {net_path,
+ {srvr,
+ {userinfo, nil},
+ _HostportBefore},
+ nil},
+ {port, nil}}} = URI_Before,
+ %% ... some funky code ommitted, not relevant ...
+ {absoluteURI,
+ {scheme, _},
+ {hier_part,
+ {net_path,
+ {srvr,
+ {userinfo, nil},
+ HostportAfter},
+ nil},
+ {port, nil}}} = URI_Before,
+ %% NOTE: I intended to write URI_After instead of URI_Before
+ %% but the accident revealed that when you add the line below,
+ %% it causes internal error in v3_codegen on compilation
+ {hostport, {hostname, "HostName"}, {port, nil}} = HostportAfter,
+ ok.
+
+%%--------------------------------------------------------------------
+%% From: Martin Bjorklund
+%% Date: Aug 16, 2006
+%%
+%% I found this compiler bug in R10B-10 and R11B-0.
+%%
+%% Function -just_compile_me/0-fun-2-/1 refers to undefined label 18
+%% ./bjorklund_R11compiler_bug.erl:none: internal error in beam_clean;
+%% crash reason: {{case_clause,{'EXIT',{undefined_label,18}}},
+%% [{compile,'-select_passes/2-anonymous-2-',2},
+%% {compile,'-internal_comp/4-anonymous-1-',2},
+%% {compile,fold_comp,3},
+%% {compile,internal_comp,4},
+%% {compile,internal,3}]}
+%%--------------------------------------------------------------------
+
+test_error_R11_bjorklund() ->
+ just_compile_me_R11_bjorklund().
+
+just_compile_me_R11_bjorklund() ->
+ G = fun() -> ok end,
+ try
+ G() %% fun() -> ok end
+ after
+ fun({A, B}) -> A + B end
+ end.
+
+%%--------------------------------------------------------------------
+%% From: Tim Rath
+%% Date: Sep 13, 2006
+%% Subject: Compiler bug not quite fixed
+%%
+%%
+%% I saw a compiler bug posted to the list by Martin Bjorklund that
+%% appeared to be exactly the problem I'm seeing, and then noticed
+%% that this was fixed in R11B-1. Unfortunately, though R11B-1 appears
+%% to fix the code submitted by Martin, it does not fix my case.
+%%
+%% Function -just_compile_me/0-fun-2-/1 refers to undefined label 13
+%% ./rath_R11compiler_bug.erl:none: internal error in beam_clean;
+%% crash reason: {{case_clause,{'EXIT',{undefined_label,13}}},
+%% [{compile,'-select_passes/2-anonymous-2-',2},
+%% {compile,'-internal_comp/4-anonymous-1-',2},
+%% {compile,fold_comp,3},
+%% {compile,internal_comp,4},
+%% {compile,internal,3}]}
+%%--------------------------------------------------------------------
+
+test_error_R11_rath() ->
+ just_compile_me_R11_rath().
+
+just_compile_me_R11_rath() ->
+ A = {6},
+ try
+ io:fwrite("")
+ after
+ fun () ->
+ fun () -> {_} = A end
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Program that crashed the R12B-0 compiler: internal error in v3_codegen
+%%----------------------------------------------------------------------
+
+-record(rec, {a = <<>> :: binary(), b = 42 :: integer()}).
+
+test_error_R12_empty_bin_rec() ->
+ 42 = test_empty_bin_rec(#rec{}),
+ ok.
+
+test_empty_bin_rec(R) ->
+ #rec{a = <<>>} = R,
+ R#rec.b.
+
+%%----------------------------------------------------------------------
+%% From: Simon Cornish
+%% Date: Jan 13, 2008
+%%
+%% The attached Erlang code demonstrates an R12B-0 bug with funs.
+%% Compile and evaluate the two die/1 calls for two different failure modes.
+%% It seems to me that the live register check for call_fun is off by one.
+%%----------------------------------------------------------------------
+
+-record(b, {c}).
+
+test_bug_R12_cornish() ->
+ {a2, a} = die(a),
+ {a2, {b, c}} = die({b, c}),
+ ok.
+
+die(A) ->
+ F = fun() -> {ok, A} end,
+ if A#b.c =:= [] -> one;
+ true ->
+ case F() of
+ {ok, A2} -> {a2, A2};
+ _ -> three
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% From: Hunter Morris
+%% Date: Nov 20, 2008
+%%
+%% The following code (tested with R12B-4 or R12B-5, vanilla compiler
+%% options) produces a compiler crash. It's nonsensical, and I realise
+%% that andalso can be quite evil, but it's a crash nonetheless.
+%%----------------------------------------------------------------------
+
+test_crash_R12_morris() ->
+ foo(42).
+
+foo(Bar) when (is_integer(Bar) andalso Bar =:= 0) ; Bar =:= 42 ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% From: Paulo Sergio Almeida
+%% Date: May 20, 2009
+%%
+%% The following code when compiled under R13B gives a compiler error.
+%% Function loop/1 refers to undefined label 6
+%% ./almeida_R13compiler_bug.erl:none: internal error in beam_peep;
+%% crash reason: {{case_clause,{'EXIT',{undefined_label,6}}},
+%% [{compile,'-select_passes/2-anonymous-2-',2},
+%% {compile,'-internal_comp/4-anonymous-1-',2},
+%%--------------------------------------------------------------------
+
+test_error_R13_almeida() ->
+ self() ! {backup, 42, false},
+ loop([]).
+
+loop(Tids) ->
+ receive
+ {backup, Tid, Dumping} ->
+ case Dumping of
+ false -> ok;
+ _ -> receive {logged, Tab, Tid} -> put({log, Tab}, Tid) end
+ end,
+ collect(Tid, Tids, [])
+ end.
+
+collect(_, _, _) -> ok.
+
+%%--------------------------------------------------------------------
+%% Fisher R13B01 compiler error
+%%--------------------------------------------------------------------
+
+test_error_R13B01_fisher() ->
+ perform_select({foo, "42"}).
+
+perform_select({Type, Keyval}) ->
+ try
+ if is_atom(Type) andalso length(Keyval) > 0 -> ok;
+ true -> ok
+ end
+ catch
+ _:_ -> fail
+ end.
+
+%%--------------------------------------------------------------------
+%% From: Mikage Sawatari
+%% Date: Jun 12, 2009
+%%
+%% I have the following compilation problem on Erlang R13B01.
+%% Compiler reports "Internal consistency check failed".
+%%--------------------------------------------------------------------
+
+test_error_R13B01_sawatari() ->
+ test_sawatari([1, null, 3], <<1, 2, 3>>).
+
+test_sawatari([], _Bin) -> ok;
+test_sawatari([H|T], Bin) ->
+ _ = case H of
+ null -> <<Bin/binary>>;
+ _ -> ok
+ end,
+ test_sawatari(T, Bin).
+
+%%--------------------------------------------------------------------
+
+test_error_R13B01_whongo() ->
+ S = "gazonk",
+ S = orgno_alphanum(S),
+ ok.
+
+orgno_alphanum(Cs) ->
+ [C || C <- Cs, ((C >= $0) andalso (C =< $9))
+ orelse ((C >= $a) andalso (C =< $z))
+ orelse ((C >= $A) andalso (C =< $Z))].
+
+%%--------------------------------------------------------------------
+%% I'm getting an Internal Consistency Check error when attempting to
+%% build Wings3D on Mac OS X 10.4.2 (Erlang OTP R10B-6):
+%%
+%% erlc -pa /ebin +warn_unused_vars -I/include -I ../e3d -W +debug_info
+%% '-Dwings_version="0.98.31"' -pa ../ebin -o../ebin wings_color.erl
+%% wings_color: function internal_rgb_to_hsv/3+97:
+%% Internal consistency check failed - please report this bug.
+%% Instruction: {test,is_eq_exact,{f,80},[{x,0},{atom,error}]}
+%% Error: {unsafe_instruction,{float_error_state,cleared}}:
+%%
+%% The problem is the interaction of the 'try' construct with the
+%% handling of FP exceptions.
+%%--------------------------------------------------------------------
+
+test_error_try_wings() ->
+ %% a call with a possible FP exception
+ {199.99999999999997, 0.045454545454545456, 44} = rgb_to_hsv(42, 43, 44),
+ ok.
+
+rgb_to_hsv(R, G, B) ->
+ Max = lists:max([R, G, B]),
+ Min = lists:min([R, G, B]),
+ V = Max,
+ {Hue, Sat} = try
+ {if Min == B -> (G-Min)/(R+G-2.0*Min);
+ Min == R -> (1.0+(B-Min)/(B+G-2.0*Min));
+ Min == G -> (2.0+(R-Min)/(B+R-2.0*Min))
+ end * 120, (Max-Min)/Max}
+ catch
+ error:badarith -> {undefined, 0.0}
+ end,
+ {Hue, Sat, V}.
+
+%%--------------------------------------------------------------------
+%% From: Ulf Norell
+%% Date: Feb 28, 2014
+%%
+%% This caused an internal error in v3_codegen
+%%--------------------------------------------------------------------
+
+test_error_R16B03_norell() ->
+ test_error_R16B03_norell(#r{}, gazonk).
+
+test_error_R16B03_norell(Rec, Tag) ->
+ is_record(Rec, Tag, 3) orelse ok.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl
new file mode 100644
index 0000000000..e71045bfe2
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl
@@ -0,0 +1,153 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples that exhibited crashes in the HiPE compiler.
+%%%-------------------------------------------------------------------
+-module(basic_issues_hipe).
+
+-export([test/0]).
+
+%% functions that need to be exported so that they are retained.
+-export([auth/4]).
+
+test() ->
+ ok = test_dominance_trees(),
+ ok = test_merged_const(),
+ ok = test_var_pair(),
+ ok = test_bif_fails(),
+ ok = test_find_catches(),
+ ok = test_heap_allocate_trim(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% This is taken from a file sent to us by Martin Bjorklund @ Nortel
+%% on 14th November 2004. The problem was in the SSA unconvert pass.
+%%
+%% No tests here; we simply check that the HiPE compiler does not go
+%% into an infinite loop when compiling strange functions like this.
+%%--------------------------------------------------------------------
+
+auth(_, A, B, C) ->
+ auth(A, B, C, []).
+
+%%--------------------------------------------------------------------
+%% Exposed a crash in the generation of dominance trees used in SSA.
+%%--------------------------------------------------------------------
+
+-record(state, {f}).
+
+test_dominance_trees() ->
+ {ok, true} = doit(true, #state{f = true}),
+ ok.
+
+doit(Foo, S) ->
+ Fee = case Foo of
+ Bar when Bar == S#state.f; Bar == [] -> true;
+ _ -> false
+ end,
+ {ok, Fee}.
+
+%%--------------------------------------------------------------------
+%% Checks that the merging of constants in the constant table uses the
+%% appropriate comparison function for this.
+%%--------------------------------------------------------------------
+
+test_merged_const() ->
+ Const1 = {'', 1.0000},
+ Const2 = {'', 1},
+ match(Const1, Const2).
+
+match(A, A) ->
+ error;
+match(_A, _B) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Checks that the HiPE compiler does not get confused by constant
+%% data structures similar to the internal compiler data structures.
+%%--------------------------------------------------------------------
+
+test_var_pair() ->
+ ok = var_pair([gazonk]).
+
+var_pair([_|_]) ->
+ var_pair({var, some_atom});
+var_pair(_) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% This module was causing the HiPE compiler to crash in January 2007.
+%% The culprit was an "optimization" of the BEAM compiler: postponing
+%% the save of x variables when BIFs cannot fail. This was fixed on
+%% February 1st, by making the HiPE compiler use the same functions
+%% as the BEAM compiler for deciding whether a BIF fails.
+%%--------------------------------------------------------------------
+
+test_bif_fails() ->
+ [42] = bif_fails_in_catch([42]),
+ true = bif_fails_in_try([42]),
+ ok.
+
+bif_fails_in_catch(X) ->
+ case catch get(gazonk) of
+ _ -> X
+ end.
+
+bif_fails_in_try(X) ->
+ try
+ true = X =/= []
+ catch
+ _ -> nil(X)
+ end.
+
+nil(_) -> [].
+
+%%--------------------------------------------------------------------
+%% Test that resulted in a native code compiler crash in the code of
+%% hipe_icode_exceptions:find_catches/1 when compiling find_catches/2.
+%%--------------------------------------------------------------------
+
+test_find_catches() ->
+ 42 = find_catches(a, false),
+ ok.
+
+find_catches(X, Y) ->
+ case X of
+ a when Y =:= true ->
+ catch id(X),
+ X;
+ b when Y =:= true ->
+ catch id(X),
+ X;
+ a ->
+ catch id(X),
+ 42;
+ b ->
+ catch id(X),
+ 42
+ end.
+
+id(X) -> X.
+
+%%--------------------------------------------------------------------
+%% Date: Dec 28, 2007
+%%
+%% This is a test adapted from the file sent to the Erlang mailing
+%% list by Eranga Udesh. The file did not compile because of problems
+%% with the heap_allocate instruction and stack trimming.
+%%--------------------------------------------------------------------
+
+test_heap_allocate_trim() ->
+ {abandon, 42} = get_next_retry(a, 42),
+ ok.
+
+get_next_retry(Error, Count) ->
+ case catch pair(retry_scheme, {Error, Count}) of
+ _ ->
+ case pair(Error, Count) of
+ _ -> {abandon, Count}
+ end
+ end.
+
+pair(A, B) -> {A, B}.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_lists.erl b/lib/hipe/test/basic_SUITE_data/basic_lists.erl
new file mode 100644
index 0000000000..264a7f86f6
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_lists.erl
@@ -0,0 +1,61 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that manipulate and pattern match against lists
+%%% (perhaps by calling functions from the 'lists' module).
+%%%-------------------------------------------------------------------
+-module(basic_lists).
+
+-export([test/0]).
+
+test() ->
+ ok = test_length(),
+ ok = test_lists_key(),
+ ok = test_lists_and_strings(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_length() ->
+ Len = 42,
+ Lst = mklist(Len, []),
+ Len = iterate(100, Lst),
+ ok.
+
+mklist(0, L) -> L;
+mklist(X, L) -> mklist(X-1, [X|L]).
+
+iterate(0, L) -> len(L, 0);
+iterate(X, L) -> len(L, 0), iterate(X-1, L).
+
+len([_|X], L) -> len(X, L+1);
+len([], L) -> L.
+
+%%--------------------------------------------------------------------
+
+test_lists_key() ->
+ First = {x, 42.0},
+ Second = {y, -77},
+ Third = {z, [a, b, c], {5.0}},
+ List = [First, Second, Third],
+ {value, First} = key_search_find(42, 2, List),
+ ok.
+
+key_search_find(Key, Pos, List) ->
+ case lists:keyfind(Key, Pos, List) of
+ false ->
+ false = lists:keysearch(Key, Pos, List);
+ Tuple when is_tuple(Tuple) ->
+ {value, Tuple} = lists:keysearch(Key, Pos, List)
+ end.
+
+%%--------------------------------------------------------------------
+
+test_lists_and_strings() ->
+ LL = ["H'A", " H'B", " H'C"],
+ LL2 = lists:map(fun string:strip/1, LL),
+ HexFormat = fun(X, Acc) -> {string:substr(X, 3), Acc} end,
+ {LL3,_Ret} = lists:mapfoldl(HexFormat, 0, LL2),
+ ["A", "B", "C"] = lists:sublist(LL3, 42),
+ ok.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_module_info.erl b/lib/hipe/test/basic_SUITE_data/basic_module_info.erl
new file mode 100644
index 0000000000..cab48b10ba
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_module_info.erl
@@ -0,0 +1,32 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%% Date: Oct 25, 2003
+%%%
+%%% Tests whether calling module_info from the same module works.
+%%% This seems trivial, but the problem is that the module_info/[0,1]
+%%% functions that the BEAM file contains used to be dummy functions
+%%% containing crap. So, these functions could not be used for
+%%% compilation to native code and the functions that the BEAM loader
+%%% generates should have been used instead. This was a HiPE bug
+%%% reported by Dan Wallin.
+%%%-------------------------------------------------------------------
+-module(basic_module_info).
+
+-export([test/0]).
+
+test() ->
+ L = test_local_mi0_call(),
+ E = test_remote_mi1_call(),
+ {3, 3} = {L, E},
+ ok.
+
+test_local_mi0_call() ->
+ ModInfo = module_info(),
+ %% io:format("ok, ModInfo=~w\n", [ModInfo]),
+ {exports, FunList} = lists:keyfind(exports, 1, ModInfo),
+ length(FunList).
+
+test_remote_mi1_call() ->
+ FunList = ?MODULE:module_info(exports),
+ length(FunList).
diff --git a/lib/hipe/test/basic_SUITE_data/basic_pattern_match.erl b/lib/hipe/test/basic_SUITE_data/basic_pattern_match.erl
new file mode 100644
index 0000000000..93240354a7
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_pattern_match.erl
@@ -0,0 +1,46 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples that test pattern matching against terms of
+%%% various types.
+%%%-------------------------------------------------------------------
+-module(basic_pattern_match).
+
+-export([test/0]).
+
+test() ->
+ ok = test_hello_world(),
+ ok = test_list_plus_plus_match(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Trivial test to test pattern matching compilation with atoms, the
+%% correct handling of all sorts of alphanumeric types in Erlang, and
+%% conversions between them.
+
+test_hello_world() ->
+ String = gimme(string),
+ String = atom_to_list(gimme(atom)),
+ String = binary_to_list(gimme(binary)),
+ true = (list_to_atom(String) =:= gimme(atom)),
+ true = (list_to_binary(String) =:= gimme(binary)),
+ ok.
+
+gimme(string) ->
+ "hello world";
+gimme(atom) ->
+ 'hello world';
+gimme(binary) ->
+ <<"hello world">>.
+
+%%--------------------------------------------------------------------
+%% Makes sure that pattern matching expressions involving ++ work OK.
+%% The third expression caused a problem in the Erlang shell of R11B-5.
+%% It worked OK in both interpreted and compiled code.
+
+test_list_plus_plus_match() ->
+ ok = (fun("X" ++ _) -> ok end)("X"),
+ ok = (fun([$X | _]) -> ok end)("X"),
+ ok = (fun([$X] ++ _) -> ok end)("X"),
+ ok.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_random.erl b/lib/hipe/test/basic_SUITE_data/basic_random.erl
new file mode 100644
index 0000000000..783947bd31
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_random.erl
@@ -0,0 +1,238 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% A test for list handling created using the 'random' module.
+%%%-------------------------------------------------------------------
+-module(basic_random).
+
+-export([test/0]).
+
+%% It can be used as a benchmark by playing with the following defines
+-define(N, 1000).
+-define(Iter, 500).
+
+test() ->
+ ok = random(?N).
+
+random(N) ->
+ random(N, ?Iter).
+
+random(N, Iter) ->
+ random:seed(1, 2, 3),
+ t(ranlist(N, [], N*100), Iter).
+
+ranlist(0, L, _N) -> L;
+ranlist(N, L, N0) -> ranlist(N-1, [random:uniform(N0)+300 | L], N0).
+
+t(_, 0) -> ok;
+t(L, Iter) ->
+ %% io:format("Sort starting~n"),
+ sort(L),
+ t(L, Iter-1).
+
+sort([X, Y | L]) when X =< Y ->
+ split_1(X, Y, L, [], []);
+sort([X, Y | L]) ->
+ split_2(X, Y, L, [], []);
+sort(L) ->
+ L.
+
+%% Ascending.
+split_1(X, Y, [Z | L], R, Rs) when Z >= Y ->
+ split_1(Y, Z, L, [X | R], Rs);
+split_1(X, Y, [Z | L], R, Rs) when Z >= X ->
+ split_1(Z, Y, L, [X | R], Rs);
+split_1(X, Y, [Z | L], [], Rs) ->
+ split_1(X, Y, L, [Z], Rs);
+split_1(X, Y, [Z | L], R, Rs) ->
+ split_1_1(X, Y, L, R, Rs, Z);
+split_1(X, Y, [], R, Rs) ->
+ rmergel([[Y, X | R] | Rs], []).
+
+%% One out-of-order element, S.
+split_1_1(X, Y, [Z | L], R, Rs, S) when Z >= Y ->
+ split_1_1(Y, Z, L, [X | R], Rs, S);
+split_1_1(X, Y, [Z | L], R, Rs, S) when Z >= X ->
+ split_1_1(Z, Y, L, [X | R], Rs, S);
+split_1_1(X, Y, [Z | L], R, Rs, S) when S =< Z ->
+ split_1(S, Z, L, [], [[Y, X | R] | Rs]);
+split_1_1(X, Y, [Z | L], R, Rs, S) ->
+ split_1(Z, S, L, [], [[Y, X | R] | Rs]);
+split_1_1(X, Y, [], R, Rs, S) ->
+ rmergel([[S], [Y, X | R] | Rs], []).
+
+%% Descending.
+split_2(X, Y, [Z | L], R, Rs) when Z =< Y ->
+ split_2(Y, Z, L, [X | R], Rs);
+split_2(X, Y, [Z | L], R, Rs) when Z =< X ->
+ split_2(Z, Y, L, [X | R], Rs);
+split_2(X, Y, [Z | L], [], Rs) ->
+ split_2(X, Y, L, [Z], Rs);
+split_2(X, Y, [Z | L], R, Rs) ->
+ split_2_1(X, Y, L, R, Rs, Z);
+split_2(X, Y, [], R, Rs) ->
+ mergel([[Y, X | R] | Rs], []).
+
+split_2_1(X, Y, [Z | L], R, Rs, S) when Z =< Y ->
+ split_2_1(Y, Z, L, [X | R], Rs, S);
+split_2_1(X, Y, [Z | L], R, Rs, S) when Z =< X ->
+ split_2_1(Z, Y, L, [X | R], Rs, S);
+split_2_1(X, Y, [Z | L], R, Rs, S) when S > Z ->
+ split_2(S, Z, L, [], [[Y, X | R] | Rs]);
+split_2_1(X, Y, [Z | L], R, Rs, S) ->
+ split_2(Z, S, L, [], [[Y, X | R] | Rs]);
+split_2_1(X, Y, [], R, Rs, S) ->
+ mergel([[S], [Y, X | R] | Rs], []).
+
+mergel([[] | L], Acc) ->
+ mergel(L, Acc);
+mergel([A, [H2 | T2], [H3 | T3] | L], Acc) ->
+ mergel(L, [merge3_1(A, [], H2, T2, H3, T3) | Acc]);
+mergel([A, [H | T]], Acc) ->
+ rmergel([merge2_1(A, H, T, []) | Acc], []);
+mergel([L], []) ->
+ L;
+mergel([L], Acc) ->
+ rmergel([lists:reverse(L, []) | Acc], []);
+mergel([], []) ->
+ [];
+mergel([], Acc) ->
+ rmergel(Acc, []);
+mergel([A, [] | L], Acc) ->
+ mergel([A | L], Acc);
+mergel([A, B, [] | L], Acc) ->
+ mergel([A, B | L], Acc).
+
+rmergel([A, [H2 | T2], [H3 | T3] | L], Acc) ->
+ rmergel(L, [rmerge3_1(A, [], H2, T2, H3, T3) | Acc]);
+rmergel([A, [H | T]], Acc) ->
+ mergel([rmerge2_1(A, H, T, []) | Acc], []);
+rmergel([L], Acc) ->
+ mergel([lists:reverse(L, []) | Acc], []);
+rmergel([], Acc) ->
+ mergel(Acc, []).
+
+%% Take L1 apart.
+merge3_1([H1 | T1], M, H2, T2, H3, T3) when H1 =< H2 ->
+ merge3_12(T1, H1, H2, T2, H3, T3, M);
+merge3_1([H1 | T1], M, H2, T2, H3, T3) ->
+ merge3_21(T1, H1, H2, T2, H3, T3, M);
+merge3_1(_nil, M, H2, T2, H3, T3) when H2 =< H3 ->
+ merge2_1(T2, H3, T3, [H2 | M]);
+merge3_1(_nil, M, H2, T2, H3, T3) ->
+ merge2_1(T3, H2, T2, [H3 | M]).
+
+%% Take L2 apart.
+merge3_2(T1, H1, M, [H2 | T2], H3, T3) when H1 =< H2 ->
+ merge3_12(T1, H1, H2, T2, H3, T3, M);
+merge3_2(T1, H1, M, [H2 | T2], H3, T3) ->
+ merge3_21(T1, H1, H2, T2, H3, T3, M);
+merge3_2(T1, H1, M, _nil, H3, T3) when H1 =< H3 ->
+ merge2_1(T1, H3, T3, [H1 | M]);
+merge3_2(T1, H1, M, _nil, H3, T3) ->
+ merge2_1(T3, H1, T1, [H3 | M]).
+
+%% H1 <= H2. Inlined.
+merge3_12(T1, H1, H2, T2, H3, T3, M) when H3 < H1 ->
+ merge3_12_3(T1, H1, H2, T2, [H3 | M], T3);
+merge3_12(T1, H1, H2, T2, H3, T3, M) ->
+ merge3_1(T1, [H1 | M], H2, T2, H3, T3).
+
+%% H1 <= H2, take L3 apart.
+merge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) when H3 < H1 ->
+ merge3_12_3(T1, H1, H2, T2, [H3 | M], T3);
+merge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) ->
+ merge3_1(T1, [H1 | M], H2, T2, H3, T3);
+merge3_12_3(T1, H1, H2, T2, M, _nil) ->
+ merge2_1(T1, H2, T2, [H1 | M]).
+
+%% H1 > H2. Inlined.
+merge3_21(T1, H1, H2, T2, H3, T3, M) when H3 < H2 ->
+ merge3_21_3(T1, H1, H2, T2, [H3 | M], T3);
+merge3_21(T1, H1, H2, T2, H3, T3, M) ->
+ merge3_2(T1, H1, [H2 | M], T2, H3, T3).
+
+%% H1 > H2, take L3 apart.
+merge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) when H3 < H2 ->
+ merge3_21_3(T1, H1, H2, T2, [H3 | M], T3);
+merge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) ->
+ merge3_2(T1, H1, [H2 | M], T2, H3, T3);
+merge3_21_3(T1, H1, H2, T2, M, _nil) ->
+ merge2_1(T2, H1, T1, [H2 | M]).
+
+%% Take L1 apart.
+rmerge3_1([H1 | T1], M, H2, T2, H3, T3) when H1 > H2 ->
+ rmerge3_12(T1, H1, H2, T2, H3, T3, M);
+rmerge3_1([H1 | T1], M, H2, T2, H3, T3) ->
+ rmerge3_21(T1, H1, H2, T2, H3, T3, M);
+rmerge3_1(_nil, M, H2, T2, H3, T3) when H2 > H3 ->
+ rmerge2_1(T2, H3, T3, [H2 | M]);
+rmerge3_1(_nil, M, H2, T2, H3, T3) ->
+ rmerge2_1(T3, H2, T2, [H3 | M]).
+
+%% Take L2 apart.
+rmerge3_2(T1, H1, M, [H2 | T2], H3, T3) when H1 > H2 ->
+ rmerge3_12(T1, H1, H2, T2, H3, T3, M);
+rmerge3_2(T1, H1, M, [H2 | T2], H3, T3) ->
+ rmerge3_21(T1, H1, H2, T2, H3, T3, M);
+rmerge3_2(T1, H1, M, _nil, H3, T3) when H1 > H3 ->
+ rmerge2_1(T1, H3, T3, [H1 | M]);
+rmerge3_2(T1, H1, M, _nil, H3, T3) ->
+ rmerge2_1(T3, H1, T1, [H3 | M]).
+
+%% H1 > H2. Inlined.
+rmerge3_12(T1, H1, H2, T2, H3, T3, M) when H3 >= H1 ->
+ rmerge3_12_3(T1, H1, H2, T2, [H3 | M], T3);
+rmerge3_12(T1, H1, H2, T2, H3, T3, M) ->
+ rmerge3_1(T1, [H1 | M], H2, T2, H3, T3).
+
+%% H1 > H2, take L3 apart.
+rmerge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) when H3 >= H1 ->
+ rmerge3_12_3(T1, H1, H2, T2, [H3 | M], T3);
+rmerge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) ->
+ rmerge3_1(T1, [H1 | M], H2, T2, H3, T3);
+rmerge3_12_3(T1, H1, H2, T2, M, _nil) ->
+ rmerge2_1(T1, H2, T2, [H1 | M]).
+
+%% H1 =< H2. Inlined.
+rmerge3_21(T1, H1, H2, T2, H3, T3, M) when H3 >= H2 ->
+ rmerge3_21_3(T1, H1, H2, T2, [H3 | M], T3);
+rmerge3_21(T1, H1, H2, T2, H3, T3, M) ->
+ rmerge3_2(T1, H1, [H2 | M], T2, H3, T3).
+
+%% H1 =< H2, take L3 apart.
+rmerge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) when H3 >= H2 ->
+ rmerge3_21_3(T1, H1, H2, T2, [H3 | M], T3);
+rmerge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) ->
+ rmerge3_2(T1, H1, [H2 | M], T2, H3, T3);
+rmerge3_21_3(T1, H1, H2, T2, M, _nil) ->
+ rmerge2_1(T2, H1, T1, [H2 | M]).
+
+merge2_1([H1 | T1], H2, T2, M) when H2 < H1 ->
+ merge2_2(T1, H1, T2, [H2 | M]);
+merge2_1([H1 | T1], H2, T2, M) ->
+ merge2_1(T1, H2, T2, [H1 | M]);
+merge2_1(_nil, H2, T2, M) ->
+ lists:reverse(T2, [H2 | M]).
+
+merge2_2(T1, H1, [H2 | T2], M) when H1 < H2 ->
+ merge2_1(T1, H2, T2, [H1 | M]);
+merge2_2(T1, H1, [H2 | T2], M) ->
+ merge2_2(T1, H1, T2, [H2 | M]);
+merge2_2(T1, H1, _nil, M) ->
+ lists:reverse(T1, [H1 | M]).
+
+rmerge2_1([H1 | T1], H2, T2, M) when H2 >= H1 ->
+ rmerge2_2(T1, H1, T2, [H2 | M]);
+rmerge2_1([H1 | T1], H2, T2, M) ->
+ rmerge2_1(T1, H2, T2, [H1 | M]);
+rmerge2_1(_nil, H2, T2, M) ->
+ lists:reverse(T2, [H2 | M]).
+
+rmerge2_2(T1, H1, [H2 | T2], M) when H1 >= H2 ->
+ rmerge2_1(T1, H2, T2, [H1 | M]);
+rmerge2_2(T1, H1, [H2 | T2], M) ->
+ rmerge2_2(T1, H1, T2, [H2 | M]);
+rmerge2_2(T1, H1, _nil, M) ->
+ lists:reverse(T1, [H1 | M]).
diff --git a/lib/hipe/test/basic_SUITE_data/basic_receive.erl b/lib/hipe/test/basic_SUITE_data/basic_receive.erl
new file mode 100644
index 0000000000..5f865d7b7a
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_receive.erl
@@ -0,0 +1,56 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains code examples that test correct handling of receives.
+%%%-------------------------------------------------------------------
+-module(basic_receive).
+
+-export([test/0]).
+
+test() ->
+ ok = test_wait_timeout(),
+ ok = test_double_timeout(),
+ ok = test_reschedule(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_wait_timeout() ->
+ receive after 42 -> ok end.
+
+%%--------------------------------------------------------------------
+
+test_double_timeout() ->
+ self() ! foo,
+ self() ! another_foo,
+ receive
+ non_existent -> weird
+ after 0 -> timeout
+ end,
+ receive
+ foo -> ok
+ after 1000 -> timeout
+ end.
+
+%%--------------------------------------------------------------------
+%% Check that RESCHEDULE returns from BIFs work.
+
+test_reschedule() ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ First = self(),
+ Second = spawn(fun() -> doit(First) end),
+ receive
+ Second -> ok
+ end,
+ receive
+ after 42 -> ok
+ end,
+ erts_debug:set_internal_state(hipe_test_reschedule_resume, Second),
+ ok.
+
+doit(First) ->
+ First ! self(),
+ erts_debug:set_internal_state(hipe_test_reschedule_suspend, 1).
+
+%%--------------------------------------------------------------------
diff --git a/lib/hipe/test/basic_SUITE_data/basic_records.erl b/lib/hipe/test/basic_SUITE_data/basic_records.erl
new file mode 100644
index 0000000000..cbb451196c
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_records.erl
@@ -0,0 +1,28 @@
+%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that manipulate and pattern match against records.
+%%%-------------------------------------------------------------------
+-module(basic_records).
+
+-export([test/0]).
+
+test() ->
+ ok = test_rec1(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+-record(r, {ra}).
+-record(s, {sa, sb, sc, sd}).
+
+test_rec1() ->
+ R = #r{},
+ S = #s{},
+ S1 = S#s{sc=R, sd=1},
+ R1 = S1#s.sc,
+ undefined = R1#r.ra,
+ ok.
+
+%%--------------------------------------------------------------------
diff --git a/lib/hipe/test/basic_SUITE_data/basic_strength_reduce.erl b/lib/hipe/test/basic_SUITE_data/basic_strength_reduce.erl
new file mode 100644
index 0000000000..0f94320a33
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_strength_reduce.erl
@@ -0,0 +1,65 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Tests the strength reduction component of the HiPE compiler.
+%%%-------------------------------------------------------------------
+-module(basic_strength_reduce).
+
+-export([test/0]).
+%% These functions are exported so as to not remove them by inlining
+-export([crash_0/1, crash_1/1, crash_2/1, crash_3/1, bug_div_2N/1]).
+
+test() ->
+ ok = test_strength_reduce1(),
+ ok.
+
+%%--------------------------------------------------------------------
+
+test_strength_reduce1() ->
+ ok = crash_0(0),
+ ok = crash_1(42),
+ ok = crash_2(42),
+ ok = crash_3(42),
+ 5 = 42 bsr 3 = bug_div_2N(42),
+ -6 = -42 bsr 3 = bug_div_2N(-42) - 1,
+ ok.
+
+%% This is a crash report by Peter Wang (10 July 2007) triggering an
+%% R11B-5 crash: strength reduction could not handle calls with no
+%% destination
+crash_0(A) ->
+ case A of
+ 0 ->
+ A div 8,
+ ok
+ end.
+
+%% The above was simplified to the following which showed another
+%% crash, this time on RTL
+crash_1(A) when is_integer(A), A >= 0 ->
+ A div 8,
+ ok.
+
+%% A similar crash like the first one, but in a different place in the
+%% code, was triggered by the following code
+crash_2(A) when is_integer(A), A >= 0 ->
+ A div 1,
+ ok.
+
+%% A crash similar to the first one happened in the following code
+crash_3(A) ->
+ case A of
+ 42 ->
+ A * 0,
+ ok
+ end.
+
+%% Strength reduction for div/2 and rem/2 with a power of 2
+%% should be performed only for non-negative integers
+bug_div_2N(X) when is_integer(X), X >= 0 ->
+ X div 8;
+bug_div_2N(X) when is_integer(X), X < 0 ->
+ X div 8.
+
+%%--------------------------------------------------------------------
diff --git a/lib/hipe/test/basic_SUITE_data/basic_switches.erl b/lib/hipe/test/basic_SUITE_data/basic_switches.erl
new file mode 100644
index 0000000000..0a7ae5b8b7
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_switches.erl
@@ -0,0 +1,52 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests for pattern matching switches.
+%%%-------------------------------------------------------------------
+-module(basic_switches).
+
+-export([test/0]).
+
+test() ->
+ ok = test_switch_mix(),
+ ok.
+
+%%---------------------------------------------------------------------
+
+-define(BIG1, 21323233222132323322).
+-define(BIG2, 4242424242424242424242424242424242).
+
+test_switch_mix() ->
+ small1 = t(42),
+ small2 = t(17),
+ big1 = t(?BIG1),
+ big2 = t(?BIG2),
+ atom = t(foo),
+ pid = t(self()),
+ float = t(4.2),
+ ok.
+
+t(V) ->
+ S = self(),
+ case V of
+ 42 -> small1;
+ 17 -> small2;
+ ?BIG1 -> big1;
+ ?BIG2 -> big2;
+ 1 -> no;
+ 2 -> no;
+ 3 -> no;
+ 4 -> no;
+ 5 -> no;
+ 6 -> no;
+ 7 -> no;
+ 8 -> no;
+ foo -> atom;
+ 9 -> no;
+ 4.2 -> float;
+ S -> pid;
+ _ -> no
+ end.
+
+%%---------------------------------------------------------------------
diff --git a/lib/hipe/test/basic_SUITE_data/basic_tail_rec.erl b/lib/hipe/test/basic_SUITE_data/basic_tail_rec.erl
new file mode 100644
index 0000000000..0124f13df6
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_tail_rec.erl
@@ -0,0 +1,39 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that check that tail recursion optimization occurs.
+%%%-------------------------------------------------------------------
+-module(basic_tail_rec).
+
+-export([test/0]).
+-export([app0/2]). %% used in an apply/3 call
+
+test() ->
+ ok = test_app_tail(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Written by Mikael Pettersson: check that apply is tail recursive.
+
+%% Increased the following quantity from 20 to 30 so that the test
+%% remains valid even with the naive register allocator. - Kostis
+-define(SIZE_INCREASE, 30).
+
+test_app_tail() ->
+ Inc = start(400),
+ %% io:format("Inc ~w\n", [Inc]),
+ case Inc > ?SIZE_INCREASE of
+ true ->
+ {error, "apply/3 is not tail recursive in native code"};
+ false ->
+ ok
+ end.
+
+start(N) ->
+ app0(N, hipe_bifs:nstack_used_size()).
+
+app0(0, Size0) ->
+ hipe_bifs:nstack_used_size() - Size0;
+app0(N, Size) ->
+ apply(?MODULE, app0, [N-1, Size]).
diff --git a/lib/hipe/test/basic_SUITE_data/basic_tuples.erl b/lib/hipe/test/basic_SUITE_data/basic_tuples.erl
new file mode 100644
index 0000000000..94c187e364
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_tuples.erl
@@ -0,0 +1,177 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Contains tests that manipulate and pattern match against tuples.
+%%%-------------------------------------------------------------------
+-module(basic_tuples).
+
+-export([test/0]).
+
+test() ->
+ Num = 4711,
+ ok = test_match({}, {1}, {1,2}, {1,2,3}, {1,2,3,4}, {1,2,3,4,5},
+ {1,2,3,4,5,6}, {1,2,3,4,5,6,7}, {1,2,3,4,5,6,7,8}),
+ ok = test_size({}, {a}, {{a},{b}}, {a,{b},c}),
+ ok = test_element({}, {a}, {a,b}, Num),
+ ok = test_setelement({}, {1}, {1,2}, 3, [1,2]),
+ ok = test_tuple_to_list({}, {a}, {a,b}, {a,b,c}, {a,b,c,d}, Num),
+ ok = test_list_to_tuple([], [a], [a,b], [a,b,c], [a,b,c,d], Num),
+ ok = test_tuple_with_case(),
+ ok = test_tuple_in_guard({a, b}, {a, b, c}),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests matching of tuples
+
+test_match(T0, T1, T2, T3, T4, T5, T6, T7, T8) ->
+ {} = T0,
+ {1} = T1,
+ {1, 2} = T2,
+ {1, 2, 3} = T3,
+ {1, 2, 3, 4} = T4,
+ {1, 2, 3, 4, 5} = T5,
+ {1, 2, 3, 4, 5, 6} = T6,
+ T6 = {1, 2, 3, 4, 5, 6},
+ T7 = {1, 2, 3, 4, 5, 6, 7},
+ {1, 2, 3, 4, 5, 6, 7, 8} = T8,
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests the size/1 and tuple_size/1 BIFs.
+
+test_size(T0, T1, T2, T3) ->
+ [0, 1, 2, 3] = [size(T) || T <- [T0, T1, T2, T3]],
+ [0, 1, 2, 3] = [tuple_size(T) || T <- [T0, T1, T2, T3]],
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests element/2.
+
+test_element(T0, T1, T2, N) ->
+ a = element(1, T1),
+ a = element(1, T2),
+ %% indirect calls to element/2
+ List = lists:seq(1, N),
+ Tuple = list_to_tuple(List),
+ ok = get_elements(List, Tuple, 1),
+ %% some cases that throw exceptions
+ {'EXIT', _} = (catch my_element(0, T2)),
+ {'EXIT', _} = (catch my_element(3, T2)),
+ {'EXIT', _} = (catch my_element(1, T0)),
+ {'EXIT', _} = (catch my_element(1, List)),
+ {'EXIT', _} = (catch my_element(1, N)),
+ {'EXIT', _} = (catch my_element(1.5, T2)),
+ ok.
+
+my_element(Pos, Term) ->
+ element(Pos, Term).
+
+get_elements([Element|Rest], Tuple, Pos) ->
+ Element = element(Pos, Tuple),
+ get_elements(Rest, Tuple, Pos + 1);
+get_elements([], _Tuple, _Pos) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Tests set_element/3.
+
+test_setelement(T0, T1, Pair, Three, L) ->
+ {x} = setelement(1, T1, x),
+ {x, 2} = setelement(1, Pair, x),
+ {1, x} = setelement(2, Pair, x),
+ %% indirect calls to setelement/3
+ Tuple = list_to_tuple(lists:duplicate(2048, x)),
+ NewTuple = set_all_elements(Tuple, 1),
+ NewTuple = list_to_tuple(lists:seq(1+7, 2048+7)),
+ %% the following cases were rewritten to use the Three
+ %% variable in this weird way so as to silence the compiler
+ {'EXIT', _} = (catch setelement(Three - Three, Pair, x)),
+ {'EXIT', _} = (catch setelement(Three, Pair, x)),
+ {'EXIT', _} = (catch setelement(Three div Three, T0, x)),
+ {'EXIT', _} = (catch setelement(Three div Three, L, x)),
+ {'EXIT', _} = (catch setelement(Three / 2, Pair, x)),
+ ok.
+
+set_all_elements(Tuple, Pos) when Pos =< tuple_size(Tuple) ->
+ set_all_elements(setelement(Pos, Tuple, Pos+7), Pos+1);
+set_all_elements(Tuple, Pos) when Pos > tuple_size(Tuple) ->
+ Tuple.
+
+%%--------------------------------------------------------------------
+%% Tests tuple_to_list/1.
+
+test_tuple_to_list(T0, T1, T2, T3, T4, Size) ->
+ [] = tuple_to_list(T0),
+ [a] = tuple_to_list(T1),
+ [a, b] = tuple_to_list(T2),
+ [a, b, c] = tuple_to_list(T3),
+ [a, b, c, d] = tuple_to_list(T4),
+ [a, b, c, d] = tuple_to_list(T4),
+ %% test a big tuple
+ List = lists:seq(1, Size),
+ Tuple = list_to_tuple(List),
+ Size = tuple_size(Tuple),
+ List = tuple_to_list(Tuple),
+ %% some cases that should result in errors
+ {'EXIT', _} = (catch my_tuple_to_list(element(2, T3))),
+ {'EXIT', _} = (catch my_tuple_to_list(Size)),
+ ok.
+
+my_tuple_to_list(X) ->
+ tuple_to_list(X).
+
+%%--------------------------------------------------------------------
+%% Tests list_to_tuple/1.
+
+test_list_to_tuple(L0, L1, L2, L3, L4, Size) ->
+ {} = list_to_tuple(L0),
+ {a} = list_to_tuple(L1),
+ {a, b} = list_to_tuple(L2),
+ {a, b, c} = list_to_tuple(L3),
+ {a, b, c, d} = list_to_tuple(L4),
+ {a, b, c, d, e} = list_to_tuple(L4++[e]),
+ %% test list_to_tuple with a big list
+ Tuple = list_to_tuple(lists:seq(1, Size)),
+ Size = tuple_size(Tuple),
+ %% some cases that should result in errors
+ {'EXIT', _} = (catch my_list_to_tuple({a,b})),
+ {'EXIT', _} = (catch my_list_to_tuple([hd(L1)|hd(L2)])),
+ ok.
+
+my_list_to_tuple(X) ->
+ list_to_tuple(X).
+
+%%--------------------------------------------------------------------
+%% Tests that a case nested inside a tuple is ok.
+%% (This was known to crash earlier versions of BEAM.)
+
+test_tuple_with_case() ->
+ {reply, true} = tuple_with_case(),
+ ok.
+
+tuple_with_case() ->
+ %% The following comments apply to the BEAM compiler.
+ void(), % Reset var count.
+ {reply, % Compiler will choose {x,1} for tuple.
+ case void() of % Call will reset var count.
+ {'EXIT', Reason} -> % Case will return in {x,1} (first free),
+ {error, Reason}; % but the tuple will be build in {x,1},
+ _ -> % so case value is lost and a circular
+ true % data element is built.
+ end}.
+
+void() -> ok.
+
+%%--------------------------------------------------------------------
+%% Test to build a tuple in a guard.
+
+test_tuple_in_guard(T2, T3) ->
+ %% T2 = {a, b}; T3 = {a, b, c}
+ ok = if T2 == {element(1, T3), element(2, T3)} -> ok;
+ true -> other
+ end,
+ ok = if T3 == {element(1, T3), element(2, T3), element(3, T3)} -> ok;
+ true -> other
+ end,
+ ok.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_add.erl b/lib/hipe/test/bs_SUITE_data/bs_add.erl
index af5a3b2f23..4b92e6b413 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_add.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_add.erl
@@ -2,7 +2,7 @@
%%-------------------------------------------------------------------------
%% The guard in f/3 revealed a problem in the translation of the 'bs_add'
%% BEAM instruction to Icode. The fail label was not properly translated.
-%% Fixed 3/2/2011.
+%% Fixed 3/2/2011. Then in 2015 we found another issue: g/2. Also fixed.
%%-------------------------------------------------------------------------
-module(bs_add).
@@ -10,9 +10,17 @@
test() ->
42 = f(<<12345:16>>, 4711, <<42>>),
+ true = g(<<1:13>>, 3), %% was handled OK, but
+ false = g(<<>>, gurka), %% this one leaked badarith
ok.
f(Bin, A, B) when <<A:9, B:7/binary>> == Bin ->
gazonk;
f(Bin, _, _) when is_binary(Bin) ->
42.
+
+%% Complex way of testing (bit_size(Bin) + Len) rem 8 =:= 0
+g(Bin, Len) when is_binary(<<Bin/binary-unit:1, 123:Len>>) ->
+ true;
+g(_, _) ->
+ false.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_construct.erl b/lib/hipe/test/bs_SUITE_data/bs_construct.erl
index 9cc9ac848c..b9e7d93570 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_construct.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_construct.erl
@@ -13,6 +13,12 @@ test() ->
ok = bs5(),
16#10000008 = bit_size(large_bin(1, 2, 3, 4)),
ok = bad_ones(),
+ ok = zero_width(),
+ ok = not_used(),
+ ok = bad_append(),
+ ok = system_limit(),
+ ok = bad_floats(),
+ ok = huge_binaries(),
ok.
%%--------------------------------------------------------------------
@@ -126,3 +132,174 @@ bad_ones() ->
Bin123 = <<1,2,3>>,
?FAIL(<<Bin123/float>>),
ok.
+
+%%--------------------------------------------------------------------
+%% Taken from the emulator bs_construct_SUITE - seg faulted till 18.1
+
+zero_width() ->
+ Z = id(0),
+ Small = id(42),
+ Big = id(1 bsl 128), % puts stuff on the heap
+ <<>> = <<Small:Z>>,
+ <<>> = <<Small:0>>,
+ <<>> = <<Big:Z>>,
+ <<>> = <<Big:0>>,
+ ok.
+
+id(X) -> X.
+
+%%--------------------------------------------------------------------
+%% Taken from bs_construct_SUITE. The test checks that constructed
+%% binaries that are not used would still give a `badarg' exception.
+%% Problem was that in native code one of them gave `badarith'.
+
+not_used() ->
+ ok = not_used1(3, <<"dum">>),
+ {'EXIT',{badarg,_}} = (catch not_used1(42, "dum_string")),
+ {'EXIT',{badarg,_}} = (catch not_used2(666, -2)),
+ {'EXIT',{badarg,_}} = (catch not_used2(666, "bad_size")), % this one
+ {'EXIT',{badarg,_}} = (catch not_used3(666)),
+ ok.
+
+not_used1(I, BinString) ->
+ <<I:32,BinString/binary>>,
+ ok.
+
+not_used2(I, Sz) ->
+ <<I:Sz>>,
+ ok.
+
+not_used3(I) ->
+ <<I:(-8)>>,
+ ok.
+
+%%--------------------------------------------------------------------
+%% Taken from bs_construct_SUITE.
+
+bad_append() ->
+ do_bad_append(<<127:1>>, fun append_unit_3/1),
+ do_bad_append(<<127:2>>, fun append_unit_3/1),
+ do_bad_append(<<127:17>>, fun append_unit_3/1),
+
+ do_bad_append(<<127:3>>, fun append_unit_4/1),
+ do_bad_append(<<127:5>>, fun append_unit_4/1),
+ do_bad_append(<<127:7>>, fun append_unit_4/1),
+ do_bad_append(<<127:199>>, fun append_unit_4/1),
+
+ do_bad_append(<<127:7>>, fun append_unit_8/1),
+ do_bad_append(<<127:9>>, fun append_unit_8/1),
+
+ do_bad_append(<<0:8>>, fun append_unit_16/1),
+ do_bad_append(<<0:15>>, fun append_unit_16/1),
+ do_bad_append(<<0:17>>, fun append_unit_16/1),
+ ok.
+
+do_bad_append(Bin0, Appender) ->
+ {'EXIT',{badarg,_}} = (catch Appender(Bin0)),
+
+ Bin1 = id(<<0:3,Bin0/bitstring>>),
+ <<_:3,Bin2/bitstring>> = Bin1,
+ {'EXIT',{badarg,_}} = (catch Appender(Bin2)),
+
+ %% Create a writable binary.
+ Empty = id(<<>>),
+ Bin3 = <<Empty/bitstring,Bin0/bitstring>>,
+ {'EXIT',{badarg,_}} = (catch Appender(Bin3)),
+ ok.
+
+append_unit_3(Bin) ->
+ <<Bin/binary-unit:3,0:1>>.
+
+append_unit_4(Bin) ->
+ <<Bin/binary-unit:4,0:1>>.
+
+append_unit_8(Bin) ->
+ <<Bin/binary,0:1>>.
+
+append_unit_16(Bin) ->
+ <<Bin/binary-unit:16,0:1>>.
+
+%%--------------------------------------------------------------------
+%% Taken from bs_construct_SUITE.
+
+system_limit() ->
+ WordSize = erlang:system_info(wordsize),
+ BitsPerWord = WordSize * 8,
+ {'EXIT',{system_limit,_}} =
+ (catch <<0:(id(0)),42:(id(1 bsl BitsPerWord))>>),
+ {'EXIT',{system_limit,_}} =
+ (catch <<42:(id(1 bsl BitsPerWord)),0:(id(0))>>),
+ {'EXIT',{system_limit,_}} =
+ (catch <<(id(<<>>))/binary,0:(id(1 bsl 100))>>),
+
+ %% Would fail to load.
+ {'EXIT',{system_limit,_}} = (catch <<0:(1 bsl 67)>>),
+ {'EXIT',{system_limit,_}} = (catch <<0:((1 bsl 64)+1)>>),
+ case WordSize of
+ 4 ->
+ system_limit_32();
+ 8 ->
+ ok
+ end.
+
+system_limit_32() ->
+ {'EXIT',{badarg,_}} = (catch <<42:(-1)>>),
+ {'EXIT',{badarg,_}} = (catch <<42:(id(-1))>>),
+ {'EXIT',{badarg,_}} = (catch <<42:(id(-389739873536870912))/unit:8>>),
+ {'EXIT',{system_limit,_}} = (catch <<42:536870912/unit:8>>),
+ {'EXIT',{system_limit,_}} = (catch <<42:(id(536870912))/unit:8>>),
+ {'EXIT',{system_limit,_}} = (catch <<0:(id(8)),42:536870912/unit:8>>),
+ {'EXIT',{system_limit,_}} = (catch <<0:(id(8)),42:(id(536870912))/unit:8>>),
+
+ %% The size would be silently truncated, resulting in a crash.
+ {'EXIT',{system_limit,_}} = (catch <<0:(1 bsl 35)>>),
+ {'EXIT',{system_limit,_}} = (catch <<0:((1 bsl 32)+1)>>),
+
+ %% Would fail to load.
+ {'EXIT',{system_limit,_}} = (catch <<0:(1 bsl 43)>>),
+ {'EXIT',{system_limit,_}} = (catch <<0:((1 bsl 40)+1)>>),
+ ok.
+
+%%--------------------------------------------------------------------
+
+bad_floats() ->
+ WordSize = erlang:system_info(wordsize),
+ BitsPerWord = WordSize * 8,
+ {'EXIT',{badarg,_}} = (catch <<3.14:(id(33))/float>>),
+ {'EXIT',{badarg,_}} = (catch <<3.14:(id(64 bor 32))/float>>),
+ {'EXIT',{badarg,_}} = (catch <<3.14:(id((1 bsl 28) bor 32))/float>>),
+ {'EXIT',{system_limit,_}} = (catch <<3.14:(id(1 bsl BitsPerWord))/float>>),
+ ok.
+
+%%--------------------------------------------------------------------
+%% A bug in the implementation of binaries compared sizes in bits with sizes in
+%% bytes, causing <<0:(id((1 bsl 31)-1))>> to fail to construct with
+%% 'system_limit'.
+%% <<0:(id((1 bsl 32)-1))>> was succeeding because the comparison was
+%% (incorrectly) signed.
+
+huge_binaries() ->
+ AlmostIllegal = id(<<0:(id((1 bsl 32)-8))>>),
+ case erlang:system_info(wordsize) of
+ 4 -> huge_binaries_32(AlmostIllegal);
+ 8 -> ok
+ end,
+ garbage_collect(),
+ id(<<0:(id((1 bsl 31)-1))>>),
+ id(<<0:(id((1 bsl 30)-1))>>),
+ garbage_collect(),
+ ok.
+
+huge_binaries_32(AlmostIllegal) ->
+ %% Attempt construction of too large binary using bs_init/1 (which takes the
+ %% number of bytes as an argument, which should be compared to the maximum
+ %% size in bytes).
+ {'EXIT',{system_limit,_}} = (catch <<0:32,AlmostIllegal/binary>>),
+ %% Attempt construction of too large binary using bs_init/1 with a size in
+ %% bytes that has the msb set (and would be negative if it was signed).
+ {'EXIT',{system_limit,_}} =
+ (catch <<0:8, AlmostIllegal/binary, AlmostIllegal/binary,
+ AlmostIllegal/binary, AlmostIllegal/binary,
+ AlmostIllegal/binary, AlmostIllegal/binary,
+ AlmostIllegal/binary, AlmostIllegal/binary>>),
+ ok.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_match.erl b/lib/hipe/test/bs_SUITE_data/bs_match.erl
index 8194d878b8..b241ea8d35 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_match.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_match.erl
@@ -1,8 +1,8 @@
%%% -*- erlang-indent-level: 2 -*-
%%%-------------------------------------------------------------------
%%% File : bs_match.erl
-%%% Author : Per Gustafsson <[email protected]>
-%%% Purpose : Performs simple matching and construction of binaries
+%%% Authors : Per Gustafsson <[email protected]>, Kostis Sagonas <[email protected]>
+%%% Purpose : Tests matching and construction of binaries
%%% TODO : Add binary and float tests
%%% Created : 20 Feb 2004
%%%-------------------------------------------------------------------
@@ -12,7 +12,8 @@
test() ->
Funs = [fun test_aligned/0, fun test_unaligned/0,
- fun test_zero_tail/0, fun test_integer_matching/0],
+ fun test_zero_tail/0, fun test_integer_matching/0,
+ fun test_writable_bin/0, fun test_match_huge_bin/0],
lists:foreach(fun (F) -> ok = F() end, Funs).
%%-------------------------------------------------------------------
@@ -173,3 +174,116 @@ test_dynamic_integer_matching(N) ->
<<12:N/integer, 0:S>> = <<12:N/integer, 0:S>>,
<<12:N/integer-little, 0:S>> = <<12:N/integer-little, 0:S>>,
ok.
+
+%%-------------------------------------------------------------------
+%% Test writable bin -- added by Sverker Eriksson
+
+test_writable_bin() ->
+ test_writable_bin(<<>>, 0),
+ ok.
+
+test_writable_bin(Bin, 128) ->
+ Bin;
+test_writable_bin(Bin0, N) when N < 128 ->
+ Bin1 = <<Bin0/binary, N>>,
+ <<_/utf8, _/binary>> = Bin1,
+ test_writable_bin(Bin1, N+1).
+
+%%-------------------------------------------------------------------
+%% Test matching with a huge bin -- taken from bs_match_bin_SUITE
+
+test_match_huge_bin() ->
+ Bin = <<0:(1 bsl 27),13:8>>,
+ skip_huge_bin_1(1 bsl 27, Bin),
+ 16777216 = match_huge_bin_1(1 bsl 27, Bin),
+ %% Test overflowing the size of a binary field.
+ nomatch = overflow_huge_bin_skip_32(Bin),
+ nomatch = overflow_huge_bin_32(Bin),
+ nomatch = overflow_huge_bin_skip_64(Bin),
+ nomatch = overflow_huge_bin_64(Bin),
+ %% Size in variable
+ ok = overflow_huge_bin(Bin, lists:seq(25, 32)++lists:seq(50, 64)),
+ ok = overflow_huge_bin_unit128(Bin, lists:seq(25, 32)++lists:seq(50, 64)),
+ ok.
+
+overflow_huge_bin(Bin, [Sz0|Sizes]) ->
+ Sz = id(1 bsl Sz0),
+ case Bin of
+ <<_:Sz/binary-unit:8,0,_/binary>> ->
+ {error,Sz};
+ _ ->
+ case Bin of
+ <<NewBin:Sz/binary-unit:8,0,_/binary>> ->
+ {error,Sz,size(NewBin)};
+ _ ->
+ overflow_huge_bin(Bin, Sizes)
+ end
+ end;
+overflow_huge_bin(_, []) -> ok.
+
+overflow_huge_bin_unit128(Bin, [Sz0|Sizes]) ->
+ Sz = id(1 bsl Sz0),
+ case Bin of
+ <<_:Sz/binary-unit:128,0,_/binary>> ->
+ {error,Sz};
+ _ ->
+ case Bin of
+ <<NewBin:Sz/binary-unit:128,0,_/binary>> ->
+ {error,Sz,size(NewBin)};
+ _ ->
+ overflow_huge_bin_unit128(Bin, Sizes)
+ end
+ end;
+overflow_huge_bin_unit128(_, []) -> ok.
+
+skip_huge_bin_1(I, Bin) ->
+ <<_:I/binary-unit:1,13>> = Bin,
+ ok.
+
+match_huge_bin_1(I, Bin) ->
+ case Bin of
+ <<Val:I/binary-unit:1,13>> -> size(Val);
+ _ -> nomatch
+ end.
+
+overflow_huge_bin_skip_32(<<_:4294967296/binary,0,_/binary>>) -> 1; % 1 bsl 32
+overflow_huge_bin_skip_32(<<_:33554432/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 25
+overflow_huge_bin_skip_32(<<_:67108864/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 26
+overflow_huge_bin_skip_32(<<_:134217728/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 27
+overflow_huge_bin_skip_32(<<_:268435456/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 28
+overflow_huge_bin_skip_32(<<_:536870912/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 29
+overflow_huge_bin_skip_32(<<_:1073741824/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 30
+overflow_huge_bin_skip_32(<<_:2147483648/binary-unit:8,0,_/binary>>) -> 8; % 1 bsl 31
+overflow_huge_bin_skip_32(_) -> nomatch.
+
+overflow_huge_bin_32(<<Bin:4294967296/binary,_/binary>>) -> {1,Bin}; % 1 bsl 32
+overflow_huge_bin_32(<<Bin:33554432/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 25
+overflow_huge_bin_32(<<Bin:67108864/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 26
+overflow_huge_bin_32(<<Bin:134217728/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 27
+overflow_huge_bin_32(<<Bin:268435456/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 28
+overflow_huge_bin_32(<<Bin:536870912/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 29
+overflow_huge_bin_32(<<Bin:1073741824/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 30
+overflow_huge_bin_32(<<Bin:2147483648/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 31
+overflow_huge_bin_32(_) -> nomatch.
+
+overflow_huge_bin_skip_64(<<_:18446744073709551616/binary,0,_/binary>>) -> 1; % 1 bsl 64
+overflow_huge_bin_skip_64(<<_:144115188075855872/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 57
+overflow_huge_bin_skip_64(<<_:288230376151711744/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 58
+overflow_huge_bin_skip_64(<<_:576460752303423488/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 59
+overflow_huge_bin_skip_64(<<_:1152921504606846976/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 60
+overflow_huge_bin_skip_64(<<_:2305843009213693952/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 61
+overflow_huge_bin_skip_64(<<_:4611686018427387904/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 62
+overflow_huge_bin_skip_64(<<_:9223372036854775808/binary-unit:8,_/binary>>) -> 8; % 1 bsl 63
+overflow_huge_bin_skip_64(_) -> nomatch.
+
+overflow_huge_bin_64(<<Bin:18446744073709551616/binary,_/binary>>) -> {1,Bin}; % 1 bsl 64
+overflow_huge_bin_64(<<Bin:144115188075855872/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 57
+overflow_huge_bin_64(<<Bin:288230376151711744/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 58
+overflow_huge_bin_64(<<Bin:576460752303423488/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 59
+overflow_huge_bin_64(<<Bin:1152921504606846976/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 60
+overflow_huge_bin_64(<<Bin:2305843009213693952/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 61
+overflow_huge_bin_64(<<Bin:4611686018427387904/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 62
+overflow_huge_bin_64(<<Bin:9223372036854775808/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 63
+overflow_huge_bin_64(_) -> nomatch.
+
+id(I) -> I.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_split.erl b/lib/hipe/test/bs_SUITE_data/bs_split.erl
index 2e52308a77..617543f789 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_split.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_split.erl
@@ -26,13 +26,13 @@ bs1(L, B, Pos, Sz1, Sz2) ->
<<B1:Sz1/binary, B2:Sz2/binary>> = B,
bs2(L, B, Pos, B1, B2).
-bs2(L, B, Pos, B1, B2)->
+bs2(L, B, Pos, B1, B2) ->
B1 = list_to_binary(lists:sublist(L, 1, Pos)),
bs3(L, B, Pos, B2).
bs3(L, B, Pos, B2) ->
B2 = list_to_binary(lists:nthtail(Pos, L)),
- byte_split(L, B, Pos-1).
+ byte_split(L, B, Pos - 1).
%%--------------------------------------------------------------------
@@ -56,14 +56,14 @@ bit_split_binary2(_Action, _Bin, [], _Bef) -> ok.
bit_split_binary3(Action, Bin, List, Bef, Aft) when Bef =< Aft ->
Action(Bin, List, Bef, (Aft-Bef) div 8 * 8),
- bit_split_binary3(Action, Bin, List, Bef, Aft-8);
+ bit_split_binary3(Action, Bin, List, Bef, Aft - 8);
bit_split_binary3(_, _, _, _, _) -> ok.
make_bin_from_list(_List, 0) ->
mkbin([]);
make_bin_from_list(List, N) ->
list_to_binary([make_int(List, 8, 0),
- make_bin_from_list(lists:nthtail(8, List), N-8)]).
+ make_bin_from_list(lists:nthtail(8, List), N - 8)]).
make_int(_List, 0, Acc) -> Acc;
make_int([H|T], N, Acc) -> make_int(T, N-1, Acc bsl 1 bor H).
@@ -101,5 +101,5 @@ z_split(B, N) ->
<<_:N/binary>> ->
[B];
_ ->
- z_split(B, N+1)
+ z_split(B, N + 1)
end.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_utf.erl b/lib/hipe/test/bs_SUITE_data/bs_utf.erl
index f50ae08964..24526f574d 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_utf.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_utf.erl
@@ -1,18 +1,356 @@
%% -*- erlang-indent-level: 2 -*-
%%-------------------------------------------------------------------
-%% Purpose: test support for UTF datatypes in binaries - INCOMPLETE
+%% Purpose: test support for UTF datatypes in binaries
+%%
+%% Most of it taken from emulator/test/bs_utf_SUITE.erl
%%-------------------------------------------------------------------
-module(bs_utf).
-export([test/0]).
+-include_lib("test_server/include/test_server.hrl").
+
test() ->
+ ok = utf8_cm65(),
+ ok = utf8_roundtrip(),
+ ok = utf16_roundtrip(),
+ ok = utf32_roundtrip(),
+ %% The following were problematic for the LLVM backend
+ ok = utf8_illegal_sequences(),
+ ok = utf16_illegal_sequences(),
+ ok = utf32_illegal_sequences(),
+ ok.
+
+%%-------------------------------------------------------------------
+%% A test with construction and matching
+
+utf8_cm65() ->
<<65>> = b65utf8(),
ok = m(<<65>>).
+b65utf8() ->
+ <<65/utf8>>.
+
m(<<65/utf8>>) ->
ok.
-b65utf8() ->
- <<65/utf8>>.
+%%-------------------------------------------------------------------
+
+utf8_roundtrip() ->
+ ok = utf8_roundtrip(0, 16#D7FF),
+ ok = utf8_roundtrip(16#E000, 16#10FFFF),
+ ok.
+
+utf8_roundtrip(First, Last) when First =< Last ->
+ Bin = int_to_utf8(First),
+ Bin = id(<<First/utf8>>),
+ Bin = id(<<(id(<<>>))/binary,First/utf8>>),
+ Unaligned = id(<<3:2,First/utf8>>),
+ <<_:2,Bin/binary>> = Unaligned,
+ <<First/utf8>> = Bin,
+ <<First/utf8>> = make_unaligned(Bin),
+ utf8_roundtrip(First+1, Last);
+utf8_roundtrip(_, _) ->
+ ok.
+
+%%-------------------------------------------------------------------
+
+utf16_roundtrip() ->
+ Big = fun utf16_big_roundtrip/1,
+ Little = fun utf16_little_roundtrip/1,
+ PidRefs = [spawn_monitor(fun() -> do_utf16_roundtrip(Fun) end) ||
+ Fun <- [Big,Little]],
+ [receive {'DOWN', Ref, process, Pid, Reason} -> normal=Reason end ||
+ {Pid, Ref} <- PidRefs],
+ ok.
+
+do_utf16_roundtrip(Fun) ->
+ do_utf16_roundtrip(0, 16#D7FF, Fun),
+ do_utf16_roundtrip(16#E000, 16#10FFFF, Fun).
+
+do_utf16_roundtrip(First, Last, Fun) when First =< Last ->
+ Fun(First),
+ do_utf16_roundtrip(First+1, Last, Fun);
+do_utf16_roundtrip(_, _, _) -> ok.
+
+utf16_big_roundtrip(Char) ->
+ Bin = id(<<Char/utf16>>),
+ Bin = id(<<(id(<<>>))/binary,Char/utf16>>),
+ Unaligned = id(<<3:2,Char/utf16>>),
+ <<_:2,Bin/binary>> = Unaligned,
+ <<Char/utf16>> = Bin,
+ <<Char/utf16>> = make_unaligned(Bin),
+ ok.
+
+utf16_little_roundtrip(Char) ->
+ Bin = id(<<Char/little-utf16>>),
+ Bin = id(<<(id(<<>>))/binary,Char/little-utf16>>),
+ Unaligned = id(<<3:2,Char/little-utf16>>),
+ <<_:2,Bin/binary>> = Unaligned,
+ <<Char/little-utf16>> = Bin,
+ <<Char/little-utf16>> = make_unaligned(Bin),
+ ok.
+
+%%-------------------------------------------------------------------
+
+utf32_roundtrip() ->
+ Big = fun utf32_big_roundtrip/1,
+ Little = fun utf32_little_roundtrip/1,
+ PidRefs = [spawn_monitor(fun() -> do_utf32_roundtrip(Fun) end) ||
+ Fun <- [Big,Little]],
+ [receive {'DOWN', Ref, process, Pid, Reason} -> normal=Reason end ||
+ {Pid, Ref} <- PidRefs],
+ ok.
+
+do_utf32_roundtrip(Fun) ->
+ do_utf32_roundtrip(0, 16#D7FF, Fun),
+ do_utf32_roundtrip(16#E000, 16#10FFFF, Fun).
+
+do_utf32_roundtrip(First, Last, Fun) when First =< Last ->
+ Fun(First),
+ do_utf32_roundtrip(First+1, Last, Fun);
+do_utf32_roundtrip(_, _, _) -> ok.
+
+utf32_big_roundtrip(Char) ->
+ Bin = id(<<Char/utf32>>),
+ Bin = id(<<(id(<<>>))/binary,Char/utf32>>),
+ Unaligned = id(<<3:2,Char/utf32>>),
+ <<_:2,Bin/binary>> = Unaligned,
+ <<Char/utf32>> = Bin,
+ <<Char/utf32>> = make_unaligned(Bin),
+ ok.
+
+utf32_little_roundtrip(Char) ->
+ Bin = id(<<Char/little-utf32>>),
+ Bin = id(<<(id(<<>>))/binary,Char/little-utf32>>),
+ Unaligned = id(<<3:2,Char/little-utf32>>),
+ <<_:2,Bin/binary>> = Unaligned,
+ <<Char/little-utf32>> = Bin,
+ <<Char/little-utf32>> = make_unaligned(Bin),
+ ok.
+
+%%-------------------------------------------------------------------
+
+utf8_illegal_sequences() ->
+ fail_range(16#10FFFF+1, 16#10FFFF+512), % Too large.
+ fail_range(16#D800, 16#DFFF), % Reserved for UTF-16.
+
+ %% Illegal first character.
+ [fail(<<I,16#8F,16#8F,16#8F>>) || I <- lists:seq(16#80, 16#BF)],
+
+ %% Short sequences.
+ short_sequences(16#80, 16#10FFFF),
+
+ %% Overlong sequences. (Using more bytes than necessary
+ %% is not allowed.)
+ overlong(0, 127, 2),
+ overlong(128, 16#7FF, 3),
+ overlong(16#800, 16#FFFF, 4),
+ ok.
+
+fail_range(Char, End) when Char =< End ->
+ {'EXIT', _} = (catch <<Char/utf8>>),
+ Bin = int_to_utf8(Char),
+ fail(Bin),
+ fail_range(Char+1, End);
+fail_range(_, _) -> ok.
+
+short_sequences(Char, End) ->
+ Step = (End - Char) div erlang:system_info(schedulers) + 1,
+ PidRefs = short_sequences_1(Char, Step, End),
+ [receive {'DOWN', Ref, process, Pid, Reason} -> normal=Reason end ||
+ {Pid, Ref} <- PidRefs],
+ ok.
+
+short_sequences_1(Char, Step, End) when Char =< End ->
+ CharEnd = lists:min([Char+Step-1,End]),
+ [spawn_monitor(fun() ->
+ %% io:format("~p - ~p\n", [Char, CharEnd]),
+ do_short_sequences(Char, CharEnd)
+ end)|short_sequences_1(Char+Step, Step, End)];
+short_sequences_1(_, _, _) -> [].
+
+do_short_sequences(Char, End) when Char =< End ->
+ short_sequence(Char),
+ do_short_sequences(Char+1, End);
+do_short_sequences(_, _) -> ok.
+
+short_sequence(I) ->
+ case int_to_utf8(I) of
+ <<S0:3/binary,_:8>> ->
+ <<S1:2/binary,R1:8>> = S0,
+ <<S2:1/binary,_:8>> = S1,
+ fail(S0),
+ fail(S1),
+ fail(S2),
+ fail(<<S2/binary,16#7F,R1,R1>>),
+ fail(<<S1/binary,16#7F,R1>>),
+ fail(<<S0/binary,16#7F>>);
+ <<S0:2/binary,_:8>> ->
+ <<S1:1/binary,R1:8>> = S0,
+ fail(S0),
+ fail(S1),
+ fail(<<S0/binary,16#7F>>),
+ fail(<<S1/binary,16#7F>>),
+ fail(<<S1/binary,16#7F,R1>>);
+ <<S:1/binary,_:8>> ->
+ fail(S),
+ fail(<<S/binary,16#7F>>)
+ end.
+
+overlong(Char, Last, NumBytes) when Char =< Last ->
+ overlong(Char, NumBytes),
+ overlong(Char+1, Last, NumBytes);
+overlong(_, _, _) -> ok.
+
+overlong(Char, NumBytes) when NumBytes < 5 ->
+ case int_to_utf8(Char, NumBytes) of
+ <<Char/utf8>>=Bin ->
+ ?t:fail({illegal_encoding_accepted,Bin,Char});
+ <<OtherChar/utf8>>=Bin ->
+ ?t:fail({illegal_encoding_accepted,Bin,Char,OtherChar});
+ _ -> ok
+ end,
+ overlong(Char, NumBytes+1);
+overlong(_, _) -> ok.
+
+fail(Bin) ->
+ fail_1(Bin),
+ fail_1(make_unaligned(Bin)).
+
+fail_1(<<Char/utf8>> = Bin) ->
+ ?t:fail({illegal_encoding_accepted, Bin, Char});
+fail_1(_) -> ok.
+
+%%-------------------------------------------------------------------
+
+utf16_illegal_sequences() ->
+ utf16_fail_range(16#10FFFF+1, 16#10FFFF+512), % Too large.
+ utf16_fail_range(16#D800, 16#DFFF), % Reserved for UTF-16.
+ lonely_hi_surrogate(16#D800, 16#DFFF),
+ leading_lo_surrogate(16#DC00, 16#DFFF),
+ ok.
+
+utf16_fail_range(Char, End) when Char =< End ->
+ {'EXIT', _} = (catch <<Char/big-utf16>>),
+ {'EXIT', _} = (catch <<Char/little-utf16>>),
+ utf16_fail_range(Char+1, End);
+utf16_fail_range(_, _) -> ok.
+
+lonely_hi_surrogate(Char, End) when Char =< End ->
+ BinBig = <<Char:16/big>>,
+ BinLittle = <<Char:16/little>>,
+ case {BinBig,BinLittle} of
+ {<<Bad/big-utf16>>,_} ->
+ ?t:fail({lonely_hi_surrogate_accepted,Bad});
+ {_,<<Bad/little-utf16>>} ->
+ ?t:fail({lonely_hi_surrogate_accepted,Bad});
+ {_,_} ->
+ ok
+ end,
+ lonely_hi_surrogate(Char+1, End);
+lonely_hi_surrogate(_, _) -> ok.
+
+leading_lo_surrogate(Char, End) when Char =< End ->
+ leading_lo_surrogate(Char, 16#D800, 16#DFFF),
+ leading_lo_surrogate(Char+1, End);
+leading_lo_surrogate(_, _) -> ok.
+
+leading_lo_surrogate(HiSurr, LoSurr, End) when LoSurr =< End ->
+ BinBig = <<HiSurr:16/big,LoSurr:16/big>>,
+ BinLittle = <<HiSurr:16/little,LoSurr:16/little>>,
+ case {BinBig,BinLittle} of
+ {<<Bad/big-utf16,_/bits>>,_} ->
+ ?t:fail({leading_lo_surrogate_accepted,Bad});
+ {_,<<Bad/little-utf16,_/bits>>} ->
+ ?t:fail({leading_lo_surrogate_accepted,Bad});
+ {_,_} ->
+ ok
+ end,
+ leading_lo_surrogate(HiSurr, LoSurr+1, End);
+leading_lo_surrogate(_, _, _) -> ok.
+
+%%-------------------------------------------------------------------
+
+utf32_illegal_sequences() ->
+ utf32_fail_range(16#10FFFF+1, 16#10FFFF+512), % Too large.
+ utf32_fail_range(16#D800, 16#DFFF), % Reserved for UTF-16.
+ utf32_fail_range(-100, -1),
+ ok.
+
+utf32_fail_range(Char, End) when Char =< End ->
+ {'EXIT', _} = (catch <<Char/big-utf32>>),
+ {'EXIT', _} = (catch <<Char/little-utf32>>),
+ case {<<Char:32>>,<<Char:32/little>>} of
+ {<<Unexpected/utf32>>,_} ->
+ ?t:fail(Unexpected);
+ {_,<<Unexpected/little-utf32>>} ->
+ ?t:fail(Unexpected);
+ {_,_} -> ok
+ end,
+ utf32_fail_range(Char+1, End);
+utf32_fail_range(_, _) -> ok.
+
+%%-------------------------------------------------------------------
+%% This function intentionally allows construction of UTF-8 sequence
+%% in illegal ranges.
+
+int_to_utf8(I) when I =< 16#7F ->
+ <<I>>;
+int_to_utf8(I) when I =< 16#7FF ->
+ B2 = I,
+ B1 = (I bsr 6),
+ <<1:1,1:1,0:1,B1:5,1:1,0:1,B2:6>>;
+int_to_utf8(I) when I =< 16#FFFF ->
+ B3 = I,
+ B2 = (I bsr 6),
+ B1 = (I bsr 12),
+ <<1:1,1:1,1:1,0:1,B1:4,1:1,0:1,B2:6,1:1,0:1,B3:6>>;
+int_to_utf8(I) when I =< 16#3FFFFF ->
+ B4 = I,
+ B3 = (I bsr 6),
+ B2 = (I bsr 12),
+ B1 = (I bsr 18),
+ <<1:1,1:1,1:1,1:1,0:1,B1:3,1:1,0:1,B2:6,1:1,0:1,B3:6,1:1,0:1,B4:6>>;
+int_to_utf8(I) when I =< 16#3FFFFFF ->
+ B5 = I,
+ B4 = (I bsr 6),
+ B3 = (I bsr 12),
+ B2 = (I bsr 18),
+ B1 = (I bsr 24),
+ <<1:1,1:1,1:1,1:1,1:1,0:1,B1:2,1:1,0:1,B2:6,1:1,0:1,B3:6,1:1,0:1,B4:6,
+ 1:1,0:1,B5:6>>.
+
+%% int_to_utf8(I, NumberOfBytes) -> Binary.
+%% This function can be used to construct overlong sequences.
+int_to_utf8(I, 1) ->
+ <<I>>;
+int_to_utf8(I, 2) ->
+ B2 = I,
+ B1 = (I bsr 6),
+ <<1:1,1:1,0:1,B1:5,1:1,0:1,B2:6>>;
+int_to_utf8(I, 3) ->
+ B3 = I,
+ B2 = (I bsr 6),
+ B1 = (I bsr 12),
+ <<1:1,1:1,1:1,0:1,B1:4,1:1,0:1,B2:6,1:1,0:1,B3:6>>;
+int_to_utf8(I, 4) ->
+ B4 = I,
+ B3 = (I bsr 6),
+ B2 = (I bsr 12),
+ B1 = (I bsr 18),
+ <<1:1,1:1,1:1,1:1,0:1,B1:3,1:1,0:1,B2:6,1:1,0:1,B3:6,1:1,0:1,B4:6>>.
+
+%%-------------------------------------------------------------------
+
+make_unaligned(Bin0) when is_binary(Bin0) ->
+ Bin1 = <<0:3,Bin0/binary,31:5>>,
+ Sz = byte_size(Bin0),
+ <<0:3,Bin:Sz/binary,31:5>> = id(Bin1),
+ Bin.
+
+%%-------------------------------------------------------------------
+%% Just to prevent compiler optimizations
+
+id(X) -> X.
diff --git a/lib/hipe/test/hipe_SUITE.erl b/lib/hipe/test/hipe_SUITE.erl
index 554bc972f6..9319b710d9 100644
--- a/lib/hipe/test/hipe_SUITE.erl
+++ b/lib/hipe/test/hipe_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/hipe/test/hipe_testsuite_driver.erl b/lib/hipe/test/hipe_testsuite_driver.erl
index 5f05a716bc..9f5d7421b4 100644
--- a/lib/hipe/test/hipe_testsuite_driver.erl
+++ b/lib/hipe/test/hipe_testsuite_driver.erl
@@ -176,7 +176,8 @@ run(TestCase, Dir, _OutDir) ->
HiPEOpts = try TestCase:hipe_options() catch error:undef -> [] end,
{ok, TestCase} = hipe:c(TestCase, HiPEOpts),
ok = TestCase:test(),
- case is_llvm_opt_available() of
+ ToLLVM = try TestCase:to_llvm() catch error:undef -> true end,
+ case ToLLVM andalso hipe:llvm_support_available() of
true ->
{ok, TestCase} = hipe:c(TestCase, [to_llvm|HiPEOpts]),
ok = TestCase:test();
@@ -186,16 +187,3 @@ run(TestCase, Dir, _OutDir) ->
%% lists:foreach(fun (DF) -> ok end, % = file:delete(DF) end,
%% [filename:join(OutDir, D) || D <- DataFiles])
%% end.
-
-
-%% This function, which is supposed to check whether the right LLVM
-%% infrastructure is available, should be probably written in a better
-%% and more portable way and moved to the hipe application.
-
-is_llvm_opt_available() ->
- OptStr = os:cmd("opt -version"),
- SubStr = "LLVM version ", N = length(SubStr),
- case string:str(OptStr, SubStr) of
- 0 -> false;
- S -> P = S + N, string:sub_string(OptStr, P, P + 2) >= "3.4"
- end.
diff --git a/lib/hipe/test/maps_SUITE_data/maps_map_size.erl b/lib/hipe/test/maps_SUITE_data/maps_map_size.erl
index 25c8e5d4c7..3cd2d90dfb 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_map_size.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_map_size.erl
@@ -17,9 +17,9 @@ test() ->
false = map_is_size(M#{ "c" => 2}, 2),
%% Error cases.
- {'EXIT',{badarg,_}} = (catch map_size([])),
- {'EXIT',{badarg,_}} = (catch map_size(<<1,2,3>>)),
- {'EXIT',{badarg,_}} = (catch map_size(1)),
+ {'EXIT',{{badmap,[]},_}} = (catch map_size([])),
+ {'EXIT',{{badmap,<<1,2,3>>},_}} = (catch map_size(<<1,2,3>>)),
+ {'EXIT',{{badmap,1},_}} = (catch map_size(1)),
ok.
map_is_size(M,N) when map_size(M) =:= N -> true;
diff --git a/lib/hipe/test/maps_SUITE_data/maps_map_sort_literals.erl b/lib/hipe/test/maps_SUITE_data/maps_map_sort_literals.erl
index 31abf15d49..ccacbfe5c8 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_map_sort_literals.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_map_sort_literals.erl
@@ -10,23 +10,25 @@ test() ->
false = #{ c => 1, b => 1, a => 1} < id(#{ c => 1, a => 1}),
%% key order
- true = id(#{ a => 1 }) < id(#{ b => 1}),
- false = id(#{ b => 1 }) < id(#{ a => 1}),
- true = id(#{ a => 1, b => 1, c => 1 }) < id(#{ b => 1, c => 1, d => 1}),
- true = id(#{ b => 1, c => 1, d => 1 }) > id(#{ a => 1, b => 1, c => 1}),
- true = id(#{ c => 1, b => 1, a => 1 }) < id(#{ b => 1, c => 1, d => 1}),
- true = id(#{ "a" => 1 }) < id(#{ <<"a">> => 1}),
- false = id(#{ <<"a">> => 1 }) < id(#{ "a" => 1}),
- false = id(#{ 1 => 1 }) < id(#{ 1.0 => 1}),
- false = id(#{ 1.0 => 1 }) < id(#{ 1 => 1}),
+ true = #{ a => 1 } < id(#{ b => 1}),
+ false = #{ b => 1 } < id(#{ a => 1}),
+ true = #{ a => 1, b => 1, c => 1 } < id(#{ b => 1, c => 1, d => 1}),
+ true = #{ b => 1, c => 1, d => 1 } > id(#{ a => 1, b => 1, c => 1}),
+ true = #{ c => 1, b => 1, a => 1 } < id(#{ b => 1, c => 1, d => 1}),
+ true = #{ "a" => 1 } < id(#{ <<"a">> => 1}),
+ false = #{ <<"a">> => 1 } < id(#{ "a" => 1}),
+ true = #{ 1 => 1 } < id(#{ 1.0 => 1}),
+ false = #{ 1.0 => 1 } < id(#{ 1 => 1}),
%% value order
- true = id(#{ a => 1 }) < id(#{ a => 2}),
- false = id(#{ a => 2 }) < id(#{ a => 1}),
- false = id(#{ a => 2, b => 1 }) < id(#{ a => 1, b => 3}),
- true = id(#{ a => 1, b => 1 }) < id(#{ a => 1, b => 3}),
+ true = #{ a => 1 } < id(#{ a => 2}),
+ false = #{ a => 2 } < id(#{ a => 1}),
+ false = #{ a => 2, b => 1 } < id(#{ a => 1, b => 3}),
+ true = #{ a => 1, b => 1 } < id(#{ a => 1, b => 3}),
+ false = #{ a => 1 } < id(#{ a => 1.0}),
+ false = #{ a => 1.0 } < id(#{ a => 1}),
- true = id(#{ "a" => "hi", b => 134 }) == id(#{ b => 134,"a" => "hi"}),
+ true = #{ "a" => "hi", b => 134 } == id(#{ b => 134,"a" => "hi"}),
%% lists:sort
@@ -34,7 +36,6 @@ test() ->
[#{1:=ok},#{a:=ok},#{"a":=ok},#{<<"a">>:=ok}] = lists:sort([#{"a"=>ok},#{a=>ok},#{1=>ok},#{<<"a">>=>ok}]),
[#{1:=3},#{a:=2},#{"a":=1},#{<<"a">>:=4}] = lists:sort(SortVs),
[#{1:=3},#{a:=2},#{"a":=1},#{<<"a">>:=4}] = lists:sort(lists:reverse(SortVs)),
-
ok.
%% Use this function to avoid compile-time evaluation of an expression.
diff --git a/lib/hipe/test/maps_SUITE_data/maps_put_map_assoc.erl b/lib/hipe/test/maps_SUITE_data/maps_put_map_assoc.erl
index 72ac9ce078..2fe4f204d1 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_put_map_assoc.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_put_map_assoc.erl
@@ -8,7 +8,7 @@ test() ->
true = assoc_guard(#{}),
false = assoc_guard(not_a_map),
#{a := true} = assoc_update(#{}),
- {'EXIT', {badarg, [{?MODULE, assoc_update, 1, _}|_]}}
+ {'EXIT', {{badmap, not_a_map}, [{?MODULE, assoc_update, 1, _}|_]}}
= (catch assoc_update(not_a_map)),
ok = assoc_guard_clause(#{}),
{'EXIT', {function_clause, [{?MODULE, assoc_guard_clause, _, _}|_]}}
diff --git a/lib/hipe/test/maps_SUITE_data/maps_put_map_exact.erl b/lib/hipe/test/maps_SUITE_data/maps_put_map_exact.erl
index 1cfcd80180..3c85289a36 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_put_map_exact.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_put_map_exact.erl
@@ -9,9 +9,9 @@ test() ->
false = exact_guard(not_a_map),
true = exact_guard(#{a => false}),
#{a := true} = exact_update(#{a => false}),
- {'EXIT', {badarg, [{?MODULE, exact_update, 1, _}|_]}}
+ {'EXIT', {{badmap, not_a_map}, [{?MODULE, exact_update, 1, _}|_]}}
= (catch exact_update(not_a_map)),
- {'EXIT', {badarg, [{?MODULE, exact_update, 1, _}|_]}}
+ {'EXIT', {{badkey, a}, [{?MODULE, exact_update, 1, _}|_]}}
= (catch exact_update(#{})),
ok = exact_guard_clause(#{a => yes}),
{'EXIT', {function_clause, [{?MODULE, exact_guard_clause, _, _}|_]}}
diff --git a/lib/hipe/test/maps_SUITE_data/maps_update_assoc.erl b/lib/hipe/test/maps_SUITE_data/maps_update_assoc.erl
index cc7c1353de..99228a1927 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_update_assoc.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_update_assoc.erl
@@ -14,7 +14,7 @@ test() ->
%% Errors cases.
BadMap = id(badmap),
- {'EXIT',{badarg,_}} = (catch BadMap#{nonexisting=>val}),
+ {'EXIT',{{badmap,badmap},_}} = (catch BadMap#{nonexisting=>val}),
ok.
diff --git a/lib/hipe/test/maps_SUITE_data/maps_update_exact.erl b/lib/hipe/test/maps_SUITE_data/maps_update_exact.erl
index 6e5acb3283..1c38820a7c 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_update_exact.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_update_exact.erl
@@ -21,11 +21,11 @@ test() ->
1.0 => new_val4 },
%% Errors cases.
- {'EXIT',{badarg,_}} = (catch ((id(nil))#{ a := b })),
- {'EXIT',{badarg,_}} = (catch M0#{nonexisting:=val}),
- {'EXIT',{badarg,_}} = (catch M0#{1.0:=v,1.0=>v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42.0:=v,42:=v2}),
- {'EXIT',{badarg,_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ {'EXIT',{{badmap,nil},_}} = (catch ((id(nil))#{ a := b })),
+ {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{1.0:=v,1.0=>v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42.0:=v,42:=v2}),
+ {'EXIT',{{badkey,_},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
ok.
%% Use this function to avoid compile-time evaluation of an expression.
diff --git a/lib/hipe/test/maps_SUITE_data/maps_update_map_expressions.erl b/lib/hipe/test/maps_SUITE_data/maps_update_map_expressions.erl
index 181e3f18f7..213fc33d97 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_update_map_expressions.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_update_map_expressions.erl
@@ -23,9 +23,9 @@ test() ->
#{ "a" := b } = F(),
- %% Error cases, FIXME: should be 'badmap'?
- {'EXIT',{badarg,_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
- {'EXIT',{badarg,_}} = (catch (id([]))#{ a := 42, b => 2 }),
+ %% Error cases.
+ {'EXIT',{{badmap,<<>>},_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
+ {'EXIT',{{badmap,[]},_}} = (catch (id([]))#{ a := 42, b => 2 }),
ok.
%% Use this function to avoid compile-time evaluation of an expression.
diff --git a/lib/hipe/test/sanity_SUITE_data/sanity_comp_timeout.erl b/lib/hipe/test/sanity_SUITE_data/sanity_comp_timeout.erl
new file mode 100644
index 0000000000..9f0830574f
--- /dev/null
+++ b/lib/hipe/test/sanity_SUITE_data/sanity_comp_timeout.erl
@@ -0,0 +1,28 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%----------------------------------------------------------------------
+%%% Author: Kostis Sagonas
+%%%
+%%% Tests that when the native code compilation times out or gets killed
+%%% for some other reason, the parent process does not also get killed.
+%%%
+%%% Problem discovered by Bjorn G. on 1/12/2003 and fixed by Kostis.
+%%%----------------------------------------------------------------------
+
+-module(sanity_comp_timeout).
+
+-export([test/0, to_llvm/0]).
+
+test() ->
+ ok = write_dummy_mod(),
+ error_logger:tty(false), % disable printouts of error reports
+ Self = self(), % get the parent process
+ c:c(dummy_mod, [native, {hipe, [{timeout, 1}]}]), % This will kill the process
+ Self = self(), % make sure the parent process stays the same
+ ok.
+
+to_llvm() -> false.
+
+write_dummy_mod() ->
+ Prog = <<"-module(dummy_mod).\n-export([test/0]).\ntest() -> ok.\n">>,
+ ok = file:write_file("dummy_mod.erl", Prog).
+
diff --git a/lib/hipe/test/sanity_SUITE_data/sanity_no_zombies.erl b/lib/hipe/test/sanity_SUITE_data/sanity_no_zombies.erl
new file mode 100644
index 0000000000..87e746042e
--- /dev/null
+++ b/lib/hipe/test/sanity_SUITE_data/sanity_no_zombies.erl
@@ -0,0 +1,21 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%----------------------------------------------------------------------
+%%% Author: Per Gustafsson
+%%%
+%%% Checks that HiPE's concurrent compilation does not leave any zombie
+%%% processes around after compilation has finished.
+%%%
+%%% This was a bug reported on erlang-bugs (Oct 25, 2007).
+%%%----------------------------------------------------------------------
+
+-module(sanity_no_zombies).
+
+-export([test/0, to_llvm/0]).
+
+test() ->
+ L = length(processes()),
+ hipe:c(?MODULE, [concurrent_comp]), % force concurrent compilation
+ L = length(processes()),
+ ok.
+
+to_llvm() -> false.
diff --git a/lib/hipe/tools/Makefile b/lib/hipe/tools/Makefile
index ed80eb075b..095a210529 100644
--- a/lib/hipe/tools/Makefile
+++ b/lib/hipe/tools/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/tools/hipe_jit.erl b/lib/hipe/tools/hipe_jit.erl
index 0ac84388ae..20118cd523 100644
--- a/lib/hipe/tools/hipe_jit.erl
+++ b/lib/hipe/tools/hipe_jit.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/tools/hipe_profile.erl b/lib/hipe/tools/hipe_profile.erl
index ea6b1fb42c..fea2d46101 100644
--- a/lib/hipe/tools/hipe_profile.erl
+++ b/lib/hipe/tools/hipe_profile.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/tools/hipe_timer.erl b/lib/hipe/tools/hipe_timer.erl
index 03cc358f17..179060c149 100644
--- a/lib/hipe/tools/hipe_timer.erl
+++ b/lib/hipe/tools/hipe_timer.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -46,27 +47,27 @@ tr(F) ->
{R,{WT-EWT,(RT-ERT)/1000}}.
empty_time() ->
- {WT1,WT2,WT3} = erlang:now(),
+ WTA = erlang:monotonic_time(),
{A,_} = erlang:statistics(runtime),
- {WT12,WT22,WT32} = erlang:now(),
+ WTB = erlang:monotonic_time(),
{B,_} = erlang:statistics(runtime),
- {(WT12-WT1)*1000000+(WT22-WT2)+(WT32-WT3)/1000000,B-A}.
+ {(WTB-WTA)/erlang:convert_time_unit(1, seconds, native),B-A}.
time(F) ->
- {WT1,WT2,WT3} = erlang:now(),
+ WTA = erlang:monotonic_time(),
{A,_} = erlang:statistics(runtime),
F(),
- {WT12,WT22,WT32} = erlang:now(),
+ WTB = erlang:monotonic_time(),
{B,_} = erlang:statistics(runtime),
- {(WT12-WT1)*1000000+(WT22-WT2)+(WT32-WT3)/1000000,B-A}.
+ {(WTB-WTA)/erlang:convert_time_unit(1, seconds, native),B-A}.
timer(F) ->
- {WT1,WT2,WT3} = erlang:now(),
+ WTA = erlang:monotonic_time(),
{A,_} = erlang:statistics(runtime),
R = F(),
- {WT12,WT22,WT32} = erlang:now(),
+ WTB = erlang:monotonic_time(),
{B,_} = erlang:statistics(runtime),
- {R,{(WT12-WT1)*1000000+(WT22-WT2)+(WT32-WT3)/1000000,B-A}}.
+ {R,{(WTB-WTA)/erlang:convert_time_unit(1, seconds, native),B-A}}.
advanced(_Fun, I) when I < 2 -> false;
advanced(Fun, Iterations) ->
diff --git a/lib/hipe/util/Makefile b/lib/hipe/util/Makefile
index a5ee232057..4a78ad7a1b 100644
--- a/lib/hipe/util/Makefile
+++ b/lib/hipe/util/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/util/hipe_digraph.erl b/lib/hipe/util/hipe_digraph.erl
index 01b1f8c77c..c5f7d482e4 100644
--- a/lib/hipe/util/hipe_digraph.erl
+++ b/lib/hipe/util/hipe_digraph.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/util/hipe_dot.erl b/lib/hipe/util/hipe_dot.erl
index 94f7fd60cc..76af78d6a2 100644
--- a/lib/hipe/util/hipe_dot.erl
+++ b/lib/hipe/util/hipe_dot.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/util/hipe_timing.erl b/lib/hipe/util/hipe_timing.erl
index 191db497e2..9f423f29f1 100644
--- a/lib/hipe/util/hipe_timing.erl
+++ b/lib/hipe/util/hipe_timing.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/util/hipe_vectors.erl b/lib/hipe/util/hipe_vectors.erl
index d153f3a50d..ceab52a7dc 100644
--- a/lib/hipe/util/hipe_vectors.erl
+++ b/lib/hipe/util/hipe_vectors.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/util/hipe_vectors.hrl b/lib/hipe/util/hipe_vectors.hrl
index 5e24db238d..825074e2cf 100644
--- a/lib/hipe/util/hipe_vectors.hrl
+++ b/lib/hipe/util/hipe_vectors.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 60b4e0559b..2edfd790ed 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.11.3
+HIPE_VSN = 3.15
diff --git a/lib/hipe/x86/Makefile b/lib/hipe/x86/Makefile
index 3602949944..ddd704d054 100644
--- a/lib/hipe/x86/Makefile
+++ b/lib/hipe/x86/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl
index 36da2f4d44..54ecc468f8 100644
--- a/lib/hipe/x86/hipe_rtl_to_x86.erl
+++ b/lib/hipe/x86/hipe_rtl_to_x86.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86.erl b/lib/hipe/x86/hipe_x86.erl
index 3298151366..9348d88d25 100644
--- a/lib/hipe/x86/hipe_x86.erl
+++ b/lib/hipe/x86/hipe_x86.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/x86/hipe_x86.hrl b/lib/hipe/x86/hipe_x86.hrl
index 3d22fb381f..8a62480530 100644
--- a/lib/hipe/x86/hipe_x86.hrl
+++ b/lib/hipe/x86/hipe_x86.hrl
@@ -3,16 +3,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_assemble.erl b/lib/hipe/x86/hipe_x86_assemble.erl
index 3f756769c4..695ce16887 100644
--- a/lib/hipe/x86/hipe_x86_assemble.erl
+++ b/lib/hipe/x86/hipe_x86_assemble.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
@@ -82,7 +83,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
DataRelocs = hipe_pack_constants:mk_data_relocs(RefsFromConsts, LabelMap),
SSE = hipe_pack_constants:slim_sorted_exportmap(ExportMap,Closures,Exports),
SlimRefs = hipe_pack_constants:slim_refs(AccRefs),
- Bin = term_to_binary([{?VERSION_STRING(),?HIPE_SYSTEM_CRC},
+ Bin = term_to_binary([{?VERSION_STRING(),?HIPE_ERTS_CHECKSUM},
ConstAlign, ConstSize,
SC,
DataRelocs, % nee LM, LabelMap
diff --git a/lib/hipe/x86/hipe_x86_cfg.erl b/lib/hipe/x86/hipe_x86_cfg.erl
index d15dcc061a..374a0868b9 100644
--- a/lib/hipe/x86/hipe_x86_cfg.erl
+++ b/lib/hipe/x86/hipe_x86_cfg.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/x86/hipe_x86_defuse.erl b/lib/hipe/x86/hipe_x86_defuse.erl
index 3387f77595..68e6a55942 100644
--- a/lib/hipe/x86/hipe_x86_defuse.erl
+++ b/lib/hipe/x86/hipe_x86_defuse.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_encode.erl b/lib/hipe/x86/hipe_x86_encode.erl
index db7f53ad26..3b209dfe52 100644
--- a/lib/hipe/x86/hipe_x86_encode.erl
+++ b/lib/hipe/x86/hipe_x86_encode.erl
@@ -3,16 +3,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_frame.erl b/lib/hipe/x86/hipe_x86_frame.erl
index 0a3317a369..1b23f90809 100644
--- a/lib/hipe/x86/hipe_x86_frame.erl
+++ b/lib/hipe/x86/hipe_x86_frame.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_liveness.erl b/lib/hipe/x86/hipe_x86_liveness.erl
index 6874b05a59..e93faf64a8 100644
--- a/lib/hipe/x86/hipe_x86_liveness.erl
+++ b/lib/hipe/x86/hipe_x86_liveness.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_main.erl b/lib/hipe/x86/hipe_x86_main.erl
index f45a49ca0a..2b3ebf6f1b 100644
--- a/lib/hipe/x86/hipe_x86_main.erl
+++ b/lib/hipe/x86/hipe_x86_main.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/x86/hipe_x86_postpass.erl b/lib/hipe/x86/hipe_x86_postpass.erl
index a95a8745ba..a0bbf29510 100644
--- a/lib/hipe/x86/hipe_x86_postpass.erl
+++ b/lib/hipe/x86/hipe_x86_postpass.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2003-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.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_pp.erl b/lib/hipe/x86/hipe_x86_pp.erl
index 555e21a446..ab7ae5b703 100644
--- a/lib/hipe/x86/hipe_x86_pp.erl
+++ b/lib/hipe/x86/hipe_x86_pp.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_ra.erl b/lib/hipe/x86/hipe_x86_ra.erl
index d50b9aabad..117bd06ab7 100644
--- a/lib/hipe/x86/hipe_x86_ra.erl
+++ b/lib/hipe/x86/hipe_x86_ra.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/x86/hipe_x86_ra_finalise.erl b/lib/hipe/x86/hipe_x86_ra_finalise.erl
index 10b4df05d2..bac3dab867 100644
--- a/lib/hipe/x86/hipe_x86_ra_finalise.erl
+++ b/lib/hipe/x86/hipe_x86_ra_finalise.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_ra_ls.erl b/lib/hipe/x86/hipe_x86_ra_ls.erl
index ab7b6708ad..09fce1f33b 100644
--- a/lib/hipe/x86/hipe_x86_ra_ls.erl
+++ b/lib/hipe/x86/hipe_x86_ra_ls.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_ra_naive.erl b/lib/hipe/x86/hipe_x86_ra_naive.erl
index e9b99cd2c5..14eaf00860 100644
--- a/lib/hipe/x86/hipe_x86_ra_naive.erl
+++ b/lib/hipe/x86/hipe_x86_ra_naive.erl
@@ -4,16 +4,17 @@
%%%
%%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_ra_postconditions.erl b/lib/hipe/x86/hipe_x86_ra_postconditions.erl
index 6d7e90df43..de5a4f6a4d 100644
--- a/lib/hipe/x86/hipe_x86_ra_postconditions.erl
+++ b/lib/hipe/x86/hipe_x86_ra_postconditions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/x86/hipe_x86_ra_x87_ls.erl b/lib/hipe/x86/hipe_x86_ra_x87_ls.erl
index 6bdb08c6fb..e412ed262d 100644
--- a/lib/hipe/x86/hipe_x86_ra_x87_ls.erl
+++ b/lib/hipe/x86/hipe_x86_ra_x87_ls.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/hipe/x86/hipe_x86_registers.erl b/lib/hipe/x86/hipe_x86_registers.erl
index 1cfa095995..db9497b569 100644
--- a/lib/hipe/x86/hipe_x86_registers.erl
+++ b/lib/hipe/x86/hipe_x86_registers.erl
@@ -3,16 +3,17 @@
%%%
%%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%%
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.1, (the "License"); you may not use this file except in
-%%% compliance with the License. You should have received a copy of the
-%%% Erlang Public License along with this software. If not, it can be
-%%% retrieved online at http://www.erlang.org/.
-%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/hipe/x86/hipe_x86_spill_restore.erl b/lib/hipe/x86/hipe_x86_spill_restore.erl
index cd927669fb..590ec43d23 100644
--- a/lib/hipe/x86/hipe_x86_spill_restore.erl
+++ b/lib/hipe/x86/hipe_x86_spill_restore.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/hipe/x86/hipe_x86_x87.erl b/lib/hipe/x86/hipe_x86_x87.erl
index 6ef14abdbb..dcab396483 100644
--- a/lib/hipe/x86/hipe_x86_x87.erl
+++ b/lib/hipe/x86/hipe_x86_x87.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/Makefile b/lib/ic/Makefile
index 07db8b7d35..99207d3e57 100644
--- a/lib/ic/Makefile
+++ b/lib/ic/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/c_src/Makefile b/lib/ic/c_src/Makefile
index 8256edda64..89443e4327 100644
--- a/lib/ic/c_src/Makefile
+++ b/lib/ic/c_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/c_src/Makefile.in b/lib/ic/c_src/Makefile.in
index ed860ab73b..b9f92a0925 100644
--- a/lib/ic/c_src/Makefile.in
+++ b/lib/ic/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/c_src/Makefile.win32 b/lib/ic/c_src/Makefile.win32
index d782555788..abd676ffb1 100644
--- a/lib/ic/c_src/Makefile.win32
+++ b/lib/ic/c_src/Makefile.win32
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/c_src/ic.c b/lib/ic/c_src/ic.c
index 1c9b58b21b..0c8bb3479d 100644
--- a/lib/ic/c_src/ic.c
+++ b/lib/ic/c_src/ic.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/ic_tmo.c b/lib/ic/c_src/ic_tmo.c
index 78698a6a89..d1a81210af 100644
--- a/lib/ic/c_src/ic_tmo.c
+++ b/lib/ic/c_src/ic_tmo.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_code_erlang_binary.c b/lib/ic/c_src/oe_ei_code_erlang_binary.c
index a484dadbe0..e1842b8dee 100644
--- a/lib/ic/c_src/oe_ei_code_erlang_binary.c
+++ b/lib/ic/c_src/oe_ei_code_erlang_binary.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_decode_longlong.c b/lib/ic/c_src/oe_ei_decode_longlong.c
index 1fd5c8420a..d685bc420b 100644
--- a/lib/ic/c_src/oe_ei_decode_longlong.c
+++ b/lib/ic/c_src/oe_ei_decode_longlong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_decode_ulonglong.c b/lib/ic/c_src/oe_ei_decode_ulonglong.c
index 26e4294783..b1e022011b 100644
--- a/lib/ic/c_src/oe_ei_decode_ulonglong.c
+++ b/lib/ic/c_src/oe_ei_decode_ulonglong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_decode_wchar.c b/lib/ic/c_src/oe_ei_decode_wchar.c
index b68cdb829f..adc99dfabc 100644
--- a/lib/ic/c_src/oe_ei_decode_wchar.c
+++ b/lib/ic/c_src/oe_ei_decode_wchar.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_decode_wstring.c b/lib/ic/c_src/oe_ei_decode_wstring.c
index b89922f4b8..32ab96ecf1 100644
--- a/lib/ic/c_src/oe_ei_decode_wstring.c
+++ b/lib/ic/c_src/oe_ei_decode_wstring.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_atom.c b/lib/ic/c_src/oe_ei_encode_atom.c
index c643cf4fee..09126e841c 100644
--- a/lib/ic/c_src/oe_ei_encode_atom.c
+++ b/lib/ic/c_src/oe_ei_encode_atom.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_char.c b/lib/ic/c_src/oe_ei_encode_char.c
index a180b908af..96b8d04170 100644
--- a/lib/ic/c_src/oe_ei_encode_char.c
+++ b/lib/ic/c_src/oe_ei_encode_char.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_double.c b/lib/ic/c_src/oe_ei_encode_double.c
index 931b91ab90..c8db4d0771 100644
--- a/lib/ic/c_src/oe_ei_encode_double.c
+++ b/lib/ic/c_src/oe_ei_encode_double.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_list_header.c b/lib/ic/c_src/oe_ei_encode_list_header.c
index b93ad9c22a..b7a362705a 100644
--- a/lib/ic/c_src/oe_ei_encode_list_header.c
+++ b/lib/ic/c_src/oe_ei_encode_list_header.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_long.c b/lib/ic/c_src/oe_ei_encode_long.c
index 1f2e62a999..67c6cbd3db 100644
--- a/lib/ic/c_src/oe_ei_encode_long.c
+++ b/lib/ic/c_src/oe_ei_encode_long.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_longlong.c b/lib/ic/c_src/oe_ei_encode_longlong.c
index 79b4eef6a8..f741e1872a 100644
--- a/lib/ic/c_src/oe_ei_encode_longlong.c
+++ b/lib/ic/c_src/oe_ei_encode_longlong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_pid.c b/lib/ic/c_src/oe_ei_encode_pid.c
index 609f441cf8..d46d658fcb 100644
--- a/lib/ic/c_src/oe_ei_encode_pid.c
+++ b/lib/ic/c_src/oe_ei_encode_pid.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_port.c b/lib/ic/c_src/oe_ei_encode_port.c
index 4be1523df1..8de53fff1c 100644
--- a/lib/ic/c_src/oe_ei_encode_port.c
+++ b/lib/ic/c_src/oe_ei_encode_port.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_ref.c b/lib/ic/c_src/oe_ei_encode_ref.c
index 71dc5e5a70..c28b507af7 100644
--- a/lib/ic/c_src/oe_ei_encode_ref.c
+++ b/lib/ic/c_src/oe_ei_encode_ref.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_string.c b/lib/ic/c_src/oe_ei_encode_string.c
index a52a2e639d..17e1a975a6 100644
--- a/lib/ic/c_src/oe_ei_encode_string.c
+++ b/lib/ic/c_src/oe_ei_encode_string.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_term.c b/lib/ic/c_src/oe_ei_encode_term.c
index b1f1375638..f4946ae875 100644
--- a/lib/ic/c_src/oe_ei_encode_term.c
+++ b/lib/ic/c_src/oe_ei_encode_term.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_tuple_header.c b/lib/ic/c_src/oe_ei_encode_tuple_header.c
index c2d92a79fb..8ef6111f58 100644
--- a/lib/ic/c_src/oe_ei_encode_tuple_header.c
+++ b/lib/ic/c_src/oe_ei_encode_tuple_header.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_ulong.c b/lib/ic/c_src/oe_ei_encode_ulong.c
index d1a9cf1aa1..eb47f96d0b 100644
--- a/lib/ic/c_src/oe_ei_encode_ulong.c
+++ b/lib/ic/c_src/oe_ei_encode_ulong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_ulonglong.c b/lib/ic/c_src/oe_ei_encode_ulonglong.c
index 1260053116..d552d64b31 100644
--- a/lib/ic/c_src/oe_ei_encode_ulonglong.c
+++ b/lib/ic/c_src/oe_ei_encode_ulonglong.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_version.c b/lib/ic/c_src/oe_ei_encode_version.c
index 2448b32916..4d07777c67 100644
--- a/lib/ic/c_src/oe_ei_encode_version.c
+++ b/lib/ic/c_src/oe_ei_encode_version.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_wchar.c b/lib/ic/c_src/oe_ei_encode_wchar.c
index 6b9505aab0..3cc46bc1aa 100644
--- a/lib/ic/c_src/oe_ei_encode_wchar.c
+++ b/lib/ic/c_src/oe_ei_encode_wchar.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/c_src/oe_ei_encode_wstring.c b/lib/ic/c_src/oe_ei_encode_wstring.c
index 6f26c53623..4bf8fe7121 100644
--- a/lib/ic/c_src/oe_ei_encode_wstring.c
+++ b/lib/ic/c_src/oe_ei_encode_wstring.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/doc/src/CORBA_Environment_alloc.xml b/lib/ic/doc/src/CORBA_Environment_alloc.xml
index ee76739a10..b4778d5ae2 100644
--- a/lib/ic/doc/src/CORBA_Environment_alloc.xml
+++ b/lib/ic/doc/src/CORBA_Environment_alloc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile
index 3561cb620f..30b59ae3db 100644
--- a/lib/ic/doc/src/Makefile
+++ b/lib/ic/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/ic/doc/src/book.xml b/lib/ic/doc/src/book.xml
index 066c1d8150..7508368b42 100644
--- a/lib/ic/doc/src/book.xml
+++ b/lib/ic/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/c-part.xml b/lib/ic/doc/src/c-part.xml
index 967f17858b..230ba5faa8 100644
--- a/lib/ic/doc/src/c-part.xml
+++ b/lib/ic/doc/src/c-part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_basic_idl.xml b/lib/ic/doc/src/ch_basic_idl.xml
index 986052bf16..433cc40224 100644
--- a/lib/ic/doc/src/ch_basic_idl.xml
+++ b/lib/ic/doc/src/ch_basic_idl.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_c_client.xml b/lib/ic/doc/src/ch_c_client.xml
index bbdf502b32..d6282d614c 100644
--- a/lib/ic/doc/src/ch_c_client.xml
+++ b/lib/ic/doc/src/ch_c_client.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_c_corba_env.xml b/lib/ic/doc/src/ch_c_corba_env.xml
index 69ce0e5e0e..3efe0645ab 100644
--- a/lib/ic/doc/src/ch_c_corba_env.xml
+++ b/lib/ic/doc/src/ch_c_corba_env.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_c_mapping.xml b/lib/ic/doc/src/ch_c_mapping.xml
index 59ab4d9817..bc18e62dfc 100644
--- a/lib/ic/doc/src/ch_c_mapping.xml
+++ b/lib/ic/doc/src/ch_c_mapping.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_c_server.xml b/lib/ic/doc/src/ch_c_server.xml
index 8c64b87dcc..f58db0c071 100644
--- a/lib/ic/doc/src/ch_c_server.xml
+++ b/lib/ic/doc/src/ch_c_server.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_erl_genserv.xml b/lib/ic/doc/src/ch_erl_genserv.xml
index 34de3d64dd..228636bcd0 100644
--- a/lib/ic/doc/src/ch_erl_genserv.xml
+++ b/lib/ic/doc/src/ch_erl_genserv.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_erl_plain.xml b/lib/ic/doc/src/ch_erl_plain.xml
index 0744cb99d1..4b36fde143 100644
--- a/lib/ic/doc/src/ch_erl_plain.xml
+++ b/lib/ic/doc/src/ch_erl_plain.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_ic_protocol.xml b/lib/ic/doc/src/ch_ic_protocol.xml
index 465e397880..e483cec298 100644
--- a/lib/ic/doc/src/ch_ic_protocol.xml
+++ b/lib/ic/doc/src/ch_ic_protocol.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_introduction.xml b/lib/ic/doc/src/ch_introduction.xml
index f2ed61c4ed..595758d25f 100644
--- a/lib/ic/doc/src/ch_introduction.xml
+++ b/lib/ic/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ch_java.xml b/lib/ic/doc/src/ch_java.xml
index 4ee61ddf19..a1e9f7a968 100644
--- a/lib/ic/doc/src/ch_java.xml
+++ b/lib/ic/doc/src/ch_java.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/erl-part.xml b/lib/ic/doc/src/erl-part.xml
index 470f936ae4..f7a6ca68a3 100644
--- a/lib/ic/doc/src/erl-part.xml
+++ b/lib/ic/doc/src/erl-part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ic.xml b/lib/ic/doc/src/ic.xml
index b11206257f..704a70595c 100644
--- a/lib/ic/doc/src/ic.xml
+++ b/lib/ic/doc/src/ic.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ic_c_protocol.xml b/lib/ic/doc/src/ic_c_protocol.xml
index 460fcdec0d..6107767fd4 100644
--- a/lib/ic/doc/src/ic_c_protocol.xml
+++ b/lib/ic/doc/src/ic_c_protocol.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ic_clib.xml b/lib/ic/doc/src/ic_clib.xml
index 8ac783e5b2..2fbe766c9f 100644
--- a/lib/ic/doc/src/ic_clib.xml
+++ b/lib/ic/doc/src/ic_clib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/java-part.xml b/lib/ic/doc/src/java-part.xml
index 69a8e4b55b..b67b136ffd 100644
--- a/lib/ic/doc/src/java-part.xml
+++ b/lib/ic/doc/src/java-part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index bacac09f11..367f6397fc 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,7 +31,23 @@
<file>notes.xml</file>
</header>
- <section><title>IC 4.3.6</title>
+ <section><title>IC 4.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>IC 4.3.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ic/doc/src/part.xml b/lib/ic/doc/src/part.xml
index 891fc8a7e2..90673fd2b0 100644
--- a/lib/ic/doc/src/part.xml
+++ b/lib/ic/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/part_notes.xml b/lib/ic/doc/src/part_notes.xml
index e8ddbd3879..881740f62c 100644
--- a/lib/ic/doc/src/part_notes.xml
+++ b/lib/ic/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/doc/src/ref_man.xml b/lib/ic/doc/src/ref_man.xml
index a43750d495..a0fbd70e24 100644
--- a/lib/ic/doc/src/ref_man.xml
+++ b/lib/ic/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ic/examples/all-against-all/Makefile b/lib/ic/examples/all-against-all/Makefile
index a71099ef72..8ce182c3e3 100644
--- a/lib/ic/examples/all-against-all/Makefile
+++ b/lib/ic/examples/all-against-all/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/examples/all-against-all/Makefile.win32 b/lib/ic/examples/all-against-all/Makefile.win32
index 0085a85aad..6d79c8a094 100644
--- a/lib/ic/examples/all-against-all/Makefile.win32
+++ b/lib/ic/examples/all-against-all/Makefile.win32
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/examples/all-against-all/callbacks.c b/lib/ic/examples/all-against-all/callbacks.c
index f8642f4d2e..9ebba3422f 100644
--- a/lib/ic/examples/all-against-all/callbacks.c
+++ b/lib/ic/examples/all-against-all/callbacks.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/all-against-all/client.c b/lib/ic/examples/all-against-all/client.c
index a638ac6b86..492651af99 100644
--- a/lib/ic/examples/all-against-all/client.c
+++ b/lib/ic/examples/all-against-all/client.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/all-against-all/client.erl b/lib/ic/examples/all-against-all/client.erl
index 921c2c91ea..656a84d56d 100644
--- a/lib/ic/examples/all-against-all/client.erl
+++ b/lib/ic/examples/all-against-all/client.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/all-against-all/client.java b/lib/ic/examples/all-against-all/client.java
index 4dc88cffbb..f11b0388dc 100644
--- a/lib/ic/examples/all-against-all/client.java
+++ b/lib/ic/examples/all-against-all/client.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/all-against-all/random.idl b/lib/ic/examples/all-against-all/random.idl
index b44f7379f6..3402dfee2c 100644
--- a/lib/ic/examples/all-against-all/random.idl
+++ b/lib/ic/examples/all-against-all/random.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/all-against-all/rmod_random_impl.erl b/lib/ic/examples/all-against-all/rmod_random_impl.erl
index 8113cfb768..b0171715b9 100644
--- a/lib/ic/examples/all-against-all/rmod_random_impl.erl
+++ b/lib/ic/examples/all-against-all/rmod_random_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/all-against-all/server.c b/lib/ic/examples/all-against-all/server.c
index be4953e9b9..6e74d32ca9 100644
--- a/lib/ic/examples/all-against-all/server.c
+++ b/lib/ic/examples/all-against-all/server.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/all-against-all/server.erl b/lib/ic/examples/all-against-all/server.erl
index 24ace2e598..c086b53df4 100644
--- a/lib/ic/examples/all-against-all/server.erl
+++ b/lib/ic/examples/all-against-all/server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/all-against-all/server.java b/lib/ic/examples/all-against-all/server.java
index 6b5fe8fcfd..2b5355fff7 100644
--- a/lib/ic/examples/all-against-all/server.java
+++ b/lib/ic/examples/all-against-all/server.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/all-against-all/serverImpl.java b/lib/ic/examples/all-against-all/serverImpl.java
index d5fb66e96b..f5f345e93e 100644
--- a/lib/ic/examples/all-against-all/serverImpl.java
+++ b/lib/ic/examples/all-against-all/serverImpl.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/c-client/Makefile b/lib/ic/examples/c-client/Makefile
index 7c57e4f7ed..e31a36e6d2 100644
--- a/lib/ic/examples/c-client/Makefile
+++ b/lib/ic/examples/c-client/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/examples/c-client/client.c b/lib/ic/examples/c-client/client.c
index 53dbbf9192..d8502a638a 100644
--- a/lib/ic/examples/c-client/client.c
+++ b/lib/ic/examples/c-client/client.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/c-client/random.idl b/lib/ic/examples/c-client/random.idl
index cfe38e32d8..8f54058e2b 100644
--- a/lib/ic/examples/c-client/random.idl
+++ b/lib/ic/examples/c-client/random.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/c-client/rmod_random_impl.erl b/lib/ic/examples/c-client/rmod_random_impl.erl
index 863e3e8c24..fb97fd0007 100644
--- a/lib/ic/examples/c-client/rmod_random_impl.erl
+++ b/lib/ic/examples/c-client/rmod_random_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/c-client/test.erl b/lib/ic/examples/c-client/test.erl
index 0a05ce2944..2eda04234e 100644
--- a/lib/ic/examples/c-client/test.erl
+++ b/lib/ic/examples/c-client/test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/c-server/Makefile b/lib/ic/examples/c-server/Makefile
index caf4306932..205ede2d0c 100644
--- a/lib/ic/examples/c-server/Makefile
+++ b/lib/ic/examples/c-server/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/examples/c-server/callbacks.c b/lib/ic/examples/c-server/callbacks.c
index d50d26ced1..630456b214 100644
--- a/lib/ic/examples/c-server/callbacks.c
+++ b/lib/ic/examples/c-server/callbacks.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/c-server/client.c b/lib/ic/examples/c-server/client.c
index d683d586d8..a729e2beb5 100644
--- a/lib/ic/examples/c-server/client.c
+++ b/lib/ic/examples/c-server/client.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/c-server/client.erl b/lib/ic/examples/c-server/client.erl
index e225fc5789..7ff2c6de52 100644
--- a/lib/ic/examples/c-server/client.erl
+++ b/lib/ic/examples/c-server/client.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/c-server/random.idl b/lib/ic/examples/c-server/random.idl
index b2c21bdbfd..7ce302a2e7 100644
--- a/lib/ic/examples/c-server/random.idl
+++ b/lib/ic/examples/c-server/random.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/c-server/server.c b/lib/ic/examples/c-server/server.c
index 7e3c620040..b0a534fcbf 100644
--- a/lib/ic/examples/c-server/server.c
+++ b/lib/ic/examples/c-server/server.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/erl-genserv/random.idl b/lib/ic/examples/erl-genserv/random.idl
index 4527988b48..969b24b749 100644
--- a/lib/ic/examples/erl-genserv/random.idl
+++ b/lib/ic/examples/erl-genserv/random.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/erl-genserv/rmod_random_impl.erl b/lib/ic/examples/erl-genserv/rmod_random_impl.erl
index 70f5887f1c..83c1dad61f 100644
--- a/lib/ic/examples/erl-genserv/rmod_random_impl.erl
+++ b/lib/ic/examples/erl-genserv/rmod_random_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/erl-plain/random.idl b/lib/ic/examples/erl-plain/random.idl
index f7762236ca..606d91f6c5 100644
--- a/lib/ic/examples/erl-plain/random.idl
+++ b/lib/ic/examples/erl-plain/random.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/erl-plain/rmod_random_impl.erl b/lib/ic/examples/erl-plain/rmod_random_impl.erl
index 7e7b2f0821..ebed98c327 100644
--- a/lib/ic/examples/erl-plain/rmod_random_impl.erl
+++ b/lib/ic/examples/erl-plain/rmod_random_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/java-client-server/client.java b/lib/ic/examples/java-client-server/client.java
index 4dc88cffbb..f11b0388dc 100644
--- a/lib/ic/examples/java-client-server/client.java
+++ b/lib/ic/examples/java-client-server/client.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/java-client-server/random.idl b/lib/ic/examples/java-client-server/random.idl
index b2c21bdbfd..7ce302a2e7 100644
--- a/lib/ic/examples/java-client-server/random.idl
+++ b/lib/ic/examples/java-client-server/random.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/java-client-server/server.java b/lib/ic/examples/java-client-server/server.java
index 6b5fe8fcfd..2b5355fff7 100644
--- a/lib/ic/examples/java-client-server/server.java
+++ b/lib/ic/examples/java-client-server/server.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/java-client-server/serverImpl.java b/lib/ic/examples/java-client-server/serverImpl.java
index d5fb66e96b..f5f345e93e 100644
--- a/lib/ic/examples/java-client-server/serverImpl.java
+++ b/lib/ic/examples/java-client-server/serverImpl.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/examples/pre_post_condition/Makefile b/lib/ic/examples/pre_post_condition/Makefile
index 53e647e793..e300c933c3 100644
--- a/lib/ic/examples/pre_post_condition/Makefile
+++ b/lib/ic/examples/pre_post_condition/Makefile
@@ -3,30 +3,32 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
#
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/pre_post_condition/ReadMe.txt b/lib/ic/examples/pre_post_condition/ReadMe.txt
index 9db54f438d..2fb3f0a04f 100644
--- a/lib/ic/examples/pre_post_condition/ReadMe.txt
+++ b/lib/ic/examples/pre_post_condition/ReadMe.txt
@@ -1,17 +1,18 @@
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson Utvecklings AB.
- Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
- AB. All Rights Reserved.''
+ ``Licensed under the Apache License, Version 2.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.
+
+ 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$
diff --git a/lib/ic/examples/pre_post_condition/ex.idl b/lib/ic/examples/pre_post_condition/ex.idl
index e632448cc5..29298c8efb 100644
--- a/lib/ic/examples/pre_post_condition/ex.idl
+++ b/lib/ic/examples/pre_post_condition/ex.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/examples/pre_post_condition/m_i_impl.erl b/lib/ic/examples/pre_post_condition/m_i_impl.erl
index d43ee0ac94..71ddb5fb41 100644
--- a/lib/ic/examples/pre_post_condition/m_i_impl.erl
+++ b/lib/ic/examples/pre_post_condition/m_i_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/examples/pre_post_condition/tracer.erl b/lib/ic/examples/pre_post_condition/tracer.erl
index 4cba7ba9bb..f51c9de28b 100644
--- a/lib/ic/examples/pre_post_condition/tracer.erl
+++ b/lib/ic/examples/pre_post_condition/tracer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/include/erlang.idl b/lib/ic/include/erlang.idl
index 78acc7c5de..87d1247b87 100644
--- a/lib/ic/include/erlang.idl
+++ b/lib/ic/include/erlang.idl
@@ -1,13 +1,14 @@
-// ``The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved via the world wide web at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// ``Licensed under the Apache License, Version 2.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.
//
// The Initial Developer of the Original Code is Ericsson Utvecklings AB.
// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/ic/include/ic.h b/lib/ic/include/ic.h
index b3b8a2fd47..8344f51226 100644
--- a/lib/ic/include/ic.h
+++ b/lib/ic/include/ic.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/Makefile b/lib/ic/java_src/Makefile
index e6a4cd7e4d..6f965a5533 100644
--- a/lib/ic/java_src/Makefile
+++ b/lib/ic/java_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Any.java b/lib/ic/java_src/com/ericsson/otp/ic/Any.java
index 003ad5dd93..b0e717bc59 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Any.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Any.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/AnyHelper.java b/lib/ic/java_src/com/ericsson/otp/ic/AnyHelper.java
index d80d299db8..abcf9ef204 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/AnyHelper.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/AnyHelper.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/AnyHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/AnyHolder.java
index fa28bd0e5d..03c48061af 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/AnyHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/AnyHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/BooleanHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/BooleanHolder.java
index 5e91ae81af..b6ee1418dc 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/BooleanHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/BooleanHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/ByteHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/ByteHolder.java
index cd70573ab4..cc2f25579a 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/ByteHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/ByteHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/CharHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/CharHolder.java
index 6005269a38..6d49e7fbbb 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/CharHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/CharHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/DoubleHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/DoubleHolder.java
index d0da72cc2c..bf52fb4d9c 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/DoubleHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/DoubleHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Environment.java b/lib/ic/java_src/com/ericsson/otp/ic/Environment.java
index 4b321fbce7..9393d61e40 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Environment.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Environment.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/FloatHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/FloatHolder.java
index 4904fd5fc1..6ee2a25305 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/FloatHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/FloatHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Holder.java b/lib/ic/java_src/com/ericsson/otp/ic/Holder.java
index a00efcef68..74515c262d 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Holder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Holder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/IntHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/IntHolder.java
index 1037af4f08..c47f0ae01d 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/IntHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/IntHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/LongHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/LongHolder.java
index 8fa4430018..8a4481be98 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/LongHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/LongHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Makefile b/lib/ic/java_src/com/ericsson/otp/ic/Makefile
index 273614e8d9..d9100cf267 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Makefile
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Pid.java b/lib/ic/java_src/com/ericsson/otp/ic/Pid.java
index 8d0608bf58..f2c8dafa0f 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Pid.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Pid.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/PidHelper.java b/lib/ic/java_src/com/ericsson/otp/ic/PidHelper.java
index a51ff2fe80..1d0a108233 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/PidHelper.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/PidHelper.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/PidHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/PidHolder.java
index 9e42385dec..afd42c8b91 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/PidHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/PidHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Port.java b/lib/ic/java_src/com/ericsson/otp/ic/Port.java
index e830365d5c..5c36aee257 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Port.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Port.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/PortHelper.java b/lib/ic/java_src/com/ericsson/otp/ic/PortHelper.java
index 26c79713e0..22dde64530 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/PortHelper.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/PortHelper.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/PortHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/PortHolder.java
index 80744f223f..0a0a7eadad 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/PortHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/PortHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Ref.java b/lib/ic/java_src/com/ericsson/otp/ic/Ref.java
index 0a3876989e..ff01bd7162 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Ref.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Ref.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/RefHelper.java b/lib/ic/java_src/com/ericsson/otp/ic/RefHelper.java
index a58dec7905..a1b19b5fcb 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/RefHelper.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/RefHelper.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/RefHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/RefHolder.java
index 2dc3f4b42a..f853076339 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/RefHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/RefHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/ShortHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/ShortHolder.java
index 81fd7656b8..cc1f09be89 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/ShortHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/ShortHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/StringHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/StringHolder.java
index 09b42dc270..5c6ccbab5b 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/StringHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/StringHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/TCKind.java b/lib/ic/java_src/com/ericsson/otp/ic/TCKind.java
index 210f7f6216..a6a3abace9 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/TCKind.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/TCKind.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Term.java b/lib/ic/java_src/com/ericsson/otp/ic/Term.java
index 510e3b6644..cb0c6ea78a 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Term.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Term.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java b/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java
index 2942480283..0739d41877 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/TermHolder.java b/lib/ic/java_src/com/ericsson/otp/ic/TermHolder.java
index 9c92de9523..414447bfa2 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/TermHolder.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/TermHolder.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java b/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java
index 734872386b..b8508562b8 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/src/Makefile b/lib/ic/src/Makefile
index e8769d2335..a6da81a03b 100644
--- a/lib/ic/src/Makefile
+++ b/lib/ic/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/src/ic.erl b/lib/ic/src/ic.erl
index 4f3e8d180c..6e64781785 100644
--- a/lib/ic/src/ic.erl
+++ b/lib/ic/src/ic.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic.hrl b/lib/ic/src/ic.hrl
index 974e6088f4..c38b7395b0 100644
--- a/lib/ic/src/ic.hrl
+++ b/lib/ic/src/ic.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_array_java.erl b/lib/ic/src/ic_array_java.erl
index e21d646bf5..211815b171 100644
--- a/lib/ic/src/ic_array_java.erl
+++ b/lib/ic/src/ic_array_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_attribute_java.erl b/lib/ic/src/ic_attribute_java.erl
index 6352dcf608..6663c62212 100644
--- a/lib/ic/src/ic_attribute_java.erl
+++ b/lib/ic/src/ic_attribute_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_cbe.erl b/lib/ic/src/ic_cbe.erl
index 1000e0d962..63fffe49ee 100644
--- a/lib/ic/src/ic_cbe.erl
+++ b/lib/ic/src/ic_cbe.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_cclient.erl b/lib/ic/src/ic_cclient.erl
index ebe7e0c207..919c8e6571 100644
--- a/lib/ic/src/ic_cclient.erl
+++ b/lib/ic/src/ic_cclient.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_code.erl b/lib/ic/src/ic_code.erl
index 6802b9ca65..76b06396e5 100644
--- a/lib/ic/src/ic_code.erl
+++ b/lib/ic/src/ic_code.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_codegen.erl b/lib/ic/src/ic_codegen.erl
index 82431b79a2..993391f638 100644
--- a/lib/ic/src/ic_codegen.erl
+++ b/lib/ic/src/ic_codegen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_constant_java.erl b/lib/ic/src/ic_constant_java.erl
index 0a3172363f..0bfd708ba5 100644
--- a/lib/ic/src/ic_constant_java.erl
+++ b/lib/ic/src/ic_constant_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_cserver.erl b/lib/ic/src/ic_cserver.erl
index 52d98c5795..4aabf2cd92 100644
--- a/lib/ic/src/ic_cserver.erl
+++ b/lib/ic/src/ic_cserver.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_debug.hrl b/lib/ic/src/ic_debug.hrl
index c0490b4c13..72524c573d 100644
--- a/lib/ic/src/ic_debug.hrl
+++ b/lib/ic/src/ic_debug.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_enum_java.erl b/lib/ic/src/ic_enum_java.erl
index 5978c3468e..22cd006e96 100644
--- a/lib/ic/src/ic_enum_java.erl
+++ b/lib/ic/src/ic_enum_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_erl_template.erl b/lib/ic/src/ic_erl_template.erl
index f5983a53bd..7a874e312e 100644
--- a/lib/ic/src/ic_erl_template.erl
+++ b/lib/ic/src/ic_erl_template.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_erlbe.erl b/lib/ic/src/ic_erlbe.erl
index 75c87929db..2b618b63cf 100644
--- a/lib/ic/src/ic_erlbe.erl
+++ b/lib/ic/src/ic_erlbe.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_error.erl b/lib/ic/src/ic_error.erl
index f41e78a8be..c781400a80 100644
--- a/lib/ic/src/ic_error.erl
+++ b/lib/ic/src/ic_error.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_fetch.erl b/lib/ic/src/ic_fetch.erl
index c1b140ef11..208037aae9 100644
--- a/lib/ic/src/ic_fetch.erl
+++ b/lib/ic/src/ic_fetch.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_file.erl b/lib/ic/src/ic_file.erl
index 6a99d6cfde..d8f21abf5c 100644
--- a/lib/ic/src/ic_file.erl
+++ b/lib/ic/src/ic_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_forms.erl b/lib/ic/src/ic_forms.erl
index fc46a2ed40..10f9b8cea3 100644
--- a/lib/ic/src/ic_forms.erl
+++ b/lib/ic/src/ic_forms.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_genobj.erl b/lib/ic/src/ic_genobj.erl
index afb00eeb19..250b883f7b 100644
--- a/lib/ic/src/ic_genobj.erl
+++ b/lib/ic/src/ic_genobj.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_java_type.erl b/lib/ic/src/ic_java_type.erl
index b8979b6dbe..2ea71817e5 100644
--- a/lib/ic/src/ic_java_type.erl
+++ b/lib/ic/src/ic_java_type.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_jbe.erl b/lib/ic/src/ic_jbe.erl
index 81798d0429..8227f5559d 100644
--- a/lib/ic/src/ic_jbe.erl
+++ b/lib/ic/src/ic_jbe.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_noc.erl b/lib/ic/src/ic_noc.erl
index fcb413ba2e..e53c4a48ff 100644
--- a/lib/ic/src/ic_noc.erl
+++ b/lib/ic/src/ic_noc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_options.erl b/lib/ic/src/ic_options.erl
index 8d17fc1753..2f7e9e7ab2 100644
--- a/lib/ic/src/ic_options.erl
+++ b/lib/ic/src/ic_options.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_plainbe.erl b/lib/ic/src/ic_plainbe.erl
index 7b3e3dc859..dc993224ed 100644
--- a/lib/ic/src/ic_plainbe.erl
+++ b/lib/ic/src/ic_plainbe.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_pp.erl b/lib/ic/src/ic_pp.erl
index e54304ebaa..8e6b5f3810 100644
--- a/lib/ic/src/ic_pp.erl
+++ b/lib/ic/src/ic_pp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_pragma.erl b/lib/ic/src/ic_pragma.erl
index beaa2852ab..01cf47265c 100644
--- a/lib/ic/src/ic_pragma.erl
+++ b/lib/ic/src/ic_pragma.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_sequence_java.erl b/lib/ic/src/ic_sequence_java.erl
index b57652fb82..537992c3e2 100644
--- a/lib/ic/src/ic_sequence_java.erl
+++ b/lib/ic/src/ic_sequence_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_struct_java.erl b/lib/ic/src/ic_struct_java.erl
index e577fd64a3..4efc976d62 100644
--- a/lib/ic/src/ic_struct_java.erl
+++ b/lib/ic/src/ic_struct_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_symtab.erl b/lib/ic/src/ic_symtab.erl
index d710154a5d..098932f9cd 100644
--- a/lib/ic/src/ic_symtab.erl
+++ b/lib/ic/src/ic_symtab.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_union_java.erl b/lib/ic/src/ic_union_java.erl
index 4be93f3c1f..168c2ffdae 100644
--- a/lib/ic/src/ic_union_java.erl
+++ b/lib/ic/src/ic_union_java.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ic_util.erl b/lib/ic/src/ic_util.erl
index 1a6acb286a..e44ff3d4dd 100644
--- a/lib/ic/src/ic_util.erl
+++ b/lib/ic/src/ic_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icenum.erl b/lib/ic/src/icenum.erl
index 0af200e229..0ed3e0dfa7 100644
--- a/lib/ic/src/icenum.erl
+++ b/lib/ic/src/icenum.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/iceval.erl b/lib/ic/src/iceval.erl
index 81093dcd5b..3921d66559 100644
--- a/lib/ic/src/iceval.erl
+++ b/lib/ic/src/iceval.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icforms.hrl b/lib/ic/src/icforms.hrl
index 1b394a11b4..afa74b21ce 100644
--- a/lib/ic/src/icforms.hrl
+++ b/lib/ic/src/icforms.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icparse.yrl b/lib/ic/src/icparse.yrl
index 420067fa09..fcea0383ef 100644
--- a/lib/ic/src/icparse.yrl
+++ b/lib/ic/src/icparse.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icpreproc.erl b/lib/ic/src/icpreproc.erl
index 0ed7813ebd..1f9b5d89f1 100644
--- a/lib/ic/src/icpreproc.erl
+++ b/lib/ic/src/icpreproc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icscan.erl b/lib/ic/src/icscan.erl
index 0960ba5d70..8df00432f3 100644
--- a/lib/ic/src/icscan.erl
+++ b/lib/ic/src/icscan.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icstruct.erl b/lib/ic/src/icstruct.erl
index 6058b3c455..7828b8d8d7 100644
--- a/lib/ic/src/icstruct.erl
+++ b/lib/ic/src/icstruct.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ictk.erl b/lib/ic/src/ictk.erl
index 63a7705699..a6e543ad7a 100644
--- a/lib/ic/src/ictk.erl
+++ b/lib/ic/src/ictk.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/ictype.erl b/lib/ic/src/ictype.erl
index 9e20801464..a00f50dbad 100644
--- a/lib/ic/src/ictype.erl
+++ b/lib/ic/src/ictype.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icunion.erl b/lib/ic/src/icunion.erl
index 38a2d14913..d4b7eb7134 100644
--- a/lib/ic/src/icunion.erl
+++ b/lib/ic/src/icunion.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/src/icyeccpre.hrl b/lib/ic/src/icyeccpre.hrl
index 71b02b784b..2d793dd724 100644
--- a/lib/ic/src/icyeccpre.hrl
+++ b/lib/ic/src/icyeccpre.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/Makefile b/lib/ic/test/Makefile
index 63af6ed9f1..576ffc4eff 100644
--- a/lib/ic/test/Makefile
+++ b/lib/ic/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/c_client_erl_server_SUITE.erl b/lib/ic/test/c_client_erl_server_SUITE.erl
index 9f43d28f4d..90e5808c0a 100644
--- a/lib/ic/test/c_client_erl_server_SUITE.erl
+++ b/lib/ic/test/c_client_erl_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src
index 8073e3c97d..d662c50f90 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
index f910592609..61274d161b 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2001-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl
index ccb8f54508..cd06c6cbb1 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2001-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl
index 8ccb00aa4d..98693e3546 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl
index 9bb29bba16..179aaba944 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_SUITE.erl
index de643ee8cc..ab08a5d082 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE.erl
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src
index bd8b2a0972..b5e892dd19 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
index 40ff898dcb..2fe44342ea 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl
index 6d229c3ac1..0d5f6c3302 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 2003-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl
index ec0757bfab..317303fb93 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl
index 1eb792cb6d..b0c1e60b06 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c
index 103066a795..5c9355f4b5 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
index 1a2d885867..caac3c0a03 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src
index 746991b17f..68c7ec5a51 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
index f270d2abb9..33459d5917 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl
index e687cec114..2b791b4b87 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 2004-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl
index 06b39b8c35..5f51d7263d 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl
index 094855c27f..eeb3766605 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c
index 9567635742..0bf0c7d304 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/erl_client_c_server_SUITE.erl b/lib/ic/test/erl_client_c_server_SUITE.erl
index 9bd9d4a46d..eccf9d1868 100644
--- a/lib/ic/test/erl_client_c_server_SUITE.erl
+++ b/lib/ic/test/erl_client_c_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src
index 997d7a4cdc..e66f6080f4 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
index 74f29f59f9..362df0e3f3 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
index 3cc71aa2e8..84eb0f43db 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl
index 963bc69017..02fcbc75ca 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2002-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl
index 79ec28a921..61f2e843db 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE.erl b/lib/ic/test/erl_client_c_server_proto_SUITE.erl
index f4a06b0f16..a252089c69 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE.erl
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src
index 1213944383..42c4fda295 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
index 8192341548..a7de4dd07a 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
index 96fac33b29..d559feed95 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-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.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl
index e90d0dd5f0..46c78c5d45 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2004-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl
index f204896aee..2c233ce52b 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c
index 88417ef498..da88d940f3 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/ic_SUITE.erl b/lib/ic/test/ic_SUITE.erl
index c30d6485ad..bca75b8349 100644
--- a/lib/ic/test/ic_SUITE.erl
+++ b/lib/ic/test/ic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/ic_SUITE_data/attr.idl b/lib/ic/test/ic_SUITE_data/attr.idl
index c74223eca6..fb3914d1cc 100644
--- a/lib/ic/test/ic_SUITE_data/attr.idl
+++ b/lib/ic/test/ic_SUITE_data/attr.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/c_err1.idl b/lib/ic/test/ic_SUITE_data/c_err1.idl
index e1bc93dae8..8332bab825 100644
--- a/lib/ic/test/ic_SUITE_data/c_err1.idl
+++ b/lib/ic/test/ic_SUITE_data/c_err1.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/c_err2.idl b/lib/ic/test/ic_SUITE_data/c_err2.idl
index 8dac241c7f..c385a2e703 100644
--- a/lib/ic/test/ic_SUITE_data/c_err2.idl
+++ b/lib/ic/test/ic_SUITE_data/c_err2.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/c_err3.idl b/lib/ic/test/ic_SUITE_data/c_err3.idl
index dde9539f6f..83946eceae 100644
--- a/lib/ic/test/ic_SUITE_data/c_err3.idl
+++ b/lib/ic/test/ic_SUITE_data/c_err3.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/c_norm.idl b/lib/ic/test/ic_SUITE_data/c_norm.idl
index 6f6ef8ff79..b340b6090a 100644
--- a/lib/ic/test/ic_SUITE_data/c_norm.idl
+++ b/lib/ic/test/ic_SUITE_data/c_norm.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/enum.idl b/lib/ic/test/ic_SUITE_data/enum.idl
index c164e4bf74..484647781a 100644
--- a/lib/ic/test/ic_SUITE_data/enum.idl
+++ b/lib/ic/test/ic_SUITE_data/enum.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/forward.idl b/lib/ic/test/ic_SUITE_data/forward.idl
index 1e16265af5..c55b00b992 100644
--- a/lib/ic/test/ic_SUITE_data/forward.idl
+++ b/lib/ic/test/ic_SUITE_data/forward.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/include.idl b/lib/ic/test/ic_SUITE_data/include.idl
index 24022bfa1e..1f5185089d 100644
--- a/lib/ic/test/ic_SUITE_data/include.idl
+++ b/lib/ic/test/ic_SUITE_data/include.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/include2.idl b/lib/ic/test/ic_SUITE_data/include2.idl
index 2f8f7fd62c..4487663ca0 100644
--- a/lib/ic/test/ic_SUITE_data/include2.idl
+++ b/lib/ic/test/ic_SUITE_data/include2.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/include3.idl b/lib/ic/test/ic_SUITE_data/include3.idl
index c5f89c6c63..5cacc4aadd 100644
--- a/lib/ic/test/ic_SUITE_data/include3.idl
+++ b/lib/ic/test/ic_SUITE_data/include3.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/inherit.idl b/lib/ic/test/ic_SUITE_data/inherit.idl
index 71b79c8748..1ce8b2b3b6 100644
--- a/lib/ic/test/ic_SUITE_data/inherit.idl
+++ b/lib/ic/test/ic_SUITE_data/inherit.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/inherit_err.idl b/lib/ic/test/ic_SUITE_data/inherit_err.idl
index 4cfc3ffbff..c3eac38d0f 100644
--- a/lib/ic/test/ic_SUITE_data/inherit_err.idl
+++ b/lib/ic/test/ic_SUITE_data/inherit_err.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/inherit_warn.idl b/lib/ic/test/ic_SUITE_data/inherit_warn.idl
index 502bfac8d4..9a8f9039e5 100644
--- a/lib/ic/test/ic_SUITE_data/inherit_warn.idl
+++ b/lib/ic/test/ic_SUITE_data/inherit_warn.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/mult_ids.idl b/lib/ic/test/ic_SUITE_data/mult_ids.idl
index 46deaa9f55..234383fcfd 100644
--- a/lib/ic/test/ic_SUITE_data/mult_ids.idl
+++ b/lib/ic/test/ic_SUITE_data/mult_ids.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/lib/ic/test/ic_SUITE_data/nasty.idl b/lib/ic/test/ic_SUITE_data/nasty.idl
index 15fd523c0f..d29674ab44 100644
--- a/lib/ic/test/ic_SUITE_data/nasty.idl
+++ b/lib/ic/test/ic_SUITE_data/nasty.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/one.idl b/lib/ic/test/ic_SUITE_data/one.idl
index 99281d6079..8b1f212989 100644
--- a/lib/ic/test/ic_SUITE_data/one.idl
+++ b/lib/ic/test/ic_SUITE_data/one.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/one_followed.idl b/lib/ic/test/ic_SUITE_data/one_followed.idl
index da8ee74e25..fe92a78760 100644
--- a/lib/ic/test/ic_SUITE_data/one_followed.idl
+++ b/lib/ic/test/ic_SUITE_data/one_followed.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/one_out.idl b/lib/ic/test/ic_SUITE_data/one_out.idl
index 65f177ff22..51d0394485 100644
--- a/lib/ic/test/ic_SUITE_data/one_out.idl
+++ b/lib/ic/test/ic_SUITE_data/one_out.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/one_raises.idl b/lib/ic/test/ic_SUITE_data/one_raises.idl
index 8290877363..df8343ac8f 100644
--- a/lib/ic/test/ic_SUITE_data/one_raises.idl
+++ b/lib/ic/test/ic_SUITE_data/one_raises.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/one_void.idl b/lib/ic/test/ic_SUITE_data/one_void.idl
index e1d51c7abb..d4f5ce6e16 100644
--- a/lib/ic/test/ic_SUITE_data/one_void.idl
+++ b/lib/ic/test/ic_SUITE_data/one_void.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/raises_reg.idl b/lib/ic/test/ic_SUITE_data/raises_reg.idl
index d4458811dc..342f20a116 100644
--- a/lib/ic/test/ic_SUITE_data/raises_reg.idl
+++ b/lib/ic/test/ic_SUITE_data/raises_reg.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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 _RAISES_REG_IDL
diff --git a/lib/ic/test/ic_SUITE_data/struct.idl b/lib/ic/test/ic_SUITE_data/struct.idl
index 337ee170e3..22b2a16aaf 100644
--- a/lib/ic/test/ic_SUITE_data/struct.idl
+++ b/lib/ic/test/ic_SUITE_data/struct.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/syntax1.idl b/lib/ic/test/ic_SUITE_data/syntax1.idl
index 83c7de7943..a805c846db 100644
--- a/lib/ic/test/ic_SUITE_data/syntax1.idl
+++ b/lib/ic/test/ic_SUITE_data/syntax1.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/syntax2.idl b/lib/ic/test/ic_SUITE_data/syntax2.idl
index 10498206c1..9da0c51a1b 100644
--- a/lib/ic/test/ic_SUITE_data/syntax2.idl
+++ b/lib/ic/test/ic_SUITE_data/syntax2.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
struct S2 {
diff --git a/lib/ic/test/ic_SUITE_data/syntax3.idl b/lib/ic/test/ic_SUITE_data/syntax3.idl
index 69ab6b9783..7911ed4ecf 100644
--- a/lib/ic/test/ic_SUITE_data/syntax3.idl
+++ b/lib/ic/test/ic_SUITE_data/syntax3.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
typdef long T1;
diff --git a/lib/ic/test/ic_SUITE_data/syntax4.idl b/lib/ic/test/ic_SUITE_data/syntax4.idl
index 077a251729..0f09847449 100644
--- a/lib/ic/test/ic_SUITE_data/syntax4.idl
+++ b/lib/ic/test/ic_SUITE_data/syntax4.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
union U1 switch (long) {
diff --git a/lib/ic/test/ic_SUITE_data/syntax5.idl b/lib/ic/test/ic_SUITE_data/syntax5.idl
index 10af9fc18c..7c9b26f7b1 100644
--- a/lib/ic/test/ic_SUITE_data/syntax5.idl
+++ b/lib/ic/test/ic_SUITE_data/syntax5.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
union U1 switch (enum E1 {kalle, sune}) {
diff --git a/lib/ic/test/ic_SUITE_data/syntax6.idl b/lib/ic/test/ic_SUITE_data/syntax6.idl
index dc15704d94..9ceac7729b 100644
--- a/lib/ic/test/ic_SUITE_data/syntax6.idl
+++ b/lib/ic/test/ic_SUITE_data/syntax6.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/type.idl b/lib/ic/test/ic_SUITE_data/type.idl
index 67e1d502bd..65322bf78d 100644
--- a/lib/ic/test/ic_SUITE_data/type.idl
+++ b/lib/ic/test/ic_SUITE_data/type.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/typeid.idl b/lib/ic/test/ic_SUITE_data/typeid.idl
index 6e99f4a50d..0878283ed1 100644
--- a/lib/ic/test/ic_SUITE_data/typeid.idl
+++ b/lib/ic/test/ic_SUITE_data/typeid.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/u_case_mult.idl b/lib/ic/test/ic_SUITE_data/u_case_mult.idl
index 3c30e144d8..37d99f0e9b 100644
--- a/lib/ic/test/ic_SUITE_data/u_case_mult.idl
+++ b/lib/ic/test/ic_SUITE_data/u_case_mult.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/u_default.idl b/lib/ic/test/ic_SUITE_data/u_default.idl
index e5d94a5e54..80a59b9bee 100644
--- a/lib/ic/test/ic_SUITE_data/u_default.idl
+++ b/lib/ic/test/ic_SUITE_data/u_default.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/u_mult.idl b/lib/ic/test/ic_SUITE_data/u_mult.idl
index b916861eec..0bc6b64f08 100644
--- a/lib/ic/test/ic_SUITE_data/u_mult.idl
+++ b/lib/ic/test/ic_SUITE_data/u_mult.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/u_norm.idl b/lib/ic/test/ic_SUITE_data/u_norm.idl
index e23796b8ca..11ab4aeca5 100644
--- a/lib/ic/test/ic_SUITE_data/u_norm.idl
+++ b/lib/ic/test/ic_SUITE_data/u_norm.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/u_type.idl b/lib/ic/test/ic_SUITE_data/u_type.idl
index 44e3326305..49a59bfd57 100644
--- a/lib/ic/test/ic_SUITE_data/u_type.idl
+++ b/lib/ic/test/ic_SUITE_data/u_type.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_SUITE_data/undef_id.idl b/lib/ic/test/ic_SUITE_data/undef_id.idl
index 01a35c4ef8..094a59637f 100644
--- a/lib/ic/test/ic_SUITE_data/undef_id.idl
+++ b/lib/ic/test/ic_SUITE_data/undef_id.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_be_SUITE.erl b/lib/ic/test/ic_be_SUITE.erl
index 5a213ebd5f..42c30fc86e 100644
--- a/lib/ic/test/ic_be_SUITE.erl
+++ b/lib/ic/test/ic_be_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/ic_be_SUITE_data/plain.idl b/lib/ic/test/ic_be_SUITE_data/plain.idl
index ee0a995807..ab55ba4987 100644
--- a/lib/ic/test/ic_be_SUITE_data/plain.idl
+++ b/lib/ic/test/ic_be_SUITE_data/plain.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_pp_SUITE.erl b/lib/ic/test/ic_pp_SUITE.erl
index 571c37c3da..ab22d532a1 100644
--- a/lib/ic/test/ic_pp_SUITE.erl
+++ b/lib/ic/test/ic_pp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/ic_pp_SUITE_data/arg.idl b/lib/ic/test/ic_pp_SUITE_data/arg.idl
index b4d266121d..f3b0c3a7d7 100644
--- a/lib/ic/test/ic_pp_SUITE_data/arg.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/arg.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define xstr (s) str(s)
diff --git a/lib/ic/test/ic_pp_SUITE_data/cascade.idl b/lib/ic/test/ic_pp_SUITE_data/cascade.idl
index 8dff1ee99f..09608f4197 100644
--- a/lib/ic/test/ic_pp_SUITE_data/cascade.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/cascade.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define BUFS 1020
diff --git a/lib/ic/test/ic_pp_SUITE_data/comment.idl b/lib/ic/test/ic_pp_SUITE_data/comment.idl
index d2ca3e7872..e2005694fe 100644
--- a/lib/ic/test/ic_pp_SUITE_data/comment.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/comment.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define T 12
diff --git a/lib/ic/test/ic_pp_SUITE_data/concat.idl b/lib/ic/test/ic_pp_SUITE_data/concat.idl
index b8527fadfc..df7c408d2e 100644
--- a/lib/ic/test/ic_pp_SUITE_data/concat.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/concat.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define sune kurt
diff --git a/lib/ic/test/ic_pp_SUITE_data/define.idl b/lib/ic/test/ic_pp_SUITE_data/define.idl
index 6aac63dd1e..a398125d72 100644
--- a/lib/ic/test/ic_pp_SUITE_data/define.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/define.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define 8
diff --git a/lib/ic/test/ic_pp_SUITE_data/if.idl b/lib/ic/test/ic_pp_SUITE_data/if.idl
index c381fa73ee..6b6b101546 100644
--- a/lib/ic/test/ic_pp_SUITE_data/if.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/if.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define kurt 12
diff --git a/lib/ic/test/ic_pp_SUITE_data/if_zero.idl b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl
index d715f9d61e..50a9e85b4b 100644
--- a/lib/ic/test/ic_pp_SUITE_data/if_zero.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#if 0
diff --git a/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl
index 463ee3c695..66e6be930f 100644
--- a/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define double(x) (2*(x))
diff --git a/lib/ic/test/ic_pp_SUITE_data/inc.idl b/lib/ic/test/ic_pp_SUITE_data/inc.idl
index 0dcd637082..4b51591835 100644
--- a/lib/ic/test/ic_pp_SUITE_data/inc.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/inc.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_pp_SUITE_data/included1.idl b/lib/ic/test/ic_pp_SUITE_data/included1.idl
index 4cd26c4543..57e8bc1b72 100644
--- a/lib/ic/test/ic_pp_SUITE_data/included1.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/included1.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2000-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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 INCLUDED1_IDL
diff --git a/lib/ic/test/ic_pp_SUITE_data/included2.idl b/lib/ic/test/ic_pp_SUITE_data/included2.idl
index 7cc44eef3e..3f5bc32198 100644
--- a/lib/ic/test/ic_pp_SUITE_data/included2.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/included2.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2000-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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 INCLUDED2_IDL
diff --git a/lib/ic/test/ic_pp_SUITE_data/includer.idl b/lib/ic/test/ic_pp_SUITE_data/includer.idl
index c6ebc234e8..3c6aab8114 100644
--- a/lib/ic/test/ic_pp_SUITE_data/includer.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/includer.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2000-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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 INCLUDER_IDL
diff --git a/lib/ic/test/ic_pp_SUITE_data/line.idl b/lib/ic/test/ic_pp_SUITE_data/line.idl
index 5bd9c9446d..679cbaa30e 100644
--- a/lib/ic/test/ic_pp_SUITE_data/line.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/line.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#line
diff --git a/lib/ic/test/ic_pp_SUITE_data/misc.idl b/lib/ic/test/ic_pp_SUITE_data/misc.idl
index 9c18610fcf..5febf4b038 100644
--- a/lib/ic/test/ic_pp_SUITE_data/misc.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/misc.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define str(s) #s
diff --git a/lib/ic/test/ic_pp_SUITE_data/nopara.idl b/lib/ic/test/ic_pp_SUITE_data/nopara.idl
index 1bb137da11..473be6a900 100644
--- a/lib/ic/test/ic_pp_SUITE_data/nopara.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/nopara.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#11a
diff --git a/lib/ic/test/ic_pp_SUITE_data/predef.idl b/lib/ic/test/ic_pp_SUITE_data/predef.idl
index d8abcb25d5..f412583181 100644
--- a/lib/ic/test/ic_pp_SUITE_data/predef.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/predef.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define b(q,w) kurt q w
diff --git a/lib/ic/test/ic_pp_SUITE_data/predef_time.idl b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl
index 05e3ba9175..74d63a5c17 100644
--- a/lib/ic/test/ic_pp_SUITE_data/predef_time.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define b(q,w) kurt q w
diff --git a/lib/ic/test/ic_pp_SUITE_data/self_ref.idl b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl
index a44666272e..c3003ce325 100644
--- a/lib/ic/test/ic_pp_SUITE_data/self_ref.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define foo (4 + foo)
diff --git a/lib/ic/test/ic_pp_SUITE_data/separate.idl b/lib/ic/test/ic_pp_SUITE_data/separate.idl
index a3faf9b986..8df955cb70 100644
--- a/lib/ic/test/ic_pp_SUITE_data/separate.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/separate.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define xstr(s) str(s)
diff --git a/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl
index 71ed329ca6..d74c9d8e62 100644
--- a/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
/* comment \
diff --git a/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl
index 3618bab1bc..0f563c2cc5 100644
--- a/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl
+++ b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
#define ceil_div( xz, yz) (xz + yz - 1) / yz
diff --git a/lib/ic/test/ic_pragma_SUITE.erl b/lib/ic/test/ic_pragma_SUITE.erl
index 6919af78b5..e0ab43e178 100644
--- a/lib/ic/test/ic_pragma_SUITE.erl
+++ b/lib/ic/test/ic_pragma_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl
index 80f0f2cdd1..6c5fbeb435 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl
index 6c22788290..efec9c4371 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
// Bad pragma IDs
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl
index 1751751295..7154af7a90 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
// Bad pragma versions
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl
index b7c9da249f..4e806180c9 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
// Bad pragma prefixs
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl
index 0c7079e3dd..fd29d8bc81 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
// Unrecognmizable pragmas
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl
index cbf053fac4..54f738e797 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl
index b7c9da249f..4e806180c9 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
// Bad pragma prefixs
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl
index 349c13b244..02f75216c6 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
diff --git a/lib/ic/test/ic_pragma_SUITE_data/uggly.idl b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl
index 8ed3ac57ec..6c6b612309 100644
--- a/lib/ic/test/ic_pragma_SUITE_data/uggly.idl
+++ b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
// Really uggly pragmas
diff --git a/lib/ic/test/ic_register_SUITE.erl b/lib/ic/test/ic_register_SUITE.erl
index c3a9464a10..e402692940 100644
--- a/lib/ic/test/ic_register_SUITE.erl
+++ b/lib/ic/test/ic_register_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m10.idl b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl
index 9c1f126b64..d673d8eba9 100644
--- a/lib/ic/test/ic_register_SUITE_data/reg_m10.idl
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m11.idl b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl
index 607d695357..14ddaa9be1 100644
--- a/lib/ic/test/ic_register_SUITE_data/reg_m11.idl
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m12.idl b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl
index 3dd9267655..7d81c18c25 100644
--- a/lib/ic/test/ic_register_SUITE_data/reg_m12.idl
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m8.idl b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl
index dc7432c05d..dc6d499cd0 100644
--- a/lib/ic/test/ic_register_SUITE_data/reg_m8.idl
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m9.idl b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl
index e937c41608..38fe06afcb 100644
--- a/lib/ic/test/ic_register_SUITE_data/reg_m9.idl
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 1998-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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%
//
diff --git a/lib/ic/test/java_client_erl_server_SUITE.erl b/lib/ic/test/java_client_erl_server_SUITE.erl
index cbcf32515e..e95b3d5026 100644
--- a/lib/ic/test/java_client_erl_server_SUITE.erl
+++ b/lib/ic/test/java_client_erl_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -280,11 +281,7 @@ classpath(Dir) ->
Dir++PS++
filename:join([code:lib_dir(ic),"priv","ic.jar"])++PS++
filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++
- case os:getenv("CLASSPATH") of
- false -> "";
- Classpath -> Classpath
- end.
-
+ os:getenv("CLASSPATH", "").
cmd(Cmd) ->
PortOpts = [{line,80},eof,exit_status,stderr_to_stdout],
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java
index 7da5a99c03..586551dca8 100644
--- a/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
index d09f45df73..7d68e6c3ef 100644
--- a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl
index b72c972d3b..57586d3735 100644
--- a/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl
@@ -4,16 +4,17 @@
//
// Copyright Ericsson AB 2003-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// Licensed under the Apache License, Version 2.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 m {
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl
index 20959b549d..299f4f0a0f 100644
--- a/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index bb273c7b57..272c306799 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1 +1 @@
-IC_VSN = 4.3.6
+IC_VSN = 4.4
diff --git a/lib/inets/Makefile b/lib/inets/Makefile
index d837a3396a..3fff719cf3 100644
--- a/lib/inets/Makefile
+++ b/lib/inets/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/doc/archive/rfc1945.html b/lib/inets/doc/archive/rfc1945.html
index cf88f53319..3cb37c1f1e 100644
--- a/lib/inets/doc/archive/rfc1945.html
+++ b/lib/inets/doc/archive/rfc1945.html
@@ -1,14 +1,15 @@
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/inets/doc/src/Makefile b/lib/inets/doc/src/Makefile
index 961bfa838d..cb71fbeb9c 100644
--- a/lib/inets/doc/src/Makefile
+++ b/lib/inets/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -51,7 +52,6 @@ XML_REF3_FILES = \
http_uri.xml\
httpc.xml\
httpd.xml \
- httpd_conf.xml \
httpd_custom_api.xml \
httpd_socket.xml \
httpd_util.xml \
diff --git a/lib/inets/doc/src/book.xml b/lib/inets/doc/src/book.xml
index eca0c319ef..80db82ee45 100644
--- a/lib/inets/doc/src/book.xml
+++ b/lib/inets/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml
index 0cd75ff645..f64bc0e18b 100644
--- a/lib/inets/doc/src/ftp.xml
+++ b/lib/inets/doc/src/ftp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,95 +30,94 @@
<file>ftp.xml</file>
</header>
<module>ftp</module>
- <modulesummary>A File Transfer Protocol client</modulesummary>
+ <modulesummary>A File Transfer Protocol client.</modulesummary>
<description>
- <p>The <c>ftp</c> module implements a client for file transfer
- according to a subset of the File Transfer Protocol (see <term
- id="RFC"></term>959). </p>
+ <p>This module implements a client for file transfer
+ according to a subset of the File Transfer Protocol (FTP), see
+ <url href="http://www.ietf.org/rfc/rfc959.txt">RFC 959</url>.</p>
- <p>Starting from inets version 4.4.1 the ftp
- client will always try to use passive ftp mode and only resort
- to active ftp mode if this fails. There is a start option
- <seealso marker="#mode">mode</seealso> where this default behavior
- may be changed. </p>
+ <p>As from <c>Inets</c> 4.4.1, the FTP
+ client always tries to use passive FTP mode and only resort
+ to active FTP mode if this fails. This default behavior can be
+ changed by start option <seealso marker="#mode">mode</seealso>.</p>
<marker id="two_start"></marker>
- <p>There are two ways to start an ftp client. One is using the
- <seealso marker="#service_start">Inets service framework</seealso>
- and the other is to start it directy as a standalone process
- using the <seealso marker="#open">open</seealso> function. </p>
+ <p>An FTP client can be started in two ways. One is using the
+ <seealso marker="#service_start">Inets service framework</seealso>,
+ the other is to start it directly as a standalone process
+ using function <seealso marker="#open">open</seealso>.</p>
- <p>For a simple example of an ftp session see
- <seealso marker="ftp_client">Inets User's Guide.</seealso></p>
+ <p>For a simple example of an FTP session, see
+ <seealso marker="ftp_client">Inets User's Guide</seealso>.</p>
<p>In addition to the ordinary functions for receiving and sending
- files (see <c>recv/2</c>, <c>recv/3</c>, <c>send/2</c> and
+ files (see <c>recv/2</c>, <c>recv/3</c>, <c>send/2</c>, and
<c>send/3</c>) there are functions for receiving remote files as
- binaries (see <c>recv_bin/2</c>) and for sending binaries to to be
+ binaries (see <c>recv_bin/2</c>) and for sending binaries to be
stored as remote files (see <c>send_bin/3</c>).</p>
- <p>There is also a set of functions for sending and receiving
- contiguous parts of a file to be stored in a remote file (for send
- see <c>send_chunk_start/2</c>, <c>send_chunk/2</c> and
- <c>send_chunk_end/1</c> and for receive see
+ <p>A set of functions is provvided for sending and receiving
+ contiguous parts of a file to be stored in a remote file. For send,
+ see <c>send_chunk_start/2</c>, <c>send_chunk/2</c>, and
+ <c>send_chunk_end/1</c>. For receive, see
<c>recv_chunk_start/2</c> and <c>recv_chunk/</c>).</p>
- <p>The particular return values of the functions below depend very
+ <p>The return values of the following functions depend
much on the implementation of the FTP server at the remote
- host. In particular the results from <c>ls</c> and <c>nlist</c>
+ host. In particular, the results from <c>ls</c> and <c>nlist</c>
varies. Often real errors are not reported as errors by <c>ls</c>,
- even if for instance a file or directory does not
+ even if, for example, a file or directory does not
exist. <c>nlist</c> is usually more strict, but some
implementations have the peculiar behaviour of responding with an
- error, if the request is a listing of the contents of directory
- which exists but is empty.</p>
+ error if the request is a listing of the contents of a directory
+ that exists but is empty.</p>
<marker id="service_start"></marker>
</description>
<section>
- <title>FTP CLIENT SERVICE START/STOP </title>
+ <title>FTP CLIENT SERVICE START/STOP</title>
<p>The FTP client can be started and stopped dynamically in runtime by
- calling the Inets application API
+ calling the <c>Inets</c> application API
<c>inets:start(ftpc, ServiceConfig)</c>,
or <c>inets:start(ftpc, ServiceConfig, How)</c>, and
<c>inets:stop(ftpc, Pid)</c>.
- See <seealso marker="inets">inets(3)</seealso> for more info. </p>
- <p>Below follows a description of
- the available configuration options.</p>
+ For details, see <seealso marker="inets">inets(3)</seealso>.</p>
+
+ <p>The available configuration options are as follows:</p>
<taglist>
<tag>{host, Host}</tag>
<item>
<marker id="host"></marker>
- <p>Host = <c>string() | ip_address()</c> </p>
+ <p>Host = <c>string() | ip_address()</c></p>
</item>
<tag>{port, Port}</tag>
<item>
<marker id="port"></marker>
- <p>Port = <c>integer() > 0</c> </p>
- <p>Default is 21.</p>
+ <p>Port = <c>integer() > 0</c></p>
+ <p>Default is <c>21</c>.</p>
</item>
<tag>{mode, Mode}</tag>
<item>
<marker id="mode"></marker>
- <p>Mode = <c>active | passive</c> </p>
- <p>Default is <c>passive</c>. </p>
+ <p>Mode = <c>active | passive</c></p>
+ <p>Default is <c>passive</c>.</p>
</item>
<tag>{verbose, Verbose}</tag>
<item>
<marker id="verbose"></marker>
<p>Verbose = <c>boolean()</c> </p>
- <p>This determines if the FTP communication should be
- verbose or not. </p>
- <p>Default is <c>false</c>. </p>
+ <p>Determines if the FTP communication is to be
+ verbose or not.</p>
+ <p>Default is <c>false</c>.</p>
</item>
<tag>{debug, Debug}</tag>
@@ -125,93 +125,90 @@
<marker id="debug"></marker>
<p>Debug = <c>trace | debug | disable</c> </p>
<p>Debugging using the dbg toolkit. </p>
- <p>Default is <c>disable</c>. </p>
+ <p>Default is <c>disable</c>.</p>
</item>
<tag>{ipfamily, IpFamily}</tag>
<item>
<marker id="ipfamily"></marker>
<p>IpFamily = <c>inet | inet6 | inet6fb4</c> </p>
- <p>With <c>inet6fb4</c> the client behaves as before
- (it tries to use IPv6 and only if that does not work, it
- uses IPv4). </p>
- <p>Default is <c>inet</c> (IPv4). </p>
+ <p>With <c>inet6fb4</c> the client behaves as before, that is,
+ tries to use IPv6, and only if that does not work it
+ uses IPv4).</p>
+ <p>Default is <c>inet</c> (IPv4).</p>
</item>
<tag>{timeout, Timeout}</tag>
<item>
<marker id="timeout"></marker>
- <p>Timeout = <c>non_neg_integer()</c> </p>
- <p>Connection timeout. </p>
- <p>Default is 60000 (milliseconds). </p>
+ <p>Timeout = <c>non_neg_integer()</c></p>
+ <p>Connection time-out.</p>
+ <p>Default is <c>60000</c> (milliseconds).</p>
</item>
<tag>{dtimeout, DTimeout}</tag>
<item>
<marker id="dtimeout"></marker>
<p>DTimeout = <c>non_neg_integer() | infinity</c> </p>
- <p>Data Connect timeout.
- The time the client will wait for the server to connect to the
- data socket. </p>
- <p>Default is infinity. </p>
+ <p>Data connect time-out.
+ The time the client waits for the server to connect to the
+ data socket.</p>
+ <p>Default is <c>infinity</c>. </p>
</item>
<tag>{progress, Progress}</tag>
<item>
<marker id="progress"></marker>
<p>Progress = <c>ignore | {CBModule, CBFunction, InitProgress}</c></p>
- <p>CBModule = <c>atom()</c>, CBFunction = <c>atom()</c> </p>
- <p>InitProgress = <c>term()</c> </p>
- <p>Default is <c>ignore</c>. </p>
+ <p><c>CBModule = atom()</c>, <c>CBFunction = atom()</c></p>
+ <p><c>InitProgress = term()</c></p>
+ <p>Default is <c>ignore</c>.</p>
</item>
</taglist>
- <p>The progress option is intended to be used by applications that
- want to create some type of progress report such as a progress bar in
- a GUI. The default value for the progress option is ignore
- e.i. the option is not used. When the progress option is
- specified the following will happen when ftp:send/[3,4] or
- ftp:recv/[3,4] are called.</p>
+ <p>Option <c>progress</c> is intended to be used by applications that
+ want to create some type of progress report, such as a progress bar in
+ a GUI. Default for the progress option is <c>ignore</c>,
+ that is, the option is not used. When the progress option is
+ specified, the following happens when <c>ftp:send/[3,4]</c> or
+ <c>ftp:recv/[3,4]</c> are called:</p>
<list type="bulleted">
<item>
- <p>Before a file is transfered the following call will
- be made to indicate the start of the file transfer and how big
+ <p>Before a file is transferred, the following call is
+ made to indicate the start of the file transfer and how large
the file is. The return value of the callback function
- should be a new value for the UserProgressTerm that will
- bu used as input next time the callback function is
+ is to be a new value for the <c>UserProgressTerm</c> that will
+ be used as input the next time the callback function is
called.</p>
- <br></br>
<p><c>
CBModule:CBFunction(InitProgress, File, {file_size, FileSize})
</c></p>
- <br></br>
</item>
<item>
- <p>Every time a chunk of bytes is transfered the
- following call will be made:</p>
- <br></br>
+ <p>Every time a chunk of bytes is transferred the
+ following call is made:</p>
<p><c>
- CBModule:CBFunction(UserProgressTerm, File, {transfer_size, TransferSize}) </c></p>
- <br></br>
+ CBModule:CBFunction(UserProgressTerm, File, {transfer_size, TransferSize})
+ </c></p>
</item>
<item>
- <p>At the end of the file the following call will be
- made to indicate the end of the transfer.</p>
- <br></br>
+ <p>At the end of the file the following call is
+ made to indicate the end of the transfer:</p>
<p><c>
- CBModule:CBFunction(UserProgressTerm, File, {transfer_size, 0}) </c></p>
- <br></br>
+ CBModule:CBFunction(UserProgressTerm, File, {transfer_size, 0})
+ </c></p>
</item>
</list>
- <p>The callback function should be defined as </p>
+ <p>The callback function is to be defined as follows:</p>
<p><c>
- CBModule:CBFunction(UserProgressTerm, File, Size) -> UserProgressTerm </c></p>
+ CBModule:CBFunction(UserProgressTerm, File, Size) -> UserProgressTerm
+ </c></p>
<p><c>
CBModule = CBFunction = atom()
@@ -226,50 +223,51 @@
</c></p>
<p><c>
- Size = {transfer_size, integer()} | {file_size, integer()} | {file_size, unknown} </c></p>
+ Size = {transfer_size, integer()} | {file_size, integer()} | {file_size, unknown}
+ </c></p>
- <p>Alas for remote files it is not possible for ftp to determine the
+ <p>For remote files, <c>ftp</c> cannot determine the
file size in a platform independent way. In this case the size
- will be <c>unknown</c> and it is left to the application to find
- out the size. </p>
+ becomes <c>unknown</c> and it is left to the application to
+ determine the size.</p>
<note>
<p>The callback is made by a middleman process, hence the
- file transfer will not be affected by the code in the progress
- callback function. If the callback should crash this will be
- detected by the ftp connection process that will print an
- info-report and then go one as if the progress option was set
- to ignore. </p>
+ file transfer is not affected by the code in the progress
+ callback function. If the callback crashes, this is
+ detected by the FTP connection process, which then prints an
+ info-report and goes on as if the progress option was set
+ to <c>ignore</c>.</p>
</note>
<p>The file transfer type is set to the default of the FTP server
- when the session is opened. This is usually ASCCI-mode.
+ when the session is opened. This is usually ASCCI mode.
</p>
- <p>The current local working directory (cf. <c>lpwd/1</c>) is set to
- the value reported by <c>file:get_cwd/1</c>. the wanted
+ <p>The current local working directory (compare <c>lpwd/1</c>) is set
+ to the value reported by <c>file:get_cwd/1</c>, the wanted
local directory.
</p>
<p>The return value <c>Pid</c> is used as a reference to the
- newly created ftp client in all other functions, and they should
- be called by the process that created the connection. The ftp
+ newly created FTP client in all other functions, and they are to
+ be called by the process that created the connection. The FTP
client process monitors the process that created it and
- will terminate if that process terminates.</p>
+ terminates if that process terminates.</p>
</section>
<section>
- <title>COMMON DATA TYPES </title>
- <p>Here follows type definitions that are used by more than one
- function in the FTP client API. </p>
- <p><c> pid() - identifier of an ftp connection.</c></p>
- <p><c> string() = list of ASCII characters.</c></p>
- <p><c> shortage_reason() = etnospc | epnospc</c></p>
- <p><c> restriction_reason() = epath | efnamena | elogin | enotbinary
- - note not all restrictions may always relevant to all functions
- </c></p>
- <p><c>common_reason() = econn | eclosed | term() - some kind of
- explanation of what went wrong.</c></p>
+ <title>DATA TYPES</title>
+ <p>The following type definitions are used by more than one
+ function in the FTP client API:</p>
+ <p><c>pid()</c> = identifier of an FTP connection</p>
+ <p><c>string()</c> = list of ASCII characters</p>
+ <p><c>shortage_reason()</c> = <c>etnospc | epnospc</c></p>
+ <p><c>restriction_reason()</c> = <c>epath | efnamena | elogin | enotbinary</c>
+ - all restrictions are not always relevant to all functions
+ </p>
+ <p><c>common_reason()</c> = <c>econn | eclosed | term()</c>
+ - some explanation of what went wrong</p>
<marker id="account"></marker>
</section>
@@ -277,15 +275,14 @@
<funcs>
<func>
<name>account(Pid, Account) -> ok | {error, Reason}</name>
- <fsummary>Specify which account to use.</fsummary>
+ <fsummary>Specifies which account to use.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Account = string()</v>
<v>Reason = eacct | common_reason()</v>
</type>
<desc>
- <p>If an account is needed for an operation set the account
- with this operation.</p>
+ <p>Sets the account for an operation, if needed.</p>
<marker id="append"></marker>
<marker id="append2"></marker>
@@ -296,7 +293,8 @@
<func>
<name>append(Pid, LocalFile) -> </name>
<name>append(Pid, LocalFile, RemoteFile) -> ok | {error, Reason}</name>
- <fsummary>Transfer file to remote server, and append it to Remotefile.</fsummary>
+ <fsummary>Transfers a file to remote server, and appends it to
+ <c>Remotefile</c>.</fsummary>
<type>
<v>Pid = pid()</v>
<v>LocalFile = RemoteFile = string()</v>
@@ -305,9 +303,9 @@
<desc>
<p>Transfers the file <c>LocalFile</c> to the remote server. If
<c>RemoteFile</c> is specified, the name of the remote file that the
- file will be appended to is set to <c>RemoteFile</c>; otherwise
- the name is set to <c>LocalFile</c> If the file does not exists the
- file will be created.</p>
+ file is appended to is set to <c>RemoteFile</c>, otherwise
+ to <c>LocalFile</c>. If the file does not exists,
+ it is created.</p>
<marker id="append_bin"></marker>
</desc>
@@ -315,17 +313,17 @@
<func>
<name>append_bin(Pid, Bin, RemoteFile) -> ok | {error, Reason}</name>
- <fsummary>Transfer a binary into a remote file.</fsummary>
+ <fsummary>Transfers a binary into a remote file.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Bin = binary()()</v>
<v>RemoteFile = string()</v>
- <v>Reason = restriction_reason()| shortage_reason() | common_reason()</v>
+ <v>Reason = restriction_reason()| shortage_reason() | common_reason()</v>
</type>
<desc>
- <p>Transfers the binary <c>Bin</c> to the remote server and append
- it to the file <c>RemoteFile</c>. If the file does not exists it
- will be created.</p>
+ <p>Transfers the binary <c>Bin</c> to the remote server and appends
+ it to the file <c>RemoteFile</c>. If the file does not exist, it
+ is created.</p>
<marker id="append_chunk"></marker>
</desc>
@@ -333,18 +331,18 @@
<func>
<name>append_chunk(Pid, Bin) -> ok | {error, Reason}</name>
- <fsummary>append a chunk to the remote file.</fsummary>
+ <fsummary>Appends a chunk to the remote file.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Bin = binary()</v>
<v>Reason = echunk | restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Transfer the chunk <c>Bin</c> to the remote server, which
- append it into the file specified in the call to
- <c>append_chunk_start/2</c>. </p>
- <p>Note that for some errors, e.g. file system full, it is
- necessary to to call <c>append_chunk_end</c> to get the
+ <p>Transfers the chunk <c>Bin</c> to the remote server, which
+ appends it to the file specified in the call to
+ <c>append_chunk_start/2</c>.</p>
+ <p>For some errors, for example, file system full, it is
+ necessary to call <c>append_chunk_end</c> to get the
proper reason.</p>
<marker id="append_chunk_start"></marker>
@@ -353,16 +351,16 @@
<func>
<name>append_chunk_start(Pid, File) -> ok | {error, Reason}</name>
- <fsummary>Start transfer of file chunks for appending to File.</fsummary>
+ <fsummary>Starts transfer of file chunks for appending to <c>File</c>.</fsummary>
<type>
<v>Pid = pid()</v>
<v>File = string()</v>
<v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Start the transfer of chunks for appending to the file
- <c>File</c> at the remote server. If the file does not exists
- it will be created.</p>
+ <p>Starts the transfer of chunks for appending to the file
+ <c>File</c> at the remote server. If the file does not exist,
+ it is created.</p>
<marker id="append_chunk_end"></marker>
</desc>
@@ -370,7 +368,7 @@
<func>
<name>append_chunk_end(Pid) -> ok | {error, Reason}</name>
- <fsummary>Stop transfer of chunks for appending.</fsummary>
+ <fsummary>Stops transfer of chunks for appending.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Reason = echunk | restriction_reason() | shortage_reason() </v>
@@ -378,7 +376,7 @@
<desc>
<p>Stops transfer of chunks for appending to the remote server.
The file at the remote server, specified in the call to
- <c>append_chunk_start/2</c> is closed by the server.</p>
+ <c>append_chunk_start/2</c>, is closed by the server.</p>
<marker id="cd"></marker>
</desc>
@@ -386,7 +384,7 @@
<func>
<name>cd(Pid, Dir) -> ok | {error, Reason}</name>
- <fsummary>Change remote working directory.</fsummary>
+ <fsummary>Changes remote working directory.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Dir = string()</v>
@@ -402,13 +400,13 @@
<func>
<name>close(Pid) -> ok</name>
- <fsummary>End the ftp session.</fsummary>
+ <fsummary>Ends the FTP session.</fsummary>
<type>
<v>Pid = pid()</v>
</type>
<desc>
- <p>Ends an ftp session, created using the
- <seealso marker="#open">open</seealso> function. </p>
+ <p>Ends an FTP session, created using function
+ <seealso marker="#open">open</seealso>.</p>
<marker id="delete"></marker>
</desc>
@@ -416,7 +414,7 @@
<func>
<name>delete(Pid, File) -> ok | {error, Reason}</name>
- <fsummary>Delete a file at the remote server..</fsummary>
+ <fsummary>Deletes a file at the remote server.</fsummary>
<type>
<v>Pid = pid()</v>
<v>File = string()</v>
@@ -431,7 +429,7 @@
<func>
<name>formaterror(Tag) -> string()</name>
- <fsummary>Return error diagnostics.</fsummary>
+ <fsummary>Returns error diagnostics.</fsummary>
<type>
<v>Tag = {error, atom()} | atom()</v>
</type>
@@ -445,14 +443,14 @@
<func>
<name>lcd(Pid, Dir) -> ok | {error, Reason}</name>
- <fsummary>Change local working directory.</fsummary>
+ <fsummary>Changes local working directory.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Dir = string()</v>
<v>Reason = restriction_reason()</v>
</type>
<desc>
- <p>Changes the working directory to <c>Dir</c> for the local client. </p>
+ <p>Changes the working directory to <c>Dir</c> for the local client.</p>
<marker id="lpwd"></marker>
</desc>
@@ -460,7 +458,7 @@
<func>
<name>lpwd(Pid) -> {ok, Dir}</name>
- <fsummary>Get local current working directory.</fsummary>
+ <fsummary>Gets local current working directory.</fsummary>
<type>
<v>Pid = pid()</v>
</type>
@@ -484,13 +482,13 @@
<v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Returns a list of files in long format. </p>
- <p><c>Pathname</c> can be a directory, a group of files or
- even a file. The <c>Pathname</c> string can contain wildcard(s). </p>
- <p><c>ls/1</c> implies the user's current remote directory. </p>
- <p>The format of <c>Listing</c> is operating system dependent
- (on UNIX it is typically produced from the output of the
- <c>ls -l</c> shell command).</p>
+ <p>Returns a list of files in long format.</p>
+ <p><c>Pathname</c> can be a directory, a group of files, or
+ a file. The <c>Pathname</c> string can contain wildcards.</p>
+ <p><c>ls/1</c> implies the current remote directory of the user.</p>
+ <p>The format of <c>Listing</c> depends on the operating system.
+ On UNIX, it is typically produced from the output of the
+ <c>ls -l</c> shell command.</p>
<marker id="mkdir"></marker>
</desc>
@@ -498,7 +496,7 @@
<func>
<name>mkdir(Pid, Dir) -> ok | {error, Reason}</name>
- <fsummary>Create remote directory.</fsummary>
+ <fsummary>Creates a remote directory.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Dir = string()</v>
@@ -524,15 +522,15 @@
<v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Returns a list of files in short format. </p>
- <p><c>Pathname</c> can be a directory, a group of files or
- even a file. The <c>Pathname</c> string can contain wildcard(s). </p>
- <p><c>nlist/1</c> implies the user's current remote directory. </p>
+ <p>Returns a list of files in short format.</p>
+ <p><c>Pathname</c> can be a directory, a group of files, or
+ a file. The <c>Pathname</c> string can contain wildcards.</p>
+ <p><c>nlist/1</c> implies the current remote directory of the user.</p>
<p>The format of <c>Listing</c> is a stream of
- file names, where each name is separated by &lt;CRLF&gt; or
- &lt;NL&gt;. Contrary to the <c>ls</c> function, the purpose of
- <c>nlist</c> is to make it possible for a program to
- automatically process file name information.</p>
+ filenames where each filename is separated by &lt;CRLF&gt; or
+ &lt;NL&gt;. Contrary to function <c>ls</c>, the purpose of
+ <c>nlist</c> is to enable a program to
+ process filename information automatically.</p>
<marker id="open"></marker>
</desc>
@@ -541,23 +539,23 @@
<func>
<name>open(Host) -> {ok, Pid} | {error, Reason}</name>
<name>open(Host, Opts) -> {ok, Pid} | {error, Reason}</name>
- <fsummary>Start an standalone ftp client.</fsummary>
+ <fsummary>Starts a standalone FTP client.</fsummary>
<type>
<v>Host = string() | ip_address()</v>
<v>Opts = options()</v>
<v>options() = [option()]</v>
<v>option() = start_option() | open_option()</v>
<v>start_option() = {verbose, verbose()} | {debug, debug()}</v>
- <v>verbose() = boolean() (defaults to false)</v>
- <v>debug() = disable | debug | trace (defaults to disable)</v>
+ <v>verbose() = boolean() (default is false)</v>
+ <v>debug() = disable | debug | trace (default is disable)</v>
<v>open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {tls, tls_options()} | {timeout, timeout()} | {dtimeout, dtimeout()} | {progress, progress()}</v>
- <v>ipfamily() = inet | inet6 | inet6fb4 (defaults to inet)</v>
- <v>port() = integer() > 0 (defaults to 21)</v>
- <v>mode() = active | passive (defaults to passive)</v>
+ <v>ipfamily() = inet | inet6 | inet6fb4 (default is inet)</v>
+ <v>port() = integer() > 0 (default is 21)</v>
+ <v>mode() = active | passive (default is passive)</v>
<v>tls_options() = [<seealso marker="ssl:ssl#type-ssloption">ssl:ssloption()</seealso>]</v>
- <v>timeout() = integer() > 0 (defaults to 60000 milliseconds)</v>
- <v>dtimeout() = integer() > 0 | infinity (defaults to infinity)</v>
- <v>pogress() = ignore | {module(), function(), initial_data()} (defaults to ignore)</v>
+ <v>timeout() = integer() > 0 (default is 60000 milliseconds)</v>
+ <v>dtimeout() = integer() > 0 | infinity (default is infinity)</v>
+ <v>pogress() = ignore | {module(), function(), initial_data()} (default is ignore)</v>
<v>module() = atom()</v>
<v>function() = atom()</v>
<v>initial_data() = term()</v>
@@ -565,16 +563,20 @@
</type>
<desc>
- <p>This function is used to start a standalone ftp client process
- (without the inets service framework) and
- open a session with the FTP server at <c>Host</c>. </p>
+ <p>Starts a standalone FTP client process
+ (without the <c>Inets</c> service framework) and
+ opens a session with the FTP server at <c>Host</c>. </p>
- <p>If the option <c>{tls, tls_options()}</c> is present, the ftp session will be transported over tls (ftps, see
-<url href="http://www.ietf.org/rfc/rfc4217.txt">RFC 4217</url>). The list <c>tls_options()</c> may be empty. The function <seealso marker="ssl:ssl#connect/3"><c>ssl:connect/3</c></seealso> is used for securing both the control connection and the data sessions.
+ <p>If option <c>{tls, tls_options()}</c> is present, the FTP session
+ is transported over <c>tls</c> (<c>ftps</c>, see
+ <url href="http://www.ietf.org/rfc/rfc4217.txt">RFC 4217</url>).
+ The list <c>tls_options()</c> can be empty. The function
+ <seealso marker="ssl:ssl#connect/3"><c>ssl:connect/3</c></seealso>
+ is used for securing both the control connection and the data sessions.
</p>
- <p>A session opened in this way, is closed using the
- <seealso marker="#close">close</seealso> function. </p>
+ <p>A session opened in this way is closed using function
+ <seealso marker="#close">close</seealso>.</p>
<marker id="pwd"></marker>
</desc>
@@ -582,22 +584,10 @@
<func>
<name>pwd(Pid) -> {ok, Dir} | {error, Reason}</name>
- <fsummary>Get remote current working directory.</fsummary>
- <type>
- <v>Pid = pid()</v>
- <v>Reason = restriction_reason() | common_reason() </v>
- </type>
- <desc>
- <p>Returns the current working directory at the remote server. </p>
- </desc>
- </func>
-
- <func>
- <name>pwd(Pid) -> {ok, Dir} | {error, Reason}</name>
- <fsummary>Get remote current working directory.</fsummary>
+ <fsummary>Gets the remote current working directory.</fsummary>
<type>
<v>Pid = pid()</v>
- <v>Reason = restriction_reason() | common_reason() </v>
+ <v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
<p>Returns the current working directory at the remote server.</p>
@@ -611,7 +601,7 @@
<func>
<name>recv(Pid, RemoteFile) -> </name>
<name>recv(Pid, RemoteFile, LocalFile) -> ok | {error, Reason}</name>
- <fsummary>Transfer file from remote server.</fsummary>
+ <fsummary>Transfers a file from remote server.</fsummary>
<type>
<v>Pid = pid()</v>
<v>RemoteFile = LocalFile = string()</v>
@@ -619,14 +609,14 @@
<v>file_write_error_reason() = see file:write/2</v>
</type>
<desc>
- <p>Transfer the file <c>RemoteFile</c> from the remote server
- to the the file system of the local client. If
+ <p>Transfers the file <c>RemoteFile</c> from the remote server
+ to the file system of the local client. If
<c>LocalFile</c> is specified, the local file will be
- <c>LocalFile</c>; otherwise it will be
+ <c>LocalFile</c>, otherwise
<c>RemoteFile</c>.</p>
- <p>If the file write fails
- (e.g. enospc), then the command is aborted and <c>{error, file_write_error_reason()}</c> is returned. The file is
- however <em>not</em> removed.</p>
+ <p>If the file write fails (for example, <c>enospc</c>), the command is
+ aborted and <c>{error, file_write_error_reason()}</c> is returned.
+ However, the file is <em>not</em> removed.</p>
<marker id="recv_bin"></marker>
</desc>
@@ -634,7 +624,7 @@
<func>
<name>recv_bin(Pid, RemoteFile) -> {ok, Bin} | {error, Reason}</name>
- <fsummary>Transfer file from remote server as a binary.</fsummary>
+ <fsummary>Transfers a file from remote server as a binary.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Bin = binary()</v>
@@ -651,14 +641,14 @@
<func>
<name>recv_chunk_start(Pid, RemoteFile) -> ok | {error, Reason}</name>
- <fsummary>Start chunk-reading of the remote file.</fsummary>
+ <fsummary>Starts chunk-reading of the remote file.</fsummary>
<type>
<v>Pid = pid()</v>
<v>RemoteFile = string()</v>
<v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Start transfer of the file <c>RemoteFile</c> from the
+ <p>Starts transfer of the file <c>RemoteFile</c> from the
remote server.</p>
<marker id="recv_chunk"></marker>
@@ -667,20 +657,20 @@
<func>
<name>recv_chunk(Pid) -> ok | {ok, Bin} | {error, Reason}</name>
- <fsummary>Receive a chunk of the remote file.</fsummary>
+ <fsummary>Receives a chunk of the remote file.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Bin = binary()</v>
<v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Receive a chunk of the remote file (<c>RemoteFile</c> of
- <c>recv_chunk_start</c>). The return values has the following
+ <p>Receives a chunk of the remote file (<c>RemoteFile</c> of
+ <c>recv_chunk_start</c>). The return values have the following
meaning:</p>
<list type="bulleted">
- <item><c>ok</c> the transfer is complete.</item>
- <item><c>{ok, Bin}</c> just another chunk of the file.</item>
- <item><c>{error, Reason}</c> transfer failed.</item>
+ <item><c>ok</c> = the transfer is complete.</item>
+ <item><c>{ok, Bin}</c> = just another chunk of the file.</item>
+ <item><c>{error, Reason}</c> = transfer failed.</item>
</list>
<marker id="rename"></marker>
@@ -689,7 +679,7 @@
<func>
<name>rename(Pid, Old, New) -> ok | {error, Reason}</name>
- <fsummary>Rename a file at the remote server..</fsummary>
+ <fsummary>Renames a file at the remote server.</fsummary>
<type>
<v>Pid = pid()</v>
<v>CurrFile = NewFile = string()</v>
@@ -704,7 +694,7 @@
<func>
<name>rmdir(Pid, Dir) -> ok | {error, Reason}</name>
- <fsummary>Remove a remote directory.</fsummary>
+ <fsummary>Removes a remote directory.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Dir = string()</v>
@@ -722,7 +712,7 @@
<func>
<name>send(Pid, LocalFile) -></name>
<name>send(Pid, LocalFile, RemoteFile) -> ok | {error, Reason}</name>
- <fsummary>Transfer file to remote server.</fsummary>
+ <fsummary>Transfers a file to the remote server.</fsummary>
<type>
<v>Pid = pid()</v>
<v>LocalFile = RemoteFile = string()</v>
@@ -731,7 +721,7 @@
<desc>
<p>Transfers the file <c>LocalFile</c> to the remote server. If
<c>RemoteFile</c> is specified, the name of the remote file is set
- to <c>RemoteFile</c>; otherwise the name is set to <c>LocalFile</c>.</p>
+ to <c>RemoteFile</c>, otherwise to <c>LocalFile</c>.</p>
<marker id="send_bin"></marker>
</desc>
@@ -739,7 +729,7 @@
<func>
<name>send_bin(Pid, Bin, RemoteFile) -> ok | {error, Reason}</name>
- <fsummary>Transfer a binary into a remote file.</fsummary>
+ <fsummary>Transfers a binary into a remote file.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Bin = binary()()</v>
@@ -756,17 +746,17 @@
<func>
<name>send_chunk(Pid, Bin) -> ok | {error, Reason}</name>
- <fsummary>Write a chunk to the remote file.</fsummary>
+ <fsummary>Writes a chunk to the remote file.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Bin = binary()</v>
<v>Reason = echunk | restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Transfer the chunk <c>Bin</c> to the remote server, which
+ <p>Transfers the chunk <c>Bin</c> to the remote server, which
writes it into the file specified in the call to
- <c>send_chunk_start/2</c>. </p>
- <p>Note that for some errors, e.g. file system full, it is
+ <c>send_chunk_start/2</c>.</p>
+ <p>For some errors, for example, file system full, it is
necessary to to call <c>send_chunk_end</c> to get the
proper reason.</p>
@@ -776,14 +766,14 @@
<func>
<name>send_chunk_start(Pid, File) -> ok | {error, Reason}</name>
- <fsummary>Start transfer of file chunks.</fsummary>
+ <fsummary>Starts transfer of file chunks.</fsummary>
<type>
<v>Pid = pid()</v>
<v>File = string()</v>
<v>Reason = restriction_reason() | common_reason()</v>
</type>
<desc>
- <p>Start transfer of chunks into the file <c>File</c> at the
+ <p>Starts transfer of chunks into the file <c>File</c> at the
remote server.</p>
<marker id="send_chunk_end"></marker>
@@ -792,7 +782,7 @@
<func>
<name>send_chunk_end(Pid) -> ok | {error, Reason}</name>
- <fsummary>Stop transfer of chunks.</fsummary>
+ <fsummary>Stops transfer of chunks.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Reason = restriction_reason() | common_reason() | shortage_reason()</v>
@@ -808,7 +798,7 @@
<func>
<name>type(Pid, Type) -> ok | {error, Reason}</name>
- <fsummary>Set transfer type to <c>ascii</c>or <c>binary</c>.</fsummary>
+ <fsummary>Sets transfer type to <c>ascii</c>or <c>binary</c>.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Type = ascii | binary</v>
@@ -816,8 +806,8 @@
</type>
<desc>
<p>Sets the file transfer type to <c>ascii</c> or <c>binary</c>. When
- an ftp session is opened, the default transfer type of the
- server is used, most often <c>ascii</c>, which is the default
+ an FTP session is opened, the default transfer type of the
+ server is used, most often <c>ascii</c>, which is default
according to <url href="http://www.ietf.org/rfc/rfc959.txt">RFC 959</url>.</p>
<marker id="user3"></marker>
</desc>
@@ -856,21 +846,22 @@
<func>
<name>quote(Pid, Command) -> [FTPLine]</name>
- <fsummary>Sends an arbitrary FTP command. </fsummary>
+ <fsummary>Sends an arbitrary FTP command.</fsummary>
<type>
<v>Pid = pid()</v>
<v>Command = string()</v>
- <v>FTPLine = string() - Note the telnet end of line characters, from the ftp protocol definition, CRLF e.g. "\\r\\n" has been removed.</v>
- </type>
- <desc>
- <p>Sends an arbitrary FTP command and returns verbatimly a list
- of the lines sent back by the FTP server. This functions is
- intended to give an application accesses to FTP commands
- that are server specific or that may not be provided by
- this FTP client. </p>
+ <v>FTPLine = string(</v>
+ </type>
+ <desc><note><p>The telnet end of line characters, from the FTP
+ protocol definition, CRLF, for example, "\\r\\n" has been removed.</p></note>
+ <p>Sends an arbitrary FTP command and returns verbatim a list
+ of the lines sent back by the FTP server. This function is
+ intended to give application accesses to FTP commands
+ that are server-specific or that cannot be provided by
+ this FTP client.</p>
<note>
- <p>FTP commands that require a data connection can not be
- successfully issued with this function. </p>
+ <p>FTP commands requiring a data connection cannot be
+ successfully issued with this function.</p>
</note>
</desc>
</func>
@@ -884,30 +875,31 @@
<taglist>
<tag><c>echunk</c></tag>
<item>
- <p>Synchronisation error during chunk sending.
- </p>
- <p>A call has been made to <c>send_chunk/2</c> or
- <c>send_chunk_end/1</c>, before a call to
- <c>send_chunk_start/2</c>; or a call has been made to another
- transfer function during chunk sending, i.e. before a call
- to <c>send_chunk_end/1</c>.</p>
+ <p>Synchronization error during chunk sending according to one
+ of the following:
+ </p><list type="bulleted">
+ <item>A call is made to <c>send_chunk/2</c> or <c>send_chunk_end/1</c>
+ before a call to <c>send_chunk_start/2</c>.</item>
+ <item>A call has been made to another transfer function during chunk
+ sending, that is, before a call to <c>send_chunk_end/1</c>.</item>
+ </list>
</item>
<tag><c>eclosed</c></tag>
<item>
- <p>The session has been closed.</p>
+ <p>The session is closed.</p>
</item>
<tag><c>econn</c></tag>
<item>
- <p>Connection to remote server prematurely closed.</p>
+ <p>Connection to the remote server is prematurely closed.</p>
</item>
<tag><c>ehost</c></tag>
<item>
- <p>Host not found, FTP server not found, or connection rejected
+ <p>Host is not found, FTP server is not found, or connection is rejected
by FTP server.</p>
</item>
<tag><c>elogin</c></tag>
<item>
- <p>User not logged in.</p>
+ <p>User is not logged in.</p>
</item>
<tag><c>enotbinary</c></tag>
<item>
@@ -924,7 +916,7 @@
</item>
<tag><c>euser</c></tag>
<item>
- <p>User name or password not valid.</p>
+ <p>Invalid username or password.</p>
</item>
<tag><c>etnospc</c></tag>
<item>
@@ -937,14 +929,16 @@
</item>
<tag><c>efnamena</c></tag>
<item>
- <p>File name not allowed [553].</p>
+ <p>Filename not allowed [553].</p>
</item>
</taglist>
</section>
<section>
<title>SEE ALSO</title>
- <p>file, filename, J. Postel and J. Reynolds: File Transfer Protocol
+ <p><seealso marker="kernel:file">file(3)</seealso>
+ <seealso marker="stdlib:filename">filename(3)</seealso>
+ and J. Postel and J. Reynolds: File Transfer Protocol
(<url href="http://www.ietf.org/rfc/rfc959.txt">RFC 959</url>).
</p>
</section>
diff --git a/lib/inets/doc/src/ftp_client.xml b/lib/inets/doc/src/ftp_client.xml
index e46b354e45..89e66db814 100644
--- a/lib/inets/doc/src/ftp_client.xml
+++ b/lib/inets/doc/src/ftp_client.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -33,38 +34,24 @@
</header>
<section>
- <title>Introduction</title>
-
- <p>Ftp clients are consider to be rather temporary and are
- for that reason only started and stopped during
- runtime and can not be started at application startup.
- Due to the design of FTP client API, letting some
- functions return intermediate results, only the process
- that started the ftp client will be able to access it in
- order to preserve sane semantics. (This could be solved
- by changing the API and using the concept of a controlling
- process more in line with other OTP applications, but
- that is perhaps something for the future.)
- If the process that started the ftp session
- dies the ftp client process will terminate.</p>
+ <title>Getting Started</title>
- <p>The client supports ipv6 as long as the underlying mechanisms
- also do so. </p>
+ <p>FTP clients are considered to be rather temporary. Thus,
+ they are only started and stopped during runtime and cannot
+ be started at application startup.
+ The FTP client API is designed to allow some functions to
+ return intermediate results. This implies that only the process
+ that started the FTP client can access it with
+ preserved sane semantics.
+ If the process that started the FTP session
+ dies, the FTP client process terminates.</p>
- </section>
+ <p>The client supports IPv6 as long as the underlying mechanisms
+ also do so.</p>
- <section>
- <title>Using the FTP Client API</title>
- <p>The following is a simple example of an ftp session, where
+ <p>The following is a simple example of an FTP session, where
the user <c>guest</c> with password <c>password</c> logs on to
- the remote host <c>erlang.org</c>, and where the file
- <c>appl.erl</c> is transferred from the remote to the local
- host. When the session is opened, the current directory at
- the remote host is <c>/home/guest</c>, and <c>/home/fred</c>
- at the local host. Before transferring the file, the current
- local directory is changed to <c>/home/eproj/examples</c>, and
- the remote directory is set to
- <c>/home/guest/appl/examples</c>.</p>
+ the remote host <c>erlang.org</c>:</p>
<code type="erl"><![CDATA[
1> inets:start().
ok
@@ -85,6 +72,14 @@
9> inets:stop(ftpc, Pid).
ok
]]></code>
+ <p> The file
+ <c>appl.erl</c> is transferred from the remote to the local
+ host. When the session is opened, the current directory at
+ the remote host is <c>/home/guest</c>, and <c>/home/fred</c>
+ at the local host. Before transferring the file, the current
+ local directory is changed to <c>/home/eproj/examples</c>, and
+ the remote directory is set to
+ <c>/home/guest/appl/examples</c>.</p>
</section>
</chapter>
diff --git a/lib/inets/doc/src/http_client.xml b/lib/inets/doc/src/http_client.xml
index 1c7f76ec28..f4d7b751ac 100644
--- a/lib/inets/doc/src/http_client.xml
+++ b/lib/inets/doc/src/http_client.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -33,103 +34,91 @@
</header>
<section>
- <title>Introduction</title>
+ <title>Configuration</title>
- <p>The HTTP client default profile will be started when the inets
+ <p>The HTTP client default profile is started when the <c>Inets</c>
application is started and is then available to all processes on
- that erlang node. Other profiles may also be started at
+ that Erlang node. Other profiles can also be started at
application startup, or profiles can be started and stopped
- dynamically in runtime. Each client profile will spawn a new
- process to handle each request unless there is a possibility to use
- a persistent connection with or without pipelining.
- The client will add a <c>host</c> header and an empty
+ dynamically in runtime. Each client profile spawns a new
+ process to handle each request, unless a persistent connection
+ can be used with or without pipelining.
+ The client adds a <c>host</c> header and an empty
<c>te</c> header if there are no such headers present in the request.</p>
- <p>The client supports ipv6 as long as the underlying mechanisms also do
+ <p>The client supports IPv6 as long as the underlying mechanisms also do
so.</p>
- </section>
- <section>
- <title>Configuration</title>
- <p> What to put in the erlang node application configuration file
- in order to start a profile at application startup.</p>
+ <p>The following is to be put in the Erlang node application configuration file
+ to start a profile at application startup:</p>
<pre>
- [{inets, [{services, [{httpc, PropertyList}]}]}]
- </pre>
- <p>For valid properties see
+ [{inets, [{services, [{httpc, PropertyList}]}]}]</pre>
+ <p>For valid properties, see
<seealso marker="httpc">httpc(3)</seealso>. </p>
</section>
<section>
- <title>Using the HTTP Client API</title>
+ <title>Getting Started</title>
+ <p>Start <c>Inets</c>:</p>
<code type="erl">
1 > inets:start().
- ok
- </code>
- <p> The following calls uses the default client profile.
- Use the proxy "www-proxy.mycompany.com:8000",
- but not for requests to localhost. This will apply to all subsequent
- requests</p>
+ ok</code>
+ <p>The following calls use the default client profile.
+ Use the proxy <c>"www-proxy.mycompany.com:8000"</c>,
+ except from requests to localhost. This applies to all the
+ following requests.</p>
+ <p>Example:</p>
<code type="erl">
2 > httpc:set_options([{proxy, {{"www-proxy.mycompany.com", 8000},
["localhost"]}}]).
- ok
- </code>
- <p>An ordinary synchronous request. </p>
+ ok</code>
+ <p>The following is an ordinary synchronous request:</p>
<code type="erl">
3 > {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
- httpc:request(get, {"http://www.erlang.org", []}, [], []).
- </code>
- <p>With all default values, as above, a get request can also be written
- like this.</p>
+ httpc:request(get, {"http://www.erlang.org", []}, [], []).</code>
+ <p>With all the default values presented, a get request can also be written
+ as follows:</p>
<code type="erl">
4 > {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
- httpc:request("http://www.erlang.org").
- </code>
- <p>An ordinary asynchronous request. The result will be sent
- to the calling process in the form <c>{http, {ReqestId, Result}}</c></p>
+ httpc:request("http://www.erlang.org").</code>
+ <p>The following is an ordinary asynchronous request:</p>
<code type="erl">
5 > {ok, RequestId} =
- httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).
- </code>
- <p>In this case the calling process is the shell, so we receive the
- result.</p>
+ httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).</code>
+ <p>The result is sent to the calling process as
+ <c>{http, {ReqestId, Result}}</c>.</p>
+ <p>In this case, the calling process is the shell, so the following
+ result is received:</p>
<code type="erl">
6 > receive {http, {RequestId, Result}} -> ok after 500 -> error end.
- ok
- </code>
- <p>Send a request with a specified connection header. </p>
+ ok</code>
+ <p>This sends a request with a specified connection header:</p>
<code type="erl">
7 > {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
httpc:request(get, {"http://www.erlang.org", [{"connection", "close"}]},
- [], []).
- </code>
+ [], []).</code>
- <p>Start a HTTP client profile. </p>
+ <p>Start an HTTP client profile:</p>
<code><![CDATA[
8 > {ok, Pid} = inets:start(httpc, [{profile, foo}]).
{ok, <0.45.0>}
]]></code>
- <p>The new profile has no proxy settings so the connection will
- be refused</p>
+ <p>The new profile has no proxy settings, so the connection is refused:</p>
<code type="erl">
9 > httpc:request("http://www.erlang.org", foo).
- {error, econnrefused}
- </code>
+ {error, econnrefused}</code>
- <p>Stop a HTTP client profile. </p>
+ <p>Stop the HTTP client profile:</p>
<code type="erl">
10 > inets:stop(httpc, foo).
- ok
- </code>
+ ok</code>
- <p>Alternatively:</p>
+ <p>Alternative way to stop the HTTP client profile:</p>
<code type="erl">
10 > inets:stop(httpc, Pid).
- ok
- </code>
+ ok</code>
</section>
</chapter>
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index e3b763b4f3..aeda961714 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -4,94 +4,84 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
-
- <title>HTTP server </title>
- <prepared>Ingela Anderton Andin</prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date></date>
- <rev></rev>
+ <title>HTTP server</title>
<file>http_server.xml</file>
-
- <marker id="intro"></marker>
</header>
<section>
- <title>Introduction</title>
-
+ <title>Configuration</title>
+ <marker id="config"></marker>
<p>The HTTP server, also referred to as httpd, handles HTTP requests
- as described in RFC 2616 with a few exceptions such as gateway
- and proxy functionality. The server supports ipv6 as long as the
- underlying mechanisms also do so. </p>
-
- <p>The server implements numerous features such as SSL (Secure Sockets
- Layer), ESI (Erlang Scripting Interface), CGI (Common Gateway
- Interface), User Authentication(using Mnesia, dets or plain text
- database), Common Logfile Format (with or without disk_log(3)
- support), URL Aliasing, Action Mappings, Directory Listings and SSI
- (Server-Side Includes).</p>
-
- <p>The configuration of the server is provided as an erlang
- property list, and for backwards compatibility also a configuration
+ as described in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>
+ with a few exceptions, such as gateway
+ and proxy functionality. The server supports IPv6 as long as the
+ underlying mechanisms also do so.</p>
+
+ <p>The server implements numerous features, such as:</p>
+ <list type="bulleted">
+ <item>Secure Sockets Layer (SSL)</item>
+ <item>Erlang Scripting Interface (ESI)</item>
+ <item>Common Gateway Interface (CGI)</item>
+ <item>User Authentication (using <c>Mnesia</c>,
+ <c>Dets</c> or plain text database)</item>
+ <item>Common Logfile Format (with or without disk_log(3) support)</item>
+ <item>URL Aliasing</item>
+ <item>Action Mappings</item>
+ <item>Directory Listings</item>
+ </list>
+
+ <p>The configuration of the server is provided as an Erlang
+ property list. For backwards compatibility, a configuration
file using apache-style configuration directives is
supported.</p>
- <p>As of inets version 5.0 the HTTP server is an easy to
- start/stop and customize web server that provides the most basic
- web server functionality. Depending on your needs there
- are also other erlang based web servers that may be of interest
- such as Yaws, http://yaws.hyber.org, that for instance has its own
- markup support to generate html, and supports certain buzzword
- technologies such as SOAP.</p>
+ <p>As of <c>Inets</c> 5.0 the HTTP server is an easy to
+ start/stop and customize web server providing the most basic
+ web server functionality. Inets is designed for embedded systems
+ and if you want a full-fledged web server there are exists other
+ erlang open source alternatives.</p>
- <p>Allmost all server functionality has been implemented using an
- especially crafted server API which is described in the Erlang Web
- Server API. This API can be used to advantage by all who wish
+ <p>Almost all server functionality has been implemented using an
+ especially crafted server API, which is described in the Erlang Web
+ Server API. This API can be used
to enhance the core server functionality, for example with custom
logging and authentication.</p>
- <marker id="config"></marker>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <p> What to put in the erlang node application configuration file
- in order to start a http server at application startup.</p>
+ <p>The following is to be put in the Erlang node application configuration
+ file to start an HTTP server at application startup:</p>
<code type="erl">
[{inets, [{services, [{httpd, [{proplist_file,
"/var/tmp/server_root/conf/8888_props.conf"}]},
{httpd, [{proplist_file,
- "/var/tmp/server_root/conf/8080_props.conf"}]}]}]}].
- </code>
-
- <p>The server is configured using an erlang property list.
- For the available properties see
- <seealso marker="httpd">httpd(3)</seealso>
- For backwards compatibility also apache-like config files
- are supported.
+ "/var/tmp/server_root/conf/8080_props.conf"}]}]}]}].</code>
+
+ <p>The server is configured using an Erlang property list.
+ For the available properties, see
+ <seealso marker="httpd">httpd(3)</seealso>.
+ For backwards compatibility, apache-like configuration files
+ are also supported.
</p>
- <p>All possible config properties are as follows </p>
+ <p>The available configuration properties are as follows:</p>
<code type="none">
httpd_service() -> {httpd, httpd()}
httpd() -> [httpd_config()]
@@ -103,40 +93,43 @@
debug_options() -> {all_functions, modules()} |
{exported_functions, modules()} |
{disable, modules()}
- modules() -> [atom()]
- </code>
- <p>{proplist_file, file()} File containing an erlang property
+ modules() -> [atom()]</code>
+ <p>Here:</p>
+ <taglist>
+ <tag><c>{file, file()}</c></tag>
+ <item><p>If you use an old apace-like configuration file.</p></item>
+ <tag><c>{proplist_file, file()}</c></tag>
+ <item><p>File containing an Erlang property
list, followed by a full stop, describing the HTTP server
- configuration.</p>
- <p>{file, file()} If you use an old apace-like configuration file.</p>
- <p>{debug, debug()} - Can enable trace on all
- functions or only exported functions on chosen modules.</p>
- <p>{accept_timeout, integer()} sets the wanted timeout value for
- the server to set up a request connection.</p>
-
- <marker id="using_http_server_api"></marker>
+ configuration.</p></item>
+ <tag><c>{debug, debug()}</c></tag>
+ <item><p>Can enable trace on all functions or only exported functions
+ on chosen modules.</p></item>
+ <tag><c>{accept_timeout, integer()}</c></tag>
+ <item><p>Sets the wanted time-out value for
+ the server to set up a request connection.</p></item>
+ </taglist>
</section>
<section>
- <title>Using the HTTP Server API</title>
+ <title>Getting Started</title>
+ <marker id="using_http_server_api"></marker>
+ <p>Start <c>Inets</c>:</p>
<code type="none">
1 > inets:start().
- ok
- </code>
- <p> Start a HTTP server with minimal
- required configuration. Note that if you
- specify port 0 an arbitrary available port will be
- used and you can use the info function to find out
- which port number that was picked.
- </p>
+ ok</code>
+ <p>Start an HTTP server with minimal required configuration.
+ If you specify port <c>0</c>, an arbitrary available port is
+ used, and you can use function <c>info</c> to find which port
+ number that was picked:</p>
<code type="none">
2 > {ok, Pid} = inets:start(httpd, [{port, 0},
{server_name,"httpd_test"}, {server_root,"/tmp"},
{document_root,"/tmp/htdocs"}, {bind_address, "localhost"}]).
- {ok, 0.79.0}
- </code>
+ {ok, 0.79.0} </code>
+ <p>Call <c>info</c>:</p>
<code type="none">
3 > httpd:info(Pid).
[{mime_types,[{"html","text/html"},{"htm","text/html"}]},
@@ -144,571 +137,404 @@
{bind_address, {127,0,0,1}},
{server_root,"/tmp"},
{port,59408},
- {document_root,"/tmp/htdocs"}]
- </code>
+ {document_root,"/tmp/htdocs"}]</code>
- <p> Reload the configuration without restarting the server.
- Note port and bind_address can not be changed. Clients
- trying to access the server during the reload will
- get a service temporary unavailable answer.
+ <p>Reload the configuration without restarting the server:
+
</p>
<code type="none">
4 > httpd:reload_config([{port, 59408},
{server_name,"httpd_test"}, {server_root,"/tmp/www_test"},
{document_root,"/tmp/www_test/htdocs"},
{bind_address, "localhost"}], non_disturbing).
- ok.
- </code>
+ ok.</code>
+
+ <note><p><c>port</c> and <c>bind_address</c> cannot be changed.
+ Clients trying to access the server during the reload
+ get a service temporary unavailable answer.</p></note>
<code type="none">
5 > httpd:info(Pid, [server_root, document_root]).
- [{server_root,"/tmp/www_test"},{document_root,"/tmp/www_test/htdocs"}]
- </code>
+ [{server_root,"/tmp/www_test"},{document_root,"/tmp/www_test/htdocs"}] </code>
<code type="none">
- 6 > ok = inets:stop(httpd, Pid).
- </code>
+ 6 > ok = inets:stop(httpd, Pid).</code>
- <p> Alternative:</p>
+ <p>Alternative:</p>
<code type="none">
- 6 > ok = inets:stop(httpd, {{127,0,0,1}, 59408}).
- </code>
+ 6 > ok = inets:stop(httpd, {{127,0,0,1}, 59408}).</code>
- <p>Note that bind_address has to be
- the ip address reported by the info function and can
- not be the hostname that is allowed when inputting bind_address.</p>
-
- <marker id="htaccess"></marker>
+ <p>Notice that <c>bind_address</c> must be the IP address reported
+ by function <c>info</c> and cannot be the hostname that is allowed
+ when putting in <c>bind_address</c>.</p>
</section>
<section>
- <title>Htaccess - User Configurable Authentication.</title>
- <p>If users of the web server needs to manage authentication of
- web pages that are local to their user and do not have
- server administrative privileges. They can use the
- per-directory runtime configurable user-authentication scheme
- that Inets calls htaccess. It works the following way: </p>
+ <title>Htaccess - User Configurable Authentication</title>
+ <marker id="htaccess"></marker>
+ <p>Web server users without server administrative privileges
+ that need to manage authentication of web pages that are local
+ to their user can use the per-directory runtime configurable
+ user-authentication scheme <c>htaccess</c>.
+ It works as follows:</p>
<list type="bulleted">
<item>Each directory in the path to the requested asset is
- searched for an access-file (default .htaccess), that restricts
- the web servers rights to respond to a request. If an access-file
- is found the rules in that file is applied to the
- request. </item>
- <item>The rules in an access-file applies both to files in the same
- directories and in subdirectories. If there exists more than one
- access-file in the path to an asset, the rules in the
- access-file nearest the requested asset will be applied.</item>
- <item>To change the rules that restricts the use of
- an asset. The user only needs to have write access
- to the directory where the asset exists.</item>
- <item>All the access-files in the path to a requested asset is read
- once per request, this means that the load on the server will
- increase when this scheme is used.</item>
- <item>If a directory is
- limited both by auth directives in the HTTP server configuration
- file and by the htaccess files. The user must be allowed to get
- access the file by both methods for the request to succeed.</item>
+ searched for an access file (default is <c>.htaccess</c>), which
+ restricts the web servers rights to respond to a request.
+ If an access file is found, the rules in that file is applied to the
+ request.</item>
+ <item>The rules in an access file apply to files in the same
+ directory and in subdirectories. If there exists more than one
+ access file in the path to an asset, the rules in the
+ access file nearest the requested asset is applied.</item>
+ <item>To change the rules that restrict the use of
+ an asset, the user only needs write access
+ to the directory where the asset is.</item>
+ <item>All access files in the path to a requested asset are read
+ once per request. This means that the load on the server
+ increases when <c>htaccess</c> is used.</item>
+ <item>If a directory is limited both by authentication directives
+ in the HTTP server configuration file and by the <c>htaccess</c>
+ files, the user must be allowed to get access to the file by both
+ methods for the request to succeed.</item>
</list>
<section>
<title>Access Files Directives</title>
- <p>In every directory under the <c>DocumentRoot</c> or under an
- <c>Alias</c> a user can place an access-file. An access-file
- is a plain text file that specify the restrictions that
- shall be considered before the web server answer to a
- request. If there are more than one access-file in the path
- to the requested asset, the directives in the access-file in
- the directory nearest the asset will be used.</p>
- <list type="bulleted">
+ <p>In every directory under <c>DocumentRoot</c> or under an
+ <c>Alias</c> a user can place an access file. An access file
+ is a plain text file that specifies the restrictions to
+ consider before the web server answers to a
+ request. If there are more than one access file in the path
+ to the requested asset, the directives in the access file in
+ the directory nearest the asset is used.</p>
+ <taglist>
+ <tag><em>"allow"</em></tag>
<item>
- <p><em>DIRECTIVE: "allow"</em></p>
- <p><em>Syntax:</em><c>Allow</c> from subnet subnet|from all <br></br>
-<em>Default:</em><c>from all </c> <br></br>
-</p>
- <p>Same as the directive allow for the server config file. </p>
+ <p><em>Syntax:</em> <c>Allow</c> from subnet <c>subnet | from all</c></p>
+ <p><em>Default:</em> <c>from all</c></p>
+ <p>Same as directive <c>allow</c> for the server configuration file.</p>
</item>
- <item>
- <p><em>DIRECTIVE: "AllowOverRide"</em></p>
- <p><em>Syntax:</em><c>AllowOverRide</c> all | none |
- Directives <br></br>
-<em>Default:</em><c>- None -</c> <br></br>
-<c>AllowOverRide</c> Specify which parameters that not
- access-files in subdirectories are allowed to alter the value
- for. If the parameter is set to none no more
- access-files will be parsed.
+ <tag><em>"AllowOverRide"</em></tag>
+ <item>
+ <p><em>Syntax:</em> <c>AllowOverRide</c> <c>all | none | Directives</c></p>
+ <p><em>Default:</em> <c>none</c></p>
+ <p><c>AllowOverRide</c> specifies the parameters that
+ access files in subdirectories are not allowed to alter the value
+ for. If the parameter is set to <c>none</c>, no further
+ access files is parsed.
</p>
- <p>If only one access-file exists setting this parameter to
- none can lessen the burden on the server since the server
- will stop looking for access-files.</p>
+ <p>If only one access file exists, setting this parameter to
+ <c>none</c> can ease the burden on the server as the server
+ then stops looking for access files.</p>
</item>
+ <tag><em>"AuthGroupfile"</em></tag>
<item>
- <p><em>DIRECTIVE: "AuthGroupfile"</em></p>
- <p><em>Syntax:</em><c>AuthGroupFile</c> Filename <br></br>
-<em>Default:</em><c>- None -</c> <br></br>
-</p>
- <p>AuthGroupFile indicates which file that contains the list
- of groups. Filename must contain the absolute path to the
- file. The format of the file is one group per row and
+ <p><em>Syntax:</em> <c>AuthGroupFile</c> Filename</p>
+ <p><em>Default:</em> <c>none</c></p>
+ <p><c>AuthGroupFile</c> indicates which file that contains the list
+ of groups. The filename must contain the absolute path to the
+ file. The format of the file is one group per row and
every row contains the name of the group and the members
- of the group separated by a space, for example:</p>
+ of the group, separated by a space, for example:</p>
<pre>
-GroupName: Member1 Member2 .... MemberN
- </pre>
+GroupName: Member1 Member2 .... MemberN</pre>
</item>
+ <tag><em>"AuthName"</em></tag>
<item>
- <p><em>DIRECTIVE: "AuthName"</em></p>
- <p><em>Syntax:</em><c>AuthName</c> auth-domain <br></br>
-<em>Default:</em><c>- None -</c> <br></br>
-</p>
- <p>Same as the directive AuthName for the server config file. </p>
+ <p><em>Syntax:</em> <c>AuthName</c> auth-domain</p>
+ <p><em>Default:</em> <c>none</c></p>
+ <p>Same as directive <c>AuthName</c> for the server
+ configuration file.</p>
</item>
+ <tag><em>"AuthType"</em></tag>
<item>
- <p><em>DIRECTIVE: "AuthType"</em></p>
- <p><em>Syntax:</em><c>AuthType</c> Basic <br></br>
-<em>Default:</em><c>Basic</c> <br></br>
-</p>
- <p><c>AuthType</c> Specify which authentication scheme that shall
- be used. Today only Basic Authenticating using UUEncoding of
- the password and user ID is implemented. </p>
+ <p><em>Syntax:</em> <c>AuthType</c> <c>Basic</c></p>
+ <p><em>Default:</em> <c>Basic</c></p>
+ <p><c>AuthType</c> specifies which authentication scheme to
+ be used. Only Basic Authenticating using UUEncoding of
+ the password and user ID is implemented.</p>
</item>
+ <tag><em>"AuthUserFile"</em></tag>
<item>
- <p><em>DIRECTIVE: "AuthUserFile"</em></p>
- <p><em>Syntax:</em><c>AuthUserFile</c> Filename <br></br>
-<em>Default:</em><c>- None -</c> <br></br>
-</p>
- <p><c>AuthUserFile</c> indicate which file that contains the list
- of users. Filename must contain the absolute path to the
- file. The users name and password are not encrypted so do not
+ <p><em>Syntax:</em> <c>AuthUserFile</c> Filename</p>
+ <p><em>Default:</em><c>none</c></p>
+ <p><c>AuthUserFile</c> indicates which file that contains the list
+ of users. The filename must contain the absolute path to the
+ file. The username and password are not encrypted so do not
place the file with users in a directory that is accessible
- via the web server. The format of the file is one user per row
- and every row contains User Name and Password separated by a
- colon, for example:</p>
+ through the web server. The format of the file is one user per row.
+ Every row contains <c>UserName</c> and <c>Password</c> separated
+ by a colon, for example:</p>
<pre>
UserName:Password
-UserName:Password
- </pre>
+UserName:Password</pre>
</item>
+ <tag><em>"deny"</em></tag>
<item>
- <p><em>DIRECTIVE: "deny"</em></p>
- <p><em>Syntax:</em><c>deny</c> from subnet subnet|from all <br></br>
-<em>Context:</em> Limit</p>
- <p>Same as the directive deny for the server config file. </p>
+ <p><em>Syntax:</em> <c>deny</c> from subnet <c>subnet | from all</c></p>
+ <p><em>Context:</em> Limit</p>
+ <p>Same as directive <c>deny</c> for the server configuration file.</p>
</item>
- <item>
- <p><em>DIRECTIVE: "Limit"</em> <br></br>
-</p>
- <p><em>Syntax:</em><c><![CDATA[<Limit]]></c> RequestMethods<c>></c> <br></br>
-<em>Default:</em> - None - <br></br>
-</p>
- <p><c><![CDATA[<Limit>]]></c> and &lt;/Limit&gt; are used to enclose
- a group of directives which applies only to requests using
- the specified methods. If no request method is specified
+ <tag><em>"Limit"</em></tag>
+ <item>
+ <p><em>Syntax:</em> <c><![CDATA[<Limit]]></c> RequestMethods<c>></c></p>
+ <p><em>Default:</em> <c>none</c></p>
+ <p><c><![CDATA[<Limit>]]></c> and <c>&lt;/Limit&gt;</c> are used to enclose
+ a group of directives applying only to requests using
+ the specified methods. If no request method is specified,
all request methods are verified against the restrictions.</p>
+ <p>Example:</p>
<pre>
&lt;Limit POST GET HEAD&gt;
order allow deny
require group group1
allow from 123.145.244.5
-&lt;/Limit&gt;
- </pre>
+&lt;/Limit&gt;</pre>
</item>
- <item>
- <p><em>DIRECTIVE: "order"</em> <br></br>
-<em>Syntax:</em><c>order</c> allow deny | deny allow <br></br>
-<em>Default:</em> allow deny <br></br>
-</p>
- <p><c>order</c>, defines if the deny or allow control shall
- be preformed first.</p>
- <p>If the order is set to allow deny, then first the users
- network address is controlled to be in the allow subset. If
- the users network address is not in the allowed subset he will
- be denied to get the asset. If the network-address is in the
- allowed subset then a second control will be preformed, that
- the users network address is not in the subset of network
- addresses that shall be denied as specified by the deny
- parameter.</p>
- <p>If the order is set to deny allow then only users from networks
- specified to be in the allowed subset will succeed to request
+ <tag><em>"order"</em></tag>
+ <item>
+ <p><em>Syntax:</em> <c>order</c> <c>allow deny | deny allow</c></p>
+ <p><em>Default:</em> <c>allow deny</c></p>
+ <p><c>order</c> defines if the deny or allow control is to
+ be performed first.</p>
+ <p>If the order is set to <c>allow deny</c>, the users
+ network address is first controlled to be in the allow subset.
+ If the user network address is not in the allowed subset, the user
+ is denied to get the asset. If the network address is in the
+ allowed subset, a second control is performed. That is,
+ the user network address is not in the subset of network
+ addresses to be denied as specified by parameter <c>deny</c>.</p>
+ <p>If the order is set to <c>deny allow</c>, only users from networks
+ specified to be in the allowed subset succeeds to request
assets in the limited area.</p>
</item>
- <item>
- <p><em>DIRECTIVE: "require"</em></p>
- <p><em>Syntax:</em><c>require</c>
- group group1 group2...|user user1 user2... <br></br>
-<em>Default:</em><c>- None -</c> <br></br>
-<em>Context:</em> Limit <br></br>
-</p>
- <p>See the require directive in the documentation of mod_auth(3)
- for more information.</p>
+ <tag><em>"require"</em></tag>
+ <item>
+ <p><em>Syntax:</em> <c>require</c>
+ <c>group group1 group2... | user user1 user2...</c></p>
+ <p><em>Default:</em> <c>none</c></p>
+ <p><em>Context:</em> Limit</p>
+ <p>For more information, see directive <c>require</c> in
+ <seealso marker="mod_auth">mod_auth(3)</seealso>.</p>
</item>
- </list>
+ </taglist>
</section>
-
- <marker id="dynamic_we_pages"></marker>
</section>
<section>
<title>Dynamic Web Pages</title>
- <p>The Inets HTTP server provides two ways of creating dynamic web
- pages, each with its own advantages and disadvantages. </p>
- <p>First there are CGI-scripts that can be written in any programming
- language. CGI-scripts are standardized and supported by most
- web servers. The drawback with CGI-scripts is that they are resource
- intensive because of their design. CGI requires the server to fork a
- new OS process for each executable it needs to start. </p>
- <p>Second there are ESI-functions that provide a tight and efficient
- interface to the execution of Erlang functions, this interface
- on the other hand is Inets specific. </p>
-
+ <marker id="dynamic_we_pages"></marker>
+ <p><c>Inets</c> HTTP server provides two ways of creating dynamic web
+ pages, each with its own advantages and disadvantages:</p>
+ <taglist>
+ <tag><em>CGI scripts</em></tag>
+ <item><p>Common Gateway Interface (CGI) scripts can be written
+ in any programming language. CGI scripts are standardized and
+ supported by most web servers. The drawback with CGI scripts is that
+ they are resource-intensive because of their design. CGI requires the
+ server to fork a new OS process for each executable it needs to start.
+ </p></item>
+ <tag><em>ESI-functions</em></tag>
+ <item><p>Erlang Server Interface (ESI) functions provide a tight and efficient
+ interface to the execution of Erlang functions. This interface,
+ on the other hand, is <c>Inets</c> specific.</p></item>
+ </taglist>
+
<section>
- <title>The Common Gateway Interface (CGI) Version 1.1, RFC 3875.</title>
- <p>The mod_cgi module makes it possible to execute CGI scripts
- in the server. A file that matches the definition of a
- ScriptAlias config directive is treated as a CGI script. A CGI
+ <title>CGI Version 1.1, RFC 3875</title>
+ <p>The module <c>mod_cgi</c> enables execution of
+ <url href="http://www.ietf.org/rfc/rfc3875.txt">CGI scripts</url>
+ on the server. A file matching the definition of a
+ ScriptAlias config directive is treated as a CGI script. A CGI
script is executed by the server and its output is returned to
- the client. </p>
- <p>The CGI Script response comprises a message-header and a
- message-body, separated by a blank line. The message-header
- contains one or more header fields. The body may be
- empty. Example: </p>
+ the client.</p>
+ <p>The CGI script response comprises a message header and a
+ message body, separated by a blank line. The message header
+ contains one or more header fields. The body can be
+ empty.</p>
+ <p>Example:</p>
<code>"Content-Type:text/plain\nAccept-Ranges:none\n\nsome very
- plain text" </code>
+ plain text"</code>
- <p>The server will interpret the cgi-headers and most of them
- will be transformed into HTTP headers and sent back to the
- client together with the body.</p>
- <p>Support for CGI-1.1 is implemented in accordance with the RFC
- 3875. </p>
+ <p>The server interprets the message headers and most of them
+ are transformed into HTTP headers and sent back to the
+ client together with the message-body.</p>
+ <p>Support for CGI-1.1 is implemented in accordance with
+ <url href="http://www.ietf.org/rfc/rfc3875.txt">RFC 3875</url>.</p>
</section>
<section>
- <title>Erlang Server Interface (ESI)</title>
- <p>The erlang server interface is implemented by the
- module mod_esi.</p>
+ <title>ESI</title>
+ <p>The Erlang server interface is implemented by
+ module <c>mod_esi</c>.</p>
<section>
- <title>ERL Scheme </title>
+ <title>ERL Scheme</title>
<p>The erl scheme is designed to mimic plain CGI, but without
- the extra overhead. An URL which calls an Erlang erl function
+ the extra overhead. An URL that calls an Erlang <c>erl</c> function
has the following syntax (regular expression): </p>
<code type="none">
-http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)
- </code>
- <p>*** above depends on how the ErlScriptAlias config
- directive has been used</p>
- <p>The module (Module) referred to must be found in the code
- path, and it must define a function (Function) with an arity
- of two or three. It is preferable to implement a funtion
- with arity three as it permits you to send chunks of the
- webpage beeing generated to the client during the generation
+http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)</code>
+ <p>*** depends on how the ErlScriptAlias config
+ directive has been used.</p>
+ <p>The module <c>Module</c> referred to must be found in the code
+ path, and it must define a function <c>Function</c> with an arity
+ of two or three. It is preferable to implement a function
+ with arity three, as it permits to send chunks of the
+ web page to the client during the generation
phase instead of first generating the whole web page and
then sending it to the client. The option to implement a
function with arity two is only kept for
backwards compatibility reasons.
- See <seealso marker="mod_esi">mod_esi(3)</seealso> for
- implementation details of the esi callback function.</p>
+ For implementation details of the ESI callback function,
+ see <seealso marker="mod_esi">mod_esi(3)</seealso>.</p>
</section>
<section>
- <title>EVAL Scheme </title>
+ <title>EVAL Scheme</title>
<p>The eval scheme is straight-forward and does not mimic the
- behavior of plain CGI. An URL which calls an Erlang eval
+ behavior of plain CGI. An URL that calls an Erlang <c>eval</c>
function has the following syntax:</p>
<code type="none">
-http://your.server.org/***/Mod:Func(Arg1,...,ArgN)
- </code>
- <p>*** above depends on how the ErlScriptAlias config
- directive has been used</p>
- <p>The module (Mod) referred to must be found in the code
- path, and data returned by the function (Func) is passed
+http://your.server.org/***/Mod:Func(Arg1,...,ArgN)</code>
+ <p>*** depends on how the ErlScriptAlias config
+ directive has been used.</p>
+ <p>The module <c>Mod</c> referred to must be found in the code
+ path and data returned by the function <c>Func</c> is passed
back to the client. Data returned from the
- function must furthermore take the form as specified in
- the CGI specification. See <seealso marker="mod_esi">mod_esi(3)</seealso> for implementation details of the esi
- callback function.</p>
+ function must take the form as specified in
+ the CGI specification. For implementation details of the ESI
+ callback function,
+ see <seealso marker="mod_esi">mod_esi(3)</seealso>.</p>
<note>
<p>The eval scheme can seriously threaten the
- integrity of the Erlang node housing a Web server, for
- example: </p>
+ integrity of the Erlang node housing a web server, for
+ example:</p>
<code type="none">
-http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[])))
- </code>
- <p>which effectively will close down the Erlang node,
- therefor, use the erl scheme instead, until this
- security breach has been fixed.</p>
- <p>Today there are no good way of solving this problem
- and therefore Eval Scheme may be removed in future
- release of Inets. </p>
+http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[])))</code>
+ <p>This effectively closes down the Erlang node.
+ Therefore, use the erl scheme instead, until this
+ security breach is fixed.</p>
+ <p>Today there are no good ways of solving this problem
+ and therefore the eval scheme can be removed in future
+ release of <c>Inets</c>.</p>
</note>
</section>
</section>
-
- <marker id="logging"></marker>
</section>
<section>
- <title>Logging </title>
- <p>There are three types of logs supported. Transfer logs,
- security logs and error logs. The de-facto standard Common
+ <title>Logging</title>
+ <marker id="logging"></marker>
+ <p>Three types of logs are supported: transfer logs,
+ security logs, and error logs. The de-facto standard Common
Logfile Format is used for the transfer and security logging.
There are numerous statistics programs available to analyze Common
Logfile Format. The Common Logfile Format looks as follows:
</p>
<p><em>remotehost rfc931 authuser [date] "request" status bytes</em></p>
+ <p>Here:</p>
<taglist>
<tag><em>remotehost</em></tag>
- <item>Remote hostname</item>
+ <item>Remote hostname.</item>
<tag><em>rfc931</em></tag>
- <item>The client's remote username (RFC 931).</item>
+ <item>The client remote username (<url href="http://www.ietf.org/rfc/rfc931.txt">RFC 931</url>).</item>
<tag><em>authuser</em></tag>
- <item>The username with which the user authenticated himself.</item>
+ <item>The username used for authentication.</item>
<tag><em>[date]</em></tag>
- <item>Date and time of the request (RFC 1123).</item>
+ <item>Date and time of the request (<url href="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</url>).</item>
<tag><em>"request"</em></tag>
- <item>The request line exactly as it came from the client (RFC 1945).</item>
+ <item>The request line exactly as it came from the client (<url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>).</item>
<tag><em>status</em></tag>
- <item>The HTTP status code returned to the client (RFC 1945).</item>
+ <item>The HTTP status code returned to the client (<url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>).</item>
<tag><em>bytes</em></tag>
<item>The content-length of the document transferred. </item>
</taglist>
<p>Internal server errors are recorded in the error log file. The
- format of this file is a more ad hoc format than the logs using
+ format of this file is a more unplanned format than the logs using
Common Logfile Format, but conforms to the following syntax:
</p>
<p><em>[date]</em> access to <em>path</em> failed for
<em>remotehost</em>, reason: <em>reason</em></p>
-
- <marker id="ssi"></marker>
</section>
-
+
<section>
- <title>Server Side Includes</title>
- <p>Server Side Includes enables the server to run code embedded
- in HTML pages to generate the response to the client.</p>
- <note>
- <p>Having the server parse HTML pages is a double edged sword!
- It can be costly for a heavily loaded server to perform
- parsing of HTML pages while sending them. Furthermore, it can
- be considered a security risk to have average users executing
- commands in the name of the Erlang node user. Carefully
- consider these items before activating server-side includes.</p>
- </note>
-
- <section>
- <marker id="ssi_setup"></marker>
- <title>SERVER-SIDE INCLUDES (SSI) SETUP</title>
- <p>The server must be told which filename extensions to be used
- for the parsed files. These files, while very similar to HTML,
- are not HTML and are thus not treated the same. Internally, the
- server uses the magic MIME type <c>text/x-server-parsed-html</c>
- to identify parsed documents. It will then perform a format
- conversion to change these files into HTML for the
- client. Update the <c>mime.types</c> file, as described in the
- Mime Type Settings, to tell the server which extension to use
- for parsed files, for example:
- </p>
- <pre>
- text/x-server-parsed-html shtml shtm
- </pre>
- <p>This makes files ending with <c>.shtml</c> and <c>.shtm</c>
- into parsed files. Alternatively, if the performance hit is not a
- problem, <em>all</em> HTML pages can be marked as parsed:
- </p>
- <pre>
- text/x-server-parsed-html html htm
- </pre>
- </section>
-
- <section>
- <marker id="ssi_format"></marker>
- <title>Server-Side Includes (SSI) Format</title>
- <p>All server-side include directives to the server are formatted
- as SGML comments within the HTML page. This is in case the
- document should ever find itself in the client's hands
- unparsed. Each directive has the following format:
- </p>
- <pre>
- &lt;!--#command tag1="value1" tag2="value2" --&gt;
- </pre>
- <p>Each command takes different arguments, most only accept one
- tag at a time. Here is a breakdown of the commands and their
- associated tags:
- </p>
- <p>The config directive controls various aspects of the
- file parsing. There are two valid tags:
- </p>
- <taglist>
- <tag><c>errmsg</c></tag>
- <item>
- <p>controls the message sent back to the client if an
- error occurred while parsing the document. All errors are
- logged in the server's error log.</p>
- </item>
- <tag><c>sizefmt</c></tag>
- <item>
- <p>determines the format used to display the size of
- a file. Valid choices are <c>bytes</c> or
- <c>abbrev</c>. <c>bytes</c> for a formatted byte count
- or <c>abbrev</c> for an abbreviated version displaying
- the number of kilobytes.</p>
- </item>
- </taglist>
- <p>The include directory
- will insert the text of a document into the parsed
- document. This command accepts two tags:</p>
- <taglist>
- <tag><c>virtual</c></tag>
- <item>
- <p>gives a virtual path to a document on the
- server. Only normal files and other parsed documents can
- be accessed in this way.</p>
- </item>
- <tag><c>file</c></tag>
- <item>
- <p>gives a pathname relative to the current
- directory. <c>../</c> cannot be used in this pathname, nor
- can absolute paths. As above, you can send other parsed
- documents, but you cannot send CGI scripts.</p>
- </item>
- </taglist>
- <p>The echo directive prints the value of one of the include
- variables (defined below). The only valid tag to this
- command is <c>var</c>, whose value is the name of the
- variable you wish to echo.</p>
- <p>The fsize directive prints the size of the specified
- file. Valid tags are the same as with the <c>include</c>
- command. The resulting format of this command is subject
- to the <c>sizefmt</c> parameter to the <c>config</c>
- command.</p>
- <p>The lastmod directive prints the last modification date of
- the specified file. Valid tags are the same as with the
- <c>include</c> command.</p>
- <p>The exec directive executes a given shell command or CGI
- script. Valid tags are:</p>
- <taglist>
- <tag><c>cmd</c></tag>
- <item>
- <p>executes the given string using <c>/bin/sh</c>. All
- of the variables defined below are defined, and can be
- used in the command.</p>
- </item>
- <tag><c>cgi</c></tag>
- <item>
- <p>executes the given virtual path to a CGI script and
- includes its output. The server does not perform error
- checking on the script output.</p>
- </item>
- </taglist>
- </section>
-
- <section>
- <marker id="ssi_environment_variables"></marker>
- <title>Server-Side Includes (SSI) Environment Variables</title>
- <p>A number of variables are made available to parsed
- documents. In addition to the CGI variable set, the following
- variables are made available:
- </p>
- <taglist>
- <tag><c>DOCUMENT_NAME</c></tag>
- <item>
- <p>The current filename.</p>
- </item>
- <tag><c>DOCUMENT_URI</c></tag>
- <item>
- <p>The virtual path to this document (such as
- <c>/docs/tutorials/foo.shtml</c>).</p>
- </item>
- <tag><c>QUERY_STRING_UNESCAPED</c></tag>
- <item>
- <p>The unescaped version of any search query the client
- sent, with all shell-special characters escaped with
- <c>\</c>.</p>
- </item>
- <tag><c>DATE_LOCAL</c></tag>
- <item>
- <p>The current date, local time zone.</p>
- </item>
- <tag><c>DATE_GMT</c></tag>
- <item>
- <p>Same as DATE_LOCAL but in Greenwich mean time.</p>
- </item>
- <tag><c>LAST_MODIFIED</c></tag>
- <item>
- <p>The last modification date of the current document.</p>
- </item>
- </taglist>
- </section>
- </section>
-
- <section>
- <title>The Erlang Web Server API</title>
- <p>The process of handling a HTTP request involves several steps
+ <title>Erlang Web Server API</title>
+ <p>The process of handling an HTTP request involves several steps,
such as:</p>
<list type="bulleted">
- <item>Seting up connections, sending and receiving data.</item>
- <item>URI to filename translation</item>
- <item>Authenication/access checks.</item>
- <item>Retriving/generating the response.</item>
- <item>Logging</item>
+ <item>Setting up connections, sending and receiving data.</item>
+ <item>URI to filename translation.</item>
+ <item>Authentication/access checks.</item>
+ <item>Retrieving/generating the response.</item>
+ <item>Logging.</item>
</list>
- <p>To provide customization and extensibility of the HTTP servers
- request handling most of these steps are handled by one or more
- modules that may be replaced or removed at runtime, and of course
- new ones can be added. For each request all modules will be
- traversed in the order specified by the modules directive in the
- server configuration file. Some parts mainly the communication
- related steps are considered server core functionality and are
- not implemented using the Erlang Web Server API. A description of
- functionality implemented by the Erlang Webserver API is described
- in the section Inets Webserver Modules.</p>
+ <p>To provide customization and extensibility of the request
+ handling of the HTTP servers, most of these steps are handled by
+ one or more modules. These modules can be replaced or removed at
+ runtime and new ones can be added. For each request, all modules are
+ traversed in the order specified by the module directive in the
+ server configuration file. Some parts, mainly the communication-
+ related steps, are considered server core functionality and are
+ not implemented using the Erlang web server API. A description of
+ functionality implemented by the Erlang webserver API is described
+ in <seealso marker="#Inets_Web_Server_Modules">Section
+ Inets Web Server Modules</seealso>.</p>
+
<p>A module can use data generated by previous modules in the
- Erlang Webserver API module sequence or generate data to be used
- by consecutive Erlang Web Server API modules. This is made
- possible due to an internal list of key-value tuples, also referred to
- as interaction data. </p>
+ Erlang webserver API module sequence or generate data to be used
+ by consecutive Erlang Web Server API modules. This is
+ possible owing to an internal list of key-value tuples, referred to
+ as interaction data.</p>
<note>
<p>Interaction data enforces module dependencies and
- should be avoided if possible. This means the order
- of modules in the Modules property is significant.</p>
+ is to be avoided if possible. This means that the order
+ of modules in the modules property is significant.</p>
</note>
<section>
<title>API Description</title>
- <p>Each module implements server functionality
- using the Erlang Web Server API should implement the following
+ <p>Each module that implements server functionality
+ using the Erlang web server API is to implement the following
call back functions:</p>
<list type="bulleted">
- <item>do/1 (mandatory) - the function called when
- a request should be handled.</item>
- <item>load/2</item>
- <item>store/2</item>
- <item>remove/1</item>
+ <item><c>do/1</c> (mandatory) - the function called when
+ a request is to be handled</item>
+ <item><c>load/2</c></item>
+ <item><c>store/2</c></item>
+ <item><c>remove/1</c></item>
</list>
<p>The latter functions are needed only when new config
- directives are to be introduced. For details see
- <seealso marker="httpd">httpd(3)</seealso></p>
+ directives are to be introduced. For details, see
+ <seealso marker="httpd">httpd(3)</seealso>.</p>
</section>
</section>
<section>
- <title>Inets Web Server Modules</title> <p>The convention is that
- all modules implementing some webserver functionality has the
- name mod_*. When configuring the web server an appropriate
- selection of these modules should be present in the Module
- directive. Please note that there are some interaction dependencies
- to take into account so the order of the modules can not be
- totally random.</p>
+ <title>Inets Web Server Modules</title>
+ <marker id="Inets_Web_Server_Modules"></marker>
+ <p>The convention is that
+ all modules implementing some web server functionality has the
+ name <c>mod_*</c>. When configuring the web server, an appropriate
+ selection of these modules is to be present in the module
+ directive. Notice that there are some interaction dependencies
+ to take into account, so the order of the modules cannot be
+ random.</p>
<section>
- <title>mod_action - Filetype/Method-Based Script Execution.</title>
- <p>Runs CGI scripts whenever a file of a
- certain type or HTTP method (See RFC 1945) is requested.
+ <title>mod_action - Filetype/Method-Based Script Execution</title>
+ <p>This module runs CGI scripts whenever a file of a
+ certain type or HTTP method (see
+ <url href="http://tools.ietf.org/html/rfc1945">RFC 1945</url>)
+ is requested.
</p>
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso>.</item>
</list>
<p>Exports the following Erlang Web Server API interaction data, if possible:
</p>
@@ -720,48 +546,51 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
<section>
<title>mod_alias - URL Aliasing</title>
- <p>This module makes it possible to map different parts of the
- host file system into the document tree e.i. creates aliases and
+ <p>The <seealso marker="mod_alias">mod_alias</seealso>
+ module makes it possible to map different parts of the
+ host file system into the document tree, that is, creates aliases and
redirections.</p>
<p>Exports the following Erlang Web Server API interaction data, if possible:
</p>
<taglist>
<tag><c>{real_name, PathData}</c></tag>
- <item>PathData is the argument used for API function mod_alias:path/3.</item>
+ <item><c>PathData</c> is the argument used for API function
+ <seealso marker="mod_alias#path/3">mod_alias:path/3</seealso>.</item>
</taglist>
</section>
<section>
- <title>mod_auth - User Authentication </title>
- <p>This module provides for basic user authentication using
- textual files, dets databases as well as mnesia databases.</p>
+ <title>mod_auth - User Authentication</title>
+ <p>The <seealso marker="mod_auth">mod_auth(3)</seealso>
+ module provides for basic user authentication using
+ textual files, <c>Dets</c> databases as well as <c>Mnesia</c> databases.</p>
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
<p>Exports the following Erlang Web Server API interaction data:
</p>
<taglist>
<tag><c>{remote_user, User}</c></tag>
- <item>The user name with which the user has authenticated himself.</item>
+ <item>The username used for authentication.</item>
</taglist>
<section>
- <title>Mnesia as Authentication Database</title>
+ <title>Mnesia As Authentication Database</title>
- <p> If Mnesia is used as storage method, Mnesia must be
- started prio to the HTTP server. The first time Mnesia is
- started the schema and the tables must be created before
- Mnesia is started. A naive example of a module with two
- functions that creates and start mnesia is provided
- here. The function shall be used the first
- time. first_start/0 creates the schema and the tables. The
- second function start/0 shall be used in consecutive
- startups. start/0 Starts Mnesia and wait for the tables to
+ <p>If <c>Mnesia</c> is used as storage method, <c>Mnesia</c> must be
+ started before the HTTP server. The first time <c>Mnesia</c> is
+ started, the schema and the tables must be created before
+ <c>Mnesia</c> is started. A simple example of a module with two
+ functions that creates and start <c>Mnesia</c> is provided
+ here. Function <c>first_start/0</c> is to be used the first
+ time. It creates the schema and the tables.
+ <c>start/0</c> is to be used in consecutive startups.
+ <c>start/0</c> starts <c>Mnesia</c> and waits for the tables to
be initiated. This function must only be used when the
- schema and the tables already is created. </p>
+ schema and the tables are already created.</p>
<code>
-module(mnesia_test).
@@ -785,28 +614,28 @@ first_start() ->
start() ->
mnesia:start(),
- mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
- </code>
+ mnesia:wait_for_tables([httpd_user, httpd_group], 60000). </code>
- <p>To create the Mnesia tables we use two records defined in
- mod_auth.hrl so the file must be included. The first
- function first_start/0 creates a schema that specify on
- which nodes the database shall reside. Then it starts Mnesia
- and creates the tables. The first argument is the name of
- the tables, the second argument is a list of options how the
- table will be created, see Mnesia documentation for more
- information. Since the current implementation of the
- mod_auth_mnesia saves one row for each user the type must be
- bag. When the schema and the tables is created the second
- function start/0 shall be used to start Mensia. It starts
- Mnesia and wait for the tables to be loaded. Mnesia use the
- directory specified as mnesia_dir at startup if specified,
- otherwise Mnesia use the current directory. For security
- reasons, make sure that the Mnesia tables are stored outside
- the document tree of the HTTP server. If it is placed in the
- directory which it protects, clients will be able to
- download the tables. Only the dets and mnesia storage
- methods allow writing of dynamic user data to disk. plain is
+ <p>To create the <c>Mnesia</c> tables, we use two records defined in
+ <c>mod_auth.hrl</c>, so that file must be included. <c>first_start/0</c>
+ creates a schema that specifies on which nodes the database is to reside.
+ Then it starts <c>Mnesia</c> and creates the tables. The first argument
+ is the name of the tables, the second argument is a list of options of
+ how to create the table, see
+ <seealso marker="mnesia:mnesia"><c>mnesia</c></seealso>, documentation for
+ more information. As the implementation of the <c>mod_auth_mnesia</c>
+ saves one row for each user, the type must be <c>bag</c>.
+ When the schema and the tables are created, function
+ <seealso marker="mnesia:mnesia#start-0">mnesia:start/0</seealso>
+ is used to start <c>Mnesia</c> and
+ waits for the tables to be loaded. <c>Mnesia</c> uses the
+ directory specified as <c>mnesia_dir</c> at startup if specified,
+ otherwise <c>Mnesia</c> uses the current directory. For security
+ reasons, ensure that the <c>Mnesia</c> tables are stored outside
+ the document tree of the HTTP server. If they are placed in the
+ directory which it protects, clients can download the tables.
+ Only the <c>Dets</c> and <c>Mnesia</c> storage
+ methods allow writing of dynamic user data to disk. <c>plain</c> is
a read only method.</p>
</section>
@@ -814,19 +643,19 @@ start() ->
<section>
<title>mod_cgi - CGI Scripts</title>
- <p>This module handles invoking of CGI scripts</p>
+ <p>This module handles invoking of CGI scripts.</p>
</section>
<section>
<title>mod_dir - Directories</title>
<p>This module generates an HTML directory listing
(Apache-style) if a client sends a request for a directory
- instead of a file. This module needs to be removed from the
+ instead of a file. This module must be removed from the
Modules config directive if directory listings is unwanted.</p>
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
<p>Exports the following Erlang Web Server API interaction data:
</p>
@@ -838,27 +667,27 @@ start() ->
</section>
<section>
- <title>mod_disk_log - Logging Using disk_log.</title>
+ <title>mod_disk_log - Logging Using Disk_Log.</title>
<p>Standard logging using the "Common Logfile Format" and
- disk_log(3).</p>
+ <seealso marker="kernel:disk_log">kernel:disk_log(3)</seealso>.</p>
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>remote_user - from mod_auth</item>
+ <item><c>remote_user</c> - from <c>mod_auth</c></item>
</list>
</section>
<section>
<title>mod_esi - Erlang Server Interface</title>
- <p>This module implements
- the Erlang Server Interface (ESI) that provides a tight and
- efficient interface to the execution of Erlang functions. </p>
- <p>Uses the following Erlang Web Server API interaction data:
+ <p>The <seealso marker="mod_esi">mod_esi(3)</seealso>
+ module implements the Erlang Server Interface (ESI) providing a
+ tight and efficient interface to the execution of Erlang functions.</p>
+ <p>Uses the following Erlang web server API interaction data:
</p>
<list type="bulleted">
- <item>remote_user - from mod_auth</item>
+ <item><c>remote_user</c> - from <c>mod_auth</c></item>
</list>
- <p>Exports the following Erlang Web Server API interaction data:
+ <p>Exports the following Erlang web server API interaction data:
</p>
<taglist>
<tag><c>{mime_type, MimeType}</c></tag>
@@ -870,11 +699,11 @@ start() ->
<section>
<title>mod_get - Regular GET Requests</title>
<p>This module is responsible for handling GET requests to regular
- files. GET requests for parts of files is handled by mod_range.</p>
- <p>Uses the following Erlang Web Server API interaction data:
+ files. GET requests for parts of files is handled by <c>mod_range</c>.</p>
+ <p>Uses the following Erlang web server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
</section>
@@ -886,7 +715,7 @@ start() ->
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
</section>
@@ -897,120 +726,97 @@ start() ->
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
<p>Exports the following Erlang Web Server API interaction data:
</p>
<taglist>
<tag><c>{remote_user_name, User}</c></tag>
- <item>The user name with which the user has authenticated himself.</item>
+ <item>The username used for authentication.</item>
</taglist>
</section>
- <section>
- <title>mod_include - SSI</title>
- <p>This module makes it possible to expand "macros" embedded in
- HTML pages before they are delivered to the client, that is
- Server-Side Includes (SSI).
- </p>
- <p>Uses the following Erlang Webserver API interaction data:
- </p>
- <list type="bulleted">
- <item>real_name - from mod_alias</item>
- <item>remote_user - from mod_auth</item>
- </list>
- <p>Exports the following Erlang Webserver API interaction data:
- </p>
- <taglist>
- <tag><c>{mime_type, MimeType}</c></tag>
- <item>The file suffix of the incoming URL mapped into a
- <c>MimeType</c> as defined in the Mime Type Settings
- section.</item>
- </taglist>
- </section>
-
<section>
<title>mod_log - Logging Using Text Files.</title>
<p>Standard logging using the "Common Logfile Format" and text
files.</p>
- <p>Uses the following Erlang Webserver API interaction data:
+ <p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>remote_user - from mod_auth</item>
+ <item><c>remote_user</c> - from <c>mod_auth</c></item>
</list>
</section>
<section>
<title>mod_range - Requests with Range Headers</title>
- <p>This module response to requests for one or many ranges of a
- file. This is especially useful when downloading large files,
- since a broken download may be resumed.</p>
- <p>Note that request for multiple parts of a document will report a
+ <p>This module responses to requests for one or many ranges of a
+ file. This is especially useful when downloading large files,
+ as a broken download can be resumed.</p>
+ <p>Notice that request for multiple parts of a document report a
size of zero to the log file.</p>
- <p>Uses the following Erlang Webserver API interaction data:
+ <p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
</section>
<section>
<title>mod_response_control - Requests with If* Headers</title>
- <p>This module controls that the conditions in the requests is
- fulfilled. For example a request may specify that the answer
- only is of interest if the content is unchanged since last
- retrieval. Or if the content is changed the range-request shall
- be converted to a request for the whole file instead.</p> <p>If
- a client sends more then one of the header fields that restricts
- the servers right to respond, the standard does not specify how
- this shall be handled. httpd will control each field in the
- following order and if one of the fields not match the current
- state the request will be rejected with a proper response.
- <br></br>
+ <p>This module controls that the conditions in the requests are
+ fulfilled. For example, a request can specify that the answer
+ only is of interest if the content is unchanged since the last
+ retrieval. If the content is changed, the range request is to
+ be converted to a request for the whole file instead.</p>
+ <p>If a client sends more than one of the header fields that
+ restricts the servers right to respond, the standard does not
+ specify how this is to be handled.
+ <seealso marker="httpd">httpd(3)</seealso> controls each
+ field in the following order and if one of the fields does not
+ match the current state, the request is rejected with a proper
+ response:</p>
+ <p><c>If-modified</c></p>
+ <p><c>If-Unmodified</c></p>
+ <p><c>If-Match</c></p>
+ <p><c>If-Nomatch</c></p>
- 1.If-modified <br></br>
-
- 2.If-Unmodified <br></br>
-
- 3.If-Match <br></br>
-
- 4.If-Nomatch <br></br>
-</p>
- <p>Uses the following Erlang Webserver API interaction data:
+ <p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
- <item>real_name - from mod_alias</item>
+ <item><c>real_name</c> - from <seealso marker="mod_alias">mod_alias</seealso></item>
</list>
- <p>Exports the following Erlang Webserver API interaction data:
+ <p>Exports the following Erlang Web Server API interaction data:
</p>
<taglist>
<tag><c>{if_range, send_file}</c></tag>
- <item>The conditions for the range request was not fulfilled.
+ <item>The conditions for the range request are not fulfilled.
The response must not be treated as a range request, instead it
- must be treated as a ordinary get request. </item>
+ must be treated as an ordinary get request.</item>
</taglist>
</section>
<section>
<title>mod_security - Security Filter</title>
- <p>This module serves as a filter for authenticated requests
- handled in mod_auth. It provides possibility to restrict users
- from access for a specified amount of time if they fail to
+ <p>The <seealso marker="mod_security">mod_security</seealso>
+ module serves as a filter for authenticated requests
+ handled in <seealso marker="mod_auth">mod_auth(3)</seealso>.
+ It provides a possibility to restrict users from
+ access for a specified amount of time if they fail to
authenticate several times. It logs failed authentication as
- well as blocking of users, and it also calls a configurable
- call-back module when the events occur. </p>
+ well as blocking of users, and it calls a configurable
+ callback module when the events occur.</p>
<p>There is also an
- API to manually block, unblock and list blocked users or users,
- who have been authenticated within a configurable amount of
- time.</p>
+ API to block or unblock users manually. This API can also list
+ blocked users or users who have been authenticated within a
+ configurable amount of time.</p>
</section>
<section>
<title>mod_trace - TRACE Request</title>
- <p>mod_trace is responsible for handling of TRACE requests.
+ <p><c>mod_trace</c> is responsible for handling of TRACE requests.
Trace is a new request method in HTTP/1.1. The intended use of
trace requests is for testing. The body of the trace response is
- the request message that the responding Web server or proxy
+ the request message that the responding web server or proxy
received.</p>
</section>
</section>
diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml
index acbd79b201..8e0301c520 100644
--- a/lib/inets/doc/src/http_uri.xml
+++ b/lib/inets/doc/src/http_uri.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2012</year><year>2013</year>
+ <year>2012</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -34,67 +35,90 @@
<description>
<p>This module provides utility functions for working with URIs,
- according to RFC 3986. </p>
-
+ according to
+ <url href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</url>.</p>
</description>
<section>
- <title>COMMON DATA TYPES </title>
+ <title>DATA TYPES</title>
<p>Type definitions that are used more than once in
this module:</p>
- <code type="none"><![CDATA[
-boolean() = true | false
-string() = list of ASCII characters
- ]]></code>
+ <p><c>boolean() = true | false</c></p>
+ <p><c>string()</c> = list of ASCII characters</p>
</section>
<section>
- <title>URI DATA TYPES </title>
+ <title>URI DATA TYPES</title>
<p>Type definitions that are related to URI:</p>
- <p>For more information about URI, see RFC 3986. </p>
-
- <code type="none"><![CDATA[
-uri() = string() - Syntax according to the URI definition in rfc 3986,
- e.g.: "http://www.erlang.org/"
-user_info() = string()
-scheme() = atom() - Example: http, https
-host() = string()
-port() = pos_integer()
-path() = string() - Representing a file path or directory path
-query() = string()
-fragment() = string()
- ]]></code>
-
+
+<taglist>
+ <tag><c>uri() = string()</c></tag>
+ <item><p>Syntax according to the URI definition in RFC 3986,
+ for example, "http://www.erlang.org/"</p></item>
+ <tag><c>user_info() = string()</c></tag>
+ <item><p></p></item>
+ <tag><c>scheme() = atom()</c></tag>
+ <item><p>Example: http, https</p></item>
+ <tag><c>host() = string()</c></tag>
+ <item><p></p></item>
+ <tag><c>port() = pos_integer()</c></tag>
+ <item><p></p></item>
+ <tag><c>path() = string()</c></tag>
+ <item><p>Represents a file path or directory path</p></item>
+ <tag><c>query() = string()</c></tag>
+ <item><p></p></item>
+ <tag><c>fragment() = string()</c></tag>
+ <item><p></p></item>
+ </taglist>
+
+ <p>For more information about URI, see
+ <url href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</url>.</p>
<marker id="scheme_defaults"></marker>
</section>
<funcs>
<func>
- <name>scheme_defaults() -> SchemeDefaults</name>
- <fsummary>A list of scheme and their default ports</fsummary>
+ <name>decode(HexEncodedURI) -> URI</name>
+
+ <fsummary>Decodes a hexadecimal encoded URI.</fsummary>
<type>
- <v>SchemeDefaults = [{scheme(), default_scheme_port_number()}] </v>
- <v>default_scheme_port_number() = pos_integer()</v>
+ <v>HexEncodedURI = string() - A possibly hexadecimal encoded URI</v>
+ <v>URI = uri()</v>
</type>
+
<desc>
- <p>This function provides a list of the scheme and their default
- port numbers currently supported (by default) by this utility. </p>
+ <p>Decodes a possibly hexadecimal encoded URI.</p>
- <marker id="parse"></marker>
+ </desc>
+ </func>
+ <func>
+ <name>encode(URI) -> HexEncodedURI</name>
+
+ <fsummary>Encodes a hexadecimal encoded URI.</fsummary>
+ <type>
+ <v>URI = uri()</v>
+ <v>HexEncodedURI = string() - Hexadecimal encoded URI</v>
+ </type>
+
+ <desc>
+ <p>Encodes a hexadecimal encoded URI.</p>
+
+ <marker id="decode"></marker>
</desc>
</func>
<func>
<name>parse(URI) -> {ok, Result} | {error, Reason}</name>
<name>parse(URI, Options) -> {ok, Result} | {error, Reason}</name>
- <fsummary>Parse an URI</fsummary>
+ <fsummary>Parses a URI.</fsummary>
<type>
- <v>URI = uri() </v>
- <v>Options = [Option] </v>
+ <v>URI = uri()</v>
+ <v>Options = [Option]</v>
<v>Option = {ipv6_host_with_brackets, boolean()} |
{scheme_defaults, scheme_defaults()} |
- {fragment, boolean()}]</v>
+ {fragment, boolean()} |
+ {schema_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>
@@ -103,62 +127,59 @@ fragment() = string()
<v>Path = path()</v>
<v>Query = query()</v>
<v>Fragment = fragment()</v>
- <v>Reason = term() </v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>This function is used to parse an URI. If no scheme defaults
- are provided, the value of
+ <p>Parses a URI. If no scheme defaults
+ are provided, the value of the
<seealso marker="#scheme_defaults">scheme_defaults</seealso>
- function will be used. </p>
+ function is used.</p>
- <p>Note that when parsing an URI with an unknown scheme (that is,
- a scheme not found in the scheme defaults) a port number must be
- provided or else the parsing will fail. </p>
+ <p>When parsing a URI with an unknown scheme (that is,
+ a scheme not found in the scheme defaults), a port number must be
+ provided, otherwise the parsing fails.</p>
- <p>If the fragment option is true, the URI fragment will be returned as
- part of the parsing result, otherwise it is completely ignored.</p>
+ <p>If the fragment option is <c>true</c>, the URI fragment is returned as
+ part of the parsing result, otherwise it is ignored.</p>
- <marker id="encode"></marker>
- </desc>
- </func>
+ <p>Scheme validation fun is to be defined as follows:</p>
- <func>
- <name>encode(URI) -> HexEncodedURI</name>
-
- <fsummary>Hex encode an URI</fsummary>
- <type>
- <v>URI = uri()</v>
- <v>HexEncodedURI = string() - Hex encoded uri</v>
- </type>
+ <code>
+fun(SchemeStr :: string()) ->
+ valid | {error, Reason :: term()}.
+ </code>
- <desc>
- <p>Hex encode an URI. </p>
+ <p>It is called before scheme string gets converted into scheme atom and
+ thus possible atom leak could be prevented</p>
- <marker id="decode"></marker>
+ <marker id="encode"></marker>
</desc>
</func>
<func>
- <name>decode(HexEncodedURI) -> URI</name>
-
- <fsummary>Decode a hex encoded URI</fsummary>
+ <name>scheme_defaults() -> SchemeDefaults</name>
+ <fsummary>A list of the scheme and their default ports.</fsummary>
<type>
- <v>HexEncodedURI = string() - A possibly hex encoded uri</v>
- <v>URI = uri()</v>
+ <v>SchemeDefaults = [{scheme(), default_scheme_port_number()}] </v>
+ <v>default_scheme_port_number() = pos_integer()</v>
</type>
-
<desc>
- <p>Decode a possibly hex encoded URI. </p>
+ <p>Provides a list of the scheme and their default
+ port numbers supported (by default) by this utility.</p>
+ <marker id="parse"></marker>
</desc>
</func>
+
+
</funcs>
<!--
<section>
<title>SEE ALSO</title>
- <p>RFC 2616, <seealso marker="inets">inets(3)</seealso>,
+ <p><url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>,
+ <seealso marker="inets">inets(3)</seealso>,
<seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>,
<seealso marker="ssl:ssl">ssl(3)</seealso>
</p>
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index 4178cb7d4c..ca9b268a03 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,143 +31,252 @@
</header>
<module>httpc</module>
- <modulesummary>An HTTP/1.1 client </modulesummary>
+ <modulesummary>An HTTP/1.1 client</modulesummary>
<description>
- <p>This module provides the API to a HTTP/1.1 compatible client according
- to RFC 2616, caching is currently not supported.</p>
+ <p>This module provides the API to an HTTP/1.1 compatible client according
+ to <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.
+ Caching is not supported.</p>
<note>
- <p>When starting the Inets application a manager process for the
- default profile will be started. The functions in this API
- that do not explicitly use a profile will access the
+ <p>When starting the <c>Inets</c> application, a manager process for the
+ default profile is started. The functions in this API
+ that do not explicitly use a profile accesses the
default profile. A profile keeps track of proxy options,
- cookies and other options that can be applied to more than one
- request. </p>
+ cookies, and other options that can be applied to more than one
+ request.</p>
- <p>If the scheme https is used the ssl application needs to be
- started. When https links needs to go through a proxy the
+ <p>If the scheme <c>https</c> is used, the <c>SSL</c> application must
+ be started. When <c>https</c> links need to go through a proxy, the
CONNECT method extension to HTTP-1.1 is used to establish a
- tunnel and then the connection is upgraded to TLS,
- however "TLS upgrade" according to RFC 2817 is not
+ tunnel and then the connection is upgraded to TLS.
+ However, "TLS upgrade" according to <url href="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817</url>is not
supported.</p>
- <p>Also note that pipelining will only be used if the pipeline
- timeout is set, otherwise persistent connections without
- pipelining will be used e.i. the client always waits for
+ <p>Pipelining is only used if the pipeline
+ time-out is set, otherwise persistent connections without
+ pipelining are used. That is, the client always waits for
the previous response before sending the next request.</p>
</note>
- <p>There are some usage examples in the <seealso
- marker="http_client">Inets User's Guide.</seealso></p>
+ <p>Some examples are provided in the <seealso
+ marker="http_client">Inets User's Guide</seealso>.</p>
</description>
<section>
- <title>COMMON DATA TYPES </title>
+ <title>DATA TYPES</title>
+ <marker id="DATA_TYPES"></marker>
<p>Type definitions that are used more than once in
this module:</p>
- <code type="none"><![CDATA[
-boolean() = true | false
-string() = list of ASCII characters
-request_id() = ref()
-profile() = atom()
-path() = string() representing a file path or directory path
-ip_address() = See inet(3)
-socket_opt() = See the Options used by gen_tcp(3) and
- ssl(3) connect(s)
- ]]></code>
-
+ <p><c>boolean() = true | false</c></p>
+ <p><c>string()</c> = list of ASCII characters</p>
+ <p><c>request_id() = ref()</c></p>
+ <p><c>profile() = atom()</c></p>
+ <p><c>path() = string()</c> representing a file path or directory path</p>
+ <p><c>ip_address()</c> = See the
+ <seealso marker="kernel:inet">inet(3)</seealso> manual page in <c>Kernel</c>.</p>
+ <p><c>socket_opt()</c> = See the options used by
+ <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso> <c>gen_tcp(3)</c> and
+ <seealso marker="ssl:ssl">ssl(3)</seealso> connect(s)</p>
+
</section>
<section>
- <title>HTTP DATA TYPES </title>
- <p>Type definitions that are related to HTTP:</p>
- <p>For more information about HTTP see rfc 2616</p>
-
- <code type="none"><![CDATA[
-method() = head | get | put | post | trace | options | delete
-request() = {url(), headers()} |
- {url(), headers(), content_type(), body()}
-url() = string() - Syntax according to the URI definition in rfc 2396, ex: "http://www.erlang.org"
-status_line() = {http_version(), status_code(), reason_phrase()}
-http_version() = string() ex: "HTTP/1.1"
-status_code() = integer()
-reason_phrase() = string()
-content_type() = string()
-headers() = [header()]
-header() = {field(), value()}
-field() = string()
-value() = string()
-body() = string() |
- binary() |
- {fun(accumulator()) -> body_processing_result(),
- accumulator()} |
- {chunkify,
- fun(accumulator()) -> body_processing_result(),
- accumulator()}
-body_processing_result() = eof | {ok, iolist(), accumulator()}
-accumulator() = term()
-filename() = string()
- ]]></code>
+ <title>HTTP DATA TYPES</title>
+ <p>Type definitions related to HTTP:</p>
- </section>
+ <p><c>method() = head | get | put | post | trace | options | delete</c></p>
+ <taglist>
+ <tag><c>request()</c></tag>
+ <item><p>= <c>{url(), headers()}</c></p>
+ <p>| <c>{url(), headers(), content_type(), body()}</c></p>
+ </item>
+ </taglist>
+ <p><c>url() = string()</c> syntax according to the URI definition in
+ <url href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</url>,
+ for example <c>"http://www.erlang.org"</c></p>
+ <p><c>status_line() = {http_version(), status_code(), reason_phrase()}</c></p>
+ <p><c>http_version() = string()</c>, for example, <c>"HTTP/1.1"</c></p>
+ <p><c>status_code() = integer()</c></p>
+ <p><c>reason_phrase() = string()</c></p>
+ <p><c>content_type() = string()</c></p>
+ <p><c>headers() = [header()]</c></p>
+ <p><c>header() = {field(), value()}</c></p>
+ <p><c>field() = string()</c></p>
+ <p><c>value() = string()</c></p>
+ <taglist>
+ <tag><c>body()</c></tag>
+ <item><p>= <c>string() | binary()</c></p>
+ <p>| <c>{fun(accumulator())</c></p>
+ <p><c> -> body_processing_result(), accumulator()}</c></p>
+ <p>| <c>{chunkify, fun(accumulator())</c></p>
+ <p><c> -> body_processing_result(), accumulator()}</c></p>
+ </item>
+ </taglist>
+ <p><c>body_processing_result() = eof | {ok, iolist(), accumulator()}</c></p>
+ <p><c>accumulator() = term()</c></p>
+ <p><c>filename() = string()</c></p>
+ <p>For more information about HTTP, see
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.</p>
+</section>
<section>
- <title>SSL DATA TYPES </title>
+ <title>SSL DATA TYPES</title>
<p>See <seealso marker="ssl:ssl">ssl(3)</seealso> for information
- about ssl options (<c>ssloptions()</c>). </p>
+ about <c>SSL</c> options (<c>ssloptions()</c>). </p>
</section>
<section>
- <title>HTTP CLIENT SERVICE START/STOP </title>
+ <title>HTTP CLIENT SERVICE START/STOP</title>
- <p>A HTTP client can be configured to start when starting the inets
+ <p>An HTTP client can be configured to start when starting the <c>Inets</c>
application or started dynamically in runtime by calling the
- inets application API <c>inets:start(httpc, ServiceConfig)</c>, or
- <c>inets:start(httpc, ServiceConfig, How)</c>
- see <seealso marker="inets">inets(3)</seealso>. Below follows a
- description of the available configuration options.</p>
+ <c>Inets</c> application API <c>inets:start(httpc, ServiceConfig)</c>
+ or <c>inets:start(httpc, ServiceConfig, How)</c>,
+ see <seealso marker="inets">inets(3)</seealso>.
+ The configuration options are as follows:</p>
<taglist>
<tag>{profile, profile()}</tag>
- <item>Name of the profile, see
- common data types below, this option is mandatory.</item>
+ <item><p>Name of the profile, see
+ <seealso marker="#DATA_TYPES">DATA TYPES</seealso>.
+ This option is mandatory.</p></item>
<tag>{data_dir, path()}</tag>
- <item>Directory where the profile
- may save persistent data, if omitted all cookies will be treated
- as session cookies.</item>
+ <item><p>Directory where the profile
+ can save persistent data. If omitted, all cookies are treated
+ as session cookies.</p></item>
</taglist>
<p>The client can be stopped using <c>inets:stop(httpc, Pid)</c> or
<c>inets:stop(httpc, Profile)</c>.</p>
-
- <marker id="request1"></marker>
</section>
<funcs>
+
+ <func>
+ <name>cancel_request(RequestId) -></name>
+ <name>cancel_request(RequestId, Profile) -> ok</name>
+ <fsummary>Cancels an asynchronous HTTP request.</fsummary>
+ <type>
+ <v>RequestId = request_id() - A unique identifier as returned
+ by request/4</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
+ </type>
+ <desc>
+ <p>Cancels an asynchronous HTTP request. Notice that this does not guarantee
+ that the request response is not delivered. Because it is asynchronous,
+ the request can already have been completed when the cancellation arrives.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>cookie_header(Url) -> </name>
+ <name>cookie_header(Url, Profile | Opts) -> header() | {error, Reason}</name>
+ <name>cookie_header(Url, Opts, Profile) -> header() | {error, Reason}</name>
+ <fsummary>Returns the cookie header that would have been sent when
+ making a request to URL using the profile <c>Profile</c>.</fsummary>
+ <type>
+ <v>Url = url()</v>
+ <v>Opts = [cookie_header_opt()]</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c>.</d>
+ <v>cookie_header_opt() = {ipv6_host_with_brackets, boolean()}</v>
+ </type>
+ <desc>
+ <p>Returns the cookie header that would have been sent
+ when making a request to <c>Url</c> using profile <c>Profile</c>.
+ If no profile is specified, the default profile is used.</p>
+ <p>Option <c>ipv6_host_with_bracket</c> deals with how to
+ parse IPv6 addresses. For details,
+ see argument <c>Options</c> of
+ <seealso marker="#request-4">request/[4,5]</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>get_options(OptionItems) -> {ok, Values} | {error, Reason}</name>
+ <name>get_options(OptionItems, Profile) -> {ok, Values} | {error, Reason}</name>
+ <fsummary>Gets the currently used options.</fsummary>
+ <type>
+ <v>OptionItems = all | [option_item()]</v>
+ <v>option_item() = proxy |
+ https_proxy |
+ max_sessions |
+ keep_alive_timeout |
+ max_keep_alive_length |
+ pipeline_timeout |
+ max_pipeline_length |
+ cookies |
+ ipfamily |
+ ip |
+ port |
+ socket_opts |
+ verbose</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can used.</d>
+ <v>Values = [{option_item(), term()}]</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Retrieves the options currently used by the client.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>info() -> list()</name>
+ <name>info(Profile) -> list()</name>
+ <fsummary>Produces a list of miscellaneous information.</fsummary>
+ <type>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
+ </type>
+ <desc>
+ <p>Produces a list of miscellaneous information.
+ Intended for debugging.
+ If no profile is specified, the default profile is used.</p>
+ </desc>
+ </func>
+
+
+ <func>
+ <name>reset_cookies() -> void()</name>
+ <name>reset_cookies(Profile) -> void()</name>
+ <fsummary>Resets the cookie database.</fsummary>
+ <type>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
+ </type>
+ <desc>
+ <p>Resets (clears) the cookie database for the specified
+ <c>Profile</c>. If no profile is specified the default profile
+ is used.</p>
+ </desc>
+ </func>
+
<func>
<name>request(Url) -> </name>
<name>request(Url, Profile) -> {ok, Result} | {error, Reason}</name>
- <fsummary>Sends a get HTTP-request</fsummary>
+ <fsummary>Sends a get HTTP request.</fsummary>
<type>
- <v>Url = url() </v>
+ <v>Url = url()</v>
<v>Result = {status_line(), headers(), Body} |
- {status_code(), Body} | request_id() </v>
+ {status_code(), Body} | request_id()</v>
<v>Body = string() | binary()</v>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
- <v>Reason = term() </v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
+ <v>Reason = term()</v>
</type>
<desc>
<p>Equivalent to <c>httpc:request(get, {Url, []}, [], [])</c>.</p>
-
- <marker id="request2"></marker>
</desc>
</func>
<func>
- <name>request(Method, Request, HTTPOptions, Options) -> </name>
+ <name>request(Method, Request, HTTPOptions, Options) -></name>
<name>request(Method, Request, HTTPOptions, Options, Profile) -> {ok, Result} | {ok, saved_to_file} | {error, Reason}</name>
- <fsummary>Sends a HTTP-request</fsummary>
+ <fsummary>Sends an HTTP request.</fsummary>
<type>
- <v>Method = method() </v>
+ <v>Method = method()</v>
<v>Request = request()</v>
<v>HTTPOptions = http_options()</v>
<v>http_options() = [http_option()]</v>
@@ -190,215 +300,200 @@ filename() = string()
{socket_opts, socket_opts()} |
{receiver, receiver()},
{ipv6_host_with_brackets, boolean()}}</v>
- <v>stream_to() = none | self | {self, once} | filename() </v>
+ <v>stream_to() = none | self | {self, once} | filename()</v>
<v>socket_opts() = [socket_opt()]</v>
- <v>receiver() = pid() | function()/1 | {Module, Function, Args} </v>
- <v>Module = atom() </v>
- <v>Function = atom() </v>
- <v>Args = list() </v>
- <v>body_format() = string | binary </v>
+ <v>receiver() = pid() | function()/1 | {Module, Function, Args}</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = list()</v>
+ <v>body_format() = string | binary</v>
<v>Result = {status_line(), headers(), Body} |
- {status_code(), Body} | request_id() </v>
+ {status_code(), Body} | request_id()</v>
<v>Body = string() | binary()</v>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
<v>Reason = {connect_failed, term()} |
- {send_failed, term()} | term() </v>
+ {send_failed, term()} | term()</v>
</type>
<desc>
- <p>Sends a HTTP-request. The function can be both synchronous
- and asynchronous. In the later case the function will return
- <c>{ok, RequestId}</c> and later on the information will be delivered
- to the <c>receiver</c> depending on that value. </p>
+ <p>Sends an HTTP request. The function can be both synchronous
+ and asynchronous. In the latter case, the function returns
+ <c>{ok, RequestId}</c> and then the information is delivered
+ to the <c>receiver</c> depending on that value.</p>
- <p>Http option (<c>http_option()</c>) details: </p>
+ <p>HTTP option (<c>http_option()</c>) details:</p>
<marker id="request2_http_options"></marker>
<taglist>
<tag><c><![CDATA[timeout]]></c></tag>
<item>
- <p>Timeout time for the request. </p>
- <p>The clock starts ticking as soon as the request has been
- sent. </p>
- <p>Time is in milliseconds. </p>
- <p>Defaults to <c>infinity</c>. </p>
+ <p>Time-out time for the request.</p>
+ <p>The clock starts ticking when the request is sent.</p>
+ <p>Time is in milliseconds.</p>
+ <p>Default is <c>infinity</c>.</p>
</item>
<tag><c><![CDATA[connect_timeout]]></c></tag>
<item>
- <p>Connection timeout time, used during the initial request,
- when the client is <em>connecting</em> to the server. </p>
- <p>Time is in milliseconds. </p>
- <p>Defaults to the value of the <c>timeout</c> option. </p>
+ <p>Connection time-out time, used during the initial request,
+ when the client is <em>connecting</em> to the server.</p>
+ <p>Time is in milliseconds.</p>
+ <p>Default is the value of option <c>timeout</c>.</p>
</item>
<tag><c><![CDATA[ssl]]></c></tag>
<item>
- <p>This is the default ssl config option, currently defaults to
- <c>essl</c>, see below. </p>
- <p>Defaults to <c>[]</c>. </p>
- </item>
-
- <tag><c><![CDATA[essl]]></c></tag>
- <item>
- <p>If using the Erlang based implementation of SSL,
- these SSL-specific options are used. </p>
- <p>Defaults to <c>[]</c>. </p>
+ <p>This is the <c>SSL/TLS</c> connectin configuration option.</p>
+ <p>Defaults to <c>[]</c>. See <seealso marker="ssl:ssl">ssl:connect/[2, 3,4]</seealso> for availble options.</p>
</item>
<tag><c><![CDATA[autoredirect]]></c></tag>
<item>
- <p>Should the client automatically retrieve the information
- from the new URI and return that as the result instead
- of a 30X-result code. </p>
- <p>Note that for some 30X-result codes automatic redirect
- is not allowed. In these cases the 30X-result will always
- be returned. </p>
- <p>Defaults to <c>true</c>. </p>
+ <p>The client automatically retrieves the information
+ from the new URI and returns that as the result, instead
+ of a 30X-result code.</p>
+ <p>For some 30X-result codes, automatic redirect
+ is not allowed. In these cases the 30X-result is always
+ returned.</p>
+ <p>Default is <c>true</c>.</p>
</item>
<tag><c><![CDATA[proxy_auth]]></c></tag>
<item>
- <p>A proxy-authorization header using the provided user name and
- password will be added to the request. </p>
+ <p>A proxy-authorization header using the provided username and
+ password is added to the request.</p>
</item>
<tag><c><![CDATA[version]]></c></tag>
<item>
<p>Can be used to make the client act as an <c>HTTP/1.0</c> or
<c>HTTP/0.9</c> client. By default this is an <c>HTTP/1.1</c>
- client. When using <c>HTTP/1.0</c> persistent connections will
- not be used. </p>
- <p>Defaults to the string <c>"HTTP/1.1"</c>. </p>
+ client. When using <c>HTTP/1.0</c> persistent connections are
+ not used.</p>
+ <p>Default is the string <c>"HTTP/1.1"</c>.</p>
</item>
<tag><c><![CDATA[relaxed]]></c></tag>
<item>
- <p>If set to <c>true</c> workarounds for known server deviations
- from the HTTP-standard are enabled. </p>
- <p>Defaults to <c>false</c>. </p>
+ <p>If set to <c>true</c>, workarounds for known server deviations
+ from the HTTP-standard are enabled.</p>
+ <p>Default is <c>false</c>.</p>
</item>
<tag><c><![CDATA[url_encode]]></c></tag>
<item>
- <p>Will apply Percent-encoding, also known as URL encoding on the
+ <p>Applies Percent-encoding, also known as URL encoding on the
URL.</p>
- <p>Defaults to <c>false</c>. </p>
+ <p>Default is <c>false</c>.</p>
</item>
</taglist>
- <p>Option (<c>option()</c>) details: </p>
+ <p>Option (<c>option()</c>) details:</p>
<taglist>
<tag><c><![CDATA[sync]]></c></tag>
<item>
- <p>Shall the request be synchronous or asynchronous. </p>
- <p>Defaults to <c>true</c>. </p>
+ <p>Option for the request to be synchronous or asynchronous.</p>
+ <p>Default is <c>true</c>.</p>
</item>
<tag><c><![CDATA[stream]]></c></tag>
<item>
<p>Streams the body of a 200 or 206 response to the calling
process or to a file. When streaming to the calling process
- using the option <c>self</c> the following stream messages
- will be sent to that process: <c>{http, {RequestId,
+ using option <c>self</c>, the following stream messages
+ are sent to that process: <c>{http, {RequestId,
stream_start, Headers}}, {http, {RequestId, stream,
- BinBodyPart}}, {http, {RequestId, stream_end, Headers}}</c>. When
- streaming to the calling processes using the option
- <c>{self, once}</c> the first message will have an additional
- element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}}</c>,
- this is the process id that should be used as an argument to
+ BinBodyPart}}, and {http, {RequestId, stream_end, Headers}}</c>.</p>
+ <p>When streaming to the calling processes using option
+ <c>{self, once}</c>, the first message has an extra
+ element, that is, <c>{http, {RequestId, stream_start, Headers, Pid}}</c>.
+ This is the process id to be used as an argument to
<c>http:stream_next/1</c> to trigger the next message to be sent to
- the calling process. </p>
- <p>Note that it is possible that chunked encoding will add
+ the calling process.</p>
+ <p>Notice that chunked encoding can add
headers so that there are more headers in the <c>stream_end</c>
- message than in the <c>stream_start</c>.
- When streaming to a file and the request is asynchronous the
- message <c>{http, {RequestId, saved_to_file}}</c> will be sent. </p>
- <p>Defaults to <c>none</c>. </p>
+ message than in <c>stream_start</c>.
+ When streaming to a file and the request is asynchronous, the
+ message <c>{http, {RequestId, saved_to_file}}</c> is sent.</p>
+ <p>Default is <c>none</c>.</p>
</item>
<tag><c><![CDATA[body_format]]></c></tag>
<item>
- <p>Defines if the body shall be delivered as a string or as a
+ <p>Defines if the body is to be delivered as a string or
binary. This option is only valid for the synchronous
- request. </p>
- <p>Defaults to <c>string</c>. </p>
+ request.</p>
+ <p>Default is <c>string</c>.</p>
</item>
<tag><c><![CDATA[full_result]]></c></tag>
<item>
- <p>Should a "full result" be returned to the caller (that is,
- the body, the headers and the entire status-line) or not
- (the body and the status code). </p>
- <p>Defaults to <c>true</c>. </p>
+ <p>Defines if a "full result" is to be returned to the caller (that is,
+ the body, the headers, and the entire status line) or not
+ (the body and the status code).</p>
+ <p>Default is <c>true</c>.</p>
</item>
<tag><c><![CDATA[headers_as_is]]></c></tag>
<item>
- <p>Shall the headers provided by the user be made
- lower case or be regarded as case sensitive. </p>
- <p>Note that the http standard requires them to be
- case insenstive. This feature should only be used if there is
+ <p>Defines if the headers provided by the user are to be made
+ lower case or to be regarded as case sensitive.</p>
+ <p>The HTTP standard requires them to be
+ case insensitive. Use this feature only if there is
no other way to communicate with the server or for testing
- purpose. Also note that when this option is used no headers
- will be automatically added, all necessary headers have to be
- provided by the user. </p>
- <p>Defaults to <c>false</c>. </p>
+ purpose. When this option is used, no headers
+ are automatically added. All necessary headers must be
+ provided by the user.</p>
+ <p>Default is <c>false</c>.</p>
</item>
<tag><c><![CDATA[socket_opts]]></c></tag>
<item>
<p>Socket options to be used for this and subsequent
- request(s). </p>
- <p>Overrides any value set by the
- <seealso marker="#set_options">set_options</seealso>
- function. </p>
- <p>Note that the validity of the options are <em>not</em>
- checked in any way. </p>
- <p>Note that this may change the socket behaviour
- (see <seealso marker="kernel:inet#setopts/2">inet:setopts/2</seealso>)
- for an already existing one, and therefore an already connected
- request handler. </p>
- <p>By default the socket options set by the
- <seealso marker="#set_options">set_options/1,2</seealso>
- function are used when establishing a connection. </p>
+ requests.</p>
+ <p>Overrides any value set by function
+ <seealso marker="#set_options-1">set_options</seealso>.</p>
+ <p>The validity of the options is <em>not</em> checked by
+ the HTTP client they are assumed to be correct and passed
+ on to ssl application and inet driver, which may reject
+ them if they are not correct. Note that the current
+ implementation assumes the requests to the same host, port
+ combination will use the same socket options.
+ </p>
+
+ <p>By default the socket options set by function
+ <seealso marker="#set_options-1">set_options/[1,2]</seealso>
+ are used when establishing a connection.</p>
</item>
<tag><c><![CDATA[receiver]]></c></tag>
<item>
- <p>Defines how the client will deliver the result of an
- asynchroneous request (<c>sync</c> has the value
- <c>false</c>). </p>
+ <p>Defines how the client delivers the result of an
+ asynchronous request (<c>sync</c> has the value
+ <c>false</c>).</p>
<taglist>
<tag><c><![CDATA[pid()]]></c></tag>
<item>
- <p>Message(s) will be sent to this process in the format: </p>
-<pre>
-{http, ReplyInfo}
-</pre>
+ <p>Messages are sent to this process in the format
+ <c>{http, ReplyInfo}</c>.</p>
</item>
<tag><c><![CDATA[function/1]]></c></tag>
<item>
- <p>Information will be delivered to the receiver via calls
- to the provided fun: </p>
-<pre>
-Receiver(ReplyInfo)
-</pre>
+ <p>Information is delivered to the receiver through calls
+ to the provided fun <c>Receiver(ReplyInfo)</c>.</p>
</item>
<tag><c><![CDATA[{Module, Function, Args}]]></c></tag>
<item>
- <p>Information will be delivered to the receiver via calls
- to the callback function: </p>
-<pre>
-apply(Module, Function, [ReplyInfo | Args])
-</pre>
+ <p>Information is delivered to the receiver through calls
+ to the callback function
+ <c>apply(Module, Function, [ReplyInfo | Args])</c>.</p>
</item>
-
</taglist>
- <p>In all of the above cases, <c>ReplyInfo</c> has the following
- structure: </p>
+ <p>In all of these cases, <c>ReplyInfo</c> has the following
+ structure:</p>
<pre>
{RequestId, saved_to_file}
@@ -406,11 +501,10 @@ apply(Module, Function, [ReplyInfo | Args])
{RequestId, Result}
{RequestId, stream_start, Headers}
{RequestId, stream_start, Headers, HandlerPid}
-{RequestId, stream, BinBodyPart}
-{RequestId, stream_end, Headers}
-</pre>
+{RequestId, stream, BinBodyPart}
+{RequestId, stream_end, Headers}</pre>
- <p>Defaults to the <c>pid()</c> of the process calling the request
+ <p>Default is the <c>pid</c> of the process calling the request
function (<c>self()</c>). </p>
<marker id="ipv6_host_with_brackets"></marker>
@@ -418,276 +512,178 @@ apply(Module, Function, [ReplyInfo | Args])
<tag><c><![CDATA[ipv6_host_with_brackets]]></c></tag>
<item>
- <p>When parsing the Host-Port part of an URI with a IPv6 address
- with brackets, shall we retain those brackets (<c>true</c>) or
- strip them (<c>false</c>). </p>
- <p>Defaults to <c>false</c>. </p>
+ <p>Defines when parsing the Host-Port part of an URI with an IPv6 address
+ with brackets, if those brackets are to be retained (<c>true</c>)
+ or stripped (<c>false</c>).</p>
+ <p>Default is <c>false</c>.</p>
</item>
</taglist>
-
- <marker id="cancel_request"></marker>
- </desc>
- </func>
-
- <func>
- <name>cancel_request(RequestId) -> </name>
- <name>cancel_request(RequestId, Profile) -> ok</name>
- <fsummary>Cancels an asynchronous HTTP-request.</fsummary>
- <type>
- <v>RequestId = request_id() - A unique identifier as returned
- by request/4</v>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
- </type>
- <desc>
- <p>Cancels an asynchronous HTTP-request. Note this does not guarantee
- that the request response will not be delivered, as it is asynchronous the
- the request may already have been completed when the cancellation arrives.
- </p>
-
- <marker id="set_options"></marker>
</desc>
</func>
+
<func>
<name>set_options(Options) -> </name>
<name>set_options(Options, Profile) -> ok | {error, Reason}</name>
<fsummary>Sets options to be used for subsequent requests.</fsummary>
<type>
<v>Options = [Option]</v>
- <v>Option = {proxy, {Proxy, NoProxy}} |
- {https_proxy, {Proxy, NoProxy}} |
- {max_sessions, MaxSessions} |
- {max_keep_alive_length, MaxKeepAlive} |
- {keep_alive_timeout, KeepAliveTimeout} |
- {max_pipeline_length, MaxPipeline} |
- {pipeline_timeout, PipelineTimeout} |
- {cookies, CookieMode} |
- {ipfamily, IpFamily} |
- {ip, IpAddress} |
- {port, Port} |
- {socket_opts, socket_opts()} |
- {verbose, VerboseMode} </v>
-
+ <v>Option = {proxy, {Proxy, NoProxy}}</v>
+ <v>| {https_proxy, {Proxy, NoProxy}}</v>
+ <v>| {max_sessions, MaxSessions}</v>
+ <v>| {max_keep_alive_length, MaxKeepAlive}</v>
+ <v>| {keep_alive_timeout, KeepAliveTimeout}</v>
+ <v>| {max_pipeline_length, MaxPipeline}</v>
+ <v>| {pipeline_timeout, PipelineTimeout}</v>
+ <v>| {cookies, CookieMode}</v>
+ <v>| {ipfamily, IpFamily}</v>
+ <v>| {ip, IpAddress}</v>
+ <v>| {port, Port}</v>
+ <v>| {socket_opts, socket_opts()}</v>
+ <v>| {verbose, VerboseMode}</v>
<v>Proxy = {Hostname, Port}</v>
- <v>Hostname = string() </v>
- <d>ex: "localhost" or "foo.bar.se"</d>
+ <v>Hostname = string()</v>
+ <d>Example: "localhost" or "foo.bar.se"</d>
<v>Port = integer()</v>
- <d>ex: 8080 </d>
+ <d>Example: 8080</d>
<v>NoProxy = [NoProxyDesc]</v>
<v>NoProxyDesc = DomainDesc | HostName | IPDesc</v>
<v>DomainDesc = "*.Domain"</v>
- <d>ex: "*.ericsson.se"</d>
+ <d>Example: "*.ericsson.se"</d>
<v>IpDesc = string()</v>
- <d>ex: "134.138" or "[FEDC:BA98" (all IP-addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP-address).</d>
-
- <d>proxy defaults to {undefined, []} e.i. no proxy is configured and https_proxy defaults to
- the value of proxy.</d>
-
- <v>MaxSessions = integer() </v>
- <d>Default is <c>2</c>.
- Maximum number of persistent connections to a host.</d>
- <v>MaxKeepAlive = integer() </v>
- <d>Default is <c>5</c>.
- Maximum number of outstanding requests on the same connection to
- a host.</d>
- <v>KeepAliveTimeout = integer() </v>
- <d>Default is <c>120000</c> (= 2 min).
- If a persistent connection is idle longer than the
+ <d>Example: "134.138" or "[FEDC:BA98"
+ (all IP addresses starting with 134.138 or FEDC:BA98),
+ "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP address).
+ <c>proxy</c> defaults to <c>{undefined, []}</c>,
+ that is, no proxy is configured and
+ <c>https_proxy</c> defaults to the value of <c>proxy</c>.</d>
+ <v>MaxSessions = integer()</v>
+ <d>Maximum number of persistent connections to a host.
+ Default is <c>2</c>.</d>
+ <v>MaxKeepAlive = integer()</v>
+ <d>Maximum number of outstanding requests on the same connection to
+ a host. Default is <c>5</c>.</d>
+ <v>KeepAliveTimeout = integer()</v>
+ <d>If a persistent connection is idle longer than the
<c>keep_alive_timeout</c> in milliseconds,
- the client will close the connection.
- The server may also have such a time out but you should
- not count on it!</d>
- <v>MaxPipeline = integer() </v>
- <d>Default is <c>2</c>.
- Maximum number of outstanding requests on a pipelined connection
- to a host.</d>
- <v>PipelineTimeout = integer() </v>
- <d>Default is <c>0</c>,
- which will result in pipelining not being used.
- If a persistent connection is idle longer than the
+ the client closes the connection.
+ The server can also have such a time-out but do not take that for granted.
+ Default is <c>120000</c> (= 2 min).</d>
+ <v>MaxPipeline = integer()</v>
+ <d>Maximum number of outstanding requests on a pipelined connection
+ to a host. Default is <c>2</c>.</d>
+ <v>PipelineTimeout = integer()</v>
+ <d>If a persistent connection is idle longer than the
<c>pipeline_timeout</c> in milliseconds,
- the client will close the connection. </d>
- <v>CookieMode = enabled | disabled | verify </v>
- <d>Default is <c>disabled</c>.
- If Cookies are enabled all valid cookies will automatically be
- saved in the client manager's cookie database.
- If the option <c>verify</c> is used the function <c>store_cookies/2</c>
- has to be called for the cookies to be saved.</d>
- <v>IpFamily = inet | inet6 | inet6fb4 </v>
- <d>By default <c>inet</c>.
- When it is set to <c>inet6fb4</c> you can use both ipv4 and ipv6.
- It first tries <c>inet6</c> and if that does not works falls back to <c>inet</c>.
- The option is here to provide a workaround for buggy ipv6 stacks to ensure that
- ipv4 will always work.</d>
- <v>IpAddress = ip_address() </v>
- <d>If the host has several network interfaces, this option specifies which one to use.
- See <seealso marker="kernel:gen_tcp#connect">gen_tcp:connect/3,4</seealso> for more info. </d>
- <v>Port = integer() </v>
- <d>Specify which local port number to use.
- See <seealso marker="kernel:gen_tcp#connect">gen_tcp:connect/3,4</seealso> for more info. </d>
+ the client closes the connection. Default is <c>0</c>,
+ which results in pipelining not being used.</d>
+ <v>CookieMode = enabled | disabled | verify</v>
+ <d>If cookies are enabled, all valid cookies are automatically
+ saved in the cookie database of the client manager.
+ If option <c>verify</c> is used, function <c>store_cookies/2</c>
+ has to be called for the cookies to be saved.
+ Default is <c>disabled</c>.</d>
+ <v>IpFamily = inet | inet6 </v>
+ <d>Default is <c>inet</c>.</d>
+ <v>IpAddress = ip_address()</v>
+ <d>If the host has several network interfaces, this option specifies
+ which one to use.
+ See <seealso marker="kernel:gen_tcp#connect">gen_tcp:connect/3,4</seealso>
+ for details.</d>
+ <v>Port = integer()</v>
+ <d>Local port number to use.
+ See <seealso marker="kernel:gen_tcp#connect">gen_tcp:connect/3,4</seealso>
+ for details.</d>
<v>socket_opts() = [socket_opt()]</v>
<d>The options are appended to the socket options used by the
- client. </d>
- <d>These are the default values when a new request handler
+ client.
+ These are the default values when a new request handler
is started (for the initial connect). They are passed directly
- to the underlying transport (gen_tcp or ssl) <em>without</em>
- verification! </d>
- <v>VerboseMode = false | verbose | debug | trace </v>
+ to the underlying transport (<c>gen_tcp</c> or <c>SSL</c>)
+ <em>without</em> verification.</d>
+ <v>VerboseMode = false | verbose | debug | trace</v>
<d>Default is <c>false</c>.
This option is used to switch on (or off)
- different levels of erlang trace on the client.
+ different levels of Erlang trace on the client.
It is a debug feature.</d>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
</type>
<desc>
<p>Sets options to be used for subsequent requests.</p>
<note>
- <p>If possible the client will keep its connections
- alive and use persistent connections
- with or without pipeline depending on configuration
+ <p>If possible, the client keeps its connections
+ alive and uses persistent connections
+ with or without pipeline depending on configuration
and current circumstances. The HTTP/1.1 specification does not
- provide a guideline for how many requests would be
- ideal to be sent on a persistent connection,
- this very much depends on the
- application. Note that a very long queue of requests may cause a
- user perceived delay as earlier requests may take a long time
- to complete. The HTTP/1.1 specification does suggest a
- limit of 2 persistent connections per server, which is the
- default value of the <c>max_sessions</c> option. </p>
+ provide a guideline for how many requests that are
+ ideal to be sent on a persistent connection.
+ This depends much on the application.</p>
+ <p>A long queue of requests can cause a
+ user-perceived delay, as earlier requests can take a long time
+ to complete. The HTTP/1.1 specification suggests a
+ limit of two persistent connections per server, which is the
+ default value of option <c>max_sessions</c>.</p>
</note>
<marker id="get_options"></marker>
</desc>
</func>
-
- <func>
- <name>get_options(OptionItems) -> {ok, Values} | {error, Reason}</name>
- <name>get_options(OptionItems, Profile) -> {ok, Values} | {error, Reason}</name>
- <fsummary>Gets the currently used options.</fsummary>
- <type>
- <v>OptionItems = all | [option_item()]</v>
- <v>option_item() = proxy |
- https_proxy
- max_sessions |
- keep_alive_timeout |
- max_keep_alive_length |
- pipeline_timeout |
- max_pipeline_length |
- cookies |
- ipfamily |
- ip |
- port |
- socket_opts |
- verbose</v>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
- <v>Values = [{option_item(), term()}]</v>
- <v>Reason = term() </v>
- </type>
- <desc>
- <p>Retrieves the options currently used by the client.</p>
-
- <marker id="stream_next"></marker>
- </desc>
- </func>
-
- <func>
- <name>stream_next(Pid) -> ok</name>
- <fsummary> Triggers the next message to be streamed, e.i.
- same behavior as active once for sockets.
- </fsummary>
- <type>
- <v>Pid = pid() - as received in the stream_start message</v>
- </type>
- <desc>
- <p>Triggers the next message to be streamed, e.i.
- same behavior as active once for sockets. </p>
-
- <marker id="verify_cookies"></marker>
- <marker id="store_cookies"></marker>
- </desc>
- </func>
-
+
<func>
<name>store_cookies(SetCookieHeaders, Url) -> </name>
<name>store_cookies(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
- <fsummary>Saves the cookies defined in SetCookieHeaders in the client profile's cookie database.</fsummary>
+ <fsummary>Saves the cookies defined in <c>SetCookieHeaders</c> in the
+ client profile cookie database.</fsummary>
<type>
<v>SetCookieHeaders = headers() - where field = "set-cookie"</v>
<v>Url = url()</v>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
- </type>
- <desc>
- <p>Saves the cookies defined in SetCookieHeaders
- in the client profile's cookie database. You need to
- call this function if you have set the option <c>cookies</c>
- to <c>verify</c>.
- If no profile is specified the default profile will be used. </p>
-
- <marker id="cookie_header"></marker>
- </desc>
- </func>
-
- <func>
- <name>cookie_header(Url) -> </name>
- <name>cookie_header(Url, Profile | Opts) -> header() | {error, Reason}</name>
- <name>cookie_header(Url, Opts, Profile) -> header() | {error, Reason}</name>
- <fsummary>Returns the cookie header that would be sent when
- making a request to Url using the profile <c>Profile</c>.</fsummary>
- <type>
- <v>Url = url()</v>
- <v>Opts = [cookie_header_opt()]</v>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
- <v>cookie_header_opt() = {ipv6_host_with_brackets, boolean()}</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
</type>
<desc>
- <p>Returns the cookie header that would be sent
- when making a request to <c>Url</c> using the profile <c>Profile</c>.
- If no profile is specified the default profile will be used. </p>
- <p>The option <c>ipv6_host_with_bracket</c> deals with how to
- parse IPv6 addresses.
- See the <c>Options</c> argument of the
- <seealso marker="#request2">request/4,5</seealso> for more info. </p>
-
- <marker id="reset_cookies"></marker>
+ <p>Saves the cookies defined in <c>SetCookieHeaders</c>
+ in the client profile cookie database.
+ Call this function if option <c>cookies</c> is set to <c>verify</c>.
+ If no profile is specified, the default profile is used.</p>
</desc>
</func>
-
<func>
- <name>reset_cookies() -> void()</name>
- <name>reset_cookies(Profile) -> void()</name>
- <fsummary>Reset the cookie database.</fsummary>
+ <name>stream_next(Pid) -> ok</name>
+ <fsummary>Triggers the next message to be streamed, that is,
+ the same behavior as active one for sockets.
+ </fsummary>
<type>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
+ <v>Pid = pid()</v>
+ <d>As received in the <c>stream_start message</c></d>
</type>
<desc>
- <p>Resets (clears) the cookie database for the specified
- <c>Profile</c>. If no profile is specified the default profile
- will be used. </p>
+ <p>Triggers the next message to be streamed, that is,
+ the same behavior as active ones for sockets.</p>
- <marker id="which_cookies"></marker>
+ <marker id="verify_cookies"></marker>
+ <marker id="store_cookies"></marker>
</desc>
</func>
-
-
+
<func>
<name>which_cookies() -> cookies()</name>
<name>which_cookies(Profile) -> cookies()</name>
- <fsummary>Dumps out the entire cookie database.</fsummary>
+ <fsummary>Dumps the entire cookie database.</fsummary>
<type>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
<v>cookies() = [cookie_stores()]</v>
<v>cookie_stores() = {cookies, cookies()} | {session_cookies, cookies()}</v>
<v>cookies() = [cookie()]</v>
<v>cookie() = term()</v>
</type>
<desc>
- <p>This function produces a list of the entire cookie database.
- It is intended for debugging/testing purposes.
- If no profile is specified the default profile will be used. </p>
-
- <marker id="which_sessions"></marker>
+ <p>Produces a list of the entire cookie database.
+ Intended for debugging/testing purposes.
+ If no profile is specified, the default profile is used.</p>
</desc>
</func>
@@ -696,41 +692,29 @@ apply(Module, Function, [ReplyInfo | Args])
<name>which_sessions(Profile) -> session_info()</name>
<fsummary>Produces a slightly processed dump of the sessions database.</fsummary>
<type>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
+ <v>Profile = profile() | pid()</v>
+ <d>When started <c>stand_alone</c> only the pid can be used.</d>
<v>session_info() = {GoodSessions, BadSessions, NonSessions}</v>
<v>GoodSessions = session()</v>
<v>BadSessions = tuple()</v>
<v>NonSessions = term()</v>
</type>
<desc>
- <p>This function produces a slightly processed dump of the session
+ <p>Produces a slightly processed dump of the session
database. It is intended for debugging.
- If no profile is specified the default profile will be used. </p>
-
- <marker id="info"></marker>
+ If no profile is specified, the default profile is used.</p>
</desc>
</func>
- <func>
- <name>info() -> list()</name>
- <name>info(Profile) -> list()</name>
- <fsummary>Produces a list of miscelleneous info</fsummary>
- <type>
- <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
- </type>
- <desc>
- <p>This function produces a list of miscelleneous info.
- It is intended for debugging.
- If no profile is specified the default profile will be used. </p>
- </desc>
- </func>
+
</funcs>
<section>
<title>SEE ALSO</title>
- <p>RFC 2616, <seealso marker="inets">inets(3)</seealso>,
- <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>,
- <seealso marker="ssl:ssl">ssl(3)</seealso>
+ <p><url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>,
+ <seealso marker="inets">inets(3)</seealso>,
+ <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>,
+ <seealso marker="ssl:ssl">ssl(3)</seealso>
</p>
</section>
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 435f99ee23..62b92b8356 100644
--- a/lib/inets/doc/src/httpd.xml
+++ b/lib/inets/doc/src/httpd.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -29,176 +30,182 @@
<file>httpd.sgml</file>
</header>
<module>httpd</module>
- <modulesummary>An implementation of an HTTP
- 1.1 compliant Web server, as defined in RFC 2616.
+ <modulesummary>
+ HTTP server API
</modulesummary>
<description>
- <p>Documents the HTTP server start options, some administrative
- functions and also specifies the Erlang Web server callback
- API</p>
+ <p>An implementation of an HTTP 1.1 compliant web server, as defined in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.
+ Provides web server start options, administrative functions, and
+ an Erlang callback API.</p>
</description>
<section>
- <title>COMMON DATA TYPES </title>
+ <title>DATA TYPES</title>
<p>Type definitions that are used more than once in
this module:</p>
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = list of ASCII characters</c></p>
- <p><c>path() = string() - representing a file or directory path.</c></p>
- <p><c> ip_address() = {N1,N2,N3,N4} % IPv4
+ <p><c>boolean() = true | false</c></p>
+ <p><c>string()</c> = list of ASCII characters</p>
+ <p><c>path() = string()</c> representing a file or a directory path</p>
+ <p><c> ip_address() = {N1,N2,N3,N4} % IPv4
| {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6</c></p>
- <p><c>hostname() = string() - representing a host ex "foo.bar.com"</c></p>
+ <p><c>hostname() = string()</c> representing a host, for example,
+ "foo.bar.com"</p>
<p><c>property() = atom()</c></p>
</section>
<section>
- <title>ERLANG HTTP SERVER SERVICE START/STOP </title>
- <p>A web server can be configured to start when starting the inets
- application or started dynamically in runtime by calling the
- Inets application API <c>inets:start(httpd, ServiceConfig)</c>, or
+ <title>ERLANG HTTP SERVER SERVICE START/STOP</title>
+ <p>A web server can be configured to start when starting the <c>Inets</c>
+ application, or dynamically in runtime by calling the
+ <c>Inets</c> application API <c>inets:start(httpd, ServiceConfig)</c> or
<c>inets:start(httpd, ServiceConfig, How)</c>,
- see <seealso marker="inets">inets(3)</seealso> Below follows a
- description of the available configuration options, also called
- properties.</p>
+ see <seealso marker="inets">inets(3)</seealso>.
+ The configuration options, also called
+ properties, are as follows:</p>
<marker id="props_file"></marker>
- <p><em>File properties</em></p>
+ <p><em>File Properties</em></p>
<p>When the web server is started
- at application start time the properties should be fetched from a
- configuration file that could consist of a regular erlang property
- list, e.i. <c>[{Option, Value}] </c> where <c> Option = property()
+ at application start time, the properties are to be fetched from a
+ configuration file that can consist of a regular Erlang property
+ list, that is, <c>[{Option, Value}]</c>, where <c> Option = property()
</c> and <c>Value = term()</c>, followed by a full stop, or for
- backwards compatibility an Apache like configuration file. If the
- web server is started dynamically at runtime you may still specify
- a file but you could also just specify the complete property
+ backwards compatibility, an Apache-like configuration file. If the
+ web server is started dynamically at runtime,
+ a file can still be specified but also the complete property
list.</p>
<taglist>
- <marker id="prop_proplist_file"></marker>
- <tag>{proplist_file, path()}</tag>
+ <tag><marker id="prop_proplist_file"></marker>{proplist_file, path()}</tag>
<item>
- <p>If this property is defined inets will expect to find
- all other properties defined in this file. Note that the
+ <p>If this property is defined, <c>Inets</c> expects to find
+ all other properties defined in this file. The
file must include all properties listed under mandatory
- properties. </p>
+ properties.</p>
</item>
- <marker id="prop_file"></marker>
- <tag>{file, path()}</tag>
+ <tag><marker id="prop_file"></marker>{file, path()}</tag>
<item>
- <p>If this property is defined inets will expect to find all
- other properties defined in this file, that uses Apache like
- syntax. Note that the file must include all properties listed
- under mandatory properties. The Apache like syntax is the property,
+ <p>If this property is defined, <c>Inets</c> expects to find all
+ other properties defined in this file, which uses Apache-like
+ syntax. The file must include all properties listed
+ under mandatory properties. The Apache-like syntax is the property,
written as one word where each new word begins with a capital,
- followed by a white-space followed by the value followed by a
- new line. Ex: </p>
-
+ followed by a white-space, followed by the value, followed by a
+ new line.</p>
+ <p>Example:</p>
<code>
-{server_root, "/urs/local/www"} -> ServerRoot /usr/local/www
- </code>
+{server_root, "/urs/local/www"} -> ServerRoot /usr/local/www</code>
- <p>With a few exceptions, that are documented
+ <p>A few exceptions are documented
for each property that behaves differently,
- and the special case {directory, {path(), PropertyList}} and
- {security_directory, {Dir, PropertyList}} that are represented
+ and the special cases <c>{directory, {path(), PropertyList}}</c>
+ and <c>{security_directory, {Dir, PropertyList}}</c>, are represented
as:</p>
<pre>
<![CDATA[
<Directory Dir>
<Properties handled as described above>
</Directory>
- ]]>
- </pre>
+ ]]></pre>
</item>
</taglist>
<note>
- <p>The properties proplist_file and file are mutually exclusive.</p>
+ <p>The properties <c>proplist_file</c> and <c>file</c> are mutually exclusive. Also newer properties may not be supported as Apache-like options, this is a legacy feature.</p>
</note>
<marker id="props_mand"></marker>
- <p><em>Mandatory properties</em></p>
+ <p><em>Mandatory Properties</em></p>
<taglist>
- <marker id="prop_port"></marker>
- <tag>{port, integer()} </tag>
+ <tag><marker id="prop_port"></marker>{port, integer()} </tag>
<item>
- <p>The port that the HTTP server shall listen on.
+ <p>The port that the HTTP server listen to.
If zero is specified as port, an arbitrary available port
- will be picked and you can use the httpd:info/2 function to find
- out which port was picked. </p>
+ is picked and function <c>httpd:info/2</c> can be used to
+ determine which port was picked.</p>
</item>
- <marker id="prop_server_name"></marker>
- <tag>{server_name, string()} </tag>
+ <tag><marker id="prop_server_name"></marker>{server_name, string()}</tag>
<item>
- <p>The name of your server, normally a fully qualified domain name. </p>
+ <p>The name of your server, normally a fully qualified domain name.</p>
</item>
- <marker id="prop_server_root"></marker>
- <tag>{server_root, path()} </tag>
+ <tag><marker id="prop_server_root"></marker>{server_root, path()}</tag>
<item>
- <p>Defines the server's home directory where log files etc can
- be stored. Relative paths specified in other properties refer
- to this directory. </p>
+ <p>Defines the home directory of the server, where log files, and so on,
+ can be stored. Relative paths specified in other properties refer
+ to this directory.</p>
</item>
- <marker id="prop_doc_root"></marker>
- <tag>{document_root, path()}</tag>
+ <tag> <marker id="prop_doc_root"></marker>{document_root, path()}</tag>
<item>
- Defines the top directory for the documents that
- are available on the HTTP server.
+ <p>Defines the top directory for the documents that
+ are available on the HTTP server.</p>
</item>
</taglist>
<marker id="props_comm"></marker>
- <p><em>Communication properties</em> </p>
+ <p><em>Communication Properties</em></p>
<taglist>
- <marker id="prop_bind_address"></marker>
- <tag>{bind_address, ip_address() | hostname() | any} </tag>
+ <tag><marker id="prop_bind_address"></marker>{bind_address, ip_address() | hostname() | any}</tag>
+ <item>
+ <p>Default is <c>any</c>. <c>any</c> is denoted <em>*</em>
+ in the Apache-like configuration file.</p>
+ </item>
+
+ <tag><marker id="profile"></marker>{profile, atom()}</tag>
<item>
- <p>Defaults to <c>any</c>. Note that <c>any</c> is denoted <em>*</em>
- in the apache like configuration file. </p>
+ <p>Used together with <seealso marker="#prop_bind_address"><c>bind_address</c></seealso>
+ and <seealso marker="#prop_port"><c>port</c></seealso> to uniquely identify
+ a HTTP server. This can be useful in a virtualized environment,
+ where there can
+ be more that one server that has the same bind_address and port.
+ If this property is not explicitly set, it is assumed that the
+ <seealso marker="#prop_bind_address"><c>bind_address</c></seealso> and
+ <seealso marker="#prop_port"><c>port</c></seealso>uniquely identifies the HTTP server.
+ </p>
</item>
- <marker id="prop_socket_type"></marker>
- <tag>{socket_type, ip_comm | {essl, Config::proplist()}}</tag>
+ <tag><marker id="prop_socket_type"></marker>{socket_type, ip_comm | {ip_comm, Config::proplist()} | {essl, Config::proplist()}}</tag>
<item>
- <p> For ssl configuration options see <seealso marker="ssl:ssl#listen-2">ssl:listen/2</seealso> </p>
- <p>Defaults to <c>ip_comm</c>. </p>
+ <p>For <c>ip_comm</c> configuration options, see
+ <seealso marker="kernel:gen_tcp#listen-2">gen_tcp:listen/2</seealso>, some options
+ that are used internally by httpd can not be set.</p>
+ <p>For <c>SSL</c> configuration options, see
+ <seealso marker="ssl:ssl#listen-2">ssl:listen/2</seealso>.</p>
+ <p>Default is <c>ip_comm</c>.</p>
</item>
- <marker id="prop_ipfamily"></marker>
- <tag>{ipfamily, inet | inet6 | inet6fb4}</tag>
+ <tag><marker id="prop_ipfamily"></marker>{ipfamily, inet | inet6}</tag>
<item>
- <p>Defaults to <c>inet6fb4. </c> </p>
- <p>Note that this option is only used when the option
- <c>socket_type</c> has the value <c>ip_comm</c>. </p>
+ <p>Default is <c>inet</c>, legacy option <c>inet6fb4</c> no longer makes sense and will be translated
+ to inet.</p>
</item>
- <marker id="prop_minimum_bytes_per_second"></marker>
- <tag>{minimum_bytes_per_second, integer()}</tag>
+
+ <tag><marker id="prop_minimum_bytes_per_second"></marker>{minimum_bytes_per_second, integer()}</tag>
<item>
- <p>If given, sets a minimum bytes per second value for connections.</p>
- <p>If the value is not reached, the socket will close for that connection.</p>
- <p>The option is good for reducing the risk of "slow dos" attacks.</p>
+ <p>If given, sets a minimum of bytes per second value for connections.</p>
+ <p>If the value is unreached, the socket closes for that connection.</p>
+ <p>The option is good for reducing the risk of "slow DoS" attacks.</p>
</item>
</taglist>
<marker id="props_api_modules"></marker>
- <p><em>Erlang Web server API modules</em> </p>
+ <p><em>Erlang Web Server API Modules</em> </p>
<taglist>
- <marker id="prop_modules"></marker>
- <tag>{modules, [atom()]} </tag>
+ <tag><marker id="prop_modules"></marker>{modules, [atom()]} </tag>
<item>
- <p>Defines which modules the HTTP server will use to handle
- requests. Defaults to: <c>[mod_alias, mod_auth, mod_esi,
+ <p>Defines which modules the HTTP server uses when handling
+ requests. Default is <c>[mod_alias, mod_auth, mod_esi,
mod_actions, mod_cgi, mod_dir, mod_get, mod_head, mod_log,
- mod_disk_log] </c>
- Note that some mod-modules are dependent on
- others, so the order can not be entirely arbitrary. See the
- <seealso marker="http_server"> Inets Web server Modules in the
- Users guide</seealso> for more information. </p>
+ mod_disk_log]</c>.
+ Notice that some <c>mod</c>-modules are dependent on
+ others, so the order cannot be entirely arbitrary. See the
+ <seealso marker="http_server">Inets Web Server Modules</seealso> in the
+ User's Guide for details.</p>
</item>
</taglist>
@@ -206,760 +213,709 @@
<p><em>Limit properties</em> </p>
<taglist>
- <marker id="prop_customize"></marker>
- <tag>{customize, atom()}</tag>
+ <tag><marker id="prop_customize"></marker>{customize, atom()}</tag>
<item>
<p>A callback module to customize the inets HTTP servers behaviour
- see <seealso marker="http_custom_api"> httpd_custom_api</seealso> </p>
+ see <seealso marker="httpd_custom_api"> httpd_custom_api</seealso> </p>
</item>
- <marker id="prop_disable_chunked_encoding"></marker>
- <tag>{disable_chunked_transfer_encoding_send, boolean()}</tag>
+ <tag><marker id="prop_disable_chunked_encoding"></marker>{disable_chunked_transfer_encoding_send, boolean()}</tag>
<item>
- <p>This property allows you to disable chunked
- transfer-encoding when sending a response to a HTTP/1.1
- client, by default this is false. </p>
+ <p>Allows you to disable chunked
+ transfer-encoding when sending a response to an HTTP/1.1
+ client. Default is <c>false</c>.</p>
</item>
- <marker id="prop_keep_alive"></marker>
- <tag>{keep_alive, boolean()}</tag>
+ <tag><marker id="prop_keep_alive"></marker>{keep_alive, boolean()}</tag>
<item>
- <p>Instructs the server whether or not to use persistent
+ <p>Instructs the server whether to use persistent
connections when the client claims to be HTTP/1.1
- compliant, default is true. </p>
+ compliant. Default is <c>true</c>.</p>
</item>
- <marker id="prop_keep_alive_timeout"></marker>
- <tag>{keep_alive_timeout, integer()}</tag>
+ <tag><marker id="prop_keep_alive_timeout"></marker>{keep_alive_timeout, integer()}</tag>
<item>
- <p>The number of seconds the server will wait for a
+ <p>The number of seconds the server waits for a
subsequent request from the client before closing the
- connection. Default is 150. </p>
+ connection. Default is <c>150</c>.</p>
</item>
- <marker id="prop_max_body_size"></marker>
- <tag>{max_body_size, integer()}</tag>
+ <tag><marker id="prop_max_body_size"></marker>{max_body_size, integer()}</tag>
<item>
- <p>Limits the size of the message body of HTTP request.
- By the default there is no limit. </p>
+ <p>Limits the size of the message body of an HTTP request.
+ Default is no limit.</p>
</item>
- <marker id="prop_max_clients"></marker>
- <tag>{max_clients, integer()}</tag>
+ <tag><marker id="prop_max_clients"></marker>{max_clients, integer()}</tag>
<item>
<p>Limits the number of simultaneous requests that can be
- supported. Defaults to 150. </p>
+ supported. Default is <c>150</c>.</p>
</item>
- <marker id="prop_max_header_size"></marker>
- <tag>{max_header_size, integer()}</tag>
+ <tag><marker id="prop_max_header_size"></marker>{max_header_size, integer()}</tag>
<item>
- <p>Limits the size of the message header of HTTP request.
- Defaults to 10240. </p>
+ <p>Limits the size of the message header of an HTTP request.
+ Default is <c>10240</c>.</p>
</item>
- <marker id="prop_max_content_length"></marker>
- <tag>{max_content_length, integer()}</tag>
+ <tag><marker id="prop_max_content_length"></marker>{max_content_length, integer()}</tag>
<item>
- <p>Maximum Content-Length in an incoming request, in bytes. Requests
- with content larger than this are answered with Status 413.
- Defaults to 100000000 (100 MB).
+ <p>Maximum content-length in an incoming request, in bytes. Requests
+ with content larger than this are answered with status 413.
+ Default is <c>100000000</c> (100 MB).
</p>
</item>
- <marker id="prop_max_uri"></marker>
- <tag>{max_uri_size, integer()}</tag>
+ <tag><marker id="prop_max_uri"></marker>{max_uri_size, integer()}</tag>
<item>
- <p>Limits the size of the HTTP request URI. By
- default there is no limit. </p>
+ <p>Limits the size of the HTTP request URI.
+ Default is no limit.</p>
</item>
- <marker id="prop_max_keep_alive_req"></marker>
- <tag>{max_keep_alive_request, integer()}</tag>
+ <tag><marker id="prop_max_keep_alive_req"></marker>{max_keep_alive_request, integer()}</tag>
<item>
- <p>The number of request that a client can do on one
+ <p>The number of requests that a client can do on one
connection. When the server has responded to the number of
- requests defined by max_keep_alive_requests the server close the
- connection. The server will close it even if there are queued
- request. Defaults to no limit. </p>
+ requests defined by <c>max_keep_alive_requests</c>, the server
+ closes the connection. The server closes it even if there are
+ queued request. Default is no limit.</p>
</item>
</taglist>
<marker id="props_admin"></marker>
- <p><em>Administrative properties</em></p>
+ <p><em>Administrative Properties</em></p>
<taglist>
- <marker id="prop_mime_types"></marker>
- <tag>{mime_types, [{MimeType, Extension}] | path()}</tag>
+ <tag><marker id="prop_mime_types"></marker>{mime_types, [{MimeType, Extension}] | path()}</tag>
<item>
- <p>Where MimeType = string() and Extension = string().
+ <p><c>MimeType = string()</c> and <c>Extension = string()</c>.
Files delivered to the client are MIME typed according to RFC
1590. File suffixes are mapped to MIME types before file delivery.
The mapping between file suffixes and MIME types can be specified
- as an Apache like file as well as directly in the property list. Such
- a file may look like:</p>
+ as an Apache-like file or directly in the property list. Such
+ a file can look like the follwoing:</p>
<pre>
# MIME type Extension
text/html html htm
-text/plain asc txt
- </pre>
+text/plain asc txt</pre>
- <p>Defaults to [{"html","text/html"},{"htm","text/html"}]</p>
+ <p>Default is [{"html","text/html"},{"htm","text/html"}].</p>
</item>
- <marker id="prop_mime_type"></marker>
- <tag>{mime_type, string()}</tag>
+ <tag><marker id="prop_mime_type"></marker>{mime_type, string()}</tag>
<item>
- <p>When the server is asked to provide a document type which
- cannot be determined by the MIME Type Settings, the server will
- use this default type. </p>
+ <p>When the server is asked to provide a document type that
+ cannot be determined by the MIME Type Settings, the server
+ uses this default type.</p>
</item>
- <marker id="prop_server_admin"></marker>
- <tag>{server_admin, string()}</tag>
+ <tag><marker id="prop_server_admin"></marker>{server_admin, string()}</tag>
<item>
- <p>ServerAdmin defines the email-address of the server
- administrator, to be included in any error messages returned by
- the server. </p>
+ <p>Defines the email-address of the server
+ administrator to be included in any error messages returned by
+ the server.</p>
</item>
- <marker id="prop_server_tokens"></marker>
- <tag>{server_tokens, none|prod|major|minor|minimal|os|full|{private, string()}}</tag>
+ <tag><marker id="prop_server_tokens"></marker>{server_tokens, none|prod|major|minor|minimal|os|full|{private, string()}}</tag>
<item>
- <p>ServerTokens defines how the value of the server header
- should look. </p>
- <p>Example: Assuming the version of inets is 5.8.1,
- here is what the server header string could look like for
- the different values of server-tokens: </p>
- <pre>
-none "" % A Server: header will not be generated
-prod "inets"
-major "inets/5"
-minor "inets/5.8"
-minimal "inets/5.8.1"
-os "inets/5.8.1 (unix)"
-full "inets/5.8.1 (unix/linux) OTP/R15B"
-{private, "foo/bar"} "foo/bar"
- </pre>
- <p>By default, the value is as before, which is <c>minimal</c>. </p>
- </item>
-
- <marker id="prop_log_format"></marker>
- <tag>{log_format, common | combined}</tag>
+ <p>Defines the look of the value of the server header.</p>
+ <p>Example: Assuming the version of <c>Inets</c> is 5.8.1,
+ the server header string can look as follows for
+ the different values of server-tokens:</p>
+ <taglist>
+ <tag><c>none</c></tag>
+ <item><p>"" % A Server: header will not be generated</p></item>
+ <tag><c>prod</c></tag>
+ <item><p>"inets"</p></item>
+ <tag><c>major</c></tag>
+ <item><p>"inets/5"</p></item>
+ <tag><c>minor</c></tag>
+ <item><p>"inets/5.8"</p></item>
+ <tag><c>minimal</c></tag>
+ <item><p>"inets/5.8.1"</p></item>
+ <tag><c>os</c></tag>
+ <item><p>"inets/5.8.1 (unix)"</p></item>
+ <tag><c>full</c></tag>
+ <item><p>"inets/5.8.1 (unix/linux) OTP/R15B"</p></item>
+ <tag><c>{private, "foo/bar"}</c></tag>
+ <item><p>"foo/bar"</p></item>
+ </taglist>
+ <p>By default, the value is as before, that is, <c>minimal</c>.</p>
+ </item>
+
+ <tag><marker id="prop_log_format"></marker>{log_format, common | combined}</tag>
<item>
- <p>Defines if access logs should be written according to the common
- log format or to the extended common log format.
- The <c>common</c> format is one line that looks like this:
- <c>remotehost rfc931 authuser [date] "request" status bytes</c></p>
-
- <pre>
-remotehost
- Remote
-rfc931
- The client's remote username (RFC 931).
-authuser
- The username with which the user authenticated
- himself.
-[date]
- Date and time of the request (RFC 1123).
-"request"
- The request line exactly as it came from the client
- (RFC 1945).
-status
- The HTTP status code returned to the client
- (RFC 1945).
-bytes
- The content-length of the document transferred.
- </pre>
-
- <p>The <c>combined</c> format is on line that look like this:
+ <p>Defines if access logs are to be written according to the <c>common</c>
+ log format or the extended common log format.
+ The <c>common</c> format is one line looking like this:
+ <c>remotehost rfc931 authuser [date] "request" status bytes</c>.</p>
+ <p>Here:</p>
+ <taglist>
+ <tag><c>remotehost</c></tag>
+ <item>Remote.</item>
+ <tag><c>rfc931</c></tag>
+ <item>The remote username of the client (<url href="http://www.ietf.org/rfc/rfc931.txt">RFC 931</url>).</item>
+ <tag><c>authuser</c></tag>
+ <item>The username used for authentication.</item>
+ <tag><c>[date]</c></tag>
+ <item>Date and time of the request (<url href="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</url>).</item>
+ <tag><c>"request"</c></tag>
+ <item>The request line as it came from the client (<url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>).</item>
+ <tag><c>status</c></tag>
+ <item>The HTTP status code returned to the client (<url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>).</item>
+ <tag><c>bytes</c></tag>
+ <item>The content-length of the document transferred.</item>
+ </taglist>
+
+ <p>The <c>combined</c> format is one line looking like this:
<c>remotehost rfc931 authuser [date] "request" status bytes "referer" "user_agent" </c></p>
+ <p>In addition to the earlier:</p>
+ <taglist>
+ <tag><c>"referer"</c></tag>
+ <item>The URL the client was on before
+ requesting the URL (if it could not be determined,
+ a minus sign is placed in this field).</item>
+ <tag><c>"user_agent"</c></tag>
+ <item>The software the client claims to be using (if it
+ could not be determined, a minus sign is placed in
+ this field).</item>
+ </taglist>
- <pre>
-"referer"
- The url the client was on before
- requesting your url. (If it could not be determined
- a minus sign will be placed in this field)
-"user_agent"
- The software the client claims to be using. (If it
- could not be determined a minus sign will be placed in
- this field)
- </pre>
-
- <p>This affects the access logs written by mod_log and mod_disk_log.
- </p>
-
+ <p>This affects the access logs written by <c>mod_log</c> and
+ <c>mod_disk_log</c>.
+ </p>
</item>
- <marker id="prop_elog_format"></marker>
- <tag>{error_log_format, pretty | compact}</tag>
+ <tag><marker id="prop_elog_format"></marker>{error_log_format, pretty | compact}</tag>
<item>
- <p>Defaults to pretty. If the error log is meant to be read
- directly by a human <c>pretty</c> will be the best
- option. <c>pretty</c> has the format corresponding to:
- </p>
+ <p>Default is <c>pretty</c>. If the error log is meant to be read
+ directly by a human, <c>pretty</c> is the best option.</p>
+ <p><c>pretty</c> has a format corresponding to:</p>
- <code>io:format("[~s] ~s, reason: ~n ~p ~n~n", [Date, Msg, Reason]).
- </code>
+ <code>io:format("[~s] ~s, reason: ~n ~p ~n~n", [Date, Msg, Reason]).</code>
- <p><c>compact</c> has the format corresponding to:</p>
+ <p><c>compact</c> has a format corresponding to:</p>
- <code>io:format("[~s] ~s, reason: ~w ~n", [Date, Msg, Reason]).
- </code>
+ <code>io:format("[~s] ~s, reason: ~w ~n", [Date, Msg, Reason]).</code>
- <p>This affects the error logs written by mod_log and mod_disk_log.
+ <p>This affects the error logs written by <c>mod_log</c> and
+ <c>mod_disk_log</c>.
</p>
</item>
</taglist>
<marker id="props_alias"></marker>
- <p><em>URL aliasing properties - requires mod_alias</em></p>
+ <p><em>URL Aliasing Properties - Requires mod_alias</em></p>
<taglist>
- <marker id="prop_alias"></marker>
- <tag>{alias, {Alias, RealName}}</tag>
+ <tag><marker id="prop_alias"></marker>{alias, {Alias, RealName}}</tag>
<item>
- <p>Where Alias = string() and RealName = string().
- The Alias property allows documents to be stored in the local file
- system instead of the document_root location. URLs with a path that
- begins with url-path is mapped to local files that begins with
- directory-filename, for example:
+ <p><c>Alias = string()</c> and <c>RealName = string()</c>.
+ <c>alias</c> allows documents to be stored in the local file
+ system instead of the <c>document_root</c> location. URLs with a path
+ beginning with url-path is mapped to local files beginning with
+ directory-filename, for example:</p>
<code>{alias, {"/image", "/ftp/pub/image"}}</code>
- and an access to http://your.server.org/image/foo.gif would refer to
- the file /ftp/pub/image/foo.gif. </p>
+ <p>Access to http://your.server.org/image/foo.gif would refer to
+ the file /ftp/pub/image/foo.gif.</p>
</item>
- <marker id="prop_re_write"></marker>
- <tag>{re_write, {Re, Replacement}}</tag>
+ <tag><marker id="prop_re_write"></marker>{re_write, {Re, Replacement}}</tag>
<item>
- <p>Where Re = string() and Replacement = string().
- The ReWrite property allows documents to be stored in the local file
- system instead of the document_root location. URLs are rewritten
- by re:replace/3 to produce a path in the local filesystem.
- For example:
+ <p><c>Re = string()</c> and <c>Replacement = string()</c>.
+ <c>re_write</c> allows documents to be stored in the local file
+ system instead of the <c>document_root</c> location. URLs are rewritten
+ by <c>re:replace/3</c> to produce a path in the local file-system,
+ for example:</p>
<code>{re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}}</code>
- and an access to http://your.server.org/~bob/foo.gif would refer to
+ <p>Access to http://your.server.org/~bob/foo.gif would refer to
the file /home/bob/public/foo.gif.
- In an Apache like configuration file the Re is separated
- from Replacement with one single space, and as expected
- backslashes do not need to be backslash escaped so the
- same example would become:
+ In an Apache-like configuration file, <c>Re</c> is separated
+ from <c>Replacement</c> with one single space, and as expected
+ backslashes do not need to be backslash escaped, the
+ same example would become:</p>
<code>ReWrite ^/[~]([^/]+)(.*)$ /home/\1/public\2</code>
- Beware of trailing space in Replacement that will be used.
- If you must have a space in Re use e.g the character encoding
- <code>\040</code> see <seealso marker="stdlib:re">re(3)</seealso>. </p>
+ <p>Beware of trailing space in <c>Replacement</c> to be used.
+ If you must have a space in <c>Re</c>, use, for example, the character
+ encoding <c>\040</c>, see
+ <seealso marker="stdlib:re">re(3)</seealso>.</p>
</item>
- <marker id="prop_dir_idx"></marker>
- <tag>{directory_index, [string()]}</tag>
+ <tag><marker id="prop_dir_idx"></marker>{directory_index, [string()]}</tag>
<item>
- <p>DirectoryIndex specifies a list of resources to look for
- if a client requests a directory using a / at the end of the
- directory name. file depicts the name of a file in the
- directory. Several files may be given, in which case the server
- will return the first it finds, for example:
+ <p><c>directory_index</c> specifies a list of resources to look for
+ if a client requests a directory using a <c>/</c> at the end of the
+ directory name. <c>file</c> depicts the name of a file in the
+ directory. Several files can be given, in which case the server
+ returns the first it finds, for example:</p>
<code>{directory_index, ["index.hml", "welcome.html"]}</code>
- and access to http://your.server.org/docs/ would return
+ <p>Access to http://your.server.org/docs/ would return
http://your.server.org/docs/index.html or
- http://your.server.org/docs/welcome.html if index.html do not
- exist. </p>
+ http://your.server.org/docs/welcome.html if index.html does not
+ exist.</p>
</item>
</taglist>
<marker id="props_cgi"></marker>
- <p><em>CGI properties - requires mod_cgi</em></p>
+ <p><em>CGI Properties - Requires mod_cgi</em></p>
<taglist>
- <marker id="prop_script_alias"></marker>
- <tag>{script_alias, {Alias, RealName}}</tag>
+ <tag><marker id="prop_script_alias"></marker>{script_alias, {Alias, RealName}}</tag>
<item>
- <p>Where Alias = string() and RealName = string().
- Has the same behavior as the Alias property, except that
- it also marks the target directory as containing CGI
+ <p><c>Alias = string()</c> and <c>RealName = string()</c>.
+ Have the same behavior as property <c>alias</c>, except that
+ they also mark the target directory as containing CGI
scripts. URLs with a path beginning with url-path are mapped to
- scripts beginning with directory-filename, for example:
+ scripts beginning with directory-filename, for example:</p>
<code>{script_alias, {"/cgi-bin/", "/web/cgi-bin/"}}</code>
- and an access to http://your.server.org/cgi-bin/foo would cause
- the server to run the script /web/cgi-bin/foo. </p>
+ <p>Access to http://your.server.org/cgi-bin/foo would cause
+ the server to run the script /web/cgi-bin/foo.</p>
</item>
- <marker id="prop_script_re_write"></marker>
- <tag>{script_re_write, {Re, Replacement}}</tag>
+ <tag><marker id="prop_script_re_write"></marker>{script_re_write, {Re, Replacement}}</tag>
<item>
- <p>Where Re = string() and Replacement = string().
- Has the same behavior as the ReWrite property, except that
- it also marks the target directory as containing CGI
+ <p><c>Re = string()</c> and <c>Replacement = string()</c>.
+ Have the same behavior as property <c>re_write</c>, except that
+ they also mark the target directory as containing CGI
scripts. URLs with a path beginning with url-path are mapped to
- scripts beginning with directory-filename, for example:
+ scripts beginning with directory-filename, for example:</p>
<code>{script_re_write, {"^/cgi-bin/(\\d+)/", "/web/\\1/cgi-bin/"}}</code>
- and an access to http://your.server.org/cgi-bin/17/foo would cause
- the server to run the script /web/17/cgi-bin/foo. </p>
+ <p>Access to http://your.server.org/cgi-bin/17/foo would cause
+ the server to run the script /web/17/cgi-bin/foo.</p>
</item>
- <marker id="prop_script_nocache"></marker>
- <tag>{script_nocache, boolean()}</tag>
+ <tag><marker id="prop_script_nocache"></marker>{script_nocache, boolean()}</tag>
<item>
- <p>If ScriptNoCache is set to true the HTTP server will by
- default add the header fields necessary to prevent proxies from
- caching the page. Generally this is something you want. Defaults
- to false. </p>
+ <p>If <c>script_nocache</c> is set to <c>true</c>, the HTTP server by
+ default adds the header fields necessary to prevent proxies from
+ caching the page. Generally this is preferred.
+ Default to <c>false</c>.</p>
</item>
- <marker id="prop_script_timeout"></marker>
- <tag>{script_timeout, integer()}</tag>
+ <tag><marker id="prop_script_timeout"></marker>{script_timeout, integer()}</tag>
<item>
- <p>The time in seconds the web server will wait between each
- chunk of data from the script. If the CGI-script not delivers
- any data before the timeout the connection to the client will be
- closed. Defaults to 15. </p>
+ <p>The time in seconds the web server waits between each
+ chunk of data from the script. If the CGI script does not deliver
+ any data before the timeout, the connection to the client is
+ closed. Default is <c>15</c>.</p>
</item>
- <marker id="prop_action"></marker>
- <tag>{action, {MimeType, CgiScript}} - requires mod_action</tag>
+ <tag><marker id="prop_action"></marker>{action, {MimeType, CgiScript}} - requires mod_action</tag>
<item>
- <p>Where MimeType = string() and CgiScript = string().
- Action adds an action, which will activate a cgi-script
- whenever a file of a certain mime-type is requested. It
+ <p><c>MimeType = string()</c> and <c>CgiScript = string()</c>.
+ <c>action</c> adds an action activating a CGI script
+ whenever a file of a certain MIME type is requested. It
propagates the URL and file path of the requested document using
the standard CGI PATH_INFO and PATH_TRANSLATED environment
- variables.
+ variables.</p>
+ <p>Example:</p>
<code>{action, {"text/plain", "/cgi-bin/log_and_deliver_text"}}</code>
- </p>
</item>
- <marker id="prop_script"></marker>
- <tag>{script, {Method, CgiScript}} - requires mod_action</tag>
+ <tag><marker id="prop_script"></marker>{script, {Method, CgiScript}} - requires mod_action</tag>
<item>
- <p>Where Method = string() and CgiScript = string().
- Script adds an action, which will activate a cgi-script
+ <p><c>Method = string()</c> and <c>CgiScript = string()</c>.
+ <c>script</c> adds an action activating a CGI script
whenever a file is requested using a certain HTTP method. The
- method is either GET or POST as defined in RFC 1945. It
+ method is either GET or POST, as defined in <url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>. It
propagates the URL and file path of the requested document using
the standard CGI PATH_INFO and PATH_TRANSLATED environment
- variables.
+ variables.</p>
+ <p>Example:</p>
<code>{script, {"PUT", "/cgi-bin/put"}}</code>
- </p>
</item>
</taglist>
<marker id="props_esi"></marker>
- <p><em>ESI properties - requires mod_esi</em></p>
+ <p><em>ESI Properties - Requires mod_esi</em></p>
<taglist>
- <marker id="prop_esi_alias"></marker>
- <tag>{erl_script_alias, {URLPath, [AllowedModule]}}</tag>
+ <tag><marker id="prop_esi_alias"></marker>{erl_script_alias, {URLPath, [AllowedModule]}}</tag>
<item>
- <p>Where URLPath = string() and AllowedModule = atom().
- erl_script_alias marks all URLs matching url-path as erl
+ <p><c>URLPath = string()</c> and <c>AllowedModule = atom()</c>.
+ <c>erl_script_alias</c> marks all URLs matching url-path as erl
scheme scripts. A matching URL is mapped into a specific module
- and function. For example:
+ and function, for example:</p>
- <code>{erl_script_alias, {"/cgi-bin/example", [httpd_example]}}
- </code>
+ <code>{erl_script_alias, {"/cgi-bin/example", [httpd_example]}}</code>
- and a request to
+ <p>A request to
http://your.server.org/cgi-bin/example/httpd_example:yahoo
- would refer to httpd_example:yahoo/3 or, if that did not exist,
+ would refer to httpd_example:yahoo/3 or, if that does not exist,
httpd_example:yahoo/2 and
http://your.server.org/cgi-bin/example/other:yahoo would
- not be allowed to execute. </p>
+ not be allowed to execute.</p>
</item>
- <marker id="prop_esi_nocache"></marker>
- <tag>{erl_script_nocache, boolean()}</tag>
+ <tag><marker id="prop_esi_nocache"></marker>{erl_script_nocache, boolean()}</tag>
<item>
- <p>If erl_script_nocache is set to true the server will add
- http header fields that prevents proxies from caching the
- page. This is generally a good idea for dynamic content, since
- the content often vary between each request.
- Defaults to false. </p>
+ <p>If <c>erl_script_nocache</c> is set to <c>true</c>, the server adds
+ HTTP header fields preventing proxies from caching the
+ page. This is generally a good idea for dynamic content, as
+ the content often varies between each request.
+ Default is <c>false</c>.</p>
</item>
- <marker id="prop_esi_timeout"></marker>
- <tag>{erl_script_timeout, integer()}</tag>
+ <tag><marker id="prop_esi_timeout"></marker>{erl_script_timeout, integer()}</tag>
<item>
- <p>If erl_script_timeout sets the time in seconds the server will
- wait between each chunk of data to be delivered through
- mod_esi:deliver/2. Defaults to 15. This is only relevant
- for scripts that uses the erl scheme. </p>
+ <p>If <c>erl_script_timeout</c> sets the time in seconds the server
+ waits between each chunk of data to be delivered through
+ <c>mod_esi:deliver/2</c>. Default is <c>15</c>. This is only relevant
+ for scripts that use the erl scheme.</p>
</item>
- <marker id="prop_esi_timeout"></marker>
- <tag>{eval_script_alias, {URLPath, [AllowedModule]}}</tag>
+ <tag><marker id="prop_esi_timeout"></marker>{eval_script_alias, {URLPath, [AllowedModule]}}</tag>
<item>
- <p>Where URLPath = string() and AllowedModule = atom().
- Same as erl_script_alias but for scripts
- using the eval scheme. Note that this is only supported
- for backwards compatibility. The eval scheme is deprecated. </p>
+ <p><c>URLPath = string()</c> and <c>AllowedModule = atom()</c>.
+ Same as <c>erl_script_alias</c> but for scripts
+ using the eval scheme. This is only supported
+ for backwards compatibility. The eval scheme is deprecated.</p>
</item>
</taglist>
<marker id="props_log"></marker>
- <p><em>Log properties - requires mod_log</em></p>
+ <p><em>Log Properties - Requires mod_log</em></p>
<taglist>
- <marker id="prop_elog"></marker>
- <tag>{error_log, path()}</tag>
+ <tag><marker id="prop_elog"></marker>{error_log, path()}</tag>
<item>
<p>Defines the filename of the error log file to be used to log
- server errors. If the filename does not begin with a slash (/)
- it is assumed to be relative to the server_root. </p>
+ server errors. If the filename does not begin with a slash (/),
+ it is assumed to be relative to the <c>server_root</c>.</p>
</item>
- <marker id="prop_slog"></marker>
- <tag>{security_log, path()}</tag>
+ <tag><marker id="prop_slog"></marker>{security_log, path()}</tag>
<item>
<p>Defines the filename of the access log file to be used to
log security events. If the filename does not begin with a slash
- (/) it is assumed to be relative to the server_root. </p>
+ (/), it is assumed to be relative to the <c>server_root</c>.</p>
</item>
- <marker id="prop_tlog"></marker>
- <tag>{transfer_log, path()}</tag>
+ <tag><marker id="prop_tlog"></marker>{transfer_log, path()}</tag>
<item>
<p>Defines the filename of the access log file to be used to
log incoming requests. If the filename does not begin with a
- slash (/) it is assumed to be relative to the server_root. </p>
+ slash (/), it is assumed to be relative to the <c>server_root</c>.</p>
</item>
</taglist>
<marker id="props_dlog"></marker>
- <p><em>Disk Log properties - requires mod_disk_log</em></p>
+ <p><em>Disk Log Properties - Requires mod_disk_log</em></p>
<taglist>
- <marker id="prop_dlog_format"></marker>
- <tag>{disk_log_format, internal | external}</tag>
+ <tag><marker id="prop_dlog_format"></marker>{disk_log_format, internal | external}</tag>
<item>
- <p>Defines the file-format of the log files see disk_log for
- more information. If the internal file-format is used, the
- logfile will be repaired after a crash. When a log file is
- repaired data might get lost. When the external file-format is
- used httpd will not start if the log file is broken. Defaults to
- external. </p>
+ <p>Defines the file format of the log files. See <c>disk_log</c> for
+ details. If the internal file format is used, the
+ log file is repaired after a crash. When a log file is
+ repaired, data can disappear. When the external file format is
+ used, <c>httpd</c> does not start if the log file is broken. Default is
+ <c>external</c>.</p>
</item>
- <marker id="prop_edlog"></marker>
- <tag>{error_disk_log, path()}</tag>
+ <tag><marker id="prop_edlog"></marker>{error_disk_log, path()}</tag>
<item>
- <p>Defines the filename of the (disk_log(3)) error log file
+ <p>Defines the filename of the (<c>disk_log(3)</c>) error log file
to be used to log server errors. If the filename does not begin
- with a slash (/) it is assumed to be relative to the server_root. </p>
+ with a slash (/), it is assumed to be relative to the <c>server_root</c>.</p>
</item>
- <marker id="prop_edlog_size"></marker>
- <tag>{error_disk_log_size, {MaxBytes, MaxFiles}}</tag>
+ <tag><marker id="prop_edlog_size"></marker>{error_disk_log_size, {MaxBytes, MaxFiles}}</tag>
<item>
- <p>Where MaxBytes = integer() and MaxFiles = integer().
- Defines the properties of the (disk_log(3)) error log
- file. The disk_log(3) error log file is of type wrap log and
- max-bytes will be written to each file and max-files will be
- used before the first file is truncated and reused. </p>
+ <p><c>MaxBytes = integer()</c> and <c>MaxFiles = integer()</c>.
+ Defines the properties of the (<c>disk_log(3)</c>) error log
+ file. This file is of type wrap log and
+ max bytes is written to each file and max files is
+ used before the first file is truncated and reused.</p>
</item>
- <marker id="prop_sdlog"></marker>
- <tag>{security_disk_log, path()}</tag>
+ <tag><marker id="prop_sdlog"></marker>{security_disk_log, path()}</tag>
<item>
- <p>Defines the filename of the (disk_log(3)) access log file
- which logs incoming security events i.e authenticated
- requests. If the filename does not begin with a slash (/) it
- is assumed to be relative to the server_root. </p>
+ <p>Defines the filename of the (<c>disk_log(3)</c>) access log file
+ logging incoming security events, that is, authenticated
+ requests. If the filename does not begin with a slash (/), it
+ is assumed to be relative to the <c>server_root</c>.</p>
</item>
- <marker id="prop_sdlog_size"></marker>
- <tag>{security_disk_log_size, {MaxBytes, MaxFiles}}</tag>
+ <tag><marker id="prop_sdlog_size"></marker>{security_disk_log_size, {MaxBytes, MaxFiles}}</tag>
<item>
- <p>Where MaxBytes = integer() and MaxFiles = integer().
- Defines the properties of the disk_log(3) access log
- file. The disk_log(3) access log file is of type wrap log and
- max-bytes will be written to each file and max-files will be
- used before the first file is truncated and reused. </p>
+ <p><c>MaxBytes = integer()</c> and <c>MaxFiles = integer()</c>.
+ Defines the properties of the <c>disk_log(3)</c> access log
+ file. This file is of type wrap log and
+ max bytes is written to each file and max files is
+ used before the first file is truncated and reused.</p>
</item>
- <marker id="prop_tdlog"></marker>
- <tag>{transfer_disk_log, path()}</tag>
+ <tag><marker id="prop_tdlog"></marker>{transfer_disk_log, path()}</tag>
<item>
- <p>Defines the filename of the (disk_log(3)) access log file
- which logs incoming requests. If the filename does not begin
- with a slash (/) it is assumed to be relative to the
- server_root. </p>
+ <p>Defines the filename of the (<c>disk_log(3)</c>) access log file
+ logging incoming requests. If the filename does not begin
+ with a slash (/), it is assumed to be relative to the
+ <c>server_root</c>.</p>
</item>
- <marker id="prop_tdlog_size"></marker>
- <tag>{transfer_disk_log_size, {MaxBytes, MaxFiles}}</tag>
+ <tag><marker id="prop_tdlog_size"></marker>{transfer_disk_log_size, {MaxBytes, MaxFiles}}</tag>
<item>
- <p>Where MaxBytes = integer() and MaxFiles = integer().
- Defines the properties of the disk_log(3) access log
- file. The disk_log(3) access log file is of type wrap log and
- max-bytes will be written to each file and max-files will be
- used before the first file is truncated and reused. </p>
+ <p><c>MaxBytes = integer()</c> and <c>MaxFiles = integer()</c>.
+ Defines the properties of the <c>disk_log(3)</c> access log
+ file. This file is of type wrap log and
+ max bytes is written to each file and max files is
+ used before the first file is truncated and reused.</p>
</item>
</taglist>
<marker id="props_auth"></marker>
- <p><em>Authentication properties - requires mod_auth</em></p>
+ <p><em>Authentication Properties - Requires mod_auth</em></p>
<marker id="prop_dri"></marker>
<p><em>{directory, {path(), [{property(), term()}]}}</em></p>
<marker id="props_dir"></marker>
- <p>Here follows the valid properties for directories </p>
+ <p>The properties for directories are as follows:</p>
<taglist>
- <marker id="prop_allow_from"></marker>
- <tag>{allow_from, all | [RegxpHostString]}</tag>
+ <tag><marker id="prop_allow_from"></marker>{allow_from, all | [RegxpHostString]}</tag>
<item>
- <p>Defines a set of hosts which should be granted access to a
- given directory.
-
- For example:
+ <p>Defines a set of hosts to be granted access to a
+ given directory, for example:</p>
<code>{allow_from, ["123.34.56.11", "150.100.23"]}</code>
- The host 123.34.56.11 and all machines on the 150.100.23
- subnet are allowed access. </p>
+ <p>The host <c>123.34.56.11</c> and all machines on the <c>150.100.23</c>
+ subnet are allowed access.</p>
</item>
- <marker id="prop_deny_from"></marker>
- <tag>{deny_from, all | [RegxpHostString]}</tag>
+ <tag><marker id="prop_deny_from"></marker>{deny_from, all | [RegxpHostString]}</tag>
<item>
<p>Defines a set of hosts
- which should be denied access to a given directory.
- For example:
+ to be denied access to a given directory, for example:</p>
<code>{deny_from, ["123.34.56.11", "150.100.23"]}</code>
- The host 123.34.56.11 and all machines on the 150.100.23
- subnet are not allowed access. </p>
+ <p>The host <c>123.34.56.11</c> and all machines on the <c>150.100.23</c>
+ subnet are not allowed access.</p>
</item>
- <marker id="prop_auth_type"></marker>
- <tag>{auth_type, plain | dets | mnesia}</tag>
+ <tag><marker id="prop_auth_type"></marker>{auth_type, plain | dets | mnesia}</tag>
<item>
<p>Sets the type of authentication database that is used for the
- directory.The key difference between the different methods is
- that dynamic data can be saved when Mnesia and Dets is used.
- This property is called AuthDbType in the Apache like
- configuration files. </p>
+ directory. The key difference between the different methods is
+ that dynamic data can be saved when <c>Mnesia</c> and <c>Dets</c>
+ are used.
+ This property is called <c>AuthDbType</c> in the Apache-like
+ configuration files.</p>
</item>
- <marker id="prop_auth_user_file"></marker>
- <tag>{auth_user_file, path()}</tag>
+ <tag><marker id="prop_auth_user_file"></marker>{auth_user_file, path()}</tag>
<item>
- <p>Sets the name of a file which contains the list of users and
- passwords for user authentication. filename can be either
+ <p>Sets the name of a file containing the list of users and
+ passwords for user authentication. The filename can be either
absolute or relative to the <c>server_root</c>. If using the
- plain storage method, this file is a plain text file, where
- each line contains a user name followed by a colon, followed
- by the non-encrypted password. If user names are duplicated,
- the behavior is undefined. For example:
+ plain storage method, this file is a plain text file where
+ each line contains a username followed by a colon, followed
+ by the non-encrypted password. If usernames are duplicated,
+ the behavior is undefined.</p>
+ <p>Example:</p>
<code> ragnar:s7Xxv7
edward:wwjau8 </code>
- If using the dets storage method, the user database is
- maintained by dets and should not be edited by hand. Use the
- API functions in mod_auth module to create / edit the user
- database. This directive is ignored if using the mnesia
- storage method. For security reasons, make sure that the
- <c>auth_user_file</c> is stored outside the document tree of the Web
- server. If it is placed in the directory which it protects,
- clients will be able to download it. </p>
+ <p>If the <c>Dets</c> storage method is used, the user database is
+ maintained by <c>Dets</c> and must not be edited by hand. Use the
+ API functions in module <c>mod_auth</c> to create/edit the user
+ database. This directive is ignored if the <c>Mnesia</c>
+ storage method is used. For security reasons, ensure that
+ <c>auth_user_file</c> is stored outside the document tree of the web
+ server. If it is placed in the directory that it protects,
+ clients can download it.</p>
</item>
- <marker id="prop_auth_group_file"></marker>
- <tag>{auth_group_file, path()}</tag>
+ <tag><marker id="prop_auth_group_file"></marker>{auth_group_file, path()}</tag>
<item>
- <p>Sets the name of a file which contains the list of user
- groups for user authentication. Filename can be either
- absolute or relative to the <c>server_root</c>. If you use the plain
- storage method, the group file is a plain text file, where
+ <p>Sets the name of a file containing the list of user
+ groups for user authentication. The filename can be either
+ absolute or relative to the <c>server_root</c>. If the plain
+ storage method is used, the group file is a plain text file, where
each line contains a group name followed by a colon, followed
- by the member user names separated by spaces. For example:
+ by the members usernames separated by spaces.</p>
+ <p>Example:</p>
<code>group1: bob joe ante</code>
- If using the dets storage method, the group database is
- maintained by dets and should not be edited by hand. Use the
- API for mod_auth module to create / edit the group database.
- This directive is ignored if using the mnesia storage method.
- For security reasons, make sure that the <c>auth_group_file</c> is
- stored outside the document tree of the Web server. If it is
- placed in the directory which it protects, clients will be
- able to download it. </p>
- </item>
-
- <marker id="prop_auth_name"></marker>
- <tag>{auth_name, string()}</tag>
+ <p>If the <c>Dets</c> storage method is used, the group database is
+ maintained by <c>Dets</c> and must not be edited by hand. Use the
+ API for module <c>mod_auth</c> to create/edit the group database.
+ This directive is ignored if the <c>Mnesia</c> storage method is used.
+ For security reasons, ensure that the <c>auth_group_file</c> is
+ stored outside the document tree of the web server. If it is
+ placed in the directory that it protects, clients
+ can download it.</p>
+ </item>
+
+ <tag><marker id="prop_auth_name"></marker>{auth_name, string()}</tag>
<item>
<p>Sets the name of the authorization realm (auth-domain) for
- a directory. This string informs the client about which user
- name and password to use. </p>
+ a directory. This string informs the client about which
+ username and password to use.</p>
</item>
- <marker id="prop_auth_access_passwd"></marker>
- <tag>{auth_access_password, string()}</tag>
+ <tag><marker id="prop_auth_access_passwd"></marker>{auth_access_password, string()}</tag>
<item>
- <p>If set to other than "NoPassword" the password is required
- for all API calls. If the password is set to "DummyPassword" the
+ <p>If set to other than "NoPassword", the password is required
+ for all API calls. If the password is set to "DummyPassword", the
password must be changed before any other API calls. To secure
- the authenticating data the password must be changed after the
- web server is started since it otherwise is written in clear
- text in the configuration file. </p>
+ the authenticating data, the password must be changed after the
+ web server is started. Otherwise it is written in clear
+ text in the configuration file.</p>
</item>
- <marker id="prop_req_user"></marker>
- <tag>{require_user, [string()]}</tag>
+ <tag><marker id="prop_req_user"></marker>{require_user, [string()]}</tag>
<item>
- <p>Defines users which should be granted access to a given
- directory using a secret password. </p>
+ <p>Defines users to grant access to a given
+ directory using a secret password.</p>
</item>
- <marker id="prop_req_grp"></marker>
- <tag>{require_group, [string()]}</tag>
+ <tag><marker id="prop_req_grp"></marker>{require_group, [string()]}</tag>
<item>
- <p>Defines users which should be granted access to a given
- directory using a secret password. </p>
+ <p>Defines users to grant access to a given
+ directory using a secret password.</p>
</item>
</taglist>
<marker id="props_htaccess"></marker>
- <p><em>Htaccess authentication properties - requires mod_htaccess</em></p>
+ <p><em>Htaccess Authentication Properties - Requires mod_htaccess</em></p>
<taglist>
- <marker id="prop_access_files"></marker>
- <tag>{access_files, [path()]}</tag>
+ <tag><marker id="prop_access_files"></marker>{access_files, [path()]}</tag>
<item>
- <p>Specify which filenames that are used for
- access-files. When a request comes every directory in the path
- to the requested asset will be searched after files with the
- names specified by this parameter. If such a file is found the
- file will be parsed and the restrictions specified in it will
- be applied to the request. </p>
+ <p>Specifies the filenames that are used for
+ access files. When a request comes, every directory in the path
+ to the requested asset are searched after files with the
+ names specified by this parameter. If such a file is found, the
+ file is parsed and the restrictions specified in it are
+ applied to the request.</p>
</item>
</taglist>
<marker id="props_sec"></marker>
- <p><em>Security properties - requires mod_security </em></p>
+ <p><em>Security Properties - Requires mod_security</em></p>
<marker id="prop_sec_dir"></marker>
<p><em>{security_directory, {path(), [{property(), term()}]}}</em></p>
<marker id="props_sdir"></marker>
- <p>Here follows the valid properties for security directories</p>
+ <p>The properties for the security directories are as follows:</p>
<taglist>
- <marker id="prop_data_file"></marker>
- <tag>{data_file, path()}</tag>
+ <tag><marker id="prop_data_file"></marker>{data_file, path()}</tag>
<item>
- <p>Name of the security data file. The filename can either
- absolute or relative to the server_root. This file is used to
- store persistent data for the mod_security module. </p>
+ <p>Name of the security data file. The filename can either be
+ absolute or relative to the <c>server_root</c>. This file is used to
+ store persistent data for module <c>mod_security</c>.</p>
</item>
- <marker id="prop_max_retries"></marker>
- <tag>{max_retries, integer()}</tag>
+ <tag><marker id="prop_max_retries"></marker>{max_retries, integer()}</tag>
<item>
- <p>Specifies the maximum number of tries to authenticate a
- user has before the user is blocked out. If a user
- successfully authenticates when the user has been blocked, the
- user will receive a 403 (Forbidden) response from the
- server. If the user makes a failed attempt while blocked the
- server will return 401 (Unauthorized), for security
+ <p>Specifies the maximum number of attempts to authenticate a
+ user before the user is blocked out. If a user
+ successfully authenticates while blocked, the
+ user receives a 403 (Forbidden) response from the
+ server. If the user makes a failed attempt while blocked, the
+ server returns 401 (Unauthorized), for security
reasons.
- Defaults to 3 may also be set to infinity. </p>
+ Default is <c>3</c>. Can be set to infinity.</p>
</item>
- <marker id="prop_block_time"></marker>
- <tag>{block_time, integer()}</tag>
+ <tag><marker id="prop_block_time"></marker>{block_time, integer()}</tag>
<item>
<p>Specifies the number of minutes a user is blocked. After
- this amount of time, he automatically regains access.
- Defaults to 60. </p>
+ this timehas passed, the user automatically regains access.
+ Default is <c>60</c>.</p>
</item>
- <marker id="prop_fail_exp_time"></marker>
- <tag>{fail_expire_time, integer()}</tag>
+ <tag><marker id="prop_fail_exp_time"></marker>{fail_expire_time, integer()}</tag>
<item>
<p>Specifies the number of minutes a failed user authentication
- is remembered. If a user authenticates after this amount of
- time, his previous failed authentications are
+ is remembered. If a user authenticates after this
+ time has passed, the previous failed authentications are
forgotten.
- Defaults to 30. </p>
+ Default is <c>30</c>.</p>
</item>
- <marker id="prop_auth_timeout"></marker>
- <tag>{auth_timeout, integer()}</tag>
+ <tag><marker id="prop_auth_timeout"></marker>{auth_timeout, integer()}</tag>
<item>
Specifies the number of seconds a successful user
authentication is remembered. After this time has passed, the
- authentication will no longer be reported. Defaults to 30.
+ authentication is no longer reported. Default is <c>30</c>.
</item>
</taglist>
</section>
<funcs>
<func>
- <marker id="info1"></marker>
<name>info(Pid) -></name>
<name>info(Pid, Properties) -> [{Option, Value}]</name>
- <fsummary>Fetches information about the HTTP server</fsummary>
+ <fsummary>Fetches information about the HTTP server.</fsummary>
<type>
<v>Properties = [property()]</v>
- <v>Option = property()</v>
+ <v>Option = property()</v>
<v>Value = term()</v>
</type>
<desc>
<p>Fetches information about the HTTP server. When called
- with only the pid all properties are fetched, when called
- with a list of specific properties they are fetched.
- Available properties are the same as the server's start options.
+ with only the pid, all properties are fetched. When called
+ with a list of specific properties, they are fetched.
+ The available properties are the same as the start options
+ of the server.
</p>
- <note><p>Pid is the pid returned from inets:start/[2,3].
- Can also be retrieved form inets:services/0, inets:services_info/0
- see <seealso marker="inets">inets(3)</seealso>
+ <note><p>Pid is the pid returned from <c>inets:start/[2,3]</c>.
+ Can also be retrieved form <c>inets:services/0</c> and
+ <c>inets:services_info/0</c>,
+ see <seealso marker="inets">inets(3)</seealso>.
</p></note>
</desc>
</func>
<func>
- <marker id="info2"></marker>
<name>info(Address, Port) -> </name>
+ <name>info(Address, Port, Profile) -> </name>
+ <name>info(Address, Port, Profile, Properties) -> [{Option, Value}] </name>
<name>info(Address, Port, Properties) -> [{Option, Value}] </name>
- <fsummary>Fetches information about the HTTP server</fsummary>
+ <fsummary>Fetches information about the HTTP server.</fsummary>
<type>
<v>Address = ip_address()</v>
<v>Port = integer()</v>
+ <v>Profile = atom()</v>
<v>Properties = [property()]</v>
<v>Option = property()</v>
<v>Value = term()</v>
</type>
<desc>
<p>Fetches information about the HTTP server. When called with
- only the Address and Port all properties are fetched, when
- called with a list of specific properties they are fetched.
- Available properties are the same as the server's start
- options.
+ only <c>Address</c> and <c>Port</c>, all properties are
+ fetched. When called with a list of specific properties, they
+ are fetched. The available properties are the same as the
+ start options of the server.
</p>
- <note><p> Address has to be the ip-address and can not be
+ <note><p>The address must be the IP address and cannot be
the hostname.
</p></note>
</desc>
</func>
<func>
- <marker id="reload_config"></marker>
<name>reload_config(Config, Mode) -> ok | {error, Reason}</name>
<fsummary>Reloads the HTTP server configuration without
restarting the server.</fsummary>
@@ -971,24 +927,26 @@ bytes
</type>
<desc>
<p>Reloads the HTTP server configuration without restarting the
- server. Incoming requests will be answered with a temporary
- down message during the time the it takes to reload.</p>
+ server. Incoming requests are answered with a temporary
+ down message during the reload time.</p>
- <note><p>Available properties are the same as the server's
- start options, although the properties bind_address and
- port can not be changed.</p></note>
+ <note><p>Available properties are the same as the
+ start options of the server, but the properties
+ <c>bind_address</c> and <c>port</c>
+ cannot be changed.</p></note>
- <p>If mode is disturbing, the server is blocked forcefully and
- all ongoing requests are terminated and the reload will
- start immediately. If mode is non-disturbing, no new
- connections are accepted, but the ongoing requests are
+ <p>If mode is disturbing, the server is blocked forcefully,
+ all ongoing requests terminates, and the reload
+ starts immediately. If mode is non-disturbing, no new
+ connections are accepted, but ongoing requests are
allowed to complete before the reload is done.</p>
</desc>
</func>
</funcs>
<section>
- <title>ERLANG WEB SERVER API DATA TYPES </title>
+ <title>ERLANG WEB SERVER API DATA TYPES</title>
+ <p>The Erlang web server API data types are as follows:</p>
<code type="none">
ModData = #mod{}
@@ -1005,73 +963,75 @@ bytes
parsed_header = [],
entity_body,
connection
- }).
- </code>
+ }).</code>
- <p>To acess the record in your callback-module use </p>
- <code> -include_lib("inets/include/httpd.hrl"). </code>
+ <p>To acess the record in your callback-module use:</p>
+ <code> -include_lib("inets/include/httpd.hrl").</code>
- <p>The fields of the <c>mod</c> record has the following meaning:
+ <p>The fields of record <c>mod</c> have the following meaning:
</p>
<taglist>
<tag><c>data</c></tag>
- <item>Type <c>[{InteractionKey,InteractionValue}]</c> is used to
+ <item><p>Type <c>[{InteractionKey,InteractionValue}]</c> is used to
propagate data between modules. Depicted
- <c>interaction_data()</c> in function type declarations.
+ <c>interaction_data()</c> in function type declarations.</p>
</item>
<tag><c>socket_type</c></tag>
- <item><c>socket_type()</c>,
- Indicates whether it is an ip socket or a ssl socket.
+ <item><p><c>socket_type()</c>
+ indicates whether it is an IP socket or an <c>ssl</c> socket.</p>
</item>
<tag><c>socket</c></tag>
- <item>The actual socket in <c>ip_comm</c> or <c>ssl</c> format
- depending on the <c>socket_type</c>.
+ <item><p>The socket, in format <c>ip_comm</c> or <c>ssl</c>,
+ depending on <c>socket_type</c>.</p>
</item>
<tag><c>config_db</c></tag>
- <item>The config file directives stored as key-value tuples in
- an ETS-table. Depicted <c>config_db()</c> in function type
- declarations.
+ <item><p>The config file directives stored as key-value tuples in
+ an ETS table. Depicted <c>config_db()</c> in function type
+ declarations.</p>
</item>
<tag><c>method</c></tag>
- <item>Type <c>"GET" | "POST" | "HEAD" | "TRACE"</c>, that is the
- HTTP method.
+ <item><p>Type <c>"GET" | "POST" | "HEAD" | "TRACE"</c>, that is, the
+ HTTP method.</p>
</item>
<tag><c>absolute_uri</c></tag>
- <item>If the request is a HTTP/1.1
- request the URI might be in the absolute URI format. In that
- case httpd will save the absolute URI in this field. An Example
- of an absolute URI could
- be<c>"http://ServerName:Part/cgi-bin/find.pl?person=jocke"</c></item>
+ <item><p>If the request is an HTTP/1.1
+ request, the URI can be in the absolute URI format. In that
+ case, <c>httpd</c> saves the absolute URI in this field. An Example
+ of an absolute URI is
+ <c>"http://ServerName:Part/cgi-bin/find.pl?person=jocke"</c></p></item>
<tag><c>request_uri</c></tag>
- <item>The <c>Request-URI</c> as defined
- in RFC 1945, for example <c>"/cgi-bin/find.pl?person=jocke"</c></item>
+ <item><p>The <c>Request-URI</c> as defined
+ in <url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>, for example, <c>"/cgi-bin/find.pl?person=jocke"</c>.</p>
+ </item>
<tag><c>http_version</c></tag>
- <item>The <c>HTTP</c> version of the
- request, that is "HTTP/0.9", "HTTP/1.0", or "HTTP/1.1".
+ <item><p>The <c>HTTP</c> version of the
+ request, that is, "HTTP/0.9", "HTTP/1.0", or "HTTP/1.1".</p>
</item>
<tag><c>request_line</c></tag>
- <item>The <c>Request-Line</c> as
- defined in RFC 1945, for example <c>"GET /cgi-bin/find.pl?person=jocke HTTP/1.0"</c>.
+ <item><p>The <c>Request-Line</c> as
+ defined in<url href="http://www.ietf.org/rfc/rfc1945.txt">RFC 1945</url>, for example,
+ <c>"GET /cgi-bin/find.pl?person=jocke HTTP/1.0"</c>.</p>
</item>
<tag><c>parsed_header</c></tag>
- <item>Type <c>[{HeaderKey,HeaderValue}]</c>,
+ <item>Type <c>[{HeaderKey,HeaderValue}]</c>.
<c>parsed_header</c> contains all HTTP header fields from the
- HTTP-request stored in a list as key-value tuples. See RFC 2616
- for a listing of all header fields. For example the date field
- would be stored as: <c>{"date","Wed, 15 Oct 1997 14:35:17 GMT"} </c>.
- RFC 2616 defines that HTTP is a case insensitive protocol and
- the header fields may be in lower case or upper case. Httpd will
- ensure that all header field names are in lower case.
+ HTTP request stored in a list as key-value tuples. See
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>
+ for a listing of all header fields. For example, the date field
+ is stored as <c>{"date","Wed, 15 Oct 1997 14:35:17 GMT"}</c>.
+ RFC 2616 defines that HTTP is a case-insensitive protocol and
+ the header fields can be in lower case or upper case. <c>httpd</c>
+ ensures that all header field names are in lower case.
</item>
<tag><c>entity_body</c></tag>
- <item>The <c>Entity-Body</c> as defined
- in RFC 2616, for example data sent from a CGI-script using the
- POST method.
+ <item><p>The <c>entity-Body</c> as defined
+ in <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>, for example, data sent from a CGI script using the
+ POST method.</p>
</item>
<tag><c>connection</c></tag>
- <item><c>true | false</c> If set to true the connection to the
- client is a persistent connection and will not be closed when
- the request is served.</item>
+ <item><p><c>true | false</c>. If set to <c>true</c>, the connection to the
+ client is a persistent connection and is not closed when
+ the request is served.</p></item>
</taglist>
</section>
@@ -1080,56 +1040,63 @@ bytes
</section>
<funcs>
<func>
- <marker id="module_do"></marker>
<name>Module:do(ModData)-> {proceed, OldData} | {proceed, NewData} | {break, NewData} | done</name>
- <fsummary>Called for each request to the Web server.</fsummary>
+ <fsummary>Called for each request to the web server.</fsummary>
<type>
<v>OldData = list()</v>
- <v>NewData = [{response,{StatusCode,Body}}] | [{response,{response,Head,Body}}] | [{response,{already_sent,Statuscode,Size}}] </v>
+ <v>NewData = [{response,{StatusCode,Body}}]</v>
+ <v>| [{response,{response,Head,Body}}]</v>
+ <v>| [{response,{already_sent,Statuscode,Size}}]</v>
<v>StatusCode = integer()</v>
<v>Body = io_list() | nobody | {Fun, Arg}</v>
<v>Head = [HeaderOption]</v>
<v>HeaderOption = {Option, Value} | {code, StatusCode}</v>
- <v>Option = accept_ranges | allow | cache_control | content_MD5 | content_encoding | content_language | content_length | content_location | content_range | content_type | date | etag | expires | last_modified | location | pragma | retry_after | server | trailer | transfer_encoding</v>
+ <v>Option = accept_ranges | allow</v>
+ <v>| cache_control | content_MD5</v>
+ <v>| content_encoding | content_language</v>
+ <v>| content_length | content_location</v>
+ <v>| content_range | content_type | date</v>
+ <v>| etag | expires | last_modified</v>
+ <v>| location | pragma | retry_after</v>
+ <v>| server | trailer | transfer_encoding</v>
<v>Value = string()</v>
<v>Fun = fun( Arg ) -> sent| close | Body </v>
<v>Arg = [term()]</v>
</type>
<desc>
- <p>When a valid request reaches httpd it calls <c>do/1</c> in
- each module defined by the Modules configuration
- option. The function may generate data for other modules
- or a response that can be sent back to the client.</p>
- <p>The field <c>data</c> in ModData is a list. This list will be
+ <p>When a valid request reaches <c>httpd</c>, it calls <c>do/1</c> in
+ each module, defined by the configuration
+ option of <c>Module</c>. The function can generate data for other
+ modules or a response that can be sent back to the client.</p>
+ <p>The field <c>data</c> in <c>ModData</c> is a list. This list is
the list returned from the last call to
<c>do/1</c>.</p>
- <p><c>Body</c> is the body of the http-response that will be
- sent back to the client an appropriate header will be
- appended to the message. <c>StatusCode</c> will be the
- status code of the response see RFC2616 for the appropriate
- values.</p>
+ <p><c>Body</c> is the body of the HTTP response that is
+ sent back to the client. An appropriate header is
+ appended to the message. <c>StatusCode</c> is the
+ status code of the response, see
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>
+ for the appropriate values.</p>
<p><c>Head</c> is a key value list of HTTP header fields. The
- server will construct a HTTP header from this data. See RFC
- 2616 for the appropriate value for each header field. If the
- client is a HTTP/1.0 client then the server will filter the
- list so that only HTTP/1.0 header fields will be sent back
- to the client.</p>
+ server constructs an HTTP header from this data. See <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url> for the appropriate value for each header field. If the
+ client is an HTTP/1.0 client, the server filters the
+ list so that only HTTP/1.0 header fields are sent back
+ to the client.</p>
<p>If <c>Body</c> is returned and equal to <c>{Fun,Arg}</c>,
- the Web server will try <c>apply/2</c> on <c>Fun</c> with
- <c>Arg</c> as argument and expect that the fun either
- returns a list <c>(Body)</c> that is a HTTP-repsonse or the
- atom sent if the HTTP-response is sent back to the
- client. If close is returned from the fun something has gone
- wrong and the server will signal this to the client by
+ the web server tries <c>apply/2</c> on <c>Fun</c> with
+ <c>Arg</c> as argument. The web server expects that the fun either
+ returns a list <c>(Body)</c> that is an HTTP repsonse, or the
+ atom <c>sent</c> if the HTTP response is sent back to the
+ client. If <c>close</c> is returned from the fun, something has gone
+ wrong and the server signals this to the client by
closing the connection.</p>
</desc>
</func>
<func>
- <marker id="module_load"></marker>
- <name>Module:load(Line, AccIn)-> eof | ok | {ok, AccOut} | {ok, AccOut, {Option, Value}} | {ok, AccOut, [{Option, Value}]} | {error, Reason} </name>
- <fsummary>Load is used to convert a line in a Apache like config
- file to a <c>{Option, Value}</c> tuple.</fsummary>
+ <name>Module:load(Line, AccIn)-> eof | ok | {ok, AccOut} | {ok, AccOut, {Option, Value}} | {ok, AccOut, [{Option, Value}]} | {error, Reason}</name>
+ <fsummary>Converts a line in an Apache-like config
+ file to an <c>{Option, Value}</c> tuple.</fsummary>
<type>
<v>Line = string()</v>
<v>AccIn = [{Option, Value}]</v>
@@ -1139,55 +1106,53 @@ bytes
<v>Reason = term()</v>
</type>
<desc>
- <p>Load is used to convert a line in a Apache like
- configuration file to a <c>{Option, Value}</c> tuple. Some
- more complex configuration options such as <c>directory</c>
- and <c>security_directory</c> will create an
- accumulator.This function does only need clauses for the
+ <p>Converts a line in an Apache-like
+ configuration file to an <c>{Option, Value}</c> tuple. Some
+ more complex configuration options, such as <c>directory</c>
+ and <c>security_directory</c>, create an
+ accumulator. This function only needs clauses for the
options implemented by this particular callback module.
</p>
</desc>
</func>
-
+
+ <func>
+ <name>Module:remove(ConfigDB) -> ok | {error, Reason} </name>
+ <fsummary>Callback function that is called when the web server is closed.</fsummary>
+ <type>
+ <v>ConfigDB = ets_table()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>When <c>httpd</c> is shut down, it tries to execute
+ <c>remove/1</c> in each Erlang web server callback module. The
+ programmer can use this function to clean up resources
+ created in the store function.</p>
+ </desc>
+ </func>
+
<func>
- <marker id="module_store"></marker>
- <name>Module:store({Option, Value}, Config)-> {ok, {Option, NewValue}} | {error, Reason} </name>
- <fsummary></fsummary>
+ <name>Module:store({Option, Value}, Config)-> {ok, {Option, NewValue}} | {error, Reason}</name>
+ <fsummary>Checks the validity of the configuration options.</fsummary>
<type>
<v>Line = string()</v>
<v>Option = property()</v>
<v>Config = [{Option, Value}]</v>
- <v>Value = term() </v>
+ <v>Value = term()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>This function is used to check the validity of the
+ <p>Checks the validity of the
configuration options before saving them in the internal
- database. This function may also have a side effect
- e.i. setup necessary extra resources implied by the
+ database. This function can also have a side effect,
+ that is, setup of necessary extra resources implied by the
configuration option. It can also
resolve possible dependencies among
configuration options by changing the value of the option.
- This function does only need clauses for the options
+ This function only needs clauses for the options
implemented by this particular callback module.</p>
</desc>
</func>
-
- <func>
- <marker id="module_remove"></marker>
- <name>Module:remove(ConfigDB) -> ok | {error, Reason} </name>
- <fsummary>Callback function that is called when the Web server is closed.</fsummary>
- <type>
- <v>ConfigDB = ets_table()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>When httpd is shutdown it will try to execute
- <c>remove/1</c> in each Erlang web server callback module. The
- programmer may use this function to clean up resources
- that may have been created in the store function.</p>
- </desc>
- </func>
</funcs>
<section>
@@ -1195,9 +1160,8 @@ bytes
</section>
<funcs>
<func>
- <marker id="parse_query"></marker>
- <name>parse_query(QueryString) -> [{Key,Value}]</name>
- <fsummary>Parse incoming data to <c>erl </c>and <c>eval </c>scripts.</fsummary>
+ <name>parse_query(QueryString) -> [{Key,Value}]</name>
+ <fsummary>Parses incoming data to <c>erl</c> and <c>eval</c> scripts.</fsummary>
<type>
<v>QueryString = string()</v>
<v>Key = string()</v>
@@ -1205,8 +1169,9 @@ bytes
</type>
<desc>
<p><c>parse_query/1</c> parses incoming data to <c>erl</c> and
- <c>eval</c> scripts (See <seealso marker="mod_esi">mod_esi(3)</seealso>) as defined in the standard
- URL format, that is '+' becomes 'space' and decoding of
+ <c>eval</c> scripts (see <seealso marker="mod_esi">mod_esi(3)</seealso>)
+ as defined in the standard
+ URL format, that is, '+' becomes 'space' and decoding of
hexadecimal characters (<c>%xx</c>).</p>
</desc>
</func>
@@ -1214,8 +1179,9 @@ bytes
<section>
<title>SEE ALSO</title>
- <p>RFC 2616, <seealso marker="inets">inets(3)</seealso>,
- <seealso marker="ssl:ssl">ssl(3)</seealso>
+ <p><url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>,
+ <seealso marker="inets">inets(3)</seealso>,
+ <seealso marker="ssl:ssl">ssl(3)</seealso>
</p>
</section>
diff --git a/lib/inets/doc/src/httpd_conf.xml b/lib/inets/doc/src/httpd_conf.xml
deleted file mode 100644
index 60fc2f135e..0000000000
--- a/lib/inets/doc/src/httpd_conf.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <header>
- <copyright>
- <year>1997</year><year>2013</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>httpd_conf</title>
- <prepared>Joakim Greben&ouml;</prepared>
- <docno></docno>
- <date>1997-10-14</date>
- <rev>2.2</rev>
- <file>httpd_conf.sgml</file>
- </header>
- <module>httpd_conf</module>
- <modulesummary>Configuration utility functions to be used by the Erlang
- Web server API programmer.</modulesummary>
- <description>
- <p>This module provides the Erlang Webserver API programmer with
- utility functions for adding run-time configuration directives.</p>
-
- <marker id="check_enum"></marker>
- </description>
-
- <funcs>
- <func>
- <name>check_enum(EnumString, ValidEnumStrings) -> Result</name>
- <fsummary>Check if string is a valid enumeration.</fsummary>
- <type>
- <v>EnumString = string()</v>
- <v>ValidEnumStrings = [string()]</v>
- <v>Result = {ok,atom()} | {error,not_valid}</v>
- </type>
- <desc>
- <marker id="check_enum"></marker>
- <p><c>check_enum/2</c> checks if <c>EnumString</c> is a valid
- enumeration of <c>ValidEnumStrings</c> in which case it is
- returned as an atom.</p>
-
- <marker id="clean"></marker>
- </desc>
- </func>
-
- <func>
- <name>clean(String) -> Stripped</name>
- <fsummary>Remove leading and/or trailing white spaces.</fsummary>
- <type>
- <v>String = Stripped = string()</v>
- </type>
- <desc>
- <marker id="clean"></marker>
- <p><c>clean/1</c> removes leading and/or trailing white spaces
- from <c>String</c>.</p>
-
- <marker id="custom_clean"></marker>
- </desc>
- </func>
-
- <func>
- <name>custom_clean(String,Before,After) -> Stripped</name>
- <fsummary>Remove leading and/or trailing white spaces and custom characters.</fsummary>
- <type>
- <v>Before = After = regexp()</v>
- <v>String = Stripped = string()</v>
- </type>
- <desc>
- <marker id="custom_clean"></marker>
- <p><c>custom_clean/3</c> removes leading and/or trailing white
- spaces and custom characters from <c>String</c>. <c>Before</c>
- and <c>After</c> are regular expressions, as defined in
- <c>regexp(3)</c>, describing the custom characters.</p>
-
- <marker id="is_directory"></marker>
- </desc>
- </func>
-
- <func>
- <name>is_directory(FilePath) -> Result</name>
- <fsummary>Check if a file path is a directory.</fsummary>
- <type>
- <v>FilePath = string()</v>
- <v>Result = {ok,Directory} | {error,Reason}</v>
- <v>Directory = string()</v>
- <v>Reason = string() | enoent | eacces | enotdir | FileInfo</v>
- <v>FileInfo = File info record</v>
- </type>
- <desc>
- <marker id="is_directory"></marker>
- <p><c>is_directory/1</c> checks if <c>FilePath</c> is a
- directory in which case it is returned. Please read
- <c>file(3)</c> for a description of <c>enoent</c>,
- <c>eacces</c> and <c>enotdir</c>. The definition of
- the file info record can be found by including <c>file.hrl</c>
- from the kernel application, see file(3).</p>
-
- <marker id="is_file"></marker>
- </desc>
- </func>
-
- <func>
- <name>is_file(FilePath) -> Result</name>
- <fsummary>Check if a file path is a regular file.</fsummary>
- <type>
- <v>FilePath = string()</v>
- <v>Result = {ok,File} | {error,Reason}</v>
- <v>File = string()</v>
- <v>Reason = string() | enoent | eacces | enotdir | FileInfo</v>
- <v>FileInfo = File info record</v>
- </type>
- <desc>
- <marker id="is_file"></marker>
- <p><c>is_file/1</c> checks if <c>FilePath</c> is a regular
- file in which case it is returned. Read <c>file(3)</c> for a
- description of <c>enoent</c>, <c>eacces</c> and
- <c>enotdir</c>. The definition of the file info record can be
- found by including <c>file.hrl</c> from the kernel application,
- see file(3).</p>
-
- <marker id="make_integer"></marker>
- </desc>
- </func>
-
- <func>
- <name>make_integer(String) -> Result</name>
- <fsummary>Return an integer representation of a string.</fsummary>
- <type>
- <v>String = string()</v>
- <v>Result = {ok,integer()} | {error,nomatch}</v>
- </type>
- <desc>
- <marker id="make_integer"></marker>
- <p><c>make_integer/1</c> returns an integer representation of
- <c>String</c>.</p>
- </desc>
- </func>
- </funcs>
-
- <section>
- <marker id="see_also"></marker>
- <title>SEE ALSO</title>
- <p><seealso marker="httpd">httpd(3)</seealso></p>
- </section>
-
-</erlref>
-
-
diff --git a/lib/inets/doc/src/httpd_custom_api.xml b/lib/inets/doc/src/httpd_custom_api.xml
index faf1d277df..d2e5441895 100644
--- a/lib/inets/doc/src/httpd_custom_api.xml
+++ b/lib/inets/doc/src/httpd_custom_api.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,10 +29,24 @@
<modulesummary>Behaviour with optional callbacks to customize the inets HTTP server.</modulesummary>
<description>
<p> The module implementing this behaviour shall be supplied to to the servers
- configuration with the option <seealso marker="httpd:prop_customize"> customize</seealso></p>
+ configuration with the option <seealso marker="httpd#prop_customize"> customize</seealso></p>
</description>
<funcs>
+ <func>
+ <name>response_default_headers() -> [Header] </name>
+ <fsummary>Provide default headers for the HTTP servers responses.</fsummary>
+ <type>
+ <v>Header = {HeaderName :: string(), HeaderValue::string()}</v>
+ <d>string:to_lower/1 will be performed on the HeaderName</d>
+ </type>
+ <desc>
+ <p>Provide default headers for the HTTP servers responses. Note that this
+ option may override built-in defaults.
+ </p>
+ </desc>
+ </func>
+
<func>
<name>response_header({HeaderName, HeaderValue}) -> {true, Header} | false </name>
<fsummary>Filter and possible alter HTTP response headers.</fsummary>
diff --git a/lib/inets/doc/src/httpd_socket.xml b/lib/inets/doc/src/httpd_socket.xml
index 70b4a4a842..f71dac90b2 100644
--- a/lib/inets/doc/src/httpd_socket.xml
+++ b/lib/inets/doc/src/httpd_socket.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,12 +31,12 @@
</header>
<module>httpd_socket</module>
<modulesummary>Communication utility functions to be used by the Erlang
- Web server API programmer.</modulesummary>
+ web server API programmer.</modulesummary>
<description>
- <p>This module provides the Erlang Web server API module programmer
+ <p>This module provides the Erlang web server API module programmer
with utility functions for generic sockets communication. The
appropriate communication mechanism is transparently used, that
- is <c>ip_comm</c> or <c>ssl</c>.</p>
+ is, <c>ip_comm</c> or <c>ssl</c>.</p>
<marker id="deliver"></marker>
</description>
@@ -43,7 +44,7 @@
<funcs>
<func>
<name>deliver(SocketType, Socket, Data) -> Result</name>
- <fsummary>Send binary data over socket.</fsummary>
+ <fsummary>Sends binary data over socket.</fsummary>
<type>
<v>SocketType = socket_type()</v>
<v>Socket = socket()</v>
@@ -52,10 +53,10 @@
</type>
<desc>
<marker id="deliver"></marker>
- <p><c>deliver/3</c> sends the <c>Binary</c> over the
- <c>Socket</c> using the specified <c>SocketType</c>. Socket
- and SocketType should be the socket and the socket_type form
- the mod record as defined in httpd.hrl</p>
+ <p><c>deliver/3</c> sends <c>Data</c> over
+ <c>Socket</c> using the specified <c>SocketType</c>. <c>Socket</c>
+ and <c>SocketType</c> is to be the socket and the <c>socket_type</c>
+ form the <c>mod</c> record as defined in <c>httpd.hrl</c></p>
<marker id="peername"></marker>
</desc>
@@ -63,7 +64,7 @@
<func>
<name>peername(SocketType,Socket) -> {Port,IPAddress}</name>
- <fsummary>Return the port and IP-address of the remote socket.</fsummary>
+ <fsummary>Returns the port and IP address of the remote socket.</fsummary>
<type>
<v>SocketType = socket_type()</v>
<v>Socket = socket()</v>
@@ -72,8 +73,8 @@
</type>
<desc>
<marker id="peername"></marker>
- <p><c>peername/3</c> returns the <c>Port</c> and
- <c>IPAddress</c> of the remote <c>Socket</c>. </p>
+ <p><c>peername/2</c> returns the <c>Port</c> and
+ <c>IPAddress</c> of the remote <c>Socket</c>.</p>
<marker id="resolve"></marker>
</desc>
@@ -81,7 +82,7 @@
<func>
<name>resolve() -> HostName</name>
- <fsummary>Return the official name of the current host.</fsummary>
+ <fsummary>Returns the official name of the current host.</fsummary>
<type>
<v>HostName = string()</v>
</type>
diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml
index 1236576ca8..0f498ba2fc 100644
--- a/lib/inets/doc/src/httpd_util.xml
+++ b/lib/inets/doc/src/httpd_util.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,9 +30,10 @@
<file>httpd_util.sgml</file>
</header>
<module>httpd_util</module>
- <modulesummary>Miscellaneous utility functions to be used when implementing Erlang Web server API modules.</modulesummary>
+ <modulesummary>Miscellaneous utility functions to be used when implementing
+ Erlang web server API modules.</modulesummary>
<description>
- <p>This module provides the Erlang Web Server API module
+ <p>This module provides the Erlang web server API module
programmer with miscellaneous utility functions.</p>
<marker id="convert_request_date"></marker>
@@ -40,7 +42,7 @@
<funcs>
<func>
<name>convert_request_date(DateString) -> ErlDate|bad_date</name>
- <fsummary>Convert The the date to the Erlang date format.</fsummary>
+ <fsummary>Converts the date to the Erlang date format.</fsummary>
<type>
<v>DateString = string()</v>
<v>ErlDate = {{Year,Month,Date},{Hour,Min,Sec}}</v>
@@ -48,10 +50,9 @@
</type>
<desc>
<p><c>convert_request_date/1</c> converts <c>DateString</c> to
- the Erlang date format. DateString must be in one of the three
- date formats that is defined in the RFC 2616.</p>
-
- <marker id="create_etag"></marker>
+ the Erlang date format. <c>DateString</c> must be in one of the
+ three date formats defined in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.</p>
</desc>
</func>
@@ -63,128 +64,84 @@
<v>Etag = string()</v>
</type>
<desc>
- <p><c>create_etag/1</c> calculates the Etag for a file, from its
- size and time for last modification. fileinfo is a record defined
- in <c>kernel/include/file.hrl</c></p>
-
- <marker id="decode_hex"></marker>
- </desc>
- </func>
-
- <func>
- <name>decode_hex(HexValue) -> DecValue</name>
- <fsummary>Convert a hex value into its decimal equivalent.</fsummary>
- <type>
- <v>HexValue = DecValue = string()</v>
- </type>
- <desc>
- <p>Converts the hexadecimal value <c>HexValue</c> into its
- decimal equivalent (<c>DecValue</c>).</p>
-
- <marker id="day"></marker>
+ <p><c>create_etag/1</c> calculates the Etag for a file from its
+ size and time for last modification. <c>FileInfo</c> is a record defined
+ in <c>kernel/include/file.hrl</c>.</p>
</desc>
</func>
-
+
<func>
<name>day(NthDayOfWeek) -> DayOfWeek</name>
- <fsummary>Convert the day of the week (integer [1-7]) to an abbreviated string.</fsummary>
+ <fsummary>Converts the day of the week
+ (integer [1-7]) to an abbreviated string.</fsummary>
<type>
<v>NthDayOfWeek = 1-7</v>
<v>DayOfWeek = string()</v>
</type>
<desc>
- <marker id="day"></marker>
<p><c>day/1</c> converts the day of the week
- (<c>NthDayOfWeek</c>) as an integer (1-7) to an abbreviated
- string, that is: </p>
+ (<c>NthDayOfWeek</c>) from an integer (1-7) to an abbreviated
+ string, that is:</p>
<p>1 = "Mon", 2 = "Tue", ..., 7 = "Sat".</p>
-
- <marker id="flatlength"></marker>
</desc>
</func>
<func>
- <name>flatlength(NestedList) -> Size</name>
- <fsummary>Compute the size of a possibly nested list.</fsummary>
+ <name>decode_hex(HexValue) -> DecValue</name>
+ <fsummary>Converts a hexadecimal value into its decimal equivalent.</fsummary>
<type>
- <v>NestedList = list()</v>
- <v>Size = integer()</v>
+ <v>HexValue = DecValue = string()</v>
</type>
<desc>
- <marker id="flatlength"></marker>
- <p><c>flatlength/1</c> computes the size of the possibly nested
- list <c>NestedList</c>. Which may contain binaries.</p>
-
- <marker id="hexlist_to_integer"></marker>
+ <p>Converts the hexadecimal value <c>HexValue</c> into its
+ decimal equivalent (<c>DecValue</c>).</p>
</desc>
</func>
-
-<!--
+
<func>
- <name>header(StatusCode,PersistentConn)</name>
- <name>header(StatusCode,Date)</name>
- <name>header(StatusCode,MimeType,Date)</name>
- <name>header(StatusCode,MimeType,PersistentConn,Date) -> HTTPHeader</name>
- <fsummary>Generate a HTTP 1.1 header.</fsummary>
+ <name>flatlength(NestedList) -> Size</name>
+ <fsummary>Computes the size of a possibly nested list.</fsummary>
<type>
- <v>StatusCode = integer()</v>
- <v>Date = rfc1123_date()</v>
- <v>MimeType = string()</v>
- <v>PersistentConn = true | false</v>
+ <v>NestedList = list()</v>
+ <v>Size = integer()</v>
</type>
<desc>
- <marker id="header"></marker>
- <p><c>header</c> returns a HTTP 1.1 header string. The
- <c>StatusCode</c> is one of the status codes defined in RFC
- 2616 and the <c>Date</c> string is RFC 1123
- compliant. (See <seealso marker="#rfc1123_date">rfc1123_date/0</seealso>).
- </p>
- <p>Note that the two version of <c>header/n</c> that does not
- has a <c>PersistentConn</c> argument is there only for
- backward compatibility, and must not be used in new Erlang
- Webserver API modules. that will support persistent
- connections.</p>
-
- <marker id="hexlist_to_integer"></marker>
+ <p><c>flatlength/1</c> computes the size of the possibly nested
+ list <c>NestedList</c>, which can contain binaries.</p>
</desc>
</func>
--->
<func>
<name>hexlist_to_integer(HexString) -> Number</name>
- <fsummary>Convert a hexadecimal string to an integer.</fsummary>
+ <fsummary>Converts a hexadecimal string to an integer.</fsummary>
<type>
<v>Number = integer()</v>
<v>HexString = string()</v>
</type>
<desc>
- <p><c>hexlist_to_integer</c> Convert the Hexadecimal value of
- HexString to an integer.</p>
-
- <marker id="integer_to_hexlist"></marker>
+ <p><c>hexlist_to_integer</c> converts the hexadecimal value of
+ <c>HexString</c> to an integer.</p>
</desc>
</func>
<func>
<name>integer_to_hexlist(Number) -> HexString</name>
- <fsummary>Convert an integer to a hexadecimal string.</fsummary>
+ <fsummary>Converts an integer to a hexadecimal string.</fsummary>
<type>
<v>Number = integer()</v>
<v>HexString = string()</v>
</type>
<desc>
- <marker id="integer_to_hexlist"></marker>
- <p><c>integer_to_hexlist/1</c> Returns a string that represents
- the Number in a Hexadecimal form.</p>
-
- <marker id="lookup"></marker>
+ <p><c>integer_to_hexlist/1</c> returns a string representing
+ <c>Number</c> in a hexadecimal form.</p>
</desc>
</func>
<func>
<name>lookup(ETSTable,Key) -> Result</name>
<name>lookup(ETSTable,Key,Undefined) -> Result</name>
- <fsummary>Extract the first value associated with a key in an ETS table.</fsummary>
+ <fsummary>Extracts the first value associated with a <c>Key</c>
+ in an ETS table.</fsummary>
<type>
<v>ETSTable = ets_table()</v>
<v>Key = term()</v>
@@ -194,20 +151,18 @@
<desc>
<p><c>lookup</c> extracts <c>{Key,Value}</c> tuples from
<c>ETSTable</c> and returns the <c>Value</c> associated
- with <c>Key</c>. If <c>ETSTable</c> is of type <c>bag</c>
+ with <c>Key</c>. If <c>ETSTable</c> is of type <c>bag</c>,
only the first <c>Value</c> associated with <c>Key</c> is
returned. <c>lookup/2</c> returns <c>undefined</c> and
<c>lookup/3</c> returns <c>Undefined</c> if no <c>Value</c>
is found.</p>
-
- <marker id="lookup_mime"></marker>
</desc>
</func>
<func>
<name>lookup_mime(ConfigDB,Suffix)</name>
<name>lookup_mime(ConfigDB,Suffix,Undefined) -> MimeType</name>
- <fsummary>Return the mime type associated with a specific file suffix. </fsummary>
+ <fsummary>Returns the MIME type associated with a specific file suffix.</fsummary>
<type>
<v>ConfigDB = ets_table()</v>
<v>Suffix = string()</v>
@@ -215,20 +170,19 @@
<v>Undefined = term()</v>
</type>
<desc>
- <marker id="lookup_mime"></marker>
- <p><c>lookup_mime</c> returns the mime type associated with a
- specific file suffix as specified in the <c>mime.types</c>
- file (located in the
- <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">config directory</path>).</p>
-
- <marker id="lookup_mime_default"></marker>
+ <p><c>lookup_mime</c> returns the MIME type associated with a
+ specific file suffix as specified in the file <c>mime.types</c>
+ (located in the
+ <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">
+ config directory</path>).</p>
</desc>
</func>
<func>
<name>lookup_mime_default(ConfigDB,Suffix)</name>
<name>lookup_mime_default(ConfigDB,Suffix,Undefined) -> MimeType</name>
- <fsummary>Return the mime type associated with a specific file suffix or the value of the DefaultType.</fsummary>
+ <fsummary>Returns the MIME type associated with a specific file suffix
+ or the value of the DefaultType.</fsummary>
<type>
<v>ConfigDB = ets_table()</v>
<v>Suffix = string()</v>
@@ -236,22 +190,19 @@
<v>Undefined = term()</v>
</type>
<desc>
- <marker id="lookup_mime_default"></marker>
- <p><c>lookup_mime_default</c> returns the mime type associated
+ <p><c>lookup_mime_default</c> returns the MIME type associated
with a specific file suffix as specified in the
<c>mime.types</c> file (located in the
- <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">config directory</path>).
- If no appropriate association can be found
- the value of DefaultType is
+ <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">
+ config directory</path>).
+ If no appropriate association is found, the value of <c>DefaultType</c> is
returned.</p>
-
- <marker id="message"></marker>
</desc>
</func>
<func>
<name>message(StatusCode,PhraseArgs,ConfigDB) -> Message</name>
- <fsummary>Return an informative HTTP 1.1 status string in HTML.</fsummary>
+ <fsummary>Returns an informative HTTP 1.1 status string in HTML.</fsummary>
<type>
<v>StatusCode = 301 | 400 | 403 | 404 | 500 | 501 | 504</v>
<v>PhraseArgs = term()</v>
@@ -259,53 +210,48 @@
<v>Message = string()</v>
</type>
<desc>
- <marker id="message"></marker>
<p><c>message/3</c> returns an informative HTTP 1.1 status
string in HTML. Each <c>StatusCode</c> requires a specific
<c>PhraseArgs</c>:
</p>
<taglist>
<tag><c>301</c></tag>
- <item><c>string()</c>: A URL pointing at the new document
- position.</item>
+ <item><p><c>string()</c>: A URL pointing at the new document
+ position.</p></item>
<tag><c>400 | 401 | 500</c></tag>
- <item><c>none</c> (No <c>PhraseArgs</c>)</item>
+ <item><p><c>none</c> (no <c>PhraseArgs</c>).</p></item>
<tag><c>403 | 404</c></tag>
- <item><c>string()</c>: A <c>Request-URI</c> as described in
- RFC 2616.</item>
+ <item><p><c>string()</c>: A <c>Request-URI</c> as described in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.</p>
+ </item>
<tag><c>501</c></tag>
- <item><c>{Method,RequestURI,HTTPVersion}</c>: The HTTP
- <c>Method</c>, <c>Request-URI</c> and <c>HTTP-Version</c>
- as defined in RFC 2616.</item>
+ <item><p><c>{Method,RequestURI,HTTPVersion}</c>: The HTTP
+ <c>Method</c>, <c>Request-URI</c>, and <c>HTTP-Version</c>
+ as defined in RFC 2616.</p></item>
<tag><c>504</c></tag>
- <item><c>string()</c>: A string describing why the service
- was unavailable.</item>
+ <item><p><c>string()</c>: A string describing why the service
+ was unavailable.</p></item>
</taglist>
-
- <marker id="month"></marker>
</desc>
</func>
<func>
<name>month(NthMonth) -> Month</name>
- <fsummary>Convert the month as an integer (1-12) to an abbreviated string.</fsummary>
+ <fsummary>Converts the month as an integer (1-12) to an abbreviated string.</fsummary>
<type>
<v>NthMonth = 1-12</v>
<v>Month = string()</v>
</type>
<desc>
- <marker id="month"></marker>
<p><c>month/1</c> converts the month <c>NthMonth</c> as an
integer (1-12) to an abbreviated string, that is: </p>
<p>1 = "Jan", 2 = "Feb", ..., 12 = "Dec".</p>
-
- <marker id="multi_lookup"></marker>
</desc>
</func>
<func>
<name>multi_lookup(ETSTable,Key) -> Result</name>
- <fsummary>Extract the values associated with a key in a ETS table.</fsummary>
+ <fsummary>Extracts the values associated with a key in an ETS table.</fsummary>
<type>
<v>ETSTable = ets_table()</v>
<v>Key = term()</v>
@@ -313,49 +259,44 @@
</type>
<desc>
<p><c>multi_lookup</c> extracts all <c>{Key,Value}</c> tuples
- from an <c>ETSTable</c> and returns <em>all</em><c>Values</c> associated with the <c>Key</c> in a list.</p>
-
- <marker id="reason phrase"></marker>
+ from an <c>ETSTable</c> and returns <em>all</em> <c>Values</c>
+ associated with <c>Key</c> in a list.</p>
</desc>
</func>
<func>
<name>reason_phrase(StatusCode) -> Description</name>
- <fsummary>Return the description of an HTTP 1.1 status code.</fsummary>
+ <fsummary>Returns the description of an HTTP 1.1 status code.</fsummary>
<type>
- <v>StatusCode = 100| 200 | 201 | 202 | 204 | 205 | 206 | 300 | 301 | 302 | 303 | 304 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 410 411 | 412 | 413 | 414 415 | 416 | 417 | 500 | 501 | 502 | 503 | 504 | 505</v>
+ <v>StatusCode = 100| 200 | 201 | 202 | 204 | 205 | 206 | 300 | 301 | 302 | 303 | 304 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 410 411 | 412 | 413 | 414 415 | 416 | 417 | 500 | 501 | 502 | 503 | 504 | 505</v>
<v>Description = string()</v>
</type>
<desc>
- <p><c>reason_phrase</c> returns the <c>Description</c> of an
- HTTP 1.1 <c>StatusCode</c>, for example 200 is "OK" and 201
- is "Created". Read RFC 2616 for further information.</p>
-
- <marker id="rfc1123_date"></marker>
+ <p><c>reason_phrase</c> returns <c>Description</c> of an
+ HTTP 1.1 <c>StatusCode</c>, for example, 200 is "OK" and 201
+ is "Created". For more information, see
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.</p>
</desc>
</func>
<func>
<name>rfc1123_date() -> RFC1123Date</name>
<name>rfc1123_date({{YYYY,MM,DD},{Hour,Min,Sec}}) -> RFC1123Date</name>
- <fsummary>Return the current date in RFC 1123 format.</fsummary>
+ <fsummary>Returns the current date in RFC 1123 format.</fsummary>
<type>
<v>YYYY = MM = DD = Hour = Min = Sec = integer()</v>
<v>RFC1123Date = string()</v>
</type>
<desc>
- <marker id="rfc1123_date"></marker>
<p><c>rfc1123_date/0</c> returns the current date in RFC 1123
format. <c>rfc_date/1</c> converts the date in the Erlang format
to the RFC 1123 date format.</p>
-
- <marker id="split"></marker>
</desc>
</func>
<func>
<name>split(String,RegExp,N) -> SplitRes</name>
- <fsummary>Split a string in N chunks using a regular expression.</fsummary>
+ <fsummary>Splits a string in N chunks using a regular expression.</fsummary>
<type>
<v>String = RegExp = string()</v>
<v>SplitRes = {ok, FieldList} | {error, errordesc()}</v>
@@ -363,96 +304,86 @@
<v>N = integer</v>
</type>
<desc>
- <marker id="split"></marker>
- <p><c>split/3</c> splits the <c>String</c> in <c>N</c> chunks
- using the <c>RegExp</c>. <c>split/3</c> is is equivalent to
- <c>regexp:split/2</c> with one exception, that is <c>N</c>
- defines the number of maximum number of fields in the
+ <p><c>split/3</c> splits <c>String</c> in <c>N</c> chunks
+ using <c>RegExp</c>. <c>split/3</c> is equivalent to
+ <c>regexp:split/2</c> with the exception that <c>N</c>
+ defines the maximum number of fields in
<c>FieldList</c>.</p>
-
- <marker id="split_script_path"></marker>
</desc>
</func>
<func>
<name>split_script_path(RequestLine) -> Splitted</name>
- <fsummary>Split a <c>RequestLine</c>in a file reference to an executable and a<c>QueryString</c>or a <c>PathInfo</c>string.</fsummary>
+ <fsummary>Splits a <c>RequestLine</c> in a file reference to an executable,
+ and a <c>QueryString</c> or a <c>PathInfo</c>string.</fsummary>
<type>
<v>RequestLine = string()</v>
<v>Splitted = not_a_script | {Path, PathInfo, QueryString}</v>
<v>Path = QueryString = PathInfo = string()</v>
</type>
<desc>
- <marker id="split_script_path"></marker>
<p><c>split_script_path/1</c> is equivalent to
<c>split_path/1</c> with one exception. If the longest
- possible path is not a regular, accessible and executable
- file <c>not_a_script</c> is returned.</p>
-
- <marker id="split_path"></marker>
+ possible path is not a regular, accessible, and executable
+ file, then <c>not_a_script</c> is returned.</p>
</desc>
</func>
<func>
<name>split_path(RequestLine) -> {Path,QueryStringOrPathInfo}</name>
- <fsummary>Split a <c>RequestLine</c>in a file reference and a <c>QueryString</c>or a<c>PathInfo</c>string.</fsummary>
+ <fsummary>Splits a <c>RequestLine</c> in a file reference, and a
+ <c>QueryString</c> or a <c>PathInfo</c> string.</fsummary>
<type>
<v>RequestLine = Path = QueryStringOrPathInfo = string()</v>
</type>
<desc>
- <marker id="split_path"></marker>
- <p><c>split_path/1</c> splits the <c>RequestLine</c> in a file
- reference (<c>Path</c>) and a <c>QueryString</c> or a
- <c>PathInfo</c> string as specified in RFC 2616. A
- <c>QueryString</c> is isolated from the <c>Path</c> with a
+ <p><c>split_path/1</c> splits <c>RequestLine</c> in a file
+ reference (<c>Path</c>), and a <c>QueryString</c> or a
+ <c>PathInfo</c> string as specified in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.
+ A <c>QueryString</c> is isolated from <c>Path</c> with a
question mark (<c>?</c>) and <c>PathInfo</c> with a slash
(/). In the case of a <c>QueryString</c>, everything before
- the <c>?</c> is a <c>Path</c> and everything after a
- <c>QueryString</c>. In the case of a <c>PathInfo</c> the
+ <c>?</c> is a <c>Path</c> and everything after <c>?</c> is a
+ <c>QueryString</c>. In the case of a <c>PathInfo</c>,
<c>RequestLine</c> is scanned from left-to-right on the hunt
for longest possible <c>Path</c> being a file or a
directory. Everything after the longest possible
<c>Path</c>, isolated with a <c>/</c>, is regarded as
<c>PathInfo</c>. The resulting <c>Path</c> is decoded using
<c>decode_hex/1</c> before delivery.</p>
-
- <marker id="strip"></marker>
</desc>
</func>
<func>
<name>strip(String) -> Stripped</name>
- <fsummary>Returns String where the leading and trailing space and tabs has been removed.</fsummary>
+ <fsummary>Returns <c>String</c> where the leading and trailing space
+ tabs are removed.</fsummary>
<type>
<v>String = Stripped = string()</v>
</type>
<desc>
- <marker id="strip"></marker>
<p><c>strip/1</c> removes any leading or trailing linear white
- space from the string. Linear white space should be read as
+ space from the string. Linear white space is to be read as
horizontal tab or space.</p>
-
- <marker id="suffix"></marker>
</desc>
</func>
<func>
<name>suffix(FileName) -> Suffix</name>
- <fsummary>Extract the file suffix from a given filename.</fsummary>
+ <fsummary>Extracts the file suffix from a given filename.</fsummary>
<type>
<v>FileName = Suffix = string()</v>
</type>
<desc>
- <marker id="suffix"></marker>
<p><c>suffix/1</c> is equivalent to
- <c>filename:extension/1</c> with one exception, that is
- <c>Suffix</c> is returned without a leading dot (<c>.</c>). </p>
+ <c>filename:extension/1</c> with the exception that
+ <c>Suffix</c> is returned without a leading dot (<c>.</c>).</p>
</desc>
</func>
</funcs>
<section>
- <marker id="see_also"></marker>
<title>SEE ALSO</title>
<p><seealso marker="httpd">httpd(3)</seealso></p>
</section>
diff --git a/lib/inets/doc/src/inets.xml b/lib/inets/doc/src/inets.xml
index 8c3a677966..5d071c9a48 100644
--- a/lib/inets/doc/src/inets.xml
+++ b/lib/inets/doc/src/inets.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,21 +30,21 @@
<rev></rev>
</header>
<module>inets</module>
- <modulesummary>The inets services API</modulesummary>
+ <modulesummary>The Inets services API.</modulesummary>
<description>
<p>This module provides the most basic API to the
- clients and servers, that are part of the Inets application,
- such as start and stop. </p>
+ clients and servers that are part of the <c>Inets</c> application,
+ such as start and stop.</p>
<marker id="common_data_types"></marker>
</description>
<section>
- <title>COMMON DATA TYPES </title>
+ <title>DATA TYPES</title>
<p>Type definitions that are used more than once in
- this module: </p>
- <p><c> service() = ftpc | tftp | httpc | httpd</c></p>
- <p><c> property() = atom() </c></p>
+ this module:</p>
+ <p><c>service() = ftpc | tftp | httpc | httpd</c></p>
+ <p><c>property() = atom()</c></p>
<marker id="functions"></marker>
<marker id="services"></marker>
</section>
@@ -51,7 +52,7 @@
<funcs>
<func>
<name>services() -> [{Service, Pid}]</name>
- <fsummary>Returns a list of currently running services. </fsummary>
+ <fsummary>Returns a list of currently running services.</fsummary>
<type>
<v>Service = service()</v>
<v>Pid = pid()</v>
@@ -59,7 +60,7 @@
<desc>
<p>Returns a list of currently running services.</p>
<note>
- <p>Services started as <c>stand_alone</c> will not be listed.</p>
+ <p>Services started as <c>stand_alone</c> are not listed.</p>
</note>
<marker id="services_info"></marker>
@@ -69,8 +70,8 @@
<func>
<name>services_info() -> [{Service, Pid, Info}]</name>
<fsummary>Returns a list of currently running services where
- each service is described by a [{Option, Value}]
- list. </fsummary>
+ each service is described by an <c>[{Option, Value}]</c>
+ list.</fsummary>
<type>
<v>Service = service()</v>
<v>Pid = pid()</v>
@@ -80,11 +81,10 @@
</type>
<desc>
<p>Returns a list of currently running services where each
- service is described by a [{Option, Value}] list. The
- information given in the list is specific for each service
- and it is probable that each service will have its own info
- function that gives you even more details about the
- service.</p>
+ service is described by an <c>[{Option, Value}]</c> list. The
+ information in the list is specific for each service
+ and each service has probably its own info
+ function that gives more details about the service.</p>
<marker id="service_names"></marker>
</desc>
@@ -106,59 +106,48 @@
<func>
<name>start() -> </name>
<name>start(Type) -> ok | {error, Reason}</name>
- <fsummary>Starts the Inets application. </fsummary>
+ <fsummary>Starts the <c>Inets</c> application.</fsummary>
<type>
<v>Type = permanent | transient | temporary</v>
</type>
<desc>
- <p>Starts the Inets application. Default type
- is temporary. See also
- <seealso marker="kernel:application">application(3)</seealso>. </p>
+ <p>Starts the <c>Inets</c> application. Default type
+ is <c>temporary</c>. See also
+ <seealso marker="kernel:application">application(3)</seealso>.</p>
<marker id="stop"></marker>
</desc>
</func>
<func>
- <name>stop() -> ok </name>
- <fsummary>Stops the inets application.</fsummary>
- <desc>
- <p>Stops the inets application. See also
- <seealso marker="kernel:application">application(3)</seealso>. </p>
-
- <marker id="start2"></marker>
- </desc>
- </func>
-
- <func>
<name>start(Service, ServiceConfig) -> {ok, Pid} | {error, Reason}</name>
<name>start(Service, ServiceConfig, How) -> {ok, Pid} | {error, Reason}</name>
- <fsummary>Dynamically starts an inets
- service after the inets application has been started. </fsummary>
+ <fsummary>Dynamically starts an <c>Inets</c>
+ service after the <c>Inets</c> application has been started.</fsummary>
<type>
<v>Service = service()</v>
<v>ServiceConfig = [{Option, Value}]</v>
<v>Option = property()</v>
<v>Value = term()</v>
- <v>How = inets | stand_alone - default is inets</v>
+ <v>How = inets | stand_alone - default is inets.</v>
</type>
<desc>
- <p>Dynamically starts an inets service after the inets
- application has been started. </p>
+ <p>Dynamically starts an <c>Inets</c> service after the <c>Inets</c>
+ application has been started.</p>
<note>
- <p>Dynamically started services will not be handled by
- application takeover and failover behavior when inets is
- run as a distributed application. Nor will they be
- automatically restarted when the inets application is
- restarted, but as long as the inets application is up and
- running they will be supervised and may be soft code
- upgraded. Services started as <c>stand_alone</c>,
- e.i. the service is not started as part of the inets
- application, will lose all OTP application benefits such
- as soft upgrade. The "stand_alone-service" will be linked to
- the process that started it. In most cases some of the
- supervision functionality will still be in place and in
- some sense the calling process has now become the top
+ <p>Dynamically started services are not handled by
+ application takeover and failover behavior when <c>Inets</c> is
+ run as a distributed application. Nor are they
+ automatically restarted when the <c>Inets</c> application is
+ restarted. As long as the <c>Inets</c> application is operational,
+ they are supervised and can be soft code upgraded.</p>
+ <p>A service started as <c>stand_alone</c>, that is, the service
+ is not started as part of the <c>Inets</c> application,
+ lose all OTP application benefits, such as soft upgrade.
+ The <c>stand_alone</c>-service is linked to
+ the process that started it. Usually some
+ supervision functionality is still in place and in
+ some sense the calling process becomes the top
supervisor.</p>
</note>
@@ -166,19 +155,30 @@
</desc>
</func>
+ <func>
+ <name>stop() -> ok </name>
+ <fsummary>Stops the <c>Inets</c> application.</fsummary>
+ <desc>
+ <p>Stops the <c>Inets</c> application. See also
+ <seealso marker="kernel:application">application(3)</seealso>.</p>
+
+ <marker id="start2"></marker>
+ </desc>
+ </func>
+
<func>
<name>stop(Service, Reference) -> ok | {error, Reason} </name>
- <fsummary>Stops a started service of the inets application or takes
- down a "stand_alone-service" gracefully.</fsummary>
+ <fsummary>Stops a started service of the <c>Inets</c> application or takes
+ down a <c>stand_alone </c>service gracefully.</fsummary>
<type>
<v>Service = service() | stand_alone</v>
- <v>Reference = pid() | term() - service specified reference</v>
+ <v>Reference = pid() | term() - service-specified reference</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Stops a started service of the inets application or takes
- down a "stand_alone-service" gracefully. When the
- <c>stand_alone</c> option is used in start,
+ <p>Stops a started service of the <c>Inets</c> application or takes
+ down a <c>stand_alone</c>-service gracefully. When option
+ <c>stand_alone</c> is used in start,
only the pid is a valid argument to stop.</p>
<marker id="see_also"></marker>
diff --git a/lib/inets/doc/src/inets_services.xml b/lib/inets/doc/src/inets_services.xml
index 8cd0794ff2..d100216ebb 100644
--- a/lib/inets/doc/src/inets_services.xml
+++ b/lib/inets/doc/src/inets_services.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Introduction</title>
+ <title>Inets</title>
<prepared>Ingela Anderton Andin</prepared>
<responsible></responsible>
<docno></docno>
@@ -33,45 +34,26 @@
</header>
<section>
- <title>Purpose</title>
- <p>Inets is a container for Internet clients and
- servers. Currently, an <term id="HTTP"></term>client and server, a
- TFPT client and server, and a FTP client has been incorporated
- into Inets. The HTTP server and client is HTTP 1.1 compliant as
- defined in <term id="RFC"></term>2616.</p>
- </section>
-
- <section>
- <title>Prerequisites</title>
- <p>It is assumed that the reader is familiar with the Erlang
- programming language, concepts of OTP and has a basic
- understanding of the HTTP, TFTP and FTP protocols.</p>
- </section>
-
- <section>
- <title>The Service Concept</title>
- <p>Each client and server in inets is viewed as service. Services
- may be configured to be started at application startup or
- started dynamically in runtime. If you want to run inets as an
- distributed application that should handle application failover
- and takeover, services should be configured to be started at
- application startup. When starting the inets application
- the inets top supervisor will start a number of subsupervisors
- and worker processes for handling the different services
- provided. When starting services dynamically new children will
- be added to the supervision tree, unless the service is started
- with the stand alone option, in which case the service is linked
- to the calling process and all OTP application features such as
- soft upgrade are lost.</p>
- <p>Services that should be configured for startup at application
- startup time should be put into the erlang node configuration file
- on the form: </p>
+ <title>Service Concept</title>
+ <p>Each client and server in <c>Inets</c> is viewed as a service.
+ Services can be configured to be started at application startup or
+ dynamically in runtime. To run <c>Inets</c> as a distributed
+ application that handles application failover and takeover,
+ configure the services to be started at application startup.
+ When starting the <c>Inets</c> application, the <c>Inets</c>
+ top supervisor starts a number of subsupervisors and worker
+ processes for handling the provided services.
+ When starting services dynamically, new children are added to the
+ supervision tree, unless the service is started with the standalone
+ option. In this case the service is linked to the calling process
+ and all OTP application features, such as soft upgrade, are lost.</p>
+ <p>Services to be configured for startup at application startup are to
+ be put into the Erlang node configuration file
+ on the following form:</p>
<pre>
- [{inets, [{services, ListofConfiguredServices}]}].
- </pre>
- <p>For details of exactly what to put in the list of configured
- services see the documentation for the services that should be
- configured.</p>
+ [{inets, [{services, ListofConfiguredServices}]}].</pre>
+ <p>For details of what to put in the list of configured services,
+ see the documentation for the services to be configured.</p>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_App_D.xmlsrc b/lib/inets/doc/src/introduction.xml
index b7a4c270ad..491835f852 100644
--- a/lib/mnesia/doc/src/Mnesia_App_D.xmlsrc
+++ b/lib/inets/doc/src/introduction.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2013</year>
+ <year>1997</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,23 +21,37 @@
</legalnotice>
- <title>Appendix D: The Fragmented Table Hashing Call Back Interface</title>
- <prepared>H&aring;kan Mattsson</prepared>
+ <title>Introduction</title>
+ <prepared>Ingela Anderton Andin</prepared>
<responsible></responsible>
<docno></docno>
<approved></approved>
<checked></checked>
- <date></date>
- <rev></rev>
- <file>Mnesia_App_D.xml</file>
+ <date>2004-09-28</date>
+ <rev>A</rev>
+ <file>introduction.xml</file>
</header>
<section>
- <title>mnesia_frag_hash callback behavior</title>
- <p></p>
- <codeinclude file="../../src/mnesia_frag_hash.erl" tag="%header_doc_include" type="erl"></codeinclude>
- <p></p>
- <codeinclude file="../../src/mnesia_frag_hash.erl" tag="%impl_doc_include" type="erl"></codeinclude>
+ <title>Purpose</title>
+ <p><c>Inets</c> is a container for Internet clients and servers
+ including the following:</p>
+ <list type="bulleted">
+ <item>An FTP client</item>
+ <item>A TFTP client and server</item>
+ <item>An <term id="HTTP"></term> client and server</item>
+ </list>
+ <p>The HTTP client and server are HTTP 1.1 compliant as
+ defined in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.</p>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language, concepts of OTP, and has a basic
+ understanding of the FTP, TFTP, and HTTP protocols.</p>
</section>
</chapter>
+
diff --git a/lib/inets/doc/src/mod_alias.xml b/lib/inets/doc/src/mod_alias.xml
index e4c78a5b15..87c950cc6b 100644
--- a/lib/inets/doc/src/mod_alias.xml
+++ b/lib/inets/doc/src/mod_alias.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,8 +32,8 @@
<module>mod_alias</module>
<modulesummary>URL aliasing.</modulesummary>
<description>
- <p>Erlang Webserver Server internal API for handling of things
- such as interaction data exported by the mod_alias module.</p>
+ <p>Erlang web server internal API for handling of, for example,
+ interaction data exported by module <c>mod_alias</c>.</p>
<marker id="default_index"></marker>
</description>
@@ -40,7 +41,7 @@
<funcs>
<func>
<name>default_index(ConfigDB, Path) -> NewPath</name>
- <fsummary>Return a new path with the default resource or file appended.</fsummary>
+ <fsummary>Returns a new path with the default resource or file appended.</fsummary>
<type>
<v>ConfigDB = config_db()</v>
<v>Path = NewPath = string()</v>
@@ -49,14 +50,14 @@
<marker id="default_index"></marker>
<p>If <c>Path</c> is a directory, <c>default_index/2</c>, it starts
searching for resources or files that are specified in the config
- directive DirectoryIndex.
+ directive <c>DirectoryIndex</c>.
If an appropriate resource or file is found, it is appended to
the end of <c>Path</c> and then returned. <c>Path</c> is
- returned unaltered, if no appropriate
- file is found, or if <c>Path</c> is not a directory.
+ returned unaltered if no appropriate
+ file is found or if <c>Path</c> is not a directory.
<c>config_db()</c> is the server config file in ETS table format
as described in
- <seealso marker="http_server">Inets Users Guide.</seealso>.</p>
+ <seealso marker="http_server">Inets User's Guide</seealso>.</p>
<marker id="path"></marker>
</desc>
@@ -64,7 +65,7 @@
<func>
<name>path(PathData, ConfigDB, RequestURI) -> Path</name>
- <fsummary>Return the actual file path to a URL.</fsummary>
+ <fsummary>Returns the file path to a URL.</fsummary>
<type>
<v>PathData = interaction_data()</v>
<v>ConfigDB = config_db()</v>
@@ -72,15 +73,16 @@
</type>
<desc>
<marker id="path"></marker>
- <p><c>path/3</c> returns the actual file <c>Path</c> in the
- <c>RequestURI</c> (See RFC 1945). If the interaction data
- <c>{real_name,{Path,AfterPath}}</c> has been exported by
- mod_alias;
+ <p><c>path/3</c> returns the file <c>Path</c> in the
+ <c>RequestURI</c> (see
+ <url href="http://www.rfc-base.org/rfc-1945.html">RFC 1945</url>).
+ If the interaction data <c>{real_name,{Path,AfterPath}}</c>
+ has been exported by <c>mod_alias</c>,
<c>Path</c> is returned. If no interaction data has been
- exported, ServerRoot is used to
+ exported, <c>ServerRoot</c> is used to
generate a file <c>Path</c>. <c>config_db()</c> and
<c>interaction_data()</c> are as defined in
- <seealso marker="http_server">Inets Users Guide</seealso>.</p>
+ <seealso marker="http_server">Inets User's Guide</seealso>.</p>
<marker id="real_name"></marker>
</desc>
@@ -88,7 +90,7 @@
<func>
<name>real_name(ConfigDB, RequestURI, Aliases) -> Ret</name>
- <fsummary>Expand a request uri using Alias config directives.</fsummary>
+ <fsummary>Expands a request URI using <c>Aliases</c> config directives.</fsummary>
<type>
<v>ConfigDB = config_db()</v>
<v>RequestURI = string()</v>
@@ -100,18 +102,18 @@
<marker id="real_name"></marker>
<p><c>real_name/3</c> traverses <c>Aliases</c>, typically
extracted from <c>ConfigDB</c>, and matches each
- <c>FakeName</c> with <c>RequestURI</c>. If a match is found
+ <c>FakeName</c> with <c>RequestURI</c>. If a match is found,
<c>FakeName</c> is replaced with <c>RealName</c> in the
- match. The resulting path is split into two parts, that
- is <c>ShortPath</c> and <c>AfterPath</c> as defined in
- <seealso marker="httpd_util#split_path">httpd_util:split_path/1</seealso>.
- <c>Path</c> is generated from <c>ShortPath</c>, that is
+ match. The resulting path is split into two parts,
+ <c>ShortPath</c> and <c>AfterPath</c>, as defined in
+ <seealso marker="httpd_util#split_path-1">httpd_util:split_path/1</seealso>.
+ <c>Path</c> is generated from <c>ShortPath</c>, that is,
the result from
<seealso marker="#default_index">default_index/2</seealso> with
<c>ShortPath</c> as an argument.
<c>config_db()</c> is the server config file in ETS table
format as described in
- <seealso marker="http_server">Inets User Guide.</seealso>. </p>
+ <seealso marker="http_server">Inets User's Guide</seealso>.</p>
<marker id="real_script_name"></marker>
</desc>
@@ -119,7 +121,8 @@
<func>
<name>real_script_name(ConfigDB, RequestURI, ScriptAliases) -> Ret</name>
- <fsummary>Expand a request uri using ScriptAlias config directives.</fsummary>
+ <fsummary>Expands a request URI using <c>ScriptAliases</c>
+ config directives.</fsummary>
<type>
<v>ConfigDB = config_db()</v>
<v>RequestURI = string()</v>
@@ -131,14 +134,16 @@
<marker id="real_script_name"></marker>
<p><c>real_script_name/3</c> traverses <c>ScriptAliases</c>,
typically extracted from <c>ConfigDB</c>, and matches each
- <c>FakeName</c> with <c>RequestURI</c>. If a match is found
+ <c>FakeName</c> with <c>RequestURI</c>. If a match is found,
<c>FakeName</c> is replaced with <c>RealName</c> in the
- match. If the resulting match is not an executable script
- <c>not_a_script</c> is returned. If it is a script the
- resulting script path is in two parts, that is
- <c>ShortPath</c> and <c>AfterPath</c> as defined in <seealso marker="httpd_util#split_script_path">httpd_util:split_script_path/1</seealso>.
+ match. If the resulting match is not an executable script,
+ <c>not_a_script</c> is returned. If it is a script, the
+ resulting script path is in two parts,
+ <c>ShortPath</c> and <c>AfterPath</c>, as defined in
+ <seealso marker="httpd_util#split_script_path-1">httpd_util:split_script_path/1</seealso>.
<c>config_db()</c> is the server config file in ETS table
- format as described in <seealso marker="http_server">Inets Users Guide.</seealso>.</p>
+ format as described in
+ <seealso marker="http_server">Inets User's Guide</seealso>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/inets/doc/src/mod_auth.xml b/lib/inets/doc/src/mod_auth.xml
index e941b799a1..2da2be37ed 100644
--- a/lib/inets/doc/src/mod_auth.xml
+++ b/lib/inets/doc/src/mod_auth.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,299 +30,267 @@
<file>mod_auth.sgml</file>
</header>
<module>mod_auth</module>
- <modulesummary>User authentication using text files, dets or mnesia database.</modulesummary>
+ <modulesummary>User authentication using text files, Dets, or Mnesia database.</modulesummary>
<description>
<p>This module provides for basic user authentication using
- textual files, dets databases as well as mnesia databases. </p>
-
- <marker id="add_user"></marker>
+ textual files, <c>Dets</c> databases, or <c>Mnesia</c> databases.</p>
</description>
<funcs>
+ <func>
+ <name>add_group_member(GroupName, UserName, Options) -> true | {error, Reason}</name>
+ <name>add_group_member(GroupName, UserName, Port, Dir) -> true | {error, Reason}</name>
+ <name>add_group_member(GroupName, UserName, Address, Port, Dir) -> true | {error, Reason}</name>
+ <fsummary>Adds a user to a group.</fsummary>
+ <type>
+ <v>GroupName = string()</v>
+ <v>UserName = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>AuthPassword = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p><c>add_group_member/3, add_group_member/4</c>, and
+ <c>add_group_member/5</c> each
+ adds a user to a group. If the group does not exist, it
+ is created and the user is added to the group. Upon successful
+ operation, this function returns <c>true</c>.
+ When <c>add_group_members/3</c>
+ is called, options <c>Port</c> and <c>Dir</c> are mandatory.</p>
+ </desc>
+ </func>
+
<func>
- <name>add_user(UserName, Options) -> true| {error, Reason}</name>
+ <name>add_user(UserName, Options) -> true| {error, Reason}</name>
<name>add_user(UserName, Password, UserData, Port, Dir) -> true | {error, Reason}</name>
<name>add_user(UserName, Password, UserData, Address, Port, Dir) -> true | {error, Reason}</name>
- <fsummary>Add a user to the user database.</fsummary>
+ <fsummary>Adds a user to the user database.</fsummary>
<type>
- <v>UserName = string()</v>
- <v>Options = [Option]</v>
- <v>Option = {password,Password} | {userData,UserData} | {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Password = string()</v>
- <v>UserData = term()</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
+ <v>UserName = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {password,Password} | {userData,UserData} | {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Password = string()</v>
+ <v>UserData = term()</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
<v>AuthPassword =string()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="user_api"></marker>
- <marker id="add_user"></marker>
- <p><c>add_user/2, add_user/5</c> and <c>add_user/6</c> adds a
- user to the user
- database. If the operation is successful, this function returns
- <c>true</c>. If an error occurs, <c>{error,Reason}</c> is returned.
- When <c>add_user/2</c> is called the Password,
- UserData Port and Dir options is mandatory.</p>
-
- <marker id="delete_user"></marker>
+ <p><c>add_user/2, add_user/5</c>, and <c>add_user/6</c> each adds a
+ user to the user database. If the operation is successful,
+ this function returns <c>true</c>. If an error occurs,
+ <c>{error,Reason}</c> is returned.
+ When <c>add_user/2</c> is called, options <c>Password</c>,
+ <c>UserData</c>, <c>Port</c>, and <c>Dir</c> are mandatory.</p>
</desc>
</func>
- <func>
- <name>delete_user(UserName,Options) -> true | {error, Reason}</name>
- <name>delete_user(UserName, Port, Dir) -> true | {error, Reason}</name>
- <name>delete_user(UserName, Address, Port, Dir) -> true | {error, Reason}</name>
- <fsummary>Delete a user from the user database.</fsummary>
+ <func>
+ <name>delete_group(GroupName, Options) -> true | {error,Reason} &lt;name>delete_group(GroupName, Port, Dir) -> true | {error, Reason}</name>
+ <name>delete_group(GroupName, Address, Port, Dir) -> true | {error, Reason}</name>
+ <fsummary>Deletes a group.</fsummary>
<type>
- <v>UserName = string()</v>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>GroupName = string()</v>
<v>AuthPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="delete_user"></marker>
- <p><c>delete_user/2, delete_user/3</c> and <c>delete_user/4</c>
- deletes a user from the user database.
- If the operation is successful, this function returns <c>true</c>.
- If an error occurs, <c>{error,Reason}</c> is returned.
- When <c>delete_user/2</c> is called the Port and Dir options
- are mandatory.</p>
-
- <marker id="get_user"></marker>
+ <p><c>delete_group/2, delete_group/3</c>, and <c>delete_group/4</c>
+ each deletes the group specified and returns <c>true</c>.
+ If there is an error, <c>{error, Reason}</c> is returned.
+ When <c>delete_group/2</c> is called, option
+ <c>Port</c> and <c>Dir</c> are mandatory.</p>
</desc>
</func>
- <func>
- <name>get_user(UserName,Options) -> {ok, #httpd_user} |{error, Reason}</name>
- <name>get_user(UserName, Port, Dir) -> {ok, #httpd_user} | {error, Reason}</name>
- <name>get_user(UserName, Address, Port, Dir) -> {ok, #httpd_user} | {error, Reason}</name>
- <fsummary>Returns a user from the user database.</fsummary>
+ <func>
+ <name>delete_group_member(GroupName, UserName, Options) -> true | {error, Reason}</name>
+ <name>delete_group_member(GroupName, UserName, Port, Dir) -> true | {error, Reason}</name>
+ <name>delete_group_member(GroupName, UserName, Address, Port, Dir) -> true | {error, Reason}</name>
+ <fsummary>Removes a user from a group.</fsummary>
<type>
- <v>UserName = string()</v>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
+ <v>GroupName = string()</v>
+ <v>UserName = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
<v>AuthPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="get_user"></marker>
- <p><c>get_user/2, get_user/3</c> and <c>get_user/4</c> returns a
- <c>httpd_user</c> record containing the userdata for a
- specific user. If the user cannot be found, <c>{error, Reason}</c>
- is returned. When <c>get_user/2</c> is called the Port and Dir
- options are mandatory.</p>
-
- <marker id="list_users"></marker>
+ <p><c>delete_group_member/3, delete_group_member/4</c>, and
+ <c>delete_group_member/5</c> each deletes a user from a group.
+ If the group or the user does not exist,
+ this function returns an error, otherwise <c>true</c>.
+ When <c>delete_group_member/3</c> is called, the options <c>Port</c>
+ and <c>Dir</c> are mandatory.</p>
</desc>
</func>
-
+
<func>
- <name>list_users(Options) -> {ok, Users} | {error, Reason}</name>
- <name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name>
- <name>list_users(Address, Port, Dir) -> {ok, Users} | {error, Reason}</name>
- <fsummary>List users in the user database.</fsummary>
+ <name>delete_user(UserName,Options) -> true | {error, Reason}</name>
+ <name>delete_user(UserName, Port, Dir) -> true | {error, Reason}</name>
+ <name>delete_user(UserName, Address, Port, Dir) -> true | {error, Reason}</name>
+ <fsummary>Deletes a user from the user database.</fsummary>
<type>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>Users = list()</v>
+ <v>UserName = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
<v>AuthPassword = string()</v>
- <v>Reason = atom()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="list_users"></marker>
- <p><c>list_users/1, list_users/2</c> and <c>list_users/3</c>
- returns a list
- of users in the user database for a specific <c>Port/Dir</c>.
- When <c>list_users/1</c> is called the Port and Dir
- options are mandatory.</p>
-
- <marker id="add_group_member"></marker>
+ <p><c>delete_user/2, delete_user/3</c>, and <c>delete_user/4</c>
+ each deletes a user from the user database.
+ If the operation is successful, this function returns <c>true</c>.
+ If an error occurs, <c>{error,Reason}</c> is returned.
+ When <c>delete_user/2</c> is called, options <c>Port</c> and <c>Dir</c>
+ are mandatory.</p>
</desc>
</func>
<func>
- <name>add_group_member(GroupName, UserName, Options) -> true | {error, Reason}</name>
- <name>add_group_member(GroupName, UserName, Port, Dir) -> true | {error, Reason}</name>
- <name>add_group_member(GroupName, UserName, Address, Port, Dir) -> true | {error, Reason}</name>
- <fsummary>Add a user to a group.</fsummary>
+ <name>get_user(UserName,Options) -> {ok, #httpd_user} |{error, Reason}</name>
+ <name>get_user(UserName, Port, Dir) -> {ok, #httpd_user} | {error, Reason}</name>
+ <name>get_user(UserName, Address, Port, Dir) -> {ok, #httpd_user} | {error, Reason}</name>
+ <fsummary>Returns a user from the user database.</fsummary>
<type>
- <v>GroupName = string()</v>
- <v>UserName = string()</v>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
+ <v>UserName = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
<v>AuthPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="add_group_member"></marker>
- <p><c>add_group_member/3, add_group_member/4</c> and
- <c>add_group_member/5</c>
- adds a user to a group. If the group does not exist, it
- is created and the user is added to the group. Upon successful
- operation, this function returns <c>true</c>.
- When <c>add_group_members/3</c>
- is called the Port and Dir options are mandatory.</p>
-
- <marker id="delete_group_member"></marker>
+ <p><c>get_user/2, get_user/3</c>, and <c>get_user/4</c> each
+ returns an <c>httpd_user</c> record containing the userdata for a
+ specific user. If the user cannot be found, <c>{error, Reason}</c>
+ is returned. When <c>get_user/2</c> is called, options <c>Port</c> and <c>Dir</c>
+ are mandatory.</p>
</desc>
</func>
- <func>
- <name>delete_group_member(GroupName, UserName, Options) -> true | {error, Reason}</name>
- <name>delete_group_member(GroupName, UserName, Port, Dir) -> true | {error, Reason}</name>
- <name>delete_group_member(GroupName, UserName, Address, Port, Dir) -> true | {error, Reason}</name>
- <fsummary>Remove a user from a group.</fsummary>
+ <func>
+ <name>list_groups(Options) -> {ok, Groups} | {error, Reason}</name>
+ <name>list_groups(Port, Dir) -> {ok, Groups} | {error, Reason}</name>
+ <name>list_groups(Address, Port, Dir) -> {ok, Groups} | {error, Reason}</name>
+ <fsummary>Lists all the groups.</fsummary>
<type>
- <v>GroupName = string()</v>
- <v>UserName = string()</v>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>Groups = list()</v>
<v>AuthPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="delete_group_member"></marker>
- <p><c>delete_group_member/3, delete_group_member/4</c> and
- <c>delete_group_member/5</c> deletes a user from a group.
- If the group or the user does not exist,
- this function returns an error, otherwise it returns <c>true</c>.
- When <c>delete_group_member/3</c> is called the Port and Dir options
- are mandatory.</p>
-
- <marker id="list_group_members"></marker>
+ <p><c>list_groups/1, list_groups/2</c>, and <c>list_groups/3</c>
+ each lists all the groups available.
+ If there is an error, <c>{error, Reason}</c> is returned.
+ When <c>list_groups/1</c> is called, options <c>Port</c>
+ and <c>Dir</c> are mandatory.</p>
</desc>
</func>
-
+
<func>
<name>list_group_members(GroupName, Options) -> {ok, Users} | {error, Reason}</name>
<name>list_group_members(GroupName, Port, Dir) -> {ok, Users} | {error, Reason}</name>
<name>list_group_members(GroupName, Address, Port, Dir) -> {ok, Users} | {error, Reason}</name>
- <fsummary>List the members of a group.</fsummary>
+ <fsummary>Lists the members of a group.</fsummary>
<type>
- <v>GroupName = string()</v>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>Users = list()</v>
+ <v>GroupName = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>Users = list()</v>
<v>AuthPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="list_group_members"></marker>
- <p><c>list_group_members/2, list_group_members/3</c> and
- <c>list_group_members/4</c>
+ <p><c>list_group_members/2, list_group_members/3</c>, and
+ <c>list_group_members/4</c> each
lists the members of a specified group. If the group does not
exist or there is an error, <c>{error, Reason}</c> is returned.
- When <c>list_group_members/2</c> is called the Port and Dir options
- are mandatory.</p>
-
- <marker id="list_groups"></marker>
+ When <c>list_group_members/2</c> is called, options <c>Port</c>
+ and <c>Dir</c> are mandatory.</p>
</desc>
</func>
- <func>
- <name>list_groups(Options) -> {ok, Groups} | {error, Reason}</name>
- <name>list_groups(Port, Dir) -> {ok, Groups} | {error, Reason}</name>
- <name>list_groups(Address, Port, Dir) -> {ok, Groups} | {error, Reason}</name>
- <fsummary>List all the groups.</fsummary>
+ <func>
+ <name>list_users(Options) -> {ok, Users} | {error, Reason}</name>
+ <name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name>
+ <name>list_users(Address, Port, Dir) -> {ok, Users} | {error, Reason}</name>
+ <fsummary>Lists users in the user database.</fsummary>
<type>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>Groups = list()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>Users = list()</v>
<v>AuthPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Reason = atom()</v>
</type>
<desc>
- <marker id="list_groups"></marker>
- <p><c>list_groups/1, list_groups/2</c> and <c>list_groups/3</c>
- lists all the groups available.
- If there is an error, <c>{error, Reason}</c> is returned.
- When <c>list_groups/1</c> is called the Port and Dir options
+ <p><c>list_users/1, list_users/2</c>, and <c>list_users/3</c>
+ each returns a list
+ of users in the user database for a specific <c>Port/Dir</c>.
+ When <c>list_users/1</c> is called, options <c>Port</c> and <c>Dir</c>
are mandatory.</p>
-
- <marker id="delete_group"></marker>
</desc>
</func>
-
- <func>
- <name>delete_group(GroupName, Options) -> true | {error,Reason} &lt;name>delete_group(GroupName, Port, Dir) -> true | {error, Reason}</name>
- <name>delete_group(GroupName, Address, Port, Dir) -> true | {error, Reason}</name>
- <fsummary>Deletes a group</fsummary>
- <type>
- <v>Options = [Option]</v>
- <v>Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>GroupName = string()</v>
- <v>AuthPassword = string()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <marker id="delete_group"></marker>
- <p><c>delete_group/2, delete_group/3</c> and <c>delete_group/4</c>
- deletes the group specified and returns <c>true</c>.
- If there is an error, <c>{error, Reason}</c> is returned.
- When <c>delete_group/2</c> is called the
- Port and Dir options are mandatory.</p>
-
- <marker id="update_password"></marker>
- </desc>
- </func>
-
+
<func>
<name>update_password(Port, Dir, OldPassword, NewPassword, NewPassword) -> ok | {error, Reason}</name>
<name>update_password(Address,Port, Dir, OldPassword, NewPassword, NewPassword) -> ok | {error, Reason}</name>
- <fsummary>Change the AuthAcessPassword</fsummary>
+ <fsummary>Changes <c>AuthAcessPassword</c>.</fsummary>
<type>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>GroupName = string()</v>
- <v>OldPassword = string()</v>
- <v>NewPassword = string()</v>
- <v>Reason = term()</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>GroupName = string()</v>
+ <v>OldPassword = string()</v>
+ <v>NewPassword = string()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <marker id="update_password"></marker>
- <p><c>update_password/5</c> and <c>update_password/6</c>
- Updates the AuthAccessPassword for the specified directory.
- If NewPassword is equal to "NoPassword" no password is requires to
+ <p><c>update_password/5</c> and <c>update_password/6</c> each
+ updates <c>AuthAccessPassword</c> for the specified directory.
+ If <c>NewPassword</c> is equal to "NoPassword", no password is required to
change authorisation data.
- If NewPassword is equal to "DummyPassword" no changes can be done
+ If <c>NewPassword</c> is equal to "DummyPassword", no changes can be done
without changing the password first.</p>
</desc>
</func>
</funcs>
<section>
- <marker id="see_also"></marker>
<title>SEE ALSO</title>
<p><seealso marker="httpd">httpd(3)</seealso>,
- <seealso marker="mod_alias">mod_alias(3)</seealso>,</p>
+ <seealso marker="mod_alias">mod_alias(3)</seealso></p>
</section>
</erlref>
diff --git a/lib/inets/doc/src/mod_esi.xml b/lib/inets/doc/src/mod_esi.xml
index 5afe5835c7..c2fb60c416 100644
--- a/lib/inets/doc/src/mod_esi.xml
+++ b/lib/inets/doc/src/mod_esi.xml
@@ -8,40 +8,87 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>mod_esi</title>
- <prepared>Joakim Greben&ouml;</prepared>
- <docno></docno>
- <date>1997-10-14</date>
- <rev>2.2</rev>
<file>mod_esi.sgml</file>
</header>
<module>mod_esi</module>
- <modulesummary>Erlang Server Interface </modulesummary>
+ <modulesummary>Erlang Server Interface</modulesummary>
<description>
<p>This module defines the Erlang Server Interface (ESI) API.
- It is a more efficient way of writing erlang scripts
- for your Inets web server than writing them as common CGI scripts.</p>
+ It is a more efficient way of writing Erlang scripts
+ for your <c>Inets</c> web server than writing them as common CGI scripts.</p>
<marker id="deliver"></marker>
</description>
+ <section>
+ <title>DATA TYPES</title>
+ <p>The following data types are used in the functions for mod_esi:</p>
+
+ <taglist>
+ <tag><c>env() = </c></tag>
+ <item> <p><c>{EnvKey()::atom(), Value::term()}</c></p>
+ </item>
+
+ <p>Currently supported key value pairs</p>
+ <taglist>
+
+ <tag><c>{server_software, string()}</c></tag>
+ <item><p>Indicates the inets version.</p></item>
+
+ <tag><c>{server_name, string()}</c></tag>
+ <item><p>The local hostname. </p></item>
+
+ <tag><c>{gateway_interface, string()}</c></tag>
+ <item><p>Legacy string used in CGI, just ignore.</p> </item>
+
+ <tag><c>{server_protocol, string()}</c></tag>
+ <item><p> HTTP version, currently "HTTP/1.1"</p></item>
+
+ <tag>{server_port, integer()}</tag>
+ <item><p>Servers port number.</p></item>
+
+ <tag><c>{request_method, "GET | "PUT" | "DELETE | "POST" | "PATCH"}</c></tag>
+
+ <tag><c>{remote_adress, inet:ip_address()} </c></tag>
+ <item><p>The clients ip address.</p></item>
+
+ <tag><c>{peer_cert, undefined | no_peercert | DER:binary()</c></tag>
+ <item>
+ <p>For TLS connections where client certificates are used this will
+ be an ASN.1 DER-encoded X509-certificate as an Erlang binary.
+ If client certificates are not used the value will be <c>no_peercert</c>,
+ and if TLS is not used (HTTP or connection is lost due to network failure)
+ the value will be <c>undefined</c>.
+ </p></item>
+
+ <tag><c>{script_name, string()}</c></tag>
+ <item><p>Request URI</p></item>
+
+ <tag><c>{http_LowerCaseHTTPHeaderName, string()}</c></tag>
+ <item><p>example: {http_content_type, "text/html"}</p></item>
+ </taglist>
+
+ </taglist>
+
<funcs>
<func>
<name>deliver(SessionID, Data) -> ok | {error, Reason}</name>
- <fsummary>Sends Data back to client.</fsummary>
+ <fsummary>Sends <c>Data</c> back to client.</fsummary>
<type>
<v>SessionID = term()</v>
<v>Data = string() | io_list() | binary()</v>
@@ -52,75 +99,72 @@
<p>This function is <em>only</em> intended to be used from
functions called by the Erl Scheme interface to deliver
parts of the content to the user.</p>
- <p>Sends data from a Erl Scheme script back to the client.</p>
+ <p>Sends data from an Erl Scheme script back to the client.</p>
<note>
- <p>Note that if any HTTP-header fields should be added by the
- script they must be in the first call to deliver/2 and the
- data in the call must be a string. Calls after the headers
- are complete may contain binary data to reduce copying
- overhead. Do not assume anything about the data type of
- SessionID, the SessionID must be the value given as input to
- the esi call back function that you implemented.</p>
- </note>
+ <p>If any HTTP header fields are added by the
+ script, they must be in the first call to <c>deliver/2</c>,
+ and the data in the call must be a string. Calls after the headers
+ are complete can contain binary data to reduce copying
+ overhead. Do not assume anything about the data type of
+ <c>SessionID</c>. <c>SessionID</c> must be the value given
+ as input to the ESI callback function that you implemented.</p>
+ </note>
</desc>
</func>
</funcs>
-
+ </section>
<section>
<title>ESI Callback Functions</title>
</section>
<funcs>
<func>
<name>Module:Function(SessionID, Env, Input)-> _ </name>
- <fsummary>Creates a dynamic web page and returns it chunk by chunk to the server process by calling mod_esi:deliver/2.</fsummary>
+ <fsummary>Creates a dynamic web page and returns it chunk by chunk
+ to the server process by calling <c>mod_esi:deliver/2</c>.</fsummary>
<type>
<v>SessionID = term()</v>
- <v>Env = [EnvironmentDirectives] ++ ParsedHeader</v>
- <v>EnvironmentDirectives = {Key,Value}</v>
- <v>Key = query_string | content_length | server_software | gateway_interface | server_protocol | server_port | request_method | remote_addr | script_name</v>
+ <v>Env = env()</v>
<v>Input = string()</v>
</type>
<desc>
- <p>The <c>Module</c> must be found in the code path and export
- <c>Function</c> with an arity of three. An erlScriptAlias must
- also be set up in the configuration file for the Web server.</p>
- <p>If the HTTP request is a 'post' request and a body is sent
- then content_length will be the length of the posted
- data. If 'get' is used query_string will be the data after
- <em>?</em> in the url.</p>
- <p>ParsedHeader is the HTTP request as a key value tuple
- list. The keys in parsed header will be the in lower case.</p>
- <p>SessionID is a identifier
- the server uses when <c>deliver/2</c> is called; do not
+ <p><c>Module</c> must be found in the code path and export
+ <c>Function</c> with an arity of three. An <c>erlScriptAlias</c> must
+ also be set up in the configuration file for the web server.</p>
+ <p>If the HTTP request is a 'post' request and a body is sent,
+ <c>content_length</c> is the length of the posted
+ data. If 'get' is used, <c>query_string</c> is the data after
+ <em>?</em> in the URL.</p>
+ <p><c>ParsedHeader</c> is the HTTP request as a key-value tuple
+ list. The keys in <c>ParsedHeader</c> are in lower case.</p>
+ <p><c>SessionID</c> is an identifier
+ the server uses when <c>deliver/2</c> is called. Do not
assume anything about the datatype.</p>
- <p>Use this callback function to dynamically generate dynamic web
- content. When a part of the page is generated send the
- data back to the client through <c>deliver/2</c>. Note
+ <p>Use this callback function to generate dynamic web
+ content dynamically. When a part of the page is generated, send the
+ data back to the client through <c>deliver/2</c>. Notice
that the first chunk of data sent to the client must at
least contain all HTTP header fields that the response
will generate. If the first chunk does not contain the
- <em>End of HTTP header</em>, that is <c>"\r\n\r\n",</c>
- the server will
- assume that no HTTP header fields will be generated.</p>
+ <em>end of HTTP header</em>, that is, <c>"\r\n\r\n",</c>
+ the server assumes that no HTTP header fields will be generated.</p>
</desc>
</func>
<func>
<name>Module:Function(Env, Input)-> Response </name>
- <fsummary>Creates a dynamic web page and return it as a list. This functions is deprecated and only kept for backwards compatibility.</fsummary>
+ <fsummary>Creates a dynamic web page and returns it as a list.
+ This function is deprecated and is only kept for backwards compatibility.</fsummary>
<type>
- <v>Env = [EnvironmentDirectives] ++ ParsedHeader</v>
- <v>EnvironmentDirectives = {Key,Value}</v>
- <v>Key = query_string | content_length | server_software | gateway_interface | server_protocol | server_port | request_method | remote_addr | script_name.</v>
+ <v>Env = env()</v>
<v>Input = string()</v>
<v>Response = string()</v>
</type>
<desc>
- <p>This callback format consumes a lot of memory since the
+ <p>This callback format consumes much memory, as the
whole response must be generated before it is sent to the
- user. This function is deprecated and only kept for backwards
+ user. This function is deprecated and is only kept for backwards
compatibility.
- For new development Module:Function/3 should be used.</p>
+ For new development, use <c>Module:Function/3</c>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/inets/doc/src/mod_security.xml b/lib/inets/doc/src/mod_security.xml
index e67111a73d..9dc32b971b 100644
--- a/lib/inets/doc/src/mod_security.xml
+++ b/lib/inets/doc/src/mod_security.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -34,24 +35,45 @@
<p>Security Audit and Trailing Functionality</p>
</description>
<funcs>
+
+ <func>
+ <name>block_user(User, Port, Dir, Seconds) -> true | {error, Reason}</name>
+ <name>block_user(User, Address, Port, Dir, Seconds) -> true | {error, Reason}</name>
+ <fsummary>Blocks a user from access to a directory for a certain amount of time.</fsummary>
+ <type>
+ <v>User = string()</v>
+ <v>Port = integer()</v>
+ <v>Address = {A,B,C,D} | string() | undefined</v>
+ <v>Dir = string()</v>
+ <v>Seconds = integer() | infinity</v>
+ <v>Reason = no_such_directory</v>
+ </type>
+ <desc>
+ <p><c>block_user/4</c> and <c>block_user/5</c> each blocks the user
+ <c>User</c> from directory <c>Dir</c> for a specified
+ amount of time.</p>
+ </desc>
+ </func>
+
<func>
<name>list_auth_users(Port) -> Users | []</name>
<name>list_auth_users(Address, Port) -> Users | []</name>
<name>list_auth_users(Port, Dir) -> Users | []</name>
<name>list_auth_users(Address, Port, Dir) -> Users | []</name>
- <fsummary>List users that have authenticated within the SecurityAuthTimeout time for a given address (if specified), port number and directory (if specified).</fsummary>
+ <fsummary>Lists users that have authenticated within the <c>SecurityAuthTimeout</c>
+ time for a given address (if specified), port number, and directory
+ (if specified).</fsummary>
<type>
- <v>Port = integer()</v>
+ <v>Port = integer()</v>
<v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>Users = list() = [string()]</v>
+ <v>Dir = string()</v>
+ <v>Users = list() = [string()]</v>
</type>
<desc>
- <marker id="list_auth_users"></marker>
- <p><c>list_auth_users/1</c>, <c>list_auth_users/2</c> and
- <c>list_auth_users/3</c> returns a list of users that are
+ <p><c>list_auth_users/1</c>, <c>list_auth_users/2</c>, and
+ <c>list_auth_users/3</c> each returns a list of users that are
currently authenticated. Authentications are stored for
- SecurityAuthTimeout seconds, and are then discarded.</p>
+ <c>SecurityAuthTimeout</c> seconds, and then discarded.</p>
</desc>
</func>
<func>
@@ -59,96 +81,83 @@
<name>list_blocked_users(Address, Port) -> Users | []</name>
<name>list_blocked_users(Port, Dir) -> Users | []</name>
<name>list_blocked_users(Address, Port, Dir) -> Users | []</name>
- <fsummary>List users that are currently blocked from access to a specified port number, for a given address (if specified).</fsummary>
+ <fsummary>Lists users that are currently blocked from access to a
+ specified port number, for a given address (if specified).</fsummary>
<type>
- <v>Port = integer()</v>
+ <v>Port = integer()</v>
<v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>Users = list() = [string()]</v>
+ <v>Dir = string()</v>
+ <v>Users = list() = [string()]</v>
</type>
<desc>
- <marker id="list_blocked_users"></marker>
- <p><c>list_blocked_users/1</c>, <c>list_blocked_users/2</c> and
- <c>list_blocked_users/3</c> returns a list of users that are
+ <p><c>list_blocked_users/1</c>, <c>list_blocked_users/2</c>, and
+ <c>list_blocked_users/3</c> each returns a list of users that are
currently blocked from access.</p>
</desc>
</func>
+
<func>
- <name>block_user(User, Port, Dir, Seconds) -> true | {error, Reason}</name>
- <name>block_user(User, Address, Port, Dir, Seconds) -> true | {error, Reason}</name>
- <fsummary>Block user from access to a directory for a certain amount of time.</fsummary>
- <type>
- <v>User = string()</v>
- <v>Port = integer()</v>
- <v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
- <v>Seconds = integer() | infinity</v>
- <v>Reason = no_such_directory</v>
- </type>
- <desc>
- <marker id="block_user"></marker>
- <p><c>block_user/4</c> and <c>block_user/5</c> blocks the user
- <c>User</c> from the directory <c>Dir</c> for a specified
- amount of time.</p>
- </desc>
- </func>
- <func>
- <name>unblock_user(User, Port) -> true | {error, Reason}</name>
+ <name>unblock_user(User, Port) -> true | {error, Reason}</name>
<name>unblock_user(User, Address, Port) -> true | {error, Reason}</name>
- <name>unblock_user(User, Port, Dir) -> true | {error, Reason}</name>
+ <name>unblock_user(User, Port, Dir) -> true | {error, Reason}</name>
<name>unblock_user(User, Address, Port, Dir) -> true | {error, Reason}</name>
- <fsummary>Remove a blocked user from the block list</fsummary>
+ <fsummary>Removes a blocked user from the block list.</fsummary>
<type>
- <v>User = string()</v>
- <v>Port = integer()</v>
+ <v>User = string()</v>
+ <v>Port = integer()</v>
<v>Address = {A,B,C,D} | string() | undefined</v>
- <v>Dir = string()</v>
+ <v>Dir = string()</v>
<v>Reason = term()</v>
</type>
<desc>
- <marker id="unblock_user"></marker>
- <p><c>unblock_user/2</c>, <c>unblock_user/3</c> and
- <c>unblock_user/4</c> removes the user <c>User</c> from
- the list of blocked users for the Port (and Dir) specified.</p>
+ <p><c>unblock_user/2</c>, <c>unblock_user/3</c>, and
+ <c>unblock_user/4</c> each removes the user <c>User</c> from
+ the list of blocked users for <c>Port</c> (and <c>Dir</c>).</p>
</desc>
</func>
</funcs>
<section>
<marker id="callback_module"></marker>
- <title>The SecurityCallbackModule</title>
- <p>The SecurityCallbackModule is a user written module that can receive
- events from the mod_security Erlang Webserver API module.
- This module only exports the function(s),
- <seealso marker="#callback_module_event">event/4,5</seealso>,
- which are described below.
+ <title>SecurityCallbackModule</title>
+ <p>The <c>SecurityCallbackModule</c> is a user-written module that can receive
+ events from the <c>mod_security</c> Erlang web server API module.
+ This module only exports the functions event/[4,5]
+ which are described here.
</p>
</section>
<funcs>
<func>
- <name>event(What, Port, Dir, Data) -> ignored</name>
- <name>event(What, Address, Port, Dir, Data) -> ignored</name>
- <fsummary>This function is called whenever an event occurs in mod_security</fsummary>
+ <name>Module:event(What, Port, Dir, Data) -> ignored</name>
+ <name>Module:event(What, Address, Port, Dir, Data) -> ignored</name>
+ <fsummary>Called whenever an event occurs in <c>mod_security</c>.</fsummary>
<type>
- <v>What = atom()</v>
- <v>Port = integer()</v>
+ <v>What = atom()</v>
+ <v>Port = integer()</v>
<v>Address = {A,B,C,D} | string() &lt;v>Dir = string()</v>
- <v>Data = [Info]</v>
- <v>Info = {Name, Value}</v>
+ <v>Data = [Info]</v>
+ <v>Info = {Name, Value}</v>
</type>
<desc>
<marker id="callback_module_event"></marker>
- <p><c>event/4</c> or <c>event/4</c> is called whenever an event
- occurs in the mod_security Erlang Webserver API module (<c>event/4</c> is
- called if Address is undefined and <c>event/5</c> otherwise).
- The <c>What</c> argument specifies the type of event that has
- occurred, and should be one of the following reasons;
- <c>auth_fail</c> (a failed user authentication),
- <c>user_block</c> (a user is being blocked from access) or
- <c>user_unblock</c> (a user is being removed from the block list).</p>
+ <p><c>event/4</c> or <c>event/5</c> is called whenever an event
+ occurs in the <c>mod_security</c> Erlang web server API module.
+ (<c>event/4</c> is called if <c>Address</c> is undefined,
+ otherwise <c>event/5</c>.
+ Argument <c>What</c> specifies the type of event that has
+ occurred and is one of the following reasons:
+ </p>
+ <taglist>
+ <tag><c>auth_fail</c></tag>
+ <item><p>A failed user authentication.</p></item>
+ <tag><c>user_block</c></tag>
+ <item><p>A user is being blocked from access.</p></item>
+ <tag><c>user_unblock</c></tag>
+ <item><p>A user is being removed from the block list.</p></item>
+ </taglist>
<note>
- <p>Note that the <c>user_unblock</c> event is not triggered when
+ <p>The event <c>user_unblock</c> is not triggered when
a user is removed from the block list explicitly using the
<c>unblock_user</c> function.</p>
</note>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index f563a8c4b0..6593be02dc 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2014</year>
+ <year>2002</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,7 +33,398 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 5.10.9</title>
+ <section><title>Inets 6.2.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Handle multiple \t in mime types file</p>
+ <p>
+ Own Id: OTP-13663 Aux Id: seq13132 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.2.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Put back unused module inets_regexp and remove it in OTP
+ 19 instead as it is an incompatibility, although it is an
+ undocumented module and should not affect other
+ applications.</p>
+ <p>
+ Own Id: OTP-13533</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.2.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add environment information item peer_cert to mod_esi</p>
+ <p>
+ Own Id: OTP-13510</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Mend ipv6_host_with_brackets option in httpc</p>
+ <p>
+ Own Id: OTP-13417</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The TFTP client/server has been fixed to allow file sizes
+ larger than 32MB block by allowing the 16 bit block
+ counter to wrap. Since this is a commonly accepted
+ behavior we regard it as a bug fix.</p>
+ <p>
+ Own Id: OTP-13403</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Handle HTTP PATCH method in client.</p>
+ <p>
+ Own Id: OTP-13286</p>
+ </item>
+ <item>
+ <p>
+ Expected termination should not be logged as an
+ application error.</p>
+ <p>
+ Own Id: OTP-13389</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ mod_alias now traverses all aliases picking the longest
+ match and not the first match.</p>
+ <p>
+ Own Id: OTP-13248</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Replace obs-folds with spaces instead of failing</p>
+ <p>
+ Own Id: OTP-13069</p>
+ </item>
+ <item>
+ <p>
+ Add validation fun for URI scheme to http_uri API</p>
+ <p>
+ Own Id: OTP-13071</p>
+ </item>
+ <item>
+ <p>
+ Handle stream bodies as documented.</p>
+ <p>
+ Own Id: OTP-13093</p>
+ </item>
+ <item>
+ <p>
+ Correct error handling of mod_esi generated chunks. Send
+ warning headers in chunk trailers instead of generating
+ an unexpected additional 500 request response, when
+ problems, such as a timeout occurs.</p>
+ <p>
+ Own Id: OTP-13110</p>
+ </item>
+ <item>
+ <p>
+ HTTP client terminates gracefully when an invalid chunked
+ length header is encountered.</p>
+ <p>
+ Own Id: OTP-13117</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add default for SNI (Server Name Indication) when running
+ https using the inets HTTP-client.</p>
+ <p>
+ Own Id: OTP-12985</p>
+ </item>
+ <item>
+ <p>
+ Be forgiving to chunked sizes that have trailing
+ whitespaces as prior implementation was. Also some legacy
+ embedded devices does actually have trailing whitespaces
+ even though this in not according to the spec.</p>
+ <p>
+ Own Id: OTP-13116</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Improved error handling and gracfully termination when an
+ invalid chunked length header is encountered.</p>
+ <p>
+ Own Id: OTP-13061</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add possibility to set socket options, such as nodelay,
+ for httpd. Also phase out legacy option value inet6bf4
+ for the ipfamily option. This value will be translated to
+ the value inet.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-13062</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Avoid crash in mod_auth_server and mod_security_server
+ due to using an atom instead of a string when creating a
+ name.</p>
+ <p>
+ Own Id: OTP-13022</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add function response_default_headers/0 to httpd
+ customize API, to allow user to specify default values
+ for HTTP response headers.</p>
+ <p>
+ Own Id: OTP-13013</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix broken socket feature, that is on Linux systems a
+ socket may be opened before starting Erlang and then
+ passed to Erlang's httpd daemon. This is useful as the
+ wrap program can open a privileged port and Erlang does
+ not have to be run as root.</p>
+ <p>
+ Own Id: OTP-12875 Aux Id: seq12878 </p>
+ </item>
+ <item>
+ <p>
+ Fix broken socket feature, that is on Linux systems a
+ socket may be opened before starting Erlang and then
+ passed to Erlangs tftp daemon. This is useful as the wrap
+ program can open a privileged port and Erlang does not
+ have to be run as root.</p>
+ <p>
+ Own Id: OTP-12898 Aux Id: seq12900 </p>
+ </item>
+ <item>
+ <p>
+ httpc_handler should react properly to cancel requests
+ even when the request to be canceled was already finished
+ but httpc_manager did not get notified about that yet.</p>
+ <p>
+ Own Id: OTP-12922</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added format_status function to httpd process to avoid
+ sensitive information to be printed in supervisor logs.</p>
+ <p>
+ Own Id: OTP-12976</p>
+ </item>
+ <item>
+ <p>
+ Return meaningful error reason disregarding whether a
+ http proxy is used or not.</p>
+ <p>
+ Own Id: OTP-12984</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix race condition in httpc. If the socket is closed by
+ the peer do not try to close it again.</p>
+ <p>
+ Own Id: OTP-11845</p>
+ </item>
+ <item>
+ <p>
+ Avoid process leak by gracefully terminating httpc
+ request handler process when send operation fails.</p>
+ <p>
+ Own Id: OTP-12362</p>
+ </item>
+ <item>
+ <p>
+ Reject messages with a Content-Length less than 0</p>
+ <p>
+ Own Id: OTP-12739 Aux Id: seq12860 </p>
+ </item>
+ <item>
+ <p>
+ Let gen_tcp:controlling_process/2 and
+ inet_sctp:connect/[45] propagate prim_inet:setopt/3
+ errors instead of having them generate badmatch
+ exceptions.</p>
+ <p>
+ Own Id: OTP-12798</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Remove Server Side Include support from inets, as this is
+ an old technic that has security issues and was not well
+ tested.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12156</p>
+ </item>
+ <item>
+ <p>
+ New value in <c>server_tokens</c> config for limiting
+ banner grabbing attempts. </p>
+ <p>
+ By setting <c>{server_tokens, none}</c> in
+ <c>ServiceConfig</c> for <c>inets:start(httpd,
+ ServiceConfig)</c>, the "Server:" header will not be set
+ in messages from the server.</p>
+ <p>
+ Own Id: OTP-12661 Aux Id: seq12840 </p>
+ </item>
+ <item>
+ <p>
+ To enable the HTTP server to run in a virtualized
+ environment, where there can be more that one server that
+ has the same ip-address and port, we add a new option
+ profile.</p>
+ <p>
+ Own Id: OTP-12674</p>
+ </item>
+ <item>
+ <p>
+ httpc: Fix implementation of gracefull shudown to work as
+ intended for keep alive connections not using pipelining.</p>
+ <p>
+ Own Id: OTP-12803</p>
+ </item>
+ <item>
+ <p>
+ Correct handling of proxy options when using persistent
+ connections.</p>
+ <p>
+ Own Id: OTP-12822</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 5.10.9</title>
<section><title>Improvements and New Features</title>
<list>
@@ -675,9 +1067,9 @@
<p>Better handling of errorI(s) during update of the session
database. </p>
<p>Also added and updated some debugging functions
- <seealso marker="httpc#which_sessions">which_sessions/10,1</seealso>
+ <seealso marker="httpc#which_sessions-0">which_sessions/[0,1]</seealso>
and
- <seealso marker="httpc#info">info/0</seealso>. </p>
+ <seealso marker="httpc#info-0">info/0</seealso>. </p>
<p>Own Id: OTP-10093</p>
<p>Aux Id: Seq 12062</p>
</item>
@@ -771,7 +1163,7 @@
<item>
<p>[httpc] Add function for retrieving current options,
- <seealso marker="httpc#get_options">get_options/1,2</seealso>. </p>
+ <seealso marker="httpc#get_options-1">get_options/[1,2]</seealso>. </p>
<p>Own Id: OTP-9979</p>
</item>
@@ -948,15 +1340,11 @@
<section>
<title>Incompatibilities</title>
-<!--
- <p>-</p>
--->
-
<list>
<item>
<p>[httpc] Deprecated interface module <c>http</c> has been removed.
It has (long) been replaced by http client interface module
- <seealso marker="httpc#">httpc</seealso>. </p>
+ <seealso marker="httpc">httpc</seealso>. </p>
<p>Own Id: OTP-9359</p>
</item>
@@ -1144,15 +1532,13 @@
<section><title>Inets 5.6</title>
<section><title>Improvements and New Features</title>
-<!--
- <p>-</p>
--->
+
<list>
<item>
<p>[httpc] Add support for upload body streaming (PUT and POST).</p>
<p>For more info,
see the definition of the <c>Body</c> argument of the
- <seealso marker="httpc#request2">request/4,5</seealso>
+ <seealso marker="httpc#request-4">request/[4,5]</seealso>
function. </p>
<p>Filipe David Manana</p>
<p>Own Id: OTP-9094</p>
@@ -1165,7 +1551,7 @@
<item>
<p>[httpd]
- <seealso marker="mod_esi#deliver">mod_esi:deliver/2</seealso>
+ <seealso marker="mod_esi#deliver-2">mod_esi:deliver/2</seealso>
made to accept binary data. </p>
<p>Bernard Duggan</p>
<p>Own Id: OTP-9123</p>
@@ -1193,7 +1579,7 @@
for using file descriptors has been improved.
It is now possible to add the file descriptor to the config
(option fd) when calling the
- <seealso marker="inets#start2">inets:start(httpd, ...)</seealso>
+ <seealso marker="inets#start-2">inets:start(httpd, ...)</seealso>
function. </p>
<p>Attila Rajmund Nohl</p>
<p>Own Id: OTP-9202</p>
@@ -1207,7 +1593,7 @@
<p>See the httpd
<seealso marker="httpd#props_comm">socket_type</seealso>
communication property or the httpc
- <seealso marker="httpc#request2">request/4,5</seealso> function
+ <seealso marker="httpc#request-4">request/[4,5]</seealso> function
for more info. </p>
<p>Own Id: OTP-9230</p>
<p>*** POTENTIAL INCOMPATIBILITY ***</p>
@@ -1407,7 +1793,7 @@
<p>[httpc|httpd] - Now allow the use of the "new" ssl, by using
the <c>essl</c> tag instead. </p>
<p>See the <c>http_option</c> option in the
- <seealso marker="httpc#request2">request/4,5</seealso> or
+ <seealso marker="httpc#request-4">request/[4,5]</seealso> or
the <seealso marker="httpd#props_comm">socket-type</seealso>
section of the Communication properties chapter for more info, </p>
<p>Own Id: OTP-7907</p>
@@ -1602,23 +1988,21 @@
<item>
<p>[httpd] - Issues with ESI erl_script_timeout. </p>
- <p>
- <list type="bulleted">
- <item>
- <p>The <c>erl_script_timeout</c> config option is ducumented
- as a number of seconds. But when parsing the config, in the
- new format (not a config file), it was handled as if in
- number of milliseconds. </p>
- </item>
- <item>
- <p>When the erl-script-timeout time was exceeded, the server
- incorrectly marked the answer as sent, thereby leaving
- client hanging (with an incomplete answer).
- This has been changed, so that now the socket will be
- closed. </p>
- </item>
- </list>
- </p>
+ <list type="bulleted">
+ <item>
+ <p>The <c>erl_script_timeout</c> config option is ducumented
+ as a number of seconds. But when parsing the config, in the
+ new format (not a config file), it was handled as if in
+ number of milliseconds. </p>
+ </item>
+ <item>
+ <p>When the erl-script-timeout time was exceeded, the server
+ incorrectly marked the answer as sent, thereby leaving
+ client hanging (with an incomplete answer).
+ This has been changed, so that now the socket will be
+ closed. </p>
+ </item>
+ </list>
<p>Own Id: OTP-8509</p>
</item>
</list>
@@ -1639,8 +2023,8 @@
<p>[httpc] - Allow users to pass socket options to the transport
module when making requests. </p>
<p>See the <c>socket_opts</c> option in the
- <seealso marker="httpc#request2">request/4</seealso> or
- <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ <seealso marker="httpc#request-4">request/4</seealso> or
+ <seealso marker="httpc#set_options-1">set_options/[1,2]</seealso>
for more info, </p>
<p>Own Id: OTP-8352</p>
</item>
@@ -1681,7 +2065,7 @@
deliver an async reply to more receivers then the calling
process. </p>
<p>See the
- <seealso marker="httpc#request2">receiver</seealso>
+ <seealso marker="httpc#request-2">receiver</seealso>
option for more info, </p>
<p>Own Id: OTP-8106</p>
</item>
@@ -1694,20 +2078,19 @@
<item>
<p>[httpc] Several more or less critical fixes:</p>
- <p>
- <list type="bulleted">
- <item>
- <p>Initial call between the httpc manager and request
- handler was synchronous. </p>
- <p>When the manager starts a new request handler,
- this is no longer a synchronous operation. Previously,
- the new request handler made the connection to the
- server and issuing of the first request (the reason
- for starting it) in the gen_server init function.
- If the connection for some reason "took some time",
- the manager hanged, leaving all other activities by
- that manager also hanging. </p>
- </item>
+ <list type="bulleted">
+ <item>
+ <p>Initial call between the httpc manager and request
+ handler was synchronous. </p>
+ <p>When the manager starts a new request handler,
+ this is no longer a synchronous operation. Previously,
+ the new request handler made the connection to the
+ server and issuing of the first request (the reason
+ for starting it) in the gen_server init function.
+ If the connection for some reason "took some time",
+ the manager hanged, leaving all other activities by
+ that manager also hanging. </p>
+ </item>
<!--
<item>
<p>Copying of data between processes</p>
@@ -1718,8 +2101,7 @@
<p>TBD</p>
</item>
-->
- </list>
- </p>
+ </list>
<p>As a side-effect of these changes, some modules was also
renamed, and a new api module,
<seealso marker="httpc">httpc</seealso>, has been introduced
@@ -1950,7 +2332,7 @@
request, when the client connects to the server. Default
value is that of the <c>timeout</c> option. </p>
<p>See the
- <seealso marker="httpc#request2">request/4,5</seealso>
+ <seealso marker="httpc#request-4">request/[4,5]</seealso>
function for more info. </p>
<p>Own Id: OTP-7298</p>
<!-- <p>Aux Id: seq11086</p> -->
@@ -2057,7 +2439,7 @@
the client connects to the server. </p>
<p>As a side-effect of this, the option <c>ipv6</c> has been
removed and replaced by the <c>ipfamily</c> option. </p>
- <p>See <seealso marker="httpc#set_options">http:set_options/1,2</seealso>
+ <p>See <seealso marker="httpc#set_options-1">http:set_options/[1,2]</seealso>
for more info. </p>
<p>*** POTENTIAL INCOMPATIBILITY ***</p>
<p>Own Id: OTP-8004</p>
diff --git a/lib/inets/doc/src/notes_history.xml b/lib/inets/doc/src/notes_history.xml
index 2903b753a1..411c62b7f1 100644
--- a/lib/inets/doc/src/notes_history.xml
+++ b/lib/inets/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/inets/doc/src/part.xml b/lib/inets/doc/src/part.xml
index 6ebca1f87f..3b817eecf2 100644
--- a/lib/inets/doc/src/part.xml
+++ b/lib/inets/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,10 +30,18 @@
<file>part.sgml</file>
</header>
<description>
- <p>The <em>Inets Application </em> provides a set of Internet
- related services. Currently supported are a HTTP client, a HTTP
- server a FTP client and a TFTP client and server.</p>
+ <p>The <c>Inets</c> application provides a set of
+ Internet-related services as follows:</p>
+ <list type="bulleted">
+ <item>An FTP client</item>
+ <item>A TFTP client and server</item>
+ <item>An <term id="HTTP"></term> client and server</item>
+ </list>
+ <p>The HTTP client and server are HTTP 1.1 compliant as
+ defined in
+ <url href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</url>.</p>
</description>
+ <xi:include href="introduction.xml"/>
<xi:include href="inets_services.xml"/>
<xi:include href="ftp_client.xml"/>
<xi:include href="http_client.xml"/>
diff --git a/lib/inets/doc/src/part_notes.xml b/lib/inets/doc/src/part_notes.xml
index 35d645e299..702e3dc09c 100644
--- a/lib/inets/doc/src/part_notes.xml
+++ b/lib/inets/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/inets/doc/src/part_notes_history.xml b/lib/inets/doc/src/part_notes_history.xml
index d699f5f60a..56c44c9e9e 100644
--- a/lib/inets/doc/src/part_notes_history.xml
+++ b/lib/inets/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/inets/doc/src/ref_man.xml b/lib/inets/doc/src/ref_man.xml
index 3afb020431..27021ea09a 100644
--- a/lib/inets/doc/src/ref_man.xml
+++ b/lib/inets/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,16 +30,15 @@
<file>ref_man.xml</file>
</header>
<description>
- <p>Inets is a container for Internet clients and
- servers. Currently a FTP client, a HTTP client and server, and
- a tftp client and server has been incorporated in Inets.</p>
+ <p><c>Inets</c> is a container for Internet clients and
+ servers. An FTP client, an HTTP client and server, and
+ a TFTP client and server are incorporated in <c>Inets</c>.</p>
</description>
<xi:include href="inets.xml"/>
<xi:include href="ftp.xml"/>
<xi:include href="tftp.xml"/>
<xi:include href="httpc.xml"/>
<xi:include href="httpd.xml"/>
- <xi:include href="httpd_conf.xml"/>
<xi:include href="httpd_custom_api.xml"/>
<xi:include href="httpd_socket.xml"/>
<xi:include href="httpd_util.xml"/>
diff --git a/lib/inets/doc/src/tftp.xml b/lib/inets/doc/src/tftp.xml
index 42a65ed0c5..10398f5088 100644
--- a/lib/inets/doc/src/tftp.xml
+++ b/lib/inets/doc/src/tftp.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2013</year>
+ <year>2006</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,173 +29,170 @@
<rev></rev>
</header>
<module>tftp</module>
- <modulesummary>Trivial FTP</modulesummary>
+ <modulesummary>Trivial FTP.</modulesummary>
<description>
<p>This is a complete implementation of the following IETF standards:</p>
<list type="bulleted">
- <item>RFC 1350, The TFTP Protocol (revision 2).</item>
- <item>RFC 2347, TFTP Option Extension.</item>
- <item>RFC 2348, TFTP Blocksize Option.</item>
- <item>RFC 2349, TFTP Timeout Interval and Transfer Size Options.</item>
+ <item>RFC 1350, The TFTP Protocol (revision 2)</item>
+ <item>RFC 2347, TFTP Option Extension</item>
+ <item>RFC 2348, TFTP Blocksize Option</item>
+ <item>RFC 2349, TFTP Timeout Interval and Transfer Size Options</item>
</list>
- <p>The only feature that not is implemented in this release is
+ <p>The only feature that not is implemented is
the "netascii" transfer mode.</p>
<p>The <seealso marker="#start/1">start/1</seealso> function starts
- a daemon process which listens for UDP packets on a port. When it
- receives a request for read or write it spawns a temporary server
- process which handles the actual transfer of the file.</p>
- <p>On the client side
- the <seealso marker="#read_file/3">read_file/3</seealso>
+ a daemon process listening for UDP packets on a port. When it
+ receives a request for read or write, it spawns a temporary server
+ process handling the transfer.</p>
+ <p>On the client side,
+ function <seealso marker="#read_file/3">read_file/3</seealso>
and <seealso marker="#write_file/3">write_file/3</seealso>
- functions spawns a temporary client process which establishes
- contact with a TFTP daemon and performs the actual transfer of
- the file.</p>
- <p><c>tftp</c> uses a callback module to handle the actual file
+ spawn a temporary client process establishing
+ contact with a TFTP daemon and perform the file transfer.</p>
+ <p><c>tftp</c> uses a callback module to handle the file
transfer. Two such callback modules are provided,
<c>tftp_binary</c> and <c>tftp_file</c>. See
<seealso marker="#read_file/3">read_file/3</seealso> and
- <seealso marker="#write_file/3">write_file/3</seealso> for
- more information about these. The user can also implement own
- callback modules, see <seealso marker="#tftp_callback">CALLBACK FUNCTIONS</seealso> below. A callback module provided by
- the user is registered using the <c>callback</c> option, see
- <seealso marker="#options">DATA TYPES</seealso> below.</p>
+ <seealso marker="#write_file/3">write_file/3</seealso> for details.
+ You can also implement your own callback modules, see
+ <seealso marker="#tftp_callback">CALLBACK FUNCTIONS</seealso>.
+ A callback module provided by
+ the user is registered using option <c>callback</c>, see
+ <seealso marker="#options">DATA TYPES</seealso>.</p>
</description>
<section>
- <title>TFTP SERVER SERVICE START/STOP </title>
+ <title>TFTP SERVER SERVICE START/STOP</title>
<p>A TFTP server can be configured to start statically when starting
- the Inets application. Alternatively it can be started dynamically
- (when Inets already is started) by calling the Inets application API
- <c>inets:start(tftpd, ServiceConfig)</c>, or
+ the <c>Inets</c> application. Alternatively, it can be started dynamically
+ (when <c>Inets</c> is already started) by calling the <c>Inets</c> application
+ API <c>inets:start(tftpd, ServiceConfig)</c> or
<c>inets:start(tftpd, ServiceConfig, How)</c>,
see <seealso marker="inets">inets(3)</seealso> for details.
- The <c>ServiceConfig</c> for TFTP is described below in
- the <seealso marker="#options">COMMON DATA TYPES</seealso>
+ The <c>ServiceConfig</c> for TFTP is described in
+ the <seealso marker="#options">DATA TYPES</seealso>
section.</p>
<p>The TFTP server can be stopped using <c>inets:stop(tftpd, Pid)</c>,
see <seealso marker="inets">inets(3)</seealso> for details.</p>
<p>The TPFT client is of such a temporary nature that it is not
- handled as a service in the Inets service framework.</p>
+ handled as a service in the <c>Inets</c> service framework.</p>
</section>
<section>
<marker id="options"></marker>
- <title>COMMON DATA TYPES</title>
- <pre>
- ServiceConfig = Options
- Options = [option()]
- option() -- see below
- </pre>
+ <title>DATA TYPES</title>
+ <p><c>ServiceConfig = Options</c></p>
+ <p><c>Options = [option()]</c></p>
<p>Most of the options are common for both the client and the server
- side, but some of them differs a little. Here are the available
- options:</p>
+ side, but some of them differs a little.
+ The available <c>option()</c>s are as follows:</p>
<taglist>
<tag><c>{debug, Level}</c></tag>
<item>
<p><c>Level = none | error | warning | brief | normal | verbose | all</c></p>
- <p>Controls the level of debug printouts. The default is
- <c>none</c>.</p>
+ <p>Controls the level of debug printouts.
+ Default is <c>none</c>.</p>
</item>
<tag><c>{host, Host}</c></tag>
<item>
- <p><c>Host = hostname()</c> see
- <seealso marker="kernel:inet">inet(3)</seealso></p>
+ <p><c>Host = hostname()</c>, see
+ <seealso marker="kernel:inet">inet(3)</seealso>.</p>
<p>The name or IP address of the host where the TFTP daemon
resides. This option is only used by the client.</p>
</item>
<tag><c>{port, Port}</c></tag>
<item>
<p><c>Port = int()</c></p>
- <p>The TFTP port where the daemon listens. It defaults to
- the standardized number 69. On the server side it may
- sometimes make sense to set it to 0, which means that
- the daemon just will pick a free port (which one is
- returned by the <c>info/1</c> function).</p>
- <p>If a socket has somehow already has been connected, the
- {udp, [{fd, integer()}]} option can be used to pass the
- open file descriptor to gen_udp. This can be automated
- a bit by using a command line argument stating the
+ <p>The TFTP port where the daemon listens. Defaults is
+ the standardized number 69. On the server side, it can
+ sometimes make sense to set it to 0, meaning that
+ the daemon just picks a free port (which one is
+ returned by function <c>info/1</c>).</p>
+ <p>If a socket is connected already, option
+ <c>{udp, [{fd, integer()}]}</c> can be used to pass the
+ open file descriptor to <c>gen_udp</c>. This can be automated
+ by using a command-line argument stating the
prebound file descriptor number. For example, if the
- Port is 69 and the file descriptor 22 has been opened by
- setuid_socket_wrap. Then the command line argument
- "-tftpd_69 22" will trigger the prebound file
+ port is 69 and file descriptor 22 is opened by
+ <c>setuid_socket_wrap</c>, the command-line argument
+ "-tftpd_69 22" triggers the prebound file
descriptor 22 to be used instead of opening port 69.
- The UDP option {udp, [{fd, 22}]} automatically be added.
- See init:get_argument/ about command line arguments and
- gen_udp:open/2 about UDP options.</p>
+ The UDP option <c>{udp, [{fd, 22}]}</c> is automatically added.
+ See <c>init:get_argument/</c> about command-line arguments and
+ <c>gen_udp:open/2</c> about UDP options.</p>
</item>
<tag><c>{port_policy, Policy}</c></tag>
<item>
- <p><c>Policy = random | Port | {range, MinPort, MaxPort}</c> <br></br>
-<c>Port = MinPort = MaxPort = int()</c></p>
- <p>Policy for the selection of the temporary port which is used
- by the server/client during the file transfer. It defaults to
- <c>random</c> which is the standardized policy. With this
- policy a randomized free port used. A single port or a range
- of ports can be useful if the protocol should pass through a
+ <p><c>Policy = random | Port | {range, MinPort, MaxPort}</c></p>
+ <p><c>Port = MinPort = MaxPort = int()</c></p>
+ <p>Policy for the selection of the temporary port that is used
+ by the server/client during the file transfer. Default is
+ <c>random</c>, which is the standardized policy. With this
+ policy a randomized free port is used. A single port or a range
+ of ports can be useful if the protocol passes through a
firewall.</p>
</item>
<tag><c>{udp, Options}</c></tag>
<item>
- <p><c>Options = [Opt]</c> see
- <seealso marker="kernel:gen_udp#open/1">gen_udp:open/2</seealso></p>
+ <p><c>Options = [Opt]</c>, see
+ <seealso marker="kernel:gen_udp#open/1">gen_udp:open/2</seealso>.</p>
</item>
<tag><c>{use_tsize, Bool}</c></tag>
<item>
<p><c>Bool = bool()</c></p>
- <p>Flag for automated usage of the <c>tsize</c> option. With
- this set to true, the <c>write_file/3</c> client will
- determine the filesize and send it to the server as
+ <p>Flag for automated use of option <c>tsize</c>. With
+ this set to <c>true</c>, the <c>write_file/3</c> client
+ determines the filesize and sends it to the server as
the standardized <c>tsize</c> option. A <c>read_file/3</c>
- client will just acquire filesize from the server by sending
+ client acquires only a filesize from the server by sending
a zero <c>tsize</c>.</p>
</item>
<tag><c>{max_tsize, MaxTsize}</c></tag>
<item>
<p><c>MaxTsize = int() | infinity</c></p>
<p>Threshold for the maximal filesize in bytes. The transfer
- will be aborted if the limit is exceeded. It defaults to
- <c>infinity</c>.</p>
+ is aborted if the limit is exceeded.
+ Default is <c>infinity</c>.</p>
</item>
<tag><c>{max_conn, MaxConn}</c></tag>
<item>
<p><c>MaxConn = int() | infinity</c></p>
<p>Threshold for the maximal number of active connections.
- The daemon will reject the setup of new connections if
- the limit is exceeded. It defaults to <c>infinity</c>.</p>
+ The daemon rejects the setup of new connections if
+ the limit is exceeded. Default is <c>infinity</c>.</p>
</item>
<tag><c>{TftpKey, TftpVal}</c></tag>
<item>
<p><c>TftpKey = string()</c> <br></br>
<c>TftpVal = string()</c></p>
- <p>The name and value of a TFTP option.</p>
+ <p>Name and value of a TFTP option.</p>
</item>
<tag><c>{reject, Feature}</c></tag>
<item>
<p><c>Feature = Mode | TftpKey</c> <br></br>
<c>&nbsp;Mode = read | write</c> <br></br>
<c>&nbsp;TftpKey = string()</c></p>
- <p>Control which features that should be rejected. This is
- mostly useful for the server as it may restrict usage of
- certain TFTP options or read/write access.</p>
+ <p>Controls which features to reject. This is
+ mostly useful for the server as it can restrict the use
+ of certain TFTP options or read/write access.</p>
</item>
<tag><c>{callback, {RegExp, Module, State}}</c></tag>
<item>
<p><c>RegExp = string()</c> <br></br>
<c>Module = atom()</c> <br></br>
-<c>State = term()</c></p>
+<c>State = term()</c></p>
<p>Registration of a callback module. When a file is to be
- transferred, its local filename will be matched to the regular
+ transferred, its local filename is matched to the regular
expressions of the registered callbacks. The first matching
- callback will be used the during the transfer. See
+ callback is used during the transfer. See
<seealso marker="#read_file/3">read_file/3</seealso> and
<seealso marker="#write_file/3">write_file/3</seealso>.
</p>
- <p>The callback module must implement the <c>tftp</c> behavior,
+ <p>The callback module must implement the <c>tftp</c> behavior, see
<seealso marker="#tftp_callback">CALLBACK FUNCTIONS</seealso>.</p>
</item>
@@ -202,9 +200,9 @@
<item>
<p><c>Module = module()()</c></p>
- <p>Callback module for customized logging of error, warning and
- info messages. >The callback module must implement the
- <c>tftp_logger</c> behavior,
+ <p>Callback module for customized logging of errors, warnings, and
+ info messages. The callback module must implement the
+ <c>tftp_logger</c> behavior, see
<seealso marker="#tftp_logger">LOGGER FUNCTIONS</seealso>.
The default module is <c>tftp_logger</c>.</p>
</item>
@@ -214,199 +212,169 @@
<p><c>MaxRetries = int()</c></p>
<p>Threshold for the maximal number of retries. By default
- the server/client will try to resend a message up to
- <c>5</c> times when the timeout expires.</p>
+ the server/client tries to resend a message up to
+ five times when the time-out expires.</p>
</item>
</taglist>
-
- <marker id="start1"></marker>
</section>
<funcs>
<func>
- <name>start(Options) -> {ok, Pid} | {error, Reason}</name>
- <fsummary>Start a daemon process</fsummary>
+ <name>change_config(daemons, Options) -> [{Pid, Result}]</name>
+ <fsummary>Changes configuration for all daemons.
+ </fsummary>
<type>
<v>Options = [option()]</v>
<v>Pid = pid()</v>
+ <v>Result = ok | {error, Reason}</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Starts a daemon process which listens for udp packets on a
- port. When it receives a request for read or write it spawns
- a temporary server process which handles the actual transfer
- of the (virtual) file.</p>
-
- <marker id="read_file"></marker>
+ <p>Changes configuration for all TFTP daemon processes. </p>
</desc>
</func>
<func>
- <name>read_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name>
- <fsummary>Read a (virtual) file from a TFTP server</fsummary>
+ <name>change_config(servers, Options) -> [{Pid, Result}]</name>
+ <fsummary>Changes configuration for all servers.
+ </fsummary>
<type>
- <v>RemoteFilename = string()</v>
- <v>LocalFilename = binary | string()</v>
<v>Options = [option()]</v>
- <v>LastCallbackState = term()</v>
+ <v>Pid = pid()</v>
+ <v>Result = ok | {error, Reason}</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Reads a (virtual) file <c>RemoteFilename</c> from a TFTP
- server.</p>
- <p>If <c>LocalFilename</c> is the atom <c>binary</c>,
- <c>tftp_binary</c> is used as callback module. It concatenates
- all transferred blocks and returns them as one single binary
- in <c>LastCallbackState</c>.</p>
- <p>If <c>LocalFilename</c> is a string and there are no
- registered callback modules, <c>tftp_file</c> is used as
- callback module. It writes each transferred block to the file
- named <c>LocalFilename</c> and returns the number of
- transferred bytes in <c>LastCallbackState</c>.</p>
- <p>If <c>LocalFilename</c> is a string and there are registered
- callback modules, <c>LocalFilename</c> is tested against
- the regexps of these and the callback module corresponding to
- the first match is used, or an error tuple is returned if no
- matching regexp is found.</p>
+ <p>Changes configuration for all TFTP server processes.</p>
</desc>
-
- <marker id="write_file"></marker>
</func>
<func>
- <name>write_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name>
- <fsummary>Write a (virtual) file to a TFTP server</fsummary>
+ <name>change_config(Pid, Options) -> Result</name>
+ <fsummary>Changes configuration for a TFTP daemon, server,
+ or client process.</fsummary>
<type>
- <v>RemoteFilename = string()</v>
- <v>LocalFilename = binary() | string()</v>
+ <v>Pid = pid()</v>
<v>Options = [option()]</v>
- <v>LastCallbackState = term()</v>
+ <v>Result = ok | {error, Reason}</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes a (virtual) file <c>RemoteFilename</c> to a TFTP
- server.</p>
- <p>If <c>LocalFilename</c> is a binary, <c>tftp_binary</c> is
- used as callback module. The binary is transferred block by
- block and the number of transferred bytes is returned in
- <c>LastCallbackState</c>.</p>
- <p>If <c>LocalFilename</c> is a string and there are no
- registered callback modules, <c>tftp_file</c> is used as
- callback module. It reads the file named <c>LocalFilename</c>
- block by block and returns the number of transferred bytes
- in <c>LastCallbackState</c>.</p>
- <p>If <c>LocalFilename</c> is a string and there are registered
- callback modules, <c>LocalFilename</c> is tested against
- the regexps of these and the callback module corresponding to
- the first match is used, or an error tuple is returned if no
- matching regexp is found.</p>
-
- <marker id="info_daemons"></marker>
+ <p>Changes configuration for a TFTP daemon, server, or client process.</p>
</desc>
</func>
-
+
<func>
<name>info(daemons) -> [{Pid, Options}]</name>
- <fsummary>Return information about all daemons</fsummary>
+ <fsummary>Returns information about all daemons.</fsummary>
<type>
<v>Pid = [pid()()]</v>
<v>Options = [option()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Returns info about all TFTP daemon processes. </p>
-
- <marker id="info_servers"></marker>
+ <p>Returns information about all TFTP daemon processes.</p>
</desc>
</func>
<func>
<name>info(servers) -> [{Pid, Options}]</name>
- <fsummary>Return information about all servers</fsummary>
+ <fsummary>Returns information about all servers.</fsummary>
<type>
<v>Pid = [pid()()]</v>
<v>Options = [option()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Returns info about all TFTP server processes. </p>
-
- <marker id="info_pid"></marker>
+ <p>Returns information about all TFTP server processes. </p>
</desc>
</func>
<func>
<name>info(Pid) -> {ok, Options} | {error, Reason}</name>
- <fsummary>Return information about a daemon, server or client process</fsummary>
+ <fsummary>Returns information about a daemon, server, or client process.</fsummary>
<type>
<v>Options = [option()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Returns info about a TFTP daemon, server or client process.</p>
-
- <marker id="change_config_daemons"></marker>
+ <p>Returns information about a TFTP daemon, server, or client process.</p>
</desc>
</func>
-
- <func>
- <name>change_config(daemons, Options) -> [{Pid, Result}]</name>
- <fsummary>Changes config for all daemons
- </fsummary>
+
+ <func>
+ <name>read_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name>
+ <fsummary>Reads a (virtual) file from a TFTP server.</fsummary>
<type>
+ <v>RemoteFilename = string()</v>
+ <v>LocalFilename = binary | string()</v>
<v>Options = [option()]</v>
- <v>Pid = pid()</v>
- <v>Result = ok | {error, Reason}</v>
+ <v>LastCallbackState = term()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Changes config for all TFTP daemon processes. </p>
-
- <marker id="change_config_servers"></marker>
- </desc>
+ <p>Reads a (virtual) file <c>RemoteFilename</c> from a TFTP
+ server.</p>
+ <p>If <c>LocalFilename</c> is the atom <c>binary</c>,
+ <c>tftp_binary</c> is used as callback module. It concatenates
+ all transferred blocks and returns them as one single binary
+ in <c>LastCallbackState</c>.</p>
+ <p>If <c>LocalFilename</c> is a string and there are no
+ registered callback modules, <c>tftp_file</c> is used as
+ callback module. It writes each transferred block to the file
+ named <c>LocalFilename</c> and returns the number of
+ transferred bytes in <c>LastCallbackState</c>.</p>
+ <p>If <c>LocalFilename</c> is a string and there are registered
+ callback modules, <c>LocalFilename</c> is tested against
+ the regexps of these and the callback module corresponding to
+ the first match is used, or an error tuple is returned if no
+ matching regexp is found.</p>
+ </desc>
</func>
-
+
<func>
- <name>change_config(servers, Options) -> [{Pid, Result}]</name>
- <fsummary>Changes config for all servers
- </fsummary>
+ <name>start(Options) -> {ok, Pid} | {error, Reason}</name>
+ <fsummary>Starts a daemon process.</fsummary>
<type>
<v>Options = [option()]</v>
<v>Pid = pid()</v>
- <v>Result = ok | {error, Reason}</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Changes config for all TFTP server processes. </p>
-
- <marker id="change_config_pid"></marker>
+ <p>Starts a daemon process listening for UDP packets on a
+ port. When it receives a request for read or write, it spawns
+ a temporary server process handling the actual transfer
+ of the (virtual) file.</p>
</desc>
</func>
<func>
- <name>change_config(Pid, Options) -> Result</name>
- <fsummary>Changes config for a TFTP daemon, server or client process</fsummary>
+ <name>write_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name>
+ <fsummary>Writes a (virtual) file to a TFTP server.</fsummary>
<type>
- <v>Pid = pid()</v>
+ <v>RemoteFilename = string()</v>
+ <v>LocalFilename = binary() | string()</v>
<v>Options = [option()]</v>
- <v>Result = ok | {error, Reason}</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Changes config for a TFTP daemon, server or client process</p>
-
- <marker id="start2"></marker>
- </desc>
- </func>
-
- <func>
- <name>start() -> ok | {error, Reason}</name>
- <fsummary>Start the Inets application</fsummary>
- <type>
+ <v>LastCallbackState = term()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Starts the Inets application.</p>
+ <p>Writes a (virtual) file <c>RemoteFilename</c> to a TFTP
+ server.</p>
+ <p>If <c>LocalFilename</c> is a binary, <c>tftp_binary</c> is
+ used as callback module. The binary is transferred block by
+ block and the number of transferred bytes is returned in
+ <c>LastCallbackState</c>.</p>
+ <p>If <c>LocalFilename</c> is a string and there are no
+ registered callback modules, <c>tftp_file</c> is used as
+ callback module. It reads the file named <c>LocalFilename</c>
+ block by block and returns the number of transferred bytes
+ in <c>LastCallbackState</c>.</p>
+ <p>If <c>LocalFilename</c> is a string and there are registered
+ callback modules, <c>LocalFilename</c> is tested against
+ the regexps of these and the callback module corresponding to
+ the first match is used, or an error tuple is returned if no
+ matching regexp is found.</p>
</desc>
</func>
</funcs>
@@ -414,40 +382,41 @@
<section>
<marker id="tftp_callback"></marker>
<title>CALLBACK FUNCTIONS</title>
- <p>A <c>tftp</c> callback module should be implemented as a
- <c>tftp</c> behavior and export the functions listed below.</p>
- <p>On the server side the callback interaction starts with a call to
+ <p>A <c>tftp</c> callback module is to be implemented as a
+ <c>tftp</c> behavior and export the functions listed
+ in the following.</p>
+ <p>On the server side, the callback interaction starts with a call to
<c>open/5</c> with the registered initial callback state.
<c>open/5</c> is expected to open the (virtual) file. Then either
- the <c>read/1</c> or <c>write/2</c> functions are invoked
- repeatedly, once per transferred block. At each function call
+ function <c>read/1</c> or <c>write/2</c> is invoked
+ repeatedly, once per transferred block. At each function call,
the state returned from the previous call is obtained. When
- the last block has been encountered the <c>read/1</c> or
- <c>write/2</c> functions is expected to close the (virtual) file
- and return its last state. The <c>abort/3</c> function is only
- used in error situations. <c>prepare/5</c> is not used on
+ the last block is encountered, function <c>read/1</c> or
+ <c>write/2</c> is expected to close the (virtual) file
+ and return its last state. Function <c>abort/3</c> is only
+ used in error situations. Function <c>prepare/5</c> is not used on
the server side.</p>
- <p>On the client side the callback interaction is the same, but it
+ <p>On the client side, the callback interaction is the same, but it
starts and ends a bit differently. It starts with a call to
<c>prepare/5</c> with the same arguments as <c>open/5</c> takes.
- <c>prepare/5</c> is expected to validate the TFTP options,
- suggested by the user and return the subset of them that it
- accepts. Then the options is sent to the server which will perform
+ <c>prepare/5</c> is expected to validate the TFTP options
+ suggested by the user and to return the subset of them that it
+ accepts. Then the options are sent to the server, which performs
the same TFTP option negotiation procedure. The options that are
- accepted by the server are forwarded to the <c>open/5</c> function
- on the client side. On the client side the <c>open/5</c> function
- must accept all option as is or reject the transfer. Then
+ accepted by the server are forwarded to function <c>open/5</c>
+ on the client side. On the client side, function <c>open/5</c>
+ must accept all option as-is or reject the transfer. Then
the callback interaction follows the same pattern as described
- above for the server side. When the last block is encountered in
- <c>read/1</c> or <c>write/2</c> the returned state is forwarded to
+ for the server side. When the last block is encountered in
+ <c>read/1</c> or <c>write/2</c>, the returned state is forwarded to
the user and returned from <c>read_file</c>/3 or
<c>write_file/3</c>.</p>
- <p> If a callback (which performs the file access
+ <p> If a callback (performing the file access
in the TFTP server) takes too long time (more than
- the double TFTP timeout), the server will abort the
- connection and send an error reply to the client.
- This implies that the server will release resources
+ the double TFTP time-out), the server aborts the
+ connection and sends an error reply to the client.
+ This implies that the server releases resources
attached to the connection faster than before. The
server simply assumes that the client has given
up.</p>
@@ -455,21 +424,45 @@
<p>If the TFTP server receives yet another request from
the same client (same host and port) while it
already has an active connection to the client, it
- will simply ignore the new request if the request is
- equal with the first one (same filename and options).
+ ignores the new request if the request is
+ equal to the first one (same filename and options).
This implies that the (new) client will be served
by the already ongoing connection on the server
side. By not setting up yet another connection, in
- parallel with the ongoing one, the server will
- consumer lesser resources. </p>
+ parallel with the ongoing one, the server
+ consumes less resources.</p>
<marker id="prepare"></marker>
</section>
<funcs>
- <func>
- <name>prepare(Peer, Access, Filename, Mode, SuggestedOptions, InitialState) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name>
- <fsummary>Prepare to open a file on the client side</fsummary>
+ <func>
+ <name>Module:abort(Code, Text, State) -> ok</name>
+ <fsummary>Aborts the file transfer.</fsummary>
+ <type>
+ <v>Code = undef | enoent | eacces | enospc</v>
+ <v>&nbsp;&nbsp;| badop | eexist | baduser | badopt</v>
+ <v>&nbsp;&nbsp;| int()</v>
+ <v>Text = string()</v>
+ <v>State = term()</v>
+ </type>
+ <desc>
+ <p>Invoked when the file transfer is aborted.</p>
+ <p>The callback function is expected to clean
+ up its used resources after the aborted file
+ transfer, such as closing open file
+ descriptors and so on. The function is not
+ invoked if any of the other callback
+ functions returns an error, as it is
+ expected that they already have cleaned up
+ the necessary resources. However, it is
+ invoked if the functions fail (crash).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:open(Peer, Access, Filename, Mode, SuggestedOptions, State) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name>
+ <fsummary>Opens a file for read or write access.</fsummary>
<type>
<v>Peer = {PeerType, PeerHost, PeerPort}</v>
<v>PeerType = inet | inet6</v>
@@ -480,7 +473,8 @@
<v>Mode = string()</v>
<v>SuggestedOptions = AcceptedOptions = [{Key, Value}]</v>
<v>&nbsp;Key = Value = string()</v>
- <v>InitialState = [] | [{root_dir, string()}]</v>
+ <v>State = InitialState | term()</v>
+ <v>&nbsp;InitialState = [] | [{root_dir, string()}]</v>
<v>NewState = term()</v>
<v>Code = undef | enoent | eacces | enospc</v>
<v>&nbsp;&nbsp;| badop | eexist | baduser | badopt</v>
@@ -488,23 +482,22 @@
<v>Text = string()</v>
</type>
<desc>
- <p>Prepares to open a file on the client side.</p>
- <p>No new options may be added, but the ones that are present in
- <c>SuggestedOptions</c> may be omitted or replaced with new
- values in <c>AcceptedOptions</c>.</p>
- <p>Will be followed by a call to <c>open/4</c> before any
- read/write access is performed. <c>AcceptedOptions</c> is
- sent to the server which replies with those options that it
- accepts. These will be forwarded to <c>open/4</c> as
- <c>SuggestedOptions</c>.</p>
+ <p>Opens a file for read or write access.</p>
+ <p>On the client side, where the <c>open/5</c> call has been
+ preceded by a call to <c>prepare/5</c>, all options must be
+ accepted or rejected.</p>
+ <p>On the server side, where there is no preceding
+ <c>prepare/5</c> call, no new options can be added, but
+ those present in <c>SuggestedOptions</c> can be
+ omitted or replaced with new values in <c>AcceptedOptions</c>.</p>
- <marker id="open"></marker>
+ <marker id="read"></marker>
</desc>
</func>
-
+
<func>
- <name>open(Peer, Access, Filename, Mode, SuggestedOptions, State) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name>
- <fsummary>Open a file for read or write access</fsummary>
+ <name>Module:prepare(Peer, Access, Filename, Mode, SuggestedOptions, InitialState) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name>
+ <fsummary>Prepares to open a file on the client side.</fsummary>
<type>
<v>Peer = {PeerType, PeerHost, PeerPort}</v>
<v>PeerType = inet | inet6</v>
@@ -515,8 +508,7 @@
<v>Mode = string()</v>
<v>SuggestedOptions = AcceptedOptions = [{Key, Value}]</v>
<v>&nbsp;Key = Value = string()</v>
- <v>State = InitialState | term()</v>
- <v>&nbsp;InitialState = [] | [{root_dir, string()}]</v>
+ <v>InitialState = [] | [{root_dir, string()}]</v>
<v>NewState = term()</v>
<v>Code = undef | enoent | eacces | enospc</v>
<v>&nbsp;&nbsp;| badop | eexist | baduser | badopt</v>
@@ -524,22 +516,23 @@
<v>Text = string()</v>
</type>
<desc>
- <p>Opens a file for read or write access.</p>
- <p>On the client side where the <c>open/5</c> call has been
- preceded by a call to <c>prepare/5</c>, all options must be
- accepted or rejected.</p>
- <p>On the server side, where there is no preceding
- <c>prepare/5</c> call, no new options may be added, but
- the ones that are present in <c>SuggestedOptions</c> may be
- omitted or replaced with new values in <c>AcceptedOptions</c>.</p>
+ <p>Prepares to open a file on the client side.</p>
+ <p>No new options can be added, but those present in
+ <c>SuggestedOptions</c> can be omitted or replaced with new
+ values in <c>AcceptedOptions</c>.</p>
+ <p>This is followed by a call to <c>open/4</c> before any
+ read/write access is performed. <c>AcceptedOptions</c> is
+ sent to the server, which replies with the options that it
+ accepts. These are then forwarded to <c>open/4</c> as
+ <c>SuggestedOptions</c>.</p>
- <marker id="read"></marker>
+ <marker id="open"></marker>
</desc>
</func>
<func>
- <name>read(State) -> {more, Bin, NewState} | {last, Bin, FileSize} | {error, {Code, Text}}</name>
- <fsummary>Read a chunk from the file</fsummary>
+ <name>Module:read(State) -> {more, Bin, NewState} | {last, Bin, FileSize} | {error, {Code, Text}}</name>
+ <fsummary>Reads a chunk from the file.</fsummary>
<type>
<v>State = NewState = term()</v>
<v>Bin = binary()</v>
@@ -550,13 +543,13 @@
<v>Text = string()</v>
</type>
<desc>
- <p>Read a chunk from the file.</p>
+ <p>Reads a chunk from the file.</p>
<p>The callback function is expected to close
the file when the last file chunk is
- encountered. When an error is encountered
+ encountered. When an error is encountered,
the callback function is expected to clean
up after the aborted file transfer, such as
- closing open file descriptors etc. In both
+ closing open file descriptors, and so on. In both
cases there will be no more calls to any of
the callback functions.</p>
@@ -565,8 +558,8 @@
</func>
<func>
- <name>write(Bin, State) -> {more, NewState} | {last, FileSize} | {error, {Code, Text}}</name>
- <fsummary>Write a chunk to the file</fsummary>
+ <name>Module:write(Bin, State) -> {more, NewState} | {last, FileSize} | {error, {Code, Text}}</name>
+ <fsummary>Writes a chunk to the file.</fsummary>
<type>
<v>Bin = binary()</v>
<v>State = NewState = term()</v>
@@ -577,99 +570,75 @@
<v>Text = string()</v>
</type>
<desc>
- <p>Write a chunk to the file.</p>
+ <p>Writes a chunk to the file.</p>
<p>The callback function is expected to close
the file when the last file chunk is
- encountered. When an error is encountered
+ encountered. When an error is encountered,
the callback function is expected to clean
up after the aborted file transfer, such as
- closing open file descriptors etc. In both
+ closing open file descriptors, and so on. In both
cases there will be no more calls to any of
the callback functions.</p>
<marker id="abort"></marker>
</desc>
</func>
-
- <func>
- <name>abort(Code, Text, State) -> ok</name>
- <fsummary>Abort the file transfer</fsummary>
- <type>
- <v>Code = undef | enoent | eacces | enospc</v>
- <v>&nbsp;&nbsp;| badop | eexist | baduser | badopt</v>
- <v>&nbsp;&nbsp;| int()</v>
- <v>Text = string()</v>
- <v>State = term()</v>
- </type>
- <desc>
- <p>Invoked when the file transfer is aborted.</p>
- <p>The callback function is expected to clean
- up its used resources after the aborted file
- transfer, such as closing open file
- descriptors etc. The function will not be
- invoked if any of the other callback
- functions returns an error, as it is
- expected that they already have cleaned up
- the necessary resources. It will however be
- invoked if the functions fails (crashes).</p>
- </desc>
- </func>
</funcs>
<section>
<marker id="tftp_logger"></marker>
<title>LOGGER FUNCTIONS</title>
- <p>A <c>tftp_logger</c> callback module should be implemented as a
- <c>tftp_logger</c> behavior and export the functions listed below.</p>
+ <p>A <c>tftp_logger</c> callback module is to be implemented as a
+ <c>tftp_logger</c> behavior and export the following functions:</p>
<marker id="error_msg"></marker>
</section>
<funcs>
<func>
- <name>error_msg(Format, Data) -> ok | exit(Reason)</name>
- <fsummary>Log an error message</fsummary>
+ <name>Logger:error_msg(Format, Data) -> ok | exit(Reason)</name>
+ <fsummary>Logs an error message.</fsummary>
<type>
<v>Format = string()</v>
<v>Data = [term()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Log an error message.
- See <c>error_logger:error_msg/2 for details.</c> </p>
+ <p>Logs an error message.
+ See <c>error_logger:error_msg/2</c> for details.</p>
<marker id="warning_msg"></marker>
</desc>
</func>
<func>
- <name>warning_msg(Format, Data) -> ok | exit(Reason)</name>
- <fsummary>Log an error message</fsummary>
+ <name>Logger:info_msg(Format, Data) -> ok | exit(Reason)</name>
+ <fsummary>Logs an info message.</fsummary>
<type>
<v>Format = string()</v>
<v>Data = [term()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Log a warning message.
- See <c>error_logger:warning_msg/2 for details.</c> </p>
-
- <marker id="info_msg"></marker>
+ <p>Logs an info message.
+ See <c>error_logger:info_msg/2</c> for details.</p>
</desc>
</func>
-
+
<func>
- <name>info_msg(Format, Data) -> ok | exit(Reason)</name>
- <fsummary>Log an error message</fsummary>
+ <name>Logger:warning_msg(Format, Data) -> ok | exit(Reason)</name>
+ <fsummary>Logs a warning message.</fsummary>
<type>
<v>Format = string()</v>
<v>Data = [term()]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Log an info message.
- See <c>error_logger:info_msg/2 for details.</c> </p>
+ <p>Logs a warning message.
+ See <c>error_logger:warning_msg/2</c> for details.</p>
+
+ <marker id="info_msg"></marker>
</desc>
</func>
</funcs>
diff --git a/lib/inets/examples/Makefile b/lib/inets/examples/Makefile
index 775c449062..9a852cf023 100644
--- a/lib/inets/examples/Makefile
+++ b/lib/inets/examples/Makefile
@@ -3,16 +3,17 @@
#
# 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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/inets/examples/httpd_load_test/Makefile b/lib/inets/examples/httpd_load_test/Makefile
index abd2d8c35d..aab62e7305 100644
--- a/lib/inets/examples/httpd_load_test/Makefile
+++ b/lib/inets/examples/httpd_load_test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/inets/examples/httpd_load_test/hdlt.erl b/lib/inets/examples/httpd_load_test/hdlt.erl
index 18d8c34ccf..ae12606bb2 100644
--- a/lib/inets/examples/httpd_load_test/hdlt.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/examples/httpd_load_test/hdlt.sh.skel b/lib/inets/examples/httpd_load_test/hdlt.sh.skel
index a250bad9c5..537a555e50 100644
--- a/lib/inets/examples/httpd_load_test/hdlt.sh.skel
+++ b/lib/inets/examples/httpd_load_test/hdlt.sh.skel
@@ -5,16 +5,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/inets/examples/httpd_load_test/hdlt_client.erl b/lib/inets/examples/httpd_load_test/hdlt_client.erl
index d65ac5a885..a6273a11b8 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_client.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_client.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl b/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl
index 950d2632f7..880ce99e72 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/examples/httpd_load_test/hdlt_logger.erl b/lib/inets/examples/httpd_load_test/hdlt_logger.erl
index b0c7eab2d1..e444030d7f 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_logger.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_logger.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/examples/httpd_load_test/hdlt_logger.hrl b/lib/inets/examples/httpd_load_test/hdlt_logger.hrl
index aa94babc48..240add0147 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_logger.hrl
+++ b/lib/inets/examples/httpd_load_test/hdlt_logger.hrl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
index e3a572c61f..3b72d27f06 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,7 +49,10 @@ stop() ->
".
content(WorkSim, SzSim) ->
- {A, B, C} = now(),
+ {A, B, C} = {erlang:phash2([node()]),
+ inets_time_compat:monotonic_time(),
+ inets_time_compat:unique_integer()},
+
random:seed(A, B, C),
lists:sort([random:uniform(X) || X <- lists:seq(1, WorkSim)]),
lists:flatten(lists:duplicate(SzSim, "Dummy data ")).
diff --git a/lib/inets/examples/httpd_load_test/hdlt_server.erl b/lib/inets/examples/httpd_load_test/hdlt_server.erl
index 3e5a849d5b..dde09a46df 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_server.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_server.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/examples/httpd_load_test/hdlt_slave.erl b/lib/inets/examples/httpd_load_test/hdlt_slave.erl
index 41361418bc..f05a1046d3 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_slave.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_slave.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/examples/httpd_load_test/modules.mk b/lib/inets/examples/httpd_load_test/modules.mk
index 9d0d7103d5..3349664230 100644
--- a/lib/inets/examples/httpd_load_test/modules.mk
+++ b/lib/inets/examples/httpd_load_test/modules.mk
@@ -4,16 +4,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/inets/examples/server_root/Makefile b/lib/inets/examples/server_root/Makefile
index 7a0ee78ecf..45118aeae0 100644
--- a/lib/inets/examples/server_root/Makefile
+++ b/lib/inets/examples/server_root/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/examples/server_root/conf/httpd.conf b/lib/inets/examples/server_root/conf/httpd.conf
index 8a74ed1afd..f99563d14b 100644
--- a/lib/inets/examples/server_root/conf/httpd.conf
+++ b/lib/inets/examples/server_root/conf/httpd.conf
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/inets/include/httpd.hrl b/lib/inets/include/httpd.hrl
index a7e63ca670..8d2803ad3b 100644
--- a/lib/inets/include/httpd.hrl
+++ b/lib/inets/include/httpd.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/include/mod_auth.hrl b/lib/inets/include/mod_auth.hrl
index cf931e681a..bd3577b9ee 100644
--- a/lib/inets/include/mod_auth.hrl
+++ b/lib/inets/include/mod_auth.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/priv/Makefile b/lib/inets/priv/Makefile
index acca20f076..b0e65f8f9c 100644
--- a/lib/inets/priv/Makefile
+++ b/lib/inets/priv/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/inets/src/Makefile b/lib/inets/src/Makefile
index dd18e92107..a2a70a7b8f 100644
--- a/lib/inets/src/Makefile
+++ b/lib/inets/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/inets/src/ftp/Makefile b/lib/inets/src/ftp/Makefile
index 2c3d2b6d13..f8daa2b894 100644
--- a/lib/inets/src/ftp/Makefile
+++ b/lib/inets/src/ftp/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index 8e51b1be5a..db6260c7af 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -2176,16 +2177,16 @@ handle_caller(#state{caller = {transfer_data, {Cmd, Bin, RemoteFile}}} =
%% Connect to FTP server at Host (default is TCP port 21)
%% in order to establish a control connection.
setup_ctrl_connection(Host, Port, Timeout, State) ->
- MsTime = millisec_time(),
+ MsTime = inets_time_compat:monotonic_time(),
case connect(Host, Port, Timeout, State) of
{ok, IpFam, CSock} ->
NewState = State#state{csock = {tcp, CSock}, ipfamily = IpFam},
activate_ctrl_connection(NewState),
- case Timeout - (millisec_time() - MsTime) of
+ case Timeout - inets_lib:millisec_passed(MsTime) of
Timeout2 when (Timeout2 >= 0) ->
{ok, NewState#state{caller = open}, Timeout2};
_ ->
- %% Oups: Simulate timeout
+ %% Oups: Simulate timeout
{ok, NewState#state{caller = open}, 0}
end;
Error ->
@@ -2501,10 +2502,6 @@ progress_report(Report, #state{progress = ProgressPid}) ->
ftp_progress:report(ProgressPid, Report).
-millisec_time() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
peername({tcp, Socket}) -> inet:peername(Socket);
peername({ssl, Socket}) -> ssl:peername(Socket).
diff --git a/lib/inets/src/ftp/ftp_internal.hrl b/lib/inets/src/ftp/ftp_internal.hrl
index 148f8217ba..a6c9fa098a 100644
--- a/lib/inets/src/ftp/ftp_internal.hrl
+++ b/lib/inets/src/ftp/ftp_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/ftp/ftp_progress.erl b/lib/inets/src/ftp/ftp_progress.erl
index 39f4d05bc2..9c42723a07 100644
--- a/lib/inets/src/ftp/ftp_progress.erl
+++ b/lib/inets/src/ftp/ftp_progress.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/ftp/ftp_response.erl b/lib/inets/src/ftp/ftp_response.erl
index dfe180ff18..0aac15ef6c 100644
--- a/lib/inets/src/ftp/ftp_response.erl
+++ b/lib/inets/src/ftp/ftp_response.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/ftp/ftp_sup.erl b/lib/inets/src/ftp/ftp_sup.erl
index 547170b671..b5b3f6a105 100644
--- a/lib/inets/src/ftp/ftp_sup.erl
+++ b/lib/inets/src/ftp/ftp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile
index f0d4ce139e..cb97b525f6 100644
--- a/lib/inets/src/http_client/Makefile
+++ b/lib/inets/src/http_client/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
index da9bbdd1ec..4554881d79 100644
--- a/lib/inets/src/http_client/httpc.erl
+++ b/lib/inets/src/http_client/httpc.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -100,7 +101,8 @@ request(Url, Profile) ->
%% {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |
%% {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}
%%
-%% Method - atom() = head | get | put | post | trace | options| delete
+%% Method - atom() = head | get | put | patch | post | trace |
+%% options | delete
%% Request - {Url, Headers} | {Url, Headers, ContentType, Body}
%% Url - string()
%% HTTPOptions - [HttpOption]
@@ -175,8 +177,8 @@ request(Method,
request(Method,
{Url, Headers, ContentType, Body},
HTTPOptions, Options, Profile)
- when ((Method =:= post) orelse (Method =:= put) orelse (Method =:= delete)) andalso
- (is_atom(Profile) orelse is_pid(Profile)) ->
+ when ((Method =:= post) orelse (Method =:= patch) orelse (Method =:= put) orelse
+ (Method =:= delete)) andalso (is_atom(Profile) orelse is_pid(Profile)) ->
?hcrt("request", [{method, Method},
{url, Url},
{headers, Headers},
@@ -554,7 +556,7 @@ handle_request(Method, Url,
Request = #request{from = Receiver,
scheme = Scheme,
- address = {Host, Port},
+ address = {host_address(Host, BracketedHost), Port},
path = MaybeEscPath,
pquery = MaybeEscQuery,
method = Method,
@@ -1266,3 +1268,7 @@ child_name(Pid, [_ | Children]) ->
%% d(_, _, _) ->
%% ok.
+host_address(Host, false) ->
+ Host;
+host_address(Host, true) ->
+ string:strip(string:strip(Host, right, $]), left, $[).
diff --git a/lib/inets/src/http_client/httpc_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl
index 35778d3ed5..0c4f44a575 100644
--- a/lib/inets/src/http_client/httpc_cookie.erl
+++ b/lib/inets/src/http_client/httpc_cookie.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 0bbd40d656..d1c52dcc78 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -25,6 +26,7 @@
-include_lib("inets/src/http_lib/http_internal.hrl").
-include("httpc_internal.hrl").
+-define(IS_STREAMED(Code), ((Code =:= 200) orelse (Code =:= 206))).
%%--------------------------------------------------------------------
%% Internal Application API
@@ -87,7 +89,7 @@
%% block the httpc manager process in odd cases such as trying to call
%% a server that does not exist. (See OTP-6735) The only API function
%% sending messages to the handler process that can be called before
-%% init has compleated is cancel and that is not a problem! (Send and
+%% init has completed is cancel and that is not a problem! (Send and
%% stream will not be called before the first request has been sent and
%% the reply or part of it has arrived.)
%%--------------------------------------------------------------------
@@ -162,22 +164,22 @@ info(Pid) ->
%% Request should not be streamed
stream(BodyPart, #request{stream = none} = Request, _) ->
?hcrt("stream - none", []),
- {BodyPart, Request};
+ {false, BodyPart, Request};
%% Stream to caller
stream(BodyPart, #request{stream = Self} = Request, Code)
- when ((Code =:= 200) orelse (Code =:= 206)) andalso
+ when ?IS_STREAMED(Code) andalso
((Self =:= self) orelse (Self =:= {self, once})) ->
?hcrt("stream - self", [{stream, Self}, {code, Code}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
- {<<>>, Request};
+ {true, <<>>, Request};
%% Stream to file
%% This has been moved to start_stream/3
%% We keep this for backward compatibillity...
stream(BodyPart, #request{stream = Filename} = Request, Code)
- when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
+ when ?IS_STREAMED(Code) andalso is_list(Filename) ->
?hcrt("stream - filename", [{stream, Filename}, {code, Code}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
@@ -189,18 +191,18 @@ stream(BodyPart, #request{stream = Filename} = Request, Code)
%% Stream to file
stream(BodyPart, #request{stream = Fd} = Request, Code)
- when ((Code =:= 200) orelse (Code =:= 206)) ->
+ when ?IS_STREAMED(Code) ->
?hcrt("stream to file", [{stream, Fd}, {code, Code}]),
case file:write(Fd, BodyPart) of
ok ->
- {<<>>, Request};
+ {true, <<>>, Request};
{error, Reason} ->
exit({stream_to_file_failed, Reason})
end;
stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
?hcrt("stream - ignore", [{request, Request}]),
- {BodyPart, Request}.
+ {false, BodyPart, Request}.
%%====================================================================
@@ -316,8 +318,9 @@ handle_call(#request{address = Addr} = Request, _,
{reply, ok, State}
end;
{error, Reason} ->
- ?hcri("failed sending request", [{reason, Reason}]),
- {reply, {pipeline_failed, Reason}, State0}
+ ?hcri("failed sending request", [{reason, Reason}]),
+ NewPipeline = queue:in(Request, State0#state.pipeline),
+ {stop, shutdown, {pipeline_failed, Reason}, State0#state{pipeline = NewPipeline}}
end;
handle_call(#request{address = Addr} = Request, _,
@@ -355,25 +358,25 @@ handle_call(#request{address = Addr} = Request, _,
?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
+ NewTimers = Timers#timers{queue_timer = undefined},
+ State1 = State0#state{timers = NewTimers},
Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Session, Request) of
ok ->
?hcrd("request sent", []),
%% Activate the request time out for the new request
- State1 =
- activate_request_timeout(State0#state{request = Request}),
- NewTimers = State1#state.timers,
+ State2 =
+ activate_request_timeout(State1#state{request = Request}),
NewSession =
Session#session{queue_length = 1,
client_close = ClientClose},
insert_session(NewSession, ProfileName),
- State = init_wait_for_response_state(Request, State1#state{session = NewSession,
- timers = NewTimers}),
+ State = init_wait_for_response_state(Request, State2#state{session = NewSession}),
{reply, ok, State};
{error, Reason} ->
?hcri("failed sending request", [{reason, Reason}]),
- {reply, {request_failed, Reason}, State0}
+ {stop, shutdown, {keepalive_failed, Reason}, State1}
end
end;
@@ -391,7 +394,7 @@ handle_call(info, _, State) ->
%% When the request in process has been canceled the handler process is
%% stopped and the pipelined requests will be reissued or remaining
%% requests will be sent on a new connection. This is is
-%% based on the assumption that it is proably cheaper to reissue the
+%% based on the assumption that it is probably cheaper to reissue the
%% requests than to wait for a potentiall large response that we then
%% only throw away. This of course is not always true maybe we could
%% do something smarter here?! If the request canceled is not
@@ -419,6 +422,16 @@ handle_cast({cancel, RequestId},
{profile, ProfileName},
{canceled, Canceled}]),
{noreply, State#state{canceled = [RequestId | Canceled]}};
+handle_cast({cancel, RequestId},
+ #state{profile_name = ProfileName,
+ request = undefined,
+ canceled = Canceled} = State) ->
+ ?hcrv("cancel", [{request_id, RequestId},
+ {curr_req_id, undefined},
+ {profile, ProfileName},
+ {canceled, Canceled}]),
+ {noreply, State};
+
handle_cast(stream_next, #state{session = Session} = State) ->
activate_once(Session),
@@ -462,18 +475,18 @@ handle_info({Proto, _Socket, Data},
{Module, whole_body, [Body, Length]} ->
?hcrd("data processed - whole body", [{length, Length}]),
{_, Code, _} = StatusLine,
- {NewBody, NewRequest} = stream(Body, Request, Code),
+ {Streamed, NewBody, NewRequest} = stream(Body, Request, Code),
%% When we stream we will not keep the already
%% streamed data, that would be a waste of memory.
NewLength =
- case Stream of
- none ->
+ case Streamed of
+ false ->
Length;
- _ ->
+ true ->
Length - size(Body)
end,
- NewState = next_body_chunk(State),
+ NewState = next_body_chunk(State, Code),
NewMFA = {Module, whole_body, [NewBody, NewLength]},
{noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
@@ -485,8 +498,8 @@ handle_info({Proto, _Socket, Data},
%% The response body is chunk-encoded. Steal decoded
%% chunks as much as possible to stream.
{_, Code, _} = StatusLine,
- {NewBody, NewRequest} = stream(BodySoFar, Request, Code),
- NewState = next_body_chunk(State),
+ {_, NewBody, NewRequest} = stream(BodySoFar, Request, Code),
+ NewState = next_body_chunk(State, Code),
NewMFA = {Module, decode_size,
[TotalChunk, HexList,
{MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
@@ -505,8 +518,8 @@ handle_info({Proto, _Socket, Data},
NewChunkSize = ChunkSize - ChunkSizeToSteal,
{_, Code, _} = StatusLine,
- {NewBody, NewRequest} = stream(StolenBody, Request, Code),
- NewState = next_body_chunk(State),
+ {_, NewBody, NewRequest} = stream(StolenBody, Request, Code),
+ NewState = next_body_chunk(State, Code),
NewMFA = {Module, decode_data,
[NewChunkSize, NewTotalChunk,
{MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
@@ -1059,13 +1072,13 @@ handle_http_msg({ChunkedHeaders, Body},
?hcrt("handle_http_msg",
[{chunked_headers, ChunkedHeaders}, {headers, Headers}]),
NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
- {NewBody, NewRequest} = stream(Body, State#state.request, Code),
+ {_, NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{headers = NewHeaders,
body = NewBody,
request = NewRequest});
handle_http_msg(Body, #state{status_line = {_,Code, _}} = State) ->
?hcrt("handle_http_msg", [{code, Code}]),
- {NewBody, NewRequest} = stream(Body, State#state.request, Code),
+ {_, NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{body = NewBody, request = NewRequest}).
handle_http_body(_, #state{status = {ssl_tunnel, _},
@@ -1100,14 +1113,14 @@ handle_http_body(Body, #state{headers = Headers,
case case_insensitive_header(TransferEnc) of
"chunked" ->
?hcrt("handle_http_body - chunked", []),
- case http_chunk:decode(Body, State#state.max_body_size,
- State#state.max_header_size) of
+ try http_chunk:decode(Body, State#state.max_body_size,
+ State#state.max_header_size) of
{Module, Function, Args} ->
?hcrt("handle_http_body - new mfa",
[{module, Module},
{function, Function},
{args, Args}]),
- NewState = next_body_chunk(State),
+ NewState = next_body_chunk(State, Code),
{noreply, NewState#state{mfa =
{Module, Function, Args}}};
{ok, {ChunkedHeaders, NewBody}} ->
@@ -1121,11 +1134,18 @@ handle_http_body(Body, #state{headers = Headers,
handle_response(State#state{headers = NewHeaders,
body = NewBody});
_ ->
- {NewBody2, NewRequest} =
+ {_, NewBody2, _} =
stream(NewBody, Request, Code),
handle_response(State#state{headers = NewHeaders,
body = NewBody2})
end
+ catch throw:{error, Reason} ->
+ NewState =
+ answer_request(Request,
+ httpc_response:error(Request,
+ Reason),
+ State),
+ {stop, normal, NewState}
end;
Enc when Enc =:= "identity"; Enc =:= undefined ->
?hcrt("handle_http_body - identity", []),
@@ -1135,12 +1155,12 @@ handle_http_body(Body, #state{headers = Headers,
true ->
case httpc_response:whole_body(Body, Length) of
{ok, Body} ->
- {NewBody, NewRequest} =
+ {_, NewBody, NewRequest} =
stream(Body, Request, Code),
handle_response(State#state{body = NewBody,
request = NewRequest});
MFA ->
- NewState = next_body_chunk(State),
+ NewState = next_body_chunk(State, Code),
{noreply, NewState#state{mfa = MFA}}
end;
false ->
@@ -1301,7 +1321,8 @@ handle_pipeline(#state{status = pipeline,
handle_keep_alive_queue(#state{status = keep_alive,
session = Session,
profile_name = ProfileName,
- options = #options{keep_alive_timeout = TimeOut}} = State,
+ options = #options{keep_alive_timeout = TimeOut,
+ proxy = Proxy}} = State,
Data) ->
?hcrd("handle keep_alive", [{profile, ProfileName},
@@ -1322,14 +1343,15 @@ handle_keep_alive_queue(#state{status = keep_alive,
State#state{keep_alive = KeepAlive}, Data);
false ->
?hcrv("next request", [{request, NextRequest}]),
- #request{address = Address} = NextRequest,
+ #request{address = Addr} = NextRequest,
+ Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Session, NextRequest) of
ok ->
receive_response(NextRequest,
Session, <<>>,
State#state{keep_alive = KeepAlive});
{error, Reason} ->
- {reply, {keep_alive_failed, Reason}, State}
+ {stop, {shutdown, {keepalive_failed, Reason}}, State}
end
end
end.
@@ -1344,7 +1366,7 @@ handle_empty_queue(Session, ProfileName, TimeOut, State) ->
%% closed by the server, the client may want to close it.
NewState = activate_queue_timeout(TimeOut, State),
update_session(ProfileName, Session, #session.queue_length, 0),
- %% Note mfa will be initilized when a new request
+ %% Note mfa will be initialized when a new request
%% arrives.
{noreply,
NewState#state{request = undefined,
@@ -1387,6 +1409,8 @@ case_insensitive_header(Str) ->
activate_once(#session{socket = Socket, socket_type = SocketType}) ->
http_transport:setopts(SocketType, Socket, [{active, once}]).
+close_socket(#session{socket = {remote_close,_}}) ->
+ ok;
close_socket(#session{socket = Socket, socket_type = SocketType}) ->
http_transport:close(SocketType, Socket).
@@ -1630,21 +1654,21 @@ start_stream({_Version, _Code, _ReasonPhrase}, _Headers,
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, Headers,
#request{stream = self} = Request)
- when (Code =:= 200) orelse (Code =:= 206) ->
+ when ?IS_STREAMED(Code) ->
?hcrt("start stream - self", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, ignore),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, Headers,
#request{stream = {self, once}} = Request)
- when (Code =:= 200) orelse (Code =:= 206) ->
+ when ?IS_STREAMED(Code) ->
?hcrt("start stream - self:once", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, self()),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, _Headers,
#request{stream = Filename} = Request)
- when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
+ when ?IS_STREAMED(Code) andalso is_list(Filename) ->
?hcrt("start stream", [{code, Code}, {filename, Filename}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
@@ -1696,13 +1720,15 @@ end_stream(SL, R) ->
next_body_chunk(#state{request = #request{stream = {self, once}},
once = once,
- session = Session} = State) ->
+ session = Session} = State,
+ Code) when ?IS_STREAMED(Code) ->
activate_once(Session),
State#state{once = inactive};
next_body_chunk(#state{request = #request{stream = {self, once}},
- once = inactive} = State) ->
+ once = inactive} = State,
+ Code) when ?IS_STREAMED(Code) ->
State; %% Wait for user to call stream_next
-next_body_chunk(#state{session = Session} = State) ->
+next_body_chunk(#state{session = Session} = State, _) ->
activate_once(Session),
State.
@@ -1801,13 +1827,15 @@ host_header(_, URI) ->
tls_upgrade(#state{status =
{ssl_tunnel,
#request{settings =
- #http_options{ssl = {_, TLSOptions} = SocketType}} = Request},
+ #http_options{ssl = {_, TLSOptions0} = SocketType},
+ address = {Host, _} = Address} = Request},
session = #session{socket = TCPSocket} = Session0,
options = Options} = State) ->
+ TLSOptions = maybe_add_sni(Host, TLSOptions0),
+
case ssl:connect(TCPSocket, TLSOptions) of
{ok, TLSSocket} ->
- Address = Request#request.address,
ClientClose = httpc_request:is_client_closing(Request#request.headers),
SessionType = httpc_manager:session_type(Options),
Session = Session0#session{
@@ -1828,10 +1856,23 @@ tls_upgrade(#state{status =
status = new
},
{noreply, activate_request_timeout(NewState)};
- {error, _Reason} ->
+ {error, Reason} ->
+ Error = httpc_response:error(Request, {failed_connect,
+ [{to_address, Address},
+ {tls, TLSOptions, Reason}]}),
+ maybe_send_answer(Request, Error, State),
{stop, normal, State#state{request = Request}}
end.
+maybe_add_sni(Host, Options) ->
+ case http_util:is_hostname(Host) andalso
+ not lists:keymember(server_name_indication, 1, Options) of
+ true ->
+ [{server_name_indication, Host} | Options];
+ false ->
+ Options
+ end.
+
%% ---------------------------------------------------------------------
%% Session wrappers
%% ---------------------------------------------------------------------
@@ -1850,6 +1891,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
Session2 = erlang:setelement(Pos, Session, Value),
insert_session(Session2, ProfileName);
T:E ->
+ Stacktrace = erlang:get_stacktrace(),
error_logger:error_msg("Failed updating session: "
"~n ProfileName: ~p"
"~n SessionId: ~p"
@@ -1873,7 +1915,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
{value, Value},
{etype, T},
{error, E},
- {stacktrace, erlang:get_stacktrace()}]})
+ {stacktrace, Stacktrace}]})
end.
diff --git a/lib/inets/src/http_client/httpc_handler_sup.erl b/lib/inets/src/http_client/httpc_handler_sup.erl
index f7a0b014b3..403512fc25 100644
--- a/lib/inets/src/http_client/httpc_handler_sup.erl
+++ b/lib/inets/src/http_client/httpc_handler_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl
index add5d11dfa..bb8c0e20fa 100644
--- a/lib/inets/src/http_client/httpc_internal.hrl
+++ b/lib/inets/src/http_client/httpc_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 48a9c32454..c7974836c2 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_client/httpc_profile_sup.erl b/lib/inets/src/http_client/httpc_profile_sup.erl
index 29f86aa373..b83aeaa4e0 100644
--- a/lib/inets/src/http_client/httpc_profile_sup.erl
+++ b/lib/inets/src/http_client/httpc_profile_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl
index 879053f0f2..af4c3f75f2 100644
--- a/lib/inets/src/http_client/httpc_request.erl
+++ b/lib/inets/src/http_client/httpc_request.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -186,7 +187,8 @@ is_client_closing(Headers) ->
%%% Internal functions
%%%========================================================================
post_data(Method, Headers, {ContentType, Body}, HeadersAsIs)
- when (Method =:= post) orelse (Method =:= put) ->
+ when (Method =:= post) orelse (Method =:= put)
+ orelse (Method =:= patch) ->
NewBody = case Headers#http_request_h.expect of
"100-continue" ->
"";
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index 9107dfbf05..4bf2ba2b9b 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -327,7 +328,7 @@ status_service_unavailable(Response = {_, Headers, _}, Request) ->
undefined ->
status_server_error_50x(Response, Request);
Time when (length(Time) < 3) -> % Wait only 99 s or less
- NewTime = list_to_integer(Time) * 100, % time in ms
+ NewTime = list_to_integer(Time) * 1000, % time in ms
{_, Data} = format_response(Response),
{retry, {NewTime, Request}, Data};
_ ->
diff --git a/lib/inets/src/http_client/httpc_sup.erl b/lib/inets/src/http_client/httpc_sup.erl
index 152a57d32d..2b2ee0f34a 100644
--- a/lib/inets/src/http_client/httpc_sup.erl
+++ b/lib/inets/src/http_client/httpc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile
index 51167b34fa..4a4eef9f24 100644
--- a/lib/inets/src/http_lib/Makefile
+++ b/lib/inets/src/http_lib/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/src/http_lib/http_chunk.erl b/lib/inets/src/http_lib/http_chunk.erl
index d15d7ba49a..7325f24809 100644
--- a/lib/inets/src/http_lib/http_chunk.erl
+++ b/lib/inets/src/http_lib/http_chunk.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,7 +25,7 @@
-include("http_internal.hrl").
%% API
--export([decode/3, encode/1, encode_last/0, handle_headers/2]).
+-export([decode/3, encode/1, encode_last/0, encode_last/1, handle_headers/2]).
%% Callback API - used for example if the chunkedbody is received a
%% little at a time on a socket.
-export([decode_size/1, ignore_extensions/1, decode_data/1, decode_trailer/1]).
@@ -56,7 +57,7 @@
%%-------------------------------------------------------------------------
decode(ChunkedBody, MaxBodySize, MaxHeaderSize) ->
%% Note decode_size will call decode_data.
- decode_size([ChunkedBody, <<>>, [],
+ decode_size([ChunkedBody, <<>>, [], 0,
{MaxBodySize, <<>>, 0, MaxHeaderSize}]).
%%-------------------------------------------------------------------------
@@ -84,6 +85,11 @@ encode(Chunk) when is_list(Chunk)->
encode_last() ->
<<$0, ?CR, ?LF, ?CR, ?LF >>.
+encode_last([]) ->
+ encode_last();
+encode_last(Trailers0) ->
+ Trailers = list_to_binary(encode_trailers(Trailers0)),
+ <<$0, ?CR, ?LF, Trailers/binary>>.
%%-------------------------------------------------------------------------
%% handle_headers(HeaderRecord, ChunkedHeaders) -> NewHeaderRecord
@@ -119,65 +125,80 @@ handle_headers(ResponseHeaderRecord = #http_response_h{}, ChunkedHeaders) ->
%% Functions that may be returned during the decoding process
%% if the input data is incompleate.
-decode_size([Bin, Rest, HexList, Info]) ->
- decode_size(<<Rest/binary, Bin/binary>>, HexList, Info).
+decode_size([Bin, Rest, HexList, AccSize, Info]) ->
+ decode_size(<<Rest/binary, Bin/binary>>, HexList, AccSize, Info).
-ignore_extensions([Bin, Rest, NextFunction]) ->
- ignore_extensions(<<Rest/binary, Bin/binary>>, NextFunction).
+ignore_extensions([Bin, Rest, RemainingSize, TotalMaxHeaderSize, NextFunction]) ->
+ ignore_extensions(<<Rest/binary, Bin/binary>>, RemainingSize, TotalMaxHeaderSize, NextFunction).
decode_data([Bin, ChunkSize, TotalChunk, Info]) ->
decode_data(ChunkSize, <<TotalChunk/binary, Bin/binary>>, Info).
-decode_trailer([Bin, Rest, Header, Headers, MaxHeaderSize, Body,
- BodyLength]) ->
+decode_trailer([Bin, Rest, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]) ->
decode_trailer(<<Rest/binary, Bin/binary>>,
- Header, Headers, MaxHeaderSize, Body, BodyLength).
+ Header, Headers, Body, BodyLength, RemainingSize, TotalMaxHeaderSize).
%%%========================================================================
%%% Internal functions
%%%========================================================================
-decode_size(<<>>, HexList, Info) ->
- {?MODULE, decode_size, [<<>>, HexList, Info]};
-decode_size(Data = <<?CR, ?LF, ChunkRest/binary>>, HexList,
+decode_size(_, _, AccHeaderSize, {_,_,_, MaxHeaderSize}) when
+ AccHeaderSize > MaxHeaderSize ->
+ throw({error, {header_too_long, {max, MaxHeaderSize}}});
+
+decode_size(<<>>, HexList, AccHeaderSize, Info) ->
+ {?MODULE, decode_size, [<<>>, HexList, AccHeaderSize, Info]};
+decode_size(Data = <<?CR, ?LF, ChunkRest/binary>>, HexList, AccHeaderSize,
{MaxBodySize, Body,
AccLength,
MaxHeaderSize}) ->
- ChunkSize = http_util:hexlist_to_integer(lists:reverse(HexList)),
- case ChunkSize of
+ try http_util:hexlist_to_integer(lists:reverse(string:strip(HexList, left))) of
0 -> % Last chunk, there was no data
- ignore_extensions(Data, {?MODULE, decode_trailer,
- [<<>>, [],[], MaxHeaderSize,
- Body,
- integer_to_list(AccLength)]});
- _ ->
+ ignore_extensions(Data, remaing_size(MaxHeaderSize, AccHeaderSize), MaxHeaderSize,
+ {?MODULE, decode_trailer,
+ [<<>>, [],[],
+ Body,
+ integer_to_list(AccLength)]});
+ ChunkSize ->
%% Note decode_data may call decode_size again if there
%% is more than one chunk, hence here is where the last parameter
%% to this function comes in.
decode_data(ChunkSize, ChunkRest, {MaxBodySize, Body,
- ChunkSize + AccLength ,
+ ChunkSize + AccLength,
MaxHeaderSize})
+ catch
+ _:_ ->
+ throw({error, {chunk_size, lists:reverse(HexList)}})
end;
-decode_size(<<";", Rest/binary>>, HexList, Info) ->
+decode_size(<<";", Rest/binary>>, HexList, AccHeaderSize, {_,_,_, MaxHeaderSize} = Info) ->
%% Note ignore_extensions will call decode_size/1 again when
%% it ignored all extensions.
- ignore_extensions(Rest, {?MODULE, decode_size, [<<>>, HexList, Info]});
-decode_size(<<?CR>> = Data, HexList, Info) ->
- {?MODULE, decode_size, [Data, HexList, Info]};
-decode_size(<<Octet, Rest/binary>>, HexList, Info) ->
- decode_size(Rest, [Octet | HexList], Info).
+ ignore_extensions(Rest, remaing_size(MaxHeaderSize, AccHeaderSize), MaxHeaderSize,
+ {?MODULE, decode_size, [<<>>, HexList, AccHeaderSize, Info]});
+decode_size(<<?CR>> = Data, HexList, AccHeaderSize, Info) ->
+ {?MODULE, decode_size, [Data, HexList, AccHeaderSize, Info]};
+decode_size(<<Octet, Rest/binary>>, HexList, AccHeaderSize, Info) ->
+ decode_size(Rest, [Octet | HexList], AccHeaderSize + 1, Info).
%% "All applications MUST ignore chunk-extension extensions they
%% do not understand.", see RFC 2616 Section 3.6.1 We don't
%% understand any extension...
-ignore_extensions(<<>>, NextFunction) ->
- {?MODULE, ignore_extensions, [<<>>, NextFunction]};
-ignore_extensions(Data = <<?CR, ?LF, _ChunkRest/binary>>,
+ignore_extensions(_, 0, TotalMaxHeaderSize, _) ->
+ throw({error, {header_too_long, {max, TotalMaxHeaderSize}}});
+ignore_extensions(<<>>, RemainingSize, TotalMaxHeaderSize, NextFunction) ->
+ {?MODULE, ignore_extensions, [<<>>, RemainingSize, TotalMaxHeaderSize, NextFunction]};
+ignore_extensions(Data = <<?CR, ?LF, _ChunkRest/binary>>, RemainingSize, TotalMaxHeaderSize,
{Module, Function, Args}) ->
- Module:Function([Data | Args]);
-ignore_extensions(<<?CR>> = Data, NextFunction) ->
- {?MODULE, ignore_extensions, [Data, NextFunction]};
-ignore_extensions(<<_Octet, Rest/binary>>, NextFunction) ->
- ignore_extensions(Rest, NextFunction).
+ case Function of
+ decode_trailer ->
+ Module:Function([Data | Args ++ [RemainingSize, TotalMaxHeaderSize]]);
+ _ ->
+ Module:Function([Data | Args])
+ end;
+ignore_extensions(<<?CR>> = Data, RemainingSize, TotalMaxHeaderSize, NextFunction) ->
+ {?MODULE, ignore_extensions, [Data, RemainingSize, TotalMaxHeaderSize, NextFunction]};
+ignore_extensions(<<_Octet, Rest/binary>>, RemainingSize, TotalMaxHeaderSize, NextFunction) ->
+ ignore_extensions(Rest, remaing_size(RemainingSize, 1), TotalMaxHeaderSize, NextFunction).
decode_data(ChunkSize, TotalChunk,
Info = {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize})
@@ -189,83 +210,89 @@ decode_data(ChunkSize, TotalChunk,
%% once it ignored all extensions.
{?MODULE, ignore_extensions,
[<<>>,
- {?MODULE, decode_trailer, [<<>>, [],[], MaxHeaderSize,
+ {?MODULE, decode_trailer, [<<>>, [],[],
<<BodySoFar/binary, Data/binary>>,
integer_to_list(AccLength)]}]};
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ";", Rest/binary>> ->
%% Note ignore_extensions will call decode_trailer/1
%% once it ignored all extensions.
- ignore_extensions(Rest, {?MODULE, decode_trailer,
- [<<>>, [],[], MaxHeaderSize,
+ ignore_extensions(Rest, MaxHeaderSize, MaxHeaderSize,
+ {?MODULE, decode_trailer,
+ [<<>>, [],[],
<<BodySoFar/binary, Data/binary>>,
integer_to_list(AccLength)]});
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ?CR, ?LF>> ->
- {?MODULE, decode_trailer, [<<?CR, ?LF>>, [],[], MaxHeaderSize,
+ {?MODULE, decode_trailer, [<<?CR, ?LF>>, [],[],
<<BodySoFar/binary, Data/binary>>,
- integer_to_list(AccLength)]};
+ integer_to_list(AccLength), MaxHeaderSize, MaxHeaderSize]};
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ?CR, ?LF, Rest/binary>> ->
- decode_trailer(<<?CR, ?LF, Rest/binary>>, [],[], MaxHeaderSize,
+ decode_trailer(<<?CR, ?LF, Rest/binary>>, [],[],
<<BodySoFar/binary, Data/binary>>,
- integer_to_list(AccLength));
- %% There are more chunks, so here we go agin...
+ integer_to_list(AccLength), MaxHeaderSize, MaxHeaderSize);
+ %% There are more chunks, so here we go again...
<<Data:ChunkSize/binary, ?CR, ?LF>> ->
NewBody = <<BodySoFar/binary, Data/binary>>,
- {?MODULE, decode_size, [<<>>, [], {MaxBodySize, NewBody, AccLength, MaxHeaderSize}]};
+ {?MODULE, decode_size, [<<>>, [], 0, {MaxBodySize, NewBody, AccLength, MaxHeaderSize}]};
<<Data:ChunkSize/binary, ?CR, ?LF, Rest/binary>>
when (AccLength < MaxBodySize) or (MaxBodySize == nolimit) ->
- decode_size(Rest, [],
+ decode_size(Rest, [], 0,
{MaxBodySize, <<BodySoFar/binary, Data/binary>>,
AccLength, MaxHeaderSize});
<<_:ChunkSize/binary, ?CR, ?LF, _/binary>> ->
- throw({error, body_too_big});
+ throw({error, {body_too_big, {max, MaxBodySize}}});
_ ->
{?MODULE, decode_data, [ChunkSize, TotalChunk, Info]}
end;
decode_data(ChunkSize, TotalChunk, Info) ->
{?MODULE, decode_data, [ChunkSize, TotalChunk, Info]}.
-decode_trailer(<<>>, Header, Headers, MaxHeaderSize, Body, BodyLength) ->
- {?MODULE, decode_trailer, [<<>>, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-
+decode_trailer(_,_,_,_,_, 0, TotalMaxHeaderSize) ->
+ throw({error, {header_too_long, {max, TotalMaxHeaderSize}}});
+decode_trailer(<<>>, Header, Headers, Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [<<>>, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
%% Note: If Bin is not empty it is part of a pipelined request/response.
-decode_trailer(<<?CR,?LF,?CR,?LF, Bin/binary>>, [], [], _, Body, BodyLength) ->
+decode_trailer(<<?CR,?LF,?CR,?LF, Bin/binary>>, [], [], Body, BodyLength, _, _) ->
{ok, {["content-length:" ++ BodyLength], <<Body/binary, Bin/binary>>}};
decode_trailer(<<?CR,?LF,?CR,?LF, Bin/binary>>,
- Header, Headers, MaxHeaderSize, Body, BodyLength) ->
+ Header, Headers, Body, BodyLength, _, _) ->
NewHeaders = case Header of
[] ->
Headers;
_ ->
[lists:reverse(Header) | Headers]
end,
- Length = length(NewHeaders),
- case Length > MaxHeaderSize of
- true ->
- throw({error, {header_too_long, MaxHeaderSize,
- MaxHeaderSize-Length}});
- false ->
- {ok, {["content-length:" ++ BodyLength | NewHeaders],
- <<Body/binary, Bin/binary>>}}
- end;
-decode_trailer(<<?CR,?LF,?CR>> = Data, Header, Headers, MaxHeaderSize,
- Body, BodyLength) ->
- {?MODULE, decode_trailer, [Data, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-decode_trailer(<<?CR,?LF>> = Data, Header, Headers, MaxHeaderSize,
- Body, BodyLength) ->
- {?MODULE, decode_trailer, [Data, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-decode_trailer(<<?CR>> = Data, Header, Headers, MaxHeaderSize,
- Body, BodyLength) ->
- {?MODULE, decode_trailer, [Data, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-decode_trailer(<<?CR, ?LF, Rest/binary>>, Header, Headers,
- MaxHeaderSize, Body, BodyLength) ->
+ {ok, {["content-length:" ++ BodyLength | NewHeaders],
+ <<Body/binary, Bin/binary>>}};
+decode_trailer(<<?CR,?LF,?CR>> = Data, Header, Headers,
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [Data, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
+decode_trailer(<<?CR,?LF>> = Data, Header, Headers,
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [Data, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
+decode_trailer(<<?CR>> = Data, Header, Headers,
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [Data, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
+decode_trailer(<<?CR, ?LF, Rest/binary>>, Header, Headers, Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
decode_trailer(Rest, [], [lists:reverse(Header) | Headers],
- MaxHeaderSize, Body, BodyLength);
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize);
+decode_trailer(<<Octet, Rest/binary>>, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ decode_trailer(Rest, [Octet | Header], Headers,
+ Body, BodyLength, remaing_size(RemainingSize, 1), TotalMaxHeaderSize).
+
+remaing_size(nolimit, _) ->
+ nolimit;
+remaing_size(Total, Consumed) ->
+ Total - Consumed.
-decode_trailer(<<Octet, Rest/binary>>, Header, Headers, MaxHeaderSize, Body,
- BodyLength) ->
- decode_trailer(Rest, [Octet | Header], Headers, MaxHeaderSize,
- Body, BodyLength).
+encode_trailers(Trailers) ->
+ encode_trailers(Trailers, "").
+
+encode_trailers([], Acc) ->
+ Acc ++ ?CRLF ++ ?CRLF;
+encode_trailers([{Header, Value} | Rest], Acc) ->
+ encode_trailers(Rest, Header ++ ":" ++ Value ++ ?CRLF ++ Acc).
diff --git a/lib/inets/src/http_lib/http_internal.hrl b/lib/inets/src/http_lib/http_internal.hrl
index 54425740b5..ae92b5df8f 100644
--- a/lib/inets/src/http_lib/http_internal.hrl
+++ b/lib/inets/src/http_lib/http_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_lib/http_request.erl b/lib/inets/src/http_lib/http_request.erl
index a0833ddf01..c77b616f0d 100644
--- a/lib/inets/src/http_lib/http_request.erl
+++ b/lib/inets/src/http_lib/http_request.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_lib/http_response.erl b/lib/inets/src/http_lib/http_response.erl
index b1e7f1e647..42e5dd263d 100644
--- a/lib/inets/src/http_lib/http_response.erl
+++ b/lib/inets/src/http_lib/http_response.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -30,16 +31,11 @@
%% Value - string()
%%
%% Description: Creates a http_response_h-record used internally to
-%% handle http-headers.
+%% handle http-headers, assumes reversed list of headers
+%% to unfold multiline headers with obs-folds
%%-------------------------------------------------------------------------
-headers([], Headers) ->
- Headers;
-
-headers([Header | Tail], Headers) ->
- {Key, [$: | Value]} =
- lists:splitwith(fun($:) -> false; (_) -> true end, Header),
- headers(Tail, headers(http_util:to_lower(string:strip(Key)),
- string:strip(Value), Headers)).
+headers(RevLines, Headers) ->
+ fill_headers(RevLines, [], Headers).
%%-------------------------------------------------------------------------
%% headers(#http_response_h{}) -> HeaderList
@@ -67,6 +63,25 @@ header_list(Headers) ->
%%%========================================================================
%%% Internal functions
%%%========================================================================
+fill_headers([], _, Headers) ->
+ Headers;
+fill_headers([[]], _, Headers) ->
+ Headers;
+fill_headers([[Ch|HeaderFold]|Tail], Folded, Headers)
+ when Ch == $\t; Ch == $\s ->
+ fill_headers(Tail, [HeaderFold|Folded], Headers);
+fill_headers([Header | Tail], Folded, Headers) ->
+ Unfolded = unfold([Header|Folded]),
+ {Key, [$: | Value]} =
+ lists:splitwith(fun($:) -> false; (_) -> true end, Unfolded),
+ fill_headers(Tail, [], headers(http_util:to_lower(string:strip(Key)),
+ string:strip(Value), Headers)).
+
+unfold([L]) ->
+ L;
+unfold(Folded) ->
+ string:join(Folded, " ").
+
headers("cache-control", Value, Headers) ->
Headers#http_response_h{'cache-control'= Value};
headers("connection", Value, Headers) ->
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index 7e679531cf..ab6afe9c6c 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,12 +40,6 @@
-include_lib("inets/src/inets_app/inets_internal.hrl").
-include("http_internal.hrl").
--define(SERVICE, httpl).
--define(hlri(Label, Content), ?report_important(Label, ?SERVICE, Content)).
--define(hlrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)).
--define(hlrd(Label, Content), ?report_debug(Label, ?SERVICE, Content)).
--define(hlrt(Label, Content), ?report_trace(Label, ?SERVICE, Content)).
-
%%%=========================================================================
%%% Internal application API
@@ -54,38 +49,27 @@
%% start(SocketType) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
%%
-%% Description: Makes sure inet_db or ssl is started.
+%% Description: Makes sure ssl is started.
%%-------------------------------------------------------------------------
start(ip_comm) ->
- do_start_ip_comm();
-
-%% This is just for backward compatibillity
+ ok;
+start({ip_comm, _}) ->
+ ok;
start({ssl, _}) ->
do_start_ssl();
start({essl, _}) ->
do_start_ssl().
-
-do_start_ip_comm() ->
- case inet_db:start() of
- {ok, _} ->
- ok;
- {error, {already_started, _}} ->
- ok;
- Error ->
- Error
- end.
-
do_start_ssl() ->
- case ssl:start() of
- ok ->
- ok;
- {error, {already_started,_}} ->
- ok;
- Error ->
- Error
+ try lists:foreach(fun(App) ->
+ ok = application:ensure_started(App)
+ end,
+ [crypto, asn1, public_key, ssl])
+ catch
+ _:Reason ->
+ {error, Reason}
end.
-
+
%%-------------------------------------------------------------------------
%% connect(SocketType, Address, Options, Timeout) ->
@@ -102,12 +86,8 @@ do_start_ssl() ->
connect(SocketType, Address, Opts) ->
connect(SocketType, Address, Opts, infinity).
-
-connect(ip_comm = _SocketType, {Host, Port}, Opts0, Timeout)
- when is_list(Opts0) ->
- Opts = [binary, {packet, 0}, {active, false}, {reuseaddr, true} | Opts0],
- ?hlrt("connect using gen_tcp",
- [{host, Host}, {port, Port}, {opts, Opts}, {timeout, Timeout}]),
+connect(ip_comm, {Host, Port}, Opts0, Timeout) ->
+ Opts = [binary, {packet, 0}, {active, false}, {reuseaddr, true} | Opts0 ],
try gen_tcp:connect(Host, Port, Opts, Timeout) of
{ok, _} = OK ->
OK;
@@ -126,11 +106,6 @@ connect({ssl, SslConfig}, Address, Opts, Timeout) ->
connect({essl, SslConfig}, {Host, Port}, Opts0, Timeout) ->
Opts = [binary, {active, false}, {ssl_imp, new} | Opts0] ++ SslConfig,
- ?hlrt("connect using essl",
- [{host, Host},
- {port, Port},
- {ssl_config, SslConfig},
- {timeout, Timeout}]),
case (catch ssl:connect(Host, Port, Opts, Timeout)) of
{'EXIT', Reason} ->
{error, {eoptions, Reason}};
@@ -155,29 +130,23 @@ connect({essl, SslConfig}, {Host, Port}, Opts0, Timeout) ->
%% reason for this to enable a HTTP-server not running as root to use
%% port 80.
%%-------------------------------------------------------------------------
-listen(ip_comm = _SocketType, Addr, Port, Fd, IpFamily) ->
- listen_ip_comm(Addr, Port, Fd, IpFamily);
-
+listen(ip_comm, Addr, Port, Fd, IpFamily) ->
+ listen_ip_comm(Addr, Port, [], Fd, IpFamily);
+
+listen({ip_comm, SockOpts}, Addr, Port, Fd, IpFamily) ->
+ listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily);
+
listen({essl, SSLConfig}, Addr, Port, Fd, IpFamily) ->
listen_ssl(Addr, Port, Fd, SSLConfig, IpFamily, []).
-listen(ip_comm = _SocketType, Addr, Port, IpFamily) ->
- listen_ip_comm(Addr, Port, undefined, IpFamily);
+listen(ip_comm, Addr, Port, IpFamily) ->
+ listen_ip_comm(Addr, Port, [], undefined, IpFamily);
%% Wrapper for backaward compatibillity
listen({ssl, SSLConfig}, Addr, Port, IpFamily) ->
- ?hlrt("listen (wrapper)",
- [{addr, Addr},
- {port, Port},
- {ssl_config, SSLConfig}]),
listen({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Addr, Port, IpFamily);
-
listen({essl, SSLConfig}, Addr, Port, IpFamily) ->
- ?hlrt("listen (essl)",
- [{addr, Addr},
- {port, Port},
- {ssl_config, SSLConfig}]),
{SSLConfig2, ExtraOpts} = case proplists:get_value(log_alert, SSLConfig, undefined) of
undefined ->
{SSLConfig, []};
@@ -186,89 +155,36 @@ listen({essl, SSLConfig}, Addr, Port, IpFamily) ->
end,
listen_ssl(Addr, Port, undefined, SSLConfig2, IpFamily, ExtraOpts).
-listen_ip_comm(Addr, Port, Fd, IpFamily) ->
- case (catch do_listen_ip_comm(Addr, Port, Fd, IpFamily)) of
+listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily) ->
+ case (catch do_listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily)) of
{'EXIT', Reason} ->
{error, {exit, Reason}};
Else ->
Else
end.
-do_listen_ip_comm(Addr, Port, Fd, IpFamily) ->
- {NewPort, Opts} = get_socket_info(Addr, Port, Fd),
- case IpFamily of
- inet6fb4 ->
- Opts2 = [inet6 | Opts],
- ?hlrt("try ipv6 listen", [{port, NewPort}, {opts, Opts2}]),
- case (catch gen_tcp:listen(NewPort, Opts2)) of
- {error, Reason} when ((Reason =:= nxdomain) orelse
- (Reason =:= eafnosupport)) ->
- Opts3 = [inet | Opts],
- ?hlrt("ipv6 listen failed - try ipv4 instead",
- [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
- gen_tcp:listen(NewPort, Opts3);
-
- %% This is when a given hostname has resolved to a
- %% IPv4-address. The inet6-option together with a
- %% {ip, IPv4} option results in badarg
- {'EXIT', Reason} ->
- Opts3 = [inet | Opts],
- ?hlrt("ipv6 listen exit - try ipv4 instead",
- [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
- gen_tcp:listen(NewPort, Opts3);
-
- Other ->
- ?hlrt("ipv6 listen done", [{other, Other}]),
- Other
- end;
- _ ->
- Opts2 = [IpFamily | Opts],
- ?hlrt("listen", [{port, NewPort}, {opts, Opts2}]),
- gen_tcp:listen(NewPort, Opts2)
- end.
+do_listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily) ->
+ Backlog = proplists:get_value(backlog, SockOpts, 128),
+ {NewPort, Opts} = get_socket_info(Addr, Port, Fd,
+ [{backlog, Backlog}, {reuseaddr, true} | SockOpts]),
+ Opts2 = [IpFamily | Opts],
+ gen_tcp:listen(NewPort, Opts2).
listen_ssl(Addr, Port, Fd, Opts0, IpFamily, ExtraOpts) ->
- {NewPort, SockOpt} = get_socket_info(Addr, Port, Fd),
+ Backlog = proplists:get_value(backlog, Opts0, 128),
+ {NewPort, SockOpt} = get_socket_info(Addr, Port, Fd,
+ [{backlog, Backlog}, {reuseaddr, true}]),
Opts = SockOpt ++ Opts0,
- case IpFamily of
- inet6fb4 ->
- Opts2 = [inet6 | Opts] ++ ExtraOpts,
- ?hlrt("try ipv6 listen", [{opts, Opts2}]),
- case (catch ssl:listen(Port, Opts2)) of
- {error, Reason} when ((Reason =:= nxdomain) orelse
- (Reason =:= eafnosupport)) ->
- Opts3 = [inet | Opts] ++ ExtraOpts,
- ?hlrt("ipv6 listen failed - try ipv4 instead",
- [{reason, Reason}, {opts, Opts3}]),
- ssl:listen(NewPort, Opts3);
-
- {'EXIT', Reason} ->
- Opts3 = [inet | Opts] ++ ExtraOpts,
- ?hlrt("ipv6 listen exit - try ipv4 instead",
- [{reason, Reason}, {opts, Opts3}]),
- ssl:listen(NewPort, Opts3);
-
- Other ->
- ?hlrt("ipv6 listen done", [{other, Other}]),
- Other
- end;
-
- _ ->
- Opts2 = [IpFamily | Opts],
- ?hlrt("listen", [{opts, Opts2}]),
- ssl:listen(NewPort, Opts2 ++ ExtraOpts)
- end.
+ Opts2 = [IpFamily | Opts],
+ ssl:listen(NewPort, Opts2 ++ ExtraOpts).
-
-
-get_socket_info(Addr, Port, Fd) ->
- BaseOpts = [{backlog, 128}, {reuseaddr, true}],
+get_socket_info(Addr, Port, Fd, BaseOpts) ->
%% The presence of a file descriptor takes precedence
case Fd of
undefined ->
{Port, sock_opts(Addr, BaseOpts)};
Fd ->
- {0, sock_opts(Addr, [{fd, Fd} | BaseOpts])}
+ {0, sock_opts([{fd, Fd} | BaseOpts])}
end.
%%-------------------------------------------------------------------------
@@ -287,6 +203,8 @@ accept(SocketType, ListenSocket) ->
accept(ip_comm, ListenSocket, Timeout) ->
gen_tcp:accept(ListenSocket, Timeout);
+accept({ip_comm, _}, ListenSocket, Timeout) ->
+ gen_tcp:accept(ListenSocket, Timeout);
%% Wrapper for backaward compatibillity
accept({ssl, SSLConfig}, ListenSocket, Timeout) ->
@@ -306,6 +224,8 @@ accept({essl, _SSLConfig}, ListenSocket, Timeout) ->
%%-------------------------------------------------------------------------
controlling_process(ip_comm, Socket, NewOwner) ->
gen_tcp:controlling_process(Socket, NewOwner);
+controlling_process({ip_comm, _}, Socket, NewOwner) ->
+ gen_tcp:controlling_process(Socket, NewOwner);
%% Wrapper for backaward compatibillity
controlling_process({ssl, SSLConfig}, Socket, NewOwner) ->
@@ -324,7 +244,8 @@ controlling_process({essl, _}, Socket, NewOwner) ->
%% gen_tcp or ssl.
%%-------------------------------------------------------------------------
setopts(ip_comm, Socket, Options) ->
- ?hlrt("ip_comm setopts", [{socket, Socket}, {options, Options}]),
+ inet:setopts(Socket, Options);
+setopts({ip_comm, _}, Socket, Options) ->
inet:setopts(Socket, Options);
%% Wrapper for backaward compatibillity
@@ -332,10 +253,7 @@ setopts({ssl, SSLConfig}, Socket, Options) ->
setopts({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Options);
setopts({essl, _}, Socket, Options) ->
- ?hlrt("[e]ssl setopts", [{socket, Socket}, {options, Options}]),
- Reason = (catch ssl:setopts(Socket, Options)),
- ?hlrt("[e]ssl setopts result", [{reason, Reason}]),
- Reason.
+ (catch ssl:setopts(Socket, Options)).
%%-------------------------------------------------------------------------
@@ -349,8 +267,10 @@ getopts(SocketType, Socket) ->
Opts = [packet, packet_size, recbuf, sndbuf, priority, tos, send_timeout],
getopts(SocketType, Socket, Opts).
+getopts({ip_comm, _}, Socket, Options) ->
+ getopts(ip_comm, Socket, Options);
+
getopts(ip_comm, Socket, Options) ->
- ?hlrt("ip_comm getopts", [{socket, Socket}, {options, Options}]),
case inet:getopts(Socket, Options) of
{ok, SocketOpts} ->
SocketOpts;
@@ -363,7 +283,6 @@ getopts({ssl, SSLConfig}, Socket, Options) ->
getopts({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Options);
getopts({essl, _}, Socket, Options) ->
- ?hlrt("essl getopts", [{socket, Socket}, {options, Options}]),
getopts_ssl(Socket, Options).
getopts_ssl(Socket, Options) ->
@@ -383,7 +302,6 @@ getopts_ssl(Socket, Options) ->
%% Description: Gets the socket stats values for the socket
%%-------------------------------------------------------------------------
getstat(ip_comm = _SocketType, Socket) ->
- ?hlrt("ip_comm getstat", [{socket, Socket}]),
case inet:getstat(Socket) of
{ok, Stats} ->
Stats;
@@ -408,6 +326,8 @@ getstat({essl, _} = _SocketType, _Socket) ->
%%-------------------------------------------------------------------------
send(ip_comm, Socket, Message) ->
gen_tcp:send(Socket, Message);
+send({ip_comm, _}, Socket, Message) ->
+ gen_tcp:send(Socket, Message);
%% Wrapper for backaward compatibillity
send({ssl, SSLConfig}, Socket, Message) ->
@@ -416,7 +336,6 @@ send({ssl, SSLConfig}, Socket, Message) ->
send({essl, _}, Socket, Message) ->
ssl:send(Socket, Message).
-
%%-------------------------------------------------------------------------
%% close(SocketType, Socket) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -426,6 +345,8 @@ send({essl, _}, Socket, Message) ->
%%-------------------------------------------------------------------------
close(ip_comm, Socket) ->
gen_tcp:close(Socket);
+close({ip_comm, []}, Socket) ->
+ gen_tcp:close(Socket);
%% Wrapper for backaward compatibillity
close({ssl, SSLConfig}, Socket) ->
@@ -447,6 +368,8 @@ close({essl, _}, Socket) ->
%%-------------------------------------------------------------------------
peername(ip_comm, Socket) ->
do_peername(inet:peername(Socket));
+peername({ip_comm, _}, Socket) ->
+ do_peername(inet:peername(Socket));
%% Wrapper for backaward compatibillity
peername({ssl, SSLConfig}, Socket) ->
@@ -479,7 +402,8 @@ do_peername({error, _}) ->
%%-------------------------------------------------------------------------
sockname(ip_comm, Socket) ->
do_sockname(inet:sockname(Socket));
-
+sockname({ip_comm, _}, Socket) ->
+ do_sockname(inet:sockname(Socket));
%% Wrapper for backaward compatibillity
sockname({ssl, SSLConfig}, Socket) ->
sockname({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket);
@@ -554,28 +478,13 @@ sock_opts(Opts) ->
%% -- negotiate --
negotiate(ip_comm,_,_) ->
- ?hlrt("negotiate(ip_comm)", []),
+ ok;
+negotiate({ip_comm, _},_,_) ->
ok;
negotiate({ssl, SSLConfig}, Socket, Timeout) ->
- ?hlrt("negotiate(ssl)", []),
negotiate({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Timeout);
negotiate({essl, _}, Socket, Timeout) ->
- ?hlrt("negotiate(essl)", []),
negotiate_ssl(Socket, Timeout).
negotiate_ssl(Socket, Timeout) ->
- ?hlrt("negotiate_ssl", [{socket, Socket}, {timeout, Timeout}]),
- case ssl:ssl_accept(Socket, Timeout) of
- ok ->
- ok;
- {error, Reason} ->
- ?hlrd("negotiate_ssl - accept failed", [{reason, Reason}]),
- %% Look for "valid" error reasons
- ValidReasons = [timeout, econnreset, esslaccept, esslerrssl],
- case lists:member(Reason, ValidReasons) of
- true ->
- {error, normal};
- false ->
- {error, Reason}
- end
- end.
+ ssl:ssl_accept(Socket, Timeout).
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index 350a4bc169..9940136f5a 100644
--- a/lib/inets/src/http_lib/http_uri.erl
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -137,16 +138,33 @@ parse_scheme(AbsURI, Opts) ->
{error, no_scheme} ->
{error, no_scheme};
{SchemeStr, Rest} ->
- Scheme = list_to_atom(http_util:to_lower(SchemeStr)),
- SchemeDefaults = which_scheme_defaults(Opts),
- case lists:keysearch(Scheme, 1, SchemeDefaults) of
- {value, {Scheme, DefaultPort}} ->
- {Scheme, DefaultPort, Rest};
- false ->
- {Scheme, no_default_port, Rest}
+ case extract_scheme(SchemeStr, Opts) of
+ {error, Error} ->
+ {error, Error};
+ {ok, Scheme} ->
+ SchemeDefaults = which_scheme_defaults(Opts),
+ case lists:keysearch(Scheme, 1, SchemeDefaults) of
+ {value, {Scheme, DefaultPort}} ->
+ {Scheme, DefaultPort, Rest};
+ false ->
+ {Scheme, no_default_port, Rest}
+ end
end
end.
+extract_scheme(Str, Opts) ->
+ case lists:keysearch(scheme_validation_fun, 1, Opts) of
+ {value, {scheme_validation_fun, Fun}} when is_function(Fun) ->
+ case Fun(Str) of
+ valid ->
+ {ok, list_to_atom(http_util:to_lower(Str))};
+ {error, Error} ->
+ {error, Error}
+ end;
+ _ ->
+ {ok, list_to_atom(http_util:to_lower(Str))}
+ end.
+
parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) ->
{Authority, PathQueryFragment} =
split_uri(URIPart, "[/?#]", {URIPart, ""}, 1, 0),
@@ -178,10 +196,10 @@ parse_host_port(_Scheme, DefaultPort, HostPort, _Opts) ->
{Host, int_port(Port)}.
split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) ->
- case inets_regexp:first_match(UriPart, SplitChar) of
- {match, Match, _} ->
- {string:substr(UriPart, 1, Match - SkipLeft),
- string:substr(UriPart, Match + SkipRight, length(UriPart))};
+ case re:run(UriPart, SplitChar, [{capture, first}]) of
+ {match, [{Match, _}]} ->
+ {string:substr(UriPart, 1, Match + 1 - SkipLeft),
+ string:substr(UriPart, Match + 1 + SkipRight, length(UriPart))};
nomatch ->
NoMatchResult
end.
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index 5b21170b78..aafa97afee 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -151,27 +152,11 @@ convert_netscapecookie_date([_D,_A,_Y, _SP,
Sec=list_to_integer([S1,S2]),
{{Year,Month,Day},{Hour,Min,Sec}}.
-hexlist_to_integer([]) ->
- empty;
-%%When the string only contains one value its eaasy done.
-%% 0-9
-hexlist_to_integer([Size]) when (Size >= 48) andalso (Size =< 57) ->
- Size - 48;
-%% A-F
-hexlist_to_integer([Size]) when (Size >= 65) andalso (Size =< 70) ->
- Size - 55;
-%% a-f
-hexlist_to_integer([Size]) when (Size >= 97) andalso (Size =< 102) ->
- Size - 87;
-hexlist_to_integer([_Size]) ->
- not_a_num;
-
-hexlist_to_integer(Size) ->
- Len = string:span(Size, "1234567890abcdefABCDEF"),
- hexlist_to_integer2(Size, 16 bsl (4 *(Len-2)),0).
+hexlist_to_integer(List) ->
+ list_to_integer(List, 16).
-integer_to_hexlist(Num)->
- integer_to_hexlist(Num, get_size(Num), []).
+integer_to_hexlist(Int) ->
+ integer_to_list(Int, 16).
convert_month("Jan") -> 1;
convert_month("Feb") -> 2;
@@ -212,51 +197,6 @@ html_encode(Chars) ->
%%%========================================================================
%%% Internal functions
%%%========================================================================
-hexlist_to_integer2([],_Pos,Sum)->
- Sum;
-hexlist_to_integer2([HexVal | HexString], Pos, Sum)
- when HexVal >= 48, HexVal =< 57 ->
- hexlist_to_integer2(HexString, Pos bsr 4, Sum + ((HexVal-48) * Pos));
-
-hexlist_to_integer2([HexVal | HexString], Pos, Sum)
- when HexVal >= 65, HexVal =<70 ->
- hexlist_to_integer2(HexString, Pos bsr 4, Sum + ((HexVal-55) * Pos));
-
-hexlist_to_integer2([HexVal | HexString], Pos, Sum)
- when HexVal>=97, HexVal=<102 ->
- hexlist_to_integer2(HexString, Pos bsr 4, Sum + ((HexVal-87) * Pos));
-
-hexlist_to_integer2(_AfterHexString, _Pos, Sum)->
- Sum.
-
-integer_to_hexlist(Num, Pot, Res) when Pot < 0 ->
- convert_to_ascii([Num | Res]);
-
-integer_to_hexlist(Num,Pot,Res) ->
- Position = (16 bsl (Pot*4)),
- PosVal = Num div Position,
- integer_to_hexlist(Num - (PosVal*Position), Pot-1, [PosVal | Res]).
-
-get_size(Num)->
- get_size(Num, 0).
-
-get_size(Num, Pot) when Num < (16 bsl(Pot *4)) ->
- Pot-1;
-
-get_size(Num, Pot) ->
- get_size(Num, Pot+1).
-
-convert_to_ascii(RevesedNum) ->
- convert_to_ascii(RevesedNum, []).
-
-convert_to_ascii([], Num)->
- Num;
-convert_to_ascii([Num | Reversed], Number)
- when (Num > -1) andalso (Num < 10) ->
- convert_to_ascii(Reversed, [Num + 48 | Number]);
-convert_to_ascii([Num | Reversed], Number)
- when (Num > 9) andalso (Num < 16) ->
- convert_to_ascii(Reversed, [Num + 55 | Number]).
char_to_html_entity(Char, Reserved) ->
case sets:is_element(Char, Reserved) of
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index 636d580e28..1c05d454a5 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -39,6 +40,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
+
+BEHAVIOUR_MODULES= \
+ httpd_custom_api
+
MODULES = \
httpd \
httpd_acceptor \
@@ -76,7 +81,6 @@ MODULES = \
mod_get \
mod_head \
mod_htaccess \
- mod_include \
mod_log \
mod_range \
mod_responsecontrol \
@@ -86,10 +90,13 @@ MODULES = \
HRL_FILES = httpd.hrl httpd_internal.hrl mod_auth.hrl
-ERL_FILES = $(MODULES:%=%.erl)
+ERL_FILES = $(MODULES:%=%.erl)\
+ $(BEHAVIOUR_MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR))
+
INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
@@ -109,11 +116,12 @@ ERL_COMPILE_FLAGS += \
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
+$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES)
debug opt: $(TARGET_FILES)
clean:
- rm -f $(TARGET_FILES)
+ rm -f $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES)
rm -f core
docs:
@@ -129,7 +137,7 @@ release_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)/src/http_server"
$(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/http_server"
$(INSTALL_DIR) "$(RELSYSDIR)/ebin"
- $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
+ $(INSTALL_DATA) $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES) "$(RELSYSDIR)/ebin"
release_docs_spec:
diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl
index e8148ea362..e6377b4882 100644
--- a/lib/inets/src/http_server/httpd.erl
+++ b/lib/inets/src/http_server/httpd.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,6 +24,7 @@
-behaviour(inets_service).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
%% Behavior callbacks
-export([
@@ -41,7 +43,7 @@
%%%========================================================================
parse_query(String) ->
- {ok, SplitString} = inets_regexp:split(String,"[&;]"),
+ SplitString = re:split(String,"[&;]", [{return, list}]),
foreach(SplitString).
reload_config(Config = [Value| _], Mode) when is_tuple(Value) ->
@@ -61,18 +63,27 @@ info(Pid, Properties) when is_pid(Pid) andalso is_list(Properties) ->
{ok, ServiceInfo} = service_info(Pid),
Address = proplists:get_value(bind_address, ServiceInfo),
Port = proplists:get_value(port, ServiceInfo),
+ Profile = proplists:get_value(profile, ServiceInfo, default),
case Properties of
[] ->
- info(Address, Port);
+ info(Address, Port, Profile);
_ ->
- info(Address, Port, Properties)
+ info(Address, Port, Profile, Properties)
end;
+
info(Address, Port) when is_integer(Port) ->
- httpd_conf:get_config(Address, Port).
+ info(Address, Port, default).
+
+info(Address, Port, Profile) when is_integer(Port), is_atom(Profile) ->
+ httpd_conf:get_config(Address, Port, Profile);
info(Address, Port, Properties) when is_integer(Port) andalso
is_list(Properties) ->
- httpd_conf:get_config(Address, Port, Properties).
+ httpd_conf:get_config(Address, Port, default, Properties).
+
+info(Address, Port, Profile, Properties) when is_integer(Port) andalso
+ is_atom(Profile) andalso is_list(Properties) ->
+ httpd_conf:get_config(Address, Port, Profile, Properties).
%%%========================================================================
@@ -86,14 +97,16 @@ start_service(Conf) ->
httpd_sup:start_child(Conf).
stop_service({Address, Port}) ->
- httpd_sup:stop_child(Address, Port);
-
+ stop_service({Address, Port, ?DEFAULT_PROFILE});
+stop_service({Address, Port, Profile}) ->
+ httpd_sup:stop_child(Address, Port, Profile);
stop_service(Pid) when is_pid(Pid) ->
case service_info(Pid) of
{ok, Info} ->
Address = proplists:get_value(bind_address, Info),
Port = proplists:get_value(port, Info),
- stop_service({Address, Port});
+ Profile = proplists:get_value(profile, Info, ?DEFAULT_PROFILE),
+ stop_service({Address, Port, Profile});
Error ->
Error
end.
@@ -101,7 +114,6 @@ stop_service(Pid) when is_pid(Pid) ->
services() ->
[{httpd, ChildPid} || {_, ChildPid, _, _} <-
supervisor:which_children(httpd_sup)].
-
service_info(Pid) ->
try
[{ChildName, ChildPid} ||
@@ -114,7 +126,6 @@ service_info(Pid) ->
{error, service_not_available}
end.
-
%%%--------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
@@ -128,12 +139,12 @@ child_name(Pid, [_ | Children]) ->
child_name2info(undefined) ->
{error, no_such_service};
-child_name2info({httpd_instance_sup, any, Port}) ->
+child_name2info({httpd_instance_sup, any, Port, Profile}) ->
{ok, Host} = inet:gethostname(),
- Info = info(any, Port, [server_name]),
+ Info = info(any, Port, Profile, [server_name]),
{ok, [{bind_address, any}, {host, Host}, {port, Port} | Info]};
-child_name2info({httpd_instance_sup, Address, Port}) ->
- Info = info(Address, Port, [server_name]),
+child_name2info({httpd_instance_sup, Address, Port, Profile}) ->
+ Info = info(Address, Port, Profile, [server_name]),
case inet:gethostbyaddr(Address) of
{ok, {_, Host, _, _,_, _}} ->
{ok, [{bind_address, Address},
@@ -143,8 +154,8 @@ child_name2info({httpd_instance_sup, Address, Port}) ->
end.
-reload(Config, Address, Port) ->
- Name = make_name(Address,Port),
+reload(Config, Address, Port, Profile) ->
+ Name = make_name(Address,Port, Profile),
case whereis(Name) of
Pid when is_pid(Pid) ->
httpd_manager:reload(Pid, Config);
@@ -191,51 +202,19 @@ reload(Config, Address, Port) ->
%%% Timeout -> integer()
%%%
-block(Addr, Port, disturbing) when is_integer(Port) ->
- do_block(Addr, Port, disturbing);
-block(Addr, Port, non_disturbing) when is_integer(Port) ->
- do_block(Addr, Port, non_disturbing);
-
-block(ConfigFile, Mode, Timeout)
- when is_list(ConfigFile) andalso
- is_atom(Mode) andalso
- is_integer(Timeout) ->
- case get_addr_and_port(ConfigFile) of
- {ok, Addr, Port} ->
- block(Addr, Port, Mode, Timeout);
- Error ->
- Error
- end.
-
-
-block(Addr, Port, non_disturbing, Timeout)
- when is_integer(Port) andalso is_integer(Timeout) ->
- do_block(Addr, Port, non_disturbing, Timeout);
-block(Addr,Port,disturbing,Timeout)
- when is_integer(Port) andalso is_integer(Timeout) ->
- do_block(Addr, Port, disturbing, Timeout).
-
-do_block(Addr, Port, Mode) when is_integer(Port) andalso is_atom(Mode) ->
- Name = make_name(Addr,Port),
+block(Addr, Port, Profile, disturbing) when is_integer(Port) ->
+ do_block(Addr, Port, Profile, disturbing);
+block(Addr, Port, Profile, non_disturbing) when is_integer(Port) ->
+ do_block(Addr, Port, Profile, non_disturbing).
+do_block(Addr, Port, Profile, Mode) when is_integer(Port) andalso is_atom(Mode) ->
+ Name = make_name(Addr, Port, Profile),
case whereis(Name) of
Pid when is_pid(Pid) ->
- httpd_manager:block(Pid,Mode);
+ httpd_manager:block(Pid, Mode);
_ ->
{error,not_started}
end.
-
-do_block(Addr, Port, Mode, Timeout)
- when is_integer(Port) andalso is_atom(Mode) ->
- Name = make_name(Addr,Port),
- case whereis(Name) of
- Pid when is_pid(Pid) ->
- httpd_manager:block(Pid,Mode,Timeout);
- _ ->
- {error,not_started}
- end.
-
-
%%% =========================================================
%%% Function: unblock/2
%%% unblock(Addr, Port)
@@ -248,8 +227,8 @@ do_block(Addr, Port, Mode, Timeout)
%%% ConfigFile -> string()
%%%
-unblock(Addr, Port) when is_integer(Port) ->
- Name = make_name(Addr,Port),
+unblock(Addr, Port, Profile) when is_integer(Port) ->
+ Name = make_name(Addr,Port, Profile),
case whereis(Name) of
Pid when is_pid(Pid) ->
httpd_manager:unblock(Pid);
@@ -260,33 +239,18 @@ unblock(Addr, Port) when is_integer(Port) ->
foreach([]) ->
[];
foreach([KeyValue|Rest]) ->
- {ok, Plus2Space, _} = inets_regexp:gsub(KeyValue,"[\+]"," "),
- case inets_regexp:split(Plus2Space,"=") of
- {ok,[Key|Value]} ->
- [{http_uri:decode(Key),
- http_uri:decode(lists:flatten(Value))}|foreach(Rest)];
- {ok,_} ->
- foreach(Rest)
- end.
-
-get_addr_and_port(ConfigFile) ->
- case httpd_conf:load(ConfigFile) of
- {ok, ConfigList} ->
- case (catch httpd_conf:validate_properties(ConfigList)) of
- {ok, Config} ->
- Address = proplists:get_value(bind_address, Config, any),
- Port = proplists:get_value(port, Config, 80),
- {ok, Address, Port};
- Error ->
- Error
- end;
- Error ->
- Error
+ Plus2Space = re:replace(KeyValue,"[\+]"," ", [{return,list}, global]),
+ case re:split(Plus2Space,"=", [{return, list}]) of
+ [Key|Value] ->
+ [{http_uri:decode(Key),
+ http_uri:decode(lists:flatten(Value))}|foreach(Rest)];
+ _ ->
+ foreach(Rest)
end.
-make_name(Addr, Port) ->
- httpd_util:make_name("httpd", Addr, Port).
+make_name(Addr, Port, Profile) ->
+ httpd_util:make_name("httpd", Addr, Port, Profile).
do_reload_config(ConfigList, Mode) ->
@@ -294,10 +258,11 @@ do_reload_config(ConfigList, Mode) ->
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
- case block(Address, Port, Mode) of
+ Profile = proplists:get_value(profile, Config, default),
+ case block(Address, Port, Profile, Mode) of
ok ->
- reload(Config, Address, Port),
- unblock(Address, Port);
+ reload(Config, Address, Port, Profile),
+ unblock(Address, Port, Profile);
Error ->
Error
end;
diff --git a/lib/inets/src/http_server/httpd.hrl b/lib/inets/src/http_server/httpd.hrl
index 4eba833e2c..29dc45f93a 100644
--- a/lib/inets/src/http_server/httpd.hrl
+++ b/lib/inets/src/http_server/httpd.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl
index e812bc76f5..adccaf3b69 100644
--- a/lib/inets/src/http_server/httpd_acceptor.erl
+++ b/lib/inets/src/http_server/httpd_acceptor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_server/httpd_acceptor_sup.erl b/lib/inets/src/http_server/httpd_acceptor_sup.erl
index cc2b582b52..172498df8b 100644
--- a/lib/inets/src/http_server/httpd_acceptor_sup.erl
+++ b/lib/inets/src/http_server/httpd_acceptor_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -26,6 +27,8 @@
-behaviour(supervisor).
+-include("httpd_internal.hrl").
+
%% API
-export([start_link/1]).
%%, start_acceptor/6, start_acceptor/7, stop_acceptor/2]).
@@ -36,8 +39,9 @@
%%%=========================================================================
%%% API
%%%=========================================================================
-start_link([Addr, Port| _] = Args) ->
- SupName = make_name(Addr, Port),
+start_link([Addr, Port, Config| _] = Args) ->
+ Profile = proplists:get_value(profile, Config, ?DEFAULT_PROFILE),
+ SupName = make_name(Addr, Port, Profile),
supervisor:start_link({local, SupName}, ?MODULE, [Args]).
%%%=========================================================================
@@ -54,20 +58,23 @@ init([Args]) ->
%%% Internal functions
%%%=========================================================================
child_spec([Address, Port, ConfigList, AcceptTimeout, ListenInfo]) ->
- Name = id(Address, Port),
- Manager = httpd_util:make_name("httpd", Address, Port),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
+ Name = id(Address, Port, Profile),
+ Manager = httpd_util:make_name("httpd", Address, Port, Profile),
SockType = proplists:get_value(socket_type, ConfigList, ip_comm),
IpFamily = proplists:get_value(ipfamily, ConfigList, inet),
StartFunc = case ListenInfo of
undefined ->
- {httpd_acceptor, start_link, [Manager, SockType, Address, Port, IpFamily,
- httpd_util:make_name("httpd_conf", Address, Port),
- AcceptTimeout]};
+ {httpd_acceptor, start_link,
+ [Manager, SockType, Address, Port, IpFamily,
+ httpd_util:make_name("httpd_conf", Address, Port, Profile),
+ AcceptTimeout]};
_ ->
- {httpd_acceptor, start_link, [Manager, SockType, Address, Port, ListenInfo,
- IpFamily,
- httpd_util:make_name("httpd_conf", Address, Port),
- AcceptTimeout]}
+ {httpd_acceptor, start_link,
+ [Manager, SockType, Address, Port, ListenInfo,
+ IpFamily,
+ httpd_util:make_name("httpd_conf", Address, Port, Profile),
+ AcceptTimeout]}
end,
Restart = transient,
Shutdown = brutal_kill,
@@ -75,9 +82,9 @@ child_spec([Address, Port, ConfigList, AcceptTimeout, ListenInfo]) ->
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Address, Port) ->
- {httpd_acceptor_sup, Address, Port}.
+id(Address, Port, Profile) ->
+ {httpd_acceptor_sup, Address, Port, Profile}.
-make_name(Addr,Port) ->
- httpd_util:make_name("httpd_acceptor_sup", Addr, Port).
+make_name(Addr, Port, Profile) ->
+ httpd_util:make_name("httpd_acceptor_sup", Addr, Port, Profile).
diff --git a/lib/inets/src/http_server/httpd_cgi.erl b/lib/inets/src/http_server/httpd_cgi.erl
index c06a06aad3..fb5feb5fbe 100644
--- a/lib/inets/src/http_server/httpd_cgi.erl
+++ b/lib/inets/src/http_server/httpd_cgi.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index dbdc1be272..132e1b5b7a 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -3,157 +3,46 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(httpd_conf).
-%% EWSAPI
--export([is_directory/1, is_file/1, make_integer/1, clean/1,
- custom_clean/3, check_enum/2]).
-
%% Application internal API
-export([load/1, load/2, load_mime_types/1, store/1, store/2,
- remove/1, remove_all/1, get_config/2, get_config/3,
+ remove/1, remove_all/1, get_config/3, get_config/4,
lookup_socket_type/1,
lookup/2, lookup/3, lookup/4,
- validate_properties/1]).
+ validate_properties/1, white_space_clean/1]).
+
+%% Deprecated
+-export([is_directory/1, is_file/1, make_integer/1, clean/1,
+ custom_clean/3, check_enum/2]).
+
+-deprecated({is_directory, 1, next_major_release}).
+-deprecated({is_file, 1, next_major_release}).
+-deprecated({make_integer, 1, next_major_release}).
+-deprecated({clean, 1, next_major_release}).
+-deprecated({custom_clean, 3, next_major_release}).
+-deprecated({check_enum, 2, next_major_release}).
-define(VMODULE,"CONF").
-include("httpd_internal.hrl").
-include("httpd.hrl").
-include_lib("inets/src/http_lib/http_internal.hrl").
-
-%%%=========================================================================
-%%% EWSAPI
-%%%=========================================================================
-%%-------------------------------------------------------------------------
-%% is_directory(FilePath) -> Result
-%% FilePath = string()
-%% Result = {ok,Directory} | {error,Reason}
-%% Directory = string()
-%% Reason = string() | enoent | eacces | enotdir | FileInfo
-%% FileInfo = File info record
-%%
-%% Description: Checks if FilePath is a directory in which case it is
-%% returned.
-%%-------------------------------------------------------------------------
-is_directory(Directory) ->
- case file:read_file_info(Directory) of
- {ok,FileInfo} ->
- #file_info{type = Type, access = Access} = FileInfo,
- is_directory(Type,Access,FileInfo,Directory);
- {error,Reason} ->
- {error,Reason}
- end.
-is_directory(directory,read,_FileInfo,Directory) ->
- {ok,Directory};
-is_directory(directory,read_write,_FileInfo,Directory) ->
- {ok,Directory};
-is_directory(_Type,_Access,FileInfo,_Directory) ->
- {error,FileInfo}.
-
-
-%%-------------------------------------------------------------------------
-%% is_file(FilePath) -> Result
-%% FilePath = string()
-%% Result = {ok,File} | {error,Reason}
-%% File = string()
-%% Reason = string() | enoent | eacces | enotdir | FileInfo
-%% FileInfo = File info record
-%%
-%% Description: Checks if FilePath is a regular file in which case it
-%% is returned.
-%%-------------------------------------------------------------------------
-is_file(File) ->
- case file:read_file_info(File) of
- {ok,FileInfo} ->
- #file_info{type = Type, access = Access} = FileInfo,
- is_file(Type,Access,FileInfo,File);
- {error,Reason} ->
- {error,Reason}
- end.
-is_file(regular,read,_FileInfo,File) ->
- {ok,File};
-is_file(regular,read_write,_FileInfo,File) ->
- {ok,File};
-is_file(_Type,_Access,FileInfo,_File) ->
- {error,FileInfo}.
-
-
-%%-------------------------------------------------------------------------
-%% make_integer(String) -> Result
-%% String = string()
-%% Result = {ok,integer()} | {error,nomatch}
-%%
-%% Description: make_integer/1 returns an integer representation of String.
-%%-------------------------------------------------------------------------
-make_integer(String) ->
- case inets_regexp:match(clean(String),"[0-9]+") of
- {match, _, _} ->
- {ok, list_to_integer(clean(String))};
- nomatch ->
- {error, nomatch}
- end.
-
-
-%%-------------------------------------------------------------------------
-%% clean(String) -> Stripped
-%% String = Stripped = string()
-%%
-%% Description:clean/1 removes leading and/or trailing white spaces
-%% from String.
-%%-------------------------------------------------------------------------
-clean(String) ->
- {ok,CleanedString,_} =
- inets_regexp:gsub(String, "^[ \t\n\r\f]*|[ \t\n\r\f]*\$",""),
- CleanedString.
-
-
-%%-------------------------------------------------------------------------
-%% custom_clean(String,Before,After) -> Stripped
-%% Before = After = regexp()
-%% String = Stripped = string()
-%%
-%% Description: custom_clean/3 removes leading and/or trailing white
-%% spaces and custom characters from String.
-%%-------------------------------------------------------------------------
-custom_clean(String,MoreBefore,MoreAfter) ->
- {ok,CleanedString,_} = inets_regexp:gsub(String,"^[ \t\n\r\f"++MoreBefore++
- "]*|[ \t\n\r\f"++MoreAfter++"]*\$",""),
- CleanedString.
-
-
-%%-------------------------------------------------------------------------
-%% check_enum(EnumString,ValidEnumStrings) -> Result
-%% EnumString = string()
-%% ValidEnumStrings = [string()]
-%% Result = {ok,atom()} | {error,not_valid}
-%%
-%% Description: check_enum/2 checks if EnumString is a valid
-%% enumeration of ValidEnumStrings in which case it is returned as an
-%% atom.
-%%-------------------------------------------------------------------------
-check_enum(_Enum,[]) ->
- {error, not_valid};
-check_enum(Enum,[Enum|_Rest]) ->
- {ok, list_to_atom(Enum)};
-check_enum(Enum, [_NotValid|Rest]) ->
- check_enum(Enum, Rest).
-
-
%%%=========================================================================
%%% Application internal API
%%%=========================================================================
@@ -192,7 +81,7 @@ load("MaxHeaderSize " ++ MaxHeaderSize, []) ->
{ok, Integer} ->
{ok, [], {max_header_size,Integer}};
{error, _} ->
- {error, ?NICE(clean(MaxHeaderSize)++
+ {error, ?NICE(string:strip(MaxHeaderSize)++
" is an invalid number of MaxHeaderSize")}
end;
@@ -201,7 +90,7 @@ load("MaxURISize " ++ MaxHeaderSize, []) ->
{ok, Integer} ->
{ok, [], {max_uri_size, Integer}};
{error, _} ->
- {error, ?NICE(clean(MaxHeaderSize)++
+ {error, ?NICE(string:strip(MaxHeaderSize)++
" is an invalid number of MaxHeaderSize")}
end;
@@ -210,12 +99,12 @@ load("MaxContentLength " ++ Max, []) ->
{ok, Integer} ->
{ok, [], {max_content_length, Integer}};
{error, _} ->
- {error, ?NICE(clean(Max) ++
+ {error, ?NICE(string:strip(Max) ++
" is an invalid number of MaxContentLength")}
end;
load("ServerName " ++ ServerName, []) ->
- {ok,[], {server_name, clean(ServerName)}};
+ {ok,[], {server_name, string:strip(ServerName)}};
load("ServerTokens " ++ ServerTokens, []) ->
%% These are the valid *plain* server tokens:
@@ -223,28 +112,28 @@ load("ServerTokens " ++ ServerTokens, []) ->
%% It can also be a "private" server token: private:<any string>
case string:tokens(ServerTokens, [$:]) of
["private", Private] ->
- {ok,[], {server_tokens, clean(Private)}};
+ {ok,[], {server_tokens, string:strip(Private)}};
[TokStr] ->
- Tok = list_to_atom(clean(TokStr)),
+ Tok = list_to_atom(string:strip(TokStr)),
case lists:member(Tok, [none, prod, major, minor, minimum, os, full]) of
true ->
{ok,[], {server_tokens, Tok}};
false ->
- {error, ?NICE(clean(ServerTokens) ++
+ {error, ?NICE(string:strip(ServerTokens) ++
" is an invalid ServerTokens")}
end;
_ ->
- {error, ?NICE(clean(ServerTokens) ++ " is an invalid ServerTokens")}
+ {error, ?NICE(string:strip(ServerTokens) ++ " is an invalid ServerTokens")}
end;
load("SocketType " ++ SocketType, []) ->
%% ssl is the same as HTTP_DEFAULT_SSL_KIND
%% essl is the pure Erlang-based ssl (the "new" ssl)
- case check_enum(clean(SocketType), ["ssl", "essl", "ip_comm"]) of
+ case check_enum(string:strip(SocketType), ["ssl", "essl", "ip_comm"]) of
{ok, ValidSocketType} ->
{ok, [], {socket_type, ValidSocketType}};
{error,_} ->
- {error, ?NICE(clean(SocketType) ++ " is an invalid SocketType")}
+ {error, ?NICE(string:strip(SocketType) ++ " is an invalid SocketType")}
end;
load("Port " ++ Port, []) ->
@@ -252,7 +141,7 @@ load("Port " ++ Port, []) ->
{ok, Integer} ->
{ok, [], {port, Integer}};
{error, _} ->
- {error, ?NICE(clean(Port)++" is an invalid Port")}
+ {error, ?NICE(string:strip(Port)++" is an invalid Port")}
end;
load("BindAddress " ++ Address0, []) ->
@@ -267,7 +156,7 @@ load("BindAddress " ++ Address0, []) ->
case string:tokens(Address0, [$|]) of
[Address1] ->
?hdrv("load BindAddress", [{address1, Address1}]),
- {clean_address(Address1), inet6fb4};
+ {clean_address(Address1), inet};
[Address1, IpFamilyStr] ->
?hdrv("load BindAddress",
[{address1, Address1},
@@ -308,7 +197,7 @@ load("BindAddress " ++ Address0, []) ->
end;
load("KeepAlive " ++ OnorOff, []) ->
- case list_to_atom(clean(OnorOff)) of
+ case list_to_atom(string:strip(OnorOff)) of
off ->
{ok, [], {keep_alive, false}};
_ ->
@@ -320,7 +209,7 @@ load("MaxKeepAliveRequests " ++ MaxRequests, []) ->
{ok, Integer} ->
{ok, [], {max_keep_alive_request, Integer}};
{error, _} ->
- {error, ?NICE(clean(MaxRequests) ++
+ {error, ?NICE(string:strip(MaxRequests) ++
" is an invalid MaxKeepAliveRequests")}
end;
@@ -330,7 +219,7 @@ load("MaxKeepAliveRequest " ++ MaxRequests, []) ->
{ok, Integer} ->
{ok, [], {max_keep_alive_request, Integer}};
{error, _} ->
- {error, ?NICE(clean(MaxRequests) ++
+ {error, ?NICE(string:strip(MaxRequests) ++
" is an invalid MaxKeepAliveRequest")}
end;
@@ -339,26 +228,26 @@ load("KeepAliveTimeout " ++ Timeout, []) ->
{ok, Integer} ->
{ok, [], {keep_alive_timeout, Integer}};
{error, _} ->
- {error, ?NICE(clean(Timeout)++" is an invalid KeepAliveTimeout")}
+ {error, ?NICE(string:strip(Timeout)++" is an invalid KeepAliveTimeout")}
end;
load("Modules " ++ Modules, []) ->
- {ok, ModuleList} = inets_regexp:split(Modules," "),
+ ModuleList = re:split(Modules," ", [{return, list}]),
{ok, [], {modules,[list_to_atom(X) || X <- ModuleList]}};
load("ServerAdmin " ++ ServerAdmin, []) ->
- {ok, [], {server_admin,clean(ServerAdmin)}};
+ {ok, [], {server_admin,string:strip(ServerAdmin)}};
load("ServerRoot " ++ ServerRoot, []) ->
- case is_directory(clean(ServerRoot)) of
+ case is_directory(string:strip(ServerRoot)) of
{ok, Directory} ->
{ok, [], [{server_root,string:strip(Directory,right,$/)}]};
{error, _} ->
- {error, ?NICE(clean(ServerRoot)++" is an invalid ServerRoot")}
+ {error, ?NICE(string:strip(ServerRoot)++" is an invalid ServerRoot")}
end;
load("MimeTypes " ++ MimeTypes, []) ->
- case load_mime_types(clean(MimeTypes)) of
+ case load_mime_types(white_space_clean(MimeTypes)) of
{ok, MimeTypesList} ->
{ok, [], [{mime_types, MimeTypesList}]};
{error, Reason} ->
@@ -370,24 +259,24 @@ load("MaxClients " ++ MaxClients, []) ->
{ok, Integer} ->
{ok, [], {max_clients,Integer}};
{error, _} ->
- {error, ?NICE(clean(MaxClients) ++
+ {error, ?NICE(string:strip(MaxClients) ++
" is an invalid number of MaxClients")}
end;
load("DocumentRoot " ++ DocumentRoot,[]) ->
- case is_directory(clean(DocumentRoot)) of
+ case is_directory(string:strip(DocumentRoot)) of
{ok, Directory} ->
{ok, [], {document_root,string:strip(Directory,right,$/)}};
{error, _} ->
- {error, ?NICE(clean(DocumentRoot)++" is an invalid DocumentRoot")}
+ {error, ?NICE(string:strip(DocumentRoot)++" is an invalid DocumentRoot")}
end;
load("DefaultType " ++ DefaultType, []) ->
- {ok, [], {default_type,clean(DefaultType)}};
+ {ok, [], {default_type,string:strip(DefaultType)}};
load("SSLCertificateFile " ++ SSLCertificateFile, []) ->
- case is_file(clean(SSLCertificateFile)) of
+ case is_file(string:strip(SSLCertificateFile)) of
{ok, File} ->
{ok, [], {ssl_certificate_file,File}};
{error, _} ->
- {error, ?NICE(clean(SSLCertificateFile)++
+ {error, ?NICE(string:strip(SSLCertificateFile)++
" is an invalid SSLCertificateFile")}
end;
load("SSLLogLevel " ++ SSLLogAlert, []) ->
@@ -398,80 +287,87 @@ load("SSLLogLevel " ++ SSLLogAlert, []) ->
{ok, [], {ssl_log_alert, true}}
end;
load("SSLCertificateKeyFile " ++ SSLCertificateKeyFile, []) ->
- case is_file(clean(SSLCertificateKeyFile)) of
+ case is_file(string:strip(SSLCertificateKeyFile)) of
{ok, File} ->
{ok, [], {ssl_certificate_key_file,File}};
{error, _} ->
- {error, ?NICE(clean(SSLCertificateKeyFile)++
+ {error, ?NICE(string:strip(SSLCertificateKeyFile)++
" is an invalid SSLCertificateKeyFile")}
end;
load("SSLVerifyClient " ++ SSLVerifyClient, []) ->
- case make_integer(clean(SSLVerifyClient)) of
+ case make_integer(string:strip(SSLVerifyClient)) of
{ok, Integer} when (Integer >=0) andalso (Integer =< 2) ->
{ok, [], {ssl_verify_client,Integer}};
{ok, _Integer} ->
- {error,?NICE(clean(SSLVerifyClient) ++
+ {error,?NICE(string:strip(SSLVerifyClient) ++
" is an invalid SSLVerifyClient")};
{error, nomatch} ->
- {error,?NICE(clean(SSLVerifyClient) ++
+ {error,?NICE(string:strip(SSLVerifyClient) ++
" is an invalid SSLVerifyClient")}
end;
load("SSLVerifyDepth " ++ SSLVerifyDepth, []) ->
- case make_integer(clean(SSLVerifyDepth)) of
+ case make_integer(string:strip(SSLVerifyDepth)) of
{ok, Integer} when Integer > 0 ->
{ok, [], {ssl_verify_client_depth,Integer}};
{ok, _Integer} ->
- {error,?NICE(clean(SSLVerifyDepth) ++
+ {error,?NICE(string:strip(SSLVerifyDepth) ++
" is an invalid SSLVerifyDepth")};
{error, nomatch} ->
- {error,?NICE(clean(SSLVerifyDepth) ++
+ {error,?NICE(string:strip(SSLVerifyDepth) ++
" is an invalid SSLVerifyDepth")}
end;
load("SSLCiphers " ++ SSLCiphers, []) ->
- {ok, [], {ssl_ciphers, clean(SSLCiphers)}};
+ {ok, [], {ssl_ciphers, string:strip(SSLCiphers)}};
load("SSLCACertificateFile " ++ SSLCACertificateFile, []) ->
- case is_file(clean(SSLCACertificateFile)) of
+ case is_file(string:strip(SSLCACertificateFile)) of
{ok, File} ->
{ok, [], {ssl_ca_certificate_file,File}};
{error, _} ->
- {error, ?NICE(clean(SSLCACertificateFile)++
+ {error, ?NICE(string:strip(SSLCACertificateFile)++
" is an invalid SSLCACertificateFile")}
end;
load("SSLPasswordCallbackModule " ++ SSLPasswordCallbackModule, []) ->
{ok, [], {ssl_password_callback_module,
- list_to_atom(clean(SSLPasswordCallbackModule))}};
+ list_to_atom(string:strip(SSLPasswordCallbackModule))}};
load("SSLPasswordCallbackFunction " ++ SSLPasswordCallbackFunction, []) ->
{ok, [], {ssl_password_callback_function,
- list_to_atom(clean(SSLPasswordCallbackFunction))}};
+ list_to_atom(string:strip(SSLPasswordCallbackFunction))}};
load("SSLPasswordCallbackArguments " ++ SSLPasswordCallbackArguments, []) ->
{ok, [], {ssl_password_callback_arguments,
SSLPasswordCallbackArguments}};
load("DisableChunkedTransferEncodingSend " ++ TrueOrFalse, []) ->
- case list_to_atom(clean(TrueOrFalse)) of
+ case list_to_atom(string:strip(TrueOrFalse)) of
true ->
{ok, [], {disable_chunked_transfer_encoding_send, true}};
_ ->
{ok, [], {disable_chunked_transfer_encoding_send, false}}
end;
load("LogFormat " ++ LogFormat, []) ->
- {ok,[],{log_format, list_to_atom(httpd_conf:clean(LogFormat))}};
+ {ok,[],{log_format, list_to_atom(string:strip(LogFormat))}};
load("ErrorLogFormat " ++ LogFormat, []) ->
- {ok,[],{error_log_format, list_to_atom(httpd_conf:clean(LogFormat))}}.
+ {ok,[],{error_log_format, list_to_atom(string:strip(LogFormat))}}.
clean_address(Addr) ->
- string:strip(string:strip(clean(Addr), left, $[), right, $]).
+ string:strip(string:strip(string:strip(Addr), left, $[), right, $]).
make_ipfamily(IpFamilyStr) ->
- IpFamily = list_to_atom(IpFamilyStr),
- case lists:member(IpFamily, [inet, inet6, inet6fb4]) of
- true ->
- IpFamily;
- false ->
- throw({error, {bad_ipfamily, IpFamilyStr}})
- end.
-
+ validate_ipfamily(list_to_atom(IpFamilyStr)).
+
+validate_ipfamily(inet) ->
+ inet;
+validate_ipfamily(inet6) ->
+ inet6;
+%% Backwards compatibility wrapper,
+%% fallback to the default, IPV4,
+%% as it will most proably work.
+%% IPv6 standard moved away from
+%% beeing able to fallback to ipv4
+validate_ipfamily(inet6fb4) ->
+ inet;
+validate_ipfamily(IpFamilyStr) ->
+ throw({error, {bad_ipfamily, IpFamilyStr}}).
%%
%% load_mime_types/1 -> {ok, MimeTypes} | {error, Reason}
@@ -504,20 +400,16 @@ validate_properties2(Properties) ->
undefined ->
case proplists:get_value(sock_type, Properties, ip_comm) of
ip_comm ->
- case proplists:get_value(ipfamily, Properties) of
- undefined ->
- [{bind_address, any},
- {ipfamily, inet6fb4} | Properties];
- _ ->
- [{bind_address, any} | Properties]
- end;
+ add_inet_defaults(Properties);
+ {ip_comm, _} ->
+ add_inet_defaults(Properties);
_ ->
[{bind_address, any} | Properties]
end;
any ->
Properties;
Address0 ->
- IpFamily = proplists:get_value(ipfamily, Properties, inet6fb4),
+ IpFamily = proplists:get_value(ipfamily, Properties, inet),
case httpd_util:ip_address(Address0, IpFamily) of
{ok, Address} ->
Properties1 = proplists:delete(bind_address, Properties),
@@ -529,6 +421,16 @@ validate_properties2(Properties) ->
throw(Error)
end
end.
+
+add_inet_defaults(Properties) ->
+ case proplists:get_value(ipfamily, Properties) of
+ undefined ->
+ [{bind_address, any},
+ {ipfamily, inet} | Properties];
+ _ ->
+ [{bind_address, any} | Properties]
+ end.
+
check_minimum_bytes_per_second(Properties) ->
case proplists:get_value(minimum_bytes_per_second, Properties, false) of
false ->
@@ -598,12 +500,11 @@ validate_config_params([{server_tokens, Value} | _]) ->
validate_config_params([{socket_type, ip_comm} | Rest]) ->
validate_config_params(Rest);
-validate_config_params([{socket_type, Value} | Rest])
- when Value == ssl; Value == essl ->
- validate_config_params(Rest);
-
-validate_config_params([{socket_type, {Value, _}} | Rest])
- when Value == essl orelse Value == ssl ->
+validate_config_params([{socket_type, {Value, Opts}} | Rest]) when Value == ip_comm;
+ Value == ssl;
+ Value == essl ->
+ %% Make sure not to set socket values used internaly
+ validate_config_params(Opts),
validate_config_params(Rest);
validate_config_params([{socket_type, Value} | _]) ->
@@ -733,21 +634,32 @@ validate_config_params([{disable_chunked_transfer_encoding_send, Value} |
validate_config_params([{disable_chunked_transfer_encoding_send, Value} |
_ ]) ->
throw({disable_chunked_transfer_encoding_send, Value});
+validate_config_params([{Name, _} = Opt | _]) when Name == packet;
+ Name == mode;
+ Name == active;
+ Name == reuseaddr ->
+ throw({internaly_handled_opt_can_not_be_set, Opt});
validate_config_params([_| Rest]) ->
validate_config_params(Rest).
-%% It is actually pointless to check bind_address in this way since
-%% we need ipfamily to do it properly...
is_bind_address(any) ->
true;
is_bind_address(Value) ->
- case httpd_util:ip_address(Value, inet6fb4) of
+ case is_bind_address(Value, inet) of
+ false ->
+ is_bind_address(Value, inet6);
+ True ->
+ True
+ end.
+
+is_bind_address(Value, IpFamily) ->
+ case httpd_util:ip_address(Value, IpFamily) of
{ok, _} ->
true;
_ ->
false
end.
-
+
store(ConfigList0) ->
?hdrd("store", []),
try validate_config_params(ConfigList0) of
@@ -757,8 +669,9 @@ store(ConfigList0) ->
?hdrt("store", [{modules, Modules}]),
Port = proplists:get_value(port, ConfigList0),
Addr = proplists:get_value(bind_address, ConfigList0, any),
+ Profile = proplists:get_value(profile, ConfigList0, default),
ConfigList = fix_mime_types(ConfigList0),
- Name = httpd_util:make_name("httpd_conf", Addr, Port),
+ Name = httpd_util:make_name("httpd_conf", Addr, Port, Profile),
ConfigDB = ets:new(Name, [named_table, bag, protected]),
store(ConfigDB, ConfigList,
lists:append(Modules, [?MODULE]),
@@ -785,8 +698,15 @@ fix_mime_types(ConfigList0) ->
[{"html","text/html"},{"htm","text/html"}]}
| ConfigList0]
end;
- _ ->
- ConfigList0
+ MimeTypes ->
+ case filelib:is_file(MimeTypes) of
+ true ->
+ {ok, MimeTypesList} = load_mime_types(MimeTypes),
+ ConfigList = proplists:delete(mime_types, ConfigList0),
+ [{mime_types, MimeTypesList} | ConfigList];
+ false ->
+ ConfigList0
+ end
end.
store({mime_types,MimeTypesList},ConfigList) ->
@@ -879,38 +799,16 @@ remove(ConfigDB) ->
ets:delete(ConfigDB),
ok.
-%% config(ConfigDB) ->
-%% case httpd_util:lookup(ConfigDB, socket_type, ip_comm) of
-%% ssl ->
-%% case ssl_certificate_file(ConfigDB) of
-%% undefined ->
-%% {error,
-%% "Directive SSLCertificateFile "
-%% "not found in the config file"};
-%% SSLCertificateFile ->
-%% {ssl,
-%% SSLCertificateFile++
-%% ssl_certificate_key_file(ConfigDB)++
-%% ssl_verify_client(ConfigDB)++
-%% ssl_ciphers(ConfigDB)++
-%% ssl_password(ConfigDB)++
-%% ssl_verify_depth(ConfigDB)++
-%% ssl_ca_certificate_file(ConfigDB)}
-%% end;
-%% ip_comm ->
-%% ip_comm
-%% end.
-
-
-get_config(Address, Port) ->
- Tab = httpd_util:make_name("httpd_conf", Address, Port),
+
+get_config(Address, Port, Profile) ->
+ Tab = httpd_util:make_name("httpd_conf", Address, Port, Profile),
Properties = ets:tab2list(Tab),
MimeTab = proplists:get_value(mime_types, Properties),
NewProperties = proplists:delete(mime_types, Properties),
[{mime_types, ets:tab2list(MimeTab)} | NewProperties].
-get_config(Address, Port, Properties) ->
- Tab = httpd_util:make_name("httpd_conf", Address, Port),
+get_config(Address, Port, Profile, Properties) ->
+ Tab = httpd_util:make_name("httpd_conf", Address, Port, Profile),
Config =
lists:map(fun(Prop) -> {Prop, httpd_util:lookup(Tab, Prop)} end,
Properties),
@@ -939,6 +837,8 @@ lookup_socket_type(ConfigDB) ->
case httpd_util:lookup(ConfigDB, socket_type, ip_comm) of
ip_comm ->
ip_comm;
+ {ip_comm, _} = Type ->
+ Type;
{Tag, Conf} ->
{Tag, Conf};
SSL when (SSL =:= ssl) orelse (SSL =:= essl) ->
@@ -979,7 +879,7 @@ bootstrap([]) ->
bootstrap([Line|Config]) ->
case Line of
"Modules " ++ Modules ->
- {ok, ModuleList} = inets_regexp:split(Modules," "),
+ ModuleList = re:split(Modules," ", [{return, list}]),
TheMods = [list_to_atom(X) || X <- ModuleList],
case verify_modules(TheMods) of
ok ->
@@ -1078,7 +978,7 @@ verify_modules([]) ->
verify_modules([Mod|Rest]) ->
case code:which(Mod) of
non_existing ->
- {error, ?NICE(atom_to_list(Mod)++" does not exist")};
+ {error, ?NICE(string:strip(atom_to_list(Mod), right, $\n) ++" does not exist")};
_Path ->
verify_modules(Rest)
end.
@@ -1104,7 +1004,8 @@ read_config_file(Stream, SoFar) ->
%% Ignore commented lines for efficiency later ..
read_config_file(Stream, SoFar);
Line ->
- {ok, NewLine, _}=inets_regexp:sub(clean(Line),"[\t\r\f ]"," "),
+ NewLine = re:replace(white_space_clean(Line),
+ "[\t\r\f ]"," ", [{return,list}, global]),
case NewLine of
[] ->
%% Also ignore empty lines ..
@@ -1120,7 +1021,7 @@ parse_mime_types(Stream,MimeTypesList) ->
eof ->
eof;
String ->
- clean(String)
+ re:replace(white_space_clean(String), "[\t\r\f ]"," ", [{return,list}, global])
end,
parse_mime_types(Stream, MimeTypesList, Line).
parse_mime_types(Stream, MimeTypesList, eof) ->
@@ -1131,17 +1032,19 @@ parse_mime_types(Stream, MimeTypesList, "") ->
parse_mime_types(Stream, MimeTypesList, [$#|_]) ->
parse_mime_types(Stream, MimeTypesList);
parse_mime_types(Stream, MimeTypesList, Line) ->
- case inets_regexp:split(Line, " ") of
- {ok, [NewMimeType|Suffixes]} ->
+ case re:split(Line, " ", [{return, list}]) of
+ [NewMimeType|Suffixes] ->
parse_mime_types(Stream,
lists:append(suffixes(NewMimeType,Suffixes),
MimeTypesList));
- {ok, _} ->
+ _ ->
{error, ?NICE(Line)}
end.
suffixes(_MimeType,[]) ->
[];
+suffixes(MimeType,[""|Rest]) ->
+ suffixes(MimeType, Rest);
suffixes(MimeType,[Suffix|Rest]) ->
[{Suffix,MimeType}|suffixes(MimeType,Rest)].
@@ -1306,4 +1209,68 @@ plain_server_tokens() ->
error_report(Where,M,F,Error) ->
error_logger:error_report([{?MODULE, Where},
{apply, {M, F, []}}, Error]).
+white_space_clean(String) ->
+ re:replace(String, "^[ \t\n\r\f]*|[ \t\n\r\f]*\$","",
+ [{return,list}, global]).
+
+
+%%%=========================================================================
+%%% Deprecated remove in 19
+%%%=========================================================================
+is_directory(Directory) ->
+ case file:read_file_info(Directory) of
+ {ok,FileInfo} ->
+ #file_info{type = Type, access = Access} = FileInfo,
+ is_directory(Type,Access,FileInfo,Directory);
+ {error,Reason} ->
+ {error,Reason}
+ end.
+is_directory(directory,read,_FileInfo,Directory) ->
+ {ok,Directory};
+is_directory(directory,read_write,_FileInfo,Directory) ->
+ {ok,Directory};
+is_directory(_Type,_Access,FileInfo,_Directory) ->
+ {error,FileInfo}.
+
+is_file(File) ->
+ case file:read_file_info(File) of
+ {ok,FileInfo} ->
+ #file_info{type = Type, access = Access} = FileInfo,
+ is_file(Type,Access,FileInfo,File);
+ {error,Reason} ->
+ {error,Reason}
+ end.
+is_file(regular,read,_FileInfo,File) ->
+ {ok,File};
+is_file(regular,read_write,_FileInfo,File) ->
+ {ok,File};
+is_file(_Type,_Access,FileInfo,_File) ->
+ {error,FileInfo}.
+
+make_integer(String) ->
+ case re:run(string:strip(String),"[0-9]+", [{capture, none}]) of
+ match ->
+ {ok, list_to_integer(string:strip(String))};
+ nomatch ->
+ {error, nomatch}
+ end.
+
+clean(String) ->
+ re:replace(String, "^[ \t\n\r\f]*|[ \t\n\r\f]*\$","",
+ [{return,list}, global]).
+
+custom_clean(String,MoreBefore,MoreAfter) ->
+ re:replace(String,
+ "^[ \t\n\r\f"++MoreBefore++
+ "]*|[ \t\n\r\f"++MoreAfter++"]*\$","",
+ [{return,list}, global]).
+
+
+check_enum(_Enum,[]) ->
+ {error, not_valid};
+check_enum(Enum,[Enum|_Rest]) ->
+ {ok, list_to_atom(Enum)};
+check_enum(Enum, [_NotValid|Rest]) ->
+ check_enum(Enum, Rest).
+
diff --git a/lib/inets/src/http_server/httpd_connection_sup.erl b/lib/inets/src/http_server/httpd_connection_sup.erl
index 48c2d8f076..939aa5366b 100644
--- a/lib/inets/src/http_server/httpd_connection_sup.erl
+++ b/lib/inets/src/http_server/httpd_connection_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/httpd_custom.erl b/lib/inets/src/http_server/httpd_custom.erl
index 342469a579..2b9701ef75 100644
--- a/lib/inets/src/http_server/httpd_custom.erl
+++ b/lib/inets/src/http_server/httpd_custom.erl
@@ -3,32 +3,44 @@
%%
%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(httpd_custom).
--export([response_header/1, request_header/1]).
--export([customize_headers/3]).
+-export([response_header/1, request_header/1, response_default_headers/0]).
+-export([customize_headers/3, response_default_headers/1]).
+
+-include("../inets_app/inets_internal.hrl").
--include_lib("inets/src/inets_app/inets_internal.hrl").
+-behaviour(httpd_custom_api).
+
+%%--------------------------------------------------------------------
+%% Behavior API -----------------------------------
+%%--------------------------------------------------------------------
response_header(Header) ->
{true, httpify(Header)}.
request_header(Header) ->
{true, Header}.
+response_default_headers() ->
+ [].
+%%--------------------------------------------------------------------
+%% Internal API -----------------------------------
+%%--------------------------------------------------------------------
customize_headers(?MODULE, Function, Arg) ->
?MODULE:Function(Arg);
customize_headers(Module, Function, Arg) ->
@@ -42,6 +54,20 @@ customize_headers(Module, Function, Arg) ->
?MODULE:Function(Arg)
end.
+response_default_headers(?MODULE) ->
+ response_default_headers();
+response_default_headers(Module) ->
+ try Module:response_default_headers() of
+ Defaults ->
+ [{http_util:to_lower(Key), Value} || {Key, Value} <- Defaults,
+ is_list(Key), is_list(Value)]
+ catch
+ _:_ ->
+ ?MODULE:response_default_headers()
+ end.
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------
+%%--------------------------------------------------------------------
httpify({Key0, Value}) ->
%% make sure first letter is capital (defacto standard)
Words1 = string:tokens(Key0, "-"),
diff --git a/lib/inets/src/http_server/httpd_custom_api.erl b/lib/inets/src/http_server/httpd_custom_api.erl
new file mode 100644
index 0000000000..d5a6fa8715
--- /dev/null
+++ b/lib/inets/src/http_server/httpd_custom_api.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_custom_api).
+
+-callback response_default_headers() ->
+ [{Key::string(), Value::string()}].
+-callback response_header({Key::string(), Value::string()}) ->
+ {true, {Key::string(), Value::string()}} | false |
+ {true, string()}. %% Used internally to avoid traversing headers twice
+-callback request_header({Key::string(), Value::string()}) ->
+ {true, {Key::string(), Value::string()}} | false.
+
+-optional_callbacks([response_default_headers/0, response_header/1,
+ request_header/1]).
diff --git a/lib/inets/src/http_server/httpd_esi.erl b/lib/inets/src/http_server/httpd_esi.erl
index 000874d0a3..a925fac217 100644
--- a/lib/inets/src/http_server/httpd_esi.erl
+++ b/lib/inets/src/http_server/httpd_esi.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_server/httpd_example.erl b/lib/inets/src/http_server/httpd_example.erl
index 6fc07f033c..ad29b5b29a 100644
--- a/lib/inets/src/http_server/httpd_example.erl
+++ b/lib/inets/src/http_server/httpd_example.erl
@@ -3,27 +3,28 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(httpd_example).
-export([print/1]).
--export([get/2, post/2, yahoo/2, test1/2, get_bin/2]).
+-export([get/2, post/2, yahoo/2, test1/2, get_bin/2, peer/2]).
-export([newformat/3]).
%% These are used by the inets test-suite
--export([delay/1]).
+-export([delay/1, chunk_timeout/3]).
print(String) ->
@@ -93,10 +94,26 @@ default(Env,Input) ->
io_lib:format("~p",[httpd:parse_query(Input)]),"\n",
footer()].
+peer(Env, Input) ->
+ Header =
+ case proplists:get_value(peer_cert, Env) of
+ undefined ->
+ header("text/html", "Peer-Cert-Exist:false");
+ _ ->
+ header("text/html", "Peer-Cert-Exist:true")
+ end,
+ [Header,
+ top("Test peer_cert environment option"),
+ "<B>Peer cert:</B> ",
+ io_lib:format("~p",[proplists:get_value(peer_cert, Env)]),"\n",
+ footer()].
+
header() ->
header("text/html").
header(MimeType) ->
"Content-type: " ++ MimeType ++ "\r\n\r\n".
+header(MimeType, Other) ->
+ "Content-type: " ++ MimeType ++ "\r\n" ++ Other ++ "\r\n\r\n".
top(Title) ->
"<HTML>
@@ -126,9 +143,7 @@ delay(Time) when is_integer(Time) ->
i("httpd_example:delay(~p) -> done, now reply",[Time]),
delay_reply("delay ok");
delay(Time) when is_list(Time) ->
- delay(httpd_conf:make_integer(Time));
-delay({ok,Time}) when is_integer(Time) ->
- delay(Time);
+ delay(list_to_integer(Time));
delay({error,_Reason}) ->
i("delay -> called with invalid time"),
delay_reply("delay failed: invalid delay time").
@@ -143,3 +158,11 @@ i(F) -> i(F,[]).
i(F,A) -> io:format(F ++ "~n",A).
sleep(T) -> receive after T -> ok end.
+
+%% ------------------------------------------------------
+
+chunk_timeout(SessionID, _, StrInt) ->
+ mod_esi:deliver(SessionID, "Tranfer-Encoding:chunked/html\r\n\r\n"),
+ mod_esi:deliver(SessionID, top("Test chunk encoding timeout")),
+ timer:sleep(20000),
+ mod_esi:deliver(SessionID, footer()).
diff --git a/lib/inets/src/http_server/httpd_file.erl b/lib/inets/src/http_server/httpd_file.erl
index f2ba33099e..5ada71ad76 100644
--- a/lib/inets/src/http_server/httpd_file.erl
+++ b/lib/inets/src/http_server/httpd_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/httpd_instance_sup.erl b/lib/inets/src/http_server/httpd_instance_sup.erl
index b95be44b2a..079cc464ba 100644
--- a/lib/inets/src/http_server/httpd_instance_sup.erl
+++ b/lib/inets/src/http_server/httpd_instance_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,6 +28,8 @@
-behaviour(supervisor).
+-include("httpd_internal.hrl").
+
%% Internal application API
-export([start_link/3, start_link/4]).
@@ -41,7 +44,8 @@ start_link([{_, _}| _] = Config, AcceptTimeout, Debug) ->
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
- Name = make_name(Address, Port),
+ Profile = proplists:get_value(profile, Config2, ?DEFAULT_PROFILE),
+ Name = make_name(Address, Port, Profile),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[undefined, Config2, AcceptTimeout,
@@ -54,7 +58,8 @@ start_link([{_, _}| _] = Config, AcceptTimeout, Debug) ->
start_link(ConfigFile, AcceptTimeout, Debug) ->
case file_2_config(ConfigFile) of
{ok, ConfigList, Address, Port} ->
- Name = make_name(Address, Port),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
+ Name = make_name(Address, Port, Profile),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[ConfigFile, ConfigList, AcceptTimeout,
@@ -70,7 +75,8 @@ start_link([{_, _}| _] = Config, AcceptTimeout, ListenInfo, Debug) ->
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
- Name = make_name(Address, Port),
+ Profile = proplists:get_value(profile, Config2, ?DEFAULT_PROFILE),
+ Name = make_name(Address, Port, Profile),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[undefined, Config2, AcceptTimeout,
@@ -83,7 +89,8 @@ start_link([{_, _}| _] = Config, AcceptTimeout, ListenInfo, Debug) ->
start_link(ConfigFile, AcceptTimeout, ListenInfo, Debug) ->
case file_2_config(ConfigFile) of
{ok, ConfigList, Address, Port} ->
- Name = make_name(Address, Port),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
+ Name = make_name(Address, Port, Profile),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[ConfigFile, ConfigList, AcceptTimeout,
@@ -99,22 +106,24 @@ start_link(ConfigFile, AcceptTimeout, ListenInfo, Debug) ->
%%%=========================================================================
init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port]) ->
httpd_util:enable_debug(Debug),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
Flags = {one_for_one, 0, 1},
- Children = [httpd_connection_sup_spec(Address, Port),
- httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout,
+ Children = [httpd_connection_sup_spec(Address, Port, Profile),
+ httpd_acceptor_sup_spec(Address, Port, Profile, ConfigList, AcceptTimeout,
undefined),
- sup_spec(httpd_misc_sup, Address, Port),
- worker_spec(httpd_manager, Address, Port,
+ sup_spec(httpd_misc_sup, Address, Port, Profile),
+ worker_spec(httpd_manager, Address, Port, Profile,
ConfigFile, ConfigList,AcceptTimeout)],
{ok, {Flags, Children}};
init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port, ListenInfo]) ->
httpd_util:enable_debug(Debug),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
Flags = {one_for_one, 0, 1},
- Children = [httpd_connection_sup_spec(Address, Port),
- httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout,
- ListenInfo),
- sup_spec(httpd_misc_sup, Address, Port),
- worker_spec(httpd_manager, Address, Port, ListenInfo,
+ Children = [httpd_connection_sup_spec(Address, Port, Profile),
+ httpd_acceptor_sup_spec(Address, Port, Profile, ConfigList, AcceptTimeout,
+ ListenInfo),
+ sup_spec(httpd_misc_sup, Address, Port, Profile),
+ worker_spec(httpd_manager, Address, Port, Profile, ListenInfo,
ConfigFile, ConfigList, AcceptTimeout)],
{ok, {Flags, Children}}.
@@ -122,8 +131,8 @@ init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port, ListenInfo])
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-httpd_connection_sup_spec(Address, Port) ->
- Name = {httpd_connection_sup, Address, Port},
+httpd_connection_sup_spec(Address, Port, Profile) ->
+ Name = {httpd_connection_sup, Address, Port, Profile},
StartFunc = {httpd_connection_sup, start_link, [[Address, Port]]},
Restart = permanent,
Shutdown = 5000,
@@ -131,8 +140,8 @@ httpd_connection_sup_spec(Address, Port) ->
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout, ListenInfo) ->
- Name = {httpd_acceptor_sup, Address, Port},
+httpd_acceptor_sup_spec(Address, Port, Profile, ConfigList, AcceptTimeout, ListenInfo) ->
+ Name = {httpd_acceptor_sup, Address, Port, Profile},
StartFunc = {httpd_acceptor_sup, start_link, [[Address, Port, ConfigList, AcceptTimeout, ListenInfo]]},
Restart = permanent,
Shutdown = infinity,
@@ -140,18 +149,18 @@ httpd_acceptor_sup_spec(Address, Port, ConfigList, AcceptTimeout, ListenInfo) ->
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-sup_spec(SupModule, Address, Port) ->
- Name = {SupModule, Address, Port},
- StartFunc = {SupModule, start_link, [Address, Port]},
+sup_spec(SupModule, Address, Port, Profile) ->
+ Name = {SupModule, Address, Port, Profile},
+ StartFunc = {SupModule, start_link, [Address, Port, Profile]},
Restart = permanent,
Shutdown = infinity,
Modules = [SupModule],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-worker_spec(WorkerModule, Address, Port, ConfigFile,
+worker_spec(WorkerModule, Address, Port, Profile, ConfigFile,
ConfigList, AcceptTimeout) ->
- Name = {WorkerModule, Address, Port},
+ Name = {WorkerModule, Address, Port, Profile},
StartFunc = {WorkerModule, start_link,
[ConfigFile, ConfigList, AcceptTimeout]},
Restart = permanent,
@@ -160,9 +169,9 @@ worker_spec(WorkerModule, Address, Port, ConfigFile,
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-worker_spec(WorkerModule, Address, Port, ListenInfo, ConfigFile,
+worker_spec(WorkerModule, Address, Port, Profile, ListenInfo, ConfigFile,
ConfigList, AcceptTimeout) ->
- Name = {WorkerModule, Address, Port},
+ Name = {WorkerModule, Address, Port, Profile},
StartFunc = {WorkerModule, start_link,
[ConfigFile, ConfigList, AcceptTimeout, ListenInfo]},
Restart = permanent,
@@ -171,8 +180,8 @@ worker_spec(WorkerModule, Address, Port, ListenInfo, ConfigFile,
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-make_name(Address,Port) ->
- httpd_util:make_name("httpd_instance_sup", Address, Port).
+make_name(Address, Port, Profile) ->
+ httpd_util:make_name("httpd_instance_sup", Address, Port, Profile).
file_2_config(ConfigFile) ->
diff --git a/lib/inets/src/http_server/httpd_internal.hrl b/lib/inets/src/http_server/httpd_internal.hrl
index 108469ea0a..79b53668ad 100644
--- a/lib/inets/src/http_server/httpd_internal.hrl
+++ b/lib/inets/src/http_server/httpd_internal.hrl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,6 +32,8 @@
-define(SOCKET_MAX_POLL,25).
-define(FILE_CHUNK_SIZE,64*1024).
-define(GATEWAY_INTERFACE,"CGI/1.1").
+-define(DEFAULT_PROFILE, default).
+
-define(NICE(Reason),lists:flatten(atom_to_list(?MODULE)++": "++Reason)).
-define(DEFAULT_CONTEXT,
[{errmsg,"[an error occurred while processing this directive]"},
diff --git a/lib/inets/src/http_server/httpd_log.erl b/lib/inets/src/http_server/httpd_log.erl
index 7ff73669f9..0bad759774 100644
--- a/lib/inets/src/http_server/httpd_log.erl
+++ b/lib/inets/src/http_server/httpd_log.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/httpd_manager.erl b/lib/inets/src/http_server/httpd_manager.erl
index 3da0343401..763ddae524 100644
--- a/lib/inets/src/http_server/httpd_manager.erl
+++ b/lib/inets/src/http_server/httpd_manager.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,7 +29,7 @@
-export([start/2, start_link/2, start_link/3, start_link/4,
stop/1, reload/2]).
-export([new_connection/1]).
--export([config_match/2, config_match/3]).
+-export([config_match/3, config_match/4]).
-export([block/2, block/3, unblock/1]).
%% gen_server exports
@@ -54,7 +55,8 @@
start(ConfigFile, ConfigList) ->
Port = proplists:get_value(port,ConfigList,80),
Addr = proplists:get_value(bind_address, ConfigList),
- Name = make_name(Addr,Port),
+ Profile = proplists:get_value(profile, ConfigList, default),
+ Name = make_name(Addr, Port, Profile),
gen_server:start({local,Name},?MODULE,
[ConfigFile, ConfigList, 15000, Addr, Port],[]).
@@ -65,7 +67,8 @@ start_link(ConfigFile, ConfigList) ->
start_link(ConfigFile, ConfigList, AcceptTimeout) ->
Port = proplists:get_value(port, ConfigList, 80),
Addr = proplists:get_value(bind_address, ConfigList),
- Name = make_name(Addr, Port),
+ Profile = proplists:get_value(profile, ConfigList, default),
+ Name = make_name(Addr, Port, Profile),
gen_server:start_link({local, Name},?MODULE,
[ConfigFile, ConfigList,
@@ -74,7 +77,8 @@ start_link(ConfigFile, ConfigList, AcceptTimeout) ->
start_link(ConfigFile, ConfigList, AcceptTimeout, ListenSocket) ->
Port = proplists:get_value(port, ConfigList, 80),
Addr = proplists:get_value(bind_address, ConfigList),
- Name = make_name(Addr, Port),
+ Profile = proplists:get_value(profile, ConfigList, default),
+ Name = make_name(Addr, Port, Profile),
gen_server:start_link({local, Name},?MODULE,
[ConfigFile, ConfigList, AcceptTimeout, Addr,
@@ -97,10 +101,10 @@ unblock(ServerRef) ->
new_connection(Manager) ->
call(Manager, {new_connection, self()}).
-config_match(Port, Pattern) ->
- config_match(undefined,Port,Pattern).
-config_match(Addr, Port, Pattern) ->
- Name = httpd_util:make_name("httpd",Addr,Port),
+config_match(Port, Profile, Pattern) ->
+ config_match(undefined,Port, Profile, Pattern).
+config_match(Addr, Port, Profile, Pattern) ->
+ Name = httpd_util:make_name("httpd",Addr,Port, Profile),
call(whereis(Name), {config_match, Pattern}).
%%%--------------------------------------------------------------------
@@ -446,8 +450,8 @@ get_ustate(ConnectionCnt,State) ->
active
end.
-make_name(Addr,Port) ->
- httpd_util:make_name("httpd",Addr,Port).
+make_name(Addr, Port, Profile) ->
+ httpd_util:make_name("httpd", Addr, Port, Profile).
report_error(State,String) ->
diff --git a/lib/inets/src/http_server/httpd_misc_sup.erl b/lib/inets/src/http_server/httpd_misc_sup.erl
index fd7c28bd7d..114a3c746f 100644
--- a/lib/inets/src/http_server/httpd_misc_sup.erl
+++ b/lib/inets/src/http_server/httpd_misc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -27,8 +28,8 @@
-behaviour(supervisor).
%% API
--export([start_link/2, start_auth_server/2, stop_auth_server/2,
- start_sec_server/2, stop_sec_server/2]).
+-export([start_link/3, start_auth_server/3, stop_auth_server/3,
+ start_sec_server/3, stop_sec_server/3]).
%% Supervisor callback
-export([init/1]).
@@ -37,26 +38,26 @@
%%% API
%%%=========================================================================
-start_link(Addr, Port) ->
- SupName = make_name(Addr, Port),
+start_link(Addr, Port, Profile) ->
+ SupName = make_name(Addr, Port, Profile),
supervisor:start_link({local, SupName}, ?MODULE, []).
%%----------------------------------------------------------------------
%% Function: [start|stop]_[auth|sec]_server/3
%% Description: Starts a [auth | security] worker (child) process
%%----------------------------------------------------------------------
-start_auth_server(Addr, Port) ->
- start_permanent_worker(mod_auth_server, Addr, Port, [gen_server]).
+start_auth_server(Addr, Port, Profile) ->
+ start_permanent_worker(mod_auth_server, Addr, Port, Profile, [gen_server]).
-stop_auth_server(Addr, Port) ->
- stop_permanent_worker(mod_auth_server, Addr, Port).
+stop_auth_server(Addr, Port, Profile) ->
+ stop_permanent_worker(mod_auth_server, Addr, Port, Profile).
-start_sec_server(Addr, Port) ->
- start_permanent_worker(mod_security_server, Addr, Port, [gen_server]).
+start_sec_server(Addr, Port, Profile) ->
+ start_permanent_worker(mod_security_server, Addr, Port, Profile, [gen_server]).
-stop_sec_server(Addr, Port) ->
- stop_permanent_worker(mod_security_server, Addr, Port).
+stop_sec_server(Addr, Port, Profile) ->
+ stop_permanent_worker(mod_security_server, Addr, Port, Profile).
%%%=========================================================================
@@ -70,15 +71,15 @@ init(_) ->
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-start_permanent_worker(Mod, Addr, Port, Modules) ->
- SupName = make_name(Addr, Port),
+start_permanent_worker(Mod, Addr, Port, Profile, Modules) ->
+ SupName = make_name(Addr, Port, Profile),
Spec = {{Mod, Addr, Port},
- {Mod, start_link, [Addr, Port]},
+ {Mod, start_link, [Addr, Port, Profile]},
permanent, timer:seconds(1), worker, [Mod] ++ Modules},
supervisor:start_child(SupName, Spec).
-stop_permanent_worker(Mod, Addr, Port) ->
- SupName = make_name(Addr, Port),
+stop_permanent_worker(Mod, Addr, Port, Profile) ->
+ SupName = make_name(Addr, Port, Profile),
Name = {Mod, Addr, Port},
case supervisor:terminate_child(SupName, Name) of
ok ->
@@ -87,5 +88,5 @@ stop_permanent_worker(Mod, Addr, Port) ->
Error
end.
-make_name(Addr,Port) ->
- httpd_util:make_name("httpd_misc_sup",Addr,Port).
+make_name(Addr,Port, Profile) ->
+ httpd_util:make_name("httpd_misc_sup",Addr,Port, Profile).
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index 782120c284..749f58c197 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -85,7 +86,8 @@ body_data(Headers, Body) ->
%%-------------------------------------------------------------------------
%% validate(Method, Uri, Version) -> ok | {error, {bad_request, Reason} |
%% {error, {not_supported, {Method, Uri, Version}}
-%% Method = "HEAD" | "GET" | "POST" | "TRACE" | "PUT" | "DELETE"
+%% Method = "HEAD" | "GET" | "POST" | "PATCH" | "TRACE" | "PUT"
+%% | "DELETE"
%% Uri = uri()
%% Version = "HTTP/N.M"
%% Description: Checks that HTTP-request-line is valid.
@@ -104,6 +106,8 @@ validate("DELETE", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
validate("POST", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
+validate("PATCH", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
validate("TRACE", Uri, "HTTP/1." ++ N) when hd(N) >= $1 ->
validate_uri(Uri);
validate(Method, Uri, Version) ->
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index 9947e17b47..8fae9ac46e 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,7 @@
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
+ terminate/2, code_change/3, format_status/2]).
-include("httpd.hrl").
-include("http_internal.hrl").
@@ -101,8 +102,8 @@ init([Manager, ConfigDB, AcceptTimeout]) ->
KeepAliveTimeOut = 1000 * httpd_util:lookup(ConfigDB, keep_alive_timeout, 150),
case http_transport:negotiate(SocketType, Socket, ?HANDSHAKE_TIMEOUT) of
- {error, _Error} ->
- exit(shutdown); %% Can be 'normal'.
+ {error, Error} ->
+ exit({shutdown, Error}); %% Can be 'normal'.
ok ->
continue_init(Manager, ConfigDB, SocketType, Socket, KeepAliveTimeOut)
end.
@@ -293,7 +294,10 @@ handle_info(Info, #state{mod = ModData} = State) ->
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
-terminate(normal, State) ->
+terminate(Reason, State) when Reason == normal;
+ Reason == shutdown ->
+ do_terminate(State);
+terminate({shutdown,_}, State) ->
do_terminate(State);
terminate(Reason, #state{response_sent = false, mod = ModData} = State) ->
httpd_response:send_status(ModData, 500, none),
@@ -309,6 +313,18 @@ do_terminate(#state{mod = ModData} = State) ->
cancel_request_timeout(State),
httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket).
+format_status(normal, [_, State]) ->
+ [{data, [{"StateData", State}]}];
+format_status(terminate, [_, State]) ->
+ Mod = (State#state.mod),
+ case Mod#mod.socket_type of
+ ip_comm ->
+ [{data, [{"StateData", State}]}];
+ {essl, _} ->
+ %% Do not print ssl options in superviosr reports
+ [{data, [{"StateData",
+ State#state{mod = Mod#mod{socket_type = 'TLS'}}}]}]
+ end.
%%--------------------------------------------------------------------
%% code_change(OldVsn, State, Extra) -> {ok, NewState}
@@ -430,7 +446,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
MaxHeaderSize, MaxBodySize) ->
case Headers#http_request_h.'transfer-encoding' of
"chunked" ->
- case http_chunk:decode(Body, MaxBodySize, MaxHeaderSize) of
+ try http_chunk:decode(Body, MaxBodySize, MaxHeaderSize) of
{Module, Function, Args} ->
http_transport:setopts(ModData#mod.socket_type,
ModData#mod.socket,
@@ -442,6 +458,14 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
http_chunk:handle_headers(Headers, ChunkedHeaders),
handle_response(State#state{headers = NewHeaders,
body = NewBody})
+ catch
+ throw:Error ->
+ httpd_response:send_status(ModData, 400,
+ "Bad input"),
+ Reason = io_lib:format("Chunk decoding failed: ~p~n",
+ [Error]),
+ error_log(Reason, ModData),
+ {stop, normal, State#state{response_sent = true}}
end;
Encoding when is_list(Encoding) ->
httpd_response:send_status(ModData, 501,
@@ -609,21 +633,10 @@ decrease(N) when is_integer(N) ->
decrease(N) ->
N.
-error_log(ReasonString, Info) ->
+error_log(ReasonString, #mod{config_db = ConfigDB}) ->
Error = lists:flatten(
io_lib:format("Error reading request: ~s", [ReasonString])),
- error_log(mod_log, Info, Error),
- error_log(mod_disk_log, Info, Error).
-
-error_log(Mod, #mod{config_db = ConfigDB} = Info, String) ->
- Modules = httpd_util:lookup(ConfigDB, modules,
- [mod_get, mod_head, mod_log]),
- case lists:member(Mod, Modules) of
- true ->
- Mod:error_log(Info, String);
- _ ->
- ok
- end.
+ httpd_util:error_log(ConfigDB, Error).
%%--------------------------------------------------------------------
diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl
index 71dc05e46d..c0b5f09faf 100644
--- a/lib/inets/src/http_server/httpd_response.erl
+++ b/lib/inets/src/http_server/httpd_response.erl
@@ -3,24 +3,25 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(httpd_response).
-export([generate_and_send_response/1, send_status/3, send_header/3,
- send_body/3, send_chunk/3, send_final_chunk/2, split_header/2,
- is_disable_chunked_send/1, cache_headers/2]).
+ send_body/3, send_chunk/3, send_final_chunk/2, send_final_chunk/3,
+ split_header/2, is_disable_chunked_send/1, cache_headers/2]).
-export([map_status_code/2]).
-include_lib("inets/src/inets_app/inets_internal.hrl").
@@ -88,8 +89,7 @@ traverse_modules(ModData,[Module|Rest]) ->
"~n Error: ~p"
"~n Stack trace: ~p",
[Module, T, E, ?STACK()])),
- report_error(mod_log, ModData#mod.config_db, String),
- report_error(mod_disk_log, ModData#mod.config_db, String),
+ httpd_util:error_log(ModData#mod.config_db, String),
send_status(ModData, 500, none),
done
end.
@@ -244,7 +244,6 @@ send_chunk(_, <<>>, _) ->
ok;
send_chunk(_, [], _) ->
ok;
-
send_chunk(#mod{http_version = "HTTP/1.1",
socket_type = Type, socket = Sock}, Response0, false) ->
Response = http_chunk:encode(Response0),
@@ -253,10 +252,13 @@ send_chunk(#mod{http_version = "HTTP/1.1",
send_chunk(#mod{socket_type = Type, socket = Sock} = _ModData, Response, _) ->
httpd_socket:deliver(Type, Sock, Response).
+send_final_chunk(Mod, IsDisableChunkedSend) ->
+ send_final_chunk(Mod, [], IsDisableChunkedSend).
+
send_final_chunk(#mod{http_version = "HTTP/1.1",
- socket_type = Type, socket = Sock}, false) ->
- httpd_socket:deliver(Type, Sock, http_chunk:encode_last());
-send_final_chunk(#mod{socket_type = Type, socket = Sock}, _) ->
+ socket_type = Type, socket = Sock}, Trailers, false) ->
+ httpd_socket:deliver(Type, Sock, http_chunk:encode_last(Trailers));
+send_final_chunk(#mod{socket_type = Type, socket = Sock}, _, _) ->
httpd_socket:close(Type, Sock).
is_disable_chunked_send(Db) ->
@@ -286,14 +288,21 @@ create_header(ConfigDb, KeyValueTupleHeaders) ->
Date = httpd_util:rfc1123_date(),
ContentType = "text/html",
Server = server(ConfigDb),
- Headers0 = add_default_headers([{"date", Date},
- {"content-type", ContentType}
- | if Server=="" -> [];
- true -> [{"server", Server}]
- end
- ],
- KeyValueTupleHeaders),
CustomizeCB = httpd_util:lookup(ConfigDb, customize, httpd_custom),
+
+ CustomDefaults = httpd_custom:response_default_headers(CustomizeCB),
+ SystemDefaultes = ([{"date", Date},
+ {"content-type", ContentType}
+ | if Server=="" -> [];
+ true -> [{"server", Server}]
+ end
+ ]),
+
+ %% System defaults not present in custom defaults will be added
+ %% to defaults
+ Defaults = add_default_headers(SystemDefaultes, CustomDefaults),
+
+ Headers0 = add_default_headers(Defaults, KeyValueTupleHeaders),
lists:filtermap(fun(H) ->
httpd_custom:customize_headers(CustomizeCB, response_header, H)
end,
@@ -389,16 +398,6 @@ send_response_old(#mod{socket_type = Type,
content_length(Body)->
integer_to_list(httpd_util:flatlength(Body)).
-report_error(Mod, ConfigDB, Error) ->
- Modules = httpd_util:lookup(ConfigDB, modules,
- [mod_get, mod_head, mod_log]),
- case lists:member(Mod, Modules) of
- true ->
- Mod:report_error(ConfigDB, Error);
- _ ->
- ok
- end.
-
handle_headers([], NewHeaders) ->
{ok, NewHeaders};
diff --git a/lib/inets/src/http_server/httpd_script_env.erl b/lib/inets/src/http_server/httpd_script_env.erl
index ac79a8cc63..1c5d828b46 100644
--- a/lib/inets/src/http_server/httpd_script_env.erl
+++ b/lib/inets/src/http_server/httpd_script_env.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -60,6 +61,19 @@ which_port(#mod{config_db = ConfigDb}) ->
which_peername(#mod{init_data = #init_data{peername = {_, RemoteAddr}}}) ->
RemoteAddr.
+which_peercert(#mod{socket_type = {Type, _}, socket = Socket}) when Type == essl;
+ Type == ssl ->
+ case ssl:peercert(Socket) of
+ {ok, Cert} ->
+ Cert;
+ {error, no_peercert} ->
+ no_peercert;
+ _ ->
+ undefined
+ end;
+which_peercert(_) -> %% Not an ssl connection
+ undefined.
+
which_resolve(#mod{init_data = #init_data{resolve = Resolve}}) ->
Resolve.
@@ -77,6 +91,7 @@ create_basic_elements(esi, ModData) ->
{server_port, which_port(ModData)},
{request_method, which_method(ModData)},
{remote_addr, which_peername(ModData)},
+ {peer_cert, which_peercert(ModData)},
{script_name, which_request_uri(ModData)}];
create_basic_elements(cgi, ModData) ->
@@ -103,7 +118,7 @@ create_http_header_elements(ScriptType, [{Name, [Value | _] = Values } |
create_http_header_elements(ScriptType, [{Name, Value} | Headers], Acc)
when is_list(Value) ->
- {ok, NewName, _} = inets_regexp:gsub(Name,"-","_"),
+ NewName = re:replace(Name,"-","_", [{return,list}, global]),
Element = http_env_element(ScriptType, NewName, Value),
create_http_header_elements(ScriptType, Headers, [Element | Acc]).
diff --git a/lib/inets/src/http_server/httpd_socket.erl b/lib/inets/src/http_server/httpd_socket.erl
index e9d3e06b38..b7b232a686 100644
--- a/lib/inets/src/http_server/httpd_socket.erl
+++ b/lib/inets/src/http_server/httpd_socket.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index 3b1e16cf78..bf40cedd5c 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,7 +29,7 @@
%% Internal application API
-export([start_link/1, start_link/2]).
--export([start_child/1, restart_child/2, stop_child/2]).
+-export([start_child/1, restart_child/3, stop_child/3]).
%% Supervisor callback
-export([init/1]).
@@ -37,7 +38,6 @@
-define(TIMEOUT, 15000).
-include("httpd_internal.hrl").
--include("inets_internal.hrl").
%%%=========================================================================
%%% API
@@ -64,33 +64,32 @@ start_child(Config) ->
end.
-restart_child(Address, Port) ->
- Name = id(Address, Port),
+restart_child(Address, Port, Profile) ->
+ Name = id(Address, Port, Profile),
case supervisor:terminate_child(?MODULE, Name) of
- ok ->
- supervisor:restart_child(?MODULE, Name);
- Error ->
- Error
- end.
-
-stop_child(Address, Port) ->
- Name = id(Address, Port),
+ ok ->
+ supervisor:restart_child(?MODULE, Name);
+ Error ->
+ Error
+ end.
+
+stop_child(Address, Port, Profile) ->
+ Name = id(Address, Port, Profile),
case supervisor:terminate_child(?MODULE, Name) of
- ok ->
- supervisor:delete_child(?MODULE, Name);
- Error ->
+ ok ->
+ supervisor:delete_child(?MODULE, Name);
+ Error ->
Error
end.
-
-id(Address, Port) ->
- {httpd_instance_sup, Address, Port}.
+
+id(Address, Port, Profile) ->
+ {httpd_instance_sup, Address, Port, Profile}.
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
init([HttpdServices]) ->
- ?hdrd("starting", [{httpd_service, HttpdServices}]),
RestartStrategy = one_for_one,
MaxR = 10,
MaxT = 3600,
@@ -118,23 +117,18 @@ init([HttpdServices]) ->
child_specs([], Acc) ->
Acc;
child_specs([{httpd, HttpdService} | Rest], Acc) ->
- ?hdrd("child specs", [{httpd, HttpdService}]),
NewHttpdService = (catch mk_tuple_list(HttpdService)),
- ?hdrd("child specs", [{new_httpd, NewHttpdService}]),
case catch child_spec(NewHttpdService) of
{error, Reason} ->
- ?hdri("failed generating child spec", [{reason, Reason}]),
error_msg("Failed to start service: ~n~p ~n due to: ~p~n",
[HttpdService, Reason]),
child_specs(Rest, Acc);
Spec ->
- ?hdrt("child spec", [{child_spec, Spec}]),
child_specs(Rest, [Spec | Acc])
end.
child_spec(HttpdService) ->
{ok, Config} = httpd_config(HttpdService),
- ?hdrt("child spec", [{config, Config}]),
Debug = proplists:get_value(debug, Config, []),
AcceptTimeout = proplists:get_value(accept_timeout, Config, 15000),
httpd_util:valid_options(Debug, AcceptTimeout, Config),
@@ -162,32 +156,27 @@ httpd_config([Value| _] = Config) when is_tuple(Value) ->
httpd_child_spec([Value| _] = Config, AcceptTimeout, Debug)
when is_tuple(Value) ->
- ?hdrt("httpd_child_spec - entry", [{accept_timeout, AcceptTimeout},
- {debug, Debug}]),
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
- httpd_child_spec(Config, AcceptTimeout, Debug, Address, Port);
+ Profile = proplists:get_value(profile, Config, ?DEFAULT_PROFILE),
+ httpd_child_spec(Config, AcceptTimeout, Debug, Address, Port, Profile);
%% In this case the AcceptTimeout and Debug will only have default values...
httpd_child_spec(ConfigFile, AcceptTimeoutDef, DebugDef) ->
- ?hdrt("httpd_child_spec - entry", [{config_file, ConfigFile},
- {accept_timeout_def, AcceptTimeoutDef},
- {debug_def, DebugDef}]),
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- ?hdrt("httpd_child_spec - loaded", [{config_list, ConfigList}]),
case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
- ?hdrt("httpd_child_spec - validated", [{config, Config}]),
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
+ Profile = proplists:get_value(profile, Config, ?DEFAULT_PROFILE),
AcceptTimeout =
proplists:get_value(accept_timeout, Config,
AcceptTimeoutDef),
Debug =
proplists:get_value(debug, Config, DebugDef),
httpd_child_spec([{file, ConfigFile} | Config],
- AcceptTimeout, Debug, Address, Port);
+ AcceptTimeout, Debug, Address, Port, Profile);
Error ->
Error
end;
@@ -195,19 +184,23 @@ httpd_child_spec(ConfigFile, AcceptTimeoutDef, DebugDef) ->
Error
end.
-httpd_child_spec(Config, AcceptTimeout, Debug, Addr, Port) ->
- Fd = proplists:get_value(fd, Config, undefined),
- case Port == 0 orelse Fd =/= undefined of
- true ->
- httpd_child_spec_listen(Config, AcceptTimeout, Debug, Addr, Port);
- false ->
- httpd_child_spec_nolisten(Config, AcceptTimeout, Debug, Addr, Port)
+httpd_child_spec(Config, AcceptTimeout, Debug, Addr, Port, Profile) ->
+ case get_fd(Port) of
+ {ok, Fd} ->
+ case Port == 0 orelse Fd =/= undefined of
+ true ->
+ httpd_child_spec_listen(Config, AcceptTimeout, Debug, Addr, Port, Profile);
+ false ->
+ httpd_child_spec_nolisten(Config, AcceptTimeout, Debug, Addr, Port, Profile)
+ end;
+ Error ->
+ Error
end.
-httpd_child_spec_listen(Config, AcceptTimeout, Debug, Addr, Port) ->
+httpd_child_spec_listen(Config, AcceptTimeout, Debug, Addr, Port, Profile) ->
case start_listen(Addr, Port, Config) of
{Pid, {NewPort, NewConfig, ListenSocket}} ->
- Name = {httpd_instance_sup, Addr, NewPort},
+ Name = {httpd_instance_sup, Addr, NewPort, Profile},
StartFunc = {httpd_instance_sup, start_link,
[NewConfig, AcceptTimeout,
{Pid, ListenSocket}, Debug]},
@@ -221,8 +214,8 @@ httpd_child_spec_listen(Config, AcceptTimeout, Debug, Addr, Port) ->
{error, Reason}
end.
-httpd_child_spec_nolisten(Config, AcceptTimeout, Debug, Addr, Port) ->
- Name = {httpd_instance_sup, Addr, Port},
+httpd_child_spec_nolisten(Config, AcceptTimeout, Debug, Addr, Port, Profile) ->
+ Name = {httpd_instance_sup, Addr, Port, Profile},
StartFunc = {httpd_instance_sup, start_link,
[Config, AcceptTimeout, Debug]},
Restart = permanent,
@@ -247,8 +240,8 @@ listen(Address, Port, Config) ->
SocketType ->
case http_transport:start(SocketType) of
ok ->
- Fd = proplists:get_value(fd, Config),
- IpFamily = proplists:get_value(ipfamily, Config, inet6fb4),
+ {ok, Fd} = get_fd(Port),
+ IpFamily = proplists:get_value(ipfamily, Config, inet),
case http_transport:listen(SocketType, Address, Port, Fd, IpFamily) of
{ok, ListenSocket} ->
NewConfig = proplists:delete(port, Config),
@@ -293,6 +286,8 @@ socket_type(Config) ->
socket_type(ip_comm = SocketType, _) ->
SocketType;
+socket_type({ip_comm, _} = SocketType, _) ->
+ SocketType;
socket_type({essl, _} = SocketType, _) ->
SocketType;
socket_type(_, Config) ->
@@ -366,3 +361,19 @@ ssl_ca_certificate_file(Config) ->
File ->
[{cacertfile, File}]
end.
+
+get_fd(0) ->
+ {ok, undefined};
+get_fd(Port) ->
+ FdKey = list_to_atom("httpd_" ++ integer_to_list(Port)),
+ case init:get_argument(FdKey) of
+ {ok, [[Value]]} ->
+ case (catch list_to_integer(Value)) of
+ N when is_integer(N) ->
+ {ok, N};
+ _ ->
+ {error, {bad_descriptor, Value}}
+ end;
+ _ ->
+ {ok, undefined}
+ end.
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index 0d04a75205..6dd6db6a0c 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,7 @@
convert_netscapecookie_date/1, enable_debug/1, valid_options/3,
modules_validate/1, module_validate/1,
dir_validate/2, file_validate/2, mime_type_validate/1,
- mime_types_validate/1, custom_date/0]).
+ mime_types_validate/1, custom_date/0, error_log/2]).
-export([encode_hex/1, decode_hex/1]).
-include_lib("kernel/include/file.hrl").
@@ -41,17 +42,7 @@ ip_address({_,_,_,_,_,_,_,_} = Address, _IpFamily) ->
{ok, Address};
ip_address(Host, IpFamily)
when ((IpFamily =:= inet) orelse (IpFamily =:= inet6)) ->
- inet:getaddr(Host, IpFamily);
-ip_address(Host, inet6fb4 = _IpFamily) ->
- Inet = case gen_tcp:listen(0, [inet6]) of
- {ok, Dummyport} ->
- gen_tcp:close(Dummyport),
- inet6;
- _ ->
- inet
- end,
- inet:getaddr(Host, Inet).
-
+ inet:getaddr(Host, IpFamily).
%% lookup
@@ -429,11 +420,11 @@ flatlength([],L) ->
%% split_path
split_path(Path) ->
- case inets_regexp:match(Path,"[\?].*\$") of
+ case re:run(Path,"[\?].*\$", [{capture, first}]) of
%% A QUERY_STRING exists!
- {match,Start,Length} ->
- {http_uri:decode(string:substr(Path,1,Start-1)),
- string:substr(Path,Start,Length)};
+ {match,[{Start,Length}]} ->
+ {http_uri:decode(string:substr(Path,1,Start)),
+ string:substr(Path,Start+1,Length)};
%% A possible PATH_INFO exists!
nomatch ->
split_path(Path,[])
@@ -531,25 +522,8 @@ remove_ws(Rest) ->
%% split
-split(String,RegExp,Limit) ->
- case inets_regexp:parse(RegExp) of
- {error,Reason} ->
- {error,Reason};
- {ok,_} ->
- {ok,do_split(String,RegExp,Limit)}
- end.
-
-do_split(String, _RegExp, 1) ->
- [String];
-
-do_split(String,RegExp,Limit) ->
- case inets_regexp:first_match(String,RegExp) of
- {match,Start,Length} ->
- [string:substr(String,1,Start-1)|
- do_split(lists:nthtail(Start+Length-1,String),RegExp,Limit-1)];
- nomatch ->
- [String]
- end.
+split(String,RegExp,N) ->
+ {ok, re:split(String, RegExp, [{parts, N}, {return, list}])}.
%% make_name/2, make_name/3
%% Prefix -> string()
@@ -572,7 +546,10 @@ make_name(Prefix,Port) ->
make_name(Prefix,Addr,Port) ->
make_name(Prefix,Addr,Port,"").
-
+
+make_name(Prefix, Addr,Port,Postfix) when is_atom(Postfix)->
+ make_name(Prefix, Addr,Port, atom_to_list(Postfix));
+
make_name(Prefix,"*",Port,Postfix) ->
make_name(Prefix,undefined,Port,Postfix);
@@ -595,15 +572,7 @@ make_name2({A,B,C,D}) ->
io_lib:format("~w_~w_~w_~w", [A,B,C,D]);
make_name2({A, B, C, D, E, F, G, H}) ->
- io_lib:format("~s_~s_~s_~s_~s_~s_~s_~s", [integer_to_hexlist(A),
- integer_to_hexlist(B),
- integer_to_hexlist(C),
- integer_to_hexlist(D),
- integer_to_hexlist(E),
- integer_to_hexlist(F),
- integer_to_hexlist(G),
- integer_to_hexlist(H)
- ]);
+ io_lib:format("~w_~w_~w_~w_~w_~w_~w_~w", [A,B,C,D,E,F,G,H]);
make_name2(Addr) ->
search_and_replace(Addr,$.,$_).
@@ -790,3 +759,17 @@ do_enable_debug([{Level,Modules}|Rest])
ok
end,
do_enable_debug(Rest).
+
+error_log(ConfigDb, Error) ->
+ error_log(mod_log, ConfigDb, Error),
+ error_log(mod_disk_log, ConfigDb, Error).
+
+error_log(Mod, ConfigDB, Error) ->
+ Modules = httpd_util:lookup(ConfigDB, modules,
+ [mod_get, mod_head, mod_log]),
+ case lists:member(Mod, Modules) of
+ true ->
+ Mod:report_error(ConfigDB, Error);
+ _ ->
+ ok
+ end.
diff --git a/lib/inets/src/http_server/mod_actions.erl b/lib/inets/src/http_server/mod_actions.erl
index c3946ff9b4..154fde294e 100644
--- a/lib/inets/src/http_server/mod_actions.erl
+++ b/lib/inets/src/http_server/mod_actions.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -80,18 +81,18 @@ script(RequestURI, Method, [_ | Rest]) ->
%% load
load("Action "++ Action, []) ->
- case inets_regexp:split(Action, " ") of
- {ok,[MimeType, CGIScript]} ->
- {ok,[],{action, {MimeType, CGIScript}}};
- {ok,_} ->
- {error,?NICE(httpd_conf:clean(Action)++" is an invalid Action")}
+ case re:split(Action, " ", [{return, list}]) of
+ [MimeType, CGIScript] ->
+ {ok,[],{action, {MimeType, CGIScript}}};
+ _ ->
+ {error,?NICE(string:strip(Action)++" is an invalid Action")}
end;
load("Script " ++ Script,[]) ->
- case inets_regexp:split(Script, " ") of
- {ok,[Method, CGIScript]} ->
- {ok,[],{script, {Method, CGIScript}}};
- {ok,_} ->
- {error,?NICE(httpd_conf:clean(Script)++" is an invalid Script")}
+ case re:split(Script, " ", [{return, list}]) of
+ [Method, CGIScript] ->
+ {ok,[],{script, {Method, CGIScript}}};
+ _ ->
+ {error,?NICE(string:strip(Script)++" is an invalid Script")}
end.
store({action, {MimeType, CGIScript}} = Conf, _) when is_list(MimeType),
diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl
index 5039cd56b5..727f6e0ce3 100644
--- a/lib/inets/src/http_server/mod_alias.erl
+++ b/lib/inets/src/http_server/mod_alias.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -112,32 +113,52 @@ real_name(ConfigDB, RequestURI, []) ->
httpd_util:split_path(default_index(ConfigDB, RealName)),
{ShortPath, Path, AfterPath};
-real_name(ConfigDB, RequestURI, [{MP,Replacement}|Rest])
+real_name(ConfigDB, RequestURI, [{MP,Replacement}| _] = Aliases)
when element(1, MP) =:= re_pattern ->
- case re:run(RequestURI, MP, [{capture,[]}]) of
- match ->
+ case longest_match(Aliases, RequestURI) of
+ {match, {MP, Replacement}} ->
NewURI = re:replace(RequestURI, MP, Replacement, [{return,list}]),
{ShortPath,_} = httpd_util:split_path(NewURI),
{Path,AfterPath} =
httpd_util:split_path(default_index(ConfigDB, NewURI)),
{ShortPath, Path, AfterPath};
nomatch ->
- real_name(ConfigDB, RequestURI, Rest)
+ real_name(ConfigDB, RequestURI, [])
end;
-real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
- case inets_regexp:match(RequestURI, "^" ++ FakeName) of
- {match, _, _} ->
- {ok, ActualName, _} = inets_regexp:sub(RequestURI,
- "^" ++ FakeName, RealName),
+real_name(ConfigDB, RequestURI, [{_,_}|_] = Aliases) ->
+ case longest_match(Aliases, RequestURI) of
+ {match, {FakeName, RealName}} ->
+ ActualName = re:replace(RequestURI,
+ "^" ++ FakeName, RealName, [{return,list}]),
{ShortPath, _AfterPath} = httpd_util:split_path(ActualName),
{Path, AfterPath} =
- httpd_util:split_path(default_index(ConfigDB, ActualName)),
+ httpd_util:split_path(default_index(ConfigDB, ActualName)),
{ShortPath, Path, AfterPath};
- nomatch ->
- real_name(ConfigDB, RequestURI, Rest)
+ nomatch ->
+ real_name(ConfigDB, RequestURI, [])
end.
+longest_match(Aliases, RequestURI) ->
+ longest_match(Aliases, RequestURI, _LongestNo = 0, _LongestAlias = undefined).
+
+longest_match([{FakeName, RealName} | Rest], RequestURI, LongestNo, LongestAlias) ->
+ case re:run(RequestURI, "^" ++ FakeName, [{capture, first}]) of
+ {match, [{_, Length}]} ->
+ if
+ Length > LongestNo ->
+ longest_match(Rest, RequestURI, Length, {FakeName, RealName});
+ true ->
+ longest_match(Rest, RequestURI, LongestNo, LongestAlias)
+ end;
+ nomatch ->
+ longest_match(Rest, RequestURI, LongestNo, LongestAlias)
+ end;
+longest_match([], _RequestURI, 0, _LongestAlias) ->
+ nomatch;
+longest_match([], _RequestURI, _LongestNo, LongestAlias) ->
+ {match, LongestAlias}.
+
%% real_script_name
real_script_name(_ConfigDB, _RequestURI, []) ->
@@ -145,7 +166,7 @@ real_script_name(_ConfigDB, _RequestURI, []) ->
real_script_name(ConfigDB, RequestURI, [{MP,Replacement} | Rest])
when element(1, MP) =:= re_pattern ->
- case re:run(RequestURI, MP, [{capture,[]}]) of
+ case re:run(RequestURI, MP, [{capture, none}]) of
match ->
ActualName =
re:replace(RequestURI, MP, Replacement, [{return,list}]),
@@ -155,10 +176,10 @@ real_script_name(ConfigDB, RequestURI, [{MP,Replacement} | Rest])
end;
real_script_name(ConfigDB, RequestURI, [{FakeName,RealName} | Rest]) ->
- case inets_regexp:match(RequestURI, "^" ++ FakeName) of
- {match,_,_} ->
- {ok, ActualName, _} =
- inets_regexp:sub(RequestURI, "^" ++ FakeName, RealName),
+ case re:run(RequestURI, "^" ++ FakeName, [{capture, none}]) of
+ match ->
+ ActualName =
+ re:replace(RequestURI, "^" ++ FakeName, RealName, [{return,list}]),
httpd_util:split_script_path(default_index(ConfigDB, ActualName));
nomatch ->
real_script_name(ConfigDB, RequestURI, Rest)
@@ -205,26 +226,26 @@ path(Data, ConfigDB, RequestURI) ->
%% load
load("DirectoryIndex " ++ DirectoryIndex, []) ->
- {ok, DirectoryIndexes} = inets_regexp:split(DirectoryIndex," "),
+ DirectoryIndexes = re:split(DirectoryIndex," ", [{return, list}]),
{ok,[], {directory_index, DirectoryIndexes}};
load("Alias " ++ Alias, []) ->
- case inets_regexp:split(Alias," ") of
- {ok, [FakeName, RealName]} ->
+ case re:split(Alias," ", [{return, list}]) of
+ [FakeName, RealName] ->
{ok,[],{alias,{FakeName,RealName}}};
- {ok, _} ->
- {error,?NICE(httpd_conf:clean(Alias)++" is an invalid Alias")}
+ _ ->
+ {error,?NICE(string:strip(Alias)++" is an invalid Alias")}
end;
load("ReWrite " ++ Rule, Acc) ->
load_re_write(Rule, Acc, "ReWrite", re_write);
load("ScriptAlias " ++ ScriptAlias, []) ->
- case inets_regexp:split(ScriptAlias, " ") of
- {ok, [FakeName, RealName]} ->
+ case re:split(ScriptAlias, " ", [{return, list}]) of
+ [FakeName, RealName] ->
%% Make sure the path always has a trailing slash..
RealName1 = filename:join(filename:split(RealName)),
{ok, [], {script_alias, {FakeName, RealName1++"/"}}};
- {ok, _} ->
- {error, ?NICE(httpd_conf:clean(ScriptAlias)++
- " is an invalid ScriptAlias")}
+ _ ->
+ {error, ?NICE(string:strip(ScriptAlias)++
+ " is an invalid ScriptAlias")}
end;
load("ScriptReWrite " ++ Rule, Acc) ->
load_re_write(Rule, Acc, "ScriptReWrite", script_re_write).
@@ -234,7 +255,7 @@ load_re_write(Rule0, Acc, Type, Tag) ->
fun ($\s) -> true; ($\t) -> true; (_) -> false end,
Rule0) of
"" ->
- {error, ?NICE(httpd_conf:clean(Rule0)++" is an invalid "++Type)};
+ {error, ?NICE(string:strip(Rule0)++" is an invalid "++Type)};
Rule ->
case string:chr(Rule, $\s) of
0 ->
diff --git a/lib/inets/src/http_server/mod_auth.erl b/lib/inets/src/http_server/mod_auth.erl
index 85a87ab884..b03629cabe 100644
--- a/lib/inets/src/http_server/mod_auth.erl
+++ b/lib/inets/src/http_server/mod_auth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -38,15 +39,16 @@
-include("httpd.hrl").
-include("mod_auth.hrl").
-include("httpd_internal.hrl").
--include("inets_internal.hrl").
-define(VMODULE,"AUTH").
-define(NOPASSWORD,"NoPassword").
-%% do
+%%====================================================================
+%% Internal application API
+%%====================================================================
+
do(Info) ->
- ?hdrt("do", [{info, Info}]),
case proplists:get_value(status,Info#mod.data) of
%% A status code has been generated!
{_StatusCode, _PhraseArgs, _Reason} ->
@@ -61,22 +63,15 @@ do(Info) ->
%% Is it a secret area?
case secretp(Path,Info#mod.config_db) of
{yes, {Directory, DirectoryData}} ->
- ?hdrt("secret area",
- [{directory, Directory},
- {directory_data, DirectoryData}]),
-
- %% Authenticate (allow)
case allow((Info#mod.init_data)#init_data.peername,
Info#mod.socket_type,Info#mod.socket,
DirectoryData) of
allowed ->
- ?hdrt("allowed", []),
case deny((Info#mod.init_data)#init_data.peername,
Info#mod.socket_type,
Info#mod.socket,
DirectoryData) of
not_denied ->
- ?hdrt("not denied", []),
case proplists:get_value(auth_type,
DirectoryData) of
undefined ->
@@ -90,15 +85,13 @@ do(Info) ->
AuthType)
end;
{denied, Reason} ->
- ?hdrt("denied", [{reason, Reason}]),
{proceed,
[{status, {403,
- Info#mod.request_uri,
- Reason}}|
+ Info#mod.request_uri,
+ Reason}}|
Info#mod.data]}
end;
{not_allowed, Reason} ->
- ?hdrt("not allowed", [{reason, Reason}]),
{proceed,[{status,{403,
Info#mod.request_uri,
Reason}} |
@@ -114,18 +107,299 @@ do(Info) ->
end.
-do_auth(Info, Directory, DirectoryData, AuthType) ->
+%% mod_auth recognizes the following Configuration Directives:
+%% <Directory /path/to/directory>
+%% AuthDBType
+%% AuthName
+%% AuthUserFile
+%% AuthGroupFile
+%% AuthAccessPassword
+%% require
+%% allow
+%% </Directory>
+
+%% When a <Directory> directive is found, a new context is set to
+%% [{directory, Directory, DirData}|OtherContext]
+%% DirData in this case is a key-value list of data belonging to the
+%% directory in question.
+%%
+%% When the </Directory> statement is found, the Context created earlier
+%% will be returned as a ConfigList and the context will return to the
+%% state it was previously.
+
+load("<Directory " ++ Directory,[]) ->
+ Dir = string:strip(string:strip(Directory),right, $>),
+ {ok,[{directory, {Dir, [{path, Dir}]}}]};
+load(eof,[{directory, {Directory, _DirData}}|_]) ->
+ {error, ?NICE("Premature end-of-file in "++ Directory)};
+
+load("AuthName " ++ AuthName, [{directory, {Directory, DirData}}|Rest]) ->
+ {ok, [{directory, {Directory,
+ [{auth_name, string:strip(AuthName)} | DirData]}}
+ | Rest ]};
+load("AuthUserFile " ++ AuthUserFile0,
+ [{directory, {Directory, DirData}}|Rest]) ->
+ AuthUserFile = string:strip(AuthUserFile0),
+ {ok, [{directory, {Directory,
+ [{auth_user_file, AuthUserFile}|DirData]}} | Rest ]};
+load("AuthGroupFile " ++ AuthGroupFile0,
+ [{directory, {Directory, DirData}}|Rest]) ->
+ AuthGroupFile = string:strip(AuthGroupFile0),
+ {ok,[{directory, {Directory,
+ [{auth_group_file, AuthGroupFile}|DirData]}} | Rest]};
+
+load("AuthAccessPassword " ++ AuthAccessPassword0,
+ [{directory, {Directory, DirData}}|Rest]) ->
+ AuthAccessPassword = string:strip(AuthAccessPassword0),
+ {ok,[{directory, {Directory,
+ [{auth_access_password, AuthAccessPassword}|DirData]}} | Rest]};
+
+load("AuthDBType " ++ Type,
+ [{directory, {Dir, DirData}}|Rest]) ->
+ case string:strip(Type) of
+ "plain" ->
+ {ok, [{directory, {Dir, [{auth_type, plain}|DirData]}} | Rest ]};
+ "mnesia" ->
+ {ok, [{directory, {Dir, [{auth_type, mnesia}|DirData]}} | Rest ]};
+ "dets" ->
+ {ok, [{directory, {Dir, [{auth_type, dets}|DirData]}} | Rest ]};
+ _ ->
+ {error, ?NICE(string:strip(Type)++" is an invalid AuthDBType")}
+ end;
+
+load("require " ++ Require,[{directory, {Directory, DirData}}|Rest]) ->
+ case re:split(Require," ", [{return, list}]) of
+ ["user" | Users] ->
+ {ok,[{directory, {Directory,
+ [{require_user,Users}|DirData]}} | Rest]};
+ ["group"|Groups] ->
+ {ok,[{directory, {Directory,
+ [{require_group,Groups}|DirData]}} | Rest]};
+ _ ->
+ {error,?NICE(string:strip(Require) ++" is an invalid require")}
+ end;
+
+load("allow " ++ Allow,[{directory, {Directory, DirData}}|Rest]) ->
+ case re:split(Allow," ", [{return, list}]) of
+ ["from","all"] ->
+ {ok,[{directory, {Directory,
+ [{allow_from,all}|DirData]}} | Rest]};
+ ["from"|Hosts] ->
+ {ok,[{directory, {Directory,
+ [{allow_from,Hosts}|DirData]}} | Rest]};
+ _ ->
+ {error,?NICE(string:strip(Allow) ++" is an invalid allow")}
+ end;
+
+load("deny " ++ Deny,[{directory, {Directory, DirData}}|Rest]) ->
+ case re:split(Deny," ", [{return, list}]) of
+ ["from", "all"] ->
+ {ok,[{{directory, Directory,
+ [{deny_from, all}|DirData]}} | Rest]};
+ ["from"|Hosts] ->
+ {ok,[{{directory, Directory,
+ [{deny_from, Hosts}|DirData]}} | Rest]};
+ _ ->
+ {error,?NICE(string:strip(Deny) ++" is an invalid deny")}
+ end;
+
+load("</Directory>",[{directory, {Directory, DirData}}|Rest]) ->
+ {ok, Rest, {directory, {Directory, DirData}}};
+
+load("AuthMnesiaDB " ++ AuthMnesiaDB,
+ [{directory, {Dir, DirData}}|Rest]) ->
+ case string:strip(AuthMnesiaDB) of
+ "On" ->
+ {ok,[{directory, {Dir,[{auth_type,mnesia}|DirData]}}|Rest]};
+ "Off" ->
+ {ok,[{directory, {Dir,[{auth_type,plain}|DirData]}}|Rest]};
+ _ ->
+ {error, ?NICE(string:strip(AuthMnesiaDB) ++
+ " is an invalid AuthMnesiaDB")}
+ end.
+
+store({directory, {Directory, DirData}}, ConfigList)
+ when is_list(Directory) andalso is_list(DirData) ->
+ try directory_config_check(Directory, DirData) of
+ ok ->
+ store_directory(Directory, DirData, ConfigList)
+ catch
+ throw:Error ->
+ {error, Error, {directory, Directory, DirData}}
+ end;
+store({directory, {Directory, DirData}}, _) ->
+ {error, {wrong_type, {directory, {Directory, DirData}}}}.
+
+remove(ConfigDB) ->
+ lists:foreach(fun({directory, {_Dir, DirData}}) ->
+ AuthMod = auth_mod_name(DirData),
+ (catch apply(AuthMod, remove, [DirData]))
+ end,
+ ets:match_object(ConfigDB,{directory,{'_','_'}})),
+
+ Addr = httpd_util:lookup(ConfigDB, bind_address, undefined),
+ Port = httpd_util:lookup(ConfigDB, port),
+ Profile = httpd_util:lookup(ConfigDB, profile, ?DEFAULT_PROFILE),
+ mod_auth_server:stop(Addr, Port, Profile),
+ ok.
+
+add_user(UserName, Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd}->
+ case get_options(Opt, userData) of
+ {error, Reason}->
+ {error, Reason};
+ {UserData, Password}->
+ User = [#httpd_user{username = UserName,
+ password = Password,
+ user_data = UserData}],
+ mod_auth_server:add_user(Addr, Port, Dir, User, AuthPwd)
+ end
+ end.
+
+
+add_user(UserName, Password, UserData, Port, Dir) ->
+ add_user(UserName, Password, UserData, undefined, Port, Dir).
+add_user(UserName, Password, UserData, Addr, Port, Dir) ->
+ User = [#httpd_user{username = UserName,
+ password = Password,
+ user_data = UserData}],
+ mod_auth_server:add_user(Addr, Port, Dir, User, ?NOPASSWORD).
+
+get_user(UserName, Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:get_user(Addr, Port, Dir, UserName, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+get_user(UserName, Port, Dir) ->
+ get_user(UserName, undefined, Port, Dir).
+get_user(UserName, Addr, Port, Dir) ->
+ mod_auth_server:get_user(Addr, Port, Dir, UserName, ?NOPASSWORD).
+
+add_group_member(GroupName, UserName, Opt)->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd}->
+ mod_auth_server:add_group_member(Addr, Port, Dir,
+ GroupName, UserName, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+add_group_member(GroupName, UserName, Port, Dir) ->
+ add_group_member(GroupName, UserName, undefined, Port, Dir).
+
+add_group_member(GroupName, UserName, Addr, Port, Dir) ->
+ mod_auth_server:add_group_member(Addr, Port, Dir,
+ GroupName, UserName, ?NOPASSWORD).
+
+delete_group_member(GroupName, UserName, Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:delete_group_member(Addr, Port, Dir,
+ GroupName, UserName, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+delete_group_member(GroupName, UserName, Port, Dir) ->
+ delete_group_member(GroupName, UserName, undefined, Port, Dir).
+delete_group_member(GroupName, UserName, Addr, Port, Dir) ->
+ mod_auth_server:delete_group_member(Addr, Port, Dir,
+ GroupName, UserName, ?NOPASSWORD).
+
+list_users(Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:list_users(Addr, Port, Dir, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+list_users(Port, Dir) ->
+ list_users(undefined, Port, Dir).
+list_users(Addr, Port, Dir) ->
+ mod_auth_server:list_users(Addr, Port, Dir, ?NOPASSWORD).
+
+delete_user(UserName, Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:delete_user(Addr, Port, Dir, UserName, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+delete_user(UserName, Port, Dir) ->
+ delete_user(UserName, undefined, Port, Dir).
+delete_user(UserName, Addr, Port, Dir) ->
+ mod_auth_server:delete_user(Addr, Port, Dir, UserName, ?NOPASSWORD).
+
+delete_group(GroupName, Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:delete_group(Addr, Port, Dir, GroupName, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+delete_group(GroupName, Port, Dir) ->
+ delete_group(GroupName, undefined, Port, Dir).
+delete_group(GroupName, Addr, Port, Dir) ->
+ mod_auth_server:delete_group(Addr, Port, Dir, GroupName, ?NOPASSWORD).
+
+list_groups(Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:list_groups(Addr, Port, Dir, AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+list_groups(Port, Dir) ->
+ list_groups(undefined, Port, Dir).
+list_groups(Addr, Port, Dir) ->
+ mod_auth_server:list_groups(Addr, Port, Dir, ?NOPASSWORD).
+
+list_group_members(GroupName, Opt) ->
+ case get_options(Opt, mandatory) of
+ {Addr, Port, Dir, AuthPwd} ->
+ mod_auth_server:list_group_members(Addr, Port, Dir, GroupName,
+ AuthPwd);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+list_group_members(GroupName, Port, Dir) ->
+ list_group_members(GroupName, undefined, Port, Dir).
+list_group_members(GroupName, Addr, Port, Dir) ->
+ mod_auth_server:list_group_members(Addr, Port, Dir,
+ GroupName, ?NOPASSWORD).
+
+update_password(Port, Dir, Old, New, New)->
+ update_password(undefined, Port, Dir, Old, New, New).
+
+update_password(Addr, Port, Dir, Old, New, New) when is_list(New) ->
+ mod_auth_server:update_password(Addr, Port, Dir, Old, New);
+
+update_password(_Addr, _Port, _Dir, _Old, _New, _New) ->
+ {error, badtype};
+update_password(_Addr, _Port, _Dir, _Old, _New, _New1) ->
+ {error, notqeual}.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+do_auth(Info, Directory, DirectoryData, _AuthType) ->
%% Authenticate (require)
- ?hdrt("authenticate", [{auth_type, AuthType}]),
case require(Info, Directory, DirectoryData) of
authorized ->
- ?hdrt("authorized", []),
{proceed,Info#mod.data};
{authorized, User} ->
- ?hdrt("authorized", [{user, User}]),
{proceed, [{remote_user,User}|Info#mod.data]};
{authorization_required, Realm} ->
- ?hdrt("authorization required", [{realm, Realm}]),
ReasonPhrase = httpd_util:reason_phrase(401),
Message = httpd_util:message(401,none,Info#mod.config_db),
{proceed,
@@ -142,8 +416,6 @@ do_auth(Info, Directory, DirectoryData, AuthType) ->
Info#mod.data]}
end.
-%% require
-
require(Info, Directory, DirectoryData) ->
ParsedHeader = Info#mod.parsed_header,
ValidUsers = proplists:get_value(require_user, DirectoryData),
@@ -270,13 +542,6 @@ auth_mod_name(DirData) ->
dets -> mod_auth_dets
end.
-
-%%
-%% Is it a secret area?
-%%
-
-%% secretp
-
secretp(Path,ConfigDB) ->
Directories = ets:match(ConfigDB,{directory, {'$1','_'}}),
case secret_path(Path, Directories) of
@@ -296,23 +561,17 @@ secret_path(_Path, [], to_be_found) ->
secret_path(_Path, [], Directory) ->
{yes, Directory};
secret_path(Path, [[NewDirectory] | Rest], Directory) ->
- case inets_regexp:match(Path, NewDirectory) of
- {match, _, _} when Directory =:= to_be_found ->
+ case re:run(Path, NewDirectory, [{capture, first}]) of
+ {match, _} when Directory =:= to_be_found ->
secret_path(Path, Rest, NewDirectory);
- {match, _, Length} when Length > length(Directory)->
+ {match, [{_, Length}]} when Length > length(Directory)->
secret_path(Path, Rest,NewDirectory);
- {match, _, _Length} ->
+ {match, _} ->
secret_path(Path, Rest, Directory);
nomatch ->
secret_path(Path, Rest, Directory)
end.
-%%
-%% Authenticate
-%%
-
-%% allow
-
allow({_,RemoteAddr}, _SocketType, _Socket, DirectoryData) ->
Hosts = proplists:get_value(allow_from, DirectoryData, all),
case validate_addr(RemoteAddr, Hosts) of
@@ -329,15 +588,13 @@ validate_addr(_RemoteAddr, none) -> % When called from 'deny'
validate_addr(_RemoteAddr, []) ->
false;
validate_addr(RemoteAddr, [HostRegExp | Rest]) ->
- case inets_regexp:match(RemoteAddr, HostRegExp) of
- {match,_,_} ->
+ case re:run(RemoteAddr, HostRegExp, [{capture, none}]) of
+ match ->
true;
nomatch ->
validate_addr(RemoteAddr,Rest)
end.
-%% deny
-
deny({_,RemoteAddr}, _SocketType, _Socket,DirectoryData) ->
Hosts = proplists:get_value(deny_from, DirectoryData, none),
case validate_addr(RemoteAddr,Hosts) of
@@ -347,124 +604,6 @@ deny({_,RemoteAddr}, _SocketType, _Socket,DirectoryData) ->
not_denied
end.
-%%
-%% Configuration
-%%
-
-%% load/2
-%%
-
-%% mod_auth recognizes the following Configuration Directives:
-%% <Directory /path/to/directory>
-%% AuthDBType
-%% AuthName
-%% AuthUserFile
-%% AuthGroupFile
-%% AuthAccessPassword
-%% require
-%% allow
-%% </Directory>
-
-%% When a <Directory> directive is found, a new context is set to
-%% [{directory, Directory, DirData}|OtherContext]
-%% DirData in this case is a key-value list of data belonging to the
-%% directory in question.
-%%
-%% When the </Directory> statement is found, the Context created earlier
-%% will be returned as a ConfigList and the context will return to the
-%% state it was previously.
-
-load("<Directory " ++ Directory,[]) ->
- Dir = httpd_conf:custom_clean(Directory,"",">"),
- {ok,[{directory, {Dir, [{path, Dir}]}}]};
-load(eof,[{directory, {Directory, _DirData}}|_]) ->
- {error, ?NICE("Premature end-of-file in "++ Directory)};
-
-load("AuthName " ++ AuthName, [{directory, {Directory, DirData}}|Rest]) ->
- {ok, [{directory, {Directory,
- [{auth_name, httpd_conf:clean(AuthName)} | DirData]}}
- | Rest ]};
-load("AuthUserFile " ++ AuthUserFile0,
- [{directory, {Directory, DirData}}|Rest]) ->
- AuthUserFile = httpd_conf:clean(AuthUserFile0),
- {ok, [{directory, {Directory,
- [{auth_user_file, AuthUserFile}|DirData]}} | Rest ]};
-load("AuthGroupFile " ++ AuthGroupFile0,
- [{directory, {Directory, DirData}}|Rest]) ->
- AuthGroupFile = httpd_conf:clean(AuthGroupFile0),
- {ok,[{directory, {Directory,
- [{auth_group_file, AuthGroupFile}|DirData]}} | Rest]};
-
-%AuthAccessPassword
-load("AuthAccessPassword " ++ AuthAccessPassword0,
- [{directory, {Directory, DirData}}|Rest]) ->
- AuthAccessPassword = httpd_conf:clean(AuthAccessPassword0),
- {ok,[{directory, {Directory,
- [{auth_access_password, AuthAccessPassword}|DirData]}} | Rest]};
-
-load("AuthDBType " ++ Type,
- [{directory, {Dir, DirData}}|Rest]) ->
- case httpd_conf:clean(Type) of
- "plain" ->
- {ok, [{directory, {Dir, [{auth_type, plain}|DirData]}} | Rest ]};
- "mnesia" ->
- {ok, [{directory, {Dir, [{auth_type, mnesia}|DirData]}} | Rest ]};
- "dets" ->
- {ok, [{directory, {Dir, [{auth_type, dets}|DirData]}} | Rest ]};
- _ ->
- {error, ?NICE(httpd_conf:clean(Type)++" is an invalid AuthDBType")}
- end;
-
-load("require " ++ Require,[{directory, {Directory, DirData}}|Rest]) ->
- case inets_regexp:split(Require," ") of
- {ok,["user"|Users]} ->
- {ok,[{directory, {Directory,
- [{require_user,Users}|DirData]}} | Rest]};
- {ok,["group"|Groups]} ->
- {ok,[{directory, {Directory,
- [{require_group,Groups}|DirData]}} | Rest]};
- {ok,_} ->
- {error,?NICE(httpd_conf:clean(Require) ++" is an invalid require")}
- end;
-
-load("allow " ++ Allow,[{directory, {Directory, DirData}}|Rest]) ->
- case inets_regexp:split(Allow," ") of
- {ok,["from","all"]} ->
- {ok,[{directory, {Directory,
- [{allow_from,all}|DirData]}} | Rest]};
- {ok,["from"|Hosts]} ->
- {ok,[{directory, {Directory,
- [{allow_from,Hosts}|DirData]}} | Rest]};
- {ok,_} ->
- {error,?NICE(httpd_conf:clean(Allow) ++" is an invalid allow")}
- end;
-
-load("deny " ++ Deny,[{directory, {Directory, DirData}}|Rest]) ->
- case inets_regexp:split(Deny," ") of
- {ok, ["from", "all"]} ->
- {ok,[{{directory, Directory,
- [{deny_from, all}|DirData]}} | Rest]};
- {ok, ["from"|Hosts]} ->
- {ok,[{{directory, Directory,
- [{deny_from, Hosts}|DirData]}} | Rest]};
- {ok, _} ->
- {error,?NICE(httpd_conf:clean(Deny) ++" is an invalid deny")}
- end;
-
-load("</Directory>",[{directory, {Directory, DirData}}|Rest]) ->
- {ok, Rest, {directory, {Directory, DirData}}};
-
-load("AuthMnesiaDB " ++ AuthMnesiaDB,
- [{directory, {Dir, DirData}}|Rest]) ->
- case httpd_conf:clean(AuthMnesiaDB) of
- "On" ->
- {ok,[{directory, {Dir,[{auth_type,mnesia}|DirData]}}|Rest]};
- "Off" ->
- {ok,[{directory, {Dir,[{auth_type,plain}|DirData]}}|Rest]};
- _ ->
- {error, ?NICE(httpd_conf:clean(AuthMnesiaDB) ++
- " is an invalid AuthMnesiaDB")}
- end.
directory_config_check(Directory, DirData) ->
case proplists:get_value(auth_type, DirData) of
@@ -482,25 +621,7 @@ check_filename_present(Dir,AuthFile,DirData) ->
throw({missing_auth_file, AuthFile, {directory, {Dir, DirData}}})
end.
-%% store
-
-store({directory, {Directory, DirData}}, ConfigList)
- when is_list(Directory) andalso is_list(DirData) ->
- ?hdrt("store",
- [{directory, Directory}, {dir_data, DirData}]),
- try directory_config_check(Directory, DirData) of
- ok ->
- store_directory(Directory, DirData, ConfigList)
- catch
- throw:Error ->
- {error, Error, {directory, Directory, DirData}}
- end;
-store({directory, {Directory, DirData}}, _) ->
- {error, {wrong_type, {directory, {Directory, DirData}}}}.
-
store_directory(Directory0, DirData0, ConfigList) ->
- ?hdrt("store directory - entry",
- [{directory, Directory0}, {dir_data, DirData0}]),
Port = proplists:get_value(port, ConfigList),
DirData = case proplists:get_value(bind_address, ConfigList) of
undefined ->
@@ -522,9 +643,7 @@ store_directory(Directory0, DirData0, ConfigList) ->
dets -> mod_auth_dets;
plain -> mod_auth_plain;
_ -> no_module_at_all
- end,
- ?hdrt("store directory",
- [{directory, Directory}, {dir_data, DirData}, {auth_mod, AuthMod}]),
+ end,
case AuthMod of
no_module_at_all ->
{ok, {directory, {Directory, DirData}}};
@@ -560,204 +679,10 @@ store_directory(Directory0, DirData0, ConfigList) ->
add_auth_password(Dir, Pwd0, ConfigList) ->
Addr = proplists:get_value(bind_address, ConfigList),
Port = proplists:get_value(port, ConfigList),
- mod_auth_server:start(Addr, Port),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
+ mod_auth_server:start(Addr, Port, Profile),
mod_auth_server:add_password(Addr, Port, Dir, Pwd0).
-%% remove
-
-
-remove(ConfigDB) ->
- lists:foreach(fun({directory, {_Dir, DirData}}) ->
- AuthMod = auth_mod_name(DirData),
- (catch apply(AuthMod, remove, [DirData]))
- end,
- ets:match_object(ConfigDB,{directory,{'_','_'}})),
- Addr = case lookup(ConfigDB, bind_address) of
- [] ->
- undefined;
- [{bind_address, Address}] ->
- Address
- end,
- [{port, Port}] = lookup(ConfigDB, port),
- mod_auth_server:stop(Addr, Port),
- ok.
-
-%% --------------------------------------------------------------------
-
-%% update_password
-
-update_password(Port, Dir, Old, New, New)->
- update_password(undefined, Port, Dir, Old, New, New).
-
-update_password(Addr, Port, Dir, Old, New, New) when is_list(New) ->
- mod_auth_server:update_password(Addr, Port, Dir, Old, New);
-
-update_password(_Addr, _Port, _Dir, _Old, _New, _New) ->
- {error, badtype};
-update_password(_Addr, _Port, _Dir, _Old, _New, _New1) ->
- {error, notqeual}.
-
-
-%% add_user
-
-add_user(UserName, Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd}->
- case get_options(Opt, userData) of
- {error, Reason}->
- {error, Reason};
- {UserData, Password}->
- User = [#httpd_user{username = UserName,
- password = Password,
- user_data = UserData}],
- mod_auth_server:add_user(Addr, Port, Dir, User, AuthPwd)
- end
- end.
-
-
-add_user(UserName, Password, UserData, Port, Dir) ->
- add_user(UserName, Password, UserData, undefined, Port, Dir).
-add_user(UserName, Password, UserData, Addr, Port, Dir) ->
- User = [#httpd_user{username = UserName,
- password = Password,
- user_data = UserData}],
- mod_auth_server:add_user(Addr, Port, Dir, User, ?NOPASSWORD).
-
-
-%% get_user
-
-get_user(UserName, Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:get_user(Addr, Port, Dir, UserName, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-get_user(UserName, Port, Dir) ->
- get_user(UserName, undefined, Port, Dir).
-get_user(UserName, Addr, Port, Dir) ->
- mod_auth_server:get_user(Addr, Port, Dir, UserName, ?NOPASSWORD).
-
-
-%% add_group_member
-
-add_group_member(GroupName, UserName, Opt)->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd}->
- mod_auth_server:add_group_member(Addr, Port, Dir,
- GroupName, UserName, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-add_group_member(GroupName, UserName, Port, Dir) ->
- add_group_member(GroupName, UserName, undefined, Port, Dir).
-
-add_group_member(GroupName, UserName, Addr, Port, Dir) ->
- mod_auth_server:add_group_member(Addr, Port, Dir,
- GroupName, UserName, ?NOPASSWORD).
-
-
-%% delete_group_member
-
-delete_group_member(GroupName, UserName, Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:delete_group_member(Addr, Port, Dir,
- GroupName, UserName, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-delete_group_member(GroupName, UserName, Port, Dir) ->
- delete_group_member(GroupName, UserName, undefined, Port, Dir).
-delete_group_member(GroupName, UserName, Addr, Port, Dir) ->
- mod_auth_server:delete_group_member(Addr, Port, Dir,
- GroupName, UserName, ?NOPASSWORD).
-
-
-%% list_users
-
-list_users(Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:list_users(Addr, Port, Dir, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-list_users(Port, Dir) ->
- list_users(undefined, Port, Dir).
-list_users(Addr, Port, Dir) ->
- mod_auth_server:list_users(Addr, Port, Dir, ?NOPASSWORD).
-
-
-%% delete_user
-
-delete_user(UserName, Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:delete_user(Addr, Port, Dir, UserName, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-delete_user(UserName, Port, Dir) ->
- delete_user(UserName, undefined, Port, Dir).
-delete_user(UserName, Addr, Port, Dir) ->
- mod_auth_server:delete_user(Addr, Port, Dir, UserName, ?NOPASSWORD).
-
-
-%% delete_group
-
-delete_group(GroupName, Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:delete_group(Addr, Port, Dir, GroupName, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-delete_group(GroupName, Port, Dir) ->
- delete_group(GroupName, undefined, Port, Dir).
-delete_group(GroupName, Addr, Port, Dir) ->
- mod_auth_server:delete_group(Addr, Port, Dir, GroupName, ?NOPASSWORD).
-
-
-%% list_groups
-
-list_groups(Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:list_groups(Addr, Port, Dir, AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-list_groups(Port, Dir) ->
- list_groups(undefined, Port, Dir).
-list_groups(Addr, Port, Dir) ->
- mod_auth_server:list_groups(Addr, Port, Dir, ?NOPASSWORD).
-
-
-%% list_group_members
-
-list_group_members(GroupName, Opt) ->
- case get_options(Opt, mandatory) of
- {Addr, Port, Dir, AuthPwd} ->
- mod_auth_server:list_group_members(Addr, Port, Dir, GroupName,
- AuthPwd);
- {error, Reason} ->
- {error, Reason}
- end.
-
-list_group_members(GroupName, Port, Dir) ->
- list_group_members(GroupName, undefined, Port, Dir).
-list_group_members(GroupName, Addr, Port, Dir) ->
- mod_auth_server:list_group_members(Addr, Port, Dir,
- GroupName, ?NOPASSWORD).
-
%% Opt = [{port, Port},
%% {addr, Addr},
%% {dir, Dir},
@@ -792,7 +717,3 @@ get_options(Opt, userData)->
{UserData, Pwd}
end
end.
-
-
-lookup(Db, Key) ->
- ets:lookup(Db, Key).
diff --git a/lib/inets/src/http_server/mod_auth.hrl b/lib/inets/src/http_server/mod_auth.hrl
index 674e6d1652..88554a64ed 100644
--- a/lib/inets/src/http_server/mod_auth.hrl
+++ b/lib/inets/src/http_server/mod_auth.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/http_server/mod_auth_dets.erl b/lib/inets/src/http_server/mod_auth_dets.erl
index a48725d5d9..95a2cdd669 100644
--- a/lib/inets/src/http_server/mod_auth_dets.erl
+++ b/lib/inets/src/http_server/mod_auth_dets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -38,23 +39,23 @@
-include("httpd_internal.hrl").
-include("mod_auth.hrl").
-store_directory_data(_Directory, DirData, Server_root) ->
- ?CDEBUG("store_directory_data -> ~n"
- " Directory: ~p~n"
- " DirData: ~p",
- [_Directory, DirData]),
+%%====================================================================
+%% Internal application API
+%%====================================================================
+store_directory_data(_Directory, DirData, Server_root) ->
{PWFile, Absolute_pwdfile} = absolute_file_name(auth_user_file, DirData,
Server_root),
{GroupFile, Absolute_groupfile} = absolute_file_name(auth_group_file,
DirData, Server_root),
Addr = proplists:get_value(bind_address, DirData),
Port = proplists:get_value(port, DirData),
+ Profile = proplists:get_value(profile, DirData, ?DEFAULT_PROFILE),
- PWName = httpd_util:make_name("httpd_dets_pwdb",Addr,Port),
+ PWName = httpd_util:make_name("httpd_dets_pwdb", Addr, Port, Profile),
case dets:open_file(PWName,[{type,set},{file,Absolute_pwdfile},{repair,true}]) of
{ok, PWDB} ->
- GDBName = httpd_util:make_name("httpd_dets_groupdb",Addr,Port),
+ GDBName = httpd_util:make_name("httpd_dets_groupdb", Addr, Port, Profile),
case dets:open_file(GDBName,[{type,set},{file,Absolute_groupfile},{repair,true}]) of
{ok, GDB} ->
NDD1 = lists:keyreplace(auth_user_file, 1, DirData,
@@ -69,11 +70,8 @@ store_directory_data(_Directory, DirData, Server_root) ->
{error, {{file, PWFile},Err2}}
end.
-%%
%% Storage format of users in the dets table:
%% {{UserName, Addr, Port, Dir}, Password, UserData}
-%%
-
add_user(DirData, UStruct) ->
{Addr, Port, Dir} = lookup_common(DirData),
PWDB = proplists:get_value(auth_user_file, DirData),
@@ -99,21 +97,15 @@ get_user(DirData, UserName) ->
end.
list_users(DirData) ->
- ?DEBUG("list_users -> ~n"
- " DirData: ~p", [DirData]),
{Addr, Port, Dir} = lookup_common(DirData),
PWDB = proplists:get_value(auth_user_file, DirData),
- case dets:traverse(PWDB, fun(X) -> {continue, X} end) of %% SOOOO Ugly !
+ case dets:traverse(PWDB, fun(X) -> {continue, X} end) of
Records when is_list(Records) ->
- ?DEBUG("list_users -> ~n"
- " Records: ~p", [Records]),
{ok, [UserName || {{UserName, AnyAddr, AnyPort, AnyDir},
_Password, _Data} <- Records,
AnyAddr == Addr, AnyPort == Port,
AnyDir == Dir]};
_O ->
- ?DEBUG("list_users -> ~n"
- " O: ~p", [_O]),
{ok, []}
end.
@@ -134,10 +126,8 @@ delete_user(DirData, UserName) ->
{error, no_such_user}
end.
-%%
%% Storage of groups in the dets table:
%% {Group, UserList} where UserList is a list of strings.
-%%
add_group_member(DirData, GroupName, UserName) ->
{Addr, Port, Dir} = lookup_common(DirData),
GDB = proplists:get_value(auth_group_file, DirData),
@@ -215,16 +205,7 @@ delete_group(DirData, GroupName) ->
{error, no_such_group}
end.
-lookup_common(DirData) ->
- Dir = proplists:get_value(path, DirData),
- Port = proplists:get_value(port, DirData),
- Addr = proplists:get_value(bind_address, DirData),
- {Addr, Port, Dir}.
-
-%% remove/1
-%%
%% Closes dets tables used by this auth mod.
-%%
remove(DirData) ->
PWDB = proplists:get_value(auth_user_file, DirData),
GDB = proplists:get_value(auth_group_file, DirData),
@@ -232,8 +213,9 @@ remove(DirData) ->
dets:close(PWDB),
ok.
-%% absolute_file_name/2
-%%
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
%% Return the absolute path name of File_type.
absolute_file_name(File_type, DirData, Server_root) ->
Path = proplists:get_value(File_type, DirData),
@@ -253,3 +235,8 @@ absolute_file_name(File_type, DirData, Server_root) ->
end,
{Path, Absolute_path}.
+lookup_common(DirData) ->
+ Dir = proplists:get_value(path, DirData),
+ Port = proplists:get_value(port, DirData),
+ Addr = proplists:get_value(bind_address, DirData),
+ {Addr, Port, Dir}.
diff --git a/lib/inets/src/http_server/mod_auth_mnesia.erl b/lib/inets/src/http_server/mod_auth_mnesia.erl
index 91beb0e062..994f25a462 100644
--- a/lib/inets/src/http_server/mod_auth_mnesia.erl
+++ b/lib/inets/src/http_server/mod_auth_mnesia.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/mod_auth_plain.erl b/lib/inets/src/http_server/mod_auth_plain.erl
index c0a83711ba..1a3120e03c 100644
--- a/lib/inets/src/http_server/mod_auth_plain.erl
+++ b/lib/inets/src/http_server/mod_auth_plain.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -22,15 +23,11 @@
-include("httpd.hrl").
-include("mod_auth.hrl").
-include("httpd_internal.hrl").
--include("inets_internal.hrl").
-
-define(VMODULE,"AUTH_PLAIN").
%% Internal API
-export([store_directory_data/3]).
-
-
-export([get_user/2,
list_group_members/2,
add_user/2,
@@ -42,17 +39,13 @@
delete_group/2,
remove/1]).
-%%
-%% API
-%%
+%%====================================================================
+%% Internal application API
+%%====================================================================
-%%
%% Storage format of users in the ets table:
%% {UserName, Password, UserData}
-%%
-
add_user(DirData, #httpd_user{username = User} = UStruct) ->
- ?hdrt("add user", [{user, UStruct}]),
PWDB = proplists:get_value(auth_user_file, DirData),
Record = {User,
UStruct#httpd_user.password,
@@ -66,7 +59,6 @@ add_user(DirData, #httpd_user{username = User} = UStruct) ->
end.
get_user(DirData, User) ->
- ?hdrt("get user", [{dir_data, DirData}, {user, User}]),
PWDB = proplists:get_value(auth_user_file, DirData),
case ets:lookup(PWDB, User) of
[{User, PassWd, Data}] ->
@@ -84,7 +76,6 @@ list_users(DirData) ->
[], lists:flatten(Records))}.
delete_user(DirData, UserName) ->
- ?hdrt("delete user", [{dir_data, DirData}, {user, UserName}]),
PWDB = proplists:get_value(auth_user_file, DirData),
case ets:lookup(PWDB, UserName) of
[{UserName, _SomePassword, _SomeData}] ->
@@ -98,11 +89,8 @@ delete_user(DirData, UserName) ->
{error, no_such_user}
end.
-%%
%% Storage of groups in the ets table:
%% {Group, UserList} where UserList is a list of strings.
-%%
-
add_group_member(DirData, Group, UserName) ->
GDB = proplists:get_value(auth_group_file, DirData),
case ets:lookup(GDB, Group) of
@@ -163,17 +151,12 @@ delete_group(DirData, Group) ->
end.
store_directory_data(_Directory, DirData, Server_root) ->
- ?hdrt("store directory data",
- [{dir_data, DirData}, {server_root, Server_root}]),
PWFile = absolute_file_name(auth_user_file, DirData, Server_root),
GroupFile = absolute_file_name(auth_group_file, DirData, Server_root),
case load_passwd(PWFile) of
{ok, PWDB} ->
- ?hdrt("password file loaded", [{file, PWFile}, {pwdb, PWDB}]),
case load_group(GroupFile) of
{ok, GRDB} ->
- ?hdrt("group file loaded",
- [{file, GroupFile}, {grdb, GRDB}]),
%% Address and port is included in the file names...
Addr = proplists:get_value(bind_address, DirData),
Port = proplists:get_value(port, DirData),
@@ -191,9 +174,83 @@ store_directory_data(_Directory, DirData, Server_root) ->
{error, Err2}
end.
+%% Deletes ets tables used by this auth mod.
+remove(DirData) ->
+ PWDB = proplists:get_value(auth_user_file, DirData),
+ GDB = proplists:get_value(auth_group_file, DirData),
+ ets:delete(PWDB),
+ ets:delete(GDB).
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+%% Return the absolute path name of File_type.
+absolute_file_name(File_type, DirData, Server_root) ->
+ Path = proplists:get_value(File_type, DirData),
+ case filename:pathtype(Path) of
+ relative ->
+ case Server_root of
+ undefined ->
+ {error,
+ ?NICE(Path++
+ " is an invalid file name because "
+ "ServerRoot is not defined")};
+ _ ->
+ filename:join(Server_root,Path)
+ end;
+ _ ->
+ Path
+ end.
+
+store_group(Addr,Port,GroupList) ->
+ %% Not a named table so not importante to add Profile to name
+ Name = httpd_util:make_name("httpd_group",Addr,Port),
+ GroupDB = ets:new(Name, [set, public]),
+ store_group(GroupDB, GroupList).
+
+store_group(GroupDB,[]) ->
+ {ok, GroupDB};
+store_group(GroupDB, [User|Rest]) ->
+ ets:insert(GroupDB, User),
+ store_group(GroupDB, Rest).
+
+store_passwd(Addr,Port,PasswdList) ->
+ %% Not a named table so not importante to add Profile to name
+ Name = httpd_util:make_name("httpd_passwd",Addr,Port),
+ PasswdDB = ets:new(Name, [set, public]),
+ store_passwd(PasswdDB, PasswdList).
+
+store_passwd(PasswdDB, []) ->
+ {ok, PasswdDB};
+store_passwd(PasswdDB, [User|Rest]) ->
+ ets:insert(PasswdDB, User),
+ store_passwd(PasswdDB, Rest).
+parse_group(Stream, GroupList) ->
+ Line =
+ case io:get_line(Stream,'') of
+ eof ->
+ eof;
+ String ->
+ httpd_conf:white_space_clean(String)
+ end,
+ parse_group(Stream, GroupList, Line).
-%% load_passwd
+parse_group(Stream, GroupList, eof) ->
+ file:close(Stream),
+ {ok, GroupList};
+parse_group(Stream, GroupList, "") ->
+ parse_group(Stream, GroupList);
+parse_group(Stream, GroupList, [$#|_]) ->
+ parse_group(Stream, GroupList);
+parse_group(Stream, GroupList, Line) ->
+ case re:split(Line, ":", [{return, list}]) of
+ [Group,Users] ->
+ UserList = re:split(Users," ", [{return, list}]),
+ parse_group(Stream, [{Group,UserList}|GroupList]);
+ _ ->
+ {error, ?NICE(Line)}
+ end.
load_passwd(AuthUserFile) ->
case file:open(AuthUserFile, [read]) of
@@ -209,7 +266,7 @@ parse_passwd(Stream, PasswdList) ->
eof ->
eof;
String ->
- httpd_conf:clean(String)
+ httpd_conf:white_space_clean(String)
end,
parse_passwd(Stream, PasswdList, Line).
@@ -221,15 +278,13 @@ parse_passwd(Stream, PasswdList, "") ->
parse_passwd(Stream, PasswdList, [$#|_]) ->
parse_passwd(Stream, PasswdList);
parse_passwd(Stream, PasswdList, Line) ->
- case inets_regexp:split(Line,":") of
- {ok, [User,Password]} ->
+ case re:split(Line,":", [{return, list}]) of
+ [User,Password] ->
parse_passwd(Stream, [{User,Password, []}|PasswdList]);
- {ok,_} ->
+ _ ->
{error, ?NICE(Line)}
end.
-%% load_group
-
load_group(AuthGroupFile) ->
case file:open(AuthGroupFile, [read]) of
{ok, Stream} ->
@@ -237,91 +292,3 @@ load_group(AuthGroupFile) ->
{error, _} ->
{error, ?NICE("Can't open " ++ AuthGroupFile)}
end.
-
-parse_group(Stream, GroupList) ->
- Line =
- case io:get_line(Stream,'') of
- eof ->
- eof;
- String ->
- httpd_conf:clean(String)
- end,
- parse_group(Stream, GroupList, Line).
-
-parse_group(Stream, GroupList, eof) ->
- file:close(Stream),
- {ok, GroupList};
-parse_group(Stream, GroupList, "") ->
- parse_group(Stream, GroupList);
-parse_group(Stream, GroupList, [$#|_]) ->
- parse_group(Stream, GroupList);
-parse_group(Stream, GroupList, Line) ->
- case inets_regexp:split(Line, ":") of
- {ok, [Group,Users]} ->
- {ok, UserList} = inets_regexp:split(Users," "),
- parse_group(Stream, [{Group,UserList}|GroupList]);
- {ok, _} ->
- {error, ?NICE(Line)}
- end.
-
-
-%% store_passwd
-
-store_passwd(Addr,Port,PasswdList) ->
- Name = httpd_util:make_name("httpd_passwd",Addr,Port),
- PasswdDB = ets:new(Name, [set, public]),
- store_passwd(PasswdDB, PasswdList).
-
-store_passwd(PasswdDB, []) ->
- {ok, PasswdDB};
-store_passwd(PasswdDB, [User|Rest]) ->
- ets:insert(PasswdDB, User),
- store_passwd(PasswdDB, Rest).
-
-%% store_group
-
-store_group(Addr,Port,GroupList) ->
- Name = httpd_util:make_name("httpd_group",Addr,Port),
- GroupDB = ets:new(Name, [set, public]),
- store_group(GroupDB, GroupList).
-
-
-store_group(GroupDB,[]) ->
- {ok, GroupDB};
-store_group(GroupDB, [User|Rest]) ->
- ets:insert(GroupDB, User),
- store_group(GroupDB, Rest).
-
-
-%% remove/1
-%%
-%% Deletes ets tables used by this auth mod.
-%%
-remove(DirData) ->
- PWDB = proplists:get_value(auth_user_file, DirData),
- GDB = proplists:get_value(auth_group_file, DirData),
- ets:delete(PWDB),
- ets:delete(GDB).
-
-
-
-%% absolute_file_name/2
-%%
-%% Return the absolute path name of File_type.
-absolute_file_name(File_type, DirData, Server_root) ->
- Path = proplists:get_value(File_type, DirData),
- case filename:pathtype(Path) of
- relative ->
- case Server_root of
- undefined ->
- {error,
- ?NICE(Path++
- " is an invalid file name because "
- "ServerRoot is not defined")};
- _ ->
- filename:join(Server_root,Path)
- end;
- _ ->
- Path
- end.
-
diff --git a/lib/inets/src/http_server/mod_auth_server.erl b/lib/inets/src/http_server/mod_auth_server.erl
index 947273bd9e..7d1e1a3431 100644
--- a/lib/inets/src/http_server/mod_auth_server.erl
+++ b/lib/inets/src/http_server/mod_auth_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -22,246 +23,184 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
--include("inets_internal.hrl").
-behaviour(gen_server).
-
%% mod_auth exports
--export([start/2, stop/2,
+-export([start/3, stop/3,
add_password/4, update_password/5,
add_user/5, delete_user/5, get_user/5, list_users/4,
add_group_member/6, delete_group_member/6, list_group_members/5,
delete_group/5, list_groups/4]).
%% gen_server exports
--export([start_link/2, init/1,
+-export([start_link/3, init/1,
handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record(state, {tab}).
+%%====================================================================
+%% Internal application API
+%%====================================================================
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%% External API %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% start_link/3
-%%
%% NOTE: This is called by httpd_misc_sup when the process is started
%%
-start_link(Addr, Port) ->
- ?hdrt("start_link", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+start_link(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
gen_server:start_link({local, Name}, ?MODULE, [], [{timeout, infinity}]).
-
-%% start/2
-
-start(Addr, Port) ->
- ?hdrd("start", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+start(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
case whereis(Name) of
undefined ->
- httpd_misc_sup:start_auth_server(Addr, Port);
+ httpd_misc_sup:start_auth_server(Addr, Port, Profile);
_ -> %% Already started...
ok
end.
-
-%% stop/2
-
-stop(Addr, Port) ->
- ?hdrd("stop", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+stop(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
case whereis(Name) of
undefined -> %% Already stopped
ok;
_ ->
- (catch httpd_misc_sup:stop_auth_server(Addr, Port))
+ (catch httpd_misc_sup:stop_auth_server(Addr, Port, Profile))
end.
-%% add_password/4
-
add_password(Addr, Port, Dir, Password) ->
- ?hdrt("add password", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+ add_password(Addr, Port, ?DEFAULT_PROFILE, Dir, Password).
+add_password(Addr, Port, Profile, Dir, Password) ->
+ Name = make_name(Addr, Port, Profile),
Req = {add_password, Dir, Password},
call(Name, Req).
-
-%% update_password/6
-
-update_password(Addr, Port, Dir, Old, New) when is_list(New) ->
- ?hdrt("update password",
- [{address, Addr}, {port, Port}, {dir, Dir}, {old, Old}, {new, New}]),
- Name = make_name(Addr, Port),
+update_password(Addr, Port, Dir, Old, New) ->
+ update_password(Addr, Port, ?DEFAULT_PROFILE, Dir, Old, New).
+update_password(Addr, Port, Profile, Dir, Old, New) when is_list(New) ->
+ Name = make_name(Addr, Port, Profile),
Req = {update_password, Dir, Old, New},
call(Name, Req).
-
-
-%% add_user/5
add_user(Addr, Port, Dir, User, Password) ->
- ?hdrt("add user",
- [{address, Addr}, {port, Port},
- {dir, Dir}, {user, User}, {passwd, Password}]),
- Name = make_name(Addr, Port),
- Req = {add_user, Addr, Port, Dir, User, Password},
+ add_user(Addr, Port, ?DEFAULT_PROFILE, Dir, User, Password).
+add_user(Addr, Port, Profile, Dir, User, Password) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {add_user, Addr, Port, Profile, Dir, User, Password},
call(Name, Req).
-
-%% delete_user/5
-
delete_user(Addr, Port, Dir, UserName, Password) ->
- ?hdrt("delete user",
- [{address, Addr}, {port, Port},
- {dir, Dir}, {user, UserName}, {passwd, Password}]),
- Name = make_name(Addr, Port),
- Req = {delete_user, Addr, Port, Dir, UserName, Password},
+ delete_user(Addr, Port, ?DEFAULT_PROFILE, Dir, UserName, Password).
+delete_user(Addr, Port, Profile, Dir, UserName, Password) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {delete_user, Addr, Port, Profile, Dir, UserName, Password},
call(Name, Req).
-
-%% get_user/5
-
get_user(Addr, Port, Dir, UserName, Password) ->
- ?hdrt("get user",
- [{address, Addr}, {port, Port},
- {dir, Dir}, {user, UserName}, {passwd, Password}]),
- Name = make_name(Addr, Port),
- Req = {get_user, Addr, Port, Dir, UserName, Password},
+ get_user(Addr, Port, ?DEFAULT_PROFILE, Dir, UserName, Password).
+get_user(Addr, Port, Profile,Dir, UserName, Password) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {get_user, Addr, Port, Profile, Dir, UserName, Password},
call(Name, Req).
-
-%% list_users/4
-
list_users(Addr, Port, Dir, Password) ->
- ?hdrt("list users",
- [{address, Addr}, {port, Port}, {dir, Dir}, {passwd, Password}]),
- Name = make_name(Addr,Port),
- Req = {list_users, Addr, Port, Dir, Password},
+ list_users(Addr, Port, ?DEFAULT_PROFILE, Dir, Password).
+list_users(Addr, Port, Profile, Dir, Password) ->
+ Name = make_name(Addr,Port, Profile),
+ Req = {list_users, Addr, Port, Profile, Dir, Password},
call(Name, Req).
-
-%% add_group_member/6
-
add_group_member(Addr, Port, Dir, GroupName, UserName, Password) ->
- ?hdrt("add group member",
- [{address, Addr}, {port, Port}, {dir, Dir},
- {group, GroupName}, {user, UserName}, {passwd, Password}]),
- Name = make_name(Addr,Port),
- Req = {add_group_member, Addr, Port, Dir, GroupName, UserName, Password},
+ add_group_member(Addr, Port, ?DEFAULT_PROFILE, Dir, GroupName, UserName, Password).
+add_group_member(Addr, Port, Profile, Dir, GroupName, UserName, Password) ->
+ Name = make_name(Addr,Port, Profile),
+ Req = {add_group_member, Addr, Port, Profile, Dir, GroupName, UserName, Password},
call(Name, Req).
-
-%% delete_group_member/6
-
delete_group_member(Addr, Port, Dir, GroupName, UserName, Password) ->
- ?hdrt("delete group member",
- [{address, Addr}, {port, Port}, {dir, Dir},
- {group, GroupName}, {user, UserName}, {passwd, Password}]),
- Name = make_name(Addr,Port),
- Req = {delete_group_member, Addr, Port, Dir, GroupName, UserName, Password},
+ delete_group_member(Addr, Port, ?DEFAULT_PROFILE, Dir, GroupName, UserName, Password).
+delete_group_member(Addr, Port, Profile, Dir, GroupName, UserName, Password) ->
+ Name = make_name(Addr,Port,Profile),
+ Req = {delete_group_member, Addr, Port, Profile, Dir, GroupName, UserName, Password},
call(Name, Req).
-
-%% list_group_members/4
-
list_group_members(Addr, Port, Dir, Group, Password) ->
- ?hdrt("list group members",
- [{address, Addr}, {port, Port}, {dir, Dir},
- {group, Group}, {passwd, Password}]),
- Name = make_name(Addr, Port),
+ list_group_members(Addr, Port, ?DEFAULT_PROFILE, Dir, Group, Password).
+list_group_members(Addr, Port, Profile, Dir, Group, Password) ->
+ Name = make_name(Addr, Port, Profile),
Req = {list_group_members, Addr, Port, Dir, Group, Password},
call(Name, Req).
-
-%% delete_group/5
-
delete_group(Addr, Port, Dir, GroupName, Password) ->
- ?hdrt("delete group",
- [{address, Addr}, {port, Port}, {dir, Dir},
- {group, GroupName}, {passwd, Password}]),
- Name = make_name(Addr, Port),
- Req = {delete_group, Addr, Port, Dir, GroupName, Password},
+ delete_group(Addr, Port, ?DEFAULT_PROFILE, Dir, GroupName, Password).
+delete_group(Addr, Port, Profile, Dir, GroupName, Password) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {delete_group, Addr, Port, Profile, Dir, GroupName, Password},
call(Name, Req).
-
-%% list_groups/4
-
list_groups(Addr, Port, Dir, Password) ->
- ?hdrt("list groups",
- [{address, Addr}, {port, Port}, {dir, Dir}, {passwd, Password}]),
- Name = make_name(Addr, Port),
- Req = {list_groups, Addr, Port, Dir, Password},
+ list_groups(Addr, Port, ?DEFAULT_PROFILE, Dir, Password).
+list_groups(Addr, Port, Profile, Dir, Password) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {list_groups, Addr, Port,Profile, Dir, Password},
call(Name, Req).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%% Server call-back functions %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% init
-
+%%====================================================================
+%% Behavior call backs
+%%====================================================================
init(_) ->
- ?hdrv("initiating", []),
{ok,#state{tab = ets:new(auth_pwd,[set,protected])}}.
%% handle_call
%% Add a user
-handle_call({add_user, Addr, Port, Dir, User, AuthPwd}, _From, State) ->
- Reply = api_call(Addr, Port, Dir, add_user, User, AuthPwd, State),
- ?hdrt("add user", [{reply, Reply}]),
+handle_call({add_user, Addr, Port, Profile, Dir, User, AuthPwd}, _From, State) ->
+ Reply = api_call(Addr, Port, Profile, Dir, add_user, User, AuthPwd, State),
{reply, Reply, State};
%% Get data about a user
-handle_call({get_user, Addr, Port, Dir, User, AuthPwd}, _From, State) ->
- Reply = api_call(Addr, Port, Dir, get_user, [User], AuthPwd, State),
+handle_call({get_user, Addr, Port, Profile, Dir, User, AuthPwd}, _From, State) ->
+ Reply = api_call(Addr, Port, Profile, Dir, get_user, [User], AuthPwd, State),
{reply, Reply, State};
%% Add a group member
-handle_call({add_group_member, Addr, Port, Dir, Group, User, AuthPwd},
+handle_call({add_group_member, Addr, Port, Profile, Dir, Group, User, AuthPwd},
_From, State) ->
- Reply = api_call(Addr, Port, Dir, add_group_member, [Group, User],
+ Reply = api_call(Addr, Port, Profile, Dir, add_group_member, [Group, User],
AuthPwd, State),
{reply, Reply, State};
%% delete a group
-handle_call({delete_group_member, Addr, Port, Dir, Group, User, AuthPwd},
+handle_call({delete_group_member, Addr, Port, Profile, Dir, Group, User, AuthPwd},
_From, State) ->
- Reply = api_call(Addr, Port, Dir, delete_group_member, [Group, User],
+ Reply = api_call(Addr, Port, Profile, Dir, delete_group_member, [Group, User],
AuthPwd, State),
{reply, Reply, State};
%% List all users thats standalone users
-handle_call({list_users, Addr, Port, Dir, AuthPwd}, _From, State) ->
- Reply = api_call(Addr, Port, Dir, list_users, [], AuthPwd, State),
+handle_call({list_users, Addr, Port, Profile, Dir, AuthPwd}, _From, State) ->
+ Reply = api_call(Addr, Port, Profile, Dir, list_users, [], AuthPwd, State),
{reply, Reply, State};
%% Delete a user
-handle_call({delete_user, Addr, Port, Dir, User, AuthPwd}, _From, State) ->
- Reply = api_call(Addr, Port, Dir, delete_user, [User], AuthPwd, State),
+handle_call({delete_user, Addr, Port, Profile, Dir, User, AuthPwd}, _From, State) ->
+ Reply = api_call(Addr, Port, Profile, Dir, delete_user, [User], AuthPwd, State),
{reply, Reply, State};
%% Delete a group
-handle_call({delete_group, Addr, Port, Dir, Group, AuthPwd}, _From, State) ->
- Reply = api_call(Addr, Port, Dir, delete_group, [Group], AuthPwd, State),
+handle_call({delete_group, Addr, Port, Profile, Dir, Group, AuthPwd}, _From, State) ->
+ Reply = api_call(Addr, Port, Profile, Dir, delete_group, [Group], AuthPwd, State),
{reply, Reply, State};
%% List the current groups
-handle_call({list_groups, Addr, Port, Dir, AuthPwd}, _From, State) ->
- Reply = api_call(Addr, Port, Dir, list_groups, [], AuthPwd, State),
+handle_call({list_groups, Addr, Port, Profile, Dir, AuthPwd}, _From, State) ->
+ Reply = api_call(Addr, Port, Profile, Dir, list_groups, [], AuthPwd, State),
{reply, Reply, State};
%% List the members of the given group
-handle_call({list_group_members, Addr, Port, Dir, Group, AuthPwd},
+handle_call({list_group_members, Addr, Port, Profile, Dir, Group, AuthPwd},
_From, State) ->
- Reply = api_call(Addr, Port, Dir, list_group_members, [Group],
+ Reply = api_call(Addr, Port, Profile, Dir, list_group_members, [Group],
AuthPwd, State),
{reply, Reply, State};
@@ -306,26 +245,16 @@ terminate(_Reason,State) ->
ets:delete(State#state.tab),
ok.
-
-%% code_change(Vsn, State, Extra)
-%%
code_change(_Vsn, State, _Extra) ->
{ok, State}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%% The functions that really changes the data in the database %%
-%% of users to different directories %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% API gateway
-
-api_call(Addr, Port, Dir, Func, Args,Password,State) ->
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+api_call(Addr, Port, Profile, Dir, Func, Args,Password,State) ->
case controlPassword(Password, State, Dir) of
ok->
- ConfigName = httpd_util:make_name("httpd_conf", Addr, Port),
+ ConfigName = httpd_util:make_name("httpd_conf", Addr, Port, Profile),
case ets:match_object(ConfigName, {directory, {Dir, '$1'}}) of
[{directory, {Dir, DirData}}] ->
AuthMod = auth_mod_name(DirData),
@@ -386,8 +315,8 @@ lookup(Db, Key) ->
ets:lookup(Db, Key).
-make_name(Addr,Port) ->
- httpd_util:make_name("httpd_auth",Addr,Port).
+make_name(Addr, Port, Profile) ->
+ httpd_util:make_name(?MODULE_STRING, Addr, Port, Profile).
call(Name, Req) ->
@@ -397,5 +326,3 @@ call(Name, Req) ->
Reply ->
Reply
end.
-
-
diff --git a/lib/inets/src/http_server/mod_browser.erl b/lib/inets/src/http_server/mod_browser.erl
index 1c9b33dffa..e3c41793ae 100644
--- a/lib/inets/src/http_server/mod_browser.erl
+++ b/lib/inets/src/http_server/mod_browser.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -97,9 +98,9 @@ getBrowser1(Info) ->
getBrowser(AgentString) ->
LAgentString = http_util:to_lower(AgentString),
- case inets_regexp:first_match(LAgentString,"^[^ ]*") of
- {match,Start,Length} ->
- Browser = lists:sublist(LAgentString,Start,Length),
+ case re:run(LAgentString,"^[^ ]*", [{capture, first}]) of
+ {match,[{Start,Length}]} ->
+ Browser = lists:sublist(LAgentString,Start+1,Length),
case browserType(Browser) of
{mozilla,Vsn} ->
{getMozilla(LAgentString,
@@ -163,8 +164,8 @@ operativeSystem(OpString,[{RetVal,RegExps}|Rest]) ->
controlOperativeSystem(_OpString,[]) ->
false;
controlOperativeSystem(OpString,[Regexp|Regexps]) ->
- case inets_regexp:match(OpString,Regexp) of
- {match,_,_} ->
+ case re:run(OpString,Regexp, [{capture, none}]) of
+ match ->
true;
nomatch ->
controlOperativeSystem(OpString,Regexps)
@@ -181,18 +182,19 @@ controlOperativeSystem(OpString,[Regexp|Regexps]) ->
getMozilla(_AgentString,[],Default) ->
Default;
getMozilla(AgentString,[{Agent,AgentRegExp}|Rest],Default) ->
- case inets_regexp:match(AgentString,AgentRegExp) of
- {match,_,_} ->
+ case re:run(AgentString,AgentRegExp, [{capture, none}]) of
+ match ->
{Agent,getMozVersion(AgentString,AgentRegExp)};
nomatch ->
getMozilla(AgentString,Rest,Default)
end.
getMozVersion(AgentString, AgentRegExp) ->
- case inets_regexp:match(AgentString,AgentRegExp++"[0-9\.\ \/]*") of
- {match,Start,Length} when length(AgentRegExp) < Length ->
+ case re:run(AgentString,AgentRegExp++"[0-9\.\ \/]*",
+ [{capture, first}]) of
+ {match, [{Start,Length}]} when length(AgentRegExp) < Length ->
%% Ok we got the number split it out
- RealStart = Start+length(AgentRegExp),
+ RealStart = Start+1+length(AgentRegExp),
RealLength = Length-length(AgentRegExp),
VsnString = string:substr(AgentString,RealStart,RealLength),
%% case string:strip(VsnString,both,$\ ) of
diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl
index d933b0a4ba..ec8b9be32e 100644
--- a/lib/inets/src/http_server/mod_cgi.erl
+++ b/lib/inets/src/http_server/mod_cgi.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -95,24 +96,24 @@ do(ModData) ->
%% or cache
%%
load("ScriptNoCache " ++ CacheArg, [])->
- case catch list_to_atom(httpd_conf:clean(CacheArg)) of
+ case catch list_to_atom(string:strip(CacheArg)) of
true ->
{ok, [], {script_nocache, true}};
false ->
{ok, [], {script_nocache, false}};
_ ->
- {error, ?NICE(httpd_conf:clean(CacheArg)++
+ {error, ?NICE(string:strip(CacheArg)++
" is an invalid ScriptNoCache directive")}
end;
%% ScriptTimeout Seconds, The number of seconds that the server
%% maximum will wait for the script to
%% generate a part of the document
load("ScriptTimeout " ++ Timeout, [])->
- case catch list_to_integer(httpd_conf:clean(Timeout)) of
+ case catch list_to_integer(string:strip(Timeout)) of
TimeoutSec when is_integer(TimeoutSec) ->
{ok, [], {script_timeout,TimeoutSec*1000}};
_ ->
- {error, ?NICE(httpd_conf:clean(Timeout)++
+ {error, ?NICE(string:strip(Timeout)++
" is an invalid ScriptTimeout")}
end.
@@ -336,6 +337,8 @@ script_elements(#mod{method = "GET"}, {PathInfo, QueryString}) ->
[{query_string, QueryString}, {path_info, PathInfo}];
script_elements(#mod{method = "POST", entity_body = Body}, _) ->
[{entity_body, Body}];
+script_elements(#mod{method = "PATCH", entity_body = Body}, _) ->
+ [{entity_body, Body}];
script_elements(#mod{method = "PUT", entity_body = Body}, _) ->
[{entity_body, Body}];
script_elements(_, _) ->
diff --git a/lib/inets/src/http_server/mod_dir.erl b/lib/inets/src/http_server/mod_dir.erl
index d791ee28e9..2d8f27af3c 100644
--- a/lib/inets/src/http_server/mod_dir.erl
+++ b/lib/inets/src/http_server/mod_dir.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -124,12 +125,13 @@ header(Path,RequestURI) ->
RequestURI ++ "</H1>\n<PRE><IMG SRC=\"" ++ icon(blank) ++
"\" ALT=" "> Name Last modified "
"Size Description <HR>\n",
- case inets_regexp:sub(RequestURI,"[^/]*\$","") of
- {ok,"/",_} ->
+ case re:replace(RequestURI,"[^/]*\$","", [{return,list}]) of
+ "/" ->
Header;
- {ok,ParentRequestURI,_} ->
- {ok,ParentPath,_} =
- inets_regexp:sub(string:strip(Path,right,$/),"[^/]*\$",""),
+ ParentRequestURI ->
+ ParentPath =
+ re:replace(string:strip(Path,right,$/),"[^/]*\$","",
+ [{return,list}]),
Header++format(ParentPath,ParentRequestURI)
end.
diff --git a/lib/inets/src/http_server/mod_disk_log.erl b/lib/inets/src/http_server/mod_disk_log.erl
index 5a3766de66..5e395a2118 100644
--- a/lib/inets/src/http_server/mod_disk_log.erl
+++ b/lib/inets/src/http_server/mod_disk_log.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -137,72 +138,81 @@ do(Info) ->
%% Description: See httpd(3) ESWAPI CALLBACK FUNCTIONS
%%-------------------------------------------------------------------------
load("TransferDiskLogSize " ++ TransferDiskLogSize, []) ->
- case inets_regexp:split(TransferDiskLogSize," ") of
- {ok,[MaxBytes,MaxFiles]} ->
- case httpd_conf:make_integer(MaxBytes) of
+ try re:split(TransferDiskLogSize, " ", [{return, list}]) of
+ [MaxBytes, MaxFiles] ->
+ case make_integer(MaxBytes) of
{ok,MaxBytesInteger} ->
- case httpd_conf:make_integer(MaxFiles) of
+ case make_integer(MaxFiles) of
{ok,MaxFilesInteger} ->
{ok,[],{transfer_disk_log_size,
{MaxBytesInteger,MaxFilesInteger}}};
{error,_} ->
{error,
- ?NICE(httpd_conf:clean(TransferDiskLogSize)++
+ ?NICE(string:strip(TransferDiskLogSize)++
" is an invalid TransferDiskLogSize")}
end;
- {error,_} ->
- {error,?NICE(httpd_conf:clean(TransferDiskLogSize)++
- " is an invalid TransferDiskLogSize")}
+ _ ->
+ {error,?NICE(string:strip(TransferDiskLogSize)++
+ " is an invalid TransferDiskLogSize")}
end
+ catch _:_ ->
+ {error,?NICE(string:strip(TransferDiskLogSize) ++
+ " is an invalid TransferDiskLogSize")}
end;
load("TransferDiskLog " ++ TransferDiskLog,[]) ->
- {ok,[],{transfer_disk_log,httpd_conf:clean(TransferDiskLog)}};
+ {ok,[],{transfer_disk_log,string:strip(TransferDiskLog)}};
load("ErrorDiskLogSize " ++ ErrorDiskLogSize, []) ->
- case inets_regexp:split(ErrorDiskLogSize," ") of
- {ok,[MaxBytes,MaxFiles]} ->
- case httpd_conf:make_integer(MaxBytes) of
+ try re:split(ErrorDiskLogSize," ", [{return, list}]) of
+ [MaxBytes,MaxFiles] ->
+ case make_integer(MaxBytes) of
{ok,MaxBytesInteger} ->
- case httpd_conf:make_integer(MaxFiles) of
+ case make_integer(MaxFiles) of
{ok,MaxFilesInteger} ->
{ok,[],{error_disk_log_size,
{MaxBytesInteger,MaxFilesInteger}}};
{error,_} ->
- {error,?NICE(httpd_conf:clean(ErrorDiskLogSize)++
+ {error,?NICE(string:strip(ErrorDiskLogSize)++
" is an invalid ErrorDiskLogSize")}
end;
{error,_} ->
- {error,?NICE(httpd_conf:clean(ErrorDiskLogSize)++
+ {error,?NICE(string:strip(ErrorDiskLogSize)++
" is an invalid ErrorDiskLogSize")}
end
+ catch _:_ ->
+ {error,?NICE(string:strip(ErrorDiskLogSize) ++
+ " is an invalid TransferDiskLogSize")}
end;
load("ErrorDiskLog " ++ ErrorDiskLog, []) ->
- {ok, [], {error_disk_log, httpd_conf:clean(ErrorDiskLog)}};
+ {ok, [], {error_disk_log, string:strip(ErrorDiskLog)}};
load("SecurityDiskLogSize " ++ SecurityDiskLogSize, []) ->
- case inets_regexp:split(SecurityDiskLogSize, " ") of
- {ok, [MaxBytes, MaxFiles]} ->
- case httpd_conf:make_integer(MaxBytes) of
+ try re:split(SecurityDiskLogSize, " ", [{return, list}]) of
+ [MaxBytes, MaxFiles] ->
+ case make_integer(MaxBytes) of
{ok, MaxBytesInteger} ->
- case httpd_conf:make_integer(MaxFiles) of
+ case make_integer(MaxFiles) of
{ok, MaxFilesInteger} ->
{ok, [], {security_disk_log_size,
{MaxBytesInteger, MaxFilesInteger}}};
{error,_} ->
{error,
- ?NICE(httpd_conf:clean(SecurityDiskLogSize) ++
+ ?NICE(string:strip(SecurityDiskLogSize) ++
" is an invalid SecurityDiskLogSize")}
end;
{error, _} ->
- {error, ?NICE(httpd_conf:clean(SecurityDiskLogSize) ++
+ {error, ?NICE(string:strip(SecurityDiskLogSize) ++
" is an invalid SecurityDiskLogSize")}
end
+ catch _:_ ->
+ {error,?NICE(string:strip(SecurityDiskLogSize) ++
+ " is an invalid SecurityDiskLogSize")}
end;
load("SecurityDiskLog " ++ SecurityDiskLog, []) ->
- {ok, [], {security_disk_log, httpd_conf:clean(SecurityDiskLog)}};
+ {ok, [], {security_disk_log, string:strip(SecurityDiskLog)}};
load("DiskLogFormat " ++ Format, []) ->
- case httpd_conf:clean(Format) of
+ case string:strip(Format) of
"internal" ->
{ok, [], {disk_log_format,internal}};
"external" ->
@@ -314,7 +324,7 @@ log_size(ConfigList, Tag) ->
proplists:get_value(Tag, ConfigList, {500*1024,8}).
create_disk_log(LogFile, SizeTag, ConfigList) ->
- Filename = httpd_conf:clean(LogFile),
+ Filename = string:strip(LogFile),
{MaxBytes, MaxFiles} = log_size(ConfigList, SizeTag),
case filename:pathtype(Filename) of
absolute ->
@@ -413,3 +423,11 @@ log_internal_info(Info,Date,[{internal_info,Reason}|Rest]) ->
log_internal_info(Info,Date,[_|Rest]) ->
log_internal_info(Info,Date,Rest).
+make_integer(List) ->
+ try list_to_integer(List) of
+ N ->
+ {ok, N}
+ catch
+ _:_ ->
+ {error, {badarg, list_to_integer, List}}
+ end.
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index b11df34f9e..2978ac9095 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -95,43 +96,44 @@ do(ModData) ->
%% Description: See httpd(3) ESWAPI CALLBACK FUNCTIONS
%%-------------------------------------------------------------------------
load("ErlScriptAlias " ++ ErlScriptAlias, []) ->
- case inets_regexp:split(ErlScriptAlias," ") of
- {ok, [ErlName | StrModules]} ->
+ try re:split(ErlScriptAlias," ", [{return, list}]) of
+ [ErlName | StrModules] ->
Modules = lists:map(fun(Str) ->
- list_to_atom(httpd_conf:clean(Str))
+ list_to_atom(string:strip(Str))
end, StrModules),
- {ok, [], {erl_script_alias, {ErlName, Modules}}};
- {ok, _} ->
- {error, ?NICE(httpd_conf:clean(ErlScriptAlias) ++
- " is an invalid ErlScriptAlias")}
+ {ok, [], {erl_script_alias, {ErlName, Modules}}}
+ catch _:_ ->
+ {error, ?NICE(string:strip(ErlScriptAlias) ++
+ " is an invalid ErlScriptAlias")}
end;
load("EvalScriptAlias " ++ EvalScriptAlias, []) ->
- case inets_regexp:split(EvalScriptAlias, " ") of
- {ok, [EvalName | StrModules]} ->
+ try re:split(EvalScriptAlias, " ", [{return, list}]) of
+ [EvalName | StrModules] ->
Modules = lists:map(fun(Str) ->
- list_to_atom(httpd_conf:clean(Str))
+ list_to_atom(string:strip(Str))
end, StrModules),
- {ok, [], {eval_script_alias, {EvalName, Modules}}};
- {ok, _} ->
- {error, ?NICE(httpd_conf:clean(EvalScriptAlias) ++
- " is an invalid EvalScriptAlias")}
+ {ok, [], {eval_script_alias, {EvalName, Modules}}}
+ catch
+ _:_ ->
+ {error, ?NICE(string:strip(EvalScriptAlias) ++
+ " is an invalid EvalScriptAlias")}
end;
load("ErlScriptTimeout " ++ Timeout, [])->
- case catch list_to_integer(httpd_conf:clean(Timeout)) of
+ case catch list_to_integer(string:strip(Timeout)) of
TimeoutSec when is_integer(TimeoutSec) ->
{ok, [], {erl_script_timeout, TimeoutSec * 1000}};
_ ->
- {error, ?NICE(httpd_conf:clean(Timeout) ++
+ {error, ?NICE(string:strip(Timeout) ++
" is an invalid ErlScriptTimeout")}
end;
load("ErlScriptNoCache " ++ CacheArg, [])->
- case catch list_to_atom(httpd_conf:clean(CacheArg)) of
+ case catch list_to_atom(string:strip(CacheArg)) of
true ->
{ok, [], {erl_script_nocache, true}};
false ->
{ok, [], {erl_script_nocache, false}};
_ ->
- {error, ?NICE(httpd_conf:clean(CacheArg)++
+ {error, ?NICE(string:strip(CacheArg)++
" is an invalid ErlScriptNoCache directive")}
end.
@@ -223,8 +225,8 @@ match_esi_script(_, [], _) ->
no_match;
match_esi_script(RequestURI, [{Alias,Modules} | Rest], AliasType) ->
AliasMatchStr = alias_match_str(Alias, AliasType),
- case inets_regexp:first_match(RequestURI, AliasMatchStr) of
- {match, 1, Length} ->
+ case re:run(RequestURI, AliasMatchStr, [{capture, first}]) of
+ {match, [{0, Length}]} ->
{string:substr(RequestURI, Length + 1), Modules};
nomatch ->
match_esi_script(RequestURI, Rest, AliasType)
@@ -280,6 +282,15 @@ erl(#mod{request_uri = ReqUri,
?NICE("Erl mechanism doesn't support method DELETE")}}|
Data]};
+erl(#mod{request_uri = ReqUri,
+ method = "PATCH",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ ?hdrt("erl", [{method, patch}]),
+ {proceed, [{status,{501,{"PATCH", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method PATCH")}}|
+ Data]};
+
erl(#mod{method = "POST",
entity_body = Body} = ModData, ESIBody, Modules) ->
?hdrt("erl", [{method, post}]),
@@ -375,7 +386,6 @@ erl_scheme_webpage_chunk(Mod, Func, Env, Input, ModData) ->
end),
Response = deliver_webpage_chunk(ModData, Pid),
-
process_flag(trap_exit,false),
Response.
@@ -417,7 +427,6 @@ deliver_webpage_chunk(#mod{config_db = Db} = ModData, Pid, Timeout) ->
?hdrv("deliver_webpage_chunk - timeout", []),
send_headers(ModData, 504, [{"connection", "close"}]),
httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket),
- process_flag(trap_exit,false),
{proceed,[{response, {already_sent, 200, 0}} | ModData#mod.data]}
end.
@@ -445,7 +454,6 @@ send_headers(ModData, StatusCode, HTTPHeaders) ->
ExtraHeaders ++ HTTPHeaders).
handle_body(_, #mod{method = "HEAD"} = ModData, _, _, Size, _) ->
- process_flag(trap_exit,false),
{proceed, [{response, {already_sent, 200, Size}} | ModData#mod.data]};
handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) ->
@@ -453,34 +461,54 @@ handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) ->
httpd_response:send_chunk(ModData, Body, IsDisableChunkedSend),
receive
{esi_data, Data} when is_binary(Data) ->
- ?hdrt("handle_body - received binary data (esi)", []),
handle_body(Pid, ModData, Data, Timeout, Size + byte_size(Data),
IsDisableChunkedSend);
{esi_data, Data} ->
- ?hdrt("handle_body - received data (esi)", []),
handle_body(Pid, ModData, Data, Timeout, Size + length(Data),
IsDisableChunkedSend);
{ok, Data} ->
- ?hdrt("handle_body - received data (ok)", []),
handle_body(Pid, ModData, Data, Timeout, Size + length(Data),
IsDisableChunkedSend);
{'EXIT', Pid, normal} when is_pid(Pid) ->
- ?hdrt("handle_body - exit:normal", []),
httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
{proceed, [{response, {already_sent, 200, Size}} |
ModData#mod.data]};
{'EXIT', Pid, Reason} when is_pid(Pid) ->
- ?hdrv("handle_body - exit", [{reason, Reason}]),
- httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
- exit({mod_esi_linked_process_died, Pid, Reason})
-
+ Error = lists:flatten(io_lib:format("mod_esi process failed with reason ~p", [Reason])),
+ httpd_util:error_log(ModData#mod.config_db, Error),
+ httpd_response:send_final_chunk(ModData,
+ [{"Warning", "199 inets server - body maybe incomplete, "
+ "internal server error"}],
+ IsDisableChunkedSend),
+ done
after Timeout ->
- ?hdrv("handle_body - timeout", []),
- process_flag(trap_exit,false),
- httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
- exit({mod_esi_linked_process_timeout, Pid})
+ kill_esi_delivery_process(Pid),
+ httpd_response:send_final_chunk(ModData, [{"Warning", "199 inets server - "
+ "body maybe incomplete, timed out"}],
+ IsDisableChunkedSend),
+ done
end.
+kill_esi_delivery_process(Pid) ->
+ exit(Pid, kill),
+ receive
+ {'EXIT', Pid, killed} ->
+ %% Clean message queue
+ receive
+ {esi_data, _} ->
+ ok
+ after 0 ->
+ ok
+ end,
+ receive
+ {ok, _} ->
+ ok
+ after 0 ->
+ ok
+ end
+ end.
+
+
erl_script_timeout(Db) ->
httpd_util:lookup(Db, erl_script_timeout, ?DEFAULT_ERL_TIMEOUT).
@@ -566,9 +594,9 @@ generate_webpage(ESIBody) ->
is_authorized(_ESIBody, [all]) ->
true;
is_authorized(ESIBody, Modules) ->
- case inets_regexp:match(ESIBody, "^[^\:(%3A)]*") of
- {match, Start, Length} ->
- lists:member(list_to_atom(string:substr(ESIBody, Start, Length)),
+ case re:run(ESIBody, "^[^\:(%3A)]*", [{capture, first}]) of
+ {match, [{Start, Length}]} ->
+ lists:member(list_to_atom(string:substr(ESIBody, Start+1, Length)),
Modules);
nomatch ->
false
diff --git a/lib/inets/src/http_server/mod_get.erl b/lib/inets/src/http_server/mod_get.erl
index 758985f330..e8b3896f89 100644
--- a/lib/inets/src/http_server/mod_get.erl
+++ b/lib/inets/src/http_server/mod_get.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/mod_head.erl b/lib/inets/src/http_server/mod_head.erl
index 02b8485b25..1b68c1c66b 100644
--- a/lib/inets/src/http_server/mod_head.erl
+++ b/lib/inets/src/http_server/mod_head.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/mod_htaccess.erl b/lib/inets/src/http_server/mod_htaccess.erl
index e1f66d01c8..f229c96f2d 100644
--- a/lib/inets/src/http_server/mod_htaccess.erl
+++ b/lib/inets/src/http_server/mod_htaccess.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -34,7 +35,7 @@
% Names on accessfiles
%----------------------------------------------------------------------
load("AccessFileName" ++ FileNames, _Context)->
- CleanFileNames=httpd_conf:clean(FileNames),
+ CleanFileNames=string:strip(FileNames),
{ok,[],{access_files,string:tokens(CleanFileNames," ")}}.
store({access_files, Files} = Conf, _) when is_list(Files)->
@@ -326,9 +327,9 @@ memberNetwork(Networks,UserNetwork,IfTrue,IfFalse)->
%ipadresses or subnet addresses.
memberNetwork(Networks,UserNetwork)->
case lists:filter(fun(Net)->
- case inets_regexp:match(UserNetwork,
- formatRegexp(Net)) of
- {match,1,_}->
+ case re:run(UserNetwork,
+ formatRegexp(Net), [{capture, first}]) of
+ {match,[{0,_}]}->
true;
_NotSubNet ->
false
@@ -637,13 +638,8 @@ getHtAccessFileNames(Info)->
%HtAccessFileNames=["accessfileName1",..."AccessFileName2"]
%----------------------------------------------------------------------
getData(Path,Info,HtAccessFileNames)->
- case inets_regexp:split(Path,"/") of
- {error,Error}->
- {error,Error};
- {ok,SplittedPath}->
- getData2(HtAccessFileNames,SplittedPath,Info)
- end.
-
+ SplittedPath = re:split(Path, "/", [{return, list}]),
+ getData2(HtAccessFileNames,SplittedPath,Info).
%----------------------------------------------------------------------
%Add to together the data in the Splittedpath up to the path
@@ -941,20 +937,16 @@ getAuthorizationType(AuthType)->
%Returns a list of the specified methods to limit or the atom all
%----------------------------------------------------------------------
getLimits(Limits)->
- case inets_regexp:split(Limits,">")of
- {ok,[_NoEndOnLimit]}->
+ case re:split(Limits,">", [{return, list}])of
+ [_NoEndOnLimit]->
error;
- {ok, [Methods | _Crap]}->
- case inets_regexp:split(Methods," ") of
- {ok,[]}->
+ [Methods | _Crap]->
+ case re:split(Methods," ", [{return, list}]) of
+ [[]]->
all;
- {ok,SplittedMethods}->
- SplittedMethods;
- {error, _Error}->
- error
- end;
- {error,_Error}->
- error
+ SplittedMethods ->
+ SplittedMethods
+ end
end.
diff --git a/lib/inets/src/http_server/mod_include.erl b/lib/inets/src/http_server/mod_include.erl
deleted file mode 100644
index 35f45bdd33..0000000000
--- a/lib/inets/src/http_server/mod_include.erl
+++ /dev/null
@@ -1,598 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
--module(mod_include).
--export([do/1,parse/2,config/6,include/6,echo/6,fsize/6,flastmod/6,exec/6]).
-
--include("httpd.hrl").
--include("httpd_internal.hrl").
-
--define(VMODULE,"INCLUDE").
-
-%% do
-
-do(Info) ->
- case Info#mod.method of
- "GET" ->
- case proplists:get_value(status, Info#mod.data) of
- %% A status code has been generated!
- {_StatusCode, _PhraseArgs, _Reason} ->
- {proceed,Info#mod.data};
- %% No status code has been generated!
- undefined ->
- case proplists:get_value(response, Info#mod.data) of
- %% No response has been generated!
- undefined ->
- do_include(Info);
- %% A response has been generated or sent!
- _Response ->
- {proceed,Info#mod.data}
- end
- end;
- %% Not a GET method!
- _ ->
- {proceed,Info#mod.data}
- end.
-
-do_include(Info) ->
- Path = mod_alias:path(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri),
- Suffix = httpd_util:suffix(Path),
- case httpd_util:lookup_mime_default(Info#mod.config_db,Suffix) of
- "text/x-server-parsed-html" ->
- HeaderStart = [{content_type, "text/html"}],
- case send_in(Info, Path, HeaderStart, file:read_file_info(Path)) of
- {ok, ErrorLog, Size} ->
- {proceed, [{response, {already_sent, 200, Size}},
- {mime_type, "text/html"} |
- lists:append(ErrorLog, Info#mod.data)]};
- {error, Reason} ->
- {proceed,
- [{status,send_error(Reason,Info,Path)}|Info#mod.data]}
- end;
- _ -> %% Unknown mime type, ignore
- {proceed,Info#mod.data}
- end.
-
-
-%%
-%% config directive
-%%
-
-config(_Info, Context, ErrorLog, TagList, ValueList, R) ->
- case verify_tags("config",[errmsg,timefmt,sizefmt],
- TagList,ValueList) of
- ok ->
- {ok,update_context(TagList,ValueList,Context),ErrorLog,"",R};
- {error,Reason} ->
- {ok,Context,[{internal_info,Reason}|ErrorLog],
- proplists:get_value(errmsg,Context,""),R}
- end.
-
-update_context([],[],Context) ->
- Context;
-update_context([Tag|R1],[Value|R2],Context) ->
- update_context(R1,R2,[{Tag,Value}|Context]).
-
-verify_tags(Command,ValidTags,TagList,ValueList)
- when length(TagList) =:= length(ValueList) ->
- verify_tags(Command, ValidTags, TagList);
-verify_tags(Command, _ValidTags, _TagList, _ValueList) ->
- {error, ?NICE(Command ++ " directive has spurious tags")}.
-
-verify_tags(_Command, _ValidTags, []) ->
- ok;
-verify_tags(Command, ValidTags, [Tag|Rest]) ->
- case lists:member(Tag, ValidTags) of
- true ->
- verify_tags(Command, ValidTags, Rest);
- false ->
- {error, ?NICE(Command++" directive has a spurious tag ("++
- atom_to_list(Tag)++")")}
- end.
-
-%%
-%% include directive
-%%
-
-include(Info,Context,ErrorLog,[virtual],[VirtualPath],R) ->
- Aliases = httpd_util:multi_lookup(Info#mod.config_db,alias),
- {_, Path, _AfterPath} =
- mod_alias:real_name(Info#mod.config_db, VirtualPath, Aliases),
- include(Info,Context,ErrorLog,R,Path);
-include(Info, Context, ErrorLog, [file], [FileName], R) ->
- Path = file(Info#mod.config_db, Info#mod.request_uri, FileName),
- include(Info, Context, ErrorLog, R, Path);
-include(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok, Context,
- [{internal_info,?NICE("include directive has a spurious tag")}|
- ErrorLog], proplists:get_value(errmsg, Context, ""), R}.
-
-include(Info, Context, ErrorLog, R, Path) ->
- case file:read_file(Path) of
- {ok, Body} ->
- {ok, NewContext, NewErrorLog, Result} =
- parse(Info, binary_to_list(Body), Context, ErrorLog, []),
- {ok, NewContext, NewErrorLog, Result, R};
- {error, _Reason} ->
- {ok, Context,
- [{internal_info, ?NICE("Can't open "++Path)}|ErrorLog],
- proplists:get_value(errmsg, Context, ""), R}
- end.
-
-file(ConfigDB, RequestURI, FileName) ->
- Aliases = httpd_util:multi_lookup(ConfigDB, alias),
- {_, Path, _AfterPath}
- = mod_alias:real_name(ConfigDB, RequestURI, Aliases),
- Pwd = filename:dirname(Path),
- filename:join(Pwd, FileName).
-
-%%
-%% echo directive
-%%
-
-echo(Info,Context,ErrorLog,[var],["DOCUMENT_NAME"],R) ->
- {ok,Context,ErrorLog,document_name(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri),R};
-echo(Info,Context,ErrorLog,[var],["DOCUMENT_URI"],R) ->
- {ok,Context,ErrorLog,document_uri(Info#mod.config_db,
- Info#mod.request_uri),R};
-echo(Info,Context,ErrorLog,[var],["QUERY_STRING_UNESCAPED"],R) ->
- {ok,Context,ErrorLog,query_string_unescaped(Info#mod.request_uri),R};
-echo(_Info,Context,ErrorLog,[var],["DATE_LOCAL"],R) ->
- {ok,Context,ErrorLog,date_local(),R};
-echo(_Info,Context,ErrorLog,[var],["DATE_GMT"],R) ->
- {ok,Context,ErrorLog,date_gmt(),R};
-echo(Info,Context,ErrorLog,[var],["LAST_MODIFIED"],R) ->
- {ok,Context,ErrorLog,last_modified(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri),R};
-echo(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok,Context,
- [{internal_info,?NICE("echo directive has a spurious tag")}|
- ErrorLog],"(none)",R}.
-
-document_name(Data,ConfigDB,RequestURI) ->
- Path = mod_alias:path(Data,ConfigDB,RequestURI),
- case inets_regexp:match(Path,"[^/]*\$") of
- {match,Start,Length} ->
- string:substr(Path,Start,Length);
- nomatch ->
- "(none)"
- end.
-
-document_uri(ConfigDB, RequestURI) ->
- Aliases = httpd_util:multi_lookup(ConfigDB, alias),
-
- {_, Path, AfterPath} = mod_alias:real_name(ConfigDB, RequestURI, Aliases),
-
- VirtualPath = string:substr(RequestURI, 1,
- length(RequestURI)-length(AfterPath)),
- {match, Start, Length} = inets_regexp:match(Path,"[^/]*\$"),
- FileName = string:substr(Path,Start,Length),
- case inets_regexp:match(VirtualPath, FileName++"\$") of
- {match, _, _} ->
- http_uri:decode(VirtualPath)++AfterPath;
- nomatch ->
- string:strip(http_uri:decode(VirtualPath),right,$/)++
- "/"++FileName++AfterPath
- end.
-
-query_string_unescaped(RequestURI) ->
- case inets_regexp:match(RequestURI,"[\?].*\$") of
- {match,Start,Length} ->
- %% Escape all shell-special variables with \
- escape(string:substr(RequestURI,Start+1,Length-1));
- nomatch ->
- "(none)"
- end.
-
-escape([]) -> [];
-escape([$;|R]) -> [$\\,$;|escape(R)];
-escape([$&|R]) -> [$\\,$&|escape(R)];
-escape([$(|R]) -> [$\\,$(|escape(R)];
-escape([$)|R]) -> [$\\,$)|escape(R)];
-escape([$||R]) -> [$\\,$||escape(R)];
-escape([$^|R]) -> [$\\,$^|escape(R)];
-escape([$<|R]) -> [$\\,$<|escape(R)];
-escape([$>|R]) -> [$\\,$>|escape(R)];
-escape([$\n|R]) -> [$\\,$\n|escape(R)];
-escape([$ |R]) -> [$\\,$ |escape(R)];
-escape([$\t|R]) -> [$\\,$\t|escape(R)];
-escape([C|R]) -> [C|escape(R)].
-
-date_local() ->
- {{Year,Month,Day},{Hour,Minute,Second}}=calendar:local_time(),
- %% Time format hard-wired to: "%a %b %e %T %Y" according to strftime(3)
- io_lib:format("~s ~s ~2w ~2.2.0w:~2.2.0w:~2.2.0w ~w",
- [httpd_util:day(calendar:day_of_the_week(Year,Month,Day)),
- httpd_util:month(Month),Day,Hour,Minute,Second,Year]).
-
-date_gmt() ->
- {{Year,Month,Day},{Hour,Minute,Second}}=calendar:universal_time(),
- %% Time format hard-wired to: "%a %b %e %T %Z %Y" according to strftime(3)
- io_lib:format("~s ~s ~2w ~2.2.0w:~2.2.0w:~2.2.0w GMT ~w",
- [httpd_util:day(calendar:day_of_the_week(Year,Month,Day)),
- httpd_util:month(Month),Day,Hour,Minute,Second,Year]).
-
-last_modified(Data,ConfigDB,RequestURI) ->
- {ok,FileInfo}=file:read_file_info(mod_alias:path(Data,ConfigDB,RequestURI)),
- {{Year,Month,Day},{Hour,Minute,Second}}=FileInfo#file_info.mtime,
- io_lib:format("~s ~s ~2w ~2.2.0w:~2.2.0w:~2.2.0w ~w",
- [httpd_util:day(calendar:day_of_the_week(Year,Month,Day)),
- httpd_util:month(Month),Day,Hour,Minute,Second,Year]).
-
-%%
-%% fsize directive
-%%
-
-fsize(Info,Context,ErrorLog,[virtual],[VirtualPath],R) ->
- Aliases = httpd_util:multi_lookup(Info#mod.config_db,alias),
- {_,Path, _AfterPath}=
- mod_alias:real_name(Info#mod.config_db,VirtualPath,Aliases),
- fsize(Info, Context, ErrorLog, R, Path);
-fsize(Info,Context,ErrorLog,[file],[FileName],R) ->
- Path = file(Info#mod.config_db,Info#mod.request_uri,FileName),
- fsize(Info,Context,ErrorLog,R,Path);
-fsize(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok,Context,[{internal_info,?NICE("fsize directive has a spurious tag")}|
- ErrorLog],proplists:get_value(errmsg,Context,""),R}.
-
-fsize(_Info, Context, ErrorLog, R, Path) ->
- case file:read_file_info(Path) of
- {ok,FileInfo} ->
- case proplists:get_value(sizefmt,Context) of
- "bytes" ->
- {ok,Context,ErrorLog,
- integer_to_list(FileInfo#file_info.size),R};
- "abbrev" ->
- Size = integer_to_list(trunc(FileInfo#file_info.size/1024+1))++"k",
- {ok,Context,ErrorLog,Size,R};
- Value->
- {ok,Context,
- [{internal_info,
- ?NICE("fsize directive has a spurious tag value ("++
- Value++")")}|
- ErrorLog],
- proplists:get_value(errmsg, Context, ""), R}
- end;
- {error, _Reason} ->
- {ok,Context,[{internal_info,?NICE("Can't open "++Path)}|ErrorLog],
- proplists:get_value(errmsg,Context,""),R}
- end.
-
-%%
-%% flastmod directive
-%%
-
-flastmod(#mod{config_db = Db} = Info,
- Context, ErrorLog, [virtual], [VirtualPath],R) ->
- Aliases = httpd_util:multi_lookup(Db,alias),
- {_,Path, _AfterPath} = mod_alias:real_name(Db, VirtualPath, Aliases),
- flastmod(Info,Context,ErrorLog,R,Path);
-flastmod(#mod{config_db = Db, request_uri = RequestUri} = Info,
- Context, ErrorLog, [file], [FileName], R) ->
- Path = file(Db, RequestUri, FileName),
- flastmod(Info, Context, ErrorLog, R, Path);
-flastmod(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok,Context,
- [{internal_info,?NICE("flastmod directive has a spurious tag")}|
- ErrorLog],proplists:get_value(errmsg,Context,""),R}.
-
-flastmod(_Info, Context, ErrorLog, R, File) ->
- case file:read_file_info(File) of
- {ok, FileInfo} ->
- {{Yr,Mon,Day},{Hour,Minute,Second}}=FileInfo#file_info.mtime,
- Result =
- io_lib:format("~s ~s ~2w ~w:~w:~w ~w",
- [httpd_util:day(
- calendar:day_of_the_week(Yr,Mon, Day)),
- httpd_util:month(Mon),Day,Hour,Minute,Second, Yr]),
- {ok, Context, ErrorLog, Result, R};
- {error, _Reason} ->
- {ok,Context,[{internal_info,?NICE("Can't open "++File)}|ErrorLog],
- proplists:get_value(errmsg,Context,""),R}
- end.
-
-%%
-%% exec directive
-%%
-
-exec(Info,Context,ErrorLog,[cmd],[Command],R) ->
- cmd(Info,Context,ErrorLog,R,Command);
-exec(Info,Context,ErrorLog,[cgi],[RequestURI],R) ->
- cgi(Info,Context,ErrorLog,R,RequestURI);
-exec(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok, Context,
- [{internal_info,?NICE("exec directive has a spurious tag")}|
- ErrorLog], proplists:get_value(errmsg,Context,""),R}.
-
-%% cmd
-
-cmd(Info, Context, ErrorLog, R, Command) ->
- process_flag(trap_exit,true),
- Env = env(Info),
- Dir = filename:dirname(Command),
- Port = (catch open_port({spawn,Command},[stream,{cd,Dir},{env,Env}])),
- case Port of
- P when is_port(P) ->
- {NewErrorLog, Result} = proxy(Port, ErrorLog),
- {ok, Context, NewErrorLog, Result, R};
- {'EXIT', Reason} ->
- exit({open_port_failed,Reason,
- [{uri,Info#mod.request_uri},{script,Command},
- {env,Env},{dir,Dir}]});
- O ->
- exit({open_port_failed,O,
- [{uri,Info#mod.request_uri},{script,Command},
- {env,Env},{dir,Dir}]})
- end.
-
-env(Info) ->
- [{"DOCUMENT_NAME",document_name(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri)},
- {"DOCUMENT_URI", document_uri(Info#mod.config_db, Info#mod.request_uri)},
- {"QUERY_STRING_UNESCAPED", query_string_unescaped(Info#mod.request_uri)},
- {"DATE_LOCAL", date_local()},
- {"DATE_GMT", date_gmt()},
- {"LAST_MODIFIED", last_modified(Info#mod.data, Info#mod.config_db,
- Info#mod.request_uri)}
- ].
-
-%% cgi
-
-cgi(Info, Context, ErrorLog, R, RequestURI) ->
- ScriptAliases = httpd_util:multi_lookup(Info#mod.config_db, script_alias),
- case mod_alias:real_script_name(Info#mod.config_db, RequestURI,
- ScriptAliases) of
- {Script, AfterScript} ->
- exec_script(Info,Script,AfterScript,ErrorLog,Context,R);
- not_a_script ->
- {ok, Context,
- [{internal_info, ?NICE(RequestURI++" is not a script")}|
- ErrorLog], proplists:get_value(errmsg, Context, ""),R}
- end.
-
-remove_header([]) ->
- [];
-remove_header([$\n,$\n|Rest]) ->
- Rest;
-remove_header([_C|Rest]) ->
- remove_header(Rest).
-
-
-exec_script(#mod{config_db = Db, request_uri = RequestUri} = Info,
- Script, _AfterScript, ErrorLog, Context, R) ->
- process_flag(trap_exit,true),
- Aliases = httpd_util:multi_lookup(Db, alias),
- {_, Path, AfterPath} = mod_alias:real_name(Db, RequestUri, Aliases),
- Env = env(Info) ++ mod_cgi:env(Info, Path, AfterPath),
- Dir = filename:dirname(Path),
- Port = (catch open_port({spawn,Script},[stream,{env, Env},{cd, Dir}])),
- case Port of
- P when is_port(P) ->
- %% Send entity body to port.
- Res = case Info#mod.entity_body of
- [] ->
- true;
- EntityBody ->
- (catch port_command(Port, EntityBody))
- end,
- case Res of
- {'EXIT', Reason} ->
- exit({open_cmd_failed,Reason,
- [{mod,?MODULE},{port,Port},
- {uri,RequestUri},
- {script,Script},{env,Env},{dir,Dir},
- {ebody_size,sz(Info#mod.entity_body)}]});
- true ->
- {NewErrorLog, Result} = proxy(Port, ErrorLog),
- {ok, Context, NewErrorLog, remove_header(Result), R}
- end;
- {'EXIT', Reason} ->
- exit({open_port_failed,Reason,
- [{mod,?MODULE},{uri,RequestUri},{script,Script},
- {env,Env},{dir,Dir}]});
- O ->
- exit({open_port_failed,O,
- [{mod,?MODULE},{uri,RequestUri},{script,Script},
- {env,Env},{dir,Dir}]})
- end.
-
-
-%%
-%% Port communication
-%%
-
-proxy(Port, ErrorLog) ->
- process_flag(trap_exit, true),
- proxy(Port, ErrorLog, []).
-
-proxy(Port, ErrorLog, Result) ->
- receive
- {Port, {data, Response}} ->
- proxy(Port, ErrorLog, lists:append(Result,Response));
- {'EXIT', Port, normal} when is_port(Port) ->
- process_flag(trap_exit, false),
- {ErrorLog, Result};
- {'EXIT', Port, _Reason} when is_port(Port) ->
- process_flag(trap_exit, false),
- {[{internal_info,
- ?NICE("Scrambled output from CGI-script")}|ErrorLog],
- Result};
- {'EXIT', Pid, Reason} when is_pid(Pid) ->
- process_flag(trap_exit, false),
- {'EXIT', Pid, Reason};
- %% This should not happen!
- _WhatEver ->
- process_flag(trap_exit, false),
- {ErrorLog, Result}
- end.
-
-
-%% ------
-%% Temporary until I figure out a way to fix send_in_chunks
-%% (comments and directives that start in one chunk but end
-%% in another is not handled).
-%%
-
-send_in(Info, Path, Head, {ok,FileInfo}) ->
- case file:read_file(Path) of
- {ok, Bin} ->
- send_in1(Info, binary_to_list(Bin), Head, FileInfo);
- {error, Reason} ->
- {error, {read,Reason}}
- end;
-send_in(_Info , _Path, _Head,{error,Reason}) ->
- {error, {open,Reason}}.
-
-send_in1(Info, Data, Head, FileInfo) ->
- {ok, _Context, Err, ParsedBody} = parse(Info,Data,?DEFAULT_CONTEXT,[],[]),
- Size = length(ParsedBody),
- LastModified = case catch httpd_util:rfc1123_date(FileInfo#file_info.mtime) of
- Date when is_list(Date) -> [{last_modified,Date}];
- _ -> []
- end,
- Head1 = case Info#mod.http_version of
- "HTTP/1.1"->
- Head ++ [{content_length, integer_to_list(Size)},
- {etag, httpd_util:create_etag(FileInfo,Size)}|
- LastModified];
- _->
- %% i.e http/1.0 and http/0.9
- Head ++ [{content_length, integer_to_list(Size)}|
- LastModified]
- end,
- httpd_response:send_header(Info, 200, Head1),
- httpd_socket:deliver(Info#mod.socket_type,Info#mod.socket, ParsedBody),
- {ok, Err, Size}.
-
-
-parse(Info,Body) ->
- parse(Info, Body, ?DEFAULT_CONTEXT, [], []).
-
-parse(_Info, [], Context, ErrorLog, Result) ->
- {ok, Context, lists:reverse(ErrorLog), lists:reverse(Result)};
-parse(Info,[$<,$!,$-,$-,$#|R1],Context,ErrorLog,Result) ->
- case catch parse0(R1,Context) of
- {parse_error,Reason} ->
- parse(Info,R1,Context,[{internal_info,?NICE(Reason)}|ErrorLog],
- [$#,$-,$-,$!,$<|Result]);
- {ok,Context,Command,TagList,ValueList,R2} ->
- {ok,NewContext,NewErrorLog,MoreResult,R3}=
- handle(Info,Context,ErrorLog,Command,TagList,ValueList,R2),
- parse(Info,R3,NewContext,NewErrorLog,
- lists:reverse(MoreResult)++Result)
- end;
-parse(Info,[$<,$!,$-,$-|R1],Context,ErrorLog,Result) ->
- case catch parse5(R1,[],0) of
- {parse_error,Reason} ->
- parse(Info,R1,Context,
- [{internal_info,?NICE(Reason)}|ErrorLog],Result);
- {Comment,R2} ->
- parse(Info,R2,Context,ErrorLog,Comment++Result)
- end;
-parse(Info,[C|R],Context,ErrorLog,Result) ->
- parse(Info,R,Context,ErrorLog,[C|Result]).
-
-handle(Info,Context,ErrorLog,Command,TagList,ValueList,R) ->
- case catch apply(?MODULE,Command,[Info,Context,ErrorLog,TagList,ValueList,
- R]) of
- {'EXIT',{undef,_}} ->
- throw({parse_error,"Unknown command "++atom_to_list(Command)++
- " in parsed doc"});
- Result ->
- Result
- end.
-
-parse0([], _Context) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse0([$-,$-,$>|_R], _Context) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse0([$ |R], Context) ->
- parse0(R,Context);
-parse0(String, Context) ->
- parse1(String, Context,"").
-
-parse1([], _Context, _Command) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse1([$-,$-,$>|_R], _Context, _Command) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse1([$ |R], Context, Command) ->
- parse2(R,Context,list_to_atom(lists:reverse(Command)),[],[],"");
-parse1([C|R], Context, Command) ->
- parse1(R,Context,[C|Command]).
-
-parse2([], _Context, _Command, _TagList, _ValueList, _Tag) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse2([$-,$-,$>|R], Context, Command, TagList, ValueList, _Tag) ->
- {ok,Context,Command,TagList,ValueList,R};
-parse2([$ |R],Context,Command,TagList,ValueList,Tag) ->
- parse2(R,Context,Command,TagList,ValueList,Tag);
-parse2([$=|R],Context,Command,TagList,ValueList,Tag) ->
- parse3(R,Context,Command,[list_to_atom(lists:reverse(Tag))|TagList],
- ValueList);
-parse2([C|R],Context,Command,TagList,ValueList,Tag) ->
- parse2(R,Context,Command,TagList,ValueList,[C|Tag]).
-
-parse3([], _Context, _Command, _TagList, _ValueList) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse3([$-,$-,$>|_R], _Context, _Command, _TagList, _ValueList) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse3([$ |R], Context, Command, TagList, ValueList) ->
- parse3(R, Context, Command, TagList, ValueList);
-parse3([$"|R], Context, Command, TagList, ValueList) ->
- parse4(R,Context,Command,TagList,ValueList,"");
-parse3(_String, _Context, _Command, _TagList, _ValueList) ->
- throw({parse_error,"Premature EOF in parsed file"}).
-
-parse4([], _Context, _Command, _TagList, _ValueList, _Value) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse4([$-,$-,$>|_R], _Context, _Command, _TagList, _ValueList, _Value) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse4([$"|R],Context,Command,TagList,ValueList,Value) ->
- parse2(R,Context,Command,TagList,[lists:reverse(Value)|ValueList],"");
-parse4([C|R],Context,Command,TagList,ValueList,Value) ->
- parse4(R,Context,Command,TagList,ValueList,[C|Value]).
-
-parse5([], _Comment, _Depth) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse5([$<,$!,$-,$-|R],Comment,Depth) ->
- parse5(R,[$-,$-,$!,$<|Comment],Depth+1);
-parse5([$-,$-,$>|R],Comment,0) ->
- {">--"++Comment++"--!<",R};
-parse5([$-,$-,$>|R],Comment,Depth) ->
- parse5(R,[$>,$-,$-|Comment],Depth-1);
-parse5([C|R],Comment,Depth) ->
- parse5(R,[C|Comment],Depth).
-
-
-sz(B) when is_binary(B) -> {binary,size(B)};
-sz(L) when is_list(L) -> {list,length(L)};
-sz(_) -> undefined.
-
-%% send_error - Handle failure to send the file
-%%
-send_error({open,Reason},Info,Path) ->
- httpd_file:handle_error(Reason, "open", Info, Path);
-send_error({read,Reason},Info,Path) ->
- httpd_file:handle_error(Reason, "read", Info, Path).
-
-
-
-
diff --git a/lib/inets/src/http_server/mod_log.erl b/lib/inets/src/http_server/mod_log.erl
index a912f5616c..4161f7059c 100644
--- a/lib/inets/src/http_server/mod_log.erl
+++ b/lib/inets/src/http_server/mod_log.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -127,11 +128,11 @@ do(Info) ->
%% Description: See httpd(3) ESWAPI CALLBACK FUNCTIONS
%%-------------------------------------------------------------------------
load("TransferLog " ++ TransferLog, []) ->
- {ok,[],{transfer_log,httpd_conf:clean(TransferLog)}};
+ {ok,[],{transfer_log,string:strip(TransferLog)}};
load("ErrorLog " ++ ErrorLog, []) ->
- {ok,[],{error_log,httpd_conf:clean(ErrorLog)}};
+ {ok,[],{error_log,string:strip(ErrorLog)}};
load("SecurityLog " ++ SecurityLog, []) ->
- {ok, [], {security_log, httpd_conf:clean(SecurityLog)}}.
+ {ok, [], {security_log, string:strip(SecurityLog)}}.
%%--------------------------------------------------------------------------
%% store(Directive, DirectiveList) -> {ok, NewDirective} |
@@ -200,7 +201,7 @@ transfer_log(Info,RFC931,AuthUser,Date,StatusCode,Bytes) ->
end.
create_log(LogFile, ConfigList) ->
- Filename = httpd_conf:clean(LogFile),
+ Filename = string:strip(LogFile),
case filename:pathtype(Filename) of
absolute ->
case file:open(Filename, [read, write]) of
diff --git a/lib/inets/src/http_server/mod_range.erl b/lib/inets/src/http_server/mod_range.erl
index a0408cba79..66d66c2809 100644
--- a/lib/inets/src/http_server/mod_range.erl
+++ b/lib/inets/src/http_server/mod_range.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/mod_responsecontrol.erl b/lib/inets/src/http_server/mod_responsecontrol.erl
index 6af5f6211e..9b410952f0 100644
--- a/lib/inets/src/http_server/mod_responsecontrol.erl
+++ b/lib/inets/src/http_server/mod_responsecontrol.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/http_server/mod_security.erl b/lib/inets/src/http_server/mod_security.erl
index 41988732ad..1f936d598a 100644
--- a/lib/inets/src/http_server/mod_security.erl
+++ b/lib/inets/src/http_server/mod_security.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -32,14 +33,13 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
--include("inets_internal.hrl").
-define(VMODULE,"SEC").
-
-%% do/1
+%%====================================================================
+%% Internal application API
+%%====================================================================
do(Info) ->
- ?hdrt("do", [{info, Info}]),
%% Check and see if any user has been authorized.
case proplists:get_value(remote_user, Info#mod.data,not_defined_user) of
not_defined_user ->
@@ -84,151 +84,66 @@ do(Info) ->
{_Dir, SDirData} = secretp(Path, Info#mod.config_db),
Addr = httpd_util:lookup(Info#mod.config_db, bind_address),
Port = httpd_util:lookup(Info#mod.config_db, port),
+ Profile = httpd_util:lookup(Info#mod.config_db, profile, ?DEFAULT_PROFILE),
case mod_security_server:check_blocked_user(Info, User,
SDirData,
- Addr, Port) of
+ Addr, Port, Profile) of
true ->
report_failed(Info, User ,"User Blocked"),
{proceed, [{status, {403, Info#mod.request_uri, ""}} |
Info#mod.data]};
false ->
report_failed(Info, User,"Authentication Succedded"),
- mod_security_server:store_successful_auth(Addr, Port,
+ mod_security_server:store_successful_auth(Addr, Port, Profile,
User,
SDirData),
{proceed, Info#mod.data}
end
end.
-report_failed(Info, Auth, Event) ->
- Request = Info#mod.request_line,
- {_PortNumber,RemoteHost}=(Info#mod.init_data)#init_data.peername,
- String = RemoteHost ++ " : " ++ Event ++ " : " ++ Request ++
- " : " ++ Auth,
- mod_disk_log:security_log(Info,String),
- mod_log:security_log(Info, String).
-
-take_failed_action(Info, Auth) ->
- ?hdrd("take failed action", [{auth, Auth}]),
- Path = mod_alias:path(Info#mod.data, Info#mod.config_db,
- Info#mod.request_uri),
- {_Dir, SDirData} = secretp(Path, Info#mod.config_db),
- Addr = httpd_util:lookup(Info#mod.config_db, bind_address),
- Port = httpd_util:lookup(Info#mod.config_db, port),
- mod_security_server:store_failed_auth(Info, Addr, Port,
- Auth, SDirData).
-
-secretp(Path, ConfigDB) ->
- Directories = ets:match(ConfigDB,{directory,{'$1','_'}}),
- case secret_path(Path, Directories) of
- {yes, Directory} ->
- ?hdrd("secretp - yes", [{dir, Directory}]),
- SDirs0 = httpd_util:multi_lookup(ConfigDB, security_directory),
- [SDir] = lists:filter(fun({Directory0, _})
- when Directory0 == Directory ->
- true;
- (_) ->
- false
- end, SDirs0),
- SDir;
- no ->
- {[], []}
- end.
-
-secret_path(Path,Directories) ->
- secret_path(Path, httpd_util:uniq(lists:sort(Directories)), to_be_found).
-
-secret_path(_Path, [], to_be_found) ->
- no;
-secret_path(_Path, [], Dir) ->
- {yes, Dir};
-secret_path(Path, [[NewDir]|Rest], Dir) ->
- case inets_regexp:match(Path, NewDir) of
- {match, _, _} when Dir =:= to_be_found ->
- secret_path(Path, Rest, NewDir);
- {match, _, Length} when Length > length(Dir) ->
- secret_path(Path, Rest, NewDir);
- {match, _, _} ->
- secret_path(Path, Rest, Dir);
- nomatch ->
- secret_path(Path, Rest, Dir)
- end.
-
-
load("<Directory " ++ Directory, []) ->
- ?hdrt("load security directory - begin", [{directory, Directory}]),
- Dir = httpd_conf:custom_clean(Directory,"",">"),
+ Dir = string:strip(string:strip(Directory),right, $>),
{ok, [{security_directory, {Dir, [{path, Dir}]}}]};
load(eof,[{security_directory, {Directory, _DirData}}|_]) ->
{error, ?NICE("Premature end-of-file in "++Directory)};
load("SecurityDataFile " ++ FileName,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{file, FileName}, {dir, Dir}, {dir_data, DirData}]),
- File = httpd_conf:clean(FileName),
+ File = string:strip(FileName),
{ok, [{security_directory, {Dir, [{data_file, File}|DirData]}}]};
load("SecurityCallbackModule " ++ ModuleName,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{module, ModuleName}, {dir, Dir}, {dir_data, DirData}]),
- Mod = list_to_atom(httpd_conf:clean(ModuleName)),
+ Mod = list_to_atom(string:strip(ModuleName)),
{ok, [{security_directory, {Dir, [{callback_module, Mod}|DirData]}}]};
load("SecurityMaxRetries " ++ Retries,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{max_retries, Retries}, {dir, Dir}, {dir_data, DirData}]),
load_return_int_tag("SecurityMaxRetries", max_retries,
- httpd_conf:clean(Retries), Dir, DirData);
+ string:strip(Retries), Dir, DirData);
load("SecurityBlockTime " ++ Time,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{block_time, Time}, {dir, Dir}, {dir_data, DirData}]),
load_return_int_tag("SecurityBlockTime", block_time,
- httpd_conf:clean(Time), Dir, DirData);
+ string:strip(Time), Dir, DirData);
load("SecurityFailExpireTime " ++ Time,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{expire_time, Time}, {dir, Dir}, {dir_data, DirData}]),
load_return_int_tag("SecurityFailExpireTime", fail_expire_time,
- httpd_conf:clean(Time), Dir, DirData);
+ string:strip(Time), Dir, DirData);
load("SecurityAuthTimeout " ++ Time0,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{auth_timeout, Time0}, {dir, Dir}, {dir_data, DirData}]),
- Time = httpd_conf:clean(Time0),
+ Time = string:strip(Time0),
load_return_int_tag("SecurityAuthTimeout", auth_timeout,
- httpd_conf:clean(Time), Dir, DirData);
+ string:strip(Time), Dir, DirData);
load("AuthName " ++ Name0,
[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory",
- [{name, Name0}, {dir, Dir}, {dir_data, DirData}]),
- Name = httpd_conf:clean(Name0),
+ Name = string:strip(Name0),
{ok, [{security_directory, {Dir, [{auth_name, Name}|DirData]}}]};
load("</Directory>",[{security_directory, {Dir, DirData}}]) ->
- ?hdrt("load security directory - end",
- [{dir, Dir}, {dir_data, DirData}]),
{ok, [], {security_directory, {Dir, DirData}}}.
-load_return_int_tag(Name, Atom, Time, Dir, DirData) ->
- case Time of
- "infinity" ->
- {ok, [{security_directory, {Dir,
- [{Atom, 99999999999999999999999999999} | DirData]}}]};
- _Int ->
- case catch list_to_integer(Time) of
- {'EXIT', _} ->
- {error, Time++" is an invalid "++Name};
- Val ->
- {ok, [{security_directory, {Dir, [{Atom, Val}|DirData]}}]}
- end
- end.
-
store({security_directory, {Dir, DirData}}, ConfigList)
when is_list(Dir) andalso is_list(DirData) ->
- ?hdrt("store security directory", [{dir, Dir}, {dir_data, DirData}]),
Addr = proplists:get_value(bind_address, ConfigList),
Port = proplists:get_value(port, ConfigList),
- mod_security_server:start(Addr, Port),
+ Profile = proplists:get_value(profile, ConfigList, ?DEFAULT_PROFILE),
+ mod_security_server:start(Addr, Port, Profile),
SR = proplists:get_value(server_root, ConfigList),
case proplists:get_value(data_file, DirData, no_data_file) of
no_data_file ->
@@ -241,7 +156,7 @@ store({security_directory, {Dir, DirData}}, ConfigList)
_ ->
DataFile0
end,
- case mod_security_server:new_table(Addr, Port, DataFile) of
+ case mod_security_server:new_table(Addr, Port, Profile, DataFile) of
{ok, TwoTables} ->
NewDirData0 = lists:keyreplace(data_file, 1, DirData,
{data_file, TwoTables}),
@@ -261,45 +176,35 @@ store({directory, {Directory, DirData}}, _) ->
{error, {wrong_type, {security_directory, {Directory, DirData}}}}.
remove(ConfigDB) ->
- Addr = case ets:lookup(ConfigDB, bind_address) of
- [] ->
- undefined;
- [{bind_address, Address}] ->
- Address
- end,
- [{port, Port}] = ets:lookup(ConfigDB, port),
- mod_security_server:delete_tables(Addr, Port),
- mod_security_server:stop(Addr, Port).
+ Addr = httpd_util:lookup(ConfigDB, bind_address, undefined),
+ Port = httpd_util:lookup(ConfigDB, port),
+ Profile = httpd_util:lookup(ConfigDB, profile, ?DEFAULT_PROFILE),
+ mod_security_server:delete_tables(Addr, Port, Profile),
+ mod_security_server:stop(Addr, Port, Profile).
-%%
-%% User API
-%%
-
-%% list_blocked_users
-
list_blocked_users(Port) ->
list_blocked_users(undefined, Port).
list_blocked_users(Port, Dir) when is_integer(Port) ->
list_blocked_users(undefined,Port,Dir);
list_blocked_users(Addr, Port) when is_integer(Port) ->
- mod_security_server:list_blocked_users(Addr, Port).
+ lists:map(fun({User, Addr0, Port0, ?DEFAULT_PROFILE, Dir0, Time}) ->
+ {User, Addr0, Port0, Dir0,Time}
+ end,
+ mod_security_server:list_blocked_users(Addr, Port)).
list_blocked_users(Addr, Port, Dir) ->
- mod_security_server:list_blocked_users(Addr, Port, Dir).
-
-
-%% block_user
+ lists:map(fun({User, Addr0, Port0, ?DEFAULT_PROFILE, Dir0, Time}) ->
+ {User, Addr0, Port0, Dir0,Time}
+ end,
+ mod_security_server:list_blocked_users(Addr, Port, Dir)).
block_user(User, Port, Dir, Time) ->
block_user(User, undefined, Port, Dir, Time).
block_user(User, Addr, Port, Dir, Time) ->
mod_security_server:block_user(User, Addr, Port, Dir, Time).
-
-%% unblock_user
-
unblock_user(User, Port) ->
unblock_user(User, undefined, Port).
@@ -311,9 +216,6 @@ unblock_user(User, Addr, Port) when is_integer(Port) ->
unblock_user(User, Addr, Port, Dir) ->
mod_security_server:unblock_user(User, Addr, Port, Dir).
-
-%% list_auth_users
-
list_auth_users(Port) ->
list_auth_users(undefined,Port).
@@ -324,3 +226,76 @@ list_auth_users(Addr, Port) when is_integer(Port) ->
list_auth_users(Addr, Port, Dir) ->
mod_security_server:list_auth_users(Addr, Port, Dir).
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+report_failed(Info, Auth, Event) ->
+ Request = Info#mod.request_line,
+ {_PortNumber,RemoteHost}=(Info#mod.init_data)#init_data.peername,
+ String = RemoteHost ++ " : " ++ Event ++ " : " ++ Request ++
+ " : " ++ Auth,
+ mod_disk_log:security_log(Info,String),
+ mod_log:security_log(Info, String).
+
+take_failed_action(Info, Auth) ->
+ Path = mod_alias:path(Info#mod.data, Info#mod.config_db,
+ Info#mod.request_uri),
+ {_Dir, SDirData} = secretp(Path, Info#mod.config_db),
+ Addr = httpd_util:lookup(Info#mod.config_db, bind_address),
+ Port = httpd_util:lookup(Info#mod.config_db, port),
+ Profile = httpd_util:lookup(Info#mod.config_db, profile, ?DEFAULT_PROFILE),
+ mod_security_server:store_failed_auth(Info, Addr, Port, Profile,
+ Auth, SDirData).
+
+secretp(Path, ConfigDB) ->
+ Directories = ets:match(ConfigDB,{directory,{'$1','_'}}),
+ case secret_path(Path, Directories) of
+ {yes, Directory} ->
+ SDirs0 = httpd_util:multi_lookup(ConfigDB, security_directory),
+ [SDir] = lists:filter(fun({Directory0, _})
+ when Directory0 == Directory ->
+ true;
+ (_) ->
+ false
+ end, SDirs0),
+ SDir;
+ no ->
+ {[], []}
+ end.
+
+secret_path(Path,Directories) ->
+ secret_path(Path, httpd_util:uniq(lists:sort(Directories)), to_be_found).
+
+secret_path(_Path, [], to_be_found) ->
+ no;
+secret_path(_Path, [], Dir) ->
+ {yes, Dir};
+secret_path(Path, [[NewDir]|Rest], Dir) ->
+ case re:run(Path, NewDir, [{capture, first}]) of
+ {match, _} when Dir =:= to_be_found ->
+ secret_path(Path, Rest, NewDir);
+ {match, [{_, Length}]} when Length > length(Dir) ->
+ secret_path(Path, Rest, NewDir);
+ {match, _} ->
+ secret_path(Path, Rest, Dir);
+ nomatch ->
+ secret_path(Path, Rest, Dir)
+ end.
+
+
+
+load_return_int_tag(Name, Atom, Time, Dir, DirData) ->
+ case Time of
+ "infinity" ->
+ {ok, [{security_directory, {Dir,
+ [{Atom, 99999999999999999999999999999} | DirData]}}]};
+ _Int ->
+ case catch list_to_integer(Time) of
+ {'EXIT', _} ->
+ {error, Time++" is an invalid "++Name};
+ Val ->
+ {ok, [{security_directory, {Dir, [{Atom, Val}|DirData]}}]}
+ end
+ end.
diff --git a/lib/inets/src/http_server/mod_security_server.erl b/lib/inets/src/http_server/mod_security_server.erl
index 784b3eba70..f9281b0fdc 100644
--- a/lib/inets/src/http_server/mod_security_server.erl
+++ b/lib/inets/src/http_server/mod_security_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -45,7 +46,6 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
--include("inets_internal.hrl").
-behaviour(gen_server).
@@ -57,129 +57,105 @@
list_auth_users/2, list_auth_users/3]).
%% Internal exports (for mod_security only)
--export([start/2, stop/1, stop/2,
- new_table/3, delete_tables/2,
- store_failed_auth/5, store_successful_auth/4,
- check_blocked_user/5]).
+-export([start/3, stop/2, stop/3,
+ new_table/4, delete_tables/3,
+ store_failed_auth/6, store_successful_auth/5,
+ check_blocked_user/6]).
%% gen_server exports
--export([start_link/2, init/1,
+-export([start_link/3, init/1,
handle_info/2, handle_call/3, handle_cast/2,
terminate/2,
code_change/3]).
+%%====================================================================
+%% Internal application API
+%%====================================================================
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%% External API %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% start_link/3
-%%
%% NOTE: This is called by httpd_misc_sup when the process is started
-%%
-
-start_link(Addr, Port) ->
- ?hdrt("start_link", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+start_link(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
gen_server:start_link({local, Name}, ?MODULE, [], [{timeout, infinity}]).
-
-%% start/2
%% Called by the mod_security module.
-
-start(Addr, Port) ->
- ?hdrt("start", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+start(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
case whereis(Name) of
undefined ->
- httpd_misc_sup:start_sec_server(Addr, Port);
+ httpd_misc_sup:start_sec_server(Addr, Port, Profile);
_ -> %% Already started...
ok
end.
-
-%% stop
-
-stop(Port) ->
- stop(undefined, Port).
-stop(Addr, Port) ->
- ?hdrt("stop", [{address, Addr}, {port, Port}]),
- Name = make_name(Addr, Port),
+stop(Port, Profile) ->
+ stop(undefined, Port, Profile).
+stop(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
case whereis(Name) of
undefined ->
ok;
_ ->
- httpd_misc_sup:stop_sec_server(Addr, Port)
+ httpd_misc_sup:stop_sec_server(Addr, Port, Profile)
end.
-
addr(undefined) ->
any;
addr(Addr) ->
Addr.
-
-%% list_blocked_users
-
list_blocked_users(Addr, Port) ->
- Name = make_name(Addr, Port),
- Req = {list_blocked_users, addr(Addr), Port, '_'},
- call(Name, Req).
-
+ list_blocked_users(Addr, Port, ?DEFAULT_PROFILE).
+list_blocked_users(Addr, Port, Profile) when is_atom(Profile)->
+ Name = make_name(Addr, Port, Profile),
+ Req = {list_blocked_users, addr(Addr), Port, Profile,'_'},
+ call(Name, Req);
list_blocked_users(Addr, Port, Dir) ->
- Name = make_name(Addr, Port),
- Req = {list_blocked_users, addr(Addr), Port, Dir},
+ list_blocked_users(Addr, Port, ?DEFAULT_PROFILE, Dir).
+list_blocked_users(Addr, Port, Profile, Dir) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {list_blocked_users, addr(Addr), Port, Profile, Dir},
call(Name, Req).
-
-%% block_user
-
block_user(User, Addr, Port, Dir, Time) ->
- Name = make_name(Addr, Port),
- Req = {block_user, User, addr(Addr), Port, Dir, Time},
+ block_user(User, Addr, Port, ?DEFAULT_PROFILE, Dir, Time).
+block_user(User, Addr, Port, Profile, Dir, Time) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {block_user, User, addr(Addr), Port, Profile, Dir, Time},
call(Name, Req).
-
-%% unblock_user
-
unblock_user(User, Addr, Port) ->
- Name = make_name(Addr, Port),
- Req = {unblock_user, User, addr(Addr), Port, '_'},
- call(Name, Req).
-
+ unblock_user(User, Addr, Port, ?DEFAULT_PROFILE).
+unblock_user(User, Addr, Port, Profile) when is_atom(Profile)->
+ Name = make_name(Addr, Port, Profile),
+ Req = {unblock_user, User, addr(Addr), Port, Profile, '_'},
+ call(Name, Req);
unblock_user(User, Addr, Port, Dir) ->
- Name = make_name(Addr, Port),
- Req = {unblock_user, User, addr(Addr), Port, Dir},
+ unblock_user(User, Addr, Port, ?DEFAULT_PROFILE, Dir).
+unblock_user(User, Addr, Port, Profile, Dir) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {unblock_user, User, addr(Addr), Port, Profile, Dir},
call(Name, Req).
-
-%% list_auth_users
-
list_auth_users(Addr, Port) ->
- Name = make_name(Addr, Port),
- Req = {list_auth_users, addr(Addr), Port, '_'},
- call(Name, Req).
-
+ list_auth_users(Addr, Port, ?DEFAULT_PROFILE).
+list_auth_users(Addr, Port, Profile) when is_atom(Profile) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {list_auth_users, addr(Addr), Port, Profile, '_'},
+ call(Name, Req);
list_auth_users(Addr, Port, Dir) ->
- Name = make_name(Addr,Port),
- Req = {list_auth_users, addr(Addr), Port, Dir},
+ list_auth_users(Addr, Port, ?DEFAULT_PROFILE, Dir).
+list_auth_users(Addr, Port, Profile, Dir) ->
+ Name = make_name(Addr,Port, Profile),
+ Req = {list_auth_users, addr(Addr), Port, Profile, Dir},
call(Name, Req).
-
-%% new_table
-
-new_table(Addr, Port, TabName) ->
- Name = make_name(Addr,Port),
- Req = {new_table, addr(Addr), Port, TabName},
+new_table(Addr, Port, Profile, TabName) ->
+ Name = make_name(Addr,Port, Profile),
+ Req = {new_table, addr(Addr), Port, Profile, TabName},
call(Name, Req).
-
-%% delete_tables
-
-delete_tables(Addr, Port) ->
- Name = make_name(Addr, Port),
+delete_tables(Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
case whereis(Name) of
undefined ->
ok;
@@ -187,79 +163,53 @@ delete_tables(Addr, Port) ->
call(Name, delete_tables)
end.
-
-%% store_failed_auth
-
-store_failed_auth(Info, Addr, Port, DecodedString, SDirData) ->
- ?hdrv("store failed auth",
- [{addr, Addr}, {port, Port},
- {decoded_string, DecodedString}, {sdir_data, SDirData}]),
- Name = make_name(Addr,Port),
- Msg = {store_failed_auth,[Info,DecodedString,SDirData]},
+store_failed_auth(Info, Addr, Port, Profile, DecodedString, SDirData) ->
+ Name = make_name(Addr, Port, Profile),
+ Msg = {store_failed_auth, Profile, [Info,DecodedString,SDirData]},
cast(Name, Msg).
-
-%% store_successful_auth
-
-store_successful_auth(Addr, Port, User, SDirData) ->
- Name = make_name(Addr,Port),
- Msg = {store_successful_auth, [User,Addr,Port,SDirData]},
+store_successful_auth(Addr, Port, Profile, User, SDirData) ->
+ Name = make_name(Addr,Port, Profile),
+ Msg = {store_successful_auth, [User,Addr,Port, Profile, SDirData]},
cast(Name, Msg).
-
-
-%% check_blocked_user
-
-check_blocked_user(Info, User, SDirData, Addr, Port) ->
- Name = make_name(Addr, Port),
- Req = {check_blocked_user, [Info, User, SDirData]},
+
+check_blocked_user(Info, User, SDirData, Addr, Port, Profile) ->
+ Name = make_name(Addr, Port, Profile),
+ Req = {check_blocked_user, Profile, [Info, User, SDirData]},
call(Name, Req).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%% Server call-back functions %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
+%%====================================================================
+%% Behavior call backs
+%%====================================================================
init(_) ->
- ?hdrv("initiating", []),
process_flag(trap_exit, true),
{ok, []}.
handle_call(stop, _From, _Tables) ->
{stop, normal, ok, []};
-handle_call({block_user, User, Addr, Port, Dir, Time}, _From, Tables) ->
- ?hdrv("block user",
- [{user, User}, {addr, Addr}, {port, Port}, {dir, Dir},
- {time, Time}]),
- Ret = block_user_int(User, Addr, Port, Dir, Time),
+handle_call({block_user, User, Addr, Port, Profile, Dir, Time}, _From, Tables) ->
+ Ret = block_user_int(User, Addr, Port, Profile, Dir, Time),
{reply, Ret, Tables};
-handle_call({list_blocked_users, Addr, Port, Dir}, _From, Tables) ->
- ?hdrv("list blocked users",
- [{addr, Addr}, {port, Port}, {dir, Dir}]),
- Blocked = list_blocked(Tables, Addr, Port, Dir, []),
+handle_call({list_blocked_users, Addr, Port, Profile, Dir}, _From, Tables) ->
+ Blocked = list_blocked(Tables, Addr, Port, Profile, Dir, []),
{reply, Blocked, Tables};
-handle_call({unblock_user, User, Addr, Port, Dir}, _From, Tables) ->
- ?hdrv("block user",
- [{user, User}, {addr, Addr}, {port, Port}, {dir, Dir}]),
- Ret = unblock_user_int(User, Addr, Port, Dir),
+handle_call({unblock_user, User, Addr, Port, Profile, Dir}, _From, Tables) ->
+ Ret = unblock_user_int(User, Addr, Port, Profile,Dir),
{reply, Ret, Tables};
-handle_call({list_auth_users, Addr, Port, Dir}, _From, Tables) ->
- ?hdrv("list auth users",
- [{addr, Addr}, {port, Port}, {dir, Dir}]),
- Auth = list_auth(Tables, Addr, Port, Dir, []),
+handle_call({list_auth_users, Addr, Port, Profile, Dir}, _From, Tables) ->
+ Auth = list_auth(Tables, Addr, Port, Profile, Dir, []),
{reply, Auth, Tables};
-handle_call({new_table, Addr, Port, Name}, _From, Tables) ->
+handle_call({new_table, Addr, Port, Profile, Name}, _From, Tables) ->
case lists:keysearch(Name, 1, Tables) of
{value, {Name, {Ets, Dets}}} ->
{reply, {ok, {Ets, Dets}}, Tables};
false ->
- TName = make_name(Addr,Port,length(Tables)),
+ TName = make_name(Addr,Port, Profile, length(Tables)),
case dets:open_file(TName, [{type, bag}, {file, Name},
{repair, true},
{access, read_write}]) of
@@ -280,7 +230,7 @@ handle_call(delete_tables, _From, Tables) ->
end, Tables),
{reply, ok, []};
-handle_call({check_blocked_user, [Info, User, SDirData]}, _From, Tables) ->
+handle_call({check_blocked_user, Profile, [Info, User, SDirData]}, _From, Tables) ->
{ETS, DETS} = proplists:get_value(data_file, SDirData),
Dir = proplists:get_value(path, SDirData),
Addr = proplists:get_value(bind_address, SDirData),
@@ -288,27 +238,24 @@ handle_call({check_blocked_user, [Info, User, SDirData]}, _From, Tables) ->
CBModule =
proplists:get_value(callback_module, SDirData, no_module_at_all),
Ret =
- check_blocked_user(Info, User, Dir, Addr, Port, ETS, DETS, CBModule),
+ check_blocked_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, CBModule),
{reply, Ret, Tables};
handle_call(_Request,_From,Tables) ->
{reply,ok,Tables}.
-
-%% handle_cast
-
-handle_cast({store_failed_auth, [_, _, []]}, Tables) ->
+handle_cast({store_failed_auth, _,[_, _, []]}, Tables) ->
%% Some other authentication scheme than mod_auth (example mod_htacess)
%% was the source for the authentication failure so we should ignor it!
{noreply, Tables};
-handle_cast({store_failed_auth, [Info, DecodedString, SDirData]}, Tables) ->
+handle_cast({store_failed_auth, Profile, [Info, DecodedString, SDirData]}, Tables) ->
{ETS, DETS} = proplists:get_value(data_file, SDirData),
Dir = proplists:get_value(path, SDirData),
Addr = proplists:get_value(bind_address, SDirData),
Port = proplists:get_value(port, SDirData),
{ok, [User,Password]} = httpd_util:split(DecodedString,":",2),
Seconds = universal_time(),
- Key = {User, Dir, Addr, Port},
+ Key = {User, Dir, Addr, Port, Profile},
%% Event
CBModule = proplists:get_value(callback_module,
SDirData, no_module_at_all),
@@ -363,7 +310,7 @@ handle_cast({store_failed_auth, [Info, DecodedString, SDirData]}, Tables) ->
dets:match_delete(DETS, {blocked_user,
{User, Addr, Port, Dir, '$1'}}),
BlockRecord = {blocked_user,
- {User, Addr, Port, Dir, Future}},
+ {User, Addr, Port, Profile, Dir, Future}},
ets:insert(ETS, BlockRecord),
dets:insert(DETS, BlockRecord),
%% Remove previous failed requests.
@@ -374,11 +321,11 @@ handle_cast({store_failed_auth, [Info, DecodedString, SDirData]}, Tables) ->
end,
{noreply, Tables};
-handle_cast({store_successful_auth, [User, Addr, Port, SDirData]}, Tables) ->
+handle_cast({store_successful_auth, [User, Addr, Port, Profile, SDirData]}, Tables) ->
{ETS, DETS} = proplists:get_value(data_file, SDirData),
AuthTimeOut = proplists:get_value(auth_timeout, SDirData, 30),
Dir = proplists:get_value(path, SDirData),
- Key = {User, Dir, Addr, Port},
+ Key = {User, Dir, Addr, Port, Profile},
%% Remove failed entries for this Key
dets:match_delete(DETS, {failed, {Key, '_', '_'}}),
@@ -396,33 +343,22 @@ handle_cast(Req, Tables) ->
error_msg("security server got unknown cast: ~p",[Req]),
{noreply, Tables}.
-
-%% handle_info
-
handle_info(_Info, State) ->
{noreply, State}.
-
-%% terminate
-
terminate(_Reason, _Tables) ->
ok.
-
-%% code_change({down, ToVsn}, State, Extra)
-%%
-code_change({down, _}, State, _Extra) ->
- {ok, State};
-
-
-%% code_change(FromVsn, State, Extra)
-%%
code_change(_, State, _Extra) ->
{ok, State}.
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
%% block_user_int/5
-block_user_int(User, Addr, Port, Dir, Time) ->
- Dirs = httpd_manager:config_match(Addr, Port,
+block_user_int(User, Addr, Port, Profile, Dir, Time) ->
+ Dirs = httpd_manager:config_match(Addr, Port, Profile,
{security_directory, {'_', '_'}}),
case find_dirdata(Dirs, Dir) of
{ok, DirData, {ETS, DETS}} ->
@@ -434,11 +370,11 @@ block_user_int(User, Addr, Port, Dir, Time) ->
Time
end,
Future = universal_time()+Time1,
- ets:match_delete(ETS, {blocked_user, {User,Addr,Port,Dir,'_'}}),
+ ets:match_delete(ETS, {blocked_user, {User,Addr,Port,Profile, Dir,'_'}}),
dets:match_delete(DETS, {blocked_user,
- {User,Addr,Port,Dir,'_'}}),
- ets:insert(ETS, {blocked_user, {User,Addr,Port,Dir,Future}}),
- dets:insert(DETS, {blocked_user, {User,Addr,Port,Dir,Future}}),
+ {User,Addr,Port,Profile, Dir,'_'}}),
+ ets:insert(ETS, {blocked_user, {User,Addr,Port, Profile, Dir,Future}}),
+ dets:insert(DETS, {blocked_user, {User,Addr,Port,Profile, Dir,Future}}),
CBModule = proplists:get_value(callback_module, DirData,
no_module_at_all),
user_block_event(CBModule,Addr,Port,Dir,User),
@@ -447,7 +383,6 @@ block_user_int(User, Addr, Port, Dir, Time) ->
{error, no_such_directory}
end.
-
find_dirdata([], _Dir) ->
false;
find_dirdata([{security_directory, {_, DirData}}|SDirs], Dir) ->
@@ -460,21 +395,20 @@ find_dirdata([{security_directory, {_, DirData}}|SDirs], Dir) ->
find_dirdata(SDirs, Dir)
end.
-%% unblock_user_int/4
-unblock_user_int(User, Addr, Port, Dir) ->
- Dirs = httpd_manager:config_match(Addr, Port,
+unblock_user_int(User, Addr, Port, Profile, Dir) ->
+ Dirs = httpd_manager:config_match(Addr, Port, Profile,
{security_directory, {'_', '_'}}),
case find_dirdata(Dirs, Dir) of
{ok, DirData, {ETS, DETS}} ->
case ets:match_object(ETS,
- {blocked_user,{User,Addr,Port,Dir,'_'}}) of
+ {blocked_user,{User,Addr,Port,Profile,Dir,'_'}}) of
[] ->
{error, not_blocked};
_Objects ->
ets:match_delete(ETS, {blocked_user,
- {User, Addr, Port, Dir, '_'}}),
+ {User, Addr, Port, Profile, Dir, '_'}}),
dets:match_delete(DETS, {blocked_user,
- {User, Addr, Port, Dir, '_'}}),
+ {User, Addr, Port, Profile, Dir, '_'}}),
CBModule = proplists:get_value(callback_module,
DirData,
no_module_at_all),
@@ -485,63 +419,51 @@ unblock_user_int(User, Addr, Port, Dir) ->
{error, no_such_directory}
end.
-
-
-%% list_auth/2
-
-list_auth([], _Addr, _Port, _Dir, Acc) ->
+list_auth([], _, _, _, _, Acc) ->
Acc;
-list_auth([{_Name, {ETS, DETS}}|Tables], Addr, Port, Dir, Acc) ->
- case ets:match_object(ETS, {success, {{'_', Dir, Addr, Port}, '_'}}) of
+list_auth([{_Name, {ETS, DETS}}|Tables], Addr, Port, Profile, Dir, Acc) ->
+ case ets:match_object(ETS, {success, {{'_', Dir, Addr, Port, Profile}, '_'}}) of
[] ->
- list_auth(Tables, Addr, Port, Dir, Acc);
+ list_auth(Tables, Addr, Port, Profile, Dir, Acc);
List ->
TN = universal_time(),
- NewAcc = lists:foldr(fun({success,{{U,Ad,P,D},T}},Ac) ->
+ NewAcc = lists:foldr(fun({success,{{U,Ad,P, Pr,D},T}},Ac) ->
if
T-TN > 0 ->
[U|Ac];
true ->
Rec = {success,
- {{U,Ad,P,D},T}},
+ {{U,Ad,P,Pr,D},T}},
ets:match_delete(ETS,Rec),
dets:match_delete(DETS,Rec),
Ac
end
end,
Acc, List),
- list_auth(Tables, Addr, Port, Dir, NewAcc)
+ list_auth(Tables, Addr, Port, Profile, Dir, NewAcc)
end.
-
-%% list_blocked/2
-
-list_blocked([], _Addr, _Port, _Dir, Acc) ->
- ?hdrv("list blocked", [{acc, Acc}]),
+list_blocked([], _, _, _, _, Acc) ->
TN = universal_time(),
- lists:foldl(fun({U,Ad,P,D,T}, Ac) ->
+ lists:foldl(fun({U,Ad,P,Pr,D,T}, Ac) ->
if
T-TN > 0 ->
- [{U,Ad,P,D,local_time(T)}|Ac];
+ [{U,Ad,P, Pr,D,local_time(T)}|Ac];
true ->
Ac
end
end,
[], Acc);
-list_blocked([{_Name, {ETS, _DETS}}|Tables], Addr, Port, Dir, Acc) ->
- ?hdrv("list blocked", [{ets, ETS}, {tab2list, ets:tab2list(ETS)}]),
+list_blocked([{_Name, {ETS, _DETS}}|Tables], Addr, Port, Profile, Dir, Acc) ->
List = ets:match_object(ETS, {blocked_user,
- {'_',Addr,Port,Dir,'_'}}),
+ {'_',Addr,Port,Profile, Dir,'_'}}),
NewBlocked = lists:foldl(fun({blocked_user, X}, A) ->
[X|A] end, Acc, List),
- list_blocked(Tables, Addr, Port, Dir, NewBlocked).
+ list_blocked(Tables, Addr, Port, Profile, Dir, NewBlocked).
-%%
-%% sync_dets_to_ets/2
-%%
%% Reads dets-table DETS and syncronizes it with the ets-table ETS.
%%
sync_dets_to_ets(DETS, ETS) ->
@@ -550,68 +472,62 @@ sync_dets_to_ets(DETS, ETS) ->
continue
end).
-%%
-%% check_blocked_user/7 -> true | false
-%%
%% Check if a specific user is blocked from access.
%%
%% The sideeffect of this routine is that it unblocks also other users
%% whos blocking time has expired. This to keep the tables as small
%% as possible.
%%
-check_blocked_user(Info, User, Dir, Addr, Port, ETS, DETS, CBModule) ->
+check_blocked_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, CBModule) ->
TN = universal_time(),
- BlockList = ets:match_object(ETS, {blocked_user, {User, '_', '_', '_', '_'}}),
+ BlockList = ets:match_object(ETS, {blocked_user, {User, '_', '_', '_', '_', '_'}}),
Blocked = lists:foldl(fun({blocked_user, X}, A) ->
[X|A] end, [], BlockList),
check_blocked_user(Info,User,Dir,
- Addr,Port,ETS,DETS,TN,Blocked,CBModule).
+ Addr,Port, Profile, ETS,DETS,TN,Blocked,CBModule).
-check_blocked_user(_Info, _User, _Dir, _Addr, _Port, _ETS, _DETS, _TN,
- [], _CBModule) ->
+check_blocked_user(_Info, _, _, _, _, _, _, _, _,[], _CBModule) ->
false;
-check_blocked_user(Info, User, Dir, Addr, Port, ETS, DETS, TN,
- [{User,Addr,Port,Dir,T}| _], CBModule) ->
+check_blocked_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, TN,
+ [{User,Addr,Port,Profile, Dir,T}| _], CBModule) ->
TD = T-TN,
if
TD =< 0 ->
%% Blocking has expired, remove and grant access.
- unblock_user(Info, User, Dir, Addr, Port, ETS, DETS, CBModule),
+ unblock_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, CBModule),
false;
true ->
true
end;
-check_blocked_user(Info, User, Dir, Addr, Port, ETS, DETS, TN,
- [{OUser,ODir,OAddr,OPort,T}|Ls], CBModule) ->
+check_blocked_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, TN,
+ [{OUser,ODir,OAddr,OPort, OProfile, T}|Ls], CBModule) ->
TD = T-TN,
if
TD =< 0 ->
%% Blocking has expired, remove.
- unblock_user(Info, OUser, ODir, OAddr, OPort,
+ unblock_user(Info, OUser, ODir, OAddr, OPort, OProfile,
ETS, DETS, CBModule);
true ->
true
end,
- check_blocked_user(Info, User, Dir, Addr, Port, ETS, DETS,
+ check_blocked_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS,
TN, Ls, CBModule).
-unblock_user(Info, User, Dir, Addr, Port, ETS, DETS, CBModule) ->
+unblock_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, CBModule) ->
Reason =
io_lib:format("User ~s was removed from the block list for dir ~s",
[User, Dir]),
mod_log:security_log(Info, lists:flatten(Reason)),
user_unblock_event(CBModule,Addr,Port,Dir,User),
- dets:match_delete(DETS, {blocked_user, {User, Addr, Port, Dir, '_'}}),
- ets:match_delete(ETS, {blocked_user, {User, Addr, Port, Dir, '_'}}).
+ dets:match_delete(DETS, {blocked_user, {User, Addr, Port, Profile, Dir, '_'}}),
+ ets:match_delete(ETS, {blocked_user, {User, Addr, Port, Profile, Dir, '_'}}).
+make_name(Addr,Port, Profile) ->
+ httpd_util:make_name(?MODULE_STRING, Addr, Port, Profile).
-make_name(Addr,Port) ->
- httpd_util:make_name("httpd_security",Addr,Port).
-
-make_name(Addr,Port,Num) ->
- httpd_util:make_name("httpd_security",Addr,Port,
- "__" ++ integer_to_list(Num)).
-
+make_name(Addr,Port, Profile, Num) ->
+ httpd_util:make_name(?MODULE_STRING, Addr,Port,
+ atom_to_list(Profile) ++ "__" ++ integer_to_list(Num)).
auth_fail_event(Mod,Addr,Port,Dir,User,Passwd) ->
event(auth_fail,Mod,Addr,Port,Dir,[{user,User},{password,Passwd}]).
@@ -623,17 +539,10 @@ user_unblock_event(Mod,Addr,Port,Dir,User) ->
event(user_unblock,Mod,Addr,Port,Dir,[{user,User}]).
event(Event, Mod, undefined, Port, Dir, Info) ->
- ?hdrt("event",
- [{event, Event}, {mod, Mod}, {port, Port}, {dir, Dir}]),
(catch Mod:event(Event,Port,Dir,Info));
event(Event, Mod, any, Port, Dir, Info) ->
- ?hdrt("event",
- [{event, Event}, {mod, Mod}, {port, Port}, {dir, Dir}]),
(catch Mod:event(Event,Port,Dir,Info));
event(Event, Mod, Addr, Port, Dir, Info) ->
- ?hdrt("event",
- [{event, Event}, {mod, Mod},
- {addr, Addr}, {port, Port}, {dir, Dir}]),
(catch Mod:event(Event,Addr,Port,Dir,Info)).
universal_time() ->
@@ -643,11 +552,9 @@ local_time(T) ->
calendar:universal_time_to_local_time(
calendar:gregorian_seconds_to_datetime(T)).
-
error_msg(F, A) ->
error_logger:error_msg(F, A).
-
call(Name, Req) ->
case (catch gen_server:call(Name, Req)) of
{'EXIT', Reason} ->
@@ -656,7 +563,6 @@ call(Name, Req) ->
Reply
end.
-
cast(Name, Msg) ->
case (catch gen_server:cast(Name, Msg)) of
{'EXIT', Reason} ->
diff --git a/lib/inets/src/http_server/mod_trace.erl b/lib/inets/src/http_server/mod_trace.erl
index 7233925783..e1cb428264 100644
--- a/lib/inets/src/http_server/mod_trace.erl
+++ b/lib/inets/src/http_server/mod_trace.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 22426eee79..7f51676dc5 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2005-2012. All Rights Reserved.
+# Copyright Ericsson AB 2005-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -46,8 +47,10 @@ MODULES = \
inets_service \
inets_app \
inets_sup \
- inets_regexp \
- inets_trace
+ inets_trace \
+ inets_lib \
+ inets_time_compat \
+ inets_regexp
INTERNAL_HRL_FILES = inets_internal.hrl
EXTERNAL_HRL_FILES = ../../include/httpd.hrl \
diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src
index 48660bec62..c09139872f 100644
--- a/lib/inets/src/inets_app/inets.app.src
+++ b/lib/inets/src/inets_app/inets.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -25,8 +26,10 @@
inets_sup,
inets_app,
inets_service,
- inets_regexp,
- inets_trace,
+ inets_trace,
+ inets_lib,
+ inets_time_compat,
+ inets_regexp,
%% FTP
ftp,
@@ -62,6 +65,7 @@
httpd_connection_sup,
httpd_conf,
httpd_custom,
+ httpd_custom_api,
httpd_esi,
httpd_example,
httpd_file,
@@ -91,7 +95,6 @@
mod_get,
mod_head,
mod_htaccess,
- mod_include,
mod_log,
mod_range,
mod_responsecontrol,
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 90524ac367..a9fbb1c3f7 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -3,23 +3,26 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
[
+ {<<"6\\..*">>,[{restart_application, inets}]},
{<<"5\\..*">>,[{restart_application, inets}]}
],
[
+ {<<"6\\..*">>,[{restart_application, inets}]},
{<<"5\\..*">>,[{restart_application, inets}]}
]
}.
diff --git a/lib/inets/src/inets_app/inets.erl b/lib/inets/src/inets_app/inets.erl
index ed8082534f..2a40f73889 100644
--- a/lib/inets/src/inets_app/inets.erl
+++ b/lib/inets/src/inets_app/inets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/inets_app/inets.mk b/lib/inets/src/inets_app/inets.mk
index adef32dc19..2c85173c68 100644
--- a/lib/inets/src/inets_app/inets.mk
+++ b/lib/inets/src/inets_app/inets.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2010-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/inets/src/inets_app/inets_app.erl b/lib/inets/src/inets_app/inets_app.erl
index ee3359c4c3..3e4718070c 100644
--- a/lib/inets/src/inets_app/inets_app.erl
+++ b/lib/inets/src/inets_app/inets_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/inets_app/inets_internal.hrl b/lib/inets/src/inets_app/inets_internal.hrl
index 06843f2275..cc794d27c0 100644
--- a/lib/inets/src/inets_app/inets_internal.hrl
+++ b/lib/inets/src/inets_app/inets_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/inets_app/inets_lib.erl b/lib/inets/src/inets_app/inets_lib.erl
new file mode 100644
index 0000000000..6e16f5ef6e
--- /dev/null
+++ b/lib/inets/src/inets_app/inets_lib.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(inets_lib).
+
+-export([millisec_passed/1, formated_timestamp/0, format_timestamp/1]).
+
+
+
+%% Help function, elapsed milliseconds since T0
+millisec_passed({_,_,_} = T0 ) ->
+ %% OTP 17 and earlier
+ timer:now_diff(inets_time_compat:timestamp(), T0) div 1000;
+
+millisec_passed(T0) ->
+ %% OTP 18
+ erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native,
+ micro_seconds) div 1000.
+
+%% Return formated time stamp (e.g. 2015:03:16 10:05:23 1234)
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+%% Return formated time stamp (e.g. 2015:03:16 10:05:23 1234)
+format_timestamp({_N1, _N2, N3} = Tme) ->
+ {Date, Time} = calendar:now_to_datetime(Tme),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
diff --git a/lib/inets/src/inets_app/inets_regexp.erl b/lib/inets/src/inets_app/inets_regexp.erl
index a065533236..fc1608bc5a 100644
--- a/lib/inets/src/inets_app/inets_regexp.erl
+++ b/lib/inets/src/inets_app/inets_regexp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/inets_app/inets_service.erl b/lib/inets/src/inets_app/inets_service.erl
index d17fdfe13e..706915de92 100644
--- a/lib/inets/src/inets_app/inets_service.erl
+++ b/lib/inets/src/inets_app/inets_service.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/src/inets_app/inets_sup.erl b/lib/inets/src/inets_app/inets_sup.erl
index 66a0cdf785..a48a8db190 100644
--- a/lib/inets/src/inets_app/inets_sup.erl
+++ b/lib/inets/src/inets_app/inets_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/inets_app/inets_time_compat.erl b/lib/inets/src/inets_app/inets_time_compat.erl
new file mode 100644
index 0000000000..475f0685dc
--- /dev/null
+++ b/lib/inets/src/inets_app/inets_time_compat.erl
@@ -0,0 +1,72 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+%%
+
+%% This module is created to be able to execute on ERTS versions both
+%% earlier and later than 7.0.
+
+-module(inets_time_compat).
+
+%% We don't want warnings about the use of erlang:now/0 in
+%% this module.
+-compile(nowarn_deprecated_function).
+
+-export([monotonic_time/0,
+ timestamp/0,
+ unique_integer/0,
+ unique_integer/1]).
+
+monotonic_time() ->
+ try
+ erlang:monotonic_time()
+ catch
+ error:undef ->
+ %% Use Erlang system time as monotonic time
+ erlang_system_time_fallback()
+ end.
+
+timestamp() ->
+ try
+ erlang:timestamp()
+ catch
+ error:undef ->
+ erlang:now()
+ end.
+
+unique_integer() ->
+ try
+ erlang:unique_integer()
+ catch
+ error:undef ->
+ erlang_system_time_fallback()
+ end.
+
+unique_integer(Modifiers) ->
+ try
+ erlang:unique_integer(Modifiers)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Modifiers]);
+ error:undef ->
+ erlang_system_time_fallback()
+ end.
+
+erlang_system_time_fallback() ->
+ {MS, S, US} = erlang:now(),
+ (MS*1000000+S)*1000000+US.
diff --git a/lib/inets/src/inets_app/inets_trace.erl b/lib/inets/src/inets_app/inets_trace.erl
index 8911f65897..64ab9bec35 100644
--- a/lib/inets/src/inets_app/inets_trace.erl
+++ b/lib/inets/src/inets_app/inets_trace.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -228,21 +229,24 @@ handle_trace({trace_ts, _Who, call,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
{_, standard_io} = Fd) ->
- (catch io:format(standard_io, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(standard_io, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
Fd;
handle_trace({trace_ts, _Who, call,
{?MODULE, report_event,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
standard_io = Fd) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(Fd, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
Fd;
handle_trace({trace_ts, _Who, call,
{?MODULE, report_event,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
{_Service, Fd}) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(Fd, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
(catch file:close(Fd)),
closed_file;
handle_trace({trace_ts, _Who, call,
@@ -250,7 +254,8 @@ handle_trace({trace_ts, _Who, call,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
Fd) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(Fd, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
(catch file:close(Fd)),
closed_file;
handle_trace({trace_ts, Who, call,
@@ -280,7 +285,7 @@ print_inets_trace(Fd, Sev, Timestamp, Who, Label, Service, Content) ->
do_print_inets_trace(Fd, Sev, Timestamp, Who, Label, Service, Content).
do_print_inets_trace(Fd, Sev, Timestamp, Who, Label, Service, Content) ->
- Ts = format_timestamp(Timestamp),
+ Ts = inets_lib:format_timestamp(Timestamp),
io:format(Fd, "[inets ~w trace ~w ~w ~s] ~s "
"~n Content: ~p"
"~n",
@@ -307,7 +312,7 @@ do_print_trace(Fd, {trace, Who, What, Where, Extra}) ->
"~n", [Who, What, Where, Extra]);
do_print_trace(Fd, {trace_ts, Who, What, Where, When}) ->
- Ts = format_timestamp(When),
+ Ts = inets_lib:format_timestamp(When),
io:format(Fd, "[trace ~s]"
"~n Who: ~p"
"~n What: ~p"
@@ -315,7 +320,7 @@ do_print_trace(Fd, {trace_ts, Who, What, Where, When}) ->
"~n", [Ts, Who, What, Where]);
do_print_trace(Fd, {trace_ts, Who, What, Where, Extra, When}) ->
- Ts = format_timestamp(When),
+ Ts = inets_lib:format_timestamp(When),
io:format(Fd, "[trace ~s]"
"~n Who: ~p"
"~n What: ~p"
@@ -330,7 +335,7 @@ do_print_trace(Fd, {seq_trace, What, Where}) ->
"~n", [What, Where]);
do_print_trace(Fd, {seq_trace, What, Where, When}) ->
- Ts = format_timestamp(When),
+ Ts = inets_lib:format_timestamp(When),
io:format(Fd, "[seq trace ~s]"
"~n What: ~p"
"~n Where: ~p"
@@ -345,13 +350,3 @@ do_print_trace(Fd, Trace) ->
"~n", [Trace]).
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
-
diff --git a/lib/inets/src/tftp/Makefile b/lib/inets/src/tftp/Makefile
index b368b12462..d5d94e1b78 100644
--- a/lib/inets/src/tftp/Makefile
+++ b/lib/inets/src/tftp/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/src/tftp/tftp.erl b/lib/inets/src/tftp/tftp.erl
index 1621add246..45d7852863 100644
--- a/lib/inets/src/tftp/tftp.erl
+++ b/lib/inets/src/tftp/tftp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/tftp/tftp.hrl b/lib/inets/src/tftp/tftp.hrl
index 6846b07690..2cea18a7ea 100644
--- a/lib/inets/src/tftp/tftp.hrl
+++ b/lib/inets/src/tftp/tftp.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/tftp/tftp_binary.erl b/lib/inets/src/tftp/tftp_binary.erl
index 9efa79105d..6981d741c6 100644
--- a/lib/inets/src/tftp/tftp_binary.erl
+++ b/lib/inets/src/tftp/tftp_binary.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/tftp/tftp_engine.erl b/lib/inets/src/tftp/tftp_engine.erl
index 81c53bbe40..493a29a68f 100644
--- a/lib/inets/src/tftp/tftp_engine.erl
+++ b/lib/inets/src/tftp/tftp_engine.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -127,8 +128,8 @@ daemon_start(Options) when is_list(Options) ->
daemon_init(Config) when is_record(Config, config),
is_pid(Config#config.parent_pid) ->
process_flag(trap_exit, true),
- UdpOptions = prepare_daemon_udp(Config),
- case catch gen_udp:open(Config#config.udp_port, UdpOptions) of
+ {Port, UdpOptions} = prepare_daemon_udp(Config),
+ case catch gen_udp:open(Port, UdpOptions) of
{ok, Socket} ->
{ok, ActualPort} = inet:port(Socket),
proc_lib:init_ack({ok, self()}),
@@ -156,7 +157,7 @@ prepare_daemon_udp(#config{udp_port = Port, udp_options = UdpOptions} = Config)
case lists:keymember(fd, 1, UdpOptions) of
true ->
%% Use explicit fd
- UdpOptions;
+ {Port, UdpOptions};
false ->
%% Use fd from setuid_socket_wrap, such as -tftpd_69
InitArg = list_to_atom("tftpd_" ++ integer_to_list(Port)),
@@ -164,7 +165,7 @@ prepare_daemon_udp(#config{udp_port = Port, udp_options = UdpOptions} = Config)
{ok, [[FdStr]] = Badarg} when is_list(FdStr) ->
case catch list_to_integer(FdStr) of
Fd when is_integer(Fd) ->
- [{fd, Fd} | UdpOptions];
+ {0, [{fd, Fd} | lists:keydelete(ip, 1, UdpOptions)]};
{'EXIT', _} ->
Text = lists:flatten(io_lib:format("Illegal prebound fd ~p: ~p", [InitArg, Badarg])),
print_debug_info(Config, daemon, open, ?ERROR(open, undef, Text, "")),
@@ -175,7 +176,7 @@ prepare_daemon_udp(#config{udp_port = Port, udp_options = UdpOptions} = Config)
print_debug_info(Config, daemon, open, ?ERROR(open, undef, Text, "")),
exit({badarg, {prebound_fd, InitArg, Badarg}});
error ->
- UdpOptions
+ {Port, UdpOptions}
end
end.
@@ -655,22 +656,11 @@ common_read(Config, Callback, Req, _LocalAccess, ExpectedBlockNo, ActualBlockNo,
do_common_read(Config, Callback, Req, LocalAccess, BlockNo, Data, Prepared)
when is_binary(Data), is_record(Prepared, prepared) ->
- NextBlockNo = BlockNo + 1,
- case NextBlockNo =< 65535 of
- true ->
- Reply = #tftp_msg_data{block_no = NextBlockNo, data = Data},
- {Config2, Callback2, TransferRes} =
- transfer(Config, Callback, Req, Reply, LocalAccess, NextBlockNo, Prepared),
- ?MODULE:common_loop(Config2, Callback2, Req, TransferRes, LocalAccess, NextBlockNo);
- false ->
- Code = badblk,
- Text = "Too big transfer ID = " ++
- integer_to_list(NextBlockNo) ++ " > 65535",
- {undefined, Error} =
- callback({abort, {Code, Text}}, Config, Callback, Req),
- send_msg(Config, Req, Error),
- terminate(Config, Req, ?ERROR(read, Code, Text, Req#tftp_msg_req.filename))
- end.
+ NextBlockNo = (BlockNo + 1) rem 65536,
+ Reply = #tftp_msg_data{block_no = NextBlockNo, data = Data},
+ {Config2, Callback2, TransferRes} =
+ transfer(Config, Callback, Req, Reply, LocalAccess, NextBlockNo, Prepared),
+ ?MODULE:common_loop(Config2, Callback2, Req, TransferRes, LocalAccess, NextBlockNo).
-spec common_write(#config{}, #callback{}, _, 'write', integer(), integer(), _, #prepared{}) -> no_return().
@@ -714,21 +704,10 @@ common_write(Config, Callback, Req, _, ExpectedBlockNo, ActualBlockNo, Data, Pre
common_ack(Config, Callback, Req, LocalAccess, BlockNo, Prepared)
when is_record(Prepared, prepared) ->
Reply = #tftp_msg_ack{block_no = BlockNo},
- NextBlockNo = BlockNo + 1,
+ NextBlockNo = (BlockNo + 1) rem 65536,
{Config2, Callback2, TransferRes} =
transfer(Config, Callback, Req, Reply, LocalAccess, NextBlockNo, Prepared),
- case NextBlockNo =< 65535 of
- true ->
- ?MODULE:common_loop(Config2, Callback2, Req, TransferRes, LocalAccess, NextBlockNo);
- false ->
- Code = badblk,
- Text = "Too big transfer ID = " ++
- integer_to_list(NextBlockNo) ++ " > 65535",
- {undefined, Error} =
- callback({abort, {Code, Text}}, Config, Callback2, Req),
- send_msg(Config, Req, Error),
- terminate(Config, Req, ?ERROR(read, Code, Text, Req#tftp_msg_req.filename))
- end.
+ ?MODULE:common_loop(Config2, Callback2, Req, TransferRes, LocalAccess, NextBlockNo).
pre_terminate(Config, Req, Result) ->
if
@@ -1152,8 +1131,8 @@ match_callback(Filename, Callbacks) ->
end.
do_match_callback(Filename, [C | Tail]) when is_record(C, callback) ->
- case catch inets_regexp:match(Filename, C#callback.internal) of
- {match, _, _} ->
+ case catch re:run(Filename, C#callback.internal, [{capture, none}]) of
+ match ->
{ok, C};
nomatch ->
do_match_callback(Filename, Tail);
diff --git a/lib/inets/src/tftp/tftp_file.erl b/lib/inets/src/tftp/tftp_file.erl
index e0cbb49330..39382d6fd0 100644
--- a/lib/inets/src/tftp/tftp_file.erl
+++ b/lib/inets/src/tftp/tftp_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/src/tftp/tftp_lib.erl b/lib/inets/src/tftp/tftp_lib.erl
index ffb7b9a797..01dea97d07 100644
--- a/lib/inets/src/tftp/tftp_lib.erl
+++ b/lib/inets/src/tftp/tftp_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -183,7 +184,7 @@ do_parse_config([{Key, Val} | Tail], Config) when is_record(Config, config) ->
callback ->
case Val of
{RegExp, Mod, State} when is_list(RegExp), is_atom(Mod) ->
- case inets_regexp:parse(RegExp) of
+ case re:compile(RegExp) of
{ok, Internal} ->
Callback = #callback{regexp = RegExp,
internal = Internal,
@@ -252,7 +253,7 @@ do_parse_config(Options, Config) when is_record(Config, config) ->
add_default_callbacks(Callbacks) ->
RegExp = "",
- {ok, Internal} = inets_regexp:parse(RegExp),
+ {ok, Internal} = re:compile(RegExp),
File = #callback{regexp = RegExp,
internal = Internal,
module = tftp_file,
diff --git a/lib/inets/src/tftp/tftp_logger.erl b/lib/inets/src/tftp/tftp_logger.erl
index 0c3620e665..5e5d1d56c7 100644
--- a/lib/inets/src/tftp/tftp_logger.erl
+++ b/lib/inets/src/tftp/tftp_logger.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -84,8 +85,8 @@ info_msg(Format, Data) ->
%%-------------------------------------------------------------------
add_timestamp(Format, Data) ->
- Now = {_MegaSecs, _Secs, _MicroSecs} = erlang:now(),
- {{_Y, _Mo, _D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
+ Time = inets_time_compat:timestamp(),
+ {{_Y, _Mo, _D}, {H, Mi, S}} = calendar:now_to_universal_time(Time),
%% {"~p-~s-~sT~s:~s:~sZ,~6.6.0w tftp: " ++ Format ++ "\n",
%% [Y, t(Mo), t(D), t(H), t(Mi), t(S), MicroSecs | Data]}.
{"~s:~s:~s tftp: " ++ Format, [t(H), t(Mi), t(S) | Data]}.
diff --git a/lib/inets/src/tftp/tftp_sup.erl b/lib/inets/src/tftp/tftp_sup.erl
index 1cafcc1069..98b92cc87c 100644
--- a/lib/inets/src/tftp/tftp_sup.erl
+++ b/lib/inets/src/tftp/tftp_sup.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -93,7 +94,7 @@ unique_name(Options) ->
{value, {_, Port}} when is_integer(Port), Port > 0 ->
{tftpd, Port};
_ ->
- {tftpd, erlang:now()}
+ {tftpd, inets_time_compat:unique_integer([positive])}
end.
default_kill_after() ->
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
index 609396273d..607ec7c182 100644
--- a/lib/inets/test/Makefile
+++ b/lib/inets/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -173,7 +174,8 @@ MODULES = \
inets_appup_test \
tftp_test_lib \
tftp_SUITE \
- uri_SUITE
+ uri_SUITE \
+ inets_socketwrap_SUITE
EBIN = .
@@ -202,7 +204,7 @@ INETS_FILES = inets.config $(INETS_SPECS)
# inets_ftp_suite \
# inets_tftp_suite
-INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data
+INETS_DATADIRS = inets_SUITE_data inets_socketwrap_SUITE_data
HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data httpd_basic_SUITE_data old_httpd_SUITE_data
HTTPC_DATADIRS = httpc_SUITE_data httpc_proxy_SUITE_data
FTP_DATADIRS = ftp_SUITE_data
@@ -249,7 +251,7 @@ ERL_COMPILE_FLAGS += \
# 1) INETS_PRIV_DIR must be created
# ----------------------------------------------------
-tests debug opt: $(BUILDTARGET)
+tests debug opt: $(BUILDTARGET)
targets: $(TARGET_FILES)
diff --git a/lib/inets/test/erl_make_certs.erl b/lib/inets/test/erl_make_certs.erl
index 22dc951ac1..f7666864ff 100644
--- a/lib/inets/test/erl_make_certs.erl
+++ b/lib/inets/test/erl_make_certs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -204,7 +205,7 @@ issuer_der(Issuer) ->
Subject.
subject(undefined, IsRootCA) ->
- User = if IsRootCA -> "RootCA"; true -> user() end,
+ User = if IsRootCA -> "RootCA"; true -> os:getenv("USER", "test_user") end,
Opts = [{email, User ++ "@erlang.org"},
{name, User},
{city, "Stockholm"},
@@ -215,14 +216,6 @@ subject(undefined, IsRootCA) ->
subject(Opts, _) ->
subject(Opts).
-user() ->
- case os:getenv("USER") of
- false ->
- "test_user";
- User ->
- User
- end.
-
subject(SubjectOpts) when is_list(SubjectOpts) ->
Encode = fun(Opt) ->
{Type,Value} = subject_enc(Opt),
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
index e39f9f1eb6..12c8185187 100644
--- a/lib/inets/test/ftp_SUITE.erl
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl
index 16e5cdb4bc..7ed94b9c61 100644
--- a/lib/inets/test/ftp_format_SUITE.erl
+++ b/lib/inets/test/ftp_format_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/ftp_property_test_SUITE.erl b/lib/inets/test/ftp_property_test_SUITE.erl
index c7077421f4..984fb58f16 100644
--- a/lib/inets/test/ftp_property_test_SUITE.erl
+++ b/lib/inets/test/ftp_property_test_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
index daee1bdcdc..6d30f3aa62 100644
--- a/lib/inets/test/ftp_suite_lib.erl
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1352,9 +1353,9 @@ do_delete(Pid, Config) ->
ok.
do_mkdir(Pid) ->
- {A, B, C} = erlang:now(),
- NewDir = "nisse_" ++ integer_to_list(A) ++ "_" ++
- integer_to_list(B) ++ "_" ++ integer_to_list(C),
+ NewDir = "earl_" ++
+ integer_to_list(inets_time_compat:unique_integer([positive])),
+
ok = ftp:cd(Pid, "incoming"),
{ok, CurrDir} = ftp:pwd(Pid),
{error, efnamena} = ftp:mkdir(Pid, NewDir++"\r\nCWD ."),
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index 5952e9fd6e..e977bd1b9b 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -3,42 +3,29 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(http_format_SUITE).
--author('[email protected]').
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include("http_internal.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]).
-
-%% Test cases must be exported.
--export([ chunk_decode/1, chunk_encode/1,
- chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
- chunk_decode_empty_chunk_otp_6511/1,
- chunk_decode_trailer/1,
- http_response/1, http_request/1, validate_request_line/1,
- esi_parse_headers/1, cgi_parse_headers/1,
- is_absolut_uri/1, convert_netscapecookie_date/1,
- check_content_length_encoding/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
all() ->
[{group, chunk}, http_response, http_request,
@@ -51,7 +38,8 @@ groups() ->
[chunk_decode, chunk_encode, chunk_extensions_otp_6005,
chunk_decode_otp_6264,
chunk_decode_empty_chunk_otp_6511,
- chunk_decode_trailer]}].
+ chunk_whitespace_suffix,
+ chunk_decode_trailer, chunk_max_headersize, chunk_max_bodysize, chunk_not_hex]}].
init_per_suite(Config) ->
Config.
@@ -80,12 +68,8 @@ end_per_testcase(_, Config) ->
%% Test cases starts here.
%%-------------------------------------------------------------------------
-
-%%-------------------------------------------------------------------------
-chunk_decode(doc) ->
- ["Test http_chunk:decode/3"];
-chunk_decode(suite) ->
- [];
+chunk_decode() ->
+ [{doc, "Test http_chunk:decode/3"}].
chunk_decode(Config) when is_list(Config) ->
ReqHeaders = #http_request_h{'transfer-encoding' = "chunked"},
ChunkedBody = "A" ++ ?CRLF ++ "1234567890" ++ ?CRLF ++ "4" ++
@@ -108,15 +92,11 @@ chunk_decode(Config) when is_list(Config) ->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, Body} = parse(Module, Function, Args, tl(NewChunkedBody)),
- "1234567890HEJ!" = binary_to_list(Body),
-
- ok.
+ "1234567890HEJ!" = binary_to_list(Body).
%%-------------------------------------------------------------------------
-chunk_extensions_otp_6005(doc) ->
- ["Make sure so called extensions are ignored"];
-chunk_extensions_otp_6005(suite) ->
- [];
+chunk_extensions_otp_6005() ->
+ [{doc, "Make sure so called extensions are ignored"}].
chunk_extensions_otp_6005(Config) when is_list(Config)->
ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
@@ -135,14 +115,11 @@ chunk_extensions_otp_6005(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody1)),
- "1234567890HEJ!" = binary_to_list(NewBody),
- ok.
+ "1234567890HEJ!" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_decode_otp_6264(doc) ->
- ["Check that 0 in the body does not count as the last chunk"];
-chunk_decode_otp_6264(suite) ->
- [];
+chunk_decode_otp_6264() ->
+ [{doc, "Check that 0 in the body does not count as the last chunk"}].
chunk_decode_otp_6264(Config) when is_list(Config)->
ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
?CRLF ++ "4" ++ ?CRLF ++ "0123"++ ?CRLF ++ "0" ++
@@ -172,27 +149,33 @@ chunk_decode_otp_6264(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(NewChunkedBody1)),
- "12345678900" = binary_to_list(NewBody),
-
- ok.
+ "12345678900" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_decode_empty_chunk_otp_6511(doc) ->
- [""];
-chunk_decode_empty_chunk_otp_6511(suite) ->
- [];
chunk_decode_empty_chunk_otp_6511(Config) when is_list(Config) ->
ChunkedBody = "0" ++ ?CRLF ++ ?CRLF,
{ok,{["content-length:0"],<<>>}} =
http_chunk:decode(list_to_binary(ChunkedBody),
- ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
- ok.
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE).
%%-------------------------------------------------------------------------
-chunk_decode_trailer(doc) ->
- ["Make sure trailers are handled correctly. Trailers should"
- "become new headers"];
-chunk_decode_trailer(suite) ->
- [];
+chunk_whitespace_suffix() ->
+ [{doc, "Test whitespace after chunked length header"}].
+chunk_whitespace_suffix(Config) when is_list(Config) ->
+ ChunkedBody = "1a ; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10 " ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0 " ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:42", "another-footer:another-value",
+ "some-footer:some-value", ""],
+ <<"abcdefghijklmnopqrstuvwxyz1234567890abcdef">>}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE).
+
+%%-------------------------------------------------------------------------
+chunk_decode_trailer() ->
+ [{doc,"Make sure trailers are handled correctly. Trailers should"
+ "become new headers"}].
chunk_decode_trailer(Config) when is_list(Config)->
ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
"abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
@@ -248,30 +231,79 @@ chunk_decode_trailer(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody3)),
- "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
-
- ok.
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_encode(doc) ->
- ["Test http_chunk:encode/1 & http_chunk:encode_last/0"];
-chunk_encode(suite) ->
- [];
+chunk_encode() ->
+ [{doc, "Test http_chunk:encode/1 & http_chunk:encode_last/0"}].
chunk_encode(Config) when is_list(Config) ->
<<54, ?CR, ?LF, 102,111,111,98,97,114, ?CR, ?LF>> =
http_chunk:encode(list_to_binary("foobar")),
["6", ?CR, ?LF,"foobar", ?CR, ?LF] = http_chunk:encode("foobar"),
- <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last(),
- ok.
-
+ <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last().
+%%-------------------------------------------------------------------------
+chunk_max_headersize() ->
+ [{doc, "Test max header limit"}].
+chunk_max_headersize(Config) when is_list(Config) ->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {_, _}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% Too long in length header
+ {error,{header_too_long, {max, 1}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 1)),
+
+ %% Too long in extension field
+ {error,{header_too_long, {max, 10}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 10)),
+
+ %% Too long in trailer
+ {error,{header_too_long, {max, 30}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 30)).
+%%-------------------------------------------------------------------------
+chunk_not_hex() ->
+ [{doc, "Test bad chunked length header"}].
+chunk_not_hex(Config) when is_list(Config) ->
+ ChunkedBody = "åäö; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {error,{chunk_size, "åäö"}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE)).
+%%-------------------------------------------------------------------------
+chunk_max_bodysize() ->
+ [{doc, "Test max body limit"}].
+chunk_max_bodysize(Config) when is_list(Config) ->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {ok, {_, _}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% Too long body
+ {error,{body_too_big, {max, 10}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ 10, ?HTTP_MAX_HEADER_SIZE)).
%%-------------------------------------------------------------------------
-http_response(doc) ->
- ["Test httpc_response:parse*. This test case will simulate that the "
+http_response() ->
+ [{doc, "Test httpc_response:parse*. This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-http_response(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
http_response(Config) when is_list(Config) ->
HttpHead1 = ["HTTP", "/1.1 ", "20", "0 ", "ok", [?CR, ?LF],
@@ -339,12 +371,10 @@ http_response(Config) when is_list(Config) ->
[<<>>,Length1], HttpBody1)),
ok.
%%-------------------------------------------------------------------------
-http_request(doc) ->
- ["Test httpd_request:parse* This test case will simulate that the "
+http_request() ->
+ [{doc, "Test httpd_request:parse* This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-http_request(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
http_request(Config) when is_list(Config) ->
HttpHead = ["GE", "T ", "http://www.erlang", ".org ", "HTTP",
@@ -406,15 +436,12 @@ http_request(Config) when is_list(Config) ->
NewBody1 =
binary_to_list(parse
(httpd_request, whole_body,
- [<<>>, Length1], HttpBody1)),
- ok.
+ [<<>>, Length1], HttpBody1)).
%%-------------------------------------------------------------------------
-validate_request_line(doc) ->
- ["Test httpd_request:validate/3. Makes sure you can not get past"
+validate_request_line() ->
+ [{doc, "Test httpd_request:validate/3. Makes sure you can not get past"
" the server_root and that the request is recognized by the server"
- " and protcol version." ];
-validate_request_line(suite) ->
- [];
+ " and protcol version."}].
validate_request_line(Config) when is_list(Config) ->
%% HTTP/0.9 only has GET requests
@@ -467,16 +494,12 @@ validate_request_line(Config) when is_list(Config) ->
NewForbiddenUri1 =
"http://127.0.0.1:8888/../home/ingela/test.html",
{error, {bad_request, {forbidden, NewForbiddenUri1}}} =
- httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1"),
-
- ok.
+ httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1").
%%-------------------------------------------------------------------------
-check_content_length_encoding(doc) ->
- ["Test http_request:headers/2. Check that the content-length is"
- " encoded even when it is zero." ];
-check_content_length_encoding(suite) ->
- [];
+check_content_length_encoding() ->
+ [{doc, "Test http_request:headers/2. Check that the content-length is"
+ " encoded even when it is zero."}].
check_content_length_encoding(Config) when is_list(Config) ->
%% Check that the content-length is preserved.
@@ -485,16 +508,12 @@ check_content_length_encoding(Config) when is_list(Config) ->
true = (string:str(Header1, "content-length: 123\r\n") > 0),
%% Check that content-length=0 is handled correctly.
Header2 = http_request:http_headers(#http_request_h{'content-length'="0"}),
- true = (string:str(Header2, "content-length: 0\r\n") > 0),
-
- ok.
+ true = (string:str(Header2, "content-length: 0\r\n") > 0).
%%-------------------------------------------------------------------------
-esi_parse_headers(doc) ->
- ["Test httpd_esi:*. All header values are received in the same"
- " erlang message."];
-esi_parse_headers(suite) ->
- [];
+esi_parse_headers() ->
+ [{doc, "Test httpd_esi:*. All header values are received in the same"
+ " erlang message."}].
esi_parse_headers(Config) when is_list(Config) ->
ESIResult = "content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 "
@@ -521,16 +540,14 @@ esi_parse_headers(Config) when is_list(Config) ->
httpd_esi:handle_headers(Headers2),
{proceed,"/foo/bar.html"} =
- httpd_esi:handle_headers("location:/foo/bar.html\r\n"),
- ok.
+ httpd_esi:handle_headers("location:/foo/bar.html\r\n").
%%--------------------------------------------------------------------
-cgi_parse_headers(doc) ->
- ["Test httpd_cgi:*. This test case will simulate that the "
+cgi_parse_headers() ->
+ [{doc, "Test httpd_cgi:*. This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-cgi_parse_headers(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
+
cgi_parse_headers(Config) when is_list(Config) ->
CGIResult = ["content-type:text", "/html\ndate:Thu, 28 Oct 2004 07:57:43 "
@@ -566,26 +583,18 @@ cgi_parse_headers(Config) when is_list(Config) ->
{ok,[{"content-type","text/html"},
{"connection","close"},
{"content-language","en"},
- {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3),
-
- ok.
-
+ {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3).
%%-------------------------------------------------------------------------
-is_absolut_uri(doc) ->
- ["Test http_request:is_absolut_uri/1."];
-is_absolut_uri(suite) ->
- [];
+is_absolut_uri() ->
+ [{doc, "Test http_request:is_absolut_uri/1."}].
is_absolut_uri(Config) when is_list(Config) ->
true = http_request:is_absolut_uri("http://www.erlang.org"),
true = http_request:is_absolut_uri("https://www.erlang.org"),
false = http_request:is_absolut_uri("index.html").
-
%%-------------------------------------------------------------------------
-convert_netscapecookie_date(doc) ->
- ["Test http_util:convert_netscapecookie_date/1."];
-convert_netscapecookie_date(suite) ->
- [];
+convert_netscapecookie_date() ->
+ [{doc, "Test http_util:convert_netscapecookie_date/1."}].
convert_netscapecookie_date(Config) when is_list(Config) ->
{{2006,1,6},{8,59,38}} =
http_util:convert_netscapecookie_date("Mon, 06-Jan-2006 08:59:38 GMT"),
@@ -618,9 +627,7 @@ convert_netscapecookie_date(Config) when is_list(Config) ->
{{2006,12,12},{8,59,38}} =
http_util:convert_netscapecookie_date("Sun 12-Dec-06 08:59:38 GMT"),
{{2036,1,1},{8,0,1}} =
- http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT"),
- ok.
-
+ http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT").
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 4b1c6931d2..93b96e101f 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -28,6 +29,7 @@
-include_lib("common_test/include/ct.hrl").
-include("inets_test_lib.hrl").
-include("http_internal.hrl").
+-include("httpc_internal.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
@@ -66,6 +68,7 @@ real_requests()->
get,
post,
post_stream,
+ patch,
async,
pipeline,
persistent_connection,
@@ -96,16 +99,21 @@ only_simulated() ->
stream_once,
stream_single_chunk,
stream_no_length,
+ not_streamed_once,
+ stream_large_not_200_or_206,
no_content_204,
tolerate_missing_CR,
userinfo,
bad_response,
internal_server_error,
invalid_http,
+ invalid_chunk_size,
headers_dummy,
+ headers_with_obs_fold,
empty_response_header,
remote_socket_close,
remote_socket_close_async,
+ process_leak_on_keepalive,
transfer_encoding,
transfer_encoding_identity,
redirect_loop,
@@ -250,6 +258,28 @@ post(Config) when is_list(Config) ->
"text/plain", "foobar"}, [], []).
%%--------------------------------------------------------------------
+patch() ->
+ [{"Test http patch request against local server. We do in this case "
+ "only care about the client side of the the patch. The server "
+ "script will not actually use the patch data."}].
+patch(Config) when is_list(Config) ->
+ CGI = case test_server:os_type() of
+ {win32, _} ->
+ "/cgi-bin/cgi_echo.exe";
+ _ ->
+ "/cgi-bin/cgi_echo"
+ end,
+
+ URL = url(group_name(Config), CGI, Config),
+
+ %% Cgi-script expects the body length to be 100
+ Body = lists:duplicate(100, "1"),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ httpc:request(patch, {URL, [{"expect","100-continue"}],
+ "text/plain", Body}, [], []).
+
+%%--------------------------------------------------------------------
post_stream() ->
[{"Test streaming http post request against local server. "
"We only care about the client side of the the post. "
@@ -404,6 +434,21 @@ stream_no_length(Config) when is_list(Config) ->
stream_test(Request1, {stream, self}),
Request2 = {url(group_name(Config), "/http_1_0_no_length_multiple.html", Config), []},
stream_test(Request2, {stream, self}).
+%%-------------------------------------------------------------------------
+stream_large_not_200_or_206() ->
+ [{doc, "Test the option stream for large responses with status codes "
+ "other than 200 or 206" }].
+stream_large_not_200_or_206(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/large_404_response.html", Config), []},
+ {404, _} = not_streamed_test(Request, {stream, self}).
+%%-------------------------------------------------------------------------
+not_streamed_once() ->
+ [{doc, "Test not streamed responses with once streaming"}].
+not_streamed_once(Config) when is_list(Config) ->
+ Request0 = {url(group_name(Config), "/404.html", Config), []},
+ {404, _} = not_streamed_test(Request0, {stream, {self, once}}),
+ Request1 = {url(group_name(Config), "/404_chunked.html", Config), []},
+ {404, _} = not_streamed_test(Request1, {stream, {self, once}}).
%%-------------------------------------------------------------------------
@@ -744,6 +789,22 @@ invalid_http(Config) when is_list(Config) ->
ct:print("Parse error: ~p ~n", [Reason]).
%%-------------------------------------------------------------------------
+
+invalid_chunk_size(doc) ->
+ ["Test parse error of HTTP chunk size"];
+invalid_chunk_size(suite) ->
+ [];
+invalid_chunk_size(Config) when is_list(Config) ->
+
+ URL = url(group_name(Config), "/invalid_chunk_size.html", Config),
+
+ {error, {chunk_size, _} = Reason} =
+ httpc:request(get, {URL, []}, [], []),
+
+ ct:print("Parse error: ~p ~n", [Reason]).
+
+%%-------------------------------------------------------------------------
+
emulate_lower_versions(doc) ->
[{doc, "Perform request as 0.9 and 1.0 clients."}];
emulate_lower_versions(Config) when is_list(Config) ->
@@ -890,6 +951,13 @@ headers_dummy(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+headers_with_obs_fold(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/obs_folded_headers.html", Config), []},
+ {ok, {{_,200,_}, Headers, [_|_]}} = httpc:request(get, Request, [], []),
+ "a b" = proplists:get_value("folded", Headers).
+
+%%-------------------------------------------------------------------------
+
invalid_headers(Config) ->
Request = {url(group_name(Config), "/dummy.html", Config), [{"cookie", undefined}]},
{error, _} = httpc:request(get, Request, [], []).
@@ -913,6 +981,33 @@ remote_socket_close_async(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+process_leak_on_keepalive(Config) ->
+ {ok, ClosedSocket} = gen_tcp:listen(6666, [{active, false}]),
+ ok = gen_tcp:close(ClosedSocket),
+ Request = {url(group_name(Config), "/dummy.html", Config), []},
+ HttpcHandlers0 = supervisor:which_children(httpc_handler_sup),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ HttpcHandlers1 = supervisor:which_children(httpc_handler_sup),
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ %% Assuming that the new handler will be selected for keep_alive
+ %% which could not be the case if other handlers existed
+ [{undefined, Pid, worker, [httpc_handler]}] =
+ ordsets:to_list(
+ ordsets:subtract(ordsets:from_list(HttpcHandlers1),
+ ordsets:from_list(HttpcHandlers0))),
+ sys:replace_state(
+ Pid, fun (State) ->
+ Session = element(3, State),
+ setelement(3, State, Session#session{socket=ClosedSocket})
+ end),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ %% bad handler with the closed socket should get replaced by
+ %% the new one, so children count should stay the same
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ ok.
+
+%%-------------------------------------------------------------------------
+
stream_to_pid(Config) when is_list(Config) ->
ReceiverPid = create_receiver(pid),
Receiver = ReceiverPid,
@@ -1079,6 +1174,19 @@ stream_test(Request, To) ->
Body = binary_to_list(StreamedBody).
+not_streamed_test(Request, To) ->
+ {ok, {{_,Code,_}, [_ | _], Body}} =
+ httpc:request(get, Request, [], [{body_format, binary}]),
+ {ok, RequestId} =
+ httpc:request(get, Request, [], [{body_format, binary}, {sync, false}, To]),
+
+ receive
+ {http, {RequestId, {{_, Code, _}, _Headers, Body}}} ->
+ {Code, binary_to_list(Body)};
+ {http, Msg} ->
+ ct:fail(Msg)
+ end.
+
url(http, End, Config) ->
Port = ?config(port, Config),
{ok,Host} = inet:gethostname(),
@@ -1610,6 +1718,11 @@ handle_uri(_,"/307.html",Port,_,Socket,_) ->
"Content-Length:" ++ integer_to_list(length(Body))
++ "\r\n\r\n" ++ Body;
+handle_uri(_,"/404.html",_,_,_,_) ->
+ "HTTP/1.1 404 not found\r\n" ++
+ "Content-Length:14\r\n\r\n" ++
+ "Page not found";
+
handle_uri(_,"/500.html",_,_,_,_) ->
"HTTP/1.1 500 Internal Server Error\r\n" ++
"Content-Length:47\r\n\r\n" ++
@@ -1683,6 +1796,13 @@ handle_uri(_,"/dummy_headers.html",_,_,Socket,_) ->
send(Socket, http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/obs_folded_headers.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n"
+ "Content-Length:5\r\n"
+ "Folded: a\r\n"
+ " b\r\n\r\n"
+ "Hello";
+
handle_uri(_,"/capital_transfer_encoding.html",_,_,Socket,_) ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n",
@@ -1738,6 +1858,15 @@ handle_uri(_,"/once_chunked.html",_,_,Socket,_) ->
http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/404_chunked.html",_,_,Socket,_) ->
+ Head = "HTTP/1.1 404 not found\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ send(Socket, Head),
+ send(Socket, http_chunk:encode("<HTML><BODY>Not ")),
+ send(Socket,
+ http_chunk:encode("found</BODY></HTML>")),
+ http_chunk:encode_last();
+
handle_uri(_,"/single_chunk.html",_,_,Socket,_) ->
Chunk = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n" ++
@@ -1762,6 +1891,17 @@ handle_uri(_,"/http_1_0_no_length_multiple.html",_,_,Socket,_) ->
send(Socket, string:copies("other multiple packets ", 200)),
close(Socket);
+handle_uri(_,"/large_404_response.html",_,_,Socket,_) ->
+ %% long body to make sure it will be sent in multiple tcp packets
+ Body = string:copies("other multiple packets ", 200),
+ Head = io_lib:format("HTTP/1.1 404 not found\r\n"
+ "Content-length: ~B\r\n"
+ "Content-type: text/plain\r\n\r\n",
+ [length(Body)]),
+ send(Socket, Head),
+ send(Socket, Body),
+ close(Socket);
+
handle_uri(_,"/once.html",_,_,Socket,_) ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Content-Length:32\r\n\r\n",
@@ -1776,6 +1916,10 @@ handle_uri(_,"/invalid_http.html",_,_,_,_) ->
"HTTP/1.1 301\r\nDate:Sun, 09 Dec 2007 13:04:18 GMT\r\n" ++
"Transfer-Encoding:chunked\r\n\r\n";
+handle_uri(_,"/invalid_chunk_size.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:chunked\r\n\r\nåäö\r\n";
+
handle_uri(_,"/missing_reason_phrase.html",_,_,_,_) ->
"HTTP/1.1 200\r\n" ++
"Content-Length: 32\r\n\r\n"
@@ -1909,12 +2053,13 @@ run_clients(NumClients, ServerPort, SeqNumServer) ->
wait4clients([], _Timeout) ->
ok;
wait4clients(Clients, Timeout) when Timeout > 0 ->
- Time = now_ms(),
+ Time = inets_time_compat:monotonic_time(),
+
receive
{'DOWN', _MRef, process, Pid, normal} ->
{value, {Id, _, _}} = lists:keysearch(Pid, 2, Clients),
NewClients = lists:keydelete(Id, 1, Clients),
- wait4clients(NewClients, Timeout - (now_ms() - Time));
+ wait4clients(NewClients, Timeout - inets_lib:millisec_passed(Time));
{'DOWN', _MRef, process, Pid, Reason} ->
{value, {Id, _, _}} = lists:keysearch(Pid, 2, Clients),
ct:fail({bad_client_termination, Id, Reason})
@@ -2007,14 +2152,10 @@ parse_connection_type(Request) ->
"keep-alive" -> keep_alive
end.
-%% Time in milli seconds
-now_ms() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
set_random_seed() ->
- {_, _, Micros} = now(),
- A = erlang:phash2([make_ref(), self(), Micros]),
+ Unique = inets_time_compat:unique_integer(),
+
+ A = erlang:phash2([make_ref(), self(), Unique]),
random:seed(A, A, A).
diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
index 80f43ec236..9a62bdb43f 100644
--- a/lib/inets/test/httpc_cookie_SUITE.erl
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/test/httpc_proxy_SUITE.erl b/lib/inets/test/httpc_proxy_SUITE.erl
index ddd23d0c65..6d7af4ea5d 100644
--- a/lib/inets/test/httpc_proxy_SUITE.erl
+++ b/lib/inets/test/httpc_proxy_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -57,7 +58,7 @@ groups() ->
[http_emulate_lower_versions
|local_proxy_cases()]},
{local_proxy_https,[],
- local_proxy_cases()}].
+ local_proxy_cases() ++ local_proxy_https_cases()}].
%% internal functions
@@ -76,10 +77,13 @@ local_proxy_cases() ->
http_stream,
http_not_modified_otp_6821].
+local_proxy_https_cases() ->
+ [https_connect_error].
+
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
- case init_apps([crypto,public_key], Config0) of
+ case init_apps(suite_apps(), Config0) of
Config when is_list(Config) ->
make_cert_files(dsa, "server-", Config),
Config;
@@ -94,7 +98,7 @@ end_per_suite(_Config) ->
%% internal functions
suite_apps() ->
- [crypto,public_key].
+ [asn1,crypto,public_key].
%%--------------------------------------------------------------------
@@ -431,6 +435,21 @@ header_value(Name, [{HeaderName,HeaderValue}|Headers]) ->
end.
%%--------------------------------------------------------------------
+https_connect_error(doc) ->
+ ["Error from CONNECT tunnel should be returned"];
+https_connect_error(Config) when is_list(Config) ->
+ {HttpServer,HttpPort} = ?config(http, Config),
+ Method = get,
+ %% using HTTPS scheme with HTTP port to trigger connection error
+ URL = "https://" ++ HttpServer ++ ":" ++
+ integer_to_list(HttpPort) ++ "/index.html",
+ Opts = [],
+ HttpOpts = [],
+ Request = {URL,[]},
+ {error,{failed_connect,[_,{tls,_,_}]}} =
+ httpc:request(Method, Request, HttpOpts, Opts).
+
+%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf b/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf
index 37af88c510..03f80aaf6d 100644
--- a/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf
+++ b/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh b/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh
index 4b05ea63ef..473024ae63 100755
--- a/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh
+++ b/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh
@@ -7,16 +7,17 @@
##
## Copyright Ericsson AB 2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
@@ -168,6 +169,8 @@ MaxRequestsPerChild 0
ViaProxyName "tinyproxy"
ConnectPort $APACHE_HTTPS_PORT
+# to test connect error
+ConnectPort $APACHE_HTTP_PORT
EOF
(tinyproxy -d -c tinyproxy.conf 1>/dev/null 2>&1 </dev/null &)&
wait_for_pidfile tinyproxy.pid
diff --git a/lib/inets/test/httpd_1_0.erl b/lib/inets/test/httpd_1_0.erl
index 0836c9e881..7535b148ae 100644
--- a/lib/inets/test/httpd_1_0.erl
+++ b/lib/inets/test/httpd_1_0.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
index 6a5fc4a18f..d3a1e3672a 100644
--- a/lib/inets/test/httpd_1_1.erl
+++ b/lib/inets/test/httpd_1_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -23,7 +24,7 @@
-include_lib("kernel/include/file.hrl").
-export([host/4, chunked/4, expect/4, range/4, if_test/5, trace/4,
- head/4, mod_cgi_chunked_encoding_test/5]).
+ head/4, mod_cgi_chunked_encoding_test/5, mod_esi_chunk_timeout/4]).
%% -define(all_keys_lower_case,true).
-ifndef(all_keys_lower_case).
@@ -273,6 +274,15 @@ mod_cgi_chunked_encoding_test(Type, Port, Host, Node, [Request| Rest])->
[{statuscode, 200}]),
mod_cgi_chunked_encoding_test(Type, Port, Host, Node, Rest).
+
+mod_esi_chunk_timeout(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example/chunk_timeout?input=20000 HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "\r\n",
+ [{statuscode, 200},
+ {header, "warning"}]).
+
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
@@ -360,18 +370,18 @@ validateRangeRequest2(Socket, Head, Body, ValidBody, BodySize)
validateMultiPartRangeRequest(Body, ValidBody, Boundary)->
- case inets_regexp:split(Body,"--"++Boundary++"--") of
+ case re:split(Body,"--"++Boundary++"--", [{return, list}]) of
%%Last is the epilogue and must be ignored
- {ok,[First | _Last]}->
+ [First | _Last]->
%%First is now the actuall http request body.
- case inets_regexp:split(First, "--" ++ Boundary) of
+ case re:split(First, "--" ++ Boundary, [{return, list}]) of
%%Parts is now a list of ranges and the heads for each range
%%Gues we try to split out the body
- {ok,Parts}->
+ Parts->
case lists:flatten(lists:map(fun splitRange/1,Parts)) of
ValidBody->
ok;
- ParsedBody->
+ ParsedBody->
error = ParsedBody
end
end;
@@ -381,8 +391,8 @@ validateMultiPartRangeRequest(Body, ValidBody, Boundary)->
splitRange(Part)->
- case inets_regexp:split(Part, "\r\n\r\n") of
- {ok,[_, Body]} ->
+ case re:split(Part, "\r\n\r\n", [{return, list}]) of
+ [_, Body] ->
string:substr(Body, 1, length(Body) - 2);
_ ->
[]
@@ -402,13 +412,13 @@ getRangeSize(Head)->
{multiPart, BoundaryString}->
{multiPart, BoundaryString};
_X1 ->
- case inets_regexp:match(Head, ?CONTENT_RANGE "bytes=.*\r\n") of
- {match, Start, Lenght} ->
+ case re:run(Head, ?CONTENT_RANGE "bytes=.*\r\n", [{capture, first}]) of
+ {match, [{Start, Lenght}]} ->
%% Get the range data remove the fieldname and the
%% end of line.
- RangeInfo = string:substr(Head, Start + 20,
- Lenght - (20 - 2)),
- rangeSize(RangeInfo);
+ RangeInfo = string:substr(Head, Start + 1 + 20,
+ Lenght - (20 +2)),
+ rangeSize(string:strip(RangeInfo));
_X2 ->
error
end
@@ -444,10 +454,10 @@ num(_CharVal, false) ->
true.
controlMimeType(Head)->
- case inets_regexp:match(Head,?CONTENT_TYPE "multipart/byteranges.*\r\n") of
- {match,Start,Length}->
+ case re:run(Head,?CONTENT_TYPE "multipart/byteranges.*\r\n", [{capture, first}]) of
+ {match, [{Start,Length}]}->
FieldNameLen = length(?CONTENT_TYPE "multipart/byteranges"),
- case clearBoundary(string:substr(Head, Start + FieldNameLen,
+ case clearBoundary(string:substr(Head, Start + 1 + FieldNameLen,
Length - (FieldNameLen+2))) of
error ->
error;
@@ -461,10 +471,10 @@ controlMimeType(Head)->
end.
clearBoundary(Boundary)->
- case inets_regexp:match(Boundary, "boundary=.*\$") of
- {match, Start1, Length1}->
+ case re:run(Boundary, "boundary=.*\$", [{capture, first}]) of
+ {match, [{Start1, Length1}]}->
BoundLen = length("boundary="),
- string:substr(Boundary, Start1 + BoundLen, Length1 - BoundLen);
+ string:substr(Boundary, Start1 + 1 + BoundLen, Length1 - BoundLen);
_ ->
error
end.
@@ -479,12 +489,12 @@ end_of_header(HeaderPart) ->
end.
get_body_size(Head) ->
- case inets_regexp:match(Head,?CONTENT_LENGTH ".*\r\n") of
- {match, Start, Length} ->
+ case re:run(Head,?CONTENT_LENGTH ".*\r\n", [{capture, first}]) of
+ {match, [{Start, Length}]} ->
%% 15 is length of Content-Length,
%% 17 Is length of Content-Length and \r\
S = list_to_integer(
- string:strip(string:substr(Head, Start + 15, Length-17))),
+ string:strip(string:substr(Head, Start +1 + 15, Length-17))),
S;
_->
0
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 1457f735ad..87c504af74 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -68,7 +69,9 @@ all() ->
{group, http_security},
{group, https_security},
{group, http_reload},
- {group, https_reload}
+ {group, https_reload},
+ {group, http_mime_types},
+ mime_types_format
].
groups() ->
@@ -93,8 +96,9 @@ groups() ->
{https_security, [], [{group, security}]},
{http_reload, [], [{group, reload}]},
{https_reload, [], [{group, reload}]},
- {limit, [], [max_clients_1_1, max_clients_1_0, max_clients_0_9]},
- {custom, [], [customize]},
+ {http_mime_types, [], [alias_1_1, alias_1_0, alias_0_9]},
+ {limit, [], [max_clients_1_1, max_clients_1_0, max_clients_0_9]},
+ {custom, [], [customize, add_default]},
{reload, [], [non_disturbing_reconfiger_dies,
disturbing_reconfiger_dies,
non_disturbing_1_1,
@@ -114,7 +118,7 @@ groups() ->
{htaccess, [], [htaccess_1_1, htaccess_1_0, htaccess_0_9]},
{security, [], [security_1_1, security_1_0]}, %% Skip 0.9 as causes timing issus in test code
{http_1_1, [], [host, chunked, expect, cgi, cgi_chunked_encoding_test,
- trace, range, if_modified_since] ++ http_head() ++ http_get() ++ load()},
+ trace, range, if_modified_since, mod_esi_chunk_timeout] ++ http_head() ++ http_get() ++ load()},
{http_1_0, [], [host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
{http_0_9, [], http_head() ++ http_get() ++ load()}
].
@@ -132,7 +136,6 @@ http_get() ->
get,
%%actions, Add configuration so that this test mod_action
esi,
- ssi,
content_length,
bad_hex,
missing_CR,
@@ -199,7 +202,8 @@ init_per_group(Group, Config0) when Group == http_basic;
Group == http_auth_api_dets;
Group == http_auth_api_mnesia;
Group == http_security;
- Group == http_reload
+ Group == http_reload;
+ Group == http_mime_types
->
ok = start_apps(Group),
init_httpd(Group, [{type, ip_comm} | Config0]);
@@ -243,7 +247,8 @@ end_per_group(Group, _Config) when Group == http_basic;
Group == http_auth_api_mnesia;
Group == http_htaccess;
Group == http_security;
- Group == http_reload
+ Group == http_reload;
+ Group == http_mime_types
->
inets:stop();
end_per_group(Group, _Config) when Group == https_basic;
@@ -559,22 +564,6 @@ ipv6(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-ssi() ->
- [{doc, "HTTP GET server side include test"}].
-ssi(Config) when is_list(Config) ->
- Version = ?config(http_version, Config),
- Host = ?config(host, Config),
- Type = ?config(type, Config),
- ok = httpd_test_lib:verify_request(?config(type, Config), Host, ?config(port, Config),
- transport_opts(Type, Config),
- ?config(node, Config),
- http_request("GET /fsize.shtml ", Version, Host),
- [{statuscode, 200},
- {header, "Content-Type", "text/html"},
- {header, "Date"},
- {header, "Server"},
- {version, Version}]).
-%%-------------------------------------------------------------------------
htaccess_1_1(Config) when is_list(Config) ->
htaccess([{http_version, "HTTP/1.1"} | Config]).
@@ -767,7 +756,18 @@ esi(Config) when is_list(Config) ->
%% Check "ErlScriptNoCache" directive (default: false)
ok = http_status("GET /cgi-bin/erl/httpd_example:get ",
Config, [{statuscode, 200},
- {no_header, "cache-control"}]).
+ {no_header, "cache-control"}]),
+ ok = http_status("GET /cgi-bin/erl/httpd_example:peer ",
+ Config, [{statuscode, 200},
+ {header, "peer-cert-exist", peer(Config)}]).
+
+%%-------------------------------------------------------------------------
+mod_esi_chunk_timeout(Config) when is_list(Config) ->
+ ok = httpd_1_1:mod_esi_chunk_timeout(?config(type, Config),
+ ?config(port, Config),
+ ?config(host, Config),
+ ?config(node, Config)).
+
%%-------------------------------------------------------------------------
cgi() ->
[{doc, "Test mod_cgi"}].
@@ -864,6 +864,24 @@ cgi_chunked_encoding_test(Config) when is_list(Config) ->
?config(node, Config),
Requests).
%%-------------------------------------------------------------------------
+alias_1_1() ->
+ [{doc, "Test mod_alias"}].
+
+alias_1_1(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/1.1"} | Config]).
+
+alias_1_0() ->
+ [{doc, "Test mod_alias"}].
+
+alias_1_0(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/1.0"} | Config]).
+
+alias_0_9() ->
+ [{doc, "Test mod_alias"}].
+
+alias_0_9(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/0.9"} | Config]).
+
alias() ->
[{doc, "Test mod_alias"}].
@@ -922,7 +940,6 @@ trace(Config) when is_list(Config) ->
Cb = ?config(version_cb, Config),
Cb:trace(?config(type, Config), ?config(port, Config),
?config(host, Config), ?config(node, Config)).
-
%%-------------------------------------------------------------------------
light() ->
["Test light load"].
@@ -998,10 +1015,23 @@ customize(Config) when is_list(Config) ->
{no_header, "Server"},
{version, Version}]).
-response_header({"server", _}) ->
- false;
-response_header(Header) ->
- {true, Header}.
+add_default() ->
+ [{doc, "Test adding default header with custom callback"}].
+
+add_default(Config) when is_list(Config) ->
+ Version = "HTTP/1.1",
+ Host = ?config(host, Config),
+ Type = ?config(type, Config),
+ ok = httpd_test_lib:verify_request(?config(type, Config), Host,
+ ?config(port, Config),
+ transport_opts(Type, Config),
+ ?config(node, Config),
+ http_request("GET /index.html ", Version, Host),
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date", "Override-date"},
+ {header, "X-Frame-Options"},
+ {version, Version}]).
%%-------------------------------------------------------------------------
max_header() ->
@@ -1262,6 +1292,115 @@ non_disturbing(Config) when is_list(Config)->
inets_test_lib:close(Type, Socket),
[{server_name, "httpd_non_disturbing_" ++ Version}] = httpd:info(Server, [server_name]).
+%%-------------------------------------------------------------------------
+mime_types_format(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ MimeTypes = filename:join(DataDir, "mime_types.txt"),
+ {ok,[{"wrl","x-world/x-vrml"},
+ {"vrml","x-world/x-vrml"},
+ {"ice","x-conference/x-cooltalk"},
+ {"movie","video/x-sgi-movie"},
+ {"avi","video/x-msvideo"},
+ {"qt","video/quicktime"},
+ {"mov","video/quicktime"},
+ {"mpeg","video/mpeg"},
+ {"mpg","video/mpeg"},
+ {"mpe","video/mpeg"},
+ {"sgml","text/x-sgml"},
+ {"sgm","text/x-sgml"},
+ {"etx","text/x-setext"},
+ {"tsv","text/tab-separated-values"},
+ {"rtx","text/richtext"},
+ {"txt","text/plain"},
+ {"html","text/html"},
+ {"htm","text/html"},
+ {"css","text/css"},
+ {"xwd","image/x-xwindowdump"},
+ {"xpm","image/x-xpixmap"},
+ {"xbm","image/x-xbitmap"},
+ {"rgb","image/x-rgb"},
+ {"ppm","image/x-portable-pixmap"},
+ {"pgm","image/x-portable-graymap"},
+ {"pbm","image/x-portable-bitmap"},
+ {"pnm","image/x-portable-anymap"},
+ {"ras","image/x-cmu-raster"},
+ {"tiff","image/tiff"},
+ {"tif","image/tiff"},
+ {"png","image/png"},
+ {"jpeg","image/jpeg"},
+ {"jpg","image/jpeg"},
+ {"jpe","image/jpeg"},
+ {"ief","image/ief"},
+ {"gif","image/gif"},
+ {"pdb","chemical/x-pdb"},
+ {"xyz","chemical/x-pdb"},
+ {"wav","audio/x-wav"},
+ {"ra","audio/x-realaudio"},
+ {"rpm","audio/x-pn-realaudio-plugin"},
+ {"ram","audio/x-pn-realaudio"},
+ {"aif","audio/x-aiff"},
+ {"aiff","audio/x-aiff"},
+ {"aifc","audio/x-aiff"},
+ {"mpga","audio/mpeg"},
+ {"mp2","audio/mpeg"},
+ {"au","audio/basic"},
+ {"snd","audio/basic"},
+ {"zip","application/zip"},
+ {"src","application/x-wais-source"},
+ {"ustar","application/x-ustar"},
+ {"ms","application/x-troff-ms"},
+ {"me","application/x-troff-me"},
+ {"man","application/x-troff-man"},
+ {"t","application/x-troff"},
+ {"tr","application/x-troff"},
+ {"roff","application/x-troff"},
+ {"texinfo","application/x-texinfo"},
+ {"texi","application/x-texinfo"},
+ {"tex","application/x-tex"},
+ {"tcl","application/x-tcl"},
+ {"tar","application/x-tar"},
+ {"sv4crc","application/x-sv4crc"},
+ {"sv4cpio","application/x-sv4cpio"},
+ {"sit","application/x-stuffit"},
+ {"shar","application/x-shar"},
+ {"sh","application/x-sh"},
+ {"nc","application/x-netcdf"},
+ {"cdf","application/x-netcdf"},
+ {"mif","application/x-mif"},
+ {"latex","application/x-latex"},
+ {"skp","application/x-koan"},
+ {"skd","application/x-koan"},
+ {"skt","application/x-koan"},
+ {"skm","application/x-koan"},
+ {"cgi","application/x-httpd-cgi"},
+ {"hdf","application/x-hdf"},
+ {"gz","application/x-gzip"},
+ {"gtar","application/x-gtar"},
+ {"dvi","application/x-dvi"},
+ {"dcr","application/x-director"},
+ {"dir","application/x-director"},
+ {"dxr","application/x-director"},
+ {"csh","application/x-csh"},
+ {"cpio","application/x-cpio"},
+ {"Z","application/x-compress"},
+ {"vcd","application/x-cdlink"},
+ {"bcpio","application/x-bcpio"},
+ {"rtf","application/rtf"},
+ {"ppt","application/powerpoint"},
+ {"ai","application/postscript"},
+ {"eps","application/postscript"},
+ {"ps","application/postscript"},
+ {"pdf","application/pdf"},
+ {"oda","application/oda"},
+ {"bin","application/octet-stream"},
+ {"dms","application/octet-stream"},
+ {"lha","application/octet-stream"},
+ {"lzh","application/octet-stream"},
+ {"exe","application/octet-stream"},
+ {"class","application/octet-stream"},
+ {"doc","application/msword"},
+ {"cpt","application/mac-compactpro"},
+ {"hqx","application/mac-binhex40"}]} = httpd_conf:load_mime_types(MimeTypes).
%%--------------------------------------------------------------------
%% Internal functions -----------------------------------
@@ -1307,22 +1446,26 @@ setup_server_dirs(ServerRoot, DocRoot, DataDir) ->
CgiDir = filename:join(ServerRoot, "cgi-bin"),
AuthDir = filename:join(ServerRoot, "auth"),
PicsDir = filename:join(ServerRoot, "icons"),
+ ConfigDir = filename:join(ServerRoot, "config"),
ok = file:make_dir(ServerRoot),
ok = file:make_dir(DocRoot),
ok = file:make_dir(CgiDir),
ok = file:make_dir(AuthDir),
ok = file:make_dir(PicsDir),
+ ok = file:make_dir(ConfigDir),
DocSrc = filename:join(DataDir, "server_root/htdocs"),
AuthSrc = filename:join(DataDir, "server_root/auth"),
CgiSrc = filename:join(DataDir, "server_root/cgi-bin"),
PicsSrc = filename:join(DataDir, "server_root/icons"),
+ ConfigSrc = filename:join(DataDir, "server_root/config"),
inets_test_lib:copy_dirs(DocSrc, DocRoot),
inets_test_lib:copy_dirs(AuthSrc, AuthDir),
inets_test_lib:copy_dirs(CgiSrc, CgiDir),
inets_test_lib:copy_dirs(PicsSrc, PicsDir),
+ inets_test_lib:copy_dirs(ConfigSrc, ConfigDir),
Cgi = case test_server:os_type() of
{win32, _} ->
@@ -1362,7 +1505,8 @@ start_apps(Group) when Group == http_basic;
Group == http_auth_api_mnesia;
Group == http_htaccess;
Group == http_security;
- Group == http_reload->
+ Group == http_reload;
+ Group == http_mime_types->
inets_test_lib:start_apps([inets]).
server_start(_, HttpdConfig) ->
@@ -1411,13 +1555,15 @@ server_config(http_reload, Config) ->
server_config(https_reload, Config) ->
[{keep_alive_timeout, 2}] ++ server_config(https, Config);
server_config(http_limit, Config) ->
- [{max_clients, 1},
- %% Make sure option checking code is run
- {max_content_length, 100000002}] ++ server_config(http, Config);
+ Conf = [{max_clients, 1},
+ %% Make sure option checking code is run
+ {max_content_length, 100000002}] ++ server_config(http, Config),
+ ct:pal("Received message ~p~n", [Conf]),
+ Conf;
server_config(http_custom, Config) ->
- [{custom, ?MODULE}] ++ server_config(http, Config);
+ [{customize, ?MODULE}] ++ server_config(http, Config);
server_config(https_custom, Config) ->
- [{custom, ?MODULE}] ++ server_config(https, Config);
+ [{customize, ?MODULE}] ++ server_config(https, Config);
server_config(https_limit, Config) ->
[{max_clients, 1}] ++ server_config(https, Config);
server_config(http_basic_auth, Config) ->
@@ -1454,10 +1600,16 @@ server_config(http_security, Config) ->
server_config(https_security, Config) ->
ServerRoot = ?config(server_root, Config),
tl(auth_conf(ServerRoot)) ++ security_conf(ServerRoot) ++ server_config(https, Config);
+server_config(http_mime_types, Config0) ->
+ Config1 = basic_conf() ++ server_config(http, Config0),
+ ServerRoot = ?config(server_root, Config0),
+ MimeTypesFile = filename:join([ServerRoot,"config", "mime.types"]),
+ [{mime_types, MimeTypesFile} | proplists:delete(mime_types, Config1)];
server_config(http, Config) ->
ServerRoot = ?config(server_root, Config),
[{port, 0},
+ {socket_type, {ip_comm, [{nodelay, true}]}},
{server_name,"httpd_test"},
{server_root, ServerRoot},
{document_root, ?config(doc_root, Config)},
@@ -1479,13 +1631,14 @@ server_config(http, Config) ->
server_config(https, Config) ->
PrivDir = ?config(priv_dir, Config),
[{socket_type, {essl,
- [{cacertfile,
- filename:join(PrivDir, "public_key_cacert.pem")},
- {certfile,
- filename:join(PrivDir, "public_key_cert.pem")},
- {keyfile,
- filename:join(PrivDir, "public_key_cert_key.pem")}
- ]}}] ++ server_config(http, Config).
+ [{nodelay, true},
+ {cacertfile,
+ filename:join(PrivDir, "public_key_cacert.pem")},
+ {certfile,
+ filename:join(PrivDir, "public_key_cert.pem")},
+ {keyfile,
+ filename:join(PrivDir, "public_key_cert_key.pem")}
+ ]}}] ++ proplists:delete(socket_type, server_config(http, Config)).
init_httpd(Group, Config0) ->
Config1 = proplists:delete(port, Config0),
@@ -2015,3 +2168,22 @@ typestr(ip_comm) ->
"tcp";
typestr(_) ->
"ssl".
+
+response_header({"server", _}) ->
+ false;
+response_header(Header) ->
+ {true, Header}.
+
+response_default_headers() ->
+ [%% Add new header
+ {"X-Frame-Options", "SAMEORIGIN"},
+ %% Override built-in default
+ {"Date", "Override-date"}].
+
+peer(Config) ->
+ case proplists:get_value(type, Config) of
+ ssl ->
+ "true";
+ _ ->
+ "false"
+ end. \ No newline at end of file
diff --git a/lib/inets/test/httpd_SUITE_data/Makefile.src b/lib/inets/test/httpd_SUITE_data/Makefile.src
index b0fdb43d8d..cea40dd8cb 100644
--- a/lib/inets/test/httpd_SUITE_data/Makefile.src
+++ b/lib/inets/test/httpd_SUITE_data/Makefile.src
@@ -10,5 +10,10 @@ all: $(PROGS)
cgi_echo@exe@: cgi_echo@obj@
$(LD) $(CROSSLDFLAGS) -o cgi_echo cgi_echo@obj@ @LIBS@
+@IFEQ@ (@CC@, cl -nologo)
+cgi_echo@obj@: cgi_echo.c
+ $(CC) /c /Focgi_echo@obj@ $(CFLAGS) cgi_echo.c
+@ELSE@
cgi_echo@obj@: cgi_echo.c
$(CC) -c -o cgi_echo@obj@ $(CFLAGS) cgi_echo.c
+@ENDIF@
diff --git a/lib/inets/test/httpd_SUITE_data/mime_types.txt b/lib/inets/test/httpd_SUITE_data/mime_types.txt
new file mode 100644
index 0000000000..3149a119d5
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/mime_types.txt
@@ -0,0 +1,100 @@
+# This is a comment. I love comments.
+
+
+application/activemessage
+application/andrew-inset
+application/applefile
+application/atomicmail
+application/dca-rft
+application/dec-dx
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/octet-stream bin dms lha lzh exe class
+application/oda oda
+application/pdf pdf
+application/postscript ai eps ps
+application/powerpoint ppt
+application/remote-printing
+application/rtf rtf
+application/slate
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-compress Z
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-gtar gtar
+application/x-gzip gz
+application/x-hdf hdf
+application/x-httpd-cgi cgi
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-mif mif
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/zip zip
+audio/basic au snd
+audio/mpeg mpga mp2
+audio/x-aiff aif aiff aifc
+audio/x-pn-realaudio ram
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb xyz
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/png png
+image/tiff tiff tif
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/external-body
+message/news
+message/partial
+message/rfc822
+multipart/alternative
+multipart/appledouble
+multipart/digest
+multipart/mixed
+multipart/parallel
+text/css css
+text/html html htm
+text/plain txt
+text/richtext rtx
+text/tab-separated-values tsv
+text/x-setext etx
+text/x-sgml sgml sgm
+video/mpeg mpeg mpg mpe
+video/quicktime qt mov
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+x-world/x-vrml wrl vrml
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types b/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types
new file mode 100644
index 0000000000..b68cff21a6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types
@@ -0,0 +1,4 @@
+text/html html
+text/html htm
+text/html shtml
+image/gif gif
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
index baef699629..db7f3c525d 100644
--- a/lib/inets/test/httpd_basic_SUITE.erl
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/httpd_block.erl b/lib/inets/test/httpd_block.erl
index 9790623b6f..ca2ab517fb 100644
--- a/lib/inets/test/httpd_block.erl
+++ b/lib/inets/test/httpd_block.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -292,7 +293,7 @@ httpd_restart(Addr, Port) ->
end.
make_name(Addr, Port) ->
- httpd_util:make_name("httpd", Addr, Port).
+ httpd_util:make_name("httpd", Addr, Port, default).
get_admin_state(_, _Host, Port) ->
Name = make_name(undefined, Port),
diff --git a/lib/inets/test/httpd_load.erl b/lib/inets/test/httpd_load.erl
index 83520033dc..39c2280f23 100644
--- a/lib/inets/test/httpd_load.erl
+++ b/lib/inets/test/httpd_load.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl
index 7d3326fb65..847586a903 100644
--- a/lib/inets/test/httpd_mod.erl
+++ b/lib/inets/test/httpd_mod.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/test/httpd_mod_SUITE.erl b/lib/inets/test/httpd_mod_SUITE.erl
index d23cd22670..89b9e0a303 100644
--- a/lib/inets/test/httpd_mod_SUITE.erl
+++ b/lib/inets/test/httpd_mod_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/httpd_poll.erl b/lib/inets/test/httpd_poll.erl
index 32335cabcf..4a570fb512 100644
--- a/lib/inets/test/httpd_poll.erl
+++ b/lib/inets/test/httpd_poll.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -258,11 +259,11 @@ validate(ExpStatusCode,Socket,Response) ->
vtrace("validate -> Entry with ~p bytes response",[Sz]),
Size = trash_the_rest(Socket,Sz),
close(Socket),
- case inets_regexp:split(Response," ") of
- {ok,["HTTP/1.0",ExpStatusCode|_]} ->
+ case re:split(Response," ", [{return, list}]) of
+ ["HTTP/1.0",ExpStatusCode|_] ->
vlog("response (~p bytes) was ok",[Size]),
ok;
- {ok,["HTTP/1.0",StatusCode|_]} ->
+ ["HTTP/1.0",StatusCode|_] ->
verror("unexpected response status received: ~s => ~s",
[StatusCode,status_to_message(StatusCode)]),
log("unexpected result to GET of '~s': ~s => ~s",
diff --git a/lib/inets/test/httpd_test_data/server_root/Makefile b/lib/inets/test/httpd_test_data/server_root/Makefile
index d7a3231068..4f23295401 100644
--- a/lib/inets/test/httpd_test_data/server_root/Makefile
+++ b/lib/inets/test/httpd_test_data/server_root/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
index ceb94237d2..87c2973e5a 100644
--- a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
+++ b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index 647fa6f6c1..71e201f826 100644
--- a/lib/inets/test/httpd_test_lib.erl
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -95,10 +96,10 @@ verify_request(SocketType, Host, Port, TranspOpts, Node, RequestStr, Options, Ti
try inets_test_lib:connect_bin(SocketType, Host, Port, TranspOpts) of
{ok, Socket} ->
ok = inets_test_lib:send(SocketType, Socket, RequestStr),
- State = case inets_regexp:match(RequestStr, "printenv") of
+ State = case re:run(RequestStr, "printenv", [{capture, none}]) of
nomatch ->
#state{};
- _ ->
+ match ->
#state{print = true}
end,
@@ -234,11 +235,17 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
_ ->
ok
end,
- do_validate(http_response:header_list(Headers), Options, N, P),
- check_body(RequestStr, StatusCode,
- Headers#http_response_h.'content-type',
- list_to_integer(Headers#http_response_h.'content-length'),
- Body).
+ HList = http_response:header_list(Headers),
+ do_validate(HList, Options, N, P),
+ case lists:keysearch("warning", 1, HList) of
+ {value, _} ->
+ ok;
+ _ ->
+ check_body(RequestStr, StatusCode,
+ Headers#http_response_h.'content-type',
+ list_to_integer(Headers#http_response_h.'content-length'),
+ Body)
+ end.
%--------------------------------------------------------------------
%% Internal functions
@@ -293,9 +300,9 @@ do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
{value, {LowerHeaderField, Value}} ->
ok;
false ->
- ct:fail({wrong_header_field_value, LowerHeaderField, Header});
+ ct:fail({wrong_header_field_value, LowerHeaderField, Header, Value});
_ ->
- ct:fail({wrong_header_field_value, LowerHeaderField, Header})
+ ct:fail({wrong_header_field_value, LowerHeaderField, Header, Value})
end,
do_validate(Header, Rest, N, P);
do_validate(Header,[{no_header, HeaderField}|Rest],N,P) ->
@@ -310,10 +317,10 @@ do_validate(Header, [_Unknown | Rest], N, P) ->
do_validate(Header, Rest, N, P).
is_expect(RequestStr) ->
- case inets_regexp:match(RequestStr, "xpect:100-continue") of
- {match, _, _}->
+ case re:run(RequestStr, "xpect:100-continue", [{capture, none}]) of
+ match->
true;
- _ ->
+ nomatch ->
false
end.
diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl
index 0bb457f9b9..1b4d74b28e 100644
--- a/lib/inets/test/httpd_time_test.erl
+++ b/lib/inets/test/httpd_time_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -116,13 +117,14 @@ main(N, SocketType, Host, Port, Time)
loop(Pollers, Timeout) ->
d("loop -> entry when"
"~n Timeout: ~p", [Timeout]),
- Start = t(),
+ Start = inets_time_compat:monotonic_time(),
+
receive
{'EXIT', Pid, {poller_stat_failure, SocketType, Host, Port, Time, Reason}} ->
case is_poller(Pid, Pollers) of
true ->
error_msg("received unexpected exit from poller ~p~n"
- "befor completion of test "
+ "before completion of test "
"after ~p micro sec"
"~n SocketType: ~p"
"~n Host: ~p"
@@ -133,7 +135,7 @@ loop(Pollers, Timeout) ->
false ->
error_msg("received unexpected ~p from ~p"
"befor completion of test", [Reason, Pid]),
- loop(Pollers, to(Timeout, Start))
+ loop(Pollers, Timeout - inets_lib:millisec_passed(Start))
end;
{poller_stat_failure, Pid, {SocketType, Host, Port, Time, Reason}} ->
@@ -384,63 +386,34 @@ validate(ExpStatusCode, _SocketType, _Socket, Response) ->
%% Sz = sz(Response),
%% trash_the_rest(Socket, Sz),
%% inets_test_lib:close(SocketType, Socket),
- case inets_regexp:split(Response," ") of
- {ok, ["HTTP/1.0", ExpStatusCode|_]} ->
+ case re:split(Response," ", [{return, list}]) of
+ ["HTTP/1.0", ExpStatusCode|_] ->
ok;
- {ok, ["HTTP/1.0", StatusCode|_]} ->
+ ["HTTP/1.0", StatusCode|_] ->
error_msg("Unexpected status code: ~p (~s). "
"Expected status code: ~p (~s)",
[StatusCode, status_to_message(StatusCode),
ExpStatusCode, status_to_message(ExpStatusCode)]),
exit({unexpected_response_code, StatusCode, ExpStatusCode});
- {ok, ["HTTP/1.1", ExpStatusCode|_]} ->
+ ["HTTP/1.1", ExpStatusCode|_] ->
ok;
- {ok, ["HTTP/1.1", StatusCode|_]} ->
+ ["HTTP/1.1", StatusCode|_] ->
error_msg("Unexpected status code: ~p (~s). "
"Expected status code: ~p (~s)",
[StatusCode, status_to_message(StatusCode),
ExpStatusCode, status_to_message(ExpStatusCode)]),
exit({unexpected_response_code, StatusCode, ExpStatusCode});
- {ok, Unexpected} ->
- error_msg("Unexpected response split: ~p (~s)",
- [Unexpected, Response]),
- exit({unexpected_response, Unexpected, Response});
- {error, Reason} ->
+ {error, Reason} ->
error_msg("Failed processing response: ~p (~s)",
[Reason, Response]),
- exit({failed_response_processing, Reason, Response})
- end.
-
-
-trash_the_rest(Socket, N) ->
- receive
- {ssl, Socket, Trash} ->
- trash_the_rest(Socket, add(N,sz(Trash)));
- {ssl_closed, Socket} ->
- N;
- {ssl_error, Socket, Error} ->
- exit({connection_error, Error});
-
- {tcp, Socket, Trash} ->
- trash_the_rest(Socket, add(N,sz(Trash)));
- {tcp_closed, Socket} ->
- N;
- {tcp_error, Socket, Error} ->
- exit({connection_error, Error})
-
- after 10000 ->
- exit({connection_timed_out, N})
+ exit({failed_response_processing, Reason, Response});
+ Unexpected ->
+ error_msg("Unexpected response split: ~p (~s)",
+ [Unexpected, Response]),
+ exit({unexpected_response, Unexpected, Response})
end.
-add(N1,N2) when is_integer(N1) andalso is_integer(N2) ->
- N1 + N2;
-add(N1,_) when is_integer(N1) ->
- N1;
-add(_,N2) when is_integer(N2) ->
- N2.
-
-
sz(L) when is_list(L) ->
length(lists:flatten(L));
sz(B) when is_binary(B) ->
@@ -505,17 +478,6 @@ status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
%% ----------------------------------------------------------------
-to(To, Start) ->
- To - (t() - Start).
-
-%% Time in milli seconds
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-
-%% ----------------------------------------------------------------
-
% close(Socket) ->
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index 6510c70d08..928d9dc391 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -20,7 +21,6 @@
-module(inets_SUITE).
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include("inets_test_lib.hrl").
%% Note: This directive should only be used in test suites.
@@ -36,8 +36,12 @@ all() ->
groups() ->
[{services_test, [],
- [start_inets, start_httpc, start_httpd, start_ftpc,
- start_tftpd]},
+ [start_inets,
+ start_httpc,
+ start_httpd,
+ start_ftpc,
+ start_tftpd
+ ]},
{app_test, [], [{inets_app_test, all}]},
{appup_test, [], [{inets_appup_test, all}]}].
@@ -47,9 +51,6 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-
-
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -102,14 +103,8 @@ end_per_testcase(_, Config) ->
%% Test cases starts here.
%%-------------------------------------------------------------------------
-
-
-%%-------------------------------------------------------------------------
-
-start_inets(doc) ->
- ["Test inets API functions"];
-start_inets(suite) ->
- [];
+start_inets() ->
+ [{doc, "Test inets API functions"}].
start_inets(Config) when is_list(Config) ->
[_|_] = inets:service_names(),
@@ -133,134 +128,85 @@ start_inets(Config) when is_list(Config) ->
ok = inets:start(permanent),
ok = inets:stop().
-
%%-------------------------------------------------------------------------
-start_httpc(doc) ->
- ["Start/stop of httpc service"];
-start_httpc(suite) ->
- [];
+start_httpc() ->
+ [{doc, "Start/stop of httpc service"}].
start_httpc(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- tsp("start_httpc -> entry with"
- "~n Config: ~p", [Config]),
-
PrivDir = ?config(priv_dir, Config),
- tsp("start_httpc -> start (empty) inets"),
ok = inets:start(),
-
- tsp("start_httpc -> start httpc (as inets service) with profile foo"),
{ok, Pid0} = inets:start(httpc, [{profile, foo}]),
- tsp("start_httpc -> check running services"),
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
- tsp("start_httpc -> stop httpc"),
inets:stop(httpc, Pid0),
- tsp("start_httpc -> sleep some"),
test_server:sleep(100),
- tsp("start_httpc -> check running services"),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid0, Pids1),
- tsp("start_httpc -> start httpc (stand-alone) with profile bar"),
{ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone),
- tsp("start_httpc -> check running services"),
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid1, Pids2),
- tsp("start_httpc -> stop httpc"),
ok = inets:stop(stand_alone, Pid1),
receive
{'EXIT', Pid1, shutdown} ->
ok
after 100 ->
- tsf(stand_alone_not_shutdown)
+ ct:fail(stand_alone_not_shutdown)
end,
- tsp("start_httpc -> stop inets"),
ok = inets:stop(),
- tsp("start_httpc -> unload inets"),
application:load(inets),
-
- tsp("start_httpc -> set inets environment (httpc profile foo)"),
application:set_env(inets, services, [{httpc,[{profile, foo},
{data_dir, PrivDir}]}]),
-
- tsp("start_httpc -> start inets"),
ok = inets:start(),
- tsp("start_httpc -> check running services"),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- tsp("start_httpc -> unset inets env"),
application:unset_env(inets, services),
-
- tsp("start_httpc -> stop inets"),
ok = inets:stop(),
-
- tsp("start_httpc -> start (empty) inets"),
ok = inets:start(),
- tsp("start_httpc -> start inets httpc service with profile foo"),
{ok, Pid3} = inets:start(httpc, [{profile, foo}]),
-
- tsp("start_httpc -> stop inets service httpc with profile foo"),
ok = inets:stop(httpc, foo),
-
- tsp("start_httpc -> check running services"),
Pids3 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid3, Pids3),
-
- tsp("start_httpc -> stop inets"),
- ok = inets:stop(),
-
- tsp("start_httpc -> done"),
- ok.
-
+ ok = inets:stop().
%%-------------------------------------------------------------------------
-start_httpd(doc) ->
- ["Start/stop of httpd service"];
-start_httpd(suite) ->
- [];
+start_httpd() ->
+ [{doc, "Start/stop of httpd service"}].
start_httpd(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- i("start_httpd -> entry with"
- "~n Config: ~p", [Config]),
PrivDir = ?config(priv_dir, Config),
HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir},
- {document_root, PrivDir}, {bind_address, "localhost"}],
+ {document_root, PrivDir}, {bind_address, any}],
- i("start_httpd -> start inets"),
ok = inets:start(),
-
- i("start_httpd -> start httpd service"),
{ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
- i("start_httpd -> stop httpd service"),
inets:stop(httpd, Pid0),
test_server:sleep(500),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid0, Pids1),
- i("start_httpd -> start (stand-alone) httpd service"),
{ok, Pid1} =
inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf],
stand_alone),
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid1, Pids2),
- i("start_httpd -> stop (stand-alone) httpd service"),
ok = inets:stop(stand_alone, Pid1),
receive
{'EXIT', Pid1, shutdown} ->
@@ -268,7 +214,6 @@ start_httpd(Config) when is_list(Config) ->
after 100 ->
test_server:fail(stand_alone_not_shutdown)
end,
- i("start_httpd -> stop inets"),
ok = inets:stop(),
File0 = filename:join(PrivDir, "httpd.conf"),
{ok, Fd0} = file:open(File0, [write]),
@@ -276,17 +221,12 @@ start_httpd(Config) when is_list(Config) ->
ok = file:write(Fd0, Str),
file:close(Fd0),
- i("start_httpd -> [application] load inets"),
application:load(inets),
- i("start_httpd -> [application] set httpd services env with proplist-file"),
application:set_env(inets,
services, [{httpd, [{proplist_file, File0}]}]),
- i("start_httpd -> start inets"),
ok = inets:start(),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- i("start_httpd -> [application] unset services env"),
application:unset_env(inets, services),
- i("start_httpd -> stop inets"),
ok = inets:stop(),
File1 = filename:join(PrivDir, "httpd_apache.conf"),
@@ -299,68 +239,46 @@ start_httpd(Config) when is_list(Config) ->
file:write(Fd1, "Port 0\r\n"),
file:close(Fd1),
- i("start_httpd -> [application] load inets"),
application:load(inets),
- i("start_httpd -> [application] set httpd services env with file"),
application:set_env(inets,
services, [{httpd, [{file, File1}]}]),
- i("start_httpd -> start inets"),
ok = inets:start(),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- i("start_httpd -> [application] unset services env"),
application:unset_env(inets, services),
- i("start_httpd -> stop inets"),
ok = inets:stop(),
%% OLD format
- i("start_httpd -> [application] load inets"),
application:load(inets),
- i("start_httpd -> [application] set httpd services OLD env"),
application:set_env(inets,
services, [{httpd, File1}]),
- i("start_httpd -> start inets"),
ok = inets:start(),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- i("start_httpd -> [application] unset services enc"),
application:unset_env(inets, services),
- i("start_httpd -> stop inets"),
ok = inets:stop(),
-
- i("start_httpd -> start inets"),
ok = inets:start(),
- i("start_httpd -> try (and fail) start httpd service - server_name"),
{error, {missing_property, server_name}} =
inets:start(httpd, [{port, 0},
{server_root, PrivDir},
{document_root, PrivDir},
{bind_address, "localhost"}]),
- i("start_httpd -> try (and fail) start httpd service - missing document_root"),
{error, {missing_property, document_root}} =
inets:start(httpd, [{port, 0},
{server_name, "httpd_test"},
{server_root, PrivDir},
{bind_address, "localhost"}]),
- i("start_httpd -> try (and fail) start httpd service - missing server_root"),
{error, {missing_property, server_root}} =
inets:start(httpd, [{port, 0},
{server_name, "httpd_test"},
{document_root, PrivDir},
{bind_address, "localhost"}]),
- i("start_httpd -> try (and fail) start httpd service - missing port"),
{error, {missing_property, port}} =
inets:start(httpd, HttpdConf),
- i("start_httpd -> stop inets"),
- ok = inets:stop(),
- i("start_httpd -> done"),
- ok.
-
+ ok = inets:stop().
%%-------------------------------------------------------------------------
start_ftpc(doc) ->
- ["Start/stop of ftpc service"];
-start_ftpc(suite) ->
- [];
+ [{doc, "Start/stop of ftpc service"}];
start_ftpc(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ok = inets:start(),
@@ -388,7 +306,7 @@ start_ftpc(Config) when is_list(Config) ->
{'EXIT', Pid1, shutdown} ->
ok
after 100 ->
- tsf(stand_alone_not_shutdown)
+ ct:fail(stand_alone_not_shutdown)
end,
ok = inets:stop(),
ok;
@@ -400,15 +318,11 @@ start_ftpc(Config) when is_list(Config) ->
throw:{error, not_found} ->
{skip, "No available FTP servers"}
end.
-
-
%%-------------------------------------------------------------------------
-start_tftpd(doc) ->
- ["Start/stop of tfpd service"];
-start_tftpd(suite) ->
- [];
+start_tftpd() ->
+ [{doc, "Start/stop of tfpd service"}].
start_tftpd(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ok = inets:start(),
@@ -440,16 +354,12 @@ start_tftpd(Config) when is_list(Config) ->
application:unset_env(inets, services),
ok = inets:stop().
-
%%-------------------------------------------------------------------------
-httpd_reload(doc) ->
- ["Reload httpd configuration without restarting service"];
-httpd_reload(suite) ->
- [];
+httpd_reload() ->
+ [{doc, "Reload httpd configuration without restarting service"}].
httpd_reload(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- i("httpd_reload -> starting"),
PrivDir = ?config(priv_dir, Config),
DataDir = ?config(data_dir, Config),
HttpdConf = [{server_name, "httpd_test"},
@@ -457,23 +367,18 @@ httpd_reload(Config) when is_list(Config) ->
{document_root, PrivDir},
{bind_address, "localhost"}],
- i("httpd_reload -> start inets"),
-
ok = inets:start(),
test_server:sleep(5000),
- i("httpd_reload -> inets started - start httpd service"),
- {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
+ {ok, Pid0} = inets:start(httpd, [{port, 0},
+ {ipfamily, inet} | HttpdConf]),
test_server:sleep(5000),
- i("httpd_reload -> httpd service started (~p) - get port", [Pid0]),
[{port, Port0}] = httpd:info(Pid0, [port]),
test_server:sleep(5000),
- i("httpd_reload -> Port: ~p - get document root", [Port0]),
[{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
test_server:sleep(5000),
- i("httpd_reload -> document root: ~p - reload config", [PrivDir]),
ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
{server_name, "httpd_test"},
@@ -481,11 +386,8 @@ httpd_reload(Config) when is_list(Config) ->
{document_root, DataDir},
{bind_address, "localhost"}], non_disturbing),
test_server:sleep(5000),
- io:format("~w:~w:httpd_reload - reloaded - get document root~n", [?MODULE, ?LINE]),
-
[{document_root, DataDir}] = httpd:info(Pid0, [document_root]),
test_server:sleep(5000),
- i("httpd_reload -> document root: ~p - reload config", [DataDir]),
ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
{server_name, "httpd_test"},
@@ -538,36 +440,5 @@ httpd_reload(Config) when is_list(Config) ->
ok = inets:stop(httpd, Pid1),
application:unset_env(inets, services),
- ok = inets:stop(),
- i("httpd_reload -> starting"),
- ok.
-
-
-tsf(Reason) ->
- test_server:fail(Reason).
-
-tsp(F) ->
- tsp(F, []).
-tsp(F, A) ->
- Timestamp = formated_timestamp(),
- test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
-
-i(F) ->
- i(F, []).
-
-i(F, A) ->
- Timestamp = formated_timestamp(),
- io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
-
-formated_timestamp() ->
- format_timestamp( os:timestamp() ).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
+ ok = inets:stop().
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
index eabfa69f7c..c6d0715e1f 100644
--- a/lib/inets/test/inets_app_test.erl
+++ b/lib/inets/test/inets_app_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -32,19 +33,6 @@
%% Test server callbacks
-init_per_testcase(undef_funcs, Config) ->
- NewConfig = lists:keydelete(watchdog, 1, Config),
- Dog = test_server:timetrap(inets_test_lib:minutes(10)),
-
- %% We need to check if there is a point to run this test.
- %% On some platforms, crypto will not build, which in turn
- %% causes ssl to not build (at this time, this will
- %% change in the future).
- %% So, we first check if we can start crypto, and if not,
- %% we skip this test case!
- ?ENSURE_STARTED(crypto),
-
- [{watchdog, Dog}| NewConfig];
init_per_testcase(_, Config) ->
Config.
@@ -54,7 +42,7 @@ end_per_testcase(_Case, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all() ->
- [fields, modules, exportall, app_depend, undef_funcs].
+ [fields, modules, exportall, app_depend].
groups() ->
[].
@@ -244,56 +232,6 @@ check_apps([App|Apps]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-undef_funcs(suite) ->
- [];
-undef_funcs(doc) ->
- [];
-undef_funcs(Config) when is_list(Config) ->
- App = inets,
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
- Root = code:root_dir(),
- LibDir = code:lib_dir(App),
- EbinDir = filename:join([LibDir,"ebin"]),
- XRefTestName = undef_funcs_make_name(App, xref_test_name),
- {ok, XRef} = xref:start(XRefTestName),
- ok = xref:set_default(XRef,
- [{verbose,false},{warnings,false}]),
- XRefName = undef_funcs_make_name(App, xref_name),
- {ok, XRefName} = xref:add_release(XRef, Root, {name, XRefName}),
- {ok, App} = xref:replace_application(XRef, App, EbinDir),
- {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
- xref:stop(XRef),
- analyze_undefined_function_calls(Undefs, Mods, []).
-
-analyze_undefined_function_calls([], _, []) ->
- ok;
-analyze_undefined_function_calls([], _, AppUndefs) ->
- exit({suite_failed, {undefined_function_calls, AppUndefs}});
-analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
- AppModules, AppUndefs) ->
- %% Check that this module is our's
- case lists:member(Mod,AppModules) of
- true ->
- {Calling,Called} = AppUndef,
- {Mod1,Func1,Ar1} = Calling,
- {Mod2,Func2,Ar2} = Called,
- io:format("undefined function call: "
- "~n ~w:~w/~w calls ~w:~w/~w~n",
- [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
- analyze_undefined_function_calls(Undefs, AppModules,
- [AppUndef|AppUndefs]);
- false ->
- io:format("dropping ~p~n", [Mod]),
- analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
- end.
-
-%% This function is used simply to avoid cut-and-paste errors later...
-undef_funcs_make_name(App, PostFix) ->
- list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
fail(Reason) ->
exit({suite_failed, Reason}).
diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl
index a8051c6c85..999989b8b4 100644
--- a/lib/inets/test/inets_appup_test.erl
+++ b/lib/inets/test/inets_appup_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/inets_socketwrap_SUITE.erl b/lib/inets/test/inets_socketwrap_SUITE.erl
new file mode 100644
index 0000000000..cfbda3ccf5
--- /dev/null
+++ b/lib/inets/test/inets_socketwrap_SUITE.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(inets_socketwrap_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include("inets_test_lib.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_httpd_fd, start_tftpd_fd].
+
+init_per_suite(Config) ->
+ case os:type() of
+ {unix, linux} ->
+ Config;
+ _ ->
+ {skip, linux_feature}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(Case, Config) ->
+ end_per_testcase(Case, Config),
+ Config.
+
+end_per_testcase(_, Config) ->
+ inets:stop(),
+ Config.
+
+%%-------------------------------------------------------------------------
+start_httpd_fd() ->
+ [{doc, "Start/stop of httpd service with socket wrapper"}].
+start_httpd_fd(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ HttpdConf = [{port, 80}, {ipfamily, inet},
+ {server_name, "httpd_fd_test"}, {server_root, PrivDir},
+ {document_root, PrivDir}, {bind_address, any}],
+ case setup_node_info(node()) of
+ {skip, _} = Skip ->
+ Skip;
+ {Node, NodeArg} ->
+ InetPort = inets_test_lib:inet_port(node()),
+ ct:pal("Node: ~p Port ~p~n", [Node, InetPort]),
+ Wrapper = filename:join(DataDir, "setuid_socket_wrap"),
+ Cmd = Wrapper ++
+ " -s -httpd_80,0:" ++ integer_to_list(InetPort)
+ ++ " -p " ++ os:find_executable("erl") ++
+ " -- " ++ NodeArg,
+ ct:pal("cmd: ~p~n", [Cmd]),
+ case open_port({spawn, Cmd}, [stderr_to_stdout]) of
+ Port when is_port(Port) ->
+ wait_node_up(Node, 10),
+ ct:pal("~p", [rpc:call(Node, init, get_argument, [httpd_80])]),
+ ok = rpc:call(Node, inets, start, []),
+ {ok, Pid} = rpc:call(Node, inets, start, [httpd, HttpdConf]),
+ [{port, InetPort}] = rpc:call(Node, httpd, info, [Pid, [port]]),
+ rpc:call(Node, erlang, halt, []);
+ _ ->
+ ct:fail(open_port_failed)
+ end
+ end.
+%%-------------------------------------------------------------------------
+start_tftpd_fd() ->
+ [{doc, "Start/stop of tfpd service with socket wrapper"}].
+start_tftpd_fd(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ case setup_node_info(node()) of
+ {skip, _} = Skip ->
+ Skip;
+ {Node, NodeArg} ->
+ InetPort = inets_test_lib:inet_port(node()),
+ ct:pal("Node: ~p~n", [Node]),
+ Wrapper = filename:join(DataDir, "setuid_socket_wrap"),
+ Cmd = Wrapper ++
+ " -s -tftpd_69,0:" ++ integer_to_list(InetPort)
+ ++ " -p " ++ os:find_executable("erl") ++
+ " -- " ++ NodeArg,
+ ct:pal("cmd: ~p~n", [Cmd]),
+ case open_port({spawn, Cmd}, [stderr_to_stdout]) of
+ Port when is_port(Port) ->
+ wait_node_up(Node, 10),
+ ct:pal("~p", [rpc:call(Node, init, get_argument, [tftpd_69])]),
+ ok = rpc:call(Node, inets, start, []),
+ {ok, Pid} = rpc:call(Node, inets, start,
+ [tftpd,[{host, "localhost"}]]),
+ {ok, Info} = rpc:call(Node, tftp, info, [Pid]),
+ {value,{port, InetPort}} = lists:keysearch(port, 1, Info),
+ rpc:call(Node, erlang, halt, []);
+ _ ->
+ ct:fail(open_port_failed)
+ end
+ end.
+%%-------------------------------------------------------------------------
+%% Internal functions
+%%-------------------------------------------------------------------------
+setup_node_info(nonode@nohost) ->
+ {skip, needs_distributed_node};
+setup_node_info(Node) ->
+ Static = "-detached -noinput",
+ Name = "inets_fd_test",
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ _ -> "-name "
+ end,
+ StrNode =
+ Static ++ " "
+ ++ NameSw ++ " " ++ Name ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()),
+ [_, Location] = string:tokens(atom_to_list(Node), "$@"),
+ TestNode = Name ++ "@" ++ Location,
+ {list_to_atom(TestNode), StrNode}.
+
+wait_node_up(Node, 0) ->
+ ct:fail({failed_to_start_node, Node});
+wait_node_up(Node, N) ->
+ ct:pal("(Node ~p: net_adm:ping(~p)~n", [node(), Node]),
+ case net_adm:ping(Node) of
+ pong ->
+ ok;
+ pang ->
+ ct:sleep(5000),
+ wait_node_up(Node, N-1)
+ end.
diff --git a/lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src b/lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..0933815b58
--- /dev/null
+++ b/lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src
@@ -0,0 +1,39 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2015-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.
+#
+# %CopyrightEnd%
+#
+
+CC = @CC@
+LD = @LD@
+CFLAGS = @CFLAGS@
+CROSSLDFLAGS = @CROSSLDFLAGS@
+
+PROGS = setuid_socket_wrap@exe@
+
+.PHONY: all
+@IFEQ@ (@os@, linux-gnu)
+all: $(PROGS)
+@ELSE@
+all:
+@ENDIF@
+
+setuid_socket_wrap@exe@: setuid_socket_wrap@obj@
+ $(LD) $(CROSSLDFLAGS) -o setuid_socket_wrap setuid_socket_wrap@obj@ @LIBS@
+
+setuid_socket_wrap@obj@: setuid_socket_wrap.c
+ $(CC) -c $(CFLAGS) -o setuid_socket_wrap@obj@ setuid_socket_wrap.c
diff --git a/lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c b/lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c
new file mode 100644
index 0000000000..b28f6b1c08
--- /dev/null
+++ b/lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c
@@ -0,0 +1,259 @@
+/*
+ * %CopyrightBegin%
+ *
+ * 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.
+ *
+ * %CopyrightEnd%
+ */
+/*
+ * setuid_socket_wrap.c
+ *
+ * ./a.out [-s [tag,][addr]:[port]]* [-d [tag,][addr]:[port]]*
+ * [-r [tag,]proto]* [-p erl_path]* -- program args
+ *
+ * Where: -s = stream socket, -d datagram socket and -r means raw socket.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+struct sock_list {
+ struct sock_list *next;
+ int fd;
+ int type;
+ int protocol;
+ struct sockaddr_in addr;
+ char *arg;
+};
+
+int parse_addr(addr, str)
+ struct sockaddr_in *addr;
+ char *str;
+{
+ int port = 0;
+ char *cp;
+ struct hostent *hp;
+ struct servent *se;
+
+ if ((cp = strrchr(str, (int)':')) != NULL)
+ *cp++ = '\0';
+ if (cp) {
+ if (!isdigit((int)cp[0])) {
+ if ((se = getservbyname(cp, "tcp")) != NULL) {
+ port = ntohs(se->s_port);
+ } else {
+ fprintf(stderr, "unknown port %s\n", cp);
+ return -1;
+ }
+ } else {
+ port = atoi(cp);
+ }
+ }
+ if (port < 0 || port > 0xffff) {
+ fprintf(stderr, "bad port number %d\n", port);
+ return -1;
+ }
+
+ bzero(addr, sizeof(*addr));
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(port);
+ if (*str == '\000') {
+ addr->sin_addr.s_addr = INADDR_ANY;
+ } else {
+ if ((addr->sin_addr.s_addr = inet_addr(str)) == INADDR_NONE) {
+ if ((hp = gethostbyname(str)) == NULL) {
+ fprintf(stderr, "\"%s\" unknown host or address!\n", str);
+ return -1;
+ } else {
+ bcopy(hp->h_addr_list[0], &addr->sin_addr.s_addr,hp->h_length);
+ }
+ }
+ }
+ return 0;
+}
+
+struct sock_list *new_entry(type, argstr)
+ int type;
+ char *argstr;
+{
+ struct sock_list *sle;
+ char *cp;
+
+ sle = (struct sock_list *)malloc(sizeof(struct sock_list));
+ if (!sle)
+ return NULL;
+ sle->next = NULL;
+ sle->fd = -1;
+
+ if ((cp = strchr(argstr, (int)',')) != NULL) {
+ *cp++ = '\0';
+ sle->arg = argstr;
+ argstr = cp;
+ } else {
+ sle->arg = "-fd";
+ }
+ sle->type = type;
+ switch (type) {
+ case SOCK_RAW: {
+ struct protoent *pe;
+ pe = getprotobyname(argstr);
+ if (!pe) {
+ fprintf(stderr, "Unknown protocol: %s\n", argstr);
+ free(sle);
+ return NULL;
+ }
+ sle->protocol = pe->p_proto;
+ break;
+ }
+ case SOCK_STREAM:
+ case SOCK_DGRAM:
+ sle->protocol = 0;
+ if (parse_addr(&sle->addr, argstr) < 0) {
+ free(sle);
+ return NULL;
+ }
+ break;
+ }
+ return sle;
+}
+
+int open_socket(sle)
+ struct sock_list *sle;
+{
+ sle->fd = socket(AF_INET, sle->type, sle->protocol);
+ if (sle->fd < 0) {
+ perror("socket");
+ return -1;
+ }
+ if (sle->type != SOCK_RAW) {
+#if 0
+ printf("binding fd %d to %s:%d\n", sle->fd,
+ inet_ntoa(sle->addr.sin_addr), ntohs(sle->addr.sin_port));
+#endif
+ if (bind(sle->fd, (struct sockaddr *)&sle->addr, sizeof(sle->addr))<0){
+ perror("bind");
+ close(sle->fd);
+ return -1;
+ }
+ }
+ return sle->fd;
+}
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct sock_list *sl = NULL, *sltmp = NULL;
+ int count = 0;
+ int c;
+ char *run_prog = NULL;
+
+ while ((c = getopt(argc, argv, "s:d:r:p:")) != EOF)
+ switch (c) {
+ case 's':
+ sltmp = new_entry(SOCK_STREAM, optarg);
+ if (!sltmp) {
+ exit(1);
+ }
+ sltmp->next = sl;
+ sl = sltmp;
+ count++;
+ break;
+ case 'd':
+ sltmp = new_entry(SOCK_DGRAM, optarg);
+ if (!sltmp) {
+ exit(1);
+ }
+ sltmp->next = sl;
+ sl = sltmp;
+ count++;
+ break;
+ case 'r':
+ sltmp = new_entry(SOCK_RAW, optarg);
+ if (!sltmp) {
+ exit(1);
+ }
+ sltmp->next = sl;
+ sl = sltmp;
+ count++;
+ break;
+ case 'p':
+ run_prog = optarg;
+ break;
+ default:
+ exit(1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ for(sltmp = sl; sltmp != NULL; sltmp = sltmp->next)
+ if (open_socket(sltmp) < 0) {
+ fprintf(stderr, "failed to create socket!\n");
+ exit(1);
+ }
+
+ setuid(getuid());
+
+ {
+ int i;
+ char **newargv;
+ char *run_prog_name;
+
+ newargv = (char **)malloc((1 + 2*count + argc + 1) * sizeof(char*));
+
+ if ((run_prog_name = strrchr(run_prog, (int)'/')) == NULL)
+ run_prog_name = run_prog;
+ else
+ run_prog_name++;
+
+ i = 0;
+ newargv[i++] = run_prog_name;
+
+ for (; argc; argc--, argv++, i++)
+ newargv[i] = *argv;
+ for(sltmp = sl; sltmp != NULL; ) {
+ char *fd_str = (char *)malloc(8);
+ if (!fd_str) exit(1);
+ sprintf(fd_str, "%d", sltmp->fd);
+ if (sltmp->arg && *(sltmp->arg))
+ newargv[i++] = sltmp->arg;
+ newargv[i++] = fd_str;
+ sl = sltmp;
+ sltmp = sltmp->next;
+ free(sl);
+ }
+ newargv[i] = (char *)NULL;
+ execv(run_prog, newargv);
+ perror("exec");
+ exit(1);
+ }
+ exit(0);
+}
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
index 60979278fc..33ae3bd3f2 100644
--- a/lib/inets/test/inets_sup_SUITE.erl
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,14 +23,14 @@
-include_lib("common_test/include/ct.hrl").
-
%% Note: This directive should only be used in test suites.
-compile(export_all).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [default_tree, ftpc_worker, tftpd_worker, httpd_subtree,
+ [default_tree, ftpc_worker, tftpd_worker,
+ httpd_subtree, httpd_subtree_profile,
httpc_subtree].
groups() ->
@@ -41,54 +42,29 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-%%--------------------------------------------------------------------
-%% Function: init_per_suite(Config) -> Config
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Initiation before the whole suite
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%%--------------------------------------------------------------------
init_per_suite(Config) ->
Config.
-%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config) -> _
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after the whole suite
-%%--------------------------------------------------------------------
end_per_suite(_) ->
inets:stop(),
ok.
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(Case, Config) -> Config
-%% Case - atom()
-%% Name of the test case that is about to be run.
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Initiation before each test case
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%%--------------------------------------------------------------------
init_per_testcase(httpd_subtree, Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
NewConfig = lists:keydelete(watchdog, 1, Config),
PrivDir = ?config(priv_dir, Config),
-
+ Dir = filename:join(PrivDir, "root"),
+ ok = file:make_dir(Dir),
+
SimpleConfig = [{port, 0},
{server_name,"www.test"},
{modules, [mod_get]},
- {server_root, PrivDir},
- {document_root, PrivDir},
+ {server_root, Dir},
+ {document_root, Dir},
{bind_address, any},
{ipfamily, inet}],
try
+ inets:stop(),
inets:start(),
inets:start(httpd, SimpleConfig),
[{watchdog, Dog} | NewConfig]
@@ -97,7 +73,33 @@ init_per_testcase(httpd_subtree, Config) ->
inets:stop(),
exit({failed_starting_inets, Reason})
end;
-
+
+init_per_testcase(httpd_subtree_profile, Config) ->
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Dir = filename:join(PrivDir, "root"),
+ ok = file:make_dir(Dir),
+
+ SimpleConfig = [{port, 0},
+ {server_name,"www.test"},
+ {modules, [mod_get]},
+ {server_root, Dir},
+ {document_root, Dir},
+ {bind_address, any},
+ {profile, test_profile},
+ {ipfamily, inet}],
+ try
+ inets:stop(),
+ inets:start(),
+ {ok, _} = inets:start(httpd, SimpleConfig),
+ [{watchdog, Dog} | NewConfig]
+ catch
+ _:Reason ->
+ inets:stop(),
+ exit({failed_starting_inets, Reason})
+ end;
+
init_per_testcase(_Case, Config) ->
Dog = test_server:timetrap(?t:minutes(5)),
@@ -106,20 +108,13 @@ init_per_testcase(_Case, Config) ->
ok = inets:start(),
[{watchdog, Dog} | NewConfig].
-
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(Case, Config) -> _
-%% Case - atom()
-%% Name of the test case that is about to be run.
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after each test case
-%%--------------------------------------------------------------------
-end_per_testcase(httpd_subtree, Config) ->
+end_per_testcase(Case, Config) when Case == httpd_subtree;
+ Case == httpd_subtree_profile ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
- PrivDir = ?config(priv_dir, Config),
- inets_test_lib:del_dirs(PrivDir),
+ PrivDir = ?config(priv_dir, Config),
+ Dir = filename:join(PrivDir, "root"),
+ inets_test_lib:del_dirs(Dir),
ok;
end_per_testcase(_, Config) ->
@@ -131,16 +126,9 @@ end_per_testcase(_, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-
-
-%%-------------------------------------------------------------------------
-%% default_tree
-%%-------------------------------------------------------------------------
-default_tree(doc) ->
- ["Makes sure the correct processes are started and linked,"
- "in the default case."];
-default_tree(suite) ->
- [];
+default_tree() ->
+ [{doc, "Makes sure the correct processes are started and linked,"
+ "in the default case."}].
default_tree(Config) when is_list(Config) ->
TopSupChildren = supervisor:which_children(inets_sup),
4 = length(TopSupChildren),
@@ -173,15 +161,9 @@ default_tree(Config) when is_list(Config) ->
ok.
-
-%%-------------------------------------------------------------------------
-%% ftpc_worker
-%%-------------------------------------------------------------------------
-ftpc_worker(doc) ->
- ["Makes sure the ftp worker processes are added and removed "
- "appropriatly to/from the supervison tree."];
-ftpc_worker(suite) ->
- [];
+ftpc_worker() ->
+ [{doc, "Makes sure the ftp worker processes are added and removed "
+ "appropriatly to/from the supervison tree."}].
ftpc_worker(Config) when is_list(Config) ->
[] = supervisor:which_children(ftp_sup),
try
@@ -207,14 +189,8 @@ ftpc_worker(Config) when is_list(Config) ->
{skip, "No available FTP servers"}
end.
-
-%%-------------------------------------------------------------------------
-%% tftpd_worker
-%%-------------------------------------------------------------------------
-tftpd_worker(doc) ->
- ["Makes sure the tftp sub tree is correct."];
-tftpd_worker(suite) ->
- [];
+tftpd_worker() ->
+ [{doc, "Makes sure the tftp sub tree is correct."}].
tftpd_worker(Config) when is_list(Config) ->
[] = supervisor:which_children(tftp_sup),
{ok, Pid0} = inets:start(tftpd, [{host, inets_test_lib:hostname()},
@@ -228,22 +204,63 @@ tftpd_worker(Config) when is_list(Config) ->
[] = supervisor:which_children(tftp_sup),
ok.
+httpd_subtree() ->
+ [{doc, "Makes sure the httpd sub tree is correct."}].
+httpd_subtree(Config) when is_list(Config) ->
+ do_httpd_subtree(Config, default).
+
+httpd_subtree_profile(doc) ->
+ ["Makes sure the httpd sub tree is correct when using a profile"];
+httpd_subtree_profile(Config) when is_list(Config) ->
+ do_httpd_subtree(Config, test_profile).
+
+httpc_subtree() ->
+ [{doc, "Makes sure the httpd sub tree is correct."}].
+httpc_subtree(Config) when is_list(Config) ->
+ {ok, Foo} = inets:start(httpc, [{profile, foo}]),
+
+ {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ HttpcChildren = supervisor:which_children(httpc_profile_sup),
+
+ {value, {httpc_manager, _, worker, [httpc_manager]}} =
+ lists:keysearch(httpc_manager, 1, HttpcChildren),
+
+ {value,{{httpc,foo}, _Pid, worker, [httpc_manager]}} =
+ lists:keysearch({httpc, foo}, 1, HttpcChildren),
+ false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
+
+ inets:stop(httpc, Foo),
+ exit(Bar, normal).
%%-------------------------------------------------------------------------
-%% httpd_subtree
+%% Internal functions
%%-------------------------------------------------------------------------
-httpd_subtree(doc) ->
- ["Makes sure the httpd sub tree is correct."];
-httpd_subtree(suite) ->
- [];
-httpd_subtree(Config) when is_list(Config) ->
- %% Check that we have the httpd top supervisor
+
+verify_child(Parent, Child, Type) ->
+ Children = supervisor:which_children(Parent),
+ verify_child(Children, Parent, Child, Type).
+
+verify_child([], Parent, Child, _Type) ->
+ {error, {child_not_found, Child, Parent}};
+verify_child([{Id, _Pid, Type2, Mods}|Children], Parent, Child, Type) ->
+ case lists:member(Child, Mods) of
+ true when (Type2 =:= Type) ->
+ {ok, Id};
+ true when (Type2 =/= Type) ->
+ {error, {wrong_type, Type2, Child, Parent}};
+ false ->
+ verify_child(Children, Parent, Child, Type)
+ end.
+
+do_httpd_subtree(_Config, Profile) ->
+ %% Check that we have the httpd top supervisor
{ok, _} = verify_child(inets_sup, httpd_sup, supervisor),
%% Check that we have the httpd instance supervisor
{ok, Id} = verify_child(httpd_sup, httpd_instance_sup, supervisor),
- {httpd_instance_sup, Addr, Port} = Id,
- Instance = httpd_util:make_name("httpd_instance_sup", Addr, Port),
+ {httpd_instance_sup, Addr, Port, Profile} = Id,
+ Instance = httpd_util:make_name("httpd_instance_sup", Addr, Port, Profile),
%% Check that we have the expected httpd instance children
{ok, _} = verify_child(Instance, httpd_connection_sup, supervisor),
@@ -252,7 +269,7 @@ httpd_subtree(Config) when is_list(Config) ->
{ok, _} = verify_child(Instance, httpd_manager, worker),
%% Check that the httpd instance acc supervisor has children
- InstanceAcc = httpd_util:make_name("httpd_acceptor_sup", Addr, Port),
+ InstanceAcc = httpd_util:make_name("httpd_acceptor_sup", Addr, Port, Profile),
case supervisor:which_children(InstanceAcc) of
[_ | _] ->
ok;
@@ -263,7 +280,7 @@ httpd_subtree(Config) when is_list(Config) ->
%% Check that the httpd instance misc supervisor has no children
io:format("httpd_subtree -> verify misc~n", []),
- InstanceMisc = httpd_util:make_name("httpd_misc_sup", Addr, Port),
+ InstanceMisc = httpd_util:make_name("httpd_misc_sup", Addr, Port, Profile),
case supervisor:which_children(InstanceMisc) of
[] ->
ok;
@@ -273,45 +290,3 @@ httpd_subtree(Config) when is_list(Config) ->
end,
io:format("httpd_subtree -> done~n", []),
ok.
-
-
-verify_child(Parent, Child, Type) ->
- Children = supervisor:which_children(Parent),
- verify_child(Children, Parent, Child, Type).
-
-verify_child([], Parent, Child, _Type) ->
- {error, {child_not_found, Child, Parent}};
-verify_child([{Id, _Pid, Type2, Mods}|Children], Parent, Child, Type) ->
- case lists:member(Child, Mods) of
- true when (Type2 =:= Type) ->
- {ok, Id};
- true when (Type2 =/= Type) ->
- {error, {wrong_type, Type2, Child, Parent}};
- false ->
- verify_child(Children, Parent, Child, Type)
- end.
-
-%%-------------------------------------------------------------------------
-%% httpc_subtree
-%%-------------------------------------------------------------------------
-httpc_subtree(doc) ->
- ["Makes sure the httpc sub tree is correct."];
-httpc_subtree(suite) ->
- [];
-httpc_subtree(Config) when is_list(Config) ->
- {ok, Foo} = inets:start(httpc, [{profile, foo}]),
-
- {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
-
- HttpcChildren = supervisor:which_children(httpc_profile_sup),
-
- {value, {httpc_manager, _, worker, [httpc_manager]}} =
- lists:keysearch(httpc_manager, 1, HttpcChildren),
-
- {value,{{httpc,foo}, _Pid, worker, [httpc_manager]}} =
- lists:keysearch({httpc, foo}, 1, HttpcChildren),
- false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
-
- inets:stop(httpc, Foo),
- exit(Bar, normal).
-
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
index 4be9d9c8b3..f1185f7574 100644
--- a/lib/inets/test/inets_test_lib.erl
+++ b/lib/inets/test/inets_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -498,13 +499,6 @@ close(essl,Socket) ->
close(ip_comm,Socket) ->
catch gen_tcp:close(Socket).
-millis() ->
- erlang:now().
-
-millis_diff(A,B) ->
- T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000),
- T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000),
- T1 - T2.
hours(N) -> trunc(N * 1000 * 60 * 60).
minutes(N) -> trunc(N * 1000 * 60).
@@ -546,7 +540,7 @@ flush() ->
tsp(F) ->
tsp(F, []).
tsp(F, A) ->
- Timestamp = formated_timestamp(),
+ Timestamp = inets_lib:formated_timestamp(),
ct:pal("*** ~s ~p ~p " ++ F ++ "~n",
[Timestamp, node(), self() | A]).
@@ -559,18 +553,6 @@ tss(Time) ->
timestamp() ->
http_util:timestamp().
-formated_timestamp() ->
- format_timestamp( os:timestamp() ).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
start_apps(Apps) ->
lists:foreach(fun(App) ->
application:stop(App),
@@ -581,3 +563,12 @@ stop_apps(Apps) ->
application:stop(App)
end, Apps).
+inet_port(Node) ->
+ {Port, Socket} = do_inet_port(Node),
+ rpc:call(Node, gen_tcp, close, [Socket]),
+ Port.
+
+do_inet_port(Node) ->
+ {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
+ {ok, Port} = rpc:call(Node, inet, port, [Socket]),
+ {Port, Socket}.
diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl
index 6a86b1b764..b2989be08d 100644
--- a/lib/inets/test/inets_test_lib.hrl
+++ b/lib/inets/test/inets_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/inets/test/old_httpd_SUITE.erl b/lib/inets/test/old_httpd_SUITE.erl
index 74c11f71ba..aaaf69fbec 100644
--- a/lib/inets/test/old_httpd_SUITE.erl
+++ b/lib/inets/test/old_httpd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -2072,13 +2073,13 @@ create_config(Config, Access, FileName) ->
"Modules mod_alias mod_htaccess mod_auth "
"mod_security "
"mod_responsecontrol mod_trace mod_esi "
- "mod_actions mod_cgi mod_include mod_dir "
+ "mod_actions mod_cgi mod_dir "
"mod_range mod_get "
"mod_head mod_log mod_disk_log";
_ ->
"Modules mod_alias mod_auth mod_security "
"mod_responsecontrol mod_trace mod_esi "
- "mod_actions mod_cgi mod_include mod_dir "
+ "mod_actions mod_cgi mod_dir "
"mod_range mod_get "
"mod_head mod_log mod_disk_log"
end,
@@ -2436,7 +2437,7 @@ create_ipv6_config(Config, FileName, Ipv6Address) ->
MaxHdrAct = io_lib:format("~p", [close]),
Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
- " mod_include mod_dir mod_get mod_head"
+ " mod_dir mod_get mod_head"
" mod_log mod_disk_log mod_trace",
SSL =
diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile b/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile
index d7a3231068..4f23295401 100644
--- a/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf
index ceb94237d2..87c2973e5a 100644
--- a/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/inets/test/property_test/ftp_simple_client_server.erl b/lib/inets/test/property_test/ftp_simple_client_server.erl
index 40e630ee5c..8b6aff3c56 100644
--- a/lib/inets/test/property_test/ftp_simple_client_server.erl
+++ b/lib/inets/test/property_test/ftp_simple_client_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/tftp_SUITE.erl b/lib/inets/test/tftp_SUITE.erl
index 59fb644667..497a50e654 100644
--- a/lib/inets/test/tftp_SUITE.erl
+++ b/lib/inets/test/tftp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -75,7 +76,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[simple, extra, reuse_connection, resend_client,
- resend_server].
+ resend_server, large_file].
groups() ->
[].
@@ -901,6 +902,41 @@ reuse_connection(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Large file: transfer > 65535 blocks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+large_file(doc) ->
+ ["Start the daemon and test transfer of files greater than 32M."];
+large_file(suite) ->
+ [];
+large_file(Config) when is_list(Config) ->
+ ?VERIFY(ok, application:start(inets)),
+
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])),
+
+ %% Read fail
+ RemoteFilename = "tftp_temporary_large_file_remote_test_file.txt",
+ LocalFilename = "tftp_temporary_large_file_local_test_file.txt",
+
+ {ok, FH} = file:open(LocalFilename, [write,exclusive]),
+ {ok, Size} = file:position(FH, {eof, 2*512*65535}),
+ ok = file:truncate(FH),
+ ?IGNORE(file:close(FH)),
+
+ %% Write and read
+ ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, LocalFilename, [{port, Port}])),
+ ?IGNORE(file:delete(LocalFilename)),
+ ?VERIFY({ok, Size}, tftp:read_file(RemoteFilename, LocalFilename, [{port, Port}])),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ?VERIFY(ok, application:stop(inets)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Goodies
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/inets/test/tftp_test_lib.erl b/lib/inets/test/tftp_test_lib.erl
index e9b691828f..406a49e863 100644
--- a/lib/inets/test/tftp_test_lib.erl
+++ b/lib/inets/test/tftp_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/tftp_test_lib.hrl b/lib/inets/test/tftp_test_lib.hrl
index bef024720a..4e50f05d04 100644
--- a/lib/inets/test/tftp_test_lib.hrl
+++ b/lib/inets/test/tftp_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl
index f75e347d0c..2642b8fd4e 100644
--- a/lib/inets/test/uri_SUITE.erl
+++ b/lib/inets/test/uri_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,7 +49,8 @@ all() ->
queries,
fragments,
escaped,
- hexed_query
+ hexed_query,
+ scheme_validation
].
%%--------------------------------------------------------------------
@@ -174,6 +176,26 @@ hexed_query(Config) when is_list(Config) ->
verify_uri(URI2, Verify2),
verify_uri(URI3, Verify3).
+scheme_validation(Config) when is_list(Config) ->
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment"),
+
+ ValidationFun =
+ fun("http") -> valid;
+ (_) -> {error, bad_scheme}
+ end,
+
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment",
+ [{scheme_validation_fun, ValidationFun}]),
+ {error, bad_scheme} =
+ http_uri:parse("https://localhost#fragment",
+ [{scheme_validation_fun, ValidationFun}]),
+ %% non-fun scheme_validation_fun works as no option passed
+ {ok, {https,[],"localhost",443,"/",""}} =
+ http_uri:parse("https://localhost#fragment",
+ [{scheme_validation_fun, none}]).
+
%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 38d46cc6fd..12ac75a4b9 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -4,20 +4,21 @@
#
# Copyright Ericsson AB 2001-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
APPLICATION = inets
-INETS_VSN = 5.10.9
+INETS_VSN = 6.2.4
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/.classpath b/lib/jinterface/.classpath
new file mode 100644
index 0000000000..9785e55986
--- /dev/null
+++ b/lib/jinterface/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="java_src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="output" path="priv"/>
+</classpath>
diff --git a/lib/jinterface/.gitignore b/lib/jinterface/.gitignore
new file mode 100644
index 0000000000..3418d354a9
--- /dev/null
+++ b/lib/jinterface/.gitignore
@@ -0,0 +1,2 @@
+priv/
+
diff --git a/lib/jinterface/.project b/lib/jinterface/.project
new file mode 100644
index 0000000000..450b96dc12
--- /dev/null
+++ b/lib/jinterface/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>jinterface</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/lib/jinterface/.settings/org.eclipse.jdt.core.prefs b/lib/jinterface/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..e8b3772a8a
--- /dev/null
+++ b/lib/jinterface/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,296 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/lib/jinterface/.settings/org.eclipse.jdt.ui.prefs b/lib/jinterface/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000000..9190d818bc
--- /dev/null
+++ b/lib/jinterface/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,121 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=true
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=true
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=true
+cleanup.use_this_for_non_static_field_access=true
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=true
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_jinterface
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_jinterface
+formatter_settings_version=12
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=true
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=false
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=false
+sp_cleanup.use_parentheses_in_expressions=true
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
diff --git a/lib/jinterface/Makefile b/lib/jinterface/Makefile
index 2f937523f1..9cb993c87e 100644
--- a/lib/jinterface/Makefile
+++ b/lib/jinterface/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/jinterface/doc/src/Makefile b/lib/jinterface/doc/src/Makefile
index 069a5bef1f..baf9418787 100644
--- a/lib/jinterface/doc/src/Makefile
+++ b/lib/jinterface/doc/src/Makefile
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/jinterface/doc/src/book.xml b/lib/jinterface/doc/src/book.xml
index 498fdbfd63..954ff3944b 100644
--- a/lib/jinterface/doc/src/book.xml
+++ b/lib/jinterface/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/doc/src/index.html.src b/lib/jinterface/doc/src/index.html.src
index 76c304d4fe..b9b4555636 100644
--- a/lib/jinterface/doc/src/index.html.src
+++ b/lib/jinterface/doc/src/index.html.src
@@ -6,16 +6,17 @@
Copyright Ericsson AB 2000-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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%
-->
diff --git a/lib/jinterface/doc/src/jinterface.xml b/lib/jinterface/doc/src/jinterface.xml
index d8f6183bd8..513ce36248 100644
--- a/lib/jinterface/doc/src/jinterface.xml
+++ b/lib/jinterface/doc/src/jinterface.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/doc/src/jinterface_users_guide.xml b/lib/jinterface/doc/src/jinterface_users_guide.xml
index 5dfe5c0c6d..0be0f87b92 100644
--- a/lib/jinterface/doc/src/jinterface_users_guide.xml
+++ b/lib/jinterface/doc/src/jinterface_users_guide.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -223,6 +224,14 @@ OtpNode node = new OtpNode("gurka"); </code>
</section>
<section>
+ <title>Transport Factory</title>
+ <p>All necessary connections are made using methods of
+ <seealso marker="java/com/ericsson/otp/erlang/OtpTransportFactory">OtpTransportFactory</seealso>
+ interface. Default OtpTransportFactory implementation is based on standard Socket class.
+ User may provide custom transport factory as needed. See java doc for details.</p>
+ </section>
+
+ <section>
<title>Sending and Receiving Messages</title>
<p>Messages sent with this package must be instances of
<seealso marker="java/com/ericsson/otp/erlang/OtpErlangObject">OtpErlangObject</seealso>
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index fc5f8be53e..e66bcda0c1 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,88 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
+<section><title>Jinterface 1.6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add missing Term tag matching switch statement that was
+ missing an external fun tag.</p>
+ <p>
+ Own Id: OTP-13106</p>
+ </item>
+ <item>
+ <p>
+ fixed writing small compressed values.</p>
+ <p>
+ Own Id: OTP-13165</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Jinterface 1.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Reformat the sources for JInterface uniformly and
+ according to the standard Java style guidelines. Provide
+ description of the rules applied in Eclipse format (for
+ other editors one can check the settings against these).</p>
+ <p>
+ In short, the formatting style is: * indentation uses
+ only spaces; each level is 4 positions * no trailing
+ whitespace * mostly default Java style formatting (any
+ difference is minor) * always use {} blocks * use 'final'
+ as much as possible</p>
+ <p>
+ Own Id: OTP-12333</p>
+ </item>
+ <item>
+ <p>
+ Remove extra @param in javadoc as this gives an error
+ when building the docs in java 1.8</p>
+ <p>
+ Own Id: OTP-12746</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add basic transport factory implementation. This makes
+ possible creating connections between nodes using ssh
+ channels for example.</p>
+ <p>
+ Own Id: OTP-12686</p>
+ </item>
+ <item>
+ <p>
+ Add Jinterface generic match and bind methods to provide
+ low level interface base methods sufficient for variety
+ of higher level pattern matching/variable binding
+ implementations.</p>
+ <p>
+ Own Id: OTP-12691</p>
+ </item>
+ <item>
+ <p>
+ Minimal Java version is now 1.6</p>
+ <p>
+ Own Id: OTP-12715</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Jinterface 1.5.12</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/jinterface/doc/src/notes_history.xml b/lib/jinterface/doc/src/notes_history.xml
index 6e25446751..31313e2e34 100644
--- a/lib/jinterface/doc/src/notes_history.xml
+++ b/lib/jinterface/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/doc/src/part.xml b/lib/jinterface/doc/src/part.xml
index dfa0d91cda..8459bf5131 100644
--- a/lib/jinterface/doc/src/part.xml
+++ b/lib/jinterface/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/doc/src/part_notes.xml b/lib/jinterface/doc/src/part_notes.xml
index 1f8fc69798..19047603c7 100644
--- a/lib/jinterface/doc/src/part_notes.xml
+++ b/lib/jinterface/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/doc/src/part_notes_history.xml b/lib/jinterface/doc/src/part_notes_history.xml
index 31211f3645..2d058ff3ba 100644
--- a/lib/jinterface/doc/src/part_notes_history.xml
+++ b/lib/jinterface/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/doc/src/ref_man.xml b/lib/jinterface/doc/src/ref_man.xml
index 62d6013db6..738eb1943d 100644
--- a/lib/jinterface/doc/src/ref_man.xml
+++ b/lib/jinterface/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/jinterface/java_src/Makefile b/lib/jinterface/java_src/Makefile
index dafb634eac..bb6844ead8 100644
--- a/lib/jinterface/java_src/Makefile
+++ b/lib/jinterface/java_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
index b8a973753a..e84a4296b5 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
@@ -1,52 +1,53 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2010. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
import java.io.IOException;
-import java.net.Socket;
+import java.io.OutputStream;
import java.util.Random;
/**
* Maintains a connection between a Java process and a remote Erlang, Java or C
* node. The object maintains connection state and allows data to be sent to and
* received from the peer.
- *
+ *
* <p>
* This abstract class provides the neccesary methods to maintain the actual
* connection and encode the messages and headers in the proper format according
* to the Erlang distribution protocol. Subclasses can use these methods to
* provide a more or less transparent communication channel as desired.
* </p>
- *
+ *
* <p>
* Note that no receive methods are provided. Subclasses must provide methods
* for message delivery, and may implement their own receive methods.
* <p>
- *
+ *
* <p>
* If an exception occurs in any of the methods in this class, the connection
* will be closed and must be reopened in order to resume communication with the
* peer. This will be indicated to the subclass by passing the exception to its
* delivery() method.
* </p>
- *
+ *
* <p>
* The System property OtpConnection.trace can be used to change the initial
* trace level setting for all connections. Normally the initial trace level is
@@ -84,7 +85,7 @@ public abstract class AbstractConnection extends Thread {
private volatile boolean done = false;
protected boolean connected = false; // connection status
- protected Socket socket; // communication channel
+ protected OtpTransport socket; // communication channel
protected OtpPeer peer; // who are we connected to
protected OtpLocalNode localNode; // this nodes id
String name; // local name of this connection
@@ -106,104 +107,103 @@ public abstract class AbstractConnection extends Thread {
private int flags = 0;
static {
- // trace this connection?
- final String trace = System.getProperties().getProperty(
- "OtpConnection.trace");
- try {
- if (trace != null) {
- defaultLevel = Integer.valueOf(trace).intValue();
- }
- } catch (final NumberFormatException e) {
- defaultLevel = 0;
- }
- random = new Random();
+ // trace this connection?
+ final String trace = System.getProperties().getProperty(
+ "OtpConnection.trace");
+ try {
+ if (trace != null) {
+ defaultLevel = Integer.valueOf(trace).intValue();
+ }
+ } catch (final NumberFormatException e) {
+ defaultLevel = 0;
+ }
+ random = new Random();
}
// private AbstractConnection() {
// }
/**
- * Accept an incoming connection from a remote node. Used by {@link
- * OtpSelf#accept() OtpSelf.accept()} to create a connection based on data
- * received when handshaking with the peer node, when the remote node is the
- * connection intitiator.
- *
- * @exception java.io.IOException if it was not possible to connect to the
- * peer.
- *
- * @exception OtpAuthException if handshake resulted in an authentication
- * error
+ * Accept an incoming connection from a remote node. Used by
+ * {@link OtpSelf#accept() OtpSelf.accept()} to create a connection based on
+ * data received when handshaking with the peer node, when the remote node
+ * is the connection initiator.
+ *
+ * @exception java.io.IOException
+ * if it was not possible to connect to the peer.
+ *
+ * @exception OtpAuthException
+ * if handshake resulted in an authentication error
*/
- protected AbstractConnection(final OtpLocalNode self, final Socket s)
- throws IOException, OtpAuthException {
- this.localNode = self;
- peer = new OtpPeer();
- socket = s;
-
- socket.setTcpNoDelay(true);
-
- traceLevel = defaultLevel;
- setDaemon(true);
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- ACCEPT FROM " + s.getInetAddress() + ":"
- + s.getPort());
- }
-
- // get his info
- recvName(peer);
-
- // now find highest common dist value
- if (peer.proto != self.proto || self.distHigh < peer.distLow
- || self.distLow > peer.distHigh) {
- close();
- throw new IOException(
- "No common protocol found - cannot accept connection");
- }
- // highest common version: min(peer.distHigh, self.distHigh)
- peer.distChoose = peer.distHigh > self.distHigh ? self.distHigh
- : peer.distHigh;
-
- doAccept();
- name = peer.node();
+ protected AbstractConnection(final OtpLocalNode self, final OtpTransport s)
+ throws IOException, OtpAuthException {
+ localNode = self;
+ peer = new OtpPeer(self.transportFactory);
+ socket = s;
+
+ traceLevel = defaultLevel;
+ setDaemon(true);
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- ACCEPT FROM " + s);
+ }
+
+ // get his info
+ recvName(peer);
+
+ // now find highest common dist value
+ if (peer.proto != self.proto || self.distHigh < peer.distLow
+ || self.distLow > peer.distHigh) {
+ close();
+ throw new IOException(
+ "No common protocol found - cannot accept connection");
+ }
+ // highest common version: min(peer.distHigh, self.distHigh)
+ peer.distChoose = peer.distHigh > self.distHigh ? self.distHigh
+ : peer.distHigh;
+
+ doAccept();
+ name = peer.node();
}
/**
* Intiate and open a connection to a remote node.
- *
- * @exception java.io.IOException if it was not possible to connect to the
- * peer.
- *
- * @exception OtpAuthException if handshake resulted in an authentication
- * error.
+ *
+ * @exception java.io.IOException
+ * if it was not possible to connect to the peer.
+ *
+ * @exception OtpAuthException
+ * if handshake resulted in an authentication error.
*/
protected AbstractConnection(final OtpLocalNode self, final OtpPeer other)
- throws IOException, OtpAuthException {
- peer = other;
- this.localNode = self;
- socket = null;
- int port;
-
- traceLevel = defaultLevel;
- setDaemon(true);
-
- // now get a connection between the two...
- port = OtpEpmd.lookupPort(peer);
-
- // now find highest common dist value
- if (peer.proto != self.proto || self.distHigh < peer.distLow
- || self.distLow > peer.distHigh) {
- throw new IOException("No common protocol found - cannot connect");
- }
-
- // highest common version: min(peer.distHigh, self.distHigh)
- peer.distChoose = peer.distHigh > self.distHigh ? self.distHigh
- : peer.distHigh;
-
- doConnect(port);
-
- name = peer.node();
- connected = true;
+ throws IOException, OtpAuthException {
+ peer = other;
+ localNode = self;
+ socket = null;
+ int port;
+
+ traceLevel = defaultLevel;
+ setDaemon(true);
+
+ // now get a connection between the two...
+ port = OtpEpmd.lookupPort(peer);
+ if (port == 0)
+ throw new IOException("No remote node found - cannot connect");
+
+ // now find highest common dist value
+ if (peer.proto != self.proto || self.distHigh < peer.distLow
+ || self.distLow > peer.distHigh) {
+ throw new IOException("No common protocol found - cannot connect");
+ }
+
+ // highest common version: min(peer.distHigh, self.distHigh)
+ peer.distChoose = peer.distHigh > self.distHigh ? self.distHigh
+ : peer.distHigh;
+
+ doConnect(port);
+
+ name = peer.node();
+ connected = true;
}
/**
@@ -218,91 +218,91 @@ public abstract class AbstractConnection extends Thread {
/**
* Send a pre-encoded message to a named process on a remote node.
- *
+ *
* @param dest
* the name of the remote process.
* @param payload
* the encoded message to send.
- *
+ *
* @exception java.io.IOException
* if the connection is not active or a communication error
* occurs.
*/
protected void sendBuf(final OtpErlangPid from, final String dest,
- final OtpOutputStream payload) throws IOException {
- if (!connected) {
- throw new IOException("Not connected");
- }
- @SuppressWarnings("resource")
- final OtpOutputStream header = new OtpOutputStream(headerLen);
-
- // preamble: 4 byte length + "passthrough" tag + version
- header.write4BE(0); // reserve space for length
- header.write1(passThrough);
- header.write1(version);
-
- // header info
- header.write_tuple_head(4);
- header.write_long(regSendTag);
- header.write_any(from);
- if (sendCookie) {
- header.write_atom(localNode.cookie());
- } else {
- header.write_atom("");
- }
- header.write_atom(dest);
-
- // version for payload
- header.write1(version);
-
- // fix up length in preamble
- header.poke4BE(0, header.size() + payload.size() - 4);
-
- do_send(header, payload);
+ final OtpOutputStream payload) throws IOException {
+ if (!connected) {
+ throw new IOException("Not connected");
+ }
+ @SuppressWarnings("resource")
+ final OtpOutputStream header = new OtpOutputStream(headerLen);
+
+ // preamble: 4 byte length + "passthrough" tag + version
+ header.write4BE(0); // reserve space for length
+ header.write1(passThrough);
+ header.write1(version);
+
+ // header info
+ header.write_tuple_head(4);
+ header.write_long(regSendTag);
+ header.write_any(from);
+ if (sendCookie) {
+ header.write_atom(localNode.cookie());
+ } else {
+ header.write_atom("");
+ }
+ header.write_atom(dest);
+
+ // version for payload
+ header.write1(version);
+
+ // fix up length in preamble
+ header.poke4BE(0, header.size() + payload.size() - 4);
+
+ do_send(header, payload);
}
/**
* Send a pre-encoded message to a process on a remote node.
- *
+ *
* @param dest
* the Erlang PID of the remote process.
* @param payload
* the encoded message to send.
- *
+ *
* @exception java.io.IOException
* if the connection is not active or a communication error
* occurs.
*/
protected void sendBuf(final OtpErlangPid from, final OtpErlangPid dest,
- final OtpOutputStream payload) throws IOException {
- if (!connected) {
- throw new IOException("Not connected");
- }
- @SuppressWarnings("resource")
- final OtpOutputStream header = new OtpOutputStream(headerLen);
-
- // preamble: 4 byte length + "passthrough" tag + version
- header.write4BE(0); // reserve space for length
- header.write1(passThrough);
- header.write1(version);
-
- // header info
- header.write_tuple_head(3);
- header.write_long(sendTag);
- if (sendCookie) {
- header.write_atom(localNode.cookie());
- } else {
- header.write_atom("");
- }
- header.write_any(dest);
-
- // version for payload
- header.write1(version);
-
- // fix up length in preamble
- header.poke4BE(0, header.size() + payload.size() - 4);
-
- do_send(header, payload);
+ final OtpOutputStream payload) throws IOException {
+ if (!connected) {
+ throw new IOException("Not connected");
+ }
+ @SuppressWarnings("resource")
+ final OtpOutputStream header = new OtpOutputStream(headerLen);
+
+ // preamble: 4 byte length + "passthrough" tag + version
+ header.write4BE(0); // reserve space for length
+ header.write1(passThrough);
+ header.write1(version);
+
+ // header info
+ header.write_tuple_head(3);
+ header.write_long(sendTag);
+ if (sendCookie) {
+ header.write_atom(localNode.cookie());
+ } else {
+ header.write_atom("");
+ }
+ header.write_any(dest);
+
+ // version for payload
+ header.write1(version);
+
+ // fix up length in preamble
+ header.poke4BE(0, header.size() + payload.size() - 4);
+
+ do_send(header, payload);
}
/*
@@ -311,60 +311,60 @@ public abstract class AbstractConnection extends Thread {
* otherwise
*/
private void cookieError(final OtpLocalNode local,
- final OtpErlangAtom cookie) throws OtpAuthException {
- try {
- @SuppressWarnings("resource")
- final OtpOutputStream header = new OtpOutputStream(headerLen);
-
- // preamble: 4 byte length + "passthrough" tag + version
- header.write4BE(0); // reserve space for length
- header.write1(passThrough);
- header.write1(version);
-
- header.write_tuple_head(4);
- header.write_long(regSendTag);
- header.write_any(local.createPid()); // disposable pid
- header.write_atom(cookie.atomValue()); // important: his cookie,
- // not mine...
- header.write_atom("auth");
-
- // version for payload
- header.write1(version);
-
- // the payload
-
- // the no_auth message (copied from Erlang) Don't change this
- // (Erlang will crash)
- // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
- // [foo@aule]}}
- final OtpErlangObject[] msg = new OtpErlangObject[2];
- final OtpErlangObject[] msgbody = new OtpErlangObject[3];
-
- msgbody[0] = new OtpErlangAtom("print");
- msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local
- + " **~n");
- // Erlang will crash and burn if there is no third argument here...
- msgbody[2] = new OtpErlangList(); // empty list
-
- msg[0] = new OtpErlangAtom("$gen_cast");
- msg[1] = new OtpErlangTuple(msgbody);
-
- @SuppressWarnings("resource")
- final OtpOutputStream payload = new OtpOutputStream(
- new OtpErlangTuple(msg));
-
- // fix up length in preamble
- header.poke4BE(0, header.size() + payload.size() - 4);
-
- try {
- do_send(header, payload);
- } catch (final IOException e) {
- } // ignore
- } finally {
- close();
- }
- throw new OtpAuthException("Remote cookie not authorized: "
- + cookie.atomValue());
+ final OtpErlangAtom cookie) throws OtpAuthException {
+ try {
+ @SuppressWarnings("resource")
+ final OtpOutputStream header = new OtpOutputStream(headerLen);
+
+ // preamble: 4 byte length + "passthrough" tag + version
+ header.write4BE(0); // reserve space for length
+ header.write1(passThrough);
+ header.write1(version);
+
+ header.write_tuple_head(4);
+ header.write_long(regSendTag);
+ header.write_any(local.createPid()); // disposable pid
+ header.write_atom(cookie.atomValue()); // important: his cookie,
+ // not mine...
+ header.write_atom("auth");
+
+ // version for payload
+ header.write1(version);
+
+ // the payload
+
+ // the no_auth message (copied from Erlang) Don't change this
+ // (Erlang will crash)
+ // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
+ // [foo@aule]}}
+ final OtpErlangObject[] msg = new OtpErlangObject[2];
+ final OtpErlangObject[] msgbody = new OtpErlangObject[3];
+
+ msgbody[0] = new OtpErlangAtom("print");
+ msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local
+ + " **~n");
+ // Erlang will crash and burn if there is no third argument here...
+ msgbody[2] = new OtpErlangList(); // empty list
+
+ msg[0] = new OtpErlangAtom("$gen_cast");
+ msg[1] = new OtpErlangTuple(msgbody);
+
+ @SuppressWarnings("resource")
+ final OtpOutputStream payload = new OtpOutputStream(
+ new OtpErlangTuple(msg));
+
+ // fix up length in preamble
+ header.poke4BE(0, header.size() + payload.size() - 4);
+
+ try {
+ do_send(header, payload);
+ } catch (final IOException e) {
+ } // ignore
+ } finally {
+ close();
+ }
+ throw new OtpAuthException("Remote cookie not authorized: "
+ + cookie.atomValue());
}
// link to pid
@@ -374,364 +374,366 @@ public abstract class AbstractConnection extends Thread {
* remote node. If the link is still active when the remote process
* terminates, an exit signal will be sent to this connection. Use
* {@link #sendUnlink unlink()} to remove the link.
- *
+ *
* @param dest
* the Erlang PID of the remote process.
- *
+ *
* @exception java.io.IOException
* if the connection is not active or a communication error
* occurs.
*/
protected void sendLink(final OtpErlangPid from, final OtpErlangPid dest)
- throws IOException {
- if (!connected) {
- throw new IOException("Not connected");
- }
- @SuppressWarnings("resource")
- final OtpOutputStream header = new OtpOutputStream(headerLen);
+ throws IOException {
+ if (!connected) {
+ throw new IOException("Not connected");
+ }
+ @SuppressWarnings("resource")
+ final OtpOutputStream header = new OtpOutputStream(headerLen);
- // preamble: 4 byte length + "passthrough" tag
- header.write4BE(0); // reserve space for length
- header.write1(passThrough);
- header.write1(version);
+ // preamble: 4 byte length + "passthrough" tag
+ header.write4BE(0); // reserve space for length
+ header.write1(passThrough);
+ header.write1(version);
- // header
- header.write_tuple_head(3);
- header.write_long(linkTag);
- header.write_any(from);
- header.write_any(dest);
+ // header
+ header.write_tuple_head(3);
+ header.write_long(linkTag);
+ header.write_any(from);
+ header.write_any(dest);
- // fix up length in preamble
- header.poke4BE(0, header.size() - 4);
+ // fix up length in preamble
+ header.poke4BE(0, header.size() - 4);
- do_send(header);
+ do_send(header);
}
/**
* Remove a link between the local node and the specified process on the
* remote node. This method deactivates links created with {@link #sendLink
* link()}.
- *
+ *
* @param dest
* the Erlang PID of the remote process.
- *
+ *
* @exception java.io.IOException
* if the connection is not active or a communication error
* occurs.
*/
protected void sendUnlink(final OtpErlangPid from, final OtpErlangPid dest)
- throws IOException {
- if (!connected) {
- throw new IOException("Not connected");
- }
- @SuppressWarnings("resource")
- final OtpOutputStream header = new OtpOutputStream(headerLen);
+ throws IOException {
+ if (!connected) {
+ throw new IOException("Not connected");
+ }
+ @SuppressWarnings("resource")
+ final OtpOutputStream header = new OtpOutputStream(headerLen);
- // preamble: 4 byte length + "passthrough" tag
- header.write4BE(0); // reserve space for length
- header.write1(passThrough);
- header.write1(version);
+ // preamble: 4 byte length + "passthrough" tag
+ header.write4BE(0); // reserve space for length
+ header.write1(passThrough);
+ header.write1(version);
- // header
- header.write_tuple_head(3);
- header.write_long(unlinkTag);
- header.write_any(from);
- header.write_any(dest);
+ // header
+ header.write_tuple_head(3);
+ header.write_long(unlinkTag);
+ header.write_any(from);
+ header.write_any(dest);
- // fix up length in preamble
- header.poke4BE(0, header.size() - 4);
+ // fix up length in preamble
+ header.poke4BE(0, header.size() - 4);
- do_send(header);
+ do_send(header);
}
/* used internally when "processes" terminate */
protected void sendExit(final OtpErlangPid from, final OtpErlangPid dest,
- final OtpErlangObject reason) throws IOException {
- sendExit(exitTag, from, dest, reason);
+ final OtpErlangObject reason) throws IOException {
+ sendExit(exitTag, from, dest, reason);
}
/**
* Send an exit signal to a remote process.
- *
+ *
* @param dest
* the Erlang PID of the remote process.
* @param reason
* an Erlang term describing the exit reason.
- *
+ *
* @exception java.io.IOException
* if the connection is not active or a communication error
* occurs.
*/
protected void sendExit2(final OtpErlangPid from, final OtpErlangPid dest,
- final OtpErlangObject reason) throws IOException {
- sendExit(exit2Tag, from, dest, reason);
+ final OtpErlangObject reason) throws IOException {
+ sendExit(exit2Tag, from, dest, reason);
}
private void sendExit(final int tag, final OtpErlangPid from,
- final OtpErlangPid dest, final OtpErlangObject reason)
- throws IOException {
- if (!connected) {
- throw new IOException("Not connected");
- }
- @SuppressWarnings("resource")
- final OtpOutputStream header = new OtpOutputStream(headerLen);
+ final OtpErlangPid dest, final OtpErlangObject reason)
+ throws IOException {
+ if (!connected) {
+ throw new IOException("Not connected");
+ }
+ @SuppressWarnings("resource")
+ final OtpOutputStream header = new OtpOutputStream(headerLen);
- // preamble: 4 byte length + "passthrough" tag
- header.write4BE(0); // reserve space for length
- header.write1(passThrough);
- header.write1(version);
+ // preamble: 4 byte length + "passthrough" tag
+ header.write4BE(0); // reserve space for length
+ header.write1(passThrough);
+ header.write1(version);
- // header
- header.write_tuple_head(4);
- header.write_long(tag);
- header.write_any(from);
- header.write_any(dest);
- header.write_any(reason);
+ // header
+ header.write_tuple_head(4);
+ header.write_long(tag);
+ header.write_any(from);
+ header.write_any(dest);
+ header.write_any(reason);
- // fix up length in preamble
- header.poke4BE(0, header.size() - 4);
+ // fix up length in preamble
+ header.poke4BE(0, header.size() - 4);
- do_send(header);
+ do_send(header);
}
@SuppressWarnings("resource")
@Override
public void run() {
- if (!connected) {
- deliver(new IOException("Not connected"));
- return;
- }
-
- final byte[] lbuf = new byte[4];
- OtpInputStream ibuf;
- OtpErlangObject traceobj;
- int len;
- final byte[] tock = { 0, 0, 0, 0 };
-
- try {
- receive_loop: while (!done) {
- // don't return until we get a real message
- // or a failure of some kind (e.g. EXIT)
- // read length and read buffer must be atomic!
- do {
- // read 4 bytes - get length of incoming packet
- // socket.getInputStream().read(lbuf);
- readSock(socket, lbuf);
- ibuf = new OtpInputStream(lbuf, flags);
- len = ibuf.read4BE();
-
- // received tick? send tock!
- if (len == 0) {
- synchronized (this) {
- socket.getOutputStream().write(tock);
- }
- }
-
- } while (len == 0); // tick_loop
-
- // got a real message (maybe) - read len bytes
- final byte[] tmpbuf = new byte[len];
- // i = socket.getInputStream().read(tmpbuf);
- readSock(socket, tmpbuf);
- ibuf.close();
- ibuf = new OtpInputStream(tmpbuf, flags);
-
- if (ibuf.read1() != passThrough) {
- break receive_loop;
- }
-
- // got a real message (really)
- OtpErlangObject reason = null;
- OtpErlangAtom cookie = null;
- OtpErlangObject tmp = null;
- OtpErlangTuple head = null;
- OtpErlangAtom toName;
- OtpErlangPid to;
- OtpErlangPid from;
- int tag;
-
- // decode the header
- tmp = ibuf.read_any();
- if (!(tmp instanceof OtpErlangTuple)) {
- break receive_loop;
- }
-
- head = (OtpErlangTuple) tmp;
- if (!(head.elementAt(0) instanceof OtpErlangLong)) {
- break receive_loop;
- }
-
- // lets see what kind of message this is
- tag = (int) ((OtpErlangLong) head.elementAt(0)).longValue();
-
- switch (tag) {
- case sendTag: // { SEND, Cookie, ToPid }
- case sendTTTag: // { SEND, Cookie, ToPid, TraceToken }
- if (!cookieOk) {
- // we only check this once, he can send us bad cookies
- // later if he likes
- if (!(head.elementAt(1) instanceof OtpErlangAtom)) {
- break receive_loop;
- }
- cookie = (OtpErlangAtom) head.elementAt(1);
- if (sendCookie) {
- if (!cookie.atomValue().equals(localNode.cookie())) {
- cookieError(localNode, cookie);
- }
- } else {
- if (!cookie.atomValue().equals("")) {
- cookieError(localNode, cookie);
- }
- }
- cookieOk = true;
- }
-
- if (traceLevel >= sendThreshold) {
- System.out.println("<- " + headerType(head) + " "
- + head);
-
- /* show received payload too */
- ibuf.mark(0);
- traceobj = ibuf.read_any();
-
- if (traceobj != null) {
- System.out.println(" " + traceobj);
- } else {
- System.out.println(" (null)");
- }
- ibuf.reset();
- }
-
- to = (OtpErlangPid) head.elementAt(2);
-
- deliver(new OtpMsg(to, ibuf));
- break;
-
- case regSendTag: // { REG_SEND, FromPid, Cookie, ToName }
- case regSendTTTag: // { REG_SEND, FromPid, Cookie, ToName,
- // TraceToken }
- if (!cookieOk) {
- // we only check this once, he can send us bad cookies
- // later if he likes
- if (!(head.elementAt(2) instanceof OtpErlangAtom)) {
- break receive_loop;
- }
- cookie = (OtpErlangAtom) head.elementAt(2);
- if (sendCookie) {
- if (!cookie.atomValue().equals(localNode.cookie())) {
- cookieError(localNode, cookie);
- }
- } else {
- if (!cookie.atomValue().equals("")) {
- cookieError(localNode, cookie);
- }
- }
- cookieOk = true;
- }
-
- if (traceLevel >= sendThreshold) {
- System.out.println("<- " + headerType(head) + " "
- + head);
-
- /* show received payload too */
- ibuf.mark(0);
- traceobj = ibuf.read_any();
-
- if (traceobj != null) {
- System.out.println(" " + traceobj);
- } else {
- System.out.println(" (null)");
- }
- ibuf.reset();
- }
-
- from = (OtpErlangPid) head.elementAt(1);
- toName = (OtpErlangAtom) head.elementAt(3);
-
- deliver(new OtpMsg(from, toName.atomValue(), ibuf));
- break;
-
- case exitTag: // { EXIT, FromPid, ToPid, Reason }
- case exit2Tag: // { EXIT2, FromPid, ToPid, Reason }
- if (head.elementAt(3) == null) {
- break receive_loop;
- }
- if (traceLevel >= ctrlThreshold) {
- System.out.println("<- " + headerType(head) + " "
- + head);
- }
-
- from = (OtpErlangPid) head.elementAt(1);
- to = (OtpErlangPid) head.elementAt(2);
- reason = head.elementAt(3);
-
- deliver(new OtpMsg(tag, from, to, reason));
- break;
-
- case exitTTTag: // { EXIT, FromPid, ToPid, TraceToken, Reason }
- case exit2TTTag: // { EXIT2, FromPid, ToPid, TraceToken,
- // Reason
- // }
- // as above, but bifferent element number
- if (head.elementAt(4) == null) {
- break receive_loop;
- }
- if (traceLevel >= ctrlThreshold) {
- System.out.println("<- " + headerType(head) + " "
- + head);
- }
-
- from = (OtpErlangPid) head.elementAt(1);
- to = (OtpErlangPid) head.elementAt(2);
- reason = head.elementAt(4);
-
- deliver(new OtpMsg(tag, from, to, reason));
- break;
-
- case linkTag: // { LINK, FromPid, ToPid}
- case unlinkTag: // { UNLINK, FromPid, ToPid}
- if (traceLevel >= ctrlThreshold) {
- System.out.println("<- " + headerType(head) + " "
- + head);
- }
-
- from = (OtpErlangPid) head.elementAt(1);
- to = (OtpErlangPid) head.elementAt(2);
-
- deliver(new OtpMsg(tag, from, to));
- break;
-
- // absolutely no idea what to do with these, so we ignore
- // them...
- case groupLeaderTag: // { GROUPLEADER, FromPid, ToPid}
- // (just show trace)
- if (traceLevel >= ctrlThreshold) {
- System.out.println("<- " + headerType(head) + " "
- + head);
- }
- break;
-
- default:
- // garbage?
- break receive_loop;
- }
- } // end receive_loop
-
- // this section reachable only with break
- // we have received garbage from peer
- deliver(new OtpErlangExit("Remote is sending garbage"));
-
- } // try
-
- catch (final OtpAuthException e) {
- deliver(e);
- } catch (final OtpErlangDecodeException e) {
- deliver(new OtpErlangExit("Remote is sending garbage"));
- } catch (final IOException e) {
- deliver(new OtpErlangExit("Remote has closed connection"));
- } finally {
- close();
- }
+ if (!connected) {
+ deliver(new IOException("Not connected"));
+ return;
+ }
+
+ final byte[] lbuf = new byte[4];
+ OtpInputStream ibuf;
+ OtpErlangObject traceobj;
+ int len;
+ final byte[] tock = { 0, 0, 0, 0 };
+
+ try {
+ receive_loop: while (!done) {
+ // don't return until we get a real message
+ // or a failure of some kind (e.g. EXIT)
+ // read length and read buffer must be atomic!
+ do {
+ // read 4 bytes - get length of incoming packet
+ // socket.getInputStream().read(lbuf);
+ readSock(socket, lbuf);
+ ibuf = new OtpInputStream(lbuf, flags);
+ len = ibuf.read4BE();
+
+ // received tick? send tock!
+ if (len == 0) {
+ synchronized (this) {
+ OutputStream out = socket.getOutputStream();
+ out.write(tock);
+ out.flush();
+ }
+ }
+
+ } while (len == 0); // tick_loop
+
+ // got a real message (maybe) - read len bytes
+ final byte[] tmpbuf = new byte[len];
+ // i = socket.getInputStream().read(tmpbuf);
+ readSock(socket, tmpbuf);
+ ibuf.close();
+ ibuf = new OtpInputStream(tmpbuf, flags);
+
+ if (ibuf.read1() != passThrough) {
+ break receive_loop;
+ }
+
+ // got a real message (really)
+ OtpErlangObject reason = null;
+ OtpErlangAtom cookie = null;
+ OtpErlangObject tmp = null;
+ OtpErlangTuple head = null;
+ OtpErlangAtom toName;
+ OtpErlangPid to;
+ OtpErlangPid from;
+ int tag;
+
+ // decode the header
+ tmp = ibuf.read_any();
+ if (!(tmp instanceof OtpErlangTuple)) {
+ break receive_loop;
+ }
+
+ head = (OtpErlangTuple) tmp;
+ if (!(head.elementAt(0) instanceof OtpErlangLong)) {
+ break receive_loop;
+ }
+
+ // lets see what kind of message this is
+ tag = (int) ((OtpErlangLong) head.elementAt(0)).longValue();
+
+ switch (tag) {
+ case sendTag: // { SEND, Cookie, ToPid }
+ case sendTTTag: // { SEND, Cookie, ToPid, TraceToken }
+ if (!cookieOk) {
+ // we only check this once, he can send us bad cookies
+ // later if he likes
+ if (!(head.elementAt(1) instanceof OtpErlangAtom)) {
+ break receive_loop;
+ }
+ cookie = (OtpErlangAtom) head.elementAt(1);
+ if (sendCookie) {
+ if (!cookie.atomValue().equals(localNode.cookie())) {
+ cookieError(localNode, cookie);
+ }
+ } else {
+ if (!cookie.atomValue().equals("")) {
+ cookieError(localNode, cookie);
+ }
+ }
+ cookieOk = true;
+ }
+
+ if (traceLevel >= sendThreshold) {
+ System.out.println("<- " + headerType(head) + " "
+ + head);
+
+ /* show received payload too */
+ ibuf.mark(0);
+ traceobj = ibuf.read_any();
+
+ if (traceobj != null) {
+ System.out.println(" " + traceobj);
+ } else {
+ System.out.println(" (null)");
+ }
+ ibuf.reset();
+ }
+
+ to = (OtpErlangPid) head.elementAt(2);
+
+ deliver(new OtpMsg(to, ibuf));
+ break;
+
+ case regSendTag: // { REG_SEND, FromPid, Cookie, ToName }
+ case regSendTTTag: // { REG_SEND, FromPid, Cookie, ToName,
+ // TraceToken }
+ if (!cookieOk) {
+ // we only check this once, he can send us bad cookies
+ // later if he likes
+ if (!(head.elementAt(2) instanceof OtpErlangAtom)) {
+ break receive_loop;
+ }
+ cookie = (OtpErlangAtom) head.elementAt(2);
+ if (sendCookie) {
+ if (!cookie.atomValue().equals(localNode.cookie())) {
+ cookieError(localNode, cookie);
+ }
+ } else {
+ if (!cookie.atomValue().equals("")) {
+ cookieError(localNode, cookie);
+ }
+ }
+ cookieOk = true;
+ }
+
+ if (traceLevel >= sendThreshold) {
+ System.out.println("<- " + headerType(head) + " "
+ + head);
+
+ /* show received payload too */
+ ibuf.mark(0);
+ traceobj = ibuf.read_any();
+
+ if (traceobj != null) {
+ System.out.println(" " + traceobj);
+ } else {
+ System.out.println(" (null)");
+ }
+ ibuf.reset();
+ }
+
+ from = (OtpErlangPid) head.elementAt(1);
+ toName = (OtpErlangAtom) head.elementAt(3);
+
+ deliver(new OtpMsg(from, toName.atomValue(), ibuf));
+ break;
+
+ case exitTag: // { EXIT, FromPid, ToPid, Reason }
+ case exit2Tag: // { EXIT2, FromPid, ToPid, Reason }
+ if (head.elementAt(3) == null) {
+ break receive_loop;
+ }
+ if (traceLevel >= ctrlThreshold) {
+ System.out.println("<- " + headerType(head) + " "
+ + head);
+ }
+
+ from = (OtpErlangPid) head.elementAt(1);
+ to = (OtpErlangPid) head.elementAt(2);
+ reason = head.elementAt(3);
+
+ deliver(new OtpMsg(tag, from, to, reason));
+ break;
+
+ case exitTTTag: // { EXIT, FromPid, ToPid, TraceToken, Reason }
+ case exit2TTTag: // { EXIT2, FromPid, ToPid, TraceToken,
+ // Reason
+ // }
+ // as above, but bifferent element number
+ if (head.elementAt(4) == null) {
+ break receive_loop;
+ }
+ if (traceLevel >= ctrlThreshold) {
+ System.out.println("<- " + headerType(head) + " "
+ + head);
+ }
+
+ from = (OtpErlangPid) head.elementAt(1);
+ to = (OtpErlangPid) head.elementAt(2);
+ reason = head.elementAt(4);
+
+ deliver(new OtpMsg(tag, from, to, reason));
+ break;
+
+ case linkTag: // { LINK, FromPid, ToPid}
+ case unlinkTag: // { UNLINK, FromPid, ToPid}
+ if (traceLevel >= ctrlThreshold) {
+ System.out.println("<- " + headerType(head) + " "
+ + head);
+ }
+
+ from = (OtpErlangPid) head.elementAt(1);
+ to = (OtpErlangPid) head.elementAt(2);
+
+ deliver(new OtpMsg(tag, from, to));
+ break;
+
+ // absolutely no idea what to do with these, so we ignore
+ // them...
+ case groupLeaderTag: // { GROUPLEADER, FromPid, ToPid}
+ // (just show trace)
+ if (traceLevel >= ctrlThreshold) {
+ System.out.println("<- " + headerType(head) + " "
+ + head);
+ }
+ break;
+
+ default:
+ // garbage?
+ break receive_loop;
+ }
+ } // end receive_loop
+
+ // this section reachable only with break
+ // we have received garbage from peer
+ deliver(new OtpErlangExit("Remote is sending garbage"));
+
+ } // try
+
+ catch (final OtpAuthException e) {
+ deliver(e);
+ } catch (final OtpErlangDecodeException e) {
+ deliver(new OtpErlangExit("Remote is sending garbage"));
+ } catch (final IOException e) {
+ deliver(new OtpErlangExit("Remote has closed connection"));
+ } finally {
+ close();
+ }
}
/**
@@ -739,7 +741,7 @@ public abstract class AbstractConnection extends Thread {
* Set the trace level for this connection. Normally tracing is off by
* default unless System property OtpConnection.trace was set.
* </p>
- *
+ *
* <p>
* The following levels are valid: 0 turns off tracing completely, 1 shows
* ordinary send and receive messages, 2 shows control messages such as link
@@ -747,632 +749,643 @@ public abstract class AbstractConnection extends Thread {
* communication with Epmd. Each level includes the information shown by the
* lower ones.
* </p>
- *
+ *
* @param level
* the level to set.
- *
+ *
* @return the previous trace level.
*/
- public int setTraceLevel(int level) {
- final int oldLevel = traceLevel;
+ public int setTraceLevel(final int level) {
+ final int oldLevel = traceLevel;
- // pin the value
- int theLevel = level;
- if (level < 0) {
- theLevel = 0;
- } else if (level > 4) {
- theLevel = 4;
- }
+ // pin the value
+ int theLevel = level;
+ if (level < 0) {
+ theLevel = 0;
+ } else if (level > 4) {
+ theLevel = 4;
+ }
- traceLevel = theLevel;
+ traceLevel = theLevel;
- return oldLevel;
+ return oldLevel;
}
/**
* Get the trace level for this connection.
- *
+ *
* @return the current trace level.
*/
public int getTraceLevel() {
- return traceLevel;
+ return traceLevel;
}
/**
* Close the connection to the remote node.
*/
public void close() {
- done = true;
- connected = false;
- synchronized (this) {
- try {
- if (socket != null) {
- if (traceLevel >= ctrlThreshold) {
- System.out.println("-> CLOSE");
- }
- socket.close();
- }
- } catch (final IOException e) { /* ignore socket close errors */
- } finally {
- socket = null;
- }
- }
+ done = true;
+ connected = false;
+ synchronized (this) {
+ try {
+ if (socket != null) {
+ if (traceLevel >= ctrlThreshold) {
+ System.out.println("-> CLOSE");
+ }
+ socket.close();
+ }
+ } catch (final IOException e) { /* ignore socket close errors */
+ } finally {
+ socket = null;
+ }
+ }
}
@Override
protected void finalize() {
- close();
+ close();
}
/**
* Determine if the connection is still alive. Note that this method only
* reports the status of the connection, and that it is possible that there
* are unread messages waiting in the receive queue.
- *
+ *
* @return true if the connection is alive.
*/
public boolean isConnected() {
- return connected;
+ return connected;
}
// used by send and send_reg (message types with payload)
protected synchronized void do_send(final OtpOutputStream header,
- final OtpOutputStream payload) throws IOException {
- try {
- if (traceLevel >= sendThreshold) {
- // Need to decode header and output buffer to show trace
- // message!
- // First make OtpInputStream, then decode.
- try {
- final OtpErlangObject h = header.getOtpInputStream(5)
- .read_any();
- System.out.println("-> " + headerType(h) + " " + h);
-
- OtpErlangObject o = payload.getOtpInputStream(0).read_any();
- System.out.println(" " + o);
- o = null;
- } catch (final OtpErlangDecodeException e) {
- System.out.println(" " + "can't decode output buffer:"
- + e);
- }
- }
-
- header.writeTo(socket.getOutputStream());
- payload.writeTo(socket.getOutputStream());
- } catch (final IOException e) {
- close();
- throw e;
- }
+ final OtpOutputStream payload) throws IOException {
+ try {
+ if (traceLevel >= sendThreshold) {
+ // Need to decode header and output buffer to show trace
+ // message!
+ // First make OtpInputStream, then decode.
+ try {
+ final OtpErlangObject h = header.getOtpInputStream(5)
+ .read_any();
+ System.out.println("-> " + headerType(h) + " " + h);
+
+ OtpErlangObject o = payload.getOtpInputStream(0).read_any();
+ System.out.println(" " + o);
+ o = null;
+ } catch (final OtpErlangDecodeException e) {
+ System.out.println(" " + "can't decode output buffer:"
+ + e);
+ }
+ }
+
+ // group flush op in favour of possible ssh-tunneled stream
+ OutputStream out = socket.getOutputStream();
+ header.writeTo(out);
+ payload.writeTo(out);
+ out.flush();
+ } catch (final IOException e) {
+ close();
+ throw e;
+ }
}
// used by the other message types
protected synchronized void do_send(final OtpOutputStream header)
- throws IOException {
- try {
- if (traceLevel >= ctrlThreshold) {
- try {
- final OtpErlangObject h = header.getOtpInputStream(5)
- .read_any();
- System.out.println("-> " + headerType(h) + " " + h);
- } catch (final OtpErlangDecodeException e) {
- System.out.println(" " + "can't decode output buffer: "
- + e);
- }
- }
- header.writeTo(socket.getOutputStream());
- } catch (final IOException e) {
- close();
- throw e;
- }
+ throws IOException {
+ try {
+ if (traceLevel >= ctrlThreshold) {
+ try {
+ final OtpErlangObject h = header.getOtpInputStream(5)
+ .read_any();
+ System.out.println("-> " + headerType(h) + " " + h);
+ } catch (final OtpErlangDecodeException e) {
+ System.out.println(" " + "can't decode output buffer: "
+ + e);
+ }
+ }
+ header.writeToAndFlush(socket.getOutputStream());
+ } catch (final IOException e) {
+ close();
+ throw e;
+ }
}
protected String headerType(final OtpErlangObject h) {
- int tag = -1;
+ int tag = -1;
- if (h instanceof OtpErlangTuple) {
- tag = (int) ((OtpErlangLong) ((OtpErlangTuple) h).elementAt(0))
- .longValue();
- }
+ if (h instanceof OtpErlangTuple) {
+ tag = (int) ((OtpErlangLong) ((OtpErlangTuple) h).elementAt(0))
+ .longValue();
+ }
- switch (tag) {
- case linkTag:
- return "LINK";
+ switch (tag) {
+ case linkTag:
+ return "LINK";
- case sendTag:
- return "SEND";
+ case sendTag:
+ return "SEND";
- case exitTag:
- return "EXIT";
+ case exitTag:
+ return "EXIT";
- case unlinkTag:
- return "UNLINK";
+ case unlinkTag:
+ return "UNLINK";
- case regSendTag:
- return "REG_SEND";
+ case regSendTag:
+ return "REG_SEND";
- case groupLeaderTag:
- return "GROUP_LEADER";
+ case groupLeaderTag:
+ return "GROUP_LEADER";
- case exit2Tag:
- return "EXIT2";
+ case exit2Tag:
+ return "EXIT2";
- case sendTTTag:
- return "SEND_TT";
+ case sendTTTag:
+ return "SEND_TT";
- case exitTTTag:
- return "EXIT_TT";
+ case exitTTTag:
+ return "EXIT_TT";
- case regSendTTTag:
- return "REG_SEND_TT";
+ case regSendTTTag:
+ return "REG_SEND_TT";
- case exit2TTTag:
- return "EXIT2_TT";
- }
+ case exit2TTTag:
+ return "EXIT2_TT";
+ }
- return "(unknown type)";
+ return "(unknown type)";
}
/* this method now throws exception if we don't get full read */
- protected int readSock(final Socket s, final byte[] b) throws IOException {
- int got = 0;
- final int len = b.length;
- int i;
-
- synchronized (this) {
- if (s == null) {
- throw new IOException("expected " + len
- + " bytes, socket was closed");
- }
- }
-
- while (got < len) {
- i = s.getInputStream().read(b, got, len - got);
-
- if (i < 0) {
- throw new IOException("expected " + len
- + " bytes, got EOF after " + got + " bytes");
- } else if (i == 0 && len != 0) {
- /*
- * This is a corner case. According to
- * http://java.sun.com/j2se/1.4.2/docs/api/ class InputStream
- * is.read(,,l) can only return 0 if l==0. In other words it
- * should not happen, but apparently did.
- */
- throw new IOException("Remote connection closed");
- } else {
- got += i;
- }
- }
- return got;
+ protected int readSock(final OtpTransport s, final byte[] b)
+ throws IOException {
+ int got = 0;
+ final int len = b.length;
+ int i;
+
+ synchronized (this) {
+ if (s == null) {
+ throw new IOException("expected " + len
+ + " bytes, socket was closed");
+ }
+ }
+
+ while (got < len) {
+ i = s.getInputStream().read(b, got, len - got);
+
+ if (i < 0) {
+ throw new IOException("expected " + len
+ + " bytes, got EOF after " + got + " bytes");
+ } else if (i == 0 && len != 0) {
+ /*
+ * This is a corner case. According to
+ * http://java.sun.com/j2se/1.4.2/docs/api/ class InputStream
+ * is.read(,,l) can only return 0 if l==0. In other words it
+ * should not happen, but apparently did.
+ */
+ throw new IOException("Remote connection closed");
+ } else {
+ got += i;
+ }
+ }
+ return got;
}
protected void doAccept() throws IOException, OtpAuthException {
- try {
- sendStatus("ok");
- final int our_challenge = genChallenge();
- sendChallenge(peer.distChoose, localNode.flags, our_challenge);
- final int her_challenge = recvChallengeReply(our_challenge);
- final byte[] our_digest = genDigest(her_challenge, localNode.cookie());
- sendChallengeAck(our_digest);
- connected = true;
- cookieOk = true;
- sendCookie = false;
- } catch (final IOException ie) {
- close();
- throw ie;
- } catch (final OtpAuthException ae) {
- close();
- throw ae;
- } catch (final Exception e) {
- final String nn = peer.node();
- close();
- IOException ioe = new IOException("Error accepting connection from " + nn);
- ioe.initCause(e);
- throw ioe;
- }
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- MD5 ACCEPTED " + peer.host());
- }
+ try {
+ sendStatus("ok");
+ final int our_challenge = genChallenge();
+ sendChallenge(peer.distChoose, localNode.flags, our_challenge);
+ final int her_challenge = recvChallengeReply(our_challenge);
+ final byte[] our_digest = genDigest(her_challenge,
+ localNode.cookie());
+ sendChallengeAck(our_digest);
+ connected = true;
+ cookieOk = true;
+ sendCookie = false;
+ } catch (final IOException ie) {
+ close();
+ throw ie;
+ } catch (final OtpAuthException ae) {
+ close();
+ throw ae;
+ } catch (final Exception e) {
+ final String nn = peer.node();
+ close();
+ final IOException ioe = new IOException(
+ "Error accepting connection from " + nn);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- MD5 ACCEPTED " + peer.host());
+ }
}
protected void doConnect(final int port) throws IOException,
- OtpAuthException {
- try {
- socket = new Socket(peer.host(), port);
- socket.setTcpNoDelay(true);
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("-> MD5 CONNECT TO " + peer.host() + ":"
- + port);
- }
- sendName(peer.distChoose, localNode.flags);
- recvStatus();
- final int her_challenge = recvChallenge();
- final byte[] our_digest = genDigest(her_challenge, localNode.cookie());
- final int our_challenge = genChallenge();
- sendChallengeReply(our_challenge, our_digest);
- recvChallengeAck(our_challenge);
- cookieOk = true;
- sendCookie = false;
- } catch (final OtpAuthException ae) {
- close();
- throw ae;
- } catch (final Exception e) {
- close();
- IOException ioe = new IOException("Cannot connect to peer node");
- ioe.initCause(e);
- throw ioe;
- }
+ OtpAuthException {
+ try {
+ socket = peer.createTransport(peer.host(), port);
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("-> MD5 CONNECT TO " + peer.host() + ":"
+ + port);
+ }
+ sendName(peer.distChoose, localNode.flags);
+ recvStatus();
+ final int her_challenge = recvChallenge();
+ final byte[] our_digest = genDigest(her_challenge,
+ localNode.cookie());
+ final int our_challenge = genChallenge();
+ sendChallengeReply(our_challenge, our_digest);
+ recvChallengeAck(our_challenge);
+ cookieOk = true;
+ sendCookie = false;
+ } catch (final OtpAuthException ae) {
+ close();
+ throw ae;
+ } catch (final Exception e) {
+ close();
+ final IOException ioe = new IOException(
+ "Cannot connect to peer node");
+ ioe.initCause(e);
+ throw ioe;
+ }
}
// This is nooo good as a challenge,
// XXX fix me.
static protected int genChallenge() {
- return random.nextInt();
+ return random.nextInt();
}
// Used to debug print a message digest
static String hex0(final byte x) {
- final char tab[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'a', 'b', 'c', 'd', 'e', 'f' };
- int uint;
- if (x < 0) {
- uint = x & 0x7F;
- uint |= 1 << 7;
- } else {
- uint = x;
- }
- return "" + tab[uint >>> 4] + tab[uint & 0xF];
+ final char tab[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f' };
+ int uint;
+ if (x < 0) {
+ uint = x & 0x7F;
+ uint |= 1 << 7;
+ } else {
+ uint = x;
+ }
+ return "" + tab[uint >>> 4] + tab[uint & 0xF];
}
static String hex(final byte[] b) {
- final StringBuffer sb = new StringBuffer();
- try {
- int i;
- for (i = 0; i < b.length; ++i) {
- sb.append(hex0(b[i]));
- }
- } catch (final Exception e) {
- // Debug function, ignore errors.
- }
- return sb.toString();
+ final StringBuffer sb = new StringBuffer();
+ try {
+ int i;
+ for (i = 0; i < b.length; ++i) {
+ sb.append(hex0(b[i]));
+ }
+ } catch (final Exception e) {
+ // Debug function, ignore errors.
+ }
+ return sb.toString();
}
protected byte[] genDigest(final int challenge, final String cookie) {
- int i;
- long ch2;
-
- if (challenge < 0) {
- ch2 = 1L << 31;
- ch2 |= challenge & 0x7FFFFFFF;
- } else {
- ch2 = challenge;
- }
- final OtpMD5 context = new OtpMD5();
- context.update(cookie);
- context.update("" + ch2);
-
- final int[] tmp = context.final_bytes();
- final byte[] res = new byte[tmp.length];
- for (i = 0; i < tmp.length; ++i) {
- res[i] = (byte) (tmp[i] & 0xFF);
- }
- return res;
+ int i;
+ long ch2;
+
+ if (challenge < 0) {
+ ch2 = 1L << 31;
+ ch2 |= challenge & 0x7FFFFFFF;
+ } else {
+ ch2 = challenge;
+ }
+ final OtpMD5 context = new OtpMD5();
+ context.update(cookie);
+ context.update("" + ch2);
+
+ final int[] tmp = context.final_bytes();
+ final byte[] res = new byte[tmp.length];
+ for (i = 0; i < tmp.length; ++i) {
+ res[i] = (byte) (tmp[i] & 0xFF);
+ }
+ return res;
}
- protected void sendName(final int dist, final int aflags) throws IOException {
+ protected void sendName(final int dist, final int aflags)
+ throws IOException {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- final String str = localNode.node();
- obuf.write2BE(str.length() + 7); // 7 bytes + nodename
- obuf.write1(AbstractNode.NTYPE_R6);
- obuf.write2BE(dist);
- obuf.write4BE(aflags);
- obuf.write(str.getBytes());
-
- obuf.writeTo(socket.getOutputStream());
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("-> " + "HANDSHAKE sendName" + " flags=" + aflags
- + " dist=" + dist + " local=" + localNode);
- }
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ final String str = localNode.node();
+ obuf.write2BE(str.length() + 7); // 7 bytes + nodename
+ obuf.write1(AbstractNode.NTYPE_R6);
+ obuf.write2BE(dist);
+ obuf.write4BE(aflags);
+ obuf.write(str.getBytes());
+
+ obuf.writeToAndFlush(socket.getOutputStream());
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("-> " + "HANDSHAKE sendName" + " flags="
+ + aflags + " dist=" + dist + " local=" + localNode);
+ }
}
protected void sendChallenge(final int dist, final int aflags,
- final int challenge) throws IOException {
+ final int challenge) throws IOException {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- final String str = localNode.node();
- obuf.write2BE(str.length() + 11); // 11 bytes + nodename
- obuf.write1(AbstractNode.NTYPE_R6);
- obuf.write2BE(dist);
- obuf.write4BE(aflags);
- obuf.write4BE(challenge);
- obuf.write(str.getBytes());
-
- obuf.writeTo(socket.getOutputStream());
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("-> " + "HANDSHAKE sendChallenge" + " flags="
- + aflags + " dist=" + dist + " challenge=" + challenge
- + " local=" + localNode);
- }
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ final String str = localNode.node();
+ obuf.write2BE(str.length() + 11); // 11 bytes + nodename
+ obuf.write1(AbstractNode.NTYPE_R6);
+ obuf.write2BE(dist);
+ obuf.write4BE(aflags);
+ obuf.write4BE(challenge);
+ obuf.write(str.getBytes());
+
+ obuf.writeToAndFlush(socket.getOutputStream());
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("-> " + "HANDSHAKE sendChallenge" + " flags="
+ + aflags + " dist=" + dist + " challenge=" + challenge
+ + " local=" + localNode);
+ }
}
protected byte[] read2BytePackage() throws IOException,
- OtpErlangDecodeException {
+ OtpErlangDecodeException {
- final byte[] lbuf = new byte[2];
- byte[] tmpbuf;
+ final byte[] lbuf = new byte[2];
+ byte[] tmpbuf;
- readSock(socket, lbuf);
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(lbuf, 0);
- final int len = ibuf.read2BE();
- tmpbuf = new byte[len];
- readSock(socket, tmpbuf);
- return tmpbuf;
+ readSock(socket, lbuf);
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(lbuf, 0);
+ final int len = ibuf.read2BE();
+ tmpbuf = new byte[len];
+ readSock(socket, tmpbuf);
+ return tmpbuf;
}
protected void recvName(final OtpPeer apeer) throws IOException {
- String hisname = "";
-
- try {
- final byte[] tmpbuf = read2BytePackage();
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
- byte[] tmpname;
- final int len = tmpbuf.length;
- apeer.ntype = ibuf.read1();
- if (apeer.ntype != AbstractNode.NTYPE_R6) {
- throw new IOException("Unknown remote node type");
- }
- apeer.distLow = apeer.distHigh = ibuf.read2BE();
- if (apeer.distLow < 5) {
- throw new IOException("Unknown remote node type");
- }
- apeer.flags = ibuf.read4BE();
- tmpname = new byte[len - 7];
- ibuf.readN(tmpname);
- hisname = OtpErlangString.newString(tmpname);
- // Set the old nodetype parameter to indicate hidden/normal status
- // When the old handshake is removed, the ntype should also be.
- if ((apeer.flags & AbstractNode.dFlagPublished) != 0) {
- apeer.ntype = AbstractNode.NTYPE_R4_ERLANG;
- } else {
- apeer.ntype = AbstractNode.NTYPE_R4_HIDDEN;
- }
-
- if ((apeer.flags & AbstractNode.dFlagExtendedReferences) == 0) {
- throw new IOException(
- "Handshake failed - peer cannot handle extended references");
- }
-
- if ((apeer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) {
- throw new IOException(
- "Handshake failed - peer cannot handle extended pids and ports");
- }
-
- } catch (final OtpErlangDecodeException e) {
- throw new IOException("Handshake failed - not enough data");
- }
-
- final int i = hisname.indexOf('@', 0);
- apeer.node = hisname;
- apeer.alive = hisname.substring(0, i);
- apeer.host = hisname.substring(i + 1, hisname.length());
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- " + "HANDSHAKE" + " ntype=" + apeer.ntype
- + " dist=" + apeer.distHigh + " remote=" + apeer);
- }
+ String hisname = "";
+
+ try {
+ final byte[] tmpbuf = read2BytePackage();
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
+ byte[] tmpname;
+ final int len = tmpbuf.length;
+ apeer.ntype = ibuf.read1();
+ if (apeer.ntype != AbstractNode.NTYPE_R6) {
+ throw new IOException("Unknown remote node type");
+ }
+ apeer.distLow = apeer.distHigh = ibuf.read2BE();
+ if (apeer.distLow < 5) {
+ throw new IOException("Unknown remote node type");
+ }
+ apeer.flags = ibuf.read4BE();
+ tmpname = new byte[len - 7];
+ ibuf.readN(tmpname);
+ hisname = OtpErlangString.newString(tmpname);
+ // Set the old nodetype parameter to indicate hidden/normal status
+ // When the old handshake is removed, the ntype should also be.
+ if ((apeer.flags & AbstractNode.dFlagPublished) != 0) {
+ apeer.ntype = AbstractNode.NTYPE_R4_ERLANG;
+ } else {
+ apeer.ntype = AbstractNode.NTYPE_R4_HIDDEN;
+ }
+
+ if ((apeer.flags & AbstractNode.dFlagExtendedReferences) == 0) {
+ throw new IOException(
+ "Handshake failed - peer cannot handle extended references");
+ }
+
+ if ((apeer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) {
+ throw new IOException(
+ "Handshake failed - peer cannot handle extended pids and ports");
+ }
+
+ } catch (final OtpErlangDecodeException e) {
+ throw new IOException("Handshake failed - not enough data");
+ }
+
+ final int i = hisname.indexOf('@', 0);
+ apeer.node = hisname;
+ apeer.alive = hisname.substring(0, i);
+ apeer.host = hisname.substring(i + 1, hisname.length());
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- " + "HANDSHAKE" + " ntype=" + apeer.ntype
+ + " dist=" + apeer.distHigh + " remote=" + apeer);
+ }
}
protected int recvChallenge() throws IOException {
- int challenge;
-
- try {
- final byte[] buf = read2BytePackage();
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(buf, 0);
- peer.ntype = ibuf.read1();
- if (peer.ntype != AbstractNode.NTYPE_R6) {
- throw new IOException("Unexpected peer type");
- }
- peer.distLow = peer.distHigh = ibuf.read2BE();
- peer.flags = ibuf.read4BE();
- challenge = ibuf.read4BE();
- final byte[] tmpname = new byte[buf.length - 11];
- ibuf.readN(tmpname);
- final String hisname = OtpErlangString.newString(tmpname);
- if (!hisname.equals(peer.node)) {
- throw new IOException(
- "Handshake failed - peer has wrong name: " + hisname);
- }
-
- if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) {
- throw new IOException(
- "Handshake failed - peer cannot handle extended references");
- }
-
- if ((peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) {
- throw new IOException(
- "Handshake failed - peer cannot handle extended pids and ports");
- }
-
- } catch (final OtpErlangDecodeException e) {
- throw new IOException("Handshake failed - not enough data");
- }
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- " + "HANDSHAKE recvChallenge" + " from="
- + peer.node + " challenge=" + challenge + " local=" + localNode);
- }
-
- return challenge;
+ int challenge;
+
+ try {
+ final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(buf, 0);
+ peer.ntype = ibuf.read1();
+ if (peer.ntype != AbstractNode.NTYPE_R6) {
+ throw new IOException("Unexpected peer type");
+ }
+ peer.distLow = peer.distHigh = ibuf.read2BE();
+ peer.flags = ibuf.read4BE();
+ challenge = ibuf.read4BE();
+ final byte[] tmpname = new byte[buf.length - 11];
+ ibuf.readN(tmpname);
+ final String hisname = OtpErlangString.newString(tmpname);
+ if (!hisname.equals(peer.node)) {
+ throw new IOException(
+ "Handshake failed - peer has wrong name: " + hisname);
+ }
+
+ if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) {
+ throw new IOException(
+ "Handshake failed - peer cannot handle extended references");
+ }
+
+ if ((peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) {
+ throw new IOException(
+ "Handshake failed - peer cannot handle extended pids and ports");
+ }
+
+ } catch (final OtpErlangDecodeException e) {
+ throw new IOException("Handshake failed - not enough data");
+ }
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- " + "HANDSHAKE recvChallenge" + " from="
+ + peer.node + " challenge=" + challenge + " local="
+ + localNode);
+ }
+
+ return challenge;
}
protected void sendChallengeReply(final int challenge, final byte[] digest)
- throws IOException {
+ throws IOException {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- obuf.write2BE(21);
- obuf.write1(ChallengeReply);
- obuf.write4BE(challenge);
- obuf.write(digest);
- obuf.writeTo(socket.getOutputStream());
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("-> " + "HANDSHAKE sendChallengeReply"
- + " challenge=" + challenge + " digest=" + hex(digest)
- + " local=" + localNode);
- }
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ obuf.write2BE(21);
+ obuf.write1(ChallengeReply);
+ obuf.write4BE(challenge);
+ obuf.write(digest);
+ obuf.writeToAndFlush(socket.getOutputStream());
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("-> " + "HANDSHAKE sendChallengeReply"
+ + " challenge=" + challenge + " digest=" + hex(digest)
+ + " local=" + localNode);
+ }
}
// Would use Array.equals in newer JDK...
private boolean digests_equals(final byte[] a, final byte[] b) {
- int i;
- for (i = 0; i < 16; ++i) {
- if (a[i] != b[i]) {
- return false;
- }
- }
- return true;
+ int i;
+ for (i = 0; i < 16; ++i) {
+ if (a[i] != b[i]) {
+ return false;
+ }
+ }
+ return true;
}
protected int recvChallengeReply(final int our_challenge)
- throws IOException, OtpAuthException {
-
- int challenge;
- final byte[] her_digest = new byte[16];
-
- try {
- final byte[] buf = read2BytePackage();
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(buf, 0);
- final int tag = ibuf.read1();
- if (tag != ChallengeReply) {
- throw new IOException("Handshake protocol error");
- }
- challenge = ibuf.read4BE();
- ibuf.readN(her_digest);
- final byte[] our_digest = genDigest(our_challenge, localNode.cookie());
- if (!digests_equals(her_digest, our_digest)) {
- throw new OtpAuthException("Peer authentication error.");
- }
- } catch (final OtpErlangDecodeException e) {
- throw new IOException("Handshake failed - not enough data");
- }
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- " + "HANDSHAKE recvChallengeReply"
- + " from=" + peer.node + " challenge=" + challenge
- + " digest=" + hex(her_digest) + " local=" + localNode);
- }
-
- return challenge;
+ throws IOException, OtpAuthException {
+
+ int challenge;
+ final byte[] her_digest = new byte[16];
+
+ try {
+ final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(buf, 0);
+ final int tag = ibuf.read1();
+ if (tag != ChallengeReply) {
+ throw new IOException("Handshake protocol error");
+ }
+ challenge = ibuf.read4BE();
+ ibuf.readN(her_digest);
+ final byte[] our_digest = genDigest(our_challenge,
+ localNode.cookie());
+ if (!digests_equals(her_digest, our_digest)) {
+ throw new OtpAuthException("Peer authentication error.");
+ }
+ } catch (final OtpErlangDecodeException e) {
+ throw new IOException("Handshake failed - not enough data");
+ }
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- " + "HANDSHAKE recvChallengeReply"
+ + " from=" + peer.node + " challenge=" + challenge
+ + " digest=" + hex(her_digest) + " local=" + localNode);
+ }
+
+ return challenge;
}
protected void sendChallengeAck(final byte[] digest) throws IOException {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- obuf.write2BE(17);
- obuf.write1(ChallengeAck);
- obuf.write(digest);
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ obuf.write2BE(17);
+ obuf.write1(ChallengeAck);
+ obuf.write(digest);
- obuf.writeTo(socket.getOutputStream());
+ obuf.writeToAndFlush(socket.getOutputStream());
- if (traceLevel >= handshakeThreshold) {
- System.out.println("-> " + "HANDSHAKE sendChallengeAck"
- + " digest=" + hex(digest) + " local=" + localNode);
- }
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("-> " + "HANDSHAKE sendChallengeAck"
+ + " digest=" + hex(digest) + " local=" + localNode);
+ }
}
protected void recvChallengeAck(final int our_challenge)
- throws IOException, OtpAuthException {
-
- final byte[] her_digest = new byte[16];
- try {
- final byte[] buf = read2BytePackage();
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(buf, 0);
- final int tag = ibuf.read1();
- if (tag != ChallengeAck) {
- throw new IOException("Handshake protocol error");
- }
- ibuf.readN(her_digest);
- final byte[] our_digest = genDigest(our_challenge, localNode.cookie());
- if (!digests_equals(her_digest, our_digest)) {
- throw new OtpAuthException("Peer authentication error.");
- }
- } catch (final OtpErlangDecodeException e) {
- throw new IOException("Handshake failed - not enough data");
- } catch (final Exception e) {
- throw new OtpAuthException("Peer authentication error.");
- }
-
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- " + "HANDSHAKE recvChallengeAck" + " from="
- + peer.node + " digest=" + hex(her_digest) + " local="
- + localNode);
- }
+ throws IOException, OtpAuthException {
+
+ final byte[] her_digest = new byte[16];
+ try {
+ final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(buf, 0);
+ final int tag = ibuf.read1();
+ if (tag != ChallengeAck) {
+ throw new IOException("Handshake protocol error");
+ }
+ ibuf.readN(her_digest);
+ final byte[] our_digest = genDigest(our_challenge,
+ localNode.cookie());
+ if (!digests_equals(her_digest, our_digest)) {
+ throw new OtpAuthException("Peer authentication error.");
+ }
+ } catch (final OtpErlangDecodeException e) {
+ throw new IOException("Handshake failed - not enough data");
+ } catch (final Exception e) {
+ throw new OtpAuthException("Peer authentication error.");
+ }
+
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- " + "HANDSHAKE recvChallengeAck" + " from="
+ + peer.node + " digest=" + hex(her_digest) + " local="
+ + localNode);
+ }
}
protected void sendStatus(final String status) throws IOException {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- obuf.write2BE(status.length() + 1);
- obuf.write1(ChallengeStatus);
- obuf.write(status.getBytes());
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ obuf.write2BE(status.length() + 1);
+ obuf.write1(ChallengeStatus);
+ obuf.write(status.getBytes());
- obuf.writeTo(socket.getOutputStream());
+ obuf.writeToAndFlush(socket.getOutputStream());
- if (traceLevel >= handshakeThreshold) {
- System.out.println("-> " + "HANDSHAKE sendStatus" + " status="
- + status + " local=" + localNode);
- }
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("-> " + "HANDSHAKE sendStatus" + " status="
+ + status + " local=" + localNode);
+ }
}
protected void recvStatus() throws IOException {
- try {
- final byte[] buf = read2BytePackage();
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(buf, 0);
- final int tag = ibuf.read1();
- if (tag != ChallengeStatus) {
- throw new IOException("Handshake protocol error");
- }
- final byte[] tmpbuf = new byte[buf.length - 1];
- ibuf.readN(tmpbuf);
- final String status = OtpErlangString.newString(tmpbuf);
-
- if (status.compareTo("ok") != 0) {
- throw new IOException("Peer replied with status '" + status
- + "' instead of 'ok'");
- }
- } catch (final OtpErlangDecodeException e) {
- throw new IOException("Handshake failed - not enough data");
- }
- if (traceLevel >= handshakeThreshold) {
- System.out.println("<- " + "HANDSHAKE recvStatus (ok)" + " local="
- + localNode);
- }
+ try {
+ final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(buf, 0);
+ final int tag = ibuf.read1();
+ if (tag != ChallengeStatus) {
+ throw new IOException("Handshake protocol error");
+ }
+ final byte[] tmpbuf = new byte[buf.length - 1];
+ ibuf.readN(tmpbuf);
+ final String status = OtpErlangString.newString(tmpbuf);
+
+ if (status.compareTo("ok") != 0) {
+ throw new IOException("Peer replied with status '" + status
+ + "' instead of 'ok'");
+ }
+ } catch (final OtpErlangDecodeException e) {
+ throw new IOException("Handshake failed - not enough data");
+ }
+ if (traceLevel >= handshakeThreshold) {
+ System.out.println("<- " + "HANDSHAKE recvStatus (ok)" + " local="
+ + localNode);
+ }
}
public void setFlags(final int flags) {
- this.flags = flags;
+ this.flags = flags;
}
public int getFlags() {
- return flags;
+ return flags;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
index 3bb1bbbd18..d7ba88288f 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
@@ -1,20 +1,21 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2014. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -29,7 +30,7 @@ import java.net.UnknownHostException;
* <p>
* Represents an OTP node.
* </p>
- *
+ *
* <p>
* About nodenames: Erlang nodenames consist of two components, an alivename and
* a hostname separated by '@'. Additionally, there are two nodename formats:
@@ -40,7 +41,7 @@ import java.net.UnknownHostException;
* however Jinterface makes no distinction. See the Erlang documentation for
* more information about nodenames.
* </p>
- *
+ *
* <p>
* The constructors for the AbstractNode classes will create names exactly as
* you provide them as long as the name contains '@'. If the string you provide
@@ -48,7 +49,7 @@ import java.net.UnknownHostException;
* host will be appended, resulting in a shortname. Nodenames longer than 255
* characters will be truncated without warning.
* </p>
- *
+ *
* <p>
* Upon initialization, this class attempts to read the file .erlang.cookie in
* the user's home directory, and uses the trimmed first line of the file as the
@@ -58,19 +59,20 @@ import java.net.UnknownHostException;
* using the system property "user.home", which may not be automatically set on
* all platforms.
* </p>
- *
+ *
* <p>
* Instances of this class cannot be created directly, use one of the subclasses
* instead.
* </p>
*/
-public class AbstractNode {
+public class AbstractNode implements OtpTransportFactory {
static String localHost = null;
String node;
String host;
String alive;
String cookie;
static String defaultCookie = null;
+ final OtpTransportFactory transportFactory;
// Node types
static final int NTYPE_R6 = 110; // 'n' post-r5, all nodes
@@ -100,172 +102,207 @@ public class AbstractNode {
int distLow = 5; // Cannot talk to nodes before R6
int creation = 0;
int flags = dFlagExtendedReferences | dFlagExtendedPidsPorts
- | dFlagBitBinaries | dFlagNewFloats | dFlagFunTags
- | dflagNewFunTags | dFlagUtf8Atoms | dFlagMapTag;
+ | dFlagBitBinaries | dFlagNewFloats | dFlagFunTags
+ | dflagNewFunTags | dFlagUtf8Atoms | dFlagMapTag;
/* initialize hostname and default cookie */
static {
- try {
- localHost = InetAddress.getLocalHost().getHostName();
- /*
- * Make sure it's a short name, i.e. strip of everything after first
- * '.'
- */
- final int dot = localHost.indexOf(".");
- if (dot != -1) {
- localHost = localHost.substring(0, dot);
- }
- } catch (final UnknownHostException e) {
- localHost = "localhost";
- }
-
- final String homeDir = getHomeDir();
- final String dotCookieFilename = homeDir + File.separator
+ try {
+ localHost = InetAddress.getLocalHost().getHostName();
+ /*
+ * Make sure it's a short name, i.e. strip of everything after first
+ * '.'
+ */
+ final int dot = localHost.indexOf(".");
+ if (dot != -1) {
+ localHost = localHost.substring(0, dot);
+ }
+ } catch (final UnknownHostException e) {
+ localHost = "localhost";
+ }
+
+ final String homeDir = getHomeDir();
+ final String dotCookieFilename = homeDir + File.separator
+ ".erlang.cookie";
- BufferedReader br = null;
-
- try {
- final File dotCookieFile = new File(dotCookieFilename);
-
- br = new BufferedReader(new FileReader(dotCookieFile));
- final String line = br.readLine();
- if (line == null) {
- defaultCookie = "";
- } else {
- defaultCookie = line.trim();
- }
- } catch (final IOException e) {
- defaultCookie = "";
- } finally {
- try {
- if (br != null) {
- br.close();
- }
- } catch (final IOException e) {
- }
- }
+ BufferedReader br = null;
+
+ try {
+ final File dotCookieFile = new File(dotCookieFilename);
+
+ br = new BufferedReader(new FileReader(dotCookieFile));
+ final String line = br.readLine();
+ if (line == null) {
+ defaultCookie = "";
+ } else {
+ defaultCookie = line.trim();
+ }
+ } catch (final IOException e) {
+ defaultCookie = "";
+ } finally {
+ try {
+ if (br != null) {
+ br.close();
+ }
+ } catch (final IOException e) {
+ }
+ }
}
- protected AbstractNode() {
+ protected AbstractNode(final OtpTransportFactory transportFactory) {
+ this.transportFactory = transportFactory;
}
/**
- * Create a node with the given name and the default cookie.
+ * Create a node with the given name and default cookie and transport
+ * factory.
*/
protected AbstractNode(final String node) {
- this(node, defaultCookie);
+ this(node, defaultCookie, new OtpSocketTransportFactory());
+ }
+
+ /**
+ * Create a node with the given name, transport factory and the default
+ * cookie.
+ */
+ protected AbstractNode(final String node,
+ final OtpTransportFactory transportFactory) {
+ this(node, defaultCookie, transportFactory);
}
/**
- * Create a node with the given name and cookie.
+ * Create a node with the given name, cookie and default transport factory.
*/
protected AbstractNode(final String name, final String cookie) {
- this.cookie = cookie;
-
- final int i = name.indexOf('@', 0);
- if (i < 0) {
- alive = name;
- host = localHost;
- } else {
- alive = name.substring(0, i);
- host = name.substring(i + 1, name.length());
- }
-
- if (alive.length() > 0xff) {
- alive = alive.substring(0, 0xff);
- }
-
- node = alive + "@" + host;
+ this(name, cookie, new OtpSocketTransportFactory());
+ }
+
+ /**
+ * Create a node with the given name, cookie and transport factory.
+ */
+ protected AbstractNode(final String name, final String cookie,
+ final OtpTransportFactory transportFactory) {
+ this.cookie = cookie;
+ this.transportFactory = transportFactory;
+
+ final int i = name.indexOf('@', 0);
+ if (i < 0) {
+ alive = name;
+ host = localHost;
+ } else {
+ alive = name.substring(0, i);
+ host = name.substring(i + 1, name.length());
+ }
+
+ if (alive.length() > 0xff) {
+ alive = alive.substring(0, 0xff);
+ }
+
+ node = alive + "@" + host;
}
/**
* Get the name of this node.
- *
+ *
* @return the name of the node represented by this object.
*/
public String node() {
- return node;
+ return node;
}
/**
* Get the hostname part of the nodename. Nodenames are composed of two
* parts, an alivename and a hostname, separated by '@'. This method returns
* the part of the nodename following the '@'.
- *
+ *
* @return the hostname component of the nodename.
*/
public String host() {
- return host;
+ return host;
}
/**
* Get the alivename part of the hostname. Nodenames are composed of two
* parts, an alivename and a hostname, separated by '@'. This method returns
* the part of the nodename preceding the '@'.
- *
+ *
* @return the alivename component of the nodename.
*/
public String alive() {
- return alive;
+ return alive;
}
/**
* Get the authorization cookie used by this node.
- *
+ *
* @return the authorization cookie used by this node.
*/
public String cookie() {
- return cookie;
+ return cookie;
}
// package scope
int type() {
- return ntype;
+ return ntype;
}
// package scope
int distHigh() {
- return distHigh;
+ return distHigh;
}
// package scope
int distLow() {
- return distLow;
+ return distLow;
}
// package scope: useless information?
int proto() {
- return proto;
+ return proto;
}
// package scope
int creation() {
- return creation;
+ return creation;
}
/**
* Set the authorization cookie used by this node.
- *
+ *
* @return the previous authorization cookie used by this node.
*/
public String setCookie(final String cookie) {
- final String prev = this.cookie;
- this.cookie = cookie;
- return prev;
+ final String prev = this.cookie;
+ this.cookie = cookie;
+ return prev;
}
@Override
public String toString() {
- return node();
+ return node();
}
private static String getHomeDir() {
- final String home = System.getProperty("user.home");
- if (System.getProperty("os.name").toLowerCase().contains("windows")) {
- final String drive = System.getenv("HOMEDRIVE");
- final String path = System.getenv("HOMEPATH");
- return (drive != null && path != null) ? drive + path : home;
- }
- return home;
+ final String home = System.getProperty("user.home");
+ if (System.getProperty("os.name").toLowerCase().contains("windows")) {
+ final String drive = System.getenv("HOMEDRIVE");
+ final String path = System.getenv("HOMEPATH");
+ return drive != null && path != null ? drive + path : home;
+ }
+ return home;
+ }
+
+ public OtpTransport createTransport(final String addr, final int port)
+ throws IOException {
+ return transportFactory.createTransport(addr, port);
+ }
+
+ public OtpTransport createTransport(final InetAddress addr, final int port)
+ throws IOException {
+ return transportFactory.createTransport(addr, port);
+ }
+
+ public OtpServerTransport createServerTransport(final int port)
+ throws IOException {
+ return transportFactory.createServerTransport(port);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/GenericQueue.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/GenericQueue.java
index 80bb02f16c..193df527d5 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/GenericQueue.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/GenericQueue.java
@@ -1,19 +1,20 @@
-/*
+/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -34,128 +35,128 @@ public class GenericQueue {
private int count;
private void init() {
- head = null;
- tail = null;
- count = 0;
+ head = null;
+ tail = null;
+ count = 0;
}
/** Create an empty queue */
public GenericQueue() {
- init();
- status = open;
+ init();
+ status = open;
}
/** Clear a queue */
public void flush() {
- init();
+ init();
}
public void close() {
- status = closing;
+ status = closing;
}
/**
* Add an object to the tail of the queue.
- *
+ *
* @param o
- * Object to insert in the queue
+ * Object to insert in the queue
*/
public synchronized void put(final Object o) {
- final Bucket b = new Bucket(o);
-
- if (tail != null) {
- tail.setNext(b);
- tail = b;
- } else {
- // queue was empty but has one element now
- head = tail = b;
- }
- count++;
-
- // notify any waiting tasks
- notify();
+ final Bucket b = new Bucket(o);
+
+ if (tail != null) {
+ tail.setNext(b);
+ tail = b;
+ } else {
+ // queue was empty but has one element now
+ head = tail = b;
+ }
+ count++;
+
+ // notify any waiting tasks
+ notify();
}
/**
* Retrieve an object from the head of the queue, or block until one
* arrives.
- *
+ *
* @return The object at the head of the queue.
*/
public synchronized Object get() {
- Object o = null;
-
- while ((o = tryGet()) == null) {
- try {
- this.wait();
- } catch (final InterruptedException e) {
- }
- }
- return o;
+ Object o = null;
+
+ while ((o = tryGet()) == null) {
+ try {
+ this.wait();
+ } catch (final InterruptedException e) {
+ }
+ }
+ return o;
}
/**
* Retrieve an object from the head of the queue, blocking until one arrives
* or until timeout occurs.
- *
+ *
* @param timeout
- * Maximum time to block on queue, in ms. Use 0 to poll the
- * queue.
- *
+ * Maximum time to block on queue, in ms. Use 0 to poll the
+ * queue.
+ *
* @exception InterruptedException
- * if the operation times out.
- *
+ * if the operation times out.
+ *
* @return The object at the head of the queue, or null if none arrived in
* time.
*/
public synchronized Object get(final long timeout)
- throws InterruptedException {
- if (status == closed) {
- return null;
- }
-
- long currentTime = System.currentTimeMillis();
- final long stopTime = currentTime + timeout;
- Object o = null;
-
- while (true) {
- if ((o = tryGet()) != null) {
- return o;
- }
-
- currentTime = System.currentTimeMillis();
- if (stopTime <= currentTime) {
- throw new InterruptedException("Get operation timed out");
- }
-
- try {
- this.wait(stopTime - currentTime);
- } catch (final InterruptedException e) {
- // ignore, but really should retry operation instead
- }
- }
+ throws InterruptedException {
+ if (status == closed) {
+ return null;
+ }
+
+ long currentTime = System.currentTimeMillis();
+ final long stopTime = currentTime + timeout;
+ Object o = null;
+
+ while (true) {
+ if ((o = tryGet()) != null) {
+ return o;
+ }
+
+ currentTime = System.currentTimeMillis();
+ if (stopTime <= currentTime) {
+ throw new InterruptedException("Get operation timed out");
+ }
+
+ try {
+ this.wait(stopTime - currentTime);
+ } catch (final InterruptedException e) {
+ // ignore, but really should retry operation instead
+ }
+ }
}
// attempt to retrieve message from queue head
public Object tryGet() {
- Object o = null;
+ Object o = null;
- if (head != null) {
- o = head.getContents();
- head = head.getNext();
- count--;
+ if (head != null) {
+ o = head.getContents();
+ head = head.getNext();
+ count--;
- if (head == null) {
- tail = null;
- count = 0;
- }
- }
+ if (head == null) {
+ tail = null;
+ count = 0;
+ }
+ }
- return o;
+ return o;
}
public synchronized int getCount() {
- return count;
+ return count;
}
/*
@@ -163,24 +164,24 @@ public class GenericQueue {
* The container holds the queued object and a reference to the next Bucket.
*/
class Bucket {
- private Bucket next;
- private final Object contents;
+ private Bucket next;
+ private final Object contents;
- public Bucket(final Object o) {
- next = null;
- contents = o;
- }
+ public Bucket(final Object o) {
+ next = null;
+ contents = o;
+ }
- public void setNext(final Bucket newNext) {
- next = newNext;
- }
+ public void setNext(final Bucket newNext) {
+ next = newNext;
+ }
- public Bucket getNext() {
- return next;
- }
+ public Bucket getNext() {
+ return next;
+ }
- public Object getContents() {
- return contents;
- }
+ public Object getContents() {
+ return contents;
+ }
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java
index c8b4fcebde..a5ac2bb663 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -25,34 +26,34 @@ class Link {
private int hashCodeValue = 0;
public Link(final OtpErlangPid local, final OtpErlangPid remote) {
- this.local = local;
- this.remote = remote;
+ this.local = local;
+ this.remote = remote;
}
public OtpErlangPid local() {
- return local;
+ return local;
}
public OtpErlangPid remote() {
- return remote;
+ return remote;
}
public boolean contains(final OtpErlangPid pid) {
- return local.equals(pid) || remote.equals(pid);
+ return local.equals(pid) || remote.equals(pid);
}
public boolean equals(final OtpErlangPid alocal, final OtpErlangPid aremote) {
- return local.equals(alocal) && remote.equals(aremote)
- || local.equals(aremote) && remote.equals(alocal);
+ return local.equals(alocal) && remote.equals(aremote)
+ || local.equals(aremote) && remote.equals(alocal);
}
-
+
@Override
public int hashCode() {
- if (hashCodeValue == 0) {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(5);
- hash.combine(local.hashCode() + remote.hashCode());
- hashCodeValue = hash.valueOf();
- }
- return hashCodeValue;
+ if (hashCodeValue == 0) {
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(5);
+ hash.combine(local.hashCode() + remote.hashCode());
+ hashCodeValue = hash.valueOf();
+ }
+ return hashCodeValue;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Links.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/Links.java
index 0bb4a708a3..3117b11149 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Links.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Links.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -24,100 +25,100 @@ class Links {
int count;
Links() {
- this(10);
+ this(10);
}
Links(final int initialSize) {
- links = new Link[initialSize];
- count = 0;
+ links = new Link[initialSize];
+ count = 0;
}
synchronized void addLink(final OtpErlangPid local,
- final OtpErlangPid remote) {
- if (find(local, remote) == -1) {
- if (count >= links.length) {
- final Link[] tmp = new Link[count * 2];
- System.arraycopy(links, 0, tmp, 0, count);
- links = tmp;
- }
- links[count++] = new Link(local, remote);
- }
+ final OtpErlangPid remote) {
+ if (find(local, remote) == -1) {
+ if (count >= links.length) {
+ final Link[] tmp = new Link[count * 2];
+ System.arraycopy(links, 0, tmp, 0, count);
+ links = tmp;
+ }
+ links[count++] = new Link(local, remote);
+ }
}
synchronized void removeLink(final OtpErlangPid local,
- final OtpErlangPid remote) {
- int i;
+ final OtpErlangPid remote) {
+ int i;
- if ((i = find(local, remote)) != -1) {
- count--;
- links[i] = links[count];
- links[count] = null;
- }
+ if ((i = find(local, remote)) != -1) {
+ count--;
+ links[i] = links[count];
+ links[count] = null;
+ }
}
synchronized boolean exists(final OtpErlangPid local,
- final OtpErlangPid remote) {
- return find(local, remote) != -1;
+ final OtpErlangPid remote) {
+ return find(local, remote) != -1;
}
synchronized int find(final OtpErlangPid local, final OtpErlangPid remote) {
- for (int i = 0; i < count; i++) {
- if (links[i].equals(local, remote)) {
- return i;
- }
- }
- return -1;
+ for (int i = 0; i < count; i++) {
+ if (links[i].equals(local, remote)) {
+ return i;
+ }
+ }
+ return -1;
}
int count() {
- return count;
+ return count;
}
/* all local pids get notified about broken connection */
synchronized OtpErlangPid[] localPids() {
- OtpErlangPid[] ret = null;
- if (count != 0) {
- ret = new OtpErlangPid[count];
- for (int i = 0; i < count; i++) {
- ret[i] = links[i].local();
- }
- }
- return ret;
+ OtpErlangPid[] ret = null;
+ if (count != 0) {
+ ret = new OtpErlangPid[count];
+ for (int i = 0; i < count; i++) {
+ ret[i] = links[i].local();
+ }
+ }
+ return ret;
}
/* all remote pids get notified about failed pid */
synchronized OtpErlangPid[] remotePids() {
- OtpErlangPid[] ret = null;
- if (count != 0) {
- ret = new OtpErlangPid[count];
- for (int i = 0; i < count; i++) {
- ret[i] = links[i].remote();
- }
- }
- return ret;
+ OtpErlangPid[] ret = null;
+ if (count != 0) {
+ ret = new OtpErlangPid[count];
+ for (int i = 0; i < count; i++) {
+ ret[i] = links[i].remote();
+ }
+ }
+ return ret;
}
/* clears the link table, returns a copy */
synchronized Link[] clearLinks() {
- Link[] ret = null;
- if (count != 0) {
- ret = new Link[count];
- for (int i = 0; i < count; i++) {
- ret[i] = links[i];
- links[i] = null;
- }
- count = 0;
- }
- return ret;
+ Link[] ret = null;
+ if (count != 0) {
+ ret = new Link[count];
+ for (int i = 0; i < count; i++) {
+ ret[i] = links[i];
+ links[i] = null;
+ }
+ count = 0;
+ }
+ return ret;
}
/* returns a copy of the link table */
synchronized Link[] links() {
- Link[] ret = null;
- if (count != 0) {
- ret = new Link[count];
- System.arraycopy(links, 0, ret, 0, count);
- }
- return ret;
+ Link[] ret = null;
+ if (count != 0) {
+ ret = new Link[count];
+ System.arraycopy(links, 0, ret, 0, count);
+ }
+ return ret;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
index ea3ab770ce..1c8364e951 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpAuthException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpAuthException.java
index 39d254d9fa..d0fdd9569e 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpAuthException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpAuthException.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -22,7 +23,7 @@ package com.ericsson.otp.erlang;
* Exception raised when a node attempts to establish a communication channel
* when it is not authorized to do so, or when a node sends a message containing
* an invalid cookie on an established channel.
- *
+ *
* @see OtpConnection
*/
public class OtpAuthException extends OtpException {
@@ -32,6 +33,6 @@ public class OtpAuthException extends OtpException {
* Provides a detailed message.
*/
public OtpAuthException(final String s) {
- super(s);
+ super(s);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
index 9ad02506fd..1a4627c62b 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
@@ -1,46 +1,46 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
import java.io.IOException;
-import java.net.Socket;
/**
* Maintains a connection between a Java process and a remote Erlang, Java or C
* node. The object maintains connection state and allows data to be sent to and
* received from the peer.
- *
+ *
* <p>
* Once a connection is established between the local node and a remote node,
* the connection object can be used to send and receive messages between the
* nodes and make rpc calls (assuming that the remote node is a real Erlang
* node).
- *
+ *
* <p>
* The various receive methods are all blocking and will return only when a
* valid message has been received or an exception is raised.
- *
+ *
* <p>
* If an exception occurs in any of the methods in this class, the connection
* will be closed and must be explicitely reopened in order to resume
* communication with the peer.
- *
+ *
* <p>
* It is not possible to create an instance of this class directly.
* OtpConnection objects are returned by {@link OtpSelf#connect(OtpPeer)
@@ -55,66 +55,66 @@ public class OtpConnection extends AbstractConnection {
* OtpSelf#accept() OtpSelf.accept()} to create a connection based on data
* received when handshaking with the peer node, when the remote node is the
* connection intitiator.
- *
+ *
* @exception java.io.IOException if it was not possible to connect to the
* peer.
- *
+ *
* @exception OtpAuthException if handshake resulted in an authentication
* error
*/
// package scope
- OtpConnection(final OtpSelf self, final Socket s) throws IOException,
- OtpAuthException {
- super(self, s);
- this.self = self;
- queue = new GenericQueue();
- start();
+ OtpConnection(final OtpSelf self, final OtpTransport s)
+ throws IOException, OtpAuthException {
+ super(self, s);
+ this.self = self;
+ queue = new GenericQueue();
+ start();
}
/*
* Intiate and open a connection to a remote node.
- *
+ *
* @exception java.io.IOException if it was not possible to connect to the
* peer.
- *
+ *
* @exception OtpAuthException if handshake resulted in an authentication
* error.
*/
// package scope
OtpConnection(final OtpSelf self, final OtpPeer other) throws IOException,
- OtpAuthException {
- super(self, other);
- this.self = self;
- queue = new GenericQueue();
- start();
+ OtpAuthException {
+ super(self, other);
+ this.self = self;
+ queue = new GenericQueue();
+ start();
}
@Override
public void deliver(final Exception e) {
- queue.put(e);
+ queue.put(e);
}
@Override
public void deliver(final OtpMsg msg) {
- queue.put(msg);
+ queue.put(msg);
}
/**
* Get information about the node at the peer end of this connection.
- *
+ *
* @return the {@link OtpPeer Node} representing the peer node.
*/
public OtpPeer peer() {
- return peer;
+ return peer;
}
/**
* Get information about the node at the local end of this connection.
- *
+ *
* @return the {@link OtpSelf Node} representing the local node.
*/
public OtpSelf self() {
- return self;
+ return self;
}
/**
@@ -122,416 +122,412 @@ public class OtpConnection extends AbstractConnection {
* this connection.
*/
public int msgCount() {
- return queue.getCount();
+ return queue.getCount();
}
/**
* Receive a message from a remote process. This method blocks until a valid
* message is received or an exception is raised.
- *
+ *
* <p>
* If the remote node sends a message that cannot be decoded properly, the
* connection is closed and the method throws an exception.
- *
+ *
* @return an object containing a single Erlang term.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node.
- *
+ * if an exit signal is received from a process on the peer
+ * node.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
+ * if the remote node sends a message containing an invalid
+ * cookie.
*/
public OtpErlangObject receive() throws IOException, OtpErlangExit,
- OtpAuthException {
- try {
- return receiveMsg().getMsg();
- } catch (final OtpErlangDecodeException e) {
- close();
- throw new IOException(e.getMessage());
- }
+ OtpAuthException {
+ try {
+ return receiveMsg().getMsg();
+ } catch (final OtpErlangDecodeException e) {
+ close();
+ throw new IOException(e.getMessage());
+ }
}
/**
* Receive a message from a remote process. This method blocks at most for
* the specified time, until a valid message is received or an exception is
* raised.
- *
+ *
* <p>
* If the remote node sends a message that cannot be decoded properly, the
* connection is closed and the method throws an exception.
- *
+ *
* @param timeout
- * the time in milliseconds that this operation will block.
- * Specify 0 to poll the queue.
- *
+ * the time in milliseconds that this operation will block.
+ * Specify 0 to poll the queue.
+ *
* @return an object containing a single Erlang term.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node.
- *
+ * if an exit signal is received from a process on the peer
+ * node.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
- *
+ * if the remote node sends a message containing an invalid
+ * cookie.
+ *
* @exception InterruptedException
- * if no message if the method times out before a message
- * becomes available.
+ * if no message if the method times out before a message
+ * becomes available.
*/
public OtpErlangObject receive(final long timeout)
- throws InterruptedException, IOException, OtpErlangExit,
- OtpAuthException {
- try {
- return receiveMsg(timeout).getMsg();
- } catch (final OtpErlangDecodeException e) {
- close();
- throw new IOException(e.getMessage());
- }
+ throws InterruptedException, IOException, OtpErlangExit,
+ OtpAuthException {
+ try {
+ return receiveMsg(timeout).getMsg();
+ } catch (final OtpErlangDecodeException e) {
+ close();
+ throw new IOException(e.getMessage());
+ }
}
/**
* Receive a raw (still encoded) message from a remote process. This message
* blocks until a valid message is received or an exception is raised.
- *
+ *
* <p>
* If the remote node sends a message that cannot be decoded properly, the
* connection is closed and the method throws an exception.
- *
+ *
* @return an object containing a raw (still encoded) Erlang term.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node, or if the connection is lost for any
- * reason.
- *
+ * if an exit signal is received from a process on the peer
+ * node, or if the connection is lost for any reason.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
+ * if the remote node sends a message containing an invalid
+ * cookie.
*/
public OtpInputStream receiveBuf() throws IOException, OtpErlangExit,
- OtpAuthException {
- return receiveMsg().getMsgBuf();
+ OtpAuthException {
+ return receiveMsg().getMsgBuf();
}
/**
* Receive a raw (still encoded) message from a remote process. This message
* blocks at most for the specified time until a valid message is received
* or an exception is raised.
- *
+ *
* <p>
* If the remote node sends a message that cannot be decoded properly, the
* connection is closed and the method throws an exception.
- *
+ *
* @param timeout
- * the time in milliseconds that this operation will block.
- * Specify 0 to poll the queue.
- *
+ * the time in milliseconds that this operation will block.
+ * Specify 0 to poll the queue.
+ *
* @return an object containing a raw (still encoded) Erlang term.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node, or if the connection is lost for any
- * reason.
- *
+ * if an exit signal is received from a process on the peer
+ * node, or if the connection is lost for any reason.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
- *
+ * if the remote node sends a message containing an invalid
+ * cookie.
+ *
* @exception InterruptedException
- * if no message if the method times out before a message
- * becomes available.
+ * if no message if the method times out before a message
+ * becomes available.
*/
public OtpInputStream receiveBuf(final long timeout)
- throws InterruptedException, IOException, OtpErlangExit,
- OtpAuthException {
- return receiveMsg(timeout).getMsgBuf();
+ throws InterruptedException, IOException, OtpErlangExit,
+ OtpAuthException {
+ return receiveMsg(timeout).getMsgBuf();
}
/**
* Receive a messge complete with sender and recipient information.
- *
+ *
* @return an {@link OtpMsg OtpMsg} containing the header information about
* the sender and recipient, as well as the actual message contents.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node, or if the connection is lost for any
- * reason.
- *
+ * if an exit signal is received from a process on the peer
+ * node, or if the connection is lost for any reason.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
+ * if the remote node sends a message containing an invalid
+ * cookie.
*/
public OtpMsg receiveMsg() throws IOException, OtpErlangExit,
- OtpAuthException {
- final Object o = queue.get();
-
- if (o instanceof OtpMsg) {
- return (OtpMsg) o;
- } else if (o instanceof IOException) {
- throw (IOException) o;
- } else if (o instanceof OtpErlangExit) {
- throw (OtpErlangExit) o;
- } else if (o instanceof OtpAuthException) {
- throw (OtpAuthException) o;
- }
-
- return null;
+ OtpAuthException {
+ final Object o = queue.get();
+
+ if (o instanceof OtpMsg) {
+ return (OtpMsg) o;
+ } else if (o instanceof IOException) {
+ throw (IOException) o;
+ } else if (o instanceof OtpErlangExit) {
+ throw (OtpErlangExit) o;
+ } else if (o instanceof OtpAuthException) {
+ throw (OtpAuthException) o;
+ }
+
+ return null;
}
/**
* Receive a messge complete with sender and recipient information. This
* method blocks at most for the specified time.
- *
+ *
* @param timeout
- * the time in milliseconds that this operation will block.
- * Specify 0 to poll the queue.
- *
+ * the time in milliseconds that this operation will block.
+ * Specify 0 to poll the queue.
+ *
* @return an {@link OtpMsg OtpMsg} containing the header information about
* the sender and recipient, as well as the actual message contents.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node, or if the connection is lost for any
- * reason.
- *
+ * if an exit signal is received from a process on the peer
+ * node, or if the connection is lost for any reason.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
- *
+ * if the remote node sends a message containing an invalid
+ * cookie.
+ *
* @exception InterruptedException
- * if no message if the method times out before a message
- * becomes available.
+ * if no message if the method times out before a message
+ * becomes available.
*/
public OtpMsg receiveMsg(final long timeout) throws InterruptedException,
- IOException, OtpErlangExit, OtpAuthException {
- final Object o = queue.get(timeout);
-
- if (o instanceof OtpMsg) {
- return (OtpMsg) o;
- } else if (o instanceof IOException) {
- throw (IOException) o;
- } else if (o instanceof OtpErlangExit) {
- throw (OtpErlangExit) o;
- } else if (o instanceof OtpAuthException) {
- throw (OtpAuthException) o;
- }
-
- return null;
+ IOException, OtpErlangExit, OtpAuthException {
+ final Object o = queue.get(timeout);
+
+ if (o instanceof OtpMsg) {
+ return (OtpMsg) o;
+ } else if (o instanceof IOException) {
+ throw (IOException) o;
+ } else if (o instanceof OtpErlangExit) {
+ throw (OtpErlangExit) o;
+ } else if (o instanceof OtpAuthException) {
+ throw (OtpAuthException) o;
+ }
+
+ return null;
}
/**
* Send a message to a process on a remote node.
- *
+ *
* @param dest
- * the Erlang PID of the remote process.
+ * the Erlang PID of the remote process.
* @param msg
- * the message to send.
- *
+ * the message to send.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
@SuppressWarnings("resource")
public void send(final OtpErlangPid dest, final OtpErlangObject msg)
- throws IOException {
- // encode and send the message
- super.sendBuf(self.pid(), dest, new OtpOutputStream(msg));
+ throws IOException {
+ // encode and send the message
+ super.sendBuf(self.pid(), dest, new OtpOutputStream(msg));
}
/**
* Send a message to a named process on a remote node.
- *
+ *
* @param dest
- * the name of the remote process.
+ * the name of the remote process.
* @param msg
- * the message to send.
- *
+ * the message to send.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
@SuppressWarnings("resource")
public void send(final String dest, final OtpErlangObject msg)
- throws IOException {
- // encode and send the message
- super.sendBuf(self.pid(), dest, new OtpOutputStream(msg));
+ throws IOException {
+ // encode and send the message
+ super.sendBuf(self.pid(), dest, new OtpOutputStream(msg));
}
/**
* Send a pre-encoded message to a named process on a remote node.
- *
+ *
* @param dest
- * the name of the remote process.
+ * the name of the remote process.
* @param payload
- * the encoded message to send.
- *
+ * the encoded message to send.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void sendBuf(final String dest, final OtpOutputStream payload)
- throws IOException {
- super.sendBuf(self.pid(), dest, payload);
+ throws IOException {
+ super.sendBuf(self.pid(), dest, payload);
}
/**
* Send a pre-encoded message to a process on a remote node.
- *
+ *
* @param dest
- * the Erlang PID of the remote process.
+ * the Erlang PID of the remote process.
* @param payload
- * the encoded message to send.
- *
+ * the encoded message to send.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void sendBuf(final OtpErlangPid dest, final OtpOutputStream payload)
- throws IOException {
- super.sendBuf(self.pid(), dest, payload);
+ throws IOException {
+ super.sendBuf(self.pid(), dest, payload);
}
/**
* Send an RPC request to the remote Erlang node. This convenience function
* creates the following message and sends it to 'rex' on the remote node:
- *
+ *
* <pre>
* { self, { call, Mod, Fun, Args, user } }
* </pre>
- *
+ *
* <p>
* Note that this method has unpredicatble results if the remote node is not
* an Erlang node.
* </p>
- *
+ *
* @param mod
- * the name of the Erlang module containing the function to
- * be called.
+ * the name of the Erlang module containing the function to be
+ * called.
* @param fun
- * the name of the function to call.
+ * the name of the function to call.
* @param args
- * an array of Erlang terms, to be used as arguments to the
- * function.
- *
+ * an array of Erlang terms, to be used as arguments to the
+ * function.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void sendRPC(final String mod, final String fun,
- final OtpErlangObject[] args) throws IOException {
- sendRPC(mod, fun, new OtpErlangList(args));
+ final OtpErlangObject[] args) throws IOException {
+ sendRPC(mod, fun, new OtpErlangList(args));
}
/**
* Send an RPC request to the remote Erlang node. This convenience function
* creates the following message and sends it to 'rex' on the remote node:
- *
+ *
* <pre>
* { self, { call, Mod, Fun, Args, user } }
* </pre>
- *
+ *
* <p>
* Note that this method has unpredicatble results if the remote node is not
* an Erlang node.
* </p>
- *
+ *
* @param mod
- * the name of the Erlang module containing the function to
- * be called.
+ * the name of the Erlang module containing the function to be
+ * called.
* @param fun
- * the name of the function to call.
+ * the name of the function to call.
* @param args
- * a list of Erlang terms, to be used as arguments to the
- * function.
- *
+ * a list of Erlang terms, to be used as arguments to the
+ * function.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void sendRPC(final String mod, final String fun,
- final OtpErlangList args) throws IOException {
- final OtpErlangObject[] rpc = new OtpErlangObject[2];
- final OtpErlangObject[] call = new OtpErlangObject[5];
+ final OtpErlangList args) throws IOException {
+ final OtpErlangObject[] rpc = new OtpErlangObject[2];
+ final OtpErlangObject[] call = new OtpErlangObject[5];
- /* {self, { call, Mod, Fun, Args, user}} */
+ /* {self, { call, Mod, Fun, Args, user}} */
- call[0] = new OtpErlangAtom("call");
- call[1] = new OtpErlangAtom(mod);
- call[2] = new OtpErlangAtom(fun);
- call[3] = args;
- call[4] = new OtpErlangAtom("user");
+ call[0] = new OtpErlangAtom("call");
+ call[1] = new OtpErlangAtom(mod);
+ call[2] = new OtpErlangAtom(fun);
+ call[3] = args;
+ call[4] = new OtpErlangAtom("user");
- rpc[0] = self.pid();
- rpc[1] = new OtpErlangTuple(call);
+ rpc[0] = self.pid();
+ rpc[1] = new OtpErlangTuple(call);
- send("rex", new OtpErlangTuple(rpc));
+ send("rex", new OtpErlangTuple(rpc));
}
/**
* Receive an RPC reply from the remote Erlang node. This convenience
* function receives a message from the remote node, and expects it to have
* the following format:
- *
+ *
* <pre>
* { rex, Term }
* </pre>
- *
+ *
* @return the second element of the tuple if the received message is a
* two-tuple, otherwise null. No further error checking is
* performed.
- *
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
- *
+ * if the connection is not active or a communication error
+ * occurs.
+ *
* @exception OtpErlangExit
- * if an exit signal is received from a process on the
- * peer node.
- *
+ * if an exit signal is received from a process on the peer
+ * node.
+ *
* @exception OtpAuthException
- * if the remote node sends a message containing an
- * invalid cookie.
+ * if the remote node sends a message containing an invalid
+ * cookie.
*/
public OtpErlangObject receiveRPC() throws IOException, OtpErlangExit,
- OtpAuthException {
+ OtpAuthException {
- final OtpErlangObject msg = receive();
+ final OtpErlangObject msg = receive();
- if (msg instanceof OtpErlangTuple) {
- final OtpErlangTuple t = (OtpErlangTuple) msg;
- if (t.arity() == 2) {
- return t.elementAt(1); // obs: second element
- }
- }
+ if (msg instanceof OtpErlangTuple) {
+ final OtpErlangTuple t = (OtpErlangTuple) msg;
+ if (t.arity() == 2) {
+ return t.elementAt(1); // obs: second element
+ }
+ }
- return null;
+ return null;
}
/**
@@ -539,48 +535,48 @@ public class OtpConnection extends AbstractConnection {
* remote node. If the link is still active when the remote process
* terminates, an exit signal will be sent to this connection. Use
* {@link #unlink unlink()} to remove the link.
- *
+ *
* @param dest
- * the Erlang PID of the remote process.
- *
+ * the Erlang PID of the remote process.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void link(final OtpErlangPid dest) throws IOException {
- super.sendLink(self.pid(), dest);
+ super.sendLink(self.pid(), dest);
}
/**
* Remove a link between the local node and the specified process on the
- * remote node. This method deactivates links created with
- * {@link #link link()}.
- *
+ * remote node. This method deactivates links created with {@link #link
+ * link()}.
+ *
* @param dest
- * the Erlang PID of the remote process.
- *
+ * the Erlang PID of the remote process.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void unlink(final OtpErlangPid dest) throws IOException {
- super.sendUnlink(self.pid(), dest);
+ super.sendUnlink(self.pid(), dest);
}
/**
* Send an exit signal to a remote process.
- *
+ *
* @param dest
- * the Erlang PID of the remote process.
+ * the Erlang PID of the remote process.
* @param reason
- * an Erlang term describing the exit reason.
- *
+ * an Erlang term describing the exit reason.
+ *
* @exception java.io.IOException
- * if the connection is not active or a communication
- * error occurs.
+ * if the connection is not active or a communication error
+ * occurs.
*/
public void exit(final OtpErlangPid dest, final OtpErlangObject reason)
- throws IOException {
- super.sendExit2(self.pid(), dest, reason);
+ throws IOException {
+ super.sendExit2(self.pid(), dest, reason);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java
index 43b0cad222..de9569aa27 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java
@@ -1,25 +1,25 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
import java.io.IOException;
-import java.net.Socket;
/**
* <p>
@@ -27,29 +27,29 @@ import java.net.Socket;
* node. The object maintains connection state and allows data to be sent to and
* received from the peer.
* </p>
- *
+ *
* <p>
* Once a connection is established between the local node and a remote node,
* the connection object can be used to send and receive messages between the
* nodes.
* </p>
- *
+ *
* <p>
* The various receive methods are all blocking and will return only when a
* valid message has been received or an exception is raised.
* </p>
- *
+ *
* <p>
* If an exception occurs in any of the methods in this class, the connection
* will be closed and must be reopened in order to resume communication with the
* peer.
* </p>
- *
+ *
* <p>
* The message delivery methods in this class deliver directly to
* {@link OtpMbox mailboxes} in the {@link OtpNode OtpNode} class.
* </p>
- *
+ *
* <p>
* It is not possible to create an instance of this class directly.
* OtpCookedConnection objects are created as needed by the underlying mailbox
@@ -70,45 +70,45 @@ public class OtpCookedConnection extends AbstractConnection {
* OtpSelf#accept() OtpSelf.accept()} to create a connection based on data
* received when handshaking with the peer node, when the remote node is the
* connection intitiator.
- *
+ *
* @exception java.io.IOException if it was not possible to connect to the
* peer.
- *
+ *
* @exception OtpAuthException if handshake resulted in an authentication
* error
*/
// package scope
- OtpCookedConnection(final OtpNode self, final Socket s) throws IOException,
- OtpAuthException {
- super(self, s);
- this.self = self;
- links = new Links(25);
- start();
+ OtpCookedConnection(final OtpNode self, final OtpTransport s)
+ throws IOException, OtpAuthException {
+ super(self, s);
+ this.self = self;
+ links = new Links(25);
+ start();
}
/*
* Intiate and open a connection to a remote node.
- *
+ *
* @exception java.io.IOException if it was not possible to connect to the
* peer.
- *
+ *
* @exception OtpAuthException if handshake resulted in an authentication
* error.
*/
// package scope
OtpCookedConnection(final OtpNode self, final OtpPeer other)
- throws IOException, OtpAuthException {
- super(self, other);
- this.self = self;
- links = new Links(25);
- start();
+ throws IOException, OtpAuthException {
+ super(self, other);
+ this.self = self;
+ links = new Links(25);
+ start();
}
// pass the error to the node
@Override
public void deliver(final Exception e) {
- self.deliverError(this, e);
- return;
+ self.deliverError(this, e);
+ return;
}
/*
@@ -118,32 +118,32 @@ public class OtpCookedConnection extends AbstractConnection {
*/
@Override
public void deliver(final OtpMsg msg) {
- final boolean delivered = self.deliver(msg);
-
- switch (msg.type()) {
- case OtpMsg.linkTag:
- if (delivered) {
- links.addLink(msg.getRecipientPid(), msg.getSenderPid());
- } else {
- try {
- // no such pid - send exit to sender
- super.sendExit(msg.getRecipientPid(), msg.getSenderPid(),
- new OtpErlangAtom("noproc"));
- } catch (final IOException e) {
- }
- }
- break;
-
- case OtpMsg.unlinkTag:
- case OtpMsg.exitTag:
- links.removeLink(msg.getRecipientPid(), msg.getSenderPid());
- break;
-
- case OtpMsg.exit2Tag:
- break;
- }
-
- return;
+ final boolean delivered = self.deliver(msg);
+
+ switch (msg.type()) {
+ case OtpMsg.linkTag:
+ if (delivered) {
+ links.addLink(msg.getRecipientPid(), msg.getSenderPid());
+ } else {
+ try {
+ // no such pid - send exit to sender
+ super.sendExit(msg.getRecipientPid(), msg.getSenderPid(),
+ new OtpErlangAtom("noproc"));
+ } catch (final IOException e) {
+ }
+ }
+ break;
+
+ case OtpMsg.unlinkTag:
+ case OtpMsg.exitTag:
+ links.removeLink(msg.getRecipientPid(), msg.getSenderPid());
+ break;
+
+ case OtpMsg.exit2Tag:
+ break;
+ }
+
+ return;
}
/*
@@ -151,9 +151,9 @@ public class OtpCookedConnection extends AbstractConnection {
*/
@SuppressWarnings("resource")
void send(final OtpErlangPid from, final OtpErlangPid dest,
- final OtpErlangObject msg) throws IOException {
- // encode and send the message
- sendBuf(from, dest, new OtpOutputStream(msg));
+ final OtpErlangObject msg) throws IOException {
+ // encode and send the message
+ sendBuf(from, dest, new OtpOutputStream(msg));
}
/*
@@ -162,66 +162,66 @@ public class OtpCookedConnection extends AbstractConnection {
*/
@SuppressWarnings("resource")
void send(final OtpErlangPid from, final String dest,
- final OtpErlangObject msg) throws IOException {
- // encode and send the message
- sendBuf(from, dest, new OtpOutputStream(msg));
+ final OtpErlangObject msg) throws IOException {
+ // encode and send the message
+ sendBuf(from, dest, new OtpOutputStream(msg));
}
@Override
public void close() {
- super.close();
- breakLinks();
+ super.close();
+ breakLinks();
}
@Override
protected void finalize() {
- close();
+ close();
}
/*
* this one called by dying/killed process
*/
void exit(final OtpErlangPid from, final OtpErlangPid to,
- final OtpErlangObject reason) {
- try {
- super.sendExit(from, to, reason);
- } catch (final Exception e) {
- }
+ final OtpErlangObject reason) {
+ try {
+ super.sendExit(from, to, reason);
+ } catch (final Exception e) {
+ }
}
/*
* this one called explicitely by user code => use exit2
*/
void exit2(final OtpErlangPid from, final OtpErlangPid to,
- final OtpErlangObject reason) {
- try {
- super.sendExit2(from, to, reason);
- } catch (final Exception e) {
- }
+ final OtpErlangObject reason) {
+ try {
+ super.sendExit2(from, to, reason);
+ } catch (final Exception e) {
+ }
}
/*
* snoop for outgoing links and update own table
*/
synchronized void link(final OtpErlangPid from, final OtpErlangPid to)
- throws OtpErlangExit {
- try {
- super.sendLink(from, to);
- links.addLink(from, to);
- } catch (final IOException e) {
- throw new OtpErlangExit("noproc", to);
- }
+ throws OtpErlangExit {
+ try {
+ super.sendLink(from, to);
+ links.addLink(from, to);
+ } catch (final IOException e) {
+ throw new OtpErlangExit("noproc", to);
+ }
}
/*
* snoop for outgoing unlinks and update own table
*/
synchronized void unlink(final OtpErlangPid from, final OtpErlangPid to) {
- links.removeLink(from, to);
- try {
- super.sendUnlink(from, to);
- } catch (final IOException e) {
- }
+ links.removeLink(from, to);
+ try {
+ super.sendUnlink(from, to);
+ } catch (final IOException e) {
+ }
}
/*
@@ -229,18 +229,18 @@ public class OtpCookedConnection extends AbstractConnection {
* through this connection
*/
synchronized void breakLinks() {
- if (links != null) {
- final Link[] l = links.clearLinks();
-
- if (l != null) {
- final int len = l.length;
-
- for (int i = 0; i < len; i++) {
- // send exit "from" remote pids to local ones
- self.deliver(new OtpMsg(OtpMsg.exitTag, l[i].remote(), l[i]
- .local(), new OtpErlangAtom("noconnection")));
- }
- }
- }
+ if (links != null) {
+ final Link[] l = links.clearLinks();
+
+ if (l != null) {
+ final int len = l.length;
+
+ for (int i = 0; i < len; i++) {
+ // send exit "from" remote pids to local ones
+ self.deliver(new OtpMsg(OtpMsg.exitTag, l[i].remote(), l[i]
+ .local(), new OtpErlangAtom("noconnection")));
+ }
+ }
+ }
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
index 8a8ba785d9..82a701559d 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-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.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -21,20 +22,19 @@ package com.ericsson.otp.erlang;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
-import java.net.Socket;
/**
* Provides methods for registering, unregistering and looking up nodes with the
* Erlang portmapper daemon (Epmd). For each registered node, Epmd maintains
* information about the port on which incoming connections are accepted, as
- * well as which versions of the Erlang communication protocolt the node
+ * well as which versions of the Erlang communication protocol the node
* supports.
- *
+ *
* <p>
* Nodes wishing to contact other nodes must first request information from Epmd
* before a connection can be set up, however this is done automatically by
* {@link OtpSelf#connect(OtpPeer) OtpSelf.connect()} when necessary.
- *
+ *
* <p>
* The methods {@link #publishPort(OtpLocalNode) publishPort()} and
* {@link #unPublishPort(OtpLocalNode) unPublishPort()} will fail if an Epmd
@@ -42,32 +42,33 @@ import java.net.Socket;
* {@link #lookupPort(AbstractNode) lookupPort()} will fail if there is no Epmd
* process running on the host where the specified node is running. See the
* Erlang documentation for information about starting Epmd.
- *
+ *
* <p>
* This class contains only static methods, there are no constructors.
*/
public class OtpEpmd {
private static class EpmdPort {
- private static int epmdPort = 0;
-
- public static int get() {
- if (epmdPort == 0) {
- String env;
- try {
- env = System.getenv("ERL_EPMD_PORT");
- }
- catch (java.lang.SecurityException e) {
- env = null;
- }
- epmdPort = (env != null) ? Integer.parseInt(env) : 4369;
- }
- return epmdPort;
- }
- public static void set(int port) {
- epmdPort = port;
- }
+ private static int epmdPort = 0;
+
+ public static int get() {
+ if (epmdPort == 0) {
+ String env;
+ try {
+ env = System.getenv("ERL_EPMD_PORT");
+ } catch (final java.lang.SecurityException e) {
+ env = null;
+ }
+ epmdPort = env != null ? Integer.parseInt(env) : 4369;
+ }
+ return epmdPort;
+ }
+
+ public static void set(final int port) {
+ epmdPort = port;
+ }
}
+
// common values
private static final byte stopReq = (byte) 115;
@@ -81,16 +82,16 @@ public class OtpEpmd {
private static final int traceThreshold = 4;
static {
- // debug this connection?
- final String trace = System.getProperties().getProperty(
- "OtpConnection.trace");
- try {
- if (trace != null) {
- traceLevel = Integer.valueOf(trace).intValue();
- }
- } catch (final NumberFormatException e) {
- traceLevel = 0;
- }
+ // debug this connection?
+ final String trace = System.getProperties().getProperty(
+ "OtpConnection.trace");
+ try {
+ if (trace != null) {
+ traceLevel = Integer.valueOf(trace).intValue();
+ }
+ } catch (final NumberFormatException e) {
+ traceLevel = 0;
+ }
}
// only static methods: no public constructors
@@ -98,51 +99,50 @@ public class OtpEpmd {
private OtpEpmd() {
}
-
/**
- * Set the port number to be used to contact the epmd process.
- * Only needed when the default port is not desired and system environment
- * variable ERL_EPMD_PORT can not be read (applet).
+ * Set the port number to be used to contact the epmd process. Only needed
+ * when the default port is not desired and system environment variable
+ * ERL_EPMD_PORT can not be read (applet).
*/
- public static void useEpmdPort(int port) {
- EpmdPort.set(port);
+ public static void useEpmdPort(final int port) {
+ EpmdPort.set(port);
}
/**
* Determine what port a node listens for incoming connections on.
- *
+ *
* @return the listen port for the specified node, or 0 if the node was not
* registered with Epmd.
- *
+ *
* @exception java.io.IOException
* if there was no response from the name server.
*/
public static int lookupPort(final AbstractNode node) throws IOException {
- return r4_lookupPort(node);
+ return r4_lookupPort(node);
}
/**
* Register with Epmd, so that other nodes are able to find and connect to
* it.
- *
+ *
* @param node
* the server node that should be registered with Epmd.
- *
+ *
* @return true if the operation was successful. False if the node was
* already registered.
- *
+ *
* @exception java.io.IOException
* if there was no response from the name server.
*/
public static boolean publishPort(final OtpLocalNode node)
- throws IOException {
- Socket s = null;
+ throws IOException {
+ OtpTransport s = null;
- s = r4_publish(node);
+ s = r4_publish(node);
- node.setEpmd(s);
+ node.setEpmd(s);
- return s != null;
+ return s != null;
}
// Ask epmd to close his end of the connection.
@@ -151,275 +151,285 @@ public class OtpEpmd {
/**
* Unregister from Epmd. Other nodes wishing to connect will no longer be
* able to.
- *
+ *
* <p>
* This method does not report any failures.
*/
public static void unPublishPort(final OtpLocalNode node) {
- Socket s = null;
-
- try {
- s = new Socket((String) null, EpmdPort.get());
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- obuf.write2BE(node.alive().length() + 1);
- obuf.write1(stopReq);
- obuf.writeN(node.alive().getBytes());
- obuf.writeTo(s.getOutputStream());
- // don't even wait for a response (is there one?)
- if (traceLevel >= traceThreshold) {
- System.out.println("-> UNPUBLISH " + node + " port="
- + node.port());
- System.out.println("<- OK (assumed)");
- }
- } catch (final Exception e) {/* ignore all failures */
- } finally {
- try {
- if (s != null) {
- s.close();
- }
- } catch (final IOException e) { /* ignore close failure */
- }
- s = null;
- }
+ OtpTransport s = null;
+
+ try {
+ s = node.createTransport((String) null, EpmdPort.get());
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ obuf.write2BE(node.alive().length() + 1);
+ obuf.write1(stopReq);
+ obuf.writeN(node.alive().getBytes());
+ obuf.writeToAndFlush(s.getOutputStream());
+ // don't even wait for a response (is there one?)
+ if (traceLevel >= traceThreshold) {
+ System.out.println("-> UNPUBLISH " + node + " port="
+ + node.port());
+ System.out.println("<- OK (assumed)");
+ }
+ } catch (final Exception e) {/* ignore all failures */
+ } finally {
+ try {
+ if (s != null) {
+ s.close();
+ }
+ } catch (final IOException e) { /* ignore close failure */
+ }
+ s = null;
+ }
}
private static int r4_lookupPort(final AbstractNode node)
- throws IOException {
- int port = 0;
- Socket s = null;
-
- try {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- s = new Socket(node.host(), EpmdPort.get());
-
- // build and send epmd request
- // length[2], tag[1], alivename[n] (length = n+1)
- obuf.write2BE(node.alive().length() + 1);
- obuf.write1(port4req);
- obuf.writeN(node.alive().getBytes());
-
- // send request
- obuf.writeTo(s.getOutputStream());
-
- if (traceLevel >= traceThreshold) {
- System.out.println("-> LOOKUP (r4) " + node);
- }
-
- // receive and decode reply
- // resptag[1], result[1], port[2], ntype[1], proto[1],
- // disthigh[2], distlow[2], nlen[2], alivename[n],
- // elen[2], edata[m]
- final byte[] tmpbuf = new byte[100];
-
- final int n = s.getInputStream().read(tmpbuf);
-
- if (n < 0) {
- s.close();
- throw new IOException("Nameserver not responding on "
- + node.host() + " when looking up " + node.alive());
- }
-
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
-
- final int response = ibuf.read1();
- if (response == port4resp) {
- final int result = ibuf.read1();
- if (result == 0) {
- port = ibuf.read2BE();
-
- node.ntype = ibuf.read1();
- node.proto = ibuf.read1();
- node.distHigh = ibuf.read2BE();
- node.distLow = ibuf.read2BE();
- // ignore rest of fields
- }
- }
- } catch (final IOException e) {
- if (traceLevel >= traceThreshold) {
- System.out.println("<- (no response)");
- }
- throw new IOException("Nameserver not responding on " + node.host()
- + " when looking up " + node.alive());
- } catch (final OtpErlangDecodeException e) {
- if (traceLevel >= traceThreshold) {
- System.out.println("<- (invalid response)");
- }
- throw new IOException("Nameserver not responding on " + node.host()
- + " when looking up " + node.alive());
- } finally {
- try {
- if (s != null) {
- s.close();
- }
- } catch (final IOException e) { /* ignore close errors */
- }
- s = null;
- }
-
- if (traceLevel >= traceThreshold) {
- if (port == 0) {
- System.out.println("<- NOT FOUND");
- } else {
- System.out.println("<- PORT " + port);
- }
- }
- return port;
+ throws IOException {
+ int port = 0;
+ OtpTransport s = null;
+
+ try {
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ s = node.createTransport(node.host(), EpmdPort.get());
+
+ // build and send epmd request
+ // length[2], tag[1], alivename[n] (length = n+1)
+ obuf.write2BE(node.alive().length() + 1);
+ obuf.write1(port4req);
+ obuf.writeN(node.alive().getBytes());
+
+ // send request
+ obuf.writeToAndFlush(s.getOutputStream());
+
+ if (traceLevel >= traceThreshold) {
+ System.out.println("-> LOOKUP (r4) " + node);
+ }
+
+ // receive and decode reply
+ // resptag[1], result[1], port[2], ntype[1], proto[1],
+ // disthigh[2], distlow[2], nlen[2], alivename[n],
+ // elen[2], edata[m]
+ final byte[] tmpbuf = new byte[100];
+
+ final int n = s.getInputStream().read(tmpbuf);
+
+ if (n < 0) {
+ s.close();
+ throw new IOException("Nameserver not responding on "
+ + node.host() + " when looking up " + node.alive());
+ }
+
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
+
+ final int response = ibuf.read1();
+ if (response == port4resp) {
+ final int result = ibuf.read1();
+ if (result == 0) {
+ port = ibuf.read2BE();
+
+ node.ntype = ibuf.read1();
+ node.proto = ibuf.read1();
+ node.distHigh = ibuf.read2BE();
+ node.distLow = ibuf.read2BE();
+ // ignore rest of fields
+ }
+ }
+ } catch (final IOException e) {
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- (no response)");
+ }
+ throw new IOException("Nameserver not responding on " + node.host()
+ + " when looking up " + node.alive(), e);
+ } catch (final OtpErlangDecodeException e) {
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- (invalid response)");
+ }
+ throw new IOException("Nameserver not responding on " + node.host()
+ + " when looking up " + node.alive());
+ } finally {
+ try {
+ if (s != null) {
+ s.close();
+ }
+ } catch (final IOException e) { /* ignore close errors */
+ }
+ s = null;
+ }
+
+ if (traceLevel >= traceThreshold) {
+ if (port == 0) {
+ System.out.println("<- NOT FOUND");
+ } else {
+ System.out.println("<- PORT " + port);
+ }
+ }
+ return port;
}
/*
- * this function will get an exception if it tries to talk to a
- * very old epmd, or if something else happens that it cannot
- * forsee. In both cases we return an exception. We no longer
- * support r3, so the exception is fatal. If we manage to
- * successfully communicate with an r4 epmd, we return either the
- * socket, or null, depending on the result.
+ * this function will get an exception if it tries to talk to a very old
+ * epmd, or if something else happens that it cannot forsee. In both cases
+ * we return an exception. We no longer support r3, so the exception is
+ * fatal. If we manage to successfully communicate with an r4 epmd, we
+ * return either the socket, or null, depending on the result.
*/
- private static Socket r4_publish(final OtpLocalNode node)
- throws IOException {
- Socket s = null;
-
- try {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- s = new Socket((String) null, EpmdPort.get());
-
- obuf.write2BE(node.alive().length() + 13);
-
- obuf.write1(publish4req);
- obuf.write2BE(node.port());
-
- obuf.write1(node.type());
-
- obuf.write1(node.proto());
- obuf.write2BE(node.distHigh());
- obuf.write2BE(node.distLow());
-
- obuf.write2BE(node.alive().length());
- obuf.writeN(node.alive().getBytes());
- obuf.write2BE(0); // No extra
-
- // send request
- obuf.writeTo(s.getOutputStream());
-
- if (traceLevel >= traceThreshold) {
- System.out.println("-> PUBLISH (r4) " + node + " port="
- + node.port());
- }
-
- // get reply
- final byte[] tmpbuf = new byte[100];
- final int n = s.getInputStream().read(tmpbuf);
-
- if (n < 0) {
- s.close();
- throw new IOException("Nameserver not responding on "
- + node.host() + " when publishing " + node.alive());
- }
-
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
-
- final int response = ibuf.read1();
- if (response == publish4resp) {
- final int result = ibuf.read1();
- if (result == 0) {
- node.creation = ibuf.read2BE();
- if (traceLevel >= traceThreshold) {
- System.out.println("<- OK");
- }
- return s; // success
- }
- }
- } catch (final IOException e) {
- // epmd closed the connection = fail
- if (s != null) {
- s.close();
- }
- if (traceLevel >= traceThreshold) {
- System.out.println("<- (no response)");
- }
- throw new IOException("Nameserver not responding on " + node.host()
- + " when publishing " + node.alive());
- } catch (final OtpErlangDecodeException e) {
- s.close();
- if (traceLevel >= traceThreshold) {
- System.out.println("<- (invalid response)");
- }
- throw new IOException("Nameserver not responding on " + node.host()
- + " when publishing " + node.alive());
- }
-
- s.close();
- return null;
+ private static OtpTransport r4_publish(final OtpLocalNode node)
+ throws IOException {
+ OtpTransport s = null;
+
+ try {
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ s = node.createTransport((String) null, EpmdPort.get());
+
+ obuf.write2BE(node.alive().length() + 13);
+
+ obuf.write1(publish4req);
+ obuf.write2BE(node.port());
+
+ obuf.write1(node.type());
+
+ obuf.write1(node.proto());
+ obuf.write2BE(node.distHigh());
+ obuf.write2BE(node.distLow());
+
+ obuf.write2BE(node.alive().length());
+ obuf.writeN(node.alive().getBytes());
+ obuf.write2BE(0); // No extra
+
+ // send request
+ obuf.writeToAndFlush(s.getOutputStream());
+
+ if (traceLevel >= traceThreshold) {
+ System.out.println("-> PUBLISH (r4) " + node + " port="
+ + node.port());
+ }
+
+ // get reply
+ final byte[] tmpbuf = new byte[100];
+ final int n = s.getInputStream().read(tmpbuf);
+
+ if (n < 0) {
+ s.close();
+ throw new IOException("Nameserver not responding on "
+ + node.host() + " when publishing " + node.alive());
+ }
+
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
+
+ final int response = ibuf.read1();
+ if (response == publish4resp) {
+ final int result = ibuf.read1();
+ if (result == 0) {
+ node.creation = ibuf.read2BE();
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- OK");
+ }
+ return s; // success
+ }
+ }
+ } catch (final IOException e) {
+ // epmd closed the connection = fail
+ if (s != null) {
+ s.close();
+ }
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- (no response)");
+ }
+ throw new IOException("Nameserver not responding on " + node.host()
+ + " when publishing " + node.alive());
+ } catch (final OtpErlangDecodeException e) {
+ s.close();
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- (invalid response)");
+ }
+ throw new IOException("Nameserver not responding on " + node.host()
+ + " when publishing " + node.alive());
+ }
+
+ s.close();
+ return null;
}
public static String[] lookupNames() throws IOException {
- return lookupNames(InetAddress.getByName(null));
+ return lookupNames(InetAddress.getByName(null),
+ new OtpSocketTransportFactory());
+ }
+
+ public static String[] lookupNames(
+ final OtpTransportFactory transportFactory) throws IOException {
+ return lookupNames(InetAddress.getByName(null), transportFactory);
}
public static String[] lookupNames(final InetAddress address)
- throws IOException {
- Socket s = null;
-
- try {
- @SuppressWarnings("resource")
- final OtpOutputStream obuf = new OtpOutputStream();
- try {
- s = new Socket(address, EpmdPort.get());
-
- obuf.write2BE(1);
- obuf.write1(names4req);
- // send request
- obuf.writeTo(s.getOutputStream());
-
- if (traceLevel >= traceThreshold) {
- System.out.println("-> NAMES (r4) ");
- }
-
- // get reply
- final byte[] buffer = new byte[256];
- final ByteArrayOutputStream out = new ByteArrayOutputStream(256);
- while (true) {
- final int bytesRead = s.getInputStream().read(buffer);
- if (bytesRead == -1) {
- break;
- }
- out.write(buffer, 0, bytesRead);
- }
- final byte[] tmpbuf = out.toByteArray();
- @SuppressWarnings("resource")
- final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
- ibuf.read4BE(); // read port int
- // final int port = ibuf.read4BE();
- // check if port = epmdPort
-
- final int n = tmpbuf.length;
- final byte[] buf = new byte[n - 4];
- System.arraycopy(tmpbuf, 4, buf, 0, n - 4);
- final String all = OtpErlangString.newString(buf);
- return all.split("\n");
- } finally {
- if (s != null) {
- s.close();
- }
- }
-
- } catch (final IOException e) {
- if (traceLevel >= traceThreshold) {
- System.out.println("<- (no response)");
- }
- throw new IOException(
- "Nameserver not responding when requesting names");
- } catch (final OtpErlangDecodeException e) {
- if (traceLevel >= traceThreshold) {
- System.out.println("<- (invalid response)");
- }
- throw new IOException(
- "Nameserver not responding when requesting names");
- }
+ throws IOException {
+ return lookupNames(address, new OtpSocketTransportFactory());
+ }
+
+ public static String[] lookupNames(final InetAddress address,
+ final OtpTransportFactory transportFactory) throws IOException {
+ OtpTransport s = null;
+
+ try {
+ @SuppressWarnings("resource")
+ final OtpOutputStream obuf = new OtpOutputStream();
+ try {
+ s = transportFactory.createTransport(address, EpmdPort.get());
+
+ obuf.write2BE(1);
+ obuf.write1(names4req);
+ // send request
+ obuf.writeToAndFlush(s.getOutputStream());
+
+ if (traceLevel >= traceThreshold) {
+ System.out.println("-> NAMES (r4) ");
+ }
+
+ // get reply
+ final byte[] buffer = new byte[256];
+ final ByteArrayOutputStream out = new ByteArrayOutputStream(256);
+ while (true) {
+ final int bytesRead = s.getInputStream().read(buffer);
+ if (bytesRead == -1) {
+ break;
+ }
+ out.write(buffer, 0, bytesRead);
+ }
+ final byte[] tmpbuf = out.toByteArray();
+ @SuppressWarnings("resource")
+ final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
+ ibuf.read4BE(); // read port int
+ // final int port = ibuf.read4BE();
+ // check if port = epmdPort
+
+ final int n = tmpbuf.length;
+ final byte[] buf = new byte[n - 4];
+ System.arraycopy(tmpbuf, 4, buf, 0, n - 4);
+ final String all = OtpErlangString.newString(buf);
+ return all.split("\n");
+ } finally {
+ if (s != null) {
+ s.close();
+ }
+ }
+
+ } catch (final IOException e) {
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- (no response)");
+ }
+ throw new IOException(
+ "Nameserver not responding when requesting names");
+ } catch (final OtpErlangDecodeException e) {
+ if (traceLevel >= traceThreshold) {
+ System.out.println("<- (invalid response)");
+ }
+ throw new IOException(
+ "Nameserver not responding when requesting names");
+ }
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
index bff3e2c0e3..4fbd580ff5 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-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.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang atoms. Atoms can be created from
* strings whose length is not more than {@link #maxAtomLength maxAtomLength}
@@ -35,72 +35,71 @@ public class OtpErlangAtom extends OtpErlangObject {
/**
* Create an atom from the given string.
- *
+ *
* @param atom
- * the string to create the atom from.
- *
+ * the string to create the atom from.
+ *
* @exception java.lang.IllegalArgumentException
- * if the string is null or contains more than
- * {@link #maxAtomLength maxAtomLength} characters.
+ * if the string is null or contains more than
+ * {@link #maxAtomLength maxAtomLength} characters.
*/
public OtpErlangAtom(final String atom) {
- if (atom == null) {
- throw new java.lang.IllegalArgumentException(
- "null string value");
- }
-
- if (atom.codePointCount(0, atom.length()) > maxAtomLength) {
- throw new java.lang.IllegalArgumentException("Atom may not exceed "
- + maxAtomLength + " characters: " + atom);
- }
- this.atom = atom;
+ if (atom == null) {
+ throw new java.lang.IllegalArgumentException("null string value");
+ }
+
+ if (atom.codePointCount(0, atom.length()) > maxAtomLength) {
+ throw new java.lang.IllegalArgumentException("Atom may not exceed "
+ + maxAtomLength + " characters: " + atom);
+ }
+ this.atom = atom;
}
/**
* Create an atom from a stream containing an atom encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded atom.
- *
+ * the stream containing the encoded atom.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang atom.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang atom.
*/
public OtpErlangAtom(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- atom = buf.read_atom();
+ throws OtpErlangDecodeException {
+ atom = buf.read_atom();
}
/**
* Create an atom whose value is "true" or "false".
*/
public OtpErlangAtom(final boolean t) {
- atom = String.valueOf(t);
+ atom = String.valueOf(t);
}
/**
* Get the actual string contained in this object.
- *
+ *
* @return the raw string contained in this object, without regard to Erlang
* quoting rules.
- *
+ *
* @see #toString
*/
public String atomValue() {
- return atom;
+ return atom;
}
/**
* The boolean value of this atom.
- *
+ *
* @return the value of this atom expressed as a boolean value. If the atom
* consists of the characters "true" (independent of case) the value
* will be true. For any other values, the value will be false.
- *
+ *
*/
public boolean booleanValue() {
- return Boolean.valueOf(atomValue()).booleanValue();
+ return Boolean.valueOf(atomValue()).booleanValue();
}
/**
@@ -108,92 +107,91 @@ public class OtpErlangAtom extends OtpErlangObject {
* between this method and {link #atomValue atomValue()} is that the
* printname is quoted and escaped where necessary, according to the Erlang
* rules for atom naming.
- *
+ *
* @return the printname representation of this atom object.
- *
+ *
* @see #atomValue
*/
@Override
public String toString() {
- if (atomNeedsQuoting(atom)) {
- return "'" + escapeSpecialChars(atom) + "'";
- }
- return atom;
+ if (atomNeedsQuoting(atom)) {
+ return "'" + escapeSpecialChars(atom) + "'";
+ }
+ return atom;
}
/**
* Determine if two atoms are equal.
- *
+ *
* @param o
- * the other object to compare to.
- *
+ * the other object to compare to.
+ *
* @return true if the atoms are equal, false otherwise.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangAtom)) {
- return false;
- }
+ if (!(o instanceof OtpErlangAtom)) {
+ return false;
+ }
- final OtpErlangAtom other = (OtpErlangAtom) o;
- return this.atom.compareTo(other.atom) == 0;
+ final OtpErlangAtom other = (OtpErlangAtom) o;
+ return atom.compareTo(other.atom) == 0;
}
-
+
@Override
protected int doHashCode() {
- return atom.hashCode();
+ return atom.hashCode();
}
/**
* Convert this atom to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded atom should be
- * written.
+ * an output stream to which the encoded atom should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_atom(atom);
+ buf.write_atom(atom);
}
/* the following four predicates are helpers for the toString() method */
private boolean isErlangDigit(final char c) {
- return c >= '0' && c <= '9';
+ return c >= '0' && c <= '9';
}
private boolean isErlangUpper(final char c) {
- return c >= 'A' && c <= 'Z' || c == '_';
+ return c >= 'A' && c <= 'Z' || c == '_';
}
private boolean isErlangLower(final char c) {
- return c >= 'a' && c <= 'z';
+ return c >= 'a' && c <= 'z';
}
private boolean isErlangLetter(final char c) {
- return isErlangLower(c) || isErlangUpper(c);
+ return isErlangLower(c) || isErlangUpper(c);
}
// true if the atom should be displayed with quotation marks
private boolean atomNeedsQuoting(final String s) {
- char c;
-
- if (s.length() == 0) {
- return true;
- }
- if (!isErlangLower(s.charAt(0))) {
- return true;
- }
-
- final int len = s.length();
- for (int i = 1; i < len; i++) {
- c = s.charAt(i);
-
- if (!isErlangLetter(c) && !isErlangDigit(c) && c != '@') {
- return true;
- }
- }
- return false;
+ char c;
+
+ if (s.length() == 0) {
+ return true;
+ }
+ if (!isErlangLower(s.charAt(0))) {
+ return true;
+ }
+
+ final int len = s.length();
+ for (int i = 1; i < len; i++) {
+ c = s.charAt(i);
+
+ if (!isErlangLetter(c) && !isErlangDigit(c) && c != '@') {
+ return true;
+ }
+ }
+ return false;
}
/*
@@ -202,80 +200,80 @@ public class OtpErlangAtom extends OtpErlangObject {
* printable.
*/
private String escapeSpecialChars(final String s) {
- char c;
- final StringBuffer so = new StringBuffer();
-
- final int len = s.length();
- for (int i = 0; i < len; i++) {
- c = s.charAt(i);
-
- /*
- * note that some of these escape sequences are unique to Erlang,
- * which is why the corresponding 'case' values use octal. The
- * resulting string is, of course, in Erlang format.
- */
-
- switch (c) {
- // some special escape sequences
- case '\b':
- so.append("\\b");
- break;
-
- case 0177:
- so.append("\\d");
- break;
-
- case 033:
- so.append("\\e");
- break;
-
- case '\f':
- so.append("\\f");
- break;
-
- case '\n':
- so.append("\\n");
- break;
-
- case '\r':
- so.append("\\r");
- break;
-
- case '\t':
- so.append("\\t");
- break;
-
- case 013:
- so.append("\\v");
- break;
-
- case '\\':
- so.append("\\\\");
- break;
-
- case '\'':
- so.append("\\'");
- break;
-
- case '\"':
- so.append("\\\"");
- break;
-
- default:
- // some other character classes
- if (c < 027) {
- // control chars show as "\^@", "\^A" etc
- so.append("\\^" + (char) ('A' - 1 + c));
- } else if (c > 126) {
- // 8-bit chars show as \345 \344 \366 etc
- so.append("\\" + Integer.toOctalString(c));
- } else {
- // character is printable without modification!
- so.append(c);
- }
- }
- }
- return new String(so);
+ char c;
+ final StringBuffer so = new StringBuffer();
+
+ final int len = s.length();
+ for (int i = 0; i < len; i++) {
+ c = s.charAt(i);
+
+ /*
+ * note that some of these escape sequences are unique to Erlang,
+ * which is why the corresponding 'case' values use octal. The
+ * resulting string is, of course, in Erlang format.
+ */
+
+ switch (c) {
+ // some special escape sequences
+ case '\b':
+ so.append("\\b");
+ break;
+
+ case 0177:
+ so.append("\\d");
+ break;
+
+ case 033:
+ so.append("\\e");
+ break;
+
+ case '\f':
+ so.append("\\f");
+ break;
+
+ case '\n':
+ so.append("\\n");
+ break;
+
+ case '\r':
+ so.append("\\r");
+ break;
+
+ case '\t':
+ so.append("\\t");
+ break;
+
+ case 013:
+ so.append("\\v");
+ break;
+
+ case '\\':
+ so.append("\\\\");
+ break;
+
+ case '\'':
+ so.append("\\'");
+ break;
+
+ case '\"':
+ so.append("\\\"");
+ break;
+
+ default:
+ // some other character classes
+ if (c < 027) {
+ // control chars show as "\^@", "\^A" etc
+ so.append("\\^" + (char) ('A' - 1 + c));
+ } else if (c > 126) {
+ // 8-bit chars show as \345 \344 \366 etc
+ so.append("\\" + Integer.toOctalString(c));
+ } else {
+ // character is printable without modification!
+ so.append(c);
+ }
+ }
+ }
+ return new String(so);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java
index 0891781f8d..fa460d7f9a 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang binaries. Anything that can be
* represented as a sequence of bytes can be made into an Erlang binary.
@@ -29,58 +29,58 @@ public class OtpErlangBinary extends OtpErlangBitstr {
/**
* Create a binary from a byte array
- *
+ *
* @param bin
- * the array of bytes from which to create the binary.
+ * the array of bytes from which to create the binary.
*/
public OtpErlangBinary(final byte[] bin) {
- super(bin);
+ super(bin);
}
/**
* Create a binary from a stream containing a binary encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded binary.
- *
+ * the stream containing the encoded binary.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang binary.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang binary.
*/
public OtpErlangBinary(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- super(new byte[0]);
- bin = buf.read_binary();
- pad_bits = 0;
+ throws OtpErlangDecodeException {
+ super(new byte[0]);
+ bin = buf.read_binary();
+ pad_bits = 0;
}
/**
* Create a binary from an arbitrary Java Object. The object must implement
* java.io.Serializable or java.io.Externalizable.
- *
+ *
* @param o
- * the object to serialize and create this binary from.
+ * the object to serialize and create this binary from.
*/
public OtpErlangBinary(final Object o) {
- super(o);
+ super(o);
}
/**
* Convert this binary to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded binary should be
- * written.
+ * an output stream to which the encoded binary should be
+ * written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_binary(bin);
+ buf.write_binary(bin);
}
@Override
public Object clone() {
- final OtpErlangBinary that = (OtpErlangBinary) super.clone();
- return that;
+ final OtpErlangBinary that = (OtpErlangBinary) super.clone();
+ return that;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
index 8cb4e0e685..ecf07c3cf0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -35,249 +36,249 @@ public class OtpErlangBitstr extends OtpErlangObject {
/**
* Create a bitstr from a byte array
- *
+ *
* @param bin
- * the array of bytes from which to create the bitstr.
+ * the array of bytes from which to create the bitstr.
*/
public OtpErlangBitstr(final byte[] bin) {
- this.bin = new byte[bin.length];
- System.arraycopy(bin, 0, this.bin, 0, bin.length);
- pad_bits = 0;
+ this.bin = new byte[bin.length];
+ System.arraycopy(bin, 0, this.bin, 0, bin.length);
+ pad_bits = 0;
}
/**
* Create a bitstr with pad bits from a byte array.
- *
+ *
* @param bin
- * the array of bytes from which to create the bitstr.
+ * the array of bytes from which to create the bitstr.
* @param pad_bits
- * the number of unused bits in the low end of the last byte.
+ * the number of unused bits in the low end of the last byte.
*/
public OtpErlangBitstr(final byte[] bin, final int pad_bits) {
- this.bin = new byte[bin.length];
- System.arraycopy(bin, 0, this.bin, 0, bin.length);
- this.pad_bits = pad_bits;
+ this.bin = new byte[bin.length];
+ System.arraycopy(bin, 0, this.bin, 0, bin.length);
+ this.pad_bits = pad_bits;
- check_bitstr(this.bin, this.pad_bits);
+ check_bitstr(this.bin, this.pad_bits);
}
private void check_bitstr(final byte[] abin, final int a_pad_bits) {
- if (a_pad_bits < 0 || 7 < a_pad_bits) {
- throw new java.lang.IllegalArgumentException(
- "Padding must be in range 0..7");
- }
- if (a_pad_bits != 0 && abin.length == 0) {
- throw new java.lang.IllegalArgumentException(
- "Padding on zero length bitstr");
- }
- if (abin.length != 0) {
- // Make sure padding is zero
- abin[abin.length - 1] &= ~((1 << a_pad_bits) - 1);
- }
+ if (a_pad_bits < 0 || 7 < a_pad_bits) {
+ throw new java.lang.IllegalArgumentException(
+ "Padding must be in range 0..7");
+ }
+ if (a_pad_bits != 0 && abin.length == 0) {
+ throw new java.lang.IllegalArgumentException(
+ "Padding on zero length bitstr");
+ }
+ if (abin.length != 0) {
+ // Make sure padding is zero
+ abin[abin.length - 1] &= ~((1 << a_pad_bits) - 1);
+ }
}
/**
* Create a bitstr from a stream containing a bitstr encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded bitstr.
- *
+ * the stream containing the encoded bitstr.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang bitstr.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang bitstr.
*/
public OtpErlangBitstr(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final int pbs[] = { 0 }; // This is ugly just to get a value-result
- // parameter
- bin = buf.read_bitstr(pbs);
- pad_bits = pbs[0];
+ throws OtpErlangDecodeException {
+ final int pbs[] = { 0 }; // This is ugly just to get a value-result
+ // parameter
+ bin = buf.read_bitstr(pbs);
+ pad_bits = pbs[0];
- check_bitstr(bin, pad_bits);
+ check_bitstr(bin, pad_bits);
}
/**
* Create a bitstr from an arbitrary Java Object. The object must implement
* java.io.Serializable or java.io.Externalizable.
- *
+ *
* @param o
- * the object to serialize and create this bitstr from.
+ * the object to serialize and create this bitstr from.
*/
public OtpErlangBitstr(final Object o) {
- try {
- bin = toByteArray(o);
- pad_bits = 0;
- } catch (final IOException e) {
- throw new java.lang.IllegalArgumentException(
- "Object must implement Serializable");
- }
+ try {
+ bin = toByteArray(o);
+ pad_bits = 0;
+ } catch (final IOException e) {
+ throw new java.lang.IllegalArgumentException(
+ "Object must implement Serializable");
+ }
}
private static byte[] toByteArray(final Object o)
- throws java.io.IOException {
+ throws java.io.IOException {
- if (o == null) {
- return null;
- }
+ if (o == null) {
+ return null;
+ }
- /* need to synchronize use of the shared baos */
- final java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
- final java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(
- baos);
+ /* need to synchronize use of the shared baos */
+ final java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(
+ baos);
- oos.writeObject(o);
- oos.flush();
+ oos.writeObject(o);
+ oos.flush();
- return baos.toByteArray();
+ return baos.toByteArray();
}
private static Object fromByteArray(final byte[] buf) {
- if (buf == null) {
- return null;
- }
+ if (buf == null) {
+ return null;
+ }
- try {
- final java.io.ByteArrayInputStream bais = new java.io.ByteArrayInputStream(
- buf);
- final java.io.ObjectInputStream ois = new java.io.ObjectInputStream(
- bais);
- return ois.readObject();
- } catch (final java.lang.ClassNotFoundException e) {
- } catch (final java.io.IOException e) {
- }
+ try {
+ final java.io.ByteArrayInputStream bais = new java.io.ByteArrayInputStream(
+ buf);
+ final java.io.ObjectInputStream ois = new java.io.ObjectInputStream(
+ bais);
+ return ois.readObject();
+ } catch (final java.lang.ClassNotFoundException e) {
+ } catch (final java.io.IOException e) {
+ }
- return null;
+ return null;
}
/**
* Get the byte array from a bitstr, padded with zero bits in the little end
* of the last byte.
- *
+ *
* @return the byte array containing the bytes for this bitstr.
*/
public byte[] binaryValue() {
- return bin;
+ return bin;
}
/**
* Get the size in whole bytes of the bitstr, rest bits in the last byte not
* counted.
- *
+ *
* @return the number of bytes contained in the bintstr.
*/
public int size() {
- if (pad_bits == 0) {
- return bin.length;
- }
- if (bin.length == 0) {
- throw new java.lang.IllegalStateException("Impossible length");
- }
- return bin.length - 1;
+ if (pad_bits == 0) {
+ return bin.length;
+ }
+ if (bin.length == 0) {
+ throw new java.lang.IllegalStateException("Impossible length");
+ }
+ return bin.length - 1;
}
/**
* Get the number of pad bits in the last byte of the bitstr. The pad bits
* are zero and in the little end.
- *
+ *
* @return the number of pad bits in the bitstr.
*/
public int pad_bits() {
- return pad_bits;
+ return pad_bits;
}
/**
* Get the java Object from the bitstr. If the bitstr contains a serialized
* Java object, then this method will recreate the object.
- *
- *
+ *
+ *
* @return the java Object represented by this bitstr, or null if the bitstr
* does not represent a Java Object.
*/
public Object getObject() {
- if (pad_bits != 0) {
- return null;
- }
- return fromByteArray(bin);
+ if (pad_bits != 0) {
+ return null;
+ }
+ return fromByteArray(bin);
}
/**
* Get the string representation of this bitstr object. A bitstr is printed
* as #Bin&lt;N&gt;, where N is the number of bytes contained in the object
* or #bin&lt;N-M&gt; if there are M pad bits.
- *
+ *
* @return the Erlang string representation of this bitstr.
*/
@Override
public String toString() {
- if (pad_bits == 0) {
- return "#Bin<" + bin.length + ">";
- }
- if (bin.length == 0) {
- throw new java.lang.IllegalStateException("Impossible length");
- }
- return "#Bin<" + bin.length + "-" + pad_bits + ">";
+ if (pad_bits == 0) {
+ return "#Bin<" + bin.length + ">";
+ }
+ if (bin.length == 0) {
+ throw new java.lang.IllegalStateException("Impossible length");
+ }
+ return "#Bin<" + bin.length + "-" + pad_bits + ">";
}
/**
* Convert this bitstr to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded bitstr should be
- * written.
+ * an output stream to which the encoded bitstr should be
+ * written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_bitstr(bin, pad_bits);
+ buf.write_bitstr(bin, pad_bits);
}
/**
* Determine if two bitstrs are equal. Bitstrs are equal if they have the
* same byte length and tail length, and the array of bytes is identical.
- *
+ *
* @param o
- * the bitstr to compare to.
- *
+ * the bitstr to compare to.
+ *
* @return true if the bitstrs contain the same bits, false otherwise.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangBitstr)) {
- return false;
- }
+ if (!(o instanceof OtpErlangBitstr)) {
+ return false;
+ }
- final OtpErlangBitstr that = (OtpErlangBitstr) o;
- if (pad_bits != that.pad_bits) {
- return false;
- }
+ final OtpErlangBitstr that = (OtpErlangBitstr) o;
+ if (pad_bits != that.pad_bits) {
+ return false;
+ }
- final int len = bin.length;
- if (len != that.bin.length) {
- return false;
- }
+ final int len = bin.length;
+ if (len != that.bin.length) {
+ return false;
+ }
- for (int i = 0; i < len; i++) {
- if (bin[i] != that.bin[i]) {
- return false; // early exit
- }
- }
+ for (int i = 0; i < len; i++) {
+ if (bin[i] != that.bin[i]) {
+ return false; // early exit
+ }
+ }
- return true;
+ return true;
}
-
+
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(15);
- hash.combine(bin);
- hash.combine(pad_bits);
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(15);
+ hash.combine(bin);
+ hash.combine(pad_bits);
+ return hash.valueOf();
}
-
+
@Override
public Object clone() {
- final OtpErlangBitstr that = (OtpErlangBitstr) super.clone();
- that.bin = bin.clone();
- that.pad_bits = pad_bits;
- return that;
+ final OtpErlangBitstr that = (OtpErlangBitstr) super.clone();
+ that.bin = bin.clone();
+ that.pad_bits = pad_bits;
+ return that;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java
index eecd2ea288..50ada048c2 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang booleans, which are special cases of
* atoms with values 'true' and 'false'.
@@ -29,12 +29,12 @@ public class OtpErlangBoolean extends OtpErlangAtom {
/**
* Create a boolean from the given value
- *
+ *
* @param t
- * the boolean value to represent as an atom.
+ * the boolean value to represent as an atom.
*/
public OtpErlangBoolean(final boolean t) {
- super(t);
+ super(t);
}
/**
@@ -42,13 +42,13 @@ public class OtpErlangBoolean extends OtpErlangAtom {
* external format. The value of the boolean will be true if the atom
* represented by the stream is "true" without regard to case. For other
* atom values, the boolean will have the value false.
- *
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang atom.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang atom.
*/
public OtpErlangBoolean(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangDecodeException {
+ super(buf);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java
index eb6f3d8aba..ae4ecfae23 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang integral types.
*/
@@ -28,32 +28,32 @@ public class OtpErlangByte extends OtpErlangLong {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param b
- * the byte value to use.
+ * the byte value to use.
*/
public OtpErlangByte(final byte b) {
- super(b);
+ super(b);
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a byte.
+ * if the value is too large to be represented as a byte.
*/
public OtpErlangByte(final OtpInputStream buf)
- throws OtpErlangRangeException, OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangRangeException, OtpErlangDecodeException {
+ super(buf);
- byteValue();
+ byteValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java
index e7c6dd8ad4..7f22918978 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang integral types.
*/
@@ -28,32 +28,32 @@ public class OtpErlangChar extends OtpErlangLong {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param c
- * the char value to use.
+ * the char value to use.
*/
public OtpErlangChar(final char c) {
- super(c);
+ super(c);
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a char.
+ * if the value is too large to be represented as a char.
*/
public OtpErlangChar(final OtpInputStream buf)
- throws OtpErlangRangeException, OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangRangeException, OtpErlangDecodeException {
+ super(buf);
- charValue();
+ charValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java
index 6986e26908..850d43b35a 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -22,7 +23,7 @@ package com.ericsson.otp.erlang;
* Exception raised when an attempt is made to create an Erlang term by decoding
* a sequence of bytes that does not represent the type of term that was
* requested.
- *
+ *
* @see OtpInputStream
*/
public class OtpErlangDecodeException extends OtpErlangException {
@@ -32,6 +33,6 @@ public class OtpErlangDecodeException extends OtpErlangException {
* Provides a detailed message.
*/
public OtpErlangDecodeException(final String msg) {
- super(msg);
+ super(msg);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java
index e92ce11431..3087ae1dbb 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang floats and doubles. Erlang defines
* only one floating point numeric type, however this class and its subclass
@@ -35,96 +35,95 @@ public class OtpErlangDouble extends OtpErlangObject {
* Create an Erlang float from the given double value.
*/
public OtpErlangDouble(final double d) {
- this.d = d;
+ this.d = d;
}
/**
* Create an Erlang float from a stream containing a double encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang float.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang float.
*/
public OtpErlangDouble(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- d = buf.read_double();
+ throws OtpErlangDecodeException {
+ d = buf.read_double();
}
/**
* Get the value, as a double.
- *
+ *
* @return the value of this object, as a double.
*/
public double doubleValue() {
- return d;
+ return d;
}
/**
* Get the value, as a float.
- *
+ *
* @return the value of this object, as a float.
- *
+ *
* @exception OtpErlangRangeException
- * if the value cannot be represented as a float.
+ * if the value cannot be represented as a float.
*/
public float floatValue() throws OtpErlangRangeException {
- final float f = (float) d;
+ final float f = (float) d;
- if (f != d) {
- throw new OtpErlangRangeException("Value too large for float: " + d);
- }
+ if (f != d) {
+ throw new OtpErlangRangeException("Value too large for float: " + d);
+ }
- return f;
+ return f;
}
/**
* Get the string representation of this double.
- *
+ *
* @return the string representation of this double.
*/
@Override
public String toString() {
- return "" + d;
+ return "" + d;
}
/**
* Convert this double to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded value should be
- * written.
+ * an output stream to which the encoded value should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_double(d);
+ buf.write_double(d);
}
/**
* Determine if two floats are equal. Floats are equal if they contain the
* same value.
- *
+ *
* @param o
- * the float to compare to.
- *
+ * the float to compare to.
+ *
* @return true if the floats have the same value.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangDouble)) {
- return false;
- }
+ if (!(o instanceof OtpErlangDouble)) {
+ return false;
+ }
- final OtpErlangDouble other = (OtpErlangDouble) o;
- return this.d == other.d;
+ final OtpErlangDouble other = (OtpErlangDouble) o;
+ return d == other.d;
}
-
+
@Override
protected int doHashCode() {
- Double v = new Double(d);
- return v.hashCode();
+ final Double v = new Double(d);
+ return v.hashCode();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangException.java
index 5b111a56a8..7e80385308 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangException.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -28,13 +29,13 @@ public class OtpErlangException extends OtpException {
* Provides no message.
*/
public OtpErlangException() {
- super();
+ super();
}
/**
* Provides a detailed message.
*/
public OtpErlangException(final String msg) {
- super(msg);
+ super(msg);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExit.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExit.java
index 6b9015c0e5..6f31cc8ebd 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExit.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExit.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -21,13 +22,13 @@ package com.ericsson.otp.erlang;
/**
* Exception raised when a communication channel is broken. This can be caused
* for a number of reasons, for example:
- *
+ *
* <ul>
- * <li> an error in communication has occurred
- * <li> a remote process has sent an exit signal
- * <li> a linked process has exited
+ * <li>an error in communication has occurred
+ * <li>a remote process has sent an exit signal
+ * <li>a linked process has exited
* </ul>
- *
+ *
* @see OtpConnection
*/
@@ -39,13 +40,13 @@ public class OtpErlangExit extends OtpErlangException {
/**
* Create an OtpErlangExit exception with the given reason.
- *
+ *
* @param reason
- * the reason this exit signal has been sent.
+ * the reason this exit signal has been sent.
*/
public OtpErlangExit(final OtpErlangObject reason) {
- super(reason.toString());
- this.reason = reason;
+ super(reason.toString());
+ this.reason = reason;
}
/**
@@ -53,29 +54,29 @@ public class OtpErlangExit extends OtpErlangException {
* Equivalent to <code>OtpErlangExit(new
* OtpErlangAtom(reason)</code>.
* </p>
- *
+ *
* @param reason
- * the reason this exit signal has been sent.
- *
+ * the reason this exit signal has been sent.
+ *
* @see #OtpErlangExit(OtpErlangObject)
*/
public OtpErlangExit(final String reason) {
- this(new OtpErlangAtom(reason));
+ this(new OtpErlangAtom(reason));
}
/**
* Create an OtpErlangExit exception with the given reason and sender pid.
- *
+ *
* @param reason
- * the reason this exit signal has been sent.
- *
+ * the reason this exit signal has been sent.
+ *
* @param pid
- * the pid that sent this exit.
+ * the pid that sent this exit.
*/
public OtpErlangExit(final OtpErlangObject reason, final OtpErlangPid pid) {
- super(reason.toString());
- this.reason = reason;
- this.pid = pid;
+ super(reason.toString());
+ this.reason = reason;
+ this.pid = pid;
}
/**
@@ -83,30 +84,30 @@ public class OtpErlangExit extends OtpErlangException {
* Equivalent to <code>OtpErlangExit(new OtpErlangAtom(reason),
* pid)</code>.
* </p>
- *
+ *
* @param reason
- * the reason this exit signal has been sent.
- *
+ * the reason this exit signal has been sent.
+ *
* @param pid
- * the pid that sent this exit.
- *
+ * the pid that sent this exit.
+ *
* @see #OtpErlangExit(OtpErlangObject, OtpErlangPid)
*/
public OtpErlangExit(final String reason, final OtpErlangPid pid) {
- this(new OtpErlangAtom(reason), pid);
+ this(new OtpErlangAtom(reason), pid);
}
/**
* Get the reason associated with this exit signal.
*/
public OtpErlangObject reason() {
- return reason;
+ return reason;
}
/**
* Get the pid that sent this exit.
*/
public OtpErlangPid pid() {
- return pid;
+ return pid;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExternalFun.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExternalFun.java
index 09f36b1ff4..d4564293c6 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExternalFun.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangExternalFun.java
@@ -1,20 +1,21 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -27,47 +28,47 @@ public class OtpErlangExternalFun extends OtpErlangObject {
private final int arity;
public OtpErlangExternalFun(final String module, final String function,
- final int arity) {
- super();
- this.module = module;
- this.function = function;
- this.arity = arity;
+ final int arity) {
+ super();
+ this.module = module;
+ this.function = function;
+ this.arity = arity;
}
public OtpErlangExternalFun(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final OtpErlangExternalFun f = buf.read_external_fun();
- module = f.module;
- function = f.function;
- arity = f.arity;
+ throws OtpErlangDecodeException {
+ final OtpErlangExternalFun f = buf.read_external_fun();
+ module = f.module;
+ function = f.function;
+ arity = f.arity;
}
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_external_fun(module, function, arity);
+ buf.write_external_fun(module, function, arity);
}
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangExternalFun)) {
- return false;
- }
- final OtpErlangExternalFun f = (OtpErlangExternalFun) o;
- return module.equals(f.module) && function.equals(f.function)
- && arity == f.arity;
+ if (!(o instanceof OtpErlangExternalFun)) {
+ return false;
+ }
+ final OtpErlangExternalFun f = (OtpErlangExternalFun) o;
+ return module.equals(f.module) && function.equals(f.function)
+ && arity == f.arity;
}
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(14);
- hash.combine(module.hashCode(), function.hashCode());
- hash.combine(arity);
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(14);
+ hash.combine(module.hashCode(), function.hashCode());
+ hash.combine(arity);
+ return hash.valueOf();
}
-
+
@Override
public String toString() {
- return "#Fun<" + module + "." + function + "." + arity + ">";
+ return "#Fun<" + module + "." + function + "." + arity + ">";
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java
index 7d48f848f0..d552d51cd7 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang floats and doubles.
*/
@@ -30,27 +30,27 @@ public class OtpErlangFloat extends OtpErlangDouble {
* Create an Erlang float from the given float value.
*/
public OtpErlangFloat(final float f) {
- super(f);
+ super(f);
}
/**
* Create an Erlang float from a stream containing a float encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang float.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang float.
+ *
* @exception OtpErlangRangeException
- * if the value cannot be represented as a Java float.
+ * if the value cannot be represented as a Java float.
*/
public OtpErlangFloat(final OtpInputStream buf)
- throws OtpErlangDecodeException, OtpErlangRangeException {
- super(buf);
+ throws OtpErlangDecodeException, OtpErlangRangeException {
+ super(buf);
- floatValue();
+ floatValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java
index 05fa0cbb23..c8c8d2221a 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java
@@ -1,20 +1,21 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -34,97 +35,97 @@ public class OtpErlangFun extends OtpErlangObject {
private final byte[] md5;
public OtpErlangFun(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final OtpErlangFun f = buf.read_fun();
- pid = f.pid;
- module = f.module;
- arity = f.arity;
- md5 = f.md5;
- index = f.index;
- old_index = f.old_index;
- uniq = f.uniq;
- freeVars = f.freeVars;
+ throws OtpErlangDecodeException {
+ final OtpErlangFun f = buf.read_fun();
+ pid = f.pid;
+ module = f.module;
+ arity = f.arity;
+ md5 = f.md5;
+ index = f.index;
+ old_index = f.old_index;
+ uniq = f.uniq;
+ freeVars = f.freeVars;
}
public OtpErlangFun(final OtpErlangPid pid, final String module,
- final long index, final long uniq, final OtpErlangObject[] freeVars) {
- this.pid = pid;
- this.module = module;
- arity = -1;
- md5 = null;
- this.index = index;
- old_index = 0;
- this.uniq = uniq;
- this.freeVars = freeVars;
+ final long index, final long uniq, final OtpErlangObject[] freeVars) {
+ this.pid = pid;
+ this.module = module;
+ arity = -1;
+ md5 = null;
+ this.index = index;
+ old_index = 0;
+ this.uniq = uniq;
+ this.freeVars = freeVars;
}
public OtpErlangFun(final OtpErlangPid pid, final String module,
- final int arity, final byte[] md5, final int index,
- final long old_index, final long uniq,
- final OtpErlangObject[] freeVars) {
- this.pid = pid;
- this.module = module;
- this.arity = arity;
- this.md5 = md5;
- this.index = index;
- this.old_index = old_index;
- this.uniq = uniq;
- this.freeVars = freeVars;
+ final int arity, final byte[] md5, final int index,
+ final long old_index, final long uniq,
+ final OtpErlangObject[] freeVars) {
+ this.pid = pid;
+ this.module = module;
+ this.arity = arity;
+ this.md5 = md5;
+ this.index = index;
+ this.old_index = old_index;
+ this.uniq = uniq;
+ this.freeVars = freeVars;
}
@Override
public void encode(final OtpOutputStream buf) {
- buf
- .write_fun(pid, module, old_index, arity, md5, index, uniq,
- freeVars);
+ buf.write_fun(pid, module, old_index, arity, md5, index, uniq, freeVars);
}
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangFun)) {
- return false;
- }
- final OtpErlangFun f = (OtpErlangFun) o;
- if (!pid.equals(f.pid) || !module.equals(f.module) || arity != f.arity) {
- return false;
- }
- if (md5 == null) {
- if (f.md5 != null) {
- return false;
- }
- } else {
- if (!Arrays.equals(md5, f.md5)) {
- return false;
- }
- }
- if (index != f.index || uniq != f.uniq) {
- return false;
- }
- if (freeVars == null) {
- return f.freeVars == null;
- }
- return Arrays.equals(freeVars, f.freeVars);
+ if (!(o instanceof OtpErlangFun)) {
+ return false;
+ }
+ final OtpErlangFun f = (OtpErlangFun) o;
+ if (!pid.equals(f.pid) || !module.equals(f.module) || arity != f.arity) {
+ return false;
+ }
+ if (md5 == null) {
+ if (f.md5 != null) {
+ return false;
+ }
+ } else {
+ if (!Arrays.equals(md5, f.md5)) {
+ return false;
+ }
+ }
+ if (index != f.index || uniq != f.uniq) {
+ return false;
+ }
+ if (freeVars == null) {
+ return f.freeVars == null;
+ }
+ return Arrays.equals(freeVars, f.freeVars);
}
-
+
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(1);
- hash.combine(pid.hashCode(), module.hashCode());
- hash.combine(arity);
- if (md5 != null) hash.combine(md5);
- hash.combine(index);
- hash.combine(uniq);
- if (freeVars != null) {
- for (OtpErlangObject o: freeVars) {
- hash.combine(o.hashCode(), 1);
- }
- }
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(1);
+ hash.combine(pid.hashCode(), module.hashCode());
+ hash.combine(arity);
+ if (md5 != null) {
+ hash.combine(md5);
+ }
+ hash.combine(index);
+ hash.combine(uniq);
+ if (freeVars != null) {
+ for (final OtpErlangObject o : freeVars) {
+ hash.combine(o.hashCode(), 1);
+ }
+ }
+ return hash.valueOf();
}
-
+
@Override
public String toString() {
- return "#Fun<" + module + "." + old_index + "." + uniq + ">";
+ return "#Fun<" + module + "." + old_index + "." + uniq + ">";
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java
index 741fc29dd0..48d8640a73 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang integral types.
*/
@@ -28,32 +28,32 @@ public class OtpErlangInt extends OtpErlangLong {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param i
- * the int value to use.
+ * the int value to use.
*/
public OtpErlangInt(final int i) {
- super(i);
+ super(i);
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as an int.
+ * if the value is too large to be represented as an int.
*/
public OtpErlangInt(final OtpInputStream buf)
- throws OtpErlangRangeException, OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangRangeException, OtpErlangDecodeException {
+ super(buf);
- intValue();
+ intValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
index 9f7c5f5499..8afb118ff2 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -24,12 +25,12 @@ import java.util.NoSuchElementException;
/**
* Provides a Java representation of Erlang lists. Lists are created from zero
* or more arbitrary Erlang terms.
- *
+ *
* <p>
* The arity of the list is the number of elements it contains.
*/
public class OtpErlangList extends OtpErlangObject implements
- Iterable<OtpErlangObject> {
+ Iterable<OtpErlangObject> {
// don't change this!
private static final long serialVersionUID = 5999112769036676548L;
@@ -43,69 +44,69 @@ public class OtpErlangList extends OtpErlangObject implements
* Create an empty list.
*/
public OtpErlangList() {
- elems = NO_ELEMENTS;
+ elems = NO_ELEMENTS;
}
/**
- * Create a list of Erlang integers representing Unicode codePoints.
- * This method does not check if the string contains valid code points.
- *
+ * Create a list of Erlang integers representing Unicode codePoints. This
+ * method does not check if the string contains valid code points.
+ *
* @param str
* the characters from which to create the list.
*/
public OtpErlangList(final String str) {
- if (str == null || str.length() == 0) {
- elems = NO_ELEMENTS;
- } else {
- final int[] codePoints = OtpErlangString.stringToCodePoints(str);
- elems = new OtpErlangObject[codePoints.length];
- for (int i = 0; i < elems.length; i++) {
- elems[i] = new OtpErlangInt(codePoints[i]);
- }
- }
+ if (str == null || str.length() == 0) {
+ elems = NO_ELEMENTS;
+ } else {
+ final int[] codePoints = OtpErlangString.stringToCodePoints(str);
+ elems = new OtpErlangObject[codePoints.length];
+ for (int i = 0; i < elems.length; i++) {
+ elems[i] = new OtpErlangInt(codePoints[i]);
+ }
+ }
}
/**
* Create a list containing one element.
- *
+ *
* @param elem
* the elememet to make the list from.
*/
public OtpErlangList(final OtpErlangObject elem) {
- elems = new OtpErlangObject[] { elem };
+ elems = new OtpErlangObject[] { elem };
}
/**
* Create a list from an array of arbitrary Erlang terms.
- *
+ *
* @param elems
* the array of terms from which to create the list.
*/
public OtpErlangList(final OtpErlangObject[] elems) {
- this(elems, 0, elems.length);
+ this(elems, 0, elems.length);
}
/**
* Create a list from an array of arbitrary Erlang terms. Tail can be
* specified, if not null, the list will not be proper.
- *
+ *
* @param elems
* array of terms from which to create the list
* @param lastTail
* @throws OtpErlangException
*/
public OtpErlangList(final OtpErlangObject[] elems,
- final OtpErlangObject lastTail) throws OtpErlangException {
- this(elems, 0, elems.length);
- if (elems.length == 0 && lastTail != null) {
- throw new OtpErlangException("Bad list, empty head, non-empty tail");
- }
- this.lastTail = lastTail;
+ final OtpErlangObject lastTail) throws OtpErlangException {
+ this(elems, 0, elems.length);
+ if (elems.length == 0 && lastTail != null) {
+ throw new OtpErlangException("Bad list, empty head, non-empty tail");
+ }
+ this.lastTail = lastTail;
}
/**
* Create a list from an array of arbitrary Erlang terms.
- *
+ *
* @param elems
* the array of terms from which to create the list.
* @param start
@@ -114,152 +115,152 @@ public class OtpErlangList extends OtpErlangObject implements
* the number of terms to insert.
*/
public OtpErlangList(final OtpErlangObject[] elems, final int start,
- final int count) {
- if (elems != null && count > 0) {
- this.elems = new OtpErlangObject[count];
- System.arraycopy(elems, start, this.elems, 0, count);
- } else {
- this.elems = NO_ELEMENTS;
- }
+ final int count) {
+ if (elems != null && count > 0) {
+ this.elems = new OtpErlangObject[count];
+ System.arraycopy(elems, start, this.elems, 0, count);
+ } else {
+ this.elems = NO_ELEMENTS;
+ }
}
/**
* Create a list from a stream containing an list encoded in Erlang external
* format.
- *
+ *
* @param buf
* the stream containing the encoded list.
- *
+ *
* @exception OtpErlangDecodeException
* if the buffer does not contain a valid external
* representation of an Erlang list.
*/
public OtpErlangList(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final int arity = buf.read_list_head();
- if (arity > 0) {
- elems = new OtpErlangObject[arity];
- for (int i = 0; i < arity; i++) {
- elems[i] = buf.read_any();
- }
- /* discard the terminating nil (empty list) or read tail */
- if (buf.peek1() == OtpExternal.nilTag) {
- buf.read_nil();
- } else {
- lastTail = buf.read_any();
- }
- } else {
- elems = NO_ELEMENTS;
- }
+ throws OtpErlangDecodeException {
+ final int arity = buf.read_list_head();
+ if (arity > 0) {
+ elems = new OtpErlangObject[arity];
+ for (int i = 0; i < arity; i++) {
+ elems[i] = buf.read_any();
+ }
+ /* discard the terminating nil (empty list) or read tail */
+ if (buf.peek1() == OtpExternal.nilTag) {
+ buf.read_nil();
+ } else {
+ lastTail = buf.read_any();
+ }
+ } else {
+ elems = NO_ELEMENTS;
+ }
}
/**
* Get the arity of the list.
- *
+ *
* @return the number of elements contained in the list.
*/
public int arity() {
- return elems.length;
+ return elems.length;
}
/**
* Get the specified element from the list.
- *
+ *
* @param i
* the index of the requested element. List elements are numbered
* as array elements, starting at 0.
- *
+ *
* @return the requested element, of null if i is not a valid element index.
*/
public OtpErlangObject elementAt(final int i) {
- if (i >= arity() || i < 0) {
- return null;
- }
- return elems[i];
+ if (i >= arity() || i < 0) {
+ return null;
+ }
+ return elems[i];
}
/**
* Get all the elements from the list as an array.
- *
+ *
* @return an array containing all of the list's elements.
*/
public OtpErlangObject[] elements() {
- if (arity() == 0) {
- return NO_ELEMENTS;
+ if (arity() == 0) {
+ return NO_ELEMENTS;
+ }
+ final OtpErlangObject[] res = new OtpErlangObject[arity()];
+ System.arraycopy(elems, 0, res, 0, res.length);
+ return res;
}
- final OtpErlangObject[] res = new OtpErlangObject[arity()];
- System.arraycopy(elems, 0, res, 0, res.length);
- return res;
- }
/**
* Get the string representation of the list.
- *
+ *
* @return the string representation of the list.
*/
@Override
public String toString() {
- return toString(0);
+ return toString(0);
}
protected String toString(final int start) {
- final StringBuffer s = new StringBuffer();
- s.append("[");
-
- for (int i = start; i < arity(); i++) {
- if (i > start) {
- s.append(",");
- }
- s.append(elems[i].toString());
- }
- if (lastTail != null) {
- s.append("|").append(lastTail.toString());
- }
- s.append("]");
-
- return s.toString();
+ final StringBuffer s = new StringBuffer();
+ s.append("[");
+
+ for (int i = start; i < arity(); i++) {
+ if (i > start) {
+ s.append(",");
+ }
+ s.append(elems[i].toString());
+ }
+ if (lastTail != null) {
+ s.append("|").append(lastTail.toString());
+ }
+ s.append("]");
+
+ return s.toString();
}
/**
* Convert this list to the equivalent Erlang external representation. Note
* that this method never encodes lists as strings, even when it is possible
* to do so.
- *
+ *
* @param buf
* An output stream to which the encoded list should be written.
- *
+ *
*/
@Override
public void encode(final OtpOutputStream buf) {
- encode(buf, 0);
+ encode(buf, 0);
}
protected void encode(final OtpOutputStream buf, final int start) {
- final int arity = arity() - start;
-
- if (arity > 0) {
- buf.write_list_head(arity);
-
- for (int i = start; i < arity + start; i++) {
- buf.write_any(elems[i]);
- }
- }
- if (lastTail == null) {
- buf.write_nil();
- } else {
- buf.write_any(lastTail);
- }
+ final int arity = arity() - start;
+
+ if (arity > 0) {
+ buf.write_list_head(arity);
+
+ for (int i = start; i < arity + start; i++) {
+ buf.write_any(elems[i]);
+ }
+ }
+ if (lastTail == null) {
+ buf.write_nil();
+ } else {
+ buf.write_any(lastTail);
+ }
}
/**
* Determine if two lists are equal. Lists are equal if they have the same
* arity and all of the elements are equal.
- *
+ *
* @param o
* the list to compare to.
- *
+ *
* @return true if the lists have the same arity and all the elements are
* equal.
*/
@@ -267,236 +268,282 @@ public class OtpErlangList extends OtpErlangObject implements
@Override
public boolean equals(final Object o) {
- /*
- * Be careful to use methods even for "this", so that equals work also
- * for sublists
- */
-
- if (!(o instanceof OtpErlangList)) {
- return false;
- }
-
- final OtpErlangList l = (OtpErlangList) o;
-
- final int a = arity();
- if (a != l.arity()) {
- return false;
- }
- for (int i = 0; i < a; i++) {
- if (!elementAt(i).equals(l.elementAt(i))) {
- return false; // early exit
- }
- }
- final OtpErlangObject otherTail = l.getLastTail();
- if (getLastTail() == null && otherTail == null) {
- return true;
- }
- if (getLastTail() == null) {
- return false;
- }
- return getLastTail().equals(l.getLastTail());
+ /*
+ * Be careful to use methods even for "this", so that equals work also
+ * for sublists
+ */
+
+ if (!(o instanceof OtpErlangList)) {
+ return false;
+ }
+
+ final OtpErlangList l = (OtpErlangList) o;
+
+ final int a = arity();
+ if (a != l.arity()) {
+ return false;
+ }
+ for (int i = 0; i < a; i++) {
+ if (!elementAt(i).equals(l.elementAt(i))) {
+ return false; // early exit
+ }
+ }
+ final OtpErlangObject otherTail = l.getLastTail();
+ if (getLastTail() == null && otherTail == null) {
+ return true;
+ }
+ if (getLastTail() == null) {
+ return false;
+ }
+ return getLastTail().equals(l.getLastTail());
+ }
+
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T bindings) {
+ if (!(term instanceof OtpErlangList)) {
+ return false;
+ }
+ final OtpErlangList that = (OtpErlangList) term;
+
+ final int thisArity = this.arity();
+ final int thatArity = that.arity();
+ final OtpErlangObject thisTail = this.getLastTail();
+ final OtpErlangObject thatTail = that.getLastTail();
+
+ if (thisTail == null) {
+ if (thisArity != thatArity || thatTail != null) {
+ return false;
+ }
+ } else {
+ if (thisArity > thatArity) {
+ return false;
+ }
+ }
+ for (int i = 0; i < thisArity; i++) {
+ if (!elementAt(i).match(that.elementAt(i), bindings)) {
+ return false;
+ }
+ }
+ if (thisTail == null) {
+ return true;
+ }
+ return thisTail.match(that.getNthTail(thisArity), bindings);
+ }
+
+ @Override
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ final OtpErlangList list = (OtpErlangList) this.clone();
+
+ final int a = list.elems.length;
+ for (int i = 0; i < a; i++) {
+ list.elems[i] = list.elems[i].bind(binds);
+ }
+
+ if (list.lastTail != null) {
+ list.lastTail = list.lastTail.bind(binds);
+ }
+
+ return list;
}
public OtpErlangObject getLastTail() {
- return lastTail;
+ return lastTail;
}
-
+
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(4);
- final int a = arity();
- if (a == 0) {
- return (int)3468870702L;
- }
- for (int i = 0; i < a; i++) {
- hash.combine(elementAt(i).hashCode());
- }
- final OtpErlangObject t = getLastTail();
- if (t != null) {
- int h = t.hashCode();
- hash.combine(h, h);
- }
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(4);
+ final int a = arity();
+ if (a == 0) {
+ return (int) 3468870702L;
+ }
+ for (int i = 0; i < a; i++) {
+ hash.combine(elementAt(i).hashCode());
+ }
+ final OtpErlangObject t = getLastTail();
+ if (t != null) {
+ final int h = t.hashCode();
+ hash.combine(h, h);
+ }
+ return hash.valueOf();
}
-
+
@Override
public Object clone() {
- try {
- return new OtpErlangList(elements(), getLastTail());
- } catch (final OtpErlangException e) {
- throw new AssertionError(this);
- }
+ try {
+ return new OtpErlangList(elements(), getLastTail());
+ } catch (final OtpErlangException e) {
+ throw new AssertionError(this);
+ }
}
public Iterator<OtpErlangObject> iterator() {
- return iterator(0);
+ return iterator(0);
}
private Iterator<OtpErlangObject> iterator(final int start) {
- return new Itr(start);
+ return new Itr(start);
}
/**
* @return true if the list is proper, i.e. the last tail is nil
*/
public boolean isProper() {
- return lastTail == null;
+ return lastTail == null;
}
public OtpErlangObject getHead() {
- if (arity() > 0) {
- return elems[0];
- }
- return null;
+ if (arity() > 0) {
+ return elems[0];
+ }
+ return null;
}
public OtpErlangObject getTail() {
- return getNthTail(1);
+ return getNthTail(1);
}
public OtpErlangObject getNthTail(final int n) {
- final int arity = arity();
- if (arity >= n) {
- if (arity == n && lastTail != null) {
- return lastTail;
- }
- return new SubList(this, n);
- }
- return null;
+ final int arity = arity();
+ if (arity >= n) {
+ if (arity == n && lastTail != null) {
+ return lastTail;
+ }
+ return new SubList(this, n);
+ }
+ return null;
}
/**
- * Convert a list of integers into a Unicode string,
- * interpreting each integer as a Unicode code point value.
- *
- * @return A java.lang.String object created through its
- * constructor String(int[], int, int).
+ * Convert a list of integers into a Unicode string, interpreting each
+ * integer as a Unicode code point value.
+ *
+ * @return A java.lang.String object created through its constructor
+ * String(int[], int, int).
*
* @exception OtpErlangException
- * for non-proper and non-integer lists.
+ * for non-proper and non-integer lists.
*
* @exception OtpErlangRangeException
- * if any integer does not fit into a Java int.
+ * if any integer does not fit into a Java int.
*
* @exception java.security.InvalidParameterException
- * if any integer is not within the Unicode range.
+ * if any integer is not within the Unicode range.
*
* @see String#String(int[], int, int)
*
*/
public String stringValue() throws OtpErlangException {
- if (! isProper()) {
- throw new OtpErlangException("Non-proper list: " + this);
- }
- final int[] values = new int[arity()];
- for (int i = 0; i < values.length; ++i) {
- final OtpErlangObject o = elementAt(i);
- if (! (o instanceof OtpErlangLong)) {
- throw new OtpErlangException("Non-integer term: " + o);
- }
- final OtpErlangLong l = (OtpErlangLong) o;
- values[i] = l.intValue();
- }
- return new String(values, 0, values.length);
+ if (!isProper()) {
+ throw new OtpErlangException("Non-proper list: " + this);
+ }
+ final int[] values = new int[arity()];
+ for (int i = 0; i < values.length; ++i) {
+ final OtpErlangObject o = elementAt(i);
+ if (!(o instanceof OtpErlangLong)) {
+ throw new OtpErlangException("Non-integer term: " + o);
+ }
+ final OtpErlangLong l = (OtpErlangLong) o;
+ values[i] = l.intValue();
+ }
+ return new String(values, 0, values.length);
}
-
-
public static class SubList extends OtpErlangList {
- private static final long serialVersionUID = OtpErlangList.serialVersionUID;
-
- private final int start;
-
- private final OtpErlangList parent;
-
- private SubList(final OtpErlangList parent, final int start) {
- super();
- this.parent = parent;
- this.start = start;
- }
-
- @Override
- public int arity() {
- return parent.arity() - start;
- }
-
- @Override
- public OtpErlangObject elementAt(final int i) {
- return parent.elementAt(i + start);
- }
-
- @Override
- public OtpErlangObject[] elements() {
- final int n = parent.arity() - start;
- final OtpErlangObject[] res = new OtpErlangObject[n];
- for (int i = 0; i < res.length; i++) {
- res[i] = parent.elementAt(i + start);
- }
- return res;
- }
-
- @Override
- public boolean isProper() {
- return parent.isProper();
- }
-
- @Override
- public OtpErlangObject getHead() {
- return parent.elementAt(start);
- }
-
- @Override
- public OtpErlangObject getNthTail(final int n) {
- return parent.getNthTail(n + start);
- }
-
- @Override
- public String toString() {
- return parent.toString(start);
- }
-
- @Override
- public void encode(final OtpOutputStream stream) {
- parent.encode(stream, start);
- }
-
- @Override
- public OtpErlangObject getLastTail() {
- return parent.getLastTail();
- }
-
- @Override
- public Iterator<OtpErlangObject> iterator() {
- return parent.iterator(start);
- }
+ private static final long serialVersionUID = OtpErlangList.serialVersionUID;
+
+ private final int start;
+
+ private final OtpErlangList parent;
+
+ private SubList(final OtpErlangList parent, final int start) {
+ super();
+ this.parent = parent;
+ this.start = start;
+ }
+
+ @Override
+ public int arity() {
+ return parent.arity() - start;
+ }
+
+ @Override
+ public OtpErlangObject elementAt(final int i) {
+ return parent.elementAt(i + start);
+ }
+
+ @Override
+ public OtpErlangObject[] elements() {
+ final int n = parent.arity() - start;
+ final OtpErlangObject[] res = new OtpErlangObject[n];
+ for (int i = 0; i < res.length; i++) {
+ res[i] = parent.elementAt(i + start);
+ }
+ return res;
+ }
+
+ @Override
+ public boolean isProper() {
+ return parent.isProper();
+ }
+
+ @Override
+ public OtpErlangObject getHead() {
+ return parent.elementAt(start);
+ }
+
+ @Override
+ public OtpErlangObject getNthTail(final int n) {
+ return parent.getNthTail(n + start);
+ }
+
+ @Override
+ public String toString() {
+ return parent.toString(start);
+ }
+
+ @Override
+ public void encode(final OtpOutputStream stream) {
+ parent.encode(stream, start);
+ }
+
+ @Override
+ public OtpErlangObject getLastTail() {
+ return parent.getLastTail();
+ }
+
+ @Override
+ public Iterator<OtpErlangObject> iterator() {
+ return parent.iterator(start);
+ }
}
private class Itr implements Iterator<OtpErlangObject> {
- /**
- * Index of element to be returned by subsequent call to next.
- */
- private int cursor;
-
- private Itr(final int cursor) {
- this.cursor = cursor;
- }
-
- public boolean hasNext() {
- return cursor < elems.length;
- }
-
- public OtpErlangObject next() {
- try {
- return elems[cursor++];
- } catch (final IndexOutOfBoundsException e) {
- throw new NoSuchElementException();
- }
- }
-
- public void remove() {
- throw new UnsupportedOperationException(
- "OtpErlangList cannot be modified!");
- }
+ /**
+ * Index of element to be returned by subsequent call to next.
+ */
+ private int cursor;
+
+ private Itr(final int cursor) {
+ this.cursor = cursor;
+ }
+
+ public boolean hasNext() {
+ return cursor < elems.length;
+ }
+
+ public OtpErlangObject next() {
+ try {
+ return elems[cursor++];
+ } catch (final IndexOutOfBoundsException e) {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException(
+ "OtpErlangList cannot be modified!");
+ }
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
index c6021a6ae1..4bcae63519 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -23,11 +24,11 @@ import java.math.BigInteger;
/**
* Provides a Java representation of Erlang integral types. Erlang does not
* distinguish between different integral types, however this class and its
- * subclasses {@link OtpErlangByte}, {@link OtpErlangChar},
- * {@link OtpErlangInt}, and {@link OtpErlangShort} attempt to map the Erlang
- * types onto the various Java integral types. Two additional classes,
- * {@link OtpErlangUInt} and {@link OtpErlangUShort} are provided for Corba
- * compatibility. See the documentation for IC for more information.
+ * subclasses {@link OtpErlangByte}, {@link OtpErlangChar}, {@link OtpErlangInt}
+ * , and {@link OtpErlangShort} attempt to map the Erlang types onto the various
+ * Java integral types. Two additional classes, {@link OtpErlangUInt} and
+ * {@link OtpErlangUShort} are provided for Corba compatibility. See the
+ * documentation for IC for more information.
*/
public class OtpErlangLong extends OtpErlangObject {
// don't change this!
@@ -38,354 +39,353 @@ public class OtpErlangLong extends OtpErlangObject {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param l
- * the long value to use.
+ * the long value to use.
*/
public OtpErlangLong(final long l) {
- val = l;
+ val = l;
}
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param v
- * the big integer value to use.
+ * the big integer value to use.
*/
public OtpErlangLong(final BigInteger v) {
- if (v == null) {
- throw new java.lang.NullPointerException();
- }
- if (v.bitLength() < 64) {
- val = v.longValue();
- } else {
- bigVal = v;
- }
+ if (v == null) {
+ throw new java.lang.NullPointerException();
+ }
+ if (v.bitLength() < 64) {
+ val = v.longValue();
+ } else {
+ bigVal = v;
+ }
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
*/
public OtpErlangLong(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final byte[] b = buf.read_integer_byte_array();
- try {
- val = OtpInputStream.byte_array_to_long(b, false);
- } catch (final OtpErlangDecodeException e) {
- bigVal = new BigInteger(b);
- }
+ throws OtpErlangDecodeException {
+ final byte[] b = buf.read_integer_byte_array();
+ try {
+ val = OtpInputStream.byte_array_to_long(b, false);
+ } catch (final OtpErlangDecodeException e) {
+ bigVal = new BigInteger(b);
+ }
}
/**
* Get this number as a BigInteger.
- *
+ *
* @return the value of this number, as a BigInteger.
*/
public BigInteger bigIntegerValue() {
- if (bigVal != null) {
- return bigVal;
- }
- return BigInteger.valueOf(val);
+ if (bigVal != null) {
+ return bigVal;
+ }
+ return BigInteger.valueOf(val);
}
/**
* Get this number as a long, or rather truncate all but the least
* significant 64 bits from the 2's complement representation of this number
* and return them as a long.
- *
+ *
* @return the value of this number, as a long.
*/
public long longValue() {
- if (bigVal != null) {
- return bigVal.longValue();
- }
- return val;
+ if (bigVal != null) {
+ return bigVal.longValue();
+ }
+ return val;
}
/**
* Determine if this value can be represented as a long without truncation.
- *
+ *
* @return true if this value fits in a long, false otherwise.
*/
public boolean isLong() {
- // To just chech this.bigVal is a wee bit to simple, since
- // there just might have be a mean bignum that arrived on
- // a stream, and was a long disguised as more than 8 byte integer.
- if (bigVal != null) {
- return bigVal.bitLength() < 64;
- }
- return true;
+ // To just chech this.bigVal is a wee bit to simple, since
+ // there just might have be a mean bignum that arrived on
+ // a stream, and was a long disguised as more than 8 byte integer.
+ if (bigVal != null) {
+ return bigVal.bitLength() < 64;
+ }
+ return true;
}
/**
* Determine if this value can be represented as an unsigned long without
* truncation, that is if the value is non-negative and its bit pattern
* completely fits in a long.
- *
+ *
* @return true if this value is non-negative and fits in a long false
* otherwise.
*/
public boolean isULong() {
- // Here we have the same problem as for isLong(), plus
- // the whole range 1<<63 .. (1<<64-1) is allowed.
- if (bigVal != null) {
- return bigVal.signum() >= 0 && bigVal.bitLength() <= 64;
- }
- return val >= 0;
+ // Here we have the same problem as for isLong(), plus
+ // the whole range 1<<63 .. (1<<64-1) is allowed.
+ if (bigVal != null) {
+ return bigVal.signum() >= 0 && bigVal.bitLength() <= 64;
+ }
+ return val >= 0;
}
/**
* Returns the number of bits in the minimal two's-complement representation
* of this BigInteger, excluding a sign bit.
- *
+ *
* @return number of bits in the minimal two's-complement representation of
* this BigInteger, excluding a sign bit.
*/
public int bitLength() {
- if (bigVal != null) {
- return bigVal.bitLength();
- }
- if (val == 0 || val == -1) {
- return 0;
+ if (bigVal != null) {
+ return bigVal.bitLength();
+ }
+ if (val == 0 || val == -1) {
+ return 0;
+ }
+ // Binary search for bit length
+ int i = 32; // mask length
+ long m = (1L << i) - 1; // AND mask with ones in little end
+ if (val < 0) {
+ m = ~m; // OR mask with ones in big end
+ for (int j = i >> 1; j > 0; j >>= 1) { // mask delta
+ if ((val | m) == val) { // mask >= enough
+ i -= j;
+ m >>= j; // try less bits
+ } else {
+ i += j;
+ m <<= j; // try more bits
+ }
+ }
+ if ((val | m) != val) {
+ i++; // mask < enough
+ }
+ } else {
+ for (int j = i >> 1; j > 0; j >>= 1) { // mask delta
+ if ((val & m) == val) { // mask >= enough
+ i -= j;
+ m >>= j; // try less bits
+ } else {
+ i += j;
+ m = m << j | m; // try more bits
+ }
+ }
+ if ((val & m) != val) {
+ i++; // mask < enough
+ }
+ }
+ return i;
}
- // Binary search for bit length
- int i = 32; // mask length
- long m = (1L << i) - 1; // AND mask with ones in little end
- if (val < 0) {
- m = ~m; // OR mask with ones in big end
- for (int j = i >> 1; j > 0; j >>= 1) { // mask delta
- if ((val | m) == val) { // mask >= enough
- i -= j;
- m >>= j; // try less bits
- } else {
- i += j;
- m <<= j; // try more bits
- }
- }
- if ((val | m) != val) {
- i++; // mask < enough
- }
- } else {
- for (int j = i >> 1; j > 0; j >>= 1) { // mask delta
- if ((val & m) == val) { // mask >= enough
- i -= j;
- m >>= j; // try less bits
- } else {
- i += j;
- m = m << j | m; // try more bits
- }
- }
- if ((val & m) != val) {
- i++; // mask < enough
- }
- }
- return i;
- }
/**
* Return the signum function of this object.
- *
+ *
* @return -1, 0 or 1 as the value is negative, zero or positive.
*/
public int signum() {
- if (bigVal != null) {
- return bigVal.signum();
- }
- return val > 0 ? 1 : val < 0 ? -1 : 0;
+ if (bigVal != null) {
+ return bigVal.signum();
+ }
+ return val > 0 ? 1 : val < 0 ? -1 : 0;
}
/**
* Get this number as an int.
- *
+ *
* @return the value of this number, as an int.
- *
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as an int.
+ * if the value is too large to be represented as an int.
*/
public int intValue() throws OtpErlangRangeException {
- final long l = longValue();
- final int i = (int) l;
+ final long l = longValue();
+ final int i = (int) l;
- if (i != l) {
- throw new OtpErlangRangeException("Value too large for int: " + val);
- }
+ if (i != l) {
+ throw new OtpErlangRangeException("Value too large for int: " + val);
+ }
- return i;
+ return i;
}
/**
* Get this number as a non-negative int.
- *
+ *
* @return the value of this number, as an int.
- *
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as an int,
- * or if the value is negative.
+ * if the value is too large to be represented as an int, or
+ * if the value is negative.
*/
public int uIntValue() throws OtpErlangRangeException {
- final long l = longValue();
- final int i = (int) l;
+ final long l = longValue();
+ final int i = (int) l;
- if (i != l) {
- throw new OtpErlangRangeException("Value too large for int: " + val);
- } else if (i < 0) {
- throw new OtpErlangRangeException("Value not positive: " + val);
- }
+ if (i != l) {
+ throw new OtpErlangRangeException("Value too large for int: " + val);
+ } else if (i < 0) {
+ throw new OtpErlangRangeException("Value not positive: " + val);
+ }
- return i;
+ return i;
}
/**
* Get this number as a short.
- *
+ *
* @return the value of this number, as a short.
- *
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a
- * short.
+ * if the value is too large to be represented as a short.
*/
public short shortValue() throws OtpErlangRangeException {
- final long l = longValue();
- final short i = (short) l;
+ final long l = longValue();
+ final short i = (short) l;
- if (i != l) {
- throw new OtpErlangRangeException("Value too large for short: "
- + val);
- }
+ if (i != l) {
+ throw new OtpErlangRangeException("Value too large for short: "
+ + val);
+ }
- return i;
+ return i;
}
/**
* Get this number as a non-negative short.
- *
+ *
* @return the value of this number, as a short.
- *
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a
- * short, or if the value is negative.
+ * if the value is too large to be represented as a short, or
+ * if the value is negative.
*/
public short uShortValue() throws OtpErlangRangeException {
- final long l = longValue();
- final short i = (short) l;
+ final long l = longValue();
+ final short i = (short) l;
- if (i != l) {
- throw new OtpErlangRangeException("Value too large for short: "
- + val);
- } else if (i < 0) {
- throw new OtpErlangRangeException("Value not positive: " + val);
- }
+ if (i != l) {
+ throw new OtpErlangRangeException("Value too large for short: "
+ + val);
+ } else if (i < 0) {
+ throw new OtpErlangRangeException("Value not positive: " + val);
+ }
- return i;
+ return i;
}
/**
* Get this number as a char.
- *
+ *
* @return the char value of this number.
- *
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a char.
+ * if the value is too large to be represented as a char.
*/
public char charValue() throws OtpErlangRangeException {
- final long l = longValue();
- final char i = (char) l;
+ final long l = longValue();
+ final char i = (char) l;
- if (i != l) {
- throw new OtpErlangRangeException("Value too large for char: "
- + val);
- }
+ if (i != l) {
+ throw new OtpErlangRangeException("Value too large for char: "
+ + val);
+ }
- return i;
+ return i;
}
/**
* Get this number as a byte.
- *
+ *
* @return the byte value of this number.
- *
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a byte.
+ * if the value is too large to be represented as a byte.
*/
public byte byteValue() throws OtpErlangRangeException {
- final long l = longValue();
- final byte i = (byte) l;
+ final long l = longValue();
+ final byte i = (byte) l;
- if (i != l) {
- throw new OtpErlangRangeException("Value too large for byte: "
- + val);
- }
+ if (i != l) {
+ throw new OtpErlangRangeException("Value too large for byte: "
+ + val);
+ }
- return i;
+ return i;
}
/**
* Get the string representation of this number.
- *
+ *
* @return the string representation of this number.
*/
@Override
public String toString() {
- if (bigVal != null) {
- return "" + bigVal;
- }
- return "" + val;
+ if (bigVal != null) {
+ return "" + bigVal;
+ }
+ return "" + val;
}
/**
* Convert this number to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded number should be
- * written.
+ * an output stream to which the encoded number should be
+ * written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- if (bigVal != null) {
- buf.write_big_integer(bigVal);
- } else {
- buf.write_long(val);
- }
+ if (bigVal != null) {
+ buf.write_big_integer(bigVal);
+ } else {
+ buf.write_long(val);
+ }
}
/**
* Determine if two numbers are equal. Numbers are equal if they contain the
* same value.
- *
+ *
* @param o
- * the number to compare to.
- *
+ * the number to compare to.
+ *
* @return true if the numbers have the same value.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangLong)) {
- return false;
- }
-
- final OtpErlangLong that = (OtpErlangLong) o;
-
- if (bigVal != null && that.bigVal != null) {
- return bigVal.equals(that.bigVal);
- } else if (bigVal == null && that.bigVal == null) {
- return val == that.val;
- }
- return false;
+ if (!(o instanceof OtpErlangLong)) {
+ return false;
+ }
+
+ final OtpErlangLong that = (OtpErlangLong) o;
+
+ if (bigVal != null && that.bigVal != null) {
+ return bigVal.equals(that.bigVal);
+ } else if (bigVal == null && that.bigVal == null) {
+ return val == that.val;
+ }
+ return false;
}
-
+
@Override
protected int doHashCode() {
- if (bigVal != null) {
- return bigVal.hashCode();
- }
- return BigInteger.valueOf(val).hashCode();
+ if (bigVal != null) {
+ return bigVal.hashCode();
+ }
+ return BigInteger.valueOf(val).hashCode();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
index 7f1a64b87d..30126db3fd 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
@@ -3,59 +3,77 @@
*
* Copyright Ericsson AB 2000-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
package com.ericsson.otp.erlang;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
/**
* Provides a Java representation of Erlang maps. Maps are created from one or
* more arbitrary Erlang terms.
- *
+ *
* <p>
* The arity of the map is the number of elements it contains. The keys and
* values can be retrieved as arrays and the value for a key can be queried.
- *
+ *
*/
public class OtpErlangMap extends OtpErlangObject {
// don't change this!
private static final long serialVersionUID = -6410770117696198497L;
- private static final OtpErlangObject[] NO_ELEMENTS = new OtpErlangObject[0];
+ private OtpMap map;
+
+ private static class OtpMap
+ extends LinkedHashMap<OtpErlangObject, OtpErlangObject> {
+ private static final long serialVersionUID = -2666505810905455082L;
+
+ public OtpMap() {
+ super();
+ }
+ }
- private OtpErlangObject[] keys = NO_ELEMENTS;
- private OtpErlangObject[] values = NO_ELEMENTS;
+ /**
+ * Create an empty map.
+ */
+ public OtpErlangMap() {
+ map = new OtpMap();
+ }
/**
* Create a map from an array of keys and an array of values.
- *
+ *
* @param keys
* the array of terms to create the map keys from.
* @param values
* the array of terms to create the map values from.
- *
+ *
* @exception java.lang.IllegalArgumentException
* if any array is empty (null) or contains null elements.
*/
public OtpErlangMap(final OtpErlangObject[] keys,
- final OtpErlangObject[] values) {
- this(keys, 0, keys.length, values, 0, values.length);
+ final OtpErlangObject[] values) {
+ this(keys, 0, keys.length, values, 0, values.length);
}
/**
* Create a map from an array of terms.
- *
+ *
* @param keys
* the array of terms to create the map from.
* @param kstart
@@ -68,228 +86,280 @@ public class OtpErlangMap extends OtpErlangObject {
* the offset of the first value to insert.
* @param vcount
* the number of values to insert.
- *
+ *
* @exception java.lang.IllegalArgumentException
* if any array is empty (null) or contains null elements.
* @exception java.lang.IllegalArgumentException
* if kcount and vcount differ.
*/
public OtpErlangMap(final OtpErlangObject[] keys, final int kstart,
- final int kcount, final OtpErlangObject[] values, final int vstart,
- final int vcount) {
- if (keys == null || values == null) {
- throw new java.lang.IllegalArgumentException(
- "Map content can't be null");
- } else if (kcount != vcount) {
- throw new java.lang.IllegalArgumentException(
- "Map keys and values must have same arity");
- } else if (vcount < 1) {
- this.keys = NO_ELEMENTS;
- this.values = NO_ELEMENTS;
- } else {
- this.keys = new OtpErlangObject[vcount];
- for (int i = 0; i < vcount; i++) {
- if (keys[kstart + i] != null) {
- this.keys[i] = keys[kstart + i];
- } else {
- throw new java.lang.IllegalArgumentException(
- "Map key cannot be null (element" + (kstart + i)
- + ")");
- }
- }
- this.values = new OtpErlangObject[vcount];
- for (int i = 0; i < vcount; i++) {
- if (values[vstart + i] != null) {
- this.values[i] = values[vstart + i];
- } else {
- throw new java.lang.IllegalArgumentException(
- "Map value cannot be null (element" + (vstart + i)
- + ")");
- }
- }
- }
+ final int kcount, final OtpErlangObject[] values, final int vstart,
+ final int vcount) {
+ if (keys == null || values == null) {
+ throw new java.lang.IllegalArgumentException(
+ "Map content can't be null");
+ } else if (kcount != vcount) {
+ throw new java.lang.IllegalArgumentException(
+ "Map keys and values must have same arity");
+ }
+ map = new OtpMap();
+ OtpErlangObject key, val;
+ for (int i = 0; i < vcount; i++) {
+ if ((key = keys[kstart + i]) == null) {
+ throw new java.lang.IllegalArgumentException(
+ "Map key cannot be null (element" + (kstart + i) + ")");
+ }
+ if ((val = values[vstart + i]) == null) {
+ throw new java.lang.IllegalArgumentException(
+ "Map value cannot be null (element" + (vstart + i)
+ + ")");
+ }
+ put(key, val);
+ }
}
/**
* Create a map from a stream containing a map encoded in Erlang external
* format.
- *
+ *
* @param buf
* the stream containing the encoded map.
- *
+ *
* @exception OtpErlangDecodeException
* if the buffer does not contain a valid external
* representation of an Erlang map.
*/
public OtpErlangMap(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final int arity = buf.read_map_head();
-
- if (arity > 0) {
- keys = new OtpErlangObject[arity];
- values = new OtpErlangObject[arity];
-
- for (int i = 0; i < arity; i++) {
- keys[i] = buf.read_any();
- values[i] = buf.read_any();
- }
- } else {
- keys = NO_ELEMENTS;
- values = NO_ELEMENTS;
- }
+ throws OtpErlangDecodeException {
+ final int arity = buf.read_map_head();
+
+ if (arity > 0) {
+ map = new OtpMap();
+ for (int i = 0; i < arity; i++) {
+ OtpErlangObject key, val;
+ key = buf.read_any();
+ val = buf.read_any();
+ put(key, val);
+ }
+ } else {
+ map = new OtpMap();
+ }
}
/**
* Get the arity of the map.
- *
+ *
* @return the number of elements contained in the map.
*/
public int arity() {
- return keys.length;
+ return map.size();
+ }
+
+ /**
+ * Put value corresponding to key into the map. For detailed behavior
+ * description see {@link Map#put(Object, Object)}.
+ *
+ * @param key
+ * key to associate value with
+ * @param value
+ * value to associate with key
+ * @return previous value associated with key or null
+ */
+ public OtpErlangObject put(final OtpErlangObject key,
+ final OtpErlangObject value) {
+ return map.put(key, value);
+ }
+
+ /**
+ * removes mapping for the key if present.
+ *
+ * @param key
+ * key for which mapping is to be remove
+ * @return value associated with key or null
+ */
+ public OtpErlangObject remove(final OtpErlangObject key) {
+ return map.remove(key);
}
/**
* Get the specified value from the map.
- *
+ *
* @param key
* the key of the requested value.
- *
+ *
* @return the requested value, of null if key is not a valid key.
*/
public OtpErlangObject get(final OtpErlangObject key) {
- if (key == null) {
- return null;
- }
- for (int i = 0; i < keys.length; i++) {
- if (key.equals(keys[i])) {
- return values[i];
- }
- }
- return null;
+ return map.get(key);
}
/**
* Get all the keys from the map as an array.
- *
+ *
* @return an array containing all of the map's keys.
*/
public OtpErlangObject[] keys() {
- final OtpErlangObject[] res = new OtpErlangObject[arity()];
- System.arraycopy(keys, 0, res, 0, res.length);
- return res;
+ return map.keySet().toArray(new OtpErlangObject[arity()]);
}
/**
* Get all the values from the map as an array.
- *
+ *
* @return an array containing all of the map's values.
*/
public OtpErlangObject[] values() {
- final OtpErlangObject[] res = new OtpErlangObject[arity()];
- System.arraycopy(values, 0, res, 0, res.length);
- return res;
+ return map.values().toArray(new OtpErlangObject[arity()]);
+ }
+
+ /**
+ * make Set view of the map key-value pairs
+ *
+ * @return a set containing key-value pairs
+ */
+ public Set<Entry<OtpErlangObject, OtpErlangObject>> entrySet() {
+ return map.entrySet();
}
/**
* Get the string representation of the map.
- *
+ *
* @return the string representation of the map.
*/
@Override
public String toString() {
- int i;
- final StringBuffer s = new StringBuffer();
- final int arity = values.length;
+ final StringBuffer s = new StringBuffer();
- s.append("#{");
+ s.append("#{");
- for (i = 0; i < arity; i++) {
- if (i > 0) {
- s.append(",");
- }
- s.append(keys[i].toString());
- s.append(" => ");
- s.append(values[i].toString());
- }
+ boolean first = true;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ if (first) {
+ first = false;
+ } else {
+ s.append(",");
+ }
+ s.append(e.getKey().toString());
+ s.append(" => ");
+ s.append(e.getValue().toString());
+ }
- s.append("}");
+ s.append("}");
- return s.toString();
+ return s.toString();
}
/**
* Convert this map to the equivalent Erlang external representation.
- *
+ *
* @param buf
* an output stream to which the encoded map should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- final int arity = values.length;
+ final int arity = arity();
- buf.write_map_head(arity);
+ buf.write_map_head(arity);
- for (int i = 0; i < arity; i++) {
- buf.write_any(keys[i]);
- buf.write_any(values[i]);
- }
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ buf.write_any(e.getKey());
+ buf.write_any(e.getValue());
+ }
}
/**
* Determine if two maps are equal. Maps are equal if they have the same
* arity and all of the elements are equal.
- *
+ *
* @param o
* the map to compare to.
- *
+ *
* @return true if the maps have the same arity and all the elements are
* equal.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangMap)) {
- return false;
- }
-
- final OtpErlangMap t = (OtpErlangMap) o;
- final int a = arity();
-
- if (a != t.arity()) {
- return false;
- }
-
- for (int i = 0; i < a; i++) {
- if (!keys[i].equals(t.keys[i])) {
- return false; // early exit
- }
- }
- for (int i = 0; i < a; i++) {
- if (!values[i].equals(t.values[i])) {
- return false; // early exit
- }
- }
-
- return true;
+ if (!(o instanceof OtpErlangMap)) {
+ return false;
+ }
+
+ final OtpErlangMap t = (OtpErlangMap) o;
+ final int a = arity();
+
+ if (a != t.arity()) {
+ return false;
+ }
+ if (a == 0) {
+ return true;
+ }
+
+ OtpErlangObject key, val;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ key = e.getKey();
+ val = e.getValue();
+ final OtpErlangObject v = t.get(key);
+ if (v == null || !val.equals(v)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T binds) {
+ if (!(term instanceof OtpErlangMap)) {
+ return false;
+ }
+
+ final OtpErlangMap t = (OtpErlangMap) term;
+ final int a = arity();
+
+ if (a > t.arity()) {
+ return false;
+ }
+ if (a == 0) {
+ return true;
+ }
+
+ OtpErlangObject key, val;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ key = e.getKey();
+ val = e.getValue();
+ final OtpErlangObject v = t.get(key);
+ if (v == null || !val.match(v, binds)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ final OtpErlangMap ret = new OtpErlangMap();
+
+ OtpErlangObject key, val;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ key = e.getKey();
+ val = e.getValue();
+ ret.put(key, val.bind(binds));
+ }
+
+ return ret;
}
@Override
protected int doHashCode() {
- final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
- final int a = arity();
- hash.combine(a);
- for (int i = 0; i < a; i++) {
- hash.combine(keys[i].hashCode());
- }
- for (int i = 0; i < a; i++) {
- hash.combine(values[i].hashCode());
- }
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
+ hash.combine(map.hashCode());
+ return hash.valueOf();
}
@Override
+ @SuppressWarnings("unchecked")
public Object clone() {
- final OtpErlangMap newMap = (OtpErlangMap) super.clone();
- newMap.values = values.clone();
- return newMap;
+ final OtpErlangMap newMap = (OtpErlangMap) super.clone();
+ newMap.map = (OtpMap) map.clone();
+ return newMap;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
index 5215e5887b..68e438cd27 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -26,7 +27,7 @@ import java.io.Serializable;
*/
public abstract class OtpErlangObject implements Serializable, Cloneable {
protected int hashCodeValue = 0;
-
+
// don't change this!
static final long serialVersionUID = -8435938572339430044L;
@@ -42,10 +43,9 @@ public abstract class OtpErlangObject implements Serializable, Cloneable {
* Convert the object according to the rules of the Erlang external format.
* This is mainly used for sending Erlang terms in messages, however it can
* also be used for storing terms to disk.
- *
+ *
* @param buf
- * an output stream to which the encoded term should be
- * written.
+ * an output stream to which the encoded term should be written.
*/
public abstract void encode(OtpOutputStream buf);
@@ -54,137 +54,176 @@ public abstract class OtpErlangObject implements Serializable, Cloneable {
* corresponding Erlang data type object. This method is normally used when
* Erlang terms are received in messages, however it can also be used for
* reading terms from disk.
- *
+ *
* @param buf
- * an input stream containing one or more encoded Erlang
- * terms.
- *
+ * an input stream containing one or more encoded Erlang terms.
+ *
* @return an object representing one of the Erlang data types.
- *
+ *
* @exception OtpErlangDecodeException
- * if the stream does not contain a valid representation
- * of an Erlang term.
+ * if the stream does not contain a valid representation of
+ * an Erlang term.
*/
public static OtpErlangObject decode(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- return buf.read_any();
+ throws OtpErlangDecodeException {
+ return buf.read_any();
}
/**
* Determine if two Erlang objects are equal. In general, Erlang objects are
* equal if the components they consist of are equal.
- *
+ *
* @param o
- * the object to compare to.
- *
+ * the object to compare to.
+ *
* @return true if the objects are identical.
*/
@Override
public abstract boolean equals(Object o);
-
+
+ /**
+ * Perform match operation against given term.
+ *
+ * @param term
+ * the object to match
+ * @param binds
+ * variable bindings
+ * @return true if match succeeded
+ */
+ public <T> boolean match(final OtpErlangObject term, final T binds) {
+ return equals(term);
+ }
+
+ /**
+ * Make new Erlang term replacing variables with the respective values from
+ * bindings argument(s).
+ *
+ * @param binds
+ * variable bindings
+ * @return new term
+ * @throws OtpErlangException
+ */
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ return this;
+ }
+
@Override
public int hashCode() {
- if (hashCodeValue == 0) {
- hashCodeValue = doHashCode();
- }
- return hashCodeValue;
+ if (hashCodeValue == 0) {
+ hashCodeValue = doHashCode();
+ }
+ return hashCodeValue;
}
-
+
protected int doHashCode() {
- return super.hashCode();
+ return super.hashCode();
}
-
+
@Override
public Object clone() {
- try {
- return super.clone();
- } catch (final CloneNotSupportedException e) {
- /* cannot happen */
- throw new InternalError(e.toString());
- }
+ try {
+ return super.clone();
+ } catch (final CloneNotSupportedException e) {
+ /* cannot happen */
+ throw new InternalError(e.toString());
+ }
}
protected final static class Hash {
- int abc[] = {0, 0, 0};
-
- /* Hash function suggested by Bob Jenkins.
- * The same as in the Erlang VM (beam); utils.c.
- */
-
- private final static int HASH_CONST[] = {
- 0, // not used
- 0x9e3779b9, // the golden ratio; an arbitrary value
- 0x3c6ef372, // (hashHConst[1] * 2) % (1<<32)
- 0xdaa66d2b, // 1 3
- 0x78dde6e4, // 1 4
- 0x1715609d, // 1 5
- 0xb54cda56, // 1 6
- 0x5384540f, // 1 7
- 0xf1bbcdc8, // 1 8
- 0x8ff34781, // 1 9
- 0x2e2ac13a, // 1 10
- 0xcc623af3, // 1 11
- 0x6a99b4ac, // 1 12
- 0x08d12e65, // 1 13
- 0xa708a81e, // 1 14
- 0x454021d7, // 1 15
- };
-
- protected Hash(int i) {
- abc[0] = abc[1] = HASH_CONST[i];
- abc[2] = 0;
- }
-
- //protected Hash() {
- // Hash(1);
- //}
-
- private void mix() {
- abc[0] -= abc[1]; abc[0] -= abc[2]; abc[0] ^= (abc[2]>>>13);
- abc[1] -= abc[2]; abc[1] -= abc[0]; abc[1] ^= (abc[0]<<8);
- abc[2] -= abc[0]; abc[2] -= abc[1]; abc[2] ^= (abc[1]>>>13);
- abc[0] -= abc[1]; abc[0] -= abc[2]; abc[0] ^= (abc[2]>>>12);
- abc[1] -= abc[2]; abc[1] -= abc[0]; abc[1] ^= (abc[0]<<16);
- abc[2] -= abc[0]; abc[2] -= abc[1]; abc[2] ^= (abc[1]>>>5);
- abc[0] -= abc[1]; abc[0] -= abc[2]; abc[0] ^= (abc[2]>>>3);
- abc[1] -= abc[2]; abc[1] -= abc[0]; abc[1] ^= (abc[0]<<10);
- abc[2] -= abc[0]; abc[2] -= abc[1]; abc[2] ^= (abc[1]>>>15);
- }
-
- protected void combine(int a) {
- abc[0] += a;
- mix();
- }
-
- protected void combine(long a) {
- combine((int)(a >>> 32), (int) a);
- }
-
- protected void combine(int a, int b) {
- abc[0] += a;
- abc[1] += b;
- mix();
- }
-
- protected void combine(byte b[]) {
- int j, k;
- for (j = 0, k = 0;
- j + 4 < b.length;
- j += 4, k += 1, k %= 3) {
- abc[k] += (b[j+0] & 0xFF) + (b[j+1]<<8 & 0xFF00)
- + (b[j+2]<<16 & 0xFF0000) + (b[j+3]<<24);
- mix();
- }
- for (int n = 0, m = 0xFF;
- j < b.length;
- j++, n += 8, m <<= 8) {
- abc[k] += b[j]<<n & m;
- }
- mix();
- }
-
- protected int valueOf() {
- return abc[2];
- }
+ int abc[] = { 0, 0, 0 };
+
+ /*
+ * Hash function suggested by Bob Jenkins. The same as in the Erlang VM
+ * (beam); utils.c.
+ */
+
+ private final static int HASH_CONST[] = { 0, // not used
+ 0x9e3779b9, // the golden ratio; an arbitrary value
+ 0x3c6ef372, // (hashHConst[1] * 2) % (1<<32)
+ 0xdaa66d2b, // 1 3
+ 0x78dde6e4, // 1 4
+ 0x1715609d, // 1 5
+ 0xb54cda56, // 1 6
+ 0x5384540f, // 1 7
+ 0xf1bbcdc8, // 1 8
+ 0x8ff34781, // 1 9
+ 0x2e2ac13a, // 1 10
+ 0xcc623af3, // 1 11
+ 0x6a99b4ac, // 1 12
+ 0x08d12e65, // 1 13
+ 0xa708a81e, // 1 14
+ 0x454021d7, // 1 15
+ };
+
+ protected Hash(final int i) {
+ abc[0] = abc[1] = HASH_CONST[i];
+ abc[2] = 0;
+ }
+
+ // protected Hash() {
+ // Hash(1);
+ // }
+
+ private void mix() {
+ abc[0] -= abc[1];
+ abc[0] -= abc[2];
+ abc[0] ^= abc[2] >>> 13;
+ abc[1] -= abc[2];
+ abc[1] -= abc[0];
+ abc[1] ^= abc[0] << 8;
+ abc[2] -= abc[0];
+ abc[2] -= abc[1];
+ abc[2] ^= abc[1] >>> 13;
+ abc[0] -= abc[1];
+ abc[0] -= abc[2];
+ abc[0] ^= abc[2] >>> 12;
+ abc[1] -= abc[2];
+ abc[1] -= abc[0];
+ abc[1] ^= abc[0] << 16;
+ abc[2] -= abc[0];
+ abc[2] -= abc[1];
+ abc[2] ^= abc[1] >>> 5;
+ abc[0] -= abc[1];
+ abc[0] -= abc[2];
+ abc[0] ^= abc[2] >>> 3;
+ abc[1] -= abc[2];
+ abc[1] -= abc[0];
+ abc[1] ^= abc[0] << 10;
+ abc[2] -= abc[0];
+ abc[2] -= abc[1];
+ abc[2] ^= abc[1] >>> 15;
+ }
+
+ protected void combine(final int a) {
+ abc[0] += a;
+ mix();
+ }
+
+ protected void combine(final long a) {
+ combine((int) (a >>> 32), (int) a);
+ }
+
+ protected void combine(final int a, final int b) {
+ abc[0] += a;
+ abc[1] += b;
+ mix();
+ }
+
+ protected void combine(final byte b[]) {
+ int j, k;
+ for (j = 0, k = 0; j + 4 < b.length; j += 4, k += 1, k %= 3) {
+ abc[k] += (b[j + 0] & 0xFF) + (b[j + 1] << 8 & 0xFF00)
+ + (b[j + 2] << 16 & 0xFF0000) + (b[j + 3] << 24);
+ mix();
+ }
+ for (int n = 0, m = 0xFF; j < b.length; j++, n += 8, m <<= 8) {
+ abc[k] += b[j] << n & m;
+ }
+ mix();
+ }
+
+ protected int valueOf() {
+ return abc[2];
+ }
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
index 4c9f5c78a3..20b7ff6a7f 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang PIDs. PIDs represent Erlang
* processes and consist of a nodename and a number of integers.
@@ -34,172 +34,170 @@ public class OtpErlangPid extends OtpErlangObject implements Comparable<Object>
/**
* Create a unique Erlang PID belonging to the local node.
- *
+ *
* @param self
- * the local node.
- *
+ * the local node.
+ *
* @deprecated use OtpLocalNode:createPid() instead
*/
@Deprecated
public OtpErlangPid(final OtpLocalNode self) {
- final OtpErlangPid p = self.createPid();
+ final OtpErlangPid p = self.createPid();
- id = p.id;
- serial = p.serial;
- creation = p.creation;
- node = p.node;
+ id = p.id;
+ serial = p.serial;
+ creation = p.creation;
+ node = p.node;
}
/**
* Create an Erlang PID from a stream containing a PID encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded PID.
- *
+ * the stream containing the encoded PID.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang PID.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang PID.
*/
public OtpErlangPid(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final OtpErlangPid p = buf.read_pid();
+ throws OtpErlangDecodeException {
+ final OtpErlangPid p = buf.read_pid();
- node = p.node();
- id = p.id();
- serial = p.serial();
- creation = p.creation();
+ node = p.node();
+ id = p.id();
+ serial = p.serial();
+ creation = p.creation();
}
/**
* Create an Erlang pid from its components.
- *
+ *
* @param node
- * the nodename.
- *
+ * the nodename.
+ *
* @param id
- * an arbitrary number. Only the low order 15 bits will be
- * used.
- *
+ * an arbitrary number. Only the low order 15 bits will be used.
+ *
* @param serial
- * another arbitrary number. Only the low order 13 bits will
- * be used.
- *
+ * another arbitrary number. Only the low order 13 bits will be
+ * used.
+ *
* @param creation
- * yet another arbitrary number. Only the low order 2 bits
- * will be used.
+ * yet another arbitrary number. Only the low order 2 bits will
+ * be used.
*/
public OtpErlangPid(final String node, final int id, final int serial,
- final int creation) {
- this.node = node;
- this.id = id & 0x7fff; // 15 bits
- this.serial = serial & 0x1fff; // 13 bits
- this.creation = creation & 0x03; // 2 bits
+ final int creation) {
+ this.node = node;
+ this.id = id & 0x7fff; // 15 bits
+ this.serial = serial & 0x1fff; // 13 bits
+ this.creation = creation & 0x03; // 2 bits
}
/**
* Get the serial number from the PID.
- *
+ *
* @return the serial number from the PID.
*/
public int serial() {
- return serial;
+ return serial;
}
/**
* Get the id number from the PID.
- *
+ *
* @return the id number from the PID.
*/
public int id() {
- return id;
+ return id;
}
/**
* Get the creation number from the PID.
- *
+ *
* @return the creation number from the PID.
*/
public int creation() {
- return creation;
+ return creation;
}
/**
* Get the node name from the PID.
- *
+ *
* @return the node name from the PID.
*/
public String node() {
- return node;
+ return node;
}
/**
* Get the string representation of the PID. Erlang PIDs are printed as
* #Pid&lt;node.id.serial&gt;
- *
+ *
* @return the string representation of the PID.
*/
@Override
public String toString() {
- return "#Pid<" + node.toString() + "." + id + "." + serial + ">";
+ return "#Pid<" + node.toString() + "." + id + "." + serial + ">";
}
/**
* Convert this PID to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded PID should be
- * written.
+ * an output stream to which the encoded PID should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_pid(node, id, serial, creation);
+ buf.write_pid(node, id, serial, creation);
}
/**
* Determine if two PIDs are equal. PIDs are equal if their components are
* equal.
- *
+ *
* @param o
- * the other PID to compare to.
- *
+ * the other PID to compare to.
+ *
* @return true if the PIDs are equal, false otherwise.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangPid)) {
- return false;
- }
+ if (!(o instanceof OtpErlangPid)) {
+ return false;
+ }
- final OtpErlangPid pid = (OtpErlangPid) o;
+ final OtpErlangPid pid = (OtpErlangPid) o;
- return creation == pid.creation && serial == pid.serial && id == pid.id
- && node.compareTo(pid.node) == 0;
+ return creation == pid.creation && serial == pid.serial && id == pid.id
+ && node.compareTo(pid.node) == 0;
}
-
+
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(5);
- hash.combine(creation, serial);
- hash.combine(id, node.hashCode());
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(5);
+ hash.combine(creation, serial);
+ hash.combine(id, node.hashCode());
+ return hash.valueOf();
}
-
+
public int compareTo(final Object o) {
- if (!(o instanceof OtpErlangPid)) {
- return -1;
- }
-
- final OtpErlangPid pid = (OtpErlangPid) o;
- if (creation == pid.creation) {
- if (serial == pid.serial) {
- if (id == pid.id) {
- return node.compareTo(pid.node);
+ if (!(o instanceof OtpErlangPid)) {
+ return -1;
+ }
+
+ final OtpErlangPid pid = (OtpErlangPid) o;
+ if (creation == pid.creation) {
+ if (serial == pid.serial) {
+ if (id == pid.id) {
+ return node.compareTo(pid.node);
+ }
+ return id - pid.id;
+ }
+ return serial - pid.serial;
}
- return id - pid.id;
- }
- return serial - pid.serial;
- }
- return creation - pid.creation;
- }
+ return creation - pid.creation;
}
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java
index 8557e17325..a6198d56cc 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang ports.
*/
@@ -33,136 +33,134 @@ public class OtpErlangPort extends OtpErlangObject {
/*
* Create a unique Erlang port belonging to the local node. Since it isn't
* meaninful to do so, this constructor is private...
- *
+ *
* @param self the local node.
- *
+ *
* @deprecated use OtpLocalNode:createPort() instead
*/
@SuppressWarnings("unused")
private OtpErlangPort(final OtpSelf self) {
- final OtpErlangPort p = self.createPort();
+ final OtpErlangPort p = self.createPort();
- id = p.id;
- creation = p.creation;
- node = p.node;
+ id = p.id;
+ creation = p.creation;
+ node = p.node;
}
/**
* Create an Erlang port from a stream containing a port encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded port.
- *
+ * the stream containing the encoded port.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang port.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang port.
*/
public OtpErlangPort(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final OtpErlangPort p = buf.read_port();
+ throws OtpErlangDecodeException {
+ final OtpErlangPort p = buf.read_port();
- node = p.node();
- id = p.id();
- creation = p.creation();
+ node = p.node();
+ id = p.id();
+ creation = p.creation();
}
/**
* Create an Erlang port from its components.
- *
+ *
* @param node
- * the nodename.
- *
+ * the nodename.
+ *
* @param id
- * an arbitrary number. Only the low order 28 bits will be
- * used.
- *
+ * an arbitrary number. Only the low order 28 bits will be used.
+ *
* @param creation
- * another arbitrary number. Only the low order 2 bits will
- * be used.
+ * another arbitrary number. Only the low order 2 bits will be
+ * used.
*/
public OtpErlangPort(final String node, final int id, final int creation) {
- this.node = node;
- this.id = id & 0xfffffff; // 28 bits
- this.creation = creation & 0x03; // 2 bits
+ this.node = node;
+ this.id = id & 0xfffffff; // 28 bits
+ this.creation = creation & 0x03; // 2 bits
}
/**
* Get the id number from the port.
- *
+ *
* @return the id number from the port.
*/
public int id() {
- return id;
+ return id;
}
/**
* Get the creation number from the port.
- *
+ *
* @return the creation number from the port.
*/
public int creation() {
- return creation;
+ return creation;
}
/**
* Get the node name from the port.
- *
+ *
* @return the node name from the port.
*/
public String node() {
- return node;
+ return node;
}
/**
* Get the string representation of the port. Erlang ports are printed as
* #Port&lt;node.id&gt;.
- *
+ *
* @return the string representation of the port.
*/
@Override
public String toString() {
- return "#Port<" + node + "." + id + ">";
+ return "#Port<" + node + "." + id + ">";
}
/**
* Convert this port to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded port should be
- * written.
+ * an output stream to which the encoded port should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_port(node, id, creation);
+ buf.write_port(node, id, creation);
}
/**
* Determine if two ports are equal. Ports are equal if their components are
* equal.
- *
+ *
* @param o
- * the other port to compare to.
- *
+ * the other port to compare to.
+ *
* @return true if the ports are equal, false otherwise.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangPort)) {
- return false;
- }
+ if (!(o instanceof OtpErlangPort)) {
+ return false;
+ }
- final OtpErlangPort port = (OtpErlangPort) o;
+ final OtpErlangPort port = (OtpErlangPort) o;
- return creation == port.creation && id == port.id
- && node.compareTo(port.node) == 0;
+ return creation == port.creation && id == port.id
+ && node.compareTo(port.node) == 0;
}
-
+
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(6);
- hash.combine(creation);
- hash.combine(id, node.hashCode());
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(6);
+ hash.combine(creation);
+ hash.combine(id, node.hashCode());
+ return hash.valueOf();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRangeException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRangeException.java
index a78b6df6ef..cbddea9f24 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRangeException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRangeException.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -21,7 +22,7 @@ package com.ericsson.otp.erlang;
/**
* Exception raised when an attempt is made to create an Erlang term with data
* that is out of range for the term in question.
- *
+ *
* @see OtpErlangByte
* @see OtpErlangChar
* @see OtpErlangInt
@@ -37,6 +38,6 @@ public class OtpErlangRangeException extends OtpErlangException {
* Provides a detailed message.
*/
public OtpErlangRangeException(final String msg) {
- super(msg);
+ super(msg);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java
index 13a83333fa..8b57e7265b 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang refs. There are two styles of Erlang
* refs, old style (one id value) and new style (array of id values). This class
@@ -37,203 +37,201 @@ public class OtpErlangRef extends OtpErlangObject {
/**
* Create a unique Erlang ref belonging to the local node.
- *
+ *
* @param self
- * the local node.
- *
+ * the local node.
+ *
* @deprecated use OtpLocalNode:createRef() instead
*/
@Deprecated
public OtpErlangRef(final OtpLocalNode self) {
- final OtpErlangRef r = self.createRef();
+ final OtpErlangRef r = self.createRef();
- ids = r.ids;
- creation = r.creation;
- node = r.node;
+ ids = r.ids;
+ creation = r.creation;
+ node = r.node;
}
/**
* Create an Erlang ref from a stream containing a ref encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded ref.
- *
+ * the stream containing the encoded ref.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang ref.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang ref.
*/
public OtpErlangRef(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final OtpErlangRef r = buf.read_ref();
+ throws OtpErlangDecodeException {
+ final OtpErlangRef r = buf.read_ref();
- node = r.node();
- creation = r.creation();
+ node = r.node();
+ creation = r.creation();
- ids = r.ids();
+ ids = r.ids();
}
/**
* Create an old style Erlang ref from its components.
- *
+ *
* @param node
- * the nodename.
- *
+ * the nodename.
+ *
* @param id
- * an arbitrary number. Only the low order 18 bits will be
- * used.
- *
+ * an arbitrary number. Only the low order 18 bits will be used.
+ *
* @param creation
- * another arbitrary number. Only the low order 2 bits will
- * be used.
+ * another arbitrary number. Only the low order 2 bits will be
+ * used.
*/
public OtpErlangRef(final String node, final int id, final int creation) {
- this.node = node;
- ids = new int[1];
- ids[0] = id & 0x3ffff; // 18 bits
- this.creation = creation & 0x03; // 2 bits
+ this.node = node;
+ ids = new int[1];
+ ids[0] = id & 0x3ffff; // 18 bits
+ this.creation = creation & 0x03; // 2 bits
}
/**
* Create a new style Erlang ref from its components.
- *
+ *
* @param node
- * the nodename.
- *
+ * the nodename.
+ *
* @param ids
- * an array of arbitrary numbers. Only the low order 18 bits
- * of the first number will be used. If the array contains
- * only one number, an old style ref will be written instead.
- * At most three numbers will be read from the array.
- *
+ * an array of arbitrary numbers. Only the low order 18 bits of
+ * the first number will be used. If the array contains only one
+ * number, an old style ref will be written instead. At most
+ * three numbers will be read from the array.
+ *
* @param creation
- * another arbitrary number. Only the low order 2 bits will
- * be used.
+ * another arbitrary number. Only the low order 2 bits will be
+ * used.
*/
public OtpErlangRef(final String node, final int[] ids, final int creation) {
- this.node = node;
- this.creation = creation & 0x03; // 2 bits
+ this.node = node;
+ this.creation = creation & 0x03; // 2 bits
- // use at most 82 bits (18 + 32 + 32)
- int len = ids.length;
- this.ids = new int[3];
- this.ids[0] = 0;
- this.ids[1] = 0;
- this.ids[2] = 0;
+ // use at most 82 bits (18 + 32 + 32)
+ int len = ids.length;
+ this.ids = new int[3];
+ this.ids[0] = 0;
+ this.ids[1] = 0;
+ this.ids[2] = 0;
- if (len > 3) {
- len = 3;
- }
- System.arraycopy(ids, 0, this.ids, 0, len);
- this.ids[0] &= 0x3ffff; // only 18 significant bits in first number
+ if (len > 3) {
+ len = 3;
+ }
+ System.arraycopy(ids, 0, this.ids, 0, len);
+ this.ids[0] &= 0x3ffff; // only 18 significant bits in first number
}
/**
* Get the id number from the ref. Old style refs have only one id number.
* If this is a new style ref, the first id number is returned.
- *
+ *
* @return the id number from the ref.
*/
public int id() {
- return ids[0];
+ return ids[0];
}
/**
* Get the array of id numbers from the ref. If this is an old style ref,
* the array is of length 1. If this is a new style ref, the array has
* length 3.
- *
+ *
* @return the array of id numbers from the ref.
*/
public int[] ids() {
- return ids;
+ return ids;
}
/**
* Determine whether this is a new style ref.
- *
+ *
* @return true if this ref is a new style ref, false otherwise.
*/
public boolean isNewRef() {
- return ids.length > 1;
+ return ids.length > 1;
}
/**
* Get the creation number from the ref.
- *
+ *
* @return the creation number from the ref.
*/
public int creation() {
- return creation;
+ return creation;
}
/**
* Get the node name from the ref.
- *
+ *
* @return the node name from the ref.
*/
public String node() {
- return node;
+ return node;
}
/**
* Get the string representation of the ref. Erlang refs are printed as
* #Ref&lt;node.id&gt;
- *
+ *
* @return the string representation of the ref.
*/
@Override
public String toString() {
- String s = "#Ref<" + node;
+ String s = "#Ref<" + node;
- for (int i = 0; i < ids.length; i++) {
- s += "." + ids[i];
- }
+ for (int i = 0; i < ids.length; i++) {
+ s += "." + ids[i];
+ }
- s += ">";
+ s += ">";
- return s;
+ return s;
}
/**
* Convert this ref to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded ref should be
- * written.
+ * an output stream to which the encoded ref should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_ref(node, ids, creation);
+ buf.write_ref(node, ids, creation);
}
/**
* Determine if two refs are equal. Refs are equal if their components are
* equal. New refs and old refs are considered equal if the node, creation
* and first id numnber are equal.
- *
+ *
* @param o
- * the other ref to compare to.
- *
+ * the other ref to compare to.
+ *
* @return true if the refs are equal, false otherwise.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangRef)) {
- return false;
- }
+ if (!(o instanceof OtpErlangRef)) {
+ return false;
+ }
- final OtpErlangRef ref = (OtpErlangRef) o;
+ final OtpErlangRef ref = (OtpErlangRef) o;
- if (!(node.equals(ref.node()) && creation == ref.creation())) {
- return false;
- }
+ if (!(node.equals(ref.node()) && creation == ref.creation())) {
+ return false;
+ }
- if (isNewRef() && ref.isNewRef()) {
- return ids[0] == ref.ids[0] && ids[1] == ref.ids[1]
- && ids[2] == ref.ids[2];
- }
- return ids[0] == ref.ids[0];
+ if (isNewRef() && ref.isNewRef()) {
+ return ids[0] == ref.ids[0] && ids[1] == ref.ids[1]
+ && ids[2] == ref.ids[2];
+ }
+ return ids[0] == ref.ids[0];
}
/**
@@ -245,18 +243,18 @@ public class OtpErlangRef extends OtpErlangObject {
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(7);
- hash.combine(creation, ids[0]);
- if (isNewRef()) {
- hash.combine(ids[1], ids[2]);
- }
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(7);
+ hash.combine(creation, ids[0]);
+ if (isNewRef()) {
+ hash.combine(ids[1], ids[2]);
+ }
+ return hash.valueOf();
}
-
+
@Override
public Object clone() {
- final OtpErlangRef newRef = (OtpErlangRef) super.clone();
- newRef.ids = ids.clone();
- return newRef;
+ final OtpErlangRef newRef = (OtpErlangRef) super.clone();
+ newRef.ids = ids.clone();
+ return newRef;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java
index 6ef56defbd..fcd417b4a7 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang integral types.
*/
@@ -28,34 +28,33 @@ public class OtpErlangShort extends OtpErlangLong {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param s
- * the short value to use.
+ * the short value to use.
*/
public OtpErlangShort(final short s) {
- super(s);
+ super(s);
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a
- * short.
+ * if the value is too large to be represented as a short.
*/
public OtpErlangShort(final OtpInputStream buf)
- throws OtpErlangRangeException, OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangRangeException, OtpErlangDecodeException {
+ super(buf);
- shortValue();
+ shortValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
index 1bccfcc567..dab83f98a2 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2012. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -33,75 +34,74 @@ public class OtpErlangString extends OtpErlangObject {
* Create an Erlang string from the given string.
*/
public OtpErlangString(final String str) {
- this.str = str;
+ this.str = str;
}
/**
* Create an Erlang string from a list of integers.
*
* @throws OtpErlangException
- * for non-proper and non-integer lists.
+ * for non-proper and non-integer lists.
* @throws OtpErlangRangeException
- * if an integer in the list is not
- * a valid Unicode code point according to Erlang.
+ * if an integer in the list is not a valid Unicode code point
+ * according to Erlang.
*/
- public OtpErlangString(final OtpErlangList list)
- throws OtpErlangException {
- String s = list.stringValue();
- final int n = s.length();
- for (int i = 0; i < n; i = s.offsetByCodePoints(i, 1)) {
- int cp = s.codePointAt(i);
- if (! isValidCodePoint(cp)) {
- throw new OtpErlangRangeException("Invalid CodePoint: " + cp);
- }
- }
- str = s;
+ public OtpErlangString(final OtpErlangList list) throws OtpErlangException {
+ final String s = list.stringValue();
+ final int n = s.length();
+ for (int i = 0; i < n; i = s.offsetByCodePoints(i, 1)) {
+ final int cp = s.codePointAt(i);
+ if (!isValidCodePoint(cp)) {
+ throw new OtpErlangRangeException("Invalid CodePoint: " + cp);
+ }
+ }
+ str = s;
}
/**
* Create an Erlang string from a stream containing a string encoded in
* Erlang external format.
- *
+ *
* @param buf
* the stream containing the encoded string.
- *
+ *
* @exception OtpErlangDecodeException
* if the buffer does not contain a valid external
* representation of an Erlang string.
*/
public OtpErlangString(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- str = buf.read_string();
+ throws OtpErlangDecodeException {
+ str = buf.read_string();
}
/**
* Get the actual string contained in this object.
- *
+ *
* @return the raw string contained in this object, without regard to Erlang
* quoting rules.
- *
+ *
* @see #toString
*/
public String stringValue() {
- return str;
+ return str;
}
/**
* Get the printable version of the string contained in this object.
- *
+ *
* @return the string contained in this object, quoted.
- *
+ *
* @see #stringValue
*/
@Override
public String toString() {
- return "\"" + str + "\"";
+ return "\"" + str + "\"";
}
/**
* Convert this string to the equivalent Erlang external representation.
- *
+ *
* @param buf
* an output stream to which the encoded string should be
* written.
@@ -109,48 +109,48 @@ public class OtpErlangString extends OtpErlangObject {
@Override
public void encode(final OtpOutputStream buf) {
- buf.write_string(str);
+ buf.write_string(str);
}
/**
* Determine if two strings are equal. They are equal if they represent the
* same sequence of characters. This method can be used to compare
* OtpErlangStrings with each other and with Strings.
- *
+ *
* @param o
* the OtpErlangString or String to compare to.
- *
+ *
* @return true if the strings consist of the same sequence of characters,
* false otherwise.
*/
@Override
public boolean equals(final Object o) {
- if (o instanceof String) {
- return str.compareTo((String) o) == 0;
- } else if (o instanceof OtpErlangString) {
- return str.compareTo(((OtpErlangString) o).str) == 0;
- }
+ if (o instanceof String) {
+ return str.compareTo((String) o) == 0;
+ } else if (o instanceof OtpErlangString) {
+ return str.compareTo(((OtpErlangString) o).str) == 0;
+ }
- return false;
+ return false;
}
-
+
@Override
protected int doHashCode() {
- return str.hashCode();
+ return str.hashCode();
}
/**
* Create Unicode code points from a String.
- *
- * @param s
- * a String to convert to an Unicode code point array
*
- * @return the corresponding array of integers representing
- * Unicode code points
+ * @param s
+ * a String to convert to an Unicode code point array
+ *
+ * @return the corresponding array of integers representing Unicode code
+ * points
*/
- public static int[] stringToCodePoints(final String s) {
+ public static int[] stringToCodePoints(final String s) {
final int m = s.codePointCount(0, s.length());
final int[] codePoints = new int[m];
int j = 0;
@@ -163,34 +163,34 @@ public class OtpErlangString extends OtpErlangObject {
}
/**
- * Validate a code point according to Erlang definition; Unicode 3.0.
- * That is; valid in the range U+0..U+10FFFF, but not in the range
- * U+D800..U+DFFF (surrogat pairs).
+ * Validate a code point according to Erlang definition; Unicode 3.0. That
+ * is; valid in the range U+0..U+10FFFF, but not in the range U+D800..U+DFFF
+ * (surrogat pairs).
*
- * @param cp
- * the code point value to validate
+ * @param cp
+ * the code point value to validate
*
- * @return true if the code point is valid,
- * false otherwise.
+ * @return true if the code point is valid, false otherwise.
*/
public static boolean isValidCodePoint(final int cp) {
- // Erlang definition of valid Unicode code points;
- // Unicode 3.0, XML, et.al.
- return (cp>>>16) <= 0x10 // in 0..10FFFF; Unicode range
- && (cp & ~0x7FF) != 0xD800; // not in D800..DFFF; surrogate range
+ // Erlang definition of valid Unicode code points;
+ // Unicode 3.0, XML, et.al.
+ return cp >>> 16 <= 0x10 // in 0..10FFFF; Unicode range
+ && (cp & ~0x7FF) != 0xD800; // not in D800..DFFF; surrogate
+ // range
}
/**
- * Construct a String from a Latin-1 (ISO-8859-1) encoded byte array,
- * if Latin-1 is available, otherwise use the default encoding.
+ * Construct a String from a Latin-1 (ISO-8859-1) encoded byte array, if
+ * Latin-1 is available, otherwise use the default encoding.
*
*/
public static String newString(final byte[] bytes) {
- try {
- return new String(bytes, "ISO-8859-1");
- } catch (final UnsupportedEncodingException e) {
- }
- return new String(bytes);
+ try {
+ return new String(bytes, "ISO-8859-1");
+ } catch (final UnsupportedEncodingException e) {
+ }
+ return new String(bytes);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
index dffaa530cd..477f5dff83 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
@@ -1,28 +1,28 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-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.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang tuples. Tuples are created from one
* or more arbitrary Erlang terms.
- *
+ *
* <p>
* The arity of the tuple is the number of elements it contains. Elements are
* indexed from 0 to (arity-1) and can be retrieved individually by using the
@@ -38,222 +38,248 @@ public class OtpErlangTuple extends OtpErlangObject {
/**
* Create a unary tuple containing the given element.
- *
+ *
* @param elem
- * the element to create the tuple from.
- *
+ * the element to create the tuple from.
+ *
* @exception java.lang.IllegalArgumentException
- * if the element is null.
+ * if the element is null.
*/
public OtpErlangTuple(final OtpErlangObject elem) {
- if (elem == null) {
- throw new java.lang.IllegalArgumentException(
- "Tuple element cannot be null");
- }
- elems = new OtpErlangObject[] { elem };
+ if (elem == null) {
+ throw new java.lang.IllegalArgumentException(
+ "Tuple element cannot be null");
+ }
+ elems = new OtpErlangObject[] { elem };
}
/**
* Create a tuple from an array of terms.
- *
+ *
* @param elems
- * the array of terms to create the tuple from.
- *
+ * the array of terms to create the tuple from.
+ *
* @exception java.lang.IllegalArgumentException
- * if the array is empty (null) or contains null
- * elements.
+ * if the array is empty (null) or contains null elements.
*/
public OtpErlangTuple(final OtpErlangObject[] elems) {
- this(elems, 0, elems.length);
+ this(elems, 0, elems.length);
}
/**
* Create a tuple from an array of terms.
- *
+ *
* @param elems
- * the array of terms to create the tuple from.
+ * the array of terms to create the tuple from.
* @param start
- * the offset of the first term to insert.
+ * the offset of the first term to insert.
* @param count
- * the number of terms to insert.
- *
+ * the number of terms to insert.
+ *
* @exception java.lang.IllegalArgumentException
- * if the array is empty (null) or contains null
- * elements.
+ * if the array is empty (null) or contains null elements.
*/
public OtpErlangTuple(final OtpErlangObject[] elems, final int start,
- final int count) {
- if (elems == null) {
- throw new java.lang.IllegalArgumentException(
- "Tuple content can't be null");
- } else if (count < 1) {
- this.elems = NO_ELEMENTS;
- } else {
- this.elems = new OtpErlangObject[count];
- for (int i = 0; i < count; i++) {
- if (elems[start + i] != null) {
- this.elems[i] = elems[start + i];
- } else {
- throw new java.lang.IllegalArgumentException(
- "Tuple element cannot be null (element"
- + (start + i) + ")");
- }
- }
- }
+ final int count) {
+ if (elems == null) {
+ throw new java.lang.IllegalArgumentException(
+ "Tuple content can't be null");
+ } else if (count < 1) {
+ this.elems = NO_ELEMENTS;
+ } else {
+ this.elems = new OtpErlangObject[count];
+ for (int i = 0; i < count; i++) {
+ if (elems[start + i] != null) {
+ this.elems[i] = elems[start + i];
+ } else {
+ throw new java.lang.IllegalArgumentException(
+ "Tuple element cannot be null (element"
+ + (start + i) + ")");
+ }
+ }
+ }
}
/**
* Create a tuple from a stream containing an tuple encoded in Erlang
* external format.
- *
+ *
* @param buf
- * the stream containing the encoded tuple.
- *
+ * the stream containing the encoded tuple.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang tuple.
+ * if the buffer does not contain a valid external
+ * representation of an Erlang tuple.
*/
public OtpErlangTuple(final OtpInputStream buf)
- throws OtpErlangDecodeException {
- final int arity = buf.read_tuple_head();
+ throws OtpErlangDecodeException {
+ final int arity = buf.read_tuple_head();
- if (arity > 0) {
- elems = new OtpErlangObject[arity];
+ if (arity > 0) {
+ elems = new OtpErlangObject[arity];
- for (int i = 0; i < arity; i++) {
- elems[i] = buf.read_any();
- }
- } else {
- elems = NO_ELEMENTS;
- }
+ for (int i = 0; i < arity; i++) {
+ elems[i] = buf.read_any();
+ }
+ } else {
+ elems = NO_ELEMENTS;
+ }
}
/**
* Get the arity of the tuple.
- *
+ *
* @return the number of elements contained in the tuple.
*/
public int arity() {
- return elems.length;
+ return elems.length;
}
/**
* Get the specified element from the tuple.
- *
+ *
* @param i
- * the index of the requested element. Tuple elements are
- * numbered as array elements, starting at 0.
- *
+ * the index of the requested element. Tuple elements are
+ * numbered as array elements, starting at 0.
+ *
* @return the requested element, of null if i is not a valid element index.
*/
public OtpErlangObject elementAt(final int i) {
- if (i >= arity() || i < 0) {
- return null;
- }
- return elems[i];
+ if (i >= arity() || i < 0) {
+ return null;
+ }
+ return elems[i];
}
/**
* Get all the elements from the tuple as an array.
- *
+ *
* @return an array containing all of the tuple's elements.
*/
public OtpErlangObject[] elements() {
- final OtpErlangObject[] res = new OtpErlangObject[arity()];
- System.arraycopy(elems, 0, res, 0, res.length);
- return res;
+ final OtpErlangObject[] res = new OtpErlangObject[arity()];
+ System.arraycopy(elems, 0, res, 0, res.length);
+ return res;
}
/**
* Get the string representation of the tuple.
- *
+ *
* @return the string representation of the tuple.
*/
@Override
public String toString() {
- int i;
- final StringBuffer s = new StringBuffer();
- final int arity = elems.length;
+ int i;
+ final StringBuffer s = new StringBuffer();
+ final int arity = elems.length;
- s.append("{");
+ s.append("{");
- for (i = 0; i < arity; i++) {
- if (i > 0) {
- s.append(",");
- }
- s.append(elems[i].toString());
- }
+ for (i = 0; i < arity; i++) {
+ if (i > 0) {
+ s.append(",");
+ }
+ s.append(elems[i].toString());
+ }
- s.append("}");
+ s.append("}");
- return s.toString();
+ return s.toString();
}
/**
* Convert this tuple to the equivalent Erlang external representation.
- *
+ *
* @param buf
- * an output stream to which the encoded tuple should be
- * written.
+ * an output stream to which the encoded tuple should be written.
*/
@Override
public void encode(final OtpOutputStream buf) {
- final int arity = elems.length;
+ final int arity = elems.length;
- buf.write_tuple_head(arity);
+ buf.write_tuple_head(arity);
- for (int i = 0; i < arity; i++) {
- buf.write_any(elems[i]);
- }
+ for (int i = 0; i < arity; i++) {
+ buf.write_any(elems[i]);
+ }
}
/**
* Determine if two tuples are equal. Tuples are equal if they have the same
* arity and all of the elements are equal.
- *
+ *
* @param o
- * the tuple to compare to.
- *
+ * the tuple to compare to.
+ *
* @return true if the tuples have the same arity and all the elements are
* equal.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpErlangTuple)) {
- return false;
- }
+ if (!(o instanceof OtpErlangTuple)) {
+ return false;
+ }
- final OtpErlangTuple t = (OtpErlangTuple) o;
- final int a = arity();
+ final OtpErlangTuple t = (OtpErlangTuple) o;
+ final int a = arity();
- if (a != t.arity()) {
- return false;
- }
+ if (a != t.arity()) {
+ return false;
+ }
- for (int i = 0; i < a; i++) {
- if (!elems[i].equals(t.elems[i])) {
- return false; // early exit
- }
- }
+ for (int i = 0; i < a; i++) {
+ if (!elems[i].equals(t.elems[i])) {
+ return false; // early exit
+ }
+ }
- return true;
+ return true;
}
-
+
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T bindings) {
+ if (!(term instanceof OtpErlangTuple)) {
+ return false;
+ }
+ final OtpErlangTuple t = (OtpErlangTuple) term;
+ final int a = elems.length;
+ if (a != t.elems.length) {
+ return false;
+ }
+ for (int i = 0; i < a; i++) {
+ if (!elems[i].match(t.elems[i], bindings)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ final OtpErlangTuple tuple = (OtpErlangTuple) this.clone();
+ final int a = tuple.elems.length;
+ for (int i = 0; i < a; i++) {
+ final OtpErlangObject e = tuple.elems[i];
+ tuple.elems[i] = e.bind(binds);
+ }
+ return tuple;
+ }
+
@Override
protected int doHashCode() {
- OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
- final int a = arity();
- hash.combine(a);
- for (int i = 0; i < a; i++) {
- hash.combine(elems[i].hashCode());
- }
- return hash.valueOf();
+ final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
+ final int a = arity();
+ hash.combine(a);
+ for (int i = 0; i < a; i++) {
+ hash.combine(elems[i].hashCode());
+ }
+ return hash.valueOf();
}
-
+
@Override
public Object clone() {
- final OtpErlangTuple newTuple = (OtpErlangTuple) super.clone();
- newTuple.elems = elems.clone();
- return newTuple;
+ final OtpErlangTuple newTuple = (OtpErlangTuple) super.clone();
+ newTuple.elems = elems.clone();
+ return newTuple;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java
index a02996e437..ea1060121a 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang integral types.
*/
@@ -28,38 +28,38 @@ public class OtpErlangUInt extends OtpErlangLong {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param i
- * the non-negative int value to use.
- *
+ * the non-negative int value to use.
+ *
* @exception OtpErlangRangeException
- * if the value is negative.
+ * if the value is negative.
*/
public OtpErlangUInt(final int i) throws OtpErlangRangeException {
- super(i);
+ super(i);
- uIntValue();
+ uIntValue();
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as an int,
- * or the value is negative.
+ * if the value is too large to be represented as an int, or
+ * the value is negative.
*/
public OtpErlangUInt(final OtpInputStream buf)
- throws OtpErlangRangeException, OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangRangeException, OtpErlangDecodeException {
+ super(buf);
- uIntValue();
+ uIntValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java
index e9d251f815..b1391fddf9 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java
@@ -1,24 +1,24 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
-
/**
* Provides a Java representation of Erlang integral types.
*/
@@ -28,38 +28,38 @@ public class OtpErlangUShort extends OtpErlangLong {
/**
* Create an Erlang integer from the given value.
- *
+ *
* @param s
- * the non-negative short value to use.
- *
+ * the non-negative short value to use.
+ *
* @exception OtpErlangRangeException
- * if the value is negative.
+ * if the value is negative.
*/
public OtpErlangUShort(final short s) throws OtpErlangRangeException {
- super(s);
+ super(s);
- uShortValue();
+ uShortValue();
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
- *
+ *
* @param buf
- * the stream containing the encoded value.
- *
+ * the stream containing the encoded value.
+ *
* @exception OtpErlangDecodeException
- * if the buffer does not contain a valid external
- * representation of an Erlang integer.
- *
+ * if the buffer does not contain a valid external
+ * representation of an Erlang integer.
+ *
* @exception OtpErlangRangeException
- * if the value is too large to be represented as a
- * short, or the value is negative.
+ * if the value is too large to be represented as a short, or
+ * the value is negative.
*/
public OtpErlangUShort(final OtpInputStream buf)
- throws OtpErlangRangeException, OtpErlangDecodeException {
- super(buf);
+ throws OtpErlangRangeException, OtpErlangDecodeException {
+ super(buf);
- uShortValue();
+ uShortValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java
index 874c7da104..6f44cecd32 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -28,13 +29,13 @@ public abstract class OtpException extends Exception {
* Provides no message.
*/
public OtpException() {
- super();
+ super();
}
/**
* Provides a detailed message.
*/
public OtpException(final String msg) {
- super(msg);
+ super(msg);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
index fa0fe18e95..4645f25590 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-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.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
index bab0629382..fa0815fbf0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-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.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -25,7 +26,7 @@ import java.util.Arrays;
/**
* Provides a stream for decoding Erlang terms from external format.
- *
+ *
* <p>
* Note that this class is not synchronized, if you need synchronization you
* must provide it yourself.
@@ -40,1211 +41,1214 @@ public class OtpInputStream extends ByteArrayInputStream {
* @param buf
*/
public OtpInputStream(final byte[] buf) {
- this(buf, 0);
+ this(buf, 0);
}
/**
* Create a stream from a buffer containing encoded Erlang terms.
- *
+ *
* @param flags
*/
public OtpInputStream(final byte[] buf, final int flags) {
- super(buf);
- this.flags = flags;
+ super(buf);
+ this.flags = flags;
}
/**
* Create a stream from a buffer containing encoded Erlang terms at the
* given offset and length.
- *
+ *
* @param flags
*/
public OtpInputStream(final byte[] buf, final int offset, final int length,
- final int flags) {
- super(buf, offset, length);
- this.flags = flags;
+ final int flags) {
+ super(buf, offset, length);
+ this.flags = flags;
}
/**
* Get the current position in the stream.
- *
+ *
* @return the current position in the stream.
*/
public int getPos() {
- return super.pos;
+ return super.pos;
}
/**
* Set the current position in the stream.
- *
+ *
* @param pos
* the position to move to in the stream. If pos indicates a
* position beyond the end of the stream, the position is move to
* the end of the stream instead. If pos is negative, the
* position is moved to the beginning of the stream instead.
- *
+ *
* @return the previous position in the stream.
*/
public int setPos(final int pos) {
- final int oldpos = super.pos;
+ final int oldpos = super.pos;
- int apos = pos;
- if (pos > super.count) {
- apos = super.count;
- } else if (pos < 0) {
- apos = 0;
- }
+ int apos = pos;
+ if (pos > super.count) {
+ apos = super.count;
+ } else if (pos < 0) {
+ apos = 0;
+ }
- super.pos = apos;
+ super.pos = apos;
- return oldpos;
+ return oldpos;
}
/**
* Read an array of bytes from the stream. The method reads at most
* buf.length bytes from the input stream.
- *
+ *
* @return the number of bytes read.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int readN(final byte[] abuf) throws OtpErlangDecodeException {
- return this.readN(abuf, 0, abuf.length);
+ return this.readN(abuf, 0, abuf.length);
}
/**
* Read an array of bytes from the stream. The method reads at most len
* bytes from the input stream into offset off of the buffer.
- *
+ *
* @return the number of bytes read.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int readN(final byte[] abuf, final int off, final int len)
- throws OtpErlangDecodeException {
- if (len == 0 && available() == 0) {
- return 0;
- }
- final int i = super.read(abuf, off, len);
- if (i < 0) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- return i;
+ throws OtpErlangDecodeException {
+ if (len == 0 && available() == 0) {
+ return 0;
+ }
+ final int i = super.read(abuf, off, len);
+ if (i < 0) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ return i;
}
/**
* Alias for peek1()
*/
public int peek() throws OtpErlangDecodeException {
- return peek1();
+ return peek1();
}
/**
* Look ahead one position in the stream without consuming the byte found
* there.
- *
+ *
* @return the next byte in the stream, as an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int peek1() throws OtpErlangDecodeException {
- int i;
- try {
- i = super.buf[super.pos];
- if (i < 0) {
- i += 256;
- }
-
- return i;
- } catch (final Exception e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
+ int i;
+ try {
+ i = super.buf[super.pos];
+ if (i < 0) {
+ i += 256;
+ }
+
+ return i;
+ } catch (final Exception e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
}
public int peek1skip_version() throws OtpErlangDecodeException {
- int i = peek1();
- if (i == OtpExternal.versionTag) {
- read1();
- i = peek1();
- }
- return i;
+ int i = peek1();
+ if (i == OtpExternal.versionTag) {
+ read1();
+ i = peek1();
+ }
+ return i;
}
/**
* Read a one byte integer from the stream.
- *
+ *
* @return the byte read, as an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int read1() throws OtpErlangDecodeException {
- int i;
- i = super.read();
+ int i;
+ i = super.read();
- if (i < 0) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
+ if (i < 0) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
- return i;
+ return i;
}
public int read1skip_version() throws OtpErlangDecodeException {
- int tag = read1();
- if (tag == OtpExternal.versionTag) {
- tag = read1();
- }
- return tag;
+ int tag = read1();
+ if (tag == OtpExternal.versionTag) {
+ tag = read1();
+ }
+ return tag;
}
/**
* Read a two byte big endian integer from the stream.
- *
+ *
* @return the bytes read, converted from big endian to an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int read2BE() throws OtpErlangDecodeException {
- final byte[] b = new byte[2];
- try {
- super.read(b);
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- return (b[0] << 8 & 0xff00) + (b[1] & 0xff);
+ final byte[] b = new byte[2];
+ try {
+ super.read(b);
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ return (b[0] << 8 & 0xff00) + (b[1] & 0xff);
}
/**
* Read a four byte big endian integer from the stream.
- *
+ *
* @return the bytes read, converted from big endian to an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int read4BE() throws OtpErlangDecodeException {
- final byte[] b = new byte[4];
- try {
- super.read(b);
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- return (b[0] << 24 & 0xff000000) + (b[1] << 16 & 0xff0000)
- + (b[2] << 8 & 0xff00) + (b[3] & 0xff);
+ final byte[] b = new byte[4];
+ try {
+ super.read(b);
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ return (b[0] << 24 & 0xff000000) + (b[1] << 16 & 0xff0000)
+ + (b[2] << 8 & 0xff00) + (b[3] & 0xff);
}
/**
* Read a two byte little endian integer from the stream.
- *
+ *
* @return the bytes read, converted from little endian to an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int read2LE() throws OtpErlangDecodeException {
- final byte[] b = new byte[2];
- try {
- super.read(b);
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- return (b[1] << 8 & 0xff00) + (b[0] & 0xff);
+ final byte[] b = new byte[2];
+ try {
+ super.read(b);
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ return (b[1] << 8 & 0xff00) + (b[0] & 0xff);
}
/**
* Read a four byte little endian integer from the stream.
- *
+ *
* @return the bytes read, converted from little endian to an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public int read4LE() throws OtpErlangDecodeException {
- final byte[] b = new byte[4];
- try {
- super.read(b);
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- return (b[3] << 24 & 0xff000000) + (b[2] << 16 & 0xff0000)
- + (b[1] << 8 & 0xff00) + (b[0] & 0xff);
+ final byte[] b = new byte[4];
+ try {
+ super.read(b);
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ return (b[3] << 24 & 0xff000000) + (b[2] << 16 & 0xff0000)
+ + (b[1] << 8 & 0xff00) + (b[0] & 0xff);
}
/**
* Read a little endian integer from the stream.
- *
+ *
* @param n
* the number of bytes to read
- *
+ *
* @return the bytes read, converted from little endian to an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public long readLE(final int n) throws OtpErlangDecodeException {
- final byte[] b = new byte[n];
- try {
- super.read(b);
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- long v = 0;
- int i = n;
- while (i-- > 0) {
- v = v << 8 | (long) b[i] & 0xff;
- }
- return v;
+ final byte[] b = new byte[n];
+ try {
+ super.read(b);
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ long v = 0;
+ int i = n;
+ while (i-- > 0) {
+ v = v << 8 | (long) b[i] & 0xff;
+ }
+ return v;
}
/**
* Read a bigendian integer from the stream.
- *
+ *
* @param n
* the number of bytes to read
- *
+ *
* @return the bytes read, converted from big endian to an integer.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public long readBE(final int n) throws OtpErlangDecodeException {
- final byte[] b = new byte[n];
- try {
- super.read(b);
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
- long v = 0;
- for (int i = 0; i < n; i++) {
- v = v << 8 | (long) b[i] & 0xff;
- }
- return v;
+ final byte[] b = new byte[n];
+ try {
+ super.read(b);
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+ long v = 0;
+ for (int i = 0; i < n; i++) {
+ v = v << 8 | (long) b[i] & 0xff;
+ }
+ return v;
}
/**
* Read an Erlang atom from the stream and interpret the value as a boolean.
- *
+ *
* @return true if the atom at the current position in the stream contains
* the value 'true' (ignoring case), false otherwise.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an atom.
*/
public boolean read_boolean() throws OtpErlangDecodeException {
- return Boolean.valueOf(read_atom()).booleanValue();
+ return Boolean.valueOf(read_atom()).booleanValue();
}
/**
* Read an Erlang atom from the stream.
- *
+ *
* @return a String containing the value of the atom.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an atom.
*/
@SuppressWarnings("fallthrough")
public String read_atom() throws OtpErlangDecodeException {
- int tag;
- int len = -1;
- byte[] strbuf;
- String atom;
-
- tag = read1skip_version();
-
- switch (tag) {
-
- case OtpExternal.atomTag:
- len = read2BE();
- strbuf = new byte[len];
- this.readN(strbuf);
- try {
- atom = new String(strbuf, "ISO-8859-1");
- } catch (final java.io.UnsupportedEncodingException e) {
- throw new OtpErlangDecodeException(
- "Failed to decode ISO-8859-1 atom");
- }
- if (atom.length() > OtpExternal.maxAtomLength) {
- /*
- * Throwing an exception would be better I think,
- * but truncation seems to be the way it has
- * been done in other parts of OTP...
- */
- atom = atom.substring(0, OtpExternal.maxAtomLength);
- }
- break;
-
- case OtpExternal.smallAtomUtf8Tag:
- len = read1();
- // fall-through
- case OtpExternal.atomUtf8Tag:
- if (len < 0) {
- len = read2BE();
- }
- strbuf = new byte[len];
- this.readN(strbuf);
- try {
- atom = new String(strbuf, "UTF-8");
- } catch (final java.io.UnsupportedEncodingException e) {
- throw new OtpErlangDecodeException(
- "Failed to decode UTF-8 atom");
- }
- if (atom.codePointCount(0, atom.length()) > OtpExternal.maxAtomLength) {
- /*
- * Throwing an exception would be better I think,
- * but truncation seems to be the way it has
- * been done in other parts of OTP...
- */
- final int[] cps = OtpErlangString.stringToCodePoints(atom);
- atom = new String(cps, 0, OtpExternal.maxAtomLength);
- }
- break;
-
- default:
- throw new OtpErlangDecodeException(
- "wrong tag encountered, expected " + OtpExternal.atomTag
- + ", or " + OtpExternal.atomUtf8Tag + ", got " + tag);
- }
-
- return atom;
+ int tag;
+ int len = -1;
+ byte[] strbuf;
+ String atom;
+
+ tag = read1skip_version();
+
+ switch (tag) {
+
+ case OtpExternal.atomTag:
+ len = read2BE();
+ strbuf = new byte[len];
+ this.readN(strbuf);
+ try {
+ atom = new String(strbuf, "ISO-8859-1");
+ } catch (final java.io.UnsupportedEncodingException e) {
+ throw new OtpErlangDecodeException(
+ "Failed to decode ISO-8859-1 atom");
+ }
+ if (atom.length() > OtpExternal.maxAtomLength) {
+ /*
+ * Throwing an exception would be better I think, but truncation
+ * seems to be the way it has been done in other parts of OTP...
+ */
+ atom = atom.substring(0, OtpExternal.maxAtomLength);
+ }
+ break;
+
+ case OtpExternal.smallAtomUtf8Tag:
+ len = read1();
+ // fall-through
+ case OtpExternal.atomUtf8Tag:
+ if (len < 0) {
+ len = read2BE();
+ }
+ strbuf = new byte[len];
+ this.readN(strbuf);
+ try {
+ atom = new String(strbuf, "UTF-8");
+ } catch (final java.io.UnsupportedEncodingException e) {
+ throw new OtpErlangDecodeException(
+ "Failed to decode UTF-8 atom");
+ }
+ if (atom.codePointCount(0, atom.length()) > OtpExternal.maxAtomLength) {
+ /*
+ * Throwing an exception would be better I think, but truncation
+ * seems to be the way it has been done in other parts of OTP...
+ */
+ final int[] cps = OtpErlangString.stringToCodePoints(atom);
+ atom = new String(cps, 0, OtpExternal.maxAtomLength);
+ }
+ break;
+
+ default:
+ throw new OtpErlangDecodeException(
+ "wrong tag encountered, expected " + OtpExternal.atomTag
+ + ", or " + OtpExternal.atomUtf8Tag + ", got "
+ + tag);
+ }
+
+ return atom;
}
/**
* Read an Erlang binary from the stream.
- *
+ *
* @return a byte array containing the value of the binary.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a binary.
*/
public byte[] read_binary() throws OtpErlangDecodeException {
- int tag;
- int len;
- byte[] bin;
+ int tag;
+ int len;
+ byte[] bin;
- tag = read1skip_version();
+ tag = read1skip_version();
- if (tag != OtpExternal.binTag) {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected " + OtpExternal.binTag
- + ", got " + tag);
- }
+ if (tag != OtpExternal.binTag) {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected " + OtpExternal.binTag
+ + ", got " + tag);
+ }
- len = read4BE();
+ len = read4BE();
- bin = new byte[len];
- this.readN(bin);
+ bin = new byte[len];
+ this.readN(bin);
- return bin;
+ return bin;
}
/**
* Read an Erlang bitstr from the stream.
- *
+ *
* @param pad_bits
* an int array whose first element will be set to the number of
* pad bits in the last byte.
- *
+ *
* @return a byte array containing the value of the bitstr.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a bitstr.
*/
public byte[] read_bitstr(final int pad_bits[])
- throws OtpErlangDecodeException {
- int tag;
- int len;
- byte[] bin;
-
- tag = read1skip_version();
-
- if (tag != OtpExternal.bitBinTag) {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected " + OtpExternal.bitBinTag
- + ", got " + tag);
- }
-
- len = read4BE();
- bin = new byte[len];
- final int tail_bits = read1();
- if (tail_bits < 0 || 7 < tail_bits) {
- throw new OtpErlangDecodeException(
- "Wrong tail bit count in bitstr: " + tail_bits);
- }
- if (len == 0 && tail_bits != 0) {
- throw new OtpErlangDecodeException(
- "Length 0 on bitstr with tail bit count: " + tail_bits);
- }
- this.readN(bin);
-
- pad_bits[0] = 8 - tail_bits;
- return bin;
+ throws OtpErlangDecodeException {
+ int tag;
+ int len;
+ byte[] bin;
+
+ tag = read1skip_version();
+
+ if (tag != OtpExternal.bitBinTag) {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected " + OtpExternal.bitBinTag
+ + ", got " + tag);
+ }
+
+ len = read4BE();
+ bin = new byte[len];
+ final int tail_bits = read1();
+ if (tail_bits < 0 || 7 < tail_bits) {
+ throw new OtpErlangDecodeException(
+ "Wrong tail bit count in bitstr: " + tail_bits);
+ }
+ if (len == 0 && tail_bits != 0) {
+ throw new OtpErlangDecodeException(
+ "Length 0 on bitstr with tail bit count: " + tail_bits);
+ }
+ this.readN(bin);
+
+ pad_bits[0] = 8 - tail_bits;
+ return bin;
}
/**
* Read an Erlang float from the stream.
- *
+ *
* @return the float value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a float.
*/
public float read_float() throws OtpErlangDecodeException {
- final double d = read_double();
- return (float) d;
+ final double d = read_double();
+ return (float) d;
}
/**
* Read an Erlang float from the stream.
- *
+ *
* @return the float value, as a double.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a float.
*/
public double read_double() throws OtpErlangDecodeException {
- int tag;
-
- // parse the stream
- tag = read1skip_version();
-
- switch (tag) {
- case OtpExternal.newFloatTag: {
- return Double.longBitsToDouble(readBE(8));
- }
- case OtpExternal.floatTag: {
- BigDecimal val;
- int epos;
- int exp;
- final byte[] strbuf = new byte[31];
- String str;
-
- // get the string
- this.readN(strbuf);
- str = OtpErlangString.newString(strbuf);
-
- // find the exponent prefix 'e' in the string
- epos = str.indexOf('e', 0);
-
- if (epos < 0) {
- throw new OtpErlangDecodeException("Invalid float format: '"
- + str + "'");
- }
-
- // remove the sign from the exponent, if positive
- String estr = str.substring(epos + 1).trim();
-
- if (estr.substring(0, 1).equals("+")) {
- estr = estr.substring(1);
- }
-
- // now put the mantissa and exponent together
- exp = Integer.valueOf(estr).intValue();
- val = new BigDecimal(str.substring(0, epos)).movePointRight(exp);
-
- return val.doubleValue();
- }
- default:
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected "
- + OtpExternal.newFloatTag + ", got " + tag);
- }
+ int tag;
+
+ // parse the stream
+ tag = read1skip_version();
+
+ switch (tag) {
+ case OtpExternal.newFloatTag: {
+ return Double.longBitsToDouble(readBE(8));
+ }
+ case OtpExternal.floatTag: {
+ BigDecimal val;
+ int epos;
+ int exp;
+ final byte[] strbuf = new byte[31];
+ String str;
+
+ // get the string
+ this.readN(strbuf);
+ str = OtpErlangString.newString(strbuf);
+
+ // find the exponent prefix 'e' in the string
+ epos = str.indexOf('e', 0);
+
+ if (epos < 0) {
+ throw new OtpErlangDecodeException("Invalid float format: '"
+ + str + "'");
+ }
+
+ // remove the sign from the exponent, if positive
+ String estr = str.substring(epos + 1).trim();
+
+ if (estr.substring(0, 1).equals("+")) {
+ estr = estr.substring(1);
+ }
+
+ // now put the mantissa and exponent together
+ exp = Integer.valueOf(estr).intValue();
+ val = new BigDecimal(str.substring(0, epos)).movePointRight(exp);
+
+ return val.doubleValue();
+ }
+ default:
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected "
+ + OtpExternal.newFloatTag + ", got " + tag);
+ }
}
/**
* Read one byte from the stream.
- *
+ *
* @return the byte read.
- *
+ *
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
public byte read_byte() throws OtpErlangDecodeException {
- final long l = this.read_long(false);
- final byte i = (byte) l;
+ final long l = this.read_long(false);
+ final byte i = (byte) l;
- if (l != i) {
- throw new OtpErlangDecodeException("Value does not fit in byte: "
- + l);
- }
+ if (l != i) {
+ throw new OtpErlangDecodeException("Value does not fit in byte: "
+ + l);
+ }
- return i;
+ return i;
}
/**
* Read a character from the stream.
- *
+ *
* @return the character value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an integer that can
* be represented as a char.
*/
public char read_char() throws OtpErlangDecodeException {
- final long l = this.read_long(true);
- final char i = (char) l;
+ final long l = this.read_long(true);
+ final char i = (char) l;
- if (l != (i & 0xffffL)) {
- throw new OtpErlangDecodeException("Value does not fit in char: "
- + l);
- }
+ if (l != (i & 0xffffL)) {
+ throw new OtpErlangDecodeException("Value does not fit in char: "
+ + l);
+ }
- return i;
+ return i;
}
/**
* Read an unsigned integer from the stream.
- *
+ *
* @return the integer value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream can not be represented as a
* positive integer.
*/
public int read_uint() throws OtpErlangDecodeException {
- final long l = this.read_long(true);
- final int i = (int) l;
+ final long l = this.read_long(true);
+ final int i = (int) l;
- if (l != (i & 0xFFFFffffL)) {
- throw new OtpErlangDecodeException("Value does not fit in uint: "
- + l);
- }
+ if (l != (i & 0xFFFFffffL)) {
+ throw new OtpErlangDecodeException("Value does not fit in uint: "
+ + l);
+ }
- return i;
+ return i;
}
/**
* Read an integer from the stream.
- *
+ *
* @return the integer value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream can not be represented as
* an integer.
*/
public int read_int() throws OtpErlangDecodeException {
- final long l = this.read_long(false);
- final int i = (int) l;
+ final long l = this.read_long(false);
+ final int i = (int) l;
- if (l != i) {
- throw new OtpErlangDecodeException("Value does not fit in int: "
- + l);
- }
+ if (l != i) {
+ throw new OtpErlangDecodeException("Value does not fit in int: "
+ + l);
+ }
- return i;
+ return i;
}
/**
* Read an unsigned short from the stream.
- *
+ *
* @return the short value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream can not be represented as a
* positive short.
*/
public short read_ushort() throws OtpErlangDecodeException {
- final long l = this.read_long(true);
- final short i = (short) l;
+ final long l = this.read_long(true);
+ final short i = (short) l;
- if (l != (i & 0xffffL)) {
- throw new OtpErlangDecodeException("Value does not fit in ushort: "
- + l);
- }
+ if (l != (i & 0xffffL)) {
+ throw new OtpErlangDecodeException("Value does not fit in ushort: "
+ + l);
+ }
- return i;
+ return i;
}
/**
* Read a short from the stream.
- *
+ *
* @return the short value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream can not be represented as a
* short.
*/
public short read_short() throws OtpErlangDecodeException {
- final long l = this.read_long(false);
- final short i = (short) l;
+ final long l = this.read_long(false);
+ final short i = (short) l;
- if (l != i) {
- throw new OtpErlangDecodeException("Value does not fit in short: "
- + l);
- }
+ if (l != i) {
+ throw new OtpErlangDecodeException("Value does not fit in short: "
+ + l);
+ }
- return i;
+ return i;
}
/**
* Read an unsigned long from the stream.
- *
+ *
* @return the long value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream can not be represented as a
* positive long.
*/
public long read_ulong() throws OtpErlangDecodeException {
- return this.read_long(true);
+ return this.read_long(true);
}
/**
* Read a long from the stream.
- *
+ *
* @return the long value.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream can not be represented as a
* long.
*/
public long read_long() throws OtpErlangDecodeException {
- return this.read_long(false);
+ return this.read_long(false);
}
public long read_long(final boolean unsigned)
- throws OtpErlangDecodeException {
- final byte[] b = read_integer_byte_array();
- return OtpInputStream.byte_array_to_long(b, unsigned);
+ throws OtpErlangDecodeException {
+ final byte[] b = read_integer_byte_array();
+ return OtpInputStream.byte_array_to_long(b, unsigned);
}
/**
* Read an integer from the stream.
- *
+ *
* @return the value as a big endian 2's complement byte array.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an integer.
*/
public byte[] read_integer_byte_array() throws OtpErlangDecodeException {
- int tag;
- byte[] nb;
-
- tag = read1skip_version();
-
- switch (tag) {
- case OtpExternal.smallIntTag:
- nb = new byte[2];
- nb[0] = 0;
- nb[1] = (byte) read1();
- break;
-
- case OtpExternal.intTag:
- nb = new byte[4];
- if (this.readN(nb) != 4) { // Big endian
- throw new OtpErlangDecodeException(
- "Cannot read from intput stream");
- }
- break;
-
- case OtpExternal.smallBigTag:
- case OtpExternal.largeBigTag:
- int arity;
- int sign;
- if (tag == OtpExternal.smallBigTag) {
- arity = read1();
- sign = read1();
- } else {
- arity = read4BE();
- sign = read1();
- if (arity + 1 < 0) {
- throw new OtpErlangDecodeException(
- "Value of largeBig does not fit in BigInteger, arity "
- + arity + " sign " + sign);
- }
- }
- nb = new byte[arity + 1];
- // Value is read as little endian. The big end is augumented
- // with one zero byte to make the value 2's complement positive.
- if (this.readN(nb, 0, arity) != arity) {
- throw new OtpErlangDecodeException(
- "Cannot read from intput stream");
- }
- // Reverse the array to make it big endian.
- for (int i = 0, j = nb.length; i < j--; i++) {
- // Swap [i] with [j]
- final byte b = nb[i];
- nb[i] = nb[j];
- nb[j] = b;
- }
- if (sign != 0) {
- // 2's complement negate the big endian value in the array
- int c = 1; // Carry
- for (int j = nb.length; j-- > 0;) {
- c = (~nb[j] & 0xFF) + c;
- nb[j] = (byte) c;
- c >>= 8;
- }
- }
- break;
-
- default:
- throw new OtpErlangDecodeException("Not valid integer tag: " + tag);
- }
-
- return nb;
+ int tag;
+ byte[] nb;
+
+ tag = read1skip_version();
+
+ switch (tag) {
+ case OtpExternal.smallIntTag:
+ nb = new byte[2];
+ nb[0] = 0;
+ nb[1] = (byte) read1();
+ break;
+
+ case OtpExternal.intTag:
+ nb = new byte[4];
+ if (this.readN(nb) != 4) { // Big endian
+ throw new OtpErlangDecodeException(
+ "Cannot read from intput stream");
+ }
+ break;
+
+ case OtpExternal.smallBigTag:
+ case OtpExternal.largeBigTag:
+ int arity;
+ int sign;
+ if (tag == OtpExternal.smallBigTag) {
+ arity = read1();
+ sign = read1();
+ } else {
+ arity = read4BE();
+ sign = read1();
+ if (arity + 1 < 0) {
+ throw new OtpErlangDecodeException(
+ "Value of largeBig does not fit in BigInteger, arity "
+ + arity + " sign " + sign);
+ }
+ }
+ nb = new byte[arity + 1];
+ // Value is read as little endian. The big end is augumented
+ // with one zero byte to make the value 2's complement positive.
+ if (this.readN(nb, 0, arity) != arity) {
+ throw new OtpErlangDecodeException(
+ "Cannot read from intput stream");
+ }
+ // Reverse the array to make it big endian.
+ for (int i = 0, j = nb.length; i < j--; i++) {
+ // Swap [i] with [j]
+ final byte b = nb[i];
+ nb[i] = nb[j];
+ nb[j] = b;
+ }
+ if (sign != 0) {
+ // 2's complement negate the big endian value in the array
+ int c = 1; // Carry
+ for (int j = nb.length; j-- > 0;) {
+ c = (~nb[j] & 0xFF) + c;
+ nb[j] = (byte) c;
+ c >>= 8;
+ }
+ }
+ break;
+
+ default:
+ throw new OtpErlangDecodeException("Not valid integer tag: " + tag);
+ }
+
+ return nb;
}
public static long byte_array_to_long(final byte[] b, final boolean unsigned)
- throws OtpErlangDecodeException {
- long v;
- switch (b.length) {
- case 0:
- v = 0;
- break;
- case 2:
- v = ((b[0] & 0xFF) << 8) + (b[1] & 0xFF);
- v = (short) v; // Sign extend
- if (v < 0 && unsigned) {
- throw new OtpErlangDecodeException("Value not unsigned: " + v);
- }
- break;
- case 4:
- v = ((b[0] & 0xFF) << 24) + ((b[1] & 0xFF) << 16)
- + ((b[2] & 0xFF) << 8) + (b[3] & 0xFF);
- v = (int) v; // Sign extend
- if (v < 0 && unsigned) {
- throw new OtpErlangDecodeException("Value not unsigned: " + v);
- }
- break;
- default:
- int i = 0;
- final byte c = b[i];
- // Skip non-essential leading bytes
- if (unsigned) {
- if (c < 0) {
- throw new OtpErlangDecodeException("Value not unsigned: "
- + Arrays.toString(b));
- }
- while (b[i] == 0) {
- i++; // Skip leading zero sign bytes
- }
- } else {
- if (c == 0 || c == -1) { // Leading sign byte
- i = 1;
- // Skip all leading sign bytes
- while (i < b.length && b[i] == c) {
- i++;
- }
- if (i < b.length) {
- // Check first non-sign byte to see if its sign
- // matches the whole number's sign. If not one more
- // byte is needed to represent the value.
- if (((c ^ b[i]) & 0x80) != 0) {
- i--;
- }
- }
- }
- }
- if (b.length - i > 8) {
- // More than 64 bits of value
- throw new OtpErlangDecodeException(
- "Value does not fit in long: " + Arrays.toString(b));
- }
- // Convert the necessary bytes
- for (v = c < 0 ? -1 : 0; i < b.length; i++) {
- v = v << 8 | b[i] & 0xFF;
- }
- }
- return v;
+ throws OtpErlangDecodeException {
+ long v;
+ switch (b.length) {
+ case 0:
+ v = 0;
+ break;
+ case 2:
+ v = ((b[0] & 0xFF) << 8) + (b[1] & 0xFF);
+ v = (short) v; // Sign extend
+ if (v < 0 && unsigned) {
+ throw new OtpErlangDecodeException("Value not unsigned: " + v);
+ }
+ break;
+ case 4:
+ v = ((b[0] & 0xFF) << 24) + ((b[1] & 0xFF) << 16)
+ + ((b[2] & 0xFF) << 8) + (b[3] & 0xFF);
+ v = (int) v; // Sign extend
+ if (v < 0 && unsigned) {
+ throw new OtpErlangDecodeException("Value not unsigned: " + v);
+ }
+ break;
+ default:
+ int i = 0;
+ final byte c = b[i];
+ // Skip non-essential leading bytes
+ if (unsigned) {
+ if (c < 0) {
+ throw new OtpErlangDecodeException("Value not unsigned: "
+ + Arrays.toString(b));
+ }
+ while (b[i] == 0) {
+ i++; // Skip leading zero sign bytes
+ }
+ } else {
+ if (c == 0 || c == -1) { // Leading sign byte
+ i = 1;
+ // Skip all leading sign bytes
+ while (i < b.length && b[i] == c) {
+ i++;
+ }
+ if (i < b.length) {
+ // Check first non-sign byte to see if its sign
+ // matches the whole number's sign. If not one more
+ // byte is needed to represent the value.
+ if (((c ^ b[i]) & 0x80) != 0) {
+ i--;
+ }
+ }
+ }
+ }
+ if (b.length - i > 8) {
+ // More than 64 bits of value
+ throw new OtpErlangDecodeException(
+ "Value does not fit in long: " + Arrays.toString(b));
+ }
+ // Convert the necessary bytes
+ for (v = c < 0 ? -1 : 0; i < b.length; i++) {
+ v = v << 8 | b[i] & 0xFF;
+ }
+ }
+ return v;
}
/**
* Read a list header from the stream.
- *
+ *
* @return the arity of the list.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a list.
*/
public int read_list_head() throws OtpErlangDecodeException {
- int arity = 0;
- final int tag = read1skip_version();
+ int arity = 0;
+ final int tag = read1skip_version();
- switch (tag) {
- case OtpExternal.nilTag:
- arity = 0;
- break;
+ switch (tag) {
+ case OtpExternal.nilTag:
+ arity = 0;
+ break;
- case OtpExternal.stringTag:
- arity = read2BE();
- break;
+ case OtpExternal.stringTag:
+ arity = read2BE();
+ break;
- case OtpExternal.listTag:
- arity = read4BE();
- break;
+ case OtpExternal.listTag:
+ arity = read4BE();
+ break;
- default:
- throw new OtpErlangDecodeException("Not valid list tag: " + tag);
- }
+ default:
+ throw new OtpErlangDecodeException("Not valid list tag: " + tag);
+ }
- return arity;
+ return arity;
}
/**
* Read a tuple header from the stream.
- *
+ *
* @return the arity of the tuple.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a tuple.
*/
public int read_tuple_head() throws OtpErlangDecodeException {
- int arity = 0;
- final int tag = read1skip_version();
+ int arity = 0;
+ final int tag = read1skip_version();
- // decode the tuple header and get arity
- switch (tag) {
- case OtpExternal.smallTupleTag:
- arity = read1();
- break;
+ // decode the tuple header and get arity
+ switch (tag) {
+ case OtpExternal.smallTupleTag:
+ arity = read1();
+ break;
- case OtpExternal.largeTupleTag:
- arity = read4BE();
- break;
+ case OtpExternal.largeTupleTag:
+ arity = read4BE();
+ break;
- default:
- throw new OtpErlangDecodeException("Not valid tuple tag: " + tag);
- }
+ default:
+ throw new OtpErlangDecodeException("Not valid tuple tag: " + tag);
+ }
- return arity;
+ return arity;
}
/**
* Read an empty list from the stream.
- *
+ *
* @return zero (the arity of the list).
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an empty list.
*/
public int read_nil() throws OtpErlangDecodeException {
- int arity = 0;
- final int tag = read1skip_version();
+ int arity = 0;
+ final int tag = read1skip_version();
- switch (tag) {
- case OtpExternal.nilTag:
- arity = 0;
- break;
+ switch (tag) {
+ case OtpExternal.nilTag:
+ arity = 0;
+ break;
- default:
- throw new OtpErlangDecodeException("Not valid nil tag: " + tag);
- }
+ default:
+ throw new OtpErlangDecodeException("Not valid nil tag: " + tag);
+ }
- return arity;
+ return arity;
}
/**
* Read an Erlang PID from the stream.
- *
+ *
* @return the value of the PID.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an Erlang PID.
*/
public OtpErlangPid read_pid() throws OtpErlangDecodeException {
- String node;
- int id;
- int serial;
- int creation;
- int tag;
-
- tag = read1skip_version();
-
- if (tag != OtpExternal.pidTag) {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected " + OtpExternal.pidTag
- + ", got " + tag);
- }
-
- node = read_atom();
- id = read4BE() & 0x7fff; // 15 bits
- serial = read4BE() & 0x1fff; // 13 bits
- creation = read1() & 0x03; // 2 bits
-
- return new OtpErlangPid(node, id, serial, creation);
+ String node;
+ int id;
+ int serial;
+ int creation;
+ int tag;
+
+ tag = read1skip_version();
+
+ if (tag != OtpExternal.pidTag) {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected " + OtpExternal.pidTag
+ + ", got " + tag);
+ }
+
+ node = read_atom();
+ id = read4BE() & 0x7fff; // 15 bits
+ serial = read4BE() & 0x1fff; // 13 bits
+ creation = read1() & 0x03; // 2 bits
+
+ return new OtpErlangPid(node, id, serial, creation);
}
/**
* Read an Erlang port from the stream.
- *
+ *
* @return the value of the port.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an Erlang port.
*/
public OtpErlangPort read_port() throws OtpErlangDecodeException {
- String node;
- int id;
- int creation;
- int tag;
+ String node;
+ int id;
+ int creation;
+ int tag;
- tag = read1skip_version();
+ tag = read1skip_version();
- if (tag != OtpExternal.portTag) {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected " + OtpExternal.portTag
- + ", got " + tag);
- }
+ if (tag != OtpExternal.portTag) {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected " + OtpExternal.portTag
+ + ", got " + tag);
+ }
- node = read_atom();
- id = read4BE() & 0xfffffff; // 28 bits
- creation = read1() & 0x03; // 2 bits
+ node = read_atom();
+ id = read4BE() & 0xfffffff; // 28 bits
+ creation = read1() & 0x03; // 2 bits
- return new OtpErlangPort(node, id, creation);
+ return new OtpErlangPort(node, id, creation);
}
/**
* Read an Erlang reference from the stream.
- *
+ *
* @return the value of the reference
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not an Erlang reference.
*/
public OtpErlangRef read_ref() throws OtpErlangDecodeException {
- String node;
- int id;
- int creation;
- int tag;
-
- tag = read1skip_version();
-
- switch (tag) {
- case OtpExternal.refTag:
- node = read_atom();
- id = read4BE() & 0x3ffff; // 18 bits
- creation = read1() & 0x03; // 2 bits
- return new OtpErlangRef(node, id, creation);
-
- case OtpExternal.newRefTag:
- final int arity = read2BE();
- node = read_atom();
- creation = read1() & 0x03; // 2 bits
-
- final int[] ids = new int[arity];
- for (int i = 0; i < arity; i++) {
- ids[i] = read4BE();
- }
- ids[0] &= 0x3ffff; // first id gets truncated to 18 bits
- return new OtpErlangRef(node, ids, creation);
-
- default:
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected ref, got " + tag);
- }
+ String node;
+ int id;
+ int creation;
+ int tag;
+
+ tag = read1skip_version();
+
+ switch (tag) {
+ case OtpExternal.refTag:
+ node = read_atom();
+ id = read4BE() & 0x3ffff; // 18 bits
+ creation = read1() & 0x03; // 2 bits
+ return new OtpErlangRef(node, id, creation);
+
+ case OtpExternal.newRefTag:
+ final int arity = read2BE();
+ node = read_atom();
+ creation = read1() & 0x03; // 2 bits
+
+ final int[] ids = new int[arity];
+ for (int i = 0; i < arity; i++) {
+ ids[i] = read4BE();
+ }
+ ids[0] &= 0x3ffff; // first id gets truncated to 18 bits
+ return new OtpErlangRef(node, ids, creation);
+
+ default:
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected ref, got " + tag);
+ }
}
public OtpErlangFun read_fun() throws OtpErlangDecodeException {
- final int tag = read1skip_version();
- if (tag == OtpExternal.funTag) {
- final int nFreeVars = read4BE();
- final OtpErlangPid pid = read_pid();
- final String module = read_atom();
- final long index = read_long();
- final long uniq = read_long();
- final OtpErlangObject[] freeVars = new OtpErlangObject[nFreeVars];
- for (int i = 0; i < nFreeVars; ++i) {
- freeVars[i] = read_any();
- }
- return new OtpErlangFun(pid, module, index, uniq, freeVars);
- } else if (tag == OtpExternal.newFunTag) {
- read4BE();
- final int arity = read1();
- final byte[] md5 = new byte[16];
- readN(md5);
- final int index = read4BE();
- final int nFreeVars = read4BE();
- final String module = read_atom();
- final long oldIndex = read_long();
- final long uniq = read_long();
- final OtpErlangPid pid = read_pid();
- final OtpErlangObject[] freeVars = new OtpErlangObject[nFreeVars];
- for (int i = 0; i < nFreeVars; ++i) {
- freeVars[i] = read_any();
- }
- return new OtpErlangFun(pid, module, arity, md5, index, oldIndex,
- uniq, freeVars);
- } else {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected fun, got " + tag);
- }
+ final int tag = read1skip_version();
+ if (tag == OtpExternal.funTag) {
+ final int nFreeVars = read4BE();
+ final OtpErlangPid pid = read_pid();
+ final String module = read_atom();
+ final long index = read_long();
+ final long uniq = read_long();
+ final OtpErlangObject[] freeVars = new OtpErlangObject[nFreeVars];
+ for (int i = 0; i < nFreeVars; ++i) {
+ freeVars[i] = read_any();
+ }
+ return new OtpErlangFun(pid, module, index, uniq, freeVars);
+ } else if (tag == OtpExternal.newFunTag) {
+ read4BE();
+ final int arity = read1();
+ final byte[] md5 = new byte[16];
+ readN(md5);
+ final int index = read4BE();
+ final int nFreeVars = read4BE();
+ final String module = read_atom();
+ final long oldIndex = read_long();
+ final long uniq = read_long();
+ final OtpErlangPid pid = read_pid();
+ final OtpErlangObject[] freeVars = new OtpErlangObject[nFreeVars];
+ for (int i = 0; i < nFreeVars; ++i) {
+ freeVars[i] = read_any();
+ }
+ return new OtpErlangFun(pid, module, arity, md5, index, oldIndex,
+ uniq, freeVars);
+ } else {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected fun, got " + tag);
+ }
}
public OtpErlangExternalFun read_external_fun()
- throws OtpErlangDecodeException {
- final int tag = read1skip_version();
- if (tag != OtpExternal.externalFunTag) {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected external fun, got " + tag);
- }
- final String module = read_atom();
- final String function = read_atom();
- final int arity = (int) read_long();
- return new OtpErlangExternalFun(module, function, arity);
+ throws OtpErlangDecodeException {
+ final int tag = read1skip_version();
+ if (tag != OtpExternal.externalFunTag) {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected external fun, got " + tag);
+ }
+ final String module = read_atom();
+ final String function = read_atom();
+ final int arity = (int) read_long();
+ return new OtpErlangExternalFun(module, function, arity);
}
/**
* Read a string from the stream.
- *
+ *
* @return the value of the string.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a string.
*/
public String read_string() throws OtpErlangDecodeException {
- int tag;
- int len;
- byte[] strbuf;
- int[] intbuf;
- tag = read1skip_version();
- switch (tag) {
- case OtpExternal.stringTag:
- len = read2BE();
- strbuf = new byte[len];
- this.readN(strbuf);
- return OtpErlangString.newString(strbuf);
- case OtpExternal.nilTag:
- return "";
- case OtpExternal.listTag: // List when unicode +
- len = read4BE();
- intbuf = new int[len];
- for (int i = 0; i < len; i++) {
- intbuf[i] = read_int();
- if (! OtpErlangString.isValidCodePoint(intbuf[i])) {
- throw new OtpErlangDecodeException
- ("Invalid CodePoint: " + intbuf[i]);
- }
- }
- read_nil();
- return new String(intbuf, 0, intbuf.length);
- default:
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected " + OtpExternal.stringTag
- + " or " + OtpExternal.listTag + ", got " + tag);
- }
+ int tag;
+ int len;
+ byte[] strbuf;
+ int[] intbuf;
+ tag = read1skip_version();
+ switch (tag) {
+ case OtpExternal.stringTag:
+ len = read2BE();
+ strbuf = new byte[len];
+ this.readN(strbuf);
+ return OtpErlangString.newString(strbuf);
+ case OtpExternal.nilTag:
+ return "";
+ case OtpExternal.listTag: // List when unicode +
+ len = read4BE();
+ intbuf = new int[len];
+ for (int i = 0; i < len; i++) {
+ intbuf[i] = read_int();
+ if (!OtpErlangString.isValidCodePoint(intbuf[i])) {
+ throw new OtpErlangDecodeException("Invalid CodePoint: "
+ + intbuf[i]);
+ }
+ }
+ read_nil();
+ return new String(intbuf, 0, intbuf.length);
+ default:
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected " + OtpExternal.stringTag
+ + " or " + OtpExternal.listTag + ", got " + tag);
+ }
}
/**
* Read a compressed term from the stream
- *
+ *
* @return the resulting uncompressed term.
- *
+ *
* @exception OtpErlangDecodeException
* if the next term in the stream is not a compressed term.
*/
public OtpErlangObject read_compressed() throws OtpErlangDecodeException {
- final int tag = read1skip_version();
-
- if (tag != OtpExternal.compressedTag) {
- throw new OtpErlangDecodeException(
- "Wrong tag encountered, expected "
- + OtpExternal.compressedTag + ", got " + tag);
- }
-
- final int size = read4BE();
- final byte[] abuf = new byte[size];
- final java.util.zip.InflaterInputStream is =
- new java.util.zip.InflaterInputStream(this, new java.util.zip.Inflater(), size);
- int curPos = 0;
- try {
- int curRead;
- while(curPos < size && (curRead = is.read(abuf, curPos, size - curPos)) != -1) {
- curPos += curRead;
- }
- if (curPos != size) {
- throw new OtpErlangDecodeException("Decompression gave "
- + curPos + " bytes, not " + size);
- }
- } catch (final IOException e) {
- throw new OtpErlangDecodeException("Cannot read from input stream");
- }
-
- @SuppressWarnings("resource")
- final OtpInputStream ois = new OtpInputStream(abuf, flags);
- return ois.read_any();
+ final int tag = read1skip_version();
+
+ if (tag != OtpExternal.compressedTag) {
+ throw new OtpErlangDecodeException(
+ "Wrong tag encountered, expected "
+ + OtpExternal.compressedTag + ", got " + tag);
+ }
+
+ final int size = read4BE();
+ final byte[] abuf = new byte[size];
+ final java.util.zip.InflaterInputStream is = new java.util.zip.InflaterInputStream(
+ this, new java.util.zip.Inflater(), size);
+ int curPos = 0;
+ try {
+ int curRead;
+ while (curPos < size
+ && (curRead = is.read(abuf, curPos, size - curPos)) != -1) {
+ curPos += curRead;
+ }
+ if (curPos != size) {
+ throw new OtpErlangDecodeException("Decompression gave "
+ + curPos + " bytes, not " + size);
+ }
+ } catch (final IOException e) {
+ throw new OtpErlangDecodeException("Cannot read from input stream");
+ }
+
+ @SuppressWarnings("resource")
+ final OtpInputStream ois = new OtpInputStream(abuf, flags);
+ return ois.read_any();
}
/**
* Read an arbitrary Erlang term from the stream.
- *
+ *
* @return the Erlang term.
- *
+ *
* @exception OtpErlangDecodeException
* if the stream does not contain a known Erlang type at the
* next position.
*/
public OtpErlangObject read_any() throws OtpErlangDecodeException {
- // calls one of the above functions, depending on o
- final int tag = peek1skip_version();
+ // calls one of the above functions, depending on o
+ final int tag = peek1skip_version();
- switch (tag) {
- case OtpExternal.smallIntTag:
- case OtpExternal.intTag:
- case OtpExternal.smallBigTag:
- case OtpExternal.largeBigTag:
- return new OtpErlangLong(this);
+ switch (tag) {
+ case OtpExternal.smallIntTag:
+ case OtpExternal.intTag:
+ case OtpExternal.smallBigTag:
+ case OtpExternal.largeBigTag:
+ return new OtpErlangLong(this);
- case OtpExternal.atomTag:
- case OtpExternal.smallAtomUtf8Tag:
- case OtpExternal.atomUtf8Tag:
- return new OtpErlangAtom(this);
+ case OtpExternal.atomTag:
+ case OtpExternal.smallAtomUtf8Tag:
+ case OtpExternal.atomUtf8Tag:
+ return new OtpErlangAtom(this);
- case OtpExternal.floatTag:
- case OtpExternal.newFloatTag:
- return new OtpErlangDouble(this);
+ case OtpExternal.floatTag:
+ case OtpExternal.newFloatTag:
+ return new OtpErlangDouble(this);
- case OtpExternal.refTag:
- case OtpExternal.newRefTag:
- return new OtpErlangRef(this);
+ case OtpExternal.refTag:
+ case OtpExternal.newRefTag:
+ return new OtpErlangRef(this);
case OtpExternal.mapTag:
return new OtpErlangMap(this);
- case OtpExternal.portTag:
- return new OtpErlangPort(this);
+ case OtpExternal.portTag:
+ return new OtpErlangPort(this);
- case OtpExternal.pidTag:
- return new OtpErlangPid(this);
+ case OtpExternal.pidTag:
+ return new OtpErlangPid(this);
- case OtpExternal.stringTag:
- return new OtpErlangString(this);
+ case OtpExternal.stringTag:
+ return new OtpErlangString(this);
- case OtpExternal.listTag:
- case OtpExternal.nilTag:
- if ((flags & DECODE_INT_LISTS_AS_STRINGS) != 0) {
- final int savePos = getPos();
- try {
- return new OtpErlangString(this);
- } catch (final OtpErlangDecodeException e) {
- }
- setPos(savePos);
- }
- return new OtpErlangList(this);
+ case OtpExternal.listTag:
+ case OtpExternal.nilTag:
+ if ((flags & DECODE_INT_LISTS_AS_STRINGS) != 0) {
+ final int savePos = getPos();
+ try {
+ return new OtpErlangString(this);
+ } catch (final OtpErlangDecodeException e) {
+ }
+ setPos(savePos);
+ }
+ return new OtpErlangList(this);
- case OtpExternal.smallTupleTag:
- case OtpExternal.largeTupleTag:
- return new OtpErlangTuple(this);
+ case OtpExternal.smallTupleTag:
+ case OtpExternal.largeTupleTag:
+ return new OtpErlangTuple(this);
- case OtpExternal.binTag:
- return new OtpErlangBinary(this);
+ case OtpExternal.binTag:
+ return new OtpErlangBinary(this);
- case OtpExternal.bitBinTag:
- return new OtpErlangBitstr(this);
+ case OtpExternal.bitBinTag:
+ return new OtpErlangBitstr(this);
- case OtpExternal.compressedTag:
- return read_compressed();
+ case OtpExternal.compressedTag:
+ return read_compressed();
- case OtpExternal.newFunTag:
- case OtpExternal.funTag:
- return new OtpErlangFun(this);
+ case OtpExternal.newFunTag:
+ case OtpExternal.funTag:
+ return new OtpErlangFun(this);
- default:
- throw new OtpErlangDecodeException("Uknown data type: " + tag);
- }
+ case OtpExternal.externalFunTag:
+ return new OtpErlangExternalFun(this);
+
+ default:
+ throw new OtpErlangDecodeException("Uknown data type: " + tag);
+ }
}
public int read_map_head() throws OtpErlangDecodeException {
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpLocalNode.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpLocalNode.java
index fbd0eb4073..3d6b15ad64 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpLocalNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpLocalNode.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -29,89 +30,103 @@ public class OtpLocalNode extends AbstractNode {
private int refId[];
protected int port;
- protected java.net.Socket epmd;
-
- protected OtpLocalNode() {
- super();
- init();
- }
+ protected OtpTransport epmd;
/**
* Create a node with the given name and the default cookie.
*/
protected OtpLocalNode(final String node) {
- super(node);
- init();
+ super(node);
+ init();
+ }
+
+ /**
+ * Create a node with the given name, transport factory and the default
+ * cookie.
+ */
+ protected OtpLocalNode(final String node,
+ final OtpTransportFactory transportFactory) {
+ super(node, transportFactory);
+ init();
}
/**
* Create a node with the given name and cookie.
*/
protected OtpLocalNode(final String node, final String cookie) {
- super(node, cookie);
- init();
+ super(node, cookie);
+ init();
+ }
+
+ /**
+ * Create a node with the given name, cookie and transport factory.
+ */
+ protected OtpLocalNode(final String node, final String cookie,
+ final OtpTransportFactory transportFactory) {
+ super(node, cookie, transportFactory);
+ init();
}
private void init() {
- serial = 0;
- pidCount = 1;
- portCount = 1;
- refId = new int[3];
- refId[0] = 1;
- refId[1] = 0;
- refId[2] = 0;
+ serial = 0;
+ pidCount = 1;
+ portCount = 1;
+ refId = new int[3];
+ refId[0] = 1;
+ refId[1] = 0;
+ refId[2] = 0;
}
/**
* Get the port number used by this node.
- *
+ *
* @return the port number this server node is accepting connections on.
*/
public int port() {
- return port;
+ return port;
}
/**
* Set the Epmd socket after publishing this nodes listen port to Epmd.
- *
+ *
* @param s
- * The socket connecting this node to Epmd.
+ * The socket connecting this node to Epmd.
*/
- protected void setEpmd(final java.net.Socket s) {
- epmd = s;
+ protected void setEpmd(final OtpTransport s) {
+ epmd = s;
}
/**
* Get the Epmd socket.
- *
+ *
* @return The socket connecting this node to Epmd.
*/
- protected java.net.Socket getEpmd() {
- return epmd;
+ protected OtpTransport getEpmd() {
+ return epmd;
}
/**
* Create an Erlang {@link OtpErlangPid pid}. Erlang pids are based upon
* some node specific information; this method creates a pid using the
* information in this node. Each call to this method produces a unique pid.
- *
+ *
* @return an Erlang pid.
*/
public synchronized OtpErlangPid createPid() {
- final OtpErlangPid p = new OtpErlangPid(node, pidCount, serial,
- creation);
+ final OtpErlangPid p = new OtpErlangPid(node, pidCount, serial,
+ creation);
- pidCount++;
- if (pidCount > 0x7fff) {
- pidCount = 0;
+ pidCount++;
+ if (pidCount > 0x7fff) {
+ pidCount = 0;
- serial++;
- if (serial > 0x1fff) { /* 13 bits */
- serial = 0;
- }
- }
+ serial++;
+ if (serial > 0x1fff) { /* 13 bits */
+ serial = 0;
+ }
+ }
- return p;
+ return p;
}
/**
@@ -120,18 +135,18 @@ public class OtpLocalNode extends AbstractNode {
* information in this node. Each call to this method produces a unique
* port. It may not be meaningful to create a port in a non-Erlang
* environment, but this method is provided for completeness.
- *
+ *
* @return an Erlang port.
*/
public synchronized OtpErlangPort createPort() {
- final OtpErlangPort p = new OtpErlangPort(node, portCount, creation);
+ final OtpErlangPort p = new OtpErlangPort(node, portCount, creation);
- portCount++;
- if (portCount > 0xfffffff) { /* 28 bits */
- portCount = 0;
- }
+ portCount++;
+ if (portCount > 0xfffffff) { /* 28 bits */
+ portCount = 0;
+ }
- return p;
+ return p;
}
/**
@@ -139,23 +154,23 @@ public class OtpLocalNode extends AbstractNode {
* based upon some node specific information; this method creates a
* reference using the information in this node. Each call to this method
* produces a unique reference.
- *
+ *
* @return an Erlang reference.
*/
public synchronized OtpErlangRef createRef() {
- final OtpErlangRef r = new OtpErlangRef(node, refId, creation);
+ final OtpErlangRef r = new OtpErlangRef(node, refId, creation);
- // increment ref ids (3 ints: 18 + 32 + 32 bits)
- refId[0]++;
- if (refId[0] > 0x3ffff) {
- refId[0] = 0;
+ // increment ref ids (3 ints: 18 + 32 + 32 bits)
+ refId[0]++;
+ if (refId[0] > 0x3ffff) {
+ refId[0] = 0;
- refId[1]++;
- if (refId[1] == 0) {
- refId[2]++;
- }
- }
+ refId[1]++;
+ if (refId[1] == 0) {
+ refId[2]++;
+ }
+ }
- return r;
+ return r;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java
index a5a4d86602..6d1a04d9f0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -46,37 +47,37 @@ class OtpMD5 {
*/
private final long state[] = { 0x67452301L, 0xefcdab89L, 0x98badcfeL,
- 0x10325476L };
+ 0x10325476L };
private final long count[] = { 0L, 0L };
private final int buffer[];
public OtpMD5() {
- buffer = new int[64];
- int i;
- for (i = 0; i < 64; ++i) {
- buffer[i] = 0;
- }
+ buffer = new int[64];
+ int i;
+ for (i = 0; i < 64; ++i) {
+ buffer[i] = 0;
+ }
}
private int[] to_bytes(final String s) {
- final char tmp[] = s.toCharArray();
- final int ret[] = new int[tmp.length];
- int i;
-
- for (i = 0; i < tmp.length; ++i) {
- ret[i] = tmp[i] & 0xFF;
- }
- return ret;
+ final char tmp[] = s.toCharArray();
+ final int ret[] = new int[tmp.length];
+ int i;
+
+ for (i = 0; i < tmp.length; ++i) {
+ ret[i] = tmp[i] & 0xFF;
+ }
+ return ret;
}
private int[] clean_bytes(final int bytes[]) {
- final int ret[] = new int[bytes.length];
- int i;
+ final int ret[] = new int[bytes.length];
+ int i;
- for (i = 0; i < bytes.length; ++i) {
- ret[i] = bytes[i] & 0xFF;
- }
- return ret;
+ for (i = 0; i < bytes.length; ++i) {
+ ret[i] = bytes[i] & 0xFF;
+ }
+ return ret;
}
/*
@@ -84,83 +85,83 @@ class OtpMD5 {
*/
private long shl(final long what, final int steps) {
- return what << steps & 0xFFFFFFFFL;
+ return what << steps & 0xFFFFFFFFL;
}
private long shr(final long what, final int steps) {
- return what >>> steps;
+ return what >>> steps;
}
private long plus(final long a, final long b) {
- return a + b & 0xFFFFFFFFL;
+ return a + b & 0xFFFFFFFFL;
}
- private long not(long x) {
- return ~x & 0xFFFFFFFFL;
+ private long not(final long x) {
+ return ~x & 0xFFFFFFFFL;
}
- private void to_buffer(int to_start, final int[] from, int from_start,
- int num) {
- int ix = num;
- int to_ix = to_start;
- int from_ix = from_start;
- while (ix-- > 0) {
- buffer[to_ix++] = from[from_ix++];
- }
+ private void to_buffer(final int to_start, final int[] from,
+ final int from_start, final int num) {
+ int ix = num;
+ int to_ix = to_start;
+ int from_ix = from_start;
+ while (ix-- > 0) {
+ buffer[to_ix++] = from[from_ix++];
+ }
}
private void do_update(final int bytes[]) {
- int index = (int) (count[0] >>> 3 & 0x3F);
- final long inlen = bytes.length;
- final long addcount = shl(inlen, 3);
- final long partlen = 64 - index;
- int i;
+ int index = (int) (count[0] >>> 3 & 0x3F);
+ final long inlen = bytes.length;
+ final long addcount = shl(inlen, 3);
+ final long partlen = 64 - index;
+ int i;
- count[0] = plus(count[0], addcount);
+ count[0] = plus(count[0], addcount);
- if (count[0] < addcount) {
- ++count[1];
- }
+ if (count[0] < addcount) {
+ ++count[1];
+ }
- count[1] = plus(count[1], shr(inlen, 29));
+ count[1] = plus(count[1], shr(inlen, 29));
- // dumpstate();
+ // dumpstate();
- if (inlen >= partlen) {
- to_buffer(index, bytes, 0, (int) partlen);
- transform(buffer, 0);
+ if (inlen >= partlen) {
+ to_buffer(index, bytes, 0, (int) partlen);
+ transform(buffer, 0);
- for (i = (int) partlen; i + 63 < inlen; i += 64) {
- transform(bytes, i);
- }
+ for (i = (int) partlen; i + 63 < inlen; i += 64) {
+ transform(bytes, i);
+ }
- index = 0;
- } else {
- i = 0;
- }
+ index = 0;
+ } else {
+ i = 0;
+ }
- /* dumpstate(); */
+ /* dumpstate(); */
- to_buffer(index, bytes, i, (int) inlen - i);
+ to_buffer(index, bytes, i, (int) inlen - i);
- /* dumpstate(); */
+ /* dumpstate(); */
}
@SuppressWarnings("unused")
private void dumpstate() {
- System.out.println("state = {" + state[0] + ", " + state[1] + ", "
- + state[2] + ", " + state[3] + "}");
- System.out.println("count = {" + count[0] + ", " + count[1] + "}");
- System.out.print("buffer = {");
- int i;
- for (i = 0; i < 64; ++i) {
- if (i > 0) {
- System.out.print(", ");
- }
- System.out.print(buffer[i]);
- }
- System.out.println("}");
+ System.out.println("state = {" + state[0] + ", " + state[1] + ", "
+ + state[2] + ", " + state[3] + "}");
+ System.out.println("count = {" + count[0] + ", " + count[1] + "}");
+ System.out.print("buffer = {");
+ int i;
+ for (i = 0; i < 64; ++i) {
+ if (i > 0) {
+ System.out.print(", ");
+ }
+ System.out.print(buffer[i]);
+ }
+ System.out.println("}");
}
/*
@@ -168,191 +169,191 @@ class OtpMD5 {
*/
private long F(final long x, final long y, final long z) {
- return x & y | not(x) & z;
+ return x & y | not(x) & z;
}
private long G(final long x, final long y, final long z) {
- return x & z | y & not(z);
+ return x & z | y & not(z);
}
private long H(final long x, final long y, final long z) {
- return x ^ y ^ z;
+ return x ^ y ^ z;
}
private long I(final long x, final long y, final long z) {
- return y ^ (x | not(z));
+ return y ^ (x | not(z));
}
private long ROTATE_LEFT(final long x, final long n) {
- return shl(x, (int) n) | shr(x, (int) (32 - n));
+ return shl(x, (int) n) | shr(x, (int) (32 - n));
}
- private long FF(long a, final long b, final long c, final long d,
- final long x, final long s, final long ac) {
- long tmp = plus(a, plus(plus(F(b, c, d), x), ac));
- tmp = ROTATE_LEFT(tmp, s);
- return plus(tmp, b);
+ private long FF(final long a, final long b, final long c, final long d,
+ final long x, final long s, final long ac) {
+ long tmp = plus(a, plus(plus(F(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
- private long GG(long a, final long b, final long c, final long d,
- final long x, final long s, final long ac) {
- long tmp = plus(a, plus(plus(G(b, c, d), x), ac));
- tmp = ROTATE_LEFT(tmp, s);
- return plus(tmp, b);
+ private long GG(final long a, final long b, final long c, final long d,
+ final long x, final long s, final long ac) {
+ long tmp = plus(a, plus(plus(G(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
- private long HH(long a, final long b, final long c, final long d,
- final long x, final long s, final long ac) {
- long tmp = plus(a, plus(plus(H(b, c, d), x), ac));
- tmp = ROTATE_LEFT(tmp, s);
- return plus(tmp, b);
+ private long HH(final long a, final long b, final long c, final long d,
+ final long x, final long s, final long ac) {
+ long tmp = plus(a, plus(plus(H(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
- private long II(long a, final long b, final long c, final long d,
- final long x, final long s, final long ac) {
- long tmp = plus(a, plus(plus(I(b, c, d), x), ac));
- tmp = ROTATE_LEFT(tmp, s);
- return plus(tmp, b);
+ private long II(final long a, final long b, final long c, final long d,
+ final long x, final long s, final long ac) {
+ long tmp = plus(a, plus(plus(I(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
private void decode(final long output[], final int input[],
- final int in_from, final int len) {
- int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[i] = input[j + in_from] | shl(input[j + in_from + 1], 8)
- | shl(input[j + in_from + 2], 16)
- | shl(input[j + in_from + 3], 24);
- }
+ final int in_from, final int len) {
+ int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[i] = input[j + in_from] | shl(input[j + in_from + 1], 8)
+ | shl(input[j + in_from + 2], 16)
+ | shl(input[j + in_from + 3], 24);
+ }
}
private void transform(final int block[], final int from) {
- long a = state[0];
- long b = state[1];
- long c = state[2];
- long d = state[3];
- final long x[] = new long[16];
-
- decode(x, block, from, 64);
-
- a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
- d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
- c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
- b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
- a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
- d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
- c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
- b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
- a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
- d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
- c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
- b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
- a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
- d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
- c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
- b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
-
- /* Round 2 */
- a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
- d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
- c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
- b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
- a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
- d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
- c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
- b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
- a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
- d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
- c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
- b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
- a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
- d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
- c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
- b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
-
- /* Round 3 */
- a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
- d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
- c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
- b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
- a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
- d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
- c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
- b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
- a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
- d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
- c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
- b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
- a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
- d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
- c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
- b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
-
- /* Round 4 */
- a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
- d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
- c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
- b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
- a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
- d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
- c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
- b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
- a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
- d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
- c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
- b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
- a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
- d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
- c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
- b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
-
- state[0] = plus(state[0], a);
- state[1] = plus(state[1], b);
- state[2] = plus(state[2], c);
- state[3] = plus(state[3], d);
+ long a = state[0];
+ long b = state[1];
+ long c = state[2];
+ long d = state[3];
+ final long x[] = new long[16];
+
+ decode(x, block, from, 64);
+
+ a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
+ d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
+ c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
+ b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
+ a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
+ d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
+ c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
+ b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
+ a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
+ d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
+ c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
+ b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
+ a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
+ d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
+ c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
+ b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
+
+ /* Round 2 */
+ a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
+ d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
+ c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
+ b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
+ a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
+ d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
+ c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
+ b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
+ a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
+ d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
+ c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
+ b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
+ a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
+ d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
+ c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
+ b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
+
+ /* Round 3 */
+ a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
+ d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
+ c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
+ b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
+ a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
+ d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
+ c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
+ b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
+ a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
+ d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
+ c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
+ b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
+ a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
+ d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
+ c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
+ b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
+
+ /* Round 4 */
+ a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
+ d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
+ c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
+ b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
+ a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
+ d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
+ c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
+ b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
+ a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
+ d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
+ c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
+ b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
+ a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
+ d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
+ c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
+ b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
+
+ state[0] = plus(state[0], a);
+ state[1] = plus(state[1], b);
+ state[2] = plus(state[2], c);
+ state[3] = plus(state[3], d);
}
public void update(final int bytes[]) {
- do_update(clean_bytes(bytes));
+ do_update(clean_bytes(bytes));
}
public void update(final String s) {
- do_update(to_bytes(s));
+ do_update(to_bytes(s));
}
private int[] encode(final long[] input, final int len) {
- final int output[] = new int[len];
- int i, j;
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (int) (input[i] & 0xff);
- output[j + 1] = (int) (input[i] >>> 8 & 0xff);
- output[j + 2] = (int) (input[i] >>> 16 & 0xff);
- output[j + 3] = (int) (input[i] >>> 24 & 0xff);
- }
- return output;
+ final int output[] = new int[len];
+ int i, j;
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (int) (input[i] & 0xff);
+ output[j + 1] = (int) (input[i] >>> 8 & 0xff);
+ output[j + 2] = (int) (input[i] >>> 16 & 0xff);
+ output[j + 3] = (int) (input[i] >>> 24 & 0xff);
+ }
+ return output;
}
public int[] final_bytes() {
- final int bits[] = encode(count, 8);
- int index, padlen;
- int padding[], i;
- int[] digest;
+ final int bits[] = encode(count, 8);
+ int index, padlen;
+ int padding[], i;
+ int[] digest;
- index = (int) (count[0] >>> 3 & 0x3f);
- padlen = index < 56 ? 56 - index : 120 - index;
- /* padlen > 0 */
- padding = new int[padlen];
- padding[0] = 0x80;
- for (i = 1; i < padlen; ++i) {
- padding[i] = 0;
- }
+ index = (int) (count[0] >>> 3 & 0x3f);
+ padlen = index < 56 ? 56 - index : 120 - index;
+ /* padlen > 0 */
+ padding = new int[padlen];
+ padding[0] = 0x80;
+ for (i = 1; i < padlen; ++i) {
+ padding[i] = 0;
+ }
- do_update(padding);
+ do_update(padding);
- do_update(bits);
+ do_update(bits);
- digest = encode(state, 16);
+ digest = encode(state, 16);
- return digest;
+ return digest;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
index fc592c222c..29119dec5c 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2012. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -23,7 +24,7 @@ package com.ericsson.otp.erlang;
* Provides a simple mechanism for exchanging messages with Erlang processes or
* other instances of this class.
* </p>
- *
+ *
* <p>
* Each mailbox is associated with a unique {@link OtpErlangPid pid} that
* contains information necessary for delivery of messages. When sending
@@ -33,7 +34,7 @@ package com.ericsson.otp.erlang;
* message contents. The sender can determine his own pid by calling
* {@link #self() self()}.
* </p>
- *
+ *
* <p>
* Mailboxes can be named, either at creation or later. Messages can be sent to
* named mailboxes and named Erlang processes without knowing the
@@ -41,7 +42,7 @@ package com.ericsson.otp.erlang;
* order to set up initial communication between parts of an application. Each
* mailbox can have at most one name.
* </p>
- *
+ *
* <p>
* Since this class was intended for communication with Erlang, all of the send
* methods take {@link OtpErlangObject OtpErlangObject} arguments. However this
@@ -49,14 +50,14 @@ package com.ericsson.otp.erlang;
* implement one of java.io.Serializable or java.io.Externalizable) by
* encapsulating the object in a {@link OtpErlangBinary OtpErlangBinary}.
* </p>
- *
+ *
* <p>
* Messages to remote nodes are externalized for transmission, and as a result
* the recipient receives a <b>copy</b> of the original Java object. To ensure
* consistent behaviour when messages are sent between local mailboxes, such
* messages are cloned before delivery.
* </p>
- *
+ *
* <p>
* Additionally, mailboxes can be linked in much the same way as Erlang
* processes. If a link is active when a mailbox is {@link #close closed}, any
@@ -68,14 +69,14 @@ package com.ericsson.otp.erlang;
* close mailboxes if you are using links instead of relying on finalization to
* notify other parties in a timely manner.
* </p>
- *
+ *
* <p>
* When retrieving messages from a mailbox that has received an exit signal, an
* {@link OtpErlangExit OtpErlangExit} exception will be raised. Note that the
* exception is queued in the mailbox along with other messages, and will not be
* raised until it reaches the head of the queue and is about to be retrieved.
* </p>
- *
+ *
*/
public class OtpMbox {
OtpNode home;
@@ -87,17 +88,17 @@ public class OtpMbox {
// package constructor: called by OtpNode:createMbox(name)
// to create a named mbox
OtpMbox(final OtpNode home, final OtpErlangPid self, final String name) {
- this.self = self;
- this.home = home;
- this.name = name;
- queue = new GenericQueue();
- links = new Links(10);
+ this.self = self;
+ this.home = home;
+ this.name = name;
+ queue = new GenericQueue();
+ links = new Links(10);
}
// package constructor: called by OtpNode:createMbox()
// to create an anonymous
OtpMbox(final OtpNode home, final OtpErlangPid self) {
- this(home, self, null);
+ this(home, self, null);
}
/**
@@ -105,18 +106,18 @@ public class OtpMbox {
* Get the identifying {@link OtpErlangPid pid} associated with this
* mailbox.
* </p>
- *
+ *
* <p>
* The {@link OtpErlangPid pid} associated with this mailbox uniquely
* identifies the mailbox and can be used to address the mailbox. You can
* send the {@link OtpErlangPid pid} to a remote communicating part so that
* he can know where to send his response.
* </p>
- *
+ *
* @return the self pid for this mailbox.
*/
public OtpErlangPid self() {
- return self;
+ return self;
}
/**
@@ -127,305 +128,305 @@ public class OtpMbox {
* name; if the mailbox already had a name, calling this method will
* supercede that name.
* </p>
- *
+ *
* @param aname
- * the name to register for the mailbox. Specify null to
- * unregister the existing name from this mailbox.
- *
+ * the name to register for the mailbox. Specify null to
+ * unregister the existing name from this mailbox.
+ *
* @return true if the name was available, or false otherwise.
*/
public synchronized boolean registerName(final String aname) {
- return home.registerName(aname, this);
+ return home.registerName(aname, this);
}
/**
* Get the registered name of this mailbox.
- *
+ *
* @return the registered name of this mailbox, or null if the mailbox had
* no registered name.
*/
public String getName() {
- return name;
+ return name;
}
/**
* Block until a message arrives for this mailbox.
- *
+ *
* @return an {@link OtpErlangObject OtpErlangObject} representing the body
* of the next message waiting in this mailbox.
- *
+ *
* @exception OtpErlangDecodeException
- * if the message can not be decoded.
- *
+ * if the message can not be decoded.
+ *
* @exception OtpErlangExit
- * if a linked {@link OtpErlangPid pid} has exited or has
- * sent an exit signal to this mailbox.
+ * if a linked {@link OtpErlangPid pid} has exited or has
+ * sent an exit signal to this mailbox.
*/
public OtpErlangObject receive() throws OtpErlangExit,
- OtpErlangDecodeException {
- try {
- return receiveMsg().getMsg();
- } catch (final OtpErlangExit e) {
- throw e;
- } catch (final OtpErlangDecodeException f) {
- throw f;
- }
+ OtpErlangDecodeException {
+ try {
+ return receiveMsg().getMsg();
+ } catch (final OtpErlangExit e) {
+ throw e;
+ } catch (final OtpErlangDecodeException f) {
+ throw f;
+ }
}
/**
* Wait for a message to arrive for this mailbox.
- *
+ *
* @param timeout
- * the time, in milliseconds, to wait for a message before
- * returning null.
- *
+ * the time, in milliseconds, to wait for a message before
+ * returning null.
+ *
* @return an {@link OtpErlangObject OtpErlangObject} representing the body
* of the next message waiting in this mailbox.
- *
+ *
* @exception OtpErlangDecodeException
- * if the message can not be decoded.
- *
+ * if the message can not be decoded.
+ *
* @exception OtpErlangExit
- * if a linked {@link OtpErlangPid pid} has exited or has
- * sent an exit signal to this mailbox.
+ * if a linked {@link OtpErlangPid pid} has exited or has
+ * sent an exit signal to this mailbox.
*/
public OtpErlangObject receive(final long timeout) throws OtpErlangExit,
- OtpErlangDecodeException {
- try {
- final OtpMsg m = receiveMsg(timeout);
- if (m != null) {
- return m.getMsg();
- }
- } catch (final OtpErlangExit e) {
- throw e;
- } catch (final OtpErlangDecodeException f) {
- throw f;
- } catch (final InterruptedException g) {
- }
- return null;
+ OtpErlangDecodeException {
+ try {
+ final OtpMsg m = receiveMsg(timeout);
+ if (m != null) {
+ return m.getMsg();
+ }
+ } catch (final OtpErlangExit e) {
+ throw e;
+ } catch (final OtpErlangDecodeException f) {
+ throw f;
+ } catch (final InterruptedException g) {
+ }
+ return null;
}
/**
* Block until a message arrives for this mailbox.
- *
+ *
* @return a byte array representing the still-encoded body of the next
* message waiting in this mailbox.
- *
+ *
* @exception OtpErlangExit
- * if a linked {@link OtpErlangPid pid} has exited or has
- * sent an exit signal to this mailbox.
- *
+ * if a linked {@link OtpErlangPid pid} has exited or has
+ * sent an exit signal to this mailbox.
+ *
*/
public OtpInputStream receiveBuf() throws OtpErlangExit {
- return receiveMsg().getMsgBuf();
+ return receiveMsg().getMsgBuf();
}
/**
* Wait for a message to arrive for this mailbox.
- *
+ *
* @param timeout
- * the time, in milliseconds, to wait for a message before
- * returning null.
- *
+ * the time, in milliseconds, to wait for a message before
+ * returning null.
+ *
* @return a byte array representing the still-encoded body of the next
* message waiting in this mailbox.
- *
+ *
* @exception OtpErlangExit
- * if a linked {@link OtpErlangPid pid} has exited or has
- * sent an exit signal to this mailbox.
- *
+ * if a linked {@link OtpErlangPid pid} has exited or has
+ * sent an exit signal to this mailbox.
+ *
* @exception InterruptedException
- * if no message if the method times out before a message
- * becomes available.
+ * if no message if the method times out before a message
+ * becomes available.
*/
public OtpInputStream receiveBuf(final long timeout)
- throws InterruptedException, OtpErlangExit {
- final OtpMsg m = receiveMsg(timeout);
- if (m != null) {
- return m.getMsgBuf();
- }
+ throws InterruptedException, OtpErlangExit {
+ final OtpMsg m = receiveMsg(timeout);
+ if (m != null) {
+ return m.getMsgBuf();
+ }
- return null;
+ return null;
}
/**
* Block until a message arrives for this mailbox.
- *
+ *
* @return an {@link OtpMsg OtpMsg} containing the header information as
* well as the body of the next message waiting in this mailbox.
- *
+ *
* @exception OtpErlangExit
- * if a linked {@link OtpErlangPid pid} has exited or has
- * sent an exit signal to this mailbox.
- *
+ * if a linked {@link OtpErlangPid pid} has exited or has
+ * sent an exit signal to this mailbox.
+ *
*/
public OtpMsg receiveMsg() throws OtpErlangExit {
- final OtpMsg m = (OtpMsg) queue.get();
-
- switch (m.type()) {
- case OtpMsg.exitTag:
- case OtpMsg.exit2Tag:
- try {
- final OtpErlangObject o = m.getMsg();
- throw new OtpErlangExit(o, m.getSenderPid());
- } catch (final OtpErlangDecodeException e) {
- throw new OtpErlangExit("unknown", m.getSenderPid());
- }
-
- default:
- return m;
- }
+ final OtpMsg m = (OtpMsg) queue.get();
+
+ switch (m.type()) {
+ case OtpMsg.exitTag:
+ case OtpMsg.exit2Tag:
+ try {
+ final OtpErlangObject o = m.getMsg();
+ throw new OtpErlangExit(o, m.getSenderPid());
+ } catch (final OtpErlangDecodeException e) {
+ throw new OtpErlangExit("unknown", m.getSenderPid());
+ }
+
+ default:
+ return m;
+ }
}
/**
* Wait for a message to arrive for this mailbox.
- *
+ *
* @param timeout
- * the time, in milliseconds, to wait for a message.
- *
+ * the time, in milliseconds, to wait for a message.
+ *
* @return an {@link OtpMsg OtpMsg} containing the header information as
* well as the body of the next message waiting in this mailbox.
- *
+ *
* @exception OtpErlangExit
- * if a linked {@link OtpErlangPid pid} has exited or has
- * sent an exit signal to this mailbox.
- *
+ * if a linked {@link OtpErlangPid pid} has exited or has
+ * sent an exit signal to this mailbox.
+ *
* @exception InterruptedException
- * if no message if the method times out before a message
- * becomes available.
+ * if no message if the method times out before a message
+ * becomes available.
*/
public OtpMsg receiveMsg(final long timeout) throws InterruptedException,
- OtpErlangExit {
- final OtpMsg m = (OtpMsg) queue.get(timeout);
-
- if (m == null) {
- return null;
- }
-
- switch (m.type()) {
- case OtpMsg.exitTag:
- case OtpMsg.exit2Tag:
- try {
- final OtpErlangObject o = m.getMsg();
- throw new OtpErlangExit(o, m.getSenderPid());
- } catch (final OtpErlangDecodeException e) {
- throw new OtpErlangExit("unknown", m.getSenderPid());
- }
-
- default:
- return m;
- }
+ OtpErlangExit {
+ final OtpMsg m = (OtpMsg) queue.get(timeout);
+
+ if (m == null) {
+ return null;
+ }
+
+ switch (m.type()) {
+ case OtpMsg.exitTag:
+ case OtpMsg.exit2Tag:
+ try {
+ final OtpErlangObject o = m.getMsg();
+ throw new OtpErlangExit(o, m.getSenderPid());
+ } catch (final OtpErlangDecodeException e) {
+ throw new OtpErlangExit("unknown", m.getSenderPid());
+ }
+
+ default:
+ return m;
+ }
}
/**
* Send a message to a remote {@link OtpErlangPid pid}, representing either
* another {@link OtpMbox mailbox} or an Erlang process.
- *
+ *
* @param to
- * the {@link OtpErlangPid pid} identifying the intended
- * recipient of the message.
- *
+ * the {@link OtpErlangPid pid} identifying the intended
+ * recipient of the message.
+ *
* @param msg
- * the body of the message to send.
- *
+ * the body of the message to send.
+ *
*/
public void send(final OtpErlangPid to, final OtpErlangObject msg) {
- try {
- final String node = to.node();
- if (node.equals(home.node())) {
- home.deliver(new OtpMsg(to, (OtpErlangObject) msg.clone()));
- } else {
- final OtpCookedConnection conn = home.getConnection(node);
- if (conn == null) {
- return;
- }
- conn.send(self, to, msg);
- }
- } catch (final Exception e) {
- }
+ try {
+ final String node = to.node();
+ if (node.equals(home.node())) {
+ home.deliver(new OtpMsg(to, (OtpErlangObject) msg.clone()));
+ } else {
+ final OtpCookedConnection conn = home.getConnection(node);
+ if (conn == null) {
+ return;
+ }
+ conn.send(self, to, msg);
+ }
+ } catch (final Exception e) {
+ }
}
/**
* Send a message to a named mailbox created from the same node as this
* mailbox.
- *
+ *
* @param aname
- * the registered name of recipient mailbox.
- *
+ * the registered name of recipient mailbox.
+ *
* @param msg
- * the body of the message to send.
- *
+ * the body of the message to send.
+ *
*/
public void send(final String aname, final OtpErlangObject msg) {
- home.deliver(new OtpMsg(self, aname, (OtpErlangObject) msg.clone()));
+ home.deliver(new OtpMsg(self, aname, (OtpErlangObject) msg.clone()));
}
/**
* Send a message to a named mailbox created from another node.
- *
+ *
* @param aname
- * the registered name of recipient mailbox.
- *
+ * the registered name of recipient mailbox.
+ *
* @param node
- * the name of the remote node where the recipient mailbox is
- * registered.
- *
+ * the name of the remote node where the recipient mailbox is
+ * registered.
+ *
* @param msg
- * the body of the message to send.
- *
+ * the body of the message to send.
+ *
*/
public void send(final String aname, final String node,
- final OtpErlangObject msg) {
- try {
- final String currentNode = home.node();
- if (node.equals(currentNode)) {
- send(aname, msg);
- } else if (node.indexOf('@', 0) < 0
- && node.equals(currentNode.substring(0, currentNode
- .indexOf('@', 0)))) {
- send(aname, msg);
- } else {
- // other node
- final OtpCookedConnection conn = home.getConnection(node);
- if (conn == null) {
- return;
- }
- conn.send(self, aname, msg);
- }
- } catch (final Exception e) {
- }
+ final OtpErlangObject msg) {
+ try {
+ final String currentNode = home.node();
+ if (node.equals(currentNode)) {
+ send(aname, msg);
+ } else if (node.indexOf('@', 0) < 0
+ && node.equals(currentNode.substring(0,
+ currentNode.indexOf('@', 0)))) {
+ send(aname, msg);
+ } else {
+ // other node
+ final OtpCookedConnection conn = home.getConnection(node);
+ if (conn == null) {
+ return;
+ }
+ conn.send(self, aname, msg);
+ }
+ } catch (final Exception e) {
+ }
}
/**
* Close this mailbox with the given reason.
- *
+ *
* <p>
* After this operation, the mailbox will no longer be able to receive
* messages. Any delivered but as yet unretrieved messages can still be
* retrieved however.
* </p>
- *
+ *
* <p>
* If there are links from this mailbox to other {@link OtpErlangPid pids},
* they will be broken when this method is called and exit signals will be
* sent.
* </p>
- *
+ *
* @param reason
- * an Erlang term describing the reason for the exit.
+ * an Erlang term describing the reason for the exit.
*/
public void exit(final OtpErlangObject reason) {
- home.closeMbox(this, reason);
+ home.closeMbox(this, reason);
}
/**
* Equivalent to <code>exit(new OtpErlangAtom(reason))</code>.
- *
+ *
* @see #exit(OtpErlangObject)
*/
public void exit(final String reason) {
- exit(new OtpErlangAtom(reason));
+ exit(new OtpErlangAtom(reason));
}
/**
@@ -434,17 +435,17 @@ public class OtpMbox {
* does not cause any links to be broken, except indirectly if the remote
* {@link OtpErlangPid pid} exits as a result of this exit signal.
* </p>
- *
+ *
* @param to
- * the {@link OtpErlangPid pid} to which the exit signal
- * should be sent.
- *
+ * the {@link OtpErlangPid pid} to which the exit signal should
+ * be sent.
+ *
* @param reason
- * an Erlang term indicating the reason for the exit.
+ * an Erlang term indicating the reason for the exit.
*/
// it's called exit, but it sends exit2
public void exit(final OtpErlangPid to, final OtpErlangObject reason) {
- exit(2, to, reason);
+ exit(2, to, reason);
}
/**
@@ -452,38 +453,38 @@ public class OtpMbox {
* Equivalent to <code>exit(to, new
* OtpErlangAtom(reason))</code>.
* </p>
- *
+ *
* @see #exit(OtpErlangPid, OtpErlangObject)
*/
public void exit(final OtpErlangPid to, final String reason) {
- exit(to, new OtpErlangAtom(reason));
+ exit(to, new OtpErlangAtom(reason));
}
// this function used internally when "process" dies
// since Erlang discerns between exit and exit/2.
private void exit(final int arity, final OtpErlangPid to,
- final OtpErlangObject reason) {
- try {
- final String node = to.node();
- if (node.equals(home.node())) {
- home.deliver(new OtpMsg(OtpMsg.exitTag, self, to, reason));
- } else {
- final OtpCookedConnection conn = home.getConnection(node);
- if (conn == null) {
- return;
- }
- switch (arity) {
- case 1:
- conn.exit(self, to, reason);
- break;
-
- case 2:
- conn.exit2(self, to, reason);
- break;
- }
- }
- } catch (final Exception e) {
- }
+ final OtpErlangObject reason) {
+ try {
+ final String node = to.node();
+ if (node.equals(home.node())) {
+ home.deliver(new OtpMsg(OtpMsg.exitTag, self, to, reason));
+ } else {
+ final OtpCookedConnection conn = home.getConnection(node);
+ if (conn == null) {
+ return;
+ }
+ switch (arity) {
+ case 1:
+ conn.exit(self, to, reason);
+ break;
+
+ case 2:
+ conn.exit2(self, to, reason);
+ break;
+ }
+ }
+ } catch (final Exception e) {
+ }
}
/**
@@ -492,7 +493,7 @@ public class OtpMbox {
* this method multiple times will not result in more than one link being
* created.
* </p>
- *
+ *
* <p>
* If the remote process subsequently exits or the mailbox is closed, a
* subsequent attempt to retrieve a message through this mailbox will cause
@@ -500,42 +501,42 @@ public class OtpMbox {
* if the sending mailbox is closed, the linked mailbox or process will
* receive an exit signal.
* </p>
- *
+ *
* <p>
* If the remote process cannot be reached in order to set the link, the
* exception is raised immediately.
* </p>
- *
+ *
* @param to
- * the {@link OtpErlangPid pid} representing the object to
- * link to.
- *
+ * the {@link OtpErlangPid pid} representing the object to link
+ * to.
+ *
* @exception OtpErlangExit
- * if the {@link OtpErlangPid pid} referred to does not
- * exist or could not be reached.
- *
+ * if the {@link OtpErlangPid pid} referred to does not exist
+ * or could not be reached.
+ *
*/
public void link(final OtpErlangPid to) throws OtpErlangExit {
- try {
- final String node = to.node();
- if (node.equals(home.node())) {
- if (!home.deliver(new OtpMsg(OtpMsg.linkTag, self, to))) {
- throw new OtpErlangExit("noproc", to);
- }
- } else {
- final OtpCookedConnection conn = home.getConnection(node);
- if (conn != null) {
- conn.link(self, to);
- } else {
- throw new OtpErlangExit("noproc", to);
- }
- }
- } catch (final OtpErlangExit e) {
- throw e;
- } catch (final Exception e) {
- }
-
- links.addLink(self, to);
+ try {
+ final String node = to.node();
+ if (node.equals(home.node())) {
+ if (!home.deliver(new OtpMsg(OtpMsg.linkTag, self, to))) {
+ throw new OtpErlangExit("noproc", to);
+ }
+ } else {
+ final OtpCookedConnection conn = home.getConnection(node);
+ if (conn != null) {
+ conn.link(self, to);
+ } else {
+ throw new OtpErlangExit("noproc", to);
+ }
+ }
+ } catch (final OtpErlangExit e) {
+ throw e;
+ } catch (final Exception e) {
+ }
+
+ links.addLink(self, to);
}
/**
@@ -545,58 +546,58 @@ public class OtpMbox {
* this method once will remove all links between this mailbox and the
* remote {@link OtpErlangPid pid}.
* </p>
- *
+ *
* @param to
- * the {@link OtpErlangPid pid} representing the object to
- * unlink from.
- *
+ * the {@link OtpErlangPid pid} representing the object to unlink
+ * from.
+ *
*/
public void unlink(final OtpErlangPid to) {
- links.removeLink(self, to);
-
- try {
- final String node = to.node();
- if (node.equals(home.node())) {
- home.deliver(new OtpMsg(OtpMsg.unlinkTag, self, to));
- } else {
- final OtpCookedConnection conn = home.getConnection(node);
- if (conn != null) {
- conn.unlink(self, to);
- }
- }
- } catch (final Exception e) {
- }
+ links.removeLink(self, to);
+
+ try {
+ final String node = to.node();
+ if (node.equals(home.node())) {
+ home.deliver(new OtpMsg(OtpMsg.unlinkTag, self, to));
+ } else {
+ final OtpCookedConnection conn = home.getConnection(node);
+ if (conn != null) {
+ conn.unlink(self, to);
+ }
+ }
+ } catch (final Exception e) {
+ }
}
/**
* <p>
* Create a connection to a remote node.
* </p>
- *
+ *
* <p>
* Strictly speaking, this method is not necessary simply to set up a
* connection, since connections are created automatically first time a
* message is sent to a {@link OtpErlangPid pid} on the remote node.
* </p>
- *
+ *
* <p>
* This method makes it possible to wait for a node to come up, however, or
* check that a node is still alive.
* </p>
- *
+ *
* <p>
* This method calls a method with the same name in {@link OtpNode#ping
* Otpnode} but is provided here for convenience.
* </p>
- *
+ *
* @param node
- * the name of the node to ping.
- *
+ * the name of the node to ping.
+ *
* @param timeout
- * the time, in milliseconds, before reporting failure.
+ * the time, in milliseconds, before reporting failure.
*/
public boolean ping(final String node, final long timeout) {
- return home.ping(node, timeout);
+ return home.ping(node, timeout);
}
/**
@@ -604,78 +605,78 @@ public class OtpMbox {
* Get a list of all known registered names on the same {@link OtpNode node}
* as this mailbox.
* </p>
- *
+ *
* <p>
* This method calls a method with the same name in {@link OtpNode#getNames
* Otpnode} but is provided here for convenience.
* </p>
- *
+ *
* @return an array of Strings containing all registered names on this
* {@link OtpNode node}.
*/
public String[] getNames() {
- return home.getNames();
+ return home.getNames();
}
/**
* Determine the {@link OtpErlangPid pid} corresponding to a registered name
* on this {@link OtpNode node}.
- *
+ *
* <p>
* This method calls a method with the same name in {@link OtpNode#whereis
* Otpnode} but is provided here for convenience.
* </p>
- *
+ *
* @return the {@link OtpErlangPid pid} corresponding to the registered
* name, or null if the name is not known on this node.
*/
public OtpErlangPid whereis(final String aname) {
- return home.whereis(aname);
+ return home.whereis(aname);
}
/**
* Close this mailbox.
- *
+ *
* <p>
* After this operation, the mailbox will no longer be able to receive
* messages. Any delivered but as yet unretrieved messages can still be
* retrieved however.
* </p>
- *
+ *
* <p>
* If there are links from this mailbox to other {@link OtpErlangPid pids},
* they will be broken when this method is called and exit signals with
* reason 'normal' will be sent.
* </p>
- *
+ *
* <p>
* This is equivalent to {@link #exit(String) exit("normal")}.
* </p>
*/
public void close() {
- home.closeMbox(this);
+ home.closeMbox(this);
}
@Override
protected void finalize() {
- close();
- queue.flush();
+ close();
+ queue.flush();
}
/**
* Determine if two mailboxes are equal.
- *
+ *
* @return true if both Objects are mailboxes with the same identifying
* {@link OtpErlangPid pids}.
*/
@Override
public boolean equals(final Object o) {
- if (!(o instanceof OtpMbox)) {
- return false;
- }
+ if (!(o instanceof OtpMbox)) {
+ return false;
+ }
- final OtpMbox m = (OtpMbox) o;
- return m.self.equals(self);
+ final OtpMbox m = (OtpMbox) o;
+ return m.self.equals(self);
}
@Override
@@ -685,43 +686,43 @@ public class OtpMbox {
/*
* called by OtpNode to deliver message to this mailbox.
- *
+ *
* About exit and exit2: both cause exception to be raised upon receive().
* However exit (not 2) causes any link to be removed as well, while exit2
* leaves any links intact.
*/
void deliver(final OtpMsg m) {
- switch (m.type()) {
- case OtpMsg.linkTag:
- links.addLink(self, m.getSenderPid());
- break;
-
- case OtpMsg.unlinkTag:
- links.removeLink(self, m.getSenderPid());
- break;
-
- case OtpMsg.exitTag:
- links.removeLink(self, m.getSenderPid());
- queue.put(m);
- break;
-
- case OtpMsg.exit2Tag:
- default:
- queue.put(m);
- break;
- }
+ switch (m.type()) {
+ case OtpMsg.linkTag:
+ links.addLink(self, m.getSenderPid());
+ break;
+
+ case OtpMsg.unlinkTag:
+ links.removeLink(self, m.getSenderPid());
+ break;
+
+ case OtpMsg.exitTag:
+ links.removeLink(self, m.getSenderPid());
+ queue.put(m);
+ break;
+
+ case OtpMsg.exit2Tag:
+ default:
+ queue.put(m);
+ break;
+ }
}
// used to break all known links to this mbox
void breakLinks(final OtpErlangObject reason) {
- final Link[] l = links.clearLinks();
+ final Link[] l = links.clearLinks();
- if (l != null) {
- final int len = l.length;
+ if (l != null) {
+ final int len = l.length;
- for (int i = 0; i < len; i++) {
- exit(1, l[i].remote(), reason);
- }
- }
+ for (int i = 0; i < len; i++) {
+ exit(1, l[i].remote(), reason);
+ }
+ }
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
index 7c5bc69361..9597f2abd6 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2010. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -22,23 +23,25 @@ package com.ericsson.otp.erlang;
* <p>
* Provides a carrier for Erlang messages.
* </p>
- *
+ *
* <p>
* Instances of this class are created to package header and payload information
* in received Erlang messages so that the recipient can obtain both parts with
* a single call to {@link OtpMbox#receiveMsg receiveMsg()}.
* </p>
- *
+ *
* <p>
- * The header information that is available is as follows: <ul>
- * <li> a tag indicating the type of message
- * <li> the intended recipient of the message, either as a
- * {@link OtpErlangPid pid} or as a String, but never both.
- * <li> (sometimes) the sender of the message. Due to some eccentric
+ * The header information that is available is as follows:
+ * <ul>
+ * <li>a tag indicating the type of message
+ * <li>the intended recipient of the message, either as a {@link OtpErlangPid
+ * pid} or as a String, but never both.
+ * <li>(sometimes) the sender of the message. Due to some eccentric
* characteristics of the Erlang distribution protocol, not all messages have
* information about the sending process. In particular, only messages whose tag
- * is {@link OtpMsg#regSendTag regSendTag} contain sender information. </ul>
- *
+ * is {@link OtpMsg#regSendTag regSendTag} contain sender information.
+ * </ul>
+ *
* <p>
* Message are sent using the Erlang external format (see separate
* documentation). When a message is received and delivered to the recipient
@@ -68,87 +71,87 @@ public class OtpMsg {
// send has receiver pid but no sender information
OtpMsg(final OtpErlangPid to, final OtpInputStream paybuf) {
- tag = sendTag;
- from = null;
- this.to = to;
- toName = null;
- this.paybuf = paybuf;
- payload = null;
+ tag = sendTag;
+ from = null;
+ this.to = to;
+ toName = null;
+ this.paybuf = paybuf;
+ payload = null;
}
// send has receiver pid but no sender information
OtpMsg(final OtpErlangPid to, final OtpErlangObject payload) {
- tag = sendTag;
- from = null;
- this.to = to;
- toName = null;
- paybuf = null;
- this.payload = payload;
+ tag = sendTag;
+ from = null;
+ this.to = to;
+ toName = null;
+ paybuf = null;
+ this.payload = payload;
}
// send_reg has sender pid and receiver name
OtpMsg(final OtpErlangPid from, final String toName,
- final OtpInputStream paybuf) {
- tag = regSendTag;
- this.from = from;
- this.toName = toName;
- to = null;
- this.paybuf = paybuf;
- payload = null;
+ final OtpInputStream paybuf) {
+ tag = regSendTag;
+ this.from = from;
+ this.toName = toName;
+ to = null;
+ this.paybuf = paybuf;
+ payload = null;
}
// send_reg has sender pid and receiver name
OtpMsg(final OtpErlangPid from, final String toName,
- final OtpErlangObject payload) {
- tag = regSendTag;
- this.from = from;
- this.toName = toName;
- to = null;
- paybuf = null;
- this.payload = payload;
+ final OtpErlangObject payload) {
+ tag = regSendTag;
+ this.from = from;
+ this.toName = toName;
+ to = null;
+ paybuf = null;
+ this.payload = payload;
}
// exit (etc) has from, to, reason
OtpMsg(final int tag, final OtpErlangPid from, final OtpErlangPid to,
- final OtpErlangObject reason) {
- this.tag = tag;
- this.from = from;
- this.to = to;
- paybuf = null;
- payload = reason;
+ final OtpErlangObject reason) {
+ this.tag = tag;
+ this.from = from;
+ this.to = to;
+ paybuf = null;
+ payload = reason;
}
// special case when reason is an atom (i.e. most of the time)
OtpMsg(final int tag, final OtpErlangPid from, final OtpErlangPid to,
- final String reason) {
- this.tag = tag;
- this.from = from;
- this.to = to;
- paybuf = null;
- payload = new OtpErlangAtom(reason);
+ final String reason) {
+ this.tag = tag;
+ this.from = from;
+ this.to = to;
+ paybuf = null;
+ payload = new OtpErlangAtom(reason);
}
// other message types (link, unlink)
OtpMsg(final int tag, final OtpErlangPid from, final OtpErlangPid to) {
- // convert TT-tags to equiv non-TT versions
- int atag = tag;
- if (tag > 10) {
- atag -= 10;
- }
+ // convert TT-tags to equiv non-TT versions
+ int atag = tag;
+ if (tag > 10) {
+ atag -= 10;
+ }
- this.tag = atag;
- this.from = from;
- this.to = to;
+ this.tag = atag;
+ this.from = from;
+ this.to = to;
}
/**
* Get the payload from this message without deserializing it.
- *
+ *
* @return the serialized Erlang term contained in this message.
- *
+ *
*/
OtpInputStream getMsgBuf() {
- return paybuf;
+ return paybuf;
}
/**
@@ -157,36 +160,37 @@ public class OtpMsg {
* type of message. Valid values are the ``tag'' constants defined in this
* class.
* </p>
- *
+ *
* <p>
* The tab identifies not only the type of message but also the content of
* the OtpMsg object, since different messages have different components, as
* follows:
* </p>
- *
+ *
* <ul>
- * <li> sendTag identifies a "normal" message. The recipient is a
- * {@link OtpErlangPid Pid} and it is available through {@link
- * #getRecipientPid getRecipientPid()}. Sender information is not available.
- * The message body can be retrieved with {@link #getMsg getMsg()}. </li>
- *
- * <li> regSendTag also identifies a "normal" message. The recipient here is
+ * <li>sendTag identifies a "normal" message. The recipient is a
+ * {@link OtpErlangPid Pid} and it is available through
+ * {@link #getRecipientPid getRecipientPid()}. Sender information is not
+ * available. The message body can be retrieved with {@link #getMsg
+ * getMsg()}.</li>
+ *
+ * <li>regSendTag also identifies a "normal" message. The recipient here is
* a String and it is available through {@link #getRecipientName
* getRecipientName()}. Sender information is available through
* #getSenderPid getSenderPid()}. The message body can be retrieved with
- * {@link #getMsg getMsg()}. </li>
- *
- * <li> linkTag identifies a link request. The Pid of the sender is
- * available, as well as the Pid to which the link should be made. </li>
- *
- * <li> exitTag and exit2Tag messages are sent as a result of broken links.
+ * {@link #getMsg getMsg()}.</li>
+ *
+ * <li>linkTag identifies a link request. The Pid of the sender is
+ * available, as well as the Pid to which the link should be made.</li>
+ *
+ * <li>exitTag and exit2Tag messages are sent as a result of broken links.
* Both sender and recipient Pids and are available through the
* corresponding methods, and the "reason" is available through
- * {@link #getMsg getMsg()}. </li>
+ * {@link #getMsg getMsg()}.</li>
* </ul>
*/
public int type() {
- return tag;
+ return tag;
}
/**
@@ -194,42 +198,42 @@ public class OtpMsg {
* Deserialize and return a new copy of the message contained in this
* OtpMsg.
* </p>
- *
+ *
* <p>
* The first time this method is called the actual payload is deserialized
* and the Erlang term is created. Calling this method subsequent times will
* not cuase the message to be deserialized additional times, instead the
* same Erlang term object will be returned.
* </p>
- *
+ *
* @return an Erlang term.
- *
+ *
* @exception OtpErlangDecodeException
- * if the byte stream could not be deserialized.
- *
+ * if the byte stream could not be deserialized.
+ *
*/
public OtpErlangObject getMsg() throws OtpErlangDecodeException {
- if (payload == null) {
- payload = paybuf.read_any();
- }
- return payload;
+ if (payload == null) {
+ payload = paybuf.read_any();
+ }
+ return payload;
}
/**
* <p>
* Get the name of the recipient for this message.
* </p>
- *
+ *
* <p>
* Messages are sent to Pids or names. If this message was sent to a name
* then the name is returned by this method.
* </p>
- *
+ *
* @return the name of the recipient, or null if the recipient was in fact a
* Pid.
*/
public String getRecipientName() {
- return toName;
+ return toName;
}
/**
@@ -237,18 +241,18 @@ public class OtpMsg {
* Get the Pid of the recipient for this message, if it is a sendTag
* message.
* </p>
- *
+ *
* <p>
* Messages are sent to Pids or names. If this message was sent to a Pid
* then the Pid is returned by this method. The recipient Pid is also
* available for link, unlink and exit messages.
* </p>
- *
+ *
* @return the Pid of the recipient, or null if the recipient was in fact a
* name.
*/
public OtpErlangPid getRecipientPid() {
- return to;
+ return to;
}
/**
@@ -256,36 +260,36 @@ public class OtpMsg {
* Get the name of the recipient for this message, if it is a regSendTag
* message.
* </p>
- *
+ *
* <p>
* Messages are sent to Pids or names. If this message was sent to a name
* then the name is returned by this method.
* </p>
- *
+ *
* @return the Pid of the recipient, or null if the recipient was in fact a
* name.
*/
public Object getRecipient() {
- if (toName != null) {
- return toName;
- }
- return to;
+ if (toName != null) {
+ return toName;
+ }
+ return to;
}
/**
* <p>
* Get the Pid of the sender of this message.
* </p>
- *
+ *
* <p>
* For messages sent to names, the Pid of the sender is included with the
* message. The sender Pid is also available for link, unlink and exit
* messages. It is not available for sendTag messages sent to Pids.
* </p>
- *
+ *
* @return the Pid of the sender, or null if it was not available.
*/
public OtpErlangPid getSenderPid() {
- return from;
+ return from;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java
index 68addb9f2c..b2598924e9 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java
@@ -1,27 +1,26 @@
-/*
+/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2012. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
import java.io.IOException;
import java.lang.ref.WeakReference;
-import java.net.ServerSocket;
-import java.net.Socket;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
@@ -36,21 +35,21 @@ import java.util.Iterator;
* communication mechanism is automatic and hidden from the application
* programmer.
* </p>
- *
+ *
* <p>
* Once an instance of this class has been created, obtain one or more mailboxes
* in order to send or receive messages. The first message sent to a given node
* will cause a connection to be set up to that node. Any messages received will
* be delivered to the appropriate mailboxes.
* </p>
- *
+ *
* <p>
* To shut down the node, call {@link #close close()}. This will prevent the
* node from accepting additional connections and it will cause all existing
* connections to be closed. Any unread messages in existing mailboxes can still
* be read, however no new messages will be delivered to the mailboxes.
* </p>
- *
+ *
* <p>
* Note that the use of this class requires that Epmd (Erlang Port Mapper
* Daemon) is running on each cooperating host. This class does not start Epmd
@@ -83,74 +82,156 @@ public class OtpNode extends OtpLocalNode {
* directory. The home directory is obtained from the System property
* "user.home".
* </p>
- *
+ *
* <p>
* If the file does not exist, an empty string is used. This method makes no
* attempt to create the file.
* </p>
- *
+ *
* @param node
* the name of this node.
- *
+ *
* @exception IOException
* if communication could not be initialized.
- *
+ *
*/
public OtpNode(final String node) throws IOException {
- this(node, defaultCookie, 0);
+ super(node);
+
+ init(0);
+ }
+
+ /**
+ * <p>
+ * Create a node using the default cookie. The default cookie is found by
+ * reading the first line of the .erlang.cookie file in the user's home
+ * directory. The home directory is obtained from the System property
+ * "user.home".
+ * </p>
+ *
+ * <p>
+ * If the file does not exist, an empty string is used. This method makes no
+ * attempt to create the file.
+ * </p>
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param transportFactory
+ * the transport factory to use when creating connections.
+ *
+ * @exception IOException
+ * if communication could not be initialized.
+ *
+ */
+ public OtpNode(final String node,
+ final OtpTransportFactory transportFactory) throws IOException {
+ super(node, transportFactory);
+
+ init(0);
}
/**
* Create a node.
- *
+ *
* @param node
* the name of this node.
- *
+ *
* @param cookie
* the authorization cookie that will be used by this node when
* it communicates with other nodes.
- *
+ *
* @exception IOException
* if communication could not be initialized.
- *
+ *
*/
public OtpNode(final String node, final String cookie) throws IOException {
- this(node, cookie, 0);
+ this(node, cookie, 0);
+ }
+
+ /**
+ * Create a node.
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param cookie
+ * the authorization cookie that will be used by this node when
+ * it communicates with other nodes.
+ *
+ * @param transportFactory
+ * the transport factory to use when creating connections.
+ *
+ * @exception IOException
+ * if communication could not be initialized.
+ *
+ */
+ public OtpNode(final String node, final String cookie,
+ final OtpTransportFactory transportFactory) throws IOException {
+ this(node, cookie, 0, transportFactory);
}
/**
* Create a node.
- *
+ *
* @param node
* the name of this node.
- *
+ *
* @param cookie
* the authorization cookie that will be used by this node when
* it communicates with other nodes.
- *
+ *
* @param port
* the port number you wish to use for incoming connections.
* Specifying 0 lets the system choose an available port.
- *
+ *
* @exception IOException
* if communication could not be initialized.
- *
+ *
*/
public OtpNode(final String node, final String cookie, final int port)
- throws IOException {
- super(node, cookie);
+ throws IOException {
+ super(node, cookie);
+
+ init(port);
+ }
+
+ /**
+ * Create a node.
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param cookie
+ * the authorization cookie that will be used by this node when
+ * it communicates with other nodes.
+ *
+ * @param port
+ * the port number you wish to use for incoming connections.
+ * Specifying 0 lets the system choose an available port.
+ *
+ * @param transportFactory
+ * the transport factory to use when creating connections.
+ *
+ * @exception IOException
+ * if communication could not be initialized.
+ *
+ */
+ public OtpNode(final String node, final String cookie, final int port,
+ final OtpTransportFactory transportFactory) throws IOException {
+ super(node, cookie, transportFactory);
- init(port);
+ init(port);
}
private synchronized void init(final int aport) throws IOException {
- if (!initDone) {
- connections = new Hashtable<String, OtpCookedConnection>(17,
- (float) 0.95);
- mboxes = new Mailboxes();
- acceptor = new Acceptor(aport);
- initDone = true;
- }
+ if (!initDone) {
+ connections = new Hashtable<String, OtpCookedConnection>(17,
+ (float) 0.95);
+ mboxes = new Mailboxes();
+ acceptor = new Acceptor(aport);
+ initDone = true;
+ }
}
/**
@@ -158,24 +239,24 @@ public class OtpNode extends OtpLocalNode {
* and close all existing connections.
*/
public synchronized void close() {
- acceptor.quit();
- OtpCookedConnection conn;
- final Collection<OtpCookedConnection> coll = connections.values();
- final Iterator<OtpCookedConnection> it = coll.iterator();
-
- mboxes.clear();
-
- while (it.hasNext()) {
- conn = it.next();
- it.remove();
- conn.close();
- }
- initDone = false;
+ acceptor.quit();
+ OtpCookedConnection conn;
+ final Collection<OtpCookedConnection> coll = connections.values();
+ final Iterator<OtpCookedConnection> it = coll.iterator();
+
+ mboxes.clear();
+
+ while (it.hasNext()) {
+ conn = it.next();
+ it.remove();
+ conn.close();
+ }
+ initDone = false;
}
@Override
protected void finalize() {
- close();
+ close();
}
/**
@@ -183,65 +264,65 @@ public class OtpNode extends OtpLocalNode {
* receive messages with other, similar mailboxes and with Erlang processes.
* Messages can be sent to this mailbox by using its associated
* {@link OtpMbox#self() pid}.
- *
+ *
* @return a mailbox.
*/
public OtpMbox createMbox() {
- return mboxes.create();
+ return mboxes.create();
}
/**
* Close the specified mailbox with reason 'normal'.
- *
+ *
* @param mbox
* the mailbox to close.
- *
+ *
* <p>
* After this operation, the mailbox will no longer be able to
* receive messages. Any delivered but as yet unretrieved
* messages can still be retrieved however.
* </p>
- *
+ *
* <p>
* If there are links from the mailbox to other
* {@link OtpErlangPid pids}, they will be broken when this
* method is called and exit signals with reason 'normal' will be
* sent.
* </p>
- *
+ *
*/
public void closeMbox(final OtpMbox mbox) {
- closeMbox(mbox, new OtpErlangAtom("normal"));
+ closeMbox(mbox, new OtpErlangAtom("normal"));
}
/**
* Close the specified mailbox with the given reason.
- *
+ *
* @param mbox
* the mailbox to close.
* @param reason
* an Erlang term describing the reason for the termination.
- *
+ *
* <p>
* After this operation, the mailbox will no longer be able to
* receive messages. Any delivered but as yet unretrieved
* messages can still be retrieved however.
* </p>
- *
+ *
* <p>
* If there are links from the mailbox to other
* {@link OtpErlangPid pids}, they will be broken when this
* method is called and exit signals with the given reason will
* be sent.
* </p>
- *
+ *
*/
public void closeMbox(final OtpMbox mbox, final OtpErlangObject reason) {
- if (mbox != null) {
- mboxes.remove(mbox);
- mbox.name = null;
- mbox.breakLinks(reason);
- }
+ if (mbox != null) {
+ mboxes.remove(mbox);
+ mbox.name = null;
+ mbox.breakLinks(reason);
+ }
}
/**
@@ -249,16 +330,16 @@ public class OtpNode extends OtpLocalNode {
* with other, similar mailboxes and with Erlang processes. Messages can be
* sent to this mailbox by using its registered name or the associated
* {@link OtpMbox#self() pid}.
- *
+ *
* @param name
* a name to register for this mailbox. The name must be unique
* within this OtpNode.
- *
+ *
* @return a mailbox, or null if the name was already in use.
- *
+ *
*/
public OtpMbox createMbox(final String name) {
- return mboxes.create(name);
+ return mboxes.create(name);
}
/**
@@ -269,58 +350,58 @@ public class OtpNode extends OtpLocalNode {
* name; if the mailbox already had a name, calling this method will
* supercede that name.
* </p>
- *
+ *
* @param name
* the name to register for the mailbox. Specify null to
* unregister the existing name from this mailbox.
- *
+ *
* @param mbox
* the mailbox to associate with the name.
- *
+ *
* @return true if the name was available, or false otherwise.
*/
public boolean registerName(final String name, final OtpMbox mbox) {
- return mboxes.register(name, mbox);
+ return mboxes.register(name, mbox);
}
/**
* Get a list of all known registered names on this node.
- *
+ *
* @return an array of Strings, containins all known registered names on
* this node.
*/
public String[] getNames() {
- return mboxes.names();
+ return mboxes.names();
}
/**
* Determine the {@link OtpErlangPid pid} corresponding to a registered name
* on this node.
- *
+ *
* @return the {@link OtpErlangPid pid} corresponding to the registered
* name, or null if the name is not known on this node.
*/
public OtpErlangPid whereis(final String name) {
- final OtpMbox m = mboxes.get(name);
- if (m != null) {
- return m.self();
- }
- return null;
+ final OtpMbox m = mboxes.get(name);
+ if (m != null) {
+ return m.self();
+ }
+ return null;
}
/**
* Register interest in certain system events. The {@link OtpNodeStatus
* OtpNodeStatus} handler object contains callback methods, that will be
* called when certain events occur.
- *
+ *
* @param ahandler
* the callback object to register. To clear the handler, specify
* null as the handler to use.
- *
+ *
*/
public synchronized void registerStatusHandler(final OtpNodeStatus ahandler) {
- this.handler = ahandler;
+ handler = ahandler;
}
/**
@@ -329,7 +410,7 @@ public class OtpNode extends OtpLocalNode {
* setting up a connection to the remote node (if possible). Only a single
* outgoing message is sent; the timeout is how long to wait for a response.
* </p>
- *
+ *
* <p>
* Only a single attempt is made to connect to the remote node, so for
* example it is not possible to specify an extremely long timeout and
@@ -337,74 +418,73 @@ public class OtpNode extends OtpLocalNode {
* wait for a remote node to be started, the following construction may be
* useful:
* </p>
- *
+ *
* <pre>
* // ping every 2 seconds until positive response
* while (!me.ping(him, 2000))
* ;
* </pre>
- *
+ *
* @param anode
* the name of the node to ping.
- *
+ *
* @param timeout
* the time, in milliseconds, to wait for response before
* returning false.
- *
+ *
* @return true if the node was alive and the correct ping response was
* returned. false if the correct response was not returned on time.
*/
/*
* internal info about the message formats...
- *
+ *
* the request: -> REG_SEND {6,#Pid<[email protected]>,'',net_kernel}
* {'$gen_call',{#Pid<[email protected]>,#Ref<[email protected]>},{is_auth,bingo@aule}}
- *
+ *
* the reply: <- SEND {2,'',#Pid<[email protected]>} {#Ref<[email protected]>,yes}
*/
public boolean ping(final String anode, final long timeout) {
- if (anode.equals(this.node)) {
- return true;
- } else if (anode.indexOf('@', 0) < 0
- && anode.equals(this.node
- .substring(0, this.node.indexOf('@', 0)))) {
- return true;
- }
-
- // other node
- OtpMbox mbox = null;
- try {
- mbox = createMbox();
- mbox.send("net_kernel", anode, getPingTuple(mbox));
- final OtpErlangObject reply = mbox.receive(timeout);
-
- final OtpErlangTuple t = (OtpErlangTuple) reply;
- final OtpErlangAtom a = (OtpErlangAtom) t.elementAt(1);
- return "yes".equals(a.atomValue());
- } catch (final Exception e) {
- } finally {
- closeMbox(mbox);
- }
- return false;
+ if (anode.equals(node)) {
+ return true;
+ } else if (anode.indexOf('@', 0) < 0
+ && anode.equals(node.substring(0, node.indexOf('@', 0)))) {
+ return true;
+ }
+
+ // other node
+ OtpMbox mbox = null;
+ try {
+ mbox = createMbox();
+ mbox.send("net_kernel", anode, getPingTuple(mbox));
+ final OtpErlangObject reply = mbox.receive(timeout);
+
+ final OtpErlangTuple t = (OtpErlangTuple) reply;
+ final OtpErlangAtom a = (OtpErlangAtom) t.elementAt(1);
+ return "yes".equals(a.atomValue());
+ } catch (final Exception e) {
+ } finally {
+ closeMbox(mbox);
+ }
+ return false;
}
/* create the outgoing ping message */
private OtpErlangTuple getPingTuple(final OtpMbox mbox) {
- final OtpErlangObject[] ping = new OtpErlangObject[3];
- final OtpErlangObject[] pid = new OtpErlangObject[2];
- final OtpErlangObject[] anode = new OtpErlangObject[2];
+ final OtpErlangObject[] ping = new OtpErlangObject[3];
+ final OtpErlangObject[] pid = new OtpErlangObject[2];
+ final OtpErlangObject[] anode = new OtpErlangObject[2];
- pid[0] = mbox.self();
- pid[1] = createRef();
+ pid[0] = mbox.self();
+ pid[1] = createRef();
- anode[0] = new OtpErlangAtom("is_auth");
- anode[1] = new OtpErlangAtom(node());
+ anode[0] = new OtpErlangAtom("is_auth");
+ anode[1] = new OtpErlangAtom(node());
- ping[0] = new OtpErlangAtom("$gen_call");
- ping[1] = new OtpErlangTuple(pid);
- ping[2] = new OtpErlangTuple(anode);
+ ping[0] = new OtpErlangAtom("$gen_call");
+ ping[1] = new OtpErlangTuple(pid);
+ ping[2] = new OtpErlangTuple(anode);
- return new OtpErlangTuple(ping);
+ return new OtpErlangTuple(ping);
}
/*
@@ -412,27 +492,27 @@ public class OtpNode extends OtpLocalNode {
* pings.
*/
private boolean netKernel(final OtpMsg m) {
- OtpMbox mbox = null;
- try {
- final OtpErlangTuple t = (OtpErlangTuple) m.getMsg();
- final OtpErlangTuple req = (OtpErlangTuple) t.elementAt(1); // actual
- // request
-
- final OtpErlangPid pid = (OtpErlangPid) req.elementAt(0); // originating
- // pid
-
- final OtpErlangObject[] pong = new OtpErlangObject[2];
- pong[0] = req.elementAt(1); // his #Ref
- pong[1] = new OtpErlangAtom("yes");
-
- mbox = createMbox();
- mbox.send(pid, new OtpErlangTuple(pong));
- return true;
- } catch (final Exception e) {
- } finally {
- closeMbox(mbox);
- }
- return false;
+ OtpMbox mbox = null;
+ try {
+ final OtpErlangTuple t = (OtpErlangTuple) m.getMsg();
+ final OtpErlangTuple req = (OtpErlangTuple) t.elementAt(1); // actual
+ // request
+
+ final OtpErlangPid pid = (OtpErlangPid) req.elementAt(0); // originating
+ // pid
+
+ final OtpErlangObject[] pong = new OtpErlangObject[2];
+ pong[0] = req.elementAt(1); // his #Ref
+ pong[1] = new OtpErlangAtom("yes");
+
+ mbox = createMbox();
+ mbox.send(pid, new OtpErlangTuple(pong));
+ return true;
+ } catch (final Exception e) {
+ } finally {
+ closeMbox(mbox);
+ }
+ return false;
}
/*
@@ -440,31 +520,31 @@ public class OtpNode extends OtpLocalNode {
* delivered successfully, or false otherwise.
*/
boolean deliver(final OtpMsg m) {
- OtpMbox mbox = null;
-
- try {
- final int t = m.type();
-
- if (t == OtpMsg.regSendTag) {
- final String name = m.getRecipientName();
- /* special case for netKernel requests */
- if (name.equals("net_kernel")) {
- return netKernel(m);
- }
- mbox = mboxes.get(name);
- } else {
- mbox = mboxes.get(m.getRecipientPid());
- }
-
- if (mbox == null) {
- return false;
- }
- mbox.deliver(m);
- } catch (final Exception e) {
- return false;
- }
-
- return true;
+ OtpMbox mbox = null;
+
+ try {
+ final int t = m.type();
+
+ if (t == OtpMsg.regSendTag) {
+ final String name = m.getRecipientName();
+ /* special case for netKernel requests */
+ if (name.equals("net_kernel")) {
+ return netKernel(m);
+ }
+ mbox = mboxes.get(name);
+ } else {
+ mbox = mboxes.get(m.getRecipientPid());
+ }
+
+ if (mbox == null) {
+ return false;
+ }
+ mbox.deliver(m);
+ } catch (final Exception e) {
+ return false;
+ }
+
+ return true;
}
/*
@@ -472,86 +552,86 @@ public class OtpNode extends OtpLocalNode {
* specified by the application
*/
void deliverError(final OtpCookedConnection conn, final Exception e) {
- removeConnection(conn);
- remoteStatus(conn.name, false, e);
+ removeConnection(conn);
+ remoteStatus(conn.name, false, e);
}
/*
* find or create a connection to the given node
*/
OtpCookedConnection getConnection(final String anode) {
- OtpPeer peer = null;
- OtpCookedConnection conn = null;
-
- synchronized (connections) {
- // first just try looking up the name as-is
- conn = connections.get(anode);
-
- if (conn == null) {
- // in case node had no '@' add localhost info and try again
- peer = new OtpPeer(anode);
- conn = connections.get(peer.node());
-
- if (conn == null) {
- try {
- conn = new OtpCookedConnection(this, peer);
- conn.setFlags(connFlags);
- addConnection(conn);
- } catch (final Exception e) {
- /* false = outgoing */
- connAttempt(peer.node(), false, e);
- }
- }
- }
- return conn;
- }
+ OtpPeer peer = null;
+ OtpCookedConnection conn = null;
+
+ synchronized (connections) {
+ // first just try looking up the name as-is
+ conn = connections.get(anode);
+
+ if (conn == null) {
+ // in case node had no '@' add localhost info and try again
+ peer = new OtpPeer(anode);
+ conn = connections.get(peer.node());
+
+ if (conn == null) {
+ try {
+ conn = new OtpCookedConnection(this, peer);
+ conn.setFlags(connFlags);
+ addConnection(conn);
+ } catch (final Exception e) {
+ /* false = outgoing */
+ connAttempt(peer.node(), false, e);
+ }
+ }
+ }
+ return conn;
+ }
}
void addConnection(final OtpCookedConnection conn) {
- if (conn != null && conn.name != null) {
- connections.put(conn.name, conn);
- remoteStatus(conn.name, true, null);
- }
+ if (conn != null && conn.name != null) {
+ connections.put(conn.name, conn);
+ remoteStatus(conn.name, true, null);
+ }
}
private void removeConnection(final OtpCookedConnection conn) {
- if (conn != null && conn.name != null) {
- connections.remove(conn.name);
- }
+ if (conn != null && conn.name != null) {
+ connections.remove(conn.name);
+ }
}
/* use these wrappers to call handler functions */
- private synchronized void remoteStatus(final String anode, final boolean up,
- final Object info) {
- if (handler == null) {
- return;
- }
- try {
- handler.remoteStatus(anode, up, info);
- } catch (final Exception e) {
- }
+ private synchronized void remoteStatus(final String anode,
+ final boolean up, final Object info) {
+ if (handler == null) {
+ return;
+ }
+ try {
+ handler.remoteStatus(anode, up, info);
+ } catch (final Exception e) {
+ }
}
synchronized void localStatus(final String anode, final boolean up,
- final Object info) {
- if (handler == null) {
- return;
- }
- try {
- handler.localStatus(anode, up, info);
- } catch (final Exception e) {
- }
+ final Object info) {
+ if (handler == null) {
+ return;
+ }
+ try {
+ handler.localStatus(anode, up, info);
+ } catch (final Exception e) {
+ }
}
synchronized void connAttempt(final String anode, final boolean incoming,
- final Object info) {
- if (handler == null) {
- return;
- }
- try {
- handler.connAttempt(anode, incoming, info);
- } catch (final Exception e) {
- }
+ final Object info) {
+ if (handler == null) {
+ return;
+ }
+ try {
+ handler.connAttempt(anode, incoming, info);
+ } catch (final Exception e) {
+ }
}
/*
@@ -559,248 +639,248 @@ public class OtpNode extends OtpLocalNode {
* references
*/
public class Mailboxes {
- // mbox pids here
- private Hashtable<OtpErlangPid, WeakReference<OtpMbox>> byPid = null;
- // mbox names here
- private Hashtable<String, WeakReference<OtpMbox>> byName = null;
-
- public Mailboxes() {
- byPid = new Hashtable<OtpErlangPid, WeakReference<OtpMbox>>(17,
- (float) 0.95);
- byName = new Hashtable<String, WeakReference<OtpMbox>>(17,
- (float) 0.95);
- }
-
- public OtpMbox create(final String name) {
- OtpMbox m = null;
-
- synchronized (byName) {
- if (get(name) != null) {
- return null;
- }
- final OtpErlangPid pid = createPid();
- m = new OtpMbox(OtpNode.this, pid, name);
- byPid.put(pid, new WeakReference<OtpMbox>(m));
- byName.put(name, new WeakReference<OtpMbox>(m));
- }
- return m;
- }
-
- public OtpMbox create() {
- final OtpErlangPid pid = createPid();
- final OtpMbox m = new OtpMbox(OtpNode.this, pid);
- byPid.put(pid, new WeakReference<OtpMbox>(m));
- return m;
- }
-
- public void clear() {
- byPid.clear();
- byName.clear();
- }
-
- public String[] names() {
- String allnames[] = null;
-
- synchronized (byName) {
- final int n = byName.size();
- final Enumeration<String> keys = byName.keys();
- allnames = new String[n];
-
- int i = 0;
- while (keys.hasMoreElements()) {
- allnames[i++] = keys.nextElement();
- }
- }
- return allnames;
- }
-
- public boolean register(final String name, final OtpMbox mbox) {
- if (name == null) {
- if (mbox.name != null) {
- byName.remove(mbox.name);
- mbox.name = null;
- }
- } else {
- synchronized (byName) {
- if (get(name) != null) {
- return false;
- }
- byName.put(name, new WeakReference<OtpMbox>(mbox));
- mbox.name = name;
- }
- }
- return true;
- }
-
- /*
- * look up a mailbox based on its name. If the mailbox has gone out of
- * scope we also remove the reference from the hashtable so we don't
- * find it again.
- */
- public OtpMbox get(final String name) {
- final WeakReference<OtpMbox> wr = byName.get(name);
-
- if (wr != null) {
- final OtpMbox m = wr.get();
-
- if (m != null) {
- return m;
- }
- byName.remove(name);
- }
- return null;
- }
-
- /*
- * look up a mailbox based on its pid. If the mailbox has gone out of
- * scope we also remove the reference from the hashtable so we don't
- * find it again.
- */
- public OtpMbox get(final OtpErlangPid pid) {
- final WeakReference<OtpMbox> wr = byPid.get(pid);
-
- if (wr != null) {
- final OtpMbox m = wr.get();
-
- if (m != null) {
- return m;
- }
- byPid.remove(pid);
- }
- return null;
- }
-
- public void remove(final OtpMbox mbox) {
- byPid.remove(mbox.self);
- if (mbox.name != null) {
- byName.remove(mbox.name);
- }
- }
+ // mbox pids here
+ private Hashtable<OtpErlangPid, WeakReference<OtpMbox>> byPid = null;
+ // mbox names here
+ private Hashtable<String, WeakReference<OtpMbox>> byName = null;
+
+ public Mailboxes() {
+ byPid = new Hashtable<OtpErlangPid, WeakReference<OtpMbox>>(17,
+ (float) 0.95);
+ byName = new Hashtable<String, WeakReference<OtpMbox>>(17,
+ (float) 0.95);
+ }
+
+ public OtpMbox create(final String name) {
+ OtpMbox m = null;
+
+ synchronized (byName) {
+ if (get(name) != null) {
+ return null;
+ }
+ final OtpErlangPid pid = createPid();
+ m = new OtpMbox(OtpNode.this, pid, name);
+ byPid.put(pid, new WeakReference<OtpMbox>(m));
+ byName.put(name, new WeakReference<OtpMbox>(m));
+ }
+ return m;
+ }
+
+ public OtpMbox create() {
+ final OtpErlangPid pid = createPid();
+ final OtpMbox m = new OtpMbox(OtpNode.this, pid);
+ byPid.put(pid, new WeakReference<OtpMbox>(m));
+ return m;
+ }
+
+ public void clear() {
+ byPid.clear();
+ byName.clear();
+ }
+
+ public String[] names() {
+ String allnames[] = null;
+
+ synchronized (byName) {
+ final int n = byName.size();
+ final Enumeration<String> keys = byName.keys();
+ allnames = new String[n];
+
+ int i = 0;
+ while (keys.hasMoreElements()) {
+ allnames[i++] = keys.nextElement();
+ }
+ }
+ return allnames;
+ }
+
+ public boolean register(final String name, final OtpMbox mbox) {
+ if (name == null) {
+ if (mbox.name != null) {
+ byName.remove(mbox.name);
+ mbox.name = null;
+ }
+ } else {
+ synchronized (byName) {
+ if (get(name) != null) {
+ return false;
+ }
+ byName.put(name, new WeakReference<OtpMbox>(mbox));
+ mbox.name = name;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * look up a mailbox based on its name. If the mailbox has gone out of
+ * scope we also remove the reference from the hashtable so we don't
+ * find it again.
+ */
+ public OtpMbox get(final String name) {
+ final WeakReference<OtpMbox> wr = byName.get(name);
+
+ if (wr != null) {
+ final OtpMbox m = wr.get();
+
+ if (m != null) {
+ return m;
+ }
+ byName.remove(name);
+ }
+ return null;
+ }
+
+ /*
+ * look up a mailbox based on its pid. If the mailbox has gone out of
+ * scope we also remove the reference from the hashtable so we don't
+ * find it again.
+ */
+ public OtpMbox get(final OtpErlangPid pid) {
+ final WeakReference<OtpMbox> wr = byPid.get(pid);
+
+ if (wr != null) {
+ final OtpMbox m = wr.get();
+
+ if (m != null) {
+ return m;
+ }
+ byPid.remove(pid);
+ }
+ return null;
+ }
+
+ public void remove(final OtpMbox mbox) {
+ byPid.remove(mbox.self);
+ if (mbox.name != null) {
+ byName.remove(mbox.name);
+ }
+ }
}
/*
* this thread simply listens for incoming connections
*/
public class Acceptor extends Thread {
- private final ServerSocket sock;
- private final int acceptorPort;
- private volatile boolean done = false;
-
- Acceptor(final int port) throws IOException {
- sock = new ServerSocket(port);
- this.acceptorPort = sock.getLocalPort();
- OtpNode.this.port = this.acceptorPort;
-
- setDaemon(true);
- setName("acceptor");
- publishPort();
- start();
- }
-
- private boolean publishPort() throws IOException {
- if (getEpmd() != null) {
- return false; // already published
- }
- OtpEpmd.publishPort(OtpNode.this);
- return true;
- }
-
- private void unPublishPort() {
- // unregister with epmd
- OtpEpmd.unPublishPort(OtpNode.this);
-
- // close the local descriptor (if we have one)
- closeSock(epmd);
- epmd = null;
- }
-
- public void quit() {
- unPublishPort();
- done = true;
- closeSock(sock);
- localStatus(node, false, null);
- }
-
- private void closeSock(final ServerSocket s) {
- try {
- if (s != null) {
- s.close();
- }
- } catch (final Exception e) {
- }
- }
-
- private void closeSock(final Socket s) {
- try {
- if (s != null) {
- s.close();
- }
- } catch (final Exception e) {
- }
- }
-
- public int port() {
- return acceptorPort;
- }
-
- @Override
- public void run() {
- Socket newsock = null;
- OtpCookedConnection conn = null;
-
- localStatus(node, true, null);
-
- accept_loop: while (!done) {
- conn = null;
-
- try {
- newsock = sock.accept();
- } catch (final Exception e) {
- // Problem in java1.2.2: accept throws SocketException
- // when socket is closed. This will happen when
- // acceptor.quit()
- // is called. acceptor.quit() will call localStatus(...), so
- // we have to check if that's where we come from.
- if (!done) {
- localStatus(node, false, e);
- }
- break accept_loop;
- }
-
- try {
- synchronized (connections) {
- conn = new OtpCookedConnection(OtpNode.this, newsock);
- conn.setFlags(connFlags);
- addConnection(conn);
- }
- } catch (final OtpAuthException e) {
- if (conn != null && conn.name != null) {
- connAttempt(conn.name, true, e);
- } else {
- connAttempt("unknown", true, e);
- }
- closeSock(newsock);
- } catch (final IOException e) {
- if (conn != null && conn.name != null) {
- connAttempt(conn.name, true, e);
- } else {
- connAttempt("unknown", true, e);
- }
- closeSock(newsock);
- } catch (final Exception e) {
- closeSock(newsock);
- closeSock(sock);
- localStatus(node, false, e);
- break accept_loop;
- }
- } // while
-
- // if we have exited loop we must do this too
- unPublishPort();
- }
+ private final OtpServerTransport sock;
+ private final int acceptorPort;
+ private volatile boolean done = false;
+
+ Acceptor(final int port) throws IOException {
+ sock = createServerTransport(port);
+ acceptorPort = sock.getLocalPort();
+ OtpNode.this.port = acceptorPort;
+
+ setDaemon(true);
+ setName("acceptor");
+ publishPort();
+ start();
+ }
+
+ private boolean publishPort() throws IOException {
+ if (getEpmd() != null) {
+ return false; // already published
+ }
+ OtpEpmd.publishPort(OtpNode.this);
+ return true;
+ }
+
+ private void unPublishPort() {
+ // unregister with epmd
+ OtpEpmd.unPublishPort(OtpNode.this);
+
+ // close the local descriptor (if we have one)
+ closeSock(epmd);
+ epmd = null;
+ }
+
+ public void quit() {
+ unPublishPort();
+ done = true;
+ closeSock(sock);
+ localStatus(node, false, null);
+ }
+
+ private void closeSock(final OtpServerTransport s) {
+ try {
+ if (s != null) {
+ s.close();
+ }
+ } catch (final Exception e) {
+ }
+ }
+
+ private void closeSock(final OtpTransport s) {
+ try {
+ if (s != null) {
+ s.close();
+ }
+ } catch (final Exception e) {
+ }
+ }
+
+ public int port() {
+ return acceptorPort;
+ }
+
+ @Override
+ public void run() {
+ OtpTransport newsock = null;
+ OtpCookedConnection conn = null;
+
+ localStatus(node, true, null);
+
+ accept_loop: while (!done) {
+ conn = null;
+
+ try {
+ newsock = sock.accept();
+ } catch (final Exception e) {
+ // Problem in java1.2.2: accept throws SocketException
+ // when socket is closed. This will happen when
+ // acceptor.quit()
+ // is called. acceptor.quit() will call localStatus(...), so
+ // we have to check if that's where we come from.
+ if (!done) {
+ localStatus(node, false, e);
+ }
+ break accept_loop;
+ }
+
+ try {
+ synchronized (connections) {
+ conn = new OtpCookedConnection(OtpNode.this, newsock);
+ conn.setFlags(connFlags);
+ addConnection(conn);
+ }
+ } catch (final OtpAuthException e) {
+ if (conn != null && conn.name != null) {
+ connAttempt(conn.name, true, e);
+ } else {
+ connAttempt("unknown", true, e);
+ }
+ closeSock(newsock);
+ } catch (final IOException e) {
+ if (conn != null && conn.name != null) {
+ connAttempt(conn.name, true, e);
+ } else {
+ connAttempt("unknown", true, e);
+ }
+ closeSock(newsock);
+ } catch (final Exception e) {
+ closeSock(newsock);
+ closeSock(sock);
+ localStatus(node, false, e);
+ break accept_loop;
+ }
+ } // while
+
+ // if we have exited loop we must do this too
+ unPublishPort();
+ }
}
public void setFlags(final int flags) {
- this.connFlags = flags;
+ connFlags = flags;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNodeStatus.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNodeStatus.java
index aee1f8b67a..4c0cb257fe 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNodeStatus.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNodeStatus.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -25,13 +26,13 @@ package com.ericsson.otp.erlang;
* with your {@link OtpNode OtpNode} when you wish to be notified about such
* status changes and other similar events.
* </p>
- *
+ *
* <p>
* This class provides default handers that ignore all events. Applications are
* expected to extend this class in order to act on events that are deemed
* interesting.
* </p>
- *
+ *
* <p>
* <b> Note that this class is likely to change in the near future </b>
* </p>
@@ -42,59 +43,57 @@ public class OtpNodeStatus {
/**
* Notify about remote node status changes.
- *
+ *
* @param node
- * the node whose status change is being indicated by this
- * call.
- *
+ * the node whose status change is being indicated by this call.
+ *
* @param up
- * true if the node has come up, false if it has gone down.
- *
+ * true if the node has come up, false if it has gone down.
+ *
* @param info
- * additional info that may be available, for example an
- * exception that was raised causing the event in question
- * (may be null).
- *
+ * additional info that may be available, for example an
+ * exception that was raised causing the event in question (may
+ * be null).
+ *
*/
public void remoteStatus(final String node, final boolean up,
- final Object info) {
+ final Object info) {
}
/**
* Notify about local node exceptions.
- *
+ *
* @param node
- * the node whose status change is being indicated by this
- * call.
- *
+ * the node whose status change is being indicated by this call.
+ *
* @param up
- * true if the node has come up, false if it has gone down.
- *
+ * true if the node has come up, false if it has gone down.
+ *
* @param info
- * additional info that may be available, for example an
- * exception that was raised causing the event in question
- * (may be null).
+ * additional info that may be available, for example an
+ * exception that was raised causing the event in question (may
+ * be null).
*/
public void localStatus(final String node, final boolean up,
- final Object info) {
+ final Object info) {
}
/**
* Notify about failed connection attempts.
- *
+ *
* @param node
- * The name of the remote node
- *
+ * The name of the remote node
+ *
* @param incoming
- * The direction of the connection attempt, i.e. true for
- * incoming, false for outgoing.
- *
+ * The direction of the connection attempt, i.e. true for
+ * incoming, false for outgoing.
+ *
* @param info
- * additional info that may be available, for example an
- * exception that was raised causing the event in question
- * (may be null).
+ * additional info that may be available, for example an
+ * exception that was raised causing the event in question (may
+ * be null).
*/
public void connAttempt(final String node, final boolean incoming,
- final Object info) {
+ final Object info) {
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
index ef60a9f38a..4faae2a157 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-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.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -21,6 +22,7 @@ package com.ericsson.otp.erlang;
// import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -30,17 +32,20 @@ import java.util.zip.Deflater;
/**
* Provides a stream for encoding Erlang terms to external format, for
* transmission or storage.
- *
+ *
* <p>
* Note that this class is not synchronized, if you need synchronization you
* must provide it yourself.
- *
+ *
*/
public class OtpOutputStream extends ByteArrayOutputStream {
/** The default initial size of the stream. * */
public static final int defaultInitialSize = 2048;
- /** The default increment used when growing the stream (increment at least this much). * */
+ /**
+ * The default increment used when growing the stream (increment at least
+ * this much). *
+ */
public static final int defaultIncrement = 2048;
// static formats, used to encode floats and doubles
@@ -57,66 +62,66 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* Create a stream with the default initial size (2048 bytes).
*/
public OtpOutputStream() {
- this(defaultInitialSize);
+ this(defaultInitialSize);
}
/**
* Create a stream with the specified initial size.
*/
public OtpOutputStream(final int size) {
- super(size);
+ super(size);
}
/**
* Create a stream containing the encoded version of the given Erlang term.
*/
public OtpOutputStream(final OtpErlangObject o) {
- this();
- write_any(o);
+ this();
+ write_any(o);
}
// package scope
/*
* Get the contents of the output stream as an input stream instead. This is
* used internally in {@link OtpCconnection} for tracing outgoing packages.
- *
+ *
* @param offset where in the output stream to read data from when creating
* the input stream. The offset is necessary because header contents start 5
* bytes into the header buffer, whereas payload contents start at the
* beginning
- *
+ *
* @return an input stream containing the same raw data.
*/
OtpInputStream getOtpInputStream(final int offset) {
- return new OtpInputStream(super.buf, offset, super.count - offset, 0);
+ return new OtpInputStream(super.buf, offset, super.count - offset, 0);
}
/**
* Get the current position in the stream.
- *
+ *
* @return the current position in the stream.
*/
public int getPos() {
- return super.count;
+ return super.count;
}
/**
* Trims the capacity of this <tt>OtpOutputStream</tt> instance to be the
- * buffer's current size. An application can use this operation to minimize
+ * buffer's current size. An application can use this operation to minimize
* the storage of an <tt>OtpOutputStream</tt> instance.
*/
public void trimToSize() {
- resize(super.count);
+ resize(super.count);
}
- private void resize(int size) {
- if (size < super.buf.length) {
- final byte[] tmp = new byte[size];
- System.arraycopy(super.buf, 0, tmp, 0, size);
- super.buf = tmp;
- } else if (size > super.buf.length) {
- ensureCapacity(size);
- }
+ private void resize(final int size) {
+ if (size < super.buf.length) {
+ final byte[] tmp = new byte[size];
+ System.arraycopy(super.buf, 0, tmp, 0, size);
+ super.buf = tmp;
+ } else if (size > super.buf.length) {
+ ensureCapacity(size);
+ }
}
/**
@@ -124,228 +129,247 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
- * @param minCapacity the desired minimum capacity
+ * @param minCapacity
+ * the desired minimum capacity
*/
- public void ensureCapacity(int minCapacity) {
- if (minCapacity > fixedSize) {
- throw new IllegalArgumentException("Trying to increase fixed-size buffer");
- }
- int oldCapacity = super.buf.length;
- if (minCapacity > oldCapacity) {
- int newCapacity = (oldCapacity * 3)/2 + 1;
- if (newCapacity < oldCapacity + defaultIncrement)
- newCapacity = oldCapacity + defaultIncrement;
- if (newCapacity < minCapacity)
- newCapacity = minCapacity;
- newCapacity = Math.min(fixedSize, newCapacity);
- // minCapacity is usually close to size, so this is a win:
- final byte[] tmp = new byte[newCapacity];
- System.arraycopy(super.buf, 0, tmp, 0, super.count);
- super.buf = tmp;
- }
+ public void ensureCapacity(final int minCapacity) {
+ if (minCapacity > fixedSize) {
+ throw new IllegalArgumentException(
+ "Trying to increase fixed-size buffer");
+ }
+ final int oldCapacity = super.buf.length;
+ if (minCapacity > oldCapacity) {
+ int newCapacity = oldCapacity * 3 / 2 + 1;
+ if (newCapacity < oldCapacity + defaultIncrement) {
+ newCapacity = oldCapacity + defaultIncrement;
+ }
+ if (newCapacity < minCapacity) {
+ newCapacity = minCapacity;
+ }
+ newCapacity = Math.min(fixedSize, newCapacity);
+ // minCapacity is usually close to size, so this is a win:
+ final byte[] tmp = new byte[newCapacity];
+ System.arraycopy(super.buf, 0, tmp, 0, super.count);
+ super.buf = tmp;
+ }
}
/**
* Write one byte to the stream.
- *
+ *
* @param b
* the byte to write.
- *
+ *
*/
public void write(final byte b) {
- ensureCapacity(super.count + 1);
- super.buf[super.count++] = b;
+ ensureCapacity(super.count + 1);
+ super.buf[super.count++] = b;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.io.ByteArrayOutputStream#write(byte[])
*/
@Override
public void write(final byte[] abuf) {
- // don't assume that super.write(byte[]) calls write(buf, 0, buf.length)
- write(abuf, 0, abuf.length);
+ // don't assume that super.write(byte[]) calls write(buf, 0, buf.length)
+ write(abuf, 0, abuf.length);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.io.ByteArrayOutputStream#write(int)
*/
@Override
- public synchronized void write(int b) {
- ensureCapacity(super.count + 1);
- super.buf[super.count] = (byte) b;
- count += 1;
+ public synchronized void write(final int b) {
+ ensureCapacity(super.count + 1);
+ super.buf[super.count] = (byte) b;
+ count += 1;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.io.ByteArrayOutputStream#write(byte[], int, int)
*/
@Override
- public synchronized void write(byte[] b, int off, int len) {
- if ((off < 0) || (off > b.length) || (len < 0)
- || ((off + len) - b.length > 0)) {
- throw new IndexOutOfBoundsException();
- }
- ensureCapacity(super.count + len);
- System.arraycopy(b, off, super.buf, super.count, len);
- super.count += len;
+ public synchronized void write(final byte[] b, final int off, final int len) {
+ if (off < 0 || off > b.length || len < 0 || off + len - b.length > 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ ensureCapacity(super.count + len);
+ System.arraycopy(b, off, super.buf, super.count, len);
+ super.count += len;
+ }
+
+ @Override
+ public synchronized void writeTo(OutputStream out) throws IOException {
+ super.writeTo(out);
+ }
+
+ public synchronized void writeToAndFlush(OutputStream out) throws IOException {
+ super.writeTo(out);
+ out.flush();
}
/**
* Write the low byte of a value to the stream.
- *
+ *
* @param n
* the value to use.
- *
+ *
*/
public void write1(final long n) {
- write((byte) (n & 0xff));
+ write((byte) (n & 0xff));
}
/**
* Write an array of bytes to the stream.
- *
+ *
* @param bytes
* the array of bytes to write.
- *
+ *
*/
public void writeN(final byte[] bytes) {
- write(bytes);
+ write(bytes);
}
/**
* Get the current capacity of the stream. As bytes are added the capacity
* of the stream is increased automatically, however this method returns the
* current size.
- *
+ *
* @return the size of the internal buffer used by the stream.
*/
public int length() {
- return super.buf.length;
+ return super.buf.length;
}
/**
* Get the number of bytes in the stream.
- *
+ *
* @return the number of bytes in the stream.
- *
+ *
* @deprecated As of Jinterface 1.4, replaced by super.size().
* @see #size()
*/
@Deprecated
public int count() {
- return count;
+ return count;
}
/**
* Write the low two bytes of a value to the stream in big endian order.
- *
+ *
* @param n
* the value to use.
*/
public void write2BE(final long n) {
- write((byte) ((n & 0xff00) >> 8));
- write((byte) (n & 0xff));
+ write((byte) ((n & 0xff00) >> 8));
+ write((byte) (n & 0xff));
}
/**
* Write the low four bytes of a value to the stream in big endian order.
- *
+ *
* @param n
* the value to use.
*/
public void write4BE(final long n) {
- write((byte) ((n & 0xff000000) >> 24));
- write((byte) ((n & 0xff0000) >> 16));
- write((byte) ((n & 0xff00) >> 8));
- write((byte) (n & 0xff));
+ write((byte) ((n & 0xff000000) >> 24));
+ write((byte) ((n & 0xff0000) >> 16));
+ write((byte) ((n & 0xff00) >> 8));
+ write((byte) (n & 0xff));
}
/**
* Write the low eight (all) bytes of a value to the stream in big endian
* order.
- *
+ *
* @param n
* the value to use.
*/
public void write8BE(final long n) {
- write((byte) (n >> 56 & 0xff));
- write((byte) (n >> 48 & 0xff));
- write((byte) (n >> 40 & 0xff));
- write((byte) (n >> 32 & 0xff));
- write((byte) (n >> 24 & 0xff));
- write((byte) (n >> 16 & 0xff));
- write((byte) (n >> 8 & 0xff));
- write((byte) (n & 0xff));
+ write((byte) (n >> 56 & 0xff));
+ write((byte) (n >> 48 & 0xff));
+ write((byte) (n >> 40 & 0xff));
+ write((byte) (n >> 32 & 0xff));
+ write((byte) (n >> 24 & 0xff));
+ write((byte) (n >> 16 & 0xff));
+ write((byte) (n >> 8 & 0xff));
+ write((byte) (n & 0xff));
}
/**
* Write any number of bytes in little endian format.
- *
+ *
* @param n
* the value to use.
* @param b
* the number of bytes to write from the little end.
*/
public void writeLE(final long n, final int b) {
- long v = n;
- for (int i = 0; i < b; i++) {
- write((byte) (v & 0xff));
- v >>= 8;
- }
+ long v = n;
+ for (int i = 0; i < b; i++) {
+ write((byte) (v & 0xff));
+ v >>= 8;
+ }
}
/**
* Write the low two bytes of a value to the stream in little endian order.
- *
+ *
* @param n
* the value to use.
*/
public void write2LE(final long n) {
- write((byte) (n & 0xff));
- write((byte) ((n & 0xff00) >> 8));
+ write((byte) (n & 0xff));
+ write((byte) ((n & 0xff00) >> 8));
}
/**
* Write the low four bytes of a value to the stream in little endian order.
- *
+ *
* @param n
* the value to use.
*/
public void write4LE(final long n) {
- write((byte) (n & 0xff));
- write((byte) ((n & 0xff00) >> 8));
- write((byte) ((n & 0xff0000) >> 16));
- write((byte) ((n & 0xff000000) >> 24));
+ write((byte) (n & 0xff));
+ write((byte) ((n & 0xff00) >> 8));
+ write((byte) ((n & 0xff0000) >> 16));
+ write((byte) ((n & 0xff000000) >> 24));
}
/**
* Write the low eight bytes of a value to the stream in little endian
* order.
- *
+ *
* @param n
* the value to use.
*/
public void write8LE(final long n) {
- write((byte) (n & 0xff));
- write((byte) (n >> 8 & 0xff));
- write((byte) (n >> 16 & 0xff));
- write((byte) (n >> 24 & 0xff));
- write((byte) (n >> 32 & 0xff));
- write((byte) (n >> 40 & 0xff));
- write((byte) (n >> 48 & 0xff));
- write((byte) (n >> 56 & 0xff));
+ write((byte) (n & 0xff));
+ write((byte) (n >> 8 & 0xff));
+ write((byte) (n >> 16 & 0xff));
+ write((byte) (n >> 24 & 0xff));
+ write((byte) (n >> 32 & 0xff));
+ write((byte) (n >> 40 & 0xff));
+ write((byte) (n >> 48 & 0xff));
+ write((byte) (n >> 56 & 0xff));
}
/**
* Write the low four bytes of a value to the stream in bif endian order, at
* the specified position. If the position specified is beyond the end of
* the stream, this method will have no effect.
- *
+ *
* Normally this method should be used in conjunction with {@link #size()
* size()}, when is is necessary to insert data into the stream before it is
* known what the actual value should be. For example:
- *
+ *
* <pre>
* int pos = s.size();
* s.write4BE(0); // make space for length data,
@@ -354,501 +378,495 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* // later... when we know the length value
* s.poke4BE(pos, length);
* </pre>
- *
- *
+ *
+ *
* @param offset
* the position in the stream.
* @param n
* the value to use.
*/
public void poke4BE(final int offset, final long n) {
- if (offset < super.count) {
- buf[offset + 0] = (byte) ((n & 0xff000000) >> 24);
- buf[offset + 1] = (byte) ((n & 0xff0000) >> 16);
- buf[offset + 2] = (byte) ((n & 0xff00) >> 8);
- buf[offset + 3] = (byte) (n & 0xff);
- }
+ if (offset < super.count) {
+ buf[offset + 0] = (byte) ((n & 0xff000000) >> 24);
+ buf[offset + 1] = (byte) ((n & 0xff0000) >> 16);
+ buf[offset + 2] = (byte) ((n & 0xff00) >> 8);
+ buf[offset + 3] = (byte) (n & 0xff);
+ }
}
/**
* Write a string to the stream as an Erlang atom.
- *
+ *
* @param atom
* the string to write.
*/
public void write_atom(final String atom) {
- String enc_atom;
- byte[] bytes;
- boolean isLatin1 = true;
-
- if (atom.codePointCount(0, atom.length()) <= OtpExternal.maxAtomLength) {
- enc_atom = atom;
- }
- else {
- /*
- * Throwing an exception would be better I think,
- * but truncation seems to be the way it has
- * been done in other parts of OTP...
- */
- enc_atom = new String(OtpErlangString.stringToCodePoints(atom),
- 0, OtpExternal.maxAtomLength);
- }
-
- for (int offset = 0; offset < enc_atom.length();) {
- final int cp = enc_atom.codePointAt(offset);
- if ((cp & ~0xFF) != 0) {
- isLatin1 = false;
- break;
- }
- offset += Character.charCount(cp);
- }
- try {
- if (isLatin1) {
- bytes = enc_atom.getBytes("ISO-8859-1");
- write1(OtpExternal.atomTag);
- write2BE(bytes.length);
- }
- else {
- bytes = enc_atom.getBytes("UTF-8");
- final int length = bytes.length;
- if (length < 256) {
- write1(OtpExternal.smallAtomUtf8Tag);
- write1(length);
- }
- else {
- write1(OtpExternal.atomUtf8Tag);
- write2BE(length);
- }
- }
- writeN(bytes);
- } catch (final java.io.UnsupportedEncodingException e) {
- /*
- * Sigh, why didn't the API designer add an
- * OtpErlangEncodeException to these encoding
- * functions?!? Instead of changing the API we
- * write an invalid atom and let it fail for
- * whoever trying to decode this... Sigh,
- * again...
- */
- write1(OtpExternal.smallAtomUtf8Tag);
- write1(2);
- write2BE(0xffff); /* Invalid UTF-8 */
- }
+ String enc_atom;
+ byte[] bytes;
+ boolean isLatin1 = true;
+
+ if (atom.codePointCount(0, atom.length()) <= OtpExternal.maxAtomLength) {
+ enc_atom = atom;
+ } else {
+ /*
+ * Throwing an exception would be better I think, but truncation
+ * seems to be the way it has been done in other parts of OTP...
+ */
+ enc_atom = new String(OtpErlangString.stringToCodePoints(atom), 0,
+ OtpExternal.maxAtomLength);
+ }
+
+ for (int offset = 0; offset < enc_atom.length();) {
+ final int cp = enc_atom.codePointAt(offset);
+ if ((cp & ~0xFF) != 0) {
+ isLatin1 = false;
+ break;
+ }
+ offset += Character.charCount(cp);
+ }
+ try {
+ if (isLatin1) {
+ bytes = enc_atom.getBytes("ISO-8859-1");
+ write1(OtpExternal.atomTag);
+ write2BE(bytes.length);
+ } else {
+ bytes = enc_atom.getBytes("UTF-8");
+ final int length = bytes.length;
+ if (length < 256) {
+ write1(OtpExternal.smallAtomUtf8Tag);
+ write1(length);
+ } else {
+ write1(OtpExternal.atomUtf8Tag);
+ write2BE(length);
+ }
+ }
+ writeN(bytes);
+ } catch (final java.io.UnsupportedEncodingException e) {
+ /*
+ * Sigh, why didn't the API designer add an OtpErlangEncodeException
+ * to these encoding functions?!? Instead of changing the API we
+ * write an invalid atom and let it fail for whoever trying to
+ * decode this... Sigh, again...
+ */
+ write1(OtpExternal.smallAtomUtf8Tag);
+ write1(2);
+ write2BE(0xffff); /* Invalid UTF-8 */
+ }
}
/**
* Write an array of bytes to the stream as an Erlang binary.
- *
+ *
* @param bin
* the array of bytes to write.
*/
public void write_binary(final byte[] bin) {
- write1(OtpExternal.binTag);
- write4BE(bin.length);
- writeN(bin);
+ write1(OtpExternal.binTag);
+ write4BE(bin.length);
+ writeN(bin);
}
/**
* Write an array of bytes to the stream as an Erlang bitstr.
- *
+ *
* @param bin
* the array of bytes to write.
* @param pad_bits
* the number of zero pad bits at the low end of the last byte
*/
public void write_bitstr(final byte[] bin, final int pad_bits) {
- if (pad_bits == 0) {
- write_binary(bin);
- return;
- }
- write1(OtpExternal.bitBinTag);
- write4BE(bin.length);
- write1(8 - pad_bits);
- writeN(bin);
+ if (pad_bits == 0) {
+ write_binary(bin);
+ return;
+ }
+ write1(OtpExternal.bitBinTag);
+ write4BE(bin.length);
+ write1(8 - pad_bits);
+ writeN(bin);
}
/**
* Write a boolean value to the stream as the Erlang atom 'true' or 'false'.
- *
+ *
* @param b
* the boolean value to write.
*/
public void write_boolean(final boolean b) {
- write_atom(String.valueOf(b));
+ write_atom(String.valueOf(b));
}
/**
* Write a single byte to the stream as an Erlang integer. The byte is
* really an IDL 'octet', that is, unsigned.
- *
+ *
* @param b
* the byte to use.
*/
public void write_byte(final byte b) {
- this.write_long(b & 0xffL, true);
+ this.write_long(b & 0xffL, true);
}
/**
* Write a character to the stream as an Erlang integer. The character may
* be a 16 bit character, kind of IDL 'wchar'. It is up to the Erlang side
* to take care of souch, if they should be used.
- *
+ *
* @param c
* the character to use.
*/
public void write_char(final char c) {
- this.write_long(c & 0xffffL, true);
+ this.write_long(c & 0xffffL, true);
}
/**
* Write a double value to the stream.
- *
+ *
* @param d
* the double to use.
*/
public void write_double(final double d) {
- write1(OtpExternal.newFloatTag);
- write8BE(Double.doubleToLongBits(d));
+ write1(OtpExternal.newFloatTag);
+ write8BE(Double.doubleToLongBits(d));
}
/**
* Write a float value to the stream.
- *
+ *
* @param f
* the float to use.
*/
public void write_float(final float f) {
- write_double(f);
+ write_double(f);
}
public void write_big_integer(final BigInteger v) {
- if (v.bitLength() < 64) {
- this.write_long(v.longValue(), true);
- return;
- }
- final int signum = v.signum();
- BigInteger val = v;
- if (signum < 0) {
- val = val.negate();
- }
- final byte[] magnitude = val.toByteArray();
- final int n = magnitude.length;
- // Reverse the array to make it little endian.
- for (int i = 0, j = n; i < j--; i++) {
- // Swap [i] with [j]
- final byte b = magnitude[i];
- magnitude[i] = magnitude[j];
- magnitude[j] = b;
- }
- if ((n & 0xFF) == n) {
- write1(OtpExternal.smallBigTag);
- write1(n); // length
- } else {
- write1(OtpExternal.largeBigTag);
- write4BE(n); // length
- }
- write1(signum < 0 ? 1 : 0); // sign
- // Write the array
- writeN(magnitude);
+ if (v.bitLength() < 64) {
+ this.write_long(v.longValue(), true);
+ return;
+ }
+ final int signum = v.signum();
+ BigInteger val = v;
+ if (signum < 0) {
+ val = val.negate();
+ }
+ final byte[] magnitude = val.toByteArray();
+ final int n = magnitude.length;
+ // Reverse the array to make it little endian.
+ for (int i = 0, j = n; i < j--; i++) {
+ // Swap [i] with [j]
+ final byte b = magnitude[i];
+ magnitude[i] = magnitude[j];
+ magnitude[j] = b;
+ }
+ if ((n & 0xFF) == n) {
+ write1(OtpExternal.smallBigTag);
+ write1(n); // length
+ } else {
+ write1(OtpExternal.largeBigTag);
+ write4BE(n); // length
+ }
+ write1(signum < 0 ? 1 : 0); // sign
+ // Write the array
+ writeN(magnitude);
}
void write_long(final long v, final boolean unsigned) {
- /*
- * If v<0 and unsigned==true the value
- * java.lang.Long.MAX_VALUE-java.lang.Long.MIN_VALUE+1+v is written, i.e
- * v is regarded as unsigned two's complement.
- */
- if ((v & 0xffL) == v) {
- // will fit in one byte
- write1(OtpExternal.smallIntTag);
- write1(v);
- } else {
- // note that v != 0L
- if (v < 0 && unsigned || v < OtpExternal.erlMin
- || v > OtpExternal.erlMax) {
- // some kind of bignum
- final long abs = unsigned ? v : v < 0 ? -v : v;
- final int sign = unsigned ? 0 : v < 0 ? 1 : 0;
- int n;
- long mask;
- for (mask = 0xFFFFffffL, n = 4; (abs & mask) != abs; n++, mask = mask << 8 | 0xffL) {
- // count nonzero bytes
- }
- write1(OtpExternal.smallBigTag);
- write1(n); // length
- write1(sign); // sign
- writeLE(abs, n); // value. obs! little endian
- } else {
- write1(OtpExternal.intTag);
- write4BE(v);
- }
- }
+ /*
+ * If v<0 and unsigned==true the value
+ * java.lang.Long.MAX_VALUE-java.lang.Long.MIN_VALUE+1+v is written, i.e
+ * v is regarded as unsigned two's complement.
+ */
+ if ((v & 0xffL) == v) {
+ // will fit in one byte
+ write1(OtpExternal.smallIntTag);
+ write1(v);
+ } else {
+ // note that v != 0L
+ if (v < 0 && unsigned || v < OtpExternal.erlMin
+ || v > OtpExternal.erlMax) {
+ // some kind of bignum
+ final long abs = unsigned ? v : v < 0 ? -v : v;
+ final int sign = unsigned ? 0 : v < 0 ? 1 : 0;
+ int n;
+ long mask;
+ for (mask = 0xFFFFffffL, n = 4; (abs & mask) != abs; n++, mask = mask << 8 | 0xffL) {
+ // count nonzero bytes
+ }
+ write1(OtpExternal.smallBigTag);
+ write1(n); // length
+ write1(sign); // sign
+ writeLE(abs, n); // value. obs! little endian
+ } else {
+ write1(OtpExternal.intTag);
+ write4BE(v);
+ }
+ }
}
/**
* Write a long to the stream.
- *
+ *
* @param l
* the long to use.
*/
public void write_long(final long l) {
- this.write_long(l, false);
+ this.write_long(l, false);
}
/**
* Write a positive long to the stream. The long is interpreted as a two's
* complement unsigned long even if it is negative.
- *
+ *
* @param ul
* the long to use.
*/
public void write_ulong(final long ul) {
- this.write_long(ul, true);
+ this.write_long(ul, true);
}
/**
* Write an integer to the stream.
- *
+ *
* @param i
* the integer to use.
*/
public void write_int(final int i) {
- this.write_long(i, false);
+ this.write_long(i, false);
}
/**
* Write a positive integer to the stream. The integer is interpreted as a
* two's complement unsigned integer even if it is negative.
- *
+ *
* @param ui
* the integer to use.
*/
public void write_uint(final int ui) {
- this.write_long(ui & 0xFFFFffffL, true);
+ this.write_long(ui & 0xFFFFffffL, true);
}
/**
* Write a short to the stream.
- *
+ *
* @param s
* the short to use.
*/
public void write_short(final short s) {
- this.write_long(s, false);
+ this.write_long(s, false);
}
/**
* Write a positive short to the stream. The short is interpreted as a two's
* complement unsigned short even if it is negative.
- *
+ *
* @param us
* the short to use.
*/
public void write_ushort(final short us) {
- this.write_long(us & 0xffffL, true);
+ this.write_long(us & 0xffffL, true);
}
/**
* Write an Erlang list header to the stream. After calling this method, you
* must write 'arity' elements to the stream followed by nil, or it will not
* be possible to decode it later.
- *
+ *
* @param arity
* the number of elements in the list.
*/
public void write_list_head(final int arity) {
- if (arity == 0) {
- write_nil();
- } else {
- write1(OtpExternal.listTag);
- write4BE(arity);
- }
+ if (arity == 0) {
+ write_nil();
+ } else {
+ write1(OtpExternal.listTag);
+ write4BE(arity);
+ }
}
/**
* Write an empty Erlang list to the stream.
*/
public void write_nil() {
- write1(OtpExternal.nilTag);
+ write1(OtpExternal.nilTag);
}
/**
* Write an Erlang tuple header to the stream. After calling this method,
* you must write 'arity' elements to the stream or it will not be possible
* to decode it later.
- *
+ *
* @param arity
* the number of elements in the tuple.
*/
public void write_tuple_head(final int arity) {
- if (arity < 0xff) {
- write1(OtpExternal.smallTupleTag);
- write1(arity);
- } else {
- write1(OtpExternal.largeTupleTag);
- write4BE(arity);
- }
+ if (arity < 0xff) {
+ write1(OtpExternal.smallTupleTag);
+ write1(arity);
+ } else {
+ write1(OtpExternal.largeTupleTag);
+ write4BE(arity);
+ }
}
/**
* Write an Erlang PID to the stream.
- *
+ *
* @param node
* the nodename.
- *
+ *
* @param id
* an arbitrary number. Only the low order 15 bits will be used.
- *
+ *
* @param serial
* another arbitrary number. Only the low order 13 bits will be
* used.
- *
+ *
* @param creation
* yet another arbitrary number. Only the low order 2 bits will
* be used.
- *
+ *
*/
public void write_pid(final String node, final int id, final int serial,
- final int creation) {
- write1(OtpExternal.pidTag);
- write_atom(node);
- write4BE(id & 0x7fff); // 15 bits
- write4BE(serial & 0x1fff); // 13 bits
- write1(creation & 0x3); // 2 bits
+ final int creation) {
+ write1(OtpExternal.pidTag);
+ write_atom(node);
+ write4BE(id & 0x7fff); // 15 bits
+ write4BE(serial & 0x1fff); // 13 bits
+ write1(creation & 0x3); // 2 bits
}
/**
* Write an Erlang port to the stream.
- *
+ *
* @param node
* the nodename.
- *
+ *
* @param id
* an arbitrary number. Only the low order 28 bits will be used.
- *
+ *
* @param creation
* another arbitrary number. Only the low order 2 bits will be
* used.
- *
+ *
*/
public void write_port(final String node, final int id, final int creation) {
- write1(OtpExternal.portTag);
- write_atom(node);
- write4BE(id & 0xfffffff); // 28 bits
- write1(creation & 0x3); // 2 bits
+ write1(OtpExternal.portTag);
+ write_atom(node);
+ write4BE(id & 0xfffffff); // 28 bits
+ write1(creation & 0x3); // 2 bits
}
/**
* Write an old style Erlang ref to the stream.
- *
+ *
* @param node
* the nodename.
- *
+ *
* @param id
* an arbitrary number. Only the low order 18 bits will be used.
- *
+ *
* @param creation
* another arbitrary number. Only the low order 2 bits will be
* used.
- *
+ *
*/
public void write_ref(final String node, final int id, final int creation) {
- write1(OtpExternal.refTag);
- write_atom(node);
- write4BE(id & 0x3ffff); // 18 bits
- write1(creation & 0x3); // 2 bits
+ write1(OtpExternal.refTag);
+ write_atom(node);
+ write4BE(id & 0x3ffff); // 18 bits
+ write1(creation & 0x3); // 2 bits
}
/**
* Write a new style (R6 and later) Erlang ref to the stream.
- *
+ *
* @param node
* the nodename.
- *
+ *
* @param ids
* an array of arbitrary numbers. Only the low order 18 bits of
* the first number will be used. If the array contains only one
* number, an old style ref will be written instead. At most
* three numbers will be read from the array.
- *
+ *
* @param creation
* another arbitrary number. Only the low order 2 bits will be
* used.
- *
+ *
*/
public void write_ref(final String node, final int[] ids, final int creation) {
- int arity = ids.length;
- if (arity > 3) {
- arity = 3; // max 3 words in ref
- }
+ int arity = ids.length;
+ if (arity > 3) {
+ arity = 3; // max 3 words in ref
+ }
- if (arity == 1) {
- // use old method
- this.write_ref(node, ids[0], creation);
- } else {
- // r6 ref
- write1(OtpExternal.newRefTag);
+ if (arity == 1) {
+ // use old method
+ this.write_ref(node, ids[0], creation);
+ } else {
+ // r6 ref
+ write1(OtpExternal.newRefTag);
- // how many id values
- write2BE(arity);
+ // how many id values
+ write2BE(arity);
- write_atom(node);
+ write_atom(node);
- // note: creation BEFORE id in r6 ref
- write1(creation & 0x3); // 2 bits
+ // note: creation BEFORE id in r6 ref
+ write1(creation & 0x3); // 2 bits
- // first int gets truncated to 18 bits
- write4BE(ids[0] & 0x3ffff);
+ // first int gets truncated to 18 bits
+ write4BE(ids[0] & 0x3ffff);
- // remaining ones are left as is
- for (int i = 1; i < arity; i++) {
- write4BE(ids[i]);
- }
- }
+ // remaining ones are left as is
+ for (int i = 1; i < arity; i++) {
+ write4BE(ids[i]);
+ }
+ }
}
/**
* Write a string to the stream.
- *
+ *
* @param s
* the string to write.
*/
public void write_string(final String s) {
- final int len = s.length();
-
- switch (len) {
- case 0:
- write_nil();
- break;
- default:
- if (len <= 65535 && is8bitString(s)) { // 8-bit string
- try {
- final byte[] bytebuf = s.getBytes("ISO-8859-1");
- write1(OtpExternal.stringTag);
- write2BE(len);
- writeN(bytebuf);
- } catch (final UnsupportedEncodingException e) {
- write_nil(); // it should never ever get here...
- }
- } else { // unicode or longer, must code as list
- final int[] codePoints = OtpErlangString.stringToCodePoints(s);
- write_list_head(codePoints.length);
- for (final int codePoint : codePoints) {
- write_int(codePoint);
- }
- write_nil();
- }
- }
+ final int len = s.length();
+
+ switch (len) {
+ case 0:
+ write_nil();
+ break;
+ default:
+ if (len <= 65535 && is8bitString(s)) { // 8-bit string
+ try {
+ final byte[] bytebuf = s.getBytes("ISO-8859-1");
+ write1(OtpExternal.stringTag);
+ write2BE(len);
+ writeN(bytebuf);
+ } catch (final UnsupportedEncodingException e) {
+ write_nil(); // it should never ever get here...
+ }
+ } else { // unicode or longer, must code as list
+ final int[] codePoints = OtpErlangString.stringToCodePoints(s);
+ write_list_head(codePoints.length);
+ for (final int codePoint : codePoints) {
+ write_int(codePoint);
+ }
+ write_nil();
+ }
+ }
}
private boolean is8bitString(final String s) {
- for (int i = 0; i < s.length(); ++i) {
- final char c = s.charAt(i);
- if (c < 0 || c > 255) {
- return false;
- }
- }
- return true;
+ for (int i = 0; i < s.length(); ++i) {
+ final char c = s.charAt(i);
+ if (c < 0 || c > 255) {
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -858,7 +876,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* the Erlang term to write.
*/
public void write_compressed(final OtpErlangObject o) {
- write_compressed(o, Deflater.DEFAULT_COMPRESSION);
+ write_compressed(o, Deflater.DEFAULT_COMPRESSION);
}
/**
@@ -869,119 +887,128 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* @param level
* the compression level (<tt>0..9</tt>)
*/
- public void write_compressed(final OtpErlangObject o, int level) {
- @SuppressWarnings("resource")
- final OtpOutputStream oos = new OtpOutputStream(o);
- /*
- * similar to erts_term_to_binary() in external.c:
- * We don't want to compress if compression actually increases the size.
- * Since compression uses 5 extra bytes (COMPRESSED tag + size), don't
- * compress if the original term is smaller.
- */
- if (oos.size() < 5) {
- // fast path for small terms
- try {
- oos.writeTo(this);
- // if the term is written as a compressed term, the output
- // stream is closed, so we do this here, too
- this.close();
- } catch (IOException e) {
- throw new java.lang.IllegalArgumentException(
- "Intermediate stream failed for Erlang object " + o);
- }
- } else {
- int startCount = super.count;
- // we need destCount bytes for an uncompressed term
- // -> if compression uses more, use the uncompressed term!
- int destCount = startCount + oos.size();
- this.fixedSize = destCount;
- Deflater def = new Deflater(level);
- final java.util.zip.DeflaterOutputStream dos = new java.util.zip.DeflaterOutputStream(
- this, def);
- try {
- write1(OtpExternal.compressedTag);
- write4BE(oos.size());
- oos.writeTo(dos);
- dos.close(); // note: closes this, too!
- } catch (final IllegalArgumentException e) {
- // discard further un-compressed data
- // -> if not called, there may be memory leaks!
- def.end();
- // could not make the value smaller than originally
- // -> reset to starting count, write uncompressed
- super.count = startCount;
- try {
- oos.writeTo(this);
- // if the term is written as a compressed term, the output
- // stream is closed, so we do this here, too
- this.close();
- } catch (IOException e2) {
- throw new java.lang.IllegalArgumentException(
- "Intermediate stream failed for Erlang object " + o);
- }
- } catch (final IOException e) {
- throw new java.lang.IllegalArgumentException(
- "Intermediate stream failed for Erlang object " + o);
- } finally {
- this.fixedSize = Integer.MAX_VALUE;
- try {
- dos.close();
- } catch (IOException e) {
- // ignore
+ public void write_compressed(final OtpErlangObject o, final int level) {
+ @SuppressWarnings("resource")
+ final OtpOutputStream oos = new OtpOutputStream(o);
+ /*
+ * similar to erts_term_to_binary() in external.c: We don't want to
+ * compress if compression actually increases the size. Since
+ * compression uses 5 extra bytes (COMPRESSED tag + size), don't
+ * compress if the original term is smaller.
+ */
+ if (oos.size() < 5) {
+ // fast path for small terms
+ try {
+ oos.writeToAndFlush(this);
+ // if the term is written as a compressed term, the output
+ // stream is closed, so we do this here, too
+ close();
+ } catch (final IOException e) {
+ throw new java.lang.IllegalArgumentException(
+ "Intermediate stream failed for Erlang object " + o);
+ }
+ } else {
+ final int startCount = super.count;
+ // we need destCount bytes for an uncompressed term
+ // -> if compression uses more, use the uncompressed term!
+ final int destCount = startCount + oos.size();
+ fixedSize = destCount;
+ final Deflater def = new Deflater(level);
+ final java.util.zip.DeflaterOutputStream dos = new java.util.zip.DeflaterOutputStream(
+ this, def);
+ try {
+ write1(OtpExternal.compressedTag);
+ write4BE(oos.size());
+ oos.writeTo(dos);
+ dos.close(); // note: closes this, too!
+ } catch (final IllegalArgumentException e) {
+ /*
+ * Discard further un-compressed data (if not called, there may
+ * be memory leaks).
+ *
+ * After calling java.util.zip.Deflater.end(), the deflater
+ * should not be used anymore, not even the close() method of
+ * dos. Calling dos.close() before def.end() is prevented since
+ * an unfinished DeflaterOutputStream will try to deflate its
+ * unprocessed data to the (fixed) byte array which is prevented
+ * by ensureCapacity() and would also unnecessarily process
+ * further data that is discarded anyway.
+ *
+ * Since we are re-using the byte array of this object below, we
+ * must not call close() in e.g. a finally block either (with or
+ * without a call to def.end()).
+ */
+ def.end();
+ // could not make the value smaller than originally
+ // -> reset to starting count, write uncompressed
+ super.count = startCount;
+ try {
+ oos.writeTo(this);
+ // if the term is written as a compressed term, the output
+ // stream is closed, so we do this here, too
+ close();
+ } catch (final IOException e2) {
+ throw new java.lang.IllegalArgumentException(
+ "Intermediate stream failed for Erlang object " + o);
+ }
+ } catch (final IOException e) {
+ throw new java.lang.IllegalArgumentException(
+ "Intermediate stream failed for Erlang object " + o);
+ } finally {
+ fixedSize = Integer.MAX_VALUE;
+ }
}
- }
- }
}
/**
* Write an arbitrary Erlang term to the stream.
- *
+ *
* @param o
* the Erlang term to write.
*/
public void write_any(final OtpErlangObject o) {
- // calls one of the above functions, depending on o
- o.encode(this);
+ // calls one of the above functions, depending on o
+ o.encode(this);
}
public void write_fun(final OtpErlangPid pid, final String module,
- final long old_index, final int arity, final byte[] md5,
- final long index, final long uniq, final OtpErlangObject[] freeVars) {
- if (arity == -1) {
- write1(OtpExternal.funTag);
- write4BE(freeVars.length);
- pid.encode(this);
- write_atom(module);
- write_long(index);
- write_long(uniq);
- for (final OtpErlangObject fv : freeVars) {
- fv.encode(this);
- }
- } else {
- write1(OtpExternal.newFunTag);
- final int saveSizePos = getPos();
- write4BE(0); // this is where we patch in the size
- write1(arity);
- writeN(md5);
- write4BE(index);
- write4BE(freeVars.length);
- write_atom(module);
- write_long(old_index);
- write_long(uniq);
- pid.encode(this);
- for (final OtpErlangObject fv : freeVars) {
- fv.encode(this);
- }
- poke4BE(saveSizePos, getPos() - saveSizePos);
- }
+ final long old_index, final int arity, final byte[] md5,
+ final long index, final long uniq, final OtpErlangObject[] freeVars) {
+ if (arity == -1) {
+ write1(OtpExternal.funTag);
+ write4BE(freeVars.length);
+ pid.encode(this);
+ write_atom(module);
+ write_long(index);
+ write_long(uniq);
+ for (final OtpErlangObject fv : freeVars) {
+ fv.encode(this);
+ }
+ } else {
+ write1(OtpExternal.newFunTag);
+ final int saveSizePos = getPos();
+ write4BE(0); // this is where we patch in the size
+ write1(arity);
+ writeN(md5);
+ write4BE(index);
+ write4BE(freeVars.length);
+ write_atom(module);
+ write_long(old_index);
+ write_long(uniq);
+ pid.encode(this);
+ for (final OtpErlangObject fv : freeVars) {
+ fv.encode(this);
+ }
+ poke4BE(saveSizePos, getPos() - saveSizePos);
+ }
}
public void write_external_fun(final String module, final String function,
- final int arity) {
- write1(OtpExternal.externalFunTag);
- write_atom(module);
- write_atom(function);
- write_long(arity);
+ final int arity) {
+ write1(OtpExternal.externalFunTag);
+ write_atom(module);
+ write_atom(function);
+ write_long(arity);
}
public void write_map_head(final int arity) {
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpPeer.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpPeer.java
index df5ce61820..1f06e2eb9f 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpPeer.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpPeer.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -28,59 +29,72 @@ import java.net.UnknownHostException;
*/
public class OtpPeer extends AbstractNode {
int distChoose = 0; /*
- * this is set by OtpConnection and is the highest
- * common protocol version we both support
- */
+ * this is set by OtpConnection and is the highest
+ * common protocol version we both support
+ */
- OtpPeer() {
- super();
+ OtpPeer(final OtpTransportFactory transportFactory) {
+ super(transportFactory);
}
/**
* Create a peer node.
- *
+ *
* @param node
- * the name of the node.
+ * the name of the node.
*/
public OtpPeer(final String node) {
- super(node);
+ super(node);
+ }
+
+ /**
+ * Create a peer node with custom transport factory.
+ *
+ * @param node
+ * the name of the node.
+ * @param transportFactory
+ * custom transport factory
+ */
+ public OtpPeer(final String node, final OtpTransportFactory
+ transportFactory) {
+ super(node, transportFactory);
}
/**
* Create a connection to a remote node.
- *
+ *
* @param self
- * the local node from which you wish to connect.
- *
+ * the local node from which you wish to connect.
+ *
* @return a connection to the remote node.
- *
+ *
* @exception java.net.UnknownHostException
- * if the remote host could not be found.
- *
+ * if the remote host could not be found.
+ *
* @exception java.io.IOException
- * if it was not possible to connect to the remote node.
- *
+ * if it was not possible to connect to the remote node.
+ *
* @exception OtpAuthException
- * if the connection was refused by the remote node.
- *
+ * if the connection was refused by the remote node.
+ *
* @deprecated Use the corresponding method in {@link OtpSelf} instead.
*/
@Deprecated
public OtpConnection connect(final OtpSelf self) throws IOException,
- UnknownHostException, OtpAuthException {
- return new OtpConnection(self, this);
+ UnknownHostException, OtpAuthException {
+ return new OtpConnection(self, this);
}
// package
/*
* Get the port number used by the remote node.
- *
+ *
* @return the port number used by the remote node, or 0 if the node was not
* registered with the port mapper.
- *
+ *
* @exception java.io.IOException if the port mapper could not be contacted.
*/
int port() throws IOException {
- return OtpEpmd.lookupPort(this);
+ return OtpEpmd.lookupPort(this);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSelf.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSelf.java
index 8e78cda894..03154aa785 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSelf.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSelf.java
@@ -1,54 +1,53 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
import java.net.UnknownHostException;
/**
* Represents an OTP node. It is used to connect to remote nodes or accept
* incoming connections from remote nodes.
- *
+ *
* <p>
* When the Java node will be connecting to a remote Erlang, Java or C node, it
* must first identify itself as a node by creating an instance of this class,
* after which it may connect to the remote node.
- *
+ *
* <p>
* When you create an instance of this class, it will bind a socket to a port so
* that incoming connections can be accepted. However the port number will not
* be made available to other nodes wishing to connect until you explicitely
* register with the port mapper daemon by calling {@link #publishPort()}.
* </p>
- *
+ *
* <pre>
* OtpSelf self = new OtpSelf(&quot;client&quot;, &quot;authcookie&quot;); // identify self
* OtpPeer other = new OtpPeer(&quot;server&quot;); // identify peer
- *
+ *
* OtpConnection conn = self.connect(other); // connect to peer
* </pre>
- *
+ *
*/
public class OtpSelf extends OtpLocalNode {
- private final ServerSocket sock;
+ private final OtpServerTransport sock;
private final OtpErlangPid pid;
/**
@@ -58,47 +57,154 @@ public class OtpSelf extends OtpLocalNode {
* directory. The home directory is obtained from the System property
* "user.home".
* </p>
- *
+ *
* <p>
* If the file does not exist, an empty string is used. This method makes no
* attempt to create the file.
* </p>
- *
+ *
* @param node
- * the name of this node.
- *
+ * the name of this node.
+ *
+ * @exception IOException
+ * in case of server transport failure
+ *
*/
public OtpSelf(final String node) throws IOException {
- this(node, defaultCookie, 0);
+ this(node, defaultCookie, 0);
+ }
+
+ /**
+ * <p>
+ * Create a self node using the default cookie and custom transport factory.
+ * The default cookie is found by reading the first line of the
+ * .erlang.cookie file in the user's home directory. The home directory is
+ * obtained from the System property "user.home".
+ * </p>
+ *
+ * <p>
+ * If the file does not exist, an empty string is used. This method makes no
+ * attempt to create the file.
+ * </p>
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param transportFactory
+ * the transport factory to use when creating connections.
+ *
+ * @exception IOException
+ * in case of server transport failure
+ *
+ */
+ public OtpSelf(final String node,
+ final OtpTransportFactory transportFactory) throws IOException {
+ this(node, defaultCookie, 0, transportFactory);
}
/**
* Create a self node.
- *
+ *
* @param node
- * the name of this node.
- *
+ * the name of this node.
+ *
* @param cookie
- * the authorization cookie that will be used by this node
- * when it communicates with other nodes.
+ * the authorization cookie that will be used by this node when
+ * it communicates with other nodes.
+ *
+ * @exception IOException
+ * in case of server transport failure
*/
public OtpSelf(final String node, final String cookie) throws IOException {
- this(node, cookie, 0);
+ this(node, cookie, 0);
+ }
+
+ /**
+ * Create a self node.
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param cookie
+ * the authorization cookie that will be used by this node when
+ * it communicates with other nodes.
+ *
+ * @param transportFactory
+ * the transport factory to use when creating connections.
+ *
+ * @exception IOException
+ * in case of server transport failure
+ */
+ public OtpSelf(final String node, final String cookie,
+ final OtpTransportFactory transportFactory) throws IOException {
+ this(node, cookie, 0, transportFactory);
}
+ /**
+ * Create a self node.
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param cookie
+ * the authorization cookie that will be used by this node when
+ * it communicates with other nodes.
+ *
+ * @param port
+ * the port number you wish to use for incoming connections.
+ * Specifying 0 lets the system choose an available port.
+ *
+ * @exception IOException
+ * in case of server transport failure
+ */
public OtpSelf(final String node, final String cookie, final int port)
- throws IOException {
- super(node, cookie);
+ throws IOException {
+ super(node, cookie);
- sock = new ServerSocket(port);
+ sock = createServerTransport(port);
- if (port != 0) {
- this.port = port;
- } else {
- this.port = sock.getLocalPort();
- }
+ if (port != 0) {
+ this.port = port;
+ } else {
+ this.port = sock.getLocalPort();
+ }
- pid = createPid();
+ pid = createPid();
+ }
+
+ /**
+ * Create a self node.
+ *
+ * @param node
+ * the name of this node.
+ *
+ * @param cookie
+ * the authorization cookie that will be used by this node when
+ * it communicates with other nodes.
+ *
+ * @param port
+ * the port number you wish to use for incoming connections.
+ * Specifying 0 lets the system choose an available port.
+ *
+ * @param transportFactory
+ * the transport factory to use when creating connections.
+ *
+ * @exception IOException
+ * in case of server transport failure
+ */
+ public OtpSelf(final String node, final String cookie, final int port,
+ final OtpTransportFactory transportFactory) throws IOException {
+ super(node, cookie, transportFactory);
+
+ sock = createServerTransport(port);
+
+ if (port != 0) {
+ this.port = port;
+ } else {
+ this.port = sock.getLocalPort();
+ }
+
+ pid = createPid();
}
/**
@@ -106,12 +212,12 @@ public class OtpSelf extends OtpLocalNode {
* messages sent by this node. Anonymous messages are those sent via send
* methods in {@link OtpConnection OtpConnection} that do not specify a
* sender.
- *
+ *
* @return the Erlang PID that will be used as the sender id in all
* anonymous messages sent by this node.
*/
public OtpErlangPid pid() {
- return pid;
+ return pid;
}
/**
@@ -119,31 +225,31 @@ public class OtpSelf extends OtpLocalNode {
* connect to this one. This method establishes a connection to the Erlang
* port mapper (Epmd) and registers the server node's name and port so that
* remote nodes are able to connect.
- *
+ *
* <p>
* This method will fail if an Epmd process is not running on the localhost.
* See the Erlang documentation for information about starting Epmd.
- *
+ *
* <p>
* Note that once this method has been called, the node is expected to be
* available to accept incoming connections. For that reason you should make
* sure that you call {@link #accept()} shortly after calling
* {@link #publishPort()}. When you no longer intend to accept connections
* you should call {@link #unPublishPort()}.
- *
+ *
* @return true if the operation was successful, false if the node was
* already registered.
- *
+ *
* @exception java.io.IOException
- * if the port mapper could not be contacted.
+ * if the port mapper could not be contacted.
*/
public boolean publishPort() throws IOException {
- if (getEpmd() != null) {
- return false; // already published
- }
+ if (getEpmd() != null) {
+ return false; // already published
+ }
- OtpEpmd.publishPort(this);
- return getEpmd() != null;
+ OtpEpmd.publishPort(this);
+ return getEpmd() != null;
}
/**
@@ -151,71 +257,71 @@ public class OtpSelf extends OtpLocalNode {
* mapper, thus preventing any new connections from remote nodes.
*/
public void unPublishPort() {
- // unregister with epmd
- OtpEpmd.unPublishPort(this);
-
- // close the local descriptor (if we have one)
- try {
- if (super.epmd != null) {
- super.epmd.close();
- }
- } catch (final IOException e) {/* ignore close errors */
- }
- super.epmd = null;
+ // unregister with epmd
+ OtpEpmd.unPublishPort(this);
+
+ // close the local descriptor (if we have one)
+ try {
+ if (super.epmd != null) {
+ super.epmd.close();
+ }
+ } catch (final IOException e) {/* ignore close errors */
+ }
+ super.epmd = null;
}
/**
* Accept an incoming connection from a remote node. A call to this method
* will block until an incoming connection is at least attempted.
- *
+ *
* @return a connection to a remote node.
- *
+ *
* @exception java.io.IOException
- * if a remote node attempted to connect but no common
- * protocol was found.
- *
+ * if a remote node attempted to connect but no common
+ * protocol was found.
+ *
* @exception OtpAuthException
- * if a remote node attempted to connect, but was not
- * authorized to connect.
+ * if a remote node attempted to connect, but was not
+ * authorized to connect.
*/
public OtpConnection accept() throws IOException, OtpAuthException {
- Socket newsock = null;
-
- while (true) {
- try {
- newsock = sock.accept();
- return new OtpConnection(this, newsock);
- } catch (final IOException e) {
- try {
- if (newsock != null) {
- newsock.close();
- }
- } catch (final IOException f) {/* ignore close errors */
- }
- throw e;
- }
- }
+ OtpTransport newsock = null;
+
+ while (true) {
+ try {
+ newsock = sock.accept();
+ return new OtpConnection(this, newsock);
+ } catch (final IOException e) {
+ try {
+ if (newsock != null) {
+ newsock.close();
+ }
+ } catch (final IOException f) {/* ignore close errors */
+ }
+ throw e;
+ }
+ }
}
/**
* Open a connection to a remote node.
- *
+ *
* @param other
- * the remote node to which you wish to connect.
- *
+ * the remote node to which you wish to connect.
+ *
* @return a connection to the remote node.
- *
+ *
* @exception java.net.UnknownHostException
- * if the remote host could not be found.
- *
+ * if the remote host could not be found.
+ *
* @exception java.io.IOException
- * if it was not possible to connect to the remote node.
- *
+ * if it was not possible to connect to the remote node.
+ *
* @exception OtpAuthException
- * if the connection was refused by the remote node.
+ * if the connection was refused by the remote node.
*/
public OtpConnection connect(final OtpPeer other) throws IOException,
- UnknownHostException, OtpAuthException {
- return new OtpConnection(this, other);
+ UnknownHostException, OtpAuthException {
+ return new OtpConnection(this, other);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServer.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServer.java
index 0de399ac61..d4831b948d 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServer.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServer.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -23,88 +24,89 @@ import java.io.IOException;
/**
* Represents a local OTP client or server node. It is used when you want other
* nodes to be able to establish connections to this one.
- *
+ *
* When you create an instance of this class, it will bind a socket to a port so
* that incoming connections can be accepted. However the port number will not
* be made available to other nodes wishing to connect until you explicitely
* register with the port mapper daemon by calling {@link #publishPort()}.
- *
+ *
* <p>
* When the Java node will be connecting to a remote Erlang, Java or C node, it
* must first identify itself as a node by creating an instance of this class,
* after which it may connect to the remote node.
- *
+ *
* <p>
* Setting up a connection may be done as follows:
- *
- *
+ *
+ *
* <pre>
* OtpServer self = new OtpServer(&quot;server&quot;, &quot;cookie&quot;); // identify self
* self.publishPort(); // make port information available
- *
+ *
* OtpConnection conn = self.accept(); // get incoming connection
* </pre>
- *
+ *
* @see OtpSelf
- *
- * @deprecated the functionality of this class has been moved to {@link OtpSelf}.
+ *
+ * @deprecated the functionality of this class has been moved to {@link OtpSelf}
+ * .
*/
@Deprecated
public class OtpServer extends OtpSelf {
/**
* Create an {@link OtpServer} from an existing {@link OtpSelf}.
- *
+ *
* @param self
- * an existing self node.
- *
+ * an existing self node.
+ *
* @exception java.io.IOException
- * if a ServerSocket could not be created.
- *
+ * if a ServerSocket could not be created.
+ *
*/
public OtpServer(final OtpSelf self) throws IOException {
- super(self.node(), self.cookie());
+ super(self.node(), self.cookie());
}
/**
* Create an OtpServer, using a vacant port chosen by the operating system.
* To determine what port was chosen, call the object's {@link #port()}
* method.
- *
+ *
* @param node
- * the name of the node.
- *
+ * the name of the node.
+ *
* @param cookie
- * the authorization cookie that will be used by this node
- * when accepts connections from remote nodes.
- *
+ * the authorization cookie that will be used by this node when
+ * accepts connections from remote nodes.
+ *
* @exception java.io.IOException
- * if a ServerSocket could not be created.
- *
+ * if a ServerSocket could not be created.
+ *
*/
public OtpServer(final String node, final String cookie) throws IOException {
- super(node, cookie);
+ super(node, cookie);
}
/**
* Create an OtpServer, using the specified port number.
- *
+ *
* @param node
- * a name for this node, as above.
- *
+ * a name for this node, as above.
+ *
* @param cookie
- * the authorization cookie that will be used by this node
- * when accepts connections from remote nodes.
- *
+ * the authorization cookie that will be used by this node when
+ * accepts connections from remote nodes.
+ *
* @param port
- * the port number to bind the socket to.
- *
+ * the port number to bind the socket to.
+ *
* @exception java.io.IOException
- * if a ServerSocket could not be created or if the
- * chosen port number was not available.
- *
+ * if a ServerSocket could not be created or if the chosen
+ * port number was not available.
+ *
*/
public OtpServer(final String node, final String cookie, final int port)
- throws IOException {
- super(node, cookie, port);
+ throws IOException {
+ super(node, cookie, port);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerSocketTransport.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerSocketTransport.java
new file mode 100644
index 0000000000..93c0dbbb9b
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerSocketTransport.java
@@ -0,0 +1,69 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+package com.ericsson.otp.erlang;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * Default socket-based server transport
+ *
+ * @author Dmitriy Kargapolov
+ */
+public class OtpServerSocketTransport implements OtpServerTransport {
+
+ /**
+ * Underlying server socket
+ */
+ private final ServerSocket socket;
+
+ /**
+ * @see ServerSocket#ServerSocket(int)
+ */
+ public OtpServerSocketTransport(final int port) throws IOException {
+ socket = new ServerSocket(port);
+ }
+
+ /**
+ * @see ServerSocket#getLocalPort()
+ */
+ public int getLocalPort() {
+ return socket.getLocalPort();
+ }
+
+ /**
+ * @see ServerSocket#accept()
+ */
+ public OtpTransport accept() throws IOException {
+ final Socket sock = socket.accept();
+ sock.setTcpNoDelay(true);
+ return new OtpSocketTransport(sock);
+ }
+
+ /**
+ * @see ServerSocket#close()
+ */
+ public void close() throws IOException {
+ socket.close();
+ }
+
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerTransport.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerTransport.java
new file mode 100644
index 0000000000..f2f5312354
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpServerTransport.java
@@ -0,0 +1,47 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+package com.ericsson.otp.erlang;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+/**
+ * Server-side connection-oriented transport interface.
+ *
+ * @author Dmitriy Kargapolov
+ */
+public interface OtpServerTransport {
+
+ /**
+ * @see ServerSocket#getLocalPort()
+ */
+ int getLocalPort();
+
+ /**
+ * @see ServerSocket#accept()
+ */
+ OtpTransport accept() throws IOException;
+
+ /**
+ * @see ServerSocket#close()
+ */
+ void close() throws IOException;
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransport.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransport.java
new file mode 100644
index 0000000000..95be473e3e
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransport.java
@@ -0,0 +1,90 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+package com.ericsson.otp.erlang;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * Default socket-based client transport
+ *
+ * @author Dmitriy Kargapolov
+ */
+public class OtpSocketTransport implements OtpTransport {
+
+ /**
+ * Underlying socket
+ */
+ private final Socket socket;
+
+ /**
+ * @see Socket#Socket(String, int)
+ */
+ public OtpSocketTransport(final String addr, final int port)
+ throws UnknownHostException, IOException {
+ socket = new Socket(addr, port);
+ socket.setTcpNoDelay(true);
+ }
+
+ /**
+ * @see Socket#Socket(InetAddress, int)
+ */
+ public OtpSocketTransport(final InetAddress addr, final int port)
+ throws UnknownHostException, IOException {
+ socket = new Socket(addr, port);
+ socket.setTcpNoDelay(true);
+ }
+
+ /**
+ * Socket wrapping constructor
+ *
+ * @param s
+ * socket to wrap
+ */
+ public OtpSocketTransport(final Socket s) {
+ socket = s;
+ }
+
+ /**
+ * @see Socket#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ return socket.getInputStream();
+ }
+
+ /**
+ * @see Socket#getOutputStream()
+ */
+ public OutputStream getOutputStream() throws IOException {
+ return socket.getOutputStream();
+ }
+
+ /**
+ * @see Socket#close()
+ */
+ public void close() throws IOException {
+ socket.close();
+ }
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransportFactory.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransportFactory.java
new file mode 100644
index 0000000000..60ee234d0b
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSocketTransportFactory.java
@@ -0,0 +1,57 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+package com.ericsson.otp.erlang;
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+/**
+ * Default socket-based transport factory
+ *
+ * @author Dmitriy Kargapolov
+ */
+public class OtpSocketTransportFactory implements OtpTransportFactory {
+
+ /**
+ * @see OtpTransportFactory#createTransport(String, int)
+ */
+ public OtpTransport createTransport(final String addr, final int port)
+ throws IOException {
+ return new OtpSocketTransport(addr, port);
+ }
+
+ /**
+ * @see OtpTransportFactory#createTransport(InetAddress, int)
+ */
+ public OtpTransport createTransport(final InetAddress addr, final int port)
+ throws IOException {
+ return new OtpSocketTransport(addr, port);
+ }
+
+ /**
+ * @see OtpTransportFactory#createServerTransport(int)
+ */
+ public OtpServerTransport createServerTransport(final int port)
+ throws IOException {
+ return new OtpServerSocketTransport(port);
+ }
+
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSystem.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSystem.java
index 969da39d70..0ff38d7026 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSystem.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpSystem.java
@@ -1,19 +1,20 @@
/*
* %CopyrightBegin%
- *
+ *
* Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
+ *
+ * Licensed under the Apache License, Version 2.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%
*/
package com.ericsson.otp.erlang;
@@ -24,27 +25,27 @@ final class OtpSystem {
static {
- final String rel = System.getProperty("OtpCompatRel", "0");
-
- try {
-
- switch (Integer.parseInt(rel)) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 0:
- default:
- break;
- }
- } catch (final NumberFormatException e) {
- /* Ignore ... */
- }
+ final String rel = System.getProperty("OtpCompatRel", "0");
+
+ try {
+
+ switch (Integer.parseInt(rel)) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 0:
+ default:
+ break;
+ }
+ } catch (final NumberFormatException e) {
+ /* Ignore ... */
+ }
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransport.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransport.java
new file mode 100644
index 0000000000..616db87c92
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransport.java
@@ -0,0 +1,50 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+package com.ericsson.otp.erlang;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * Client-side connection-oriented transport interface.
+ *
+ * @author Dmitriy Kargapolov
+ */
+public interface OtpTransport {
+
+ /**
+ * @see Socket#getInputStream()
+ */
+ public abstract InputStream getInputStream() throws IOException;
+
+ /**
+ * @see Socket#getOutputStream()
+ */
+ public abstract OutputStream getOutputStream() throws IOException;
+
+ /**
+ * @see Socket#close()
+ */
+ public abstract void close() throws IOException;
+
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransportFactory.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransportFactory.java
new file mode 100644
index 0000000000..857d3ee764
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpTransportFactory.java
@@ -0,0 +1,125 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+package com.ericsson.otp.erlang;
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+/**
+ * Factory class used to create client- and server-side transport instances. One
+ * static instance of class implementing this interface is created when program
+ * loaded. Default implementation used is {@link OtpSocketTransportFactory}.
+ * JInterface user can specify custom transport factory implementing this
+ * interface in the following ways:
+ * <dl>
+ * <dt>defining static class as internal to class holding main() method</dt>
+ * <dd>In the systems, where main class can be retrieved with
+ * <code>System.getProperty("sun.java.command")</code>, user can define static
+ * class <b>OtpErlangSystemTuner</b> internal to the main class, providing at
+ * least one static method with the name <b>getOtpTransportFactory</b>, with no
+ * parameters, returning object of class implementing
+ * <b>OtpTransportFactory</b>, for example:
+ *
+ * <pre>
+ *
+ * public class MyMainClass {
+ *
+ * public static class OtpErlangSystemTuner {
+ * ...
+ * public static OtpTransportFactory getOtpTransportFactory() {
+ * return new MyTransportFactory();
+ * }
+ * }
+ *
+ * public static class MyTransportFactory implements OtpTransportFactory {
+ * ...
+ * }
+ *
+ * public static void main(String[] args) {
+ * ...
+ * }
+ * }
+ *
+ *
+ * </pre>
+ *
+ * </dd>
+ *
+ * <dt>specifying factory class in the system properties</dt>
+ * <dd>User-defined transport factory class may be specified via system property
+ * <b>OtpTransportFactory</b>, for example:
+ *
+ * <pre>
+ *
+ * package com.my.company;
+ *
+ * public static class MyTransportFactory implements OtpTransportFactory {
+ * ...
+ * }
+ * </pre>
+ *
+ * In such case program may be run with
+ * -DOtpTransportFactory=com.my.company.MyTransportFactory, or other way of
+ * setting system property <i>before execution of static initializers</i> may be
+ * used.</dd>
+ * </dl>
+ *
+ * @author Dmitriy Kargapolov
+ */
+public interface OtpTransportFactory {
+
+ /**
+ * Create instance of {@link OtpTransport}
+ *
+ * @param addr
+ * host name or IP address string
+ * @param port
+ * port number
+ * @return new socket object
+ * @throws IOException
+ */
+ public abstract OtpTransport createTransport(String addr, int port)
+ throws IOException;
+
+ /**
+ * Create instance of {@link OtpTransport}
+ *
+ * @param addr
+ * peer address
+ * @param port
+ * port number
+ * @return new socket object
+ * @throws IOException
+ */
+ public abstract OtpTransport createTransport(InetAddress addr, int port)
+ throws IOException;
+
+ /**
+ * Create instance of {@link OtpServerTransport}
+ *
+ * @param port
+ * port number to listen on
+ * @return new socket object
+ * @throws IOException
+ */
+ public OtpServerTransport createServerTransport(int port)
+ throws IOException;
+}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/java_files b/lib/jinterface/java_src/com/ericsson/otp/erlang/java_files
index 62fa7f990e..a039a75f34 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/java_files
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/java_files
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -53,7 +54,13 @@ COMM = \
OtpOutputStream \
OtpPeer \
OtpSelf \
- OtpServer
+ OtpServer \
+ OtpServerSocketTransport \
+ OtpServerTransport \
+ OtpSocketTransport \
+ OtpSocketTransportFactory \
+ OtpTransport \
+ OtpTransportFactory
ERL = \
OtpErlangAtom \
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src
index d25d9bc142..bc8b99f2a1 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src
index d267e3d3d5..eee7be1540 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%", [], []}.
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/package.html b/lib/jinterface/java_src/com/ericsson/otp/erlang/package.html
index 039a8778f2..70af29c041 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/package.html
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/package.html
@@ -5,16 +5,17 @@
Copyright Ericsson AB 2000-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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%
-->
diff --git a/lib/jinterface/priv/.gitignore b/lib/jinterface/priv/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/jinterface/priv/.gitignore
+++ /dev/null
diff --git a/lib/jinterface/test/.classpath b/lib/jinterface/test/.classpath
new file mode 100644
index 0000000000..2e4a3e6776
--- /dev/null
+++ b/lib/jinterface/test/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="jinterface_SUITE_data" path="jinterface_SUITE_data"/>
+ <classpathentry kind="src" output="nc_SUITE_data" path="nc_SUITE_data"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/jinterface"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/lib/jinterface/test/.project b/lib/jinterface/test/.project
new file mode 100644
index 0000000000..4144c6ebea
--- /dev/null
+++ b/lib/jinterface/test/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>jinterface_tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/lib/jinterface/test/.settings/org.eclipse.jdt.core.prefs b/lib/jinterface/test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..af0f20f97a
--- /dev/null
+++ b/lib/jinterface/test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/lib/jinterface/test/Makefile b/lib/jinterface/test/Makefile
index 90d4e01035..40abcd18a0 100644
--- a/lib/jinterface/test/Makefile
+++ b/lib/jinterface/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/jinterface/test/jinterface.spec b/lib/jinterface/test/jinterface.spec
index 99bc0f4005..b0d0fa9d8d 100644
--- a/lib/jinterface/test/jinterface.spec
+++ b/lib/jinterface/test/jinterface.spec
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/jinterface/test/jinterface_SUITE.erl b/lib/jinterface/test/jinterface_SUITE.erl
index 00abc97ff5..6d34a21209 100644
--- a/lib/jinterface/test/jinterface_SUITE.erl
+++ b/lib/jinterface/test/jinterface_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,7 +23,8 @@
init_per_suite/1, end_per_suite/1,
init_per_testcase/2, end_per_testcase/2]).
--export([nodename/1, register_and_whereis/1, get_names/1, boolean_atom/1,
+-export([transport_factory/1,
+ nodename/1, register_and_whereis/1, get_names/1, boolean_atom/1,
node_ping/1, mbox_ping/1,
java_erlang_send_receive/1,
java_internal_send_receive_same_node/1,
@@ -39,7 +41,8 @@
status_handler_localStatus/1, status_handler_remoteStatus/1,
status_handler_connAttempt/1,
maps/1,
- fun_equals/1
+ fun_equals/1,
+ core_match_bind/1
]).
-include_lib("common_test/include/ct.hrl").
@@ -103,12 +106,14 @@ end_per_group(_GroupName, Config) ->
fundamental() ->
[
+ transport_factory, % TransportFactoryTest.java
nodename, % Nodename.java
register_and_whereis, % RegisterAndWhereis.java
get_names, % GetNames.java
boolean_atom, % BooleanAtom.java
maps, % Maps.java
- fun_equals % FunEquals.java
+ fun_equals, % FunEquals.java
+ core_match_bind % CoreMatchBind.java
].
ping() ->
@@ -201,6 +206,16 @@ end_per_testcase(_Case,Config) ->
%%%-----------------------------------------------------------------
%%% TEST CASES
%%%-----------------------------------------------------------------
+transport_factory(doc) ->
+ ["TransportFactoryTest.java: Test custom OTP Transport Factory"];
+transport_factory(suite) ->
+ [];
+transport_factory(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "TransportFactoryTest").
+
+%%%-----------------------------------------------------------------
nodename(doc) ->
["Nodename.java: "
"Test OtpNode.node(), OtpNode.alive() and OtpNode.host()"];
@@ -705,6 +720,18 @@ fun_equals(Config) when is_list(Config) ->
[]).
%%%-----------------------------------------------------------------
+core_match_bind(doc) ->
+ ["CoreMatchBind.java: "
+ "Test OtpErlangObject.match() and bind()"];
+core_match_bind(suite) ->
+ [];
+core_match_bind(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "CoreMatchBind",
+ []).
+
+%%%-----------------------------------------------------------------
%%% INTERNAL FUNCTIONS
%%%-----------------------------------------------------------------
send_receive(TestCaseTag,Fun,Config) ->
diff --git a/lib/jinterface/test/jinterface_SUITE_data/.gitignore b/lib/jinterface/test/jinterface_SUITE_data/.gitignore
new file mode 100644
index 0000000000..6b468b62a9
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/.gitignore
@@ -0,0 +1 @@
+*.class
diff --git a/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java b/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java
index 9554d50c9f..0d482f3fd2 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/CoreMatchBind.java b/lib/jinterface/test/jinterface_SUITE_data/CoreMatchBind.java
new file mode 100644
index 0000000000..56b723e4fe
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/CoreMatchBind.java
@@ -0,0 +1,585 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-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.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.OtpErlangException;
+import com.ericsson.otp.erlang.OtpErlangInt;
+import com.ericsson.otp.erlang.OtpErlangList;
+import com.ericsson.otp.erlang.OtpErlangMap;
+import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangTuple;
+import com.ericsson.otp.erlang.OtpOutputStream;
+
+public class CoreMatchBind {
+
+ @SuppressWarnings("serial")
+ private static class DumbObject extends OtpErlangObject {
+
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName();
+ }
+
+ @Override
+ public void encode(final OtpOutputStream buf) {
+ fail("unexpected encode() call");
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ fail("unexpected equals() call");
+ return false;
+ }
+
+ }
+
+ @SuppressWarnings("serial")
+ private static class BoundObject extends OtpErlangObject {
+
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName();
+ }
+
+ @Override
+ public void encode(final OtpOutputStream buf) {
+ fail("unexpected encode() call");
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ fail("unexpected equals() call");
+ return false;
+ }
+
+ }
+
+ @SuppressWarnings("serial")
+ private static class TestObject extends OtpErlangObject {
+
+ private final Binder binder;
+ private DumbObject dumb;
+ private boolean flag;
+ private BoundObject obj;
+
+ public TestObject(final boolean flag, final Binder binder,
+ final DumbObject dumb) {
+ this.flag = flag;
+ this.binder = binder;
+ this.dumb = dumb;
+ }
+
+ public TestObject(final Binder binder, final BoundObject obj) {
+ this.binder = binder;
+ this.obj = obj;
+ }
+
+ public DumbObject getDumb() {
+ return dumb;
+ }
+
+ @Override
+ public String toString() {
+ return flag ? "T" : "F";
+ }
+
+ @Override
+ public void encode(final OtpOutputStream buf) {
+ fail("unexpected encode() call");
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (obj == null) {
+ fail("unexpected equals() call");
+ }
+ return o == obj;
+ }
+
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T binds) {
+ if (binds != binder) {
+ fail("invalid binder");
+ }
+ if (term != dumb) {
+ fail("invalid object");
+ }
+ return flag;
+ }
+
+ @Override
+ public <T> OtpErlangObject bind(final T binds)
+ throws OtpErlangException {
+ if (binds != binder) {
+ fail("invalid binder");
+ }
+ return obj;
+ }
+
+ }
+
+ /*
+ * "always matched" object
+ */
+ @SuppressWarnings("serial")
+ private static class Any extends OtpErlangObject {
+
+ @Override
+ public String toString() {
+ return "any";
+ }
+
+ @Override
+ public void encode(final OtpOutputStream buf) {
+ fail("unexpected encode() call");
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ fail("unexpected equals() call");
+ return false;
+ }
+
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T binds) {
+ return true;
+ }
+ }
+
+ private static class Binder {
+ // make object pair for match() testing
+ TestObject makeTest(final boolean flag) {
+ return new TestObject(flag, this, new DumbObject());
+ }
+
+ // make object pair for bind() testing
+ TestObject makeTest() {
+ return new TestObject(this, new BoundObject());
+ }
+ }
+
+ private static void isNotNull(final Object o) throws Exception {
+ if (o == null) {
+ throw new Exception("not null expected");
+ }
+ }
+
+ private static void fail(final String string) {
+ System.err.println(string);
+ new Throwable().printStackTrace(System.err);
+ System.exit(1);
+ }
+
+ private static void isT(final boolean b) throws Exception {
+ if (!b) {
+ throw new Exception("true expected");
+ }
+ }
+
+ private static void isF(final boolean b) throws Exception {
+ if (b) {
+ throw new Exception("false expected");
+ }
+ }
+
+ private static void equals(final OtpErlangObject a, final OtpErlangObject b)
+ throws Exception {
+ if (!a.equals(b)) {
+ throw new Exception(a + " != " + b);
+ }
+ }
+
+ /*
+ * scalar match test - match particular test object (producing given result)
+ * against particular dumb object passing particular bindings object; ensure
+ * all participants are used as expected in match behavior, check result.
+ */
+ private static void scalar_match_test() throws Exception {
+ final Binder bind = new Binder();
+
+ final TestObject t = bind.makeTest(true);
+ isT(t.match(t.getDumb(), bind));
+
+ final TestObject f = bind.makeTest(false);
+ isF(f.match(f.getDumb(), bind));
+ }
+
+ /*
+ * scalar bind test - ensure right object generated based on bindings
+ */
+ private static void scalar_bind_test() throws Exception {
+ final Binder bind = new Binder();
+ final TestObject t = bind.makeTest();
+ final OtpErlangObject o = t.bind(bind);
+ isNotNull(o);
+ equals(t, o);
+ }
+
+ /*
+ * used by tuple_arity_match_test()
+ */
+ private static OtpErlangObject mkTuplePattern(final int n) {
+ final Any a[] = new Any[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = new Any();
+ }
+ return new OtpErlangTuple(a);
+ }
+
+ /*
+ * used by tuple_arity_match_test()
+ */
+ private static OtpErlangObject mkTupleObject(final int n) {
+ final DumbObject a[] = new DumbObject[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = new DumbObject();
+ }
+ return new OtpErlangTuple(a);
+ }
+
+ /*
+ * ensure only tuples of the same arity can match
+ */
+ private static void tuple_arity_match_test(final int m, final int n)
+ throws Exception {
+ final Binder bind = new Binder();
+ for (int i = m; i < n; i++) {
+ for (int j = m; j < n; j++) {
+ final OtpErlangObject p = mkTuplePattern(i);
+ final OtpErlangObject o = mkTupleObject(j);
+ if (i == j) {
+ isT(p.match(o, bind));
+ } else {
+ isF(p.match(o, bind));
+ }
+ }
+ }
+ }
+
+ /*
+ * tuple match test - ensure elements of tuple are matched to corresponding
+ * elements of tested object and result is logical "and" over all elements.
+ */
+ private static void tuple_match_test(final int n) throws Exception {
+ final Binder bind = new Binder();
+ final int max = 1 << n;
+ final TestObject a[] = new TestObject[n];
+ final DumbObject d[] = new DumbObject[n];
+ for (int k = 0; k < max; k++) {
+ for (int m = 1, i = 0; m < max; m = m << 1, i++) {
+ d[i] = new DumbObject();
+ a[i] = new TestObject((k & m) != 0, bind, d[i]);
+ }
+ final OtpErlangObject tpl = new OtpErlangTuple(a);
+ final OtpErlangObject obj = new OtpErlangTuple(d);
+ if (k + 1 < max) {
+ isF(tpl.match(obj, bind));
+ } else {
+ isT(tpl.match(obj, bind));
+ }
+ }
+ }
+
+ /*
+ * tuple bind test - ensure result is a tuple where each element is a result
+ * of binding of corresponding pattern element using provided bindings.
+ */
+ private static void tuple_bind_test(final int n) throws Exception {
+ final Binder bind = new Binder();
+ final TestObject a[] = new TestObject[n];
+ final OtpErlangObject b[] = new OtpErlangObject[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = bind.makeTest();
+ b[i] = a[i].obj;
+ }
+ final OtpErlangObject t = new OtpErlangTuple(a);
+ final OtpErlangObject o = t.bind(bind);
+ isNotNull(o);
+ equals(t, o);
+ }
+
+ private static OtpErlangObject mkListPattern(final int n, final boolean tail)
+ throws OtpErlangException {
+ final Any a[] = new Any[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = new Any();
+ }
+ return tail ? new OtpErlangList(a, new Any()) : new OtpErlangList(a);
+ }
+
+ private static OtpErlangObject mkListObject(final int n, final boolean tail)
+ throws OtpErlangException {
+ final DumbObject a[] = new DumbObject[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = new DumbObject();
+ }
+ return tail ? new OtpErlangList(a, new DumbObject())
+ : new OtpErlangList(a);
+ }
+
+ /*
+ * ensure only lists of the same arity and same tail presence can match
+ */
+ private static void list_arity_match_test(final int m, final int n)
+ throws Exception {
+ final Binder bind = new Binder();
+ for (int i = m; i < n; i++) {
+ for (int j = m; j < n; j++) {
+ for (int k = 0; k < 2; k++) {
+ if (i == 0 && k == 1) {
+ continue;
+ }
+ for (int l = 0; l < 2; l++) {
+ if (j == 0 && l == 1) {
+ continue;
+ }
+ final OtpErlangObject p = mkListPattern(i, k == 1);
+ final OtpErlangObject o = mkListObject(j, l == 1);
+ if (i == j && k == l || k == 1 && i <= j) {
+ isT(p.match(o, bind));
+ } else {
+ isF(p.match(o, bind));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * lists match test - ensure elements of lists are matched to corresponding
+ * elements of tested object and result is logical "and" over all elements,
+ * count tails as well
+ */
+ private static void list_match_test(final int n) throws Exception {
+ final Binder bind = new Binder();
+ final int max = 1 << n;
+ final TestObject a[] = new TestObject[n];
+ final DumbObject d[] = new DumbObject[n];
+ final DumbObject e[] = new DumbObject[n + 1];
+ for (int k = 0; k < max; k++) {
+ for (int m = 1, i = 0; m < max; m = m << 1, i++) {
+ d[i] = new DumbObject();
+ e[i] = d[i];
+ a[i] = new TestObject((k & m) != 0, bind, d[i]);
+ }
+ for (int i = n; i < n + 1; i++) {
+ e[i] = new DumbObject();
+ }
+ final OtpErlangObject lst = new OtpErlangList(a);
+ final OtpErlangObject obj = new OtpErlangList(d);
+ final OtpErlangObject ext = new OtpErlangList(e);
+ final OtpErlangObject eTl = new OtpErlangList(e, new DumbObject());
+
+ if (n > 0) {
+ final DumbObject dTail = new DumbObject();
+ final TestObject tTail = new TestObject(true, bind, dTail);
+ final TestObject fTail = new TestObject(false, bind, dTail);
+ final OtpErlangObject fTailLst = new OtpErlangList(a, fTail);
+ final OtpErlangObject tTailLst = new OtpErlangList(a, tTail);
+ final OtpErlangObject tailObj = new OtpErlangList(d, dTail);
+
+ // match lists with non-matching tails is always false
+ isF(fTailLst.match(tailObj, bind));
+
+ // match list with no tail to list with tail is always false
+ isF(lst.match(tailObj, bind));
+
+ // matching lists with matching tails
+ if (k + 1 < max) {
+ isF(tTailLst.match(tailObj, bind));
+ } else {
+ isT(tTailLst.match(tailObj, bind));
+ }
+
+ // matching shorter pattern with last tail to longer list
+ // with or with no extra tail; matching list pattern
+ // with last tail to same length list with no tail.
+ final Any aTail = new Any();
+ final OtpErlangObject shortLst = new OtpErlangList(a, aTail);
+ if (k + 1 < max) {
+ isF(shortLst.match(obj, bind)); // same arity
+ isF(shortLst.match(ext, bind)); // pattern arity is less
+ isF(shortLst.match(eTl, bind)); //
+ } else {
+ isT(shortLst.match(obj, bind)); // same arity
+ isT(shortLst.match(ext, bind)); // pattern arity is less
+ isT(shortLst.match(eTl, bind)); //
+ }
+ }
+
+ // matching lists with no tails
+ if (k + 1 < max) {
+ isF(lst.match(obj, bind));
+ } else {
+ isT(lst.match(obj, bind));
+ }
+
+ // extra-length object, no tail in "pattern"
+ isF(lst.match(ext, bind));
+ }
+ }
+
+ /*
+ * list bind test - ensure result is a list where each element is a result
+ * of binding of corresponding pattern element using provided bindings.
+ */
+ private static void list_bind_test(final int n) throws Exception {
+ final Binder bind = new Binder();
+ final TestObject a[] = new TestObject[n];
+ final OtpErlangObject b[] = new OtpErlangObject[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = bind.makeTest();
+ b[i] = a[i].obj;
+ }
+ OtpErlangObject t = new OtpErlangList(a);
+ OtpErlangObject o = t.bind(bind);
+ isNotNull(o);
+ equals(t, o);
+ if (n > 0) {
+ // improper list case
+ t = new OtpErlangList(a, bind.makeTest());
+ o = t.bind(bind);
+ isNotNull(o);
+ equals(t, o);
+ }
+ }
+
+ /*
+ * map match test - object may have more keys than pattern
+ */
+ private static void map_match_test(final int m, final int n)
+ throws Exception {
+ final Binder bind = new Binder();
+
+ // pattern side - m elements
+ final OtpErlangObject k1[] = new OtpErlangObject[m];
+ final TestObject a[] = new TestObject[m];
+
+ // object side - n elements
+ final OtpErlangObject k2[] = new OtpErlangObject[n];
+ final DumbObject d[] = new DumbObject[n];
+
+ final int max = Math.max(m, n);
+ final int mskHi = 1 << max;
+ final int full = (1 << m) - 1;
+ for (int k = 0; k < mskHi; k++) {
+ for (int msk = 1, i = 0; msk < mskHi; msk = msk << 1, i++) {
+ if (i < n) {
+ k2[i] = new OtpErlangInt(i);
+ d[i] = new DumbObject();
+ }
+ if (i < m) {
+ k1[i] = new OtpErlangInt(i);
+ a[i] = new TestObject((k & msk) != 0, bind, i < n ? d[i]
+ : new DumbObject());
+ }
+ }
+ final OtpErlangObject map = new OtpErlangMap(k1, a); // m items
+ final OtpErlangObject obj = new OtpErlangMap(k2, d); // n items
+ if ((k & full) == full && m <= n) {
+ isT(map.match(obj, bind));
+ } else {
+ isF(map.match(obj, bind));
+ }
+ }
+ }
+
+ /*
+ * map bind test - ensure result is a map where each element is a result of
+ * binding of corresponding pattern element using provided bindings.
+ */
+ private static void map_bind_test(final int n) throws Exception {
+ final Binder bind = new Binder();
+ final TestObject a[] = new TestObject[n];
+ final OtpErlangObject b[] = new OtpErlangObject[n];
+ final OtpErlangObject k[] = new OtpErlangObject[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = bind.makeTest();
+ b[i] = a[i].obj;
+ k[i] = new OtpErlangInt(i);
+ }
+ final OtpErlangObject t = new OtpErlangMap(k, a);
+ final OtpErlangObject o = t.bind(bind);
+ isNotNull(o);
+ equals(t, o);
+ }
+
+ public static void main(final String[] args) {
+ try {
+ scalar_match_test();
+ System.out.println("scalar_match_test() passed");
+
+ scalar_bind_test();
+ System.out.println("scalar_bind_test() passed");
+
+ for (int m = 0; m < 16; m++) {
+ for (int n = 0; n < 16; n++) {
+ tuple_arity_match_test(m, n);
+ }
+ }
+ System.out.println("tuple_arity_match_test() passed");
+
+ for (int n = 0; n < 16; n++) {
+ tuple_match_test(n);
+ }
+ System.out.println("tuple_match_test() passed");
+
+ for (int n = 0; n < 16; n++) {
+ tuple_bind_test(n);
+ }
+ System.out.println("tuple_bind_test() passed");
+
+ for (int m = 0; m < 16; m++) {
+ for (int n = 0; n < 16; n++) {
+ list_arity_match_test(m, n);
+ }
+ }
+ System.out.println("list_arity_match_test() passed");
+
+ for (int n = 0; n < 16; n++) {
+ list_match_test(n);
+ }
+ System.out.println("list_match_test() passed");
+
+ for (int n = 0; n < 16; n++) {
+ list_bind_test(n);
+ }
+ System.out.println("list_bind_test() passed");
+
+ for (int m = 0; m < 12; m++) {
+ for (int n = 0; n < 12; n++) {
+ map_match_test(m, n);
+ }
+ }
+ System.out.println("map_match_test() passed");
+
+ for (int n = 0; n < 16; n++) {
+ map_bind_test(n);
+ }
+ System.out.println("map_bind_test() passed");
+
+ } catch (final Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ System.out.println("ok");
+ }
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java b/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java
index 961e462cb3..e15ba30a52 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/GetNames.java b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
index 54efaad242..87a27f71ab 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Makefile.src b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
index cd68f1ead5..94625da188 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
+++ b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -38,6 +39,7 @@ JINTERFACE_CLASSPATH = @jinterface_classpath@
CLASSPATH = .@PS@$(JINTERFACE_CLASSPATH)@PS@
JAVA_FILES = \
+ TransportFactoryTest.java \
Nodename.java \
RegisterAndWhereis.java \
GetNames.java \
@@ -48,7 +50,8 @@ JAVA_FILES = \
MboxLinkUnlink.java \
NodeStatusHandler.java \
Maps.java \
- FunEquals.java
+ FunEquals.java \
+ CoreMatchBind.java
CLASS_FILES = $(JAVA_FILES:.java=.class)
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Maps.java b/lib/jinterface/test/jinterface_SUITE_data/Maps.java
index 653defc621..e31b476e02 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/Maps.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/Maps.java
@@ -13,16 +13,17 @@ import com.ericsson.otp.erlang.OtpOutputStream;
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
index 470fdb4a14..7042b6297d 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java b/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java
index 3a8497028e..13e2c8edc4 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
index 44433aa619..67ab6b13aa 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodePing.java b/lib/jinterface/test/jinterface_SUITE_data/NodePing.java
index d0df5c46b5..5938f2b335 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/NodePing.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/NodePing.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
index 06ddfa2d61..bb21fa85ad 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Nodename.java b/lib/jinterface/test/jinterface_SUITE_data/Nodename.java
index dc8cb9c49f..770431a414 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/Nodename.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/Nodename.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java b/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java
index 9df01981b2..3612460cce 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/jinterface_SUITE_data/TransportFactoryTest.java b/lib/jinterface/test/jinterface_SUITE_data/TransportFactoryTest.java
new file mode 100644
index 0000000000..6f5b94832e
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/TransportFactoryTest.java
@@ -0,0 +1,91 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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.
+ *
+ * %CopyrightEnd%
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+import com.ericsson.otp.erlang.OtpSelf;
+import com.ericsson.otp.erlang.OtpServerTransport;
+import com.ericsson.otp.erlang.OtpSocketTransportFactory;
+import com.ericsson.otp.erlang.OtpTransport;
+import com.ericsson.otp.erlang.OtpTransportFactory;
+
+/**
+ * @author Dmitriy Kargapolov
+ */
+public class TransportFactoryTest {
+
+ /**
+ * example of custom transport factory wrapping default one
+ */
+ public static class TransportFactory implements OtpTransportFactory {
+
+ OtpSocketTransportFactory tf = new OtpSocketTransportFactory();
+
+ public OtpTransport createTransport(final String addr, final int port)
+ throws IOException {
+ clientOk = true;
+ System.out.println("creating transport to " + addr + ", " + port);
+ return tf.createTransport(addr, port);
+ }
+
+ public OtpTransport createTransport(final InetAddress addr,
+ final int port) throws IOException {
+ clientOk = true;
+ System.out.println("creating transport to " + addr + ", " + port);
+ return tf.createTransport(addr, port);
+ }
+
+ public OtpServerTransport createServerTransport(final int port)
+ throws IOException {
+ serverOk = true;
+ System.out.println("creating server transport to " + port);
+ return tf.createServerTransport(port);
+ }
+
+ }
+
+ static boolean serverOk = false;
+ static boolean clientOk = false;
+
+ public static void main(final String[] args) throws IOException {
+
+ // check server transport
+ final OtpSelf self = new OtpSelf("local", new TransportFactory());
+ if (!serverOk) {
+ fail("custom server transport was not created");
+ }
+ System.out.println("accepting connections on " + self.port());
+
+ // check client transport
+ try {
+ self.publishPort();
+ } catch (final Exception e) {
+ }
+ if (!clientOk) {
+ fail("custom client transport was not created");
+ }
+ }
+
+ private static void fail(final String string) {
+ System.err.println(string);
+ System.exit(1);
+ }
+}
diff --git a/lib/jinterface/test/jitu.erl b/lib/jinterface/test/jitu.erl
index 46b8cb3ac2..adcadac85e 100644
--- a/lib/jinterface/test/jitu.erl
+++ b/lib/jinterface/test/jitu.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -117,10 +118,7 @@ classpath(Dir) ->
end,
es(Dir++PS++
filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++
- case os:getenv("CLASSPATH") of
- false -> "";
- Classpath -> Classpath
- end,
+ os:getenv("CLASSPATH", ""),
Quote,
EscSpace).
diff --git a/lib/jinterface/test/nc_SUITE.erl b/lib/jinterface/test/nc_SUITE.erl
index 9f37b33718..c5f3198c21 100644
--- a/lib/jinterface/test/nc_SUITE.erl
+++ b/lib/jinterface/test/nc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -214,6 +215,7 @@ decompress_roundtrip(Config) when is_list(Config) ->
0.0,
math:sqrt(2),
<<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,31:5>>,
+ "{}",
RandomBin1k,
RandomBin1M,
RandomBin10M,
@@ -243,6 +245,7 @@ compress_roundtrip(Config) when is_list(Config) ->
0.0,
math:sqrt(2),
<<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,31:5>>,
+ "{}",
RandomBin1k,
RandomBin1M,
RandomBin10M,
diff --git a/lib/jinterface/test/nc_SUITE_data/.gitignore b/lib/jinterface/test/nc_SUITE_data/.gitignore
new file mode 100644
index 0000000000..6b468b62a9
--- /dev/null
+++ b/lib/jinterface/test/nc_SUITE_data/.gitignore
@@ -0,0 +1 @@
+*.class
diff --git a/lib/jinterface/test/nc_SUITE_data/Makefile.src b/lib/jinterface/test/nc_SUITE_data/Makefile.src
index 3d131250be..3d02389df8 100644
--- a/lib/jinterface/test/nc_SUITE_data/Makefile.src
+++ b/lib/jinterface/test/nc_SUITE_data/Makefile.src
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/jinterface/test/nc_SUITE_data/connection_server.java b/lib/jinterface/test/nc_SUITE_data/connection_server.java
index 19ed1c7d5c..36c5074031 100644
--- a/lib/jinterface/test/nc_SUITE_data/connection_server.java
+++ b/lib/jinterface/test/nc_SUITE_data/connection_server.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2010. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/test/nc_SUITE_data/echo_server.java b/lib/jinterface/test/nc_SUITE_data/echo_server.java
index 0e43ea0680..4caf0dedde 100644
--- a/lib/jinterface/test/nc_SUITE_data/echo_server.java
+++ b/lib/jinterface/test/nc_SUITE_data/echo_server.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2004-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index 72ad316333..41e670528a 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1 +1 @@
-JINTERFACE_VSN = 1.5.12
+JINTERFACE_VSN = 1.6.1
diff --git a/lib/kernel/Makefile b/lib/kernel/Makefile
index b90373db8b..74f942b027 100644
--- a/lib/kernel/Makefile
+++ b/lib/kernel/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index ec5d1f09e4..3c6414a620 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/kernel/doc/src/app.xml b/lib/kernel/doc/src/app.xml
index 8575d94048..35feec144e 100644
--- a/lib/kernel/doc/src/app.xml
+++ b/lib/kernel/doc/src/app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -190,7 +191,7 @@ RTDeps [ApplicationVersion] []
start phases must be a subset of the set of phases defined
for the primary application. Refer to <em>OTP Design Principles</em> for more information.</p>
</item>
- <tag><marker id="runtime_dependencies"><c>runtime_dependencies</c></marker></tag>
+ <tag><marker id="runtime_dependencies"></marker><c>runtime_dependencies</c></tag>
<item><p>A list of application versions that the application
depends on. An example of such an application version is
<c>"kernel-3.0"</c>. Application versions specified as runtime
@@ -200,7 +201,7 @@ RTDeps [ApplicationVersion] []
how to compare application versions see
<seealso marker="doc/system_principles:versions">the
documentation of versions in the system principles
- guide</seealso>. Note that that the application version
+ guide</seealso>. Note that the application version
specifies a source code version. An additional indirect
requirement is that installed binary application of
the specified version has been built so that it is
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 7664fda4db..4d8e6ce94b 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -59,8 +60,9 @@
</datatype>
<datatype>
<!-- Parameterized opaque types are NYI: -->
- <name><marker id="type-tuple_of">tuple_of(T)</marker></name>
- <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
+ <name>tuple_of(T)</name>
+ <desc><p><marker id="type-tuple_of"/>
+ A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/kernel/doc/src/auth.xml b/lib/kernel/doc/src/auth.xml
index 72beee46f5..71b1863e96 100644
--- a/lib/kernel/doc/src/auth.xml
+++ b/lib/kernel/doc/src/auth.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -49,7 +50,7 @@
be established in this case. Returns <c>no</c> if <c><anno>Node</anno></c>
does not exist or communication is not authorized (it has
another cookie than <c>auth</c> thinks it has).</p>
- <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(<anno>Node</anno>)</seealso>
+ <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(<c><anno>Node</anno></c>)</seealso>
instead.</p>
</desc>
</func>
@@ -70,7 +71,7 @@
</type_desc>
<desc>
<p>Use
- <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), <anno>Cookie</anno>)</seealso>
+ <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), <c><anno>Cookie</anno></c>)</seealso>
instead.</p>
</desc>
</func>
@@ -93,8 +94,8 @@
<p>Sets the magic cookie of <c><anno>Node</anno></c> to <c><anno>Cookie</anno></c>, and
verifies the status of the authorization.
Equivalent to calling
- <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(<anno>Node</anno>, <anno>Cookie</anno>)</seealso>, followed by
- <seealso marker="#is_auth/1">auth:is_auth(<anno>Node</anno>)</seealso>.</p>
+ <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(<c><anno>Node</anno></c>, <c><anno>Cookie</anno>)</c></seealso>, followed by
+ <seealso marker="#is_auth/1">auth:is_auth(<c><anno>Node</anno></c>)</seealso>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/kernel/doc/src/book.xml b/lib/kernel/doc/src/book.xml
index 09123976cb..8eaff39dc5 100644
--- a/lib/kernel/doc/src/book.xml
+++ b/lib/kernel/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 454ee9bcbb..1bd52040a0 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -179,7 +180,7 @@
example, the call
<c>erl_prim_loader:list_dir( "/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/examples/bench)"</c>
would list the contents of a directory inside an archive.
- See <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso></p>.
+ See <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso>.</p>
<p>An application archive file and a regular application directory
may coexist. This may be useful when there is a need of having
@@ -229,7 +230,7 @@
<c>-code_path_choice Choice</c>. If the flag is set to <c>relaxed</c>,
the code server will instead choose a suitable directory
depending on the actual file structure. If there exists a regular
- application ebin directory,situation it will be chosen. But if it does
+ application ebin directory, it will be chosen. But if it does
not exist, the ebin directory in the archive is chosen if it
exists. If neither of them exists the original directory will be
chosen.</p>
@@ -241,7 +242,7 @@
particular useful to set the flag to <c>relaxed</c> when you want
to elaborate with code loading from archives without editing the
<c>boot script</c>. The default is <c>relaxed</c>. See <seealso
- marker="erts:init">init(3)</seealso></p> </section>
+ marker="erts:init">init(3)</seealso></p></section>
<section>
@@ -281,11 +282,51 @@
<p>From the R12B release, functions in this module will generally fail with an
exception if they are passed an incorrect type (for instance, an integer or a tuple
- where an atom was expected). An error tuple will be returned if type of argument
+ where an atom was expected). An error tuple will be returned if the type of the argument
was correct, but there was some other error (for instance, a non-existing directory
- given to <c>set_path/1</c>.</p>
+ was given to <c>set_path/1</c>).</p>
</section>
+ <section>
+ <marker id="error_reasons"></marker>
+ <title>Error Reasons for Code-Loading Functions</title>
+
+ <p>Functions that load code (such as <c>load_file/1</c>) will
+ return <c>{error,Reason}</c> if the load operation fails.
+ Here follows a description of the common reasons.</p>
+
+ <taglist>
+ <tag><c>badfile</c></tag>
+ <item>
+ <p>The object code has an incorrect format or the module
+ name in the object code is not the expected module name.</p>
+ </item>
+
+ <tag><c>nofile</c></tag>
+ <item>
+ <p>No file with object code was found.</p>
+ </item>
+
+ <tag><c>not_purged</c></tag>
+ <item>
+ <p>The object code could not be loaded because an old version
+ of the code already existed.</p>
+ </item>
+
+ <tag><c>on_load_failure</c></tag>
+ <item>
+ <p>The module has an
+ <seealso marker="doc/reference_manual:code_loading#on_load">-on_load function</seealso>
+ that failed when it was called.</p>
+ </item>
+
+ <tag><c>sticky_directory</c></tag>
+ <item>
+ <p>The object code resides in a sticky directory.</p>
+ </item>
+
+ </taglist>
+ </section>
<datatypes>
<datatype>
<name name="load_ret"/>
@@ -410,12 +451,8 @@
be used to load object code with a module name that is
different from the file name.</p>
<p>Returns <c>{module, <anno>Module</anno>}</c> if successful, or
- <c>{error, nofile}</c> if no object code is found, or
- <c>{error, sticky_directory}</c> if the object code resides in
- a sticky directory. Also if the loading fails, an error tuple is
- returned. See
- <seealso marker="erts:erlang#load_module/2">erlang:load_module/2</seealso>
- for possible values of <c><anno>What</anno></c>.</p>
+ <c>{error, Reason}</c> if loading fails.
+ See <seealso marker="#error_reasons">Error Reasons for Code-Loading Functions</seealso> for a description of the possible error reasons.</p>
</desc>
</func>
<func>
@@ -427,7 +464,7 @@
<desc>
<p>Does the same as <c>load_file(<anno>Module</anno>)</c>, but
<c><anno>Filename</anno></c> is either an absolute file name, or a
- relative file name. The code path is not searched. It returns
+ relative file name. The code path is not searched. It returns
a value in the same way as
<seealso marker="#load_file/1">load_file/1</seealso>. Note
that <c><anno>Filename</anno></c> should not contain the extension (for
@@ -443,7 +480,8 @@
<seealso marker="#load_file/1">load_file/1</seealso>,
unless the module is already loaded.
In embedded mode, however, it does not load a module which is not
- already loaded, but returns <c>{error, embedded}</c> instead.</p>
+ already loaded, but returns <c>{error, embedded}</c> instead.
+ See <seealso marker="#error_reasons">Error Reasons for Code-Loading Functions</seealso> for a description of other possible error reasons.</p>
</desc>
</func>
<func>
@@ -460,12 +498,8 @@
comes. Accordingly, <c><anno>Filename</anno></c> is not opened and read by
the code server.</p>
<p>Returns <c>{module, <anno>Module</anno>}</c> if successful, or
- <c>{error, sticky_directory}</c> if the object code resides in
- a sticky directory, or <c>{error, badarg}</c> if any argument
- is invalid. Also if the loading fails, an error tuple is
- returned. See
- <seealso marker="erts:erlang#load_module/2">erlang:load_module/2</seealso>
- for possible values of <c><anno>What</anno></c>.</p>
+ <c>{error, Reason}</c> if loading fails.
+ See <seealso marker="#error_reasons">Error Reasons for Code-Loading Functions</seealso> for a description of the possible error reasons.</p>
</desc>
</func>
<func>
diff --git a/lib/kernel/doc/src/config.xml b/lib/kernel/doc/src/config.xml
index 005504dbd1..0e34549482 100644
--- a/lib/kernel/doc/src/config.xml
+++ b/lib/kernel/doc/src/config.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml
index 27d8ab4fc1..7d4a9687ea 100644
--- a/lib/kernel/doc/src/disk_log.xml
+++ b/lib/kernel/doc/src/disk_log.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -232,11 +233,11 @@
<func>
<name name="alog" arity="2"/>
<name name="balog" arity="2"/>
+ <fsummary>Asynchronously log an item onto a disk log.</fsummary>
<type variable="Log"/>
<type variable="Term" name_i="1"/>
<type variable="Bytes"/>
<type name="notify_ret"/>
- <fsummary>Asynchronously log an item onto a disk log.</fsummary>
<desc>
<p>The <c>alog/2</c> and <c>balog/2</c> functions asynchronously
append an item to a disk log. The function <c>alog/2</c> is
@@ -287,8 +288,8 @@
<func>
<name name="block" arity="1"/>
<name name="block" arity="2"/>
- <type name="block_error_rsn"/>
<fsummary>Block a disk log.</fsummary>
+ <type name="block_error_rsn"/>
<desc>
<p>With a call to <c>block/1,2</c> a process can block a log.
If the blocking process is not an owner of the log, a temporary
@@ -662,8 +663,8 @@
<func>
<name name="lclose" arity="1"/>
<name name="lclose" arity="2"/>
- <type name="lclose_error_rsn"/>
<fsummary>Close a disk log on one node.</fsummary>
+ <type name="lclose_error_rsn"/>
<desc>
<p>The function <c>lclose/1</c> closes a local log or an
individual distributed log on the current node.
@@ -743,6 +744,7 @@
</func>
<func>
<name name="open" arity="1"/>
+ <fsummary>Open a disk log file.</fsummary>
<type name="dlog_options"/>
<type name="dlog_option"/>
<type name="open_ret"/>
@@ -752,7 +754,6 @@
<type name="open_error_rsn"/>
<type name="dlog_optattr"/>
<type name="dlog_size"/>
- <fsummary>Open a disk log file.</fsummary>
<desc>
<p>The <c><anno>ArgL</anno></c> parameter is a list of options which have
the following meanings:</p>
@@ -1042,8 +1043,8 @@ If
</func>
<func>
<name name="sync" arity="1"/>
- <type name="sync_error_rsn"/>
<fsummary>Flush the contents of a disk log to the disk.</fsummary>
+ <type name="sync_error_rsn"/>
<desc>
<p>The <c>sync/1</c> function ensures that the contents of the
log are actually written to the disk.
@@ -1085,8 +1086,8 @@ If
</func>
<func>
<name name="unblock" arity="1"/>
- <type name="unblock_error_rsn"/>
<fsummary>Unblock a disk log.</fsummary>
+ <type name="unblock_error_rsn"/>
<desc>
<p>The <c>unblock/1</c> function unblocks a log.
A log can only be unblocked by the blocking process.
diff --git a/lib/kernel/doc/src/erl_boot_server.xml b/lib/kernel/doc/src/erl_boot_server.xml
index abaea4f695..a8015fa453 100644
--- a/lib/kernel/doc/src/erl_boot_server.xml
+++ b/lib/kernel/doc/src/erl_boot_server.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml
index 7be54c8b95..8d71883cf4 100644
--- a/lib/kernel/doc/src/erl_ddll.xml
+++ b/lib/kernel/doc/src/erl_ddll.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -387,14 +388,14 @@
remove a monitor.</p>
<p>The function accepts the following parameters:</p>
<taglist>
- <tag><em><anno>Tag</anno></em></tag>
+ <tag><em><c><anno>Tag</anno></c></em></tag>
<item>
<p>The monitor tag is always <c>driver</c> as this function
can only be used to create driver monitors. In the future,
driver monitors will be integrated with process monitors,
why this parameter has to be given for consistence.</p>
</item>
- <tag><em><anno>Item</anno></em></tag>
+ <tag><em><c><anno>Item</anno></c></em></tag>
<item>
<p>The <c><anno>Item</anno></c> parameter specifies which driver one
wants to monitor (the name of the driver) as well as
@@ -641,7 +642,7 @@
</note>
<p>The function accepts the following parameters:</p>
<taglist>
- <tag><em><anno>Path</anno></em></tag>
+ <tag><em><c><anno>Path</anno></c></em></tag>
<item>
<p>The filesystem path to the directory where the driver
object file is situated. The filename of the object file
@@ -664,7 +665,7 @@
to have <em>only one loader</em> of a driver one wants to
upgrade in a running system! </p>
</item>
- <tag><em><anno>Name</anno></em></tag>
+ <tag><em><c><anno>Name</anno></c></em></tag>
<item>
<p>The name parameter is the name of the driver to be used
in subsequent calls to <seealso marker="erts:erlang#open_port/2">open_port</seealso>. The
@@ -677,14 +678,14 @@
with this <c><anno>Name</anno></c> parameter, much as a beam-file's
module name much correspond to its filename.</p>
</item>
- <tag><em><anno>OptionList</anno></em></tag>
+ <tag><em><c><anno>OptionList</anno></c></em></tag>
<item>
<p>A number of options can be specified to control the
loading operation. The options are given as a list of
two-tuples, the tuples having the following values and
meanings:</p>
<taglist>
- <tag><em>{driver_options, <anno>DriverOptionList</anno>}</em></tag>
+ <tag><em>{driver_options, <c><anno>DriverOptionList</anno></c>}</em></tag>
<item>
<p>This option is to provide options that will change
its general behavior and will "stick" to the driver
@@ -700,7 +701,7 @@
when the last <seealso marker="#users">user</seealso> calls <seealso marker="#try_unload/2">try_unload/2</seealso>, or
the last process having loaded the driver exits.</p>
</item>
- <tag><em>{monitor, <anno>MonitorOption</anno>}</em></tag>
+ <tag><em>{monitor, <c><anno>MonitorOption</anno></c>}</em></tag>
<item>
<p>A <c><anno>MonitorOption</anno></c> tells <c>try_load/3</c> to
trigger a driver monitor under certain
@@ -731,7 +732,7 @@
<c>{monitor, pending_driver}</c> in production
code (see the monitor discussion above). </p>
</item>
- <tag><em>{reload,<anno>ReloadOption</anno>}</em></tag>
+ <tag><em>{reload, <c><anno>ReloadOption</anno></c>}</em></tag>
<item>
<p>This option is used when one wants to
<em>reload</em> a driver from disk, most often in a
@@ -909,13 +910,13 @@
</taglist>
<p>The function accepts the following parameters:</p>
<taglist>
- <tag><em><anno>Name</anno></em></tag>
+ <tag><em><c><anno>Name</anno></c></em></tag>
<item>
<p>The name parameter is the name of the driver to be
unloaded. The name can be specified either as an
<c>iolist()</c> or as an <c>atom()</c>. </p>
</item>
- <tag><em><anno>OptionList</anno></em></tag>
+ <tag><em><c><anno>OptionList</anno></c></em></tag>
<item>
<p>The <c><anno>OptionList</anno></c> argument can be used to specify
certain behavior regarding ports as well as triggering
@@ -933,7 +934,7 @@
unloads, one should use the driver option
<c>kill_ports</c> when loading the driver instead.</p>
</item>
- <tag><em>{monitor, <anno>MonitorOption</anno>}</em></tag>
+ <tag><em>{monitor, <c><anno>MonitorOption</anno></c>}</em></tag>
<item>
<p>This option creates a driver monitor if the condition
given in <c><anno>MonitorOption</anno></c> is true. The valid
diff --git a/lib/kernel/doc/src/erl_prim_loader_stub.xml b/lib/kernel/doc/src/erl_prim_loader_stub.xml
index 485b16b91f..8d5f58dc3a 100644
--- a/lib/kernel/doc/src/erl_prim_loader_stub.xml
+++ b/lib/kernel/doc/src/erl_prim_loader_stub.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/doc/src/erlang_stub.xml b/lib/kernel/doc/src/erlang_stub.xml
index 79a041110a..b9867806bd 100644
--- a/lib/kernel/doc/src/erlang_stub.xml
+++ b/lib/kernel/doc/src/erlang_stub.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/doc/src/error_handler.xml b/lib/kernel/doc/src/error_handler.xml
index 2f8f09b984..6aec5c77d5 100644
--- a/lib/kernel/doc/src/error_handler.xml
+++ b/lib/kernel/doc/src/error_handler.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml
index df2f0b01ee..92e14c2bef 100644
--- a/lib/kernel/doc/src/error_logger.xml
+++ b/lib/kernel/doc/src/error_logger.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -58,12 +59,11 @@
specific events. (<c>add_report_handler/1,2</c>). Also, there is
a useful event handler in STDLIB for multi-file logging of events,
see <c>log_mf_h(3)</c>.</p>
- <p>Warning events were introduced in Erlang/OTP R9C. To retain
- backwards compatibility, these are by default tagged as errors,
- thus showing up as error reports in the logs. By using
- the command line flag <c><![CDATA[+W <w | i>]]></c>, they can instead
- be tagged as warnings or info. Tagging them as warnings may
- require rewriting existing user defined event handlers.</p>
+ <p>Warning events were introduced in Erlang/OTP R9C and are enabled
+ by default as of 18.0. To retain backwards compatibility with existing
+ user defined event handlers, these may be tagged as errors or info
+ using the command line flag <c><![CDATA[+W <e | i | w>]]></c>, thus
+ showing up as error or info reports in the logs.</p>
</description>
<datatypes>
<datatype>
@@ -132,7 +132,7 @@ ok</pre>
<desc>
<p>Returns the current mapping for warning events. Events sent
using <c>warning_msg/1,2</c> or <c>warning_report/1,2</c>
- are tagged as errors (default), warnings or info, depending
+ are tagged as errors, warnings (default) or info, depending
on the value of the command line flag <c>+W</c>.</p>
<pre>
os$ <input>erl</input>
@@ -140,25 +140,25 @@ Erlang (BEAM) emulator version 5.4.8 [hipe] [threads:0] [kernel-poll]
Eshell V5.4.8 (abort with ^G)
1> <input>error_logger:warning_map().</input>
-error
-2> <input>error_logger:warning_msg("Warnings tagged as: ~p~n", [error]).</input>
+warning
+2> <input>error_logger:warning_msg("Warnings tagged as: ~p~n", [warning]).</input>
-=ERROR REPORT==== 11-Aug-2005::15:31:23 ===
-Warnings tagged as: error
+=WARNING REPORT==== 11-Aug-2005::15:31:55 ===
+Warnings tagged as: warning
ok
3>
User switch command
--> q
-os$ <input>erl +W w</input>
+os$ <input>erl +W e</input>
Erlang (BEAM) emulator version 5.4.8 [hipe] [threads:0] [kernel-poll]
Eshell V5.4.8 (abort with ^G)
1> <input>error_logger:warning_map().</input>
-warning
-2> <input>error_logger:warning_msg("Warnings tagged as: ~p~n", [warning]).</input>
+error
+2> <input>error_logger:warning_msg("Warnings tagged as: ~p~n", [error]).</input>
-=WARNING REPORT==== 11-Aug-2005::15:31:55 ===
-Warnings tagged as: warning
+=ERROR REPORT==== 11-Aug-2005::15:31:23 ===
+Warnings tagged as: error
ok</pre>
</desc>
</func>
@@ -299,12 +299,12 @@ ok</pre>
<name name="logfile" arity="1" clause_i="1"/>
<name name="logfile" arity="1" clause_i="2"/>
<name name="logfile" arity="1" clause_i="3"/>
+ <fsummary>Enable or disable error printouts to a file</fsummary>
<type variable="Filename"/>
<type variable="OpenReason" name_i="1"/>
<type variable="CloseReason" name_i="2"/>
<type variable="FilenameReason" name_i="3"/>
<type name="open_error"/>
- <fsummary>Enable or disable error printouts to a file</fsummary>
<desc>
<p>Enables or disables printout of standard events to a file.</p>
<p>This is done by adding or deleting the standard event handler
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index dcb9640dcf..831ef1c22a 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -86,9 +87,10 @@
<name name="deep_list"/>
</datatype>
<datatype>
- <name><marker id="type-fd">fd()</marker></name>
+ <name>fd()</name>
<desc>
- <p>A file descriptor representing a file opened in <seealso
+ <p><marker id="type-fd"/>
+ A file descriptor representing a file opened in <seealso
marker="#raw">raw</seealso> mode.</p>
</desc>
</datatype>
@@ -490,7 +492,7 @@
<name name="list_dir" arity="1"/>
<fsummary>List files in a directory</fsummary>
<desc>
- <p>Lists all files in a directory, <b>except</b> files
+ <p>Lists all files in a directory, <em>except</em> files
with "raw" names. Returns
<c>{ok, <anno>Filenames</anno>}</c> if successful.
Otherwise, it returns <c>{error, <anno>Reason</anno>}</c>.
@@ -1192,8 +1194,8 @@
and <c>read_line/1</c> are the only ways to read from a file
opened in raw mode (although they work for normally opened
files, too).</p>
- <p>For files where <c>encoding</c> is set to something else than <c>latin1</c>, one character might be represented by more than one byte on the file. The parameter <c>Number</c> always denotes the number of <em>characters</em> read from the file, why the position in the file might be moved a lot more than this number when reading a Unicode file.</p>
- <p>Also if <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read/3</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
+ <p>For files where <c>encoding</c> is set to something else than <c>latin1</c>, one character might be represented by more than one byte on the file. The parameter <c>Number</c> always denotes the number of <em>characters</em> read from the file, while the position in the file might be moved much more than this number when reading a Unicode file.</p>
+ <p>Also, if <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read/3</c> call will fail if the data contains characters larger than 255, which is why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
<p>The function returns:</p>
<taglist>
<tag><c>{ok, <anno>Data</anno>}</c></tag>
@@ -1306,15 +1308,15 @@
<item>
<p>The current system access to the file.</p>
</item>
- <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>atime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was read.</p>
</item>
- <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>mtime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was written.</p>
</item>
- <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >=0</c></tag>
+ <tag><c>ctime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >=0</c></tag>
<item>
<p>The interpretation of this time field depends on
the operating system. On Unix, it is the last time
@@ -1693,9 +1695,9 @@
<desc>
<p>Makes sure that any buffers kept by the operating system
(not by the Erlang runtime system) are written to disk. In
- many ways it's resembles fsync but it not requires to update
- some of file's metadata such as the access time. On
- some platforms, this function might have no effect.</p>
+ many ways it resembles fsync but it does not update
+ some of the file's metadata such as the access time. On
+ some platforms this function has no effect.</p>
<p>Applications that access databases or log files often write
a tiny data fragment (e.g., one line in a log file) and then
call fsync() immediately in order to ensure that the written
@@ -1703,11 +1705,11 @@
will always initiate two write operations: one for the newly
written data and another one in order to update the modification
time stored in the inode. If the modification time is not a part
- of the transaction concept fdatasync() can be used to avoid
+ of the transaction concept, fdatasync() can be used to avoid
unnecessary inode disk write operations.</p>
- <p>Available only in some POSIX systems. This call results in a
- call to fsync(), or has no effect, in systems not implementing
- the fdatasync syscall.</p>
+ <p>Available only in some POSIX systems, this call results in a
+ call to fsync(), or has no effect in systems not implementing
+ the fdatasync() syscall.</p>
</desc>
</func>
<func>
@@ -1744,7 +1746,7 @@
See <seealso marker="gen_tcp#controlling_process-2">gen_tcp:controlling_process/2</seealso></p>
<p>If the OS used does not support sendfile, an Erlang fallback
using file:read and gen_tcp:send is used.</p>
- <p>The option list can contain the following options:
+ <p>The option list can contain the following options:</p>
<taglist>
<tag><c>chunk_size</c></tag>
<item>The chunk size used by the erlang fallback to send
@@ -1759,7 +1761,6 @@
the sendfile call will return <c>{error,einval}</c>.
Introduced in Erlang/OTP 17.0. Default is false.</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -1850,22 +1851,21 @@
Type <c>local</c> will interpret the time set as local, <c>universal</c> will
interpret it as universal time and <c>posix</c> must be seconds since
or before unix time epoch which is 1970-01-01 00:00 UTC.
- Default is <c>{time, local}</c>.
+ Default is <c>{time, local}</c>.</p>
<p>If the <c>raw</c> option is set, the file server will not be called
and only informations about local files will be returned.</p>
- </p>
<p>The following fields are used from the record, if they are
given.</p>
<taglist>
- <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>atime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was read.</p>
</item>
- <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>mtime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was written.</p>
</item>
- <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>ctime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>On Unix, any value give for this field will be ignored
(the "ctime" for the file will be set to the current
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml
index ee8cd441d4..456108a2fe 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -76,9 +77,10 @@
<datatypes>
<datatype>
- <name><marker id="type-assoc_id">assoc_id()</marker></name>
+ <name>assoc_id()</name>
<desc>
- <p>An opaque term returned in for example #sctp_paddr_change{}
+ <p><marker id="type-assoc_id"/>
+ An opaque term returned in for example #sctp_paddr_change{}
that identifies an association for an SCTP socket. The term
is opaque except for the special value <c>0</c> that has a
meaning such as "the whole endpoint" or "all future associations".
@@ -97,9 +99,10 @@
<desc><marker id="type-sctp_socket"></marker></desc>
</datatype>
<datatype>
- <name><marker id="type-sctp_socket">sctp_socket()</marker></name>
+ <name>sctp_socket()</name>
<desc>
- <p>Socket identifier returned from <c>open/*</c>.</p>
+ <p><marker id="type-sctp_socket"/>
+ Socket identifier returned from <c>open/*</c>.</p>
<marker id="exports"></marker>
</desc>
</datatype>
@@ -145,7 +148,7 @@
<c><anno>Addr</anno></c> and <c><anno>Port</anno></c>. The <c><anno>Timeout</anno></c>,
is expressed in milliseconds. A socket can be associated with multiple peers.</p>
- <p><b>WARNING:</b>Using a value of <c><anno>Timeout</anno></c> less than
+ <p><em>WARNING:</em>Using a value of <c><anno>Timeout</anno></c> less than
the maximum time taken by the OS to establish an association (around 4.5 minutes
if the default values from RFC 4960 are used) can result in
inconsistent or incorrect return values. This is especially
@@ -169,7 +172,7 @@
<p>The number of outbound and inbound streams can be set by
giving an <c>sctp_initmsg</c> option to <c>connect</c>
as in:</p>
-<pre> connect(<anno>Socket</anno>, Ip, <anno>Port</anno>,
+<pre> connect(Socket, Ip, Port>,
[{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
max_instreams=MaxInStreams}}]) </pre>
<p>All options <c><anno>Opt</anno></c> are set on the socket before the
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index 820ecd1e30..6a19e76c4f 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -77,9 +78,10 @@ do_recv(Sock, Bs) ->
<name name="listen_option"/>
</datatype>
<datatype>
- <name><marker id="type-socket">socket()</marker></name>
+ <name>socket()</name>
<desc>
- <p>As returned by accept/1,2 and connect/3,4.</p>
+ <p><marker id="type-socket"/>
+ As returned by accept/1,2 and connect/3,4.</p>
<marker id="connect"></marker>
</desc>
</datatype>
@@ -347,11 +349,22 @@ do_recv(Sock, Bs) ->
</func>
<func>
<name name="shutdown" arity="2"/>
- <fsummary>Immediately close a socket</fsummary>
+ <fsummary>Asynchronously close a socket</fsummary>
<desc>
- <p>Immediately close a socket in one or two directions.</p>
+ <p>Close a socket in one or two directions.</p>
<p><c><anno>How</anno> == write</c> means closing the socket for writing,
reading from it is still possible.</p>
+ <p>If <c><anno>How</anno> == read</c>, or there is no outgoing
+ data buffered in the <c><anno>Socket</anno></c> port,
+ then the socket is shutdown immediately and any error encountered
+ is returned in <c><anno>Reason</anno></c>.</p>
+ <p>If there is data buffered in the socket port, then the attempt
+ to shutdown the socket is postponed until that data is written to the
+ kernel socket send buffer. Any errors encountered will result
+ in the socket being closed and <c>{error, closed}</c> being returned
+ on the next
+ <seealso marker="gen_tcp#recv/2">recv/2</seealso> or
+ <seealso marker="gen_tcp#send/2">send/2</seealso>.</p>
<p>To be able to handle that the peer has done a shutdown on
the write side, the <c>{exit_on_close, false}</c> option
is useful.</p>
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 291d1b0da7..79cd87dcef 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -42,9 +43,9 @@
<name name="option_name"/>
</datatype>
<datatype>
- <name><marker id="type-socket">socket()</marker></name>
+ <name>socket()</name>
<desc>
- <p>As returned by open/1,2.</p>
+ <p><marker id="type-socket"/>As returned by open/1,2.</p>
</desc>
</datatype>
</datatypes>
diff --git a/lib/kernel/doc/src/global.xml b/lib/kernel/doc/src/global.xml
index 691b243443..bd75945115 100644
--- a/lib/kernel/doc/src/global.xml
+++ b/lib/kernel/doc/src/global.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/global_group.xml b/lib/kernel/doc/src/global_group.xml
index 2c181da83a..4b21b0a14a 100644
--- a/lib/kernel/doc/src/global_group.xml
+++ b/lib/kernel/doc/src/global_group.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml
index 3ec33d2f18..9da4773f2d 100644
--- a/lib/kernel/doc/src/heart.xml
+++ b/lib/kernel/doc/src/heart.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -78,6 +79,16 @@
<pre>
% <input>erl -heart -env ERL_CRASH_DUMP_SECONDS 10 ...</input></pre>
+
+ <p> If a regular core dump is wanted, let heart know by setting the kill signal to abort
+ using the environment variable <c><![CDATA[HEART_KILL_SIGNAL=SIGABRT]]></c>.
+ If unset, or not set to <c><![CDATA[SIGABRT]]></c>, the default behaviour will be a kill
+ signal using <c><![CDATA[SIGKILL]]></c>.
+ </p>
+
+ <pre>
+% <input>erl -heart -env HEART_KILL_SIGNAL SIGABRT ...</input></pre>
+
<p>
Furthermore, <c><![CDATA[ERL_CRASH_DUMP_SECONDS]]></c> has the following behaviour on
<c>heart</c>:
@@ -107,6 +118,13 @@
<p>In the following descriptions, all function fails with reason
<c>badarg</c> if <c>heart</c> is not started.</p>
</description>
+
+ <datatypes>
+ <datatype>
+ <name name="heart_option"/>
+ </datatype>
+ </datatypes>
+
<funcs>
<func>
<name name="set_cmd" arity="1"/>
@@ -143,6 +161,62 @@
the empty string will be returned.</p>
</desc>
</func>
+
+ <func>
+ <name name="set_callback" arity="2"/>
+ <fsummary>Set a validation callback</fsummary>
+ <desc>
+ <p> This validation callback will be executed before any heartbeat sent
+ to the port program. For the validation to succeed it needs to return
+ with the value <c>ok</c>.
+ </p>
+ <p> An exception within the callback will be treated as a validation failure. </p>
+ <p> The callback will be removed if the system reboots. </p>
+ </desc>
+ </func>
+ <func>
+ <name name="clear_callback" arity="0"/>
+ <fsummary>Clear the validation callback</fsummary>
+ <desc>
+ <p>Removes the validation callback call before heartbeats.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="get_callback" arity="0"/>
+ <fsummary>Get the validation callback</fsummary>
+ <desc>
+ <p>Get the validation callback. If the callback is cleared, <c>none</c> will be returned.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="set_options" arity="1"/>
+ <fsummary>Set a list of options</fsummary>
+ <desc>
+ <p> Valid options <c>set_options</c> are: </p>
+ <taglist>
+ <tag><c>check_schedulers</c></tag>
+ <item>
+ <p>If enabled, a signal will be sent to each scheduler to check its
+ responsiveness. The system check occurs before any heartbeat sent
+ to the port program. If any scheduler is not responsive enough the
+ heart program will not receive its heartbeat and thus eventually terminate the node.
+ </p>
+ </item>
+ </taglist>
+ <p> Returns with the value <c>ok</c> if the options are valid.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="get_options" arity="0"/>
+ <fsummary>Get the temporary reboot command</fsummary>
+ <desc>
+ <p>Returns <c>{ok, Options}</c> where <c>Options</c> is a list of current options enabled for heart.
+ If the callback is cleared, <c>none</c> will be returned.</p>
+ </desc>
+ </func>
+
+
</funcs>
</erlref>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index 77a8caaaf6..088d78c1d6 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -116,8 +117,9 @@ fe80::204:acff:fe17:bf38
</desc>
</datatype>
<datatype>
- <name><marker id="type-socket">socket()</marker></name>
- <desc><p>See <seealso marker="gen_tcp#type-socket">gen_tcp(3)</seealso>
+ <name>socket()</name>
+ <desc><p><marker id="type-socket"></marker>
+ See <seealso marker="gen_tcp#type-socket">gen_tcp(3)</seealso>
and <seealso marker="gen_udp#type-socket">gen_udp(3)</seealso>.</p>
</desc>
</datatype>
@@ -221,7 +223,7 @@ fe80::204:acff:fe17:bf38
</p>
<p>
Do not rely too much on the order of <c><anno>Flag</anno></c> atoms or
- <c><anno>Ifopt</anno></c> tuples. There are some rules, though:
+ <c><anno>Ifopt</anno></c> tuples. There are some rules, though:</p>
<list>
<item>
Immediately after <c>{addr,_}</c> follows <c>{netmask,_}</c>
@@ -237,7 +239,6 @@ fe80::204:acff:fe17:bf38
tuple concerns that address.
</item>
</list>
- </p>
<p>
The <c>{hwaddr,_}</c> tuple is not returned on Solaris since the
hardware address historically belongs to the link layer and only
@@ -378,14 +379,14 @@ fe80::204:acff:fe17:bf38
<name name="ntoa" arity="1" />
<fsummary>Convert IPv6 / IPV4 adress to ascii</fsummary>
<desc>
- <p>Parses an <a href="#type-ip_address">ip_address()</a> and returns an IPv4 or IPv6 address string.</p>
+ <p>Parses an <seealso marker="#type-ip_address">ip_address()</seealso> and returns an IPv4 or IPv6 address string.</p>
</desc>
</func>
<func>
<name name="parse_ipv4_address" arity="1" />
<fsummary>Parse an IPv4 address</fsummary>
<desc>
- <p>Parses an IPv4 address string and returns an <a href="#type-ip4_address">ip4_address()</a>.
+ <p>Parses an IPv4 address string and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso>.
Accepts a shortened IPv4 shortened address string.</p>
</desc>
</func>
@@ -393,14 +394,14 @@ fe80::204:acff:fe17:bf38
<name name="parse_ipv4strict_address" arity="1" />
<fsummary>Parse an IPv4 address strict.</fsummary>
<desc>
- <p>Parses an IPv4 address string containing four fields, i.e <b>not</b> shortened, and returns an <a href="#type-ip4_adress">ip4_address()</a>.</p>
+ <p>Parses an IPv4 address string containing four fields, i.e <em>not</em> shortened, and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso>.</p>
</desc>
</func>
<func>
<name name="parse_ipv6_address" arity="1" />
<fsummary>Parse an IPv6 address</fsummary>
<desc>
- <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
+ <p>Parses an IPv6 address string and returns an <seealso marker="#type-ip6_address">ip6_address()</seealso>.
If an IPv4 address string is passed, an IPv4-mapped IPv6 address is returned.</p>
</desc>
</func>
@@ -408,22 +409,22 @@ fe80::204:acff:fe17:bf38
<name name="parse_ipv6strict_address" arity="1" />
<fsummary>Parse an IPv6 address strict.</fsummary>
<desc>
- <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
- Does <b>not</b> accept IPv4 adresses.</p>
+ <p>Parses an IPv6 address string and returns an <seealso marker="#type-ip6_address">ip6_address()</seealso>.
+ Does <em>not</em> accept IPv4 adresses.</p>
</desc>
</func>
<func>
<name name="parse_address" arity="1" />
<fsummary>Parse an IPv4 or IPv6 address.</fsummary>
<desc>
- <p>Parses an IPv4 or IPv6 address string and returns an <a href="#type-ip4_address">ip4_address()</a> or <a href="#type-ip6_address">ip6_address()</a>. Accepts a shortened IPv4 address string.</p>
+ <p>Parses an IPv4 or IPv6 address string and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso> or <seealso marker="#type-ip6_address">ip6_address()</seealso>. Accepts a shortened IPv4 address string.</p>
</desc>
</func>
<func>
<name name="parse_strict_address" arity="1" />
<fsummary>Parse an IPv4 or IPv6 address strict.</fsummary>
<desc>
- <p>Parses an IPv4 or IPv6 address string and returns an <a href="#type-ip4_address">ip4_address()</a> or <a href="#type-ip6_adress">ip6_address()</a>. Does <b>not</b> accept a shortened IPv4 address string.</p>
+ <p>Parses an IPv4 or IPv6 address string and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso> or <seealso marker="#type-ip6_address">ip6_address()</seealso>. Does <em>not</em> accept a shortened IPv4 address string.</p>
</desc>
</func>
<func>
@@ -861,10 +862,10 @@ fe80::204:acff:fe17:bf38
<c>CAP_SYS_ADMIN</c> according to the documentation for setns(2).
However, during testing also <c>CAP_SYS_PTRACE</c>
and <c>CAP_DAC_READ_SEARCH</c> has proven to be necessary.
- Example:<code>
+ Example:</p><code>
setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
</code>
- Note also that the filesystem containing the virtual machine
+ <p>Note also that the filesystem containing the virtual machine
executable (<c>beam.smp</c> in the example above) has to be local,
mounted without the <c>nosetuid</c> flag,
support extended attributes and that
@@ -980,6 +981,11 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
indicated length are accepted and not considered invalid due
to internal buffer limitations.</p>
</item>
+ <tag><c>{line_delimiter, Char}</c>(TCP/IP sockets)</tag>
+ <item>
+ <p>Sets the line delimiting character for line oriented protocols
+ (<c>line</c>). Default value is <c>$\n</c>.</p>
+ </item>
<tag><c>{priority, Priority}</c></tag>
<item> <p>Set the protocol-defined priority for all packets to be sent
@@ -1037,6 +1043,36 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
<marker id="option-sndbuf"></marker>
</item>
+ <tag><c>{show_econnreset, Boolean}</c>(TCP/IP sockets)</tag>
+ <item>
+ <p>When this option is set to <c>false</c>, as it is by
+ default, an RST that is received from the TCP peer is treated
+ as a normal close (as though a FIN was sent). A caller
+ to <seealso marker="gen_tcp#recv/2">gen_tcp:recv/2</seealso>
+ will get <c>{error, closed}</c>. In active
+ mode the controlling process will receive a
+ <c>{tcp_close, Socket}</c> message, indicating that the
+ peer has closed the connection.</p>
+ <p>Setting this option to <c>true</c> will allow you to
+ distinguish between a connection that was closed normally,
+ and one which was aborted (intentionally or unintentionally)
+ by the TCP peer. A call to
+ <seealso marker="gen_tcp#recv/2">gen_tcp:recv/2</seealso>
+ will return <c>{error, econnreset}</c>. In
+ active mode, the controlling process will receive a
+ <c>{tcp_error, Socket, econnreset}</c> message
+ before the usual <c>{tcp_closed, Socket}</c>, as is
+ the case for any other socket error. Calls to
+ <seealso marker="gen_tcp#send/2">gen_tcp:send/2</seealso>
+ will also return <c>{error, econnreset}</c> when it
+ is detected that a TCP peer has sent an RST.</p>
+ <p>A connected socket returned from
+ <seealso marker="gen_tcp#accept/1">gen_tcp:accept/1</seealso>
+ will inherit the <c>show_econnreset</c> setting from the
+ listening socket.</p>
+ <marker id="option-show_econnreset"></marker>
+ </item>
+
<tag><c>{sndbuf, Size}</c></tag>
<item>
<p>The minimum size of the send buffer to use for the socket.
diff --git a/lib/kernel/doc/src/inet_res.xml b/lib/kernel/doc/src/inet_res.xml
index 7880ccda05..851a36aba9 100644
--- a/lib/kernel/doc/src/inet_res.xml
+++ b/lib/kernel/doc/src/inet_res.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2009</year><year>2013</year>
+ <year>2009</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -76,8 +77,11 @@
query is tried for the <c>alt_nameservers</c>.</p>
</section>
+ <section>
+ <title>Resolver Types</title>
+ <p>The following data types concern the resolver:</p>
+ </section>
<datatypes>
- <p>Resolver types:</p>
<datatype>
<name name="res_option"/>
</datatype>
@@ -87,8 +91,13 @@
<datatype>
<name name="res_error"/>
</datatype>
-
- <p><marker id="dns_types"/>DNS types:</p>
+ </datatypes>
+ <section>
+ <title>DNS Types</title>
+ <p><marker id="dns_types"/>
+ The following data types concern the DNS client:</p>
+ </section>
+ <datatypes>
<datatype>
<name name="dns_name"/>
<desc><p>A string with no adjacent dots.</p></desc>
@@ -105,7 +114,7 @@
<p>This is the start of a hiearchy of opaque data structures
that can be examined with access functions in inet_dns that
return lists of {Field,Value} tuples. The arity 2 functions
- just return the value for a given field.
+ just return the value for a given field.</p>
<pre>
dns_msg() = DnsMsg
inet_dns:msg(DnsMsg) ->
@@ -153,18 +162,19 @@ dns_rr() = DnsRr
| {version, integer()}
| {z, integer()}
| {data, dns_data()} ]
- inet_dns:rr(DnsRr, Field) -> Value
+ inet_dns:rr(DnsRr, Field) -> Value</pre>
-There is an info function for the types above:
+<p>There is an info function for the types above:</p>
+<pre>
inet_dns:record_type(dns_msg()) -> msg;
inet_dns:record_type(dns_header()) -> header;
inet_dns:record_type(dns_query()) -> dns_query;
inet_dns:record_type(dns_rr()) -> rr;
-inet_dns:record_type(_) -> undefined.
+inet_dns:record_type(_) -> undefined.</pre>
-So; inet_dns:(inet_dns:record_type(X))(X) will convert
-any of these data structures into a {Field,Value} list.</pre></p>
+<p>So; inet_dns:(inet_dns:record_type(X))(X) will convert
+any of these data structures into a {Field,Value} list.</p>
</desc>
</datatype>
<datatype>
@@ -271,7 +281,7 @@ any of these data structures into a {Field,Value} list.</pre></p>
<p>Resolve a DNS record of the given type and class for the given name.
The returned <c>dns_msg()</c> can be examined using
access functions in <c>inet_db</c> as described
- in <seealso marker="#dns_types">DNS types</seealso>.
+ in <seealso marker="#dns_types">DNS Types</seealso>.
</p><p>
If <c><anno>Name</anno></c> is an <c>ip_address()</c>, the domain name
to query for is generated as the standard reverse
diff --git a/lib/kernel/doc/src/init_stub.xml b/lib/kernel/doc/src/init_stub.xml
index 5c57f8850e..eae2cbea95 100644
--- a/lib/kernel/doc/src/init_stub.xml
+++ b/lib/kernel/doc/src/init_stub.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml
index 96e3651140..956c57f7c1 100644
--- a/lib/kernel/doc/src/kernel_app.xml
+++ b/lib/kernel/doc/src/kernel_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -42,6 +43,7 @@
<item><c>erl_boot_server</c></item>
<item><c>erl_ddll</c></item>
<item><c>error_logger</c></item>
+ <item><c>error_logger_format_depth</c></item>
<item><c>file</c></item>
<item><c>global</c></item>
<item><c>global_group</c></item>
@@ -151,6 +153,42 @@
</item>
</taglist>
</item>
+ <tag><c>error_logger_format_depth = Depth</c></tag>
+ <item>
+ <marker id="error_logger_format_depth"></marker>
+ <p>This parameter can be used to limit the size of the
+ formatted output from the error logger event handlers.</p>
+
+ <note><p>This configuration parameter was introduced in OTP 18.1.
+ It is currently experimental. Based on user feedback it
+ may be changed or improved in future releases, for example
+ to gain better control over how to limit the size of the
+ formatted output. We have no plans to entirely remove this
+ new feature, unless it turns out to be completely
+ useless. In OTP 19, the default may be changed to limit the
+ formatted output.</p></note>
+
+ <p><c>Depth</c> is a positive integer that is the maximum
+ depth to which terms are printed by the error logger event
+ handlers included in OTP. Specifically, the two event handlers
+ defined by the <c>Kernel</c> application and the two event
+ handlers in the <c>SASL</c> application will use this
+ configuration parameter. (If you have implemented you own
+ error handlers, this configuration parameter will have no
+ effect on them.)</p>
+
+ <p>The way <c>Depth</c> is used, is that format strings
+ string passed to the event handlers will be rewritten.
+ The "~p" and "~w" format controls will be replaced with
+ "~P" and "~W", respectively, and <c>Depth</c> will be
+ used as the depth parameter. See
+ <seealso marker="stdlib:io#format/2">io:format/2</seealso>.</p>
+
+ <note><p>A reasonable starting value for <c>Depth</c> is
+ <c>30</c>. You should test crashing various processes in your
+ application and examine the logs from the crashes, and then
+ either increase or decrease the value.</p></note>
+ </item>
<tag><c>global_groups = [GroupTuple]</c></tag>
<item>
<p>Defines global groups, see
diff --git a/lib/kernel/doc/src/net_adm.xml b/lib/kernel/doc/src/net_adm.xml
index 3009b1913d..4ef9d361f6 100644
--- a/lib/kernel/doc/src/net_adm.xml
+++ b/lib/kernel/doc/src/net_adm.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -88,8 +89,8 @@
<func>
<name name="world" arity="0"/>
<name name="world" arity="1"/>
- <type name="verbosity"/>
<fsummary>Lookup and connect to all nodes at all hosts in <c>.hosts.erlang</c></fsummary>
+ <type name="verbosity"/>
<desc>
<p>This function calls <c>names(Host)</c> for all hosts which
are specified in the Erlang host file <c>.hosts.erlang</c>,
@@ -109,8 +110,8 @@
<func>
<name name="world_list" arity="1"/>
<name name="world_list" arity="2"/>
- <type name="verbosity"/>
<fsummary>Lookup and connect to all nodes at specified hosts</fsummary>
+ <type name="verbosity"/>
<desc>
<p>As <c>world/0,1</c>, but the hosts are given as argument
instead of being read from <c>.hosts.erlang</c>.</p>
diff --git a/lib/kernel/doc/src/net_kernel.xml b/lib/kernel/doc/src/net_kernel.xml
index f5103136a1..311e0d8ea4 100644
--- a/lib/kernel/doc/src/net_kernel.xml
+++ b/lib/kernel/doc/src/net_kernel.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -62,11 +63,16 @@
<funcs>
<func>
<name name="allow" arity="1"/>
- <fsummary>Limit access to a specified set of nodes</fsummary>
+ <fsummary>Permit access to a specified set of nodes</fsummary>
<desc>
- <p>Limits access to the specified set of nodes. Any access
- attempts made from (or to) nodes not in <c><anno>Nodes</anno></c> will be
- rejected.</p>
+ <p>Permits access to the specified set of nodes.</p>
+ <p>Before the first call to <c>allow/1</c>, any node with the correct
+ cookie can be connected. When <c>allow/1</c> is called, a list
+ of allowed nodes is established. Any access attempts made from (or to)
+ nodes not in that list will be rejected.</p>
+ <p>Subsequent calls to <c>allow/1</c> will add the specified nodes
+ to the list of allowed nodes. It is not possible to remove nodes
+ from the list.</p>
<p>Returns <c>error</c> if any element in <c><anno>Nodes</anno></c> is not
an atom.</p>
</desc>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 6f7f18a8e7..cf5777d4be 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,334 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p><c>code:load_abs([10100])</c> would bring down the
+ entire runtime system and create a crash dump. Corrected
+ to generate an error exception in the calling
+ process.</p>
+ <p>Also corrected specs for code loading functions and
+ added more information in the documentation about the
+ error reasons returned by code-loading functions.</p>
+ <p>
+ Own Id: OTP-9375</p>
+ </item>
+ <item>
+ <p>
+ <seealso
+ marker="kernel:gen_tcp#accept/2"><c>gen_tcp:accept/2</c></seealso>
+ was not <seealso
+ marker="erts:time_correction#Time_Warp_Safe_Code">time
+ warp safe</seealso>. This since it used the same time as
+ returned by <seealso
+ marker="erts:erlang#now/0"><c>erlang:now/0</c></seealso>
+ when calculating timeout. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-13254 Aux Id: OTP-11997, OTP-13222 </p>
+ </item>
+ <item>
+ <p> Correct the contract for <c>inet:getifaddrs/1</c>.
+ </p>
+ <p>
+ Own Id: OTP-13335 Aux Id: ERL-95 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Time warp safety improvements.</p>
+ <p>
+ Introduced the options <c>monotonic_timestamp</c>, and
+ <c>strict_monotonic_timestamp</c> to the trace,
+ sequential trace, and system profile functionality. This
+ since the already existing <c>timestamp</c> option is not
+ time warp safe.</p>
+ <p>
+ Introduced the option <c>safe_fixed_monotonic_time</c> to
+ <c>ets:info/2</c> and <c>dets:info/2</c>. This since the
+ already existing <c>safe_fixed</c> option is not time
+ warp safe.</p>
+ <p>
+ Own Id: OTP-13222 Aux Id: OTP-11997 </p>
+ </item>
+ <item>
+ <p>
+ Add validation callback for heart</p>
+ <p>
+ The erlang heart process may now have a validation
+ callback installed. The validation callback will be
+ executed, if present, before any heartbeat to heart port
+ program. If the validation fails, or stalls, no heartbeat
+ will be sent and the node will go down.</p>
+ <p>
+ With the option <c>'check_schedulers'</c> heart executes
+ a responsiveness check of the schedulers before a
+ heartbeat is sent to the port program. If the
+ responsiveness check fails, the heartbeat will not be
+ performed (as intended).</p>
+ <p>
+ Own Id: OTP-13250</p>
+ </item>
+ <item>
+ <p>
+ Clarify documentation of <c>net_kernel:allow/1</c></p>
+ <p>
+ Own Id: OTP-13299</p>
+ </item>
+ <item>
+ <p>
+ EPMD supports both IPv4 and IPv6</p>
+ <p>
+ Also affects oldest supported windows version.</p>
+ <p>
+ Own Id: OTP-13364</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 4.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Host name lookups though inet_res, the Erlang DNS
+ resolver, are now done case insensitively according to
+ RFC 4343. Patch by Holger Weiß.</p>
+ <p>
+ Own Id: OTP-12836</p>
+ </item>
+ <item>
+ <p>
+ IPv6 distribution handler has been updated to share code
+ with IPv4 so that all features are supported in IPv6 as
+ well. A bug when using an IPv4 address as hostname has
+ been fixed.</p>
+ <p>
+ Own Id: OTP-13040</p>
+ </item>
+ <item>
+ <p>
+ Caching of host names in the internal DNS resolver
+ inet_res has been made character case insensitive for
+ host names according to RFC 4343.</p>
+ <p>
+ Own Id: OTP-13083</p>
+ </item>
+ <item>
+ <p>Cooked file mode buffering has been fixed so
+ file:position/2 now works according to Posix on Posix
+ systems i.e. when file:position/2 returns an error the
+ file pointer is unaffected.</p> <p>The Windows system
+ documentation, however, is unclear on this point so the
+ documentation of file:position/2 still does not promise
+ anything.</p> <p>Cooked file mode file:pread/2,3 and
+ file:pwrite/2,3 have been corrected to honor character
+ encoding like the combination of file:position/2 and
+ file:read/2 or file:write/2 already does. This is
+ probably not very useful since the character
+ representation on the caller's side is latin1,
+ period.</p>
+ <p>
+ Own Id: OTP-13155 Aux Id: PR#646 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add {line_delim, byte()} option to inet:setopts/2 and
+ decode_packet/3</p>
+ <p>
+ Own Id: OTP-12837</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 4.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>A mechanism for limiting the amount of text that the
+ built-in error logger events will produce has been
+ introduced. It is useful for limiting both the size of
+ log files and the CPU time used to produce them.</p>
+ <p>This mechanism is experimental in the sense that it
+ may be changed if it turns out that it does not solve the
+ problem it is supposed to solve. In that case, there may
+ be backward incompatible improvements to this
+ mechanism.</p>
+ <p>See the documentation for the config parameter
+ <c>error_logger_format_depth</c> in the Kernel
+ application for information about how to turn on this
+ feature.</p>
+ <p>
+ Own Id: OTP-12864</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 4.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix error handling in <c>file:read_line/1</c> for Unicode
+ contents.</p>
+ <p>
+ Own Id: OTP-12144</p>
+ </item>
+ <item>
+ <p>
+ Introduce <c>os:getenv/2</c> which is similar to
+ <c>os:getenv/1</c> but returns the passed default value
+ if the required environment variable is undefined.</p>
+ <p>
+ Own Id: OTP-12342</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to paste text in JCL mode (using
+ Ctrl-Y) that has been copied in the previous shell
+ session. Also a bug that caused the JCL mode to crash
+ when pasting text has been fixed.</p>
+ <p>
+ Own Id: OTP-12673</p>
+ </item>
+ <item>
+ <p>
+ Ensure that each segment of an IPv6 address when parsed
+ from a string has a maximum of 4 hex digits</p>
+ <p>
+ Own Id: OTP-12773</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New BIF: <c>erlang:get_keys/0</c>, lists all keys
+ associated with the process dictionary. Note:
+ <c>erlang:get_keys/0</c> is auto-imported.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12151 Aux Id: seq12521 </p>
+ </item>
+ <item>
+ <p>
+ The internal group to user_drv protocol has been changed
+ to be synchronous in order to guarantee that output sent
+ to a process implementing the user_drv protocol is
+ printed before replying. This protocol is used by the
+ standard_output device and the ssh application when
+ acting as a client. </p>
+ <p>
+ This change changes the previous unlimited buffer when
+ printing to standard_io and other devices that end up in
+ user_drv to 1KB.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12240</p>
+ </item>
+ <item>
+ <p>The <c>inflateInit/2</c> and <c>deflateInit/6</c>
+ functions now accepts a WindowBits argument equal to 8
+ and -8.</p>
+ <p>
+ Own Id: OTP-12564</p>
+ </item>
+ <item>
+ <p>
+ Map error logger warnings to warning messages by default.</p>
+ <p>
+ Own Id: OTP-12755</p>
+ </item>
+ <item>
+ <p>
+ Map beam error logger warnings to warning messages by
+ default. Previously these messages were mapped to the
+ error channel by default.</p>
+ <p>
+ Own Id: OTP-12781</p>
+ </item>
+ <item>
+ <p>
+ gen_tcp:shutdown/2 is now asynchronous</p>
+ <p>
+ This solves the following problems with the old
+ implementation:</p>
+ <p>
+ It doesn't block when the TCP peer is idle or slow. This
+ is the expected behaviour when shutdown() is called: the
+ caller needs to be able to continue reading from the
+ socket, not be prevented from doing so.</p>
+ <p>
+ It doesn't truncate the output. The current version of
+ gen_tcp:shutdown/2 will truncate any outbound data in the
+ driver queue after about 10 seconds if the TCP peer is
+ idle of slow. Worse yet, it doesn't even inform anyone
+ that the data has been truncated: 'ok' is returned to the
+ caller; and a FIN rather than an RST is sent to the TCP
+ peer.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12797</p>
+ </item>
+ <item>
+ <p>
+ There are many cases where user code needs to be able to
+ distinguish between a socket that was closed normally and
+ one that was aborted. Setting the option
+ {show_econnreset, true} enables the user to receive
+ ECONNRESET errors on both active and passive sockets.</p>
+ <p>
+ Own Id: OTP-12843</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 3.2.0.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The 'raw' socket option could not be used multiple times
+ in one call to any e.g gen_tcp function because only one
+ of the occurrences were used. This bug has been fixed,
+ and also a small bug concerning propagating error codes
+ from within inet:setopts/2.</p>
+ <p>Own Id: OTP-11482 Aux Id: seq12872 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+
<section><title>Kernel 3.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -1063,7 +1392,7 @@
</item>
<item>
<p> Fix returned error from gen_tcp:accept/1,2 when
- running out of ports
+ running out of ports.</p>
<p>
The {error, enfile} return value is badly misleading and
confusing for this case, since the Posix ENFILE errno
@@ -1072,7 +1401,7 @@
{error, system_limit}, which is consistent with e.g.
various file(3) functions. inet:format_error/1 has also
been updated to support system_limit in the same manner
- as file:format_error/1. (Thanks to Per Hedeland)</p></p>
+ as file:format_error/1. (Thanks to Per Hedeland)</p>
<p>
Own Id: OTP-9990</p>
</item>
@@ -1267,7 +1596,6 @@
Own Id: OTP-9764</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -1278,7 +1606,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/kernel/doc/src/notes_history.xml b/lib/kernel/doc/src/notes_history.xml
index 58d5109774..97ff3e7400 100644
--- a/lib/kernel/doc/src/notes_history.xml
+++ b/lib/kernel/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml
index 2b57e75023..682d4a2eac 100644
--- a/lib/kernel/doc/src/os.xml
+++ b/lib/kernel/doc/src/os.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -100,6 +101,19 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
</desc>
</func>
<func>
+ <name name="getenv" arity="2"/>
+ <fsummary>Get the value of an environment variable</fsummary>
+ <desc>
+ <p>Returns the <c><anno>Value</anno></c> of the environment variable
+ <c><anno>VarName</anno></c>, or <c>DefaultValue</c> if the environment variable
+ is undefined.</p>
+ <p>If Unicode file name encoding is in effect (see the <seealso
+ marker="erts:erl#file_name_encoding">erl manual
+ page</seealso>), the strings (both <c><anno>VarName</anno></c> and
+ <c><anno>Value</anno></c>) may contain characters with codepoints > 255.</p>
+ </desc>
+ </func>
+ <func>
<name name="getpid" arity="0"/>
<fsummary>Return the process identifier of the emulator process</fsummary>
<desc>
@@ -129,14 +143,49 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
</desc>
</func>
<func>
+ <name name="system_time" arity="0"/>
+ <fsummary>Current OS system time</fsummary>
+ <desc>
+ <p>Returns current
+ <seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso>
+ in <c>native</c>
+ <seealso marker="erts:erlang#type_time_unit">time unit</seealso>.</p>
+
+ <note><p>This time is <em>not</em> a monotonically increasing time.</p></note>
+ </desc>
+ </func>
+ <func>
+ <name name="system_time" arity="1"/>
+ <fsummary>Current OS system time</fsummary>
+ <desc>
+ <p>Returns current
+ <seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso>
+ converted into the <c><anno>Unit</anno></c> passed as argument.</p>
+
+ <p>Calling <c>os:system_time(<anno>Unit</anno>)</c> is equivalent to:
+ <seealso marker="erts:erlang#convert_time_unit/3"><c>erlang:convert_time_unit</c></seealso><c>(</c><seealso marker="#system_time/0"><c>os:system_time()</c></seealso><c>,
+ native, <anno>Unit</anno>)</c>.</p>
+
+ <note><p>This time is <em>not</em> a monotonically increasing time.</p></note>
+ </desc>
+ </func>
+ <func>
<name name="timestamp" arity="0"/>
+ <fsummary>Current OS system time on the erlang:timestamp/0 format</fsummary>
<type_desc variable="Timestamp">Timestamp = {MegaSecs, Secs, MicroSecs}</type_desc>
- <fsummary>Returna a timestamp from the OS in the erlang:now/0 format</fsummary>
<desc>
- <p>Returns a tuple in the same format as <seealso marker="erts:erlang#now/0">erlang:now/0</seealso>. The difference is that this function returns what the operating system thinks (a.k.a. the wall clock time) without any attempts at time correction. The result of two different calls to this function is <em>not</em> guaranteed to be different.</p>
- <p>The most obvious use for this function is logging. The tuple can be used together with the function <seealso marker="stdlib:calendar#now_to_universal_time/1">calendar:now_to_universal_time/1</seealso>
-or <seealso marker="stdlib:calendar#now_to_local_time/1">calendar:now_to_local_time/1</seealso> to get calendar time. Using the calendar time together with the <c>MicroSecs</c> part of the return tuple from this function allows you to log timestamps in high resolution and consistent with the time in the rest of the operating system.</p>
- <p>Example of code formatting a string in the format &quot;DD Mon YYYY HH:MM:SS.mmmmmm&quot;, where DD is the day of month, Mon is the textual month name, YYYY is the year, HH:MM:SS is the time and mmmmmm is the microseconds in six positions:</p>
+ <p>Returns current
+ <seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso>
+ in the same format as <seealso marker="erts:erlang#timestamp/0">erlang:timestamp/0</seealso>.
+ The tuple can be used together with the function
+ <seealso marker="stdlib:calendar#now_to_universal_time/1">calendar:now_to_universal_time/1</seealso>
+ or <seealso marker="stdlib:calendar#now_to_local_time/1">calendar:now_to_local_time/1</seealso> to
+ get calendar time. Using the calendar time together with the <c>MicroSecs</c> part of the return
+ tuple from this function allows you to log timestamps in high resolution and consistent with the
+ time in the rest of the operating system.</p>
+ <p>Example of code formatting a string in the format &quot;DD Mon YYYY HH:MM:SS.mmmmmm&quot;, where
+ DD is the day of month, Mon is the textual month name, YYYY is the year, HH:MM:SS is the time and
+ mmmmmm is the microseconds in six positions:</p>
<code>
-module(print_time).
-export([format_utc_timestamp/0]).
@@ -155,6 +204,9 @@ format_utc_timestamp() ->
1> <input>io:format("~s~n",[print_time:format_utc_timestamp()]).</input>
29 Apr 2009 9:55:30.051711
</pre>
+ <p>OS system time can also be retreived by
+ <seealso marker="#system_time/0"><c>os:system_time/0</c></seealso>,
+ and <seealso marker="#system_time/1"><c>os:system_time/1</c></seealso>.</p>
</desc>
</func>
<func>
diff --git a/lib/kernel/doc/src/part_notes.xml b/lib/kernel/doc/src/part_notes.xml
index d196878f19..ec19cfa80d 100644
--- a/lib/kernel/doc/src/part_notes.xml
+++ b/lib/kernel/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/part_notes_history.xml b/lib/kernel/doc/src/part_notes_history.xml
index ec4998408e..87c32c3fba 100644
--- a/lib/kernel/doc/src/part_notes_history.xml
+++ b/lib/kernel/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/doc/src/pg2.xml b/lib/kernel/doc/src/pg2.xml
index 5eb63c1ef6..8c2fdb4cd3 100644
--- a/lib/kernel/doc/src/pg2.xml
+++ b/lib/kernel/doc/src/pg2.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -34,11 +35,8 @@
<module>pg2</module>
<modulesummary>Distributed Named Process Groups</modulesummary>
<description>
- <p>This module implements process groups. The groups in this
- module differ from the groups in the module <c>pg</c> in several
- ways. In <c>pg</c>, each message is sent to all members in the
- group. In this module, each message may be sent to one, some, or
- all members.
+ <p>This module implements process groups. Each message may be sent
+ to one, some, or all members of the group.
</p>
<p>A group of processes can be accessed by a common name. For
example, if there is a group named <c>foobar</c>, there can be a
@@ -160,8 +158,7 @@
<section>
<title>See Also</title>
- <p><seealso marker="kernel_app">kernel(6)</seealso>,
- <seealso marker="stdlib:pg">pg(3)</seealso></p>
+ <p><seealso marker="kernel_app">kernel(6)</seealso></p>
</section>
</erlref>
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
index bd25d1e78d..7eb48a5f1d 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/kernel/doc/src/ref_man.xml.src b/lib/kernel/doc/src/ref_man.xml.src
index bd25d1e78d..7eb48a5f1d 100644
--- a/lib/kernel/doc/src/ref_man.xml.src
+++ b/lib/kernel/doc/src/ref_man.xml.src
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/kernel/doc/src/rpc.xml b/lib/kernel/doc/src/rpc.xml
index e6c896f18d..c323a84e50 100644
--- a/lib/kernel/doc/src/rpc.xml
+++ b/lib/kernel/doc/src/rpc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/seq_trace.xml b/lib/kernel/doc/src/seq_trace.xml
index 45df06e0b4..f4fcd222ec 100644
--- a/lib/kernel/doc/src/seq_trace.xml
+++ b/lib/kernel/doc/src/seq_trace.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -126,6 +127,35 @@ seq_trace:set_token(OldToken), % activate the trace token again
enables/disables a timestamp to be generated for each
traced event. Default is <c>false</c>.</p>
</item>
+ <tag><c>set_token(strict_monotonic_timestamp, <anno>Bool</anno>)</c></tag>
+ <item>
+ <p>A trace token flag (<c>true | false</c>) which
+ enables/disables a strict monotonic timestamp to be generated
+ for each traced event. Default is <c>false</c>. Timestamps will
+ consist of
+ <seealso marker="erts:time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso> and a monotonically increasing
+ integer. The time-stamp has the same format and value
+ as produced by <c>{erlang:monotonic_time(nano_seconds),
+ erlang:unique_integer([monotonic])}</c>.</p>
+ </item>
+ <tag><c>set_token(monotonic_timestamp, <anno>Bool</anno>)</c></tag>
+ <item>
+ <p>A trace token flag (<c>true | false</c>) which
+ enables/disables a strict monotonic timestamp to be generated
+ for each traced event. Default is <c>false</c>. Timestamps
+ will use
+ <seealso marker="erts:time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>. The time-stamp has the same
+ format and value as produced by
+ <c>erlang:monotonic_time(nano_seconds)</c>.</p>
+ </item>
+ <p>If multiple timestamp flags are passed, <c>timestamp</c> has
+ precedence over <c>strict_monotonic_timestamp</c> which
+ in turn has precedence over <c>monotonic_timestamp</c>. All
+ timestamp flags are remembered, so if two are passed
+ and the one with highest precedence later is disabled
+ the other one will become active.</p>
</taglist>
</desc>
</func>
diff --git a/lib/kernel/doc/src/user.xml b/lib/kernel/doc/src/user.xml
index df6dff9882..24119bea82 100644
--- a/lib/kernel/doc/src/user.xml
+++ b/lib/kernel/doc/src/user.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/doc/src/wrap_log_reader.xml b/lib/kernel/doc/src/wrap_log_reader.xml
index 5227b4d01c..c021f42cac 100644
--- a/lib/kernel/doc/src/wrap_log_reader.xml
+++ b/lib/kernel/doc/src/wrap_log_reader.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/kernel/doc/src/zlib_stub.xml b/lib/kernel/doc/src/zlib_stub.xml
index 5f5bfd56db..d1823b01aa 100644
--- a/lib/kernel/doc/src/zlib_stub.xml
+++ b/lib/kernel/doc/src/zlib_stub.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/kernel/examples/Makefile b/lib/kernel/examples/Makefile
index 21dfd0ec0e..26ec58f571 100644
--- a/lib/kernel/examples/Makefile
+++ b/lib/kernel/examples/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/kernel/examples/uds_dist/c_src/uds_drv.c b/lib/kernel/examples/uds_dist/c_src/uds_drv.c
index 9ad6b85a0f..8c028ba910 100644
--- a/lib/kernel/examples/uds_dist/c_src/uds_drv.c
+++ b/lib/kernel/examples/uds_dist/c_src/uds_drv.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -956,28 +957,24 @@ static void put_packet_length(char *b, int len)
/*
** Malloc wrappers
-** Note!
-** The function erl_exit is actually not a pert of the
-** driver interface, but it is very nice to use if one wants to halt
-** with a core and an erlang crash dump.
*/
static void *my_malloc(size_t size)
{
- void erl_exit(int, char *, ...);
void *ptr;
if ((ptr = driver_alloc(size)) == NULL) {
- erl_exit(1,"Could not allocate %lu bytes of memory",(unsigned long) size);
+ fprintf(stderr, "Could not allocate %lu bytes of memory",(unsigned long) size);
+ abort();
}
return ptr;
}
static void *my_realloc(void *ptr, size_t size)
{
- void erl_exit(int, char *, ...);
void *nptr;
if ((nptr = driver_realloc(ptr, size)) == NULL) {
- erl_exit(1,"Could not reallocate %lu bytes of memory",(unsigned long) size);
+ fprintf(stderr, "Could not reallocate %lu bytes of memory",(unsigned long) size);
+ abort();
}
return nptr;
}
diff --git a/lib/kernel/examples/uds_dist/src/uds_dist.erl b/lib/kernel/examples/uds_dist/src/uds_dist.erl
index 7a9c15a3c8..df29f99a29 100644
--- a/lib/kernel/examples/uds_dist/src/uds_dist.erl
+++ b/lib/kernel/examples/uds_dist/src/uds_dist.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/kernel/include/dist.hrl b/lib/kernel/include/dist.hrl
index 77556d1303..47d9459a19 100644
--- a/lib/kernel/include/dist.hrl
+++ b/lib/kernel/include/dist.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/include/dist_util.hrl b/lib/kernel/include/dist_util.hrl
index c3a7f97418..d5df2be4ec 100644
--- a/lib/kernel/include/dist_util.hrl
+++ b/lib/kernel/include/dist_util.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/include/file.hrl b/lib/kernel/include/file.hrl
index 69aec1ee36..7cf033f7f5 100644
--- a/lib/kernel/include/file.hrl
+++ b/lib/kernel/include/file.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/include/inet.hrl b/lib/kernel/include/inet.hrl
index 3e64d4bb79..d983fa9e72 100644
--- a/lib/kernel/include/inet.hrl
+++ b/lib/kernel/include/inet.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/include/inet_sctp.hrl b/lib/kernel/include/inet_sctp.hrl
index 169ba013aa..d6376e452e 100644
--- a/lib/kernel/include/inet_sctp.hrl
+++ b/lib/kernel/include/inet_sctp.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/include/net_address.hrl b/lib/kernel/include/net_address.hrl
index 9b9ea42931..9dd4b78cd4 100644
--- a/lib/kernel/include/net_address.hrl
+++ b/lib/kernel/include/net_address.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index c7c70ad257..57dacebde3 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index c4bef5188a..1abfbfb9ec 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 6635885aaf..b1ca2ea64f 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -490,7 +491,8 @@ init(Init, Kernel) ->
%% called during start-up of any app.
case check_conf_data(ConfData) of
ok ->
- _ = ets:new(ac_tab, [set, public, named_table]),
+ _ = ets:new(ac_tab, [set, public, named_table,
+ {read_concurrency,true}]),
S = #state{conf_data = ConfData},
{ok, KAppl} = make_appl(Kernel),
case catch load(S, KAppl) of
diff --git a/lib/kernel/src/application_master.erl b/lib/kernel/src/application_master.erl
index 7cdbe31ab2..85b7efc402 100644
--- a/lib/kernel/src/application_master.erl
+++ b/lib/kernel/src/application_master.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/application_master.hrl b/lib/kernel/src/application_master.hrl
index cd6d12c33c..f252ce8f16 100644
--- a/lib/kernel/src/application_master.hrl
+++ b/lib/kernel/src/application_master.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/application_starter.erl b/lib/kernel/src/application_starter.erl
index 564366f304..692681b515 100644
--- a/lib/kernel/src/application_starter.erl
+++ b/lib/kernel/src/application_starter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl
index eda35147d3..78cf1e77be 100644
--- a/lib/kernel/src/auth.erl
+++ b/lib/kernel/src/auth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -370,8 +371,8 @@ check_cookie1([], Result) ->
%% Creates a new, random cookie.
create_cookie(Name) ->
- {_, S1, S2} = now(),
- Seed = S2*10000+S1,
+ Seed = abs(erlang:monotonic_time()
+ bxor erlang:unique_integer()),
Cookie = random_cookie(20, Seed, []),
case file:open(Name, [write, raw]) of
{ok, File} ->
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 0eda558ed5..7237550786 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -76,10 +77,9 @@
%%----------------------------------------------------------------------------
-type load_error_rsn() :: 'badfile'
- | 'native_code'
| 'nofile'
| 'not_purged'
- | 'on_load'
+ | 'on_load_failure'
| 'sticky_directory'.
-type load_ret() :: {'error', What :: load_error_rsn()}
| {'module', Module :: module()}.
@@ -107,7 +107,7 @@ is_module_native(_) ->
-spec make_stub_module(Module, Beam, Info) -> Module when
Module :: module(),
Beam :: binary(),
- Info :: {list(), list()}.
+ Info :: {list(), list(), binary()}.
make_stub_module(_, _, _) ->
erlang:nif_error(undef).
@@ -134,14 +134,16 @@ load_file(Mod) when is_atom(Mod) ->
-spec ensure_loaded(Module) -> {module, Module} | {error, What} when
Module :: module(),
- What :: embedded | badfile | native_code | nofile | on_load.
+ What :: embedded | badfile | nofile | on_load_failure.
ensure_loaded(Mod) when is_atom(Mod) ->
call({ensure_loaded,Mod}).
%% XXX File as an atom is allowed only for backwards compatibility.
-spec load_abs(Filename) -> load_ret() when
Filename :: file:filename().
-load_abs(File) when is_list(File); is_atom(File) -> call({load_abs,File,[]}).
+load_abs(File) when is_list(File); is_atom(File) ->
+ Mod = list_to_atom(filename:basename(File)),
+ call({load_abs,File,Mod}).
%% XXX Filename is also an atom(), e.g. 'cover_compiled'
-spec load_abs(Filename :: loaded_filename(), Module :: module()) -> load_ret().
@@ -339,7 +341,8 @@ do_start(Flags) ->
ok
end,
%% Quietly load native code for all modules loaded so far
- catch load_native_code_for_all_loaded(),
+ Architecture = erlang:system_info(hipe_architecture),
+ load_native_code_for_all_loaded(Architecture),
Ok2;
Other ->
Other
@@ -550,18 +553,43 @@ has_ext(Ext, Extlen, File) ->
_ -> false
end.
--spec load_native_code_for_all_loaded() -> ok.
-load_native_code_for_all_loaded() ->
- Architecture = erlang:system_info(hipe_architecture),
- ChunkName = hipe_unified_loader:chunk_name(Architecture),
- lists:foreach(fun({Module, BeamFilename}) ->
- case code:is_module_native(Module) of
- false ->
- case beam_lib:chunks(BeamFilename, [ChunkName]) of
- {ok,{_,[{_,Bin}]}} when is_binary(Bin) ->
- load_native_partial(Module, Bin);
- {error, beam_lib, _} -> ok
- end;
- true -> ok
- end
- end, all_loaded()).
+%%%
+%%% Silently load native code for all modules loaded so far.
+%%%
+
+load_native_code_for_all_loaded(undefined) ->
+ ok;
+load_native_code_for_all_loaded(Architecture) ->
+ try hipe_unified_loader:chunk_name(Architecture) of
+ ChunkTag ->
+ Loaded = all_loaded(),
+ _ = spawn(fun() -> load_all_native(Loaded, ChunkTag) end),
+ ok
+ catch
+ _:_ ->
+ ok
+ end.
+
+load_all_native(Loaded, ChunkTag) ->
+ catch load_all_native_1(Loaded, ChunkTag).
+
+load_all_native_1([{_,preloaded}|T], ChunkTag) ->
+ load_all_native_1(T, ChunkTag);
+load_all_native_1([{Mod,BeamFilename}|T], ChunkTag) ->
+ case code:is_module_native(Mod) of
+ false ->
+ %% prim_file is faster than file and the file server may
+ %% not be started yet.
+ {ok,Beam} = prim_file:read_file(BeamFilename),
+ case code:get_chunk(Beam, ChunkTag) of
+ undefined ->
+ ok;
+ NativeCode when is_binary(NativeCode) ->
+ _ = load_native_partial(Mod, NativeCode),
+ ok
+ end;
+ true -> ok
+ end,
+ load_all_native_1(T, ChunkTag);
+load_all_native_1([], _) ->
+ ok.
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 819554ce74..614219794c 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -312,7 +313,7 @@ handle_call(get_path, {_From,_Tag}, S) ->
{reply,S#state.path,S};
%% Messages to load, delete and purge modules/files.
-handle_call({load_abs,File,Mod}, Caller, S) ->
+handle_call({load_abs,File,Mod}, Caller, S) when is_atom(Mod) ->
case modp(File) of
false ->
{reply,{error,badarg},S};
@@ -324,12 +325,15 @@ handle_call({load_binary,Mod,File,Bin}, Caller, S) ->
do_load_binary(Mod, File, Bin, Caller, S);
handle_call({load_native_partial,Mod,Bin}, {_From,_Tag}, S) ->
- Result = (catch hipe_unified_loader:load(Mod, Bin)),
+ Architecture = erlang:system_info(hipe_architecture),
+ Result = (catch hipe_unified_loader:load(Mod, Bin, Architecture)),
Status = hipe_result_to_status(Result),
{reply,Status,S};
handle_call({load_native_sticky,Mod,Bin,WholeModule}, {_From,_Tag}, S) ->
- Result = (catch hipe_unified_loader:load_module(Mod, Bin, WholeModule)),
+ Architecture = erlang:system_info(hipe_architecture),
+ Result = (catch hipe_unified_loader:load_module(Mod, Bin, WholeModule,
+ Architecture)),
Status = hipe_result_to_status(Result),
{reply,Status,S};
@@ -1218,15 +1222,10 @@ modp(Atom) when is_atom(Atom) -> true;
modp(List) when is_list(List) -> int_list(List);
modp(_) -> false.
-load_abs(File, Mod0, Caller, St) ->
+load_abs(File, Mod, Caller, St) ->
Ext = objfile_extension(),
FileName0 = lists:concat([File, Ext]),
FileName = absname(FileName0),
- Mod = if Mod0 =:= [] ->
- list_to_atom(filename:basename(FileName0, Ext));
- true ->
- Mod0
- end,
case erl_prim_loader:get_file(FileName) of
{ok,Bin,_} ->
try_load_module(FileName, Mod, Bin, Caller, St);
@@ -1256,33 +1255,43 @@ try_load_module(File, Mod, Bin, {From,_}=Caller, St0) ->
try_load_module_1(File, Mod, Bin, Caller, #state{moddb=Db}=St) ->
case is_sticky(Mod, Db) of
true -> %% Sticky file reject the load
- error_msg("Can't load module that resides in sticky dir\n",[]),
+ error_msg("Can't load module '~w' that resides in sticky dir\n",[Mod]),
{reply,{error,sticky_directory},St};
false ->
- case catch load_native_code(Mod, Bin) of
- {module,Mod} = Module ->
- ets:insert(Db, {Mod,File}),
- {reply,Module,St};
- no_native ->
- case erlang:load_module(Mod, Bin) of
- {module,Mod} = Module ->
- ets:insert(Db, {Mod,File}),
- post_beam_load(Mod),
- {reply,Module,St};
- {error,on_load} ->
- handle_on_load(Mod, File, Caller, St);
- {error,What} = Error ->
- error_msg("Loading of ~ts failed: ~p\n", [File, What]),
- {reply,Error,St}
- end;
- Error ->
- error_msg("Native loading of ~ts failed: ~p\n",
- [File,Error]),
- {reply,ok,St}
- end
+ Architecture = erlang:system_info(hipe_architecture),
+ try_load_module_2(File, Mod, Bin, Caller, Architecture, St)
+ end.
+
+try_load_module_2(File, Mod, Bin, Caller, undefined, St) ->
+ try_load_module_3(File, Mod, Bin, Caller, undefined, St);
+try_load_module_2(File, Mod, Bin, Caller, Architecture,
+ #state{moddb=Db}=St) ->
+ case catch load_native_code(Mod, Bin, Architecture) of
+ {module,Mod} = Module ->
+ ets:insert(Db, {Mod,File}),
+ {reply,Module,St};
+ no_native ->
+ try_load_module_3(File, Mod, Bin, Caller, Architecture, St);
+ Error ->
+ error_msg("Native loading of ~ts failed: ~p\n", [File,Error]),
+ {reply,ok,St}
+ end.
+
+try_load_module_3(File, Mod, Bin, Caller, Architecture,
+ #state{moddb=Db}=St) ->
+ case erlang:load_module(Mod, Bin) of
+ {module,Mod} = Module ->
+ ets:insert(Db, {Mod,File}),
+ post_beam_load(Mod, Architecture),
+ {reply,Module,St};
+ {error,on_load} ->
+ handle_on_load(Mod, File, Caller, St);
+ {error,What} = Error ->
+ error_msg("Loading of ~ts failed: ~p\n", [File, What]),
+ {reply,Error,St}
end.
-load_native_code(Mod, Bin) ->
+load_native_code(Mod, Bin, Architecture) ->
%% During bootstrapping of Open Source Erlang, we don't have any hipe
%% loader modules, but the Erlang emulator might be hipe enabled.
%% Therefore we must test for that the loader modules are available
@@ -1291,7 +1300,8 @@ load_native_code(Mod, Bin) ->
false ->
no_native;
true ->
- Result = hipe_unified_loader:load_native_code(Mod, Bin),
+ Result = hipe_unified_loader:load_native_code(Mod, Bin,
+ Architecture),
case Result of
{module,_} ->
put(?ANY_NATIVE_CODE_LOADED, true);
@@ -1310,12 +1320,12 @@ hipe_result_to_status(Result) ->
{error,Result}
end.
-post_beam_load(Mod) ->
- %% post_beam_load/1 can potentially be very expensive because it
+post_beam_load(Mod, Architecture) ->
+ %% post_beam_load/2 can potentially be very expensive because it
%% blocks multi-scheduling; thus we want to avoid the call if we
%% know that it is not needed.
case get(?ANY_NATIVE_CODE_LOADED) of
- true -> hipe_unified_loader:post_beam_load(Mod);
+ true -> hipe_unified_loader:post_beam_load(Mod, Architecture);
false -> ok
end.
diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl
index 9a7726cfa0..f5450f30af 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl
index 242a25a7a6..6c0aea070f 100644
--- a/lib/kernel/src/disk_log.hrl
+++ b/lib/kernel/src/disk_log.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl
index 59f5cad001..2e61363aa6 100644
--- a/lib/kernel/src/disk_log_1.erl
+++ b/lib/kernel/src/disk_log_1.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -78,6 +79,7 @@ log(FdC, FileName, X) ->
logl(X) ->
logl(X, [], 0).
+-dialyzer({no_improper_lists, logl/3}).
logl([X | T], Bs, Size) ->
Sz = byte_size(X),
BSz = <<Sz:?SIZESZ/unit:8>>,
@@ -1141,6 +1143,7 @@ write_index_file(read_write, FName, NewFile, OldFile, OldCnt) ->
file_error(FileName, E)
end.
+-dialyzer({no_improper_lists, to_8_bytes/4}).
to_8_bytes(<<N:32,T/binary>>, NT, FileName, Fd) ->
to_8_bytes(T, [NT | <<N:64>>], FileName, Fd);
to_8_bytes(B, NT, _FileName, _Fd) when byte_size(B) =:= 0 ->
@@ -1275,6 +1278,7 @@ ext_split_bins(CurB, MaxB, FirstPos, Bins) ->
MaxBs = MaxB - CurB, IsFirst = CurB =:= FirstPos,
ext_split_bins(MaxBs, IsFirst, [], Bins, 0, 0).
+-dialyzer({no_improper_lists, ext_split_bins/6}).
ext_split_bins(MaxBs, IsFirst, First, [X | Last], Bs, N) ->
NBs = Bs + byte_size(X),
if
@@ -1295,6 +1299,7 @@ int_split_bins(CurB, MaxB, FirstPos, Bins) ->
MaxBs = MaxB - CurB, IsFirst = CurB =:= FirstPos,
int_split_bins(MaxBs, IsFirst, [], Bins, 0, 0).
+-dialyzer({no_improper_lists, int_split_bins/6}).
int_split_bins(MaxBs, IsFirst, First, [X | Last], Bs, N) ->
Sz = byte_size(X),
NBs = Bs + Sz + ?HEADERSZ,
diff --git a/lib/kernel/src/disk_log_server.erl b/lib/kernel/src/disk_log_server.erl
index 45334912eb..735f1e5ceb 100644
--- a/lib/kernel/src/disk_log_server.erl
+++ b/lib/kernel/src/disk_log_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/disk_log_sup.erl b/lib/kernel/src/disk_log_sup.erl
index 96e37b678c..c09b3f94d1 100644
--- a/lib/kernel/src/disk_log_sup.erl
+++ b/lib/kernel/src/disk_log_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/dist_ac.erl b/lib/kernel/src/dist_ac.erl
index a4d4ae386c..f649f33a53 100644
--- a/lib/kernel/src/dist_ac.erl
+++ b/lib/kernel/src/dist_ac.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index b127fe2e33..c9fc26d62c 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -298,7 +299,7 @@ shutdown(_Module, _Line, _Data, Reason) ->
exit(Reason).
%% Use this line to debug connection.
%% Set net_kernel verbose = 1 as well.
-%% exit({Reason, ?MODULE, _Line, _Data, erlang:now()}).
+%% exit({Reason, ?MODULE, _Line, _Data, erlang:timestamp()}).
flush_down() ->
@@ -373,7 +374,9 @@ gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) ->
%% gen_challenge() returns a "random" number
%% ---------------------------------------------------------------
gen_challenge() ->
- {A,B,C} = erlang:now(),
+ A = erlang:phash2([erlang:node()]),
+ B = erlang:monotonic_time(),
+ C = erlang:unique_integer(),
{D,_} = erlang:statistics(reductions),
{E,_} = erlang:statistics(runtime),
{F,_} = erlang:statistics(wall_clock),
diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl
index ef09d86ca4..4076fab86d 100644
--- a/lib/kernel/src/erl_boot_server.erl
+++ b/lib/kernel/src/erl_boot_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/erl_ddll.erl b/lib/kernel/src/erl_ddll.erl
index e03d280cd8..6180510bdd 100644
--- a/lib/kernel/src/erl_ddll.erl
+++ b/lib/kernel/src/erl_ddll.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/erl_distribution.erl b/lib/kernel/src/erl_distribution.erl
index 3c4429129e..99db7a8bf0 100644
--- a/lib/kernel/src/erl_distribution.erl
+++ b/lib/kernel/src/erl_distribution.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl
index f6e2ca0954..c6202dd796 100644
--- a/lib/kernel/src/erl_epmd.erl
+++ b/lib/kernel/src/erl_epmd.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,7 +32,7 @@
%% External exports
-export([start/0, start_link/0, stop/0, port_please/2,
port_please/3, names/0, names/1,
- register_node/2, open/0, open/1, open/2]).
+ register_node/2, register_node/3, open/0, open/1, open/2]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -101,7 +102,9 @@ names(EpmdAddr) ->
register_node(Name, PortNo) ->
- gen_server:call(erl_epmd, {register, Name, PortNo}, infinity).
+ register_node(Name, PortNo, inet).
+register_node(Name, PortNo, Family) ->
+ gen_server:call(erl_epmd, {register, Name, PortNo, Family}, infinity).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_server
@@ -119,10 +122,10 @@ init(_) ->
-spec handle_call(calls(), term(), state()) ->
{'reply', term(), state()} | {'stop', 'shutdown', 'ok', state()}.
-handle_call({register, Name, PortNo}, _From, State) ->
+handle_call({register, Name, PortNo, Family}, _From, State) ->
case State#state.socket of
P when P < 0 ->
- case do_register_node(Name, PortNo) of
+ case do_register_node(Name, PortNo, Family) of
{alive, Socket, Creation} ->
S = State#state{socket = Socket,
port_no = PortNo,
@@ -205,8 +208,12 @@ open({A,B,C,D,E,F,G,H}=EpmdAddr, Timeout) when ?ip6(A,B,C,D,E,F,G,H) ->
close(Socket) ->
gen_tcp:close(Socket).
-do_register_node(NodeName, TcpPort) ->
- case open() of
+do_register_node(NodeName, TcpPort, Family) ->
+ Localhost = case Family of
+ inet -> open({127,0,0,1});
+ inet6 -> open({0,0,0,0,0,0,0,1})
+ end,
+ case Localhost of
{ok, Socket} ->
Name = to_string(NodeName),
Extra = "",
diff --git a/lib/kernel/src/erl_epmd.hrl b/lib/kernel/src/erl_epmd.hrl
index 5a50fda508..f3585fea5e 100644
--- a/lib/kernel/src/erl_epmd.hrl
+++ b/lib/kernel/src/erl_epmd.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/erl_reply.erl b/lib/kernel/src/erl_reply.erl
index f0be3ee654..ba046980f6 100644
--- a/lib/kernel/src/erl_reply.erl
+++ b/lib/kernel/src/erl_reply.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl
index 40aabba803..095e1163f7 100644
--- a/lib/kernel/src/error_handler.erl
+++ b/lib/kernel/src/error_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl
index b8fbf02feb..eb231fd155 100644
--- a/lib/kernel/src/error_logger.erl
+++ b/lib/kernel/src/error_logger.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl
index ef605d0bfe..39308c0043 100644
--- a/lib/kernel/src/erts_debug.erl
+++ b/lib/kernel/src/erts_debug.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -20,7 +21,7 @@
%% Low-level debugging support. EXPERIMENTAL!
--export([size/1,df/1,df/2,df/3]).
+-export([size/1,df/1,df/2,df/3,ic/1]).
%% This module contains the following *experimental* BIFs:
%% disassemble/1
@@ -33,7 +34,7 @@
-export([breakpoint/2, disassemble/1, display/1, dist_ext_to_term/2,
dump_monitors/1, dump_links/1, flat_size/1,
get_internal_state/1, instructions/0, lock_counters/1,
- same/2, set_internal_state/2]).
+ map_info/1, same/2, set_internal_state/2]).
-spec breakpoint(MFA, Flag) -> non_neg_integer() when
MFA :: {Module :: module(),
@@ -114,6 +115,19 @@ get_internal_state(_) ->
instructions() ->
erlang:nif_error(undef).
+-spec ic(F) -> Result when
+ F :: function(),
+ Result :: term().
+
+ic(F) when is_function(F) ->
+ Is0 = erlang:system_info(instruction_counts),
+ R = F(),
+ Is1 = erlang:system_info(instruction_counts),
+ Is = lists:keysort(2,[{I,C1 - C0}||{{I,C1},{I,C0}} <- lists:zip(Is1,Is0)]),
+ _ = [io:format("~12w ~w~n", [C,I])||{I,C}<-Is],
+ io:format("Total: ~w~n",[lists:sum([C||{_I,C}<-Is])]),
+ R.
+
-spec lock_counters(info) -> term();
(clear) -> ok;
({copy_save, boolean()}) -> boolean();
@@ -164,8 +178,10 @@ set_internal_state(_, _) ->
-spec size(term()) -> non_neg_integer().
+-record(s, {seen, maps}).
+
size(Term) ->
- {Sum,_} = size(Term, gb_trees:empty(), 0),
+ {Sum,_} = size(Term, #s{seen=gb_trees:empty(),maps=[]}, 0),
Sum.
size([H|T]=Term, Seen0, Sum0) ->
@@ -209,10 +225,24 @@ tuple_size(I, Sz, Tuple, Seen0, Sum0) ->
tuple_size(I+1, Sz, Tuple, Seen, Sum).
map_size(Map,Seen0,Sum0) ->
- Kt = erts_internal:map_to_tuple_keys(Map),
- Vs = maps:values(Map),
- {Sum1,Seen1} = size(Kt,Seen0,Sum0),
- fold_size(Vs,Seen1,Sum1+length(Vs)+3).
+ %% Danger:
+ %% The internal nodes from erts_internal:map_hashmap_children/1
+ %% is not allowed to leak anywhere. They are only allowed in
+ %% containers (cons cells and tuples, not maps), in gc and
+ %% in erts_debug:same/2
+ case erts_internal:map_type(Map) of
+ flatmap ->
+ Kt = erts_internal:map_to_tuple_keys(Map),
+ Vs = maps:values(Map),
+ {Sum1,Seen1} = size(Kt,Seen0,Sum0),
+ fold_size(Vs,Seen1,Sum1+length(Vs)+3);
+ hashmap ->
+ Cs = erts_internal:map_hashmap_children(Map),
+ fold_size(Cs,Seen0,Sum0+length(Cs)+2);
+ hashmap_node ->
+ Cs = erts_internal:map_hashmap_children(Map),
+ fold_size(Cs,Seen0,Sum0+length(Cs)+1)
+ end.
fun_size(Fun, Seen, Sum) ->
case erlang:fun_info(Fun, type) of
@@ -229,13 +259,18 @@ fold_size([H|T], Seen0, Sum0) ->
fold_size(T, Seen, Sum);
fold_size([], Seen, Sum) -> {Sum,Seen}.
-remember_term(Term, Seen) ->
- case gb_trees:lookup(Term, Seen) of
- none -> gb_trees:insert(Term, [Term], Seen);
+remember_term(Term, #s{maps=Ms}=S) when is_map(Term) ->
+ case is_term_seen(Term, Ms) of
+ false -> S#s{maps=[Term|Ms]};
+ true -> seen
+ end;
+remember_term(Term, #s{seen=T}=S) ->
+ case gb_trees:lookup(Term,T) of
+ none -> S#s{seen=gb_trees:insert(Term,[Term],T)};
{value,Terms} ->
case is_term_seen(Term, Terms) of
- false -> gb_trees:update(Term, [Term|Terms], Seen);
- true -> seen
+ false -> S#s{seen=gb_trees:update(Term,[Term|Terms],T)};
+ true -> seen
end
end.
@@ -313,3 +348,9 @@ cont_dis(File, {Addr,Str,MFA}, MFA) ->
io:put_chars(File, binary_to_list(Str)),
cont_dis(File, erts_debug:disassemble(Addr), MFA);
cont_dis(_, {_,_,_}, _) -> ok.
+
+-spec map_info(Map) -> list() when
+ Map :: map().
+
+map_info(_) ->
+ erlang:nif_error(undef).
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 3d6665a36a..1007f04413 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -445,21 +446,15 @@ open(Item, ModeList) when is_list(ModeList) ->
case lists:member(raw, ModeList) of
%% Raw file, use ?PRIM_FILE to handle this file
true ->
- %% check if raw file mode is disabled
- case catch application:get_env(kernel, raw_files) of
- {ok,false} ->
- open(Item, lists:delete(raw, ModeList));
- _ -> % undefined | {ok,true}
- Args = [file_name(Item) | ModeList],
- case check_args(Args) of
- ok ->
- [FileName | _] = Args,
- %% We rely on the returned Handle (in {ok, Handle})
- %% being a pid() or a #file_descriptor{}
- ?PRIM_FILE:open(FileName, ModeList);
- Error ->
- Error
- end
+ Args = [file_name(Item) | ModeList],
+ case check_args(Args) of
+ ok ->
+ [FileName | _] = Args,
+ %% We rely on the returned Handle (in {ok, Handle})
+ %% being a pid() or a #file_descriptor{}
+ ?PRIM_FILE:open(FileName, ModeList);
+ Error ->
+ Error
end;
false ->
case lists:member(ram, ModeList) of
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index 0e9ff5bc0f..deb7b315b1 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -205,8 +206,8 @@ io_reply(From, ReplyAs, Reply) ->
file_request({advise,Offset,Length,Advise},
#state{handle=Handle}=State) ->
case ?PRIM_FILE:advise(Handle, Offset, Length, Advise) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
@@ -214,62 +215,91 @@ file_request({allocate, Offset, Length},
#state{handle = Handle} = State) ->
Reply = ?PRIM_FILE:allocate(Handle, Offset, Length),
{reply, Reply, State};
+file_request({pread,At,Sz}, State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ case get_chars(Sz, latin1, State) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ Other ->
+ Other
+ end;
file_request({pread,At,Sz},
- #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
+ #state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
- {ok,_Offs} ->
- case ?PRIM_FILE:read(Handle, Sz) of
- {ok,Bin} when ReadMode =:= list ->
- std_reply({ok,binary_to_list(Bin)}, State);
- Reply ->
- std_reply(Reply, State)
- end;
- Reply ->
- std_reply(Reply, State)
+ {error,_} = Reply ->
+ {error,Reply,State};
+ _ ->
+ case get_chars(Sz, latin1, State#state{buf= <<>>}) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ Other ->
+ Other
+ end
end;
+file_request({pwrite,At,Data},
+ #state{buf= <<>>}=State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ put_chars(Data, latin1, State);
file_request({pwrite,At,Data},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
- {ok,_Offs} ->
- std_reply(?PRIM_FILE:write(Handle, Data), State);
- Reply ->
- std_reply(Reply, State)
+ {error,_} = Reply ->
+ {error,Reply,State};
+ _ ->
+ put_chars(Data, latin1, State)
end;
file_request(datasync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:datasync(Handle) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
file_request(sync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:sync(Handle) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
file_request(close,
#state{handle=Handle}=State) ->
- {stop,normal,?PRIM_FILE:close(Handle),State#state{buf= <<>>}};
+ case ?PRIM_FILE:close(Handle) of
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State#state{buf= <<>>}};
+ Reply ->
+ {stop,normal,Reply,State#state{buf= <<>>}}
+ end;
file_request({position,At},
#state{handle=Handle,buf=Buf}=State) ->
- std_reply(position(Handle, At, Buf), State);
+ case position(Handle, At, Buf) of
+ {error,_} = Reply ->
+ {error,Reply,State};
+ Reply ->
+ std_reply(Reply, State)
+ end;
file_request(truncate,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:truncate(Handle) of
- {error,_Reason}=Reply ->
- {stop,normal,Reply,State#state{buf= <<>>}};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State#state{buf= <<>>}};
Reply ->
- {reply,Reply,State}
+ std_reply(Reply, State)
end;
file_request(Unknown,
#state{}=State) ->
Reason = {request, Unknown},
{error,{error,Reason},State}.
+%% Standard reply and clear buffer
std_reply({error,_}=Reply, State) ->
{error,Reply,State#state{buf= <<>>}};
std_reply(Reply, State) ->
@@ -285,8 +315,8 @@ io_request({put_chars, Enc, Chars},
io_request({put_chars, Enc, Chars},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, cur, Buf) of
- {error,_}=Reply ->
- {stop,normal,Reply,State#state{buf= <<>>}};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
_ ->
put_chars(Chars, Enc, State#state{buf= <<>>})
end;
@@ -307,18 +337,18 @@ io_request({get_chars,Enc,_Prompt,N},
#state{}=State) ->
get_chars(N, Enc, State);
-%%
-%% This optimization gives almost nothing - needs more working...
-%% Disabled for now. /PaN
-%%
-%% io_request({get_line,Enc,_Prompt},
-%% #state{unic=latin1}=State) ->
-%% get_line(Enc,State);
-
-io_request({get_line,Enc,_Prompt},
- #state{}=State) ->
- get_chars(io_lib, collect_line, [], Enc, State);
-
+io_request({get_line,OutEnc,_Prompt}, #state{buf=Buf, read_mode=Mode, unic=InEnc} = State0) ->
+ try
+ %% Minimize the encoding conversions
+ WorkEnc = case InEnc of
+ {_,_} -> OutEnc; %% utf16 or utf32
+ _ -> InEnc %% Byte oriented utf8 or latin1
+ end,
+ {Res, State} = get_line(start, convert_enc(Buf, InEnc, WorkEnc), WorkEnc, State0),
+ {reply, cast(Res, Mode, WorkEnc, OutEnc), State}
+ catch exit:ExError ->
+ {stop,ExError,{error,ExError},State0#state{buf= <<>>}}
+ end;
io_request({setopts, Opts},
#state{}=State) when is_list(Opts) ->
@@ -367,75 +397,63 @@ io_request_loop([Request|Tail],
%% I/O request put_chars
%%
put_chars(Chars, latin1, #state{handle=Handle, unic=latin1}=State) ->
+ NewState = State#state{buf = <<>>},
case ?PRIM_FILE:write(Handle, Chars) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,NewState};
Reply ->
- {reply,Reply,State}
+ {reply,Reply,NewState}
end;
put_chars(Chars, InEncoding, #state{handle=Handle, unic=OutEncoding}=State) ->
+ NewState = State#state{buf = <<>>},
case unicode:characters_to_binary(Chars,InEncoding,OutEncoding) of
Bin when is_binary(Bin) ->
case ?PRIM_FILE:write(Handle, Bin) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,NewState};
Reply ->
- {reply,Reply,State}
+ {reply,Reply,NewState}
end;
{error,_,_} ->
- {stop,normal,{error,{no_translation, InEncoding, OutEncoding}},State}
+ {stop,no_translation,
+ {error,{no_translation, InEncoding, OutEncoding}},
+ NewState}
+ end.
+
+get_line(S, {<<>>, Cont}, OutEnc,
+ #state{handle=Handle, read_mode=Mode, unic=InEnc}=State) ->
+ case ?PRIM_FILE:read(Handle, read_size(Mode)) of
+ {ok,Bin} ->
+ get_line(S, convert_enc([Cont, Bin], InEnc, OutEnc), OutEnc, State);
+ eof ->
+ get_line(S, {eof, Cont}, OutEnc, State);
+ {error,Reason}=Error ->
+ {stop,Reason,Error,State}
+ end;
+get_line(S0, {Buf, BCont}, OutEnc, #state{unic=InEnc}=State) ->
+ case io_lib:collect_line(S0, Buf, OutEnc, []) of
+ {stop, Result, Cont0} ->
+ %% Convert both buffers back to file InEnc encoding
+ {Cont, <<>>} = convert_enc(Cont0, OutEnc, InEnc),
+ {Result, State#state{buf=cast_binary([Cont, BCont])}};
+ S ->
+ get_line(S, {<<>>, BCont}, OutEnc, State)
+ end.
+
+convert_enc(Bins, Enc, Enc) ->
+ {cast_binary(Bins), <<>>};
+convert_enc(eof, _, _) ->
+ {<<>>, <<>>};
+convert_enc(Bin, InEnc, OutEnc) ->
+ case unicode:characters_to_binary(Bin, InEnc, OutEnc) of
+ Res when is_binary(Res) ->
+ {Res, <<>>};
+ {incomplete, Res, Cont} ->
+ {Res, Cont};
+ {error, _, _} ->
+ exit({no_translation, InEnc, OutEnc})
end.
-%%
-%% Process the I/O request get_line for latin1 encoding of file specially
-%% Unfortunately this function gives almost nothing, it needs more work
-%% I disable it for now /PaN
-%%
-%% srch(<<>>,_,_) ->
-%% nomatch;
-%% srch(<<X:8,_/binary>>,X,N) ->
-%% {match,N};
-%% srch(<<_:8,T/binary>>,X,N) ->
-%% srch(T,X,N+1).
-%% get_line(OutEnc, #state{handle=Handle,buf = <<>>,unic=latin1}=State) ->
-%% case ?PRIM_FILE:read(Handle,?READ_SIZE_BINARY) of
-%% {ok, B} ->
-%% get_line(OutEnc, State#state{buf = B});
-%% eof ->
-%% {reply,eof,State};
-%% {error,Reason}=Error ->
-%% {stop,Reason,Error,State}
-%% end;
-%% get_line(OutEnc, #state{handle=Handle,buf=Buf,read_mode=ReadMode,unic=latin1}=State) ->
-%% case srch(Buf,$\n,0) of
-%% nomatch ->
-%% case ?PRIM_FILE:read(Handle,?READ_SIZE_BINARY) of
-%% {ok, B} ->
-%% get_line(OutEnc,State#state{buf = <<Buf/binary,B/binary>>});
-%% eof ->
-%% std_reply(cast(Buf, ReadMode,latin1,OutEnc), State);
-%% {error,Reason}=Error ->
-%% {stop,Reason,Error,State#state{buf= <<>>}}
-%% end;
-%% {match,Pos} when Pos >= 1->
-%% PosP1 = Pos + 1,
-%% <<Res0:PosP1/binary,NewBuf/binary>> = Buf,
-%% PosM1 = Pos - 1,
-%% Res = case Res0 of
-%% <<Chomped:PosM1/binary,$\r:8,$\n:8>> ->
-%% cat(Chomped, <<"\n">>, ReadMode,latin1,OutEnc);
-%% _Other ->
-%% cast(Res0, ReadMode,latin1,OutEnc)
-%% end,
-%% {reply,Res,State#state{buf=NewBuf}};
-%% {match,Pos} ->
-%% PosP1 = Pos + 1,
-%% <<Res:PosP1/binary,NewBuf/binary>> = Buf,
-%% {reply,Res,State#state{buf=NewBuf}}
-%% end;
-%% get_line(_, #state{}=State) ->
-%% {error,{error,get_line},State}.
-
%%
%% Process the I/O request get_chars
%%
@@ -640,8 +658,6 @@ invalid_unicode_error(Mod, Func, XtraArg, S) ->
%% Convert error code to make it look as before
err_func(io_lib, get_until, {_,F,_}) ->
- F;
-err_func(_, F, _) ->
F.
@@ -713,6 +729,8 @@ cat(B1, B2, list, latin1,_) ->
binary_to_list(B1)++binary_to_list(B2).
%% Cast binary to list or binary
+cast(eof, _, _, _) ->
+ eof;
cast(B, binary, latin1, latin1) ->
B;
cast(B, binary, InEncoding, OutEncoding) ->
@@ -736,6 +754,8 @@ cast(B, list, InEncoding, OutEncoding) ->
%% Convert buffer to binary
cast_binary(Binary) when is_binary(Binary) ->
Binary;
+cast_binary([<<>>|List]) ->
+ cast_binary(List);
cast_binary(List) when is_list(List) ->
list_to_binary(List);
cast_binary(_EOF) ->
@@ -897,11 +917,14 @@ cbv({utf32,little},_) ->
%% Compensates ?PRIM_FILE:position/2 for the number of bytes
%% we have buffered
-
-position(Handle, cur, Buf) ->
- position(Handle, {cur, 0}, Buf);
-position(Handle, {cur, Offs}, Buf) when is_binary(Buf) ->
- ?PRIM_FILE:position(Handle, {cur, Offs-byte_size(Buf)});
-position(Handle, At, _Buf) ->
- ?PRIM_FILE:position(Handle, At).
-
+position(Handle, At, Buf) ->
+ ?PRIM_FILE:position(
+ Handle,
+ case At of
+ cur ->
+ {cur, -byte_size(Buf)};
+ {cur, Offs} ->
+ {cur, Offs-byte_size(Buf)};
+ _ ->
+ At
+ end).
diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl
index eabf0401a3..6df6be7d06 100644
--- a/lib/kernel/src/file_server.erl
+++ b/lib/kernel/src/file_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index adaa3159ec..a47535b2f8 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index bc8ffbe5e3..8cb2a725e8 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -58,6 +59,7 @@
{reuseaddr, boolean()} |
{send_timeout, non_neg_integer() | infinity} |
{send_timeout_close, boolean()} |
+ {show_econnreset, boolean()} |
{sndbuf, non_neg_integer()} |
{tos, non_neg_integer()} |
{ipv6_v6only, boolean()}.
@@ -89,6 +91,7 @@
reuseaddr |
send_timeout |
send_timeout_close |
+ show_econnreset |
sndbuf |
tos |
ipv6_v6only.
@@ -111,7 +114,8 @@
option().
-type socket() :: port().
--export_type([option/0, option_name/0, connect_option/0, listen_option/0]).
+-export_type([option/0, option_name/0, connect_option/0, listen_option/0,
+ socket/0]).
%%
%% Connect a socket
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index 860eec10a0..6698d5f0fa 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl
index 0a4edea452..2be1efaf24 100644
--- a/lib/kernel/src/global.erl
+++ b/lib/kernel/src/global.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -881,11 +882,12 @@ handle_info({nodeup, Node}, S0) when S0#state.connect_all ->
false ->
resend_pre_connect(Node),
- %% now() is used as a tag to separate different synch sessions
+ %% erlang:unique_integer([monotonic]) is used as a tag to
+ %% separate different synch sessions
%% from each others. Global could be confused at bursty nodeups
%% because it couldn't separate the messages between the different
%% synch sessions started by a nodeup.
- MyTag = now(),
+ MyTag = erlang:unique_integer([monotonic]),
put({sync_tag_my, Node}, MyTag),
?trace({sending_nodeup_to_locker, {node,Node},{mytag,MyTag}}),
S1#state.the_locker ! {nodeup, Node, MyTag},
@@ -1772,8 +1774,8 @@ update_locker_known(Upd, S) ->
S#multi{known = Known, the_boss = TheBoss}.
random_element(L) ->
- {A,B,C} = now(),
- E = (A+B+C) rem length(L),
+ E = abs(erlang:monotonic_time()
+ bxor erlang:unique_integer()) rem length(L),
lists:nth(E+1, L).
exclude_known(Others, Known) ->
@@ -2072,9 +2074,10 @@ random_sleep(Times) ->
end,
case get(random_seed) of
undefined ->
- {A1, A2, A3} = now(),
- _ = random:seed(A1, A2, A3 + erlang:phash(node(), 100000)),
- ok;
+ _ = random:seed(erlang:phash2([erlang:node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
+ ok;
_ -> ok
end,
%% First time 1/4 seconds, then doubling each time up to 8 seconds max.
@@ -2106,7 +2109,7 @@ trace_message(S, M, X) ->
S#state{trace = [trace_message(M, X) | S#state.trace]}.
trace_message(M, X) ->
- {node(), now(), M, nodes(), X}.
+ {node(), erlang:timestamp(), M, nodes(), X}.
%%-----------------------------------------------------------------
%% Each sync process corresponds to one call to sync. Each such
diff --git a/lib/kernel/src/global_group.erl b/lib/kernel/src/global_group.erl
index da8b573749..848df13c39 100644
--- a/lib/kernel/src/global_group.erl
+++ b/lib/kernel/src/global_group.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/global_search.erl b/lib/kernel/src/global_search.erl
index 0bf53e29b8..9429295bdb 100644
--- a/lib/kernel/src/global_search.erl
+++ b/lib/kernel/src/global_search.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl
index b36dbf33dd..ea0734e0c9 100644
--- a/lib/kernel/src/group.erl
+++ b/lib/kernel/src/group.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -111,8 +112,13 @@ start_shell1(Fun) ->
server_loop(Drv, Shell, Buf0) ->
receive
{io_request,From,ReplyAs,Req} when is_pid(From) ->
- Buf = io_request(Req, From, ReplyAs, Drv, Buf0),
- server_loop(Drv, Shell, Buf);
+ %% This io_request may cause a transition to a couple of
+ %% selective receive loops elsewhere in this module.
+ Buf = io_request(Req, From, ReplyAs, Drv, Buf0),
+ server_loop(Drv, Shell, Buf);
+ {reply,{{From,ReplyAs},Reply}} ->
+ io_reply(From, ReplyAs, Reply),
+ server_loop(Drv, Shell, Buf0);
{driver_id,ReplyTo} ->
ReplyTo ! {self(),driver_id,Drv},
server_loop(Drv, Shell, Buf0);
@@ -172,10 +178,13 @@ set_unicode_state(Drv,Bool) ->
io_request(Req, From, ReplyAs, Drv, Buf0) ->
- case io_request(Req, Drv, Buf0) of
+ case io_request(Req, Drv, {From,ReplyAs}, Buf0) of
{ok,Reply,Buf} ->
io_reply(From, ReplyAs, Reply),
Buf;
+ {noreply,Buf} ->
+ %% We expect a {reply,_} message from the Drv when request is done
+ Buf;
{error,Reply,Buf} ->
io_reply(From, ReplyAs, Reply),
Buf;
@@ -196,78 +205,85 @@ io_request(Req, From, ReplyAs, Drv, Buf0) ->
%% io_request({put_chars,unicode,Binary}, Drv, Buf) when is_binary(Binary) ->
%% send_drv(Drv, {put_chars,Binary}),
%% {ok,ok,Buf};
-io_request({put_chars,unicode,Chars}, Drv, Buf) ->
+%%
+%% These put requests have to be synchronous to the driver as otherwise
+%% there is no guarantee that the data has actually been printed.
+io_request({put_chars,unicode,Chars}, Drv, From, Buf) ->
case catch unicode:characters_to_binary(Chars,utf8) of
Binary when is_binary(Binary) ->
- send_drv(Drv, {put_chars, unicode, Binary}),
- {ok,ok,Buf};
+ send_drv(Drv, {put_chars_sync, unicode, Binary, {From,ok}}),
+ {noreply,Buf};
_ ->
{error,{error,{put_chars, unicode,Chars}},Buf}
end;
-io_request({put_chars,unicode,M,F,As}, Drv, Buf) ->
+io_request({put_chars,unicode,M,F,As}, Drv, From, Buf) ->
case catch apply(M, F, As) of
Binary when is_binary(Binary) ->
- send_drv(Drv, {put_chars, unicode,Binary}),
- {ok,ok,Buf};
+ send_drv(Drv, {put_chars_sync, unicode, Binary, {From,ok}}),
+ {noreply,Buf};
Chars ->
case catch unicode:characters_to_binary(Chars,utf8) of
B when is_binary(B) ->
- send_drv(Drv, {put_chars, unicode,B}),
- {ok,ok,Buf};
+ send_drv(Drv, {put_chars_sync, unicode, B, {From,ok}}),
+ {noreply,Buf};
_ ->
{error,{error,F},Buf}
end
end;
-io_request({put_chars,latin1,Binary}, Drv, Buf) when is_binary(Binary) ->
- send_drv(Drv, {put_chars, unicode,unicode:characters_to_binary(Binary,latin1)}),
- {ok,ok,Buf};
-io_request({put_chars,latin1,Chars}, Drv, Buf) ->
+io_request({put_chars,latin1,Binary}, Drv, From, Buf) when is_binary(Binary) ->
+ send_drv(Drv, {put_chars_sync, unicode,
+ unicode:characters_to_binary(Binary,latin1),
+ {From,ok}}),
+ {noreply,Buf};
+io_request({put_chars,latin1,Chars}, Drv, From, Buf) ->
case catch unicode:characters_to_binary(Chars,latin1) of
Binary when is_binary(Binary) ->
- send_drv(Drv, {put_chars, unicode,Binary}),
- {ok,ok,Buf};
+ send_drv(Drv, {put_chars_sync, unicode, Binary, {From,ok}}),
+ {noreply,Buf};
_ ->
{error,{error,{put_chars,latin1,Chars}},Buf}
end;
-io_request({put_chars,latin1,M,F,As}, Drv, Buf) ->
+io_request({put_chars,latin1,M,F,As}, Drv, From, Buf) ->
case catch apply(M, F, As) of
Binary when is_binary(Binary) ->
- send_drv(Drv, {put_chars, unicode,unicode:characters_to_binary(Binary,latin1)}),
- {ok,ok,Buf};
+ send_drv(Drv, {put_chars_sync, unicode,
+ unicode:characters_to_binary(Binary,latin1),
+ {From,ok}}),
+ {noreply,Buf};
Chars ->
case catch unicode:characters_to_binary(Chars,latin1) of
B when is_binary(B) ->
- send_drv(Drv, {put_chars, unicode,B}),
- {ok,ok,Buf};
+ send_drv(Drv, {put_chars_sync, unicode, B, {From,ok}}),
+ {noreply,Buf};
_ ->
{error,{error,F},Buf}
end
end;
-io_request({get_chars,Encoding,Prompt,N}, Drv, Buf) ->
+io_request({get_chars,Encoding,Prompt,N}, Drv, _From, Buf) ->
get_chars(Prompt, io_lib, collect_chars, N, Drv, Buf, Encoding);
-io_request({get_line,Encoding,Prompt}, Drv, Buf) ->
+io_request({get_line,Encoding,Prompt}, Drv, _From, Buf) ->
get_chars(Prompt, io_lib, collect_line, [], Drv, Buf, Encoding);
-io_request({get_until,Encoding, Prompt,M,F,As}, Drv, Buf) ->
+io_request({get_until,Encoding, Prompt,M,F,As}, Drv, _From, Buf) ->
get_chars(Prompt, io_lib, get_until, {M,F,As}, Drv, Buf, Encoding);
-io_request({get_password,_Encoding},Drv,Buf) ->
+io_request({get_password,_Encoding},Drv,_From,Buf) ->
get_password_chars(Drv, Buf);
-io_request({setopts,Opts}, Drv, Buf) when is_list(Opts) ->
+io_request({setopts,Opts}, Drv, _From, Buf) when is_list(Opts) ->
setopts(Opts, Drv, Buf);
-io_request(getopts, Drv, Buf) ->
+io_request(getopts, Drv, _From, Buf) ->
getopts(Drv, Buf);
-io_request({requests,Reqs}, Drv, Buf) ->
- io_requests(Reqs, {ok,ok,Buf}, Drv);
+io_request({requests,Reqs}, Drv, From, Buf) ->
+ io_requests(Reqs, {ok,ok,Buf}, From, Drv);
%% New in R12
-io_request({get_geometry,columns},Drv,Buf) ->
+io_request({get_geometry,columns},Drv,_From,Buf) ->
case get_tty_geometry(Drv) of
{W,_H} ->
{ok,W,Buf};
_ ->
{error,{error,enotsup},Buf}
end;
-io_request({get_geometry,rows},Drv,Buf) ->
+io_request({get_geometry,rows},Drv,_From,Buf) ->
case get_tty_geometry(Drv) of
{_W,H} ->
{ok,H,Buf};
@@ -276,38 +292,49 @@ io_request({get_geometry,rows},Drv,Buf) ->
end;
%% BC with pre-R13
-io_request({put_chars,Chars}, Drv, Buf) ->
- io_request({put_chars,latin1,Chars}, Drv, Buf);
-io_request({put_chars,M,F,As}, Drv, Buf) ->
- io_request({put_chars,latin1,M,F,As}, Drv, Buf);
-io_request({get_chars,Prompt,N}, Drv, Buf) ->
- io_request({get_chars,latin1,Prompt,N}, Drv, Buf);
-io_request({get_line,Prompt}, Drv, Buf) ->
- io_request({get_line,latin1,Prompt}, Drv, Buf);
-io_request({get_until, Prompt,M,F,As}, Drv, Buf) ->
- io_request({get_until,latin1, Prompt,M,F,As}, Drv, Buf);
-io_request(get_password,Drv,Buf) ->
- io_request({get_password,latin1},Drv,Buf);
-
-
-
-io_request(_, _Drv, Buf) ->
+io_request({put_chars,Chars}, Drv, From, Buf) ->
+ io_request({put_chars,latin1,Chars}, Drv, From, Buf);
+io_request({put_chars,M,F,As}, Drv, From, Buf) ->
+ io_request({put_chars,latin1,M,F,As}, Drv, From, Buf);
+io_request({get_chars,Prompt,N}, Drv, From, Buf) ->
+ io_request({get_chars,latin1,Prompt,N}, Drv, From, Buf);
+io_request({get_line,Prompt}, Drv, From, Buf) ->
+ io_request({get_line,latin1,Prompt}, Drv, From, Buf);
+io_request({get_until, Prompt,M,F,As}, Drv, From, Buf) ->
+ io_request({get_until,latin1, Prompt,M,F,As}, Drv, From, Buf);
+io_request(get_password,Drv,From,Buf) ->
+ io_request({get_password,latin1},Drv,From,Buf);
+
+
+
+io_request(_, _Drv, _From, Buf) ->
{error,{error,request},Buf}.
-%% Status = io_requests(RequestList, PrevStat, Drv)
-%% Process a list of output requests as long as the previous status is 'ok'.
-
-io_requests([R|Rs], {ok,ok,Buf}, Drv) ->
- io_requests(Rs, io_request(R, Drv, Buf), Drv);
-io_requests([_|_], Error, _Drv) ->
+%% Status = io_requests(RequestList, PrevStat, From, Drv)
+%% Process a list of output requests as long as
+%% the previous status is 'ok' or noreply.
+%%
+%% We use undefined as the From for all but the last request
+%% in order to discards acknowledgements from those requests.
+%%
+io_requests([R|Rs], {noreply,Buf}, From, Drv) ->
+ ReqFrom = if Rs =:= [] -> From; true -> undefined end,
+ io_requests(Rs, io_request(R, Drv, ReqFrom, Buf), From, Drv);
+io_requests([R|Rs], {ok,ok,Buf}, From, Drv) ->
+ ReqFrom = if Rs =:= [] -> From; true -> undefined end,
+ io_requests(Rs, io_request(R, Drv, ReqFrom, Buf), From, Drv);
+io_requests([_|_], Error, _From, _Drv) ->
Error;
-io_requests([], Stat, _) ->
+io_requests([], Stat, _From, _) ->
Stat.
%% io_reply(From, ReplyAs, Reply)
%% The function for sending i/o command acknowledgement.
%% The ACK contains the return value.
+io_reply(undefined, _ReplyAs, _Reply) ->
+ %% Ignore these replies as they are generated from io_requests/4.
+ ok;
io_reply(From, ReplyAs, Reply) ->
From ! {io_reply,ReplyAs,Reply},
ok.
@@ -619,6 +646,10 @@ more_data(What, Cont0, Drv, Ls, Encoding) ->
io_request(Req, From, ReplyAs, Drv, []), %WRONG!!!
send_drv_reqs(Drv, edlin:redraw_line(Cont)),
get_line1({more_chars,Cont,[]}, Drv, Ls, Encoding);
+ {reply,{{From,ReplyAs},Reply}} ->
+ %% We take care of replies from puts here as well
+ io_reply(From, ReplyAs, Reply),
+ more_data(What, Cont0, Drv, Ls, Encoding);
{'EXIT',Drv,interrupt} ->
interrupted;
{'EXIT',Drv,_} ->
@@ -641,6 +672,10 @@ get_line_echo_off1({Chars,[]}, Drv) ->
{io_request,From,ReplyAs,Req} when is_pid(From) ->
io_request(Req, From, ReplyAs, Drv, []),
get_line_echo_off1({Chars,[]}, Drv);
+ {reply,{{From,ReplyAs},Reply}} when From =/= undefined ->
+ %% We take care of replies from puts here as well
+ io_reply(From, ReplyAs, Reply),
+ get_line_echo_off1({Chars,[]},Drv);
{'EXIT',Drv,interrupt} ->
interrupted;
{'EXIT',Drv,_} ->
@@ -790,6 +825,10 @@ get_password1({Chars,[]}, Drv) ->
%% set to []. But do we expect anything but plain output?
get_password1({Chars, []}, Drv);
+ {reply,{{From,ReplyAs},Reply}} ->
+ %% We take care of replies from puts here as well
+ io_reply(From, ReplyAs, Reply),
+ get_password1({Chars, []},Drv);
{'EXIT',Drv,interrupt} ->
interrupted;
{'EXIT',Drv,_} ->
diff --git a/lib/kernel/src/heart.erl b/lib/kernel/src/heart.erl
index daed6dd488..eea78aabdf 100644
--- a/lib/kernel/src/heart.erl
+++ b/lib/kernel/src/heart.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -25,7 +26,7 @@
%%%--------------------------------------------------------------------
%%% This is a rewrite of pre_heart from BS.3.
%%%
-%%% The purpose of this process-module is to act as an supervisor
+%%% The purpose of this process-module is to act as a supervisor
%%% of the entire erlang-system. This 'heart' beats with a frequence
%%% satisfying an external port program *not* reboot the entire
%%% system. If however the erlang-emulator would hang, a reboot is
@@ -33,7 +34,11 @@
%%%
%%% It recognizes the flag '-heart'
%%%--------------------------------------------------------------------
--export([start/0, init/2, set_cmd/1, clear_cmd/0, get_cmd/0, cycle/0]).
+-export([start/0, init/2,
+ set_cmd/1, clear_cmd/0, get_cmd/0,
+ set_callback/2, clear_callback/0, get_callback/0,
+ set_options/1, get_options/0,
+ cycle/0]).
-define(START_ACK, 1).
-define(HEART_BEAT, 2).
@@ -48,6 +53,16 @@
-define(CYCLE_TIMEOUT, 10000).
-define(HEART_PORT_NAME, heart_port).
+%% valid heart options
+-define(SCHEDULER_CHECK_OPT, check_schedulers).
+
+-type heart_option() :: ?SCHEDULER_CHECK_OPT.
+
+-record(state,{port :: port(),
+ cmd :: [] | binary(),
+ options :: [heart_option()],
+ callback :: 'undefined' | {atom(), atom()}}).
+
%%---------------------------------------------------------------------
-spec start() -> 'ignore' | {'error', term()} | {'ok', pid()}.
@@ -80,11 +95,11 @@ wait_for_init_ack(From) ->
init(Starter, Parent) ->
process_flag(trap_exit, true),
process_flag(priority, max),
- register(heart, self()),
+ register(?MODULE, self()),
case catch start_portprogram() of
{ok, Port} ->
Starter ! {ok, self()},
- loop(Parent, Port, "");
+ loop(Parent, #state{port=Port, cmd=[], options=[]});
no_heart ->
Starter ! {no_heart, self()};
error ->
@@ -95,33 +110,68 @@ init(Starter, Parent) ->
Cmd :: string().
set_cmd(Cmd) ->
- heart ! {self(), set_cmd, Cmd},
+ ?MODULE ! {self(), set_cmd, Cmd},
wait().
-spec get_cmd() -> {ok, Cmd} when
Cmd :: string().
get_cmd() ->
- heart ! {self(), get_cmd},
+ ?MODULE ! {self(), get_cmd},
wait().
-spec clear_cmd() -> ok.
clear_cmd() ->
- heart ! {self(), clear_cmd},
+ ?MODULE ! {self(), clear_cmd},
wait().
+-spec set_callback(Module,Function) -> 'ok' | {'error', {'bad_callback', {Module, Function}}} when
+ Module :: atom(),
+ Function :: atom().
+
+set_callback(Module, Function) ->
+ ?MODULE ! {self(), set_callback, {Module,Function}},
+ wait().
+
+-spec get_callback() -> {'ok', {Module, Function}} | 'none' when
+ Module :: atom(),
+ Function :: atom().
+
+get_callback() ->
+ ?MODULE ! {self(), get_callback},
+ wait().
+
+-spec clear_callback() -> ok.
+
+clear_callback() ->
+ ?MODULE ! {self(), clear_callback},
+ wait().
+
+-spec set_options(Options) -> 'ok' | {'error', {'bad_options', Options}} when
+ Options :: [heart_option()].
+
+set_options(Options) ->
+ ?MODULE ! {self(), set_options, Options},
+ wait().
+
+-spec get_options() -> {'ok', Options} | 'none' when
+ Options :: [atom()].
+
+get_options() ->
+ ?MODULE ! {self(), get_options},
+ wait().
%%% Should be used solely by the release handler!!!!!!!
-spec cycle() -> 'ok' | {'error', term()}.
cycle() ->
- heart ! {self(), cycle},
+ ?MODULE ! {self(), cycle},
wait().
wait() ->
receive
- {heart, Res} ->
+ {?MODULE, Res} ->
Res
end.
@@ -181,8 +231,8 @@ wait_ack(Port) ->
{error, Reason}
end.
-loop(Parent, Port, Cmd) ->
- _ = send_heart_beat(Port),
+loop(Parent, #state{port=Port}=S) ->
+ _ = send_heart_beat(S),
receive
{From, set_cmd, NewCmd0} ->
Enc = file:native_name_encoding(),
@@ -190,37 +240,72 @@ loop(Parent, Port, Cmd) ->
NewCmd when is_binary(NewCmd), byte_size(NewCmd) < 2047 ->
_ = send_heart_cmd(Port, NewCmd),
_ = wait_ack(Port),
- From ! {heart, ok},
- loop(Parent, Port, NewCmd);
+ From ! {?MODULE, ok},
+ loop(Parent, S#state{cmd=NewCmd});
_ ->
- From ! {heart, {error, {bad_cmd, NewCmd0}}},
- loop(Parent, Port, Cmd)
+ From ! {?MODULE, {error, {bad_cmd, NewCmd0}}},
+ loop(Parent, S)
end;
{From, clear_cmd} ->
- From ! {heart, ok},
- _ = send_heart_cmd(Port, ""),
+ From ! {?MODULE, ok},
+ _ = send_heart_cmd(Port, []),
_ = wait_ack(Port),
- loop(Parent, Port, "");
+ loop(Parent, S#state{cmd = []});
{From, get_cmd} ->
- From ! {heart, get_heart_cmd(Port)},
- loop(Parent, Port, Cmd);
+ From ! {?MODULE, get_heart_cmd(Port)},
+ loop(Parent, S);
+ {From, set_callback, Callback} ->
+ case Callback of
+ {M,F} when is_atom(M), is_atom(F) ->
+ From ! {?MODULE, ok},
+ loop(Parent, S#state{callback=Callback});
+ _ ->
+ From ! {?MODULE, {error, {bad_callback, Callback}}},
+ loop(Parent, S)
+ end;
+ {From, get_callback} ->
+ Res = case S#state.callback of
+ undefined -> none;
+ Cb -> {ok, Cb}
+ end,
+ From ! {?MODULE, Res},
+ loop(Parent, S);
+ {From, clear_callback} ->
+ From ! {?MODULE, ok},
+ loop(Parent, S#state{callback=undefined});
+ {From, set_options, Options} ->
+ case validate_options(Options) of
+ Validated when is_list(Validated) ->
+ From ! {?MODULE, ok},
+ loop(Parent, S#state{options=Validated});
+ _ ->
+ From ! {?MODULE, {error, {bad_options, Options}}},
+ loop(Parent, S)
+ end;
+ {From, get_options} ->
+ Res = case S#state.options of
+ [] -> none;
+ Cb -> {ok, Cb}
+ end,
+ From ! {?MODULE, Res},
+ loop(Parent, S);
{From, cycle} ->
%% Calls back to loop
- do_cycle_port_program(From, Parent, Port, Cmd);
+ do_cycle_port_program(From, Parent, S);
{'EXIT', Parent, shutdown} ->
no_reboot_shutdown(Port);
{'EXIT', Parent, Reason} ->
exit(Port, Reason),
exit(Reason);
{'EXIT', Port, badsig} -> % we can ignore badsig-messages!
- loop(Parent, Port, Cmd);
+ loop(Parent, S);
{'EXIT', Port, _Reason} ->
- exit({port_terminated, {heart, loop, [Parent, Port, Cmd]}});
+ exit({port_terminated, {?MODULE, loop, [Parent, S]}});
_ ->
- loop(Parent, Port, Cmd)
+ loop(Parent, S)
after
?TIMEOUT ->
- loop(Parent, Port, Cmd)
+ loop(Parent, S)
end.
-spec no_reboot_shutdown(port()) -> no_return().
@@ -232,38 +317,47 @@ no_reboot_shutdown(Port) ->
exit(normal)
end.
-do_cycle_port_program(Caller, Parent, Port, Cmd) ->
+validate_options(Opts) -> validate_options(Opts,[]).
+validate_options([],Res) -> Res;
+validate_options([?SCHEDULER_CHECK_OPT=Opt|Opts],Res) -> validate_options(Opts,[Opt|Res]);
+validate_options(_,_) -> error.
+
+do_cycle_port_program(Caller, Parent, #state{port=Port} = S) ->
unregister(?HEART_PORT_NAME),
case catch start_portprogram() of
{ok, NewPort} ->
_ = send_shutdown(Port),
receive
{'EXIT', Port, _Reason} ->
- _ = send_heart_cmd(NewPort, Cmd),
- Caller ! {heart, ok},
- loop(Parent, NewPort, Cmd)
+ _ = send_heart_cmd(NewPort, S#state.cmd),
+ Caller ! {?MODULE, ok},
+ loop(Parent, S#state{port=NewPort})
after
?CYCLE_TIMEOUT ->
%% Huh! Two heart port programs running...
%% well, the old one has to be sick not to respond
%% so we'll settle for the new one...
- _ = send_heart_cmd(NewPort, Cmd),
- Caller ! {heart, {error, stop_error}},
- loop(Parent, NewPort, Cmd)
+ _ = send_heart_cmd(NewPort, S#state.cmd),
+ Caller ! {?MODULE, {error, stop_error}},
+ loop(Parent, S#state{port=NewPort})
end;
no_heart ->
- Caller ! {heart, {error, no_heart}},
- loop(Parent, Port, Cmd);
+ Caller ! {?MODULE, {error, no_heart}},
+ loop(Parent, S);
error ->
- Caller ! {heart, {error, start_error}},
- loop(Parent, Port, Cmd)
+ Caller ! {?MODULE, {error, start_error}},
+ loop(Parent, S)
end.
%% "Beates" the heart once.
-send_heart_beat(Port) -> Port ! {self(), {command, [?HEART_BEAT]}}.
+send_heart_beat(#state{port=Port, callback=Cb, options=Opts}) ->
+ ok = check_system(Opts),
+ ok = check_callback(Cb),
+ Port ! {self(), {command, [?HEART_BEAT]}}.
%% Set a new HEART_COMMAND.
+-dialyzer({no_improper_lists, send_heart_cmd/2}).
send_heart_cmd(Port, []) ->
Port ! {self(), {command, [?CLEAR_CMD]}};
send_heart_cmd(Port, Cmd) ->
@@ -276,6 +370,24 @@ get_heart_cmd(Port) ->
{ok, Cmd}
end.
+check_system([]) -> ok;
+check_system([?SCHEDULER_CHECK_OPT|Opts]) ->
+ ok = erts_internal:system_check(schedulers),
+ check_system(Opts).
+
+%% validate system by performing a check before the heartbeat
+%% return 'ok' if everything is alright.
+%% Terminate if with reason if something is a miss.
+%% It is fine to timeout in the callback, in fact that is the intention
+%% if something goes wront -> no heartbeat.
+
+check_callback(Callback) ->
+ case Callback of
+ undefined -> ok;
+ {M,F} ->
+ erlang:apply(M,F,[])
+ end.
+
%% Sends shutdown command to the port.
send_shutdown(Port) -> Port ! {self(), {command, [?SHUT_DOWN]}}.
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index e5928c7b63..ddbbc548dd 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -43,10 +43,10 @@
-export([chunk_name/1,
%% Only the code and code_server modules may call the entries below!
- load_native_code/2,
- post_beam_load/1,
- load_module/3,
- load/2]).
+ load_native_code/3,
+ post_beam_load/2,
+ load_module/4,
+ load/3]).
%%-define(DEBUG,true).
-define(DO_ASSERT,true).
@@ -82,58 +82,57 @@ chunk_name(Architecture) ->
%% HW32 %% HiPE, x86, Win32
end.
+word_size(Architecture) ->
+ case Architecture of
+ amd64 -> 8;
+ ppc64 -> 8;
+ _ -> 4
+ end.
+
%%========================================================================
--spec load_native_code(Mod, binary()) -> 'no_native' | {'module', Mod}
- when Mod :: atom().
+-spec load_native_code(Mod, binary(), hipe_architecture()) ->
+ 'no_native' | {'module', Mod} when Mod :: atom().
%% @doc
%% Loads the native code of a module Mod.
%% Returns {module,Mod} on success (for compatibility with
%% code:load_file/1) and the atom `no_native' on failure.
-load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
- Architecture = erlang:system_info(hipe_architecture),
- try chunk_name(Architecture) of
- ChunkTag ->
- %% patch_to_emu(Mod),
- case code:get_chunk(Bin, ChunkTag) of
- undefined -> no_native;
- NativeCode when is_binary(NativeCode) ->
- erlang:system_flag(multi_scheduling, block),
- try
- OldReferencesToPatch = patch_to_emu_step1(Mod),
- case load_module(Mod, NativeCode, Bin, OldReferencesToPatch) of
- bad_crc -> no_native;
- Result -> Result
- end
- after
- erlang:system_flag(multi_scheduling, unblock)
- end
+load_native_code(_Mod, _Bin, undefined) ->
+ no_native;
+load_native_code(Mod, Bin, Architecture) when is_atom(Mod), is_binary(Bin) ->
+ %% patch_to_emu(Mod),
+ case code:get_chunk(Bin, chunk_name(Architecture)) of
+ undefined -> no_native;
+ NativeCode when is_binary(NativeCode) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ OldReferencesToPatch = patch_to_emu_step1(Mod),
+ case load_module(Mod, NativeCode, Bin, OldReferencesToPatch,
+ Architecture) of
+ bad_crc -> no_native;
+ Result -> Result
+ end
+ after
+ erlang:system_flag(multi_scheduling, unblock)
end
- catch
- _:_ ->
- %% Unknown HiPE architecture. Can't happen (in principle).
- no_native
end.
%%========================================================================
--spec post_beam_load(atom()) -> 'ok'.
+-spec post_beam_load(atom(), hipe_architecture()) -> 'ok'.
-post_beam_load(Mod) when is_atom(Mod) ->
- Architecture = erlang:system_info(hipe_architecture),
- try chunk_name(Architecture) of
- _ChunkTag ->
- erlang:system_flag(multi_scheduling, block),
- try
- patch_to_emu(Mod)
- after
- erlang:system_flag(multi_scheduling, unblock)
- end
- catch
- _:_ ->
- ok
- end.
+%% does nothing on a hipe-disabled system
+post_beam_load(_Mod, undefined) ->
+ ok;
+post_beam_load(Mod, _) when is_atom(Mod) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ patch_to_emu(Mod)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end,
+ ok.
%%========================================================================
@@ -148,52 +147,55 @@ version_check(Version, Mod) when is_atom(Mod) ->
%%========================================================================
--spec load_module(Mod, binary(), _) -> 'bad_crc' | {'module', Mod}
- when Mod :: atom().
-load_module(Mod, Bin, Beam) ->
+-spec load_module(Mod, binary(), _, hipe_architecture()) ->
+ 'bad_crc' | {'module', Mod} when Mod :: atom().
+
+load_module(Mod, Bin, Beam, Architecture) ->
erlang:system_flag(multi_scheduling, block),
try
- load_module_nosmp(Mod, Bin, Beam)
+ load_module_nosmp(Mod, Bin, Beam, Architecture)
after
erlang:system_flag(multi_scheduling, unblock)
end.
-load_module_nosmp(Mod, Bin, Beam) ->
- load_module(Mod, Bin, Beam, []).
+load_module_nosmp(Mod, Bin, Beam, Architecture) ->
+ load_module(Mod, Bin, Beam, [], Architecture).
-load_module(Mod, Bin, Beam, OldReferencesToPatch) ->
+load_module(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
?debug_msg("************ Loading Module ~w ************\n",[Mod]),
%% Loading a whole module, let the BEAM loader patch closures.
put(hipe_patch_closures, false),
- load_common(Mod, Bin, Beam, OldReferencesToPatch).
+ load_common(Mod, Bin, Beam, OldReferencesToPatch, Architecture).
%%========================================================================
--spec load(Mod, binary()) -> 'bad_crc' | {'module', Mod} when Mod :: atom().
+-spec load(Mod, binary(), hipe_architecture()) ->
+ 'bad_crc' | {'module', Mod} when Mod :: atom().
-load(Mod, Bin) ->
+load(Mod, Bin, Architecture) ->
erlang:system_flag(multi_scheduling, block),
try
- load_nosmp(Mod, Bin)
+ load_nosmp(Mod, Bin, Architecture)
after
erlang:system_flag(multi_scheduling, unblock)
end.
-load_nosmp(Mod, Bin) ->
+load_nosmp(Mod, Bin, Architecture) ->
?debug_msg("********* Loading funs in module ~w *********\n",[Mod]),
%% Loading just some functions in a module; patch closures separately.
put(hipe_patch_closures, true),
- load_common(Mod, Bin, [], []).
+ load_common(Mod, Bin, [], [], Architecture).
%%------------------------------------------------------------------------
-load_common(Mod, Bin, Beam, OldReferencesToPatch) ->
+load_common(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
%% Unpack the binary.
[{Version, CheckSum},
ConstAlign, ConstSize, ConstMap, LabelMap, ExportMap,
CodeSize, CodeBinary, Refs,
0,[] % ColdSize, CRrefs
] = binary_to_term(Bin),
+ MD5 = erlang:md5(Bin), % use md5 of actual running code for module_info
?debug_msg("***** ErLLVM *****~nVersion: ~s~nCheckSum: ~w~nConstAlign: ~w~n" ++
"ConstSize: ~w~nConstMap: ~w~nLabelMap: ~w~nExportMap ~w~nRefs ~w~n",
[Version, CheckSum, ConstAlign, ConstSize, ConstMap, LabelMap, ExportMap,
@@ -211,18 +213,21 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) ->
bad_crc;
true ->
put(closures_to_patch, []),
+ WordSize = word_size(Architecture),
+ WriteWord = write_word_fun(WordSize),
%% Create data segment
{ConstAddr,ConstMap2} =
- create_data_segment(ConstAlign, ConstSize, ConstMap),
+ create_data_segment(ConstAlign, ConstSize, ConstMap, WriteWord),
%% Find callees for which we may need trampolines.
- CalleeMFAs = find_callee_mfas(Refs),
+ CalleeMFAs = find_callee_mfas(Refs, Architecture),
%% Write the code to memory.
{CodeAddress,Trampolines} =
enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, Beam),
%% Construct CalleeMFA-to-trampoline mapping.
- TrampolineMap = mk_trampoline_map(CalleeMFAs, Trampolines),
+ TrampolineMap = mk_trampoline_map(CalleeMFAs, Trampolines,
+ Architecture),
%% Patch references to code labels in data seg.
- ok = patch_consts(LabelMap, ConstAddr, CodeAddress),
+ ok = patch_consts(LabelMap, ConstAddr, CodeAddress, WriteWord),
%% Find out which functions are being loaded (and where).
%% Note: Addresses are sorted descending.
{MFAs,Addresses} = exports(ExportMap, CodeAddress),
@@ -254,7 +259,8 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) ->
AddressesOfClosuresToPatch =
calculate_addresses(ClosurePatches, CodeAddress, Addresses),
export_funs(Addresses),
- export_funs(Mod, BeamBinary, Addresses, AddressesOfClosuresToPatch)
+ export_funs(Mod, MD5, BeamBinary,
+ Addresses, AddressesOfClosuresToPatch)
end,
%% Redirect references to the old module to the new module's BEAM stub.
patch_to_emu_step2(OldReferencesToPatch),
@@ -273,14 +279,26 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) ->
%% Scan the list of patches and build a set (returned as a tuple)
%% of the callees for which we may need trampolines.
%%
-find_callee_mfas(Patches) when is_list(Patches) ->
- case erlang:system_info(hipe_architecture) of
- amd64 -> [];
- arm -> find_callee_mfas(Patches, gb_sets:empty(), false);
- powerpc -> find_callee_mfas(Patches, gb_sets:empty(), true);
- ppc64 -> find_callee_mfas(Patches, gb_sets:empty(), true);
- ultrasparc -> [];
- x86 -> []
+find_callee_mfas(Patches, Architecture) when is_list(Patches) ->
+ case needs_trampolines(Architecture) of
+ true -> find_callee_mfas(Patches, gb_sets:empty(),
+ no_erts_trampolines(Architecture));
+ _ -> []
+ end.
+
+needs_trampolines(Architecture) ->
+ case Architecture of
+ arm -> true;
+ powerpc -> true;
+ ppc64 -> true;
+ _ -> false
+ end.
+
+no_erts_trampolines(Architecture) ->
+ case Architecture of
+ powerpc -> true;
+ ppc64 -> true;
+ _ -> false
end.
find_callee_mfas([{Type,Data}|Patches], MFAs, SkipErtsSyms) ->
@@ -316,14 +334,9 @@ add_callee_mfas([], MFAs, _SkipErtsSyms) -> MFAs.
%%----------------------------------------------------------------
%%
-mk_trampoline_map([], []) -> []; % archs not using trampolines
-mk_trampoline_map(CalleeMFAs, Trampolines) ->
- SizeofLong =
- case erlang:system_info(hipe_architecture) of
- amd64 -> 8;
- ppc64 -> 8;
- _ -> 4
- end,
+mk_trampoline_map([], [], _) -> []; % archs not using trampolines
+mk_trampoline_map(CalleeMFAs, Trampolines, Architecture) ->
+ SizeofLong = word_size(Architecture),
mk_trampoline_map(tuple_size(CalleeMFAs), CalleeMFAs,
Trampolines, SizeofLong, gb_trees:empty()).
@@ -430,9 +443,9 @@ export_funs([FunDef | Addresses]) ->
export_funs([]) ->
ok.
-export_funs(Mod, Beam, Addresses, ClosuresToPatch) ->
+export_funs(Mod, MD5, Beam, Addresses, ClosuresToPatch) ->
Fs = [{F,A,Address} || #fundef{address=Address, mfa={_M,F,A}} <- Addresses],
- Mod = code:make_stub_module(Mod, Beam, {Fs,ClosuresToPatch}),
+ Mod = code:make_stub_module(Mod, Beam, {Fs,ClosuresToPatch,MD5}),
ok.
%%========================================================================
@@ -619,22 +632,24 @@ patch_load_mfa(CodeAddress, DestMFA, Addresses, RemoteOrLocal) ->
%%----------------------------------------------------------------
%% Patch references to code labels in the data segment.
%%
-patch_consts(Labels, DataAddress, CodeAddress) ->
+patch_consts(Labels, DataAddress, CodeAddress, WriteWord) ->
lists:foreach(fun (L) ->
- patch_label_or_labels(L, DataAddress, CodeAddress)
+ patch_label_or_labels(L, DataAddress, CodeAddress,
+ WriteWord)
end, Labels).
-patch_label_or_labels({Pos,Offset}, DataAddress, CodeAddress) ->
+patch_label_or_labels({Pos,Offset}, DataAddress, CodeAddress, WriteWord) ->
?ASSERT(assert_local_patch(CodeAddress+Offset)),
- write_word(DataAddress+Pos, CodeAddress+Offset);
-patch_label_or_labels({sorted,Base,UnOrderdList}, DataAddress, CodeAddress) ->
- sort_and_write(UnOrderdList, Base, DataAddress, CodeAddress).
+ WriteWord(DataAddress+Pos, CodeAddress+Offset);
+patch_label_or_labels({sorted,Base,UnOrderdList}, DataAddress, CodeAddress,
+ WriteWord) ->
+ sort_and_write(UnOrderdList, Base, DataAddress, CodeAddress, WriteWord).
-sort_and_write(UnOrderdList, Base, DataAddress, CodeAddress) ->
+sort_and_write(UnOrderdList, Base, DataAddress, CodeAddress, WriteWord) ->
WriteAndInc =
fun ({_, Offset}, DataPos) ->
?ASSERT(assert_local_patch(CodeAddress+Offset)),
- write_word(DataPos, CodeAddress+Offset)
+ WriteWord(DataPos, CodeAddress+Offset)
end,
lists:foldl(WriteAndInc, DataAddress+Base, sort_on_representation(UnOrderdList)).
@@ -660,17 +675,18 @@ patch_instr(Address, Value, Type) ->
%% XXX: It appears this is used for inserting both code addresses
%% and other data. In HiPE, code addresses are still 32-bit on
%% some 64-bit machines.
-write_word(DataAddress, DataWord) ->
- case erlang:system_info(hipe_architecture) of
- amd64 ->
- hipe_bifs:write_u64(DataAddress, DataWord),
- DataAddress+8;
- ppc64 ->
- hipe_bifs:write_u64(DataAddress, DataWord),
- DataAddress+8;
- _ ->
- hipe_bifs:write_u32(DataAddress, DataWord),
- DataAddress+4
+write_word_fun(WordSize) ->
+ case WordSize of
+ 8 ->
+ fun (DataAddress, DataWord) ->
+ hipe_bifs:write_u64(DataAddress, DataWord),
+ DataAddress+8
+ end;
+ 4 ->
+ fun (DataAddress, DataWord) ->
+ hipe_bifs:write_u32(DataAddress, DataWord),
+ DataAddress+4
+ end
end.
%%--------------------------------------------------------------------
@@ -686,30 +702,31 @@ bif_address(Name) when is_atom(Name) ->
%% memory, and produces a ConstMap2 mapping each constant's ConstNo to
%% its runtime address, tagged if the constant is a term.
%%
-create_data_segment(DataAlign, DataSize, DataList) ->
+create_data_segment(DataAlign, DataSize, DataList, WriteWord) ->
%%io:format("create_data_segment: \nDataAlign: ~p\nDataSize: ~p\nDataList: ~p\n",[DataAlign,DataSize,DataList]),
DataAddress = hipe_bifs:alloc_data(DataAlign, DataSize),
- enter_data(DataList, [], DataAddress, DataSize).
+ enter_data(DataList, [], DataAddress, DataSize, WriteWord).
-enter_data(List, ConstMap2, DataAddress, DataSize) ->
+enter_data(List, ConstMap2, DataAddress, DataSize, WriteWord) ->
case List of
[ConstNo,Offset,Type,Data|Rest] when is_integer(Offset) ->
%%?msg("Const ~w\n",[[ConstNo,Offset,Type,Data]]),
?ASSERT((Offset >= 0) and (Offset =< DataSize)),
- Res = enter_datum(Type, Data, DataAddress+Offset),
- enter_data(Rest, [{ConstNo,Res}|ConstMap2], DataAddress, DataSize);
+ Res = enter_datum(Type, Data, DataAddress+Offset, WriteWord),
+ enter_data(Rest, [{ConstNo,Res}|ConstMap2], DataAddress, DataSize,
+ WriteWord);
[] ->
{DataAddress, ConstMap2}
end.
-enter_datum(Type, Data, Address) ->
+enter_datum(Type, Data, Address, WriteWord) ->
case ?EXT2CONST_TYPE(Type) of
term ->
%% Address is unused for terms
hipe_bifs:term_to_word(hipe_bifs:merge_term(Data));
sorted_block ->
L = lists:sort([hipe_bifs:term_to_word(Term) || Term <- Data]),
- write_words(L, Address),
+ write_words(L, Address, WriteWord),
Address;
block ->
case Data of
@@ -717,7 +734,7 @@ enter_datum(Type, Data, Address) ->
write_bytes(Lbls, Address);
{Lbls, SortOrder} ->
SortedLbls = [Lbl || {_,Lbl} <- lists:sort(group(Lbls, SortOrder))],
- write_words(SortedLbls, Address);
+ write_words(SortedLbls, Address, WriteWord);
Lbls ->
write_bytes(Lbls, Address)
end,
@@ -732,9 +749,9 @@ group([B1,B2,B3,B4|Ls], [O|Os]) ->
bytes_to_32(B4,B3,B2,B1) ->
(B4 bsl 24) bor (B3 bsl 16) bor (B2 bsl 8) bor B1.
-write_words([W|Rest], Addr) ->
- write_words(Rest, write_word(Addr, W));
-write_words([], Addr) when is_integer(Addr) -> true.
+write_words([W|Rest], Addr, WriteWord) ->
+ write_words(Rest, WriteWord(Addr, W), WriteWord);
+write_words([], Addr, _) when is_integer(Addr) -> true.
write_bytes([B|Rest], Addr) ->
hipe_bifs:write_u8(Addr, B),
@@ -810,7 +827,7 @@ address_to_mfa_lth(_Address, [], Prev) ->
%%----------------------------------------------------------------
%% Change callers of the given module to instead trap to BEAM.
-%% load_native_code/2 calls this just before loading native code.
+%% load_native_code/3 calls this just before loading native code.
%%
patch_to_emu(Mod) ->
patch_to_emu_step2(patch_to_emu_step1(Mod)).
@@ -827,7 +844,6 @@ patch_to_emu_step1(Mod) ->
%% were added as the result of dynamic apply calls. We must
%% purge them too, but we have no explicit record of them.
%% Therefore invalidate all native addresses for the module.
- %% emu_make_stubs/1 will repair the ones for compiled static calls.
hipe_bifs:invalidate_funinfo_native_addresses(MFAs),
%% Find all call sites that call these MFAs. As a side-effect,
%% create native stubs for any MFAs that are referred.
@@ -841,7 +857,6 @@ patch_to_emu_step1(Mod) ->
%% Step 2 must occur after the new BEAM stub module is created.
patch_to_emu_step2(ReferencesToPatch) ->
- emu_make_stubs(ReferencesToPatch),
redirect(ReferencesToPatch).
-spec is_loaded(Module::atom()) -> boolean().
@@ -852,21 +867,6 @@ is_loaded(M) when is_atom(M) ->
catch _:_ -> false
end.
--ifdef(notdef).
-emu_make_stubs([{MFA,_Refs}|Rest]) ->
- make_stub(MFA),
- emu_make_stubs(Rest);
-emu_make_stubs([]) ->
- [].
-
-make_stub({_,_,A} = MFA) ->
- EmuAddress = hipe_bifs:get_emu_address(MFA),
- StubAddress = hipe_bifs:make_native_stub(EmuAddress, A),
- hipe_bifs:set_funinfo_native_address(MFA, StubAddress).
--else.
-emu_make_stubs(_) -> [].
--endif.
-
%%--------------------------------------------------------------------
%% Given a list of MFAs, tag them with their referred_from references.
%% The resulting {MFA,Refs} list is later passed to redirect/1, once
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index ec2c350931..c1ae99ea24 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -288,7 +289,7 @@ getifaddrs(Socket) ->
-spec getifaddrs() -> {ok, Iflist} | {error, posix()} when
Iflist :: [{Ifname,[Ifopt]}],
Ifname :: string(),
- Ifopt :: {flag,[Flag]} | {addr,Addr} | {netmask,Netmask}
+ Ifopt :: {flags,[Flag]} | {addr,Addr} | {netmask,Netmask}
| {broadaddr,Broadaddr} | {dstaddr,Dstaddr}
| {hwaddr,Hwaddr},
Flag :: up | broadcast | loopback | pointtopoint
@@ -654,7 +655,7 @@ options() ->
multicast_if, multicast_ttl, multicast_loop,
exit_on_close, high_watermark, low_watermark,
high_msgq_watermark, low_msgq_watermark,
- send_timeout, send_timeout_close
+ send_timeout, send_timeout_close, show_econnreset
].
%% Return a list of statistics options
@@ -670,9 +671,10 @@ stats() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
connect_options() ->
[tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
- header, active, packet, packet_size, buffer, mode, deliver,
+ header, active, packet, packet_size, buffer, mode, deliver, line_delimiter,
exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
- low_msgq_watermark, send_timeout, send_timeout_close, delay_send, raw].
+ low_msgq_watermark, send_timeout, send_timeout_close, delay_send, raw,
+ show_econnreset].
connect_options(Opts, Family) ->
BaseOpts =
@@ -690,6 +692,7 @@ connect_options(Opts, Family) ->
case con_opt(Opts, BaseOpts, connect_options()) of
{ok, R} ->
{ok, R#connect_opts {
+ opts = lists:reverse(R#connect_opts.opts),
ifaddr = translate_ip(R#connect_opts.ifaddr, Family)
}};
Error -> Error
@@ -719,6 +722,8 @@ con_opt([Opt | Opts], #connect_opts{} = R, As) ->
{active,N} when is_integer(N), N < 32768, N >= -32768 ->
NOpts = lists:keydelete(active, 1, R#connect_opts.opts),
con_opt(Opts, R#connect_opts { opts = [{active,N}|NOpts] }, As);
+ {line_delimiter,C} when is_integer(C), C >= 0, C =< 255 ->
+ con_add(line_delimiter, C, R, Opts, As);
{Name,Val} when is_atom(Name) -> con_add(Name, Val, R, Opts, As);
_ -> {error, badarg}
end;
@@ -740,7 +745,7 @@ listen_options() ->
header, active, packet, buffer, mode, deliver, backlog, ipv6_v6only,
exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
low_msgq_watermark, send_timeout, send_timeout_close, delay_send,
- packet_size, raw].
+ packet_size, raw, show_econnreset].
listen_options(Opts, Family) ->
BaseOpts =
@@ -758,6 +763,7 @@ listen_options(Opts, Family) ->
case list_opt(Opts, BaseOpts, listen_options()) of
{ok, R} ->
{ok, R#listen_opts {
+ opts = lists:reverse(R#listen_opts.opts),
ifaddr = translate_ip(R#listen_opts.ifaddr, Family)
}};
Error -> Error
@@ -816,6 +822,7 @@ udp_options(Opts, Family) ->
case udp_opt(Opts, #udp_opts { }, udp_options()) of
{ok, R} ->
{ok, R#udp_opts {
+ opts = lists:reverse(R#udp_opts.opts),
ifaddr = translate_ip(R#udp_opts.ifaddr, Family)
}};
Error -> Error
@@ -889,9 +896,12 @@ sctp_options() ->
sctp_options(Opts, Mod) ->
case sctp_opt(Opts, Mod, #sctp_opts{}, sctp_options()) of
{ok,#sctp_opts{ifaddr=undefined}=SO} ->
- {ok,SO#sctp_opts{ifaddr=Mod:translate_ip(?SCTP_DEF_IFADDR)}};
- {ok,_}=OK ->
- OK;
+ {ok,
+ SO#sctp_opts{
+ opts=lists:reverse(SO#sctp_opts.opts),
+ ifaddr=Mod:translate_ip(?SCTP_DEF_IFADDR)}};
+ {ok,SO} ->
+ {ok,SO#sctp_opts{opts=lists:reverse(SO#sctp_opts.opts)}};
Error -> Error
end.
@@ -963,6 +973,8 @@ add_opt(Name, Val, Opts, As) ->
case lists:member(Name, As) of
true ->
case prim_inet:is_sockopt_val(Name, Val) of
+ true when Name =:= raw ->
+ {ok, [{Name,Val} | Opts]};
true ->
Opts1 = lists:keydelete(Name, 1, Opts),
{ok, [{Name,Val} | Opts1]};
@@ -1527,26 +1539,28 @@ tcp_controlling_process(S, NewOwner) when is_port(S), is_pid(NewOwner) ->
_ ->
case prim_inet:getopt(S, active) of
{ok, A0} ->
- case A0 of
- false -> ok;
- _ -> ok = prim_inet:setopt(S, active, false)
- end,
- case tcp_sync_input(S, NewOwner, false) of
- true -> %% socket already closed,
+ SetOptRes =
+ case A0 of
+ false -> ok;
+ _ -> prim_inet:setopt(S, active, false)
+ end,
+ case {tcp_sync_input(S, NewOwner, false), SetOptRes} of
+ {true, _} -> %% socket already closed
ok;
- false ->
+ {false, ok} ->
try erlang:port_connect(S, NewOwner) of
true ->
unlink(S), %% unlink from port
case A0 of
false -> ok;
- _ -> ok = prim_inet:setopt(S, active, A0)
- end,
- ok
+ _ -> prim_inet:setopt(S, active, A0)
+ end
catch
error:Reason ->
{error, Reason}
- end
+ end;
+ {false, Error} ->
+ Error
end;
Error ->
Error
diff --git a/lib/kernel/src/inet6_sctp.erl b/lib/kernel/src/inet6_sctp.erl
index c47483bbdd..5934c269fa 100644
--- a/lib/kernel/src/inet6_sctp.erl
+++ b/lib/kernel/src/inet6_sctp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet6_tcp.erl b/lib/kernel/src/inet6_tcp.erl
index c714b2bee0..1978307b3c 100644
--- a/lib/kernel/src/inet6_tcp.erl
+++ b/lib/kernel/src/inet6_tcp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,10 +25,29 @@
-export([controlling_process/2]).
-export([fdopen/2]).
+-export([family/0, mask/2, parse_address/1]).
-export([getserv/1, getaddr/1, getaddr/2, getaddrs/1, getaddrs/2]).
-include("inet_int.hrl").
+%% my address family
+family() -> inet6.
+
+%% Apply netmask on address
+mask({M1,M2,M3,M4,M5,M6,M7,M8}, {IP1,IP2,IP3,IP4,IP5,IP6,IP7,IP8}) ->
+ {M1 band IP1,
+ M2 band IP2,
+ M3 band IP3,
+ M4 band IP4,
+ M5 band IP5,
+ M6 band IP6,
+ M7 band IP7,
+ M8 band IP8 }.
+
+%% Parse address string
+parse_address(Host) ->
+ inet_parse:ipv6strict_address(Host).
+
%% inet_tcp port lookup
getserv(Port) when is_integer(Port) -> {ok, Port};
getserv(Name) when is_atom(Name) -> inet:getservbyname(Name,tcp).
diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl
index 459fdc2ad5..3ab7f269bb 100644
--- a/lib/kernel/src/inet6_tcp_dist.erl
+++ b/lib/kernel/src/inet6_tcp_dist.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,28 +24,6 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
-%% internal exports
-
--export([accept_loop/2,do_accept/6,do_setup/6, getstat/1,tick/1]).
-
--import(error_logger,[error_msg/2]).
-
--include("net_address.hrl").
-
-
-
--define(to_port(Socket, Data, Opts),
- case inet6_tcp:send(Socket, Data, Opts) of
- {error, closed} ->
- self() ! {tcp_closed, Socket},
- {error, closed};
- R ->
- R
- end).
-
-
--include("dist.hrl").
--include("dist_util.hrl").
%% ------------------------------------------------------------
%% Select this protocol based on node name
@@ -52,14 +31,7 @@
%% ------------------------------------------------------------
select(Node) ->
- case split_node(atom_to_list(Node), $@, []) of
- [_, Host] ->
- case inet:getaddr(Host,inet6) of
- {ok,_} -> true;
- _ -> false
- end;
- _ -> false
- end.
+ inet_tcp_dist:gen_select(inet6_tcp, Node).
%% ------------------------------------------------------------
%% Create the listen socket, i.e. the port that this erlang
@@ -67,59 +39,14 @@ select(Node) ->
%% ------------------------------------------------------------
listen(Name) ->
- case inet6_tcp:listen(0, [{active, false}, {packet,2}]) of
- {ok, Socket} ->
- TcpAddress = get_tcp_address(Socket),
- {_,Port} = TcpAddress#net_address.address,
- case erl_epmd:register_node(Name, Port) of
- {ok, Creation} ->
- {ok, {Socket, TcpAddress, Creation}};
- Error ->
- Error
- end;
- Error ->
- Error
- end.
+ inet_tcp_dist:gen_listen(inet6_tcp, Name).
%% ------------------------------------------------------------
%% Accepts new connection attempts from other Erlang nodes.
%% ------------------------------------------------------------
accept(Listen) ->
- spawn_opt(?MODULE, accept_loop, [self(), Listen], [link, {priority, max}]).
-
-accept_loop(Kernel, Listen) ->
- case inet6_tcp:accept(Listen) of
- {ok, Socket} ->
- Kernel ! {accept,self(),Socket,inet6,tcp},
- _ = controller(Kernel, Socket),
- accept_loop(Kernel, Listen);
- Error ->
- exit(Error)
- end.
-
-controller(Kernel, Socket) ->
- receive
- {Kernel, controller, Pid} ->
- flush_controller(Pid, Socket),
- inet6_tcp:controlling_process(Socket, Pid),
- flush_controller(Pid, Socket),
- Pid ! {self(), controller};
- {Kernel, unsupported_protocol} ->
- exit(unsupported_protocol)
- end.
-
-flush_controller(Pid, Socket) ->
- receive
- {tcp, Socket, Data} ->
- Pid ! {tcp, Socket, Data},
- flush_controller(Pid, Socket);
- {tcp_closed, Socket} ->
- Pid ! {tcp_closed, Socket},
- flush_controller(Pid, Socket)
- after 0 ->
- ok
- end.
+ inet_tcp_dist:gen_accept(inet6_tcp, Listen).
%% ------------------------------------------------------------
%% Accepts a new connection attempt from another Erlang node.
@@ -127,85 +54,7 @@ flush_controller(Pid, Socket) ->
%% ------------------------------------------------------------
accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
- spawn_opt(?MODULE, do_accept,
- [self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
- [link, {priority, max}]).
-
-do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
- receive
- {AcceptPid, controller} ->
- Timer = dist_util:start_timer(SetupTime),
- case check_ip(Socket) of
- true ->
- HSData = #hs_data{
- kernel_pid = Kernel,
- this_node = MyNode,
- socket = Socket,
- timer = Timer,
- this_flags = 0,
- allowed = Allowed,
- f_send = fun(S,D) -> inet6_tcp:send(S,D) end,
- f_recv = fun(S,N,T) -> inet6_tcp:recv(S,N,T)
- end,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts(S,
- [{active, false},
- {packet, 4},
- nodelay()])
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts(S,
- [{active, true},
- {deliver, port},
- {packet, 4},
- nodelay()])
- end,
- f_getll = fun(S) ->
- inet:getll(S)
- end,
- f_address = fun get_remote_id/2,
- mf_tick = fun ?MODULE:tick/1,
- mf_getstat = fun ?MODULE:getstat/1
- },
- dist_util:handshake_other_started(HSData);
- {false,IP} ->
- error_msg("** Connection attempt from "
- "disallowed IP ~w ** ~n", [IP]),
- ?shutdown(no_node)
- end
- end.
-
-
-%% we may not always want the nodelay behaviour
-%% for performance reasons
-
-nodelay() ->
- case application:get_env(kernel, dist_nodelay) of
- undefined ->
- {nodelay, true};
- {ok, true} ->
- {nodelay, true};
- {ok, false} ->
- {nodelay, false};
- _ ->
- {nodelay, true}
- end.
-
-
-%% ------------------------------------------------------------
-%% Get remote information about a Socket.
-%% ------------------------------------------------------------
-
-get_remote_id(Socket, Node) ->
- {ok, Address} = inet:peername(Socket),
- [_, Host] = split_node(atom_to_list(Node), $@, []),
- #net_address {
- address = Address,
- host = Host,
- protocol = tcp,
- family = inet6 }.
+ inet_tcp_dist:gen_accept_connection(inet6_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime).
%% ------------------------------------------------------------
%% Setup a new connection to another Erlang node.
@@ -213,214 +62,13 @@ get_remote_id(Socket, Node) ->
%% ------------------------------------------------------------
setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
- spawn_opt(?MODULE, do_setup,
- [self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
- [link, {priority, max}]).
-
-do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
- ?trace("~p~n",[{?MODULE,self(),setup,Node}]),
- [Name, Address] = splitnode(Node, LongOrShortNames),
- case inet:getaddr(Address, inet6) of
- {ok, Ip} ->
- Timer = dist_util:start_timer(SetupTime),
- case erl_epmd:port_please(Name, Ip) of
- {port, TcpPort, Version} ->
- ?trace("port_please(~p) -> version ~p~n",
- [Node,Version]),
- dist_util:reset_timer(Timer),
- case inet6_tcp:connect(Ip, TcpPort,
- [{active, false},
- {packet,2}]) of
- {ok, Socket} ->
- HSData = #hs_data{
- kernel_pid = Kernel,
- other_node = Node,
- this_node = MyNode,
- socket = Socket,
- timer = Timer,
- this_flags = 0,
- other_version = Version,
- f_send = fun inet6_tcp:send/2,
- f_recv = fun inet6_tcp:recv/3,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts
- (S,
- [{active, false},
- {packet, 4},
- nodelay()])
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts
- (S,
- [{active, true},
- {deliver, port},
- {packet, 4},
- nodelay()])
- end,
- f_getll = fun inet:getll/1,
- f_address =
- fun(_,_) ->
- #net_address {
- address = {Ip,TcpPort},
- host = Address,
- protocol = tcp,
- family = inet6}
- end,
- mf_tick = fun ?MODULE:tick/1,
- mf_getstat = fun ?MODULE:getstat/1,
- request_type = Type
- },
- dist_util:handshake_we_started(HSData);
- _ ->
- %% Other Node may have closed since
- %% port_please !
- ?trace("other node (~p) "
- "closed since port_please.~n",
- [Node]),
- ?shutdown(Node)
- end;
- _ ->
- ?trace("port_please (~p) "
- "failed.~n", [Node]),
- ?shutdown(Node)
- end;
- __Other ->
- ?trace("inet_getaddr(~p) "
- "failed (~p).~n", [Node,__Other]),
- ?shutdown(Node)
- end.
+ inet_tcp_dist:gen_setup(inet6_tcp, Node, Type, MyNode, LongOrShortNames, SetupTime).
%%
%% Close a socket.
%%
close(Socket) ->
inet6_tcp:close(Socket).
-
-
-%% If Node is illegal terminate the connection setup!!
-splitnode(Node, LongOrShortNames) ->
- case split_node(atom_to_list(Node), $@, []) of
- [Name|Tail] when Tail =/= [] ->
- Host = lists:append(Tail),
- case split_node(Host, $., []) of
- [_] when LongOrShortNames =:= longnames ->
- case inet_parse:ipv6strict_address(Host) of
- {ok, _} ->
- [Name, Host];
- _ ->
- error_msg("** System running to use "
- "fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node)
- end;
- L when length(L) > 1, LongOrShortNames =:= shortnames ->
- error_msg("** System NOT running to use fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node);
- _ ->
- [Name, Host]
- end;
- [_] ->
- error_msg("** Nodename ~p illegal, no '@' character **~n",
- [Node]),
- ?shutdown(Node);
- _ ->
- error_msg("** Nodename ~p illegal **~n", [Node]),
- ?shutdown(Node)
- end.
-
-split_node([Chr|T], Chr, Ack) -> [lists:reverse(Ack)|split_node(T, Chr, [])];
-split_node([H|T], Chr, Ack) -> split_node(T, Chr, [H|Ack]);
-split_node([], _, Ack) -> [lists:reverse(Ack)].
-
-%% ------------------------------------------------------------
-%% Fetch local information about a Socket.
-%% ------------------------------------------------------------
-get_tcp_address(Socket) ->
- {ok, Address} = inet:sockname(Socket),
- {ok, Host} = inet:gethostname(),
- #net_address {
- address = Address,
- host = Host,
- protocol = tcp,
- family = inet6
- }.
-
-%% ------------------------------------------------------------
-%% Do only accept new connection attempts from nodes at our
-%% own LAN, if the check_ip environment parameter is true.
-%% ------------------------------------------------------------
-check_ip(Socket) ->
- case application:get_env(check_ip) of
- {ok, true} ->
- case get_ifs(Socket) of
- {ok, IFs, IP} ->
- check_ip(IFs, IP);
- _ ->
- ?shutdown(no_node)
- end;
- _ ->
- true
- end.
-
-get_ifs(Socket) ->
- case inet:peername(Socket) of
- {ok, {IP, _}} ->
- case inet:getif(Socket) of
- {ok, IFs} -> {ok, IFs, IP};
- Error -> Error
- end;
- Error ->
- Error
- end.
-
-check_ip([{OwnIP, _, Netmask}|IFs], PeerIP) ->
- case {mask(Netmask, PeerIP), mask(Netmask, OwnIP)} of
- {M, M} -> true;
- _ -> check_ip(IFs, PeerIP)
- end;
-check_ip([], PeerIP) ->
- {false, PeerIP}.
-mask({M1,M2,M3,M4,M5,M6,M7,M8}, {IP1,IP2,IP3,IP4,IP5,IP6,IP7,IP8}) ->
- {M1 band IP1,
- M2 band IP2,
- M3 band IP3,
- M4 band IP4,
- M5 band IP5,
- M6 band IP6,
- M7 band IP7,
- M8 band IP8 }.
-
is_node_name(Node) when is_atom(Node) ->
- case split_node(atom_to_list(Node), $@, []) of
- [_,_Host] -> true;
- _ -> false
- end;
-is_node_name(_Node) ->
- false.
-tick(Sock) ->
- ?to_port(Sock,[],[force]).
-getstat(Socket) ->
- case inet:getstat(Socket, [recv_cnt, send_cnt, send_pend]) of
- {ok, Stat} ->
- split_stat(Stat,0,0,0);
- Error ->
- Error
- end.
-
-split_stat([{recv_cnt, R}|Stat], _, W, P) ->
- split_stat(Stat, R, W, P);
-split_stat([{send_cnt, W}|Stat], R, _, P) ->
- split_stat(Stat, R, W, P);
-split_stat([{send_pend, P}|Stat], R, W, _) ->
- split_stat(Stat, R, W, P);
-split_stat([], R, W, P) ->
- {ok, R, W, P}.
-
+ inet_tcp_dist:is_node_name(Node).
diff --git a/lib/kernel/src/inet6_udp.erl b/lib/kernel/src/inet6_udp.erl
index ca43c94211..61c74bf14f 100644
--- a/lib/kernel/src/inet6_udp.erl
+++ b/lib/kernel/src/inet6_udp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_boot.hrl b/lib/kernel/src/inet_boot.hrl
index 35501a0f9c..ec0d4064e5 100644
--- a/lib/kernel/src/inet_boot.hrl
+++ b/lib/kernel/src/inet_boot.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_config.erl b/lib/kernel/src/inet_config.erl
index fdc244f959..803fae846e 100644
--- a/lib/kernel/src/inet_config.erl
+++ b/lib/kernel/src/inet_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -113,13 +114,7 @@ init() ->
{unix,_} ->
%% The Etc variable enables us to run tests with other
%% configuration files than the normal ones
- Etc =
- case os:getenv("ERL_INET_ETC_DIR") of
- false ->
- ?DEFAULT_ETC;
- _EtcDir ->
- _EtcDir
- end,
+ Etc = os:getenv("ERL_INET_ETC_DIR", ?DEFAULT_ETC),
case inet_db:res_option(resolv_conf) of
undefined ->
inet_db:res_option(
@@ -152,11 +147,7 @@ erl_dist_mode() ->
do_load_resolv({unix,Type}, longnames) ->
%% The Etc variable enables us to run tests with other
%% configuration files than the normal ones
- Etc = case os:getenv("ERL_INET_ETC_DIR") of
- false -> ?DEFAULT_ETC;
- _EtcDir ->
- _EtcDir
- end,
+ Etc = os:getenv("ERL_INET_ETC_DIR", ?DEFAULT_ETC),
load_resolv(filename:join(Etc, ?DEFAULT_RESOLV), resolv),
case Type of
freebsd -> %% we may have to check version (2.2.2)
@@ -307,10 +298,7 @@ load_hosts(File,Os) ->
win32_load_from_registry(Type) ->
%% The TcpReg variable enables us to run tests with other registry configurations than
%% the normal ones
- TcpReg = case os:getenv("ERL_INET_ETC_DIR") of
- false -> [];
- _TReg -> _TReg
- end,
+ TcpReg = os:getenv("ERL_INET_ETC_DIR", ""),
{ok, Reg} = win32reg:open([read]),
{TcpIp,HFileKey} =
case Type of
diff --git a/lib/kernel/src/inet_config.hrl b/lib/kernel/src/inet_config.hrl
index e9bb79f05d..7faae8d127 100644
--- a/lib/kernel/src/inet_config.hrl
+++ b/lib/kernel/src/inet_config.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl
index 2ebdc0f554..108a803610 100644
--- a/lib/kernel/src/inet_db.erl
+++ b/lib/kernel/src/inet_db.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -632,20 +633,22 @@ make_hostent(Name, Datas, Aliases, Type) ->
hostent_by_domain(Domain, Type) ->
?dbg("hostent_by_domain: ~p~n", [Domain]),
- hostent_by_domain(stripdot(Domain), [], Type).
+ hostent_by_domain(stripdot(Domain), [], [], Type).
-hostent_by_domain(Domain, Aliases, Type) ->
+hostent_by_domain(Domain, Aliases, LAliases, Type) ->
case lookup_type(Domain, Type) of
[] ->
case lookup_cname(Domain) of
[] ->
{error, nxdomain};
[CName | _] ->
- case lists:member(CName, [Domain | Aliases]) of
+ LDomain = tolower(Domain),
+ case lists:member(CName, [LDomain | LAliases]) of
true ->
{error, nxdomain};
false ->
- hostent_by_domain(CName, [Domain | Aliases], Type)
+ hostent_by_domain(CName, [Domain | Aliases],
+ [LDomain | LAliases], Type)
end
end;
Addrs ->
@@ -670,24 +673,26 @@ lookup_rr(Domain, Class, Type) ->
%% match data field directly and cache RRs.
%%
res_hostent_by_domain(Domain, Type, Rec) ->
- res_cache_answer(Rec),
- RRs = Rec#dns_rec.anlist,
+ RRs = lists:map(fun lower_rr/1, Rec#dns_rec.anlist),
+ res_cache_answer(Rec#dns_rec{anlist = RRs}),
?dbg("res_hostent_by_domain: ~p - ~p~n", [Domain, RRs]),
- res_hostent_by_domain(stripdot(Domain), [], Type, RRs).
+ res_hostent_by_domain(stripdot(Domain), [], [], Type, RRs).
-res_hostent_by_domain(Domain, Aliases, Type, RRs) ->
- case res_lookup_type(Domain, Type, RRs) of
+res_hostent_by_domain(Domain, Aliases, LAliases, Type, RRs) ->
+ LDomain = tolower(Domain),
+ case res_lookup_type(LDomain, Type, RRs) of
[] ->
- case res_lookup_type(Domain, ?S_CNAME, RRs) of
+ case res_lookup_type(LDomain, ?S_CNAME, RRs) of
[] ->
{error, nxdomain};
[CName | _] ->
- case lists:member(CName, [Domain | Aliases]) of
+ case lists:member(tolower(CName), [LDomain | LAliases]) of
true ->
{error, nxdomain};
false ->
res_hostent_by_domain(CName, [Domain | Aliases],
- Type, RRs)
+ [LDomain | LAliases], Type,
+ RRs)
end
end;
Addrs ->
@@ -720,7 +725,8 @@ gethostbyaddr(IP) ->
%%
res_gethostbyaddr(IP, Rec) ->
{ok, {IP1, HType, HLen}} = dnt(IP),
- res_cache_answer(Rec),
+ RRs = lists:map(fun lower_rr/1, Rec#dns_rec.anlist),
+ res_cache_answer(Rec#dns_rec{anlist = RRs}),
ent_gethostbyaddr(Rec#dns_rec.anlist, IP1, HType, HLen).
ent_gethostbyaddr(RRs, IP, AddrType, Length) ->
@@ -1372,13 +1378,12 @@ cache_rr(_Db, Cache, RR) ->
ets:insert(Cache, RR).
times() ->
- {Mega,Secs,_} = erlang:now(),
- Mega*1000000 + Secs.
+ erlang:convert_time_unit(erlang:monotonic_time() - erlang:system_info(start_time),native,seconds).
%% lookup and remove old entries
do_lookup_rr(Domain, Class, Type) ->
- match_rr(#dns_rr{domain = Domain, class = Class,type = Type,
+ match_rr(#dns_rr{domain = tolower(Domain), class = Class,type = Type,
cnt = '_', tm = '_', ttl = '_',
bm = '_', func = '_', data = '_'}).
@@ -1400,6 +1405,11 @@ filter_rr([RR | RRs], Time) ->
[RR | filter_rr(RRs, Time)];
filter_rr([], _Time) -> [].
+%% Lower case the domain name before storage.
+%%
+lower_rr(#dns_rr{domain=Domain}=RR) when is_list(Domain) ->
+ RR#dns_rr { domain = tolower(Domain) };
+lower_rr(RR) -> RR.
%%
%% Case fold upper-case to lower-case according to RFC 4343
diff --git a/lib/kernel/src/inet_dns.erl b/lib/kernel/src/inet_dns.erl
index 1289e176c7..f344b26228 100644
--- a/lib/kernel/src/inet_dns.erl
+++ b/lib/kernel/src/inet_dns.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_dns.hrl b/lib/kernel/src/inet_dns.hrl
index 1b69f31a4d..d1b01bb9c4 100644
--- a/lib/kernel/src/inet_dns.hrl
+++ b/lib/kernel/src/inet_dns.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_dns_record_adts.pl b/lib/kernel/src/inet_dns_record_adts.pl
index da50c7114f..6d719d836e 100644
--- a/lib/kernel/src/inet_dns_record_adts.pl
+++ b/lib/kernel/src/inet_dns_record_adts.pl
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2009-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -56,7 +57,8 @@ while(<DATA>) {
$" = ',';
$\ = "\n";
-while( my ($Name, $r) = each(%Names)) {
+foreach my $Name (sort keys %Names) {
+ my $r = $Names{$Name};
# Create substitutions for this Name
my ($Record, @Fields) = @{ $r };
my @FieldMatchValues;
@@ -109,7 +111,8 @@ while( my ($Name, $r) = each(%Names)) {
for my $i ( 0 .. $#INDEX ) {
my $line = $INDEX[$i];
if ($line =~ s/^[*]//) {
- while( my ($Name, $r) = each(%Names)) {
+ foreach my $Name (sort keys %Names) {
+ my $r = $Names{$Name};
my ($Record) = @{ $r };
$_ = $line;
s/Name\b/$Name/g;
diff --git a/lib/kernel/src/inet_gethost_native.erl b/lib/kernel/src/inet_gethost_native.erl
index 4320987078..53294810af 100644
--- a/lib/kernel/src/inet_gethost_native.erl
+++ b/lib/kernel/src/inet_gethost_native.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/inet_hosts.erl b/lib/kernel/src/inet_hosts.erl
index 6e9719b4aa..e8457fd9d6 100644
--- a/lib/kernel/src/inet_hosts.erl
+++ b/lib/kernel/src/inet_hosts.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl
index 889b596a22..e7c6cf8ae2 100644
--- a/lib/kernel/src/inet_int.hrl
+++ b/lib/kernel/src/inet_int.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -147,6 +148,8 @@
-define(INET_LOPT_MSGQ_HIWTRMRK, 36).
-define(INET_LOPT_MSGQ_LOWTRMRK, 37).
-define(INET_LOPT_NETNS, 38).
+-define(INET_LOPT_TCP_SHOW_ECONNRESET, 39).
+-define(INET_LOPT_LINE_DELIM, 40).
% Specific SCTP options: separate range:
-define(SCTP_OPT_RTOINFO, 100).
-define(SCTP_OPT_ASSOCINFO, 101).
diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl
index a88c94a453..877745ed55 100644
--- a/lib/kernel/src/inet_parse.erl
+++ b/lib/kernel/src/inet_parse.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -675,28 +676,22 @@ ipv6_addr_done(Ar, Br, N) ->
ipv6_addr_done(Ar) ->
list_to_tuple(lists:reverse(Ar)).
-%% Collect Hex digits
-hex(Cs) -> hex(Cs, []).
+%% Collect 1-4 Hex digits
+hex(Cs) -> hex(Cs, [], 4).
%%
-hex([C|Cs], R) when C >= $0, C =< $9 ->
- hex(Cs, [C|R]);
-hex([C|Cs], R) when C >= $a, C =< $f ->
- hex(Cs, [C|R]);
-hex([C|Cs], R) when C >= $A, C =< $F ->
- hex(Cs, [C|R]);
-hex(Cs, [_|_]=R) when is_list(Cs) ->
+hex([C|Cs], R, N) when C >= $0, C =< $9, N > 0 ->
+ hex(Cs, [C|R], N-1);
+hex([C|Cs], R, N) when C >= $a, C =< $f, N > 0 ->
+ hex(Cs, [C|R], N-1);
+hex([C|Cs], R, N) when C >= $A, C =< $F, N > 0 ->
+ hex(Cs, [C|R], N-1);
+hex(Cs, [_|_]=R, _) when is_list(Cs) ->
{lists:reverse(R),Cs};
-hex(_, _) ->
+hex(_, _, _) ->
erlang:error(badarg).
%% Hex string to integer
-hex_to_int(Cs0) ->
- case strip0(Cs0) of
- Cs when length(Cs) =< 4 ->
- erlang:list_to_integer("0"++Cs, 16);
- _ ->
- erlang:error(badarg)
- end.
+hex_to_int(Cs) -> erlang:list_to_integer(Cs, 16).
%% Dup onto head of existing list
dup(0, _, L) ->
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 6037da1d22..e6988ac79b 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -715,10 +716,10 @@ udp_send(#sock{inet=I}, {A,B,C,D}=IP, Port, Buffer)
udp_recv(#sock{inet6=I}, {A,B,C,D,E,F,G,H}=IP, Port, Timeout, Decode)
when ?ip6(A,B,C,D,E,F,G,H), ?port(Port) ->
- do_udp_recv(I, IP, Port, Timeout, Decode, erlang:now(), Timeout);
+ do_udp_recv(I, IP, Port, Timeout, Decode, time_now(), Timeout);
udp_recv(#sock{inet=I}, {A,B,C,D}=IP, Port, Timeout, Decode)
when ?ip(A,B,C,D), ?port(Port) ->
- do_udp_recv(I, IP, Port, Timeout, Decode, erlang:now(), Timeout).
+ do_udp_recv(I, IP, Port, Timeout, Decode, time_now(), Timeout).
do_udp_recv(_I, _IP, _Port, 0, _Decode, _Start, _T) ->
timeout;
@@ -742,7 +743,7 @@ do_udp_recv(I, IP, Port, Timeout, Decode, Start, T) ->
NewTimeout = erlang:max(0, Timeout - 50),
do_udp_recv(I, IP, Port, NewTimeout, Decode, Start, T);
false ->
- Now = erlang:now(),
+ Now = time_now(),
NewT = erlang:max(0, Timeout - now_ms(Now, Start)),
do_udp_recv(I, IP, Port, Timeout, Decode, Start, NewT);
Result ->
@@ -1057,5 +1058,9 @@ dns_msg(Msg) ->
end.
-compile({inline, [now_ms/2]}).
-now_ms({Meg1,Sec1,Mic1}, {Meg0,Sec0,Mic0}) ->
- ((Meg1-Meg0)*1000000 + (Sec1-Sec0))*1000 + ((Mic1-Mic0) div 1000).
+now_ms(Int1, Int0) ->
+ Int1 - Int0.
+
+-compile({inline, [time_now/0]}).
+time_now() ->
+ erlang:monotonic_time(1000).
diff --git a/lib/kernel/src/inet_res.hrl b/lib/kernel/src/inet_res.hrl
index bfaf32a1ba..c77fe30e7a 100644
--- a/lib/kernel/src/inet_res.hrl
+++ b/lib/kernel/src/inet_res.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl
index 93528d305d..88c8d24143 100644
--- a/lib/kernel/src/inet_sctp.erl
+++ b/lib/kernel/src/inet_sctp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -133,15 +134,18 @@ connect_get_assoc(S, Addr, Port, Active, Timer) ->
Timeout = inet:timeout(Timer),
receive
{sctp,S,Addr,Port,{_,#sctp_assoc_change{state=St}=Ev}} ->
- case Active of
- once ->
- ok = prim_inet:setopt(S, active, once);
- _ -> ok
- end,
- if St =:= comm_up ->
+ SetOptRes =
+ case Active of
+ once -> prim_inet:setopt(S, active, once);
+ _ -> ok
+ end,
+ case {St, SetOptRes} of
+ {comm_up, ok} ->
{ok,Ev};
- true ->
- {error,Ev}
+ {_, ok} ->
+ {error,Ev};
+ {_, Error} ->
+ Error
end
after Timeout ->
{error,timeout}
diff --git a/lib/kernel/src/inet_tcp.erl b/lib/kernel/src/inet_tcp.erl
index 4c2db16ce3..f551af9709 100644
--- a/lib/kernel/src/inet_tcp.erl
+++ b/lib/kernel/src/inet_tcp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -26,11 +27,25 @@
-export([controlling_process/2]).
-export([fdopen/2]).
+-export([family/0, mask/2, parse_address/1]).
-export([getserv/1, getaddr/1, getaddr/2, getaddrs/1, getaddrs/2]).
-
-include("inet_int.hrl").
+%% my address family
+family() -> inet.
+
+%% Apply netmask on address
+mask({M1,M2,M3,M4}, {IP1,IP2,IP3,IP4}) ->
+ {M1 band IP1,
+ M2 band IP2,
+ M3 band IP3,
+ M4 band IP4}.
+
+%% Parse address string
+parse_address(Host) ->
+ inet_parse:ipv4strict_address(Host).
+
%% inet_tcp port lookup
getserv(Port) when is_integer(Port) -> {ok, Port};
getserv(Name) when is_atom(Name) -> inet:getservbyname(Name,tcp).
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index 835dcf2705..64b28bb49b 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -23,9 +24,13 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+%% Generalized dist API
+-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
+ gen_setup/6, gen_select/2]).
+
%% internal exports
--export([accept_loop/2,do_accept/6,do_setup/6,getstat/1,tick/1]).
+-export([accept_loop/3,do_accept/7,do_setup/7,getstat/1]).
-import(error_logger,[error_msg/2]).
@@ -33,15 +38,6 @@
--define(to_port(Socket, Data, Opts),
- case inet_tcp:send(Socket, Data, Opts) of
- {error, closed} ->
- self() ! {tcp_closed, Socket},
- {error, closed};
- R ->
- R
- end).
-
-include("dist.hrl").
-include("dist_util.hrl").
@@ -52,8 +48,15 @@
%% ------------------------------------------------------------
select(Node) ->
+ gen_select(inet_tcp, Node).
+
+gen_select(Driver, Node) ->
case split_node(atom_to_list(Node), $@, []) of
- [_,_Host] -> true;
+ [_, Host] ->
+ case inet:getaddr(Host, Driver:family()) of
+ {ok,_} -> true;
+ _ -> false
+ end;
_ -> false
end.
@@ -63,9 +66,12 @@ select(Node) ->
%% ------------------------------------------------------------
listen(Name) ->
- case do_listen([{active, false}, {packet,2}, {reuseaddr, true}]) of
+ gen_listen(inet_tcp, Name).
+
+gen_listen(Driver, Name) ->
+ case do_listen(Driver, [{active, false}, {packet,2}, {reuseaddr, true}]) of
{ok, Socket} ->
- TcpAddress = get_tcp_address(Socket),
+ TcpAddress = get_tcp_address(Driver, Socket),
{_,Port} = TcpAddress#net_address.address,
case erl_epmd:register_node(Name, Port) of
{ok, Creation} ->
@@ -77,7 +83,7 @@ listen(Name) ->
Error
end.
-do_listen(Options) ->
+do_listen(Driver, Options) ->
{First,Last} = case application:get_env(kernel,inet_dist_listen_min) of
{ok,N} when is_integer(N) ->
case application:get_env(kernel,
@@ -90,14 +96,14 @@ do_listen(Options) ->
_ ->
{0,0}
end,
- do_listen(First, Last, listen_options([{backlog,128}|Options])).
+ do_listen(Driver, First, Last, listen_options([{backlog,128}|Options])).
-do_listen(First,Last,_) when First > Last ->
+do_listen(_Driver, First,Last,_) when First > Last ->
{error,eaddrinuse};
-do_listen(First,Last,Options) ->
- case inet_tcp:listen(First, Options) of
+do_listen(Driver, First,Last,Options) ->
+ case Driver:listen(First, Options) of
{error, eaddrinuse} ->
- do_listen(First+1,Last,Options);
+ do_listen(Driver, First+1,Last,Options);
Other ->
Other
end.
@@ -112,7 +118,6 @@ listen_options(Opts0) ->
end,
case application:get_env(kernel, inet_dist_listen_options) of
{ok,ListenOpts} ->
- erlang:display({inet_dist_listen_options, ListenOpts}),
ListenOpts ++ Opts1;
_ ->
Opts1
@@ -124,23 +129,26 @@ listen_options(Opts0) ->
%% ------------------------------------------------------------
accept(Listen) ->
- spawn_opt(?MODULE, accept_loop, [self(), Listen], [link, {priority, max}]).
+ gen_accept(inet_tcp, Listen).
+
+gen_accept(Driver, Listen) ->
+ spawn_opt(?MODULE, accept_loop, [Driver, self(), Listen], [link, {priority, max}]).
-accept_loop(Kernel, Listen) ->
- case inet_tcp:accept(Listen) of
+accept_loop(Driver, Kernel, Listen) ->
+ case Driver:accept(Listen) of
{ok, Socket} ->
- Kernel ! {accept,self(),Socket,inet,tcp},
- _ = controller(Kernel, Socket),
- accept_loop(Kernel, Listen);
+ Kernel ! {accept,self(),Socket,Driver:family(),tcp},
+ _ = controller(Driver, Kernel, Socket),
+ accept_loop(Driver, Kernel, Listen);
Error ->
exit(Error)
end.
-controller(Kernel, Socket) ->
+controller(Driver, Kernel, Socket) ->
receive
{Kernel, controller, Pid} ->
flush_controller(Pid, Socket),
- inet_tcp:controlling_process(Socket, Pid),
+ Driver:controlling_process(Socket, Pid),
flush_controller(Pid, Socket),
Pid ! {self(), controller};
{Kernel, unsupported_protocol} ->
@@ -165,15 +173,18 @@ flush_controller(Pid, Socket) ->
%% ------------------------------------------------------------
accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+ gen_accept_connection(inet_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime).
+
+gen_accept_connection(Driver, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
spawn_opt(?MODULE, do_accept,
- [self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
+ [Driver, self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
[link, {priority, max}]).
-do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
receive
{AcceptPid, controller} ->
Timer = dist_util:start_timer(SetupTime),
- case check_ip(Socket) of
+ case check_ip(Driver, Socket) of
true ->
HSData = #hs_data{
kernel_pid = Kernel,
@@ -182,9 +193,8 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
timer = Timer,
this_flags = 0,
allowed = Allowed,
- f_send = fun(S,D) -> inet_tcp:send(S,D) end,
- f_recv = fun(S,N,T) -> inet_tcp:recv(S,N,T)
- end,
+ f_send = fun Driver:send/2,
+ f_recv = fun Driver:recv/3,
f_setopts_pre_nodeup =
fun(S) ->
inet:setopts(S,
@@ -203,8 +213,8 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
f_getll = fun(S) ->
inet:getll(S)
end,
- f_address = fun get_remote_id/2,
- mf_tick = fun ?MODULE:tick/1,
+ f_address = fun(S, Node) -> get_remote_id(Driver, S, Node) end,
+ mf_tick = fun(S) -> tick(Driver, S) end,
mf_getstat = fun ?MODULE:getstat/1
},
dist_util:handshake_other_started(HSData);
@@ -235,13 +245,13 @@ nodelay() ->
%% ------------------------------------------------------------
%% Get remote information about a Socket.
%% ------------------------------------------------------------
-get_remote_id(Socket, Node) ->
+get_remote_id(Driver, Socket, Node) ->
case inet:peername(Socket) of
{ok,Address} ->
case split_node(atom_to_list(Node), $@, []) of
[_,Host] ->
#net_address{address=Address,host=Host,
- protocol=tcp,family=inet};
+ protocol=tcp,family=Driver:family()};
_ ->
%% No '@' or more than one '@' in node name.
?shutdown(no_node)
@@ -256,14 +266,18 @@ get_remote_id(Socket, Node) ->
%% ------------------------------------------------------------
setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
+ gen_setup(inet_tcp, Node, Type, MyNode, LongOrShortNames, SetupTime).
+
+gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
spawn_opt(?MODULE, do_setup,
- [self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
+ [Driver, self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
[link, {priority, max}]).
-do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
+do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
?trace("~p~n",[{inet_tcp_dist,self(),setup,Node}]),
- [Name, Address] = splitnode(Node, LongOrShortNames),
- case inet:getaddr(Address, inet) of
+ [Name, Address] = splitnode(Driver, Node, LongOrShortNames),
+ AddressFamily = Driver:family(),
+ case inet:getaddr(Address, AddressFamily) of
{ok, Ip} ->
Timer = dist_util:start_timer(SetupTime),
case erl_epmd:port_please(Name, Ip) of
@@ -272,7 +286,7 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
[Node,Version]),
dist_util:reset_timer(Timer),
case
- inet_tcp:connect(
+ Driver:connect(
Ip, TcpPort,
connect_options([{active, false}, {packet, 2}]))
of
@@ -285,8 +299,8 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
timer = Timer,
this_flags = 0,
other_version = Version,
- f_send = fun inet_tcp:send/2,
- f_recv = fun inet_tcp:recv/3,
+ f_send = fun Driver:send/2,
+ f_recv = fun Driver:recv/3,
f_setopts_pre_nodeup =
fun(S) ->
inet:setopts
@@ -311,9 +325,9 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
address = {Ip,TcpPort},
host = Address,
protocol = tcp,
- family = inet}
+ family = AddressFamily}
end,
- mf_tick = fun ?MODULE:tick/1,
+ mf_tick = fun(S) -> tick(Driver, S) end,
mf_getstat = fun ?MODULE:getstat/1,
request_type = Type
},
@@ -340,7 +354,6 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
connect_options(Opts) ->
case application:get_env(kernel, inet_dist_connect_options) of
{ok,ConnectOpts} ->
- erlang:display({inet_dist_listen_options, ConnectOpts}),
ConnectOpts ++ Opts;
_ ->
Opts
@@ -354,18 +367,23 @@ close(Socket) ->
%% If Node is illegal terminate the connection setup!!
-splitnode(Node, LongOrShortNames) ->
+splitnode(Driver, Node, LongOrShortNames) ->
case split_node(atom_to_list(Node), $@, []) of
[Name|Tail] when Tail =/= [] ->
Host = lists:append(Tail),
case split_node(Host, $., []) of
[_] when LongOrShortNames =:= longnames ->
- error_msg("** System running to use "
- "fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node);
+ case Driver:parse_address(Host) of
+ {ok, _} ->
+ [Name, Host];
+ _ ->
+ error_msg("** System running to use "
+ "fully qualified "
+ "hostnames **~n"
+ "** Hostname ~s is illegal **~n",
+ [Host]),
+ ?shutdown(Node)
+ end;
L when length(L) > 1, LongOrShortNames =:= shortnames ->
error_msg("** System NOT running to use fully qualified "
"hostnames **~n"
@@ -391,26 +409,26 @@ split_node([], _, Ack) -> [lists:reverse(Ack)].
%% ------------------------------------------------------------
%% Fetch local information about a Socket.
%% ------------------------------------------------------------
-get_tcp_address(Socket) ->
+get_tcp_address(Driver, Socket) ->
{ok, Address} = inet:sockname(Socket),
{ok, Host} = inet:gethostname(),
#net_address {
address = Address,
host = Host,
protocol = tcp,
- family = inet
+ family = Driver:family()
}.
%% ------------------------------------------------------------
%% Do only accept new connection attempts from nodes at our
%% own LAN, if the check_ip environment parameter is true.
%% ------------------------------------------------------------
-check_ip(Socket) ->
+check_ip(Driver, Socket) ->
case application:get_env(check_ip) of
{ok, true} ->
case get_ifs(Socket) of
{ok, IFs, IP} ->
- check_ip(IFs, IP);
+ check_ip(Driver, IFs, IP);
_ ->
?shutdown(no_node)
end;
@@ -429,20 +447,14 @@ get_ifs(Socket) ->
Error
end.
-check_ip([{OwnIP, _, Netmask}|IFs], PeerIP) ->
- case {mask(Netmask, PeerIP), mask(Netmask, OwnIP)} of
+check_ip(Driver, [{OwnIP, _, Netmask}|IFs], PeerIP) ->
+ case {Driver:mask(Netmask, PeerIP), Driver:mask(Netmask, OwnIP)} of
{M, M} -> true;
- _ -> check_ip(IFs, PeerIP)
+ _ -> check_ip(Driver, IFs, PeerIP)
end;
-check_ip([], PeerIP) ->
+check_ip(_Driver, [], PeerIP) ->
{false, PeerIP}.
-mask({M1,M2,M3,M4}, {IP1,IP2,IP3,IP4}) ->
- {M1 band IP1,
- M2 band IP2,
- M3 band IP3,
- M4 band IP4}.
-
is_node_name(Node) when is_atom(Node) ->
case split_node(atom_to_list(Node), $@, []) of
[_, _Host] -> true;
@@ -451,8 +463,14 @@ is_node_name(Node) when is_atom(Node) ->
is_node_name(_Node) ->
false.
-tick(Sock) ->
- ?to_port(Sock,[],[force]).
+tick(Driver, Socket) ->
+ case Driver:send(Socket, [], [force]) of
+ {error, closed} ->
+ self() ! {tcp_closed, Socket},
+ {error, closed};
+ R ->
+ R
+ end.
getstat(Socket) ->
case inet:getstat(Socket, [recv_cnt, send_cnt, send_pend]) of
diff --git a/lib/kernel/src/inet_udp.erl b/lib/kernel/src/inet_udp.erl
index 80d930fe10..5b2e5120c9 100644
--- a/lib/kernel/src/inet_udp.erl
+++ b/lib/kernel/src/inet_udp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 9f6c0f4624..419dc0a2fc 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -115,6 +116,6 @@
{applications, []},
{env, [{error_logger, tty}]},
{mod, {kernel, []}},
- {runtime_dependencies, ["erts-6.1.2", "stdlib-2.0", "sasl-2.4"]}
+ {runtime_dependencies, ["erts-7.3", "stdlib-2.6", "sasl-2.6"]}
]
}.
diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src
index f8f4cc1ec2..cc9e6f771a 100644
--- a/lib/kernel/src/kernel.appup.src
+++ b/lib/kernel/src/kernel.appup.src
@@ -1,25 +1,26 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
+ [{<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"3\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-17
%% Down to - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
+ [{<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"3\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-17
}.
diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl
index ecdb32424a..5f33f25a0d 100644
--- a/lib/kernel/src/kernel.erl
+++ b/lib/kernel/src/kernel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -117,7 +118,7 @@ init([]) ->
[{local, kernel_safe_sup}, ?MODULE, safe]},
permanent, infinity, supervisor, [?MODULE]},
{ok, {SupFlags,
- [File, Code, StdError, User,
+ [Code, File, StdError, User,
Config, SafeSupervisor]}};
_ ->
Rpc = {rex, {rpc, start_link, []},
@@ -139,8 +140,8 @@ init([]) ->
[{local, kernel_safe_sup}, ?MODULE, safe]},
permanent, infinity, supervisor, [?MODULE]},
{ok, {SupFlags,
- [Rpc, Global, InetDb | DistAC] ++
- [NetSup, Glo_grp, File, Code,
+ [Code, Rpc, Global, InetDb | DistAC] ++
+ [NetSup, Glo_grp, File,
StdError, User, Config, SafeSupervisor] ++ Timer}}
end;
init(safe) ->
diff --git a/lib/kernel/src/kernel_config.erl b/lib/kernel/src/kernel_config.erl
index 56defcb167..c65728aa53 100644
--- a/lib/kernel/src/kernel_config.erl
+++ b/lib/kernel/src/kernel_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/net.erl b/lib/kernel/src/net.erl
index e8f4b6ba26..f058042bdd 100644
--- a/lib/kernel/src/net.erl
+++ b/lib/kernel/src/net.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/net_adm.erl b/lib/kernel/src/net_adm.erl
index 2cdfb76417..e6a81126c2 100644
--- a/lib/kernel/src/net_adm.erl
+++ b/lib/kernel/src/net_adm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index 04a0d94ebf..35a54f591e 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index 187fd0001b..3330b38d84 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,7 +27,8 @@
%%% BIFs
--export([getenv/0, getenv/1, getpid/0, putenv/2, timestamp/0, unsetenv/1]).
+-export([getenv/0, getenv/1, getenv/2, getpid/0, putenv/2, system_time/0, system_time/1,
+ timestamp/0, unsetenv/1]).
-spec getenv() -> [string()].
@@ -39,6 +41,19 @@ getenv() -> erlang:nif_error(undef).
getenv(_) ->
erlang:nif_error(undef).
+-spec getenv(VarName, DefaultValue) -> Value when
+ VarName :: string(),
+ DefaultValue :: string(),
+ Value :: string().
+
+getenv(VarName, DefaultValue) ->
+ case os:getenv(VarName) of
+ false ->
+ DefaultValue;
+ Value ->
+ Value
+ end.
+
-spec getpid() -> Value when
Value :: string().
@@ -52,6 +67,17 @@ getpid() ->
putenv(_, _) ->
erlang:nif_error(undef).
+-spec system_time() -> integer().
+
+system_time() ->
+ erlang:nif_error(undef).
+
+-spec system_time(Unit) -> integer() when
+ Unit :: erlang:time_unit().
+
+system_time(_Unit) ->
+ erlang:nif_error(undef).
+
-spec timestamp() -> Timestamp when
Timestamp :: erlang:timestamp().
@@ -85,10 +111,7 @@ version() ->
Name :: string(),
Filename :: string().
find_executable(Name) ->
- case os:getenv("PATH") of
- false -> find_executable(Name, []);
- Path -> find_executable(Name, Path)
- end.
+ find_executable(Name, os:getenv("PATH", "")).
-spec find_executable(Name, Path) -> Filename | 'false' when
Name :: string(),
diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl
index b562d4ffd2..ab98181b2a 100644
--- a/lib/kernel/src/pg2.erl
+++ b/lib/kernel/src/pg2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -140,19 +141,22 @@ get_closest_pid(Name) ->
[Pid] ->
Pid;
[] ->
- {_,_,X} = erlang:now(),
case get_members(Name) of
[] -> {error, {no_process, Name}};
Members ->
- lists:nth((X rem length(Members))+1, Members)
+ random_element(Members)
end;
Members when is_list(Members) ->
- {_,_,X} = erlang:now(),
- lists:nth((X rem length(Members))+1, Members);
+ random_element(Members);
Else ->
Else
end.
+random_element(List) ->
+ X = abs(erlang:monotonic_time()
+ bxor erlang:unique_integer()),
+ lists:nth((X rem length(List)) + 1, List).
+
%%%
%%% Callback functions from gen_server
%%%
diff --git a/lib/kernel/src/ram_file.erl b/lib/kernel/src/ram_file.erl
index ca881ff8a4..df335f7a8e 100644
--- a/lib/kernel/src/ram_file.erl
+++ b/lib/kernel/src/ram_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl
index 2300b7e901..d3db8eb80a 100644
--- a/lib/kernel/src/rpc.erl
+++ b/lib/kernel/src/rpc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,7 +23,7 @@
%% facility
%% This code used to reside in net.erl, but has now been moved to
-%% a searate module.
+%% a separate module.
-define(NAME, rex).
diff --git a/lib/kernel/src/seq_trace.erl b/lib/kernel/src/seq_trace.erl
index 38a61f4644..a7a782c29c 100644
--- a/lib/kernel/src/seq_trace.erl
+++ b/lib/kernel/src/seq_trace.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -22,7 +23,9 @@
-define(SEQ_TRACE_SEND, 1). %(1 << 0)
-define(SEQ_TRACE_RECEIVE, 2). %(1 << 1)
-define(SEQ_TRACE_PRINT, 4). %(1 << 2)
--define(SEQ_TRACE_TIMESTAMP, 8). %(1 << 3)
+-define(SEQ_TRACE_NOW_TIMESTAMP, 8). %(1 << 3)
+-define(SEQ_TRACE_STRICT_MON_TIMESTAMP, 16). %(1 << 4)
+-define(SEQ_TRACE_MON_TIMESTAMP, 32). %(1 << 5)
-export([set_token/1,
set_token/2,
@@ -36,7 +39,7 @@
%%---------------------------------------------------------------------------
--type flag() :: 'send' | 'receive' | 'print' | 'timestamp'.
+-type flag() :: 'send' | 'receive' | 'print' | 'timestamp' | 'monotonic_timestamp' | 'strict_monotonic_timestamp'.
-type component() :: 'label' | 'serial' | flag().
-type value() :: (Integer :: non_neg_integer())
| {Previous :: non_neg_integer(),
@@ -134,5 +137,9 @@ decode_flags(Flags) ->
Print = (Flags band ?SEQ_TRACE_PRINT) > 0,
Send = (Flags band ?SEQ_TRACE_SEND) > 0,
Rec = (Flags band ?SEQ_TRACE_RECEIVE) > 0,
- Ts = (Flags band ?SEQ_TRACE_TIMESTAMP) > 0,
- [{print,Print},{send,Send},{'receive',Rec},{timestamp,Ts}].
+ NowTs = (Flags band ?SEQ_TRACE_NOW_TIMESTAMP) > 0,
+ StrictMonTs = (Flags band ?SEQ_TRACE_STRICT_MON_TIMESTAMP) > 0,
+ MonTs = (Flags band ?SEQ_TRACE_MON_TIMESTAMP) > 0,
+ [{print,Print},{send,Send},{'receive',Rec},{timestamp,NowTs},
+ {strict_monotonic_timestamp, StrictMonTs},
+ {monotonic_timestamp, MonTs}].
diff --git a/lib/kernel/src/standard_error.erl b/lib/kernel/src/standard_error.erl
index 1c43063937..74dd004fa6 100644
--- a/lib/kernel/src/standard_error.erl
+++ b/lib/kernel/src/standard_error.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/user.erl b/lib/kernel/src/user.erl
index 40376ef752..77781e0251 100644
--- a/lib/kernel/src/user.erl
+++ b/lib/kernel/src/user.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/src/user_drv.erl b/lib/kernel/src/user_drv.erl
index a91c23539d..b794d4f45e 100644
--- a/lib/kernel/src/user_drv.erl
+++ b/lib/kernel/src/user_drv.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -29,6 +30,7 @@
-define(OP_INSC,2).
-define(OP_DELC,3).
-define(OP_BEEP,4).
+-define(OP_PUTC_SYNC,5).
% Control op
-define(CTRL_OP_GET_WINSIZE,100).
-define(CTRL_OP_GET_UNICODE_STATE,101).
@@ -132,8 +134,9 @@ server1(Iport, Oport, Shell) ->
flatten(io_lib:format("~ts\n",
[erlang:system_info(system_version)]))},
Iport, Oport),
+
%% Enter the server loop.
- server_loop(Iport, Oport, Curr, User, Gr).
+ server_loop(Iport, Oport, Curr, User, Gr, {false, queue:new()}).
rem_sh_opts(Node) ->
[{expand_fun,fun(B)-> rpc:call(Node,edlin_expand,expand,[B]) end}].
@@ -158,42 +161,41 @@ start_user() ->
User
end.
-server_loop(Iport, Oport, User, Gr) ->
+server_loop(Iport, Oport, User, Gr, IOQueue) ->
Curr = gr_cur_pid(Gr),
put(current_group, Curr),
- server_loop(Iport, Oport, Curr, User, Gr).
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue).
-server_loop(Iport, Oport, Curr, User, Gr) ->
+server_loop(Iport, Oport, Curr, User, Gr, {Resp, IOQ} = IOQueue) ->
receive
{Iport,{data,Bs}} ->
BsBin = list_to_binary(Bs),
Unicode = unicode:characters_to_list(BsBin,utf8),
- port_bytes(Unicode, Iport, Oport, Curr, User, Gr);
+ port_bytes(Unicode, Iport, Oport, Curr, User, Gr, IOQueue);
{Iport,eof} ->
Curr ! {self(),eof},
- server_loop(Iport, Oport, Curr, User, Gr);
- {User,Req} -> % never block from user!
- io_request(Req, Iport, Oport),
- server_loop(Iport, Oport, Curr, User, Gr);
- {Curr,tty_geometry} ->
- Curr ! {self(),tty_geometry,get_tty_geometry(Iport)},
- server_loop(Iport, Oport, Curr, User, Gr);
- {Curr,get_unicode_state} ->
- Curr ! {self(),get_unicode_state,get_unicode_state(Iport)},
- server_loop(Iport, Oport, Curr, User, Gr);
- {Curr,set_unicode_state, Bool} ->
- Curr ! {self(),set_unicode_state,set_unicode_state(Iport,Bool)},
- server_loop(Iport, Oport, Curr, User, Gr);
- {Curr,Req} ->
- io_request(Req, Iport, Oport),
- server_loop(Iport, Oport, Curr, User, Gr);
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue);
+ Req when element(1,Req) =:= User orelse element(1,Req) =:= Curr,
+ tuple_size(Req) =:= 2 orelse tuple_size(Req) =:= 3 ->
+ %% We match {User|Curr,_}|{User|Curr,_,_}
+ NewQ = handle_req(Req, Iport, Oport, IOQueue),
+ server_loop(Iport, Oport, Curr, User, Gr, NewQ);
+ {Oport,ok} ->
+ %% We get this ok from the port, in io_request we store
+ %% info about where to send reply at head of queue
+ {Origin,Reply} = Resp,
+ Origin ! {reply,Reply},
+ NewQ = handle_req(next, Iport, Oport, {false, IOQ}),
+ server_loop(Iport, Oport, Curr, User, Gr, NewQ);
{'EXIT',Iport,_R} ->
- server_loop(Iport, Oport, Curr, User, Gr);
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue);
{'EXIT',Oport,_R} ->
- server_loop(Iport, Oport, Curr, User, Gr);
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue);
+ {'EXIT',User,shutdown} -> % force data to port
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue);
{'EXIT',User,_R} -> % keep 'user' alive
NewU = start_user(),
- server_loop(Iport, Oport, Curr, NewU, gr_set_num(Gr, 1, NewU, {}));
+ server_loop(Iport, Oport, Curr, NewU, gr_set_num(Gr, 1, NewU, {}), IOQueue);
{'EXIT',Pid,R} -> % shell and group leader exit
case gr_cur_pid(Gr) of
Pid when R =/= die ,
@@ -213,53 +215,88 @@ server_loop(Iport, Oport, Curr, User, Gr) ->
{ok,Gr2} = gr_set_cur(gr_set_num(Gr1, Ix, Pid1,
{shell,start,Params}), Ix),
put(current_group, Pid1),
- server_loop(Iport, Oport, Pid1, User, Gr2);
+ server_loop(Iport, Oport, Pid1, User, Gr2, IOQueue);
_ -> % remote shell
io_requests([{put_chars,unicode,"(^G to start new job) ***\n"}],
Iport, Oport),
- server_loop(Iport, Oport, Curr, User, Gr1)
+ server_loop(Iport, Oport, Curr, User, Gr1, IOQueue)
end;
_ -> % not current, just remove it
- server_loop(Iport, Oport, Curr, User, gr_del_pid(Gr, Pid))
+ server_loop(Iport, Oport, Curr, User, gr_del_pid(Gr, Pid), IOQueue)
end;
_X ->
%% Ignore unknown messages.
- server_loop(Iport, Oport, Curr, User, Gr)
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue)
end.
+%% We always handle geometry and unicode requests
+handle_req({Curr,tty_geometry},Iport,_Oport,IOQueue) ->
+ Curr ! {self(),tty_geometry,get_tty_geometry(Iport)},
+ IOQueue;
+handle_req({Curr,get_unicode_state},Iport,_Oport,IOQueue) ->
+ Curr ! {self(),get_unicode_state,get_unicode_state(Iport)},
+ IOQueue;
+handle_req({Curr,set_unicode_state, Bool},Iport,_Oport,IOQueue) ->
+ Curr ! {self(),set_unicode_state,set_unicode_state(Iport,Bool)},
+ IOQueue;
+handle_req(next,Iport,Oport,{false,IOQ}=IOQueue) ->
+ case queue:out(IOQ) of
+ {empty,_} ->
+ IOQueue;
+ {{value,{Origin,Req}},ExecQ} ->
+ case io_request(Req, Iport, Oport) of
+ ok ->
+ handle_req(next,Iport,Oport,{false,ExecQ});
+ Reply ->
+ {{Origin,Reply}, ExecQ}
+ end
+ end;
+handle_req(Msg,Iport,Oport,{false,IOQ}=IOQueue) ->
+ empty = queue:peek(IOQ),
+ {Origin,Req} = Msg,
+ case io_request(Req, Iport, Oport) of
+ ok ->
+ IOQueue;
+ Reply ->
+ {{Origin,Reply}, IOQ}
+ end;
+handle_req(Msg,_Iport,_Oport,{Resp, IOQ}) ->
+ %% All requests are queued when we have outstanding sync put_chars
+ {Resp, queue:in(Msg,IOQ)}.
+
%% port_bytes(Bytes, InPort, OutPort, CurrentProcess, UserProcess, Group)
%% Check the Bytes from the port to see if it contains a ^G. If so,
%% either escape to switch_loop or restart the shell. Otherwise send
%% the bytes to Curr.
-port_bytes([$\^G|_Bs], Iport, Oport, _Curr, User, Gr) ->
- handle_escape(Iport, Oport, User, Gr);
+port_bytes([$\^G|_Bs], Iport, Oport, _Curr, User, Gr, IOQueue) ->
+ handle_escape(Iport, Oport, User, Gr, IOQueue);
-port_bytes([$\^C|_Bs], Iport, Oport, Curr, User, Gr) ->
- interrupt_shell(Iport, Oport, Curr, User, Gr);
+port_bytes([$\^C|_Bs], Iport, Oport, Curr, User, Gr, IOQueue) ->
+ interrupt_shell(Iport, Oport, Curr, User, Gr, IOQueue);
-port_bytes([B], Iport, Oport, Curr, User, Gr) ->
+port_bytes([B], Iport, Oport, Curr, User, Gr, IOQueue) ->
Curr ! {self(),{data,[B]}},
- server_loop(Iport, Oport, Curr, User, Gr);
-port_bytes(Bs, Iport, Oport, Curr, User, Gr) ->
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue);
+port_bytes(Bs, Iport, Oport, Curr, User, Gr, IOQueue) ->
case member($\^G, Bs) of
true ->
- handle_escape(Iport, Oport, User, Gr);
+ handle_escape(Iport, Oport, User, Gr, IOQueue);
false ->
Curr ! {self(),{data,Bs}},
- server_loop(Iport, Oport, Curr, User, Gr)
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue)
end.
-interrupt_shell(Iport, Oport, Curr, User, Gr) ->
+interrupt_shell(Iport, Oport, Curr, User, Gr, IOQueue) ->
case gr_get_info(Gr, Curr) of
undefined ->
ok; % unknown
_ ->
exit(Curr, interrupt)
end,
- server_loop(Iport, Oport, Curr, User, Gr).
+ server_loop(Iport, Oport, Curr, User, Gr, IOQueue).
-handle_escape(Iport, Oport, User, Gr) ->
+handle_escape(Iport, Oport, User, Gr, IOQueue) ->
case application:get_env(stdlib, shell_esc) of
{ok,abort} ->
Pid = gr_cur_pid(Gr),
@@ -278,11 +315,14 @@ handle_escape(Iport, Oport, User, Gr) ->
Pid1 = group:start(self(), {shell,start,[]}),
io_request({put_chars,unicode,"\n"}, Iport, Oport),
server_loop(Iport, Oport, User,
- gr_add_cur(Gr1, Pid1, {shell,start,[]}));
+ gr_add_cur(Gr1, Pid1, {shell,start,[]}), IOQueue);
_ -> % {ok,jcl} | undefined
io_request({put_chars,unicode,"\nUser switch command\n"}, Iport, Oport),
- server_loop(Iport, Oport, User, switch_loop(Iport, Oport, Gr))
+ %% init edlin used by switch command and have it copy the
+ %% text buffer from current group process
+ edlin:init(gr_cur_pid(Gr)),
+ server_loop(Iport, Oport, User, switch_loop(Iport, Oport, Gr), IOQueue)
end.
switch_loop(Iport, Oport, Gr) ->
@@ -492,9 +532,12 @@ set_unicode_state(Iport, Bool) ->
io_request(Request, Iport, Oport) ->
try io_command(Request) of
- Command ->
+ {command,_} = Command ->
Oport ! {self(),Command},
- ok
+ ok;
+ {Command,Reply} ->
+ Oport ! {self(),Command},
+ Reply
catch
{requests,Rs} ->
io_requests(Rs, Iport, Oport);
@@ -511,6 +554,14 @@ io_requests([], _Iport, _Oport) ->
put_int16(N, Tail) ->
[(N bsr 8)band 255,N band 255|Tail].
+%% When a put_chars_sync command is used, user_drv guarantees that
+%% the bytes have been put in the buffer of the port before an acknowledgement
+%% is sent back to the process sending the request. This command was added in
+%% OTP 18 to make sure that data sent from io:format is actually printed
+%% to the console before the vm stops when calling erlang:halt(integer()).
+-dialyzer({no_improper_lists, io_command/1}).
+io_command({put_chars_sync, unicode,Cs,Reply}) ->
+ {{command,[?OP_PUTC_SYNC|unicode:characters_to_binary(Cs,utf8)]},Reply};
io_command({put_chars, unicode,Cs}) ->
{command,[?OP_PUTC|unicode:characters_to_binary(Cs,utf8)]};
io_command({move_rel,N}) ->
diff --git a/lib/kernel/src/user_sup.erl b/lib/kernel/src/user_sup.erl
index cb50d9491d..72c3fad3a9 100644
--- a/lib/kernel/src/user_sup.erl
+++ b/lib/kernel/src/user_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/src/wrap_log_reader.erl b/lib/kernel/src/wrap_log_reader.erl
index 7e1f4aa07f..6622405d85 100644
--- a/lib/kernel/src/wrap_log_reader.erl
+++ b/lib/kernel/src/wrap_log_reader.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index ef351a25fb..9e972b4f95 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/kernel/test/appinc1.erl b/lib/kernel/test/appinc1.erl
index 343fefb25c..fc9180b35a 100644
--- a/lib/kernel/test/appinc1.erl
+++ b/lib/kernel/test/appinc1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/appinc1x.erl b/lib/kernel/test/appinc1x.erl
index 8c144676ac..b05cd55b43 100644
--- a/lib/kernel/test/appinc1x.erl
+++ b/lib/kernel/test/appinc1x.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/appinc2.erl b/lib/kernel/test/appinc2.erl
index d2e0305109..7e92e7e092 100644
--- a/lib/kernel/test/appinc2.erl
+++ b/lib/kernel/test/appinc2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/appinc2A.erl b/lib/kernel/test/appinc2A.erl
index 604e31e3d3..f0e2cd4277 100644
--- a/lib/kernel/test/appinc2A.erl
+++ b/lib/kernel/test/appinc2A.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/appinc2B.erl b/lib/kernel/test/appinc2B.erl
index abb60010aa..17623621bb 100644
--- a/lib/kernel/test/appinc2B.erl
+++ b/lib/kernel/test/appinc2B.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/appinc2top.erl b/lib/kernel/test/appinc2top.erl
index 5a8d0d6687..f3d9715a2a 100644
--- a/lib/kernel/test/appinc2top.erl
+++ b/lib/kernel/test/appinc2top.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 4901206c8e..0c198b90ae 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -2699,10 +2700,7 @@ node_names(Names, Config) ->
node_name(Name, Config) ->
U = "_",
- {{Y,M,D}, {H,Min,S}} = calendar:now_to_local_time(now()),
- Date = io_lib:format("~4w_~2..0w_~2..0w__~2..0w_~2..0w_~2..0w",
- [Y,M,D, H,Min,S]),
- L = lists:flatten(Date),
+ L = integer_to_list(erlang:unique_integer([positive])),
lists:concat([Name,U,?testcase,U,U,L]).
stop_node_nice(Node) when is_atom(Node) ->
diff --git a/lib/kernel/test/application_SUITE_data/app_start_error.erl b/lib/kernel/test/application_SUITE_data/app_start_error.erl
index cfe3508eb3..531a10d442 100644
--- a/lib/kernel/test/application_SUITE_data/app_start_error.erl
+++ b/lib/kernel/test/application_SUITE_data/app_start_error.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/application_SUITE_data/group_leader.erl b/lib/kernel/test/application_SUITE_data/group_leader.erl
index 08c5b43808..e791437272 100644
--- a/lib/kernel/test/application_SUITE_data/group_leader.erl
+++ b/lib/kernel/test/application_SUITE_data/group_leader.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/application_SUITE_data/group_leader_sup.erl b/lib/kernel/test/application_SUITE_data/group_leader_sup.erl
index 04bb0538fe..ade8de8470 100644
--- a/lib/kernel/test/application_SUITE_data/group_leader_sup.erl
+++ b/lib/kernel/test/application_SUITE_data/group_leader_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/application_SUITE_data/trans_abnormal_sup.erl b/lib/kernel/test/application_SUITE_data/trans_abnormal_sup.erl
index d060347aff..98d7e90235 100644
--- a/lib/kernel/test/application_SUITE_data/trans_abnormal_sup.erl
+++ b/lib/kernel/test/application_SUITE_data/trans_abnormal_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/application_SUITE_data/trans_normal_sup.erl b/lib/kernel/test/application_SUITE_data/trans_normal_sup.erl
index 48eb52ddcf..233a79d8c3 100644
--- a/lib/kernel/test/application_SUITE_data/trans_normal_sup.erl
+++ b/lib/kernel/test/application_SUITE_data/trans_normal_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/application_SUITE_data/transient.erl b/lib/kernel/test/application_SUITE_data/transient.erl
index 1f38b4803a..a58bc4600e 100644
--- a/lib/kernel/test/application_SUITE_data/transient.erl
+++ b/lib/kernel/test/application_SUITE_data/transient.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl
index c369dca4e1..dd3010567a 100644
--- a/lib/kernel/test/bif_SUITE.erl
+++ b/lib/kernel/test/bif_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -32,6 +33,7 @@
spawn_failures/1,
run_fun/1,
+ decode_packet_delim/1,
wilderness/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -515,6 +517,15 @@ fetch_proc_vals(Pid) ->
{value,{heap_size,HS}} = lists:keysearch(heap_size, 1, PI),
?line {Ls, P, FA, HS}.
+decode_packet_delim(doc) ->
+ ["Test erlang:packet_delim/3 with {line_delimiter,0} option"];
+decode_packet_delim(suite) ->
+ [];
+decode_packet_delim(Config) when is_list(Config) ->
+ {ok,<<"abc",0>>,<<"efg",0>>} =
+ erlang:decode_packet(line, <<"abc",0,"efg",0>>, [{line_delimiter, 0}]),
+ {more, undefined} = erlang:decode_packet(line, <<"abc",0,"efg",0>>, []).
+
% This testcase should probably be moved somewhere else
wilderness(doc) ->
["Test that memory allocation command line options affecting the"
diff --git a/lib/kernel/test/ch.erl b/lib/kernel/test/ch.erl
index 25d6f6d200..ba8aa9f05a 100644
--- a/lib/kernel/test/ch.erl
+++ b/lib/kernel/test/ch.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/ch_sup.erl b/lib/kernel/test/ch_sup.erl
index 4c923b2909..a297b60200 100644
--- a/lib/kernel/test/ch_sup.erl
+++ b/lib/kernel/test/ch_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/cleanup.erl b/lib/kernel/test/cleanup.erl
index 01db1e9124..7eb0a9e140 100644
--- a/lib/kernel/test/cleanup.erl
+++ b/lib/kernel/test/cleanup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index afedc17e57..73ade14fa1 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -322,6 +323,7 @@ load_abs(Config) when is_list(Config) ->
{error, nofile} = code:load_abs(TestDir ++ "/duuuumy_mod"),
{error, badfile} = code:load_abs(TestDir ++ "/code_a_test"),
{'EXIT', _} = (catch code:load_abs({})),
+ {'EXIT', _} = (catch code:load_abs("Non-latin-имя-файла")),
{module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
code:stick_dir(TestDir),
{error, sticky_directory} = code:load_abs(TestDir ++ "/code_b_test"),
@@ -810,14 +812,6 @@ check_funs({'$M_EXPR','$F_EXPR',_},
{unicode,characters_to_binary,3},
{filename,filename_string_to_binary,1}|_]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',_},
- [{code_server,load_native_code,4},
- {code_server,load_native_code_1,2},
- {code_server,load_native_code,2},
- {code_server,try_load_module,4},
- {code_server,do_load_binary,4},
- {code_server,handle_call,3},
- {code_server,loop,1}|_]) -> 0;
-check_funs({'$M_EXPR','$F_EXPR',_},
[{code_server,do_mod_call,4},
{code_server,handle_call,3}|_]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',_},
@@ -866,8 +860,14 @@ check_funs({'$M_EXPR','$F_EXPR',_},
check_funs({'$M_EXPR',module_info,1},
[{hipe_unified_loader,patch_to_emu_step1,1} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',2},
+ [{hipe_unified_loader,write_words,3} | _]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',2},
+ [{hipe_unified_loader,patch_label_or_labels,4} | _]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',2},
+ [{hipe_unified_loader,sort_and_write,5} | _]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',2},
[{lists,foldl,3},
- {hipe_unified_loader,sort_and_write,4} | _]) -> 0;
+ {hipe_unified_loader,sort_and_write,5} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',1},
[{lists,foreach,2},
{hipe_unified_loader,patch_consts,3} | _]) -> 0;
@@ -1133,9 +1133,8 @@ mult_lib_roots(Config) when is_list(Config) ->
?t:start_node(mult_lib_roots, slave,
[{args,"-env ERL_LIBS "++ErlLibs}]),
- TSPath = filename:dirname(code:which(test_server)),
Path0 = rpc:call(Node, code, get_path, []),
- [TSPath,"."|Path1] = Path0,
+ ["."|Path1] = Path0,
[Kernel|Path2] = Path1,
[Stdlib|Path3] = Path2,
mult_lib_verify_lib(Kernel, "kernel"),
@@ -1179,16 +1178,19 @@ mult_lib_remove_prefix([$/|T], []) -> T.
bad_erl_libs(Config) when is_list(Config) ->
{ok,Node} =
- ?t:start_node(mult_lib_roots, slave,
- [{args,"-env ERL_LIBS "}]),
-
+ ?t:start_node(bad_erl_libs, slave, []),
+ Code = rpc:call(Node,code,get_path,[]),
?t:stop_node(Node),
{ok,Node2} =
- ?t:start_node(mult_lib_roots, slave,
+ ?t:start_node(bad_erl_libs, slave,
[{args,"-env ERL_LIBS /no/such/dir"}]),
-
+ Code2 = rpc:call(Node,code,get_path,[]),
?t:stop_node(Node2),
+
+ %% Test that code path is not affected by the faulty ERL_LIBS
+ Code = Code2,
+
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1396,8 +1398,9 @@ on_load_binary(_) ->
{tuple,6,[{atom,6,Mod},{call,6,{atom,6,self},[]}]}},
{'receive',7,[{clause,8,[{atom,8,go}],[],[{atom,8,ok}]}]}]}]},
{function,11,ok,0,[{clause,11,[],[],[{atom,11,true}]}]}],
- {ok,Mod,Bin} = compile:forms(Forms, [report]),
- [io:put_chars(erl_pp:form(F)) || F <- Forms],
+ Forms1 = erl_parse:new_anno(Forms),
+ {ok,Mod,Bin} = compile:forms(Forms1, [report]),
+ [io:put_chars(erl_pp:form(F)) || F <- Forms1],
{Pid1,Ref1} = spawn_monitor(fun() ->
code:load_binary(Mod, File, Bin),
@@ -1599,6 +1602,17 @@ on_load_errors(Config) when is_list(Config) ->
ok
end,
+ %% Make sure that the code loading functions return the correct
+ %% error code.
+ Simple = simple_on_load_error,
+ SimpleList = atom_to_list(Simple),
+ {error,on_load_failure} = code:load_file(Simple),
+ {error,on_load_failure} = code:ensure_loaded(Simple),
+ {ok,SimpleCode} = file:read_file("simple_on_load_error.beam"),
+ {error,on_load_failure} = code:load_binary(Simple, "", SimpleCode),
+ {error,on_load_failure} = code:load_abs(SimpleList),
+ {error,on_load_failure} = code:load_abs(SimpleList, Simple),
+
ok.
do_on_load_error(ReturnValue) ->
@@ -1653,9 +1667,7 @@ get_mode(Config) when is_list(Config) ->
init(Tester) ->
{ok, Tester}.
-handle_event({error, _GL, {emulator, _, _}}, Tester) ->
- {ok, Tester};
-handle_event({error, _GL, Msg}, Tester) ->
+handle_event({warning_msg, _GL, Msg}, Tester) ->
Tester ! Msg,
{ok, Tester};
handle_event(_Event, State) ->
diff --git a/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict.erl b/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict.erl
index ccc954ee17..9fb5a31358 100644
--- a/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict.erl
+++ b/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_app.erl b/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_app.erl
index a23ef7001d..8012ddafb4 100644
--- a/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_app.erl
+++ b/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_sup.erl b/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_sup.erl
index 3e427ed34a..8c7b49644a 100644
--- a/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_sup.erl
+++ b/lib/kernel/test/code_SUITE_data/code_archive_dict-1.0/src/code_archive_dict_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-b/ebin/lists.erl b/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-b/ebin/lists.erl
index e97dde2703..07a4ffc8b6 100644
--- a/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-b/ebin/lists.erl
+++ b/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-b/ebin/lists.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-c/ebin/code_SUITE_mult_root_module.erl b/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-c/ebin/code_SUITE_mult_root_module.erl
index 3c9cd75f34..15ff5d4896 100644
--- a/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-c/ebin/code_SUITE_mult_root_module.erl
+++ b/lib/kernel/test/code_SUITE_data/mult_lib_roots/first_root/my_dummy_app-c/ebin/code_SUITE_mult_root_module.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/code_SUITE_data/on_load_errors/simple_on_load_error.erl b/lib/kernel/test/code_SUITE_data/on_load_errors/simple_on_load_error.erl
new file mode 100644
index 0000000000..603c282257
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/on_load_errors/simple_on_load_error.erl
@@ -0,0 +1,5 @@
+-module(simple_on_load_error).
+-on_load(on_load/0).
+
+on_load() ->
+ nope.
diff --git a/lib/kernel/test/code_a_test.erl b/lib/kernel/test/code_a_test.erl
index 22830fff53..fa33c6f57a 100644
--- a/lib/kernel/test/code_a_test.erl
+++ b/lib/kernel/test/code_a_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/code_b_test.erl b/lib/kernel/test/code_b_test.erl
index a8ff570e2e..559698dd8e 100644
--- a/lib/kernel/test/code_b_test.erl
+++ b/lib/kernel/test/code_b_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl
index f55af1e354..9988347581 100644
--- a/lib/kernel/test/disk_log_SUITE.erl
+++ b/lib/kernel/test/disk_log_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/disk_log_SUITE_data/wrap_log_test.erl b/lib/kernel/test/disk_log_SUITE_data/wrap_log_test.erl
index e5ff70fd49..1cd1a4b0a4 100644
--- a/lib/kernel/test/disk_log_SUITE_data/wrap_log_test.erl
+++ b/lib/kernel/test/disk_log_SUITE_data/wrap_log_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_boot_server_SUITE.erl b/lib/kernel/test/erl_boot_server_SUITE.erl
index bb64c01058..954880e252 100644
--- a/lib/kernel/test/erl_boot_server_SUITE.erl
+++ b/lib/kernel/test/erl_boot_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 15c2adc957..2f73ab170a 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -235,11 +236,10 @@ do_test_setuptime(Setuptime) when is_list(Setuptime) ->
Res.
time_ping(Node) ->
- T0 = erlang:now(),
+ T0 = erlang:monotonic_time(),
pang = net_adm:ping(Node),
- T1 = erlang:now(),
- time_diff(T0,T1).
-
+ T1 = erlang:monotonic_time(),
+ erlang:convert_time_unit(T1 - T0, native, milli_seconds).
%% Keep the connection with the client node up.
%% This is neccessary as the client node runs with much shorter
@@ -276,13 +276,15 @@ tick_cli_test1(Node) ->
erlang:monitor_node(Node, true),
sleep(2),
rpc:call(Node, erlang, time, []), %% simulate action on the connection
- T1 = now(),
+ T1 = erlang:monotonic_time(),
receive
{nodedown, Node} ->
- T2 = now(),
+ T2 = erlang:monotonic_time(),
receive
{whats_the_result, From} ->
- case time_diff(T1, T2) of
+ Diff = erlang:convert_time_unit(T2-T1, native,
+ milli_seconds),
+ case Diff of
T when T > 8000, T < 16000 ->
From ! {tick_test, T};
T ->
@@ -1208,19 +1210,6 @@ print_my_messages() ->
?line ?t:format("Messages: ~p~n", [Messages]),
?line ok.
-%% Time difference in milliseconds !!
-time_diff({TimeM, TimeS, TimeU}, {CurM, CurS, CurU}) when CurM > TimeM ->
- ((CurM - TimeM) * 1000000000) + sec_diff({TimeS, TimeU}, {CurS, CurU});
-time_diff({_, TimeS, TimeU}, {_, CurS, CurU}) ->
- sec_diff({TimeS, TimeU}, {CurS, CurU}).
-
-sec_diff({TimeS, TimeU}, {CurS, CurU}) when CurS > TimeS ->
- ((CurS - TimeS) * 1000) + micro_diff(TimeU, CurU);
-sec_diff({_, TimeU}, {_, CurU}) ->
- micro_diff(TimeU, CurU).
-
-micro_diff(TimeU, CurU) ->
- trunc(CurU/1000) - trunc(TimeU/1000).
sleep(T) -> receive after T * 1000 -> ok end.
@@ -1267,16 +1256,12 @@ get_nodenames(N, T) ->
get_nodenames(0, _, Acc) ->
Acc;
get_nodenames(N, T, Acc) ->
- {A, B, C} = now(),
+ U = erlang:unique_integer([positive]),
get_nodenames(N-1, T, [list_to_atom(atom_to_list(T)
++ "-"
- ++ atom_to_list(?MODULE)
+ ++ ?MODULE_STRING
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)) | Acc]).
+ ++ integer_to_list(U)) | Acc]).
get_numbered_nodenames(N, T) ->
get_numbered_nodenames(N, T, []).
@@ -1284,16 +1269,12 @@ get_numbered_nodenames(N, T) ->
get_numbered_nodenames(0, _, Acc) ->
Acc;
get_numbered_nodenames(N, T, Acc) ->
- {A, B, C} = now(),
+ U = erlang:unique_integer([positive]),
NL = [list_to_atom(atom_to_list(T) ++ integer_to_list(N)
++ "-"
- ++ atom_to_list(?MODULE)
- ++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
+ ++ ?MODULE_STRING
++ "-"
- ++ integer_to_list(C)) | Acc],
+ ++ integer_to_list(U)) | Acc],
get_numbered_nodenames(N-1, T, NL).
wait_until(Fun) ->
diff --git a/lib/kernel/test/erl_distribution_wb_SUITE.erl b/lib/kernel/test/erl_distribution_wb_SUITE.erl
index 3b8b2d9150..c107e92fae 100644
--- a/lib/kernel/test/erl_distribution_wb_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_wb_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -451,11 +452,8 @@ close_pair({Client, Server}) ->
%% MD5 hashing
%%
-%% This is no proper random number, but that is not really important in
-%% this test
gen_challenge() ->
- {_,_,N} = erlang:now(),
- N.
+ rand:uniform(1000000).
%% Generate a message digest from Challenge number and Cookie
gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) ->
@@ -712,13 +710,9 @@ get_nodenames(N, T) ->
get_nodenames(0, _, Acc) ->
Acc;
get_nodenames(N, T, Acc) ->
- {A, B, C} = now(),
- get_nodenames(N-1, T, [list_to_atom(atom_to_list(?MODULE)
+ U = erlang:unique_integer([positive]),
+ get_nodenames(N-1, T, [list_to_atom(?MODULE_STRING
++ "-"
++ atom_to_list(T)
++ "-"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C)) | Acc]).
+ ++ integer_to_list(U)) | Acc]).
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 658c31c14d..0803cf428f 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict.erl b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict.erl
index 2444224810..7d8167f575 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_app.erl b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_app.erl
index 075632ab95..bf66179e00 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_app.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_sup.erl b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_sup.erl
index 12fe90aaab..e57d8c5a00 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_sup.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dict-1.0/src/primary_archive_dict_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy.erl b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy.erl
index 186e752c3d..e1c7655331 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_app.erl b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_app.erl
index 4a29c86a89..e9db18c47e 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_app.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_sup.erl b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_sup.erl
index c8cee46d08..7bab86be68 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_sup.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE_data/primary_archive/primary_archive_dummy/src/primary_archive_dummy_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/error_handler_SUITE.erl b/lib/kernel/test/error_handler_SUITE.erl
index 2a86d39b74..d93ec643ce 100644
--- a/lib/kernel/test/error_handler_SUITE.erl
+++ b/lib/kernel/test/error_handler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/error_logger_SUITE.erl b/lib/kernel/test/error_logger_SUITE.erl
index 05bf5aae18..f1988b68d9 100644
--- a/lib/kernel/test/error_logger_SUITE.erl
+++ b/lib/kernel/test/error_logger_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -32,7 +33,7 @@
error_report/1, info_report/1, error/1, info/1,
emulator/1, tty/1, logfile/1, add/1, delete/1]).
--export([generate_error/0]).
+-export([generate_error/2]).
-export([init/1,
handle_event/2, handle_call/2, handle_info/2,
@@ -210,13 +211,16 @@ emulator(suite) -> [];
emulator(doc) -> [];
emulator(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
- spawn(?MODULE, generate_error, []),
- reported(emulator),
+ Msg = "Error in process ~p on node ~p with exit value:~n~p~n",
+ Error = {badmatch,4},
+ Stack = [{module, function, 2, []}],
+ Pid = spawn(?MODULE, generate_error, [Error, Stack]),
+ reported(error, Msg, [Pid, node(), {Error, Stack}]),
?line my_yes = error_logger:delete_report_handler(?MODULE),
ok.
-generate_error() ->
- erlang:error({badmatch,4}).
+generate_error(Error, Stack) ->
+ erlang:raise(error, Error, Stack).
%%-----------------------------------------------------------------
%% We don't enables or disables tty error logging here. We do not
@@ -283,15 +287,6 @@ reported(Tag, Type, Report) ->
test_server:fail(no_report_received)
end.
-reported(emulator) ->
- receive
- {error, "~s~n", String} when is_list(String) ->
- test_server:messages_get(),
- ok
- after 1000 ->
- test_server:fail(no_report_received)
- end.
-
%%-----------------------------------------------------------------
%% The error_logger handler (gen_event behaviour).
%% Sends a notification to the Tester process about the events
diff --git a/lib/kernel/test/error_logger_warn_SUITE.erl b/lib/kernel/test/error_logger_warn_SUITE.erl
index 2bf467610e..a3a3b2f8c6 100644
--- a/lib/kernel/test/error_logger_warn_SUITE.erl
+++ b/lib/kernel/test/error_logger_warn_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -21,8 +22,8 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- basic/1,warnings_info/1,warnings_warnings/1,
- rb_basic/1,rb_warnings_info/1,rb_warnings_warnings/1,
+ basic/1,warnings_info/1,warnings_errors/1,
+ rb_basic/1,rb_warnings_info/1,rb_warnings_errors/1,
rb_trunc/1,rb_utc/1,file_utc/1]).
%% Internal exports.
@@ -48,8 +49,8 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [basic, warnings_info, warnings_warnings, rb_basic,
- rb_warnings_info, rb_warnings_warnings, rb_trunc,
+ [basic, warnings_info, warnings_errors, rb_basic,
+ rb_warnings_info, rb_warnings_errors, rb_trunc,
rb_utc, file_utc].
groups() ->
@@ -69,7 +70,7 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_Case, Config) ->
- ?line Dog = ?t:timetrap(?default_timeout),
+ Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
@@ -88,11 +89,11 @@ warnings_info(Config) when is_list(Config) ->
put(elw_config,Config),
warnings_info().
-warnings_warnings(doc) ->
- ["Tests mapping warnings to warnings functionality"];
-warnings_warnings(Config) when is_list(Config) ->
+warnings_errors(doc) ->
+ ["Tests mapping warnings to errors functionality"];
+warnings_errors(Config) when is_list(Config) ->
put(elw_config,Config),
- warnings_warnings().
+ warnings_errors().
rb_basic(doc) ->
["Tests basic rb functionality"];
@@ -106,11 +107,11 @@ rb_warnings_info(Config) when is_list(Config) ->
put(elw_config,Config),
rb_warnings_info().
-rb_warnings_warnings(doc) ->
- ["Tests warnings as warnings rb functionality"];
-rb_warnings_warnings(Config) when is_list(Config) ->
+rb_warnings_errors(doc) ->
+ ["Tests warnings as errors rb functionality"];
+rb_warnings_errors(Config) when is_list(Config) ->
put(elw_config,Config),
- rb_warnings_warnings().
+ rb_warnings_errors().
rb_trunc(doc) ->
["Tests rb functionality on truncated data"];
@@ -159,6 +160,9 @@ install_relay(Node) ->
rpc:call(Node,error_logger,add_report_handler,[?MODULE,[self()]]).
+warning_map(Node) ->
+ rpc:call(Node,error_logger,warning_map,[]).
+
format(Node,A,B) ->
rpc:call(Node,error_logger,format,[A,B]).
error_msg(Node,A,B) ->
@@ -181,80 +185,81 @@ nn() ->
basic() ->
- ?line Node = start_node(nn(),[]),
- ?line ok = install_relay(Node),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line format(Node,"~p~n",[Self]),
- ?line ?EXPECT({handle_event,{error,GL,{_,"~p~n",[Self]}}}),
- ?line error_msg(Node,"~p~n",[Self]),
- ?line ?EXPECT({handle_event,{error,GL,{_,"~p~n",[Self]}}}),
- ?line warning_msg(Node,"~p~n",[Self]),
- ?line ?EXPECT({handle_event,{error,GL,{_,"~p~n",[Self]}}}),
- ?line info_msg(Node,"~p~n",[Self]),
- ?line ?EXPECT({handle_event,{info_msg,GL,{_,"~p~n",[Self]}}}),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line error_report(Node,Report),
- ?line ?EXPECT({handle_event,{error_report,GL,{_,std_error,Report}}}),
- ?line warning_report(Node,Report),
- ?line ?EXPECT({handle_event,{error_report,GL,{_,std_error,Report}}}),
- ?line info_report(Node,Report),
- ?line ?EXPECT({handle_event,{info_report,GL,{_,std_info,Report}}}),
-
- ?line stop_node(Node),
+ Node = start_node(nn(),[]),
+ ok = install_relay(Node),
+ Self = self(),
+ GL = group_leader(),
+ warning = warning_map(Node),
+ format(Node,"~p~n",[Self]),
+ ?EXPECT({handle_event,{error,GL,{_,"~p~n",[Self]}}}),
+ error_msg(Node,"~p~n",[Self]),
+ ?EXPECT({handle_event,{error,GL,{_,"~p~n",[Self]}}}),
+ warning_msg(Node,"~p~n",[Self]),
+ ?EXPECT({handle_event,{warning_msg,GL,{_,"~p~n",[Self]}}}),
+ info_msg(Node,"~p~n",[Self]),
+ ?EXPECT({handle_event,{info_msg,GL,{_,"~p~n",[Self]}}}),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ error_report(Node,Report),
+ ?EXPECT({handle_event,{error_report,GL,{_,std_error,Report}}}),
+ warning_report(Node,Report),
+ ?EXPECT({handle_event,{warning_report,GL,{_,std_warning,Report}}}),
+ info_report(Node,Report),
+ ?EXPECT({handle_event,{info_report,GL,{_,std_info,Report}}}),
+ stop_node(Node),
ok.
warnings_info() ->
- ?line Node = start_node(nn(),"+Wi"),
- ?line ok = install_relay(Node),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line warning_msg(Node,"~p~n",[Self]),
- ?line ?EXPECT({handle_event,{info_msg,GL,{_,"~p~n",[Self]}}}),
- ?line warning_report(Node,Report),
- ?line ?EXPECT({handle_event,{info_report,GL,{_,std_info,Report}}}),
- ?line stop_node(Node),
+ Node = start_node(nn(),"+Wi"),
+ ok = install_relay(Node),
+ Self = self(),
+ GL = group_leader(),
+ info = warning_map(Node),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ warning_msg(Node,"~p~n",[Self]),
+ ?EXPECT({handle_event,{info_msg,GL,{_,"~p~n",[Self]}}}),
+ warning_report(Node,Report),
+ ?EXPECT({handle_event,{info_report,GL,{_,std_info,Report}}}),
+ stop_node(Node),
ok.
-warnings_warnings() ->
- ?line Node = start_node(nn(),"+Ww"),
- ?line ok = install_relay(Node),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line warning_msg(Node,"~p~n",[Self]),
- ?line ?EXPECT({handle_event,{warning_msg,GL,{_,"~p~n",[Self]}}}),
- ?line warning_report(Node,Report),
- ?line ?EXPECT({handle_event,{warning_report,GL,{_,std_warning,Report}}}),
- ?line stop_node(Node),
+warnings_errors() ->
+ Node = start_node(nn(),"+We"),
+ ok = install_relay(Node),
+ Self = self(),
+ GL = group_leader(),
+ error = warning_map(Node),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ warning_msg(Node,"~p~n",[Self]),
+ ?EXPECT({handle_event,{error,GL,{_,"~p~n",[Self]}}}),
+ warning_report(Node,Report),
+ ?EXPECT({handle_event,{error_report,GL,{_,std_error,Report}}}),
+ stop_node(Node),
ok.
-
-
+
% RB...
quote(String) ->
case os:type() of
- {win32,_} ->
- "\\\""++String++"\\\"";
- _ ->
- "'\""++String++"\"'"
+ {win32,_} ->
+ "\\\""++String++"\\\"";
+ _ ->
+ "'\""++String++"\"'"
end.
iquote(String) ->
case os:type() of
- {win32,_} ->
- "\\\""++String++"\\\"";
- _ ->
- "\""++String++"\""
+ {win32,_} ->
+ "\\\""++String++"\\\"";
+ _ ->
+ "\""++String++"\""
end.
oquote(String) ->
case os:type() of
- {win32,_} ->
- "\""++String++"\"";
- _ ->
- "'"++String++"'"
+ {win32,_} ->
+ "\""++String++"\"";
+ _ ->
+ "'"++String++"'"
end.
@@ -264,18 +269,18 @@ findstr(String,FileName) ->
findstrc(String,File) ->
case string:str(File,String) of
- N when is_integer(N),
- N > 0 ->
- S2 = lists:sublist(File,N,length(File)),
- case string:str(S2,"\n") of
- 0 ->
- 1;
- M ->
- S3 = lists:sublist(S2,M,length(S2)),
- 1 + findstrc(String,S3)
- end;
- _ ->
- 0
+ N when is_integer(N),
+ N > 0 ->
+ S2 = lists:sublist(File,N,length(File)),
+ case string:str(S2,"\n") of
+ 0 ->
+ 1;
+ M ->
+ S3 = lists:sublist(S2,M,length(S2)),
+ 1 + findstrc(String,S3)
+ end;
+ _ ->
+ 0
end.
% Doesn't count empty lines
@@ -349,175 +354,182 @@ one_rb_findstr(Param,String) ->
% Tests
rb_basic() ->
- ?line clean_rd(),
+ clean_rd(),
% Behold, the magic parameters to activate rb logging...
- ?line Node = start_node(nn(),"-boot start_sasl -sasl error_logger_mf_dir "++
- quote(rd())++" error_logger_mf_maxbytes 5000 "
- "error_logger_mf_maxfiles 5"),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line fake_gl(Node,warning_msg,"~p~n",[Self]),
- ?line fake_gl(Node,warning_report,Report),
- ?line nice_stop_node(Node),
- ?line application:start(sasl),
- ?line rb:start([{report_dir, rd()}]),
- ?line rb:list(),
- ?line true = (one_rb_lines([error]) > 1),
- ?line true = (one_rb_lines([error_report]) > 1),
- ?line 1 = one_rb_findstr([error],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([error_report],pid_to_list(Self)),
- ?line 2 = one_rb_findstr([],pid_to_list(Self)),
- ?line true = (one_rb_findstr([progress],"===") > 4),
- ?line rb:stop(),
- ?line application:stop(sasl),
- ?line stop_node(Node),
+ Node = start_node(nn(),"-boot start_sasl -sasl error_logger_mf_dir "++
+ quote(rd())++" error_logger_mf_maxbytes 5000 "
+ "error_logger_mf_maxfiles 5"),
+ Self = self(),
+ GL = group_leader(),
+ warning = warning_map(Node),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ fake_gl(Node,warning_msg,"~p~n",[Self]),
+ fake_gl(Node,warning_report,Report),
+ nice_stop_node(Node),
+ application:start(sasl),
+ rb:start([{report_dir, rd()}]),
+ rb:list(),
+ true = (one_rb_lines([error]) =:= 0),
+ true = (one_rb_lines([error_report]) =:= 0),
+ 0 = one_rb_findstr([error],pid_to_list(Self)),
+ 0 = one_rb_findstr([error_report],pid_to_list(Self)),
+ 1 = one_rb_findstr([warning_msg],pid_to_list(Self)),
+ 1 = one_rb_findstr([warning_report],pid_to_list(Self)),
+ 0 = one_rb_findstr([info_msg],pid_to_list(Self)),
+ 0 = one_rb_findstr([info_report],pid_to_list(Self)),
+ 2 = one_rb_findstr([],pid_to_list(Self)),
+ true = (one_rb_findstr([progress],"===") > 4),
+ rb:stop(),
+ application:stop(sasl),
+ stop_node(Node),
ok.
rb_warnings_info() ->
- ?line clean_rd(),
- ?line Node = start_node(nn(),"+W i -boot start_sasl -sasl error_logger_mf_dir "++
- quote(rd())++" error_logger_mf_maxbytes 5000 "
- "error_logger_mf_maxfiles 5"),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line fake_gl(Node,warning_msg,"~p~n",[Self]),
- ?line fake_gl(Node,warning_report,Report),
- ?line nice_stop_node(Node),
- ?line application:start(sasl),
- ?line rb:start([{report_dir, rd()}]),
- ?line rb:list(),
- ?line true = (one_rb_lines([error]) =:= 0),
- ?line true = (one_rb_lines([error_report]) =:= 0),
- ?line 0 = one_rb_findstr([error],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([error_report],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([warning_msg],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([warning_report],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([info_msg],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([info_report],pid_to_list(Self)),
- ?line 2 = one_rb_findstr([],pid_to_list(Self)),
- ?line true = (one_rb_findstr([progress],"===") > 4),
- ?line rb:stop(),
- ?line application:stop(sasl),
- ?line stop_node(Node),
+ clean_rd(),
+ Node = start_node(nn(),"+W i -boot start_sasl -sasl error_logger_mf_dir "++
+ quote(rd())++" error_logger_mf_maxbytes 5000 "
+ "error_logger_mf_maxfiles 5"),
+ Self = self(),
+ GL = group_leader(),
+ info = warning_map(Node),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ fake_gl(Node,warning_msg,"~p~n",[Self]),
+ fake_gl(Node,warning_report,Report),
+ nice_stop_node(Node),
+ application:start(sasl),
+ rb:start([{report_dir, rd()}]),
+ rb:list(),
+ true = (one_rb_lines([error]) =:= 0),
+ true = (one_rb_lines([error_report]) =:= 0),
+ 0 = one_rb_findstr([error],pid_to_list(Self)),
+ 0 = one_rb_findstr([error_report],pid_to_list(Self)),
+ 0 = one_rb_findstr([warning_msg],pid_to_list(Self)),
+ 0 = one_rb_findstr([warning_report],pid_to_list(Self)),
+ 1 = one_rb_findstr([info_msg],pid_to_list(Self)),
+ 1 = one_rb_findstr([info_report],pid_to_list(Self)),
+ 2 = one_rb_findstr([],pid_to_list(Self)),
+ true = (one_rb_findstr([progress],"===") > 4),
+ rb:stop(),
+ application:stop(sasl),
+ stop_node(Node),
ok.
-rb_warnings_warnings() ->
- ?line clean_rd(),
- ?line Node = start_node(nn(),"+W w -boot start_sasl -sasl error_logger_mf_dir "++
- quote(rd())++" error_logger_mf_maxbytes 5000 "
- "error_logger_mf_maxfiles 5"),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line fake_gl(Node,warning_msg,"~p~n",[Self]),
- ?line fake_gl(Node,warning_report,Report),
- ?line nice_stop_node(Node),
- ?line application:start(sasl),
- ?line rb:start([{report_dir, rd()}]),
- ?line rb:list(),
- ?line true = (one_rb_lines([error]) =:= 0),
- ?line true = (one_rb_lines([error_report]) =:= 0),
- ?line 0 = one_rb_findstr([error],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([error_report],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([warning_msg],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([warning_report],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([info_msg],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([info_report],pid_to_list(Self)),
- ?line 2 = one_rb_findstr([],pid_to_list(Self)),
- ?line true = (one_rb_findstr([progress],"===") > 4),
- ?line rb:stop(),
- ?line application:stop(sasl),
- ?line stop_node(Node),
+rb_warnings_errors() ->
+ clean_rd(),
+ Node = start_node(nn(),"+W e -boot start_sasl -sasl error_logger_mf_dir "++
+ quote(rd())++" error_logger_mf_maxbytes 5000 "
+ "error_logger_mf_maxfiles 5"),
+ Self = self(),
+ GL = group_leader(),
+ error = warning_map(Node),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ fake_gl(Node,warning_msg,"~p~n",[Self]),
+ fake_gl(Node,warning_report,Report),
+ nice_stop_node(Node),
+ application:start(sasl),
+ rb:start([{report_dir, rd()}]),
+ rb:list(),
+ true = (one_rb_lines([error]) > 1),
+ true = (one_rb_lines([error_report]) > 1),
+ 1 = one_rb_findstr([error],pid_to_list(Self)),
+ 1 = one_rb_findstr([error_report],pid_to_list(Self)),
+ 0 = one_rb_findstr([warning_msg],pid_to_list(Self)),
+ 0 = one_rb_findstr([warning_report],pid_to_list(Self)),
+ 0 = one_rb_findstr([info_msg],pid_to_list(Self)),
+ 0 = one_rb_findstr([info_report],pid_to_list(Self)),
+ 2 = one_rb_findstr([],pid_to_list(Self)),
+ true = (one_rb_findstr([progress],"===") > 4),
+ rb:stop(),
+ application:stop(sasl),
+ stop_node(Node),
ok.
rb_trunc() ->
- ?line clean_rd(),
- ?line Node = start_node(nn(),"+W w -boot start_sasl -sasl error_logger_mf_dir "++
- quote(rd())++" error_logger_mf_maxbytes 5000 "
- "error_logger_mf_maxfiles 5"),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line fake_gl(Node,warning_msg,"~p~n",[Self]),
- ?line fake_gl(Node,warning_report,Report),
- ?line nice_stop_node(Node),
- ?line application:start(sasl),
- ?line {ok,File} = file:read_file(rf()),
- ?line S=byte_size(File)-2,
- ?line <<TFile:S/binary,_/binary>>=File,
- ?line file:write_file(rf(),TFile),
- ?line rb:start([{report_dir, rd()}]),
- ?line rb:list(),
- ?line true = (one_rb_lines([error]) =:= 0),
- ?line true = (one_rb_lines([error_report]) =:= 0),
- ?line 0 = one_rb_findstr([error],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([error_report],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([warning_msg],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([warning_report],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([info_msg],pid_to_list(Self)),
- ?line 0 = one_rb_findstr([info_report],pid_to_list(Self)),
- ?line 1 = one_rb_findstr([],pid_to_list(Self)),
- ?line true = (one_rb_findstr([progress],"===") > 4),
- ?line rb:stop(),
- ?line application:stop(sasl),
- ?line stop_node(Node),
+ clean_rd(),
+ Node = start_node(nn(),"-boot start_sasl -sasl error_logger_mf_dir "++
+ quote(rd())++" error_logger_mf_maxbytes 5000 "
+ "error_logger_mf_maxfiles 5"),
+ Self = self(),
+ GL = group_leader(),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ fake_gl(Node,warning_msg,"~p~n",[Self]),
+ fake_gl(Node,warning_report,Report),
+ nice_stop_node(Node),
+ application:start(sasl),
+ {ok,File} = file:read_file(rf()),
+ S=byte_size(File)-2,
+ <<TFile:S/binary,_/binary>>=File,
+ file:write_file(rf(),TFile),
+ rb:start([{report_dir, rd()}]),
+ rb:list(),
+ true = (one_rb_lines([error]) =:= 0),
+ true = (one_rb_lines([error_report]) =:= 0),
+ 0 = one_rb_findstr([error],pid_to_list(Self)),
+ 0 = one_rb_findstr([error_report],pid_to_list(Self)),
+ 1 = one_rb_findstr([warning_msg],pid_to_list(Self)),
+ 0 = one_rb_findstr([warning_report],pid_to_list(Self)),
+ 0 = one_rb_findstr([info_msg],pid_to_list(Self)),
+ 0 = one_rb_findstr([info_report],pid_to_list(Self)),
+ 1 = one_rb_findstr([],pid_to_list(Self)),
+ true = (one_rb_findstr([progress],"===") > 4),
+ rb:stop(),
+ application:stop(sasl),
+ stop_node(Node),
ok.
rb_utc() ->
- ?line clean_rd(),
- ?line Node = start_node(nn(),"+W w -boot start_sasl -sasl error_logger_mf_dir "++
- quote(rd())++" error_logger_mf_maxbytes 5000 "
- "error_logger_mf_maxfiles 5 -sasl utc_log true"),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line fake_gl(Node,warning_msg,"~p~n",[Self]),
- ?line fake_gl(Node,warning_report,Report),
- ?line nice_stop_node(Node),
- ?line application:stop(sasl),
- ?line UtcLog=case application:get_env(sasl,utc_log) of
- {ok,true} ->
- true;
- _AllOthers ->
- application:set_env(sasl,utc_log,true),
- false
- end,
- ?line application:start(sasl),
- ?line rb:start([{report_dir, rd()}]),
- ?line rb:list(),
- ?line Pr=one_rb_findstr([progress],"==="),
- ?line Wm=one_rb_findstr([warning_msg],"==="),
- ?line Wr=one_rb_findstr([warning_report],"==="),
- ?line Sum=Pr+Wm+Wr,
- ?line Sum=one_rb_findstr([],"UTC"),
- ?line rb:stop(),
- ?line application:stop(sasl),
- ?line application:set_env(sasl,utc_log,UtcLog),
- ?line stop_node(Node),
+ clean_rd(),
+ Node = start_node(nn(),"-boot start_sasl -sasl error_logger_mf_dir "++
+ quote(rd())++" error_logger_mf_maxbytes 5000 "
+ "error_logger_mf_maxfiles 5 -sasl utc_log true"),
+ Self = self(),
+ GL = group_leader(),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ fake_gl(Node,warning_msg,"~p~n",[Self]),
+ fake_gl(Node,warning_report,Report),
+ nice_stop_node(Node),
+ application:stop(sasl),
+ UtcLog=case application:get_env(sasl,utc_log) of
+ {ok,true} ->
+ true;
+ _AllOthers ->
+ application:set_env(sasl,utc_log,true),
+ false
+ end,
+ application:start(sasl),
+ rb:start([{report_dir, rd()}]),
+ rb:list(),
+ Pr=one_rb_findstr([progress],"==="),
+ Wm=one_rb_findstr([warning_msg],"==="),
+ Wr=one_rb_findstr([warning_report],"==="),
+ Sum=Pr+Wm+Wr,
+ Sum=one_rb_findstr([],"UTC"),
+ rb:stop(),
+ application:stop(sasl),
+ application:set_env(sasl,utc_log,UtcLog),
+ stop_node(Node),
ok.
file_utc() ->
- ?line file:delete(lf()),
- ?line SS="+W w -stdlib utc_log true -kernel error_logger "++ oquote("{file,"++iquote(lf())++"}"),
+ file:delete(lf()),
+ SS="-stdlib utc_log true -kernel error_logger "++ oquote("{file,"++iquote(lf())++"}"),
%erlang:display(SS),
- ?line Node = start_node(nn(),SS),
+ Node = start_node(nn(),SS),
%erlang:display(rpc:call(Node,application,get_env,[kernel,error_logger])),
- ?line Self = self(),
- ?line GL = group_leader(),
- ?line fake_gl(Node,error_msg,"~p~n",[Self]),
- ?line fake_gl(Node,warning_msg,"~p~n",[Self]),
- ?line fake_gl(Node,info_msg,"~p~n",[Self]),
- ?line Report = [{self,Self},{gl,GL},make_ref()],
- ?line fake_gl(Node,error_report,Report),
- ?line fake_gl(Node,warning_report,Report),
- ?line fake_gl(Node,info_report,Report),
- ?line nice_stop_node(Node),
- ?line receive after 5000 -> ok end, % Let the node die, needed
- ?line 6 = findstr("UTC",lf()),
- ?line 2 = findstr("WARNING",lf()),
- ?line 2 = findstr("ERROR",lf()),
- ?line 2 = findstr("INFO",lf()),
- ?line stop_node(Node),
+ Self = self(),
+ GL = group_leader(),
+ fake_gl(Node,error_msg,"~p~n",[Self]),
+ fake_gl(Node,warning_msg,"~p~n",[Self]),
+ fake_gl(Node,info_msg,"~p~n",[Self]),
+ Report = [{self,Self},{gl,GL},make_ref()],
+ fake_gl(Node,error_report,Report),
+ fake_gl(Node,warning_report,Report),
+ fake_gl(Node,info_report,Report),
+ nice_stop_node(Node),
+ receive after 5000 -> ok end, % Let the node die, needed
+ 6 = findstr("UTC",lf()),
+ 2 = findstr("WARNING",lf()),
+ 2 = findstr("ERROR",lf()),
+ 2 = findstr("INFO",lf()),
+ stop_node(Node),
ok.
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 2ce2303ba3..09d9a45197 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -47,7 +48,7 @@
-export([cur_dir_0/1, cur_dir_1/1, make_del_dir/1,
list_dir/1,list_dir_error/1,
untranslatable_names/1, untranslatable_names_error/1,
- pos1/1, pos2/1]).
+ pos1/1, pos2/1, pos3/1]).
-export([close/1, consult1/1, path_consult/1, delete/1]).
-export([ eval1/1, path_eval/1, script1/1, path_script/1,
open1/1,
@@ -79,6 +80,7 @@
-export([interleaved_read_write/1]).
+-export([unicode/1]).
-export([altname/1]).
-export([large_file/1, large_write/1]).
@@ -93,6 +95,8 @@
-export([old_io_protocol/1]).
+-export([unicode_mode/1]).
+
%% Debug exports
-export([create_file_slow/2, create_file/2, create_bin/2]).
-export([verify_file/2, verify_bin/3]).
@@ -105,18 +109,21 @@
-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
+-define(THROW_ERROR(RES), throw({fail, ?LINE, RES})).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [altname, read_write_file, {group, dirs},
+ [unicode, altname, read_write_file, {group, dirs},
{group, files}, delete, rename, names, {group, errors},
{group, compression}, {group, links}, copy,
delayed_write, read_ahead, segment_read, segment_write,
ipread, pid2name, interleaved_read_write, otp_5814, otp_10852,
large_file, large_write, read_line_1, read_line_2, read_line_3,
- read_line_4, standard_io, old_io_protocol].
+ read_line_4, standard_io, old_io_protocol,
+ unicode_mode
+ ].
groups() ->
[{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1,
@@ -130,7 +137,7 @@ groups() ->
[open1, old_modes, new_modes, path_open, close, access,
read_write, pread_write, append, open_errors,
exclusive]},
- {pos, [], [pos1, pos2]},
+ {pos, [], [pos1, pos2, pos3]},
{file_info, [],
[file_info_basic_file, file_info_basic_directory,
file_info_bad, file_info_times, file_write_file_info]},
@@ -347,8 +354,153 @@ old_io_protocol(Config) when is_list(Config) ->
[] = flush(),
ok.
+unicode_mode(suite) -> [];
+unicode_mode(doc) -> [""];
+unicode_mode(Config) ->
+ Dir = {dir, ?config(priv_dir,Config)},
+ OptVariants = [[Dir],
+ [Dir, {encoding, utf8}],
+ [Dir, binary],
+ [Dir, binary, {encoding, utf8}]
+ ],
+ ReadVariants = [{read, fun(Fd) -> um_read(Fd, fun(Fd1) -> file:read(Fd1, 1024) end) end},
+ {read_line, fun(Fd) -> um_read(Fd, fun(Fd1) -> file:read_line(Fd1) end) end}
+ %%{pread, fun(Fd) -> file:pread(Fd, 0, 1024) end},
+ %%{preadl, fun(Fd) -> file:pread(Fd, [{0, 1024}]) end},
+ ],
+
+ _ = [read_write_0("ASCII: list: Hello World", Read, Opt) ||
+ Opt <- OptVariants, Read <- ReadVariants],
+ _ = [read_write_0("LATIN1: list: åäöÅÄÖ", Read, Opt) ||
+ Opt <- OptVariants, Read <- ReadVariants],
+ _ = [read_write_0(<<"ASCII: bin: Hello World">>, Read, Opt) ||
+ Opt <- OptVariants, Read <- ReadVariants],
+ _ = [read_write_0(<<"LATIN1: bin: åäöÅÄÖ">>, Read, Opt) ||
+ Opt <- OptVariants, Read <- ReadVariants],
+ %% These will be double encoded if option is encoding utf-8
+ _ = [read_write_0(<<"UTF8: bin: Ωß"/utf8>>, Read, Opt) ||
+ Opt <- OptVariants, Read <- ReadVariants],
+ %% These should not work (with encoding set to utf-8)
+ %% according to file's documentation
+ _ = [read_write_0("UTF8: list: Ωß", Read, Opt) ||
+ Opt <- OptVariants, Read <- ReadVariants],
+ ok.
+
+read_write_0(Str, {Func, ReadFun}, Options) ->
+ try
+ Res = read_write_1(Str, ReadFun, Options),
+ io:format("~p: ~ts ~p '~p'~n", [Func, Str, tl(Options), Res]),
+ ok
+ catch {fail, Line, ReadBytes = [_|_]} ->
+ io:format("~p:~p: ~p ERROR: ~w vs~n ~w~n - ~p~n",
+ [?MODULE, Line, Func, Str, ReadBytes, Options]),
+ exit({error, ?LINE});
+ {fail, Line, ReadBytes} ->
+ io:format("~p:~p: ~p ERROR: ~ts vs~n ~w~n - ~p~n",
+ [?MODULE, Line, Func, Str, ReadBytes, Options]),
+ exit({error, ?LINE});
+ error:What ->
+ io:format("~p:??: ~p ERROR: ~p from~n ~w~n ~p~n",
+ [?MODULE, Func, What, Str, Options]),
+
+ io:format("\t~p~n", [erlang:get_stacktrace()]),
+ exit({error, ?LINE})
+ end.
+
+read_write_1(Str0, ReadFun, [{dir,Dir}|Options]) ->
+ File = um_filename(Str0, Dir, Options),
+ Pre = "line 1\n", Post = "\nlast line\n",
+ Str = case is_list(Str0) andalso lists:max(Str0) > 255 of
+ false -> %% Normal case Use options
+ {ok, FdW} = file:open(File, [write|Options]),
+ IO = [Pre, Str0, Post],
+ ok = file:write(FdW, IO),
+ case is_binary(Str0) of
+ true -> iolist_to_binary(IO);
+ false -> lists:append(IO)
+ end;
+ true -> %% Test unicode lists
+ {ok, FdW} = file:open(File, [write]),
+ Utf8 = unicode:characters_to_binary([Pre, Str0, Post]),
+ file:write(FdW, Utf8),
+ {unicode, Utf8}
+ end,
+ file:close(FdW),
+ {ok, FdR} = file:open(File, [read|Options]),
+ ReadRes = ReadFun(FdR),
+ file:close(FdR),
+ Res = um_check(Str, ReadRes, Options),
+ file:delete(File),
+ Res.
+um_read(Fd, Fun) ->
+ um_read(Fd, Fun, []).
+
+um_read(Fd, Fun, Acc) ->
+ case Fun(Fd) of
+ eof ->
+ case is_binary(hd(Acc)) of
+ true -> {ok, iolist_to_binary(lists:reverse(Acc))};
+ false -> {ok, lists:append(lists:reverse(Acc))}
+ end;
+ {ok, Data} ->
+ um_read(Fd, Fun, [Data|Acc]);
+ Error ->
+ Error
+ end.
+
+
+um_check(Str, {ok, Str}, _) -> ok;
+um_check(Bin, {ok, Res}, _Options) when is_binary(Bin), is_list(Res) ->
+ case list_to_binary(Res) of
+ Bin -> ok;
+ _ -> ?THROW_ERROR(Res)
+ end;
+um_check(Str, {ok, Res}, _Options) when is_list(Str), is_binary(Res) ->
+ case iolist_to_binary(Str) of
+ Res -> ok;
+ _ -> ?THROW_ERROR(Res)
+ end;
+um_check({unicode, Utf8Bin}, Res, Options) ->
+ um_check_unicode(Utf8Bin, Res,
+ proplists:get_value(binary, Options, false),
+ proplists:get_value(encoding, Options, none));
+um_check(_Str, Res, _Options) ->
+ ?THROW_ERROR(Res).
+
+um_check_unicode(Utf8Bin, {ok, Utf8Bin}, true, none) ->
+ ok;
+um_check_unicode(Utf8Bin, {ok, List = [_|_]}, false, none) ->
+ case binary_to_list(Utf8Bin) == List of
+ true -> ok;
+ false -> ?THROW_ERROR(List)
+ end;
+um_check_unicode(_Utf8Bin, {error, {no_translation, unicode, latin1}}, _, _) ->
+ no_translation;
+um_check_unicode(_Utf8Bin, Error = {error, _}, _, _Unicode) ->
+ ?THROW_ERROR(Error);
+um_check_unicode(_Utf8Bin, {ok, _ListOrBin}, _, _UTF8_) ->
+ %% List = if is_binary(ListOrBin) -> unicode:characters_to_list(ListOrBin);
+ %% true -> ListOrBin
+ %% end,
+ %% io:format("In: ~w~n", [binary_to_list(Utf8Bin)]),
+ %% io:format("Ut: ~w~n", [List]),
+ ?THROW_ERROR({shoud_be, no_translation}).
+
+um_filename(Bin, Dir, Options) when is_binary(Bin) ->
+ um_filename(binary_to_list(Bin), Dir, Options);
+um_filename(Str = [_|_], Dir, Options) ->
+ Name = hd(string:tokens(Str, ":")),
+ Enc = atom_to_list(proplists:get_value(encoding, Options, latin1)),
+ File = case lists:member(binary, Options) of
+ true ->
+ "test_" ++ Name ++ "_bin_enc_" ++ Enc;
+ false ->
+ "test_" ++ Name ++ "_list_enc_" ++ Enc
+ end,
+ filename:join(Dir, File).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
read_write_file(suite) -> [];
@@ -1219,6 +1371,27 @@ pos2(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+pos3(suite) -> [];
+pos3(doc) -> ["When it does not use raw mode, file:position had a bug."];
+pos3(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(data_dir, Config),
+ ?line Name = filename:join(RootDir, "realmen.html.gz"),
+
+ ?line {ok, Fd} = ?FILE_MODULE:open(Name, [read, binary]),
+ ?line {ok, _} = ?FILE_MODULE:read(Fd, 5),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {bof, -1}),
+
+ %% Here ok had returned =(
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {cur, -10}),
+ %% That test is actually questionable since file:position/2
+ %% is documented to leave the file position undefined after
+ %% it has returned an error. But on Posix systems the position
+ %% is guaranteed to be unchanged after an error return. On e.g
+ %% Windows there is nothing stated about this in the documentation.
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
file_info_basic_file(suite) -> [];
file_info_basic_file(doc) -> [];
@@ -2610,6 +2783,40 @@ compress_async_crash_loop(N, Path, ExpectedData) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+unicode(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ Name = filename:join(Dir, "data-utf8.txt"),
+ Txt = lists:seq(128, 255),
+ D = unicode:characters_to_binary(Txt, latin1, latin1),
+ {ok,Fd1} =
+ ?FILE_MODULE:open(Name, [write,read,binary,{encoding,unicode}]),
+ ok = ?FILE_MODULE:truncate(Fd1),
+ ok = ?FILE_MODULE:write(Fd1, Txt),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D} = ?FILE_MODULE:read(Fd1, 129),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D1} = ?FILE_MODULE:read(Fd1, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, cur),
+ {ok,D2} = ?FILE_MODULE:pread(Fd1, {cur,0}, 65),
+ D = <<D1/binary, D2/binary>>,
+ {ok,D1} = ?FILE_MODULE:pread(Fd1, bof, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, Pos),
+ {ok,D2} = ?FILE_MODULE:read(Fd1, 64),
+ ok = ?FILE_MODULE:close(Fd1),
+ %%
+ RawD = unicode:characters_to_binary(Txt, latin1, unicode),
+ {ok,RawD} = ?FILE_MODULE:read_file(Name),
+ %%
+ {ok,Fd2} = ?FILE_MODULE:open(Name, [read,{encoding,unicode}]),
+ {ok,Txt} = ?FILE_MODULE:read(Fd2, 129),
+ {Txt1,Txt2} = lists:split(64, Txt),
+ {ok,Txt2} = ?FILE_MODULE:pread(Fd2, Pos, 65),
+ {ok,0} = ?FILE_MODULE:position(Fd2, bof),
+ {ok,Txt1} = ?FILE_MODULE:read(Fd2, 64),
+ ok = ?FILE_MODULE:close(Fd2).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
altname(doc) ->
"Test the file:altname/1 function";
altname(suite) ->
@@ -3764,7 +3971,7 @@ response_analysis(Module, Function, Arguments) ->
receive {Parent, start, Ts} -> ok end,
Stat =
iterate(response_stat(response_stat(init, Ts),
- erlang:now()),
+ micro_ts()),
done,
fun (S) ->
erlang:yield(),
@@ -3772,12 +3979,12 @@ response_analysis(Module, Function, Arguments) ->
{Parent, stop} ->
done
after 0 ->
- response_stat(S, erlang:now())
+ response_stat(S, micro_ts())
end
end),
- Parent ! {self(), stopped, response_stat(Stat, erlang:now())}
+ Parent ! {self(), stopped, response_stat(Stat, micro_ts())}
end),
- ?line Child ! {Parent, start, erlang:now()},
+ Child ! {Parent, start, micro_ts()},
?line Result = apply(Module, Function, Arguments),
?line Child ! {Parent, stop},
?line {N, Sum, _, M, Max} = receive {Child, stopped, X} -> X end,
@@ -3791,12 +3998,13 @@ response_analysis(Module, Function, Arguments) ->
[Mean_ms, Max_ms, M, (N-1)])),
?line {Result, Comment}.
-
+micro_ts() ->
+ erlang:monotonic_time(micro_seconds).
response_stat(init, Ts) ->
{0, 0, Ts, 0, 0};
-response_stat({N, Sum, {A1, B1, C1}, M, Max}, {A2, B2, C2} = Ts) ->
- D = C2-C1 + 1000000*((B2-B1) + 1000000*(A2-A1)),
+response_stat({N, Sum, Ts0, M, Max}, Ts) ->
+ D = Ts - Ts0,
if D > Max ->
{N+1, Sum+D, Ts, N, D};
true ->
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
index 9354af2e41..32006d893e 100644
--- a/lib/kernel/test/file_name_SUITE.erl
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index 881aaed429..91a57d3290 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl
index c27d265550..962471c20c 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_api_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -30,8 +31,9 @@
init_per_testcase/2, end_per_testcase/2,
t_connect_timeout/1, t_accept_timeout/1,
t_connect_bad/1,
- t_recv_timeout/1, t_recv_eof/1,
+ t_recv_timeout/1, t_recv_eof/1, t_recv_delim/1,
t_shutdown_write/1, t_shutdown_both/1, t_shutdown_error/1,
+ t_shutdown_async/1,
t_fdopen/1, t_fdconnect/1, t_implicit_inet6/1]).
-export([getsockfd/0,closesockfd/1]).
@@ -41,12 +43,12 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[{group, t_accept}, {group, t_connect}, {group, t_recv},
t_shutdown_write, t_shutdown_both, t_shutdown_error,
- t_fdopen, t_fdconnect, t_implicit_inet6].
+ t_shutdown_async, t_fdopen, t_fdconnect, t_implicit_inet6].
groups() ->
[{t_accept, [], [t_accept_timeout]},
{t_connect, [], [t_connect_timeout, t_connect_bad]},
- {t_recv, [], [t_recv_timeout, t_recv_eof]}].
+ {t_recv, [], [t_recv_timeout, t_recv_eof, t_recv_delim]}].
@@ -129,6 +131,21 @@ t_recv_eof(Config) when is_list(Config) ->
?line {error, closed} = gen_tcp:recv(Client, 0),
ok.
+t_recv_delim(doc) -> "Test using message delimiter $X";
+t_recv_delim(suite) -> [];
+t_recv_delim(Config) when is_list(Config) ->
+ {ok, L} = gen_tcp:listen(0, []),
+ {ok, Port} = inet:port(L),
+ Opts = [{active,false},{packet,line},{line_delimiter,$X}],
+ {ok, Client} = gen_tcp:connect(localhost, Port, Opts),
+ {ok, A} = gen_tcp:accept(L),
+ ok = gen_tcp:send(A, "abcXefgX"),
+ {ok, "abcX"} = gen_tcp:recv(Client, 0, 0),
+ {ok, "efgX"} = gen_tcp:recv(Client, 0, 0),
+ ok = gen_tcp:close(Client),
+ ok = gen_tcp:close(A),
+ ok.
+
%%% gen_tcp:shutdown/2
t_shutdown_write(Config) when is_list(Config) ->
@@ -155,7 +172,34 @@ t_shutdown_error(Config) when is_list(Config) ->
?line ok = gen_tcp:close(L),
?line {error, closed} = gen_tcp:shutdown(L, read_write),
ok.
-
+
+t_shutdown_async(Config) when is_list(Config) ->
+ ?line {OS, _} = os:type(),
+ ?line {ok, L} = gen_tcp:listen(0, [{sndbuf, 4096}]),
+ ?line {ok, Port} = inet:port(L),
+ ?line {ok, Client} = gen_tcp:connect(localhost, Port,
+ [{recbuf, 4096},
+ {active, false}]),
+ ?line {ok, S} = gen_tcp:accept(L),
+ ?line PayloadSize = 1024 * 1024,
+ ?line Payload = lists:duplicate(PayloadSize, $.),
+ ?line ok = gen_tcp:send(S, Payload),
+ ?line case erlang:port_info(S, queue_size) of
+ {queue_size, N} when N > 0 -> ok;
+ {queue_size, 0} when OS =:= win32 -> ok;
+ {queue_size, 0} = T -> ?t:fail({unexpected, T})
+ end,
+
+ ?line ok = gen_tcp:shutdown(S, write),
+ ?line {ok, Buf} = gen_tcp:recv(Client, PayloadSize),
+ ?line {error, closed} = gen_tcp:recv(Client, 0),
+ ?line case length(Buf) of
+ PayloadSize -> ok;
+ Sz -> ?t:fail({payload_size,
+ {expected, PayloadSize},
+ {received, Sz}})
+ end.
+
%%% gen_tcp:fdopen/2
diff --git a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
index d774767624..ca8eacdf40 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
+++ b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
@@ -3,16 +3,17 @@
*
* 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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/kernel/test/gen_tcp_echo_SUITE.erl b/lib/kernel/test/gen_tcp_echo_SUITE.erl
index 9bc66dbae0..6dcb21758b 100644
--- a/lib/kernel/test/gen_tcp_echo_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_echo_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 4e4aeb67e2..81c6dcd0fd 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,6 +32,11 @@
init_per_testcase/2, end_per_testcase/2,
otp_3924/1, otp_3924_sender/4, closed_socket/1,
shutdown_active/1, shutdown_passive/1, shutdown_pending/1,
+ show_econnreset_active/1, show_econnreset_active_once/1,
+ show_econnreset_passive/1, econnreset_after_sync_send/1,
+ econnreset_after_async_send_active/1,
+ econnreset_after_async_send_active_once/1,
+ econnreset_after_async_send_passive/1, linger_zero/1,
default_options/1, http_bad_packet/1,
busy_send/1, busy_disconnect_passive/1, busy_disconnect_active/1,
fill_sendq/1, partial_recv_and_close/1,
@@ -38,7 +44,9 @@
% Accept tests
primitive_accept/1,multi_accept_close_listen/1,accept_timeout/1,
accept_timeouts_in_order/1,accept_timeouts_in_order2/1,
- accept_timeouts_in_order3/1,accept_timeouts_mixed/1,
+ accept_timeouts_in_order3/1,accept_timeouts_in_order4/1,
+ accept_timeouts_in_order5/1,accept_timeouts_in_order6/1,
+ accept_timeouts_in_order7/1,accept_timeouts_mixed/1,
killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1,
several_accepts_in_one_go/1, accept_system_limit/1,
active_once_closed/1, send_timeout/1, send_timeout_active/1,
@@ -60,19 +68,19 @@ init_per_testcase(wrapping_oct, Config) when is_list(Config) ->
[{watchdog, Dog}|Config];
init_per_testcase(iter_max_socks, Config) when is_list(Config) ->
Dog = case os:type() of
- {win32,_} ->
- test_server:timetrap(test_server:minutes(30));
- _Else ->
- test_server:timetrap(test_server:seconds(240))
- end,
+ {win32,_} ->
+ test_server:timetrap(test_server:minutes(30));
+ _Else ->
+ test_server:timetrap(test_server:seconds(240))
+ end,
[{watchdog, Dog}|Config];
init_per_testcase(accept_system_limit, Config) when is_list(Config) ->
case os:type() of
- {ose,_} ->
- {skip,"Skip in OSE"};
- _ ->
- Dog = test_server:timetrap(test_server:seconds(240)),
- [{watchdog,Dog}|Config]
+ {ose,_} ->
+ {skip,"Skip in OSE"};
+ _ ->
+ Dog = test_server:timetrap(test_server:seconds(240)),
+ [{watchdog,Dog}|Config]
end;
init_per_testcase(wrapping_oct, Config) when is_list(Config) ->
Dog = test_server:timetrap(test_server:seconds(600)),
@@ -92,6 +100,11 @@ all() ->
iter_max_socks, passive_sockets, active_n,
accept_closed_by_other_process, otp_3924, closed_socket,
shutdown_active, shutdown_passive, shutdown_pending,
+ show_econnreset_active, show_econnreset_active_once,
+ show_econnreset_passive, econnreset_after_sync_send,
+ econnreset_after_async_send_active,
+ econnreset_after_async_send_active_once,
+ econnreset_after_async_send_passive, linger_zero,
default_options, http_bad_packet, busy_send,
busy_disconnect_passive, busy_disconnect_active,
fill_sendq, partial_recv_and_close,
@@ -99,7 +112,9 @@ all() ->
so_priority, primitive_accept,
multi_accept_close_listen, accept_timeout,
accept_timeouts_in_order, accept_timeouts_in_order2,
- accept_timeouts_in_order3, accept_timeouts_mixed,
+ accept_timeouts_in_order3, accept_timeouts_in_order4,
+ accept_timeouts_in_order5, accept_timeouts_in_order6,
+ accept_timeouts_in_order7, accept_timeouts_mixed,
killing_acceptor, killing_multi_acceptors,
killing_multi_acceptors2, several_accepts_in_one_go, accept_system_limit,
active_once_closed, send_timeout, send_timeout_active, otp_7731,
@@ -121,8 +136,6 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-
default_options(doc) ->
["Tests kernel application variables inet_default_listen_options and "
"inet_default_connect_options"];
@@ -130,69 +143,68 @@ default_options(suite) ->
[];
default_options(Config) when is_list(Config) ->
%% First check the delay_send option
- ?line {true,true,true}=do_delay_send_1(),
- ?line {false,false,false}=do_delay_send_2(),
- ?line {true,false,false}=do_delay_send_3(),
- ?line {false,false,false}=do_delay_send_4(),
- ?line {false,false,false}=do_delay_send_5(),
- ?line {false,true,true}=do_delay_send_6(),
+ {true,true,true}=do_delay_send_1(),
+ {false,false,false}=do_delay_send_2(),
+ {true,false,false}=do_delay_send_3(),
+ {false,false,false}=do_delay_send_4(),
+ {false,false,false}=do_delay_send_5(),
+ {false,true,true}=do_delay_send_6(),
%% Now lets start some nodes with different combinations of options:
- ?line {true,true,true} = do_delay_on_other_node("",
- fun do_delay_send_1/0),
- ?line {true,false,false} =
+ {true,true,true} = do_delay_on_other_node("", fun do_delay_send_1/0),
+ {true,false,false} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_2/0),
- ?line {false,true,true} =
+ {false,true,true} =
do_delay_on_other_node("-kernel inet_default_listen_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_2/0),
- ?line {true,true,true} =
+ {true,true,true} =
do_delay_on_other_node("-kernel inet_default_listen_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_3/0),
- ?line {true,true,true} =
+ {true,true,true} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_6/0),
- ?line {false,false,false} =
+ {false,false,false} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_5/0),
- ?line {false,true,true} =
+ {false,true,true} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{delay_send,true}]\" "
"-kernel inet_default_listen_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_5/0),
- ?line {true,false,false} =
+ {true,false,false} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{delay_send,true}]\" "
"-kernel inet_default_listen_options "
"\"[{delay_send,true}]\"",
fun do_delay_send_4/0),
- ?line {true,true,true} =
+ {true,true,true} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"{delay_send,true}\" "
"-kernel inet_default_listen_options "
"\"{delay_send,true}\"",
fun do_delay_send_2/0),
%% Active is to dangerous and is supressed
- ?line {true,true,true} =
+ {true,true,true} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"{active,false}\" "
"-kernel inet_default_listen_options "
"\"{active,false}\"",
fun do_delay_send_7/0),
- ?line {true,true,true} =
+ {true,true,true} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{active,false},{delay_send,true}]\" "
"-kernel inet_default_listen_options "
"\"[{active,false},{delay_send,true}]\"",
fun do_delay_send_7/0),
- ?line {true,true,true} =
+ {true,true,true} =
do_delay_on_other_node("-kernel inet_default_connect_options "
"\"[{active,false},{delay_send,true}]\" "
"-kernel inet_default_listen_options "
@@ -204,12 +216,10 @@ default_options(Config) when is_list(Config) ->
do_delay_on_other_node(XArgs, Function) ->
Dir = filename:dirname(code:which(?MODULE)),
{ok,Node} = test_server:start_node(test_default_options_slave,slave,
- [{args,"-pa " ++ Dir ++ " " ++
- XArgs}]),
+ [{args,"-pa " ++ Dir ++ " " ++ XArgs}]),
Res = rpc:call(Node,erlang,apply,[Function,[]]),
test_server:stop_node(Node),
Res.
-
do_delay_send_1() ->
{ok,LS}=gen_tcp:listen(0,[{delay_send,true}]),
@@ -301,8 +311,6 @@ do_delay_send_7() ->
gen_tcp:close(S),
gen_tcp:close(LS),
{B1,B2,B3}.
-
-
controlling_process(doc) ->
["Open a listen port and change controlling_process for it",
@@ -313,18 +321,18 @@ controlling_process(Config) when is_list(Config) ->
{ok,S} = gen_tcp:listen(0,[]),
Pid2 = spawn(?MODULE,not_owner,[S]),
Pid2 ! {self(),2,control},
- ?line {error, E} = receive {2,_E} ->
+ {error, E} = receive {2,_E} ->
_E
after 10000 -> timeout
end,
io:format("received ~p~n",[E]),
Pid = spawn(?MODULE,not_owner,[S]),
- ?line ok = gen_tcp:controlling_process(S,Pid),
+ ok = gen_tcp:controlling_process(S,Pid),
Pid ! {self(),1,control},
- ?line ok = receive {1,ok} ->
- ok
- after 1000 -> timeout
- end,
+ ok = receive {1,ok} ->
+ ok
+ after 1000 -> timeout
+ end,
Pid ! close.
not_owner(S) ->
@@ -377,7 +385,7 @@ no_accept(Config) when is_list(Config) ->
{tcp_closed, Client} ->
ok
after 5000 ->
- ?line test_server:fail(never_closed)
+ test_server:fail(never_closed)
end.
@@ -386,30 +394,30 @@ close_with_pending_output(doc) ->
"to the other end."];
close_with_pending_output(suite) -> [];
close_with_pending_output(Config) when is_list(Config) ->
- ?line {ok, L} = gen_tcp:listen(0, [binary, {active, false}]),
- ?line {ok, {_, Port}} = inet:sockname(L),
- ?line Packets = 16,
- ?line Total = 2048*Packets,
+ {ok, L} = gen_tcp:listen(0, [binary, {active, false}]),
+ {ok, {_, Port}} = inet:sockname(L),
+ Packets = 16,
+ Total = 2048*Packets,
case start_remote(close_pending) of
{ok, Node} ->
- ?line {ok, Host} = inet:gethostname(),
- ?line spawn_link(Node, ?MODULE, sender, [Port, Packets, Host]),
- ?line {ok, A} = gen_tcp:accept(L),
- ?line case gen_tcp:recv(A, Total) of
+ {ok, Host} = inet:gethostname(),
+ spawn_link(Node, ?MODULE, sender, [Port, Packets, Host]),
+ {ok, A} = gen_tcp:accept(L),
+ case gen_tcp:recv(A, Total) of
{ok, Bin} when byte_size(Bin) == Total ->
gen_tcp:close(A),
gen_tcp:close(L);
{ok, Bin} ->
- ?line test_server:fail({small_packet,
+ test_server:fail({small_packet,
byte_size(Bin)});
Error ->
- ?line test_server:fail({unexpected, Error})
+ test_server:fail({unexpected, Error})
end,
ok;
{error, no_remote_hosts} ->
{skipped,"No remote hosts"};
{error, Other} ->
- ?line ?t:fail({failed_to_start_slave_node, Other})
+ ?t:fail({failed_to_start_slave_node, Other})
end.
sender(Port, Packets, Host) ->
@@ -556,63 +564,62 @@ otp_3924(Config) when is_list(Config) ->
otp_3924_1(MaxDelay).
otp_3924_1(MaxDelay) ->
- ?line {ok, Node} = start_node(otp_3924),
- ?line DataLen = 100*1024,
- ?line Data = otp_3924_data(DataLen),
+ {ok, Node} = start_node(otp_3924),
+ DataLen = 100*1024,
+ Data = otp_3924_data(DataLen),
% Repeat the test a couple of times to prevent the test from passing
% by chance.
- repeat(10,
- fun (N) ->
- ?line ok = otp_3924(MaxDelay, Node, Data, DataLen, N)
- end),
- ?line test_server:stop_node(Node),
+ repeat(10, fun(N) ->
+ ok = otp_3924(MaxDelay, Node, Data, DataLen, N)
+ end),
+ test_server:stop_node(Node),
ok.
otp_3924(MaxDelay, Node, Data, DataLen, N) ->
- ?line {ok, L} = gen_tcp:listen(0, [list, {active, false}]),
- ?line {ok, {_, Port}} = inet:sockname(L),
- ?line {ok, Host} = inet:gethostname(),
- ?line Sender = spawn_link(Node,
- ?MODULE,
- otp_3924_sender,
- [self(), Host, Port, Data]),
- ?line Data = otp_3924_receive_data(L, Sender, MaxDelay, DataLen, N),
- ?line ok = gen_tcp:close(L).
+ {ok, L} = gen_tcp:listen(0, [list, {active, false}]),
+ {ok, {_, Port}} = inet:sockname(L),
+ {ok, Host} = inet:gethostname(),
+ Sender = spawn_link(Node,
+ ?MODULE,
+ otp_3924_sender,
+ [self(), Host, Port, Data]),
+ Data = otp_3924_receive_data(L, Sender, MaxDelay, DataLen, N),
+ ok = gen_tcp:close(L).
otp_3924_receive_data(LSock, Sender, MaxDelay, Len, N) ->
- ?line OP = process_flag(priority, max),
- ?line OTE = process_flag(trap_exit, true),
- ?line TimeoutRef = make_ref(),
- ?line Data = (catch begin
- ?line Sender ! start,
- ?line {ok, Sock} = gen_tcp:accept(LSock),
- ?line D = otp_3924_receive_data(Sock,
- TimeoutRef,
- MaxDelay,
- Len,
- [],
- 0),
- ?line ok = gen_tcp:close(Sock),
- D
- end),
- ?line unlink(Sender),
- ?line process_flag(trap_exit, OTE),
- ?line process_flag(priority, OP),
+ OP = process_flag(priority, max),
+ OTE = process_flag(trap_exit, true),
+ TimeoutRef = make_ref(),
+ Data = (catch begin
+ Sender ! start,
+ {ok, Sock} = gen_tcp:accept(LSock),
+ D = otp_3924_receive_data(Sock,
+ TimeoutRef,
+ MaxDelay,
+ Len,
+ [],
+ 0),
+ ok = gen_tcp:close(Sock),
+ D
+ end),
+ unlink(Sender),
+ process_flag(trap_exit, OTE),
+ process_flag(priority, OP),
receive
{'EXIT', _, TimeoutRef} ->
- ?line test_server:fail({close_not_fast_enough,MaxDelay,N});
+ test_server:fail({close_not_fast_enough,MaxDelay,N});
{'EXIT', Sender, Reason} ->
- ?line test_server:fail({sender_exited, Reason});
+ test_server:fail({sender_exited, Reason});
{'EXIT', _Other, Reason} ->
- ?line test_server:fail({linked_process_exited, Reason})
+ test_server:fail({linked_process_exited, Reason})
after 0 ->
case Data of
{'EXIT', {A,B}} ->
- ?line test_server:fail({A,B,N});
+ test_server:fail({A,B,N});
{'EXIT', Failure} ->
- ?line test_server:fail(Failure);
+ test_server:fail(Failure);
_ ->
- ?line Data
+ Data
end
end.
@@ -623,12 +630,12 @@ otp_3924_receive_data(Sock, TimeoutRef, MaxDelay, Len, Acc, AccLen) ->
NewAccLen = AccLen + length(Data),
if
NewAccLen == Len ->
- ?line {ok, TRef} = timer:exit_after(MaxDelay,
+ {ok, TRef} = timer:exit_after(MaxDelay,
self(),
TimeoutRef),
- ?line {error, closed} = gen_tcp:recv(Sock, 0),
- ?line timer:cancel(TRef),
- ?line lists:flatten([Acc, Data]);
+ {error, closed} = gen_tcp:recv(Sock, 0),
+ timer:cancel(TRef),
+ lists:flatten([Acc, Data]);
NewAccLen > Len ->
exit({received_too_much, NewAccLen});
true ->
@@ -713,8 +720,8 @@ get_status(doc) ->
"is called."];
get_status(suite) -> [];
get_status(Config) when is_list(Config) ->
- ?line {ok,{socket,Pid,_,_}} = gen_tcp:listen(5678,[]),
- ?line {status,Pid,_,_} = sys:get_status(Pid).
+ {ok,{socket,Pid,_,_}} = gen_tcp:listen(5678,[]),
+ {status,Pid,_,_} = sys:get_status(Pid).
-define(RECOVER_SLEEP, 60000).
-define(RETRY_SLEEP, 15000).
@@ -744,19 +751,19 @@ do_iter_max_socks(N, failed) ->
MS = max_socks(),
[MS|do_iter_max_socks(N-1, failed)];
do_iter_max_socks(N, First) when is_integer(First) ->
- ?line MS = max_socks(),
+ MS = max_socks(),
if MS == First ->
- ?line [MS|do_iter_max_socks(N-1, First)];
+ [MS|do_iter_max_socks(N-1, First)];
true ->
- ?line io:format("Sleeping for ~p seconds...~n",
+ io:format("Sleeping for ~p seconds...~n",
[?RETRY_SLEEP/1000]),
- ?line ?t:sleep(?RETRY_SLEEP),
- ?line io:format("Trying again...~n", []),
- ?line RetryMS = max_socks(),
- ?line if RetryMS == First ->
- ?line [RetryMS|do_iter_max_socks(N-1, First)];
+ ?t:sleep(?RETRY_SLEEP),
+ io:format("Trying again...~n", []),
+ RetryMS = max_socks(),
+ if RetryMS == First ->
+ [RetryMS|do_iter_max_socks(N-1, First)];
true ->
- ?line [RetryMS|do_iter_max_socks(N-1, failed)]
+ [RetryMS|do_iter_max_socks(N-1, failed)]
end
end.
@@ -768,7 +775,7 @@ all_equal([Rule | T]) ->
all_equal(Rule, [Rule | T]) ->
all_equal(Rule, T);
all_equal(_, [_ | _]) ->
- ?line ?t:sleep(?RECOVER_SLEEP), % Wait a while and *hope* that we'll
+ ?t:sleep(?RECOVER_SLEEP), % Wait a while and *hope* that we'll
% recover so other tests won't be
% affected.
?t:fail(max_socket_mismatch);
@@ -776,9 +783,9 @@ all_equal(_Rule, []) ->
ok.
max_socks() ->
- ?line Socks = open_socks(),
- ?line N = length(Socks),
- ?line lists:foreach(fun(S) -> ok = gen_tcp:close(S) end, Socks),
+ Socks = open_socks(),
+ N = length(Socks),
+ lists:foreach(fun(S) -> ok = gen_tcp:close(S) end, Socks),
io:format("Got ~p sockets", [N]),
N.
@@ -817,18 +824,18 @@ passive_sockets(doc) ->
["Tests that when 'the other side' on a passive socket closes, the connecting",
"side still can read until the end of data."];
passive_sockets(Config) when is_list(Config) ->
- ?line spawn_link(?MODULE, passive_sockets_server,
- [[{active,false}],self()]),
- ?line receive
- {socket,Port} -> ok
- end,
+ spawn_link(?MODULE, passive_sockets_server,
+ [[{active,false}],self()]),
+ receive
+ {socket,Port} -> ok
+ end,
?t:sleep(500),
- ?line case gen_tcp:connect("localhost", Port, [{active, false}]) of
- {ok, Sock} ->
- passive_sockets_read(Sock);
- Error ->
- ?t:fail({"Could not connect to server", Error})
- end.
+ case gen_tcp:connect("localhost", Port, [{active, false}]) of
+ {ok, Sock} ->
+ passive_sockets_read(Sock);
+ Error ->
+ ?t:fail({"Could not connect to server", Error})
+ end.
%%
%% Read until we get an {error, closed}. If we get another error, this test case
@@ -847,58 +854,58 @@ passive_sockets_read(Sock) ->
end.
passive_sockets_server(Opts, Parent) ->
- ?line case gen_tcp:listen(0, Opts) of
- {ok, LSock} ->
- {ok,{_,Port}} = inet:sockname(LSock),
- Parent ! {socket,Port},
- passive_sockets_server_accept(LSock);
- Error ->
- ?t:fail({"Could not create listen socket", Error})
- end.
+ case gen_tcp:listen(0, Opts) of
+ {ok, LSock} ->
+ {ok,{_,Port}} = inet:sockname(LSock),
+ Parent ! {socket,Port},
+ passive_sockets_server_accept(LSock);
+ Error ->
+ ?t:fail({"Could not create listen socket", Error})
+ end.
passive_sockets_server_accept(Sock) ->
- ?line case gen_tcp:accept(Sock) of
- {ok, Socket} ->
- ?t:sleep(500), % Simulate latency
- passive_sockets_server_send(Socket, 5),
- passive_sockets_server_accept(Sock);
- Error ->
- ?t:fail({"Could not accept connection", Error})
- end.
+ case gen_tcp:accept(Sock) of
+ {ok, Socket} ->
+ ?t:sleep(500), % Simulate latency
+ passive_sockets_server_send(Socket, 5),
+ passive_sockets_server_accept(Sock);
+ Error ->
+ ?t:fail({"Could not accept connection", Error})
+ end.
passive_sockets_server_send(Socket, 0) ->
io:format("Closing other end..~n", []),
gen_tcp:close(Socket);
passive_sockets_server_send(Socket, X) ->
- ?line Data = lists:duplicate(1024*X, $a),
- ?line case gen_tcp:send(Socket, Data) of
- ok ->
- ?t:sleep(50), % Simulate some processing.
- passive_sockets_server_send(Socket, X-1);
- {error, _Reason} ->
- ?t:fail("Failed to send data")
- end.
+ Data = lists:duplicate(1024*X, $a),
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ?t:sleep(50), % Simulate some processing.
+ passive_sockets_server_send(Socket, X-1);
+ {error, _Reason} ->
+ ?t:fail("Failed to send data")
+ end.
accept_closed_by_other_process(doc) ->
["Tests the return value from gen_tcp:accept when ",
"the socket is closed from another process. (OTP-3817)"];
accept_closed_by_other_process(Config) when is_list(Config) ->
- ?line Parent = self(),
- ?line {ok, ListenSocket} = gen_tcp:listen(0, []),
- ?line Child =
+ Parent = self(),
+ {ok, ListenSocket} = gen_tcp:listen(0, []),
+ Child =
spawn_link(
fun() ->
Parent ! {self(), gen_tcp:accept(ListenSocket)}
end),
- ?line receive after 1000 -> ok end,
- ?line ok = gen_tcp:close(ListenSocket),
- ?line receive
- {Child, {error, closed}} ->
- ok;
- {Child, Other} ->
- ?t:fail({"Wrong result of gen_tcp:accept", Other})
- end.
+ receive after 1000 -> ok end,
+ ok = gen_tcp:close(ListenSocket),
+ receive
+ {Child, {error, closed}} ->
+ ok;
+ {Child, Other} ->
+ ?t:fail({"Wrong result of gen_tcp:accept", Other})
+ end.
repeat(N, Fun) ->
repeat(N, N, Fun).
@@ -915,9 +922,9 @@ closed_socket(suite) ->
closed_socket(doc) ->
["Tests the response when using a closed socket as argument"];
closed_socket(Config) when is_list(Config) ->
- ?line {ok, LS1} = gen_tcp:listen(0, []),
- ?line erlang:yield(),
- ?line ok = gen_tcp:close(LS1),
+ {ok, LS1} = gen_tcp:listen(0, []),
+ erlang:yield(),
+ ok = gen_tcp:close(LS1),
%% If the following delay is uncommented, the result error values
%% below will change from {error, einval} to {error, closed} since
%% inet_db then will have noticed that the socket is closed.
@@ -925,19 +932,18 @@ closed_socket(Config) when is_list(Config) ->
%% in inet_db processes the 'EXIT' message from the port,
%% the socket is unregistered.
%%
- %% ?line test_server:sleep(test_server:seconds(2)),
+ %% test_server:sleep(test_server:seconds(2)),
%%
- ?line {error, R_send} = gen_tcp:send(LS1, "data"),
- ?line {error, R_recv} = gen_tcp:recv(LS1, 17),
- ?line {error, R_accept} = gen_tcp:accept(LS1),
- ?line {error, R_controlling_process} =
+ {error, R_send} = gen_tcp:send(LS1, "data"),
+ {error, R_recv} = gen_tcp:recv(LS1, 17),
+ {error, R_accept} = gen_tcp:accept(LS1),
+ {error, R_controlling_process} =
gen_tcp:controlling_process(LS1, self()),
%%
- ?line ok = io:format("R_send = ~p~n", [R_send]),
- ?line ok = io:format("R_recv = ~p~n", [R_recv]),
- ?line ok = io:format("R_accept = ~p~n", [R_accept]),
- ?line ok = io:format("R_controlling_process = ~p~n",
- [R_controlling_process]),
+ ok = io:format("R_send = ~p~n", [R_send]),
+ ok = io:format("R_recv = ~p~n", [R_recv]),
+ ok = io:format("R_accept = ~p~n", [R_accept]),
+ ok = io:format("R_controlling_process = ~p~n", [R_controlling_process]),
ok.
%%%
@@ -945,28 +951,27 @@ closed_socket(Config) when is_list(Config) ->
%%%
shutdown_active(Config) when is_list(Config) ->
- ?line shutdown_common(true).
+ shutdown_common(true).
shutdown_passive(Config) when is_list(Config) ->
- ?line shutdown_common(false).
+ shutdown_common(false).
shutdown_common(Active) ->
- ?line P = sort_server(Active),
+ P = sort_server(Active),
io:format("Sort server port: ~p\n", [P]),
- ?line do_sort(P, []),
- ?line do_sort(P, ["glurf"]),
- ?line do_sort(P, ["abc","nisse","dum"]),
-
- ?line do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(25, 255)]),
- ?line do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(77, 999)]),
- ?line do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(25, 55)]),
- ?line do_sort(P, []),
- ?line do_sort(P, ["apa"]),
- ?line do_sort(P, ["kluns","gorilla"]),
- ?line do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(25, 1233)]),
- ?line do_sort(P, []),
-
+ do_sort(P, []),
+ do_sort(P, ["glurf"]),
+ do_sort(P, ["abc","nisse","dum"]),
+
+ do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(25, 255)]),
+ do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(77, 999)]),
+ do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(25, 55)]),
+ do_sort(P, []),
+ do_sort(P, ["apa"]),
+ do_sort(P, ["kluns","gorilla"]),
+ do_sort(P, [lists:reverse(integer_to_list(I)) || I <- lists:seq(25, 1233)]),
+ do_sort(P, []),
receive
Any ->
?t:fail({unexpected_message,Any})
@@ -985,14 +990,14 @@ do_sort(P, List0) ->
sort_server(Active) ->
Opts = [{exit_on_close,false},{packet,line},{active,Active}],
- ?line {ok,L} = gen_tcp:listen(0, Opts),
+ {ok,L} = gen_tcp:listen(0, Opts),
Go = make_ref(),
- ?line Pid = spawn_link(fun() ->
- receive Go -> sort_server_1(L, Active) end
- end),
- ?line ok = gen_tcp:controlling_process(L, Pid),
- ?line Pid ! Go,
- ?line {ok,Port} = inet:port(L),
+ Pid = spawn_link(fun() ->
+ receive Go -> sort_server_1(L, Active) end
+ end),
+ ok = gen_tcp:controlling_process(L, Pid),
+ Pid ! Go,
+ {ok,Port} = inet:port(L),
Port.
sort_server_1(L, Active) ->
@@ -1042,17 +1047,17 @@ shutdown_pending(Config) when is_list(Config) ->
Data = [<<N:32>>,ones(N),42],
P = a_server(),
io:format("Server port: ~p\n", [P]),
- ?line {ok,S} = gen_tcp:connect(localhost, P, []),
- ?line gen_tcp:send(S, Data),
- ?line gen_tcp:shutdown(S, write),
- ?line receive
- {tcp,S,Msg} ->
- io:format("~p\n", [Msg]),
- ?line N = list_to_integer(Msg) - 5;
- Other ->
- ?t:fail({unexpected,Other})
- end,
- ok.
+ {ok,S} = gen_tcp:connect(localhost, P, []),
+ gen_tcp:send(S, Data),
+ gen_tcp:shutdown(S, write),
+ receive
+ {tcp,S,Msg} ->
+ io:format("~p\n", [Msg]),
+ N = list_to_integer(Msg) - 5;
+ Other ->
+ ?t:fail({unexpected,Other})
+ end,
+ ok.
ones(0) -> [];
ones(1) -> [1];
@@ -1065,10 +1070,10 @@ shutdown_pending(Config) when is_list(Config) ->
end.
a_server() ->
- ?line {ok,L} = gen_tcp:listen(0, [{exit_on_close,false},{active,false}]),
- ?line Pid = spawn_link(fun() -> a_server(L) end),
- ?line ok = gen_tcp:controlling_process(L, Pid),
- ?line {ok,Port} = inet:port(L),
+ {ok,L} = gen_tcp:listen(0, [{exit_on_close,false},{active,false}]),
+ Pid = spawn_link(fun() -> a_server(L) end),
+ ok = gen_tcp:controlling_process(L, Pid),
+ {ok,Port} = inet:port(L),
Port.
a_server(L) ->
@@ -1085,24 +1090,328 @@ shutdown_pending(Config) when is_list(Config) ->
gen_tcp:close(S)
end.
+%%
+%% Test 'show_econnreset' option
+%%
+
+show_econnreset_active(Config) when is_list(Config) ->
+ %% First confirm everything works with option turned off.
+ {ok, L} = gen_tcp:listen(0, []),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port, [{active, false}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ ok = inet:setopts(Client, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(Client),
+ receive
+ {tcp_closed, S} ->
+ ok;
+ Other ->
+ ?t:fail({unexpected1, Other})
+ after 1000 ->
+ ?t:fail({timeout, {server, no_tcp_closed}})
+ end,
+
+ %% Now test with option switched on.
+ %% Note: We are also testing that the show_econnreset option is
+ %% inherited from the listening socket by the accepting socket.
+ {ok, L1} = gen_tcp:listen(0, [{show_econnreset, true}]),
+ {ok, Port1} = inet:port(L1),
+ {ok, Client1} = gen_tcp:connect(localhost, Port1, [{active, false}]),
+ {ok, S1} = gen_tcp:accept(L1),
+ ok = gen_tcp:close(L1),
+ ok = inet:setopts(Client1, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(Client1),
+ receive
+ {tcp_error, S1, econnreset} ->
+ receive
+ {tcp_closed, S1} ->
+ ok;
+ Other1 ->
+ ?t:fail({unexpected2, Other1})
+ after 1 ->
+ ?t:fail({timeout, {server, no_tcp_closed}})
+ end;
+ Other2 ->
+ ?t:fail({unexpected3, Other2})
+ after 1000 ->
+ ?t:fail({timeout, {server, no_tcp_error}})
+ end.
+
+show_econnreset_active_once(Config) when is_list(Config) ->
+ %% Now test using {active, once}
+ {ok, L} = gen_tcp:listen(0,
+ [{active, false},
+ {show_econnreset, true}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port, [{active, false}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ ok = inet:setopts(Client, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(Client),
+ ok = ?t:sleep(20),
+ ok = receive Msg -> {unexpected_msg, Msg} after 0 -> ok end,
+ ok = inet:setopts(S, [{active, once}]),
+ receive
+ {tcp_error, S, econnreset} ->
+ receive
+ {tcp_closed, S} ->
+ ok;
+ Other1 ->
+ ?t:fail({unexpected1, Other1})
+ after 1 ->
+ ?t:fail({timeout, {server, no_tcp_closed}})
+ end;
+ Other2 ->
+ ?t:fail({unexpected2, Other2})
+ after 1000 ->
+ ?t:fail({timeout, {server, no_tcp_error}})
+ end.
+
+show_econnreset_passive(Config) when is_list(Config) ->
+ %% First confirm everything works with option turned off.
+ {ok, L} = gen_tcp:listen(0, [{active, false}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port, [{active, false}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ ok = inet:setopts(S, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S),
+ ok = ?t:sleep(1),
+ {error, closed} = gen_tcp:recv(Client, 0),
+
+ %% Now test with option switched on.
+ {ok, L1} = gen_tcp:listen(0, [{active, false}]),
+ {ok, Port1} = inet:port(L1),
+ {ok, Client1} = gen_tcp:connect(localhost, Port1,
+ [{active, false},
+ {show_econnreset, true}]),
+ {ok, S1} = gen_tcp:accept(L1),
+ ok = gen_tcp:close(L1),
+ ok = inet:setopts(S1, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S1),
+ ok = ?t:sleep(1),
+ {error, econnreset} = gen_tcp:recv(Client1, 0).
+
+econnreset_after_sync_send(Config) when is_list(Config) ->
+ %% First confirm everything works with option turned off.
+ {ok, L} = gen_tcp:listen(0, [{active, false}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port, [{active, false}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ ok = inet:setopts(S, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S),
+ ok = ?t:sleep(20),
+ {error, closed} = gen_tcp:send(Client, "Whatever"),
+
+ %% Now test with option switched on.
+ {ok, L1} = gen_tcp:listen(0, [{active, false}]),
+ {ok, Port1} = inet:port(L1),
+ {ok, Client1} = gen_tcp:connect(localhost, Port1,
+ [{active, false},
+ {show_econnreset, true}]),
+ {ok, S1} = gen_tcp:accept(L1),
+ ok = gen_tcp:close(L1),
+ ok = inet:setopts(S1, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S1),
+ ok = ?t:sleep(20),
+ {error, econnreset} = gen_tcp:send(Client1, "Whatever").
+
+econnreset_after_async_send_active(Config) when is_list(Config) ->
+ {OS, _} = os:type(),
+ Payload = lists:duplicate(1024 * 1024, $.),
+
+ %% First confirm everything works with option turned off.
+ {ok, L} = gen_tcp:listen(0, [{active, false}, {recbuf, 4096}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port, [{sndbuf, 4096}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ ok = gen_tcp:send(Client, Payload),
+ case erlang:port_info(Client, queue_size) of
+ {queue_size, N} when N > 0 -> ok;
+ {queue_size, 0} when OS =:= win32 -> ok;
+ {queue_size, 0} = T -> ?t:fail(T)
+ end,
+ ok = gen_tcp:send(S, "Whatever"),
+ ok = ?t:sleep(20),
+ ok = inet:setopts(S, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S),
+ ok = ?t:sleep(20),
+ receive
+ {tcp, Client, "Whatever"} ->
+ receive
+ {tcp_closed, Client} ->
+ ok;
+ Other1 ->
+ ?t:fail({unexpected1, Other1})
+ end;
+ Other2 ->
+ ?t:fail({unexpected2, Other2})
+ end,
+
+ %% Now test with option switched on.
+ {ok, L1} = gen_tcp:listen(0, [{active, false}, {recbuf, 4096}]),
+ {ok, Port1} = inet:port(L1),
+ {ok, Client1} = gen_tcp:connect(localhost, Port1,
+ [{sndbuf, 4096},
+ {show_econnreset, true}]),
+ {ok, S1} = gen_tcp:accept(L1),
+ ok = gen_tcp:close(L1),
+ ok = gen_tcp:send(Client1, Payload),
+ case erlang:port_info(Client1, queue_size) of
+ {queue_size, N1} when N1 > 0 -> ok;
+ {queue_size, 0} when OS =:= win32 -> ok;
+ {queue_size, 0} = T1 -> ?t:fail(T1)
+ end,
+ ok = gen_tcp:send(S1, "Whatever"),
+ ok = ?t:sleep(20),
+ ok = inet:setopts(S1, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S1),
+ ok = ?t:sleep(20),
+ receive
+ {tcp, Client1, "Whatever"} ->
+ receive
+ {tcp_error, Client1, econnreset} ->
+ receive
+ {tcp_closed, Client1} ->
+ ok;
+ Other3 ->
+ ?t:fail({unexpected3, Other3})
+ end;
+ Other4 ->
+ ?t:fail({unexpected4, Other4})
+ end;
+ Other5 ->
+ ?t:fail({unexpected5, Other5})
+ end.
+
+econnreset_after_async_send_active_once(Config) when is_list(Config) ->
+ {OS, _} = os:type(),
+ {ok, L} = gen_tcp:listen(0, [{active, false}, {recbuf, 4096}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port,
+ [{active, false},
+ {sndbuf, 4096},
+ {show_econnreset, true}]),
+ {ok,S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ Payload = lists:duplicate(1024 * 1024, $.),
+ ok = gen_tcp:send(Client, Payload),
+ case erlang:port_info(Client, queue_size) of
+ {queue_size, N} when N > 0 -> ok;
+ {queue_size, 0} when OS =:= win32 -> ok;
+ {queue_size, 0} = T -> ?t:fail(T)
+ end,
+ ok = gen_tcp:send(S, "Whatever"),
+ ok = ?t:sleep(20),
+ ok = inet:setopts(S, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(S),
+ ok = ?t:sleep(20),
+ ok = receive Msg -> {unexpected_msg, Msg} after 0 -> ok end,
+ ok = inet:setopts(Client, [{active, once}]),
+ receive
+ {tcp_error, Client, econnreset} ->
+ receive
+ {tcp_closed, Client} ->
+ ok;
+ Other ->
+ ?t:fail({unexpected1, Other})
+ end;
+ Other ->
+ ?t:fail({unexpected2, Other})
+ end.
+
+econnreset_after_async_send_passive(Config) when is_list(Config) ->
+ {OS, _} = os:type(),
+ Payload = lists:duplicate(1024 * 1024, $.),
+
+ %% First confirm everything works with option turned off.
+ {ok, L} = gen_tcp:listen(0, [{active, false}, {recbuf, 4096}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port,
+ [{active, false},
+ {sndbuf, 4096}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ ok = inet:setopts(S, [{linger, {true, 0}}]),
+ ok = gen_tcp:send(S, "Whatever"),
+ ok = gen_tcp:send(Client, Payload),
+ case erlang:port_info(Client, queue_size) of
+ {queue_size, N} when N > 0 -> ok;
+ {queue_size, 0} when OS =:= win32 -> ok;
+ {queue_size, 0} = T -> ?t:fail(T)
+ end,
+ ok = gen_tcp:close(S),
+ ok = ?t:sleep(20),
+ {error, closed} = gen_tcp:recv(Client, 0),
+
+ %% Now test with option switched on.
+ {ok, L1} = gen_tcp:listen(0, [{active, false}, {recbuf, 4096}]),
+ {ok, Port1} = inet:port(L1),
+ {ok, Client1} = gen_tcp:connect(localhost, Port1,
+ [{active, false},
+ {sndbuf, 4096},
+ {show_econnreset, true}]),
+ {ok, S1} = gen_tcp:accept(L1),
+ ok = gen_tcp:close(L1),
+ ok = inet:setopts(S1, [{linger, {true, 0}}]),
+ ok = gen_tcp:send(S1, "Whatever"),
+ ok = gen_tcp:send(Client1, Payload),
+ ok = gen_tcp:close(S1),
+ ok = ?t:sleep(20),
+ {error, econnreset} = gen_tcp:recv(Client1, 0).
+
+%%
+%% Test {linger {true, 0}} aborts a connection
+%%
+
+linger_zero(Config) when is_list(Config) ->
+ %% All the econnreset tests will prove that {linger, {true, 0}} aborts
+ %% a connection when the driver queue is empty. We will test here
+ %% that it also works when the driver queue is not empty.
+ {OS, _} = os:type(),
+ {ok, L} = gen_tcp:listen(0, [{active, false},
+ {recbuf, 4096},
+ {show_econnreset, true}]),
+ {ok, Port} = inet:port(L),
+ {ok, Client} = gen_tcp:connect(localhost, Port,
+ [{active, false},
+ {sndbuf, 4096}]),
+ {ok, S} = gen_tcp:accept(L),
+ ok = gen_tcp:close(L),
+ PayloadSize = 1024 * 1024,
+ Payload = lists:duplicate(PayloadSize, $.),
+ ok = gen_tcp:send(Client, Payload),
+ case erlang:port_info(Client, queue_size) of
+ {queue_size, N} when N > 0 -> ok;
+ {queue_size, 0} when OS =:= win32 -> ok;
+ {queue_size, 0} = T -> ?t:fail(T)
+ end,
+ ok = inet:setopts(Client, [{linger, {true, 0}}]),
+ ok = gen_tcp:close(Client),
+ ok = ?t:sleep(1),
+ undefined = erlang:port_info(Client, connected),
+ {error, econnreset} = gen_tcp:recv(S, PayloadSize).
+
%% Thanks to Luke Gorrie. Tests for a very specific problem with
%% corrupt data. The testcase will be killed by the timetrap timeout
%% if the bug is present.
http_bad_packet(Config) when is_list(Config) ->
- ?line {ok,L} = gen_tcp:listen(0,
- [{active, false},
- binary,
- {reuseaddr, true},
- {packet, http}]),
- ?line {ok,Port} = inet:port(L),
- ?line spawn_link(fun() -> erlang:yield(), http_bad_client(Port) end),
- ?line case gen_tcp:accept(L) of
- {ok,S} ->
- http_worker(S);
- Err ->
- exit({accept,Err})
- end.
+ {ok,L} = gen_tcp:listen(0, [{active, false},
+ binary,
+ {reuseaddr, true},
+ {packet, http}]),
+ {ok,Port} = inet:port(L),
+ spawn_link(fun() -> erlang:yield(), http_bad_client(Port) end),
+ case gen_tcp:accept(L) of
+ {ok,S} ->
+ http_worker(S);
+ Err ->
+ exit({accept,Err})
+ end.
http_worker(S) ->
case gen_tcp:recv(S, 0, 30000) of
@@ -1122,9 +1431,9 @@ http_bad_client(Port) ->
%% Fill send queue and then start receiving.
%%
busy_send(Config) when is_list(Config) ->
- ?line Master = self(),
- ?line Msg = <<"the quick brown fox jumps over a lazy dog~n">>,
- ?line Server =
+ Master = self(),
+ Msg = <<"the quick brown fox jumps over a lazy dog~n">>,
+ Server =
spawn_link(fun () ->
{ok,L} = gen_tcp:listen
(0, [{active,false},binary,
@@ -1134,45 +1443,42 @@ busy_send(Config) when is_list(Config) ->
busy_send_client(Port, Master, Msg)},
busy_send_srv(L, Master, Msg)
end),
- ?line io:format("~p Server~n", [Server]),
- ?line receive
- {Server,client,Client} ->
- ?line io:format("~p Client~n", [Client]),
- ?line busy_send_loop(Server, Client, 0)
- end.
+ io:format("~p Server~n", [Server]),
+ receive
+ {Server,client,Client} ->
+ io:format("~p Client~n", [Client]),
+ busy_send_loop(Server, Client, 0)
+ end.
busy_send_loop(Server, Client, N) ->
%% Master
%%
- ?line receive {Server,send} ->
+ receive {Server,send} ->
busy_send_loop(Server, Client, N+1)
after 2000 ->
%% Send queue full, sender blocked
%% -> stop sender and release client
- ?line io:format("Send timeout, time to receive...~n", []),
- ?line Server ! {self(),close},
- ?line Client ! {self(),recv,N+1},
- ?line receive
- {Server,send} ->
- ?line busy_send_2(Server, Client, N+1)
- after 10000 ->
- %% If this happens, see busy_send_srv
- ?t:fail({timeout,{server,not_send,flush([])}})
- end
- end.
+ io:format("Send timeout, time to receive...~n", []),
+ Server ! {self(),close},
+ Client ! {self(),recv,N+1},
+ receive
+ {Server,send} ->
+ busy_send_2(Server, Client, N+1)
+ after 10000 ->
+ %% If this happens, see busy_send_srv
+ ?t:fail({timeout,{server,not_send,flush([])}})
+ end
+ end.
busy_send_2(Server, Client, _N) ->
%% Master
%%
- ?line receive
- {Server,[closed]} ->
- ?line receive
- {Client,[0,{error,closed}]} ->
- ok
- end
- after 10000 ->
- ?t:fail({timeout,{server,not_closed,flush([])}})
- end.
+ receive
+ {Server,[closed]} ->
+ receive {Client,[0,{error,closed}]} -> ok end
+ after 10000 ->
+ ?t:fail({timeout,{server,not_closed,flush([])}})
+ end.
busy_send_srv(L, Master, Msg) ->
%% Server
@@ -1228,7 +1534,7 @@ busy_send_client_loop(Socket, Master, Msg, N) ->
busy_disconnect_passive(Config) when is_list(Config) ->
MuchoData = list_to_binary(ones(64*1024)),
- ?line [do_busy_disconnect_passive(MuchoData) || _ <- lists:seq(1, 10)],
+ [do_busy_disconnect_passive(MuchoData) || _ <- lists:seq(1, 10)],
ok.
do_busy_disconnect_passive(MuchoData) ->
@@ -1236,8 +1542,8 @@ do_busy_disconnect_passive(MuchoData) ->
busy_disconnect_passive_send(S, MuchoData).
busy_disconnect_passive_send(S, Data) ->
- ?line case gen_tcp:send(S, Data) of
- ok -> ?line busy_disconnect_passive_send(S, Data);
+ case gen_tcp:send(S, Data) of
+ ok -> busy_disconnect_passive_send(S, Data);
{error,closed} -> ok
end.
@@ -1248,7 +1554,7 @@ busy_disconnect_passive_send(S, Data) ->
%%%
busy_disconnect_active(Config) when is_list(Config) ->
MuchoData = list_to_binary(ones(64*1024)),
- ?line [do_busy_disconnect_active(MuchoData) || _ <- lists:seq(1, 10)],
+ [do_busy_disconnect_active(MuchoData) || _ <- lists:seq(1, 10)],
ok.
do_busy_disconnect_active(MuchoData) ->
@@ -1256,21 +1562,21 @@ do_busy_disconnect_active(MuchoData) ->
busy_disconnect_active_send(S, MuchoData).
busy_disconnect_active_send(S, Data) ->
- ?line case gen_tcp:send(S, Data) of
- ok -> ?line busy_disconnect_active_send(S, Data);
+ case gen_tcp:send(S, Data) of
+ ok -> busy_disconnect_active_send(S, Data);
{error,closed} ->
receive
{tcp_closed,S} -> ok;
- _Other -> ?line ?t:fail()
+ _Other -> ?t:fail()
end
end.
busy_disconnect_prepare_server(ConnectOpts) ->
- ?line Sender = self(),
- ?line Server = spawn_link(fun() -> busy_disconnect_server(Sender) end),
+ Sender = self(),
+ Server = spawn_link(fun() -> busy_disconnect_server(Sender) end),
receive {port,Server,Port} -> ok end,
- ?line {ok,S} = gen_tcp:connect(localhost, Port, ConnectOpts),
+ {ok,S} = gen_tcp:connect(localhost, Port, ConnectOpts),
Server ! {Sender,sending},
S.
@@ -1304,8 +1610,8 @@ busy_disconnect_server_wait_for_busy(Sender, S) ->
%%% Fill send queue
%%%
fill_sendq(Config) when is_list(Config) ->
- ?line Master = self(),
- ?line Server =
+ Master = self(),
+ Server =
spawn_link(fun () ->
{ok,L} = gen_tcp:listen
(0, [{active,false},binary,
@@ -1315,12 +1621,12 @@ fill_sendq(Config) when is_list(Config) ->
fill_sendq_client(Port, Master)},
fill_sendq_srv(L, Master)
end),
- ?line io:format("~p Server~n", [Server]),
- ?line receive {Server,client,Client} ->
- ?line io:format("~p Client~n", [Client]),
- ?line receive {Server,reader,Reader} ->
- ?line io:format("~p Reader~n", [Reader]),
- ?line fill_sendq_loop(Server, Client, Reader)
+ io:format("~p Server~n", [Server]),
+ receive {Server,client,Client} ->
+ io:format("~p Client~n", [Client]),
+ receive {Server,reader,Reader} ->
+ io:format("~p Reader~n", [Reader]),
+ fill_sendq_loop(Server, Client, Reader)
end
end.
@@ -1331,21 +1637,21 @@ fill_sendq_loop(Server, Client, Reader) ->
fill_sendq_loop(Server, Client, Reader)
after 2000 ->
%% Send queue full, sender blocked -> close client.
- ?line io:format("Send timeout, closing Client...~n", []),
- ?line Client ! {self(),close},
- ?line receive {Server,[{error,closed}]} ->
- ?line io:format("Got server closed.~n"),
- ?line receive {Reader,[{error,closed}]} ->
- ?line io:format
+ io:format("Send timeout, closing Client...~n", []),
+ Client ! {self(),close},
+ receive {Server,[{error,closed}]} ->
+ io:format("Got server closed.~n"),
+ receive {Reader,[{error,closed}]} ->
+ io:format
("Got reader closed.~n"),
ok
after 3000 ->
?t:fail({timeout,{closed,reader}})
end;
{Reader,[{error,closed}]} ->
- ?line io:format("Got reader closed.~n"),
- ?line receive {Server,[{error,closed}]} ->
- ?line io:format("Got server closed~n"),
+ io:format("Got reader closed.~n"),
+ receive {Server,[{error,closed}]} ->
+ io:format("Got server closed~n"),
ok
after 3000 ->
?t:fail({timeout,{closed,server}})
@@ -1416,39 +1722,39 @@ fill_sendq_client(Port, Master) ->
%%% a closed socket.
%%%
partial_recv_and_close(Config) when is_list(Config) ->
- ?line Msg = "the quick brown fox jumps over a lazy dog 0123456789\n",
- ?line Len = length(Msg),
- ?line {ok,L} = gen_tcp:listen(0, [{active,false}]),
- ?line {ok,P} = inet:port(L),
- ?line {ok,S} = gen_tcp:connect("localhost", P, [{active,false}]),
- ?line {ok,A} = gen_tcp:accept(L),
- ?line ok = gen_tcp:send(S, Msg),
- ?line ok = gen_tcp:close(S),
- ?line {error,closed} = gen_tcp:recv(A, Len+1),
+ Msg = "the quick brown fox jumps over a lazy dog 0123456789\n",
+ Len = length(Msg),
+ {ok,L} = gen_tcp:listen(0, [{active,false}]),
+ {ok,P} = inet:port(L),
+ {ok,S} = gen_tcp:connect("localhost", P, [{active,false}]),
+ {ok,A} = gen_tcp:accept(L),
+ ok = gen_tcp:send(S, Msg),
+ ok = gen_tcp:close(S),
+ {error,closed} = gen_tcp:recv(A, Len+1),
ok.
%%% Try to receive more than available number of bytes from
%%% a closed socket, this time waiting in the recv before closing.
%%%
partial_recv_and_close_2(Config) when is_list(Config) ->
- ?line Msg = "the quick brown fox jumps over a lazy dog 0123456789\n",
- ?line Len = length(Msg),
- ?line {ok,L} = gen_tcp:listen(0, [{active,false}]),
- ?line {ok,P} = inet:port(L),
- ?line Server = self(),
- ?line Client =
+ Msg = "the quick brown fox jumps over a lazy dog 0123456789\n",
+ Len = length(Msg),
+ {ok,L} = gen_tcp:listen(0, [{active,false}]),
+ {ok,P} = inet:port(L),
+ Server = self(),
+ Client =
spawn_link(
fun () ->
receive after 2000 -> ok end,
{ok,S} = gen_tcp:connect("localhost", P, [{active,false}]),
- ?line ok = gen_tcp:send(S, Msg),
+ ok = gen_tcp:send(S, Msg),
receive {Server,close} -> ok end,
receive after 2000 -> ok end,
- ?line ok = gen_tcp:close(S)
+ ok = gen_tcp:close(S)
end),
- ?line {ok,A} = gen_tcp:accept(L),
- ?line Client ! {Server,close},
- ?line {error,closed} = gen_tcp:recv(A, Len+1),
+ {ok,A} = gen_tcp:accept(L),
+ Client ! {Server,close},
+ {error,closed} = gen_tcp:recv(A, Len+1),
ok.
%%% Here we tests that gen_tcp:recv/2 will return {error,closed} following
@@ -1471,151 +1777,151 @@ do_partial_recv_and_close_3() ->
receive
{port,Port} -> ok
end,
- ?line Much = ones(8*64*1024),
- ?line {ok,S} = gen_tcp:connect(localhost, Port, [{active,false}]),
+ Much = ones(8*64*1024),
+ {ok,S} = gen_tcp:connect(localhost, Port, [{active,false}]),
%% Send a lot of data (most of it will be queued). The receiver will read one byte
%% and close the connection. The write operation will fail.
- ?line gen_tcp:send(S, Much),
+ gen_tcp:send(S, Much),
%% We should always get {error,closed} here.
- ?line {error,closed} = gen_tcp:recv(S, 0).
+ {error,closed} = gen_tcp:recv(S, 0).
test_prio_put_get() ->
Tos = 3 bsl 5,
- ?line {ok,L1} = gen_tcp:listen(0, [{active,false}]),
- ?line ok = inet:setopts(L1,[{priority,3}]),
- ?line ok = inet:setopts(L1,[{tos,Tos}]),
- ?line {ok,[{priority,3},{tos,Tos}]} = inet:getopts(L1,[priority,tos]),
- ?line ok = inet:setopts(L1,[{priority,3}]), % Dont destroy each other
- ?line {ok,[{priority,3},{tos,Tos}]} = inet:getopts(L1,[priority,tos]),
- ?line ok = inet:setopts(L1,[{reuseaddr,true}]), % Dont let others destroy
- ?line {ok,[{priority,3},{tos,Tos}]} = inet:getopts(L1,[priority,tos]),
- ?line gen_tcp:close(L1),
+ {ok,L1} = gen_tcp:listen(0, [{active,false}]),
+ ok = inet:setopts(L1,[{priority,3}]),
+ ok = inet:setopts(L1,[{tos,Tos}]),
+ {ok,[{priority,3},{tos,Tos}]} = inet:getopts(L1,[priority,tos]),
+ ok = inet:setopts(L1,[{priority,3}]), % Dont destroy each other
+ {ok,[{priority,3},{tos,Tos}]} = inet:getopts(L1,[priority,tos]),
+ ok = inet:setopts(L1,[{reuseaddr,true}]), % Dont let others destroy
+ {ok,[{priority,3},{tos,Tos}]} = inet:getopts(L1,[priority,tos]),
+ gen_tcp:close(L1),
ok.
test_prio_accept() ->
- ?line {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
- {reuseaddr,true},{priority,4}]),
- ?line {ok,Port} = inet:port(Sock),
- ?line {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
- {active,false},
- {reuseaddr,true},
- {priority,4}]),
- ?line {ok,Sock3}=gen_tcp:accept(Sock),
- ?line {ok,[{priority,4}]} = inet:getopts(Sock,[priority]),
- ?line {ok,[{priority,4}]} = inet:getopts(Sock2,[priority]),
- ?line {ok,[{priority,4}]} = inet:getopts(Sock3,[priority]),
- ?line gen_tcp:close(Sock),
- ?line gen_tcp:close(Sock2),
- ?line gen_tcp:close(Sock3),
+ {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
+ {reuseaddr,true},{priority,4}]),
+ {ok,Port} = inet:port(Sock),
+ {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
+ {active,false},
+ {reuseaddr,true},
+ {priority,4}]),
+ {ok,Sock3}=gen_tcp:accept(Sock),
+ {ok,[{priority,4}]} = inet:getopts(Sock,[priority]),
+ {ok,[{priority,4}]} = inet:getopts(Sock2,[priority]),
+ {ok,[{priority,4}]} = inet:getopts(Sock3,[priority]),
+ gen_tcp:close(Sock),
+ gen_tcp:close(Sock2),
+ gen_tcp:close(Sock3),
ok.
test_prio_accept2() ->
Tos1 = 4 bsl 5,
Tos2 = 3 bsl 5,
- ?line {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
- {reuseaddr,true},{priority,4},
- {tos,Tos1}]),
- ?line {ok,Port} = inet:port(Sock),
- ?line {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
- {active,false},
- {reuseaddr,true},
- {priority,4},
- {tos,Tos2}]),
- ?line {ok,Sock3}=gen_tcp:accept(Sock),
- ?line {ok,[{priority,4},{tos,Tos1}]} = inet:getopts(Sock,[priority,tos]),
- ?line {ok,[{priority,4},{tos,Tos2}]} = inet:getopts(Sock2,[priority,tos]),
- ?line {ok,[{priority,4},{tos,Tos1}]} = inet:getopts(Sock3,[priority,tos]),
- ?line gen_tcp:close(Sock),
- ?line gen_tcp:close(Sock2),
- ?line gen_tcp:close(Sock3),
+ {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
+ {reuseaddr,true},{priority,4},
+ {tos,Tos1}]),
+ {ok,Port} = inet:port(Sock),
+ {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
+ {active,false},
+ {reuseaddr,true},
+ {priority,4},
+ {tos,Tos2}]),
+ {ok,Sock3}=gen_tcp:accept(Sock),
+ {ok,[{priority,4},{tos,Tos1}]} = inet:getopts(Sock,[priority,tos]),
+ {ok,[{priority,4},{tos,Tos2}]} = inet:getopts(Sock2,[priority,tos]),
+ {ok,[{priority,4},{tos,Tos1}]} = inet:getopts(Sock3,[priority,tos]),
+ gen_tcp:close(Sock),
+ gen_tcp:close(Sock2),
+ gen_tcp:close(Sock3),
ok.
test_prio_accept3() ->
Tos1 = 4 bsl 5,
Tos2 = 3 bsl 5,
- ?line {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
- {reuseaddr,true},
- {tos,Tos1}]),
- ?line {ok,Port} = inet:port(Sock),
- ?line {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
- {active,false},
- {reuseaddr,true},
- {tos,Tos2}]),
- ?line {ok,Sock3}=gen_tcp:accept(Sock),
- ?line {ok,[{priority,0},{tos,Tos1}]} = inet:getopts(Sock,[priority,tos]),
- ?line {ok,[{priority,0},{tos,Tos2}]} = inet:getopts(Sock2,[priority,tos]),
- ?line {ok,[{priority,0},{tos,Tos1}]} = inet:getopts(Sock3,[priority,tos]),
- ?line gen_tcp:close(Sock),
- ?line gen_tcp:close(Sock2),
- ?line gen_tcp:close(Sock3),
+ {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
+ {reuseaddr,true},
+ {tos,Tos1}]),
+ {ok,Port} = inet:port(Sock),
+ {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
+ {active,false},
+ {reuseaddr,true},
+ {tos,Tos2}]),
+ {ok,Sock3}=gen_tcp:accept(Sock),
+ {ok,[{priority,0},{tos,Tos1}]} = inet:getopts(Sock,[priority,tos]),
+ {ok,[{priority,0},{tos,Tos2}]} = inet:getopts(Sock2,[priority,tos]),
+ {ok,[{priority,0},{tos,Tos1}]} = inet:getopts(Sock3,[priority,tos]),
+ gen_tcp:close(Sock),
+ gen_tcp:close(Sock2),
+ gen_tcp:close(Sock3),
ok.
test_prio_accept_async() ->
Tos1 = 4 bsl 5,
Tos2 = 3 bsl 5,
Ref = make_ref(),
- ?line spawn(?MODULE,priority_server,[{self(),Ref}]),
- ?line Port = receive
- {Ref,P} -> P
- after 5000 -> ?t:fail({error,"helper process timeout"})
- end,
- ?line receive
- after 3000 -> ok
- end,
- ?line {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
- {active,false},
- {reuseaddr,true},
- {priority,4},
- {tos,Tos2}]),
- ?line receive
- {Ref,{ok,[{priority,4},{tos,Tos1}]}} ->
- ok ;
- {Ref,Error} ->
- ?t:fail({missmatch,Error})
- after 5000 -> ?t:fail({error,"helper process timeout"})
- end,
- ?line receive
- {Ref,{ok,[{priority,4},{tos,Tos1}]}} ->
- ok ;
- {Ref,Error2} ->
- ?t:fail({missmatch,Error2})
- after 5000 -> ?t:fail({error,"helper process timeout"})
- end,
-
- ?line {ok,[{priority,4},{tos,Tos2}]} = inet:getopts(Sock2,[priority,tos]),
- ?line catch gen_tcp:close(Sock2),
+ spawn(?MODULE,priority_server,[{self(),Ref}]),
+ Port = receive
+ {Ref,P} -> P
+ after 5000 -> ?t:fail({error,"helper process timeout"})
+ end,
+ receive
+ after 3000 -> ok
+ end,
+ {ok,Sock2}=gen_tcp:connect("localhost",Port,[binary,{packet,0},
+ {active,false},
+ {reuseaddr,true},
+ {priority,4},
+ {tos,Tos2}]),
+ receive
+ {Ref,{ok,[{priority,4},{tos,Tos1}]}} ->
+ ok;
+ {Ref,Error} ->
+ ?t:fail({missmatch,Error})
+ after 5000 -> ?t:fail({error,"helper process timeout"})
+ end,
+ receive
+ {Ref,{ok,[{priority,4},{tos,Tos1}]}} ->
+ ok;
+ {Ref,Error2} ->
+ ?t:fail({missmatch,Error2})
+ after 5000 -> ?t:fail({error,"helper process timeout"})
+ end,
+
+ {ok,[{priority,4},{tos,Tos2}]} = inet:getopts(Sock2,[priority,tos]),
+ catch gen_tcp:close(Sock2),
ok.
priority_server({Parent,Ref}) ->
Tos1 = 4 bsl 5,
- ?line {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
- {reuseaddr,true},{priority,4},
- {tos,Tos1}]),
- ?line {ok,Port} = inet:port(Sock),
+ {ok,Sock}=gen_tcp:listen(0,[binary,{packet,0},{active,false},
+ {reuseaddr,true},{priority,4},
+ {tos,Tos1}]),
+ {ok,Port} = inet:port(Sock),
Parent ! {Ref,Port},
- ?line {ok,Sock3}=gen_tcp:accept(Sock),
+ {ok,Sock3}=gen_tcp:accept(Sock),
Parent ! {Ref, inet:getopts(Sock,[priority,tos])},
Parent ! {Ref, inet:getopts(Sock3,[priority,tos])},
ok.
test_prio_fail() ->
- ?line {ok,L} = gen_tcp:listen(0, [{active,false}]),
- ?line {error,_} = inet:setopts(L,[{priority,1000}]),
+ {ok,L} = gen_tcp:listen(0, [{active,false}]),
+ {error,_} = inet:setopts(L,[{priority,1000}]),
% This error could only happen in linux kernels earlier than 2.6.24.4
% Privilege check is now disabled and IP_TOS can never fail (only silently
% be masked).
-% ?line {error,_} = inet:setopts(L,[{tos,6 bsl 5}]),
- ?line gen_tcp:close(L),
+% {error,_} = inet:setopts(L,[{tos,6 bsl 5}]),
+ gen_tcp:close(L),
ok.
test_prio_udp() ->
Tos = 3 bsl 5,
- ?line {ok,S} = gen_udp:open(0,[{active,false},binary,{tos, Tos},
- {priority,3}]),
- ?line {ok,[{priority,3},{tos,Tos}]} = inet:getopts(S,[priority,tos]),
- ?line gen_udp:close(S),
+ {ok,S} = gen_udp:open(0,[{active,false},binary,{tos, Tos},
+ {priority,3}]),
+ {ok,[{priority,3},{tos,Tos}]} = inet:getopts(S,[priority,tos]),
+ gen_udp:close(S),
ok.
so_priority(doc) ->
@@ -1623,9 +1929,9 @@ so_priority(doc) ->
so_priority(suite) ->
[];
so_priority(Config) when is_list(Config) ->
- ?line {ok,L} = gen_tcp:listen(0, [{active,false}]),
- ?line ok = inet:setopts(L,[{priority,1}]),
- ?line case inet:getopts(L,[priority]) of
+ {ok,L} = gen_tcp:listen(0, [{active,false}]),
+ ok = inet:setopts(L,[{priority,1}]),
+ case inet:getopts(L,[priority]) of
{ok,[{priority,1}]} ->
gen_tcp:close(L),
test_prio_put_get(),
@@ -1641,7 +1947,7 @@ so_priority(Config) when is_list(Config) ->
{unix,linux} ->
case os:version() of
{X,Y,_} when (X > 2) or ((X =:= 2) and (Y >= 4)) ->
- ?line ?t:fail({error,
+ ?t:fail({error,
"so_priority should work on this "
"OS, but does not"});
_ ->
@@ -1655,21 +1961,21 @@ so_priority(Config) when is_list(Config) ->
%% Accept test utilities (suites are below)
millis() ->
- {A,B,C}=erlang:now(),
- (A*1000000*1000)+(B*1000)+(C div 1000).
+ erlang:monotonic_time(milli_seconds).
-collect_accepts(Tmo) ->
+collect_accepts(0,_) -> [];
+collect_accepts(N,Tmo) ->
A = millis(),
receive
{accepted,P,Msg} ->
- [{P,Msg}] ++ collect_accepts(Tmo-(millis() - A))
+ [{P,Msg}] ++ collect_accepts(N-1,Tmo-(millis() - A))
after Tmo ->
[]
end.
--define(EXPECT_ACCEPTS(Pattern,Timeout),
+-define(EXPECT_ACCEPTS(Pattern,N,Timeout),
(fun() ->
- case collect_accepts(Timeout) of
+ case collect_accepts(if N =:= infinity -> -1; true -> N end,Timeout) of
Pattern ->
ok;
Other ->
@@ -1705,20 +2011,20 @@ primitive_accept(suite) ->
primitive_accept(doc) ->
["Test singular accept"];
primitive_accept(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line {ok,PortNo}=inet:port(LS),
- ?line Parent = self(),
- ?line F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
- ?line P = spawn(F),
- ?line gen_tcp:connect("localhost",PortNo,[]),
- ?line receive
- {accepted,P,{ok,P0}} when is_port(P0) ->
- ok;
- {accepted,P,Other0} ->
- {error,Other0}
- after 500 ->
- {error,timeout}
- end.
+ {ok,LS}=gen_tcp:listen(0,[]),
+ {ok,PortNo}=inet:port(LS),
+ Parent = self(),
+ F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
+ P = spawn(F),
+ gen_tcp:connect("localhost",PortNo,[]),
+ receive
+ {accepted,P,{ok,P0}} when is_port(P0) ->
+ ok;
+ {accepted,P,Other0} ->
+ {error,Other0}
+ after 500 ->
+ {error,timeout}
+ end.
multi_accept_close_listen(suite) ->
@@ -1726,111 +2032,175 @@ multi_accept_close_listen(suite) ->
multi_accept_close_listen(doc) ->
["Closing listen socket when multi-accepting"];
multi_accept_close_listen(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
- ?line spawn(F),
- ?line spawn(F),
- ?line spawn(F),
- ?line spawn(F),
- ?line gen_tcp:close(LS),
- ?line ?EXPECT_ACCEPTS([{_,{error,closed}},{_,{error,closed}},
- {_,{error,closed}},{_,{error,closed}}], 500).
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
+ spawn(F),
+ spawn(F),
+ spawn(F),
+ spawn(F),
+ gen_tcp:close(LS),
+ ok = ?EXPECT_ACCEPTS([{_,{error,closed}},{_,{error,closed}},
+ {_,{error,closed}},{_,{error,closed}}],4,500).
accept_timeout(suite) ->
[];
accept_timeout(doc) ->
["Single accept with timeout"];
accept_timeout(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS,1000)} end,
- ?line P = spawn(F),
- ?line ?EXPECT_ACCEPTS([{P,{error,timeout}}],2000).
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS,1000)} end,
+ P = spawn(F),
+ ok = ?EXPECT_ACCEPTS([{P,{error,timeout}}],1,2000).
accept_timeouts_in_order(suite) ->
[];
accept_timeouts_in_order(doc) ->
["Check that multi-accept timeouts happen in the correct order"];
accept_timeouts_in_order(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line P1 = spawn(mktmofun(1000,Parent,LS)),
- ?line P2 = spawn(mktmofun(1200,Parent,LS)),
- ?line P3 = spawn(mktmofun(1300,Parent,LS)),
- ?line P4 = spawn(mktmofun(1400,Parent,LS)),
- ?line ?EXPECT_ACCEPTS([{P1,{error,timeout}},{P2,{error,timeout}},
- {P3,{error,timeout}},{P4,{error,timeout}}], 2000).
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(1000,Parent,LS)),
+ P2 = spawn(mktmofun(1200,Parent,LS)),
+ P3 = spawn(mktmofun(1300,Parent,LS)),
+ P4 = spawn(mktmofun(1400,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P1,{error,timeout}},{P2,{error,timeout}},
+ {P3,{error,timeout}},{P4,{error,timeout}}],infinity,2000).
accept_timeouts_in_order2(suite) ->
[];
accept_timeouts_in_order2(doc) ->
["Check that multi-accept timeouts happen in the correct order (more)"];
accept_timeouts_in_order2(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line P1 = spawn(mktmofun(1400,Parent,LS)),
- ?line P2 = spawn(mktmofun(1300,Parent,LS)),
- ?line P3 = spawn(mktmofun(1200,Parent,LS)),
- ?line P4 = spawn(mktmofun(1000,Parent,LS)),
- ?line ?EXPECT_ACCEPTS([{P4,{error,timeout}},{P3,{error,timeout}},
- {P2,{error,timeout}},{P1,{error,timeout}}], 2000).
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(1400,Parent,LS)),
+ P2 = spawn(mktmofun(1300,Parent,LS)),
+ P3 = spawn(mktmofun(1200,Parent,LS)),
+ P4 = spawn(mktmofun(1000,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P4,{error,timeout}},{P3,{error,timeout}},
+ {P2,{error,timeout}},{P1,{error,timeout}}],infinity,2000).
accept_timeouts_in_order3(suite) ->
[];
accept_timeouts_in_order3(doc) ->
["Check that multi-accept timeouts happen in the correct order (even more)"];
accept_timeouts_in_order3(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line P1 = spawn(mktmofun(1200,Parent,LS)),
- ?line P2 = spawn(mktmofun(1400,Parent,LS)),
- ?line P3 = spawn(mktmofun(1300,Parent,LS)),
- ?line P4 = spawn(mktmofun(1000,Parent,LS)),
- ?line ?EXPECT_ACCEPTS([{P4,{error,timeout}},{P1,{error,timeout}},
- {P3,{error,timeout}},{P2,{error,timeout}}], 2000).
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(1200,Parent,LS)),
+ P2 = spawn(mktmofun(1400,Parent,LS)),
+ P3 = spawn(mktmofun(1300,Parent,LS)),
+ P4 = spawn(mktmofun(1000,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P4,{error,timeout}},{P1,{error,timeout}},
+ {P3,{error,timeout}},{P2,{error,timeout}}],infinity,2000).
+
+accept_timeouts_in_order4(suite) ->
+ [];
+accept_timeouts_in_order4(doc) ->
+ ["Check that multi-accept timeouts happen in the correct order after "
+ "mixing millsec and sec timeouts"];
+accept_timeouts_in_order4(Config) when is_list(Config) ->
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(200,Parent,LS)),
+ P2 = spawn(mktmofun(400,Parent,LS)),
+ P3 = spawn(mktmofun(1000,Parent,LS)),
+ P4 = spawn(mktmofun(600,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P1,{error,timeout}},{P2,{error,timeout}},
+ {P4,{error,timeout}},{P3,{error,timeout}}],infinity,2000).
+
+accept_timeouts_in_order5(suite) ->
+ [];
+accept_timeouts_in_order5(doc) ->
+ ["Check that multi-accept timeouts happen in the correct order after "
+ "mixing millsec and sec timeouts (more)"];
+accept_timeouts_in_order5(Config) when is_list(Config) ->
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(400,Parent,LS)),
+ P2 = spawn(mktmofun(1000,Parent,LS)),
+ P3 = spawn(mktmofun(600,Parent,LS)),
+ P4 = spawn(mktmofun(200,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P4,{error,timeout}},{P1,{error,timeout}},
+ {P3,{error,timeout}},{P2,{error,timeout}}],infinity,2000).
+
+accept_timeouts_in_order6(suite) ->
+ [];
+accept_timeouts_in_order6(doc) ->
+ ["Check that multi-accept timeouts happen in the correct order after "
+ "mixing millsec and sec timeouts (even more)"];
+accept_timeouts_in_order6(Config) when is_list(Config) ->
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(1000,Parent,LS)),
+ P2 = spawn(mktmofun(400,Parent,LS)),
+ P3 = spawn(mktmofun(600,Parent,LS)),
+ P4 = spawn(mktmofun(200,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P4,{error,timeout}},{P2,{error,timeout}},
+ {P3,{error,timeout}},{P1,{error,timeout}}],infinity,2000).
+
+accept_timeouts_in_order7(suite) ->
+ [];
+accept_timeouts_in_order7(doc) ->
+ ["Check that multi-accept timeouts happen in the correct order after "
+ "mixing millsec and sec timeouts (even more++)"];
+accept_timeouts_in_order7(Config) when is_list(Config) ->
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ P1 = spawn(mktmofun(1000,Parent,LS)),
+ P2 = spawn(mktmofun(200,Parent,LS)),
+ P3 = spawn(mktmofun(1200,Parent,LS)),
+ P4 = spawn(mktmofun(600,Parent,LS)),
+ P5 = spawn(mktmofun(400,Parent,LS)),
+ P6 = spawn(mktmofun(800,Parent,LS)),
+ P7 = spawn(mktmofun(1600,Parent,LS)),
+ P8 = spawn(mktmofun(1400,Parent,LS)),
+ ok = ?EXPECT_ACCEPTS([{P2,{error,timeout}},{P5,{error,timeout}},
+ {P4,{error,timeout}},{P6,{error,timeout}},
+ {P1,{error,timeout}},{P3,{error,timeout}},
+ {P8,{error,timeout}},{P7,{error,timeout}}],infinity,2000).
accept_timeouts_mixed(suite) ->
[];
accept_timeouts_mixed(doc) ->
["Check that multi-accept timeouts behave correctly when mixed with successful timeouts"];
accept_timeouts_mixed(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line {ok,PortNo}=inet:port(LS),
- ?line P1 = spawn(mktmofun(1000,Parent,LS)),
- ?line wait_until_accepting(P1,500),
- ?line P2 = spawn(mktmofun(2000,Parent,LS)),
- ?line wait_until_accepting(P2,500),
- ?line P3 = spawn(mktmofun(3000,Parent,LS)),
- ?line wait_until_accepting(P3,500),
- ?line P4 = spawn(mktmofun(4000,Parent,LS)),
- ?line wait_until_accepting(P4,500),
- ?line ok = ?EXPECT_ACCEPTS([{P1,{error,timeout}}],1500),
- ?line {ok,_}=gen_tcp:connect("localhost",PortNo,[]),
- ?line ok = ?EXPECT_ACCEPTS([{P2,{ok,Port0}}] when is_port(Port0),100),
- ?line ok = ?EXPECT_ACCEPTS([{P3,{error,timeout}}],2000),
- ?line gen_tcp:connect("localhost",PortNo,[]),
- ?line ?EXPECT_ACCEPTS([{P4,{ok,Port1}}] when is_port(Port1),100).
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ {ok,PortNo}=inet:port(LS),
+ P1 = spawn(mktmofun(1000,Parent,LS)),
+ wait_until_accepting(P1,500),
+ P2 = spawn(mktmofun(2000,Parent,LS)),
+ wait_until_accepting(P2,500),
+ P3 = spawn(mktmofun(3000,Parent,LS)),
+ wait_until_accepting(P3,500),
+ P4 = spawn(mktmofun(4000,Parent,LS)),
+ wait_until_accepting(P4,500),
+ ok = ?EXPECT_ACCEPTS([{P1,{error,timeout}}],infinity,1500),
+ {ok,_}=gen_tcp:connect("localhost",PortNo,[]),
+ ok = ?EXPECT_ACCEPTS([{P2,{ok,Port0}}] when is_port(Port0),infinity,100),
+ ok = ?EXPECT_ACCEPTS([{P3,{error,timeout}}],infinity,2000),
+ gen_tcp:connect("localhost",PortNo,[]),
+ ok = ?EXPECT_ACCEPTS([{P4,{ok,Port1}}] when is_port(Port1),infinity,100).
killing_acceptor(suite) ->
[];
killing_acceptor(doc) ->
["Check that single acceptor behaves as expected when killed"];
killing_acceptor(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Pid = spawn(fun() -> erlang:display({accepted,self(),gen_tcp:accept(LS)}) end),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L1} = prim_inet:getstatus(LS),
- ?line true = lists:member(accepting, L1),
- ?line exit(Pid,kill),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L2} = prim_inet:getstatus(LS),
- ?line false = lists:member(accepting, L2),
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Pid = spawn(fun() -> erlang:display({accepted,self(),gen_tcp:accept(LS)}) end),
+ receive after 100 -> ok
+ end,
+ {ok,L1} = prim_inet:getstatus(LS),
+ true = lists:member(accepting, L1),
+ exit(Pid,kill),
+ receive after 100 -> ok
+ end,
+ {ok,L2} = prim_inet:getstatus(LS),
+ false = lists:member(accepting, L2),
ok.
killing_multi_acceptors(suite) ->
@@ -1838,26 +2208,24 @@ killing_multi_acceptors(suite) ->
killing_multi_acceptors(doc) ->
["Check that multi acceptors behaves as expected when killed"];
killing_multi_acceptors(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
- ?line F2 = mktmofun(1000,Parent,LS),
- ?line Pid = spawn(F),
- ?line Pid2 = spawn(F2),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L1} = prim_inet:getstatus(LS),
- ?line true = lists:member(accepting, L1),
- ?line exit(Pid,kill),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L2} = prim_inet:getstatus(LS),
- ?line true = lists:member(accepting, L2),
- ?line ok = ?EXPECT_ACCEPTS([{Pid2,{error,timeout}}],1000),
- ?line {ok,L3} = prim_inet:getstatus(LS),
- ?line false = lists:member(accepting, L3),
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
+ F2 = mktmofun(1000,Parent,LS),
+ Pid = spawn(F),
+ Pid2 = spawn(F2),
+ receive after 100 -> ok
+ end,
+ {ok,L1} = prim_inet:getstatus(LS),
+ true = lists:member(accepting, L1),
+ exit(Pid,kill),
+ receive after 100 -> ok
+ end,
+ {ok,L2} = prim_inet:getstatus(LS),
+ true = lists:member(accepting, L2),
+ ok = ?EXPECT_ACCEPTS([{Pid2,{error,timeout}}],1,1000),
+ {ok,L3} = prim_inet:getstatus(LS),
+ false = lists:member(accepting, L3),
ok.
killing_multi_acceptors2(suite) ->
@@ -1865,40 +2233,36 @@ killing_multi_acceptors2(suite) ->
killing_multi_acceptors2(doc) ->
["Check that multi acceptors behaves as expected when killed (more)"];
killing_multi_acceptors2(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line {ok,PortNo}=inet:port(LS),
- ?line F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
- ?line F2 = mktmofun(1000,Parent,LS),
- ?line Pid = spawn(F),
- ?line Pid2 = spawn(F),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L1} = prim_inet:getstatus(LS),
- ?line true = lists:member(accepting, L1),
- ?line exit(Pid,kill),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L2} = prim_inet:getstatus(LS),
- ?line true = lists:member(accepting, L2),
- ?line exit(Pid2,kill),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L3} = prim_inet:getstatus(LS),
- ?line false = lists:member(accepting, L3),
- ?line Pid3 = spawn(F2),
- ?line receive after 100 ->
- ok
- end,
- ?line {ok,L4} = prim_inet:getstatus(LS),
- ?line true = lists:member(accepting, L4),
- ?line gen_tcp:connect("localhost",PortNo,[]),
- ?line ok = ?EXPECT_ACCEPTS([{Pid3,{ok,Port}}] when is_port(Port),100),
- ?line {ok,L5} = prim_inet:getstatus(LS),
- ?line false = lists:member(accepting, L5),
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ {ok,PortNo}=inet:port(LS),
+ F = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
+ F2 = mktmofun(1000,Parent,LS),
+ Pid = spawn(F),
+ Pid2 = spawn(F),
+ receive after 100 -> ok
+ end,
+ {ok,L1} = prim_inet:getstatus(LS),
+ true = lists:member(accepting, L1),
+ exit(Pid,kill),
+ receive after 100 -> ok
+ end,
+ {ok,L2} = prim_inet:getstatus(LS),
+ true = lists:member(accepting, L2),
+ exit(Pid2,kill),
+ receive after 100 -> ok
+ end,
+ {ok,L3} = prim_inet:getstatus(LS),
+ false = lists:member(accepting, L3),
+ Pid3 = spawn(F2),
+ receive after 100 -> ok
+ end,
+ {ok,L4} = prim_inet:getstatus(LS),
+ true = lists:member(accepting, L4),
+ gen_tcp:connect("localhost",PortNo,[]),
+ ok = ?EXPECT_ACCEPTS([{Pid3,{ok,Port}}] when is_port(Port),1,100),
+ {ok,L5} = prim_inet:getstatus(LS),
+ false = lists:member(accepting, L5),
ok.
several_accepts_in_one_go(suite) ->
@@ -1907,33 +2271,19 @@ several_accepts_in_one_go(doc) ->
["checks that multi-accept works when more than one accept can be "
"done at once (wb test of inet_driver)"];
several_accepts_in_one_go(Config) when is_list(Config) ->
- ?line {ok,LS}=gen_tcp:listen(0,[]),
- ?line Parent = self(),
- ?line {ok,PortNo}=inet:port(LS),
- ?line F1 = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
- ?line F2 = fun() -> Parent ! {connected,self(),gen_tcp:connect("localhost",PortNo,[])} end,
- ?line spawn(F1),
- ?line spawn(F1),
- ?line spawn(F1),
- ?line spawn(F1),
- ?line spawn(F1),
- ?line spawn(F1),
- ?line spawn(F1),
- ?line spawn(F1),
- ?line ok = ?EXPECT_ACCEPTS([],500),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line spawn(F2),
- ?line ok = ?EXPECT_ACCEPTS([{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}}],15000),
- ?line ok = ?EXPECT_CONNECTS([{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}}],1000),
+ {ok,LS}=gen_tcp:listen(0,[]),
+ Parent = self(),
+ {ok,PortNo}=inet:port(LS),
+ F1 = fun() -> Parent ! {accepted,self(),gen_tcp:accept(LS)} end,
+ F2 = fun() -> Parent ! {connected,self(),gen_tcp:connect("localhost",PortNo,[])} end,
+ Ns = lists:seq(1,8),
+ _ = [spawn(F1) || _ <- Ns],
+ ok = ?EXPECT_ACCEPTS([],1,500), % wait for tmo
+ _ = [spawn(F2) || _ <- Ns],
+ ok = ?EXPECT_ACCEPTS([{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}}],8,15000),
+ ok = ?EXPECT_CONNECTS([{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}},{_,{ok,_}}],1000),
ok.
-
flush(Msgs) ->
erlang:yield(),
receive Msg -> flush([Msg|Msgs])
@@ -1968,13 +2318,13 @@ accept_system_limit(doc) ->
["Check that accept returns {error, system_limit} "
"(and not {error, enfile}) when running out of ports"];
accept_system_limit(Config) when is_list(Config) ->
- ?line {ok, LS} = gen_tcp:listen(0, []),
- ?line {ok, TcpPort} = inet:port(LS),
+ {ok, LS} = gen_tcp:listen(0, []),
+ {ok, TcpPort} = inet:port(LS),
Me = self(),
- ?line Connector = spawn_link(fun () -> connector(TcpPort, Me) end),
+ Connector = spawn_link(fun () -> connector(TcpPort, Me) end),
receive {Connector, sync} -> Connector ! {self(), continue} end,
- ?line ok = acceptor(LS, false, []),
- ?line Connector ! stop,
+ ok = acceptor(LS, false, []),
+ Connector ! stop,
ok.
acceptor(LS, GotSL, A) ->
@@ -2021,49 +2371,49 @@ active_once_closed(doc) ->
["Check that active once and tcp_close messages behave as expected"];
active_once_closed(Config) when is_list(Config) ->
(fun() ->
- ?line {Loop,A} = setup_closed_ao(),
- ?line Loop({{error,closed},{error,econnaborted}},
+ {Loop,A} = setup_closed_ao(),
+ Loop({{error,closed},{error,econnaborted}},
fun() -> gen_tcp:send(A,"Hello") end),
- ?line ok = inet:setopts(A,[{active,once}]),
- ?line ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
- ?line {error,einval} = inet:setopts(A,[{active,once}]),
- ?line ok = receive {tcp_closed, A} -> error after 1000 -> ok end
+ ok = inet:setopts(A,[{active,once}]),
+ ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
+ {error,einval} = inet:setopts(A,[{active,once}]),
+ ok = receive {tcp_closed, A} -> error after 1000 -> ok end
end)(),
(fun() ->
- ?line {Loop,A} = setup_closed_ao(),
- ?line Loop({{error,closed},{error,econnaborted}},
+ {Loop,A} = setup_closed_ao(),
+ Loop({{error,closed},{error,econnaborted}},
fun() -> gen_tcp:send(A,"Hello") end),
- ?line ok = inet:setopts(A,[{active,true}]),
- ?line ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
- ?line {error,einval} = inet:setopts(A,[{active,true}]),
- ?line ok = receive {tcp_closed, A} -> error after 1000 -> ok end
+ ok = inet:setopts(A,[{active,true}]),
+ ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
+ {error,einval} = inet:setopts(A,[{active,true}]),
+ ok = receive {tcp_closed, A} -> error after 1000 -> ok end
end)(),
(fun() ->
- ?line {Loop,A} = setup_closed_ao(),
- ?line Loop({{error,closed},{error,econnaborted}},
+ {Loop,A} = setup_closed_ao(),
+ Loop({{error,closed},{error,econnaborted}},
fun() -> gen_tcp:send(A,"Hello") end),
- ?line ok = inet:setopts(A,[{active,true}]),
- ?line ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
- ?line {error,einval} = inet:setopts(A,[{active,once}]),
- ?line ok = receive {tcp_closed, A} -> error after 1000 -> ok end
+ ok = inet:setopts(A,[{active,true}]),
+ ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
+ {error,einval} = inet:setopts(A,[{active,once}]),
+ ok = receive {tcp_closed, A} -> error after 1000 -> ok end
end)(),
(fun() ->
- ?line {Loop,A} = setup_closed_ao(),
- ?line Loop({{error,closed},{error,econnaborted}},
+ {Loop,A} = setup_closed_ao(),
+ Loop({{error,closed},{error,econnaborted}},
fun() -> gen_tcp:send(A,"Hello") end),
- ?line ok = inet:setopts(A,[{active,once}]),
- ?line ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
- ?line {error,einval} = inet:setopts(A,[{active,true}]),
- ?line ok = receive {tcp_closed, A} -> error after 1000 -> ok end
+ ok = inet:setopts(A,[{active,once}]),
+ ok = receive {tcp_closed, A} -> ok after 1000 -> error end,
+ {error,einval} = inet:setopts(A,[{active,true}]),
+ ok = receive {tcp_closed, A} -> error after 1000 -> ok end
end)(),
(fun() ->
- ?line {Loop,A} = setup_closed_ao(),
- ?line Loop({{error,closed},{error,econnaborted}},
+ {Loop,A} = setup_closed_ao(),
+ Loop({{error,closed},{error,econnaborted}},
fun() -> gen_tcp:send(A,"Hello") end),
- ?line ok = inet:setopts(A,[{active,false}]),
- ?line ok = receive {tcp_closed, A} -> error after 1000 -> ok end,
- ?line ok = inet:setopts(A,[{active,once}]),
- ?line ok = receive {tcp_closed, A} -> ok after 1000 -> error end
+ ok = inet:setopts(A,[{active,false}]),
+ ok = receive {tcp_closed, A} -> error after 1000 -> ok end,
+ ok = inet:setopts(A,[{active,once}]),
+ ok = receive {tcp_closed, A} -> ok after 1000 -> error end
end)().
send_timeout(suite) ->
@@ -2072,10 +2422,10 @@ send_timeout(doc) ->
["Test the send_timeout socket option"];
send_timeout(Config) when is_list(Config) ->
%% Basic
- BasicFun =
+ BasicFun =
fun(AutoClose) ->
- ?line {Loop,A,RNode} = setup_timeout_sink(1000, AutoClose),
- ?line {error,timeout} =
+ {Loop,A,RNode} = setup_timeout_sink(1000, AutoClose),
+ {error,timeout} =
Loop(fun() ->
Res = gen_tcp:send(A,<<1:10000>>),
%%erlang:display(Res),
@@ -2083,64 +2433,63 @@ send_timeout(Config) when is_list(Config) ->
end),
%% Check that the socket is not busy/closed...
Error = after_send_timeout(AutoClose),
- ?line {error,Error} = gen_tcp:send(A,<<"Hej">>),
- ?line test_server:stop_node(RNode)
+ {error,Error} = gen_tcp:send(A,<<"Hej">>),
+ test_server:stop_node(RNode)
end,
BasicFun(false),
BasicFun(true),
%% Check timeout length
- ?line Self = self(),
- ?line Pid =
- spawn(fun() ->
- {Loop,A,RNode} = setup_timeout_sink(1000, true),
- {error,timeout} =
- Loop(fun() ->
- Res = gen_tcp:send(A,<<1:10000>>),
- %%erlang:display(Res),
- Self ! Res,
- Res
- end),
- test_server:stop_node(RNode)
- end),
- ?line Diff = get_max_diff(),
- ?line io:format("Max time for send: ~p~n",[Diff]),
- ?line true = (Diff > 500) and (Diff < 1500),
+ Self = self(),
+ Pid = spawn(fun() ->
+ {Loop,A,RNode} = setup_timeout_sink(1000, true),
+ {error,timeout} = Loop(fun() ->
+ Res = gen_tcp:send(A,<<1:10000>>),
+ %%erlang:display(Res),
+ Self ! Res,
+ Res
+ end),
+ test_server:stop_node(RNode)
+ end),
+ Diff = get_max_diff(),
+ io:format("Max time for send: ~p~n",[Diff]),
+ true = (Diff > 500) and (Diff < 1500),
%% Let test_server slave die...
- ?line Mon = erlang:monitor(process, Pid),
- ?line receive {'DOWN',Mon,process,Pid,_} -> ok end,
+ Mon = erlang:monitor(process, Pid),
+ receive {'DOWN',Mon,process,Pid,_} -> ok end,
%% Check that parallell writers do not hang forever
- ParaFun =
+ ParaFun =
fun(AutoClose) ->
- ?line {Loop,A,RNode} = setup_timeout_sink(1000, AutoClose),
+ {Loop,A,RNode} = setup_timeout_sink(1000, AutoClose),
SenderFun = fun() ->
- {error,Error} =
+ {error,Error} =
Loop(fun() ->
gen_tcp:send(A, <<1:10000>>)
end),
Self ! {error,Error}
end,
- ?line spawn_link(SenderFun),
- ?line spawn_link(SenderFun),
- ?line receive
- {error,timeout} -> ok
- after 10000 ->
- ?line exit(timeout)
- end,
+ spawn_link(SenderFun),
+ spawn_link(SenderFun),
+ receive
+ {error,timeout} -> ok
+ after 10000 ->
+ exit(timeout)
+ end,
NextErr = after_send_timeout(AutoClose),
- ?line receive
- {error,NextErr} -> ok
- after 10000 ->
- ?line exit(timeout)
- end,
- ?line {error,NextErr} = gen_tcp:send(A,<<"Hej">>),
- ?line test_server:stop_node(RNode)
+ receive
+ {error,NextErr} -> ok
+ after 10000 ->
+ exit(timeout)
+ end,
+ {error,NextErr} = gen_tcp:send(A,<<"Hej">>),
+ test_server:stop_node(RNode)
end,
ParaFun(false),
ParaFun(true),
ok.
+
mad_sender(S) ->
- {_, _, USec} = now(),
- case gen_tcp:send(S, integer_to_list(USec)) of
+ U = rand:uniform(1000000),
+ case gen_tcp:send(S, integer_to_list(U)) of
ok ->
mad_sender(S);
Err ->
@@ -2166,25 +2515,25 @@ send_timeout_active(Config) when is_list(Config) ->
%% Basic
BasicFun =
fun(AutoClose) ->
- ?line {Loop,A,RNode,C} = setup_active_timeout_sink(1, AutoClose),
+ {Loop,A,RNode,C} = setup_active_timeout_sink(1, AutoClose),
inet:setopts(A, [{active, once}]),
- ?line Mad = spawn_link(RNode,fun() -> mad_sender(C) end),
- ?line {error,timeout} =
- Loop(fun() ->
- receive
- {tcp, _Sock, _Data} ->
- inet:setopts(A, [{active, once}]),
- Res = gen_tcp:send(A,lists:duplicate(1000, $a)),
- %erlang:display(Res),
- Res;
- Err ->
- io:format("sock closed: ~p~n", [Err]),
- Err
- end
- end),
- unlink(Mad),
+ Mad = spawn_link(RNode,fun() -> mad_sender(C) end),
+ {error,timeout} =
+ Loop(fun() ->
+ receive
+ {tcp, _Sock, _Data} ->
+ inet:setopts(A, [{active, once}]),
+ Res = gen_tcp:send(A,lists:duplicate(1000, $a)),
+ %erlang:display(Res),
+ Res;
+ Err ->
+ io:format("sock closed: ~p~n", [Err]),
+ Err
+ end
+ end),
+ unlink(Mad),
exit(Mad,kill),
- ?line test_server:stop_node(RNode)
+ test_server:stop_node(RNode)
end,
BasicFun(false),
flush(),
@@ -2208,10 +2557,10 @@ get_max_diff() ->
end.
get_max_diff(Max) ->
- T1 = millistamp(),
+ T1 = millis(),
receive
ok ->
- Diff = millistamp() - T1,
+ Diff = millis() - T1,
if
Diff > Max ->
get_max_diff(Diff);
@@ -2219,7 +2568,7 @@ get_max_diff(Max) ->
get_max_diff(Max)
end;
{error,timeout} ->
- Diff = millistamp() - T1,
+ Diff = millis() - T1,
if
Diff > Max ->
Diff;
@@ -2227,29 +2576,29 @@ get_max_diff(Max) ->
Max
end
after 10000 ->
- exit(timeout)
+ exit(timeout)
end.
setup_closed_ao() ->
Dir = filename:dirname(code:which(?MODULE)),
{ok,R} = test_server:start_node(test_default_options_slave,slave,
- [{args,"-pa " ++ Dir}]),
+ [{args,"-pa " ++ Dir}]),
Host = list_to_atom(lists:nth(2,string:tokens(atom_to_list(node()),"@"))),
{ok, L} = gen_tcp:listen(0, [{active,false},{packet,2}]),
- Fun = fun(F) ->
- receive
- {From,X} when is_function(X) ->
- From ! {self(),X()}, F(F);
- die -> ok
- end
- end,
+ Fun = fun(F) ->
+ receive
+ {From,X} when is_function(X) ->
+ From ! {self(),X()}, F(F);
+ die -> ok
+ end
+ end,
Pid = rpc:call(R,erlang,spawn,[fun() -> Fun(Fun) end]),
{ok, Port} = inet:port(L),
- Remote = fun(Fu) ->
- Pid ! {self(), Fu},
- receive {Pid,X} -> X
- end
- end,
+ Remote = fun(Fu) ->
+ Pid ! {self(), Fu},
+ receive {Pid,X} -> X
+ end
+ end,
{ok, C} = Remote(fun() ->
gen_tcp:connect(Host,Port,
[{active,false},{packet,2}])
@@ -2257,113 +2606,109 @@ setup_closed_ao() ->
{ok,A} = gen_tcp:accept(L),
gen_tcp:send(A,"Hello"),
{ok, "Hello"} = Remote(fun() -> gen_tcp:recv(C,0) end),
- ok = Remote(fun() -> gen_tcp:close(C) end),
- Loop2 = fun(_,_,_,0) ->
+ ok = Remote(fun() -> gen_tcp:close(C) end),
+ Loop2 = fun(_,_,_,0) ->
{failure, timeout};
- (L2,{MA,MB},F2,N) ->
- case F2() of
- MA -> MA;
- MB -> MB;
- Other -> io:format("~p~n",[Other]),
- receive after 1000 -> ok end,
- L2(L2,{MA,MB},F2,N-1)
- end
+ (L2,{MA,MB},F2,N) ->
+ case F2() of
+ MA -> MA;
+ MB -> MB;
+ Other -> io:format("~p~n",[Other]),
+ receive after 1000 -> ok end,
+ L2(L2,{MA,MB},F2,N-1)
+ end
end,
Loop = fun(Match2,F3) -> Loop2(Loop2,Match2,F3,10) end,
test_server:stop_node(R),
{Loop,A}.
setup_timeout_sink(Timeout, AutoClose) ->
- ?line Dir = filename:dirname(code:which(?MODULE)),
- ?line {ok,R} = test_server:start_node(test_default_options_slave,slave,
- [{args,"-pa " ++ Dir}]),
- ?line Host = list_to_atom(lists:nth(2,string:tokens(atom_to_list(node()),"@"))),
- ?line {ok, L} = gen_tcp:listen(0, [{active,false},{packet,2},
+ Dir = filename:dirname(code:which(?MODULE)),
+ {ok,R} = test_server:start_node(test_default_options_slave,slave,
+ [{args,"-pa " ++ Dir}]),
+ Host = list_to_atom(lists:nth(2,string:tokens(atom_to_list(node()),"@"))),
+ {ok, L} = gen_tcp:listen(0, [{active,false},{packet,2},
{send_timeout,Timeout},
{send_timeout_close,AutoClose}]),
- ?line Fun = fun(F) ->
- receive
- {From,X} when is_function(X) ->
- From ! {self(),X()}, F(F);
- die -> ok
- end
- end,
- ?line Pid = rpc:call(R,erlang,spawn,[fun() -> Fun(Fun) end]),
- ?line {ok, Port} = inet:port(L),
- ?line Remote = fun(Fu) ->
- Pid ! {self(), Fu},
- receive {Pid,X} -> X
- end
+ Fun = fun(F) ->
+ receive
+ {From,X} when is_function(X) ->
+ From ! {self(),X()}, F(F);
+ die -> ok
+ end
+ end,
+ Pid = rpc:call(R,erlang,spawn,[fun() -> Fun(Fun) end]),
+ {ok, Port} = inet:port(L),
+ Remote = fun(Fu) ->
+ Pid ! {self(), Fu},
+ receive {Pid,X} -> X
+ end
end,
- ?line {ok, C} = Remote(fun() ->
+ {ok, C} = Remote(fun() ->
gen_tcp:connect(Host,Port,
- [{active,false},{packet,2}])
+ [{active,false},{packet,2}])
end),
- ?line {ok,A} = gen_tcp:accept(L),
- ?line gen_tcp:send(A,"Hello"),
- ?line {ok, "Hello"} = Remote(fun() -> gen_tcp:recv(C,0) end),
- ?line Loop2 = fun(_,_,0) ->
- {failure, timeout};
- (L2,F2,N) ->
+ {ok,A} = gen_tcp:accept(L),
+ gen_tcp:send(A,"Hello"),
+ {ok, "Hello"} = Remote(fun() -> gen_tcp:recv(C,0) end),
+ Loop2 = fun(_,_,0) ->
+ {failure, timeout};
+ (L2,F2,N) ->
Ret = F2(),
io:format("~p~n",[Ret]),
case Ret of
- ok -> receive after 1 -> ok end,
+ ok -> receive after 1 -> ok end,
L2(L2,F2,N-1);
Other -> Other
- end
+ end
end,
- ?line Loop = fun(F3) -> Loop2(Loop2,F3,1000) end,
+ Loop = fun(F3) -> Loop2(Loop2,F3,1000) end,
{Loop,A,R}.
setup_active_timeout_sink(Timeout, AutoClose) ->
- ?line Dir = filename:dirname(code:which(?MODULE)),
- ?line {ok,R} = test_server:start_node(test_default_options_slave,slave,
- [{args,"-pa " ++ Dir}]),
- ?line Host = list_to_atom(lists:nth(2,string:tokens(atom_to_list(node()),"@"))),
- ?line {ok, L} = gen_tcp:listen(0, [binary,{active,false},{packet,0},{nodelay, true},{keepalive, true},
+ Dir = filename:dirname(code:which(?MODULE)),
+ {ok,R} = test_server:start_node(test_default_options_slave,slave,
+ [{args,"-pa " ++ Dir}]),
+ Host = list_to_atom(lists:nth(2,string:tokens(atom_to_list(node()),"@"))),
+ {ok, L} = gen_tcp:listen(0, [binary,{active,false},{packet,0},{nodelay, true},{keepalive, true},
{send_timeout,Timeout},
{send_timeout_close,AutoClose}]),
- ?line Fun = fun(F) ->
- receive
- {From,X} when is_function(X) ->
- From ! {self(),X()}, F(F);
- die -> ok
- end
- end,
- ?line Pid = rpc:call(R,erlang,spawn,[fun() -> Fun(Fun) end]),
- ?line {ok, Port} = inet:port(L),
- ?line Remote = fun(Fu) ->
- Pid ! {self(), Fu},
- receive {Pid,X} -> X
- end
+ Fun = fun(F) ->
+ receive
+ {From,X} when is_function(X) ->
+ From ! {self(),X()}, F(F);
+ die -> ok
+ end
+ end,
+ Pid = rpc:call(R,erlang,spawn,[fun() -> Fun(Fun) end]),
+ {ok, Port} = inet:port(L),
+ Remote = fun(Fu) ->
+ Pid ! {self(), Fu},
+ receive {Pid,X} -> X
+ end
end,
- ?line {ok, C} = Remote(fun() ->
+ {ok, C} = Remote(fun() ->
gen_tcp:connect(Host,Port,
- [{active,false}])
+ [{active,false}])
end),
- ?line {ok,A} = gen_tcp:accept(L),
- ?line gen_tcp:send(A,"Hello"),
- ?line {ok, "H"++_} = Remote(fun() -> gen_tcp:recv(C,0) end),
- ?line Loop2 = fun(_,_,0) ->
- {failure, timeout};
- (L2,F2,N) ->
+ {ok,A} = gen_tcp:accept(L),
+ gen_tcp:send(A,"Hello"),
+ {ok, "H"++_} = Remote(fun() -> gen_tcp:recv(C,0) end),
+ Loop2 = fun(_,_,0) ->
+ {failure, timeout};
+ (L2,F2,N) ->
Ret = F2(),
io:format("~p~n",[Ret]),
case Ret of
- ok -> receive after 1 -> ok end,
+ ok -> receive after 1 -> ok end,
L2(L2,F2,N-1);
Other -> Other
- end
+ end
end,
- ?line Loop = fun(F3) -> Loop2(Loop2,F3,1000) end,
+ Loop = fun(F3) -> Loop2(Loop2,F3,1000) end,
{Loop,A,R,C}.
-millistamp() ->
- {Mega, Secs, Micros} = erlang:now(),
- (Micros div 1000) + Secs * 1000 + Mega * 1000000000.
-
has_superfluous_schedulers() ->
case {erlang:system_info(schedulers),
erlang:system_info(logical_processors)} of
@@ -2378,22 +2723,22 @@ otp_7731(doc) ->
"Leaking message from inet_drv {inet_reply,P,ok} "
"when a socket sending resumes working after a send_timeout";
otp_7731(Config) when is_list(Config) ->
- ?line ServerPid = spawn_link(?MODULE, otp_7731_server, [self()]),
- ?line receive {ServerPid, ready, PortNum} -> ok end,
+ ServerPid = spawn_link(?MODULE, otp_7731_server, [self()]),
+ receive {ServerPid, ready, PortNum} -> ok end,
- ?line {ok, Socket} = gen_tcp:connect("localhost", PortNum,
- [binary, {active, false}, {packet, raw},
- {send_timeout, 1000}]),
+ {ok, Socket} = gen_tcp:connect("localhost", PortNum,
+ [binary, {active, false}, {packet, raw},
+ {send_timeout, 1000}]),
otp_7731_send(Socket),
io:format("Sending complete...\n",[]),
ServerPid ! {self(), recv},
- receive {ServerPid, ok} -> ok end,
-
+ receive {ServerPid, ok} -> ok end,
+
io:format("Client waiting for leaking messages...\n",[]),
%% Now make sure inet_drv does not leak any internal messages.
receive Msg ->
- ?line test_server:fail({unexpected, Msg})
+ test_server:fail({unexpected, Msg})
after 1000 ->
ok
end,
@@ -2403,15 +2748,15 @@ otp_7731(Config) when is_list(Config) ->
otp_7731_send(Socket) ->
Bin = <<1:10000>>,
io:format("Client sending ~p bytes...\n",[size(Bin)]),
- ?line case gen_tcp:send(Socket, Bin) of
- ok -> otp_7731_send(Socket);
- {error,timeout} -> ok
- end.
+ case gen_tcp:send(Socket, Bin) of
+ ok -> otp_7731_send(Socket);
+ {error,timeout} -> ok
+ end.
otp_7731_server(ClientPid) ->
- ?line {ok, LSocket} = gen_tcp:listen(0, [binary, {packet, raw},
- {active, false}]),
- ?line {ok, {_, PortNum}} = inet:sockname(LSocket),
+ {ok, LSocket} = gen_tcp:listen(0, [binary, {packet, raw},
+ {active, false}]),
+ {ok, {_, PortNum}} = inet:sockname(LSocket),
io:format("Listening on ~w with port number ~p\n", [LSocket, PortNum]),
ClientPid ! {self(), ready, PortNum},
@@ -2433,7 +2778,7 @@ otp_7731_server(ClientPid) ->
otp_7731_recv(Socket) ->
- ?line case gen_tcp:recv(Socket, 0, 1000) of
+ case gen_tcp:recv(Socket, 0, 1000) of
{ok, Bin} ->
io:format("Server received ~p bytes\n",[size(Bin)]),
otp_7731_recv(Socket);
@@ -2452,21 +2797,21 @@ zombie_sockets(Config) when is_list(Config) ->
register(zombie_collector,self()),
Calls = 10,
Server = spawn_link(?MODULE, zombie_server,[self(), Calls]),
- ?line {Server, ready, PortNum} = receive Msg -> Msg end,
+ {Server, ready, PortNum} = receive Msg -> Msg end,
io:format("Ports before = ~p\n",[lists:sort(erlang:ports())]),
zombie_client_loop(Calls, PortNum),
Ports = lists:sort(zombie_collector(Calls,[])),
Server ! terminate,
io:format("Collected ports = ~p\n",[Ports]),
- ?line [] = zombies_alive(Ports, 10),
+ [] = zombies_alive(Ports, 10),
timer:sleep(1000),
ok.
zombie_client_loop(0, _) -> ok;
zombie_client_loop(N, PortNum) when is_integer(PortNum) ->
- ?line {ok, Socket} = gen_tcp:connect("localhost", PortNum,
- [binary, {active, false}, {packet, raw}]),
- ?line gen_tcp:close(Socket), % to make server recv fail
+ {ok, Socket} = gen_tcp:connect("localhost", PortNum,
+ [binary, {active, false}, {packet, raw}]),
+ gen_tcp:close(Socket), % to make server recv fail
zombie_client_loop(N-1, PortNum).
@@ -2495,19 +2840,19 @@ zombies_alive(Ports, WaitSec) ->
end.
zombie_server(Pid, Calls) ->
- ?line {ok, LSocket} = gen_tcp:listen(0, [binary, {packet, raw},
- {active, false}, {backlog, Calls}]),
- ?line {ok, {_, PortNum}} = inet:sockname(LSocket),
+ {ok, LSocket} = gen_tcp:listen(0, [binary, {packet, raw},
+ {active, false}, {backlog, Calls}]),
+ {ok, {_, PortNum}} = inet:sockname(LSocket),
io:format("Listening on ~w with port number ~p\n", [LSocket, PortNum]),
BigBin = list_to_binary(lists:duplicate(100*1024, 77)),
Pid ! {self(), ready, PortNum},
zombie_accept_loop(LSocket, BigBin, Calls),
- ?line terminate = receive Msg -> Msg end.
+ terminate = receive Msg -> Msg end.
zombie_accept_loop(_, _, 0) ->
ok;
zombie_accept_loop(Socket, BigBin, Calls) ->
- ?line case gen_tcp:accept(Socket) of
+ case gen_tcp:accept(Socket) of
{ok, NewSocket} ->
spawn_link(fun() -> zombie_serve_client(NewSocket, BigBin) end),
zombie_accept_loop(Socket, BigBin, Calls-1);
@@ -2517,29 +2862,27 @@ zombie_accept_loop(Socket, BigBin, Calls) ->
zombie_serve_client(Socket, Bin) ->
%%io:format("Got connection on ~p\n",[Socket]),
- ?line gen_tcp:send(Socket, Bin),
+ gen_tcp:send(Socket, Bin),
%%io:format("Sent data, waiting for reply on ~p\n",[Socket]),
- ?line case gen_tcp:recv(Socket, 4) of
+ case gen_tcp:recv(Socket, 4) of
{error,closed} -> ok;
{error,econnaborted} -> ok % may be returned on Windows
end,
%%io:format("Closing ~p\n",[Socket]),
- ?line gen_tcp:close(Socket),
+ gen_tcp:close(Socket),
zombie_collector ! {closed, Socket}.
-
-
otp_7816(suite) -> [];
otp_7816(doc) ->
"Hanging send on windows when sending iolist with more than 16 binaries.";
otp_7816(Config) when is_list(Config) ->
Client = self(),
- ?line Server = spawn_link(fun()-> otp_7816_server(Client) end),
- ?line receive {Server, ready, PortNum} -> ok end,
+ Server = spawn_link(fun()-> otp_7816_server(Client) end),
+ receive {Server, ready, PortNum} -> ok end,
- ?line {ok, Socket} = gen_tcp:connect("localhost", PortNum,
- [binary, {active, false}, {packet, 4},
- {send_timeout, 10}]),
+ {ok, Socket} = gen_tcp:connect("localhost", PortNum,
+ [binary, {active, false}, {packet, 4},
+ {send_timeout, 10}]),
%% We use the undocumented feature that sending can be resumed after
%% a send_timeout without any data loss if the peer starts to receive data.
%% Unless of course the 7816-bug is in affect, in which case the write event
@@ -2549,9 +2892,9 @@ otp_7816(Config) when is_list(Config) ->
io:format("Sending complete...\n",[]),
- ?line ok = gen_tcp:close(Socket),
+ ok = gen_tcp:close(Socket),
Server ! {self(), closed},
- ?line {Server, closed} = receive M -> M end.
+ {Server, closed} = receive M -> M end.
otp_7816_send(Socket, BinNr, BinSize, Server) ->
@@ -2559,7 +2902,7 @@ otp_7816_send(Socket, BinNr, BinSize, Server) ->
SentBytes = otp_7816_send_data(Socket, Data, 0) * BinNr * BinSize,
io:format("Client sent ~p bytes...\n",[SentBytes]),
Server ! {self(),recv,SentBytes},
- ?line {Server, ok} = receive M -> M end.
+ {Server, ok} = receive M -> M end.
@@ -2574,15 +2917,15 @@ otp_7816_send_data(Socket, Data, Loops) ->
otp_7816_server(Client) ->
- ?line {ok, LSocket} = gen_tcp:listen(0, [binary, {packet, 4},
+ {ok, LSocket} = gen_tcp:listen(0, [binary, {packet, 4},
{active, false}]),
- ?line {ok, {_, PortNum}} = inet:sockname(LSocket),
+ {ok, {_, PortNum}} = inet:sockname(LSocket),
io:format("Listening on ~w with port number ~p\n", [LSocket, PortNum]),
Client ! {self(), ready, PortNum},
- ?line {ok, CSocket} = gen_tcp:accept(LSocket),
+ {ok, CSocket} = gen_tcp:accept(LSocket),
io:format("Server got connection...\n",[]),
- ?line gen_tcp:close(LSocket),
+ gen_tcp:close(LSocket),
otp_7816_server_loop(CSocket),
@@ -2596,13 +2939,13 @@ otp_7816_server_loop(CSocket) ->
{Client, recv, RecvBytes} ->
io:format("Server start receiving...\n",[]),
- ?line ok = otp_7816_recv(CSocket, RecvBytes),
+ ok = otp_7816_recv(CSocket, RecvBytes),
Client ! {self(), ok},
otp_7816_server_loop(CSocket);
{Client, closed} ->
- ?line {error, closed} = gen_tcp:recv(CSocket, 0, 1000),
+ {error, closed} = gen_tcp:recv(CSocket, 0, 1000),
Client ! {self(), closed}
end.
@@ -2611,7 +2954,7 @@ otp_7816_recv(_, 0) ->
io:format("Server got all.\n",[]),
ok;
otp_7816_recv(CSocket, BytesLeft) ->
- ?line case gen_tcp:recv(CSocket, 0, 1000) of
+ case gen_tcp:recv(CSocket, 0, 1000) of
{ok, Bin} when byte_size(Bin) =< BytesLeft ->
io:format("Server received ~p of ~p bytes.\n",[size(Bin), BytesLeft]),
otp_7816_recv(CSocket, BytesLeft - byte_size(Bin));
@@ -2623,8 +2966,8 @@ otp_7816_recv(CSocket, BytesLeft) ->
otp_8102(doc) -> ["Receive a packet with a faulty packet header"];
otp_8102(suite) -> [];
otp_8102(Config) when is_list(Config) ->
- ?line {ok, LSocket} = gen_tcp:listen(0, []),
- ?line {ok, {_, PortNum}} = inet:sockname(LSocket),
+ {ok, LSocket} = gen_tcp:listen(0, []),
+ {ok, {_, PortNum}} = inet:sockname(LSocket),
io:format("Listening on ~w with port number ~p\n", [LSocket, PortNum]),
[otp_8102_do(LSocket, PortNum, otp_8102_packet(Type,Size))
@@ -2644,18 +2987,18 @@ otp_8102_packet({cdr,little}, Size) ->
otp_8102_do(LSocket, PortNum, {Bin,PType}) ->
io:format("Connect with packet option ~p ...\n",[PType]),
- ?line {ok, RSocket} = gen_tcp:connect("localhost", PortNum, [binary,
+ {ok, RSocket} = gen_tcp:connect("localhost", PortNum, [binary,
{packet,PType},
{active,true}]),
- ?line {ok, SSocket} = gen_tcp:accept(LSocket),
+ {ok, SSocket} = gen_tcp:accept(LSocket),
io:format("Got connection, sending ~p...\n",[Bin]),
- ?line ok = gen_tcp:send(SSocket, Bin),
+ ok = gen_tcp:send(SSocket, Bin),
io:format("Sending complete...\n",[]),
- ?line {tcp_error,RSocket,emsgsize} = receive M -> M end,
+ {tcp_error,RSocket,emsgsize} = receive M -> M end,
io:format("Got error msg, ok.\n",[]),
gen_tcp:close(SSocket),
@@ -2664,61 +3007,61 @@ otp_8102_do(LSocket, PortNum, {Bin,PType}) ->
otp_9389(doc) -> ["Verify packet_size handles long HTTP header lines"];
otp_9389(suite) -> [];
otp_9389(Config) when is_list(Config) ->
- ?line {ok, LS} = gen_tcp:listen(0, [{active,false}]),
- ?line {ok, {_, PortNum}} = inet:sockname(LS),
+ {ok, LS} = gen_tcp:listen(0, [{active,false}]),
+ {ok, {_, PortNum}} = inet:sockname(LS),
io:format("Listening on ~w with port number ~p\n", [LS, PortNum]),
OrigLinkHdr = "/" ++ string:chars($S, 8192),
_Server = spawn_link(
fun() ->
- ?line {ok, S} = gen_tcp:accept(LS),
- ?line ok = inet:setopts(S, [{packet_size, 16384}]),
- ?line ok = otp_9389_loop(S, OrigLinkHdr),
- ?line ok = gen_tcp:close(S)
+ {ok, S} = gen_tcp:accept(LS),
+ ok = inet:setopts(S, [{packet_size, 16384}]),
+ ok = otp_9389_loop(S, OrigLinkHdr),
+ ok = gen_tcp:close(S)
end),
- ?line {ok, S} = gen_tcp:connect("localhost", PortNum,
+ {ok, S} = gen_tcp:connect("localhost", PortNum,
[binary, {active, false}]),
Req = "GET / HTTP/1.1\r\n"
++ "Host: localhost\r\n"
++ "Link: " ++ OrigLinkHdr ++ "\r\n\r\n",
- ?line ok = gen_tcp:send(S, Req),
- ?line ok = inet:setopts(S, [{packet, http}]),
- ?line {ok, {http_response, {1,1}, 200, "OK"}} = gen_tcp:recv(S, 0),
- ?line ok = inet:setopts(S, [{packet, httph}, {packet_size, 16384}]),
- ?line {ok, {http_header, _, 'Content-Length', _, "0"}} = gen_tcp:recv(S, 0),
- ?line {ok, {http_header, _, "Link", _, LinkHdr}} = gen_tcp:recv(S, 0),
- ?line true = (LinkHdr == OrigLinkHdr),
+ ok = gen_tcp:send(S, Req),
+ ok = inet:setopts(S, [{packet, http}]),
+ {ok, {http_response, {1,1}, 200, "OK"}} = gen_tcp:recv(S, 0),
+ ok = inet:setopts(S, [{packet, httph}, {packet_size, 16384}]),
+ {ok, {http_header, _, 'Content-Length', _, "0"}} = gen_tcp:recv(S, 0),
+ {ok, {http_header, _, "Link", _, LinkHdr}} = gen_tcp:recv(S, 0),
+ true = (LinkHdr == OrigLinkHdr),
ok = gen_tcp:close(S),
ok = gen_tcp:close(LS),
ok.
otp_9389_loop(S, OrigLinkHdr) ->
- ?line ok = inet:setopts(S, [{active,once},{packet,http}]),
+ ok = inet:setopts(S, [{active,once},{packet,http}]),
receive
{http, S, {http_request, 'GET', _, _}} ->
- ?line ok = otp_9389_loop(S, OrigLinkHdr, undefined)
+ ok = otp_9389_loop(S, OrigLinkHdr, undefined)
after
3000 ->
- ?line error({timeout,request_line})
+ error({timeout,request_line})
end.
otp_9389_loop(S, OrigLinkHdr, ok) ->
- ?line Resp = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n" ++
+ Resp = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n" ++
"Link: " ++ OrigLinkHdr ++ "\r\n\r\n",
- ?line ok = gen_tcp:send(S, Resp);
+ ok = gen_tcp:send(S, Resp);
otp_9389_loop(S, OrigLinkHdr, State) ->
- ?line ok = inet:setopts(S, [{active,once}, {packet,httph}]),
+ ok = inet:setopts(S, [{active,once}, {packet,httph}]),
receive
{http, S, http_eoh} ->
- ?line otp_9389_loop(S, OrigLinkHdr, ok);
+ otp_9389_loop(S, OrigLinkHdr, ok);
{http, S, {http_header, _, "Link", _, LinkHdr}} ->
- ?line LinkHdr = OrigLinkHdr,
- ?line otp_9389_loop(S, OrigLinkHdr, State);
+ LinkHdr = OrigLinkHdr,
+ otp_9389_loop(S, OrigLinkHdr, State);
{http, S, {http_header, _, _Hdr, _, _Val}} ->
- ?line otp_9389_loop(S, OrigLinkHdr, State);
+ otp_9389_loop(S, OrigLinkHdr, State);
{http, S, {http_error, Err}} ->
- ?line error({error, Err})
+ error({error, Err})
after
3000 ->
- ?line error({timeout,header})
+ error({timeout,header})
end.
wrapping_oct(doc) ->
@@ -2729,7 +3072,7 @@ wrapping_oct(Config) when is_list(Config) ->
{ok,Sock} = gen_tcp:listen(0,[{active,false},{mode,binary}]),
{ok,Port} = inet:port(Sock),
spawn_link(?MODULE,oct_acceptor,[Sock]),
- Res = oct_datapump(Port,16#1FFFFFFFF),
+ Res = oct_datapump(Port,16#10000FFFF),
gen_tcp:close(Sock),
ok = Res,
ok.
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index 8177123332..8d8c953303 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl
index 9428a38660..73ee86eba4 100644
--- a/lib/kernel/test/global_SUITE.erl
+++ b/lib/kernel/test/global_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/global_SUITE_data/global_trace.erl b/lib/kernel/test/global_SUITE_data/global_trace.erl
index 1396d86c79..69d95f610d 100644
--- a/lib/kernel/test/global_SUITE_data/global_trace.erl
+++ b/lib/kernel/test/global_SUITE_data/global_trace.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/global_group_SUITE.erl b/lib/kernel/test/global_group_SUITE.erl
index 799b0d9d05..0a994c3bf0 100644
--- a/lib/kernel/test/global_group_SUITE.erl
+++ b/lib/kernel/test/global_group_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index 35d3b75b34..39cd29cea0 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,6 +27,8 @@
node_start_immediately_after_crash/1,
node_start_soon_after_crash/1,
set_cmd/1, clear_cmd/1, get_cmd/1,
+ callback_api/1,
+ options_api/1,
dont_drop/1, kill_pid/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -65,6 +68,8 @@ all() -> [
node_start_immediately_after_crash,
node_start_soon_after_crash,
set_cmd, clear_cmd, get_cmd,
+ callback_api,
+ options_api,
kill_pid
].
@@ -357,6 +362,69 @@ get_cmd(Config) when is_list(Config) ->
stop_node(Node),
ok.
+callback_api(Config) when is_list(Config) ->
+ {ok, Node} = start_check(slave, heart_test),
+ none = rpc:call(Node, heart, get_callback, []),
+ M0 = self(),
+ F0 = ok,
+ {error, {bad_callback, {M0,F0}}} = rpc:call(Node, heart, set_callback, [M0,F0]),
+ none = rpc:call(Node, heart, get_callback, []),
+ M1 = lists:duplicate(28, $a),
+ F1 = lists:duplicate(28, $b),
+ {error, {bad_callback, {M1,F1}}} = rpc:call(Node, heart, set_callback, [M1,F1]),
+ none = rpc:call(Node, heart, get_callback, []),
+
+ M2 = heart_check_module,
+ F2 = cb_ok,
+ F3 = cb_error,
+ Code0 = generate(M2, [], [
+ atom_to_list(F2) ++ "() -> ok.",
+ atom_to_list(F3) ++ "() -> exit(\"callback_error (as intended)\")."
+ ]),
+ {module, M2} = rpc:call(Node, erlang, load_module, [M2, Code0]),
+ ok = rpc:call(Node, M2, F2, []),
+ ok = rpc:call(Node, heart, set_callback, [M2,F2]),
+ {ok, {M2,F2}} = rpc:call(Node, heart, get_callback, []),
+ ok = rpc:call(Node, heart, clear_callback, []),
+ none = rpc:call(Node, heart, get_callback, []),
+ ok = rpc:call(Node, heart, set_callback, [M2,F2]),
+ {ok, {M2,F2}} = rpc:call(Node, heart, get_callback, []),
+ ok = rpc:call(Node, heart, set_callback, [M2,F3]),
+ receive {nodedown, Node} -> ok
+ after 5000 -> test_server:fail(node_not_killed)
+ end,
+ stop_node(Node),
+ ok.
+
+options_api(Config) when is_list(Config) ->
+ {ok, Node} = start_check(slave, heart_test),
+ none = rpc:call(Node, heart, get_options, []),
+ M0 = self(),
+ F0 = ok,
+ {error, {bad_options, {M0,F0}}} = rpc:call(Node, heart, set_options, [{M0,F0}]),
+ none = rpc:call(Node, heart, get_options, []),
+ Ls = lists:duplicate(28, $b),
+ {error, {bad_options, Ls}} = rpc:call(Node, heart, set_options, [Ls]),
+ none = rpc:call(Node, heart, get_options, []),
+
+ ok = rpc:call(Node, heart, set_options, [[check_schedulers]]),
+ {ok, [check_schedulers]} = rpc:call(Node, heart, get_options, []),
+ ok = rpc:call(Node, heart, set_options, [[]]),
+ none = rpc:call(Node, heart, get_options, []),
+
+ ok = rpc:call(Node, heart, set_options, [[check_schedulers]]),
+ {ok, [check_schedulers]} = rpc:call(Node, heart, get_options, []),
+ {error, {bad_options, Ls}} = rpc:call(Node, heart, set_options, [Ls]),
+ {ok, [check_schedulers]} = rpc:call(Node, heart, get_options, []),
+
+ receive after 3000 -> ok end, %% wait 3 secs
+
+ ok = rpc:call(Node, heart, set_options, [[]]),
+ none = rpc:call(Node, heart, get_options, []),
+ stop_node(Node),
+ ok.
+
+
dont_drop(suite) ->
%%% Removed as it may crash epmd/distribution in colourful
%%% ways. While we ARE finding out WHY, it would
@@ -562,13 +630,15 @@ suicide_by_heart() ->
generate(Module, Attributes, FunStrings) ->
FunForms = function_forms(FunStrings),
Forms = [
- {attribute,1,module,Module},
- {attribute,2,export,[FA || {FA,_} <- FunForms]}
- ] ++ [{attribute, 3, A, V}|| {A, V} <- Attributes] ++
+ {attribute,a(1),module,Module},
+ {attribute,a(2),export,[FA || {FA,_} <- FunForms]}
+ ] ++ [{attribute, a(3), A, V}|| {A, V} <- Attributes] ++
[ Function || {_, Function} <- FunForms],
{ok, Module, Bin} = compile:forms(Forms),
Bin.
+a(L) ->
+ erl_anno:new(L).
function_forms([]) -> [];
function_forms([S|Ss]) ->
diff --git a/lib/kernel/test/ignore_cores.erl b/lib/kernel/test/ignore_cores.erl
index d4bb02df3f..db61c4003b 100644
--- a/lib/kernel/test/ignore_cores.erl
+++ b/lib/kernel/test/ignore_cores.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index 44a32fc1ec..5ba06bb032 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -120,36 +121,37 @@ t_gethostbyaddr() ->
required(v4).
t_gethostbyaddr(doc) -> "Test the inet:gethostbyaddr/1 function.";
t_gethostbyaddr(Config) when is_list(Config) ->
- ?line {Name,FullName,IPStr,{A,B,C,D}=IP,Aliases,_,_} =
- ct:get_config(test_host_ipv4_only),
- ?line Rname = integer_to_list(D) ++ "." ++
- integer_to_list(C) ++ "." ++
- integer_to_list(B) ++ "." ++
- integer_to_list(A) ++ ".in-addr.arpa",
- ?line {ok,HEnt} = inet:gethostbyaddr(IPStr),
- ?line {ok,HEnt} = inet:gethostbyaddr(IP),
- ?line {error,Error} = inet:gethostbyaddr(Name),
- ?line ok = io:format("Failure reason: ~p: ~s",
- [error,inet:format_error(Error)]),
- ?line HEnt_ = HEnt#hostent{h_addrtype = inet,
- h_length = 4,
- h_addr_list = [IP]},
- ?line HEnt_ = HEnt,
+ {Name,FullName,IPStr,{A,B,C,D}=IP,Aliases,_,_} = ct:get_config(test_host_ipv4_only),
+ Rname = integer_to_list(D) ++ "." ++
+ integer_to_list(C) ++ "." ++
+ integer_to_list(B) ++ "." ++
+ integer_to_list(A) ++ ".in-addr.arpa",
+ {ok,HEnt} = inet:gethostbyaddr(IPStr),
+ {ok,HEnt} = inet:gethostbyaddr(IP),
+ {error,Error} = inet:gethostbyaddr(Name),
+ ok = io:format("Failure reason: ~p: ~s", [error,inet:format_error(Error)]),
+ HEnt_ = HEnt#hostent{h_addrtype = inet,
+ h_length = 4,
+ h_addr_list = [IP]},
+ HEnt_ = HEnt,
case {os:type(),os:version()} of
- {{unix,freebsd},{5,0,0}} ->
- %% The alias list seems to be buggy in FreeBSD 5.0.0.
- ?line check_elems([{HEnt#hostent.h_name,[Name,FullName]}]),
- io:format("Buggy alias list: ~p", [HEnt#hostent.h_aliases]),
- ok;
- _ ->
- ?line check_elems([{HEnt#hostent.h_name,[Name,FullName]},
- {HEnt#hostent.h_aliases,[[],Aliases,[Rname]]}])
+ {{unix,freebsd},{5,0,0}} ->
+ %% The alias list seems to be buggy in FreeBSD 5.0.0.
+ check_elems([{HEnt#hostent.h_name,[Name,FullName]}]),
+ io:format("Buggy alias list: ~p", [HEnt#hostent.h_aliases]),
+ ok;
+ _ ->
+ io:format("alias list: ~p", [HEnt#hostent.h_aliases]),
+ io:format("check alias list: ~p", [[Aliases,[Rname]]]),
+ io:format("name: ~p", [HEnt#hostent.h_name]),
+ io:format("check name: ~p", [[Name,FullName]]),
+ check_elems([{HEnt#hostent.h_name,[Name,FullName]},
+ {HEnt#hostent.h_aliases,[[],Aliases,[Rname]]}])
end,
- ?line {_DName, _DFullName, DIPStr, DIP, _, _, _} =
- ct:get_config(test_dummy_host),
- ?line {error,nxdomain} = inet:gethostbyaddr(DIPStr),
- ?line {error,nxdomain} = inet:gethostbyaddr(DIP),
+ {_DName, _DFullName, DIPStr, DIP, _, _, _} = ct:get_config(test_dummy_host),
+ {error,nxdomain} = inet:gethostbyaddr(DIPStr),
+ {error,nxdomain} = inet:gethostbyaddr(DIP),
ok.
t_gethostbyaddr_v6() -> required(v6).
@@ -569,8 +571,11 @@ parse_address(Config) when is_list(Config) ->
"::-1",
"::g",
"f:f11::10100:2",
+ "f:f11::01100:2",
"::17000",
+ "::01700",
"10000::",
+ "01000::",
"::8:7:6:5:4:3:2:1",
"8:7:6:5:4:3:2:1::",
"8:7:6:5:4::3:2:1",
diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index 1bc93e3138..ace4ccb8bd 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/inet_res_SUITE_data/run-named b/lib/kernel/test/inet_res_SUITE_data/run-named
index 211d2c7af7..d9befb352d 100755
--- a/lib/kernel/test/inet_res_SUITE_data/run-named
+++ b/lib/kernel/test/inet_res_SUITE_data/run-named
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
-##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## Licensed under the Apache License, Version 2.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%
##
diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl
index 9d236a8a0a..cb522c8abe 100644
--- a/lib/kernel/test/inet_sockopt_SUITE.erl
+++ b/lib/kernel/test/inet_sockopt_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -51,6 +52,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
simple/1, loop_all/1, simple_raw/1, simple_raw_getbin/1,
+ multiple_raw/1, multiple_raw_getbin/1,
doc_examples_raw/1,doc_examples_raw_getbin/1,
large_raw/1,large_raw_getbin/1,combined/1,combined_getbin/1,
ipv6_v6only_udp/1, ipv6_v6only_tcp/1, ipv6_v6only_sctp/1,
@@ -64,6 +66,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[simple, loop_all, simple_raw, simple_raw_getbin,
+ multiple_raw, multiple_raw_getbin,
doc_examples_raw, doc_examples_raw_getbin, large_raw,
large_raw_getbin, combined, combined_getbin,
ipv6_v6only_udp, ipv6_v6only_tcp, ipv6_v6only_sctp,
@@ -184,6 +187,84 @@ nintbin2int(<<Int:16/native>>) -> Int;
nintbin2int(<<Int:8/native>>) -> Int;
nintbin2int(<<>>) -> 0.
+
+
+multiple_raw(suite) -> [];
+multiple_raw(doc) -> "Test setopt/getopt of multiple raw options.";
+multiple_raw(Config) when is_list(Config) ->
+ do_multiple_raw(Config,false).
+multiple_raw_getbin(suite) -> [];
+multiple_raw_getbin(doc) -> "Test setopt/getopt of multiple raw options, "
+ "with binaries in getopt.";
+multiple_raw_getbin(Config) when is_list(Config) ->
+ do_multiple_raw(Config,true).
+
+do_multiple_raw(Config, Binary) ->
+ Port = start_helper(Config),
+ SolSocket = ask_helper(Port, ?C_GET_SOL_SOCKET),
+ SoKeepalive = ask_helper(Port, ?C_GET_SO_KEEPALIVE),
+ SoKeepaliveTrue = {raw,SolSocket,SoKeepalive,<<1:32/native>>},
+ SoKeepaliveFalse = {raw,SolSocket,SoKeepalive,<<0:32/native>>},
+ SoReuseaddr = ask_helper(Port, ?C_GET_SO_REUSEADDR),
+ SoReuseaddrTrue = {raw,SolSocket,SoReuseaddr,<<1:32/native>>},
+ SoReuseaddrFalse = {raw,SolSocket,SoReuseaddr,<<0:32/native>>},
+ {S1,S2} =
+ create_socketpair(
+ [SoReuseaddrFalse,SoKeepaliveTrue],
+ [SoKeepaliveFalse,SoReuseaddrTrue]),
+ {ok,[{reuseaddr,false},{keepalive,true}]} =
+ inet:getopts(S1, [reuseaddr,keepalive]),
+ {ok,
+ [{raw,SolSocket,SoReuseaddr,S1R1},
+ {raw,SolSocket,SoKeepalive,S1K1}]} =
+ inet:getopts(
+ S1,
+ [{raw,SolSocket,SoReuseaddr,binarify(4, Binary)},
+ {raw,SolSocket,SoKeepalive,binarify(4, Binary)}]),
+ true = nintbin2int(S1R1) =:= 0,
+ true = nintbin2int(S1K1) =/= 0,
+ {ok,[{keepalive,false},{reuseaddr,true}]} =
+ inet:getopts(S2, [keepalive,reuseaddr]),
+ {ok,
+ [{raw,SolSocket,SoKeepalive,S2K1},
+ {raw,SolSocket,SoReuseaddr,S2R1}]} =
+ inet:getopts(
+ S2,
+ [{raw,SolSocket,SoKeepalive,binarify(4, Binary)},
+ {raw,SolSocket,SoReuseaddr,binarify(4, Binary)}]),
+ true = nintbin2int(S2K1) =:= 0,
+ true = nintbin2int(S2R1) =/= 0,
+ %%
+ ok = inet:setopts(
+ S1, [SoReuseaddrTrue,SoKeepaliveFalse]),
+ ok = inet:setopts(
+ S2, [SoKeepaliveTrue,SoReuseaddrFalse]),
+ {ok,
+ [{raw,SolSocket,SoReuseaddr,S1R2},
+ {raw,SolSocket,SoKeepalive,S1K2}]} =
+ inet:getopts(
+ S1,
+ [{raw,SolSocket,SoReuseaddr,binarify(4, Binary)},
+ {raw,SolSocket,SoKeepalive,binarify(4, Binary)}]),
+ true = nintbin2int(S1R2) =/= 0,
+ true = nintbin2int(S1K2) =:= 0,
+ {ok,
+ [{raw,SolSocket,SoKeepalive,S2K2},
+ {raw,SolSocket,SoReuseaddr,S2R2}]} =
+ inet:getopts(
+ S2,
+ [{raw,SolSocket,SoKeepalive,binarify(4, Binary)},
+ {raw,SolSocket,SoReuseaddr,binarify(4, Binary)}]),
+ true = nintbin2int(S2K2) =/= 0,
+ true = nintbin2int(S2R2) =:= 0,
+ %%
+ gen_tcp:close(S1),
+ gen_tcp:close(S2),
+ stop_helper(Port),
+ ok.
+
+
+
doc_examples_raw(suite) -> [];
doc_examples_raw(doc) -> "Test that the example code from the documentation "
"works";
diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl
index 6fe97ed04f..54ab5aa566 100644
--- a/lib/kernel/test/init_SUITE.erl
+++ b/lib/kernel/test/init_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl
index 7f6024f642..8adae1f606 100644
--- a/lib/kernel/test/interactive_shell_SUITE.erl
+++ b/lib/kernel/test/interactive_shell_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -48,12 +49,7 @@ groups() ->
[].
init_per_suite(Config) ->
- Term = case os:getenv("TERM") of
- List when is_list(List) ->
- List;
- _ ->
- "dumb"
- end,
+ Term = os:getenv("TERM", "dumb"),
os:putenv("TERM","vt100"),
DefShell = get_default_shell(),
[{default_shell,DefShell},{term,Term}|Config].
@@ -723,8 +719,7 @@ toerl_loop(Port,Acc) ->
end.
millistamp() ->
- {Mega, Secs, Micros} = erlang:now(),
- (Micros div 1000) + Secs * 1000 + Mega * 1000000000.
+ erlang:monotonic_time(milli_seconds).
get_data_within(Port, X, Acc) when X =< 0 ->
?dbg({get_data_within, X, Acc, ?LINE}),
diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl
index 613efeeb2f..8ae2e4b23b 100644
--- a/lib/kernel/test/kernel_SUITE.erl
+++ b/lib/kernel/test/kernel_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/kernel_config_SUITE.erl b/lib/kernel/test/kernel_config_SUITE.erl
index 93bdb8657c..4be44015c9 100644
--- a/lib/kernel/test/kernel_config_SUITE.erl
+++ b/lib/kernel/test/kernel_config_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/loose_node.erl b/lib/kernel/test/loose_node.erl
index 87a4ef01c0..ba293a821a 100644
--- a/lib/kernel/test/loose_node.erl
+++ b/lib/kernel/test/loose_node.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/myApp.erl b/lib/kernel/test/myApp.erl
index 26dc74f91b..add1d5d500 100644
--- a/lib/kernel/test/myApp.erl
+++ b/lib/kernel/test/myApp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 9b474c4cdf..29d8d10262 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 98cff0222e..6de4ff9f77 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,7 +32,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
- simple/1, complicated/1, heavy/1, info/1]).
+ simple/1, complicated/1, heavy/1, simple_all_keys/1, info/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
-export([other_process/2]).
@@ -46,7 +47,7 @@ end_per_testcase(_Case, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [simple, complicated, heavy, info].
+ [simple, complicated, heavy, simple_all_keys, info].
groups() ->
[].
@@ -70,6 +71,7 @@ simple(suite) ->
[];
simple(Config) when is_list(Config) ->
XX = get(),
+ ok = match_keys(XX),
erase(),
L = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
q,r,s,t,u,v,x,y,z,'A','B','C','D'],
@@ -105,6 +107,7 @@ simple(Config) when is_list(Config) ->
complicated(Config) when is_list(Config) ->
Previous = get(),
+ ok = match_keys(Previous),
Previous = erase(),
N = case ?t:is_debug() of
false -> 500000;
@@ -113,8 +116,10 @@ complicated(Config) when is_list(Config) ->
comp_1(N),
comp_2(N),
N = comp_3(lists:sort(get()), 1),
+ ok = match_keys(get()),
comp_4(get()),
[] = get(),
+ [] = get_keys(),
[put(Key, Value) || {Key,Value} <- Previous],
ok.
@@ -160,6 +165,26 @@ heavy(Config) when is_list(Config) ->
[put(Key, Value) || {Key,Value} <- XX],
ok.
+simple_all_keys(Config) when is_list(Config) ->
+ erase(),
+ ok = simple_all_keys_add_loop(1000),
+ [] = get_keys(),
+ [] = get(),
+ ok.
+
+simple_all_keys_add_loop(0) ->
+ simple_all_keys_del_loop(erlang:get_keys());
+simple_all_keys_add_loop(N) ->
+ put(gen_key(N),value),
+ ok = match_keys(get()),
+ simple_all_keys_add_loop(N-1).
+
+simple_all_keys_del_loop([]) -> ok;
+simple_all_keys_del_loop([K|Ks]) ->
+ value = erase(K),
+ ok = match_keys(get()),
+ simple_all_keys_del_loop(Ks).
+
info(doc) ->
["Tests process_info(Pid, dictionary)"];
info(suite) ->
@@ -339,3 +364,8 @@ m(A,B,Module,Line) ->
[A,B,Module,Line]),
exit({no_match,{A,B},Module,Line})
end.
+
+match_keys(All) ->
+ Ks = lists:sort([K||{K,_}<-All]),
+ Ks = lists:sort(erlang:get_keys()),
+ ok.
diff --git a/lib/kernel/test/pg2_SUITE.erl b/lib/kernel/test/pg2_SUITE.erl
index 520b53b4e4..832d2d1c27 100644
--- a/lib/kernel/test/pg2_SUITE.erl
+++ b/lib/kernel/test/pg2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index f55716cbec..3e6d8492f7 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl
index 615251a257..933dc88d21 100644
--- a/lib/kernel/test/ram_file_SUITE.erl
+++ b/lib/kernel/test/ram_file_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/rpc_SUITE.erl b/lib/kernel/test/rpc_SUITE.erl
index 7adef49014..ed30c2dffa 100644
--- a/lib/kernel/test/rpc_SUITE.erl
+++ b/lib/kernel/test/rpc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -456,32 +457,33 @@ called_throws(Config) when is_list(Config) ->
call_benchmark(Config) when is_list(Config) ->
Timetrap = ?t:timetrap(?t:seconds(120)),
- ?line PA = filename:dirname(code:which(?MODULE)),
- ?line {ok, Node} = ?t:start_node(rpc_SUITE_call_benchmark, slave,
- [{args, "-pa " ++ PA}]),
+ PA = filename:dirname(code:which(?MODULE)),
+ {ok, Node} = ?t:start_node(rpc_SUITE_call_benchmark, slave,
+ [{args, "-pa " ++ PA}]),
Iter = case erlang:system_info(modified_timing_level) of
undefined -> 10000;
- _ -> 500 %Moified timing - spawn is slower
+ _ -> 500 %Modified timing - spawn is slower
end,
- ?line do_call_benchmark(Node, Iter),
+ Res = do_call_benchmark(Node, Iter),
+ ?t:stop_node(Node),
?t:timetrap_cancel(Timetrap),
- ok.
+ Res.
do_call_benchmark(Node, M) when is_integer(M), M > 0 ->
- do_call_benchmark(Node, erlang:now(), 0, M).
-
-do_call_benchmark(Node, {A,B,C}, M, M) ->
- ?line {D,E,F} = erlang:now(),
- ?line T = float(D-A)*1000000.0 + float(E-B) + float(F-C)*0.000001,
- ?line Q = 3.0 * float(M) / T,
- ?line ?t:stop_node(Node),
- {comment,
- lists:flatten([float_to_list(Q)," RPC calls per second"])};
-do_call_benchmark(Node, Then, I, M) ->
- ?line Node = rpc:call(Node, erlang, node, []),
- ?line _ = rpc:call(Node, erlang, whereis, [rex]),
- ?line 3 = rpc:call(Node, erlang, '+', [1,2]),
- ?line do_call_benchmark(Node, Then, I+1, M).
+ {Micros,ok} = timer:tc(fun() ->
+ do_call_benchmark(Node, 0, M)
+ end),
+ Calls = 3*M,
+ S = io_lib:format("~p RPC calls/second", [Calls*1000000 div Micros]),
+ {comment,lists:flatten(S)}.
+
+do_call_benchmark(_Node, M, M) ->
+ ok;
+do_call_benchmark(Node, I, M) ->
+ Node = rpc:call(Node, erlang, node, []),
+ _ = rpc:call(Node, erlang, whereis, [rex]),
+ 3 = rpc:call(Node, erlang, '+', [1,2]),
+ do_call_benchmark(Node, I+1, M).
async_call(Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(120)),
diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl
index 123e849ccb..a82b9c5fcd 100644
--- a/lib/kernel/test/sendfile_SUITE.erl
+++ b/lib/kernel/test/sendfile_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/seq_trace_SUITE.erl b/lib/kernel/test/seq_trace_SUITE.erl
index 47eeb4df4c..6a63f7bc9c 100644
--- a/lib/kernel/test/seq_trace_SUITE.erl
+++ b/lib/kernel/test/seq_trace_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,6 +35,11 @@
%-define(line_trace, 1).
-include_lib("test_server/include/test_server.hrl").
+-define(TIMESTAMP_MODES, [no_timestamp,
+ timestamp,
+ monotonic_timestamp,
+ strict_monotonic_timestamp]).
+
-define(default_timeout, ?t:minutes(1)).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -74,6 +80,17 @@ end_per_testcase(_Case, Config) ->
token_set_get(doc) -> [];
token_set_get(suite) -> [];
token_set_get(Config) when is_list(Config) ->
+ do_token_set_get(timestamp),
+ do_token_set_get(monotonic_timestamp),
+ do_token_set_get(strict_monotonic_timestamp).
+
+do_token_set_get(TsType) ->
+ io:format("Testing ~p~n", [TsType]),
+ Flags = case TsType of
+ timestamp -> 15;
+ strict_monotonic_timestamp -> 23;
+ monotonic_timestamp -> 39
+ end,
?line Self = self(),
?line seq_trace:reset_trace(),
%% Test that initial seq_trace is disabled
@@ -87,22 +104,22 @@ token_set_get(Config) when is_list(Config) ->
?line {send,true} = seq_trace:get_token(send),
?line false = seq_trace:set_token('receive',true),
?line {'receive',true} = seq_trace:get_token('receive'),
- ?line false = seq_trace:set_token(timestamp,true),
- ?line {timestamp,true} = seq_trace:get_token(timestamp),
+ ?line false = seq_trace:set_token(TsType,true),
+ ?line {TsType,true} = seq_trace:get_token(TsType),
%% Check the whole token
- ?line {15,17,0,Self,0} = seq_trace:get_token(), % all flags are set
+ ?line {Flags,17,0,Self,0} = seq_trace:get_token(), % all flags are set
%% Test setting and reading the 'serial' field
?line {0,0} = seq_trace:set_token(serial,{3,5}),
?line {serial,{3,5}} = seq_trace:get_token(serial),
%% Check the whole token, test that a whole token can be set and get
- ?line {15,17,5,Self,3} = seq_trace:get_token(),
- ?line seq_trace:set_token({15,19,7,Self,5}),
- ?line {15,19,7,Self,5} = seq_trace:get_token(),
+ ?line {Flags,17,5,Self,3} = seq_trace:get_token(),
+ ?line seq_trace:set_token({Flags,19,7,Self,5}),
+ ?line {Flags,19,7,Self,5} = seq_trace:get_token(),
%% Check that receive timeout does not reset token
?line receive after 0 -> ok end,
- ?line {15,19,7,Self,5} = seq_trace:get_token(),
+ ?line {Flags,19,7,Self,5} = seq_trace:get_token(),
%% Check that token can be unset
- ?line {15,19,7,Self,5} = seq_trace:set_token([]),
+ ?line {Flags,19,7,Self,5} = seq_trace:set_token([]),
?line [] = seq_trace:get_token(),
%% Check that Previous serial counter survived unset token
?line 0 = seq_trace:set_token(label, 17),
@@ -138,30 +155,42 @@ tracer_set_get(Config) when is_list(Config) ->
print(doc) -> [];
print(suite) -> [];
print(Config) when is_list(Config) ->
+ lists:foreach(fun do_print/1, ?TIMESTAMP_MODES).
+
+do_print(TsType) ->
?line start_tracer(),
- ?line seq_trace:set_token(print,true),
+ ?line set_token_flags([print, TsType]),
?line seq_trace:print(0,print1),
?line seq_trace:print(1,print2),
?line seq_trace:print(print3),
?line seq_trace:reset_trace(),
- ?line [{0,{print,_,_,[],print1}},
- {0,{print,_,_,[],print3}}] = stop_tracer(2).
+ ?line [{0,{print,_,_,[],print1}, Ts0},
+ {0,{print,_,_,[],print3}, Ts1}] = stop_tracer(2),
+ check_ts(TsType, Ts0),
+ check_ts(TsType, Ts1).
send(doc) -> [];
send(suite) -> [];
send(Config) when is_list(Config) ->
+ lists:foreach(fun do_send/1, ?TIMESTAMP_MODES).
+
+do_send(TsType) ->
?line seq_trace:reset_trace(),
?line start_tracer(),
?line Receiver = spawn(?MODULE,one_time_receiver,[]),
- ?line seq_trace:set_token(send,true),
+ ?line set_token_flags([send, TsType]),
?line Receiver ! send,
?line Self = self(),
?line seq_trace:reset_trace(),
- ?line [{0,{send,_,Self,Receiver,send}}] = stop_tracer(1).
+ ?line [{0,{send,_,Self,Receiver,send}, Ts}] = stop_tracer(1),
+ check_ts(TsType, Ts).
distributed_send(doc) -> [];
distributed_send(suite) -> [];
distributed_send(Config) when is_list(Config) ->
+ lists:foreach(fun do_distributed_send/1, ?TIMESTAMP_MODES).
+
+do_distributed_send(TsType) ->
?line {ok,Node} = start_node(seq_trace_other,[]),
?line {_,Dir} = code:is_loaded(?MODULE),
?line Mdir = filename:dirname(Dir),
@@ -169,30 +198,39 @@ distributed_send(Config) when is_list(Config) ->
?line seq_trace:reset_trace(),
?line start_tracer(),
?line Receiver = spawn(Node,?MODULE,one_time_receiver,[]),
- ?line seq_trace:set_token(send,true),
+ ?line set_token_flags([send,TsType]),
?line Receiver ! send,
?line Self = self(),
?line seq_trace:reset_trace(),
?line stop_node(Node),
- ?line [{0,{send,_,Self,Receiver,send}}] = stop_tracer(1).
+ ?line [{0,{send,_,Self,Receiver,send}, Ts}] = stop_tracer(1),
+ check_ts(TsType, Ts).
+
recv(doc) -> [];
recv(suite) -> [];
recv(Config) when is_list(Config) ->
+ lists:foreach(fun do_recv/1, ?TIMESTAMP_MODES).
+
+do_recv(TsType) ->
?line seq_trace:reset_trace(),
?line start_tracer(),
?line Receiver = spawn(?MODULE,one_time_receiver,[]),
- ?line seq_trace:set_token('receive',true),
+ ?line set_token_flags(['receive',TsType]),
?line Receiver ! 'receive',
%% let the other process receive the message:
?line receive after 1 -> ok end,
?line Self = self(),
?line seq_trace:reset_trace(),
- ?line [{0,{'receive',_,Self,Receiver,'receive'}}] = stop_tracer(1).
+ ?line [{0,{'receive',_,Self,Receiver,'receive'}, Ts}] = stop_tracer(1),
+ check_ts(TsType, Ts).
distributed_recv(doc) -> [];
distributed_recv(suite) -> [];
distributed_recv(Config) when is_list(Config) ->
+ lists:foreach(fun do_distributed_recv/1, ?TIMESTAMP_MODES).
+
+do_distributed_recv(TsType) ->
?line {ok,Node} = start_node(seq_trace_other,[]),
?line {_,Dir} = code:is_loaded(?MODULE),
?line Mdir = filename:dirname(Dir),
@@ -200,7 +238,7 @@ distributed_recv(Config) when is_list(Config) ->
?line seq_trace:reset_trace(),
?line rpc:call(Node,?MODULE,start_tracer,[]),
?line Receiver = spawn(Node,?MODULE,one_time_receiver,[]),
- ?line seq_trace:set_token('receive',true),
+ ?line set_token_flags(['receive',TsType]),
?line Receiver ! 'receive',
%% let the other process receive the message:
?line receive after 1 -> ok end,
@@ -209,16 +247,20 @@ distributed_recv(Config) when is_list(Config) ->
?line Result = rpc:call(Node,?MODULE,stop_tracer,[1]),
?line stop_node(Node),
?line ok = io:format("~p~n",[Result]),
- ?line [{0,{'receive',_,Self,Receiver,'receive'}}] = Result.
+ ?line [{0,{'receive',_,Self,Receiver,'receive'}, Ts}] = Result,
+ check_ts(TsType, Ts).
trace_exit(doc) -> [];
trace_exit(suite) -> [];
trace_exit(Config) when is_list(Config) ->
+ lists:foreach(fun do_trace_exit/1, ?TIMESTAMP_MODES).
+
+do_trace_exit(TsType) ->
?line seq_trace:reset_trace(),
?line start_tracer(),
?line Receiver = spawn_link(?MODULE, one_time_receiver, [exit]),
?line process_flag(trap_exit, true),
- ?line seq_trace:set_token(send,true),
+ ?line set_token_flags([send, TsType]),
?line Receiver ! {before, exit},
%% let the other process receive the message:
?line receive
@@ -232,13 +274,18 @@ trace_exit(Config) when is_list(Config) ->
?line Result = stop_tracer(2),
?line seq_trace:reset_trace(),
?line ok = io:format("~p~n", [Result]),
- ?line [{0, {send, {0,1}, Self, Receiver, {before, exit}}},
+ ?line [{0, {send, {0,1}, Self, Receiver, {before, exit}}, Ts0},
{0, {send, {1,2}, Receiver, Self,
- {'EXIT', Receiver, {exit, {before, exit}}}}}] = Result.
+ {'EXIT', Receiver, {exit, {before, exit}}}}, Ts1}] = Result,
+ check_ts(TsType, Ts0),
+ check_ts(TsType, Ts1).
distributed_exit(doc) -> [];
distributed_exit(suite) -> [];
distributed_exit(Config) when is_list(Config) ->
+ lists:foreach(fun do_distributed_exit/1, ?TIMESTAMP_MODES).
+
+do_distributed_exit(TsType) ->
?line {ok, Node} = start_node(seq_trace_other, []),
?line {_, Dir} = code:is_loaded(?MODULE),
?line Mdir = filename:dirname(Dir),
@@ -247,7 +294,7 @@ distributed_exit(Config) when is_list(Config) ->
?line rpc:call(Node, ?MODULE, start_tracer,[]),
?line Receiver = spawn_link(Node, ?MODULE, one_time_receiver, [exit]),
?line process_flag(trap_exit, true),
- ?line seq_trace:set_token(send, true),
+ ?line set_token_flags([send, TsType]),
?line Receiver ! {before, exit},
%% let the other process receive the message:
?line receive
@@ -263,7 +310,8 @@ distributed_exit(Config) when is_list(Config) ->
?line stop_node(Node),
?line ok = io:format("~p~n", [Result]),
?line [{0, {send, {1, 2}, Receiver, Self,
- {'EXIT', Receiver, {exit, {before, exit}}}}}] = Result.
+ {'EXIT', Receiver, {exit, {before, exit}}}}, Ts}] = Result,
+ check_ts(TsType, Ts).
call(doc) ->
"Tests special forms {is_seq_trace} and {get_seq_token} "
@@ -360,14 +408,22 @@ port(doc) ->
"Send trace messages to a port.";
port(suite) -> [];
port(Config) when is_list(Config) ->
+ lists:foreach(fun (TsType) -> do_port(TsType, Config) end,
+ ?TIMESTAMP_MODES).
+
+do_port(TsType, Config) ->
+ io:format("Testing ~p~n",[TsType]),
?line Port = load_tracer(Config),
?line seq_trace:set_system_tracer(Port),
- ?line seq_trace:set_token(print, true),
+ ?line set_token_flags([print, TsType]),
?line Small = [small,term],
?line seq_trace:print(0, Small),
?line case get_port_message(Port) of
- {seq_trace,0,{print,_,_,[],Small}} ->
+ {seq_trace,0,{print,_,_,[],Small}} when TsType == no_timestamp ->
+ ok;
+ {seq_trace,0,{print,_,_,[],Small},Ts0} when TsType /= no_timestamp ->
+ check_ts(TsType, Ts0),
ok;
Other ->
?line seq_trace:reset_trace(),
@@ -381,7 +437,10 @@ port(Config) when is_list(Config) ->
?line seq_trace:print(0, OtherSmall),
?line seq_trace:reset_trace(),
?line case get_port_message(Port) of
- {seq_trace,0,{print,_,_,[],OtherSmall}} ->
+ {seq_trace,0,{print,_,_,[],OtherSmall}} when TsType == no_timestamp ->
+ ok;
+ {seq_trace,0,{print,_,_,[],OtherSmall}, Ts1} when TsType /= no_timestamp ->
+ check_ts(TsType, Ts1),
ok;
Other1 ->
?line ?t:fail({unexpected,Other1})
@@ -398,6 +457,8 @@ port(Config) when is_list(Config) ->
Other2 ->
?line ?t:fail({unexpected,Other2})
end,
+ unlink(Port),
+ exit(Port,kill),
ok.
get_port_message(Port) ->
@@ -733,7 +794,7 @@ simple_tracer(Data, DN) ->
{seq_trace,Label,Info,Ts} ->
simple_tracer([{Label,Info,Ts}|Data], DN+1);
{seq_trace,Label,Info} ->
- simple_tracer([{Label,Info}|Data], DN+1);
+ simple_tracer([{Label,Info, no_timestamp}|Data], DN+1);
{stop,N,From} when DN >= N ->
From ! {tracerlog,lists:reverse(Data)}
end.
@@ -758,7 +819,55 @@ start_tracer() ->
seq_trace:set_system_tracer(Pid),
Pid.
-
+
+set_token_flags([]) ->
+ ok;
+set_token_flags([no_timestamp|Flags]) ->
+ seq_trace:set_token(timestamp, false),
+ seq_trace:set_token(monotonic_timestamp, false),
+ seq_trace:set_token(strict_monotonic_timestamp, false),
+ set_token_flags(Flags);
+set_token_flags([Flag|Flags]) ->
+ seq_trace:set_token(Flag, true),
+ set_token_flags(Flags).
+
+check_ts(no_timestamp, Ts) ->
+ try
+ no_timestamp = Ts
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok;
+check_ts(timestamp, Ts) ->
+ try
+ {Ms,S,Us} = Ts,
+ true = is_integer(Ms),
+ true = is_integer(S),
+ true = is_integer(Us)
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok;
+check_ts(monotonic_timestamp, Ts) ->
+ try
+ true = is_integer(Ts)
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok;
+check_ts(strict_monotonic_timestamp, Ts) ->
+ try
+ {MT, UMI} = Ts,
+ true = is_integer(MT),
+ true = is_integer(UMI)
+ catch
+ _ : _ ->
+ ?t:fail({unexpected_timestamp, Ts})
+ end,
+ ok.
start_node(Name, Param) ->
test_server:start_node(Name, slave, [{args, Param}]).
diff --git a/lib/kernel/test/standard_error_SUITE.erl b/lib/kernel/test/standard_error_SUITE.erl
index b290454b40..97ead9b9fd 100644
--- a/lib/kernel/test/standard_error_SUITE.erl
+++ b/lib/kernel/test/standard_error_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -20,13 +21,13 @@
-module(standard_error_SUITE).
-export([all/0,suite/0]).
--export([badarg/1,getopts/1]).
+-export([badarg/1,getopts/1,output/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
all() ->
- [badarg,getopts].
+ [badarg,getopts,output].
badarg(Config) when is_list(Config) ->
{'EXIT',{badarg,_}} = (catch io:put_chars(standard_error, [oops])),
@@ -36,3 +37,30 @@ badarg(Config) when is_list(Config) ->
getopts(Config) when is_list(Config) ->
[{encoding,latin1}] = io:getopts(standard_error),
ok.
+
+%% Test that writing a lot of output to standard_error does not cause the
+%% processes handling it to terminate like this:
+%%
+%% =ERROR REPORT==== 9-Aug-2015::23:19:23 ===
+%% ** Generic server standard_error_sup terminating
+%% ** Last message in was {'EXIT',<0.28.0>,eagain}
+%% ** When Server state == {state,standard_error,undefined,<0.28.0>,
+%% {local,standard_error_sup}}
+%% ** Reason for termination ==
+%% ** eagain
+%%
+%% This problem, observed with Erlang 18.0.2, was fixed in fd_driver by
+%% properly handling EAGAIN if it arises on file descriptor writes.
+%%
+output(Config) when is_list(Config) ->
+ Ref = monitor(process, standard_error_sup),
+ Chars = [ [["1234567890" || _ <- lists:seq(1,10)], $\s,
+ integer_to_list(L), $\r, $\n] || L <- lists:seq(1, 100) ],
+ ok = io:put_chars(standard_error, Chars),
+ receive
+ {'DOWN', Ref, process, _, _} ->
+ error(standard_error_noproc)
+ after
+ 500 ->
+ ok
+ end.
diff --git a/lib/kernel/test/topApp.erl b/lib/kernel/test/topApp.erl
index f44e99f738..597268a5a2 100644
--- a/lib/kernel/test/topApp.erl
+++ b/lib/kernel/test/topApp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/topApp2.erl b/lib/kernel/test/topApp2.erl
index b791d4a914..69d5c047be 100644
--- a/lib/kernel/test/topApp2.erl
+++ b/lib/kernel/test/topApp2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/topApp3.erl b/lib/kernel/test/topApp3.erl
index 456ef5b2fb..e892aadcd0 100644
--- a/lib/kernel/test/topApp3.erl
+++ b/lib/kernel/test/topApp3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/wrap_log_reader_SUITE.erl b/lib/kernel/test/wrap_log_reader_SUITE.erl
index 16b3a7cc1e..9a93b9037f 100644
--- a/lib/kernel/test/wrap_log_reader_SUITE.erl
+++ b/lib/kernel/test/wrap_log_reader_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/kernel/test/wrap_log_reader_SUITE_data/wrap_log_test.erl b/lib/kernel/test/wrap_log_reader_SUITE_data/wrap_log_test.erl
index e5ff70fd49..1cd1a4b0a4 100644
--- a/lib/kernel/test/wrap_log_reader_SUITE_data/wrap_log_test.erl
+++ b/lib/kernel/test/wrap_log_reader_SUITE_data/wrap_log_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index 3be6f39d95..6aaa024a82 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -82,7 +83,7 @@ groups() ->
api_deflateSetDictionary, api_deflateReset,
api_deflateParams, api_deflate, api_deflateEnd,
api_inflateInit, api_inflateSetDictionary,
- api_inflateSync, api_inflateReset, api_inflate,
+ api_inflateSync, api_inflateReset, api_inflate, api_inflateChunk,
api_inflateEnd, api_setBufsz, api_getBufsz, api_crc32,
api_adler32, api_getQSize, api_un_compress, api_un_zip,
api_g_un_zip]},
@@ -146,8 +147,6 @@ api_deflateInit(Config) when is_list(Config) ->
?m(?BARG, zlib:deflateInit(Z1,default,deflated,-20,8,default)),
?m(?BARG, zlib:deflateInit(Z1,default,deflated,-7,8,default)),
?m(?BARG, zlib:deflateInit(Z1,default,deflated,7,8,default)),
- ?m(?BARG, zlib:deflateInit(Z1,default,deflated,-8,8,default)),
- ?m(?BARG, zlib:deflateInit(Z1,default,deflated,8,8,default)),
?m(?BARG, zlib:deflateInit(Z1,default,deflated,-15,0,default)),
?m(?BARG, zlib:deflateInit(Z1,default,deflated,-15,10,default)),
@@ -169,7 +168,7 @@ api_deflateInit(Config) when is_list(Config) ->
?m(ok, zlib:deflateInit(Z12,default,deflated,-Wbits,8,default)),
?m(ok,zlib:close(Z11)),
?m(ok,zlib:close(Z12))
- end, lists:seq(9, 15)),
+ end, lists:seq(8, 15)),
lists:foreach(fun(MemLevel) ->
?line Z = zlib:open(),
@@ -277,7 +276,7 @@ api_inflateInit(Config) when is_list(Config) ->
?m(ok, zlib:inflateInit(Z12,-Wbits)),
?m(ok,zlib:close(Z11)),
?m(ok,zlib:close(Z12))
- end, lists:seq(9,15)),
+ end, lists:seq(8,15)),
?m(?BARG, zlib:inflateInit(gurka, -15)),
?m(?BARG, zlib:inflateInit(Z1, 7)),
?m(?BARG, zlib:inflateInit(Z1, -7)),
@@ -357,6 +356,39 @@ api_inflate(Config) when is_list(Config) ->
?m({'EXIT',{data_error,_}}, zlib:inflate(Z1, <<2,1,2,1,2>>)),
?m(ok, zlib:close(Z1)).
+api_inflateChunk(doc) -> "Test inflateChunk";
+api_inflateChunk(suite) -> [];
+api_inflateChunk(Config) when is_list(Config) ->
+ ChunkSize = 1024,
+ Data = << <<(I rem 150)>> || I <- lists:seq(1, 3 * ChunkSize) >>,
+ Part1 = binary:part(Data, 0, ChunkSize),
+ Part2 = binary:part(Data, ChunkSize, ChunkSize),
+ Part3 = binary:part(Data, ChunkSize * 2, ChunkSize),
+ ?line Compressed = zlib:compress(Data),
+ ?line Z1 = zlib:open(),
+ ?line zlib:setBufSize(Z1, ChunkSize),
+ ?m(ok, zlib:inflateInit(Z1)),
+ ?m([], zlib:inflateChunk(Z1, <<>>)),
+ ?m({more, Part1}, zlib:inflateChunk(Z1, Compressed)),
+ ?m({more, Part2}, zlib:inflateChunk(Z1)),
+ ?m(Part3, zlib:inflateChunk(Z1)),
+ ?m(ok, zlib:inflateEnd(Z1)),
+
+ ?m(ok, zlib:inflateInit(Z1)),
+ ?m({more, Part1}, zlib:inflateChunk(Z1, Compressed)),
+
+ ?m(ok, zlib:inflateReset(Z1)),
+
+ ?line zlib:setBufSize(Z1, size(Data)),
+ ?m(Data, zlib:inflateChunk(Z1, Compressed)),
+ ?m(ok, zlib:inflateEnd(Z1)),
+
+ ?m(ok, zlib:inflateInit(Z1)),
+ ?m(?BARG, zlib:inflateChunk(gurka, Compressed)),
+ ?m(?BARG, zlib:inflateChunk(Z1, 4384)),
+ ?m({'EXIT',{data_error,_}}, zlib:inflateEnd(Z1)),
+ ?m(ok, zlib:close(Z1)).
+
api_inflateEnd(doc) -> "Test inflateEnd";
api_inflateEnd(suite) -> [];
api_inflateEnd(Config) when is_list(Config) ->
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index e1d447a465..c8917ebc3c 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 3.2
+KERNEL_VSN = 4.2
diff --git a/lib/megaco/Makefile b/lib/megaco/Makefile
index 3bf502ba1c..867953013d 100644
--- a/lib/megaco/Makefile
+++ b/lib/megaco/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/configure.in b/lib/megaco/configure.in
index e3c24a58b8..d012c07645 100644
--- a/lib/megaco/configure.in
+++ b/lib/megaco/configure.in
@@ -4,16 +4,17 @@ dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 2001-2013. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
dnl
diff --git a/lib/megaco/doc/src/Makefile b/lib/megaco/doc/src/Makefile
index ea2284e89b..582cb9035f 100644
--- a/lib/megaco/doc/src/Makefile
+++ b/lib/megaco/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/megaco/doc/src/book.xml b/lib/megaco/doc/src/book.xml
index 1a4f532a70..ebf627cfdb 100644
--- a/lib/megaco/doc/src/book.xml
+++ b/lib/megaco/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/files.mk b/lib/megaco/doc/src/files.mk
index efacb7e422..62e3ab404e 100644
--- a/lib/megaco/doc/src/files.mk
+++ b/lib/megaco/doc/src/files.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/megaco/doc/src/index.html.src b/lib/megaco/doc/src/index.html.src
index 4de3450f67..b3ff9c3ae7 100644
--- a/lib/megaco/doc/src/index.html.src
+++ b/lib/megaco/doc/src/index.html.src
@@ -2,16 +2,17 @@
<!-- This file is obsolete -->
<HTML>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/megaco/doc/src/megaco.xml b/lib/megaco/doc/src/megaco.xml
index dff1c3afc6..6e0260f916 100644
--- a/lib/megaco/doc/src/megaco.xml
+++ b/lib/megaco/doc/src/megaco.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -336,7 +337,7 @@ megaco_incr_timer() = #megaco_incr_timer{}
<tag><c><![CDATA[request_keep_alive_timeout]]></c></tag>
<item>
<p>Specifies the timeout time for the request-keep-alive timer. </p>
- <p>This timer is started when the <em>first</em> reply to an asynchroneous
+ <p>This timer is started when the <em>first</em> reply to an asynchronous
request (issued using the
<seealso marker="megaco#cast">megaco:cast/3</seealso> function)
arrives. As long as this timer is running, replies will
@@ -837,7 +838,7 @@ megaco_incr_timer() = #megaco_incr_timer{}
<tag><c><![CDATA[request_keep_alive_timeout]]></c></tag>
<item>
<p>Specifies the timeout time for the request-keep-alive timer. </p>
- <p>This timer is started when the <em>first</em> reply to an asynchroneous
+ <p>This timer is started when the <em>first</em> reply to an asynchronous
request (issued using the
<seealso marker="megaco#cast">megaco:cast/3</seealso> function)
arrives. As long as this timer is running, replies will
diff --git a/lib/megaco/doc/src/megaco_architecture.xml b/lib/megaco/doc/src/megaco_architecture.xml
index 6795cd17a1..6f3d0808d7 100644
--- a/lib/megaco/doc/src/megaco_architecture.xml
+++ b/lib/megaco/doc/src/megaco_architecture.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_codec_meas.xml b/lib/megaco/doc/src/megaco_codec_meas.xml
index c6d73fb518..ad79bcec4d 100644
--- a/lib/megaco/doc/src/megaco_codec_meas.xml
+++ b/lib/megaco/doc/src/megaco_codec_meas.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_codec_mstone1.xml b/lib/megaco/doc/src/megaco_codec_mstone1.xml
index 4c32d9f497..0634d328e0 100644
--- a/lib/megaco/doc/src/megaco_codec_mstone1.xml
+++ b/lib/megaco/doc/src/megaco_codec_mstone1.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_codec_mstone2.xml b/lib/megaco/doc/src/megaco_codec_mstone2.xml
index d86a540ec2..b9f3a8ff0c 100644
--- a/lib/megaco/doc/src/megaco_codec_mstone2.xml
+++ b/lib/megaco/doc/src/megaco_codec_mstone2.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_codec_transform.xml b/lib/megaco/doc/src/megaco_codec_transform.xml
index 9257c3a80c..b068c01f3b 100644
--- a/lib/megaco/doc/src/megaco_codec_transform.xml
+++ b/lib/megaco/doc/src/megaco_codec_transform.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_debug.xml b/lib/megaco/doc/src/megaco_debug.xml
index 5c0132b6ef..701e17a54c 100644
--- a/lib/megaco/doc/src/megaco_debug.xml
+++ b/lib/megaco/doc/src/megaco_debug.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_edist_compress.xml b/lib/megaco/doc/src/megaco_edist_compress.xml
index dca5046f6f..04c4ad1cd5 100644
--- a/lib/megaco/doc/src/megaco_edist_compress.xml
+++ b/lib/megaco/doc/src/megaco_edist_compress.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_encode.xml b/lib/megaco/doc/src/megaco_encode.xml
index 2ceefed7e3..c916eb227f 100644
--- a/lib/megaco/doc/src/megaco_encode.xml
+++ b/lib/megaco/doc/src/megaco_encode.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_encoder.xml b/lib/megaco/doc/src/megaco_encoder.xml
index c7f7338204..9482ee643b 100644
--- a/lib/megaco/doc/src/megaco_encoder.xml
+++ b/lib/megaco/doc/src/megaco_encoder.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_examples.xml b/lib/megaco/doc/src/megaco_examples.xml
index 2ab33795a8..17b42c3fc9 100644
--- a/lib/megaco/doc/src/megaco_examples.xml
+++ b/lib/megaco/doc/src/megaco_examples.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_flex_scanner.xml b/lib/megaco/doc/src/megaco_flex_scanner.xml
index 7c32f1036b..68ff087afe 100644
--- a/lib/megaco/doc/src/megaco_flex_scanner.xml
+++ b/lib/megaco/doc/src/megaco_flex_scanner.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_intro.xml b/lib/megaco/doc/src/megaco_intro.xml
index 1399f28168..c33a74ebe5 100644
--- a/lib/megaco/doc/src/megaco_intro.xml
+++ b/lib/megaco/doc/src/megaco_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_mib.xml b/lib/megaco/doc/src/megaco_mib.xml
index cdc8b2f491..eb315014aa 100644
--- a/lib/megaco/doc/src/megaco_mib.xml
+++ b/lib/megaco/doc/src/megaco_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_performance.xml b/lib/megaco/doc/src/megaco_performance.xml
index 18dbb84a68..5f1558de4a 100644
--- a/lib/megaco/doc/src/megaco_performance.xml
+++ b/lib/megaco/doc/src/megaco_performance.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_run.xml b/lib/megaco/doc/src/megaco_run.xml
index 5bec4d779e..4a8fc1f7d0 100644
--- a/lib/megaco/doc/src/megaco_run.xml
+++ b/lib/megaco/doc/src/megaco_run.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_tcp.xml b/lib/megaco/doc/src/megaco_tcp.xml
index 7d487e0f91..95b391c0de 100644
--- a/lib/megaco/doc/src/megaco_tcp.xml
+++ b/lib/megaco/doc/src/megaco_tcp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_transport.xml b/lib/megaco/doc/src/megaco_transport.xml
index 8c60b00569..753d61a238 100644
--- a/lib/megaco/doc/src/megaco_transport.xml
+++ b/lib/megaco/doc/src/megaco_transport.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_transport_mechanisms.xml b/lib/megaco/doc/src/megaco_transport_mechanisms.xml
index c747732fe5..46d7113307 100644
--- a/lib/megaco/doc/src/megaco_transport_mechanisms.xml
+++ b/lib/megaco/doc/src/megaco_transport_mechanisms.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_udp.xml b/lib/megaco/doc/src/megaco_udp.xml
index 4352cc0430..63b908cc87 100644
--- a/lib/megaco/doc/src/megaco_udp.xml
+++ b/lib/megaco/doc/src/megaco_udp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/megaco_user.xml b/lib/megaco/doc/src/megaco_user.xml
index 44246935bb..9aae072896 100644
--- a/lib/megaco/doc/src/megaco_user.xml
+++ b/lib/megaco/doc/src/megaco_user.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index fd654af051..139a65b6fc 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -36,7 +37,22 @@
section is the version number of Megaco.</p>
- <section><title>Megaco 3.17.3</title>
+ <section><title>Megaco 3.18</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The runtime dependencies in the application resource
+ file have been updated. </p>
+ <p>
+ Own Id: OTP-12762</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Megaco 3.17.3</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/megaco/doc/src/notes_history.xml b/lib/megaco/doc/src/notes_history.xml
index 48ffd7d97a..33dba78257 100644
--- a/lib/megaco/doc/src/notes_history.xml
+++ b/lib/megaco/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/part.xml b/lib/megaco/doc/src/part.xml
index ed7368468e..f411013c01 100644
--- a/lib/megaco/doc/src/part.xml
+++ b/lib/megaco/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/part_notes.xml b/lib/megaco/doc/src/part_notes.xml
index 6783dd8616..26cc687247 100644
--- a/lib/megaco/doc/src/part_notes.xml
+++ b/lib/megaco/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/part_notes_history.xml b/lib/megaco/doc/src/part_notes_history.xml
index e5b64c7cd3..c51758284a 100644
--- a/lib/megaco/doc/src/part_notes_history.xml
+++ b/lib/megaco/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/doc/src/ref_man.xml b/lib/megaco/doc/src/ref_man.xml
index b7dbf66344..c855ae975d 100644
--- a/lib/megaco/doc/src/ref_man.xml
+++ b/lib/megaco/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/megaco/examples/meas/Makefile.in b/lib/megaco/examples/meas/Makefile.in
index 91e342cd9a..d9e7aee452 100644
--- a/lib/megaco/examples/meas/Makefile.in
+++ b/lib/megaco/examples/meas/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/examples/meas/meas.sh.skel.src b/lib/megaco/examples/meas/meas.sh.skel.src
index ecf463b9c6..a70e36f12f 100644
--- a/lib/megaco/examples/meas/meas.sh.skel.src
+++ b/lib/megaco/examples/meas/meas.sh.skel.src
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/megaco/examples/meas/megaco_codec_meas.erl b/lib/megaco/examples/meas/megaco_codec_meas.erl
index 5af40eea7d..009b085a3f 100644
--- a/lib/megaco/examples/meas/megaco_codec_meas.erl
+++ b/lib/megaco/examples/meas/megaco_codec_meas.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/meas/megaco_codec_mstone1.erl b/lib/megaco/examples/meas/megaco_codec_mstone1.erl
index 2133cd633c..1f73c97da4 100644
--- a/lib/megaco/examples/meas/megaco_codec_mstone1.erl
+++ b/lib/megaco/examples/meas/megaco_codec_mstone1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/meas/megaco_codec_mstone2.erl b/lib/megaco/examples/meas/megaco_codec_mstone2.erl
index 54b889345f..95a75b7d83 100644
--- a/lib/megaco/examples/meas/megaco_codec_mstone2.erl
+++ b/lib/megaco/examples/meas/megaco_codec_mstone2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl
index b527ff2e89..02092bd8be 100644
--- a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl
+++ b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/meas/megaco_codec_transform.erl b/lib/megaco/examples/meas/megaco_codec_transform.erl
index 7825e7856f..7182ccd621 100644
--- a/lib/megaco/examples/meas/megaco_codec_transform.erl
+++ b/lib/megaco/examples/meas/megaco_codec_transform.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/meas/modules.mk b/lib/megaco/examples/meas/modules.mk
index 26979933d7..1f4e359e08 100644
--- a/lib/megaco/examples/meas/modules.mk
+++ b/lib/megaco/examples/meas/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/examples/meas/mstone1.sh.skel.src b/lib/megaco/examples/meas/mstone1.sh.skel.src
index b1935acef6..088739f88b 100644
--- a/lib/megaco/examples/meas/mstone1.sh.skel.src
+++ b/lib/megaco/examples/meas/mstone1.sh.skel.src
@@ -5,16 +5,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/examples/simple/Makefile b/lib/megaco/examples/simple/Makefile
index 8ec9db71db..720e1b29d2 100644
--- a/lib/megaco/examples/simple/Makefile
+++ b/lib/megaco/examples/simple/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/examples/simple/megaco_simple_mg.erl b/lib/megaco/examples/simple/megaco_simple_mg.erl
index 95efaf5df3..3ad7bad8b1 100644
--- a/lib/megaco/examples/simple/megaco_simple_mg.erl
+++ b/lib/megaco/examples/simple/megaco_simple_mg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/simple/megaco_simple_mgc.erl b/lib/megaco/examples/simple/megaco_simple_mgc.erl
index 04493b983f..aea8890af7 100644
--- a/lib/megaco/examples/simple/megaco_simple_mgc.erl
+++ b/lib/megaco/examples/simple/megaco_simple_mgc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/examples/simple/modules.mk b/lib/megaco/examples/simple/modules.mk
index bcba5666a1..a2a2ac4324 100644
--- a/lib/megaco/examples/simple/modules.mk
+++ b/lib/megaco/examples/simple/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/include/megaco.hrl b/lib/megaco/include/megaco.hrl
index 87e830323f..2ea4029adf 100644
--- a/lib/megaco/include/megaco.hrl
+++ b/lib/megaco/include/megaco.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/include/megaco_message_prev3a.hrl b/lib/megaco/include/megaco_message_prev3a.hrl
index 3e73f94761..4ca4c4d1a2 100644
--- a/lib/megaco/include/megaco_message_prev3a.hrl
+++ b/lib/megaco/include/megaco_message_prev3a.hrl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/megaco/include/megaco_message_prev3b.hrl b/lib/megaco/include/megaco_message_prev3b.hrl
index b4bde2bb7e..e4e7fb9ed0 100644
--- a/lib/megaco/include/megaco_message_prev3b.hrl
+++ b/lib/megaco/include/megaco_message_prev3b.hrl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/megaco/include/megaco_message_prev3c.hrl b/lib/megaco/include/megaco_message_prev3c.hrl
index 90612f66c8..93a6728064 100644
--- a/lib/megaco/include/megaco_message_prev3c.hrl
+++ b/lib/megaco/include/megaco_message_prev3c.hrl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/megaco/include/megaco_message_v1.hrl b/lib/megaco/include/megaco_message_v1.hrl
index f196c26713..caf15c7041 100644
--- a/lib/megaco/include/megaco_message_v1.hrl
+++ b/lib/megaco/include/megaco_message_v1.hrl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/megaco/include/megaco_message_v2.hrl b/lib/megaco/include/megaco_message_v2.hrl
index af79c4dc92..05e2a551ae 100644
--- a/lib/megaco/include/megaco_message_v2.hrl
+++ b/lib/megaco/include/megaco_message_v2.hrl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/megaco/include/megaco_message_v3.hrl b/lib/megaco/include/megaco_message_v3.hrl
index 466cfa6856..9a52089005 100644
--- a/lib/megaco/include/megaco_message_v3.hrl
+++ b/lib/megaco/include/megaco_message_v3.hrl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/megaco/include/megaco_sdp.hrl b/lib/megaco/include/megaco_sdp.hrl
index e6d9f92edd..eaaf4cfde4 100644
--- a/lib/megaco/include/megaco_sdp.hrl
+++ b/lib/megaco/include/megaco_sdp.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/megaco/src/Makefile b/lib/megaco/src/Makefile
index d2d66d2c89..38211272c0 100644
--- a/lib/megaco/src/Makefile
+++ b/lib/megaco/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/app/Makefile b/lib/megaco/src/app/Makefile
index d18da5326a..8f8e6ecded 100644
--- a/lib/megaco/src/app/Makefile
+++ b/lib/megaco/src/app/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/app/depend.mk b/lib/megaco/src/app/depend.mk
index 27394d6f29..65ecdf25ad 100644
--- a/lib/megaco/src/app/depend.mk
+++ b/lib/megaco/src/app/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/app/megaco.app.src b/lib/megaco/src/app/megaco.app.src
index 6ab85a1bbc..c54c80351c 100644
--- a/lib/megaco/src/app/megaco.app.src
+++ b/lib/megaco/src/app/megaco.app.src
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -113,8 +114,8 @@
{applications, [stdlib, kernel]},
{env, []},
{mod, {megaco_sup, []}},
- {runtime_dependencies, ["stdlib-2.0","runtime_tools-1.8.14","kernel-3.0",
- "et-1.5","erts-6.0","debugger-4.0",
+ {runtime_dependencies, ["stdlib-2.5","runtime_tools-1.8.14","kernel-3.0",
+ "et-1.5","erts-7.0","debugger-4.0",
"asn1-3.0"]}
]}.
diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src
index 92504e8e87..93bf1d980c 100644
--- a/lib/megaco/src/app/megaco.appup.src
+++ b/lib/megaco/src/app/megaco.appup.src
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -183,11 +184,15 @@
%% |
%% v
%% 3.17.3
+%% |
+%% v
+%% 3.18
%%
%%
{"%VSN%",
[
+ {"3.17.3", [{restart_application,megaco}]},
{"3.17.2", []},
{"3.17.1", [{restart_application,megaco}]},
{"3.17.0.3", [{restart_application,megaco}]},
@@ -202,6 +207,7 @@
}
],
[
+ {"3.17.3", [{restart_application,megaco}]},
{"3.17.2", []},
{"3.17.1", [{restart_application,megaco}]},
{"3.17.0.3", [{restart_application,megaco}]},
diff --git a/lib/megaco/src/app/megaco.erl b/lib/megaco/src/app/megaco.erl
index 215a516d77..71d75e136d 100644
--- a/lib/megaco/src/app/megaco.erl
+++ b/lib/megaco/src/app/megaco.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/app/megaco.mk b/lib/megaco/src/app/megaco.mk
index 7bc276d26d..d6ad5eaf2e 100644
--- a/lib/megaco/src/app/megaco.mk
+++ b/lib/megaco/src/app/megaco.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/app/megaco_internal.hrl b/lib/megaco/src/app/megaco_internal.hrl
index 2c124e9060..9f0b41ae73 100644
--- a/lib/megaco/src/app/megaco_internal.hrl
+++ b/lib/megaco/src/app/megaco_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/app/modules.mk b/lib/megaco/src/app/modules.mk
index 42a2e94752..8eb7ddafbf 100644
--- a/lib/megaco/src/app/modules.mk
+++ b/lib/megaco/src/app/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/binary/Makefile b/lib/megaco/src/binary/Makefile
index c1fd66b848..711fbb7665 100644
--- a/lib/megaco/src/binary/Makefile
+++ b/lib/megaco/src/binary/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/binary/depend.mk b/lib/megaco/src/binary/depend.mk
index 4225bc69dc..64efe41503 100644
--- a/lib/megaco/src/binary/depend.mk
+++ b/lib/megaco/src/binary/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/binary/megaco_ber_encoder.erl b/lib/megaco/src/binary/megaco_ber_encoder.erl
index ff65b5bf81..de00a411af 100644
--- a/lib/megaco/src/binary/megaco_ber_encoder.erl
+++ b/lib/megaco/src/binary/megaco_ber_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_encoder.erl b/lib/megaco/src/binary/megaco_binary_encoder.erl
index abb496c173..c82e67280b 100644
--- a/lib/megaco/src/binary/megaco_binary_encoder.erl
+++ b/lib/megaco/src/binary/megaco_binary_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
index 7d82262a59..e9c4475b35 100644
--- a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
+++ b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl
index 24dc410dbe..60f48b1d45 100644
--- a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl
index d89717c00a..1fedd55915 100644
--- a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl
index 8b4192ad44..45b7bb365f 100644
--- a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl
index a748a1d0cc..35508fa13f 100644
--- a/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl
index 53891a26f2..a5d8a7a433 100644
--- a/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl
index 20954d4c9d..8b33d6c317 100644
--- a/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_term_id.erl b/lib/megaco/src/binary/megaco_binary_term_id.erl
index f975c1ab53..7416003158 100644
--- a/lib/megaco/src/binary/megaco_binary_term_id.erl
+++ b/lib/megaco/src/binary/megaco_binary_term_id.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_term_id_gen.erl b/lib/megaco/src/binary/megaco_binary_term_id_gen.erl
index c8192c79b6..c0e83702f2 100644
--- a/lib/megaco/src/binary/megaco_binary_term_id_gen.erl
+++ b/lib/megaco/src/binary/megaco_binary_term_id_gen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl
index ba4324f4f2..08bf461737 100644
--- a/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl
+++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl
index 8e42353b9b..26000e3ae6 100644
--- a/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl
+++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl
index c26d1fa99d..886bf20b93 100644
--- a/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl
+++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v1.erl b/lib/megaco/src/binary/megaco_binary_transformer_v1.erl
index 7236c0a9e1..105fb94a19 100644
--- a/lib/megaco/src/binary/megaco_binary_transformer_v1.erl
+++ b/lib/megaco/src/binary/megaco_binary_transformer_v1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v2.erl b/lib/megaco/src/binary/megaco_binary_transformer_v2.erl
index 686e384a29..6a205993ce 100644
--- a/lib/megaco/src/binary/megaco_binary_transformer_v2.erl
+++ b/lib/megaco/src/binary/megaco_binary_transformer_v2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v3.erl b/lib/megaco/src/binary/megaco_binary_transformer_v3.erl
index 1ff7c86e82..eed90aeaa9 100644
--- a/lib/megaco/src/binary/megaco_binary_transformer_v3.erl
+++ b/lib/megaco/src/binary/megaco_binary_transformer_v3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/megaco_per_encoder.erl b/lib/megaco/src/binary/megaco_per_encoder.erl
index 596e621c65..d82006f615 100644
--- a/lib/megaco/src/binary/megaco_per_encoder.erl
+++ b/lib/megaco/src/binary/megaco_per_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/modules.mk b/lib/megaco/src/binary/modules.mk
index d0765b7a6b..e4b0eac8d6 100644
--- a/lib/megaco/src/binary/modules.mk
+++ b/lib/megaco/src/binary/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl b/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl
index a9217940a1..76b4b4cdcf 100644
--- a/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl
+++ b/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl b/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl
index 0afe6d9f36..a256eebe54 100644
--- a/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl
+++ b/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/Makefile b/lib/megaco/src/engine/Makefile
index 7cecef1444..208942c3be 100644
--- a/lib/megaco/src/engine/Makefile
+++ b/lib/megaco/src/engine/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/engine/depend.mk b/lib/megaco/src/engine/depend.mk
index 935eb813e5..45e649b20d 100644
--- a/lib/megaco/src/engine/depend.mk
+++ b/lib/megaco/src/engine/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/engine/megaco_config.erl b/lib/megaco/src/engine/megaco_config.erl
index b65ddbe232..f6e977ac1e 100644
--- a/lib/megaco/src/engine/megaco_config.erl
+++ b/lib/megaco/src/engine/megaco_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/engine/megaco_config_misc.erl b/lib/megaco/src/engine/megaco_config_misc.erl
index 0a1601c766..fc0ea9cbc5 100644
--- a/lib/megaco/src/engine/megaco_config_misc.erl
+++ b/lib/megaco/src/engine/megaco_config_misc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/engine/megaco_digit_map.erl b/lib/megaco/src/engine/megaco_digit_map.erl
index bf798d7938..64ada63290 100644
--- a/lib/megaco/src/engine/megaco_digit_map.erl
+++ b/lib/megaco/src/engine/megaco_digit_map.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_edist_compress.erl b/lib/megaco/src/engine/megaco_edist_compress.erl
index 544e3b8ff0..e9329d7515 100644
--- a/lib/megaco/src/engine/megaco_edist_compress.erl
+++ b/lib/megaco/src/engine/megaco_edist_compress.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_encoder.erl b/lib/megaco/src/engine/megaco_encoder.erl
index a07ee1a6bc..1788d6cc42 100644
--- a/lib/megaco/src/engine/megaco_encoder.erl
+++ b/lib/megaco/src/engine/megaco_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_erl_dist_encoder.erl b/lib/megaco/src/engine/megaco_erl_dist_encoder.erl
index e8ade615df..22c07d48ac 100644
--- a/lib/megaco/src/engine/megaco_erl_dist_encoder.erl
+++ b/lib/megaco/src/engine/megaco_erl_dist_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_erl_dist_encoder_mc.erl b/lib/megaco/src/engine/megaco_erl_dist_encoder_mc.erl
index 52395ae516..b8d7625d48 100644
--- a/lib/megaco/src/engine/megaco_erl_dist_encoder_mc.erl
+++ b/lib/megaco/src/engine/megaco_erl_dist_encoder_mc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_filter.erl b/lib/megaco/src/engine/megaco_filter.erl
index fb0c700a82..0f48844945 100644
--- a/lib/megaco/src/engine/megaco_filter.erl
+++ b/lib/megaco/src/engine/megaco_filter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/engine/megaco_message_internal.hrl b/lib/megaco/src/engine/megaco_message_internal.hrl
index 44f38752a9..40990190bd 100644
--- a/lib/megaco/src/engine/megaco_message_internal.hrl
+++ b/lib/megaco/src/engine/megaco_message_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_messenger.erl b/lib/megaco/src/engine/megaco_messenger.erl
index 5fad29931b..27688132fd 100644
--- a/lib/megaco/src/engine/megaco_messenger.erl
+++ b/lib/megaco/src/engine/megaco_messenger.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/engine/megaco_messenger_misc.erl b/lib/megaco/src/engine/megaco_messenger_misc.erl
index 3c340a8484..bdb97c7630 100644
--- a/lib/megaco/src/engine/megaco_messenger_misc.erl
+++ b/lib/megaco/src/engine/megaco_messenger_misc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_misc_sup.erl b/lib/megaco/src/engine/megaco_misc_sup.erl
index 07fe96871d..8ad3f3ba43 100644
--- a/lib/megaco/src/engine/megaco_misc_sup.erl
+++ b/lib/megaco/src/engine/megaco_misc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_monitor.erl b/lib/megaco/src/engine/megaco_monitor.erl
index 29275371be..267f41ca15 100644
--- a/lib/megaco/src/engine/megaco_monitor.erl
+++ b/lib/megaco/src/engine/megaco_monitor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/engine/megaco_sdp.erl b/lib/megaco/src/engine/megaco_sdp.erl
index 96732584fb..1c1daa5c1c 100644
--- a/lib/megaco/src/engine/megaco_sdp.erl
+++ b/lib/megaco/src/engine/megaco_sdp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_stats.erl b/lib/megaco/src/engine/megaco_stats.erl
index af180fb9d6..746a3bd2f0 100644
--- a/lib/megaco/src/engine/megaco_stats.erl
+++ b/lib/megaco/src/engine/megaco_stats.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_sup.erl b/lib/megaco/src/engine/megaco_sup.erl
index c61a1da298..c7059e91d5 100644
--- a/lib/megaco/src/engine/megaco_sup.erl
+++ b/lib/megaco/src/engine/megaco_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_timer.erl b/lib/megaco/src/engine/megaco_timer.erl
index 1336be0b5b..c7367d939c 100644
--- a/lib/megaco/src/engine/megaco_timer.erl
+++ b/lib/megaco/src/engine/megaco_timer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_trans_sender.erl b/lib/megaco/src/engine/megaco_trans_sender.erl
index 710fef405a..98f6809f02 100644
--- a/lib/megaco/src/engine/megaco_trans_sender.erl
+++ b/lib/megaco/src/engine/megaco_trans_sender.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -672,8 +673,7 @@ to(To, Start) ->
%% Time in milli seconds
t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
+ erlang:monotonic_time(milli_seconds).
warning_msg(F, A) ->
?megaco_warning("Transaction sender: " ++ F, A).
diff --git a/lib/megaco/src/engine/megaco_trans_sup.erl b/lib/megaco/src/engine/megaco_trans_sup.erl
index 6c4a0b7145..6015a63ca3 100644
--- a/lib/megaco/src/engine/megaco_trans_sup.erl
+++ b/lib/megaco/src/engine/megaco_trans_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_transport.erl b/lib/megaco/src/engine/megaco_transport.erl
index 79cec8781c..d6c9fa632b 100644
--- a/lib/megaco/src/engine/megaco_transport.erl
+++ b/lib/megaco/src/engine/megaco_transport.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/megaco_user_default.erl b/lib/megaco/src/engine/megaco_user_default.erl
index ff98107d57..907f3bebb9 100644
--- a/lib/megaco/src/engine/megaco_user_default.erl
+++ b/lib/megaco/src/engine/megaco_user_default.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/engine/modules.mk b/lib/megaco/src/engine/modules.mk
index e6e5e29829..e2fd495342 100644
--- a/lib/megaco/src/engine/modules.mk
+++ b/lib/megaco/src/engine/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/flex/Makefile b/lib/megaco/src/flex/Makefile
index ab8183e548..ee366bdda0 100644
--- a/lib/megaco/src/flex/Makefile
+++ b/lib/megaco/src/flex/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/flex/Makefile.in b/lib/megaco/src/flex/Makefile.in
index 6111cf2304..045b6d871a 100644
--- a/lib/megaco/src/flex/Makefile.in
+++ b/lib/megaco/src/flex/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/megaco/src/flex/megaco_flex_scanner.erl b/lib/megaco/src/flex/megaco_flex_scanner.erl
index 508f8905e7..921926211d 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner.erl
+++ b/lib/megaco/src/flex/megaco_flex_scanner.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
index 90d5c2aae6..0ac15fae4a 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
+++ b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
@@ -1,28 +1,29 @@
- /*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-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%
- *
- * ----------------------------------------------------------------------
- * Purpose : Scanner for text encoded Megaco/H.248 messages
- * ----------------------------------------------------------------------
- *
- * Throughout this file the prefix mfs is used for megaco_flex_scanner.
- * The reason is to get shorter function and variable names.
- */
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2013. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.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 : Scanner for text encoded Megaco/H.248 messages
+ * ----------------------------------------------------------------------
+ *
+ * Throughout this file the prefix mfs is used for megaco_flex_scanner.
+ * The reason is to get shorter function and variable names.
+ */
%option case-insensitive
diff --git a/lib/megaco/src/flex/megaco_flex_scanner_handler.erl b/lib/megaco/src/flex/megaco_flex_scanner_handler.erl
index ad28e25c39..1f7c127ccf 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner_handler.erl
+++ b/lib/megaco/src/flex/megaco_flex_scanner_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/src/flex/modules.mk b/lib/megaco/src/flex/modules.mk
index fb9957cffd..e317b2ea51 100644
--- a/lib/megaco/src/flex/modules.mk
+++ b/lib/megaco/src/flex/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/rules.mk b/lib/megaco/src/rules.mk
index d9473af26e..1ac98a16a1 100644
--- a/lib/megaco/src/rules.mk
+++ b/lib/megaco/src/rules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1999-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/subdirs.mk b/lib/megaco/src/subdirs.mk
index af1a679561..abc1b88758 100644
--- a/lib/megaco/src/subdirs.mk
+++ b/lib/megaco/src/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/tcp/Makefile b/lib/megaco/src/tcp/Makefile
index 0c30abae2c..0c546a881f 100644
--- a/lib/megaco/src/tcp/Makefile
+++ b/lib/megaco/src/tcp/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/tcp/depend.mk b/lib/megaco/src/tcp/depend.mk
index 27b0feec94..a5f5f9b844 100644
--- a/lib/megaco/src/tcp/depend.mk
+++ b/lib/megaco/src/tcp/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2007-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/tcp/megaco_tcp.erl b/lib/megaco/src/tcp/megaco_tcp.erl
index 45fd35eabc..25b7902c0b 100644
--- a/lib/megaco/src/tcp/megaco_tcp.erl
+++ b/lib/megaco/src/tcp/megaco_tcp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/megaco_tcp.hrl b/lib/megaco/src/tcp/megaco_tcp.hrl
index 5de1dd9070..37963a7099 100644
--- a/lib/megaco/src/tcp/megaco_tcp.hrl
+++ b/lib/megaco/src/tcp/megaco_tcp.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/megaco_tcp_accept.erl b/lib/megaco/src/tcp/megaco_tcp_accept.erl
index 68bda8a340..f3e45d8cd4 100644
--- a/lib/megaco/src/tcp/megaco_tcp_accept.erl
+++ b/lib/megaco/src/tcp/megaco_tcp_accept.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/megaco_tcp_accept_sup.erl b/lib/megaco/src/tcp/megaco_tcp_accept_sup.erl
index a601f32558..9a8369edd2 100644
--- a/lib/megaco/src/tcp/megaco_tcp_accept_sup.erl
+++ b/lib/megaco/src/tcp/megaco_tcp_accept_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/megaco_tcp_connection.erl b/lib/megaco/src/tcp/megaco_tcp_connection.erl
index 614edf513a..962c5928c1 100644
--- a/lib/megaco/src/tcp/megaco_tcp_connection.erl
+++ b/lib/megaco/src/tcp/megaco_tcp_connection.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/megaco_tcp_connection_sup.erl b/lib/megaco/src/tcp/megaco_tcp_connection_sup.erl
index 0ca8697418..7c9ed0b17e 100644
--- a/lib/megaco/src/tcp/megaco_tcp_connection_sup.erl
+++ b/lib/megaco/src/tcp/megaco_tcp_connection_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/megaco_tcp_sup.erl b/lib/megaco/src/tcp/megaco_tcp_sup.erl
index 6afc7582ec..aa8c9da539 100644
--- a/lib/megaco/src/tcp/megaco_tcp_sup.erl
+++ b/lib/megaco/src/tcp/megaco_tcp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/tcp/modules.mk b/lib/megaco/src/tcp/modules.mk
index 505bd67792..eb21eef60f 100644
--- a/lib/megaco/src/tcp/modules.mk
+++ b/lib/megaco/src/tcp/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/text/Makefile b/lib/megaco/src/text/Makefile
index cab4256e68..f4fc56a27d 100644
--- a/lib/megaco/src/text/Makefile
+++ b/lib/megaco/src/text/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/text/depend.mk b/lib/megaco/src/text/depend.mk
index 62d0811692..8eac5f9e3f 100644
--- a/lib/megaco/src/text/depend.mk
+++ b/lib/megaco/src/text/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder.erl b/lib/megaco/src/text/megaco_compact_text_encoder.erl
index f5195bda14..799759d97b 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder_prev3a.erl b/lib/megaco/src/text/megaco_compact_text_encoder_prev3a.erl
index a45d35cc43..77078a586b 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder_prev3a.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder_prev3a.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder_prev3b.erl b/lib/megaco/src/text/megaco_compact_text_encoder_prev3b.erl
index 63f76040ce..90d8e671bc 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder_prev3b.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder_prev3b.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder_prev3c.erl b/lib/megaco/src/text/megaco_compact_text_encoder_prev3c.erl
index 10d7b7e732..210a8d2161 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder_prev3c.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder_prev3c.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder_v1.erl b/lib/megaco/src/text/megaco_compact_text_encoder_v1.erl
index c1b454dc0f..e88fc67db3 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder_v1.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder_v1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder_v2.erl b/lib/megaco/src/text/megaco_compact_text_encoder_v2.erl
index ac0877da2f..d75bcd8a0d 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder_v2.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder_v2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_compact_text_encoder_v3.erl b/lib/megaco/src/text/megaco_compact_text_encoder_v3.erl
index 5dd239222b..8e1076a8fe 100644
--- a/lib/megaco/src/text/megaco_compact_text_encoder_v3.erl
+++ b/lib/megaco/src/text/megaco_compact_text_encoder_v3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder.erl b/lib/megaco/src/text/megaco_pretty_text_encoder.erl
index 6a9a7df041..03246a50f7 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder_prev3a.erl b/lib/megaco/src/text/megaco_pretty_text_encoder_prev3a.erl
index 6f42bf963c..dbf2c44e6f 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder_prev3a.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder_prev3a.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder_prev3b.erl b/lib/megaco/src/text/megaco_pretty_text_encoder_prev3b.erl
index 44bdc4690d..a3f9c09783 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder_prev3b.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder_prev3b.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder_prev3c.erl b/lib/megaco/src/text/megaco_pretty_text_encoder_prev3c.erl
index 1511056f00..832e6cf9ec 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder_prev3c.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder_prev3c.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder_v1.erl b/lib/megaco/src/text/megaco_pretty_text_encoder_v1.erl
index 6f65bc7337..2d6e69dc17 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder_v1.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder_v1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder_v2.erl b/lib/megaco/src/text/megaco_pretty_text_encoder_v2.erl
index 37c067b937..93a855b540 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder_v2.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder_v2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_pretty_text_encoder_v3.erl b/lib/megaco/src/text/megaco_pretty_text_encoder_v3.erl
index 833b6ea00f..9ca7f6012b 100644
--- a/lib/megaco/src/text/megaco_pretty_text_encoder_v3.erl
+++ b/lib/megaco/src/text/megaco_pretty_text_encoder_v3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_gen_prev3a.hrl b/lib/megaco/src/text/megaco_text_gen_prev3a.hrl
index 81916cb9ec..d5eaaf622d 100644
--- a/lib/megaco/src/text/megaco_text_gen_prev3a.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_prev3a.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_gen_prev3b.hrl b/lib/megaco/src/text/megaco_text_gen_prev3b.hrl
index 83d25c83c9..95478fac89 100644
--- a/lib/megaco/src/text/megaco_text_gen_prev3b.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_prev3b.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_gen_prev3c.hrl b/lib/megaco/src/text/megaco_text_gen_prev3c.hrl
index 458809ca75..b1299c2a4d 100644
--- a/lib/megaco/src/text/megaco_text_gen_prev3c.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_prev3c.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_gen_v1.hrl b/lib/megaco/src/text/megaco_text_gen_v1.hrl
index 0726d68941..0399a5449b 100644
--- a/lib/megaco/src/text/megaco_text_gen_v1.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_v1.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_gen_v2.hrl b/lib/megaco/src/text/megaco_text_gen_v2.hrl
index 8e12efe65a..35130d5229 100644
--- a/lib/megaco/src/text/megaco_text_gen_v2.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_v2.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_gen_v3.hrl b/lib/megaco/src/text/megaco_text_gen_v3.hrl
index ce2e5e508d..409803d17a 100644
--- a/lib/megaco/src/text/megaco_text_gen_v3.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_v3.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_mini_decoder.erl b/lib/megaco/src/text/megaco_text_mini_decoder.erl
index 6e1bf9295a..5a8516bfbc 100644
--- a/lib/megaco/src/text/megaco_text_mini_decoder.erl
+++ b/lib/megaco/src/text/megaco_text_mini_decoder.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_mini_parser.hrl b/lib/megaco/src/text/megaco_text_mini_parser.hrl
index bb6ee43247..9f276b9682 100644
--- a/lib/megaco/src/text/megaco_text_mini_parser.hrl
+++ b/lib/megaco/src/text/megaco_text_mini_parser.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_mini_parser.yrl b/lib/megaco/src/text/megaco_text_mini_parser.yrl
index 50e31b9eb4..5a0983b439 100644
--- a/lib/megaco/src/text/megaco_text_mini_parser.yrl
+++ b/lib/megaco/src/text/megaco_text_mini_parser.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_prev3a.hrl b/lib/megaco/src/text/megaco_text_parser_prev3a.hrl
index 7faf46afc8..2b1b9f3145 100644
--- a/lib/megaco/src/text/megaco_text_parser_prev3a.hrl
+++ b/lib/megaco/src/text/megaco_text_parser_prev3a.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_prev3a.yrl b/lib/megaco/src/text/megaco_text_parser_prev3a.yrl
index b8c39a5f33..6ce82514d3 100644
--- a/lib/megaco/src/text/megaco_text_parser_prev3a.yrl
+++ b/lib/megaco/src/text/megaco_text_parser_prev3a.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_prev3b.hrl b/lib/megaco/src/text/megaco_text_parser_prev3b.hrl
index ba10dfb943..bca64ac37e 100644
--- a/lib/megaco/src/text/megaco_text_parser_prev3b.hrl
+++ b/lib/megaco/src/text/megaco_text_parser_prev3b.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_prev3b.yrl b/lib/megaco/src/text/megaco_text_parser_prev3b.yrl
index d660fb787a..6fc23dae82 100644
--- a/lib/megaco/src/text/megaco_text_parser_prev3b.yrl
+++ b/lib/megaco/src/text/megaco_text_parser_prev3b.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_prev3c.hrl b/lib/megaco/src/text/megaco_text_parser_prev3c.hrl
index ab099e5a24..89dc6accbd 100644
--- a/lib/megaco/src/text/megaco_text_parser_prev3c.hrl
+++ b/lib/megaco/src/text/megaco_text_parser_prev3c.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_prev3c.yrl b/lib/megaco/src/text/megaco_text_parser_prev3c.yrl
index 9b7984deab..42a8ae627d 100644
--- a/lib/megaco/src/text/megaco_text_parser_prev3c.yrl
+++ b/lib/megaco/src/text/megaco_text_parser_prev3c.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_v1.hrl b/lib/megaco/src/text/megaco_text_parser_v1.hrl
index ebc43c0352..b5913d01f3 100644
--- a/lib/megaco/src/text/megaco_text_parser_v1.hrl
+++ b/lib/megaco/src/text/megaco_text_parser_v1.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_v1.yrl b/lib/megaco/src/text/megaco_text_parser_v1.yrl
index fd50d90523..c231cdf7ca 100644
--- a/lib/megaco/src/text/megaco_text_parser_v1.yrl
+++ b/lib/megaco/src/text/megaco_text_parser_v1.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_v2.hrl b/lib/megaco/src/text/megaco_text_parser_v2.hrl
index e968db398d..0615c75ba1 100644
--- a/lib/megaco/src/text/megaco_text_parser_v2.hrl
+++ b/lib/megaco/src/text/megaco_text_parser_v2.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_v2.yrl b/lib/megaco/src/text/megaco_text_parser_v2.yrl
index 8152cc4e9b..09e87c59ab 100644
--- a/lib/megaco/src/text/megaco_text_parser_v2.yrl
+++ b/lib/megaco/src/text/megaco_text_parser_v2.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_v3.hrl b/lib/megaco/src/text/megaco_text_parser_v3.hrl
index 9f68fb6127..efe81c9e7a 100644
--- a/lib/megaco/src/text/megaco_text_parser_v3.hrl
+++ b/lib/megaco/src/text/megaco_text_parser_v3.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_parser_v3.yrl b/lib/megaco/src/text/megaco_text_parser_v3.yrl
index d400a93c66..dc5cd5bcc7 100644
--- a/lib/megaco/src/text/megaco_text_parser_v3.yrl
+++ b/lib/megaco/src/text/megaco_text_parser_v3.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_scanner.erl b/lib/megaco/src/text/megaco_text_scanner.erl
index 8559941e5f..790b2beb33 100644
--- a/lib/megaco/src/text/megaco_text_scanner.erl
+++ b/lib/megaco/src/text/megaco_text_scanner.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/megaco_text_tokens.hrl b/lib/megaco/src/text/megaco_text_tokens.hrl
index 14f59c3f06..28c07e91a2 100644
--- a/lib/megaco/src/text/megaco_text_tokens.hrl
+++ b/lib/megaco/src/text/megaco_text_tokens.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/text/modules.mk b/lib/megaco/src/text/modules.mk
index c493c978a8..09aebb7c6e 100644
--- a/lib/megaco/src/text/modules.mk
+++ b/lib/megaco/src/text/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/udp/Makefile b/lib/megaco/src/udp/Makefile
index 9486804d38..7288c205f0 100644
--- a/lib/megaco/src/udp/Makefile
+++ b/lib/megaco/src/udp/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/src/udp/megaco_udp.erl b/lib/megaco/src/udp/megaco_udp.erl
index c75b703949..b7a1eb3e2d 100644
--- a/lib/megaco/src/udp/megaco_udp.erl
+++ b/lib/megaco/src/udp/megaco_udp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/udp/megaco_udp.hrl b/lib/megaco/src/udp/megaco_udp.hrl
index d0b9ec1916..7e36fa144b 100644
--- a/lib/megaco/src/udp/megaco_udp.hrl
+++ b/lib/megaco/src/udp/megaco_udp.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/udp/megaco_udp_server.erl b/lib/megaco/src/udp/megaco_udp_server.erl
index f126043141..537a0ad8df 100644
--- a/lib/megaco/src/udp/megaco_udp_server.erl
+++ b/lib/megaco/src/udp/megaco_udp_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/udp/megaco_udp_sup.erl b/lib/megaco/src/udp/megaco_udp_sup.erl
index 6a381c22d8..aed5ec11d8 100644
--- a/lib/megaco/src/udp/megaco_udp_sup.erl
+++ b/lib/megaco/src/udp/megaco_udp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/src/udp/modules.mk b/lib/megaco/src/udp/modules.mk
index 47126f6207..6a9618cefe 100644
--- a/lib/megaco/src/udp/modules.mk
+++ b/lib/megaco/src/udp/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/subdirs.mk b/lib/megaco/subdirs.mk
index 8c20c3e815..cdc6d7b9c4 100644
--- a/lib/megaco/subdirs.mk
+++ b/lib/megaco/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/megaco/test/Makefile b/lib/megaco/test/Makefile
index b78f21f608..06ecc06d20 100644
--- a/lib/megaco/test/Makefile
+++ b/lib/megaco/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/megaco/test/megaco_SUITE.erl b/lib/megaco/test/megaco_SUITE.erl
index 007677ba4d..1cd6a78d07 100644
--- a/lib/megaco/test/megaco_SUITE.erl
+++ b/lib/megaco/test/megaco_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_actions_test.erl b/lib/megaco/test/megaco_actions_test.erl
index cdf11f09cc..b554622a27 100644
--- a/lib/megaco/test/megaco_actions_test.erl
+++ b/lib/megaco/test/megaco_actions_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_app_test.erl b/lib/megaco/test/megaco_app_test.erl
index 00f7b7fb68..78ca2d4774 100644
--- a/lib/megaco/test/megaco_app_test.erl
+++ b/lib/megaco/test/megaco_app_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/test/megaco_appup_mg.erl b/lib/megaco/test/megaco_appup_mg.erl
index bb8b098f5d..3ff051b0bc 100644
--- a/lib/megaco/test/megaco_appup_mg.erl
+++ b/lib/megaco/test/megaco_appup_mg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_appup_mgc.erl b/lib/megaco/test/megaco_appup_mgc.erl
index 49c5f24852..90e27e8728 100644
--- a/lib/megaco/test/megaco_appup_mgc.erl
+++ b/lib/megaco/test/megaco_appup_mgc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_appup_test.erl b/lib/megaco/test/megaco_appup_test.erl
index fce6cf3cba..7809dd4e09 100644
--- a/lib/megaco/test/megaco_appup_test.erl
+++ b/lib/megaco/test/megaco_appup_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_binary_term_id_test.erl b/lib/megaco/test/megaco_binary_term_id_test.erl
index 47a7a76c1c..47520bafe1 100644
--- a/lib/megaco/test/megaco_binary_term_id_test.erl
+++ b/lib/megaco/test/megaco_binary_term_id_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_call_flow_test.erl b/lib/megaco/test/megaco_call_flow_test.erl
index 8ad1cf6445..2c3a08ca0a 100644
--- a/lib/megaco/test/megaco_call_flow_test.erl
+++ b/lib/megaco/test/megaco_call_flow_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_flex_lib.erl b/lib/megaco/test/megaco_codec_flex_lib.erl
index 3e70454faf..13ee8e824a 100644
--- a/lib/megaco/test/megaco_codec_flex_lib.erl
+++ b/lib/megaco/test/megaco_codec_flex_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_mini_test.erl b/lib/megaco/test/megaco_codec_mini_test.erl
index ff0c154c7c..536ac51798 100644
--- a/lib/megaco/test/megaco_codec_mini_test.erl
+++ b/lib/megaco/test/megaco_codec_mini_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_prev3a_test.erl b/lib/megaco/test/megaco_codec_prev3a_test.erl
index 9c4ed385a6..6486a8eaf9 100644
--- a/lib/megaco/test/megaco_codec_prev3a_test.erl
+++ b/lib/megaco/test/megaco_codec_prev3a_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_prev3b_test.erl b/lib/megaco/test/megaco_codec_prev3b_test.erl
index 36df434e80..04614df545 100644
--- a/lib/megaco/test/megaco_codec_prev3b_test.erl
+++ b/lib/megaco/test/megaco_codec_prev3b_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_prev3c_test.erl b/lib/megaco/test/megaco_codec_prev3c_test.erl
index 3f715cbb7e..cb3efa7cf9 100644
--- a/lib/megaco/test/megaco_codec_prev3c_test.erl
+++ b/lib/megaco/test/megaco_codec_prev3c_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_test.erl b/lib/megaco/test/megaco_codec_test.erl
index 8391024c3f..118937fc6f 100644
--- a/lib/megaco/test/megaco_codec_test.erl
+++ b/lib/megaco/test/megaco_codec_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_test_lib.erl b/lib/megaco/test/megaco_codec_test_lib.erl
index 0a903f5617..dcae348e89 100644
--- a/lib/megaco/test/megaco_codec_test_lib.erl
+++ b/lib/megaco/test/megaco_codec_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_v1_test.erl b/lib/megaco/test/megaco_codec_v1_test.erl
index d1a1d31da0..a0ddacc20a 100644
--- a/lib/megaco/test/megaco_codec_v1_test.erl
+++ b/lib/megaco/test/megaco_codec_v1_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_v2_test.erl b/lib/megaco/test/megaco_codec_v2_test.erl
index d1fb22cbee..afdfc48900 100644
--- a/lib/megaco/test/megaco_codec_v2_test.erl
+++ b/lib/megaco/test/megaco_codec_v2_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_codec_v3_test.erl b/lib/megaco/test/megaco_codec_v3_test.erl
index 84cc863300..4c7e17d10a 100644
--- a/lib/megaco/test/megaco_codec_v3_test.erl
+++ b/lib/megaco/test/megaco_codec_v3_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_config_test.erl b/lib/megaco/test/megaco_config_test.erl
index 1fc4d09d3b..1f619856f8 100644
--- a/lib/megaco/test/megaco_config_test.erl
+++ b/lib/megaco/test/megaco_config_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/megaco/test/megaco_digit_map_test.erl b/lib/megaco/test/megaco_digit_map_test.erl
index d16fb679ae..72426d2305 100644
--- a/lib/megaco/test/megaco_digit_map_test.erl
+++ b/lib/megaco/test/megaco_digit_map_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_examples_test.erl b/lib/megaco/test/megaco_examples_test.erl
index 528b61c2af..ddaad4be3c 100644
--- a/lib/megaco/test/megaco_examples_test.erl
+++ b/lib/megaco/test/megaco_examples_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_flex_test.erl b/lib/megaco/test/megaco_flex_test.erl
index d7fc8eacb5..928ff719cf 100644
--- a/lib/megaco/test/megaco_flex_test.erl
+++ b/lib/megaco/test/megaco_flex_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_load_test.erl b/lib/megaco/test/megaco_load_test.erl
index 5519ca15c6..9599a5221d 100644
--- a/lib/megaco/test/megaco_load_test.erl
+++ b/lib/megaco/test/megaco_load_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_mess_otp8212_test.erl b/lib/megaco/test/megaco_mess_otp8212_test.erl
index e074e2f0b3..25c21bea35 100644
--- a/lib/megaco/test/megaco_mess_otp8212_test.erl
+++ b/lib/megaco/test/megaco_mess_otp8212_test.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_mess_test.erl b/lib/megaco/test/megaco_mess_test.erl
index f8be96c254..2f11a6ba1b 100644
--- a/lib/megaco/test/megaco_mess_test.erl
+++ b/lib/megaco/test/megaco_mess_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_mess_user_test.erl b/lib/megaco/test/megaco_mess_user_test.erl
index ce682c167b..4c284af93e 100644
--- a/lib/megaco/test/megaco_mess_user_test.erl
+++ b/lib/megaco/test/megaco_mess_user_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_mib_test.erl b/lib/megaco/test/megaco_mib_test.erl
index 96d7248726..be6741439d 100644
--- a/lib/megaco/test/megaco_mib_test.erl
+++ b/lib/megaco/test/megaco_mib_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_mreq_test.erl b/lib/megaco/test/megaco_mreq_test.erl
index 1d3f38d50d..2d6d936f75 100644
--- a/lib/megaco/test/megaco_mreq_test.erl
+++ b/lib/megaco/test/megaco_mreq_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_pending_limit_test.erl b/lib/megaco/test/megaco_pending_limit_test.erl
index 233c22f4d2..5440fadec8 100644
--- a/lib/megaco/test/megaco_pending_limit_test.erl
+++ b/lib/megaco/test/megaco_pending_limit_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_profile.erl b/lib/megaco/test/megaco_profile.erl
index fd72604e92..86daad173c 100644
--- a/lib/megaco/test/megaco_profile.erl
+++ b/lib/megaco/test/megaco_profile.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_sdp_test.erl b/lib/megaco/test/megaco_sdp_test.erl
index 796a956f23..95ada63273 100644
--- a/lib/megaco/test/megaco_sdp_test.erl
+++ b/lib/megaco/test/megaco_sdp_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_segment_test.erl b/lib/megaco/test/megaco_segment_test.erl
index e4b568119d..abd63ac00f 100644
--- a/lib/megaco/test/megaco_segment_test.erl
+++ b/lib/megaco/test/megaco_segment_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_tc_controller.erl b/lib/megaco/test/megaco_tc_controller.erl
index 458bff55e8..979c2e3be8 100644
--- a/lib/megaco/test/megaco_tc_controller.erl
+++ b/lib/megaco/test/megaco_tc_controller.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_tcp_test.erl b/lib/megaco/test/megaco_tcp_test.erl
index 013096c385..c72f4f07b0 100644
--- a/lib/megaco/test/megaco_tcp_test.erl
+++ b/lib/megaco/test/megaco_tcp_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_deliver.erl b/lib/megaco/test/megaco_test_deliver.erl
index ece0a48015..307caad73b 100644
--- a/lib/megaco/test/megaco_test_deliver.erl
+++ b/lib/megaco/test/megaco_test_deliver.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_generator.erl b/lib/megaco/test/megaco_test_generator.erl
index 4fbc86262e..7f9714aec9 100644
--- a/lib/megaco/test/megaco_test_generator.erl
+++ b/lib/megaco/test/megaco_test_generator.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_generator_lib.erl b/lib/megaco/test/megaco_test_generator_lib.erl
index 1584605913..fd9dd1c491 100644
--- a/lib/megaco/test/megaco_test_generator_lib.erl
+++ b/lib/megaco/test/megaco_test_generator_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_generic_transport.erl b/lib/megaco/test/megaco_test_generic_transport.erl
index 7a3dbc5317..81ea3e728e 100644
--- a/lib/megaco/test/megaco_test_generic_transport.erl
+++ b/lib/megaco/test/megaco_test_generic_transport.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_lib.erl b/lib/megaco/test/megaco_test_lib.erl
index 41b49f6d30..2339955e55 100644
--- a/lib/megaco/test/megaco_test_lib.erl
+++ b/lib/megaco/test/megaco_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_lib.hrl b/lib/megaco/test/megaco_test_lib.hrl
index b92474d7b8..e066b805e6 100644
--- a/lib/megaco/test/megaco_test_lib.hrl
+++ b/lib/megaco/test/megaco_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_megaco_generator.erl b/lib/megaco/test/megaco_test_megaco_generator.erl
index f0c723d2cf..07b9a806f4 100644
--- a/lib/megaco/test/megaco_test_megaco_generator.erl
+++ b/lib/megaco/test/megaco_test_megaco_generator.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_mg.erl b/lib/megaco/test/megaco_test_mg.erl
index cc1d2dd1b9..667e5babdb 100644
--- a/lib/megaco/test/megaco_test_mg.erl
+++ b/lib/megaco/test/megaco_test_mg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_mgc.erl b/lib/megaco/test/megaco_test_mgc.erl
index d9183f847e..8b6fe3f611 100644
--- a/lib/megaco/test/megaco_test_mgc.erl
+++ b/lib/megaco/test/megaco_test_mgc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_msg_prev3a_lib.erl b/lib/megaco/test/megaco_test_msg_prev3a_lib.erl
index fad7f29831..6bdb82ce06 100644
--- a/lib/megaco/test/megaco_test_msg_prev3a_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_prev3a_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_msg_prev3b_lib.erl b/lib/megaco/test/megaco_test_msg_prev3b_lib.erl
index 2f1a093728..6fc8e8de35 100644
--- a/lib/megaco/test/megaco_test_msg_prev3b_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_prev3b_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_msg_prev3c_lib.erl b/lib/megaco/test/megaco_test_msg_prev3c_lib.erl
index 884e2f2bad..3eff0d9a59 100644
--- a/lib/megaco/test/megaco_test_msg_prev3c_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_prev3c_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_msg_v1_lib.erl b/lib/megaco/test/megaco_test_msg_v1_lib.erl
index 76665cb575..03f3561218 100644
--- a/lib/megaco/test/megaco_test_msg_v1_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_v1_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_msg_v2_lib.erl b/lib/megaco/test/megaco_test_msg_v2_lib.erl
index 66e423284a..27f65faf32 100644
--- a/lib/megaco/test/megaco_test_msg_v2_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_v2_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_msg_v3_lib.erl b/lib/megaco/test/megaco_test_msg_v3_lib.erl
index 24492167ff..e214215b10 100644
--- a/lib/megaco/test/megaco_test_msg_v3_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_v3_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_test_tcp_generator.erl b/lib/megaco/test/megaco_test_tcp_generator.erl
index 3ed4c49bab..2ee0259a9a 100644
--- a/lib/megaco/test/megaco_test_tcp_generator.erl
+++ b/lib/megaco/test/megaco_test_tcp_generator.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_timer_test.erl b/lib/megaco/test/megaco_timer_test.erl
index 9b9103c40b..bd64fe9c17 100644
--- a/lib/megaco/test/megaco_timer_test.erl
+++ b/lib/megaco/test/megaco_timer_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_trans_test.erl b/lib/megaco/test/megaco_trans_test.erl
index 5f564e3bf6..ef527662af 100644
--- a/lib/megaco/test/megaco_trans_test.erl
+++ b/lib/megaco/test/megaco_trans_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/megaco_udp_test.erl b/lib/megaco/test/megaco_udp_test.erl
index ffbff9b762..b461925d94 100644
--- a/lib/megaco/test/megaco_udp_test.erl
+++ b/lib/megaco/test/megaco_udp_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/megaco/test/modules.mk b/lib/megaco/test/modules.mk
index 049d8babe2..3e56dfdc9c 100644
--- a/lib/megaco/test/modules.mk
+++ b/lib/megaco/test/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index 8687d622e9..2e850f2917 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -2,22 +2,23 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2014. All Rights Reserved.
+# Copyright Ericsson AB 1997-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
APPLICATION = megaco
-MEGACO_VSN = 3.17.3
+MEGACO_VSN = 3.18
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
diff --git a/lib/mnesia/Makefile b/lib/mnesia/Makefile
index f687b0ecdb..0333f73a27 100644
--- a/lib/mnesia/Makefile
+++ b/lib/mnesia/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/mnesia/doc/misc/Makefile b/lib/mnesia/doc/misc/Makefile
index e5fa327f5b..4d364649b6 100644
--- a/lib/mnesia/doc/misc/Makefile
+++ b/lib/mnesia/doc/misc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/mnesia/doc/src/Makefile b/lib/mnesia/doc/src/Makefile
index 6a72b98ebc..af85e1bc59 100644
--- a/lib/mnesia/doc/src/Makefile
+++ b/lib/mnesia/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -58,7 +59,6 @@ XML_CHAPTER_FILES = \
Mnesia_App_A.xml \
Mnesia_App_B.xml \
Mnesia_App_C.xml \
- Mnesia_App_D.xml \
notes.xml
BOOK_FILES = book.xml
diff --git a/lib/mnesia/doc/src/Mnesia_App_A.xml b/lib/mnesia/doc/src/Mnesia_App_A.xml
deleted file mode 100644
index 62dbffa14a..0000000000
--- a/lib/mnesia/doc/src/Mnesia_App_A.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year><year>2013</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Appendix A: Mnesia Error Messages</title>
- <prepared>Claes Wikstr&ouml;m, Hans Nilsson and H&aring;kan Mattsson</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno></docno>
- <approved>Bjarne D&auml;cker</approved>
- <checked>Bjarne D&auml;cker</checked>
- <date>96-11-20</date>
- <rev>B</rev>
- <file>Mnesia_App_A.xml</file>
- </header>
- <p>Whenever an operation returns an error in Mnesia, a description
- of the error is available. For example, the functions
- <c>mnesia:transaction(Fun)</c>, or <c>mnesia:create_table(N,L)</c>
- may return the tuple <c>{aborted, Reason}</c>, where <c>Reason</c>
- is a term describing the error. The following function is used to
- retrieve more detailed information about the error:
- </p>
- <list type="bulleted">
- <item><c>mnesia:error_description(Error)</c></item>
- </list>
-
- <section>
- <title>Errors in Mnesia</title>
- <p>The following is a list of valid errors in Mnesia.</p>
- <list type="bulleted">
- <item><c>badarg</c>. Bad or invalid argument, possibly bad type.
- </item>
- <item><c>no_transaction</c>. Operation not allowed outside transactions.
- </item>
- <item><c>combine_error</c>. Table options were illegally combined.
- </item>
- <item><c>bad_index</c>. Index already exists, or was out of bounds.
- </item>
- <item><c>already_exists</c>. Schema option to be activated is already on.
- </item>
- <item><c>index_exists</c>. Some operations cannot be performed on tables with an index.
- </item>
- <item><c>no_exists</c>.; Tried to perform operation on non-existing (non-alive) item.
- </item>
- <item><c>system_limit</c>.; A system limit was exhausted.
- </item>
- <item><c>mnesia_down</c>. A transaction involves records on a
- remote node which became unavailable before the transaction
- was completed. Record(s) are no longer available elsewhere in
- the network.</item>
- <item><c>not_a_db_node</c>. A node was mentioned which does not exist in the schema.</item>
- <item><c>bad_type</c>.; Bad type specified in argument.</item>
- <item><c>node_not_running</c>. Node is not running.</item>
- <item><c>truncated_binary_file</c>. Truncated binary in file.</item>
- <item><c>active</c>. Some delete operations require that all active records are removed.</item>
- <item><c>illegal</c>. Operation not supported on this record.</item>
- </list>
- <p>The following example illustrates a function which returns an error, and the method to retrieve more detailed error information.
- </p>
- <p>The function <c>mnesia:create_table(bar, [{attributes, 3.14}])</c> will return the tuple <c>{aborted,Reason}</c>, where <c>Reason</c> is the tuple
- <c>{bad_type,bar,3.14000}</c>.
- </p>
- <p>The function <c>mnesia:error_description(Reason)</c>, returns the term
- <c>{"Bad type on some provided arguments",bar,3.14000}</c> which is an error
- description suitable
- for display.</p>
- </section>
-</chapter>
-
diff --git a/lib/mnesia/doc/src/Mnesia_App_A.xmlsrc b/lib/mnesia/doc/src/Mnesia_App_A.xmlsrc
new file mode 100644
index 0000000000..7bc0688887
--- /dev/null
+++ b/lib/mnesia/doc/src/Mnesia_App_A.xmlsrc
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Appendix A: Backup Callback Interface</title>
+ <prepared>Claes Wikstr&ouml;m, Hans Nilsson and H&aring;kan Mattsson</prepared>
+ <responsible>Bjarne D&auml;cker</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Bjarne D&auml;cker</checked>
+ <date>97-05-27</date>
+ <rev>C</rev>
+ <file>Mnesia_App_A.xml</file>
+ </header>
+
+ <section>
+ <title>mnesia_backup Callback Behavior</title>
+ <p></p>
+ <codeinclude file="../../src/mnesia_backup.erl" tag="%0" type="erl"></codeinclude>
+ </section>
+</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_App_B.xmlsrc b/lib/mnesia/doc/src/Mnesia_App_B.xmlsrc
index f02e424ca4..1b76a31ef0 100644
--- a/lib/mnesia/doc/src/Mnesia_App_B.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_App_B.xmlsrc
@@ -4,38 +4,41 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1998</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Appendix B: The Backup Call Back Interface</title>
- <prepared>Claes Wikstr&ouml;m, Hans Nilsson and H&aring;kan Mattsson</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
+ <title>Appendix B: Activity Access Callback Interface</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Bjarne D&auml;cker</approved>
- <checked>Bjarne D&auml;cker</checked>
- <date>97-05-27</date>
- <rev>C</rev>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>Mnesia_App_B.xml</file>
</header>
<section>
- <title>mnesia_backup callback behavior</title>
+ <title>mnesia_access Callback Behavior</title>
+ <p></p>
+ <codeinclude file="../../src/mnesia_frag.erl" tag="%header_doc_include" type="erl"></codeinclude>
<p></p>
- <codeinclude file="../../src/mnesia_backup.erl" tag="%0" type="erl"></codeinclude>
+ <codeinclude file="../../src/mnesia_frag.erl" tag="%impl_doc_include" type="erl"></codeinclude>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_App_C.xmlsrc b/lib/mnesia/doc/src/Mnesia_App_C.xmlsrc
index f7fefa36c4..34dafc772b 100644
--- a/lib/mnesia/doc/src/Mnesia_App_C.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_App_C.xmlsrc
@@ -4,24 +4,25 @@
<chapter>
<header>
<copyright>
- <year>1998</year><year>2013</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Appendix C: The Activity Access Call Back Interface</title>
+ <title>Appendix C: Fragmented Table Hashing Callback Interface</title>
<prepared>H&aring;kan Mattsson</prepared>
<responsible></responsible>
<docno></docno>
@@ -33,11 +34,11 @@
</header>
<section>
- <title>mnesia_access callback behavior</title>
+ <title>mnesia_frag_hash Callback Behavior</title>
<p></p>
- <codeinclude file="../../src/mnesia_frag.erl" tag="%header_doc_include" type="erl"></codeinclude>
+ <codeinclude file="../../src/mnesia_frag_hash.erl" tag="%header_doc_include" type="erl"></codeinclude>
<p></p>
- <codeinclude file="../../src/mnesia_frag.erl" tag="%impl_doc_include" type="erl"></codeinclude>
+ <codeinclude file="../../src/mnesia_frag_hash.erl" tag="%impl_doc_include" type="erl"></codeinclude>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_chap1.xml b/lib/mnesia/doc/src/Mnesia_chap1.xml
index 540008cdc5..fd614a655b 100644
--- a/lib/mnesia/doc/src/Mnesia_chap1.xml
+++ b/lib/mnesia/doc/src/Mnesia_chap1.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,235 +32,82 @@
<rev>C</rev>
<file>Mnesia_chap1.xml</file>
</header>
- <p>This book describes the Mnesia DataBase Management
- System (DBMS). <em>Mnesia</em> is a distributed Database Management
- System, appropriate for telecommunications applications and other
- Erlang applications which require continuous operation and soft
- real-time properties. It is one section of the Open Telecom Platform
- (OTP), which is a control system platform for building
- telecommunications applications.</p>
-
- <section>
- <title>About Mnesia</title>
- <p>The management of data in telecommunications system has many
- aspects whereof some, but not all, are addressed by traditional
- commercial DBMSs (Data Base Management Systems). In particular the
- very high level of fault tolerance which is required in many nonstop
- systems, combined with requirements on the DBMS to run in the same
- address space as the application, have led us to implement a brand new
- DBMS. called Mnesia. Mnesia is implemented in, and very tightly
- connected to, the programming language Erlang and it provides the
- functionality that is necessary for the implementation of fault
- tolerant telecommunications systems. Mnesia is a multiuser Distributed
- DBMS specially made for industrial telecommunications applications
- written in the symbolic programming language Erlang, which is also
- the intended target language. Mnesia tries to address all of the data
- management issues required for typical telecommunications systems and
- it has a number of features that are not normally found in traditional
- databases. <br></br>
-
- In telecommunications applications there are different needs
- from the features provided by traditional DBMSs. The applications now
- implemented in the Erlang language need a mixture of a broad range
- of features, which generally are not satisfied by traditional DBMSs.
- Mnesia is designed with requirements like the following in mind:</p>
- <list type="ordered">
- <item>Fast real-time key/value lookup</item>
- <item>Complicated non real-time queries mainly for
- operation and maintenance</item>
- <item>Distributed data due to distributed
- applications</item>
- <item>High fault tolerance</item>
- <item>Dynamic re-configuration</item>
- <item>Complex objects</item>
- </list>
- <p>What
- sets Mnesia apart from most other DBMSs is that it is designed with
- the typical data management problems of telecommunications applications
- in mind. Hence Mnesia combines many concepts found in traditional
- databases, such as transactions and queries with concepts found in data
- management systems for telecommunications applications, such as very
- fast real-time operations, configurable degree of fault tolerance (by
- means of replication) and the ability to reconfigure the system without
- stopping or suspending it. Mnesia is also interesting due to its tight
- coupling to the programming language Erlang, thus almost turning Erlang
- into a database programming language. This has many benefits, the
- foremost is that
- the impedance mismatch between data format used by the
- DBMS and data format used by the programming language, which is used
- to manipulate the data, completely disappears. <br></br>
-</p>
- </section>
-
- <section>
- <title>The Mnesia DataBase Management System (DBMS)</title>
- <p></p>
+ <p>The <c>Mnesia</c> application provides a heavy duty real-time
+ distributed database.</p>
<section>
- <title>Features</title>
- <p>Mnesia contains the following features which combine to produce a fault-tolerant,
- distributed database management system written in Erlang:
- </p>
+ <title>Scope</title>
+ <p>This User's Guide describes how to
+ build <c>Mnesia</c> database applications, and how to integrate
+ and use the <c>Mnesia</c> database management system with
+ OTP. Programming constructs are described, and numerous
+ programming examples are included to illustrate the use of
+ <c>Mnesia</c>.</p>
+ <p>This User's Guide is organized as follows:</p>
<list type="bulleted">
- <item>Database schema can be dynamically reconfigured at runtime.
+ <item><seealso marker="Mnesia_overview">Mnesia</seealso>
+ provides an introduction to
+ <c>Mnesia</c>.
+ </item>
+ <item><seealso marker="Mnesia_chap2">Getting Started</seealso>
+ introduces <c>Mnesia</c> with an example database. Examples
+ are included how to start an Erlang session, specify a
+ <c>Mnesia</c> database directory, initialize a database
+ schema, start <c>Mnesia</c>, and create tables. Initial
+ prototyping of record definitions is also discussed.
+ </item>
+ <item><seealso marker="Mnesia_chap3">Build a Mnesia
+ Database</seealso> more formally describes the steps
+ introduced in the previous section, namely the <c>Mnesia</c>
+ functions that define a database schema, start <c>Mnesia</c>,
+ and create the required tables.
+ </item>
+ <item><seealso marker="Mnesia_chap4">Transactions and Other Access Contexts</seealso>
+ describes the transactions properties that make <c>Mnesia</c> into
+ a fault tolerant, real-time distributed database management
+ system. This section also describes the concept of locking
+ to ensure consistency in tables, and "dirty
+ operations", or short cuts, which bypass the transaction system
+ to improve speed and reduce overheads.
</item>
- <item>Tables can be declared to have properties such as location,
- replication, and persistence.
+ <item><seealso marker="Mnesia_chap5">Miscellaneous Mnesia
+ Features</seealso> describes features that enable the
+ construction of more complex database applications. These
+ features include indexing, checkpoints, distribution and fault
+ tolerance, disc-less nodes, replication manipulation, local
+ content tables, concurrency, and object-based programming in
+ <c>Mnesia</c>.
</item>
- <item>Tables can be moved or replicated to several nodes to improve
- fault tolerance. The rest of the system can still access the tables
- to read, write, and delete records.
+ <item><seealso marker="Mnesia_chap7">Mnesia System
+ Information</seealso> describes the files contained in the
+ <c>Mnesia</c> database directory, database configuration data,
+ core and table dumps, as well as the important subject of
+ backup, fall-back, and disaster recovery principles.
</item>
- <item>Table locations are transparent to the programmer.
- Programs address table names and the system itself keeps track of
- table locations.
+ <item><seealso marker="Mnesia_chap8">Combine Mnesia with
+ SNMP</seealso> is a short section that outlines <c>Mnesia</c>
+ integrated with SNMP.
</item>
- <item>Database transactions can be distributed, and a large number of
- functions can be called within one transaction.
+ <item><seealso marker="Mnesia_App_A">Appendix A: Backup
+ Callback Interface</seealso> is a program listing of the
+ default implementation of this facility.
</item>
- <item>Several transactions can run concurrently, and their execution is
- fully synchronized by the database management system.
- Mnesia ensures that no two processes manipulate data simultaneously.
+ <item><seealso marker="Mnesia_App_B">Appendix B: Activity
+ Access Callback Interface</seealso> is a program outlining
+ one possible implementation of this facility.
</item>
- <item>Transactions can be assigned the property of being executed on
- all nodes in the system, or on none. Transactions can also be bypassed
- in favor of running so called "dirty operations", which reduce
- overheads and run very fast.
+ <item><seealso marker="Mnesia_App_C">Appendix C: Fragmented
+ Table Hashing Callback Interface</seealso> is a program
+ outlining one possible implementation of this facility.
</item>
</list>
- <p>Details of these features are described in the following sections.</p>
- </section>
- <p></p>
-
- <section>
- <title>Add-on Applications</title>
- <p>QLC and Mnesia Session can be used in conjunction with Mnesia to produce
- specialized functions which enhance the operational ability of Mnesia.
- Both Mnesia Session and QLC have their own documentation as part
- of the OTP documentation set. Below are the main features of Mnesia Session
- and QLC when used in conjunction with Mnesia:</p>
- <list type="bulleted">
- <item><em>QLC</em> has the ability to optimize the query
- compiler for the Mnesia Database Management System, essentially making
- the DBMS more efficient.</item>
- <item><em>QLC</em>, can be used as a database programming
- language for Mnesia. It includes a notation called "list
- comprehensions" and can be used to make complex database
- queries over a set of tables.</item>
- <item><em>Mnesia Session</em> is an interface for the Mnesia Database
- Management System</item>
- <item><em>Mnesia Session</em> enables access to the
- Mnesia DBMS from foreign programming languages (i.e. other
- languages than Erlang).</item>
- </list>
- <p></p>
-
- <section>
- <title>When to Use Mnesia</title>
- <p>Use Mnesia with the following types of applications:
- </p>
- <list type="bulleted">
- <item>Applications that need to replicate data.
- </item>
- <item>Applications that perform complicated searches on data.
- </item>
- <item>Applications that need to use atomic transactions to
- update several records simultaneously.
- </item>
- <item>Applications that use soft real-time characteristics.
- </item>
- </list>
- <p>On the other hand, Mnesia may not be appropriate with the
- following types of applications:
- </p>
- <list type="bulleted">
- <item>Programs that process plain text or binary data files
- </item>
- <item>Applications that merely need a look-up dictionary
- which can be stored to disc can utilize the standard
- library module <c>dets</c>, which is a disc based version
- of the module <c>ets</c>.
- </item>
- <item>Applications which need disc logging facilities can
- utilize the module <c>disc_log</c> by preference.
- </item>
- <item>Not suitable for hard real time systems.
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Scope and Purpose</title>
- <p>This manual is included in the OTP document set. It describes
- how to build Mnesia database applications, and how to integrate
- and utilize the Mnesia database management system with
- OTP. Programming constructs are described, and numerous
- programming examples are included to illustrate the use of
- Mnesia.
- </p>
</section>
<section>
<title>Prerequisites</title>
- <p>Readers of this manual are assumed to be familiar with system
- development principles and database management systems. Readers
- are also assumed to be familiar with the Erlang programming
- language.</p>
- </section>
-
- <section>
- <title>About This Book</title>
- <p>This book contains the following chapters:
- </p>
- <list type="bulleted">
- <item>Chapter 2, "Getting Started with Mnesia", introduces
- Mnesia with an example database. Examples are shown of how to
- start an Erlang session, specify a Mnesia database directory,
- initialize a database schema, start Mnesia, and create
- tables. Initial prototyping of record definitions is also
- discussed.
- </item>
- <item>Chapter 3, "Building a Mnesia Database", more formally
- describes the steps introduced in Chapter 2, namely the Mnesia
- functions which define a database schema, start Mnesia, and
- create the required tables.
- </item>
- <item>Chapter 4, "Transactions and other access contexts",
- describes the transactions properties which make Mnesia into a
- fault tolerant, real-time distributed database management
- system. This chapter also describes the concept of locking in
- order to ensure consistency in tables, and so called "dirty
- operations", or short cuts which bypass the transaction system
- to improve speed and reduce overheads.
- </item>
- <item>Chapter 5, "Miscellaneous Mnesia Features", describes
- features which enable the construction of more complex
- database applications. These features includes indexing,
- checkpoints, distribution and fault tolerance, disc-less
- nodes, replication manipulation, local content tables, concurrency,
- and object based programming in Mnesia.
- </item>
- <item>Chapter 6, "Mnesia System Information", describes the
- files contained in the Mnesia database directory, database
- configuration data, core and table dumps, as well as the
- important subject of backup, fall-back, and disaster recovery
- principles.
- </item>
- <item>Chapter 7, "Combining Mnesia with SNMP", is a short
- chapter which outlines Mnesia integrated with SNMP.
- </item>
- <item>Appendix A, "Mnesia Errors Messages", lists Mnesia error
- messages and their meanings.
- </item>
- <item>Appendix B, "The Backup Call Back Interface", is a
- program listing of the default implementation of this facility.
- </item>
- <item>Appendix C, "The Activity Access Call Back Interface",
- is a program outlining of one possible implementations of this facility.
- </item>
- </list>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language, system development principles, and
+ database management systems.</p>
</section>
- </section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
index f464135a89..ad2ba7784e 100644
--- a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Getting Started with Mnesia</title>
+ <title>Getting Started</title>
<prepared>Claes Wikstr&ouml;m, Hans Nilsson and H&aring;kan Mattsson</prepared>
<responsible></responsible>
<docno></docno>
@@ -31,27 +32,31 @@
<rev>C</rev>
<file>Mnesia_chap2.xml</file>
</header>
- <p>This chapter introduces Mnesia. Following a brief discussion
- about the first initial setup, a Mnesia database example is
- demonstrated. This database example will be referenced in the
- following chapters, where this example is modified in order to
- illustrate various program constructs. In this chapter, the
- following mandatory procedures are illustrated by examples:
- </p>
+ <marker id="getting_started"></marker>
+ <p>This section introduces <c>Mnesia</c> with an example database.
+ This example is referenced in the
+ following sections, where the example is modified to
+ illustrate various program constructs. This section illustrates
+ the following mandatory procedures through examples:</p>
<list type="bulleted">
- <item>Starting an Erlang session and specifying a directory for the
- Mnesia database.
+ <item>Starting the Erlang session.
+ </item>
+ <item>Specifying the <c>Mnesia</c> directory where the database
+ is to be stored.
+ </item>
+ <item>Initializing a new database schema with an attribute that
+ specifies on which node, or nodes, that database is to operate.
+ </item>
+ <item>Starting <c>Mnesia</c>.
</item>
- <item>Initializing a database schema.
+ <item>Creating and populating the database tables.
</item>
- <item>Starting Mnesia and creating the required tables.</item>
</list>
<section>
- <title>Starting Mnesia for the first time</title>
- <p>Following is a simplified demonstration of a Mnesia system startup. This is the dialogue from the Erlang
- shell:
- </p>
+ <title>Starting Mnesia for the First Time</title>
+ <p>This section provides a simplified demonstration of a <c>Mnesia</c>
+ system startup. The dialogue from the Erlang shell is as follows:</p>
<pre><![CDATA[
unix> erl -mnesia dir '"/tmp/funky"'
Erlang (BEAM) emulator version 4.9
@@ -89,79 +94,62 @@
0 transactions waits for other nodes: []
ok
]]></pre>
- <p>In the example above the following actions were performed:
- </p>
+ <p>In this example, the following actions are performed:</p>
<list type="bulleted">
- <item>The Erlang system was started from the UNIX prompt
- with a flag <c>-mnesia dir '"/tmp/funky"'</c>. This flag indicates
- to Mnesia which directory will store the data.
+ <item><em>Step 1:</em> The Erlang system is started from the UNIX
+ prompt with a flag <c>-mnesia dir '"/tmp/funky"'</c>, which indicates
+ in which directory to store the data.
</item>
- <item>A new empty schema was initialized on the local node by evaluating
- <c>mnesia:create_schema([node()]).</c> The schema contains
- information about the database in general. This will be
- thoroughly explained later on.
+ <item><em>Step 2:</em> A new empty schema is initialized on the local
+ node by evaluating
+ <seealso marker="mnesia#create_schema/1">mnesia:create_schema([node()])</seealso>.
+ The schema contains information about the database in general.
+ This is explained in detail later.
</item>
- <item>The DBMS was started by evaluating <c>mnesia:start()</c>.
+ <item><em>Step 3:</em> The DBMS is started by evaluating
+ <seealso marker="mnesia#start/0">mnesia:start()</seealso>.
</item>
- <item>A first table was created, called <c>funky</c> by evaluating
- the expression <c>mnesia:create_table(funky, [])</c>. The table
- was given default properties.
+ <item><em>Step 4:</em> A first table is created, called <c>funky</c>,
+ by evaluating the expression <c>mnesia:create_table(funky, [])</c>.
+ The table is given default properties.
</item>
- <item><c>mnesia:info()</c> was evaluated and subsequently displayed
- information regarding the status of the database on the terminal.
+ <item><em>Step 5:</em> <seealso marker="mnesia#info/0">mnesia:info()</seealso>
+ is evaluated to
+ display information on the terminal about the status of the database.
</item>
</list>
</section>
<section>
- <title>An Introductory Example</title>
- <p>A Mnesia database is organized as a set of tables.
+ <title>Example</title>
+ <p>A <c>Mnesia</c> database is organized as a set of tables.
Each table is populated with instances (Erlang records).
- A table also has a number of properties, such as location and
- persistence.
- </p>
- <p>In this example we shall:
- </p>
- <list type="bulleted">
- <item>Start an Erlang system, and specify the directory where
- the database will be located.
- </item>
- <item>Initiate a new schema with an attribute that specifies
- on which node, or nodes, the database will operate.
- </item>
- <item>Start Mnesia itself.
- </item>
- <item>Create and populate the database tables.
- </item>
- </list>
+ A table has also a number of properties, such as location and
+ persistence.</p>
<section>
- <title>The Example Database</title>
+ <title>Database</title>
</section>
- <p>In this database example, we will create the database and
- relationships depicted in the following diagram. We will call this
- database the <em>Company</em> database.
- </p>
+ <p>This example shows how to create a database called <c>Company</c>
+ and the relationships shown in the following diagram:</p>
<image file="company.gif">
<icaption>Company Entity-Relation Diagram</icaption>
</image>
- <p>The database model looks as follows:
- </p>
+ <p>The database model is as follows:</p>
<list type="bulleted">
- <item>There are three entities: employee, project, and
- department.
+ <item>There are three entities: department, employee, and project.
</item>
<item>
<p>There are three relationships between these entities:</p>
<list type="ordered">
- <item>A department is managed by an employee, hence the
- <em>manager</em> relationship.
+ <item>A department is managed by an employee,
+ hence the <c>manager</c> relationship.
</item>
<item>An employee works at a department, hence the
- <em>at_dep</em> relationship.
+ <c>at_dep</c> relationship.
</item>
- <item>Each employee works on a number of projects, hence
- the <em>in_proj</em> relationship.
+ <item>Each employee works on a number of projects,
+ hence the <c>in_proj</c> relationship.
</item>
</list>
</item>
@@ -169,35 +157,32 @@
<section>
<title>Defining Structure and Content</title>
- <p>We first enter our record definitions into a text file
+ <p>First the record definitions are entered into a text file
named <c>company.hrl</c>. This file defines the following
- structure for our sample database:
- </p>
+ structure for the example database: </p>
<codeinclude file="company.hrl" tag="%0" type="erl"></codeinclude>
- <p>The structure defines six tables in our database. In Mnesia,
- the function <c>mnesia:create_table(Name, ArgList)</c> is
- used to create tables. <c>Name</c> is the table
- name <em>Note:</em> The current version of Mnesia does
- not require that the name of the table is the same as the record
- name, See Chapter 4:
- <seealso marker="Mnesia_chap4#recordnames_tablenames">Record Names Versus Table Names.</seealso></p>
- <p>For example, the table
- for employees will be created with the function
- <c>mnesia:create_table(employee, [{attributes, record_info(fields, employee)}]).</c> The table
+ <p>The structure defines six tables in the database. In <c>Mnesia</c>,
+ the function
+ <seealso marker="mnesia#create_table/2">mnesia:create_table(Name, ArgList)</seealso>
+ creates tables. <c>Name</c> is the table name.</p>
+ <note><p>The current version of <c>Mnesia</c> does not require that
+ the name of the table is the same as the record name, see
+ <seealso marker="Mnesia_chap4#recordnames_tablenames">Record Names versus Table Names.</seealso>.</p></note>
+ <p>For example, the table for employees is created with the
+ function <c>mnesia:create_table(employee,
+ [{attributes, record_info(fields, employee)}])</c>. The table
name <c>employee</c> matches the name for records specified
- in <c>ArgList</c>. The expression <c>record_info(fields, RecordName)</c> is processed by the Erlang preprocessor and
- evaluates to a list containing the names of the different
- fields for a record.
- </p>
+ in <c>ArgList</c>. The expression
+ <c>record_info(fields, RecordName)</c> is processed by the Erlang
+ preprocessor and evaluates to a list containing the names of the
+ different fields for a record.</p>
</section>
<section>
- <title>The Program</title>
- <p>The following shell interaction starts Mnesia and
- initializes the schema for our <c>company</c> database:
- </p>
+ <title>Program</title>
+ <p>The following shell interaction starts <c>Mnesia</c> and
+ initializes the schema for the <c>Company</c> database:</p>
<pre>
-
% <input>erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'</input>
Erlang (BEAM) emulator version 4.9
@@ -205,37 +190,39 @@
1> mnesia:create_schema([node()]).
ok
2> mnesia:start().
- ok
- </pre>
- <p>The following program module creates and populates previously defined tables:
- </p>
+ ok</pre>
+ <p>The following program module creates and populates previously
+ defined tables:</p>
<codeinclude file="company.erl" tag="%0" type="erl"></codeinclude>
</section>
<section>
- <title>The Program Explained</title>
- <p>The following commands and functions were used to initiate the
- Company database:
- </p>
+ <title>Program Explained</title>
+ <p>The following commands and functions are used to initiate the
+ <c>Company</c> database:</p>
<list type="bulleted">
- <item><c>% erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'.</c> This is a UNIX
- command line entry which starts the Erlang system. The flag
- <c>-mnesia dir Dir</c> specifies the location of the
+ <item><c>% erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'</c>.
+ This is a UNIX
+ command-line entry that starts the Erlang system. The flag
+ <c>-mnesia dir Dir</c> specifies the location of the
database directory. The system responds and waits for
- further input with the prompt <em>1></em>.
+ further input with the prompt <c>1></c>.
</item>
- <item><c>mnesia:create_schema([node()]).</c> This function
- has the format <c>mnesia:create_schema(DiscNodeList)</c> and
- initiates a new schema. In this example, we have created a
- non-distributed system using only one node. Schemas are fully
- explained in Chapter 3:<seealso marker="Mnesia_chap3#def_schema">Defining a Schema</seealso>.
+ <item>
+ <seealso marker="mnesia#create_schema/1">mnesia:create_schema([node()])</seealso>.
+ This function
+ has the format <c>mnesia:create_schema(DiscNodeList)</c> and
+ initiates a new schema. In this example, a non-distributed system
+ using only one node is created. Schemas are fully explained in
+ <seealso marker="Mnesia_chap3#def_schema">Define a Schema</seealso>.
</item>
- <item><c>mnesia:start().</c> This function starts
- Mnesia. This function is fully explained in Chapter 3:
- <seealso marker="Mnesia_chap3#start_mnesia">Starting Mnesia</seealso>.
+ <item><seealso marker="mnesia#start/0">mnesia:start()</seealso>.
+ This function starts <c>Mnesia</c> and is fully explained in
+ <seealso marker="Mnesia_chap3#start_mnesia">Start Mnesia</seealso>.
</item>
</list>
- <p>Continuing the dialogue with the Erlang shell will produce the following:</p>
+ <p>Continuing the dialogue with the Erlang shell produces the
+ following:</p>
<pre><![CDATA[
3> company:init().
{atomic,ok}
@@ -271,63 +258,58 @@
0 transactions waits for other nodes: []
ok
]]></pre>
- <p>A set of tables is created:
- </p>
- <list type="bulleted">
- <item><c>mnesia:create_table(Name,ArgList)</c>. This
- function is used to create the required database tables. The
- options available with <c>ArgList</c> are explained in
- Chapter 3: <seealso marker="Mnesia_chap3#create_tables">Creating New Tables</seealso>. </item>
- </list>
- <p>The <c>company:init/0</c> function creates our tables. Two tables are
- of type <c>bag</c>. This is the <c>manager</c> relation as well
- the <c>in_proj</c> relation. This shall be interpreted as: An
+ <p>A set of tables is created. The function
+ <seealso marker="mnesia#create_table/2">mnesia:create_table(Name, ArgList)</seealso>
+ creates the required database tables. The
+ options available with <c>ArgList</c> are explained in
+ <seealso marker="Mnesia_chap3#create_tables">Create New Tables</seealso>.</p>
+ <p>The function <c>company:init/0</c> creates the tables. Two tables
+ are of type <c>bag</c>. This is the <c>manager</c> relation as well
+ the <c>in_proj</c> relation. This is interpreted as: an
employee can be manager over several departments, and an employee
can participate in several projects. However, the <c>at_dep</c>
- relation is <c>set</c> because an employee can only work in one department.
- In this data model we have examples of relations that are one-to-one (<c>set</c>),
- as well as one-to-many (<c>bag</c>).
- </p>
- <p><c>mnesia:info()</c> now indicates that a database
- which has seven local tables, of which, six are our
- user defined tables and one is the schema.
- Six transactions have been committed, as six successful transactions were run when
- creating the tables.
- </p>
- <p>To write a function which inserts an employee record into the database, there must be an
- <c>at_dep</c> record and a set of <c>in_proj</c> records inserted. Examine the following
- code used to complete this action:
- </p>
- <codeinclude file="company.erl" tag="%1" type="erl"></codeinclude>
+ relation is <c>set</c>, as an employee can only work in one department.
+ In this data model, there are examples of relations that are 1-to-1
+ (<c>set</c>) and 1-to-many (<c>bag</c>).</p>
+ <p><seealso marker="mnesia#info/0">mnesia:info()</seealso>
+ now indicates that a database has seven
+ local tables, where six are the user-defined tables and one is
+ the schema. Six transactions have been committed, as six successful
+ transactions were run when creating the tables.</p>
+ <p>To write a function that inserts an employee record into the
+ database, there must be an <c>at_dep</c> record and a set of
+ <c>in_proj</c> records inserted. Examine the following
+ code used to complete this action:</p>
+ <codeinclude file="company.erl" tag="%1" type="erl"></codeinclude>
<list type="bulleted">
<item>
- <p><c>insert_emp(Emp, DeptId, ProjNames) -></c>. The
- <c>insert_emp/3</c> arguments are:</p>
+ <p>The <c>insert_emp/3</c> arguments are as follows:</p>
<list type="ordered">
<item><c>Emp</c> is an employee record.
</item>
- <item><c>DeptId</c> is the identity of the department where the employee is working.
+ <item><c>DeptId</c> is the identity of the department where
+ the employee works.
</item>
- <item><c>ProjNames</c> is a list of the names of the projects where the employee are working.</item>
+ <item><c>ProjNames</c> is a list of the names of the projects
+ where the employee works.</item>
</list>
</item>
</list>
- <p>The <c>insert_emp(Emp, DeptId, ProjNames) -></c> function
- creates a <em>functional object</em>. Functional objects
- are identified by the term <c>Fun</c>. The Fun is passed
+ <p>The function <c>insert_emp/3</c> creates a Functional Object (Fun).
+ <c>Fun</c> is passed
as a single argument to the function
- <c>mnesia:transaction(Fun)</c>. This means that Fun is
- run as a transaction with the following properties:
- </p>
+ <seealso marker="mnesia#transaction/2">mnesia:transaction(Fun)</seealso>.
+ This means that <c>Fun</c> is
+ run as a transaction with the following properties:</p>
<list type="bulleted">
- <item>Fun either succeeds or fails completely.
+ <item>A <c>Fun</c> either succeeds or fails.
</item>
- <item>Code which manipulates the same data records can be
+ <item>Code that manipulates the same data records can be
run concurrently without the different processes interfering
with each other.
</item>
</list>
- <p>The function can be used as:</p>
+ <p>The function can be used as follows:</p>
<code type="none">
Emp = #employee{emp_no= 104732,
name = klacke,
@@ -335,20 +317,17 @@
sex = male,
phone = 98108,
room_no = {221, 015}},
- insert_emp(Me, 'B/SFR', [Erlang, mnesia, otp]).
- </code>
- <note>
- <p>Functional Objects (Funs) are described in the
- Erlang Reference Manual, "Fun Expressions".
- </p>
+ insert_emp(Me, 'B/SFR', [Erlang, mnesia, otp]).</code>
+ <note><p>For information about Funs, see "Fun Expressions" in
+ section <c>Erlang Reference Manual</c> in System
+ Documentation..</p>
</note>
</section>
<section>
<title>Initial Database Content</title>
- <p>After the insertion of the employee named <c>klacke</c>
- we have the following records in the database:
- </p>
+ <p>After the insertion of the employee named <c>klacke</c>,
+ the databse has the following records:</p>
<marker id="table2_1"></marker>
<table>
<row>
@@ -364,14 +343,14 @@
<cell align="left" valign="middle">klacke</cell>
<cell align="left" valign="middle">7</cell>
<cell align="left" valign="middle">male</cell>
- <cell align="left" valign="middle">99586</cell>
+ <cell align="left" valign="middle">98108</cell>
<cell align="left" valign="middle">{221, 015}</cell>
</row>
- <tcaption>
-Employee</tcaption>
+ <tcaption>employee Database Record</tcaption>
</table>
- <p>An employee record has the following Erlang record/tuple
- representation: <c>{employee, 104732, klacke, 7, male, 98108, {221, 015}}</c></p>
+ <p>This <c>employee</c> record has the Erlang record/tuple
+ representation
+ <c>{employee, 104732, klacke, 7, male, 98108, {221, 015}}</c>.</p>
<marker id="table2_2"></marker>
<table>
<row>
@@ -382,12 +361,10 @@ Employee</tcaption>
<cell align="left" valign="middle">klacke</cell>
<cell align="left" valign="middle">B/SFR</cell>
</row>
- <tcaption>
-At_dep</tcaption>
+ <tcaption>at_dep Database Record</tcaption>
</table>
- <p>At_dep has the following Erlang tuple representation:
- <c>{at_dep, klacke, 'B/SFR'}</c>.
- </p>
+ <p>This <c>at_dep</c> record has the Erlang tuple representation
+ <c>{at_dep, klacke, 'B/SFR'}</c>.</p>
<marker id="table3_3"></marker>
<table>
<row>
@@ -406,39 +383,36 @@ At_dep</tcaption>
<cell align="left" valign="middle">klacke</cell>
<cell align="left" valign="middle">mnesia</cell>
</row>
- <tcaption>
-In_proj</tcaption>
+ <tcaption>in_proj Database Record</tcaption>
</table>
- <p>In_proj has the following Erlang tuple representation:
- <c>{in_proj, klacke, 'Erlang', klacke, 'otp', klacke, 'mnesia'}</c></p>
- <p>There is no difference between rows in a table and Mnesia
- records. Both concepts are the same and will be used
- interchangeably throughout this book.
- </p>
- <p>A Mnesia table is populated by Mnesia records. For example,
- the tuple <c>{boss, klacke, bjarne}</c> is a record. The
- second element in this tuple is the key. In order to uniquely
- identify a table row both the key and the table name is
- needed. The term <em>object identifier</em>,
- (oid) is sometimes used for the arity two tuple {Tab, Key}. The oid for
- the <c>{boss, klacke, bjarne}</c> record is the arity two
+ <p>This <c>in_proj</c> record has the Erlang tuple representation
+ <c>{in_proj, klacke, 'Erlang', klacke, 'otp', klacke,
+ 'mnesia'}</c>.</p>
+ <p>There is no difference between rows in a table and <c>Mnesia</c>
+ records. Both concepts are the same and are used
+ interchangeably throughout this User's Guide.</p>
+ <p>A <c>Mnesia</c> table is populated by <c>Mnesia</c> records. For
+ example, the tuple <c>{boss, klacke, bjarne}</c> is a record. The
+ second element in this tuple is the key. To identify a table
+ uniquely, both the key and the table name is needed.
+ The term Object Identifier (OID) is
+ sometimes used for the arity two tuple {Tab, Key}. The OID for
+ the record <c>{boss, klacke, bjarne}</c> is the arity two
tuple <c>{boss, klacke}</c>. The first element of the tuple is
the type of the record and the second element is the key. An
- oid can lead to zero, one, or more records depending on
- whether the table type is <c>set</c> or <c>bag</c>.
- </p>
- <p>We were also able to insert the <c>{boss, klacke, bjarne}</c> record which contains an implicit reference to
- another employee which does not yet exist in the
- database. Mnesia does not enforce this.
- </p>
+ OID can lead to zero, one, or more records depending on
+ whether the table type is <c>set</c> or <c>bag</c>.</p>
+ <p>The record <c>{boss, klacke, bjarne}</c> can also be inserted.
+ This record contains an implicit reference to
+ another employee that does not yet exist in the
+ database. <c>Mnesia</c> does not enforce this.</p>
</section>
<section>
- <title>Adding Records and Relationships to the Database</title>
- <p>After adding additional record to the Company database, we
- may end up with the following records:
- </p>
- <p><em>Employees</em></p>
+ <title>Adding Records and Relationships to Database</title>
+ <p>After adding more records to the <c>Company</c> database, the
+ result can be the following records:</p>
+ <p><c>employees</c>:</p>
<code type="none">
{employee, 104465, "Johnson Torbjorn", 1, male, 99184, {242,038}}.
{employee, 107912, "Carlsson Tuula", 2, female,94556, {242,056}}.
@@ -447,16 +421,13 @@ In_proj</tcaption>
{employee, 104659, "Tornkvist Torbjorn", 2, male, 99514, {222,022}}.
{employee, 104732, "Wikstrom Claes", 2, male, 99586, {221,015}}.
{employee, 117716, "Fedoriw Anna", 1, female,99143, {221,031}}.
- {employee, 115018, "Mattsson Hakan", 3, male, 99251, {203,348}}.
- </code>
- <p><em>Dept</em></p>
+ {employee, 115018, "Mattsson Hakan", 3, male, 99251, {203,348}}.</code>
+ <p><c>dept</c>:</p>
<code type="none">
-
{dept, 'B/SF', "Open Telecom Platform"}.
{dept, 'B/SFP', "OTP - Product Development"}.
- {dept, 'B/SFR', "Computer Science Laboratory"}.
- </code>
- <p><em>Projects</em></p>
+ {dept, 'B/SFR', "Computer Science Laboratory"}.</code>
+ <p><c>projects</c>:</p>
<code type="none">
%% projects
{project, erlang, 1}.
@@ -465,23 +436,19 @@ In_proj</tcaption>
{project, mnesia, 5}.
{project, wolf, 6}.
{project, documentation, 7}.
- {project, www, 8}.
- </code>
- <p>The above three tables, titled <c>employees</c>,
- <c>dept</c>, and <c>projects</c>, are the tables which are
+ {project, www, 8}.</code>
+ <p>These three tables, <c>employees</c>, <c>dept</c>, and
+ <c>projects</c>, are
made up of real records. The following database content is
- stored in the tables which is built on
- relationships. These tables are titled <c>manager</c>,
- <c>at_dep</c>, and <c>in_proj</c>.
- </p>
- <p><em>Manager</em></p>
+ stored in the tables and is built on
+ relationships. These tables are <c>manager</c>,
+ <c>at_dep</c>, and <c>in_proj</c>.</p>
+ <p><c>manager</c>:</p>
<code type="none">
-
{manager, 104465, 'B/SF'}.
{manager, 104465, 'B/SFP'}.
- {manager, 114872, 'B/SFR'}.
- </code>
- <p><em>At_dep</em></p>
+ {manager, 114872, 'B/SFR'}.</code>
+ <p><c>at_dep</c>:</p>
<code type="none">
{at_dep, 104465, 'B/SF'}.
{at_dep, 107912, 'B/SF'}.
@@ -490,9 +457,8 @@ In_proj</tcaption>
{at_dep, 104659, 'B/SFR'}.
{at_dep, 104732, 'B/SFR'}.
{at_dep, 117716, 'B/SFP'}.
- {at_dep, 115018, 'B/SFP'}.
- </code>
- <p><em>In_proj</em></p>
+ {at_dep, 115018, 'B/SFP'}.</code>
+ <p><c>in_proj</c>:</p>
<code type="none">
{in_proj, 104465, otp}.
{in_proj, 107912, otp}.
@@ -508,136 +474,118 @@ In_proj</tcaption>
{in_proj, 117716, otp}.
{in_proj, 117716, documentation}.
{in_proj, 115018, otp}.
- {in_proj, 115018, mnesia}.
- </code>
+ {in_proj, 115018, mnesia}.</code>
<p>The room number is an attribute of the employee
- record. This is a structured attribute which consists of a
+ record. This is a structured attribute that consists of a
tuple. The first element of the tuple identifies a corridor,
- and the second element identifies the actual room in the
- corridor. We could have chosen to represent this as a record
+ and the second element identifies the room in that
+ corridor. An alternative is to represent this as a record
<c>-record(room, {corr, no}).</c> instead of an anonymous
- tuple representation.
- </p>
- <p>The Company database is now initialized and contains
- data. </p>
+ tuple representation.</p>
+ <p>The <c>Company</c> database is now initialized and contains
+ data.</p>
</section>
<section>
<title>Writing Queries</title>
- <p>Retrieving data from DBMS should usually be done with <c>mnesia:read/3</c> or
- <c>mnesia:read/1</c> functions. The following function raises the salary:</p>
+ <p>Retrieving data from DBMS is usually to be done with the
+ functions
+ <seealso marker="mnesia#read/3">mnesia:read/3</seealso> or
+ <seealso marker="mnesia#read/2">mnesia:read/1</seealso>.
+ The following function raises the salary:</p>
<codeinclude file="company.erl" tag="%5" type="erl"></codeinclude>
- <p>Since we want to update the record using <c>mnesia:write/1</c> after we have
- increased the salary we acquire a write lock (third argument to read) when we read the
- record from the table.
- </p>
- <p>It is not always the case that we can directly read the values from the table,
- we might need to search the table or several tables to get the data we want, this
- is done by writing database queries. Queries are always more expensive operations
- than direct lookups done with <c>mnesia:read</c> and should be avoided in performance
- critical code.</p>
- <p>There are two methods for writing database queries:
- </p>
+ <p>Since it is desired to update the record using the function
+ <seealso marker="mnesia#write/1">mnesia:write/1</seealso>
+ after the salary has been increased, a write
+ lock (third argument to <c>read</c>) is acquired when the record from
+ the table is read.</p>
+ <p>To read the values from the table directly is not always possible.
+ It can be needed to search one or more tables to get the
+ wanted data, and this is done by writing database queries. Queries
+ are always more expensive operations than direct lookups done with
+ <c>mnesia:read</c>. Therefore, avoid queries in
+ performance-critical code.</p>
+ <p>Two methods are available for writing database queries:</p>
<list type="bulleted">
- <item>Mnesia functions
- </item>
+ <item><c>Mnesia</c> functions</item>
<item>QLC</item>
</list>
<section>
- <title>Mnesia functions </title>
- <p></p>
+ <title>Using Mnesia Functions</title>
<p>The following function extracts the names of the female employees
- stored in the database:
- </p>
+ stored in the database:</p>
<pre>
-mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]).
- </pre>
- <p>Select must always run within an activity such as a
- transaction. To be able to call from the shell we might
- construct a function as:
- </p>
+mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]).</pre>
+ <p><c>select</c> must always run within an activity, such as a
+ transaction. The following function can be constructed to call
+ from the shell:</p>
<codeinclude file="company.erl" tag="%20" type="erl"></codeinclude>
- <p>The select expression matches all entries in table employee with
- the field sex set to female.
- </p>
- <p>This function can be called from the shell as follows:
- </p>
+ <p>The <c>select</c> expression matches all entries in table
+ employee with the field <c>sex</c> set to <c>female</c>.</p>
+ <p>This function can be called from the shell as follows:</p>
<pre>
(klacke@gin)1> <input>company:all_females().</input>
- {atomic, ["Carlsson Tuula", "Fedoriw Anna"]}
- </pre>
- <p>See also the <seealso marker="Mnesia_chap4#matching">Pattern Matching </seealso>
- chapter for a description of select and its syntax.
- </p>
+ {atomic, ["Carlsson Tuula", "Fedoriw Anna"]}</pre>
+ <p>For a description of <c>select</c> and its syntax, see
+ <seealso marker="Mnesia_chap4#matching">Pattern Matching</seealso>.
+ </p>
</section>
<section>
<title>Using QLC </title>
- <p>This section contains simple introductory examples
- only. Refer to <em>QLC reference manual</em> for a
- full description of the QLC query language. Using QLC
- might be more expensive than using Mnesia functions directly but
- offers a nice syntax.
- </p>
+ <p>This section contains simple introductory examples only. For
+ a full description of the QLC query language, see the
+ <seealso marker="stdlib:qlc">qlc</seealso> manual page in
+ <c>STDLIB</c>.</p>
+ <p>Using QLC can be more expensive than using <c>Mnesia</c>
+ functions directly but offers a nice syntax.</p>
<p>The following function extracts a list of female employees
- from the database:
- </p>
+ from the database:</p>
<pre>
Q = qlc:q([E#employee.name || E <![CDATA[<-]]> mnesia:table(employee),
E#employee.sex == female]),
- qlc:e(Q),
- </pre>
- <p>Accessing mnesia tables from a QLC list comprehension must
+ qlc:e(Q),</pre>
+ <p>Accessing <c>Mnesia</c> tables from a QLC list comprehension must
always be done within a transaction. Consider the following
- function:
- </p>
+ function:</p>
<codeinclude file="company.erl" tag="%2" type="erl"></codeinclude>
- <p>This function can be called from the shell as follows:
- </p>
+ <p>This function can be called from the shell as follows:</p>
<pre>
(klacke@gin)1> <input>company:females().</input>
- {atomic, ["Carlsson Tuula", "Fedoriw Anna"]}
- </pre>
- <p>In traditional relational database terminology, the above
- operation would be called a selection, followed by a projection.
- </p>
- <p>The list comprehension expression shown above contains a
- number of syntactical elements.
- </p>
+ {atomic, ["Carlsson Tuula", "Fedoriw Anna"]}</pre>
+ <p>In traditional relational database terminology, this
+ operation is called a selection, followed by a projection.</p>
+ <p>The previous list comprehension expression contains a
+ number of syntactical elements:</p>
<list type="bulleted">
- <item>the first <c>[</c> bracket should be read as "build the
- list"
+ <item>The first <c>[</c> bracket is read as "build the
+ list".
</item>
- <item>the <c>||</c> "such that" and the arrow <c><![CDATA[<-]]></c> should
- be read as "taken from"
+ <item>The <c>||</c> "such that" and the arrow <c><![CDATA[<-]]></c>
+ is read as "taken from".
</item>
</list>
- <p>Hence, the above list comprehension demonstrates the
- formation of the list <c>E#employee.name</c> such that <c>E</c> is
- taken from the table of employees and the <c>sex</c> attribute
- of each records is equal with the atom <c>female</c>.
- </p>
- <p>The whole list comprehension must be given to the
- <c>qlc:q/1</c> function.
- </p>
- <p>It is possible to combine list comprehensions with low
- level Mnesia functions in the same transaction. If we want to
- raise the salary of all female employees we execute:
- </p>
+ <p>Hence, the previous list comprehension demonstrates the
+ formation of the list <c>E#employee.name</c> such that <c>E</c> is
+ taken from the table of employees, and attribute <c>sex</c>
+ of each record is equal to the atom <c>female</c>.</p>
+ <p>The whole list comprehension must be given to the function
+ <c>qlc:q/1</c>.</p>
+ <p>List comprehensions with low-level <c>Mnesia</c> functions
+ can be combined in the same transaction. To raise the
+ salary of all female employees, execute the following:</p>
<codeinclude file="company.erl" tag="%4" type="erl"></codeinclude>
<p>The function <c>raise_females/1</c> returns the tuple
<c>{atomic, Number}</c>, where <c>Number</c> is the number of
- female employees who received a salary increase. Should an error
- occur, the value <c>{aborted, Reason}</c> is returned. In the
- case of an error, Mnesia guarantees that the salary is not
- raised for any employees at all.
- </p>
+ female employees who received a salary increase. If an error
+ occurs, the value <c>{aborted, Reason}</c> is returned, and
+ <c>Mnesia</c> guarantees that the salary is not
+ raised for any employee.</p>
+ <p><em>Example:</em></p>
<pre>
-
33><input>company:raise_females(33).</input>
- {atomic,2}
- </pre>
+ {atomic,2}</pre>
</section>
</section>
</section>
diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xml b/lib/mnesia/doc/src/Mnesia_chap3.xml
deleted file mode 100644
index ae704b4199..0000000000
--- a/lib/mnesia/doc/src/Mnesia_chap3.xml
+++ /dev/null
@@ -1,556 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year><year>2013</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Building A Mnesia Database</title>
- <prepared></prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date></date>
- <rev></rev>
- <file>Mnesia_chap3.xml</file>
- </header>
- <p>This chapter details the basic steps involved when designing
- a Mnesia database and the programming constructs which make different
- solutions available to the programmer. The chapter includes the following
- sections:
- </p>
- <list type="bulleted">
- <item>defining a schema</item>
- <item>the datamodel</item>
- <item>starting Mnesia</item>
- <item>creating new tables.</item>
- </list>
-
- <section>
- <marker id="def_schema"></marker>
- <title>Defining a Schema</title>
- <p>The configuration of a Mnesia system is described in the
- schema. The schema is a special table which contains information
- such as the table names and each table's
- storage type, (i.e. whether a table should be stored in RAM,
- on disc or possibly on both, as well as its location).
- </p>
- <p>Unlike data tables, information contained in schema tables can only be
- accessed and modified by using the schema related functions
- described in this section.
- </p>
- <p>Mnesia has various functions for defining the
- database schema. It is possible to move tables, delete tables,
- or reconfigure the layout of tables.
- </p>
- <p>An important aspect of these functions is that the system can access a
- table while it is being reconfigured. For example, it is possible to move a
- table and simultaneously perform write operations to the same
- table. This feature is essential for applications that require
- continuous service.
- </p>
- <p>The following section describes the functions available for schema management,
- all of which return a tuple:
- </p>
- <list type="bulleted">
- <item><c>{atomic, ok}</c>; or,
- </item>
- <item><c>{aborted, Reason}</c> if unsuccessful.</item>
- </list>
-
- <section>
- <title>Schema Functions</title>
- <list type="bulleted">
- <item><c>mnesia:create_schema(NodeList)</c>. This function is
- used to initialize a new, empty schema. This is a mandatory
- requirement before Mnesia can be started. Mnesia is a truly
- distributed DBMS and the schema is a system table that is
- replicated on all nodes in a Mnesia system.
- The function will fail if a schema is already present on any of
- the nodes in <c>NodeList</c>. This function requires Mnesia
- to be stopped on the all
- <c>db_nodes</c> contained in the parameter <c>NodeList</c>.
- Applications call this function only once,
- since it is usually a one-time activity to initialize a new
- database.
- </item>
- <item><c>mnesia:delete_schema(DiscNodeList)</c>. This function
- erases any old schemas on the nodes in
- <c>DiscNodeList</c>. It also removes all old tables together
- with all data. This function requires Mnesia to be stopped
- on all <c>db_nodes</c>.
- </item>
- <item><c>mnesia:delete_table(Tab)</c>. This function
- permanently deletes all replicas of table <c>Tab</c>.
- </item>
- <item><c>mnesia:clear_table(Tab)</c>. This function
- permanently deletes all entries in table <c>Tab</c>.
- </item>
- <item><c>mnesia:move_table_copy(Tab, From, To)</c>. This
- function moves the copy of table <c>Tab</c> from node
- <c>From</c> to node <c>To</c>. The table storage type,
- <c>{type}</c> is preserved, so if a RAM table is moved from
- one node to another node, it remains a RAM table on the new
- node. It is still possible for other transactions to perform
- read and write operation to the table while it is being
- moved.
- </item>
- <item><c>mnesia:add_table_copy(Tab, Node, Type)</c>. This
- function creates a replica of the table <c>Tab</c> at node
- <c>Node</c>. The <c>Type</c> argument must be either of the
- atoms <c>ram_copies</c>, <c>disc_copies</c>, or
- <c>disc_only_copies</c>. If we add a copy of the system
- table <c>schema</c> to a node, this means that we want the
- Mnesia schema to reside there as well. This action then
- extends the set of nodes that comprise this particular
- Mnesia system.
- </item>
- <item><c>mnesia:del_table_copy(Tab, Node)</c>. This function
- deletes the replica of table <c>Tab</c> at node <c>Node</c>.
- When the last replica of a table is removed, the table is
- deleted.
- </item>
- <item>
- <p><c>mnesia:transform_table(Tab, Fun, NewAttributeList, NewRecordName)</c>. This
- function changes the format on all records in table
- <c>Tab</c>. It applies the argument <c>Fun</c> to all
- records in the table. <c>Fun</c> shall be a function which
- takes a record of the old type, and returns the record of the new
- type. The table key may not be changed.</p>
- <code type="none">
--record(old, {key, val}).
--record(new, {key, val, extra}).
-
-Transformer =
- fun(X) when record(X, old) ->
- #new{key = X#old.key,
- val = X#old.val,
- extra = 42}
- end,
-{atomic, ok} = mnesia:transform_table(foo, Transformer,
- record_info(fields, new),
- new),
- </code>
- <p>The <c>Fun</c> argument can also be the atom
- <c>ignore</c>, it indicates that only the meta data about the table will
- be updated. Usage of <c>ignore</c> is not recommended (since it creates
- inconsistencies between the meta data and the actual data) but included
- as a possibility for the user to do his own (off-line) transform.</p>
- </item>
- <item><c>change_table_copy_type(Tab, Node, ToType)</c>. This
- function changes the storage type of a table. For example, a
- RAM table is changed to a disc_table at the node specified
- as <c>Node</c>.</item>
- </list>
- </section>
- </section>
-
- <section>
- <title>The Data Model</title>
- <p>The data model employed by Mnesia is an extended
- relational data model. Data is organized as a set of
- tables and relations between different data records can
- be modeled as additional tables describing the actual
- relationships.
- Each table contains instances of Erlang records
- and records are represented as Erlang tuples.
- </p>
- <p>Object identifiers, also known as oid, are made up of a table name and a key.
- For example, if we have an employee record represented by the tuple
- <c>{employee, 104732, klacke, 7, male, 98108, {221, 015}}</c>.
- This record has an object id, (Oid) which is the tuple
- <c>{employee, 104732}</c>.
- </p>
- <p>Thus, each table is made up of records, where the first element
- is a record name and the second element of the table is a key
- which identifies the particular record in that table. The
- combination of the table name and a key, is an arity two tuple
- <c>{Tab, Key}</c> called the Oid. See Chapter 4:<seealso marker="Mnesia_chap4#recordnames_tablenames">Record Names Versus Table Names</seealso>, for more information
- regarding the relationship between the record name and the table
- name.
- </p>
- <p>What makes the Mnesia data model an extended relational model
- is the ability to store arbitrary Erlang terms in the attribute
- fields. One attribute value could for example be a whole tree of
- oids leading to other terms in other tables. This
- type of record is hard to model in traditional relational
- DBMSs.</p>
- </section>
-
- <section>
- <marker id="start_mnesia"></marker>
- <title>Starting Mnesia</title>
- <p>Before we can start Mnesia, we must initialize an empty schema
- on all the participating nodes.
- </p>
- <list type="bulleted">
- <item>The Erlang system must be started.
- </item>
- <item>Nodes with disc database schema must be defined and
- implemented with the function <c>create_schema(NodeList).</c></item>
- </list>
- <p>When running a distributed system, with two or more
- participating nodes, then the <c>mnesia:start( ).</c> function
- must be executed on each participating node. Typically this would
- be part of the boot script in an embedded environment.
- In a test environment or an interactive environment,
- <c>mnesia:start()</c> can also be used either from the
- Erlang shell, or another program.
- </p>
-
- <section>
- <title>Initializing a Schema and Starting Mnesia</title>
- <p>To use a known example, we illustrate how to run the
- Company database described in Chapter 2 on two separate nodes,
- which we call <c>a@gin</c> and <c>b@skeppet</c>. Each of these
- nodes must have have a Mnesia directory as well as an
- initialized schema before Mnesia can be started. There are two
- ways to specify the Mnesia directory to be used:
- </p>
- <list type="bulleted">
- <item>
- <p>Specify the Mnesia directory by providing an application
- parameter either when starting the Erlang shell or in the
- application script. Previously the following example was used
- to create the directory for our Company database:</p>
- <pre>
-%<input>erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'</input>
- </pre>
- </item>
- <item>If no command line flag is entered, then the Mnesia
- directory will be the current working directory on the node
- where the Erlang shell is started.</item>
- </list>
- <p>To start our Company database and get it running on the two
- specified nodes, we enter the following commands:
- </p>
- <list type="ordered">
- <item>
- <p>On the node called gin:</p>
- <pre>
- gin %<input>erl -sname a -mnesia dir '"/ldisc/scratch/Mnesia.company"'</input>
- </pre>
- </item>
- <item>
- <p>On the node called skeppet:</p>
- <pre>
-skeppet %<input>erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'</input>
- </pre>
- </item>
- <item>
- <p>On one of the two nodes:</p>
- <pre>
-(a@gin1)><input>mnesia:create_schema([a@gin, b@skeppet]).</input>
- </pre>
- </item>
- <item>The function <c>mnesia:start()</c> is called on both
- nodes.
- </item>
- <item>
- <p>To initialize the database, execute the following
- code on one of the two nodes.</p>
- <codeinclude file="company.erl" tag="%12" type="erl"></codeinclude>
- </item>
- </list>
- <p>As illustrated above, the two directories reside on different nodes, because the
- <c>/ldisc/scratch</c> (the "local" disc) exists on the two different
- nodes.
- </p>
- <p>By executing these commands we have configured two Erlang
- nodes to run the Company database, and therefore, initialize the
- database. This is required only once when setting up, the next time the
- system is started <c>mnesia:start()</c> is called
- on both nodes, to initialize the system from disc.
- </p>
- <p>In a system of Mnesia nodes, every node is aware of the
- current location of all tables. In this example, data is
- replicated on both nodes and functions which manipulate the
- data in our tables can be executed on either of the two nodes.
- Code which manipulate Mnesia data behaves identically
- regardless of where the data resides.
- </p>
- <p>The function <c>mnesia:stop()</c> stops Mnesia on the node
- where the function is executed. Both the <c>start/0</c> and
- the <c>stop/0</c> functions work on the "local" Mnesia system,
- and there are no functions which start or stop a set of nodes.
- </p>
- </section>
-
- <section>
- <title>The Start-Up Procedure</title>
- <p>Mnesia is started by calling the following function:
- </p>
- <code type="none">
- mnesia:start().
- </code>
- <p>This function initiates the DBMS locally. </p>
- <p>The choice of configuration will alter the location and load
- order of the tables. The alternatives are listed below: <br></br>
-</p>
- <list type="ordered">
- <item>Tables that are stored locally only, are initialized
- from the local Mnesia directory.
- </item>
- <item>Replicated tables that reside locally
- as well as somewhere else are either initiated from disc or
- by copying the entire table from the other node depending on
- which of the different replicas is the most recent. Mnesia
- determines which of the tables is the most recent.
- </item>
- <item>Tables that reside on remote nodes are available to other nodes as soon
- as they are loaded.</item>
- </list>
- <p>Table initialization is asynchronous, the function
- call <c>mnesia:start()</c> returns the atom <c>ok</c> and
- then starts to initialize the different tables. Depending on
- the size of the database, this may take some time, and the
- application programmer must wait for the tables that the
- application needs before they can be used. This achieved by using
- the function:</p>
- <list type="bulleted">
- <item><c>mnesia:wait_for_tables(TabList, Timeout)</c></item>
- </list>
- <p>This function suspends the caller until all tables
- specified in <c>TabList</c> are properly initiated.
- </p>
- <p>A problem can arise if a replicated table on one node is
- initiated, but Mnesia deduces that another (remote)
- replica is more recent than the replica existing on
- the local node, the initialization procedure will not proceed.
- In this situation, a call to to
- <c>mnesia:wait_for_tables/2</c> suspends the caller until the
- remote node has initiated the table from its local disc and
- the node has copied the table over the network to the local node.
- </p>
- <p>This procedure can be time consuming however, the shortcut function
- shown below will load all the tables from disc at a faster rate:
- </p>
- <list type="bulleted">
- <item><c>mnesia:force_load_table(Tab)</c>. This function forces
- tables to be loaded from disc regardless of the network
- situation.</item>
- </list>
- <p>Thus, we can assume that if an application
- wishes to use tables <c>a</c> and <c>b</c>, then the
- application must perform some action similar to the below code before it can utilize the tables.
- </p>
- <pre>
- case mnesia:wait_for_tables([a, b], 20000) of
- {timeout, RemainingTabs} ->
- panic(RemainingTabs);
- ok ->
- synced
- end.
- </pre>
- <warning>
- <p>When tables are forcefully loaded from the local disc,
- all operations that were performed on the replicated table
- while the local node was down, and the remote replica was
- alive, are lost. This can cause the database to become
- inconsistent.</p>
- </warning>
- <p>If the start-up procedure fails, the
- <c>mnesia:start()</c> function returns the cryptic tuple
- <c>{error,{shutdown, {mnesia_sup,start,[normal,[]]}}}</c>.
- Use command line arguments -boot start_sasl as argument to
- the erl script in order to get more information
- about the start failure.
- </p>
- </section>
- </section>
-
- <section>
- <marker id="create_tables"></marker>
- <title>Creating New Tables</title>
- <p>Mnesia provides one function to create new tables. This
- function is: <c>mnesia:create_table(Name, ArgList).</c></p>
- <p>When executing this function, it returns one of the following
- responses:
- </p>
- <list type="bulleted">
- <item><c>{atomic, ok}</c> if the function executes
- successfully
- </item>
- <item><c>{aborted, Reason}</c> if the function fails.
- </item>
- </list>
- <p>The function arguments are:
- </p>
- <list type="bulleted">
- <item><c>Name</c> is the atomic name of the table. It is
- usually the same name as the name of the records that
- constitute the table. (See <c>record_name</c> for more
- details.)
- </item>
- <item>
- <p><c>ArgList</c> is a list of <c>{Key,Value}</c> tuples.
- The following arguments are valid:
- </p>
- <list type="bulleted">
- <item>
- <p><c>{type, Type}</c> where <c>Type</c> must be either of the
- atoms <c>set</c>, <c>ordered_set</c> or <c>bag</c>.
- The default value is
- <c>set</c>. Note: currently 'ordered_set'
- is not supported for 'disc_only_copies' tables.
- A table of type <c>set</c> or <c>ordered_set</c> has either zero or
- one record per key. Whereas a table of type <c>bag</c> can
- have an arbitrary number of records per key. The key for
- each record is always the first attribute of the record.</p>
- <p>The following example illustrates the difference between
- type <c>set</c> and <c>bag</c>: </p>
- <pre>
- f() -> F = fun() ->
- mnesia:write({foo, 1, 2}), mnesia:write({foo, 1, 3}),
- mnesia:read({foo, 1}) end, mnesia:transaction(F). </pre>
- <p>This transaction will return the list <c>[{foo,1,3}]</c> if
- the <c>foo</c> table is of type <c>set</c>. However, list
- <c>[{foo,1,2}, {foo,1,3}]</c> will return if the table is
- of type <c>bag</c>. Note the use of <c>bag</c> and
- <c>set</c> table types. </p>
- <p>Mnesia tables can never contain
- duplicates of the same record in the same table. Duplicate
- records have attributes with the same contents and key.
- </p>
- </item>
- <item>
- <p><c>{disc_copies, NodeList}</c>, where <c>NodeList</c> is a
- list of the nodes where this table will reside on disc.</p>
- <p>Write operations to a table replica of type
- <c>disc_copies</c> will write data to the disc copy as well
- as to the RAM copy of the table. </p>
- <p>It is possible to have a
- replicated table of type <c>disc_copies</c> on one node, and
- the same table stored as a different type on another node.
- The default value is <c>[]</c>. This arrangement is
- desirable if we want the following operational
- characteristics are required:</p>
- <list type="ordered">
- <item>read operations must be very fast and performed in RAM
- </item>
- <item>all write operations must be written to persistent
- storage.</item>
- </list>
- <p>A write operation on a <c>disc_copies</c> table
- replica will be performed in two steps. First the write
- operation is appended to a log file, then the actual
- operation is performed in RAM.
- </p>
- </item>
- <item>
- <p><c>{ram_copies, NodeList}</c>, where <c>NodeList</c> is a
- list of the nodes where this table is stored in RAM. The
- default value for <c>NodeList</c> is <c>[node()]</c>. If the
- default value is used to create a new table, it will be
- located on the local node only. </p>
- <p>Table replicas of type
- <c>ram_copies</c> can be dumped to disc with the function
- <c>mnesia:dump_tables(TabList)</c>.
- </p>
- </item>
- <item><c>{disc_only_copies, NodeList}</c>. These table
- replicas are stored on disc only and are therefore slower to
- access. However, a disc only replica consumes less memory than
- a table replica of the other two storage types.
- </item>
- <item><c>{index, AttributeNameList}</c>, where
- <c>AttributeNameList</c> is a list of atoms specifying the
- names of the attributes Mnesia shall build and maintain. An
- index table will exist for every element in the list. The
- first field of a Mnesia record is the key and thus need no
- extra index.
- <br></br>
-The first field of a record is the second element of the
- tuple, which is the representation of the record.
- </item>
- <item><c>{snmp, SnmpStruct}</c>. <c>SnmpStruct</c> is
- described in the SNMP User Guide. Basically, if this attribute
- is present in <c>ArgList</c> of <c>mnesia:create_table/2</c>,
- the table is immediately accessible by means of the Simple
- Network Management Protocol (SNMP).
- <br></br>
-It is easy to design applications which use SNMP to
- manipulate and control the system. Mnesia provides a direct
- mapping between the logical tables that make up an SNMP
- control application and the physical data which make up a
- Mnesia table. <c>[]</c>
- is default.
- </item>
- <item><c>{local_content, true}</c> When an application needs a
- table whose contents should be locally unique on each
- node,
- <c>local_content</c> tables may be used. The name of the
- table is known to all Mnesia nodes, but its contents is
- unique for each node. Access to this type of table must be
- done locally. </item>
- <item>
- <p><c>{attributes, AtomList}</c> is a list of the attribute
- names for the records that are supposed to populate the
- table. The default value is the list <c>[key, val]</c>. The
- table must at least have one extra attribute besides the
- key. When accessing single attributes in a record, it is not
- recommended to hard code the attribute names as atoms. Use
- the construct <c>record_info(fields,record_name)</c>
- instead. The expression
- <c>record_info(fields,record_name)</c> is processed by the
- Erlang macro pre-processor and returns a list of the
- record's field names. With the record definition
- <c>-record(foo, {x,y,z}).</c> the expression
- <c>record_info(fields,foo)</c> is expanded to the list
- <c>[x,y,z]</c>. Accordingly, it is possible to provide the
- attribute names yourself, or to use the <c>record_info/2</c>
- notation. </p>
- <p>It is recommended that
- the <c>record_info/2</c> notation be used as it is easier to
- maintain the program and it will be more robust with regards
- to future record changes.
- </p>
- </item>
- <item>
- <p><c>{record_name, Atom}</c> specifies the common name of
- all records stored in the table. All records, stored in
- the table, must have this name as their first element.
- The <c>record_name</c> defaults to the name of the
- table. For more information see Chapter 4:<seealso marker="Mnesia_chap4#recordnames_tablenames">Record Names Versus Table Names</seealso>.</p>
- </item>
- </list>
- </item>
- </list>
- <p>As an example, assume we have the record definition:</p>
- <pre>
- -record(funky, {x, y}).
- </pre>
- <p>The below call would create a table which is replicated on two
- nodes, has an additional index on the <c>y</c> attribute, and is
- of type
- <c>bag</c>.</p>
- <pre>
- mnesia:create_table(funky, [{disc_copies, [N1, N2]}, {index,
- [y]}, {type, bag}, {attributes, record_info(fields, funky)}]).
- </pre>
- <p>Whereas a call to the below default code values: </p>
- <pre>
-mnesia:create_table(stuff, []) </pre>
- <p>would return a table with a RAM copy on the
- local node, no additional indexes and the attributes defaulted to
- the list <c>[key,val]</c>.</p>
- </section>
-</chapter>
-
diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
new file mode 100644
index 0000000000..849b5f4281
--- /dev/null
+++ b/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
@@ -0,0 +1,521 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+ under the License.
+
+ </legalnotice>
+
+ <title>Build a Mnesia Database</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
+ <file>Mnesia_chap3.xml</file>
+ </header>
+ <p>This section describes the basic steps when designing a
+ <c>Mnesia</c> database and the programming constructs that make different
+ solutions available to the programmer. The following topics are
+ included:</p>
+ <list type="bulleted">
+ <item>Define a schema</item>
+ <item>Data model</item>
+ <item>Start <c>Mnesia</c></item>
+ <item>Create tables</item>
+ </list>
+
+ <section>
+ <marker id="def_schema"></marker>
+ <title>Define a Schema</title>
+ <p>The configuration of a <c>Mnesia</c> system is described in a
+ schema. The schema is a special table that includes information
+ such as the table names and the storage type of each table
+ (that is, whether a table is to be stored in RAM,
+ on disc, or on both, as well as its location).</p>
+ <p>Unlike data tables, information in schema tables can only be
+ accessed and modified by using the schema-related functions
+ described in this section.</p>
+ <p><c>Mnesia</c> has various functions for defining the
+ database schema. Tables can be moved or deleted, and the
+ table layout can be reconfigured.</p>
+ <p>An important aspect of these functions is that the system can access
+ a table while it is being reconfigured. For example, it is possible
+ to move a
+ table and simultaneously perform write operations to the same
+ table. This feature is essential for applications that require
+ continuous service.</p>
+ <p>This section describes the functions available for schema management,
+ all which return either of the following tuples:</p>
+ <list type="bulleted">
+ <item><c>{atomic, ok}</c> if successful</item>
+ <item><c>{aborted, Reason}</c> if unsuccessful</item>
+ </list>
+
+ <section>
+ <title>Schema Functions</title>
+ <p>The schema functions are as follows:</p>
+ <list type="bulleted">
+ <item><seealso marker="mnesia#create_schema/1">mnesia:create_schema(NodeList)</seealso>
+ initializes a new, empty schema. This is a mandatory requirement
+ before <c>Mnesia</c> can be started. <c>Mnesia</c> is a truly
+ distributed DBMS and the schema is a system table that is
+ replicated on all nodes in a <c>Mnesia</c> system.
+ This function fails if a schema is already present on any of
+ the nodes in <c>NodeList</c>. The function requires <c>Mnesia</c>
+ to be stopped on the all
+ <c>db_nodes</c> contained in parameter <c>NodeList</c>.
+ Applications call this function only once, as
+ it is usually a one-time activity to initialize a new database.
+ </item>
+ <item><seealso marker="mnesia#delete_schema/1">mnesia:delete_schema(DiscNodeList)</seealso>
+ erases any old schemas on the nodes in
+ <c>DiscNodeList</c>. It also removes all old tables together
+ with all data. This function requires <c>Mnesia</c> to be stopped
+ on all <c>db_nodes</c>.
+ </item>
+ <item><seealso marker="mnesia#delete_table/1">mnesia:delete_table(Tab)</seealso>
+ permanently deletes all replicas of table <c>Tab</c>.
+ </item>
+ <item><seealso marker="mnesia#clear_table/1">mnesia:clear_table(Tab)</seealso>
+ permanently deletes all entries in table <c>Tab</c>.
+ </item>
+ <item><seealso marker="mnesia#move_table_copy/3">mnesia:move_table_copy(Tab, From, To)</seealso>
+ moves the copy of table <c>Tab</c> from node
+ <c>From</c> to node <c>To</c>. The table storage type
+ <c>{type}</c> is preserved, so if a RAM table is moved from
+ one node to another, it remains a RAM table on the new
+ node. Other transactions can still perform read
+ and write operation to the table while it is being moved.
+ </item>
+ <item><seealso marker="mnesia#add_table_copy/3">mnesia:add_table_copy(Tab, Node, Type)</seealso>
+ creates a replica of table <c>Tab</c> at node
+ <c>Node</c>. Argument <c>Type</c> must be either of the
+ atoms <c>ram_copies</c>, <c>disc_copies</c>, or
+ <c>disc_only_copies</c>. If you add a copy of the system
+ table <c>schema</c> to a node, you want the <c>Mnesia</c>
+ schema to reside there as well. This action
+ extends the set of nodes that comprise this particular
+ <c>Mnesia</c> system.
+ </item>
+ <item><seealso marker="mnesia#del_table_copy/2">mnesia:del_table_copy(Tab, Node)</seealso>
+ deletes the replica of table <c>Tab</c> at node <c>Node</c>.
+ When the last replica of a table is removed, the table is
+ deleted.
+ </item>
+ <item>
+ <p><seealso marker="mnesia#transform_table/4">mnesia:transform_table(Tab, Fun, NewAttributeList, NewRecordName)</seealso>
+ changes the format on all records in table
+ <c>Tab</c>. It applies argument <c>Fun</c> to all
+ records in the table. <c>Fun</c> must be a function that
+ takes a record of the old type, and returns the record of the
+ new type. The table key must not be changed.</p>
+ <p><em>Example:</em></p>
+ <code type="none">
+-record(old, {key, val}).
+-record(new, {key, val, extra}).
+
+Transformer =
+ fun(X) when record(X, old) ->
+ #new{key = X#old.key,
+ val = X#old.val,
+ extra = 42}
+ end,
+{atomic, ok} = mnesia:transform_table(foo, Transformer,
+ record_info(fields, new),
+ new),
+</code>
+ <p>Argument <c>Fun</c> can also be the atom
+ <c>ignore</c>, which indicates that only the metadata about
+ the table is updated. Use of <c>ignore</c> is not recommended
+ (as it creates inconsistencies between the metadata and the
+ actual data) but it is included as a possibility for the user
+ do to an own (offline) transform.</p>
+ </item>
+ <item><c>change_table_copy_type(Tab, Node, ToType)</c>
+ changes the storage type of a table. For example, a
+ RAM table is changed to a <c>disc_table</c> at the node specified
+ as <c>Node</c>.</item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Data Model</title>
+ <p>The data model employed by <c>Mnesia</c> is an extended
+ relational data model. Data is organized as a set of
+ tables and relations between different data records can
+ be modeled as more tables describing the relationships.
+ Each table contains instances of Erlang records.
+ The records are represented as Erlang tuples.</p>
+ <p>Each Object Identifier (OID) is made up of a table name and a key.
+ For example, if an employee record is represented by the tuple
+ <c>{employee, 104732, klacke, 7, male, 98108, {221, 015}}</c>,
+ this record has an OID, which is the tuple
+ <c>{employee, 104732}</c>.</p>
+ <p>Thus, each table is made up of records, where the first element
+ is a record name and the second element of the table is a key,
+ which identifies the particular record in that table. The
+ combination of the table name and a key is an arity two tuple
+ <c>{Tab, Key}</c> called the OID. For more information about
+ the relationship beween the record name and the table name, see
+ <seealso marker="Mnesia_chap4#recordnames_tablenames">Record Names versus Table Names</seealso>.
+ </p>
+ <p>What makes the <c>Mnesia</c> data model an extended relational model
+ is the ability to store arbitrary Erlang terms in the attribute
+ fields. One attribute value can, for example, be a whole tree of
+ OIDs leading to other terms in other tables. This type
+ of record is difficult to model in traditional relational DBMSs.</p>
+ </section>
+
+ <section>
+ <marker id="start_mnesia"></marker>
+ <title>Start Mnesia</title>
+ <p>Before starting <c>Mnesia</c>, the following must be done:
+ </p>
+ <list type="bulleted">
+ <item>An empty schema must be initialized on all the
+ participating nodes.</item>
+ <item>The Erlang system must be started.</item>
+ <item>Nodes with disc database schema must be defined and
+ implemented with the function
+ <seealso marker="mnesia#create_schema/1">mnesia:create_schema(NodeList)</seealso>.</item>
+ </list>
+ <p>When running a distributed system with two or more
+ participating nodes, the function
+ <seealso marker="mnesia#start/0">mnesia:start()</seealso>
+ must be executed on each participating node. This would typically
+ be part of the boot script in an embedded environment.
+ In a test environment or an interactive environment,
+ <c>mnesia:start()</c> can also be used either from the
+ Erlang shell or another program.
+ </p>
+
+ <section>
+ <title>Initialize a Schema and Start Mnesia</title>
+ <p>Let us use the example database <c>Company</c>, described in
+ <seealso marker="Mnesia_chap2#getting_started">Getting Started</seealso> to
+ illustrate how to run a database on two separate nodes,
+ called <c>a@gin</c> and <c>b@skeppet</c>. Each of these
+ nodes must have a <c>Mnesia</c> directory and an
+ initialized schema before <c>Mnesia</c> can be started. There are
+ two ways to specify the <c>Mnesia</c> directory to be used:</p>
+ <list type="bulleted">
+ <item>
+ <p>Specify the <c>Mnesia</c> directory by providing an application
+ parameter either when starting the Erlang shell or in the
+ application script. Previously, the following example was used
+ to create the directory for the <c>Company</c> database:</p>
+ <pre>
+%<input>erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'</input>
+ </pre>
+ </item>
+ <item>If no command-line flag is entered, the <c>Mnesia</c>
+ directory becomes the current working directory on the node
+ where the Erlang shell is started.</item>
+ </list>
+ <p>To start the <c>Company</c> database and get it running on the two
+ specified nodes, enter the following commands:</p>
+ <list type="ordered">
+ <item>
+ <p>On the node <c>a@gin</c>:</p>
+ <pre>
+ gin %<input>erl -sname a -mnesia dir '"/ldisc/scratch/Mnesia.company"'</input></pre>
+ </item>
+ <item><p>On the node <c>b@skeppet</c>:</p>
+ <pre>
+skeppet %<input>erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'</input></pre>
+ </item>
+ <item>
+ <p>On one of the two nodes:</p>
+ <pre>
+(a@gin)1><input>mnesia:create_schema([a@gin, b@skeppet]).</input></pre>
+ </item>
+ <item>The function
+ <seealso marker="mnesia#start/0">mnesia:start()</seealso>
+ is called on both nodes.
+ </item>
+ <item><p>To initialize the database, execute the following
+ code on one of the two nodes:</p>
+ <codeinclude file="company.erl" tag="%12" type="erl"></codeinclude>
+ </item>
+ </list>
+ <p>As illustrated, the two directories reside on different nodes,
+ because <c>/ldisc/scratch</c> (the "local" disc) exists on
+ the two different nodes.</p>
+ <p>By executing these commands, two Erlang nodes are configured to
+ run the <c>Company</c> database, and therefore, initialize the
+ database. This is required only once when setting up. The next time
+ the system is started,
+ <seealso marker="mnesia#start/0">mnesia:start()</seealso>
+ is called
+ on both nodes, to initialize the system from disc.</p>
+ <p>In a system of <c>Mnesia</c> nodes, every node is aware of the
+ current location of all tables. In this example, data is
+ replicated on both nodes and functions that manipulate the
+ data in the tables can be executed on either of the two nodes.
+ Code that manipulate <c>Mnesia</c> data behaves identically
+ regardless of where the data resides.</p>
+ <p>The function <seealso marker="mnesia#stop/0">mnesia:stop()</seealso>
+ stops <c>Mnesia</c> on the node
+ where the function is executed. The functions <c>mnesia:start/0</c>
+ and <c>mnesia:stop/0</c> work on the "local" <c>Mnesia</c> system.
+ No functions start or stop a set of nodes.</p>
+ </section>
+
+ <section>
+ <title>Startup Procedure</title>
+ <p>Start <c>Mnesia</c> by calling the following function:</p>
+ <code type="none">
+ mnesia:start().</code>
+ <p>This function initiates the DBMS locally.</p>
+ <p>The choice of configuration alters the location and load
+ order of the tables. The alternatives are as follows:</p>
+ <list type="ordered">
+ <item>Tables that are only stored locally are initialized
+ from the local <c>Mnesia</c> directory.
+ </item>
+ <item>Replicated tables that reside locally
+ as well as somewhere else are either initiated from disc or
+ by copying the entire table from the other node, depending on
+ which of the different replicas are the most recent. <c>Mnesia</c>
+ determines which of the tables are the most recent.
+ </item>
+ <item>Tables that reside on remote nodes are available to other
+ nodes as soon as they are loaded.</item>
+ </list>
+ <p>Table initialization is asynchronous. The function
+ call <seealso marker="mnesia#start/0">mnesia:start()</seealso>
+ returns the atom <c>ok</c> and
+ then starts to initialize the different tables. Depending on
+ the size of the database, this can take some time, and the
+ application programmer must wait for the tables that the
+ application needs before they can be used. This is achieved by
+ using the function
+ <seealso marker="mnesia#wait_for_tables/2">mnesia:wait_for_tables(TabList, Timeout)</seealso>,
+ which suspends the caller until all tables
+ specified in <c>TabList</c> are properly initiated.</p>
+ <p>A problem can arise if a replicated table on one node is
+ initiated, but <c>Mnesia</c> deduces that another (remote)
+ replica is more recent than the replica existing on the
+ local node, and the initialization procedure does not proceed.
+ In this situation, a call to
+ <seealso marker="mnesia#wait_for_tables/2">mnesia:wait_for_tables/2</seealso>,
+ suspends the caller until the
+ remote node has initialized the table from its local disc and
+ the node has copied the table over the network to the local node.</p>
+ <p>However, this procedure can be time-consuming, the shortcut function
+ <seealso marker="mnesia#force_load_table/1">mnesia:force_load_table(Tab)</seealso>
+ loads all the tables from disc at a faster rate. The function forces
+ tables to be loaded from disc regardless of the network
+ situation.</p>
+ <p>Thus, it can be assumed that if an application wants to use
+ tables <c>a</c> and <c>b</c>, the application must perform
+ some action similar to following before it can use the tables:</p>
+ <pre>
+ case mnesia:wait_for_tables([a, b], 20000) of
+ {timeout, RemainingTabs} ->
+ panic(RemainingTabs);
+ ok ->
+ synced
+ end.</pre>
+ <warning>
+ <p>When tables are forcefully loaded from the local disc,
+ all operations that were performed on the replicated table
+ while the local node was down, and the remote replica was
+ alive, are lost. This can cause the database to become
+ inconsistent.</p>
+ </warning>
+ <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>.
+ 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>
+ </section>
+ </section>
+
+ <section>
+ <marker id="create_tables"></marker>
+ <title>Create Tables</title>
+ <p>The function
+ <seealso marker="mnesia#create_table/2">mnesia:create_table(Name, ArgList)</seealso>
+ creates tables. When executing this function, it returns one of
+ the following responses:</p>
+ <list type="bulleted">
+ <item><c>{atomic, ok}</c> if the function executes successfully
+ </item>
+ <item><c>{aborted, Reason}</c> if the function fails
+ </item>
+ </list>
+ <p>The function arguments are as follows:</p>
+ <list type="bulleted">
+ <item><c>Name</c> is the name of the table. It is
+ usually the same name as the name of the records that
+ constitute the table. For details, see <c>record_name</c>.
+ </item>
+ <item>
+ <p><c>ArgList</c> is a list of <c>{Key,Value}</c> tuples.
+ The following arguments are valid:</p>
+ <list type="bulleted">
+ <item>
+ <p><c>{type, Type}</c>, where <c>Type</c> must be either of
+ the atoms <c>set</c>, <c>ordered_set</c>, or <c>bag</c>.
+ Default is <c>set</c>.</p>
+ <p>Notice that currently <c>ordered_set</c> is not
+ supported for <c>disc_only_copies</c> tables.</p>
+ <p>A table of type
+ <c>set</c> or <c>ordered_set</c> has either zero or
+ one record per key, whereas a table of type <c>bag</c> can
+ have an arbitrary number of records per key. The key for
+ each record is always the first attribute of the record.</p>
+ <p>The following example illustrates the difference between
+ type <c>set</c> and <c>bag</c>:</p>
+ <pre>
+ f() ->
+ F = fun() ->
+ mnesia:write({foo, 1, 2}),
+ mnesia:write({foo, 1, 3}),
+ mnesia:read({foo, 1})
+ end,
+ mnesia:transaction(F).</pre>
+ <p>This transaction returns the list <c>[{foo,1,3}]</c> if
+ table <c>foo</c> is of type <c>set</c>. However, the list
+ <c>[{foo,1,2}, {foo,1,3}]</c> is returned if the table is
+ of type <c>bag</c>.</p>
+ <p><c>Mnesia</c> tables can never contain
+ duplicates of the same record in the same table. Duplicate
+ records have attributes with the same contents and key.</p>
+ </item>
+ <item>
+ <p><c>{disc_copies, NodeList}</c>, where <c>NodeList</c> is a
+ list of the nodes where this table is to reside on disc.</p>
+ <p>Write operations to a table replica of type
+ <c>disc_copies</c> write data to the disc copy and
+ to the RAM copy of the table.</p>
+ <p>It is possible to have a
+ replicated table of type <c>disc_copies</c> on one node, and
+ the same table stored as a different type on another node.
+ Default is <c>[]</c>. This arrangement is
+ desirable if the following operational
+ characteristics are required:</p>
+ <list type="ordered">
+ <item>Read operations must be fast and performed in RAM.</item>
+ <item>All write operations must be written to persistent
+ storage.</item>
+ </list>
+ <p>A write operation on a <c>disc_copies</c> table
+ replica is performed in two steps. First the write
+ operation is appended to a log file, then the actual
+ operation is performed in RAM.</p>
+ </item>
+ <item>
+ <p><c>{ram_copies, NodeList}</c>, where <c>NodeList</c> is a
+ list of the nodes where this table is stored in RAM.
+ Default is <c>[node()]</c>. If the default value is used
+ to create a table, it is located on the local node only.</p>
+ <p>Table replicas of type
+ <c>ram_copies</c> can be dumped to disc with the function
+ <seealso marker="mnesia#dump_tables/1">mnesia:dump_tables(TabList)</seealso>.</p>
+ </item>
+ <item><c>{disc_only_copies, NodeList}</c>. These table
+ replicas are stored on disc only and are therefore slower to
+ access. However, a disc-only replica consumes less memory than
+ a table replica of the other two storage types.
+ </item>
+ <item><p><c>{index, AttributeNameList}</c>, where
+ <c>AttributeNameList</c> is a list of atoms specifying the
+ names of the attributes <c>Mnesia</c> is to build and maintain.
+ An index table exists for every element in the list. The first
+ field of a <c>Mnesia</c> record is the key and thus need no
+ extra index.</p>
+ <p>The first field of a record is the second element of the
+ tuple, which is the representation of the record.</p>
+ </item>
+ <item><p><c>{snmp, SnmpStruct}</c>. <c>SnmpStruct</c> is
+ described in the
+ <seealso marker="snmp:index">SNMP</seealso> User's Guide.
+ Basically, if this attribute is present in <c>ArgList</c> of
+ <seealso marker="mnesia#create_table/2">mnesia:create_table/2</seealso>,
+ the table is immediately accessible the SNMP.</p>
+ <p>It is easy to design applications that use SNMP to
+ manipulate and control the system. <c>Mnesia</c> provides a
+ direct mapping between the logical tables that make up an SNMP
+ control application and the physical data that makes up a
+ <c>Mnesia</c> table. The default value is <c>[]</c>.</p>
+ </item>
+ <item><c>{local_content, true}</c>. When an application needs a
+ table whose contents is to be locally unique on each node,
+ <c>local_content</c> tables can be used. The name of the
+ table is known to all <c>Mnesia</c> nodes, but its contents is
+ unique for each node. Access to this type of table must be
+ done locally.</item>
+ <item>
+ <p><c>{attributes, AtomList}</c> is a list of the attribute
+ names for the records that are supposed to populate the
+ table. Default is the list <c>[key, val]</c>. The
+ table must at least have one extra attribute besides the
+ key. When accessing single attributes in a record, it is not
+ recommended to hard code the attribute names as atoms. Use
+ the construct <c>record_info(fields, record_name)</c>
+ instead.</p>
+ <p>The expression
+ <c>record_info(fields, record_name)</c> is processed by the
+ Erlang preprocessor and returns a list of the
+ record field names. With the record definition
+ <c>-record(foo, {x,y,z}).</c>, the expression
+ <c>record_info(fields,foo)</c> is expanded to the list
+ <c>[x,y,z]</c>. It is therefore possible for you to provide
+ the attribute names or to use the <c>record_info/2</c>
+ notation.</p>
+ <p>It is recommended to use the <c>record_info/2</c> notation,
+ as it becomes easier to maintain the program and the program
+ becomes more robust with regards to future record changes.</p>
+ </item>
+ <item>
+ <p><c>{record_name, Atom}</c> specifies the common name of
+ all records stored in the table. All records stored in
+ the table must have this name as their first element.
+ <c>record_name</c> defaults to the name of the table.
+ For more information, see
+ <seealso marker="Mnesia_chap4#recordnames_tablenames">Record Names versus Table Names</seealso>.</p>
+ </item>
+ </list>
+ </item>
+ </list>
+ <p>As an example, consider the following record definition:</p>
+ <pre>
+ -record(funky, {x, y}).</pre>
+ <p>The following call would create a table that is replicated on two
+ nodes, has an extra index on attribute <c>y</c>, and is of type
+ <c>bag</c>.</p>
+ <pre>
+ mnesia:create_table(funky, [{disc_copies, [N1, N2]}, {index,
+ [y]}, {type, bag}, {attributes, record_info(fields, funky)}]).</pre>
+ <p>Whereas a call to the following default code values would return
+ a table with a RAM copy on the local node, no extra indexes, and the
+ attributes defaulted to the list <c>[key,val]</c>.</p>
+ <pre>
+mnesia:create_table(stuff, [])</pre>
+ </section>
+</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc
index a18f853662..db48811d76 100644
--- a/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,163 +32,146 @@
<rev></rev>
<file>Mnesia_chap4.xml</file>
</header>
- <p>This chapter describes the Mnesia transaction system and the
- transaction properties which make Mnesia a fault tolerant,
- distributed database management system.
- </p>
- <p>Also covered in this chapter are the locking functions,
+ <p>This section describes the <c>Mnesia</c> transaction system and
+ the transaction properties that make <c>Mnesia</c> a fault-tolerant,
+ distributed Database Management System (DBMS).</p>
+ <p>This section also describes the locking functions,
including table locks and sticky locks, as well as alternative
- functions which bypass the transaction system in favor of improved
- speed and reduced overheads. These functions are called "dirty
- operations". We also describe the usage of nested transactions.
- This chapter contains the following sections:
- </p>
+ functions that bypass the transaction system in favor of improved
+ speed and reduced overhead. These functions are called "dirty
+ operations". The use of nested transactions is also described.
+ The following topics are included:</p>
<list type="bulleted">
- <item>transaction properties, which include atomicity,
- consistency, isolation, and durability
- </item>
- <item>Locking
- </item>
- <item>Dirty operations
- </item>
- <item>Record names vs table names
- </item>
- <item>Activity concept and various access contexts
- </item>
- <item>Nested transactions
- </item>
- <item>Pattern matching
- </item>
- <item>Iteration
- </item>
+ <item>Transaction properties, which include atomicity,
+ consistency, isolation, and durability</item>
+ <item>Locking</item>
+ <item>Dirty operations</item>
+ <item>Record names versus table names</item>
+ <item>Activity concept and various access contexts</item>
+ <item>Nested transactions</item>
+ <item>Pattern matching</item>
+ <item>Iteration</item>
</list>
<section>
<marker id="trans_prop"></marker>
<title>Transaction Properties</title>
- <p>Transactions are an important tool when designing fault
- tolerant, distributed systems. A Mnesia transaction is a mechanism
+ <p>Transactions are important when designing fault-tolerant,
+ distributed systems. A <c>Mnesia</c> transaction is a mechanism
by which a series of database operations can be executed as one
- functional block. The functional block which is run as a
+ functional block. The functional block that is run as a
transaction is called a Functional Object (Fun), and this code can
- read, write, or delete Mnesia records. The Fun is evaluated as a
- transaction which either commits, or aborts. If a transaction
- succeeds in executing Fun it will replicate the action on all nodes
- involved, or abort if an error occurs.
- </p>
- <p>The following example shows a transaction which raises the
- salary of certain employee numbers.
- </p>
+ read, write, and delete <c>Mnesia</c> records. The Fun is evaluated
+ as a transaction that either commits or terminates. If a transaction
+ succeeds in executing the Fun, it replicates the action on all nodes
+ involved, or terminates if an error occurs.</p>
+ <p>The following example shows a transaction that raises the
+ salary of certain employee numbers:</p>
<codeinclude file="company.erl" tag="%5" type="erl"></codeinclude>
- <p>The transaction <c>raise(Eno, Raise) - ></c> contains a Fun
- made up of four lines of code. This Fun is called by the statement
- <c>mnesia:transaction(F)</c> and returns a value.
- </p>
- <p>The Mnesia transaction system facilitates the construction of
+ <p>The function <c>raise/2</c> contains a Fun
+ made up of four code lines. This Fun is called by the statement
+ <c>mnesia:transaction(F)</c> and returns a value.</p>
+ <p>The <c>Mnesia</c> transaction system facilitates the construction of
reliable, distributed systems by providing the following important
- properties:
- </p>
+ properties:</p>
<list type="bulleted">
- <item>The transaction handler ensures that a Fun which is placed
- inside a transaction does not interfere with operations embedded
+ <item>The transaction handler ensures that a Fun, which is placed
+ inside a transaction, does not interfere with operations embedded
in other transactions when it executes a series of operations on
tables.
</item>
<item>The transaction handler ensures that either all operations
in the transaction are performed successfully on all nodes
atomically, or the transaction fails without permanent effect on
- any of the nodes.
+ any node.
</item>
- <item>The Mnesia transactions have four important properties,
- which we call <em>A</em>tomicity,
- <em>C</em>onsistency,<em>I</em>solation, and
- <em>D</em>urability, or ACID for short. These properties are
- described in the following sub-sections.</item>
+ <item>The <c>Mnesia</c> transactions have four important properties,
+ called <em>A</em>tomicity,
+ <em>C</em>onsistency, <em>I</em>solation, and
+ <em>D</em>urability (ACID). These properties are
+ described in the following sections.</item>
</list>
<section>
<title>Atomicity</title>
- <p><em>Atomicity</em> means that database changes which are
+ <p>Atomicity means that database changes that are
executed by a transaction take effect on all nodes involved, or
- on none of the nodes. In other words, the transaction either
- succeeds entirely, or it fails entirely.
- </p>
- <p>Atomicity is particularly important when we want to
- atomically write more than one record in the same
- transaction. The <c>raise/2</c> function, shown as an example
- above, writes one record only. The <c>insert_emp/3</c> function,
- shown in the program listing in Chapter 2, writes the record
- <c>employee</c> as well as employee relations such as
- <c>at_dep</c> and <c>in_proj</c> into the database. If we run
- this latter code inside a transaction, then the transaction
+ on none of the nodes. That is, the transaction either
+ succeeds entirely, or it fails entirely.</p>
+ <p>Atomicity is important when it is needed to write
+ atomically more than one record in the same
+ transaction. The function <c>raise/2</c>, shown in the previous
+ example, writes one record only. The function <c>insert_emp/3</c>,
+ shown in the program listing in
+ <seealso marker="Mnesia_chap2#getting_started">Getting Started</seealso>, writes the record
+ <c>employee</c> as well as employee relations, such as
+ <c>at_dep</c> and <c>in_proj</c>, into the database. If this
+ latter code is run inside a transaction, the transaction
handler ensures that the transaction either succeeds completely,
- or not at all.
- </p>
- <p>Mnesia is a distributed DBMS where data can be replicated on
- several nodes. In many such applications, it is important that a
+ or not at all.</p>
+ <p><c>Mnesia</c> is a distributed DBMS where data can be replicated
+ on several nodes. In many applications, it is important that a
series of write operations are performed atomically inside a
transaction. The atomicity property ensures that a transaction
- take effect on all nodes, or none at all. </p>
+ takes effect on all nodes, or none.</p>
</section>
<section>
<title>Consistency</title>
- <p><em>Consistency</em>. This transaction property ensures that
+ <p>The consistency property ensures that
a transaction always leaves the DBMS in a consistent state. For
- example, Mnesia ensures that inconsistencies will not occur if
- Erlang, Mnesia or the computer crashes while a write operation
- is in progress.
- </p>
+ example, <c>Mnesia</c> ensures that no inconsistencies occur if
+ Erlang, <c>Mnesia</c>, or the computer crashes while a write
+ operation is in progress.</p>
</section>
<section>
<title>Isolation</title>
- <p><em>Isolation</em>. This transaction property ensures that
- transactions which execute on different nodes in a network, and
- access and manipulate the same data records, will not interfere
- with each other.
- </p>
- <p>The isolation property makes it possible to concurrently execute
- the <c>raise/2</c> function. A classical problem in concurrency control
- theory is the so called "lost update problem".
- </p>
- <p>The isolation property is extremely useful if the following
- circumstances occurs where an employee (with an employee number
- 123) and two processes, (P1 and P2), are concurrently trying to
- raise the salary for the employee. The initial value of the
- employees salary is, for example, 5. Process P1 then starts to execute,
- it reads the employee record and adds 2 to the salary. At this
- point in time, process P1 is for some reason preempted and
- process P2 has the opportunity to run. P2 reads the record, adds 3
- to the salary, and finally writes a new employee record with
- the salary set to 8. Now, process P1 start to run again and
+ <p>The isolation property ensures that
+ transactions that execute on different nodes in a network, and
+ access and manipulate the same data records, do not interfere
+ with each other. The isolation property makes it possible to
+ execute the function <c>raise/2</c> concurrently. A classical
+ problem in concurrency control theory is the "lost update
+ problem".</p>
+ <p>The isolation property is in particular useful if the following
+ circumstances occur where an employee (with employee number
+ 123) and two processes (P1 and P2) are concurrently trying to
+ raise the salary for the employee:</p>
+ <list type="bulleted">
+ <item><em>Step 1:</em> The initial value of the employees salary
+ is, for example, 5. Process P1 starts to execute, reads the
+ employee record, and adds 2 to the salary.</item>
+ <item><em>Step 2:</em> Process P1 is for some reason pre-empted
+ and process P2 has the opportunity to run.</item>
+ <item><em>Step 3:</em> Process P2 reads the record, adds 3 to
+ the salary, and finally writes a new employee record with
+ the salary set to 8.</item>
+ <item><em>Step 4:</em> Process P1 starts to run again and
writes its employee record with salary set to 7, thus
effectively overwriting and undoing the work performed by
- process P2. The update performed by P2 is lost.
- </p>
- <p>A transaction system makes it possible to concurrently
- execute two or more processes which manipulate the same
- record. The programmer does not need to check that the
- updates are synchronous, this is overseen by the
+ process P2. The update performed by P2 is lost.</item>
+ </list>
+ <p>A transaction system makes it possible to execute two or more
+ processes concurrently that manipulate the same record.
+ The programmer does not need to check that the
+ updates are synchronous; this is overseen by the
transaction handler. All programs accessing the database through
- the transaction system may be written as if they had sole access
- to the data.
- </p>
+ the transaction system can be written as if they had sole access
+ to the data.</p>
</section>
<section>
<title>Durability</title>
- <p><em>Durability</em>. This transaction property ensures that
+ <p>The durability property ensures that
changes made to the DBMS by a transaction are permanent. Once a
- transaction has been committed, all changes made to the database
- are durable - i.e. they are written safely to disc and will not
- be corrupted or disappear.
- </p>
+ transaction is committed, all changes made to the database are
+ durable, that is, they are written safely to disc and do not
+ become corrupted and do not disappear.</p>
<note>
- <p>The durability feature described does not entirely apply to
- situations where Mnesia is configured as a "pure" primary memory
- database.
- </p>
+ <p>The described durability feature does not entirely apply to
+ situations where <c>Mnesia</c> is configured as a "pure"
+ primary memory database.</p>
</note>
</section>
</section>
@@ -195,397 +179,383 @@
<section>
<title>Locking</title>
<p>Different transaction managers employ different strategies to
- satisfy the isolation property. Mnesia uses the standard technique
- of two-phase locking. This means that locks are set on records
- before they are read or written. Mnesia uses five different kinds
- of locks.
- </p>
+ satisfy the isolation property. <c>Mnesia</c> uses the standard
+ technique of two phase locking. That is, locks are set on records
+ before they are read or written. <c>Mnesia</c> uses the following
+ lock types:</p>
<list type="bulleted">
<item><em>Read locks</em>. A read lock is set on one replica of
a record before it can be read.
</item>
- <item><em>Write locks</em>. Whenever a transaction writes to an
+ <item><em>Write locks</em>. Whenever a transaction writes to a
record, write locks are first set on all replicas of that
- particular record.
+ particular record.
</item>
<item><em>Read table locks</em>. If a transaction traverses an
- entire table in search for a record which satisfy some
+ entire table in search for a record that satisfies some
particular property, it is most inefficient to set read locks on
- the records, one by one. It is also very memory consuming, since
- the read locks themselves may take up considerable space if the
- table is very large. For this reason, Mnesia can set a read lock
- on an entire table.
+ the records one by one. It is also memory consuming, as
+ the read locks themselves can take up considerable space if the
+ table is large. Therefore, <c>Mnesia</c> can set a read lock
+ on an entire table.
</item>
- <item><em>Write table locks</em>. If a transaction writes a
- large number of records to one table, it is possible to set a
- write lock on the entire table.
+ <item><em>Write table locks</em>. If a transaction writes many
+ records to one table, a write lock can be set on the entire table.
</item>
<item><em>Sticky locks</em>. These are write locks that stay in
- place at a node after the transaction which initiated the lock
- has terminated. </item>
+ place at a node after the transaction that initiated the lock
+ has terminated.</item>
</list>
- <p>Mnesia employs a strategy whereby functions such as
- <c>mnesia:read/1</c> acquire the necessary locks dynamically as
- the transactions execute. Mnesia automatically sets and releases
- the locks and the programmer does not have to code these
- operations.
- </p>
+ <p><c>Mnesia</c> employs a strategy whereby functions, such as
+ <seealso marker="mnesia#read/1">mnesia:read/1</seealso>
+ acquire the necessary locks dynamically as
+ the transactions execute. <c>Mnesia</c> automatically sets and
+ releases the locks and the programmer does not need to code these
+ operations.</p>
<p>Deadlocks can occur when concurrent processes set and release
- locks on the same records. Mnesia employs a "wait-die" strategy to
- resolve these situations. If Mnesia suspects that a deadlock can
+ locks on the same records. <c>Mnesia</c> employs a "wait-die"
+ strategy to resolve
+ these situations. If <c>Mnesia</c> suspects that a deadlock can
occur when a transaction tries to set a lock, the transaction is
- forced to release all its locks and sleep for a while. The
- Fun in the transaction will be evaluated one more time.
- </p>
- <p>For this reason, it is important that the code inside the Fun given to
- <c>mnesia:transaction/1</c> is pure. Some strange results can
+ forced to release all its locks and sleep for a while. The Fun
+ in the transaction is evaluated once more.</p>
+ <p>It is therefore important that the code inside the Fun given to
+ <seealso marker="mnesia#transaction/2"><c>mnesia:transaction/1</c></seealso>
+ is pure. Some strange results can
occur if, for example, messages are sent by the transaction
- Fun. The following example illustrates this situation:
- </p>
+ Fun. The following example illustrates this situation:</p>
<codeinclude file="company.erl" tag="%6" type="erl"></codeinclude>
- <p>This transaction could write the text <c>"Trying to write ... "</c> a thousand times to the terminal. Mnesia does guarantee,
- however, that each and every transaction will eventually run. As a
- result, Mnesia is not only deadlock free, but also livelock
- free.
- </p>
- <p>The Mnesia programmer cannot prioritize one particular
- transaction to execute before other transactions which are waiting
- to execute. As a result, the Mnesia DBMS transaction system is not
- suitable for hard real time applications. However, Mnesia contains
- other features that have real time properties.
- </p>
- <p>Mnesia dynamically sets and releases locks as
- transactions execute, therefore, it is very dangerous to execute code with
+ <p>This transaction can write the text <c>"Trying to write ... "</c>
+ 1000 times to the terminal. However, <c>Mnesia</c> guarantees
+ that each transaction will eventually run. As a result,
+ <c>Mnesia</c> is not only deadlock free, but also livelock free.</p>
+ <p>The <c>Mnesia</c> programmer cannot prioritize one particular
+ transaction to execute before other transactions that are waiting
+ to execute. As a result, the <c>Mnesia</c> DBMS transaction system is
+ not suitable for hard real-time applications. However, <c>Mnesia</c>
+ contains other features that have real-time properties.</p>
+ <p><c>Mnesia</c> dynamically sets and releases locks as transactions
+ execute. It is therefore dangerous to execute code with
transaction side-effects. In particular, a <c>receive</c>
statement inside a transaction can lead to a situation where the
transaction hangs and never returns, which in turn can cause locks
- not to release. This situation could bring the whole system to a
- standstill since other transactions which execute in other
+ not to release. This situation can bring the whole system to a
+ standstill, as other transactions that execute in other
processes, or on other nodes, are forced to wait for the defective
- transaction.
- </p>
- <p>If a transaction terminates abnormally, Mnesia will
- automatically release the locks held by the transaction.
- </p>
- <p>We have shown examples of a number of functions that can be
- used inside a transaction. The following list shows the
- <em>simplest</em> Mnesia functions that work with transactions. It
- is important to realize that these functions must be embedded in a
+ transaction.</p>
+ <p>If a transaction terminates abnormally, <c>Mnesia</c>
+ automatically releases the locks held by the transaction.</p>
+ <p>Up to now, examples of a number of functions that can be used
+ inside a transaction have been shown. The following list shows
+ the <em>simplest</em> <c>Mnesia</c> functions that work with
+ transactions. Notice that these functions must be embedded in a
transaction. If no enclosing transaction (or other enclosing
- Mnesia activity) exists, they will all fail.
- </p>
+ <c>Mnesia</c> activity) exists, they all fail.</p>
<list type="bulleted">
- <item><c>mnesia:transaction(Fun) -> {aborted, Reason} |{atomic, Value}</c>. This function executes one transaction with the
- functional object <c>Fun</c> as the single parameter.
+ <item><seealso marker="mnesia#transaction/2">mnesia:transaction(Fun) -> {aborted, Reason} |{atomic, Value}</seealso>
+ executes one transaction with the
+ functional object <c>Fun</c> as the single parameter.
</item>
- <item><c>mnesia:read({Tab, Key}) -> transaction abort | RecordList</c>. This function reads all records with <c>Key</c>
- as key from table <c>Tab</c>. This function has the same semantics
+ <item><seealso marker="mnesia#read/1">mnesia:read({Tab, Key}) -> transaction abort | RecordList</seealso>
+ reads all records with <c>Key</c>
+ as key from table <c>Tab</c>. This function has the same semantics
regardless of the location of <c>Table</c>. If the table is of
- type <c>bag</c>, the <c>read({Tab, Key})</c> can return an arbitrarily
+ type <c>bag</c>, <c>read({Tab, Key})</c> can return an arbitrarily
long list. If the table is of type <c>set</c>, the list is
- either of length one, or <c>[]</c>.
+ either of length one or <c>[]</c>.
</item>
- <item><c>mnesia:wread({Tab, Key}) -> transaction abort | RecordList</c>. This function behaves the same way as the
- previously listed <c>read/1</c> function, except that it
- acquires a write lock instead of a read lock. If we execute a
- transaction which reads a record, modifies the record, and then
+ <item><seealso marker="mnesia#wread/1">mnesia:wread({Tab, Key}) -> transaction abort | RecordList</seealso>
+ behaves the same way as the
+ previously listed function <c>read/1</c>, except that it
+ acquires a write lock instead of a read lock. To execute a
+ transaction that reads a record, modifies the record, and then
writes the record, it is slightly more efficient to set the
- write lock immediately. In cases where we issue a
- <c>mnesia:read/1</c>, followed by a <c>mnesia:write/1</c>, the
- first read lock must be upgraded to a write lock when the write
- operation is executed.
+ write lock immediately. When a <seealso marker="mnesia#read/1">mnesia:read/1</seealso>
+ is issued, followed by a
+ <seealso marker="mnesia#write/1">mnesia:write/1</seealso>
+ the first read lock must be upgraded to a write lock when the
+ write operation is executed.
</item>
- <item><c>mnesia:write(Record) -> transaction abort | ok</c>. This function writes a record into the database. The
- <c>Record</c> argument is an instance of a record. The function
- returns <c>ok</c>, or aborts the transaction if an error should
- occur.
+ <item><seealso marker="mnesia#write/1">mnesia:write(Record) -> transaction abort | ok</seealso>
+ writes a record into the database. Argument
+ <c>Record</c> is an instance of a record. The function returns
+ <c>ok</c>, or terminates the transaction if an error occurs.
</item>
- <item><c>mnesia:delete({Tab, Key}) -> transaction abort | ok</c>. This
- function deletes all records with the given key.
+ <item><seealso marker="mnesia#delete/1">mnesia:delete({Tab, Key}) -> transaction abort | ok</seealso>
+ deletes all records with the given key.
</item>
- <item><c>mnesia:delete_object(Record) -> transaction abort | ok</c>. This function deletes records with object id
- <c>Record</c>. This function is used when we want to delete only
- some records in a table of type <c>bag</c>. </item>
+ <item><seealso marker="mnesia#delete_object/1">mnesia:delete_object(Record) -> transaction abort | ok</seealso>
+ deletes records with the OID <c>Record</c>. Use this function to
+ delete only some records in a table of type <c>bag</c>.</item>
</list>
<section>
<title>Sticky Locks</title>
- <p>As previously stated, the locking strategy used by Mnesia is
- to lock one record when we read a record, and lock all replicas
- of a record when we write a record. However, there are
- applications which use Mnesia mainly for its fault-tolerant
- qualities, and these applications may be configured with one
- node doing all the heavy work, and a standby node which is ready
- to take over in case the main node fails. Such applications may
+ <p>As previously stated, the locking strategy used by <c>Mnesia</c>
+ is to lock one record when reading a record, and lock all replicas
+ of a record when writing a record. However, some
+ applications use <c>Mnesia</c> mainly for its fault-tolerant
+ qualities. These applications can be configured with one
+ node doing all the heavy work, and a standby node that is ready
+ to take over if the main node fails. Such applications can
benefit from using sticky locks instead of the normal locking
- scheme.
- </p>
- <p>A sticky lock is a lock which stays in place at a node after
- the transaction which first acquired the lock has terminated. To
- illustrate this, assume that we execute the following
- transaction:
- </p>
+ scheme.</p>
+ <p>A sticky lock is a lock that stays in place at a node, after
+ the transaction that first acquired the lock has terminated. To
+ illustrate this, assume that the following transaction is
+ executed:</p>
<code type="none">
F = fun() ->
mnesia:write(#foo{a = kalle})
end,
- mnesia:transaction(F).
- </code>
+ mnesia:transaction(F).</code>
<p>The <c>foo</c> table is replicated on the two nodes <c>N1</c>
- and <c>N2</c>.
- <br></br>
-Normal locking requires:
- </p>
+ and <c>N2</c>.</p>
+ <p>Normal locking requires the following:</p>
<list type="bulleted">
- <item>one network rpc (2 messages) to acquire the write lock
+ <item>One network RPC (two messages) to acquire the write lock
</item>
- <item>three network messages to execute the two-phase commit protocol.
+ <item>Three network messages to execute the two-phase commit
+ protocol
</item>
</list>
- <p>If we use sticky locks, we must first change the code as follows:
- </p>
+ <p>If sticky locks are used, the code must first be changed as
+ follows:</p>
<code type="none">
-
F = fun() ->
mnesia:s_write(#foo{a = kalle})
end,
- mnesia:transaction(F).
- </code>
- <p>This code uses the <c>s_write/1</c> function instead of the
- <c>write/1</c> function. The <c>s_write/1</c> function sets a
+ mnesia:transaction(F).</code>
+ <p>This code uses the function
+ <seealso marker="mnesia#s_write/1">s_write/1</seealso>
+ instead of the function
+ <seealso marker="mnesia#write/1">write/1</seealso>
+ The function <c>s_write/1</c> sets a
sticky lock instead of a normal lock. If the table is not
replicated, sticky locks have no special effect. If the table is
- replicated, and we set a sticky lock on node <c>N1</c>, this
- lock will then stick to node <c>N1</c>. The next time we try to
- set a sticky lock on the same record at node <c>N1</c>, Mnesia
- will see that the lock is already set and will not do a network
- operation in order to acquire the lock.
- </p>
- <p>It is much more efficient to set a local lock than it is to set
- a networked lock, and for this reason sticky locks can benefit
- application that use a replicated table and perform most of the
- work on only one of the nodes.
- </p>
- <p>If a record is stuck at node <c>N1</c> and we try to set a
+ replicated, and a sticky lock is set on node <c>N1</c>, this
+ lock then sticks to node <c>N1</c>. The next time you try to
+ set a sticky lock on the same record at node <c>N1</c>,
+ <c>Mnesia</c> detects that the lock is already set and do no
+ network operation to acquire the lock.</p>
+ <p>It is more efficient to set a local lock than it is to set
+ a networked lock. Sticky locks can therefore benefit an
+ application that uses a replicated table and perform most of the
+ work on only one of the nodes.</p>
+ <p>If a record is stuck at node <c>N1</c> and you try to set a
sticky lock for the record on node <c>N2</c>, the record must be
- unstuck. This operation is expensive and will reduce performance. The unsticking is
- done automatically if we issue <c>s_write/1</c> requests at
- <c>N2</c>.
- </p>
+ unstuck. This operation is expensive and reduces performance.
+ The unsticking is done automatically if you issue <c>s_write/1</c>
+ requests at <c>N2</c>.</p>
</section>
<section>
<title>Table Locks</title>
- <p>Mnesia supports read and write locks on whole tables as a
+ <p><c>Mnesia</c> supports read and write locks on whole tables as a
complement to the normal locks on single records. As previously
- stated, Mnesia sets and releases locks automatically, and the
- programmer does not have to code these operations. However,
- transactions which read and write a large number of records in a
- specific table will execute more efficiently if we start the
- transaction by setting a table lock on this table. This will
- block other concurrent transactions from the table. The
- following two function are used to set explicit table locks for
- read and write operations:
- </p>
+ stated, <c>Mnesia</c> sets and releases locks automatically, and
+ the programmer does not need to code these operations. However,
+ transactions that read and write many records in a
+ specific table execute more efficiently if the
+ transaction is started by setting a table lock on this table. This
+ blocks other concurrent transactions from the table. The
+ following two functions are used to set explicit table locks for
+ read and write operations:</p>
<list type="bulleted">
- <item><c>mnesia:read_lock_table(Tab)</c> Sets a read lock on
- the table <c>Tab</c></item>
- <item><c>mnesia:write_lock_table(Tab)</c> Sets a write lock on
- the table <c>Tab</c></item>
+ <item><seealso marker="mnesia#read_lock_table/1">mnesia:read_lock_table(Tab)</seealso>
+ sets a read lock on table <c>Tab</c>.</item>
+ <item><seealso marker="mnesia#write_lock_table/1">mnesia:write_lock_table(Tab)</seealso>
+ sets a write lock on table <c>Tab</c>.</item>
</list>
- <p>Alternate syntax for acquisition of table locks is as follows:
- </p>
+ <p>Alternative syntax for acquisition of table locks is as
+ follows:</p>
<code type="none">
mnesia:lock({table, Tab}, read)
- mnesia:lock({table, Tab}, write)
- </code>
- <p>The matching operations in Mnesia may either lock the entire
- table or just a single record (when the key is bound in the
- pattern).
- </p>
+ mnesia:lock({table, Tab}, write)</code>
+ <p>The matching operations in <c>Mnesia</c> can either lock the
+ entire table or only a single record (when the key is bound in
+ the pattern).</p>
</section>
<section>
<title>Global Locks</title>
<p>Write locks are normally acquired on all nodes where a
replica of the table resides (and is active). Read locks are
- acquired on one node (the local one if a local
- replica exists).
- </p>
- <p>The function <c>mnesia:lock/2</c> is intended to support
- table locks (as mentioned previously)
- but also for situations when locks need to be
- acquired regardless of how tables have been replicated:
- </p>
+ acquired on one node (the local one if a local
+ replica exists).</p>
+ <p>The function
+ <seealso marker="mnesia#lock/2">mnesia:lock/2</seealso>
+ is intended to support table locks (as mentioned previously)
+ but also for situations when locks need to be
+ acquired regardless of how tables have been replicated:</p>
<code type="none">
mnesia:lock({global, GlobalKey, Nodes}, LockKind)
- LockKind ::= read | write | ...
- </code>
- <p>The lock is acquired on the LockItem on all Nodes in the
- nodes list.</p>
+ LockKind ::= read | write | ...</code>
+ <p>The lock is acquired on <c>LockItem</c> on all nodes in the
+ node list.</p>
</section>
</section>
<section>
<title>Dirty Operations</title>
<p>In many applications, the overhead of processing a transaction
- may result in a loss of performance. Dirty operation are short
- cuts which bypass much of the processing and increase the speed
- of the transaction.
- </p>
- <p>Dirty operation are useful in many situations, for example in a datagram routing
- application where Mnesia stores the routing table, and it is time
+ can result in a loss of performance. Dirty operation are short
+ cuts that bypass much of the processing and increase the speed
+ of the transaction.</p>
+ <p>Dirty operation are often useful, for example, in a
+ datagram routing application
+ where <c>Mnesia</c> stores the routing table, and it is time
consuming to start a whole transaction every time a packet is
- received. For this reason, Mnesia has functions which manipulate
+ received. <c>Mnesia</c> has therefore functions that manipulate
tables without using transactions. This alternative
- to processing is known as a dirty operation. However, it is important to
- realize the trade-off in avoiding the overhead of transaction
- processing:
- </p>
+ to processing is known as a dirty operation. However, notice the
+ trade-off in avoiding the overhead of transaction processing:</p>
<list type="bulleted">
- <item>The atomicity and the isolation properties of Mnesia are lost.
+ <item>The atomicity and the isolation properties of <c>Mnesia</c>
+ are lost.
</item>
<item>The isolation property is compromised, because other
Erlang processes, which use transaction to manipulate the data,
- do not get the benefit of isolation if we simultaneously use
- dirty operations to read and write records from the same table.
+ do not get the benefit of isolation if dirty operations
+ simultaneously are used to read and write records from the same
+ table.
</item>
</list>
<p>The major advantage of dirty operations is that they execute
- much faster than equivalent operations that are processed as
- functional objects within a transaction.
- </p>
+ much faster than equivalent operations that are processed as
+ functional objects within a transaction.</p>
<p>Dirty operations
are written to disc if they are performed on a table of type
- <c>disc_copies</c>, or type <c>disc_only_copies</c>. Mnesia also
- ensures that all replicas of a table are updated if a
- dirty write operation is performed on a table.
- </p>
- <p>A dirty operation will ensure a certain level of consistency.
- For example, it is not possible for dirty operations to return
- garbled records. Hence, each individual read or write operation
- is performed in an atomic manner.
- </p>
- <p>All dirty functions execute a call to <c>exit({aborted, Reason})</c> on failure. Even if the following functions are
- executed inside a transaction no locks will be acquired. The
- following functions are available:
- </p>
+ <c>disc_copies</c> or type <c>disc_only_copies</c>. <c>Mnesia</c>
+ also ensures that all replicas of a table are updated if a
+ dirty write operation is performed on a table.</p>
+ <p>A dirty operation ensures a certain level of consistency.
+ For example, dirty operations cannot return
+ garbled records. Hence, each individual read or write operation
+ is performed in an atomic manner.</p>
+ <p>All dirty functions execute a call to <c>exit({aborted, Reason})</c>
+ on failure. Even if the following functions are
+ executed inside a transaction no locks are acquired. The
+ following functions are available:</p>
<list type="bulleted">
- <item><c>mnesia:dirty_read({Tab, Key})</c>. This function reads
- record(s) from Mnesia.
+ <item><seealso marker="mnesia#dirty_read/1">mnesia:dirty_read({Tab, Key})</seealso>
+ reads one or more records from <c>Mnesia</c>.
+ </item>
+ <item><seealso marker="mnesia#dirty_write/1">mnesia:dirty_write(Record)</seealso>
+ writes the record <c>Record</c>.
</item>
- <item><c>mnesia:dirty_write(Record)</c>. This function writes
- the record <c>Record</c></item>
- <item><c>mnesia:dirty_delete({Tab, Key})</c>. This function deletes
- record(s) with the key <c>Key</c>.
+ <item><seealso marker="mnesia#dirty_delete/1">mnesia:dirty_delete({Tab, Key})</seealso>
+ deletes one or more records with key <c>Key</c>.
+ </item>
+ <item><seealso marker="mnesia#dirty_delete_object/1">mnesia:dirty_delete_object(Record)</seealso>
+ is the dirty operation alternative to the function
+ <seealso marker="mnesia#delete_object/1">delete_object/1</seealso>.
</item>
- <item><c>mnesia:dirty_delete_object(Record)</c> This function is
- the dirty operation alternative to the function
- <c>delete_object/1</c></item>
<item>
- <p><c>mnesia:dirty_first(Tab)</c>. This function returns the
- "first" key in the table <c>Tab</c>. </p>
- <p>Records in <c>set</c> or <c>bag</c> tables are not sorted.
- However, there is
- a record order which is not known to the user.
- This means that it is possible to traverse a table by means of
- this function in conjunction with the <c>dirty_next/2</c>
- function.
- </p>
- <p>If there are no records at all in the table, this function
- will return the atom <c>'$end_of_table'</c>. It is not
+ <p><seealso marker="mnesia#dirty_first/1">mnesia:dirty_first(Tab)</seealso>
+ returns the "first" key in table <c>Tab</c>.</p>
+ <p>Records in <c>set</c> or <c>bag</c> tables are not sorted.
+ However, there is a record order that is unknown to the user.
+ This means that a table can be traversed by this function
+ with the function
+ <seealso marker="mnesia#dirty_next/2">mnesia:dirty_next/2</seealso>.</p>
+ <p>If there are no records in the table, this function
+ returns the atom <c>'$end_of_table'</c>. It is not
recommended to use this atom as the key for any user
- records.
- </p>
+ records.</p>
</item>
- <item><c>mnesia:dirty_next(Tab, Key)</c>. This function returns
- the "next" key in the table <c>Tab</c>. This function makes it
+ <item><p><seealso marker="mnesia#dirty_next/2">mnesia:dirty_next(Tab, Key)</seealso>
+ returns the "next" key in table <c>Tab</c>. This function makes it
possible to traverse a table and perform some operation on all
- records in the table. When the end of the table is reached the
+ records in the table. When the end of the table is reached, the
special key <c>'$end_of_table'</c> is returned. Otherwise, the
- function returns a key which can be used to read the actual
- record.
- <br></br>
-The behavior is undefined if any process perform a write
- operation on the table while we traverse the table with the
- <c>dirty_next/2</c> function. This is because <c>write</c>
- operations on a Mnesia table may lead to internal reorganizations
- of the table itself. This is an implementation detail, but remember
- the dirty functions are low level functions.
+ function returns a key that can be used to read the actual
+ record.</p>
+ <p>The behavior is undefined if any process performs a write
+ operation on the table while traversing the table with the
+ function
+ <seealso marker="mnesia#dirty_next/2">dirty_next/2</seealso>
+ This is because <c>write</c>
+ operations on a <c>Mnesia</c> table can lead to internal
+ reorganizations of the table itself. This is an implementation
+ detail, but remember that the dirty functions are low-level
+ functions.</p>
</item>
- <item><c>mnesia:dirty_last(Tab)</c> This function works exactly like
- <c>mnesia:dirty_first/1</c> but returns the last object in
- Erlang term order for the <c>ordered_set</c> table type. For
+ <item><seealso marker="mnesia#dirty_last/1">mnesia:dirty_last(Tab)</seealso>
+ works exactly like
+ <seealso marker="mnesia#dirty_first/1">mnesia:dirty_first/1</seealso>
+ but returns the last object in
+ Erlang term order for the table type <c>ordered_set</c>. For
all other table types, <c>mnesia:dirty_first/1</c> and
- <c>mnesia:dirty_last/1</c> are synonyms.
+ <c>mnesia:dirty_last/1</c> are synonyms.
</item>
- <item><c>mnesia:dirty_prev(Tab, Key)</c> This function works exactly like
- <c>mnesia:dirty_next/2</c> but returns the previous object in
- Erlang term order for the ordered_set table type. For
- all other table types, <c>mnesia:dirty_next/2</c> and
- <c>mnesia:dirty_prev/2</c> are synonyms.
+ <item><seealso marker="mnesia#dirty_prev/2">mnesia:dirty_prev(Tab, Key)</seealso>
+ works exactly like
+ <c>mnesia:dirty_next/2</c> but returns the previous object in
+ Erlang term order for the table type <c>ordered_set</c>. For
+ all other table types, <c>mnesia:dirty_next/2</c> and
+ <c>mnesia:dirty_prev/2</c> are synonyms.
</item>
<item>
- <p><c>mnesia:dirty_slot(Tab, Slot)</c></p>
- <p>Returns the list of records that are associated with Slot
+ <p><seealso marker="mnesia#dirty_slot/2">mnesia:dirty_slot(Tab, Slot)</seealso>
+ returns the list of records that are associated with <c>Slot</c>
in a table. It can be used to traverse a table in a manner
- similar to the <c>dirty_next/2</c> function. A table has a
+ similar to the function <c>dirty_next/2</c>. A table has a
number of slots that range from zero to some unknown upper
bound. The function <c>dirty_slot/2</c> returns the special
atom <c>'$end_of_table'</c> when the end of the table is
- reached.
- <br></br>
-The behavior of this function is undefined if the
+ reached.</p>
+ <p>The behavior of this function is undefined if the
table is written on while being
- traversed. <c>mnesia:read_lock_table(Tab)</c> may be used to
- ensure that no transaction protected writes are performed
- during the iteration.
- </p>
+ traversed. The function
+ <seealso marker="mnesia#read_lock_table/1">mnesia:read_lock_table(Tab)</seealso>
+ can be used to ensure that no transaction-protected writes
+ are performed during the iteration.</p>
</item>
- <item>
- <p><c>mnesia:dirty_update_counter({Tab,Key}, Val)</c>. </p>
- <p>Counters are positive integers with a value greater than or
- equal to zero. Updating a counter will add the <c>Val</c> and
- the counter where <c>Val</c> is a positive or negative integer.
- <br></br>
- There exists no special counter records in
- Mnesia. However, records on the form of <c>{TabName, Key, Integer}</c> can be used as counters, and can be
- persistent.
- </p>
- <p>It is not possible to have transaction protected updates of
- counter records.
- </p>
+ <item><p><seealso marker="mnesia#dirty_update_counter/2">mnesia:dirty_update_counter({Tab,Key}, Val)</seealso>.
+ Counters are positive integers with a value greater than or
+ equal to zero. Updating a counter adds <c>Val</c> and the
+ counter where <c>Val</c> is a positive or negative integer.</p>
+ <p><c>Mnesia</c> has no special counter records. However, records
+ of the form <c>{TabName, Key, Integer}</c> can be used as
+ counters, and can be persistent.</p>
+ <p>Transaction-protected updates of counter records are not
+ possible.</p>
<p>There are two significant differences when using this
function instead of reading the record, performing the
- arithmetic, and writing the record:
- </p>
+ arithmetic, and writing the record:</p>
<list type="ordered">
- <item>it is much more efficient
+ <item>It is much more efficient.
</item>
- <item>the <c>dirty_update_counter/2</c> function is
- performed as an atomic operation although it is not protected by
- a transaction. Accordingly, no table update is lost if two
- processes simultaneously execute the
- <c>dirty_update_counter/2</c> function.
+ <item>The funcion
+ <seealso marker="mnesia#dirty_update_counter/2">dirty_update_counter/2</seealso>
+ is performed as an atomic operation although it is not protected
+ by a transaction. Therfore no table update is lost if two
+ processes simultaneously execute the function
+ <c>dirty_update_counter/2</c>.
</item>
</list>
</item>
- <item><c>mnesia:dirty_match_object(Pat)</c>. This function is
- the dirty equivalent of <c>mnesia:match_object/1</c>.
+ <item><seealso marker="mnesia#dirty_match_object/2">mnesia:dirty_match_object(Pat)</seealso>
+ is the dirty equivalent of
+ <seealso marker="mnesia#match_object/1">mnesia:match_object/1</seealso>.
</item>
- <item><c>mnesia:dirty_select(Tab, Pat)</c>. This function is
- the dirty equivalent of <c>mnesia:select/2</c>.
+ <item><seealso marker="mnesia#dirty_select/2">mnesia:dirty_select(Tab, Pat)</seealso>
+ is the dirty equivalent of
+ <seealso marker="mnesia#select/2"> mnesia:select/2</seealso>.
</item>
- <item><c>mnesia:dirty_index_match_object(Pat, Pos)</c>. This
- function is the dirty equivalent of
- <c>mnesia:index_match_object/2</c>.
+ <item><seealso marker="mnesia#dirty_index_match_object/2">mnesia:dirty_index_match_object(Pat, Pos)</seealso>
+ is the dirty equivalent of
+ <seealso marker="mnesia#index_match_object/2">mnesia:index_match_object/2</seealso>.
</item>
- <item><c>mnesia:dirty_index_read(Tab, SecondaryKey, Pos)</c>. This
- function is the dirty equivalent of <c>mnesia:index_read/3</c>.
+ <item><seealso marker="mnesia#dirty_index_read/3">mnesia:dirty_index_read(Tab, SecondaryKey, Pos)</seealso>
+ is the dirty equivalent of
+ <seealso marker="mnesia#index_read/3">mnesia:index_read/3</seealso>.
</item>
- <item><c>mnesia:dirty_all_keys(Tab)</c>. This function is the
- dirty equivalent of <c>mnesia:all_keys/1</c>.
+ <item><seealso marker="mnesia#dirty_all_keys/1">mnesia:dirty_all_keys(Tab)</seealso>
+ is the dirty equivalent of <seealso marker="mnesia#all_keys/1">
+mnesia:all_keys/1</seealso>.
</item>
</list>
</section>
@@ -593,42 +563,38 @@ The behavior of this function is undefined if the
<section>
<marker id="recordnames_tablenames"></marker>
<title>Record Names versus Table Names</title>
- <p>In Mnesia, all records in a table must have the same name. All
- the records must be instances of the same
- record type. The record name does however not necessarily be
- the same as the table name. Even though that it is the case in
- the most of the examples in this document. If a table is created
- without the <c>record_name</c> property the code below will
- ensure all records in the tables have the same name as the table:
- </p>
+ <p>In <c>Mnesia</c>, all records in a table must have the same name.
+ All the records must be instances of the same
+ record type. The record name, however, does not necessarily have
+ to be the same as the table name, although this is the case in
+ most of the examples in this User's Guide. If a table is created
+ without property <c>record_name</c>, the following code ensures
+ that all records in the tables have the same name as the table:</p>
<code type="none">
- mnesia:create_table(subscriber, [])
- </code>
- <p>However, if the table is is created with an explicit record name
- as argument, as shown below, it is possible to store subscriber
- records in both of the tables regardless of the table names:
- </p>
+ mnesia:create_table(subscriber, [])</code>
+ <p>However, if the table is created with an explicit record name
+ as argument, as shown in the following example, subscriber records
+ can be stored in both of the tables regardless of the table
+ names:</p>
<code type="none">
TabDef = [{record_name, subscriber}],
mnesia:create_table(my_subscriber, TabDef),
- mnesia:create_table(your_subscriber, TabDef).
- </code>
- <p>In order to access such
- tables it is not possible to use the simplified access functions
- as described earlier in the document. For example,
- writing a subscriber record into a table requires a
- <c>mnesia:write/3</c>function instead of the simplified functions
- <c>mnesia:write/1</c> and <c>mnesia:s_write/1</c>:
- </p>
+ mnesia:create_table(your_subscriber, TabDef).</code>
+ <p>To access such tables, simplified access functions
+ (as described earlier) cannot be used. For example,
+ writing a subscriber record into a table requires the function
+ <seealso marker="mnesia#write/3">mnesia:write/3</seealso>
+ instead of the simplified functions
+ <seealso marker="mnesia#write/1">mnesia:write/1</seealso>
+ and
+ <seealso marker="mnesia#s_write/1">mnesia:s_write/1</seealso>:</p>
<code type="none">
mnesia:write(subscriber, #subscriber{}, write)
mnesia:write(my_subscriber, #subscriber{}, sticky_write)
- mnesia:write(your_subscriber, #subscriber{}, write)
- </code>
- <p>The following simplified piece of code illustrates the
+ mnesia:write(your_subscriber, #subscriber{}, write)</code>
+ <p>The following simple code illustrates the
relationship between the simplified access functions used in
- most examples and their more flexible counterparts:
- </p>
+ most of the examples and their more flexible counterparts:</p>
<code type="none">
mnesia:dirty_write(Record) ->
Tab = element(1, Record),
@@ -676,7 +642,7 @@ The behavior of this function is undefined if the
mnesia:s_delete_object(Record) ->
Tab = element(1, Record),
- mnesia:delete_object(Tab, Record. sticky_write).
+ mnesia:delete_object(Tab, Record, sticky_write).
mnesia:read({Tab, Key}) ->
mnesia:read(Tab, Key, read).
@@ -690,217 +656,222 @@ The behavior of this function is undefined if the
mnesia:index_match_object(Pattern, Attr) ->
Tab = element(1, Pattern),
- mnesia:index_match_object(Tab, Pattern, Attr, read).
- </code>
+ mnesia:index_match_object(Tab, Pattern, Attr, read).</code>
</section>
<section>
<title>Activity Concept and Various Access Contexts</title>
- <p>As previously described, a functional object (Fun) performing
- table access operations as listed below may be
- passed on as arguments to the function
- <c>mnesia:transaction/1,2,3</c>:
- </p>
+ <p>As previously described, a Functional Object (Fun) performing
+ table access operations, as listed here, can be passed
+ on as arguments to the function
+ <seealso marker="mnesia#transaction/2">mnesia:transaction/1,2,3</seealso>:
+ </p>
<list type="bulleted">
<item>
- <p>mnesia:write/3 (write/1, s_write/1)</p>
+ <seealso marker="mnesia#write/3">mnesia:write/3 (write/1, s_write/1)</seealso>
</item>
<item>
- <p>mnesia:delete/3 (delete/1, s_delete/1)</p>
+ <seealso marker="mnesia#delete/3">mnesia:delete/3</seealso>
+ (<seealso marker="mnesia#delete/1">mnesia:delete/1</seealso>,
+ <seealso marker="mnesia#s_delete/1">mnesia:s_delete/1</seealso>)
</item>
<item>
- <p>mnesia:delete_object/3 (delete_object/1, s_delete_object/1)</p>
+ <seealso marker="mnesia#delete_object/3">mnesia:delete_object/3</seealso>
+ (<seealso marker="mnesia#delete_object/1">mnesia:delete_object/1</seealso>,
+ <seealso marker="mnesia#s_delete_object/1">mnesia:s_delete_object/1</seealso>)
</item>
<item>
- <p>mnesia:read/3 (read/1, wread/1)</p>
+ <seealso marker="mnesia#read/3">mnesia:read/3</seealso>
+ (<seealso marker="mnesia#read/1">mnesia:read/1</seealso>,
+ <seealso marker="mnesia#wread/1">mnesia:wread/1</seealso>)
</item>
<item>
- <p>mnesia:match_object/2 (match_object/1)</p>
+ <seealso marker="mnesia#match_object/3">mnesia:match_object/2</seealso>
+ (<seealso marker="mnesia#match_object/1">mnesia:match_object/1</seealso>)
</item>
<item>
- <p>mnesia:select/3 (select/2)</p>
+ <seealso marker="mnesia#select/2">mnesia:select/3</seealso>
+ (<seealso marker="mnesia#select/2">mnesia:select/2</seealso>)
</item>
<item>
- <p>mnesia:foldl/3 (foldl/4, foldr/3, foldr/4)</p>
+ <seealso marker="mnesia#foldl/3">mnesia:foldl/3</seealso>
+ (<c>mnesia:foldl/4</c>,
+ <seealso marker="mnesia#foldr/3">mnesia:foldr/3</seealso>,
+ <c>mnesia:foldr/4</c>)
</item>
<item>
- <p>mnesia:all_keys/1</p>
+ <seealso marker="mnesia#all_keys/1">mnesia:all_keys/1</seealso>
</item>
<item>
- <p>mnesia:index_match_object/4 (index_match_object/2)</p>
+ <seealso marker="mnesia#index_match_object/4">mnesia:index_match_object/4</seealso>
+ (<seealso marker="mnesia#index_match_object/2">mnesia:index_match_object/2</seealso>)
</item>
<item>
- <p>mnesia:index_read/3</p>
+ <seealso marker="mnesia#index_read/3">mnesia:index_read/3</seealso>
</item>
<item>
- <p>mnesia:lock/2 (read_lock_table/1, write_lock_table/1)</p>
+ <seealso marker="mnesia#lock/2">mnesia:lock/2</seealso>
+ (<seealso marker="mnesia#read_lock_table/1">mnesia:read_lock_table/1</seealso>,
+ <seealso marker="mnesia#write_lock_table/1">mnesia:write_lock_table/1</seealso>)
</item>
<item>
- <p>mnesia:table_info/2</p>
+ <seealso marker="mnesia#table_info/2">mnesia:table_info/2</seealso>
</item>
</list>
- <p>These functions will be performed in a
- transaction context involving mechanisms like locking, logging,
- replication, checkpoints, subscriptions, commit protocols
- etc.However, the same function may also be
- evaluated in other activity contexts.
- <br></br>
-The following activity access contexts are currently supported:
- </p>
+ <p>These functions are performed in a
+ transaction context involving mechanisms, such as locking, logging,
+ replication, checkpoints, subscriptions, and commit protocols.
+ However, the same function can also be
+ evaluated in other activity contexts.</p>
+ <p>The following activity access contexts are currently supported:</p>
<list type="bulleted">
- <item>
- <p>transaction </p>
- </item>
- <item>
- <p>sync_transaction</p>
- </item>
- <item>
- <p>async_dirty</p>
- </item>
- <item>
- <p>sync_dirty</p>
- </item>
- <item>
- <p>ets</p>
- </item>
+ <item><c>transaction</c></item>
+ <item><c>sync_transaction</c></item>
+ <item><c>async_dirty</c></item>
+ <item><c>sync_dirty</c></item>
+ <item><c>ets</c></item>
</list>
<p>By passing the same "fun" as argument to the function
- <c>mnesia:sync_transaction(Fun [, Args])</c> it will be performed
- in synced transaction context. Synced transactions waits until all
+ <seealso marker="mnesia#sync_transaction/3">mnesia:sync_transaction(Fun [, Args])</seealso>
+ it is performed
+ in synced transaction context. Synced transactions wait until all
active replicas has committed the transaction (to disc) before
- returning from the mnesia:sync_transaction call. Using
- sync_transaction is useful for applications that are executing on
- several nodes and want to be sure that the update is performed on
- the remote nodes before a remote process is spawned or a message
- is sent to a remote process, and also when combining transaction
- writes with dirty_reads. This is also useful in situations where
- an application performs frequent or voluminous updates which may
- overload Mnesia on other nodes.
- </p>
+ returning from the <c>mnesia:sync_transaction</c> call. Using
+ <c>sync_transaction</c> is useful in the following cases:</p>
+ <list type="bulleted">
+ <item>When an application executes on several nodes and wants to
+ be sure that the update is performed on the remote nodes before
+ a remote process is spawned or a message is sent to a remote
+ process.</item>
+ <item>When a combining transaction writes with "dirty_reads", that
+ is, the functions <c>dirty_match_object</c>, <c>dirty_read</c>,
+ <c>dirty_index_read</c>, <c>dirty_select</c>, and so on.</item>
+ <item>When an application performs frequent or voluminous updates
+ that can overload <c>Mnesia</c> on other nodes.</item>
+ </list>
<p>By passing the same "fun" as argument to the function
- <c>mnesia:async_dirty(Fun [, Args])</c> it will be performed in
- dirty context. The function calls will be mapped to the
- corresponding dirty functions. This will still involve logging,
- replication and subscriptions but there will be no locking,
- local transaction storage or commit protocols involved.
- Checkpoint retainers will be updated but will be updated
- "dirty". Thus, they will be updated asynchronously. The
- functions will wait for the operation to be performed on one
- node but not the others. If the table resides locally no waiting
- will occur.
- </p>
+ <seealso marker="mnesia#async_dirty/2">mnesia:async_dirty(Fun [, Args])</seealso>,
+ it is performed in dirty context. The function calls are mapped to
+ the corresponding dirty functions. This still involves logging,
+ replication, and subscriptions but no locking,
+ local transaction storage, or commit protocols are involved.
+ Checkpoint retainers are updated but updated
+ "dirty". Thus, they are updated asynchronously. The
+ functions wait for the operation to be performed on one
+ node but not the others. If the table resides locally, no waiting
+ occurs.</p>
<p>By passing the same "fun" as an argument to the function
- <c>mnesia:sync_dirty(Fun [, Args])</c> it will be performed in
- almost the same context as <c>mnesia:async_dirty/1,2</c>. The
- difference is that the operations are performed
- synchronously. The caller will wait for the updates to be
- performed on all active replicas. Using sync_dirty is useful for
- applications that are executing on several nodes and want to be
- sure that the update is performed on the remote nodes before a remote
- process is spawned or a message is sent to a remote process. This
- is also useful in situations where an application performs frequent or
- voluminous updates which may overload Mnesia on other
- nodes.
- </p>
- <p>You can check if your code is executed within a transaction with
- <c>mnesia:is_transaction/0</c>, it returns <c>true</c> when called
- inside a transaction context and false otherwise.</p>
-
- <p>Mnesia tables with storage type RAM_copies and disc_copies
- are implemented internally as "ets-tables" and
- it is possible for applications to access the these tables
- directly. This is only recommended if all options have been weighed
- and the possible outcomes are understood. By passing the earlier
- mentioned "fun" to the function
- <c>mnesia:ets(Fun [, Args])</c> it will be performed but in a very raw
- context. The operations will be performed directly on the
- local ets tables assuming that the local storage type are
- RAM_copies and that the table is not replicated on other
- nodes. Subscriptions will not be triggered nor
- checkpoints updated, but this operation is blindingly fast. Disc resident
- tables should not be updated with the ets-function since the
- disc will not be updated.
- </p>
- <p>The Fun may also be passed as an argument to the function
- <c>mnesia:activity/2,3,4</c> which enables usage of customized
+ <seealso marker="mnesia#sync_dirty/2">mnesia:sync_dirty(Fun [, Args])</seealso>,
+ it is performed in almost the same context as the function
+ <seealso marker="mnesia#async_dirty/2">mnesia:async_dirty/1,2</seealso>.
+ The difference is that the operations are performed
+ synchronously. The caller waits for the updates to be
+ performed on all active replicas. Using <c>mnesia:sync_dirty/1,2</c>
+ is useful in the following cases:</p>
+ <list type="bulleted">
+ <item>When an application executes on several nodes and wants to
+ be sure that the update is performed on the remote nodes before
+ a remote process is spawned or a message is sent to a remote
+ process.</item>
+ <item>When an application performs frequent or voluminous updates
+ that can overload <c>Mnesia</c> on the nodes.</item>
+ </list>
+ <p>To check if your code is executed within a transaction, use
+ the function
+ <seealso marker="mnesia#is_transaction/0">mnesia:is_transaction/0</seealso>.
+ It returns <c>true</c> when called
+ inside a transaction context, otherwise <c>false</c>.</p>
+ <p><c>Mnesia</c> tables with storage type <c>RAM_copies</c> and
+ <c>disc_copies</c> are implemented internally as
+ <c>ets</c> tables. Applications can access the these tables
+ directly. This is only
+ recommended if all options have been weighed and the possible
+ outcomes are understood. By passing the earlier mentioned "fun"
+ to the function
+ <seealso marker="mnesia#ets/2">mnesia:ets(Fun [, Args])</seealso>,
+ it is performed but in a raw
+ context. The operations are performed directly on the
+ local <c>ets</c> tables, assuming that the local storage type is
+ <c>RAM_copies</c> and that the table is not replicated on other
+ nodes.</p>
+ <p>Subscriptions are not triggered and no checkpoints are updated,
+ but this operation is blindingly fast. Disc resident
+ tables are not to be updated with the <c>ets</c> function, as the
+ disc is not updated.</p>
+ <p>The Fun can also be passed as an argument to the function
+ <seealso marker="mnesia#activity-4">mnesia:activity/2,3,4</seealso>,
+ which enables use of customized
activity access callback modules. It can either be obtained
- directly by stating the module name as argument or implicitly
- by usage of the <c>access_module</c> configuration parameter. A
- customized callback module may be used for several purposes,
- such as providing triggers, integrity constraints, run time
- statistics, or virtual tables.
- <br></br>
- The callback module does
- not have to access real Mnesia tables, it is free to do whatever
- it likes as long as the callback interface is fulfilled.
- <br></br>
- In Appendix C "The Activity Access Call Back Interface" the source
- code for one alternate implementation is provided
- (mnesia_frag.erl). The context sensitive function
- <c>mnesia:table_info/2</c> may be used to provide virtual
- information about a table. One usage of this is to perform
+ directly by stating the module name as argument, or implicitly
+ by use of configuration parameter <c>access_module</c>. A
+ customized callback module can be used for several purposes,
+ such as providing triggers, integrity constraints, runtime
+ statistics, or virtual tables.</p>
+ <p>The callback module does not have
+ to access real <c>Mnesia</c> tables, it is free to do whatever
+ it wants as long as the callback interface is fulfilled.</p>
+ <p><seealso marker="Mnesia_App_B">Appendix B,
+ Activity Access Callback Interface</seealso> provides the
+ source code, <c>mnesia_frag.erl</c>, for one alternative
+ implementation. The context-sensitive function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info/2</seealso>
+ can be used to provide virtual
+ information about a table. One use of this is to perform
<c>QLC</c> queries within an activity context with a
customized callback module. By providing table information about
- table indices and other <c>QLC</c> requirements,
- <c>QLC</c> may be used as a generic query language to
- access virtual tables.
- </p>
- <p>QLC queries may be performed in all these activity
- contexts (transaction, sync_transaction, async_dirty, sync_dirty
- and ets). The ets activity will only work if the table has no
- indices.
- </p>
+ table indexes and other <c>QLC</c> requirements, <c>QLC</c> can
+ be used as a generic query language to access virtual tables.</p>
+ <p>QLC queries can be performed in all these activity
+ contexts (<c>transaction</c>, <c>sync_transaction</c>,
+ <c>async_dirty</c>, <c>sync_dirty</c>, and <c>ets</c>). The
+ <c>ets</c> activity only works if the table has no indexes.</p>
<note>
- <p>The mnesia:dirty_* function always executes with
- async_dirty semantics regardless of which activity access contexts
- are invoked. They may even invoke contexts without any
- enclosing activity access context.</p>
+ <p>The function <c>mnesia:dirty_*</c> always executes with
+ <c>async_dirty</c> semantics regardless of which activity
+ access contexts that are started. It can even start contexts
+ without any enclosing activity access context.</p>
</note>
</section>
<section>
- <title>Nested transactions</title>
- <p>Transactions may be nested in an arbitrary fashion. A child transaction
- must run in the same process as its parent. When a child transaction
- aborts, the caller of the child transaction will get the
- return value <c>{aborted, Reason}</c> and any work performed
- by the child will be erased. If a child transaction commits, the
- records written by the child will be propagated to the parent.
- </p>
+ <title>Nested Transactions</title>
+ <p>Transactions can be nested in an arbitrary fashion. A child
+ transaction must run in the same process as its parent. When a
+ child transaction terminates, the caller of the child transaction
+ gets return value <c>{aborted, Reason}</c> and any work performed
+ by the child is erased. If a child transaction commits, the
+ records written by the child are propagated to the parent.</p>
<p>No locks are released when child transactions terminate. Locks
- created by a sequence of nested transactions are kept until
- the topmost transaction terminates. Furthermore, any updates
- performed by a nested transaction are only propagated
+ created by a sequence of nested transactions are kept until
+ the topmost transaction terminates. Furthermore, any update
+ performed by a nested transaction is only propagated
in such a manner so that the parent of the nested transaction
- sees the updates. No final commitment will be done until
- the top level transaction is terminated.
+ sees the updates. No final commitment is done until
+ the top-level transaction terminates.
So, although a nested transaction returns <c>{atomic, Val}</c>,
- if the enclosing parent transaction is aborted, the entire
- nested operation is aborted.
- </p>
+ if the enclosing parent transaction terminates, the entire
+ nested operation terminates.</p>
<p>The ability to have nested transaction with identical semantics
- as top level transaction makes it easier to write
- library functions that manipulate mnesia tables.
- </p>
- <p>Say for example that we have a function that adds a
- new subscriber to a telephony system:</p>
+ as top-level transaction makes it easier to write
+ library functions that manipulate <c>Mnesia</c> tables.</p>
+ <p>Consider a function that adds a subscriber to a telephony
+ system:</p>
<pre>
add_subscriber(S) ->
mnesia:transaction(fun() ->
- case mnesia:read( ..........
- </pre>
+ case mnesia:read( ..........</pre>
<p>This function needs to be called as a transaction.
- Now assume that we wish to write a function that
- both calls the <c>add_subscriber/1</c> function and
+ Assume that you wish to write a function that
+ both calls the function <c>add_subscriber/1</c> and
is in itself protected by the context of a transaction.
- By simply calling the <c>add_subscriber/1</c> from within
- another transaction, a nested transaction is created.
- </p>
- <p>It is also possible to mix different activity access contexts while nesting,
- but the dirty ones (async_dirty,sync_dirty and ets) will inherit the transaction
- semantics if they are called inside a transaction and thus it will grab locks and
- use two or three phase commit.
- </p>
+ By calling <c>add_subscriber/1</c> from within
+ another transaction, a nested transaction is created.</p>
+ <p>Also, different activity access contexts can be mixed while
+ nesting. However, the dirty ones (<c>async_dirty</c>,
+ <c>sync_dirty</c>, and <c>ets</c>) inherit the transaction
+ semantics if they are called inside a transaction and thus
+ grab locks and use two or three phase commit.</p>
+ <p><em>Example:</em></p>
<pre>
add_subscriber(S) ->
mnesia:transaction(fun() ->
@@ -915,17 +886,18 @@ The following activity access contexts are currently supported:
mnesia:read({some_tab, some_data}),
mnesia:transaction(fun() ->
%% In a transaction context.
- case mnesia:read( ..) ..end), end).
- </pre>
+ case mnesia:read( ..) ..end), end).</pre>
</section>
<section>
<title>Pattern Matching</title>
<marker id="matching"></marker>
- <p>When it is not possible to use <c>mnesia:read/3</c> Mnesia
+ <p>When the function
+ <seealso marker="mnesia#read/3">mnesia:read/3</seealso>
+ cannot be used, <c>Mnesia</c>
provides the programmer with several functions for matching
- records against a pattern. The most useful functions of these are:
- </p>
+ records against a pattern. The most useful ones
+ are the following:</p>
<code type="none">
mnesia:select(Tab, MatchSpecification, LockKind) ->
transaction abort | [ObjectList]
@@ -934,170 +906,178 @@ The following activity access contexts are currently supported:
mnesia:select(Cont) ->
transaction abort | {[Object],Continuation} | '$end_of_table'
mnesia:match_object(Tab, Pattern, LockKind) ->
- transaction abort | RecordList
- </code>
- <p>These functions matches a <c>Pattern</c> against all records in
- table <c>Tab</c>. In a <c>mnesia:select</c> call <c>Pattern</c> is
- a part of <c>MatchSpecification</c> described below. It is not
- necessarily performed as an exhaustive search of the entire
- table. By utilizing indices and bound values in the key of the
- pattern, the actual work done by the function may be condensed
- into a few hash lookups. Using <c>ordered_set</c> tables may reduce the
- search space if the keys are partially bound.
- </p>
+ transaction abort | RecordList</code>
+ <p>These functions match a <c>Pattern</c> against all records in
+ table <c>Tab</c>. In a
+ <seealso marker="mnesia#select/2">mnesia:select</seealso>
+ call, <c>Pattern</c> is
+ a part of <c>MatchSpecification</c> described in the following. It
+ is not necessarily performed as an exhaustive search of the entire
+ table. By using indexes and bound values in the key of the
+ pattern, the actual work done by the function can be condensed
+ into a few hash lookups. Using <c>ordered_set</c> tables can reduce
+ the search space if the keys are partially bound.</p>
<p>The pattern provided to the functions must be a valid record,
and the first element of the provided tuple must be the
<c>record_name</c> of the table. The special element <c>'_'</c>
matches any data structure in Erlang (also known as an Erlang
- term). The special elements <c><![CDATA['$<number>']]></c> behaves as Erlang
- variables i.e. matches anything and binds the first occurrence and
- matches the coming occurrences of that variable against the bound value.
- </p>
- <p>Use the function <c>mnesia:table_info(Tab, wild_pattern)</c>
- to obtain a basic pattern which matches all records in a table
+ term). The special elements <c><![CDATA['$<number>']]></c>
+ behave as Erlang variables, that is, they match anything,
+ bind the first occurrence, and match the
+ coming occurrences of that variable against the bound value.</p>
+ <p>Use function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, wild_pattern)</seealso>
+ to obtain a basic pattern, which matches all records in a table,
or use the default value in record creation.
- Do not make the pattern hard coded since it will make your code more
- vulnerable to future changes of the record definition.
- </p>
+ Do not make the pattern hard-coded, as this makes the code more
+ vulnerable to future changes of the record definition.</p>
+ <p><em>Example:</em></p>
<code type="none">
Wildpattern = mnesia:table_info(employee, wild_pattern),
%% Or use
- Wildpattern = #employee{_ = '_'},
- </code>
- <p>For the employee table the wild pattern will look like:</p>
+ Wildpattern = #employee{_ = '_'},</code>
+ <p>For the employee table, the wild pattern looks as follows:</p>
<code type="none">
- {employee, '_', '_', '_', '_', '_',' _'}.
- </code>
- <p>In order to constrain the match you must replace some
+ {employee, '_', '_', '_', '_', '_',' _'}.</code>
+ <p>To constrain the match, it is needed to replace some
of the <c>'_'</c> elements. The code for matching out
- all female employees, looks like:
- </p>
+ all female employees looks as follows:</p>
<code type="none">
Pat = #employee{sex = female, _ = '_'},
F = fun() -> mnesia:match_object(Pat) end,
- Females = mnesia:transaction(F).
- </code>
- <p>It is also possible to use the match function if we want to
- check the equality of different attributes. Assume that we want
- to find all employees which happens to have a employee number
- which is equal to their room number:
- </p>
+ Females = mnesia:transaction(F).</code>
+ <p>The match function can also be used to check the equality of
+ different attributes. For example, to find all employees with
+ an employee number equal to their room number:</p>
<code type="none">
Pat = #employee{emp_no = '$1', room_no = '$1', _ = '_'},
F = fun() -> mnesia:match_object(Pat) end,
- Odd = mnesia:transaction(F).
- </code>
- <p>The function <c>mnesia:match_object/3</c> lacks some important
- features that <c>mnesia:select/3</c> have. For example
+ Odd = mnesia:transaction(F).</code>
+ <p>The function
+ <seealso marker="mnesia#match_object/3">mnesia:match_object/3</seealso>
+ lacks some important features that
+ <seealso marker="mnesia#select/2">mnesia:select/3</seealso>
+ have. For example,
<c>mnesia:match_object/3</c> can only return the matching records,
- and it can not express constraints other then equality.
- If we want to find the names of the male employees on the second floor
- we could write:
- </p>
+ and it cannot express constraints other than equality. To find
+ the names of the male employees on the second floor:</p>
<codeinclude file="company.erl" tag="%21" type="erl"></codeinclude>
- <p>Select can be used to add additional constraints and create
- output which can not be done with <c>mnesia:match_object/3</c>. </p>
- <p>The second argument to select is a <c>MatchSpecification</c>.
- A <c>MatchSpecification</c> is list of <c>MatchFunctions</c>, where
+ <p>The function <c>select</c> can be used to add more constraints
+ and create output that cannot be done with
+ <c>mnesia:match_object/3</c>.</p>
+ <p>The second argument to <c>select</c> is a <c>MatchSpecification</c>.
+ A <c>MatchSpecification</c> is a list of <c>MatchFunction</c>s, where
each <c>MatchFunction</c> consists of a tuple containing
- <c>{MatchHead, MatchCondition, MatchBody}</c>. <c>MatchHead</c>
- is the same pattern used in <c>mnesia:match_object/3</c>
- described above. <c>MatchCondition</c> is a list of additional
- constraints applied to each record, and <c>MatchBody</c> is used
- to construct the return values.
- </p>
- <p>A detailed explanation of match specifications can be found in
- the <em>Erts users guide: Match specifications in Erlang </em>,
- and the ets/dets documentations may provide some additional
- information.
- </p>
- <p>The functions <c>select/4</c> and <c>select/1</c> are used to
- get a limited number of results, where the <c>Continuation</c>
- are used to get the next chunk of results. Mnesia uses the
- <c>NObjects</c> as an recommendation only, thus more or less
- results then specified with <c>NObjects</c> may be returned in
- the result list, even the empty list may be returned despite there
- are more results to collect.
- </p>
+ <c>{MatchHead, MatchCondition, MatchBody}</c>:</p>
+ <list type="bulleted">
+ <item><c>MatchHead</c> is the same pattern as used in
+ <c>mnesia:match_object/3</c> described earlier.</item>
+ <item><c>MatchCondition</c> is a list of extra constraints
+ applied to each record.</item>
+ <item><c>MatchBody</c> constructs the return values.</item>
+ </list>
+ <p>For details about the match specifications, see
+ "Match Specifications in Erlang" in
+ <seealso marker="erts:index">ERTS</seealso> User's Guide.
+ For more information, see the
+ <seealso marker="stdlib:ets">ets</seealso> and
+ <seealso marker="stdlib:dets">dets</seealso>
+ manual pages in <c>STDLIB</c>.</p>
+ <p>The functions
+ <seealso marker="mnesia#select/4">select/4</seealso> and
+ <seealso marker="mnesia#select/2">select/1</seealso>
+ are used to
+ get a limited number of results, where <c>Continuation</c>
+ gets the next chunk of results. <c>Mnesia</c> uses
+ <c>NObjects</c> as a recommendation only. Thus, more or less
+ results than specified with <c>NObjects</c> can be returned in
+ the result list, even the empty list can be returned even
+ if there are more results to collect.</p>
<warning>
<p>There is a severe performance penalty in using
- <c>mnesia:select/[1|2|3|4]</c> after any modifying operations
- are done on that table in the same transaction, i.e. avoid using
- <c>mnesia:write/1</c> or <c>mnesia:delete/1</c> before a
- <c>mnesia:select</c> in the same transaction.</p>
+ <c>mnesia:select/[1|2|3|4]</c> after any modifying operation
+ is done on that table in the same transaction. That is, avoid
+ using
+ <seealso marker="mnesia#write/1">mnesia:write/1</seealso> or
+ <seealso marker="mnesia#delete/1">mnesia:delete/1</seealso>
+ before <c>mnesia:select</c> in the same transaction.</p>
</warning>
<p>If the key attribute is bound in a pattern, the match operation
- is very efficient. However, if the key attribute in a pattern is
- given as <c>'_'</c>, or <c>'$1'</c>, the whole <c>employee</c>
+ is efficient. However, if the key attribute in a pattern is
+ given as <c>'_'</c> or <c>'$1'</c>, the whole <c>employee</c>
table must be searched for records that match. Hence if the table is
- large, this can become a time consuming operation, but it can be
- remedied with indices (refer to Chapter 5: <seealso marker="Mnesia_chap5#indexing">Indexing</seealso>) if
- <c>mnesia:match_object</c> is used.
- </p>
- <p>QLC queries can also be used to search Mnesia tables. By
- using <c>mnesia:table/[1|2]</c> as the generator inside a QLC
- query you let the query operate on a mnesia table. Mnesia
- specific options to <c>mnesia:table/2</c> are {lock, Lock},
- {n_objects,Integer} and {traverse, SelMethod}. The <c>lock</c>
- option specifies whether mnesia should acquire a read or write
- lock on the table, and <c>n_objects</c> specifies how many
- results should be returned in each chunk to QLC. The last option is
- <c>traverse</c> and it specifies which function mnesia should
- use to traverse the table. Default <c>select</c> is used, but by using
- <c>{traverse, {select, MatchSpecification}}</c> as an option to
- <c>mnesia:table/2</c> the user can specify it's own view of the
- table.
- </p>
- <p>If no options are specified a read lock will acquired and 100
- results will be returned in each chunk, and select will be used
- to traverse the table, i.e.:
- </p>
+ large, this can become a time-consuming operation, but it can be
+ remedied with indexes (see
+ <seealso marker="Mnesia_chap5#indexing">Indexing</seealso>)
+ if the function
+ <seealso marker="mnesia#match_object/1">mnesia:match_object</seealso>
+ is used.</p>
+ <p>QLC queries can also be used to search <c>Mnesia</c> tables. By
+ using the function
+ <seealso marker="mnesia#table/1">mnesia:table/[1|2]</seealso>
+ as the generator inside a QLC
+ query, you let the query operate on a <c>Mnesia</c> table.
+ <c>Mnesia</c>-specific options to <c>mnesia:table/2</c> are
+ <c>{lock, Lock}</c>, <c>{n_objects,Integer}</c>, and
+ <c>{traverse, SelMethod}</c>:</p>
+ <list type="bulleted">
+ <item><c>lock</c> specifies whether <c>Mnesia</c> is to acquire a
+ read or write lock on the table.</item>
+ <item><c>n_objects</c> specifies how many results are to be
+ returned in each chunk to QLC.</item>
+ <item><c>traverse</c> specifies which function <c>Mnesia</c> is
+ to use to traverse the table. Default <c>select</c> is used, but
+ by using <c>{traverse, {select, MatchSpecification}}</c> as an
+ option to
+ <seealso marker="mnesia#table/1">mnesia:table/2</seealso>
+ the user can specify its own view of the table.</item>
+ </list>
+ <p>If no options are specified, a read lock is acquired, 100
+ results are returned in each chunk, and <c>select</c> is used
+ to traverse the table, that is:</p>
<code type="none">
mnesia:table(Tab) ->
- mnesia:table(Tab, [{n_objects,100},{lock, read}, {traverse, select}]).
- </code>
- <p>The function <c>mnesia:all_keys(Tab)</c> returns all keys in a
- table.</p>
+ mnesia:table(Tab, [{n_objects,100},{lock, read}, {traverse, select}]).</code>
+ <p>The function
+ <seealso marker="mnesia#all_keys/1">mnesia:all_keys(Tab)</seealso>
+ returns all keys in a table.</p>
</section>
<section>
<title>Iteration</title>
<marker id="iteration"></marker>
- <p>Mnesia provides a couple of functions which iterates over all
- the records in a table.
- </p>
+ <p><c>Mnesia</c> provides the following functions that iterate over all
+ the records in a table:</p>
<code type="none">
mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort
mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort
mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
- mnesia:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
- </code>
- <p>These functions iterate over the mnesia table <c>Tab</c> and
- apply the function <c>Fun</c> to each record. The <c>Fun</c>
- takes two arguments, the first argument is a record from the
- table and the second argument is the accumulator. The
- <c>Fun</c> return a new accumulator. </p>
- <p>The first time the <c>Fun</c> is applied <c>Acc0</c> will
- be the second argument. The next time the <c>Fun</c> is called
- the return value from the previous call, will be used as the
- second argument. The term the last call to the Fun returns
- will be the return value of the <c>fold[lr]</c> function.
- </p>
- <p>The difference between <c>foldl</c> and <c>foldr</c> is the
- order the table is accessed for <c>ordered_set</c> tables,
- for every other table type the functions are equivalent.
- </p>
- <p><c>LockType</c> specifies what type of lock that shall be
+ mnesia:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort</code>
+ <p>These functions iterate over the <c>Mnesia</c> table <c>Tab</c>
+ and apply the function <c>Fun</c> to each record. <c>Fun</c>
+ takes two arguments, the first is a record from the
+ table, and the second is the accumulator.
+ <c>Fun</c> returns a new accumulator.</p>
+ <p>The first time <c>Fun</c> is applied, <c>Acc0</c> is
+ the second argument. The next time <c>Fun</c> is called,
+ the return value from the previous call is used as the
+ second argument. The term the last call to <c>Fun</c> returns
+ is the return value of the function
+ <seealso marker="mnesia#foldl/3">mnesia:foldl/3</seealso> or
+ <seealso marker="mnesia#foldr/3">mnesia:foldr/3</seealso>.</p>
+ <p>The difference between these functions is the
+ order the table is accessed for <c>ordered_set</c> tables.
+ For other table types the functions are equivalent.</p>
+ <p><c>LockType</c> specifies what type of lock that is to be
acquired for the iteration, default is <c>read</c>. If
- records are written or deleted during the iteration a write
- lock should be acquired. </p>
- <p>These functions might be used to find records in a table
- when it is impossible to write constraints for
- <c>mnesia:match_object/3</c>, or when you want to perform
- some action on certain records.
- </p>
- <p>For example finding all the employees who has a salary
- below 10 could look like:</p>
+ records are written or deleted during the iteration, a write
+ lock is to be acquired.</p>
+ <p>These functions can be used to find records in a table
+ when it is impossible to write constraints for the function
+ <seealso marker="mnesia#match_object/3">mnesia:match_object/3</seealso>,
+ or when you want to perform some action on certain records.</p>
+ <p>For example, finding all the employees who have a salary
+ less than 10 can look as follows:</p>
<code type="none"><![CDATA[
find_low_salaries() ->
Constraint =
@@ -1109,7 +1089,7 @@ The following activity access contexts are currently supported:
Find = fun() -> mnesia:foldl(Constraint, [], employee) end,
mnesia:transaction(Find).
]]></code>
- <p>Raising the salary to 10 for everyone with a salary below 10
+ <p>To raise the salary to 10 for everyone with a salary less than 10
and return the sum of all raises:</p>
<code type="none"><![CDATA[
increase_low_salaries() ->
@@ -1124,48 +1104,54 @@ The following activity access contexts are currently supported:
IncLow = fun() -> mnesia:foldl(Increase, 0, employee, write) end,
mnesia:transaction(IncLow).
]]></code>
- <p>A lot of nice things can be done with the iterator functions
- but some caution should be taken about performance and memory
- utilization for large tables. </p>
- <p>Call these iteration functions on nodes that contain a replica of the
- table. Each call to the function <c>Fun</c> access the table and if the table
- resides on another node it will generate a lot of unnecessary
- network traffic. </p>
- <p>Mnesia also provides some functions that make it possible for
- the user to iterate over the table. The order of the
- iteration is unspecified if the table is not of the <c>ordered_set</c>
- type. </p>
+ <p>Many nice things can be done with the iterator functions but take
+ some caution about performance and memory use for large tables.</p>
+ <p>Call these iteration functions on nodes that contain a replica of
+ the table. Each call to the function <c>Fun</c> access the table
+ and if the table resides on another node it generates much
+ unnecessary network traffic.</p>
+ <p><c>Mnesia</c> also provides some functions that make it possible
+ for the user to iterate over the table. The order of the iteration
+ is unspecified if the table is not of type <c>ordered_set</c>:</p>
<code type="none">
mnesia:first(Tab) -> Key | transaction abort
mnesia:last(Tab) -> Key | transaction abort
mnesia:next(Tab,Key) -> Key | transaction abort
mnesia:prev(Tab,Key) -> Key | transaction abort
- mnesia:snmp_get_next_index(Tab,Index) -> {ok, NextIndex} | endOfTable
- </code>
- <p>The order of first/last and next/prev are only valid for
- <c>ordered_set</c> tables, for all other tables, they are synonyms.
- When the end of the table is reached the special key
+ mnesia:snmp_get_next_index(Tab,Index) -> {ok, NextIndex} | endOfTable</code>
+ <p>The order of <c>first</c>/<c>last</c> and <c>next</c>/<c>prev</c>
+ is only valid for
+ <c>ordered_set</c> tables, they are synonyms for other tables.
+ When the end of the table is reached, the special key
<c>'$end_of_table'</c> is returned.</p>
<p>If records are written and deleted during the traversal, use
- <c>mnesia:fold[lr]/4</c> with a <c>write</c> lock. Or
- <c>mnesia:write_lock_table/1</c> when using first and next.</p>
+ the function
+ <seealso marker="mnesia#foldl">mnesia:foldl/3</seealso> or
+ <seealso marker="mnesia#foldr">mnesia:foldr/3</seealso>
+ with a <c>write</c> lock. Or the function
+ <seealso marker="mnesia#write_lock_table/1">mnesia:write_lock_table/1</seealso>
+ when using <c>first</c> and <c>next</c>.</p>
<p>Writing or deleting in transaction context creates a local copy
- of each modified record, so modifying each record in a large
- table uses a lot of memory. Mnesia will compensate for every
+ of each modified record. Thus, modifying each record in a large
+ table uses much memory. <c>Mnesia</c> compensates for every
written or deleted record during the iteration in a transaction
- context, which may reduce the performance. If possible avoid writing
+ context, which can reduce the performance. If possible, avoid writing
or deleting records in the same transaction before iterating over the
table.</p>
- <p>In dirty context, i.e. <c>sync_dirty</c> or <c>async_dirty</c>,
+ <p>In dirty context, that is, <c>sync_dirty</c> or <c>async_dirty</c>,
the modified records are not stored in a local copy; instead,
- each record is updated separately. This generates a lot of
+ each record is updated separately. This generates much
network traffic if the table has a replica on another node and
has all the other drawbacks that dirty operations
- have. Especially for the <c>mnesia:first/1</c> and
- <c>mnesia:next/2</c> commands, the same drawbacks as described
- above for <c>dirty_first</c> and <c>dirty_next</c> applies, i.e.
- no writes to the table should be done during iteration.</p>
- <p></p>
+ have. Especially for commands
+ <seealso marker="mnesia#first/1">mnesia:first/1</seealso> and
+ <seealso marker="mnesia#next/2">mnesia:next/2</seealso>,
+ the same drawbacks as described previously for
+ <seealso marker="mnesia#dirty_first/1">mnesia:dirty_first/1</seealso>
+ and
+ <seealso marker="mnesia#dirty_next/2">mnesia:dirty_next/2</seealso>
+ applies, that
+ is, no writing to the table is to be done during iteration.</p>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
index 127c23e0f7..f32f9eb590 100644
--- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,222 +32,205 @@
<rev></rev>
<file>Mnesia_chap5.xml</file>
</header>
- <p>The earlier chapters of this User Guide described how to get
- started with Mnesia, and how to build a Mnesia database. In this
- chapter, we will describe the more advanced features available
- when building a distributed, fault tolerant Mnesia database. This
- chapter contains the following sections:
- </p>
+
+ <p>The previous sections describe how to get started
+ with <c>Mnesia</c> and how to build a <c>Mnesia</c> database. This
+ section describes the more advanced features available
+ when building a distributed, fault-tolerant <c>Mnesia</c> database.
+ The following topics are included:</p>
<list type="bulleted">
- <item>Indexing
- </item>
- <item>Distribution and Fault Tolerance
- </item>
- <item>Table fragmentation.
- </item>
- <item>Local content tables.
- </item>
- <item>Disc-less nodes.
- </item>
- <item>More about schema management
- </item>
- <item>Debugging a Mnesia application
- </item>
- <item>Concurrent Processes in Mnesia
- </item>
- <item>Prototyping
- </item>
- <item>Object Based Programming with Mnesia.
- </item>
+ <item>Indexing</item>
+ <item>Distribution and fault tolerance</item>
+ <item>Table fragmentation</item>
+ <item>Local content tables</item>
+ <item>Disc-less nodes</item>
+ <item>More about schema management</item>
+ <item><c>Mnesia</c> event handling</item>
+ <item>Debugging <c>Mnesia</c> applications</item>
+ <item>Concurrent processes in <c>Mnesia</c></item>
+ <item>Prototyping</item>
+ <item>Object-based programming with <c>Mnesia</c></item>
</list>
<section>
<marker id="indexing"></marker>
<title>Indexing</title>
- <p>Data retrieval and matching can be performed very efficiently
- if we know the key for the record. Conversely, if the key is not
- known, all records in a table must be searched. The larger the
- table the more time consuming it will become. To remedy this
- problem Mnesia's indexing capabilities are used to improve data
- retrieval and matching of records.
- </p>
- <p>The following two functions manipulate indexes on existing tables:
- </p>
+ <p>Data retrieval and matching can be performed efficiently
+ if the key for the record is known. Conversely, if the key is
+ unknown, all records in a table must be searched. The larger the
+ table, the more time consuming it becomes. To remedy this
+ problem, <c>Mnesia</c> indexing capabilities are used to improve
+ data retrieval and matching of records.</p>
+ <p>The following two functions manipulate indexes on existing
+ tables:</p>
<list type="bulleted">
- <item><c>mnesia:add_table_index(Tab, AttributeName) -> {aborted, R} |{atomic, ok}</c></item>
- <item><c>mnesia:del_table_index(Tab, AttributeName) -> {aborted, R} |{atomic, ok}</c></item>
+ <item><seealso marker="mnesia#add_table_index/2">mnesia:add_table_index(Tab, AttributeName)
+ -> {aborted, R} |{atomic, ok}</seealso></item>
+ <item><seealso marker="mnesia#del_table_index/2">mnesia:del_table_index(Tab, AttributeName)
+ -> {aborted, R} |{atomic, ok}</seealso></item>
</list>
- <p>These functions create or delete a table index on field
- defined by <c>AttributeName</c>. To illustrate this, add an
- index to the table definition <c>(employee, {emp_no, name, salary, sex, phone, room_no}</c>, which is the example table
- from the Company database. The function
- which adds an index on the element <c>salary</c> can be expressed in
- the following way:
- </p>
- <list type="ordered">
- <item><c>mnesia:add_table_index(employee, salary)</c></item>
- </list>
- <p>The indexing capabilities of Mnesia are utilized with the
- following three functions, which retrieve and match records on the
- basis of index entries in the database.
- </p>
+ <p>These functions create or delete a table index on a field
+ defined by <c>AttributeName</c>. To illustrate this, add an
+ index to the table definition <c>(employee, {emp_no, name,
+ salary, sex, phone, room_no})</c>, which is the example table
+ from the <c>Company</c> database. The function that
+ adds an index on element <c>salary</c> can be expressed
+ as <c>mnesia:add_table_index(employee, salary)</c>.</p>
+ <p>The indexing capabilities of <c>Mnesia</c> are used with the
+ following three functions, which retrieve and match records
+ based on index entries in the database:</p>
<list type="bulleted">
- <item><c>mnesia:index_read(Tab, SecondaryKey, AttributeName) -> transaction abort | RecordList</c>.
- Avoids an exhaustive search of the entire table, by looking up
- the <c>SecondaryKey</c> in the index to find the primary keys.
+ <item>
+ <seealso marker="mnesia#index_read/3">mnesia:index_read(Tab, SecondaryKey, AttributeName)
+ -> transaction abort | RecordList</seealso>
+ avoids an exhaustive search of the entire table, by looking up
+ <c>SecondaryKey</c> in the index to find the primary keys.
</item>
- <item><c>mnesia:index_match_object(Pattern, AttributeName) -> transaction abort | RecordList</c>
- Avoids an exhaustive search of the entire table, by looking up
+ <item>
+ <seealso marker="mnesia#index_match_object/2">mnesia:index_match_object(Pattern, AttributeName)
+ -> transaction abort | RecordList</seealso>
+ avoids an exhaustive search of the entire table, by looking up
the secondary key in the index to find the primary keys.
- The secondary key is found in the <c>AttributeName</c> field of
- the <c>Pattern</c>. The secondary key must be bound.
+ The secondary key is found in field <c>AttributeName</c> of
+ <c>Pattern</c>. The secondary key must be bound.
</item>
- <item><c>mnesia:match_object(Pattern) -> transaction abort | RecordList</c>
- Uses indices to avoid exhaustive search of the entire table.
- Unlike the other functions above, this function may utilize
+ <item>
+ <seealso marker="mnesia#match_object/1">mnesia:match_object(Pattern)
+ -> transaction abort | RecordList</seealso>
+ uses indexes to avoid exhaustive search of the entire table.
+ Unlike the previous functions, this function can use
any index as long as the secondary key is bound.</item>
</list>
<p>These functions are further described and exemplified in
- Chapter 4: <seealso marker="Mnesia_chap4#matching">Pattern matching</seealso>.
- </p>
+ <seealso marker="Mnesia_chap4#matching">Pattern Matching</seealso>.
+ </p>
</section>
<section>
<title>Distribution and Fault Tolerance</title>
- <p>Mnesia is a distributed, fault tolerant DBMS. It is possible
- to replicate tables on different Erlang nodes in a variety of
- ways. The Mnesia programmer does not have to state
+ <p><c>Mnesia</c> is a distributed, fault-tolerant DBMS. Tables
+ can be replicated on different Erlang nodes in various
+ ways. The <c>Mnesia</c> programmer does not need to state
where the different tables reside, only the names of the
- different tables are specified in the program code. This is
- known as "location transparency" and it is an important
- concept. In particular:
- </p>
+ different tables need to be specified in the program code. This
+ is known as "location transparency" and is an important
+ concept. In particular:</p>
<list type="bulleted">
- <item>A program will work regardless of the
- location of the data. It makes no difference whether the data
- resides on the local node, or on a remote node. <em>Note:</em> The program
- will run slower if the data is located on a remote node.
+ <item><p>A program works regardless of the data
+ location. It makes no difference whether the data
+ resides on the local node or on a remote node.</p>
+ <p>Notice that the program runs slower if the data
+ is located on a remote node.</p>
</item>
<item>The database can be reconfigured, and tables can be
- moved between nodes. These operations do not effect the user
+ moved between nodes. These operations do not affect the user
programs.
</item>
</list>
- <p>We have previously seen that each table has a number of
- system attributes, such as <c>index</c> and
- <c>type</c>.
- </p>
+ <p>It has previously been shown that each table has a number of
+ system attributes, such as <c>index</c> and <c>type</c>.</p>
<p>Table attributes are specified when the table is created. For
- example, the following function will create a new table with two
- RAM replicas:
- </p>
+ example, the following function creates a table with two
+ RAM replicas:</p>
<pre>
mnesia:create_table(foo,
[{ram_copies, [N1, N2]},
- {attributes, record_info(fields, foo)}]).
- </pre>
+ {attributes, record_info(fields, foo)}]).</pre>
<p>Tables can also have the following properties,
- where each attribute has a list of Erlang nodes as its value.
- </p>
+ where each attribute has a list of Erlang nodes as its value:</p>
<list type="bulleted">
<item>
- <p><c>ram_copies</c>. The value of the node list is a list of
- Erlang nodes, and a RAM replica of the table will reside on
- each node in the list. This is a RAM replica, and it is
- important to realize that no disc operations are performed when
- a program executes write operations to these replicas. However,
- should permanent RAM replicas be a requirement, then the
+ <p><c>ram_copies</c>. The value of the node list is a list
+ of Erlang nodes, and a RAM replica of the table resides on
+ each node in the list.</p>
+ <p>Notice that no disc operations are performed when
+ a program executes write operations to these replicas.
+ However, if permanent RAM replicas are required, the
following alternatives are available:</p>
<list type="ordered">
- <item>The <c>mnesia:dump_tables/1</c> function can be used
- to dump RAM table replicas to disc.
+ <item>The function
+ <seealso marker="mnesia#dump_tables/1">mnesia:dump_tables/1</seealso>
+ can be used to dump RAM table replicas to disc.
</item>
- <item>The table replicas can be backed up; either from
- RAM, or from disc if dumped there with the above
- function.
+ <item>The table replicas can be backed up, either from
+ RAM, or from disc if dumped there with this function.
</item>
</list>
</item>
<item><c>disc_copies</c>. The value of the attribute is a list
- of Erlang nodes, and a replica of the table will reside both
+ of Erlang nodes, and a replica of the table resides both
in RAM and on disc on each node in the list. Write operations
- addressed to the table will address both the RAM and the disc
+ addressed to the table address both the RAM and the disc
copy of the table.
</item>
<item><c>disc_only_copies</c>. The value of the attribute is a
- list of Erlang nodes, and a replica of the table will reside
+ list of Erlang nodes, and a replica of the table resides
only as a disc copy on each node in the list. The major
disadvantage of this type of table replica is the access
speed. The major advantage is that the table does not occupy
space in memory.
</item>
</list>
- <p>It is also possible to set and change table properties on
- existing tables. Refer to Chapter 3: <seealso marker="Mnesia_chap3#def_schema">Defining the Schema</seealso> for full
- details.
- </p>
+ <p>In addition, table properties can be set and changed.
+ For details, see
+ <seealso marker="Mnesia_chap3#def_schema">Define a Schema</seealso>.
+ </p>
<p>There are basically two reasons for using more than one table
- replica: fault tolerance, or speed. It is worthwhile to note
+ replica: fault tolerance and speed. Notice
that table replication provides a solution to both of these
- system requirements.
- </p>
- <p>If we have two active table replicas, all information is
- still available if one of the replicas fail. This can be a very
+ system requirements.</p>
+ <p>If there are two active table replicas, all information is
+ still available if one replica fails. This can be an
important property in many applications. Furthermore, if a table
- replica exists at two specific nodes, applications which execute
+ replica exists at two specific nodes, applications that execute
at either of these nodes can read data from the table without
- accessing the network. Network operations are considerably
- slower and consume more resources than local operations.
- </p>
+ accessing the network. Network operations are considerably
+ slower and consume more resources than local operations.</p>
<p>It can be advantageous to create table replicas for a
- distributed application which reads data often, but writes data
- seldom, in order to achieve fast read operations on the local
+ distributed application that reads data often, but writes data
+ seldom, to achieve fast read operations on the local
node. The major disadvantage with replication is the increased
time to write data. If a table has two replicas, every write
operation must access both table replicas. Since one of these
write operations must be a network operation, it is considerably
more expensive to perform a write operation to a replicated
- table than to a non-replicated table.
- </p>
+ table than to a non-replicated table.</p>
</section>
<section>
<title>Table Fragmentation</title>
<section>
- <title>The Concept</title>
- <p>A concept of table fragmentation has been introduced in
- order to cope with very large tables. The idea is to split a
- table into several more manageable fragments. Each fragment
- is implemented as a first class Mnesia table and may be
- replicated, have indices etc. as any other table. But the
- tables may neither have <c>local_content</c> nor have the
- <c>snmp</c> connection activated.
- </p>
- <p>In order to be able to access a record in a fragmented
- table, Mnesia must determine to which fragment the
- actual record belongs. This is done by the
- <c>mnesia_frag</c> module, which implements the
- <c>mnesia_access</c> callback behaviour. Please, read the
- documentation about <c>mnesia:activity/4</c> to see how
- <c>mnesia_frag</c> can be used as a <c>mnesia_access</c>
- callback module.
- </p>
- <p>At each record access <c>mnesia_frag</c> first computes
- a hash value from the record key. Secondly the name of the
- table fragment is determined from the hash value. And
- finally the actual table access is performed by the same
+ <title>Concept</title>
+ <p>A concept of table fragmentation has been introduced
+ to cope with large tables. The idea is to split a
+ table into several manageable fragments. Each fragment is
+ implemented as a first class <c>Mnesia</c> table and can be
+ replicated, have indexes, and so on, as any other table. But
+ the tables cannot have <c>local_content</c> or have the
+ <c>snmp</c> connection activated.</p>
+ <p>To be able to access a record in a fragmented
+ table, <c>Mnesia</c> must determine to which fragment the
+ actual record belongs. This is done by module
+ <c>mnesia_frag</c>, which implements the <c>mnesia_access</c>
+ callback behavior. It is recommended to read the
+ documentation about the function
+ <seealso marker="mnesia#activity/4">mnesia:activity/4</seealso>
+ to see how <c>mnesia_frag</c>
+ can be used as a <c>mnesia_access</c> callback module.</p>
+ <p>At each record access, <c>mnesia_frag</c> first computes
+ a hash value from the record key. Second, the name of the
+ table fragment is determined from the hash value.
+ Finally the actual table access is performed by the same
functions as for non-fragmented tables. When the key is
not known beforehand, all fragments are searched for
- matching records. Note: In <c>ordered_set</c> tables
- the records will be ordered per fragment, and the
- the order is undefined in results returned by select and
- match_object.
- </p>
- <p>The following piece of code illustrates
- how an existing Mnesia table is converted to be a
- fragmented table and how more fragments are added later on.
- </p>
+ matching records.</p>
+ <p>Notice that in <c>ordered_set</c> tables, the records
+ are ordered per fragment, and the the order is undefined in
+ results returned by <c>select</c> and <c>match_object</c>.</p>
+ <p>The following code illustrates how a <c>Mnesia</c> table is
+ converted to be a fragmented table and how more fragments
+ are added later:</p>
<code type="none"><![CDATA[
Eshell V4.7.3.3 (abort with ^G)
(a@sam)1> mnesia:start().
@@ -299,102 +283,96 @@ ok
<section>
<title>Fragmentation Properties</title>
- <p>There is a table property called
- <c>frag_properties</c> and may be read with
- <c>mnesia:table_info(Tab, frag_properties)</c>. The
- fragmentation properties is a list of tagged tuples with
- the arity 2. By default the list is empty, but when it is
- non-empty it triggers Mnesia to regard the table as
- fragmented. The fragmentation properties are:
- </p>
+ <p>The table property <c>frag_properties</c> can be read with
+ the function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, frag_properties)</seealso>.
+ The fragmentation properties are a list of tagged tuples with
+ arity 2. By default the list is empty, but when it is
+ non-empty it triggers <c>Mnesia</c> to regard the table as
+ fragmented. The fragmentation properties are as follows:</p>
<taglist>
<tag><c>{n_fragments, Int}</c></tag>
<item>
<p><c>n_fragments</c> regulates how many fragments
- that the table currently has. This property may explicitly
+ that the table currently has. This property can explicitly
be set at table creation and later be changed with
<c>{add_frag, NodesOrDist}</c> or
- <c>del_frag</c>. <c>n_fragment</c>s defaults to <c>1</c>.
- </p>
+ <c>del_frag</c>. <c>n_fragments</c> defaults to <c>1</c>.</p>
</item>
<tag><c>{node_pool, List}</c></tag>
<item>
- <p>The node pool contains a list of nodes and may
+ <p>The node pool contains a list of nodes and can
explicitly be set at table creation and later be changed
- with <c>{add_node, Node}</c> or <c>{del_node, Node}</c>. At table creation Mnesia tries to distribute
+ with <c>{add_node, Node}</c> or <c>{del_node, Node}</c>.
+ At table creation <c>Mnesia</c> tries to distribute
the replicas of each fragment evenly over all the nodes in
- the node pool. Hopefully all nodes will end up with the
+ the node pool. Hopefully all nodes end up with the
same number of replicas. <c>node_pool</c> defaults to the
- return value from <c>mnesia:system_info(db_nodes)</c>.
- </p>
+ return value from the function
+ <seealso marker="mnesia#system_info/1">mnesia:system_info(db_nodes)</seealso>.</p>
</item>
<tag><c>{n_ram_copies, Int}</c></tag>
<item>
<p>Regulates how many <c>ram_copies</c> replicas
- that each fragment should have. This property may
- explicitly be set at table creation. The default is
+ that each fragment is to have. This property can
+ explicitly be set at table creation. Defaults is
<c>0</c>, but if <c>n_disc_copies</c> and
<c>n_disc_only_copies</c> also are <c>0</c>,
- <c>n_ram_copies</c> will default be set to <c>1</c>.
- </p>
+ <c>n_ram_copies</c> defaults to <c>1</c>.</p>
</item>
<tag><c>{n_disc_copies, Int}</c></tag>
<item>
- <p>Regulates how many <c>disc_copies</c> replicas
- that each fragment should have. This property may
- explicitly be set at table creation. The default is <c>0</c>.
- </p>
+ <p>Regulates how many <c>disc_copies</c> replicas that
+ each fragment is to have. This property can explicitly
+ be set at table creation. Default is <c>0</c>.</p>
</item>
<tag><c>{n_disc_only_copies, Int}</c></tag>
<item>
<p>Regulates how many <c>disc_only_copies</c> replicas
- that each fragment should have. This property may
- explicitly be set at table creation. The default is <c>0</c>.
- </p>
+ that each fragment is to have. This property can
+ explicitly be set at table creation. Defaults is
+ <c>0</c>.</p>
</item>
<tag><c>{foreign_key, ForeignKey}</c></tag>
<item>
- <p><c>ForeignKey</c> may either be the atom
+ <p><c>ForeignKey</c> can either be the atom
<c>undefined</c> or the tuple <c>{ForeignTab, Attr}</c>,
- where <c>Attr</c> denotes an attribute which should be
+ where <c>Attr</c> denotes an attribute that is to be
interpreted as a key in another fragmented table named
- <c>ForeignTab</c>. Mnesia will ensure that the number of
+ <c>ForeignTab</c>. <c>Mnesia</c> ensures that the number of
fragments in this table and in the foreign table are
- always the same. When fragments are added or deleted
- Mnesia will automatically propagate the operation to all
- fragmented tables that has a foreign key referring to this
+ always the same.</p>
+ <p>When fragments are added or deleted, <c>Mnesia</c>
+ automatically propagates the operation to all
+ fragmented tables that have a foreign key referring to this
table. Instead of using the record key to determine which
- fragment to access, the value of the <c>Attr</c> field is
- used. This feature makes it possible to automatically
- co-locate records in different tables to the same
- node. <c>foreign_key</c> defaults to
- <c>undefined</c>. However if the foreign key is set to
- something else it will cause the default values of the
+ fragment to access, the value of field <c>Attr</c> is
+ used. This feature makes it possible to colocate records
+ automatically in different tables to the same node.
+ <c>foreign_key</c> defaults to
+ <c>undefined</c>. However, if the foreign key is set to
+ something else, it causes the default values of the
other fragmentation properties to be the same values as
- the actual fragmentation properties of the foreign table.
- </p>
+ the actual fragmentation properties of the foreign table.</p>
</item>
<tag><c>{hash_module, Atom}</c></tag>
<item>
- <p>Enables definition of an alternate hashing scheme.
- The module must implement the <c>mnesia_frag_hash</c>
- callback behaviour (see the reference manual). This
- property may explicitly be set at table creation.
- The default is <c>mnesia_frag_hash</c>.</p>
- <p>Older tables that was created before the concept of
- user defined hash modules was introduced, uses
- the <c>mnesia_frag_old_hash</c> module in order to
- be backwards compatible. The <c>mnesia_frag_old_hash</c>
- is still using the poor deprecated <c>erlang:hash/1</c>
- function.
- </p>
+ <p>Enables definition of an alternative hashing scheme.
+ The module must implement the
+ <seealso marker="mnesia_frag_hash">mnesia_frag_hash</seealso>
+ callback behavior. This property can explicitly be set at
+ table creation. Default is <c>mnesia_frag_hash</c>.</p>
+ <p>Older tables, that were created before the concept of
+ user-defined hash modules was introduced, use module
+ <c>mnesia_frag_old_hash</c> to be backwards compatible.
+ <c>mnesia_frag_old_hash</c> still uses the poor
+ deprecated function <c>erlang:hash/1</c>.</p>
</item>
<tag><c>{hash_state, Term}</c></tag>
<item>
- <p>Enables a table specific parameterization
- of a generic hash module. This property may explicitly
- be set at table creation.
- The default is <c>undefined</c>.</p>
+ <p>Enables a table-specific parameterization of a
+ generic hash module. This property can explicitly be set
+ at table creation. Default is <c>undefined</c>.</p>
<code type="none"><![CDATA[
Eshell V4.7.3.3 (abort with ^G)
(a@sam)1> mnesia:start().
@@ -463,177 +441,159 @@ ok
<title>Management of Fragmented Tables</title>
<p>The function <c>mnesia:change_table_frag(Tab, Change)</c>
is intended to be used for reconfiguration of fragmented
- tables. The <c>Change</c> argument should have one of the
- following values:
- </p>
+ tables. Argument <c>Change</c> is to have one of the
+ following values:</p>
<taglist>
<tag><c>{activate, FragProps}</c></tag>
<item>
<p>Activates the fragmentation properties of an
- existing table. <c>FragProps</c> should either contain
- <c>{node_pool, Nodes}</c> or be empty.
- </p>
+ existing table. <c>FragProps</c> is either to contain
+ <c>{node_pool, Nodes}</c> or be empty.</p>
</item>
<tag><c>deactivate</c></tag>
<item>
<p>Deactivates the fragmentation properties of a
- table. The number of fragments must be <c>1</c>. No other
- tables may refer to this table in its foreign key.
- </p>
+ table. The number of fragments must be <c>1</c>. No other
+ table can refer to this table in its foreign key.</p>
</item>
<tag><c>{add_frag, NodesOrDist}</c></tag>
<item>
- <p>Adds one new fragment to a fragmented table. All
- records in one of the old fragments will be rehashed and
- about half of them will be moved to the new (last)
- fragment. All other fragmented tables, which refers to this
- table in their foreign key, will automatically get a new
- fragment, and their records will also be dynamically
- rehashed in the same manner as for the main table.
- </p>
- <p>The <c>NodesOrDist</c> argument may either be a list
- of nodes or the result from <c>mnesia:table_info(Tab, frag_dist)</c>. The <c>NodesOrDist</c> argument is
+ <p>Adds a fragment to a fragmented table. All
+ records in one of the old fragments are rehashed and
+ about half of them are moved to the new (last)
+ fragment. All other fragmented tables, which refer to this
+ table in their foreign key, automatically get a new
+ fragment. Also, their records are dynamically
+ rehashed in the same manner as for the main table.</p>
+ <p>Argument <c>NodesOrDist</c> can either be a list of
+ nodes or the result from the function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, frag_dist)</seealso>.
+ Argument <c>NodesOrDist</c> is
assumed to be a sorted list with the best nodes to
host new replicas first in the list. The new fragment
- will get the same number of replicas as the first
- fragment (see <c>n_ram_copies</c>, <c>n_disc_copies</c>
+ gets the same number of replicas as the first
+ fragment (see <c>n_ram_copies</c>, <c>n_disc_copies</c>,
and <c>n_disc_only_copies</c>). The <c>NodesOrDist</c>
list must at least contain one element for each
- replica that needs to be allocated.
- </p>
+ replica that needs to be allocated.</p>
</item>
<tag><c>del_frag</c></tag>
<item>
- <p>Deletes one fragment from a fragmented table. All
- records in the last fragment will be moved to one of the other
- fragments. All other fragmented tables which refers to
- this table in their foreign key, will automatically lose
- their last fragment and their records will also be
+ <p>Deletes a fragment from a fragmented table. All
+ records in the last fragment are moved to one of the other
+ fragments. All other fragmented tables, which refer to
+ this table in their foreign key, automatically lose
+ their last fragment. Also, their records are
dynamically rehashed in the same manner as for the main
- table.
- </p>
+ table.</p>
</item>
<tag><c>{add_node, Node}</c></tag>
<item>
- <p>Adds a new node to the <c>node_pool</c>. The new
- node pool will affect the list returned from
- <c>mnesia:table_info(Tab, frag_dist)</c>.
- </p>
+ <p>Adds a node to <c>node_pool</c>. The new
+ node pool affects the list returned from the function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, frag_dist)</seealso>.
+ </p>
</item>
<tag><c>{del_node, Node}</c></tag>
<item>
- <p>Deletes a new node from the <c>node_pool</c>. The
- new node pool will affect the list returned from
- <c>mnesia:table_info(Tab, frag_dist)</c>.</p>
+ <p>Deletes a node from <c>node_pool</c>. The new
+ node pool affects the list returned from the function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, frag_dist)</seealso>.
+ </p>
</item>
</taglist>
</section>
<section>
<title>Extensions of Existing Functions</title>
- <p>The function <c>mnesia:create_table/2</c> is used to
- create a brand new fragmented table, by setting the table
- property <c>frag_properties</c> to some proper values.
- </p>
- <p>The function <c>mnesia:delete_table/1</c> is used to
- delete a fragmented table including all its
- fragments. There must however not exist any other
- fragmented tables which refers to this table in their foreign key.
- </p>
- <p>The function <c>mnesia:table_info/2</c> now understands
- the <c>frag_properties</c> item.
- </p>
- <p>If the function <c>mnesia:table_info/2</c> is invoked in
- the activity context of the <c>mnesia_frag</c> module,
- information of several new items may be obtained:
- </p>
+ <p>The function
+ <seealso marker="mnesia#create_table/2">mnesia:create_table/2</seealso>
+ creates a brand new fragmented table, by setting table
+ property <c>frag_properties</c> to some proper values.</p>
+ <p>The function
+ <seealso marker="mnesia#delete_table/1">mnesia:delete_table/1</seealso>
+ deletes a fragmented table including all its
+ fragments. There must however not exist any other fragmented
+ tables that refer to this table in their foreign key.</p>
+ <p>The function
+ <seealso marker="mnesia#table_info/2">mnesia:table_info/2</seealso>
+ now understands item <c>frag_properties</c>.</p>
+ <p>If the function <c>mnesia:table_info/2</c> is started in
+ the activity context of module <c>mnesia_frag</c>,
+ information of several new items can be obtained:</p>
<taglist>
<tag><c>base_table</c></tag>
- <item>
- <p>the name of the fragmented table
- </p>
- </item>
+ <item>The name of the fragmented table</item>
<tag><c>n_fragments</c></tag>
- <item>
- <p>the actual number of fragments
- </p>
- </item>
+ <item>The actual number of fragments</item>
<tag><c>node_pool</c></tag>
- <item>
- <p>the pool of nodes
- </p>
- </item>
+ <item>The pool of nodes</item>
<tag><c>n_ram_copies</c></tag>
<item></item>
<tag><c>n_disc_copies</c></tag>
<item></item>
<tag><c>n_disc_only_copies</c></tag>
<item>
- <p>the number of replicas with storage type
- <c>ram_copies</c>, <c>disc_copies</c> and <c>disc_only_copies</c>
+ <p>The number of replicas with storage type <c>ram_copies</c>,
+ <c>disc_copies</c>, and <c>disc_only_copies</c>,
respectively. The actual values are dynamically derived
from the first fragment. The first fragment serves as a
- pro-type and when the actual values needs to be computed
- (e.g. when adding new fragments) they are simply
- determined by counting the number of each replicas for
- each storage type. This means, when the functions
- <c>mnesia:add_table_copy/3</c>,
- <c>mnesia:del_table_copy/2</c> and<c>mnesia:change_table_copy_type/2</c> are applied on the
- first fragment, it will affect the settings on
+ protype. When the actual values need to be computed
+ (for example, when adding new fragments) they are
+ determined by counting the number of each replica for
+ each storage type. This means that when the functions
+ <seealso marker="mnesia#add_table_copy/3">mnesia:add_table_copy/3</seealso>,
+
+ <seealso marker="mnesia#del_table_copy/2">mnesia:del_table_copy/2</seealso>,
+ and
+ <seealso marker="mnesia#change_table_copy_type/3">mnesia:change_table_copy_type/2</seealso> are applied on the
+ first fragment, it affects the settings on
<c>n_ram_copies</c>, <c>n_disc_copies</c>, and
- <c>n_disc_only_copies</c>.
- </p>
+ <c>n_disc_only_copies</c>.</p>
</item>
<tag><c>foreign_key</c></tag>
<item>
- <p>the foreign key.
- </p>
+ <p>The foreign key</p>
</item>
<tag><c>foreigners</c></tag>
<item>
- <p>all other tables that refers to this table in
- their foreign key.
- </p>
+ <p>All other tables that refer to this table in
+ their foreign key</p>
</item>
<tag><c>frag_names</c></tag>
<item>
- <p>the names of all fragments.
- </p>
+ <p>The names of all fragments</p>
</item>
<tag><c>frag_dist</c></tag>
<item>
- <p>a sorted list of <c>{Node, Count}</c> tuples
- which is sorted in increasing <c>Count</c> order. The
+ <p>A sorted list of <c>{Node, Count}</c> tuples
+ that are sorted in increasing <c>Count</c> order.
<c>Count</c> is the total number of replicas that this
fragmented table hosts on each <c>Node</c>. The list
- always contains at least all nodes in the
- <c>node_pool</c>. The nodes which not belongs to the
- <c>node_pool</c> will be put last in the list even if
- their <c>Count</c> is lower.
- </p>
+ always contains at least all nodes in
+ <c>node_pool</c>. Nodes that do not belong to
+ <c>node_pool</c> are put last in the list even if
+ their <c>Count</c> is lower.</p>
</item>
<tag><c>frag_size</c></tag>
<item>
- <p>a list of <c>{Name, Size}</c> tuples where
- <c>Name</c> is a fragment <c>Name</c> and <c>Size</c> is
- how many records it contains.
- </p>
+ <p>A list of <c>{Name, Size}</c> tuples, where
+ <c>Name</c> is a fragment <c>Name</c>, and <c>Size</c> is
+ how many records it contains</p>
</item>
<tag><c>frag_memory</c></tag>
<item>
- <p>a list of <c>{Name, Memory}</c> tuples where
- <c>Name</c> is a fragment <c>Name</c> and <c>Memory</c> is
- how much memory it occupies.
- </p>
+ <p>A list of <c>{Name, Memory}</c> tuples, where
+ <c>Name</c> is a fragment <c>Name</c>, and <c>Memory</c> is
+ how much memory it occupies</p>
</item>
<tag><c>size</c></tag>
<item>
- <p>total size of all fragments
- </p>
+ <p>Total size of all fragments</p>
</item>
<tag><c>memory</c></tag>
<item>
- <p>the total memory of all fragments</p>
+ <p>Total memory of all fragments</p>
</item>
</taglist>
</section>
@@ -642,42 +602,45 @@ ok
<title>Load Balancing</title>
<p>There are several algorithms for distributing records
in a fragmented table evenly over a
- pool of nodes. No one is best, it simply depends of the
- application needs. Here follows some examples of
- situations which may need some attention:
- </p>
- <p><c>permanent change of nodes</c> when a new permanent
- <c>db_node</c> is introduced or dropped, it may be time to
- change the pool of nodes and re-distribute the replicas
- evenly over the new pool of nodes. It may also be time to
- add or delete a fragment before the replicas are re-distributed.
- </p>
- <p><c>size/memory threshold</c> when the total size or
+ pool of nodes. No one is best, it depends on the
+ application needs. The following examples of
+ situations need some attention:</p>
+ <list type="bulleted">
+ <item><c>permanent change of nodes</c>. When a new permanent
+ <c>db_node</c> is introduced or dropped, it can be time to
+ change the pool of nodes and redistribute the replicas
+ evenly over the new pool of nodes. It can also be time to
+ add or delete a fragment before the replicas are redistributed.
+ </item>
+ <item><c>size/memory threshold</c>. When the total size or
total memory of a fragmented table (or a single
- fragment) exceeds some application specific threshold, it
- may be time to dynamically add a new fragment in order
- obtain a better distribution of records.
- </p>
- <p><c>temporary node down</c> when a node temporarily goes
- down it may be time to compensate some fragments with new
- replicas in order to keep the desired level of
- redundancy. When the node comes up again it may be time to
- remove the superfluous replica.
- </p>
- <p><c>overload threshold</c> when the load on some node is
- exceeds some application specific threshold, it may be time to
- either add or move some fragment replicas to nodes with lesser
- load. Extra care should be taken if the table has a foreign
- key relation to some other table. In order to avoid severe
- performance penalties, the same re-distribution must be
- performed for all of the related tables.
- </p>
- <p>Use <c>mnesia:change_table_frag/2</c> to add new fragments
+ fragment) exceeds some application-specific threshold, it
+ can be time to add a new fragment dynamically to
+ obtain a better distribution of records.
+ </item>
+ <item><c>temporary node down</c>. When a node temporarily goes
+ down, it can be time to compensate some fragments with new
+ replicas to keep the desired level of
+ redundancy. When the node comes up again, it can be time to
+ remove the superfluous replica.
+ </item>
+ <item><c>overload threshold</c>. When the load on some node
+ exceeds some application-specific threshold, it can be time to
+ either add or move some fragment replicas to nodes with lower
+ load. Take extra care if the table has a foreign
+ key relation to some other table. To avoid severe
+ performance penalties, the same redistribution must be
+ performed for all the related tables.
+ </item>
+ </list>
+ <p>Use the function
+ <c>mnesia:change_table_frag/2</c> to add new fragments
and apply the usual schema manipulation functions (such as
- <c>mnesia:add_table_copy/3</c>, <c>mnesia:del_table_copy/2</c>
- and <c>mnesia:change_table_copy_type/2</c>) on each fragment
- to perform the actual re-distribution.
- </p>
+ <seealso marker="mnesia#add_table_copy/3">mnesia:add_table_copy/3</seealso>,
+ <seealso marker="mnesia#del_table_copy/2">mnesia:del_table_copy/2</seealso>,
+ and
+ <seealso marker="mnesia#change_table_copy_type/3">mnesia:change_table_copy_type/2</seealso>)
+ on each fragment to perform the actual redistribution.</p>
</section>
</section>
@@ -685,356 +648,369 @@ ok
<title>Local Content Tables</title>
<p>Replicated tables have the same content on all nodes where
they are replicated. However, it is sometimes advantageous to
- have tables but different content on different nodes.
- </p>
- <p>If we specify the attribute <c>{local_content, true}</c> when
- we create the table, the table will reside on the nodes where
- we specify that the table shall exist, but the write operations on the
- table will only be performed on the local copy.
- </p>
- <p>Furthermore, when the table is initialized at start-up, the
- table will only be initialized locally, and the table
- content will not be copied from another node.
- </p>
+ have tables, but different content on different nodes.</p>
+ <p>If attribute <c>{local_content, true}</c> is specified when
+ you create the table, the table resides on the nodes where you
+ specify the table to exist, but the write operations on the
+ table are only performed on the local copy.</p>
+ <p>Furthermore, when the table is initialized at startup, the
+ table is only initialized locally, and the table
+ content is not copied from another node.</p>
</section>
<section>
- <title>Disc-less Nodes</title>
- <p>It is possible to run Mnesia on nodes that do not have a
- disc. It is of course not possible to have replicas
- of neither <c>disc_copies</c>, nor <c>disc_only_copies</c>
- on such nodes. This especially troublesome for the
- <c>schema</c> table since Mnesia need the schema in order
- to initialize itself.
- </p>
- <p>The schema table may, as other tables, reside on one or
- more nodes. The storage type of the schema table may either
- be <c>disc_copies</c> or <c>ram_copies</c>
- (not <c>disc_only_copies</c>). At
- start-up Mnesia uses its schema to determine with which
- nodes it should try to establish contact. If any
- of the other nodes are already started, the starting node
+ <title>Disc-Less Nodes</title>
+ <p><c>Mnesia</c> can be run on nodes that do not have a disc.
+ Replicas of <c>disc_copies</c> or <c>disc_only_copies</c> are
+ not possible on such nodes. This is especially troublesome for
+ the <c>schema</c> table, as <c>Mnesia</c> needs the schema
+ to initialize itself.</p>
+ <p>The schema table can, as other tables, reside on one or
+ more nodes. The storage type of the schema table can either
+ be <c>disc_copies</c> or <c>ram_copies</c>
+ (but not <c>disc_only_copies</c>). At
+ startup, <c>Mnesia</c> uses its schema to determine with which
+ nodes it is to try to establish contact. If any
+ other node is started already, the starting node
merges its table definitions with the table definitions
brought from the other nodes. This also applies to the
- definition of the schema table itself. The application
- parameter <c>extra_db_nodes</c> contains a list of nodes which
- Mnesia also should establish contact with besides the ones
- found in the schema. The default value is the empty list
- <c>[]</c>.
- </p>
+ definition of the schema table itself. Application
+ parameter <c>extra_db_nodes</c> contains a list of nodes that
+ <c>Mnesia</c> also is to establish contact with besides those
+ found in the schema. Default is <c>[]</c> (empty list).</p>
<p>Hence, when a disc-less node needs to find the schema
- definitions from a remote node on the network, we need to supply
- this information through the application parameter <c>-mnesia extra_db_nodes NodeList</c>. Without this
- configuration parameter set, Mnesia will start as a single node
- system. It is also possible to use <c>mnesia:change_config/2</c>
- to assign a value to 'extra_db_nodes' and force a connection
- after mnesia have been started, i.e.
- mnesia:change_config(extra_db_nodes, NodeList).
- </p>
- <p>The application parameter schema_location controls where
- Mnesia will search for its schema. The parameter may be one of
- the following atoms:
- </p>
+ definitions from a remote node on the network, this
+ information must be supplied through application parameter
+ <c>-mnesia extra_db_nodes NodeList</c>. Without this
+ configuration parameter set, <c>Mnesia</c> starts as a single
+ node system. Also, the function
+ <seealso marker="mnesia#change_config/2">mnesia:change_config/2</seealso>
+ can be used to assign a value to <c>extra_db_nodes</c> and force
+ a connection after <c>Mnesia</c> has been started, that is,
+ <c>mnesia:change_config(extra_db_nodes, NodeList)</c>.</p>
+ <p>Application parameter <c>schema_location</c> controls where
+ <c>Mnesia</c> searches for its schema. The parameter can be one
+ of the following atoms:</p>
<taglist>
<tag><c>disc</c></tag>
<item>
<p>Mandatory disc. The schema is assumed to be located
- on the Mnesia directory. And if the schema cannot be found,
- Mnesia refuses to start.
- </p>
+ in the <c>Mnesia</c> directory. If the schema cannot be found,
+ <c>Mnesia</c> refuses to start.</p>
</item>
<tag><c>ram</c></tag>
<item>
- <p>Mandatory ram. The schema resides in ram
- only. At start-up a tiny new schema is generated. This
- default schema contains just the definition of the schema
- table and only resides on the local node. Since no other
- nodes are found in the default schema, the configuration
- parameter <c>extra_db_nodes</c> must be used in order to let the
- node share its table definitions with other nodes. (The
- <c>extra_db_nodes</c> parameter may also be used on disc-full nodes.)
- </p>
+ <p>Mandatory RAM. The schema resides in RAM
+ only. At startup, a tiny new schema is generated. This
+ default schema contains only the definition of the schema
+ table and resides on the local node only. Since no other
+ nodes are found in the default schema, configuration
+ parameter <c>extra_db_nodes</c> must be used to let the
+ node share its table definitions with other nodes. (Parameter
+ <c>extra_db_nodes</c> can also be used on disc-full nodes.)</p>
</item>
<tag><c>opt_disc</c></tag>
<item>
- <p>Optional disc. The schema may reside on either disc
- or ram. If the schema is found on disc, Mnesia starts as a
- disc-full node (the storage type of the schema table is
- disc_copies). If no schema is found on disc, Mnesia starts
- as a disc-less node (the storage type of the schema table is
- ram_copies). The default value for the application parameter
- is
- <c>opt_disc</c>. </p>
+ <p>Optional disc. The schema can reside on either disc or
+ RAM. If the schema is found on disc, <c>Mnesia</c> starts as
+ a disc-full node (the storage type of the schema table is
+ disc_copies). If no schema is found on disc, <c>Mnesia</c>
+ starts as a disc-less node (the storage type of the schema
+ table is <c>ram_copies</c>). The default for the
+ application parameter is <c>opt_disc</c>.</p>
</item>
</taglist>
- <p>When the <c>schema_location</c> is set to opt_disc the
- function <c>mnesia:change_table_copy_type/3</c> may be used to
- change the storage type of the schema.
- This is illustrated below:
- </p>
+ <p>When <c>schema_location</c> is set to <c>opt_disc</c>, the
+ function
+ <seealso marker="mnesia#change_table_copy_type/3">mnesia:change_table_copy_type/3</seealso>
+ can be used to change the storage type of the schema.
+ This is illustrated as follows:</p>
<pre>
1> mnesia:start().
ok
2> mnesia:change_table_copy_type(schema, node(), disc_copies).
- {atomic, ok}
- </pre>
- <p>Assuming that the call to <c>mnesia:start</c> did not
- find any schema to read on the disc, then Mnesia has started
- as a disc-less node, and then changed it to a node that
- utilizes the disc to locally store the schema.
- </p>
+ {atomic, ok}</pre>
+ <p>Assuming that the call to
+ <seealso marker="mnesia#start/0">mnesia:start/0</seealso> does not
+ find any schema to read on the disc, <c>Mnesia</c> starts
+ as a disc-less node, and then change it to a node that
+ use the disc to store the schema locally.</p>
</section>
<section>
- <title>More Schema Management</title>
- <p>It is possible to add and remove nodes from a Mnesia system.
- This can be done by adding a copy of the schema to those nodes.
- </p>
- <p>The functions <c>mnesia:add_table_copy/3</c> and
- <c>mnesia:del_table_copy/2</c> may be used to add and delete
- replicas of the schema table. Adding a node to the list
- of nodes where the schema is replicated will affect two
- things. First it allows other tables to be replicated to
- this node. Secondly it will cause Mnesia to try to contact
- the node at start-up of disc-full nodes.
- </p>
- <p>The function call <c>mnesia:del_table_copy(schema, mynode@host)</c> deletes the node 'mynode@host' from the
- Mnesia system. The call fails if mnesia is running on
- 'mynode@host'. The other mnesia nodes will never try to connect
- to that node again. Note, if there is a disc
- resident schema on the node 'mynode@host', the entire mnesia
- directory should be deleted. This can be done with
- <c>mnesia:delete_schema/1</c>. If
- mnesia is started again on the the node 'mynode@host' and the
- directory has not been cleared, mnesia's behaviour is undefined.
- </p>
- <p>If the storage type of the schema is ram_copies, i.e, we
- have disc-less node, Mnesia
- will not use the disc on that particular node. The disc
- usage is enabled by changing the storage type of the table
- <c>schema</c> to disc_copies.
- </p>
- <p>New schemas are
- created explicitly with <c>mnesia:create_schema/1</c> or implicitly
- by starting Mnesia without a disc resident schema. Whenever
- a table (including the schema table) is created it is
- assigned its own unique cookie. The schema table is not created with
- <c>mnesia:create_table/2</c> as normal tables.
- </p>
- <p>At start-up Mnesia connects different nodes to each other,
- then they exchange table definitions with each other and the
- table definitions are merged. During the merge procedure Mnesia
+ <title>More about Schema Management</title>
+ <p>Nodes can be added to and removed from a <c>Mnesia</c> system.
+ This can be done by adding a copy of the schema to those nodes.</p>
+ <p>The functions
+ <seealso marker="mnesia#add_table_copy/3">mnesia:add_table_copy/3</seealso>
+ and
+ <seealso marker="mnesia#del_table_copy/2">mnesia:del_table_copy/2</seealso>
+ can be used to add and delete
+ replicas of the schema table. Adding a node to the list of
+ nodes where the schema is replicated affects the following:</p>
+ <list type="bulleted">
+ <item>It allows other tables to be replicated to this node.
+ </item>
+ <item>It causes <c>Mnesia</c> to try to contact the node at
+ startup of disc-full nodes.
+ </item>
+ </list>
+ <p>The function call <c>mnesia:del_table_copy(schema,
+ mynode@host)</c> deletes node <c>mynode@host</c> from the
+ <c>Mnesia</c> system. The call fails if <c>Mnesia</c> is running
+ on <c>mynode@host</c>. The other <c>Mnesia</c> nodes never try to
+ connect to that node again. Notice that if there is a disc resident
+ schema on node <c>mynode@host</c>, the entire <c>Mnesia</c>
+ directory is to be deleted. This is done with the function
+ <seealso marker="mnesia#delete_schema/1">mnesia:delete_schema/1</seealso>.
+ If <c>Mnesia</c> is started again
+ on node <c>mynode@host</c> and the directory has not been
+ cleared, the behavior of <c>Mnesia</c> is undefined.</p>
+ <p>If the storage type of the schema is <c>ram_copies</c>,
+ that is, a disc-less node, <c>Mnesia</c>
+ does not use the disc on that particular node. The disc
+ use is enabled by changing the storage type of table
+ <c>schema</c> to <c>disc_copies</c>.</p>
+ <p>New schemas are created explicitly with the function
+ <seealso marker="mnesia#create_schema/1">mnesia:create_schema/1</seealso>
+ or implicitly by starting
+ <c>Mnesia</c> without a disc resident schema. Whenever
+ a table (including the schema table) is created, it is
+ assigned its own unique cookie. The schema table is not created
+ with the function
+ <seealso marker="mnesia#create_table/2">mnesia:create_table/2</seealso>
+ as normal tables.</p>
+ <p>At startup, <c>Mnesia</c> connects different nodes to each other,
+ then they exchange table definitions with each other, and the table
+ definitions are merged. During the merge procedure, <c>Mnesia</c>
performs a sanity test to ensure that the table definitions are
- compatible with each other. If a table exists on several nodes
- the cookie must be the same, otherwise Mnesia will shutdown one
- of the nodes. This unfortunate situation will occur if a table
+ compatible with each other. If a table exists on several nodes,
+ the cookie must be the same, otherwise <c>Mnesia</c> shut down one
+ of the nodes. This unfortunate situation occurs if a table
has been created on two nodes independently of each other while
- they were disconnected. To solve the problem, one of the tables
- must be deleted (as the cookies differ we regard it to be two
- different tables even if they happen to have the same name).
- </p>
- <p>Merging different versions of the schema table, does not
+ they were disconnected. To solve this, one of the tables
+ must be deleted (as the cookies differ, it is regarded to be two
+ different tables even if they have the same name).</p>
+ <p>Merging different versions of the schema table does not
always require the cookies to be the same. If the storage
- type of the schema table is disc_copies, the cookie is
- immutable, and all other db_nodes must have the same
- cookie. When the schema is stored as type ram_copies,
+ type of the schema table is <c>disc_copies</c>, the cookie is
+ immutable, and all other <c>db_nodes</c> must have the same
+ cookie. When the schema is stored as type <c>ram_copies</c>,
its cookie can be replaced with a cookie from another node
- (ram_copies or disc_copies). The cookie replacement (during
- merge of the schema table definition) is performed each time
- a RAM node connects to another node.
- </p>
- <p><c>mnesia:system_info(schema_location)</c> and
- <c>mnesia:system_info(extra_db_nodes)</c> may be used to determine
- the actual values of schema_location and extra_db_nodes
- respectively. <c>mnesia:system_info(use_dir)</c> may be used to
- determine whether Mnesia is actually using the Mnesia
- directory. <c>use_dir</c> may be determined even before
- Mnesia is started. The function <c>mnesia:info/0</c> may now be
- used to printout some system information even before Mnesia
- is started. When Mnesia is started the function prints out
- more information.
- </p>
- <p>Transactions which update the definition of a table,
- requires that Mnesia is started on all nodes where the
- storage type of the schema is disc_copies. All replicas of
+ (<c>ram_copies</c> or <c>disc_copies</c>). The cookie replacement
+ (during merge of the schema table definition) is performed each
+ time a RAM node connects to another node.</p>
+ <p>Further, the following applies:</p>
+ <list type ="bulleted">
+ <item><seealso marker="mnesia#system_info/1">mnesia:system_info(schema_location)</seealso>
+ and
+ <seealso marker="mnesia#system_info/1">mnesia:system_info(extra_db_nodes)</seealso>
+ can be used to determine the actual values of <c>schema_location</c>
+ and <c>extra_db_nodes</c>, respectively.
+ </item>
+ <item><seealso marker="mnesia#system_info/1">mnesia:system_info(use_dir)</seealso>
+ can be used to determine whether <c>Mnesia</c> is actually
+ using the <c>Mnesia</c> directory.
+ </item>
+ <item><c>use_dir</c> can be determined even before
+ <c>Mnesia</c> is started.
+ </item>
+ </list>
+ <p>The function <seealso marker="mnesia#info/0">mnesia:info/0</seealso>
+ can now be used to print
+ some system information even before <c>Mnesia</c> is started.
+ When <c>Mnesia</c> is started, the function prints more
+ information.</p>
+ <p>Transactions that update the definition of a table
+ requires that <c>Mnesia</c> is started on all nodes where the
+ storage type of the schema is <c>disc_copies</c>. All replicas of
the table on these nodes must also be loaded. There are a
- few exceptions to these availability rules. Tables may be
- created and new replicas may be added without starting all
- of the disc-full nodes. New replicas may be added before all
- other replicas of the table have been loaded, it will suffice
- when one other replica is active.
- </p>
+ few exceptions to these availability rules:</p>
+ <list type="bulleted">
+ <item>Tables can be created and new replicas can be added
+ without starting all the disc-full nodes.
+ </item>
+ <item>New replicas can be added before all other replicas of
+ the table have been loaded, provided that at least one other
+ replica is active.
+ </item>
+ </list>
</section>
<section>
<marker id="event_handling"></marker>
<title>Mnesia Event Handling</title>
- <p>System events and table events are the two categories of events
- that Mnesia will generate in various situations.
- </p>
- <p>It is possible for user process to subscribe on the
- events generated by Mnesia.
- We have the following two functions:</p>
+ <p>System events and table events are the two event categories
+ that <c>Mnesia</c> generates in various situations.</p>
+ <p>A user process can subscribe on the events generated by
+ <c>Mnesia</c>. The following two functions are provided:</p>
<taglist>
- <tag><c>mnesia:subscribe(Event-Category)</c></tag>
- <item>
- <p>Ensures that a copy of all events of type
- <c>Event-Category</c> are sent to the calling process.
- </p>
- </item>
- <tag><c>mnesia:unsubscribe(Event-Category)</c></tag>
+ <tag><seealso marker="mnesia#subscribe/1">mnesia:subscribe(Event-Category)</seealso>
+ </tag>
+ <item>Ensures that a copy of all events of type
+ <c>Event-Category</c> are sent to the calling process</item>
+ <tag><seealso marker="mnesia#unsubscribe/1">mnesia:unsubscribe(Event-Category)</seealso>
+ </tag>
<item>Removes the subscription on events of type
- <c>Event-Category</c></item>
+ <c>Event-Category</c>
+ </item>
</taglist>
- <p><c>Event-Category</c> may either be the atom <c>system</c>, the atom <c>activity</c>, or
- one of the tuples <c>{table, Tab, simple}</c>, <c>{table, Tab, detailed}</c>. The old event-category <c>{table, Tab}</c> is the same
- event-category as <c>{table, Tab, simple}</c>.
- The subscribe functions activate a subscription
+ <p><c>Event-Category</c> can be either of the following:</p>
+ <list type="bulleted">
+ <item>The atom <c>system</c>
+ </item>
+ <item>The atom <c>activity</c>
+ </item>
+ <item>The tuple <c>{table, Tab, simple}</c>
+ </item>
+ <item>The tuple <c>{table, Tab, detailed}</c>
+ </item>
+ </list>
+ <p>The old event category <c>{table, Tab}</c> is the same
+ event category as <c>{table, Tab, simple}</c>.</p>
+ <p>The subscribe functions activate a subscription
of events. The events are delivered as messages to the process
- evaluating the <c>mnesia:subscribe/1</c> function. The syntax of
- system events is <c>{mnesia_system_event, Event}</c>,
- <c>{mnesia_activity_event, Event}</c> for activity events, and
- <c>{mnesia_table_event, Event}</c> for table events. What the various
- event types mean is described below.</p>
- <p>All system events are subscribed by Mnesia's
- gen_event handler. The default gen_event handler is
- <c>mnesia_event</c>. But it may be changed by using the application
- parameter <c>event_module</c>. The value of this parameter must be
- the name of a module implementing a complete handler
- as specified by the <c>gen_event</c> module in
- STDLIB. <c>mnesia:system_info(subscribers)</c> and
- <c>mnesia:table_info(Tab, subscribers)</c> may be used to determine
- which processes are subscribed to various
- events.
- </p>
+ evaluating the function
+ <seealso marker="mnesia#subscribe/1">mnesia:subscribe/1</seealso>
+ The syntax is as follows:</p>
+ <list type="bulleted">
+ <item><c>{mnesia_system_event, Event}</c> for system events
+ </item>
+ <item><c>{mnesia_activity_event, Event}</c> for activity events
+ </item>
+ <item><c>{mnesia_table_event, Event}</c> for table events
+ </item>
+ </list>
+ <p>The event types are described in the next sections.</p>
+ <p>All system events are subscribed by the <c>Mnesia</c>
+ <c>gen_event</c> handler. The default <c>gen_event</c> handler
+ is <c>mnesia_event</c>, but it can be changed by using
+ application parameter <c>event_module</c>. The value of this
+ parameter must be the name of a module implementing a complete
+ handler, as specified by the
+ <seealso marker="stdlib:gen_event">gen_event</seealso> module
+ in <c>STDLIB</c>.</p>
+ <p><seealso marker="mnesia#system_info/1">mnesia:system_info(subscribers)</seealso>
+ and
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, subscribers)</seealso>
+ can be used to determine which processes are subscribed to
+ various events.</p>
<section>
<title>System Events</title>
- <p>The system events are detailed below:</p>
+ <p>The system events are as follows:</p>
<taglist>
<tag><c>{mnesia_up, Node}</c></tag>
- <item>
- <p>Mnesia has been started on a node.
- Node is the name of the node. By default this event is ignored.
- </p>
+ <item>Mnesia is started on a node. <c>Node</c> is the node
+ name. By default this event is ignored.
</item>
<tag><c>{mnesia_down, Node}</c></tag>
- <item>
- <p>Mnesia has been stopped on a node.
- Node is the name of the node. By default this event is
- ignored.
- </p>
+ <item>Mnesia is stopped on a node. <c>Node</c> is the node
+ name. By default this event is ignored.
</item>
<tag><c>{mnesia_checkpoint_activated, Checkpoint}</c></tag>
- <item>
- <p>a checkpoint with the name
- <c>Checkpoint</c> has been activated and that the current node is
- involved in the checkpoint. Checkpoints may be activated
- explicitly with <c>mnesia:activate_checkpoint/1</c> or implicitly
- at backup, adding table replicas, internal transfer of data
- between nodes etc. By default this event is ignored.
- </p>
+ <item>A checkpoint with the name <c>Checkpoint</c> is
+ activated and the current node is involved in the
+ checkpoint. Checkpoints can be activated explicitly with
+ the function
+ <seealso marker="mnesia#activate_checkpoint/1">mnesia:activate_checkpoint/1</seealso>
+ or implicitly at
+ backup, when adding table replicas, at internal transfer of
+ data between nodes, and so on. By default this event is
+ ignored.
</item>
<tag><c>{mnesia_checkpoint_deactivated, Checkpoint}</c></tag>
- <item>
- <p>A checkpoint with the name
- <c>Checkpoint</c> has been deactivated and that the current node was
- involved in the checkpoint. Checkpoints may explicitly be
- deactivated with <c>mnesia:deactivate/1</c> or implicitly when the
- last replica of a table (involved in the checkpoint)
- becomes unavailable, e.g. at node down. By default this
- event is ignored.
- </p>
+ <item>A checkpoint with the name <c>Checkpoint</c> is
+ deactivated and the current node is involved in the
+ checkpoint. Checkpoints can be deactivated explicitly with
+ the function
+ <seealso marker="mnesia#deactivate_checkpoint/1">mnesia:deactivate/1</seealso>
+ or implicitly when the last
+ replica of a table (involved in the checkpoint) becomes
+ unavailable, for example, at node-down. By default this
+ event is ignored.
</item>
<tag><c>{mnesia_overload, Details}</c></tag>
- <item>
- <p>Mnesia on the current node is
- overloaded and the subscriber should take action.
- </p>
+ <item><p><c>Mnesia</c> on the current node is
+ overloaded and the subscriber is to take action.</p>
<p>A typical overload situation occurs when the
- applications are performing more updates on disc
- resident tables than Mnesia is able to handle. Ignoring
- this kind of overload may lead into a situation where
+ applications perform more updates on disc resident
+ tables than <c>Mnesia</c> can handle. Ignoring
+ this kind of overload can lead to a situation where
the disc space is exhausted (regardless of the size of
- the tables stored on disc).
- <br></br>
- Each update is appended to
- the transaction log and occasionally(depending of how it
+ the tables stored on disc).</p>
+ <p>Each update is appended to the transaction log and
+ occasionally (depending on how it
is configured) dumped to the tables files. The
table file storage is more compact than the transaction
log storage, especially if the same record is updated
- over and over again. If the thresholds for dumping the
- transaction log have been reached before the previous
- dump was finished an overload event is triggered.
- </p>
+ repeatedly. If the thresholds for dumping the
+ transaction log are reached before the previous
+ dump is finished, an overload event is triggered.</p>
<p>Another typical overload situation is when the
transaction manager cannot commit transactions at the
- same pace as the applications are performing updates of
- disc resident tables. When this happens the message
- queue of the transaction manager will continue to grow
+ same pace as the applications perform updates of
+ disc resident tables. When this occurs, the message
+ queue of the transaction manager continues to grow
until the memory is exhausted or the load
- decreases.
- </p>
- <p>The same problem may occur for dirty updates. The overload
- is detected locally on the current node, but its cause may
- be on another node. Application processes may cause heavy
- loads if any table are residing on other nodes (replicated or not). By default this event
- is reported to the error_logger.
- </p>
+ decreases.</p>
+ <p>The same problem can occur for dirty updates. The overload
+ is detected locally on the current node, but its cause can
+ be on another node. Application processes can cause high
+ load if any table resides on another node (replicated
+ or not). By default this event
+ is reported to <c>error_logger.</c></p>
</item>
<tag><c>{inconsistent_database, Context, Node}</c></tag>
- <item>
- <p>Mnesia regards the database as
- potential inconsistent and gives its applications a chance
- to recover from the inconsistency, e.g. by installing a
- consistent backup as fallback and then restart the system
- or pick a <c>MasterNode</c> from <c>mnesia:system_info(db_nodes)</c>)
- and invoke <c>mnesia:set_master_node([MasterNode])</c>. By default an
- error is reported to the error logger.
- </p>
+ <item><c>Mnesia</c> regards the database as potential
+ inconsistent and gives its applications a chance to
+ recover from the inconsistency. For example, by installing a
+ consistent backup as fallback and then restart the system.
+ An alternative is to pick a <c>MasterNode</c> from
+ <seealso marker="mnesia#system_info/1">mnesia:system_info(db_nodes)</seealso>
+ and invoke
+ <seealso marker="mnesia#set_master_nodes/1">mnesia:set_master_node([MasterNode])</seealso>.
+ By default an error is reported to <c>error_logger</c>.
</item>
<tag><c>{mnesia_fatal, Format, Args, BinaryCore}</c></tag>
<item>
- <p>Mnesia has encountered a fatal error
- and will (in a short period of time) be terminated. The reason for
- the fatal error is explained in Format and Args which may
- be given as input to <c>io:format/2</c> or sent to the
- error_logger. By default it will be sent to the
- error_logger. <c>BinaryCore</c> is a binary containing a summary of
- Mnesia's internal state at the time the when the fatal error was
- encountered. By default the binary is written to a
- unique file name on current directory. On RAM nodes the
- core is ignored.
- </p>
+ <p><c>Mnesia</c> detected a fatal error and
+ terminates soon. The fault reason is explained in
+ <c>Format</c> and <c>Args</c>, which can be given as input
+ to <c>io:format/2</c> or sent to <c>error_logger</c>. By
+ default it is sent to <c>error_logger</c>.</p>
+ <p><c>BinaryCore</c> is a binary containing a summary of the
+ <c>Mnesia</c> internal state at the time when the fatal
+ error was detected. By default the binary is written to a
+ unique filename on the current directory. On RAM nodes, the
+ core is ignored.</p>
</item>
<tag><c>{mnesia_info, Format, Args}</c></tag>
- <item>
- <p>Mnesia has detected something that
- may be of interest when debugging the system. This is explained
- in <c>Format</c> and <c>Args</c> which may appear
- as input to <c>io:format/2</c> or sent to the error_logger. By
- default this event is printed with <c>io:format/2</c>.
- </p>
+ <item><c>Mnesia</c> detected something that can be of
+ interest when debugging the system. This is explained in
+ <c>Format</c> and <c>Args</c>, which can appear as input
+ to <c>io:format/2</c> or sent to <c>error_logger</c>. By
+ default this event is printed with <c>io:format/2</c>.
</item>
<tag><c>{mnesia_error, Format, Args}</c></tag>
- <item>
- <p>Mnesia has encountered an error. The
- reason for the error is explained i <c>Format</c> and <c>Args</c>
- which may be given as input to <c>io:format/2</c> or sent to the
- error_logger. By default this event is reported to the error_logger.
- </p>
+ <item><c>Mnesia</c> has detected an error. The fault reason is
+ explained in <c>Format</c> and <c>Args</c>, which can be
+ given as input to <c>io:format/2</c> or sent to
+ <c>error_logger</c>. By default this event is reported to
+ <c>error_logger</c>.
</item>
<tag><c>{mnesia_user, Event}</c></tag>
- <item>
- <p>An application has invoked the
- function <c>mnesia:report_event(Event)</c>. <c>Event</c> may be any Erlang
- data structure. When tracing a system of Mnesia applications
- it is useful to be able to interleave Mnesia's own events with
- application related events that give information about the
- application context. Whenever the application starts with
- a new and demanding Mnesia activity or enters a
- new and interesting phase in its execution it may be a good idea
- to use <c>mnesia:report_event/1</c>. </p>
+ <item>An application started the function
+ <seealso marker="mnesia#report_event/1">mnesia:report_event(Event)</seealso>.
+ <c>Event</c> can be
+ any Erlang data structure. When tracing a system of
+ <c>Mnesia</c> applications, it is useful to be able to
+ interleave own events of <c>Mnesia</c> with application-related
+ events that give information about the application context.
+ Whenever the application starts with a new and demanding
+ <c>Mnesia</c> activity, or enters a new and interesting
+ phase in its execution, it can be a good idea to use
+ <c>mnesia:report_event/1</c>.
</item>
</taglist>
</section>
@@ -1045,80 +1021,86 @@ ok
<taglist>
<tag><c>{complete, ActivityID}</c></tag>
<item>
- <p>This event occurs when a transaction that caused a modification to the database
- has completed. It is useful for determining when a set of table events
- (see below) caused by a given activity have all been sent. Once the this event
- has been received, it is guaranteed that no further table events with the same
- ActivityID will be received. Note that this event may still be received even
- if no table events with a corresponding ActivityID were received, depending on
+ <p>This event occurs when a transaction that caused a modification
+ to the database is completed. It is useful for determining when
+ a set of table events (see the next section), caused by a given
+ activity, have been sent. Once this event is received, it is
+ guaranteed that no further table events with the same
+ <c>ActivityID</c> will be received. Notice that this event can
+ still be received even if no table events with a corresponding
+ <c>ActivityID</c> were received, depending on
the tables to which the receiving process is subscribed.</p>
- <p>Dirty operations always only contain one update and thus no activity event is sent.</p>
+ <p>Dirty operations always contain only one update and thus no
+ activity event is sent.</p>
</item>
</taglist>
</section>
<section>
<title>Table Events</title>
- <p>The final category of events are table events, which are
- events related to table updates. There are two types of table
- events simple and detailed.
- </p>
- <p>The simple table events are tuples looking like this:
- <c>{Oper, Record, ActivityId}</c>. Where <c>Oper</c> is the
- operation performed. <c>Record</c> is the record involved in the
- operation and <c>ActivityId</c> is the identity of the
- transaction performing the operation. Note that the name of the
- record is the table name even when the <c>record_name</c> has
- another setting. The various table related events that may
- occur are:
- </p>
+ <p>Table events are events related to table updates. There are
+ two types of table events, simple and detailed.</p>
+ <p>The <em>simple table events</em> are tuples like
+ <c>{Oper, Record, ActivityId}</c>, where:</p>
+ <list type="bulleted">
+ <item><c>Oper</c> is the operation performed.
+ </item>
+ <item><c>Record</c> is the record involved in the operation.
+ </item>
+ <item><c>ActivityId</c> is the identity of the transaction
+ performing the operation.
+ </item>
+ </list>
+ <p>Notice that the record name is the table name even when
+ <c>record_name</c> has another setting.</p>
+ <p>The table-related events that can occur are as follows:</p>
<taglist>
<tag><c>{write, NewRecord, ActivityId}</c></tag>
- <item>
- <p>a new record has been written.
- NewRecord contains the new value of the record.
- </p>
+ <item>A new record has been written. <c>NewRecord</c> contains
+ the new record value.
</item>
<tag><c>{delete_object, OldRecord, ActivityId}</c></tag>
- <item>
- <p>a record has possibly been deleted
- with <c>mnesia:delete_object/1</c>. <c>OldRecord</c>
- contains the value of the old record as stated as argument
- by the application. Note that, other records with the same
- key may be remaining in the table if it is a bag.
- </p>
+ <item>A record has possibly been deleted with
+ <seealso marker="mnesia#delete_object/1">mnesia:delete_object/1</seealso>.
+ <c>OldRecord</c>
+ contains the value of the old record, as stated as argument
+ by the application. Notice that other records with the same
+ key can remain in the table if it is of type <c>bag</c>.
</item>
<tag><c>{delete, {Tab, Key}, ActivityId}</c></tag>
- <item>
- <p>one or more records possibly has
- been deleted. All records with the key Key in the table
- <c>Tab</c> have been deleted. </p>
+ <item>One or more records have possibly been deleted.
+ All records with the key <c>Key</c> in the table
+ <c>Tab</c> have been deleted.
</item>
</taglist>
- <p>The detailed table events are tuples looking like
- this: <c>{Oper, Table, Data, [OldRecs], ActivityId}</c>.
- Where <c>Oper</c> is the operation
- performed. <c>Table</c> is the table involved in the operation,
- <c>Data</c> is the record/oid written/deleted.
- <c>OldRecs</c> is the contents before the operation.
- and <c>ActivityId</c> is the identity of the transaction
- performing the operation.
- The various table related events that may occur are:
- </p>
+ <p>The <em>detailed table events</em> are tuples like
+ <c>{Oper, Table, Data, [OldRecs], ActivityId}</c>, where:</p>
+ <list type="bulleted">
+ <item><c>Oper</c> is the operation performed.
+ </item>
+ <item><c>Table</c> is the table involved in the operation.
+ </item>
+ <item><c>Data</c> is the record/OID written/deleted.
+ </item>
+ <item><c>OldRecs</c> is the contents before the operation.
+ </item>
+ <item><c>ActivityId</c> is the identity of the transaction
+ performing the operation.
+ </item>
+ </list>
+ <p>The table-related events that can occur are as follows:</p>
<taglist>
<tag><c>{write, Table, NewRecord, [OldRecords], ActivityId}</c></tag>
- <item>
- <p>a new record has been written.
- NewRecord contains the new value of the record and OldRecords
- contains the records before the operation is performed.
- Note that the new content is dependent on the type of the table.</p>
+ <item>A new record has been written. <c>NewRecord</c> contains
+ the new record value and <c>OldRecords</c> contains the
+ records before the operation is performed. Notice that the
+ new content depends on the table type.
</item>
<tag><c>{delete, Table, What, [OldRecords], ActivityId}</c></tag>
- <item>
- <p>records has possibly been deleted
- <c>What</c> is either {Table, Key} or a record {RecordName, Key, ...}
- that was deleted.
- Note that the new content is dependent on the type of the table.</p>
+ <item>Records have possibly been deleted. <c>What</c> is
+ either <c>{Table, Key}</c> or a record
+ <c>{RecordName, Key, ...}</c> that was deleted. Notice
+ that the new content depends on the table type.
</item>
</taglist>
</section>
@@ -1126,69 +1108,55 @@ ok
<section>
<title>Debugging Mnesia Applications</title>
- <p>Debugging a Mnesia application can be difficult due to a number of reasons, primarily related
+ <p>Debugging a <c>Mnesia</c> application can be difficult
+ for various reasons, primarily related
to difficulties in understanding how the transaction
- and table load mechanisms work. An other source of
- confusion may be the semantics of nested transactions.
- </p>
- <p>We may set the debug level of Mnesia by calling:
- </p>
- <list type="bulleted">
- <item><c>mnesia:set_debug_level(Level)</c></item>
- </list>
- <p>Where the parameter <c>Level</c> is:
- </p>
+ and table load mechanisms work. Another source of
+ confusion can be the semantics of nested transactions.</p>
+ <p>The debug level of <c>Mnesia</c> is set by calling the function
+ <seealso marker="mnesia#set_debug_level/1">mnesia:set_debug_level(Level)</seealso>,
+ where <c>Level</c>is one of the following:</p>
<taglist>
<tag><c>none</c></tag>
- <item>
- <p>no trace outputs at all. This is the default.
- </p>
+ <item>No trace outputs. This is the default.
</item>
<tag><c>verbose</c></tag>
- <item>
- <p>activates tracing of important debug events. These
- debug events will generate <c>{mnesia_info, Format, Args}</c>
- system events. Processes may subscribe to these events with
- <c>mnesia:subscribe/1</c>. The events are always sent to Mnesia's
- event handler.
- </p>
+ <item>Activates tracing of important debug events. These
+ events generate <c>{mnesia_info, Format, Args}</c>
+ system events. Processes can subscribe to these events with
+ the function
+ <seealso marker="mnesia#subscribe/1">mnesia:subscribe/1</seealso>.
+ The events are always sent to the <c>Mnesia</c> event handler.
</item>
<tag><c>debug</c></tag>
- <item>
- <p>activates all events at the verbose level plus
- traces of all debug events. These debug events will generate
- <c>{mnesia_info, Format, Args}</c> system events. Processes may
- subscribe to these events with <c>mnesia:subscribe/1</c>. The
- events are always sent to Mnesia's event handler. On this
- debug level Mnesia's event handler starts subscribing
- updates in the schema table.
- </p>
+ <item>Activates all events at the verbose level plus
+ traces of all debug events. These debug events generate
+ <c>{mnesia_info, Format, Args}</c> system events. Processes
+ can subscribe to these events with <c>mnesia:subscribe/1</c>.
+ The events are always sent to the <c>Mnesia</c> event handler.
+ On this debug level, the <c> Mnesia</c> event handler starts
+ subscribing to updates in the schema table.
</item>
<tag><c>trace</c></tag>
- <item>
- <p>activates all events at the debug level. On this
- debug level Mnesia's event handler starts subscribing
- updates on all Mnesia tables. This level is only intended
- for debugging small toy systems, since many large
- events may be generated.</p>
+ <item>Activates all events at the debug level. On this
+ level, the <c>Mnesia</c> event handler starts subscribing to
+ updates on all <c>Mnesia</c> tables. This level is intended
+ only for debugging small toy systems, as many large
+ events can be generated.
</item>
<tag><c>false</c></tag>
- <item>
- <p>is an alias for none.</p>
+ <item>An alias for none.
</item>
<tag><c>true</c></tag>
- <item>
- <p>is an alias for debug.</p>
+ <item>An alias for debug.
</item>
</taglist>
- <p>The debug level of Mnesia itself, is also an application
- parameter, thereby making it possible to start an Erlang system
- in order to turn on Mnesia debug in the initial
- start-up phase by using the following code:
- </p>
+ <p>The debug level of <c>Mnesia</c> itself is also an application
+ parameter, making it possible to start an Erlang system
+ to turn on <c>Mnesia</c> debug in the initial
+ startup phase by using the following code:</p>
<pre>
- % erl -mnesia debug verbose
- </pre>
+ % erl -mnesia debug verbose</pre>
</section>
<section>
@@ -1196,85 +1164,81 @@ ok
<p>Programming concurrent Erlang systems is the subject of
a separate book. However, it is worthwhile to draw attention to
the following features, which permit concurrent processes to
- exist in a Mnesia system.
- </p>
- <p>A group of functions or processes can be called within a
- transaction. A transaction may include statements that read,
- write or delete data from the DBMS. A large number of such
+ exist in a <c>Mnesia</c> system:</p>
+ <list type="bulleted">
+ <item><p>A group of functions or processes can be called within a
+ transaction. A transaction can include statements that read,
+ write, or delete data from the DBMS. Many such
transactions can run concurrently, and the programmer does not
- have to explicitly synchronize the processes which manipulate
- the data. All programs accessing the database through the
- transaction system may be written as if they had sole access to
- the data. This is a very desirable property since all
+ need to explicitly synchronize the processes that manipulate
+ the data.</p>
+ <p>All programs accessing the database through the
+ transaction system can be written as if they had sole access to
+ the data. This is a desirable property, as all
synchronization is taken care of by the transaction handler. If
a program reads or writes data, the system ensures that no other
- program tries to manipulate the same data at the same time.
- </p>
- <p>It is possible to move tables, delete tables or reconfigure
- the layout of a table in various ways. An important aspect of
- the actual implementation of these functions is that it is
- possible for user programs to continue to use a table while it
- is being reconfigured. For example, it is possible to
- simultaneously move a table and perform write operations to the
- table . This is important for many applications that
- require continuously available services. Refer to Chapter 4:
- <seealso marker="Mnesia_chap4#trans_prop">Transactions and other access contexts</seealso> for more information.
- </p>
+ program tries to manipulate the same data at the same time.</p>
+ </item>
+ <item>Tables can be moved or deleted, and the layout of a table
+ can be reconfigured in various ways. An important aspect of
+ the implementation of these functions is that user programs
+ can continue to use a table while it
+ is being reconfigured. For example, it is possible to move a
+ table and perform write operations to the table at the same
+ time. This is important for many applications that require
+ continuously available services. For more information, see
+ <seealso marker="Mnesia_chap4#trans_prop">Transactions and Other Access Contexts</seealso>.
+ </item>
+ </list>
</section>
<section>
<title>Prototyping</title>
- <p>If and when we decide that we would like to start and manipulate
- Mnesia, it is often easier to write the definitions and
+ <p>If and when you would like to start and manipulate
+ <c>Mnesia</c>, it is often easier to write the definitions and
data into an ordinary text file.
Initially, no tables and no data exist, or which
- tables are required. At the initial stages of prototyping it
- is prudent write all data into one file, process
- that file and have the data in the file inserted into the database.
- It is possible to initialize Mnesia with data read from a text file.
- We have the following two functions to work with text files.
- </p>
+ tables are required. At the initial stages of prototyping, it
+ is prudent to write all data into one file, process that
+ file, and have the data in the file inserted into the database.
+ <c>Mnesia</c> can be initialized with data read from a text file.
+ The following two functions can be used to work with text
+ files.</p>
<list type="bulleted">
<item>
- <p><c>mnesia:load_textfile(Filename)</c> Which loads a
- series of local table definitions and data found in the file
- into Mnesia. This function also starts Mnesia and possibly
- creates a new schema. The function only operates on the
- local node.
- </p>
+ <seealso marker="mnesia#load_textfile/1">mnesia:load_textfile(Filename)</seealso>
+ loads a series of local table definitions and data found in the
+ file into <c>Mnesia</c>. This function also starts <c>Mnesia</c>
+ and possibly creates a new schema. The function operates
+ on the local node only.
</item>
<item>
- <p><c>mnesia:dump_to_textfile(Filename)</c> Dumps
- all local tables of a mnesia system into a text file which can
- then be edited (by means of a normal text editor) and then
- later reloaded.</p>
+ <seealso marker="mnesia#dump_to_textfile/1">mnesia:dump_to_textfile(Filename)</seealso>
+ dumps all local
+ tables of a <c>Mnesia</c> system into a text file, which
+ can be edited (with a normal text editor) and later reloaded.
</item>
</list>
- <p>These functions are of course much slower than the ordinary
- store and load functions of Mnesia. However, this is mainly intended for minor experiments
- and initial prototyping. The major advantages of these functions is that they are very easy
- to use.
- </p>
- <p>The format of the text file is:
- </p>
+ <p>These functions are much slower than the ordinary store and
+ load functions of <c>Mnesia</c>. However, this is mainly intended
+ for minor experiments and initial prototyping. The major
+ advantage of these functions is that they are easy to use.</p>
+ <p>The format of the text file is as follows:</p>
<pre>
{tables, [{Typename, [Options]},
{Typename2 ......}]}.
- {Typename, Attribute1, Atrribute2 ....}.
- {Typename, Attribute1, Atrribute2 ....}.
- </pre>
+ {Typename, Attribute1, Attribute2 ....}.
+ {Typename, Attribute1, Attribute2 ....}.</pre>
<p><c>Options</c> is a list of <c>{Key,Value}</c> tuples conforming
- to the options we could give to <c>mnesia:create_table/2</c>.
- </p>
- <p>For example, if we want to start playing with a small
- database for healthy foods, we enter then following data into
- the file <c>FRUITS</c>.
- </p>
+ to the options that you can give to
+ <seealso marker="mnesia#create_table/2">mnesia:create_table/2</seealso>.
+ </p>
+ <p>For example, to start playing with a small database for healthy
+ foods, enter the following data into file <c>FRUITS</c>:</p>
<codeinclude file="FRUITS" tag="%0" type="erl"></codeinclude>
- <p>The following session with the Erlang shell then shows how
- to load the fruits database.
- </p>
+ <p>The following session with the Erlang shell shows how
+ to load the <c>FRUITS</c> database:</p>
<pre><![CDATA[
% erl
Erlang (BEAM) emulator version 4.9
@@ -1311,54 +1275,49 @@ ok
ok
3>
]]></pre>
- <p>Where we can see that the DBMS was initiated from a
- regular text file.
- </p>
+ <p>It can be seen that the DBMS was initiated from a
+ regular text file.</p>
</section>
<section>
- <title>Object Based Programming with Mnesia</title>
- <p>The Company database introduced in Chapter 2 has three tables
- which store records (employee, dept, project), and three tables
- which store relationships (manager, at_dep, in_proj). This is a
- normalized data model, which has some advantages over a
- non-normalized data model.
- </p>
- <p>It is more efficient to do a
+ <title>Object-Based Programming with Mnesia</title>
+ <p>The <c>Company</c> database, introduced in
+ <seealso marker="Mnesia_chap2#getting_started">Getting Started</seealso>,
+ has three tables that store records (<c>employee</c>,
+ <c>dept</c>, <c>project</c>), and three tables that store
+ relationships (<c>manager</c>, <c>at_dep</c>, <c>in_proj</c>).
+ This is a normalized data model, which has some advantages over
+ a non-normalized data model.</p>
+ <p>It is more efficient to do a
generalized search in a normalized database. Some operations are
also easier to perform on a normalized data model. For example,
- we can easily remove one project, as the following example
- illustrates:
- </p>
+ one project can easily be removed, as the following example
+ illustrates:</p>
<codeinclude file="company.erl" tag="%13" type="erl"></codeinclude>
<p>In reality, data models are seldom fully normalized. A
realistic alternative to a normalized database model would be
- a data model which is not even in first normal form. Mnesia
- is very suitable for applications such as telecommunications,
- because it is easy to organize data in a very flexible manner. A
- Mnesia database is always organized as a set of tables. Each
- table is filled with rows/objects/records. What sets Mnesia
- apart is that individual fields in a record can contain any type
- of compound data structures. An individual field in a record can
- contain lists, tuples, functions, and even record code.
- </p>
+ a data model that is not even in first normal form. <c>Mnesia</c>
+ is suitable for applications such as telecommunications,
+ because it is easy to organize data in a flexible manner. A
+ <c>Mnesia</c> database is always organized as a set of tables.
+ Each table is filled with rows, objects, and records.
+ What sets <c>Mnesia</c> apart is that individual fields in
+ a record can contain any type of
+ compound data structures. An individual field in a record can
+ contain lists, tuples, functions, and even record code.</p>
<p>Many telecommunications applications have unique requirements
- on lookup times for certain types of records. If our Company
- database had been a part of a telecommunications system, then it
- could be that the lookup time of an employee <em>together</em>
- with a list of the projects the employee is working on, should
- be minimized. If this was the case, we might choose a
- drastically different data model which has no direct
- relationships. We would only have the records themselves, and
- different records could contain either direct references to
- other records, or they could contain other records which are not
- part of the Mnesia schema.
- </p>
- <p>We could create the following record definitions:
- </p>
+ on lookup times for certain types of records. If the <c>Company</c>
+ database had been a part of a telecommunications system, it
+ could be to minimize the lookup time of an employee
+ <em>together</em> with a list of the projects the employee is
+ working on. If this is the case, a drastically different data model
+ without direct relationships can be chosen. You would then have
+ only the records themselves, and different records could contain
+ either direct references to other records, or contain other
+ records that are not part of the <c>Mnesia</c> schema.</p>
+ <p>The following record definitions can be created:</p>
<codeinclude file="company_o.hrl" tag="%0" type="erl"></codeinclude>
- <p>An record which describes an employee might look like this:
- </p>
+ <p>A record that describes an employee can look as follows:</p>
<pre>
Me = #employee{emp_no= 104732,
name = klacke,
@@ -1368,50 +1327,43 @@ ok
room_no = {221, 015},
dept = 'B/SFR',
projects = [erlang, mnesia, otp],
- manager = 114872},
- </pre>
- <p>This model only has three different tables, and the employee
- records contain references to other records. We have the following
- references in the record.
- </p>
+ manager = 114872},</pre>
+ <p>This model has only three different tables, and the employee
+ records contain references to other records. The record has the
+ following references:</p>
<list type="bulleted">
- <item><c>'B/SFR'</c> refers to a <c>dept</c> record.
+ <item><c>'B/SFR'</c> refers to a <c>dept</c> record.
</item>
- <item><c>[erlang, mnesia, otp]</c>. This is a list of three
- direct references to three different <c>projects</c> records.
+ <item><c>[erlang, mnesia, otp]</c> is a list of three
+ direct references to three different <c>projects</c> records.
</item>
- <item><c>114872</c>. This refers to another employee record.
+ <item><c>114872</c> refers to another employee record.
</item>
</list>
- <p>We could also use the Mnesia record identifiers (<c>{Tab, Key}</c>)
- as references. In this case, the <c>dept</c> attribute would be
- set to the value <c>{dept, 'B/SFR'}</c> instead of
- <c>'B/SFR'</c>.
- </p>
+ <p>The <c>Mnesia</c> record identifiers (<c>{Tab, Key}</c>) can
+ also be used as references. In this case, attribute <c>dept</c>
+ would be set to value <c>{dept, 'B/SFR'}</c> instead of
+ <c>'B/SFR'</c>.</p>
<p>With this data model, some operations execute considerably
- faster than they do with the normalized data model in our
- Company database. On the other hand, some other operations
+ faster than they do with the normalized data model in the
+ <c>Company</c> database. However, some other operations
become much more complicated. In particular, it becomes more
difficult to ensure that records do not contain dangling
- pointers to other non-existent, or deleted, records.
- </p>
+ pointers to other non-existent, or deleted, records.</p>
<p>The following code exemplifies a search with a non-normalized
- data model. To find all employees at department
- <c>Dep</c> with a salary higher than <c>Salary</c>, use the following code:
- </p>
+ data model. To find all employees at department <c>Dep</c> with
+ a salary higher than <c>Salary</c>, use the following code:</p>
<codeinclude file="company_o.erl" tag="%9" type="erl"></codeinclude>
- <p>This code is not only easier to write and to understand, but it
- also executes much faster.
- </p>
- <p>It is easy to show examples of code which executes faster if
- we use a non-normalized data model, instead of a normalized
- model. The main reason for this is that fewer tables are
- required. For this reason, we can more easily combine data from
- different tables in join operations. In the above example, the
- <c>get_emps/2</c> function was transformed from a join operation
- into a simple query which consists of a selection and a projection
- on one single table.
- </p>
+ <p>This code is easier to write and to understand, and it
+ also executes much faster.</p>
+ <p>It is easy to show examples of code that executes faster if
+ a non-normalized data model is used, instead of a normalized
+ model. The main reason is that fewer tables are required.
+ Therefore, data from different tables can more easily be
+ combined in join operations. In the previous example, the
+ function <c>get_emps/2</c> is transformed from a join operation
+ into a simple query, which consists of a selection and a
+ projection on one single table.</p>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
index 4458cd3919..fa8fa6bbb0 100644
--- a/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,47 +33,61 @@
<file>Mnesia_chap7.xml</file>
</header>
+ <p>The following topics are included:</p>
+ <list type="bulleted">
+ <item>Database configuration data</item>
+ <item>Core dumps</item>
+ <item>Dumping tables</item>
+ <item>Checkpoints</item>
+ <item>Startup files, log file, and data files</item>
+ <item>Loading tables at startup</item>
+ <item>Recovery from communication failure</item>
+ <item>Recovery of transactions</item>
+ <item>Backup, restore, fallback, and disaster recovery</item>
+ </list>
+
<section>
<title>Database Configuration Data</title>
<p>The following two functions can be used to retrieve system
- information. They are described in detail in the reference manual.
- </p>
+ information. For details, see the Reference Manual.</p>
<list type="bulleted">
- <item><c>mnesia:table_info(Tab, Key) -></c><c>Info | exit({aborted, Reason})</c>.
- Returns information about one table. Such as the
- current size of the table, on which nodes it resides etc.
+ <item><seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, Key)
+ -> Info | exit({aborted,Reason})</seealso>
+ returns information about one table, for example,
+ the current size of the table and on which nodes it resides.
</item>
- <item><c>mnesia:system_info(Key) -> </c><c>Info | exit({aborted, Reason})</c>.
- Returns information about the Mnesia system. For example, transaction
- statistics, db_nodes, configuration parameters etc.
+ <item><seealso marker="mnesia#system_info/1">mnesia:system_info(Key)
+ -> Info | exit({aborted, Reason})</seealso>
+ returns information about the <c>Mnesia</c> system,
+ for example, transaction statistics, <c>db_nodes</c>, and
+ configuration parameters.
</item>
</list>
</section>
<section>
<title>Core Dumps</title>
- <p>If Mnesia malfunctions, system information is dumped to a file
- named <c>MnesiaCore.Node.When</c>. The type of system
+ <p>If <c>Mnesia</c> malfunctions, system information is dumped to
+ file <c>MnesiaCore.Node.When</c>. The type of system
information contained in this file can also be generated with
- the function <c>mnesia_lib:coredump()</c>. If a Mnesia system
- behaves strangely, it is recommended that a Mnesia core dump
- file be included in the bug report.</p>
+ the function <c>mnesia_lib:coredump()</c>. If a <c>Mnesia</c>
+ system behaves strangely, it is recommended that a <c>Mnesia</c>
+ core dump file is included in the bug report.</p>
</section>
<section>
<title>Dumping Tables</title>
<p>Tables of type <c>ram_copies</c> are by definition stored in
- memory only. It is possible, however, to dump these tables to
- disc, either at regular intervals, or before the system is
- shutdown. The function <c>mnesia:dump_tables(TabList)</c> dumps
- all replicas of a set of RAM tables to disc. The tables can be
- accessed while being dumped to disc. To dump the tables to
- disc all replicas must have the storage type <c>ram_copies</c>.
- </p>
- <p>The table content is placed in a .DCD file on the
- disc. When the Mnesia system is started, the RAM table will
- initially be loaded with data from its .DCD file.
- </p>
+ memory only. However, these tables can be dumped to
+ disc, either at regular intervals or before the system is
+ shut down. The function
+ <seealso marker="mnesia#dump_tables/1">mnesia:dump_tables(TabList)</seealso>
+ dumps all replicas of a set of RAM tables to disc. The tables can be
+ accessed while being dumped to disc. To dump the tables to disc,
+ all replicas must have the storage type <c>ram_copies</c>.</p>
+ <p>The table content is placed in a <c>.DCD</c> file on the
+ disc. When the <c>Mnesia</c> system is started, the RAM table
+ is initially loaded with data from its <c>.DCD</c> file.</p>
</section>
<section>
@@ -80,137 +95,128 @@
<title>Checkpoints</title>
<p>A checkpoint is a transaction consistent state that spans over
one or more tables. When a checkpoint is activated, the system
- will remember the current content of the set of tables. The
+ remembers the current content of the set of tables. The
checkpoint retains a transaction consistent state of the tables,
allowing the tables to be read and updated while the checkpoint
- is active. A checkpoint is typically used to
+ is active. A checkpoint is typically used to
back up tables to external media, but they are also used
- internally in Mnesia for other purposes. Each checkpoint is
- independent and a table may be involved in several checkpoints
- simultaneously.
- </p>
- <p>Each table retains its old contents in a checkpoint retainer
- and for performance critical applications, it may be important
+ internally in <c>Mnesia</c> for other purposes. Each checkpoint
+ is independent and a table can be involved in several checkpoints
+ simultaneously.</p>
+ <p>Each table retains its old contents in a checkpoint retainer.
+ For performance critical applications, it can be important
to realize the processing overhead associated with checkpoints.
- In a worst case scenario, the checkpoint retainer will consume
- even more memory than the table itself. Each update will also be
+ In a worst case scenario, the checkpoint retainer consumes
+ more memory than the table itself. Also, each update becomes
slightly slower on those nodes where checkpoint
- retainers are attached to the tables.
- </p>
- <p>For each table it is possible to choose if there should be one
+ retainers are attached to the tables.</p>
+ <p>For each table, it is possible to choose if there is to be one
checkpoint retainer attached to all replicas of the table, or if
it is enough to have only one checkpoint retainer attached to a
single replica. With a single checkpoint retainer per table, the
- checkpoint will consume less memory, but it will be vulnerable
- to node crashes. With several redundant checkpoint retainers the
- checkpoint will survive as long as there is at least one active
- checkpoint retainer attached to each table.
- </p>
- <p>Checkpoints may be explicitly deactivated with the function
- <c>mnesia:deactivate_checkpoint(Name)</c>, where <c>Name</c> is
+ checkpoint consumes less memory, but it is vulnerable
+ to node crashes. With several redundant checkpoint retainers, the
+ checkpoint survives as long as there is at least one active
+ checkpoint retainer attached to each table.</p>
+ <p>Checkpoints can be explicitly deactivated with the function
+ <seealso marker="mnesia#deactivate_checkpoint/1">mnesia:deactivate_checkpoint(Name)</seealso>,
+ where <c>Name</c> is
the name of an active checkpoint. This function returns
- <c>ok</c> if successful, or <c>{error, Reason}</c> in the case
- of an error. All tables in a checkpoint must be attached to at
+ <c>ok</c> if successful or <c>{error, Reason}</c> if there is
+ an error. All tables in a checkpoint must be attached to at
least one checkpoint retainer. The checkpoint is automatically
- de-activated by Mnesia, when any table lacks a checkpoint
- retainer. This may happen when a node goes down or when a
- replica is deleted. Use the <c>min</c> and
- <c>max</c> arguments described below, to control the degree of
- checkpoint retainer redundancy.
- </p>
- <p>Checkpoints are activated with the function <marker id="mnesia:chkpt(Args)"></marker>
-<c>mnesia:activate_checkpoint(Args)</c>,
- where <c>Args</c> is a list of the following tuples:
- </p>
+ deactivated by <c>Mnesia</c>, when any table lacks a checkpoint
+ retainer. This can occur when a node goes down or when a
+ replica is deleted. Use arguments <c>min</c> and
+ <c>max</c> (described in the following list) to control the
+ degree of checkpoint retainer redundancy.</p>
+ <marker id="mnesia:chkpt(Args)"></marker>
+ <p>Checkpoints are activated with the function
+ <seealso marker="mnesia#activate_checkpoint/1">mnesia:activate_checkpoint(Args)</seealso>,
+ where <c>Args</c> is a list of the following tuples:</p>
<list type="bulleted">
- <item><c>{name,Name}</c>. <c>Name</c> specifies a temporary name
- of the checkpoint. The name may be re-used when the checkpoint
- has been de-activated. If no name is specified, a name is
+ <item><c>{name,Name}</c>, where <c>Name</c> specifies a temporary
+ name of the checkpoint. The name can be reused when the checkpoint
+ has been deactivated. If no name is specified, a name is
generated automatically.
</item>
- <item><c>{max,MaxTabs}</c>. <c>MaxTabs</c> is a list of tables
- which will be included in the checkpoint. The default is
- <c>[]</c> (an empty list). For these tables, the redundancy
- will be maximized. The old contents of the table will be
+ <item><c>{max,MaxTabs}</c>, where <c>MaxTabs</c> is a list of
+ tables that are to be included in the checkpoint. Default is
+ <c>[]</c> (empty list). For these tables, the redundancy
+ is maximized. The old content of the table is
retained in the checkpoint retainer when the main table is
- updated by the applications. The checkpoint becomes more fault
+ updated by the applications. The checkpoint is more fault
tolerant if the tables have several replicas. When new
- replicas are added by means of the schema manipulation
- function <c>mnesia:add_table_copy/3</c>, it will also
- attach a local checkpoint retainer.
+ replicas are added by the schema manipulation function
+ <seealso marker="mnesia#add_table_copy/3">mnesia:add_table_copy/3</seealso>
+ it also attaches a local checkpoint retainer.
</item>
- <item><c>{min,MinTabs}</c>. <c>MinTabs</c> is a list of tables
- that should be included in the checkpoint. The default is
- <c>[]</c>. For these tables, the redundancy will be minimized,
- and there will be a single checkpoint retainer per table,
+ <item><c>{min,MinTabs}</c>, where <c>MinTabs</c> is a list of
+ tables that are to be included in the checkpoint. Default
+ is <c>[]</c>. For these tables, the redundancy is minimized,
+ and there is to be single checkpoint retainer per table,
preferably at the local node.
</item>
- <item><c>{allow_remote,Bool}</c>. <c>false</c> means that all
- checkpoint retainers must be local. If a table does not reside
- locally, the checkpoint cannot be activated. <c>true</c>
- allows checkpoint retainers to be allocated on any node. The
- defaults is <c>true</c>.
+ <item><c>{allow_remote,Bool}</c>, where <c>false</c> means that
+ all checkpoint retainers must be local. If a table does not
+ reside locally, the checkpoint cannot be activated. <c>true</c>
+ allows checkpoint retainers to be allocated on any node.
+ Default is <c>true</c>.
</item>
<item><c>{ram_overrides_dump,Bool}</c>. This argument only
applies to tables of type <c>ram_copies</c>. <c>Bool</c>
- specifies if the table state in RAM should override the table
+ specifies if the table state in RAM is to override the table
state on disc. <c>true</c> means that the latest committed
records in RAM are included in the checkpoint retainer. These
are the records that the application accesses. <c>false</c>
- means that the records on the disc .DAT file are
- included in the checkpoint retainer. These are the records
- that will be loaded on start-up. Default is <c>false</c>.</item>
+ means that the records on the disc <c>.DAT</c> file are
+ included in the checkpoint retainer. These records are
+ loaded on startup. Default is <c>false</c>.</item>
</list>
- <p>The <c>mnesia:activate_checkpoint(Args)</c> returns one of the
- following values:
- </p>
+ <p>The function
+ <seealso marker="mnesia#activate_checkpoint/1">mnesia:activate_checkpoint(Args)</seealso>
+ returns one of the following values:</p>
<list type="bulleted">
<item><c>{ok, Name, Nodes}</c></item>
- <item><c>{error, Reason}</c>.</item>
+ <item><c>{error, Reason}</c></item>
</list>
- <p><c>Name</c> is the name of the checkpoint, and <c>Nodes</c> are
- the nodes where the checkpoint is known.
- </p>
+ <p><c>Name</c> is the checkpoint name. <c>Nodes</c> are
+ the nodes where the checkpoint is known.</p>
<p>A list of active checkpoints can be obtained with the following
- functions:
- </p>
+ functions:</p>
<list type="bulleted">
- <item><c>mnesia:system_info(checkpoints)</c>. This function
+ <item><seealso marker="mnesia#system_info/1">mnesia:system_info(checkpoints)</seealso>
returns all active checkpoints on the current node.</item>
- <item><c>mnesia:table_info(Tab,checkpoints)</c>. This function
+ <item><seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, checkpoints)</seealso>
returns active checkpoints on a specific table.</item>
</list>
</section>
<section>
- <title>Files</title>
- <p>This section describes the internal files which are created and maintained by the Mnesia system,
- in particular, the workings of the Mnesia log is described.
- </p>
+ <title>Startup Files, Log File, and Data Files</title>
+ <p>This section describes the internal files that are created
+ and maintained by the <c>Mnesia</c> system. In particular,
+ the workings of the <c>Mnesia</c> log are described.</p>
<section>
- <title>Start-Up Files</title>
- </section>
- <p>In Chapter 3 we detailed the following pre-requisites for
- starting Mnesia (refer Chapter 3: <seealso marker="Mnesia_chap3#start_mnesia">Starting Mnesia</seealso>:
- </p>
+ <title>Startup Files</title>
+ <p><seealso marker="Mnesia_chap3#start_mnesia">Start Mnesia</seealso>
+ states the following prerequisites
+ for starting <c>Mnesia</c>:</p>
<list type="bulleted">
- <item>We must start an Erlang session and specify a Mnesia
- directory for our database.
+ <item>An Erlang session must be started and a <c>Mnesia</c>
+ directory must be specified for the database.
</item>
- <item>We must initiate a database schema, using the function
- <c>mnesia:create_schema/1</c>.
+ <item>A database schema must be initiated, using the function
+ <seealso marker="mnesia#create_schema/1">mnesia:create_schema/1</seealso>.
</item>
</list>
- <p>The following example shows how these tasks are performed:
- </p>
- <list type="ordered">
- <item>
- <pre>
-% <input>erl -sname klacke -mnesia dir '"/ldisc/scratch/klacke"'</input> </pre>
- </item>
- <item>
- <pre>
+ <p>The following example shows how these tasks are performed:</p>
+ <p><em>Step 1:</em> Start an Erlang session and specify a
+ <c>Mnesia</c> directory for the database:</p>
+ <pre>
+% <input>erl -sname klacke -mnesia dir '"/ldisc/scratch/klacke"'</input></pre>
+ <pre>
Erlang (BEAM) emulator version 4.9
Eshell V4.9 (abort with ^G)
@@ -218,679 +224,700 @@ Eshell V4.9 (abort with ^G)
ok
(klacke@gin)2>
<input>^Z</input>
-Suspended </pre>
- <p>We can inspect the Mnesia directory to see what files have been created. Enter the following command:
- </p>
- <pre>
+Suspended</pre>
+ <p><em>Step 2:</em> You can inspect the <c>Mnesia</c> directory
+ to see what files have been created:</p>
+ <pre>
% <input>ls -l /ldisc/scratch/klacke</input>
--rw-rw-r-- 1 klacke staff 247 Aug 12 15:06 FALLBACK.BUP </pre>
- <p>The response shows that the file FALLBACK.BUP has been created. This is called a backup file, and it contains an initial schema. If we had specified more than one node in the <c>mnesia:create_schema/1</c> function, identical backup files would have been created on all nodes.
- </p>
- </item>
- <item>
- <p>Continue by starting Mnesia:</p>
- <pre>
+-rw-rw-r-- 1 klacke staff 247 Aug 12 15:06 FALLBACK.BUP</pre>
+ <p>The response shows that the file <c>FALLBACK.BUP</c> has
+ been created. This is called a backup file, and it contains
+ an initial schema. If more than one node in the function
+ <seealso marker="mnesia#create_schema/1">mnesia:create_schema/1</seealso>
+ had been specified, identical
+ backup files would have been created on all nodes.</p>
+ <p><em>Step 3:</em> Start <c>Mnesia</c>:</p>
+ <pre>
(klacke@gin)3><input>mnesia:start( ).</input>
-ok </pre>
- <p>We can now see the following listing in the Mnesia directory:
- </p>
- <pre>
+ok</pre>
+ <p><em>Step 4:</em> You can see the following listing in
+ the <c>Mnesia</c> directory:</p>
+ <pre>
-rw-rw-r-- 1 klacke staff 86 May 26 19:03 LATEST.LOG
--rw-rw-r-- 1 klacke staff 34507 May 26 19:03 schema.DAT </pre>
- <p>The schema in the backup file FALLBACK.BUP has been used to generate the file <c>schema.DAT.</c> Since we have no other disc resident tables than the schema, no other data files were created. The file FALLBACK.BUP was removed after the successful "restoration". We also see a number of files that are for internal use by Mnesia.
- </p>
- </item>
- <item>
- <p>Enter the following command to create a table:</p>
- <pre>
+-rw-rw-r-- 1 klacke staff 34507 May 26 19:03 schema.DAT</pre>
+ <p>The schema in the backup file <c>FALLBACK.BUP</c> has been
+ used to generate the file <c>schema.DAT</c>. Since there are
+ no other disc resident tables than the schema, no other data
+ files were created. The file <c>FALLBACK.BUP</c> was removed
+ after the successful "restoration". You also see some files
+ that are for internal use by <c>Mnesia</c>.</p>
+ <p><em>Step 5:</em> Create a table:</p>
+ <pre>
(klacke@gin)4> <input>mnesia:create_table(foo,[{disc_copies, [node()]}]).</input>
-{atomic,ok} </pre>
- <p>We can now see the following listing in the Mnesia directory:
- </p>
- <pre>
+{atomic,ok}</pre>
+ <p><em>Step 6:</em> You can see the following listing in
+ the <c>Mnesia</c> directory:</p>
+ <pre>
% <input>ls -l /ldisc/scratch/klacke</input>
-rw-rw-r-- 1 klacke staff 86 May 26 19:07 LATEST.LOG
-rw-rw-r-- 1 klacke staff 94 May 26 19:07 foo.DCD
--rw-rw-r-- 1 klacke staff 6679 May 26 19:07 schema.DAT </pre>
- <p>Where a file <c>foo.DCD</c> has been created. This file will eventually store
- all data that is written into the <c>foo</c> table.</p>
- </item>
- </list>
+-rw-rw-r-- 1 klacke staff 6679 May 26 19:07 schema.DAT</pre>
+ <p>The file <c>foo.DCD</c> has been created. This file will
+ eventually store all data that is written into the
+ <c>foo</c> table.</p>
+ </section>
<section>
- <title>The Log File</title>
- <p>When starting Mnesia, a .LOG file called <c>LATEST.LOG</c>
- was created and placed in the database directory. This file is
- used by Mnesia to log disc based transactions. This includes all
- transactions that write at least one record in a table which is
- of storage type <c>disc_copies</c>, or
- <c>disc_only_copies</c>. It also includes all operations which
- manipulate the schema itself, such as creating new tables. The
- format of the log can vary with different implementations of
- Mnesia. The Mnesia log is currently implemented with the
- standard library module <c>disc_log</c>.
- </p>
- <p>The log file will grow continuously and must be dumped at
- regular intervals. "Dumping the log file" means that Mnesia will
- perform all the operations listed in the log and place the
- records in the corresponding .DAT, .DCD and .DCL data files. For
- example, if the operation "write record <c>{foo, 4, elvis, 6}</c>"
- is listed in the log, Mnesia inserts the operation into the
- file <c>foo.DCL</c>, later when Mnesia thinks the .DCL has become to large
- the data is moved to the .DCD file.
- The dumping operation can be time consuming
- if the log is very large. However, it is important to realize
- that the Mnesia system continues to operate during log dumps.
- </p>
- <p>By default Mnesia either dumps the log whenever 100 records have
- been written in the log or when 3 minutes have passed.
+ <title>Log File</title>
+ <p>When starting <c>Mnesia</c>, a <c>.LOG</c> file called
+ <c>LATEST.LOG</c> is created
+ and placed in the database directory. This file is used by
+ <c>Mnesia</c> to log disc-based transactions. This includes all
+ transactions that write at least one record in a table that is
+ of storage type <c>disc_copies</c> or <c>disc_only_copies</c>.
+ The file also includes all operations that
+ manipulate the schema itself, such as creating new tables.
+ The log format can vary with different implementations of
+ <c>Mnesia</c>. The <c>Mnesia</c> log is currently implemented
+ in the standard library module
+ <seealso marker="kernel:disk_log">disk_log</seealso> in
+ <c>Kernel</c>.</p>
+ <p>The log file grows continuously and must be dumped at
+ regular intervals. "Dumping the log file" means that <c>Mnesia</c>
+ performs all the operations listed in the log and place the
+ records in the corresponding <c>.DAT</c>, <c>.DCD</c>, and
+ <c>.DCL</c> data files. For example, if the operation "write
+ record <c>{foo, 4, elvis, 6}</c>" is listed in the log,
+ <c>Mnesia</c> inserts the operation into the file
+ <c>foo.DCL</c>. Later, when <c>Mnesia</c> thinks that the
+ <c>.DCL</c> file is too large, the data is moved to the
+ <c>.DCD</c> file. The dumping operation can be time consuming
+ if the log is large. Notice that the <c>Mnesia</c> system
+ continues to operate during log dumps.</p>
+ <p>By default <c>Mnesia</c> either dumps the log whenever
+ 100 records have
+ been written in the log or when three minutes have passed.
This is controlled by the two application parameters
<c>-mnesia dump_log_write_threshold WriteOperations</c> and
- <c>-mnesia dump_log_time_threshold MilliSecs</c>.
- </p>
+ <c>-mnesia dump_log_time_threshold MilliSecs</c>.</p>
<p>Before the log is dumped, the file <c>LATEST.LOG</c> is
renamed to <c>PREVIOUS.LOG</c>, and a new <c>LATEST.LOG</c> file
is created. Once the log has been successfully dumped, the file
- <c>PREVIOUS.LOG</c> is deleted.
- </p>
- <p>The log is also dumped at start-up and whenever a schema
- operation is performed.
- </p>
+ <c>PREVIOUS.LOG</c> is deleted.</p>
+ <p>The log is also dumped at startup and whenever a schema
+ operation is performed.</p>
</section>
<section>
- <title>The Data Files</title>
- <p>The directory listing also contains one .DAT file. This contain
- the schema itself, contained in the <c>schema.DAT</c>
- file. The DAT files are indexed files, and it is efficient to
- insert and search for records in these files with a specific
- key. The .DAT files are used for the schema and for <c>disc_only_copies</c>
- tables. The Mnesia data files are currently implemented with the
- standard library module <c>dets</c>, and all operations which
- can be performed on <c>dets</c> files can also be performed on
- the Mnesia data files. For example, <c>dets</c> contains a
- function <c>dets:traverse/2</c> which can be used to view the
- contents of a Mnesia DAT file. However, this can only be done
- when Mnesia is not running. So, to view a our schema file, we
- can: </p>
+ <title>Data Files</title>
+ <p>The directory listing also contains one <c>.DAT</c> file,
+ which contains the schema itself, contained in the
+ <c>schema.DAT</c> file. The <c>DAT</c> files are indexed
+ files, and it is efficient to insert and search for records
+ in these files with a specific key. The <c>.DAT</c> files
+ are used for the schema and for <c>disc_only_copies</c>
+ tables. The <c>Mnesia</c> data files are currently implemented
+ in the standard library module
+ <seealso marker="stdlib:dets">dets</seealso> in
+ <c>STDLIB</c>.</p>
+ <p>All operations that can be performed on <c>dets</c> files
+ can also be performed on the <c>Mnesia</c> data files. For
+ example, <c>dets</c> contains the function
+ <c>dets:traverse/2</c>, which can be used to view the
+ contents of a <c>Mnesia</c> <c>DAT</c> file. However, this
+ can only be done when <c>Mnesia</c> is not running. So, to
+ view the schema file, do as follows;</p>
<pre>
{ok, N} = dets:open_file(schema, [{file, "./schema.DAT"},{repair,false},
{keypos, 2}]),
F = fun(X) -> io:format("~p~n", [X]), continue end,
dets:traverse(N, F),
-dets:close(N). </pre>
- <note>
- <p>Refer to the Reference Manual, <c>std_lib</c> for information about <c>dets</c>.</p>
- </note>
+dets:close(N).</pre>
<warning>
- <p>The DAT files must always be opened with the <c>{repair, false}</c>
- option. This ensures that these files are not
- automatically repaired. Without this option, the database may
- become inconsistent, because Mnesia may
- believe that the files were properly closed. Refer to the reference
- manual for information about the configuration parameter
- <c>auto_repair</c>.</p>
+ <p>The <c>DAT</c> files must always be opened with option
+ <c>{repair, false}</c>. This ensures that these files are not
+ automatically repaired. Without this option, the database can
+ become inconsistent, because <c>Mnesia</c> can believe that
+ the files were properly closed. For information about
+ configuration parameter <c>auto_repair</c>, see the
+ Reference Manual.</p>
</warning>
<warning>
- <p>It is recommended that Data files are not tampered with while Mnesia is
- running. While not prohibited, the behavior of Mnesia is unpredictable. </p>
+ <p>It is recommended that the data files are not tampered
+ with while <c>Mnesia</c> is running. While not prohibited,
+ the behavior of <c>Mnesia</c> is unpredictable.</p>
</warning>
- <p>The <c>disc_copies</c> tables are stored on disk with .DCL and .DCD files,
- which are standard disk_log files.
- </p>
+ <p>The <c>disc_copies</c> tables are stored on disk with
+ <c>.DCL</c> and <c>.DCD</c> files, which are standard
+ <c>disk_log</c> files.</p>
</section>
</section>
<section>
- <title>Loading of Tables at Start-up</title>
- <p>At start-up Mnesia loads tables in order to make them accessible
- for its applications. Sometimes Mnesia decides to load all tables
- that reside locally, and sometimes the tables may not be
- accessible until Mnesia brings a copy of the table
- from another node.
- </p>
- <p>To understand the behavior of Mnesia at start-up it is
- essential to understand how Mnesia reacts when it loses contact
- with Mnesia on another node. At this stage, Mnesia cannot distinguish
- between a communication failure and a "normal" node down. <br></br>
-
- When this happens, Mnesia will assume that the other node is no longer running.
- Whereas, in reality, the communication between the nodes has merely failed.
- </p>
- <p>To overcome this situation, simply try to restart the ongoing transactions that are
- accessing tables on the failing node, and write a <c>mnesia_down</c> entry to a log file.
- </p>
- <p>At start-up, it must be noted that all tables residing on nodes
- without a <c>mnesia_down</c> entry, may have fresher replicas.
- Their replicas may have been updated after the termination
- of Mnesia on the current node. In order to catch up with the latest
+ <title>Loading Tables at Startup</title>
+ <p>At startup, <c>Mnesia</c> loads tables to make them accessible
+ for its applications. Sometimes <c>Mnesia</c> decides to load
+ all tables that reside locally, and sometimes the tables are
+ not accessible until <c>Mnesia</c> brings a copy of the table
+ from another node.</p>
+ <p>To understand the behavior of <c>Mnesia</c> at startup, it is
+ essential to understand how <c>Mnesia</c> reacts when it loses
+ contact with <c>Mnesia</c> on another node. At this stage,
+ <c>Mnesia</c> cannot distinguish between a communication
+ failure and a "normal" node-down. When this occurs,
+ <c>Mnesia</c> assumes that the other node is no longer running,
+ whereas, in reality, the communication between the nodes has
+ failed.</p>
+ <p>To overcome this situation, try to restart the ongoing
+ transactions that are accessing tables on the failing node,
+ and write a <c>mnesia_down</c> entry to a log file.</p>
+ <p>At startup, notice that all tables residing on nodes
+ without a <c>mnesia_down</c> entry can have fresher replicas.
+ Their replicas can have been updated after the termination of
+ <c>Mnesia</c> on the current node. To catch up with the latest
updates, transfer a copy of the table from one of these other
- "fresh" nodes. If you are unlucky, other nodes may be down
- and you must wait for the table to be
- loaded on one of these nodes before receiving a fresh copy of
- the table.
- </p>
+ "fresh" nodes. If you are unlucky, other nodes can be down
+ and you must wait for the table to be loaded on one of these
+ nodes before receiving a fresh copy of the table.</p>
<p>Before an application makes its first access to a table,
- <c>mnesia:wait_for_tables(TabList, Timeout)</c> ought to be executed
+ <seealso marker="mnesia#wait_for_tables/2">mnesia:wait_for_tables(TabList, Timeout)</seealso>
+ is to be executed
to ensure that the table is accessible from the local node. If
- the function times out the application may choose to force a
+ the function times out, the application can choose to force a
load of the local replica with
- <c>mnesia:force_load_table(Tab)</c> and deliberately lose all
- updates that may have been performed on the other nodes while
- the local node was down. If
- Mnesia already has loaded the table on another node or intends
- to do so, we will copy the table from that node in order to
- avoid unnecessary inconsistency.
- </p>
+ <seealso marker="mnesia#force_load_table/1">mnesia:force_load_table(Tab)</seealso>
+ and deliberately lose all
+ updates that can have been performed on the other nodes while
+ the local node was down. If <c>Mnesia</c>
+ has loaded the table on another node already, or intends
+ to do so, copy the table from that node to
+ avoid unnecessary inconsistency.</p>
<warning>
- <p>Keep in mind that it is only
- one table that is loaded by <c>mnesia:force_load_table(Tab)</c>
- and since committed transactions may have caused updates in
- several tables, the tables may now become inconsistent due to
- the forced load.</p>
+ <p>Only one table is loaded by
+ <seealso marker="mnesia#force_load_table/1">mnesia:force_load_table(Tab)</seealso>.
+ Since committed
+ transactions can have caused updates in several tables, the
+ tables can become inconsistent because of the forced load.</p>
</warning>
- <p>The allowed <c>AccessMode</c> of a table may be defined to
- either be <c>read_only</c> or <c>read_write</c>. And it may be
- toggled with the function <c>mnesia:change_table_access_mode(Tab, AccessMode)</c> in runtime. <c>read_only</c> tables and
- <c>local_content</c> tables will always be loaded locally, since
- there are no need for copying the table from other nodes. Other
- tables will primary be loaded remotely from active replicas on
- other nodes if the table already has been loaded there, or if
- the running Mnesia already has decided to load the table there.
- </p>
- <p>At start up, Mnesia will assume that its local replica is the
- most recent version and load the table from disc if either
- situation is detected:
- </p>
+ <p>The allowed <c>AccessMode</c> of a table can be defined to be
+ <c>read_only</c> or <c>read_write</c>. It can be toggled with
+ the function
+ <seealso marker="mnesia#change_table_access_mode/2">
+ mnesia:change_table_access_mode(Tab, AccessMode)</seealso>
+ in runtime. <c>read_only</c> tables and
+ <c>local_content</c> tables are always loaded locally, as
+ there is no need for copying the table from other nodes. Other
+ tables are primarily loaded remotely from active replicas on
+ other nodes if the table has been loaded there already, or if
+ the running <c>Mnesia</c> has decided to load the table there
+ already.</p>
+ <p>At startup, <c>Mnesia</c> assumes that its local replica is the
+ most recent version and loads the table from disc if either of
+ the following situations is detected:</p>
<list type="bulleted">
- <item><c>mnesia_down</c> is returned from all other nodes that holds a disc
- resident replica of the table; or,</item>
- <item>if all replicas are <c>ram_copies</c></item>
+ <item><c>mnesia_down</c> is returned from all other nodes that
+ hold a disc resident replica of the table.</item>
+ <item>All replicas are <c>ram_copies</c>.</item>
</list>
- <p>This is normally a wise decision, but it may turn out to
- be disastrous if the nodes have been disconnected due to a
- communication failure, since Mnesia's normal table load
- mechanism does not cope with communication failures.
- </p>
- <p>When Mnesia is loading many tables the default load
- order. However, it is possible to
- affect the load order by explicitly changing the
- <c>load_order</c> property for the tables, with the function
- <c>mnesia:change_table_load_order(Tab, LoadOrder)</c>. The
- <c>LoadOrder</c> is by default <c>0</c> for all tables, but it
- can be set to any integer. The table with the highest
- <c>load_order</c> will be loaded first. Changing load order is
+ <p>This is normally a wise decision, but it can be disastrous
+ if the nodes have been disconnected because of a communication
+ failure, as the <c>Mnesia</c> normal table load
+ mechanism does not cope with communication failures.</p>
+ <p>When <c>Mnesia</c> loads many tables, the default load order
+ is used. However, the load order
+ can be affected, by explicitly changing property
+ <c>load_order</c> for the tables, with the function
+ <seealso marker="mnesia#change_table_load_order/2">
+ mnesia:change_table_load_order(Tab, LoadOrder)</seealso>.
+ <c>LoadOrder</c> is by default <c>0</c> for all tables, but
+ it can be set to any integer. The table with the highest
+ <c>load_order</c> is loaded first. Changing the load order is
especially useful for applications that need to ensure early
- availability of fundamental tables. Large peripheral
- tables should have a low load order value, perhaps set
- below 0.
- </p>
+ availability of fundamental tables. Large peripheral tables
+ are to have a low load order value, perhaps less than <c>0</c></p>
</section>
<section>
<title>Recovery from Communication Failure</title>
- <p>There are several occasions when Mnesia may detect that the
- network has been partitioned due to a communication failure.
- </p>
- <p>One is when Mnesia already is up and running and the Erlang
- nodes gain contact again. Then Mnesia will try to contact Mnesia
- on the other node to see if it also thinks that the network has
- been partitioned for a while. If Mnesia on both nodes has logged
- <c>mnesia_down</c> entries from each other, Mnesia generates a
- system event, called <c>{inconsistent_database, running_partitioned_network, Node}</c> which is sent to Mnesia's
- event handler and other possible subscribers. The default event
- handler reports an error to the error logger.
- </p>
- <p>Another occasion when Mnesia may detect that the network has
- been partitioned due to a communication failure, is at start-up.
- If Mnesia detects that both the local node and another node received
- <c>mnesia_down</c> from each other it generates a
- <c>{inconsistent_database, starting_partitioned_network, Node}</c> system event and acts as described above.
- </p>
+ <p>There are several occasions when <c>Mnesia</c> can detect
+ that the network has been partitioned because of a
+ communication failure, for example:</p>
+ <list type="bulleted">
+ <item><c>Mnesia</c> is operational already and the Erlang nodes
+ gain contact again. Then <c>Mnesia</c> tries to contact
+ <c>Mnesia</c> on the other node to see if it also thinks that
+ the network has been partitioned for a while. If <c>Mnesia</c>
+ on both nodes has logged <c>mnesia_down</c> entries from each
+ other, <c>Mnesia</c> generates a system event, called
+ <c>{inconsistent_database, running_partitioned_network, Node}</c>,
+ which is sent to the <c>Mnesia</c> event handler and other
+ possible subscribers. The default event
+ handler reports an error to the error logger.
+ </item>
+ <item>If <c>Mnesia</c> detects at startup that both the local
+ node and another node received <c>mnesia_down</c> from each
+ other, <c>Mnesia</c> generates an
+ <c>{inconsistent_database, starting_partitioned_network, Node}</c>
+ system event and acts as described in the previous item.
+ </item>
+ </list>
<p>If the application detects that there has been a communication
- failure which may have caused an inconsistent database, it may
- use the function <c>mnesia:set_master_nodes(Tab, Nodes)</c> to
- pinpoint from which nodes each table may be loaded.</p>
- <p>At start-up Mnesia's normal table load algorithm will be
- bypassed and the table will be loaded from one of the master
+ failure that can have caused an inconsistent database, it can
+ use the function
+ <seealso marker="mnesia#set_master_nodes/2">mnesia:set_master_nodes(Tab, Nodes)</seealso>
+ to pinpoint from which nodes each table can be loaded.</p>
+ <p>At startup, the <c>Mnesia</c> normal table load algorithm is
+ bypassed and the table is loaded from one of the master
nodes defined for the table, regardless of potential
- <c>mnesia_down</c> entries in the log. The <c>Nodes</c> may only
- contain nodes where the table has a replica and if it is empty,
- the master node recovery mechanism for the particular table will
- be reset and the normal load mechanism will be used when next
- restarting.
- </p>
- <p>The function <c>mnesia:set_master_nodes(Nodes)</c> sets master
- nodes for all tables. For each table it will determine its
- replica nodes and invoke <c>mnesia:set_master_nodes(Tab, TabNodes)</c> with those replica nodes that are included in the
- <c>Nodes</c> list (i.e. <c>TabNodes</c> is the intersection of
+ <c>mnesia_down</c> entries in the log. <c>Nodes</c> can only
+ contain nodes where the table has a replica. If <c>Nodes</c>
+ is empty, the master node recovery mechanism for the particular
+ table is reset and the normal load mechanism is used at the
+ next restart.</p>
+ <p>The function
+ <seealso marker="mnesia#set_master_nodes/1">mnesia:set_master_nodes(Nodes)</seealso>
+ sets master
+ nodes for all tables. For each table it determines its replica
+ nodes and starts
+ <seealso marker="mnesia#set_master_nodes/2">mnesia:set_master_nodes(Tab, TabNodes)</seealso>
+ with those replica nodes that are included in the <c>Nodes</c>
+ list (that is, <c>TabNodes</c> is the intersection of
<c>Nodes</c> and the replica nodes of the table). If the
- intersection is empty the master node recovery mechanism for the
- particular table will be reset and the normal load mechanism
- will be used at next restart.
- </p>
- <p>The functions <c>mnesia:system_info(master_node_tables)</c> and
- <c>mnesia:table_info(Tab, master_nodes)</c> may be used to
- obtain information about the potential master nodes.
- </p>
- <p>Determining which data to keep after communication failure is outside
- the scope of Mnesia. One approach would be to determine which "island"
- contains a majority of the nodes. Using the <c>{majority,true}</c> option
- for critical tables can be a way of ensuring that nodes that are not part
- of a "majority island" are not able to update those tables. Note that this
- constitutes a reduction in service on the minority nodes. This would be
- a tradeoff in favour of higher consistency guarantees.</p>
- <p>The function <c>mnesia:force_load_table(Tab)</c> may be used to
- force load the table regardless of which table load mechanism
- is activated.
- </p>
+ intersection is empty, the master node recovery mechanism for
+ the particular table is reset and the normal load mechanism
+ is used at the next restart.</p>
+ <p>The functions
+ <seealso marker="mnesia#system_info/1">mnesia:system_info(master_node_tables)</seealso>
+ and
+ <seealso marker="mnesia#table_info/2">mnesia:table_info(Tab, master_nodes)</seealso>
+ can be used to
+ obtain information about the potential master nodes.</p>
+ <p>Determining what data to keep after a communication failure
+ is outside the scope of <c>Mnesia</c>. One approach is to
+ determine which "island" contains most of the nodes. Using
+ option <c>{majority,true}</c> for critical tables can be a way
+ to ensure that nodes that are not part of a "majority island"
+ cannot update those tables. Notice that this constitutes a
+ reduction in service on the minority nodes. This would be a
+ tradeoff in favor of higher consistency guarantees.</p>
+ <p>The function
+ <seealso marker="mnesia#force_load_table/1">mnesia:force_load_table(Tab)</seealso>
+ can be used to force load the table regardless of which table
+ load mechanism that is activated.</p>
</section>
<section>
<title>Recovery of Transactions</title>
- <p>A Mnesia table may reside on one or more nodes. When a table is
- updated, Mnesia will ensure that the updates will be replicated
- to all nodes where the table resides. If a replica happens to be
- inaccessible for some reason (e.g. due to a temporary node down),
- Mnesia will then perform the replication later.
- </p>
- <p>On the node where the application is started, there will be a
+ <p>A <c>Mnesia</c> table can reside on one or more nodes. When a
+ table is updated, <c>Mnesia</c> ensures that the updates are
+ replicated to all nodes where the table resides. If a replica is
+ inaccessible (for example, because of a temporary node-down),
+ <c>Mnesia</c> performs the replication later.</p>
+ <p>On the node where the application is started, there is a
transaction coordinator process. If the transaction is
- distributed, there will also be a transaction participant process on
- all the other nodes where commit work needs to be performed.
- </p>
- <p>Internally Mnesia uses several commit protocols. The selected
- protocol depends on which table that has been updated in
- the transaction. If all the involved tables are symmetrically
- replicated, (i.e. they all have the same <c>ram_nodes</c>,
- <c>disc_nodes</c> and <c>disc_only_nodes</c> currently
+ distributed, there is also a transaction participant process on
+ all the other nodes where commit-work needs to be performed.</p>
+ <p>Internally <c>Mnesia</c> uses several commit protocols. The
+ selected protocol depends on which table that has been updated
+ in the transaction. If all the involved tables are symmetrically
+ replicated (that is, they all have the same <c>ram_nodes</c>,
+ <c>disc_nodes</c>, and <c>disc_only_nodes</c> currently
accessible from the coordinator node), a lightweight transaction
- commit protocol is used.
- </p>
+ commit protocol is used.</p>
<p>The number of messages that the
- transaction coordinator and its participants needs to exchange
- is few, since Mnesia's table load mechanism takes care of the
- transaction recovery if the commit protocol gets
+ transaction coordinator and its participants need to exchange
+ is few, as the <c>Mnesia</c> table load mechanism takes care of
+ the transaction recovery if the commit protocol gets
interrupted. Since all involved tables are replicated
- symmetrically the transaction will automatically be recovered by
- loading the involved tables from the same node at start-up of a
- failing node. We do not really care if the transaction was
- aborted or committed as long as we can ensure the ACID
- properties. The lightweight commit protocol is non-blocking,
- i.e. the surviving participants and their coordinator will
- finish the transaction, regardless of some node crashes in the
- middle of the commit protocol or not.
- </p>
- <p>If a node goes down in the middle of a dirty operation the
- table load mechanism will ensure that the update will be
- performed on all replicas or none. Both asynchronous dirty
+ symmetrically, the transaction is automatically recovered by
+ loading the involved tables from the same node at startup of a
+ failing node. It does not matter if the transaction was
+ committed or terminated as long as the ACID properties can be
+ ensured. The lightweight commit protocol is non-blocking,
+ that is, the surviving participants and their coordinator
+ finish the transaction, even if any node crashes in the
+ middle of the commit protocol.</p>
+ <p>If a node goes down in the middle of a dirty operation, the
+ table load mechanism ensures that the update is
+ performed on all replicas, or none. Both asynchronous dirty
updates and synchronous dirty updates use the same recovery
- principle as lightweight transactions.
- </p>
+ principle as lightweight transactions.</p>
<p>If a transaction involves updates of asymmetrically replicated
tables or updates of the schema table, a heavyweight commit
- protocol will be used. The heavyweight commit protocol is able
- to finish the transaction regardless of how the tables are
- replicated. The typical usage of a heavyweight transaction is
- when we want to move a replica from one node to another. Then we
- must ensure that the replica either is entirely moved or left as
- it was. We must never end up in a situation with replicas on both
- nodes or no node at all. Even if a node crashes in the middle of
- the commit protocol, the transaction must be guaranteed to be
+ protocol is used. This protocol can
+ finish the transaction regardless of how the tables are
+ replicated. The typical use of a heavyweight transaction is
+ when a replica is to be moved from one node to another. Then
+ ensure that the replica either is entirely moved or left as
+ it was. Do never end up in a situation with replicas on both
+ nodes, or on no node at all. Even if a node crashes in the middle
+ of the commit protocol, the transaction must be guaranteed to be
atomic. The heavyweight commit protocol involves more messages
between the transaction coordinator and its participants than
- a lightweight protocol and it will perform recovery work at
- start-up in order to finish the abort or commit work.
- </p>
+ a lightweight protocol, and it performs recovery work at
+ startup to finish the terminating or commit work.</p>
<p>The heavyweight commit protocol is also non-blocking,
which allows the surviving participants and their coordinator to
finish the transaction regardless (even if a node crashes in the
- middle of the commit protocol). When a node fails at start-up,
- Mnesia will determine the outcome of the transaction and
- recover it. Lightweight protocols, heavyweight protocols and dirty updates, are
- dependent on other nodes to be up and running in order to make the
- correct heavyweight transaction recovery decision.
- </p>
- <p>If Mnesia has not started on some of the nodes that are involved in the
- transaction AND neither the local node or any of the already
- running nodes know the outcome of the transaction, Mnesia will
- by default wait for one. In the worst case scenario all other
- involved nodes must start before Mnesia can make the correct decision
- about the transaction and finish its start-up.
- </p>
- <p>This means that Mnesia (on one node)may hang if a double fault occurs, i.e. when two nodes crash simultaneously
- and one attempts to start when the other refuses to
- start e.g. due to a hardware error.
- </p>
- <p>It is possible to specify the maximum time that Mnesia
- will wait for other nodes to respond with a transaction
- recovery decision. The configuration parameter
- <c>max_wait_for_decision</c> defaults to infinity (which may
- cause the indefinite hanging as mentioned above) but if it is
- set to a definite time period (eg.three minutes), Mnesia will then enforce a
- transaction recovery decision if needed, in order to allow
- Mnesia to continue with its start-up procedure. </p>
- <p>The downside of an enforced transaction recovery decision, is that the decision may be
- incorrect, due to insufficient information regarding the other nodes'
- recovery decisions. This may result in an
- inconsistent database where Mnesia has committed the transaction
- on some nodes but aborted it on others. </p>
- <p>In fortunate cases the inconsistency will only appear in tables belonging to a specific
- application, but if a schema transaction has been inconsistently
- recovered due to the enforced transaction recovery decision, the
- effects of the inconsistency can be fatal.
+ middle of the commit protocol). When a node fails at startup,
+ <c>Mnesia</c> determines the outcome of the transaction and
+ recovers it. Lightweight protocols, heavyweight protocols, and
+ dirty updates, are dependent on other nodes to be operational
+ to make the correct heavyweight transaction recovery decision.</p>
+ <p>If <c>Mnesia</c> has not started on some of the nodes that
+ are involved in the transaction <em>and</em> neither the
+ local node nor any of the already running nodes know the
+ outcome of the transaction, <c>Mnesia</c> waits for one,
+ by default. In the worst case scenario, all other involved
+ nodes must start before <c>Mnesia</c> can make the correct
+ decision about the transaction and finish its startup.</p>
+ <p>Thus, <c>Mnesia</c> (on one node) can hang if a double fault
+ occurs, that is, when two nodes crash simultaneously
+ and one attempts to start when the other refuses to
+ start, for example, because of a hardware error.</p>
+ <p>The maximum time that <c>Mnesia</c> waits for other nodes to
+ respond with a transaction recovery decision can be specified.
+ The configuration parameter <c>max_wait_for_decision</c>
+ defaults to <c>infinity</c>, which can cause the indefinite
+ hanging as mentioned earlier. However, if the parameter is
+ set to a definite time period (for example, three minutes),
+ <c>Mnesia</c> then enforces a transaction recovery decision,
+ if needed, to allow <c>Mnesia</c> to continue with its startup
+ procedure.</p>
+ <p>The downside of an enforced transaction recovery decision is
+ that the decision can be incorrect, because of insufficient
+ information about the recovery decisions from the other nodes.
+ This can result in an inconsistent database where <c>Mnesia</c>
+ has committed the transaction on some nodes but terminated it
+ on others.</p>
+ <p>In fortunate cases, the inconsistency is only visible in
+ tables belonging to a specific application. However, if a
+ schema transaction is inconsistently recovered because of
+ the enforced transaction recovery decision, the
+ effects of the inconsistency can be fatal.
However, if the higher priority is availability rather than
- consistency, then it may be worth the risk. </p>
- <p>If Mnesia
- encounters a inconsistent transaction decision a
- <c>{inconsistent_database, bad_decision, Node}</c> system event
- will be generated in order to give the application a chance to
- install a fallback or other appropriate measures to resolve the inconsistency. The default
- behavior of the Mnesia event handler is the same as if the
- database became inconsistent as a result of partitioned network (see
- above).
- </p>
+ consistency, it can be worth the risk.</p>
+ <p>If <c>Mnesia</c> detects an inconsistent transaction decision,
+ an <c>{inconsistent_database, bad_decision, Node}</c> system event
+ is generated to give the application a chance to install a
+ fallback or other appropriate measures to resolve the
+ inconsistency. The default behavior of the <c>Mnesia</c>
+ event handler is the same as if the database became
+ inconsistent as a result of partitioned network (as
+ described earlier).</p>
</section>
<section>
- <title>Backup, Fallback, and Disaster Recovery</title>
- <p>The following functions are used to backup data, to install a
- backup as fallback, and for disaster recovery.
- </p>
+ <title>Backup, Restore, Fallback, and Disaster Recovery</title>
+ <p>The following functions are used to back up data, to install
+ a backup as fallback, and for disaster recovery:</p>
<list type="bulleted">
- <item><c>mnesia:backup_checkpoint(Name, Opaque, [Mod])</c>. This
- function performs a backup of the tables included in the
- checkpoint.
+ <item>
+ <seealso marker="mnesia#backup_checkpoint/2">mnesia:backup_checkpoint(Name, Opaque, [Mod])</seealso>
+ performs a backup of the tables included in the checkpoint.
</item>
- <item><c>mnesia:backup(Opaque, [Mod])</c>. This function
- activates a new checkpoint which covers all Mnesia tables and
+ <item>
+ <seealso marker="mnesia#backup/1">mnesia:backup(Opaque, [Mod])</seealso>
+ activates a new
+ checkpoint that covers all <c>Mnesia</c> tables and
performs a backup. It is performed with maximum degree of
- redundancy (also refer to the function <seealso marker="#checkpoints">mnesia:activate_checkpoint(Args)</seealso>,
- <c>{max, MaxTabs} and {min, MinTabs}).</c></item>
- <item><c>mnesia:traverse_backup(Source,[SourceMod,]</c><c>Target,[TargetMod,]Fun,Ac)</c>. This function can be used
- to read an existing backup, create a new backup from an
- existing one, or to copy a backup from one type media to
- another.
+ redundancy (see also the function
+ <seealso marker="#checkpoints">mnesia:activate_checkpoint(Args)</seealso>,
+ <c>{max, MaxTabs} and {min, MinTabs})</c>.
</item>
- <item><c>mnesia:uninstall_fallback()</c>. This function removes
- previously installed fallback files.
+ <item>
+ <seealso marker="mnesia#traverse_backup/4">mnesia:traverse_backup(Source, [SourceMod,] Target, [TargetMod,] Fun, Acc)</seealso>
+ can be used to read an existing backup, create a backup from an
+ existing one, or to copy a backup from one type media to another.
</item>
- <item><c>mnesia:restore(Opaque, Args)</c>. This function
+ <item>
+ <seealso marker="mnesia#uninstall_fallback/0">mnesia:uninstall_fallback()</seealso>
+ removes previously installed fallback files.
+ </item>
+ <item>
+ <seealso marker="mnesia#restore/2">mnesia:restore(Opaque, Args)</seealso>
restores a set of tables from a previous backup.
</item>
- <item><c>mnesia:install_fallback(Opaque, [Mod])</c>. This
- function can be configured to restart the Mnesia and reload data
- tables, and possibly schema tables, from an existing
+ <item>
+ <seealso marker="mnesia#install_fallback/1">mnesia:install_fallback(Opaque, [Mod])</seealso>
+ can be configured to restart <c>Mnesia</c> and the reload data
+ tables, and possibly the schema tables, from an existing
backup. This function is typically used for disaster recovery
- purposes, when data or schema tables are corrupted.</item>
+ purposes, when data or schema tables are corrupted.
+ </item>
</list>
- <p>These functions are explained in the following
- sub-sections. Also refer to the the section <seealso marker="#checkpoints">Checkpoints</seealso> in this chapter, which
- describes the two functions used to activate and de-activate
- checkpoints.
- </p>
+ <p>These functions are explained in the following sections.
+ See also <seealso marker="#checkpoints">Checkpoints</seealso>,
+ which describes the two functions used
+ to activate and deactivate checkpoints.</p>
<section>
<title>Backup</title>
- <p>Backup operation are performed with the following functions:
- </p>
+ <p>Backup operation are performed with the following functions:</p>
<list type="bulleted">
- <item><c>mnesia:backup_checkpoint(Name, Opaque, [Mod])</c></item>
- <item><c>mnesia:backup(Opaque, [Mod])</c></item>
- <item><c>mnesia:traverse_backup(Source, [SourceMod,],</c><c>Target,[TargetMod,]Fun,Acc)</c>.</item>
+ <item>
+ <seealso marker="mnesia#backup_checkpoint/2">mnesia:backup_checkpoint(Name, Opaque, [Mod])</seealso>
+ </item>
+ <item>
+ <seealso marker="mnesia#backup/1">mnesia:backup(Opaque, [Mod])</seealso>
+ </item>
+ <item>
+ <seealso marker="mnesia#traverse_backup/4">mnesia:traverse_backup(Source, [SourceMod,] Target, [TargetMod,] Fun, Acc)</seealso>
+ </item>
</list>
<p>By default, the actual access to the backup media is
- performed via the <c>mnesia_backup</c> module for both read
+ performed through module <c>mnesia_backup</c> for both read
and write. Currently <c>mnesia_backup</c> is implemented with
- the standard library module <c>disc_log</c>, but it is possible to write
- your own module with the same interface as
- <c>mnesia_backup</c> and configure Mnesia so the alternate
- module performs the actual accesses to the backup media. This
- means that the user may put the backup on medias that Mnesia
+ the standard library module <c>disc_log</c>. However, you
+ can write your own module with the same interface as
+ <c>mnesia_backup</c> and configure <c>Mnesia</c> so that
+ the alternative module performs the actual accesses to
+ the backup media. The user can
+ therefore put the backup on a media that <c>Mnesia</c>
does not know about, possibly on hosts where Erlang is not
- running. Use the configuration parameter <c><![CDATA[-mnesia backup_module <module>]]></c> for this purpose. </p>
- <p>The source
- for a backup is an activated checkpoint. The backup function
- most commonly used is <c>mnesia:backup_checkpoint(Name, Opaque,[Mod])</c>. This function returns either <c>ok</c>, or
- <c>{error,Reason}</c>. It has the following arguments:
- </p>
+ running. Use configuration parameter
+ <c><![CDATA[-mnesia backup_module <module>]]></c>
+ for this purpose.</p>
+ <p>The source for a backup is an activated checkpoint.
+ The backup function
+ <seealso marker="mnesia#backup_checkpoint/2">mnesia:backup_checkpoint(Name, Opaque,[Mod])</seealso>
+ is most commonly used and returns <c>ok</c> or
+ <c>{error,Reason}</c>. It has the following arguments:</p>
<list type="bulleted">
- <item><c>Name</c> is the name of an activated
- checkpoint. Refer to the section <seealso marker="#checkpoints">Checkpoints</seealso> in this chapter, the
- function <c>mnesia:activate_checkpoint(ArgList)</c> for
- details on how to include table names in checkpoints.
+ <item><c>Name</c> is the name of an activated checkpoint.
+ For details on how to include table names in checkpoints,
+ see the function <c>mnesia:activate_checkpoint(ArgList)</c>
+ in <seealso marker="#checkpoints">Checkpoints</seealso>.
</item>
- <item><c>Opaque</c>. Mnesia does not interpret this argument,
- but it is forwarded to the backup module. The Mnesia default
- backup module, <c>mnesia_backup</c> interprets this argument
- as a local file name.
+ <item><c>Opaque</c>. <c>Mnesia</c> does not interpret this
+ argument, but it is forwarded to the backup module. The
+ <c>Mnesia</c> default backup module <c>mnesia_backup</c>
+ interprets this argument as a local filename.
</item>
- <item><c>Mod</c>. The name of an alternate backup module.
+ <item><c>Mod</c> is the name of an alternative backup module.
</item>
</list>
- <p>The function <c>mnesia:backup(Opaque[, Mod])</c> activates a
- new checkpoint which covers all Mnesia tables with maximum
- degree of redundancy and performs a backup. Maximum
+ <p>The function
+ <seealso marker="mnesia#backup/1">mnesia:backup(Opaque [,Mod])</seealso>
+ activates a
+ new checkpoint that covers all <c>Mnesia</c> tables with
+ maximum degree of redundancy and performs a backup. Maximum
redundancy means that each table replica has a checkpoint
- retainer. Tables with the <c>local_contents</c> property are
- backed up as they
- look on the current node.
- </p>
- <p>It is possible to iterate over a backup, either for the
- purpose of transforming it into a new backup, or just reading
- it. The function <c>mnesia:traverse_backup(Source, [SourceMod,]</c><c>Target, [TargeMod,] Fun, Acc)</c> which normally returns <c>{ok, LastAcc}</c>, is used for both of these purposes.
- </p>
+ retainer. Tables with property <c>local_contents</c> are
+ backed up as they look on the current node.</p>
+ <p>You can iterate over a backup, either to transform it
+ into a new backup, or only read it. The function
+ <seealso marker="mnesia#traverse_backup/4">mnesia:traverse_backup(Source, [SourceMod,] Target, [TargetMod,] Fun, Acc)</seealso>,
+ which normally returns <c>{ok, LastAcc}</c>,
+ is used for both of these purposes.</p>
<p>Before the traversal starts, the source backup media is
opened with <c>SourceMod:open_read(Source)</c>, and the target
backup media is opened with
- <c>TargetMod:open_write(Target)</c>. The arguments are:
- </p>
+ <c>TargetMod:open_write(Target)</c>. The arguments are as
+ follows:</p>
<list type="bulleted">
<item><c>SourceMod</c> and <c>TargetMod</c> are module names.
</item>
<item><c>Source</c> and <c>Target</c> are opaque data used
exclusively by the modules <c>SourceMod</c> and
- <c>TargetMod</c> for the purpose of initializing the backup
- medias.
+ <c>TargetMod</c> for initializing the backup medias.
</item>
<item><c>Acc</c> is an initial accumulator value.
</item>
<item><c>Fun(BackupItems, Acc)</c> is applied to each item in
- the backup. The Fun must return a tuple <c>{ValGoodBackupItems, NewAcc}</c>, where <c>ValidBackupItems</c> is a list of valid
- backup items, and <c>NewAcc</c> is a new accumulator value.
+ the backup. The Fun must return a tuple
+ <c>{ValGoodBackupItems, NewAcc}</c>,
+ where <c>ValidBackupItems</c> is a list of valid
+ backup items. <c>NewAcc</c> is a new accumulator value.
The <c>ValidBackupItems</c> are written to the target backup
with the function <c>TargetMod:write/2</c>.
</item>
- <item><c>LastAcc</c> is the last accumulator value. I.e.
+ <item><c>LastAcc</c> is the last accumulator value, that is,
the last <c>NewAcc</c> value that was returned by <c>Fun</c>.
</item>
</list>
- <p>It is also possible to perform a read-only traversal of the
- source backup without updating a target backup. If
- <c>TargetMod==read_only</c>, then no target backup is accessed
- at all.
- </p>
+ <p>Also, a read-only traversal of the source backup can be
+ performed without updating a target backup. If
+ <c>TargetMod==read_only</c>, no target backup is accessed.</p>
<p>By setting <c>SourceMod</c> and <c>TargetMod</c> to different
- modules it is possible to copy a backup from one kind of backup
- media to another.
- </p>
- <p>Valid <c>BackupItems</c> are the following tuples:
- </p>
+ modules, a backup can be copied from one backup
+ media to another.</p>
+ <p>Valid <c>BackupItems</c> are the following tuples:</p>
<list type="bulleted">
<item><c>{schema, Tab}</c> specifies a table to be deleted.
</item>
<item><c>{schema, Tab, CreateList}</c> specifies a table to be
- created. See <c>mnesia_create_table/2</c> for more
- information about <c>CreateList</c>.
+ created. For more information about <c>CreateList</c>, see
+ <seealso marker="mnesia#create_table/2">mnesia:create_table/2</seealso>.
</item>
<item><c>{Tab, Key}</c> specifies the full identity of a record
- to be deleted.
+ to be deleted.
</item>
<item><c>{Record}</c> specifies a record to be inserted. It
- can be a tuple with <c>Tab</c> as first field. Note that the
+ can be a tuple with <c>Tab</c> as first field. Notice that the
record name is set to the table name regardless of what
- <c>record_name</c> is set to.
+ <c>record_name</c> is set to.
</item>
</list>
<p>The backup data is divided into two sections. The first
- section contains information related to the schema. All schema
- related items are tuples where the first field equals the atom
- schema. The second section is the record section. It is not
- possible to mix schema records with other records and all schema
- records must be located first in the backup.
- </p>
- <p>The schema itself is a table and will possibly be included in
- the backup. All nodes where the schema table resides are
- regarded as a <c>db_node</c>.
- </p>
- <p>The following example illustrates how
- <c>mnesia:traverse_backup</c> can be used to rename a db_node in
- a backup file:
- </p>
+ section contains information related to the schema. All
+ schema-related items are tuples where the first field equals
+ the atom schema. The second section is the record section.
+ Schema records cannot be mixed with other records and all
+ schema records must be located first in the backup.</p>
+ <p>The schema itself is a table and is possibly included in
+ the backup. Each node where the schema table resides is
+ regarded as a <c>db_node</c>.</p>
+ <p>The following example shows how
+ <seealso marker="mnesia#traverse_backup/4">mnesia:traverse_backup</seealso>
+ can be used to rename a <c>db_node</c> in a backup file:</p>
<codeinclude file="bup.erl" tag="%0" type="erl"></codeinclude>
</section>
<section>
<title>Restore</title>
- <p>Tables can be restored on-line from a backup without
- restarting Mnesia. A restore is performed with the function
- <c>mnesia:restore(Opaque,Args)</c>, where <c>Args</c> can
- contain the following tuples:
- </p>
+ <p>Tables can be restored online from a backup without
+ restarting <c>Mnesia</c>. A restore is performed with the
+ function
+ <seealso marker="mnesia#restore/2">mnesia:restore(Opaque, Args)</seealso>,
+ where <c>Args</c> can contain the following tuples:</p>
<list type="bulleted">
<item><c>{module,Mod}</c>. The backup module <c>Mod</c> is
used to access the backup media. If omitted, the default
- backup module will be used.</item>
- <item><c>{skip_tables, TableList}</c> Where <c>TableList</c>
- is a list of tables which should not be read from the backup.</item>
- <item><c>{clear_tables, TableList}</c> Where <c>TableList</c>
- is a list of tables which should be cleared, before the
- records from the backup are inserted, i.e. all records in
+ backup module is used.
+ </item>
+ <item><c>{skip_tables, TableList}</c>, where <c>TableList</c>
+ is a list of tables, which is not to be read from the backup.
+ </item>
+ <item><c>{clear_tables, TableList}</c>, where <c>TableList</c>
+ is a list of tables, which is to be cleared before the
+ records from the backup are inserted. That is, all records in
the tables are deleted before the tables are restored.
Schema information about the tables is not cleared or read
- from backup.</item>
- <item><c>{keep_tables, TableList}</c> Where <c>TableList</c>
- is a list of tables which should be not be cleared, before
- the records from the backup are inserted, i.e. the records
- in the backup will be added to the records in the table.
+ from the backup.
+ </item>
+ <item><c>{keep_tables, TableList}</c>, where <c>TableList</c>
+ is a list of tables, which is not to be cleared before
+ the records from the backup are inserted. That is, the records
+ in the backup are added to the records in the table.
Schema information about the tables is not cleared or read
- from backup.</item>
- <item><c>{recreate_tables, TableList}</c> Where <c>TableList</c>
- is a list of tables which should be re-created, before the
- records from the backup are inserted. The tables are first
- deleted and then created with the schema information from the
- backup. All the nodes in the backup needs to be up and running.</item>
- <item><c>{default_op, Operation}</c> Where <c>Operation</c> is
- one of the following operations <c>skip_tables</c>,
- <c>clear_tables</c>, <c>keep_tables</c> or
- <c>recreate_tables</c>. The default operation specifies
- which operation should be used on tables from the backup
- which are not specified in any of the lists above.
- If omitted, the operation <c>clear_tables</c> will be used. </item>
+ from the backup.
+ </item>
+ <item><c>{recreate_tables, TableList}</c>, where <c>TableList</c>
+ is a list of tables, which is to be recreated before the
+ records from the backup are inserted. The tables are first
+ deleted and then created with the schema information from the
+ backup. All the nodes in the backup need to be operational.
+ </item>
+ <item><c>{default_op, Operation}</c>, where <c>Operation</c> is
+ one of the operations <c>skip_tables</c>,
+ <c>clear_tables</c>, <c>keep_tables</c>, or
+ <c>recreate_tables</c>. The default operation specifies
+ which operation is to be used on tables from the backup
+ that are not specified in any of the previous lists.
+ If omitted, the operation <c>clear_tables</c> is used.
+ </item>
</list>
<p>The argument <c>Opaque</c> is forwarded to the backup module.
It returns <c>{atomic, TabList}</c> if successful, or the
- tuple <c>{aborted, Reason}</c> in the case of an error.
- <c>TabList</c> is a list of the restored tables. Tables which
- are restored are write locked for the duration of the restore
- operation. However, regardless of any lock conflict caused by
+ tuple <c>{aborted, Reason}</c> if there is an error.
+ <c>TabList</c> is a list of the restored tables. Tables that
+ are restored are write-locked during the restore
+ operation. However, regardless of any lock conflict caused by
this, applications can continue to do their work during the
- restore operation.
- </p>
+ restore operation.</p>
<p>The restoration is performed as a single transaction. If the
- database is very large, it may not be possible to restore it
- online. In such a case the old database must be restored by
- installing a fallback, and then restart.
- </p>
+ database is large, it cannot always be restored
+ online. The old database must then be restored by
+ installing a fallback, followed by a restart.</p>
</section>
<section>
- <title>Fallbacks</title>
- <p>The function <c>mnesia:install_fallback(Opaque, [Mod])</c> is
- used to install a backup as fallback. It uses the backup module
+ <title>Fallback</title>
+ <p>The function
+ <seealso marker="mnesia#install_fallback/2">mnesia:install_fallback(Opaque, [Mod])</seealso>
+ installs a backup as fallback. It uses the backup module
<c>Mod</c>, or the default backup module, to access the backup
- media. This function returns <c>ok</c> if successful, or
- <c>{error, Reason}</c> in the case of an error.
- </p>
- <p>Installing a fallback is a distributed operation that is
+ media. The function returns <c>ok</c> if successful, or
+ <c>{error, Reason}</c> if there is an error.</p>
+ <p>Installing a fallback is a distributed operation, which is
<em>only</em> performed on all <c>db_nodes</c>. The fallback
- is used to restore the database the next time the system is
- started. If a Mnesia node with a fallback installed detects that
- Mnesia on another node has died for some reason, it will
- unconditionally terminate itself.
- </p>
+ restores the database the next time the system is started.
+ If a <c>Mnesia</c> node with a fallback installed detects that
+ <c>Mnesia</c> on another node has died, it
+ unconditionally terminates itself.</p>
<p>A fallback is typically used when a system upgrade is
performed. A system typically involves the installation of new
- software versions, and Mnesia tables are often transformed into
- new layouts. If the system crashes during an upgrade, it is
- highly probable re-installation of the old
- applications will be required and restoration of the database
- to its previous state. This can be done if a backup is performed and
- installed as a fallback before the system upgrade begins.
- </p>
- <p>If the system upgrade fails, Mnesia must be restarted on all
- <c>db_nodes</c> in order to restore the old database. The
- fallback will be automatically de-installed after a successful
- start-up. The function <c>mnesia:uninstall_fallback()</c> may
- also be used to de-install the fallback after a
+ software versions, and <c>Mnesia</c> tables are often transformed
+ into new layouts. If the system crashes during an upgrade, it is
+ highly probable that reinstallation of the old applications is
+ required, and restoration of the database to its previous state.
+ This can be done if a backup is performed and
+ installed as a fallback before the system upgrade begins.</p>
+ <p>If the system upgrade fails, <c>Mnesia</c> must be restarted
+ on all <c>db_nodes</c> to restore the old database. The
+ fallback is automatically deinstalled after a successful
+ startup. The function
+ <seealso marker="mnesia#uninstall_fallback/0">mnesia:uninstall_fallback()</seealso>
+ can also be used to deinstall the fallback after a
successful system upgrade. Again, this is a distributed
- operation that is either performed on all <c>db_nodes</c>, or
- none. Both the installation and de-installation of fallbacks
- require Erlang to be up and running on all <c>db_nodes</c>, but
- it does not matter if Mnesia is running or not.
- </p>
+ operation that is either performed on all <c>db_nodes</c> or
+ none. Both the installation and deinstallation of fallbacks
+ require Erlang to be operational on all <c>db_nodes</c>, but
+ it does not matter if <c>Mnesia</c> is running or not.</p>
</section>
<section>
<title>Disaster Recovery</title>
- <p>The system may become inconsistent as a result of a power
- failure. The UNIX <c>fsck</c> feature can possibly repair the
- file system, but there is no guarantee that the file contents
- will be consistent.
- </p>
- <p>If Mnesia detects that a file has not been properly closed,
- possibly as a result of a power failure, it will attempt to
- repair the bad file in a similar manner. Data may be lost, but
- Mnesia can be restarted even if the data is inconsistent. The
- configuration parameter <c><![CDATA[-mnesia auto_repair <bool>]]></c> can be
- used to control the behavior of Mnesia at start-up. If
- <c><![CDATA[<bool>]]></c> has the value <c>true</c>, Mnesia will attempt to
- repair the file; if <c><![CDATA[<bool>]]></c> has the value <c>false</c>,
- Mnesia will not restart if it detects a suspect file. This
- configuration parameter affects the repair behavior of log
- files, DAT files, and the default backup media.
- </p>
- <p>The configuration parameter <c><![CDATA[-mnesia dump_log_update_in_place <bool>]]></c> controls the safety level of
- the <c>mnesia:dump_log()</c> function. By default, Mnesia will
- dump the transaction log directly into the DAT files. If a power
- failure happens during the dump, this may cause the randomly
- accessed DAT files to become corrupt. If the parameter is set to
- <c>false</c>, Mnesia will copy the DAT files and target the dump
+ <p>The system can become inconsistent as a result of a power
+ failure. The UNIX feature <c>fsck</c> can possibly repair the
+ file system, but there is no guarantee that the file content
+ is consistent.</p>
+ <p>If <c>Mnesia</c> detects that a file has not been properly
+ closed, possibly as a result of a power failure, it tries to
+ repair the bad file in a similar manner. Data can be lost, but
+ <c>Mnesia</c> can be restarted even if the data is inconsistent.
+ Configuration parameter
+ <c><![CDATA[-mnesia auto_repair <bool>]]></c> can be used
+ to control the behavior of <c>Mnesia</c> at startup. If
+ <c><![CDATA[<bool>]]></c> has the value <c>true</c>,
+ <c>Mnesia</c> tries to repair the file. If
+ <c><![CDATA[<bool>]]></c> has the value <c>false</c>,
+ <c>Mnesia</c> does not restart if it detects a suspect file.
+ This configuration parameter affects the repair behavior of log
+ files, <c>DAT</c> files, and the default backup media.</p>
+ <p>Configuration parameter
+ <c><![CDATA[-mnesia dump_log_update_in_place <bool>]]></c>
+ controls the safety level of the function
+ <seealso marker="mnesia#dump_log/0">mnesia:dump_log()</seealso>
+ By default, <c>Mnesia</c> dumps the
+ transaction log directly into the <c>DAT</c> files. If a power
+ failure occurs during the dump, this can cause the randomly
+ accessed <c>DAT</c> files to become corrupt. If the parameter
+ is set to <c>false</c>, <c>Mnesia</c> copies the <c>DAT</c>
+ files and target the dump
to the new temporary files. If the dump is successful, the
- temporary files will be renamed to their normal DAT
+ temporary files are renamed to their normal <c>DAT</c>
suffixes. The possibility for unrecoverable inconsistencies in
- the data files will be much smaller with this strategy. On the
- other hand, the actual dumping of the transaction log will be
+ the data files becomes much smaller with this strategy.
+ However, the actual dumping of the transaction log becomes
considerably slower. The system designer must decide whether
- speed or safety is the higher priority.
- </p>
- <p>Replicas of type <c>disc_only_copies</c> will only be
+ speed or safety is the higher priority.</p>
+ <p>Replicas of type <c>disc_only_copies</c> are only
affected by this parameter during the initial dump of the log
- file at start-up. When designing applications which have
- <em>very</em> high requirements, it may be appropriate not to
+ file at startup. When designing applications with
+ <em>very</em> high requirements, it can be appropriate not to
use <c>disc_only_copies</c> tables at all. The reason for this
is the random access nature of normal operating system files. If
- a node goes down for reason for a reason such as a power
- failure, these files may be corrupted because they are not
- properly closed. The DAT files for <c>disc_only_copies</c> are
- updated on a per transaction basis.
- </p>
- <p>If a disaster occurs and the Mnesia database has been
- corrupted, it can be reconstructed from a backup. This should be
- regarded as a last resort, since the backup contains old data. The
- data is hopefully consistent, but data will definitely be lost
- when an old backup is used to restore the database.
- </p>
+ a node goes down for a reason such as a power
+ failure, these files can be corrupted because they are not
+ properly closed. The <c>DAT</c> files for <c>disc_only_copies</c>
+ are updated on a per transaction basis.</p>
+ <p>If a disaster occurs and the <c>Mnesia</c> database is
+ corrupted, it can be reconstructed from a backup. Regard
+ this as a last resort, as the backup contains old data. The
+ data is hopefully consistent, but data is definitely lost
+ when an old backup is used to restore the database.</p>
</section>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_chap8.xml b/lib/mnesia/doc/src/Mnesia_chap8.xml
index d35dd0c539..8a4ed8a23d 100644
--- a/lib/mnesia/doc/src/Mnesia_chap8.xml
+++ b/lib/mnesia/doc/src/Mnesia_chap8.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Combining Mnesia with SNMP</title>
+ <title>Combine Mnesia with SNMP</title>
<prepared>Claes Wikstr&ouml;m, Hans Nilsson and H&aring;kan Mattsson</prepared>
<responsible></responsible>
<docno></docno>
@@ -33,32 +34,29 @@
</header>
<section>
- <title>Combining Mnesia and SNMP </title>
+ <title>Combine Mnesia and SNMP</title>
<p>Many telecommunications applications must be controlled and
reconfigured remotely. It is sometimes an advantage to perform
this remote control with an open protocol such as the Simple
Network Management Protocol (SNMP). The alternatives to this would
- be:
- </p>
+ be the following:</p>
<list type="bulleted">
- <item>Not being able to control the application remotely at all.
+ <item>Not being able to control the application remotely
</item>
- <item>Using a proprietary control protocol.
+ <item>Using a proprietary control protocol
</item>
- <item>Using a bridge which maps control messages in a
+ <item>Using a bridge that maps control messages in a
proprietary protocol to a standardized management protocol and
- vice versa.
+ conversely
</item>
</list>
- <p>All of these approaches have different advantages and
- disadvantages. Mnesia applications can easily be opened to the
- SNMP protocol. It is possible to establish a direct one-to-one
- mapping between Mnesia tables and SNMP tables. This
- means that a Mnesia table can be configured to be <em>both</em>
- a Mnesia table and an SNMP table. A number of functions to
- control this behavior are described in the Mnesia reference
- manual.
- </p>
+ <p>All these approaches have different advantages and
+ disadvantages. <c>Mnesia</c> applications can easily be opened to
+ the SNMP protocol. A direct 1-to-1 mapping can be established
+ between <c>Mnesia</c> tables and SNMP tables. This means
+ that a <c>Mnesia</c> table can be configured to be <em>both</em>
+ a <c>Mnesia</c> table and an SNMP table. A number of functions to
+ control this behavior are described in the Reference Manual.</p>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_overview.xml b/lib/mnesia/doc/src/Mnesia_overview.xml
new file mode 100644
index 0000000000..b0d67d3e1a
--- /dev/null
+++ b/lib/mnesia/doc/src/Mnesia_overview.xml
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2013</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Mnesia</title>
+ <prepared>Claes Wikstr&ouml;m, Hans Nilsson and H&aring;kan Mattsson</prepared>
+ <responsible>Bjarne D&auml;cker</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Bjarne D&auml;cker</checked>
+ <date></date>
+ <rev>C</rev>
+ <file>Mnesia_overview.xml</file>
+ </header>
+
+ <p>The management of data in telecommunications system has many
+ aspects, thereof some, but not all, are addressed by traditional
+ commercial Database Management Systems (DBMSs). In particular the
+ high level of fault tolerance that is required in many nonstop
+ systems, combined with requirements on the DBMS to run in the same
+ address space as the application, have led us to implement a new
+ DBMS, called <c>Mnesia</c>.</p>
+ <p><c>Mnesia</c> is implemented in, and tightly connected to Erlang.
+ It provides the functionality that is necessary for the
+ implementation of fault tolerant telecommunications systems.</p>
+ <p><c>Mnesia</c> is a multiuser distributed DBMS specially made for
+ industrial telecommunications applications written in Erlang,
+ which is also the intended target language.
+ <c>Mnesia</c> tries to address all the data
+ management issues required for typical telecommunications systems.
+ It has a number of features that are not normally found in traditional
+ databases.</p>
+ <p>In telecommunications applications, there are different needs
+ from the features provided by traditional DBMSs. The applications now
+ implemented in Erlang need a mixture of a broad range
+ of features, which generally are not satisfied by traditional DBMSs.
+ <c>Mnesia</c> is designed with requirements like the following in
+ mind:</p>
+ <list type="ordered">
+ <item>Fast real-time key/value lookup
+ </item>
+ <item>Complicated non-real-time queries mainly for
+ operation and maintenance
+ </item>
+ <item>Distributed data because of distributed applications
+ </item>
+ <item>High fault tolerance
+ </item>
+ <item>Dynamic reconfiguration
+ </item>
+ <item>Complex objects
+ </item>
+ </list>
+ <p><c>Mnesia</c> is designed with the typical data management problems
+ of telecommunications applications in mind. This sets <c>Mnesia</c>
+ apart from most other DBMS. Hence <c>Mnesia</c>
+ combines many concepts found in traditional databases such as
+ transactions and queries with concepts found in data management
+ systems for telecommunications applications, for example:</p>
+ <list type="bulleted">
+ <item>Fast real-time operations
+ </item>
+ <item>Configurable degree of fault tolerance (by replication)
+ </item>
+ <item>The ability to reconfigure the system without stopping or
+ suspending it.
+ </item>
+ </list>
+ <p><c>Mnesia</c> is also interesting because of its tight coupling to
+ Erlang, thus almost turning Erlang into a database programming
+ language. This has many benefits, the foremost is that
+ the impedance mismatch between the data format used by the DBMS
+ and the data format used by the programming language, which is used
+ to manipulate the data, completely disappears.</p>
+
+ <section>
+ <title>Mnesia Database Management System (DBMS)</title>
+ <section>
+ <title>Features</title>
+ <p><c>Mnesia</c> contains the following features that combine to
+ produce a fault-tolerant, distributed DBMS written in Erlang:
+ </p>
+ <list type="bulleted">
+ <item>Database schema can be dynamically reconfigured at runtime.
+ </item>
+ <item>Tables can be declared to have properties such as location,
+ replication, and persistence.
+ </item>
+ <item>Tables can be moved or replicated to several nodes to improve
+ fault tolerance. The rest of the system can still access the tables
+ to read, write, and delete records.
+ </item>
+ <item>Table locations are transparent to the programmer.
+ Programs address table names and the system itself keeps track of
+ table locations.
+ </item>
+ <item>Database transactions can be distributed, and many
+ functions can be called within one transaction.
+ </item>
+ <item>Several transactions can run concurrently, and their execution
+ is fully synchronized by the DBMS. <c>Mnesia</c> ensures that no
+ two processes manipulate data simultaneously.
+ </item>
+ <item>Transactions can be assigned the property of being executed on
+ all nodes in the system, or on none. Transactions can also be
+ bypassed in favor of running "dirty operations", which reduce
+ overheads and run fast.
+ </item>
+ </list>
+ <p>Details of these features are described in the following sections.</p>
+ </section>
+
+ <section>
+ <title>Add-On Application</title>
+ <p>Query List Comprehension (QLC) can be used with <c>Mnesia</c>
+ to produce specialized functions that enhance the operational
+ ability of <c>Mnesia</c>. QLC has its own documentation as part
+ of the OTP documentation set. The main features of QLC
+ when used with <c>Mnesia</c> are as follows:</p>
+ <list type="bulleted">
+ <item>QLC can optimize the query compiler for the <c>Mnesia</c>
+ DBMS, essentially making the DBMS more efficient.
+ </item>
+ <item>QLC can be used as a database programming
+ language for <c>Mnesia</c>. It includes a notation called "list
+ comprehensions" and can be used to make complex database
+ queries over a set of tables.
+ </item>
+ </list>
+ <p>For information about QLC, see the
+ <seealso marker="stdlib:qlc">qlc</seealso> manual page
+ in <c>STDLIB</c>.</p>
+ </section>
+
+ <section>
+ <title>When to Use Mnesia</title>
+ <p>Use <c>Mnesia</c> with the following types of applications:</p>
+ <list type="bulleted">
+ <item>Applications that need to replicate data.
+ </item>
+ <item>Applications that perform complicated searches on data.
+ </item>
+ <item>Applications that need to use atomic transactions to
+ update several records simultaneously.
+ </item>
+ <item>Applications that use soft real-time characteristics.
+ </item>
+ </list>
+ <p><c>Mnesia</c> is not as appropriate with the
+ following types of applications:</p>
+ <list type="bulleted">
+ <item>Programs that process plain text or binary data files.
+ </item>
+ <item>Applications that merely need a look-up dictionary that
+ can be stored to disc. Those applications use the standard
+ library module <c>dets</c>, which is a disc-based version
+ of the module <c>ets</c>. For information about <c>dets</c>,
+ see the <seealso marker="stdlib:dets">dets</seealso>
+ manual page in <c>STDLIB</c>.
+ </item>
+ <item>Applications that need disc logging facilities.
+ Those applications can
+ use the module <c>disk_log</c> by preference. For
+ information about <c>disk_log</c>, see the
+ <seealso marker="kernel:disk_log">disk_log</seealso>
+ manual page in <c>Kernel</c>.
+ </item>
+ <item>Hard real-time systems.
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
diff --git a/lib/mnesia/doc/src/book.xml b/lib/mnesia/doc/src/book.xml
index d200582a0f..4c638bffc0 100644
--- a/lib/mnesia/doc/src/book.xml
+++ b/lib/mnesia/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/mnesia/doc/src/bup.erl b/lib/mnesia/doc/src/bup.erl
index b9e541ad6a..9815dc1795 100644
--- a/lib/mnesia/doc/src/bup.erl
+++ b/lib/mnesia/doc/src/bup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/mnesia/doc/src/company.erl b/lib/mnesia/doc/src/company.erl
index eef5535ed3..0cc9d249cc 100644
--- a/lib/mnesia/doc/src/company.erl
+++ b/lib/mnesia/doc/src/company.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/doc/src/company.hrl b/lib/mnesia/doc/src/company.hrl
index 85e0e6ff12..a073842a61 100644
--- a/lib/mnesia/doc/src/company.hrl
+++ b/lib/mnesia/doc/src/company.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/mnesia/doc/src/company_o.erl b/lib/mnesia/doc/src/company_o.erl
index dffe9840bb..9b75d3fb3c 100644
--- a/lib/mnesia/doc/src/company_o.erl
+++ b/lib/mnesia/doc/src/company_o.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/doc/src/company_o.hrl b/lib/mnesia/doc/src/company_o.hrl
index d8b584c296..bd1cc506f0 100644
--- a/lib/mnesia/doc/src/company_o.hrl
+++ b/lib/mnesia/doc/src/company_o.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index ed5b879f7f..f441ba4c63 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -32,291 +33,254 @@
<file></file>
</header>
<module>mnesia</module>
- <modulesummary>A Distributed Telecommunications DBMS </modulesummary>
+ <modulesummary>A distributed telecommunications DBMS</modulesummary>
<description>
- <p><c>Mnesia</c> is a distributed DataBase Management System (DBMS),
- appropriate for telecommunications applications and other Erlang
- applications which require continuous operation and exhibit soft
- real-time properties.
- </p>
- <p>Listed below are some of the most important and attractive capabilities, Mnesia provides:
- </p>
+
+ <p>The following are some of the most important and attractive
+ capabilities provided by <c>Mnesia</c>:</p>
<list type="bulleted">
- <item>
- <p>A relational/object hybrid data model which is
- suitable for telecommunications applications.
- </p>
+ <item>A relational/object hybrid data model that is suitable
+ for telecommunications applications.
</item>
- <item>
- <p>A specifically designed DBMS query language, QLC (as an add-on library).
- </p>
+ <item>A DBMS query language, Query List Comprehension (QLC) as
+ an add-on library.
</item>
- <item>
- <p>Persistence. Tables may be coherently kept on disc as
- well as in main memory.
- </p>
+ <item>Persistence. Tables can be coherently kept on disc and
+ in the main memory.
</item>
- <item>
- <p>Replication. Tables may be replicated at several nodes.
- </p>
+ <item>Replication. Tables can be replicated at several nodes.
</item>
- <item>
- <p>Atomic transactions. A series of table manipulation
- operations can be grouped into a single atomic
- transaction.
- </p>
+ <item>Atomic transactions. A series of table manipulation
+ operations can be grouped into a single atomic transaction.
</item>
- <item>
- <p>Location transparency. Programs can be written without
- knowledge of the actual location of data.
- </p>
+ <item>Location transparency. Programs can be written without
+ knowledge of the actual data location.
</item>
- <item>
- <p>Extremely fast real time data searches.
- </p>
+ <item>Extremely fast real-time data searches.
</item>
- <item>
- <p>Schema manipulation routines. It is possible to
- reconfigure the DBMS at runtime without stopping the
- system.
- </p>
+ <item>Schema manipulation routines. The DBMS can be
+ reconfigured at runtime without stopping the system.
</item>
</list>
- <p>This Reference Manual describes the Mnesia API. This includes
- functions used to define and manipulate Mnesia tables.
- </p>
- <p>All functions documented in these pages can be used in any
- combination with queries using the list comprehension notation. The
- query notation is described in the QLC's man page.
- </p>
- <p>Data in Mnesia is organized as a set of tables. Each table
- has a name which must be an atom. Each table is made up of
- Erlang records. The user is responsible for the record
- definitions. Each table also has a set of properties. Below
- are some of the properties that are associated with each
- table:
- </p>
+ <p>This Reference Manual describes the <c>Mnesia</c> API. This
+ includes functions that define and manipulate <c>Mnesia</c>
+ tables.</p>
+ <p>All functions in this Reference Manual can be used in any
+ combination with queries using the list comprehension notation.
+ For information about the query notation, see the
+ <seealso marker="stdlib:qlc">qlc</seealso>
+ manual page in <c>STDLIB</c>.</p>
+ <p>Data in <c>Mnesia</c> is organized as a set of tables. Each table
+ has a name that must be an atom. Each table is made up of
+ Erlang records. The user is responsible for the record
+ definitions. Each table also has a set of properties. The
+ following are some of the properties that are associated with each
+ table:</p>
<list type="bulleted">
<item>
- <p><c>type</c>. Each table can either have 'set',
- 'ordered_set' or 'bag' semantics. Note: currently 'ordered_set'
- is not supported for 'disc_only_copies'. If a table is of type
- 'set' it means that each key leads to either one or zero
- records. <br></br>
-If a new item is inserted with the same key as
- an existing record, the old record is overwritten. On the
- other hand, if a table is of type 'bag', each key can map to
- several records. However, all records in type bag tables are
- unique, only the keys may be duplicated.
- </p>
+ <p><c>type</c>. Each table can have <c>set</c>,
+ <c>ordered_set</c>, or <c>bag</c> semantics. Notice that
+ currently <c>ordered_set</c> is not supported for
+ <c>disc_only_copies</c>.</p>
+ <p>If a table is of type <c>set</c>, each key leads to
+ either one or zero records.</p>
+ <p>If a new item is inserted with the same key as an
+ existing record, the old record is overwritten. However,
+ if a table is of type <c>bag</c>, each key can map to
+ several records. All records in type <c>bag</c> tables are
+ unique, only the keys can be duplicated.</p>
</item>
<item>
<p><c>record_name</c>. All records stored in a table must
- have the same name. You may say that the records must be
- instances of the same record type.
- </p>
+ have the same name. The records must be instances of the
+ same record type.</p>
</item>
<item>
- <p><c>ram_copies</c> A table can be replicated on a number
- of Erlang nodes. The <c>ram_copies</c> property specifies a
- list of Erlang nodes where RAM copies are kept. These
- copies can be dumped to disc at regular intervals. However,
+ <p><c>ram_copies</c>. A table can be replicated on a number
+ of Erlang nodes. Property <c>ram_copies</c> specifies a
+ list of Erlang nodes where RAM copies are kept. These
+ copies can be dumped to disc at regular intervals. However,
updates to these copies are not written to disc on a
- transaction basis.
- </p>
+ transaction basis.</p>
</item>
<item>
- <p><c>disc_copies</c> The <c>disc_copies</c> property
+ <p><c>disc_copies</c>. This property
specifies a list of Erlang nodes where the table is kept in
- RAM as well as on disc. All updates of the table are
- performed on the actual table and are also logged to disc.
+ RAM and on disc. All updates of the table are
+ performed in the actual table and are also logged to disc.
If a table is of type <c>disc_copies</c> at a certain node,
- it means that the entire table is resident in RAM memory as
- well as on disc. Each transaction performed on the table is
- appended to a LOG file as well as written into the RAM
- table.
- </p>
+ the entire table is resident in RAM memory and on disc.
+ Each transaction performed on the table is appended to a
+ <c>LOG</c> file and written into the RAM table.</p>
</item>
<item>
- <p><c>disc_only_copies</c> Some, or all, table replicas
+ <p><c>disc_only_copies</c>. Some, or all, table replicas
can be kept on disc only. These replicas are considerably
- slower than the RAM based replicas.
- </p>
+ slower than the RAM-based replicas.</p>
</item>
<item>
- <p><c>index</c> This is a list of attribute names, or
+ <p><c>index</c>. This is a list of attribute names, or
integers, which specify the tuple positions on which
- Mnesia shall build and maintain an extra index table.
- </p>
+ <c>Mnesia</c> is to build and maintain an extra index
+ table.</p>
</item>
<item>
- <p><c>local_content</c> When an application requires
+ <p><c>local_content</c>. When an application requires
tables whose contents are local to each node,
- <c>local_content</c> tables may be used. The name of the
- table is known to all Mnesia nodes, but its contents are
+ <c>local_content</c> tables can be used. The table name
+ is known to all <c>Mnesia</c> nodes, but its content is
unique on each node. This means that access to such a table
- must be done locally. Set the <c>local_content</c> field to
- <c>true</c> if you want to enable the <c>local_content</c>
- behavior. The default is <c>false</c>.
- </p>
+ must be done locally. Set field <c>local_content</c> to
+ <c>true</c> to enable the <c>local_content</c>
+ behavior. Default is <c>false</c>.</p>
</item>
<item>
- <p><c>majority</c> This attribute can be either <c>true</c> or
- <c>false</c> (default is <c>false</c>). When <c>true</c>, a majority
- of the table replicas must be available for an update to succeed.
- Majority checking can be enabled on tables with mission-critical data,
- where it is vital to avoid inconsistencies due to network splits.
- </p>
+ <p><c>majority</c>. This attribute is <c>true</c> or
+ <c>false</c>; default is <c>false</c>. When <c>true</c>,
+ a majority of the table replicas must be available for an
+ update to succeed. Majority checking can be enabled on
+ tables with mission-critical data, where it is vital to
+ avoid inconsistencies because of network splits.</p>
</item>
<item>
- <p><c>snmp</c> Each (set based) Mnesia table can be
- automatically turned into an SNMP ordered table as well.
- This property specifies the types of the SNMP keys.
- </p>
+ <p><c>snmp</c>. Each (set-based) <c>Mnesia</c> table can be
+ automatically turned into a Simple Network Management
+ Protocol (SNMP) ordered table as well.
+ This property specifies the types of the SNMP keys.</p>
</item>
<item>
<p><c>attributes</c>. The names of the attributes for the
- records that are inserted in the table.
- </p>
+ records that are inserted in the table.</p>
</item>
</list>
- <p>See <c>mnesia:create_table/2</c> about the complete set of
- table properties and their details.
- </p>
- <p>This document uses a table of persons to illustrate various
- examples. The following record definition is assumed:
- </p>
+ <p>For information about the complete set of table properties
+ and their details, see <c>mnesia:create_table/2</c>.</p>
+ <p>This Reference Manual uses a table of persons to illustrate
+ various examples. The following record definition is assumed:</p>
<code type="none">
-record(person, {name,
age = 0,
address = unknown,
salary = 0,
- children = []}),
- </code>
- <p>The first attribute of the record is the primary key, or key
- for short.
- </p>
- <p>The function descriptions are sorted in alphabetic order. <em>Hint:</em>
- start to read about <c>mnesia:create_table/2</c>,
- <c>mnesia:lock/2</c> and <c>mnesia:activity/4</c> before you continue on
- and learn about the rest.
- </p>
- <p>Writing or deleting in transaction context creates a local copy
- of each modified record during the transaction. During iteration,
- i.e. <c>mnesia:fold[lr]/4</c> <c>mnesia:next/2</c> <c>mnesia:prev/2</c>
- <c>mnesia:snmp_get_next_index/2</c>, mnesia will compensate for
- every written or deleted record, which may reduce the
- performance. If possible avoid writing or deleting records in
- the same transaction before iterating over the table.
- </p>
+ children = []}),</code>
+ <p>The first record attribute is the primary key, or key
+ for short.</p>
+ <p>The function descriptions are sorted in alphabetical order.
+ It is recommended to start to read about
+ <c>mnesia:create_table/2</c>, <c>mnesia:lock/2</c>, and
+ <c>mnesia:activity/4</c> before you continue and learn
+ about the rest.</p>
+ <p>Writing or deleting in transaction-context creates a local
+ copy of each modified record during the transaction. During
+ iteration, that is, <c>mnesia:fold[lr]/4</c>,
+ <c>mnesia:next/2</c>, <c>mnesia:prev/2</c>, and
+ <c>mnesia:snmp_get_next_index/2</c>, <c>Mnesia</c>
+ compensates for every written or deleted record, which can
+ reduce the performance.</p>
+ <p>If possible, avoid writing or deleting records in the same
+ transaction before iterating over the table.</p>
</description>
+
<funcs>
<func>
- <name>abort(Reason) -> transaction abort </name>
- <fsummary>Abort the current transaction.</fsummary>
+ <name>abort(Reason) -> transaction abort</name>
+ <fsummary>Terminates the current transaction.</fsummary>
<desc>
- <p>Makes the transaction silently
+ <p>Makes the transaction silently
return the tuple <c>{aborted, Reason}</c>.
- The abortion of a Mnesia transaction means that
- an exception will be thrown to an enclosing <c>catch</c>.
+ Termination of a <c>Mnesia</c> transaction means that
+ an exception is thrown to an enclosing <c>catch</c>.
Thus, the expression <c>catch mnesia:abort(x)</c> does
- not abort the transaction. </p>
+ not terminate the transaction.</p>
</desc>
</func>
<func>
<name>activate_checkpoint(Args) -> {ok,Name,Nodes} | {error,Reason}</name>
- <fsummary>Activate a checkpoint.</fsummary>
+ <fsummary>Activates a checkpoint.</fsummary>
<desc>
- <p>A checkpoint is a consistent view of the system.
+ <marker id="activate_checkpoint"></marker>
+ <p>A checkpoint is a consistent view of the system.
A checkpoint can be activated on a set of tables.
- This checkpoint can then be traversed and will
- present a view of the system as it existed at the time when
- the checkpoint was activated, even if the tables are being or have been
- manipulated.
- </p>
- <p><c>Args</c> is a list of the following tuples:
- </p>
+ This checkpoint can then be traversed and
+ presents a view of the system as it existed at the time when
+ the checkpoint was activated, even if the tables are
+ being or have been manipulated.</p>
+ <p><c>Args</c> is a list of the following tuples:</p>
<list type="bulleted">
<item>
- <p><c>{name,Name}</c>. <c>Name</c> of checkpoint. Each
- checkpoint must have a name which is unique to the
+ <p><c>{name,Name}</c>. <c>Name</c> is the checkpoint name.
+ Each checkpoint must have a name that is unique to the
associated nodes. The name can be reused only once the
checkpoint has been deactivated. By default, a name
- which is probably unique is generated.
- </p>
+ that is probably unique is generated.</p>
</item>
<item>
<p><c>{max,MaxTabs}</c>. <c>MaxTabs</c> is a list of
- tables that should be included in the checkpoint. The
- default is []. For these tables, the redundancy will be
- maximized and checkpoint information will be retained together
+ tables that are to be included in the checkpoint.
+ Default is <c>[]</c>. For these tables, the redundancy is
+ maximized and checkpoint information is retained together
with all replicas. The checkpoint becomes more fault
tolerant if the tables have several replicas. When a new
- replica is added by means of the schema manipulation
- function <c>mnesia:add_table_copy/3</c>, a retainer will
- also be attached automatically.
- </p>
+ replica is added by the schema manipulation
+ function <c>mnesia:add_table_copy/3</c>, a retainer is
+ also attached automatically.</p>
</item>
<item>
<p><c>{min,MinTabs}</c>. <c>MinTabs</c> is a list of
- tables that should be included in the checkpoint. The
- default is []. For these tables, the redundancy will be
- minimized and the checkpoint information will only be retained
- with one replica, preferably on the local node.
- </p>
+ tables that are to be included in the checkpoint.
+ Default is []. For these tables, the redundancy is
+ minimized and the checkpoint information is only retained
+ with one replica, preferably on the local node.</p>
</item>
<item>
<p><c>{allow_remote,Bool}</c>. <c>false</c> means that
all retainers must be local. The checkpoint cannot be
activated if a table does not reside locally.
<c>true</c> allows retainers to be allocated on any
- node. Default is set to <c>true</c>.
- </p>
+ node. Default is <c>true</c>.</p>
</item>
<item>
<p><c>{ram_overrides_dump,Bool}</c>. Only applicable
- for <c>ram_copies</c>. <c>Bool</c> allows you to choose
- to backup the table state as it is in RAM, or as it is on
- disc. <c>true</c> means that the latest committed
- records in RAM should be included in the checkpoint.
- These are the records that the application accesses.
- <c>false</c> means that the records dumped to DAT files
- should be included in the checkpoint. These are the
- records that will be loaded at startup. Default is
- <c>false</c>.
- </p>
+ for <c>ram_copies</c>. <c>Bool</c> allows you to choose
+ to back up the table state as it is in RAM, or as it is
+ on disc. <c>true</c> means that the latest committed
+ records in RAM are to be included in the checkpoint.
+ These are the records that the application accesses.
+ <c>false</c> means that the records dumped to <c>DAT</c>
+ files are to be included in the checkpoint. These
+ records are loaded at startup. Default is <c>false</c>.</p>
</item>
</list>
<p>Returns <c>{ok,Name,Nodes}</c> or <c>{error,Reason}</c>.
- <c>Name</c> is the (possibly generated) name of the
- checkpoint. <c>Nodes</c> are the nodes that
+ <c>Name</c> is the (possibly generated) checkpoint name.
+ <c>Nodes</c> are the nodes that
are involved in the checkpoint. Only nodes that keep a
- checkpoint retainer know about the checkpoint.
- </p>
+ checkpoint retainer know about the checkpoint.</p>
</desc>
</func>
<func>
<name>activity(AccessContext, Fun [, Args]) -> ResultOfFun | exit(Reason)</name>
- <fsummary>Execute <c>Fun</c>in <c>AccessContext</c>.</fsummary>
+ <fsummary>Executes <c>Fun</c> in <c>AccessContext</c>.</fsummary>
<desc>
- <p>Invokes <c>mnesia:activity(AccessContext, Fun, Args, AccessMod)</c> where <c>AccessMod</c> is the default
+ <marker id="activity_2_3"></marker>
+ <p>Calls <c>mnesia:activity(AccessContext, Fun, Args,
+ AccessMod)</c>, where <c>AccessMod</c> is the default
access callback module obtained by
<c>mnesia:system_info(access_module)</c>. <c>Args</c>
- defaults to the empty list <c>[]</c>.</p>
+ defaults to <c>[]</c> (empty list).</p>
</desc>
</func>
<func>
<name>activity(AccessContext, Fun, Args, AccessMod) -> ResultOfFun | exit(Reason)</name>
- <fsummary>Execute <c>Fun</c>in <c>AccessContext</c>.</fsummary>
- <desc>
- <p>This function executes the functional object <c>Fun</c>
- with the arguments <c>Args</c>.
- </p>
- <p>The code which executes inside the activity can
- consist of a series of table manipulation functions, which is
- performed in a <c>AccessContext</c>. Currently, the following
- access contexts are supported:
- </p>
+ <fsummary>Executes <c>Fun</c> in <c>AccessContext</c>.</fsummary>
+ <desc>
+ <marker id="activity_4"></marker>
+ <p>Executes the functional object <c>Fun</c>
+ with argument <c>Args</c>.</p>
+ <p>The code that executes inside the activity can
+ consist of a series of table manipulation functions, which are
+ performed in an <c>AccessContext</c>. Currently, the following
+ access contexts are supported:</p>
<taglist>
<tag><c>transaction</c></tag>
<item>
@@ -324,10 +288,10 @@ If a new item is inserted with the same key as
</item>
<tag><c>{transaction, Retries}</c></tag>
<item>
- <p>Invokes <c>mnesia:transaction(Fun, Args, Retries)</c>. Note that the result from the <c>Fun</c> is
- returned if the transaction was successful (atomic),
- otherwise the function exits with an abort reason.
- </p>
+ <p>Calls <c>mnesia:transaction(Fun, Args, Retries)</c>.
+ Notice that the result from <c>Fun</c> is
+ returned if the transaction is successful (atomic),
+ otherwise the function exits with an abort reason.</p>
</item>
<tag><c>sync_transaction</c></tag>
<item>
@@ -335,540 +299,499 @@ If a new item is inserted with the same key as
</item>
<tag><c>{sync_transaction, Retries}</c></tag>
<item>
- <p>Invokes <c>mnesia:sync_transaction(Fun, Args, Retries)</c>. Note that the result from the <c>Fun</c> is
- returned if the transaction was successful (atomic),
- otherwise the function exits with an abort reason.
- </p>
+ <p>Calls <c>mnesia:sync_transaction(Fun, Args, Retries)</c>.
+ Notice that the result from <c>Fun</c> is
+ returned if the transaction is successful (atomic),
+ otherwise the function exits with an abort reason.</p>
</item>
<tag><c>async_dirty</c></tag>
<item>
- <p>Invokes <c>mnesia:async_dirty(Fun, Args)</c>.
- </p>
+ <p>Calls <c>mnesia:async_dirty(Fun, Args)</c>.</p>
</item>
<tag><c>sync_dirty</c></tag>
<item>
- <p>Invokes <c>mnesia:sync_dirty(Fun, Args)</c>.
- </p>
+ <p>Calls <c>mnesia:sync_dirty(Fun, Args)</c>.</p>
</item>
<tag><c>ets</c></tag>
<item>
- <p>Invokes <c>mnesia:ets(Fun, Args)</c>.
- </p>
+ <p>Calls <c>mnesia:ets(Fun, Args)</c>.</p>
</item>
</taglist>
<p>This function (<c>mnesia:activity/4</c>) differs in an
- important aspect from the <c>mnesia:transaction</c>,
+ important way from the functions <c>mnesia:transaction</c>,
<c>mnesia:sync_transaction</c>,
- <c>mnesia:async_dirty</c>, <c>mnesia:sync_dirty</c> and
- <c>mnesia:ets</c> functions. The <c>AccessMod</c> argument
- is the name of a callback module which implements the
- <c>mnesia_access</c> behavior.
- </p>
- <p>Mnesia will forward calls to the following functions:
- </p>
+ <c>mnesia:async_dirty</c>, <c>mnesia:sync_dirty</c>, and
+ <c>mnesia:ets</c>. Argument <c>AccessMod</c>
+ is the name of a callback module, which implements the
+ <c>mnesia_access</c> behavior.</p>
+ <p><c>Mnesia</c> forwards calls to the following functions:</p>
<list type="bulleted">
- <item>
- <p>mnesia:lock/2 (read_lock_table/1, write_lock_table/1)</p>
+ <item>mnesia:lock/2 (read_lock_table/1, write_lock_table/1)
</item>
- <item>
- <p>mnesia:write/3 (write/1, s_write/1)</p>
+ <item>mnesia:write/3 (write/1, s_write/1)
</item>
- <item>
- <p>mnesia:delete/3 (delete/1, s_delete/1)</p>
+ <item>mnesia:delete/3 (delete/1, s_delete/1)
</item>
- <item>
- <p>mnesia:delete_object/3 (delete_object/1, s_delete_object/1)</p>
+ <item>mnesia:delete_object/3 (delete_object/1, s_delete_object/1)
</item>
- <item>
- <p>mnesia:read/3 (read/1, wread/1)</p>
+ <item>mnesia:read/3 (read/1, wread/1)
</item>
- <item>
- <p>mnesia:match_object/3 (match_object/1)</p>
+ <item>mnesia:match_object/3 (match_object/1)
</item>
- <item>
- <p>mnesia:all_keys/1</p>
+ <item>mnesia:all_keys/1
</item>
- <item>
- <p>mnesia:first/1</p>
+ <item>mnesia:first/1
</item>
- <item>
- <p>mnesia:last/1</p>
+ <item>mnesia:last/1
</item>
- <item>
- <p>mnesia:prev/2</p>
+ <item>mnesia:prev/2
</item>
- <item>
- <p>mnesia:next/2</p>
+ <item>mnesia:next/2
</item>
- <item>
- <p>mnesia:index_match_object/4 (index_match_object/2)</p>
+ <item>mnesia:index_match_object/4 (index_match_object/2)
</item>
- <item>
- <p>mnesia:index_read/3</p>
+ <item>mnesia:index_read/3
</item>
- <item>
- <p>mnesia:table_info/2</p>
+ <item>mnesia:table_info/2
</item>
</list>
- <p>to the corresponding:
- </p>
+ <p>to the corresponding:</p>
<list type="bulleted">
- <item>
- <p>AccessMod:lock(ActivityId, Opaque, LockItem, LockKind)</p>
+ <item>AccessMod:lock(ActivityId, Opaque, LockItem, LockKind)
</item>
- <item>
- <p>AccessMod:write(ActivityId, Opaque, Tab, Rec, LockKind)</p>
+ <item>AccessMod:write(ActivityId, Opaque, Tab, Rec, LockKind)
</item>
- <item>
- <p>AccessMod:delete(ActivityId, Opaque, Tab, Key, LockKind)</p>
+ <item>AccessMod:delete(ActivityId, Opaque, Tab, Key, LockKind)
</item>
- <item>
- <p>AccessMod:delete_object(ActivityId, Opaque, Tab, RecXS, LockKind)</p>
+ <item>AccessMod:delete_object(ActivityId, Opaque, Tab, RecXS,
+ LockKind)
</item>
- <item>
- <p>AccessMod:read(ActivityId, Opaque, Tab, Key, LockKind)</p>
+ <item>AccessMod:read(ActivityId, Opaque, Tab, Key, LockKind)
</item>
- <item>
- <p>AccessMod:match_object(ActivityId, Opaque, Tab, Pattern, LockKind)</p>
+ <item>AccessMod:match_object(ActivityId, Opaque, Tab, Pattern,
+ LockKind)
</item>
- <item>
- <p>AccessMod:all_keys(ActivityId, Opaque, Tab, LockKind)</p>
+ <item>AccessMod:all_keys(ActivityId, Opaque, Tab, LockKind)
</item>
- <item>
- <p>AccessMod:first(ActivityId, Opaque, Tab)</p>
+ <item>AccessMod:first(ActivityId, Opaque, Tab)
</item>
- <item>
- <p>AccessMod:last(ActivityId, Opaque, Tab)</p>
+ <item>AccessMod:last(ActivityId, Opaque, Tab)
</item>
- <item>
- <p>AccessMod:prev(ActivityId, Opaque, Tab, Key)</p>
+ <item>AccessMod:prev(ActivityId, Opaque, Tab, Key)
</item>
- <item>
- <p>AccessMod:next(ActivityId, Opaque, Tab, Key)</p>
+ <item>AccessMod:next(ActivityId, Opaque, Tab, Key)
</item>
- <item>
- <p>AccessMod:index_match_object(ActivityId, Opaque, Tab, Pattern, Attr, LockKind)</p>
+ <item>AccessMod:index_match_object(ActivityId, Opaque, Tab,
+ Pattern, Attr, LockKind)
</item>
- <item>
- <p>AccessMod:index_read(ActivityId, Opaque, Tab, SecondaryKey, Attr, LockKind)</p>
+ <item>AccessMod:index_read(ActivityId, Opaque, Tab,
+ SecondaryKey, Attr, LockKind)
</item>
- <item>
- <p>AccessMod:table_info(ActivityId, Opaque, Tab, InfoItem)</p>
+ <item>AccessMod:table_info(ActivityId, Opaque, Tab, InfoItem)
</item>
</list>
- <p>where <c>ActivityId</c> is a record which represents the
- identity of the enclosing Mnesia activity. The first field
- (obtained with <c>element(1, ActivityId)</c> contains an
- atom which may be interpreted as the type of the activity:
- <c>'ets'</c>, <c>'async_dirty'</c>, <c>'sync_dirty'</c> or
- <c>'tid'</c>. <c>'tid'</c> means that the activity is a
+ <p><c>ActivityId</c> is a record that represents the identity
+ of the enclosing <c>Mnesia</c> activity. The first field
+ (obtained with <c>element(1, ActivityId)</c>) contains an
+ atom, which can be interpreted as the activity type:
+ <c>ets</c>, <c>async_dirty</c>, <c>sync_dirty</c>, or
+ <c>tid</c>. <c>tid</c> means that the activity is a
transaction. The structure of the rest of the identity
- record is internal to Mnesia.
- </p>
- <p><c>Opaque</c> is an opaque data structure which is internal
- to Mnesia.</p>
+ record is internal to <c>Mnesia</c>.</p>
+ <p><c>Opaque</c> is an opaque data structure that is internal
+ to <c>Mnesia</c>.</p>
</desc>
</func>
<func>
<name>add_table_copy(Tab, Node, Type) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Copy a table to a remote node.</fsummary>
+ <fsummary>Copies a table to a remote node.</fsummary>
<desc>
- <p>This function makes another copy of a table at the
- node <c>Node</c>. The <c>Type</c> argument must be
- either of the atoms <c>ram_copies</c>, <c>disc_copies</c>,
- or
+ <marker id="add_table_copy"></marker>
+ <p>Makes another copy of a table at the node <c>Node</c>.
+ Argument <c>Type</c> must be either of the atoms
+ <c>ram_copies</c>, <c>disc_copies</c>, or
<c>disc_only_copies</c>. For example, the following call
- ensures that a disc replica of the <c>person</c> table also
- exists at node <c>Node</c>.</p>
+ ensures that a disc replica of the <c>person</c> table also
+ exists at node <c>Node</c>:</p>
<code type="none">
-mnesia:add_table_copy(person, Node, disc_copies)
- </code>
+mnesia:add_table_copy(person, Node, disc_copies)</code>
<p>This function can also be used to add a replica of the
table named <c>schema</c>.</p>
</desc>
</func>
<func>
<name>add_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Create an index for a table. </fsummary>
- <desc>
- <p>Table indices can and should be used whenever the user
- wants to frequently use some other field than the key field
- to look up records. If this other field has an index
- associated with it, these lookups can occur in constant time
- and space. For example, if our application wishes to use
- the age field of persons to efficiently find all person with
- a specific age, it might be a good idea to have an index on
- the age field. This can be accomplished with the following
+ <fsummary>Creates an index for a table.</fsummary>
+ <desc>
+ <marker id="add_table_index"></marker>
+ <p>Table indexes can be used whenever the user
+ wants to use frequently some other field than the key field
+ to look up records. If this other field has an associated
+ index, these lookups can occur in constant time
+ and space. For example, if your application wishes to use
+ field <c>age</c> to find efficiently all persons with
+ a specific age, it can be a good idea to have an index on
+ field <c>age</c>. This can be done with the following
call:</p>
<code type="none">
-mnesia:add_table_index(person, age)
- </code>
- <p>Indices do not come free, they occupy space which is
- proportional to the size of the table. They also cause insertions
- into the table to execute slightly slower. </p>
+mnesia:add_table_index(person, age)</code>
+ <p>Indexes do not come for free. They occupy space that is
+ proportional to the table size, and they cause insertions
+ into the table to execute slightly slower.</p>
</desc>
</func>
<func>
<name>all_keys(Tab) -> KeyList | transaction abort</name>
- <fsummary>Return all keys in a table.</fsummary>
+ <fsummary>Returns all keys in a table.</fsummary>
<desc>
- <p>This function returns a list of all keys in the table
- named <c>Tab</c>. The semantics of this function is context
- sensitive. See <c>mnesia:activity/4</c> for more information. In
- transaction context it acquires a read lock on the entire
+ <marker id="all_keys"></marker>
+ <p>Returns a list of all keys in the table named <c>Tab</c>.
+ The semantics of this function is context-sensitive.
+ For more information, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a read lock on the entire
table.</p>
</desc>
</func>
<func>
- <name>async_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
- <fsummary>Call the Fun in a context which is not protected by a transaction.</fsummary>
+ <name>async_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
+ <fsummary>Calls the <c>Fun</c> in a context that is not protected by a transaction.</fsummary>
<desc>
- <p>Call the <c>Fun</c> in a context which is not protected
- by a transaction. The Mnesia function calls performed in the
- <c>Fun</c> are mapped to the corresponding dirty
- functions. This still involves logging, replication and
+ <marker id="async_dirty"></marker>
+ <p>Calls the <c>Fun</c> in a context that is not protected by
+ a transaction. The <c>Mnesia</c> function calls performed in
+ the <c>Fun</c> are mapped to the corresponding dirty
+ functions. This still involves logging, replication, and
subscriptions, but there is no locking, local transaction
storage, or commit protocols involved. Checkpoint retainers
- and indices are updated, but they will be updated dirty. As
- for normal mnesia:dirty_* operations, the operations are
- performed semi-asynchronously. See
- <c>mnesia:activity/4</c> and the Mnesia User's Guide for
- more details.
- </p>
- <p>It is possible to manipulate the Mnesia tables without
+ and indexes are updated, but they are updated dirty. As
+ for normal <c>mnesia:dirty_*</c> operations, the operations
+ are performed semi-asynchronously. For details, see
+ <c>mnesia:activity/4</c> and the User's Guide.</p>
+ <p>The <c>Mnesia</c> tables can be manipulated without
using transactions. This has some serious disadvantages, but
- is considerably faster since the transaction manager is not
+ is considerably faster, as the transaction manager is not
involved and no locks are set. A dirty operation does,
- however, guarantee a certain level of consistency and it is
- not possible for the dirty operations to return garbled
- records. All dirty operations provide location transparency
- to the programmer and a program does not have to be aware of
- the whereabouts of a certain table in order to function.
- </p>
- <p><em>Note:</em>It is more than 10 times more efficient to read records dirty
- than within a transaction.
- </p>
- <p>Depending on the application, it may be a good idea to use
+ however, guarantee a certain level of consistency, and
+ the dirty operations cannot return garbled records.
+ All dirty operations provide location transparency
+ to the programmer, and a program does not have to be aware
+ of the whereabouts of a certain table to function.</p>
+ <p>Notice that it is more than ten times more efficient to
+ read records dirty than within a transaction.</p>
+ <p>Depending on the application, it can be a good idea to use
the dirty functions for certain operations. Almost all
- Mnesia functions which can be called within transactions
- have a dirty equivalent which is much more
- efficient. However, it must be noted that it is possible for
- the database to be left in an inconsistent state if dirty
- operations are used to update it. Dirty operations should
- only be used for performance reasons when it is absolutely
- necessary. </p>
- <p><em>Note:</em> Calling (nesting) a <c>mnesia:[a]sync_dirty</c>
- inside a transaction context will inherit the transaction semantics.
- </p>
+ <c>Mnesia</c> functions that can be called within
+ transactions have a dirty equivalent, which is much more
+ efficient.</p>
+ <p>However, notice that there is a risk that the database can
+ be left in an inconsistent state if dirty operations are
+ used to update it. Dirty operations are only to be used
+ for performance reasons when it is absolutely necessary.</p>
+ <p>Notice that calling (nesting) <c>mnesia:[a]sync_dirty</c>
+ inside a transaction-context inherits the transaction
+ semantics.</p>
</desc>
</func>
<func>
<name>backup(Opaque [, BackupMod]) -> ok | {error,Reason}</name>
- <fsummary>Back up all tables in the database.</fsummary>
+ <fsummary>Backs up all tables in the database.</fsummary>
<desc>
- <p>Activates a new checkpoint covering all Mnesia tables,
- including the schema, with maximum degree of redundancy and
- performs a backup using <c>backup_checkpoint/2/3</c>. The
+ <marker id="backup"></marker>
+ <p>Activates a new checkpoint covering all <c>Mnesia</c> tables,
+ including the schema, with maximum degree of redundancy, and
+ performs a backup using <c>backup_checkpoint/2/3</c>. The
default value of the backup callback module <c>BackupMod</c>
is obtained by <c>mnesia:system_info(backup_module)</c>.</p>
</desc>
</func>
<func>
- <name>backup_checkpoint(Name, Opaque [, BackupMod]) -> ok | {error,Reason}</name>
- <fsummary>Back up all tables in a checkpoint.</fsummary>
+ <name>backup_checkpoint(Name, Opaque [, BackupMod]) -> ok | {error,Reason}</name>
+ <fsummary>Backs up all tables in a checkpoint.</fsummary>
<desc>
- <p>The tables are backed up to external media using the backup
+ <marker id="backup_checkpoint"></marker>
+ <p>The tables are backed up to external media using backup
module <c>BackupMod</c>. Tables with the local contents
property are backed up as they exist on the current
- node. <c>BackupMod</c> is the default backup callback
+ node. <c>BackupMod</c> is the default backup callback
module obtained by
- <c>mnesia:system_info(backup_module)</c>. See the User's
- Guide about the exact callback interface (the
- <c>mnesia_backup behavior</c>).</p>
+ <c>mnesia:system_info(backup_module)</c>. For information
+ about the exact callback interface (the
+ <c>mnesia_backup behavior</c>), see the User's Guide.</p>
</desc>
</func>
<func>
<name>change_config(Config, Value) -> {error, Reason} | {ok, ReturnValue}</name>
- <fsummary>Change a configuration parameter.</fsummary>
+ <fsummary>Changes a configuration parameter.</fsummary>
<desc>
- <p>The <c>Config</c> should be an atom of the following
- configuration parameters: </p>
+ <marker id="change_config"></marker>
+ <p><c>Config</c> is to be an atom of the following
+ configuration parameters:</p>
<taglist>
<tag><c>extra_db_nodes</c></tag>
<item>
- <p><c>Value</c> is a list of nodes which Mnesia should try to connect to.
- The <c>ReturnValue</c> will be those nodes in
- <c>Value</c> that Mnesia are connected to.
- <br></br>
-Note: This function shall only be used to connect to newly started ram nodes
- (N.D.R.S.N.) with an empty schema. If for example it is used after the network
- have been partitioned it may lead to inconsistent tables.
- <br></br>
-Note: Mnesia may be connected to other nodes than those
- returned in <c>ReturnValue</c>.</p>
+ <p><c>Value</c> is a list of nodes that <c>Mnesia</c>
+ is to try to connect to. <c>ReturnValue</c> is those
+ nodes in <c>Value</c> that <c>Mnesia</c> is connected
+ to.</p>
+ <p>Notice that this function must only be used to connect
+ to newly started RAM nodes (N.D.R.S.N.) with an empty
+ schema. If, for example, this function is used after
+ the network has been partitioned, it can lead to
+ inconsistent tables.</p>
+ <p>Notice that <c>Mnesia</c> can be connected to other
+ nodes than those returned in <c>ReturnValue</c>.</p>
</item>
<tag><c>dc_dump_limit</c></tag>
<item>
- <p><c>Value</c> is a number. See description in
- <c>Configuration Parameters</c> below.
- The <c>ReturnValue</c> is the new value. Note this configuration parameter
- is not persistent, it will be lost when mnesia stopped.</p>
+ <p><c>Value</c> is a number. See the description in
+ <seealso marker="#configuration_parameters">Section
+ Configuration Parameters</seealso>. <c>ReturnValue</c>
+ is the new value. Notice that this configuration
+ parameter is not persistent. It is lost when
+ <c>Mnesia</c> has stopped.</p>
</item>
</taglist>
</desc>
</func>
<func>
<name>change_table_access_mode(Tab, AccessMode) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Change the access mode for the table.</fsummary>
- <desc>
- <p>The <c>AcccessMode</c> is by default the atom
- <c>read_write</c> but it may also be set to the atom
- <c>read_only</c>. If the <c>AccessMode</c> is set to
- <c>read_only</c>, it means that it is not possible to perform
- updates to the table. At startup Mnesia always loads
+ <fsummary>Changes the access mode for the table.</fsummary>
+ <desc>
+ <marker id="change_table_access_mode"></marker>
+ <p><c>AcccessMode</c> is by default the atom
+ <c>read_write</c> but it can also be set to the atom
+ <c>read_only</c>. If <c>AccessMode</c> is set to
+ <c>read_only</c>, updates to the table cannot be
+ performed. At startup, <c>Mnesia</c> always loads
<c>read_only</c> tables locally regardless of when and if
- Mnesia was terminated on other nodes.</p>
+ <c>Mnesia</c> is terminated on other nodes.</p>
</desc>
</func>
<func>
<name>change_table_copy_type(Tab, Node, To) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Change the storage type of a table.</fsummary>
+ <fsummary>Changes the storage type of a table.</fsummary>
<desc>
+ <marker id="change_table_copy_type"></marker>
<p>For example:</p>
<code type="none">
-mnesia:change_table_copy_type(person, node(), disc_copies)
- </code>
- <p>Transforms our <c>person</c> table from a RAM table into
- a disc based table at <c>Node</c>.
- </p>
- <p>This function can also be used to change the storage type of
- the table named <c>schema</c>. The schema table can only
- have <c>ram_copies</c> or <c>disc_copies</c> as the storage type. If the
- storage type of the schema is <c>ram_copies</c>, no other table
- can be disc resident on that node.</p>
+mnesia:change_table_copy_type(person, node(), disc_copies)</code>
+ <p>Transforms the <c>person</c> table from a RAM table into
+ a disc-based table at <c>Node</c>.</p>
+ <p>This function can also be used to change the storage type
+ of the table named <c>schema</c>. The schema table can only
+ have <c>ram_copies</c> or <c>disc_copies</c> as the storage
+ type. If the storage type of the schema is <c>ram_copies</c>,
+ no other table can be disc-resident on that node.</p>
</desc>
</func>
<func>
<name>change_table_load_order(Tab, LoadOrder) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Change the load order priority for the table.</fsummary>
+ <fsummary>Changes the load order priority for the table.</fsummary>
<desc>
+ <marker id="change_table_load_order"></marker>
<p>The <c>LoadOrder</c> priority is by default <c>0</c> (zero)
- but may be set to any integer. The tables with the highest
- <c>LoadOrder</c> priority will be loaded first at startup.</p>
+ but can be set to any integer. The tables with the highest
+ <c>LoadOrder</c> priority are loaded first at startup.</p>
</desc>
</func>
<func>
<name>change_table_majority(Tab, Majority) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Change the majority check setting for the table.</fsummary>
+ <fsummary>Changes the majority check setting for the table.</fsummary>
<desc>
- <p><c>Majority</c> must be a boolean; the default is <c>false</c>.
- When <c>true</c>, a majority of the table's replicas must be available
- for an update to succeed. When used on fragmented tables, <c>Tab</c>
- must be the name base table. Directly changing the majority setting on
- individual fragments is not allowed.</p>
+ <p><c>Majority</c> must be a boolean. Default is <c>false</c>.
+ When <c>true</c>, a majority of the table replicas must be
+ available for an update to succeed. When used on fragmented
+ tables, <c>Tab</c> must be the base table name. Directly
+ changing the majority setting on individual fragments is
+ not allowed.</p>
</desc>
</func>
<func>
<name>clear_table(Tab) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Deletes all entries in a table.</fsummary>
<desc>
+ <marker id="clear_table"></marker>
<p>Deletes all entries in the table <c>Tab</c>.</p>
</desc>
</func>
<func>
<name>create_schema(DiscNodes) -> ok | {error,Reason}</name>
- <fsummary>Create a brand new schema on the specified nodes.</fsummary>
+ <fsummary>Creates a new schema on the specified nodes.</fsummary>
<desc>
+ <marker id="create_schema"></marker>
<p>Creates a new database on disc. Various files are
- created in the local Mnesia directory of each node. Note
- that the directory must be unique for each node. Two nodes
- may never share the same directory. If possible, use a local
- disc device in order to improve performance.</p>
+ created in the local <c>Mnesia</c> directory of each node.
+ Notice that the directory must be unique for each node.
+ Two nodes must never share the same directory. If possible,
+ use a local disc device to improve performance.</p>
<p><c>mnesia:create_schema/1</c> fails if any of the
Erlang nodes given as <c>DiscNodes</c> are not alive, if
- Mnesia is running on anyone of the nodes, or if anyone of
- the nodes already has a schema. Use
+ <c>Mnesia</c> is running on any of the nodes, or if any
+ of the nodes already have a schema. Use
<c>mnesia:delete_schema/1</c> to get rid of old faulty
- schemas.
- </p>
- <p><em>Note:</em> Only nodes with disc should be
- included in <c>DiscNodes</c>. Disc-less nodes, that is nodes
- where all tables including the schema only resides in RAM,
- may not be included.</p>
+ schemas.</p>
+ <p>Notice that only nodes with disc are to be included in
+ <c>DiscNodes</c>. Disc-less nodes, that is, nodes where
+ all tables including the schema only resides in RAM,
+ must not be included.</p>
</desc>
</func>
<func>
<name>create_table(Name, TabDef) -> {atomic, ok} | {aborted, Reason}</name>
- <fsummary>Create a Mnesia table called <c>Name</c>with properties as described by the argument <c>TabDef</c>.</fsummary>
+ <fsummary>Creates a <c>Mnesia</c> table called <c>Name</c>with properties as described by argument <c>TabDef</c>.</fsummary>
<desc>
- <p>This function creates a Mnesia table called <c>Name</c>
- according to the
- argument <c>TabDef</c>. This list must be a list of
- <c>{Item, Value}</c> tuples, where the following values are
- allowed:</p>
+ <marker id="create_table"></marker>
+ <p>Creates a <c>Mnesia</c> table called
+ <c>Name</c> according to argument <c>TabDef</c>. This
+ list must be a list of <c>{Item, Value}</c> tuples,
+ where the following values are allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access_mode, Atom}</c>. The access mode is by
- default the atom <c>read_write</c> but it may also be
- set to the atom <c>read_only</c>. If the
- <c>AccessMode</c> is set to <c>read_only</c>, it means
- that it is not possible to perform updates to the table.
- </p>
- <p>At startup Mnesia always loads <c>read_only</c> tables
- locally regardless of when and if Mnesia was terminated
- on other nodes. This argument returns the access mode of
- the table. The access mode may either be read_only or
- read_write.
- </p>
- </item>
- <item>
- <p><c>{attributes, AtomList}</c> a list of the
+ <p><c>{access_mode, Atom}</c>. The access mode is by
+ default the atom <c>read_write</c> but it can also be
+ set to the atom <c>read_only</c>. If <c>AccessMode</c>
+ is set to <c>read_only</c>, updates to the table
+ cannot be performed.</p>
+ <p>At startup, <c>Mnesia</c> always loads <c>read_only</c>
+ table locally regardless of when and if <c>Mnesia</c> is
+ terminated on other nodes. This argument returns the
+ access mode of the table. The access mode can be
+ <c>read_only</c> or <c>read_write</c>.</p>
+ </item>
+ <item>
+ <p><c>{attributes, AtomList}</c> is a list of the
attribute names for the records that are supposed to
- populate the table. The default value is <c>[key, val]</c>. The table must have at least one extra
- attribute in addition to the key.
- </p>
- <p>When accessing single attributes in a record, it is not
- necessary, or even recommended, to hard code any
- attribute names as atoms. Use the construct
- <c>record_info(fields, RecordName)</c> instead. It can be
- used for records of type <c>RecordName</c></p>
+ populate the table. Default is <c>[key, val]</c>.
+ The table must at least have one extra attribute in
+ addition to the key.</p>
+ <p>When accessing single attributes in a record, it is
+ not necessary, or even recommended, to hard code any
+ attribute names as atoms. Use construct
+ <c>record_info(fields, RecordName)</c> instead. It can
+ be used for records of type <c>RecordName</c>.</p>
</item>
<item>
<p><c>{disc_copies, Nodelist}</c>, where
<c>Nodelist</c> is a list of the nodes where this table
- is supposed to have disc copies. If a table replica is
+ is supposed to have disc copies. If a table replica is
of type <c>disc_copies</c>, all write operations on this
- particular replica of the table are written to disc as
- well as to the RAM copy of the table.
- </p>
- <p>It is possible
- to have a replicated table of type <c>disc_copies</c>
- on one node, and another type on another node. The
- default value is <c>[]</c></p>
+ particular replica of the table are written to disc and
+ to the RAM copy of the table.</p>
+ <p>It is possible to have a replicated table of type
+ <c>disc_copies</c> on one node and another type on
+ another node. Default is <c>[]</c>.</p>
</item>
<item>
<p><c>{disc_only_copies, Nodelist}</c>, where
<c>Nodelist</c> is a list of the nodes where this table
- is supposed to have <c>disc_only_copies</c>. A disc only
- table replica is kept on disc only and unlike the other
- replica types, the contents of the replica will not
+ is supposed to have <c>disc_only_copies</c>. A disc only
+ table replica is kept on disc only and unlike the other
+ replica types, the contents of the replica do not
reside in RAM. These replicas are considerably slower
- than replicas held in RAM.
- </p>
+ than replicas held in RAM.</p>
</item>
<item>
<p><c>{index, Intlist}</c>, where
<c>Intlist</c> is a list of attribute names (atoms) or
- record fields for which Mnesia shall build and maintain
- an extra index table. The <c>qlc</c> query compiler may
- or may not utilize any additional indices while
- processing queries on a table.
- </p>
+ record fields for which <c>Mnesia</c> is to build and
+ maintain an extra index table. The <c>qlc</c> query
+ compiler <em>may</em> be able to optimize queries
+ if there are indexes available.</p>
</item>
<item>
<p><c>{load_order, Integer}</c>. The load order
- priority is by default <c>0</c> (zero) but may be set to
- any integer. The tables with the highest load order
- priority will be loaded first at startup.
- </p>
- </item>
- <item>
- <p><c>{majority, Flag}</c>, where <c>Flag</c> must be a boolean.
- If <c>true</c>, any (non-dirty) update to the table will abort unless
- a majority of the table's replicas are available for the commit.
- When used on a fragmented table, all fragments will be given
- the same majority setting.
- </p>
- </item>
+ priority is by default <c>0</c> (zero) but can be set
+ to any integer. The tables with the highest load order
+ priority are loaded first at startup.</p>
+ </item>
+ <item>
+ <p><c>{majority, Flag}</c>, where <c>Flag</c> must be a
+ boolean. If <c>true</c>, any (non-dirty) update to the
+ table is aborted, unless a majority of the table
+ replicas are available for the commit. When used on a
+ fragmented table, all fragments are given the same
+ the same majority setting.</p>
+ </item>
<item>
<p><c>{ram_copies, Nodelist}</c>, where
<c>Nodelist</c> is a list of the nodes where this table
- is supposed to have RAM copies. A table replica of type
- <c>ram_copies</c> is obviously not written to disc on a
- per transaction basis. It is possible to dump
- <c>ram_copies</c> replicas to disc with the function
- <c>mnesia:dump_tables(Tabs)</c>. The default value for
- this attribute is <c>[node()]</c>.
- </p>
+ is supposed to have RAM copies. A table replica of type
+ <c>ram_copies</c> is not written to disc on a per
+ transaction basis. <c>ram_copies</c> replicas can be
+ dumped to disc with the function
+ <c>mnesia:dump_tables(Tabs)</c>. Default value for
+ this attribute is <c>[node()]</c>.</p>
</item>
<item>
<p><c>{record_name, Name}</c>, where <c>Name</c> must
- be an atom. All records, stored in the table, must have
+ be an atom. All records stored in the table must have
this name as the first element. It defaults to the same
- name as the name of the table.
- </p>
- </item>
- <item>
- <p><c>{snmp, SnmpStruct}</c>. See
- <c>mnesia:snmp_open_table/2</c> for a description of
- <c>SnmpStruct</c>. If this attribute is present in the
- <c>ArgList</c> to <c>mnesia:create_table/2</c>, the
- table is immediately accessible by means of the Simple
- Network Management Protocol (SNMP). This means that
- applications which use SNMP to manipulate and control
- the system can be designed easily, since Mnesia provides
- a direct mapping between the logical tables that make up
- an SNMP control application and the physical data which
- makes up a Mnesia table.
- </p>
- </item>
- <item>
- <p><c>{storage_properties, [{Backend, Properties}]</c>.
- Forwards additional properties to the backend storage.
- <c>Backend</c> can currently be <c>ets</c> or <c>dets</c> and
- <c>Properties</c> is a list of options sent to the backend storage
- during table creation. <c>Properties</c> may not contain properties
- already used by mnesia such as <c>type</c> or <c>named_table</c>.
- </p>
- <p>For example:</p>
- <code type="none">
+ name as the table name.</p>
+ </item>
+ <item>
+ <p><c>{snmp, SnmpStruct}</c>. For a description of
+ <c>SnmpStruct</c>, see <c>mnesia:snmp_open_table/2</c>.
+ If this attribute is present in <c>ArgList</c> to
+ <c>mnesia:create_table/2</c>, the table is immediately
+ accessible by SNMP. Therefore applications that use
+ SNMP to manipulate and control the system can be
+ designed easily, since <c>Mnesia</c> provides a
+ direct mapping between the logical tables that make up
+ an SNMP control application and the physical data that
+ makes up a <c>Mnesia</c> table.</p>
+ </item>
+ <item>
+ <p><c>{storage_properties, [{Backend, Properties}]</c>
+ forwards more properties to the back end storage.
+ <c>Backend</c> can currently be <c>ets</c> or <c>dets</c>.
+ <c>Properties</c> is a list of options sent to the
+ back end storage during table creation. <c>Properties</c>
+ cannot contain properties already used by <c>Mnesia</c>,
+ such as <c>type</c> or <c>named_table</c>.</p>
+ <p>For example:</p>
+ <code type="none">
mnesia:create_table(table, [{ram_copies, [node()]}, {disc_only_copies, nodes()},
- {storage_properties,
- [{ets, [compressed]}, {dets, [{auto_save, 5000}]} ]}])
- </code>
+ {storage_properties,
+ [{ets, [compressed]}, {dets, [{auto_save, 5000}]} ]}])</code>
</item>
<item>
<p><c>{type, Type}</c>, where <c>Type</c> must be
- either of the atoms <c>set</c>, <c>ordered_set</c> or
- <c>bag</c>. The default value is <c>set</c>. In a
- <c>set</c> all records have unique keys and in a
- <c>bag</c> several records may have the same key, but
+ either of the atoms <c>set</c>, <c>ordered_set</c>, or
+ <c>bag</c>. Default is <c>set</c>. In a
+ <c>set</c>, all records have unique keys. In a
+ <c>bag</c>, several records can have the same key, but
the record content is unique. If a non-unique record is
- stored the old, conflicting record(s) will simply be
- overwritten. Note: currently 'ordered_set'
- is not supported for 'disc_only_copies'.
- </p>
+ stored, the old conflicting records are overwritten.</p>
+ <p>Notice that currently <c>ordered_set</c> is not
+ supported for <c>disc_only_copies</c>.</p>
</item>
<item>
- <p><c>{local_content, Bool}</c>, where <c>Bool</c> must be
- either <c>true</c> or <c>false</c>. The default value is <c>false</c>.</p>
+ <p><c>{local_content, Bool}</c>, where <c>Bool</c> is
+ <c>true</c> or <c>false</c>. Default is <c>false</c>.</p>
</item>
</list>
- <p>For example, the following call creates the <c>person</c> table
- previously defined and replicates it on 2 nodes:
- </p>
+ <p>For example, the following call creates the <c>person</c>
+ table (defined earlier) and replicates it on two nodes:</p>
<code type="none">
-mnesia:create_table(person,
+mnesia:create_table(person,
[{ram_copies, [N1, N2]},
- {attributes, record_info(fields,person)}]).
- </code>
- <p>If it was required that Mnesia build and maintain an extra index
- table on the <c>address</c> attribute of all the <c>person</c>
- records that are inserted in the table, the following code would be issued:
- </p>
+ {attributes, record_info(fields, person)}]).</code>
+ <p>If it is required that <c>Mnesia</c> must build and
+ maintain an extra index table on attribute <c>address</c>
+ of all the <c>person</c> records that are inserted in the
+ table, the following code would be issued:</p>
<code type="none">
mnesia:create_table(person,
[{ram_copies, [N1, N2]},
{index, [address]},
- {attributes, record_info(fields,person)}]).
- </code>
- <p>The specification of <c>index</c> and <c>attributes</c> may be
- hard coded as <c>{index, [4]}</c> and
- <c>{attributes, [name, age, address, salary, children]}</c>
- respectively.
- </p>
+ {attributes, record_info(fields, person)}]).
+ </code>
+ <p>The specification of <c>index</c> and <c>attributes</c>
+ can be hard-coded as <c>{index, [2]}</c> and
+ <c>{attributes, [name, age, address, salary, children]}</c>,
+ respectively.</p>
<p><c>mnesia:create_table/2</c> writes records into the
- <c>schema</c> table. This function, as well as all other
+ table <c>schema</c>. This function, and all other
schema manipulation functions, are implemented with the
normal transaction management system. This guarantees that
schema updates are performed on all nodes in an atomic
@@ -877,163 +800,169 @@ mnesia:create_table(person,
</func>
<func>
<name>deactivate_checkpoint(Name) -> ok | {error, Reason}</name>
- <fsummary>Deactivate a checkpoint.</fsummary>
+ <fsummary>Deactivates a checkpoint.</fsummary>
<desc>
+ <marker id="deactivate_checkpoint"></marker>
<p>The checkpoint is automatically deactivated when some of
- the tables involved have no retainer attached to them. This may
- happen when nodes go down or when a replica is deleted.
- Checkpoints will also be deactivated with this function.
+ the tables involved have no retainer attached to them. This
+ can occur when nodes go down or when a replica is deleted.
+ Checkpoints are also deactivated with this function.
<c>Name</c> is the name of an active checkpoint.</p>
</desc>
</func>
<func>
<name>del_table_copy(Tab, Node) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Delete the replica of table <c>Tab</c>at node <c>Node</c>.</fsummary>
+ <fsummary>Deletes the replica of table <c>Tab</c> at node <c>Node</c>.</fsummary>
<desc>
+ <marker id="del_table_copy"></marker>
<p>Deletes the replica of table <c>Tab</c> at node <c>Node</c>.
When the last replica is deleted with this
- function, the table disappears entirely.
- </p>
- <p>This function may also be used to delete a replica of
- the table named <c>schema</c>. Then the mnesia node will be removed.
- Note: Mnesia must be stopped on the node first.</p>
+ function, the table disappears entirely.</p>
+ <p>This function can also be used to delete a replica of
+ the table named <c>schema</c>. The <c>Mnesia</c> node is
+ then removed. Notice that <c>Mnesia</c> must be
+ stopped on the node first.</p>
</desc>
</func>
<func>
<name>del_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Delete an index in a table. </fsummary>
+ <fsummary>Deletes an index in a table.</fsummary>
<desc>
- <p>This function deletes the index on attribute with name
+ <marker id="del_table_index"></marker>
+ <p>Deletes the index on attribute with name
<c>AttrName</c> in a table.</p>
</desc>
</func>
<func>
- <name>delete({Tab, Key}) -> transaction abort | ok </name>
- <fsummary>Delete all records in table <c>Tab</c>with the key <c>Key</c>.</fsummary>
+ <name>delete({Tab, Key}) -> transaction abort | ok</name>
+ <fsummary>Deletes all records in table <c>Tab</c> with the key <c>Key</c>.</fsummary>
<desc>
- <p>Invokes <c>mnesia:delete(Tab, Key, write)</c></p>
+ <marker id="delete_2"></marker>
+ <p>Calls <c>mnesia:delete(Tab, Key, write)</c>.</p>
</desc>
</func>
<func>
- <name>delete(Tab, Key, LockKind) -> transaction abort | ok </name>
- <fsummary>Delete all records in table <c>Tab</c>with the key <c>Key</c>.</fsummary>
+ <name>delete(Tab, Key, LockKind) -> transaction abort | ok</name>
+ <fsummary>Deletes all records in table <c>Tab</c>with the key <c>Key</c>.</fsummary>
<desc>
+ <marker id="delete_3"></marker>
<p>Deletes all records in table <c>Tab</c> with the key
- <c>Key</c>.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a lock of type <c>LockKind</c> in the
- record. Currently the lock types <c>write</c> and
+ <c>Key</c>.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a lock of type
+ <c>LockKind</c> in the record.
+ Currently, the lock types <c>write</c> and
<c>sticky_write</c> are supported.</p>
</desc>
</func>
<func>
- <name>delete_object(Record) -> transaction abort | ok </name>
- <fsummary>Delete a record</fsummary>
+ <name>delete_object(Record) -> transaction abort | ok</name>
+ <fsummary>Delete a record.</fsummary>
<desc>
- <p>Invokes <c>mnesia:delete_object(Tab, Record, write)</c> where
+ <marker id="delete_object_1"></marker>
+ <p>Calls <c>mnesia:delete_object(Tab, Record, write)</c>, where
<c>Tab</c> is <c>element(1, Record)</c>.</p>
</desc>
</func>
<func>
- <name>delete_object(Tab, Record, LockKind) -> transaction abort | ok </name>
- <fsummary>Delete a record</fsummary>
+ <name>delete_object(Tab, Record, LockKind) -> transaction abort | ok</name>
+ <fsummary>Deletes a record.</fsummary>
<desc>
- <p>If a table is of type <c>bag</c>, we may sometimes
- want to delete only some of the records with a certain
- key. This can be done with the <c>delete_object/3</c>
- function. A complete record must be supplied to this
- function.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a lock of type <c>LockKind</c> on the
- record. Currently the lock types <c>write</c> and
+ <marker id="delete_object_3"></marker>
+ <p>If a table is of type <c>bag</c>, it can sometimes be
+ needed to delete only some of the records with a certain
+ key. This can be done with the function <c>delete_object/3</c>.
+ A complete record must be supplied to this function.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a lock of type
+ <c>LockKind</c> on the record.
+ Currently, the lock types <c>write</c> and
<c>sticky_write</c> are supported.</p>
</desc>
</func>
<func>
<name>delete_schema(DiscNodes) -> ok | {error,Reason}</name>
- <fsummary>Delete the schema on the given nodes</fsummary>
+ <fsummary>Deletes the schema on the given nodes.</fsummary>
<desc>
+ <marker id="delete_schema"></marker>
<p>Deletes a database created with
<c>mnesia:create_schema/1</c>.
<c>mnesia:delete_schema/1</c> fails if any of the Erlang
- nodes given as <c>DiscNodes</c> is not alive, or if Mnesia
- is running on any of the nodes.
- </p>
- <p>After the database has been deleted, it may still be
- possible to start Mnesia as a disc-less node. This depends on
- how the configuration parameter <c>schema_location</c> is set.
- </p>
+ nodes given as <c>DiscNodes</c> are not alive, or if
+ <c>Mnesia</c> is running on any of the nodes.</p>
+ <p>After the database is deleted, it can still be possible
+ to start <c>Mnesia</c> as a disc-less node. This depends
+ on how configuration parameter <c>schema_location</c> is
+ set.</p>
<warning>
- <p>This function must be used with extreme
- caution since it makes existing persistent data
- obsolete. Think twice before using it. </p>
+ <p>Use this function with extreme caution, as it makes
+ existing persistent data obsolete. Think twice before
+ using it.</p>
</warning>
</desc>
</func>
<func>
- <name>delete_table(Tab) -> {aborted, Reason} | {atomic, ok} </name>
- <fsummary>Delete permanently all replicas of table <c>Tab</c>.</fsummary>
+ <name>delete_table(Tab) -> {aborted, Reason} | {atomic, ok}</name>
+ <fsummary>Deletes permanently all replicas of table <c>Tab</c>.</fsummary>
<desc>
+ <marker id="delete_table"></marker>
<p>Permanently deletes all replicas of table <c>Tab</c>.</p>
</desc>
</func>
<func>
- <name>dirty_all_keys(Tab) -> KeyList | exit({aborted, Reason}).</name>
+ <name>dirty_all_keys(Tab) -> KeyList | exit({aborted, Reason})</name>
<fsummary>Dirty search for all record keys in table.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:all_keys/1</c> function.</p>
+ <marker id="delete_all_keys"></marker>
+ <p>Dirty equivalent of the function <c>mnesia:all_keys/1</c>.</p>
</desc>
</func>
<func>
- <name>dirty_delete({Tab, Key}) -> ok | exit({aborted, Reason}) </name>
+ <name>dirty_delete({Tab, Key}) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty delete of a record.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_delete(Tab, Key)</c>.</p>
+ <marker id="dirty_delete"></marker>
+ <p>Calls <c>mnesia:dirty_delete(Tab, Key)</c>.</p>
</desc>
</func>
<func>
- <name>dirty_delete(Tab, Key) -> ok | exit({aborted, Reason}) </name>
- <fsummary>Dirty delete of a record. </fsummary>
+ <name>dirty_delete(Tab, Key) -> ok | exit({aborted, Reason})</name>
+ <fsummary>Dirty delete of a record.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:delete/3</c> function.</p>
+ <p>Dirty equivalent of the function <c>mnesia:delete/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_delete_object(Record) </name>
+ <name>dirty_delete_object(Record)</name>
<fsummary>Dirty delete of a record.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_delete_object(Tab, Record)</c>
+ <marker id="dirty_delete_object_1"></marker>
+ <p>Calls <c>mnesia:dirty_delete_object(Tab, Record)</c>,
where <c>Tab</c> is <c>element(1, Record)</c>.</p>
</desc>
</func>
<func>
- <name>dirty_delete_object(Tab, Record) </name>
- <fsummary>Dirty delete of a record. </fsummary>
+ <name>dirty_delete_object(Tab, Record)</name>
+ <fsummary>Dirty delete of a record.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:delete_object/3</c> function.</p>
+ <p>Dirty equivalent of the function <c>mnesia:delete_object/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_first(Tab) -> Key | exit({aborted, Reason}) </name>
- <fsummary>Return the key for the first record in a table.</fsummary>
+ <name>dirty_first(Tab) -> Key | exit({aborted, Reason})</name>
+ <fsummary>Returns the key for the first record in a table.</fsummary>
<desc>
+ <marker id="dirty_first"></marker>
<p>Records in <c>set</c> or <c>bag</c> tables are not ordered.
- However, there
- is an ordering of the records which is not known
- to the user. Accordingly, it is possible to traverse a table by means
- of this function in conjunction with the <c>mnesia:dirty_next/2</c>
- function.
+ However, there is an ordering of the records that is unknown
+ to the user. Therefore, a table can be traversed by this
+ function with the function <c>mnesia:dirty_next/2</c>.
</p>
- <p>If there are no records at all in the table, this function
- returns the atom <c>'$end_of_table'</c>. For this reason, it
- is highly undesirable, but not disallowed, to use this atom
+ <p>If there are no records in the table, this function
+ returns the atom <c>'$end_of_table'</c>. It is therefore
+ highly undesirable, but not disallowed, to use this atom
as the key for any user records.</p>
</desc>
</func>
@@ -1041,74 +970,82 @@ mnesia:create_table(person,
<name>dirty_index_match_object(Pattern, Pos)</name>
<fsummary>Dirty pattern match using index.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_index_match_object(Tab, Pattern, Pos)</c> where <c>Tab</c> is <c>element(1, Pattern)</c>.</p>
+ <marker id="dirty_index_match_object_2"></marker>
+ <p>Starts
+ <c>mnesia:dirty_index_match_object(Tab, Pattern, Pos)</c>,
+ where <c>Tab</c> is <c>element(1, Pattern)</c>.</p>
</desc>
</func>
<func>
<name>dirty_index_match_object(Tab, Pattern, Pos)</name>
<fsummary>Dirty pattern match using index.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:index_match_object/4</c> function.</p>
+ <p>Dirty equivalent of the function
+ <c>mnesia:index_match_object/4</c>.</p>
</desc>
</func>
<func>
<name>dirty_index_read(Tab, SecondaryKey, Pos)</name>
<fsummary>Dirty read using index.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:index_read/3</c> function.</p>
+ <marker id="dirty_index_read"></marker>
+ <p>Dirty equivalent of the function
+ <c>mnesia:index_read/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_last(Tab) -> Key | exit({aborted, Reason}) </name>
- <fsummary>Return the key for the last record in a table.</fsummary>
+ <name>dirty_last(Tab) -> Key | exit({aborted, Reason})</name>
+ <fsummary>Returns the key for the last record in a table.</fsummary>
<desc>
- <p>This function works exactly like
- <c>mnesia:dirty_first/1</c> but returns the last object in
- Erlang term order for the <c>ordered_set</c> table type. For
- all other table types, <c>mnesia:dirty_first/1</c> and
+ <marker id="dirty_last"></marker>
+ <p>Works exactly like <c>mnesia:dirty_first/1</c> but returns
+ the last object in Erlang term order for the <c>ordered_set</c>
+ table type. For all other table types,
+ <c>mnesia:dirty_first/1</c> and
<c>mnesia:dirty_last/1</c> are synonyms.</p>
</desc>
</func>
<func>
- <name>dirty_match_object(Pattern) -> RecordList | exit({aborted, Reason}).</name>
+ <name>dirty_match_object(Pattern) -> RecordList | exit({aborted, Reason})</name>
<fsummary>Dirty pattern match pattern.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_match_object(Tab, Pattern)</c>
+ <marker id="dirty_match_object_1"></marker>
+ <p>Calls <c>mnesia:dirty_match_object(Tab, Pattern)</c>,
where <c>Tab</c> is <c>element(1, Pattern)</c>.</p>
</desc>
</func>
<func>
- <name>dirty_match_object(Tab, Pattern) -> RecordList | exit({aborted, Reason}).</name>
+ <name>dirty_match_object(Tab, Pattern) -> RecordList | exit({aborted, Reason})</name>
<fsummary>Dirty pattern match pattern.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:match_object/3</c> function.</p>
+ <p>Dirty equivalent of the function
+ <c>mnesia:match_object/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_next(Tab, Key) -> Key | exit({aborted, Reason}) </name>
- <fsummary>Return the next key in a table. </fsummary>
+ <name>dirty_next(Tab, Key) -> Key | exit({aborted, Reason})</name>
+ <fsummary>Return the next key in a table.</fsummary>
<desc>
- <p>This function makes it possible to traverse a table
- and perform operations on all records in the table. When
- the end of the table is reached, the special key
+ <marker id="dirty_next"></marker>
+ <p>Traverses a table and
+ performs operations on all records in the table.
+ When the end of the table is reached, the special key
<c>'$end_of_table'</c> is returned. Otherwise, the function
- returns a key which can be used to read the actual record.The
+ returns a key that can be used to read the actual record. The
behavior is undefined if another Erlang process performs write
operations on the table while it is being traversed with the
- <c>mnesia:dirty_next/2</c> function.</p>
+ function <c>mnesia:dirty_next/2</c>.</p>
</desc>
</func>
<func>
- <name>dirty_prev(Tab, Key) -> Key | exit({aborted, Reason}) </name>
- <fsummary>Return the previous key in a table. </fsummary>
+ <name>dirty_prev(Tab, Key) -> Key | exit({aborted, Reason})</name>
+ <fsummary>Returns the previous key in a table.</fsummary>
<desc>
- <p>This function works exactly like
- <c>mnesia:dirty_next/2</c> but returns the previous object in
- Erlang term order for the ordered_set table type. For
- all other table types, <c>mnesia:dirty_next/2</c> and
+ <marker id="dirty_prev"></marker>
+ <p>Works exactly like <c>mnesia:dirty_next/2</c> but returns
+ the previous object in Erlang term order for the
+ <c>ordered_set</c> table type. For all other table types,
+ <c>mnesia:dirty_next/2</c> and
<c>mnesia:dirty_prev/2</c> are synonyms.</p>
</desc>
</func>
@@ -1116,33 +1053,34 @@ mnesia:create_table(person,
<name>dirty_read({Tab, Key}) -> ValueList | exit({aborted, Reason}</name>
<fsummary>Dirty read of records.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_read(Tab, Key)</c>.</p>
+ <marker id="dirty_read"></marker>
+ <p>Calls <c>mnesia:dirty_read(Tab, Key)</c>.</p>
</desc>
</func>
<func>
<name>dirty_read(Tab, Key) -> ValueList | exit({aborted, Reason}</name>
<fsummary>Dirty read of records.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:read/3</c> function.</p>
+ <p>Dirty equivalent of the function <c>mnesia:read/3</c>.</p>
</desc>
</func>
<func>
<name>dirty_select(Tab, MatchSpec) -> ValueList | exit({aborted, Reason}</name>
- <fsummary>Dirty match the objects in <c>Tab</c>against <c>MatchSpec</c>.</fsummary>
+ <fsummary>Dirty matches the objects in <c>Tab</c> against <c>MatchSpec</c>.</fsummary>
<desc>
- <p>This is the dirty equivalent of the
- <c>mnesia:select/2</c> function.</p>
+ <marker id="dirty_select"></marker>
+ <p>Dirty equivalent of the function <c>mnesia:select/2</c>.</p>
</desc>
</func>
<func>
<name>dirty_slot(Tab, Slot) -> RecordList | exit({aborted, Reason})</name>
- <fsummary>Return the list of records that are associated with Slot in a table.</fsummary>
+ <fsummary>Returns the list of records that are associated with <c>Slot</c> in a table.</fsummary>
<desc>
- <p>This function can be used to traverse a table in a
- manner similar to the <c>mnesia:dirty_next/2</c> function.
- A table has a number of slots which range from 0 (zero) to some
- unknown upper bound. The function
+ <marker id="dirty_slot"></marker>
+ <p>Traverses a table in a
+ manner similar to the function <c>mnesia:dirty_next/2</c>.
+ A table has a number of slots that range from 0 (zero) to
+ an unknown upper bound. The function
<c>mnesia:dirty_slot/2</c> returns the special atom
<c>'$end_of_table'</c> when the end of the table is reached.
The behavior of this function is undefined if a write
@@ -1154,40 +1092,45 @@ mnesia:create_table(person,
<name>dirty_update_counter({Tab, Key}, Incr) -> NewVal | exit({aborted, Reason})</name>
<fsummary>Dirty update of a counter record.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_update_counter(Tab, Key, Incr)</c>.</p>
+ <marker id="dirty_update_counter"></marker>
+ <p>Calls <c>mnesia:dirty_update_counter(Tab, Key, Incr)</c>.</p>
</desc>
</func>
<func>
<name>dirty_update_counter(Tab, Key, Incr) -> NewVal | exit({aborted, Reason})</name>
<fsummary>Dirty update of a counter record.</fsummary>
<desc>
- <p>There are no special counter records in Mnesia. However,
+ <p><c>Mnesia</c> has no special counter records. However,
records of the form <c>{Tab, Key, Integer}</c> can be used
- as (possibly disc resident) counters, when <c>Tab</c> is a
- <c>set</c>. This function updates a counter with a
- positive or negative number. However, counters can never become less
+ as (possibly disc-resident) counters when <c>Tab</c> is a
+ <c>set</c>. This function updates a counter with a positive
+ or negative number. However, counters can never become less
than zero. There are two significant differences between
this function and the action of first reading the record,
performing the arithmetics, and then writing the record:</p>
<list type="bulleted">
- <item>It is much more efficient</item>
- <item><c>mnesia:dirty_update_counter/3</c> is
- performed as an atomic operation despite the fact that it is not
- protected by a transaction.</item>
+ <item>It is much more efficient.
+ </item>
+ <item><c>mnesia:dirty_update_counter/3</c> is performed
+ as an atomic operation although it is not protected
+ by a transaction.
+ </item>
</list>
<p>If two processes perform <c>mnesia:dirty_update_counter/3</c>
- simultaneously, both updates will take effect without the
+ simultaneously, both updates take effect without the
risk of losing one of the updates. The new value
<c>NewVal</c> of the counter is returned.</p>
- <p>If <c>Key</c> don't exits, a new record is created with the value
- <c>Incr</c> if it is larger than 0, otherwise it is set to 0.</p>
+ <p>If <c>Key</c> do not exists, a new record is created with
+ value <c>Incr</c> if it is larger than 0, otherwise it is
+ set to 0.</p>
</desc>
</func>
<func>
<name>dirty_write(Record) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty write of a record.</fsummary>
<desc>
- <p>Invokes <c>mnesia:dirty_write(Tab, Record)</c>
+ <marker id="dirty_write_1"></marker>
+ <p>Calls <c>mnesia:dirty_write(Tab, Record)</c>,
where <c>Tab</c> is <c>element(1, Record)</c>.</p>
</desc>
</func>
@@ -1195,623 +1138,607 @@ mnesia:create_table(person,
<name>dirty_write(Tab, Record) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty write of a record.</fsummary>
<desc>
- <p>This is the dirty equivalent of <c>mnesia:write/3</c>.</p>
+ <p>Dirty equivalent of the function <c>mnesia:write/3</c>.</p>
</desc>
</func>
<func>
<name>dump_log() -> dumped</name>
- <fsummary>Perform a user initiated dump of the local log file.</fsummary>
+ <fsummary>Performs a user-initiated dump of the local log file.</fsummary>
<desc>
- <p>Performs a user initiated dump of the local log file.
- This is usually not necessary since Mnesia, by default,
- manages this automatically.
- See configuration parameters
- <seealso marker="#dump_log_time_threshold">dump_log_time_threshold</seealso> and
- <seealso marker="#dump_log_write_threshold">dump_log_write_threshold</seealso>.
- </p>
+ <marker id="dump_log"></marker>
+ <p>Performs a user-initiated dump of the local log file.
+ This is usually not necessary, as <c>Mnesia</c> by default
+ manages this automatically. See configuration parameters
+ <seealso marker="#dump_log_time_threshold">dump_log_time_threshold</seealso>
+ and
+ <seealso marker="#dump_log_write_threshold">dump_log_write_threshold</seealso>.
+ </p>
</desc>
</func>
<func>
<name>dump_tables(TabList) -> {atomic, ok} | {aborted, Reason}</name>
- <fsummary>Dump all RAM tables to disc.</fsummary>
+ <fsummary>Dumps all RAM tables to disc.</fsummary>
<desc>
- <p>This function dumps a set of <c>ram_copies</c> tables
+ <marker id="dump_tables"></marker>
+ <p>Dumps a set of <c>ram_copies</c> tables
to disc. The next time the system is started, these tables
are initiated with the data found in the files that are the
- result of this dump. None of the tables may have disc
- resident replicas.</p>
+ result of this dump. None of the tables can have
+ disc-resident replicas.</p>
</desc>
</func>
<func>
- <name>dump_to_textfile(Filename) </name>
- <fsummary>Dump local tables into a text file.</fsummary>
+ <name>dump_to_textfile(Filename)</name>
+ <fsummary>Dumps local tables into a text file.</fsummary>
<desc>
- <p>Dumps all local tables of a mnesia system into a text file
- which can then be edited (by means of a normal text editor)
- and then later be reloaded with
+ <marker id="dump_to_textfile"></marker>
+ <p>Dumps all local tables of a <c>Mnesia</c> system into a
+ text file, which can be edited (by a normal text editor)
+ and then be reloaded with
<c>mnesia:load_textfile/1</c>. Only use this function for
educational purposes. Use other functions to deal with real
backups.</p>
</desc>
</func>
<func>
- <name>error_description(Error) -> String </name>
- <fsummary>Return a string describing a particular Mnesia error.</fsummary>
+ <name>error_description(Error) -> String</name>
+ <fsummary>Returns a string describing a particular <c>Mnesia</c> error.</fsummary>
<desc>
- <p>All Mnesia transactions, including all the schema
- update functions, either return the value <c>{atomic, Val}</c> or the tuple <c>{aborted, Reason}</c>. The
- <c>Reason</c> can be either of the following atoms. The
- <c>error_description/1</c> function returns a descriptive
- string which describes the error.
- </p>
+ <marker id="error_description"></marker>
+ <p>All <c>Mnesia</c> transactions, including all the schema
+ update functions, either return value <c>{atomic, Val}</c>
+ or the tuple <c>{aborted, Reason}</c>. <c>Reason</c> can
+ be either of the atoms in the following list. The
+ function <c>error_description/1</c> returns a descriptive
+ string that describes the error.</p>
<list type="bulleted">
- <item>
- <p><c>nested_transaction</c>. Nested transactions are
- not allowed in this context.
- </p>
+ <item><c>nested_transaction</c>. Nested transactions are
+ not allowed in this context.
</item>
- <item>
- <p><c>badarg</c>. Bad or invalid argument, possibly
- bad type.
- </p>
+ <item><c>badarg</c>. Bad or invalid argument, possibly
+ bad type.
</item>
- <item>
- <p><c>no_transaction</c>. Operation not allowed
- outside transactions.
- </p>
+ <item><c>no_transaction</c>. Operation not allowed
+ outside transactions.
</item>
- <item>
- <p><c>combine_error</c>. Table options were illegally
- combined.
- </p>
+ <item><c>combine_error</c>. Table options illegally
+ combined.
</item>
- <item>
- <p><c>bad_index</c>. Index already exists or was out
- of bounds.
- </p>
+ <item><c>bad_index</c>. Index already exists, or was out
+ of bounds.
</item>
- <item>
- <p><c>already_exists</c>. Schema option is already set.
- </p>
+ <item><c>already_exists</c>. Schema option to be activated
+ is already on.
</item>
- <item>
- <p><c>index_exists</c>. Some operations cannot be performed on
- tabs with index.
- </p>
+ <item><c>index_exists</c>. Some operations cannot be
+ performed on tables with an index.
</item>
- <item>
- <p><c>no_exists</c>. Tried to perform operation on
- non-existing, or not alive, item.
- </p>
+ <item><c>no_exists</c>. Tried to perform operation on
+ non-existing (not-alive) item.
</item>
- <item>
- <p><c>system_limit</c>. Some system_limit was exhausted.
- </p>
+ <item><c>system_limit</c>. A system limit was exhausted.
</item>
- <item>
- <p><c>mnesia_down</c>. A transaction involving
- records at some remote node which died while
- transaction was executing. Record(s) are no longer
- available elsewhere in the network.
- </p>
+ <item><c>mnesia_down</c>. A transaction involves records
+ on a remote node, which became unavailable before the
+ transaction was completed. Records are no longer
+ available elsewhere in the network.
</item>
- <item>
- <p><c>not_a_db_node</c>. A node which does not exist
- in the schema was mentioned.
- </p>
+ <item><c>not_a_db_node</c>. A node was mentioned that does
+ not exist in the schema.
</item>
- <item>
- <p><c>bad_type</c>. Bad type on some arguments.
- </p>
+ <item><c>bad_type</c>. Bad type specified in argument.
</item>
- <item>
- <p><c>node_not_running</c>. Node not running.
- </p>
+ <item><c>node_not_running</c>. Node is not running.
</item>
- <item>
- <p><c>truncated_binary_file</c>. Truncated binary in file.
- </p>
+ <item><c>truncated_binary_file</c>. Truncated binary in file.
</item>
- <item>
- <p><c>active</c>. Some delete operations require that
- all active records are removed.
- </p>
+ <item><c>active</c>. Some delete operations require that
+ all active records are removed.
</item>
- <item>
- <p><c>illegal</c>. Operation not supported on record.
- </p>
+ <item><c>illegal</c>. Operation not supported on this
+ record.
</item>
</list>
- <p>The <c>Error</c> may be <c>Reason</c>,
- <c>{error, Reason}</c>, or <c>{aborted, Reason}</c>. The
- <c>Reason</c> may be an atom or a tuple with <c>Reason</c>
+ <p><c>Error</c> can be <c>Reason</c>,
+ <c>{error, Reason}</c>, or <c>{aborted, Reason}</c>.
+ <c>Reason</c> can be an atom or a tuple with <c>Reason</c>
as an atom in the first field.</p>
+ <p>The following examples illustrate a function that returns an error,
+ and the method to retrieve more detailed error information:</p>
+ <list type="bulleted">
+ <item>The function
+ <seealso marker="#create_table/2">mnesia:create_table(bar, [{attributes, 3.14}])</seealso>
+ returns the tuple <c>{aborted,Reason}</c>, where <c>Reason</c> is
+ the tuple <c>{bad_type,bar,3.14000}</c>.</item>
+ <item>The function
+ <seealso marker="#error_description/1">mnesia:error_description(Reason)</seealso>
+ returns the term <c>{"Bad type on some provided
+ arguments",bar,3.14000}</c>, which is an error description
+ suitable for display.</item>
+ </list>
</desc>
</func>
<func>
<name>ets(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
- <fsummary>Call the Fun in a raw context which is not protected by a transaction.</fsummary>
+ <fsummary>Calls the <c>Fun</c> in a raw context that is not protected by a transaction.</fsummary>
<desc>
- <p>Call the <c>Fun</c> in a raw context which is not protected by
- a transaction. The Mnesia function call is performed in the
- <c>Fun</c> are performed directly on the local <c>ets</c> tables on
- the assumption that the local storage type is
+ <marker id="ets"></marker>
+ <p>Calls the <c>Fun</c> in a raw context that is not protected by
+ a transaction. The <c>Mnesia</c> function call is performed in
+ the <c>Fun</c> and performed directly on the local <c>ets</c>
+ tables on the assumption that the local storage type is
<c>ram_copies</c> and the tables are not replicated to other
nodes. Subscriptions are not triggered and checkpoints are
- not updated, but it is extremely fast. This function can
+ not updated, but it is extremely fast. This function can
also be applied to <c>disc_copies</c> tables if all
- operations are read only. See <c>mnesia:activity/4</c>
- and the Mnesia User's Guide for more details.</p>
- <p><em>Note:</em> Calling (nesting) a <c>mnesia:ets</c>
- inside a transaction context will inherit the transaction semantics.</p>
+ operations are read only. For details, see
+ <c>mnesia:activity/4</c> and the User's Guide.</p>
+ <p>Notice that calling (nesting) a <c>mnesia:ets</c> inside a
+ transaction-context inherits the transaction semantics.</p>
</desc>
</func>
<func>
- <name>first(Tab) -> Key | transaction abort </name>
- <fsummary>Return the key for the first record in a table.</fsummary>
+ <name>first(Tab) -> Key | transaction abort</name>
+ <fsummary>Returns the key for the first record in a table.</fsummary>
<desc>
- <p>Records in <c>set</c> or <c>bag</c> tables are not ordered.
- However, there
- is an ordering of the records which is not known
- to the user. Accordingly, it is possible to traverse a table by means
- of this function in conjunction with the <c>mnesia:next/2</c>
- function.
- </p>
- <p>If there are no records at all in the table, this function
- returns the atom <c>'$end_of_table'</c>. For this reason, it
- is highly undesirable, but not disallowed, to use this atom
+ <marker id="first"></marker>
+ <p>Records in <c>set</c> or <c>bag</c> tables are not ordered.
+ However, there is an ordering of the records that is unknown
+ to the user. A table can therefore be traversed by this
+ function with the function <c>mnesia:next/2</c>.</p>
+ <p>If there are no records in the table, this function
+ returns the atom <c>'$end_of_table'</c>. It is therefore
+ highly undesirable, but not disallowed, to use this atom
as the key for any user records.</p>
</desc>
</func>
<func>
- <name>foldl(Function, Acc, Table) -> NewAcc | transaction abort </name>
- <fsummary>Call Function for each record in Table </fsummary>
+ <name>foldl(Function, Acc, Table) -> NewAcc | transaction abort</name>
+ <fsummary>Calls <c>Function</c> for each record in <c>Table</c>.</fsummary>
<desc>
- <p>Iterates over the table <c>Table</c> and calls
- <c>Function(Record, NewAcc)</c> for each <c>Record</c> in the table.
- The term returned from <c>Function</c> will be used as the second
- argument in the next call to the <c>Function</c>.
- </p>
- <p><c>foldl</c> returns the same term as the last call to
+ <marker id="foldl"></marker>
+ <p>Iterates over the table <c>Table</c> and calls
+ <c>Function(Record, NewAcc)</c> for each <c>Record</c> in
+ the table. The term returned from <c>Function</c> is used
+ as the second argument in the next call to <c>Function</c>.</p>
+ <p><c>foldl</c> returns the same term as the last call to
<c>Function</c> returned.</p>
</desc>
</func>
<func>
- <name>foldr(Function, Acc, Table) -> NewAcc | transaction abort </name>
- <fsummary>Call Function for each record in Table </fsummary>
+ <name>foldr(Function, Acc, Table) -> NewAcc | transaction abort</name>
+ <fsummary>Calls <c>Function</c> for each record in <c>Table</c>.</fsummary>
<desc>
- <p>This function works exactly like
- <c>foldl/3</c> but iterates the table in the opposite order
- for the <c>ordered_set</c> table type. For
- all other table types, <c>foldr/3</c> and
+ <marker id="foldr"></marker>
+ <p>Works exactly like <c>foldl/3</c> but iterates the table
+ in the opposite order for the <c>ordered_set</c> table type.
+ For all other table types, <c>foldr/3</c> and
<c>foldl/3</c> are synonyms.</p>
</desc>
</func>
<func>
- <name>force_load_table(Tab) -> yes | ErrorDescription </name>
- <fsummary>Force a table to be loaded into the system </fsummary>
+ <name>force_load_table(Tab) -> yes | ErrorDescription</name>
+ <fsummary>Forces a table to be loaded into the system.</fsummary>
<desc>
- <p>The Mnesia algorithm for table load might lead to a
+ <marker id="force_load_table"></marker>
+ <p>The <c>Mnesia</c> algorithm for table load can lead to a
situation where a table cannot be loaded. This situation
- occurs when a node is started and Mnesia concludes, or
+ occurs when a node is started and <c>Mnesia</c> concludes, or
suspects, that another copy of the table was active after
- this local copy became inactive due to a system crash.
- </p>
+ this local copy became inactive because of a system crash.</p>
<p>If this situation is not acceptable, this function can be
- used to override the strategy of the Mnesia table load
- algorithm. This could lead to a situation where some
- transaction effects are lost with a inconsistent database as
+ used to override the strategy of the <c>Mnesia</c> table
+ load algorithm. This can lead to a situation where some
+ transaction effects are lost with an inconsistent database as
result, but for some applications high availability is more
important than consistent data.</p>
</desc>
</func>
<func>
<name>index_match_object(Pattern, Pos) -> transaction abort | ObjList</name>
- <fsummary>Match records and utilizes index information.</fsummary>
+ <fsummary>Matches records and uses index information.</fsummary>
<desc>
- <p>Invokes <c>mnesia:index_match_object(Tab, Pattern, Pos, read)</c> where <c>Tab</c> is <c>element(1, Pattern)</c>.</p>
+ <marker id="index_match_object_2"></marker>
+ <p>Starts
+ <c>mnesia:index_match_object(Tab, Pattern, Pos, read)</c>,
+ where <c>Tab</c> is <c>element(1, Pattern)</c>.</p>
</desc>
</func>
<func>
<name>index_match_object(Tab, Pattern, Pos, LockKind) -> transaction abort | ObjList</name>
- <fsummary>Match records and utilizes index information.</fsummary>
- <desc>
- <p>In a manner similar to the <c>mnesia:index_read/3</c>
- function, we can also utilize any index information when we
- try to match records. This function takes a pattern which
- obeys the same rules as the <c>mnesia:match_object/3</c>
- function with the exception that this function requires the
- following conditions:
- </p>
+ <fsummary>Matches records and uses index information.</fsummary>
+ <desc>
+ <marker id="index_match_object_4"></marker>
+ <p>In a manner similar to the function <c>mnesia:index_read/3</c>,
+ any index information can be used when trying to match records.
+ This function takes a pattern that obeys the same rules as the
+ function <c>mnesia:match_object/3</c>, except that this function
+ requires the following conditions:</p>
<list type="bulleted">
<item>
<p>The table <c>Tab</c> must have an index on
- position <c>Pos</c>.
- </p>
+ position <c>Pos</c>.</p>
</item>
<item>
<p>The element in position <c>Pos</c> in
- <c>Pattern</c> must be bound. <c>Pos</c> may either be
- an integer (#record.Field), or an attribute name.</p>
+ <c>Pattern</c> must be bound. <c>Pos</c> is
+ an integer (<c>#record.Field</c>) or an attribute name.</p>
</item>
</list>
<p>The two index search functions described here are
- automatically invoked when searching tables with <c>qlc</c>
- list comprehensions and also when using the low level
- <c>mnesia:[dirty_]match_object</c> functions.
- </p>
- <p></p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a lock of type <c>LockKind</c> on the
- entire table or on a single record. Currently, the lock type
- <c>read</c> is supported.
- </p>
+ automatically started when searching tables with <c>qlc</c>
+ list comprehensions and also when using the low-level
+ <c>mnesia:[dirty_]match_object</c> functions.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a lock of type
+ <c>LockKind</c> on the entire table or on a single record.
+ Currently, the lock type <c>read</c> is supported.</p>
</desc>
</func>
<func>
- <name>index_read(Tab, SecondaryKey, Pos) -> transaction abort | RecordList </name>
- <fsummary>Read records via index table. </fsummary>
+ <name>index_read(Tab, SecondaryKey, Pos) -> transaction abort | RecordList</name>
+ <fsummary>Reads records through index table.</fsummary>
<desc>
- <p>Assume there is an index on position <c>Pos</c> for a
+ <marker id="index_read"></marker>
+ <p>Assume that there is an index on position <c>Pos</c> for a
certain record type. This function can be used to read the
records without knowing the actual key for the record. For
- example, with an index in position 1 of the <c>person</c>
- table, the call <c>mnesia:index_read(person, 36, #person.age)</c> returns a list of all persons with age
- equal to 36. <c>Pos</c> may also be an attribute name
- (atom), but if the notation <c>mnesia:index_read(person, 36, age)</c> is used, the field position will be searched for in
- runtime, for each call.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a read lock on the entire table.</p>
+ example, with an index in position 1 of table <c>person</c>,
+ the call <c>mnesia:index_read(person, 36, #person.age)</c>
+ returns a list of all persons with age 36. <c>Pos</c> can
+ also be an attribute name (atom), but if the notation
+ <c>mnesia:index_read(person, 36, age)</c> is used, the
+ field position is searched for in runtime, for each call.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a read lock on the entire
+ table.</p>
</desc>
</func>
<func>
- <name>info() -> ok </name>
- <fsummary>Print some information about the system on the tty.</fsummary>
+ <name>info() -> ok</name>
+ <fsummary>Prints system information on the terminal.</fsummary>
<desc>
- <p>Prints some information about the system on the tty.
- This function may be used even if Mnesia is not started.
- However, more information will be displayed if Mnesia is
- started.</p>
+ <marker id="info"></marker>
+ <p>Prints system information on the terminal.
+ This function can be used even if <c>Mnesia</c> is not
+ started. However, more information is displayed if
+ <c>Mnesia</c> is started.</p>
</desc>
</func>
<func>
<name>install_fallback(Opaque) -> ok | {error,Reason}</name>
- <fsummary>Install a backup as fallback.</fsummary>
+ <fsummary>Installs a backup as fallback.</fsummary>
<desc>
- <p>Invokes <c>mnesia:install_fallback(Opaque, Args)</c> where
+ <marker id="install_fallback_1"></marker>
+ <p>Calls <c>mnesia:install_fallback(Opaque, Args)</c>, where
<c>Args</c> is <c>[{scope, global}]</c>.</p>
</desc>
</func>
<func>
<name>install_fallback(Opaque), BackupMod) -> ok | {error,Reason}</name>
- <fsummary>Install a backup as fallback.</fsummary>
+ <fsummary>Installs a backup as fallback.</fsummary>
<desc>
- <p>Invokes <c>mnesia:install_fallback(Opaque, Args)</c> where
+ <p>Calls <c>mnesia:install_fallback(Opaque, Args)</c>, where
<c>Args</c> is <c>[{scope, global}, {module, BackupMod}]</c>.</p>
</desc>
</func>
<func>
<name>install_fallback(Opaque, Args) -> ok | {error,Reason}</name>
- <fsummary>Install a backup as fallback.</fsummary>
- <desc>
- <p>This function is used to install a backup as fallback. The
- fallback will be used to restore the database at the next
- start-up. Installation of fallbacks requires Erlang to be up
- and running on all the involved nodes, but it does not
- matter if Mnesia is running or not. The installation of the
- fallback will fail if the local node is not one of the disc
- resident nodes in the backup.
- </p>
- <p><c>Args</c> is a list of the following tuples:
- </p>
+ <fsummary>Installs a backup as fallback.</fsummary>
+ <desc>
+ <p>Installs a backup as fallback. The fallback is used to
+ restore the database at the next startup. Installation of
+ fallbacks requires Erlang to be operational on all the
+ involved nodes, but it does not matter if <c>Mnesia</c>
+ is running or not. The installation of the fallback fails
+ if the local node is not one of the disc-resident nodes
+ in the backup.</p>
+ <p><c>Args</c> is a list of the following tuples:</p>
<list type="bulleted">
<item>
- <p><c>{module, BackupMod}</c>.
- All accesses of the backup media is performed via a
- callback module named <c>BackupMod</c>. The
- <c>Opaque</c> argument is forwarded to the callback
- module which may interpret it as it wish. The default
+ <p><c>{module, BackupMod}</c>.
+ All accesses of the backup media are performed through
+ a callback module named <c>BackupMod</c>. Argument
+ <c>Opaque</c> is forwarded to the callback module,
+ which can interpret it as it wishes. The default
callback module is called <c>mnesia_backup</c> and it
- interprets the <c>Opaque</c> argument as a local
+ interprets argument <c>Opaque</c> as a local
filename. The default for this module is also
- configurable via the <c>-mnesia mnesia_backup</c>
- configuration parameter. </p>
+ configurable through configuration parameter
+ <c>-mnesia mnesia_backup</c>.</p>
</item>
<item>
- <p><c>{scope, Scope}</c>
- The <c>Scope</c> of a fallback may either be
+ <p><c>{scope, Scope}</c>.
+ The <c>Scope</c> of a fallback is either
<c>global</c> for the entire database or <c>local</c>
for one node. By default, the installation of a fallback
- is a global operation which either is performed all
- nodes with disc resident schema or none. Which nodes
- that are disc resident or not, is determined from the
- schema info in the backup.</p>
- <p>If the <c>Scope</c> of the operation is <c>local</c>
- the fallback will only be installed on the local node.</p>
+ is a global operation, which either is performed on all
+ nodes with a disc-resident schema or none. Which nodes
+ that are disc-resident is determined from the
+ schema information in the backup.</p>
+ <p>If <c>Scope</c> of the operation is <c>local</c>,
+ the fallback is only installed on the local node.</p>
</item>
<item>
- <p><c>{mnesia_dir, AlternateDir}</c>
+ <p><c>{mnesia_dir, AlternateDir}</c>.
This argument is only valid if the scope of the
installation is <c>local</c>. Normally the installation
- of a fallback is targeted towards the Mnesia directory
- as configured with the <c>-mnesia dir</c> configuration
- parameter. But by explicitly supplying an
- <c>AlternateDir</c> the fallback will be installed there
- regardless of the Mnesia directory configuration
+ of a fallback is targeted to the <c>Mnesia</c> directory,
+ as configured with configuration parameter
+ <c>-mnesia dir</c>. But by explicitly supplying an
+ <c>AlternateDir</c>, the fallback is installed there
+ regardless of the <c>Mnesia</c> directory configuration
parameter setting. After installation of a fallback on
- an alternate Mnesia directory that directory is fully
- prepared for usage as an active Mnesia directory.
- </p>
- <p>This is a somewhat dangerous feature which must be
- used with care. By unintentional mixing of directories
- you may easily end up with a inconsistent database, if
+ an alternative <c>Mnesia</c> directory, that directory
+ is fully prepared for use as an active <c>Mnesia</c>
+ directory.</p>
+ <p>This is a dangerous feature that must be
+ used with care. By unintentional mixing of directories,
+ you can easily end up with an inconsistent database, if
the same backup is installed on more than one directory.</p>
</item>
</list>
</desc>
</func>
<func>
- <name>is_transaction() -> boolean </name>
- <fsummary>Check if code is running in a transaction.</fsummary>
+ <name>is_transaction() -> boolean</name>
+ <fsummary>Checks if code is running in a transaction.</fsummary>
<desc>
- <p>When this function is executed inside a transaction context
+ <marker id="is_transaction"></marker>
+ <p>When this function is executed inside a transaction-context,
it returns <c>true</c>, otherwise <c>false</c>.</p>
</desc>
</func>
<func>
- <name>last(Tab) -> Key | transaction abort </name>
- <fsummary>Return the key for the last record in a table.</fsummary>
+ <name>last(Tab) -> Key | transaction abort</name>
+ <fsummary>Returns the key for the last record in a table.</fsummary>
<desc>
- <p>This function works exactly like
- <c>mnesia:first/1</c> but returns the last object in
- Erlang term order for the <c>ordered_set</c> table type. For
- all other table types, <c>mnesia:first/1</c> and
+ <p>Works exactly like
+ <c>mnesia:first/1</c>, but returns the last object in
+ Erlang term order for the <c>ordered_set</c> table type.
+ For all other table types, <c>mnesia:first/1</c> and
<c>mnesia:last/1</c> are synonyms.</p>
</desc>
</func>
<func>
<name>load_textfile(Filename)</name>
- <fsummary>Load tables from a text file.</fsummary>
+ <fsummary>Loads tables from a text file.</fsummary>
<desc>
+ <marker id="load_textfile"></marker>
<p>Loads a series of definitions and data found in the
text file (generated with <c>mnesia:dump_to_textfile/1</c>)
- into Mnesia. This function also starts Mnesia and possibly
- creates a new schema. This function is intended for
- educational purposes only and using other functions to deal
- with real backups, is recommended.</p>
+ into <c>Mnesia</c>. This function also starts <c>Mnesia</c>
+ and possibly creates a new schema. This function is
+ intended for educational purposes only. It is recommended
+ to use other functions to deal with real backups.</p>
</desc>
</func>
<func>
<name>lock(LockItem, LockKind) -> Nodes | ok | transaction abort</name>
<fsummary>Explicit grab lock.</fsummary>
<desc>
+ <marker id="lock"></marker>
<p>Write locks are normally acquired on all nodes where a
- replica of the table resides (and is active). Read locks are
- acquired on one node (the local node if a local
- replica exists). Most of the context sensitive access functions
- acquire an implicit lock if they are invoked in a
- transaction context. The granularity of a lock may either
- be a single record or an entire table.
- </p>
- <p>The normal usage is to call the function without checking
- the return value since it exits if it fails and the
- transaction is restarted by the transaction manager. It
- returns all the locked nodes if a write lock is acquired, and
- <c>ok</c> if it was a read lock.
- </p>
- <p>This function <c>mnesia:lock/2</c> is intended to support
- explicit locking on tables but also intended for situations
- when locks need to be acquired regardless of how tables are
- replicated. Currently, two <c>LockKind</c>'s are supported:
- </p>
+ replica of the table resides (and is active). Read locks
+ are acquired on one node (the local node if a local
+ replica exists). Most of the context-sensitive access
+ functions acquire an implicit lock if they are started in a
+ transaction-context. The granularity of a lock can either
+ be a single record or an entire table.</p>
+ <p>The normal use is to call the function without checking
+ the return value, as it exits if it fails and the
+ transaction is restarted by the transaction manager. It
+ returns all the locked nodes if a write lock is acquired
+ and <c>ok</c> if it was a read lock.</p>
+ <p>The function <c>mnesia:lock/2</c> is intended to support
+ explicit locking on tables, but is also intended for
+ situations when locks need to be acquired regardless of
+ how tables are replicated. Currently, two kinds of
+ <c>LockKind</c> are supported:</p>
<taglist>
<tag><c>write</c></tag>
<item>
- <p>Write locks are exclusive, which means that if one
+ <p>Write locks are exclusive. This means that if one
transaction manages to acquire a write lock on an item,
- no other transaction may acquire any kind of lock on the
- same item.
- </p>
+ no other transaction can acquire any kind of lock on
+ the same item.</p>
</item>
<tag><c>read</c></tag>
<item>
- <p>Read locks may be shared, which means that if one
+ <p>Read locks can be shared. This means that if one
transaction manages to acquire a read lock on an item,
- other transactions may also acquire a read lock on the
- same item. However, if someone has a read lock no one can
- acquire a write lock at the same item. If some one has a
- write lock no one can acquire a read lock nor
- a write lock at the same item.</p>
+ other transactions can also acquire a read lock on the
+ same item. However, if someone has a read lock, no one
+ can acquire a write lock at the same item. If someone
+ has a write lock, no one can acquire either a read lock
+ or a write lock at the same item.</p>
</item>
</taglist>
<p>Conflicting lock requests are automatically queued if there
is no risk of a deadlock. Otherwise the transaction must be
- aborted and executed again. Mnesia does this automatically
- as long as the upper limit of maximum <c>retries</c> is not
- reached. See <c>mnesia:transaction/3</c> for the details.
- </p>
- <p>For the sake of completeness sticky write locks will also
- be described here even if a sticky write lock is not
- supported by this particular function:
- </p>
+ terminated and executed again. <c>Mnesia</c> does this
+ automatically as long as the upper limit of the maximum
+ <c>retries</c> is not reached. For details, see
+ <c>mnesia:transaction/3</c>.</p>
+ <p>For the sake of completeness, sticky write locks are also
+ described here even if a sticky write lock is not
+ supported by this function:</p>
<taglist>
<tag><c>sticky_write</c></tag>
<item>
- <p>Sticky write locks are a mechanism which can be used
+ <p>Sticky write locks are a mechanism that can be used
to optimize write lock acquisition. If your application
uses replicated tables mainly for fault tolerance (as
opposed to read access optimization purpose), sticky
- locks may be the best option available.
- </p>
- <p>When a sticky write lock is acquired, all nodes will be
- informed which node is locked. Subsequently,
- sticky lock requests from the same node will be
- performed as a local operation without any
+ locks can be the best option available.</p>
+ <p>When a sticky write lock is acquired, all nodes are
+ informed which node is locked. Then,
+ sticky lock requests from the same node are
+ performed as a local operation without any
communication with other nodes. The sticky lock
- lingers on the node even after the transaction has
- ended. See the Mnesia User's Guide for more information.</p>
+ lingers on the node even after the transaction
+ ends. For details, see the User's Guide.</p>
</item>
</taglist>
- <p>Currently, two kinds of <c>LockItem</c>'s are supported by
- this function:
- </p>
+ <p>Currently, this function supports two kinds of
+ <c>LockItem</c>:</p>
<taglist>
<tag><c>{table, Tab}</c></tag>
<item>
<p>This acquires a lock of type <c>LockKind</c> on the
- entire table <c>Tab</c>.
- </p>
+ entire table <c>Tab</c>.</p>
</item>
<tag><c>{global, GlobalKey, Nodes}</c></tag>
<item>
<p>This acquires a lock of type <c>LockKind</c> on the
global resource <c>GlobalKey</c>. The lock is acquired
- on all active nodes in the <c>Nodes</c> list. </p>
+ on all active nodes in the <c>Nodes</c> list.</p>
</item>
</taglist>
- <p>Locks are released when the outermost transaction ends.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires locks otherwise it just ignores the
- request.</p>
+ <p>Locks are released when the outermost transaction ends.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires locks, otherwise it
+ ignores the request.</p>
</desc>
</func>
<func>
- <name>match_object(Pattern) ->transaction abort | RecList </name>
- <fsummary>Match <c>Pattern</c>for records. </fsummary>
+ <name>match_object(Pattern) -> transaction abort | RecList</name>
+ <fsummary>Matches <c>Pattern</c> for records.</fsummary>
<desc>
- <p>Invokes <c>mnesia:match_object(Tab, Pattern, read)</c> where
+ <marker id="match_object_1"></marker>
+ <p>Calls <c>mnesia:match_object(Tab, Pattern, read)</c>, where
<c>Tab</c> is <c>element(1, Pattern)</c>.</p>
</desc>
</func>
<func>
- <name>match_object(Tab, Pattern, LockKind) ->transaction abort | RecList </name>
- <fsummary>Match <c>Pattern</c>for records. </fsummary>
+ <name>match_object(Tab, Pattern, LockKind) -> transaction abort | RecList</name>
+ <fsummary>Matches <c>Pattern</c> for records.</fsummary>
<desc>
- <p>This function takes a pattern with 'don't care' variables
- denoted as a '_' parameter. This function returns a list of
- records which matched the pattern. Since the second element
+ <marker id="match_object_3"></marker>
+ <p>Takes a pattern with "don't care" variables
+ denoted as a <c>'_'</c> parameter. This function returns
+ a list of records that matched the pattern.
+ Since the second element
of a record in a table is considered to be the key for the
record, the performance of this function depends on whether
- this key is bound or not.
- </p>
- <p>For example, the call <c>mnesia:match_object(person, {person, '_', 36, '_', '_'}, read)</c> returns a list of all person records with an
- age field of thirty-six (36).
- </p>
+ this key is bound or not.</p>
+ <p>For example, the call <c>mnesia:match_object(person,
+ {person, '_', 36, '_', '_'}, read)</c> returns a list of
+ all person records with an <c>age</c> field of 36.</p>
<p>The function <c>mnesia:match_object/3</c>
- automatically uses indices if these exist. However, no
- heuristics are performed in order to select the best
- index.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a lock of type <c>LockKind</c> on the
- entire table or a single record. Currently, the lock type
- <c>read</c> is supported.</p>
+ automatically uses indexes if these exist. However, no
+ heuristics are performed to select the best index.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a lock of type
+ <c>LockKind</c> on the entire table or a single record.
+ Currently, the lock type <c>read</c> is supported.</p>
</desc>
</func>
<func>
<name>move_table_copy(Tab, From, To) -> {aborted, Reason} | {atomic, ok}</name>
- <fsummary>Move the copy of table <c>Tab</c>from node<c>From</c>to node <c>To</c>.</fsummary>
+ <fsummary>Moves the copy of table <c>Tab</c> from node <c>From</c> to node <c>To</c>.</fsummary>
<desc>
+ <marker id="move_table_copy"></marker>
<p>Moves the copy of table <c>Tab</c> from node
- <c>From</c> to node <c>To</c>.
- </p>
+ <c>From</c> to node <c>To</c>.</p>
<p>The storage type is preserved. For example, a RAM table
- moved from one node remains a RAM on the new node. It is
- still possible for other transactions to read and write in
- the table while it is being moved.
- </p>
+ moved from one node remains a RAM on the new node. Other
+ transactions can still read and write in
+ the table while it is being moved.</p>
<p>This function cannot be used on <c>local_content</c> tables.</p>
</desc>
</func>
<func>
- <name>next(Tab, Key) -> Key | transaction abort </name>
- <fsummary>Return the next key in a table. </fsummary>
+ <name>next(Tab, Key) -> Key | transaction abort</name>
+ <fsummary>Returns the next key in a table.</fsummary>
<desc>
- <p>This function makes it possible to traverse a table
- and perform operations on all records in the table. When
+ <marker id="next"></marker>
+ <p>Traverses a table and
+ performs operations on all records in the table. When
the end of the table is reached, the special key
- <c>'$end_of_table'</c> is returned. Otherwise, the function
- returns a key which can be used to read the actual record.</p>
+ <c>'$end_of_table'</c> is returned. Otherwise the function
+ returns a key that can be used to read the actual record.</p>
</desc>
</func>
<func>
- <name>prev(Tab, Key) -> Key | transaction abort </name>
- <fsummary>Return the previous key in a table. </fsummary>
+ <name>prev(Tab, Key) -> Key | transaction abort</name>
+ <fsummary>Returns the previous key in a table.</fsummary>
<desc>
- <p>This function works exactly like
- <c>mnesia:next/2</c> but returns the previous object in
- Erlang term order for the ordered_set table type. For
- all other table types, <c>mnesia:next/2</c> and
+ <p>Works exactly like
+ <c>mnesia:next/2</c>, but returns the previous object in
+ Erlang term order for the <c>ordered_set</c> table type.
+ For all other table types, <c>mnesia:next/2</c> and
<c>mnesia:prev/2</c> are synonyms.</p>
</desc>
</func>
<func>
- <name>read({Tab, Key}) -> transaction abort | RecordList </name>
- <fsummary>Read records(s) with a given key. </fsummary>
+ <name>read({Tab, Key}) -> transaction abort | RecordList</name>
+ <fsummary>Reads records(s) with a given key.</fsummary>
<desc>
- <p>Invokes <c>mnesia:read(Tab, Key, read)</c>.</p>
+ <marker id="read_2"></marker>
+ <p>Calls function <c>mnesia:read(Tab, Key, read)</c>.</p>
</desc>
</func>
<func>
- <name>read(Tab, Key) -> transaction abort | RecordList </name>
- <fsummary>Read records(s) with a given key. </fsummary>
+ <name>read(Tab, Key) -> transaction abort | RecordList</name>
+ <fsummary>Reads records(s) with a given key.</fsummary>
<desc>
- <p>Invokes <c>mnesia:read(Tab, Key, read)</c>.</p>
+ <p>Calls function <c>mnesia:read(Tab, Key, read)</c>.</p>
</desc>
</func>
<func>
- <name>read(Tab, Key, LockKind) -> transaction abort | RecordList </name>
- <fsummary>Read records(s) with a given key. </fsummary>
+ <name>read(Tab, Key, LockKind) -> transaction abort | RecordList</name>
+ <fsummary>Reads records(s) with a given key.</fsummary>
<desc>
- <p>This function reads all records from table <c>Tab</c> with
+ <marker id="read_3"></marker>
+ <p>Reads all records from table <c>Tab</c> with
key <c>Key</c>. This function has the same semantics
regardless of the location of <c>Tab</c>. If the table is
- of type <c>bag</c>, the <c>mnesia:read(Tab, Key)</c> can
+ of type <c>bag</c>, the function
+ <c>mnesia:read(Tab, Key)</c> can
return an arbitrarily long list. If the table is of type
- <c>set</c>, the list is either of length 1, or <c>[]</c>.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a lock of type
+ <c>set</c>, the list is either of length 1, or <c>[]</c>.</p>
+ <p>The semantics of this function is context-sensitive.
+ For details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a lock of type
<c>LockKind</c>. Currently, the lock types <c>read</c>,
- <c>write</c> and <c>sticky_write</c> are supported.
- </p>
- <p>If the user wants to update the record it is more efficient to
- use <c>write/sticky_write</c> as the LockKind. If majority checking
- is active on the table, it will be checked as soon as a write lock is
- attempted. This can be used to quickly abort if the majority condition
- isn't met.
- </p>
+ <c>write</c>, and <c>sticky_write</c> are supported.</p>
+ <p>If the user wants to update the record, it is more
+ efficient to use <c>write/sticky_write</c> as the
+ <c>LockKind</c>. If majority checking is active on the
+ table, it is checked as soon as a write lock is
+ attempted. This can be used to end quickly if the
+ majority condition is not met.</p>
</desc>
</func>
<func>
<name>read_lock_table(Tab) -> ok | transaction abort</name>
- <fsummary>Set a read lock on an entire table.</fsummary>
+ <fsummary>Sets a read lock on an entire table.</fsummary>
<desc>
- <p>Invokes <c>mnesia:lock({table, Tab}, read)</c>.</p>
+ <marker id="read_lock_table"></marker>
+ <p>Calls the function
+ <c>mnesia:lock({table, Tab}, read)</c>.</p>
</desc>
</func>
<func>
<name>report_event(Event) -> ok</name>
- <fsummary>Report a user event to Mnesia's event handler.</fsummary>
+ <fsummary>Reports a user event to the <c>Mnesia</c> event handler.</fsummary>
<desc>
- <p>When tracing a system of Mnesia applications it is useful
- to be able to interleave Mnesia's own events with
- application related events that give information about the
- application context.
- </p>
+ <marker id="report_event"></marker>
+ <p>When tracing a system of <c>Mnesia</c> applications it is
+ useful to be able to interleave <c>Mnesia</c> own events with
+ application-related events that give information about the
+ application context.</p>
<p>Whenever the application begins a
- new and demanding Mnesia task, or if it is entering a new
- interesting phase in its execution, it may be a good idea to
- use <c>mnesia:report_event/1</c>. The <c>Event</c> may be
+ new and demanding <c>Mnesia</c> task, or if it enters a new
+ interesting phase in its execution, it can be a good idea to
+ use <c>mnesia:report_event/1</c>. <c>Event</c> can be
any term and generates a <c>{mnesia_user, Event}</c> event
- for any processes that subscribe to Mnesia system
+ for any processes that subscribe to <c>Mnesia</c> system
events.</p>
</desc>
</func>
@@ -1819,221 +1746,237 @@ mnesia:create_table(person,
<name>restore(Opaque, Args) -> {atomic, RestoredTabs} |{aborted, Reason}</name>
<fsummary>Online restore of backup.</fsummary>
<desc>
- <p>With this function, tables may be restored online from a
- backup without restarting Mnesia. <c>Opaque</c> is forwarded
- to the backup module. <c>Args</c> is a list of the following
- tuples:
- </p>
+ <marker id="restore"></marker>
+ <p>With this function, tables can be restored online from a
+ backup without restarting <c>Mnesia</c>.
+ <c>Opaque</c> is forwarded to the backup module.
+ <c>Args</c> is a list of the following tuples:</p>
<list type="bulleted">
<item>
- <p><c>{module,BackupMod}</c> The backup module
- <c>BackupMod</c> will be used to access the backup
- media. If omitted, the default backup module will be
- used.
- </p>
+ <c>{module,BackupMod}</c>. The backup module
+ <c>BackupMod</c> is used to access the backup media.
+ If omitted, the default backup module is used.
</item>
- <item><c>{skip_tables, TabList}</c> Where <c>TabList</c>
- is a list of tables which should not be read from the
+ <item><c>{skip_tables, TabList}</c>, where <c>TabList</c>
+ is a list of tables that is not to be read from the
backup.
</item>
- <item><c>{clear_tables, TabList}</c> Where
- <c>TabList</c> is a list of tables which should be
- cleared, before the records from the backup are inserted,
- ie. all records in the tables are deleted before the
- tables are restored. Schema information about the tables
- is not cleared or read from backup.
- </item>
- <item><c>{keep_tables, TabList}</c> Where <c>TabList</c>
- is a list of tables which should be not be cleared, before
- the records from the backup are inserted, i.e. the records
- in the backup will be added to the records in the table.
+ <item><c>{clear_tables, TabList}</c>, where
+ <c>TabList</c> is a list of tables that is to be
+ cleared before the records from the backup are inserted.
+ That is, all records in the tables are deleted before the
+ tables are restored. Schema information about the tables
+ is not cleared or read from the backup.
+ </item>
+ <item><c>{keep_tables, TabList}</c>, where <c>TabList</c>
+ is a list of tables that is not to be cleared before the
+ records from the backup are inserted. That is, the records
+ in the backup are added to the records in the table.
Schema information about the tables is not cleared or read
- from backup.
- </item>
- <item><c>{recreate_tables, TabList}</c> Where
- <c>TabList</c> is a list of tables which should be
- re-created, before the records from the backup are
- inserted. The tables are first deleted and then created with
- the schema information from the backup. All the nodes in the
- backup needs to be up and running.
- </item>
- <item><c>{default_op, Operation}</c> Where <c>Operation</c> is
- one of the following operations <c>skip_tables</c>,
- <c>clear_tables</c>, <c>keep_tables</c> or
- <c>recreate_tables</c>. The default operation specifies
- which operation should be used on tables from the backup
- which are not specified in any of the lists above. If
- omitted, the operation <c>clear_tables</c> will be used.
+ from the backup.
+ </item>
+ <item><c>{recreate_tables, TabList}</c>, where
+ <c>TabList</c> is a list of tables that is to be
+ recreated before the records from the backup are inserted.
+ The tables are first deleted and then created with the
+ schema information from the backup. All the nodes in the
+ backup need to be operational.
+ </item>
+ <item><c>{default_op, Operation}</c>, where <c>Operation</c>
+ is either of the operations <c>skip_tables</c>,
+ <c>clear_tables</c>, <c>keep_tables</c>, or
+ <c>recreate_tables</c>. The default operation specifies
+ which operation that is to be used on tables from the backup
+ that is not specified in any of the mentioned lists. If
+ omitted, operation <c>clear_tables</c> is used.
</item>
</list>
- <p>The affected tables are write locked during the
- restoration, but regardless of the lock conflicts caused by
- this, the applications can continue to do their work while
+ <p>The affected tables are write-locked during the
+ restoration. However, regardless of the lock conflicts caused
+ by this, the applications can continue to do their work while
the restoration is being performed. The restoration is
- performed as one single transaction.
- </p>
- <p>If the database is
- huge, it may not be possible to restore it online. In such
- cases, the old database must be restored by installing a
+ performed as one single transaction.</p>
+ <p>If the database is huge,
+ it it not always possible to restore it online. In such
+ cases, restore the old database by installing a
fallback and then restart.</p>
</desc>
</func>
<func>
- <name>s_delete({Tab, Key}) -> ok | transaction abort </name>
- <fsummary>Set sticky lock and delete records.</fsummary>
+ <name>s_delete({Tab, Key}) -> ok | transaction abort</name>
+ <fsummary>Sets sticky lock and delete records.</fsummary>
<desc>
- <p>Invokes <c>mnesia:delete(Tab, Key, sticky_write)</c></p>
+ <marker id="s_delete"></marker>
+ <p>Calls the function
+ <c>mnesia:delete(Tab, Key, sticky_write)</c></p>
</desc>
</func>
<func>
- <name>s_delete_object(Record) -> ok | transaction abort </name>
- <fsummary>Set sticky lock and delete record.</fsummary>
+ <name>s_delete_object(Record) -> ok | transaction abort</name>
+ <fsummary>Sets sticky lock and delete record.</fsummary>
<desc>
- <p>Invokes <c>mnesia:delete_object(Tab, Record, sticky_write)</c> where <c>Tab</c> is <c>element(1, Record)</c>.</p>
+ <marker id="s_delete_object"></marker>
+ <p>Calls the function
+ <c>mnesia:delete_object(Tab, Record, sticky_write)</c>,
+ where <c>Tab</c> is <c>element(1, Record)</c>.</p>
</desc>
</func>
<func>
- <name>s_write(Record) -> ok | transaction abort </name>
- <fsummary>Write <c>Record</c>and sets stick lock.</fsummary>
+ <name>s_write(Record) -> ok | transaction abort</name>
+ <fsummary>Writes <c>Record</c> and sets sticky lock.</fsummary>
<desc>
- <p>Invokes <c>mnesia:write(Tab, Record, sticky_write)</c>
+ <marker id="s_write"></marker>
+ <p>Calls the function
+ <c>mnesia:write(Tab, Record, sticky_write)</c>,
where <c>Tab</c> is <c>element(1, Record)</c>.</p>
</desc>
</func>
<func>
- <name>schema() -> ok </name>
- <fsummary>Print information about all table definitions on the tty. </fsummary>
+ <name>schema() -> ok</name>
+ <fsummary>Prints information about all table definitions on the terminal.</fsummary>
<desc>
- <p>Prints information about all table definitions on the tty.</p>
+ <p>Prints information about all table definitions on the terminal.</p>
</desc>
</func>
<func>
- <name>schema(Tab) -> ok </name>
- <fsummary>Print information about one table definition on the tty.</fsummary>
+ <name>schema(Tab) -> ok</name>
+ <fsummary>Prints information about one table definition on the terminal.</fsummary>
<desc>
- <p>Prints information about one table definition on the tty.</p>
+ <p>Prints information about one table definition on the terminal.</p>
</desc>
</func>
<func>
- <name>select(Tab, MatchSpec [, Lock]) -> transaction abort | [Object] </name>
- <fsummary>Match the objects in <c>Tab</c>against <c>MatchSpec</c>.</fsummary>
+ <name>select(Tab, MatchSpec [, Lock]) -> transaction abort | [Object]</name>
+ <fsummary>Matches the objects in <c>Tab</c> against <c>MatchSpec</c>.</fsummary>
<desc>
- <p>Matches the objects in the table <c>Tab</c> using a
- match_spec as described in the ERTS Users Guide. Optionally a lock
+ <marker id="select_2_3"></marker>
+ <p>Matches the objects in table <c>Tab</c> using a
+ <c>match_spec</c> as described in the
+ <seealso marker="stdlib:ets#select/3">ets:select/3</seealso>.
+ Optionally a lock
<c>read</c> or <c>write</c> can be given as the third
- argument, default is <c>read</c>. The return value depends
- on the <c>MatchSpec</c>.</p>
- <p><em>Note:</em> for best performance <c>select</c> should
- be used before any modifying operations are done on that table
- in the same transaction, i.e. don't use <c>write</c> or <c>delete</c>
- before a <c>select</c>.</p>
- <p>In its simplest forms the match_spec's look like this:</p>
+ argument. Default is <c>read</c>. The return value depends
+ on <c>MatchSpec</c>.</p>
+ <p>Notice that for best performance, <c>select</c> is to be
+ used before any modifying operations are done on that table
+ in the same transaction. That is, do not use <c>write</c>
+ or <c>delete</c> before a <c>select</c>.</p>
+ <p>In its simplest forms, the <c>match_spec</c> look as
+ follows:</p>
<list type="bulleted">
- <item>MatchSpec = [MatchFunction]</item>
- <item>MatchFunction = {MatchHead, [Guard], [Result]}</item>
- <item>MatchHead = tuple() | record()</item>
- <item>Guard = {"Guardtest name", ...}</item>
- <item>Result = "Term construct"</item>
+ <item><c>MatchSpec = [MatchFunction]</c></item>
+ <item><c>MatchFunction = {MatchHead, [Guard], [Result]}</c></item>
+ <item><c>MatchHead = tuple() | record()</c></item>
+ <item><c>Guard = {"Guardtest name", ...}</c></item>
+ <item><c>Result = "Term construct"</c></item>
</list>
- <p>See the ERTS Users Guide and <c>ets</c> documentation for a
- complete description of the select.</p>
- <p>For example to find the names of all male persons with an age over 30 in table
- Tab do:</p>
+ <p>For a complete description of <c>select</c>, see the
+ <seealso marker="erts:index">ERTS</seealso> User's Guide and the
+ <seealso marker="stdlib:ets">ets</seealso> manual page in
+ <c>STDLIB</c>.</p>
+ <p>For example, to find the names of all male persons older
+ than 30 in table <c>Tab</c>:</p>
<code type="none">
MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
Guard = {'>', '$2', 30},
Result = '$1',
-mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
- </code>
+mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>select(Tab, MatchSpec, NObjects, Lock) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
- <fsummary>Match the objects in <c>Tab</c>against <c>MatchSpec</c>.</fsummary>
+ <name>select(Tab, MatchSpec, NObjects, Lock) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
+ <fsummary>Matches the objects in <c>Tab</c> against <c>MatchSpec</c>.</fsummary>
<desc>
- <p>Matches the objects in the table <c>Tab</c> using a
- match_spec as described in ERTS users guide, and returns
- a chunk of terms and a continuation, the wanted number
- of returned terms is specified by the <c>NObjects</c> argument.
- The lock argument can be <c>read</c> or <c>write</c>.
- The continuation should be used as argument to <c>mnesia:select/1</c>,
+ <marker id="select_4"></marker>
+ <p>Matches the objects in table <c>Tab</c> using a
+ <c>match_spec</c> as described in the
+ <seealso marker="erts:index">ERTS</seealso> User's Guide,
+ and returns a chunk of terms and a continuation.
+ The wanted number of returned terms is specified by
+ argument <c>NObjects</c>. The lock argument can be
+ <c>read</c> or <c>write</c>. The continuation is to be
+ used as argument to <c>mnesia:select/1</c>,
if more or all answers are needed.</p>
- <p><em>Note:</em> for best performance <c>select</c> should
- be used before any modifying operations are done on that
- table in the same transaction, i.e. don't use
+ <p>Notice that for best performance, <c>select</c> is to be
+ used before any modifying operations are done on that table
+ in the same transaction. That is, do not use
<c>mnesia:write</c> or <c>mnesia:delete</c> before a
- <c>mnesia:select</c>. For efficiency the <c>NObjects</c> is
- a recommendation only and the result may contain anything
- from an empty list to all available results. </p>
+ <c>mnesia:select</c>. For efficiency, <c>NObjects</c> is
+ a recommendation only and the result can contain anything
+ from an empty list to all available results.</p>
</desc>
</func>
<func>
- <name>select(Cont) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
- <fsummary>Continues selecting objects. </fsummary>
+ <name>select(Cont) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
+ <fsummary>Continues selecting objects.</fsummary>
<desc>
<p>Selects more objects with the match specification initiated
- by <c>mnesia:select/4</c>.
- </p>
- <p><em>Note:</em> Any modifying operations, i.e. <c>mnesia:write</c>
- or <c>mnesia:delete</c>, that are done between the <c>mnesia:select/4</c>
- and <c>mnesia:select/1</c> calls will not be visible in the result.</p>
+ by <c>mnesia:select/4</c>.</p>
+ <p>Notice that any modifying operations, that is,
+ <c>mnesia:write</c> or <c>mnesia:delete</c>, that are done
+ between the <c>mnesia:select/4</c> and <c>mnesia:select/1</c>
+ calls are not visible in the result.</p>
</desc>
</func>
<func>
<name>set_debug_level(Level) -> OldLevel</name>
- <fsummary>Change the internal debug level of Mnesia</fsummary>
+ <fsummary>Changes the internal debug level of <c>Mnesia</c>.</fsummary>
<desc>
- <p>Changes the internal debug level of Mnesia. See the
- chapter about configuration parameters for details.</p>
+ <marker id="set_debug_level"></marker>
+ <p>Changes the internal debug level of <c>Mnesia</c>.
+ For details, see
+ <seealso marker="#configuration_parameters">Section
+ Configuration Parameters</seealso>.</p>
</desc>
</func>
<func>
- <name>set_master_nodes(MasterNodes) -> ok | {error, Reason} </name>
- <fsummary>Set the master nodes for all tables</fsummary>
+ <name>set_master_nodes(MasterNodes) -> ok | {error, Reason}</name>
+ <fsummary>Sets the master nodes for all tables.</fsummary>
<desc>
- <p>For each table Mnesia will determine its replica nodes
- (<c>TabNodes</c>) and invoke <c>mnesia:set_master_nodes(Tab, TabMasterNodes)</c> where <c>TabMasterNodes</c> is the
- intersection of <c>MasterNodes</c> and <c>TabNodes</c>. See
- <c>mnesia:set_master_nodes/2</c> about the semantics.</p>
+ <marker id="set_master_nodes_1"></marker>
+ <p>For each table <c>Mnesia</c> determines its replica nodes
+ (<c>TabNodes</c>) and starts
+ <c>mnesia:set_master_nodes(Tab, TabMasterNodes)</c>. where
+ <c>TabMasterNodes</c> is the intersection of
+ <c>MasterNodes</c> and <c>TabNodes</c>. For semantics, see
+ <c>mnesia:set_master_nodes/2</c>.</p>
</desc>
</func>
<func>
- <name>set_master_nodes(Tab, MasterNodes) -> ok | {error, Reason} </name>
- <fsummary>Set the master nodes for a table</fsummary>
+ <name>set_master_nodes(Tab, MasterNodes) -> ok | {error, Reason}</name>
+ <fsummary>Sets the master nodes for a table.</fsummary>
<desc>
- <p>If the application detects that there has been a
- communication failure (in a potentially partitioned network) which
- may have caused an inconsistent database, it may use the
+ <marker id="set_master_nodes_2"></marker>
+ <p>If the application detects a
+ communication failure (in a potentially partitioned network)
+ that can have caused an inconsistent database, it can use the
function <c>mnesia:set_master_nodes(Tab, MasterNodes)</c> to
- define from which nodes each table will be loaded.
- At startup Mnesia's normal table load algorithm will be
- bypassed and the table will be loaded from one of the master
- nodes defined for the table, regardless of when and if Mnesia
- was terminated on other nodes. The <c>MasterNodes</c> may only
- contain nodes where the table has a replica and if the
+ define from which nodes each table is to be loaded.
+ At startup, the <c>Mnesia</c> normal table load algorithm is
+ bypassed and the table is loaded from one of the master nodes
+ defined for the table, regardless of when and if <c>Mnesia</c>
+ terminated on other nodes. <c>MasterNodes</c> can only
+ contain nodes where the table has a replica. If the
<c>MasterNodes</c> list is empty, the master node recovery
- mechanism for the particular table will be reset and the
- normal load mechanism will be used at next restart.
- </p>
- <p>The master node setting is always local and it may be
- changed regardless of whether Mnesia is started or not.
- </p>
- <p>The database may also become inconsistent if the
- <c>max_wait_for_decision</c> configuration parameter is used
+ mechanism for the particular table is reset, and the
+ normal load mechanism is used at the next restart.</p>
+ <p>The master node setting is always local. It can be
+ changed regardless if <c>Mnesia</c> is started or not.</p>
+ <p>The database can also become inconsistent if
+ configuration parameter <c>max_wait_for_decision</c> is used
or if <c>mnesia:force_load_table/1</c> is used.</p>
</desc>
</func>
<func>
<name>snmp_close_table(Tab) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Remove the possibility for SNMP to manipulate the table.</fsummary>
+ <fsummary>Removes the possibility for SNMP to manipulate the table.</fsummary>
<desc>
- <p>Removes the possibility for SNMP to manipulate the
- table.</p>
+ <p>Removes the possibility for SNMP to manipulate the table.</p>
</desc>
</func>
<func>
<name>snmp_get_mnesia_key(Tab, RowIndex) -> {ok, Key} | undefined</name>
- <fsummary>Get the corresponding Mnesia key from an SNMP index.</fsummary>
+ <fsummary>Gets the corresponding <c>Mnesia</c> key from an SNMP index.</fsummary>
<type>
<v>Tab ::= atom()</v>
<v>RowIndex ::= [integer()]</v>
@@ -2041,44 +1984,43 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
<v>key() ::= integer() | string() | [integer()]</v>
</type>
<desc>
- <p>Transforms an SNMP index to the corresponding Mnesia key.
- If the SNMP table has multiple keys, the key is a tuple of
- the key columns.</p>
+ <p>Transforms an SNMP index to the corresponding <c>Mnesia</c>
+ key. If the SNMP table has multiple keys, the key is a tuple
+ of the key columns.</p>
</desc>
</func>
<func>
<name>snmp_get_next_index(Tab, RowIndex) -> {ok, NextIndex} | endOfTable</name>
- <fsummary>Get the index of the next lexicographical row.</fsummary>
+ <fsummary>Gets the index of the next lexicographical row.</fsummary>
<type>
<v>Tab ::= atom()</v>
<v>RowIndex ::= [integer()]</v>
<v>NextIndex ::= [integer()]</v>
</type>
<desc>
- <p>The <c>RowIndex</c> may specify a non-existing row.
- Specifically, it might be the empty list. Returns the index
+ <p><c>RowIndex</c> can specify a non-existing row.
+ Specifically, it can be the empty list. Returns the index
of the next lexicographical row. If <c>RowIndex</c> is the
- empty list, this function will return the index of the first row
+ empty list, this function returns the index of the first row
in the table.</p>
</desc>
</func>
<func>
<name>snmp_get_row(Tab, RowIndex) -> {ok, Row} | undefined</name>
- <fsummary>Retrieve a row indexed by an SNMP index.</fsummary>
+ <fsummary>Retrieves a row indexed by an SNMP index.</fsummary>
<type>
<v>Tab ::= atom()</v>
<v>RowIndex ::= [integer()]</v>
<v>Row ::= record(Tab)</v>
</type>
<desc>
- <p>Makes it possible to read a row by its SNMP index. This
- index is specified as an SNMP OBJECT IDENTIFIER, a list of
- integers.</p>
+ <p>Reads a row by its SNMP index. This index is specified as
+ an SNMP Object Identifier, a list of integers.</p>
</desc>
</func>
<func>
<name>snmp_open_table(Tab, SnmpStruct) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Organize a Mnesia table as an SNMP table.</fsummary>
+ <fsummary>Organizes a <c>Mnesia</c> table as an SNMP table.</fsummary>
<type>
<v>Tab ::= atom()</v>
<v>SnmpStruct ::= [{key, type()}]</v>
@@ -2086,624 +2028,558 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
<v>type_spec() ::= fix_string | string | integer</v>
</type>
<desc>
- <p>It is possible to establish a direct one to one mapping
- between Mnesia tables and SNMP tables. Many
- telecommunication applications are controlled and monitored
- by the SNMP protocol. This connection between Mnesia and
- SNMP makes it simple and convenient to achieve this.
- </p>
- <p>The <c>SnmpStruct</c> argument is a list of SNMP
+ <p>A direct one-to-one mapping can be established between
+ <c>Mnesia</c> tables and SNMP tables. Many telecommunication
+ applications are controlled and monitored by the SNMP
+ protocol. This connection between <c>Mnesia</c> and SNMP
+ makes it simple and convenient to achieve this mapping.</p>
+ <p>Argument <c>SnmpStruct</c> is a list of SNMP
information. Currently, the only information needed is
- information about the key types in the table. It is not
- possible to handle multiple keys in Mnesia, but many SNMP
+ information about the key types in the table. Multiple
+ keys cannot be handled in <c>Mnesia</c>, but many SNMP
tables have multiple keys. Therefore, the following
convention is used: if a table has multiple keys, these must
- always be stored as a tuple of the keys. Information about
+ always be stored as a tuple of the keys. Information about
the key types is specified as a tuple of atoms describing
- the types. The only significant type is
- <c>fix_string</c>. This means that a string has fixed
- size. For example:
- </p>
+ the types. The only significant type is <c>fix_string</c>.
+ This means that a string has a fixed size.</p>
+ <p>For example, the following causes table <c>person</c>
+ to be ordered as an SNMP table:</p>
<code type="none">
-mnesia:snmp_open_table(person, [{key, string}])
- </code>
- <p>causes the <c>person</c> table to be ordered as an SNMP
- table.
- </p>
+mnesia:snmp_open_table(person, [{key, string}])</code>
<p>Consider the following schema for a table of company
employees. Each employee is identified by department number
- and name. The other table column stores the telephone number:
- </p>
+ and name. The other table column stores the telephone
+ number:</p>
<code type="none">
mnesia:create_table(employee,
[{snmp, [{key, {integer, string}}]},
- {attributes, record_info(fields, employees)}]),
- </code>
- <p>The corresponding SNMP table would have three columns;
- <c>department</c>, <c>name</c> and <c>telno</c>.
- </p>
- <p>It is possible to have table columns that are not visible
+ {attributes, record_info(fields, employees)}]),</code>
+ <p>The corresponding SNMP table would have three columns:
+ <c>department</c>, <c>name</c>, and <c>telno</c>.</p>
+ <p>An option is to have table columns that are not visible
through the SNMP protocol. These columns must be the last
columns of the table. In the previous example, the SNMP
table could have columns <c>department</c> and <c>name</c>
- only. The application could then use the <c>telno</c> column
+ only. The application could then use column <c>telno</c>
internally, but it would not be visible to the SNMP
- managers.
- </p>
+ managers.</p>
<p>In a table monitored by SNMP, all elements must be
- integers, strings, or lists of integers.
- </p>
+ integers, strings, or lists of integers.</p>
<p>When a table is SNMP ordered, modifications are more
- expensive than usual, O(logN). And more memory is used.
- </p>
- <p><em>Note:</em>Only the lexicographical SNMP ordering is
- implemented in Mnesia, not the actual SNMP monitoring.</p>
+ expensive than usual, O(logN). Also, more memory is used.</p>
+ <p>Notice that only the lexicographical SNMP ordering is
+ implemented in <c>Mnesia</c>, not the actual SNMP monitoring.</p>
</desc>
</func>
<func>
- <name>start() -> ok | {error, Reason} </name>
- <fsummary>Start a local Mnesia system.</fsummary>
+ <name>start() -> ok | {error, Reason}</name>
+ <fsummary>Starts a local <c>Mnesia</c> system.</fsummary>
<desc>
- <p>The start-up procedure for a set of Mnesia nodes is a
- fairly complicated operation. A Mnesia system consists of a set
- of nodes, with Mnesia started locally on all
+ <marker id="start"></marker>
+ <p>The startup procedure for a set of <c>Mnesia</c> nodes is a
+ fairly complicated operation. A <c>Mnesia</c> system consists
+ of a set of nodes, with <c>Mnesia</c> started locally on all
participating nodes. Normally, each node has a directory where
- all the Mnesia files are written. This directory will be
- referred to as the Mnesia directory. Mnesia may also be
- started on disc-less nodes. See <c>mnesia:create_schema/1</c>
- and the Mnesia User's Guide for more information about disc-less
- nodes.
- </p>
- <p>The set of nodes which makes up a Mnesia system is kept in
- a schema and it is possible to add and remove Mnesia nodes
+ all the <c>Mnesia</c> files are written. This directory is
+ referred to as the <c>Mnesia</c> directory. <c>Mnesia</c> can
+ also be started on disc-less nodes. For more information
+ about disc-less nodes, see <c>mnesia:create_schema/1</c>
+ and the User's Guide.</p>
+ <p>The set of nodes that makes up a <c>Mnesia</c> system is kept
+ in a schema. <c>Mnesia</c> nodes can be added to or removed
from the schema. The initial schema is normally created on
disc with the function <c>mnesia:create_schema/1</c>. On
disc-less nodes, a tiny default schema is generated each time
- Mnesia is started. During the start-up procedure, Mnesia
- will exchange schema information between the nodes in order
- to verify that the table definitions are compatible.
- </p>
- <p>Each schema has a unique cookie which may be regarded as a
+ <c>Mnesia</c> is started. During the startup procedure,
+ <c>Mnesia</c> exchanges schema information between the nodes
+ to verify that the table definitions are compatible.</p>
+ <p>Each schema has a unique cookie, which can be regarded as a
unique schema identifier. The cookie must be the same on all
- nodes where Mnesia is supposed to run. See the Mnesia
- User's Guide for more information about these details.
- </p>
- <p>The schema file, as well as all other files which Mnesia
- needs, are kept in the Mnesia directory. The command line
- option <c>-mnesia dir Dir</c> can be used to specify the
- location of this directory to the Mnesia system. If no such
- command line option is found, the name of the directory
- defaults to <c>Mnesia.Node</c>.
- </p>
- <p><c>application:start(mnesia)</c> may also be used.</p>
+ nodes where <c>Mnesia</c> is supposed to run. For details,
+ see the User's Guide.</p>
+ <p>The schema file and all other files that <c>Mnesia</c>
+ needs are kept in the <c>Mnesia</c> directory. The
+ command-line option <c>-mnesia dir Dir</c> can be used to
+ specify the location of this directory to the <c>Mnesia</c>
+ system. If no such command-line option is found, the name
+ of the directory defaults to <c>Mnesia.Node</c>.</p>
+ <p><c>application:start(mnesia)</c> can also be used.</p>
</desc>
</func>
<func>
- <name>stop() -> stopped </name>
- <fsummary>Stop Mnesia locally.</fsummary>
+ <name>stop() -> stopped</name>
+ <fsummary>Stops <c>Mnesia</c> locally.</fsummary>
<desc>
- <p>Stops Mnesia locally on the current node.
- </p>
- <p><c>application:stop(mnesia)</c> may also be used.</p>
+ <marker id="stop"></marker>
+ <p>Stops <c>Mnesia</c> locally on the current node.</p>
+ <p><c>application:stop(mnesia)</c> can also be used.</p>
</desc>
</func>
<func>
- <name>subscribe(EventCategory) -> {ok, Node} | {error, Reason} </name>
- <fsummary>Subscribe to events of type <c>EventCategory</c>.</fsummary>
+ <name>subscribe(EventCategory) -> {ok, Node} | {error, Reason}</name>
+ <fsummary>Subscribes to events of type <c>EventCategory</c>.</fsummary>
<desc>
+ <marker id="subscribe"></marker>
<p>Ensures that a copy of all events of type
- <c>EventCategory</c> are sent to the caller. The event
- types available are described in the Mnesia User's Guide at <seealso marker="Mnesia_chap5#event_handling">Mnesia Event Handling</seealso>.</p>
- <p><c>Node</c> is the local node. For table events to be subscribed, mnesia must have a readable local copy of the table on the node.</p>
+ <c>EventCategory</c> is sent to the caller. The available
+ event types are described in the <seealso marker="Mnesia_chap5#event_handling">User's Guide</seealso>.</p>
</desc>
</func>
<func>
- <name>sync_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason) </name>
- <fsummary>Call the Fun in a context which is not protected by a transaction.</fsummary>
+ <name>sync_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
+ <fsummary>Calls the <c>Fun</c> in a context that is not protected by a transaction.</fsummary>
<desc>
- <p>Call the <c>Fun</c> in a context which is not protected
- by a transaction. The Mnesia function calls performed in the
- <c>Fun</c> are mapped to the corresponding dirty functions.
+ <marker id="sync_dirty"></marker>
+ <p>Calls the <c>Fun</c> in a context that is not protected by
+ a transaction. The <c>Mnesia</c> function calls performed in
+ the <c>Fun</c> are mapped to the corresponding dirty functions.
It is performed in almost the same context as
<c>mnesia:async_dirty/1,2</c>. The difference is that the
operations are performed synchronously. The caller waits for
the updates to be performed on all active replicas before
- the <c>Fun</c> returns. See <c>mnesia:activity/4</c> and the
- Mnesia User's Guide for more details.</p>
+ the <c>Fun</c> returns. For details, see
+ <c>mnesia:activity/4</c> and the User's Guide.</p>
</desc>
</func>
<func>
- <name>sync_log() -> ok | {error, Reason} </name>
- <fsummary>Perform a file sync of the local log file.</fsummary>
+ <name>sync_log() -> ok | {error, Reason}</name>
+ <fsummary>Performs a file sync of the local log file.</fsummary>
<desc>
<p>Ensures that the local transaction log file is synced to disk.
- On a single node system data written to disk tables, since the last dump,
- can be lost in case of a power outage.
- See <seealso marker="#dump_log/0">dump_log/0</seealso>.
- </p>
+ On a single node system, data written to disk tables since the
+ last dump can be lost if there is a power outage.
+ See <seealso marker="#dump_log/0">dump_log/0</seealso>.</p>
</desc>
</func>
-
<func>
- <name>sync_transaction(Fun, [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun} </name>
- <fsummary>Synchronously execute a transaction.</fsummary>
+ <name>sync_transaction(Fun, [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}</name>
+ <fsummary>Synchronously executes a transaction.</fsummary>
<desc>
- <p>This function waits until data have been committed and
+ <marker id="sync_transaction"></marker>
+ <p>Waits until data have been committed and
logged to disk (if disk is used) on every involved node before
- it returns, otherwise it behaves as
+ it returns, otherwise it behaves as
<c>mnesia:transaction/[1,2,3]</c>.</p>
- <p>This functionality can be used to avoid that one process may overload
- a database on another node.</p>
+ <p>This functionality can be used to avoid that one process
+ overloads a database on another node.</p>
</desc>
</func>
<func>
<name>system_info(InfoKey) -> Info | exit({aborted, Reason})</name>
- <fsummary>Return information about the Mnesia system</fsummary>
+ <fsummary>Returns information about the <c>Mnesia</c> system.</fsummary>
<desc>
- <p>Returns information about the Mnesia system, such as
- transaction statistics, db_nodes, and configuration parameters.
- Valid keys are:</p>
+ <marker id="system_info"></marker>
+ <p>Returns information about the <c>Mnesia</c> system, such as
+ transaction statistics, <c>db_nodes</c>, and configuration
+ parameters. The valid keys are as follows:</p>
<list type="bulleted">
<item>
- <p><c>all</c>. This argument returns a list of all
- local system information. Each element is a
- <c>{InfoKey, InfoVal}</c> tuples.<em>Note:</em> New <c>InfoKey</c>'s may
- be added and old undocumented <c>InfoKey</c>'s may be removed without
+ <p><c>all</c>. Returns a list of all local system
+ information. Each element is a <c>{InfoKey, InfoVal}</c>
+ tuple.</p>
+ <p>New <c>InfoKey</c>s can be added and old
+ undocumented <c>InfoKey</c>s can be removed without
notice.</p>
</item>
<item>
- <p><c>access_module</c>. This argument returns the name of
- the module which is configured to be the activity access
- callback module.
- </p>
+ <p><c>access_module</c>. Returns the name of module that is
+ configured to be the activity access callback module.</p>
</item>
<item>
- <p><c>auto_repair</c>. This argument returns
- <c>true</c> or <c>false</c> to indicate if Mnesia is
- configured to invoke the auto repair facility on corrupted
- disc files.
- </p>
+ <p><c>auto_repair</c>. Returns <c>true</c> or <c>false</c>
+ to indicate if <c>Mnesia</c> is configured to start the
+ auto-repair facility on corrupted disc files.</p>
</item>
<item>
- <p><c>backup_module</c>. This argument returns the name of
- the module which is configured to be the backup
- callback module.
- </p>
+ <p><c>backup_module</c>. Returns the name of the module
+ that is configured to be the backup callback module.</p>
</item>
<item>
- <p><c>checkpoints</c>. This argument
- returns a list of the names of the
- checkpoints currently active on this node.
- </p>
+ <p><c>checkpoints</c>. Returns a list of the names of the
+ checkpoints currently active on this node.</p>
</item>
<item>
- <p><c>event_module</c>. This argument returns the name of
- the module which is the event handler callback module.
- </p>
+ <p><c>event_module</c>. Returns the name of the module
+ that is the event handler callback module.</p>
</item>
<item>
- <p><c>db_nodes</c>. This argument returns
- the nodes which make up the persistent database. Disc
- less nodes will only be included in the list of nodes if
- they explicitly has been added to the schema, e.g. with
+ <p><c>db_nodes</c>. Returns the nodes that make up the
+ persistent database. Disc-less nodes are only included
+ in the list of nodes if they explicitly have been added
+ to the schema, for example, with
<c>mnesia:add_table_copy/3</c>. The function can be
- invoked even if Mnesia is not yet running.
- </p>
+ started even if <c>Mnesia</c> is not yet running.</p>
</item>
<item>
- <p><c>debug</c>. This argument returns the current
- debug level of Mnesia.
- </p>
+ <p><c>debug</c>. Returns the current debug level of
+ <c>Mnesia</c>.</p>
</item>
<item>
- <p><c>directory</c>. This argument returns the name of
- the Mnesia directory. It can be invoked even if Mnesia is
- not yet running.
- </p>
+ <p><c>directory</c>. Returns the name of the <c>Mnesia</c>
+ directory. It can be called even if <c>Mnesia</c> is
+ not yet running.</p>
</item>
<item>
- <p><c>dump_log_load_regulation</c>. This argument
- returns a boolean which tells whether Mnesia is
- configured to load regulate the dumper process or not.
- This feature is temporary and will disappear in future
- releases.
- </p>
+ <p><c>dump_log_load_regulation</c>. Returns a boolean that
+ tells if <c>Mnesia</c> is configured to regulate the
+ dumper process load.</p>
+ <p>This feature is temporary and will be removed in future
+ releases.</p>
</item>
<item>
- <p><c>dump_log_time_threshold</c>. This argument
- returns the time threshold for transaction log dumps in
- milliseconds.
- </p>
+ <p><c>dump_log_time_threshold</c>. Returns the time
+ threshold for transaction log dumps in milliseconds.</p>
</item>
<item>
- <p><c>dump_log_update_in_place</c>. This argument
- returns a boolean which tells whether Mnesia is
- configured to perform the updates in the dets files
- directly or if the updates should be performed in a copy
- of the dets files.
- </p>
+ <p><c>dump_log_update_in_place</c>. Returns a boolean that
+ tells if <c>Mnesia</c> is configured to perform the
+ updates in the <c>dets</c> files directly, or if the
+ updates are to be performed in a copy of the <c>dets</c>
+ files.</p>
</item>
<item>
- <p><c>dump_log_write_threshold</c>. This argument
- returns the write threshold for transaction log dumps as
- the number of writes to the transaction log.
- </p>
+ <p><c>dump_log_write_threshold</c>.
+ Returns the write threshold for transaction log dumps as
+ the number of writes to the transaction log.</p>
</item>
<item>
- <p><c>extra_db_nodes</c>. This argument returns a list
- of extra db_nodes to be contacted at start-up.
- </p>
+ <p><c>extra_db_nodes</c>. Returns a list
+ of extra <c>db_nodes</c> to be contacted at startup.</p>
</item>
<item>
- <p><c>fallback_activated</c>. This argument returns
- true if a fallback is activated, otherwise false.
- </p>
+ <p><c>fallback_activated</c>. Returns <c>true</c>
+ if a fallback is activated, otherwise <c>false</c>.</p>
</item>
<item>
- <p><c>held_locks</c>. This argument returns a list of
- all locks held by the local Mnesia lock manager.
- </p>
+ <p><c>held_locks</c>. Returns a list of all
+ locks held by the local <c>Mnesia</c> lock manager.</p>
</item>
<item>
- <p><c>is_running</c>. This argument returns <c>yes</c>
- or <c>no</c> to indicate if Mnesia is running. It may
- also return <c>starting</c> or <c>stopping</c>. Can be
- invoked even if Mnesia is not yet running.
- </p>
+ <p><c>is_running</c>. Returns <c>yes</c> or <c>no</c> to
+ indicate if <c>Mnesia</c> is running. It can
+ also return <c>starting</c> or <c>stopping</c>. Can be
+ called even if <c>Mnesia</c> is not yet running.</p>
</item>
<item>
- <p><c>local_tables</c>. This argument returns a list
- of all tables which are configured to reside locally.
- </p>
+ <p><c>local_tables</c>. Returns a list
+ of all tables that are configured to reside locally.</p>
</item>
<item>
- <p><c>lock_queue</c>. This argument returns a list of
+ <p><c>lock_queue</c>. Returns a list of
all transactions that are queued for execution by the
- local lock manager.
- </p>
+ local lock manager.</p>
</item>
<item>
- <p><c>log_version</c>. This argument returns the
- version number of the Mnesia transaction log format.
- </p>
+ <p><c>log_version</c>. Returns the version
+ number of the <c>Mnesia</c> transaction log format.</p>
</item>
<item>
- <p><c>master_node_tables</c>. This argument returns a
- list of all tables with at least one master node.
- </p>
+ <p><c>master_node_tables</c>. Returns a
+ list of all tables with at least one master node.</p>
</item>
<item>
- <p><c>protocol_version</c>. This argument
- returns the version number
- of the Mnesia inter-process communication protocol.
- </p>
+ <p><c>protocol_version</c>. Returns the version number of
+ the <c>Mnesia</c> inter-process communication protocol.</p>
</item>
<item>
- <p><c>running_db_nodes</c>. This argument returns a
- list of nodes where Mnesia currently is running. This
- function can be invoked even if Mnesia is not yet
- running, but it will then have slightly different
- semantics. If Mnesia is down on the local node, the
- function will return those other <c>db_nodes</c> and
- <c>extra_db_nodes</c> that for the moment are up and
- running. If Mnesia is started, the function will return
- those nodes that Mnesia on the local node is fully
- connected to. Only those nodes that Mnesia has exchanged
- schema information with are included as
+ <p><c>running_db_nodes</c>. Returns a list of nodes where
+ <c>Mnesia</c> currently is running. This function can be
+ called even if <c>Mnesia</c> is not yet running, but it
+ then has slightly different semantics.</p>
+ <p>If <c>Mnesia</c> is down on the local node, the function
+ returns those other <c>db_nodes</c> and
+ <c>extra_db_nodes</c> that for the moment are
+ operational.</p>
+ <p>If <c>Mnesia</c> is started, the function returns
+ those nodes that <c>Mnesia</c> on the local node is fully
+ connected to. Only those nodes that <c>Mnesia</c> has
+ exchanged schema information with are included as
<c>running_db_nodes</c>. After the merge of schemas, the
- local Mnesia system is fully operable and applications
- may perform access of remote replicas. Before the schema
- merge Mnesia will only operate locally. Sometimes there
- may be more nodes included in the
+ local <c>Mnesia</c> system is fully operable and
+ applications can perform access of remote replicas.
+ Before the schema merge, <c>Mnesia</c> only operates
+ locally. Sometimes there are more nodes included in the
<c>running_db_nodes</c> list than all <c>db_nodes</c>
- and <c>extra_db_nodes</c> together.
- </p>
+ and <c>extra_db_nodes</c> together.</p>
</item>
<item>
- <p><c>schema_location</c>. This argument returns the
- initial schema location.
- </p>
+ <p><c>schema_location</c>. Returns the
+ initial schema location.</p>
</item>
<item>
- <p><c>subscribers</c>. This argument returns a list of
- local processes currently subscribing to system events.
- </p>
+ <p><c>subscribers</c>. Returns a list of
+ local processes currently subscribing to system events.</p>
</item>
<item>
- <p><c>tables</c>. This argument returns a list of all
- locally known tables.
- </p>
+ <p><c>tables</c>. Returns a list of all
+ locally known tables.</p>
</item>
<item>
- <p><c>transactions</c>. This argument returns a list
- of all currently active local transactions.
- </p>
+ <p><c>transactions</c>. Returns a list
+ of all currently active local transactions.</p>
</item>
<item>
- <p><c>transaction_failures</c>. This argument returns
- a number which indicates how many transactions have
- failed since Mnesia was started.
- </p>
+ <p><c>transaction_failures</c>. Returns a
+ number that indicates how many transactions have
+ failed since <c>Mnesia</c> was started.</p>
</item>
<item>
- <p><c>transaction_commits</c>. This argument returns a
- number which indicates how many transactions have
- terminated successfully since Mnesia was started.
- </p>
+ <p><c>transaction_commits</c>. Returns a
+ number that indicates how many transactions have
+ terminated successfully since <c>Mnesia</c> was started.</p>
</item>
<item>
- <p><c>transaction_restarts</c>. This argument returns
- a number which indicates how many transactions have been
- restarted since Mnesia was started.
- </p>
+ <p><c>transaction_restarts</c>. Returns a
+ number that indicates how many transactions have been
+ restarted since <c>Mnesia</c> was started.</p>
</item>
<item>
- <p><c>transaction_log_writes</c>. This argument
- returns a number which indicates the number of write
- operation that have been performed to the transaction
- log since start-up.
- </p>
+ <p><c>transaction_log_writes</c>.
+ Returns a number that indicates how many write
+ operations that have been performed to the transaction
+ log since startup.</p>
</item>
<item>
- <p><c>use_dir</c>. This argument returns a boolean
- which indicates whether the Mnesia directory is used or
- not. Can be invoked even if Mnesia is not yet running.
- </p>
+ <p><c>use_dir</c>. Returns a boolean that indicates if
+ the <c>Mnesia</c> directory is used or not. Can be
+ started even if <c>Mnesia</c> is not yet running.</p>
</item>
<item>
- <p><c>version</c>. This argument returns the current
- version number of Mnesia.
- </p>
+ <p><c>version</c>. Returns the current
+ version number of <c>Mnesia</c>.</p>
</item>
</list>
</desc>
</func>
<func>
- <name>table(Tab [,[Option]]) -> QueryHandle </name>
+ <name>table(Tab [,[Option]]) -> QueryHandle</name>
<fsummary>Return a QLC query handle.</fsummary>
<desc>
- <p><marker id="qlc_table"></marker>
-Returns a QLC (Query List Comprehension) query handle, see
- <seealso marker="stdlib:qlc">qlc(3)</seealso>.The module <c>qlc</c> implements a query language, it
- can use mnesia tables as sources of data. Calling
- <c>mnesia:table/1,2</c> is the means to make the <c>mnesia</c>
- table <c>Tab</c> usable to QLC.</p>
- <p>The list of Options may contain mnesia options or QLC
- options, the following options are recognized by Mnesia:
- <c>{traverse, SelectMethod},{lock, Lock},{n_objects,Number}</c>, any other option is forwarded
- to QLC. The <c>lock</c> option may be <c>read</c> or
- <c>write</c>, default is <c>read</c>. The option
- <c>n_objects</c> specifies (roughly) the number of objects
- returned from mnesia to QLC. Queries to remote tables may
- need a larger chunks to reduce network overhead, default
- <c>100</c> objects at a time are returned. The option
- <c>traverse</c> determines the method to traverse the whole
- table (if needed), the default method is <c>select</c>:</p>
+ <marker id="qlc_table"></marker>
+ <marker id="table"></marker>
+ <p>Returns a Query List Comprehension (QLC) query handle,
+ see the <seealso marker="stdlib:qlc">qlc(3)</seealso>
+ manual page in <c>STDLIB</c>. The module <c>qlc</c>
+ implements a query language that can use <c>Mnesia</c>
+ tables as sources of data. Calling
+ <c>mnesia:table/1,2</c> is the means to make the
+ <c>mnesia</c> table <c>Tab</c> usable to QLC.</p>
+ <p><c>Option</c> can contain <c>Mnesia</c>
+ options or QLC options. <c>Mnesia</c> recognizes the
+ following options (any other option is forwarded to
+ QLC).</p>
+ <list type="bulleted">
+ <item><c>{lock, Lock}</c>, where <c>lock</c> can be
+ <c>read</c> or <c>write</c>. Default is <c>read</c>.
+ </item>
+ <item><c>{n_objects,Number}</c>, where <c>n_objects</c>
+ specifies (roughly) the number of objects returned
+ from <c>Mnesia</c> to QLC. Queries to remote tables
+ can need a larger chunk to reduce network overhead.
+ By default, <c>100</c> objects at a time are returned.
+ </item>
+ <item><c>{traverse, SelectMethod}</c>, where
+ <c>traverse</c> determines the method to traverse
+ the whole table (if needed). The default method is
+ <c>select</c>.
+ </item>
+ </list>
+ <p>There are two alternatives for <c>select</c>:</p>
<list type="bulleted">
<item>
<p><c>select</c>. The table is traversed by calling
- <c>mnesia:select/4</c> and <c>mnesia:select/1</c>. The
- match specification (the second argument of <c>select/3</c>)
- is assembled by QLC: simple filters are
- translated into equivalent match specifications while
- more complicated filters have to be applied to all
+ <c>mnesia:select/4</c> and <c>mnesia:select/1</c>.
+ The match specification (the second argument of
+ <c>select/3</c>) is assembled by QLC: simple filters
+ are translated into equivalent match specifications.
+ More complicated filters need to be applied to all
objects returned by <c>select/3</c> given a match
specification that matches all objects.</p>
</item>
<item>
- <p><c>{select, MatchSpec}</c>. As for <c>select</c>
- the table is traversed by calling <c>mnesia:select/3</c> and
- <c>mnesia:select/1</c>. The difference is that the match
- specification is explicitly given. This is how to state
- match specifications that cannot easily be expressed
- within the syntax provided by QLC.</p>
+ <p><c>{select, MatchSpec}</c>. As for <c>select</c>,
+ the table is traversed by calling <c>mnesia:select/3</c>
+ and <c>mnesia:select/1</c>. The difference is that the
+ match specification is explicitly given. This is how to
+ state match specifications that cannot easily be
+ expressed within the syntax provided by QLC.</p>
</item>
</list>
</desc>
</func>
<func>
<name>table_info(Tab, InfoKey) -> Info | exit({aborted, Reason})</name>
- <fsummary>Return local information about table.</fsummary>
+ <fsummary>Returns local information about table.</fsummary>
<desc>
+ <marker id="table_info"></marker>
<p>The <c>table_info/2</c> function takes two arguments.
- The first is the name of a Mnesia table, the second is one of
- the following keys:
- </p>
+ The first is the name of a <c>Mnesia</c> table.
+ The second is one of the following keys:</p>
<list type="bulleted">
<item>
- <p><c>all</c>. This argument returns a list of all
- local table information. Each element is a <c>{InfoKey, ItemVal}</c> tuples. <em>Note:</em> New <c>InfoItem</c>'s may be
- added and old undocumented <c>InfoItem</c>'s may be removed without
- notice.</p>
+ <p><c>all</c>. Returns a list of all local table
+ information. Each element is a
+ <c>{InfoKey, ItemVal}</c> tuple.</p>
+ <p>New <c>InfoItem</c>s can be added and old undocumented
+ <c>InfoItem</c>s can be removed without notice.</p>
</item>
<item>
- <p><c>access_mode</c>. This argument returns the
- access mode of the table. The access mode may either be
- read_only or read_write.
- </p>
+ <p><c>access_mode</c>. Returns the
+ access mode of the table. The access mode can be
+ <c>read_only</c> or <c>read_write</c>.</p>
</item>
<item>
- <p><c>arity</c>. This argument returns the arity of
- records in the table as specified in the schema.
- </p>
+ <p><c>arity</c>. Returns the arity of
+ records in the table as specified in the schema.</p>
</item>
<item>
- <p><c>attributes</c>. This argument returns the table
- attribute names which are specified in the schema.
- </p>
+ <p><c>attributes</c>. Returns the table
+ attribute names that are specified in the schema.</p>
</item>
<item>
- <p><c>checkpoints</c>. This argument returns the names
- of the currently active checkpoints which involves this
- table on this node.
- </p>
+ <p><c>checkpoints</c>. Returns the names
+ of the currently active checkpoints, which involve this
+ table on this node.</p>
</item>
<item>
- <p><c>cookie</c>. This argument returns a table cookie
- which is a unique system generated identifier for the
+ <p><c>cookie</c>. Returns a table cookie,
+ which is a unique system-generated identifier for the
table. The cookie is used internally to ensure that two
different table definitions using the same table name
cannot accidentally be intermixed. The cookie is
- generated when the table is initially created.
- </p>
+ generated when the table is created initially.</p>
</item>
<item>
- <p><c>disc_copies</c>. This argument returns the nodes
- where a disc_copy of the table resides according to the
- schema.
- </p>
+ <p><c>disc_copies</c>. Returns the nodes where a
+ <c>disc_copy</c> of the table resides according to the
+ schema.</p>
</item>
<item>
- <p><c>disc_only_copies </c>. This argument returns the
- nodes where a disc_only_copy of the table resides
- according to the schema.
- </p>
+ <p><c>disc_only_copies</c>. Returns the nodes where a
+ <c>disc_only_copy</c> of the table resides
+ according to the schema.</p>
</item>
<item>
- <p><c>index</c>. This argument returns the list of
- index position integers for the table.
- </p>
+ <p><c>index</c>. Returns the list of
+ index position integers for the table.</p>
</item>
<item>
- <p><c>load_node</c>. This argument returns the name of
- the node that Mnesia loaded the table from. The
- structure of the returned value is unspecified but may
- be useful for debugging purposes.
- </p>
+ <p><c>load_node</c>. Returns the name of
+ the node that <c>Mnesia</c> loaded the table from. The
+ structure of the returned value is unspecified, but
+ can be useful for debugging purposes.</p>
</item>
<item>
- <p><c>load_order</c>. This argument returns the load
+ <p><c>load_order</c>. Returns the load
order priority of the table. It is an integer and
- defaults to <c>0</c> (zero).
- </p>
+ defaults to <c>0</c> (zero).</p>
</item>
<item>
- <p><c>load_reason</c>. This argument returns the
- reason of why Mnesia decided to load the table. The
- structure of the returned value is unspecified but may
- be useful for debugging purposes.
- </p>
+ <p><c>load_reason</c>. Returns the
+ reason of why <c>Mnesia</c> decided to load the table.
+ The structure of the returned value is unspecified, but
+ can be useful for debugging purposes.</p>
</item>
<item>
- <p><c>local_content</c>. This argument returns
- <c>true</c> or <c>false</c> to indicate whether the
- table is configured to have locally unique content on
- each node.
- </p>
+ <p><c>local_content</c>. Returns <c>true</c> or
+ <c>false</c> to indicate if the table is configured to
+ have locally unique content on each node.</p>
</item>
<item>
- <p><c>master_nodes</c>. This argument returns the
- master nodes of a table.
- </p>
+ <p><c>master_nodes</c>. Returns the master nodes of a
+ table.</p>
</item>
<item>
- <p><c>memory</c>. This argument returns the number of
- words allocated to the table on this node.
- </p>
+ <p><c>memory</c>. Returns the number of
+ words allocated to the table on this node.</p>
</item>
<item>
- <p><c>ram_copies</c>. This argument returns the nodes
- where a ram_copy of the table resides according to the
- schema.
- </p>
+ <p><c>ram_copies</c>. Returns the nodes where a
+ <c>ram_copy</c> of the table resides according to the
+ schema.</p>
</item>
<item>
- <p><c>record_name</c>. This argument returns the
- record name, common for all records in the table
- </p>
+ <p><c>record_name</c>. Returns the
+ record name, common for all records in the table.</p>
</item>
<item>
- <p><c>size</c>. This argument returns the number of
- records inserted in the table.
- </p>
+ <p><c>size</c>. Returns the number of
+ records inserted in the table.</p>
</item>
<item>
- <p><c>snmp</c>. This argument returns the SNMP struct.
- <c>[]</c>meaning that the table currently has no SNMP
- properties.
- </p>
+ <p><c>snmp</c>. Returns the SNMP struct. <c>[]</c> means
+ that the table currently has no SNMP properties.</p>
</item>
<item>
- <p><c>storage_type</c>.This argument returns the local
+ <p><c>storage_type</c>. Returns the local
storage type of the table. It can be <c>disc_copies</c>,
<c>ram_copies</c>, <c>disc_only_copies</c>, or the atom
<c>unknown</c>. <c>unknown</c> is returned for all
- tables which only reside remotely.
- </p>
+ tables that only reside remotely.</p>
</item>
<item>
- <p><c>subscribers</c>. This argument returns a list
+ <p><c>subscribers</c>. Returns a list
of local processes currently subscribing to local table
- events which involve this table on this node.
- </p>
+ events that involve this table on this node.</p>
</item>
<item>
- <p><c>type</c>. This argument returns the table type,
- which is either <c>bag</c>, <c>set</c> or <c>ordered_set</c>..
- </p>
+ <p><c>type</c>. Returns the table type, which is
+ <c>bag</c>, <c>set</c>, or <c>ordered_set</c>.</p>
</item>
<item>
- <p><c>user_properties</c>. This argument returns the
- user associated table properties of the table. It is a
- list of the stored property records.
- </p>
+ <p><c>user_properties</c>. Returns the
+ user-associated table properties of the table. It is a
+ list of the stored property records.</p>
</item>
<item>
- <p><c>version</c>. This argument returns the current
+ <p><c>version</c>. Returns the current
version of the table definition. The table version is
incremented when the table definition is changed. The
- table definition may be incremented directly when the
- table definition has been changed in a schema
- transaction, or when a committed table definition is
- merged with table definitions from other nodes during
- start-up.
- </p>
+ table definition can be incremented directly when it
+ has been changed in a schema transaction, or
+ when a committed table definition is merged with
+ table definitions from other nodes during startup.</p>
</item>
<item>
- <p><c>where_to_read</c>.This argument returns the node
- where the table can be read. If the value <c>nowhere</c>
- is returned, the table is not loaded, or it resides at a
- remote node which is not running.
- </p>
+ <p><c>where_to_read</c>. Returns the node
+ where the table can be read. If value <c>nowhere</c>
+ is returned, either the table is not loaded or it
+ resides at a remote node that is not running.</p>
</item>
<item>
- <p><c>where_to_write</c>. This argument returns a list
- of the nodes that currently hold an active replica of
- the table.
- </p>
+ <p><c>where_to_write</c>. Returns a list of the nodes
+ that currently hold an active replica of the table.</p>
</item>
<item>
- <p><c>wild_pattern</c>. This argument returns a
- structure which can be given to the various match
- functions for a certain table. A record tuple is where all
- record fields have the value <c>'_'</c>.
- </p>
+ <p><c>wild_pattern</c>. Returns a
+ structure that can be given to the various match
+ functions for a certain table. A record tuple is where
+ all record fields have value <c>'_'</c>.</p>
</item>
</list>
</desc>
</func>
<func>
<name>transaction(Fun [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}</name>
- <fsummary>Execute a transaction.</fsummary>
+ <fsummary>Executes a transaction.</fsummary>
<desc>
- <p>This function executes the functional object <c>Fun</c>
- with arguments <c>Args</c> as a transaction.
- </p>
- <p>The code which executes inside the transaction
+ <marker id="transaction"></marker>
+ <p>Executes the functional object <c>Fun</c>
+ with arguments <c>Args</c> as a transaction.</p>
+ <p>The code that executes inside the transaction
can consist of a series of table manipulation functions.
- If something goes wrong inside the transaction as a result of a
- user error or a certain table not being available, the
- entire transaction is aborted and the function
- <c>transaction/1</c> returns the tuple
- <c>{aborted, Reason}</c>.
- </p>
- <p>If all is well, <c>{atomic, ResultOfFun}</c> is returned where
- <c>ResultOfFun</c> is the value of the last expression in
- <c>Fun</c>.
- </p>
- <p>A function which adds a family to the database can be
- written as follows if we have a structure <c>{family, Father, Mother, ChildrenList}</c>:
- </p>
+ If something goes wrong inside the transaction as a result
+ of a user error or a certain table not being available, the
+ entire transaction is terminated and the function
+ <c>transaction/1</c> returns the tuple
+ <c>{aborted, Reason}</c>.</p>
+ <p>If all is going well, <c>{atomic, ResultOfFun}</c> is
+ returned, where <c>ResultOfFun</c> is the value of the
+ last expression in <c>Fun</c>.</p>
+ <p>A function that adds a family to the database can be
+ written as follows if there is a structure
+ <c>{family, Father, Mother, ChildrenList}</c>:</p>
<code type="none">
add_family({family, F, M, Children}) ->
ChildOids = lists:map(fun oid/1, Children),
@@ -2715,23 +2591,20 @@ add_family({family, F, M, Children}) ->
end,
mnesia:transaction(Trans).
-oid(Rec) -> {element(1, Rec), element(2, Rec)}.
- </code>
- <p>This code adds a set of people to the database. Running this code
- within one transaction will ensure that either the whole
- family is added to the database, or the whole transaction
- aborts. For example, if the last child is badly formatted,
- or the executing process terminates due to an
+oid(Rec) -> {element(1, Rec), element(2, Rec)}.</code>
+ <p>This code adds a set of people to the database. Running
+ this code within one transaction ensures that either the whole
+ family is added to the database, or the whole transaction
+ terminates. For example, if the last child is badly formatted,
+ or the executing process terminates because of an
<c>'EXIT'</c> signal while executing the family code, the
- transaction aborts. Accordingly, the situation where half a
- family is added can never occur.
- </p>
+ transaction terminates. Thus, the situation where half a
+ family is added can never occur.</p>
<p>It is also useful to update the database within a transaction
if several processes concurrently update the same records.
- For example, the function <c>raise(Name, Amount)</c>, which
- adds <c>Amount</c> to the salary field of a person, should
- be implemented as follows:
- </p>
+ For example, the function <c>raise(Name, Amount)</c>, which
+ adds <c>Amount</c> to the salary field of a person, is to
+ be implemented as follows:</p>
<code type="none">
raise(Name, Amount) ->
mnesia:transaction(fun() ->
@@ -2743,71 +2616,68 @@ raise(Name, Amount) ->
_ ->
mnesia:abort("No such person")
end
- end).
- </code>
- <p>When this function executes within a transaction,
+ end).</code>
+ <p>When this function executes within a transaction,
several processes running on different nodes can concurrently
- execute the <c>raise/2</c> function without interfering
- with each other.
- </p>
- <p>Since Mnesia detects deadlocks, a transaction can be
- restarted any number of times. This function will attempt a restart as specified in
- <c>Retries</c>. <c>Retries</c> must
- be an integer greater than 0 or the atom <c>infinity</c>. Default is
- <c>infinity</c>.</p>
+ execute the function <c>raise/2</c> without interfering
+ with each other.</p>
+ <p>Since <c>Mnesia</c> detects deadlocks, a transaction can be
+ restarted any number of times. This function attempts a
+ restart as specified in <c>Retries</c>. <c>Retries</c> must
+ be an integer greater than 0 or the atom <c>infinity</c>.
+ Default is <c>infinity</c>.</p>
</desc>
</func>
<func>
- <name>transform_table(Tab, Fun, NewAttributeList, NewRecordName) -> {aborted, R} | {atomic, ok} </name>
- <fsummary>Change format on all records in table. <c>Tab</c></fsummary>
+ <name>transform_table(Tab, Fun, NewAttributeList, NewRecordName) -> {aborted, R} | {atomic, ok}</name>
+ <fsummary>Changes format on all records in table <c>Tab</c>.</fsummary>
<desc>
- <p>This function applies the argument <c>Fun</c> to all
- records in the table. <c>Fun</c> is a function which takes a
- record of the old type and returns a transformed record of the
- new type. The <c>Fun</c> argument can also be the atom
- <c>ignore</c>, it indicates that only the meta data about the table will
- be updated. Usage of <c>ignore</c> is not recommended but included
- as a possibility for the user to do his own transform.
- <c>NewAttributeList</c> and <c>NewRecordName</c>
- specifies the attributes and the new record type of converted
- table. Table name will always remain unchanged, if the
- record_name is changed only the mnesia functions which
- uses table identifiers will work, e.g. <c>mnesia:write/3</c>
- will work but <c>mnesia:write/1</c> will not.</p>
+ <marker id="transform_table_4"></marker>
+ <p>Applies argument <c>Fun</c> to all
+ records in the table. <c>Fun</c> is a function that takes a
+ record of the old type and returns a transformed record of
+ the new type. Argument <c>Fun</c> can also be the atom
+ <c>ignore</c>, which indicates that only the metadata
+ about the table is updated. Use of
+ <c>ignore</c> is not recommended, but included
+ as a possibility for the user do to an own transformation.</p>
+ <p><c>NewAttributeList</c> and <c>NewRecordName</c>
+ specify the attributes and the new record type of the
+ converted table. Table name always remains unchanged. If
+ <c>record_name</c> is changed, only the <c>Mnesia</c>
+ functions that use table identifiers work, for example,
+ <c>mnesia:write/3</c> works, but not <c>mnesia:write/1</c>.</p>
</desc>
</func>
<func>
- <name>transform_table(Tab, Fun, NewAttributeList) -> {aborted, R} | {atomic, ok} </name>
- <fsummary>Change format on all records in table. <c>Tab</c></fsummary>
+ <name>transform_table(Tab, Fun, NewAttributeList) -> {aborted, R} | {atomic, ok}</name>
+ <fsummary>Changes format on all records in table <c>Tab</c>.</fsummary>
<desc>
- <p>Invokes <c>mnesia:transform_table(Tab, Fun, NewAttributeList, RecName)</c>
- where <c>RecName</c> is <c>mnesia:table_info(Tab, record_name)</c>.</p>
+ <p>Calls <c>mnesia:transform_table(Tab, Fun,
+ NewAttributeList, RecName)</c>, where <c>RecName</c> is
+ <c>mnesia:table_info(Tab, record_name)</c>.</p>
</desc>
</func>
<func>
<name>traverse_backup(Source, [SourceMod,] Target, [TargetMod,] Fun, Acc) -> {ok, LastAcc} | {error, Reason}</name>
<fsummary>Traversal of a backup.</fsummary>
<desc>
- <p>With this function it is possible to iterate over a backup,
- either for the purpose of transforming it into a new backup,
- or just reading it. The arguments are explained briefly
- below. See the Mnesia User's Guide for additional
- details.
- </p>
+ <marker id="traverse_backup"></marker>
+ <p>Iterates over a backup, either to transform it into a
+ new backup, or read it. The arguments are explained briefly
+ here. For details, see the User's Guide.</p>
<list type="bulleted">
<item><c>SourceMod</c> and <c>TargetMod</c> are the names of
- the modules which actually access the backup
- media.
+ the modules that actually access the backup media.
</item>
<item><c>Source</c> and <c>Target</c> are opaque data used
- exclusively by the modules <c>SourceMod</c> and
- <c>TargetMod</c> for the purpose of initializing the
- backup media.
+ exclusively by modules <c>SourceMod</c> and <c>TargetMod</c>
+ to initialize the backup media.
</item>
<item><c>Acc</c> is an initial accumulator value.
</item>
<item><c>Fun(BackupItems, Acc)</c> is applied to each item in
- the backup. The Fun must return a tuple
+ the backup. The <c>Fun</c> must return a tuple
<c>{BackupItems,NewAcc}</c>, where <c>BackupItems</c> is
a list of valid backup items, and <c>NewAcc</c> is a new
accumulator value. The returned backup items are written
@@ -2821,355 +2691,341 @@ raise(Name, Amount) ->
</func>
<func>
<name>uninstall_fallback() -> ok | {error,Reason}</name>
- <fsummary>Uninstall a fallback.</fsummary>
+ <fsummary>Uninstalls a fallback.</fsummary>
<desc>
- <p>Invokes <c>mnesia:uninstall_fallback([{scope, global}])</c>.</p>
+ <marker id="uninstall_fallback_0"></marker>
+ <p>Calls the function
+ <c>mnesia:uninstall_fallback([{scope, global}])</c>.</p>
</desc>
</func>
<func>
<name>uninstall_fallback(Args) -> ok | {error,Reason}</name>
- <fsummary>Uninstall a fallback.</fsummary>
+ <fsummary>Uninstalls a fallback.</fsummary>
<desc>
- <p>This function is used to de-install a fallback before it
+ <p>Deinstalls a fallback before it
has been used to restore the database. This is normally a
distributed operation that is either performed on all
- nodes with disc resident schema or none. Uninstallation of
- fallbacks requires Erlang to be up and running on all
- involved nodes, but it does not matter if Mnesia is running
- or not. Which nodes that are considered as disc-resident
- nodes is determined from the schema info in the local
- fallback.
- </p>
- <p><c>Args</c> is a list of the following tuples:
- </p>
+ nodes with disc resident schema, or none. Uninstallation of
+ fallbacks requires Erlang to be operational on all
+ involved nodes, but it does not matter if <c>Mnesia</c> is
+ running or not. Which nodes that are considered as
+ disc-resident nodes is determined from the schema
+ information in the local fallback.</p>
+ <p><c>Args</c> is a list of the following tuples:</p>
<list type="bulleted">
- <item>
- <p><c>{module, BackupMod}</c>.
- See <c>mnesia:install_fallback/2</c> about the
- semantics.</p>
+ <item><c>{module, BackupMod}</c>. For semantics,
+ see <c>mnesia:install_fallback/2</c>.
</item>
- <item>
- <p><c>{scope, Scope}</c>
- See <c>mnesia:install_fallback/2</c> about the
- semantics.</p>
+ <item><c>{scope, Scope}</c>. For semantics,
+ see <c>mnesia:install_fallback/2</c>.
</item>
- <item>
- <p><c>{mnesia_dir, AlternateDir}</c>
- See <c>mnesia:install_fallback/2</c> about the
- semantics.</p>
+ <item><c>{mnesia_dir, AlternateDir}</c>. For semantics,
+ see <c>mnesia:install_fallback/2</c>.
</item>
</list>
</desc>
</func>
<func>
- <name>unsubscribe(EventCategory) -> {ok, Node} | {error, Reason} </name>
- <fsummary>Subscribe to events of type <c>EventCategory</c>.</fsummary>
+ <name>unsubscribe(EventCategory) -> {ok, Node} | {error, Reason}</name>
+ <fsummary>Subscribes to events of type <c>EventCategory</c>.</fsummary>
<desc>
+ <marker id="unsubscribe"></marker>
<p>Stops sending events of type
<c>EventCategory</c> to the caller.</p>
<p><c>Node</c> is the local node.</p>
</desc>
</func>
<func>
- <name>wait_for_tables(TabList,Timeout) -> ok | {timeout, BadTabList} | {error, Reason} </name>
- <fsummary>Wait for tables to be accessible.</fsummary>
+ <name>wait_for_tables(TabList, Timeout) -> ok | {timeout, BadTabList} | {error, Reason}</name>
+ <fsummary>Waits for tables to be accessible.</fsummary>
<desc>
- <p>Some applications need to wait for certain tables to
- be accessible in order to do useful work.
- <c>mnesia:wait_for_tables/2</c> hangs until all tables in the
- <c>TabList</c> are accessible, or until <c>timeout</c> is
- reached.</p>
+ <marker id="wait_for_tables"></marker>
+ <p>Some applications need to wait for certain tables to be
+ accessible to do useful work. <c>mnesia:wait_for_tables/2</c>
+ either hangs until all tables in <c>TabList</c> are accessible,
+ or until <c>timeout</c> is reached.</p>
</desc>
</func>
<func>
- <name>wread({Tab, Key}) -> transaction abort | RecordList </name>
- <fsummary>Read records with given key.</fsummary>
+ <name>wread({Tab, Key}) -> transaction abort | RecordList</name>
+ <fsummary>Reads records with given key.</fsummary>
<desc>
- <p>Invoke <c>mnesia:read(Tab, Key, write)</c>.</p>
+ <marker id="wread"></marker>
+ <p>Calls the function <c>mnesia:read(Tab, Key, write)</c>.</p>
</desc>
</func>
<func>
- <name>write(Record) -> transaction abort | ok </name>
+ <name>write(Record) -> transaction abort | ok</name>
<fsummary>Writes a record into the database.</fsummary>
<desc>
- <p>Invoke <c>mnesia:write(Tab, Record, write)</c> where
- <c>Tab</c> is <c>element(1, Record)</c>.</p>
+ <marker id="write_1"></marker>
+ <p>Calls the function <c>mnesia:write(Tab, Record, write)</c>,
+ where <c>Tab</c> is <c>element(1, Record)</c>.</p>
</desc>
</func>
<func>
- <name>write(Tab, Record, LockKind) -> transaction abort | ok </name>
- <fsummary>Write a record into the database.</fsummary>
+ <name>write(Tab, Record, LockKind) -> transaction abort | ok</name>
+ <fsummary>Writes a record into the database.</fsummary>
<desc>
- <p>Writes the record <c>Record</c> to the table <c>Tab</c>.
- </p>
- <p>The function returns <c>ok</c>, or aborts if an error
- occurs. For example, the transaction aborts if no
- <c>person</c> table exists.
- </p>
- <p>The semantics of this function is context sensitive. See
- <c>mnesia:activity/4</c> for more information. In transaction
- context it acquires a lock of type <c>LockKind</c>. The
- following lock types are supported: <c>write</c> and
- <c>sticky_write</c>.</p>
+ <marker id="write_3"></marker>
+ <p>Writes record <c>Record</c> to table <c>Tab</c>.</p>
+ <p>The function returns <c>ok</c>, or terminates if an error
+ occurs. For example, the transaction terminates if no
+ <c>person</c> table exists.</p>
+ <p>The semantics of this function is context-sensitive. For
+ details, see <c>mnesia:activity/4</c>. In
+ transaction-context, it acquires a lock of type
+ <c>LockKind</c>. The lock types <c>write</c> and
+ <c>sticky_write</c> are supported.</p>
</desc>
</func>
<func>
<name>write_lock_table(Tab) -> ok | transaction abort</name>
- <fsummary>Set write lock on an entire table.</fsummary>
+ <fsummary>Sets write lock on an entire table.</fsummary>
<desc>
- <p>Invokes <c>mnesia:lock({table, Tab}, write)</c>.</p>
+ <marker id="write_lock_table"></marker>
+ <p>Calls the function
+ <c>mnesia:lock({table, Tab}, write)</c>.</p>
</desc>
</func>
</funcs>
<section>
<title>Configuration Parameters</title>
- <p>Mnesia reads the following application configuration
+ <marker id="configuration_parameters"></marker>
+ <p><c>Mnesia</c> reads the following application configuration
parameters:</p>
<list type="bulleted">
<item>
- <p><c>-mnesia access_module Module</c>. The
- name of the Mnesia activity access callback module. The default is
- <c>mnesia</c>.
- </p>
+ <p><c>-mnesia access_module Module</c>. The name of the
+ <c>Mnesia</c> activity access callback module. Default is
+ <c>mnesia</c>.</p>
</item>
<item>
- <p><c>-mnesia auto_repair true | false</c>. This flag controls
- whether Mnesia will try to automatically repair
- files that have not been properly closed. The default is
- <c>true</c>.
- </p>
+ <p><c>-mnesia auto_repair true | false</c>. This flag
+ controls if <c>Mnesia</c> automatically tries to repair
+ files that have not been properly closed. Default is
+ <c>true</c>.</p>
</item>
<item>
- <p><c>-mnesia backup_module Module</c>. The
- name of the Mnesia backup callback module. The default is
- <c>mnesia_backup</c>.
- </p>
+ <p><c>-mnesia backup_module Module</c>. The name of the
+ <c>Mnesia</c> backup callback module. Default is
+ <c>mnesia_backup</c>.</p>
</item>
<item>
- <p><c>-mnesia debug Level</c>
- Controls the debug level of Mnesia.
- Possible values are:</p>
+ <p><c>-mnesia debug Level</c>. Controls the debug level
+ of <c>Mnesia</c>. The possible values are as follows:</p>
<taglist>
<tag><c>none</c></tag>
<item>
- <p>No trace outputs at all. This is the default setting.
- </p>
+ <p>No trace outputs. This is the default.</p>
</item>
<tag><c>verbose</c></tag>
<item>
<p>Activates tracing of important debug events. These
- debug events generate <c>{mnesia_info, Format, Args}</c>
- system events. Processes may subscribe to these events with
- <c>mnesia:subscribe/1</c>. The events are always sent to Mnesia's
- event handler.
- </p>
+ events generate <c>{mnesia_info, Format, Args}</c>
+ system events. Processes can subscribe to these events with
+ <c>mnesia:subscribe/1</c>. The events are always sent to
+ the <c>Mnesia</c> event handler.</p>
</item>
<tag><c>debug</c></tag>
<item>
<p>Activates all events at the verbose level plus full
trace of all debug events. These debug events generate
- <c>{mnesia_info, Format, Args}</c> system events. Processes may
- subscribe to these events with <c>mnesia:subscribe/1</c>. The
- events are always sent to the Mnesia event handler. On this
- debug level, the Mnesia event handler starts subscribing to
- updates in the schema table.
- </p>
+ <c>{mnesia_info, Format, Args}</c> system events.
+ Processes can subscribe to these events with
+ <c>mnesia:subscribe/1</c>. The events are always sent to
+ the <c>Mnesia</c> event handler. On this debug level,
+ the <c>Mnesia</c> event handler starts subscribing to
+ updates in the schema table.</p>
</item>
<tag><c>trace</c></tag>
<item>
- <p>Activates all events at the level debug. On this
- debug level, the Mnesia event handler starts subscribing to
- updates on all Mnesia tables. This level is only intended
- for debugging small toy systems since many large
- events may be generated.
- </p>
+ <p>Activates all events at the debug level. On this
+ level, the <c>Mnesia</c> event handler starts subscribing
+ to updates on all <c>Mnesia</c> tables. This level is
+ intended only for debugging small toy systems, as many
+ large events can be generated.</p>
</item>
<tag><c>false</c></tag>
- <item>
- <p>An alias for none.
- </p>
+ <item>An alias for none.
</item>
<tag><c>true</c></tag>
- <item>
- <p>An alias for debug.
- </p>
+ <item>An alias for debug.
</item>
</taglist>
</item>
<item>
<p><c>-mnesia core_dir Directory</c>. The name of the
- directory where Mnesia core files is stored or
- false. Setting it implies that also ram only nodes, will
- generate a core file if a crash occurs. </p>
+ directory where <c>Mnesia</c> core files is stored, or
+ false. Setting it implies that also RAM-only nodes
+ generate a core file if a crash occurs.</p>
</item>
<item>
- <p><c>-mnesia dc_dump_limit Number</c>.
- Controls how often <c>disc_copies</c> tables are dumped from memory.
+ <p><c>-mnesia dc_dump_limit Number</c>. Controls how often
+ <c>disc_copies</c> tables are dumped from memory.
Tables are dumped when
<c>filesize(Log) > (filesize(Tab)/Dc_dump_limit)</c>.
- Lower values reduces cpu overhead but increases disk space and
- startup times. The default is 4.</p>
+ Lower values reduce CPU overhead but increase disk space
+ and startup times. Default is 4.</p>
</item>
<item>
<p><c>-mnesia dir Directory</c>. The name of the directory
- where all Mnesia data is stored. The name of the directory must
- be unique for the current node. Two nodes may, under no
- circumstances, share the same Mnesia directory. The results are
- totally unpredictable.</p>
+ where all <c>Mnesia</c> data is stored. The directory name
+ must be unique for the current node. Two nodes must never
+ share the the same <c>Mnesia</c> directory. The results
+ are unpredictable.</p>
+ </item>
+ <item>
+ <p><c>-mnesia dump_disc_copies_at_startup true | false</c>.
+ If set to false, this disables the dumping of <c>disc_copies</c>
+ tables during startup while tables are being loaded. The default
+ is true.</p>
</item>
<item>
<p><c>-mnesia dump_log_load_regulation true | false</c>.
- Controls if the log dumps should be performed as fast as
- possible or if the dumper should do its own load
- regulation. This feature is temporary and will disappear in a
- future release. The default is <c>false</c>.
- </p>
+ Controls if log dumps are to be performed as fast as
+ possible, or if the dumper is to do its own load
+ regulation. Default is <c>false</c>.</p>
+ <p>This feature is temporary and will be removed in a
+ future release</p>
</item>
<item>
<p><c>-mnesia dump_log_update_in_place true | false</c>.
- Controls if log dumps are performed on a copy of
- the original data file, or if the log dump is
- performed on the original data file. The default is <c>true</c></p>
+ Controls if log dumps are performed on a copy of the
+ original data file, or if the log dump is performed
+ on the original data file. Default is <c>true</c></p>
</item>
<item>
- <marker id=" dump_log_write_threshold"></marker>
- <p><c>-mnesia dump_log_write_threshold Max</c>, where
- <c>Max</c> is an integer which specifies the maximum number of writes
- allowed to the transaction log before a new dump of the log
- is performed. It defaults to 100 log writes.
- </p>
+ <marker id=" dump_log_write_threshold"></marker>
+ <p><c>-mnesia dump_log_write_threshold Max</c>.
+ <c>Max</c> is an integer that specifies the maximum
+ number of writes allowed to the transaction log before
+ a new dump of the log is performed. Default is <c>100</c>
+ log writes.</p>
</item>
<item>
- <marker id=" dump_log_time_threshold"></marker>
- <p><c>-mnesia dump_log_time_threshold Max</c>,
- where <c>Max</c> is an integer which
- specifies the dump log interval in milliseconds. It defaults
- to 3 minutes. If a dump has not been performed within
- <c>dump_log_time_threshold</c> milliseconds, then a new dump is
- performed regardless of how many writes have been
- performed.
- </p>
+ <marker id=" dump_log_time_threshold"></marker>
+ <p><c>-mnesia dump_log_time_threshold Max</c>.
+ <c>Max</c> is an integer that specifies the dump log
+ interval in milliseconds. Default is 3 minutes. If a
+ dump has not been performed within
+ <c>dump_log_time_threshold</c> milliseconds, a new dump
+ is performed regardless of the number of writes
+ performed.</p>
</item>
<item>
- <p><c>-mnesia event_module Module</c>. The
- name of the Mnesia event handler callback module. The default is
- <c>mnesia_event</c>.
- </p>
+ <p><c>-mnesia event_module Module</c>. The name of the
+ <c>Mnesia</c> event handler callback module. Default is
+ <c>mnesia_event</c>.</p>
</item>
<item>
<p><c>-mnesia extra_db_nodes Nodes</c> specifies a list of
- nodes, in addition to the ones found in the schema, with which
- Mnesia should also establish contact. The default value
- is the empty list <c>[]</c>.
- </p>
+ nodes, in addition to the ones found in the schema, with
+ which <c>Mnesia</c> is also to establish contact. Default
+ is <c>[]</c> (empty list).</p>
</item>
<item>
- <p><c>-mnesia fallback_error_function {UserModule, UserFunc}</c>
- specifies a user supplied callback function
- which will be called if a fallback is installed and mnesia
- goes down on another node. Mnesia will call the function
- with one argument the name of the dying node, e.g.
- <c>UserModule:UserFunc(DyingNode)</c>.
- Mnesia should be restarted or else
- the database could be inconsistent.
- The default behaviour is to terminate mnesia.
- </p>
+ <p><c>-mnesia fallback_error_function {UserModule, UserFunc}</c>.
+ Specifies a user-supplied callback function, which is
+ called if a fallback is installed and <c>Mnesia</c> goes
+ down on another node. <c>Mnesia</c> calls the function
+ with one argument, the name of the dying node, for example,
+ <c>UserModule:UserFunc(DyingNode)</c>. <c>Mnesia</c> must
+ be restarted, otherwise the database can be inconsistent.
+ The default behavior is to terminate <c>Mnesia</c>.</p>
</item>
<item>
<p><c>-mnesia max_wait_for_decision Timeout</c>. Specifies
- how long Mnesia will wait for other nodes to share their
- knowledge regarding the outcome of an unclear transaction. By
- default the <c>Timeout</c> is set to the atom
- <c>infinity</c>, which implies that if Mnesia upon startup
- encounters a "heavyweight transaction" whose outcome is
- unclear, the local Mnesia will wait until Mnesia is started
- on some (in worst cases all) of the other nodes that were
- involved in the interrupted transaction. This is a very rare
- situation, but when/if it happens, Mnesia does not guess if
- the transaction on the other nodes was committed or aborted.
- Mnesia will wait until it knows the outcome and then act
- accordingly.
- </p>
+ how long <c>Mnesia</c> waits for other nodes to share their
+ knowledge about the outcome of an unclear transaction. By
+ default, <c>Timeout</c> is set to the atom <c>infinity</c>.
+ This implies that if <c>Mnesia</c> upon startup detects
+ a "heavyweight transaction" whose outcome is unclear, the
+ local <c>Mnesia</c> waits until <c>Mnesia</c> is started
+ on some (in the worst case all) of the other nodes that were
+ involved in the interrupted transaction. This is a rare
+ situation, but if it occurs, <c>Mnesia</c> does not guess if
+ the transaction on the other nodes was committed or
+ terminated. <c>Mnesia</c> waits until it knows the outcome
+ and then acts accordingly.</p>
<p>If <c>Timeout</c> is set to an integer value in
- milliseconds, Mnesia will force "heavyweight transactions"
+ milliseconds, <c>Mnesia</c> forces "heavyweight transactions"
to be finished, even if the outcome of the transaction for
the moment is unclear. After <c>Timeout</c> milliseconds,
- Mnesia will commit/abort the transaction and continue with
- the startup. This may lead to a situation where the
- transaction is committed on some nodes and aborted on other
- nodes. If the transaction was a schema transaction, the
- inconsistency may be fatal.
- </p>
+ <c>Mnesia</c> commits or terminates the transaction and
+ continues with the startup. This can lead to a situation
+ where the transaction is committed on some nodes and
+ terminated on other nodes. If the transaction is a
+ schema transaction, the inconsistency can be fatal.</p>
</item>
<item>
- <p><c>-mnesia no_table_loaders NUMBER</c> specifies the number of
- parallel table loaders during start. More loaders can be good if the
- network latency is high or if many tables contains few records.
- The default value is <c>2</c>.
- </p>
+ <p><c>-mnesia no_table_loaders NUMBER</c>. Specifies the number
+ of parallel table loaders during start. More loaders can be
+ good if the network latency is high or if many tables
+ contain few records. Default is <c>2</c>.</p>
</item>
<item>
- <p><c>-mnesia send_compressed Level</c> specifies the level of
- compression to be used when copying a table from the local node to
- another one. The default level is 0.
- </p>
- <p><c>Level</c> must be an integer in the interval [0, 9], with 0
- representing no compression and 9 representing maximum compression.
- Before setting it to a non-zero value, make sure the remote nodes
- understand this configuration.
- </p>
+ <p><c>-mnesia send_compressed Level</c>. Specifies the level of
+ compression to be used when copying a table from the local
+ node to another one. Default is <c>0</c>.</p>
+ <p><c>Level</c> must be an integer in the interval
+ <c>[0, 9]</c>, where <c>0</c> means no compression and
+ <c>9</c> means maximum compression. Before setting it to a
+ non-zero value, ensure that the remote nodes
+ understand this configuration.</p>
</item>
<item>
- <p><c>-mnesia schema_location Loc</c> controls where
- Mnesia will look for its schema. The parameter
- <c>Loc</c> may be one of the following atoms: </p>
+ <p><c>-mnesia schema_location Loc</c>. Controls where
+ <c>Mnesia</c> looks for its schema. Parameter
+ <c>Loc</c> can be one of the following atoms:</p>
<taglist>
<tag><c>disc</c></tag>
<item>
<p>Mandatory disc. The schema is assumed to be located
- in the Mnesia directory. If the schema cannot be found,
- Mnesia refuses to start. This is the old behavior.
- </p>
+ in the <c>Mnesia</c> directory. If the schema cannot
+ be found, <c>Mnesia</c> refuses to start. This is the
+ old behavior.</p>
</item>
<tag><c>ram</c></tag>
<item>
<p>Mandatory RAM. The schema resides in RAM
- only. At start-up, a tiny new schema is generated. This
- default schema just contains the definition of the schema
- table and only resides on the local node. Since no other
- nodes are found in the default schema, the configuration
- parameter <c>extra_db_nodes</c> must be used in
- order to let the
- node share its table definitions with other nodes. (The
- <c>extra_db_nodes</c> parameter may also be used on disc based nodes.)
- </p>
+ only. At startup, a tiny new schema is generated. This
+ default schema only contains the definition of the schema
+ table and only resides on the local node. Since no other
+ nodes are found in the default schema, configuration
+ parameter <c>extra_db_nodes</c> must be used to let the
+ node share its table definitions with other nodes.</p>
+ <p>Parameter <c>extra_db_nodes</c> can also be
+ used on disc based nodes.</p>
</item>
<tag><c>opt_disc</c></tag>
<item>
- <p>Optional disc. The schema may reside either on disc
- or in RAM. If the schema is found on disc, Mnesia starts as a
- disc based node and the storage type of the schema table is
- <c>disc_copies</c>. If no schema is found on disc, Mnesia starts
- as a disc-less node and the storage type of the schema table is
- <c>ram_copies</c>. The default value for the application parameter
- is <c>opt_disc</c>.
- </p>
+ <p>Optional disc. The schema can reside on disc or in
+ RAM. If the schema is found on disc, <c>Mnesia</c>
+ starts as a disc-based node and the storage type of
+ the schema table is <c>disc_copies</c>. If no schema is
+ found on disc, <c>Mnesia</c> starts as a disc-less node
+ and the storage type of the schema table is
+ <c>ram_copies</c>. Default value for the application
+ parameter is <c>opt_disc</c>.</p>
</item>
</taglist>
</item>
</list>
- <p>First the SASL application parameters are checked, then
- the command line flags are checked, and finally, the default
- value is chosen.
- </p>
+ <p>First, the <c>SASL</c> application parameters are checked,
+ then the command-line flags are checked, and finally, the
+ default value is chosen.</p>
</section>
<section>
<title>See Also</title>
- <p>mnesia_registry(3), mnesia_session(3), qlc(3),
- dets(3), ets(3), disk_log(3), application(3)
- </p>
+ <p><seealso marker="kernel:application">application(3)</seealso>,
+ <seealso marker="stdlib:dets">dets(3)</seealso>,
+ <seealso marker="kernel:disk_log">disk_log(3)</seealso>,
+ <seealso marker="stdlib:ets">ets(3)</seealso>,
+ <seealso marker="mnesia:mnesia_registry">mnesia_registry(3)</seealso>,
+ <seealso marker="stdlib:qlc">qlc(3)</seealso></p>
</section>
</erlref>
diff --git a/lib/mnesia/doc/src/mnesia_frag_hash.xml b/lib/mnesia/doc/src/mnesia_frag_hash.xml
index 0d660925e7..7e532634d0 100644
--- a/lib/mnesia/doc/src/mnesia_frag_hash.xml
+++ b/lib/mnesia/doc/src/mnesia_frag_hash.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -34,22 +35,23 @@
<file>mnesia_frag_hash.sgml</file>
</header>
<module>mnesia_frag_hash</module>
- <modulesummary>Defines mnesia_frag_hash callback behaviour</modulesummary>
+ <modulesummary>Defines mnesia_frag_hash callback behavior</modulesummary>
<description>
- <p>The module <c>mnesia_frag_hash</c> defines a callback
- behaviour for user defined hash functions of fragmented tables.</p>
+ <p>This module defines a callback behavior for user-defined hash
+ functions of fragmented tables.</p>
<p>Which module that is selected to implement the <c>mnesia_frag_hash</c>
- behaviour for a particular fragmented table is specified together
+ behavior for a particular fragmented table is specified together
with the other <c>frag_properties</c>. The <c>hash_module</c> defines
the module name. The <c>hash_state</c> defines the initial hash state.</p>
- <p>It implements dynamic hashing which is a kind of hashing
+ <p>This module implements dynamic hashing, which is a kind of hashing
that grows nicely when new fragments are added. It is well
- suited for scalable hash tables</p>
+ suited for scalable hash tables.</p>
</description>
+
<funcs>
<func>
<name>init_state(Tab, State) -> NewState | abort(Reason)</name>
- <fsummary>Initiate the hash state for a new table</fsummary>
+ <fsummary>Initiates the hash state for a new table.</fsummary>
<type>
<v>Tab = atom()</v>
<v>State = term()</v>
@@ -57,21 +59,21 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>This function is invoked when a fragmented table is
- created with <c>mnesia:create_table/2</c> or when a
- normal (un-fragmented) table is converted to be a
+ <p>Starts when a fragmented table is
+ created with the function <c>mnesia:create_table/2</c> or
+ when a normal (unfragmented) table is converted to be a
fragmented table with <c>mnesia:change_table_frag/2</c>.</p>
- <p>Note that the <c>add_frag/2</c> function will be invoked
- one time each for the rest of the fragments (all but number 1)
+ <p>Notice that the function <c>add_frag/2</c> is started
+ one time for each of the other fragments (except number 1)
as a part of the table creation procedure.</p>
- <p><c>State</c> is the initial value of the <c>hash_state</c> <c>frag_property</c>. The <c>NewState</c> will be stored as
- <c>hash_state</c> among the other <c>frag_properties</c>.
- </p>
+ <p><c>State</c> is the initial value of the <c>hash_state</c>
+ <c>frag_property</c>. <c>NewState</c> is stored as
+ <c>hash_state</c> among the other <c>frag_properties</c>.</p>
</desc>
</func>
<func>
<name>add_frag(State) -> {NewState, IterFrags, AdditionalLockFrags} | abort(Reason)</name>
- <fsummary>This function is invoked when a new fragment is added to a fragmented table</fsummary>
+ <fsummary>Starts when a new fragment is added to a fragmented table.</fsummary>
<type>
<v>State = term()</v>
<v>NewState = term()</v>
@@ -80,27 +82,26 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>In order to scale well, it is a good idea ensure that the
- records are evenly distributed over all fragments including
+ <p>To scale well, it is a good idea to ensure that the
+ records are evenly distributed over all fragments, including
the new one.</p>
- <p>The <c>NewState</c> will be stored as <c>hash_state</c> among the
- other <c>frag_properties</c>.
- </p>
- <p>As a part of the <c>add_frag</c> procedure, Mnesia will iterate
+ <p><c>NewState</c> is stored as <c>hash_state</c> among the
+ other <c>frag_properties</c>.</p>
+ <p>As a part of the <c>add_frag</c> procedure, <c>Mnesia</c> iterates
over all fragments corresponding to the <c>IterFrags</c> numbers
- and invoke <c>key_to_frag_number(NewState,RecordKey)</c> for
+ and starts <c>key_to_frag_number(NewState,RecordKey)</c> for
each record. If the new fragment differs from the old
- fragment, the record will be moved to the new fragment.</p>
+ fragment, the record is moved to the new fragment.</p>
<p>As the <c>add_frag</c> procedure is a part of a schema
- transaction Mnesia will acquire a write locks on the
- affected tables. That is both the fragments corresponding
+ transaction, <c>Mnesia</c> acquires write locks on the
+ affected tables. That is, both the fragments corresponding
to <c>IterFrags</c> and those corresponding to
<c>AdditionalLockFrags</c>.</p>
</desc>
</func>
<func>
<name>del_frag(State) -> {NewState, IterFrags, AdditionalLockFrags} | abort(Reason)</name>
- <fsummary>This function is invoked when a fragment is deleted from a fragmented table</fsummary>
+ <fsummary>Starts when a fragment is deleted from a fragmented table.</fsummary>
<type>
<v>State = term()</v>
<v>NewState = term()</v>
@@ -109,39 +110,38 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>The <c>NewState</c> will be stored as <c>hash_state</c> among the
- other <c>frag_properties</c>.
- </p>
- <p>As a part of the <c>del_frag</c> procedure, Mnesia will iterate
+ <p><c>NewState</c> is stored as <c>hash_state</c> among the
+ other <c>frag_properties</c>.</p>
+ <p>As a part of the <c>del_frag</c> procedure, <c>Mnesia</c> iterates
over all fragments corresponding to the <c>IterFrags</c> numbers
- and invoke <c>key_to_frag_number(NewState,RecordKey)</c> for
+ and starts <c>key_to_frag_number(NewState,RecordKey)</c> for
each record. If the new fragment differs from the old
- fragment, the record will be moved to the new fragment.</p>
- <p>Note that all records in the last fragment must be moved to
- another fragment as the entire fragment will be deleted.</p>
+ fragment, the record is moved to the new fragment.</p>
+ <p>Notice that all records in the last fragment must be moved to
+ another fragment, as the entire fragment is deleted.</p>
<p>As the <c>del_frag</c> procedure is a part of a schema
- transaction Mnesia will acquire a write locks on the
- affected tables. That is both the fragments corresponding
+ transaction, <c>Mnesia</c> acquires write locks on the
+ affected tables. That is, both the fragments corresponding
to <c>IterFrags</c> and those corresponding to
<c>AdditionalLockFrags</c>.</p>
</desc>
</func>
<func>
<name>key_to_frag_number(State, Key) -> FragNum | abort(Reason)</name>
- <fsummary>Resolves the key of a record into a fragment number</fsummary>
+ <fsummary>Resolves the key of a record into a fragment number.</fsummary>
<type>
<v>FragNum = integer()()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>This function is invoked whenever Mnesia needs to determine
+ <p>Starts whenever <c>Mnesia</c> needs to determine
which fragment a certain record belongs to. It is typically
- invoked at read, write and delete.</p>
+ started at <c>read</c>, <c>write</c>, and <c>delete</c>.</p>
</desc>
</func>
<func>
<name>match_spec_to_frag_numbers(State, MatchSpec) -> FragNums | abort(Reason)</name>
- <fsummary>Resolves a MatchSpec into a list of fragment numbers</fsummary>
+ <fsummary>Resolves a <c>MatchSpec</c> into a list of fragment numbers.</fsummary>
<type>
<v>MatcSpec = ets_select_match_spec()</v>
<v>FragNums = [FragNum]</v>
@@ -149,17 +149,17 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>This function is invoked whenever Mnesia needs to determine
- which fragments that needs to be searched for a MatchSpec.
- It is typically invoked at select and match_object.</p>
+ <p>This function is called whenever <c>Mnesia</c> needs to determine
+ which fragments that need to be searched for a <c>MatchSpec</c>.
+ It is typically called by <c>select</c> and
+ <c>match_object</c>.</p>
</desc>
</func>
</funcs>
<section>
<title>See Also</title>
- <p>mnesia(3)
- </p>
+ <p><seealso marker="mnesia:mnesia">mnesia(3)</seealso></p>
</section>
</erlref>
diff --git a/lib/mnesia/doc/src/mnesia_registry.xml b/lib/mnesia/doc/src/mnesia_registry.xml
index ad2b927315..b2529f08bd 100644
--- a/lib/mnesia/doc/src/mnesia_registry.xml
+++ b/lib/mnesia/doc/src/mnesia_registry.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -34,71 +35,66 @@
<file>mnesia_registry.sgml</file>
</header>
<module>mnesia_registry</module>
- <modulesummary>Dump support for registries in erl_interface. </modulesummary>
+ <modulesummary>Dump support for registries in erl_interface.</modulesummary>
<description>
- <p>The module <c>mnesia_registry</c> is usually part of
- <c>erl_interface</c>, but for the time being, it is a part of the
- Mnesia application.
- </p>
- <p><c>mnesia_registry</c> is mainly an module intended for
- internal usage within OTP, but it has two functions that
- are exported for public use.
- </p>
- <p>On C-nodes <c>erl_interface</c> has support for registry
- tables. These reside in RAM on the C-node but they may also be
- dumped into Mnesia tables. By default, the dumping of registry
- tables via <c>erl_interface</c> causes a corresponding Mnesia
- table to be created with <c>mnesia_registry:create_table/1</c>
- if necessary.
- </p>
- <p>The tables that are created with these functions can be
- administered as all other Mnesia tables. They may be included in
- backups or replicas may be added etc. The tables are in fact
- normal Mnesia tables owned by the user of the corresponding
- <c>erl_interface</c> registries.
- </p>
+ <p>This module is usually part of the <c>erl_interface</c>
+ application, but is currently part of the <c>Mnesia</c>
+ application.</p>
+ <p>This module is mainly intended for internal use within OTP,
+ but it has two functions that are exported for public use.</p>
+ <p>On C-nodes, <c>erl_interface</c> has support for registry
+ tables. These tables reside in RAM on the C-node, but can also
+ be dumped into <c>Mnesia</c> tables. By default, the dumping
+ of registry tables through <c>erl_interface</c> causes a
+ corresponding <c>Mnesia</c> table to be created with
+ <c>mnesia_registry:create_table/1</c>, if necessary.</p>
+ <p>Tables that are created with these functions can be
+ administered as all other <c>Mnesia</c> tables. They can be
+ included in backups, replicas can be added, and so on.
+ The tables are normal <c>Mnesia</c> tables owned by the user
+ of the corresponding <c>erl_interface</c> registries.</p>
</description>
+
<funcs>
<func>
<name>create_table(Tab) -> ok | exit(Reason)</name>
<fsummary>Creates a registry table in Mnesia.</fsummary>
<desc>
- <p>This is a wrapper function for
- <c>mnesia:create_table/2</c> which creates a table (if there is no existing table)
- with an appropriate set of <c>attributes</c>. The table will
- only reside on the local node and its storage type will be
- the same as the <c>schema</c> table on the local
- node, ie. <c>{ram_copies,[node()]}</c> or
- <c>{disc_copies,[node()]}</c>.
- </p>
- <p>It is this function that is used by <c>erl_interface</c> to
- create the Mnesia table if it did not already exist.</p>
+ <p>A wrapper function for <c>mnesia:create_table/2</c>,
+ which creates a table (if there is no existing table)
+ with an appropriate set of <c>attributes</c>. The table
+ only resides on the local node and its storage type is
+ the same as the <c>schema</c> table on the local node,
+ that is, <c>{ram_copies,[node()]}</c> or
+ <c>{disc_copies,[node()]}</c>.</p>
+ <p>This function is used by <c>erl_interface</c> to
+ create the <c>Mnesia</c> table if it does not already
+ exist.</p>
</desc>
</func>
<func>
<name>create_table(Tab, TabDef) -> ok | exit(Reason)</name>
- <fsummary>Creates a customized registry table in Mnesia. </fsummary>
+ <fsummary>Creates a customized registry table in Mnesia.</fsummary>
<desc>
- <p>This is a wrapper function for
- <c>mnesia:create_table/2</c> which creates a table (if there is no existing table)
- with an appropriate set of <c>attributes</c>. The attributes
- and <c>TabDef</c> are forwarded to
- <c>mnesia:create_table/2</c>. For example, if the table should
- reside as <c>disc_only_copies</c> on all nodes a call would
- look like:</p>
+ <p>A wrapper function for <c>mnesia:create_table/2</c>,
+ which creates a table (if there is no existing table)
+ with an appropriate set of <c>attributes</c>. The
+ attributes and <c>TabDef</c> are forwarded to
+ <c>mnesia:create_table/2</c>. For example, if the table
+ is to reside as <c>disc_only_copies</c> on all nodes,
+ a call looks as follows:</p>
<code type="none">
TabDef = [{{disc_only_copies, node()|nodes()]}],
- mnesia_registry:create_table(my_reg, TabDef)
- </code>
+ mnesia_registry:create_table(my_reg, TabDef)</code>
</desc>
</func>
</funcs>
<section>
<title>See Also</title>
- <p>mnesia(3), erl_interface(3)
- </p>
+ <p><seealso marker="erl_interface:index">erl_interface(3)</seealso>,
+ <seealso marker="mnesia:mnesia">mnesia(3)</seealso></p>
</section>
-
+
</erlref>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index dc98efbff3..18bb110104 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -38,7 +39,110 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.12.5</title>
+ <section><title>Mnesia 4.13.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Mnesia transactions could hang while waiting on a
+ response from a node who had stopped.</p>
+ <p>
+ Own Id: OTP-13423</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.13.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Avoid deadlock possibility in
+ <c>mnesia:del_table_copy/2</c></p>
+ <p>
+ Own Id: OTP-13284</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.13.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a process and file descriptor leak in
+ mnesia:restore/2.</p>
+ <p>
+ Own Id: OTP-13025 Aux Id: seq12957 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.13.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Improved index updates to avoid a timing glitch in
+ dirty_index_read.</p>
+ <p>
+ Own Id: OTP-12972</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Mnesia's dirty functions did not always exit with
+ <c>{aborted, Reason}</c> as documented when an error
+ occurred.</p>
+ <p>
+ Own Id: OTP-12714</p>
+ </item>
+ <item>
+ <p>
+ Consider file descriptors limits (emfile) as a fatal
+ error and do not delete log files. Previously the error
+ was seen as a corrupted disk and the log files deleted
+ which caused data loss.</p>
+ <p>
+ Own Id: OTP-12807</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Make Mnesia DCD dump behavior at start up optional, when
+ turned off mnesia loads large disc_copies tables faster.</p>
+ <p>
+ Own Id: OTP-12481</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.12.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/mnesia/doc/src/notes_history.xml b/lib/mnesia/doc/src/notes_history.xml
index 28b30f000d..b1c050a8af 100644
--- a/lib/mnesia/doc/src/notes_history.xml
+++ b/lib/mnesia/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/mnesia/doc/src/part.xml b/lib/mnesia/doc/src/part.xml
index 2a16b0a791..3406da4a34 100644
--- a/lib/mnesia/doc/src/part.xml
+++ b/lib/mnesia/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,12 +30,13 @@
<file>part.sgml</file>
</header>
<description>
- <p><em>Mnesia</em> is a distributed DataBase Management
- System(DBMS), appropriate for telecommunications applications and other
- Erlang applications which require continuous operation and exhibit soft
+ <p>The <c>Mnesia</c> application is a distributed Database Management
+ System (DBMS), appropriate for telecommunications applications and other
+ Erlang applications, which require continuous operation and exhibit soft
real-time properties.</p>
</description>
<xi:include href="Mnesia_chap1.xml"/>
+ <xi:include href="Mnesia_overview.xml"/>
<xi:include href="Mnesia_chap2.xml"/>
<xi:include href="Mnesia_chap3.xml"/>
<xi:include href="Mnesia_chap4.xml"/>
@@ -44,6 +46,5 @@
<xi:include href="Mnesia_App_A.xml"/>
<xi:include href="Mnesia_App_B.xml"/>
<xi:include href="Mnesia_App_C.xml"/>
- <xi:include href="Mnesia_App_D.xml"/>
</part>
diff --git a/lib/mnesia/doc/src/part_notes.xml b/lib/mnesia/doc/src/part_notes.xml
index cad1b48ed5..e1f475a40d 100644
--- a/lib/mnesia/doc/src/part_notes.xml
+++ b/lib/mnesia/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/mnesia/doc/src/part_notes_history.xml b/lib/mnesia/doc/src/part_notes_history.xml
index a97676050f..fec251cea6 100644
--- a/lib/mnesia/doc/src/part_notes_history.xml
+++ b/lib/mnesia/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/mnesia/doc/src/ref_man.xml b/lib/mnesia/doc/src/ref_man.xml
index e3c75be6e1..370267e3b8 100644
--- a/lib/mnesia/doc/src/ref_man.xml
+++ b/lib/mnesia/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,10 +33,10 @@
<file>refman.sgml</file>
</header>
<description>
- <p><em>Mnesia</em> is a distributed DataBase Management
+ <p>The <c>Mnesia</c> application is a distributed Database Management
System (DBMS), appropriate for telecommunications applications and other
- Erlang applications which require continuous operation and exhibit soft
- real-time properties. </p>
+ Erlang applications, which require continuous operation and exhibit soft
+ real-time properties.</p>
</description>
<xi:include href="mnesia.xml"/>
<xi:include href="mnesia_frag_hash.xml"/>
diff --git a/lib/mnesia/examples/Makefile b/lib/mnesia/examples/Makefile
index d9e6def283..0410ea2e8e 100644
--- a/lib/mnesia/examples/Makefile
+++ b/lib/mnesia/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/mnesia/examples/bench/bench.erl b/lib/mnesia/examples/bench/bench.erl
index d191169296..5a414edcf3 100644
--- a/lib/mnesia/examples/bench/bench.erl
+++ b/lib/mnesia/examples/bench/bench.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/examples/bench/bench.hrl b/lib/mnesia/examples/bench/bench.hrl
index 7b0e0c1280..5f19513fb2 100644
--- a/lib/mnesia/examples/bench/bench.hrl
+++ b/lib/mnesia/examples/bench/bench.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/examples/bench/bench_generate.erl b/lib/mnesia/examples/bench/bench_generate.erl
index 0fccc6c082..e838f07fbb 100644
--- a/lib/mnesia/examples/bench/bench_generate.erl
+++ b/lib/mnesia/examples/bench/bench_generate.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -152,9 +153,7 @@ generator_init(Monitor, C) ->
process_flag(trap_exit, true),
Tables = mnesia:system_info(tables),
ok = mnesia:wait_for_tables(Tables, infinity),
- {_Mega, Sec, Micro} = erlang:now(),
- Uniq = lists:sum(binary_to_list(term_to_binary(make_ref()))),
- random:seed(Uniq, Sec, Micro),
+ rand:seed(exsplus),
Counters = reset_counters(C, C#config.statistics_detail),
SessionTab = ets:new(bench_sessions, [public, {keypos, 1}]),
generator_loop(Monitor, C, SessionTab, Counters).
@@ -188,9 +187,9 @@ generator_loop(Monitor, C, SessionTab, Counters) ->
after 0 ->
{Name, {Nodes, Activity, Wlock}, Fun, CommitSessions} =
gen_trans(C, SessionTab),
- Before = erlang:now(),
+ Before = erlang:monotonic_time(),
Res = call_worker(Nodes, Activity, Fun, Wlock, mnesia_frag),
- After = erlang:now(),
+ After = erlang:monotonic_time(),
Elapsed = elapsed(Before, After),
post_eval(Monitor, C, Elapsed, Res, Name, CommitSessions, SessionTab, Counters)
end.
@@ -252,10 +251,8 @@ worker_loop(Parent) ->
end.
-elapsed({Before1, Before2, Before3}, {After1, After2, After3}) ->
- After = After1 * 1000000000000 + After2 * 1000000 + After3,
- Before = Before1 * 1000000000000 + Before2 * 1000000 + Before3,
- After - Before.
+elapsed(Before, After) ->
+ erlang:convert_time_unit(After-Before, native, micro_seconds).
%% Lookup counters
get_counters(_C, {table, Tab}) ->
@@ -350,7 +347,7 @@ commit_session(Fun) when is_function(Fun, 0) ->
%% Randlomly choose a transaction type according to benchmar spec
gen_trans(C, SessionTab) when C#config.generator_profile == random ->
- case random:uniform(100) of
+ case rand:uniform(100) of
Rand when Rand > 0, Rand =< 25 -> gen_t1(C, SessionTab);
Rand when Rand > 25, Rand =< 50 -> gen_t2(C, SessionTab);
Rand when Rand > 50, Rand =< 70 -> gen_t3(C, SessionTab);
@@ -368,7 +365,7 @@ gen_trans(C, SessionTab) ->
end.
gen_t1(C, _SessionTab) ->
- SubscrId = random:uniform(C#config.n_subscribers) - 1,
+ SubscrId = rand:uniform(C#config.n_subscribers) - 1,
SubscrKey = bench_trans:number_to_key(SubscrId, C),
Location = 4711,
ChangedBy = <<4711:(8*25)>>,
@@ -380,7 +377,7 @@ gen_t1(C, _SessionTab) ->
}.
gen_t2(C, _SessionTab) ->
- SubscrId = random:uniform(C#config.n_subscribers) - 1,
+ SubscrId = rand:uniform(C#config.n_subscribers) - 1,
SubscrKey = bench_trans:number_to_key(SubscrId, C),
{t2,
nearest_node(SubscrId, sync_dirty, C),
@@ -394,9 +391,9 @@ gen_t3(C, SessionTab) ->
'$end_of_table' ->
%% This generator does not have any session,
%% try reading someone elses session details
- SubscrId = random:uniform(C#config.n_subscribers) - 1,
+ SubscrId = rand:uniform(C#config.n_subscribers) - 1,
SubscrKey = bench_trans:number_to_key(SubscrId, C),
- ServerId = random:uniform(C#config.n_servers) - 1,
+ ServerId = rand:uniform(C#config.n_servers) - 1,
ServerBit = 1 bsl ServerId,
{t3,
nearest_node(SubscrId, transaction, C),
@@ -418,12 +415,12 @@ gen_t4(C, SessionTab) ->
%% This generator may already have sessions,
%% create a new session and hope that no other
%% generator already has occupied it
- SubscrId = random:uniform(C#config.n_subscribers) - 1,
+ SubscrId = rand:uniform(C#config.n_subscribers) - 1,
SubscrKey = bench_trans:number_to_key(SubscrId, C),
- ServerId = random:uniform(C#config.n_servers) - 1,
+ ServerId = rand:uniform(C#config.n_servers) - 1,
ServerBit = 1 bsl ServerId,
Details = <<4711:(8*2000)>>,
- DoRollback = (random:uniform(100) =< 2),
+ DoRollback = (rand:uniform(100) =< 2),
Insert = fun() -> ets:insert(SessionTab, {{SubscrId, SubscrKey, ServerId}, self()}) end,
{t4,
nearest_node(SubscrId, transaction, C),
@@ -436,11 +433,11 @@ gen_t5(C, SessionTab) ->
'$end_of_table' ->
%% This generator does not have any session,
%% try to delete someone elses session details
- SubscrId = random:uniform(C#config.n_subscribers) - 1,
+ SubscrId = rand:uniform(C#config.n_subscribers) - 1,
SubscrKey = bench_trans:number_to_key(SubscrId, C),
- ServerId = random:uniform(C#config.n_servers) - 1,
+ ServerId = rand:uniform(C#config.n_servers) - 1,
ServerBit = 1 bsl ServerId,
- DoRollback = (random:uniform(100) =< 2),
+ DoRollback = (rand:uniform(100) =< 2),
{t5,
nearest_node(SubscrId, transaction, C),
fun(Wlock) -> bench_trans:delete_session_from_server(Wlock, SubscrKey, ServerBit, ServerId, DoRollback) end,
@@ -450,7 +447,7 @@ gen_t5(C, SessionTab) ->
%% This generator do have at least one session,
%% delete it.
ServerBit = 1 bsl ServerId,
- DoRollback = (random:uniform(100) =< 2),
+ DoRollback = (rand:uniform(100) =< 2),
Delete = fun() -> ets:delete(SessionTab, {SubscrId, SubscrKey, ServerId}) end,
{t5,
nearest_node(SubscrId, transaction, C),
@@ -460,7 +457,7 @@ gen_t5(C, SessionTab) ->
end.
gen_ping(C, _SessionTab) ->
- SubscrId = random:uniform(C#config.n_subscribers) - 1,
+ SubscrId = rand:uniform(C#config.n_subscribers) - 1,
{ping,
nearest_node(SubscrId, transaction, C),
fun(_Wlock) -> {do_commit, true, []} end,
diff --git a/lib/mnesia/examples/bench/bench_populate.erl b/lib/mnesia/examples/bench/bench_populate.erl
index f82ee210b6..b35cc61b5a 100644
--- a/lib/mnesia/examples/bench/bench_populate.erl
+++ b/lib/mnesia/examples/bench/bench_populate.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/examples/bench/bench_trans.erl b/lib/mnesia/examples/bench/bench_trans.erl
index 945715daae..85641b29d4 100644
--- a/lib/mnesia/examples/bench/bench_trans.erl
+++ b/lib/mnesia/examples/bench/bench_trans.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/examples/mnesia_meter.erl b/lib/mnesia/examples/mnesia_meter.erl
index 68094c4431..73f35a4a46 100644
--- a/lib/mnesia/examples/mnesia_meter.erl
+++ b/lib/mnesia/examples/mnesia_meter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/examples/mnesia_tpcb.erl b/lib/mnesia/examples/mnesia_tpcb.erl
index 07ae73f0bd..c6eda1c448 100644
--- a/lib/mnesia/examples/mnesia_tpcb.erl
+++ b/lib/mnesia/examples/mnesia_tpcb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -163,7 +164,7 @@
-record(history,
{
history_id = {0, 0}, % {DriverId, DriverLocalHistoryid}
- time_stamp = now(), % Time point during active transaction
+ time_stamp = erlang:system_time(), % Time point during active transaction
branch_id = 0, % Branch associated with teller
teller_id = 0, % Teller invlolved in transaction
account_id = 0, % Account updated by transaction
@@ -411,9 +412,8 @@ config(remote_frag2_test, ReplicaType) ->
config(conflict_benchmark, ReplicaType) ->
Remote = nodes(),
Local = node(),
- Nodes = [Local | Remote],
- [{seed, {1326,448637,337711}},
- {db_nodes, Nodes},
+ Nodes = [Local | Remote],
+ [{db_nodes, Nodes},
{driver_nodes, Nodes},
{replica_nodes, Nodes},
{n_drivers_per_node, 10},
@@ -757,7 +757,7 @@ reporter_init(Starter, RC) ->
replica_type = Type
},
Drivers = start_drivers(RC, TC),
- Now = now_to_micros(erlang:now()),
+ Now = erlang:monotonic_time(),
State = #reporter_state{driver_pids = Drivers,
run_config = RC,
starter_pid = Starter,
@@ -895,7 +895,7 @@ add_time(Acc, New) ->
-define(AVOID_DIV_ZERO(_What_), try (_What_) catch _:_ -> 0 end).
show_report(State) ->
- Now = now_to_micros(erlang:now()),
+ Now = erlang:timestamp(),
Iters = State#reporter_state.n_iters,
Cfg = State#reporter_state.run_config,
Time = State#reporter_state.curr,
@@ -923,14 +923,14 @@ show_report(State) ->
case Cfg#run_config.send_bench_report of
true ->
ct_event:notify(
- #event{name = benchmark_data,
+ #event{name = benchmark_data,
data = [{suite,"mnesia_tpcb"},
{value,Tps}]});
_ ->
ok
end,
- State#reporter_state{prev_tps = Tps, prev_micros = Now}.
+ State#reporter_state{prev_tps = Tps, prev_micros = Now}.
signed_diff(Iters, Curr, Prev) ->
case Iters > 1 of
@@ -940,11 +940,6 @@ signed_diff(Iters, Curr, Prev) ->
sign(N) when N > 0 -> {"+", N};
sign(N) -> {"", N}.
-
-now_to_micros({Mega, Secs, Micros}) ->
- DT = calendar:now_to_datetime({Mega, Secs, 0}),
- S = calendar:datetime_to_gregorian_seconds(DT),
- (S * ?SECOND) + Micros.
start_drivers(RC, TC) ->
LastHistoryId = table_info(history, size),
@@ -997,13 +992,11 @@ alloc_local_branches([], Specs, OrphanBranches) ->
{Specs, OrphanBranches}.
driver_init(DS, AllBranches) ->
- case (DS#driver_state.run_config)#run_config.seed of
- undefined ->
- Seed = erlang:now();
- Seed ->
- Seed
+ Seed = case (DS#driver_state.run_config)#run_config.seed of
+ undefined -> rand:seed(exsplus);
+ ExpSeed -> rand:seed(ExpSeed)
end,
-
+
DS2 =
if
DS#driver_state.n_local_branches =:= 0 ->
@@ -1057,14 +1050,7 @@ calc_trans(DS) ->
%% Generate teller_id, account_id and delta
%% Time the TPC-B transaction
time_trans(DS) ->
- OldSeed = get(random_seed), % Avoid interference with Mnesia
- put(random_seed, DS#driver_state.seed),
- Random = random:uniform(),
- NewSeed = get(random_seed),
- case OldSeed of
- undefined -> erase(random_seed);
- _ -> put(random_seed, OldSeed)
- end,
+ {Random, NewSeed} = rand:uniform_s(DS#driver_state.seed),
TC = DS#driver_state.tab_config,
RC = DS#driver_state.run_config,
diff --git a/lib/mnesia/include/Makefile b/lib/mnesia/include/Makefile
index eea28045ea..fec963885c 100644
--- a/lib/mnesia/include/Makefile
+++ b/lib/mnesia/include/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/mnesia/src/Makefile b/lib/mnesia/src/Makefile
index ac38fa05ef..dae0df76f3 100644
--- a/lib/mnesia/src/Makefile
+++ b/lib/mnesia/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/mnesia/src/mnesia.app.src b/lib/mnesia/src/mnesia.app.src
index e755864792..c78a7cba1e 100644
--- a/lib/mnesia/src/mnesia.app.src
+++ b/lib/mnesia/src/mnesia.app.src
@@ -48,6 +48,6 @@
]},
{applications, [kernel, stdlib]},
{mod, {mnesia_sup, []}},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}]}.
+ {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 8f14831ad3..2fdc7afacd 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -145,7 +146,7 @@
%% Local function in order to avoid external function call
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
Value -> Value
end.
@@ -306,6 +307,8 @@ ms() ->
-spec abort(_) -> no_return().
+abort(Reason = {aborted, _}) ->
+ exit(Reason);
abort(Reason) ->
exit({aborted, Reason}).
@@ -807,7 +810,7 @@ next(Tid,Ts,Tab,Key)
tid ->
lock_table(Tid, Ts, Tab, read),
do_fixtable(Tab,Ts),
- New = (catch dirty_next(Tab,Key)),
+ New = ?CATCH(dirty_next(Tab,Key)),
stored_keys(Tab,New,Key,Ts,next,
val({Tab, setorbag}));
_Protocol ->
@@ -833,7 +836,7 @@ prev(Tid,Ts,Tab,Key)
tid ->
lock_table(Tid, Ts, Tab, read),
do_fixtable(Tab,Ts),
- New = (catch dirty_prev(Tab,Key)),
+ New = ?CATCH(dirty_prev(Tab,Key)),
stored_keys(Tab,New,Key,Ts,prev,
val({Tab, setorbag}));
_Protocol ->
@@ -965,7 +968,7 @@ foldl(Fun, Acc, Tab, LockKind) when is_function(Fun) ->
foldl(ActivityId, Opaque, Fun, Acc, Tab, LockKind) ->
{Type, Prev} = init_iteration(ActivityId, Opaque, Tab, LockKind),
- Res = (catch do_foldl(ActivityId, Opaque, Tab, dirty_first(Tab), Fun, Acc, Type, Prev)),
+ Res = ?CATCH(do_foldl(ActivityId, Opaque, Tab, dirty_first(Tab), Fun, Acc, Type, Prev)),
close_iteration(Res, Tab).
do_foldl(A, O, Tab, '$end_of_table', Fun, RAcc, _Type, Stored) ->
@@ -1011,7 +1014,7 @@ foldr(ActivityId, Opaque, Fun, Acc, Tab, LockKind) ->
true -> %% Order doesn't matter for set and bag
TempPrev %% Keep the order so we can use ordsets:del_element
end,
- Res = (catch do_foldr(ActivityId, Opaque, Tab, dirty_last(Tab), Fun, Acc, Type, Prev)),
+ Res = ?CATCH(do_foldr(ActivityId, Opaque, Tab, dirty_last(Tab), Fun, Acc, Type, Prev)),
close_iteration(Res, Tab).
do_foldr(A, O, Tab, '$end_of_table', Fun, RAcc, _Type, Stored) ->
@@ -1626,13 +1629,7 @@ dirty_read(Oid) ->
dirty_read(Tab, Key)
when is_atom(Tab), Tab /= schema ->
-%% case catch ?ets_lookup(Tab, Key) of
-%% {'EXIT', _} ->
- %% Bad luck, we have to perform a real lookup
- dirty_rpc(Tab, mnesia_lib, db_get, [Tab, Key]);
-%% Val ->
-%% Val
-%% end;
+ dirty_rpc(Tab, mnesia_lib, db_get, [Tab, Key]);
dirty_read(Tab, _Key) ->
abort({bad_type, Tab}).
@@ -1905,21 +1902,21 @@ any_table_info(Tab, _Item) ->
abort({bad_type, Tab}).
raw_table_info(Tab, Item) ->
- case ?catch_val({Tab, storage_type}) of
- ram_copies ->
- info_reply(catch ?ets_info(Tab, Item), Tab, Item);
- disc_copies ->
- info_reply(catch ?ets_info(Tab, Item), Tab, Item);
- disc_only_copies ->
- info_reply(catch dets:info(Tab, Item), Tab, Item);
- unknown ->
- bad_info_reply(Tab, Item);
- {'EXIT', _} ->
+ try
+ case ?ets_lookup_element(mnesia_gvar, {Tab, storage_type}, 2) of
+ ram_copies ->
+ info_reply(?ets_info(Tab, Item), Tab, Item);
+ disc_copies ->
+ info_reply(?ets_info(Tab, Item), Tab, Item);
+ disc_only_copies ->
+ info_reply(dets:info(Tab, Item), Tab, Item);
+ unknown ->
+ bad_info_reply(Tab, Item)
+ end
+ catch error:_ ->
bad_info_reply(Tab, Item)
end.
-info_reply({'EXIT', _Reason}, Tab, Item) ->
- bad_info_reply(Tab, Item);
info_reply({error, _Reason}, Tab, Item) ->
bad_info_reply(Tab, Item);
info_reply(Val, _Tab, _Item) ->
@@ -2063,9 +2060,8 @@ storage_count(T, {U, R, D, DO}) ->
end.
system_info(Item) ->
- case catch system_info2(Item) of
- {'EXIT',Error} -> abort(Error);
- Other -> Other
+ try system_info2(Item)
+ catch _:Error -> abort(Error)
end.
system_info2(all) ->
@@ -2171,7 +2167,7 @@ system_info2(version) ->
Version;
false ->
%% Ensure that it does not match
- {mnesia_not_loaded, node(), now()}
+ {mnesia_not_loaded, node(), erlang:timestamp()}
end;
Version ->
Version
@@ -2381,11 +2377,10 @@ del_table_index(Tab, Ix) ->
mnesia_schema:del_table_index(Tab, Ix).
transform_table(Tab, Fun, NewA) ->
- case catch val({Tab, record_name}) of
- {'EXIT', Reason} ->
- mnesia:abort(Reason);
- OldRN ->
- mnesia_schema:transform_table(Tab, Fun, NewA, OldRN)
+ try val({Tab, record_name}) of
+ OldRN -> mnesia_schema:transform_table(Tab, Fun, NewA, OldRN)
+ catch exit:Reason ->
+ mnesia:abort(Reason)
end.
transform_table(Tab, Fun, NewA, NewRN) ->
@@ -2796,7 +2791,7 @@ pre_qlc(Opts, Tab) ->
end.
post_qlc(Tab) ->
- case catch get(mnesia_activity_state) of
+ case get(mnesia_activity_state) of
{_,#tid{},_} -> ok;
_ ->
case ?catch_val({Tab, setorbag}) of
diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl
index c8010d5466..72940b4729 100644
--- a/lib/mnesia/src/mnesia.hrl
+++ b/lib/mnesia/src/mnesia.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -39,7 +40,12 @@
-define(ets_delete_table(Tab), ets:delete(Tab)).
-define(ets_fixtable(Tab, Bool), ets:fixtable(Tab, Bool)).
--define(catch_val(Var), (catch ?ets_lookup_element(mnesia_gvar, Var, 2))).
+
+-define(SAFE(OP), try (OP) catch error:_ -> ok end).
+-define(CATCH(OP), try (OP) catch _:_Reason -> {'EXIT', _Reason} end).
+
+-define(catch_val(Var), (try ?ets_lookup_element(mnesia_gvar, Var, 2)
+ catch error:_ -> {'EXIT', {badarg, []}} end)).
%% It's important that counter is first, since we compare tid's
@@ -53,7 +59,9 @@
up_stores = [], %% list of upper layer stores for nested trans
level = 1}). %% transaction level
--define(unique_cookie, {erlang:now(), node()}).
+-define(unique_cookie, {{erlang:monotonic_time() + erlang:time_offset(),
+ erlang:unique_integer(),1},
+ node()}).
-record(cstruct, {name, % Atom
type = set, % set | bag
diff --git a/lib/mnesia/src/mnesia_backup.erl b/lib/mnesia/src/mnesia_backup.erl
index 736f2ed9bf..78107bda56 100644
--- a/lib/mnesia/src/mnesia_backup.erl
+++ b/lib/mnesia/src/mnesia_backup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_bup.erl b/lib/mnesia/src/mnesia_bup.erl
index 3b084e7371..8b1143a352 100644
--- a/lib/mnesia/src/mnesia_bup.erl
+++ b/lib/mnesia/src/mnesia_bup.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -78,24 +79,21 @@
%% BunchOfRecords will be [] when the iteration is done.
iterate(Mod, Fun, Opaque, Acc) ->
R = #restore{bup_module = Mod, bup_data = Opaque},
- case catch read_schema_section(R) of
- {error, Reason} ->
- {error, Reason};
- {R2, {Header, Schema, Rest}} ->
- case catch iter(R2, Header, Schema, Fun, Acc, Rest) of
- {ok, R3, Res} ->
- catch safe_apply(R3, close_read, [R3#restore.bup_data]),
- {ok, Res};
- {error, Reason} ->
- catch safe_apply(R2, close_read, [R2#restore.bup_data]),
- {error, Reason};
- {'EXIT', Pid, Reason} ->
- catch safe_apply(R2, close_read, [R2#restore.bup_data]),
- {error, {'EXIT', Pid, Reason}};
- {'EXIT', Reason} ->
- catch safe_apply(R2, close_read, [R2#restore.bup_data]),
- {error, {'EXIT', Reason}}
- end
+ try read_schema_section(R) of
+ {R2, {Header, Schema, Rest}} ->
+ try iter(R2, Header, Schema, Fun, Acc, Rest) of
+ {ok, R3, Res} ->
+ close_read(R3),
+ {ok, Res}
+ catch throw:Err ->
+ close_read(R2),
+ Err;
+ _:Reason ->
+ close_read(R2),
+ {error, {Reason, erlang:get_stacktrace()}}
+ end
+ catch throw:{error,_} = Err ->
+ Err
end.
iter(R, Header, Schema, Fun, Acc, []) ->
@@ -114,9 +112,9 @@ iter(R, Header, Schema, Fun, Acc, BupItems) ->
safe_apply(R, write, [_, Items]) when Items =:= [] ->
R;
safe_apply(R, What, Args) ->
- Abort = fun(Re) -> abort_restore(R, What, Args, Re) end,
+ Abort = abort_restore_fun(R, What, Args),
Mod = R#restore.bup_module,
- case catch apply(Mod, What, Args) of
+ try apply(Mod, What, Args) of
{ok, Opaque, Items} when What =:= read ->
{R#restore{bup_data = Opaque}, Items};
{ok, Opaque} when What =/= read->
@@ -125,16 +123,23 @@ safe_apply(R, What, Args) ->
Abort(Re);
Re ->
Abort(Re)
+ catch _:Re ->
+ Abort(Re)
end.
-abort_restore(R, What, Args, Reason) ->
- Mod = R#restore.bup_module,
- Opaque = R#restore.bup_data,
+-spec abort_restore_fun(_, _, _) -> fun((_) -> no_return()).
+abort_restore_fun(R, What, Args) ->
+ fun(Re) -> abort_restore(R, What, Args, Re) end.
+
+abort_restore(R = #restore{bup_module=Mod}, What, Args, Reason) ->
dbg_out("Restore aborted. ~p:~p~p -> ~p~n",
[Mod, What, Args, Reason]),
- catch apply(Mod, close_read, [Opaque]),
+ close_read(R),
throw({error, Reason}).
+close_read(#restore{bup_module=Mod, bup_data=Opaque}) ->
+ ?SAFE(Mod:close_read(Opaque)).
+
fallback_to_schema() ->
Fname = fallback_bup(),
fallback_to_schema(Fname).
@@ -145,45 +150,41 @@ fallback_to_schema(Fname) ->
{error, Reason} ->
{error, Reason};
Schema ->
- case catch lookup_schema(schema, Schema) of
- {error, _} ->
- {error, "No schema in fallback"};
- List ->
- {ok, fallback, List}
+ try lookup_schema(schema, Schema) of
+ List -> {ok, fallback, List}
+ catch throw:_ ->
+ {error, "No schema in fallback"}
end
end.
%% Opens Opaque reads schema and then close
read_schema(Mod, Opaque) ->
R = #restore{bup_module = Mod, bup_data = Opaque},
- case catch read_schema_section(R) of
- {error, Reason} ->
- {error, Reason};
+ try read_schema_section(R) of
{R2, {_Header, Schema, _}} ->
- catch safe_apply(R2, close_read, [R2#restore.bup_data]),
- Schema
+ close_read(R2),
+ Schema
+ catch throw:{error,_} = Error ->
+ Error
end.
%% Open backup media and extract schema
%% rewind backup media and leave it open
%% Returns {R, {Header, Schema}}
read_schema_section(R) ->
- case catch do_read_schema_section(R) of
- {'EXIT', Reason} ->
- catch safe_apply(R, close_read, [R#restore.bup_data]),
- {error, {'EXIT', Reason}};
- {error, Reason} ->
- catch safe_apply(R, close_read, [R#restore.bup_data]),
- {error, Reason};
- {R2, {H, Schema, Rest}} ->
- Schema2 = convert_schema(H#log_header.log_version, Schema),
- {R2, {H, Schema2, Rest}}
- end.
+ {R2, {H, Schema, Rest}} = do_read_schema_section(R),
+ Schema2 = convert_schema(H#log_header.log_version, Schema),
+ {R2, {H, Schema2, Rest}}.
do_read_schema_section(R) ->
R2 = safe_apply(R, open_read, [R#restore.bup_data]),
- {R3, RawSchema} = safe_apply(R2, read, [R2#restore.bup_data]),
- do_read_schema_section(R3, verify_header(RawSchema), []).
+ try
+ {R3, RawSchema} = safe_apply(R2, read, [R2#restore.bup_data]),
+ do_read_schema_section(R3, verify_header(RawSchema), [])
+ catch T:E ->
+ close_read(R2),
+ erlang:raise(T,E,erlang:get_stacktrace())
+ end.
do_read_schema_section(R, {ok, B, C, []}, Acc) ->
case safe_apply(R, read, [R#restore.bup_data]) of
@@ -201,7 +202,7 @@ do_read_schema_section(R, {ok, B, _C, Rest}, Acc) ->
{R, {B, Acc, Rest}};
do_read_schema_section(_R, {error, Reason}, _Acc) ->
- {error, Reason}.
+ throw({error, Reason}).
verify_header([H | RawSchema]) when is_record(H, log_header) ->
Current = mnesia_log:backup_log_header(),
@@ -218,7 +219,7 @@ verify_header([H | RawSchema]) when is_record(H, log_header) ->
{error, {"Bad kind of header. Cannot be used as backup.", H}}
end;
verify_header(RawSchema) ->
- {error, {"Missing header. Cannot be used as backup.", catch hd(RawSchema)}}.
+ {error, {"Missing header. Cannot be used as backup.", ?CATCH(hd(RawSchema))}}.
refresh_cookie(Schema, NewCookie) ->
case lists:keysearch(schema, 2, Schema) of
@@ -345,7 +346,7 @@ create_schema(Ns, ok) ->
Str = mk_str(),
File = mnesia_lib:dir(Str),
file:delete(File),
- case catch make_initial_backup(Ns, File, Mod) of
+ try make_initial_backup(Ns, File, Mod) of
{ok, _Res} ->
case do_install_fallback(File, Mod) of
ok ->
@@ -353,8 +354,8 @@ create_schema(Ns, ok) ->
ok;
{error, Reason} ->
{error, Reason}
- end;
- {error, Reason} ->
+ end
+ catch throw:{error, Reason} ->
{error, Reason}
end
end
@@ -368,7 +369,7 @@ create_schema(_Ns, Reason) ->
{error, Reason}.
mk_str() ->
- Now = [integer_to_list(I) || I <- tuple_to_list(now())],
+ Now = integer_to_list(erlang:unique_integer([positive])),
lists:concat([node()] ++ Now ++ ".TMP").
make_initial_backup(Ns, Opaque, Mod) ->
@@ -384,10 +385,11 @@ make_initial_backup(Ns, Opaque, Mod) ->
do_apply(_, write, [_, Items], Opaque) when Items =:= [] ->
Opaque;
do_apply(Mod, What, Args, _Opaque) ->
- case catch apply(Mod, What, Args) of
+ try apply(Mod, What, Args) of
{ok, Opaque2} -> Opaque2;
- {error, Reason} -> throw({error, Reason});
- {'EXIT', Reason} -> throw({error, {'EXIT', Reason}})
+ {error, Reason} -> throw({error, Reason})
+ catch _:Reason ->
+ throw({error, {'EXIT', Reason}})
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -425,11 +427,11 @@ do_install_fallback(_Opaque, Args) ->
{error, {badarg, Args}}.
check_fallback_args([Arg | Tail], FA) ->
- case catch check_fallback_arg_type(Arg, FA) of
- {'EXIT', _Reason} ->
- {error, {badarg, Arg}};
+ try check_fallback_arg_type(Arg, FA) of
FA2 ->
check_fallback_args(Tail, FA2)
+ catch error:_ ->
+ {error, {badarg, Arg}}
end;
check_fallback_args([], FA) ->
{ok, FA}.
@@ -484,7 +486,7 @@ install_fallback_master(ClientPid, FA) ->
State = {start, FA},
Opaque = FA#fallback_args.opaque,
Mod = FA#fallback_args.module,
- Res = (catch iterate(Mod, fun restore_recs/4, Opaque, State)),
+ Res = iterate(Mod, fun restore_recs/4, Opaque, State),
unlink(ClientPid),
ClientPid ! {self(), Res},
exit(shutdown).
@@ -496,9 +498,7 @@ restore_recs(Recs, Header, Schema, {start, FA}) ->
%% No records in backup
Schema2 = convert_schema(Header#log_header.log_version, Schema),
CreateList = lookup_schema(schema, Schema2),
- case catch mnesia_schema:list2cs(CreateList) of
- {'EXIT', Reason} ->
- throw({error, {"Bad schema in restore_recs", Reason}});
+ try mnesia_schema:list2cs(CreateList) of
Cs ->
Ns = get_fallback_nodes(FA, Cs#cstruct.disc_copies),
global:set_lock({{mnesia_table_lock, schema}, self()}, Ns, infinity),
@@ -508,6 +508,8 @@ restore_recs(Recs, Header, Schema, {start, FA}) ->
Res = restore_recs(Recs, Header, Schema2, Pids),
global:del_lock({{mnesia_table_lock, schema}, self()}, Ns),
Res
+ catch _:Reason ->
+ throw({error, {"Bad schema in restore_recs", Reason}})
end;
restore_recs([], _Header, _Schema, Pids) ->
@@ -579,45 +581,46 @@ fallback_tmp_name() -> "FALLBACK.TMP".
fallback_receiver(Master, FA) ->
process_flag(trap_exit, true),
- case catch register(mnesia_fallback, self()) of
- {'EXIT', _} ->
- Reason = {already_exists, node()},
- local_fallback_error(Master, Reason);
- true ->
- FA2 = check_fallback_dir(Master, FA),
- Bup = FA2#fallback_args.fallback_bup,
- case mnesia_lib:exists(Bup) of
- true ->
- Reason2 = {already_exists, node()},
- local_fallback_error(Master, Reason2);
- false ->
- Mod = mnesia_backup,
- Tmp = FA2#fallback_args.fallback_tmp,
- R = #restore{mode = replace,
- bup_module = Mod,
- bup_data = Tmp},
- file:delete(Tmp),
- case catch fallback_receiver_loop(Master, R, FA2, schema) of
- {error, Reason} ->
- local_fallback_error(Master, Reason);
- Other ->
- exit(Other)
- end
- end
- end.
+ Res = try
+ register(mnesia_fallback, self()),
+ FA2 = check_fallback_dir(FA),
+ Bup = FA2#fallback_args.fallback_bup,
+ false = mnesia_lib:exists(Bup),
+ Mod = mnesia_backup,
+ Tmp = FA2#fallback_args.fallback_tmp,
+ R = #restore{mode = replace,
+ bup_module = Mod,
+ bup_data = Tmp},
+ file:delete(Tmp),
+ fallback_receiver_loop(Master, R, FA2, schema)
+ catch
+ error:_ ->
+ Reason = {already_exists, node()},
+ local_fallback_error(Master, Reason);
+ throw:{error, Reason} ->
+ local_fallback_error(Master, Reason)
+ end,
+ exit(Res).
local_fallback_error(Master, Reason) ->
Master ! {self(), {error, Reason}},
unlink(Master),
exit(Reason).
+
check_fallback_dir(Master, FA) ->
+ try check_fallback_dir(FA)
+ catch throw:{error,Reason} ->
+ local_fallback_error(Master, Reason)
+ end.
+
+check_fallback_dir(FA) ->
case mnesia:system_info(schema_location) of
ram ->
Reason = {has_no_disc, node()},
- local_fallback_error(Master, Reason);
+ throw({error, Reason});
_ ->
- Dir = check_fallback_dir_arg(Master, FA),
+ Dir = check_fallback_dir_arg(FA),
Bup = filename:join([Dir, fallback_name()]),
Tmp = filename:join([Dir, fallback_tmp_name()]),
FA#fallback_args{fallback_bup = Bup,
@@ -625,22 +628,20 @@ check_fallback_dir(Master, FA) ->
mnesia_dir = Dir}
end.
-check_fallback_dir_arg(Master, FA) ->
+check_fallback_dir_arg(FA) ->
case FA#fallback_args.use_default_dir of
true ->
mnesia_lib:dir();
false when FA#fallback_args.scope =:= local ->
Dir = FA#fallback_args.mnesia_dir,
- case catch mnesia_monitor:do_check_type(dir, Dir) of
- {'EXIT', _R} ->
+ try mnesia_monitor:do_check_type(dir, Dir)
+ catch _:_ ->
Reason = {badarg, {dir, Dir}, node()},
- local_fallback_error(Master, Reason);
- AbsDir->
- AbsDir
- end;
+ throw({error, Reason})
+ end;
false when FA#fallback_args.scope =:= global ->
Reason = {combine_error, global, dir, node()},
- local_fallback_error(Master, Reason)
+ throw({error, Reason})
end.
fallback_receiver_loop(Master, R, FA, State) ->
@@ -666,7 +667,7 @@ fallback_receiver_loop(Master, R, FA, State) ->
Bup = FA#fallback_args.fallback_bup,
Tmp = FA#fallback_args.fallback_tmp,
throw_bad_res(ok, file:rename(Tmp, Bup)),
- catch mnesia_lib:set(active_fallback, true),
+ ?SAFE(mnesia_lib:set(active_fallback, true)),
?eval_debug_fun({?MODULE, fallback_receiver_loop, post_swap}, []),
Master ! {self(), ok},
fallback_receiver_loop(Master, R, FA, stop);
@@ -697,7 +698,7 @@ throw_bad_res(_Expected, Actual) -> throw({error, Actual}).
tm_fallback_start(IgnoreFallback) ->
mnesia_schema:lock_schema(),
Res = do_fallback_start(fallback_exists(), IgnoreFallback),
- mnesia_schema: unlock_schema(),
+ mnesia_schema:unlock_schema(),
case Res of
ok -> ok;
{error, Reason} -> exit(Reason)
@@ -715,9 +716,9 @@ do_fallback_start(true, false) ->
BupFile = fallback_bup(),
Mod = mnesia_backup,
LocalTabs = ?ets_new_table(mnesia_local_tables, [set, public, {keypos, 2}]),
- case catch iterate(Mod, fun restore_tables/4, BupFile, {start, LocalTabs}) of
+ case iterate(Mod, fun restore_tables/4, BupFile, {start, LocalTabs}) of
{ok, _Res} ->
- catch dets:close(schema),
+ ?SAFE(dets:close(schema)),
TmpSchema = mnesia_lib:tab2tmp(schema),
DatSchema = mnesia_lib:tab2dat(schema),
AllLT = ?ets_match_object(LocalTabs, '_'),
@@ -733,8 +734,6 @@ do_fallback_start(true, false) ->
{error, {"Cannot start from fallback. Rename error.", Reason}}
end;
{error, Reason} ->
- {error, {"Cannot start from fallback", Reason}};
- {'EXIT', Reason} ->
{error, {"Cannot start from fallback", Reason}}
end.
@@ -996,10 +995,10 @@ uninstall_fallback_master(ClientPid, FA) ->
case fallback_to_schema(Bup) of
{ok, fallback, List} ->
Cs = mnesia_schema:list2cs(List),
- case catch get_fallback_nodes(FA, Cs#cstruct.disc_copies) of
+ try get_fallback_nodes(FA, Cs#cstruct.disc_copies) of
Ns when is_list(Ns) ->
- do_uninstall(ClientPid, Ns, FA);
- {error, Reason} ->
+ do_uninstall(ClientPid, Ns, FA)
+ catch throw:{error, Reason} ->
local_fallback_error(ClientPid, Reason)
end;
{error, Reason} ->
@@ -1042,13 +1041,13 @@ local_uninstall_fallback(Master, FA) ->
%% Don't trap exit
register(mnesia_fallback, self()), % May exit
- FA2 = check_fallback_dir(Master, FA), % May exit
+ FA2 = check_fallback_dir(Master, FA), % May exit
Master ! {self(), started},
receive
{Master, do_uninstall} ->
?eval_debug_fun({?MODULE, uninstall_fallback2, pre_delete}, []),
- catch mnesia_lib:set(active_fallback, false),
+ ?SAFE(mnesia_lib:set(active_fallback, false)),
Tmp = FA2#fallback_args.fallback_tmp,
Bup = FA2#fallback_args.fallback_bup,
file:delete(Tmp),
@@ -1071,10 +1070,8 @@ rec_uninstall(ClientPid, [Pid | Pids], AccRes) ->
{Pid, BadRes} ->
rec_uninstall(ClientPid, Pids, BadRes)
end;
-rec_uninstall(ClientPid, [], Res) ->
- ClientPid ! {self(), Res},
- unlink(ClientPid),
- exit(normal).
+rec_uninstall(_, [], Res) ->
+ Res.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Backup traversal
@@ -1125,12 +1122,11 @@ do_traverse_backup(ClientPid, Source, SourceMod, Target, TargetMod, Fun, Acc) ->
Iter =
if
TargetMod =/= read_only ->
- case catch do_apply(TargetMod, open_write, [Target], Target) of
- {error, Error} ->
+ try do_apply(TargetMod, open_write, [Target], Target)
+ catch throw:{error, Error} ->
unlink(ClientPid),
ClientPid ! {iter_done, self(), {error, Error}},
- exit(Error);
- Else -> Else
+ exit(Error)
end;
true ->
ignore
@@ -1139,16 +1135,16 @@ do_traverse_backup(ClientPid, Source, SourceMod, Target, TargetMod, Fun, Acc) ->
Res =
case iterate(SourceMod, fun trav_apply/4, Source, A) of
{ok, {iter, _, Acc2, _, Iter2}} when TargetMod =/= read_only ->
- case catch do_apply(TargetMod, commit_write, [Iter2], Iter2) of
- {error, Reason} ->
- {error, Reason};
- _ ->
- {ok, Acc2}
+ try
+ do_apply(TargetMod, commit_write, [Iter2], Iter2),
+ {ok, Acc2}
+ catch throw:{error, Reason} ->
+ {error, Reason}
end;
{ok, {iter, _, Acc2, _, _}} ->
{ok, Acc2};
{error, Reason} when TargetMod =/= read_only->
- catch do_apply(TargetMod, abort_write, [Iter], Iter),
+ ?CATCH(do_apply(TargetMod, abort_write, [Iter], Iter)),
{error, {"Backup traversal failed", Reason}};
{error, Reason} ->
{error, {"Backup traversal failed", Reason}}
diff --git a/lib/mnesia/src/mnesia_checkpoint.erl b/lib/mnesia/src/mnesia_checkpoint.erl
index 173e3be2f5..1407bc0557 100644
--- a/lib/mnesia/src/mnesia_checkpoint.erl
+++ b/lib/mnesia/src/mnesia_checkpoint.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2013
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -68,12 +69,12 @@
-import(mnesia_lib, [add/2, del/2, set/2, unset/1]).
-import(mnesia_lib, [dbg_out/2]).
--record(checkpoint_args, {name = {now(), node()},
+-record(checkpoint_args, {name = {erlang:unique_integer([positive]), node()},
allow_remote = true,
ram_overrides_dump = false,
nodes = [],
node = node(),
- now = now(),
+ now, %% unused
cookie = ?unique_cookie,
min = [],
max = [],
@@ -128,7 +129,7 @@ tm_enter_pending([], Pending) ->
Pending;
tm_enter_pending([Tab | Tabs], Pending) ->
%% io:format("Add ~p ~p ~p~n",[Tab, Pending, hd(tl(element(2, process_info(self(), current_stacktrace))))]),
- catch ?ets_insert(Tab, Pending),
+ ?SAFE(?ets_insert(Tab, Pending)),
tm_enter_pending(Tabs, Pending).
tm_exit_pending(Tid) ->
@@ -427,22 +428,22 @@ check_tables(Cp) ->
arrange_retainers(Cp, Overriders, AllTabs) ->
R = #retainer{cp_name = Cp#checkpoint_args.name},
- case catch [R#retainer{tab_name = Tab,
- writers = select_writers(Cp, Tab)}
- || Tab <- AllTabs] of
- {'EXIT', Reason} ->
- {error, Reason};
+ try [R#retainer{tab_name = Tab,
+ writers = select_writers(Cp, Tab)}
+ || Tab <- AllTabs] of
Retainers ->
{ok, Cp#checkpoint_args{ram_overrides_dump = Overriders,
- retainers = Retainers,
- nodes = writers(Retainers)}}
+ retainers = Retainers,
+ nodes = writers(Retainers)}}
+ catch throw:Reason ->
+ {error, Reason}
end.
select_writers(Cp, Tab) ->
case filter_remote(Cp, val({Tab, active_replicas})) of
[] ->
- exit({"Cannot prepare checkpoint (replica not available)",
- [Tab, Cp#checkpoint_args.name]});
+ throw({"Cannot prepare checkpoint (replica not available)",
+ [Tab, Cp#checkpoint_args.name]});
Writers ->
This = node(),
case {lists:member(Tab, Cp#checkpoint_args.max),
@@ -492,12 +493,12 @@ check_prep([], Name, Nodes, IgnoreNew) ->
collect_pending(Name, Nodes, IgnoreNew) ->
case rpc:multicall(Nodes, ?MODULE, call, [Name, collect_pending]) of
{Replies, []} ->
- case catch ?ets_new_table(mnesia_union, [bag]) of
- {'EXIT', Reason} -> %% system limit
+ try
+ UnionTab = ?ets_new_table(mnesia_union, [bag]),
+ compute_union(Replies, Nodes, Name, UnionTab, IgnoreNew)
+ catch error:Reason -> %% system limit
Msg = "Cannot create an ets table pending union",
- {error, {system_limit, Msg, Reason}};
- UnionTab ->
- compute_union(Replies, Nodes, Name, UnionTab, IgnoreNew)
+ {error, {system_limit, Msg, Reason}}
end;
{_, BadNodes} ->
deactivate(Nodes, Name),
@@ -1170,7 +1171,7 @@ iterate(Name, Tab, Fun, Acc, Source, Val) ->
{error, Reason};
{ok, Iter, Pid} ->
link(Pid), % We don't want any pending fixtable's
- Res = (catch iter(Fun, Acc, Iter)),
+ Res = ?CATCH(iter(Fun, Acc, Iter)),
unlink(Pid),
call(Name, {iter_end, Iter}),
case Res of
@@ -1246,7 +1247,7 @@ system_code_change(Cp, _Module, _OldVsn, _Extra) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', _ReASoN_} -> mnesia_lib:other_val(Var, _ReASoN_);
- _VaLuE_ -> _VaLuE_
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
+ _VaLuE_ -> _VaLuE_
end.
diff --git a/lib/mnesia/src/mnesia_checkpoint_sup.erl b/lib/mnesia/src/mnesia_checkpoint_sup.erl
index 2fe8df52f7..680cd86182 100644
--- a/lib/mnesia/src/mnesia_checkpoint_sup.erl
+++ b/lib/mnesia/src/mnesia_checkpoint_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 5a9bae54da..69ccc1d2c9 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -51,6 +52,7 @@
force_load_table/1,
async_dump_log/1,
sync_dump_log/1,
+ snapshot_dcd/1,
connect_nodes/1,
connect_nodes/2,
wait_for_schema_commit_lock/0,
@@ -76,7 +78,7 @@
change_table_majority/1,
del_active_replica/2,
wait_for_tables/2,
- get_network_copy/2,
+ get_network_copy/3,
merge_schema/0,
start_remote_sender/4,
schedule_late_disc_load/2
@@ -139,7 +141,8 @@ max_loaders() ->
-record(block_controller, {owner}).
-record(dump_log, {initiated_by,
- opt_reply_to
+ opt_reply_to,
+ operation = dump_log
}).
-record(net_load, {table,
@@ -184,7 +187,7 @@ max_loaders() ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
Value -> Value
end.
@@ -201,6 +204,15 @@ async_dump_log(InitBy) ->
?SERVER_NAME ! {async_dump_log, InitBy},
ok.
+snapshot_dcd(Tables) when is_list(Tables) ->
+ case [T || T <- Tables,
+ mnesia_lib:storage_type_at_node(node(), T) =/= disc_copies] of
+ [] ->
+ call({snapshot_dcd, Tables});
+ BadTabs ->
+ {error, {not_disc_copies, BadTabs}}
+ end.
+
%% Wait for tables to be active
%% If needed, we will wait for Mnesia to start
%% If Mnesia stops, we will wait for Mnesia to restart
@@ -230,9 +242,7 @@ do_wait_for_tables(Tabs, Timeout) ->
end.
reply_wait(Tabs) ->
- case catch mnesia_lib:active_tables() of
- {'EXIT', _} ->
- {error, {node_not_running, node()}};
+ try mnesia_lib:active_tables() of
Active when is_list(Active) ->
case Tabs -- Active of
[] ->
@@ -240,6 +250,7 @@ reply_wait(Tabs) ->
BadTabs ->
{timeout, BadTabs}
end
+ catch exit:_ -> {error, {node_not_running, node()}}
end.
wait_for_tables_init(From, Tabs) ->
@@ -250,13 +261,12 @@ wait_for_tables_init(From, Tabs) ->
exit(normal).
wait_for_init(From, Tabs, Init) ->
- case catch link(Init) of
- {'EXIT', _} ->
- %% Mnesia is not started
- {error, {node_not_running, node()}};
+ try link(Init) of
true when is_pid(Init) ->
cast({sync_tabs, Tabs, self()}),
rec_tabs(Tabs, Tabs, From, Init)
+ catch error:_ -> %% Mnesia is not started
+ {error, {node_not_running, node()}}
end.
sync_reply(Waiter, Tab) ->
@@ -319,20 +329,20 @@ release_schema_commit_lock() ->
unlink(whereis(?SERVER_NAME)).
%% Special for preparation of add table copy
-get_network_copy(Tab, Cs) ->
+get_network_copy(Tid, Tab, Cs) ->
% We can't let the controller queue this one
% because that may cause a deadlock between schema_operations
% and initial tableloadings which both takes schema locks.
% But we have to get copier_done msgs when the other side
% goes down.
call({add_other, self()}),
- Reason = {dumper,add_table_copy},
+ Reason = {dumper,{add_table_copy, Tid}},
Work = #net_load{table = Tab,reason = Reason,cstruct = Cs},
%% I'll need this cause it's linked trough the subscriber
%% might be solved by using monitor in subscr instead.
process_flag(trap_exit, true),
Load = load_table_fun(Work),
- Res = (catch Load()),
+ Res = ?CATCH(Load()),
process_flag(trap_exit, false),
call({del_other, self()}),
case Res of
@@ -581,11 +591,8 @@ call(Msg) ->
end.
remote_call(Node, Func, Args) ->
- case catch gen_server:call({?MODULE, Node}, {Func, Args, self()}, infinity) of
- {'EXIT', Error} ->
- {error, Error};
- Else ->
- Else
+ try gen_server:call({?MODULE, Node}, {Func, Args, self()}, infinity)
+ catch exit:Error -> {error, Error}
end.
multicall(Nodes, Msg) ->
@@ -646,6 +653,15 @@ handle_call({sync_dump_log, InitBy}, From, State) ->
State2 = add_worker(Worker, State),
noreply(State2);
+handle_call({snapshot_dcd, Tables}, From, State) ->
+ Worker = #dump_log{initiated_by = user,
+ opt_reply_to = From,
+ operation = fun() ->
+ mnesia_dumper:snapshot_dcd(Tables)
+ end},
+ State2 = add_worker(Worker, State),
+ noreply(State2);
+
handle_call(wait_for_schema_commit_lock, From, State) ->
Worker = #schema_commit_lock{owner = From},
State2 = add_worker(Worker, State),
@@ -657,7 +673,7 @@ handle_call(block_controller, From, State) ->
noreply(State2);
handle_call({update,Fun}, From, State) ->
- Res = (catch Fun()),
+ Res = ?CATCH(Fun()),
reply(From, Res),
noreply(State);
@@ -759,7 +775,7 @@ handle_call({net_load, Tab, Cs}, From, State) ->
true ->
Worker = #net_load{table = Tab,
opt_reply_to = From,
- reason = {dumper,add_table_copy},
+ reason = {dumper,{add_table_copy, unknown}},
cstruct = Cs
},
add_worker(Worker, State);
@@ -1164,11 +1180,11 @@ handle_info(Done = #loader_done{worker_pid=WPid, table_name=Tab}, State0) ->
Done#loader_done.needs_announce == true,
Done#loader_done.needs_reply == true ->
i_have_tab(Tab),
- %% Should be {dumper,add_table_copy} only
+ %% Should be {dumper,{add_table_copy, _}} only
reply(Done#loader_done.reply_to,
Done#loader_done.reply);
Done#loader_done.needs_reply == true ->
- %% Should be {dumper,add_table_copy} only
+ %% Should be {dumper,{add_table_copy,_}} only
reply(Done#loader_done.reply_to,
Done#loader_done.reply);
Done#loader_done.needs_announce == true, Tab == schema ->
@@ -1236,7 +1252,7 @@ handle_info(#sender_done{worker_pid=Pid, worker_res=Res}, State) ->
end;
handle_info({'EXIT', Pid, R}, State) when Pid == State#state.supervisor ->
- catch set(mnesia_status, stopping),
+ ?SAFE(set(mnesia_status, stopping)),
case State#state.dumper_pid of
undefined ->
dbg_out("~p was ~p~n", [?SERVER_NAME, R]),
@@ -1460,9 +1476,9 @@ orphan_tables([], _, _, LocalOrphans, RemoteMasters) ->
node_has_tabs([Tab | Tabs], Node, State) when Node /= node() ->
State2 =
- case catch update_whereabouts(Tab, Node, State) of
- State1 = #state{} -> State1;
- {'EXIT', R} -> %% Tab was just deleted?
+ try update_whereabouts(Tab, Node, State) of
+ State1 = #state{} -> State1
+ catch exit:R -> %% Tab was just deleted?
case ?catch_val({Tab, cstruct}) of
{'EXIT', _} -> State; % yes
_ -> erlang:error(R)
@@ -1748,22 +1764,17 @@ change_table_majority(Cs) ->
update_where_to_wlock(Tab) ->
WNodes = val({Tab, where_to_write}),
- Majority = case catch val({Tab, majority}) of
- true -> true;
- _ -> false
- end,
+ Majority = ?catch_val({Tab, majority}) == true,
set({Tab, where_to_wlock}, {WNodes, Majority}).
%% node To now has tab loaded, but this must be undone
%% This code is rpc:call'ed from the tab_copier process
%% when it has *not* released it's table lock
unannounce_add_table_copy(Tab, To) ->
- catch del_active_replica(Tab, To),
- case catch val({Tab , where_to_read}) of
- To ->
- mnesia_lib:set_remote_where_to_read(Tab);
- _ ->
- ignore
+ ?SAFE(del_active_replica(Tab, To)),
+ try To = val({Tab , where_to_read}),
+ mnesia_lib:set_remote_where_to_read(Tab)
+ catch _:_ -> ignore
end.
user_sync_tab(Tab) ->
@@ -2089,7 +2100,12 @@ start_remote_sender(Node, Tab, Receiver, Storage) ->
dump_and_reply(ReplyTo, Worker) ->
%% No trap_exit, die intentionally instead
- Res = mnesia_dumper:opt_dump_log(Worker#dump_log.initiated_by),
+ Res = case Worker#dump_log.operation of
+ dump_log ->
+ mnesia_dumper:opt_dump_log(Worker#dump_log.initiated_by);
+ F when is_function(F, 0) ->
+ F()
+ end,
ReplyTo ! #dumper_done{worker_pid = self(),
worker_res = Res},
unlink(ReplyTo),
@@ -2132,6 +2148,10 @@ load_table_fun(#net_load{cstruct=Cs, table=Tab, reason=Reason, opt_reply_to=Repl
reply_to = ReplyTo,
reply = {loaded, ok}
},
+ AddTableCopy = case Reason of
+ {dumper,{add_table_copy,_}} -> true;
+ _ -> false
+ end,
if
ReadNode == node() ->
%% Already loaded locally
@@ -2141,7 +2161,7 @@ load_table_fun(#net_load{cstruct=Cs, table=Tab, reason=Reason, opt_reply_to=Repl
Res = mnesia_loader:disc_load_table(Tab, load_local_content),
Done#loader_done{reply = Res, needs_announce = true, needs_sync = true}
end;
- AccessMode == read_only, Reason /= {dumper,add_table_copy} ->
+ AccessMode == read_only, not AddTableCopy ->
fun() -> disc_load_table(Tab, Reason, ReplyTo) end;
true ->
fun() ->
diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl
index 14665797a0..0e954d869d 100644
--- a/lib/mnesia/src/mnesia_dumper.erl
+++ b/lib/mnesia/src/mnesia_dumper.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,11 +35,13 @@
-export([
get_log_writes/0,
incr_log_writes/0,
+ needs_dump_ets/1,
raw_dump_table/2,
raw_named_dump_table/2,
start_regulator/0,
opt_dump_log/1,
- update/3
+ update/3,
+ snapshot_dcd/1
]).
%% Internal stuff
@@ -99,6 +102,19 @@ opt_dump_log(InitBy) ->
end,
perform_dump(InitBy, Reg).
+snapshot_dcd(Tables) ->
+ lists:foreach(
+ fun(Tab) ->
+ case mnesia_lib:storage_type_at_node(node(), Tab) of
+ disc_copies ->
+ mnesia_log:ets2dcd(Tab);
+ _ ->
+ %% Storage type was checked before queueing the op, though
+ skip
+ end
+ end, Tables),
+ dumped.
+
%% Scan for decisions
perform_dump(InitBy, Regulator) when InitBy == scan_decisions ->
?eval_debug_fun({?MODULE, perform_dump}, [InitBy]),
@@ -122,7 +138,7 @@ perform_dump(InitBy, Regulator) ->
U = mnesia_monitor:get_env(dump_log_update_in_place),
Cont = mnesia_log:init_log_dump(),
mnesia_recover:sync(),
- case catch do_perform_dump(Cont, U, InitBy, Regulator, undefined) of
+ try do_perform_dump(Cont, U, InitBy, Regulator, undefined) of
ok ->
?eval_debug_fun({?MODULE, post_dump}, [InitBy]),
case mnesia_monitor:use_dir() of
@@ -133,17 +149,15 @@ perform_dump(InitBy, Regulator) ->
end,
mnesia_recover:allow_garb(),
%% And now to the crucial point...
- mnesia_log:confirm_log_dump(Diff);
- {error, Reason} ->
- {error, Reason};
- {'EXIT', {Desc, Reason}} ->
+ mnesia_log:confirm_log_dump(Diff)
+ catch exit:Reason when Reason =/= fatal ->
case mnesia_monitor:get_env(auto_repair) of
true ->
- mnesia_lib:important(Desc, Reason),
+ mnesia_lib:important(error, Reason),
%% Ignore rest of the log
mnesia_log:confirm_log_dump(Diff);
false ->
- fatal(Desc, Reason)
+ fatal(error, Reason)
end
end;
{error, Reason} ->
@@ -161,24 +175,25 @@ scan_decisions(Fname, InitBy, Regulator) ->
mnesia_log:open_log(Name, Header, Fname, Exists,
mnesia_monitor:get_env(auto_repair), read_only),
Cont = start,
- Res = (catch do_perform_dump(Cont, false, InitBy, Regulator, undefined)),
- mnesia_log:close_log(Name),
- case Res of
- ok -> ok;
- {'EXIT', Reason} -> {error, Reason}
+ try
+ do_perform_dump(Cont, false, InitBy, Regulator, undefined)
+ catch exit:Reason when Reason =/= fatal ->
+ {error, Reason}
+ after mnesia_log:close_log(Name)
end
end.
do_perform_dump(Cont, InPlace, InitBy, Regulator, OldVersion) ->
case mnesia_log:chunk_log(Cont) of
{C2, Recs} ->
- case catch insert_recs(Recs, InPlace, InitBy, Regulator, OldVersion) of
- {'EXIT', R} ->
- Reason = {"Transaction log dump error: ~p~n", [R]},
- close_files(InPlace, {error, Reason}, InitBy),
- exit(Reason);
+ try insert_recs(Recs, InPlace, InitBy, Regulator, OldVersion) of
Version ->
do_perform_dump(C2, InPlace, InitBy, Regulator, Version)
+ catch _:R when R =/= fatal ->
+ ST = erlang:get_stacktrace(),
+ Reason = {"Transaction log dump error: ~p~n", [{R, ST}]},
+ close_files(InPlace, {error, Reason}, InitBy),
+ exit(Reason)
end;
eof ->
close_files(InPlace, ok, InitBy),
@@ -288,17 +303,16 @@ perform_update(Tid, SchemaOps, _DumperMode, _UseDir) ->
InitBy = fast_schema_update,
InPlace = mnesia_monitor:get_env(dump_log_update_in_place),
- ?eval_debug_fun({?MODULE, dump_schema_op}, [InitBy]),
- case catch insert_ops(Tid, schema_ops, SchemaOps, InPlace, InitBy,
- mnesia_log:version()) of
- {'EXIT', Reason} ->
- Error = {error, {"Schema update error", Reason}},
+ try insert_ops(Tid, schema_ops, SchemaOps, InPlace, InitBy,
+ mnesia_log:version()),
+ ?eval_debug_fun({?MODULE, post_dump}, [InitBy]),
+ close_files(InPlace, ok, InitBy),
+ ok
+ catch _:Reason when Reason =/= fatal ->
+ ST = erlang:get_stacktrace(),
+ Error = {error, {"Schema update error", {Reason, ST}}},
close_files(InPlace, Error, InitBy),
- fatal("Schema update error ~p ~p", [Reason, SchemaOps]);
- _ ->
- ?eval_debug_fun({?MODULE, post_dump}, [InitBy]),
- close_files(InPlace, ok, InitBy),
- ok
+ fatal("Schema update error ~p ~p", [{Reason,ST}, SchemaOps])
end.
insert_ops(_Tid, _Storage, [], _InPlace, _InitBy, _) -> ok;
@@ -347,13 +361,11 @@ dets_insert(Op,Tab,Key,Val) ->
case dets_incr_counter(Tab,Key) of
true ->
{RecName, Incr} = Val,
- case catch dets:update_counter(Tab, Key, Incr) of
- CounterVal when is_integer(CounterVal) ->
- ok;
- _ when Incr < 0 ->
+ try _ = dets:update_counter(Tab, Key, Incr)
+ catch error:_ when Incr < 0 ->
Zero = {RecName, Key, 0},
ok = dets:insert(Tab, Zero);
- _ ->
+ error:_ ->
Init = {RecName, Key, Incr},
ok = dets:insert(Tab, Init)
end;
@@ -771,7 +783,7 @@ insert_op(Tid, _, {op, clear_table, TabDef}, InPlace, InitBy) ->
end,
%% Need to catch this, it crashes on ram_copies if
%% the op comes before table is loaded at startup.
- catch insert(Tid, Storage, Tab, '_', Oid, clear_table, InPlace, InitBy)
+ ?CATCH(insert(Tid, Storage, Tab, '_', Oid, clear_table, InPlace, InitBy))
end;
insert_op(Tid, _, {op, merge_schema, TabDef}, InPlace, InitBy) ->
@@ -981,28 +993,10 @@ open_files(_Tab, _Storage, _UpdateInPlace, _InitBy) ->
false.
open_disc_copies(Tab, InitBy) ->
- DclF = mnesia_lib:tab2dcl(Tab),
- DumpEts =
- case file:read_file_info(DclF) of
- {error, enoent} ->
- false;
- {ok, DclInfo} ->
- DcdF = mnesia_lib:tab2dcd(Tab),
- case file:read_file_info(DcdF) of
- {error, Reason} ->
- mnesia_lib:dbg_out("File ~p info_error ~p ~n",
- [DcdF, Reason]),
- true;
- {ok, DcdInfo} ->
- Mul = case ?catch_val(dc_dump_limit) of
- {'EXIT', _} -> ?DumpToEtsMultiplier;
- Val -> Val
- end,
- DcdInfo#file_info.size =< (DclInfo#file_info.size * Mul)
- end
- end,
+ DumpEts = needs_dump_ets(Tab),
if
DumpEts == false; InitBy == startup ->
+ DclF = mnesia_lib:tab2dcl(Tab),
mnesia_log:open_log({?MODULE,Tab},
mnesia_log:dcl_log_header(),
DclF,
@@ -1017,6 +1011,27 @@ open_disc_copies(Tab, InitBy) ->
false
end.
+needs_dump_ets(Tab) ->
+ DclF = mnesia_lib:tab2dcl(Tab),
+ case file:read_file_info(DclF) of
+ {error, enoent} ->
+ false;
+ {ok, DclInfo} ->
+ DcdF = mnesia_lib:tab2dcd(Tab),
+ case file:read_file_info(DcdF) of
+ {error, Reason} ->
+ mnesia_lib:dbg_out("File ~p info_error ~p ~n",
+ [DcdF, Reason]),
+ true;
+ {ok, DcdInfo} ->
+ Mul = case ?catch_val(dc_dump_limit) of
+ {'EXIT', _} -> ?DumpToEtsMultiplier;
+ Val -> Val
+ end,
+ DcdInfo#file_info.size =< (DclInfo#file_info.size * Mul)
+ end
+ end.
+
%% Always opens the dcl file for writing overriding already_dumped
%% mechanismen, used for schema transactions.
open_dcl(Tab) ->
@@ -1042,14 +1057,13 @@ prepare_open(Tab, UpdateInPlace) ->
Dat;
false ->
Tmp = mnesia_lib:tab2tmp(Tab),
- case catch mnesia_lib:copy_file(Dat, Tmp) of
- ok ->
- Tmp;
- Error ->
+ try ok = mnesia_lib:copy_file(Dat, Tmp)
+ catch error:Error ->
fatal("Cannot copy dets file ~p to ~p: ~p~n",
[Dat, Tmp, Error])
- end
- end.
+ end,
+ Tmp
+ end.
del_opened_tab(Tab) ->
erase({?MODULE, Tab}).
@@ -1171,18 +1185,16 @@ raw_named_dump_table(Tab, Ftype) ->
Storage = ram_copies,
mnesia_lib:db_fixtable(Storage, Tab, true),
- case catch raw_dump_table(TabRef, Tab) of
- {'EXIT', Reason} ->
- mnesia_lib:db_fixtable(Storage, Tab, false),
- mnesia_lib:dets_sync_close(Tab),
- file:delete(TmpFname),
- mnesia_lib:unlock_table(Tab),
- exit({"Dump of table to disc failed", Reason});
- ok ->
- mnesia_lib:db_fixtable(Storage, Tab, false),
- mnesia_lib:dets_sync_close(Tab),
- mnesia_lib:unlock_table(Tab),
- ok = file:rename(TmpFname, Fname)
+ try
+ ok = raw_dump_table(TabRef, Tab),
+ ok = file:rename(TmpFname, Fname)
+ catch _:Reason ->
+ ?SAFE(file:delete(TmpFname)),
+ exit({"Dump of table to disc failed", Reason})
+ after
+ mnesia_lib:db_fixtable(Storage, Tab, false),
+ mnesia_lib:dets_sync_close(Tab),
+ mnesia_lib:unlock_table(Tab)
end;
{error, Reason} ->
mnesia_lib:unlock_table(Tab),
@@ -1248,6 +1260,6 @@ regulate(RegulatorPid) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
Value -> Value
end.
diff --git a/lib/mnesia/src/mnesia_event.erl b/lib/mnesia/src/mnesia_event.erl
index 67ec9d7399..58806793e5 100644
--- a/lib/mnesia/src/mnesia_event.erl
+++ b/lib/mnesia/src/mnesia_event.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -235,8 +236,7 @@ report_fatal(Format, Args, BinaryCore, CoreDumped) ->
end.
core_file(CoreDir,BinaryCore,Format,Args) ->
- %% Integers = tuple_to_list(date()) ++ tuple_to_list(time()),
- Integers = tuple_to_list(now()),
+ Integers = tuple_to_list(erlang:timestamp()),
Fun = fun(I) when I < 10 -> ["_0",I];
(I) -> ["_",I]
end,
diff --git a/lib/mnesia/src/mnesia_frag.erl b/lib/mnesia/src/mnesia_frag.erl
index 66fc20913c..cbb0dfb3be 100644
--- a/lib/mnesia/src/mnesia_frag.erl
+++ b/lib/mnesia/src/mnesia_frag.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -406,10 +407,11 @@ verify_numbers(FH,MatchSpec) ->
VerifyFun = fun(F) when is_integer(F), F >= 1, F =< N -> false;
(_F) -> true
end,
- case catch lists:filter(VerifyFun, FragNumbers) of
- [] ->
- FragNumbers;
- BadFrags ->
+ try
+ Frags = lists:filter(VerifyFun, FragNumbers),
+ Frags == [] orelse error(Frags),
+ FragNumbers
+ catch error:BadFrags ->
mnesia:abort({"match_spec_to_frag_numbers: Fragment numbers out of range",
BadFrags, {range, 1, N}})
end.
@@ -437,7 +439,7 @@ remote_select(ReplyTo, Ref, NameNodes, MatchSpec) ->
do_remote_select(ReplyTo, Ref, [{Name, Node} | NameNodes], MatchSpec) ->
if
Node == node() ->
- Res = (catch {ok, mnesia:dirty_select(Name, MatchSpec)}),
+ Res = ?CATCH({ok, mnesia:dirty_select(Name, MatchSpec)}),
ReplyTo ! {remote_select, Ref, Node, Res},
do_remote_select(ReplyTo, Ref, NameNodes, MatchSpec);
true ->
@@ -886,17 +888,19 @@ adjust_before_split(FH) ->
HashMod:add_frag(HashState)
end,
N = FH#frag_state.n_fragments + 1,
- FromFrags2 = (catch lists:sort(FromFrags)),
- UnionFrags = (catch lists:merge(FromFrags2, lists:sort(AdditionalWriteFrags))),
VerifyFun = fun(F) when is_integer(F), F >= 1, F =< N -> false;
(_F) -> true
end,
- case catch lists:filter(VerifyFun, UnionFrags) of
- [] ->
- FH2 = FH#frag_state{n_fragments = N,
- hash_state = HashState2},
- {FH2, FromFrags2, UnionFrags};
- BadFrags ->
+ try
+ FromFrags2 = lists:sort(FromFrags),
+ UnionFrags = lists:merge(FromFrags2, lists:sort(AdditionalWriteFrags)),
+
+ Frags = lists:filter(VerifyFun, UnionFrags),
+ Frags == [] orelse error(Frags),
+ FH2 = FH#frag_state{n_fragments = N,
+ hash_state = HashState2},
+ {FH2, FromFrags2, UnionFrags}
+ catch error:BadFrags ->
mnesia:abort({"add_frag: Fragment numbers out of range",
BadFrags, {range, 1, N}})
end.
@@ -981,22 +985,24 @@ adjust_before_merge(FH) ->
HashMod:del_frag(HashState)
end,
N = FH#frag_state.n_fragments,
- FromFrags2 = (catch lists:sort(FromFrags)),
- UnionFrags = (catch lists:merge(FromFrags2, lists:sort(AdditionalWriteFrags))),
VerifyFun = fun(F) when is_integer(F), F >= 1, F =< N -> false;
(_F) -> true
end,
- case catch lists:filter(VerifyFun, UnionFrags) of
- [] ->
- case lists:member(N, FromFrags2) of
- true ->
- FH2 = FH#frag_state{n_fragments = N - 1,
- hash_state = HashState2},
- {FH2, FromFrags2, UnionFrags};
+ try
+ FromFrags2 = lists:sort(FromFrags),
+ UnionFrags = lists:merge(FromFrags2, lists:sort(AdditionalWriteFrags)),
+
+ Frags = lists:filter(VerifyFun, UnionFrags),
+ [] == Frags orelse error(Frags),
+ case lists:member(N, FromFrags2) of
+ true ->
+ FH2 = FH#frag_state{n_fragments = N - 1,
+ hash_state = HashState2},
+ {FH2, FromFrags2, UnionFrags};
false ->
- mnesia:abort({"del_frag: Last fragment number not included", N})
- end;
- BadFrags ->
+ mnesia:abort({"del_frag: Last fragment number not included", N})
+ end
+ catch error:BadFrags ->
mnesia:abort({"del_frag: Fragment numbers out of range",
BadFrags, {range, 1, N}})
end.
@@ -1141,8 +1147,8 @@ remove_node(Node, Cs) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason);
- Value -> Value
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
+ Value -> Value
end.
set_frag_hash(Tab, Props) ->
diff --git a/lib/mnesia/src/mnesia_frag_hash.erl b/lib/mnesia/src/mnesia_frag_hash.erl
index 3dfdb87f30..2e4ebb98b0 100644
--- a/lib/mnesia/src/mnesia_frag_hash.erl
+++ b/lib/mnesia/src/mnesia_frag_hash.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_frag_old_hash.erl b/lib/mnesia/src/mnesia_frag_old_hash.erl
index 817bb54eb1..707be6d121 100644
--- a/lib/mnesia/src/mnesia_frag_old_hash.erl
+++ b/lib/mnesia/src/mnesia_frag_old_hash.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl
index 87cb58dae1..0c882c0df6 100644
--- a/lib/mnesia/src/mnesia_index.erl
+++ b/lib/mnesia/src/mnesia_index.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -45,21 +46,11 @@
del_transient/3,
del_index_table/3]).
--import(mnesia_lib, [verbose/2]).
+-import(mnesia_lib, [val/1, verbose/2]).
-include("mnesia.hrl").
-record(index, {setorbag, pos_list}).
-val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _ReASoN_} ->
- case mnesia_lib:other_val(Var) of
- error -> mnesia_lib:pr_other(Var, _ReASoN_);
- Val -> Val
- end;
- _VaLuE_ -> _VaLuE_
- end.
-
%% read an object list throuh its index table
%% we assume that table Tab has index on attribute number Pos
@@ -79,17 +70,24 @@ add_index(Index, Tab, Key, Obj, Old) ->
add_index2([{Pos, Ixt} |Tail], bag, Tab, K, Obj, OldRecs) ->
db_put(Ixt, {element(Pos, Obj), K}),
add_index2(Tail, bag, Tab, K, Obj, OldRecs);
-add_index2([{Pos, Ixt} |Tail], Type, Tab, K, Obj, OldRecs) ->
+add_index2([{Pos, Ixt} |Tail], Type, Tab, K, Obj, OldRecs0) ->
%% Remove old tuples in index if Tab is updated
- case OldRecs of
- undefined ->
- Old = mnesia_lib:db_get(Tab, K),
- del_ixes(Ixt, Old, Pos, K);
- Old ->
- del_ixes(Ixt, Old, Pos, K)
- end,
- db_put(Ixt, {element(Pos, Obj), K}),
- add_index2(Tail, Type, Tab, K, Obj, OldRecs);
+ OldRecs1 = case OldRecs0 of
+ undefined -> mnesia_lib:db_get(Tab, K);
+ _ -> OldRecs0
+ end,
+ IdxVal = element(Pos, Obj),
+ case [Old || Old <- OldRecs1, element(Pos, Old) =/= IdxVal] of
+ [] when OldRecs1 =:= [] -> %% Write
+ db_put(Ixt, {element(Pos, Obj), K}),
+ add_index2(Tail, Type, Tab, K, Obj, OldRecs0);
+ [] -> %% when OldRecs1 =/= [] Update without modifying index field
+ add_index2(Tail, Type, Tab, K, Obj, OldRecs0);
+ OldRecs -> %% Update
+ db_put(Ixt, {element(Pos, Obj), K}),
+ del_ixes(Ixt, OldRecs, Pos, K),
+ add_index2(Tail, Type, Tab, K, Obj, OldRecs0)
+ end;
add_index2([], _, _Tab, _K, _Obj, _) -> ok.
delete_index(Index, Tab, K) ->
diff --git a/lib/mnesia/src/mnesia_kernel_sup.erl b/lib/mnesia/src/mnesia_kernel_sup.erl
index 08f6129fc0..1583e5e1f7 100644
--- a/lib/mnesia/src/mnesia_kernel_sup.erl
+++ b/lib/mnesia/src/mnesia_kernel_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_late_loader.erl b/lib/mnesia/src/mnesia_late_loader.erl
index d09de3ca66..bd21bdc347 100644
--- a/lib/mnesia/src/mnesia_late_loader.erl
+++ b/lib/mnesia/src/mnesia_late_loader.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -36,17 +37,19 @@
-define(SERVER_NAME, ?MODULE).
+-include("mnesia.hrl").
+
-record(state, {supervisor}).
async_late_disc_load(_, [], _) -> ok;
async_late_disc_load(Node, Tabs, Reason) ->
Msg = {async_late_disc_load, Tabs, Reason},
- catch ({?SERVER_NAME, Node} ! {self(), Msg}).
+ ?SAFE({?SERVER_NAME, Node} ! {self(), Msg}).
maybe_async_late_disc_load(_, [], _) -> ok;
maybe_async_late_disc_load(Node, Tabs, Reason) ->
Msg = {maybe_async_late_disc_load, Tabs, Reason},
- catch ({?SERVER_NAME, Node} ! {self(), Msg}).
+ ?SAFE({?SERVER_NAME, Node} ! {self(), Msg}).
start() ->
mnesia_monitor:start_proc(?SERVER_NAME, ?MODULE, init, [self()]).
diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl
index a32c69c59e..0f1354f43e 100644
--- a/lib/mnesia/src/mnesia_lib.erl
+++ b/lib/mnesia/src/mnesia_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -114,9 +115,7 @@
lock_table/1,
mkcore/1,
not_active_here/1,
- other_val/2,
other_val/1,
- pr_other/2,
overload_read/0,
overload_read/1,
overload_set/2,
@@ -380,8 +379,8 @@ search_key(_Key, []) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', _ReASoN_} -> mnesia_lib:other_val(Var, _ReASoN_);
- _VaLuE_ -> _VaLuE_
+ {'EXIT', _} -> other_val(Var);
+ _VaLuE_ -> _VaLuE_
end.
set(Var, Val) ->
@@ -390,13 +389,13 @@ set(Var, Val) ->
unset(Var) ->
?ets_delete(mnesia_gvar, Var).
-other_val(Var, Other) ->
- case other_val(Var) of
- error -> pr_other(Var, Other);
+other_val(Var) ->
+ case other_val_1(Var) of
+ error -> pr_other(Var);
Val -> Val
end.
-other_val(Var) ->
+other_val_1(Var) ->
case Var of
{_, where_to_read} -> nowhere;
{_, where_to_write} -> [];
@@ -404,21 +403,17 @@ other_val(Var) ->
_ -> error
end.
-pr_other(Var, Other) ->
- Why =
+-spec pr_other(_) -> no_return().
+pr_other(Var) ->
+ Why =
case is_running() of
no -> {node_not_running, node()};
_ -> {no_exists, Var}
end,
- verbose("~p (~p) val(mnesia_gvar, ~w) -> ~p ~p ~n",
+ verbose("~p (~p) val(mnesia_gvar, ~w) -> ~p ~n",
[self(), process_info(self(), registered_name),
- Var, Other, Why]),
- case Other of
- {badarg, [{ets, lookup_element, _, _}|_]} ->
- exit(Why);
- _ ->
- erlang:error(Why)
- end.
+ Var, Why]),
+ mnesia:abort(Why).
%% Some functions for list valued variables
add(Var, Val) ->
@@ -905,7 +900,7 @@ dirty_rpc_error_tag(Reason) ->
end.
fatal(Format, Args) ->
- catch set(mnesia_status, stopping),
+ ?SAFE(catch set(mnesia_status, stopping)),
Core = mkcore({crashinfo, {Format, Args}}),
report_fatal(Format, Args, Core),
timer:sleep(10000), % Enough to write the core dump to disc?
@@ -917,7 +912,7 @@ report_fatal(Format, Args) ->
report_fatal(Format, Args, Core) ->
report_system_event({mnesia_fatal, Format, Args, Core}),
- catch exit(whereis(mnesia_monitor), fatal).
+ ?SAFE(exit(whereis(mnesia_monitor), fatal)).
%% We sleep longer and longer the more we try
%% Made some testing and came up with the following constants
@@ -930,8 +925,9 @@ random_time(Retries, _Counter0) ->
case get(random_seed) of
undefined ->
- {X, Y, Z} = erlang:now(), %% time()
- _ = random:seed(X, Y, Z),
+ _ = random:seed(erlang:unique_integer(),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
Time = Dup + random:uniform(MaxIntv),
%% dbg_out("---random_test rs ~w max ~w val ~w---~n", [Retries, MaxIntv, Time]),
Time;
@@ -1013,7 +1009,7 @@ dbg_out(Format, Args) ->
%% Keep the last 10 debug print outs
save(DbgInfo) ->
- catch save2(DbgInfo).
+ ?SAFE(save2(DbgInfo)).
save2(DbgInfo) ->
Key = {'$$$_report', current_pos},
@@ -1089,35 +1085,29 @@ db_match_object(Tab, Pat) ->
db_match_object(val({Tab, storage_type}), Tab, Pat).
db_match_object(Storage, Tab, Pat) ->
db_fixtable(Storage, Tab, true),
- Res = catch_match_object(Storage, Tab, Pat),
- db_fixtable(Storage, Tab, false),
- case Res of
- {'EXIT', Reason} -> exit(Reason);
- _ -> Res
+ try
+ case Storage of
+ disc_only_copies -> dets:match_object(Tab, Pat);
+ _ -> ets:match_object(Tab, Pat)
+ end
+ after
+ db_fixtable(Storage, Tab, false)
end.
-catch_match_object(disc_only_copies, Tab, Pat) ->
- catch dets:match_object(Tab, Pat);
-catch_match_object(_, Tab, Pat) ->
- catch ets:match_object(Tab, Pat).
-
db_select(Tab, Pat) ->
db_select(val({Tab, storage_type}), Tab, Pat).
db_select(Storage, Tab, Pat) ->
db_fixtable(Storage, Tab, true),
- Res = catch_select(Storage, Tab, Pat),
- db_fixtable(Storage, Tab, false),
- case Res of
- {'EXIT', Reason} -> exit(Reason);
- _ -> Res
+ try
+ case Storage of
+ disc_only_copies -> dets:select(Tab, Pat);
+ _ -> ets:select(Tab, Pat)
+ end
+ after
+ db_fixtable(Storage, Tab, false)
end.
-catch_select(disc_only_copies, Tab, Pat) ->
- catch dets:select(Tab, Pat);
-catch_select(_, Tab, Pat) ->
- catch ets:select(Tab, Pat).
-
db_select_init(disc_only_copies, Tab, Pat, Limit) ->
dets:select(Tab, Pat, Limit);
db_select_init(_, Tab, Pat, Limit) ->
@@ -1261,7 +1251,7 @@ dets_sync_open(Tab, Args) ->
end.
dets_sync_close(Tab) ->
- catch dets:close(Tab),
+ ?SAFE(dets:close(Tab)),
unlock_table(Tab),
ok.
@@ -1297,7 +1287,7 @@ readable_indecies(Tab) ->
scratch_debug_fun() ->
dbg_out("scratch_debug_fun(): ~p~n", [?DEBUG_TAB]),
- (catch ?ets_delete_table(?DEBUG_TAB)),
+ ?SAFE(?ets_delete_table(?DEBUG_TAB)),
?ets_new_table(?DEBUG_TAB, [set, public, named_table, {keypos, 2}]).
activate_debug_fun(FunId, Fun, InitialContext, File, Line) ->
@@ -1310,43 +1300,45 @@ activate_debug_fun(FunId, Fun, InitialContext, File, Line) ->
update_debug_info(Info).
update_debug_info(Info) ->
- case catch ?ets_insert(?DEBUG_TAB, Info) of
- {'EXIT', _} ->
+ try ?ets_insert(?DEBUG_TAB, Info),
+ ok
+ catch error:_ ->
scratch_debug_fun(),
- ?ets_insert(?DEBUG_TAB, Info);
- _ ->
- ok
+ ?ets_insert(?DEBUG_TAB, Info)
end,
dbg_out("update_debug_info(~p)~n", [Info]),
ok.
deactivate_debug_fun(FunId, _File, _Line) ->
- catch ?ets_delete(?DEBUG_TAB, FunId),
+ ?SAFE(?ets_delete(?DEBUG_TAB, FunId)),
ok.
eval_debug_fun(FunId, EvalContext, EvalFile, EvalLine) ->
- case catch ?ets_lookup(?DEBUG_TAB, FunId) of
- [] ->
- ok;
- [Info] ->
- OldContext = Info#debug_info.context,
- dbg_out("~s(~p): ~w "
- "activated in ~s(~p)~n "
- "eval_debug_fun(~w, ~w)~n",
- [filename:basename(EvalFile), EvalLine, Info#debug_info.id,
- filename:basename(Info#debug_info.file), Info#debug_info.line,
- OldContext, EvalContext]),
- Fun = Info#debug_info.function,
- NewContext = Fun(OldContext, EvalContext),
-
- case catch ?ets_lookup(?DEBUG_TAB, FunId) of
- [Info] when NewContext /= OldContext ->
- NewInfo = Info#debug_info{context = NewContext},
- update_debug_info(NewInfo);
- _ ->
- ok
- end;
- {'EXIT', _} -> ok
+ try
+ case ?ets_lookup(?DEBUG_TAB, FunId) of
+ [] ->
+ ok;
+ [Info] ->
+ OldContext = Info#debug_info.context,
+ dbg_out("~s(~p): ~w "
+ "activated in ~s(~p)~n "
+ "eval_debug_fun(~w, ~w)~n",
+ [filename:basename(EvalFile), EvalLine, Info#debug_info.id,
+ filename:basename(Info#debug_info.file), Info#debug_info.line,
+ OldContext, EvalContext]),
+ Fun = Info#debug_info.function,
+ NewContext = Fun(OldContext, EvalContext),
+
+ case ?ets_lookup(?DEBUG_TAB, FunId) of
+ [Info] when NewContext /= OldContext ->
+ NewInfo = Info#debug_info{context = NewContext},
+ update_debug_info(NewInfo);
+ _ ->
+ ok
+ end
+ end
+ catch error ->
+ ok
end.
-ifdef(debug).
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 530317bcdd..41fcd76fcb 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -35,7 +36,7 @@
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
Value -> Value
end.
@@ -69,9 +70,10 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_copies ->
ignore;
_ ->
mnesia_monitor:mktab(Tab, Args),
- Count = mnesia_log:dcd2ets(Tab, Repair),
- case ets:info(Tab, size) of
- X when X < Count * 4 ->
+ _Count = mnesia_log:dcd2ets(Tab, Repair),
+ case mnesia_monitor:get_env(dump_disc_copies_at_startup)
+ andalso mnesia_dumper:needs_dump_ets(Tab) of
+ true ->
ok = mnesia_log:ets2dcd(Tab);
_ ->
ignore
@@ -178,8 +180,7 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_only_copies -
-define(MAX_RAM_TRANSFERS, (?MAX_RAM_FILE_SIZE div ?MAX_TRANSFER_SIZE) + 1).
-define(MAX_NOPACKETS, 20).
-net_load_table(Tab, Reason, Ns, Cs)
- when Reason == {dumper,add_table_copy} ->
+net_load_table(Tab, {dumper,{add_table_copy, _}}=Reason, Ns, Cs) ->
try_net_load_table(Tab, Reason, Ns, Cs);
net_load_table(Tab, Reason, Ns, _Cs) ->
try_net_load_table(Tab, Reason, Ns, val({Tab, cstruct})).
@@ -208,8 +209,7 @@ do_get_network_copy(Tab, Reason, Ns, Storage, Cs) ->
set({Tab, load_node}, Node),
set({Tab, load_reason}, Reason),
mnesia_controller:i_have_tab(Tab),
- dbg_out("Table ~p copied from ~p to ~p (~b entries)~n",
- [Tab, Node, node(), mnesia:table_info(Tab, size)]),
+ dbg_out("Table ~p copied from ~p to ~p~n", [Tab, Node, node()]),
{loaded, ok};
Err = {error, _} when element(1, Reason) == dumper ->
{not_loaded,Err};
@@ -232,7 +232,8 @@ do_snmpify(Tab, Us, Storage) ->
set({Tab, {index, snmp}}, Snmp).
%% Start the recieiver
-init_receiver(Node, Tab, Storage, Cs, Reas={dumper,add_table_copy}) ->
+init_receiver(Node, Tab, Storage, Cs, Reas={dumper,{add_table_copy, Tid}}) ->
+ rpc:call(Node, mnesia_lib, set, [{?MODULE, active_trans}, Tid]),
case start_remote_sender(Node, Tab, Storage) of
{SenderPid, TabSize, DetsData} ->
start_receiver(Tab,Storage,Cs,SenderPid,TabSize,DetsData,Reas);
@@ -306,7 +307,7 @@ table_init_fun(SenderPid) ->
end.
%% Add_table_copy get's it's own locks.
-start_receiver(Tab,Storage,Cs,SenderPid,TabSize,DetsData,{dumper,add_table_copy}) ->
+start_receiver(Tab,Storage,Cs,SenderPid,TabSize,DetsData,{dumper,{add_table_copy,_}}) ->
Init = table_init_fun(SenderPid),
case do_init_table(Tab,Storage,Cs,SenderPid,TabSize,DetsData,self(), Init) of
Err = {error, _} ->
@@ -331,7 +332,7 @@ wait_on_load_complete(Pid) ->
{Pid, Res} ->
Res;
{'EXIT', Pid, Reason} ->
- exit(Reason);
+ error(Reason);
Else ->
Pid ! Else,
wait_on_load_complete(Pid)
@@ -441,18 +442,18 @@ init_table(Tab, disc_only_copies, Fun, DetsInfo,Sender) ->
ErtsVer = erlang:system_info(version),
case DetsInfo of
{ErtsVer, DetsData} ->
- Res = (catch dets:is_compatible_bchunk_format(Tab, DetsData)),
- case Res of
- {'EXIT',{undef,[{dets,_,_,_}|_]}} ->
- Sender ! {self(), {old_protocol, Tab}},
- dets:init_table(Tab, Fun); %% Old dets version
- {'EXIT', What} ->
- exit(What);
+ try dets:is_compatible_bchunk_format(Tab, DetsData) of
false ->
Sender ! {self(), {old_protocol, Tab}},
dets:init_table(Tab, Fun); %% Old dets version
true ->
dets:init_table(Tab, Fun, [{format, bchunk}])
+ catch
+ error:{undef,[{dets,_,_,_}|_]} ->
+ Sender ! {self(), {old_protocol, Tab}},
+ dets:init_table(Tab, Fun); %% Old dets version
+ error:What ->
+ What
end;
Old when Old /= false ->
Sender ! {self(), {old_protocol, Tab}},
@@ -461,10 +462,10 @@ init_table(Tab, disc_only_copies, Fun, DetsInfo,Sender) ->
dets:init_table(Tab, Fun)
end;
init_table(Tab, _, Fun, _DetsInfo,_) ->
- case catch ets:init_table(Tab, Fun) of
- true ->
- ok;
- {'EXIT', Else} -> Else
+ try
+ true = ets:init_table(Tab, Fun),
+ ok
+ catch _:Else -> {Else, erlang:get_stacktrace()}
end.
@@ -571,9 +572,9 @@ handle_last({ram_copies, Tab}, _Type, DatBin) ->
down(Tab, Storage) ->
case Storage of
ram_copies ->
- catch ?ets_delete_table(Tab);
+ ?SAFE(?ets_delete_table(Tab));
disc_copies ->
- catch ?ets_delete_table(Tab);
+ ?SAFE(?ets_delete_table(Tab));
disc_only_copies ->
TmpFile = mnesia_lib:tab2tmp(Tab),
mnesia_lib:dets_sync_close(Tab),
@@ -657,43 +658,51 @@ send_table(Pid, Tab, RemoteS) ->
{Init, Chunk} = reader_funcs(UseDetsChunk, Tab, Storage, KeysPerTransfer),
SendIt = fun() ->
- prepare_copy(Pid, Tab, Storage),
+ NeedLock = need_lock(Tab),
+ {atomic, ok} = prepare_copy(Pid, Tab, Storage, NeedLock),
send_more(Pid, 1, Chunk, Init(), Tab),
- finish_copy(Pid, Tab, Storage, RemoteS)
+ finish_copy(Pid, Tab, Storage, RemoteS, NeedLock)
end,
- case catch SendIt() of
- receiver_died ->
+ try SendIt() of
+ {_, receiver_died} -> ok;
+ {atomic, no_more} -> ok
+ catch
+ throw:receiver_died ->
cleanup_tab_copier(Pid, Storage, Tab),
- unlink(whereis(mnesia_tm)),
- ok;
- {_, receiver_died} ->
- unlink(whereis(mnesia_tm)),
ok;
- {atomic, no_more} ->
- unlink(whereis(mnesia_tm)),
- ok;
- Reason ->
+ error:Reason -> %% Prepare failed
cleanup_tab_copier(Pid, Storage, Tab),
- unlink(whereis(mnesia_tm)),
- {error, Reason}
+ {error, {tab_copier, Tab, {Reason, erlang:get_stacktrace()}}}
+ after
+ unlink(whereis(mnesia_tm))
end
end.
-prepare_copy(Pid, Tab, Storage) ->
+prepare_copy(Pid, Tab, Storage, NeedLock) ->
Trans =
fun() ->
- mnesia:lock_table(Tab, load),
+ NeedLock andalso mnesia:lock_table(Tab, load),
mnesia_subscr:subscribe(Pid, {table, Tab}),
update_where_to_write(Tab, node(Pid)),
mnesia_lib:db_fixtable(Storage, Tab, true),
ok
end,
- case mnesia:transaction(Trans) of
- {atomic, ok} ->
- ok;
- {aborted, Reason} ->
- exit({tab_copier_prepare, Tab, Reason})
+ mnesia:transaction(Trans).
+
+
+need_lock(Tab) ->
+ case ?catch_val({?MODULE, active_trans}) of
+ #tid{} = Tid ->
+ %% move_table_copy grabs it's own table-lock
+ %% do not deadlock with it
+ mnesia_lib:unset({?MODULE, active_trans}),
+ case mnesia_locker:get_held_locks(Tab) of
+ [{write, Tid}|_] -> false;
+ _Locks -> true
+ end;
+ _ ->
+ true
end.
update_where_to_write(Tab, Node) ->
@@ -790,12 +799,12 @@ send_packet(N, Pid, Chunk, {Recs, Cont}) when N < ?MAX_NOPACKETS ->
send_packet(_N, _Pid, _Chunk, DataState) ->
DataState.
-finish_copy(Pid, Tab, Storage, RemoteS) ->
+finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
RecNode = node(Pid),
DatBin = dat2bin(Tab, Storage, RemoteS),
Trans =
fun() ->
- mnesia:read_lock_table(Tab),
+ NeedLock andalso mnesia:read_lock_table(Tab),
A = val({Tab, access_mode}),
mnesia_controller:sync_and_block_table_whereabouts(Tab, RecNode, RemoteS, A),
cleanup_tab_copier(Pid, Storage, Tab),
@@ -827,6 +836,6 @@ dat2bin(_Tab, _LocalS, _RemoteS) ->
nobin.
handle_exit(Pid, Reason) when node(Pid) == node() ->
- exit(Reason);
+ error(Reason);
handle_exit(_Pid, _Reason) -> %% Not from our node, this will be handled by
ignore. %% mnesia_down soon.
diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl
index 1efb939e00..5766f22e92 100644
--- a/lib/mnesia/src/mnesia_locker.erl
+++ b/lib/mnesia/src/mnesia_locker.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,7 +22,7 @@
-module(mnesia_locker).
-export([
- get_held_locks/0,
+ get_held_locks/0, get_held_locks/1,
get_lock_queue/0,
global_lock/5,
ixrlock/5,
@@ -98,7 +99,7 @@ init(Parent) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', _ReASoN_} -> mnesia_lib:other_val(Var, _ReASoN_);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
_VaLuE_ -> _VaLuE_
end.
@@ -235,6 +236,11 @@ loop(State) ->
From ! {Ref, ok},
loop(State);
+ {From, {is_locked, Oid}} ->
+ Held = ?ets_lookup(mnesia_held_locks, Oid),
+ reply(From, Held),
+ loop(State);
+
{'EXIT', Pid, _} when Pid == State#state.supervisor ->
do_stop();
@@ -1001,13 +1007,11 @@ flush_remaining(Ns=[Node | Tail], SkipNode, Res) ->
opt_lookup_in_client(lookup_in_client, Oid, Lock) ->
{Tab, Key} = Oid,
- case catch mnesia_lib:db_get(Tab, Key) of
- {'EXIT', _} ->
+ try mnesia_lib:db_get(Tab, Key)
+ catch error:_ ->
%% Table has been deleted from this node,
%% restart the transaction.
- #cyclic{op = read, lock = Lock, oid = Oid, lucky = nowhere};
- Val ->
- Val
+ #cyclic{op = read, lock = Lock, oid = Oid, lucky = nowhere}
end;
opt_lookup_in_client(Val, _Oid, _Lock) ->
Val.
@@ -1139,11 +1143,10 @@ send_requests([], _X) ->
rec_requests([Node | Nodes], Oid, Store) ->
Res = l_req_rec(Node, Store),
- case catch rlock_get_reply(Node, Store, Oid, Res) of
- {'EXIT', Reason} ->
- flush_remaining(Nodes, Node, Reason);
- _ ->
- rec_requests(Nodes, Oid, Store)
+ try rlock_get_reply(Node, Store, Oid, Res) of
+ _ -> rec_requests(Nodes, Oid, Store)
+ catch _:Reason ->
+ flush_remaining(Nodes, Node, Reason)
end;
rec_requests([], _Oid, _Store) ->
ok.
@@ -1153,6 +1156,19 @@ get_held_locks() ->
Locks = receive {mnesia_held_locks, Ls} -> Ls after 5000 -> [] end,
rewrite_locks(Locks, []).
+%% Mnesia internal usage only
+get_held_locks(Tab) when is_atom(Tab) ->
+ Oid = {Tab, ?ALL},
+ ?MODULE ! {self(), {is_locked, Oid}},
+ receive
+ {?MODULE, _Node, Locks} ->
+ case Locks of
+ [] -> [];
+ [{Oid, _Prev, What}] -> What
+ end
+ end.
+
+
rewrite_locks([{Oid, _, Ls}|Locks], Acc0) ->
Acc = rewrite_locks(Ls, Oid, Acc0),
rewrite_locks(Locks, Acc);
diff --git a/lib/mnesia/src/mnesia_log.erl b/lib/mnesia/src/mnesia_log.erl
index d2fd04a60b..36135418c8 100644
--- a/lib/mnesia/src/mnesia_log.erl
+++ b/lib/mnesia/src/mnesia_log.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -200,7 +201,7 @@ log_header(Kind, Version) ->
log_kind=Kind,
mnesia_version=mnesia:system_info(version),
node=node(),
- now=now()}.
+ now=erlang:timestamp()}.
version() -> "4.3".
@@ -349,6 +350,8 @@ open_log(Name, Header, Fname, Exists, Repair, Mode) ->
mnesia_lib:important("Data may be missing, log ~p repaired: Lost ~p bytes~n",
[Fname, BadBytes]),
Log;
+ {error, Reason = {file_error, _Fname, emfile}} ->
+ fatal("Cannot open log file ~p: ~p~n", [Fname, Reason]);
{error, Reason} when Repair == true ->
file:delete(Fname),
mnesia_lib:important("Data may be missing, Corrupt logfile deleted: ~p, ~p ~n",
@@ -462,7 +465,7 @@ chunk_log(Cont) ->
chunk_log(_Log, eof) ->
eof;
chunk_log(Log, Cont) ->
- case catch disk_log:chunk(Log, Cont) of
+ case disk_log:chunk(Log, Cont) of
{error, Reason} ->
fatal("Possibly truncated ~p file: ~p~n",
[Log, Reason]);
@@ -647,11 +650,11 @@ backup_checkpoint(Name, Opaque, Args) when is_list(Args) ->
end.
check_backup_args([Arg | Tail], B) ->
- case catch check_backup_arg_type(Arg, B) of
- {'EXIT', _Reason} ->
- {error, {badarg, Arg}};
+ try check_backup_arg_type(Arg, B) of
B2 ->
check_backup_args(Tail, B2)
+ catch error:_ ->
+ {error, {badarg, Arg}}
end;
check_backup_args([], B) ->
@@ -674,11 +677,11 @@ check_backup_arg_type(Arg, B) ->
backup_master(ClientPid, B) ->
process_flag(trap_exit, true),
- case catch do_backup_master(B) of
- {'EXIT', Reason} ->
- ClientPid ! {self(), ClientPid, {error, {'EXIT', Reason}}};
+ try do_backup_master(B) of
Res ->
ClientPid ! {self(), ClientPid, Res}
+ catch _:Reason ->
+ ClientPid ! {self(), ClientPid, {error, {'EXIT', Reason}}}
end,
unlink(ClientPid),
exit(normal).
@@ -731,27 +734,30 @@ backup_schema(B, Tabs) ->
safe_apply(B, write, [_, Items]) when Items == [] ->
B;
safe_apply(B, What, Args) ->
- Abort = fun(R) -> abort_write(B, What, Args, R) end,
+ Abort = abort_write_fun(B, What, Args),
receive
{'EXIT', Pid, R} -> Abort({'EXIT', Pid, R})
after 0 ->
Mod = B#backup_args.module,
- case catch apply(Mod, What, Args) of
+ try apply(Mod, What, Args) of
{ok, Opaque} -> B#backup_args{opaque=Opaque};
- {error, R} -> Abort(R);
- R -> Abort(R)
+ {error, R} -> Abort(R)
+ catch _:R -> Abort(R)
end
end.
+-spec abort_write_fun(_, _, _) -> fun((_) -> no_return()).
+abort_write_fun(B, What, Args) ->
+ fun(R) -> abort_write(B, What, Args, R) end.
+
abort_write(B, What, Args, Reason) ->
Mod = B#backup_args.module,
Opaque = B#backup_args.opaque,
dbg_out("Failed to perform backup. M=~p:F=~p:A=~p -> ~p~n",
[Mod, What, Args, Reason]),
- case catch apply(Mod, abort_write, [Opaque]) of
- {ok, _Res} ->
- throw({error, Reason});
- Other ->
+ try apply(Mod, abort_write, [Opaque]) of
+ {ok, _Res} -> throw({error, Reason})
+ catch _:Other ->
error("Failed to abort backup. ~p:~p~p -> ~p~n",
[Mod, abort_write, [Opaque], Other]),
throw({error, Reason})
@@ -892,10 +898,8 @@ tab_receiver(Pid, B, Tab, RecName, Slot) ->
end.
rec_filter(B, schema, _RecName, Recs) ->
- case catch mnesia_bup:refresh_cookie(Recs, B#backup_args.cookie) of
- Recs2 when is_list(Recs2) ->
- Recs2;
- {error, _Reason} ->
+ try mnesia_bup:refresh_cookie(Recs, B#backup_args.cookie)
+ catch throw:{error, _Reason} ->
%% No schema table cookie
Recs
end;
@@ -1006,13 +1010,14 @@ add_recs([{{Tab, _Key}, Val, delete_object} | Rest], N) ->
add_recs(Rest, N+1);
add_recs([{{Tab, Key}, Val, update_counter} | Rest], N) ->
{RecName, Incr} = Val,
- case catch ets:update_counter(Tab, Key, Incr) of
- CounterVal when is_integer(CounterVal) ->
- ok;
- _ when Incr < 0 ->
+ try
+ CounterVal = ets:update_counter(Tab, Key, Incr),
+ true = (CounterVal >= 0)
+ catch
+ error:_ when Incr < 0 ->
Zero = {RecName, Key, 0},
true = ets:insert(Tab, Zero);
- _ ->
+ error:_ ->
Zero = {RecName, Key, Incr},
true = ets:insert(Tab, Zero)
end,
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index 6fc1a394a6..081d746257 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -81,9 +82,9 @@
going_down = [], tm_started = false, early_connects = [],
connecting, mq = [], remote_node_status = []}).
--define(current_protocol_version, {8,1}).
+-define(current_protocol_version, {8,2}).
--define(previous_protocol_version, {8,0}).
+-define(previous_protocol_version, {8,1}).
start() ->
gen_server:start_link({local, ?MODULE}, ?MODULE,
@@ -192,7 +193,7 @@ protocol_version() ->
%% A sorted list of acceptable protocols the
%% preferred protocols are first in the list
acceptable_protocol_versions() ->
- [protocol_version(), ?previous_protocol_version, {7,6}].
+ [protocol_version(), ?previous_protocol_version].
needs_protocol_conversion(Node) ->
case {?catch_val({protocol, Node}), protocol_version()} of
@@ -268,7 +269,7 @@ init([Parent]) ->
set(version, Version),
dbg_out("Version: ~p~n", [Version]),
- case catch process_config_args(env()) of
+ try process_config_args(env()) of
ok ->
mnesia_lib:set({'$$$_report', current_pos}, 0),
Level = mnesia_lib:val(debug),
@@ -288,8 +289,8 @@ init([Parent]) ->
set(pending_checkpoints, []),
set(pending_checkpoint_pids, []),
- {ok, #state{supervisor = Parent}};
- {'EXIT', Reason} ->
+ {ok, #state{supervisor = Parent}}
+ catch _:Reason ->
mnesia_lib:report_fatal("Bad configuration: ~p~n", [Reason]),
{stop, {bad_config, Reason}}
end.
@@ -323,25 +324,24 @@ non_empty_dir() ->
%%----------------------------------------------------------------------
handle_call({mktab, Tab, Args}, _From, State) ->
- case catch ?ets_new_table(Tab, Args) of
- {'EXIT', ExitReason} ->
+ try ?ets_new_table(Tab, Args) of
+ Reply ->
+ {reply, Reply, State}
+ catch error:ExitReason ->
Msg = "Cannot create ets table",
Reason = {system_limit, Msg, Tab, Args, ExitReason},
fatal("~p~n", [Reason]),
- {noreply, State};
- Reply ->
- {reply, Reply, State}
+ {noreply, State}
end;
handle_call({unsafe_mktab, Tab, Args}, _From, State) ->
- case catch ?ets_new_table(Tab, Args) of
- {'EXIT', ExitReason} ->
- {reply, {error, ExitReason}, State};
+ try ?ets_new_table(Tab, Args) of
Reply ->
{reply, Reply, State}
+ catch error:ExitReason ->
+ {reply, {error, ExitReason}, State}
end;
-
handle_call({open_dets, Tab, Args}, _From, State) ->
case mnesia_lib:dets_sync_open(Tab, Args) of
{ok, Tab} ->
@@ -424,8 +424,6 @@ handle_call({negotiate_protocol, Mon, Version, Protocols}, From, State)
case hd(Protocols) of
?previous_protocol_version ->
accept_protocol(Mon, MyVersion, ?previous_protocol_version, From, State);
- {7,6} ->
- accept_protocol(Mon, MyVersion, {7,6}, From, State);
_ ->
verbose("Connection with ~p rejected. "
"version = ~p, protocols = ~p, "
@@ -546,7 +544,7 @@ handle_info({'EXIT', Pid, fatal}, State) when node(Pid) == node() ->
%% is in progress
%% exit(State#state.supervisor, shutdown),
%% It is better to kill an innocent process
- catch exit(whereis(mnesia_locker), kill),
+ ?SAFE(exit(whereis(mnesia_locker), kill)),
{noreply, State};
handle_info(Msg = {'EXIT',Pid,_}, State) ->
@@ -664,6 +662,7 @@ env() ->
backup_module,
debug,
dir,
+ dump_disc_copies_at_startup,
dump_log_load_regulation,
dump_log_time_threshold,
dump_log_update_in_place,
@@ -692,6 +691,8 @@ default_env(debug) ->
default_env(dir) ->
Name = lists:concat(["Mnesia.", node()]),
filename:absname(Name);
+default_env(dump_disc_copies_at_startup) ->
+ true;
default_env(dump_log_load_regulation) ->
false;
default_env(dump_log_time_threshold) ->
@@ -724,11 +725,8 @@ default_env(send_compressed) ->
0.
check_type(Env, Val) ->
- case catch do_check_type(Env, Val) of
- {'EXIT', _Reason} ->
- exit({bad_config, Env, Val});
- NewVal ->
- NewVal
+ try do_check_type(Env, Val)
+ catch error:_ -> exit({bad_config, Env, Val})
end.
do_check_type(access_module, A) when is_atom(A) -> A;
@@ -741,6 +739,7 @@ do_check_type(debug, trace) -> trace;
do_check_type(debug, true) -> debug;
do_check_type(debug, verbose) -> verbose;
do_check_type(dir, V) -> filename:absname(V);
+do_check_type(dump_disc_copies_at_startup, B) -> bool(B);
do_check_type(dump_log_load_regulation, B) -> bool(B);
do_check_type(dump_log_time_threshold, I) when is_integer(I), I > 0 -> I;
do_check_type(dump_log_update_in_place, B) -> bool(B);
@@ -777,12 +776,12 @@ media(opt_disc) -> opt_disc;
media(ram) -> ram.
patch_env(Env, Val) ->
- case catch do_check_type(Env, Val) of
- {'EXIT', _Reason} ->
- {error, {bad_type, Env, Val}};
+ try do_check_type(Env, Val) of
NewVal ->
application_controller:set_env(mnesia, Env, NewVal),
NewVal
+ catch error:_ ->
+ {error, {bad_type, Env, Val}}
end.
detect_partitioned_network(Mon, Node) ->
diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl
index eeb4fa0ced..9420e57afa 100644
--- a/lib/mnesia/src/mnesia_recover.erl
+++ b/lib/mnesia/src/mnesia_recover.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -178,11 +179,8 @@ log_decision(D) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} ->
- case mnesia_lib:other_val(Var) of
- error -> mnesia_lib:pr_other(Var, Reason);
- Val -> Val
- end;
+ {'EXIT', _Reason} ->
+ mnesia_lib:other_val(Var);
Value -> Value
end.
@@ -373,11 +371,8 @@ log_master_nodes2([], _UseDir, IsRunning, WorstRes) ->
get_master_node_info() ->
Tab = mnesia_decision,
Pat = {master_nodes, '_', '_'},
- case catch mnesia_lib:db_match_object(ram_copies,Tab, Pat) of
- {'EXIT', _} ->
- [];
- Masters ->
- Masters
+ try mnesia_lib:db_match_object(ram_copies,Tab, Pat)
+ catch error:_ -> []
end.
get_master_node_tables() ->
@@ -385,9 +380,8 @@ get_master_node_tables() ->
[Tab || {master_nodes, Tab, _Nodes} <- Masters].
get_master_nodes(Tab) ->
- case catch ?ets_lookup_element(mnesia_decision, Tab, 3) of
- {'EXIT', _} -> [];
- Nodes -> Nodes
+ try ?ets_lookup_element(mnesia_decision, Tab, 3)
+ catch error:_ -> []
end.
%% Determine what has happened to the transaction
@@ -485,8 +479,6 @@ load_decision_tab() ->
load_decision_tab(Cont, load_decision_tab),
mnesia_log:close_decision_tab().
-load_decision_tab(eof, _InitBy) ->
- ok;
load_decision_tab(Cont, InitBy) ->
case mnesia_log:chunk_decision_tab(Cont) of
{Cont2, Decisions} ->
@@ -519,8 +511,6 @@ dump_decision_log(InitBy) ->
Cont = mnesia_log:prepare_decision_log_dump(),
perform_dump_decision_log(Cont, InitBy).
-perform_dump_decision_log(eof, _InitBy) ->
- confirm_decision_log_dump();
perform_dump_decision_log(Cont, InitBy) when InitBy == startup ->
case mnesia_log:chunk_decision_log(Cont) of
{Cont2, Decisions} ->
@@ -1024,7 +1014,7 @@ decision(Tid) ->
decision(Tid, tabs()).
decision(Tid, [Tab | Tabs]) ->
- case catch ?ets_lookup(Tab, Tid) of
+ try ?ets_lookup(Tab, Tid) of
[D] when is_record(D, decision) ->
D;
[C] when is_record(C, transient_decision) ->
@@ -1034,8 +1024,8 @@ decision(Tid, [Tab | Tabs]) ->
ram_nodes = []
};
[] ->
- decision(Tid, Tabs);
- {'EXIT', _} ->
+ decision(Tid, Tabs)
+ catch error:_ ->
%% Recently switched transient decision table
decision(Tid, Tabs)
end;
@@ -1046,11 +1036,8 @@ outcome(Tid, Default) ->
outcome(Tid, Default, tabs()).
outcome(Tid, Default, [Tab | Tabs]) ->
- case catch ?ets_lookup_element(Tab, Tid, 3) of
- {'EXIT', _} ->
- outcome(Tid, Default, Tabs);
- Val ->
- Val
+ try ?ets_lookup_element(Tab, Tid, 3)
+ catch error:_ -> outcome(Tid, Default, Tabs)
end;
outcome(_Tid, Default, []) ->
Default.
diff --git a/lib/mnesia/src/mnesia_registry.erl b/lib/mnesia/src/mnesia_registry.erl
index 202689ae5e..abf0b745a1 100644
--- a/lib/mnesia/src/mnesia_registry.erl
+++ b/lib/mnesia/src/mnesia_registry.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index 6e43052fb0..782493fb4f 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -151,7 +152,7 @@ exit_on_error(GoodRes) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
Value -> Value
end.
@@ -262,7 +263,7 @@ incr_version(Cs) ->
[] -> {Major + 1, 0}; % All replicas are active
_ -> {Major, Minor + 1} % Some replicas are inactive
end,
- Cs#cstruct{version = {V, {node(), now()}}}.
+ Cs#cstruct{version = {V, {node(), erlang:timestamp()}}}.
%% Returns table name
insert_cstruct(Tid, Cs, KeepWhereabouts) ->
@@ -645,54 +646,18 @@ cs2list(Cs) when is_record(Cs, cstruct) ->
rec2list(Tags, Tags, 2, Cs);
cs2list(CreateList) when is_list(CreateList) ->
CreateList;
-%% 4.6
+
+%% since 4.6
cs2list(Cs) when element(1, Cs) == cstruct, tuple_size(Cs) == 19 ->
Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
load_order,access_mode,majority,index,snmp,local_content,
record_name,attributes,
user_properties,frag_properties,storage_properties,
cookie,version],
- rec2list(Tags, Tags, 2, Cs);
-%% 4.4.19
-cs2list(Cs) when element(1, Cs) == cstruct, tuple_size(Cs) == 18 ->
- Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
- load_order,access_mode,majority,index,snmp,local_content,
- record_name,attributes,user_properties,frag_properties,
- cookie,version],
- rec2list(Tags, Tags, 2, Cs);
-%% 4.4.18 and earlier
-cs2list(Cs) when element(1, Cs) == cstruct, tuple_size(Cs) == 17 ->
- Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
- load_order,access_mode,index,snmp,local_content,
- record_name,attributes,user_properties,frag_properties,
- cookie,version],
rec2list(Tags, Tags, 2, Cs).
cs2list(false, Cs) ->
- cs2list(Cs);
-cs2list(ver4_4_18, Cs) -> %% Or earlier
- Orig = record_info(fields, cstruct),
- Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
- load_order,access_mode,index,snmp,local_content,
- record_name,attributes,user_properties,frag_properties,
- cookie,version],
- rec2list(Tags, Orig, 2, Cs);
-cs2list(ver4_4_19, Cs) ->
- Orig = record_info(fields, cstruct),
- Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
- load_order,access_mode,majority,index,snmp,local_content,
- record_name,attributes,user_properties,frag_properties,
- cookie,version],
- rec2list(Tags, Orig, 2, Cs);
-cs2list(ver4_6, Cs) ->
- Orig = record_info(fields, cstruct),
- Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
- load_order,access_mode,majority,index,snmp,local_content,
- record_name,attributes,
- user_properties,frag_properties,storage_properties,
- cookie,version],
- rec2list(Tags, Orig, 2, Cs).
-
+ cs2list(Cs).
rec2list([Tag | Tags], [Tag | Orig], Pos, Rec) ->
Val = element(Pos, Rec),
@@ -702,19 +667,8 @@ rec2list([], _, _Pos, _Rec) ->
rec2list(Tags, [_|Orig], Pos, Rec) ->
rec2list(Tags, Orig, Pos+1, Rec).
-normalize_cs(Cstructs, Node) ->
- %% backward-compatibility hack; normalize before returning
- case need_old_cstructs([Node]) of
- false ->
- Cstructs;
- Version ->
- %% some other format
- [convert_cs(Version, Cs) || Cs <- Cstructs]
- end.
-
-convert_cs(Version, Cs) ->
- Fields = [Value || {_, Value} <- cs2list(Version, Cs)],
- list_to_tuple([cstruct|Fields]).
+normalize_cs(Cstructs, _Node) ->
+ Cstructs.
list2cs(List) when is_list(List) ->
Name = pick(unknown, name, List, must),
@@ -1141,6 +1095,7 @@ do_delete_table(Tab) ->
ensure_writable(schema),
insert_schema_ops(TidTs, make_delete_table(Tab, whole_table)).
+-dialyzer({no_improper_lists, make_delete_table/2}).
make_delete_table(Tab, Mode) ->
case existed_before(Tab) of
false ->
@@ -1296,6 +1251,7 @@ make_del_table_copy(Tab, Node) ->
_ ->
ensure_active(Cs),
verify_cstruct(Cs2),
+ get_tid_ts_and_lock(Tab, write),
[{op, del_table_copy, Storage, Node, vsn_cs2list(Cs2)}]
end.
@@ -1323,6 +1279,7 @@ remove_node_from_tabs([Tab|Rest], Node) ->
remove_node_from_tabs(Rest, Node)];
_Ns ->
verify_cstruct(Cs2),
+ get_tid_ts_and_lock(Tab, write),
[{op, del_table_copy, ram_copies, Node, vsn_cs2list(Cs2)}|
remove_node_from_tabs(Rest, Node)]
end
@@ -1354,6 +1311,11 @@ do_move_table(schema, _FromNode, _ToNode) ->
mnesia:abort({bad_type, schema});
do_move_table(Tab, FromNode, ToNode) when is_atom(FromNode), is_atom(ToNode) ->
TidTs = get_tid_ts_and_lock(schema, write),
+ AnyOld = lists:any(fun(Node) -> mnesia_monitor:needs_protocol_conversion(Node) end,
+ [ToNode|val({Tab, where_to_write})]),
+ if AnyOld -> ignore; %% Leads to deadlock on old nodes
+ true -> get_tid_ts_and_lock(Tab, write)
+ end,
insert_schema_ops(TidTs, make_move_table(Tab, FromNode, ToNode));
do_move_table(Tab, FromNode, ToNode) ->
mnesia:abort({badarg, Tab, FromNode, ToNode}).
@@ -1961,7 +1923,7 @@ prepare_op(Tid, {op, add_table_copy, Storage, Node, TabDef}, _WaitFor) ->
end,
%% Tables are created by mnesia_loader get_network code
insert_cstruct(Tid, Cs, true),
- case mnesia_controller:get_network_copy(Tab, Cs) of
+ case mnesia_controller:get_network_copy(Tid, Tab, Cs) of
{loaded, ok} ->
{true, optional};
{not_loaded, ErrReason} ->
@@ -1992,28 +1954,11 @@ prepare_op(Tid, {op, add_table_copy, Storage, Node, TabDef}, _WaitFor) ->
{true, optional}
end;
-prepare_op(Tid, {op, del_table_copy, _Storage, Node, TabDef}, _WaitFor) ->
+prepare_op(_Tid, {op, del_table_copy, _Storage, Node, TabDef}, _WaitFor) ->
Cs = list2cs(TabDef),
Tab = Cs#cstruct.name,
-
- if
- %% Schema table lock is always required to run a schema op.
- %% No need to look it.
- node(Tid#tid.pid) == node(), Tab /= schema ->
- Self = self(),
- Pid = spawn_link(fun() -> lock_del_table(Tab, Node, Cs, Self) end),
- put(mnesia_lock, Pid),
- receive
- {Pid, updated} ->
- {true, optional};
- {Pid, FailReason} ->
- mnesia:abort(FailReason);
- {'EXIT', Pid, Reason} ->
- mnesia:abort(Reason)
- end;
- true ->
- {true, optional}
- end;
+ set_where_to_read(Tab, Node, Cs),
+ {true, optional};
prepare_op(_Tid, {op, change_table_copy_type, N, FromS, ToS, TabDef}, _WaitFor)
when N == node() ->
@@ -2151,14 +2096,14 @@ prepare_op(_Tid, {op, transform, Fun, TabDef}, _WaitFor) ->
mnesia_lib:db_fixtable(Storage, Tab, true),
Key = mnesia_lib:db_first(Tab),
Op = {op, transform, Fun, TabDef},
- case catch transform_objs(Fun, Tab, RecName,
- Key, NewArity, Storage, Type, [Op]) of
- {'EXIT', Reason} ->
- mnesia_lib:db_fixtable(Storage, Tab, false),
- exit({"Bad transform function", Tab, Fun, node(), Reason});
+ try transform_objs(Fun, Tab, RecName, Key,
+ NewArity, Storage, Type, [Op]) of
Objs ->
mnesia_lib:db_fixtable(Storage, Tab, false),
{true, Objs, mandatory}
+ catch _:Reason ->
+ mnesia_lib:db_fixtable(Storage, Tab, false),
+ exit({"Bad transform function", Tab, Fun, node(), Reason})
end
end;
@@ -2227,46 +2172,6 @@ receive_sync(Nodes, Pids) ->
{abort, Else}
end.
-lock_del_table(Tab, NewNode, Cs0, Father) ->
- Ns = val({schema, active_replicas}),
- process_flag(trap_exit,true),
- Lock = fun() ->
- mnesia:write_lock_table(Tab),
- %% Sigh using cs record
- Set = fun(Node) ->
- [Cs] = normalize_cs([Cs0], Node),
- rpc:call(Node, ?MODULE, set_where_to_read, [Tab, NewNode, Cs])
- end,
- Res = [Set(Node) || Node <- Ns],
- Filter = fun(ok) ->
- false;
- ({badrpc, {'EXIT', {undef, _}}}) ->
- %% This will be the case we talks with elder nodes
- %% than 3.8.2, they will set where_to_read without
- %% getting a lock.
- false;
- (_) ->
- true
- end,
- case lists:filter(Filter, Res) of
- [] ->
- Father ! {self(), updated},
- %% When transaction is commited the process dies
- %% and the lock is released.
- receive _ -> ok end;
- Err ->
- Father ! {self(), {bad_commit, Err}}
- end,
- ok
- end,
- case mnesia:transaction(Lock) of
- {atomic, ok} -> ok;
- {aborted, R} -> Father ! {self(), R}
- end,
- unlink(Father),
- unlink(whereis(mnesia_tm)),
- exit(normal).
-
set_where_to_read(Tab, Node, Cs) ->
case mnesia_lib:val({Tab, where_to_read}) of
Node ->
@@ -2342,7 +2247,7 @@ undo_prepare_commit(Tid, Commit) ->
ignore;
Ops ->
%% Catch to allow failure mnesia_controller may not be started
- catch mnesia_controller:release_schema_commit_lock(),
+ ?SAFE(mnesia_controller:release_schema_commit_lock()),
undo_prepare_ops(Tid, Ops)
end,
Commit.
@@ -2417,13 +2322,19 @@ undo_prepare_op(Tid, {op, add_table_copy, Storage, Node, TabDef}) ->
insert_cstruct(Tid, Cs2, true) % Don't care about the version
end;
-undo_prepare_op(_Tid, {op, del_table_copy, _, Node, TabDef})
- when Node == node() ->
- WriteLocker = get(mnesia_lock),
- WriteLocker =/= undefined andalso (WriteLocker ! die),
+undo_prepare_op(_Tid, {op, del_table_copy, _, Node, TabDef}) ->
Cs = list2cs(TabDef),
Tab = Cs#cstruct.name,
- mnesia_lib:set({Tab, where_to_read}, Node);
+ if node() =:= Node ->
+ mnesia_lib:set({Tab, where_to_read}, Node);
+ true ->
+ case mnesia_lib:val({Tab, where_to_read}) of
+ nowhere ->
+ mnesia_lib:set_remote_where_to_read(Tab);
+ _ ->
+ ignore
+ end
+ end;
undo_prepare_op(_Tid, {op, change_table_copy_type, N, FromS, ToS, TabDef})
when N == node() ->
@@ -2489,14 +2400,14 @@ ram_delete_table(Tab, Storage) ->
%% delete possible index files and data .....
%% Got to catch this since if no info has been set in the
%% mnesia_gvar it will crash
- catch mnesia_index:del_transient(Tab, Storage),
+ ?CATCH(mnesia_index:del_transient(Tab, Storage)),
case ?catch_val({Tab, {index, snmp}}) of
{'EXIT', _} ->
ignore;
Etab ->
- catch mnesia_snmp_hook:delete_table(Tab, Etab)
+ ?SAFE(mnesia_snmp_hook:delete_table(Tab, Etab))
end,
- catch ?ets_delete_table(Tab)
+ ?SAFE(?ets_delete_table(Tab))
end.
purge_dir(Dir, KeepFiles) ->
@@ -2584,10 +2495,7 @@ info2(_, []) ->
io:format("~n", []).
get_table_properties(Tab) ->
- case catch mnesia_lib:db_match_object(ram_copies,
- mnesia_gvar, {{Tab, '_'}, '_'}) of
- {'EXIT', _} ->
- mnesia:abort({no_exists, Tab, all});
+ try mnesia_lib:db_match_object(ram_copies, mnesia_gvar, {{Tab, '_'}, '_'}) of
RawGvar ->
case [{Item, Val} || {{_Tab, Item}, Val} <- RawGvar] of
[] ->
@@ -2598,6 +2506,8 @@ get_table_properties(Tab) ->
Master = {master_nodes, mnesia:table_info(Tab, master_nodes)},
lists:sort([Size, Memory, Master | Gvar])
end
+ catch error:_ ->
+ mnesia:abort({no_exists, Tab, all})
end.
%%%%%%%%%%% RESTORE %%%%%%%%%%%
@@ -2620,15 +2530,15 @@ restore(_Opaque, BadArg) ->
{aborted, {badarg, BadArg}}.
restore(Opaque, Args, Module) when is_list(Args), is_atom(Module) ->
InitR = #r{opaque = Opaque, module = Module},
- case catch lists:foldl(fun check_restore_arg/2, InitR, Args) of
+ try lists:foldl(fun check_restore_arg/2, InitR, Args) of
R when is_record(R, r) ->
case mnesia_bup:read_schema(R#r.module, Opaque) of
{error, Reason} ->
{aborted, Reason};
BupSchema ->
schema_transaction(fun() -> do_restore(R, BupSchema) end)
- end;
- {'EXIT', Reason} ->
+ end
+ catch exit:Reason ->
{aborted, Reason}
end;
restore(_Opaque, Args, Module) ->
@@ -2885,40 +2795,11 @@ do_merge_schema(LockTabs0) ->
end.
fetch_cstructs(Node) ->
- case need_old_cstructs([Node]) of
- false ->
- rpc:call(Node, mnesia_controller, get_remote_cstructs, []);
- _Ver ->
- case rpc:call(Node, mnesia_controller, get_cstructs, []) of
- {cstructs, Cs0, RR} ->
- {cstructs, [list2cs(cs2list(Cs)) || Cs <- Cs0], RR};
- Err -> Err
- end
- end.
+ rpc:call(Node, mnesia_controller, get_remote_cstructs, []).
-need_old_cstructs() ->
- need_old_cstructs(val({schema, where_to_write})).
-
-need_old_cstructs(Nodes) ->
- Filter = fun(Node) -> not mnesia_monitor:needs_protocol_conversion(Node) end,
- case lists:dropwhile(Filter, Nodes) of
- [] -> false;
- [Node|_] ->
- case rpc:call(Node, mnesia_lib, val, [{schema,cstruct}]) of
- #cstruct{} ->
- %% mnesia_lib:warning("Mnesia on ~p do not need to convert cstruct (~p)~n",
- %% [node(), Node]),
- false;
- {badrpc, _} ->
- need_old_cstructs(lists:delete(Node,Nodes));
- Cs when element(1, Cs) == cstruct, tuple_size(Cs) == 17 ->
- ver4_4_18; % Without majority
- Cs when element(1, Cs) == cstruct, tuple_size(Cs) == 18 ->
- ver4_4_19; % With majority
- Cs when element(1, Cs) == cstruct, tuple_size(Cs) == 19 ->
- ver4_6 % With storage_properties
- end
- end.
+need_old_cstructs() -> false.
+
+need_old_cstructs(_Nodes) -> false.
tab_to_nodes(Tab) when is_atom(Tab) ->
Cs = val({Tab, cstruct}),
@@ -3073,15 +2954,13 @@ do_make_merge_schema(Node, NeedsConv, RemoteCs = #cstruct{}) ->
%% Returns a new cstruct or issues a fatal error
merge_cstructs(Cs, RemoteCs, Force) ->
verify_cstruct(Cs),
- case catch do_merge_cstructs(Cs, RemoteCs, Force) of
- {'EXIT', {aborted, _Reason}} when Force == true ->
- Cs;
- {'EXIT', Reason} ->
- exit(Reason);
+ try do_merge_cstructs(Cs, RemoteCs, Force) of
MergedCs when is_record(MergedCs, cstruct) ->
- MergedCs;
- Other ->
- throw(Other)
+ MergedCs
+ catch exit:{aborted, _Reason} when Force == true ->
+ Cs;
+ exit:Reason -> exit(Reason);
+ error:Reason -> exit(Reason)
end.
do_merge_cstructs(Cs, RemoteCs, Force) ->
diff --git a/lib/mnesia/src/mnesia_snmp_hook.erl b/lib/mnesia/src/mnesia_snmp_hook.erl
index 256f83b029..1599ff1e65 100644
--- a/lib/mnesia/src/mnesia_snmp_hook.erl
+++ b/lib/mnesia/src/mnesia_snmp_hook.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -30,15 +31,6 @@
-include("mnesia.hrl").
-val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _ReASoN_} ->
- case mnesia_lib:other_val(Var) of
- error -> mnesia_lib:pr_other(Var, _ReASoN_);
- Val -> Val
- end;
- _VaLuE_ -> _VaLuE_
- end.
check_ustruct([]) ->
true; %% default value, not SNMP'ified
@@ -85,12 +77,12 @@ delete_table(_MnesiaTab, Tree) ->
%%-----------------------------------------------------------------
update({clear_table, MnesiaTab}) ->
- Tree = val({MnesiaTab, {index, snmp}}),
+ Tree = mnesia_lib:val({MnesiaTab, {index, snmp}}),
b_clear(Tree),
ok;
update({Op, MnesiaTab, MnesiaKey, SnmpKey}) ->
- Tree = val({MnesiaTab, {index, snmp}}),
+ Tree = mnesia_lib:val({MnesiaTab, {index, snmp}}),
update(Op, Tree, MnesiaKey, SnmpKey).
update(Op, Tree, MnesiaKey, SnmpKey) ->
@@ -120,7 +112,7 @@ update(Op, Tree, MnesiaKey, SnmpKey) ->
%%-----------------------------------------------------------------
key_to_oid(Tab,Key) ->
- Types = val({Tab,snmp}),
+ Types = mnesia_lib:val({Tab,snmp}),
key_to_oid(Tab, Key, Types).
key_to_oid(Tab, Key, [{key, Types}]) ->
@@ -144,7 +136,7 @@ keys_to_oid(N, Key, Oid, Types) ->
%% This can be lookup up in tree but that might be on a remote node.
%% It's probably faster to look it up, but use when it migth be remote
oid_to_key(Oid, Tab) ->
- [{key, Types}] = val({Tab,snmp}),
+ [{key, Types}] = mnesia_lib:val({Tab,snmp}),
oid_to_key_1(Types, Oid).
oid_to_key_1(integer, [Key]) -> Key;
diff --git a/lib/mnesia/src/mnesia_snmp_sup.erl b/lib/mnesia/src/mnesia_snmp_sup.erl
index 7e86281428..862eaaec77 100644
--- a/lib/mnesia/src/mnesia_snmp_sup.erl
+++ b/lib/mnesia/src/mnesia_snmp_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_sp.erl b/lib/mnesia/src/mnesia_sp.erl
index 58a177513f..71c1e7dd0c 100644
--- a/lib/mnesia/src/mnesia_sp.erl
+++ b/lib/mnesia/src/mnesia_sp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl
index 866a57e370..246d0e8697 100644
--- a/lib/mnesia/src/mnesia_subscr.erl
+++ b/lib/mnesia/src/mnesia_subscr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -186,11 +187,11 @@ patch_record(Tab, Obj) ->
end.
what(Tab, Tid, {RecName, Key}, delete, undefined) ->
- case catch mnesia_lib:db_get(Tab, Key) of
- Old when is_list(Old) -> %% Op only allowed for set table.
- {mnesia_table_event, {delete, Tab, {RecName, Key}, Old, Tid}};
- _ ->
- %% Record just deleted by a dirty_op or
+ try mnesia_lib:db_get(Tab, Key) of
+ Old -> %% Op only allowed for set table.
+ {mnesia_table_event, {delete, Tab, {RecName, Key}, Old, Tid}}
+ catch error:_ ->
+ %% Record just deleted by a dirty_op or
%% the whole table has been deleted
ignore
end;
@@ -199,10 +200,10 @@ what(Tab, Tid, Obj, delete, Old) ->
what(Tab, Tid, Obj, delete_object, _Old) ->
{mnesia_table_event, {delete, Tab, Obj, [Obj], Tid}};
what(Tab, Tid, Obj, write, undefined) ->
- case catch mnesia_lib:db_get(Tab, element(2, Obj)) of
- Old when is_list(Old) ->
- {mnesia_table_event, {write, Tab, Obj, Old, Tid}};
- {'EXIT', _} ->
+ try mnesia_lib:db_get(Tab, element(2, Obj)) of
+ Old ->
+ {mnesia_table_event, {write, Tab, Obj, Old, Tid}}
+ catch error:_ ->
ignore
end;
what(Tab, Tid, Obj, write, Old) ->
@@ -386,12 +387,12 @@ activate(ClientPid, What, Var, OldSubscribers, SubscrTab) ->
case lists:member(ClientPid, Old) of
false ->
%% Don't care about checking old links
- case catch link(ClientPid) of
+ try link(ClientPid) of
true ->
?ets_insert(SubscrTab, {ClientPid, What}),
add_subscr(Var, What, ClientPid),
- {ok, node()};
- {'EXIT', _Reason} ->
+ {ok, node()}
+ catch error:_ ->
{error, {no_exists, ClientPid}}
end;
true ->
@@ -443,11 +444,10 @@ add_subscr({Tab, commit_work}, What, Pid) ->
deactivate(ClientPid, What, Var, SubscrTab) ->
?ets_match_delete(SubscrTab, {ClientPid, What}),
- case catch ?ets_lookup_element(SubscrTab, ClientPid, 1) of
- List when is_list(List) ->
- ignore;
- {'EXIT', _} ->
- unlink(ClientPid)
+ try
+ ?ets_lookup_element(SubscrTab, ClientPid, 1),
+ ignore
+ catch error:_ -> unlink(ClientPid)
end,
try
del_subscr(Var, What, ClientPid),
diff --git a/lib/mnesia/src/mnesia_sup.erl b/lib/mnesia/src/mnesia_sup.erl
index 8443fefe7f..3a9360aa6d 100644
--- a/lib/mnesia/src/mnesia_sup.erl
+++ b/lib/mnesia/src/mnesia_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/src/mnesia_text.erl b/lib/mnesia/src/mnesia_text.erl
index 0906d18da9..34655b0318 100644
--- a/lib/mnesia/src/mnesia_text.erl
+++ b/lib/mnesia/src/mnesia_text.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -84,8 +85,12 @@ validate_tab({Tabname, RecName, List}) ->
validate_tab(_) -> error(badtab).
make_tabs([{Tab, Def} | Tail]) ->
- case catch mnesia:table_info(Tab, where_to_read) of
- {'EXIT', _} -> %% non-existing table
+ try mnesia:table_info(Tab, where_to_read) of
+ Node ->
+ io:format("** Table ~w already exists on ~p, just entering data~n",
+ [Tab, Node]),
+ make_tabs(Tail)
+ catch exit:_ -> %% non-existing table
case mnesia:create_table(Tab, Def) of
{aborted, Reason} ->
io:format("** Failed to create table ~w ~n"
@@ -95,11 +100,7 @@ make_tabs([{Tab, Def} | Tail]) ->
_ ->
io:format("New table ~w~n", [Tab]),
make_tabs(Tail)
- end;
- Node ->
- io:format("** Table ~w already exists on ~p, just entering data~n",
- [Tab, Node]),
- make_tabs(Tail)
+ end
end;
make_tabs([]) ->
@@ -118,11 +119,9 @@ load_data(L) ->
parse(File) ->
case file(File) of
{ok, Terms} ->
- case catch collect(Terms) of
- {error, X} ->
- {error, X};
- Other ->
- {ok, Other}
+ try collect(Terms) of
+ Other -> {ok, Other}
+ catch throw:Error -> Error
end;
Other ->
Other
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index af658150da..1d3eb87036 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -51,6 +52,7 @@
]).
-include("mnesia.hrl").
+
-import(mnesia_lib, [set/2]).
-import(mnesia_lib, [fatal/2, verbose/2, dbg_out/2]).
@@ -119,7 +121,7 @@ init(Parent) ->
val(Var) ->
case ?catch_val(Var) of
- {'EXIT', _ReASoN_} -> mnesia_lib:other_val(Var, _ReASoN_);
+ {'EXIT', _} -> mnesia_lib:other_val(Var);
_VaLuE_ -> _VaLuE_
end.
@@ -224,11 +226,7 @@ doit_loop(#state{coordinators=Coordinators,participants=Participants,supervisor=
end;
{From, start_outer} -> %% Create and associate ets_tab with Tid
- case catch ?ets_new_table(mnesia_trans_store, [bag, public]) of
- {'EXIT', Reason} -> %% system limit
- Msg = "Cannot create an ets table for the "
- "local transaction store",
- reply(From, {error, {system_limit, Msg, Reason}}, State);
+ try ?ets_new_table(mnesia_trans_store, [bag, public]) of
Etab ->
tmlink(From),
C = mnesia_recover:incr_trans_tid_serial(),
@@ -237,6 +235,10 @@ doit_loop(#state{coordinators=Coordinators,participants=Participants,supervisor=
A2 = gb_trees:insert(Tid,[Etab],Coordinators),
S2 = State#state{coordinators = A2},
reply(From, {new_tid, Tid, Etab}, S2)
+ catch error:Reason -> %% system limit
+ Msg = "Cannot create an ets table for the "
+ "local transaction store",
+ reply(From, {error, {system_limit, Msg, Reason}}, State)
end;
{From, {ask_commit, Protocol, Tid, Commit, DiscNs, RamNs}} ->
@@ -339,15 +341,15 @@ doit_loop(#state{coordinators=Coordinators,participants=Participants,supervisor=
end;
{From, {add_store, Tid}} -> %% new store for nested transaction
- case catch ?ets_new_table(mnesia_trans_store, [bag, public]) of
- {'EXIT', Reason} -> %% system limit
- Msg = "Cannot create an ets table for a nested "
- "local transaction store",
- reply(From, {error, {system_limit, Msg, Reason}}, State);
+ try ?ets_new_table(mnesia_trans_store, [bag, public]) of
Etab ->
A2 = add_coord_store(Coordinators, Tid, Etab),
reply(From, {new_store, Etab},
State#state{coordinators = A2})
+ catch error:Reason -> %% system limit
+ Msg = "Cannot create an ets table for a nested "
+ "local transaction store",
+ reply(From, {error, {system_limit, Msg, Reason}}, State)
end;
{From, {del_store, Tid, Current, Obsolete, PropagateStore}} ->
@@ -471,13 +473,13 @@ doit_loop(#state{coordinators=Coordinators,participants=Participants,supervisor=
do_sync_dirty(From, Tid, Commit, _Tab) ->
?eval_debug_fun({?MODULE, sync_dirty, pre}, [{tid, Tid}]),
- Res = (catch do_dirty(Tid, Commit)),
+ Res = do_dirty(Tid, Commit),
?eval_debug_fun({?MODULE, sync_dirty, post}, [{tid, Tid}]),
From ! {?MODULE, node(), {dirty_res, Res}}.
do_async_dirty(Tid, Commit, _Tab) ->
?eval_debug_fun({?MODULE, async_dirty, pre}, [{tid, Tid}]),
- catch do_dirty(Tid, Commit),
+ do_dirty(Tid, Commit),
?eval_debug_fun({?MODULE, async_dirty, post}, [{tid, Tid}]).
@@ -501,7 +503,7 @@ process_dirty_queue(_Tab, []) ->
[].
prepare_pending_coordinators([{Tid, [Store | _Etabs]} | Coords], IgnoreNew) ->
- case catch ?ets_lookup(Store, pending) of
+ try ?ets_lookup(Store, pending) of
[] ->
prepare_pending_coordinators(Coords, IgnoreNew);
[Pending] ->
@@ -511,8 +513,8 @@ prepare_pending_coordinators([{Tid, [Store | _Etabs]} | Coords], IgnoreNew) ->
true ->
ignore
end,
- prepare_pending_coordinators(Coords, IgnoreNew);
- {'EXIT', _} ->
+ prepare_pending_coordinators(Coords, IgnoreNew)
+ catch error:_ ->
prepare_pending_coordinators(Coords, IgnoreNew)
end;
prepare_pending_coordinators([], _IgnoreNew) ->
@@ -573,11 +575,7 @@ recover_coordinator(Tid, Etabs) ->
Store = hd(Etabs),
CheckNodes = get_elements(nodes,Store),
TellNodes = CheckNodes -- [node()],
- case catch arrange(Tid, Store, async) of
- {'EXIT', Reason} ->
- dbg_out("Recovery of coordinator ~p failed:~n", [Tid, Reason]),
- Protocol = asym_trans,
- tell_outcome(Tid, Protocol, node(), CheckNodes, TellNodes);
+ try arrange(Tid, Store, async) of
{_N, Prep} ->
%% Tell the participants about the outcome
Protocol = Prep#prep.protocol,
@@ -596,6 +594,11 @@ recover_coordinator(Tid, Etabs) ->
false -> %% When killed before store havn't been copied to
ok %% to the new nested trans store.
end
+ catch _:Reason ->
+ dbg_out("Recovery of coordinator ~p failed:~n",
+ [Tid, {Reason, erlang:get_stacktrace()}]),
+ Protocol = asym_trans,
+ tell_outcome(Tid, Protocol, node(), CheckNodes, TellNodes)
end,
erase_ets_tabs(Etabs),
transaction_terminated(Tid),
@@ -724,33 +727,25 @@ non_transaction(OldState={_,_,Trans}, Fun, Args, ActivityKind, Mod)
_ -> async
end,
case transaction(OldState, Fun, Args, infinity, Mod, Kind) of
- {atomic, Res} ->
- Res;
- {aborted,Res} ->
- exit(Res)
+ {atomic, Res} -> Res;
+ {aborted,Res} -> exit(Res)
end;
non_transaction(OldState, Fun, Args, ActivityKind, Mod) ->
Id = {ActivityKind, self()},
NewState = {Mod, Id, non_transaction},
put(mnesia_activity_state, NewState),
- %% I Want something uniqe here, references are expensive
- Ref = mNeSia_nOn_TrAnSacTioN,
- RefRes = (catch {Ref, apply(Fun, Args)}),
- case OldState of
- undefined -> erase(mnesia_activity_state);
- _ -> put(mnesia_activity_state, OldState)
- end,
- case RefRes of
- {Ref, Res} ->
- case Res of
- {'EXIT', Reason} -> exit(Reason);
- {aborted, Reason} -> mnesia:abort(Reason);
- _ -> Res
- end;
- {'EXIT', Reason} ->
- exit(Reason);
- Throw ->
- throw(Throw)
+ try apply(Fun, Args) of
+ {'EXIT', Reason} -> exit(Reason);
+ {aborted, Reason} -> mnesia:abort(Reason);
+ Res -> Res
+ catch
+ throw:Throw -> throw(Throw);
+ _:Reason -> exit(Reason)
+ after
+ case OldState of
+ undefined -> erase(mnesia_activity_state);
+ _ -> put(mnesia_activity_state, OldState)
+ end
end.
transaction(OldTidTs, Fun, Args, Retries, Mod, Type) ->
@@ -810,23 +805,28 @@ insert_objs([], _Tab) ->
ok.
execute_transaction(Fun, Args, Factor, Retries, Type) ->
- case catch apply_fun(Fun, Args, Type) of
- {'EXIT', Reason} ->
- check_exit(Fun, Args, Factor, Retries, Reason, Type);
+ try apply_fun(Fun, Args, Type) of
{atomic, Value} ->
mnesia_lib:incr_counter(trans_commits),
erase(mnesia_activity_state),
%% no need to clear locks, already done by commit ...
%% Flush any un processed mnesia_down messages we might have
flush_downs(),
- catch unlink(whereis(?MODULE)),
+ ?SAFE(unlink(whereis(?MODULE))),
{atomic, Value};
+ {do_abort, Reason} ->
+ check_exit(Fun, Args, Factor, Retries, {aborted, Reason}, Type);
{nested_atomic, Value} ->
mnesia_lib:incr_counter(trans_commits),
- {atomic, Value};
- Value -> %% User called throw
+ {atomic, Value}
+ catch throw:Value -> %% User called throw
Reason = {aborted, {throw, Value}},
- return_abort(Fun, Args, Reason)
+ return_abort(Fun, Args, Reason);
+ error:Reason ->
+ ST = erlang:get_stacktrace(),
+ check_exit(Fun, Args, Factor, Retries, {Reason,ST}, Type);
+ _:Reason ->
+ check_exit(Fun, Args, Factor, Retries, Reason, Type)
end.
apply_fun(Fun, Args, Type) ->
@@ -836,10 +836,10 @@ apply_fun(Fun, Args, Type) ->
{atomic, Result};
do_commit_nested ->
{nested_atomic, Result};
- {do_abort, {aborted, Reason}} ->
- {'EXIT', {aborted, Reason}};
- {do_abort, Reason} ->
- {'EXIT', {aborted, Reason}}
+ {do_abort, {aborted, Reason}} ->
+ {do_abort, Reason};
+ {do_abort, _} = Abort ->
+ Abort
end.
check_exit(Fun, Args, Factor, Retries, Reason, Type) ->
@@ -943,7 +943,7 @@ return_abort(Fun, Args, Reason) ->
OldStore = Ts#tidstore.store,
Nodes = get_elements(nodes, OldStore),
intercept_friends(Tid, Ts),
- catch mnesia_lib:incr_counter(trans_failures),
+ ?SAFE(mnesia_lib:incr_counter(trans_failures)),
Level = Ts#tidstore.level,
if
Level == 1 ->
@@ -951,7 +951,7 @@ return_abort(Fun, Args, Reason) ->
?MODULE ! {delete_transaction, Tid},
erase(mnesia_activity_state),
flush_downs(),
- catch unlink(whereis(?MODULE)),
+ ?SAFE(unlink(whereis(?MODULE))),
{aborted, mnesia_lib:fix_error(Reason)};
true ->
%% Nested transaction
@@ -1005,11 +1005,11 @@ erase_activity_id() ->
erase(mnesia_activity_state).
get_elements(Type,Store) ->
- case catch ?ets_lookup(Store, Type) of
+ try ?ets_lookup(Store, Type) of
[] -> [];
[{_,Val}] -> [Val];
- {'EXIT', _} -> [];
Vals -> [Val|| {_,Val} <- Vals]
+ catch error:_ -> []
end.
opt_propagate_store(_Current, _Obsolete, false) ->
@@ -1032,7 +1032,7 @@ intercept_friends(_Tid, Ts) ->
intercept_best_friend([],_) -> ok;
intercept_best_friend([{stop,Fun} | R],Ignore) ->
- catch Fun(),
+ ?CATCH(Fun()),
intercept_best_friend(R,Ignore);
intercept_best_friend([Pid | R],false) ->
Pid ! {activity_ended, undefined, self()},
@@ -1046,25 +1046,12 @@ wait_for_best_friend(Pid, Timeout) ->
{'EXIT', Pid, _} -> ok;
{activity_ended, _, Pid} -> ok
after Timeout ->
- case my_process_is_alive(Pid) of
+ case erlang:is_process_alive(Pid) of
true -> wait_for_best_friend(Pid, 1000);
false -> ok
end
end.
-my_process_is_alive(Pid) ->
- case catch erlang:is_process_alive(Pid) of % New BIF in R5
- true ->
- true;
- false ->
- false;
- {'EXIT', _} -> % Pre R5 backward compatibility
- case process_info(Pid, message_queue_len) of
- undefined -> false;
- _ -> true
- end
- end.
-
dirty(Protocol, Item) ->
{{Tab, Key}, _Val, _Op} = Item,
Tid = {dirty, self()},
@@ -1144,18 +1131,8 @@ arrange(Tid, Store, Type) ->
async -> #prep{protocol = sym_trans, records = Recs};
sync -> #prep{protocol = sync_sym_trans, records = Recs}
end,
- case catch do_arrange(Tid, Store, Key, Prep, N) of
- {'EXIT', Reason} ->
- dbg_out("do_arrange failed ~p ~p~n", [Reason, Tid]),
- case Reason of
- {aborted, R} ->
- mnesia:abort(R);
- _ ->
- mnesia:abort(Reason)
- end;
- {New, Prepared} ->
- {New, Prepared#prep{records = reverse(Prepared#prep.records)}}
- end.
+ {New, Prepared} = do_arrange(Tid, Store, Key, Prep, N),
+ {New, Prepared#prep{records = reverse(Prepared#prep.records)}}.
reverse([]) ->
[];
@@ -1522,7 +1499,7 @@ multi_commit(asym_trans, Majority, Tid, CR, Store) ->
Pending = mnesia_checkpoint:tm_enter_pending(Tid, DiscNs, RamNs),
?ets_insert(Store, Pending),
{WaitFor, Local} = ask_commit(asym_trans, Tid, CR2, DiscNs, RamNs),
- SchemaPrep = (catch mnesia_schema:prepare_commit(Tid, Local, {coord, WaitFor})),
+ SchemaPrep = ?CATCH(mnesia_schema:prepare_commit(Tid, Local, {coord, WaitFor})),
{Votes, Pids} = rec_all(WaitFor, Tid, do_commit, []),
?eval_debug_fun({?MODULE, multi_commit_asym_got_votes},
@@ -1589,7 +1566,7 @@ rec_acc_pre_commit([Pid | Tail], Tid, Store, Commit, Res, DumperMode,
GoodPids, SchemaAckPids);
{mnesia_down, Node} when Node == node(Pid) ->
AbortRes = {do_abort, {bad_commit, Node}},
- catch Pid ! {Tid, AbortRes}, %% Tell him that he has died
+ ?SAFE(Pid ! {Tid, AbortRes}), %% Tell him that he has died
rec_acc_pre_commit(Tail, Tid, Store, Commit, AbortRes, DumperMode,
GoodPids, SchemaAckPids)
end;
@@ -1666,7 +1643,7 @@ commit_participant(Coord, Tid, C = #commit{}, DiscNs, RamNs) ->
commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
?eval_debug_fun({?MODULE, commit_participant, pre}, [{tid, Tid}]),
- case catch mnesia_schema:prepare_commit(Tid, C0, {part, Coord}) of
+ try mnesia_schema:prepare_commit(Tid, C0, {part, Coord}) of
{Modified, C = #commit{}, DumperMode} ->
%% If we can not find any local unclear decision
%% we should presume abort at startup recovery
@@ -1715,13 +1692,10 @@ commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
?eval_debug_fun({?MODULE, commit_participant, undo_prepare},
[{tid, Tid}]);
- {'EXIT', _, _} ->
+ {'EXIT', _MnesiaTM, Reason} ->
+ reply(Coord, {do_abort, Tid, self(), {bad_commit,Reason}}),
mnesia_recover:log_decision(D#decision{outcome = aborted}),
- ?eval_debug_fun({?MODULE, commit_participant, exit_log_abort},
- [{tid, Tid}]),
- mnesia_schema:undo_prepare_commit(Tid, C0),
- ?eval_debug_fun({?MODULE, commit_participant, exit_undo_prepare},
- [{tid, Tid}]);
+ mnesia_schema:undo_prepare_commit(Tid, C0);
Msg ->
verbose("** ERROR ** commit_participant ~p, got unexpected msg: ~p~n",
@@ -1742,9 +1716,8 @@ commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
reply(Coord, {do_abort, Tid, self(), {bad_commit,internal}}),
verbose("** ERROR ** commit_participant ~p, got unexpected msg: ~p~n",
[Tid, Msg])
- end;
-
- {'EXIT', Reason} ->
+ end
+ catch _:Reason ->
?eval_debug_fun({?MODULE, commit_participant, vote_no},
[{tid, Tid}]),
reply(Coord, {vote_no, Tid, Reason}),
@@ -1790,22 +1763,20 @@ do_commit(Tid, C, DumperMode) ->
%% Update the items
do_update(Tid, Storage, [Op | Ops], OldRes) ->
- case catch do_update_op(Tid, Storage, Op) of
- ok ->
- do_update(Tid, Storage, Ops, OldRes);
- {'EXIT', Reason} ->
+ try do_update_op(Tid, Storage, Op) of
+ ok -> do_update(Tid, Storage, Ops, OldRes);
+ NewRes -> do_update(Tid, Storage, Ops, NewRes)
+ catch _:Reason ->
%% This may only happen when we recently have
%% deleted our local replica, changed storage_type
%% or transformed table
%% BUGBUG: Updates may be lost if storage_type is changed.
%% Determine actual storage type and try again.
%% BUGBUG: Updates may be lost if table is transformed.
-
+ ST = erlang:get_stacktrace(),
verbose("do_update in ~w failed: ~p -> {'EXIT', ~p}~n",
- [Tid, Op, Reason]),
- do_update(Tid, Storage, Ops, OldRes);
- NewRes ->
- do_update(Tid, Storage, Ops, NewRes)
+ [Tid, Op, {Reason, ST}]),
+ do_update(Tid, Storage, Ops, OldRes)
end;
do_update(_Tid, _Storage, [], Res) ->
Res.
@@ -1821,14 +1792,15 @@ do_update_op(Tid, Storage, {{Tab, K}, Val, delete}) ->
do_update_op(Tid, Storage, {{Tab, K}, {RecName, Incr}, update_counter}) ->
{NewObj, OldObjs} =
- case catch mnesia_lib:db_update_counter(Storage, Tab, K, Incr) of
- NewVal when is_integer(NewVal), NewVal >= 0 ->
- {{RecName, K, NewVal}, [{RecName, K, NewVal - Incr}]};
- _ when Incr > 0 ->
+ try
+ NewVal = mnesia_lib:db_update_counter(Storage, Tab, K, Incr),
+ true = is_integer(NewVal) andalso (NewVal >= 0),
+ {{RecName, K, NewVal}, [{RecName, K, NewVal - Incr}]}
+ catch error:_ when Incr > 0 ->
New = {RecName, K, Incr},
mnesia_lib:db_put(Storage, Tab, New),
{New, []};
- _ ->
+ error:_ ->
Zero = {RecName, K, 0},
mnesia_lib:db_put(Storage, Tab, Zero),
{Zero, []}
@@ -1913,16 +1885,14 @@ commit_clear([H|R], Tid, Tab, K, Obj)
do_snmp(_, []) -> ok;
do_snmp(Tid, [Head | Tail]) ->
- case catch mnesia_snmp_hook:update(Head) of
- {'EXIT', Reason} ->
+ try mnesia_snmp_hook:update(Head)
+ catch _:Reason ->
%% This should only happen when we recently have
%% deleted our local replica or recently deattached
%% the snmp table
-
+ ST = erlang:get_stacktrace(),
verbose("do_snmp in ~w failed: ~p -> {'EXIT', ~p}~n",
- [Tid, Head, Reason]);
- ok ->
- ignore
+ [Tid, Head, {Reason, ST}])
end,
do_snmp(Tid, Tail).
@@ -2093,7 +2063,7 @@ rec_all([Node | Tail], Tid, Res, Pids) ->
%% Make sure that mnesia_tm knows it has died
%% it may have been restarted
Abort = {do_abort, {bad_commit, Node}},
- catch {?MODULE, Node} ! {Tid, Abort},
+ ?SAFE({?MODULE, Node} ! {Tid, Abort}),
rec_all(Tail, Tid, Abort, Pids)
end;
rec_all([], _Tid, Res, Pids) ->
@@ -2237,8 +2207,6 @@ reconfigure_coordinators(N, [{Tid, [Store | _]} | Coordinators]) ->
true ->
send_mnesia_down(Tid, Store, N)
end;
- aborted ->
- ignore; % avoid spurious mnesia_down messages
_ ->
%% Tell the coordinator about the mnesia_down
send_mnesia_down(Tid, Store, N)
diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile
index 45ce5b1983..5799e34e13 100644
--- a/lib/mnesia/test/Makefile
+++ b/lib/mnesia/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/mnesia/test/mnesia_SUITE.erl b/lib/mnesia/test/mnesia_SUITE.erl
index 921ebb71e9..070f51e6a8 100644
--- a/lib/mnesia/test/mnesia_SUITE.erl
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_atomicity_test.erl b/lib/mnesia/test/mnesia_atomicity_test.erl
index 06c4d16d71..e3e0eaaf75 100644
--- a/lib/mnesia/test/mnesia_atomicity_test.erl
+++ b/lib/mnesia/test/mnesia_atomicity_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -556,8 +557,8 @@ start_lock_waiter(BlockOpA, BlockOpB, Config) ->
?verify_mnesia([N1], [N2]).
mk_tab_name(Prefix) ->
- {Mega, Sec, Micro} = erlang:now(),
- list_to_atom(lists:concat([Prefix , Mega, '_', Sec, '_', Micro])).
+ Count = erlang:unique_integer([monotonic,positive]),
+ list_to_atom(lists:concat([Prefix , '_', Count])).
lock_waiter_fun(Op, TabName, Val) ->
case Op of
diff --git a/lib/mnesia/test/mnesia_bench_SUITE.erl b/lib/mnesia/test/mnesia_bench_SUITE.erl
index 7cbf77f046..962b57ae6f 100644
--- a/lib/mnesia/test/mnesia_bench_SUITE.erl
+++ b/lib/mnesia/test/mnesia_bench_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_config_backup.erl b/lib/mnesia/test/mnesia_config_backup.erl
index 0916e255e2..a95f305b43 100644
--- a/lib/mnesia/test/mnesia_config_backup.erl
+++ b/lib/mnesia/test/mnesia_config_backup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -90,7 +91,8 @@ open_read(Name) ->
List = lists:reverse(ReverseList),
{ok, #backup{name = Name, mode = read, items = List}};
{error, Reason} ->
- {error, {open_read, Reason}}
+ %% {error, {open_read, Reason}}
+ {Reason, error} %% Testing error handling in mnesia
end.
read(Opaque) when Opaque#backup.mode == read ->
diff --git a/lib/mnesia/test/mnesia_config_event.erl b/lib/mnesia/test/mnesia_config_event.erl
index 832bf94eb9..6a35e14363 100644
--- a/lib/mnesia/test/mnesia_config_event.erl
+++ b/lib/mnesia/test/mnesia_config_event.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/test/mnesia_config_test.erl b/lib/mnesia/test/mnesia_config_test.erl
index c495bce63f..089fbc06dc 100644
--- a/lib/mnesia/test/mnesia_config_test.erl
+++ b/lib/mnesia/test/mnesia_config_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,7 +38,6 @@
dump_log_update_in_place/1,
event_module/1,
- ignore_fallback_at_startup/1,
inconsistent_database/1,
max_wait_for_decision/1,
send_compressed/1,
@@ -104,7 +104,7 @@ all() ->
[access_module, auto_repair, backup_module, debug, dir,
dump_log_load_regulation, {group, dump_log_thresholds},
dump_log_update_in_place,
- event_module, ignore_fallback_at_startup,
+ event_module,
inconsistent_database, max_wait_for_decision,
send_compressed, app_test, {group, schema_config},
unknown_config].
@@ -317,11 +317,17 @@ backup_module(Config) when is_list(Config) ->
?match([], mnesia_test_lib:start_mnesia(Nodes, [test_table, test_table2])),
%% Now check newly started tables
- ?match({atomic, [1,2]},
+ ?match({atomic, [1,2]},
mnesia:transaction(fun() -> lists:sort(mnesia:all_keys(test_table)) end)),
- ?match({atomic, [3,4]},
+ ?match({atomic, [3,4]},
mnesia:transaction(fun() -> lists:sort(mnesia:all_keys(test_table2)) end)),
-
+
+ %% Test some error cases
+ mnesia:set_debug_level(debug),
+ ?match({error, _}, mnesia:install_fallback("NonExisting.FILE")),
+ ?match({error, _}, mnesia:install_fallback(filename:join(mnesia_lib:dir(), "LATEST.LOG"))),
+
+ %% Cleanup
file:delete(File),
?verify_mnesia(Nodes, []),
?cleanup(1, Config),
@@ -609,13 +615,6 @@ dump_log_load_regulation(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ignore_fallback_at_startup(doc) ->
- ["Start Mnesia without rollback of the database to the fallback. ",
- "Once Mnesia has been (re)started the installed fallback should",
- "be handled as a normal active fallback.",
- "Install a customized event module which disables the termination",
- "of Mnesia when mnesia_down occurrs with an active fallback."].
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
max_wait_for_decision(doc) ->
@@ -1207,7 +1206,7 @@ dynamic_ext(Config) when is_list(Config) ->
end,
[Check(Test) || Test <- [{tab1, ram_copies},{tab2, disc_copies},{tab3, disc_only_copies}]],
- T = now(),
+ T = erlang:unique_integer(),
?match(ok, mnesia:dirty_write({tab0, 42, T})),
?match(ok, mnesia:dirty_write({tab1, 42, T})),
?match(ok, mnesia:dirty_write({tab2, 42, T})),
@@ -1285,7 +1284,7 @@ check_storage(Me, Orig, Other) ->
mnesia_test_lib:kill_mnesia([Orig]),
mnesia_test_lib:kill_mnesia(Other),
- T = now(),
+ T = erlang:unique_integer(),
?match(ok, rpc:call(Me, mnesia, dirty_write, [{tab2, 42, T}])),
?match(stopped, rpc:call(Me, mnesia, stop, [])),
?match(ok, rpc:call(Me, mnesia, start, [])),
diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl
index a76a0116d5..087aef86c9 100644
--- a/lib/mnesia/test/mnesia_consistency_test.erl
+++ b/lib/mnesia/test/mnesia_consistency_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_cost.erl b/lib/mnesia/test/mnesia_cost.erl
index 3221f46f61..714dbaef27 100644
--- a/lib/mnesia/test/mnesia_cost.erl
+++ b/lib/mnesia/test/mnesia_cost.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -107,11 +108,11 @@ run(What, OtherInfo, Ops, F) ->
run(t, What, OtherInfo, Ops, F).
run(How, What, OtherInfo, Ops, F) ->
- T1 = erlang:now(),
+ T1 = erlang:monotonic_time(),
statistics(runtime),
do_times(How, ?TIMES, F),
{_, RunTime} = statistics(runtime),
- T2 = erlang:now(),
+ T2 = erlang:monotonic_time(),
RealTime = subtr(T1, T2),
report(How, What, OtherInfo, Ops, RunTime, RealTime).
@@ -139,11 +140,7 @@ report(dirty, What, OtherInfo, Ops, RunTime, RealTime) ->
subtr(Before, After) ->
- E =(element(1,After)*1000000000000
- +element(2,After)*1000000+element(3,After)) -
- (element(1,Before)*1000000000000
- +element(2,Before)*1000000+element(3,Before)),
- E div 1000.
+ erlang:convert_time_unit(After-Before, native, milli_seconds).
do_times(t, I, F) ->
do_trans_times(I, F);
diff --git a/lib/mnesia/test/mnesia_dbn_meters.erl b/lib/mnesia/test/mnesia_dbn_meters.erl
index feaf90ee75..5c3ea08a1d 100644
--- a/lib/mnesia/test/mnesia_dbn_meters.erl
+++ b/lib/mnesia/test/mnesia_dbn_meters.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -92,7 +93,7 @@ some_meters() ->
report_meter(Meter) ->
Times = 100,
Micros = repeat_meter(Meter,{atomic,{0,ignore}},Times) div Times,
- io:format("\t~-30w ~-10w micro seconds (mean of ~p repetitions)~n",[Meter,Micros,Times]).
+ io:format("\t~-30w ~-10w nano seconds (mean of ~p repetitions)~n",[Meter,Micros,Times]).
repeat_meter(_Meter,{atomic,{Micros,_Result}},0) ->
Micros;
@@ -109,9 +110,9 @@ meter(create) ->
Key = 1,
mnesia:transaction(fun() -> mnesia:delete({simple,Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:write(#simple{key=Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -120,9 +121,9 @@ meter(open_safe_read) ->
Key = 2,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:read({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -131,9 +132,9 @@ meter(open_dirty_read) ->
Key = 21,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:dirty_read({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -143,9 +144,9 @@ meter(get_int) ->
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
[Simple] = mnesia:read({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
Int = Simple#simple.val,
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,Int)
end,
mnesia:transaction(Fun);
@@ -154,9 +155,9 @@ meter(open_update) ->
Key = 3,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:wread({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -166,9 +167,9 @@ meter(put_int) ->
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
[Simple] = mnesia:wread({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = Simple#simple{val=7},
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -178,10 +179,10 @@ meter(put_int_and_copy) ->
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
[Simple] = mnesia:wread({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
Simple2 = Simple#simple{val=17},
R = mnesia:write(Simple2),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -190,15 +191,15 @@ meter(dirty_put_int_and_copy) ->
Key = 55,
mnesia:dirty_write(#simple{key=Key}),
[Simple] = mnesia:dirty_read({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
Simple2 = Simple#simple{val=17},
R = mnesia:dirty_write(Simple2),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
{atomic,elapsed_time(BeforeT,AfterT,R)};
meter(start_trans) ->
- BeforeT = erlang:now(),
- {atomic,AfterT} = mnesia:transaction(fun() -> erlang:now() end),
+ BeforeT = erlang:monotonic_time(),
+ {atomic,AfterT} = mnesia:transaction(fun() -> erlang:monotonic_time() end),
{atomic,elapsed_time(BeforeT,AfterT,ok)};
meter(commit_one_update) ->
@@ -208,19 +209,19 @@ meter(commit_one_update) ->
[Simple] = mnesia:wread({simple,Key}),
Simple2 = Simple#simple{val=27},
_R = mnesia:write(Simple2),
- erlang:now()
+ erlang:monotonic_time()
end,
{atomic,BeforeT} = mnesia:transaction(Fun),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
{atomic,elapsed_time(BeforeT,AfterT,ok)};
meter(delete) ->
Key = 7,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:delete({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -228,15 +229,12 @@ meter(delete) ->
meter(dirty_delete) ->
Key = 75,
mnesia:dirty_write(#simple{key=Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:dirty_delete({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
{atomic, elapsed_time(BeforeT,AfterT,R)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Calculate the elapsed time
elapsed_time(BeforeT,AfterT,Result) ->
- {(element(1,AfterT)*1000000000000
- +element(2,AfterT)*1000000+element(3,AfterT)) -
- (element(1,BeforeT)*1000000000000
- +element(2,BeforeT)*1000000+element(3,BeforeT)),Result}.
+ {erlang:convert_time_unit(AfterT-BeforeT, native, nano_seconds),Result}.
diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl
index 519b4bb052..0d57e5a1b1 100644
--- a/lib/mnesia/test/mnesia_dirty_access_test.erl
+++ b/lib/mnesia/test/mnesia_dirty_access_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -400,9 +401,26 @@ dirty_index_read(Config, Storage) ->
?match({'EXIT', _}, mnesia:dirty_index_read(Tab, 2, BadValPos)),
?match({'EXIT', _}, mnesia:dirty_index_read(foo, 2, ValPos)),
?match({'EXIT', _}, mnesia:dirty_index_read([], 2, ValPos)),
-
+
+ mnesia:dirty_write({Tab, 5, 1}),
+ ?match(ok, index_read_loop(Tab, 0)),
+
?verify_mnesia(Nodes, []).
+
+index_read_loop(Tab, N) when N =< 1000 ->
+ spawn_link(fun() ->
+ mnesia:transaction(fun() -> mnesia:write({Tab, 5, 1}) end)
+ end),
+ case mnesia:dirty_match_object({Tab, '_', 1}) of
+ [{Tab, 5, 1}] ->
+ index_read_loop(Tab, N+1);
+ Other -> {N, Other}
+ end;
+index_read_loop(_, _) ->
+ ok.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/test/mnesia_durability_test.erl b/lib/mnesia/test/mnesia_durability_test.erl
index 366fda7044..4c9438df3e 100644
--- a/lib/mnesia/test/mnesia_durability_test.erl
+++ b/lib/mnesia/test/mnesia_durability_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl
index 9e0a8db1ae..e605fa7926 100644
--- a/lib/mnesia/test/mnesia_evil_backup.erl
+++ b/lib/mnesia/test/mnesia_evil_backup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -142,6 +143,9 @@ restore_errors(Config) when is_list(Config) ->
?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{skip_tables, xxx}])),
?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{recreate_tables, [schema]}])),
?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{default_op, asdklasd}])),
+ MnesiaDir = mnesia_lib:dir(),
+ ?match({aborted, {not_a_log_file, _}}, mnesia:restore(filename:join(MnesiaDir, "schema.DAT"), [])),
+ ?match({aborted, _}, mnesia:restore(filename:join(MnesiaDir, "LATEST.LOG"), [])),
ok.
restore_clear(suite) -> [];
@@ -225,10 +229,16 @@ restore(Config, Op) ->
[mnesia:dirty_write({Tab1, N, N+1}) || N <- lists:seq(1, 11)],
[mnesia:dirty_write({Tab2, N, N+1}) || N <- lists:seq(1, 11)],
[mnesia:dirty_write({Tab3, N, N+1}) || N <- lists:seq(1, 11)],
- _Res11 = [{Tab1, N, N+1} || N <- lists:seq(1, 11)],
+
Res21 = [{Tab2, N, N+1} || N <- lists:seq(1, 11)],
Res31 = [[{Tab3, N, N+1}, {Tab3, N, N+44}] || N <- lists:seq(1, 10)],
-
+ Check = fun() ->
+ [disk_log:pid2name(X) ||
+ X <- processes(), Data <- [process_info(X, [current_function])],
+ Data =/= undefined,
+ element(1, element(2, lists:keyfind(current_function, 1, Data)))=:= disk_log]
+ end,
+ Before = Check(),
?match({atomic, [Tab1]}, Restore(File1, [{Op, [Tab1]},
{skip_tables, Tabs -- [Tab1]}])),
case Op of
@@ -315,6 +325,8 @@ restore(Config, Op) ->
end,
?match(ok, file:delete(File1)),
?match(ok, file:delete(File2)),
+ ?match([], Check() -- Before),
+
?verify_mnesia(Nodes, []).
@@ -488,6 +500,14 @@ install_fallback(Config) when is_list(Config) ->
mnesia_test_lib:kill_mnesia([Node1, Node2]),
timer:sleep(timer:seconds(1)), % Let it die!
+ ok = mnesia:start([{ignore_fallback_at_startup, true}]),
+ ok = mnesia:wait_for_tables([Tab, Tab2, Tab3], 10000),
+ ?match([{Tab, 6, test_nok}], mnesia:dirty_read({Tab, 6})),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ application:set_env(mnesia, ignore_fallback_at_startup, false),
+
+ timer:sleep(timer:seconds(1)), % Let it die!
+
?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab, Tab2, Tab3])),
% Verify
@@ -510,6 +530,13 @@ install_fallback(Config) when is_list(Config) ->
file:delete(File3),
?match({error, _}, mnesia:install_fallback(File3)),
?match({error, _}, mnesia:install_fallback(File2, mnesia_badmod)),
+ ?match({error, _}, mnesia:install_fallback(File2, {foo, foo})),
+ ?match({error, _}, mnesia:install_fallback(File2, [{foo, foo}])),
+ ?match({error, {badarg, {skip_tables, _}}},
+ mnesia:install_fallback(File2, [{default_op, skip_tables},
+ {default_op, keep_tables},
+ {keep_tables, [Tab, Tab2, Tab3]},
+ {skip_tables, [foo,{asd}]}])),
?match(ok, mnesia:install_fallback(File2, mnesia_backup)),
?match(ok, file:delete(File)),
?match(ok, file:delete(File2)),
@@ -535,6 +562,7 @@ uninstall_fallback(Config) when is_list(Config) ->
?match(ok, mnesia:install_fallback(File2)),
?match(ok, file:delete(File)),
?match(ok, file:delete(File2)),
+ ?match({error, _}, mnesia:uninstall_fallback([foobar])),
?match(ok, mnesia:uninstall_fallback()),
mnesia_test_lib:kill_mnesia([Node1, Node2]),
diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl
index 2d1623b6ca..68b521c939 100644
--- a/lib/mnesia/test/mnesia_evil_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1338,11 +1339,11 @@ user_properties(Config) when is_list(Config) ->
?match([], mnesia:table_info(Tab2, user_properties)),
?match([], mnesia:table_info(Tab3, user_properties)),
- ?match({'EXIT', {no_exists, {Tab1, user_property, PropKey}}},
+ ?match({'EXIT', {aborted, {no_exists, {Tab1, user_property, PropKey}}}},
mnesia:read_table_property(Tab1, PropKey)),
- ?match({'EXIT', {no_exists, {Tab2, user_property, PropKey}}},
+ ?match({'EXIT', {aborted, {no_exists, {Tab2, user_property, PropKey}}}},
mnesia:read_table_property(Tab2, PropKey)),
- ?match({'EXIT', {no_exists, {Tab3, user_property, PropKey}}},
+ ?match({'EXIT', {aborted, {no_exists, {Tab3, user_property, PropKey}}}},
mnesia:read_table_property(Tab3, PropKey)),
?match({atomic, ok}, mnesia:write_table_property(Tab1, Prop)),
diff --git a/lib/mnesia/test/mnesia_examples_test.erl b/lib/mnesia/test/mnesia_examples_test.erl
index 219f358fdb..889ec50520 100644
--- a/lib/mnesia/test/mnesia_examples_test.erl
+++ b/lib/mnesia/test/mnesia_examples_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_frag_test.erl b/lib/mnesia/test/mnesia_frag_test.erl
index 6695fbc880..c6430240c8 100644
--- a/lib/mnesia/test/mnesia_frag_test.erl
+++ b/lib/mnesia/test/mnesia_frag_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_inconsistent_database_test.erl b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
index c4b6257d5b..c6ca3c6853 100644
--- a/lib/mnesia/test/mnesia_inconsistent_database_test.erl
+++ b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/test/mnesia_install_test.erl b/lib/mnesia/test/mnesia_install_test.erl
index 06d53d3912..e0145f3a8b 100644
--- a/lib/mnesia/test/mnesia_install_test.erl
+++ b/lib/mnesia/test/mnesia_install_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index 8468472cf2..4dd0c01d05 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -38,7 +39,7 @@ groups() ->
[{locking, [],
[no_conflict, simple_queue_conflict,
advanced_queue_conflict, simple_deadlock_conflict,
- advanced_deadlock_conflict, lock_burst,
+ advanced_deadlock_conflict, schema_deadlock, lock_burst,
{group, sticky_locks}, {group, unbound_locking},
{group, admin_conflict}, nasty]},
{sticky_locks, [], [basic_sticky_functionality]},
@@ -147,20 +148,32 @@ simple_queue_conflict(Config) when is_list(Config) ->
fun_loop(Fun, AllSharedLocks, OneExclusiveLocks),
ok.
-wait_for_lock(Pid, _Nodes, 0) ->
+wait_for_lock(Pid, Nodes, Retry) ->
+ wait_for_lock(Pid, Nodes, Retry, queue).
+
+wait_for_lock(Pid, _Nodes, 0, queue) ->
Queue = mnesia:system_info(lock_queue),
?error("Timeout while waiting for lock on Pid ~p in queue ~p~n", [Pid, Queue]);
-wait_for_lock(Pid, Nodes, N) ->
- rpc:multicall(Nodes, sys, get_status, [mnesia_locker]),
- List = [rpc:call(Node, mnesia, system_info, [lock_queue]) || Node <- Nodes],
+wait_for_lock(Pid, _Nodes, 0, held) ->
+ Held = mnesia:system_info(held_locks),
+ ?error("Timeout while waiting for lock on Pid ~p (held) ~p~n", [Pid, Held]);
+wait_for_lock(Pid, Nodes, N, Where) ->
+ rpc:multicall(Nodes, sys, get_status, [mnesia_locker]),
+ List = case Where of
+ queue ->
+ [rpc:call(Node, mnesia, system_info, [lock_queue]) || Node <- Nodes];
+ held ->
+ [rpc:call(Node, mnesia, system_info, [held_locks]) || Node <- Nodes]
+ end,
Q = lists:append(List),
- check_q(Pid, Q, Nodes, N).
+ check_q(Pid, Q, Nodes, N, Where).
-check_q(Pid, [{_Oid, _Op, Pid, _Tid, _WFT} | _Tail], _N, _Count) -> ok;
-check_q(Pid, [_ | Tail], N, Count) -> check_q(Pid, Tail, N, Count);
-check_q(Pid, [], N, Count) ->
- timer:sleep(500),
- wait_for_lock(Pid, N, Count - 1).
+check_q(Pid, [{_Oid, _Op, Pid, _Tid, _WFT} | _Tail], _N, _Count, _Where) -> ok;
+check_q(Pid, [{_Oid, _Op, {tid,_,Pid}} | _Tail], _N, _Count, _Where) -> ok;
+check_q(Pid, [_ | Tail], N, Count, Where) -> check_q(Pid, Tail, N, Count, Where);
+check_q(Pid, [], N, Count, Where) ->
+ timer:sleep(200),
+ wait_for_lock(Pid, N, Count - 1, Where).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -269,6 +282,43 @@ advanced_deadlock_conflict(Config) when is_list(Config) ->
?match([], mnesia:system_info(lock_queue)),
ok.
+%% Verify (and regression test) deadlock in del_table_copy(schema, Node)
+schema_deadlock(Config) when is_list(Config) ->
+ Ns = [Node1, Node2] = ?acquire_nodes(2, Config),
+ ?match({atomic, ok}, mnesia:create_table(a, [{disc_copies, Ns}])),
+ ?match({atomic, ok}, mnesia:create_table(b, [{disc_copies, Ns}])),
+
+ Tester = self(),
+
+ Deadlocker = fun() ->
+ mnesia:write({a,1,1}), %% grab write lock on A
+ receive
+ continue ->
+ mnesia:write({b,1,1}), %% grab write lock on B
+ end_trans
+ end
+ end,
+
+ ?match(stopped, rpc:call(Node2, mnesia, stop, [])),
+ timer:sleep(500), %% Let Node1 reconfigure
+ sys:get_status(mnesia_monitor),
+
+ DoingTrans = spawn_link(fun() -> Tester ! {self(),mnesia:transaction(Deadlocker)} end),
+ wait_for_lock(DoingTrans, [Node1], 10, held),
+ %% Will grab write locks on schema, a, and b
+ DoingSchema = spawn_link(fun() -> Tester ! {self(), mnesia:del_table_copy(schema, Node2)} end),
+ timer:sleep(500), %% Let schema trans start, and try to grab locks
+ DoingTrans ! continue,
+
+ ?match(ok, receive {DoingTrans, {atomic, end_trans}} -> ok after 5000 -> timeout end),
+ ?match(ok, receive {DoingSchema, {atomic, ok}} -> ok after 5000 -> timeout end),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+
one_oid(Tab) -> {Tab, 1}.
other_oid(Tab) -> {Tab, 2}.
@@ -1126,7 +1176,9 @@ update_shared(Tab, Me, Acc) ->
0 ->
case mnesia:transaction(Update) of
{atomic, {ok,Term,W2}} ->
- io:format("~p:~p:(~p,~p) ~w@~w~n", [erlang:now(),node(),Me,Acc,Term,W2]),
+ io:format("~p:~p:(~p,~p) ~w@~w~n",
+ [erlang:unique_integer([monotonic,positive]),
+ node(),Me,Acc,Term,W2]),
update_shared(Tab, Me, Acc+1);
Else ->
?error("Trans failed on ~p with ~p~n"
diff --git a/lib/mnesia/test/mnesia_majority_test.erl b/lib/mnesia/test/mnesia_majority_test.erl
index 41ba0fd601..f2e7a09e5e 100644
--- a/lib/mnesia/test/mnesia_majority_test.erl
+++ b/lib/mnesia/test/mnesia_majority_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_measure_test.erl b/lib/mnesia/test/mnesia_measure_test.erl
index 8854854570..b184c5efdf 100644
--- a/lib/mnesia/test/mnesia_measure_test.erl
+++ b/lib/mnesia/test/mnesia_measure_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/mnesia/test/mnesia_meter.erl b/lib/mnesia/test/mnesia_meter.erl
index 68094c4431..73f35a4a46 100644
--- a/lib/mnesia/test/mnesia_meter.erl
+++ b/lib/mnesia/test/mnesia_meter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_nice_coverage_test.erl b/lib/mnesia/test/mnesia_nice_coverage_test.erl
index 4b28ac634f..3e00cc7325 100644
--- a/lib/mnesia/test/mnesia_nice_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_nice_coverage_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_qlc_test.erl b/lib/mnesia/test/mnesia_qlc_test.erl
index 9886754710..90fb8540c2 100644
--- a/lib/mnesia/test/mnesia_qlc_test.erl
+++ b/lib/mnesia/test/mnesia_qlc_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_recovery_test.erl b/lib/mnesia/test/mnesia_recovery_test.erl
index 946a9f97ba..e47ed9c6c0 100644
--- a/lib/mnesia/test/mnesia_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_recovery_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_registry_test.erl b/lib/mnesia/test/mnesia_registry_test.erl
index cf8da38632..9d9190d70d 100644
--- a/lib/mnesia/test/mnesia_registry_test.erl
+++ b/lib/mnesia/test/mnesia_registry_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_schema_recovery_test.erl b/lib/mnesia/test/mnesia_schema_recovery_test.erl
index 2301b291c2..05c5639d60 100644
--- a/lib/mnesia/test/mnesia_schema_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_schema_recovery_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 6a51aefdf0..9d3b277e07 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -237,8 +238,8 @@ slave_start_link() ->
slave_start_link(Node) ->
[Local, Host] = node_to_name_and_host(Node),
- {Mega, Sec, Micro} = erlang:now(),
- List = [Local, "_", Mega, "_", Sec, "_", Micro],
+ Count = erlang:unique_integer([positive]),
+ List = [Local, "_", Count],
Name = list_to_atom(lists:concat(List)),
slave_start_link(list_to_atom(Host), Name).
diff --git a/lib/mnesia/test/mnesia_test_lib.hrl b/lib/mnesia/test/mnesia_test_lib.hrl
index cd76377df6..dc3b5b9af8 100644
--- a/lib/mnesia/test/mnesia_test_lib.hrl
+++ b/lib/mnesia/test/mnesia_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/test/mnesia_tpcb.erl b/lib/mnesia/test/mnesia_tpcb.erl
index 595412ff24..c6eda1c448 100644
--- a/lib/mnesia/test/mnesia_tpcb.erl
+++ b/lib/mnesia/test/mnesia_tpcb.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -99,9 +100,13 @@
replica_test/1,
sticky_replica_test/1,
remote_test/1,
- remote_frag2_test/1
+ remote_frag2_test/1,
+
+ conflict_benchmark/1
]).
+-include_lib("common_test/include/ct_event.hrl").
+
-define(SECOND, 1000000).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -159,7 +164,7 @@
-record(history,
{
history_id = {0, 0}, % {DriverId, DriverLocalHistoryid}
- time_stamp = now(), % Time point during active transaction
+ time_stamp = erlang:system_time(), % Time point during active transaction
branch_id = 0, % Branch associated with teller
teller_id = 0, % Teller invlolved in transaction
account_id = 0, % Account updated by transaction
@@ -191,8 +196,10 @@
driver_nodes = [node()],
n_drivers_per_node = 1,
use_running_mnesia = false,
+ seed,
stop_after = timer:minutes(15), % Minimum 15 min
report_interval = timer:minutes(1),
+ send_bench_report = false,
use_sticky_locks = false,
spawn_near_branch = false,
activity_type = transaction,
@@ -397,8 +404,29 @@ config(remote_frag2_test, ReplicaType) ->
{stop_after, timer:minutes(1)},
{report_interval, timer:seconds(10)},
{reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Ten drivers per node, tables replicated to all nodes, single branch
+
+config(conflict_benchmark, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [{db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, 1},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {send_bench_report, true},
+ {reuse_history_id, true}
].
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
start(What, ReplicaType) ->
@@ -422,6 +450,9 @@ remote_test(ReplicaType) ->
remote_frag2_test(ReplicaType) ->
start(remote_frag2_test, ReplicaType).
+conflict_benchmark(ReplicaType) ->
+ start(config(conflict_benchmark, ReplicaType)).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Args is a list of {Key, Val} tuples where Key is a field name
%% in either the record tab_config or run_config. Unknown keys are ignored.
@@ -726,7 +757,7 @@ reporter_init(Starter, RC) ->
replica_type = Type
},
Drivers = start_drivers(RC, TC),
- Now = now_to_micros(erlang:now()),
+ Now = erlang:monotonic_time(),
State = #reporter_state{driver_pids = Drivers,
run_config = RC,
starter_pid = Starter,
@@ -864,8 +895,9 @@ add_time(Acc, New) ->
-define(AVOID_DIV_ZERO(_What_), try (_What_) catch _:_ -> 0 end).
show_report(State) ->
- Now = now_to_micros(erlang:now()),
+ Now = erlang:timestamp(),
Iters = State#reporter_state.n_iters,
+ Cfg = State#reporter_state.run_config,
Time = State#reporter_state.curr,
Max = Time#time.max_time,
N = Time#time.n_trans,
@@ -888,6 +920,16 @@ show_report(State) ->
"duration of longest transaction was ~p milliseconds~n",
[Tps, BruttoTps, Max div 1000])
end,
+ case Cfg#run_config.send_bench_report of
+ true ->
+ ct_event:notify(
+ #event{name = benchmark_data,
+ data = [{suite,"mnesia_tpcb"},
+ {value,Tps}]});
+ _ ->
+ ok
+ end,
+
State#reporter_state{prev_tps = Tps, prev_micros = Now}.
signed_diff(Iters, Curr, Prev) ->
@@ -898,11 +940,6 @@ signed_diff(Iters, Curr, Prev) ->
sign(N) when N > 0 -> {"+", N};
sign(N) -> {"", N}.
-
-now_to_micros({Mega, Secs, Micros}) ->
- DT = calendar:now_to_datetime({Mega, Secs, 0}),
- S = calendar:datetime_to_gregorian_seconds(DT),
- (S * ?SECOND) + Micros.
start_drivers(RC, TC) ->
LastHistoryId = table_info(history, size),
@@ -955,7 +992,11 @@ alloc_local_branches([], Specs, OrphanBranches) ->
{Specs, OrphanBranches}.
driver_init(DS, AllBranches) ->
- Seed = erlang:now(),
+ Seed = case (DS#driver_state.run_config)#run_config.seed of
+ undefined -> rand:seed(exsplus);
+ ExpSeed -> rand:seed(ExpSeed)
+ end,
+
DS2 =
if
DS#driver_state.n_local_branches =:= 0 ->
@@ -1009,14 +1050,7 @@ calc_trans(DS) ->
%% Generate teller_id, account_id and delta
%% Time the TPC-B transaction
time_trans(DS) ->
- OldSeed = get(random_seed), % Avoid interference with Mnesia
- put(random_seed, DS#driver_state.seed),
- Random = random:uniform(),
- NewSeed = get(random_seed),
- case OldSeed of
- undefined -> erase(random_seed);
- _ -> put(random_seed, OldSeed)
- end,
+ {Random, NewSeed} = rand:uniform_s(DS#driver_state.seed),
TC = DS#driver_state.tab_config,
RC = DS#driver_state.run_config,
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
index 237984978e..a371d58e75 100644
--- a/lib/mnesia/test/mnesia_trans_access_test.erl
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -930,20 +931,20 @@ index_update_bag(Config)when is_list(Config) ->
[IPos] = mnesia_lib:val({Tab,index}),
ITab = mnesia_lib:val({index_test,{index, IPos}}),
io:format("~n Index ~p @ ~p => ~p ~n~n",[IPos,ITab, ets:tab2list(ITab)]),
- ?match([{2,1},{2,2},{12,1}], ets:tab2list(ITab)),
+ ?match([{2,1},{2,2},{12,1}], lists:keysort(1,ets:tab2list(ITab))),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec5) end)),
{atomic, R60} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
?match([Rec1,Rec5,Rec2], lists:sort(R60)),
- ?match([{2,1},{2,2},{12,1}], ets:tab2list(ITab)),
+ ?match([{2,1},{2,2},{12,1}], lists:keysort(1,ets:tab2list(ITab))),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec3) end)),
{atomic, R61} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
?match([Rec1,Rec5,Rec2], lists:sort(R61)),
{atomic, R62} = mnesia:transaction(fun() -> mnesia:index_read(Tab,12, ValPos) end),
?match([], lists:sort(R62)),
- ?match([{2,1},{2,2}], ets:tab2list(ITab)),
+ ?match([{2,1},{2,2}], lists:keysort(1,ets:tab2list(ITab))),
%% reset for rest of testcase
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec3) end)),
diff --git a/lib/mnesia/test/mt b/lib/mnesia/test/mt
index 25243f1149..a398ee0422 100755
--- a/lib/mnesia/test/mt
+++ b/lib/mnesia/test/mt
@@ -1,14 +1,15 @@
#! /bin/sh -f
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/mnesia/test/mt.erl b/lib/mnesia/test/mt.erl
index f1152a7bc4..1256dbb80a 100644
--- a/lib/mnesia/test/mt.erl
+++ b/lib/mnesia/test/mt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index b23339e408..194bc439a0 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.12.5
+MNESIA_VSN = 4.13.4
diff --git a/lib/observer/Makefile b/lib/observer/Makefile
index c8d1cd4951..865dddaf51 100644
--- a/lib/observer/Makefile
+++ b/lib/observer/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/observer/doc/src/Makefile b/lib/observer/doc/src/Makefile
index baeeeb1c65..b38278a156 100644
--- a/lib/observer/doc/src/Makefile
+++ b/lib/observer/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/observer/doc/src/book.xml b/lib/observer/doc/src/book.xml
index c47852e697..5ef1fd794b 100644
--- a/lib/observer/doc/src/book.xml
+++ b/lib/observer/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/observer/doc/src/cdv.xml b/lib/observer/doc/src/cdv.xml
index fc8f16bc4e..df1032780a 100644
--- a/lib/observer/doc/src/cdv.xml
+++ b/lib/observer/doc/src/cdv.xml
@@ -4,20 +4,21 @@
<comref>
<header>
<copyright>
- <year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -32,16 +33,16 @@
<file>cdv.xml</file>
</header>
<com>cdv</com>
- <comsummary>Script used for starting the Crashdump Viewer from the
+ <comsummary>Script to start the Crashdump Viewer from the
OS command line.
</comsummary>
<description>
- <p>The <c>cdv</c> shell script can be found under the <c>priv</c>
- directory of the <c>observer</c> application. The script is used
+ <p>The <c>cdv</c> shell script is located in directory <c>priv</c>
+ of the Observer application. The script is used
for starting the Crashdump Viewer tool from the OS command
line.</p>
- <p>For Windows users, <c>cdv.bat</c> can be found in the same
+ <p>For Windows users, <c>cdv.bat</c> is found in the same
location.</p>
</description>
@@ -50,8 +51,8 @@
<name>cdv [file]</name>
<fsummary>Start the Crashdump Viewer and load the given file.</fsummary>
<desc>
- <p>The <c>file</c> arguments is optional. If not given, a file
- dialog will pop up allowing the user to select a crashdump
+ <p>Argument <c>file</c> is optional. If not specified, a file
+ dialog is displayed, allowing you to select a crashdump
from the file system.</p>
</desc>
</func>
diff --git a/lib/observer/doc/src/crashdump.xml b/lib/observer/doc/src/crashdump.xml
index 27e42e83b7..27e88d07e5 100644
--- a/lib/observer/doc/src/crashdump.xml
+++ b/lib/observer/doc/src/crashdump.xml
@@ -9,22 +9,23 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>crashdump_viewer</title>
- <prepared>Siri hansen</prepared>
+ <prepared>Siri Hansen</prepared>
<responsible></responsible>
<docno>1</docno>
<approved></approved>
@@ -40,32 +41,31 @@
<p>The Crashdump Viewer is a WxWidgets based tool for browsing Erlang
crashdumps.</p>
- <p>See the <seealso marker="crashdump_ug">user's guide</seealso>
- for more information about how to get started with the Crashdump
- Viewer.</p>
+ <p>For details about how to get started with the Crashdump Viewer, see the
+ <seealso marker="crashdump_ug"><c>User's Guide</c></seealso>.</p>
</description>
<funcs>
<func>
<name>start() -> ok</name>
<name>start(File) -> ok</name>
- <fsummary>Start the crashdump_viewer</fsummary>
+ <fsummary>Start the Crashdump Viewer.</fsummary>
<type>
<v>File = string()</v>
- <d>The file name of the crashdump.</d>
+ <d>The filename of the crashdump.</d>
</type>
<desc>
- <p>This function starts the <c>crashdump_viewer</c> GUI and
- loads the given crashdump.</p>
+ <p>Starts the Crashdump Viewer GUI and
+ loads the specified crashdump.</p>
- <p>If <c>File</c> is not given, a file dialog will be opened
+ <p>If <c>File</c> is not specified, a file dialog is opened
where the crashdump can be selected.</p>
</desc>
</func>
<func>
<name>stop() -> ok</name>
- <fsummary>Stop the crashdump_viewer</fsummary>
+ <fsummary>Terminate the Crashdump Viewer.</fsummary>
<desc>
- <p>This function stops the <c>crashdump_viewer</c> and closes
+ <p>Terminates the Crashdump Viewer and closes
all GUI windows.</p>
</desc>
</func>
diff --git a/lib/observer/doc/src/crashdump_ug.xml b/lib/observer/doc/src/crashdump_ug.xml
index d22fb4cc40..4ba057c3fb 100644
--- a/lib/observer/doc/src/crashdump_ug.xml
+++ b/lib/observer/doc/src/crashdump_ug.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Crashdump Viewer</title>
@@ -38,360 +39,390 @@
<section>
<title>Getting Started</title>
- <p>The easiest way to start Crashdump Viewer is to use the
- provided shell script named <c>cdv</c> with the full path to the
- erlang crashdump as an argument. The script can be found in the
- priv directory of the <c>observer</c> application. This starts the
- Crashdump Viewer GUI and loads the given file. If no file name is
- given, a file dialog will be opened where the file can be
+ <p>The easiest way to start Crashdump Viewer is to use
+ shell script <c>cdv</c> with the full path to the
+ Erlang crashdump as argument. The script is located in
+ directory <c>priv</c> of the Observer application. This starts the
+ Crashdump Viewer GUI and loads the specified file. If no filename is
+ specified, a file dialog is opened where the file can be
selected.</p>
- <p>Under Windows the batch file <c>cdv.bat</c> can be used.</p>
+ <p>Under Windows, the batch file <c>cdv.bat</c> can be used.</p>
- <p>It is also possible to start the Crashdump Viewer from within
- an erlang node by calling <seealso
+ <p>Crashdump Viewer can also be started from
+ an Erlang node by calling <seealso
marker="crashdump_viewer#start/0">crashdump_viewer:start/0</seealso>
or <seealso
marker="crashdump_viewer#start/1">crashdump_viewer:start/1</seealso>.</p>
</section>
<section>
- <title>The graphical interface</title>
+ <title>GUI</title>
- <p>The main window is opened when Crashdump Viewer has loaded a
- crashdump. It contains a title bar, a menu bar, a number of
- information panels and a status bar.</p>
+ <p>The GUI main window is opened when Crashdump Viewer has loaded a
+ crashdump. It contains a title bar, a menu bar,
+ information tabs, and a status bar.</p>
<p>The title bar shows the name of the currently loaded
crashdump.</p>
<p>The menu bar contains a <em>File</em> menu and a <em>Help</em>
- menu. From the File menu a new crashdump can be loaded or the tool
- can be terminated. From the Help menu this user's guide and the
- chapter "How to interpret the Erlang crash dumps" from the user's
- guide for Erlang runtime system can be opened. "How to interpret
+ menu. From the <em>File</em> menu, a new crashdump can be loaded or
+ the tool can be terminated. From the <em>Help</em> menu, this User's Guide
+ and section "How to interpret the Erlang crash dumps" from the
+ ERTS application can be opened. "How to interpret
the Erlang crash dumps" describes the raw crashdumps in
- detail. Here you will also find information about each single
- field in the different information pages. This document can also
- be found directly in the OTP online documentation, via the Erlang
- runtime system user's guide.</p>
+ detail and includes information about each
+ field in the information pages."How to interpret the Erlang crash dumps"
+ is also available in the OTP online documentation.</p>
- <p>The status bar at the bottom of the window will show a warning
+ <p>The status bar at the bottom of the window shows a warning
if the currently loaded dump is truncated.</p>
- <p>The centre area of the main window contains the information
- panels. Each panel displays information about a specific item or a
- list of items. A panel is selected by clicking the title of the
- tab.</p>
+ <p>The center area of the main window contains the information
+ tabs. Each tab displays information about a specific item or a
+ list of items. Select a tab by clicking the tab title.</p>
- <p>From panels that display lists of items, for example the
- Processes- or the Ports panel, a new window with further
- information can be opened by double clicking a row or by right
- clicking the row and selecting an item from the drop down
+ <p>From tabs displaying lists of items, for example, the
+ <em>Processes</em> tab or the <em>Ports</em> tab, a new window with
+ more information can be opened by double-clicking a row or by right-
+ clicking the row and selecting an item from the drop-down
menu. The new window is called a detail window. Detail windows can
- be opened for processes, ports, nodes and modules.</p>
+ be opened for processes, ports, nodes, and modules.</p>
- <p>The various information shown in a detail window might contain
- links to processes or ports. Clicking one of these links will open
+ <p>The information shown in a detail window can contain
+ links to processes or ports. Clicking one of these links opens
the detail window for the process or port in question. If the
- process or port resided on a remote node, there will be no
- information available. Clicking the link will then pop up a dialog
- where you can choose whether to open the detail window for the
- remote node or not.
+ process or port resides on a remote node, no
+ information is available. Clicking the link then displays a dialog
+ where you can choose to open the detail window for the
+ remote node.
</p>
- <p>Some of the panels contain a left hand menu where sub items of
- the panel's information area can be selected. Click on one of the
- rows, and the information will be displayed in the right hand
+ <p>Some tabs contain a left-hand menu where subitems of
+ the information area can be selected. Click one of the
+ rows, and the information is displayed in the right-hand
information area.</p>
</section>
<section>
- <title>Data content</title>
-
- <p>Each panel in the main window contains an information
- page. If no information is found for an item, the page will be
- empty. The reason for not finding any information about an item
- can be that the dump is truncated, that it is a dump from an old
- OTP release in which this item was not written or that the item
- simply wasn't present in the system at the point of failure.</p>
-
- <p>If the dump was truncated, a warning is displayed in the
- status bar of the main window.</p>
-
- <p>Even if some information about an item exists, there might be
+ <title>Tab Content</title>
+
+ <p>Each tab in the main window contains an information
+ page. If no information is found for an item, the page is
+ empty. The reason for not finding information about an item
+ can be the following:</p>
+ <list type="bulleted">
+ <item>It is a dump from an old OTP release in which this item was not written.</item>
+ <item>The item was not present in the system at the point of failure.</item>
+ <item>The dump is truncated. In this case, a warning is displayed in the
+ status bar of the main window.</item>
+ </list>
+
+ <p></p>
+
+ <p>Even if some information about an item exists, there can be
empty fields if the dump originates from an old OTP release.</p>
- <p>The value "-1" in any field means "unknown", and in most
+ <p>The value <c>-1</c> in any field means "unknown", and in most
cases it means that the dump was truncated somewhere around this
field.</p>
- <p>The sections below describe some of the fields in the
- different information panels. These are fields that do not exist
+ <p>The following sections describe some of the fields in the
+ information tabs. These are fields that do not exist
in the raw crashdump, or in some way differ from the fields in
- the raw crashdump. Details about other fields can be found in
- the user's guide for the Erlang runtime system, in the chapter
- "How to interpret the Erlang crash dumps". That chapter can also
- be opened from the Help menu in the Crashdump Viewer's main
- window, and there are also direct links from the specific
- sections below to related information in "How to interpret the
- Erlang crash dumps".</p>
+ the raw crashdump. For details about other fields, see
+ the
+ <seealso marker="erts:users_guide">ERTS User's Guide</seealso>, section
+ "How to interpret the Erlang crash dumps". That section can also
+ be opened from the <em>Help</em> menu in the main window.
+ There are also links from the following sections to related information
+ in "How to interpret the Erlang crash dumps".</p>
</section>
<section>
<marker id="general_info"/>
- <title>General information</title>
+ <title>General Tab</title>
- <p>The <em>General information</em> panel shows a short overview
+ <p>Tab <em>General</em> shows a short overview
of the dump.</p>
- <p>The following fields are not described in the Erlang runtime
- system user's guide:</p>
+ <p>The following fields are not described in the ERTS
+ User's Guide:</p>
<taglist>
- <tag><em>Crashdump created on</em></tag>
- <item>Time of failure.</item>
-
- <tag><em>Memory allocated</em></tag>
- <item>The total number of bytes allocated, equivalent to
- <c>c:memory(total)</c>.</item>
-
- <tag><em>Memory maximum</em></tag>
- <item>The maximum number of bytes that has been allocated during
- the lifetime of the originating node. This will only be shown if
- the Erlang runtime system was run instrumented.</item>
-
- <tag><em>Atoms</em></tag>
- <item>If available in the dump, this is the total number of
- atoms in the atom table. If the size of the atom table is not
- available, the number of atoms visible in the dump is
- presented.</item>
-
- <tag><em>Processes, ETS tables and Funs</em></tag>
- <item>The number of processes, ETS tables and funs visible in
- the dump.</item>
+ <tag><c>Crashdump created on</c></tag>
+ <item><p>Time of failure.</p></item>
+
+ <tag><c>Memory allocated</c></tag>
+ <item><p>The total number of bytes allocated, equivalent to
+ <c>c:memory(total)</c>.</p></item>
+
+ <tag><c>Memory maximum</c></tag>
+ <item><p>The maximum number of bytes that has been allocated during
+ the lifetime of the originating node. This is only shown if
+ the Erlang runtime system is run instrumented.</p></item>
+
+ <tag><c>Atoms</c></tag>
+ <item><p>If available in the dump, this is the total number of
+ atoms in the atom table. If the size of the atom table is
+ unavailable, the number of atoms visible in the dump is
+ displayed.</p></item>
+
+ <tag><c>Processes</c></tag>
+ <item><p>The number of processes visible in the dump.</p></item>
+
+ <tag><c>ETS tables</c></tag>
+ <item><p>The number of ETS tables visible in the dump.</p></item>
+
+ <tag><c>Funs</c></tag>
+ <item><p>The number of funs visible in the dump.</p></item>
</taglist>
- <p>
- <seealso marker="erts:crash_dump#general_info">More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#general_info">General Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="processes"/>
- <title>Processes</title>
+ <title>Processes Tab</title>
- <p>The <em>Processes</em> panel shows a list of all processes
- found in the crashdump, including some short information about
- each process. By default the processes are sorted by their
- pids. To sort by other topic, click the desired column
- heading.</p>
+ <p>Tab <em>Processes</em> shows a list of all processes
+ found in the crashdump, including brief information about
+ each process. By default, the processes are sorted by their
+ pids. To sort by another topic, click the desired column heading.</p>
- <p>The <em>Memory</em> column shows the 'Memory' field which was
- added to crashdumps in R16B01. This is the total amount of memory
+ <p>Column <em>Memory</em> shows the 'Memory' field that was
+ added to crashdumps in Erlang/OTP R16B01. This is the total amount of memory
used by the process. For crashdumps from earlier releases, this
- column shows the 'Stack+heap' field. The value shown is always in
- bytes.</p>
+ column shows the 'Stack+heap' field. The value is always in bytes.</p>
- <p>To view detailed information about a specific process, double
- click the row in the list or right click the row and select
- "Properties for &lt;pid&gt;".</p>
+ <p>To view detailed information about a specific process, double-
+ click the row in the list, or right-click the row and select
+ <em>Properties for &lt;pid&gt;</em>.</p>
- <p>
- <seealso marker="erts:crash_dump#processes">More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#processes">Process Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="ports"/>
- <title>Ports</title>
+ <title>Ports Tab</title>
- <p>The <em>Ports</em> panel is similar to the <em>Processes</em>
- panel, except it lists all ports found in the crashdump.</p>
+ <p>Tab <em>Ports</em> is similar to the <em>Processes</em>
+ tab, except it lists all ports found in the crashdump.</p>
- <p>To see more details about a specific port, dobule click the row
- or right click it and select "Properties for &lt;port&gt;". From
- the right click menu you can also select "Properties for
- &lt;pid&gt;", where &lt;pid&gt; is the process connected to the
+ <p>To view more details about a specific port, double-click the row
+ or right-click it and select <em>Properties for &lt;port&gt;</em>. From
+ the right-click menu, you can also select <em>Properties for
+ &lt;pid&gt;</em>, where <c>&lt;pid&gt;</c> is the process connected to the
port.</p>
- <p>
- <seealso marker="erts:crash_dump#ports">
- More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#ports">Port Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="ets_tables"/><marker id="internal_ets_tables"/>
- <title>ETS tables</title>
+ <title>ETS Tables Tab</title>
- <p>The <em>ETS Tables</em> panel shows all ETS table information
- found in the dump. The 'Id' is the same as the 'Table' field found
- in the raw crashdump, and 'Memory' is the 'Words' field from the
- raw crashdump translated into bytes. 'Type' is the type of table,
- and it can be either "hash" or "tree". For tree tables there will
- be no value in the 'Bucket' field.</p>
-
- <p>To open the detailed information page about the owner process
- of an ETS table, right click the row and select "Properties for
- &lt;pid&gt;".</p>
+ <p>Tab <em>ETS Tables</em> shows all ETS table information
+ found in the dump. <em>Id</em> is the same as the 'Table' field
+ in the raw crashdump. <em>Memory</em> is the 'Words' field from the
+ raw crashdump translated into bytes. For tree tables, there is
+ no value in the 'Objects' field.</p>
- <p>Double clicking a row in the ETS Tables panel has no
- effect.</p>
+ <p>To open the detailed information page about the table, double-
+ click, or right-click the row and select <em>Properties for
+ 'Identifier'</em>.</p>
- <p>From the left hand menu you can also select to see internal ETS
- tables.</p>
+ <p>To open the detailed information page about the owner process
+ of an ETS table, right-click the row and select <em>Properties for
+ &lt;pid&gt;</em>.</p>
- <p>
- <seealso marker="erts:crash_dump#ets_tables">
- More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#ets_tables">ETS Tables</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="timers"/>
- <title>Timers</title>
+ <title>Timers Tab</title>
- <p>The <em>Timers</em> panel shows all timer information found in
+ <p>Tab <em>Timers</em> shows all timer information found in
the dump.</p>
<p>To open the detailed information page about the owner process
- of a timer, right click the row and select "Properties for
- &lt;pid&gt;".</p>
+ of a timer, right-click the row and select <em>Properties for
+ &lt;pid&gt;</em>.</p>
+
+ <p>Double-clicking a row in the <em>Timers</em> tab has no effect.</p>
+
+ <p>For details, see
+ <seealso marker="erts:crash_dump#timers">Timers</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
+ </p>
+ </section>
- <p>Double clicking a row in the Timers panel has no effect.</p>
+ <section>
+ <marker id="schedulers"/>
+ <title>Schedulers Tab</title>
+
+ <p>Tab <em>Schedulers</em> shows all scheduler information
+ found in the dump.</p>
+
+ <p>To open the detailed information page about the scheduler,
+ double-click, or right-click the row and select <em>Properties for
+ 'Identifier'</em>.</p>
- <p>
- <seealso marker="erts:crash_dump#timers">More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#scheduler">Scheduler Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="funs"/>
- <title>Funs</title>
+ <title>Funs Tab</title>
- <p>The <em>Funs</em> panel shows all Fun information found in the
+ <p>Tab <em>Funs</em> shows all fun information found in the
dump.</p>
<p>To open the detailed information page about the module to which
- the fun belongs, right click the row and select "Properties for
- &lt;mod&gt;".</p>
+ the fun belongs, right-click the row and select <em>Properties for
+ &lt;mod&gt;</em>.</p>
- <p>Double clicking a row in the Funs panel has no effect.</p>
+ <p>Double-clicking a row in the <em>Funs</em> tab has no effect.</p>
- <p>
- <seealso marker="erts:crash_dump#funs">More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#funs">Fun Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="atoms"/>
- <title>Atoms</title>
+ <title>Atoms Tab</title>
- <p>The <em>Atoms</em> panel lists all atoms found in the dump. By
+ <p>Tab <em>Atoms</em> lists all atoms found in the dump. By
default the atoms are sorted in creation order from first to
last. This is opposite of the raw crashdump where atoms are listed
from last to first, meaning that if the dump was truncated in the
- middle of the atom list only the last created atoms will be seen
- in the <em>Atoms</em> panel.</p>
+ middle of the atom list, only the last created atoms are visible
+ in the <em>Atoms</em> tab.</p>
- <p>
- <seealso marker="erts:crash_dump#atoms">More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#atoms">Atoms</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="distribution_info"/>
- <title>Nodes</title>
+ <title>Nodes Tab</title>
- <p>The <em>Nodes</em> panel shows a list of all external erlang
- nodes which are referenced from the crashdump.</p>
+ <p>Tab <em>Nodes</em> shows a list of all external Erlang
+ nodes that are referenced from the crashdump.</p>
- <p>If the page is empty it either means that the crashed node was
- not distributed, that it was distributed but had no references to
- other nodes or that the dump was truncated.</p>
+ <p>If the page is empty, it means either of the following:</p>
+ <list type="bulleted">
+ <item>The crashed node is not distributed.</item>
+ <item>The crashed node is distributed but has no references to other nodes.</item>
+ <item>The dump is truncated.</item>
+ </list>
- <p>If the node was distributed, all referenced nodes are
- shown. The column named <em>Connection type</em> shows if the node
- is visible, hidden or not connected. Visible nodes are alive nodes
+ <p>If the node is distributed, all referenced nodes are
+ visible. Column <em>Connection type</em> shows if the node
+ is visible, hidden, or not connected. Visible nodes are alive nodes
with a living connection to the originating node. Hidden nodes are
- the same as visible nodes, except they are started with the
- <c>-hidden</c> flag. Not connected nodes are nodes that are not
+ the same as visible nodes, except they are started with flag
+ <c>-hidden</c>. Not connected nodes are nodes that are not
connected to the originating node anymore, but references
- (i.e. process or port identifiers) exist.</p>
+ (that is, process or port identifiers) exist.</p>
- <p>To see more detailed information about a node, double click the
- row or right click the row and select "Properties for node
- &lt;node&gt;". From the right click menu you can also select
- "Properties for &lt;port&gt;", to open the detailed information
+ <p>To see more detailed information about a node, double-click the
+ row, or right-click the row and select <em>Properties for node
+ &lt;node&gt;</em>. From the right-click menu, you can also select
+ <em>Properties for &lt;port&gt;</em>, to open the detailed information
window for the controlling port.</p>
- <p>In the detailed information window for a node, any exsisting
+ <p>In the detailed information window for a node, any existing
links and monitors between processes on the originating node and
- the connected node are shown. <em>Extra Info</em> may contain
- debug information (i.e. special information written if the
- emulator is debug compiled) or error information.</p>
+ the connected node are displayed. <em>Extra Info</em> can contain
+ debug information (that is, special information written if the
+ emulator is debug-compiled) or error information.</p>
- <p>
- <seealso marker="erts:crash_dump#distribution_info">
- More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#distribution_info">Distribution Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="loaded_modules"/>
- <title>Loaded modules</title>
+ <title>Modules Tab</title>
- <p>The <em>Modules</em> panel lists all modules that were loaded
- on the originating node, and the current size of the code. If old
- code exsits, the old size is also shown.</p>
+ <p>Tab <em>Modules</em> lists all modules loaded
+ on the originating node, and the current code size. If old
+ code exists, the old size is also shown.</p>
- <p>To see detailed information about a specific module, double
- click the row or right click it and select "Properties for
- &lt;mod&gt;".</p>
+ <p>To view detailed information about a specific module, double-
+ click the row, or right-click it and select <em>Properties for
+ &lt;mod&gt;</em>.</p>
- <p>
- <seealso marker="erts:crash_dump#loaded_modules">
- More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#loaded_modules">Loaded Module Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
<section>
<marker id="memory"/>
- <title>Memory</title>
+ <title>Memory Tab</title>
- <p>The <em>Memory</em> panel shows memory and allocator
- information. From the left hand menu you can select:</p>
+ <p>Tab <em>Memory</em> shows memory and allocator
+ information. From the left-hand menu you can select the following:</p>
- <p>
- <list>
+ <taglist>
+ <tag><em>Memory</em></tag>
+ <item><p>See
+ <seealso marker="erts:crash_dump#memory">Memory Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.</p></item>
- <item><em>Memory</em> <seealso
- marker="erts:crash_dump#memory">More...</seealso></item>
+ <tag><em>Allocator Summary</em></tag>
+ <item><p>This page presents a summary of values from all allocators underneath it.</p></item>
- <item><em>Allocator Summary</em> - this page presents a
- summary of values from all allocators below.</item>
+ <tag><em>&lt;Allocator&gt;</em></tag>
+ <item><p>One entry per allocator. See
+ <seealso marker="erts:crash_dump#allocator">Allocator</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.</p></item>
- <item><em>&lt;Allocator&gt;</em> - one entry per allocator
- <seealso
- marker="erts:crash_dump#allocator">More...</seealso></item>
+ <tag><em>Allocated Areas</em></tag>
+ <item><p>See
+ <seealso marker="erts:crash_dump#allocated_areas">Allocated Areas</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.</p></item>
- <item><em>Allocated Areas</em> <seealso
- marker="erts:crash_dump#allocated_areas">More...</seealso></item>
-
- </list>
- </p>
+ </taglist>
</section>
<section>
<marker id="internal_tables"/>
- <title>Internal tables</title>
+ <title>Internal Tables Tab</title>
- <p>On the <em>Internal Tables</em> panel you can choose from the
- left hand menu to see hash tables or index tables.</p>
+ <p>On tab <em>Internal Tables</em> you can from the
+ left-hand menu select <em>Hash Tables</em>, <em>Index Tables</em>,
+ or <em>Internal ETS Tables</em>.</p>
- <p>
- <seealso marker="erts:crash_dump#internal_tables">More...</seealso>
+ <p>For details, see
+ <seealso marker="erts:crash_dump#internal_tables">Internal Table Information</seealso>
+ in section "How to Interpret the Erlang Crash Dumps" in ERTS.
</p>
</section>
</chapter>
diff --git a/lib/observer/doc/src/etop.xml b/lib/observer/doc/src/etop.xml
index 9f3cdd6de8..52f3b2a156 100644
--- a/lib/observer/doc/src/etop.xml
+++ b/lib/observer/doc/src/etop.xml
@@ -9,22 +9,23 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>etop</title>
- <prepared>Siri hansen</prepared>
+ <prepared>Siri Hansen</prepared>
<responsible></responsible>
<docno></docno>
<approved></approved>
@@ -34,89 +35,79 @@
<file></file>
</header>
<module>etop</module>
- <modulesummary>Erlang Top is a tool for presenting information about erlang processes similar to the information presented by "top" in UNIX.</modulesummary>
+ <modulesummary>Erlang Top is a tool for presenting information about Erlang
+ processes similar to the information presented by "top" in UNIX.</modulesummary>
<description>
- <p><c>etop</c> should be started with the provided scripts
- <c>etop</c>. This will start a hidden erlang node
- which connects to the node to be measured. The measured node is
- given with the <c>-node</c> option. If the measured node has a
+ <p>Start Erlang Top with the provided scripts
+ <c>etop</c>. This starts a hidden Erlang node
+ that connects to the node to be measured. The measured node is
+ specified with option <c>-node</c>. If the measured node has a
different cookie than the default cookie for the user who
- invokes the script, the cookie must be explicitly given witht
- the <c>-setcookie</c> option.</p>
+ invokes the script, the cookie must be explicitly specified with
+ option <c>-setcookie</c>.</p>
- <p>Under Windows the batch file <c>etop.bat</c> can be used.</p>
+ <p>Under Windows, batch file <c>etop.bat</c> can be used.</p>
- <p>The following configuration parameters exist for the
- <c>etop</c> tool. When executing the <c>etop</c> script,
- these parameters can be given as command line options,
- e.g. <c>etop -node testnode@myhost -setcookie MyCookie</c>.</p>
+ <p>When executing the <c>etop</c> script, configuration
+ parameters can be specified as command-line options,
+ for example, <c>etop -node testnode@myhost -setcookie MyCookie</c>.
+ The following configuration parameters exist for the
+ tool:</p>
<taglist>
- <tag>node</tag>
- <item>The measured node.
- <br></br>
-Value: atom()
- <br></br>
-Mandatory</item>
- <tag>setcookie</tag>
- <item>Cookie to use for the etop node - must be the same
- as the cookie on the measured node.
- <br></br>
-Value: atom()</item>
- <tag>lines</tag>
- <item>Number of lines (processes) to display.
- <br></br>
-Value: integer()
- <br></br>
-Default: 10</item>
- <tag>interval</tag>
- <item>The time interval (in seconds) between each update of
- the display.
- <br></br>
-Value: integer()
- <br></br>
-Default: 5</item>
- <tag>accumulate</tag>
- <item>If <c>true</c> the execution time and reductions are
- accumulated.
- <br></br>
-Value: boolean()
- <br></br>
-Default: <c>false</c></item>
- <tag>sort</tag>
- <item>Identifies what information to sort by.
- <br></br>
-Value: <c>runtime | reductions | memory | msg_q</c> <br></br>
-Default: <c>runtime</c> (<c>reductions</c> if
- <c>tracing=off</c>)</item>
- <tag>tracing</tag>
- <item><c>etop</c> uses the erlang trace facility, and thus no
+ <tag><c>node</c></tag>
+ <item><p>The measured node.</p>
+ <p>Value: <c>atom()</c></p>
+ <p>Mandatory</p></item>
+ <tag><c>setcookie</c></tag>
+ <item><p>Cookie to use for the <c>etop</c> node. Must be same as the
+ cookie on the measured node.</p>
+ <p>Value: <c>atom()</c></p></item>
+ <tag><c>lines</c></tag>
+ <item><p>Number of lines (processes) to display.</p>
+ <p>Value: <c>integer()</c></p>
+ <p>Default: <c>10</c></p></item>
+ <tag><c>interval</c></tag>
+ <item><p>Time interval (in seconds) between each update of
+ the display.</p>
+ <p>Value: <c>integer()</c></p>
+ <p>Default: <c>5</c></p></item>
+ <tag><c>accumulate</c></tag>
+ <item><p>If <c>true</c>, the execution time and reductions are
+ accumulated.</p>
+ <p>Value: <c>boolean()</c></p>
+ <p>Default: <c>false</c></p></item>
+ <tag><c>sort</c></tag>
+ <item><p>Identifies what information to sort by.</p>
+ <p>Value: <c>runtime | reductions | memory | msg_q</c></p>
+ <p>Default: <c>runtime</c> (<c>reductions</c> if <c>tracing=off</c>)</p></item>
+ <tag><c>tracing</c></tag>
+ <item><p><c>etop</c> uses the Erlang trace facility, and thus no
other tracing is possible on the measured node while
<c>etop</c> is running, unless this option is set to
<c>off</c>. Also helpful if the <c>etop</c> tracing causes too
high load on the measured node. With tracing off, runtime is
- not measured.
- <br></br>
-Value: <c>on | off</c> <br></br>
-Default: <c>on</c></item>
+ not measured.</p>
+ <p>Value: <c>on | off</c></p>
+ <p>Default: <c>on</c></p></item>
</taglist>
- <p>See the <seealso marker="etop_ug">user's guide</seealso> for
- more information about the <c>etop</c> tool.</p>
+ <p>For detalis about Erlang Top, see the
+ <seealso marker="etop_ug">User's Guide</seealso>.</p>
</description>
<funcs>
<func>
<name>start() -> ok</name>
- <fsummary>Start etop</fsummary>
+ <fsummary>Start etop.</fsummary>
<desc>
- <p>This function starts <c>etop</c>.
- Note that etop is preferably started with the etop script.</p>
+ <p>Starts <c>etop</c>.
+ Notice that <c>etop</c> is preferably started with the <c>etop</c> script.</p>
</desc>
</func>
<func>
<name>start(Options) -> ok</name>
- <fsummary>Start etop</fsummary>
+ <fsummary>Start etop.</fsummary>
<type>
<v>Options = [Option]</v>
<v>Option = {Key, Value}</v>
@@ -124,31 +115,30 @@ Default: <c>on</c></item>
<v>Value = term()</v>
</type>
<desc>
- <p>This function starts <c>etop</c>. Use
- <seealso marker="#help/0">help/0</seealso> to see a
- description of the possible options.</p>
+ <p>Starts <c>etop</c>. To view the possible options, use
+ <seealso marker="#help/0"><c>help/0</c></seealso>.</p>
</desc>
</func>
<func>
<name>help() -> ok</name>
- <fsummary>Print etop's help</fsummary>
+ <fsummary>Display the etop help.</fsummary>
<desc>
- <p>This function prints the help of <c>etop</c> and
+ <p>Displays the help of <c>etop</c> and
its options.</p>
</desc>
</func>
<func>
<name>config(Key,Value) -> Result</name>
- <fsummary>Change tool's configuration</fsummary>
+ <fsummary>Change the configuration of the tool.</fsummary>
<type>
<v>Result = ok | {error,Reason}</v>
<v>Key = lines | interval | accumulate | sort</v>
<v>Value = term()</v>
</type>
<desc>
- <p>This function is used to change the tool's configuration
- parameters during runtime. The table above indicates the
- allowed values for each parameter.</p>
+ <p>Changes the configuration parameters of the tool during runtime.
+ Allowed parameters are <c>lines</c>, <c>interval</c>, <c>accumulate</c>,
+ and <c>sort</c>.</p>
</desc>
</func>
<func>
@@ -159,14 +149,14 @@ Default: <c>on</c></item>
<v>File = string()</v>
</type>
<desc>
- <p>This function dumps the current display to a text file.</p>
+ <p>Dumps the current display to a text file.</p>
</desc>
</func>
<func>
<name>stop() -> stop</name>
- <fsummary>Terminate etop</fsummary>
+ <fsummary>Terminate etop.</fsummary>
<desc>
- <p>This function terminates <c>etop</c>.</p>
+ <p>Terminates <c>etop</c>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/observer/doc/src/etop_ug.xml b/lib/observer/doc/src/etop_ug.xml
index c57df1d324..d663b089c2 100644
--- a/lib/observer/doc/src/etop_ug.xml
+++ b/lib/observer/doc/src/etop_ug.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2013</year>
+ <year>2002</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,15 +32,25 @@
<section>
<title>Introduction</title>
- <p>Erlang Top, <c>etop</c> is a tool for presenting information
- about erlang processes similar to the information presented by
+ <p>Erlang Top, <c>etop</c>, is a tool for presenting information
+ about Erlang processes similar to the information presented by
<c>top</c> in UNIX.
</p>
</section>
+ <section>
+ <title>Getting Started</title>
+ <p>Start Erlang Top in either of the following ways:</p>
+ <list type="bulleted">
+ <item>Use script <c>etop</c>.</item>
+ <item>Use batch file <c>etop.bat</c>, for example,
+ <c>etop -node tiger@durin</c>.</item>
+ </list>
+ </section>
+
<section>
<title>Output</title>
- <p>The output from <c>etop</c> looks like this:</p>
+ <p>The output from Erlang Top is as follows:</p>
<code type="none"><![CDATA[
========================================================================================
tiger@durin 13:40:32
@@ -64,59 +75,60 @@ Pid Name or Initial Func Time Reds Memory MsgQ Current Func
<p>The header includes some system information:
</p>
<taglist>
- <tag>Load</tag>
- <item><c>cpu</c> is <c>Runtime/Wallclock</c>, i.e. the
- percentage of time where the node has been
- active, <c>procs</c> is the number of processes on the node,
- and <c>runq</c> is the number of processes that are ready to
- run.</item>
- <tag>Memory</tag>
- <item>This is the memory allocated by the node in kilo bytes.</item>
+ <tag><c>Load</c></tag>
+ <item>
+ <taglist>
+ <tag><c>cpu</c></tag>
+ <item><p><c>Runtime/Wallclock</c>, that is, the percentage of time
+ where the node has been active.</p></item>
+ <tag><c>procs</c></tag>
+ <item><p>The number of processes on the node.</p></item>
+ <tag><c>runq</c></tag>
+ <item><p>The number of processes that are ready to run.</p></item>
+ </taglist>
+ </item>
+ <tag><c>Memory</c></tag>
+ <item><p>The memory allocated by the node in kilobytes.</p></item>
</taglist>
<p>For each process the following information is presented:
</p>
<taglist>
- <tag>Time</tag>
- <item>This is the runtime for the process, i.e. the actual
- time the process has been scheduled in.</item>
- <tag>Reds</tag>
- <item>This is the number of reductions that has been executed
- on the process</item>
- <tag>Memory</tag>
- <item>This is the size of the process in bytes, obtained by a
- call to <c>process_info(Pid,memory)</c>.</item>
- <tag>MsgQ</tag>
- <item>This is the length of the message queue for the process.</item>
+ <tag><c>Time</c></tag>
+ <item><p>The runtime for the process, that is, the time that the process
+ has been scheduled in.</p></item>
+ <tag><c>Reds</c></tag>
+ <item><p>The number of reductions executed on the process.</p></item>
+ <tag><c>Memory</c></tag>
+ <item><p>The size of the process in bytes, obtained by a
+ call to <c>process_info(Pid,memory)</c>.</p></item>
+ <tag><c>MsgQ</c></tag>
+ <item><p>The length of the message queue for the process.</p></item>
</taglist>
<note>
<p><em>Time</em> and <em>Reds</em> can be presented as
- accumulated values or as values since last update.</p>
+ accumulated values or as values since the last update.</p>
</note>
</section>
- <section>
- <title>Start</title>
- <p>To start etop use the script
- <c>etop</c> or the batch file <c>etop.bat</c>, e.g. <c>etop -node tiger@durin</c>,
- </p>
- </section>
-
- <section>
+ <section>
<title>Configuration</title>
<p>All configuration parameters can be set at start by adding
- <c>-OptName Value</c> to the command line, e.g. <c>etop -node tiger@durin -setcookie mycookie -lines 15</c>.
- </p>
- <p>The parameters <c>lines</c>, <c>interval</c>, <c>accumulate</c>
- and <c>sort</c> can be changed during runtime by the
- function <c>etop:config/2</c>.
- </p>
- <p>A list of all valid configuration parameters can be found in
- the reference manual for <c>etop</c>.
+ <c>-OptName Value</c> to the command line, for example:</p>
+ <pre>
+% <input>etop -node tiger@durin -setcookie mycookie -lines 15</input></pre>
+
+ <p>A list of all valid Erlang Top configuration parameters is available in
+ module <seealso marker="etop"><c>etop</c></seealso>.
</p>
- <section>
- <title>Example: Change configuration with text based presentation</title>
- <code type="none"><![CDATA[
+ <p>The parameters <c>lines</c>, <c>interval</c>, <c>accumulate</c>,
+ and <c>sort</c> can be changed during runtime with function
+ <seealso marker="etop#config/2"><c>etop:config/2</c></seealso>.
+ </p>
+ <p><em>Example:</em></p>
+ <p>Change configuration parameter <c>lines</c> with text-based presentation.
+ Before the change, 10 lines are presented as follows:</p>
+ <code type="none"><![CDATA[
========================================================================================
tiger@durin 10:12:39
Load: cpu 0 Memory: total 1858 binary 33
@@ -136,8 +148,14 @@ Pid Name or Initial Func Time Reds Memory MsgQ Current Func
<127.43.0> ddll_server 0 582 3744 0 gen_server:loop/6
<127.5.0> application_controll 0 569 6756 0 gen_server:loop/6
======================================================================================== ]]></code>
- <p><em><c>etop:config(lines,5).</c></em> <br></br>
-<em><c>ok</c></em></p>
+ <p>Function <c>etop:config/2</c> is called to change the number of showed
+ lines to 5:</p>
+
+ <pre>
+> <input>etop:config(lines,5).</input>
+ok</pre>
+
+ <p>After the change, 5 lines are presented as follows:</p>
<code type="none"><![CDATA[
(etop@durin)2>
========================================================================================
@@ -155,19 +173,20 @@ Pid Name or Initial Func Time Reds Memory MsgQ Current Func
<127.43.0> ddll_server 0 0 3744 0 gen_server:loop/6
========================================================================================
]]></code>
- </section>
</section>
<section>
- <title>Print to file</title>
- <p>At any time, the current <c>etop</c> display can be dumped to a
- text file with the function <c>etop:dump/1</c>.
+ <title>Print to File</title>
+ <p>At any time, the current Erlang Top display can be dumped to a
+ text file with function
+ <seealso marker="etop#dump/1"><c>etop:dump/1</c></seealso>.
</p>
</section>
<section>
<title>Stop</title>
- <p>Use the function <c>etop:stop/0</c> to stop <c>etop</c>.
+ <p>To stop Erlang Top, use function
+ <seealso marker="etop#stop/0"><c>etop:stop/0</c></seealso>.
</p>
</section>
</chapter>
diff --git a/lib/observer/doc/src/introduction_ug.xml b/lib/observer/doc/src/introduction_ug.xml
new file mode 100644
index 0000000000..21f0dc709f
--- /dev/null
+++ b/lib/observer/doc/src/introduction_ug.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2016</year><year>2016</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>Introduction</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>introduction_ug.xml</file>
+ </header>
+<section>
+ <title>Scope</title>
+ <p>The Observer application is a container including the following
+ tools for tracing and investigation of distributed systems:</p>
+ <list type="bulleted">
+ <item>Observer</item>
+ <item>Trace Tool Builder</item>
+ <item>Erlang Top</item>
+ <item>Crashdump Viewer</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language.</p>
+ </section>
+</chapter>
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index a9ec68fc9e..dd99f45b19 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,98 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 2.1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Documentation corrections.</p>
+ <p>
+ Own Id: OTP-12994</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Show ets owner pid in crashdump viewers popup window,
+ thanks Leo Liu.</p>
+ <p>
+ Own Id: OTP-13030</p>
+ </item>
+ <item>
+ <p>
+ Several initialisms (eg, ERTS, ETS, SMP) are used as
+ headings. They were being capitalized incorrectly.</p>
+ <p>
+ Own Id: OTP-13044</p>
+ </item>
+ <item>
+ <p>
+ Fixed a crash in crashdump viewer when dump contained a
+ truncated binary.</p>
+ <p>
+ Own Id: OTP-13163</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Show run queue status in crashdump viewer.</p>
+ <p>
+ Own Id: OTP-12401</p>
+ </item>
+ <item>
+ <p>
+ Don't refresh observer table view if there was no change</p>
+ <p>
+ Own Id: OTP-12819</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added display of new crashdump information available in
+ crashdumps from Erlang/OTP 18.</p>
+ <p>
+ Own Id: OTP-12363</p>
+ </item>
+ <item>
+ <p>
+ Added the possibility to view sasl log entries for
+ processes.</p>
+ <p>
+ Own Id: OTP-12504</p>
+ </item>
+ <item>
+ <p>
+ Add memory allocator usage and utilization graphs.</p>
+ <p>
+ Own Id: OTP-12631</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Observer 2.0.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -225,13 +318,12 @@
<section><title>Improvements and New Features</title>
<list>
<item>
- <p>
<list> <item> The new Memory field from a crash dump is
now presented by crashdump viewer, both in the process
overview and in the process detail page. </item> <item> A
summary of blocks- and carriers sizes is added to the
allocator information page in the crashdump viewer.
- </item> </list></p>
+ </item> </list>
<p>
Own Id: OTP-10604 Aux Id: kunagi-336 [247] </p>
</item>
@@ -360,7 +452,6 @@
<item>
<p>
The following bugs in <c>ttb</c> have been corrected:</p>
- <p>
<list> <item><c>ttb:tracer/2</c> would earlier crash when
trying to set up tracing for a diskless node to wrap
files, i.e. when option
@@ -373,7 +464,7 @@
<c>{file,{local,Filename}}</c></item> <item>A deadlock
would sometimes occur due to an information printout from
the <c>ttb_control</c> process when <c>ttb</c> was
- stopped.</item> </list></p>
+ stopped.</item> </list>
<p>
Own Id: OTP-9431</p>
</item>
@@ -401,7 +492,6 @@
<item>
<p>
The following new features are added to <c>ttb</c>:</p>
- <p>
<list> <item>A one-command trace setup is added,
<c>ttb:start_trace/4</c>.</item> <item>The following new
options are added to <c>ttb:tracer/2</c>: <list>
@@ -437,7 +527,7 @@
<c>disable_sort</c> is added to <c>ttb:format/2</c>. When
this option is used, trace messages from different logs
are not merged according to timestamps, but just appended
- one log after the other. </item> </list></p>
+ one log after the other. </item> </list>
<p>
Own Id: OTP-9403</p>
</item>
@@ -445,7 +535,6 @@
<p>
The following non backwards compatible changes are done
in <c>ttb</c>:</p>
- <p>
<list> <item> When setting up trace with ttb, the
'timestamp' trace flag will now always be set. </item>
<item> The 'fetch' option to ttb:stop/1 is removed since
@@ -461,7 +550,7 @@
trace file, this is now changed so the handler state is
passed not only from one trace message to the next in the
same file, but also from one file to the next. </item>
- </list></p>
+ </list>
<p>
*** POTENTIAL INCOMPATIBILITY ***</p>
<p>
diff --git a/lib/observer/doc/src/notes_history.xml b/lib/observer/doc/src/notes_history.xml
index 55e965022c..ec155b852f 100644
--- a/lib/observer/doc/src/notes_history.xml
+++ b/lib/observer/doc/src/notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/observer/doc/src/observer.xml b/lib/observer/doc/src/observer.xml
index 315301e2c8..4d43ffe39f 100644
--- a/lib/observer/doc/src/observer.xml
+++ b/lib/observer/doc/src/observer.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2011</year><year>2013</year>
+ <year>2011</year><year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -33,24 +34,25 @@
<file>observer.xml</file>
</header>
<module>observer</module>
- <modulesummary>A GUI tool for observing an erlang system.</modulesummary>
+ <modulesummary>A GUI tool for observing an Erlang system.</modulesummary>
<description>
- <p>The observer is gui frontend containing various tools to
- inspect a system. It displays system information, application
- structures, process information, ets or mnesia tables and a frontend
- for tracing with <seealso marker="ttb">ttb</seealso>.
+ <p>Observer is a graphical tool for observing the characteristics of
+ Erlang systems. The tool Observer displays system information, application
+ supervisor trees, process information, ETS tables, Mnesia tables,
+ and contains a front end for Erlang tracing with module
+ <seealso marker="ttb"><c>ttb</c></seealso>.
</p>
- <p>See the <seealso marker="observer_ug">user's guide</seealso>
- for more information about how to get started.</p>
+ <p>For detalis about how to get started, see the
+ <seealso marker="observer_ug"><c>User's Guide</c></seealso>.</p>
</description>
<funcs>
<func>
<name>start() -> ok</name>
- <fsummary>Start the observer gui</fsummary>
+ <fsummary>Start the Observer GUI.</fsummary>
<desc>
- <p>This function starts the <c>observer</c> gui.
- Close the window to stop the application.
+ <p>Starts the Observer GUI.
+ To stop the tool, close the window.
</p>
</desc>
</func>
diff --git a/lib/observer/doc/src/observer_app.xml b/lib/observer/doc/src/observer_app.xml
index e4790ce98c..a52d6cb4d9 100644
--- a/lib/observer/doc/src/observer_app.xml
+++ b/lib/observer/doc/src/observer_app.xml
@@ -4,26 +4,26 @@
<appref>
<header>
<copyright>
- <year>2002</year>
- <year>2013</year>
+ <year>2002</year><year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>observer</title>
+ <title>Observer</title>
<prepared>Siri Hansen</prepared>
<responsible>Siri Hansen</responsible>
<docno></docno>
@@ -31,26 +31,21 @@
<checked></checked>
<date>2002-04-08</date>
<rev>PA1</rev>
- <file>observer_app.sgml</file>
+ <file>observer_app.xml</file>
</header>
- <app>observer</app>
+ <app>Observer</app>
<appsummary>The Observer Application</appsummary>
<description>
- <p>This chapter describes the <em>OBSERVER</em> application in
- OTP, which provides tools for tracing and investigation of
- distributed systems.</p>
+ <p>The Observer application contains tools for tracing and
+ investigation of distributed systems.</p>
</description>
<section>
<title>Configuration</title>
- <p>There are currently no configuration parameters available for
+ <p>No configuration parameters are available for
this application.
</p>
</section>
- <section>
- <title>SEE ALSO</title>
- <p></p>
- </section>
</appref>
diff --git a/lib/observer/doc/src/observer_ug.xml b/lib/observer/doc/src/observer_ug.xml
index 62f99c5210..ca354df864 100644
--- a/lib/observer/doc/src/observer_ug.xml
+++ b/lib/observer/doc/src/observer_ug.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2011</year><year>2014</year>
+ <year>2011</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,157 +32,253 @@
<section>
<title>Introduction</title>
- <p>Observer, is a graphical tool for observing the characteristics of
- erlang systems. Observer displays system information, application
- supervisor trees, process information, ets or mnesia tables and contains
- a frontend for erlang tracing.
+ <p>Observer is a graphical tool for observing the characteristics of
+ Erlang systems. Observer displays system information, application
+ supervisor trees, process information, ETS tables, Mnesia tables
+ and contains a front end for Erlang tracing.
</p>
</section>
<section>
- <title>General</title>
- <p>Normally observer should be run from a standalone node to minimize
- the impact of the system being observed. Example:
+ <title>Getting Started</title>
+ <p>Run Observer from a standalone node to minimize the impact of the
+ system being observed.
</p>
- <code>
- > erl -sname observer -hidden -setcookie MyCookie -run observer
- </code>
+ <p><em>Example:</em></p>
+ <pre>
+% <input>erl -sname observer -hidden -setcookie MyCookie -run observer</input></pre>
<p>
- Choose which node to observe via <c>Nodes</c> menu. The <c>View/Refresh
- Interval</c> controls how frequent the view should be updated.
+ Select the node to observe with menu <em>Nodes</em>.
+ Menu <em>View &gt; Refresh interval</em> controls how often
+ the view is to be updated.
The refresh interval is set per viewer so you can
have different settings for each viewer. To minimize the system
- impact only the active viewer is updated and the other
- views will be updated when activated.
+ impact, only the active viewer is updated. Other views are updated
+ when activated.
</p>
- <p> In general the mouse buttons behaves as expected, use left click
- to select objects, right click to pop up a menu with most used
- choices and double click to bring up information about the
- selected object. In most viewers with several columns you can change
- sort order by left clicking on column header.
+ <p>The mouse buttons behave as expected. Use left-click
+ to select objects, right-click to get a menu with the most used
+ options, and double-click to display information about the
+ selected object. In most viewers with many columns, you can change
+ the sort order by left-clicking the column header.
</p>
</section>
<section>
- <title>Applications</title>
- <p>The <c>Applications</c> view lists application information.
+ <title>System Tab</title>
+ <p>Tab <em>System</em> displays general information about the active Erlang node
+ and its runtime system, such as build configuration, system capabilities, and
+ overall use statistics.
+</p>
+ </section>
+
+ <section>
+ <title>Load Charts Tab</title>
+ <p>Tab <em>Load Charts</em> displays graphs of the current resource use on
+ the active Erlang node.</p>
+ <p>Graph <c>Scheduler Utilization</c> shows scheduler use per scheduler,
+ where each scheduler use has a unique color.</p>
+ <p>Graph <c>Memory Usage</c> shows the total memory use and per memory category
+ use, where each category has a unique color. The categories are as
+ follows:</p>
+ <taglist>
+ <tag><c>Total</c></tag>
+ <item><p>The sum of all memory categories.</p></item>
+ <tag><c>Processes</c></tag>
+ <item><p>The sum of all process memory used.</p></item>
+ <tag><c>Atom</c></tag>
+ <item><p>The size used by the atom table.</p></item>
+ <tag><c>Binary</c></tag>
+ <item><p>The sum of all off-heap binaries allocated.</p></item>
+ <tag><c>Code</c></tag>
+ <item><p>The memory allocated for code storage.</p></item>
+ <tag><c>Ets</c></tag>
+ <item><p>The used memory for all ETS tables.</p></item>
+ </taglist>
+
+ <p>Graph <c>IO Usage</c> shows the current I/O load on the system.</p>
+ </section>
+
+ <section>
+ <title>Memory Allocators Tab</title>
+ <p>Tab <em>Memory Allocators</em> displays detailed information of the carrier
+ size and current memory carriers. For details about memory carriers,
+ see module
+ <seealso marker="erts:erts_alloc"><c>erts_alloc</c></seealso>
+ in application ERTS.</p>
+ </section>
+
+ <section>
+ <title>Applications Tab</title>
+ <p>Tab <em>Applications</em> presents application information.
Select an application in the left list to display its supervisor
- tree.
- </p>
- <p><c>Trace process</c> will add the selected process identifier
- to <c>Trace Overview</c> view and the node the process resides on
- will be added as well.
- </p>
- <p><c>Trace named process</c> will add the
- registered name of the process. This can be useful when tracing on
- several nodes, then processes with that name will be traced on all traced
- nodes.
- </p>
- <p><c>Trace process tree</c> and <c>Trace named process
- tree</c> will add the selected process and all processes below,
- right of, it to the <c>Trace Overview</c> view.
+ tree. The right-click options in the tree are as follows:
</p>
+ <taglist>
+ <tag>Process info</tag>
+ <item><p>Opens a detailed information window on the selected process,
+ including the following:</p>
+ <taglist>
+ <tag>Process Information</tag>
+ <item><p>Shows the process information.</p></item>
+ <tag>Messages</tag>
+ <item><p>Shows the process messages.</p></item>
+ <tag>Dictionary</tag>
+ <item><p>Shows the process dictionary.</p></item>
+ <tag>Stack Trace</tag>
+ <item><p>Shows the process current stack trace.</p></item>
+ <tag>State</tag>
+ <item><p>Shows the process state.</p></item>
+ <tag>Log</tag>
+ <item><p>If enabled and available, shows the process SASL
+ log entries.</p></item>
+ </taglist>
+ </item>
+ <tag>Trace process</tag>
+ <item><p>Adds the selected process identifier to tab <em>Trace Overview</em>
+ plus the node that the process resides on.</p></item>
+ <tag>Trace named process</tag>
+ <item><p>Adds the registered name of the process. This can be useful when tracing on
+ many nodes, as processes with that name are then traced on all traced nodes.</p></item>
+ <tag>Trace process tree</tag>
+ <item><p>Adds the selected process and all processes below,
+ right of it, to tab <em>Trace Overview</em>.</p></item>
+ <tag>Trace named process tree</tag>
+ <item><p>Adds the selected process and all processes below,
+ right of it, to tab <em>Trace Overview</em>.</p></item>
+ </taglist>
</section>
<section>
- <title>Processes</title>
- <p>The <c>Processes</c> view lists process information.
- For each process the following information is presented:
+ <title>Processes Tab</title>
+ <p>Tab <em>Processes</em> lists process information in columns.
+ For each process the following information is displayed:
</p>
<taglist>
<tag>Pid</tag>
- <item>The process identifier.</item>
+ <item><p>The process identifier.</p></item>
<tag>Reds</tag>
- <item>This is the number of reductions that has been executed
- on the process</item>
+ <item><p>The number of reductions executed on the process.
+ This can be presented as accumulated values or as values since the last update.</p></item>
<tag>Memory</tag>
- <item>This is the size of the process in bytes, obtained by a
- call to <c>process_info(Pid,memory)</c>.</item>
+ <item><p>The size of the process, in bytes, obtained by a
+ call to <c>process_info(Pid,memory)</c>.</p></item>
<tag>MsgQ</tag>
- <item>This is the length of the message queue for the process.</item>
+ <item><p>The length of the message queue for the process.</p></item>
</taglist>
+
+ <p>Option <em>Process info</em> opens a detailed information window on the selected process,
+ including the following:</p>
+ <taglist>
+ <tag>Process Information</tag>
+ <item><p>Shows the process information.</p></item>
+ <tag>Messages</tag>
+ <item><p>Shows the process messages.</p></item>
+ <tag>Dictionary</tag>
+ <item><p>Shows the process dictionary.</p></item>
+ <tag>Stack Trace</tag>
+ <item><p>Shows the process current stack trace.</p></item>
+ <tag>State</tag>
+ <item><p>Shows the process state.</p></item>
+ <tag>Log</tag>
+ <item><p>If enabled and available, shows the process SASL log entries.</p></item>
+ </taglist>
+
<note>
- <p><em>Reds</em> can be presented as accumulated values or as values since last update.</p>
+ <p><em>Log</em> requires application SASL to be started on the observed node,
+ with <c>log_mf_h</c> as log handler.
+ The Observed node must be Erlang/OTP R16B02 or higher.
+ The <c>rb</c> server must not be started on the observed node when clicking menu
+ <em>Log &gt; Toggle log view</em>. The <c>rb</c> server is stopped on the observed node
+ when exiting or changing the observed node.
+ </p>
</note>
- <p><c>Trace Processes</c> will add the selected process identifiers to the <c>Trace Overview</c> view and the
- node the processes reside on will be added as well.
- <c>Trace Named Processes</c> will add the registered name of processes. This can be useful
- when tracing is done on several nodes, then processes with that name will be traced on all traced nodes.
+
+ <p>Option <em>Trace Processes</em> adds the selected process identifiers to tab
+ <em>Trace Overview</em> plus the node that the processes reside on.
</p>
+ <p>Option <em>Trace Named Processes</em> adds the registered name of the processes. This can be
+ useful when tracing is done on many nodes, as processes with that name are then traced on
+ all traced nodes.</p>
+
</section>
<section>
- <title>Table Viewer</title>
- <p>The <c>Table Viewer</c> view lists tables. By default ets tables
- are visible and unreadable, private ets, tables and tables created by the OTP
- applications are not visible. Use <c>View</c> menu to view "system"
- ets tables, unreadable ets tables or mnesia tables.
- </p>
- <p>Double click to view the content of the table. Select table and activate <c>View/Table Information</c>
- menu to view table information.
+ <title>Table Viewer Tab</title>
+ <p>Tab <em>Table Viewer</em> lists tables. By default, ETS tables
+ are displayed whereas unreadable private ETS tables and tables created by OTP
+ applications are not diplayed. Use menu <em>View</em> to view "system"
+ ETS tables, unreadable ETS tables, or Mnesia tables.
</p>
- <p>In the table viewer you can regexp search for objects, edit and delete objects.
+ <p>Double-click to view the table content. To view table information, select the table
+ and activate menu <em>View &gt; Table information</em>.</p>
+ <p>You can use <seealso marker="stdlib:re">regular
+ expressions</seealso> and search for objects, and edit or delete them.
</p>
</section>
<section>
- <title>Trace Overview</title>
- <p>The <c>Trace Overview</c> view handles tracing. Tracing is done
- by selecting which processes to be traced and how to trace
- them. You can trace messages, function calls and events, where
- events are process related events such as <c>spawn</c>,
- <c>exit</c> and several others.
- </p>
-
- <p>When you want to trace function calls, you also need to setup
- <c>trace patterns</c>. Trace patterns selects the function calls
- that will be traced. The number of traced function calls can be
- further reduced with <c>match specifications</c>. Match
- specifications can also be used to trigger additional information
+ <title>Trace Overview Tab</title>
+ <p>Tab <em>Trace Overview</em> handles tracing. Trace
+ by selecting the processes to be traced and how to trace
+ them. You can trace messages, function calls, and events, where
+ events are process-related events such as <c>spawn</c>,
+ <c>exit</c>, and many others.
+ </p>
+
+ <p>To trace function calls, you also need to set up
+ <em>trace patterns</em>. Trace patterns select the function calls
+ to be traced. The number of traced function calls can be
+ further reduced with <em>match specifications</em>. Match
+ specifications can also be used to trigger more information
in the trace messages.
</p>
- <note><p>Trace patterns only applies to the traced processes.</p></note>
+ <note><p>Trace patterns only apply to the traced processes.</p></note>
<p>
- Processes are added from the <c>Applications</c> or <c>Processes</c> views.
- A special <c>new</c> identifier, meaning all processes spawned after trace start,
- can be added with the <c>Add 'new' Process</c> button.
+ Processes are added from the <em>Applications</em> or <em>Processes</em> tabs.
+ A special <em>new</em> identifier, meaning all processes spawned after trace
+ start, can be added with button <em>Add 'new' Process</em>.
</p>
<p>
- When adding processes, a window with trace options will pop up. The chosen options will
- be set for the selected processes.
- Process options can be changed by right clicking on a process.
+ When adding processes, a window with trace options is displayed. The chosen
+ options are set for the selected processes.
+ Process options can be changed by right-clicking a process.
</p>
<p>
- Processes added by process identifiers will add the nodes these
- processes resides on in the node list. Additional nodes can be added by the <c>Add
- Nodes</c> button.
+ Processes added by process identifiers add the nodes these
+ processes reside on in the node list. More nodes can be added by clicking
+ button <em>Add Nodes</em>.
</p>
<p>
- If function calls are traced, trace patterns must be added by <c>Add Trace Pattern</c> button.
- Select a module, function(s) and a match specification.
- If no functions are selected, all functions in the module will be traced.
+ If function calls are traced, trace patterns must be added by clicking button
+ <em>Add Trace Pattern</em>. Select a module, function(s), and a match specification.
+ If no functions are selected, all functions in the module are traced.
A few basic match specifications are provided in the tool, and
you can provide your own match specifications. The syntax of match
- specifications are described in the <seealso
- marker="erts:match_spec">ERTS User's Guide</seealso>. To simplify
- the writing of a match specification they can also be written as
- <c>fun/1</c> see <seealso marker="stdlib:ms_transform">ms_transform manual page</seealso> for
- further information.
- </p>
-
- <p>Use the <c>Start trace</c> button to start the trace.
- By default trace output is written to a new window, tracing is stopped when the
- window is closed, or with <c>Stop Trace</c> button.
- Trace output can be changed via <c>Options/Output</c> menu.
- The trace settings, including match specifications, can be saved to, or loaded from, a file.
- </p>
- <p>More information about tracing can be found in <seealso
- marker="runtime_tools:dbg">dbg</seealso> and in the chapter "Match
- specifications in Erlang" in <seealso marker="erts:match_spec">ERTS User's
- Guide</seealso> and the
- <seealso marker="stdlib:ms_transform">ms_transform manual page</seealso>.
+ specifications is described in the <seealso
+ marker="erts:match_spec"><c>ERTS User's Guide</c></seealso>. To simplify
+ the writing of a match specification, they can also be written as
+ <c>fun/1</c>. For details, see module
+ <seealso marker="stdlib:ms_transform">ms_transform</seealso>
+ in application STDLIB.
+ </p>
+
+ <p>Click button <em>Start Trace</em> to start the trace.
+ By default, trace output is written to a new window. Tracing is stopped
+ when the window is closed, or when clicking button <em>Stop Trace</em>.
+ Trace output can be changed with menu <em>Options > Output</em>.
+ The trace settings, including match specifications, can be saved to,
+ or loaded from, a file.
+ </p>
+ <p>For details about tracing, see module <seealso
+ marker="runtime_tools:dbg">dbg</seealso> in application Runtime_Tools
+ and in section "Match specifications in Erlang" in
+ <seealso marker="erts:match_spec"><c>ERTS User's Guide</c></seealso>
+ and in module
+ <seealso marker="stdlib:ms_transform"><c>ms_transform</c></seealso>
+ in application STDLIB.
</p>
</section>
</chapter>
diff --git a/lib/observer/doc/src/part.xml b/lib/observer/doc/src/part.xml
index c05f9bdf9c..d8ec7664d9 100644
--- a/lib/observer/doc/src/part.xml
+++ b/lib/observer/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,9 +29,8 @@
<rev></rev>
</header>
<description>
- <p>The <em>Observer</em> application contains tools for tracing
- and investigation of distributed systems.</p>
</description>
+ <xi:include href="introduction_ug.xml"/>
<xi:include href="observer_ug.xml"/>
<xi:include href="ttb_ug.xml"/>
<xi:include href="etop_ug.xml"/>
diff --git a/lib/observer/doc/src/part_notes.xml b/lib/observer/doc/src/part_notes.xml
index a900779e2f..c187702f64 100644
--- a/lib/observer/doc/src/part_notes.xml
+++ b/lib/observer/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/observer/doc/src/part_notes_history.xml b/lib/observer/doc/src/part_notes_history.xml
index 8f13861bb9..c0c7b10a7e 100644
--- a/lib/observer/doc/src/part_notes_history.xml
+++ b/lib/observer/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/observer/doc/src/ref_man.xml b/lib/observer/doc/src/ref_man.xml
index c3805b2d86..37e20b2643 100644
--- a/lib/observer/doc/src/ref_man.xml
+++ b/lib/observer/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,10 +30,7 @@
<file>application.sgml</file>
</header>
<description>
- <p>The <em>Observer</em> application contains tools for tracing
- and investigation of distributed systems.</p>
- <br></br>
- </description>
+ </description>
<xi:include href="observer_app.xml"/>
<xi:include href="observer.xml"/>
<xi:include href="ttb.xml"/>
diff --git a/lib/observer/doc/src/ttb.xml b/lib/observer/doc/src/ttb.xml
index 6e60a9cb3b..2b637551db 100644
--- a/lib/observer/doc/src/ttb.xml
+++ b/lib/observer/doc/src/ttb.xml
@@ -4,48 +4,48 @@
<erlref>
<header>
<copyright>
- <year>2002</year>
- <year>2013</year>
+ <year>2002</year><year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ttb</title>
- <prepared>Siri hansen</prepared>
- <prepared>Bartlomiej Puzon</prepared>
+ <prepared>Siri Hansen, Bartlomiej Puzon</prepared>
<responsible></responsible>
<docno>1</docno>
<approved></approved>
<checked></checked>
<date>2010-08-13</date>
<rev>PA1</rev>
- <file>ttb.sgml</file>
+ <file>ttb.xml</file>
</header>
<module>ttb</module>
<modulesummary>A base for building trace tools for distributed systems.</modulesummary>
<description>
- <p>The Trace Tool Builder <c>ttb</c> is a base for building trace
+ <p>The Trace Tool Builder, <c>ttb</c>, is a base for building trace
tools for distributed systems.
</p>
- <p>When using <c>ttb</c>, <c>dbg</c> shall not be used in parallel.</p>
+ <p>When using <c>ttb</c>, do not use module <c>dbg</c> in application
+ Runtime_Tools in parallel.</p>
</description>
<funcs>
<func>
<name>start_trace(Nodes, Patterns, FlagSpec, Opts) -> Result</name>
- <fsummary>Start a trace port on each given node.</fsummary>
+ <fsummary>Start a trace port on each specified node.</fsummary>
<type>
<v>Result = see p/2</v>
<v>Nodes = see tracer/2</v>
@@ -57,49 +57,56 @@
</type>
<desc>
<p>This function is a shortcut allowing to start a trace with one command. Each
- tuple in <c>Patterns</c> is converted to list which is in turn passed to
- <c>ttb:tpl</c>.
- The call:<code type="none">
-ttb:start_trace([Node, OtherNode],
-[{mod, foo, []}, {mod, bar, 2}],
-{all, call},
-[{file, File}, {handler,{fun myhandler/4, S}}])</code>
- is equivalent to <code type="none">
-ttb:start_trace([Node, OtherNode], [{file, File}, {handler,{fun myhandler/4, S}}]),
+ tuple in <c>Patterns</c> is converted to a list, which in turn is passed to
+ <c>ttb:tpl/2,3,4</c>.</p>
+ <p>The call:</p>
+ <pre>
+> <input>ttb:start_trace([Node, OtherNode],
+ [{mod, foo, []}, {mod, bar, 2}],
+ {all, call},
+ [{file, File}, {handler,{fun myhandler/4, S}}]).</input></pre>
+ <p> is equivalent to:</p>
+ <pre>
+> <input>ttb:start_trace([Node, OtherNode],
+ [{file, File}, {handler,{fun myhandler/4, S}}]),
ttb:tpl(mod, foo, []),
ttb:tpl(mod, bar, 2, []),
-ttb:p(all, call)</code>
- </p>
+ttb:p(all, call).</input></pre>
</desc>
</func>
+
<func>
<name>tracer() -> Result</name>
- <fsummary>This is equivalent to tracer(node()).</fsummary>
+ <fsummary>Equivalent to tracer(node()).</fsummary>
<desc>
- <p>This is equivalent to <c>tracer(node())</c>.</p>
+ <p>Equivalent to <c>tracer(node())</c>.</p>
</desc>
</func>
+
<func>
<name>tracer(Shortcut) -> Result</name>
- <fsummary>Handy shortcuts for common tracing settings</fsummary>
+ <fsummary>Handy shortcuts for common tracing settings.</fsummary>
<type>
<v>Shortcut = shell | dbg</v>
</type>
<desc>
+ <p>Handy shortcuts for common tracing settings.</p>
<p><c>shell</c> is equivalent to <c>tracer(node(),[{file, {local, "ttb"}}, shell])</c>.</p>
<p><c>dbg</c> is equivalent to <c>tracer(node(),[{shell, only}])</c>.</p>
</desc>
</func>
+
<func>
<name>tracer(Nodes) -> Result</name>
- <fsummary>This is equivalent to tracer(Nodes,[]).</fsummary>
+ <fsummary>Equivalent to tracer(Nodes,[]).</fsummary>
<desc>
- <p>This is equivalent to <c>tracer(Nodes,[])</c>.</p>
+ <p>Equivalent to <c>tracer(Nodes,[])</c>.</p>
</desc>
</func>
+
<func>
<name>tracer(Nodes,Opts) -> Result</name>
- <fsummary>Start a trace port on each given node.</fsummary>
+ <fsummary>Start a trace port on each specified node.</fsummary>
<type>
<v>Result = {ok, ActivatedNodes} | {error,Reason}</v>
<v>Nodes = atom() | [atom()] | all | existing | new</v>
@@ -121,99 +128,109 @@ ttb:p(all, call)</code>
<v>ShellSpec = true | false | only</v>
</type>
<desc>
- <p>This function starts a file trace port on all given nodes
- and also points the system tracer for sequential tracing to
+ <p>Starts a file trace port on all specified nodes
+ and points the system tracer for sequential tracing to
the same port.
</p>
- <p>The given <c>Filename</c> will be prefixed with the node
- name. Default <c>Filename</c> is "ttb".
- </p>
- <p><c>File={wrap,Filename,Size,Count}</c> can be used if
- the size of the trace logs must be limited. Default values are
- <c>Size=128*1024</c> and <c>Count=8</c>.
- </p>
- <p>When tracing diskless nodes, <c>ttb</c> must be started
+ <p><em>Options:</em></p>
+ <taglist>
+ <tag><c>Filename</c></tag>
+ <item><p>The specified <c>Filename</c> is prefixed with the node name.
+ Default <c>Filename</c> is <c>ttb</c>.</p></item>
+ <tag><c>File={wrap,Filename,Size,Count}</c></tag>
+ <item><p>Can be used if the size of the trace logs must be limited.
+ Default values are
+ <c>Size=128*1024</c> and <c>Count=8</c>.</p></item>
+ <tag><c>Client</c></tag>
+ <item><p>When tracing diskless nodes, <c>ttb</c> must be started
from an external "trace control node" with disk access, and
<c>Client</c> must be <c>{local, File}</c>. All
trace information is then sent to the trace control node where
- it is written to file.
- </p>
- <p>The <c>process_info</c> option indicates if process
- information should be collected. If <c>PI = true</c> (which is
+ it is written to file.</p></item>
+ <tag><c>process_info</c></tag>
+ <item><p>Indicates if process
+ information is to be collected. If <c>PI = true</c> (which is
default), each process identifier <c>Pid</c> is replaced by a
tuple <c>{Pid,ProcessInfo,Node}</c>, where <c>ProcessInfo</c>
- is the process' registered name its globally registered name,
- or its initial function. It is possible to turn off this
- functionality by setting <c>PI = false</c>.
- </p>
- <p>The <c>{shell, ShellSpec}</c> option indicates that the trace messages should
- be printed on the console as they are received by the tracing
- process. This implies <c>{local, File}</c> trace client. If the ShellSpec
- is <c>only</c> (instead of <c>true</c>), no trace logs are stored.
- </p>
- <p>The <c>shell</c> option is a shortcut for <c>{shell, true}</c>.</p>
- <p>The <c>timer</c> option indicates that the trace should be
+ is the registered process name, its globally registered name,
+ or its initial function. To turn off this functionality,
+ set <c>PI = false</c>.</p></item>
+ <tag><c>{shell, ShellSpec}</c></tag>
+ <item><p>Indicates that trace messages are to be printed on the
+ console as they are received by the tracing process. This implies
+ trace client <c>{local, File}</c>. If <c>ShellSpec</c>
+ is <c>only</c> (instead of <c>true</c>), no trace logs are stored.</p></item>
+ <tag><c>shell</c></tag>
+ <item><p>Shortcut for <c>{shell, true}</c>.</p></item>
+ <tag><c>timer</c></tag>
+ <item><p>Indicates that the trace is to be
automatically stopped after <c>MSec</c> milliseconds. <c>StopOpts</c>
- are passed to <c>ttb:stop/2</c> command if specified (default is <c>[]</c>).
- Note that the timing is approximate, as delays related to
+ are passed to command <c>ttb:stop/2</c> if specified (default is <c>[]</c>).
+ Notice that the timing is approximate, as delays related to
network communication are always present. The timer starts after
- <c>ttb:p/2</c> is issued, so you can set up your trace patterns before.
- </p>
- <p>The <c>overload_check</c> option allows to enable overload
+ <c>ttb:p/2</c> is issued, so you can set up your trace patterns before.</p></item>
+ <tag><c>overload_check</c></tag>
+ <item><p>Allows to enable overload
checking on the nodes under trace. <c>Module:Function(check)</c>
- is performed each <c>MSec</c> milliseconds. If the check returns
- <c>true</c>, the tracing is disabled on a given node.<br/>
- <c>Module:Function</c> should be able to handle at least three
- atoms: <c>init</c>, <c>check</c> and <c>stop</c>. <c>init</c> and
- <c>stop</c> give the user a possibility to initialize and clean
- up the check environment.<br/>
- When a node gets overloaded, it is not possible to issue <c>ttb:p</c>
- nor any command from the <c>ttb:tp</c> family, as it would lead to
+ is performed each <c>MSec</c> millisecond. If the check returns
+ <c>true</c>, the tracing is disabled on a specified node.</p>
+ <p><c>Module:Function</c> must be able to handle at least three
+ atoms: <c>init</c>, <c>check</c>, and <c>stop</c>. <c>init</c> and
+ <c>stop</c> allows you to initialize and clean
+ up the check environment.</p>
+ <p>When a node gets overloaded, it is not possible to issue <c>ttb:p/2</c>
+ or any command from the <c>ttb:tp/2,3,4</c> family, as it would lead to
inconsistent tracing state (different trace specifications on
- different node).
- </p>
- <p>The <c>flush</c> option periodically flushes all file trace
- port clients (see <c>dbg:flush_trace_port/1</c>). When enabled,
- the buffers are freed each <c>MSec</c> milliseconds. This option is
- not allowed with <c>{file, {local, File}}</c> tracing.
- </p>
- <p><c>{resume, FetchTimeout}</c> enables the autoresume feature.
- Whenever enabled, remote nodes try to reconnect to the controlling node
- in case they were restarted. The feature requires <c>runtime_tools</c>
- application to be started (so it has to be present in the <c>.boot</c>
- scripts if the traced nodes run with embedded erlang). If this is
- not possible, resume may be performed manually by starting
- <c>runtime_tools</c> remotely using <c>rpc:call/4</c>.<br/>
- <c>ttb</c> tries to fetch all logs from a reconnecting node before
- reinitializing the trace. This has to finish within FetchTimeout milliseconds
- or is aborted<br/>
- By default, autostart information is stored in a file called
+ different nodes).</p></item>
+ <tag><c>flush</c></tag>
+ <item><p>Periodically flushes all file trace
+ port clients (see
+ <seealso marker="runtime_tools:dbg#flush_trace_port/1">
+ <c>dbg:flush_trace_port/1</c></seealso>). When enabled,
+ the buffers are freed each <c>MSec</c> millisecond. This option is
+ not allowed with <c>{file, {local, File}}</c> tracing.</p></item>
+ <tag><c>{resume, FetchTimeout}</c></tag>
+ <item><p>Enables the autoresume feature.
+ When enabled, remote nodes try to reconnect to the controlling node
+ if they are restarted. The feature requires application Runtime_Tools
+ to be started (so it has to be present in the <c>.boot</c>
+ scripts if the traced nodes run with embedded Erlang). If this is
+ not possible, resume can be performed manually by starting
+ <c>Runtime_Tools</c> remotely using
+ <seealso marker="kernel:rpc#call/4"><c>rpc:call/4</c></seealso>.</p>
+ <p><c>ttb</c> tries to fetch all logs from a reconnecting node before
+ reinitializing the trace. This must finish within <c>FetchTimeout</c>
+ milliseconds or is aborted.</p>
+ <p>By default, autostart information is stored in a file named
<c>ttb_autostart.bin</c> on each node. If this is not desired
- (i.e. on diskless nodes), a custom module to handle autostart
+ (for example, on diskless nodes), a custom module handling autostart
information storage and retrieval can be provided by specifying
- <c>ttb_autostart_module</c> environment variable for the <c>runtime_tools</c>
- application. The module has to respond to the following API:
- <taglist>
+ environment variable <c>ttb_autostart_module</c> for the application
+ Runtime_Tools. The module must respond to the following API:</p>
+ <taglist>
<tag><c>write_config(Data) -> ok</c></tag>
- <item>Store the provided data for further retrieval. It is
+ <item><p>Stores the provided data for further retrieval. It is
important to realize that the data storage used must not
- be affected by the node crash.</item>
+ be affected by the node crash.</p></item>
<tag><c>read_config() -> {ok, Data} | {error, Error}</c></tag>
- <item>Retrieve configuration stored with <c>write_config(Data)</c>.</item>
+ <item><p>Retrieves configuration stored with <c>write_config(Data)</c>.</p></item>
<tag><c>delete_config() -> ok</c></tag>
- <item>Delete configuration stored with <c>write_config(Data)</c>.
- Note that after this call any subsequent calls to <c>read_config</c>
- must return <c>{error, Error}</c>.
+ <item><p>Deletes configuration stored with <c>write_config(Data)</c>.
+ Notice that after this call any subsequent calls to <c>read_config</c>
+ must return <c>{error, Error}</c>.</p>
</item>
- </taglist>
- </p>
- <p>The <c>resume</c> option implies the default <c>FetchTimeout</c>, which is
+ </taglist>
+ <p><c>resume</c> implies the default <c>FetchTimeout</c>, which is
10 seconds</p>
+ </item>
+ </taglist>
+
</desc>
</func>
+
<func>
<name>p(Procs,Flags) -> Return</name>
- <fsummary>Sets the given trace flags on the given processes.</fsummary>
+ <fsummary>Set the specified trace flags on the specified processes.</fsummary>
<type>
<v>Return = {ok,[{Procs,MatchDesc}]}</v>
<v>Procs = Process | [Process] | all | new | existing</v>
@@ -221,58 +238,64 @@ ttb:p(all, call)</code>
<v>Flags = Flag | [Flag]</v>
</type>
<desc>
- <p>This function sets the given trace flags on the given
- processes. The <c>timestamp</c> flag is always turned on.
+ <p>Sets the specified trace flags on the specified
+ processes. Flag <c>timestamp</c> is always turned on.
</p>
- <p>Please turn to the Reference manual for module <c>dbg</c>
- for details about the possible trace flags. The parameter
- <c>MatchDesc</c> is the same as returned from <c>dbg:p/2</c></p>
- <p>Processes can be given as registered names, globally
- registered names or process identifiers. If a registered name
- is given, the flags are set on processes with this name on all
+ <p>See the Reference Manual for module
+ <seealso marker="runtime_tools:dbg"><c>dbg</c></seealso>
+ and the possible trace flags. Parameter
+ <c>MatchDesc</c> is the same as returned from
+ <c>dbg:p/2</c>.</p>
+ <p>Processes can be specified as registered names, globally
+ registered names, or process identifiers. If a registered name
+ is specified, the flags are set on processes with this name on all
active nodes.</p>
- <p>Issuing this command starts the timer for this trace if
- <c>timer</c> option was specified with <c>tracer/2</c>.
+ <p>Issuing this command starts the timer for this trace if option
+ <c>timer</c> is specified with <c>tracer/2</c>.
</p>
</desc>
</func>
+
<func>
<name>tp, tpl, ctp, ctpl, ctpg</name>
<fsummary>Set and clear trace patterns.</fsummary>
<desc>
- <p>These functions should be used in combination with the
- <c>call</c> trace flag for setting and clearing trace
- patterns. When the <c>call</c> trace flag is set on a process,
- function calls will be traced on that process if a trace
- pattern has been set for the called function. Trace patterns
- specifies how to trace a function by using match
+ <p>These functions are to be used with
+ trace flag <c>call</c> for setting and clearing trace
+ patterns. When trace flag <c>call</c> is set on a process,
+ function calls are traced on that process if a trace
+ pattern is set for the called function. Trace patterns
+ specify how to trace a function by using match
specifications. Match specifications are described in the
- User's Guide for the erlang runtime system <c>erts</c>.
+ <seealso marker="erts:users_guide"><c>ERTS User's Guide</c></seealso>.
</p>
<p>These functions are equivalent to the corresponding
- functions in <c>dbg</c>, but all calls are stored in the
- history. The history buffer makes it easy to create config
- files so that the same trace environment can be setup several
- times, e.g. if you want to compare two test runs. It also
+ functions in module
+ <seealso marker="runtime_tools:dbg">dbg</seealso>,
+ but all calls are stored in the
+ history. The history buffer makes it easy to create configuration
+ files; the same trace environment can be set up many
+ times, for example, to compare two test runs. It also
reduces the amount of typing when using <c>ttb</c> from the
- erlang shell.
+ Erlang shell.
</p>
<taglist>
<tag><c>tp</c></tag>
- <item>Set trace pattern on global function calls</item>
+ <item><p>Sets trace patterns on global function calls.</p></item>
<tag><c>tpl</c></tag>
- <item>Set trace pattern on local and global function calls</item>
+ <item><p>Sets trace patterns on local and global function calls.</p></item>
<tag><c>ctp</c></tag>
- <item>Clear trace pattern on local and global function
- calls</item>
+ <item><p>Clears trace patterns on local and global function
+ calls.</p></item>
<tag><c>ctpl</c></tag>
- <item>Clear trace pattern on local function calls</item>
+ <item><p>Clears trace patterns on local function calls.</p></item>
<tag><c>ctpg</c></tag>
- <item>Clear trace pattern on global function calls</item>
+ <item><p>Clears trace patterns on global function calls.</p></item>
</taglist>
- <p>With <c>tp</c> and <c>tpl</c> one of match specification shortcuts
- may be used (example: <c>ttb:tp(foo_module, caller)</c>). The shortcuts are:
- <taglist>
+ <p>With <c>tp</c> and <c>tpl</c>, one of the match specification shortcuts
+ can be used (for example, <c>ttb:tp(foo_module, caller)</c>).</p>
+ <p>The shortcuts are as follows:</p>
+ <list type="bulleted">
<item><c>return</c> - for <c>[{'_',[],[{return_trace}]}]</c>
(report the return value)</item>
<item><c>caller</c> - for <c>[{'_',[],[{message,{caller}}]}]</c>
@@ -280,34 +303,36 @@ ttb:p(all, call)</code>
<item><c>{codestr, Str}</c> - for <c>dbg:fun2ms/1</c> arguments
passed as strings (example: <c>"fun(_) -> return_trace() end"</c>)
</item>
- </taglist>
- </p>
+ </list>
</desc>
</func>
+
<func>
<name>list_history() -> History</name>
- <fsummary>Returns all calls stored in history</fsummary>
+ <fsummary>Return all calls stored in history.</fsummary>
<type>
<v>History = [{N,Func,Args}]</v>
</type>
<desc>
<p>All calls to <c>ttb</c> is stored in the history. This
function returns the current content of the history. Any entry
- can be re-executed with <c>run_history/1</c> or stored in a
- config file with <c>write_config/2/3</c>.</p>
+ can be reexecuted with <c>run_history/1</c> or stored in a
+ configuration file with <c>write_config/2,3</c>.</p>
</desc>
</func>
+
<func>
<name>run_history(N) -> ok | {error, Reason}</name>
- <fsummary>Executes one entry of the history</fsummary>
+ <fsummary>Execute one entry of the history.</fsummary>
<type>
<v>N = integer() | [integer()]</v>
</type>
<desc>
- <p>Executes the given entry or entries from the history
- list. History can be listed with <c>list_history/0</c>.</p>
+ <p>Executes the specified entry or entries from the history
+ list. To list history, use <c>list_history/0</c>.</p>
</desc>
</func>
+
<func>
<name>write_config(ConfigFile,Config)</name>
<fsummary>Equivalent to write_config(ConfigFile,Config,[]).</fsummary>
@@ -315,9 +340,10 @@ ttb:p(all, call)</code>
<p>Equivalent to <c>write_config(ConfigFile,Config,[])</c>.</p>
</desc>
</func>
+
<func>
<name>write_config(ConfigFile,Config,Opts) -> ok | {error,Reason}</name>
- <fsummary>Creates a config file.</fsummary>
+ <fsummary>Create a configuration file.</fsummary>
<type>
<v>ConfigFile = string()</v>
<v>Config = all | [integer()] | [{Mod,Func,Args}]</v>
@@ -328,92 +354,97 @@ ttb:p(all, call)</code>
<v>Opt = append</v>
</type>
<desc>
- <p>This function creates or extends a config file which can be
+ <p>Creates or extends a configuration file, which can be
used for restoring a specific configuration later.
</p>
- <p>The content of the config file can either be fetched from
- the history or given directly as a list of
+ <p>The contents of the configuration file can either be fetched from
+ the history or specified directly as a list of
<c>{Mod,Func,Args}</c>.
</p>
- <p>If the complete history is to be stored in the config file
- <c>Config</c> should be <c>all</c>. If only a selected number
- of entries from the history should be stored, <c>Config</c>
- should be a list of integers pointing out the entries to be
+ <p>If the complete history is to be stored in the configuration file,
+ <c>Config</c> must be <c>all</c>. If only a selected number
+ of entries from the history are to be stored, <c>Config</c>
+ must be a list of integers pointing out the entries to be
stored.
</p>
- <p>If <c>Opts</c> is not given or if it is <c>[]</c>,
+ <p>If <c>Opts</c> is not specified or if it is <c>[]</c>,
<c>ConfigFile</c> is deleted and a new file is created. If
- <c>Opts = [append]</c>, <c>ConfigFile</c> will not be deleted.
- The new information will be appended at the end of the file.</p>
+ <c>Opts = [append]</c>, <c>ConfigFile</c> is not deleted.
+ The new information is appended at the end of the file.</p>
</desc>
</func>
+
<func>
<name>run_config(ConfigFile) -> ok | {error,Reason}</name>
- <fsummary>Executes all entries in a config file.</fsummary>
+ <fsummary>Execute all entries in a configuration file.</fsummary>
<type>
<v>ConfigFile = string()</v>
</type>
<desc>
- <p>Executes all entries in the given config file. Note that the history
- of the last trace is always available in the file named
- <c>ttb_last_config</c>.</p>
+ <p>Executes all entries in the specified configuration file.
+ Notice that the history of the last trace is always available
+ in file <c>ttb_last_config</c>.</p>
</desc>
</func>
+
<func>
<name>run_config(ConfigFile,NumList) -> ok | {error,Reason}</name>
- <fsummary>Executes selected entries from a config file.</fsummary>
+ <fsummary>Execute selected entries from a configuration file.</fsummary>
<type>
<v>ConfigFile = string()</v>
<v>NumList = [integer()]</v>
</type>
<desc>
- <p>Executes selected entries from the given config
+ <p>Executes selected entries from the specified configuration
file. <c>NumList</c> is a list of integers pointing out the
entries to be executed.
</p>
- <p>The content of a config file can be listed with
+ <p>To list the contents of a configuration file, use
<c>list_config/1</c>.</p>
- <p> Note that the history
- of the last trace is always available in the file named
- <c>ttb_last_config</c>.</p>
+ <p>Notice that the history of the last trace is always available
+ in file <c>ttb_last_config</c>.</p>
</desc>
</func>
+
<func>
<name>list_config(ConfigFile) -> Config | {error,Reason}</name>
- <fsummary>Lists all entries in a config file.</fsummary>
+ <fsummary>List all entries in a configuration file.</fsummary>
<type>
<v>ConfigFile = string()</v>
<v>Config = [{N,Func,Args}]</v>
</type>
<desc>
- <p>Lists all entries in the given config file.</p>
+ <p>Lists all entries in the specified configuration file.</p>
</desc>
</func>
+
<func>
<name>write_trace_info(Key,Info) -> ok</name>
- <fsummary>Writes any information to the <c>.ti</c>file.</fsummary>
+ <fsummary>Write any information to file <c>.ti</c>.</fsummary>
<type>
<v>Key = term()</v>
<v>Info = Data | fun() -> Data</v>
<v>Data = term()</v>
</type>
<desc>
- <p>The <c>.ti</c> file contains <c>{Key,ValueList}</c>
- tuples. This function adds <c>Data</c> to the ValueList
+ <p>File <c>.ti</c> contains <c>{Key,ValueList}</c>
+ tuples. This function adds <c>Data</c> to the <c>ValueList</c>
associated with <c>Key</c>. All information written with this
- function will be included in the call to the format handler.</p>
+ function is included in the call to the format handler.</p>
</desc>
</func>
+
<func>
<name>seq_trigger_ms() -> MatchSpec</name>
- <fsummary>Equivalent to seq_trigger_ms(all)</fsummary>
+ <fsummary>Equivalent to seq_trigger_ms(all).</fsummary>
<desc>
- <p>Equivalent to <c>seq_trigger_ms(all)</c></p>
+ <p>Equivalent to <c>seq_trigger_ms(all)</c>.</p>
</desc>
</func>
+
<func>
<name>seq_trigger_ms(Flags) -> MatchSpec</name>
- <fsummary>Returns a match_spec() which starts sequential tracing</fsummary>
+ <fsummary>Return a match_spec() which starts sequential tracing.</fsummary>
<type>
<v>MatchSpec = match_spec()</v>
<v>Flags = all | SeqTraceFlag | [SeqTraceFlag]</v>
@@ -421,54 +452,55 @@ ttb:p(all, call)</code>
</type>
<desc>
<p>A match specification can turn on or off sequential
- tracing. This function returns a match specification which
- turns on sequential tracing with the given <c>Flags</c>.
+ tracing. This function returns a match specification, which
+ turns on sequential tracing with the specified <c>Flags</c>.
</p>
- <p>This match specification can be given as the last argument
- to <c>tp</c> or <c>tpl</c>. The activated <c>Item</c> will
- then become a <em>trigger</em> for sequential tracing. This
- means that if the item is called on a process with the
- <c>call</c> trace flag set, the process will be "contaminated"
- with the seq_trace token.
+ <p>This match specification can be specified as the last argument
+ to <c>tp</c> or <c>tpl</c>. The activated <c>Item</c>
+ then becomes a <em>trigger</em> for sequential tracing. This
+ means that if the item is called on a process with trace flag
+ <c>call</c> set, the process is "contaminated"
+ with token <c>seq_trace</c>.
</p>
<p>If <c>Flags = all</c>, all possible flags are set.
</p>
- <p>Please turn to the reference manual for the
- <em><c>seq_trace</c></em> module in the <em><c>kernel</c></em>
- application to see the possible values for
- <c>SeqTraceFlag</c>. For a description of the match_spec()
- syntax, please turn to the <em>User's guide</em> for the
- runtime system (<em>erts</em>). The chapter <em>Match Specification in Erlang</em> explains the general match
- specification "language".
+ <p>The possible values for <c>SeqTraceFlag</c> are available in
+ <seealso marker="kernel:seq_trace"><c>seq_trace</c></seealso>.</p>
+ <p>For a description of the <c>match_spec()</c> syntax,
+ see section
+ <seealso marker="erts:match_spec"><c>Match Specifications in Erlang</c></seealso>
+ in <c>ERTS</c>, which explains the general match specification "language".
</p>
<note>
<p>The <em>system tracer</em> for sequential tracing is
automatically initiated by <c>ttb</c> when a trace port is
- started with <c>ttb:tracer/0/1/2</c>.</p>
+ started with <c>ttb:tracer/0,1,2</c>.</p>
</note>
- <p>Example of how to use the <c>seq_trigger_ms/0/1</c> function:</p>
- <code type="none">
-(tiger@durin)5> ttb:tracer().
+ <p>An example of how to use function <c>seq_trigger_ms/0,1</c> follows:</p>
+ <pre>
+(tiger@durin)5> <input>ttb:tracer().</input>
{ok,[tiger@durin]}
-(tiger@durin)6> ttb:p(all,call).
+(tiger@durin)6> <input>ttb:p(all,call).</input>
{ok,{[all],[call]}}
-(tiger@durin)7> ttb:tp(mod,func,ttb:seq_trigger_ms()).
+(tiger@durin)7> <input>ttb:tp(mod,func,ttb:seq_trigger_ms()).</input>
{ok,[{matched,1},{saved,1}]}
-(tiger@durin)8> </code>
- <p>Whenever <c>mod:func(...)</c> is called after this, the
- seq_trace token will be set on the executing process.</p>
+(tiger@durin)8></pre>
+ <p>Whenever <c>mod:func(...)</c> is called after this,
+ token <c>seq_trace</c> is set on the executing process.</p>
</desc>
</func>
+
<func>
<name>stop()</name>
- <fsummary>Equivalent to stop([])</fsummary>
+ <fsummary>Equivalent to stop([]).</fsummary>
<desc>
<p>Equivalent to <c>stop([])</c>.</p>
</desc>
</func>
+
<func>
<name>stop(Opts) -> stopped | {stopped, Dir}</name>
- <fsummary>Stop tracing and fetch/format logs from all nodes</fsummary>
+ <fsummary>Stop tracing and fetch/format logs from all nodes.</fsummary>
<type>
<v>Opts = Opt | [Opt]</v>
<v>Opt = nofetch | {fetch_dir, Dir} | format | {format, FormatOpts} | return_fetch_dir</v>
@@ -485,88 +517,103 @@ ttb:p(all, call)</code>
form <c>yyyymmdd-hhmmss</c>. Even logs from nodes on the same
machine as the trace control node are moved to this directory.
The history list is saved to a file named <c>ttb_last_config</c>
- for further reference (as it will be not longer accessible
- through history and configuration management functions (like
+ for further reference (as it is no longer accessible
+ through history and configuration management functions, like
<c>ttb:list_history/0</c>).
</p>
- <p>The <c>nofetch</c> option indicates that trace logs shall not be
- collected after tracing is stopped.
- </p>
- <p>The <c>{fetch, Dir}</c> option allows to specify the directory
+ <p><em>Options:</em></p>
+ <taglist>
+ <tag><c>nofetch</c></tag>
+ <item><p>Indicates that trace logs are not to be
+ collected after tracing is stopped.</p></item>
+ <tag><c>{fetch, Dir}</c></tag>
+ <item><p>Allows specification of the directory
to fetch the data to. If the directory already exists, an
- error is thrown.
- </p>
- <p>The <c>format</c> option indicates that the trace logs
- shall be formatted after tracing is stopped. All logs in the fetch directory will be merged.
- You may use <c>{format, FormatOpts}</c> to pass additional
- arguments to <c>format/2</c>.</p>
- <p>The <c>return_fetch_dir</c> option indicates that the return value
- should be <c>{stopped, Dir}</c> and not just <c>stopped</c>.
- This implies <c>fetch</c>.
- </p>
+ error is thrown.</p></item>
+ <tag><c>format</c></tag>
+ <item><p>Indicates the trace logs to be formatted after tracing
+ is stopped. All logs in the fetch directory are merged.</p></item>
+ <tag><c>return_fetch_dir</c></tag>
+ <item><p>Indicates the return value
+ to be <c>{stopped, Dir}</c> and not just <c>stopped</c>.
+ This implies <c>fetch</c>.</p></item>
+ </taglist>
+
</desc>
</func>
+
<func>
<name>get_et_handler()</name>
- <fsummary>Returns <c>et</c> handler.</fsummary>
+ <fsummary>Return the <c>et</c> handler.</fsummary>
<desc>
- <p>The <c>et</c> handler returned by the function may be used with <c>format/2</c>
- or <c>tracer/2</c>. Example: <c>ttb:format(Dir, [{handler, ttb:get_et_handler()}])</c>.</p>
+ <p>Returns the <c>et</c> handler, which can be used with <c>format/2</c>
+ or <c>tracer/2</c>.</p>
+ <p>Example: <c>ttb:format(Dir, [{handler, ttb:get_et_handler()}])</c>.</p>
</desc>
</func>
+
<func>
<name>format(File)</name>
- <fsummary>Same as <c>format(File,[])</c>.</fsummary>
+ <fsummary>Equivalent to <c>format(File,[])</c>.</fsummary>
<desc>
- <p>Same as <c>format(File,[])</c>.</p>
+ <p>Equivalent to <c>format(File,[])</c>.</p>
</desc>
</func>
+
<func>
<name>format(File,Options) -> ok | {error, Reason}</name>
- <fsummary>Format a binary trace log</fsummary>
+ <fsummary>Format a binary trace log.</fsummary>
<type>
<v>File = string() | [string()]</v>
- <d>This can be the name of a binary log, a list of such logs or the name of a directory containing one or more binary logs.</d>
+ <d>This can be the name of a binary log, a list of such logs,
+ or the name of a directory containing one or more binary logs.</d>
<v>Options = Opt | [Opt]</v>
<v>Opt = {out,Out} | {handler,FormatHandler} | disable_sort</v>
<v>Out = standard_io | string()</v>
<v>FormatHandler = {Function, InitialState}</v>
<v>Function = fun(Fd,Trace,TraceInfo,State) -> State</v>
<v>Fd = standard_io | FileDescriptor</v>
- <d>This is the file descriptor of the destination file <c>Out</c></d>
+ <d>File descriptor of the destination file <c>Out</c>.</d>
<v>Trace = tuple()</v>
- <d>This is the trace message. Please turn to the Reference manual for the <c>erlang</c>module for details.</d>
+ <d>The trace message. For details, see the Reference Manual for
+ module <c>erlang</c>.</d>
<v>TraceInfo = [{Key,ValueList}]</v>
- <d>This includes the keys <c>flags</c>, <c>client</c> and <c>node</c>, and if <c>handler</c> is given as option to the tracer function, this is also included. In addition all information written with the <c>write_trace_info/2</c>function is included. </d>
+ <d>Includes the keys <c>flags</c>, <c>client</c>, and <c>node</c>.
+ If <c>handler</c> is specified as option to the tracer function, this
+ is also included. Also, all information written with function
+ <c>write_trace_info/2</c> is included.</d>
</type>
<desc>
- <p>Reads the given binary trace log(s). The logs are processed
- in the order of their timestamp as long as <c>disable_sort</c>
- option is not given.
+ <p>Reads the specified binary trace log(s). The logs are processed
+ in the order of their time stamps as long as option <c>disable_sort</c>
+ is not specified.
</p>
<p>If <c>FormatHandler = {Function,InitialState}</c>,
- <c>Function</c> will be called for each trace message. If
- <c>FormatHandler = get_et_handler()</c>, <c>et_viewer</c> in
- the <em>Event Tracer</em> application (<c>et</c>) is used for presenting
+ <c>Function</c> is called for each trace message.</p>
+ <p>If <c>FormatHandler = get_et_handler()</c>, <c>et_viewer</c> in
+ application ET is used for presenting
the trace log graphically. <c>ttb</c> provides a few different
- filters which can be selected from the Filter menu in the
- <c>et_viewer</c>. If <c>FormatHandler</c> is not given, a
- default handler is used which presents each trace message as a
- line of text.
+ filters that can be selected from menu <em>Filters and scaling</em>
+ in the <c>et_viewer</c>.</p>
+ <p>If <c>FormatHandler</c> is not specified, a
+ default handler is used presenting each trace message as a
+ text line.
</p>
- <p>The state returned from each call of <c>Function</c> is passed to the next call,
- even if next call is to format a message from another log file.
+ <p>The state returned from each call of <c>Function</c> is passed to
+ the next call, even if the next call is to format a message from another
+ log file.
</p>
- <p>If <c>Out</c> is given, <c>FormatHandler</c> gets the
+ <p>If <c>Out</c> is specified, <c>FormatHandler</c> gets the
file descriptor to <c>Out</c> as the first parameter.
</p>
- <p><c>Out</c> is ignored if <c>et</c> format handler is used.
+ <p><c>Out</c> is ignored if the <c>et</c> format handler is used.
</p>
- <p>Wrap logs can be formatted one by one or all in one go. To
- format one of the wrap logs in a set, give the exact name of
- the file. To format the whole set of wrap logs, give the name
- with '*' instead of the wrap count. See examples in the
- <c>ttb</c> User's Guide.</p>
+ <p>Wrap logs can be formatted one by one or all at once. To
+ format one of the wrap logs in a set, specify the exact file name.
+ To format the whole set of wrap logs, specify the name
+ with <c>*</c> instead of the wrap count. For examples, see the
+ <seealso marker="ttb_ug#format"><c>User's Guide</c></seealso>.
+ </p>
</desc>
</func>
</funcs>
diff --git a/lib/observer/doc/src/ttb_ug.xml b/lib/observer/doc/src/ttb_ug.xml
index a1740b618e..34591ae8de 100644
--- a/lib/observer/doc/src/ttb_ug.xml
+++ b/lib/observer/doc/src/ttb_ug.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2013</year>
+ <year>2002</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,78 +32,85 @@
<section>
<title>Introduction</title>
- <p>The Trace Tool Builder is a base for building trace tools for
- single node or distributed erlang systems. It requires the
- <c>runtime_tools</c> application to be available on the traced
+ <p>Trace Tool Builder is a base for building trace tools for
+ single node or distributed Erlang systems. It requires the
+ Runtime_Tools application to be available on the traced
node.
</p>
- <p>The main features of the Trace Tool Builder are:</p>
+ <p>The following are the main features of Trace Tool Builder:</p>
<list type="bulleted">
- <item>Start tracing to file ports on several nodes with one
+ <item>Start tracing to file ports on many nodes with one
function call.</item>
- <item>Write additional information to a trace information file,
+ <item>Write more information to a trace information file,
which is read during formatting.</item>
- <item>Restoring of previous configuration by maintaining a
+ <item>Restore previous configuration by maintaining a
history buffer and handling configuration files.</item>
- <item>Some simple support for sequential tracing.</item>
- <item>Formatting of binary trace logs and merging of logs from
+ <item>Provide some simple support for sequential tracing.</item>
+ <item>Format binary trace logs and merge logs from
multiple nodes.</item>
</list>
- <p>The intention of the Trace Tool Builder is to serve
- as a base for tailor made trace tools, but you may use it directly
- from the erlang shell (it may mimic <c>dbg</c> behaviour while
- still providing useful additions like match specification shortcuts).
- The application only
- allows the use of file port tracer, so if you would like
- to use other types of trace clients you will be better off
- using <c>dbg</c> directly instead.</p>
+ <p>The intention of Trace Tool Builder is to serve
+ as a base for tailor-made trace tools, but it can also be used directly
+ from the Erlang shell (it can mimic <c>dbg</c> behaviour while
+ still providing useful additions, such as match specification shortcuts).
+ Trace Tool Builder only allows the use of file port tracer, so to use
+ other types of trace clients it is better to use <c>dbg</c> directly.</p>
</section>
<section>
<title>Getting Started</title>
- <p>The <c>ttb</c> module is the interface to all functions in the
- Trace Tool Builder. To get started the least you need to do is to
- start a tracer with <c>ttb:tracer/0/1/2</c>, and set the required
- trace flags on the processes you want to trace with
- <c>ttb:p/2</c>. Then, when the tracing is completed, you must stop
- the tracer with <c>ttb:stop/0/1</c> and format the trace log with
- <c>ttb:format/1/2</c> (as long as there is anything to format, of
- course).
- </p>
- <p><c>ttb:tracer/0/1/2</c> opens a trace port on each node
- that shall be traced. By default, trace messages are written
- to binary files on remote nodes(the binary trace log).
+ <p>Module <c>ttb</c> is the interface to all functions in
+ Trace Tool Builder.</p>
+ <p>To get started, the least you need to do is to
+ start a tracer with
+ <seealso marker="ttb#tracer/0"><c>ttb:tracer/0,1,2</c></seealso>,
+ and set the required
+ trace flags on the processes you want to trace with
+ <seealso marker="ttb#p/2"><c>ttb:p/2</c></seealso>.</p>
+ <p>When the tracing is completed, stop the tracer with
+ <seealso marker="ttb#stop/0"><c>ttb:stop/0,1</c></seealso>
+ and format the trace log with
+ <seealso marker="ttb#format/1"><c>ttb:format/1,2</c></seealso>
+ (if there is anything to format).
</p>
- <p><c>ttb:p/2</c> specifies which processes shall be
- traced. Trace flags given in this call specify what to trace on
- each process. You can call this function several times if you like
- different trace flags to be set on different processes.
- </p>
- <p>If you want to trace function calls (i.e. if you have the
- <c>call</c> trace flag set on any of your processes), you must
+ <p><em>Useful functions:</em></p>
+ <taglist>
+ <tag><c>ttb:tracer/0,1,2</c></tag>
+ <item><p>Opens a trace port on each node to be traced. By default,
+ trace messages are written to binary files on remote nodes (the
+ binary trace log).</p></item>
+ <tag><c>ttb:p/2</c></tag>
+ <item><p>Specifies the processes to be traced. Trace flags specified
+ in this call specify what to trace on each process. This function can be
+ called many times if you like different trace flags to be set on different
+ processes.</p></item>
+ <tag><c>ttb:tp/2,3,4</c> or <c>ttb:tpl/2,3,4</c></tag>
+ <item><p>If you want to trace function calls (that is, if you have
+ trace flag <c>call</c> set on any process), you must
also set trace patterns on the required function(s) with
- <c>ttb:tp</c> or <c>ttb:tpl</c>. A function is only traced if it
- has a trace pattern. The trace pattern specifies how to trace the
+ <seealso marker="ttb#/0"><c>ttb:tp/2,3,4</c></seealso> or
+ <seealso marker="ttb#/0"><c>ttb:tpl/2,3,4</c></seealso>.
+ A function is only traced
+ if it has a trace pattern. The trace pattern specifies how to trace the
function by using match specifications. Match specifications are
- described in the User's Guide for the erlang runtime system
- <c>erts</c>.
- </p>
- <p><c>ttb:stop/0/1</c> stops tracing on all nodes, deletes all
- trace patterns and flushes the trace port buffer.
- </p>
- <p><c>ttb:format/1/2</c> translates the binary trace logs into
- something readable. By default <c>ttb</c> presents each trace
- message as a line of text, but you can also write your own handler
- to make more complex interpretations of the trace information. A
- trace log can even be presented graphically via the Event Tracer
- application. Note that if you give the <c>format</c> option to
- <c>ttb:stop/1</c> the formatting is automatically done when
- stopping <c>ttb</c>.
- </p>
-
+ described in the
+ <seealso marker="erts:users_guide">ERTS User's Guide</seealso>.</p></item>
+ <tag><c>ttb:stop/0,1</c></tag>
+ <item><p>Stops tracing on all nodes, deletes all trace patterns, and
+ flushes the trace port buffer.</p></item>
+ <tag><c>ttb:format/1/2</c></tag>
+ <item><p>Translates the binary trace logs into something readable.
+ By default, <c>ttb</c> presents each trace message as a line of text,
+ but you can also write your own handler to make more complex interpretations
+ of the trace information. A trace log can also be presented graphically
+ with application Event Tracer (ET).</p>
+ <p>If option <c>format</c> is specified to <c>ttb:stop/1</c>, the formatting
+ is automatically done when stopping <c>ttb</c>.</p></item>
+ </taglist>
+
<section>
- <title>Example: Tracing the local node from the erlang shell</title>
- <p>This small module is used in the example:</p>
+ <title>Tracing Local Node from Erlang Shell</title>
+ <p>The following small module is used in the subsequent example:</p>
<code type="none">
-module(m).
-export([f/0]).
@@ -113,25 +121,25 @@ f() ->
From ! {self(),Now}
end. </code>
<p>The following example shows the basic use of <c>ttb</c> from
- the erlang shell. Default options are used both for starting the
- tracer and for formatting (the custom fetch dir is however provided).
- This gives a trace log named <c>Node-ttb</c> in the newly-created
- directory, where <c>Node</c> is the name of the node. The
+ the Erlang shell. Default options are used both for starting the
+ tracer and for formatting (the custom fetch directory is however provided).
+ This gives a trace log named <c>Node-ttb</c> in the newly created
+ directory, where <c>Node</c> is the node name. The
default handler prints the formatted trace messages in the
- shell.</p>
- <code type="none"><![CDATA[
+ shell:</p>
+ <pre>
(tiger@durin)47> %% First I spawn a process running my test function
-(tiger@durin)47> Pid = spawn(m,f,[]).
-<0.125.0>
+(tiger@durin)47> <input>Pid = spawn(m,f,[]).</input>
+&lt;0.125.0>
(tiger@durin)48>
(tiger@durin)48> %% Then I start a tracer...
-(tiger@durin)48> ttb:tracer().
+(tiger@durin)48> <input>ttb:tracer().</input>
{ok,[tiger@durin]}
(tiger@durin)49>
(tiger@durin)49> %% and activate the new process for tracing
(tiger@durin)49> %% function calls and sent messages.
-(tiger@durin)49> ttb:p(Pid,[call,send]).
-{ok,[{<0.125.0>,[{matched,tiger@durin,1}]}]}
+(tiger@durin)49> <input>ttb:p(Pid,[call,send]).</input>
+{ok,[{&lt;0.125.0>,[{matched,tiger@durin,1}]}]}
(tiger@durin)50>
(tiger@durin)50> %% Here I set a trace pattern on erlang:now/0
(tiger@durin)50> %% The trace pattern is a simple match spec
@@ -139,33 +147,33 @@ f() ->
(tiger@durin)50> %% traced. Refer to the reference_manual for
(tiger@durin)50> %% the full list of match spec shortcuts
(tiger@durin)50> %% available.
-(tiger@durin)51> ttb:tp(erlang,now,return).
+(tiger@durin)51> <input>ttb:tp(erlang,now,return).</input>
{ok,[{matched,tiger@durin,1},{saved,1}]}
(tiger@durin)52>
(tiger@durin)52> %% I run my test (i.e. send a message to
(tiger@durin)52> %% my new process)
-(tiger@durin)52> Pid ! self().
-<0.72.0>
+(tiger@durin)52> <input>Pid ! self().</input>
+&lt;0.72.0>
(tiger@durin)53>
(tiger@durin)53> %% And then I have to stop ttb in order to flush
(tiger@durin)53> %% the trace port buffer
-(tiger@durin)53> ttb:stop([return, {fetch_dir, "fetch"}]).
+(tiger@durin)53> <input>ttb:stop([return, {fetch_dir, "fetch"}]).</input>
{stopped, "fetch"}
(tiger@durin)54>
(tiger@durin)54> %% Finally I format my trace log
-(tiger@durin)54> ttb:format("fetch").
-({<0.125.0>,{m,f,0},tiger@durin}) call erlang:now()
-({<0.125.0>,{m,f,0},tiger@durin}) returned from erlang:now/0 ->
+(tiger@durin)54> <input>ttb:format("fetch").</input>
+({&lt;0.125.0>,{m,f,0},tiger@durin}) call erlang:now()
+({&lt;0.125.0>,{m,f,0},tiger@durin}) returned from erlang:now/0 ->
{1031,133451,667611}
-({<0.125.0>,{m,f,0},tiger@durin}) <0.72.0> !
-{<0.125.0>,{1031,133451,667611}}
-ok ]]></code>
+({&lt;0.125.0>,{m,f,0},tiger@durin}) &lt;0.72.0> !
+{&lt;0.125.0>,{1031,133451,667611}}
+ok</pre>
</section>
<section>
- <title>Example: Build your own tool</title>
- <p>This small example shows a simple tool for "debug tracing",
- i.e. tracing of function calls with return values.</p>
+ <title>Build Your Own Tool</title>
+ <p>The following example shows a simple tool for "debug tracing",
+ that is, tracing of function calls with return values:</p>
<code type="none"><![CDATA[
-module(mydebug).
-export([start/0,trc/1,stop/0,format/1]).
@@ -227,124 +235,127 @@ do_print(Out,{trace_ts,P,return_from,{M,F,A},R,Ts},N) ->
"Return value :~p~n~n",
[N,Ts,P,M,F,A,R]). ]]></code>
<p>To distinguish trace logs produced with this tool from other
- logs, the <c>file</c> option is used in <c>tracer/2</c>. The
- logs will therefore be fetched to a directory named
+ logs, option <c>file</c> is used in
+ <seealso marker="ttb#tracer/2"><c>tracer/2</c></seealso>. The
+ logs are therefore fetched to a directory named
<c>ttb_upload_debug_log-YYYYMMDD-HHMMSS</c>
</p>
- <p>By using the <c>handler</c> option when starting the tracer,
+ <p>By using option <c>handler</c> when starting the tracer,
the information about how to format the file is stored in the
trace information file (<c>.ti</c>). This is not necessary, as
- it might be given at the time of formatting instead. It can
- however be useful if you e.g. want to automatically format your
- trace logs by using the <c>format</c> option in
- <c>ttb:stop/1</c>. It also means that you don't need any
- knowledge of the content of a binary log to be able to format it
- the way it was intended. If the <c>handler</c> option is given
- both when starting the tracer and when formatting, the one given
- when formatting is used.
+ it can be specified when formatting instead. However, It can
+ be useful if you, for example, want to format trace logs automatically
+ using option <c>format</c> in <c>ttb:stop/1</c>. Also, you do not need
+ any knowledge of the content of a binary log to format it the way it
+ is intended. If option <c>handler</c> is specified both when starting
+ the tracer and when formatting, the one specified when formatting is used.
</p>
- <p>The <c>call</c> trace flag is set on all processes. This
- means that any function activated with the <c>trc/1</c> command
- will be traced on all existing and new processes.
+ <p>Trace flag <c>call</c> is set on all processes. This
+ means that any function activated with command <c>trc/1</c>
+ is traced on all existing and new processes.
</p>
</section>
</section>
<section>
- <title>Running the Trace Tool Builder against a remote node</title>
+ <title>Running Trace Tool Builder against Remote Node</title>
<p>The Observer application might not always be available on the
- node that shall be traced (in the following called the "traced
- node"). It is still possible to run the Trace Tool Builder from
+ node to be traced (in the following called the "traced
+ node"). However, Trace Tool Builder can still be run from
another node (in the following called the "trace control node") as
- long as
+ long as the following is fulfilled:
</p>
<list type="bulleted">
<item>The Observer application is available on the trace control node.</item>
- <item>The Runtime Tools application is available on both the
+ <item>The Runtime_Tools application is available on both the
trace control node and the traced node.</item>
</list>
- <p>If the Trace Tool Builder shall be used against a remote node,
+ <p>If Trace Tool Builder is to be used against a remote node,
it is highly recommended to start the trace control node as
<em>hidden</em>. This way it can connect to the traced node
- without the traced node "seeing" it, i.e. if the <c>nodes()</c>
- BIF is called on the traced node, the trace control node will not
- show. To start a hidden node, add the <c>-hidden</c> option to the
- <c>erl</c> command, e.g.</p>
- <code type="none">
-% erl -sname trace_control -hidden </code>
+ without being "seen" by it, that is, if the <c>nodes()</c>
+ BIF is called on the traced node, the trace control node does not
+ show. To start a hidden node, add option <c>-hidden</c> to the
+ <c>erl</c> command, for example:</p>
+ <pre>
+% <input>erl -sname trace_control -hidden</input></pre>
<section>
- <title>Diskless node</title>
+ <title>Diskless Node</title>
<p>If the traced node is diskless, <c>ttb</c> must be started from
- a trace control node with disk access, and the <c>file</c> option
- must be given to the <c>tracer/2</c> function with the value
- <c>{local, File}</c>, e.g.</p>
- <code type="none">
-(trace_control@durin)1> ttb:tracer(mynode@diskless,{file,{local,
-{wrap,"mytrace"}}}).
-{ok,[mynode@diskless]} </code>
+ a trace control node with disk access, and option <c>file</c>
+ must be specified to function <c>tracer/2</c> with value
+ <c>{local, File}</c>, for example:</p>
+ <pre>
+(trace_control@durin)1> <input>ttb:tracer(mynode@diskless,
+ {file,{local,{wrap,"mytrace"}}}).</input>
+{ok,[mynode@diskless]}</pre>
</section>
</section>
<section>
- <title>Additional tracing options</title>
- <p>When setting up a trace, several features may be turned on:</p>
+ <title>More Tracing Options</title>
+ <p>When setting up a trace, the following features can also be activated:</p>
<list type="bulleted">
- <item>time-constrained tracing,</item>
- <item>overload protection,</item>
- <item>autoresuming.</item>
+ <item>Time-constrained tracing</item>
+ <item>Overload protection</item>
+ <item>Autoresume</item>
+ <item><c>dbg</c> mode</item>
</list>
<section>
- <title>Time-constrained tracing</title>
- <p>Sometimes, it may be helpful to enable trace for a
- given period of time (i.e. to monitor a system for 24 hours
- or half of a second). This may be done by issuing additional
- <c>{timer, TimerSpec}</c> option. If <c>TimerSpec</c> has the
+ <title>Time-Constrained Tracing</title>
+ <p>It can sometimes be helpful to enable trace for a
+ specified period of time (for example, to monitor a system for 24 hours
+ or half a second). This can be done with option
+ <c>{timer, TimerSpec}</c>. If <c>TimerSpec</c> has the
form of <c>MSec</c>, the trace is stopped after <c>MSec</c>
- milliseconds using <c>ttb:stop/0</c>. If any additional options
- are provided (<c>TimerSpec = {MSec, Opts}</c>), <c>ttb:stop/1</c>
- is called instead with <c>Opts</c> as the arguments. The timer
- is started with <c>ttb:p/2</c>, so any trace patterns should
- be set up before. <c>ttb:start_trace/4</c>
- always sets up all pattern before invoking <c>ttb:p/2</c>.
- Note that due to network and processing delays the the period
- of tracing is approximate.
- The example below shows how to set up a trace which will be
- automatically stopped and formatted after 5 seconds
- </p><code>
-(tiger@durin)1>ttb:start_trace([node()],
- [{erlang, now,[]}],
- {all, call},
- [{timer, {5000, format}}]).
-</code>
+ milliseconds using
+ <seealso marker="ttb#stop/0"><c>ttb:stop/0</c></seealso>. If more
+ options are provided (<c>TimerSpec = {MSec, Opts}</c>),
+ <seealso marker="ttb#stop/1"><c>ttb:stop/1</c></seealso>
+ is called instead with <c>Opts</c> as argument.</p>
+ <p>The timer is started with
+ <seealso marker="ttb#p/2"><c>ttb:p/2</c></seealso>, so any trace patterns
+ must be set up in advance.
+ <seealso marker="ttb#start_trace/4"><c>ttb:start_trace/4</c></seealso>
+ always sets up all patterns before invoking <c>ttb:p/2</c>.</p>
+ <p>The following example shows how to set up a trace that is
+ automatically stopped and formatted after 5 seconds:
+ </p><pre>
+(tiger@durin)1> <input>ttb:start_trace([node()],
+ [{erlang, now,[]}],
+ {all, call},
+ [{timer, {5000, format}}]).</input></pre>
+ <note><p>Because of network and processing delays, the period
+ of tracing is approximate.</p></note>
+
</section>
<section>
- <label>Overload protection</label>
- <p>When tracing live systems, special care needs to be always taken
- not to overload a node with too heavy tracing. <c>ttb</c> provides
- the <c>overload</c> option to help to address the problem.</p>
- <p><c>{overload, MSec, Module, Function}</c> instructs the ttb backend
- (called <c>observer_backend</c>, part of the <c>runtime_tools</c>
- application) to perform overload check every <c>MSec</c> milliseconds.
- If the check (namely <c>Module:Function(check)</c>) returns
+ <title>Overload Protection</title>
+ <p>When tracing live systems, always take special care to not
+ overload a node with too heavy tracing. <c>ttb</c> provides
+ option <c>overload</c> to address this problem.</p>
+ <p><c>{overload, MSec, Module, Function}</c> instructs the <c>ttb</c> back end
+ (a part of the <seealso marker="runtime_tools:index">Runtime_Tools</seealso>
+ application) to perform overload check every <c>MSec</c> millisecond.
+ If the check (named <c>Module:Function(check)</c>) returns
<c>true</c>, tracing is disabled on the selected node.</p>
<p>Overload protection activated on one node does not
affect other nodes, where the tracing continues as normal.
- <c>ttb:stop/0/1</c> fetches data from all clients, including everything
- that has been collected before overload protection was activated.
- Note that
- changing trace details (with <c>ttb:p</c> and <c>ttb:tp/tpl...</c>)
- once overload protection gets activated in one of the traced
- nodes is not permitted in order not to allow trace setup
- to be inconsistent between nodes.
- </p>
- <p><c>Module:Function</c> provided with the <c>overload</c> option must
- handle three calls: <c>init</c>, <c>check</c> and <c>stop</c>. <c>init</c>
- and <c>stop</c> allows to perform some setup and teardown required by
- the check. An overload check module could look like this (note that
- <c>check</c> is always called by the same process, so <c>put</c> and
- <c>get</c> are possible).
- </p><code>
+ <c>ttb:stop/0,1</c> fetches data from all clients, including everything
+ collected before the activation of overload protection.</p>
+
+ <note><p>
+ It is not allowed to change trace details
+ (with <c>ttb:p</c> and <c>ttb:tp/tpl...</c>) once overload
+ protection is activated in one of the traced nodes. This is to
+ avoid trace setup being inconsistent between nodes.</p></note>
+
+ <p><c>Module:Function</c> provided with option <c>overload</c> must
+ handle three calls: <c>init</c>, <c>check</c>, and <c>stop</c>. <c>init</c>
+ and <c>stop</c> allow some setup and teardown required by
+ the check. An overload check module can look as follows:
+ </p><code type="none">
-module(overload).
-export([check/1]).
@@ -361,33 +372,37 @@ check(check) ->
end;
check(stop) ->
get(pid) ! stop.</code>
+ <note><p>
+ <c>check</c> is always called by the same process, so <c>put</c> and
+ <c>get</c> are possible.</p></note>
</section>
<section>
<title>Autoresume</title>
- <p>It is possible that a node (probably a buggy one, hence traced)
- crashes. In order to automatically resume tracing on the node
- as soon as it gets back, <c>resume</c> has to be used. When
- it is, the failing node tries to reconnect
- to trace control node as soon as <c>runtime tools</c> is started.
- This implies that <c>runtime_tools</c> must be included in
- other node's startup chain (if it is not, one could still
- resume tracing by starting <c>runtime_tools</c> manually,
- i.e. by an RPC call).</p>
- <p>In order not to loose the data that the failing node stored
- up to the point of crash, the control node will try to fetch
- it before restarting trace. This must happen within the allowed
- time frame or is aborted (default is 10 seconds, can be customized with
- <c>{resume, MSec}</c>). The data fetched this way is then
- merged with all other traces.</p>
- <p>Autostart feature requires additional data to be stored on
+ <p>A node can crash (probably a buggy one, hence traced).
+ Use <c>resume</c> to resume tracing on the node automatically
+ when it gets back. The failing node then tries to reconnect
+ to trace control node when <c>Runtime_Tools</c> is started.
+ This implies that <c>Runtime_Tools</c> must be included in
+ the startup chain of other nodes (if not, you can still
+ resume tracing by starting <c>Runtime_Tools</c> manually,
+ that is, by an RPC call).</p>
+ <p>To not lose the data that the failing node stored
+ up to the point of crash, the control node tries to fetch
+ it before restarting trace. This must occur within the allowed
+ time frame, otherwise it is aborted (default is 10 seconds, but it
+ can be changed with <c>{resume, MSec}</c>). The data fetched
+ this way is then merged with all other traces.</p>
+ <p>The autostart feature requires more data to be stored on
traced nodes. By default, the data is stored automatically
- to the file called "ttb_autostart.bin" in the traced node's cwd.
- Users may decide to change this behaviour (i.e. on diskless
+ to the file named "ttb_autostart.bin" in the currect working directory
+ (cwd) of the traced node.
+ Users can change this behaviour (that is, on diskless
nodes) by specifying their own module to handle autostart data
storage and retrieval (<c>ttb_autostart_module</c>
- environment variable of <c>runtime_tools</c>). Please see the
- ttb's reference manual to see the module's API. This example
- shows the default handler</p>
+ environment variable of <c>runtime_tools</c>). For information
+ about the API, see module
+ <seealso marker="ttb"><c>ttb</c></seealso>.
+ The following example shows the default handler:</p>
<code>
-module(ttb_autostart).
-export([read_config/0,
@@ -406,54 +421,60 @@ read_config() ->
end.
write_config(Data) ->
- file:write_file(?AUTOSTART_FILENAME, term_to_binary(Data)).
- </code>
- <p>Remember that file trace ports buffer the data
+ file:write_file(?AUTOSTART_FILENAME, term_to_binary(Data)).</code>
+
+ <note><p>Remember that file trace ports buffer the data
by default. If the node crashes, trace messages are not
- flushed to the binary log. If the chance of failure is
- high, it might be a good idea to automatically flush
- the buffers every now and then. Passing <c>{flush, MSec}</c>
- as one of <c>ttb:tracer/2</c> option flushes all buffers
- every <c>MSec</c> milliseconds.</p>
+ flushed to the binary log. If the risk of failure is
+ high, it can be a good idea to flush the buffers every
+ now and then automatically. Passing <c>{flush, MSec}</c>
+ as an option of <c>ttb:tracer/2</c> flushes all buffers
+ every <c>MSec</c> millisecond.</p></note>
</section>
<section>
- <title>dbg mode</title>
- <p>The <c>{shell, ShellType}</c> option allows to make <c>ttb</c>
- operation similar to <c>dbg</c>. Using <c>{shell, true}</c>
+ <title>dbg Mode</title>
+ <p>Option <c>{shell, ShellType}</c> allows making <c>ttb</c>
+ operation similar to
+ <seealso marker="runtime_tools:dbg"><c>dbg</c></seealso>.
+ Using <c>{shell, true}</c>
displays all trace messages in the shell before storing them.
<c>{shell, only}</c> additionally disables message storage
- (so that the tool behaves exactly like dbg). This is allowed
- only with ip trace ports (<c>{trace, {local, File}}</c>).
+ (making the tool to behave exactly like <c>dbg</c>). This is
+ allowed only with IP trace ports (<c>{trace, {local, File}}</c>).
</p>
- <p>The command <c>ttb:tracer(dbg)</c> is a shortcut for the pure-dbg
- mode (<c>{shell, only}</c>).</p>
+ <p>Command <c>ttb:tracer(dbg)</c> is a shortcut for the pure
+ <c>dbg</c> mode (<c>{shell, only}</c>).</p>
</section>
</section>
<section>
<marker id="trace_info"></marker>
- <title>Trace Information and the .ti File</title>
- <p>In addition to the trace log file(s), a file with the extension
- <c>.ti</c> is created when the Trace Tool Builder is started. This
- is the trace information file. It is a binary file, and it
+ <title>Trace Information and File .ti</title>
+ <p>In addition to the trace log file(s), a file with extension
+ <c>.ti</c> is created when Trace Tool Builder is started. This
+ is the trace information file. It is a binary file, which
contains the process information, trace flags used, the name of
- the node to which it belongs and all information written with the
- <c>write_trace_info/2</c> function. .ti files are always fetched
- with other logs when the trace is stopped.
+ the node to which it belongs, and all information written with
+ function
+ <seealso marker="ttb#write_trace_info/2"><c>ttb:write_trace_info/2</c></seealso>.
+ <c>.ti</c> files are always fetched with other logs when the trace is stopped.
</p>
<p>Except for the process information, everything in the trace
information file is passed on to the handler function when
- formatting. The <c>TI</c> parameter is a list of
+ formatting. Parameter <c>TI</c> is a list of
<c>{Key,ValueList}</c> tuples. The keys <c>flags</c>,
- <c>handler</c>, <c>file</c> and <c>node</c> are used for
+ <c>handler</c>, <c>file</c>, and <c>node</c> are used for
information written directly by <c>ttb</c>.
</p>
- <p>You can add information to the trace information file by
- calling <c>write_trace_info/2</c>. Note that <c>ValueList</c>
- always will be a list, and if you call <c>write_trace_info/2</c>
- several times with the same <c>Key</c>, the <c>ValueList</c> will
- be extended with a new value each time. Example:
+ <p>Information to the trace information file by
+ can be added by calling
+ <seealso marker="ttb#write_trace_info/2"><c>ttb:write_trace_info/2</c></seealso>.
+ Notice that <c>ValueList</c>
+ always is a list, and if you call <c>write_trace_info/2</c>
+ many times with the same <c>Key</c>, the <c>ValueList</c> is
+ extended with a new value each time.
</p>
+ <p><em>Example:</em></p>
<p><c>ttb:write_trace_info(mykey,1)</c> gives the entry
<c>{mykey,[1]}</c> in <c>TI</c>. Another call,
<c>ttb:write_trace_info(mykey,2)</c>, changes this entry to
@@ -466,15 +487,15 @@ write_config(Data) ->
<p>If you want to limit the size of the trace logs, you can use
wrap logs. This works almost like a circular buffer. You can
specify the maximum number of binary logs and the maximum size of
- each log. <c>ttb</c> will create a new binary log each time a log
- reaches the maximum size. When the the maximum number of logs are
+ each log. <c>ttb</c> then creates a new binary log each time a log
+ reaches the maximum size. When the maximum number of logs are
reached, the oldest log is deleted before a new one is created.
</p>
- <p>Note that the overall size of data generated by ttb may be greater
- than the wrap specification would suggest - if a traced node restarts
- and autoresume is enabled, old wrap log is always stored and
+ <note><p>The overall size of data generated by <c>ttb</c> can be greater
+ than the wrap specification suggests. If a traced node restarts
+ and autoresume is enabled, the old wrap log is always stored and
a new one is created.
- </p>
+ </p></note>
<p>Wrap logs can be formatted one by one or all at once. See
<seealso marker="#format">Formatting</seealso>.
</p>
@@ -484,52 +505,61 @@ write_config(Data) ->
<marker id="format"></marker>
<title>Formatting</title>
<p>Formatting can be done automatically when stopping <c>ttb</c>
- (see <seealso marker="#fetch_format">Automatically collect and format logs from all nodes</seealso>), or explicitly by calling
- the <c>ttb:format/1/2</c> function.
+ (see section
+ <seealso marker="#fetch_format">Automatically Collect and Format Logs from All Nodes</seealso>), or explicitly by calling function
+ <c>ttb:format/1,2</c>.
</p>
<p>Formatting means to read a binary log and present it in a
readable format. You can use the default format handler in
<c>ttb</c> to present each trace message as a line of text, or
write your own handler to make more complex interpretations of the
- trace information. You can even use the Event Tracer <c>et</c> to
- present the trace log graphically (see <seealso marker="#et_viewer">Presenting trace logs with Event Tracer</seealso>).
+ trace information. You can also use application ET to
+ present the trace log graphically (see section
+ <seealso marker="#et_viewer">Presenting Trace Logs with Event Tracer</seealso>).
</p>
- <p>The first argument to <c>ttb:format/1/2</c> specifies which
+ <p>The first argument to <c>ttb:format/1,2</c> specifies which
binary log(s) to format. This is usually the name of a directory
- that ttb created during log fetch. Unless there is the <c>disable_sort</c>
- option provided, the logs from different files are always sorted
- according to timestamp in traces.
+ that <c>ttb</c> created during log fetch. Unless option
+ <c>disable_sort</c> is provided, the logs from different files
+ are always sorted according to time-stamp in traces.
</p>
<p>The second argument to <c>ttb:format/2</c> is a list of
- options. The <c>out</c> option specifies the destination where the
- formatted text shall be written. Default destination is
- <c>standard_io</c>, but a filename can also be given. The
- <c>handler</c> option specifies the format handler to use. If this
- option is not given, the <c>handler</c> option given when starting
- the tracer is used. If the <c>handler</c> option was not given
- when starting the tracer either, a default handler is used, which
- prints each trace message as a line of text. The <c>disable_sort</c>
- option indicates that there logs should not be merged according to
- timestamp, but processed one file after another (this might be
- a bit faster).
+ options as follows:
</p>
- <p>A format handler is a fun taking four arguments. This fun will
- be called for each trace message in the binary log(s). A simple
- example which only prints each trace message could be like this:</p>
+ <taglist>
+ <tag><c>out</c></tag>
+ <item><p>Specifies the destination to write the formatted text.
+ Default destination is <c>standard_io</c>, but a filename can
+ also be specified.</p></item>
+ <tag><c>handler</c></tag>
+ <item><p>Specifies the format handler to use. If this option is
+ not specified, option <c>handler</c> that is specified when starting
+ the tracer is used. If option <c>handler</c> is not specified
+ when starting the tracer either, a default handler is used, which
+ prints each trace message as a text line.</p></item>
+ <tag><c>disable_sort</c></tag>
+ <item><p>Indicates that the logs are not to be merged according to
+ time-stamp, but processed one file after another (this can be
+ a bit faster).</p></item>
+ </taglist>
+ <p>A format handler is a fun taking four arguments. This fun is
+ called for each trace message in the binary log(s). A simple
+ example that only prints each trace message can be as follows:</p>
<code type="none">
fun(Fd, Trace, _TraceInfo, State) ->
io:format(Fd, "Trace: ~p~n", [Trace]),
State
end. </code>
- <p><c>Fd</c> is the file descriptor for the destination file, or
+ <p>Here, <c>Fd</c> is the file descriptor for the destination file, or
the atom <c>standard_io</c>. <c>_TraceInfo</c> contains information
- from the trace information file (see <seealso marker="#trace_info">Trace Information and the .ti File</seealso>). <c>State</c> is a state variable for the format
- handler fun. The initial value of the <c>State</c> variable is
- given with the handler option, e.g.</p>
+ from the trace information file (see section
+ <seealso marker="#trace_info">Trace Information and File .ti</seealso>). <c>State</c> is a state variable for the format
+ handler fun. The initial value of variable <c>State</c> is
+ specified with the handler option, for example:</p>
<code type="none">
ttb:format("tiger@durin-ttb", [{handler, {{Mod,Fun}, initial_state}}])
^^^^^^^^^^^^^ </code>
- <p>Another format handler could be used to calculate time spent by
+ <p>Another format handler can be used to calculate the time spent by
the garbage collector:</p>
<code type="none">
fun(_Fd,{trace_ts,P,gc_start,_Info,StartTs},_TraceInfo,State) ->
@@ -540,111 +570,118 @@ fun(_Fd,{trace_ts,P,gc_start,_Info,StartTs},_TraceInfo,State) ->
io:format("GC in process ~w: ~w milliseconds~n", [P,Time]),
State -- [{P,StartTs}]
end </code>
- <p>A more refined version of this format handler is the function
- <c>handle_gc/4</c> in the module <c>multitrace.erl</c> which can
- be found in the <c>src</c> directory of the Observer application.
+ <p>A more refined version of this format handler is function
+ <c>handle_gc/4</c> in module <c>multitrace.erl</c>
+ included in directory <c>src</c> of the Observer application.
</p>
- <p>The actual trace message is passed as the second argument (<c>Trace</c>).
- The possible values of <c>Trace</c> are:</p>
+ <p>The trace message is passed as the second argument (<c>Trace</c>).
+ The possible values of <c>Trace</c> are the following:</p>
<list type="bulleted">
- <item>all trace messages described in <c>erlang:trace/3</c> documentation,
+ <item>All trace messages described in
+ <seealso marker="erts:erlang#trace/3"><c>erlang:trace/3</c></seealso>
</item>
- <item><c>{drop, N}</c> if ip tracer is used (see <c>dbg:trace_port/2</c>),
+ <item><c>{drop, N}</c> if IP tracer is used (see
+ <seealso marker="runtime_tools:dbg#trace_port/2"><c>dbg:trace_port/2</c></seealso>)
</item>
- <item><c>end_of_trace</c> received once when all trace messages have
- been processed.</item>
+ <item><c>end_of_trace</c> received once when all trace messages are
+ processed</item>
</list>
- <p>By giving the format handler <c>ttb:get_et_handler()</c>, you can have the trace
- log presented graphically with <c>et_viewer</c> in the Event
- Tracer application (see <seealso marker="#et_viewer">Presenting trace logs with Event Tracer</seealso>).
+ <p>By giving the format handler
+ <seealso marker="ttb#get_et_handler/0"><c>ttb:get_et_handler()</c></seealso>,
+ you can have the trace
+ log presented graphically with <c>et_viewer</c> in the ET
+ application (see section
+ <seealso marker="#et_viewer">Presenting Trace Logs with Event Tracer</seealso>).
</p>
- <p>You may always decide not to format the whole trace data contained
- in the fetch directory, but analyze single files instead. In order
- to do so, a single file (or list of files) have to be passed as
- the first argument to <c>format/1/2</c>.</p>
- <p>Wrap logs can be formatted one by one or all in one go. To
- format one of the wrap logs in a set, give the exact name of the
- file. To format the whole set of wrap logs, give the name with '*'
- instead of the wrap count. An example:
+ <p>You can always decide not to format the whole trace data contained
+ in the fetch directory, but analyze single files instead. To do so,
+ a single file (or list of files) must be passed as the first argument
+ to <c>format/1,2</c>.</p>
+ <p>Wrap logs can be formatted one by one or all at once. To
+ format one of the wrap logs in a set, specify the exact file name.
+ To format the whole set of wrap logs, specify the name with <c>*</c>
+ instead of the wrap count.
</p>
+ <p><em>Example:</em></p>
<p>Start tracing:</p>
- <code type="none">
-(tiger@durin)1> ttb:tracer(node(),{file,{wrap,"trace"}}).
+ <pre>
+(tiger@durin)1> <input>ttb:tracer(node(),{file,{wrap,"trace"}}).</input>
{ok,[tiger@durin]}
-(tiger@durin)2> ttb:p(...)
-... </code>
- <p>This will give a set of binary logs, like:</p>
+(tiger@durin)2> <input>ttb:p(...)</input>
+...</pre>
+ <p>This gives a set of binary logs, for example:</p>
<code type="none">
... </code>
<p>Format the whole set of logs:</p>
- <code type="none">
-1> ttb:format("tiger@durin-trace.*.wrp").
+ <pre>
+1> <input>ttb:format("tiger@durin-trace.*.wrp").</input>
....
ok
-2> </code>
+2> </pre>
<p>Format only the first log:</p>
- <code type="none">
-1> ttb:format("[email protected]").
+ <pre>
+1> <input>ttb:format("[email protected]").</input>
....
ok
-2> </code>
+2> </pre>
<p>To merge all wrap logs from two nodes:</p>
- <code type="none">
-1> ttb:format(["tiger@durin-trace.*.wrp","lion@durin-trace.*.wrp"]).
+ <pre>
+1> <input>ttb:format(["tiger@durin-trace.*.wrp","lion@durin-trace.*.wrp"]).</input>
....
ok
-2> </code>
+2> </pre>
<section>
<marker id="et_viewer"></marker>
- <title>Presenting trace logs with Event Tracer</title>
- <p>For detailed information about the Event Tracer, please turn
- to the User's Guide and Reference Manuals for the <c>et</c>
- application.
+ <title>Presenting Trace Logs with Event Tracer</title>
+ <p>For detailed information about the Event Tracer, see the
+ <seealso marker="et:users_guide">ET</seealso> application.
</p>
- <p>By giving the format handler <c>ttb:get_et_handler()</c>, you can have the
- trace log presented graphically with <c>et_viewer</c> in the
- Event Tracer application. <c>ttb</c> provides a few different
- filters which can be selected from the Filter menu in the
- <c>et_viewer</c> window. The filters are names according to the
- type of actors they present (i.e. what each vertical line in the
- sequence diagram represent). Interaction between actors is shown
- as red arrows between two vertical lines, and activities within
- an actor are shown as blue text to the right of the actors line.
+ <p>By giving the format handler
+ <seealso marker="ttb#get_et_handler/0"><c>ttb:get_et_handler()</c></seealso>,
+ you can have the trace log presented graphically with
+ <c>et_viewer</c> in the ET application.
+ <c>ttb</c> provides filters that can be selected from the
+ menu <em>Filter</em> in the <c>et_viewer</c> window. The filters
+ are names according to the type of actors they present
+ (that is, what each vertical line in the sequence diagram represents).
+ Interaction between actors is shown as red arrows between two
+ vertical lines, and activities within an actor are shown as
+ blue text to the right of the actors line.
</p>
- <p>The <c>processes</c> filter is the only filter which will
- show all trace messages from a trace log. Each vertical line in
+ <p>The <c>processes</c> filter is the only filter showing all
+ trace messages from a trace log. Each vertical line in
the sequence diagram represents a process. Erlang messages,
- spawn and link/unlink are typical interactions between
- processes. Function calls, scheduling and garbage collection are
- typical activities within a process. <c>processes</c> is the
- default filter.
+ spawn, and link/unlink are typical interactions between
+ processes. Function calls, scheduling, and garbage collection,
+ are typical activities within a process. <c>processes</c> is
+ the default filter.
</p>
- <p>The rest of the filters will only show function calls and
+ <p>The remaining filters only show function calls and
function returns. All other trace message are discarded. To get
- the most out of these filters, <c>et_viewer</c> needs to known
+ the most out of these filters, <c>et_viewer</c> must know
the caller of each function and the time of return. This can be
- obtained by using both the <c>call</c> and <c>return_to</c>
- flags when tracing. Note that the <c>return_to</c> flag only
- works with local call trace, i.e. when trace patterns are set
+ obtained using both the <c>call</c> and <c>return_to</c>
+ flags when tracing. Notice that flag <c>return_to</c> only
+ works with local call trace, that is, when trace patterns are set
with <c>ttb:tpl</c>.
</p>
- <p>The same result can be obtained by using the <c>call</c> flag
- only and setting a match specification like this on local or
- global function calls:</p>
- <code type="none">
-1> dbg:fun2ms(fun(_) -> return_trace(),message(caller()) end).
-[{'_',[],[{return_trace},{message,{caller}}]}] </code>
- <p>This should however be done with care, since the
- <c>{return_trace}</c> function in the match specification will
- destroy tail recursiveness.
+ <p>The same result can be obtained by using the flag <c>call</c>
+ only and setting a match specification on local or
+ global function calls as follows:</p>
+ <pre>
+1> <input>dbg:fun2ms(fun(_) -> return_trace(),message(caller()) end).</input>
+[{'_',[],[{return_trace},{message,{caller}}]}]</pre>
+ <p>This must however be done with care, as function
+ <c>{return_trace}</c> in the match specification
+ destroys tail recursiveness.
</p>
<p>The <c>modules</c> filter shows each module as a vertical
line in the sequence diagram. External function calls/returns
- are shown as interactions between modules and internal function
+ are shown as interactions between modules, and internal function
calls/returns are shown as activities within a module.
</p>
<p>The <c>functions</c> filter shows each function as a vertical
@@ -655,9 +692,9 @@ ok
<p>The <c>mods_and_procs</c> and <c>funcs_and_procs</c> filters
are equivalent to the <c>modules</c> and <c>functions</c>
filters respectively, except that each module or function can
- have several vertical lines, one for each process it resides on.
+ have many vertical lines, one for each process it resides on.
</p>
- <p>In the next example, modules <c>foo</c> and <c>bar</c> are used:</p>
+ <p>In the following example, modules <c>foo</c> and <c>bar</c> are used:</p>
<code type="none">
-module(foo).
-export([start/0,go/0]).
@@ -672,8 +709,9 @@ go() ->
go ->
bar:f1(),
go()
- end.
-</code><code type="none">
+ end.</code>
+
+<code type="none">
-module(bar).
-export([f1/0,f3/0]).
f1() ->
@@ -684,57 +722,56 @@ f2() ->
f3() ->
ok.</code>
- <p>Now let's set up the trace.</p>
-<code>
-(tiger@durin)1>%%First we retrieve the Pid to limit traced processes set
-(tiger@durin)1>Pid = foo:start().
-(tiger@durin)2>%%Now we set up tracing
-(tiger@durin)2>ttb:tracer().
-(tiger@durin)3>ttb:p(Pid, [call, return_to, procs, set_on_spawn]).
-(tiger@durin)4>ttb:tpl(bar, []).
-(tiger@durin)5>%%Invoke our test function and see output with et viewer
-(tiger@durin)5>Pid ! go.
-(tiger@durin)6>ttb:stop({format, {handler, ttb:get_et_handler()}}).
-</code>
-
- <p>This should render a result similar to the
- following:
+ <p>Setting up the trace:</p>
+<pre>
+(tiger@durin)1> %%First we retrieve the Pid to limit traced processes set
+(tiger@durin)1> <input>Pid = foo:start().</input>
+(tiger@durin)2> %%Now we set up tracing
+(tiger@durin)2> <input>ttb:tracer().</input>
+(tiger@durin)3> <input>ttb:p(Pid, [call, return_to, procs, set_on_spawn]).</input>
+(tiger@durin)4> <input>ttb:tpl(bar, []).</input>
+(tiger@durin)5> %%Invoke our test function and see output with et viewer
+(tiger@durin)5> <input>Pid ! go.</input>
+(tiger@durin)6> <input>ttb:stop({format, {handler, ttb:get_et_handler()}}).</input></pre>
+
+ <p>This renders a result similar to the following:
</p>
- <p></p>
<image file="et_processes.gif">
<icaption>Filter: "processes"</icaption>
</image>
+ <p></p>
<image file="et_modsprocs.gif">
<icaption>Filter: "mods_and_procs"</icaption>
</image>
- <p>Note, that we can use <c>ttb:start_trace/4</c> function to help
- us here:</p>
-<code>
-(tiger@durin)1>Pid = foo:start().
-(tiger@durin)2>ttb:start_trace([node()],
- [{bar,[]}],
- {Pid, [call, return_to, procs, set_on_spawn]}
- {handler, ttb:get_et_handler()}).
-(tiger@durin)3>Pid ! go.
-(tiger@durin)4>ttb:stop(format).
-</code>
+ <p>Notice that function
+ <seealso marker="ttb#start_trace/4"><c>ttb:start_trace/4</c></seealso>
+ can be used as help as follows:</p>
+<pre>
+(tiger@durin)1> <input>Pid = foo:start().</input>
+(tiger@durin)2> <input>ttb:start_trace([node()],
+ [{bar,[]}],
+ {Pid, [call, return_to, procs, set_on_spawn]}
+ {handler, ttb:get_et_handler()}).</input>
+(tiger@durin)3> <input>Pid ! go.</input>
+(tiger@durin)4> <input>ttb:stop(format).</input></pre>
</section>
</section>
<section>
<marker id="fetch_format"></marker>
- <title>Automatically collect and format logs from all nodes</title>
- <p>By default <c>ttb:stop/1</c> fetches trace logs and
- trace information files from all nodes. The logs are stored in a
- new directory named <c>ttb_upload-Filename-Timestamp</c> under the working
- directory of the trace control node. Fetching may be disabled by
- providing the <c>nofetch</c> option to <c>ttb:stop/1</c>. User can
- specify a fetch directory of his choice passing the
- <c>{fetch_dir, Dir}</c> option.
+ <title>Automatically Collect and Format Logs from All Nodes</title>
+ <p>By default,
+
+ <seealso marker="ttb#stop/1"><c>ttb:stop/1</c></seealso> fetches trace logs
+ and trace information files from all nodes. The logs are stored in a
+ new directory named <c>ttb_upload-Filename-Timestamp</c> under the
+ working directory of the trace control node. Fetching can be disabled
+ by providing option <c>nofetch</c> to <c>ttb:stop/1</c>. The user can
+ specify a fetch directory by passing option <c>{fetch_dir, Dir}</c>.
</p>
- <p>If the option <c>format</c> is given to <c>ttb:stop/1</c>, the
+ <p>If option <c>format</c> is specified to <c>ttb:stop/1</c>, the
trace logs are automatically formatted after tracing is
stopped.
</p>
@@ -742,117 +779,122 @@ f3() ->
<section>
<title>History and Configuration Files</title>
- <p>For the tracing functionality, <c>dbg</c> could be used instead
- of the <c>ttb</c> for setting trace flags on processes and trace
- patterns for call trace, i.e. the functions <c>p</c>, <c>tp</c>,
- <c>tpl</c>, <c>ctp</c>, <c>ctpl</c> and <c>ctpg</c>. There are only
- two things added by <c>ttb</c> for these functions:
+ <p>For the tracing functionality,
+ <seealso marker="runtime_tools:dbg"><c>dbg</c></seealso>
+ can be used instead
+ of <c>ttb</c> for setting trace flags on processes and trace
+ patterns for call trace, that is, the functions
+ <c>p</c>, <c>tp</c>, <c>tpl</c>, <c>ctp</c>, <c>ctpl</c>, and <c>ctpg</c>. Only the
+ following two things are added by <c>ttb</c> for these functions:</p>
<list type="bulleted">
- <item>all calls are stored in the history buffer and can be
+ <item>All calls are stored in the history buffer and can be
recalled and stored in a configuration file. This makes it
- easy to setup the same trace environment e.g. if you want to
- compare two test runs. It also reduces the amount of
- typing when using <c>ttb</c> from the erlang shell;</item>
- <item>shortcuts are provided for the most common match
- specifications (in order not to force the user to use
- <c>dbg:fun2ms</c> continually</item>).
+ easy to set up the same trace environment, for example, if you
+ want to compare two test runs. It also reduces the amount of
+ typing when using <c>ttb</c> from the Erlang shell.</item>
+ <item>Shortcuts are provided for the most common match
+ specifications (to not force you to use
+ <seealso marker="runtime_tools:dbg#fun2ms/1"><c>dbg:fun2ms</c></seealso>
+ continually).</item>
</list>
- </p>
- <p>Use <c>list_history/0</c> to see the content of the history
- buffer, and <c>run_history/1</c> to re-execute one of the entries.
+ <p>Use
+ <seealso marker="ttb#list_history/0"><c>ttb:list_history/0</c></seealso>
+ to see the content of the history buffer and
+ <seealso marker="ttb#run_history/1"><c>ttb:run_history/1</c></seealso>
+ to re-execute one of the entries.
</p>
<p>The main purpose of the history buffer is the possibility to
create configuration files. Any function stored in the history
buffer can be written to a configuration file and used for
- creating a specific configuration at any time with one single
+ creating a specific configuration at any time with a single
function call.
</p>
<p>A configuration file is created or extended with
- <c>write_config/2/3</c>. Configuration files are binary files
+ <seealso marker="ttb#write_config/2"><c>ttb:write_config/2,3</c></seealso>.
+ Configuration files are binary files
and can therefore only be read and written with functions provided
by <c>ttb</c>.
</p>
- <p>You can write the complete content of the history buffer to a
- config file by calling
- <c>ttb:write_config(ConfigFile,all)</c>. And you can write
- selected entries from the history by calling
+ <p>The complete content of the history buffer can be written to a
+ configuration file by calling
+ <c>ttb:write_config(ConfigFile,all)</c>. Selected entries from
+ the history can be written by calling
<c>ttb:write_config(ConfigFile,NumList)</c>, where
<c>NumList</c> is a list of integers pointing out the history
entries to write. Moreover, the history buffer is always dumped
- to <c>ttb_last_config</c> when <c>ttb:stop/0/1</c> is called.
+ to <c>ttb_last_config</c> when <c>ttb:stop/0,1</c> is called.
</p>
- <p>User defined entries can also be written to a config file by
- calling the function
- <c>ttb:write_config(ConfigFile,ConfigList)</c> where
+ <p>User-defined entries can also be written to a configuration file
+ by calling function
+ <c>ttb:write_config(ConfigFile,ConfigList)</c>, where
<c>ConfigList</c> is a list of <c>{Module,Function,Args}</c>.
</p>
<p>Any existing file <c>ConfigFile</c> is deleted and a new file
- is created when <c>write_config/2</c> is called. The option
- <c>append</c> can be used if you wish to add something at the end
- of an existing config file, e.g.
+ is created when <c>write_config/2</c> is called. Option
+ <c>append</c> can be used to add something at the end
+ of an existing configuration file, for example,
<c>ttb:write_config(ConfigFile,What,[append])</c>.
</p>
- <section>
- <title>Example: History and configuration files</title>
- <p>See the content of the history buffer</p>
- <code type="none"><![CDATA[
-(tiger@durin)191> ttb:tracer().
+ <p><em>Example:</em></p>
+ <p>See the content of the history buffer:</p>
+ <pre>
+(tiger@durin)191> <input>ttb:tracer().</input>
{ok,[tiger@durin]}
-(tiger@durin)192> ttb:p(self(),[garbage_collection,call]).
-{ok,{[<0.1244.0>],[garbage_collection,call]}}
-(tiger@durin)193> ttb:tp(ets,new,2,[]).
+(tiger@durin)192> <input>ttb:p(self(),[garbage_collection,call]).</input>
+{ok,{[&lt;0.1244.0>],[garbage_collection,call]}}
+(tiger@durin)193> <input>ttb:tp(ets,new,2,[]).</input>
{ok,[{matched,1}]}
-(tiger@durin)194> ttb:list_history().
+(tiger@durin)194> <input>ttb:list_history().</input>
[{1,{ttb,tracer,[tiger@durin,[]]}},
- {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
- {3,{ttb,tp,[ets,new,2,[]]}}] ]]></code>
+ {2,{ttb,p,[&lt;0.1244.0>,[garbage_collection,call]]}},
+ {3,{ttb,tp,[ets,new,2,[]]}}]</pre>
<p>Execute an entry from the history buffer:</p>
- <code type="none"><![CDATA[
-(tiger@durin)195> ttb:ctp(ets,new,2).
+ <pre>
+(tiger@durin)195> <input>ttb:ctp(ets,new,2).</input>
{ok,[{matched,1}]}
-(tiger@durin)196> ttb:list_history().
+(tiger@durin)196> <input>ttb:list_history().</input>
[{1,{ttb,tracer,[tiger@durin,[]]}},
- {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
+ {2,{ttb,p,[&lt;0.1244.0>,[garbage_collection,call]]}},
{3,{ttb,tp,[ets,new,2,[]]}},
{4,{ttb,ctp,[ets,new,2]}}]
-(tiger@durin)197> ttb:run_history(3).
+(tiger@durin)197> <input>ttb:run_history(3).</input>
ttb:tp(ets,new,2,[]) ->
-{ok,[{matched,1}]} ]]></code>
+{ok,[{matched,1}]}</pre>
<p>Write the content of the history buffer to a configuration
file:</p>
- <code type="none"><![CDATA[
-(tiger@durin)198> ttb:write_config("myconfig",all).
+ <pre>
+(tiger@durin)198> <input>ttb:write_config("myconfig",all).</input>
ok
-(tiger@durin)199> ttb:list_config("myconfig").
+(tiger@durin)199> <input>ttb:list_config("myconfig").</input>
[{1,{ttb,tracer,[tiger@durin,[]]}},
- {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
+ {2,{ttb,p,[&lt;0.1244.0>,[garbage_collection,call]]}},
{3,{ttb,tp,[ets,new,2,[]]}},
{4,{ttb,ctp,[ets,new,2]}},
- {5,{ttb,tp,[ets,new,2,[]]}}] ]]></code>
+ {5,{ttb,tp,[ets,new,2,[]]}}]</pre>
<p>Extend an existing configuration:</p>
- <code type="none"><![CDATA[
-(tiger@durin)200> ttb:write_config("myconfig",[{ttb,tp,[ets,delete,1,[]]}],
-[append]).
+ <pre>
+(tiger@durin)200> <input>ttb:write_config("myconfig",[{ttb,tp,[ets,delete,1,[]]}],
+[append]).</input>
ok
-(tiger@durin)201> ttb:list_config("myconfig").
+(tiger@durin)201> <input>ttb:list_config("myconfig").</input>
[{1,{ttb,tracer,[tiger@durin,[]]}},
- {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
+ {2,{ttb,p,[&lt;0.1244.0>,[garbage_collection,call]]}},
{3,{ttb,tp,[ets,new,2,[]]}},
{4,{ttb,ctp,[ets,new,2]}},
{5,{ttb,tp,[ets,new,2,[]]}},
- {6,{ttb,tp,[ets,delete,1,[]]}}] ]]></code>
+ {6,{ttb,tp,[ets,delete,1,[]]}}]</pre>
<p>Go back to a previous configuration after stopping Trace Tool
Builder:</p>
- <code type="none"><![CDATA[
-(tiger@durin)202> ttb:stop().
+ <pre>
+(tiger@durin)202> <input>ttb:stop().</input>
ok
-(tiger@durin)203> ttb:run_config("myconfig").
+(tiger@durin)203> <input>ttb:run_config("myconfig").</input>
ttb:tracer(tiger@durin,[]) ->
{ok,[tiger@durin]}
-ttb:p(<0.1244.0>,[garbage_collection,call]) ->
-{ok,{[<0.1244.0>],[garbage_collection,call]}}
+ttb:p(&lt;0.1244.0>,[garbage_collection,call]) ->
+{ok,{[&lt;0.1244.0>],[garbage_collection,call]}}
ttb:tp(ets,new,2,[]) ->
{ok,[{matched,1}]}
@@ -866,133 +908,135 @@ ttb:tp(ets,new,2,[]) ->
ttb:tp(ets,delete,1,[]) ->
{ok,[{matched,1}]}
-ok ]]></code>
+ok</pre>
<p>Write selected entries from the history buffer to a
configuration file:</p>
- <code type="none"><![CDATA[
-(tiger@durin)204> ttb:list_history().
+ <pre>
+(tiger@durin)204> <input>ttb:list_history().</input>
[{1,{ttb,tracer,[tiger@durin,[]]}},
- {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
+ {2,{ttb,p,[&lt;0.1244.0>,[garbage_collection,call]]}},
{3,{ttb,tp,[ets,new,2,[]]}},
{4,{ttb,ctp,[ets,new,2]}},
{5,{ttb,tp,[ets,new,2,[]]}},
{6,{ttb,tp,[ets,delete,1,[]]}}]
-(tiger@durin)205> ttb:write_config("myconfig",[1,2,3,6]).
+(tiger@durin)205> <input>ttb:write_config("myconfig",[1,2,3,6]).</input>
ok
-(tiger@durin)206> ttb:list_config("myconfig").
+(tiger@durin)206> <input>ttb:list_config("myconfig").</input>
[{1,{ttb,tracer,[tiger@durin,[]]}},
- {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
+ {2,{ttb,p,[&lt;0.1244.0>,[garbage_collection,call]]}},
{3,{ttb,tp,[ets,new,2,[]]}},
{4,{ttb,tp,[ets,delete,1,[]]}}]
-(tiger@durin)207> ]]></code>
- </section>
+(tiger@durin)207></pre>
</section>
<section>
<title>Sequential Tracing</title>
<p>To learn what sequential tracing is and how it can be used,
- please turn to the reference manual for the
- <em><c>seq_trace</c></em> module in the <em><c>kernel</c></em>
- application.
+ see the Reference Manual for
+ <seealso marker="kernel:seq_trace"><c>seq_trace</c></seealso>.
</p>
- <p>The support for sequential tracing provided by the Trace Tool
- Builder includes </p>
+ <p>The support for sequential tracing provided by Trace Tool
+ Builder includes the following:</p>
<list type="bulleted">
<item>Initiation of the system tracer. This is automatically
- done when a trace port is started with <c>ttb:tracer/0/1/2</c></item>
- <item>Creation of match specifications which activates
- sequential tracing</item>
+ done when a trace port is started with
+ <seealso marker="ttb#tracer/0"><c>ttb:tracer/0,1,2</c></seealso>.</item>
+ <item>Creation of match specifications that activates
+ sequential tracing.</item>
</list>
- <p>Starting sequential tracing requires that a tracer has been
- started with the <c>ttb:tracer/0/1/2</c> function. Sequential
- tracing can then either be started via a trigger function with a
- match specification created with <c>ttb:seq_trigger_ms/0/1</c>,
- or directly by using the <c>seq_trace</c> module in the
- <c>kernel</c> application.
+ <p>Starting sequential tracing requires that a tracer is
+ started with function <c>ttb:tracer/0,1,2</c>. Sequential
+ tracing can then be started in either of the following ways:
</p>
+ <list type="bulleted">
+ <item>Through a trigger function with a match specification
+ created with
+ <seealso marker="ttb#seq_trigger_ms/0"><c>ttb:seq_trigger_ms/0,1</c></seealso>.</item>
+ <item>Directly by using module
+ <seealso marker="kernel:seq_trace"><c>seq_trace</c></seealso>.</item>
+ </list>
- <section>
- <title>Example: Sequential tracing</title>
- <p>In the following example, the function
+ <p><em>Example 1:</em></p>
+ <p>In the following example, function
<c>dbg:get_tracer/0</c> is used as trigger for sequential
tracing:</p>
- <code type="none"><![CDATA[
-(tiger@durin)110> ttb:tracer().
+ <pre>
+(tiger@durin)110> <input>ttb:tracer().</input>
{ok,[tiger@durin]}
-(tiger@durin)111> ttb:p(self(),call).
-{ok,{[<0.158.0>],[call]}}
-(tiger@durin)112> ttb:tp(dbg,get_tracer,0,ttb:seq_trigger_ms(send)).
+(tiger@durin)111> <input>ttb:p(self(),call).</input>
+{ok,{[&lt;0.158.0>],[call]}}
+(tiger@durin)112> <input>ttb:tp(dbg,get_tracer,0,ttb:seq_trigger_ms(send)).</input>
{ok,[{matched,1},{saved,1}]}
-(tiger@durin)113> dbg:get_tracer(), seq_trace:reset_trace().
+(tiger@durin)113> <input>dbg:get_tracer(), seq_trace:reset_trace().</input>
true
-(tiger@durin)114> ttb:stop(format).
-({<0.158.0>,{shell,evaluator,3},tiger@durin}) call dbg:get_tracer()
-SeqTrace [0]: ({<0.158.0>,{shell,evaluator,3},tiger@durin})
-{<0.237.0>,dbg,tiger@durin} ! {<0.158.0>,{get_tracer,tiger@durin}}
+(tiger@durin)114> <input>ttb:stop(format).</input>
+({&lt;0.158.0>,{shell,evaluator,3},tiger@durin}) call dbg:get_tracer()
+SeqTrace [0]: ({&lt;0.158.0>,{shell,evaluator,3},tiger@durin})
+{&lt;0.237.0>,dbg,tiger@durin} ! {&lt;0.158.0>,{get_tracer,tiger@durin}}
[Serial: {0,1}]
-SeqTrace [0]: ({<0.237.0>,dbg,tiger@durin})
-{<0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port<0.222>}}
+SeqTrace [0]: ({&lt;0.237.0>,dbg,tiger@durin})
+{&lt;0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port&lt;0.222>}}
[Serial: {1,2}]
ok
-(tiger@durin)116> ]]></code>
- <p>Starting sequential tracing with a trigger is actually more
+(tiger@durin)116></pre>
+ <p><em>Example 2:</em></p>
+ <p>Starting sequential tracing with a trigger is more
useful if the trigger function is not called directly from the
shell, but rather implicitly within a larger system. When
calling a function from the shell, it is simpler to start
- sequential tracing directly, e.g.</p>
- <code type="none"><![CDATA[
-(tiger@durin)116> ttb:tracer().
+ sequential tracing directly, for example, as follows:</p>
+ <pre>
+(tiger@durin)116> <input>ttb:tracer().</input>
{ok,[tiger@durin]}
-(tiger@durin)117> seq_trace:set_token(send,true), dbg:get_tracer(),
-seq_trace:reset_trace().
+(tiger@durin)117> <input>seq_trace:set_token(send,true), dbg:get_tracer(),
+seq_trace:reset_trace().</input>
true
-(tiger@durin)118> ttb:stop(format).
-SeqTrace [0]: ({<0.158.0>,{shell,evaluator,3},tiger@durin})
-{<0.246.0>,dbg,tiger@durin} ! {<0.158.0>,{get_tracer,tiger@durin}}
+(tiger@durin)118> <input>ttb:stop(format).</input>
+SeqTrace [0]: ({&lt;0.158.0>,{shell,evaluator,3},tiger@durin})
+{&lt;0.246.0>,dbg,tiger@durin} ! {&lt;0.158.0>,{get_tracer,tiger@durin}}
[Serial: {0,1}]
-SeqTrace [0]: ({<0.246.0>,dbg,tiger@durin})
-{<0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port<0.229>}}
+SeqTrace [0]: ({&lt;0.246.0>,dbg,tiger@durin})
+{&lt;0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port&lt;0.229>}}
[Serial: {1,2}]
ok
-(tiger@durin)120> ]]></code>
- <p>In both examples above, the <c>seq_trace:reset_trace/0</c>
- resets the trace token immediately after the traced function in
- order to avoid lots of trace messages due to the printouts in
- the erlang shell.
+(tiger@durin)120></pre>
+ <p>In both previous examples, <c>seq_trace:reset_trace/0</c>
+ resets the trace token immediately after the traced function
+ to avoid many trace messages because of the printouts in
+ the Erlang shell.
</p>
- <p>All functions in the <c>seq_trace</c> module, except
- <c>set_system_tracer/1</c>, can be used after the trace port has
- been started with <c>ttb:tracer/0/1/2</c>.
+ <p>All functions in module <c>seq_trace</c>, except
+ <c>set_system_tracer/1</c>, can be used after the trace port
+ is started with <c>ttb:tracer/0,1,2</c>.
</p>
- </section>
</section>
<section>
- <title>Example: Multipurpose trace tool</title>
- <p>The module <c>multitrace.erl</c> which can be found in the
- <c>src</c> directory of the Observer application implements a
+ <title>Multipurpose Trace Tool</title>
+ <p>Module <c>multitrace</c> in
+ directory <c>src</c> of the Observer application provides a
small tool with three possible trace settings. The trace messages
- are written to binary files which can be formatted with the
- function <em><c>multitrace:format/1/2</c></em>.
+ are written to binary files, which can be formatted with
+ function <c>multitrace:format/1,2</c>:
</p>
<taglist>
- <tag><em><c>multitrace:debug(What)</c></em></tag>
- <item>Start calltrace on all processes and trace the given
+ <tag><c>multitrace:debug(What)</c></tag>
+ <item><p>Start calltrace on all processes and trace the specified
function(s). The format handler used is
- <c>multitrace:handle_debug/4</c> which prints each call and
- return. <c>What</c> must be an item or a list of items to trace,
- given on the format <c>{Module,Function,Arity}</c>,
- <c>{Module,Function}</c> or just <c>Module</c>.</item>
- <tag><em><c>multitrace:gc(Procs)</c></em></tag>
- <item>Trace garbage collection on the given process(es). The
- format handler used is <c>multitrace:handle_gc/4</c> which
- prints start and stop and the time spent for each GC.</item>
- <tag><em><c>multitrace:schedule(Procs)</c></em></tag>
- <item>Trace in- and out-scheduling on the given process(es). The
- format handler used is <c>multitrace:handle_schedule/4</c> which
- prints each in and out scheduling with process, timestamp and
+ <c>multitrace:handle_debug/4</c> that prints each call and
+ returns. <c>What</c> must be an item or a list of items to trace,
+ specified on the format <c>{Module,Function,Arity}</c>,
+ <c>{Module,Function}</c>, or only <c>Module</c>.</p></item>
+ <tag><c>multitrace:gc(Procs)</c></tag>
+ <item><p>Trace garbage collection on the specified process(es). The
+ format handler used is <c>multitrace:handle_gc/4</c> that
+ prints start, stop, and the time spent for each garbage collection.</p></item>
+ <tag><c>multitrace:schedule(Procs)</c></tag>
+ <item><p>Trace in-scheduling and out-scheduling on the specified process(es).
+ The format handler used is <c>multitrace:handle_schedule/4</c> that
+ prints each in-scheduling and out-scheduling with process, time-stamp, and
current function. It also prints the total time each traced
- process was scheduled in.</item>
+ process was scheduled in.</p></item>
</taglist>
</section>
</chapter>
diff --git a/lib/observer/include/etop.hrl b/lib/observer/include/etop.hrl
index 83b5a287f1..0dac322a2b 100644
--- a/lib/observer/include/etop.hrl
+++ b/lib/observer/include/etop.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile
index c120865213..2d42510b47 100644
--- a/lib/observer/src/Makefile
+++ b/lib/observer/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -51,6 +52,7 @@ MODULES= \
cdv_multi_wx \
cdv_port_cb \
cdv_proc_cb \
+ cdv_sched_cb \
cdv_table_wx \
cdv_term_cb \
cdv_timer_cb \
@@ -61,6 +63,7 @@ MODULES= \
etop_txt \
observer \
observer_app_wx \
+ observer_alloc_wx \
observer_html_lib \
observer_lib \
observer_perf_wx \
diff --git a/lib/observer/src/cdv_atom_cb.erl b/lib/observer/src/cdv_atom_cb.erl
index 46fce81b52..0f0c397479 100644
--- a/lib/observer/src/cdv_atom_cb.erl
+++ b/lib/observer/src/cdv_atom_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_atom_cb).
diff --git a/lib/observer/src/cdv_bin_cb.erl b/lib/observer/src/cdv_bin_cb.erl
index d5fbceff1e..7e17ef135e 100644
--- a/lib/observer/src/cdv_bin_cb.erl
+++ b/lib/observer/src/cdv_bin_cb.erl
@@ -3,28 +3,29 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_bin_cb).
--export([get_details/1,
+-export([get_details/2,
detail_pages/0]).
%% Callbacks for cdv_detail_wx
-get_details({Type, {T,Key}}) ->
+get_details({Type, {T,Key}}, _) ->
[{Key,Term}] = ets:lookup(T,Key),
{ok,{"Expanded Binary", {Type, Term}, []}};
-get_details({cdv, Id}) ->
+get_details({cdv, Id}, _) ->
{ok,Bin} = crashdump_viewer:expand_binary(Id),
{ok,{"Expanded Binary", {cvd, Bin}, []}}.
diff --git a/lib/observer/src/cdv_detail_wx.erl b/lib/observer/src/cdv_detail_wx.erl
index dc93507a36..d53b721141 100644
--- a/lib/observer/src/cdv_detail_wx.erl
+++ b/lib/observer/src/cdv_detail_wx.erl
@@ -3,23 +3,24 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_detail_wx).
-behaviour(wx_object).
--export([start_link/3]).
+-export([start_link/4]).
-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3,
handle_call/3, handle_info/2]).
@@ -38,13 +39,13 @@
-define(ID_NOTEBOOK, 604).
%% Detail view
-start_link(Id, ParentFrame, Callback) ->
- wx_object:start_link(?MODULE, [Id, ParentFrame, Callback, self()], []).
+start_link(Id, Data, ParentFrame, Callback) ->
+ wx_object:start_link(?MODULE, [Id, Data, ParentFrame, Callback, self()], []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([Id, ParentFrame, Callback, Parent]) ->
- case Callback:get_details(Id) of
+init([Id, Data, ParentFrame, Callback, Parent]) ->
+ case Callback:get_details(Id, Data) of
{ok,Details} ->
init(Id,ParentFrame,Callback,Parent,Details);
{yes_no, Info, Fun} ->
diff --git a/lib/observer/src/cdv_dist_cb.erl b/lib/observer/src/cdv_dist_cb.erl
index f7e6c9aded..9c53ec86bc 100644
--- a/lib/observer/src/cdv_dist_cb.erl
+++ b/lib/observer/src/cdv_dist_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_dist_cb).
@@ -21,7 +22,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0,
format/1]).
@@ -55,10 +56,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_CH,?COL_CTRL],true}.
+ {[{node, ?COL_CH},{port,?COL_CTRL}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _) ->
case crashdump_viewer:node_info(Id) of
{ok,Info,TW} ->
Proplist = crashdump_viewer:to_proplist(record_info(fields,nod),Info),
diff --git a/lib/observer/src/cdv_ets_cb.erl b/lib/observer/src/cdv_ets_cb.erl
index 2a5c170e58..bac8b56fc3 100644
--- a/lib/observer/src/cdv_ets_cb.erl
+++ b/lib/observer/src/cdv_ets_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_ets_cb).
@@ -20,7 +21,10 @@
-export([col_to_elem/1,
col_spec/0,
get_info/1,
- get_detail_cols/1]).
+ get_details/2,
+ get_detail_cols/1,
+ detail_pages/0
+ ]).
-include_lib("wx/include/wx.hrl").
-include("crashdump_viewer.hrl").
@@ -41,7 +45,7 @@ col_to_elem(?COL_ID) -> #ets_table.id;
col_to_elem(?COL_NAME) -> #ets_table.name;
col_to_elem(?COL_SLOT) -> #ets_table.slot;
col_to_elem(?COL_OWNER) -> #ets_table.pid;
-col_to_elem(?COL_TYPE) -> #ets_table.type;
+col_to_elem(?COL_TYPE) -> #ets_table.data_type;
col_to_elem(?COL_BUCK) -> #ets_table.buckets;
col_to_elem(?COL_OBJ) -> #ets_table.size;
col_to_elem(?COL_MEM) -> #ets_table.memory.
@@ -50,18 +54,68 @@ col_spec() ->
[{"Id", ?wxLIST_FORMAT_LEFT, 200},
{"Name", ?wxLIST_FORMAT_LEFT, 200},
{"Slot", ?wxLIST_FORMAT_RIGHT, 50},
- {"Owner", ?wxLIST_FORMAT_CENTRE, 90},
- {"Buckets", ?wxLIST_FORMAT_RIGHT, 50},
- {"Objects", ?wxLIST_FORMAT_RIGHT, 50},
- {"Memory", ?wxLIST_FORMAT_RIGHT, 80},
- {"Type", ?wxLIST_FORMAT_LEFT, 50}
+ {"Owner", ?wxLIST_FORMAT_CENTRE, 120},
+ {"Objects", ?wxLIST_FORMAT_RIGHT, 80},
+ {"Memory", ?wxLIST_FORMAT_RIGHT, 80}
+% {"Type", ?wxLIST_FORMAT_LEFT, 50}
].
get_info(Owner) ->
{ok,Info,TW} = crashdump_viewer:ets_tables(Owner),
{Info,TW}.
+%% Callbacks for cdv_detail_wx
+get_details(_Id, not_found) ->
+ Info = "The table you are searching for could not be found.",
+ {info,Info};
+get_details(Id, Data) ->
+ Proplist = crashdump_viewer:to_proplist(record_info(fields,ets_table),Data),
+ {ok,{"Table:" ++ Id,Proplist,""}}.
+
get_detail_cols(all) ->
- {[?COL_OWNER],false};
-get_detail_cols(_) ->
- {[],false}.
+ {[{ets, ?COL_ID}, {process, ?COL_OWNER}],true};
+get_detail_cols(_W) ->
+ {[],true}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+detail_pages() ->
+ [{"Table Information", fun init_gen_page/2}].
+
+init_gen_page(Parent, Info0) ->
+ Fields = info_fields(),
+ Details = proplists:get_value(details, Info0),
+ Info = if is_map(Details) -> Info0 ++ maps:to_list(Details);
+ true -> Info0
+ end,
+ cdv_info_wx:start_link(Parent,{Fields,Info,[]}).
+
+%%% Internal
+info_fields() ->
+ [{"Overview",
+ [{"Id", id},
+ {"Name", name},
+ {"Slot", slot},
+ {"Owner", pid},
+ {"Data Structure", data_type}
+ ]},
+ {"Settings",
+ [{"Type", type},
+ {"Protection", protection},
+ {"Compressed", compressed},
+ {"Fixed", fixed},
+ {"Lock write concurrency", write_c},
+ {"Lock read concurrency", read_c}
+ ]},
+ {"Memory Usage",
+ [{"Buckets", buckets},
+ {"Size", size},
+ {"Memory", memory},
+ {"Min Chain Length", chain_min},
+ {"Avg Chain Length", chain_avg},
+ {"Max Chain Length", chain_max},
+ {"Chain Length Std Dev", chain_stddev},
+ {"Chain Length Expected Std Dev", chain_exp_stddev}
+ ]}
+ ].
diff --git a/lib/observer/src/cdv_fun_cb.erl b/lib/observer/src/cdv_fun_cb.erl
index 689ef0e3bb..3a62eb3305 100644
--- a/lib/observer/src/cdv_fun_cb.erl
+++ b/lib/observer/src/cdv_fun_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_fun_cb).
@@ -55,4 +56,4 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_MOD],false}.
+ {[{module, ?COL_MOD}],false}.
diff --git a/lib/observer/src/cdv_gen_cb.erl b/lib/observer/src/cdv_gen_cb.erl
index 6be717d76d..69ecfbe80e 100644
--- a/lib/observer/src/cdv_gen_cb.erl
+++ b/lib/observer/src/cdv_gen_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_gen_cb).
@@ -42,4 +43,6 @@ info_fields() ->
{"Processes",num_procs},
{"ETS tables",num_ets},
{"Timers",num_timers},
- {"Funs",num_fun}]}].
+ {"Funs",num_fun},
+ {"Calling Thread", thread}
+ ]}].
diff --git a/lib/observer/src/cdv_html_wx.erl b/lib/observer/src/cdv_html_wx.erl
index b79c647f63..70f0d02982 100644
--- a/lib/observer/src/cdv_html_wx.erl
+++ b/lib/observer/src/cdv_html_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_html_wx).
@@ -126,7 +127,7 @@ expand(Id,Callback,#state{expand_wins=Opened0}=State) ->
Opened =
case lists:keyfind(Id,1,Opened0) of
false ->
- EW = cdv_detail_wx:start_link(Id,State#state.panel,Callback),
+ EW = cdv_detail_wx:start_link(Id,[],State#state.panel,Callback),
wx_object:get_pid(EW) ! active,
[{Id,EW}|Opened0];
{_,EW} ->
diff --git a/lib/observer/src/cdv_info_wx.erl b/lib/observer/src/cdv_info_wx.erl
index 59ce0cabb1..13c80942ac 100644
--- a/lib/observer/src/cdv_info_wx.erl
+++ b/lib/observer/src/cdv_info_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_info_wx).
diff --git a/lib/observer/src/cdv_int_tab_cb.erl b/lib/observer/src/cdv_int_tab_cb.erl
index 31727391fe..c48fbb6ee1 100644
--- a/lib/observer/src/cdv_int_tab_cb.erl
+++ b/lib/observer/src/cdv_int_tab_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_int_tab_cb).
diff --git a/lib/observer/src/cdv_mem_cb.erl b/lib/observer/src/cdv_mem_cb.erl
index 2b0809df13..bfe21bf309 100644
--- a/lib/observer/src/cdv_mem_cb.erl
+++ b/lib/observer/src/cdv_mem_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_mem_cb).
diff --git a/lib/observer/src/cdv_mod_cb.erl b/lib/observer/src/cdv_mod_cb.erl
index e829ff4fca..2e41699c5a 100644
--- a/lib/observer/src/cdv_mod_cb.erl
+++ b/lib/observer/src/cdv_mod_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_mod_cb).
@@ -21,7 +22,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0,
format/1]).
@@ -49,10 +50,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_ID],true}.
+ {[{module, ?COL_ID}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _) ->
{ok,Info,TW} = crashdump_viewer:loaded_mod_details(Id),
Proplist = crashdump_viewer:to_proplist(record_info(fields,loaded_mod),Info),
Title = io_lib:format("~s",[Info#loaded_mod.mod]),
diff --git a/lib/observer/src/cdv_multi_wx.erl b/lib/observer/src/cdv_multi_wx.erl
index 75c7f48fc2..13b980b5ea 100644
--- a/lib/observer/src/cdv_multi_wx.erl
+++ b/lib/observer/src/cdv_multi_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_multi_wx).
diff --git a/lib/observer/src/cdv_port_cb.erl b/lib/observer/src/cdv_port_cb.erl
index 08488d3e34..7dbe6d7819 100644
--- a/lib/observer/src/cdv_port_cb.erl
+++ b/lib/observer/src/cdv_port_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_port_cb).
@@ -21,7 +22,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0,
format/1]).
@@ -57,10 +58,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_ID,?COL_CONN],true}.
+ {[{port, ?COL_ID},{process, ?COL_CONN}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _Data) ->
case crashdump_viewer:port(Id) of
{ok,Info,TW} ->
Proplist =
@@ -70,7 +71,7 @@ get_details(Id) ->
Info = "The port you are searching for was residing on "
"a remote node. No port information is available. "
"Show information about the remote node?",
- Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId) end,
+ Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId, node) end,
{yes_no, Info, Fun};
{error,not_found} ->
Info = "The port you are searching for could not be found.",
diff --git a/lib/observer/src/cdv_proc_cb.erl b/lib/observer/src/cdv_proc_cb.erl
index dfc2df9c4c..90f6715a06 100644
--- a/lib/observer/src/cdv_proc_cb.erl
+++ b/lib/observer/src/cdv_proc_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_proc_cb).
@@ -21,7 +22,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0]).
-include_lib("wx/include/wx.hrl").
@@ -57,10 +58,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_ID],true}.
+ {[{process, ?COL_ID}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _) ->
case crashdump_viewer:proc_details(Id) of
{ok,Info,TW} ->
%% The following table is used by observer_html_lib
@@ -76,7 +77,7 @@ get_details(Id) ->
Info = "The process you are searching for was residing on "
"a remote node. No process information is available. "
"Show information about the remote node?",
- Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId) end,
+ Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId, port) end,
{yes_no, Info, Fun};
{error,not_found} ->
Info = "The process you are searching for could not be found.",
@@ -126,10 +127,13 @@ info_fields() ->
{dynamic, current_func},
{"Registered Name", name},
{"Status", state},
+ {"Internal State", int_state},
{"Started", start_time},
{"Parent", {click,parent}},
{"Message Queue Len",msg_q_len},
+ {"Run queue", run_queue},
{"Reductions", reds},
+
{"Program counter", prog_count},
{"Continuation pointer",cp},
{"Arity",arity}]},
diff --git a/lib/observer/src/cdv_sched_cb.erl b/lib/observer/src/cdv_sched_cb.erl
new file mode 100644
index 0000000000..f236e6a159
--- /dev/null
+++ b/lib/observer/src/cdv_sched_cb.erl
@@ -0,0 +1,118 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(cdv_sched_cb).
+
+-export([col_to_elem/1,
+ col_spec/0,
+ get_info/1,
+ get_details/2,
+ get_detail_cols/1,
+ detail_pages/0
+ ]).
+
+-include_lib("wx/include/wx.hrl").
+-include("crashdump_viewer.hrl").
+
+%% Columns
+-define(COL_ID, 0).
+-define(COL_PROC, ?COL_ID+1).
+-define(COL_PORT, ?COL_PROC+1).
+-define(COL_RQL, ?COL_PORT+1).
+-define(COL_PQL, ?COL_RQL+1).
+
+%% Callbacks for cdv_virtual_list_wx
+col_to_elem(id) -> col_to_elem(?COL_ID);
+col_to_elem(?COL_ID) -> #sched.name;
+col_to_elem(?COL_PROC) -> #sched.process;
+col_to_elem(?COL_PORT) -> #sched.port;
+col_to_elem(?COL_RQL) -> #sched.run_q;
+col_to_elem(?COL_PQL) -> #sched.port_q.
+
+col_spec() ->
+ [{"Id", ?wxLIST_FORMAT_RIGHT, 50},
+ {"Current Process", ?wxLIST_FORMAT_CENTER, 130},
+ {"Current Port", ?wxLIST_FORMAT_CENTER, 130},
+ {"Run Queue Length", ?wxLIST_FORMAT_RIGHT, 180},
+ {"Port Queue Length", ?wxLIST_FORMAT_RIGHT, 180}].
+
+get_info(_) ->
+ {ok,Info,TW} = crashdump_viewer:schedulers(),
+ {Info,TW}.
+
+get_details(_Id, not_found) ->
+ Info = "The scheduler you are searching for could not be found.",
+ {info,Info};
+get_details(Id, Data) ->
+ Proplist = crashdump_viewer:to_proplist(record_info(fields,sched),Data),
+ {ok,{"Scheduler: " ++ Id,Proplist,""}}.
+
+get_detail_cols(all) ->
+ {[{sched, ?COL_ID}, {process, ?COL_PROC}, {process, ?COL_PORT}],true};
+get_detail_cols(_) ->
+ {[],false}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+detail_pages() ->
+ [{"Scheduler Information", fun init_gen_page/2}].
+
+init_gen_page(Parent, Info0) ->
+ Fields = info_fields(),
+ Details = proplists:get_value(details, Info0),
+ Info = if is_map(Details) -> Info0 ++ maps:to_list(Details);
+ true -> Info0
+ end,
+ cdv_info_wx:start_link(Parent,{Fields,Info,[]}).
+
+%%% Internal
+info_fields() ->
+ [{"Scheduler Overview",
+ [{"Id", id},
+ {"Current Process",process},
+ {"Current Port", port},
+ {"Sleep Info Flags", sleep_info},
+ {"Sleep Aux Work", sleep_aux}
+ ]},
+ {"Run Queues",
+ [{"Flags", runq_flags},
+ {"Priority Max Length", runq_max},
+ {"Priority High Length", runq_high},
+ {"Priority Normal Length", runq_norm},
+ {"Priority Low Length", runq_low},
+ {"Port Length", port_q}
+ ]},
+ {"Current Process",
+ [{"State", currp_state},
+ {"Internal State", currp_int_state},
+ {"Program Counter", currp_prg_cnt},
+ {"CP", currp_cp},
+ {"Stack", {currp_stack, 0}},
+ {" ", {currp_stack, 1}},
+ {" ", {currp_stack, 2}},
+ {" ", {currp_stack, 3}},
+ {" ", {currp_stack, 4}},
+ {" ", {currp_stack, 5}},
+ {" ", {currp_stack, 6}},
+ {" ", {currp_stack, 7}},
+ {" ", {currp_stack, 8}},
+ {" ", {currp_stack, 9}},
+ {" ", {currp_stack, 10}},
+ {" ", {currp_stack, 11}}
+ ]}
+ ].
diff --git a/lib/observer/src/cdv_table_wx.erl b/lib/observer/src/cdv_table_wx.erl
index f8943db17d..4e9c158ce3 100644
--- a/lib/observer/src/cdv_table_wx.erl
+++ b/lib/observer/src/cdv_table_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_table_wx).
diff --git a/lib/observer/src/cdv_term_cb.erl b/lib/observer/src/cdv_term_cb.erl
index 4451045012..155cde2cd0 100644
--- a/lib/observer/src/cdv_term_cb.erl
+++ b/lib/observer/src/cdv_term_cb.erl
@@ -3,25 +3,26 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_term_cb).
--export([get_details/1,
+-export([get_details/2,
detail_pages/0]).
%% Callbacks for cdv_detail_wx
-get_details({Type, {T,Key}}) ->
+get_details({Type, {T,Key}}, _) ->
[{Key,Term}] = ets:lookup(T,Key),
{ok,{"Expanded Term", {Type,[Term, T]}, []}}.
diff --git a/lib/observer/src/cdv_timer_cb.erl b/lib/observer/src/cdv_timer_cb.erl
index d44592cf18..42285b0fc9 100644
--- a/lib/observer/src/cdv_timer_cb.erl
+++ b/lib/observer/src/cdv_timer_cb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_timer_cb).
@@ -49,6 +50,6 @@ get_info(Owner) ->
{Info,TW}.
get_detail_cols(all) ->
- {[?COL_OWNER],false};
+ {[{process, ?COL_OWNER}],false};
get_detail_cols(_) ->
{[],false}.
diff --git a/lib/observer/src/cdv_virtual_list_wx.erl b/lib/observer/src/cdv_virtual_list_wx.erl
index bfe115a42e..5b2775d61b 100644
--- a/lib/observer/src/cdv_virtual_list_wx.erl
+++ b/lib/observer/src/cdv_virtual_list_wx.erl
@@ -3,23 +3,25 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_virtual_list_wx).
-behaviour(wx_object).
--export([start_link/2, start_link/3, start_detail_win/1]).
+-export([start_link/2, start_link/3,
+ start_detail_win/1, start_detail_win/2]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -65,22 +67,31 @@ start_link(ParentWin, Callback, Owner) ->
wx_object:start_link(?MODULE, [ParentWin, Callback, Owner], []).
start_detail_win(Id) ->
- Callback =
- case Id of
- "<"++_ ->
- cdv_proc_cb;
- "#Port"++_ ->
- cdv_port_cb;
- _ ->
- case catch list_to_integer(Id) of
- NodeId when is_integer(NodeId) ->
- cdv_dist_cb;
- _ ->
- cdv_mod_cb
- end
- end,
- start_detail_win(Callback,Id).
-start_detail_win(Callback,Id) ->
+ case Id of
+ "<"++_ ->
+ start_detail_win(Id, process);
+ "#Port"++_ ->
+ start_detail_win(Id, port);
+ _ ->
+ io:format("cdv: unknown identifier: ~p~n",[Id]),
+ ignore
+ end.
+
+start_detail_win(Id, process) ->
+ start_detail_win_2(cdv_proc_cb, Id);
+start_detail_win(Id, port) ->
+ start_detail_win_2(cdv_port_cb, Id);
+start_detail_win(Id, node) ->
+ start_detail_win_2(cdv_dist_cb, Id);
+start_detail_win(Id, module) ->
+ start_detail_win_2(cdv_mod_cb, Id);
+start_detail_win(Id, ets) ->
+ start_detail_win_2(cdv_ets_cb, Id);
+start_detail_win(Id, sched) ->
+ start_detail_win_2(cdv_sched_cb, Id).
+
+
+start_detail_win_2(Callback,Id) ->
wx_object:cast(Callback,{start_detail_win,Id}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -158,15 +169,14 @@ create_list_box(Panel, Holder, Callback, Owner) ->
do_start_detail_win(undefined, State) ->
State;
do_start_detail_win(Id, #state{panel=Panel,detail_wins=Opened,
- callback=Callback}=State) ->
+ holder=Holder,callback=Callback}=State) ->
NewOpened =
case lists:keyfind(Id, 1, Opened) of
false ->
- case cdv_detail_wx:start_link(Id, Panel, Callback) of
- {error, _} ->
- Opened;
- IW ->
- [{Id, IW} | Opened]
+ Data = call(Holder, {get_data, self(), Id}),
+ case cdv_detail_wx:start_link(Id, Data, Panel, Callback) of
+ {error, _} -> Opened;
+ IW -> [{Id, IW} | Opened]
end;
{_, IW} ->
wxFrame:raise(IW),
@@ -247,8 +257,8 @@ handle_event(#wx{id=MenuId,
event=#wxCommand{type = command_menu_selected}},
#state{menu_items=MenuItems} = State) ->
case lists:keyfind(MenuId,1,MenuItems) of
- {MenuId,Id} ->
- start_detail_win(Id);
+ {MenuId,Type,Id} ->
+ start_detail_win(Id, Type);
false ->
ok
end,
@@ -265,7 +275,7 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
Menu = wxMenu:new(),
MenuItems =
lists:flatmap(
- fun(Col) ->
+ fun({Type, Col}) ->
MenuId = ?ID_DETAILS + Col,
ColText = call(Holder, {get_row, self(), Row, Col}),
case ColText of
@@ -273,14 +283,15 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
_ ->
What =
case catch list_to_integer(ColText) of
- NodeId when is_integer(NodeId) ->
+ NodeId when is_integer(NodeId),
+ Type =:= node ->
"node " ++ ColText;
_ ->
ColText
end,
Text = "Properties for " ++ What,
wxMenu:append(Menu, MenuId, Text),
- [{MenuId,ColText}]
+ [{MenuId,Type,ColText}]
end
end,
MenuCols),
@@ -300,9 +311,14 @@ handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}},
handle_event(#wx{event=#wxList{type=command_list_item_activated,
itemIndex=Row}},
- #state{holder=Holder} = State) ->
- Id = call(Holder, {get_row, self(), Row, id}),
- start_detail_win(Id),
+ #state{holder=Holder, menu_cols=MenuCols} = State) ->
+ case MenuCols of
+ [{Type, _}|_] ->
+ Id = call(Holder, {get_row, self(), Row, id}),
+ start_detail_win(Id, Type);
+ _ ->
+ ignore
+ end,
{noreply, State};
handle_event(Event, State) ->
@@ -346,7 +362,7 @@ init_table_holder(Parent, Attrs, Callback, InfoList0) ->
attrs=Attrs,
callback=Callback}).
-table_holder(#holder{callback=Callback, attrs=Attrs}=S0) ->
+table_holder(#holder{callback=Callback, attrs=Attrs, info=Info}=S0) ->
receive
_M={get_row, From, Row, Col} ->
%% erlang:display(_M),
@@ -360,6 +376,9 @@ table_holder(#holder{callback=Callback, attrs=Attrs}=S0) ->
%% erlang:display(_M),
State = change_sort(Callback:col_to_elem(Col), S0),
table_holder(State);
+ _M={get_data, From, Id} ->
+ search_id(From, Id, Callback, Info),
+ table_holder(S0);
stop ->
ok;
What ->
@@ -367,6 +386,21 @@ table_holder(#holder{callback=Callback, attrs=Attrs}=S0) ->
table_holder(S0)
end.
+search_id(From, Id, Callback, Info) ->
+ Find = fun(_, RowInfo, _) ->
+ search_id(Callback, RowInfo, Id)
+ end,
+ Res = try array:foldl(Find, not_found, Info)
+ catch Data -> Data end,
+ From ! {self(), Res},
+ ok.
+
+search_id(Callback, RowInfo, Id) ->
+ case observer_lib:to_str(get_cell_data(Callback, id, RowInfo)) of
+ Id -> throw(RowInfo);
+ _Str -> not_found
+ end.
+
change_sort(Col, S0=#holder{parent=Parent, info=Info0, sort=Sort0}) ->
NRows = array:size(Info0),
InfoList0 = array:to_list(Info0),
diff --git a/lib/observer/src/cdv_wx.erl b/lib/observer/src/cdv_wx.erl
index 26df60b0a6..82247cb93b 100644
--- a/lib/observer/src/cdv_wx.erl
+++ b/lib/observer/src/cdv_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(cdv_wx).
@@ -44,6 +45,7 @@
-define(PORT_STR, "Ports").
-define(ETS_STR, "ETS Tables").
-define(TIMER_STR, "Timers").
+-define(SCHEDULER_STR, "Schedulers").
-define(FUN_STR, "Funs").
-define(ATOM_STR, "Atoms").
-define(DIST_STR, "Nodes").
@@ -66,6 +68,7 @@
port_panel,
ets_panel,
timer_panel,
+ sched_panel,
fun_panel,
atom_panel,
dist_panel,
@@ -171,6 +174,9 @@ setup(#state{frame=Frame, notebook=Notebook}=State) ->
%% Timer Panel
TimerPanel = add_page(Notebook, ?TIMER_STR, cdv_virtual_list_wx,cdv_timer_cb),
+ %% Scheduler Panel
+ SchedPanel = add_page(Notebook, ?SCHEDULER_STR, cdv_virtual_list_wx, cdv_sched_cb),
+
%% Fun Panel
FunPanel = add_page(Notebook, ?FUN_STR, cdv_virtual_list_wx, cdv_fun_cb),
@@ -202,6 +208,7 @@ setup(#state{frame=Frame, notebook=Notebook}=State) ->
port_panel = PortPanel,
ets_panel = EtsPanel,
timer_panel = TimerPanel,
+ sched_panel = SchedPanel,
fun_panel = FunPanel,
atom_panel = AtomPanel,
dist_panel = DistPanel,
@@ -335,7 +342,8 @@ check_page_title(Notebook) ->
get_active_pid(#state{notebook=Notebook, gen_panel=Gen, pro_panel=Pro,
port_panel=Ports, ets_panel=Ets, timer_panel=Timers,
fun_panel=Funs, atom_panel=Atoms, dist_panel=Dist,
- mod_panel=Mods, mem_panel=Mem, int_panel=Int
+ mod_panel=Mods, mem_panel=Mem, int_panel=Int,
+ sched_panel=Sched
}) ->
Panel = case check_page_title(Notebook) of
?GEN_STR -> Gen;
@@ -343,6 +351,7 @@ get_active_pid(#state{notebook=Notebook, gen_panel=Gen, pro_panel=Pro,
?PORT_STR -> Ports;
?ETS_STR -> Ets;
?TIMER_STR -> Timers;
+ ?SCHEDULER_STR -> Sched;
?FUN_STR -> Funs;
?ATOM_STR -> Atoms;
?DIST_STR -> Dist;
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index 99329b94e2..b66b4d59c9 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -63,6 +64,7 @@
allocator_info/0,
hash_tables/0,
index_tables/0,
+ schedulers/0,
expand_binary/1]).
%% Library function
@@ -114,6 +116,7 @@
-define(proc_heap,proc_heap).
-define(proc_messages,proc_messages).
-define(proc_stack,proc_stack).
+-define(scheduler,scheduler).
-define(timer,timer).
-define(visible_node,visible_node).
@@ -267,6 +270,8 @@ hash_tables() ->
call(hash_tables).
index_tables() ->
call(index_tables).
+schedulers() ->
+ call(schedulers).
%%%-----------------------------------------------------------------
%%% Called when a link to a process (Pid) is clicked.
@@ -320,6 +325,8 @@ handle_call(general_info,_From,State=#state{file=File}) ->
"Some information might be missing."];
false -> []
end,
+ ets:insert(cdv_reg_proc_table,
+ {cdv_dump_node_name,GenInfo#general_info.node_name}),
{reply,{ok,GenInfo,TW},State#state{wordsize=WS, num_atoms=NumAtoms}};
handle_call({expand_binary,{Offset,Size,Pos}},_From,State=#state{file=File}) ->
Fd = open(File),
@@ -429,7 +436,11 @@ handle_call(hash_tables,_From,State=#state{file=File}) ->
handle_call(index_tables,_From,State=#state{file=File}) ->
IndexTables=index_tables(File),
TW = truncated_warning([?hash_table,?index_table]),
- {reply,{ok,IndexTables,TW},State}.
+ {reply,{ok,IndexTables,TW},State};
+handle_call(schedulers,_From,State=#state{file=File}) ->
+ Schedulers=schedulers(File),
+ TW = truncated_warning([?scheduler]),
+ {reply,{ok,Schedulers,TW},State}.
@@ -675,9 +686,11 @@ skip(Fd,<<>>) ->
val(Fd) ->
+ val(Fd, "-1").
+val(Fd, NoExist) ->
case get_rest_of_line(Fd) of
- {eof,[]} -> "-1";
- [] -> "-1";
+ {eof,[]} -> NoExist;
+ [] -> NoExist;
{eof,Val} -> Val;
Val -> Val
end.
@@ -926,7 +939,7 @@ general_info(File) ->
N;
[] ->
case lookup_index(?no_distribution) of
- [_] -> "nonode@nohost";
+ [_] -> "'nonode@nohost'";
[] -> "unknown"
end
end,
@@ -965,6 +978,8 @@ get_general_info(Fd,GenInfo) ->
get_general_info(Fd,GenInfo#general_info{taints=Val});
"Atoms" ->
get_general_info(Fd,GenInfo#general_info{num_atoms=val(Fd)});
+ "Calling Thread" ->
+ get_general_info(Fd,GenInfo#general_info{thread=val(Fd)});
"=" ++ _next_tag ->
GenInfo;
Other ->
@@ -1131,6 +1146,10 @@ all_procinfo(Fd,Fun,Proc,WS,LineHead) ->
"arity = " ++ Arity ->
%%! Temporary workaround
get_procinfo(Fd,Fun,Proc#proc{arity=Arity--"\r\n"},WS);
+ "Run queue" ->
+ get_procinfo(Fd,Fun,Proc#proc{run_queue=val(Fd)},WS);
+ "Internal State" ->
+ get_procinfo(Fd,Fun,Proc#proc{int_state=val(Fd)},WS);
"=" ++ _next_tag ->
Proc;
Other ->
@@ -1165,6 +1184,19 @@ parse_pid(Str) ->
{Pid,Rest} = parse_link(Str,[]),
{{Pid,Pid},Rest}.
+parse_monitor("{"++Str) ->
+ %% Named process
+ {Name,Node,Rest1} = parse_name_node(Str,[]),
+ Pid = get_pid_from_name(Name,Node),
+ case parse_link(string:strip(Rest1,left,$,),[]) of
+ {Ref,"}"++Rest2} ->
+ %% Bug in break.c - prints an extra "}" for remote
+ %% nodes... thus the strip
+ {{Pid,"{"++Name++","++Node++"} ("++Ref++")"},
+ string:strip(Rest2,left,$})};
+ {Ref,[]} ->
+ {{Pid,"{"++Name++","++Node++"} ("++Ref++")"},[]}
+ end;
parse_monitor(Str) ->
case parse_link(Str,[]) of
{Pid,","++Rest1} ->
@@ -1186,23 +1218,58 @@ parse_link([],Acc) ->
%% truncated
{lists:reverse(Acc),[]}.
+parse_name_node(","++Rest,Name) ->
+ parse_name_node(Rest,Name,[]);
+parse_name_node([H|T],Name) ->
+ parse_name_node(T,[H|Name]);
+parse_name_node([],Name) ->
+ %% truncated
+ {lists:reverse(Name),[],[]}.
+
+parse_name_node("}"++Rest,Name,Node) ->
+ {lists:reverse(Name),lists:reverse(Node),Rest};
+parse_name_node([H|T],Name,Node) ->
+ parse_name_node(T,Name,[H|Node]);
+parse_name_node([],Name,Node) ->
+ %% truncated
+ {lists:reverse(Name),lists:reverse(Node),[]}.
+
+get_pid_from_name(Name,Node) ->
+ case ets:lookup(cdv_reg_proc_table,cdv_dump_node_name) of
+ [{_,Node}] ->
+ case ets:lookup(cdv_reg_proc_table,Name) of
+ [{_,Pid}] when is_pid(Pid) ->
+ pid_to_list(Pid);
+ _ ->
+ "<unkonwn_pid>"
+ end;
+ _ ->
+ "<unknown_pid_other_node>"
+ end.
+
maybe_other_node(Id) ->
Channel =
case split($.,Id) of
{"<" ++ N, _Rest} ->
N;
{"#Port<" ++ N, _Rest} ->
- N
+ N;
+ {_, []} ->
+ not_found
end,
+ maybe_other_node2(Channel).
+
+maybe_other_node2(not_found) -> not_found;
+maybe_other_node2(Channel) ->
Ms = ets:fun2ms(
- fun({{Tag,Start},Ch}) when Tag=:=?visible_node, Ch=:=Channel ->
+ fun({{Tag,Start},Ch}) when Tag=:=?visible_node, Ch=:=Channel ->
{"Visible Node",Start};
({{Tag,Start},Ch}) when Tag=:=?hidden_node, Ch=:=Channel ->
{"Hidden Node",Start};
- ({{Tag,Start},Ch}) when Tag=:=?not_connected, Ch=:=Channel ->
+ ({{Tag,Start},Ch}) when Tag=:=?not_connected, Ch=:=Channel ->
{"Not Connected Node",Start}
end),
-
+
case ets:select(cdv_dump_index_table,Ms) of
[] ->
not_found;
@@ -1457,7 +1524,7 @@ get_ets_tables(File,Pid,WS) ->
end,
lookup_and_parse_index(File,{?ets,Pid},ParseFun,"ets").
-get_etsinfo(Fd,EtsTable,WS) ->
+get_etsinfo(Fd,EtsTable = #ets_table{details=Ds},WS) ->
case line_head(Fd) of
"Slot" ->
get_etsinfo(Fd,EtsTable#ets_table{slot=list_to_integer(val(Fd))},WS);
@@ -1467,7 +1534,7 @@ get_etsinfo(Fd,EtsTable,WS) ->
get_etsinfo(Fd,EtsTable#ets_table{name=val(Fd)},WS);
"Ordered set (AVL tree), Elements" ->
skip_rest_of_line(Fd),
- get_etsinfo(Fd,EtsTable#ets_table{type="tree",buckets="-"},WS);
+ get_etsinfo(Fd,EtsTable#ets_table{data_type="tree"},WS);
"Buckets" ->
%% A bug in erl_db_hash.c prints a space after the buckets
%% - need to strip the string to make list_to_integer/1 happy.
@@ -1482,9 +1549,42 @@ get_etsinfo(Fd,EtsTable,WS) ->
-1 -> -1; % probably truncated
_ -> Words * WS
end,
- get_etsinfo(Fd,EtsTable#ets_table{memory=Bytes},WS);
+ get_etsinfo(Fd,EtsTable#ets_table{memory={bytes,Bytes}},WS);
"=" ++ _next_tag ->
EtsTable;
+ "Chain Length Min" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_min=>Val}},WS);
+ "Chain Length Avg" ->
+ Val = try list_to_float(string:strip(val(Fd))) catch _:_ -> "-" end,
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_avg=>Val}},WS);
+ "Chain Length Max" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_max=>Val}},WS);
+ "Chain Length Std Dev" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_stddev=>Val}},WS);
+ "Chain Length Expected Std Dev" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_exp_stddev=>Val}},WS);
+ "Fixed" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{fixed=>Val}},WS);
+ "Type" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{data_type=Val},WS);
+ "Protection" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{protection=>Val}},WS);
+ "Compressed" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{compressed=>Val}},WS);
+ "Write Concurrency" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{write_c=>Val}},WS);
+ "Read Concurrency" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{read_c=>Val}},WS);
Other ->
unexpected(Fd,Other,"ETS info"),
EtsTable
@@ -2224,6 +2324,89 @@ get_indextableinfo1(Fd,IndexTable) ->
IndexTable
end.
+
+%%-----------------------------------------------------------------
+%% Page with scheduler table information
+schedulers(File) ->
+ case lookup_index(?scheduler) of
+ [] ->
+ [];
+ Schedulers ->
+ Fd = open(File),
+ R = lists:map(fun({Name,Start}) ->
+ get_schedulerinfo(Fd,Name,Start)
+ end,
+ Schedulers),
+ close(Fd),
+ R
+ end.
+
+get_schedulerinfo(Fd,Name,Start) ->
+ pos_bof(Fd,Start),
+ get_schedulerinfo1(Fd,#sched{name=Name}).
+
+get_schedulerinfo1(Fd,Sched=#sched{details=Ds}) ->
+ case line_head(Fd) of
+ "Current Process" ->
+ get_schedulerinfo1(Fd,Sched#sched{process=val(Fd, "None")});
+ "Current Port" ->
+ get_schedulerinfo1(Fd,Sched#sched{port=val(Fd, "None")});
+ "Run Queue Max Length" ->
+ RQMax = list_to_integer(val(Fd)),
+ RQ = RQMax + Sched#sched.run_q,
+ get_schedulerinfo1(Fd,Sched#sched{run_q=RQ, details=Ds#{runq_max=>RQMax}});
+ "Run Queue High Length" ->
+ RQHigh = list_to_integer(val(Fd)),
+ RQ = RQHigh + Sched#sched.run_q,
+ get_schedulerinfo1(Fd,Sched#sched{run_q=RQ, details=Ds#{runq_high=>RQHigh}});
+ "Run Queue Normal Length" ->
+ RQNorm = list_to_integer(val(Fd)),
+ RQ = RQNorm + Sched#sched.run_q,
+ get_schedulerinfo1(Fd,Sched#sched{run_q=RQ, details=Ds#{runq_norm=>RQNorm}});
+ "Run Queue Low Length" ->
+ RQLow = list_to_integer(val(Fd)),
+ RQ = RQLow + Sched#sched.run_q,
+ get_schedulerinfo1(Fd,Sched#sched{run_q=RQ, details=Ds#{runq_low=>RQLow}});
+ "Run Queue Port Length" ->
+ RQ = list_to_integer(val(Fd)),
+ get_schedulerinfo1(Fd,Sched#sched{port_q=RQ});
+
+ "Scheduler Sleep Info Flags" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{sleep_info=>val(Fd, "None")}});
+ "Scheduler Sleep Info Aux Work" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{sleep_aux=>val(Fd, "None")}});
+
+ "Run Queue Flags" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{runq_flags=>val(Fd, "None")}});
+
+ "Current Process State" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{currp_state=>val(Fd)}});
+ "Current Process Internal State" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{currp_int_state=>val(Fd)}});
+ "Current Process Program counter" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{currp_prg_cnt=>val(Fd)}});
+ "Current Process CP" ->
+ get_schedulerinfo1(Fd,Sched#sched{details=Ds#{currp_cp=>val(Fd)}});
+ "Current Process Limited Stack Trace" ->
+ %% If there shall be last in scheduler information block
+ Sched#sched{details=get_limited_stack(Fd, 0, Ds)};
+ "=" ++ _next_tag ->
+ Sched;
+ Other ->
+ unexpected(Fd,Other,"scheduler information"),
+ Sched
+ end.
+
+get_limited_stack(Fd, N, Ds) ->
+ case val(Fd) of
+ Addr = "0x" ++ _ ->
+ get_limited_stack(Fd, N+1, Ds#{{currp_stack, N} => Addr});
+ "=" ++ _next_tag ->
+ Ds;
+ Line ->
+ get_limited_stack(Fd, N+1, Ds#{{currp_stack, N} => Line})
+ end.
+
%%%-----------------------------------------------------------------
%%% Parse memory in crashdump version 0.1 and newer
%%%
@@ -2526,6 +2709,7 @@ tag_to_atom("proc_dictionary") -> ?proc_dictionary;
tag_to_atom("proc_heap") -> ?proc_heap;
tag_to_atom("proc_messages") -> ?proc_messages;
tag_to_atom("proc_stack") -> ?proc_stack;
+tag_to_atom("scheduler") -> ?scheduler;
tag_to_atom("timer") -> ?timer;
tag_to_atom("visible_node") -> ?visible_node;
tag_to_atom(UnknownTag) ->
diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl
index 0e2eba6dee..bd08d3e1e1 100644
--- a/lib/observer/src/crashdump_viewer.hrl
+++ b/lib/observer/src/crashdump_viewer.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -36,7 +37,9 @@
num_fun,
mem_tot,
mem_max,
- instr_info}).
+ instr_info,
+ thread
+ }).
-record(proc,
%% Initial data according to the follwoing:
@@ -85,7 +88,10 @@
old_heap_top,
old_heap_end,
memory,
- stack_dump}).
+ stack_dump,
+ run_queue=?unknown,
+ int_state
+ }).
-record(port,
{id,
@@ -96,15 +102,28 @@
monitors,
controls}).
+-record(sched,
+ {name,
+ process,
+ port,
+ run_q=0,
+ port_q=0,
+ details=#{}
+ }).
+
+
+
-record(ets_table,
{pid,
slot,
id,
name,
- type="hash",
- buckets,
+ data_type="hash",
+ buckets="-",
size,
- memory}).
+ memory,
+ details= #{}
+ }).
-record(timer,
{pid,
diff --git a/lib/observer/src/etop.erl b/lib/observer/src/etop.erl
index 96a18cf450..c97fcc481b 100644
--- a/lib/observer/src/etop.erl
+++ b/lib/observer/src/etop.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/src/etop_defs.hrl b/lib/observer/src/etop_defs.hrl
index 720fb50b5a..39acda5758 100644
--- a/lib/observer/src/etop_defs.hrl
+++ b/lib/observer/src/etop_defs.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/src/etop_tr.erl b/lib/observer/src/etop_tr.erl
index e6c69e4e1e..38e048c307 100644
--- a/lib/observer/src/etop_tr.erl
+++ b/lib/observer/src/etop_tr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/src/etop_txt.erl b/lib/observer/src/etop_txt.erl
index f048ff17ca..b77fc3c55d 100644
--- a/lib/observer/src/etop_txt.erl
+++ b/lib/observer/src/etop_txt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/src/multitrace.erl b/lib/observer/src/multitrace.erl
index 144697ce9c..dbb6858646 100644
--- a/lib/observer/src/multitrace.erl
+++ b/lib/observer/src/multitrace.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/src/observer.app.src b/lib/observer/src/observer.app.src
index 97a54cd6f9..61c21a832e 100644
--- a/lib/observer/src/observer.app.src
+++ b/lib/observer/src/observer.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -37,6 +38,7 @@
cdv_proc_cb,
cdv_table_wx,
cdv_term_cb,
+ cdv_sched_cb,
cdv_timer_cb,
cdv_virtual_list_wx,
cdv_wx,
@@ -44,6 +46,7 @@
etop_tr,
etop_txt,
observer,
+ observer_alloc_wx,
observer_app_wx,
observer_html_lib,
observer_lib,
@@ -63,6 +66,6 @@
{env, []},
{runtime_dependencies, ["wx-1.2","stdlib-2.0","runtime_tools-1.8.14",
"kernel-3.0","inets-5.10","et-1.5",
- "erts-6.0"]}]}.
+ "erts-7.0"]}]}.
diff --git a/lib/observer/src/observer.appup.src b/lib/observer/src/observer.appup.src
index 9fde365ff3..9c7ae3a195 100644
--- a/lib/observer/src/observer.appup.src
+++ b/lib/observer/src/observer.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/observer/src/observer.erl b/lib/observer/src/observer.erl
index a30ceecc63..bb1dedb7e6 100644
--- a/lib/observer/src/observer.erl
+++ b/lib/observer/src/observer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/observer/src/observer_alloc_wx.erl b/lib/observer/src/observer_alloc_wx.erl
new file mode 100644
index 0000000000..8d5c8a9037
--- /dev/null
+++ b/lib/observer/src/observer_alloc_wx.erl
@@ -0,0 +1,257 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+-module(observer_alloc_wx).
+
+-export([start_link/2]).
+
+%% wx_object callbacks
+-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
+ handle_event/2, handle_sync_event/3, handle_cast/2]).
+
+-behaviour(wx_object).
+-include_lib("wx/include/wx.hrl").
+-include("observer_defs.hrl").
+
+-record(state,
+ {
+ offset = 0.0,
+ active = false,
+ parent,
+ windows,
+ data = {0, queue:new()},
+ panel,
+ paint,
+ appmon,
+ async
+ }).
+
+-define(ALLOC_W, 1).
+-define(UTIL_W, 2).
+
+start_link(Notebook, Parent) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent], []).
+
+init([Notebook, Parent]) ->
+ try
+ Panel = wxPanel:new(Notebook),
+ Main = wxBoxSizer:new(?wxVERTICAL),
+ Style = ?wxFULL_REPAINT_ON_RESIZE bor ?wxCLIP_CHILDREN,
+ Carrier = wxPanel:new(Panel, [{winid, ?ALLOC_W}, {style,Style}]),
+ Utilz = wxPanel:new(Panel, [{winid, ?UTIL_W}, {style,Style}]),
+ BorderFlags = ?wxLEFT bor ?wxRIGHT,
+ wxSizer:add(Main, Carrier, [{flag, ?wxEXPAND bor BorderFlags bor ?wxTOP},
+ {proportion, 1}, {border, 5}]),
+
+ wxSizer:add(Main, Utilz, [{flag, ?wxEXPAND bor BorderFlags},
+ {proportion, 1}, {border, 5}]),
+
+ MemWin = {MemPanel,_} = create_mem_info(Panel),
+ wxSizer:add(Main, MemPanel, [{flag, ?wxEXPAND bor BorderFlags bor ?wxBOTTOM},
+ {proportion, 1}, {border, 5}]),
+ wxWindow:setSizer(Panel, Main),
+
+ PaintInfo = observer_perf_wx:setup_graph_drawing([Carrier, Utilz]),
+ {Panel, #state{parent=Parent,
+ panel =Panel,
+ windows = {Carrier, Utilz, MemWin},
+ paint=PaintInfo}
+ }
+ catch _:Err ->
+ io:format("~p crashed ~p: ~p~n",[?MODULE, Err, erlang:get_stacktrace()]),
+ {stop, Err}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+handle_event(#wx{event=#wxCommand{type=command_menu_selected}},
+ State = #state{}) ->
+ {noreply, State};
+
+handle_event(Event, _State) ->
+ error({unhandled_event, Event}).
+
+%%%%%%%%%%
+handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_,
+ #state{active=Active, offset=Offset, paint=Paint,
+ windows=Windows, data=Data}) ->
+ %% Sigh workaround bug on MacOSX (Id in paint event is always 0)
+ Id = if Panel =:= element(?ALLOC_W, Windows) -> alloc;
+ Panel =:= element(?UTIL_W, Windows) -> utilz
+ end,
+ observer_perf_wx:refresh_panel(Panel, Id, Offset, Data, Active, Paint),
+ ok.
+%%%%%%%%%%
+handle_call(Event, From, _State) ->
+ error({unhandled_call, Event, From}).
+
+handle_cast(Event, _State) ->
+ error({unhandled_cast, Event}).
+%%%%%%%%%%
+
+handle_info({Key, {promise_reply, {badrpc, _}}}, #state{async=Key} = State) ->
+ {noreply, State#state{active=false, appmon=undefined}};
+
+handle_info({Key, {promise_reply, SysInfo}}, #state{async=Key, data=Data} = State) ->
+ Info = alloc_info(SysInfo),
+ update_alloc(State, Info),
+ {noreply, State#state{offset=0.0, data = add_data(Info, Data), async=undefined}};
+
+handle_info({refresh, Seq, Freq, Node}, #state{panel=Panel, appmon=Node, async=Key} = State) ->
+ wxWindow:refresh(Panel),
+ Next = Seq+1,
+ if
+ Next > Freq, Key =:= undefined ->
+ erlang:send_after(trunc(1000 / Freq), self(), {refresh, 1, Freq, Node}),
+ Req = rpc:async_call(Node, observer_backend, sys_info, []),
+ {noreply, State#state{offset=Seq/Freq, async=Req}};
+ true ->
+ erlang:send_after(trunc(1000 / Freq), self(), {refresh, Next, Freq, Node}),
+ {noreply, State#state{offset=Seq/Freq}}
+ end;
+handle_info({refresh, _Seq, _Freq, _Node}, State) ->
+ {noreply, State};
+
+handle_info({active, Node}, State = #state{parent=Parent, panel=Panel, appmon=Old}) ->
+ create_menus(Parent, []),
+ try
+ Node = Old,
+ wxWindow:refresh(Panel),
+ {noreply, State#state{active=true}}
+ catch _:_ ->
+ SysInfo = observer_wx:try_rpc(Node, observer_backend, sys_info, []),
+ Info = alloc_info(SysInfo),
+ Freq = 6,
+ erlang:send_after(trunc(1000 / Freq), self(), {refresh, 1, Freq, Node}),
+ wxWindow:refresh(Panel),
+ {noreply, State#state{active=true, appmon=Node, offset=0.0,
+ data = add_data(Info, {0, queue:new()})}}
+ end;
+
+handle_info(not_active, State = #state{appmon=_Pid}) ->
+ {noreply, State#state{active=false}};
+
+handle_info({'EXIT', Old, _}, State = #state{appmon=Old}) ->
+ {noreply, State#state{active=false, appmon=undefined}};
+
+handle_info(_Event, State) ->
+ %% io:format("~p:~p: ~p~n",[?MODULE,?LINE,_Event]),
+ {noreply, State}.
+
+terminate(_Event, #state{}) ->
+ ok.
+code_change(_, _, State) ->
+ State.
+
+%%%%%%%%%%
+
+add_data(Stats, {N, Q}) when N > 60 ->
+ {N, queue:drop(queue:in(Stats, Q))};
+add_data(Stats, {N, Q}) ->
+ {N+1, queue:in(Stats, Q)}.
+
+update_alloc(#state{windows={_, _, {_, Grid}}}, Fields) ->
+ Max = wxListCtrl:getItemCount(Grid),
+ Update = fun({Name, BS, CS}, Row) ->
+ (Row >= Max) andalso wxListCtrl:insertItem(Grid, Row, ""),
+ wxListCtrl:setItem(Grid, Row, 0, observer_lib:to_str(Name)),
+ wxListCtrl:setItem(Grid, Row, 1, observer_lib:to_str(BS div 1024)),
+ wxListCtrl:setItem(Grid, Row, 2, observer_lib:to_str(CS div 1024)),
+ Row + 1
+ end,
+ lists:foldl(Update, 0, Fields),
+ Fields.
+
+alloc_info(SysInfo) ->
+ AllocInfo = proplists:get_value(alloc_info, SysInfo, []),
+ alloc_info(AllocInfo, [], 0, 0, true).
+
+alloc_info([{Type,Instances}|Allocators],TypeAcc,TotalBS,TotalCS,IncludeTotal) ->
+ {BS,CS,NewTotalBS,NewTotalCS,NewIncludeTotal} =
+ sum_alloc_instances(Instances,0,0,TotalBS,TotalCS),
+ alloc_info(Allocators,[{Type,BS,CS}|TypeAcc],NewTotalBS,NewTotalCS,
+ IncludeTotal andalso NewIncludeTotal);
+alloc_info([],TypeAcc,TotalBS,TotalCS,IncludeTotal) ->
+ Types = [X || X={_,BS,CS} <- TypeAcc, (BS>0 orelse CS>0)],
+ case IncludeTotal of
+ true ->
+ [{total,TotalBS,TotalCS} | lists:reverse(Types)];
+ false ->
+ lists:reverse(Types)
+ end.
+
+sum_alloc_instances(false,BS,CS,TotalBS,TotalCS) ->
+ {BS,CS,TotalBS,TotalCS,false};
+sum_alloc_instances([{_,_,Data}|Instances],BS,CS,TotalBS,TotalCS) ->
+ {NewBS,NewCS,NewTotalBS,NewTotalCS} =
+ sum_alloc_one_instance(Data,BS,CS,TotalBS,TotalCS),
+ sum_alloc_instances(Instances,NewBS,NewCS,NewTotalBS,NewTotalCS);
+sum_alloc_instances([],BS,CS,TotalBS,TotalCS) ->
+ {BS,CS,TotalBS,TotalCS,true}.
+
+sum_alloc_one_instance([{sbmbcs,[{blocks_size,BS,_,_},{carriers_size,CS,_,_}]}|
+ Rest],OldBS,OldCS,TotalBS,TotalCS) ->
+ sum_alloc_one_instance(Rest,OldBS+BS,OldCS+CS,TotalBS,TotalCS);
+sum_alloc_one_instance([{_,[{blocks_size,BS,_,_},{carriers_size,CS,_,_}]}|
+ Rest],OldBS,OldCS,TotalBS,TotalCS) ->
+ sum_alloc_one_instance(Rest,OldBS+BS,OldCS+CS,TotalBS+BS,TotalCS+CS);
+sum_alloc_one_instance([{_,[{blocks_size,BS},{carriers_size,CS}]}|
+ Rest],OldBS,OldCS,TotalBS,TotalCS) ->
+ sum_alloc_one_instance(Rest,OldBS+BS,OldCS+CS,TotalBS+BS,TotalCS+CS);
+sum_alloc_one_instance([_|Rest],BS,CS,TotalBS,TotalCS) ->
+ sum_alloc_one_instance(Rest,BS,CS,TotalBS,TotalCS);
+sum_alloc_one_instance([],BS,CS,TotalBS,TotalCS) ->
+ {BS,CS,TotalBS,TotalCS}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+create_mem_info(Parent) ->
+ Panel = wxPanel:new(Parent),
+ wxWindow:setBackgroundColour(Panel, {255,255,255}),
+ Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES bor ?wxLC_VRULES,
+ Grid = wxListCtrl:new(Panel, [{style, Style}]),
+ Li = wxListItem:new(),
+ AddListEntry = fun({Name, Align, DefSize}, Col) ->
+ wxListItem:setText(Li, Name),
+ wxListItem:setAlign(Li, Align),
+ wxListCtrl:insertColumn(Grid, Col, Li),
+ wxListCtrl:setColumnWidth(Grid, Col, DefSize),
+ Col + 1
+ end,
+ ListItems = [{"Allocator Type", ?wxLIST_FORMAT_LEFT, 200},
+ {"Block size (kB)", ?wxLIST_FORMAT_RIGHT, 150},
+ {"Carrier size (kB)",?wxLIST_FORMAT_RIGHT, 150}],
+ lists:foldl(AddListEntry, 0, ListItems),
+ wxListItem:destroy(Li),
+
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer, Grid, [{flag, ?wxEXPAND bor ?wxLEFT bor ?wxRIGHT},
+ {border, 5}, {proportion, 1}]),
+ wxWindow:setSizerAndFit(Panel, Sizer),
+ {Panel, Grid}.
+
+
+create_menus(Parent, _) ->
+ MenuEntries =
+ [{"File",
+ [
+ ]}
+ ],
+ observer_wx:create_menus(Parent, MenuEntries).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl
index a8ace10275..a2b7c21993 100644
--- a/lib/observer/src/observer_app_wx.erl
+++ b/lib/observer/src/observer_app_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(observer_app_wx).
diff --git a/lib/observer/src/observer_defs.hrl b/lib/observer/src/observer_defs.hrl
index 3adc358b95..1c2fe520b7 100644
--- a/lib/observer/src/observer_defs.hrl
+++ b/lib/observer/src/observer_defs.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/observer/src/observer_html_lib.erl b/lib/observer/src/observer_html_lib.erl
index c279218707..f646f8ed3e 100644
--- a/lib/observer/src/observer_html_lib.erl
+++ b/lib/observer/src/observer_html_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -60,7 +61,8 @@ expandable_term_body(Heading,[],_Tab) ->
"StackDump" -> "No stack dump was found";
"Dictionary" -> "No dictionary was found";
"ProcState" -> "Information could not be retrieved,"
- " system messages may not be handled by this process."
+ " system messages may not be handled by this process.";
+ "SaslLog" -> "No log entry was found"
end];
expandable_term_body(Heading,Expanded,Tab) ->
Attr = "BORDER=0 CELLPADDING=0 CELLSPACING=1 WIDTH=100%",
@@ -102,7 +104,10 @@ expandable_term_body(Heading,Expanded,Tab) ->
element(1, lists:mapfoldl(fun(Entry, Even) ->
{proc_state(Tab, Entry,Even),
not Even}
- end, true, Expanded))]);
+ end, true, Expanded))]);
+ "SaslLog" ->
+ table(Attr,
+ [tr("BGCOLOR=white",[td("ALIGN=left", pre(href_proc_port(Expanded)))])]) ;
_ ->
table(Attr,
[tr(
@@ -151,7 +156,7 @@ all_or_expand(_Tab,Term,Str,false)
href_proc_port(lists:flatten(Str));
all_or_expand(Tab,Term,Preview,true)
when not is_binary(Term) ->
- Key = {Key1,Key2,Key3} = now(),
+ Key = {Key1,Key2,Key3} = {erlang:unique_integer([positive]),1,2},
ets:insert(Tab,{Key,Term}),
[href_proc_port(lists:flatten(Preview), false), $\n,
href("TARGET=\"expanded\"",
@@ -382,7 +387,9 @@ remove_lgt(Deep) ->
remove_lgt_1([$<,$<|Rest]) ->
[$>,$>|BinStr] = lists:reverse(Rest),
- replace_lgt(lists:reverse(BinStr)).
+ replace_lgt(lists:reverse(BinStr));
+remove_lgt_1(TruncBin) ->
+ TruncBin.
replace_lgt([$<|R]) ->
["&lt;"|replace_lgt(R)];
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index 9592ab5977..71a2b71a72 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -173,12 +174,17 @@ fill_info([{Str,SubStructure}|Rest], Data) when is_list(SubStructure) ->
[{Str, fill_info(SubStructure, Data)}|fill_info(Rest,Data)];
fill_info([{Str,Attrib,SubStructure}|Rest], Data) ->
[{Str, Attrib, fill_info(SubStructure, Data)}|fill_info(Rest,Data)];
+fill_info([{Str, Key = {K,N}}|Rest], Data) when is_atom(K), is_integer(N) ->
+ case get_value(Key, Data) of
+ undefined -> [undefined | fill_info(Rest, Data)];
+ Value -> [{Str, Value} | fill_info(Rest, Data)]
+ end;
fill_info([], _) -> [].
-get_value(Key, Data) when is_atom(Key) ->
- proplists:get_value(Key,Data);
get_value(Fun, Data) when is_function(Fun) ->
- Fun(Data).
+ Fun(Data);
+get_value(Key, Data) ->
+ proplists:get_value(Key,Data).
update_info([Fields|Fs], [{_Header, SubStructure}| Rest]) ->
update_info2(Fields, SubStructure),
@@ -269,6 +275,8 @@ to_str(Pid) when is_pid(Pid) ->
pid_to_list(Pid);
to_str(No) when is_integer(No) ->
integer_to_list(No);
+to_str(Float) when is_float(Float) ->
+ io_lib:format("~.3f", [Float]);
to_str(Term) ->
io_lib:format("~w", [Term]).
diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl
index 8173349ed7..ace0b62c1d 100644
--- a/lib/observer/src/observer_perf_wx.erl
+++ b/lib/observer/src/observer_perf_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(observer_perf_wx).
@@ -24,7 +25,8 @@
handle_event/2, handle_sync_event/3, handle_cast/2]).
%% Drawing wrappers for DC and GC areas
--export([haveGC/0,
+-export([setup_graph_drawing/1, refresh_panel/6,
+ haveGC/0,
setPen/2, setFont/3, setBrush/2,
strokeLine/5, strokeLines/2, drawRoundedRectangle/6,
drawText/4, getTextExtent/2]).
@@ -42,13 +44,12 @@
data = {0, queue:new()},
panel,
paint,
- appmon,
- usegc = false
+ appmon
}).
-define(wxGC, wxGraphicsContext).
--record(paint, {font, small, pen, pen2, pens}).
+-record(paint, {font, small, pen, pen2, pens, usegc = false}).
-define(RQ_W, 1).
-define(MEM_W, 2).
@@ -63,14 +64,11 @@ init([Notebook, Parent]) ->
Main = wxBoxSizer:new(?wxVERTICAL),
Style = ?wxFULL_REPAINT_ON_RESIZE bor ?wxCLIP_CHILDREN,
CPU = wxPanel:new(Panel, [{winid, ?RQ_W}, {style,Style}]),
- wxWindow:setBackgroundColour(CPU, ?wxWHITE),
wxSizer:add(Main, CPU, [{flag, ?wxEXPAND bor ?wxALL},
{proportion, 1}, {border, 5}]),
MemIO = wxBoxSizer:new(?wxHORIZONTAL),
MEM = wxPanel:new(Panel, [{winid, ?MEM_W}, {style,Style}]),
- wxWindow:setBackgroundColour(MEM, ?wxWHITE),
IO = wxPanel:new(Panel, [{winid, ?IO_W}, {style,Style}]),
- wxWindow:setBackgroundColour(IO, ?wxWHITE),
wxSizer:add(MemIO, MEM, [{flag, ?wxEXPAND bor ?wxLEFT},
{proportion, 1}, {border, 5}]),
wxSizer:add(MemIO, IO, [{flag, ?wxEXPAND bor ?wxLEFT bor ?wxRIGHT},
@@ -79,53 +77,56 @@ init([Notebook, Parent]) ->
{proportion, 1}, {border, 5}]),
wxWindow:setSizer(Panel, Main),
- wxPanel:connect(CPU, paint, [callback]),
- wxPanel:connect(IO, paint, [callback]),
- wxPanel:connect(MEM, paint, [callback]),
- case os:type() of
- {win32, _} -> %% Ignore erase on windows
- wxPanel:connect(CPU, erase_background, [{callback, fun(_,_) -> ok end}]),
- wxPanel:connect(IO, erase_background, [{callback, fun(_,_) -> ok end}]),
- wxPanel:connect(MEM, erase_background, [{callback, fun(_,_) -> ok end}]);
- _ -> ok
- end,
+ PaintInfo = setup_graph_drawing([CPU, MEM, IO]),
+ process_flag(trap_exit, true),
+ {Panel, #state{parent=Parent,
+ panel =Panel,
+ windows = {CPU, MEM, IO},
+ paint=PaintInfo
+ }}
+ catch _:Err ->
+ io:format("~p crashed ~p: ~p~n",[?MODULE, Err, erlang:get_stacktrace()]),
+ {stop, Err}
+ end.
+
+setup_graph_drawing(Panels) ->
+ IsWindows = element(1, os:type()) =:= win32,
+ IgnoreCB = {callback, fun(_,_) -> ok end},
+ Do = fun(Panel) ->
+ wxWindow:setBackgroundColour(Panel, ?wxWHITE),
+ wxPanel:connect(Panel, paint, [callback]),
+ IsWindows andalso
+ wxPanel:connect(Panel, erase_background, [IgnoreCB])
+ end,
+ _ = [Do(Panel) || Panel <- Panels],
UseGC = haveGC(),
Version28 = ?wxMAJOR_VERSION =:= 2 andalso ?wxMINOR_VERSION =:= 8,
{Font, SmallFont}
- = case os:type() of
- {unix, _} when UseGC, Version28 ->
+ = if UseGC, Version28 ->
%% Def font is really small when using Graphics contexts in 2.8
%% Hardcode it
F = wxFont:new(12,?wxFONTFAMILY_DECORATIVE,?wxFONTSTYLE_NORMAL,?wxFONTWEIGHT_BOLD),
SF = wxFont:new(10, ?wxFONTFAMILY_DECORATIVE, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL),
{F, SF};
- _ ->
+ true ->
DefFont = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT),
DefSize = wxFont:getPointSize(DefFont),
DefFamily = wxFont:getFamily(DefFont),
- F = wxFont:new(DefSize, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_BOLD),
- SF = wxFont:new(DefSize-1, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL),
+ F = wxFont:new(DefSize-1, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_BOLD),
+ SF = wxFont:new(DefSize-2, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL),
{F, SF}
end,
BlackPen = wxPen:new({0,0,0}, [{width, 2}]),
- Pens = [wxPen:new(Col, [{width, 2}]) || Col <- tuple_to_list(colors())],
- process_flag(trap_exit, true),
- {Panel, #state{parent=Parent,
- panel =Panel,
- windows = {CPU, MEM, IO},
- usegc=UseGC,
- paint=#paint{font = Font,
- small = SmallFont,
- pen = ?wxGREY_PEN,
- pen2 = BlackPen,
- pens = list_to_tuple(Pens)
- }
- }}
- catch _:Err ->
- io:format("~p crashed ~p: ~p~n",[?MODULE, Err, erlang:get_stacktrace()]),
- {stop, Err}
- end.
+ Pens = [wxPen:new(Col, [{width, 3}]) || Col <- tuple_to_list(colors())],
+ #paint{usegc = UseGC,
+ font = Font,
+ small = SmallFont,
+ pen = ?wxGREY_PEN,
+ pen2 = BlackPen,
+ pens = list_to_tuple(Pens)
+ }.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -139,21 +140,25 @@ handle_event(Event, _State) ->
%%%%%%%%%%
handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_,
#state{active=Active, offset=Offset, paint=Paint,
- windows=Windows, data=Data, usegc=UseGC}) ->
- %% PaintDC must be created in a callback to work on windows.
+ windows=Windows, data=Data}) ->
%% Sigh workaround bug on MacOSX (Id in paint event is always 0)
%% Panel = element(Id, Windows),
- Id = if Panel =:= element(?RQ_W, Windows) -> ?RQ_W;
- Panel =:= element(?MEM_W, Windows) -> ?MEM_W;
- Panel =:= element(?IO_W, Windows) -> ?IO_W
+ Id = if Panel =:= element(?RQ_W, Windows) -> runq;
+ Panel =:= element(?MEM_W, Windows) -> memory;
+ Panel =:= element(?IO_W, Windows) -> io
end,
- IsWindows = element(1, os:type()) =:= win32,
- DC = if IsWindows ->
+ refresh_panel(Panel, Id, Offset, Data, Active, Paint),
+ ok.
+
+refresh_panel(Panel, Id, Offset, Data, Active, #paint{usegc=UseGC} = Paint) ->
+ %% PaintDC must be created in a callback to work on windows.
+ IsWindows = element(1, os:type()) =:= win32,
+ DC = if IsWindows ->
%% Ugly hack to aviod flickering on windows, works on windows only
%% But the other platforms are doublebuffered by default
wx:typeCast(wxBufferedPaintDC:new(Panel), wxPaintDC);
- true ->
+ true ->
wxPaintDC:new(Panel)
end,
IsWindows andalso wxDC:clear(DC),
@@ -167,8 +172,9 @@ handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_,
io:format("Internal error ~p ~p~n",[Err, erlang:get_stacktrace()])
end,
UseGC andalso ?wxGC:destroy(GC),
- wxPaintDC:destroy(DC),
- ok.
+ wxPaintDC:destroy(DC).
+
+
%%%%%%%%%%
handle_call(Event, From, _State) ->
error({unhandled_call, Event, From}).
@@ -247,10 +253,10 @@ create_menus(Parent, _) ->
observer_wx:create_menus(Parent, MenuEntries).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-collect_data(?RQ_W, {N, Q}) ->
+collect_data(runq, {N, Q}) ->
case queue:to_list(Q) of
- [] -> {0, 0, []};
- [_] -> {0, 0, []};
+ [] -> {0, 0, [], []};
+ [_] -> {0, 0, [], []};
[{stats, _Ver, Init0, _IO, _Mem}|Data0] ->
Init = lists:sort(Init0),
[_|Data=[First|_]] = lists:foldl(fun({stats, _, T0, _, _}, [Prev|Acc]) ->
@@ -258,25 +264,46 @@ collect_data(?RQ_W, {N, Q}) ->
Delta = calc_delta(TN, Prev),
[TN, list_to_tuple(Delta)|Acc]
end, [Init], Data0),
- {N, lmax(Data), lists:reverse([First|Data])}
+ NoGraphs = tuple_size(First),
+ {N, lmax(Data), lists:reverse([First|Data]), lists:seq(1, NoGraphs)}
end;
-collect_data(?MEM_W, {N, Q}) ->
+collect_data(memory, {N, Q}) ->
MemT = mem_types(),
Data = [list_to_tuple([Value || {Type,Value} <- MemInfo,
lists:member(Type, MemT)])
|| {stats, _Ver, _RQ, _IO, MemInfo} <- queue:to_list(Q)],
- {N, lmax(Data), Data};
-collect_data(?IO_W, {N, Q}) ->
+ {N, lmax(Data), Data, MemT};
+collect_data(io, {N, Q}) ->
case queue:to_list(Q) of
- [] -> {0, 0, []};
- [_] -> {0, 0, []};
+ [] -> {0, 0, [], []};
+ [_] -> {0, 0, [], []};
[{stats, _Ver, _RQ, {{_,In0}, {_,Out0}}, _Mem}|Data0] ->
[_,_|Data=[First|_]] =
lists:foldl(fun({stats, _, _, {{_,In}, {_,Out}}, _}, [PIn,Pout|Acc]) ->
[In,Out,{In-PIn,Out-Pout}|Acc]
end, [In0,Out0], Data0),
- {N, lmax(Data), lists:reverse([First|Data])}
- end.
+ {N, lmax(Data), lists:reverse([First|Data]), [input, output]}
+ end;
+collect_data(alloc, {N, Q}) ->
+ List = queue:to_list(Q),
+ Data = [list_to_tuple([Carrier || {_Type,_Block,Carrier} <- MemInfo])
+ || MemInfo <- List],
+ Info = case List of %% Varies depending on erlang build config/platform
+ [MInfo|_] -> [Type || {Type, _, _} <- MInfo];
+ _ -> []
+ end,
+ {N, lmax(Data), Data, Info};
+
+collect_data(utilz, {N, Q}) ->
+ List = queue:to_list(Q),
+ Data = [list_to_tuple([round(100*Block/Carrier) || {_Type,Block,Carrier} <- MemInfo])
+ || MemInfo <- List],
+ Info = case List of %% Varies depending on erlang build config/platform
+ [MInfo|_] -> [Type || {Type, _, _} <- MInfo];
+ _ -> []
+ end,
+ {N, lmax(Data), Data, Info}.
+
mem_types() ->
[total, processes, atom, binary, code, ets].
@@ -299,14 +326,14 @@ draw(Offset, Id, DC, Panel, Paint=#paint{pens=Pens, small=Small}, Data, Active)
%% This can be optimized a lot by collecting data once
%% and draw to memory and then blit memory and only draw new entries in new memory
%% area. Hmm now rewritten to use ?wxGC I don't now if it is feasable.
- {Len, Max0, Hs} = collect_data(Id, Data),
- Max = calc_max(Max0),
- NoGraphs = try tuple_size(hd(Hs)) catch _:_ -> 0 end,
+ {Len, Max0, Hs, Info} = collect_data(Id, Data),
+ {Max,_,_} = MaxDisp = calc_max(Id, Max0),
Size = wxWindow:getClientSize(Panel),
- {X0,Y0,WS,HS} = draw_borders(Id, NoGraphs, DC, Size, Max, Paint),
+ {X0,Y0,WS,HS, DrawBs} = draw_borders(Id, Info, DC, Size, MaxDisp, Paint),
Last = 60*WS+X0-1,
Start = max(61-Len, 0)*WS+X0 - Offset*WS,
Samples = length(Hs),
+ NoGraphs = try tuple_size(hd(Hs)) catch _:_ -> 0 end,
case Active andalso Samples > 1 andalso NoGraphs > 0 of
true ->
Draw = fun(N) ->
@@ -315,14 +342,16 @@ draw(Offset, Id, DC, Panel, Paint=#paint{pens=Pens, small=Small}, Data, Active)
strokeLines(DC, Lines),
N+1
end,
- [Draw(I) || I <- lists:seq(NoGraphs, 1, -1)];
+ [Draw(I) || I <- lists:seq(NoGraphs, 1, -1)],
+ DrawBs();
false ->
- Info = case Active andalso Samples =< 1 of
- true -> "Waiting on data";
+ DrawBs(),
+ Text = case Active andalso Samples =< 1 of
+ true -> "Waiting for data";
false -> "Information not available"
end,
setFont(DC, Small, {0,0,0}),
- drawText(DC, Info, X0 + 100, element(2,Size) div 2)
+ drawText(DC, Text, X0 + 100, element(2,Size) div 2)
end,
ok.
@@ -397,9 +426,8 @@ spline_tan(Y0, Y1, Y2, Y3) ->
-define(BW, 5).
-define(BH, 5).
-draw_borders(Type, NoGraphs, DC, {W,H}, Max,
+draw_borders(Type, Info, DC, {W,H}, {Max, Unit, MaxUnit},
#paint{pen=Pen, pen2=Pen2, font=Font, small=Small}) ->
- {Unit, MaxUnit} = bytes(Type, Max),
Str1 = observer_lib:to_str(MaxUnit),
Str2 = observer_lib:to_str(MaxUnit div 2),
Str3 = observer_lib:to_str(0),
@@ -410,10 +438,10 @@ draw_borders(Type, NoGraphs, DC, {W,H}, Max,
GraphX0 = ?BW+TW+?BW,
GraphX1 = W-?BW*4,
- TopTextX = ?BW+TW+?BW,
- MaxTextY = ?BH+TH+?BH,
+ TopTextX = ?BW*3+TW,
+ MaxTextY = TH+?BH,
BottomTextY = H-?BH-TH,
- SecondsY = BottomTextY - ?BH - TH,
+ SecondsY = BottomTextY - TH,
GraphY0 = MaxTextY + (TH / 2),
GraphY1 = SecondsY - ?BH,
GraphW = GraphX1-GraphX0-1,
@@ -447,17 +475,7 @@ draw_borders(Type, NoGraphs, DC, {W,H}, Max,
strokeLine(DC, GraphX0-3, GraphY50, GraphX1, GraphY50),
strokeLine(DC, GraphX0-3, GraphY75, GraphX1, GraphY75),
- setPen(DC, Pen2),
- strokeLines(DC, [{GraphX0, GraphY0-1}, {GraphX0, GraphY1+1},
- {GraphX1, GraphY1+1}, {GraphX1, GraphY0-1},
- {GraphX0, GraphY0-1}]),
-
setFont(DC, Font, {0,0,0}),
- case Type of
- ?RQ_W -> drawText(DC, "Scheduler Utilization (%) ", TopTextX,?BH);
- ?MEM_W -> drawText(DC, "Memory Usage " ++ Unit, TopTextX,?BH);
- ?IO_W -> drawText(DC, "IO Usage " ++ Unit, TopTextX,?BH)
- end,
Text = fun(X,Y, Str, PenId) ->
if PenId == 0 ->
@@ -468,32 +486,65 @@ draw_borders(Type, NoGraphs, DC, {W,H}, Max,
end,
drawText(DC, Str, X, Y),
{StrW, _} = getTextExtent(DC, Str),
- StrW + X + SpaceW
+ StrW + X + ?BW*2
end,
+
case Type of
- ?RQ_W ->
- TN0 = Text(?BW, BottomTextY, "Scheduler: ", 0),
+ runq ->
+ drawText(DC, "Scheduler Utilization (%) ", TopTextX, ?BH),
+ TN0 = Text(TopTextX, BottomTextY, "Scheduler: ", 0),
lists:foldl(fun(Id, Pos0) ->
Text(Pos0, BottomTextY, integer_to_list(Id), Id)
- end, TN0, lists:seq(1, NoGraphs));
- ?MEM_W ->
+ end, TN0, Info);
+ memory ->
+ drawText(DC, "Memory Usage " ++ Unit, TopTextX,?BH),
lists:foldl(fun(MType, {PenId, Pos0}) ->
- Str = uppercase(atom_to_list(MType)),
+ Str = to_string(MType),
Pos = Text(Pos0, BottomTextY, Str, PenId),
{PenId+1, Pos}
- end, {1, ?BW}, mem_types());
- ?IO_W ->
- TN0 = Text(?BW, BottomTextY, "Input", 1),
- Text(TN0, BottomTextY, "Output", 2)
+ end, {1, TopTextX}, Info);
+ io ->
+ drawText(DC, "IO Usage " ++ Unit, TopTextX,?BH),
+ lists:foldl(fun(MType, {PenId, Pos0}) ->
+ Str = to_string(MType),
+ Pos = Text(Pos0, BottomTextY, Str, PenId),
+ {PenId+1, Pos}
+ end, {1, TopTextX}, Info);
+ alloc ->
+ drawText(DC, "Carrier Size " ++ Unit, TopTextX,?BH);
+ utilz ->
+ drawText(DC, "Carrier Utilization (%)" ++ Unit, TopTextX,?BH),
+ lists:foldl(fun(MType, {PenId, Pos0}) ->
+ Str = to_string(MType),
+ Pos = Text(Pos0, BottomTextY, Str, PenId),
+ {PenId+1, Pos}
+ end, {1, TopTextX}, Info)
end,
- {GraphX0+1, GraphY1, ScaleW, ScaleH}.
+ DrawBorder = fun() ->
+ setPen(DC, Pen2),
+ strokeLines(DC, [{GraphX0, GraphY0-1}, {GraphX0, GraphY1+1},
+ {GraphX1, GraphY1+1}, {GraphX1, GraphY0-1},
+ {GraphX0, GraphY0-1}])
+ end,
+ {GraphX0+1, GraphY1, ScaleW, ScaleH, DrawBorder}.
+
+to_string(Atom) ->
+ Name = atom_to_list(Atom),
+ case lists:reverse(Name) of
+ "colla_" ++ Rev ->
+ uppercase(lists:reverse(Rev));
+ _ ->
+ uppercase(Name)
+ end.
uppercase([C|Rest]) ->
[C-$a+$A|Rest].
-calc_max(Max) when Max < 10 -> 10;
-calc_max(Max) -> calc_max1(Max).
+calc_max(Type, Max) ->
+ bytes(Type, Max).
+calc_max1(Max) when Max < 10 ->
+ 10;
calc_max1(Max) ->
case Max div 10 of
X when X < 10 ->
@@ -506,23 +557,36 @@ calc_max1(Max) ->
10*calc_max1(X)
end.
-bytes(?RQ_W, Val) -> {"", Val};
+bytes(runq, Val) ->
+ Upper = calc_max1(Val),
+ {Upper, "", Upper};
+bytes(utilz, Val) ->
+ Upper = calc_max1(Val),
+ {Upper, "", Upper};
bytes(_, B) ->
KB = B div 1024,
MB = KB div 1024,
GB = MB div 1024,
if
- GB > 10 -> {"(GB)", GB};
- MB > 10 -> {"(MB)", MB};
- KB > 0 -> {"(KB)", KB};
- true -> {"(B)", B}
+ GB > 10 ->
+ Upper = calc_max1(GB),
+ {Upper*1024*1024*1024, "(GB)", Upper};
+ MB > 10 ->
+ Upper = calc_max1(MB),
+ {Upper*1024*1024, "(MB)", Upper};
+ KB > 0 ->
+ Upper = calc_max1(KB),
+ {Upper*1024, "(KB)", Upper};
+ true ->
+ Upper = calc_max1(B),
+ {Upper, "(B)", Upper}
end.
colors() ->
- {{200, 50, 50}, {50, 200, 50}, {50, 50, 200},
- {255, 110, 0}, {50, 200, 200}, {200, 50, 200},
- {240, 200, 80}, {140, 2, 140},
- {100, 200, 240}, {100, 240, 100}
+ {{240, 100, 100}, {100, 240, 100}, {100, 100, 240},
+ {220, 220, 80}, {100, 240, 240}, {240, 100, 240},
+ {100, 25, 25}, {25, 100, 25}, {25, 25, 100},
+ {120, 120, 0}, {25, 100, 100}, {100, 50, 100}
}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl
index 0be8c18893..dd3441e482 100644
--- a/lib/observer/src/observer_pro_wx.erl
+++ b/lib/observer/src/observer_pro_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(observer_pro_wx).
@@ -578,7 +579,7 @@ get_row(From, Row, pid, Info) ->
end,
From ! {self(), Pid};
get_row(From, Row, Col, Info) ->
- Data = case Row > array:size(Info) of
+ Data = case Row >= array:size(Info) of
true ->
"";
false ->
diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl
index 8e8a37fc93..871ef603db 100644
--- a/lib/observer/src/observer_procinfo.erl
+++ b/lib/observer/src/observer_procinfo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -43,6 +44,8 @@
-record(worker, {panel, callback}).
+-record(io, {rdata=""}).
+
start(Process, ParentFrame, Parent) ->
wx_object:start_link(?MODULE, [Process, ParentFrame, Parent], []).
@@ -69,6 +72,10 @@ init([Pid, ParentFrame, Parent]) ->
DictPage = init_panel(Notebook, "Dictionary", [Pid,Table], fun init_dict_page/3),
StackPage = init_panel(Notebook, "Stack Trace", [Pid], fun init_stack_page/2),
StatePage = init_panel(Notebook, "State", [Pid,Table], fun init_state_page/3),
+ Ps = case gen_server:call(observer, log_status) of
+ true -> [init_panel(Notebook, "Log", [Pid,Table], fun init_log_page/3)];
+ false -> []
+ end,
wxFrame:connect(Frame, close_window),
wxMenu:connect(Frame, command_menu_selected),
@@ -78,7 +85,7 @@ init([Pid, ParentFrame, Parent]) ->
pid=Pid,
frame=Frame,
notebook=Notebook,
- pages=[ProcessPage,MessagePage,DictPage,StackPage,StatePage],
+ pages=[ProcessPage,MessagePage,DictPage,StackPage,StatePage|Ps],
expand_table=Table
}}
catch error:{badrpc, _} ->
@@ -144,7 +151,7 @@ handle_event(#wx{event=#wxHtmlLink{linkInfo=#wxHtmlLinkInfo{href=Href}}},
Opened =
case lists:keyfind(Id,1,Opened0) of
false ->
- Win = cdv_detail_wx:start_link(Id,Frame,Callback),
+ Win = cdv_detail_wx:start_link(Id,[],Frame,Callback),
[{Id,Win}|Opened0];
{_,Win} ->
wxFrame:raise(Win),
@@ -327,6 +334,26 @@ fetch_state_info2(Pid, M) ->
{badrpc,{'EXIT',{timeout, _}}} -> []
end.
+init_log_page(Parent, Pid, Table) ->
+ Win = observer_lib:html_window(Parent),
+ Update = fun() ->
+ Fd = spawn_link(fun() -> io_server() end),
+ rpc:call(node(Pid), rb, rescan, [[{start_log, Fd}]]),
+ rpc:call(node(Pid), rb, grep, [local_pid_str(Pid)]),
+ Logs = io_get_data(Fd),
+ %% Replace remote local pid notation to global notation
+ Pref = global_pid_node_pref(Pid),
+ ExpPid = re:replace(Logs,"<0\.","<" ++ Pref ++ ".",[global, {return, list}]),
+ %% Try to keep same look by removing blanks at right of rewritten PID
+ NbBlanks = length(Pref) - 1,
+ Re = "(<" ++ Pref ++ "\.[^>]{1,}>)[ ]{"++ integer_to_list(NbBlanks) ++ "}",
+ Look = re:replace(ExpPid, Re, "\\1", [global, {return, list}]),
+ Html = observer_html_lib:expandable_term("SaslLog", Look, Table),
+ wxHtmlWindow:setPage(Win, Html)
+ end,
+ Update(),
+ {Win, Update}.
+
create_menus(MenuBar) ->
Menus = [{"File", [#create_menu{id=?wxID_CLOSE, text="Close"}]},
{"View", [#create_menu{id=?REFRESH, text="Refresh\tCtrl-R"}]}],
@@ -409,3 +436,51 @@ filter_monitor_info() ->
Ms = proplists:get_value(monitors, Data),
[Pid || {process, Pid} <- Ms]
end.
+
+local_pid_str(Pid) ->
+ %% observer can observe remote nodes
+ %% There is no function to get the local
+ %% pid from the remote pid ...
+ %% So grep will fail to find remote pid in remote local log.
+ %% i.e. <4589.42.1> will not be found, but <0.42.1> will
+ %% Let's replace first integer by zero
+ "<0" ++ re:replace(pid_to_list(Pid),"\<([0-9]{1,})","",[{return, list}]).
+
+global_pid_node_pref(Pid) ->
+ %% Global PID node prefix : X of <X.Y.Z>
+ string:strip(string:sub_word(pid_to_list(Pid),1,$.),left,$<).
+
+
+io_get_data(Pid) ->
+ Pid ! {self(), get_data_and_close},
+ receive
+ {Pid, data, Data} -> lists:flatten(Data)
+ end.
+
+io_server() ->
+ io_server(#io{}).
+
+io_server(State) ->
+ receive
+ {io_request, From, ReplyAs, Request} ->
+ {_, Reply, NewState} = io_request(Request,State),
+ From ! {io_reply, ReplyAs, Reply},
+ io_server(NewState);
+ {Pid, get_data_and_close} ->
+ Pid ! {self(), data, lists:reverse(State#io.rdata)},
+ normal;
+ _Unknown ->
+ io_server(State)
+ end.
+
+io_request({put_chars, _Encoding, Chars}, State = #io{rdata=Data}) ->
+ {ok, ok, State#io{rdata=[Chars|Data]}};
+io_request({put_chars, Encoding, Module, Function, Args}, State) ->
+ try
+ io_request({put_chars, Encoding, apply(Module, Function, Args)}, State)
+ catch _:_ ->
+ {error, {error, Function}, State}
+ end;
+io_request(_Req, State) ->
+ %% io:format("~p: Unknown req: ~p ~n",[?LINE, _Req]),
+ {ok, {error, request}, State}.
diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl
index f989f9cf97..dfd15380f2 100644
--- a/lib/observer/src/observer_sys_wx.erl
+++ b/lib/observer/src/observer_sys_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(observer_sys_wx).
@@ -37,7 +38,6 @@
parent_notebook,
panel, sizer,
menubar,
- alloc,
fields,
timer}).
@@ -48,7 +48,6 @@ start_link(Notebook, Parent) ->
init([Notebook, Parent]) ->
SysInfo = observer_backend:sys_info(),
- AllocInfo = proplists:get_value(alloc_info, SysInfo, []),
{Info, Stat} = info_fields(),
Panel = wxPanel:new(Notebook),
Sizer = wxBoxSizer:new(?wxVERTICAL),
@@ -60,16 +59,13 @@ init([Notebook, Parent]) ->
wxSizer:add(TopSizer, FPanel0, [{flag, ?wxEXPAND}, {proportion, 1}]),
wxSizer:add(TopSizer, FPanel1, [{flag, ?wxEXPAND}, {proportion, 1}]),
BorderFlags = ?wxLEFT bor ?wxRIGHT,
- {MemPanel, MemoryInfo} = create_mem_info(Panel, AllocInfo),
wxSizer:add(Sizer, TopSizer, [{flag, ?wxEXPAND bor BorderFlags bor ?wxTOP},
{proportion, 0}, {border, 5}]),
- wxSizer:add(Sizer, MemPanel, [{flag, ?wxEXPAND bor BorderFlags bor ?wxBOTTOM},
- {proportion, 1}, {border, 5}]),
wxPanel:setSizer(Panel, Sizer),
Timer = observer_lib:start_timer(10),
{Panel, #sys_wx_state{parent=Parent,
parent_notebook=Notebook,
- panel=Panel, sizer=Sizer, alloc=MemoryInfo,
+ panel=Panel, sizer=Sizer,
timer=Timer, fields=Fields0 ++ Fields1}}.
create_sys_menu(Parent) ->
@@ -77,99 +73,21 @@ create_sys_menu(Parent) ->
#create_menu{id = ?ID_REFRESH_INTERVAL, text = "Refresh interval"}]},
observer_wx:create_menus(Parent, [View]).
-update_syspage(#sys_wx_state{node = Node, fields=Fields, sizer=Sizer, alloc=AllocCtrl}) ->
+update_syspage(#sys_wx_state{node = Node, fields=Fields, sizer=Sizer}) ->
SysInfo = observer_wx:try_rpc(Node, observer_backend, sys_info, []),
- AllocInfo = proplists:get_value(alloc_info, SysInfo, []),
{Info, Stat} = info_fields(),
observer_lib:update_info(Fields, observer_lib:fill_info(Info, SysInfo) ++
observer_lib:fill_info(Stat, SysInfo)),
- update_alloc(AllocCtrl, AllocInfo),
wxSizer:layout(Sizer).
-create_mem_info(Parent, Fields) ->
- Panel = wxPanel:new(Parent),
- wxWindow:setBackgroundColour(Panel, {255,255,255}),
- Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES bor ?wxLC_VRULES,
- Grid = wxListCtrl:new(Panel, [{style, Style}]),
- Li = wxListItem:new(),
- AddListEntry = fun({Name, Align, DefSize}, Col) ->
- wxListItem:setText(Li, Name),
- wxListItem:setAlign(Li, Align),
- wxListCtrl:insertColumn(Grid, Col, Li),
- wxListCtrl:setColumnWidth(Grid, Col, DefSize),
- Col + 1
- end,
- ListItems = [{"Allocator Type", ?wxLIST_FORMAT_LEFT, 200},
- {"Block size (kB)", ?wxLIST_FORMAT_RIGHT, 150},
- {"Carrier size (kB)",?wxLIST_FORMAT_RIGHT, 150}],
- lists:foldl(AddListEntry, 0, ListItems),
- wxListItem:destroy(Li),
- update_alloc(Grid, Fields),
-
- Sizer = wxBoxSizer:new(?wxVERTICAL),
- wxSizer:add(Sizer, Grid, [{flag, ?wxEXPAND bor ?wxLEFT bor ?wxRIGHT},
- {border, 5}, {proportion, 1}]),
- wxWindow:setSizerAndFit(Panel, Sizer),
- {Panel, Grid}.
-
-update_alloc(Grid, AllocInfo) ->
- Fields = alloc_info(AllocInfo, [], 0, 0, true),
- wxListCtrl:deleteAllItems(Grid),
- Update = fun({Name, BS, CS}, Row) ->
- wxListCtrl:insertItem(Grid, Row, ""),
- wxListCtrl:setItem(Grid, Row, 0, observer_lib:to_str(Name)),
- wxListCtrl:setItem(Grid, Row, 1, observer_lib:to_str(BS div 1024)),
- wxListCtrl:setItem(Grid, Row, 2, observer_lib:to_str(CS div 1024)),
- Row + 1
- end,
- lists:foldl(Update, 0, Fields),
- Fields.
-
-alloc_info([{Type,Instances}|Allocators],TypeAcc,TotalBS,TotalCS,IncludeTotal) ->
- {BS,CS,NewTotalBS,NewTotalCS,NewIncludeTotal} =
- sum_alloc_instances(Instances,0,0,TotalBS,TotalCS),
- alloc_info(Allocators,[{Type,BS,CS}|TypeAcc],NewTotalBS,NewTotalCS,
- IncludeTotal andalso NewIncludeTotal);
-alloc_info([],TypeAcc,TotalBS,TotalCS,IncludeTotal) ->
- Types = [X || X={_,BS,CS} <- TypeAcc, (BS>0 orelse CS>0)],
- case IncludeTotal of
- true ->
- [{total,TotalBS,TotalCS} | lists:reverse(Types)];
- false ->
- lists:reverse(Types)
- end.
-
-sum_alloc_instances(false,BS,CS,TotalBS,TotalCS) ->
- {BS,CS,TotalBS,TotalCS,false};
-sum_alloc_instances([{_,_,Data}|Instances],BS,CS,TotalBS,TotalCS) ->
- {NewBS,NewCS,NewTotalBS,NewTotalCS} =
- sum_alloc_one_instance(Data,BS,CS,TotalBS,TotalCS),
- sum_alloc_instances(Instances,NewBS,NewCS,NewTotalBS,NewTotalCS);
-sum_alloc_instances([],BS,CS,TotalBS,TotalCS) ->
- {BS,CS,TotalBS,TotalCS,true}.
-
-sum_alloc_one_instance([{sbmbcs,[{blocks_size,BS,_,_},{carriers_size,CS,_,_}]}|
- Rest],OldBS,OldCS,TotalBS,TotalCS) ->
- sum_alloc_one_instance(Rest,OldBS+BS,OldCS+CS,TotalBS,TotalCS);
-sum_alloc_one_instance([{_,[{blocks_size,BS,_,_},{carriers_size,CS,_,_}]}|
- Rest],OldBS,OldCS,TotalBS,TotalCS) ->
- sum_alloc_one_instance(Rest,OldBS+BS,OldCS+CS,TotalBS+BS,TotalCS+CS);
-sum_alloc_one_instance([{_,[{blocks_size,BS},{carriers_size,CS}]}|
- Rest],OldBS,OldCS,TotalBS,TotalCS) ->
- sum_alloc_one_instance(Rest,OldBS+BS,OldCS+CS,TotalBS+BS,TotalCS+CS);
-sum_alloc_one_instance([_|Rest],BS,CS,TotalBS,TotalCS) ->
- sum_alloc_one_instance(Rest,BS,CS,TotalBS,TotalCS);
-sum_alloc_one_instance([],BS,CS,TotalBS,TotalCS) ->
- {BS,CS,TotalBS,TotalCS}.
-
info_fields() ->
Info = [{"System and Architecture",
[{"System Version", otp_release},
- {"Erts Version", version},
+ {"ERTS Version", version},
{"Compiled for", system_architecture},
{"Emulator Wordsize", wordsize_external},
{"Process Wordsize", wordsize_internal},
- {"Smp Support", smp_support},
+ {"SMP Support", smp_support},
{"Thread Support", threads},
{"Async thread pool size", thread_pool_size}
]},
@@ -188,7 +106,7 @@ info_fields() ->
{"Atoms", {bytes, atom}},
{"Binaries", {bytes, binary}},
{"Code", {bytes, code}},
- {"Ets", {bytes, ets}}
+ {"ETS", {bytes, ets}}
]},
{"Statistics", right,
[{"Up time", {time_ms, uptime}},
diff --git a/lib/observer/src/observer_trace_wx.erl b/lib/observer/src/observer_trace_wx.erl
index 2878842c23..11c2acb561 100644
--- a/lib/observer/src/observer_trace_wx.erl
+++ b/lib/observer/src/observer_trace_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/observer/src/observer_traceoptions_wx.erl b/lib/observer/src/observer_traceoptions_wx.erl
index e27f565abc..9ba9b72b6f 100644
--- a/lib/observer/src/observer_traceoptions_wx.erl
+++ b/lib/observer/src/observer_traceoptions_wx.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -664,7 +665,7 @@ get_file(Text) ->
Str = wxTextCtrl:getValue(Text),
Dialog = wxFileDialog:new(Text,
[{message, "Select a file"},
- {default_file, Str}]),
+ {defaultFile, Str}]),
case wxDialog:showModal(Dialog) of
?wxID_OK ->
Dir = wxFileDialog:getDirectory(Dialog),
diff --git a/lib/observer/src/observer_tv.hrl b/lib/observer/src/observer_tv.hrl
index 05e4f928d0..8d57a6fa2b 100644
--- a/lib/observer/src/observer_tv.hrl
+++ b/lib/observer/src/observer_tv.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl
index 7757dfea53..75e6919642 100644
--- a/lib/observer/src/observer_tv_table.erl
+++ b/lib/observer/src/observer_tv_table.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -668,6 +669,7 @@ merge([], New, _Key) ->
merge(Old, New, Key) ->
merge2(keysort(Key, Old), keysort(Key, New), Key).
+-dialyzer({no_improper_lists, merge2/3}).
merge2([[Obj|_]|Old], [Obj|New], Key) ->
[[Obj]|merge2(Old, New, Key)];
merge2([[A|Op]|Old], [B|New], Key)
diff --git a/lib/observer/src/observer_tv_wx.erl b/lib/observer/src/observer_tv_wx.erl
index da4cb8e041..de498ff442 100644
--- a/lib/observer/src/observer_tv_wx.erl
+++ b/lib/observer/src/observer_tv_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(observer_tv_wx).
@@ -176,10 +177,16 @@ handle_call(Event, From, _State) ->
handle_cast(Event, _State) ->
error({unhandled_cast, Event}).
-handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt}) ->
- Tables = get_tables(Node, Opt),
- Tabs = update_grid(Grid, Opt, Tables),
- {noreply, State#state{tabs=Tabs}};
+handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt,
+ tabs=OldTabs}) ->
+ case get_tables(Node, Opt) of
+ OldTabs ->
+ %% no change
+ {noreply, State};
+ Tables ->
+ Tabs = update_grid(Grid, Opt, Tables),
+ {noreply, State#state{tabs=Tabs}}
+ end;
handle_info({active, Node}, State = #state{parent=Parent, grid=Grid, opt=Opt,
timer=Timer0}) ->
diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl
index 15df804975..68e814e01a 100644
--- a/lib/observer/src/observer_wx.erl
+++ b/lib/observer/src/observer_wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(observer_wx).
@@ -37,11 +38,13 @@
-define(ID_CONNECT, 2).
-define(ID_NOTEBOOK, 3).
-define(ID_CDV, 4).
+-define(ID_LOGVIEW, 5).
-define(FIRST_NODES_MENU_ID, 1000).
-define(LAST_NODES_MENU_ID, 2000).
-define(TRACE_STR, "Trace Overview").
+-define(ALLOC_STR, "Memory Allocators").
%% Records
-record(state,
@@ -57,10 +60,12 @@
trace_panel,
app_panel,
perf_panel,
+ allc_panel,
active_tab,
node,
nodes,
- prev_node=""
+ prev_node="",
+ log = false
}).
start() ->
@@ -147,6 +152,10 @@ setup(#state{frame = Frame} = State) ->
PerfPanel = observer_perf_wx:start_link(Notebook, self()),
wxNotebook:addPage(Notebook, PerfPanel, "Load Charts", []),
+ %% Memory Allocator Viewer Panel
+ AllcPanel = observer_alloc_wx:start_link(Notebook, self()),
+ wxNotebook:addPage(Notebook, AllcPanel, ?ALLOC_STR, []),
+
%% App Viewer Panel
AppPanel = observer_app_wx:start_link(Notebook, self()),
wxNotebook:addPage(Notebook, AppPanel, "Applications", []),
@@ -182,6 +191,7 @@ setup(#state{frame = Frame} = State) ->
trace_panel = TracePanel,
app_panel = AppPanel,
perf_panel = PerfPanel,
+ allc_panel = AllcPanel,
active_tab = SysPid,
node = node(),
nodes = Nodes
@@ -215,14 +225,17 @@ handle_event(#wx{event=#wxNotebook{type=command_notebook_page_changing}},
{noreply, State#state{active_tab=Pid}}
end;
-handle_event(#wx{event = #wxClose{}}, State) ->
- {stop, normal, State};
-
handle_event(#wx{id = ?ID_CDV, event = #wxCommand{type = command_menu_selected}}, State) ->
spawn(crashdump_viewer, start, []),
{noreply, State};
-handle_event(#wx{id = ?wxID_EXIT, event = #wxCommand{type = command_menu_selected}}, State) ->
+handle_event(#wx{event = #wxClose{}}, #state{log=LogOn} = State) ->
+ LogOn andalso rpc:block_call(State#state.node, rb, stop, []),
+ {stop, normal, State};
+
+handle_event(#wx{id = ?wxID_EXIT, event = #wxCommand{type = command_menu_selected}},
+ #state{log=LogOn} = State) ->
+ LogOn andalso rpc:block_call(State#state.node, rb, stop, []),
{stop, normal, State};
handle_event(#wx{id = ?wxID_HELP, event = #wxCommand{type = command_menu_selected}}, State) ->
@@ -300,12 +313,42 @@ handle_event(#wx{id = ?ID_PING, event = #wxCommand{type = command_menu_selected}
end,
{noreply, UpdState};
-handle_event(#wx{id = Id, event = #wxCommand{type = command_menu_selected}}, State)
- when Id > ?FIRST_NODES_MENU_ID, Id < ?LAST_NODES_MENU_ID ->
+handle_event(#wx{id = ?ID_LOGVIEW, event = #wxCommand{type = command_menu_selected}},
+ #state{frame = Frame, log = PrevLog, node = Node} = State) ->
+ try
+ ok = ensure_sasl_started(Node),
+ ok = ensure_mf_h_handler_used(Node),
+ ok = ensure_rb_mode(Node, PrevLog),
+ case PrevLog of
+ false ->
+ rpc:block_call(Node, rb, start, []),
+ set_status("Observer - " ++ atom_to_list(Node) ++ " (rb_server started)"),
+ {noreply, State#state{log=true}};
+ true ->
+ rpc:block_call(Node, rb, stop, []),
+ set_status("Observer - " ++ atom_to_list(Node) ++ " (rb_server stopped)"),
+ {noreply, State#state{log=false}}
+ end
+ catch
+ throw:Reason ->
+ create_txt_dialog(Frame, Reason, "Log view status", ?wxICON_ERROR),
+ {noreply, State}
+ end;
- Node = lists:nth(Id - ?FIRST_NODES_MENU_ID, State#state.nodes),
- UpdState = change_node_view(Node, State),
- {noreply, UpdState};
+handle_event(#wx{id = Id, event = #wxCommand{type = command_menu_selected}},
+ #state{nodes= Ns , node = PrevNode, log = PrevLog} = State)
+ when Id > ?FIRST_NODES_MENU_ID, Id < ?LAST_NODES_MENU_ID ->
+ Node = lists:nth(Id - ?FIRST_NODES_MENU_ID, Ns),
+ %% Close rb_server only if another node than current one selected
+ LState = case PrevLog of
+ true -> case Node == PrevNode of
+ false -> rpc:block_call(PrevNode, rb, stop, []),
+ State#state{log=false} ;
+ true -> State
+ end;
+ false -> State
+ end,
+ {noreply, change_node_view(Node, LState)};
handle_event(Event, State) ->
Pid = get_active_pid(State),
@@ -340,6 +383,9 @@ handle_call(stop, _, State = #state{frame = Frame}) ->
wxFrame:destroy(Frame),
{stop, normal, ok, State};
+handle_call(log_status, _From, State) ->
+ {reply, State#state.log, State};
+
handle_call(_Msg, _From, State) ->
{reply, ok, State}.
@@ -467,7 +513,7 @@ check_page_title(Notebook) ->
get_active_pid(#state{notebook=Notebook, pro_panel=Pro, sys_panel=Sys,
tv_panel=Tv, trace_panel=Trace, app_panel=App,
- perf_panel=Perf
+ perf_panel=Perf, allc_panel=Alloc
}) ->
Panel = case check_page_title(Notebook) of
"Processes" -> Pro;
@@ -475,13 +521,14 @@ get_active_pid(#state{notebook=Notebook, pro_panel=Pro, sys_panel=Sys,
"Table Viewer" -> Tv;
?TRACE_STR -> Trace;
"Load Charts" -> Perf;
- "Applications" -> App
+ "Applications" -> App;
+ ?ALLOC_STR -> Alloc
end,
wx_object:get_pid(Panel).
pid2panel(Pid, #state{pro_panel=Pro, sys_panel=Sys,
tv_panel=Tv, trace_panel=Trace, app_panel=App,
- perf_panel=Perf}) ->
+ perf_panel=Perf, allc_panel=Alloc}) ->
case Pid of
Pro -> "Processes";
Sys -> "System";
@@ -489,6 +536,7 @@ pid2panel(Pid, #state{pro_panel=Pro, sys_panel=Sys,
Trace -> ?TRACE_STR;
Perf -> "Load Charts";
App -> "Applications";
+ Alloc -> ?ALLOC_STR;
_ -> "unknown"
end.
@@ -568,17 +616,19 @@ default_menus(NodesMenuItems) ->
false -> {"Nodes", NodesMenuItems ++
[#create_menu{id = ?ID_CONNECT, text = "Enable distribution"}]}
end,
+ LogMenu = {"Log", [#create_menu{id = ?ID_LOGVIEW, text = "Toggle log view"}]},
case os:type() =:= {unix, darwin} of
false ->
FileMenu = {"File", [CDV, Quit]},
HelpMenu = {"Help", [About,Help]},
- [FileMenu, NodeMenu, HelpMenu];
+ [FileMenu, NodeMenu, LogMenu, HelpMenu];
true ->
%% On Mac quit and about will be moved to the "default' place
%% automagicly, so just add them to a menu that always exist.
%% But not to the help menu for some reason
+
{Tag, Menus} = FileMenu,
- [{Tag, Menus ++ [About]}, NodeMenu, {"&Help", [Help]}]
+ [{Tag, Menus ++ [Quit,About]}, NodeMenu, LogMenu, {"&Help", [Help]}]
end.
clean_menus(Menus, MenuBar) ->
@@ -657,3 +707,59 @@ update_node_list(State = #state{menubar=MenuBar}) ->
end,
observer_lib:create_menu_item(Dist, NodeMenu, Index),
State#state{nodes = Nodes}.
+
+ensure_sasl_started(Node) ->
+ %% is sasl started ?
+ Apps = rpc:block_call(Node, application, which_applications, []),
+ case lists:keyfind(sasl, 1, Apps) of
+ false -> throw("Error: sasl application not started."),
+ error;
+ {sasl, _, _} -> ok
+ end.
+
+ensure_mf_h_handler_used(Node) ->
+ %% is log_mf_h used ?
+ Handlers = rpc:block_call(Node, gen_event, which_handlers, [error_logger]),
+ case lists:any(fun(L)-> L == log_mf_h end, Handlers) of
+ false -> throw("Error: log_mf_h handler not used in sasl."),
+ error;
+ true -> ok
+ end.
+
+ensure_rb_mode(Node, PrevLog) ->
+ ok = ensure_rb_module_loaded(Node),
+ ok = is_rb_compatible(Node),
+ ok = is_rb_server_running(Node, PrevLog),
+ ok.
+
+
+ensure_rb_module_loaded(Node) ->
+ %% Need to ensure that module is loaded in order to detect exported
+ %% functions on interactive nodes
+ case rpc:block_call(Node, code, ensure_loaded, [rb]) of
+ {badrpc, Reason} ->
+ throw("Error: badrpc - " ++ io_lib:format("~tp",[Reason]));
+ {error, Reason} ->
+ throw("Error: rb module load error - " ++ io_lib:format("~tp",[Reason]));
+ {module,rb} ->
+ ok
+ end.
+
+is_rb_compatible(Node) ->
+ %% Simply test that rb:log_list/0 is exported
+ case rpc:block_call(Node, erlang, function_exported, [rb, log_list, 0]) of
+ false -> throw("Error: Node's Erlang release must be at least R16B02.");
+ true -> ok
+ end.
+
+is_rb_server_running(Node, LogState) ->
+ %% If already started, somebody else may use it.
+ %% We can not use it too, as far log file would be overriden. Not fair.
+ case rpc:block_call(Node, erlang, whereis, [rb_server]) of
+ Pid when is_pid(Pid), (LogState == false) ->
+ throw("Error: rb_server is already started and maybe used by someone.");
+ Pid when is_pid(Pid) ->
+ ok;
+ undefined ->
+ ok
+ end.
diff --git a/lib/observer/src/ttb.erl b/lib/observer/src/ttb.erl
index 61fd6d1787..3cba3b97b0 100644
--- a/lib/observer/src/ttb.erl
+++ b/lib/observer/src/ttb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -849,7 +850,7 @@ get_nodes() ->
receive {?MODULE,Nodes} -> Nodes end.
ts() ->
- {{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(now()),
+ {{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(erlang:timestamp()),
io_lib:format("-~4.4.0w~2.2.0w~2.2.0w-~2.2.0w~2.2.0w~2.2.0w",
[Y,M,D,H,Min,S]).
diff --git a/lib/observer/src/ttb_et.erl b/lib/observer/src/ttb_et.erl
index 60769f1cc2..683dd6c9a2 100644
--- a/lib/observer/src/ttb_et.erl
+++ b/lib/observer/src/ttb_et.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile
index 9df0591da5..e8bb7d0a52 100644
--- a/lib/observer/test/Makefile
+++ b/lib/observer/test/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl
index 0eb4a92c53..eea82d8c3c 100644
--- a/lib/observer/test/crashdump_helper.erl
+++ b/lib/observer/test/crashdump_helper.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl
index 03ab0c20e1..eae4ee01b9 100644
--- a/lib/observer/test/crashdump_viewer_SUITE.erl
+++ b/lib/observer/test/crashdump_viewer_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -101,7 +102,7 @@ end_per_group(_GroupName, Config) ->
init_per_suite(Config) when is_list(Config) ->
delete_saved(Config),
DataDir = ?config(data_dir,Config),
- Rels = [R || R <- [r15b,r16b], ?t:is_release_available(R)] ++ [current],
+ Rels = [R || R <- [r16b,'17'], ?t:is_release_available(R)] ++ [current],
io:format("Creating crash dumps for the following releases: ~p", [Rels]),
AllDumps = create_dumps(DataDir,Rels),
[{dumps,AllDumps}|Config].
@@ -563,28 +564,11 @@ dump_with_strange_module_name(DataDir,Rel,DumpName) ->
CD.
dump(Node,DataDir,Rel,DumpName) ->
- case Rel of
- _ when Rel<r15b, Rel=/=current ->
- rpc:call(Node,os,putenv,["ERL_CRASH_DUMP_SECONDS","600"]);
- _ ->
- ok
- end,
+ Crashdump = filename:join(DataDir, dump_prefix(Rel)++DumpName),
+ rpc:call(Node,os,putenv,["ERL_CRASH_DUMP",Crashdump]),
rpc:call(Node,erlang,halt,[DumpName]),
- Crashdump0 = filename:join(filename:dirname(code:which(?t)),
- "erl_crash_dump.n1"),
- Crashdump1 = filename:join(DataDir, dump_prefix(Rel)++DumpName),
- ok = rename(Crashdump0,Crashdump1),
- Crashdump1.
-
-rename(From,To) ->
- ok = check_complete(From),
- case file:rename(From,To) of
- {error,exdev} ->
- {ok,_} = file:copy(From,To),
- ok = file:delete(From);
- ok ->
- ok
- end.
+ ok = check_complete(Crashdump),
+ Crashdump.
check_complete(File) ->
check_complete1(File,10).
@@ -623,42 +607,21 @@ dos_dump(DataDir,Rel,Dump) ->
rel_opt(Rel) ->
case Rel of
- r9b -> [{erl,[{release,"r9b_patched"}]}];
- r9c -> [{erl,[{release,"r9c_patched"}]}];
- r10b -> [{erl,[{release,"r10b_patched"}]}];
- r11b -> [{erl,[{release,"r11b_patched"}]}];
- r12b -> [{erl,[{release,"r12b_patched"}]}];
- r13b -> [{erl,[{release,"r13b_patched"}]}];
- r14b -> [{erl,[{release,"r14b_latest"}]}]; %naming convention changed
- r15b -> [{erl,[{release,"r15b_latest"}]}];
r16b -> [{erl,[{release,"r16b_latest"}]}];
+ '17' -> [{erl,[{release,"17_latest"}]}];
current -> []
end.
dump_prefix(Rel) ->
case Rel of
- r9b -> "r9b_dump.";
- r9c -> "r9c_dump.";
- r10b -> "r10b_dump.";
- r11b -> "r11b_dump.";
- r12b -> "r12b_dump.";
- r13b -> "r13b_dump.";
- r14b -> "r14b_dump.";
- r15b -> "r15b_dump.";
r16b -> "r16b_dump.";
- current -> "r17b_dump."
+ '17' -> "r17_dump.";
+ current -> "r18_dump."
end.
compat_rel(Rel) ->
case Rel of
- r9b -> "+R9 ";
- r9c -> "+R9 ";
- r10b -> "+R10 ";
- r11b -> "+R11 ";
- r12b -> "+R12 ";
- r13b -> "+R13 ";
- r14b -> "+R14 ";
- r15b -> "+R15 ";
r16b -> "+R16 ";
+ '17' -> "+R17 ";
current -> ""
end.
diff --git a/lib/observer/test/etop_SUITE.erl b/lib/observer/test/etop_SUITE.erl
index 6ce3ea59cf..d4857c5e2f 100644
--- a/lib/observer/test/etop_SUITE.erl
+++ b/lib/observer/test/etop_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl
index 5cf719acb1..7f96d72e59 100644
--- a/lib/observer/test/observer_SUITE.erl
+++ b/lib/observer/test/observer_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,6 +23,8 @@
-include_lib("wx/include/wx.hrl").
-include_lib("observer/src/observer_tv.hrl").
+-define(ID_LOGVIEW, 5).
+
%% Test server specific exports
-export([all/0, suite/0,groups/0]).
-export([init_per_testcase/2, end_per_testcase/2,
@@ -44,8 +47,9 @@ all() ->
groups() ->
[{gui, [],
- [basic
- , process_win, table_win
+ [basic,
+ process_win,
+ table_win
]
}].
@@ -107,7 +111,7 @@ appup_file(Config) when is_list(Config) ->
basic(suite) -> [];
basic(doc) -> [""];
basic(Config) when is_list(Config) ->
- timer:send_after(100, "foobar"), %% Otherwise the timer sever gets added to procs
+ timer:send_after(100, "foobar"), %% Otherwise the timer server gets added to procs
ProcsBefore = processes(),
NumProcsBefore = length(ProcsBefore),
@@ -126,7 +130,7 @@ basic(Config) when is_list(Config) ->
timer:sleep(200),
ok = wxNotebook:advanceSelection(Notebook)
end,
- %% Just verify that we can toogle trough all pages
+ %% Just verify that we can toggle through all pages
[_|_] = [Check(N, false) || N <- lists:seq(1, Count)],
%% Cause it to resize
Frame = get_top_level_parent(Notebook),
@@ -214,10 +218,27 @@ test_page(Title, Window) ->
process_win(suite) -> [];
process_win(doc) -> [""];
process_win(Config) when is_list(Config) ->
+ % Stop SASL if already started
+ SaslStart = case whereis(sasl_sup) of
+ undefined -> false;
+ _ -> application:stop(sasl),
+ true
+ end,
+ % Define custom sasl and log_mf_h app vars
+ Privdir=?config(priv_dir,Config),
+ application:set_env(sasl, sasl_error_logger, tty),
+ application:set_env(sasl, error_logger_mf_dir, Privdir),
+ application:set_env(sasl, error_logger_mf_maxbytes, 1000),
+ application:set_env(sasl, error_logger_mf_maxfiles, 5),
+ application:start(sasl),
ok = observer:start(),
ObserverNB = setup_whitebox_testing(),
Parent = get_top_level_parent(ObserverNB),
- Frame = observer_procinfo:start(self(), Parent, self()),
+ % Activate log view
+ whereis(observer) ! #wx{id = ?ID_LOGVIEW, event = #wxCommand{type = command_menu_selected}},
+ timer:sleep(1000),
+ % Process window tests (use sasl_sup for a non empty Log tab)
+ Frame = observer_procinfo:start(whereis(sasl_sup), Parent, self()),
PIPid = wx_object:get_pid(Frame),
PIPid ! {get_debug_info, self()},
Notebook = receive {procinfo_debug, NB} -> NB end,
@@ -229,6 +250,11 @@ process_win(Config) when is_list(Config) ->
[_|_] = [Check(N) || N <- lists:seq(1, Count)],
PIPid ! #wx{event=#wxClose{type=close_window}},
observer:stop(),
+ application:stop(sasl),
+ case SaslStart of
+ true -> application:start(sasl);
+ false -> ok
+ end,
ok.
table_win(suite) -> [];
diff --git a/lib/observer/test/ttb_SUITE.erl b/lib/observer/test/ttb_SUITE.erl
index fd32e6aa71..bdf10f507d 100644
--- a/lib/observer/test/ttb_SUITE.erl
+++ b/lib/observer/test/ttb_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk
index 10ed3bdfe5..aede0858d6 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 2.0.4
+OBSERVER_VSN = 2.1.2
diff --git a/lib/odbc/Makefile b/lib/odbc/Makefile
index 4cc48cb559..b63a75270e 100644
--- a/lib/odbc/Makefile
+++ b/lib/odbc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/odbc/c_src/Makefile b/lib/odbc/c_src/Makefile
index acc79e33d5..93c971d679 100644
--- a/lib/odbc/c_src/Makefile
+++ b/lib/odbc/c_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/odbc/c_src/Makefile.in b/lib/odbc/c_src/Makefile.in
index 6572d28ee8..685eb5d150 100644
--- a/lib/odbc/c_src/Makefile.in
+++ b/lib/odbc/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index f4b0a5d8d0..6e8ab5b0c8 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index 7112fd2d47..24e3e8f3ec 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2002-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index 0cfcb9964b..4b05050ef6 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -3,16 +3,17 @@ dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 2005-2014. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
dnl
diff --git a/lib/odbc/doc/src/Makefile b/lib/odbc/doc/src/Makefile
index 53a855f182..96b4f07fe9 100644
--- a/lib/odbc/doc/src/Makefile
+++ b/lib/odbc/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/odbc/doc/src/book.xml b/lib/odbc/doc/src/book.xml
index 1c76c1cf85..4ead93f870 100644
--- a/lib/odbc/doc/src/book.xml
+++ b/lib/odbc/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/doc/src/databases.xml b/lib/odbc/doc/src/databases.xml
index f10282a24d..d81a53e936 100644
--- a/lib/odbc/doc/src/databases.xml
+++ b/lib/odbc/doc/src/databases.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/odbc/doc/src/error_handling.xml b/lib/odbc/doc/src/error_handling.xml
index 0b6179409d..83a0121035 100644
--- a/lib/odbc/doc/src/error_handling.xml
+++ b/lib/odbc/doc/src/error_handling.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/odbc/doc/src/getting_started.xml b/lib/odbc/doc/src/getting_started.xml
index 7397b5f5c5..64835b5be1 100644
--- a/lib/odbc/doc/src/getting_started.xml
+++ b/lib/odbc/doc/src/getting_started.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/odbc/doc/src/introduction.xml b/lib/odbc/doc/src/introduction.xml
index 98e805700e..148396edf0 100644
--- a/lib/odbc/doc/src/introduction.xml
+++ b/lib/odbc/doc/src/introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index 7a7658b092..59d46de02a 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,7 +32,47 @@
<p>This document describes the changes made to the odbc application.
</p>
- <section><title>ODBC 2.10.22</title>
+ <section><title>ODBC 2.11.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New application variable to set timeout of internal
+ communication setup between the erlang code and the
+ c-port program that interfaces the odbc driver. This can
+ be useful if you have an underlying system that is slow
+ due to heavy load at startup.</p>
+ <p>
+ With this environment variable you can easily bypass and
+ tailor odbc to the needs of the underlying actual system
+ without changing the configuration. Which is a good thing
+ because this value is very system specific.</p>
+ <p>
+ Own Id: OTP-12935</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.11</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.10.22</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/odbc/doc/src/notes_history.xml b/lib/odbc/doc/src/notes_history.xml
index 277bf9b460..d9f0449d9d 100644
--- a/lib/odbc/doc/src/notes_history.xml
+++ b/lib/odbc/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/doc/src/odbc.xml b/lib/odbc/doc/src/odbc.xml
index 99b9bbbe88..6a2a3587e4 100644
--- a/lib/odbc/doc/src/odbc.xml
+++ b/lib/odbc/doc/src/odbc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -220,6 +221,18 @@
and their meanings are dependent on the database being used.</item>
<item><c>Reason</c> is as per the <c>Reason</c> field when extended errors are not enabled.</item>
</list>
+
+ <note>
+ <p>The current implementation spawns a port programm
+ written in C that utilizes the actual ODBC driver. There
+ is a default timeout of 5000 msec for this port programm
+ to connect to the Erlang ODBC application. This timeout
+ can be changed by setting an application specific
+ environment variable 'port_timeout' with the number of
+ milliseconds for the ODBC application. E.g.: [{odbc,
+ [{port_timeout, 60000}]}] to set it to 60 seconds.
+ </p>
+ </note>
</desc>
</func>
<func>
diff --git a/lib/odbc/doc/src/part.xml b/lib/odbc/doc/src/part.xml
index 8d6255e083..98f4a6228b 100644
--- a/lib/odbc/doc/src/part.xml
+++ b/lib/odbc/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/doc/src/part_notes.xml b/lib/odbc/doc/src/part_notes.xml
index be2603d3a2..e7af9adc62 100644
--- a/lib/odbc/doc/src/part_notes.xml
+++ b/lib/odbc/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/doc/src/part_notes_history.xml b/lib/odbc/doc/src/part_notes_history.xml
index 89721ad0e7..f1c7005f46 100644
--- a/lib/odbc/doc/src/part_notes_history.xml
+++ b/lib/odbc/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/doc/src/ref_man.xml b/lib/odbc/doc/src/ref_man.xml
index b7f71ef496..642642737f 100644
--- a/lib/odbc/doc/src/ref_man.xml
+++ b/lib/odbc/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/odbc/include/odbc.hrl b/lib/odbc/include/odbc.hrl
index dc0a24192f..9bb7bd44a4 100644
--- a/lib/odbc/include/odbc.hrl
+++ b/lib/odbc/include/odbc.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/odbc/src/Makefile b/lib/odbc/src/Makefile
index bfbda8aaf4..51c9ed3d5c 100644
--- a/lib/odbc/src/Makefile
+++ b/lib/odbc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/odbc/src/odbc.appup.src b/lib/odbc/src/odbc.appup.src
index bf8872eae4..3580fe21b8 100644
--- a/lib/odbc/src/odbc.appup.src
+++ b/lib/odbc/src/odbc.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl
index ebfcd20d9a..12560bfb6e 100644
--- a/lib/odbc/src/odbc.erl
+++ b/lib/odbc/src/odbc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -25,6 +26,8 @@
-include("odbc_internal.hrl").
+-define(ODBC_PORT_TIMEOUT, 5000).
+
%% API --------------------------------------------------------------------
-export([start/0, start/1, stop/0,
@@ -522,10 +525,10 @@ handle_msg({connect, ODBCCmd, AutoCommitMode, SrollableCursors},
NewState = State#state{auto_commit_mode = AutoCommitMode,
scrollable_cursors = SrollableCursors},
- case gen_tcp:accept(ListenSocketSup, 5000) of
+ case gen_tcp:accept(ListenSocketSup, port_timeout()) of
{ok, SupSocket} ->
gen_tcp:close(ListenSocketSup),
- case gen_tcp:accept(ListenSocketOdbc, 5000) of
+ case gen_tcp:accept(ListenSocketOdbc, port_timeout()) of
{ok, OdbcSocket} ->
gen_tcp:close(ListenSocketOdbc),
odbc_send(OdbcSocket, ODBCCmd),
@@ -982,3 +985,6 @@ string_terminate_value(Binary) when is_binary(Binary) ->
<<Binary/binary,0:16>>;
string_terminate_value(null) ->
null.
+
+port_timeout() ->
+ application:get_env(?MODULE, port_timeout, ?ODBC_PORT_TIMEOUT).
diff --git a/lib/odbc/src/odbc_app.erl b/lib/odbc/src/odbc_app.erl
index 76d8ec1a8c..cbc4d325ad 100644
--- a/lib/odbc/src/odbc_app.erl
+++ b/lib/odbc/src/odbc_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/odbc/src/odbc_internal.hrl b/lib/odbc/src/odbc_internal.hrl
index bd80cdc659..0e0ed18a0f 100644
--- a/lib/odbc/src/odbc_internal.hrl
+++ b/lib/odbc/src/odbc_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/src/odbc_sup.erl b/lib/odbc/src/odbc_sup.erl
index 66b3e4de7c..96f0886f88 100644
--- a/lib/odbc/src/odbc_sup.erl
+++ b/lib/odbc/src/odbc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile
index d45073281b..114eb5373d 100644
--- a/lib/odbc/test/Makefile
+++ b/lib/odbc/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/odbc/test/README b/lib/odbc/test/README
index 1f3c659e28..fc9559ebe6 100644
--- a/lib/odbc/test/README
+++ b/lib/odbc/test/README
@@ -72,15 +72,16 @@ As odbc connection string use: "DSN=odbctestdb;UID=odbctest;PWD=Sesame"
>
> 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/.
+> Licensed under the Apache License, Version 2.0 (the "License");
+> you may not use this file except in compliance with the License.
+> You may obtain a copy of the License at
>
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
+> 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%
diff --git a/lib/odbc/test/mysql.erl b/lib/odbc/test/mysql.erl
index c990793213..02f1610570 100644
--- a/lib/odbc/test/mysql.erl
+++ b/lib/odbc/test/mysql.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 1907069726..2d4173a008 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -119,7 +120,16 @@ end_per_suite(_Config) ->
%% Note: This function is free to add any key/value pairs to the Config
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
+init_per_testcase(connect_port_timeout, Config) ->
+ odbc:stop(),
+ application:load(odbc),
+ application:set_env(odbc, port_timeout, 0),
+ odbc:start(),
+ init_per_testcase_common(Config);
init_per_testcase(_TestCase, Config) ->
+ init_per_testcase_common(Config).
+
+init_per_testcase_common(Config) ->
test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
Dog = test_server:timetrap(?default_timeout),
Temp = lists:keydelete(connection_ref, 1, Config),
@@ -134,7 +144,16 @@ init_per_testcase(_TestCase, Config) ->
%% A list of key/value pairs, holding the test case configuration.
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
+
+end_per_testcase(connect_port_timeout, Config) ->
+ application:unset_env(odbc, port_timeout),
+ odbc:stop(),
+ odbc:start(),
+ end_per_testcase_common(Config);
end_per_testcase(_TestCase, Config) ->
+ end_per_testcase_common(Config).
+
+end_per_testcase_common(Config) ->
Table = ?config(tableName, Config),
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
@@ -422,6 +441,18 @@ connect_timeout(Config) when is_list(Config) ->
%% Need to return ok here "{'EXIT',timeout} return value" will
%% be interpreted as that the testcase has timed out.
ok.
+
+%%-------------------------------------------------------------------------
+connect_port_timeout(doc) ->
+ ["Test the timeout for the port program to connect back to the odbc "
+ "application within the connect function."];
+connect_port_timeout(suite) -> [];
+connect_port_timeout(Config) when is_list(Config) ->
+ %% Application environment var 'port_timeout' has been set to 0 by
+ %% init_per_testcase/2.
+ {error,timeout} = odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()).
+
%%-------------------------------------------------------------------------
timeout(doc) ->
["Test that timeouts don't cause unwanted behavior sush as receiving"
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
index 95c094e081..a56af650c2 100644
--- a/lib/odbc/test/odbc_data_type_SUITE.erl
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
index 56550bfaa6..e8c2df7c31 100644
--- a/lib/odbc/test/odbc_query_SUITE.erl
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
index d75e615ed4..8fb564d1f9 100644
--- a/lib/odbc/test/odbc_start_SUITE.erl
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/odbc_test.hrl b/lib/odbc/test/odbc_test.hrl
index f7bb338a7f..7a4d9f3087 100644
--- a/lib/odbc/test/odbc_test.hrl
+++ b/lib/odbc/test/odbc_test.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl
index e814cd2aca..6f49c019e3 100644
--- a/lib/odbc/test/odbc_test_lib.erl
+++ b/lib/odbc/test/odbc_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl
index 3e49a1b64d..98e0147744 100644
--- a/lib/odbc/test/oracle.erl
+++ b/lib/odbc/test/oracle.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl
index 99a191c46a..7b41eb8c0a 100644
--- a/lib/odbc/test/postgres.erl
+++ b/lib/odbc/test/postgres.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/test/sqlserver.erl b/lib/odbc/test/sqlserver.erl
index 59252d4276..750d8d38e6 100644
--- a/lib/odbc/test/sqlserver.erl
+++ b/lib/odbc/test/sqlserver.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk
index 52c84429ec..c7c84560d1 100644
--- a/lib/odbc/vsn.mk
+++ b/lib/odbc/vsn.mk
@@ -1 +1 @@
-ODBC_VSN = 2.10.22
+ODBC_VSN = 2.11.1
diff --git a/lib/orber/COSS/CosNaming/CosNaming_BindingIterator_impl.erl b/lib/orber/COSS/CosNaming/CosNaming_BindingIterator_impl.erl
index 7d1791a785..95602ec54b 100644
--- a/lib/orber/COSS/CosNaming/CosNaming_BindingIterator_impl.erl
+++ b/lib/orber/COSS/CosNaming/CosNaming_BindingIterator_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl b/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
index 84db0b89f8..545be62852 100644
--- a/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
+++ b/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -533,7 +534,9 @@ unbind(_OE_THIS, _OE_State, []) ->
%% Returns :
%%----------------------------------------------------------------------
new_context(_OE_THIS, OE_State) ->
- DBKey = term_to_binary({now(), node()}),
+ DBKey = term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}),
%% Create a record in the table and set the key to a newly
{reply,
'CosNaming_NamingContextExt':oe_create(DBKey,
@@ -547,7 +550,9 @@ new_context(_OE_THIS, OE_State) ->
%% Returns :
%%----------------------------------------------------------------------
bind_new_context(OE_THIS, OE_State, N) ->
- DBKey = term_to_binary({now(), node()}),
+ DBKey = term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}),
%% Create a record in the table and set the key to a newly
%% generated objectkey.
%%?PRINTDEBUG("bind_new_context"),
diff --git a/lib/orber/COSS/CosNaming/Makefile b/lib/orber/COSS/CosNaming/Makefile
index 814062034c..0eca8ddfab 100644
--- a/lib/orber/COSS/CosNaming/Makefile
+++ b/lib/orber/COSS/CosNaming/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/COSS/CosNaming/lname.erl b/lib/orber/COSS/CosNaming/lname.erl
index 9f060d3296..388c4ac022 100644
--- a/lib/orber/COSS/CosNaming/lname.erl
+++ b/lib/orber/COSS/CosNaming/lname.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/COSS/CosNaming/lname.hrl b/lib/orber/COSS/CosNaming/lname.hrl
index de78e4bfc0..8f609df3ae 100644
--- a/lib/orber/COSS/CosNaming/lname.hrl
+++ b/lib/orber/COSS/CosNaming/lname.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/COSS/CosNaming/lname_component.erl b/lib/orber/COSS/CosNaming/lname_component.erl
index 9ded1d7e49..a3715d93d1 100644
--- a/lib/orber/COSS/CosNaming/lname_component.erl
+++ b/lib/orber/COSS/CosNaming/lname_component.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/COSS/CosNaming/orber_cosnaming.hrl b/lib/orber/COSS/CosNaming/orber_cosnaming.hrl
index 073158ed6a..c36ab47739 100644
--- a/lib/orber/COSS/CosNaming/orber_cosnaming.hrl
+++ b/lib/orber/COSS/CosNaming/orber_cosnaming.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
index c665e1fbc8..cb240c3011 100644
--- a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
+++ b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/Makefile b/lib/orber/Makefile
index 58a673d30e..920cc7350c 100644
--- a/lib/orber/Makefile
+++ b/lib/orber/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/c_src/InitialReference.cc b/lib/orber/c_src/InitialReference.cc
index a95fa0f599..053f3c9c8e 100644
--- a/lib/orber/c_src/InitialReference.cc
+++ b/lib/orber/c_src/InitialReference.cc
@@ -4,16 +4,17 @@
* <holder>Ericsson AB, All Rights Reserved</holder>
*</copyright>
*<legalnotice>
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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.
*
* The Initial Developer of the Original Code is Ericsson AB.
*</legalnotice>
diff --git a/lib/orber/c_src/InitialReference.hh b/lib/orber/c_src/InitialReference.hh
index 1c3c5c8e0d..79725522db 100644
--- a/lib/orber/c_src/InitialReference.hh
+++ b/lib/orber/c_src/InitialReference.hh
@@ -4,16 +4,17 @@
* <holder>Ericsson AB, All Rights Reserved</holder>
*</copyright>
*<legalnotice>
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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.
*
* The Initial Developer of the Original Code is Ericsson AB.
*</legalnotice>
diff --git a/lib/orber/c_src/Makefile b/lib/orber/c_src/Makefile
index 73ab79d145..bbf51d0efd 100644
--- a/lib/orber/c_src/Makefile
+++ b/lib/orber/c_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/c_src/Makefile.in b/lib/orber/c_src/Makefile.in
index 126ed8af21..e1323f1cc9 100644
--- a/lib/orber/c_src/Makefile.in
+++ b/lib/orber/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/c_src/main.cc b/lib/orber/c_src/main.cc
index c1d17078c5..109aaf824a 100644
--- a/lib/orber/c_src/main.cc
+++ b/lib/orber/c_src/main.cc
@@ -4,16 +4,17 @@
* <holder>Ericsson AB, All Rights Reserved</holder>
*</copyright>
*<legalnotice>
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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.
*
* The Initial Developer of the Original Code is Ericsson AB.
*</legalnotice>
diff --git a/lib/orber/doc/src/CosNaming.xml b/lib/orber/doc/src/CosNaming.xml
index 9bdd5bff94..a4e8e02702 100644
--- a/lib/orber/doc/src/CosNaming.xml
+++ b/lib/orber/doc/src/CosNaming.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/orber/doc/src/CosNaming_BindingIterator.xml b/lib/orber/doc/src/CosNaming_BindingIterator.xml
index 8be1677a45..2a8f3633ca 100644
--- a/lib/orber/doc/src/CosNaming_BindingIterator.xml
+++ b/lib/orber/doc/src/CosNaming_BindingIterator.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/CosNaming_NamingContext.xml b/lib/orber/doc/src/CosNaming_NamingContext.xml
index 3c620024a9..313015f5ee 100644
--- a/lib/orber/doc/src/CosNaming_NamingContext.xml
+++ b/lib/orber/doc/src/CosNaming_NamingContext.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/CosNaming_NamingContextExt.xml b/lib/orber/doc/src/CosNaming_NamingContextExt.xml
index c3cab87e61..ede908e13f 100644
--- a/lib/orber/doc/src/CosNaming_NamingContextExt.xml
+++ b/lib/orber/doc/src/CosNaming_NamingContextExt.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/Makefile b/lib/orber/doc/src/Makefile
index 4cd7c45437..c9c362b336 100644
--- a/lib/orber/doc/src/Makefile
+++ b/lib/orber/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/orber/doc/src/Module_Interface.xml b/lib/orber/doc/src/Module_Interface.xml
index 8ae7ab6e46..27335673cc 100644
--- a/lib/orber/doc/src/Module_Interface.xml
+++ b/lib/orber/doc/src/Module_Interface.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/Orber/InitialReference.java b/lib/orber/doc/src/Orber/InitialReference.java
index 300de59139..0ae2ebfb68 100644
--- a/lib/orber/doc/src/Orber/InitialReference.java
+++ b/lib/orber/doc/src/Orber/InitialReference.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/orber/doc/src/Orber/Makefile b/lib/orber/doc/src/Orber/Makefile
index 49da975a8b..278fa182ee 100644
--- a/lib/orber/doc/src/Orber/Makefile
+++ b/lib/orber/doc/src/Orber/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/doc/src/any.xml b/lib/orber/doc/src/any.xml
index 0c0a0f5f68..8234b62be3 100644
--- a/lib/orber/doc/src/any.xml
+++ b/lib/orber/doc/src/any.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/book.xml b/lib/orber/doc/src/book.xml
index 7ce153bbfe..dc073fdeda 100644
--- a/lib/orber/doc/src/book.xml
+++ b/lib/orber/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_contents.xml b/lib/orber/doc/src/ch_contents.xml
index d7f042ffa0..6ac9f1cb11 100644
--- a/lib/orber/doc/src/ch_contents.xml
+++ b/lib/orber/doc/src/ch_contents.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_debugging.xml b/lib/orber/doc/src/ch_debugging.xml
index 3c9b3d3da5..2fbc9285eb 100644
--- a/lib/orber/doc/src/ch_debugging.xml
+++ b/lib/orber/doc/src/ch_debugging.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_exceptions.xml b/lib/orber/doc/src/ch_exceptions.xml
index a625eb503d..8a8cb9d470 100644
--- a/lib/orber/doc/src/ch_exceptions.xml
+++ b/lib/orber/doc/src/ch_exceptions.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
index ed27ab04af..debd0cf888 100644
--- a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
+++ b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_ifr.xml b/lib/orber/doc/src/ch_ifr.xml
index 4e3fedba3a..c34a6fabd5 100644
--- a/lib/orber/doc/src/ch_ifr.xml
+++ b/lib/orber/doc/src/ch_ifr.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_install.xml b/lib/orber/doc/src/ch_install.xml
index 6b526a0b2a..5fb7d7b9a3 100644
--- a/lib/orber/doc/src/ch_install.xml
+++ b/lib/orber/doc/src/ch_install.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_interceptors.xml b/lib/orber/doc/src/ch_interceptors.xml
index c6d3fa2475..111e00cb5b 100644
--- a/lib/orber/doc/src/ch_interceptors.xml
+++ b/lib/orber/doc/src/ch_interceptors.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_introduction.xml b/lib/orber/doc/src/ch_introduction.xml
index 8d3d499324..fc86ad2dc6 100644
--- a/lib/orber/doc/src/ch_introduction.xml
+++ b/lib/orber/doc/src/ch_introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_naming_service.xml b/lib/orber/doc/src/ch_naming_service.xml
index e355db2edb..4a9c970cb4 100644
--- a/lib/orber/doc/src/ch_naming_service.xml
+++ b/lib/orber/doc/src/ch_naming_service.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_orber_kernel.xml b/lib/orber/doc/src/ch_orber_kernel.xml
index 1a9026f9b7..66d33d065c 100644
--- a/lib/orber/doc/src/ch_orber_kernel.xml
+++ b/lib/orber/doc/src/ch_orber_kernel.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_orberweb.xml b/lib/orber/doc/src/ch_orberweb.xml
index 2a17207616..804d22ff49 100644
--- a/lib/orber/doc/src/ch_orberweb.xml
+++ b/lib/orber/doc/src/ch_orberweb.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_security.xml b/lib/orber/doc/src/ch_security.xml
index 9b56319a47..6b5c9b90ec 100644
--- a/lib/orber/doc/src/ch_security.xml
+++ b/lib/orber/doc/src/ch_security.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ch_stubs.xml b/lib/orber/doc/src/ch_stubs.xml
index e0e0003af0..e055658b6c 100644
--- a/lib/orber/doc/src/ch_stubs.xml
+++ b/lib/orber/doc/src/ch_stubs.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/corba.xml b/lib/orber/doc/src/corba.xml
index 4a11b271b4..89288cdf6b 100644
--- a/lib/orber/doc/src/corba.xml
+++ b/lib/orber/doc/src/corba.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/corba_object.xml b/lib/orber/doc/src/corba_object.xml
index 84bf775f78..37b0dc9fd0 100644
--- a/lib/orber/doc/src/corba_object.xml
+++ b/lib/orber/doc/src/corba_object.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/example_part.xml b/lib/orber/doc/src/example_part.xml
index d8970be912..9460fdc9b0 100644
--- a/lib/orber/doc/src/example_part.xml
+++ b/lib/orber/doc/src/example_part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/orber/doc/src/fixed.xml b/lib/orber/doc/src/fixed.xml
index fc34c89e7e..7036e8917f 100644
--- a/lib/orber/doc/src/fixed.xml
+++ b/lib/orber/doc/src/fixed.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/interceptors.xml b/lib/orber/doc/src/interceptors.xml
index 739da8ab2f..780739fd96 100644
--- a/lib/orber/doc/src/interceptors.xml
+++ b/lib/orber/doc/src/interceptors.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/intro_part.xml b/lib/orber/doc/src/intro_part.xml
index a44f0fa786..45c121cc57 100644
--- a/lib/orber/doc/src/intro_part.xml
+++ b/lib/orber/doc/src/intro_part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/lname.xml b/lib/orber/doc/src/lname.xml
index 284a50b900..dc7928e5de 100644
--- a/lib/orber/doc/src/lname.xml
+++ b/lib/orber/doc/src/lname.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/lname_component.xml b/lib/orber/doc/src/lname_component.xml
index 9c0134609e..bf1d1e5375 100644
--- a/lib/orber/doc/src/lname_component.xml
+++ b/lib/orber/doc/src/lname_component.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 2167a43eee..1da60ba486 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -33,7 +34,37 @@
</header>
- <section><title>Orber 3.7.1</title>
+ <section><title>Orber 3.8.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Suppress Dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-12862</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Orber 3.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Remove the usage of erlang:now() from all Corba
+ applications and use the new rand module instead of
+ random. </p>
+ <p>
+ Own Id: OTP-12687</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Orber 3.7.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
@@ -152,11 +183,9 @@
<section><title>Known Bugs and Problems</title>
<list>
<item>
- <p>
- <p>
- </p></p>
<p>
- Own Id: OTP-10675 Aux Id: seq12154 </p>
+ Own Id: OTP-10675 Aux Id: seq12154
+ </p>
</item>
</list>
</section>
diff --git a/lib/orber/doc/src/orber.xml b/lib/orber/doc/src/orber.xml
index a182a56972..577bb2ee05 100644
--- a/lib/orber/doc/src/orber.xml
+++ b/lib/orber/doc/src/orber.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/orber/doc/src/orber_acl.xml b/lib/orber/doc/src/orber_acl.xml
index f78e27fc4e..ab3a35df36 100644
--- a/lib/orber/doc/src/orber_acl.xml
+++ b/lib/orber/doc/src/orber_acl.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/orber_diagnostics.xml b/lib/orber/doc/src/orber_diagnostics.xml
index c9453cfce6..a53391bb9a 100644
--- a/lib/orber/doc/src/orber_diagnostics.xml
+++ b/lib/orber/doc/src/orber_diagnostics.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/orber_ifr.xml b/lib/orber/doc/src/orber_ifr.xml
index c2dc4ff552..c9b6fe6459 100644
--- a/lib/orber/doc/src/orber_ifr.xml
+++ b/lib/orber/doc/src/orber_ifr.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/orber_tc.xml b/lib/orber/doc/src/orber_tc.xml
index 50239d7b5e..7c49ebce11 100644
--- a/lib/orber/doc/src/orber_tc.xml
+++ b/lib/orber/doc/src/orber_tc.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/doc/src/part.xml b/lib/orber/doc/src/part.xml
index a8c13588b5..236e93e73e 100644
--- a/lib/orber/doc/src/part.xml
+++ b/lib/orber/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/orber/doc/src/part_notes.xml b/lib/orber/doc/src/part_notes.xml
index f16a2bc343..d4c217e158 100644
--- a/lib/orber/doc/src/part_notes.xml
+++ b/lib/orber/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/ref_man.xml b/lib/orber/doc/src/ref_man.xml
index 361b197ef4..4785c18ff6 100644
--- a/lib/orber/doc/src/ref_man.xml
+++ b/lib/orber/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/orber/doc/src/tools_debugging_part.xml b/lib/orber/doc/src/tools_debugging_part.xml
index 683baab601..7a718ad448 100644
--- a/lib/orber/doc/src/tools_debugging_part.xml
+++ b/lib/orber/doc/src/tools_debugging_part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/orber/examples/Makefile b/lib/orber/examples/Makefile
index 5b8e06bd37..06b0be9c4d 100644
--- a/lib/orber/examples/Makefile
+++ b/lib/orber/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/examples/Stack/Makefile b/lib/orber/examples/Stack/Makefile
index 1cbb983cd6..abdd65823f 100644
--- a/lib/orber/examples/Stack/Makefile
+++ b/lib/orber/examples/Stack/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/examples/Stack/StackClient.cc b/lib/orber/examples/Stack/StackClient.cc
index 30ed85fa58..4d393390c4 100644
--- a/lib/orber/examples/Stack/StackClient.cc
+++ b/lib/orber/examples/Stack/StackClient.cc
@@ -4,16 +4,17 @@
* <holder>Ericsson AB, All Rights Reserved</holder>
*</copyright>
*<legalnotice>
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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.
*
* The Initial Developer of the Original Code is Ericsson AB.
*</legalnotice>
diff --git a/lib/orber/examples/Stack/StackClient.java b/lib/orber/examples/Stack/StackClient.java
index 4e8c0176a8..55c9c258bd 100644
--- a/lib/orber/examples/Stack/StackClient.java
+++ b/lib/orber/examples/Stack/StackClient.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/orber/examples/Stack/StackModule_StackFactory_impl.erl b/lib/orber/examples/Stack/StackModule_StackFactory_impl.erl
index e283b6f765..1fc1f6fa8e 100644
--- a/lib/orber/examples/Stack/StackModule_StackFactory_impl.erl
+++ b/lib/orber/examples/Stack/StackModule_StackFactory_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/examples/Stack/StackModule_Stack_impl.erl b/lib/orber/examples/Stack/StackModule_Stack_impl.erl
index 87b5e8a275..5b882badec 100644
--- a/lib/orber/examples/Stack/StackModule_Stack_impl.erl
+++ b/lib/orber/examples/Stack/StackModule_Stack_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/examples/Stack/stack_client.erl b/lib/orber/examples/Stack/stack_client.erl
index c90af33ff8..4b508ace8d 100644
--- a/lib/orber/examples/Stack/stack_client.erl
+++ b/lib/orber/examples/Stack/stack_client.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/examples/Stack/stack_factory.erl b/lib/orber/examples/Stack/stack_factory.erl
index 2f09b18fc4..7f9cfb7196 100644
--- a/lib/orber/examples/Stack/stack_factory.erl
+++ b/lib/orber/examples/Stack/stack_factory.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/include/corba.hrl b/lib/orber/include/corba.hrl
index b9869855bf..9acdfd808b 100644
--- a/lib/orber/include/corba.hrl
+++ b/lib/orber/include/corba.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/include/ifr_types.hrl b/lib/orber/include/ifr_types.hrl
index 324b32bd4f..451b5c622d 100644
--- a/lib/orber/include/ifr_types.hrl
+++ b/lib/orber/include/ifr_types.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/include/orber_pi.hrl b/lib/orber/include/orber_pi.hrl
index 84231758fe..b160cdae3e 100644
--- a/lib/orber/include/orber_pi.hrl
+++ b/lib/orber/include/orber_pi.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/java_src/Makefile b/lib/orber/java_src/Makefile
index 27166664b7..bc604be179 100644
--- a/lib/orber/java_src/Makefile
+++ b/lib/orber/java_src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/java_src/Orber/InitialReference.java b/lib/orber/java_src/Orber/InitialReference.java
index 300de59139..0ae2ebfb68 100644
--- a/lib/orber/java_src/Orber/InitialReference.java
+++ b/lib/orber/java_src/Orber/InitialReference.java
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*
diff --git a/lib/orber/java_src/Orber/Makefile b/lib/orber/java_src/Orber/Makefile
index f7f7336622..d42b8ad982 100644
--- a/lib/orber/java_src/Orber/Makefile
+++ b/lib/orber/java_src/Orber/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/priv/Makefile b/lib/orber/priv/Makefile
index cd361e3f0a..b8fafd952c 100644
--- a/lib/orber/priv/Makefile
+++ b/lib/orber/priv/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/src/Makefile b/lib/orber/src/Makefile
index 398e481138..30b74c490a 100644
--- a/lib/orber/src/Makefile
+++ b/lib/orber/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/orber/src/OrberApp_IFR_impl.erl b/lib/orber/src/OrberApp_IFR_impl.erl
index c0c6eb4704..468e1d80a3 100644
--- a/lib/orber/src/OrberApp_IFR_impl.erl
+++ b/lib/orber/src/OrberApp_IFR_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/any.erl b/lib/orber/src/any.erl
index b5ad34365b..03354fd632 100644
--- a/lib/orber/src/any.erl
+++ b/lib/orber/src/any.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/cdr_decode.erl b/lib/orber/src/cdr_decode.erl
index 9aec64892e..fd021988c9 100644
--- a/lib/orber/src/cdr_decode.erl
+++ b/lib/orber/src/cdr_decode.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1110,10 +1111,8 @@ ifrid_to_name(Id, Type) ->
[?LINE, Id, Type], ?DEBUG_LEVEL),
corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE});
Nodes ->
- {A,B,C} = now(),
- random:seed(A,B,C),
L = length(Nodes),
- IFR = get_ifr_node(Nodes, random:uniform(L), L),
+ IFR = get_ifr_node(Nodes, rand:uniform(L), L),
list_to_atom('OrberApp_IFR':get_absolute_name(IFR, Id))
end;
{'EXIT', Other} ->
@@ -1176,7 +1175,7 @@ get_ifr_node(Nodes, N, L) ->
_ ->
%% Not able to commincate with the node. Try next one.
NewL = L-1,
- get_ifr_node(lists:delete(Node, Nodes), random:uniform(NewL), NewL)
+ get_ifr_node(lists:delete(Node, Nodes), rand:uniform(NewL), NewL)
end.
@@ -1260,10 +1259,8 @@ get_user_exception_type(TypeId) ->
completion_status=?COMPLETED_MAYBE})
end;
Nodes ->
- {A,B,C} = now(),
- random:seed(A,B,C),
L = length(Nodes),
- IFR = get_ifr_node(Nodes, random:uniform(L), L),
+ IFR = get_ifr_node(Nodes, rand:uniform(L), L),
'OrberApp_IFR':get_user_exception_type(IFR, TypeId)
end
end.
diff --git a/lib/orber/src/cdr_encode.erl b/lib/orber/src/cdr_encode.erl
index eaf3c5b7dc..ce0b5066fc 100644
--- a/lib/orber/src/cdr_encode.erl
+++ b/lib/orber/src/cdr_encode.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/cdrlib.erl b/lib/orber/src/cdrlib.erl
index 8fd032e968..cbe25f6d84 100644
--- a/lib/orber/src/cdrlib.erl
+++ b/lib/orber/src/cdrlib.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/corba.erl b/lib/orber/src/corba.erl
index 586a02d540..faebbc4059 100644
--- a/lib/orber/src/corba.erl
+++ b/lib/orber/src/corba.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1922,7 +1923,9 @@ mk_passive_objkey(Mod, Module, Flags) ->
{Mod, 'passive', Module, term_to_binary(undefined), 0, Flags}.
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
objkey_to_string({_Mod, 'registered', 'orber_init', _UserDef, _OrberDef, _Flags}) ->
"INIT";
diff --git a/lib/orber/src/corba_boa.erl b/lib/orber/src/corba_boa.erl
index 52f2aa791c..830e3795e6 100644
--- a/lib/orber/src/corba_boa.erl
+++ b/lib/orber/src/corba_boa.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/corba_nvlist.erl b/lib/orber/src/corba_nvlist.erl
index d4bb8bff6a..e221fa1ef0 100644
--- a/lib/orber/src/corba_nvlist.erl
+++ b/lib/orber/src/corba_nvlist.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/corba_object.erl b/lib/orber/src/corba_object.erl
index 49e388b25f..32a4f76d71 100644
--- a/lib/orber/src/corba_object.erl
+++ b/lib/orber/src/corba_object.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/fixed.erl b/lib/orber/src/fixed.erl
index 255c86c22a..63058256c9 100644
--- a/lib/orber/src/fixed.erl
+++ b/lib/orber/src/fixed.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/ifr_objects.hrl b/lib/orber/src/ifr_objects.hrl
index 0d7c30a86c..a05eb3af56 100644
--- a/lib/orber/src/ifr_objects.hrl
+++ b/lib/orber/src/ifr_objects.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/iop_ior.erl b/lib/orber/src/iop_ior.erl
index 5bfc31e0e4..45a6eda157 100644
--- a/lib/orber/src/iop_ior.erl
+++ b/lib/orber/src/iop_ior.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber.app.src b/lib/orber/src/orber.app.src
index 30bd90347d..217c1b247f 100644
--- a/lib/orber/src/orber.app.src
+++ b/lib/orber/src/orber.app.src
@@ -104,8 +104,8 @@
{applications, [stdlib, kernel, mnesia]},
{env, []},
{mod, {orber, []}},
- {runtime_dependencies, ["stdlib-2.0","ssl-5.3.4","mnesia-4.12","kernel-3.0",
- "inets-5.10","erts-6.0"]}
+ {runtime_dependencies, ["stdlib-2.5","ssl-5.3.4","mnesia-4.12","kernel-3.0",
+ "inets-5.10","erts-7.0"]}
]}.
diff --git a/lib/orber/src/orber.erl b/lib/orber/src/orber.erl
index 5ab240e046..061b02fd02 100644
--- a/lib/orber/src/orber.erl
+++ b/lib/orber/src/orber.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/src/orber_acl.erl b/lib/orber/src/orber_acl.erl
index 5c696a9b2a..c5a412398e 100644
--- a/lib/orber/src/orber_acl.erl
+++ b/lib/orber/src/orber_acl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_diagnostics.erl b/lib/orber/src/orber_diagnostics.erl
index 3ab55c448d..4206ae9be8 100644
--- a/lib/orber/src/orber_diagnostics.erl
+++ b/lib/orber/src/orber_diagnostics.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_env.erl b/lib/orber/src/orber_env.erl
index 16dbb74253..98d1420148 100644
--- a/lib/orber/src/orber_env.erl
+++ b/lib/orber/src/orber_env.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/src/orber_exceptions.erl b/lib/orber/src/orber_exceptions.erl
index 9ee6e31aeb..257724e06d 100644
--- a/lib/orber/src/orber_exceptions.erl
+++ b/lib/orber/src/orber_exceptions.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr.erl b/lib/orber/src/orber_ifr.erl
index 4004ffa005..70e0cb3fca 100644
--- a/lib/orber/src/orber_ifr.erl
+++ b/lib/orber/src/orber_ifr.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -779,6 +780,7 @@ find_repository() ->
'Repository__get_def_kind'(Objref) ->
orber_ifr_repository:'_get_def_kind'(Objref).
+-spec 'Repository_destroy'(_) -> no_return().
'Repository_destroy'(Objref) ->
orber_ifr_repository:destroy(Objref).
'Repository_lookup'(Objref,Search_name) ->
@@ -1404,6 +1406,7 @@ find_repository() ->
orber_ifr_orb:create_wstring_tc(Bound).
'ORB_create_sequence_tc'(Bound,Element_type) ->
orber_ifr_orb:create_sequence_tc(Bound,Element_type).
+-spec 'ORB_create_recursive_sequence_tc'(_,_) -> no_return().
'ORB_create_recursive_sequence_tc'(Bound,Offset) ->
orber_ifr_orb:create_recursive_sequence_tc(Bound,Offset).
'ORB_create_array_tc'(Length,Element_type) ->
diff --git a/lib/orber/src/orber_ifr.hrl b/lib/orber/src/orber_ifr.hrl
index a9b791cc97..9779e9246c 100644
--- a/lib/orber/src/orber_ifr.hrl
+++ b/lib/orber/src/orber_ifr.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_aliasdef.erl b/lib/orber/src/orber_ifr_aliasdef.erl
index ab25c73f47..ddc93f98ec 100644
--- a/lib/orber/src/orber_ifr_aliasdef.erl
+++ b/lib/orber/src/orber_ifr_aliasdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_arraydef.erl b/lib/orber/src/orber_ifr_arraydef.erl
index 5b55f2da86..9e22fc221b 100644
--- a/lib/orber/src/orber_ifr_arraydef.erl
+++ b/lib/orber/src/orber_ifr_arraydef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_attributedef.erl b/lib/orber/src/orber_ifr_attributedef.erl
index 866ac3ae26..a4f20e4a88 100644
--- a/lib/orber/src/orber_ifr_attributedef.erl
+++ b/lib/orber/src/orber_ifr_attributedef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_constantdef.erl b/lib/orber/src/orber_ifr_constantdef.erl
index c966e8ed48..33a0537b81 100644
--- a/lib/orber/src/orber_ifr_constantdef.erl
+++ b/lib/orber/src/orber_ifr_constantdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_contained.erl b/lib/orber/src/orber_ifr_contained.erl
index 21c72e3b72..bcb6c73908 100644
--- a/lib/orber/src/orber_ifr_contained.erl
+++ b/lib/orber/src/orber_ifr_contained.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_container.erl b/lib/orber/src/orber_ifr_container.erl
index 85ae36bfa2..fd378f4942 100644
--- a/lib/orber/src/orber_ifr_container.erl
+++ b/lib/orber/src/orber_ifr_container.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_enumdef.erl b/lib/orber/src/orber_ifr_enumdef.erl
index 035dcdd644..ffe300bf1b 100644
--- a/lib/orber/src/orber_ifr_enumdef.erl
+++ b/lib/orber/src/orber_ifr_enumdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_exceptiondef.erl b/lib/orber/src/orber_ifr_exceptiondef.erl
index 61b3051883..e78fc1da37 100644
--- a/lib/orber/src/orber_ifr_exceptiondef.erl
+++ b/lib/orber/src/orber_ifr_exceptiondef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_fixeddef.erl b/lib/orber/src/orber_ifr_fixeddef.erl
index 815eb77ea3..52cbf5846f 100644
--- a/lib/orber/src/orber_ifr_fixeddef.erl
+++ b/lib/orber/src/orber_ifr_fixeddef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_idltype.erl b/lib/orber/src/orber_ifr_idltype.erl
index 6bebaab150..febee65508 100644
--- a/lib/orber/src/orber_ifr_idltype.erl
+++ b/lib/orber/src/orber_ifr_idltype.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_interfacedef.erl b/lib/orber/src/orber_ifr_interfacedef.erl
index d8dc4f7802..5a1e552261 100644
--- a/lib/orber/src/orber_ifr_interfacedef.erl
+++ b/lib/orber/src/orber_ifr_interfacedef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_irobject.erl b/lib/orber/src/orber_ifr_irobject.erl
index 56eab57e36..a362344107 100644
--- a/lib/orber/src/orber_ifr_irobject.erl
+++ b/lib/orber/src/orber_ifr_irobject.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_moduledef.erl b/lib/orber/src/orber_ifr_moduledef.erl
index 51229661ed..3b2bd43e5e 100644
--- a/lib/orber/src/orber_ifr_moduledef.erl
+++ b/lib/orber/src/orber_ifr_moduledef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_operationdef.erl b/lib/orber/src/orber_ifr_operationdef.erl
index 1d957e17d9..9abe895fc0 100644
--- a/lib/orber/src/orber_ifr_operationdef.erl
+++ b/lib/orber/src/orber_ifr_operationdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_orb.erl b/lib/orber/src/orber_ifr_orb.erl
index f536ae887a..3969bbf37a 100644
--- a/lib/orber/src/orber_ifr_orb.erl
+++ b/lib/orber/src/orber_ifr_orb.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -88,6 +89,7 @@ create_wstring_tc(Bound) ->
create_sequence_tc(Bound, Element_type) ->
{tk_sequence,Element_type,Bound}.
+-spec create_recursive_sequence_tc(_, _) -> no_return().
create_recursive_sequence_tc(Bound, Offset) ->
orber:dbg("[~p] ~p:create_recursive_sequence_tc(~p, ~p);~n"
"Create_recursive_sequence is not implemented.~n",
diff --git a/lib/orber/src/orber_ifr_primitivedef.erl b/lib/orber/src/orber_ifr_primitivedef.erl
index a73fd09fd1..14ca32901b 100644
--- a/lib/orber/src/orber_ifr_primitivedef.erl
+++ b/lib/orber/src/orber_ifr_primitivedef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_repository.erl b/lib/orber/src/orber_ifr_repository.erl
index dde4d62562..8d52573e53 100644
--- a/lib/orber/src/orber_ifr_repository.erl
+++ b/lib/orber/src/orber_ifr_repository.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -65,6 +66,7 @@
'_get_def_kind'({ObjType, ObjID}) ?tcheck(ir_Repository, ObjType) ->
orber_ifr_irobject:'_get_def_kind'({ObjType, ObjID}).
+-spec destroy(_) -> no_return().
destroy({ObjType, ObjID}) ?tcheck(ir_Repository, ObjType) ->
orber:dbg("[~p] ~p:destroy(~p, ~p);~n"
"Destroying a repository is an error.~n",
diff --git a/lib/orber/src/orber_ifr_sequencedef.erl b/lib/orber/src/orber_ifr_sequencedef.erl
index 8a1fee6ac6..8e9df8fc7f 100644
--- a/lib/orber/src/orber_ifr_sequencedef.erl
+++ b/lib/orber/src/orber_ifr_sequencedef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_stringdef.erl b/lib/orber/src/orber_ifr_stringdef.erl
index 10f3f2116e..09c1daf491 100644
--- a/lib/orber/src/orber_ifr_stringdef.erl
+++ b/lib/orber/src/orber_ifr_stringdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_structdef.erl b/lib/orber/src/orber_ifr_structdef.erl
index c5139ee5a8..79ad63be87 100644
--- a/lib/orber/src/orber_ifr_structdef.erl
+++ b/lib/orber/src/orber_ifr_structdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_typecode.erl b/lib/orber/src/orber_ifr_typecode.erl
index 1fac75b2af..8928ecf386 100644
--- a/lib/orber/src/orber_ifr_typecode.erl
+++ b/lib/orber/src/orber_ifr_typecode.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_typedef.erl b/lib/orber/src/orber_ifr_typedef.erl
index 1b4bacba77..8b2b2d7bf1 100644
--- a/lib/orber/src/orber_ifr_typedef.erl
+++ b/lib/orber/src/orber_ifr_typedef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_uniondef.erl b/lib/orber/src/orber_ifr_uniondef.erl
index eafa03c465..fb881cf504 100644
--- a/lib/orber/src/orber_ifr_uniondef.erl
+++ b/lib/orber/src/orber_ifr_uniondef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_ifr_utils.erl b/lib/orber/src/orber_ifr_utils.erl
index 11e3d1cd3b..95a1d504bc 100644
--- a/lib/orber/src/orber_ifr_utils.erl
+++ b/lib/orber/src/orber_ifr_utils.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -289,10 +290,9 @@ makeref(Obj) ->
%%% unique tag. I do this because the tuple generated takes a lot of space
%%% when I dump the database. A binary is simply printed as #Bin, which
%%% is much less obtrusive.
-%%% The code has been moved to a macro defined in orber_ifr.hrl, so we
-%%% can use a simpler uniqification code when debugging.
-unique() -> term_to_binary({node(), now()}).
+unique() -> term_to_binary({node(), {erlang:system_time(),
+ erlang:unique_integer()}}).
%%%----------------------------------------------------------------------
%%% Check for an existing object with the Id of the object which is
diff --git a/lib/orber/src/orber_ifr_wstringdef.erl b/lib/orber/src/orber_ifr_wstringdef.erl
index da80c0c27d..c9eb095e54 100644
--- a/lib/orber/src/orber_ifr_wstringdef.erl
+++ b/lib/orber/src/orber_ifr_wstringdef.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop.erl b/lib/orber/src/orber_iiop.erl
index 0e11f7d244..8cb39c7365 100644
--- a/lib/orber/src/orber_iiop.erl
+++ b/lib/orber/src/orber_iiop.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -175,7 +176,7 @@ request({Host, Port, InitObjkey, Index, TaggedProfile, HostData},
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
end.
-
+-dialyzer({no_improper_lists, encode_request/1}).
encode_request(#giop_env{interceptors = false} = Env) ->
case catch cdr_encode:enc_request(Env) of
{'EXCEPTION', Exc} ->
diff --git a/lib/orber/src/orber_iiop.hrl b/lib/orber/src/orber_iiop.hrl
index b2e970b30d..e0cd698061 100644
--- a/lib/orber/src/orber_iiop.hrl
+++ b/lib/orber/src/orber_iiop.hrl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_inproxy.erl b/lib/orber/src/orber_iiop_inproxy.erl
index ede1e0749f..3af06eef55 100644
--- a/lib/orber/src/orber_iiop_inproxy.erl
+++ b/lib/orber/src/orber_iiop_inproxy.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_inrequest.erl b/lib/orber/src/orber_iiop_inrequest.erl
index 42d48cfe92..9d84b63398 100644
--- a/lib/orber/src/orber_iiop_inrequest.erl
+++ b/lib/orber/src/orber_iiop_inrequest.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -239,6 +240,7 @@ check_context([_|Rest], Acc, Env) ->
%%-----------------------------------------------------------------
%% Func: call_interceptors
%%-----------------------------------------------------------------
+-dialyzer({no_improper_lists, call_interceptors/7}).
call_interceptors(SocketType, #giop_env{interceptors = {native, Ref, PIs},
ctx = Ctx} = Env,
ReqHdr, Rest, Len, ByteOrder, Msg) ->
@@ -275,6 +277,7 @@ call_interceptors(SocketType, #giop_env{interceptors = {portable, _PIs}} = Env,
%%-----------------------------------------------------------------
%% Func: call_interceptors_out
%%-----------------------------------------------------------------
+-dialyzer({no_improper_lists, call_interceptors_out/7}).
call_interceptors_out(#giop_env{interceptors = {native, Ref, PIs}, ctx = Ctx} = Env,
ReqId, Result, Obj, Type, Operation, TypeCodes) ->
ReqHdr = #request_header{object_key = Obj,
diff --git a/lib/orber/src/orber_iiop_insup.erl b/lib/orber/src/orber_iiop_insup.erl
index 713e1433e3..ac62791f7a 100644
--- a/lib/orber/src/orber_iiop_insup.erl
+++ b/lib/orber/src/orber_iiop_insup.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_net.erl b/lib/orber/src/orber_iiop_net.erl
index 1bfc6b7d58..723baa1d17 100644
--- a/lib/orber/src/orber_iiop_net.erl
+++ b/lib/orber/src/orber_iiop_net.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_net_accept.erl b/lib/orber/src/orber_iiop_net_accept.erl
index 03443e3d5c..48d8f562d4 100644
--- a/lib/orber/src/orber_iiop_net_accept.erl
+++ b/lib/orber/src/orber_iiop_net_accept.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_outproxy.erl b/lib/orber/src/orber_iiop_outproxy.erl
index 3adb40d01a..9d54f57ab9 100644
--- a/lib/orber/src/orber_iiop_outproxy.erl
+++ b/lib/orber/src/orber_iiop_outproxy.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_outsup.erl b/lib/orber/src/orber_iiop_outsup.erl
index 24432b3a82..8789b6e646 100644
--- a/lib/orber/src/orber_iiop_outsup.erl
+++ b/lib/orber/src/orber_iiop_outsup.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_pm.erl b/lib/orber/src/orber_iiop_pm.erl
index fee2354f11..cf95fe7e4f 100644
--- a/lib/orber/src/orber_iiop_pm.erl
+++ b/lib/orber/src/orber_iiop_pm.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_socketsup.erl b/lib/orber/src/orber_iiop_socketsup.erl
index 4e9b6de2ad..45113232c5 100644
--- a/lib/orber/src/orber_iiop_socketsup.erl
+++ b/lib/orber/src/orber_iiop_socketsup.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_tracer.erl b/lib/orber/src/orber_iiop_tracer.erl
index 7658066eae..0b7da19449 100644
--- a/lib/orber/src/orber_iiop_tracer.erl
+++ b/lib/orber/src/orber_iiop_tracer.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_tracer_silent.erl b/lib/orber/src/orber_iiop_tracer_silent.erl
index 663d5d5a8e..fa66b4d4cd 100644
--- a/lib/orber/src/orber_iiop_tracer_silent.erl
+++ b/lib/orber/src/orber_iiop_tracer_silent.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_iiop_tracer_stealth.erl b/lib/orber/src/orber_iiop_tracer_stealth.erl
index 494c93e694..f4185fa6fd 100644
--- a/lib/orber/src/orber_iiop_tracer_stealth.erl
+++ b/lib/orber/src/orber_iiop_tracer_stealth.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_initial_references.erl b/lib/orber/src/orber_initial_references.erl
index 21a807c4e1..e72de4dd23 100644
--- a/lib/orber/src/orber_initial_references.erl
+++ b/lib/orber/src/orber_initial_references.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_interceptors.erl b/lib/orber/src/orber_interceptors.erl
index 62870b35b5..c9b351d9fa 100644
--- a/lib/orber/src/orber_interceptors.erl
+++ b/lib/orber/src/orber_interceptors.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_objectkeys.erl b/lib/orber/src/orber_objectkeys.erl
index b0e759187b..1233e4e721 100644
--- a/lib/orber/src/orber_objectkeys.erl
+++ b/lib/orber/src/orber_objectkeys.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -374,11 +375,11 @@ handle_call({register, Objkey, Pid, Type}, _From, State) ->
%% No key exists. Ok to register.
mnesia:write(#orber_objkeys{object_key=Objkey, pid=Pid,
persistent=Type,
- timestamp=now()});
+ timestamp=erlang:monotonic_time(seconds)});
[X] when X#orber_objkeys.persistent==true,
X#orber_objkeys.pid == dead ->
%% A persistent object is being restarted. Update Pid & time.
- mnesia:write(X#orber_objkeys{pid=Pid, timestamp=now()});
+ mnesia:write(X#orber_objkeys{pid=Pid, timestamp=erlang:monotonic_time(seconds)});
[X] when is_pid(X#orber_objkeys.pid) ->
%% Object exists, i.e., trying to create an object with
%% the same name.
@@ -477,7 +478,7 @@ handle_info({'EXIT', Pid, Reason}, State) when is_pid(Pid) ->
Reason /= normal andalso
Reason /= shutdown ->
mnesia:write(X#orber_objkeys{pid=dead,
- timestamp=now()});
+ timestamp=erlang:monotonic_time(seconds)});
[X] when X#orber_objkeys.persistent==true ->
mnesia:delete({orber_objkeys, X#orber_objkeys.object_key});
_->
@@ -503,8 +504,8 @@ code_change(_OldVsn, State, _Extra) ->
%% Internal Functions
%%-----------------------------------------------------------------
-timetest(S, {MeSec, Sec, USec}) ->
- {MeSec, Sec+S, USec} < now().
+timetest(S, TimeStamp) ->
+ TimeStamp+S < erlang:monotonic_time(seconds).
get_key_from_pid(Pid) ->
case mnesia:dirty_match_object({orber_objkeys, '_', Pid,'_','_'}) of
diff --git a/lib/orber/src/orber_pi.erl b/lib/orber/src/orber_pi.erl
index 887c3924e1..19bb7af6c0 100644
--- a/lib/orber/src/orber_pi.erl
+++ b/lib/orber/src/orber_pi.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1029,6 +1030,7 @@ receive_exception(CRI, Mod) ->
%% SlotId - ulong()
%% Returns : {'EXCEPTION', #'PortableInterceptor_InvalidSlot'{}}
%%------------------------------------------------------------
+-spec get_slot(_, _) -> no_return().
get_slot(_XRI, _SlotId) ->
corba:raise(#'PortableInterceptor_InvalidSlot'{}).
@@ -1184,6 +1186,7 @@ get_server_policy(#'ServerRequestInfo'{contexts = Ctxs}, _PolicyType) ->
%% Data - #any{}
%% Returns : {'EXCEPTION', #'PortableInterceptor_InvalidSlot'{}}
%%------------------------------------------------------------
+-spec set_slot(_, _, _) -> no_return().
set_slot(_SRI, _SlotId, _Data) ->
corba:raise(#'PortableInterceptor_InvalidSlot'{}).
diff --git a/lib/orber/src/orber_request_number.erl b/lib/orber/src/orber_request_number.erl
index 77ca9e083a..5869d32b4d 100644
--- a/lib/orber/src/orber_request_number.erl
+++ b/lib/orber/src/orber_request_number.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl
index 4507d90cce..9b39dad928 100644
--- a/lib/orber/src/orber_socket.erl
+++ b/lib/orber/src/orber_socket.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
%%
@@ -167,8 +168,6 @@ multi_connect([CurrentPort|Rest], Retries, ssl, Host, Port, Options, Timeout) ->
get_port_sequence(Min, Max) ->
case orber_env:iiop_out_ports_random() of
true ->
- {A1,A2,A3} = now(),
- random:seed(A1, A2, A3),
Seq = lists:seq(Min, Max),
random_sequence((Max - Min) + 1, Seq, []);
_ ->
@@ -178,7 +177,7 @@ get_port_sequence(Min, Max) ->
random_sequence(0, _, Acc) ->
Acc;
random_sequence(Length, Seq, Acc) ->
- Nth = random:uniform(Length),
+ Nth = rand:uniform(Length),
Value = lists:nth(Nth, Seq),
NewSeq = lists:delete(Value, Seq),
random_sequence(Length-1, NewSeq, [Value|Acc]).
diff --git a/lib/orber/src/orber_tb.erl b/lib/orber/src/orber_tb.erl
index 26a36df0e9..16e8fdd9a0 100644
--- a/lib/orber/src/orber_tb.erl
+++ b/lib/orber/src/orber_tb.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_tc.erl b/lib/orber/src/orber_tc.erl
index 7c2172b565..26bdb12470 100644
--- a/lib/orber/src/orber_tc.erl
+++ b/lib/orber/src/orber_tc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_typedefs.erl b/lib/orber/src/orber_typedefs.erl
index 239546961f..bf21cf599d 100644
--- a/lib/orber/src/orber_typedefs.erl
+++ b/lib/orber/src/orber_typedefs.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_web.erl b/lib/orber/src/orber_web.erl
index 04bf65fd40..20835d0a12 100644
--- a/lib/orber/src/orber_web.erl
+++ b/lib/orber/src/orber_web.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/src/orber_web_server.erl b/lib/orber/src/orber_web_server.erl
index 9d2a063a69..3506894df2 100644
--- a/lib/orber/src/orber_web_server.erl
+++ b/lib/orber/src/orber_web_server.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -46,7 +47,7 @@
-define(DEBUG_LEVEL, 5).
--record(state, {ts}).
+-record(state, {}).
-include("ifr_objects.hrl").
%%----------------------------------------------------------------------
@@ -133,9 +134,7 @@ delete_obj(Env, Input) ->
%% Description:
%%----------------------------------------------------------------------
init(_Arg)->
- {M, S, U} = now(),
- TS = M*1000000000000 + S*1000000 + U,
- {ok, #state{ts = TS}}.
+ {ok, #state{}}.
terminate(_,_State)->
ok.
diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile
index 50be14c24a..b9be48c790 100644
--- a/lib/orber/test/Makefile
+++ b/lib/orber/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/orber/test/cdrcoding_10_SUITE.erl b/lib/orber/test/cdrcoding_10_SUITE.erl
index 54ad92cf7e..1fec91dca3 100644
--- a/lib/orber/test/cdrcoding_10_SUITE.erl
+++ b/lib/orber/test/cdrcoding_10_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -622,4 +623,6 @@ corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
term_to_binary(undefined), term_to_binary(undefined)}.
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
diff --git a/lib/orber/test/cdrcoding_11_SUITE.erl b/lib/orber/test/cdrcoding_11_SUITE.erl
index 29b3e33069..324b9b2b17 100644
--- a/lib/orber/test/cdrcoding_11_SUITE.erl
+++ b/lib/orber/test/cdrcoding_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -621,4 +622,6 @@ corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
term_to_binary(undefined), term_to_binary(undefined)}.
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
diff --git a/lib/orber/test/cdrcoding_12_SUITE.erl b/lib/orber/test/cdrcoding_12_SUITE.erl
index dd9b98434d..f0a8fe4d7f 100644
--- a/lib/orber/test/cdrcoding_12_SUITE.erl
+++ b/lib/orber/test/cdrcoding_12_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -609,4 +610,6 @@ corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
term_to_binary(undefined), term_to_binary(undefined)}.
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
diff --git a/lib/orber/test/cdrlib_SUITE.erl b/lib/orber/test/cdrlib_SUITE.erl
index 012d76b786..dd1f975d9e 100644
--- a/lib/orber/test/cdrlib_SUITE.erl
+++ b/lib/orber/test/cdrlib_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/corba_SUITE.erl b/lib/orber/test/corba_SUITE.erl
index 17a9f5fcdf..914856f370 100644
--- a/lib/orber/test/corba_SUITE.erl
+++ b/lib/orber/test/corba_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/test/csiv2_SUITE.erl b/lib/orber/test/csiv2_SUITE.erl
index da8c0d3738..7f45f16ef7 100644
--- a/lib/orber/test/csiv2_SUITE.erl
+++ b/lib/orber/test/csiv2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/test/data_types_SUITE.erl b/lib/orber/test/data_types_SUITE.erl
index 9d436aaf1b..d0e0eacad1 100644
--- a/lib/orber/test/data_types_SUITE.erl
+++ b/lib/orber/test/data_types_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/generated_SUITE.erl b/lib/orber/test/generated_SUITE.erl
index a6bcff88dc..cc14b4ebc0 100644
--- a/lib/orber/test/generated_SUITE.erl
+++ b/lib/orber/test/generated_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/iiop_module_do_test_impl.erl b/lib/orber/test/iiop_module_do_test_impl.erl
index 54fcd8239a..c6c1d4d48a 100644
--- a/lib/orber/test/iiop_module_do_test_impl.erl
+++ b/lib/orber/test/iiop_module_do_test_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/iiop_module_test_impl.erl b/lib/orber/test/iiop_module_test_impl.erl
index 2096c14a23..cebdf160ab 100644
--- a/lib/orber/test/iiop_module_test_impl.erl
+++ b/lib/orber/test/iiop_module_test_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/iiop_test.idl b/lib/orber/test/iiop_test.idl
index 339678106e..98f06e2c9d 100644
--- a/lib/orber/test/iiop_test.idl
+++ b/lib/orber/test/iiop_test.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// 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%
//
diff --git a/lib/orber/test/iiop_test_impl.erl b/lib/orber/test/iiop_test_impl.erl
index 234f7c5f73..3fd512b574 100644
--- a/lib/orber/test/iiop_test_impl.erl
+++ b/lib/orber/test/iiop_test_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/interceptors_SUITE.erl b/lib/orber/test/interceptors_SUITE.erl
index ade0183ddd..57d5a5f831 100644
--- a/lib/orber/test/interceptors_SUITE.erl
+++ b/lib/orber/test/interceptors_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/iop_ior_10_SUITE.erl b/lib/orber/test/iop_ior_10_SUITE.erl
index 58dd1b5dba..5705a95710 100644
--- a/lib/orber/test/iop_ior_10_SUITE.erl
+++ b/lib/orber/test/iop_ior_10_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -182,4 +183,6 @@ corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
diff --git a/lib/orber/test/iop_ior_11_SUITE.erl b/lib/orber/test/iop_ior_11_SUITE.erl
index 24b2f66357..b32da44c68 100644
--- a/lib/orber/test/iop_ior_11_SUITE.erl
+++ b/lib/orber/test/iop_ior_11_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -201,4 +202,6 @@ corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
{Id, 'registered', RegName, term_to_binary(undefined), 0, 0}.
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
diff --git a/lib/orber/test/iop_ior_12_SUITE.erl b/lib/orber/test/iop_ior_12_SUITE.erl
index 4c6e9ddb91..a12f341f04 100644
--- a/lib/orber/test/iop_ior_12_SUITE.erl
+++ b/lib/orber/test/iop_ior_12_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -202,4 +203,6 @@ corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
{Id, 'registered', RegName, term_to_binary(undefined), 0, 0}.
make_objkey() ->
- term_to_binary({now(), node()}).
+ term_to_binary({{erlang:system_time(),
+ erlang:unique_integer()},
+ node()}).
diff --git a/lib/orber/test/ip_v4v6_interop_SUITE.erl b/lib/orber/test/ip_v4v6_interop_SUITE.erl
index 5eee5a29c2..995a11ae1e 100644
--- a/lib/orber/test/ip_v4v6_interop_SUITE.erl
+++ b/lib/orber/test/ip_v4v6_interop_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/test/lname_SUITE.erl b/lib/orber/test/lname_SUITE.erl
index 6a3bc1fae2..2200ff6ed1 100644
--- a/lib/orber/test/lname_SUITE.erl
+++ b/lib/orber/test/lname_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl
index 40d8846e0f..6b523229cc 100644
--- a/lib/orber/test/multi_ORB_SUITE.erl
+++ b/lib/orber/test/multi_ORB_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -922,9 +923,9 @@ max_requests(Node, Host, Port) ->
spawn(orber_test_server, pseudo_call_delay, [Obj, 15000]),
%% Wait for a second to be sure that the previous request has been sent
timer:sleep(1000),
- {MegaSecsB, Before, _} = now(),
+ {MegaSecsB, Before, _} = erlang:timestamp(),
pseudo_calls(5, Obj),
- {MegaSecsA, After, _} = now(),
+ {MegaSecsA, After, _} = erlang:timestamp(),
%% Normally we we can perform hundreds of pseudo-calls per second. Hence,
%% if we add 8 seconds to 'Before' it should still be less since we only
%% allow one request at a time to the target ORB.
diff --git a/lib/orber/test/naming_context_SUITE.erl b/lib/orber/test/naming_context_SUITE.erl
index 789aace882..f99820fa24 100644
--- a/lib/orber/test/naming_context_SUITE.erl
+++ b/lib/orber/test/naming_context_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/orber_SUITE.erl b/lib/orber/test/orber_SUITE.erl
index 26dc656b63..914705adb9 100644
--- a/lib/orber/test/orber_SUITE.erl
+++ b/lib/orber/test/orber_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/orber_acl_SUITE.erl b/lib/orber/test/orber_acl_SUITE.erl
index ab2c2c872c..8d1f9ebb6d 100644
--- a/lib/orber/test/orber_acl_SUITE.erl
+++ b/lib/orber/test/orber_acl_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -272,21 +273,21 @@ ipv6_bm(_) ->
bm2(Filters, Family, Ip) ->
{ok, IPTuple} = inet:getaddr(Ip, Family),
orber_acl:init_acl(Filters, Family),
- TimeBefore1 = erlang:now(),
+ TimeBefore1 = erlang:timestamp(),
bm_loop(IPTuple, ?NO_OF_TIMES),
- TimeAfter1 = erlang:now(),
+ TimeAfter1 = erlang:timestamp(),
orber_acl:clear_acl(),
Time1 = computeTime(TimeBefore1, TimeAfter1),
orber_acl:init_acl(Filters, Family),
- TimeBefore2 = erlang:now(),
+ TimeBefore2 = erlang:timestamp(),
bm_loop2(Ip, ?NO_OF_TIMES, Family),
- TimeAfter2 = erlang:now(),
+ TimeAfter2 = erlang:timestamp(),
orber_acl:clear_acl(),
Time2 = computeTime(TimeBefore2, TimeAfter2),
orber_acl:init_acl(Filters, Family),
- TimeBefore3 = erlang:now(),
+ TimeBefore3 = erlang:timestamp(),
bm_loop2(IPTuple, ?NO_OF_TIMES, Family),
- TimeAfter3 = erlang:now(),
+ TimeAfter3 = erlang:timestamp(),
orber_acl:clear_acl(),
Time3 = computeTime(TimeBefore3, TimeAfter3),
{ok, round(?NO_OF_TIMES/Time1), round(?NO_OF_TIMES/Time2), round(?NO_OF_TIMES/Time3)}.
diff --git a/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
index 0175409a5b..220029ec72 100644
--- a/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
index 591b5f5f67..270b166fe9 100644
--- a/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
index 2853949a49..b0e28118f7 100644
--- a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
index 83d22cc487..96884f3339 100644
--- a/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/orber_nat_SUITE.erl b/lib/orber/test/orber_nat_SUITE.erl
index a21bd4d499..1294f96681 100644
--- a/lib/orber/test/orber_nat_SUITE.erl
+++ b/lib/orber/test/orber_nat_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/test/orber_test.idl b/lib/orber/test/orber_test.idl
index 3d943f2d18..3fc1e64f48 100644
--- a/lib/orber/test/orber_test.idl
+++ b/lib/orber/test/orber_test.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1997-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// 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%
//
diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl
index 46ed26f210..51025927ee 100644
--- a/lib/orber/test/orber_test_lib.erl
+++ b/lib/orber/test/orber_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -220,7 +221,7 @@ js_node(InitOptions) when is_list(InitOptions) ->
js_node(InitOptions, []).
js_node(InitOptions, StartOptions) when is_list(InitOptions) ->
- {A,B,C} = erlang:now(),
+ {A,B,C} = erlang:timestamp(),
[_, Host] = string:tokens(atom_to_list(node()), [$@]),
_NewInitOptions = check_options(InitOptions),
js_node_helper(Host, 0, lists:concat([A,'_',B,'_',C]),
diff --git a/lib/orber/test/orber_test_server.cfg b/lib/orber/test/orber_test_server.cfg
index 84c671f795..d74dcb15ce 100644
--- a/lib/orber/test/orber_test_server.cfg
+++ b/lib/orber/test/orber_test_server.cfg
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/orber/test/orber_test_server.idl b/lib/orber/test/orber_test_server.idl
index 438c10e19b..80a25763cd 100644
--- a/lib/orber/test/orber_test_server.idl
+++ b/lib/orber/test/orber_test_server.idl
@@ -3,16 +3,17 @@
//
// Copyright Ericsson AB 1999-2010. All Rights Reserved.
//
-// The contents of this file are subject to the Erlang Public License,
-// Version 1.1, (the "License"); you may not use this file except in
-// compliance with the License. You should have received a copy of the
-// Erlang Public License along with this software. If not, it can be
-// retrieved online at http://www.erlang.org/.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-// the License for the specific language governing rights and limitations
-// under the License.
+// 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%
//
diff --git a/lib/orber/test/orber_test_server_impl.erl b/lib/orber/test/orber_test_server_impl.erl
index 10a9caf242..b35e959c9d 100644
--- a/lib/orber/test/orber_test_server_impl.erl
+++ b/lib/orber/test/orber_test_server_impl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -243,22 +244,22 @@ relay_cast(_Self, State, Target) ->
%% Testing pseudo calls.
pseudo_call(_Self, State) ->
- io:format("orber_test_server:pseudo_call( ~p )~n", [now()]),
+ io:format("orber_test_server:pseudo_call( ~p )~n", [erlang:timestamp()]),
{reply, ok, State}.
pseudo_cast(_Self, State) ->
- io:format("orber_test_server:pseudo_cast( ~p )~n", [now()]),
+ io:format("orber_test_server:pseudo_cast( ~p )~n", [erlang:timestamp()]),
{noreply, State}.
pseudo_call_delay(_Self, State, Time) ->
- io:format("orber_test_server:pseudo_call_delay( ~p )~n", [now()]),
+ io:format("orber_test_server:pseudo_call_delay( ~p )~n", [erlang:timestamp()]),
timer:sleep(Time),
- io:format("orber_test_server:pseudo_call_delay( ~p )~n", [now()]),
+ io:format("orber_test_server:pseudo_call_delay( ~p )~n", [erlang:timestamp()]),
{reply, {ok, Time}, State}.
pseudo_cast_delay(_Self, State, Time) ->
- io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [now()]),
+ io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [erlang:timestamp()]),
timer:sleep(Time),
- io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [now()]),
+ io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [erlang:timestamp()]),
{noreply, State}.
pseudo_call_raise_exc(_Self, State, 1) ->
diff --git a/lib/orber/test/orber_test_timeout_server_impl.erl b/lib/orber/test/orber_test_timeout_server_impl.erl
index 67ea897fdd..9ae61378e9 100644
--- a/lib/orber/test/orber_test_timeout_server_impl.erl
+++ b/lib/orber/test/orber_test_timeout_server_impl.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/orber_web_SUITE.erl b/lib/orber/test/orber_web_SUITE.erl
index a3b4d8547d..a88e0373bd 100644
--- a/lib/orber/test/orber_web_SUITE.erl
+++ b/lib/orber/test/orber_web_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/test/tc_SUITE.erl b/lib/orber/test/tc_SUITE.erl
index 52b7f8852f..a1a5c74ae3 100644
--- a/lib/orber/test/tc_SUITE.erl
+++ b/lib/orber/test/tc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 28fe9323fb..4947315ad0 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1 +1 @@
-ORBER_VSN = 3.7.1
+ORBER_VSN = 3.8.1
diff --git a/lib/os_mon/Makefile b/lib/os_mon/Makefile
index 7eeec1577c..8399ee5f90 100644
--- a/lib/os_mon/Makefile
+++ b/lib/os_mon/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/os_mon/c_src/Makefile.in b/lib/os_mon/c_src/Makefile.in
index f84ccf7c87..e9fc5f4139 100644
--- a/lib/os_mon/c_src/Makefile.in
+++ b/lib/os_mon/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c
index e9fd75a32c..e097141125 100644
--- a/lib/os_mon/c_src/cpu_sup.c
+++ b/lib/os_mon/c_src/cpu_sup.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -31,15 +32,28 @@
#include <unistd.h>
#include <string.h>
+#if (defined(__APPLE__) && defined(__MACH__)) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <limits.h>
+#include <fcntl.h>
+#endif
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <kvm.h>
+#include <sys/user.h>
+#endif
+
#if defined(__sun__)
#include <kstat.h>
#endif
-#include <sys/sysinfo.h>
#include <errno.h>
+#if defined(__sun__) || defined(__linux__)
+#include <sys/sysinfo.h>
+#endif
+
#if defined(__linux__)
-#include <string.h> /* strlen */
#define PROCSTAT "/proc/stat"
#define BUFFERSIZE (256)
@@ -59,6 +73,13 @@ typedef struct {
#endif
+#if defined(__FreeBSD__)
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#define CU_BSD_VALUES (6)
+#endif
+
+
#define FD_IN (0)
#define FD_OUT (1)
#define FD_ERR (2)
@@ -124,10 +145,15 @@ static void util_measure(unsigned int **result_vec, int *result_sz);
#if defined(__sun__)
static unsigned int misc_measure(char* name);
#endif
-static void send(unsigned int data);
+static void sendi(unsigned int data);
static void sendv(unsigned int data[], int ints);
static void error(char* err_msg);
+#if (defined(__APPLE__) && defined(__MACH__)) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+static void bsd_count_procs(void);
+static void bsd_loadavg(int);
+#endif
+
#if defined(__sun__)
static kstat_ctl_t *kstat_ctl;
#endif
@@ -138,12 +164,16 @@ static int processors_online() {
}
#endif
+#if defined(__FreeBSD__)
+void getsysctl(const char *, void *, size_t);
+#endif
+
int main(int argc, char** argv) {
char cmd;
int rc;
int sz;
unsigned int *rv;
-#if defined(__linux__)
+#if defined(__linux__) || defined(__FreeBSD__)
unsigned int no_of_cpus = 0;
#endif
@@ -156,7 +186,14 @@ int main(int argc, char** argv) {
#if defined(__linux__)
no_of_cpus = processors_online();
if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_VALUES))) == NULL) {
- error("cpu_cup: malloc error");
+ error("cpu_sup: malloc error");
+ }
+#endif
+
+#if defined(__FreeBSD__)
+ getsysctl("hw.ncpu", &no_of_cpus, sizeof(int));
+ if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_BSD_VALUES))) == NULL) {
+ error("cpu_sup: malloc error");
}
#endif
@@ -173,20 +210,104 @@ int main(int argc, char** argv) {
error("Erlang has closed");
switch(cmd) {
- case PING: send(4711); break;
+ case PING: sendi(4711); break;
#if defined(__sun__)
- case NPROCS: send(misc_measure("nproc")); break;
- case AVG1: send(misc_measure("avenrun_1min")); break;
- case AVG5: send(misc_measure("avenrun_5min")); break;
- case AVG15: send(misc_measure("avenrun_15min")); break;
+ case NPROCS: sendi(misc_measure("nproc")); break;
+ case AVG1: sendi(misc_measure("avenrun_1min")); break;
+ case AVG5: sendi(misc_measure("avenrun_5min")); break;
+ case AVG15: sendi(misc_measure("avenrun_15min")); break;
+#elif defined(__OpenBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__DragonFly__)
+ case NPROCS: bsd_count_procs(); break;
+ case AVG1: bsd_loadavg(0); break;
+ case AVG5: bsd_loadavg(1); break;
+ case AVG15: bsd_loadavg(2); break;
#endif
+#if defined(__sun__) || defined(__linux__) || defined(__FreeBSD__)
case UTIL: util_measure(&rv,&sz); sendv(rv, sz); break;
+#endif
case QUIT: free((void*)rv); return 0;
default: error("Bad command"); break;
}
}
- return 0; /* supress warnings */
+ return 0; /* suppress warnings */
}
+
+/* ---------------------------- *
+ * BSD stat functions *
+ * ---------------------------- */
+#if defined(__OpenBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__DragonFly__)
+
+static void bsd_loadavg(int idx) {
+ double avgs[3];
+ if (getloadavg(avgs, 3) < 0) {
+ error(strerror(errno));
+ return;
+ }
+ sendi((unsigned int)(avgs[idx] * 256));
+}
+
+#endif
+
+#if defined(__OpenBSD__)
+
+static void bsd_count_procs(void) {
+ int err, nproc;
+ size_t len = sizeof(nproc);
+ int mib[] = { CTL_KERN, KERN_NPROCS };
+
+ err = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &nproc, &len, NULL, 0);
+ if (err) {
+ error(strerror(errno));
+ return;
+ }
+
+ sendi((unsigned int)nproc);
+}
+
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
+
+static void bsd_count_procs(void) {
+ kvm_t *kd;
+ struct kinfo_proc *kp;
+ char err[_POSIX2_LINE_MAX];
+ int cnt = 0;
+
+ if ((kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, err)) == NULL) {
+ error(err);
+ return;
+ }
+
+#if defined(KERN_PROC_PROC)
+ if ((kp = kvm_getprocs(kd, KERN_PROC_PROC, 0, &cnt)) == NULL) {
+#else
+ if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &cnt)) == NULL) {
+#endif
+ error(strerror(errno));
+ return;
+ }
+
+ (void)kvm_close(kd);
+ sendi((unsigned int)cnt);
+}
+
+#elif (defined(__APPLE__) && defined(__MACH__))
+
+static void bsd_count_procs(void) {
+ int err;
+ size_t len = 0;
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+
+ err = sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0);
+ if (err) {
+ error(strerror(errno));
+ return;
+ }
+
+ sendi((unsigned int)(len / sizeof(struct kinfo_proc)));
+}
+
+#endif
+
/* ---------------------------- *
* Linux stat functions *
* ---------------------------- */
@@ -417,10 +538,75 @@ static void util_measure(unsigned int **result_vec, int *result_sz) {
#endif
/* ---------------------------- *
+ * FreeBSD stat functions *
+ * ---------------------------- */
+
+#if defined(__FreeBSD__)
+
+#define EXIT_WITH(msg) (rich_error(msg, __FILE__, __LINE__))
+#define RICH_BUFLEN (213) /* left in error(char*) */
+
+void rich_error(const char *reason, const char *file, const int line) {
+ char buf[RICH_BUFLEN];
+ snprintf(buf, RICH_BUFLEN, "%s (%s:%i)", reason, file, line);
+ error(buf);
+}
+#undef RICH_BUFLEN
+
+static void util_measure(unsigned int **result_vec, int *result_sz) {
+ int no_of_cpus;
+ size_t size_cpu_times;
+ unsigned long *cpu_times;
+ unsigned int *rv = NULL;
+ int i;
+
+ getsysctl("hw.ncpu", &no_of_cpus, sizeof(int));
+ /* Header constant CPUSTATES = #long values per cpu. */
+ size_cpu_times = sizeof(long) * CPUSTATES * no_of_cpus;
+ cpu_times = malloc(size_cpu_times);
+ if (!cpu_times) {
+ EXIT_WITH("badalloc");
+ }
+ getsysctl("kern.cp_times", cpu_times, size_cpu_times);
+
+ rv = *result_vec;
+ rv[0] = no_of_cpus;
+ rv[1] = CU_BSD_VALUES;
+ ++rv; /* first value is number of cpus */
+ ++rv; /* second value is number of entries */
+
+ for (i = 0; i < no_of_cpus; ++i) {
+ int offset = i * CPUSTATES;
+ rv[ 0] = CU_CPU_ID; rv[ 1] = i;
+ rv[ 2] = CU_USER; rv[ 3] = cpu_times[CP_USER + offset];
+ rv[ 4] = CU_NICE_USER; rv[ 5] = cpu_times[CP_NICE + offset];
+ rv[ 6] = CU_KERNEL; rv[ 7] = cpu_times[CP_SYS + offset];
+ rv[ 8] = CU_IDLE; rv[ 9] = cpu_times[CP_IDLE + offset];
+ rv[10] = CU_HARD_IRQ; rv[11] = cpu_times[CP_INTR + offset];
+ rv += CU_BSD_VALUES*2;
+ }
+
+ *result_sz = 2 + 2*CU_BSD_VALUES * no_of_cpus;
+}
+
+void getsysctl(const char *name, void *ptr, size_t len)
+{
+ size_t gotlen = len;
+ if (sysctlbyname(name, ptr, &gotlen, NULL, 0) != 0) {
+ EXIT_WITH("sysctlbyname failed");
+ }
+ if (gotlen != len) {
+ EXIT_WITH("sysctlbyname: unexpected length");
+ }
+}
+#endif
+
+
+/* ---------------------------- *
* Generic functions *
* ---------------------------- */
-static void send(unsigned int data) { sendv(&data, 1); }
+static void sendi(unsigned int data) { sendv(&data, 1); }
static void sendv(unsigned int data[], int ints) {
static unsigned char *buf = NULL;
@@ -474,8 +660,7 @@ static void error(char* err_msg) {
buffer[i++] = '\n';
/* try to use one write only */
- if(write(FD_ERR, buffer, i));
+ if(write(FD_ERR, buffer, i))
+ ;
exit(-1);
}
-
-
diff --git a/lib/os_mon/c_src/ferrule.c b/lib/os_mon/c_src/ferrule.c
index c55f594f34..b5b62ca155 100644
--- a/lib/os_mon/c_src/ferrule.c
+++ b/lib/os_mon/c_src/ferrule.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/memsup.c b/lib/os_mon/c_src/memsup.c
index 5dcab07dd8..08a4cc48b6 100644
--- a/lib/os_mon/c_src/memsup.c
+++ b/lib/os_mon/c_src/memsup.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/memsup.h b/lib/os_mon/c_src/memsup.h
index 926df0a847..d86c1f1ff0 100644
--- a/lib/os_mon/c_src/memsup.h
+++ b/lib/os_mon/c_src/memsup.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/mod_syslog.c b/lib/os_mon/c_src/mod_syslog.c
index b1bbf80b2a..190e451951 100644
--- a/lib/os_mon/c_src/mod_syslog.c
+++ b/lib/os_mon/c_src/mod_syslog.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_format.c b/lib/os_mon/c_src/nteventlog/elog_format.c
index c9fb6b7e1a..91fcb542a4 100644
--- a/lib/os_mon/c_src/nteventlog/elog_format.c
+++ b/lib/os_mon/c_src/nteventlog/elog_format.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_format.h b/lib/os_mon/c_src/nteventlog/elog_format.h
index 3fb19367ab..18e99267bb 100644
--- a/lib/os_mon/c_src/nteventlog/elog_format.h
+++ b/lib/os_mon/c_src/nteventlog/elog_format.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_global.h b/lib/os_mon/c_src/nteventlog/elog_global.h
index f992b7184f..e9c4d56f48 100644
--- a/lib/os_mon/c_src/nteventlog/elog_global.h
+++ b/lib/os_mon/c_src/nteventlog/elog_global.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_main.c b/lib/os_mon/c_src/nteventlog/elog_main.c
index f79f32c8ef..3446369c00 100644
--- a/lib/os_mon/c_src/nteventlog/elog_main.c
+++ b/lib/os_mon/c_src/nteventlog/elog_main.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c b/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c
index c333c455a3..d15d137c9a 100644
--- a/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c
+++ b/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.h b/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.h
index a9a91b685f..ada990311a 100644
--- a/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.h
+++ b/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_registry.c b/lib/os_mon/c_src/nteventlog/elog_registry.c
index 478db1e56b..ff998d2bb2 100644
--- a/lib/os_mon/c_src/nteventlog/elog_registry.c
+++ b/lib/os_mon/c_src/nteventlog/elog_registry.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_registry.h b/lib/os_mon/c_src/nteventlog/elog_registry.h
index 32876ae8bf..e33afadf79 100644
--- a/lib/os_mon/c_src/nteventlog/elog_registry.h
+++ b/lib/os_mon/c_src/nteventlog/elog_registry.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_util.c b/lib/os_mon/c_src/nteventlog/elog_util.c
index ac14f2f3e4..d9f8acf2e4 100644
--- a/lib/os_mon/c_src/nteventlog/elog_util.c
+++ b/lib/os_mon/c_src/nteventlog/elog_util.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/nteventlog/elog_util.h b/lib/os_mon/c_src/nteventlog/elog_util.h
index 66f1a2519e..ea866180ef 100644
--- a/lib/os_mon/c_src/nteventlog/elog_util.h
+++ b/lib/os_mon/c_src/nteventlog/elog_util.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/c_src/win32sysinfo.c b/lib/os_mon/c_src/win32sysinfo.c
index f02ae637b2..d11f937e92 100644
--- a/lib/os_mon/c_src/win32sysinfo.c
+++ b/lib/os_mon/c_src/win32sysinfo.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/os_mon/doc/src/Makefile b/lib/os_mon/doc/src/Makefile
index 08fd23ec92..0c5acd9740 100644
--- a/lib/os_mon/doc/src/Makefile
+++ b/lib/os_mon/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/os_mon/doc/src/book.xml b/lib/os_mon/doc/src/book.xml
index 1b927fc9ac..7b851a12b4 100644
--- a/lib/os_mon/doc/src/book.xml
+++ b/lib/os_mon/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/cpu_sup.xml b/lib/os_mon/doc/src/cpu_sup.xml
index 59da876208..51e1a4c9d6 100644
--- a/lib/os_mon/doc/src/cpu_sup.xml
+++ b/lib/os_mon/doc/src/cpu_sup.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -34,7 +35,7 @@
and CPU utilization. It is part of the OS_Mon application, see
<seealso marker="os_mon_app">os_mon(6)</seealso>. Available for Unix,
although CPU utilization values (<c>util/0,1</c>) are only
- available for Solaris and Linux.</p>
+ available for Solaris, Linux and FreeBSD.</p>
<p>The load values are proportional to how long time a runnable
Unix process has to spend in the run queue before it is scheduled.
Accordingly, higher values mean more system load. The returned
@@ -62,7 +63,7 @@
measure.</p>
<p>A server which receives just enough requests to never become
idle will score a CPU utilization of 100%. If the server receives
- 50% more requests, it will still scores 100%. When the system load
+ 50% more requests, it will still score 100%. When the system load
is calculated with the percentage formula shown previously,
the load will increase from 80% to 87%.</p>
<p>The <c>avg1/0</c>, <c>avg5/0</c>, and <c>avg15/0</c> functions
diff --git a/lib/os_mon/doc/src/disksup.xml b/lib/os_mon/doc/src/disksup.xml
index 0e76178edb..88756d46c4 100644
--- a/lib/os_mon/doc/src/disksup.xml
+++ b/lib/os_mon/doc/src/disksup.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/memsup.xml b/lib/os_mon/doc/src/memsup.xml
index 62f77ea12f..5fc5e578c6 100644
--- a/lib/os_mon/doc/src/memsup.xml
+++ b/lib/os_mon/doc/src/memsup.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml
index d3acc1effc..8bb4ab33a1 100644
--- a/lib/os_mon/doc/src/notes.xml
+++ b/lib/os_mon/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,31 @@
</header>
<p>This document describes the changes made to the OS_Mon application.</p>
+<section><title>Os_Mon 2.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ cpu_sup should use native sysctl/libkvm calls on BSD</p>
+ <p>
+ This avoids forking off with os:cmd every time we just
+ want to collect the load averages. riak does this every
+ second, which results in a lot of unnecessary load.</p>
+ <p>
+ Own Id: OTP-12730</p>
+ </item>
+ <item>
+ <p>
+ Implement native cpu_sup:util/0,1 for FreeBSD</p>
+ <p>
+ Own Id: OTP-12796</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Os_Mon 2.3.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/os_mon/doc/src/nteventlog.xml b/lib/os_mon/doc/src/nteventlog.xml
index 8b27092f85..fd7950bca7 100644
--- a/lib/os_mon/doc/src/nteventlog.xml
+++ b/lib/os_mon/doc/src/nteventlog.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/os_mon_app.xml b/lib/os_mon/doc/src/os_mon_app.xml
index f6bb2300bb..d70124a995 100644
--- a/lib/os_mon/doc/src/os_mon_app.xml
+++ b/lib/os_mon/doc/src/os_mon_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/os_mon_mib.xml b/lib/os_mon/doc/src/os_mon_mib.xml
index fa183086ff..8e8721fd25 100644
--- a/lib/os_mon/doc/src/os_mon_mib.xml
+++ b/lib/os_mon/doc/src/os_mon_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/os_sup.xml b/lib/os_mon/doc/src/os_sup.xml
index fb162c15a7..0350d4f8b4 100644
--- a/lib/os_mon/doc/src/os_sup.xml
+++ b/lib/os_mon/doc/src/os_sup.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/part_notes.xml b/lib/os_mon/doc/src/part_notes.xml
index 0969fb9136..6cbfbb4961 100644
--- a/lib/os_mon/doc/src/part_notes.xml
+++ b/lib/os_mon/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/doc/src/ref_man.xml b/lib/os_mon/doc/src/ref_man.xml
index 10c0fef52c..1c6afc5a65 100644
--- a/lib/os_mon/doc/src/ref_man.xml
+++ b/lib/os_mon/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/os_mon/include/memsup.hrl b/lib/os_mon/include/memsup.hrl
index 743d16522e..f1e924a3d7 100644
--- a/lib/os_mon/include/memsup.hrl
+++ b/lib/os_mon/include/memsup.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/mibs/Makefile b/lib/os_mon/mibs/Makefile
index 19f3dc8367..725dd0f6a7 100644
--- a/lib/os_mon/mibs/Makefile
+++ b/lib/os_mon/mibs/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/os_mon/mibs/OTP-OS-MON-MIB.mib b/lib/os_mon/mibs/OTP-OS-MON-MIB.mib
index d6ababdcea..0bc5d62872 100644
--- a/lib/os_mon/mibs/OTP-OS-MON-MIB.mib
+++ b/lib/os_mon/mibs/OTP-OS-MON-MIB.mib
@@ -3,16 +3,17 @@
--
-- Copyright Ericsson AB 1997-2009. All Rights Reserved.
--
--- The contents of this file are subject to the Erlang Public License,
--- Version 1.1, (the "License"); you may not use this file except in
--- compliance with the License. You should have received a copy of the
--- Erlang Public License along with this software. If not, it can be
--- retrieved online at http://www.erlang.org/.
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
--
--- Software distributed under the License is distributed on an "AS IS"
--- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--- the License for the specific language governing rights and limitations
--- under the License.
+-- 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%
--
diff --git a/lib/os_mon/src/Makefile b/lib/os_mon/src/Makefile
index cd2dadec30..9aa068cb91 100644
--- a/lib/os_mon/src/Makefile
+++ b/lib/os_mon/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/os_mon/src/cpu_sup.erl b/lib/os_mon/src/cpu_sup.erl
index 66e7973e7e..72d392b804 100644
--- a/lib/os_mon/src/cpu_sup.erl
+++ b/lib/os_mon/src/cpu_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -121,7 +122,7 @@ util(Args) when is_list (Args) ->
util(_) ->
erlang:error(badarg).
--spec util() -> float().
+-spec util() -> float() | {'error', any()}.
util() ->
case util([]) of
@@ -160,7 +161,8 @@ handle_call(?quit, _From, State) ->
handle_call({?util, D, PC}, {Client, _Tag},
#state{os_type = {unix, Flavor}} = State)
when Flavor == sunos;
- Flavor == linux ->
+ Flavor == linux;
+ Flavor == freebsd ->
case measurement_server_call(State#state.server, {?util, D, PC, Client}) of
{error, Reason} ->
{ reply,
@@ -217,8 +219,6 @@ code_change(_OldVsn, State, _Extra) ->
%% internal functions
%%----------------------------------------------------------------------
-get_uint32_measurement(Request, #internal{port = P, os_type = {unix, sunos}}) ->
- port_server_call(P, Request);
get_uint32_measurement(Request, #internal{os_type = {unix, linux}}) ->
{ok,F} = file:open("/proc/loadavg",[read,raw]),
{ok,D} = file:read_line(F),
@@ -231,67 +231,13 @@ get_uint32_measurement(Request, #internal{os_type = {unix, linux}}) ->
?ping -> 4711;
?nprocs -> PTotal
end;
-get_uint32_measurement(Request, #internal{os_type = {unix, freebsd}}) ->
- D = os:cmd("/sbin/sysctl -n vm.loadavg") -- "\n",
- {ok,[Load1,Load5,Load15],_} = io_lib:fread("{ ~f ~f ~f }", D),
- %% We could count the lines from the ps command as well
- case Request of
- ?avg1 -> sunify(Load1);
- ?avg5 -> sunify(Load5);
- ?avg15 -> sunify(Load15);
- ?ping -> 4711;
- ?nprocs ->
- Ps = os:cmd("/bin/ps -ax | /usr/bin/wc -l"),
- {ok, [N], _} = io_lib:fread("~d", Ps),
- N-1
- end;
-get_uint32_measurement(Request, #internal{os_type = {unix, dragonfly}}) ->
- D = os:cmd("/sbin/sysctl -n vm.loadavg") -- "\n",
- {ok,[Load1,Load5,Load15],_} = io_lib:fread("{ ~f ~f ~f }", D),
- %% We could count the lines from the ps command as well
- case Request of
- ?avg1 -> sunify(Load1);
- ?avg5 -> sunify(Load5);
- ?avg15 -> sunify(Load15);
- ?ping -> 4711;
- ?nprocs ->
- Ps = os:cmd("/bin/ps -ax | /usr/bin/wc -l"),
- {ok, [N], _} = io_lib:fread("~d", Ps),
- N-1
- end;
-get_uint32_measurement(Request, #internal{os_type = {unix, openbsd}}) ->
- D = os:cmd("/sbin/sysctl -n vm.loadavg") -- "\n",
- {ok, [L1, L5, L15], _} = io_lib:fread("~f ~f ~f", D),
- case Request of
- ?avg1 -> sunify(L1);
- ?avg5 -> sunify(L5);
- ?avg15 -> sunify(L15);
- ?ping -> 4711;
- ?nprocs ->
- Ps = os:cmd("/bin/ps -ax | /usr/bin/wc -l"),
- {ok, [N], _} = io_lib:fread("~d", Ps),
- N-1
- end;
-get_uint32_measurement(Request, #internal{os_type = {unix, darwin}}) ->
- %% Get the load average using uptime, overriding Locale setting.
- D = os:cmd("LANG=C LC_ALL=C uptime") -- "\n",
- %% Here is a sample uptime string from Mac OS 10.3.8 (C Locale):
- %% "11:17 up 12 days, 20:39, 2 users, load averages: 1.07 0.95 0.66"
- %% The safest way to extract the load averages seems to be grab everything
- %% after the last colon and then do an fread on that.
- Avg = lists:reverse(hd(string:tokens(lists:reverse(D), ":"))),
- {ok,[L1,L5,L15],_} = io_lib:fread("~f ~f ~f", Avg),
-
- case Request of
- ?avg1 -> sunify(L1);
- ?avg5 -> sunify(L5);
- ?avg15 -> sunify(L15);
- ?ping -> 4711;
- ?nprocs ->
- Ps = os:cmd("/bin/ps -ax | /usr/bin/wc -l"),
- {ok, [N], _} = io_lib:fread("~d", Ps),
- N-1
- end;
+get_uint32_measurement(Request, #internal{port = P, os_type = {unix, Sys}}) when
+ Sys == sunos;
+ Sys == dragonfly;
+ Sys == openbsd;
+ Sys == freebsd;
+ Sys == darwin ->
+ port_server_call(P, Request);
get_uint32_measurement(Request, #internal{os_type = {unix, Sys}}) when Sys == irix64;
Sys == irix ->
%% Get the load average using uptime.
@@ -541,14 +487,16 @@ measurement_server_init() ->
process_flag(trap_exit, true),
OS = os:type(),
Server = case OS of
- {unix, Flavor} when Flavor==sunos;
- Flavor==linux ->
- {ok, Pid} = port_server_start_link(),
- Pid;
- {unix, Flavor} when Flavor==darwin;
+ {unix, Flavor} when
+ Flavor==sunos;
+ Flavor==linux;
+ Flavor==darwin;
Flavor==freebsd;
Flavor==dragonfly;
- Flavor==openbsd;
+ Flavor==openbsd ->
+ {ok, Pid} = port_server_start_link(),
+ Pid;
+ {unix, Flavor} when
Flavor==irix64;
Flavor==irix ->
not_used;
diff --git a/lib/os_mon/src/disksup.erl b/lib/os_mon/src/disksup.erl
index af5bcc6fe8..23c7ebbe99 100644
--- a/lib/os_mon/src/disksup.erl
+++ b/lib/os_mon/src/disksup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl
index b178732fae..e4b7c8c0ce 100644
--- a/lib/os_mon/src/memsup.erl
+++ b/lib/os_mon/src/memsup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/nteventlog.erl b/lib/os_mon/src/nteventlog.erl
index 97eaf07179..8726f369ee 100644
--- a/lib/os_mon/src/nteventlog.erl
+++ b/lib/os_mon/src/nteventlog.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/os_mon.app.src b/lib/os_mon/src/os_mon.app.src
index cc08cebe3d..6ef7beda1f 100644
--- a/lib/os_mon/src/os_mon.app.src
+++ b/lib/os_mon/src/os_mon.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/os_mon.appup.src b/lib/os_mon/src/os_mon.appup.src
index 480f5d9511..108b0bb5b8 100644
--- a/lib/os_mon/src/os_mon.appup.src
+++ b/lib/os_mon/src/os_mon.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/os_mon.erl b/lib/os_mon/src/os_mon.erl
index b5f71f3eed..0fef0ecece 100644
--- a/lib/os_mon/src/os_mon.erl
+++ b/lib/os_mon/src/os_mon.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/os_mon_mib.erl b/lib/os_mon/src/os_mon_mib.erl
index ea17f928cc..ef6f81a5d7 100644
--- a/lib/os_mon/src/os_mon_mib.erl
+++ b/lib/os_mon/src/os_mon_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/os_mon_sysinfo.erl b/lib/os_mon/src/os_mon_sysinfo.erl
index fb732d1e3a..c554b08bef 100644
--- a/lib/os_mon/src/os_mon_sysinfo.erl
+++ b/lib/os_mon/src/os_mon_sysinfo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/src/os_sup.erl b/lib/os_mon/src/os_sup.erl
index 3ad8b6e990..2a75698ab0 100644
--- a/lib/os_mon/src/os_sup.erl
+++ b/lib/os_mon/src/os_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/os_mon/test/Makefile b/lib/os_mon/test/Makefile
index cbb014324d..cdfc13a4c1 100644
--- a/lib/os_mon/test/Makefile
+++ b/lib/os_mon/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl
index 9f58e043db..e96b54d3fe 100644
--- a/lib/os_mon/test/cpu_sup_SUITE.erl
+++ b/lib/os_mon/test/cpu_sup_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -64,6 +65,8 @@ all() ->
[load_api, util_api, util_values, port, unavailable];
{unix, linux} ->
[load_api, util_api, util_values, port, unavailable];
+ {unix, freebsd} ->
+ [load_api, util_api, util_values, port, unavailable];
{unix, _OSname} -> [load_api];
_OS -> [unavailable]
end.
diff --git a/lib/os_mon/test/disksup_SUITE.erl b/lib/os_mon/test/disksup_SUITE.erl
index f9addd96cf..e41fc73ab2 100644
--- a/lib/os_mon/test/disksup_SUITE.erl
+++ b/lib/os_mon/test/disksup_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/os_mon/test/memsup_SUITE.erl b/lib/os_mon/test/memsup_SUITE.erl
index 1d9ebca51f..8ab61e9581 100644
--- a/lib/os_mon/test/memsup_SUITE.erl
+++ b/lib/os_mon/test/memsup_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/os_mon/test/os_mon_SUITE.erl b/lib/os_mon/test/os_mon_SUITE.erl
index 08ad8436dd..5c484ef2a6 100644
--- a/lib/os_mon/test/os_mon_SUITE.erl
+++ b/lib/os_mon/test/os_mon_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/os_mon/test/os_mon_conf.erl b/lib/os_mon/test/os_mon_conf.erl
index 5c1fa43047..da08bf3917 100644
--- a/lib/os_mon/test/os_mon_conf.erl
+++ b/lib/os_mon/test/os_mon_conf.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/os_mon/test/os_mon_mib_SUITE.erl b/lib/os_mon/test/os_mon_mib_SUITE.erl
index 08f5532d50..e68a139a74 100644
--- a/lib/os_mon/test/os_mon_mib_SUITE.erl
+++ b/lib/os_mon/test/os_mon_mib_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/os_mon/test/os_sup_SUITE.erl b/lib/os_mon/test/os_sup_SUITE.erl
index 61005f5ca0..768d95aebc 100644
--- a/lib/os_mon/test/os_sup_SUITE.erl
+++ b/lib/os_mon/test/os_sup_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk
index 833e855e0e..7f2667e40a 100644
--- a/lib/os_mon/vsn.mk
+++ b/lib/os_mon/vsn.mk
@@ -1 +1 @@
-OS_MON_VSN = 2.3.1
+OS_MON_VSN = 2.4
diff --git a/lib/ose/Makefile b/lib/ose/Makefile
index 2959f04c3e..6119b75c3f 100644
--- a/lib/ose/Makefile
+++ b/lib/ose/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ose/doc/src/Makefile b/lib/ose/doc/src/Makefile
index dd58029064..7ebd4125ba 100644
--- a/lib/ose/doc/src/Makefile
+++ b/lib/ose/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/ose/doc/src/book.xml b/lib/ose/doc/src/book.xml
index 485806e05b..d62e0d32f4 100644
--- a/lib/ose/doc/src/book.xml
+++ b/lib/ose/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ose/doc/src/notes.xml b/lib/ose/doc/src/notes.xml
index 7e86355f98..06881b6c99 100644
--- a/lib/ose/doc/src/notes.xml
+++ b/lib/ose/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -30,6 +31,22 @@
</header>
<p>This document describes the changes made to the OSE application.</p>
+<section><title>Ose 1.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ose 1.0.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ose/doc/src/ose_app.xml b/lib/ose/doc/src/ose_app.xml
index e40656fd7b..d555f0ec4f 100644
--- a/lib/ose/doc/src/ose_app.xml
+++ b/lib/ose/doc/src/ose_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ose/doc/src/ose_erl_driver.xml b/lib/ose/doc/src/ose_erl_driver.xml
index 1d89d7aeea..b804c29d2d 100644
--- a/lib/ose/doc/src/ose_erl_driver.xml
+++ b/lib/ose/doc/src/ose_erl_driver.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ose/doc/src/ose_intro.xml b/lib/ose/doc/src/ose_intro.xml
index 0ed470890b..982516c8bd 100644
--- a/lib/ose/doc/src/ose_intro.xml
+++ b/lib/ose/doc/src/ose_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ose/doc/src/ose_signals_chapter.xml b/lib/ose/doc/src/ose_signals_chapter.xml
index ff501777cc..bcf2259577 100644
--- a/lib/ose/doc/src/ose_signals_chapter.xml
+++ b/lib/ose/doc/src/ose_signals_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ose/doc/src/part.xml b/lib/ose/doc/src/part.xml
index 250bb11f96..0c9ebd16c0 100644
--- a/lib/ose/doc/src/part.xml
+++ b/lib/ose/doc/src/part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/ose/doc/src/ref_man.xml b/lib/ose/doc/src/ref_man.xml
index 54c1182fcb..964e5ab8ff 100644
--- a/lib/ose/doc/src/ref_man.xml
+++ b/lib/ose/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ose/src/Makefile b/lib/ose/src/Makefile
index 88f89578fb..a89e9392e9 100644
--- a/lib/ose/src/Makefile
+++ b/lib/ose/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/ose/src/ose.app.src b/lib/ose/src/ose.app.src
index 60699c369b..036779eb16 100644
--- a/lib/ose/src/ose.app.src
+++ b/lib/ose/src/ose.app.src
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ose/src/ose.appup.src b/lib/ose/src/ose.appup.src
index 6654efde16..28b6da3439 100644
--- a/lib/ose/src/ose.appup.src
+++ b/lib/ose/src/ose.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/ose/src/ose.erl b/lib/ose/src/ose.erl
index 77f11addf9..5534dba4d4 100644
--- a/lib/ose/src/ose.erl
+++ b/lib/ose/src/ose.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ose/test/ose_SUITE.erl b/lib/ose/test/ose_SUITE.erl
index 7e81b19894..31d950bd03 100644
--- a/lib/ose/test/ose_SUITE.erl
+++ b/lib/ose/test/ose_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ose/vsn.mk b/lib/ose/vsn.mk
index 70db2ed69d..fb1cf8219f 100644
--- a/lib/ose/vsn.mk
+++ b/lib/ose/vsn.mk
@@ -1 +1 @@
-OSE_VSN = 1.0.2
+OSE_VSN = 1.1
diff --git a/lib/otp_mibs/Makefile b/lib/otp_mibs/Makefile
index a88f0fef69..2dfab524fd 100644
--- a/lib/otp_mibs/Makefile
+++ b/lib/otp_mibs/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/otp_mibs/doc/src/Makefile b/lib/otp_mibs/doc/src/Makefile
index 6b8610bc23..3f9d8cc004 100644
--- a/lib/otp_mibs/doc/src/Makefile
+++ b/lib/otp_mibs/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/otp_mibs/doc/src/book.xml b/lib/otp_mibs/doc/src/book.xml
index 5377685cd3..1c3a3fdea4 100644
--- a/lib/otp_mibs/doc/src/book.xml
+++ b/lib/otp_mibs/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/doc/src/introduction.xml b/lib/otp_mibs/doc/src/introduction.xml
index e58c237de2..4236e45aae 100644
--- a/lib/otp_mibs/doc/src/introduction.xml
+++ b/lib/otp_mibs/doc/src/introduction.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/doc/src/mibs.xml b/lib/otp_mibs/doc/src/mibs.xml
index 4e3e849043..11900d3399 100644
--- a/lib/otp_mibs/doc/src/mibs.xml
+++ b/lib/otp_mibs/doc/src/mibs.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/doc/src/notes.xml b/lib/otp_mibs/doc/src/notes.xml
index c61978c99e..5dd112e937 100644
--- a/lib/otp_mibs/doc/src/notes.xml
+++ b/lib/otp_mibs/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,22 @@
<p>This document describes the changes made to the OTP_Mibs
application.</p>
+<section><title>Otp_Mibs 1.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Otp_Mibs 1.0.10</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/otp_mibs/doc/src/otp_mib.xml b/lib/otp_mibs/doc/src/otp_mib.xml
index 9be25fc7a0..bf9c474ec4 100644
--- a/lib/otp_mibs/doc/src/otp_mib.xml
+++ b/lib/otp_mibs/doc/src/otp_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/doc/src/part.xml b/lib/otp_mibs/doc/src/part.xml
index 352a4e33c8..c03254f96e 100644
--- a/lib/otp_mibs/doc/src/part.xml
+++ b/lib/otp_mibs/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/doc/src/part_notes.xml b/lib/otp_mibs/doc/src/part_notes.xml
index 1212c2d80d..be65d59fdb 100644
--- a/lib/otp_mibs/doc/src/part_notes.xml
+++ b/lib/otp_mibs/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/doc/src/ref_man.xml b/lib/otp_mibs/doc/src/ref_man.xml
index d1d5d7f2eb..52576b160b 100644
--- a/lib/otp_mibs/doc/src/ref_man.xml
+++ b/lib/otp_mibs/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/otp_mibs/mibs/Makefile b/lib/otp_mibs/mibs/Makefile
index 7f43ef31a6..01333dcac4 100644
--- a/lib/otp_mibs/mibs/Makefile
+++ b/lib/otp_mibs/mibs/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/otp_mibs/mibs/OTP-EVA-MIB.mib b/lib/otp_mibs/mibs/OTP-EVA-MIB.mib
index 2815251c23..24031478dc 100644
--- a/lib/otp_mibs/mibs/OTP-EVA-MIB.mib
+++ b/lib/otp_mibs/mibs/OTP-EVA-MIB.mib
@@ -3,16 +3,17 @@
--
-- Copyright Ericsson AB 2004-2009. All Rights Reserved.
--
--- The contents of this file are subject to the Erlang Public License,
--- Version 1.1, (the "License"); you may not use this file except in
--- compliance with the License. You should have received a copy of the
--- Erlang Public License along with this software. If not, it can be
--- retrieved online at http://www.erlang.org/.
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
--
--- Software distributed under the License is distributed on an "AS IS"
--- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--- the License for the specific language governing rights and limitations
--- under the License.
+-- 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%
--
diff --git a/lib/otp_mibs/mibs/OTP-MIB.mib b/lib/otp_mibs/mibs/OTP-MIB.mib
index 22dc21c9c5..8d7d920765 100644
--- a/lib/otp_mibs/mibs/OTP-MIB.mib
+++ b/lib/otp_mibs/mibs/OTP-MIB.mib
@@ -3,16 +3,17 @@
--
-- Copyright Ericsson AB 1996-2009. All Rights Reserved.
--
--- The contents of this file are subject to the Erlang Public License,
--- Version 1.1, (the "License"); you may not use this file except in
--- compliance with the License. You should have received a copy of the
--- Erlang Public License along with this software. If not, it can be
--- retrieved online at http://www.erlang.org/.
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
--
--- Software distributed under the License is distributed on an "AS IS"
--- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--- the License for the specific language governing rights and limitations
--- under the License.
+-- 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%
--
diff --git a/lib/otp_mibs/mibs/OTP-REG.mib b/lib/otp_mibs/mibs/OTP-REG.mib
index c700f93fd8..68b4ee3882 100644
--- a/lib/otp_mibs/mibs/OTP-REG.mib
+++ b/lib/otp_mibs/mibs/OTP-REG.mib
@@ -3,16 +3,17 @@
--
-- Copyright Ericsson AB 1997-2009. All Rights Reserved.
--
--- The contents of this file are subject to the Erlang Public License,
--- Version 1.1, (the "License"); you may not use this file except in
--- compliance with the License. You should have received a copy of the
--- Erlang Public License along with this software. If not, it can be
--- retrieved online at http://www.erlang.org/.
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
--
--- Software distributed under the License is distributed on an "AS IS"
--- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--- the License for the specific language governing rights and limitations
--- under the License.
+-- 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%
--
diff --git a/lib/otp_mibs/mibs/OTP-TC.mib b/lib/otp_mibs/mibs/OTP-TC.mib
index 9b80e1ccac..ca7625f9e2 100644
--- a/lib/otp_mibs/mibs/OTP-TC.mib
+++ b/lib/otp_mibs/mibs/OTP-TC.mib
@@ -3,16 +3,17 @@
--
-- Copyright Ericsson AB 1997-2009. All Rights Reserved.
--
--- The contents of this file are subject to the Erlang Public License,
--- Version 1.1, (the "License"); you may not use this file except in
--- compliance with the License. You should have received a copy of the
--- Erlang Public License along with this software. If not, it can be
--- retrieved online at http://www.erlang.org/.
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
--
--- Software distributed under the License is distributed on an "AS IS"
--- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--- the License for the specific language governing rights and limitations
--- under the License.
+-- 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%
--
diff --git a/lib/otp_mibs/src/Makefile b/lib/otp_mibs/src/Makefile
index 6096240bbd..03892cd43d 100644
--- a/lib/otp_mibs/src/Makefile
+++ b/lib/otp_mibs/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/otp_mibs/src/otp_mib.erl b/lib/otp_mibs/src/otp_mib.erl
index 9d52ce1fab..bd814e01e0 100644
--- a/lib/otp_mibs/src/otp_mib.erl
+++ b/lib/otp_mibs/src/otp_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/otp_mibs/src/otp_mibs.app.src b/lib/otp_mibs/src/otp_mibs.app.src
index ebc656b0b2..f4eb34d627 100644
--- a/lib/otp_mibs/src/otp_mibs.app.src
+++ b/lib/otp_mibs/src/otp_mibs.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/otp_mibs/src/otp_mibs.appup.src b/lib/otp_mibs/src/otp_mibs.appup.src
index fd5ce1e391..6b8fe71775 100644
--- a/lib/otp_mibs/src/otp_mibs.appup.src
+++ b/lib/otp_mibs/src/otp_mibs.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/otp_mibs/test/Makefile b/lib/otp_mibs/test/Makefile
index 48c1c5c7d8..e1cfbb347d 100644
--- a/lib/otp_mibs/test/Makefile
+++ b/lib/otp_mibs/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/otp_mibs/test/otp_mibs_SUITE.erl b/lib/otp_mibs/test/otp_mibs_SUITE.erl
index 5376c54210..abb5aa8194 100644
--- a/lib/otp_mibs/test/otp_mibs_SUITE.erl
+++ b/lib/otp_mibs/test/otp_mibs_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/otp_mibs/vsn.mk b/lib/otp_mibs/vsn.mk
index 2ff59431f4..38436d363e 100644
--- a/lib/otp_mibs/vsn.mk
+++ b/lib/otp_mibs/vsn.mk
@@ -1,4 +1,4 @@
-OTP_MIBS_VSN = 1.0.10
+OTP_MIBS_VSN = 1.1
# Note: The branch 'otp_mibs' is defunct as of otp_mibs-1.0.4 and
# should NOT be used again.
diff --git a/lib/parsetools/Makefile b/lib/parsetools/Makefile
index ae915551fe..8397c2550d 100644
--- a/lib/parsetools/Makefile
+++ b/lib/parsetools/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/parsetools/doc/src/Makefile b/lib/parsetools/doc/src/Makefile
index 96879084d8..97157d99e5 100644
--- a/lib/parsetools/doc/src/Makefile
+++ b/lib/parsetools/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/parsetools/doc/src/book.xml b/lib/parsetools/doc/src/book.xml
index 9ae9f72870..0853d2fdb3 100644
--- a/lib/parsetools/doc/src/book.xml
+++ b/lib/parsetools/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml
index 7ee0633dac..85680f58a6 100644
--- a/lib/parsetools/doc/src/leex.xml
+++ b/lib/parsetools/doc/src/leex.xml
@@ -47,7 +47,7 @@ Token = tuple()</code>
<v>LeexRet = {ok, Scannerfile}
| {ok, Scannerfile, Warnings}
| error
- | {error, Warnings, Errors}</v>
+ | {error, Errors, Warnings}</v>
<v>Scannerfile = filename()</v>
<v>Warnings = Errors = [{filename(), [ErrorInfo]}]</v>
<v>ErrorInfo = {ErrorLine, module(), Reason}</v>
diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml
index c8cb70b6d2..43840a3bc7 100644
--- a/lib/parsetools/doc/src/notes.xml
+++ b/lib/parsetools/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,37 @@
</header>
<p>This document describes the changes made to the Parsetools application.</p>
+<section><title>Parsetools 2.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct the documentation of the error tuple returned by
+ Yecc and Leex.</p>
+ <p>
+ Own Id: OTP-13031</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Parsetools 2.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The new <c>-dialyzer()</c> attribute is used for
+ suppressing Dialyzer warnings in generated code. </p>
+ <p>
+ Own Id: OTP-12271</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Parsetools 2.0.12</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/parsetools/doc/src/notes_history.xml b/lib/parsetools/doc/src/notes_history.xml
index 5b8ab69e30..2008a7c3e6 100644
--- a/lib/parsetools/doc/src/notes_history.xml
+++ b/lib/parsetools/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/parsetools/doc/src/part_notes.xml b/lib/parsetools/doc/src/part_notes.xml
index f7bcd22e7e..4164e7cc24 100644
--- a/lib/parsetools/doc/src/part_notes.xml
+++ b/lib/parsetools/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/parsetools/doc/src/ref_man.xml b/lib/parsetools/doc/src/ref_man.xml
index 1bdca3395a..0b9c6f3a29 100644
--- a/lib/parsetools/doc/src/ref_man.xml
+++ b/lib/parsetools/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/parsetools/doc/src/yecc.xml b/lib/parsetools/doc/src/yecc.xml
index 7298e09c2c..87fdfcdaef 100644
--- a/lib/parsetools/doc/src/yecc.xml
+++ b/lib/parsetools/doc/src/yecc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -51,7 +52,7 @@
<v>Grammarfile = filename()</v>
<v>Options = Option | [Option]</v>
<v>Option =&nbsp;-&nbsp;see below&nbsp;-</v>
- <v>YeccRet = {ok, Parserfile} | {ok, Parserfile, Warnings} | error | {error, Warnings, Errors}</v>
+ <v>YeccRet = {ok, Parserfile} | {ok, Parserfile, Warnings} | error | {error, Errors, Warnings}</v>
<v>Parserfile = filename()</v>
<v>Warnings = Errors = [{filename(), [ErrorInfo]}]</v>
<v>ErrorInfo = {ErrorLine, module(), Reason}</v>
diff --git a/lib/parsetools/include/leexinc.hrl b/lib/parsetools/include/leexinc.hrl
index 938aef58f9..2657fdcfaa 100644
--- a/lib/parsetools/include/leexinc.hrl
+++ b/lib/parsetools/include/leexinc.hrl
@@ -44,6 +44,8 @@ string(Ics0, L0, Tcs, Ts) ->
%% Test for and remove the end token wrapper. Push back characters
%% are prepended to RestChars.
+-dialyzer({nowarn_function, string_cont/4}).
+
string_cont(Rest, Line, {token,T}, Ts) ->
string(Rest, Line, Rest, [T|Ts]);
string_cont(Rest, Line, {token,T,Push}, Ts) ->
@@ -113,6 +115,8 @@ token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) ->
%% If we have a token or error then return done, else if we have a
%% skip_token then continue.
+-dialyzer({nowarn_function, token_cont/3}).
+
token_cont(Rest, Line, {token,T}) ->
{done,{ok,T,Line},Rest};
token_cont(Rest, Line, {token,T,Push}) ->
@@ -187,6 +191,8 @@ tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) ->
%% a token then save it and continue, else if we have a skip_token
%% just continue.
+-dialyzer({nowarn_function, tokens_cont/4}).
+
tokens_cont(Rest, Line, {token,T}, Ts) ->
tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0);
tokens_cont(Rest, Line, {token,T,Push}, Ts) ->
@@ -238,6 +244,8 @@ skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) ->
%% Skip tokens until we have an end_token or error then return done
%% with the original rror.
+-dialyzer({nowarn_function, skip_cont/4}).
+
skip_cont(Rest, Line, {token,_T}, Error) ->
skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0);
skip_cont(Rest, Line, {token,_T,Push}, Error) ->
diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl
index 855bff5fdc..fe958e9738 100644
--- a/lib/parsetools/include/yeccpre.hrl
+++ b/lib/parsetools/include/yeccpre.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -124,21 +125,10 @@ yecc_end(Line) ->
{'$end', Line}.
yecctoken_end_location(Token) ->
- try
- {text, Str} = erl_scan:token_info(Token, text),
- {line, Line} = erl_scan:token_info(Token, line),
- Parts = re:split(Str, "\n"),
- Dline = length(Parts) - 1,
- Yline = Line + Dline,
- case erl_scan:token_info(Token, column) of
- {column, Column} ->
- Col = byte_size(lists:last(Parts)),
- {Yline, Col + if Dline =:= 0 -> Column; true -> 1 end};
- undefined ->
- Yline
- end
- catch _:_ ->
- yecctoken_location(Token)
+ try erl_anno:end_location(element(2, Token)) of
+ undefined -> yecctoken_location(Token);
+ Loc -> Loc
+ catch _:_ -> yecctoken_location(Token)
end.
-compile({nowarn_unused_function, yeccerror/1}).
@@ -149,15 +139,15 @@ yeccerror(Token) ->
-compile({nowarn_unused_function, yecctoken_to_string/1}).
yecctoken_to_string(Token) ->
- case catch erl_scan:token_info(Token, text) of
- {text, Txt} -> Txt;
- _ -> yecctoken2string(Token)
+ try erl_scan:text(Token) of
+ undefined -> yecctoken2string(Token);
+ Txt -> Txt
+ catch _:_ -> yecctoken2string(Token)
end.
yecctoken_location(Token) ->
- case catch erl_scan:token_info(Token, location) of
- {location, Loc} -> Loc;
- _ -> element(2, Token)
+ try erl_scan:location(Token)
+ catch _:_ -> element(2, Token)
end.
-compile({nowarn_unused_function, yecctoken2string/1}).
diff --git a/lib/parsetools/src/Makefile b/lib/parsetools/src/Makefile
index 2ee2285eb3..dbecdd24a5 100644
--- a/lib/parsetools/src/Makefile
+++ b/lib/parsetools/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index 03f864ff03..15d42a4d9c 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -1545,7 +1545,7 @@ out_action_code(File, XrlFile, {_A,Code,_Vars,Name,Args,ArgsChars}) ->
%% Should set the file to the .erl file, but instead assumes that
%% ?LEEXINC is syntactically correct.
io:fwrite(File, "\n-compile({inline,~w/~w}).\n", [Name, length(Args)]),
- {line, L} = erl_scan:token_info(hd(Code), line),
+ L = erl_scan:line(hd(Code)),
output_file_directive(File, XrlFile, L-2),
io:fwrite(File, "~s(~s) ->~n", [Name, ArgsChars]),
io:fwrite(File, " ~s\n", [pp_tokens(Code, L)]).
@@ -1557,7 +1557,7 @@ pp_tokens(Tokens, Line0) -> pp_tokens(Tokens, Line0, none).
pp_tokens([], _Line0, _) -> [];
pp_tokens([T | Ts], Line0, Prev) ->
- {line, Line} = erl_scan:token_info(T, line),
+ Line = erl_scan:line(T),
[pp_sep(Line, Line0, Prev, T), pp_symbol(T) | pp_tokens(Ts, Line, T)].
pp_symbol({var,_,Var}) -> atom_to_list(Var);
diff --git a/lib/parsetools/src/parsetools.app.src b/lib/parsetools/src/parsetools.app.src
index 9eeb8fcc05..a7b258820a 100644
--- a/lib/parsetools/src/parsetools.app.src
+++ b/lib/parsetools/src/parsetools.app.src
@@ -12,7 +12,7 @@
{env, [{file_util_search_methods,[{"", ""}, {"ebin", "esrc"}, {"ebin", "src"}]}
]
},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}
+ {runtime_dependencies, ["stdlib-2.5","kernel-3.0","erts-6.0"]}
]
}.
diff --git a/lib/parsetools/src/parsetools.appup.src b/lib/parsetools/src/parsetools.appup.src
index 0e02099893..96df029f96 100644
--- a/lib/parsetools/src/parsetools.appup.src
+++ b/lib/parsetools/src/parsetools.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index f4657663e6..9d00675931 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -2064,11 +2065,13 @@ output_actions(St0, StateJumps, StateInfo) ->
SelS = [{State,Called} ||
{{State,_JActions}, {State,Called}} <-
lists:zip(StateJumps, lists:keysort(1, Sel))],
+ St05 =
+ fwrite(St0, <<"-dialyzer({nowarn_function, yeccpars2/7}).\n">>, []),
St10 = foldl(fun({State, Called}, St_0) ->
{State, #state_info{state_repr = IState}} =
lookup_state(StateInfo, State),
output_state_selection(St_0, State, IState, Called)
- end, St0, SelS),
+ end, St05, SelS),
St20 = fwrite(St10, <<"yeccpars2(Other, _, _, _, _, _, _) ->\n">>, []),
St = fwrite(St20,
?YECC_BUG(<<"{missing_state_in_action_table, Other}">>, []),
@@ -2089,7 +2092,8 @@ output_state_selection(St0, State, IState, Called) ->
[Comment, IState]).
output_state_actions(St, State, State, {Actions,jump_none}, SI) ->
- output_state_actions1(St, State, Actions, true, normal, SI);
+ St1 = output_state_actions_begin(St, State, Actions),
+ output_state_actions1(St1, State, Actions, true, normal, SI);
output_state_actions(St0, State, State, {Actions, Jump}, SI) ->
{Tag, To, Common} = Jump,
CS = case Tag of
@@ -2099,13 +2103,22 @@ output_state_actions(St0, State, State, {Actions, Jump}, SI) ->
St = output_state_actions1(St0, State, Actions, true, {to, CS}, SI),
if
To =:= State ->
- output_state_actions1(St, CS, Common, true, normal, SI);
+ St1 = output_state_actions_begin(St, State, Actions),
+ output_state_actions1(St1, CS, Common, true, normal, SI);
true ->
St
end;
output_state_actions(St, State, JState, _XActions, _SI) ->
fwrite(St, <<"%% yeccpars2_~w: see yeccpars2_~w\n\n">>, [State, JState]).
+output_state_actions_begin(St, State, Actions) ->
+ case [yes || {_, #reduce{}} <- Actions] of
+ [] ->
+ fwrite(St, <<"-dialyzer({nowarn_function, yeccpars2_~w/7}).\n">>,
+ [State]); % Only when yeccerror(T) is output.
+ _ -> St
+ end.
+
output_state_actions1(St, State, [], IsFirst, normal, _SI) ->
output_state_actions_fini(State, IsFirst, St);
output_state_actions1(St0, State, [], IsFirst, {to, ToS}, _SI) ->
diff --git a/lib/parsetools/src/yeccgramm.yrl b/lib/parsetools/src/yeccgramm.yrl
index 562a9a7458..c7b2ef6a86 100644
--- a/lib/parsetools/src/yeccgramm.yrl
+++ b/lib/parsetools/src/yeccgramm.yrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -38,8 +39,8 @@ rule -> head '->' symbols attached_code dot: {rule, ['$1' | '$3'], '$4'}.
head -> symbol : '$1'.
symbols -> symbol : ['$1'].
symbols -> symbol symbols : ['$1' | '$2'].
-strings -> string : ['$1'].
-strings -> string strings : ['$1' | '$2'].
+strings -> string : [string('$1')].
+strings -> string strings : [string('$1') | '$2'].
attached_code -> ':' tokens : {erlang_code, '$2'}.
attached_code -> '$empty' : {erlang_code, [{atom, 0, '$undefined'}]}.
tokens -> token : ['$1'].
@@ -48,12 +49,12 @@ symbol -> var : symbol('$1').
symbol -> atom : symbol('$1').
symbol -> integer : symbol('$1').
symbol -> reserved_word : symbol('$1').
-token -> var : '$1'.
-token -> atom : '$1'.
-token -> float : '$1'.
-token -> integer : '$1'.
-token -> string : '$1'.
-token -> char : '$1'.
+token -> var : token('$1').
+token -> atom : token('$1').
+token -> float : token('$1').
+token -> integer : token('$1').
+token -> string : token('$1').
+token -> char : token('$1').
token -> reserved_symbol : {value_of('$1'), line_of('$1')}.
token -> reserved_word : {value_of('$1'), line_of('$1')}.
token -> '->' : {'->', line_of('$1')}. % Have to be treated in this
@@ -67,8 +68,14 @@ Erlang code.
symbol(Symbol) ->
#symbol{line = line_of(Symbol), name = value_of(Symbol)}.
+token(Token) ->
+ setelement(2, Token, line_of(Token)).
+
+string(Token) ->
+ setelement(2, Token, line_of(Token)).
+
value_of(Token) ->
element(3, Token).
line_of(Token) ->
- element(2, Token).
+ erl_anno:line(element(2, Token)).
diff --git a/lib/parsetools/src/yeccparser.erl b/lib/parsetools/src/yeccparser.erl
index 54f9ba5a58..0025284ccf 100644
--- a/lib/parsetools/src/yeccparser.erl
+++ b/lib/parsetools/src/yeccparser.erl
@@ -7,28 +7,35 @@
symbol(Symbol) ->
#symbol{line = line_of(Symbol), name = value_of(Symbol)}.
+token(Token) ->
+ setelement(2, Token, line_of(Token)).
+
+string(Token) ->
+ setelement(2, Token, line_of(Token)).
+
value_of(Token) ->
element(3, Token).
line_of(Token) ->
- element(2, Token).
+ erl_anno:line(element(2, Token)).
--file("/clearcase/otp/erts/lib/parsetools/include/yeccpre.hrl", 0).
+-file("lib/parsetools/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% 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
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% http://www.apache.org/licenses/LICENSE-2.0
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -44,10 +51,11 @@ parse(Tokens) ->
-spec parse_and_scan({function() | {atom(), atom()}, [_]}
| {atom(), atom(), [_]}) -> yecc_ret().
-parse_and_scan({F, A}) -> % Fun or {M, F}
+parse_and_scan({F, A}) ->
yeccpars0([], {{F, A}, no_line}, 0, [], []);
parse_and_scan({M, F, A}) ->
- yeccpars0([], {{{M, F}, A}, no_line}, 0, [], []).
+ Arity = length(A),
+ yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []).
-spec format_error(any()) -> [char() | list()].
format_error(Message) ->
@@ -140,13 +148,13 @@ yecc_end(Line) ->
yecctoken_end_location(Token) ->
try
- {text, Str} = erl_scan:token_info(Token, text),
- {line, Line} = erl_scan:token_info(Token, line),
+ Str = erl_scan:text(Token),
+ Line = erl_scan:line(Token),
Parts = re:split(Str, "\n"),
Dline = length(Parts) - 1,
Yline = Line + Dline,
- case erl_scan:token_info(Token, column) of
- {column, Column} ->
+ case erl_scan:column(Token) of
+ Column when is_integer(Column) ->
Col = byte_size(lists:last(Parts)),
{Yline, Col + if Dline =:= 0 -> Column; true -> 1 end};
undefined ->
@@ -156,23 +164,26 @@ yecctoken_end_location(Token) ->
yecctoken_location(Token)
end.
+-compile({nowarn_unused_function, yeccerror/1}).
yeccerror(Token) ->
Text = yecctoken_to_string(Token),
Location = yecctoken_location(Token),
{error, {Location, ?MODULE, ["syntax error before: ", Text]}}.
+-compile({nowarn_unused_function, yecctoken_to_string/1}).
yecctoken_to_string(Token) ->
- case catch erl_scan:token_info(Token, text) of
- {text, Txt} -> Txt;
+ case catch erl_scan:text(Token) of
+ Txt when is_list(Txt) -> Txt;
_ -> yecctoken2string(Token)
end.
yecctoken_location(Token) ->
- case catch erl_scan:token_info(Token, location) of
- {location, Loc} -> Loc;
+ case catch erl_scan:location(Token) of
+ Loc when Loc =/= undefined -> Loc;
_ -> element(2, Token)
end.
+-compile({nowarn_unused_function, yecctoken2string/1}).
yecctoken2string({atom, _, A}) -> io_lib:write(A);
yecctoken2string({integer,_,N}) -> io_lib:write(N);
yecctoken2string({float,_,F}) -> io_lib:write(F);
@@ -180,7 +191,7 @@ yecctoken2string({char,_,C}) -> io_lib:write_char(C);
yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]);
yecctoken2string({string,_,S}) -> io_lib:write_string(S);
yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A);
-yecctoken2string({_Cat, _, Val}) -> io_lib:write(Val);
+yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]);
yecctoken2string({dot, _}) -> "'.'";
yecctoken2string({'$end', _}) ->
[];
@@ -193,7 +204,7 @@ yecctoken2string(Other) ->
--file("yeccparser.erl", 196).
+-file("yeccgramm.erl", 207).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
@@ -268,7 +279,7 @@ yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(Other, _, _, _, _, _, _) ->
- erlang:error({yecc_bug,"1.3",{missing_state_in_action_table, Other}}).
+ erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}).
yeccpars2_0(S, atom, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr);
@@ -417,16 +428,20 @@ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_20(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_20_(Stack),
+ yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_21_(Stack),
+ yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_22_(Stack),
+ yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_23_(Stack),
+ yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_24_(Stack),
@@ -437,10 +452,12 @@ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_26_(Stack),
+ yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_27_(Stack),
+ yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -616,6 +633,38 @@ yeccpars2_19_(__Stack0) ->
{ ':' , line_of ( __1 ) }
end | __Stack].
+-compile({inline,yeccpars2_20_/1}).
+-file("yeccgramm.yrl", 48).
+yeccpars2_20_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ token ( __1 )
+ end | __Stack].
+
+-compile({inline,yeccpars2_21_/1}).
+-file("yeccgramm.yrl", 52).
+yeccpars2_21_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ token ( __1 )
+ end | __Stack].
+
+-compile({inline,yeccpars2_22_/1}).
+-file("yeccgramm.yrl", 49).
+yeccpars2_22_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ token ( __1 )
+ end | __Stack].
+
+-compile({inline,yeccpars2_23_/1}).
+-file("yeccgramm.yrl", 50).
+yeccpars2_23_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ token ( __1 )
+ end | __Stack].
+
-compile({inline,yeccpars2_24_/1}).
-file("yeccgramm.yrl", 53).
yeccpars2_24_(__Stack0) ->
@@ -632,6 +681,22 @@ yeccpars2_25_(__Stack0) ->
{ value_of ( __1 ) , line_of ( __1 ) }
end | __Stack].
+-compile({inline,yeccpars2_26_/1}).
+-file("yeccgramm.yrl", 51).
+yeccpars2_26_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ token ( __1 )
+ end | __Stack].
+
+-compile({inline,yeccpars2_27_/1}).
+-file("yeccgramm.yrl", 47).
+yeccpars2_27_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ token ( __1 )
+ end | __Stack].
+
-compile({inline,yeccpars2_28_/1}).
-file("yeccgramm.yrl", 42).
yeccpars2_28_(__Stack0) ->
@@ -653,7 +718,7 @@ yeccpars2_29_(__Stack0) ->
yeccpars2_32_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ [ string ( __1 ) ]
end | __Stack].
-compile({inline,yeccpars2_33_/1}).
@@ -661,7 +726,7 @@ yeccpars2_32_(__Stack0) ->
yeccpars2_33_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __2 ]
+ [ string ( __1 ) | __2 ]
end | __Stack].
-compile({inline,yeccpars2_34_/1}).
@@ -681,4 +746,4 @@ yeccpars2_35_(__Stack0) ->
end | __Stack].
--file("yeccgramm.yrl", 75).
+-file("yeccgramm.yrl", 82).
diff --git a/lib/parsetools/src/yeccscan.erl b/lib/parsetools/src/yeccscan.erl
index fa3ce8c73b..56e2e5d3f4 100644
--- a/lib/parsetools/src/yeccscan.erl
+++ b/lib/parsetools/src/yeccscan.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/parsetools/test/Makefile b/lib/parsetools/test/Makefile
index 7c7cc13965..f84bb0e75e 100644
--- a/lib/parsetools/test/Makefile
+++ b/lib/parsetools/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/parsetools/test/app_SUITE.erl b/lib/parsetools/test/app_SUITE.erl
index 88ac95e311..dc9251bdae 100644
--- a/lib/parsetools/test/app_SUITE.erl
+++ b/lib/parsetools/test/app_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index 6d2afe061e..1e3738de85 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
index d308d21f82..6603a5a07d 100644
--- a/lib/parsetools/test/yecc_SUITE.erl
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -340,8 +341,8 @@ syntax(Config) when is_list(Config) ->
{_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
{L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
[]} = compile:file(Parserfile1, [basic_validation,return]),
- ?line L1 = 28 + SzYeccPre,
- ?line L2 = 35 + SzYeccPre
+ ?line L1 = 31 + SzYeccPre,
+ ?line L2 = 38 + SzYeccPre
end(),
%% Bad macro in action. OTP-7224.
@@ -358,8 +359,8 @@ syntax(Config) when is_list(Config) ->
{_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
{L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
[]} = compile:file(Parserfile1, [basic_validation,return]),
- ?line L1 = 28 + SzYeccPre,
- ?line L2 = 35 + SzYeccPre
+ ?line L1 = 31 + SzYeccPre,
+ ?line L2 = 38 + SzYeccPre
end(),
%% Check line numbers. OTP-7224.
@@ -1521,7 +1522,9 @@ otp_7945(doc) ->
"OTP-7945. A bug introduced in R13A.";
otp_7945(suite) -> [];
otp_7945(Config) when is_list(Config) ->
- ?line {error,_} = erl_parse:parse([{atom,3,foo},{'.',2,9,9}]),
+ A2 = erl_anno:new(2),
+ A3 = erl_anno:new(3),
+ {error,_} = erl_parse:parse([{atom,3,foo},{'.',A2,9,9}]),
ok.
otp_8483(doc) ->
@@ -1619,8 +1622,8 @@ otp_7292(Config) when is_list(Config) ->
{L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
[{_,[{16,_,{unused_function,{foo,0}}}]}]} =
compile:file(Parserfile1, [basic_validation, return]),
- ?line L1 = 38 + SzYeccPre,
- ?line L2 = 45 + SzYeccPre
+ L1 = 41 + SzYeccPre,
+ L2 = 48 + SzYeccPre
end(),
YeccPre = filename:join(Dir, "yeccpre.hrl"),
@@ -1637,8 +1640,8 @@ otp_7292(Config) when is_list(Config) ->
{L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
[{_,[{16,_,{unused_function,{foo,0}}}]}]} =
compile:file(Parserfile1, [basic_validation, return]),
- ?line L1 = 37 + SzYeccPre,
- ?line L2 = 44 + SzYeccPre
+ ?line L1 = 40 + SzYeccPre,
+ ?line L2 = 47 + SzYeccPre
end(),
file:delete(YeccPre),
@@ -1786,7 +1789,8 @@ otp_7969(Config) when is_list(Config) ->
?line {ok, Ts11, _}=R1 = erl_scan:string("f() -> a."),
?line F1 = fun() -> {ok,Ts11 ++ [{'$end',2}],2} end,
- ?line{ok,{function,1,f,0,[{clause,1,[],[],[{atom,1,a}]}]}} =
+ A1 = erl_anno:new(1),
+ {ok,{function,A1,f,0,[{clause,A1,[],[],[{atom,A1,a}]}]}} =
erl_parse:parse_and_scan({F1, []}),
?line F2 = fun() -> erl_scan:string("f() -> ,") end,
?line {error,{1,erl_parse,_}} = erl_parse:parse_and_scan({F2, []}),
@@ -1797,7 +1801,7 @@ otp_7969(Config) when is_list(Config) ->
put(foo,bar), R1
end
end,
- ?line {ok,{function,1,f,0,[{clause,1,[],[],[{atom,1,a}]}]}} =
+ {ok,{function,A1,f,0,[{clause,A1,[],[],[{atom,A1,a}]}]}} =
erl_parse:parse_and_scan({F3,[]}),
F4 = fun() -> {error, {1, ?MODULE, bad}, 2} end,
?line {error, {1,?MODULE,bad}} = erl_parse:parse_and_scan({F4, []}),
@@ -1813,7 +1817,8 @@ otp_8919(doc) ->
"OTP-8919. Improve formating of Yecc error messages.";
otp_8919(suite) -> [];
otp_8919(Config) when is_list(Config) ->
- {error,{1,Mod,Mess}} = erl_parse:parse([{cat,1,"hello"}]),
+ A1 = erl_anno:new(1),
+ {error,{1,Mod,Mess}} = erl_parse:parse([{cat,A1,"hello"}]),
"syntax error before: \"hello\"" = lists:flatten(Mod:format_error(Mess)),
ok.
diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk
index dd9cc2991c..de3da23c8a 100644
--- a/lib/parsetools/vsn.mk
+++ b/lib/parsetools/vsn.mk
@@ -1 +1 @@
-PARSETOOLS_VSN = 2.0.12
+PARSETOOLS_VSN = 2.1.1
diff --git a/lib/percept/Makefile b/lib/percept/Makefile
index 33f4a2fb58..2c6a970574 100644
--- a/lib/percept/Makefile
+++ b/lib/percept/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2007-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/percept/doc/src/Makefile b/lib/percept/doc/src/Makefile
index 3182dc2954..604c6d1db1 100644
--- a/lib/percept/doc/src/Makefile
+++ b/lib/percept/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/percept/doc/src/book.xml b/lib/percept/doc/src/book.xml
index cc86ab5a7f..1f12d57892 100644
--- a/lib/percept/doc/src/book.xml
+++ b/lib/percept/doc/src/book.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/percept/doc/src/egd_ug.xmlsrc b/lib/percept/doc/src/egd_ug.xmlsrc
index a980fe0611..253bfcaeb5 100644
--- a/lib/percept/doc/src/egd_ug.xmlsrc
+++ b/lib/percept/doc/src/egd_ug.xmlsrc
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml
index b51c8fcb4d..74183eb251 100644
--- a/lib/percept/doc/src/notes.xml
+++ b/lib/percept/doc/src/notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -32,6 +33,21 @@
</header>
<p>This document describes the changes made to the Percept application.</p>
+<section><title>Percept 0.8.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix http server configuration</p>
+ <p>
+ Own Id: OTP-12662</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Percept 0.8.10</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/percept/doc/src/part.xml b/lib/percept/doc/src/part.xml
index 5575eff53f..135532a9e6 100644
--- a/lib/percept/doc/src/part.xml
+++ b/lib/percept/doc/src/part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/percept/doc/src/part_notes.xml b/lib/percept/doc/src/part_notes.xml
index 8e226b35cb..458b5d3ea3 100644
--- a/lib/percept/doc/src/part_notes.xml
+++ b/lib/percept/doc/src/part_notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/percept/doc/src/percept_ug.xmlsrc b/lib/percept/doc/src/percept_ug.xmlsrc
index a0c5ab2c98..4791deea22 100644
--- a/lib/percept/doc/src/percept_ug.xmlsrc
+++ b/lib/percept/doc/src/percept_ug.xmlsrc
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/percept/doc/src/ref_man.xml b/lib/percept/doc/src/ref_man.xml
index 0f2cdb696b..b95fc56973 100644
--- a/lib/percept/doc/src/ref_man.xml
+++ b/lib/percept/doc/src/ref_man.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/percept/doc/stylesheet.css b/lib/percept/doc/stylesheet.css
index b94c0bf65b..86280a8fc4 100644
--- a/lib/percept/doc/stylesheet.css
+++ b/lib/percept/doc/stylesheet.css
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/percept/priv/Makefile b/lib/percept/priv/Makefile
index b82b51ed4b..44229c9567 100644
--- a/lib/percept/priv/Makefile
+++ b/lib/percept/priv/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/percept/priv/server_root/css/percept.css b/lib/percept/priv/server_root/css/percept.css
index 40d4e72693..7335e62387 100644
--- a/lib/percept/priv/server_root/css/percept.css
+++ b/lib/percept/priv/server_root/css/percept.css
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/percept/priv/server_root/htdocs/index.html b/lib/percept/priv/server_root/htdocs/index.html
index eeeaaf9a09..e84d8fb10a 100644
--- a/lib/percept/priv/server_root/htdocs/index.html
+++ b/lib/percept/priv/server_root/htdocs/index.html
@@ -3,16 +3,17 @@
Copyright Ericsson AB 2007-2009. All Rights Reserved.
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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%
-->
diff --git a/lib/percept/priv/server_root/scripts/percept_area_select.js b/lib/percept/priv/server_root/scripts/percept_area_select.js
index 8d2e811122..6dd64650be 100644
--- a/lib/percept/priv/server_root/scripts/percept_area_select.js
+++ b/lib/percept/priv/server_root/scripts/percept_area_select.js
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/percept/priv/server_root/scripts/percept_error_handler.js b/lib/percept/priv/server_root/scripts/percept_error_handler.js
index 4e6624d133..8bad57a5b7 100644
--- a/lib/percept/priv/server_root/scripts/percept_error_handler.js
+++ b/lib/percept/priv/server_root/scripts/percept_error_handler.js
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/percept/priv/server_root/scripts/percept_select_all.js b/lib/percept/priv/server_root/scripts/percept_select_all.js
index f5b4d26137..118741b7de 100644
--- a/lib/percept/priv/server_root/scripts/percept_select_all.js
+++ b/lib/percept/priv/server_root/scripts/percept_select_all.js
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-2009. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/percept/src/Makefile b/lib/percept/src/Makefile
index 0282d6346a..9b963e0fae 100644
--- a/lib/percept/src/Makefile
+++ b/lib/percept/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl
index 1b26d96728..3a065c8919 100644
--- a/lib/percept/src/egd.erl
+++ b/lib/percept/src/egd.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/percept/src/egd.hrl b/lib/percept/src/egd.hrl
index 2e8f5ebc50..43db16d3a1 100644
--- a/lib/percept/src/egd.hrl
+++ b/lib/percept/src/egd.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/percept/src/egd_font.erl b/lib/percept/src/egd_font.erl
index 5f0d56dd90..6ee3728fde 100644
--- a/lib/percept/src/egd_font.erl
+++ b/lib/percept/src/egd_font.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/src/egd_png.erl b/lib/percept/src/egd_png.erl
index 3a0aaeef31..c576d569a9 100644
--- a/lib/percept/src/egd_png.erl
+++ b/lib/percept/src/egd_png.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl
index 77c600279f..0a3a62c05c 100644
--- a/lib/percept/src/egd_primitives.erl
+++ b/lib/percept/src/egd_primitives.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl
index 7fd1072ab1..4297704677 100644
--- a/lib/percept/src/egd_render.erl
+++ b/lib/percept/src/egd_render.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/percept/src/percept.app.src b/lib/percept/src/percept.app.src
index f8991ee577..6a3800a17f 100644
--- a/lib/percept/src/percept.app.src
+++ b/lib/percept/src/percept.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/percept/src/percept.appup.src b/lib/percept/src/percept.appup.src
index 23e67f772f..cb4995b0d8 100644
--- a/lib/percept/src/percept.appup.src
+++ b/lib/percept/src/percept.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/percept/src/percept.erl b/lib/percept/src/percept.erl
index 3a2d9f7601..badb3f3d66 100644
--- a/lib/percept/src/percept.erl
+++ b/lib/percept/src/percept.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -319,10 +320,6 @@ get_webserver_config(Servername, Port) when is_list(Servername), is_integer(Port
{alias,{"/images/", filename:join([Root, "images"]) ++ "/"}},
{alias,{"/css/", filename:join([Root, "css"]) ++ "/"}},
- % Logs
- %{transfer_log, filename:join([Path, "logs", "transfer.log"])},
- %{error_log, filename:join([Path, "logs", "error.log"])},
-
% Configs
{default_type,"text/plain"},
{directory_index,["index.html"]},
@@ -331,12 +328,9 @@ get_webserver_config(Servername, Port) when is_list(Servername), is_integer(Port
mod_esi,
mod_actions,
mod_cgi,
- mod_include,
mod_dir,
mod_get,
mod_head
- % mod_log,
- % mod_disk_log
]},
{com_type,ip_comm},
{server_name, Servername},
diff --git a/lib/percept/src/percept.hrl b/lib/percept/src/percept.hrl
index 36b6f63a4d..a5639cfaf8 100644
--- a/lib/percept/src/percept.hrl
+++ b/lib/percept/src/percept.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/percept/src/percept_analyzer.erl b/lib/percept/src/percept_analyzer.erl
index a5440e4cd2..69338f52af 100644
--- a/lib/percept/src/percept_analyzer.erl
+++ b/lib/percept/src/percept_analyzer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl
index 68eb38d298..b627c67acd 100644
--- a/lib/percept/src/percept_db.erl
+++ b/lib/percept/src/percept_db.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/percept/src/percept_graph.erl b/lib/percept/src/percept_graph.erl
index 6f07948153..8ad7fd1bf6 100644
--- a/lib/percept/src/percept_graph.erl
+++ b/lib/percept/src/percept_graph.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/src/percept_html.erl b/lib/percept/src/percept_html.erl
index 7e0ea45783..ea7484ae70 100644
--- a/lib/percept/src/percept_html.erl
+++ b/lib/percept/src/percept_html.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/percept/src/percept_image.erl b/lib/percept/src/percept_image.erl
index 5baedabecf..f649439d7a 100644
--- a/lib/percept/src/percept_image.erl
+++ b/lib/percept/src/percept_image.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/percept/test/Makefile b/lib/percept/test/Makefile
index 156ef5dd0a..4ba0b80fc8 100644
--- a/lib/percept/test/Makefile
+++ b/lib/percept/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2007-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
index 51f090b39c..41e8999e17 100644
--- a/lib/percept/test/egd_SUITE.erl
+++ b/lib/percept/test/egd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/percept/test/ipc_tree.erl b/lib/percept/test/ipc_tree.erl
index f7639eed1b..ff1c8d49c1 100644
--- a/lib/percept/test/ipc_tree.erl
+++ b/lib/percept/test/ipc_tree.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/percept/test/percept_SUITE.erl b/lib/percept/test/percept_SUITE.erl
index aea2462b2e..fd96c2b97a 100644
--- a/lib/percept/test/percept_SUITE.erl
+++ b/lib/percept/test/percept_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/percept/test/percept_db_SUITE.erl b/lib/percept/test/percept_db_SUITE.erl
index 79be9714ba..e2775aabc0 100644
--- a/lib/percept/test/percept_db_SUITE.erl
+++ b/lib/percept/test/percept_db_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk
index 4451354e21..833ab35aa5 100644
--- a/lib/percept/vsn.mk
+++ b/lib/percept/vsn.mk
@@ -1 +1 @@
-PERCEPT_VSN = 0.8.10
+PERCEPT_VSN = 0.8.11
diff --git a/lib/public_key/Makefile b/lib/public_key/Makefile
index c679678b60..d1b6035139 100644
--- a/lib/public_key/Makefile
+++ b/lib/public_key/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile
index c1b3bc866d..7474297b9b 100644
--- a/lib/public_key/asn1/Makefile
+++ b/lib/public_key/asn1/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -66,7 +67,7 @@ EBIN = ../ebin
EXTRA_ERLC_FLAGS =
ERL_COMPILE_FLAGS += $(EXTRA_ERLC_FLAGS)
-ASN_FLAGS = -bber +der +compact_bit_string +noobj +asn1config
+ASN_FLAGS = -bber +der +noobj +asn1config
# ----------------------------------------------------
# Targets
diff --git a/lib/public_key/asn1/PKIX1Explicit88.asn1 b/lib/public_key/asn1/PKIX1Explicit88.asn1
index 91758d7269..81fec8283e 100644
--- a/lib/public_key/asn1/PKIX1Explicit88.asn1
+++ b/lib/public_key/asn1/PKIX1Explicit88.asn1
@@ -86,22 +86,22 @@ id-at-initials AttributeType ::= { id-at 43 }
id-at-generationQualifier AttributeType ::= { id-at 44 }
X520name ::= CHOICE {
- teletexString TeletexString (SIZE (1..ub-name)),
- printableString PrintableString (SIZE (1..ub-name)),
- universalString UniversalString (SIZE (1..ub-name)),
- utf8String UTF8String (SIZE (1..ub-name)),
- bmpString BMPString (SIZE (1..ub-name)) }
+ teletexString TeletexString (SIZE (1..ub-name-teletex)),
+ printableString PrintableString (SIZE (1..ub-name-printable)),
+ universalString UniversalString (SIZE (1..ub-name-universal)),
+ utf8String UTF8String (SIZE (1..ub-name-utf8)),
+ bmpString BMPString (SIZE (1..ub-name-universal)) }
-- Naming attributes of type X520CommonName
id-at-commonName AttributeType ::= { id-at 3 }
X520CommonName ::= CHOICE {
- teletexString TeletexString (SIZE (1..ub-common-name)),
- printableString PrintableString (SIZE (1..ub-common-name)),
- universalString UniversalString (SIZE (1..ub-common-name)),
- utf8String UTF8String (SIZE (1..ub-common-name)),
- bmpString BMPString (SIZE (1..ub-common-name)) }
+ teletexString TeletexString (SIZE (1..ub-common-name-teletex)),
+ printableString PrintableString (SIZE (1..ub-common-name-printable)),
+ universalString UniversalString (SIZE (1..ub-common-name-universal)),
+ utf8String UTF8String (SIZE (1..ub-common-name-utf8)),
+ bmpString BMPString (SIZE (1..ub-common-name-universal)) }
-- Naming attributes of type X520LocalityName
@@ -110,9 +110,9 @@ id-at-localityName AttributeType ::= { id-at 7 }
X520LocalityName ::= CHOICE {
teletexString TeletexString (SIZE (1..ub-locality-name)),
printableString PrintableString (SIZE (1..ub-locality-name)),
- universalString UniversalString (SIZE (1..ub-locality-name)),
- utf8String UTF8String (SIZE (1..ub-locality-name)),
- bmpString BMPString (SIZE (1..ub-locality-name)) }
+ universalString UniversalString (SIZE (1..ub-locality-name-universal)),
+ utf8String UTF8String (SIZE (1..ub-locality-name-utf8)),
+ bmpString BMPString (SIZE (1..ub-locality-name-universal)) }
-- Naming attributes of type X520StateOrProvinceName
@@ -121,9 +121,9 @@ id-at-stateOrProvinceName AttributeType ::= { id-at 8 }
X520StateOrProvinceName ::= CHOICE {
teletexString TeletexString (SIZE (1..ub-state-name)),
printableString PrintableString (SIZE (1..ub-state-name)),
- universalString UniversalString (SIZE (1..ub-state-name)),
- utf8String UTF8String (SIZE (1..ub-state-name)),
- bmpString BMPString (SIZE(1..ub-state-name)) }
+ universalString UniversalString (SIZE (1..ub-state-name-universal)),
+ utf8String UTF8String (SIZE (1..ub-state-name-utf8)),
+ bmpString BMPString (SIZE(1..ub-state-name-universal)) }
-- Naming attributes of type X520OrganizationName
@@ -131,15 +131,15 @@ id-at-organizationName AttributeType ::= { id-at 10 }
X520OrganizationName ::= CHOICE {
teletexString TeletexString
- (SIZE (1..ub-organization-name)),
+ (SIZE (1..ub-organization-name-teletex)),
printableString PrintableString
- (SIZE (1..ub-organization-name)),
+ (SIZE (1..ub-organization-name-printable)),
universalString UniversalString
- (SIZE (1..ub-organization-name)),
+ (SIZE (1..ub-organization-name-universal)),
utf8String UTF8String
- (SIZE (1..ub-organization-name)),
+ (SIZE (1..ub-organization-name-utf8)),
bmpString BMPString
- (SIZE (1..ub-organization-name)) }
+ (SIZE (1..ub-organization-name-universal)) }
-- Naming attributes of type X520OrganizationalUnitName
@@ -147,26 +147,26 @@ id-at-organizationalUnitName AttributeType ::= { id-at 11 }
X520OrganizationalUnitName ::= CHOICE {
teletexString TeletexString
- (SIZE (1..ub-organizational-unit-name)),
+ (SIZE (1..ub-organizational-unit-name-teletex)),
printableString PrintableString
- (SIZE (1..ub-organizational-unit-name)),
+ (SIZE (1..ub-organizational-unit-name-printable)),
universalString UniversalString
- (SIZE (1..ub-organizational-unit-name)),
+ (SIZE (1..ub-organizational-unit-name-universal)),
utf8String UTF8String
- (SIZE (1..ub-organizational-unit-name)),
+ (SIZE (1..ub-organizational-unit-name-utf8)),
bmpString BMPString
- (SIZE (1..ub-organizational-unit-name)) }
+ (SIZE (1..ub-organizational-unit-name-universal)) }
-- Naming attributes of type X520Title
id-at-title AttributeType ::= { id-at 12 }
X520Title ::= CHOICE {
- teletexString TeletexString (SIZE (1..ub-title)),
- printableString PrintableString (SIZE (1..ub-title)),
- universalString UniversalString (SIZE (1..ub-title)),
- utf8String UTF8String (SIZE (1..ub-title)),
- bmpString BMPString (SIZE (1..ub-title)) }
+ teletexString TeletexString (SIZE (1..ub-title-teletex)),
+ printableString PrintableString (SIZE (1..ub-title-printable)),
+ universalString UniversalString (SIZE (1..ub-title-universal)),
+ utf8String UTF8String (SIZE (1..ub-title-utf8)),
+ bmpString BMPString (SIZE (1..ub-title-universal)) }
-- Naming attributes of type X520dnQualifier
@@ -193,9 +193,9 @@ id-at-pseudonym AttributeType ::= { id-at 65 }
X520Pseudonym ::= CHOICE {
teletexString TeletexString (SIZE (1..ub-pseudonym)),
printableString PrintableString (SIZE (1..ub-pseudonym)),
- universalString UniversalString (SIZE (1..ub-pseudonym)),
- utf8String UTF8String (SIZE (1..ub-pseudonym)),
- bmpString BMPString (SIZE (1..ub-pseudonym)) }
+ universalString UniversalString (SIZE (1..ub-pseudonym-universal)),
+ utf8String UTF8String (SIZE (1..ub-pseudonym-utf8)),
+ bmpString BMPString (SIZE (1..ub-pseudonym-universal)) }
-- Naming attributes of type DomainComponent (from RFC 2247)
@@ -363,7 +363,7 @@ PrivateDomainName ::= CHOICE {
printable PrintableString (SIZE (1..ub-domain-name-length)) }
OrganizationName ::= PrintableString
- (SIZE (1..ub-organization-name-length))
+ (SIZE (1..ub-organization-name-printable))
-- see also teletex-organization-name
NumericUserIdentifier ::= NumericString
@@ -386,7 +386,7 @@ OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
-- see also teletex-organizational-unit-names
OrganizationalUnitName ::= PrintableString (SIZE
- (1..ub-organizational-unit-name-length))
+ (1..ub-organizational-unit-name-printable))
-- Built-in Domain-defined Attributes
@@ -415,16 +415,16 @@ ExtensionAttribute ::= SEQUENCE {
common-name INTEGER ::= 1
-CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
+CommonName ::= PrintableString (SIZE (1..ub-common-name-printable))
teletex-common-name INTEGER ::= 2
-TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
+TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-teletex))
teletex-organization-name INTEGER ::= 3
TeletexOrganizationName ::=
- TeletexString (SIZE (1..ub-organization-name-length))
+ TeletexString (SIZE (1..ub-organization-name-teletex))
teletex-personal-name INTEGER ::= 4
@@ -445,7 +445,7 @@ TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
(1..ub-organizational-units) OF TeletexOrganizationalUnitName
TeletexOrganizationalUnitName ::= TeletexString
- (SIZE (1..ub-organizational-unit-name-length))
+ (SIZE (1..ub-organizational-unit-name-teletex))
pds-name INTEGER ::= 7
@@ -570,16 +570,39 @@ TeletexDomainDefinedAttribute ::= SEQUENCE {
-- Upper Bounds
ub-name INTEGER ::= 32768
+ub-name-teletex INTEGER ::= 65536
+ub-name-printable INTEGER ::= 65536
+ub-name-universal INTEGER ::= 131072
+ub-name-utf8 INTEGER ::= 131072
ub-common-name INTEGER ::= 64
+ub-common-name-teletex INTEGER::= 128
+ub-common-name-printable INTEGER ::= 128
+ub-common-name-universal INTEGER ::= 256
+ub-common-name-utf8 INTEGER ::= 256
ub-locality-name INTEGER ::= 128
+ub-locality-name-utf8 INTEGER ::= 256
+ub-locality-name-universal INTEGER ::= 256
ub-state-name INTEGER ::= 128
+ub-state-name-universal INTEGER ::= 256
+ub-state-name-utf8 INTEGER ::= 256
ub-organization-name INTEGER ::= 64
+ub-organization-name-printable INTEGER ::= 128
+ub-organization-name-teletex INTEGER ::= 128
+ub-organization-name-universal INTEGER ::= 256
+ub-organization-name-utf8 INTEGER ::= 256
ub-organizational-unit-name INTEGER ::= 64
+ub-organizational-unit-name-printable INTEGER ::= 128
+ub-organizational-unit-name-teletex INTEGER ::= 128
+ub-organizational-unit-name-universal INTEGER ::= 256
+ub-organizational-unit-name-utf8 INTEGER ::= 256
ub-title INTEGER ::= 64
+ub-title-teletex INTEGER ::= 128
+ub-title-printable INTEGER ::= 128
+ub-title-universal INTEGER ::= 256
+ub-title-utf8 INTEGER ::= 256
ub-serial-number INTEGER ::= 64
ub-match INTEGER ::= 128
ub-emailaddress-length INTEGER ::= 255
-ub-common-name-length INTEGER ::= 64
ub-country-name-alpha-length INTEGER ::= 2
ub-country-name-numeric-length INTEGER ::= 3
ub-domain-defined-attributes INTEGER ::= 4
@@ -594,14 +617,14 @@ ub-given-name-length INTEGER ::= 16
ub-initials-length INTEGER ::= 5
ub-integer-options INTEGER ::= 256
ub-numeric-user-id-length INTEGER ::= 32
-ub-organization-name-length INTEGER ::= 64
-ub-organizational-unit-name-length INTEGER ::= 32
ub-organizational-units INTEGER ::= 4
ub-pds-name-length INTEGER ::= 16
ub-pds-parameter-length INTEGER ::= 30
ub-pds-physical-address-lines INTEGER ::= 6
ub-postal-code-length INTEGER ::= 16
ub-pseudonym INTEGER ::= 128
+ub-pseudonym-utf8 INTEGER ::= 256
+ub-pseudonym-universal INTEGER ::= 256
ub-surname-length INTEGER ::= 40
ub-terminal-id-length INTEGER ::= 24
ub-unformatted-address-length INTEGER ::= 180
diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile
index 17fb67e95c..3918c005f2 100644
--- a/lib/public_key/doc/src/Makefile
+++ b/lib/public_key/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -42,8 +43,7 @@ XML_REF6_FILES =
XML_PART_FILES = part.xml part_notes.xml
XML_CHAPTER_FILES = \
introduction.xml \
- public_key_records.xml \
- cert_records.xml \
+ public_key_records.xml \
using_public_key.xml \
notes.xml
diff --git a/lib/public_key/doc/src/book.xml b/lib/public_key/doc/src/book.xml
index 154a111066..d148bc0211 100644
--- a/lib/public_key/doc/src/book.xml
+++ b/lib/public_key/doc/src/book.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/public_key/doc/src/cert_records.xml b/lib/public_key/doc/src/cert_records.xml
deleted file mode 100644
index b66c66bead..0000000000
--- a/lib/public_key/doc/src/cert_records.xml
+++ /dev/null
@@ -1,690 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2008</year>
- <year>2014</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Certificate records</title>
- <prepared>Ingela Anderton Andin</prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date>2008-02-06</date>
- <rev>A</rev>
- <file>cert_records.xml</file>
- </header>
-
- <p>This chapter briefly describes erlang records derived from ASN1
- specifications used to handle <c> X509 certificates</c> and <c>CertificationRequest</c>.
- The intent is to describe the data types
-and not to specify the semantics of each component. For information on the
-semantics, please see <url
- href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</url> and
- <url href="http://www.ietf.org/rfc/rfc5967.txt">PKCS-10</url>.
- </p>
-
- <p>Use the following include directive to get access to the
- records and constant macros (OIDs) described in the following sections.</p>
-
- <code> -include_lib("public_key/include/public_key.hrl"). </code>
-
- <p>The used ASN1 specifications are available <c>asn1</c> subdirectory
- of the application <c>public_key</c>.
- </p>
-
- <section>
- <title>Common Data Types</title>
-
- <p>Common non standard erlang
- data types used to described the record fields in the
- below sections are defined in <seealso
- marker="public_key">public key reference manual </seealso> or
- follows here.</p>
-
- <p><c>time() = uct_time() | general_time()</c></p>
-
- <p><c>uct_time() = {utcTime, "YYMMDDHHMMSSZ"} </c></p>
-
- <p><c>general_time() = {generalTime, "YYYYMMDDHHMMSSZ"} </c></p>
-
- <p><c>
- general_name() = {rfc822Name, string()} | {dNSName, string()}
- | {x400Address, string()} | {directoryName,
- {rdnSequence, [#AttributeTypeAndValue'{}]}} |
- | {eidPartyName, special_string()}
- | {eidPartyName, special_string(), special_string()}
- | {uniformResourceIdentifier, string()} | {ipAddress, string()} |
- {registeredId, oid()} | {otherName, term()}
- </c></p>
-
- <p><c>
- special_string() =
- {teletexString, string()} | {printableString, string()} |
- {universalString, string()} | {utf8String, binary()} |
- {bmpString, string()}
- </c></p>
-
- <p><c>
- dist_reason() = unused | keyCompromise | cACompromise |
- affiliationChanged | superseded | cessationOfOperation |
- certificateHold | privilegeWithdrawn |
- aACompromise
- </c></p>
- </section>
-
- <section>
- <title> PKIX Certificates</title>
-<code>
-#'Certificate'{
- tbsCertificate, % #'TBSCertificate'{}
- signatureAlgorithm, % #'AlgorithmIdentifier'{}
- signature % {0, binary()} - ASN1 compact bitstring
- }.
-
-#'TBSCertificate'{
- version, % v1 | v2 | v3
- serialNumber, % integer()
- signature, % #'AlgorithmIdentifier'{}
- issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
- validity, % #'Validity'{}
- subject, % {rdnSequence, [#AttributeTypeAndValue'{}]}
- subjectPublicKeyInfo, % #'SubjectPublicKeyInfo'{}
- issuerUniqueID, % binary() | asn1_novalue
- subjectUniqueID, % binary() | asn1_novalue
- extensions % [#'Extension'{}]
- }.
-
-#'AlgorithmIdentifier'{
- algorithm, % oid()
- parameters % der_encoded()
- }.
-</code>
-
-<code>
-#'OTPCertificate'{
- tbsCertificate, % #'OTPTBSCertificate'{}
- signatureAlgorithm, % #'SignatureAlgorithm'
- signature % {0, binary()} - ASN1 compact bitstring
- }.
-
-#'OTPTBSCertificate'{
- version, % v1 | v2 | v3
- serialNumber, % integer()
- signature, % #'SignatureAlgorithm'
- issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
- validity, % #'Validity'{}
- subject, % {rdnSequence, [#AttributeTypeAndValue'{}]}
- subjectPublicKeyInfo, % #'OTPSubjectPublicKeyInfo'{}
- issuerUniqueID, % binary() | asn1_novalue
- subjectUniqueID, % binary() | asn1_novalue
- extensions % [#'Extension'{}]
- }.
-
-#'SignatureAlgorithm'{
- algorithm, % id_signature_algorithm()
- parameters % asn1_novalue | #'Dss-Parms'{}
- }.
-</code>
-
-<p><c> id_signature_algorithm() = ?oid_name_as_erlang_atom</c> for available
-oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
-<table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-dsa-with-sha1</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-dsaWithSHA1 (ISO alt oid to above)</cell>
- </row>
- <row>
- <cell align="left" valign="middle">md2WithRSAEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">md5WithRSAEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">sha1WithRSAEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">sha-1WithRSAEncryption (ISO alt oid to above)</cell>
- </row>
- <row>
- <cell align="left" valign="middle">sha224WithRSAEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">sha256WithRSAEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">sha512WithRSAEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">ecdsa-with-SHA1</cell>
- </row>
- <tcaption>Signature algorithm oids </tcaption>
-</table>
-
-<code>
-#'AttributeTypeAndValue'{
- type, % id_attributes()
- value % term()
- }.
-</code>
-
-<p><c>id_attributes() </c></p>
-<table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- <cell align="left" valign="middle">Value type</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-name</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-surname</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-givenName</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-initials </cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-generationQualifier</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-commonName</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-localityName</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-stateOrProvinceName</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-organizationName</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-title</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-dnQualifier</cell>
- <cell align="left" valign="middle">{printableString, string()}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-countryName</cell>
- <cell align="left" valign="middle">{printableString, string()}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-serialNumber</cell>
- <cell align="left" valign="middle">{printableString, string()}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-at-pseudonym</cell>
- <cell align="left" valign="middle">special_string()</cell>
- </row>
- <tcaption>Attribute oids </tcaption>
-</table>
-
-<code>
-#'Validity'{
- notBefore, % time()
- notAfter % time()
- }.
-
-#'SubjectPublicKeyInfo'{
- algorithm, % #AlgorithmIdentifier{}
- subjectPublicKey % binary()
- }.
-
-#'SubjectPublicKeyInfoAlgorithm'{
- algorithm, % id_public_key_algorithm()
- parameters % public_key_params()
- }.
-</code>
-
-<p><c> id_public_key_algorithm() </c></p>
-<table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- </row>
- <row>
- <cell align="left" valign="middle">rsaEncryption</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-dsa</cell>
- </row>
- <row>
- <cell align="left" valign="middle">dhpublicnumber</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-keyExchangeAlgorithm</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ecPublicKey</cell>
- </row>
- <tcaption>Public key algorithm oids </tcaption>
-</table>
-
-<code>
-#'Extension'{
- extnID, % id_extensions() | oid()
- critical, % boolean()
- extnValue % der_encoded()
- }.
-</code>
-
-<p><c>id_extensions()</c>
- <seealso marker="#StdCertExt">Standard Certificate Extensions</seealso>,
- <seealso marker="#PrivIntExt">Private Internet Extensions</seealso>,
- <seealso marker="#CRLCertExt">CRL Extensions</seealso> and
- <seealso marker="#CRLEntryExt">CRL Entry Extensions</seealso>.
-</p>
-
-</section>
-
-<section>
- <marker id="StdCertExt"></marker>
- <title>Standard certificate extensions</title>
-
- <table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- <cell align="left" valign="middle">Value type</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-authorityKeyIdentifier</cell>
- <cell align="left" valign="middle">#'AuthorityKeyIdentifier'{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-subjectKeyIdentifier</cell>
- <cell align="left" valign="middle">oid()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-keyUsage</cell>
- <cell align="left" valign="middle"> [key_usage()]</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-privateKeyUsagePeriod</cell>
- <cell align="left" valign="middle">#'PrivateKeyUsagePeriod'{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-certificatePolicies</cell>
- <cell align="left" valign="middle">#'PolicyInformation'{}</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-policyMappings</cell>
- <cell align="left" valign="middle">#'PolicyMappings_SEQOF'{}</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-subjectAltName</cell>
- <cell align="left" valign="middle">general_name()</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-issuerAltName</cell>
- <cell align="left" valign="middle">general_name()</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-subjectDirectoryAttributes</cell>
- <cell align="left" valign="middle"> [#'Attribute'{}]</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-basicConstraints</cell>
- <cell align="left" valign="middle">#'BasicConstraints'{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-nameConstraints</cell>
- <cell align="left" valign="middle">#'NameConstraints'{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-policyConstraints</cell>
- <cell align="left" valign="middle">#'PolicyConstraints'{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-extKeyUsage</cell>
- <cell align="left" valign="middle">[id_key_purpose()]</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-cRLDistributionPoints</cell>
- <cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-inhibitAnyPolicy</cell>
- <cell align="left" valign="middle">integer()</cell>
- </row>
-
- <row>
- <cell align="left" valign="middle">id-ce-freshestCRL</cell>
- <cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
- </row>
-
-
- <tcaption>Standard Certificate Extensions</tcaption>
- </table>
-
- <p><c>
- key_usage() = digitalSignature | nonRepudiation | keyEncipherment|
- dataEncipherment | keyAgreement | keyCertSign | cRLSign | encipherOnly |
- decipherOnly
- </c></p>
-
- <p><c> id_key_purpose()</c></p>
-
-<table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-kp-serverAuth</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-kp-clientAuth</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-kp-codeSigning</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-kp-emailProtection</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-kp-timeStamping</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-kp-OCSPSigning</cell>
- </row>
- <tcaption>Key purpose oids </tcaption>
-</table>
-
- <code>
-#'AuthorityKeyIdentifier'{
- keyIdentifier, % oid()
- authorityCertIssuer, % general_name()
- authorityCertSerialNumber % integer()
- }.
-
-#'PrivateKeyUsagePeriod'{
- notBefore, % general_time()
- notAfter % general_time()
- }.
-
-#'PolicyInformation'{
- policyIdentifier, % oid()
- policyQualifiers % [#PolicyQualifierInfo{}]
- }.
-
-#'PolicyQualifierInfo'{
- policyQualifierId, % oid()
- qualifier % string() | #'UserNotice'{}
- }.
-
-#'UserNotice'{
- noticeRef, % #'NoticeReference'{}
- explicitText % string()
- }.
-
-#'NoticeReference'{
- organization, % string()
- noticeNumbers % [integer()]
- }.
-
-#'PolicyMappings_SEQOF'{
- issuerDomainPolicy, % oid()
- subjectDomainPolicy % oid()
- }.
-
-#'Attribute'{
- type, % oid()
- values % [der_encoded()]
- }).
-
-#'BasicConstraints'{
- cA, % boolean()
- pathLenConstraint % integer()
- }).
-
-#'NameConstraints'{
- permittedSubtrees, % [#'GeneralSubtree'{}]
- excludedSubtrees % [#'GeneralSubtree'{}]
- }).
-
-#'GeneralSubtree'{
- base, % general_name()
- minimum, % integer()
- maximum % integer()
- }).
-
-#'PolicyConstraints'{
- requireExplicitPolicy, % integer()
- inhibitPolicyMapping % integer()
- }).
-
-#'DistributionPoint'{
- distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
- [#AttributeTypeAndValue{}]}
- reasons, % [dist_reason()]
- cRLIssuer % [general_name()]
- }).
-</code>
-
-</section>
-
- <section>
- <marker id="PrivIntExt"></marker>
- <title>Private Internet Extensions</title>
-
- <table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- <cell align="left" valign="middle">Value type</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-pe-authorityInfoAccess</cell>
- <cell align="left" valign="middle">[#'AccessDescription'{}]</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-pe-subjectInfoAccess</cell>
- <cell align="left" valign="middle">[#'AccessDescription'{}]</cell>
- </row>
- <tcaption>Private Internet Extensions</tcaption>
- </table>
-
-<code>
-#'AccessDescription'{
- accessMethod, % oid()
- accessLocation % general_name()
- }).
-</code>
-
- </section>
-
-<section>
- <title> CRL and CRL Extensions Profile</title>
-
- <code>
-#'CertificateList'{
- tbsCertList, % #'TBSCertList{}
- signatureAlgorithm, % #'AlgorithmIdentifier'{}
- signature % {0, binary()} - ASN1 compact bitstring
- }).
-
-#'TBSCertList'{
- version, % v2 (if defined)
- signature, % #AlgorithmIdentifier{}
- issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
- thisUpdate, % time()
- nextUpdate, % time()
- revokedCertificates, % [#'TBSCertList_revokedCertificates_SEQOF'{}]
- crlExtensions % [#'Extension'{}]
- }).
-
-#'TBSCertList_revokedCertificates_SEQOF'{
- userCertificate, % integer()
- revocationDate, % timer()
- crlEntryExtensions % [#'Extension'{}]
- }).
- </code>
-
- <section>
- <marker id="CRLCertExt"></marker>
- <title>CRL Extensions </title>
-
- <table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- <cell align="left" valign="middle">Value type</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-authorityKeyIdentifier</cell>
- <cell align="left" valign="middle">#'AuthorityKeyIdentifier{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-issuerAltName</cell>
- <cell align="left" valign="middle">{rdnSequence, [#AttributeTypeAndValue'{}]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-cRLNumber</cell>
- <cell align="left" valign="middle">integer()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-deltaCRLIndicator</cell>
- <cell align="left" valign="middle">integer()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-issuingDistributionPoint</cell>
- <cell align="left" valign="middle">#'IssuingDistributionPoint'{}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-freshestCRL</cell>
- <cell align="left" valign="middle">[#'Distributionpoint'{}]</cell>
- </row>
-
- <tcaption>CRL Extensions</tcaption>
- </table>
-
- <code>
-#'IssuingDistributionPoint'{
- distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
- [#AttributeTypeAndValue'{}]}
- onlyContainsUserCerts, % boolean()
- onlyContainsCACerts, % boolean()
- onlySomeReasons, % [dist_reason()]
- indirectCRL, % boolean()
- onlyContainsAttributeCerts % boolean()
- }).
- </code>
- </section>
-
- <section>
- <marker id="CRLEntryExt"></marker>
- <title> CRL Entry Extensions </title>
-
- <table>
- <row>
- <cell align="left" valign="middle">OID name</cell>
- <cell align="left" valign="middle">Value type</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-cRLReason</cell>
- <cell align="left" valign="middle">crl_reason()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-holdInstructionCode</cell>
- <cell align="left" valign="middle">oid()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-invalidityDate</cell>
- <cell align="left" valign="middle">general_time()</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id-ce-certificateIssuer</cell>
- <cell align="left" valign="middle">general_name()</cell>
- </row>
- <tcaption>CRL Entry Extensions</tcaption>
- </table>
- <p><c>
- crl_reason() = unspecified | keyCompromise | cACompromise |
- affiliationChanged | superseded | cessationOfOperation |
- certificateHold | removeFromCRL | privilegeWithdrawn |
- aACompromise
- </c></p>
- </section>
-
- <section>
- <marker id="PKCS10"></marker>
- <title>PKCS#10 Certification Request</title>
- <code>
-#'CertificationRequest'{
- certificationRequestInfo #'CertificationRequestInfo'{},
- signatureAlgorithm #'CertificationRequest_signatureAlgorithm'{}}.
- signature {0, binary()} - ASN1 compact bitstring
- }
-
-#'CertificationRequestInfo'{
- version atom(),
- subject {rdnSequence, [#AttributeTypeAndValue'{}]} ,
- subjectPKInfo #'CertificationRequestInfo_subjectPKInfo'{},
- attributes [#'AttributePKCS-10' {}]
- }
-
-#'CertificationRequestInfo_subjectPKInfo'{
- algorithm #'CertificationRequestInfo_subjectPKInfo_algorithm'{}
- subjectPublicKey {0, binary()} - ASN1 compact bitstring
- }
-
-#'CertificationRequestInfo_subjectPKInfo_algorithm'{
- algorithm = oid(),
- parameters = der_encoded()
-}
-
-#'CertificationRequest_signatureAlgorithm'{
- algorithm = oid(),
- parameters = der_encoded()
- }
-
-#'AttributePKCS-10'{
- type = oid(),
- values = [der_encoded()]
-}
- </code>
- </section>
-
-</section>
-</chapter>
diff --git a/lib/public_key/doc/src/introduction.xml b/lib/public_key/doc/src/introduction.xml
index bf11a092d8..7babe130d2 100644
--- a/lib/public_key/doc/src/introduction.xml
+++ b/lib/public_key/doc/src/introduction.xml
@@ -5,20 +5,21 @@
<header>
<copyright>
<year>2008</year>
- <year>2013</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -36,27 +37,28 @@
<section>
<title>Purpose</title>
- <p> public_key deals with public key related file formats, digital
- signatures and <url href="http://www.ietf.org/rfc/rfc5280.txt">
+ <p>The Public Key application deals with public-key related file
+ formats, digital signatures, and <url href="http://www.ietf.org/rfc/rfc5280.txt">
X-509 certificates</url>. It is a library application that
- provides encode/decode, sign/verify, encrypt/decrypt and similar
- functionality, it does not read or write files it expects or returns
+ provides encode/decode, sign/verify, encrypt/decrypt, and similar
+ functionality. It does not read or write files, it expects or returns
file contents or partial file contents as binaries.
</p>
</section>
<section>
<title>Prerequisites</title>
- <p>It is assumed that the reader has a basic understanding
- of the concepts of using public keys and digital certificates.</p>
+ <p>It is assumed that the reader is familiar with the Erlang programming
+ language and has a basic understanding of the concepts of using public-keys
+ and digital certificates.</p>
</section>
<section>
- <title>Performance tips</title>
- <p>The public_key decode and encode functions will try to use the NIFs
- which are in the ASN1 compilers runtime modules if they can be found.
- So for the best performance you want to have the ASN1 application in the
- path of your system. </p>
+ <title>Performance Tips</title>
+ <p>The Public Key decode- and encode-functions try to use the NIFs
+ in the ASN.1 compilers runtime modules, if they can be found.
+ Thus, to have the ASN1 application in the
+ path of your system gives the best performance.</p>
</section>
</chapter>
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index f241a91eb0..da8f62e2f8 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -34,6 +35,108 @@
<file>notes.xml</file>
</header>
+<section><title>Public_Key 1.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An encapsulated PEM header shall be followed by a blank
+ line</p>
+ <p>
+ Own Id: OTP-13381 Aux Id: seq13070 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Public_Key 1.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384' and
+ 'ecdsa-sha2-nistp521' signature algorithms for ssh are
+ implemented. See RFC 5656.</p>
+ <p>
+ Own Id: OTP-12936</p>
+ </item>
+ <item>
+ <p>
+ There is now a file (public_key/priv/moduli) which lists
+ size-generator-modulus triples. The purpose is to give
+ servers the possibility to select the crypto primes
+ randomly among a list of pregenerated triples. This
+ reduces the risk for some attacks on diffie-hellman
+ negotiation.</p>
+ <p>
+ See the reference manual for public_key:dh_gex_group/4
+ where the handling of this is described.</p>
+ <p>
+ The ssh server (ssh:daemon) uses this.</p>
+ <p>
+ Own Id: OTP-13054 Aux Id: OTP-13052 </p>
+ </item>
+ <item>
+ <p>
+ Add different upper bounds for diffrent string types as
+ suggested by comment in PKIX1Explicit88.</p>
+ <p>
+ Own Id: OTP-13132</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Public_Key 1.0.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Document enhancements</p>
+ <p>
+ Own Id: OTP-12986</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Public_Key 1.0</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ public_key: Remove legacy switch compact_bit_string</p>
+ <p>
+ E.i bitstrings will not be decode as {Unused, Binary},
+ they are now Erlang bitstrings.</p>
+ <p>
+ Also the compact_bit_string implies the
+ legacy_erlang_types switch So removing the switch will
+ also make OCTET STRING values be represented as binaries.</p>
+ <p>
+ Undecoded open type will now be wrapped in a
+ asn1_OPENTYPE tuple.</p>
+ <p>
+ This will change some values in records returned by the
+ public_key API making this change a potentiall
+ incompatibility.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12110</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Public_Key 0.23</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/public_key/doc/src/part.xml b/lib/public_key/doc/src/part.xml
index 73146c8e2a..8e5b3e9147 100644
--- a/lib/public_key/doc/src/part.xml
+++ b/lib/public_key/doc/src/part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -31,15 +32,14 @@
<file>part.xml</file>
</header>
<description>
- <p> This application provides an API to public key infrastructure
+ <p>This application provides an API to public-key infrastructure
from <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC
- 5280</url> (X.509 certificates) and public key formats defined by
+ 5280</url> (X.509 certificates) and public-key formats defined by
the <url href="http://en.wikipedia.org/wiki/PKCS">
- PKCS-standard</url></p>
+ PKCS</url> standard.</p>
</description>
<xi:include href="introduction.xml"/>
<xi:include href="public_key_records.xml"/>
- <xi:include href="cert_records.xml"/>
<xi:include href="using_public_key.xml"/>
</part>
diff --git a/lib/public_key/doc/src/part_notes.xml b/lib/public_key/doc/src/part_notes.xml
index 285f16f380..0665581474 100644
--- a/lib/public_key/doc/src/part_notes.xml
+++ b/lib/public_key/doc/src/part_notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index b86d0fe0ab..16a7497a22 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -31,11 +32,11 @@
<rev></rev>
</header>
<module>public_key</module>
- <modulesummary> API module for public key infrastructure.</modulesummary>
+ <modulesummary>API module for public-key infrastructure.</modulesummary>
<description>
- <p>This module provides functions to handle public key infrastructure. It can
- encode/decode different file formats (PEM, openssh), sign and verify digital signatures and validate
- certificate paths and certificate revocation lists.
+ <p>This module provides functions to handle public-key infrastructure. It can
+ encode/decode different file formats (PEM, OpenSSH), sign and verify digital signatures,
+ and validate certificate paths and certificate revocation lists.
</p>
</description>
@@ -43,94 +44,157 @@
<title>public_key</title>
<list type="bulleted">
- <item>public_key requires the crypto and asn1 applications, the latter since R16 (hopefully the runtime dependency on asn1 will
+ <item> Public Key requires the Crypto and ASN1 applications,
+ the latter as OTP R16 (hopefully the runtime dependency on ASN1 will
be removed again in the future).</item>
<item>Supports <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280 </url> -
- Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile </item>
- <item>Supports <url href="http://www.ietf.org/rfc/rfc3447.txt"> PKCS-1 </url> - RSA Cryptography Standard </item>
- <item>Supports <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> DSS</url>- Digital Signature Standard (DSA - Digital Signature Algorithm)</item>
- <item>Supports <url href="http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-3-diffie-hellman-key-agreement-standar.htm"> PKCS-3 </url> - Diffie-Hellman Key Agreement Standard </item>
- <item>Supports <url href="http://www.ietf.org/rfc/rfc2898.txt"> PKCS-5</url> - Password-Based Cryptography Standard </item>
- <item>Supports <url href="http://www.ietf.org/rfc/rfc5208.txt"> PKCS-8</url> - Private-Key Information Syntax Standard</item>
- <item>Supports <url href="http://www.ietf.org/rfc/rfc5967.txt"> PKCS-10</url> - Certification Request Syntax Standard</item>
+ Internet X.509 Public-Key Infrastructure Certificate and Certificate Revocation List
+ (CRL) Profile </item>
+ <item>Supports <url href="http://www.ietf.org/rfc/rfc3447.txt"> PKCS-1 </url> -
+ RSA Cryptography Standard </item>
+ <item>Supports <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> DSS</url> -
+ Digital Signature Standard (DSA - Digital Signature Algorithm)</item>
+ <item>Supports
+ <url href="http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-3-diffie-hellman-key-agreement-standar.htm"> PKCS-3 </url> -
+ Diffie-Hellman Key Agreement Standard </item>
+ <item>Supports <url href="http://www.ietf.org/rfc/rfc2898.txt"> PKCS-5</url> -
+ Password-Based Cryptography Standard </item>
+ <item>Supports <url href="http://www.ietf.org/rfc/rfc5208.txt"> PKCS-8</url> -
+ Private-Key Information Syntax Standard</item>
+ <item>Supports <url href="http://www.ietf.org/rfc/rfc5967.txt"> PKCS-10</url> -
+ Certification Request Syntax Standard</item>
</list>
</section>
<section>
- <title>COMMON DATA TYPES </title>
+ <title>DATA TYPES</title>
- <note><p>All records used in this manual
+ <note><p>All records used in this Reference Manual
<!-- except #policy_tree_node{} -->
are generated from ASN.1 specifications
and are documented in the User's Guide. See <seealso
- marker="public_key_records">Public key records</seealso> and <seealso
- marker="cert_records">X.509 Certificate records</seealso>.
+ marker="public_key_records">Public-key Records</seealso>.
</p></note>
<p>Use the following include directive to get access to the
- records and constant macros described here and in the User's Guide.</p>
+ records and constant macros described here and in the User's Guide:</p>
<code> -include_lib("public_key/include/public_key.hrl").</code>
- <p><em>Data Types </em></p>
-
- <p><code>oid() - Object Identifier, a tuple of integers as generated by the ASN1 compiler.</code></p>
-
- <p><code>boolean() = true | false</code></p>
+ <p>The following data types are used in the functions for <c>public_key</c>:</p>
- <p><code>string() = [bytes()]</code></p>
-
- <p><code>der_encoded() = binary()</code></p>
-
- <p><code>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey' |
- 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' |
- 'SubjectPublicKeyInfo' | 'PrivateKeyInfo' |
- 'CertificationRequest' | 'ECPrivateKey' | 'EcpkParameters'</code></p>
-
- <p><code>pem_entry () = {pki_asn1_type(), binary(), %% DER or encrypted DER
- not_encrypted | cipher_info()}</code></p>
+ <taglist>
+ <tag><c>oid()</c></tag>
+ <item><p>Object identifier, a tuple of integers as generated by the <c>ASN.1</c> compiler.</p></item>
- <p><code>cipher_info() = {"RC2-CBC | "DES-CBC" | "DES-EDE3-CBC",
- crypto:rand_bytes(8) | {#'PBEParameter{}, digest_type()} |#'PBES2-params'{}}</code></p>
-
- <p><code>public_key() = rsa_public_key() | dsa_public_key() | ec_public_key()</code></p>
- <p><code>private_key() = rsa_private_key() | dsa_private_key() | ec_private_key()</code></p>
- <p><code>rsa_public_key() = #'RSAPublicKey'{}</code></p>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+
+ <tag><c>string() =</c></tag>
+ <item><p><c>[bytes()]</c></p></item>
+
+ <tag><c>der_encoded() =</c></tag>
+ <item><p><c>binary()</c></p></item>
+
+ <tag><c>pki_asn1_type() =</c></tag>
+ <item>
+ <p><c>'Certificate'</c></p>
+ <p><c>| 'RSAPrivateKey'</c></p>
+ <p><c>| 'RSAPublicKey'</c></p>
+ <p><c>| 'DSAPrivateKey'</c></p>
+ <p><c>| 'DSAPublicKey'</c></p>
+ <p><c>| 'DHParameter'</c></p>
+ <p><c>| 'SubjectPublicKeyInfo'</c></p>
+ <p><c>| 'PrivateKeyInfo'</c></p>
+ <p><c>| 'CertificationRequest'</c></p>
+ <p><c>| 'CertificateList'</c></p>
+ <p><c>| 'ECPrivateKey'</c></p>
+ <p><c>| 'EcpkParameters'</c></p>
+ </item>
+
+ <tag><c>pem_entry () =</c></tag>
+ <item><p><c>{pki_asn1_type(), binary(), %% DER or encrypted DER</c></p>
+ <p><c> not_encrypted | cipher_info()}</c></p></item>
+
+ <tag><c>cipher_info() = </c></tag>
+ <item><p><c>{"RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)</c></p>
+ <p><c>| {#'PBEParameter{}, digest_type()} | #'PBES2-params'{}}</c></p>
+ </item>
+
+ <tag><c>public_key() =</c></tag>
+ <item><p><c>rsa_public_key() | dsa_public_key() | ec_public_key()</c></p></item>
+
+ <tag><c>private_key() =</c></tag>
+ <item><p><c>rsa_private_key() | dsa_private_key() | ec_private_key()</c></p></item>
- <p><code>rsa_private_key() = #'RSAPrivateKey'{}</code></p>
+ <tag><c>rsa_public_key() =</c></tag>
+ <item><p><c>#'RSAPublicKey'{}</c></p></item>
- <p><code>dsa_public_key() = {integer(), #'Dss-Parms'{}}</code></p>
+ <tag><c>rsa_private_key() =</c></tag>
+ <item><p><c>#'RSAPrivateKey'{}</c></p></item>
- <p><code>dsa_private_key() = #'DSAPrivateKey'{}</code></p>
+ <tag><c>dsa_public_key() =</c></tag>
+ <item><p><c>{integer(), #'Dss-Parms'{}}</c></p></item>
- <p><code>ec_public_key() = {#'ECPoint'{}, #'EcpkParameters'{} |
- {namedCurve, oid()}}</code></p>
-
- <p><code>ec_private_key() = #'ECPrivateKey'{}</code></p>
+ <tag><c>dsa_private_key() =</c></tag>
+ <item><p><c>#'DSAPrivateKey'{}</c></p></item>
- <p><code>public_crypt_options() = [{rsa_pad, rsa_padding()}].</code></p>
+ <tag><c>ec_public_key()</c></tag>
+ <item><p>= <c>{#'ECPoint'{}, #'EcpkParameters'{} | {namedCurve, oid()}}</c></p></item>
- <p><code>rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' |
- 'rsa_no_padding'</code></p>
+ <tag><c>ec_private_key() =</c></tag>
+ <item><p><c>#'ECPrivateKey'{}</c></p></item>
- <p><code>digest_type() - Union of below digest types</code></p>
-
- <p><code>rsa_digest_type() = 'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' |
- 'sha512'</code></p>
+ <tag><c>public_crypt_options() =</c></tag>
+ <item><p><c>[{rsa_pad, rsa_padding()}]</c></p></item>
- <p><code>dss_digest_type() = 'sha'</code></p>
+ <tag><c>rsa_padding() =</c></tag>
+ <item>
+ <p><c>'rsa_pkcs1_padding'</c></p>
+ <p><c>| 'rsa_pkcs1_oaep_padding'</c></p>
+ <p><c>| 'rsa_no_padding'</c></p>
+ </item>
- <p><code>ecdsa_digest_type() = 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'</code></p>
+ <tag><c>digest_type() = </c></tag>
+ <item><p>Union of <c>rsa_digest_type()</c>, <c>dss_digest_type()</c>,
+ and <c>ecdsa_digest_type()</c>.</p></item>
- <p><code>crl_reason() = unspecified | keyCompromise | cACompromise |
- affiliationChanged | superseded | cessationOfOperation |
- certificateHold | privilegeWithdrawn | aACompromise</code></p>
+ <tag><c>rsa_digest_type() = </c></tag>
+ <item><p><c>'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'</c></p></item>
- <p><code>issuer_name() = {rdnSequence,[#'AttributeTypeAndValue'{}]} </code> </p>
+ <tag><c>dss_digest_type() = </c></tag>
+ <item><p><c>'sha'</c></p></item>
- <p><code>ssh_file() = openssh_public_key | rfc4716_public_key | known_hosts |
- auth_keys</code></p>
+ <tag><c>ecdsa_digest_type() = </c></tag>
+ <item><p><c>'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'</c></p></item>
+
+ <tag><c>crl_reason() = </c></tag>
+ <item>
+ <p><c>unspecified</c></p>
+ <p><c>| keyCompromise</c></p>
+ <p><c>| cACompromise</c></p>
+ <p><c>| affiliationChanged</c></p>
+ <p><c>| superseded</c></p>
+ <p><c>| cessationOfOperation</c></p>
+ <p><c>| certificateHold</c></p>
+ <p><c>| privilegeWithdrawn</c></p>
+ <p><c>| aACompromise</c></p>
+ </item>
+
+ <tag><c>issuer_name() =</c></tag>
+ <item><p><c>{rdnSequence,[#'AttributeTypeAndValue'{}]}</c></p>
+ </item>
+
+ <tag><c>ssh_file() =</c></tag>
+ <item>
+ <p><c>openssh_public_key</c></p>
+ <p><c>| rfc4716_public_key</c></p>
+ <p><c>| known_hosts</c></p>
+ <p><c>| auth_keys</c></p>
+ </item>
+ </taglist>
+
<!-- <p><code>policy_tree() = [Root, Children]</code></p> -->
@@ -138,12 +202,12 @@
<!-- <p><code>Children = [] | policy_tree()</code></p> -->
-<!-- <p> The policy_tree_node record has the following fields:</p> -->
+<!-- <p>The <c>policy_tree_node</c> record has the following fields:</p> -->
<!-- <taglist> -->
<!-- <tag>valid_policy</tag> -->
-<!-- <item> Is a single policy OID representing a -->
+<!-- <item>A single policy OID representing a -->
<!-- valid policy for the path of length x.</item> -->
<!-- <tag>qualifier_set</tag> -->
@@ -151,13 +215,13 @@
<!-- with the valid policy in certificate x.</item> -->
<!-- <tag>critically_indicator</tag> -->
-<!-- <item>The critically_indicator indicates whether the -->
+<!-- <item>Indicates whether the -->
<!-- certificate policy extension in certificate x was marked as -->
-<!-- critical. </item> -->
+<!-- critical.</item> -->
<!-- <tag>expected_policy_set</tag> -->
-<!-- <item>The expected_policy_set contains one or more policy OIDs -->
-<!-- that would satisfy this policy in the certificate x+1. </item> -->
+<!-- <item>Contains one or more policy OIDs -->
+<!-- that would satisfy this policy in the certificate x+1.</item> -->
<!-- </taglist> -->
</section>
@@ -166,27 +230,27 @@
<func>
<name>compute_key(OthersKey, MyKey)-></name>
<name>compute_key(OthersKey, MyKey, Params)-></name>
- <fsummary> Compute shared secret</fsummary>
+ <fsummary>Computes shared secret.</fsummary>
<type>
<v>OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary()</v>
<v>Params = #'DHParameter'{}</v>
</type>
<desc>
- <p> Compute shared secret </p>
+ <p>Computes shared secret.</p>
</desc>
</func>
<func>
<name>decrypt_private(CipherText, Key) -> binary()</name>
<name>decrypt_private(CipherText, Key, Options) -> binary()</name>
- <fsummary>Public key decryption.</fsummary>
+ <fsummary>Public-key decryption.</fsummary>
<type>
<v>CipherText = binary()</v>
<v>Key = rsa_private_key()</v>
<v>Options = public_crypt_options()</v>
</type>
<desc>
- <p>Public key decryption using the private key. See also <seealso
+ <p>Public-key decryption using the private key. See also <seealso
marker="crypto:crypto#private_decrypt/4">crypto:private_decrypt/4</seealso></p>
</desc>
</func>
@@ -194,156 +258,187 @@
<func>
<name>decrypt_public(CipherText, Key) - > binary()</name>
<name>decrypt_public(CipherText, Key, Options) - > binary()</name>
- <fsummary></fsummary>
+ <fsummary>Public-key decryption.</fsummary>
<type>
<v>CipherText = binary()</v>
<v>Key = rsa_public_key()</v>
<v>Options = public_crypt_options()</v>
</type>
<desc>
- <p> Public key decryption using the public key. See also <seealso
+ <p>Public-key decryption using the public key. See also <seealso
marker="crypto:crypto#public_decrypt/4">crypto:public_decrypt/4</seealso></p>
</desc>
</func>
<func>
<name>der_decode(Asn1type, Der) -> term()</name>
- <fsummary> Decodes a public key ASN.1 DER encoded entity.</fsummary>
+ <fsummary>Decodes a public-key ASN.1 DER encoded entity.</fsummary>
<type>
<v>Asn1Type = atom()</v>
- <d> ASN.1 type present in the public_key applications
- asn1 specifications.</d>
+ <d>ASN.1 type present in the Public Key applications
+ ASN.1 specifications.</d>
<v>Der = der_encoded()</v>
</type>
<desc>
- <p> Decodes a public key ASN.1 DER encoded entity.</p>
+ <p>Decodes a public-key ASN.1 DER encoded entity.</p>
</desc>
</func>
<func>
<name>der_encode(Asn1Type, Entity) -> der_encoded()</name>
- <fsummary> Encodes a public key entity with asn1 DER encoding.</fsummary>
+ <fsummary>Encodes a public-key entity with ASN.1 DER encoding.</fsummary>
<type>
<v>Asn1Type = atom()</v>
- <d> Asn1 type present in the public_key applications
+ <d>ASN.1 type present in the Public Key applications
ASN.1 specifications.</d>
<v>Entity = term()</v>
- <d>The erlang representation of <c>Asn1Type</c></d>
+ <d>Erlang representation of <c>Asn1Type</c></d>
</type>
<desc>
- <p> Encodes a public key entity with ASN.1 DER encoding.</p>
+ <p>Encodes a public-key entity with ASN.1 DER encoding.</p>
</desc>
</func>
<func>
+ <name>dh_gex_group(MinSize, SuggestedSize, MaxSize, Groups) -> {ok, {Size,Group}} | {error,Error}</name>
+ <fsummary>Selects a group for Diffie-Hellman key exchange</fsummary>
+ <type>
+ <v>MinSize = positive_integer()</v>
+ <v>SuggestedSize = positive_integer()</v>
+ <v>MaxSize = positive_integer()</v>
+ <v>Groups = undefined | [{Size,[{G,P}]}]</v>
+ <v>Size = positive_integer()</v>
+ <v>Group = {G,P}</v>
+ <v>G = positive_integer()</v>
+ <v>P = positive_integer()</v>
+ </type>
+ <desc>
+ <p>Selects a group for Diffie-Hellman key exchange with the key size in the range <c>MinSize...MaxSize</c>
+ and as close to <c>SuggestedSize</c> as possible. If <c>Groups == undefined</c> a default set will be
+ used, otherwise the group is selected from <c>Groups</c>.</p>
+ <p>First a size, as close as possible to SuggestedSize, is selected. Then one group with that key size
+ is randomly selected from the specified set of groups. If no size within the limits of <c>MinSize</c>
+ and <c>MaxSize</c> is available, <c>{error,no_group_found}</c> is returned.</p>
+ <p>The default set of groups is listed in <c>lib/public_key/priv/moduli</c>. This file may be regenerated like this:</p>
+ <pre>
+ $> cd $ERL_TOP/lib/public_key/priv/
+ $> generate
+ ---- wait until all background jobs has finished. It may take several days !
+ $> cat moduli-* > moduli
+ $> cd ..; make
+ </pre>
+ </desc>
+ </func>
+
+ <func>
+ <name>encrypt_private(PlainText, Key) -> binary()</name>
+ <fsummary>Public-key encryption using the private key.</fsummary>
+ <type>
+ <v>PlainText = binary()</v>
+ <v>Key = rsa_private_key()</v>
+ </type>
+ <desc>
+ <p>Public-key encryption using the private key.
+ See also <seealso
+ marker="crypto:crypto#private_encrypt/4">crypto:private_encrypt/4</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>encrypt_public(PlainText, Key) -> binary()</name>
+ <fsummary>Public-key encryption using the public key.</fsummary>
+ <type>
+ <v>PlainText = binary()</v>
+ <v>Key = rsa_public_key()</v>
+ </type>
+ <desc>
+ <p>Public-key encryption using the public key. See also <seealso
+ marker="crypto:crypto#public_encrypt/4">crypto:public_encrypt/4</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
<name>generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} </name>
- <fsummary>Generates a new keypair</fsummary>
+ <fsummary>Generates a new keypair.</fsummary>
<type>
- <v> Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} </v>
+ <v>Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}</v>
</type>
<desc>
- <p>Generates a new keypair</p>
+ <p>Generates a new keypair.</p>
</desc>
</func>
<func>
<name>pem_decode(PemBin) -> [pem_entry()]</name>
- <fsummary>Decode PEM binary data and return
- entries as ASN.1 DER encoded entities. </fsummary>
+ <fsummary>Decodes PEM binary data and returns
+ entries as ASN.1 DER encoded entities.</fsummary>
<type>
<v>PemBin = binary()</v>
<d>Example {ok, PemBin} = file:read_file("cert.pem").</d>
</type>
<desc>
- <p>Decode PEM binary data and return
+ <p>Decodes PEM binary data and returns
entries as ASN.1 DER encoded entities.</p>
</desc>
</func>
<func>
<name>pem_encode(PemEntries) -> binary()</name>
- <fsummary>Creates a PEM binary</fsummary>
+ <fsummary>Creates a PEM binary.</fsummary>
<type>
<v> PemEntries = [pem_entry()] </v>
</type>
<desc>
- <p>Creates a PEM binary</p>
+ <p>Creates a PEM binary.</p>
</desc>
</func>
<func>
<name>pem_entry_decode(PemEntry) -> term()</name>
<name>pem_entry_decode(PemEntry, Password) -> term()</name>
- <fsummary>Decodes a pem entry.</fsummary>
+ <fsummary>Decodes a PEM entry.</fsummary>
<type>
- <v> PemEntry = pem_entry() </v>
- <v> Password = string() </v>
+ <v>PemEntry = pem_entry()</v>
+ <v>Password = string()</v>
</type>
<desc>
- <p>Decodes a PEM entry. pem_decode/1 returns a list of PEM
- entries. Note that if the PEM entry is of type
- 'SubjectPublickeyInfo' it will be further decoded to an
- rsa_public_key() or dsa_public_key().</p>
+ <p>Decodes a PEM entry. <c>pem_decode/1</c> returns a list of PEM
+ entries. Notice that if the PEM entry is of type
+ 'SubjectPublickeyInfo', it is further decoded to an
+ <c>rsa_public_key()</c> or <c>dsa_public_key()</c>.</p>
</desc>
</func>
<func>
<name>pem_entry_encode(Asn1Type, Entity) -> pem_entry()</name>
<name>pem_entry_encode(Asn1Type, Entity, {CipherInfo, Password}) -> pem_entry()</name>
- <fsummary> Creates a PEM entry that can be fed to pem_encode/1.</fsummary>
+ <fsummary>Creates a PEM entry that can be fed to <c>pem_encode/1</c>.</fsummary>
<type>
<v>Asn1Type = pki_asn1_type()</v>
<v>Entity = term()</v>
- <d>The Erlang representation of
- <c>Asn1Type</c>. If <c>Asn1Type</c> is 'SubjectPublicKeyInfo'
- then <c>Entity</c> must be either an rsa_public_key() or a
- dsa_public_key() and this function will create the appropriate
+ <d>Erlang representation of
+ <c>Asn1Type</c>. If <c>Asn1Type</c> is 'SubjectPublicKeyInfo',
+ <c>Entity</c> must be either an <c>rsa_public_key()</c> or a
+ <c>dsa_public_key()</c> and this function creates the appropriate
'SubjectPublicKeyInfo' entry.
</d>
<v>CipherInfo = cipher_info()</v>
<v>Password = string()</v>
</type>
<desc>
- <p> Creates a PEM entry that can be feed to pem_encode/1.</p>
+ <p>Creates a PEM entry that can be feed to <c>pem_encode/1</c>.</p>
</desc>
</func>
-
- <func>
- <name>encrypt_private(PlainText, Key) -> binary()</name>
- <fsummary> Public key encryption using the private key.</fsummary>
- <type>
- <v>PlainText = binary()</v>
- <v>Key = rsa_private_key()</v>
- </type>
- <desc>
- <p> Public key encryption using the private key.
- See also <seealso
- marker="crypto:crypto#private_encrypt/4">crypto:private_encrypt/4</seealso></p>
- </desc>
- </func>
-
- <func>
- <name>encrypt_public(PlainText, Key) -> binary()</name>
- <fsummary> Public key encryption using the public key.</fsummary>
- <type>
- <v>PlainText = binary()</v>
- <v>Key = rsa_public_key()</v>
- </type>
- <desc>
- <p> Public key encryption using the public key. See also <seealso
- marker="crypto:crypto#public_encrypt/4">crypto:public_encrypt/4</seealso></p>
- </desc>
- </func>
<func>
<name>pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{}</name>
- <fsummary> Decodes an ASN.1 DER encoded PKIX x509 certificate.</fsummary>
+ <fsummary>Decodes an ASN.1 DER-encoded PKIX x509 certificate.</fsummary>
<type>
<v>Cert = der_encoded()</v>
</type>
<desc>
- <p>Decodes an ASN.1 DER encoded PKIX certificate. The otp option
- will use the customized ASN.1 specification OTP-PKIX.asn1 for
+ <p>Decodes an ASN.1 DER-encoded PKIX certificate. Option <c>otp</c>
+ uses the customized ASN.1 specification OTP-PKIX.asn1 for
decoding and also recursively decode most of the standard
parts.</p>
</desc>
@@ -355,54 +450,54 @@
certificate.</fsummary>
<type>
<v>Asn1Type = atom()</v>
- <d>The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either .</d>
+ <d>The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either.</d>
<v>Entity = #'Certificate'{} | #'OTPCertificate'{} | a valid subtype</v>
</type>
<desc>
<p>DER encodes a PKIX x509 certificate or part of such a
certificate. This function must be used for encoding certificates or parts of certificates
- that are decoded/created in the otp format, whereas for the plain format this
- function will directly call der_encode/2. </p>
+ that are decoded/created in the <c>otp</c> format, whereas for the plain format this
+ function directly calls <c>der_encode/2</c>.</p>
</desc>
</func>
<func>
<name>pkix_is_issuer(Cert, IssuerCert) -> boolean()</name>
- <fsummary> Checks if <c>IssuerCert</c> issued <c>Cert</c> </fsummary>
+ <fsummary>Checks if <c>IssuerCert</c> issued <c>Cert</c>.</fsummary>
<type>
- <v>Cert = der_encoded() | #'OTPCertificate'{}</v>
+ <v>Cert = der_encoded() | #'OTPCertificate'{} | #'CertificateList'{}</v>
<v>IssuerCert = der_encoded() | #'OTPCertificate'{}</v>
</type>
<desc>
- <p> Checks if <c>IssuerCert</c> issued <c>Cert</c> </p>
+ <p>Checks if <c>IssuerCert</c> issued <c>Cert</c>.</p>
</desc>
</func>
<func>
<name>pkix_is_fixed_dh_cert(Cert) -> boolean()</name>
- <fsummary> Checks if a Certificate is a fixed Diffie-Hellman Cert.</fsummary>
+ <fsummary>Checks if a certificate is a fixed Diffie-Hellman certificate.</fsummary>
<type>
<v>Cert = der_encoded() | #'OTPCertificate'{}</v>
</type>
<desc>
- <p> Checks if a Certificate is a fixed Diffie-Hellman Cert.</p>
+ <p>Checks if a certificate is a fixed Diffie-Hellman certificate.</p>
</desc>
</func>
<func>
<name>pkix_is_self_signed(Cert) -> boolean()</name>
- <fsummary> Checks if a Certificate is self signed.</fsummary>
+ <fsummary>Checks if a certificate is self-signed.</fsummary>
<type>
<v>Cert = der_encoded() | #'OTPCertificate'{}</v>
</type>
<desc>
- <p> Checks if a Certificate is self signed.</p>
+ <p>Checks if a certificate is self-signed.</p>
</desc>
</func>
<func>
<name>pkix_issuer_id(Cert, IssuedBy) -> {ok, IssuerID} | {error, Reason}</name>
- <fsummary> Returns the issuer id.</fsummary>
+ <fsummary>Returns the issuer id.</fsummary>
<type>
<v>Cert = der_encoded() | #'OTPCertificate'{}</v>
<v>IssuedBy = self | other</v>
@@ -411,43 +506,43 @@
<v>Reason = term()</v>
</type>
<desc>
- <p> Returns the issuer id.</p>
+ <p>Returns the issuer id.</p>
</desc>
</func>
<func>
<name>pkix_normalize_name(Issuer) -> Normalized</name>
- <fsummary>Normalizes a issuer name so that it can be easily
- compared to another issuer name. </fsummary>
+ <fsummary>Normalizes an issuer name so that it can be easily
+ compared to another issuer name.</fsummary>
<type>
<v>Issuer = issuer_name()</v>
<v>Normalized = issuer_name()</v>
</type>
<desc>
- <p>Normalizes a issuer name so that it can be easily
+ <p>Normalizes an issuer name so that it can be easily
compared to another issuer name.</p>
</desc>
</func>
<func>
<name>pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, {PublicKeyInfo, PolicyTree}} | {error, {bad_cert, Reason}} </name>
- <fsummary> Performs a basic path validation according to RFC 5280.</fsummary>
+ <fsummary>Performs a basic path validation according to RFC 5280.</fsummary>
<type>
- <v> TrustedCert = #'OTPCertificate'{} | der_encoded() | atom() </v>
- <d>Normally a trusted certificate but it can also be a path validation
+ <v>TrustedCert = #'OTPCertificate'{} | der_encoded() | atom()</v>
+ <d>Normally a trusted certificate, but it can also be a path-validation
error that can be discovered while
- constructing the input to this function and that should be run through the <c>verify_fun</c>.
- For example <c>unknown_ca </c> or <c>selfsigned_peer </c>
+ constructing the input to this function and that is to be run through the <c>verify_fun</c>.
+ Examples are <c>unknown_ca</c> and <c>selfsigned_peer.</c>
</d>
- <v> CertChain = [der_encoded()]</v>
- <d>A list of DER encoded certificates in trust order ending with the peer certificate.</d>
- <v> Options = proplists:proplist()</v>
+ <v>CertChain = [der_encoded()]</v>
+ <d>A list of DER-encoded certificates in trust order ending with the peer certificate.</d>
+ <v>Options = proplists:proplist()</v>
<v>PublicKeyInfo = {?'rsaEncryption' | ?'id-dsa',
rsa_public_key() | integer(), 'NULL' | 'Dss-Parms'{}}</v>
- <v> PolicyTree = term() </v>
- <d>At the moment this will always be an empty list as Policies are not currently supported</d>
- <v> Reason = cert_expired | invalid_issuer | invalid_signature | name_not_permitted |
+ <v>PolicyTree = term()</v>
+ <d>At the moment this is always an empty list as policies are not currently supported.</d>
+ <v>Reason = cert_expired | invalid_issuer | invalid_signature | name_not_permitted |
missing_basic_constraint | invalid_key_usage | {revoked, crl_reason()} | atom()
</v>
</type>
@@ -455,17 +550,17 @@
<p>
Performs a basic path validation according to
<url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280.</url>
- However CRL validation is done separately by <seealso
- marker="#pkix_crls_validate-3">pkix_crls_validate/3 </seealso> and should be called
- from the supplied <c>verify_fun</c>
+ However, CRL validation is done separately by <seealso
+ marker="#pkix_crls_validate-3">pkix_crls_validate/3 </seealso> and is to be called
+ from the supplied <c>verify_fun</c>.
</p>
- <taglist>
- <p> Available options are: </p>
+ <p>Available options:</p>
+ <taglist>
<tag>{verify_fun, fun()}</tag>
<item>
- <p>The fun should be defined as:</p>
+ <p>The fun must be defined as:</p>
<code>
fun(OtpCert :: #'OTPCertificate'{},
@@ -478,53 +573,53 @@ fun(OtpCert :: #'OTPCertificate'{},
{unknown, UserState :: term()}.
</code>
- <p>If the verify callback fun returns {fail, Reason}, the
+ <p>If the verify callback fun returns <c>{fail, Reason}</c>, the
verification process is immediately stopped. If the verify
- callback fun returns {valid, UserState}, the verification
- process is continued, this can be used to accept specific path
- validation errors such as <c>selfsigned_peer</c> as well as
- verifying application specific extensions. If called with an
- extension unknown to the user application the return value
- {unknown, UserState} should be used.</p>
+ callback fun returns <c>{valid, UserState}</c>, the verification
+ process is continued. This can be used to accept specific path
+ validation errors, such as <c>selfsigned_peer</c>, as well as
+ verifying application-specific extensions. If called with an
+ extension unknown to the user application, the return value
+ <c>{unknown, UserState}</c> is to be used.</p>
</item>
<tag>{max_path_length, integer()}</tag>
<item>
The <c>max_path_length</c> is the maximum number of non-self-issued
- intermediate certificates that may follow the peer certificate
- in a valid certification path. So if <c>max_path_length</c> is 0 the PEER must
- be signed by the trusted ROOT-CA directly, if 1 the path can
- be PEER, CA, ROOT-CA, if it is 2 PEER, CA, CA, ROOT-CA and so
- on.
+ intermediate certificates that can follow the peer certificate
+ in a valid certification path. So, if <c>max_path_length</c> is 0, the PEER must
+ be signed by the trusted ROOT-CA directly, if it is 1, the path can
+ be PEER, CA, ROOT-CA, if it is 2, the path can
+ be PEER, CA, CA, ROOT-CA, and so on.
</item>
</taglist>
- <p> Possible reasons for a bad certificate are: </p>
+ <p>Possible reasons for a bad certificate: </p>
<taglist>
<tag>cert_expired</tag>
- <item>The certificate is no longer valid as its expiration date has passed.</item>
+ <item><p>Certificate is no longer valid as its expiration date has passed.</p></item>
<tag>invalid_issuer</tag>
- <item>The certificate issuer name does not match the name of the issuer certificate in the chain.</item>
+ <item><p>Certificate issuer name does not match the name of the issuer certificate in the chain.</p></item>
<tag>invalid_signature</tag>
- <item>The certificate was not signed by its issuer certificate in the chain.</item>
+ <item><p>Certificate was not signed by its issuer certificate in the chain.</p></item>
<tag>name_not_permitted</tag>
- <item>Invalid Subject Alternative Name extension.</item>
+ <item><p>Invalid Subject Alternative Name extension.</p></item>
<tag>missing_basic_constraint</tag>
- <item>Certificate, required to have the basic constraints extension, does not have
- a basic constraints extension.</item>
+ <item><p>Certificate, required to have the basic constraints extension, does not have
+ a basic constraints extension.</p></item>
<tag>invalid_key_usage</tag>
- <item>Certificate key is used in an invalid way according to the key usage extension.</item>
+ <item><p>Certificate key is used in an invalid way according to the key-usage extension.</p></item>
<tag>{revoked, crl_reason()}</tag>
- <item>Certificate has been revoked.</item>
+ <item><p>Certificate has been revoked.</p></item>
<tag>atom()</tag>
- <item>Application specific error reason that should be checked by the verify_fun</item>
+ <item><p>Application-specific error reason that is to be checked by the <c>verify_fun</c>.</p></item>
</taglist>
</desc>
@@ -543,44 +638,47 @@ fun(OtpCert :: #'OTPCertificate'{},
<func>
<name>pkix_crls_validate(OTPCertificate, DPAndCRLs, Options) -> CRLStatus()</name>
- <fsummary> Performs CRL validation.</fsummary>
+ <fsummary>Performs CRL validation.</fsummary>
<type>
- <v> OTPCertificate = #'OTPCertificate'{}</v>
- <v> DPAndCRLs = [{DP::#'DistributionPoint'{}, {DerCRL::der_encoded(), CRL::#'CertificateList'{}}}] </v>
- <v> Options = proplists:proplist()</v>
- <v> CRLStatus() = valid | {bad_cert, revocation_status_undetermined} |
+ <v>OTPCertificate = #'OTPCertificate'{}</v>
+ <v>DPAndCRLs = [{DP::#'DistributionPoint'{}, {DerCRL::der_encoded(), CRL::#'CertificateList'{}}}] </v>
+ <v>Options = proplists:proplist()</v>
+ <v>CRLStatus() = valid | {bad_cert, revocation_status_undetermined} |
{bad_cert, {revoked, crl_reason()}}</v>
</type>
<desc>
- <p> Performs CRL validation. It is intended to be called from
+ <p>Performs CRL validation. It is intended to be called from
the verify fun of <seealso marker="#pkix_path_validation-3"> pkix_path_validation/3
- </seealso></p>
+ </seealso>.</p>
+
+ <p>Available options:</p>
+
<taglist>
- <p> Available options are: </p>
+
<tag>{update_crl, fun()}</tag>
<item>
- <p>The fun has the following type spec:</p>
+ <p>The fun has the following type specification:</p>
<code> fun(#'DistributionPoint'{}, #'CertificateList'{}) ->
#'CertificateList'{}</code>
- <p>The fun should use the information in the distribution point to acesses
- the lates possible version of the CRL. If this fun is not specified
- public_key will use the default implementation:
+ <p>The fun uses the information in the distribution point to access
+ the latest possible version of the CRL. If this fun is not specified,
+ Public Key uses the default implementation:
</p>
<code> fun(_DP, CRL) -> CRL end</code>
</item>
<tag>{issuer_fun, fun()}</tag>
<item>
- <p>The fun has the following type spec:</p>
+ <p>The fun has the following type specification:</p>
<code>
fun(#'DistributionPoint'{}, #'CertificateList'{},
{rdnSequence,[#'AttributeTypeAndValue'{}]}, term()) ->
{ok, #'OTPCertificate'{}, [der_encoded]}</code>
- <p>The fun should return the root certificate and certificate chain
+ <p>The fun returns the root certificate and certificate chain
that has signed the CRL.
</p>
<code> fun(DP, CRL, Issuer, UserState) -> {ok, RootCert, CertChain}</code>
@@ -632,86 +730,86 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
<name>pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encoded()</name>
<fsummary>Signs certificate.</fsummary>
<type>
- <v>Key = rsa_public_key() | dsa_public_key()</v>
+ <v>Key = rsa_private_key() | dsa_private_key()</v>
</type>
<desc>
- <p>Signs a 'OTPTBSCertificate'. Returns the corresponding
- der encoded certificate.</p>
+ <p>Signs an 'OTPTBSCertificate'. Returns the corresponding
+ DER-encoded certificate.</p>
</desc>
</func>
<func>
<name>pkix_sign_types(AlgorithmId) -> {DigestType, SignatureType}</name>
- <fsummary>Translates signature algorithm oid to erlang digest and signature algorithm types.</fsummary>
+ <fsummary>Translates signature algorithm OID to Erlang digest and signature algorithm types.</fsummary>
<type>
<v>AlgorithmId = oid()</v>
- <d>Signature oid from a certificate or a certificate revocation list</d>
- <v>DigestType = rsa_digest_type() | dss_digest_type() </v>
- <v>SignatureType = rsa | dsa</v>
+ <d>Signature OID from a certificate or a certificate revocation list.</d>
+ <v>DigestType = rsa_digest_type() | dss_digest_type()</v>
+ <v>SignatureType = rsa | dsa | ecdsa</v>
</type>
<desc>
- <p>Translates signature algorithm oid to erlang digest and signature types.
+ <p>Translates signature algorithm OID to Erlang digest and signature types.
</p>
</desc>
</func>
<func>
<name>pkix_verify(Cert, Key) -> boolean()</name>
- <fsummary> Verify pkix x.509 certificate signature.</fsummary>
+ <fsummary>Verifies PKIX x.509 certificate signature.</fsummary>
<type>
<v>Cert = der_encoded()</v>
- <v>Key = rsa_public_key() | dsa_public_key()</v>
+ <v>Key = rsa_public_key() | dsa_public_key() | ec_public_key()</v>
</type>
<desc>
- <p> Verify PKIX x.509 certificate signature.</p>
+ <p>Verifies PKIX x.509 certificate signature.</p>
</desc>
</func>
<func>
<name>sign(Msg, DigestType, Key) -> binary()</name>
- <fsummary> Create digital signature.</fsummary>
+ <fsummary>Creates a digital signature.</fsummary>
<type>
<v>Msg = binary() | {digest,binary()}</v>
- <d>The msg is either the binary "plain text" data to be
- signed or it is the hashed value of "plain text" i.e. the
+ <d>The <c>Msg</c> is either the binary "plain text" data to be
+ signed or it is the hashed value of "plain text", that is, the
digest.</d>
<v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v>
<v>Key = rsa_private_key() | dsa_private_key() | ec_private_key()</v>
</type>
<desc>
- <p> Creates a digital signature.</p>
+ <p>Creates a digital signature.</p>
</desc>
</func>
<func>
<name>ssh_decode(SshBin, Type) -> [{public_key(), Attributes::list()}]</name>
- <fsummary>Decodes a ssh file-binary. </fsummary>
+ <fsummary>Decodes an SSH file-binary.</fsummary>
<type>
<v>SshBin = binary()</v>
- <d>Example {ok, SshBin} = file:read_file("known_hosts").</d>
- <v> Type = public_key | ssh_file()</v>
- <d>If <c>Type</c> is <c>public_key</c> the binary may be either
- a rfc4716 public key or a openssh public key.</d>
+ <d>Example <c>{ok, SshBin} = file:read_file("known_hosts")</c>.</d>
+ <v>Type = public_key | ssh_file()</v>
+ <d>If <c>Type</c> is <c>public_key</c> the binary can be either
+ an RFC4716 public key or an OpenSSH public key.</d>
</type>
<desc>
- <p> Decodes a ssh file-binary. In the case of know_hosts or
- auth_keys the binary may include one or more lines of the
+ <p>Decodes an SSH file-binary. In the case of <c>known_hosts</c> or
+ <c>auth_keys</c>, the binary can include one or more lines of the
file. Returns a list of public keys and their attributes, possible
attribute values depends on the file type represented by the
binary.
</p>
<taglist>
- <tag>rfc4716 attributes - see RFC 4716</tag>
- <item>{headers, [{string(), utf8_string()}]}</item>
- <tag>auth_key attributes - see man sshd </tag>
+ <tag>RFC4716 attributes - see RFC 4716.</tag>
+ <item><p>{headers, [{string(), utf8_string()}]}</p></item>
+ <tag>auth_key attributes - see manual page for sshd.</tag>
<item>{comment, string()}</item>
<item>{options, [string()]}</item>
- <item>{bits, integer()} - In ssh version 1 files</item>
- <tag>known_host attributes - see man sshd</tag>
+ <item><p>{bits, integer()} - In SSH version 1 files.</p></item>
+ <tag>known_host attributes - see manual page for sshd.</tag>
<item>{hostnames, [string()]}</item>
<item>{comment, string()}</item>
- <item>{bits, integer()} - In ssh version 1 files</item>
+ <item><p>{bits, integer()} - In SSH version 1 files.</p></item>
</taglist>
</desc>
@@ -719,16 +817,16 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
<func>
<name>ssh_encode([{Key, Attributes}], Type) -> binary()</name>
- <fsummary> Encodes a list of ssh file entries to a binary.</fsummary>
+ <fsummary>Encodes a list of SSH file entries to a binary.</fsummary>
<type>
<v>Key = public_key()</v>
<v>Attributes = list()</v>
<v>Type = ssh_file()</v>
</type>
<desc>
- <p>Encodes a list of ssh file entries (public keys and attributes) to a binary. Possible
- attributes depends on the file type, see <seealso
- marker="#ssh_decode-2"> ssh_decode/2 </seealso></p>
+ <p>Encodes a list of SSH file entries (public keys and attributes) to a binary. Possible
+ attributes depend on the file type, see <seealso
+ marker="#ssh_decode-2"> ssh_decode/2 </seealso>.</p>
</desc>
</func>
@@ -737,14 +835,14 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
<fsummary>Verifies a digital signature.</fsummary>
<type>
<v>Msg = binary() | {digest,binary()}</v>
- <d>The msg is either the binary "plain text" data
- or it is the hashed value of "plain text" i.e. the digest.</d>
+ <d>The <c>Msg</c> is either the binary "plain text" data
+ or it is the hashed value of "plain text", that is, the digest.</d>
<v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v>
<v>Signature = binary()</v>
<v>Key = rsa_public_key() | dsa_public_key() | ec_public_key()</v>
</type>
<desc>
- <p>Verifies a digital signature</p>
+ <p>Verifies a digital signature.</p>
</desc>
</func>
diff --git a/lib/public_key/doc/src/public_key_records.xml b/lib/public_key/doc/src/public_key_records.xml
index d3534846fa..d34f3ed9a3 100644
--- a/lib/public_key/doc/src/public_key_records.xml
+++ b/lib/public_key/doc/src/public_key_records.xml
@@ -5,25 +5,26 @@
<header>
<copyright>
<year>2008</year>
- <year>2014</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>Public key records</title>
+ <title>Public-Key Records</title>
<prepared>Ingela Anderton Andin</prepared>
<responsible></responsible>
<docno></docno>
@@ -34,28 +35,85 @@
<file>public_key_records.xml</file>
</header>
- <p>This chapter briefly describes Erlang records derived from ASN1
- specifications used to handle public and private keys.
- The intent is to describe the data types
- and not to specify the semantics of each component. For information on the
- semantics, please see the relevant standards and RFCs.</p>
+ <p>This chapter briefly describes Erlang records derived from ASN.1
+ specifications used to handle public key infrastructure.
+ The scope is to describe the data types of each component,
+ not the semantics. For information on the
+ semantics, refer to the relevant standards and RFCs linked in the sections below.</p>
<p>Use the following include directive to get access to the
- records and constant macros described in the following sections.</p>
+ records and constant macros described in the following sections:</p>
<code> -include_lib("public_key/include/public_key.hrl"). </code>
- <section>
- <title>Common Data Types</title>
+ <section>
+ <title>Data Types</title>
<p>Common non-standard Erlang
- data types used to described the record fields in the
- below sections are defined in <seealso
- marker="public_key">public key reference manual </seealso></p>
- </section>
+ data types used to describe the record fields in the
+ following sections and which are not defined in the Public Key <seealso
+ marker="public_key">Reference Manual</seealso>
+ follows here:</p>
+
+ <taglist>
+ <tag><c>time() =</c></tag>
+ <item><p><c>utc_time() | general_time()</c></p></item>
+
+ <tag><c>utc_time() =</c></tag>
+ <item><p><c>{utcTime, "YYMMDDHHMMSSZ"}</c></p></item>
+
+ <tag><c>general_time() =</c></tag>
+ <item><p><c>{generalTime, "YYYYMMDDHHMMSSZ"}</c></p></item>
+
+ <tag><c>general_name() =</c></tag>
+ <item><p><c>{rfc822Name, string()}</c></p>
+ <p><c>| {dNSName, string()}</c></p>
+ <p><c>| {x400Address, string()}</c></p>
+ <p><c>| {directoryName, {rdnSequence, [#AttributeTypeAndValue'{}]}}</c></p>
+ <p><c>| {eidPartyName, special_string()}</c></p>
+ <p><c>| {eidPartyName, special_string(), special_string()}</c></p>
+ <p><c>| {uniformResourceIdentifier, string()}</c></p>
+ <p><c>| {ipAddress, string()}</c></p>
+ <p><c>| {registeredId, oid()}</c></p>
+ <p><c>| {otherName, term()}</c></p>
+ </item>
+
+ <tag><c>special_string() =</c></tag>
+ <item><p><c>{teletexString, string()}</c></p>
+ <p><c>| {printableString, string()}</c></p>
+ <p><c>| {universalString, string()}</c></p>
+ <p><c>| {utf8String, binary()}</c></p>
+ <p><c>| {bmpString, string()}</c></p>
+ </item>
+
+ <tag><c>dist_reason() =</c></tag>
+ <item><p><c>unused</c></p>
+ <p><c>| keyCompromise</c></p>
+ <p><c>| cACompromise</c></p>
+ <p><c>| affiliationChanged</c></p>
+ <p><c>| superseded</c></p>
+ <p><c>| cessationOfOperation</c></p>
+ <p><c>| certificateHold</c></p>
+ <p><c>| privilegeWithdrawn</c></p>
+ <p><c>| aACompromise</c></p>
+ </item>
+ <tag><c>OID_macro() =</c></tag>
+ <item><p><c>?OID_name()</c></p>
+ </item>
+
+ <tag><c>OID_name() =</c></tag>
+ <item><p><c>atom()</c></p>
+ </item>
+
+ </taglist>
+
+ </section>
+
<section>
- <title>RSA as defined by the PKCS-1 standard and <url href="http://www.ietf.org/rfc/rfc3447.txt"> RFC 3447 </url></title>
+ <title>RSA</title>
+ <p>Erlang representation of <url href="http://www.ietf.org/rfc/rfc3447.txt">
+ Rivest-Shamir-Adleman cryptosystem (RSA)</url> keys follows:</p>
<code>
#'RSAPublicKey'{
@@ -80,16 +138,13 @@
prime, % integer()
exponent, % integer()
coefficient % integer()
- }.
- </code>
+ }. </code>
</section>
<section>
- <title>DSA as defined by
- <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> Digital Signature Standard (NIST FIPS PUB 186-2) </url>
- </title>
-
+ <title>DSA</title>
+ <p>Erlang representation of <url href="http://www.ietf.org/rfc/rfc6979.txt">Digital Signature Algorithm (DSA)</url> keys</p>
<code>
#'DSAPrivateKey',{
version, % integer()
@@ -104,18 +159,18 @@
p, % integer()
q, % integer()
g % integer()
- }.
- </code>
+ }. </code>
+
</section>
<section>
- <title>ECC (Elliptic Curve) <url href="http://www.ietf.org/rfc/rfc3447.txt"> RFC 5480 </url>
- </title>
+ <title>ECDSA </title>
+ <p>Erlang representation of <url href="http://www.ietf.org/rfc/rfc6979.txt">Elliptic Curve Digital Signature Algorithm (ECDSA)</url> keys follows:</p>
<code>
#'ECPrivateKey'{
version, % integer()
- privateKey, % octet_string()
+ privateKey, % binary()
parameters, % der_encoded() - {'EcpkParameters', #'ECParameters'{}} |
{'EcpkParameters', {namedCurve, oid()}} |
{'EcpkParameters', 'NULL'} % Inherited by CA
@@ -126,14 +181,14 @@
version, % integer()
fieldID, % #'FieldID'{}
curve, % #'Curve'{}
- base, % octet_string()
+ base, % binary()
order, % integer()
cofactor % integer()
}.
#'Curve'{
- a, % octet_string()
- b, % octet_string()
+ a, % binary()
+ b, % binary()
seed % bitstring() - optional
}.
@@ -144,10 +199,644 @@
}.
#'ECPoint'{
- point % octet_string() - the public key
- }.
-
- </code>
+ point % binary() - the public key
+ }.</code>
</section>
+ <section>
+ <title>PKIX Certificates</title>
+ <p>Erlang representation of PKIX certificates derived from ASN.1
+ specifications see also <url href="http://www.ietf.org/rfc/rfc5280.txt">X509 certificates (RFC 5280)</url>, also referred to as <c>plain</c> type, are as follows:</p>
+<code>
+#'Certificate'{
+ tbsCertificate, % #'TBSCertificate'{}
+ signatureAlgorithm, % #'AlgorithmIdentifier'{}
+ signature % bitstring()
+ }.
+
+#'TBSCertificate'{
+ version, % v1 | v2 | v3
+ serialNumber, % integer()
+ signature, % #'AlgorithmIdentifier'{}
+ issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
+ validity, % #'Validity'{}
+ subject, % {rdnSequence, [#AttributeTypeAndValue'{}]}
+ subjectPublicKeyInfo, % #'SubjectPublicKeyInfo'{}
+ issuerUniqueID, % binary() | asn1_novalue
+ subjectUniqueID, % binary() | asn1_novalue
+ extensions % [#'Extension'{}]
+ }.
+
+#'AlgorithmIdentifier'{
+ algorithm, % oid()
+ parameters % der_encoded()
+ }.</code>
+
+<p>Erlang alternate representation of PKIX certificate, also referred to as <c>otp</c> type</p>
+
+<code>
+#'OTPCertificate'{
+ tbsCertificate, % #'OTPTBSCertificate'{}
+ signatureAlgorithm, % #'SignatureAlgorithm'
+ signature % bitstring()
+ }.
+
+#'OTPTBSCertificate'{
+ version, % v1 | v2 | v3
+ serialNumber, % integer()
+ signature, % #'SignatureAlgorithm'
+ issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
+ validity, % #'Validity'{}
+ subject, % {rdnSequence, [#AttributeTypeAndValue'{}]}
+ subjectPublicKeyInfo, % #'OTPSubjectPublicKeyInfo'{}
+ issuerUniqueID, % binary() | asn1_novalue
+ subjectUniqueID, % binary() | asn1_novalue
+ extensions % [#'Extension'{}]
+ }.
+
+#'SignatureAlgorithm'{
+ algorithm, % id_signature_algorithm()
+ parameters % asn1_novalue | #'Dss-Parms'{}
+ }.</code>
+
+<p><c>id_signature_algorithm() = OID_macro()</c></p>
+
+<p>The available OID names are as follows:</p>
+<table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-dsa-with-sha1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-dsaWithSHA1 (ISO or OID to above)</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">md2WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">md5WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">sha1WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">sha-1WithRSAEncryption (ISO or OID to above)</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">sha224WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">sha256WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">sha512WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ecdsa-with-SHA1</cell>
+ </row>
+ <tcaption>Signature Algorithm OIDs </tcaption>
+</table>
+
+<p>The data type <c>'AttributeTypeAndValue'</c>, is represented as
+ the following erlang record:</p>
+
+<code>
+#'AttributeTypeAndValue'{
+ type, % id_attributes()
+ value % term()
+ }.</code>
+
+<p>The attribute OID name atoms and their corresponding value types
+are as follows:</p>
+<table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ <cell align="left" valign="middle"><em>Value Type</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-name</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-surname</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-givenName</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-initials </cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-generationQualifier</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-commonName</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-localityName</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-stateOrProvinceName</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-organizationName</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-title</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-dnQualifier</cell>
+ <cell align="left" valign="middle">{printableString, string()}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-countryName</cell>
+ <cell align="left" valign="middle">{printableString, string()}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-serialNumber</cell>
+ <cell align="left" valign="middle">{printableString, string()}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-at-pseudonym</cell>
+ <cell align="left" valign="middle">special_string()</cell>
+ </row>
+ <tcaption>Attribute OIDs</tcaption>
+</table>
+
+<p>The data types <c>'Validity'</c>, <c>'SubjectPublicKeyInfo'</c>, and
+<c>'SubjectPublicKeyInfoAlgorithm'</c> are represented as the following Erlang records:</p>
+
+<code>
+#'Validity'{
+ notBefore, % time()
+ notAfter % time()
+ }.
+
+#'SubjectPublicKeyInfo'{
+ algorithm, % #AlgorithmIdentifier{}
+ subjectPublicKey % binary()
+ }.
+
+#'SubjectPublicKeyInfoAlgorithm'{
+ algorithm, % id_public_key_algorithm()
+ parameters % public_key_params()
+ }.</code>
+
+<p>The public-key algorithm OID name atoms are as follows:</p>
+<table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">rsaEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-dsa</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">dhpublicnumber</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-keyExchangeAlgorithm</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ecPublicKey</cell>
+ </row>
+ <tcaption>Public-Key Algorithm OIDs</tcaption>
+</table>
+
+<code>
+#'Extension'{
+ extnID, % id_extensions() | oid()
+ critical, % boolean()
+ extnValue % der_encoded()
+ }.</code>
+
+<p><c>id_extensions()</c>
+ <seealso marker="#StdCertExt">Standard Certificate Extensions</seealso>,
+ <seealso marker="#PrivIntExt">Private Internet Extensions</seealso>,
+ <seealso marker="#CRLCertExt">CRL Extensions</seealso> and
+ <seealso marker="#CRLEntryExt">CRL Entry Extensions</seealso>.
+</p>
+
+</section>
+
+<section>
+ <marker id="StdCertExt"></marker>
+ <title>Standard Certificate Extensions</title>
+
+ <p>The standard certificate extensions OID name atoms and their
+ corresponding value types are as follows:</p>
+
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ <cell align="left" valign="middle"><em>Value Type</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-authorityKeyIdentifier</cell>
+ <cell align="left" valign="middle">#'AuthorityKeyIdentifier'{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-subjectKeyIdentifier</cell>
+ <cell align="left" valign="middle">oid()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-keyUsage</cell>
+ <cell align="left" valign="middle">[key_usage()]</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-privateKeyUsagePeriod</cell>
+ <cell align="left" valign="middle">#'PrivateKeyUsagePeriod'{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-certificatePolicies</cell>
+ <cell align="left" valign="middle">#'PolicyInformation'{}</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-policyMappings</cell>
+ <cell align="left" valign="middle">#'PolicyMappings_SEQOF'{}</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-subjectAltName</cell>
+ <cell align="left" valign="middle">general_name()</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-issuerAltName</cell>
+ <cell align="left" valign="middle">general_name()</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-subjectDirectoryAttributes</cell>
+ <cell align="left" valign="middle"> [#'Attribute'{}]</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-basicConstraints</cell>
+ <cell align="left" valign="middle">#'BasicConstraints'{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-nameConstraints</cell>
+ <cell align="left" valign="middle">#'NameConstraints'{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-policyConstraints</cell>
+ <cell align="left" valign="middle">#'PolicyConstraints'{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-extKeyUsage</cell>
+ <cell align="left" valign="middle">[id_key_purpose()]</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-cRLDistributionPoints</cell>
+ <cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-inhibitAnyPolicy</cell>
+ <cell align="left" valign="middle">integer()</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">id-ce-freshestCRL</cell>
+ <cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
+ </row>
+
+
+ <tcaption>Standard Certificate Extensions</tcaption>
+ </table>
+
+ <p>Here:</p>
+ <taglist>
+ <tag><c>key_usage()</c></tag>
+ <item>= <p><c>digitalSignature</c></p>
+ <p><c>| nonRepudiation</c></p>
+ <p><c>| keyEncipherment</c></p>
+ <p><c>| dataEncipherment</c></p>
+ <p><c>| keyAgreement</c></p>
+ <p><c>| keyCertSign</c></p>
+ <p><c>| cRLSign</c></p>
+ <p><c>| encipherOnly</c></p>
+ <p><c>| decipherOnly </c></p>
+ </item>
+ </taglist>
+
+ <p>And for <c>id_key_purpose()</c>:</p>
+
+<table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-kp-serverAuth</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-kp-clientAuth</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-kp-codeSigning</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-kp-emailProtection</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-kp-timeStamping</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-kp-OCSPSigning</cell>
+ </row>
+ <tcaption>Key Purpose OIDs</tcaption>
+</table>
+
+ <code>
+#'AuthorityKeyIdentifier'{
+ keyIdentifier, % oid()
+ authorityCertIssuer, % general_name()
+ authorityCertSerialNumber % integer()
+ }.
+
+#'PrivateKeyUsagePeriod'{
+ notBefore, % general_time()
+ notAfter % general_time()
+ }.
+
+#'PolicyInformation'{
+ policyIdentifier, % oid()
+ policyQualifiers % [#PolicyQualifierInfo{}]
+ }.
+
+#'PolicyQualifierInfo'{
+ policyQualifierId, % oid()
+ qualifier % string() | #'UserNotice'{}
+ }.
+
+#'UserNotice'{
+ noticeRef, % #'NoticeReference'{}
+ explicitText % string()
+ }.
+
+#'NoticeReference'{
+ organization, % string()
+ noticeNumbers % [integer()]
+ }.
+
+#'PolicyMappings_SEQOF'{
+ issuerDomainPolicy, % oid()
+ subjectDomainPolicy % oid()
+ }.
+
+#'Attribute'{
+ type, % oid()
+ values % [der_encoded()]
+ }).
+
+#'BasicConstraints'{
+ cA, % boolean()
+ pathLenConstraint % integer()
+ }).
+
+#'NameConstraints'{
+ permittedSubtrees, % [#'GeneralSubtree'{}]
+ excludedSubtrees % [#'GeneralSubtree'{}]
+ }).
+
+#'GeneralSubtree'{
+ base, % general_name()
+ minimum, % integer()
+ maximum % integer()
+ }).
+
+#'PolicyConstraints'{
+ requireExplicitPolicy, % integer()
+ inhibitPolicyMapping % integer()
+ }).
+
+#'DistributionPoint'{
+ distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
+ [#AttributeTypeAndValue{}]}
+ reasons, % [dist_reason()]
+ cRLIssuer % [general_name()]
+ }).</code>
+
+</section>
+
+ <section>
+ <marker id="PrivIntExt"></marker>
+ <title>Private Internet Extensions</title>
+
+ <p>The private internet extensions OID name atoms and their corresponding value
+ types are as follows:</p>
+
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ <cell align="left" valign="middle"><em>Value Type</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-pe-authorityInfoAccess</cell>
+ <cell align="left" valign="middle">[#'AccessDescription'{}]</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-pe-subjectInfoAccess</cell>
+ <cell align="left" valign="middle">[#'AccessDescription'{}]</cell>
+ </row>
+ <tcaption>Private Internet Extensions</tcaption>
+ </table>
+
+<code>
+#'AccessDescription'{
+ accessMethod, % oid()
+ accessLocation % general_name()
+ }).</code>
+
+ </section>
+
+<section>
+ <title>CRL and CRL Extensions Profile</title>
+
+ <p>Erlang representation of CRL and CRL extensions profile
+ derived from ASN.1 specifications and RFC 5280 are as follows:</p>
+
+ <code>
+#'CertificateList'{
+ tbsCertList, % #'TBSCertList{}
+ signatureAlgorithm, % #'AlgorithmIdentifier'{}
+ signature % bitstring()
+ }).
+
+#'TBSCertList'{
+ version, % v2 (if defined)
+ signature, % #AlgorithmIdentifier{}
+ issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
+ thisUpdate, % time()
+ nextUpdate, % time()
+ revokedCertificates, % [#'TBSCertList_revokedCertificates_SEQOF'{}]
+ crlExtensions % [#'Extension'{}]
+ }).
+
+#'TBSCertList_revokedCertificates_SEQOF'{
+ userCertificate, % integer()
+ revocationDate, % timer()
+ crlEntryExtensions % [#'Extension'{}]
+ }).</code>
+
+ <section>
+ <marker id="CRLCertExt"></marker>
+ <title>CRL Extensions</title>
+
+ <p>The CRL extensions OID name atoms and their corresponding value types are as follows:</p>
+
+
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ <cell align="left" valign="middle"><em>Value Type</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-authorityKeyIdentifier</cell>
+ <cell align="left" valign="middle">#'AuthorityKeyIdentifier{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-issuerAltName</cell>
+ <cell align="left" valign="middle">{rdnSequence, [#AttributeTypeAndValue'{}]}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-cRLNumber</cell>
+ <cell align="left" valign="middle">integer()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-deltaCRLIndicator</cell>
+ <cell align="left" valign="middle">integer()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-issuingDistributionPoint</cell>
+ <cell align="left" valign="middle">#'IssuingDistributionPoint'{}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-freshestCRL</cell>
+ <cell align="left" valign="middle">[#'Distributionpoint'{}]</cell>
+ </row>
+
+ <tcaption>CRL Extensions</tcaption>
+ </table>
+
+ <p>Here, the data type <c>'IssuingDistributionPoint'</c> is represented as
+ the following Erlang record:</p>
+
+ <code>
+#'IssuingDistributionPoint'{
+ distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
+ [#AttributeTypeAndValue'{}]}
+ onlyContainsUserCerts, % boolean()
+ onlyContainsCACerts, % boolean()
+ onlySomeReasons, % [dist_reason()]
+ indirectCRL, % boolean()
+ onlyContainsAttributeCerts % boolean()
+ }).</code>
+ </section>
+
+ <section>
+ <marker id="CRLEntryExt"></marker>
+ <title>CRL Entry Extensions</title>
+
+ <p>The CRL entry extensions OID name atoms and their corresponding value types are as follows:</p>
+
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>OID Name</em></cell>
+ <cell align="left" valign="middle"><em>Value Type</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-cRLReason</cell>
+ <cell align="left" valign="middle">crl_reason()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-holdInstructionCode</cell>
+ <cell align="left" valign="middle">oid()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-invalidityDate</cell>
+ <cell align="left" valign="middle">general_time()</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">id-ce-certificateIssuer</cell>
+ <cell align="left" valign="middle">general_name()</cell>
+ </row>
+ <tcaption>CRL Entry Extensions</tcaption>
+ </table>
+
+
+ <p>Here:</p>
+ <taglist>
+ <tag><c>crl_reason()</c></tag>
+ <item>= <p><c>unspecified</c></p>
+ <p><c>| keyCompromise</c></p>
+ <p><c>| cACompromise</c></p>
+ <p><c>| affiliationChanged</c></p>
+ <p><c>| superseded</c></p>
+ <p><c>| cessationOfOperation</c></p>
+ <p><c>| certificateHold</c></p>
+ <p><c>| removeFromCRL</c></p>
+ <p><c>| privilegeWithdrawn</c></p>
+ <p><c>| aACompromise</c></p>
+ </item>
+ </taglist>
+
+ </section>
+
+ <section>
+ <marker id="PKCS10"></marker>
+ <title>PKCS#10 Certification Request</title>
+ <p>Erlang representation of a PKCS#10 certification request
+ derived from ASN.1 specifications and RFC 5280 are as follows:</p>
+ <code>
+#'CertificationRequest'{
+ certificationRequestInfo #'CertificationRequestInfo'{},
+ signatureAlgorithm #'CertificationRequest_signatureAlgorithm'{}}.
+ signature bitstring()
+ }
+
+#'CertificationRequestInfo'{
+ version atom(),
+ subject {rdnSequence, [#AttributeTypeAndValue'{}]} ,
+ subjectPKInfo #'CertificationRequestInfo_subjectPKInfo'{},
+ attributes [#'AttributePKCS-10' {}]
+ }
+
+#'CertificationRequestInfo_subjectPKInfo'{
+ algorithm #'CertificationRequestInfo_subjectPKInfo_algorithm'{}
+ subjectPublicKey bitstring()
+ }
+
+#'CertificationRequestInfo_subjectPKInfo_algorithm'{
+ algorithm = oid(),
+ parameters = der_encoded()
+}
+
+#'CertificationRequest_signatureAlgorithm'{
+ algorithm = oid(),
+ parameters = der_encoded()
+ }
+
+#'AttributePKCS-10'{
+ type = oid(),
+ values = [der_encoded()]
+} </code>
+ </section>
+</section>
</chapter>
diff --git a/lib/public_key/doc/src/ref_man.xml b/lib/public_key/doc/src/ref_man.xml
index b7078891d4..b3823e1dc3 100644
--- a/lib/public_key/doc/src/ref_man.xml
+++ b/lib/public_key/doc/src/ref_man.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -31,8 +32,8 @@
<file>ref_man.xml</file>
</header>
<description>
- <p> Provides functions to handle public key infrastructure
- from RFC 3280 (X.509 certificates) and some parts of the PKCS-standard.
+ <p>The <c>public_key</c> application provides functions to handle public-key infrastructure
+ from RFC 3280 (X.509 certificates) and parts of the PKCS standard.
</p>
</description>
<xi:include href="public_key.xml"/>
diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml
index 450bd7e35f..d03c05d773 100644
--- a/lib/public_key/doc/src/using_public_key.xml
+++ b/lib/public_key/doc/src/using_public_key.xml
@@ -8,62 +8,65 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Getting Started</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
<file>using_public_key.xml</file>
</header>
- <section>
- <title>General information</title>
+ <p>This section describes examples of how to use the
+ Public Key API. Keys and certificates used in the following
+ sections are generated only for testing the Public Key
+ application.</p>
- <p> This chapter is dedicated to showing some
- examples of how to use the public_key API. Keys and certificates
- used in the following sections are generated only for the purpose
- of testing the public key application.</p>
+ <p>Some shell printouts in the following examples
+ are abbreviated for increased readability.</p>
- <p>Note that some shell printouts, in the following examples,
- have been abbreviated for increased readability.</p>
+
+ <section>
+ <title>PEM Files</title>
+ <p>Public-key data (keys, certificates, and so on) can be stored in
+ Privacy Enhanced Mail (PEM) format.
+ The PEM files have the following structure:</p>
- </section>
+ <code>
+ &lt;text&gt;
+ -----BEGIN &lt;SOMETHING&gt;-----
+ &lt;Attribute&gt; : &lt;Value&gt;
+ &lt;Base64 encoded DER data&gt;
+ -----END &lt;SOMETHING&gt;-----
+ &lt;text&gt;</code>
- <section>
- <title>PEM files</title>
- <p> Public key data (keys, certificates etc) may be stored in PEM format. PEM files
- comes from the Private Enhanced Mail Internet standard and has a
- structure that looks like this:</p>
-
- <code>&lt;text&gt;
- -----BEGIN &lt;SOMETHING&gt;-----
- &lt;Attribute&gt; : &lt;Value&gt;
- &lt;Base64 encoded DER data&gt;
- -----END &lt;SOMETHING&gt;-----
- &lt;text&gt;</code>
-
- <p>A file can contain several BEGIN/END blocks. Text lines between
- blocks are ignored. Attributes, if present, are currently ignored except
- for <c>Proc-Type</c> and <c>DEK-Info</c> that are used when the DER data is
- encrypted.</p>
+ <p>A file can contain several <c>BEGIN/END</c> blocks. Text lines between
+ blocks are ignored. Attributes, if present, are ignored except
+ for <c>Proc-Type</c> and <c>DEK-Info</c>, which are used when <c>DER</c>
+ data is encrypted.</p>
<section>
- <title>DSA private key</title>
+ <title>DSA Private Key</title>
+ <p>A DSA private key can look as follows:</p>
+ <note><p>File handling is not done by the Public Key application.</p></note>
- <p>Note file handling is not done by the public_key application. </p>
<code>1> {ok, PemBin} = file:read_file("dsa.pem").
{ok,&lt;&lt;"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...&gt;&gt;}</code>
- <p>This PEM file only has one entry, a private DSA key.</p>
+ <p>The following PEM file has only one entry, a private DSA key:</p>
<code>2> [DSAEntry] = public_key:pem_decode(PemBin).
[{'DSAPrivateKey',&lt;&lt;48,130,1,187,2,1,0,2,129,129,0,183,
179,230,217,37,99,144,157,21,228,204,
@@ -80,21 +83,20 @@
</section>
<section>
- <title>RSA private key encrypted with a password.</title>
+ <title>RSA Private Key with Password</title>
+ <p>An RSA private key encrypted with a password can look as follows:</p>
<code>1> {ok, PemBin} = file:read_file("rsa.pem").
{ok,&lt;&lt;"Bag Attribut"...&gt;&gt;}</code>
- <p>This PEM file only has one entry a private RSA key.</p>
+ <p>The following PEM file has only one entry, a private RSA key:</p>
<code>2>[RSAEntry] = public_key:pem_decode(PemBin).
[{'RSAPrivateKey',&lt;&lt;224,108,117,203,152,40,15,77,128,126,
221,195,154,249,85,208,202,251,109,
119,120,57,29,89,19,9,...&gt;&gt;,
- {"DES-EDE3-CBC",&lt;&lt;"kÙeø¼pµL"&gt;&gt;}}]
-
- </code>
+ {"DES-EDE3-CBC",&lt;&lt;"kÙeø¼pµL"&gt;&gt;}}]</code>
- <p>In this example the password is "abcd1234".</p>
+ <p>In this following example, the password is <c>"abcd1234"</c>:</p>
<code>3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234").
#'RSAPrivateKey'{version = 'two-prime',
modulus = 1112355156729921663373...2737107,
@@ -110,11 +112,12 @@
<section>
<title>X509 Certificates</title>
+ <p>The following is an example of X509 certificates:</p>
<code>1> {ok, PemBin} = file:read_file("cacerts.pem").
{ok,&lt;&lt;"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...&gt;&gt;}</code>
- <p>This file includes two certificates</p>
+ <p>The following file includes two certificates:</p>
<code>2> [CertEntry1, CertEntry2] = public_key:pem_decode(PemBin).
[{'Certificate',&lt;&lt;48,130,2,238,48,130,2,87,160,3,2,1,2,2,
9,0,230,145,97,214,191,2,120,150,48,13,
@@ -124,7 +127,7 @@
1,48,13,6,9,42,134,72,134,247,...&gt;&gt;>,
not_encrypted}]</code>
- <p>Certificates may of course be decoded as usual ... </p>
+ <p>Certificates can be decoded as usual:</p>
<code>2> Cert = public_key:pem_entry_decode(CertEntry1).
#'Certificate'{
tbsCertificate =
@@ -210,24 +213,24 @@
algorithm = {1,2,840,113549,1,1,5},
parameters = &lt;&lt;5,0&gt;&gt;},
signature =
- {0,
- &lt;&lt;163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
- 165,2,52,196,195,109,167,192,...&gt;&gt;}}
-</code>
-
- <p> Parts of certificates can be decoded with
- public_key:der_decode/2 using that parts ASN.1 type.
- Although application specific certificate
- extension requires application specific ASN.1 decode/encode-functions.
- Example, the first value of the rdnSequence above is of ASN.1 type
- 'X520CommonName'. ({2,5,4,3} = ?id-at-commonName)</p>
+ &lt;&lt;163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
+ 165,2,52,196,195,109,167,192,...&gt;&gt;}</code>
+
+ <p>Parts of certificates can be decoded with
+ <c>public_key:der_decode/2</c>, using the ASN.1 type of that part.
+ However, an application-specific certificate extension requires
+ application-specific ASN.1 decode/encode-functions.
+ In the recent example, the first value of <c>rdnSequence</c> is
+ of ASN.1 type <c>'X520CommonName'. ({2,5,4,3} = ?id-at-commonName)</c>:</p>
<code>public_key:der_decode('X520CommonName', &lt;&lt;19,8,101,114,108,97,110,103,67,65&gt;&gt;).
{printableString,"erlangCA"}</code>
- <p>... but certificates can also be decode using the pkix_decode_cert/2 that
- can customize and recursively decode standard parts of a certificate.</p>
+ <p>However, certificates can also be decoded using <c>pkix_decode_cert/2</c>,
+ which can customize and recursively decode standard parts of a certificate:</p>
+
<code>3>{_, DerCert, _} = CertEntry1.</code>
+
<code>4> public_key:pkix_decode_cert(DerCert, otp).
#'OTPCertificate'{
tbsCertificate =
@@ -314,30 +317,27 @@
algorithm = {1,2,840,113549,1,1,5},
parameters = 'NULL'},
signature =
- {0,
&lt;&lt;163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
- 165,2,52,196,195,109,167,192,...&gt;&gt;}}
-</code>
+ 165,2,52,196,195,109,167,192,...&gt;&gt;}</code>
- <p>This call is equivalent to public_key:pem_entry_decode(CertEntry1)</p>
+ <p>This call is equivalent to <c>public_key:pem_entry_decode(CertEntry1)</c>:</p>
<code>5> public_key:pkix_decode_cert(DerCert, plain).
-#'Certificate'{ ...}
-</code>
+#'Certificate'{ ...}</code>
</section>
<section>
- <title>Encoding public key data to PEM format</title>
+ <title>Encoding Public-Key Data to PEM Format</title>
- <p>If you have public key data and and want to create a PEM file
- you can do that by calling the functions
- public_key:pem_entry_encode/2 and pem_encode/1 and then saving the
- result to a file. For example assume you have PubKey =
- 'RSAPublicKey'{} then you can create a PEM-"RSA PUBLIC KEY" file
- (ASN.1 type 'RSAPublicKey') or a PEM-"PUBLIC KEY" file
- ('SubjectPublicKeyInfo' ASN.1 type).</p>
+ <p>If you have public-key data and want to create a PEM file
+ this can be done by calling functions
+ <c>public_key:pem_entry_encode/2</c> and <c>pem_encode/1</c> and
+ saving the result to a file. For example, assume that you have
+ <c>PubKey = 'RSAPublicKey'{}</c>. Then you can create a PEM-"RSA PUBLIC KEY"
+ file (ASN.1 type <c>'RSAPublicKey'</c>) or a PEM-"PUBLIC KEY" file
+ (<c>'SubjectPublicKeyInfo'</c> ASN.1 type).</p>
- <p> The second element of the PEM-entry will be the ASN.1 DER encoded
- key data.</p>
+ <p>The second element of the PEM-entry is the ASN.1 <c>DER</c> encoded
+ key data:</p>
<code>1> PemEntry = public_key:pem_entry_encode('RSAPublicKey', RSAPubKey).
{'RSAPublicKey', &lt;&lt;48,72,...&gt;&gt;, not_encrypted}
@@ -348,7 +348,7 @@
3> file:write_file("rsa_pub_key.pem", PemBin).
ok</code>
- <p> or </p>
+ <p>or:</p>
<code>1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey).
{'SubjectPublicKeyInfo', &lt;&lt;48,92...&gt;&gt;, not_encrypted}
@@ -363,96 +363,108 @@ ok</code>
</section>
<section>
- <title>RSA public key cryptography </title>
- <p> Suppose you have PrivateKey = #'RSAPrivateKey{}' and the
- plaintext Msg = binary() and the corresponding public key
- PublicKey = #'RSAPublicKey'{} then you can do the following.
- Note that you normally will only do one of the encrypt or
- decrypt operations and the peer will do the other.
- </p>
-
- <p>Encrypt with the private key </p>
+ <title>RSA Public-Key Cryptography</title>
+ <p>Suppose you have the following private key and a corresponding public key:</p>
+ <list type="bulleted">
+ <item><c>PrivateKey = #'RSAPrivateKey{}'</c> and
+ the plaintext <c>Msg = binary()</c></item>
+ <item><c>PublicKey = #'RSAPublicKey'{}</c>
+ </item>
+ </list>
+ <p>Then you can proceed as follows:</p>
+
+ <p>Encrypt with the private key:</p>
<code>RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey),
Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),</code>
- <p>Encrypt with the public key </p>
+ <p>Encrypt with the public key:</p>
<code>RsaEncrypted = public_key:encrypt_public(Msg, PublicKey),
Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey),</code>
+
+ <note><p>You normally do only one of the encrypt or decrypt operations,
+ and the peer does the other. This normaly used in legacy applications
+ as a primitive digital signature.
+ </p></note>
+
</section>
<section>
- <title>Digital signatures</title>
+ <title>Digital Signatures</title>
- <p> Suppose you have PrivateKey = #'RSAPrivateKey{}'or
- #'DSAPrivateKey'{} and the plaintext Msg = binary() and the
- corresponding public key PublicKey = #'RSAPublicKey'{} or
- {integer(), #'DssParams'{}} then you can do the following. Note
- that you normally will only do one of the sign or verify operations
- and the peer will do the other. </p>
+ <p>Suppose you have the following private key and a corresponding public key:</p>
+
+ <list type="bulleted">
+ <item><c>PrivateKey = #'RSAPrivateKey{}'</c> or
+ <c>#'DSAPrivateKey'{}</c> and the plaintext <c>Msg = binary()</c></item>
+ <item><c>PublicKey = #'RSAPublicKey'{}</c> or
+ <c>{integer(), #'DssParams'{}}</c></item>
+ </list>
+ <p>Then you can proceed as follows:</p>
<code>Signature = public_key:sign(Msg, sha, PrivateKey),
true = public_key:verify(Msg, sha, Signature, PublicKey),</code>
- <p>It might be appropriate to calculate the message digest before
- calling sign or verify and then you can use the none as second
- argument.</p>
+ <note><p>You normally do only one of the sign or verify operations,
+ and the peer does the other.</p></note>
+
+ <p>It can be appropriate to calculate the message digest before
+ calling <c>sign</c> or <c>verify</c>, and then use <c>none</c> as
+ second argument:</p>
<code>Digest = crypto:sha(Msg),
Signature = public_key:sign(Digest, none, PrivateKey),
-true = public_key:verify(Digest, none, Signature, PublicKey),
- </code>
+true = public_key:verify(Digest, none, Signature, PublicKey),</code>
</section>
<section>
- <title>SSH files</title>
+ <title>SSH Files</title>
<p>SSH typically uses PEM files for private keys but has its
- own file format for storing public keys. The erlang public_key
- application can be used to parse the content of SSH public key files.</p>
+ own file format for storing public keys. The <c>public_key</c>
+ application can be used to parse the content of SSH public-key files.</p>
<section>
- <title> RFC 4716 SSH public key files </title>
+ <title>RFC 4716 SSH Public-Key Files</title>
<p>RFC 4716 SSH files looks confusingly like PEM files,
- but there are some differences.</p>
+ but there are some differences:</p>
<code>1> {ok, SshBin} = file:read_file("ssh2_rsa_pub").
{ok, &lt;&lt;"---- BEGIN SSH2 PUBLIC KEY ----\nAAAA"...&gt;&gt;}</code>
- <p>This is equivalent to calling public_key:ssh_decode(SshBin, rfc4716_public_key).
+ <p>This is equivalent to calling <c>public_key:ssh_decode(SshBin, rfc4716_public_key)</c>:
</p>
<code>2> public_key:ssh_decode(SshBin, public_key).
[{#'RSAPublicKey'{modulus = 794430685...91663,
- publicExponent = 35}, []}]
-</code>
+ publicExponent = 35}, []}]</code>
</section>
<section>
- <title> Openssh public key format </title>
+ <title>OpenSSH Public-Key Format</title>
+ <p>OpenSSH public-key format looks as follows:</p>
<code>1> {ok, SshBin} = file:read_file("openssh_dsa_pub").
{ok,&lt;&lt;"ssh-dss AAAAB3Nza"...&gt;&gt;}</code>
- <p>This is equivalent to calling public_key:ssh_decode(SshBin, openssh_public_key).
+ <p>This is equivalent to calling <c>public_key:ssh_decode(SshBin, openssh_public_key)</c>:
</p>
<code>2> public_key:ssh_decode(SshBin, public_key).
[{{15642692...694280725,
#'Dss-Parms'{p = 17291273936...696123221,
q = 1255626590179665817295475654204371833735706001853,
g = 10454211196...480338645}},
- [{comment,"dhopson@VMUbuntu-DSH"}]}]
-</code>
+ [{comment,"dhopson@VMUbuntu-DSH"}]}]</code>
</section>
<section>
- <title> Known hosts - openssh format</title>
-
+ <title>Known Hosts - OpenSSH Format</title>
+ <p>Known hosts - OpenSSH format looks as follows:</p>
<code>1> {ok, SshBin} = file:read_file("known_hosts").
{ok,&lt;&lt;"hostname.domain.com,192.168.0.1 ssh-rsa AAAAB...&gt;&gt;}</code>
- <p>Returns a list of public keys and their related attributes
- each pair of key and attributes corresponds to one entry in
- the known hosts file.</p>
+ <p>Returns a list of public keys and their related attributes.
+ Each pair of key and attribute corresponds to one entry in
+ the known hosts file:</p>
<code>2> public_key:ssh_decode(SshBin, known_hosts).
[{#'RSAPublicKey'{modulus = 1498979460408...72721699,
@@ -461,19 +473,19 @@ true = public_key:verify(Digest, none, Signature, PublicKey),
{#'RSAPublicKey'{modulus = 14989794604088...2721699,
publicExponent = 35},
[{comment,"[email protected]"},
- {hostnames,["|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA="]}]}]
-</code>
+ {hostnames,["|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA="]}]}]</code>
</section>
<section>
- <title> Authorized keys - openssh format</title>
+ <title>Authorized Keys - OpenSSH Format</title>
+ <p>Authorized keys - OpenSSH format looks as follows:</p>
<code>1> {ok, SshBin} = file:read_file("auth_keys").
{ok, &lt;&lt;"command=\"dump /home\",no-pty,no-port-forwarding ssh-rsa AAA...&gt;&gt;}</code>
- <p>Returns a list of public keys and their related attributes
- each pair of key and attributes corresponds to one entry in
- the authorized key file.</p>
+ <p>Returns a list of public keys and their related attributes.
+ Each pair of key and attribute corresponds to one entry in
+ the authorized key file:</p>
<code>2> public_key:ssh_decode(SshBin, auth_keys).
[{#'RSAPublicKey'{modulus = 794430685...691663,
@@ -485,16 +497,15 @@ true = public_key:verify(Digest, none, Signature, PublicKey),
#'Dss-Parms'{p = 17291273936185...763696123221,
q = 1255626590179665817295475654204371833735706001853,
g = 10454211195705...60511039590076780999046480338645}},
- [{comment,"dhopson@VMUbuntu-DSH"}]}]
-</code>
+ [{comment,"dhopson@VMUbuntu-DSH"}]}]</code>
</section>
<section>
- <title> Creating an SSH file from public key data </title>
+ <title>Creating an SSH File from Public-Key Data</title>
<p>If you got a public key <c>PubKey</c> and a related list of
attributes <c>Attributes</c> as returned
- by ssh_decode/2 you can create a new ssh file for example</p>
+ by <c>ssh_decode/2</c>, you can create a new SSH file, for example:</p>
<code>N> SshBin = public_key:ssh_encode([{PubKey, Attributes}], openssh_public_key),
&lt;&lt;"ssh-rsa "...&gt;&gt;
N+1> file:write_file("id_rsa.pub", SshBin).
diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl
index c6394115e3..d20f7b207e 100644
--- a/lib/public_key/include/public_key.hrl
+++ b/lib/public_key/include/public_key.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/public_key/priv/convert.escript b/lib/public_key/priv/convert.escript
new file mode 100755
index 0000000000..c7ea48c686
--- /dev/null
+++ b/lib/public_key/priv/convert.escript
@@ -0,0 +1,50 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+main([InFile,OutFile]) ->
+ {ok,In} = file:open(InFile,read),
+ {ok,Out} = file:open(OutFile,write),
+ write_file(Out, read_file(In)),
+ file:close(In),
+ file:close(Out).
+
+write_file(D, {ok,Ms}) ->
+ io:format(D,'-define(dh_default_groups,~n ~p~n ).~n',[Ms]).
+
+one_line(Line, Acc) when is_binary(Line) ->
+ one_line(binary_to_list(Line), Acc);
+one_line("#"++_, Acc) ->
+ Acc;
+one_line(Line, Acc) when is_list(Line) ->
+ try
+ [_Time,_Type,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
+ [{list_to_integer(Size),
+ {list_to_integer(G), list_to_integer(P,16)}
+ } | Acc]
+ catch
+ _:_ -> io:format("*** skip line ~p",[Line]),
+ Acc
+ end.
+
+
+collect_per_size(L) ->
+ lists:foldr(
+ fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
+ ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
+ end, [], lists:sort(L)).
+
+
+read_file(D) ->
+ read_file(D, []).
+
+read_file(D, Acc) ->
+ case io:get_line(D,"") of
+ {error,Error} ->
+ {error,Error};
+ eof ->
+ {ok, collect_per_size(Acc)};
+ Data ->
+ read_file(D, one_line(Data,Acc))
+ end.
+
+
diff --git a/lib/public_key/priv/generate b/lib/public_key/priv/generate
new file mode 100755
index 0000000000..fd185bfd52
--- /dev/null
+++ b/lib/public_key/priv/generate
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Generate ssh moduli files for the sizes in $moduli
+
+moduli="1024 1536 2048 3072 4096 6144 7168 8192"
+
+# In arg 1: size
+# Out: a file "moduli-$1" (for example: $1=2048 -> file "moduli.2048"
+function one_modulus() {
+ candidates=candidate-$1
+ ssh-keygen -G $candidates -b $1
+ ssh-keygen -T moduli-$1 -f $candidates
+ rm $candidates
+}
+
+
+# Generate in background
+for m in $moduli
+do
+ one_modulus $m &
+done
+
+# When all files moduli-* are generated, do:
+# cat moduli-* > moduli
+
diff --git a/lib/public_key/priv/moduli b/lib/public_key/priv/moduli
new file mode 100644
index 0000000000..446f4b8bf4
--- /dev/null
+++ b/lib/public_key/priv/moduli
@@ -0,0 +1,193 @@
+20151021104105 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D182EB7
+20151021104106 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D27F94F
+20151021104107 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D398EB7
+20151021104108 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D4B850F
+20151021104108 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D4BF35B
+20151021104108 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D5031DF
+20151021104109 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D5A4933
+20151021104110 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D6434BF
+20151021104111 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D70676B
+20151021104111 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D7235E3
+20151021104113 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D963493
+20151021104114 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DAABAA7
+20151021104115 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DC2E333
+20151021104116 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DE16A7B
+20151021104117 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DE2C5D3
+20151021104118 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DFF382F
+20151021104119 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E158F13
+20151021104122 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E4D9FEB
+20151021104123 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E5C1FDB
+20151021104126 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E9BB69B
+20151021104126 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E9F62D3
+20151021104127 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EAA1C27
+20151021104128 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EBC3313
+20151021104129 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EC0733B
+20151021104130 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EDB7AD3
+20151021104132 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EF56457
+20151021104132 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EF5A9CF
+20151021104133 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9F13CBB3
+20151021104218 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BAAFFDF
+20151021104222 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BCB6D93
+20151021104225 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BE660BB
+20151021104226 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BE676C3
+20151021104229 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BF3E23B
+20151021104230 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BF95757
+20151021104241 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C59BEA7
+20151021104242 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C6231B3
+20151021104244 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C6879BF
+20151021104250 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C9B678F
+20151021104252 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CA66A4B
+20151021104253 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CAB5543
+20151021104256 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CB96933
+20151021104300 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CDA8493
+20151021104308 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D18C0C7
+20151021104310 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D1DA5BF
+20151021104318 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D4AB15F
+20151021104325 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D7DE42F
+20151021104329 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DA03D3B
+20151021104335 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DD88BFF
+20151021104338 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DE82B5F
+20151021104342 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E07AF43
+20151021104343 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E091E6F
+20151021104346 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E28B90F
+20151021104347 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E2A24F3
+20151021104401 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EB074A7
+20151021104403 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EC01B0F
+20151021104406 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17ED2186F
+20151021104407 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17ED55AAB
+20151021104411 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EF58773
+20151021104414 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F0B3267
+20151021104423 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F4DF61B
+20151021104434 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F9BBB0B
+20151021104442 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17FDD6AFB
+20151021104350 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE5E381EF
+20151021104414 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE641C193
+20151021104422 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE659F523
+20151021104427 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE660E217
+20151021104438 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE6842F73
+20151021104441 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE689683B
+20151021104455 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE6C41E3B
+20151021104512 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE71E3BFF
+20151021104525 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE75C804F
+20151021104527 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE75DC48B
+20151021104535 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE7738983
+20151021104543 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE787027B
+20151021104610 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8075A1B
+20151021104625 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE84F79B3
+20151021104628 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE859F617
+20151021104641 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8948E2F
+20151021104646 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8A571B3
+20151021104659 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8CEA637
+20151021104705 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8E590FF
+20151021104707 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8E7943F
+20151021104731 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE95A975F
+20151021104741 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE985F923
+20151021104745 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE996E20B
+20151021104806 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE9FACFD7
+20151021104827 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEA562C43
+20151021104839 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEA8F25E3
+20151021104939 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEBB1DA0B
+20151021104941 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEBB86153
+20151021105002 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEC1B8883
+20151021105019 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEC71316F
+20151021105035 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECB1D113
+20151021105042 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECC3F3AB
+20151021105045 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECCC109B
+20151021105101 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED16353B
+20151021105106 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED24854F
+20151021105109 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED2AE4B3
+20151021105116 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED472CF7
+20151021104612 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E360CD0C3
+20151021104628 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3620FBE7
+20151021104701 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E36490F57
+20151021105014 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E377ACADB
+20151021105125 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E37E6DE07
+20151021105320 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E38C2387F
+20151021105649 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3A61E46B
+20151021105815 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3B0A6A4B
+20151021105848 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3B47D2C3
+20151021105948 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3BBBB953
+20151021110011 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3BE3B83B
+20151021110036 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3C0A3F1B
+20151021110201 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CB1970F
+20151021110208 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CB70C2B
+20151021110235 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CE4E4DF
+20151021110424 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3DB68CD7
+20151021110525 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3E290717
+20151021110655 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3ED6DA83
+20151021110731 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3F14C563
+20151021110831 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3F85477F
+20151021111418 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E420DE56B
+20151021111430 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E421DBA2F
+20151021111624 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E42F39A93
+20151021111916 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E44302363
+20151021112222 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E4585795F
+20151021112245 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E45A1DAFF
+20151021112339 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E4601674F
+20151021112437 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46691977
+20151021112521 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46AF3AD3
+20151021112532 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46BCAE97
+20151021112708 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E476520D3
+20151021112724 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E477B3317
+20151021105143 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BA7321EB
+20151021105537 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BB3AF34B
+20151021105816 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BBC51883
+20151021110444 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BD1A86C7
+20151021111341 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BEDB7BBB
+20151021111438 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BF0297AB
+20151021111935 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BFF381FF
+20151021113820 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C433A1BF
+20151021113833 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C43B426B
+20151021113900 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C45007D3
+20151021113921 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C45D8C3B
+20151021113941 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C4685D5F
+20151021114203 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C4F95D97
+20151021114417 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C57ED2FF
+20151021114645 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C612EC33
+20151021114825 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C67219F7
+20151021114922 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C6A942BB
+20151021115945 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C91E14DB
+20151021120515 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CA5F5DB3
+20151021120715 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CAD0D497
+20151021121027 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CB8F9D6F
+20151021121241 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CC0F677F
+20151021121518 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CC9CC647
+20151021121600 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CCC0ADC3
+20151021121734 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CD1BC68B
+20151021121759 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CD2A7DBF
+20151021122003 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CDA3D323
+20151021122542 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CED8D107
+20151021122856 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CF8DFEE7
+20151021123548 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D11CAC4F
+20151021123633 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D1426BBB
+20151021124201 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D2A62F0B
+20151021124454 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D353F0FB
+20151021124620 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D3AE526F
+20151021125224 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D535C4CB
+20151021130254 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D7B5CA43
+20151021111833 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239959D5A7
+20151021112931 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239A078C1B
+20151021123021 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239EC676DF
+20151021131523 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A2B9FC6B
+20151021141029 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A7BD762B
+20151021143421 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A9C3EFDF
+20151021144912 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AB1077AF
+20151021145200 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AB49943B
+20151021145825 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23ABE06353
+20151021150910 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23ACDA0223
+20151021153131 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AE91738F
+20151021154038 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AF40D013
+20151021154300 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AF75AD97
+20151021155008 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B01C9553
+20151021162240 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B319431B
+20151021162649 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B35A3D2B
+20151021163640 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B439E263
+20151021171004 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B748B983
+20151021172144 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B8609B5B
+20151021173002 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B9021E9F
+20151021182612 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23BE0C1EDB
+20151021190053 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C120FF97
+20151021192934 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C3BEB637
+20151021113847 2 6 100 8191 2 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE37347869A3
+20151021133636 2 6 100 8191 2 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373914ECA3
+20151021140108 2 6 100 8191 5 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373A17959F
diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile
index 09393e8e50..786f244f85 100644
--- a/lib/public_key/src/Makefile
+++ b/lib/public_key/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-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.
+# Licensed under the Apache License, Version 2.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%
#
@@ -49,7 +50,7 @@ MODULES = \
HRL_FILES = $(INCLUDE)/public_key.hrl
-INTERNAL_HRL_FILES =
+INTERNAL_HRL_FILES = pubkey_moduli.hrl
ERL_FILES = $(MODULES:%=%.erl)
@@ -85,6 +86,11 @@ ERL_COMPILE_FLAGS += $(PUB_KEY_ERL_FLAGS) \
debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(HRL_FILES)
+$(EBIN)/pubkey_ssh.$(EMULATOR): pubkey_moduli.hrl
+
+pubkey_moduli.hrl: ../priv/moduli
+ escript ../priv/convert.escript $< $@
+
clean:
rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
rm -f core
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index 8b11538499..e67850cf54 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -445,7 +446,7 @@ extensions_list(Extensions) ->
Extensions.
extract_verify_data(OtpCert, DerCert) ->
- {_, Signature} = OtpCert#'OTPCertificate'.signature,
+ Signature = OtpCert#'OTPCertificate'.signature,
SigAlgRec = OtpCert#'OTPCertificate'.signatureAlgorithm,
SigAlg = SigAlgRec#'SignatureAlgorithm'.algorithm,
PlainText = encoded_tbs_cert(DerCert),
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 9a8e49f265..70ec3d5306 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -217,8 +218,8 @@ namedCurves(brainpoolP512t1) -> ?'brainpoolP512t1'.
%%% SubjectPublicKey
decode_supportedPublicKey(#'OTPSubjectPublicKeyInfo'{algorithm= PA =
- #'PublicKeyAlgorithm'{algorithm=Algo},
- subjectPublicKey = {0,SPK0}}) ->
+ #'PublicKeyAlgorithm'{algorithm=Algo},
+ subjectPublicKey = SPK0}) ->
Type = supportedPublicKeyAlgorithms(Algo),
SPK = case Type of
'ECPoint' -> #'ECPoint'{point = SPK0};
@@ -238,7 +239,7 @@ encode_supportedPublicKey(#'OTPSubjectPublicKeyInfo'{algorithm= PA =
{ok, SPK1} = 'OTP-PUB-KEY':encode(Type, SPK0),
SPK1
end,
- #'OTPSubjectPublicKeyInfo'{subjectPublicKey = {0,SPK}, algorithm=PA}.
+ #'OTPSubjectPublicKeyInfo'{subjectPublicKey = SPK, algorithm=PA}.
%%% Extensions
diff --git a/lib/public_key/src/pubkey_crl.erl b/lib/public_key/src/pubkey_crl.erl
index 488cc97c70..eee4beb7d6 100644
--- a/lib/public_key/src/pubkey_crl.erl
+++ b/lib/public_key/src/pubkey_crl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -473,7 +474,7 @@ check_crl_num(_,_) ->
extension_value(Extension, ExtType, Extensions) ->
case pubkey_cert:select_extension(Extension, Extensions) of
#'Extension'{extnValue = Value} ->
- public_key:der_decode(ExtType, list_to_binary(Value));
+ public_key:der_decode(ExtType, iolist_to_binary(Value));
_ ->
undefined
end.
@@ -565,7 +566,7 @@ verify_crl_signature(CRL, DerCRL, Key, KeyParams) ->
{Key, KeyParams})
end.
extract_crl_verify_data(CRL, DerCRL) ->
- {0, Signature} = CRL#'CertificateList'.signature,
+ Signature = CRL#'CertificateList'.signature,
#'AlgorithmIdentifier'{algorithm = SigAlg} =
CRL#'CertificateList'.signatureAlgorithm,
PlainText = encoded_tbs_crl(DerCRL),
diff --git a/lib/public_key/src/pubkey_moduli.hrl b/lib/public_key/src/pubkey_moduli.hrl
new file mode 100644
index 0000000000..e4beecc12a
--- /dev/null
+++ b/lib/public_key/src/pubkey_moduli.hrl
@@ -0,0 +1,395 @@
+-define(dh_default_groups,
+ [{1023,
+ [{2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840821904219},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840822843699},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840824293227},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840824411619},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840826770579},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840829698867},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840831699579},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840831788499},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840835116819},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840838791147},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840839741403},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840843908763},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840844149459},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840846037779},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840846316347},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840848087763},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840851778483},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840818511543},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840819546447},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840820698807},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840821875983},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840822182367},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840823493823},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840828115623},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840833652783},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840844852263},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840849785943},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840849803727}]},
+ {1535,
+ [{2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891121581459},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891123347643},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891123353283},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891124232763},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891131462067},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891135933003},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891136255299},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891137177907},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891139347603},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891152305467},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891159084867},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891161343219},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891172563627},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891174672243},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891180467739},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891185564427},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891189869307},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891119456223},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891124590423},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891130908327},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891131873727},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891135211407},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891143426247},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891143747007},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891146699103},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891150054447},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891155995647},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891157019487},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891159178863},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891161250063},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891170145447},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891171171087},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891172350063},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891176092263}]},
+ {2047,
+ [{2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127673160083},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127674746147},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127677513587},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127677855803},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127681703483},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127691773067},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127693199747},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127694475899},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127702886939},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127707613619},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127713247667},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127727962403},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127729070603},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127741606979},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127745340899},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127764392459},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127764820307},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127771318403},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127781167379},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127782355883},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127782887579},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127787746619},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127789102259},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127666983407},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127675200023},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127687609343},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127691690063},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127708300823},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127712140847},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127715948087},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127717449983},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127717581887},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127725119327},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127735619543},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127776932207},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127788684623},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127790955767}]},
+ {3071,
+ [{2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199506260163},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199530244827},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199578944619},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199589988939},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199594013379},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199601609043},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199604230203},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199606755099},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199618079787},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199653718659},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199657776483},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199707657579},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199722711699},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199743456099},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199785339603},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199797260499},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199507581927},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199510208343},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199537327623},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199551703167},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199617722127},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199621084383},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199634824407},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199642326807},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199665149823},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199708695087},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199765825887},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199767685887},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199773947727},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199780743543},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199786221207},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199798706967}]},
+ {4095,
+ [{2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328641094123},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328654189387},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328663242883},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328715041723},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328717604779},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328805204587},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328806565843},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328807451707},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328836115507},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328845968059},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328887178459},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328908234163},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328948166083},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328954136203},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328963052323},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329023777723},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329047093003},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329058480379},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329090057419},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329132001859},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328685618887},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328733393407},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328804704703},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328808160607},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328817663383},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328826409727},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328842353143},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328915670167},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328928173423},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328936548223},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328945813063},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328955100607},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328983302407},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328995176167},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329021303887},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329064403567}]},
+ {6143,
+ [{2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204878912539},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205024824427},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205108938283},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205168452667},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205178336083},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205194695203},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205234987027},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205249389907},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205299503899},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205303762219},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205318419043},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205369723267},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205388065627},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205483192027},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204867528103},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204958533343},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205142917087},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205164709807},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205223494543},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205238451607},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205398650527},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205534891927},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205578782263}]},
+ {8191,
+ [{2,
+ 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324150442403},
+ {2,
+ 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324227808419},
+ {5,
+ 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324244759967}]}]
+ ).
diff --git a/lib/public_key/src/pubkey_pbe.erl b/lib/public_key/src/pubkey_pbe.erl
index 521a32189d..2f6b121e83 100644
--- a/lib/public_key/src/pubkey_pbe.erl
+++ b/lib/public_key/src/pubkey_pbe.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -106,9 +107,8 @@ pbdkdf2(Password, Salt, Count, DerivedKeyLen, Prf, PrfHash, PrfOutputLen)->
%%--------------------------------------------------------------------
decrypt_parameters(#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
algorithm = Oid, parameters = Param}) ->
- decrypt_parameters(Oid, Param).
+ decrypt_parameters(Oid, decode_handle_open_type_wrapper(Param)).
-
%%--------------------------------------------------------------------
-spec encrypt_parameters({Cipher::string(), Params::term()}) ->
#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{}.
@@ -129,7 +129,7 @@ password_to_key_and_iv(Password, _, #'PBES2-params'{} = Params) ->
password_to_key_and_iv(Password, _Cipher, {#'PBEParameter'{salt = Salt,
iterationCount = Count}, Hash}) ->
<<Key:8/binary, IV:8/binary, _/binary>>
- = pbdkdf1(Password, erlang:iolist_to_binary(Salt), Count, Hash),
+ = pbdkdf1(Password, Salt, Count, Hash),
{Key, IV};
password_to_key_and_iv(Password, Cipher, Salt) ->
KeyLen = derived_key_length(Cipher, undefined),
@@ -151,15 +151,15 @@ do_pbdkdf1(Prev, Count, Acc, Hash) ->
do_pbdkdf1(Result, Count-1 , <<Result/binary, Acc/binary>>, Hash).
iv(#'PBES2-params_encryptionScheme'{algorithm = Algo,
- parameters = ASNIV}) when (Algo == ?'desCBC') or
- (Algo == ?'des-EDE3-CBC') ->
- %% This is an so called open ASN1-type that in this
- %% case will be an octet-string of length 8
- <<?ASN1_OCTET_STR_TAG, ?IV_LEN, IV:?IV_LEN/binary>> = ASNIV,
+ parameters = ASN1IV})
+ when (Algo == ?'desCBC') or
+ (Algo == ?'des-EDE3-CBC') ->
+ <<?ASN1_OCTET_STR_TAG, ?IV_LEN, IV:?IV_LEN/binary>> = decode_handle_open_type_wrapper(ASN1IV),
IV;
iv(#'PBES2-params_encryptionScheme'{algorithm = ?'rc2CBC',
- parameters = ASN1IV}) ->
- {ok, #'RC2-CBC-Parameter'{iv = IV}} = 'PKCS-FRAME':decode('RC2-CBC-Parameter', ASN1IV),
+ parameters = ASN1IV}) ->
+ {ok, #'RC2-CBC-Parameter'{iv = IV}}
+ = 'PKCS-FRAME':decode('RC2-CBC-Parameter', decode_handle_open_type_wrapper(ASN1IV)),
iolist_to_binary(IV).
blocks(1, N, Index, Password, Salt, Count, Prf, PrfHash, PrfLen, Acc) ->
@@ -200,13 +200,13 @@ encrypt_parameters(_Cipher, #'PBES2-params'{} = Params) ->
{ok, Der} ='PKCS-FRAME':encode('PBES2-params', Params),
#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
algorithm = ?'id-PBES2',
- parameters = Der};
+ parameters = encode_handle_open_type_wrapper(Der)};
encrypt_parameters(Cipher, {#'PBEParameter'{} = Params, Hash}) ->
{ok, Der} ='PKCS-FRAME':encode('PBEParameter', Params),
#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
algorithm = pbe1_oid(Cipher, Hash),
- parameters = Der}.
+ parameters = encode_handle_open_type_wrapper(Der)}.
pbe1_oid("RC2-CBC", sha) ->
?'pbeWithSHA1AndRC2-CBC';
@@ -277,3 +277,8 @@ cipher(#'PBES2-params_encryptionScheme'{algorithm = ?'rc2CBC'}) ->
ceiling(Float) ->
erlang:round(Float + 0.5).
+
+decode_handle_open_type_wrapper({asn1_OPENTYPE, Type}) ->
+ Type.
+encode_handle_open_type_wrapper(Type) ->
+ {asn1_OPENTYPE, Type}.
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index 98881c4a6a..d163004c7c 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -102,7 +103,7 @@ encode_pem_entry({'PrivateKeyInfo', Der, EncParams}) ->
[StartStr, "\n", b64encode_and_split(EncDer), "\n", pem_end(StartStr) ,"\n\n"];
encode_pem_entry({Type, Der, {Cipher, Salt}}) ->
StartStr = pem_start(Type),
- [StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n",
+ [StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n\n",
b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"].
decode_pem_entries([], Entries) ->
@@ -143,8 +144,7 @@ decode_encrypted_private_keyinfo(Der) ->
encryptedData = Data} =
public_key:der_decode('EncryptedPrivateKeyInfo', Der),
DecryptParams = pubkey_pbe:decrypt_parameters(AlgorithmInfo),
- {'PrivateKeyInfo', iolist_to_binary(Data), DecryptParams}.
-
+ {'PrivateKeyInfo', Data, DecryptParams}.
encode_encrypted_private_keyinfo(EncData, EncryptParmams) ->
AlgorithmInfo = pubkey_pbe:encrypt_parameters(EncryptParmams),
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
index 0522ea6ac3..9b281aa482 100644
--- a/lib/public_key/src/pubkey_ssh.erl
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -3,26 +3,34 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(pubkey_ssh).
-include("public_key.hrl").
+-include("pubkey_moduli.hrl").
+
--export([decode/2, encode/2]).
+-export([decode/2, encode/2,
+ dh_gex_group/4,
+ dh_gex_group_sizes/0
+ ]).
-define(UINT32(X), X:32/unsigned-big-integer).
+-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+
%% Max encoded line length is 72, but conformance examples use 68
%% Comment from rfc 4716: "The following are some examples of public
%% key files that are compliant (note that the examples all wrap
@@ -30,13 +38,16 @@
%% are still compliant.)" So we choose to use 68 also.
-define(ENCODED_LINE_LENGTH, 68).
+
%%====================================================================
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
-spec decode(binary(), public_key | public_key:ssh_file()) ->
- [{public_key:public_key(), Attributes::list()}].
+ [{public_key:public_key(), Attributes::list()}]
+ ; (binary(), ssh2_pubkey) -> public_key:public_key()
+ .
%%
%% Description: Decodes a ssh file-binary.
%%--------------------------------------------------------------------
@@ -49,21 +60,71 @@ decode(Bin, public_key)->
end;
decode(Bin, rfc4716_public_key) ->
rfc4716_decode(Bin);
+decode(Bin, ssh2_pubkey) ->
+ ssh2_pubkey_decode(Bin);
decode(Bin, Type) ->
openssh_decode(Bin, Type).
%%--------------------------------------------------------------------
-spec encode([{public_key:public_key(), Attributes::list()}], public_key:ssh_file()) ->
- binary().
+ binary()
+ ; (public_key:public_key(), ssh2_pubkey) -> binary()
+ .
%%
%% Description: Encodes a list of ssh file entries.
%%--------------------------------------------------------------------
+encode(Bin, ssh2_pubkey) ->
+ ssh2_pubkey_encode(Bin);
encode(Entries, Type) ->
iolist_to_binary(lists:map(fun({Key, Attributes}) ->
do_encode(Type, Key, Attributes)
end, Entries)).
%%--------------------------------------------------------------------
+-spec dh_gex_group(integer(), integer(), integer(),
+ undefined | [{integer(),[{integer(),integer()}]}]) ->
+ {ok,{integer(),{integer(),integer()}}} | {error,any()} .
+%%
+%% Description: Returns Generator and Modulus given MinSize, WantedSize
+%% and MaxSize
+%%--------------------------------------------------------------------
+dh_gex_group(Min, N, Max, undefined) ->
+ dh_gex_group(Min, N, Max, ?dh_default_groups);
+dh_gex_group(Min, N, Max, Groups) ->
+ case select_by_keylen(Min-10, N, Max+10, Groups) of
+ {ok,{Sz,GPs}} ->
+ {ok, {Sz,lists:nth(crypto:rand_uniform(1, 1+length(GPs)), GPs)}};
+ Other ->
+ Other
+ end.
+
+dh_gex_group_sizes()->
+ [KeyLen || {KeyLen,_} <- ?dh_default_groups].
+
+%% Select the one with K closest to N but within the interval [Min,Max]
+
+select_by_keylen(Min, N, Max, [{K,_Gs}|Groups]) when K < Min ->
+ select_by_keylen(Min, N, Max, Groups);
+select_by_keylen(Min, N, Max, [{K,Gs}|Groups]) when K =< Max ->
+ {ok, select_by_keylen(Min, N, Max, Groups, {K,Gs})};
+select_by_keylen(_Min, _N, _Max, _) ->
+ {error,no_group_found}.
+
+select_by_keylen(_Min, _N, Max, [{K,_Gs}|_Groups], GPprev) when K > Max ->
+ GPprev;
+select_by_keylen(Min, N, Max, [{K,Gs}|Groups], {Kprev,GsPrev}) ->
+ if
+ N == K -> {K,Gs};
+ N > K -> select_by_keylen(Min, N, Max, Groups, {K,Gs});
+ N < K, (K-N) < (N-Kprev) -> {K,Gs};
+ N < K -> {Kprev,GsPrev}
+ end;
+select_by_keylen(_Min, _N, _Max, [],GPprev) ->
+ %% is between Min and Max
+ GPprev.
+
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
begin_marker() ->
@@ -129,7 +190,12 @@ rfc4716_pubkey_decode(<<?UINT32(Len), Type:Len/binary,
{erlint(SizeY, Y),
#'Dss-Parms'{p = erlint(SizeP, P),
q = erlint(SizeQ, Q),
- g = erlint(SizeG, G)}}.
+ g = erlint(SizeG, G)}};
+rfc4716_pubkey_decode(<<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
+ ?UINT32(SizeId), Id:SizeId/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary>>) ->
+ <<"ecdsa-sha2-", Id/binary>> = ECDSA_SHA2_etc,
+ {#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.
openssh_decode(Bin, FileType) ->
Lines = binary:split(Bin, <<"\n">>, [global]),
@@ -183,46 +249,42 @@ do_openssh_decode(known_hosts = FileType, [Line | Lines], Acc) ->
end;
do_openssh_decode(openssh_public_key = FileType, [Line | Lines], Acc) ->
- case split_n(2, Line, []) of
- [KeyType, Base64Enc] when KeyType == <<"ssh-rsa">>;
- KeyType == <<"ssh-dss">> ->
+ [KeyType, Base64Enc | Comment0] = split_n(2, Line, []),
+ KnownKeyType =
+ case KeyType of
+ <<"ssh-rsa">> -> true;
+ <<"ssh-dss">> -> true;
+ <<"ecdsa-sha2-",Curve/binary>> -> is_ssh_curvename(Curve);
+ _ -> false
+ end,
+
+ case Comment0 of
+ [] when KnownKeyType==true ->
do_openssh_decode(FileType, Lines,
[{openssh_pubkey_decode(KeyType, Base64Enc),
[]} | Acc]);
- [KeyType, Base64Enc | Comment0] when KeyType == <<"ssh-rsa">>;
- KeyType == <<"ssh-dss">> ->
+ _ when KnownKeyType==true ->
Comment = string:strip(string_decode(iolist_to_binary(Comment0)), right, $\n),
do_openssh_decode(FileType, Lines,
[{openssh_pubkey_decode(KeyType, Base64Enc),
[{comment, Comment}]} | Acc])
end.
+
decode_comment([]) ->
[];
decode_comment(Comment) ->
[{comment, string_decode(iolist_to_binary(Comment))}].
-openssh_pubkey_decode(<<"ssh-rsa">>, Base64Enc) ->
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeE), E:SizeE/binary,
- ?UINT32(SizeN), N:SizeN/binary>>
- = base64:mime_decode(Base64Enc),
- #'RSAPublicKey'{modulus = erlint(SizeN, N),
- publicExponent = erlint(SizeE, E)};
-openssh_pubkey_decode(<<"ssh-dss">>, Base64Enc) ->
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeP), P:SizeP/binary,
- ?UINT32(SizeQ), Q:SizeQ/binary,
- ?UINT32(SizeG), G:SizeG/binary,
- ?UINT32(SizeY), Y:SizeY/binary>>
- = base64:mime_decode(Base64Enc),
- {erlint(SizeY, Y),
- #'Dss-Parms'{p = erlint(SizeP, P),
- q = erlint(SizeQ, Q),
- g = erlint(SizeG, G)}};
-openssh_pubkey_decode(KeyType, Base64Enc) ->
- {KeyType, base64:mime_decode(Base64Enc)}.
+openssh_pubkey_decode(Type, Base64Enc) ->
+ try
+ ssh2_pubkey_decode(Type, base64:mime_decode(Base64Enc))
+ catch
+ _:_ ->
+ {Type, base64:mime_decode(Base64Enc)}
+ end.
+
erlint(MPIntSize, MPIntValue) ->
Bits= MPIntSize * 8,
@@ -346,10 +408,9 @@ line_end("") ->
line_end(Comment) ->
[" ", Comment, "\n"].
-key_type(#'RSAPublicKey'{}) ->
- <<"ssh-rsa">>;
-key_type({_, #'Dss-Parms'{}}) ->
- <<"ssh-dss">>.
+key_type(#'RSAPublicKey'{}) -> <<"ssh-rsa">>;
+key_type({_, #'Dss-Parms'{}}) -> <<"ssh-dss">>;
+key_type({#'ECPoint'{}, {namedCurve,Curve}}) -> <<"ecdsa-sha2-", (public_key:oid2ssh_curvename(Curve))/binary>>.
comma_list_encode([Option], []) ->
Option;
@@ -379,20 +440,49 @@ ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
PBin/binary,
QBin/binary,
GBin/binary,
- YBin/binary>>.
-
-is_key_field(<<"ssh-dss">>) ->
- true;
-is_key_field(<<"ssh-rsa">>) ->
- true;
-is_key_field(<<"ecdsa-sha2-nistp256">>) ->
- true;
-is_key_field(<<"ecdsa-sha2-nistp384">>) ->
- true;
-is_key_field(<<"ecdsa-sha2-nistp521">>) ->
- true;
-is_key_field(_) ->
- false.
+ YBin/binary>>;
+ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
+ TypeStr = key_type(Key),
+ StrLen = size(TypeStr),
+ IdB = public_key:oid2ssh_curvename(OID),
+ <<?UINT32(StrLen), TypeStr:StrLen/binary,
+ (string(IdB))/binary,
+ (string(Q))/binary>>.
+
+
+ssh2_pubkey_decode(Bin = <<?UINT32(Len), Type:Len/binary, _/binary>>) ->
+ ssh2_pubkey_decode(Type, Bin).
+
+ssh2_pubkey_decode(<<"ssh-rsa">>,
+ <<?UINT32(Len), _:Len/binary,
+ ?UINT32(SizeE), E:SizeE/binary,
+ ?UINT32(SizeN), N:SizeN/binary>>) ->
+ #'RSAPublicKey'{modulus = erlint(SizeN, N),
+ publicExponent = erlint(SizeE, E)};
+
+ssh2_pubkey_decode(<<"ssh-dss">>,
+ <<?UINT32(Len), _:Len/binary,
+ ?UINT32(SizeP), P:SizeP/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary,
+ ?UINT32(SizeG), G:SizeG/binary,
+ ?UINT32(SizeY), Y:SizeY/binary>>) ->
+ {erlint(SizeY, Y),
+ #'Dss-Parms'{p = erlint(SizeP, P),
+ q = erlint(SizeQ, Q),
+ g = erlint(SizeG, G)}};
+ssh2_pubkey_decode(<<"ecdsa-sha2-",Id/binary>>,
+ <<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
+ ?UINT32(SizeId), Id:SizeId/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary>>) ->
+ <<"ecdsa-sha2-", Id/binary>> = ECDSA_SHA2_etc,
+ {#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.
+
+
+
+is_key_field(<<"ssh-dss">>) -> true;
+is_key_field(<<"ssh-rsa">>) -> true;
+is_key_field(<<"ecdsa-sha2-",Id/binary>>) -> is_ssh_curvename(Id);
+is_key_field(_) -> false.
is_bits_field(Part) ->
try list_to_integer(binary_to_list(Part)) of
@@ -506,3 +596,14 @@ int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
list_to_binary(Ds);
int_to_bin_neg(X,Ds) ->
int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
+
+
+string(X) when is_binary(X) ->
+ << ?STRING(X) >>;
+string(X) ->
+ << ?STRING(list_to_binary(X)) >>.
+
+is_ssh_curvename(Id) -> try public_key:ssh_curvename2oid(Id) of _ -> true
+ catch _:_ -> false
+ end.
+
diff --git a/lib/public_key/src/public_key.appup.src b/lib/public_key/src/public_key.appup.src
index 5278732c87..f39e7140e6 100644
--- a/lib/public_key/src/public_key.appup.src
+++ b/lib/public_key/src/public_key.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index e8ff965982..a79badef24 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,6 +35,8 @@
decrypt_private/2, decrypt_private/3,
encrypt_public/2, encrypt_public/3,
decrypt_public/2, decrypt_public/3,
+ dh_gex_group/4,
+ dh_gex_group_sizes/0,
sign/3, verify/4,
generate_key/1,
compute_key/2, compute_key/3,
@@ -46,6 +49,7 @@
pkix_normalize_name/1,
pkix_path_validation/3,
ssh_decode/2, ssh_encode/2,
+ ssh_curvename2oid/1, oid2ssh_curvename/1,
pkix_crls_validate/3,
pkix_dist_point/1,
pkix_dist_points/1,
@@ -120,7 +124,7 @@ pem_encode(PemEntries) when is_list(PemEntries) ->
%% pem entries.
%%--------------------------------------------------------------------
pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) ->
- {_, {'AlgorithmIdentifier', AlgId, Params}, {0, Key0}}
+ {_, {'AlgorithmIdentifier', AlgId, Params}, Key0}
= der_decode('SubjectPublicKeyInfo', Der),
KeyType = pubkey_cert_records:supportedPublicKeyAlgorithms(AlgId),
case KeyType of
@@ -168,14 +172,14 @@ pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry,
pem_entry_encode('SubjectPublicKeyInfo', Entity=#'RSAPublicKey'{}) ->
Der = der_encode('RSAPublicKey', Entity),
Spki = {'SubjectPublicKeyInfo',
- {'AlgorithmIdentifier', ?'rsaEncryption', ?DER_NULL}, {0, Der}},
+ {'AlgorithmIdentifier', ?'rsaEncryption', ?DER_NULL}, Der},
pem_entry_encode('SubjectPublicKeyInfo', Spki);
pem_entry_encode('SubjectPublicKeyInfo',
{DsaInt, Params=#'Dss-Parms'{}}) when is_integer(DsaInt) ->
KeyDer = der_encode('DSAPublicKey', DsaInt),
ParamDer = der_encode('DSAParams', {params, Params}),
Spki = {'SubjectPublicKeyInfo',
- {'AlgorithmIdentifier', ?'id-dsa', ParamDer}, {0, KeyDer}},
+ {'AlgorithmIdentifier', ?'id-dsa', ParamDer}, KeyDer},
pem_entry_encode('SubjectPublicKeyInfo', Spki);
pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) ->
Der = der_encode(Asn1Type, Entity),
@@ -234,7 +238,7 @@ der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') or
(Asn1Type == 'EncryptedPrivateKeyInfo') ->
try
{ok, Encoded} = 'PKCS-FRAME':encode(Asn1Type, Entity),
- iolist_to_binary(Encoded)
+ Encoded
catch
error:{badmatch, {error, _}} = Error ->
erlang:error(Error)
@@ -243,7 +247,7 @@ der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') or
der_encode(Asn1Type, Entity) when is_atom(Asn1Type) ->
try
{ok, Encoded} = 'OTP-PUB-KEY':encode(Asn1Type, Entity),
- iolist_to_binary(Encoded)
+ Encoded
catch
error:{badmatch, {error, _}} = Error ->
erlang:error(Error)
@@ -371,6 +375,13 @@ encrypt_private(PlainText,
crypto:private_encrypt(rsa, PlainText, format_rsa_private_key(Key), Padding).
%%--------------------------------------------------------------------
+dh_gex_group_sizes() ->
+ pubkey_ssh:dh_gex_group_sizes().
+
+dh_gex_group(Min, N, Max, Groups) ->
+ pubkey_ssh:dh_gex_group(Min, N, Max, Groups).
+
+%%--------------------------------------------------------------------
-spec generate_key(#'DHParameter'{} | {namedCurve, Name ::oid()} |
#'ECParameters'{}) -> {Public::binary(), Private::binary()} |
#'ECPrivateKey'{}.
@@ -391,7 +402,7 @@ generate_key(#'ECParameters'{} = Params) ->
compute_key(#'ECPoint'{point = Point}, #'ECPrivateKey'{privateKey = PrivKey,
parameters = Param}) ->
ECCurve = ec_curve_spec(Param),
- crypto:compute_key(ecdh, Point, list_to_binary(PrivKey), ECCurve).
+ crypto:compute_key(ecdh, Point, PrivKey, ECCurve).
compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) ->
crypto:compute_key(dh, PubKey, PrivKey, [P, G]).
@@ -446,7 +457,7 @@ sign(DigestOrPlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) ->
sign(DigestOrPlainText, DigestType, #'ECPrivateKey'{privateKey = PrivKey,
parameters = Param}) ->
ECCurve = ec_curve_spec(Param),
- crypto:sign(ecdsa, DigestType, DigestOrPlainText, [list_to_binary(PrivKey), ECCurve]);
+ crypto:sign(ecdsa, DigestType, DigestOrPlainText, [PrivKey, ECCurve]);
%% Backwards compatible
sign(Digest, none, #'DSAPrivateKey'{} = Key) ->
@@ -458,22 +469,12 @@ sign(Digest, none, #'DSAPrivateKey'{} = Key) ->
| dsa_public_key() | ec_public_key()) -> boolean().
%% Description: Verifies a digital signature.
%%--------------------------------------------------------------------
-verify(DigestOrPlainText, DigestType, Signature,
- #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) ->
- crypto:verify(rsa, DigestType, DigestOrPlainText, Signature,
- [Exp, Mod]);
-
-verify(DigestOrPlaintext, DigestType, Signature, {#'ECPoint'{point = Point}, Param}) ->
- ECCurve = ec_curve_spec(Param),
- crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, [Point, ECCurve]);
-
-%% Backwards compatibility
-verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) ->
- verify({digest,Digest}, sha, Signature, Key);
-
-verify(DigestOrPlainText, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}})
- when is_integer(Key), is_binary(Signature) ->
- crypto:verify(dss, DigestType, DigestOrPlainText, Signature, [P, Q, G, Key]).
+verify(DigestOrPlainText, DigestType, Signature, Key) when is_binary(Signature) ->
+ do_verify(DigestOrPlainText, DigestType, Signature, Key);
+verify(_,_,_,_) ->
+ %% If Signature is a bitstring and not a binary we know already at this
+ %% point that the signature is invalid.
+ false.
%%--------------------------------------------------------------------
-spec pkix_dist_point(der_encoded() | #'OTPCertificate'{}) ->
@@ -530,7 +531,7 @@ pkix_sign(#'OTPTBSCertificate'{signature =
Signature = sign(Msg, DigestType, Key),
Cert = #'OTPCertificate'{tbsCertificate= TBSCert,
signatureAlgorithm = SigAlg,
- signature = {0, Signature}
+ signature = Signature
},
pkix_encode('OTPCertificate', Cert, otp).
@@ -720,7 +721,9 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) ->
%%--------------------------------------------------------------------
--spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}].
+-spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}]
+ ; (binary(), ssh2_pubkey) -> public_key()
+ .
%%
%% Description: Decodes a ssh file-binary. In the case of know_hosts
%% or auth_keys the binary may include one or more lines of the
@@ -733,12 +736,15 @@ ssh_decode(SshBin, Type) when is_binary(SshBin),
Type == rfc4716_public_key;
Type == openssh_public_key;
Type == auth_keys;
- Type == known_hosts ->
+ Type == known_hosts;
+ Type == ssh2_pubkey ->
pubkey_ssh:decode(SshBin, Type).
%%--------------------------------------------------------------------
--spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) ->
- binary().
+-spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) -> binary()
+ ; (public_key(), ssh2_pubkey) -> binary()
+ .
+%%
%% Description: Encodes a list of ssh file entries (public keys and
%% attributes) to a binary. Possible attributes depends on the file
%% type.
@@ -747,12 +753,49 @@ ssh_encode(Entries, Type) when is_list(Entries),
Type == rfc4716_public_key;
Type == openssh_public_key;
Type == auth_keys;
- Type == known_hosts ->
+ Type == known_hosts;
+ Type == ssh2_pubkey ->
pubkey_ssh:encode(Entries, Type).
%%--------------------------------------------------------------------
+-spec ssh_curvename2oid(binary()) -> oid().
+
+%% Description: Converts from the ssh name of elliptic curves to
+%% the OIDs.
+%%--------------------------------------------------------------------
+ssh_curvename2oid(<<"nistp256">>) -> ?'secp256r1';
+ssh_curvename2oid(<<"nistp384">>) -> ?'secp384r1';
+ssh_curvename2oid(<<"nistp521">>) -> ?'secp521r1'.
+
+%%--------------------------------------------------------------------
+-spec oid2ssh_curvename(oid()) -> binary().
+
+%% Description: Converts from elliptic curve OIDs to the ssh name.
+%%--------------------------------------------------------------------
+oid2ssh_curvename(?'secp256r1') -> <<"nistp256">>;
+oid2ssh_curvename(?'secp384r1') -> <<"nistp384">>;
+oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>.
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+do_verify(DigestOrPlainText, DigestType, Signature,
+ #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) ->
+ crypto:verify(rsa, DigestType, DigestOrPlainText, Signature,
+ [Exp, Mod]);
+
+do_verify(DigestOrPlaintext, DigestType, Signature, {#'ECPoint'{point = Point}, Param}) ->
+ ECCurve = ec_curve_spec(Param),
+ crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, [Point, ECCurve]);
+
+%% Backwards compatibility
+do_verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) ->
+ verify({digest,Digest}, sha, Signature, Key);
+
+do_verify(DigestOrPlainText, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}})
+ when is_integer(Key), is_binary(Signature) ->
+ crypto:verify(dss, DigestType, DigestOrPlainText, Signature, [P, Q, G, Key]).
+
do_pem_entry_encode(Asn1Type, Entity, CipherInfo, Password) ->
Der = der_encode(Asn1Type, Entity),
DecryptDer = pubkey_pem:cipher(Der, CipherInfo, Password),
@@ -985,14 +1028,14 @@ ec_generate_key(Params) ->
ec_curve_spec( #'ECParameters'{fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor }) ->
Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'FieldID'.fieldType),
FieldId#'FieldID'.parameters},
- Curve = {erlang:list_to_binary(PCurve#'Curve'.a), erlang:list_to_binary(PCurve#'Curve'.b), none},
- {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor};
+ Curve = {PCurve#'Curve'.a, PCurve#'Curve'.b, none},
+ {Field, Curve, Base, Order, CoFactor};
ec_curve_spec({namedCurve, OID}) ->
pubkey_cert_records:namedCurves(OID).
ec_key({PubKey, PrivateKey}, Params) ->
#'ECPrivateKey'{version = 1,
- privateKey = binary_to_list(PrivateKey),
+ privateKey = PrivateKey,
parameters = Params,
- publicKey = {0, PubKey}}.
+ publicKey = PubKey}.
diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile
index 929d321d69..a71004eb0d 100644
--- a/lib/public_key/test/Makefile
+++ b/lib/public_key/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl
index 5926794ca8..2039745f2b 100644
--- a/lib/public_key/test/erl_make_certs.erl
+++ b/lib/public_key/test/erl_make_certs.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -114,7 +115,7 @@ verify_signature(DerEncodedCert, DerKey, _KeyParams) ->
#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} ->
public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}});
#'ECPrivateKey'{version = _Version, privateKey = _PrivKey,
- parameters = Params, publicKey = {0, PubKey}} ->
+ parameters = Params, publicKey = PubKey} ->
public_key:pkix_verify(DerEncodedCert, {#'ECPoint'{point = PubKey}, Params})
end.
@@ -204,7 +205,7 @@ issuer_der(Issuer) ->
Subject.
subject(undefined, IsRootCA) ->
- User = if IsRootCA -> "RootCA"; true -> user() end,
+ User = if IsRootCA -> "RootCA"; true -> os:getenv("USER", "test_user") end,
Opts = [{email, User ++ "@erlang.org"},
{name, User},
{city, "Stockholm"},
@@ -215,14 +216,6 @@ subject(undefined, IsRootCA) ->
subject(Opts, _) ->
subject(Opts).
-user() ->
- case os:getenv("USER") of
- false ->
- "test_user";
- User ->
- User
- end.
-
subject(SubjectOpts) when is_list(SubjectOpts) ->
Encode = fun(Opt) ->
{Type,Value} = subject_enc(Opt),
@@ -267,9 +260,8 @@ default_extensions(Exts) ->
Filter = fun({Key, _}, D) -> lists:keydelete(Key, 1, D) end,
Exts ++ lists:foldl(Filter, Def, Exts).
-
-
extension({_, undefined}) -> [];
+
extension({basic_constraints, Data}) ->
case Data of
default ->
@@ -286,9 +278,11 @@ extension({basic_constraints, Data}) ->
#'Extension'{extnID = ?'id-ce-basicConstraints',
extnValue = Data}
end;
+
extension({key_usage, default}) ->
#'Extension'{extnID = ?'id-ce-keyUsage',
extnValue = [keyCertSign], critical = true};
+
extension({Id, Data, Critical}) ->
#'Extension'{extnID = Id, extnValue = Data, critical = Critical}.
@@ -305,7 +299,7 @@ publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) ->
publickey(#'ECPrivateKey'{version = _Version,
privateKey = _PrivKey,
parameters = Params,
- publicKey = {0, PubKey}}) ->
+ publicKey = PubKey}) ->
Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-ecPublicKey', parameters=Params},
#'OTPSubjectPublicKeyInfo'{algorithm = Algo,
subjectPublicKey = #'ECPoint'{point = PubKey}}.
@@ -330,14 +324,14 @@ sign_algorithm(#'RSAPrivateKey'{}, Opts) ->
{Type, 'NULL'};
sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) ->
{?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}};
-sign_algorithm(#'ECPrivateKey'{}, Opts) ->
+sign_algorithm(#'ECPrivateKey'{parameters = Parms}, Opts) ->
Type = case proplists:get_value(digest, Opts, sha1) of
sha1 -> ?'ecdsa-with-SHA1';
sha512 -> ?'ecdsa-with-SHA512';
sha384 -> ?'ecdsa-with-SHA384';
sha256 -> ?'ecdsa-with-SHA256'
end,
- {Type, 'NULL'}.
+ {Type, Parms}.
make_key(rsa, _Opts) ->
%% (OBS: for testing only)
@@ -414,9 +408,9 @@ gen_ec2(CurveId) ->
{PubKey, PrivKey} = crypto:generate_key(ecdh, CurveId),
#'ECPrivateKey'{version = 1,
- privateKey = binary_to_list(PrivKey),
+ privateKey = PrivKey,
parameters = {namedCurve, pubkey_cert_records:namedCurves(CurveId)},
- publicKey = {0, PubKey}}.
+ publicKey = PubKey}.
%% See fips_186-3.pdf
dsa_search(T, P0, Q, Iter) when Iter > 0 ->
@@ -485,5 +479,3 @@ der_to_pem(File, Entries) ->
PemBin = public_key:pem_encode(Entries),
file:write_file(File, PemBin).
-
-
diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl
index aa2bbdd24b..5e4720563f 100644
--- a/lib/public_key/test/pbe_SUITE.erl
+++ b/lib/public_key/test/pbe_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl
index 699481b20f..06dfce5018 100644
--- a/lib/public_key/test/pkits_SUITE.erl
+++ b/lib/public_key/test/pkits_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 40c28e86b3..ea5e036a7e 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,8 +49,10 @@ groups() ->
[{pem_decode_encode, [], [dsa_pem, rsa_pem, encrypted_pem,
dh_pem, cert_pem, pkcs7_pem, pkcs10_pem]},
{ssh_public_key_decode_encode, [],
- [ssh_rsa_public_key, ssh_dsa_public_key, ssh_rfc4716_rsa_comment,
- ssh_rfc4716_dsa_comment, ssh_rfc4716_rsa_subject, ssh_known_hosts,
+ [ssh_rsa_public_key, ssh_dsa_public_key, ssh_ecdsa_public_key,
+ ssh_rfc4716_rsa_comment, ssh_rfc4716_dsa_comment,
+ ssh_rfc4716_rsa_subject,
+ ssh_known_hosts,
ssh_auth_keys, ssh1_known_hosts, ssh1_auth_keys, ssh_openssh_public_key_with_comment,
ssh_openssh_public_key_long_header]},
{sign_verify, [], [rsa_sign_verify, dsa_sign_verify]}
@@ -186,6 +189,8 @@ encrypted_pem(Config) when is_list(Config) ->
erl_make_certs:der_to_pem(DesKeyFile, [Entry1]),
[{'RSAPrivateKey', _, {"DES-CBC", Salt1}} =Entry2] =
erl_make_certs:pem_to_der(DesKeyFile),
+ {ok, Pem} = file:read_file(DesKeyFile),
+ check_encapsulated_header(Pem),
true = check_entry_type(public_key:pem_entry_decode(Entry2, "4567efgh"),
'RSAPrivateKey').
@@ -290,6 +295,32 @@ ssh_dsa_public_key(Config) when is_list(Config) ->
public_key:ssh_decode(EncodedOpenSsh, public_key).
%%--------------------------------------------------------------------
+
+ssh_ecdsa_public_key() ->
+ [{doc, "ssh ecdsa public key decode/encode"}].
+ssh_ecdsa_public_key(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, ECDSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_ecdsa_pub")),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(ECDSARawSsh2, public_key),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(ECDSARawSsh2, rfc4716_public_key),
+
+ {ok, ECDSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_ecdsa_pub")),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(ECDSARawOpenSsh, public_key),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(ECDSARawOpenSsh, openssh_public_key),
+
+ %% Can not check EncodedSSh == ECDSARawSsh2 and EncodedOpenSsh
+ %% = ECDSARawOpenSsh as line breakpoints may differ
+
+ EncodedSSh = public_key:ssh_encode([{PubKey, Attributes1}], rfc4716_public_key),
+ EncodedOpenSsh = public_key:ssh_encode([{PubKey, Attributes2}], openssh_public_key),
+
+ [{PubKey, Attributes1}] =
+ public_key:ssh_decode(EncodedSSh, public_key),
+ [{PubKey, Attributes2}] =
+ public_key:ssh_decode(EncodedOpenSsh, public_key).
+
+%%--------------------------------------------------------------------
ssh_rfc4716_rsa_comment() ->
[{doc, "Test comment header and rsa key"}].
ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
@@ -797,6 +828,15 @@ check_entry_type(#'Certificate'{}, 'Certificate') ->
check_entry_type(_,_) ->
false.
+check_encapsulated_header(Pem) when is_binary(Pem)->
+ check_encapsulated_header( binary:split(Pem, <<"\n">>, [global]));
+check_encapsulated_header([<<"DEK-Info: DES-CBC,FB7577791A9056A1">>, <<>> | _]) ->
+ true;
+check_encapsulated_header([ _ | Rest]) ->
+ check_encapsulated_header(Rest);
+check_encapsulated_header([]) ->
+ false.
+
strip_ending_newlines(Bin) ->
string:strip(binary_to_list(Bin), right, 10).
diff --git a/lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub b/lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub
new file mode 100644
index 0000000000..a49b4264b8
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIJrVlKYIT+MlxxRx5BFXisHHkcGMAAKv2dguUeOsutsYyzs9JAczvl6c+Sypra5+qOi2LHPXw6GGluuXcOssOM= uabhnil@elxadlj3q32
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub
new file mode 100644
index 0000000000..702e5c4fde
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub
@@ -0,0 +1,6 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: "256-bit ECDSA, converted by uabhnil@elxadlj3q32 from OpenSSH"
+AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIJrVlKYIT+MlxxRx5
+BFXisHHkcGMAAKv2dguUeOsutsYyzs9JAczvl6c+Sypra5+qOi2LHPXw6GGluuXcOssOM=
+
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index 16794660a5..f801f55073 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 0.23
+PUBLIC_KEY_VSN = 1.1.1
diff --git a/lib/reltool/Makefile b/lib/reltool/Makefile
index c3f6d855b4..6732f52d15 100644
--- a/lib/reltool/Makefile
+++ b/lib/reltool/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/reltool/bin/reltool.escript b/lib/reltool/bin/reltool.escript
index 0dcd5ad1e9..dd8f931251 100755
--- a/lib/reltool/bin/reltool.escript
+++ b/lib/reltool/bin/reltool.escript
@@ -5,16 +5,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/doc/src/Makefile b/lib/reltool/doc/src/Makefile
index 2373b5e507..b019c25080 100644
--- a/lib/reltool/doc/src/Makefile
+++ b/lib/reltool/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/reltool/doc/src/book.xml b/lib/reltool/doc/src/book.xml
index 660c81ddb6..c6bbef3655 100644
--- a/lib/reltool/doc/src/book.xml
+++ b/lib/reltool/doc/src/book.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/doc/src/files.mk b/lib/reltool/doc/src/files.mk
index 07b52f4934..b61707e8fe 100644
--- a/lib/reltool/doc/src/files.mk
+++ b/lib/reltool/doc/src/files.mk
@@ -4,16 +4,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index 18b36ff953..745185af27 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -37,7 +38,23 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.6.6</title>
+ <section><title>Reltool 0.7</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.6.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/reltool/doc/src/part.xml b/lib/reltool/doc/src/part.xml
index 8f4f3731b8..029c35dc0c 100644
--- a/lib/reltool/doc/src/part.xml
+++ b/lib/reltool/doc/src/part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/doc/src/ref_man.xml b/lib/reltool/doc/src/ref_man.xml
index 28e4ccfb28..17bc76b841 100644
--- a/lib/reltool/doc/src/ref_man.xml
+++ b/lib/reltool/doc/src/ref_man.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml
index c08d4228f0..82a410e3e7 100644
--- a/lib/reltool/doc/src/reltool.xml
+++ b/lib/reltool/doc/src/reltool.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml
index e56a59bfd5..6c28674a69 100644
--- a/lib/reltool/doc/src/reltool_examples.xml
+++ b/lib/reltool/doc/src/reltool_examples.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may noot use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/doc/src/reltool_intro.xml b/lib/reltool/doc/src/reltool_intro.xml
index ddba29e3f4..e72b9029b1 100644
--- a/lib/reltool/doc/src/reltool_intro.xml
+++ b/lib/reltool/doc/src/reltool_intro.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/doc/src/reltool_usage.xml b/lib/reltool/doc/src/reltool_usage.xml
index fa82b8c7d9..2adef96073 100644
--- a/lib/reltool/doc/src/reltool_usage.xml
+++ b/lib/reltool/doc/src/reltool_usage.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/reltool/examples/Makefile b/lib/reltool/examples/Makefile
index 0b495b14b7..5f2d97b439 100644
--- a/lib/reltool/examples/Makefile
+++ b/lib/reltool/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile
index b8387fff96..1fea41550c 100644
--- a/lib/reltool/src/Makefile
+++ b/lib/reltool/src/Makefile
@@ -3,16 +3,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/reltool/src/files.mk b/lib/reltool/src/files.mk
index 99a1f1c14a..a7ef5d05e2 100644
--- a/lib/reltool/src/files.mk
+++ b/lib/reltool/src/files.mk
@@ -3,16 +3,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/reltool/src/reltool.app.src b/lib/reltool/src/reltool.app.src
index 65fcf4aae5..8aef4c1dbb 100644
--- a/lib/reltool/src/reltool.app.src
+++ b/lib/reltool/src/reltool.app.src
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -36,5 +37,5 @@
{applications, [stdlib, kernel]},
{env, []},
{runtime_dependencies, ["wx-1.2","tools-2.6.14","stdlib-2.0","sasl-2.4",
- "kernel-3.0","erts-6.0"]}
+ "kernel-3.0","erts-7.0"]}
]}.
diff --git a/lib/reltool/src/reltool.appup.src b/lib/reltool/src/reltool.appup.src
index 79ecdbd392..bcd84183ba 100644
--- a/lib/reltool/src/reltool.appup.src
+++ b/lib/reltool/src/reltool.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/reltool/src/reltool.erl b/lib/reltool/src/reltool.erl
index 8ab2c2399e..269b44b709 100644
--- a/lib/reltool/src/reltool.erl
+++ b/lib/reltool/src/reltool.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl
index 56161a152a..4c3f76bdc6 100644
--- a/lib/reltool/src/reltool.hrl
+++ b/lib/reltool/src/reltool.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_app_win.erl b/lib/reltool/src/reltool_app_win.erl
index 81ab1687fb..5c623c2835 100644
--- a/lib/reltool/src/reltool_app_win.erl
+++ b/lib/reltool/src/reltool_app_win.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_fgraph.erl b/lib/reltool/src/reltool_fgraph.erl
index 2e8f39e418..afdbe78c19 100644
--- a/lib/reltool/src/reltool_fgraph.erl
+++ b/lib/reltool/src/reltool_fgraph.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_fgraph.hrl b/lib/reltool/src/reltool_fgraph.hrl
index 3eba93e3a8..6056ccbd02 100644
--- a/lib/reltool/src/reltool_fgraph.hrl
+++ b/lib/reltool/src/reltool_fgraph.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/reltool/src/reltool_fgraph_win.erl b/lib/reltool/src/reltool_fgraph_win.erl
index 66bc2b5ab3..6b58cae187 100644
--- a/lib/reltool/src/reltool_fgraph_win.erl
+++ b/lib/reltool/src/reltool_fgraph_win.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -252,10 +253,10 @@ ticker_init(Pid) ->
ticker_loop(Pid, Time) ->
receive after Time ->
Pid ! {self(), redraw},
- T0 = now(),
+ T0 = erlang:monotonic_time(),
receive {Pid, ok} -> ok end,
- T1 = now(),
- D = timer:now_diff(T1, T0)/1000,
+ T1 = erlang:monotonic_time(),
+ D = erlang:convert_time_unit(T1-T0, native, milli_seconds),
case round(40 - D) of
Ms when Ms < 0 ->
%io:format("ticker: wait is 0 ms [fg ~7s ms] [fps ~7s]~n",
diff --git a/lib/reltool/src/reltool_mod_win.erl b/lib/reltool/src/reltool_mod_win.erl
index b0193a2ae4..1788841ae7 100644
--- a/lib/reltool/src/reltool_mod_win.erl
+++ b/lib/reltool/src/reltool_mod_win.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index e7af4bd3f7..1f0e5bc476 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_sys_win.erl b/lib/reltool/src/reltool_sys_win.erl
index b5d54e6d3e..03f206ef64 100644
--- a/lib/reltool/src/reltool_sys_win.erl
+++ b/lib/reltool/src/reltool_sys_win.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl
index b59108d8dd..0728398db3 100644
--- a/lib/reltool/src/reltool_target.erl
+++ b/lib/reltool/src/reltool_target.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl
index 5a3f34506d..1879e77a54 100644
--- a/lib/reltool/src/reltool_utils.erl
+++ b/lib/reltool/src/reltool_utils.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -54,12 +55,7 @@ root_dir() ->
code:root_dir().
erl_libs() ->
- case os:getenv("ERL_LIBS") of
- false ->
- [];
- LibStr ->
- string:tokens(LibStr, ":;")
- end.
+ string:tokens(os:getenv("ERL_LIBS", ""), ":;").
lib_dirs(Dir) ->
case erl_prim_loader:list_dir(Dir) of
diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile
index 52cdef44da..ccb3d7dc55 100644
--- a/lib/reltool/test/Makefile
+++ b/lib/reltool/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/reltool/test/reltool_app_SUITE.erl b/lib/reltool/test/reltool_app_SUITE.erl
index 9abc7fea41..35971a9a3c 100644
--- a/lib/reltool/test/reltool_app_SUITE.erl
+++ b/lib/reltool/test/reltool_app_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/reltool/test/reltool_manual_gui_SUITE.erl b/lib/reltool/test/reltool_manual_gui_SUITE.erl
index 0dcc5cbf15..7800b7d031 100644
--- a/lib/reltool/test/reltool_manual_gui_SUITE.erl
+++ b/lib/reltool/test/reltool_manual_gui_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a.erl b/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a.erl
index bb500bed69..383ecbcfb8 100644
--- a/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a.erl
+++ b/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl b/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
index a141c1767b..8de9534cc3 100644
--- a/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
+++ b/lib/reltool/test/reltool_manual_gui_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index 347e80ed7c..6a487a1ddb 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -1205,14 +1206,9 @@ create_slim(Config) ->
RootDir = code:root_dir(),
Erl = filename:join([RootDir, "bin", "erl"]),
- EscapedQuote =
- case os:type() of
- {win32,_} -> "\\\"";
- _ -> "\""
- end,
Args = ["-boot_var", "RELTOOL_EXT_LIB", TargetLibDir,
"-boot", filename:join(TargetRelVsnDir,RelName),
- "-sasl", "releases_dir", EscapedQuote++TargetRelDir++EscapedQuote],
+ "-sasl", "releases_dir", "\""++TargetRelDir++"\""],
{ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl, Args)),
?msym(RootDir, rpc:call(Node, code, root_dir, [])),
wait_for_app(Node,sasl,50),
@@ -2518,10 +2514,7 @@ undefined_regexp(_Config) ->
%% Library functions
erl_libs() ->
- case os:getenv("ERL_LIBS") of
- false -> [];
- LibStr -> string:tokens(LibStr, ":;")
- end.
+ string:tokens(os:getenv("ERL_LIBS", ""), ":;").
datadir(Config) ->
%% Removes the trailing slash...
diff --git a/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl b/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl
index c315f926d3..ee5594c04f 100644
--- a/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl
+++ b/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl
index bb500bed69..383ecbcfb8 100644
--- a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl
+++ b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
index a141c1767b..8de9534cc3 100644
--- a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
+++ b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl
index bb500bed69..383ecbcfb8 100644
--- a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl
+++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl
index a141c1767b..8de9534cc3 100644
--- a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl
+++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl
index fa12f19aa7..10546f9915 100644
--- a/lib/reltool/test/reltool_test_lib.erl
+++ b/lib/reltool/test/reltool_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/test/reltool_test_lib.hrl b/lib/reltool/test/reltool_test_lib.hrl
index 0dfc08b81c..87a5d7bd1a 100644
--- a/lib/reltool/test/reltool_test_lib.hrl
+++ b/lib/reltool/test/reltool_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/reltool/test/reltool_wx_SUITE.erl b/lib/reltool/test/reltool_wx_SUITE.erl
index 13d71f4fd6..f2f1693483 100644
--- a/lib/reltool/test/reltool_wx_SUITE.erl
+++ b/lib/reltool/test/reltool_wx_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/reltool/test/rtt b/lib/reltool/test/rtt
index 1f93396196..8de2ea32ac 100755
--- a/lib/reltool/test/rtt
+++ b/lib/reltool/test/rtt
@@ -3,16 +3,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/reltool/test/rtt.erl b/lib/reltool/test/rtt.erl
index 437009e26a..5b3c84b06a 100644
--- a/lib/reltool/test/rtt.erl
+++ b/lib/reltool/test/rtt.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 4fc1534250..733c41bc02 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.6.6
+RELTOOL_VSN = 0.7
diff --git a/lib/runtime_tools/Makefile b/lib/runtime_tools/Makefile
index 0094bb036d..75174d3bca 100644
--- a/lib/runtime_tools/Makefile
+++ b/lib/runtime_tools/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/runtime_tools/c_src/Makefile.in b/lib/runtime_tools/c_src/Makefile.in
index d46b4997f7..448b8c62c2 100644
--- a/lib/runtime_tools/c_src/Makefile.in
+++ b/lib/runtime_tools/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/runtime_tools/c_src/dtrace_user.d b/lib/runtime_tools/c_src/dtrace_user.d
index 9e180a3cb2..09597f3e89 100644
--- a/lib/runtime_tools/c_src/dtrace_user.d
+++ b/lib/runtime_tools/c_src/dtrace_user.d
@@ -4,16 +4,17 @@
* Copyright Scott Lystig Fritchie 2011-2012.
* All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/c_src/dyntrace.c b/lib/runtime_tools/c_src/dyntrace.c
index 18f91cd7e7..e9bcc161c5 100644
--- a/lib/runtime_tools/c_src/dyntrace.c
+++ b/lib/runtime_tools/c_src/dyntrace.c
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/c_src/trace_file_drv.c b/lib/runtime_tools/c_src/trace_file_drv.c
index 08bace80ef..8863b0d6ac 100644
--- a/lib/runtime_tools/c_src/trace_file_drv.c
+++ b/lib/runtime_tools/c_src/trace_file_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -74,12 +75,8 @@
#ifdef DEBUG
-#ifndef __WIN32__
-#define ASSERT(X) do {if (!(X)) {erl_exit(1,"%s",#X);} } while(0)
-#else
#include <assert.h>
#define ASSERT(X) assert(X)
-#endif
#else
#define ASSERT(X)
#endif
@@ -326,9 +323,11 @@ static ErlDrvData trace_file_start(ErlDrvPort port, char *buff)
| O_BINARY
#endif
, 0777)) < 0) {
+ int saved_errno = errno;
if (wrap)
driver_free(wrap);
driver_free(data);
+ errno = saved_errno;
return ERL_DRV_ERROR_ERRNO;
}
@@ -524,14 +523,19 @@ static void *my_alloc(size_t size)
** A write wrapper that regards it as an error if not all data was written.
*/
static int do_write(FILETYPE fd, unsigned char *buff, int siz) {
- int w = write(fd, buff, siz);
- if (w != siz) {
- if (w >= 0) {
- errno = ENOSPC;
+ int w;
+ while (1) {
+ w = write(fd, buff, siz);
+ if (w < 0 && errno == EINTR)
+ continue;
+ else if (w != siz) {
+ if (w >= 0) {
+ errno = ENOSPC;
+ }
+ return -1;
}
- return -1;
+ return siz;
}
- return siz;
}
/*
@@ -626,8 +630,10 @@ static void close_unlink_port(TraceFileData *data)
*/
static int wrap_file(TraceFileData *data) {
if (my_flush(data) < 0) {
+ int saved_errno = errno;
close(data->fd);
data->fd = -1;
+ errno = saved_errno;
return -1;
}
close(data->fd);
@@ -643,12 +649,15 @@ static int wrap_file(TraceFileData *data) {
next_name(&data->wrap->del);
}
next_name(&data->wrap->cur);
+try_open:
data->fd = open(data->wrap->cur.name, O_WRONLY | O_TRUNC | O_CREAT
#ifdef O_BINARY
| O_BINARY
#endif
, 0777);
if (data->fd < 0) {
+ if (errno == EINTR)
+ goto try_open;
data->fd = -1;
return -1;
}
diff --git a/lib/runtime_tools/c_src/trace_ip_drv.c b/lib/runtime_tools/c_src/trace_ip_drv.c
index a7d132ca6e..5b43f8179e 100644
--- a/lib/runtime_tools/c_src/trace_ip_drv.c
+++ b/lib/runtime_tools/c_src/trace_ip_drv.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1999-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -43,19 +44,8 @@
#endif
#ifdef DEBUG
-# ifndef __WIN32__
- /* erl_exit is not available to dll_drivers on windows. */
- void erl_exit(int, char *, ...);
-# define ASSERT(X) \
- do { \
- if (!(X)) { \
- erl_exit(1,"%s",#X); \
- } \
- } while(0)
-# else
-# include <assert.h>
-# define ASSERT(X) assert(X)
-# endif
+# include <assert.h>
+# define ASSERT(X) assert(X)
#else
# define ASSERT(X)
#endif
diff --git a/lib/runtime_tools/doc/src/Makefile b/lib/runtime_tools/doc/src/Makefile
index 07c63197e9..0292333f0a 100644
--- a/lib/runtime_tools/doc/src/Makefile
+++ b/lib/runtime_tools/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/runtime_tools/doc/src/book.xml b/lib/runtime_tools/doc/src/book.xml
index d3c462c0ad..0e75ec28bb 100644
--- a/lib/runtime_tools/doc/src/book.xml
+++ b/lib/runtime_tools/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/dbg.xml b/lib/runtime_tools/doc/src/dbg.xml
index d31ccd834d..2065627026 100644
--- a/lib/runtime_tools/doc/src/dbg.xml
+++ b/lib/runtime_tools/doc/src/dbg.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -167,7 +168,8 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
<item>If the <c>Item</c> is a <c>pid()</c>, the corresponding
process is traced. The process may be a remote process
(on another Erlang node). The node must be in the list of
- traced nodes (<seealso marker="#n">see</seealso><c>n/1</c> and <c>tracer/0/2/3</c>).</item>
+ traced nodes (see <seealso marker="#n"><c>n/1</c></seealso> and
+ <c>tracer/0/2/3</c>).</item>
<item>If the <c>Item</c> is the atom <c>all</c>, all processes in the
system as well as all processes created hereafter are
to be traced. This also affects all nodes added with the
@@ -648,7 +650,7 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
<p>If <c>Nodename</c> is the local node, the error reason
<c>cant_add_local_node</c> is returned.
</p>
- <p>If a trace port (<seealso marker="#trace_port">see</seealso><c>trace_port/2</c>) is
+ <p>If a trace port (see <seealso marker="#trace_port"><c>trace_port/2</c></seealso>) is
running on the local node, remote nodes can not be traced with
a tracer process. The error reason
<c>cant_trace_remote_pid_to_local_port</c> is returned. A
@@ -761,7 +763,7 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
type which is independent of the tracer on the trace control
node.</p>
</note>
- <p>For details, <seealso marker="#tracer2">see</seealso><c>tracer/2</c>.</p>
+ <p>For details, see <seealso marker="#tracer2"><c>tracer/2</c></seealso>.</p>
</desc>
</func>
<func>
@@ -1028,9 +1030,9 @@ hello</pre>
<fsummary>Stop the <c>dbg</c>server and the tracing of all processes.</fsummary>
<desc>
<p>Stops the <c>dbg</c> server and clears all trace flags for
- all processes and all trace patterns for all functions. Also
+ all processes and all local trace patterns for all functions. Also
shuts down all trace clients and closes all trace ports.</p>
- <p>Note that no trace patterns are affected by this
+ <p>Note that no global trace patterns are affected by this
function.</p>
</desc>
</func>
@@ -1038,8 +1040,7 @@ hello</pre>
<name>stop_clear() -> ok</name>
<fsummary>Stop the <c>dbg</c>server and the tracing of all processes, and clears trace patterns.</fsummary>
<desc>
- <p>Same as stop/0, but also clears all trace patterns on local
- and global functions calls.</p>
+ <p>Same as stop/0, but also clears all trace patterns on global functions calls.</p>
</desc>
</func>
</funcs>
diff --git a/lib/runtime_tools/doc/src/dyntrace.xml b/lib/runtime_tools/doc/src/dyntrace.xml
index 25f750677f..edf08e7753 100644
--- a/lib/runtime_tools/doc/src/dyntrace.xml
+++ b/lib/runtime_tools/doc/src/dyntrace.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/erts_alloc_config.xml b/lib/runtime_tools/doc/src/erts_alloc_config.xml
index 31145bee63..6a6ad93d48 100644
--- a/lib/runtime_tools/doc/src/erts_alloc_config.xml
+++ b/lib/runtime_tools/doc/src/erts_alloc_config.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index 1612c62c98..24b589b928 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,69 @@
<p>This document describes the changes made to the Runtime_Tools
application.</p>
+<section><title>Runtime_Tools 1.9.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p><c>dbg:trace_client()</c> now uses a read buffer to
+ speed up reading of trace files.</p>
+ <p>
+ Own Id: OTP-13279</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Runtime_Tools 1.9.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Clarified dbg:stop documentation</p>
+ <p>
+ Own Id: OTP-13078</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Runtime_Tools 1.9.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The <c>trace_file_drv</c> did not handle <c>EINTR</c>
+ correct which caused it to fail when the runtime system
+ received a signal.</p>
+ <p>
+ Own Id: OTP-12890 Aux Id: seq12885 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Runtime_Tools 1.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change license text from Erlang Public License to Apache
+ Public License v2</p>
+ <p>
+ Own Id: OTP-12845</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Runtime_Tools 1.8.16</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/runtime_tools/doc/src/notes_history.xml b/lib/runtime_tools/doc/src/notes_history.xml
index aba9f47cbf..853a5eece0 100644
--- a/lib/runtime_tools/doc/src/notes_history.xml
+++ b/lib/runtime_tools/doc/src/notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/part.xml b/lib/runtime_tools/doc/src/part.xml
index d81eed6515..c0a9e63331 100644
--- a/lib/runtime_tools/doc/src/part.xml
+++ b/lib/runtime_tools/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/part_notes.xml b/lib/runtime_tools/doc/src/part_notes.xml
index 395de39ac7..7a452aa79a 100644
--- a/lib/runtime_tools/doc/src/part_notes.xml
+++ b/lib/runtime_tools/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/part_notes_history.xml b/lib/runtime_tools/doc/src/part_notes_history.xml
index 46a6baa45e..545d3dacfe 100644
--- a/lib/runtime_tools/doc/src/part_notes_history.xml
+++ b/lib/runtime_tools/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/ref_man.xml b/lib/runtime_tools/doc/src/ref_man.xml
index 25fa97896b..ea0c0832a4 100644
--- a/lib/runtime_tools/doc/src/ref_man.xml
+++ b/lib/runtime_tools/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/runtime_tools_app.xml b/lib/runtime_tools/doc/src/runtime_tools_app.xml
index 4b030b09af..fb02d678cc 100644
--- a/lib/runtime_tools/doc/src/runtime_tools_app.xml
+++ b/lib/runtime_tools/doc/src/runtime_tools_app.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/runtime_tools/doc/src/system_information.xml b/lib/runtime_tools/doc/src/system_information.xml
index b586334ae7..1c33ff1a40 100644
--- a/lib/runtime_tools/doc/src/system_information.xml
+++ b/lib/runtime_tools/doc/src/system_information.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/runtime_tools/examples/dist.d b/lib/runtime_tools/examples/dist.d
index 7e2d7f0e35..e9323eec8f 100644
--- a/lib/runtime_tools/examples/dist.d
+++ b/lib/runtime_tools/examples/dist.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/dist.systemtap b/lib/runtime_tools/examples/dist.systemtap
index 8935e19e28..f2fcd189b5 100644
--- a/lib/runtime_tools/examples/dist.systemtap
+++ b/lib/runtime_tools/examples/dist.systemtap
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/driver1.d b/lib/runtime_tools/examples/driver1.d
index 4871a8ee69..b873f9c0d8 100644
--- a/lib/runtime_tools/examples/driver1.d
+++ b/lib/runtime_tools/examples/driver1.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/driver1.systemtap b/lib/runtime_tools/examples/driver1.systemtap
index deae82f8fb..71e1a0fa34 100644
--- a/lib/runtime_tools/examples/driver1.systemtap
+++ b/lib/runtime_tools/examples/driver1.systemtap
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/efile_drv.d b/lib/runtime_tools/examples/efile_drv.d
index 2442222552..c6f9d3ba52 100644
--- a/lib/runtime_tools/examples/efile_drv.d
+++ b/lib/runtime_tools/examples/efile_drv.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/efile_drv.systemtap b/lib/runtime_tools/examples/efile_drv.systemtap
index 4b92e67048..12bd7a14a3 100644
--- a/lib/runtime_tools/examples/efile_drv.systemtap
+++ b/lib/runtime_tools/examples/efile_drv.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/function-calls.d b/lib/runtime_tools/examples/function-calls.d
index ec6090553e..2de7fe64dd 100644
--- a/lib/runtime_tools/examples/function-calls.d
+++ b/lib/runtime_tools/examples/function-calls.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/function-calls.systemtap b/lib/runtime_tools/examples/function-calls.systemtap
index 4de54cfb5a..30d77e4e66 100644
--- a/lib/runtime_tools/examples/function-calls.systemtap
+++ b/lib/runtime_tools/examples/function-calls.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/garbage-collection.d b/lib/runtime_tools/examples/garbage-collection.d
index ebc40a19ec..3878858765 100644
--- a/lib/runtime_tools/examples/garbage-collection.d
+++ b/lib/runtime_tools/examples/garbage-collection.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/garbage-collection.systemtap b/lib/runtime_tools/examples/garbage-collection.systemtap
index 81e9d38196..cbe949120a 100644
--- a/lib/runtime_tools/examples/garbage-collection.systemtap
+++ b/lib/runtime_tools/examples/garbage-collection.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/memory1.d b/lib/runtime_tools/examples/memory1.d
index b222aeae62..64e524b419 100644
--- a/lib/runtime_tools/examples/memory1.d
+++ b/lib/runtime_tools/examples/memory1.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/memory1.systemtap b/lib/runtime_tools/examples/memory1.systemtap
index 9374b97d18..850ebbbf53 100644
--- a/lib/runtime_tools/examples/memory1.systemtap
+++ b/lib/runtime_tools/examples/memory1.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/messages.d b/lib/runtime_tools/examples/messages.d
index 08cf52f3d2..62851a7697 100644
--- a/lib/runtime_tools/examples/messages.d
+++ b/lib/runtime_tools/examples/messages.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/messages.systemtap b/lib/runtime_tools/examples/messages.systemtap
index c58e1168f9..4f3da9986c 100644
--- a/lib/runtime_tools/examples/messages.systemtap
+++ b/lib/runtime_tools/examples/messages.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/port1.d b/lib/runtime_tools/examples/port1.d
index 1e3bd3d8a9..3531cb3398 100644
--- a/lib/runtime_tools/examples/port1.d
+++ b/lib/runtime_tools/examples/port1.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/port1.systemtap b/lib/runtime_tools/examples/port1.systemtap
index c8af240d85..4561686a80 100644
--- a/lib/runtime_tools/examples/port1.systemtap
+++ b/lib/runtime_tools/examples/port1.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/process-scheduling.d b/lib/runtime_tools/examples/process-scheduling.d
index 6408d7d5f2..1acee4fbf2 100644
--- a/lib/runtime_tools/examples/process-scheduling.d
+++ b/lib/runtime_tools/examples/process-scheduling.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/process-scheduling.systemtap b/lib/runtime_tools/examples/process-scheduling.systemtap
index 4cc3ef555c..ab95d44d40 100644
--- a/lib/runtime_tools/examples/process-scheduling.systemtap
+++ b/lib/runtime_tools/examples/process-scheduling.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/spawn-exit.d b/lib/runtime_tools/examples/spawn-exit.d
index ae690b819a..2ac79dc4f0 100644
--- a/lib/runtime_tools/examples/spawn-exit.d
+++ b/lib/runtime_tools/examples/spawn-exit.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/spawn-exit.systemtap b/lib/runtime_tools/examples/spawn-exit.systemtap
index 4b69e4aea6..ae3f0f1b06 100644
--- a/lib/runtime_tools/examples/spawn-exit.systemtap
+++ b/lib/runtime_tools/examples/spawn-exit.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/user-probe-n.d b/lib/runtime_tools/examples/user-probe-n.d
index 06a3e5c9b9..0f83b5bf3c 100644
--- a/lib/runtime_tools/examples/user-probe-n.d
+++ b/lib/runtime_tools/examples/user-probe-n.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/user-probe-n.systemtap b/lib/runtime_tools/examples/user-probe-n.systemtap
index 6aa415bb67..48335ff41e 100644
--- a/lib/runtime_tools/examples/user-probe-n.systemtap
+++ b/lib/runtime_tools/examples/user-probe-n.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/user-probe.d b/lib/runtime_tools/examples/user-probe.d
index 5cb5d61a76..6adfb10cd8 100644
--- a/lib/runtime_tools/examples/user-probe.d
+++ b/lib/runtime_tools/examples/user-probe.d
@@ -4,16 +4,17 @@
*
* Copyright Scott Lystig Fritchie 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/examples/user-probe.systemtap b/lib/runtime_tools/examples/user-probe.systemtap
index 0482235324..b599422c70 100644
--- a/lib/runtime_tools/examples/user-probe.systemtap
+++ b/lib/runtime_tools/examples/user-probe.systemtap
@@ -3,16 +3,17 @@
*
* Copyright Scott Lystig Fritchie and Andreas Schultz, 2011-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/runtime_tools/include/observer_backend.hrl b/lib/runtime_tools/include/observer_backend.hrl
index 91647a4468..a2598f03c7 100644
--- a/lib/runtime_tools/include/observer_backend.hrl
+++ b/lib/runtime_tools/include/observer_backend.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/runtime_tools/src/Makefile b/lib/runtime_tools/src/Makefile
index 8d2bcfe3d1..99b90f9ec5 100644
--- a/lib/runtime_tools/src/Makefile
+++ b/lib/runtime_tools/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/runtime_tools/src/appmon_info.erl b/lib/runtime_tools/src/appmon_info.erl
index a728312c97..dd4dc34fcb 100644
--- a/lib/runtime_tools/src/appmon_info.erl
+++ b/lib/runtime_tools/src/appmon_info.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl
index c2de57d40b..6eea1a0917 100644
--- a/lib/runtime_tools/src/dbg.erl
+++ b/lib/runtime_tools/src/dbg.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1268,13 +1269,15 @@ gen_reader(follow_file, Filename) ->
%% Opens a file and returns a reader (lazy list).
gen_reader_file(ReadFun, Filename) ->
- case file:open(Filename, [read, raw, binary]) of
+ case file:open(Filename, [read, raw, binary, read_ahead]) of
{ok, File} ->
mk_reader(ReadFun, File);
Error ->
exit({client_cannot_open, Error})
end.
+-dialyzer({no_improper_lists, mk_reader/2}).
+
%% Creates and returns a reader (lazy list).
mk_reader(ReadFun, Source) ->
fun() ->
@@ -1293,13 +1296,15 @@ mk_reader(ReadFun, Source) ->
mk_reader_wrap([]) ->
[];
mk_reader_wrap([Hd | _] = WrapFiles) ->
- case file:open(wrap_name(Hd), [read, raw, binary]) of
+ case file:open(wrap_name(Hd), [read, raw, binary, read_ahead]) of
{ok, File} ->
mk_reader_wrap(WrapFiles, File);
Error ->
exit({client_cannot_open, Error})
end.
+-dialyzer({no_improper_lists, mk_reader_wrap/2}).
+
mk_reader_wrap([_Hd | Tail] = WrapFiles, File) ->
fun() ->
case read_term(fun file_read/2, File) of
diff --git a/lib/runtime_tools/src/erts_alloc_config.erl b/lib/runtime_tools/src/erts_alloc_config.erl
index b9a26dc0dc..85aacdd6e1 100644
--- a/lib/runtime_tools/src/erts_alloc_config.erl
+++ b/lib/runtime_tools/src/erts_alloc_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%
diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl
index fea0854042..9177752cef 100644
--- a/lib/runtime_tools/src/observer_backend.erl
+++ b/lib/runtime_tools/src/observer_backend.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -248,7 +249,7 @@ etop_collect(Collector) ->
SchedulerWallTime = erlang:statistics(scheduler_wall_time),
ProcInfo = etop_collect(processes(), []),
- Collector ! {self(),#etop_info{now = now(),
+ Collector ! {self(),#etop_info{now = erlang:timestamp(),
n_procs = length(ProcInfo),
run_queue = erlang:statistics(run_queue),
runtime = SchedulerWallTime,
diff --git a/lib/runtime_tools/src/percept_profile.erl b/lib/runtime_tools/src/percept_profile.erl
index cdc7a0fca1..d5ea2c7032 100644
--- a/lib/runtime_tools/src/percept_profile.erl
+++ b/lib/runtime_tools/src/percept_profile.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -119,7 +120,7 @@ stop() ->
undefined ->
{error, not_started};
Port ->
- erlang:port_command(Port, erlang:term_to_binary({profile_stop, erlang:now()})),
+ erlang:port_command(Port, erlang:term_to_binary({profile_stop, erlang:timestamp()})),
%% trace delivered?
erlang:port_close(Port),
ok
@@ -139,7 +140,7 @@ profile_to_file(Filename, Opts) ->
erlang:system_flag(multi_scheduling, block),
Port = (dbg:trace_port(file, Filename))(),
% Send start time
- erlang:port_command(Port, erlang:term_to_binary({profile_start, erlang:now()})),
+ erlang:port_command(Port, erlang:term_to_binary({profile_start, erlang:timestamp()})),
erlang:system_flag(multi_scheduling, unblock),
%% Register Port
diff --git a/lib/runtime_tools/src/runtime_tools.app.src b/lib/runtime_tools/src/runtime_tools.app.src
index 0a70802c08..ad10655aa0 100644
--- a/lib/runtime_tools/src/runtime_tools.app.src
+++ b/lib/runtime_tools/src/runtime_tools.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -27,6 +28,6 @@
{env, []},
{mod, {runtime_tools, []}},
{runtime_dependencies, ["stdlib-2.0","mnesia-4.12","kernel-3.0",
- "erts-6.0"]}]}.
+ "erts-7.0"]}]}.
diff --git a/lib/runtime_tools/src/runtime_tools.appup.src b/lib/runtime_tools/src/runtime_tools.appup.src
index 0c2bab316f..883ff1e074 100644
--- a/lib/runtime_tools/src/runtime_tools.appup.src
+++ b/lib/runtime_tools/src/runtime_tools.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/runtime_tools/src/runtime_tools.erl b/lib/runtime_tools/src/runtime_tools.erl
index 2181244610..62b9dfd71e 100644
--- a/lib/runtime_tools/src/runtime_tools.erl
+++ b/lib/runtime_tools/src/runtime_tools.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/runtime_tools/src/runtime_tools_sup.erl b/lib/runtime_tools/src/runtime_tools_sup.erl
index 32770397dd..e69b495cb5 100644
--- a/lib/runtime_tools/src/runtime_tools_sup.erl
+++ b/lib/runtime_tools/src/runtime_tools_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/runtime_tools/src/system_information.erl b/lib/runtime_tools/src/system_information.erl
index 04cc33e1ad..ad7ee7311c 100644
--- a/lib/runtime_tools/src/system_information.erl
+++ b/lib/runtime_tools/src/system_information.erl
@@ -2,16 +2,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -577,10 +578,7 @@ get_beam_name() ->
false -> "";
true -> ".smp"
end,
- Beam = case os:getenv("EMU") of
- false -> "beam";
- Value -> Value
- end,
+ Beam = os:getenv("EMU", "beam"),
Beam ++ Type ++ Flavor.
%% Check runtime dependencies...
diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl
index 0bcbd67d05..11dd753eed 100644
--- a/lib/runtime_tools/test/dbg_SUITE.erl
+++ b/lib/runtime_tools/test/dbg_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl b/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl
index 2edbf6f99a..33de329a62 100644
--- a/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl
+++ b/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl b/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl
index 85faf620aa..1e47482fbd 100644
--- a/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl
+++ b/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/runtime_tools/test/dyntrace_SUITE.erl b/lib/runtime_tools/test/dyntrace_SUITE.erl
index 0e4f369ed0..03242784dd 100644
--- a/lib/runtime_tools/test/dyntrace_SUITE.erl
+++ b/lib/runtime_tools/test/dyntrace_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/runtime_tools/test/erts_alloc_config_SUITE.erl b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
index 8ea04e1767..9c0a643e91 100644
--- a/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
+++ b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -79,12 +80,7 @@ basic(Config) when is_list(Config) ->
SbctMod = " +MBsbct 1024 +MHsbct 4096",
%% Make sure we have enabled allocators
- ZFlgs = case os:getenv("ERL_ZFLAGS") of
- FlgString when is_list(FlgString) ->
- FlgString;
- _ ->
- ""
- end ++ " +Mea max +Mea config",
+ ZFlgs = os:getenv("ERL_ZFLAGS", "") ++ " +Mea max +Mea config",
?line os:putenv("ERL_ZFLAGS", ZFlgs ++ SbctMod),
diff --git a/lib/runtime_tools/test/runtime_tools_SUITE.erl b/lib/runtime_tools/test/runtime_tools_SUITE.erl
index 48ed810918..7599026e7e 100644
--- a/lib/runtime_tools/test/runtime_tools_SUITE.erl
+++ b/lib/runtime_tools/test/runtime_tools_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/runtime_tools/test/system_information_SUITE.erl b/lib/runtime_tools/test/system_information_SUITE.erl
index 53d20060e7..5e2e0d17ac 100644
--- a/lib/runtime_tools/test/system_information_SUITE.erl
+++ b/lib/runtime_tools/test/system_information_SUITE.erl
@@ -2,16 +2,17 @@
%%
%% Copyright Ericsson AB 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk
index e9f43df1aa..bfc8b84b91 100644
--- a/lib/runtime_tools/vsn.mk
+++ b/lib/runtime_tools/vsn.mk
@@ -1 +1 @@
-RUNTIME_TOOLS_VSN = 1.8.16
+RUNTIME_TOOLS_VSN = 1.9.3
diff --git a/lib/sasl/Makefile b/lib/sasl/Makefile
index 4073e5af85..9085c487d4 100644
--- a/lib/sasl/Makefile
+++ b/lib/sasl/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/sasl/doc/src/Makefile b/lib/sasl/doc/src/Makefile
index b0ec671adc..1ee48af338 100644
--- a/lib/sasl/doc/src/Makefile
+++ b/lib/sasl/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/doc/src/alarm_handler.xml b/lib/sasl/doc/src/alarm_handler.xml
index e4def7c7f5..68076ba28d 100644
--- a/lib/sasl/doc/src/alarm_handler.xml
+++ b/lib/sasl/doc/src/alarm_handler.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -36,94 +37,92 @@
<module>alarm_handler</module>
<modulesummary>An Alarm Handling Process</modulesummary>
<description>
- <p>The alarm handler process is a <c>gen_event</c> event manager
- process which receives alarms in the system. This process is not
- intended to be a complete alarm handler. It defines a
- place to which alarms can be sent. One simple event handler is
- installed in the alarm handler at start-up, but users are
- encouraged to write and install their own handlers.
- </p>
+ <p>The alarm handler process is a
+ <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso>
+ event manager process that receives alarms in the system.
+ This process is not intended to be a complete alarm handler.
+ It defines a place to which alarms can be sent. One simple event
+ handler is installed in the alarm handler at startup, but users
+ are encouraged to write and install their own handlers.</p>
<p>The simple event handler sends all alarms as info reports to
- the error logger, and saves all of them in a list which can be
- passed to a user defined event handler, which may be installed at
- a later stage. The list can grow large if many alarms are
- generated. So it is a good reason to install a better user defined
- handler.
- </p>
- <p>There are functions to set and clear alarms. The format of
- alarms are defined by the user. For example, an event handler
- for SNMP could be defined, together with an alarm MIB.
- </p>
- <p>The alarm handler is part of the SASL application.
- </p>
+ the error logger, and saves all in a list. This list can be
+ passed to a user-defined event handler, which can be installed
+ later. The list can grow large if many alarms are generated.
+ This is a good reason to install a better user-defined
+ handler.</p>
+ <p>Functions are provided to set and clear alarms. The alarm
+ format is defined by the user. For example, an event handler
+ for SNMP can be defined, together with an alarm Management
+ Information Base (MIB).</p>
+ <p>The alarm handler is part of the <c>SASL</c> application.</p>
<p>When writing new event handlers for the alarm handler, the
- following events must be handled:
- </p>
+ following events must be handled:</p>
<taglist>
<tag><c>{set_alarm, {AlarmId, AlarmDescr}}</c></tag>
<item>
<p>This event is generated by
- <c>alarm_handler:set_alarm({AlarmId, AlarmDecsr})</c>.
- </p>
+ <c>alarm_handler:set_alarm({AlarmId, AlarmDecsr})</c>.</p>
</item>
<tag><c>{clear_alarm, AlarmId}</c></tag>
<item>
<p>This event is
- generated by <c>alarm_handler:clear_alarm(AlarmId)</c>.
- </p>
+ generated by <c>alarm_handler:clear_alarm(AlarmId)</c>.</p>
</item>
</taglist>
<p>The default simple handler is called <c>alarm_handler</c> and
- it may be exchanged by calling <c>gen_event:swap_handler/3</c>
- as <c>gen_event:swap_handler(alarm_handler, {alarm_handler, swap}, {NewHandler, Args})</c>. <c>NewHandler:init({Args, {alarm_handler, Alarms}})</c> is called. Refer to gen_event(3)
- for further details.
- </p>
+ it can be exchanged by calling
+ <seealso marker="stdlib:gen_event#swap_handler/3"><c>gen_event:swap_handler/3</c></seealso>
+ as <c>gen_event:swap_handler(alarm_handler, {alarm_handler, swap},
+ {NewHandler, Args})</c>. <c>NewHandler:init({Args, {alarm_handler,
+ Alarms}})</c> is called. For more details, see
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>
+ in <c>STDLIB</c>.</p>
</description>
+
<funcs>
<func>
<name>clear_alarm(AlarmId) -> void()</name>
- <fsummary>Clear the specified alarms</fsummary>
+ <fsummary>Clears the specified alarms.</fsummary>
<type>
<v>AlarmId = term()</v>
</type>
<desc>
- <p>Sends the <c>clear_alarm</c> event to all event handlers.</p>
+ <p>Sends event <c>clear_alarm</c> to all event handlers.</p>
<p>When receiving this event, the default simple handler
- clears the latest received alarm with id <c>AlarmId</c>.
- </p>
+ clears the latest received alarm with id <c>AlarmId</c>.</p>
</desc>
</func>
+
<func>
<name>get_alarms() -> [alarm()]</name>
- <fsummary>Get all active alarms</fsummary>
+ <fsummary>Gets all active alarms.</fsummary>
<desc>
<p>Returns a list of all active alarms. This function can only
- be used when the simple handler is installed.
- </p>
+ be used when the simple handler is installed.</p>
</desc>
</func>
+
<func>
<name>set_alarm(alarm())</name>
- <fsummary>Set an alarm with an id</fsummary>
+ <fsummary>Sets an alarm with an id.</fsummary>
<type>
<v>alarm() = {AlarmId, AlarmDescription}</v>
<v>AlarmId = term()</v>
<v>AlarmDescription = term()</v>
</type>
<desc>
- <p>Sends the <c>set_alarm</c> event to all event handlers.</p>
+ <p>Sends event <c>set_alarm</c> to all event handlers.</p>
<p>When receiving this event, the default simple handler
- stores the alarm. The <c>AlarmId</c> identifies the alarm
- and is used when the alarm is cleared.
- </p>
+ stores the alarm. <c>AlarmId</c> identifies the alarm
+ and is used when the alarm is cleared.</p>
</desc>
</func>
</funcs>
<section>
<title>See Also</title>
- <p>error_logger(3), gen_event(3)
- </p>
+ <p><seealso marker="kernel:error_logger"><c>error_logger(3)</c></seealso>,
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso></p>
</section>
</erlref>
diff --git a/lib/sasl/doc/src/appup.xml b/lib/sasl/doc/src/appup.xml
index 95f315d269..b54d2adb19 100644
--- a/lib/sasl/doc/src/appup.xml
+++ b/lib/sasl/doc/src/appup.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,78 +29,85 @@
<rev></rev>
</header>
<file>appup</file>
- <filesummary>Application upgrade file.</filesummary>
+ <filesummary>Application upgrade file</filesummary>
<description>
<p>The <em>application upgrade file</em> defines how an application
is upgraded or downgraded in a running system.</p>
- <p>This file is used by the functions in <c>systools</c> when
- generating a release upgrade file <c>relup</c>.</p>
+ <p>This file is used by the functions in
+ <seealso marker="systools"><c>systools</c></seealso>
+ when generating a release upgrade file <c>relup</c>.</p>
</description>
<section>
- <title>FILE SYNTAX</title>
- <p>The application upgrade file should be called
- <c>Application.appup</c> where <c>Application</c> is the name of
- the application. The file should be located in the <c>ebin</c>
+ <title>File Syntax</title>
+ <p>The application upgrade file is to be called
+ <c>Application.appup</c>, where <c>Application</c> is the
+ application name. The file is to be located in the <c>ebin</c>
directory for the application.</p>
<p>The <c>.appup</c> file contains one single Erlang term, which
defines the instructions used to upgrade or downgrade
- the application. The file has the following syntax:</p>
+ the application. The file has the following syntax:</p>
<code type="none">
{Vsn,
[{UpFromVsn, Instructions}, ...],
- [{DownToVsn, Instructions}, ...]}.
- </code>
- <list type="bulleted">
- <item>
- <p><c>Vsn = string()</c> is the current version of
- the application.</p>
- </item>
- <item>
- <p><c>UpFromVsn = string() | binary()</c> is an earlier
- version of the application to upgrade from. If it is a
- string, it will be interpreted as a specific version
- number. If it is a binary, it will be interpreted as a
- regular expression which can match multiple version
- numbers.</p>
- </item>
- <item>
- <p><c>DownToVsn = string() | binary()</c> is an earlier
- version of the application to downgrade to. If it is a
- string, it will be interpreted as a specific version
- number. If it is a binary, it will be interpreted as a
- regular expression which can match multiple version
- numbers.</p>
- </item>
- <item>
- <p><c>Instructions</c> is a list of <em>release upgrade instructions</em>, see below. It is recommended to use
+ [{DownToVsn, Instructions}, ...]}.</code>
+ <taglist>
+ <tag><c>Vsn = string()</c></tag>
+ <item><p>Current application version.</p></item>
+ <tag><c>UpFromVsn = string() | binary()</c></tag>
+ <item><p>An earlier
+ application version to upgrade from. If it is a
+ string, it is interpreted as a specific version
+ number. If it is a binary, it is interpreted as a
+ regular expression that can match multiple version
+ numbers.</p></item>
+ <tag><c>DownToVsn = string() | binary()</c></tag>
+ <item><p>An earlier
+ application version to downgrade to. If it is a
+ string, it is interpreted as a specific version
+ number. If it is a binary, it is interpreted as a
+ regular expression that can match multiple version
+ numbers.</p></item>
+ <tag><c>Instructions</c></tag>
+ <item><p>A list of <em>release upgrade instructions</em>, see
+ <seealso marker="#Release Upgrade Instructions">Release
+ Upgrade Instructions</seealso>. It is recommended to use
high-level instructions only. These are automatically
translated to low-level instructions by <c>systools</c> when
- creating the <c>relup</c> file.</p>
- </item>
- </list>
- <p>In order to avoid duplication of upgrade instructions it is
- allowed to use regular expressions to specify the <c>UpFromVsn</c>
- and <c>DownToVsn</c>. To be considered a regular expression, the
- version identifier must be specified as a binary, e.g.</p>
- <code type="none">&lt;&lt;"2\\.1\\.[0-9]+">></code>
- <p>will match all versions <c>2.1.x</c>, where x is any number.</p>
- <p>Note that the regular expression must match the complete
- version string, so the above example will work for for
- e.g. <c>2.1.1</c>, but not for <c>2.1.1.1</c></p>
+ creating the <c>relup</c> file.</p></item>
+ </taglist>
+ <p>To avoid duplication of upgrade instructions, it is
+ allowed to use regular expressions to specify <c>UpFromVsn</c>
+ and <c>DownToVsn</c>. To be considered a regular expression, the
+ version identifier must be specified as a binary. For example,
+ the following match all versions <c>2.1.x</c>, where <c>x</c> is
+ any number:</p>
+ <code type="none">
+&lt;&lt;"2\\.1\\.[0-9]+">></code>
+ <p>Notice that the regular expression must match the complete
+ version string, so this example works for, for example,
+ <c>2.1.1</c>, but not for <c>2.1.1.1</c>.</p>
</section>
<section>
- <title>RELEASE UPGRADE INSTRUCTIONS</title>
+ <marker id="Release Upgrade Instructions"></marker>
+ <title>Release Upgrade Instructions</title>
<p>Release upgrade instructions are interpreted by the release
handler when an upgrade or downgrade is made. For more
- information about release handling, refer to <em>OTP Design Principles</em>.</p>
- <p>A process is said to <em>use</em> a module <c>Mod</c>, if
+ information about release handling, see
+ <seealso marker="doc/design_principles:release_handling">OTP
+ Design Principles</seealso> in <em>System Documentation</em>.</p>
+ <p>A process is said to <em>use</em> a module <c>Mod</c> if
<c>Mod</c> is listed in the <c>Modules</c> part of the child
- specification used to start the process, see <c>supervisor(3)</c>.
- In the case of gen_event, an event manager process is said to use
- <c>Mod</c> if <c>Mod</c> is an installed event handler.</p>
- <p><em>High-level instructions</em></p>
+ specification used to start the process, see
+ <seealso marker="stdlib:supervisor"><c>supervisor(3)</c></seealso>.
+ In the case of
+ <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso>,
+ an event manager process is said to use <c>Mod</c> if <c>Mod</c>
+ is an installed event handler.</p>
+
+ <section>
+ <title>High-Level Instructions</title>
<pre>
{update, Mod}
{update, Mod, supervisor}
@@ -115,52 +123,68 @@
Change = soft | {advanced,Extra}
Extra = term()
PrePurge = PostPurge = soft_purge | brutal_purge
- DepMods = [Mod]
- </pre>
- <p>Synchronized code replacement of processes using the module
- <c>Mod</c>. All those processes are suspended using
- <c>sys:suspend</c>, the new version of the module is loaded and
- then the processes are resumed using <c>sys:resume</c>.</p>
- <p><c>Change</c> defaults to <c>soft</c> and defines the type of
- code change. If it is set to <c>{advanced,Extra}</c>, processes
- implemented using gen_server, gen_fsm or gen_event will transform
- their internal state by calling the callback function
- <c>code_change</c>. Special processes will call the callback
+ DepMods = [Mod]</pre>
+ <p>Synchronized code replacement of processes using module
+ <c>Mod</c>.</p>
+ <p>All those processes are suspended using
+ <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso>,
+ the new module version is loaded, and
+ then the processes are resumed using
+ <seealso marker="stdlib:sys#resume/1"><c>sys:resume</c></seealso>.</p>
+ <taglist>
+ <tag><c>Change</c></tag>
+ <item><p>Defaults to <c>soft</c> and defines the type of
+ code change. If it is set to <c>{advanced,Extra}</c>, implemented
+ processes using
+ <seealso marker="stdlib:gen_server"><c>gen_server</c></seealso>,
+ <seealso marker="stdlib:gen_fsm"><c>gen_fsm</c></seealso>, or
+ <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso>
+ transform their internal state by calling the callback function
+ <c>code_change</c>. Special processes call the callback
function <c>system_code_change/4</c>. In both cases, the term
- <c>Extra</c> is passed as an argument to the callback function.</p>
- <p><c>PrePurge</c> defaults to <c>brutal_purge</c> and controls
- what action to take with processes that are executing old code
- before loading the new version of the module. If the value
+ <c>Extra</c> is passed as an argument to the callback
+ function.</p></item>
+ <tag><c>PrePurge</c></tag>
+ <item><p>Defaults to <c>brutal_purge</c>. It controls
+ what action to take with processes executing old code
+ before loading the new module version. If the value
is <c>brutal_purge</c>, the processes are killed. If the value is
- <c>soft_purge</c>, <c>release_handler:install_release/1</c>
- returns <c>{error,{old_processes,Mod}}</c>.</p>
- <p><c>PostPurge</c> defaults to <c>brutal_purge</c> and controls
+ <c>soft_purge</c>,
+ <seealso marker="release_handler#install_release/1"><c>release_handler:install_release/1</c></seealso>
+ returns <c>{error,{old_processes,Mod}}</c>.</p></item>
+ <tag><c>PostPurge</c></tag>
+ <item><p>Defaults to <c>brutal_purge</c>. It controls
what action to take with processes that are executing old code
- when the new version of the module has been loaded. If the value
+ when the new module version has been loaded. If the value
is <c>brutal_purge</c>, the code is purged when the release is
made permanent and the processes are killed. If the value is
- <c>soft_purge</c>, the release handler will purge the old code
- when no remaining processes execute the code.</p>
- <p><c>DepMods</c> defaults to [] and defines which other modules
- <c>Mod</c> is dependent on. In <c>relup</c>, instructions for
- suspending processes using <c>Mod</c> will come before
+ <c>soft_purge</c>, the release handler purges the old code
+ when no remaining processes execute the code.</p></item>
+ <tag><c>DepMods</c></tag>
+ <item><p>Defaults to <c>[]</c> and defines other modules that
+ <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions
+ for suspending processes using <c>Mod</c> come before
instructions for suspending processes using modules in
- <c>DepMods</c> when upgrading, and vice versa when downgrading.
+ <c>DepMods</c> when upgrading, and conversely when downgrading.
In case of circular dependencies, the order of the instructions in
- the <c>appup</c> script is kept.</p>
- <p><c>Timeout</c> defines the timeout when suspending processes.
- If no value or <c>default</c> is given, the default value for
- <c>sys:suspend</c> is used.</p>
- <p><c>ModType</c> defaults to <c>dynamic</c> and specifies if
- the code is "dynamic", that is if a process using the module does
- spontaneously switch to new code, or if it is "static".
- When doing an advanced update and upgrading, the new version of a
+ the <c>appup</c> file is kept.</p></item>
+ <tag><c>Timeout</c></tag>
+ <item><p>Defines the time-out when suspending processes.
+ If no value or <c>default</c> is specified, the default value for
+ <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso>
+ is used.</p></item>
+ <tag><c>ModType</c></tag>
+ <item><p>Defaults to <c>dynamic</c>. It specifies if
+ the code is "dynamic", that is, if a process using the module
+ spontaneously switches to new code, or if it is "static".
+ When doing an advanced update and upgrade, the new version of a
dynamic module is loaded before the process is asked to change
code. When downgrading, the process is asked to change code before
loading the new version. For static modules, the new version is
loaded before the process is asked to change code, both in
the case of upgrading and downgrading. Callback modules are
- dynamic.</p>
+ dynamic.</p></item>
+ </taglist>
<p><c>update</c> with argument <c>supervisor</c> is used when
changing the start specification of a supervisor.</p>
<pre>
@@ -169,226 +193,229 @@
{load_module, Mod, PrePurge, PostPurge, DepMods}
Mod = atom()
PrePurge = PostPurge = soft_purge | brutal_purge
- DepMods = [Mod]
- </pre>
+ DepMods = [Mod]</pre>
<p>Simple code replacement of the module <c>Mod</c>.</p>
- <p>See <c>update</c> above for a description of <c>PrePurge</c> and
- <c>PostPurge</c>.</p>
- <p><c>DepMods</c> defaults to [] and defines which other modules
- <c>Mod</c> is dependent on. In <c>relup</c>, instructions for
- loading these modules will come before the instruction for loading
- <c>Mod</c> when upgrading, and vice versa when downgrading.</p>
+ <p>For a description of <c>PrePurge</c> and <c>PostPurge</c>,
+ see <c>update</c> above.</p>
+ <p><c>DepMods</c> defaults to <c>[]</c> and defines which other modules
+ <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions for
+ loading these modules come before the instruction for loading
+ <c>Mod</c> when upgrading, and conversely when downgrading.</p>
<pre>
{add_module, Mod}
+{add_module, Mod, DepMods}
Mod = atom()
- </pre>
+ DepMods = [Mod]</pre>
<p>Loads a new module <c>Mod</c>.</p>
+ <p><c>DepMods</c> defaults to <c>[]</c> and defines which other modules
+ <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions
+ related to these modules come before the instruction for
+ loading <c>Mod</c> when upgrading, and conversely when
+ downgrading.</p>
<pre>
{delete_module, Mod}
- Mod = atom()
- </pre>
+{delete_module, Mod, DepMods}
+ Mod = atom()</pre>
<p>Deletes a module <c>Mod</c> using the low-level instructions
<c>remove</c> and <c>purge</c>.</p>
+ <p><c>DepMods</c> defaults to <c>[]</c> and defines which other modules
+ <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions
+ related to these modules come before the instruction for
+ removing <c>Mod</c> when upgrading, and conversely when
+ downgrading.</p>
<pre>
{add_application, Application}
{add_application, Application, Type}
Application = atom()
- Type = permanent | transient | temporary | load | none
- </pre>
+ Type = permanent | transient | temporary | load | none</pre>
<p>Adding an application means that the modules defined by
the <c>modules</c> key in the <c>.app</c> file are loaded using
<c>add_module</c>.</p>
<p><c>Type</c> defaults to <c>permanent</c> and specifies the start type
of the application. If <c>Type = permanent | transient | temporary</c>,
- the application will be loaded and started in the corresponding way,
- see <c>application(3)</c>. If <c>Type = load</c>, the application will
- only be loaded. If <c>Type = none</c>, the application will be neither
- loaded nor started, although the code for its modules will be loaded.</p>
+ the application is loaded and started in the corresponding way, see
+ <seealso marker="kernel:application"><c>application(3)</c></seealso>.
+ If <c>Type = load</c>, the application is only loaded.
+ If <c>Type = none</c>, the application is not loaded and not
+ started, although the code for its modules is loaded.</p>
<pre>
{remove_application, Application}
- Application = atom()
- </pre>
+ Application = atom()</pre>
<p>Removing an application means that the application is stopped,
- the modules are unloaded using <c>delete_module</c> and then
+ the modules are unloaded using <c>delete_module</c>, and then
the application specification is unloaded from the application
controller.</p>
<pre>
{restart_application, Application}
- Application = atom()
- </pre>
+ Application = atom()</pre>
<p>Restarting an application means that the application is
- stopped and then started again similar to using the instructions
+ stopped and then started again, similar to using the instructions
<c>remove_application</c> and <c>add_application</c> in sequence.</p>
- <p><em>Low-level instructions</em></p>
+ </section>
+
+ <section>
+ <title>Low-Level Instructions</title>
<pre>
{load_object_code, {App, Vsn, [Mod]}}
App = Mod = atom()
- Vsn = string()
- </pre>
- <p>Reads each <c>Mod</c> from the directory <c>App-Vsn/ebin</c> as
- a binary. It does not load the modules. The instruction should be
- placed first in the script in order to read all new code from file
- to make the suspend-load-resume cycle less time consuming. After
- this instruction has been executed, the code server with the new
- version of <c>App</c>.</p>
+ Vsn = string()</pre>
+ <p>Reads each <c>Mod</c> from directory <c>App-Vsn/ebin</c> as
+ a binary. It does not load the modules. The instruction is to be
+ placed first in the script to read all new code from the file
+ to make the suspend-load-resume cycle less time-consuming.</p>
<pre>
-point_of_no_return
- </pre>
+point_of_no_return</pre>
<p>If a crash occurs after this instruction, the system cannot
- recover and is restarted from the old version of the release.
- The instruction must only occur once in a script. It should be
+ recover and is restarted from the old release version.
+ The instruction must only occur once in a script. It is to be
placed after all <c>load_object_code</c> instructions.</p>
<pre>
{load, {Mod, PrePurge, PostPurge}}
Mod = atom()
- PrePurge = PostPurge = soft_purge | brutal_purge
- </pre>
+ PrePurge = PostPurge = soft_purge | brutal_purge</pre>
<p>Before this instruction occurs, <c>Mod</c> must have been loaded
using <c>load_object_code</c>. This instruction loads the module.
- <c>PrePurge</c> is ignored. See the high-level instruction
- <c>update</c> for a description of <c>PostPurge</c>.</p>
+ <c>PrePurge</c> is ignored. For a description of <c>PostPurge</c>,
+ see the high-level instruction <c>update</c> earlier.</p>
<pre>
{remove, {Mod, PrePurge, PostPurge}}
Mod = atom()
- PrePurge = PostPurge = soft_purge | brutal_purge
- </pre>
+ PrePurge = PostPurge = soft_purge | brutal_purge</pre>
<p>Makes the current version of <c>Mod</c> old.
- <c>PrePurge</c> is ignored. See the high-level instruction
- <c>update</c> for a description of <c>PostPurge</c>.</p>
+ <c>PrePurge</c> is ignored. For a description of <c>PostPurge</c>,
+ see the high-level instruction <c>update</c> earlier.</p>
<pre>
{purge, [Mod]}
- Mod = atom()
- </pre>
- <p>Purges each module <c>Mod</c>, that is removes the old code.
- Note that any process executing purged code is killed.</p>
+ Mod = atom()</pre>
+ <p>Purges each module <c>Mod</c>, that is, removes the old code.
+ Notice that any process executing purged code is killed.</p>
<pre>
{suspend, [Mod | {Mod, Timeout}]}
Mod = atom()
- Timeout = int()>0 | default | infinity
- </pre>
+ Timeout = int()>0 | default | infinity</pre>
<p>Tries to suspend all processes using a module <c>Mod</c>. If a
- process does not respond, it is ignored. This may cause
+ process does not respond, it is ignored. This can cause
the process to die, either because it crashes when it
spontaneously switches to new code, or as a result of a purge
operation. If no <c>Timeout</c> is specified or <c>default</c> is
- given, the default value for <c>sys:suspend</c> is used.</p>
+ specified, the default value for
+ <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso>
+ is used.</p>
<pre>
{resume, [Mod]}
- Mod = atom()
- </pre>
+ Mod = atom()</pre>
<p>Resumes all suspended processes using a module <c>Mod</c>.</p>
<pre>
{code_change, [{Mod, Extra}]}
{code_change, Mode, [{Mod, Extra}]}
Mod = atom()
Mode = up | down
- Extra = term()
- </pre>
+ Extra = term()</pre>
<p><c>Mode</c> defaults to <c>up</c> and specifies if it is an
- upgrade or downgrade.</p>
- <p>This instruction sends a <c>code_change</c> system message to
- all processes using a module <c>Mod</c> by calling the function
- <c>sys:change_code</c>, passing the term <c>Extra</c> as argument.</p>
+ upgrade or downgrade. This instruction sends a <c>code_change</c>
+ system message to all processes using a module <c>Mod</c> by
+ calling function
+ <seealso marker="stdlib:sys#change_code/4"><c>sys:change_code</c></seealso>,
+ passing term <c>Extra</c> as argument.</p>
<pre>
{stop, [Mod]}
- Mod = atom()
- </pre>
+ Mod = atom()</pre>
<p>Stops all processes using a module <c>Mod</c> by calling
- <c>supervisor:terminate_child/2</c>. The instruction is useful
+ <seealso marker="stdlib:supervisor#terminate_child/2"><c>supervisor:terminate_child/2</c></seealso>.
+ This instruction is useful
when the simplest way to change code is to stop and restart the
- processes which run the code.</p>
+ processes that run the code.</p>
<pre>
{start, [Mod]}
- Mod = atom()
- </pre>
+ Mod = atom()</pre>
<p>Starts all stopped processes using a module <c>Mod</c> by calling
- <c>supervisor:restart_child/2</c>.</p>
+ <seealso marker="stdlib:supervisor#restart_child/2"><c>supervisor:restart_child/2</c></seealso>.</p>
<pre>
{sync_nodes, Id, [Node]}
{sync_nodes, Id, {M, F, A}}
Id = term()
Node = node()
M = F = atom()
- A = [term()]
- </pre>
+ A = [term()]</pre>
<p><c>apply(M, F, A)</c> must return a list of nodes.</p>
- <p>The instruction synchronizes the release installation with other
- nodes. Each <c>Node</c> must evaluate this command, with the same
+ <p>This instruction synchronizes the release installation with other
+ nodes. Each <c>Node</c> must evaluate this command with the same
<c>Id</c>. The local node waits for all other nodes to evaluate
- the instruction before execution continues. In case a node goes
+ the instruction before execution continues. If a node goes
down, it is considered to be an unrecoverable error, and
the local node is restarted from the old release. There is no
- timeout for this instruction, which means that it may hang
+ time-out for this instruction, which means that it can hang
forever.</p>
<pre>
{apply, {M, F, A}}
M = F = atom()
- A = [term()]
- </pre>
- <p>Evaluates <c>apply(M, F, A)</c>. If the instruction appears
- before the <c>point_of_no_return</c> instruction, a failure is
- caught. <c>release_handler:install_release/1</c> then returns
- <c>{error,{'EXIT',Reason}}</c>, unless <c>{error,Error}</c> is
- thrown or returned. Then it returns <c>{error,Error}</c>.</p>
- <p>If the instruction appears after the <c>point_of_no_return</c>
- instruction, and the function call fails, the system is
- restarted.</p>
+ A = [term()]</pre>
+ <p>Evaluates <c>apply(M, F, A)</c>.</p>
+ <p>If the instruction appears before instruction
+ <c>point_of_no_return</c>, a failure is caught.
+ <seealso marker="release_handler#install_release/1"><c>release_handler:install_release/1</c></seealso>
+ then returns <c>{error,{'EXIT',Reason}}</c>, unless <c>{error,Error}</c>
+ is thrown or returned. Then it returns <c>{error,Error}</c>.</p>
+ <p>If the instruction appears after instruction
+ <c>point_of_no_return</c> and the function call fails, the
+ system is restarted.</p>
<pre>
-restart_new_emulator
- </pre>
- <p>This instruction is used when erts, kernel, stdlib or sasl is
+restart_new_emulator</pre>
+ <p>This instruction is used when the application <c>ERTS</c>,
+ <c>Kernel</c>, <c>STDLIB</c>, or <c>SASL</c> is
upgraded. It shuts down the current emulator and starts a new
one. All processes are terminated gracefully, and the new
- version of erts, kernel, stdlib and sasl are used when the
- emulator restarts. Only one <c>restart_new_emulator</c>
- instruction is allowed in the relup, and it shall be placed
- first. <seealso marker="systools#make_relup/3">systools:make_relup/3,4</seealso>
- will ensure this when the relup is generated. The rest of the
- relup script is executed after the restart as a part of the boot
- script.</p>
- <p>An info report will be written when the upgrade is
- completed. To programatically find out if the upgrade is
- complete,
+ version of <c>ERTS</c>, <c>Kernel</c>, <c>STDLIB</c>, and
+ <c>SASL</c> are used when the emulator restarts.
+ Only one <c>restart_new_emulator</c> instruction is allowed
+ in the <c>relup</c> file, and it must be placed first.
+ <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>
+ ensures this when the <c>relup</c> file is generated. The rest of the
+ instructions in the <c>relup</c> file is executed after the
+ restart as a part of the boot script.</p>
+ <p>An info report is written when the upgrade is completed.
+ To programmatically determine if the upgrade is complete,
call <seealso marker="release_handler#which_releases/0">
- release_handler:which_releases/0,1</seealso> and check if the
+ <c>release_handler:which_releases/0,1</c></seealso> and check if the
expected release has status <c>current</c>.</p>
<p>The new release must still be made permanent after the upgrade
- is completed. Otherwise, the old emulator is started in case of
+ is completed, otherwise the old emulator is started if there is
an emulator restart.</p>
<warning>
- <p>As stated above, the <c>restart_new_emulator</c>
- instruction causes the emulator to be restarted with new
- versions of <c>erts</c>, <c>kernel</c>, <c>stdlib</c> and
- <c>sasl</c>. All other applications, however, will at startup
- be running their old versions in this new emulator. In most
- cases this is no problem, but every now and then there will be
- incompatible changes to the core applications which may cause
- trouble in this setting. Such incompatible changes (when
- functions are removed) are normally preceded by a deprecation
- over two major releases. To make sure your application is not
- crashed by an incompatible change, always remove any call to
- deprecated functions as soon as possible.</p>
+ <p>As stated earlier, instruction <c>restart_new_emulator</c>
+ causes the emulator to be restarted with new versions of
+ <c>ERTS</c>, <c>Kernel</c>, <c>STDLIB</c>, and <c>SASL</c>.
+ However, all other applications do at startup run their old
+ versions in this new emulator. This is usually no problem,
+ but every now and then incompatible changes occur to the
+ core applications, which can cause
+ trouble in this setting. Such incompatible changes (when
+ functions are removed) are normally preceded by a deprecation
+ over two major releases. To ensure that your application is not
+ crashed by an incompatible change, always remove any call to
+ deprecated functions as soon as possible.</p>
</warning>
<pre>
-restart_emulator
- </pre>
+restart_emulator</pre>
<p>This instruction is similar to <c>restart_new_emulator</c>,
- except it shall be placed at the end of the relup script. It is
- not related to an upgrade of the emulator or the core
+ except it must be placed at the end of the <c>relup</c> file.
+ It is not related to an upgrade of the emulator or the core
applications, but can be used by any application when a complete
- reboot of the system is reqiured. When generating the
- relup, <seealso marker="systools#make_relup/3">systools:make_relup/3,4</seealso>
+ reboot of the system is required.</p>
+ <p>When generating the <c>relup</c> file,
+ <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>
ensures that there is only one <c>restart_emulator</c>
- instruction and that it is the last instruction of the
- relup.</p>
+ instruction and that it is the last instruction in the
+ <c>relup</c> file.</p>
+ </section>
</section>
<section>
- <title>SEE ALSO</title>
- <p><seealso marker="relup">relup(4)</seealso>,
- <seealso marker="release_handler">release_handler(3)</seealso>,
- supervisor(3),
- <seealso marker="systools">systools(3)</seealso></p>
+ <title>See Also</title>
+ <p><seealso marker="release_handler"><c>release_handler(3)</c></seealso>,
+ <seealso marker="relup"><c>relup(4)</c></seealso>,
+ <seealso marker="stdlib:supervisor"><c>supervisor(3)</c></seealso>,
+ <seealso marker="systools"><c>systools(3)</c></seealso></p>
</section>
</fileref>
diff --git a/lib/sasl/doc/src/book.xml b/lib/sasl/doc/src/book.xml
index 30f196be48..624c32a66f 100644
--- a/lib/sasl/doc/src/book.xml
+++ b/lib/sasl/doc/src/book.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>System Application Support Libraries (SASL)</title>
+ <title>System Architecture Support Libraries (SASL)</title>
<prepared>OTP Team</prepared>
<docno></docno>
<date>1999-04-22</date>
@@ -30,7 +31,7 @@
</header>
<insidecover>
</insidecover>
- <pagetext>System Application Support Libraries (SASL)</pagetext>
+ <pagetext>System Architecture Support Libraries (SASL)</pagetext>
<preamble>
<contents level="2"></contents>
</preamble>
diff --git a/lib/sasl/doc/src/error_logging.xml b/lib/sasl/doc/src/error_logging.xml
index 4d799d52f5..46b12f3872 100644
--- a/lib/sasl/doc/src/error_logging.xml
+++ b/lib/sasl/doc/src/error_logging.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,89 +31,93 @@
<date>1999-04-13</date>
<rev>B</rev>
<file>error_logging.xml</file>
- </header>
- <p>The SASL application introduces three types of reports:</p>
+ </header>
+ <p>The <c>SASL</c> application introduces three types of reports:</p>
<list type="bulleted">
- <item>supervisor report</item>
- <item>progress report</item>
- <item>crash report.</item>
+ <item>Supervisor report</item>
+ <item>Progress report</item>
+ <item>Crash report</item>
</list>
- <p>When the SASL application is started, it adds a handler that
- formats and writes these reports, as specified in the
- configuration parameters for sasl, i.e the environment variables
- in the SASL application specification, which is found in the
- <c>.app</c> file of SASL. See
- <seealso marker="sasl_app">sasl(Application)</seealso>, and app(File)
- in the Kernel Reference Manual
- for the details.</p>
+ <p>When the <c>SASL</c> application is started, it adds a handler that
+ formats and writes these reports, as specified in the configuration
+ parameters for <c>SASL</c>, that is, the environment variables
+ in the <c>SASL</c> application specification, which is found in the
+ <c>.app</c> file of <c>SASL</c>. For details, see the
+ <seealso marker="sasl_app"><c>sasl(6)</c></seealso> application in the
+ Reference Manual and the <seealso marker="kernel:app"><c>app(4)</c></seealso>
+ file in the <c>Kernel</c> Reference Manual.</p>
<section>
<title>Supervisor Report</title>
- <p>A supervisor report is issued when a supervised child terminates in
- an unexpected way. A supervisor report contains the following
+ <p>A supervisor report is issued when a supervised child terminates
+ unexpectedly. A supervisor report contains the following
items:</p>
<taglist>
- <tag>Supervisor.</tag>
- <item>The name of the reporting supervisor.</item>
- <tag>Context.</tag>
- <item>Indicates in which phase the child terminated
+ <tag><c>Supervisor</c></tag>
+ <item><p>Name of the reporting supervisor.</p></item>
+ <tag><c>Context</c></tag>
+ <item><p>Indicates in which phase the child terminated
from the supervisor's point of view. This can be
- <c>start_error</c>, <c>child_terminated</c>, or
- <c>shutdown_error</c>.</item>
- <tag>Reason.</tag>
- <item>The termination reason.</item>
- <tag>Offender.</tag>
- <item>The start specification for the child.</item>
+ <c>start_error</c>, <c>child_terminated</c>, or
+ <c>shutdown_error</c>.</p></item>
+ <tag><c>Reason</c></tag>
+ <item><p>Termination reason.</p></item>
+ <tag><c>Offender</c></tag>
+ <item><p>Start specification for the child.</p></item>
</taglist>
</section>
<section>
<title>Progress Report</title>
- <p>A progress report is issued whenever a supervisor starts or
- restarts. A progress report contains the following items:</p>
+ <p>A progress report is issued when a supervisor starts or
+ restarts a child. A progress report contains the following items:</p>
<taglist>
- <tag>Supervisor.</tag>
- <item>The name of the reporting supervisor.</item>
- <tag>Started.</tag>
- <item>The start specification for the successfully
- started child.</item>
+ <tag><c>Supervisor</c></tag>
+ <item><p>Name of the reporting supervisor.</p></item>
+ <tag><c>Started</c></tag>
+ <item><p>Start specification for the successfully
+ started child.</p></item>
</taglist>
<marker id="CRASH"></marker>
</section>
<section>
<title>Crash Report</title>
- <p>Processes started with the <c>proc_lib:spawn</c> or
- <c>proc_lib:spawn_link</c> functions are wrapped within a
- <c>catch</c>. A crash report is issued whenever such a process
- terminates with an unexpected reason, which is any reason other
- than <c>normal</c> or <c>shutdown</c>. Processes using the
- <c>gen_server</c> and <c>gen_fsm</c> behaviours are examples of
- such processes. A crash report contains the following items:</p>
+ <p>Processes started with functions
+ <seealso marker="stdlib:proc_lib#spawn/1"><c>proc_lib:spawn</c></seealso> or
+ <seealso marker="stdlib:proc_lib#spawn_link/1"><c>proc_lib:spawn_link</c></seealso>
+ are wrapped within a <c>catch</c>. A crash report is issued when such
+ a process terminates with an unexpected reason, which is any reason
+ other than <c>normal</c>, <c>shutdown</c>, or <c>{shutdown,Term}</c>.
+ Processes using behaviors
+ <seealso marker="stdlib:gen_server"><c>gen_server</c></seealso> or
+ <seealso marker="stdlib:gen_fsm"><c>gen_fsm</c></seealso>
+ are examples of such processes. A crash report contains the following items:</p>
<taglist>
- <tag>Crasher.</tag>
- <item>Information about the crashing process is reported, such
- as initial function call, exit reason, and message queue.</item>
- <tag>Neighbours.</tag>
- <item>Information about processes which are linked to the crashing
+ <tag><c>Crasher</c></tag>
+ <item><p>Information about the crashing process, such
+ as initial function call, exit reason, and message queue.</p></item>
+ <tag><c>Neighbours</c></tag>
+ <item><p>Information about processes that are linked to the crashing
process and do not trap exits. These processes are the
- neighbours which will terminate because of this process
+ neighbours that terminate because of this process
crash. The information gathered is the same as the information
- for Crasher, shown in the previous item.</item>
+ for Crasher, described in the previous item.</p></item>
</taglist>
<section>
- <title>An Example</title>
- <p>The following example shows the reports which are generated
- when a process crashes. The example process is an
+ <title>Example</title>
+ <p>The following example shows the reports generated
+ when a process crashes. The example process is a
<c>permanent</c> process supervised by the <c>test_sup</c>
supervisor. A division by zero is executed and the error is
first reported by the faulty process. A crash report is
- generated as the process was started using the
- <c>proc_lib:spawn/3</c> function. The supervisor generates a
- supervisor report showing the process that has crashed, and then a
+ generated, as the process was started using function
+ <seealso marker="stdlib:proc_lib#spawn/3"><c>proc_lib:spawn/3</c></seealso>.
+ The supervisor generates a
+ supervisor report showing the crashed process. A
progress report is generated when the process is finally
- re-started.</p>
+ restarted.</p>
<pre>
=ERROR REPORT==== 27-May-1996::13:38:56 ===
&lt;0.63.0>: Divide by zero !
@@ -145,7 +150,6 @@
{shutdown,200},
{child_type,worker}]
-
=PROGRESS REPORT==== 27-May-1996::13:38:56 ===
Supervisor: {local,test_sup}
Started: [{pid,&lt;0.64.0>},
@@ -153,64 +157,66 @@
{mfa,{test,t,[]}},
{restart_type,permanent},
{shutdown,200},
- {child_type,worker}]
- </pre>
+ {child_type,worker}]</pre>
</section>
</section>
<section>
<title>Multi-File Error Report Logging</title>
- <p>Multi-file error report logging is used to store error messages,
- which are received by the <c>error_logger</c>. The error messages
+ <p>Multi-file error report logging is used to store error messages
+ received by <c>error_logger</c>. The error messages
are stored in several files and each file is smaller than a
- specified amount of kilobytes, and no more than a specified number
- of files exist at the same time. The logging is very fast because
+ specified number of kilobytes. No more than a specified number
+ of files exist at the same time. The logging is very fast, as
each error message is written as a binary term.</p>
- <p>Refer to
- <c>sasl</c> application in the Reference Manual for more details.</p>
+ <p>For more details, see the
+ <seealso marker="sasl_app"><c>sasl(6)</c></seealso>
+ application in the Reference Manual.</p>
</section>
<section>
<title>Report Browser</title>
<p>The report browser is used to browse and format error reports
- written by the error logger handler <c>log_mf_h</c> defined in
- <c>stdlib</c>.</p>
+ written by the error logger handler
+ <seealso marker="stdlib:log_mf_h"><c>log_mf_h</c></seealso>
+ defined in <c>STDLIB</c>.</p>
<p>The <c>log_mf_h</c> handler writes all reports to a
- report logging directory. This directory is specified when
- configuring the SASL application.</p>
+ report logging directory, which is specified when
+ configuring the <c>SASL</c> application.</p>
<p>If the report browser is
- used off-line, the reports can be copied to another directory
- which is specified when starting the browser. If no such directory
- is specified, the browser reads reports from the SASL
+ used offline, the reports can be copied to another directory
+ specified when starting the browser. If no such directory
+ is specified, the browser reads reports from the <c>SASL</c>
<c>error_logger_mf_dir</c>.</p>
<section>
- <title>Starting the Report Browser</title>
- <p>Start the <c>rb_server</c> with the function
- <c>rb:start([Options])</c> as shown in the following
- example:</p>
+ <title>Starting Report Browser</title>
+ <p>Start the <c>rb_server</c> with function
+ <seealso marker="rb#start/1"><c>rb:start([Options])</c></seealso>
+ as shown in the following example:</p>
<pre>
-
- 5><input>rb:start([{max, 20}]).</input>
+ 5> <input>rb:start([{max, 20}]).</input>
rb: reading report...done.
rb: reading report...done.
rb: reading report...done.
rb: reading report...done.
- </pre>
+ {ok,&lt;0.199.0>}</pre>
</section>
<section>
- <title>On-line Help</title>
- <p>Enter the command <em>rb:help().</em> to access the report
- browser on-line help system.</p>
+ <title>Online Help</title>
+ <p>Enter command
+ <seealso marker="rb#help/0"><c>rb:help()</c></seealso>
+ to access the report browser online help system.</p>
</section>
<section>
- <title>List Reports in the Server</title>
- <p>The function <c>rb:list()</c> lists all loaded reports:</p>
+ <title>List Reports in Server</title>
+ <p>Use function
+ <seealso marker="rb#list/0"><c>rb:list()</c></seealso>
+ to list all loaded reports:</p>
<pre>
-
- 4><input>rb:list().</input>
+ 4> <input>rb:list().</input>
No Type Process Date Time
== ==== ======= ==== ====
20 progress &lt;0.17.0> 1996-10-16 16:14:54
@@ -233,17 +239,15 @@
3 progress &lt;0.14.0> 1996-10-16 16:16:36
2 error &lt;0.15.0> 1996-10-16 16:17:04
1 progress &lt;0.14.0> 1996-10-16 16:17:09
- ok
- </pre>
+ ok</pre>
</section>
<section>
<title>Show Reports</title>
- <p>To show details of a specific report, use the function
- <c>rb:show(Number)</c>:</p>
+ <p>Use function
+ <seealso marker="rb#show/1"><c>rb:show(Number)</c></seealso>
+ to show details of a specific report:</p>
<pre>
-
-10> <input>rb:show(1).</input>
7> <input>rb:show(4).</input>
PROGRESS REPORT &lt;0.20.0> 1996-10-16 16:16:36
@@ -258,7 +262,7 @@ started
{child_type,worker}]
ok
-8> rb:show(9).
+8> <input>rb:show(9).</input>
CRASH REPORT &lt;0.24.0> 1996-10-16 16:16:21
===============================================================================
@@ -286,19 +290,17 @@ heap_size 610
stack_size 142
reductions 54
-ok
- </pre>
+ok</pre>
</section>
<section>
- <title>Search the Reports</title>
- <p>It is possible to show all reports which contain a common
- pattern. Suppose a process crashes because it tries to call a
- non-existing function <c>release_handler:mbj_func.</c> We could
- then show reports as follows:</p>
+ <title>Search Reports</title>
+ <p>All reports containing a common pattern can be shown.
+ Suppose a process crashes because it tries to call a
+ non-existing function <c>release_handler:mbj_func/1</c>.
+ The reports can then be shown as follows:</p>
<pre>
-
-12><input>rb:grep("mbj_func").</input>
+12> <input>rb:grep("mbj_func").</input>
Found match in report number 11
ERROR REPORT &lt;0.24.0> 1996-10-16 16:16:21
@@ -367,19 +369,17 @@ restart_type permanent
shutdown 2000
child_type worker
-ok
- </pre>
+ok</pre>
</section>
<section>
- <title>Stop the Server</title>
- <p>Stop the <c>rb_server</c> with the function
- <c>rb:stop()</c>:</p>
+ <title>Stop Server</title>
+ <p>Use function
+ <seealso marker="rb#stop/0"><c>rb:stop()</c></seealso>
+ to stop the <c>rb_server</c>:</p>
<pre>
-
-13><input>rb:stop().</input>
-ok
- </pre>
+13> <input>rb:stop().</input>
+ok</pre>
</section>
</section>
</chapter>
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index 95d7c6fa50..da5bc6be96 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,127 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
+<section><title>SASL 2.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ During upgrade, the release_handler collects a list of
+ supervisor pids in order to list all processes in the
+ supervisor tree. If one of the supervisors (legitimately)
+ exits before release_handler can examine it, then
+ <c>sys:get_status/1</c> would earlier be called with a
+ dead pid, causing a <c>'noproc'</c> error. This has been
+ corrected.</p>
+ <p>
+ Own Id: OTP-13291</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The module <c>overload</c> is deprecated and will be
+ removed in OTP 19.</p>
+ <p>
+ Own Id: OTP-13057</p>
+ </item>
+ <item>
+ <p>
+ Improve implementation of supervisor child count, making
+ it faster and more accurate for dynamic processes of a
+ <c>simple_one_for_one</c> supervisor.</p>
+ <p>
+ Own Id: OTP-13290</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 2.6.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Documentation improvements</p>
+ <p>
+ Own Id: OTP-13000</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 2.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>A mechanism for limiting the amount of text that the
+ built-in error logger events will produce has been
+ introduced. It is useful for limiting both the size of
+ log files and the CPU time used to produce them.</p>
+ <p>This mechanism is experimental in the sense that it
+ may be changed if it turns out that it does not solve the
+ problem it is supposed to solve. In that case, there may
+ be backward incompatible improvements to this
+ mechanism.</p>
+ <p>See the documentation for the config parameter
+ <c>error_logger_format_depth</c> in the Kernel
+ application for information about how to turn on this
+ feature.</p>
+ <p>
+ Own Id: OTP-12864</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 2.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The undocumented upgrade instruction
+ <c>{remove_module,PrePurge,PostPurge,DepMods}</c> is
+ removed. This instruction was added for symmetry reasons
+ in OTP R7B, but was never documented or tested.</p>
+ <p>
+ The existing instruction <c>{add_module,Mod,DepMods}</c>
+ is now documented, and the complementing instruction
+ <c>{delete_module,Mod,DepMods}</c> is added.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-11540</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The <c>sasl_error_logger</c> configuration parameter
+ now supports the value <c>{file,FileName,Modes}</c> which
+ allows the log file to be opened in other mode than write
+ (for example, append mode).</p>
+ <p>
+ Own Id: OTP-12778</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SASL 2.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/sasl/doc/src/notes_history.xml b/lib/sasl/doc/src/notes_history.xml
index 3607d9204c..006a40f3ac 100644
--- a/lib/sasl/doc/src/notes_history.xml
+++ b/lib/sasl/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/sasl/doc/src/overload.xml b/lib/sasl/doc/src/overload.xml
index 3a82432647..2f19cd9088 100644
--- a/lib/sasl/doc/src/overload.xml
+++ b/lib/sasl/doc/src/overload.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -34,98 +35,94 @@
<module>overload</module>
<modulesummary>An Overload Regulation Process</modulesummary>
<description>
- <p><c>overload</c> is a process which indirectly regulates CPU
+ <warning>
+ <p>
+ All functions in this module are deprecated and will be
+ removed in a future release.
+ </p>
+ </warning>
+ <p><c>overload</c> is a process that indirectly regulates the CPU
usage in the system. The idea is that a main application calls
- the <c>request/0</c> function before starting a major job, and
+ function
+ <seealso marker="#request/0"><c>request/0</c></seealso>
+ before starting a major job and
proceeds with the job if the return value is positive; otherwise
- the job must not be started.
- </p>
- <p><c>overload</c> is part of the <c>sasl</c> application, and all
- configuration parameters are defined there.
- </p>
- <p>A set of two intensities are maintained, the <c>total intensity</c> and the <c>accept intensity</c>. For that purpose
- there are two configuration parameters, the <c>MaxIntensity</c>
- and the <c>Weight</c> value (both are measured in 1/second).
- </p>
+ the job must not be started.</p>
+ <p><c>overload</c> is part of the <c>SASL</c> application and all
+ configuration parameters are defined there.</p>
+ <p>A set of two intensities are maintained, the <c>total intensity</c>
+ and the <c>accept intensity</c>. For that purpose,
+ there are two configuration parameters, <c>MaxIntensity</c>
+ and <c>Weight</c>; both are measured in 1/second.</p>
<p>Then total and accept intensities are calculated as
follows. Assume that the time of the current call to
- <c>request/0</c> is <c>T(n)</c>, and that the time of the
- previous call was <c>T(n-1)</c>.
- </p>
+ <c>request/0</c> is <c>T(n)</c> and that the time of the
+ previous call was <c>T(n-1)</c>.</p>
<list type="bulleted">
<item>
<p>The current <c>total intensity</c>, denoted
- <c>TI(n)</c>, is calculated according to the formula,
- </p>
- <p><c>TI(n) = exp(-Weight*(T(n) - T(n-1)) * TI(n-1) + Weight</c>,
- </p>
- <p>where <c>TI(n-1)</c> is the previous total intensity.
- </p>
+ <c>TI(n)</c>, is calculated according to the formula</p>
+ <p><c>TI(n) = exp(-Weight*(T(n) - T(n-1)) * TI(n-1) + Weight</c>,</p>
+ <p>where <c>TI(n-1)</c> is the previous <c>total intensity</c>.</p>
</item>
<item>
<p>The current <c>accept intensity</c>, denoted
- <c>AI(n)</c>, is determined by the formula,
- </p>
- <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1) + Weight</c>,
- </p>
- <p>where <c>AI(n-1)</c> is the previous accept intensity,
- provided that the value of <c>exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c> is less than <c>MaxIntensity</c>; otherwise the
- value is
- </p>
- <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c>.
- </p>
+ <c>AI(n)</c>, is determined by the formula</p>
+ <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1) + Weight</c>,</p>
+ <p>where <c>AI(n-1)</c> is the previous <c>accept intensity</c>,
+ if the value of <c>exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c>
+ is less than <c>MaxIntensity</c>. Otherwise the value is</p>
+ <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c></p>
</item>
</list>
<p>The value of configuration parameter <c>Weight</c> controls the
- speed with which the calculations of intensities will react to
+ speed with which the calculations of intensities react to
changes in the underlying input intensity. The inverted value of
- <c>Weight</c>,
- </p>
- <p><c>T = 1/Weight</c></p>
- <p>can be thought of as the "time constant"
- of the intensity calculation formulas. For example, if <c>Weight = 0.1</c>, then a change in the underlying input intensity will be
- reflected in the <c>total</c> and <c>accept intensities</c> within
- approximately 10 seconds.
- </p>
+ <c>Weight</c>, <c>T = 1/Weight</c>, can be thought of as the
+ "time constant" of the intensity calculation formulas. For example,
+ if <c>Weight = 0.1</c>, a change in the underlying input intensity is
+ reflected in <c>total intensity</c> and <c>accept intensity</c> within
+ about 10 seconds.</p>
<p>The overload process defines one alarm, which it sets using
- <c>alarm_handler:set_alarm(Alarm)</c>. <c>Alarm</c> is defined
- as:
- </p>
+ <c>alarm_handler:set_alarm(Alarm)</c>. <c>Alarm</c> is defined
+ as follows:</p>
<taglist>
<tag><c>{overload, []}</c></tag>
<item>
- <p>This alarm is set when the current accept intensity exceeds
- <c>MaxIntensity</c>.
- </p>
+ <p>This alarm is set when the current <c>accept intensity</c> exceeds
+ <c>MaxIntensity</c>.</p>
</item>
</taglist>
- <p>A new overload alarm is not set until the current accept
- intensity has fallen below <c>MaxIntensity</c>. To prevent the
- overload process from generating a lot of set/reset alarms, the
- alarm is not reset until the current accept intensity has fallen
- below 75% of <c>MaxIntensity</c>, and it is not until then that
- the alarm can be set again.
- </p>
+ <p>A new request is not accepted until the current <c>accept
+ intensity</c> has fallen below <c>MaxIntensity</c>. To prevent the
+ overload process from generating many set/reset alarms, the
+ alarm is not reset until the current <c>accept intensity</c> has fallen
+ below 75% of <c>MaxIntensity</c>; it is not until then that
+ the alarm can be set again.</p>
</description>
+
<funcs>
<func>
<name>request() -> accept | reject</name>
- <fsummary>Request to proceed with current job</fsummary>
+ <fsummary>Requests to proceed with current job.</fsummary>
<desc>
<p>Returns <c>accept</c> or <c>reject</c> depending on the
- current value of the accept intensity. </p>
+ current value of the <c>accept intensity</c>.</p>
<p>The application
- calling this function should be processed with the job in
+ calling this function is to proceed with the job in
question if the return value is <c>accept</c>; otherwise it
- should not continue with that job.
- </p>
+ is not to continue with that job.</p>
</desc>
</func>
+
<func>
<name>get_overload_info() -> OverloadInfo</name>
- <fsummary>Return current overload information data</fsummary>
+ <fsummary>Returns current overload information data.</fsummary>
<type>
- <v>OverloadInfo = [{total_intensity, TotalIntensity}, {accept_intensity, AcceptIntensity}, {max_intensity, MaxIntensity}, {weight, Weight}, {total_requests, TotalRequests}, {accepted_requests, AcceptedRequests}].</v>
+ <v>OverloadInfo = [{total_intensity, TotalIntensity},
+ {accept_intensity, AcceptIntensity}, {max_intensity,
+ MaxIntensity}, {weight, Weight}, {total_requests,
+ TotalRequests}, {accepted_requests, AcceptedRequests}].</v>
<v>TotalIntensity = float() > 0</v>
<v>AcceptIntensity = float() > 0</v>
<v>MaxIntensity = float() > 0</v>
@@ -134,18 +131,22 @@
<v>AcceptedRequests = integer()</v>
</type>
<desc>
- <p>Returns the current total and accept intensities, the
- configuration parameters, and absolute counts of the total
- number of requests, and accepted number of requests (since
- the overload process was started).</p>
+ <p>Returns:</p>
+ <list type="bulleted">
+ <item>Current total and accept intensities</item>
+ <item>Configuration parameters</item>
+ <item>Absolute counts of the total number of requests</item>
+ <item>Accepted number of requests (since the overload
+ process was started)</item>
+ </list>
</desc>
</func>
</funcs>
<section>
<title>See Also</title>
- <p>alarm_handler(3), sasl(3)
- </p>
+ <p><seealso marker="alarm_handler"><c>alarm_handler(3)</c></seealso>,
+ <seealso marker="sasl_app"><c>sasl(6)</c></seealso></p>
</section>
</erlref>
diff --git a/lib/sasl/doc/src/part.xml b/lib/sasl/doc/src/part.xml
index 99d5210278..2f47a8ad80 100644
--- a/lib/sasl/doc/src/part.xml
+++ b/lib/sasl/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,8 +30,9 @@
<file>part.xml</file>
</header>
<description>
- <p>The System Architecture Support Libraries, <em>SASL</em>,
- provides support for alarm and release handling etc.</p>
+ <p>The System Architecture Support Libraries <c>SASL</c> application
+ provides support for alarm handling, release handling, and
+ related functions.</p>
</description>
<xi:include href="sasl_intro.xml"/>
<xi:include href="error_logging.xml"/>
diff --git a/lib/sasl/doc/src/part_notes.xml b/lib/sasl/doc/src/part_notes.xml
index 6a1e2e9408..57f20ece0e 100644
--- a/lib/sasl/doc/src/part_notes.xml
+++ b/lib/sasl/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/sasl/doc/src/part_notes_history.xml b/lib/sasl/doc/src/part_notes_history.xml
index 53fc8a7fea..b2d278e9c4 100644
--- a/lib/sasl/doc/src/part_notes_history.xml
+++ b/lib/sasl/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/sasl/doc/src/rb.xml b/lib/sasl/doc/src/rb.xml
index fa85b4bcd9..e16e9f5a62 100644
--- a/lib/sasl/doc/src/rb.xml
+++ b/lib/sasl/doc/src/rb.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -34,241 +35,252 @@
<module>rb</module>
<modulesummary>The Report Browser Tool</modulesummary>
<description>
- <p>The Report Browser (RB) tool makes it possible to browse and
+ <p>The Report Browser (RB) tool is used to browse and
format error reports written by the error logger handler
- <c>log_mf_h</c>.
- </p>
+ <seealso marker="stdlib:log_mf_h"><c>log_mf_h</c></seealso>
+ in <c>STDLIB</c>.</p>
</description>
+
<funcs>
<func>
<name>filter(Filters)</name>
<name>filter(Filters, Dates)</name>
- <fsummary>Filter reports and displays them on the screen</fsummary>
+ <fsummary>Filters reports and displays them on the screen.</fsummary>
<type>
<v>Filters = [filter()]</v>
- <v>filter() = {Key, Value} | {Key, Value, no} | {Key, RegExp, re} | {Key, RegExp, re, no}</v>
+ <v>filter() = {Key, Value} | {Key, Value, no} | {Key, RegExp, re} |
+ {Key, RegExp, re, no}</v>
<v>Key = term()</v>
<v>Value = term()</v>
- <v>RegExp = string() | {string, Options} | mp(), {mp(), Options}</v>
+ <v>RegExp = string() | {string(), Options} | re:mp() | {re:mp(), Options}</v>
<v>Dates = {DateFrom, DateTo} | {DateFrom, from} | {DateTo, to}</v>
- <v>DateFrom = DateTo = {date(), time()}</v>
- <v>date() and time() are the same type as in the <c>calendar</c> module</v>
+ <v>DateFrom = DateTo = calendar:datetime()</v>
</type>
<desc>
- <p>This function displays the reports that match the provided filters.</p>
- <p>
- When a filter includes the <c>no</c> atom it will exclude the reports that match
- that filter.
- </p>
- <p>
- The reports are matched using the <c>proplists</c> module. The report must be a proplist
- to be matched against any of the <c>filters()</c>.
- </p>
- <p>
- If the filter is of the form <c>{Key, RegExp, re}</c> the report must contain an element with
- <c>key = Key</c> and <c>Value</c> must match the RegExp regular expression.
- </p>
- <p>
- If the Dates parameter is provided, then the reports are filtered according to the date
- when they occurred. If Dates is of the form <c>{DateFrom, from}</c> then reports that occurred
- after DateFrom are displayed.
- </p>
- <p>
- If Dates is of the form <c>{DateTo, to}</c> then reports that occurred before DateTo
- are displayed.
- </p>
- <p>
- If two Dates are provided, then reports that occurred between those dates are returned.
- </p>
- <p>
- If you only want to filter only by dates, then you can provide the empty list as the Filters
- parameter.
- </p>
- <p>
- See <c>rb:grep/1</c> for more information on the RegExp parameter.
- </p>
+ <p>Displays the reports that match the provided filters.</p>
+ <p>When a filter includes the <c>no</c> atom, it excludes the
+ reports that match that filter.</p>
+ <p>The reports are matched using the
+ <seealso marker="stdlib:proplists"><c>proplists</c></seealso>
+ module in <c>STDLIB</c>. The report must be a proplist
+ to be matched against any of the filters.</p>
+ <p>If the filter has the form <c>{Key, RegExp, re}</c>, the
+ report must contain an element with key equal to <c>Key</c> and
+ the value must match the regular expression <c>RegExp</c>.</p>
+ <p>If parameter <c>Dates</c> is specified, the reports are filtered
+ according to the date when they occurred. If <c>Dates</c> has
+ the form <c>{DateFrom, from}</c>, reports that occurred after
+ <c>DateFrom</c> are displayed.</p>
+ <p>If <c>Dates</c> has the form <c>{DateTo, to}</c>, reports that
+ occurred before <c>DateTo</c> are displayed.</p>
+ <p>If two <c>Dates</c> are specified, reports that occurred between
+ those dates are returned.</p>
+ <p>To filter only by dates, specify the empty list as the <c>Filters</c>
+ parameter.</p>
+ <p>For details about parameter <c>RegExp</c>, see <c>rb:grep/1</c>.</p>
+ <p>For details about data type <c>mp()</c>, see
+ <seealso marker="stdlib:re#type-mp"><c>re:mp()</c></seealso>.</p>
+ <p>For details about data type <c>datetime()</c>, see
+ <seealso marker="stdlib:calendar#type-datetime"><c>calendar:datetime()</c></seealso>.</p>
</desc>
</func>
+
<func>
<name>grep(RegExp)</name>
- <fsummary>Search the reports for a regular expression</fsummary>
+ <fsummary>Searches the reports for a regular expression.</fsummary>
<type>
- <v>RegExp = string() | {string, Options} | mp(), {mp(), Options}</v>
+ <v>RegExp = string() | {string(), Options} | re:mp() | {re:mp(), Options}</v>
</type>
<desc>
- <p>All reports containing the regular expression <c>RegExp</c>
- are printed.
- </p>
- <p><c>RegExp</c> can be a string containing the regular
- expression; a tuple with the string and the options for
- compilation; a compiled regular expression; a compiled
- regular expression and the options for running it.
- Refer to the module <c>re</c> and specially the function <c>re:run/3</c>
- for a definition of valid regular expressions and options.
- </p>
+ <p>All reports matching the regular expression <c>RegExp</c>
+ are displayed. <c>RegExp</c> can be any of the following:</p>
+ <list type="bulleted">
+ <item>A string containing the regular expression</item>
+ <item>A tuple with the string and the options for compilation</item>
+ <item>A compiled regular expression</item>
+ <item>A compiled regular expression and the options for running it</item>
+ </list>
+ <p>For a definition of valid regular expressions and options, see
+ the <seealso marker="stdlib:re"><c>re</c></seealso> module in
+ <c>STDLIB</c> and in particular function <c>re:run/3</c>.</p>
+ <p>For details about data type <c>mp()</c>, see
+ <seealso marker="stdlib:re#type-mp"><c>re:mp()</c></seealso>.</p>
</desc>
</func>
+
<func>
<name>h()</name>
<name>help()</name>
- <fsummary>Print help information</fsummary>
+ <fsummary>Displays help information.</fsummary>
<desc>
- <p>Prints the on-line help information.
- </p>
+ <p>Displays online help information.</p>
</desc>
</func>
+
<func>
<name>list()</name>
<name>list(Type)</name>
- <fsummary>List all reports</fsummary>
+ <fsummary>Lists all reports.</fsummary>
<type>
<v>Type = type()</v>
<v>type() = error | error_report | info_msg | info_report |
- warning_msg | warning_report | crash_report |
- supervisor_report | progress</v>
+ warning_msg | warning_report | crash_report |
+ supervisor_report | progress</v>
</type>
<desc>
- <p>This function lists all reports loaded in the
+ <p>Lists all reports loaded in
<c>rb_server</c>. Each report is given a unique number that
- can be used as a reference to the report in the
- <c>show/1</c> function.
- </p>
- <p>If no <c>Type</c> is given, all reports are listed.
- </p>
+ can be used as a reference to the report in function
+ <seealso marker="#show/1"><c>show/1</c></seealso>.</p>
+ <p>If no <c>Type</c> is specified, all reports are listed.</p>
</desc>
</func>
+
<func>
<name>log_list()</name>
<name>log_list(Type)</name>
- <fsummary>Log reports list</fsummary>
+ <fsummary>Logs report lists.</fsummary>
<type>
<v>Type = type()</v>
<v>type() = error | error_report | info_msg | info_report |
- warning_msg | warning_report | crash_report |
- supervisor_report | progress</v>
+ warning_msg | warning_report | crash_report |
+ supervisor_report | progress</v>
</type>
<desc>
- <p>Same as <c>list/0</c> or <c>list/1</c> functions
- but result is printed to logfile, if set, otherwise to standard_io.
- </p>
- <p>If no <c>Type</c> is given, all reports are listed.
- </p>
+ <p>Same as functions
+ <seealso marker="#list/0"><c>list/0</c></seealso> or
+ <seealso marker="#list/1"><c>list/1</c></seealso>,
+ but the result is printed to a log file, if set; otherwise
+ to <c>standard_io</c>.</p>
+ <p>If no <c>Type</c> is specified, all reports are listed.</p>
</desc>
</func>
+
<func>
<name>rescan()</name>
<name>rescan(Options)</name>
- <fsummary>Rescan the report directory</fsummary>
+ <fsummary>Rescans the report directory.</fsummary>
<type>
<v>Options = [opt()]</v>
</type>
<desc>
<p>Rescans the report directory. <c>Options</c> is the same as
- for <c>start()</c>.
- </p>
+ for function
+ <seealso marker="#start/1"><c>start/1</c></seealso>.</p>
</desc>
</func>
+
<func>
<name>show()</name>
<name>show(Report)</name>
- <fsummary>Show reports</fsummary>
+ <fsummary>Displays reports.</fsummary>
<type>
- <v>Report = int() | type()</v>
+ <v>Report = integer() | type()</v>
</type>
<desc>
- <p>If a type argument is given, all loaded reports of this
- type are printed. If an integer argument is given, the
- report with this reference number is printed. If no argument
- is given, all reports are shown.
- </p>
+ <p>If argument <c>type</c> is specified, all loaded reports of this
+ type are displayed. If an integer argument is specified, the
+ report with this reference number is displayed. If no argument
+ is specified, all reports are displayed.</p>
</desc>
</func>
+
<func>
<name>start()</name>
<name>start(Options)</name>
- <fsummary>Start the RB server</fsummary>
+ <fsummary>Starts the <c>rb_server</c>.</fsummary>
<type>
<v>Options = [opt()]</v>
- <v>opt() = {start_log, FileName} | {max, MaxNoOfReports} | {report_dir, DirString} | {type, ReportType} | {abort_on_error, Bool}</v>
+ <v>opt() = {start_log, FileName} | {max, MaxNoOfReports} |
+ {report_dir, DirString} | {type, ReportType} |
+ {abort_on_error, Bool}</v>
<v>FileName = string() | atom() | pid()</v>
- <v>MaxNoOfReports = int() | all</v>
+ <v>MaxNoOfReports = integer() | all</v>
<v>DirString = string()</v>
<v>ReportType = type() | [type()] | all</v>
- <v>Bool = true | false</v>
+ <v>Bool = boolean()</v>
</type>
<desc>
- <p>The function <c>start/1</c> starts the <c>rb_server</c>
- with the specified options, while <c>start/0</c> starts with
- default options. The <c>rb_server</c> must be started before
- reports can be browsed. When the <c>rb_server</c> is
+ <p>Function <c>start/1</c> starts <c>rb_server</c> with the
+ specified options, whereas function <c>start/0</c> starts with
+ default options. <c>rb_server</c> must be started before
+ reports can be browsed. When <c>rb_server</c> is
started, the files in the specified directory are
scanned. The other functions assume that the server has
- started.
- </p>
- <p><c>{start_log, FileName}</c> starts logging to file,
- registered name or io_device. All reports will be printed
- to the named file. The default is <c>standard_io</c>.
- The option {start_log, standard_error} is not allowed and
- will be replaced by default standard_io.
- </p>
- <p><c>{max, MaxNoOfReports}</c>. Controls how many reports the
- <c>rb_server</c> should read on start-up. This option is
- useful as the directory may contain 20.000 reports. If this
- option is given, the <c>MaxNoOfReports</c> latest reports
- will be read. The default is 'all'.
- </p>
- <p><c>{report_dir, DirString}</c>. Defines the directory where
- the error log files are located. The default is <c>{sasl, error_logger_mf_dir}</c>. </p>
- <p><c>{type, ReportType}</c>. Controls what kind of reports the
- <c>rb_server</c> should read on start-up. <c>ReportType</c>
- is a supported type, 'all', or a list of supported
- types. The default is 'all'.
- </p>
- <p><c>{abort_on_error, Bool}</c>. This option specifies whether
- or not logging should be aborted if rb encounters an unprintable
- report. (You may get a report on incorrect form if the
- <c>error_logger</c> function <c>error_msg</c> or
- <c>info_msg</c> has been called with an invalid format string).
- If <c>Bool</c> is <c>true</c>, rb will stop logging (and print an
- error message to stdout) if it encounters a badly formatted report.
- If logging to file is enabled, an error message will be appended to
- the log file as well.
- If <c>Bool</c> is <c>false</c> (which is the default value), rb will
- print an error message to stdout for every bad report it
- encounters, but the logging process is never aborted. All printable
- reports will be written. If logging to file is enabled, rb prints
- <c>* UNPRINTABLE REPORT *</c> in the log file at the location of an
- unprintable report.
- </p>
+ started.</p>
+ <p><em>Options:</em></p>
+ <taglist>
+ <tag><c>{start_log, FileName}</c></tag>
+ <item><p>Starts logging to file,
+ registered name, or <c>io_device</c>. All reports are printed
+ to the specified destination. Default is <c>standard_io</c>.
+ Option <c>{start_log, standard_error}</c> is not allowed and
+ will be replaced by default <c>standard_io</c>.</p></item>
+ <tag><c>{max, MaxNoOfReports}</c></tag>
+ <item><p>Controls how many reports
+ <c>rb_server</c> is to read at startup. This option is
+ useful, as the directory can contain a large amount of reports. If this
+ option is specified, the <c>MaxNoOfReports</c> latest reports
+ are read. Default is <c>all</c>.</p></item>
+ <tag><c>{report_dir, DirString}</c></tag>
+ <item><p>Defines the directory where
+ the error log files are located. Default is
+ the directory specified by application environment
+ variable <c>error_logger_mf_dir</c>,
+ see <seealso marker="sasl_app">sasl(6)</seealso>.</p></item>
+ <tag><c>{type, ReportType}</c></tag>
+ <item><p>Controls what kind of reports
+ <c>rb_server</c> is to read at startup. <c>ReportType</c>
+ is a supported type, <c>all</c>, or a list of supported
+ types. Default is <c>all</c>.</p></item>
+ <tag><c>{abort_on_error, Bool}</c></tag>
+ <item><p>Specifies if
+ logging is to be ended if <c>rb</c> encounters an unprintable
+ report. (You can get a report with an incorrect form if function
+ <c>error_logger</c>, <c>error_msg</c>, or
+ <c>info_msg</c> has been called with an invalid format string)</p>
+ <list type="bulleted">
+ <item>If <c>Bool</c> is <c>true</c>, <c>rb</c> stops logging
+ (and prints an error message to <c>stdout</c>) if it encounters
+ a badly formatted report. If logging to file is enabled, an
+ error message is appended to the log file as well.</item>
+ <item>If <c>Bool</c> is <c>false</c> (the default value), <c>rb</c>
+ prints an error message to <c>stdout</c> for every bad report it
+ encounters, but the logging process is never ended. All printable
+ reports are written. If logging to file is enabled, <c>rb</c> prints
+ <c>* UNPRINTABLE REPORT *</c> in the log file at the location of an
+ unprintable report.</item>
+ </list></item>
+ </taglist>
</desc>
</func>
+
<func>
<name>start_log(FileName)</name>
- <fsummary>Redirect all output to <c>FileName</c></fsummary>
+ <fsummary>Redirects all output to <c>FileName</c>.</fsummary>
<type>
<v>FileName = string() | atom() | pid()</v>
</type>
<desc>
<p>Redirects all report output from the RB tool to the
- specified file, registered name or io_device.
- </p>
+ specified file, registered name, or <c>io_device</c>.</p>
</desc>
</func>
+
<func>
<name>stop()</name>
- <fsummary>Stop the RB server</fsummary>
+ <fsummary>Stops the <c>rb_server</c>.</fsummary>
<desc>
- <p>Stops the <c>rb_server</c>.
- </p>
+ <p>Stops <c>rb_server</c>.</p>
</desc>
</func>
+
<func>
<name>stop_log()</name>
- <fsummary>Stop logging to file</fsummary>
+ <fsummary>Stops logging to file.</fsummary>
<desc>
- <p>Closes the log file. The output from the RB tool will be
- directed to <c>standard_io</c>.
- </p>
+ <p>Closes the log file. The output from the RB tool is
+ directed to <c>standard_io</c>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/sasl/doc/src/ref_man.xml b/lib/sasl/doc/src/ref_man.xml
index fa13bf65c3..a80e5a2a00 100644
--- a/lib/sasl/doc/src/ref_man.xml
+++ b/lib/sasl/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,8 +30,8 @@
<file>application.xml</file>
</header>
<description>
- <p>The System Architecture Support Libraries application, <em>SASL</em>,
- provides support for alarm and release handling etc.</p>
+ <p>The <c>SASL</c> application provides support for alarm handling,
+ release handling, and related functions.</p>
</description>
<xi:include href="sasl_app.xml"/>
<xi:include href="alarm_handler.xml"/>
diff --git a/lib/sasl/doc/src/rel.xml b/lib/sasl/doc/src/rel.xml
index 82b54a767e..d5f3c7310a 100644
--- a/lib/sasl/doc/src/rel.xml
+++ b/lib/sasl/doc/src/rel.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -32,74 +33,65 @@
<file>rel</file>
<filesummary>Release resource file</filesummary>
<description>
- <p>The <em>release resource file</em> specifies which applications are
+ <p>The <em>release resource file</em> specifies which applications
are included in a release (system) based on Erlang/OTP.</p>
- <p>This file is used by the functions in <c>systools</c> when generating
- start scripts (<c>.script</c>, <c>.boot</c>) and release upgrade
- files (<c>relup</c>).</p>
+ <p>This file is used by the functions in
+ <seealso marker="systools"><c>systools</c></seealso>
+ when generating start scripts (<c>.script</c>, <c>.boot</c>) and
+ release upgrade files (<c>relup</c>).</p>
</description>
<section>
- <title>FILE SYNTAX</title>
- <p>The release resource file should be called <c>Name.rel</c>.</p>
+ <title>File Syntax</title>
+ <p>The release resource file is to be called <c>Name.rel</c>.</p>
<p>The <c>.rel</c> file contains one single Erlang term, which is
- called a <em>release specification</em>. The file has the
+ called a <em>release specification</em>. The file has the
following syntax:</p>
<code type="none">
{release, {RelName,Vsn}, {erts, EVsn},
[{Application, AppVsn} |
{Application, AppVsn, Type} |
{Application, AppVsn, IncApps} |
- {Application, AppVsn, Type, IncApps}]}.
- </code>
- <list type="bulleted">
- <item>
- <p><c>RelName = string()</c> is the name of the release.</p>
- </item>
- <item>
- <p><c>Vsn = string()</c> is the version of the release.</p>
- </item>
- <item>
- <p><c>EVsn = string()</c> is the version of ERTS the release is
- intended for.</p>
- </item>
- <item>
- <p><c>Application = atom()</c> is the name of an application
- included in the release.</p>
- </item>
- <item>
- <p><c>AppVsn = string()</c> is the version of an application
- included in the release.</p>
- </item>
- <item>
- <p><c>Type = permanent | transient | temporary | load | none</c>
- is the start type of an application included in the release.</p>
- <p>If <c>Type = permanent | transient | temporary</c>,
- the application will be loaded and started in the corresponding
- way, see <c>application(3)</c>. If <c>Type = load</c>,
- the application will only be loaded. If <c>Type = none</c>,
- the application will be neither loaded nor started, although
- the code for its modules will be loaded.
- Defaults to <c>permanent</c></p>
- </item>
- <item>
- <p><c>IncApps = [atom()]</c> is a list of applications that are
- included by an application included in the release.</p>
- <p>The list must be a subset of the included applications
+ {Application, AppVsn, Type, IncApps}]}.</code>
+ <taglist>
+ <tag><c>RelName = string()</c></tag>
+ <item><p>Release name.</p></item>
+ <tag><c>Vsn = string()</c></tag>
+ <item><p>Release version.</p></item>
+ <tag><c>EVsn = string()</c></tag>
+ <item><p><c>ERTS</c> version the release is intended for.</p></item>
+ <tag><c>Application = atom()</c></tag>
+ <item><p>Name of an application included in the release.</p></item>
+ <tag><c>AppVsn = string()</c></tag>
+ <item><p>Version of an application included in the release.</p></item>
+ <tag><c>Type = permanent | transient | temporary | load | none</c></tag>
+ <item><p>Start type of an application included in the release.</p>
+ <p>If <c>Type = permanent | transient | temporary</c>, the
+ application is loaded and started in the corresponding way, see
+ <seealso marker="kernel:application"><c>application(3)</c></seealso>.</p>
+ <p>If <c>Type = load</c>, the application is only loaded.</p>
+ <p>If <c>Type = none</c>, the application is not loaded and not
+ started, although the code for its modules is loaded.</p>
+ <p>Defaults to <c>permanent</c></p></item>
+ <tag><c>IncApps = [atom()]</c></tag>
+ <item><p>A list of applications that are included by an application
+ included in the release. The list must be a subset of the
+ included applications
specified in the application resource file
(<c>Application.app</c>) and overrides this value. Defaults
- to the same value as in the application resource file.</p>
- </item>
- </list>
+ to the same value as in the application resource file.</p></item>
+ </taglist>
<note>
- <p>The list of applications must contain the <c>kernel</c> and
- <c>stdlib</c> applications.</p>
+ <p>The list of applications must contain the <c>Kernel</c> and
+ <c>STDLIB</c> applications.</p>
</note>
</section>
<section>
- <title>SEE ALSO</title>
- <p>application(3), relup(4), systools(3)</p>
+ <title>See Also</title>
+ <p><seealso marker="kernel:application"><c>application(3)</c></seealso>,
+ <seealso marker="relup"><c>relup(4)</c></seealso>,
+ <seealso marker="systools"><c>systools(3)</c></seealso></p>
</section>
</fileref>
diff --git a/lib/sasl/doc/src/release_handler.xml b/lib/sasl/doc/src/release_handler.xml
index b8b9603bc0..162707676c 100644
--- a/lib/sasl/doc/src/release_handler.xml
+++ b/lib/sasl/doc/src/release_handler.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,109 +31,115 @@
<module>release_handler</module>
<modulesummary>Unpacking and Installation of Release Packages</modulesummary>
<description>
- <p>The <em>release handler</em> is a process belonging to the SASL
- application which is responsible for <em>release handling</em>,
+ <p>The <em>release handler</em> process belongs to the <c>SASL</c>
+ application, which is responsible for <em>release handling</em>,
that is, unpacking, installation, and removal of release packages.</p>
- <p>An introduction to release handling and a usage example can be
- found in
- <seealso marker="doc/design_principles:release_handling">Design Principles</seealso>.
- </p>
+ <p>An introduction to release handling and an example is provided in
+ <seealso marker="doc/design_principles:release_handling">OTP Design
+ Principles</seealso> in <em>System Documentation</em>.</p>
<p>A <em>release package</em> is a compressed tar file containing
code for a certain version of a release, created by calling
- <seealso marker="systools#make_tar/1">systools:make_tar/1,2</seealso>.
- The release package should be placed in the <c>$ROOT/releases</c>
- directory of the previous version of the release where
+ <seealso marker="systools#make_tar/1"><c>systools:make_tar/1,2</c></seealso>.
+ The release package is to be located in the <c>$ROOT/releases</c>
+ directory of the previous version of the release, where
<c>$ROOT</c> is the installation root directory,
- <c>code:root_dir()</c>.
- Another <c>releases</c> directory can be specified using the SASL
- configuration parameter <c>releases_dir</c>, or the OS environment
+ <seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso>.
+ Another <c>releases</c> directory can be specified using the <c>SASL</c>
+ configuration parameter <c>releases_dir</c> or the OS environment
variable <c>RELDIR</c>. The release handler must have write access
- to this directory in order to install the new release.
+ to this directory to install the new release.
The persistent state of the release handler is stored there in a
file called <c>RELEASES</c>.</p>
- <p>A release package should always contain the release resource file
- <c>Name.rel</c> and a boot script <c>Name.boot</c>. It may contain
- a release upgrade file <c>relup</c> and a system configuration
- file <c>sys.config</c>. The <c>.rel</c> file contains information
- about the release: its name, version, and which ERTS and
- application versions it uses. The <c>relup</c> file contains
- scripts for how to upgrade to, or downgrade from, this version of
- the release.</p>
+ <p>A release package is always to contain:</p>
+ <list type="bulleted">
+ <item>A release resource file, <c>Name.rel</c></item>
+ <item>A boot script, <c>Name.boot</c></item>
+ </list>
+ <p>The <c>.rel</c> file contains information about the release: its name,
+ version, and which <c>ERTS</c> and application versions it uses.</p>
+ <p>A release package can also contain:</p>
+ <list type="bulleted">
+ <item>A release upgrade file, <c>relup</c></item>
+ <item>A system configuration file, <c>sys.config</c></item>
+ </list>
+ <p>The <c>relup</c> file contains instructions for how to upgrade
+ to, or downgrade from, this version of the release.</p>
<p>The release package can be <em>unpacked</em>, which extracts
the files. An unpacked release can be <em>installed</em>.
The currently used version of the release is then upgraded or
downgraded to the specified version by evaluating the instructions
- in <c>relup</c>. An installed release can be made
- <em>permanent</em>. There can only be one permanent release in
- the system, and this is the release that is used if the system
+ in the <c>relup</c> file. An installed release can be made
+ <em>permanent</em>. Only one permanent release can exist in
+ the system, and this release is used if the system
is restarted. An installed release, except the permanent one,
can be <em>removed</em>. When a release is removed, all files
- that belong to that release only are deleted.</p>
- <p>Each version of the release has a status. The status can be
+ belonging to that release only are deleted.</p>
+ <p>Each release version has a status, which can be
<c>unpacked</c>, <c>current</c>, <c>permanent</c>, or <c>old</c>.
- There is always one latest release which either has status
- <c>permanent</c> (normal case), or <c>current</c> (installed, but
- not yet made permanent). The following table illustrates
- the meaning of the status values:</p>
+ There is always one latest release, which either has status
+ <c>permanent</c> (normal case) or <c>current</c> (installed, but
+ not yet made permanent). The meaning of the status values are
+ illustrated in the following table:</p>
<pre>
-Status Action NextStatus
--------------------------------------------
- - unpack unpacked
-unpacked install current
- remove -
-current make_permanent permanent
- install other old
- remove -
-permanent make other permanent old
- install permanent
-old reboot_old permanent
- install current
- remove -
- </pre>
+ Status Action NextStatus
+ -------------------------------------------
+ - unpack unpacked
+ unpacked install current
+ remove -
+ current make_permanent permanent
+ install other old
+ remove -
+ permanent make other permanent old
+ install permanent
+ old reboot_old permanent
+ install current
+ remove -</pre>
<p>The release handler process is a locally registered process on
each node. When a release is installed in a distributed system,
the release handler on each node must be called. The release
- installation may be synchronized between nodes. From an operator
- view, it may be unsatisfactory to specify each node. The aim is
+ installation can be synchronized between nodes. From an operator
+ view, it can be unsatisfactory to specify each node. The aim is
to install one release package in the system, no matter how many
- nodes there are. If this is the case, it is recommended that
- software management functions are written which take care of
- this problem. Such a function may have knowledge of the system
+ nodes there are. It is recommended that
+ software management functions are written that take care of
+ this problem. Such a function can have knowledge of the system
architecture, so it can contact each individual release handler
to install the package.</p>
- <p>For release handling to work properly, the runtime system needs
- to have knowledge about which release it is currently running. It
- must also be able to change (in run-time) which boot script and
- system configuration file should be used if the system is
+ <p>For release handling to work properly, the runtime system must
+ know which release it is running. It
+ must also be able to change (in runtime) which boot script and
+ system configuration file are to be used if the system is
restarted. This is taken care of automatically if Erlang is
- started as an embedded system. Read about this in <em>Embedded System</em>. In this case, the system configuration file
- <c>sys.config</c> is mandatory.</p>
- <p>The installation of a new release may restart the system. Which
- program to use is specified by the SASL configuration
- parameter <c>start_prg</c> which defaults
+ started as an embedded system. Read about this in
+ <seealso marker="doc/embedded:users_guide">Embedded System</seealso> in
+ <em>System Documentation</em>. In this case, the system
+ configuration file <c>sys.config</c> is mandatory.</p>
+ <p>The installation of a new release can restart the system. Which
+ program to use is specified by the <c>SASL</c> configuration
+ parameter <c>start_prg</c>, which defaults
to <c>$ROOT/bin/start</c>.</p>
<p>The emulator restart on Windows NT expects that the system is
started using the <c>erlsrv</c> program (as a service).
- Furthermore the release handler expects that the service is named
- <em>NodeName</em>_<em>Release</em>, where <em>NodeName</em> is
- the first part of the Erlang nodename (up to, but not including
- the "@") and <em>Release</em> is the current version of
- the release. The release handler furthermore expects that a
+ Furthermore, the release handler expects that the service is named
+ <c>NodeName</c>_<c>Release</c>, where <c>NodeName</c> is
+ the first part of the Erlang node name (up to, but not including
+ the "@") and <c>Release</c> is the current release version.
+ The release handler furthermore expects that a
program like <c>start_erl.exe</c> is specified as "machine" to
- <c>erlsrv</c>. During upgrading with restart, a new service will
- be registered and started. The new service will be set to
- automatic and the old service removed as soon as the new release
+ <c>erlsrv</c>. During upgrading with restart, a new service
+ is registered and started. The new service is set to
+ automatic and the old service is removed when the new release
is made permanent.</p>
- <p>The release handler at a node which runs on a diskless machine,
+ <p>The release handler at a node running on a diskless machine,
or with a read-only file system, must be configured accordingly
- using the following <c>sasl</c> configuration parameters (see
- <seealso marker="sasl_app">sasl(6)</seealso> for details):</p>
+ using the following <c>SASL</c> configuration parameters (for
+ details, see <seealso marker="sasl_app">sasl(6)</seealso>):</p>
<taglist>
<tag><c>masters</c></tag>
<item>
- <p>This node uses a number of master nodes in order to store
- and fetch release information. All master nodes must be up
- and running whenever release information is written by this
+ <p>This node uses some master nodes to store
+ and fetch release information. All master nodes must be
+ operational whenever release information is written by this
node.</p>
</item>
<tag><c>client_directory</c></tag>
@@ -144,24 +151,25 @@ old reboot_old permanent
<item>
<p>This parameter specifies if the Erlang emulator is
statically installed at the client node. A node with a static
- emulator cannot dynamically switch to a new emulator because
+ emulator cannot dynamically switch to a new emulator, as
the executable files are statically written into memory.</p>
</item>
</taglist>
- <p>It is also possible to use the release handler to unpack and
+ <p>The release handler can also be used to unpack and
install release packages when not running Erlang as an embedded
- system, but in this case the user must somehow make sure that
+ system. However, in this case the user must somehow ensure that
correct boot scripts and configuration files are used if
- the system needs to be restarted.</p>
- <p>There are additional functions for using another file structure
+ the system must be restarted.</p>
+ <p>Functions are provided for using another file structure
than the structure defined in OTP. These functions can be used
to test a release upgrade locally.</p>
</description>
+
<funcs>
<func>
<name>check_install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}</name>
<name>check_install_release(Vsn,Opts) -> {ok, OtherVsn, Descr} | {error, Reason}</name>
- <fsummary>Check installation of a release in the system.</fsummary>
+ <fsummary>Checks installation of a release in the system.</fsummary>
<type>
<v>Vsn = OtherVsn = string()</v>
<v>Opts = [Opt]</v>
@@ -172,27 +180,29 @@ old reboot_old permanent
<desc>
<p>Checks if the specified version <c>Vsn</c> of the release
can be installed. The release must not have status
- <c>current</c>. Issues warnings if <c>relup</c> or
- <c>sys.config</c> are not present. If <c>relup</c> is present,
+ <c>current</c>. Issues warnings if <c>relup</c> file or
+ <c>sys.config</c> is not present. If <c>relup</c> file is present,
its contents are checked and <c>{error,Reason}</c> is
returned if an error is found. Also checks that all required
- applications are present and that all new code can be loaded,
- or <c>{error,Reason}</c> is returned.</p>
- <p>This function evaluates all instructions that occur before
+ applications are present and that all new code can be loaded;
+ <c>{error,Reason}</c> is returned if an error is found.</p>
+ <p>Evaluates all instructions that occur before
the <c>point_of_no_return</c> instruction in the release
upgrade script.</p>
- <p>Returns the same as <c>install_release/1</c>. <c>Descr</c>
- defaults to "" if no <c>relup</c> file is found.</p>
- <p>If the option <c>purge</c> is given, all old code that can
- be soft purged will be purged after all other checks are
- successfully completed. This can be useful in order to
+ <p>Returns the same as
+ <seealso marker="#install_release/1"><c>install_release/1</c></seealso>.
+ <c>Descr</c> defaults to "" if no <c>relup</c> file is found.</p>
+ <p>If option <c>purge</c> is specified, all old code that can
+ be soft-purged is purged after all other checks are
+ successfully completed. This can be useful to
reduce the time needed by <seealso
- marker="#install_release/1">install_release</seealso>.</p>
+ marker="#install_release/1"><c>install_release/1</c></seealso>.</p>
</desc>
</func>
+
<func>
<name>create_RELEASES(Root, RelDir, RelFile, AppDirs) -> ok | {error, Reason}</name>
- <fsummary>Create an initial RELEASES file.</fsummary>
+ <fsummary>Creates an initial <c>RELEASES</c> file.</fsummary>
<type>
<v>Root = RelDir = RelFile = string()</v>
<v>AppDirs = [{App, Vsn, Dir}]</v>
@@ -201,52 +211,55 @@ old reboot_old permanent
<v>Reason = term()</v>
</type>
<desc>
- <p>Creates an initial RELEASES file to be used by the release
- handler. This file must exist in order to install new
+ <p>Creates an initial <c>RELEASES</c> file to be used by the
+ release handler. This file must exist to install new
releases.</p>
<p><c>Root</c> is the root of the installation (<c>$ROOT</c>) as
- described above. <c>RelDir</c> is the the directory where
- the <c>RELEASES</c> file should be created (normally
+ described earlier. <c>RelDir</c> is the directory where
+ the <c>RELEASES</c> file is to be created (normally
<c>$ROOT/releases</c>). <c>RelFile</c> is the name
of the <c>.rel</c> file that describes the initial release,
including the extension <c>.rel</c>.</p>
<p><c>AppDirs</c> can be used to specify from where the modules
- for the specified applications should be loaded. <c>App</c> is
+ for the specified applications are to be loaded. <c>App</c> is
the name of an application, <c>Vsn</c> is the version, and
<c>Dir</c> is the name of the directory where <c>App-Vsn</c>
- is located. The corresponding modules should be located under
+ is located. The corresponding modules are to be located under
<c>Dir/App-Vsn/ebin</c>. The directories for applications not
specified in <c>AppDirs</c> are assumed to be located in
<c>$ROOT/lib</c>.</p>
</desc>
</func>
+
<func>
<name>install_file(Vsn, File) -> ok | {error, Reason}</name>
- <fsummary>Install a release file in the release structure.</fsummary>
+ <fsummary>Installs a release file in the release structure.</fsummary>
<type>
<v>Vsn = File = string()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Installs a release dependent file in the release structure.
- A release dependent file is a file that must be in
+ <p>Installs a release-dependent file in the release structure.
+ The release-dependent file must be in
the release structure when a new release is installed:
- <c>start.boot</c>, <c>relup</c> and <c>sys.config</c>.</p>
+ <c>start.boot</c>, <c>relup</c>, and <c>sys.config</c>.</p>
<p>The function can be called, for example, when these files
- are generated at the target. It should be called after
- <c>set_unpacked/2</c> has been called.</p>
+ are generated at the target. The function is to be called after
+ <seealso marker="#set_unpacked/2"><c>set_unpacked/2</c></seealso>
+ has been called.</p>
</desc>
</func>
+
<func>
<name>install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}</name>
<name>install_release(Vsn, [Opt]) -> {ok, OtherVsn, Descr} | {continue_after_restart, OtherVsn, Descr} | {error, Reason}</name>
- <fsummary>Install a release in the system.</fsummary>
+ <fsummary>Installs a release in the system.</fsummary>
<type>
<v>Vsn = OtherVsn = string()</v>
<v>Opt = {error_action, Action} | {code_change_timeout, Timeout}</v>
<v>&nbsp;&nbsp;&nbsp;| {suspend_timeout, Timeout} | {update_paths, Bool}</v>
<v>&nbsp;Action = restart | reboot</v>
- <v>&nbsp;Timeout = default | infinity | int()>0</v>
+ <v>&nbsp;Timeout = default | infinity | pos_integer()</v>
<v>&nbsp;Bool = boolean()</v>
<v>Descr = term()</v>
<v>Reason = {illegal_option, Opt} | {already_installed, Vsn} | {change_appl_data, term()} | {missing_base_app, OtherVsn, App} | {could_not_create_hybrid_boot, term()} | term()</v>
@@ -261,7 +274,7 @@ old reboot_old permanent
version and a script <c>{Vsn,Descr2,Instructions2}</c> in this
file for downgrading to <c>Vsn</c>.</p>
<p>If a script is found, the first thing that happens is that
- the applications specifications are updated according to
+ the application specifications are updated according to
the <c>.app</c> files and <c>sys.config</c> belonging to
the release version <c>Vsn</c>.</p>
<p>After the application specifications have been updated,
@@ -270,101 +283,120 @@ old reboot_old permanent
<c>OtherVsn</c> and <c>Descr</c> are the version
(<c>UpFromVsn</c> or <c>Vsn</c>) and description
(<c>Descr1</c> or <c>Descr2</c>) as specified in the script.</p>
- <p>If <c>{continue_after_restart,OtherVsn,Descr}</c> is
- returned, it means that the emulator will be restarted
- before the upgrade instructions are executed. This will
- happen if the emulator or any of the applications kernel,
- stdlib or sasl are updated. The new version of the emulator
- and these core applications will execute after the restart,
- but for all other applications the old versions will be
- started and the upgrade will be performed as normal by
+ <p>If <c>{continue_after_restart,OtherVsn,Descr}</c> is
+ returned, the emulator is restarted
+ before the upgrade instructions are executed. This
+ occurs if the emulator or any of the applications
+ <c>Kernel</c>, <c>STDLIB</c>, or <c>SASL</c>
+ are updated. The new emulator version
+ and these core applications execute after the restart.
+ For all other applications the old versions are
+ started and the upgrade is performed as normal by
executing the upgrade instructions.</p>
<p>If a recoverable error occurs, the function returns
<c>{error,Reason}</c> and the original application
specifications are restored. If a non-recoverable error
occurs, the system is restarted.</p>
- <p>The option <c>error_action</c> defines if the node should be
- restarted (<c>init:restart()</c>) or rebooted
- (<c>init:reboot()</c>) in case of an error during
- the installation. Default is <c>restart</c>.</p>
- <p>The option <c>code_change_timeout</c> defines the timeout
- for all calls to <c>sys:change_code</c>. If no value is
- specified or <c>default</c> is given, the default value
- defined in <c>sys</c> is used.</p>
- <p>The option <c>suspend_timeout</c> defines the timeout for
- all calls to <c>sys:suspend</c>. If no value is specified,
- the values defined by the <c>Timeout</c> parameter of
- the <c>upgrade</c> or <c>suspend</c> instructions are used.
- If <c>default</c> is specified, the default value defined in
- <c>sys</c> is used.</p>
- <p>The option <c>{update_paths,Bool}</c> indicates if all
- application code paths should be updated (<c>Bool==true</c>),
- or if only code paths for modified applications should be
- updated (<c>Bool==false</c>, default). This option only has
- effect for other application directories than the default
- <c>$ROOT/lib/App-Vsn</c>, that is, application directories
- provided in the <c>AppDirs</c> argument in a call to
- <c>create_RELEASES/4</c> or <c>set_unpacked/2</c>.</p>
- <p>Example: In the current version <c>CurVsn</c> of a release,
- the application directory of <c>myapp</c> is
- <c>$ROOT/lib/myapp-1.0</c>. A new version <c>NewVsn</c> is
- unpacked outside the release handler, and the release handler
- is informed about this with a call to:</p>
- <code type="none">
+ <p><em>Options</em>:</p>
+ <taglist>
+ <tag><c>error_action</c></tag>
+ <item><p>Defines if the node is to be
+ restarted
+ (<seealso marker="erts:init#restart/0"><c>init:restart()</c></seealso>)
+ or rebooted
+ (<seealso marker="erts:init#reboot/0"><c>init:reboot()</c></seealso>)
+ if there is an error during
+ the installation. Default is <c>restart</c>.</p></item>
+ <tag><c>code_change_timeout</c></tag>
+ <item><p>Defines the time-out
+ for all calls to
+ <seealso marker="stdlib:sys#change_code/4"><c>stdlib:sys:change_code</c></seealso>.
+ If no value is specified or <c>default</c> is specified, the
+ default value defined in <c>sys</c> is used.</p></item>
+ <tag><c>suspend_timeout</c></tag>
+ <item><p>Defines the time-out for
+ all calls to
+ <seealso marker="stdlib:sys#suspend/1"><c>stdlib:sys:suspend</c></seealso>.
+ If no value is specified, the values defined by the <c>Timeout</c>
+ parameter of the <c>upgrade</c> or <c>suspend</c> instructions are used.
+ If <c>default</c> is specified, the default value defined in
+ <c>sys</c> is used.</p></item>
+ <tag><c>{update_paths,Bool}</c></tag>
+ <item><p>Indicates if all
+ application code paths are to be updated (<c>Bool==true</c>)
+ or if only code paths for modified applications are to be
+ updated (<c>Bool==false</c>, default). This option has only
+ effect for other application directories than the default
+ <c>$ROOT/lib/App-Vsn</c>, that is, application directories
+ specified in argument <c>AppDirs</c> in a call to
+ <seealso marker="#create_RELEASES/4"><c>create_RELEASES/4</c></seealso> or
+ <seealso marker="#set_unpacked/2"><c>set_unpacked/2</c></seealso>.</p>
+ <p><em>Example:</em></p>
+ <p>In the current version <c>CurVsn</c> of a release, the
+ application directory of <c>myapp</c> is
+ <c>$ROOT/lib/myapp-1.0</c>. A new version <c>NewVsn</c> is
+ unpacked outside the release handler and the release
+ handler is informed about this with a call as follows:</p>
+ <code type="none">
release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
-=> {ok,NewVsn}
- </code>
- <p>If <c>NewVsn</c> is installed with the option
- <c>{update_paths,true}</c>, afterwards
- <c>code:lib_dir(myapp)</c> will return
- <c>/home/user/myapp-1.0</c>.</p>
+=> {ok,NewVsn}</code>
+ <p>If <c>NewVsn</c> is installed with option
+ <c>{update_paths,true}</c>, then
+ <seealso marker="kernel:code#lib_dir/1"><c>kernel:code:lib_dir(myapp)</c></seealso>
+ returns <c>/home/user/myapp-1.0</c>.</p></item>
+ </taglist>
<note>
- <p>Installing a new release might be quite time consuming if
+ <p>Installing a new release can be time consuming if
there are many processes in the system. The reason is that
each process must be checked for references to old code
- before a module can be purged. This check might lead to
+ before a module can be purged. This check can lead to
garbage collections and copying of data.</p>
- <p>If you wish to speed up the execution of
- <c>install_release</c>, then you may call <seealso
- marker="#check_install_release/1">check_install_release</seealso>
- first, using the option <c>purge</c>. This will do the same
- check for old code, and then purge all modules that can be
- soft purged. The purged modules will then no longer have any
- old code, and <c>install_release</c> will not need to do the
+ <p>To speed up the execution of
+ <seealso marker="#install_release/1"><c>install_release</c></seealso>,
+ first call <seealso
+ marker="#check_install_release/1"><c>check_install_release</c></seealso>,
+ using option <c>purge</c>. This does the same
+ check for old code. Then purges all modules that can be
+ soft-purged. The purged modules do then no longer have any
+ old code, and
+ <seealso marker="#install_release/1"><c>install_release</c></seealso>
+ does not need to do the
checks.</p>
- <p>Obviously, this will not reduce the overall time for the
- upgrade, but it will allow checks and purge to be executed
+ <p>This does not reduce the overall time for the
+ upgrade, but it allows checks and purge to be executed
in the background before the real upgrade is started.</p>
</note>
<note>
<p>When upgrading the emulator from a version older than OTP
- R15, there will be an attempt to load new application beam
- code into the old emulator. In some cases, the new beam
- format can not be read by the old emulator, and so the code
- loading will fail and terminate the complete upgrade. To
- overcome this problem, the new application code should be
- compiled with the old emulator. See <seealso
- marker="doc/design_principles:appup_cookbook">Design
- Principles</seealso> for more information about emulator
- upgrade from pre OTP R15 versions.</p>
+ R15, an attempt is made to load new application beam
+ code into the old emulator. Sometimes the new beam
+ format cannot be read by the old emulator, so the code
+ loading fails and the complete upgrade is terminated. To
+ overcome this problem, the new application code is to be
+ compiled with the old emulator. For more information about
+ emulator upgrade from pre OTP R15 versions, see
+ <seealso marker="doc/design_principles:appup_cookbook">Design
+ Principles</seealso> in <em>System Documentation</em>.</p>
</note>
</desc>
</func>
+
<func>
<name>make_permanent(Vsn) -> ok | {error, Reason}</name>
- <fsummary>Make the specified release version permanent.</fsummary>
+ <fsummary>Makes the specified release version permanent.</fsummary>
<type>
<v>Vsn = string()</v>
<v>Reason = {bad_status, Status} | term()</v>
</type>
<desc>
- <p>Makes the specified version <c>Vsn</c> of the release
+ <p>Makes the specified release version <c>Vsn</c>
permanent.</p>
</desc>
</func>
+
<func>
<name>remove_release(Vsn) -> ok | {error, Reason}</name>
- <fsummary>Remove a release from the system.</fsummary>
+ <fsummary>Removes a release from the system.</fsummary>
<type>
<v>Vsn = string()</v>
<v>Reason = {permanent, Vsn} | client_node | term()</v>
@@ -374,23 +406,26 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
The release must not be the permanent release. Removes only
the files and directories not in use by another release.</p>
</desc>
+
</func>
<func>
<name>reboot_old_release(Vsn) -> ok | {error, Reason}</name>
- <fsummary>Reboot the system from an old release.</fsummary>
+ <fsummary>Reboots the system from an old release.</fsummary>
<type>
<v>Vsn = string()</v>
<v>Reason = {bad_status, Status} | term()</v>
</type>
<desc>
<p>Reboots the system by making the old release permanent, and
- calls <c>init:reboot()</c> directly. The release must have
- status <c>old</c>.</p>
+ calls
+ <seealso marker="erts:init#reboot/0"><c>init:reboot()</c></seealso>
+ directly. The release must have status <c>old</c>.</p>
</desc>
</func>
+
<func>
<name>set_removed(Vsn) -> ok | {error, Reason}</name>
- <fsummary>Mark a release as removed.</fsummary>
+ <fsummary>Marks a release as removed.</fsummary>
<type>
<v>Vsn = string()</v>
<v>Reason = {permanent, Vsn} | term()</v>
@@ -402,9 +437,10 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
not delete any files.</p>
</desc>
</func>
+
<func>
<name>set_unpacked(RelFile, AppDirs) -> {ok, Vsn} | {error, Reason}</name>
- <fsummary>Mark a release as unpacked.</fsummary>
+ <fsummary>Marks a release as unpacked.</fsummary>
<type>
<v>RelFile = string()</v>
<v>AppDirs = [{App, Vsn, Dir}]</v>
@@ -418,18 +454,19 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
the release is unpacked. <c>Vsn</c> is extracted from
the release resource file <c>RelFile</c>.</p>
<p><c>AppDirs</c> can be used to specify from where the modules
- for the specified applications should be loaded. <c>App</c> is
+ for the specified applications are to be loaded. <c>App</c> is
the name of an application, <c>Vsn</c> is the version, and
<c>Dir</c> is the name of the directory where <c>App-Vsn</c>
- is located. The corresponding modules should be located under
+ is located. The corresponding modules are to be located under
<c>Dir/App-Vsn/ebin</c>. The directories for applications not
specified in <c>AppDirs</c> are assumed to be located in
<c>$ROOT/lib</c>.</p>
</desc>
</func>
+
<func>
<name>unpack_release(Name) -> {ok, Vsn} | {error, Reason}</name>
- <fsummary>Unpack a release package.</fsummary>
+ <fsummary>Unpacks a release package.</fsummary>
<type>
<v>Name = Vsn = string()</v>
<v>Reason = client_node | term()</v>
@@ -437,14 +474,15 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
<desc>
<p>Unpacks a release package <c>Name.tar.gz</c> located in
the <c>releases</c> directory.</p>
- <p>Performs some checks on the package - for example checks
- that all mandatory files are present - and extracts its
+ <p>Performs some checks on the package, for example, checks
+ that all mandatory files are present, and extracts its
contents.</p>
</desc>
</func>
+
<func>
<name>which_releases() -> [{Name, Vsn, Apps, Status}]</name>
- <fsummary>Return all known releases</fsummary>
+ <fsummary>Returns all known releases.</fsummary>
<type>
<v>Name = Vsn = string()</v>
<v>Apps = ["App-Vsn"]</v>
@@ -454,16 +492,18 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
<p>Returns all releases known to the release handler.</p>
</desc>
</func>
+
<func>
<name>which_releases(Status) -> [{Name, Vsn, Apps, Status}]</name>
- <fsummary>Return all known releases of a specific status</fsummary>
+ <fsummary>Returns all known releases of a specific status.</fsummary>
<type>
<v>Name = Vsn = string()</v>
<v>Apps = ["App-Vsn"]</v>
<v>Status = unpacked | current | permanent | old</v>
</type>
<desc>
- <p>Returns all releases known to the release handler of a specific status.</p>
+ <p>Returns all releases, known to the release handler, of a
+ specific status.</p>
</desc>
</func>
</funcs>
@@ -472,7 +512,8 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
<title>Application Upgrade/Downgrade</title>
<p>The following functions can be used to test upgrade and downgrade
of single applications (instead of upgrading/downgrading an entire
- release). A script corresponding to <c>relup</c> is created
+ release). A script corresponding to the instructions in the
+ <c>relup</c> file is created
on-the-fly, based on the <c>.appup</c> file for the application,
and evaluated exactly in the same way as <c>release_handler</c>
does.</p>
@@ -481,20 +522,22 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
of <c>.appup</c> files. They are not run within the context of
the <c>release_handler</c> process. They must therefore
<em>not</em> be used together with calls to
- <c>install_release/1,2</c>, as this will cause
+ <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>,
+ as this causes the
<c>release_handler</c> to end up in an inconsistent state.</p>
- <p>No persistent information is updated, why these functions can
+ <p>No persistent information is updated, so these functions can
be used on any Erlang node, embedded or not. Also, using these
- functions does not affect which code will be loaded in case of
+ functions does not affect which code is loaded if there is
a reboot.</p>
- <p>If the upgrade or downgrade fails, the application may end up
+ <p>If the upgrade or downgrade fails, the application can end up
in an inconsistent state.</p>
</warning>
</section>
+
<funcs>
<func>
<name>upgrade_app(App, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name>
- <fsummary>Upgrade to a new application version</fsummary>
+ <fsummary>Upgrades to a new application version.</fsummary>
<type>
<v>App = atom()</v>
<v>Dir = string()</v>
@@ -505,39 +548,46 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
<desc>
<p>Upgrades an application <c>App</c> from the current
version to a new version located in <c>Dir</c> according to
- the <c>.appup</c> script.</p>
+ the <c>.appup</c> file.</p>
<p><c>App</c> is the name of the application, which must be
started. <c>Dir</c> is the new library directory of
- <c>App</c>, the corresponding modules as well as
- the <c>.app</c> and <c>.appup</c> files should be located
+ <c>App</c>. The corresponding modules as well as
+ the <c>.app</c> and <c>.appup</c> files are to be located
under <c>Dir/ebin</c>.</p>
<p>The function looks in the <c>.appup</c> file and tries to
find an upgrade script from the current version of
the application using
- <seealso marker="#upgrade_script/2">upgrade_script/2</seealso>.
+ <seealso marker="#upgrade_script/2"><c>upgrade_script/2</c></seealso>.
This script is evaluated using
- <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>,
+ <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>,
exactly in the same way as
- <seealso marker="#install_release/1">install_release/1,2</seealso>
+ <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>
does.</p>
- <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is
- successful, where <c>Unpurged</c> is a list of unpurged
- modules, or <c>restart_emulator</c> if this instruction is
- encountered in the script, or <c>{error, Reason}</c> if
- an error occurred when finding or evaluating the script.</p>
+ <p>Returns one of the following:</p>
+ <list type="bulleted">
+ <item><c>{ok, Unpurged}</c> if evaluating the script is
+ successful, where <c>Unpurged</c> is a list of unpurged
+ modules</item>
+ <item><c>restart_emulator</c> if this instruction is
+ encountered in the script</item>
+ <item><c>{error, Reason}</c> if an error occurred when
+ finding or evaluating the script</item>
+ </list>
<p>If the <c>restart_new_emulator</c> instruction is found in
- the script, <c>upgrade_app/2</c> will return
- <c>{error,restart_new_emulator}</c>. The reason for this is
- that this instruction requires that a new version of the
- emulator is started before the rest of the upgrade
- instructions can be executed, and this can only be done by
- <c>install_release/1,2</c>.</p>
+ the script,
+ <seealso marker="#upgrade_app/2"><c>upgrade_app/2</c></seealso>
+ returns <c>{error,restart_new_emulator}</c>. This because
+ <c>restart_new_emulator</c> requires a new version of the
+ emulator to be started before the rest of the upgrade
+ instructions can be executed, and this can only be done by
+ <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>.</p>
</desc>
</func>
+
<func>
<name>downgrade_app(App, Dir) -></name>
<name>downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name>
- <fsummary>Downgrade to a previous application version</fsummary>
+ <fsummary>Downgrades to a previous application version.</fsummary>
<type>
<v>App = atom()</v>
<v>Dir = OldVsn = string()</v>
@@ -548,110 +598,124 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
<desc>
<p>Downgrades an application <c>App</c> from the current
version to a previous version <c>OldVsn</c> located in
- <c>Dir</c> according to the <c>.appup</c> script.</p>
+ <c>Dir</c> according to the <c>.appup</c> file.</p>
<p><c>App</c> is the name of the application, which must be
- started. <c>OldVsn</c> is the previous version of
- the application and can be omitted if <c>Dir</c> is of
+ started. <c>OldVsn</c> is the previous application version
+ and can be omitted if <c>Dir</c> is of
the format <c>"App-OldVsn"</c>. <c>Dir</c> is the library
- directory of this previous version of <c>App</c>,
- the corresponding modules as well as the old <c>.app</c> file
- should be located under <c>Dir/ebin</c>. The <c>.appup</c>
- file should be located in the <c>ebin</c> directory of
+ directory of the previous version of <c>App</c>.
+ The corresponding modules and the old <c>.app</c> file
+ are to be located under <c>Dir/ebin</c>. The <c>.appup</c>
+ file is to be located in the <c>ebin</c> directory of
the <em>current</em> library directory of the application
- (<c>code:lib_dir(App)</c>).</p>
+ (<seealso marker="kernel:code#lib_dir/1"><c>code:lib_dir(App)</c></seealso>).</p>
<p>The function looks in the <c>.appup</c> file and tries to
- find an downgrade script to the previous version of
+ find a downgrade script to the previous version of
the application using
- <seealso marker="#downgrade_script/3">downgrade_script/3</seealso>.
+ <seealso marker="#downgrade_script/3"><c>downgrade_script/3</c></seealso>.
This script is evaluated using
- <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>,
+ <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>,
exactly in the same way as
- <seealso marker="#install_release/1">install_release/1,2</seealso>
+ <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>
does.</p>
- <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is
- successful, where <c>Unpurged</c> is a list of unpurged
- modules, or <c>restart_emulator</c> if this instruction is
- encountered in the script, or <c>{error, Reason}</c> if
- an error occurred when finding or evaluating the script.</p>
+ <p>Returns one of the following:</p>
+ <list type="bulleted">
+ <item><c>{ok, Unpurged}</c> if evaluating the script is
+ successful, where <c>Unpurged</c> is a list of unpurged
+ modules</item>
+ <item><c>restart_emulator</c> if this instruction is
+ encountered in the script</item>
+ <item><c>{error, Reason}</c> if an error occurred when
+ finding or evaluating the script</item>
+ </list>
</desc>
</func>
+
<func>
<name>upgrade_script(App, Dir) -> {ok, NewVsn, Script}</name>
- <fsummary>Find an application upgrade script</fsummary>
+ <fsummary>Finds an application upgrade script.</fsummary>
<type>
<v>App = atom()</v>
<v>Dir = string()</v>
<v>NewVsn = string()</v>
- <v>Script = Instructions -- see appup(4)</v>
+ <v>Script = Instructions</v>
</type>
<desc>
<p>Tries to find an application upgrade script for <c>App</c>
from the current version to a new version located in
<c>Dir</c>.</p>
<p>The upgrade script can then be evaluated using
- <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>.
+ <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>.
It is recommended to use
- <seealso marker="#upgrade_app/2">upgrade_app/2</seealso>
- instead, but this function is useful in order to inspect
- the contents of the script.</p>
+ <seealso marker="#upgrade_app/2"><c>upgrade_app/2</c></seealso>
+ instead, but this function (<c>upgrade_script</c>) is useful
+ to inspect the contents of the script.</p>
<p><c>App</c> is the name of the application, which must be
started. <c>Dir</c> is the new library directory of
- <c>App</c>, the corresponding modules as well as
- the <c>.app</c> and <c>.appup</c> files should be located
+ <c>App</c>. The corresponding modules as well as
+ the <c>.app</c> and <c>.appup</c> files are to be located
under <c>Dir/ebin</c>.</p>
<p>The function looks in the <c>.appup</c> file and tries to
- find an upgrade script from the current version of
- the application. High-level instructions are translated to
- low-level instructions and the instructions are sorted in
- the same manner as when generating a <c>relup</c> script.</p>
+ find an upgrade script from the current application version.
+ High-level instructions are translated to
+ low-level instructions. The instructions are sorted in
+ the same manner as when generating a <c>relup</c> file.</p>
<p>Returns <c>{ok, NewVsn, Script}</c> if successful, where
- <c>NewVsn</c> is the new application version.</p>
+ <c>NewVsn</c> is the new application version.
+ For details about <c>Script</c>, see
+ <seealso marker="appup"><c>appup(4)</c></seealso>.</p>
<p>Failure: If a script cannot be found, the function fails
with an appropriate error reason.</p>
</desc>
</func>
+
<func>
<name>downgrade_script(App, OldVsn, Dir) -> {ok, Script}</name>
- <fsummary>Find an application downgrade script</fsummary>
+ <fsummary>Finds an application downgrade script.</fsummary>
<type>
<v>App = atom()</v>
<v>OldVsn = Dir = string()</v>
- <v>Script = Instructions -- see appup(4)</v>
+ <v>Script = Instructions</v>
</type>
<desc>
<p>Tries to find an application downgrade script for <c>App</c>
from the current version to a previous version <c>OldVsn</c>
located in <c>Dir</c>.</p>
<p>The downgrade script can then be evaluated using
- <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>.
+ <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>.
It is recommended to use
- <seealso marker="#downgrade_app/2">downgrade_app/2,3</seealso>
- instead, but this function is useful in order to inspect
- the contents of the script.</p>
+ <seealso marker="#downgrade_app/2"><c>downgrade_app/2,3</c></seealso>
+ instead, but this function (<c>downgrade_script</c>) is useful
+ to inspect the contents of the script.</p>
<p><c>App</c> is the name of the application, which must be
started. <c>Dir</c> is the previous library directory of
- <c>App</c>, the corresponding modules as well as
- the old <c>.app</c> file should be located under
- <c>Dir/ebin</c>. The <c>.appup</c> file should be located in
+ <c>App</c>. The corresponding modules and
+ the old <c>.app</c> file are to be located under
+ <c>Dir/ebin</c>. The <c>.appup</c> file is to be located in
the <c>ebin</c> directory of the <em>current</em> library
- directory of the application (<c>code:lib_dir(App)</c>).</p>
+ directory of the application
+ (<seealso marker="kernel:code#lib_dir/1"><c>code:lib_dir(App)</c>)</seealso>.</p>
<p>The function looks in the <c>.appup</c> file and tries to
- find an downgrade script from the current version of
- the application. High-level instructions are translated to
- low-level instructions and the instructions are sorted in
- the same manner as when generating a <c>relup</c> script.</p>
- <p>Returns <c>{ok, Script}</c> if successful.</p>
+ find a downgrade script from the current application version.
+ High-level instructions are translated to
+ low-level instructions. The instructions are sorted in
+ the same manner as when generating a <c>relup</c> file.</p>
+ <p>Returns <c>{ok, Script}</c> if successful.
+ For details about <c>Script</c>, see
+ <seealso marker="appup"><c>appup(4)</c></seealso>.</p>
<p>Failure: If a script cannot be found, the function fails
with an appropriate error reason.</p>
</desc>
</func>
+
<func>
<name>eval_appup_script(App, ToVsn, ToDir, Script) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name>
- <fsummary>Evaluate an application upgrade or downgrade script</fsummary>
+ <fsummary>Evaluates an application upgrade or downgrade script.</fsummary>
<type>
<v>App = atom()</v>
<v>ToVsn = ToDir = string()</v>
- <v>Script -- see upgrade_script/2, downgrade_script/3</v>
+ <v>Script</v>
+ <d>See <seealso marker="#upgrade_script/2"><c>upgrade_script/2</c></seealso>, <seealso marker="#downgrade_script/3"><c>downgrade_script/3</c></seealso></d>
<v>Unpurged = [Module]</v>
<v>&nbsp;Module = atom()</v>
<v>Reason = term()</v>
@@ -659,114 +723,100 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
<desc>
<p>Evaluates an application upgrade or downgrade script
<c>Script</c>, the result from calling
- <seealso marker="#upgrade_app/2">upgrade_script/2</seealso> or
- <seealso marker="#downgrade_app/3">downgrade_script/3</seealso>,
+ <seealso marker="#upgrade_script/2"><c>upgrade_script/2</c></seealso> or
+ <seealso marker="#downgrade_script/3"><c>downgrade_script/3</c></seealso>,
exactly in the same way as
- <seealso marker="#install_release/1">install_release/1,2</seealso>
+ <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>
does.</p>
<p><c>App</c> is the name of the application, which must be
started. <c>ToVsn</c> is the version to be upgraded/downgraded
to, and <c>ToDir</c> is the library directory of this version.
The corresponding modules as well as the <c>.app</c> and
- <c>.appup</c> files should be located under <c>Dir/ebin</c>.</p>
- <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is
- successful, where <c>Unpurged</c> is a list of unpurged
- modules, or <c>restart_emulator</c> if this instruction is
- encountered in the script, or <c>{error, Reason}</c> if
- an error occurred when evaluating the script.</p>
- <p>If the <c>restart_new_emulator</c> instruction is found in
- the script, <c>eval_appup_script/4</c> will return
- <c>{error,restart_new_emulator}</c>. The reason for this is
- that this instruction requires that a new version of the
- emulator is started before the rest of the upgrade
- instructions can be executed, and this can only be done by
- <c>install_release/1,2</c>.</p>
+ <c>.appup</c> files are to be located under <c>Dir/ebin</c>.</p>
+ <p>Returns one of the following:</p>
+ <list type="bulleted">
+ <item><c>{ok, Unpurged}</c> if evaluating the script is
+ successful, where <c>Unpurged</c> is a list of unpurged
+ modules</item>
+ <item><c>restart_emulator</c> if this instruction is
+ encountered in the script</item>
+ <item><c>{error, Reason}</c> if an error occurred when
+ finding or evaluating the script</item>
+ </list>
+ <p>If the <c>restart_new_emulator</c> instruction is found in
+ the script,
+ <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>
+ returns <c>{error,restart_new_emulator}</c>. This because
+ <c>restart_new_emulator</c> requires a new version of the
+ emulator to be started before the rest of the upgrade
+ instructions can be executed, and this can only be done by
+ <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>.</p>
</desc>
</func>
</funcs>
<section>
<title>Typical Error Reasons</title>
- <list type="bulleted">
- <item>
- <p><c>{bad_masters, Masters}</c> - The master nodes
- <c>Masters</c> are not alive.</p>
- </item>
- <item>
- <p><c>{bad_rel_file, File}</c> - Specified <c>.rel</c> file
- <c>File</c> can not be read, or does not contain a single
- term.</p>
- </item>
- <item>
- <p><c>{bad_rel_data, Data}</c> - Specified <c>.rel</c> file
- does not contain a recognized release specification, but
- another term <c>Data</c>.</p>
- </item>
- <item>
- <p><c>{bad_relup_file, File}</c> - Specified <c>relup</c> file
- <c>Relup</c> contains bad data.</p>
- </item>
- <item>
- <p><c>{cannot_extract_file, Name, Reason}</c> - Problems when
- extracting from a tar file, <c>erl_tar:extract/2</c> returned
- <c>{error, {Name, Reason}}</c>.</p>
- </item>
- <item>
- <p><c>{existing_release, Vsn}</c> - Specified release version
- <c>Vsn</c> is already in use.</p>
- </item>
- <item>
- <p><c>{Master, Reason, When}</c> - Some operation, indicated by
- the term <c>When</c>, failed on the master node <c>Master</c>
- with the specified error reason <c>Reason</c>.</p>
- </item>
- <item>
- <p><c>{no_matching_relup, Vsn, CurrentVsn}</c> - Cannot find a
- script for up/downgrading between <c>CurrentVsn</c> and
- <c>Vsn</c>.</p>
- </item>
- <item>
- <p><c>{no_such_directory, Path}</c> - The directory <c>Path</c>
- does not exist.</p>
- </item>
- <item>
- <p><c>{no_such_file, Path}</c> - The path <c>Path</c> (file or
- directory) does not exist.</p>
- </item>
- <item>
- <p><c>{no_such_file, {Master, Path}}</c> - The path <c>Path</c>
- (file or directory) does not exist at the master node
- <c>Master</c>.</p>
- </item>
- <item>
- <p><c>{no_such_release, Vsn}</c> - The specified version
- <c>Vsn</c> of the release does not exist.</p>
- </item>
- <item>
- <p><c>{not_a_directory, Path}</c> - <c>Path</c> exists, but is
- not a directory.</p>
- </item>
- <item>
- <p><c>{Posix, File}</c> - Some file operation failed for
- <c>File</c>. <c>Posix</c> is an atom named from the Posix
- error codes, such as <c>enoent</c>, <c>eacces</c> or
- <c>eisdir</c>. See <c>file(3)</c>.</p>
- </item>
- <item>
- <p><c>Posix</c> - Some file operation failed, as above.</p>
- </item>
- </list>
+ <taglist>
+ <tag><c>{bad_masters, Masters}</c></tag>
+ <item><p>The master nodes <c>Masters</c> are not alive.</p></item>
+ <tag><c>{bad_rel_file, File}</c></tag>
+ <item><p>Specified <c>.rel</c> file <c>File</c> cannot be read or
+ does not contain a single term.</p></item>
+ <tag><c>{bad_rel_data, Data}</c></tag>
+ <item><p>Specified <c>.rel</c> file does not contain a recognized
+ release specification, but another term <c>Data</c>.</p></item>
+ <tag><c>{bad_relup_file, File}</c></tag>
+ <item><p>Specified <c>relup</c> file <c>Relup</c> contains bad
+ data.</p></item>
+ <tag><c>{cannot_extract_file, Name, Reason}</c></tag>
+ <item><p>Problems when extracting from a tar file,
+ <seealso marker="stdlib:erl_tar#extract/2"><c>erl_tar:extract/2</c></seealso>
+ returned <c>{error, {Name, Reason}}</c>.</p></item>
+ <tag><c>{existing_release, Vsn}</c></tag>
+ <item><p>Specified release version <c>Vsn</c> is already
+ in use.</p></item>
+ <tag><c>{Master, Reason, When}</c></tag>
+ <item><p>Some operation, indicated by the term <c>When</c>, failed
+ on the master node <c>Master</c> with the specified error
+ reason <c>Reason</c>.</p></item>
+ <tag><c>{no_matching_relup, Vsn, CurrentVsn}</c></tag>
+ <item><p>Cannot find a script for upgrading/downgrading between
+ <c>CurrentVsn</c> and <c>Vsn</c>.</p></item>
+ <tag><c>{no_such_directory, Path}</c></tag>
+ <item><p>The directory <c>Path</c>does not exist.</p></item>
+ <tag><c>{no_such_file, Path}</c></tag>
+ <item><p>The path <c>Path</c> (file or directory) does not
+ exist.</p></item>
+ <tag><c>{no_such_file, {Master, Path}}</c></tag>
+ <item><p>The path <c>Path</c> (file or directory) does not exist at
+ the master node <c>Master</c>.</p></item>
+ <tag><c>{no_such_release, Vsn}</c></tag>
+ <item><p>The specified release version <c>Vsn</c> does not
+ exist.</p></item>
+ <tag><c>{not_a_directory, Path}</c></tag>
+ <item><p><c>Path</c> exists but is not a directory.</p></item>
+ <tag><c>{Posix, File}</c></tag>
+ <item><p>Some file operation failed for <c>File</c>. <c>Posix</c>
+ is an atom named from the Posix error codes, such as
+ <c>enoent</c>, <c>eacces</c>, or <c>eisdir</c>. See
+ <seealso marker="kernel:file"><c>file(3)</c></seealso>
+ in <c>Kernel</c>.</p></item>
+ <tag><c>Posix</c></tag>
+ <item><p>Some file operation failed, as for the previous item in
+ the list.</p></item>
+ </taglist>
</section>
<section>
- <title>SEE ALSO</title>
- <p><seealso marker="doc/design_principles:release_handling">OTP Design Principles</seealso>,
- <seealso marker="kernel:config">config(4)</seealso>,
- <seealso marker="relup">relup(4)</seealso>,
- <seealso marker="rel">rel(4)</seealso>,
- <seealso marker="script">script(4)</seealso>,
- <seealso marker="stdlib:sys">sys(3)</seealso>,
- <seealso marker="systools">systools(3)</seealso></p>
+ <title>See Also</title>
+ <p><seealso marker="doc/design_principles:users_guide">OTP Design Principles</seealso>,
+ <seealso marker="kernel:config"><c>config(4)</c></seealso>,
+ <seealso marker="rel"><c>rel(4)</c></seealso>,
+ <seealso marker="relup"><c>relup(4)</c></seealso>,
+ <seealso marker="script"><c>script(4)</c></seealso>,
+ <seealso marker="stdlib:sys"><c>sys(3)</c></seealso>,
+ <seealso marker="systools"><c>systools(3)</c></seealso></p>
</section>
</erlref>
diff --git a/lib/sasl/doc/src/relup.xml b/lib/sasl/doc/src/relup.xml
index d7c1d6fbe4..58918fc8e8 100644
--- a/lib/sasl/doc/src/relup.xml
+++ b/lib/sasl/doc/src/relup.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -35,59 +36,53 @@
<p>The <em>release upgrade file</em> describes how a release is
upgraded in a running system.</p>
<p>This file is automatically generated by
- <c>systools:make_relup/3,4</c>, using a release resource file
- (<c>.rel</c>), application resource files (<c>.app</c>) and
+ <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>,
+ using a release resource file
+ (<c>.rel</c>), application resource files (<c>.app</c>), and
application upgrade files (<c>.appup</c>) as input.</p>
</description>
<section>
- <title>FILE SYNTAX</title>
- <p>In a target system, the release upgrade file should be located in
- the <c>OTP_ROOT/erts-EVsn/Vsn</c> directory.</p>
+ <title>File Syntax</title>
+ <p>In a target system, the release upgrade file is to be located in
+ directory <c>$ROOT/releases/Vsn</c>.</p>
<p>The <c>relup</c> file contains one single Erlang term, which
defines the instructions used to upgrade the release. The file has
the following syntax:</p>
<code type="none">
{Vsn,
[{UpFromVsn, Descr, Instructions}, ...],
- [{DownToVsn, Descr, Instructions}, ...]}.
- </code>
- <list type="bulleted">
- <item>
- <p><c>Vsn = string()</c> is the current version of the release.</p>
- </item>
- <item>
- <p><c>UpFromVsn = string()</c> is an earlier version of the release
- to upgrade from.</p>
- </item>
- <item>
- <p><c>Descr = term()</c> is a user defined parameter passed
- from the <c>systools:make_relup/3,4</c> function. It will
- be used in the return value of
- <c>release_handler:install_release/1,2</c>.</p>
- </item>
- <item>
- <p><c>Instructions</c> is a list of low-level release upgrade
- instructions, see <c>appup(4)</c>.</p>
- <p>It consists of the release upgrade instructions from
+ [{DownToVsn, Descr, Instructions}, ...]}.</code>
+ <taglist>
+ <tag><c>Vsn = string()</c></tag>
+ <item><p>Current release version.</p></item>
+ <tag><c>UpFromVsn = string()</c></tag>
+ <item><p>Earlier version of the release to upgrade from.</p></item>
+ <tag><c>Descr = term()</c></tag>
+ <item><p>A user-defined parameter passed
+ from the function
+ <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>.
+ It is used in the return value of
+ <seealso marker="release_handler#install_release/1"><c>release_handler:install_release/1,2</c></seealso>.</p></item>
+ <tag><c>Instructions</c></tag>
+ <item><p>A list of low-level release upgrade instructions, see
+ <seealso marker="appup"><c>appup(4)</c></seealso>.
+ It consists of the release upgrade instructions from
the respective application upgrade files (high-level instructions
are translated to low-level instructions), in the same order
- as in the start script.</p>
- </item>
- <item>
- <p><c>DownToVsn = string()</c> is an earlier version of the release
- to downgrade to.</p>
- </item>
- </list>
- <p>When upgrading from <c>UpFromVsn</c> with
- <c>release_handler:install_release/1,2</c>, there does not have to be
- an exact match of versions, but <c>UpFromVsn</c> can be a sub-string
- of the current release version.</p>
+ as in the start script.</p></item>
+ <tag><c>DownToVsn = string()</c></tag>
+ <item><p>Earlier version of the release to downgrade to.</p></item>
+ </taglist>
</section>
<section>
- <title>SEE ALSO</title>
- <p>app(4), appup(4), rel(4), release_handler(3), systools(3)</p>
+ <title>See Also</title>
+ <p><seealso marker="kernel:app"><c>app(4)</c></seealso>,
+ <seealso marker="appup"><c>appup(4)</c></seealso>,
+ <seealso marker="rel"><c>rel(4)</c></seealso>,
+ <seealso marker="release_handler"><c>release_handler(3)</c></seealso>,
+ <seealso marker="systools"><c>systools(3)</c></seealso></p>
</section>
</fileref>
diff --git a/lib/sasl/doc/src/sasl_app.xml b/lib/sasl/doc/src/sasl_app.xml
index 9c3c80bd13..bcd446a868 100644
--- a/lib/sasl/doc/src/sasl_app.xml
+++ b/lib/sasl/doc/src/sasl_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -26,136 +27,163 @@
<docno></docno>
<date></date>
<rev></rev>
- </header>
- <app>sasl</app>
- <appsummary>The SASL Application</appsummary>
- <description>
- <p>This section describes the SASL (System Architecture Support Libraries)
- application which provides the following services:</p>
+ </header>
+ <app>sasl</app>
+ <appsummary>The SASL application</appsummary>
+ <description>
+ <p>The <c>SASL</c> application provides the following services:</p>
<list type="bulleted">
<item><c>alarm_handler</c></item>
- <item><c>overload</c></item>
+ <item><c>overload</c> (deprecated)</item>
<item><c>rb</c></item>
<item><c>release_handler</c></item>
<item><c>systools</c></item>
</list>
- <p>The SASL application also includes <c>error_logger</c> event
- handlers for formatting SASL error and crash reports.</p>
-
+ <p>The <c>SASL</c> application also includes <c>error_logger</c> event
+ handlers for formatting <c>SASL</c> error and crash reports.</p>
<note>
- <p>The SASL application in OTP has nothing to do with
+ <p>The <c>SASL</c> application in OTP has nothing to do with
"Simple Authentication and Security Layer" (RFC 4422).</p>
</note>
-
</description>
<section>
<title>Error Logger Event Handlers</title>
<p>The following error logger event handlers are used by
- the SASL application.</p>
+ the <c>SASL</c> application.</p>
<taglist>
<tag><c>sasl_report_tty_h</c></tag>
<item>
- <p>Formats and writes <em>supervisor reports</em>, <em>crash reports</em> and <em>progress reports</em> to <c>stdio</c>.</p>
+ <p>Formats and writes <em>supervisor reports</em>, <em>crash
+ reports</em>, and <em>progress reports</em> to <c>stdio</c>.
+ This error logger event handler uses
+ <seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso>
+ in the <c>Kernel</c> application to limit how much detail is
+ printed in crash and supervisor reports.</p>
</item>
<tag><c>sasl_report_file_h</c></tag>
<item>
- <p>Formats and writes <em>supervisor reports</em>, <em>crash report</em> and <em>progress report</em> to a single file.</p>
+ <p>Formats and writes <em>supervisor reports</em>, <em>crash
+ report</em>, and <em>progress report</em> to a single file.
+ This error logger event handler uses
+ <seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso>
+ in the <c>Kernel</c> application to limit the details
+ printed in crash and supervisor reports.</p>
</item>
<tag><c>log_mf_h</c></tag>
<item>
- <p>This error logger writes <em>all</em> events sent to
- the error logger to disk.</p>
- <p>To activate this event handler, the following three sasl
- configuration parameters must be set:
- <c>error_logger_mf_dir</c>, <c>error_logger_mf_maxbytes</c>
- and <c>error_logger_mf_maxfiles</c>. See below for more
- information about the configuration parameters.</p>
+ <p>This error logger writes <em>all</em> events sent to the
+ error logger to disk. Multiple files and log rotation are
+ used. For efficiency reasons, each event is written as a
+ binary. For more information about this handler,
+ see <seealso marker="stdlib:log_mf_h">the <c>STDLIB</c> Reference
+ Manual</seealso>.</p>
+ <p>To activate this event handler, three <c>SASL</c>
+ configuration parameters must be set,
+ <c>error_logger_mf_dir</c>, <c>error_logger_mf_maxbytes</c>,
+ and <c>error_logger_mf_maxfiles</c>. The next section provides
+ more information about the configuration parameters.</p>
</item>
</taglist>
</section>
<section>
<title>Configuration</title>
- <p>The following configuration parameters are defined for the SASL
- application. See <c>app(4)</c> for more information about
- configuration parameters:</p>
+ <p>The following configuration parameters are defined for the <c>SASL</c>
+ application. For more information about configuration parameters, see
+ <seealso marker="kernel:app"><c>app(4)</c></seealso> in <c>Kernel</c>.</p>
+ <p>All configuration parameters are optional.</p>
<taglist>
- <tag><c><![CDATA[sasl_error_logger = Value <optional>]]></c></tag>
+ <tag><c><![CDATA[sasl_error_logger = Value ]]></c></tag>
<item>
- <p><c>Value</c> is one of:</p>
+ <p><c>Value</c> is one of the following:</p>
<taglist>
<tag><c>tty</c></tag>
- <item>Installs <c>sasl_report_tty_h</c> in the error logger.
- This is the default option.</item>
+ <item><p>Installs <c>sasl_report_tty_h</c> in the error logger.
+ This is the default option.</p></item>
<tag><c>{file,FileName}</c></tag>
- <item>Installs <c>sasl_report_file_h</c> in the error logger.
- This makes all reports go to the file <c>FileName</c>.
- <c>FileName</c> is a string.</item>
+ <item><p>Installs <c>sasl_report_file_h</c> in the error logger.
+ All reports go to file <c>FileName</c>, which is a
+ string.</p></item>
+ <tag><c>{file,FileName,Modes}</c></tag>
+ <item><p>Same as <c>{file,FileName}</c>, except that <c>Modes</c>
+ allows you to specify the modes used for opening the <c>FileName</c>
+ given to the <seealso marker="kernel:file#open/2">file:open/2</seealso>
+ call. When not specified, <c>Modes</c> defaults to <c>[write]</c>.
+ Use <c>[append]</c> to have the <c>FileName</c> open in append mode.
+ <c>FileName</c> is a string.</p></item>
<tag><c>false</c></tag>
- <item>
- <p>No SASL error logger handler is installed.</p>
- </item>
+ <item><p>No <c>SASL</c> error logger handler is installed.</p></item>
</taglist>
</item>
- <tag><c><![CDATA[errlog_type = error | progress | all <optional>]]></c></tag>
+ <tag><c><![CDATA[errlog_type = error | progress | all ]]></c></tag>
<item>
<p>Restricts the error logging performed by the specified
- <c>sasl_error_logger</c> to error reports, progress reports,
+ <c>sasl_error_logger</c> to error reports or progress reports,
or both. Default is <c>all</c>.</p>
</item>
- <tag><c><![CDATA[error_logger_mf_dir = string() | false<optional>]]></c></tag>
+ <tag><c><![CDATA[error_logger_mf_dir = string() | false ]]></c></tag>
<item>
- <p>Specifies in which directory the files are stored. If this
- parameter is undefined or <c>false</c>,
+ <p>Specifies in which directory <c>log_mf_h</c> is to store
+ its files. If this parameter is undefined or <c>false</c>,
the <c>log_mf_h</c> handler is not installed.</p>
</item>
- <tag><c><![CDATA[error_logger_mf_maxbytes = integer() <optional>]]></c></tag>
+ <tag><c><![CDATA[error_logger_mf_maxbytes = integer() ]]></c></tag>
<item>
- <p>Specifies how large each individual file can be. If this
- parameter is undefined, the <c>log_mf_h</c> handler is not
- installed.</p>
+ <p>Specifies the maximum size of each individual file written
+ by <c>log_mf_h</c>. If this parameter is undefined,
+ the <c>log_mf_h</c> handler is not installed.</p>
</item>
- <tag><c><![CDATA[error_logger_mf_maxfiles = 0<integer()<256 <optional>]]></c></tag>
+ <tag><c><![CDATA[error_logger_mf_maxfiles = 0<integer()<256 ]]></c></tag>
<item>
- <p>Specifies how many files are used. If this parameter is
- undefined, the <c>log_mf_h</c> handler is not installed.</p>
+ <p>Specifies the number of files used by <c>log_mf_h</c>. If
+ this parameter is undefined, the <c>log_mf_h</c> handler is
+ not installed.</p>
</item>
- <tag><c><![CDATA[overload_max_intensity = float() > 0 <optional>]]></c></tag>
+ <tag><c><![CDATA[overload_max_intensity = float() > 0 ]]></c></tag>
<item>
- <p>Specifies the maximum intensity for <c>overload</c>. Default
+ <p>Specifies the maximum intensity
+ for <seealso marker="overload"><c>overload</c></seealso>. Default
is <c>0.8</c>.</p>
+ <p>Note that the <c>overload</c> module is deprected and
+ will be removed in a future release.</p>
</item>
- <tag><c><![CDATA[overload_weight = float() > 0 <optional>]]></c></tag>
+ <tag><c><![CDATA[overload_weight = float() > 0 ]]></c></tag>
<item>
- <p>Specifies the <c>overload</c> weight. Default is <c>0.1</c>.</p>
+ <p>Specifies the <seealso marker="overload"><c>overload</c></seealso>
+ weight. Default is <c>0.1</c>.</p>
+ <p>Note that the <c>overload</c> module is deprected and
+ will be removed in a future release.</p>
</item>
- <tag><c><![CDATA[start_prg = string() <optional>]]></c></tag>
+ <tag><c><![CDATA[start_prg = string() ]]></c></tag>
<item>
- <p>Specifies which program should be used when restarting
- the system. Default is <c>$OTP_ROOT/bin/start</c>.</p>
+ <p>Specifies the program to be used when restarting the system
+ during release installation. Default is
+ <c>$OTP_ROOT/bin/start</c>.</p>
</item>
- <tag><c><![CDATA[masters = [atom()] <optional>]]></c></tag>
+ <tag><c><![CDATA[masters = [atom()] ]]></c></tag>
<item>
- <p>Specifies which nodes this node uses to read/write release
- information. This parameter is ignored if
- the <c>client_directory</c> parameter is not set.</p>
+ <p>Specifies the nodes used by this node to read/write release
+ information. This parameter is ignored if parameter
+ <c>client_directory</c> is not set.</p>
</item>
- <tag><c><![CDATA[client_directory = string() <optional>]]></c></tag>
+ <tag><c><![CDATA[client_directory = string() ]]></c></tag>
<item>
<p>This parameter specifies the client directory at the master
- nodes. Refer to Release Handling in <em>OTP Design Principles</em> for more information. This parameter is
- ignored if the <c>masters</c> parameter is not set.</p>
+ nodes. For details, see
+ <seealso marker="doc/design_principles:release_handling">Release Handling</seealso>
+ in <em>OTP Design Principles</em>. This parameter is
+ ignored if parameter <c>masters</c> is not set.</p>
</item>
- <tag><c><![CDATA[static_emulator = true | false <optional>]]></c></tag>
+ <tag><c><![CDATA[static_emulator = true | false ]]></c></tag>
<item>
<p>Indicates if the Erlang emulator is statically installed. A
node with a static emulator cannot switch dynamically to a
- new emulator as the executable files are written into memory
- statically. This parameter is ignored if the <c>masters</c>
- and <c>client_directory</c> parameters are not set.</p>
+ new emulator, as the executable files are written into memory
+ statically. This parameter is ignored if parameters <c>masters</c>
+ and <c>client_directory</c> are not set.</p>
</item>
- <tag><c><![CDATA[releases_dir = string() <optional>]]></c></tag>
+ <tag><c><![CDATA[releases_dir = string() ]]></c></tag>
<item>
<p>Indicates where the <c>releases</c> directory is located.
The release handler writes all its files to this directory.
@@ -163,7 +191,7 @@
<c>RELDIR</c> is used. By default, this is
<c>$OTP_ROOT/releases</c>.</p>
</item>
- <tag><c><![CDATA[utc_log = true | false <optional>]]></c></tag>
+ <tag><c><![CDATA[utc_log = true | false ]]></c></tag>
<item>
<p>If set to <c>true</c>, all dates in textual log outputs are
displayed in Universal Coordinated Time with the string
@@ -174,13 +202,13 @@
<section>
<title>See Also</title>
- <p><seealso marker="alarm_handler">alarm_handler(3)</seealso>,
- error_logger(3),
- log_mf_h(3),
- <seealso marker="overload">overload(3)</seealso>,
- <seealso marker="rb">rb(3)</seealso>,
- <seealso marker="release_handler">release_handler(3)</seealso>,
- <seealso marker="systools">systools(3)</seealso></p>
+ <p><seealso marker="alarm_handler"><c>alarm_handler(3)</c></seealso>,
+ <seealso marker="kernel:error_logger"><c>error_logger(3)</c></seealso>,
+ <seealso marker="stdlib:log_mf_h"><c>log_mf_h(3)</c></seealso>,
+ <seealso marker="overload"><c>overload(3)</c></seealso>,
+ <seealso marker="rb"><c>rb(3)</c></seealso>,
+ <seealso marker="release_handler"><c>release_handler(3)</c></seealso>,
+ <seealso marker="systools"><c>systools(3)</c></seealso></p>
</section>
</appref>
diff --git a/lib/sasl/doc/src/sasl_intro.xml b/lib/sasl/doc/src/sasl_intro.xml
index f3d4632218..bbc9457103 100644
--- a/lib/sasl/doc/src/sasl_intro.xml
+++ b/lib/sasl/doc/src/sasl_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,22 +31,32 @@
</header>
<section>
- <title>About This Document</title>
- <p>The SASL (System Architecture Support Libraries)
- application provides support for:</p>
+ <title>Scope</title>
+ <p>The <c>SASL</c> application provides support for:</p>
<list type="bulleted">
- <item>error logging</item>
- <item>alarm handling</item>
- <item>overload regulation</item>
- <item>release handling</item>
- <item>report browsing.</item>
+ <item>Error logging</item>
+ <item>Alarm handling</item>
+ <item>Overload regulation</item>
+ <item>Release handling</item>
+ <item>Report browsing</item>
</list>
- <p>In this document, "SASL Error Logging" describes the error
- handler which produces the supervisor, progress, and crash
- reports which can be written to screen, or to a specified file.
- It also describes the report browser <c>rb</c>.</p>
- <p>The chapters about release structure and release handling have
- been moved to <em>OTP Design Principles</em>.</p>
+ <p>Section
+ <seealso marker="error_logging">SASL Error Logging</seealso>
+ describes the error
+ handler that produces the supervisor, progress, and crash
+ reports, which can be written to screen or to a specified file.
+ It also describes the Report Browser (RB).</p>
+ <p>The sections about release structure and release handling have
+ been moved to section
+ <seealso marker="doc/design_principles:users_guide">OTP Design Principles</seealso>
+ in <em>System Documentation</em>.</p>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language.</p>
</section>
+
</chapter>
diff --git a/lib/sasl/doc/src/script.xml b/lib/sasl/doc/src/script.xml
index 3a85e64e7a..db3ea0f487 100644
--- a/lib/sasl/doc/src/script.xml
+++ b/lib/sasl/doc/src/script.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -36,25 +37,21 @@
<file>script</file>
<filesummary>Boot script</filesummary>
<description>
- <p>The <em>boot script</em> describes how the Erlang runtime system is
- started. It contains instructions on which code to load and
- which processes and applications to start.
- </p>
- <p>The command <c>erl -boot Name</c> starts the system with a boot
+ <p>The <em>boot script</em> describes how the Erlang runtime system
+ is started. It contains instructions on which code to load and
+ which processes and applications to start.</p>
+ <p>Command <c>erl -boot Name</c> starts the system with a boot
file called <c>Name.boot</c>, which is generated from the
- <c>Name.script</c> file, using <c>systools:script2boot/1</c>.
- </p>
+ <c>Name.script</c> file, using
+ <seealso marker="systools#script2boot/1"><c>systools:script2boot/1</c></seealso>.</p>
<p>The <c>.script</c> file is generated by <c>systools</c> from a
- <c>.rel</c> file and <c>.app</c> files.
- </p>
+ <c>.rel</c> file and from <c>.app</c> files.</p>
</description>
<section>
- <title>FILE SYNTAX</title>
- <p>The boot script is stored in a file with the extension
- <c>.script</c></p>
- <p>The file has the following syntax:
- </p>
+ <title>File Syntax</title>
+ <p>The boot script is stored in a file with extension
+ <c>.script</c>. The file has the following syntax:</p>
<code type="none">
{script, {Name, Vsn},
[
@@ -69,100 +66,97 @@
...
{apply, {Mod, Func, Args}},
...
- {progress, started}]}. </code>
- <list type="bulleted">
- <item><c>Name = string()</c> defines the name of the system.
- </item>
- <item><c>Vsn = string()</c> defines the version of the system.
- </item>
- <item><c>{progress, Term}</c> sets the "progress" of the
- initialization program. The function <c>init:get_status()</c>
- returns the current value of the progress, which is
- <c>{InternalStatus,Term}</c>.
- </item>
- <item>
- <p><c>{path, [Dir]}</c> where <c>Dir</c> is a string. This
+ {progress, started}]}.</code>
+ <taglist>
+ <tag><c>Name = string()</c></tag>
+ <item><p>Defines the system name.</p></item>
+ <tag><c>Vsn = string()</c></tag>
+ <item><p>Defines the system version.</p></item>
+ <tag><c>{progress, Term}</c></tag>
+ <item><p>Sets the "progress" of the initialization
+ program. The
+ <seealso marker="erts:init#get_status/0"><c>init:get_status/0</c></seealso>
+ function returns the current value of the progress, which is
+ <c>{InternalStatus,Term}</c>.</p></item>
+ <tag><c>{path, [Dir]}</c></tag>
+ <item><p><c>Dir</c> is a string. This
argument sets the load path of the system to <c>[Dir]</c>. The
load path used to load modules is obtained from the initial
load path, which is given in the script file, together with
- any path flags which were supplied in the command line
- arguments. The command line arguments modify the path as
+ any path flags that were supplied in the command-line
+ arguments. The command-line arguments modify the path as
follows:</p>
<list type="bulleted">
<item><c>-pa Dir1 Dir2 ... DirN</c> adds the directories
<c>Dir1, Dir2, ..., DirN</c> to the front of the initial
- load path.
- </item>
+ load path.</item>
<item><c>-pz Dir1 Dir2 ... DirN</c> adds the directories
<c>Dir1, Dir2, ..., DirN</c> to the end of the initial
- load path.
- </item>
+ load path.</item>
<item>
<p><c>-path Dir1 Dir2 ... DirN</c> defines a set of
- directories <c>Dir1, Dir2, ..., DirN</c> which replaces
+ directories <c>Dir1, Dir2, ..., DirN</c>, which replace
the search path given in the script file. Directory names
in the path are interpreted as follows:</p>
<list type="bulleted">
<item>Directory names starting with <c>/</c> are assumed
- to be absolute path names.
- </item>
+ to be absolute path names.</item>
<item>Directory names not starting with <c>/</c> are
- assumed to be relative the current working directory.
- </item>
+ assumed to be relative the current working directory.</item>
<item>The special <c>$ROOT</c> variable can only be used
- in the script, not as a command line argument. The
+ in the script, not as a command-line argument. The
given directory is relative the Erlang installation
- directory.
- </item>
+ directory.</item>
</list>
</item>
</list>
- </item>
- <item><c>{primLoad, [Mod]}</c> loads the modules <c>[Mod]</c>
- from the directories specified in <c>Path</c>. The script
- interpreter fetches the appropriate module by calling the
- function <c>erl_prim_loader:get_file(Mod)</c>. A fatal error
- which terminates the system will occur if the module cannot be
- located.
- </item>
- <item><c>{kernel_load_completed}</c> indicates that all modules
- which <em>must</em> be loaded <em>before</em> any processes
- are started are loaded. In interactive mode, all
- <c>{primLoad,[Mod]}</c> commands interpreted after this
- command are ignored, and these modules are loaded on demand.
- In embedded mode, <c>kernel_load_completed</c> is ignored, and
- all modules are loaded during system start.
- </item>
- <item><c>{kernelProcess, Name, {Mod, Func, Args}}</c> starts a
- "kernel process". The kernel process <c>Name</c> is started
- by evaluating <c>apply(Mod, Func, Args)</c> which is expected
- to return <c>{ok, Pid}</c> or <c>ignore</c>. The <c>init</c>
- process monitors the behaviour of <c>Pid</c> and terminates
- the system if <c>Pid</c> dies. Kernel processes are key
- components of the runtime system. Users do not normally add
- new kernel processes.
- </item>
- <item><c>{apply, {Mod, Func, Args}}</c>. The init process simply
- evaluates <c>apply(Mod, Func, Args)</c>. The system
- terminates if this results in an error. The boot procedure
- hangs if this function never returns.
- </item>
- </list>
+ </item>
+ <tag><c>{primLoad, [Mod]}</c></tag>
+ <item><p>Loads the modules <c>[Mod]</c>
+ from the directories specified in <c>Path</c>. The script
+ interpreter fetches the appropriate module by calling
+ <seealso marker="erts:erl_prim_loader#get_file/1">
+ <c>erl_prim_loader:get_file(Mod)</c></seealso>. A fatal error
+ that terminates the system occurs if the module cannot be
+ located.</p></item>
+ <tag><c>{kernel_load_completed}</c></tag>
+ <item><p>Indicates that all modules
+ that <em>must</em> be loaded <em>before</em> any processes
+ are started are loaded. In interactive mode, all
+ <c>{primLoad,[Mod]}</c> commands interpreted after this
+ command are ignored, and these modules are loaded on demand.
+ In embedded mode, <c>kernel_load_completed</c> is ignored, and
+ all modules are loaded during system start.</p></item>
+ <tag><c>{kernelProcess, Name, {Mod, Func, Args}}</c></tag>
+ <item><p>Starts the
+ "kernel process" <c>Name</c>
+ by evaluating <c>apply(Mod, Func, Args)</c>. The start function is
+ to return <c>{ok, Pid}</c> or <c>ignore</c>. The <c>init</c>
+ process monitors the behavior of <c>Pid</c> and terminates
+ the system if <c>Pid</c> dies. Kernel processes are key
+ components of the runtime system. Users do not normally add
+ new kernel processes.</p></item>
+ <tag><c>{apply, {Mod, Func, Args}}</c>.</tag>
+ <item><p>The init process
+ evaluates <c>apply(Mod, Func, Args)</c>. The system
+ terminates if this results in an error. The boot procedure
+ hangs if this function never returns.</p></item>
+ </taglist>
<note>
- <p>In the <c>interactive</c> system the code loader provides
- demand driven code loading, but in the <c>embedded</c> system
- the code loader loads all the code immediately. The same
- version of <c>code</c> is used in both cases. The code server
- calls <c>init:get_argument(mode)</c> to find out if it should
- run in demand mode, or non-demand driven mode.
- </p>
+ <p>In an interactive system, the code loader provides
+ demand-driven code loading, but in an embedded system
+ the code loader loads all code immediately. The same
+ version of <seealso marker="kernel:code"><c>code</c></seealso>
+ is used in both cases. The code server calls
+ <seealso marker="erts:init#get_argument/1"><c>init:get_argument(mode)</c></seealso>
+ to determine if it is to run in demand mode or non-demand
+ driven mode.</p>
</note>
</section>
<section>
- <title>SEE ALSO</title>
- <p>systools(3)
- </p>
+ <title>See Also</title>
+ <p><seealso marker="systools"><c>systools(3)</c></seealso></p>
</section>
</fileref>
diff --git a/lib/sasl/doc/src/systools.xml b/lib/sasl/doc/src/systools.xml
index e8076c6752..1a5119a5cf 100644
--- a/lib/sasl/doc/src/systools.xml
+++ b/lib/sasl/doc/src/systools.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -30,17 +31,18 @@
<rev></rev>
</header>
<module>systools</module>
- <modulesummary>A Set of Release Handling Tools.</modulesummary>
+ <modulesummary>A Set of Release Handling Tools</modulesummary>
<description>
<p>This module contains functions to generate boot scripts
- (<c>.boot</c>, <c>.script</c>), release upgrade scripts
+ (<c>.boot</c>, <c>.script</c>), a release upgrade file
(<c>relup</c>), and release packages.</p>
</description>
+
<funcs>
<func>
<name>make_relup(Name, UpFrom, DownTo) -> Result</name>
<name>make_relup(Name, UpFrom, DownTo, [Opt]) -> Result</name>
- <fsummary>Generate a release upgrade file <c>relup</c>.</fsummary>
+ <fsummary>Generates a release upgrade file <c>relup</c>.</fsummary>
<type>
<v>Name = string()</v>
<v>UpFrom = DownTo = [Name | {Name,Descr}]</v>
@@ -49,93 +51,94 @@
| warnings_as_errors</v>
<v>&nbsp;Dir = string()</v>
<v>Result = ok | error | {ok,Relup,Module,Warnings} | {error,Module,Error}</v>
- <v>&nbsp;Relup - see relup(4)</v>
+ <v>&nbsp;Relup, see relup(4)</v>
<v>&nbsp;Module = atom()</v>
<v>&nbsp;Warnings = Error = term()</v>
</type>
<desc>
- <p>Generates a release upgrade file <c>relup</c> containing a
- script which describes how to upgrade the system from a number
- of previous releases, and how to downgrade to a number of
- previous releases. The script is used by
- <c>release_handler</c> when installing a new version of a
- release in run-time.</p>
- <p>By default, <c>relup</c> is placed in the current working
- directory. If the option <c>{outdir,Dir}</c> is provided,
- <c>relup</c> is placed in <c>Dir</c> instead.</p>
+ <p>Generates a release upgrade file <c>relup</c> containing instructions
+ for upgrading from or downgrading to one or more previous releases.
+ The instructions are used by
+ <seealso marker="release_handler"><c>release_handler</c></seealso>
+ when installing a new version of a release in runtime.</p>
+ <p>By default, <c>relup</c> file is located in the current working
+ directory. If option <c>{outdir,Dir}</c> is specified,
+ the <c>relup</c> file is located in <c>Dir</c> instead.</p>
<p>The release resource file <c>Name.rel</c> is compared with
- all release resource files <c>Name2.rel</c> specified in
- <c>UpFrom</c> and <c>DownTo</c>. For each such pair, it is
- deducted:</p>
+ all release resource files <c>Name2.rel</c>, specified in
+ <c>UpFrom</c> and <c>DownTo</c>. For each such pair, the
+ following is deducted:</p>
<list type="bulleted">
<item>
- <p>Which applications should be deleted, that is
- applications which are listed in <c>Name.rel</c> but not
- in <c>Name2.rel</c>.</p>
+ <p>Which applications to be deleted, that is,
+ applications listed in <c>Name.rel</c> but not
+ in <c>Name2.rel</c></p>
</item>
<item>
- <p>Which applications should be added, that is applications
- which are listed in <c>Name2.rel</c> but not in
- <c>Name.rel</c>.</p>
+ <p>Which applications to be added, that is, applications
+ listed in <c>Name2.rel</c> but not in <c>Name.rel</c></p>
</item>
<item>
- <p>Which applications should be upgraded/downgraded, that
- is applications listed in both <c>Name.rel</c> and
- <c>Name2.rel</c>, but with different versions.</p>
+ <p>Which applications to be upgraded/downgraded, that
+ is, applications listed in both <c>Name.rel</c> and
+ <c>Name2.rel</c> but with different versions</p>
</item>
<item>
<p>If the emulator needs to be restarted after upgrading or
- downgrading, that is if the ERTS version differs between
- <c>Name.rel</c> and <c>Name2.rel</c>.</p>
+ downgrading, that is, if the <c>ERTS</c> version differs
+ between <c>Name.rel</c> and <c>Name2.rel</c></p>
</item>
</list>
- <p>Instructions for this are added to the <c>relup</c> script in
+ <p>Instructions for this are added to the <c>relup</c> file in
the above order. Instructions for upgrading or downgrading
between application versions are fetched from the relevant
application upgrade files <c>App.appup</c>, sorted in
the same order as when generating a boot script, see
- <c>make_script/1,2</c>. High-level instructions are translated
- into low-level instructions and the result is printed to
- <c>relup</c>.</p>
- <p>The optional <c>Descr</c> parameter is included as-is in
- the <c>relup</c> script, see <c>relup(4)</c>. Defaults to
+ <seealso marker="#make_script/1"><c>make_script/1,2</c></seealso>.
+ High-level instructions are translated
+ into low-level instructions and the result is printed to the
+ <c>relup</c> file.</p>
+ <p>The optional <c>Descr</c> parameter is included "as is" in
+ the <c>relup</c> file, see
+ <seealso marker="relup"><c>relup(4)</c></seealso>. Defaults to
the empty list.</p>
<p>All the files are searched for in the code path. It is
- assumed that the <c>.app</c> and <c>.appup</c> file for an
- application is located in the same directory.</p>
- <p>If the option <c>{path,[Dir]}</c> is provided, this path is
- appended to the current path. The wildcard <c>*</c> is
- expanded to all matching directories.
- Example: <c>lib/*/ebin</c>.</p>
- <p>If the <c>restart_emulator</c> option is supplied, a
+ assumed that the <c>.app</c> and <c>.appup</c> files for an
+ application are located in the same directory.</p>
+ <p>If option <c>{path,[Dir]}</c> is specified, this path is
+ appended to the current path. Wildcard <c>*</c> is
+ expanded to all matching directories, for example,
+ <c>lib/*/ebin</c>.</p>
+ <p>If option <c>restart_emulator</c> is specified, a
low-level instruction to restart the emulator is appended to
- the relup scripts. This ensures that a complete reboot of
+ the <c>relup</c> file. This ensures that a complete reboot of
the system is done when the system is upgraded or downgraded.</p>
- <p>If an upgrade includes a change from an emulator earlier
- than OTP R15 to OTP R15 or later, the warning
- <c>pre_R15_emulator_upgrade</c> is issued. See <seealso
- marker="doc/design_principles:appup_cookbook">Design
- Principles</seealso> for more information about this.</p>
+ <p>If an upgrade includes a change from an emulator earlier
+ than OTP R15 to OTP R15 or later, the warning
+ <c>pre_R15_emulator_upgrade</c> is issued. For more information
+ about this, see
+ <seealso marker="doc/design_principles:appup_cookbook">Design
+ Principles</seealso> in <em>System Documentation</em>.</p>
<p>By default, errors and warnings are printed to tty and
- the function returns <c>ok</c> or <c>error</c>. If the option
- <c>silent</c> is provided, the function instead returns
- <c>{ok,Relup,Module,Warnings}</c> where <c>Relup</c> is
- the release upgrade script, or it returns
- <c>{error,Module,Error}</c>. Warnings and errors can be
- converted to strings by calling
+ the function returns <c>ok</c> or <c>error</c>. If option
+ <c>silent</c> is specified, the function instead either returns
+ <c>{ok,Relup,Module,Warnings}</c>, where <c>Relup</c> is
+ the release upgrade file, or <c>{error,Module,Error}</c>.
+ Warnings and errors can be converted to strings by calling
<c>Module:format_warning(Warnings)</c> or
<c>Module:format_error(Error)</c>.</p>
- <p>If the option <c>noexec</c> is provided, the function returns
+ <p>If option <c>noexec</c> is specified, the function returns
the same values as for <c>silent</c> but no <c>relup</c> file
is created.</p>
- <p>If the option <c>warnings_as_errors</c> is provided, warnings
- are treated as errors.</p>
+ <p>If option <c>warnings_as_errors</c> is specified, warnings
+ are treated as errors.</p>
</desc>
</func>
+
<func>
<name>make_script(Name) -> Result</name>
<name>make_script(Name, [Opt]) -> Result</name>
- <fsummary>Generate a boot script <c>.script/.boot</c>.</fsummary>
+ <fsummary>Generates a boot script <c>.script/.boot</c>.</fsummary>
<type>
<v>Name = string()</v>
<v>Opt = src_tests | {path,[Dir]} | local | {variables,[Var]} | exref |
@@ -152,114 +155,117 @@
<desc>
<p>Generates a boot script <c>Name.script</c> and its binary
version, the boot file <c>Name.boot</c>. The boot file
- specifies which code should be loaded and which applications
- should be started when the Erlang runtime system is started.
- See <c>script(4)</c>.</p>
- <p>The release resource file <c>Name.rel</c> is read to find
- out which applications are included in the release. Then
- the relevant application resource files <c>App.app</c> are
- read to find out which modules should be loaded and if and
- how the application should be started. (Keys <c>modules</c>
- and <c>mod</c>, see <c>app(4)</c>).</p>
- <p>By default, the boot script and boot file are placed in
+ specifies which code to be loaded and which applications
+ to be started when the Erlang runtime system is started.
+ See <seealso marker="script"><c>script(4)</c></seealso>.</p>
+ <p>The release resource file <c>Name.rel</c> is read to determine
+ which applications are included in the release. Then
+ the relevant application resource files <c>App.app</c> are read
+ to determine which modules to be loaded, and if and
+ how the applications are to be started. (Keys <c>modules</c>
+ and <c>mod</c>, see
+ <seealso marker="kernel:app"><c>app(4)</c></seealso>.</p>
+ <p>By default, the boot script and boot file are located in
the same directory as <c>Name.rel</c>. That is, in the current
working directory unless <c>Name</c> contains a path. If
- the option <c>{outdir,Dir}</c> is provided, they are placed
+ option <c>{outdir,Dir}</c> is specified, they are located
in <c>Dir</c> instead.</p>
- <p>The correctness of each application is checked:</p>
+ <p>The correctness of each application is checked as follows:</p>
<list type="bulleted">
<item>
<p>The version of an application specified in
- the <c>.rel</c> file should be the same as the version
+ the <c>.rel</c> file is to be the same as the version
specified in the <c>.app</c> file.</p>
</item>
<item>
- <p>There should be no undefined applications, that is,
- dependencies to applications which are not included in
- the release. (Key <c>applications</c> in <c>.app</c>
+ <p>There are to be no undefined applications, that is,
+ dependencies to applications that are not included in
+ the release. (Key <c>applications</c> in the <c>.app</c>
file).</p>
</item>
<item>
- <p>There should be no circular dependencies among
+ <p>There are to be no circular dependencies among
the applications.</p>
</item>
<item>
- <p>There should be no duplicated modules, that is, modules with
+ <p>There are to be no duplicated modules, that is, modules with
the same name but belonging to different applications.</p>
</item>
<item>
- <p>If the <c>src_tests</c> option is specified, a
+ <p>If option <c>src_tests</c> is specified, a
warning is issued if the source code for a module is
- missing or newer than the object code.</p>
+ missing or is newer than the object code.</p>
</item>
</list>
<p>The applications are sorted according to the dependencies
between the applications. Where there are no dependencies,
the order in the <c>.rel</c> file is kept.</p>
- <p>The function will fail if the mandatory
- applications <c>kernel</c> and <c>stdlib</c> are not
- included in the <c>.rel</c> file and have start
- type <c>permanent</c> (default).</p>
- <p>If <c>sasl</c> is not included as an application in
- the <c>.rel</c> file, a warning is emitted because such a
- release can not be used in an upgrade. To turn off this
- warning, add the option <c>no_warn_sasl</c>.</p>
+ <p>The function fails if the mandatory
+ applications <c>Kernel</c> and <c>STDLIB</c> are not
+ included in the <c>.rel</c> file and have start
+ type <c>permanent</c> (which is default).</p>
+ <p>If <c>SASL</c> is not included as an application in
+ the <c>.rel</c> file, a warning is issued because such a
+ release cannot be used in an upgrade. To turn off this
+ warning, add option <c>no_warn_sasl</c>.</p>
<p>All files are searched for in the current path. It is
assumed that the <c>.app</c> and <c>.beam</c> files for an
- application is located in the same directory. The <c>.erl</c>
+ application are located in the same directory. The <c>.erl</c>
files are also assumed to be located in this directory, unless
- it is an <c>ebin</c> directory in which case they may be
+ it is an <c>ebin</c> directory in which case they can be
located in the corresponding <c>src</c> directory.</p>
- <p>If the option <c>{path,[Dir]}</c> is provided, this path is
+ <p>If option <c>{path,[Dir]}</c> is specified, this path is
appended to the current path. A directory in the path can be
- given with a wildcard <c>*</c>, this is expanded to all
+ specified with a wildcard <c>*</c>, this is expanded to all
matching directories. Example: <c>"lib/*/ebin"</c>.</p>
<p>In the generated boot script all application directories are
- structured as <c>App-Vsn/ebin</c> and assumed to be located
+ structured as <c>App-Vsn/ebin</c>. They are assumed to be located
in <c>$ROOT/lib</c>, where <c>$ROOT</c> is the root directory
- of the installed release. If the <c>local</c> option is
- supplied, the actual directories where the applications were
+ of the installed release. If option <c>local</c> is
+ specified, the actual directories where the applications were
found are used instead. This is a useful way to test a
generated boot script locally.</p>
- <p>The <c>variables</c> option can be used to specify an
+ <p>Option <c>variables</c> can be used to specify an
installation directory other than <c>$ROOT/lib</c> for some of
the applications. If a variable <c>{VarName,Prefix}</c> is
specified and an application is found in a directory
- <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application will get
+ <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application gets
the path <c>VarName/Rest/App-Vsn/ebin</c> in the boot script.
If an application is found in a directory <c>Prefix/Rest</c>,
- the path will be <c>VarName/Rest/App-Vsn/ebin</c>. When
+ the path is <c>VarName/Rest/App-Vsn/ebin</c>. When
starting Erlang, all variables <c>VarName</c> are given
- values using the <c>boot_var</c> command line flag.</p>
- <p>Example: If the option <c>{variables,[{"TEST","lib"}]}</c> is
- supplied, and <c>myapp.app</c> is found in
- <c>lib/myapp/ebin</c>, then the path to this application in
- the boot script will be <c>"$TEST/myapp-1/ebin"</c>. If
- <c>myapp.app</c> is found in <c>lib/test</c>, then the path
- will be <c>$TEST/test/myapp-1/ebin</c>.</p>
+ values using command-line flag <c>boot_var</c>.</p>
+ <p><em>Example:</em> If option <c>{variables,[{"TEST","lib"}]}</c>
+ is specified and <c>myapp.app</c> is found in
+ <c>lib/myapp/ebin</c>, the path to this application in
+ the boot script is <c>"$TEST/myapp-1/ebin"</c>. If
+ <c>myapp.app</c> is found in <c>lib/test</c>, the path
+ is <c>$TEST/test/myapp-1/ebin</c>.</p>
<p>The checks performed before the boot script is generated can
be extended with some cross reference checks by specifying
- the <c>exref</c> option. These checks are performed with
+ option <c>exref</c>. These checks are performed with
the Xref tool. All applications, or the applications specified
with <c>{exref,[App]}</c>, are checked by Xref and
- warnings are generated for calls to undefined functions.</p>
+ warnings are issued for calls to undefined functions.</p>
<p>By default, errors and warnings are printed to tty and
- the function returns <c>ok</c> or <c>error</c>. If the option
- <c>silent</c> is provided, the function instead returns
+ the function returns <c>ok</c> or <c>error</c>. If option
+ <c>silent</c> is specified, the function instead returns
<c>{ok,Module,Warnings}</c> or <c>{error,Module,Error}</c>.
Warnings and errors can be converted to strings by calling
<c>Module:format_warning(Warnings)</c> or
<c>Module:format_error(Error)</c>.</p>
- <p>If the option <c>warnings_as_errors</c> is provided, warnings
- are treated as errors.</p>
- <p>If the option <c>no_dot_erlang</c> is provided, the instruction to
- load the <c>.erlang</c> file during boot is <em>NOT</em> included.</p>
+ <p>If option <c>warnings_as_errors</c> is specified, warnings
+ are treated as errors.</p>
+ <p>If option <c>no_dot_erlang</c> is specified, the instruction to
+ load the <c>.erlang</c> file during boot is <em>not</em>
+ included.</p>
</desc>
</func>
+
<func>
<name>make_tar(Name) -> Result</name>
<name>make_tar(Name, [Opt]) -> Result</name>
- <fsummary>Create a release package.</fsummary>
+ <fsummary>Creates a release package.</fsummary>
<type>
<v>Name = string()</v>
<v>Opt = {dirs,[IncDir]} | {path,[Dir]} | {variables,[Var]} | {var_tar,VarTar} | {erts,Dir} | src_tests | exref | {exref,[App]} | silent | {outdir,Dir}</v>
@@ -275,90 +281,91 @@
<v>&nbsp;Warning = Error = term()</v>
</type>
<desc>
- <p>Creates a release package file <c>Name.tar.gz</c>. file.
+ <p>Creates a release package file <c>Name.tar.gz</c>.
This file must be uncompressed and unpacked on the target
- system using the <c>release_handler</c>, before the new
- release can be installed.</p>
- <p>The release resource file <c>Name.rel</c> is read to find out
+ system using
+ <seealso marker="release_handler"><c>release_handler</c></seealso>
+ before the new release can be installed.</p>
+ <p>The release resource file <c>Name.rel</c> is read to determine
which applications are included in the release. Then
the relevant application resource files <c>App.app</c> are
- read to find out the version and modules of each application.
- (Keys <c>vsn</c> and <c>modules</c>, see <c>app(4)</c>).</p>
- <p>By default, the release package file is placed in the same
+ read to determine the version and modules of each application
+ (keys <c>vsn</c> and <c>modules</c>, see
+ <seealso marker="kernel:app"><c>app(4)</c></seealso>).</p>
+ <p>By default, the release package file is located in the same
directory as <c>Name.rel</c>. That is, in the current working
- directory unless <c>Name</c> contains a path. If the option
- <c>{outdir,Dir}</c> is provided, it is placed in <c>Dir</c>
+ directory unless <c>Name</c> contains a path. If option
+ <c>{outdir,Dir}</c> is specified, it is located in <c>Dir</c>
instead.</p>
<p>By default, the release package contains the directories
<c>lib/App-Vsn/ebin</c> and <c>lib/App-Vsn/priv</c> for each
- included application. If more directories, the option
- <c>dirs</c> is supplied. Example:
+ included application. If more directories are to be included,
+ option <c>dirs</c> is specified, for example,
<c>{dirs,[src,examples]}</c>.</p>
<p>All these files are searched for in the current path. If
- the option <c>{path,[Dir]}</c> is provided, this path is
- appended to the current path. The wildcard <c>*</c> is
+ option <c>{path,[Dir]}</c> is specified, this path is
+ appended to the current path. Wildcard <c>*</c> is
expanded to all matching directories.
Example: <c>"lib/*/ebin"</c>.</p>
- <p>The <c>variables</c> option can be used to specify an
+ <p>Option <c>variables</c> can be used to specify an
installation directory other than <c>lib</c> for some of
- the applications. If a variable <c>{VarName,Prefix}</c> is
- specified and an application is found in a directory
- <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application will be
+ the applications. If variable <c>{VarName,Prefix}</c> is
+ specified and an application is found in directory
+ <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application is
packed into a separate <c>VarName.tar.gz</c> file as
<c>Rest/App-Vsn/ebin</c>.</p>
- <p>Example: If the option <c>{variables,[{"TEST","lib"}]}</c> is
- supplied, and <c>myapp.app</c> is found in
- <c>lib/myapp-1/ebin</c>, the the application <c>myapp</c> is
+ <p><em>Example:</em> If option <c>{variables,[{"TEST","lib"}]}</c>
+ is specified and <c>myapp.app</c> is located in
+ <c>lib/myapp-1/ebin</c>, application <c>myapp</c> is
included in <c>TEST.tar.gz</c>:</p>
<pre>
% <input>tar tf TEST.tar</input>
myapp-1/ebin/myapp.app
-...
- </pre>
- <p>The <c>{var_tar,VarTar}</c> option can be used to specify if
- and where a separate package should be stored. In this option,
- <c>VarTar</c> is:</p>
- <list type="bulleted">
- <item>
- <p><c>include</c>. Each separate (variable) package is
- included in the main <c>ReleaseName.tar.gz</c> file. This
- is the default.</p>
- </item>
- <item>
- <p><c>ownfile</c>. Each separate (variable) package is
- generated as separate files in the same directory as
- the <c>ReleaseName.tar.gz</c> file.</p>
- </item>
- <item>
- <p><c>omit</c>. No separate (variable) packages are
- generated and applications which are found underneath a
- variable directory are ignored.</p>
- </item>
- </list>
- <p>A directory called <c>releases</c> is also included in
+...</pre>
+ <p>Option <c>{var_tar,VarTar}</c> can be used to specify if
+ and where a separate package is to be stored. In this option
+ <c>VarTar</c> is one of the following:</p>
+ <taglist>
+ <tag><c>include</c></tag>
+ <item><p>Each separate (variable) package is included in the
+ main <c>ReleaseName.tar.gz</c> file. This is the
+ default.</p></item>
+ <tag><c>ownfile</c></tag>
+ <item><p>Each separate (variable) package is
+ generated as a separate file in the same directory as
+ the <c>ReleaseName.tar.gz</c> file.</p></item>
+ <tag><c>omit</c></tag>
+ <item><p>No separate (variable) packages are
+ generated. Applications that are found underneath a
+ variable directory are ignored.</p></item>
+ </taglist>
+ <p>A directory <c>releases</c> is also included in
the release package, containing <c>Name.rel</c> and a
- subdirectory called <c>RelVsn</c>. <c>RelVsn</c> is
+ subdirectory <c>RelVsn</c>. <c>RelVsn</c> is
the release version as specified in <c>Name.rel</c>.</p>
<p><c>releases/RelVsn</c> contains the boot script
<c>Name.boot</c> renamed to <c>start.boot</c> and, if found,
the files <c>relup</c> and <c>sys.config</c>. These files
are searched for in the same directory as <c>Name.rel</c>,
in the current working directory, and in any directories
- specified using the <c>path</c> option.</p>
- <p>If the release package should contain a new Erlang runtime
+ specified using option <c>path</c>.</p>
+ <p>If the release package is to contain a new Erlang runtime
system, the <c>bin</c> directory of the specified runtime
system <c>{erts,Dir}</c> is copied to <c>erts-ErtsVsn/bin</c>.</p>
- <p>All checks performed with the <c>make_script</c> function
- are performed before the release package is created. The
- <c>src_tests</c> and <c>exref</c> options are also
+ <p>All checks with function
+ <seealso marker="#make_script/1"><c>make_script</c></seealso>
+ are performed before the release package is created.
+ Options <c>src_tests</c> and <c>exref</c> are also
valid here.</p>
<p>The return value and the handling of errors and warnings
- are the same as described for <c>make_script</c> above.</p>
+ are the same as described for
+ <seealso marker="#make_script/1"><c>make_script</c></seealso>.</p>
</desc>
</func>
+
<func>
<name>script2boot(File) -> ok | error</name>
- <fsummary>Generate a binary version of a boot script.</fsummary>
+ <fsummary>Generates a binary version of a boot script.</fsummary>
<type>
<v>File = string()</v>
</type>
@@ -366,17 +373,24 @@ myapp-1/ebin/myapp.app
<p>The Erlang runtime system requires that the contents of
the script used to boot the system is a binary Erlang term.
This function transforms the <c>File.script</c> boot script
- to a binary term which is stored in the file <c>File.boot</c>.</p>
- <p>A boot script generated using the <c>make_script</c>
- function is already transformed to the binary form.</p>
+ to a binary term, which is stored in the <c>File.boot</c>
+ file.</p>
+ <p>A boot script generated using
+ <seealso marker="#make_script/1"><c>make_script</c></seealso>
+ is already transformed to the binary form.</p>
</desc>
</func>
</funcs>
<section>
- <title>SEE ALSO</title>
- <p>app(4), appup(4), erl(1), rel(4), release_handler(3), relup(4),
- script(4)</p>
+ <title>See Also</title>
+ <p><seealso marker="kernel:app"><c>app(4)</c></seealso>,
+ <seealso marker="appup"><c>appup(4)</c></seealso>,
+ <seealso marker="erts:erl"><c>erl(1)</c></seealso>,
+ <seealso marker="rel"><c>rel(4)</c></seealso>,
+ <seealso marker="release_handler"><c>release_handler(3)</c></seealso>,
+ <seealso marker="relup"><c>relup(4)</c></seealso>,
+ <seealso marker="script"><c>script(4)</c></seealso></p>
</section>
</erlref>
diff --git a/lib/sasl/examples/src/Makefile b/lib/sasl/examples/src/Makefile
index c0d73aab1d..82083d1197 100644
--- a/lib/sasl/examples/src/Makefile
+++ b/lib/sasl/examples/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/sasl/examples/src/target_system.erl b/lib/sasl/examples/src/target_system.erl
index a0ae016791..d18fdb17f7 100644
--- a/lib/sasl/examples/src/target_system.erl
+++ b/lib/sasl/examples/src/target_system.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/src/Makefile b/lib/sasl/src/Makefile
index ab2d3a3ecd..7ff6a03a50 100644
--- a/lib/sasl/src/Makefile
+++ b/lib/sasl/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/sasl/src/alarm_handler.erl b/lib/sasl/src/alarm_handler.erl
index b118a8cafd..e428ba80fa 100644
--- a/lib/sasl/src/alarm_handler.erl
+++ b/lib/sasl/src/alarm_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/erlsrv.erl b/lib/sasl/src/erlsrv.erl
index 0d931f1779..bec824ad78 100644
--- a/lib/sasl/src/erlsrv.erl
+++ b/lib/sasl/src/erlsrv.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/format_lib_supp.erl b/lib/sasl/src/format_lib_supp.erl
index 5348bc6d59..e2f70c7f00 100644
--- a/lib/sasl/src/format_lib_supp.erl
+++ b/lib/sasl/src/format_lib_supp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/misc_supp.erl b/lib/sasl/src/misc_supp.erl
index 8948fdb797..42de7eedec 100644
--- a/lib/sasl/src/misc_supp.erl
+++ b/lib/sasl/src/misc_supp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/overload.erl b/lib/sasl/src/overload.erl
index 736423484a..bc8ab7d5e4 100644
--- a/lib/sasl/src/overload.erl
+++ b/lib/sasl/src/overload.erl
@@ -3,21 +3,24 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(overload).
+-deprecated(module).
+
-export([start_link/0, request/0, set_config_data/2,
get_overload_info/0]).
diff --git a/lib/sasl/src/rb.erl b/lib/sasl/src/rb.erl
index 65011af568..f63c02e748 100644
--- a/lib/sasl/src/rb.erl
+++ b/lib/sasl/src/rb.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/src/rb_format_supp.erl b/lib/sasl/src/rb_format_supp.erl
index b1d83d14d0..ed10022f9d 100644
--- a/lib/sasl/src/rb_format_supp.erl
+++ b/lib/sasl/src/rb_format_supp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl
index ccd84f0c37..7e20d0b321 100644
--- a/lib/sasl/src/release_handler.erl
+++ b/lib/sasl/src/release_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl
index fa6ef77b2d..a6325270a5 100644
--- a/lib/sasl/src/release_handler_1.erl
+++ b/lib/sasl/src/release_handler_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -586,12 +587,12 @@ get_supervised_procs() ->
get_application_names()).
get_supervised_procs(_, Root, Procs, {ok, SupMod}) ->
- get_procs(maybe_supervisor_which_children(get_proc_state(Root), SupMod, Root), Root) ++
+ get_procs(maybe_supervisor_which_children(Root, SupMod, Root), Root) ++
[{undefined, undefined, Root, [SupMod]} | Procs];
get_supervised_procs(Application, Root, Procs, {error, _}) ->
error_logger:error_msg("release_handler: cannot find top supervisor for "
"application ~w~n", [Application]),
- get_procs(maybe_supervisor_which_children(get_proc_state(Root), Application, Root), Root) ++ Procs.
+ get_procs(maybe_supervisor_which_children(Root, Application, Root), Root) ++ Procs.
get_application_names() ->
lists:map(fun({Application, _Name, _Vsn}) ->
@@ -612,33 +613,54 @@ get_procs([{Name, Pid, worker, Mods} | T], Sup) when is_pid(Pid), is_list(Mods)
[{Sup, Name, Pid, Mods} | get_procs(T, Sup)];
get_procs([{Name, Pid, supervisor, Mods} | T], Sup) when is_pid(Pid) ->
[{Sup, Name, Pid, Mods} | get_procs(T, Sup)] ++
- get_procs(maybe_supervisor_which_children(get_proc_state(Pid), Name, Pid), Pid);
+ get_procs(maybe_supervisor_which_children(Pid, Name, Pid), Pid);
get_procs([_H | T], Sup) ->
get_procs(T, Sup);
get_procs(_, _Sup) ->
[].
+maybe_supervisor_which_children(Proc, Name, Pid) ->
+ case get_proc_state(Proc) of
+ noproc ->
+ %% process exited before we could interrogate it.
+ %% not necessarily a bug, but reporting a warning as a curiosity.
+ error_logger:warning_msg("release_handler: a process (~p) exited"
+ " during supervision tree interrogation."
+ " Continuing ...~n", [Proc]),
+ [];
+
+ suspended ->
+ error_logger:error_msg("release_handler: a which_children call"
+ " to ~p (~w) was avoided. This supervisor"
+ " is suspended and should likely be upgraded"
+ " differently. Exiting ...~n", [Name, Pid]),
+ error(suspended_supervisor);
+
+ running ->
+ case catch supervisor:which_children(Pid) of
+ Res when is_list(Res) ->
+ Res;
+ Other ->
+ error_logger:error_msg("release_handler: ~p~nerror during"
+ " a which_children call to ~p (~w)."
+ " [State: running] Exiting ... ~n",
+ [Other, Name, Pid]),
+ error(which_children_failed)
+ end
+ end.
+
get_proc_state(Proc) ->
- {status, _, {module, _}, [_, State, _, _, _]} = sys:get_status(Proc),
- State.
-
-maybe_supervisor_which_children(suspended, Name, Pid) ->
- error_logger:error_msg("release_handler: a which_children call"
- " to ~p (~w) was avoided. This supervisor"
- " is suspended and should likely be upgraded"
- " differently. Exiting ...~n", [Name, Pid]),
- error(suspended_supervisor);
-
-maybe_supervisor_which_children(State, Name, Pid) ->
- case catch supervisor:which_children(Pid) of
- Res when is_list(Res) ->
- Res;
- Other ->
- error_logger:error_msg("release_handler: ~p~nerror during"
- " a which_children call to ~p (~w)."
- " [State: ~p] Exiting ... ~n",
- [Other, Name, Pid, State]),
- error(which_children_failed)
+ %% sys:send_system_msg can exit with {noproc, {m,f,a}}.
+ %% This happens if a supervisor exits after which_children has provided
+ %% its pid for interrogation.
+ %% ie. Proc may no longer be running at this point.
+ try sys:get_status(Proc) of
+ %% as per sys:get_status/1, SysState can only be running | suspended.
+ {status, _, {module, _}, [_, State, _, _, _]} when State == running ;
+ State == suspended ->
+ State
+ catch exit:{noproc, {sys, get_status, [Proc]}} ->
+ noproc
end.
maybe_get_dynamic_mods(Name, Pid) ->
@@ -654,48 +676,19 @@ maybe_get_dynamic_mods(Name, Pid) ->
error(get_modules_failed)
end.
-%% XXXX
-%% Note: The following is a terrible hack done in order to resolve the
-%% problem stated in ticket OTP-3452.
-
-%% XXXX NOTE WELL: This record is from supervisor.erl. Also the record
-%% name is really `state'.
--record(supervisor_state, {name,
- strategy,
- children = [],
- dynamics = [],
- intensity,
- period,
- restarts = [],
- module,
- args}).
-
%% Return the name of the call-back module that implements the
%% (top) supervisor SupPid.
%% Returns: {ok, Module} | {error,undefined}
%%
get_supervisor_module(SupPid) ->
- case catch get_supervisor_module1(SupPid) of
- {ok, Module} when is_atom(Module) ->
+ case catch supervisor:get_callback_module(SupPid) of
+ Module when is_atom(Module) ->
{ok, Module};
_Other ->
io:format("~w: reason: ~w~n", [SupPid, _Other]),
{error, undefined}
end.
-get_supervisor_module1(SupPid) ->
- {status, _Pid, {module, _Mod},
- [_PDict, _SysState, _Parent, _Dbg, Misc]} = sys:get_status(SupPid),
- %% supervisor Misc field changed at R13B04, handle old and new variants here
- State = case Misc of
- [_Name, State1, _Type, _Time] ->
- State1;
- [_Header, _Data, {data, [{"State", State2}]}] ->
- State2
- end,
- %% Cannot use #supervisor_state{module = Module} = State.
- {ok, element(#supervisor_state.module, State)}.
-
%%-----------------------------------------------------------------
%% Func: do_soft_purge/3
%% Args: Mod = atom()
diff --git a/lib/sasl/src/sasl.app.src b/lib/sasl/src/sasl.app.src
index 8e95197a2a..507e2dc229 100644
--- a/lib/sasl/src/sasl.app.src
+++ b/lib/sasl/src/sasl.app.src
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -45,6 +46,6 @@
{env, [{sasl_error_logger, tty},
{errlog_type, all}]},
{mod, {sasl, []}},
- {runtime_dependencies, ["tools-2.6.14","stdlib-2.0","kernel-3.0",
+ {runtime_dependencies, ["tools-2.6.14","stdlib-2.8","kernel-4.1",
"erts-6.0"]}]}.
diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src
index e789853eea..e08ae369b8 100644
--- a/lib/sasl/src/sasl.appup.src
+++ b/lib/sasl/src/sasl.appup.src
@@ -3,23 +3,24 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"2\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.3(\\.[0-9]+)*">>,[restart_new_emulator]}], %% R16
+ [{<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-17
%% Down to - max one major revision back
- [{<<"2\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.3(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
+ [{<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-17
}.
diff --git a/lib/sasl/src/sasl.erl b/lib/sasl/src/sasl.erl
index fdea6da13e..fc49fc2465 100644
--- a/lib/sasl/src/sasl.erl
+++ b/lib/sasl/src/sasl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -55,7 +56,9 @@ get_sasl_error_logger() ->
case application:get_env(sasl, sasl_error_logger) of
{ok, false} -> undefined;
{ok, tty} -> tty;
- {ok, {file, File}} when is_list(File) -> {file, File};
+ {ok, {file, File}} when is_list(File) -> {file, File, [write]};
+ {ok, {file, File, Modes}} when is_list(File), is_list(Modes) ->
+ {file, File, Modes};
{ok, Bad} -> exit({bad_config, {sasl, {sasl_error_logger, Bad}}});
_ -> undefined
end.
@@ -125,9 +128,9 @@ delete_sasl_error_logger(Type) ->
error_logger:delete_report_handler(mod(Type)).
mod(tty) -> sasl_report_tty_h;
-mod({file, _File}) -> sasl_report_file_h.
+mod({file, _File, _Modes}) -> sasl_report_file_h.
-args({file, File}, Type) -> {File, type(Type)};
+args({file, File, Modes}, Type) -> {File, Modes, type(Type)};
args(_, Type) -> type(Type).
type(error) -> error;
diff --git a/lib/sasl/src/sasl_report.erl b/lib/sasl/src/sasl_report.erl
index c3e6fede15..0b8c4212d2 100644
--- a/lib/sasl/src/sasl_report.erl
+++ b/lib/sasl/src/sasl_report.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -61,27 +62,53 @@ write_report2(IO, Fd, Head, supervisor_report, Report) ->
Context = sup_get(errorContext, Report),
Reason = sup_get(reason, Report),
Offender = sup_get(offender, Report),
- FmtString = " Supervisor: ~p~n Context: ~p~n Reason: "
- "~80.18p~n Offender: ~80.18p~n~n",
- write_report_action(IO, Fd, Head ++ FmtString,
- [Name,Context,Reason,Offender]);
+ {FmtString,Args} = supervisor_format([Name,Context,Reason,Offender]),
+ write_report_action(IO, Fd, Head, FmtString, Args);
write_report2(IO, Fd, Head, progress, Report) ->
Format = format_key_val(Report),
- write_report_action(IO, Fd, Head ++ "~s", [Format]);
+ write_report_action(IO, Fd, Head, "~s", [Format]);
write_report2(IO, Fd, Head, crash_report, Report) ->
- Format = proc_lib:format(Report),
- write_report_action(IO, Fd, Head ++ "~s", [Format]).
+ Depth = get_depth(),
+ Format = proc_lib:format(Report, latin1, Depth),
+ write_report_action(IO, Fd, Head, "~s", [Format]).
+
+supervisor_format(Args0) ->
+ case get_depth() of
+ unlimited ->
+ {" Supervisor: ~p~n"
+ " Context: ~p~n"
+ " Reason: ~80.18p~n"
+ " Offender: ~80.18p~n~n",
+ Args0};
+ Depth ->
+ [A,B,C,D] = Args0,
+ Args = [A,Depth,B,Depth,C,Depth,D,Depth],
+ {" Supervisor: ~P~n"
+ " Context: ~P~n"
+ " Reason: ~80.18P~n"
+ " Offender: ~80.18P~n~n",
+ Args}
+ end.
-write_report_action(io, Fd, Format, Args) ->
- io:format(Fd, Format, Args);
-write_report_action(io_lib, _Fd, Format, Args) ->
- io_lib:format(Format, Args).
+write_report_action(IO, Fd, Head, Format, Args) ->
+ S = [Head|io_lib:format(Format, Args)],
+ case IO of
+ io -> io:put_chars(Fd, S);
+ io_lib -> S
+ end.
format_key_val([{Tag,Data}|Rep]) ->
io_lib:format(" ~16w: ~p~n",[Tag,Data]) ++ format_key_val(Rep);
format_key_val(_) ->
[].
+get_depth() ->
+ case application:get_env(kernel, error_logger_format_depth) of
+ {ok, Depth} when is_integer(Depth) ->
+ max(10, Depth);
+ undefined ->
+ unlimited
+ end.
sup_get(Tag, Report) ->
case lists:keysearch(Tag, 1, Report) of
diff --git a/lib/sasl/src/sasl_report_file_h.erl b/lib/sasl/src/sasl_report_file_h.erl
index f42b4b5ff2..6c38b320c1 100644
--- a/lib/sasl/src/sasl_report_file_h.erl
+++ b/lib/sasl/src/sasl_report_file_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -28,9 +29,9 @@
handle_event/2, handle_call/2, handle_info/2,
terminate/2]).
-init({File, Type}) ->
+init({File, Modes, Type}) when is_list(Modes) ->
process_flag(trap_exit, true),
- case file:open(File, [write]) of
+ case file:open(File, Modes) of
{ok,Fd} ->
{ok, {Fd, File, Type}};
What ->
diff --git a/lib/sasl/src/sasl_report_tty_h.erl b/lib/sasl/src/sasl_report_tty_h.erl
index 8d63428aeb..54e8addc45 100644
--- a/lib/sasl/src/sasl_report_tty_h.erl
+++ b/lib/sasl/src/sasl_report_tty_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/si.erl b/lib/sasl/src/si.erl
index e2f6d95e58..e4bd8f5fd8 100644
--- a/lib/sasl/src/si.erl
+++ b/lib/sasl/src/si.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/si_sasl_supp.erl b/lib/sasl/src/si_sasl_supp.erl
index 12b2557cd6..0dcdcdd912 100644
--- a/lib/sasl/src/si_sasl_supp.erl
+++ b/lib/sasl/src/si_sasl_supp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/src/systools.erl b/lib/sasl/src/systools.erl
index 51ef687047..98255e0b12 100644
--- a/lib/sasl/src/systools.erl
+++ b/lib/sasl/src/systools.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/systools.hrl b/lib/sasl/src/systools.hrl
index da531dbee5..0bf822ed07 100644
--- a/lib/sasl/src/systools.hrl
+++ b/lib/sasl/src/systools.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/systools_lib.erl b/lib/sasl/src/systools_lib.erl
index 0a96f2bd48..1538e1e90f 100644
--- a/lib/sasl/src/systools_lib.erl
+++ b/lib/sasl/src/systools_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl
index e5da797efb..8132034172 100644
--- a/lib/sasl/src/systools_make.erl
+++ b/lib/sasl/src/systools_make.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/src/systools_rc.erl b/lib/sasl/src/systools_rc.erl
index 76f753c3d0..285c805b5d 100644
--- a/lib/sasl/src/systools_rc.erl
+++ b/lib/sasl/src/systools_rc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -32,7 +33,6 @@
%% {load_module, Mod, PrePurge, PostPurge, [Mod]}
%% {add_module, Mod}
%% {add_module, Mod, [Mod]}
-%% {remove_module, Mod, PrePurge, PostPurge, [Mod]}
%% {restart_application, Appl}
%% {add_application, Appl, Type}
%% {remove_application, Appl}
@@ -59,7 +59,7 @@
%% High-level instructions that contain dependencies
%%
--define(DEP_INSTRS, [update, load_module, add_module, remove_module]).
+-define(DEP_INSTRS, [update, load_module, add_module, delete_module]).
%%-----------------------------------------------------------------
%% translate_scripts(Scripts, Appls, PreAppls) -> Res
@@ -107,9 +107,6 @@ expand_script([I|Script]) ->
{update, Mod, Change, Mods} when Change==soft,
is_list(Mods) ->
{update, Mod, Change, brutal_purge,brutal_purge, Mods};
- {delete_module, Mod} ->
- [{remove, {Mod, brutal_purge, brutal_purge}},
- {purge, [Mod]}];
{add_application, Application} ->
{add_application, Application, permanent};
_ ->
@@ -301,6 +298,8 @@ normalize_instrs(Script) ->
PostPurge, Mods};
({add_module, Mod}) ->
{add_module, Mod, []};
+ ({delete_module, Mod}) ->
+ {delete_module, Mod, []};
(I) ->
I
end, Script).
@@ -412,7 +411,7 @@ translate_add_module_instrs(Before, After) ->
%%-----------------------------------------------------------------
%%-----------------------------------------------------------------
-%% Translates update, load_module and remove_module, and reorder the
+%% Translates update, load_module and delete_module, and reorder the
%% instructions according to dependencies. Leaves other instructions
%% unchanged.
%%-----------------------------------------------------------------
@@ -538,7 +537,7 @@ get_dependent_instructions(G, WCs, Mod) ->
%% Instructions are in order of dependency.
%% Appls = [#application]
%%
-%% Instructions translated are: update, load_module, and remove_module
+%% Instructions translated are: update, load_module, and delete_module
%%
%% Before = [{load_object_code, ...}]
%% After = [{suspend, ...}] ++ CodeInstrs ++ [{resume, ...}]
@@ -576,17 +575,19 @@ translate_dep_to_low(Mode, Instructions, Appls) ->
end, RevUpdateMods)}]
end,
- LoadRemoveInstrs =
+ LoadRemoveInstrs0 =
filtermap(fun({update, Mod, _, _, _, PreP, PostP, _}) ->
{true, {load, {Mod, PreP, PostP}}};
({load_module, Mod, PreP, PostP, _}) ->
{true, {load, {Mod, PreP, PostP}}};
- ({remove_module, Mod, PreP, PostP, _}) ->
- {true, {remove, {Mod, PreP, PostP}}};
+ ({delete_module, Mod, _}) ->
+ {true,[{remove, {Mod, brutal_purge, brutal_purge}},
+ {purge, [Mod]}]};
(_) -> false
end,
Instructions),
- RevLoadRemoveInstrs = lists:reverse(LoadRemoveInstrs),
+ LoadRemoveInstrs = lists:flatten(LoadRemoveInstrs0),
+ RevLoadRemoveInstrs = lists:flatten(lists:reverse(LoadRemoveInstrs0)),
%% The order of loading object code is unimportant. The order
%% chosen is the order of dependency.
@@ -781,10 +782,10 @@ check_op({add_module, Mod, Mods}) ->
check_mod(Mod),
check_list(Mods),
lists:foreach(fun(M) -> check_mod(M) end, Mods);
-check_op({remove_module, Mod, PrePurge, PostPurge, Mods}) ->
+check_op({delete_module, Mod}) ->
+ check_mod(Mod);
+check_op({delete_module, Mod, Mods}) ->
check_mod(Mod),
- check_purge(PrePurge),
- check_purge(PostPurge),
check_list(Mods),
lists:foreach(fun(M) -> check_mod(M) end, Mods);
check_op({remove_application, Appl}) ->
diff --git a/lib/sasl/src/systools_relup.erl b/lib/sasl/src/systools_relup.erl
index b3494542e5..a520da1c3f 100644
--- a/lib/sasl/src/systools_relup.erl
+++ b/lib/sasl/src/systools_relup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile
index 837abf74d4..86976def6a 100644
--- a/lib/sasl/test/Makefile
+++ b/lib/sasl/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2011-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -28,11 +29,13 @@ MODULES= \
alarm_handler_SUITE \
installer \
release_handler_SUITE \
+ sasl_report_SUITE \
+ sasl_report_suite_supervisor \
systools_SUITE \
systools_rc_SUITE \
overload_SUITE \
rb_SUITE \
- rh_test_lib
+ rh_test_lib \
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/sasl/test/alarm_handler_SUITE.erl b/lib/sasl/test/alarm_handler_SUITE.erl
index a4064ef27a..f2ed9ffc19 100644
--- a/lib/sasl/test/alarm_handler_SUITE.erl
+++ b/lib/sasl/test/alarm_handler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/test/installer.erl b/lib/sasl/test/installer.erl
index fa404c8b7b..c42f26a506 100644
--- a/lib/sasl/test/installer.erl
+++ b/lib/sasl/test/installer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/test/overload_SUITE.erl b/lib/sasl/test/overload_SUITE.erl
index e7f180b2ea..02d1056698 100644
--- a/lib/sasl/test/overload_SUITE.erl
+++ b/lib/sasl/test/overload_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/test/rb_SUITE.erl b/lib/sasl/test/rb_SUITE.erl
index 453f992850..9a33df369e 100644
--- a/lib/sasl/test/rb_SUITE.erl
+++ b/lib/sasl/test/rb_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index b7c5f34f58..ee620dcdb4 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1362,7 +1363,7 @@ upgrade_supervisor(Conf) when is_list(Conf) ->
%% Check that the restart strategy and child spec is updated
{status, _, {module, _}, [_, _, _, _, [_,_,{data,[{"State",State}]}]]} =
rpc:call(Node,sys,get_status,[a_sup]),
- {state,_,RestartStrategy,[Child],_,_,_,_,_,_} = State,
+ {state,_,RestartStrategy,[Child],_,_,_,_,_,_,_} = State,
one_for_all = RestartStrategy, % changed from one_for_one
{child,_,_,_,_,brutal_kill,_,_} = Child, % changed from timeout 2000
diff --git a/lib/sasl/test/release_handler_SUITE_data/c/aa.erl b/lib/sasl/test/release_handler_SUITE_data/c/aa.erl
index 1c853c85b2..0df1221660 100644
--- a/lib/sasl/test/release_handler_SUITE_data/c/aa.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/c/aa.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/c/b.erl b/lib/sasl/test/release_handler_SUITE_data/c/b.erl
index d8426a515e..4bfe6efef0 100644
--- a/lib/sasl/test/release_handler_SUITE_data/c/b.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/c/b.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/c/c_sup.erl b/lib/sasl/test/release_handler_SUITE_data/c/c_sup.erl
index 069eb3b99b..915c89138b 100644
--- a/lib/sasl/test/release_handler_SUITE_data/c/c_sup.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/c/c_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/README b/lib/sasl/test/release_handler_SUITE_data/lib/README
index ffb8c5120b..5d17950b0b 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/README
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/README
@@ -21,7 +21,7 @@ start version, includes b_lib and b_server
b-2.0:
can be upgraded to from b-1.0.
-Removes b_lib (soft_purge) and updates b_server (brutal_purge)
+Removes b_lib (brutal_purge) and updates b_server (soft_purge)
* The diff in purge method is important for test "check_and_purge", in
order to check that the purge option to check_install_release works
for both methods.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.erl
index bb500bed69..383ecbcfb8 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a_sup.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a_sup.erl
index a141c1767b..8de9534cc3 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a_sup.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl
index 1050e53f35..9d058a1fdf 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a_sup.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a_sup.erl
index a141c1767b..8de9534cc3 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a_sup.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl
index c082ad5339..916b7c301e 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl
index a141c1767b..8de9534cc3 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl
index 1050e53f35..9d058a1fdf 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl
index ae1d080f58..8b24088a63 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl
index 1050e53f35..9d058a1fdf 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl
index b0597dc5c3..fba4193da2 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup
index 001255a88c..9df590e63f 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup
@@ -1,6 +1,6 @@
%% -*- erlang -*-
{"2.0",
- [{"1.0",[{remove_module,b_lib,soft_purge,soft_purge,[]},
- {update,b_server,{advanced,[]}}]}],
+ [{"1.0",[{delete_module,b_lib},
+ {update,b_server,{advanced,[]},soft_purge,soft_purge,[]}]}],
[{"1.0",[{add_module,b_lib},
- {update,b_server,{advanced,[]}}]}]}.
+ {update,b_server,{advanced,[]},soft_purge,soft_purge,[]}]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_atom.erl b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_atom.erl
index 883688c231..a494d8a12c 100644
--- a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_atom.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_atom.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_list.erl b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_list.erl
index 34c38307ba..bc2bc50039 100644
--- a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_list.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_list.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_numeric.erl b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_numeric.erl
index 6bf52753fd..aeba04d525 100644
--- a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_numeric.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_numeric.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_string.erl b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_string.erl
index aa430a0bb3..5fa1603c91 100644
--- a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_string.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_string.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_tuple.erl b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_tuple.erl
index 3ff1018994..160fe35419 100644
--- a/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_tuple.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/otp_2740/vsn_tuple.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app
index ba6d09cd42..e872a14c08 100644
--- a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app
+++ b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup
index 9c657232d0..accfdb3c4a 100644
--- a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup
+++ b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"1.1",
diff --git a/lib/sasl/test/sasl_SUITE.erl b/lib/sasl/test/sasl_SUITE.erl
index d7b99d506e..cd8316b451 100644
--- a/lib/sasl/test/sasl_SUITE.erl
+++ b/lib/sasl/test/sasl_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,10 +27,12 @@
%% Test cases must be exported.
-export([app_test/1,
appup_test/1,
- log_mf_h_env/1]).
+ log_mf_h_env/1,
+ log_file/1,
+ utc_log/1]).
all() ->
- [log_mf_h_env, app_test, appup_test].
+ [log_mf_h_env, log_file, app_test, appup_test, utc_log].
groups() ->
[].
@@ -151,10 +154,9 @@ check_appup([],_,_) ->
log_mf_h_env(Config) ->
PrivDir = ?config(priv_dir,Config),
LogDir = filename:join(PrivDir,sasl_SUITE_log_dir),
- ok = file:make_dir(LogDir),
+ ok = filelib:ensure_dir(LogDir),
application:stop(sasl),
- SaslEnv = application:get_all_env(sasl),
- lists:foreach(fun({E,_V}) -> application:unset_env(sasl,E) end, SaslEnv),
+ clear_env(sasl),
ok = application:set_env(sasl,error_logger_mf_dir,LogDir),
match_error(missing_config,application:start(sasl)),
@@ -178,6 +180,107 @@ log_mf_h_env(Config) ->
ok = application:set_env(sasl,error_logger_mf_dir,LogDir),
ok = application:start(sasl).
+log_file(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ LogDir = filename:join(PrivDir,sasl_SUITE_log_dir),
+ File = filename:join(LogDir, "file.log"),
+ ok = filelib:ensure_dir(File),
+ application:stop(sasl),
+ clear_env(sasl),
+
+ _ = test_log_file(File, {file,File}),
+ _ = test_log_file(File, {file,File,[write]}),
+
+ ok = file:write_file(File, <<"=PROGRESS preserve me\n">>),
+ <<"=PROGRESS preserve me\n",_/binary>> =
+ test_log_file(File, {file,File,[append]}),
+
+ ok = application:set_env(sasl,sasl_error_logger, tty,
+ [{persistent, false}]),
+ ok = application:start(sasl).
+
+test_log_file(File, Arg) ->
+ ok = application:set_env(sasl, sasl_error_logger, Arg,
+ [{persistent, true}]),
+ ok = application:start(sasl),
+ application:stop(sasl),
+ {ok,Bin} = file:read_file(File),
+ ok = file:delete(File),
+ Lines0 = binary:split(Bin, <<"\n">>, [trim_all,global]),
+ Lines = [L || L <- Lines0,
+ binary:match(L, <<"=PROGRESS">>) =:= {0,9}],
+ io:format("~p:\n~p\n", [Arg,Lines]),
+
+ %% There must be at least four PROGRESS lines.
+ if
+ length(Lines) >= 4 -> ok;
+ true -> ?t:fail()
+ end,
+ Bin.
+
+%% Make a basic test of utc_log.
+utc_log(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LogDir = filename:join(PrivDir, sasl_SUITE_log_dir),
+ Log = filename:join(LogDir, "utc.log"),
+ ok = filelib:ensure_dir(Log),
+
+ application:stop(sasl),
+ clear_env(sasl),
+
+ %% Test that the UTC marker gets added to PROGRESS lines
+ %% when the utc_log configuration variable is set to true.
+ ok = application:set_env(sasl, sasl_error_logger, {file,Log},
+ [{persistent,true}]),
+ ok = application:set_env(sasl, utc_log, true, [{persistent,true}]),
+ ok = application:start(sasl),
+ application:stop(sasl),
+
+ verify_utc_log(Log, true),
+
+ %% Test that no UTC markers gets added to PROGRESS lines
+ %% when the utc_log configuration variable is set to false.
+ ok = application:set_env(sasl, utc_log, false, [{persistent,true}]),
+ ok = application:start(sasl),
+ application:stop(sasl),
+
+ verify_utc_log(Log, false),
+
+ %% Test that no UTC markers gets added to PROGRESS lines
+ %% when the utc_log configuration variable is unset.
+ ok = application:unset_env(sasl, utc_log, [{persistent,true}]),
+ ok = application:start(sasl),
+ application:stop(sasl),
+
+ verify_utc_log(Log, false),
+
+ %% Change back to the standard TTY error logger.
+ ok = application:set_env(sasl,sasl_error_logger, tty,
+ [{persistent, false}]),
+ ok = application:start(sasl).
+
+verify_utc_log(Log, UTC) ->
+ {ok,Bin} = file:read_file(Log),
+ ok = file:delete(Log),
+
+ Lines0 = binary:split(Bin, <<"\n">>, [trim_all,global]),
+ Lines = [L || L <- Lines0,
+ binary:match(L, <<"=PROGRESS">>) =:= {0,9}],
+ Setting = application:get_env(sasl, utc_log),
+ io:format("utc_log ~p:\n~p\n", [Setting,Lines]),
+ Filtered = [L || L <- Lines,
+ binary:match(L, <<" UTC ===">>) =:= nomatch],
+ %% Filtered now contains all lines WITHOUT any UTC markers.
+ case UTC of
+ false ->
+ %% No UTC marker on the PROGRESS line.
+ Filtered = Lines;
+ true ->
+ %% Each PROGRESS line must have an UTC marker.
+ [] = Filtered
+ end,
+ ok.
+
%%-----------------------------------------------------------------
%% Internal
@@ -185,3 +288,7 @@ match_error(Expected,{error,{bad_return,{_,{'EXIT',{Expected,{sasl,_}}}}}}) ->
ok;
match_error(Expected,Actual) ->
?t:fail({unexpected_return,Expected,Actual}).
+
+clear_env(App) ->
+ [application:unset_env(App,Opt) || {Opt,_} <- application:get_all_env(App)],
+ ok.
diff --git a/lib/sasl/test/sasl_report_SUITE.erl b/lib/sasl/test/sasl_report_SUITE.erl
new file mode 100644
index 0000000000..940234f152
--- /dev/null
+++ b/lib/sasl/test/sasl_report_SUITE.erl
@@ -0,0 +1,141 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(sasl_report_SUITE).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([gen_server_crash/1]).
+
+-export([crash_me/0,start_link/0,init/1,handle_cast/2,terminate/2]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [gen_server_crash].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+gen_server_crash(Config) ->
+ try
+ do_gen_server_crash(Config)
+ after
+ error_logger:tty(true),
+ ok = application:unset_env(sasl, sasl_error_logger),
+ ok = application:unset_env(kernel, error_logger_format_depth),
+ error_logger:add_report_handler(cth_log_redirect)
+ end,
+ ok.
+
+do_gen_server_crash(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LogDir = filename:join(PrivDir, ?MODULE),
+ KernelLog = filename:join(LogDir, "kernel.log"),
+ SaslLog = filename:join(LogDir, "sasl.log"),
+ ok = filelib:ensure_dir(SaslLog),
+
+ error_logger:delete_report_handler(cth_log_redirect),
+ error_logger:tty(false),
+ application:stop(sasl),
+ ok = application:set_env(sasl, sasl_error_logger, {file,SaslLog},
+ [{persistent,true}]),
+ application:set_env(kernel, error_logger_format_depth, 30),
+ error_logger:logfile({open,KernelLog}),
+ application:start(sasl),
+ io:format("~p\n", [gen_event:which_handlers(error_logger)]),
+
+ crash_me(),
+
+ error_logger:logfile(close),
+
+ check_file(KernelLog, 70000, 150000),
+ check_file(SaslLog, 50000, 100000),
+
+ ok.
+
+check_file(File, Min, Max) ->
+ {ok,Bin} = file:read_file(File),
+ Base = filename:basename(File),
+ io:format("*** Contents of ~s ***\n", [Base]),
+ io:put_chars([Bin,"\n"]),
+ Sz = byte_size(Bin),
+ io:format("Size: ~p (allowed range is ~p..~p)\n",
+ [Sz,Min,Max]),
+ if
+ Sz < Min ->
+ %% Truncated? Other problem?
+ ?t:fail({too_short,Base});
+ Sz > Max ->
+ %% Truncation doesn't work?
+ ?t:fail({too_big,Base});
+ true ->
+ ok
+ end.
+
+%%%
+%%% gen_server that crashes.
+%%%
+
+crash_me() ->
+ {ok,SuperPid} = supervisor:start_link(sasl_report_suite_supervisor, []),
+ [{Id,Pid,_,_}] = supervisor:which_children(SuperPid),
+ HugeData = gb_sets:from_list(lists:seq(1, 100000)),
+ gen_server:cast(Pid, HugeData),
+ Ref = monitor(process, Pid),
+ receive
+ {'DOWN',Ref,process,Pid,_} ->
+ supervisor:terminate_child(SuperPid, Id),
+ unlink(SuperPid),
+ exit(SuperPid, kill),
+ ok
+ end.
+
+start_link() ->
+ gen_server:start_link(?MODULE, [], []).
+
+init(_) ->
+ St = <<0:100000/unit:8>>,
+ {ok,St}.
+
+handle_cast(Big, St) ->
+ Seq = lists:seq(1, 10000),
+ self() ! Seq,
+ self() ! Seq,
+ self() ! Seq,
+ self() ! Seq,
+ self() ! Seq,
+ x = Big,
+ {noreply,St}.
+
+terminate(_, _) ->
+ ok.
diff --git a/lib/sasl/test/sasl_report_suite_supervisor.erl b/lib/sasl/test/sasl_report_suite_supervisor.erl
new file mode 100644
index 0000000000..bc92a40af2
--- /dev/null
+++ b/lib/sasl/test/sasl_report_suite_supervisor.erl
@@ -0,0 +1,77 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(sasl_report_suite_supervisor).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+%%%===================================================================
+%%% API functions
+%%%===================================================================
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Starts the supervisor
+%%
+%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+start_link() ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%%%===================================================================
+%%% Supervisor callbacks
+%%%===================================================================
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Whenever a supervisor is started using supervisor:start_link/[2,3],
+%% this function is called by the new process to find out about
+%% restart strategy, maximum restart intensity, and child
+%% specifications.
+%%
+%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
+%% ignore |
+%% {error, Reason}
+%% @end
+%%--------------------------------------------------------------------
+init([]) ->
+
+ SupFlags = #{strategy => one_for_one,
+ intensity => 1,
+ period => 5},
+
+ AChild = #{id => 'sasl_report_suit_supervisor',
+ start => {sasl_report_SUITE, start_link, []},
+ restart => permanent,
+ shutdown => 5000,
+ type => worker,
+ modules => [sasl_report_SUITE]},
+
+ {ok, {SupFlags, [AChild]}}.
diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl
index 49a4303e0b..cf0ed5fcfc 100644
--- a/lib/sasl/test/systools_SUITE.erl
+++ b/lib/sasl/test/systools_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/sasl/test/systools_rc_SUITE.erl b/lib/sasl/test/systools_rc_SUITE.erl
index 5efab7c028..3754ed99f2 100644
--- a/lib/sasl/test/systools_rc_SUITE.erl
+++ b/lib/sasl/test/systools_rc_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,14 +23,16 @@
-include_lib("sasl/src/systools.hrl").
-export([all/0,groups/0,init_per_group/2,end_per_group/2,
syntax_check/1, translate/1, translate_app/1,
- translate_emulator_restarts/1]).
+ translate_emulator_restarts/1,
+ translate_add_delete_module/1]).
%%-----------------------------------------------------------------
%% erl -compile systools_rc_SUITE @i ../src/ @i ../../test_server/include/
%% c(systools_rc_SUITE, [{i, "../src"}, {i, "../../test_server/include"}]).
%%-----------------------------------------------------------------
all() ->
- [syntax_check, translate, translate_app, translate_emulator_restarts].
+ [syntax_check, translate, translate_app, translate_emulator_restarts,
+ translate_add_delete_module].
groups() ->
[].
@@ -707,3 +710,59 @@ translate_emulator_restarts(_Config) ->
restart_emulator] = X6,
ok.
+
+translate_add_delete_module(_Config) ->
+ PreApps =
+ [#application{name = test,
+ description = "TEST",
+ vsn = "0.1",
+ modules = [foo,bar,baz,old_mod],
+ regs = [],
+ mod = {sasl, []}}],
+ Apps =
+ [#application{name = test,
+ description = "TEST",
+ vsn = "1.0",
+ modules = [foo,bar,baz,new_mod],
+ regs = [],
+ mod = {sasl, []}}],
+ S1 = [
+ {delete_module, old_mod},
+ {add_module, new_mod},
+ {load_module, foo}
+ ],
+ {ok, X1} = systools_rc:translate_scripts([S1], Apps, PreApps),
+ [{load_object_code,{test,"1.0",[new_mod,foo]}},
+ point_of_no_return,
+ {remove,{old_mod,brutal_purge,brutal_purge}},
+ {purge,[old_mod]},
+ {load,{new_mod,brutal_purge,brutal_purge}},
+ {load,{foo,brutal_purge,brutal_purge}}] = X1,
+
+ S2 = [
+ {delete_module, old_mod},
+ {add_module, new_mod, [foo]},
+ {load_module, foo}
+ ],
+ {ok, X2} = systools_rc:translate_scripts([S2], Apps, PreApps),
+ [{load_object_code,{test,"1.0",[new_mod,foo]}},
+ point_of_no_return,
+ {remove,{old_mod,brutal_purge,brutal_purge}},
+ {purge,[old_mod]},
+ {load,{foo,brutal_purge,brutal_purge}},
+ {load,{new_mod,brutal_purge,brutal_purge}}] = X2,
+
+ S3 = [
+ {delete_module, old_mod, [new_mod]},
+ {add_module, new_mod, [foo]},
+ {load_module, foo}
+ ],
+ {ok, X3} = systools_rc:translate_scripts([S3], Apps, PreApps),
+ [{load_object_code,{test,"1.0",[new_mod,foo]}},
+ point_of_no_return,
+ {load,{foo,brutal_purge,brutal_purge}},
+ {load,{new_mod,brutal_purge,brutal_purge}},
+ {remove,{old_mod,brutal_purge,brutal_purge}},
+ {purge,[old_mod]}] = X3,
+
+ ok.
diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl
index c8a4e92f24..b16c4ac34c 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,"2.16.4").
--define(stdlibvsn,"1.19.4").
+-define(kernelvsn,"3.0").
+-define(stdlibvsn,"2.0").
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index 4259a2d76c..accb58a199 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 2.4.1
+SASL_VSN = 2.7
diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile
index ff6fad8ddc..ce739f3438 100644
--- a/lib/snmp/Makefile
+++ b/lib/snmp/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile
index 6e55498669..6d5b005e3e 100644
--- a/lib/snmp/doc/src/Makefile
+++ b/lib/snmp/doc/src/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/doc/src/book.xml b/lib/snmp/doc/src/book.xml
index a5c054142f..68e87b8afe 100644
--- a/lib/snmp/doc/src/book.xml
+++ b/lib/snmp/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/files.mk b/lib/snmp/doc/src/files.mk
index 91fd18ca85..fea8deee02 100644
--- a/lib/snmp/doc/src/files.mk
+++ b/lib/snmp/doc/src/files.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/doc/src/index.html.src b/lib/snmp/doc/src/index.html.src
index 7ad2140559..e1b6be4d1f 100644
--- a/lib/snmp/doc/src/index.html.src
+++ b/lib/snmp/doc/src/index.html.src
@@ -2,16 +2,17 @@
<!-- This file is obsolete -->
<HTML>
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 52022f59ff..4693a744f5 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -33,7 +34,66 @@
</header>
- <section><title>SNMP 5.1.2</title>
+ <section><title>SNMP 5.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Snmp agent now properly handles <c>vacmViewTreeFamily</c>
+ masks.</p>
+ <p>
+ Own Id: OTP-13264</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 5.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Small documentation fixes</p>
+ <p>
+ Own Id: OTP-13017</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Update configuration check of imask ( list of ones and
+ zeros) to allow the empty list.</p>
+ <p>
+ Own Id: OTP-13101</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 5.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The runtime dependencies in the application resource
+ file have been updated. </p>
+ <p>
+ Own Id: OTP-12762</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 5.1.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/snmp/doc/src/notes_history.xml b/lib/snmp/doc/src/notes_history.xml
index 62c6782fd7..a9726b97dc 100644
--- a/lib/snmp/doc/src/notes_history.xml
+++ b/lib/snmp/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/part.xml b/lib/snmp/doc/src/part.xml
index e68872347d..5ce7c52918 100644
--- a/lib/snmp/doc/src/part.xml
+++ b/lib/snmp/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/part_notes.xml b/lib/snmp/doc/src/part_notes.xml
index f716ac10c2..9535299d74 100644
--- a/lib/snmp/doc/src/part_notes.xml
+++ b/lib/snmp/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/part_notes_history.xml b/lib/snmp/doc/src/part_notes_history.xml
index 3c1cacbede..1edc13e29e 100644
--- a/lib/snmp/doc/src/part_notes_history.xml
+++ b/lib/snmp/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/ref_man.xml b/lib/snmp/doc/src/ref_man.xml
index 9ceaa5e4fb..1b381bc97b 100644
--- a/lib/snmp/doc/src/ref_man.xml
+++ b/lib/snmp/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp.xml b/lib/snmp/doc/src/snmp.xml
index b9cd4b3402..b8e8d43fc8 100644
--- a/lib/snmp/doc/src/snmp.xml
+++ b/lib/snmp/doc/src/snmp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_advanced_agent.xml b/lib/snmp/doc/src/snmp_advanced_agent.xml
index 4323b05858..b17246438d 100644
--- a/lib/snmp/doc/src/snmp_advanced_agent.xml
+++ b/lib/snmp/doc/src/snmp_advanced_agent.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -339,7 +340,7 @@
SEQUENCE {
empDepNo INTEGER,
empName DisplayString,
- empTelNo DisplayString
+ empTelNo DisplayString,
empStatus RowStatus
}
</code>
diff --git a/lib/snmp/doc/src/snmp_agent_config_files.xml b/lib/snmp/doc/src/snmp_agent_config_files.xml
index 1e938c0dc8..1147ff81d5 100644
--- a/lib/snmp/doc/src/snmp_agent_config_files.xml
+++ b/lib/snmp/doc/src/snmp_agent_config_files.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_agent_funct_descr.xml b/lib/snmp/doc/src/snmp_agent_funct_descr.xml
index 1c89ddea22..9d2226510e 100644
--- a/lib/snmp/doc/src/snmp_agent_funct_descr.xml
+++ b/lib/snmp/doc/src/snmp_agent_funct_descr.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_agent_netif.xml b/lib/snmp/doc/src/snmp_agent_netif.xml
index a9ce05e757..9583f1f521 100644
--- a/lib/snmp/doc/src/snmp_agent_netif.xml
+++ b/lib/snmp/doc/src/snmp_agent_netif.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -75,8 +76,7 @@
<c>{Domain, Addr}</c> tuple where <c>Domain</c> is
<c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv4</c>,
and <c>Addr</c> is an
- <c>{<seealso marker="kernel:inet#type-ip_address">IpAddr</seealso>,
- IpPort}</c> tuple.</p>
+ <c>{</c><seealso marker="kernel:inet#type-ip_address"><c>IpAddr</c></seealso><c>,IpPort}</c> tuple.</p>
<section>
<marker id="outgoing_messages"></marker>
diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml
index 86f0981988..39aac8e7d7 100644
--- a/lib/snmp/doc/src/snmp_app.xml
+++ b/lib/snmp/doc/src/snmp_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -134,16 +135,16 @@
<marker id="agent_opts_and_types"></marker>
<p>Agent specific config options and types:</p>
<taglist>
- <marker id="agent_type"></marker>
- <tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
+ <tag><marker id="agent_type"></marker>
+ <c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
<item>
<p>If <c>master</c>, one master agent is
started. Otherwise, no agents are started. </p>
<p>Default is <c>master</c>.</p>
</item>
- <marker id="agent_disco"></marker>
- <tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_disco"></marker>
+ <c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_discovery_opt() =
{terminating, agent_terminating_discovery_opts()} |
@@ -155,8 +156,8 @@
<p>For defaults see the options in <c>agent_discovery_opt()</c>.</p>
</item>
- <marker id="agent_term_disco_opts"></marker>
- <tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_term_disco_opts"></marker>
+ <c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_terminating_discovery_opt() =
{enable, boolean()} |
@@ -173,8 +174,8 @@
</list>
</item>
- <marker id="agent_orig_disco_opts"></marker>
- <tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_orig_disco_opts"></marker>
+ <c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_originating_discovery_opt() =
{enable, boolean()}</c></p>
@@ -187,38 +188,39 @@
</list>
</item>
- <marker id="agent_mt"></marker>
- <tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_mt"></marker>
+ <c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, the agent is multi-threaded, with one
thread for each get request. </p>
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_data_dir"></marker>
- <tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
+ <tag><marker id="agent_data_dir"></marker>
+ <c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent internal db files are stored.</p>
</item>
- <marker id="agent_gb_max_vbs"></marker>
- <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
+
+ <tag><marker id="agent_gb_max_vbs"></marker>
+ <c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
<item>
<p>Defines the maximum number of varbinds allowed
in a Get-BULK response.</p>
<p>Default is <c>1000</c>.</p>
</item>
- <marker id="agent_local_db"></marker>
- <tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_local_db"></marker>
+ <c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
<item>
<p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent local database.</p>
<p>For defaults see the options in <c>local_db_opt()</c>.</p>
</item>
- <marker id="agent_ldb_repair"></marker>
- <tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_repair"></marker>
+ <c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>When starting snmpa_local_db it always tries to open an
existing database. If <c>false</c>, and some errors occur, a new
@@ -228,16 +230,16 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ldb_auto_save"></marker>
- <tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_auto_save"></marker>
+ <c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="agent_net_if"></marker>
- <tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_net_if"></marker>
+ <c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_opt() = {module, agent_net_if_module()} | {verbosity, verbosity()} | {options, agent_net_if_options()}</c></p>
<p>Defines options specific for the SNMP agent network interface
@@ -245,8 +247,8 @@
<p>For defaults see the options in <c>agent_net_if_opt()</c>.</p>
</item>
- <marker id="agent_ni_module"></marker>
- <tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_module"></marker>
+ <c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
SNMP agent. Must implement the
@@ -254,8 +256,8 @@
<p>Default is <c>snmpa_net_if</c>.</p>
</item>
- <marker id="agent_ni_opts"></marker>
- <tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_opts"></marker>
+ <c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -269,15 +271,15 @@
<p>For defaults see the options in <c>agent_net_if_option()</c>.</p>
</item>
- <marker id="agent_ni_req_limit"></marker>
- <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ni_req_limit"></marker>
+ <c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
<item>
<p>Max number of simultaneous requests handled by the agent.</p>
<p>Default is <c>infinity</c>.</p>
</item>
- <marker id="agent_ni_filter_opts"></marker>
- <tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_opts"></marker>
+ <c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_filter_option() = {module, agent_net_if_filter_module()}</c></p>
<p>These options are actually specific to the used module.
@@ -287,8 +289,8 @@
<c>agent_net_if_filter_option()</c>.</p>
</item>
- <marker id="agent_ni_filter_module"></marker>
- <tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_module"></marker>
+ <c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP agent. Must implement the
@@ -296,8 +298,8 @@
<p>Default is <c>snmpa_net_if_filter</c>.</p>
</item>
- <marker id="agent_mibs"></marker>
- <tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="agent_mibs"></marker>
+ <c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) that defines which MIBs
are initially loaded into the SNMP master agent. </p>
@@ -311,8 +313,8 @@
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="agent_mib_storage"></marker>
- <tag><c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_storage"></marker>
+ <c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_storage_opt() = {module, mib_storage_module()} | {options, mib_storage_options()}</c></p>
<p>This option specifies how basic mib data is stored.
@@ -321,8 +323,8 @@
<p>Default is <c>[{module, snmpa_mib_storage_ets}]</c>. </p>
</item>
- <marker id="agent_mst_module"></marker>
- <tag><c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
+ <tag><marker id="agent_mst_module"></marker>
+ <c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
<item>
<p>Defines the mib storage module of the SNMP agent as defined by the
<seealso marker="snmpa_mib_storage">snmpa_mib_storage</seealso>
@@ -336,8 +338,8 @@
<p>Default module is <c>snmpa_mib_storage_ets</c>. </p>
</item>
- <marker id="agent_mst_options"></marker>
- <tag><c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
+ <tag><marker id="agent_mst_options"></marker>
+ <c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
<item>
<p>This is implementattion depended. That is, it depends on the
module. For each module a specific set of options are valid.
@@ -426,16 +428,16 @@
</list>
</item>
- <marker id="agent_mib_server"></marker>
- <tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_server"></marker>
+ <c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()} | {data_module, mib_server_data_module()}</c></p>
<p>Defines options specific for the SNMP agent mib server. </p>
<p>For defaults see the options in <c>mib_server_opt()</c>.</p>
</item>
- <marker id="agent_ms_meo"></marker>
- <tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_meo"></marker>
+ <c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each mib-
entry is checked prior to installation of the mib.
@@ -444,8 +446,8 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_teo"></marker>
- <tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_teo"></marker>
+ <c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each trap
is checked prior to installation of the mib.
@@ -454,11 +456,12 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_data_module"></marker>
<!--
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
-->
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
<item>
<p>Defines the backend data module of the SNMP agent mib-server as
defined by the
@@ -475,24 +478,24 @@
<p>Default module is <c>snmpa_mib_data_tttn</c>. </p>
</item>
- <marker id="agent_ms_cache"></marker>
- <tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache"></marker>
+ <c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
<item>
<p>Shall the agent utilize the mib server lookup cache or not.</p>
<p>Default is <c>true</c> (in which case the <c>mibs_cache_opts()</c>
default values apply).</p>
</item>
- <marker id="agent_ms_cache_opts"></marker>
- <tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_opts"></marker>
+ <c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
<item>
<p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p>
<p>Defines options specific for the SNMP agent mib server cache. </p>
<p>For defaults see the options in <c>mibs_cache_opt()</c>.</p>
</item>
- <marker id="agent_ms_cache_autogc"></marker>
- <tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_autogc"></marker>
+ <c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
<item>
<p>Defines if the mib server shall perform cache gc automatically or
leave it to the user (see
@@ -500,8 +503,8 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ms_cache_age"></marker>
- <tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_age"></marker>
+ <c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
<item>
<p>Defines how old the entries in the cache will be allowed
to become before they are GC'ed (assuming GC is performed).
@@ -510,8 +513,8 @@
<p>Default is <c>10 timutes</c>.</p>
</item>
- <marker id="agent_ms_cache_gclimit"></marker>
- <tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_gclimit"></marker>
+ <c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
<item>
<p>When performing a GC, this is the max number of cache entries
that will be deleted from the cache. </p>
@@ -521,8 +524,8 @@
<p>Default is <c>100</c>.</p>
</item>
- <marker id="agent_error_report_mod"></marker>
- <tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_error_report_mod"></marker>
+ <c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
<item>
<p>Defines an error report module, implementing the
<seealso marker="snmpa_error_report">snmpa_error_report</seealso>
@@ -531,38 +534,38 @@
<p>Default is <c>snmpa_error_logger</c>.</p>
</item>
- <marker id="agent_symbolic_store"></marker>
- <tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag>
+ <tag><marker id="agent_symbolic_store"></marker>
+ <c>symbolic_store() = [symbolic_store_opt()]</c></tag>
<item>
<p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent symbolic store. </p>
<p>For defaults see the options in <c>symbolic_store_opt()</c>.</p>
</item>
- <marker id="agent_target_cache"></marker>
- <tag><c>target_cache() = [target_cache_opt()]</c></tag>
+ <tag><marker id="agent_target_cache"></marker>
+ <c>target_cache() = [target_cache_opt()]</c></tag>
<item>
<p><c>target_cache_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent target cache. </p>
<p>For defaults see the options in <c>target_cache_opt()</c>.</p>
</item>
- <marker id="agent_config"></marker>
- <tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="agent_config"></marker>
+ <c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP agent. </p>
<p>For defaults see the options in <c>agent_config_opt()</c>.</p>
</item>
- <marker id="agent_config_dir"></marker>
- <tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="agent_config_dir"></marker>
+ <c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent configuration files are stored.</p>
</item>
- <marker id="agent_force_load"></marker>
- <tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_force_load"></marker>
+ <c><![CDATA[force_load() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c> the configuration files are re-read
during start-up, and the contents of the configuration
@@ -576,18 +579,18 @@
<marker id="manager_opts_and_types"></marker>
<p>Manager specific config options and types:</p>
<taglist>
- <marker id="manager_server"></marker>
- <tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_server"></marker>
+ <c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
<p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="manager_server_timeout"></marker>
- <tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="manager_server_timeout"></marker>
+ <c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
<item>
- <p>Asynchroneous request cleanup time. For every requests,
+ <p>Asynchronous request cleanup time. For every requests,
some info is stored internally, in order to be able to
deliver the reply (when it arrives) to the proper destination.
If the reply arrives, this info will be deleted. But if
@@ -605,44 +608,44 @@
<p>Default is <c>30000</c>.</p>
</item>
- <marker id="manager_config"></marker>
- <tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="manager_config"></marker>
+ <c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP manager. </p>
<p>For defaults see the options in <c>manager_config_opt()</c>.</p>
</item>
- <marker id="manager_config_dir"></marker>
- <tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_dir"></marker>
+ <c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager configuration files are stored.</p>
</item>
- <marker id="manager_config_db_dir"></marker>
- <tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_db_dir"></marker>
+ <c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager store persistent data.</p>
</item>
- <marker id="manager_config_repair"></marker>
- <tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="manager_config_repair"></marker>
+ <c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>Defines the repair option for the persistent database (if
and how the table is repaired when opened). </p>
<p>Default is <c>true</c>.</p>
</item>
- <marker id="manager_config_auto_save"></marker>
- <tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="manager_config_auto_save"></marker>
+ <c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="manager_irb"></marker>
- <tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
+ <tag><marker id="manager_irb"></marker>
+ <c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
<item>
<p>This option defines how the manager will handle the sending of
response (acknowledgment) to received inform-requests. </p>
@@ -671,16 +674,16 @@
<p>Default is <c>auto</c>.</p>
</item>
- <marker id="manager_mibs"></marker>
- <tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="manager_mibs"></marker>
+ <c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) and defines which MIBs
are initially loaded into the SNMP manager. </p>
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="manager_net_if"></marker>
- <tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_net_if"></marker>
+ <c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_opt() = {module, manager_net_if_module()} |
{verbosity, verbosity()} |
@@ -690,8 +693,8 @@
<p>For defaults see the options in <c>manager_net_if_opt()</c>.</p>
</item>
- <marker id="manager_ni_opts"></marker>
- <tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_opts"></marker>
+ <c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -704,8 +707,8 @@
<p>For defaults see the options in <c>manager_net_if_option()</c>.</p>
</item>
- <marker id="manager_ni_module"></marker>
- <tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_module"></marker>
+ <c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>The module which handles the network interface part for the
SNMP manager. It must implement the
@@ -713,8 +716,8 @@
<p>Default is <c>snmpm_net_if</c>.</p>
</item>
- <marker id="manager_ni_filter_opts"></marker>
- <tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_opts"></marker>
+ <c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p>
<p>These options are actually specific to the used module.
@@ -724,8 +727,8 @@
<c>manager_net_if_filter_option()</c>.</p>
</item>
- <marker id="manager_ni_filter_module"></marker>
- <tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_module"></marker>
+ <c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP manager. Must implement the
@@ -733,16 +736,16 @@
<p>Default is <c>snmpm_net_if_filter</c>.</p>
</item>
- <marker id="manager_def_user_module"></marker>
- <tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_module"></marker>
+ <c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
<item>
<p>The module implementing the default user. See the
<seealso marker="snmpm_user">snmpm_user</seealso> behaviour.</p>
<p>Default is <c>snmpm_user_default</c>.</p>
</item>
- <marker id="manager_def_user_data"></marker>
- <tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_data"></marker>
+ <c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
<item>
<p>Data for the default user. Passed to the user module when
calling the callback functions.</p>
@@ -753,8 +756,8 @@
<marker id="common_types"></marker>
<p>Common config types:</p>
<taglist>
- <marker id="restart_type"></marker>
- <tag><c>restart_type() = permanent | transient | temporary</c></tag>
+ <tag><marker id="restart_type"></marker>
+ <c>restart_type() = permanent | transient | temporary</c></tag>
<item>
<p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso>
documentation for more info.</p>
@@ -762,8 +765,8 @@
for the manager.</p>
</item>
- <marker id="db_init_error"></marker>
- <tag><c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
+ <tag><marker id="db_init_error"></marker>
+ <c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
<item>
<p>Defines what to do if the agent or manager is unable to open an
existing database file. <c>terminate</c> means that the
@@ -775,31 +778,31 @@
<p>Default is <c>terminate</c>.</p>
</item>
- <marker id="prio"></marker>
- <tag><c><![CDATA[priority() = atom() <optional>]]></c></tag>
+ <tag><marker id="prio"></marker>
+ <c><![CDATA[priority() = atom() <optional>]]></c></tag>
<item>
<p>Defines the Erlang priority for all SNMP processes.</p>
<p>Default is <c>normal</c>.</p>
</item>
- <marker id="versions"></marker>
- <tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag>
+ <tag><marker id="versions"></marker>
+ <c><![CDATA[versions() = [version()] <optional>]]></c></tag>
<item>
<p><c>version() = v1 | v2 | v3</c></p>
<p>Which SNMP versions shall be accepted/used.</p>
<p>Default is <c>[v1,v2,v3]</c>.</p>
</item>
- <marker id="verbosity"></marker>
- <tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
+ <tag><marker id="verbosity"></marker>
+ <c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
<item>
<p>Verbosity for a SNMP process. This specifies now much debug info
is printed.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="bind_to"></marker>
- <tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
+ <tag><marker id="bind_to"></marker>
+ <c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if binds to the IP address.
If <c>false</c>, net_if listens on any IP address on the host
@@ -807,8 +810,8 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="no_reuse"></marker>
- <tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
+ <tag><marker id="no_reuse"></marker>
+ <c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if does not specify that the IP
and port address should be reusable. If <c>false</c>,
@@ -816,30 +819,30 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="recbuf"></marker>
- <tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="recbuf"></marker>
+ <c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
<item>
<p>Receive buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="sndbuf"></marker>
- <tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="sndbuf"></marker>
+ <c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
<item>
<p>Send buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="note_store"></marker>
- <tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
+ <tag><marker id="note_store"></marker>
+ <c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
<item>
<p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the start-up verbosity for the SNMP note store.</p>
<p>For defaults see the options in <c>note_store_opt()</c>.</p>
</item>
- <marker id="ns_timeout"></marker>
- <tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="ns_timeout"></marker>
+ <c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Note cleanup time. When storing a note in the note store,
each note is given lifetime. Every <c>timeout</c> the note_store
@@ -849,8 +852,8 @@
</item>
- <marker id="audit_trail_log"></marker>
- <tag><c><![CDATA[audit_trail_log() = [audit_trail_log_opt()] <optional>]]></c></tag>
+ <tag><marker id="audit_trail_log"></marker>
+ <c><![CDATA[audit_trail_log() = [audit_trail_log_opt()] <optional>]]></c></tag>
<item>
<p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p>
<p>If present, this option specifies the options for the
@@ -860,8 +863,8 @@
<p>If not present, audit trail logging is not used.</p>
</item>
- <marker id="atl_type"></marker>
- <tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
+ <tag><marker id="atl_type"></marker>
+ <c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
<item>
<p>Specifies what type of an audit trail log should be used.
The effect of the type is actually different for the the agent
@@ -882,16 +885,16 @@
<p>Default is <c>read_write</c>.</p>
</item>
- <marker id="atl_dir"></marker>
- <tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="atl_dir"></marker>
+ <c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Specifies where the audit trail log should be stored.</p>
<p>If <c>audit_trail_log</c> specifies that logging should take
place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_size"></marker>
- <tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
+ <tag><marker id="atl_size"></marker>
+ <c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
<item>
<p>Specifies the size of the audit
trail log. This parameter is sent to <c>disk_log</c>. </p>
@@ -899,8 +902,8 @@
take place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_repair"></marker>
- <tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
+ <tag><marker id="atl_repair"></marker>
+ <c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
<item>
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
@@ -912,8 +915,8 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="atl_seqno"></marker>
- <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
+ <tag><marker id="atl_seqno"></marker>
+ <c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
<item>
<p>Specifies if the audit trail log entries will be (sequence)
numbered or not. The range of the sequence numbers are according
diff --git a/lib/snmp/doc/src/snmp_app_a.xml b/lib/snmp/doc/src/snmp_app_a.xml
index e2733b0e82..551876ee92 100644
--- a/lib/snmp/doc/src/snmp_app_a.xml
+++ b/lib/snmp/doc/src/snmp_app_a.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_app_b.xml b/lib/snmp/doc/src/snmp_app_b.xml
index f7c70f3e0c..263db2a791 100644
--- a/lib/snmp/doc/src/snmp_app_b.xml
+++ b/lib/snmp/doc/src/snmp_app_b.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_audit_trail_log.xml b/lib/snmp/doc/src/snmp_audit_trail_log.xml
index c8abeabe87..c178a995f4 100644
--- a/lib/snmp/doc/src/snmp_audit_trail_log.xml
+++ b/lib/snmp/doc/src/snmp_audit_trail_log.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_community_mib.xml b/lib/snmp/doc/src/snmp_community_mib.xml
index c5065bc319..571ff7d197 100644
--- a/lib/snmp/doc/src/snmp_community_mib.xml
+++ b/lib/snmp/doc/src/snmp_community_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index 0ec8bb91cf..a085252d90 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -129,16 +130,16 @@
<marker id="agent_opts_and_types"></marker>
<p>Agent specific config options and types:</p>
<taglist>
- <marker id="agent_type"></marker>
- <tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
+ <tag><marker id="agent_type"></marker>
+ <c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
<item>
<p>If <c>master</c>, one master agent is
started. Otherwise, no agents are started. </p>
<p>Default is <c>master</c>.</p>
</item>
- <marker id="agent_disco"></marker>
- <tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_disco"></marker>
+ <c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_discovery_opt() =
{terminating, agent_terminating_discovery_opts()} |
@@ -150,8 +151,8 @@
<p>For defaults see the options in <c>agent_discovery_opt()</c>.</p>
</item>
- <marker id="agent_term_disco_opts"></marker>
- <tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_term_disco_opts"></marker>
+ <c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_terminating_discovery_opt() =
{enable, boolean()} |
@@ -168,8 +169,8 @@
</list>
</item>
- <marker id="agent_orig_disco_opts"></marker>
- <tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_orig_disco_opts"></marker>
+ <c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_originating_discovery_opt() =
{enable, boolean()}</c></p>
@@ -182,38 +183,38 @@
</list>
</item>
- <marker id="agent_mt"></marker>
- <tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_mt"></marker>
+ <c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, the agent is multi-threaded, with one
thread for each get request. </p>
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_data_dir"></marker>
- <tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
+ <tag><marker id="agent_data_dir"></marker>
+ <c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent internal db files are stored.</p>
</item>
- <marker id="agent_gb_max_vbs"></marker>
- <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_gb_max_vbs"></marker>
+ <c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
<item>
<p>Defines the maximum number of varbinds allowed
in a Get-BULK response.</p>
<p>Default is <c>1000</c>.</p>
</item>
- <marker id="agent_local_db"></marker>
- <tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_local_db"></marker>
+ <c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
<item>
<p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent local database.</p>
<p>For defaults see the options in <c>local_db_opt()</c>.</p>
</item>
- <marker id="agent_ldb_repair"></marker>
- <tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_repair"></marker>
+ <c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>When starting snmpa_local_db it always tries to open an
existing database. If <c>false</c>, and some errors occur, a new
@@ -223,16 +224,16 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ldb_auto_save"></marker>
- <tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_auto_save"></marker>
+ <c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="agent_net_if"></marker>
- <tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_net_if"></marker>
+ <c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {module, agent_net_if_module()} |
{verbosity, verbosity()} |
@@ -242,8 +243,8 @@
<p>For defaults see the options in <c>agent_net_if_opt()</c>.</p>
</item>
- <marker id="agent_ni_module"></marker>
- <tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_module"></marker>
+ <c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
SNMP agent. Must implement the
@@ -251,8 +252,8 @@
<p>Default is <c>snmpa_net_if</c>.</p>
</item>
- <marker id="agent_ni_opts"></marker>
- <tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_opts"></marker>
+ <c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -266,15 +267,15 @@
<p>For defaults see the options in <c>agent_net_if_option()</c>.</p>
</item>
- <marker id="agent_ni_req_limit"></marker>
- <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ni_req_limit"></marker>
+ <c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
<item>
<p>Max number of simultaneous requests handled by the agent.</p>
<p>Default is <c>infinity</c>.</p>
</item>
- <marker id="agent_ni_filter_opts"></marker>
- <tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_opts"></marker>
+ <c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c><![CDATA[agent_net_if_filter_option() = {module, agent_net_if_filter_module()}]]></c></p>
<p>These options are actually specific to the used module.
@@ -283,8 +284,8 @@
<p>For defaults see the options in <c>agent_net_if_filter_option()</c>.</p>
</item>
- <marker id="agent_ni_filter_module"></marker>
- <tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_module"></marker>
+ <c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP agent. Must implement the
@@ -293,8 +294,8 @@
<p>Default is <c>snmpa_net_if_filter</c>.</p>
</item>
- <marker id="agent_mibs"></marker>
- <tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="agent_mibs"></marker>
+ <c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) that defines which MIBs
are initially loaded into the SNMP master agent. </p>
@@ -308,8 +309,8 @@
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="agent_mib_storage"></marker>
- <tag><c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_storage"></marker>
+ <c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_storage_opt() = {module, mib_storage_module()} | {options, mib_storage_options()}</c></p>
<p>This option specifies how basic mib data is stored.
@@ -318,8 +319,8 @@
<p>Default is <c>[{module, snmpa_mib_storage_ets}]</c>. </p>
</item>
- <marker id="agent_mst_module"></marker>
- <tag><c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
+ <tag><marker id="agent_mst_module"></marker>
+ <c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
<item>
<p>Defines the mib storage module of the SNMP agent as defined by the
<seealso marker="snmpa_mib_storage">snmpa_mib_storage</seealso>
@@ -333,8 +334,8 @@
<p>Default module is <c>snmpa_mib_storage_ets</c>. </p>
</item>
- <marker id="agent_mst_options"></marker>
- <tag><c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
+ <tag><marker id="agent_mst_options"></marker>
+ <c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
<item>
<p>This is implementattion depended. That is, it depends on the
module. For each module a specific set of options are valid.
@@ -428,8 +429,8 @@
This is the old format which is "supported", but not documented,
in so far as it will be converted to the new format if found.
- <marker id="agent_mib_storage"></marker>
- <tag><c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag>
+ <tag><marker id="agent_mib_storage"></marker>
+ <c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag>
<item>
<p>Specifies how info retrieved from the mibs will be stored.</p>
<p>If <c>mib_storage</c> is <c>{ets, Dir}</c>, the table will also be
@@ -455,16 +456,16 @@ in so far as it will be converted to the new format if found.
</item>
-->
- <marker id="agent_mib_server"></marker>
- <tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_server"></marker>
+ <c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()} | {data_module, mib_server_data_module()}</c></p>
<p>Defines options specific for the SNMP agent mib server. </p>
<p>For defaults see the options in <c>mib_server_opt()</c>.</p>
</item>
- <marker id="agent_ms_meo"></marker>
- <tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_meo"></marker>
+ <c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each mib-
entry is checked prior to installation of the mib.
@@ -473,8 +474,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_teo"></marker>
- <tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_teo"></marker>
+ <c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each trap
is checked prior to installation of the mib.
@@ -483,11 +484,13 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_data_module"></marker>
+
<!--
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
-->
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
<item>
<p>Defines the backend data module of the SNMP agent mib-server as
defined by the
@@ -504,24 +507,24 @@ in so far as it will be converted to the new format if found.
<p>Default module is <c>snmpa_mib_data_tttn</c>. </p>
</item>
- <marker id="agent_ms_cache"></marker>
- <tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache"></marker>
+ <c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
<item>
<p>Shall the agent utilize the mib server lookup cache or not.</p>
<p>Default is <c>true</c> (in which case the <c>mibs_cache_opts()</c>
default values apply).</p>
</item>
- <marker id="agent_ms_cache_opts"></marker>
- <tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_opts"></marker>
+ <c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
<item>
<p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p>
<p>Defines options specific for the SNMP agent mib server cache. </p>
<p>For defaults see the options in <c>mibs_cache_opt()</c>.</p>
</item>
- <marker id="agent_ms_cache_autogc"></marker>
- <tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_autogc"></marker>
+ <c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
<item>
<p>Defines if the mib server shall perform cache gc automatically or
leave it to the user (see
@@ -529,8 +532,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ms_cache_age"></marker>
- <tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_age"></marker>
+ <c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
<item>
<p>Defines how old the entries in the cache will be allowed
to become before they are GC'ed (assuming GC is performed).
@@ -539,8 +542,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>10 timutes</c>.</p>
</item>
- <marker id="agent_ms_cache_gclimit"></marker>
- <tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_gclimit"></marker>
+ <c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
<item>
<p>When performing a GC, this is the max number of cache entries
that will be deleted from the cache. </p>
@@ -550,8 +553,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>100</c>.</p>
</item>
- <marker id="agent_error_report_mod"></marker>
- <tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_error_report_mod"></marker>
+ <c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
<item>
<p>Defines an error report module, implementing the
<seealso marker="snmpa_error_report">snmpa_error_report</seealso>
@@ -560,38 +563,38 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>snmpa_error_logger</c>.</p>
</item>
- <marker id="agent_symbolic_store"></marker>
- <tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag>
+ <tag><marker id="agent_symbolic_store"></marker>
+ <c>symbolic_store() = [symbolic_store_opt()]</c></tag>
<item>
<p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent symbolic store. </p>
<p>For defaults see the options in <c>symbolic_store_opt()</c>.</p>
</item>
- <marker id="agent_target_cache"></marker>
- <tag><c>target_cache() = [target_cache_opt()]</c></tag>
+ <tag><marker id="agent_target_cache"></marker>
+ <c>target_cache() = [target_cache_opt()]</c></tag>
<item>
<p><c>target_cache_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent target cache. </p>
<p>For defaults see the options in <c>target_cache_opt()</c>.</p>
</item>
- <marker id="agent_config"></marker>
- <tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="agent_config"></marker>
+ <c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP agent. </p>
<p>For defaults see the options in <c>agent_config_opt()</c>.</p>
</item>
- <marker id="agent_config_dir"></marker>
- <tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="agent_config_dir"></marker>
+ <c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent configuration files are stored.</p>
</item>
- <marker id="agent_force_load"></marker>
- <tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_force_load"></marker>
+ <c><![CDATA[force_load() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c> the configuration files are re-read
during start-up, and the contents of the configuration
@@ -605,18 +608,18 @@ in so far as it will be converted to the new format if found.
<marker id="manager_opts_and_types"></marker>
<p>Manager specific config options and types:</p>
<taglist>
- <marker id="manager_server"></marker>
- <tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_server"></marker>
+ <c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
<p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="manager_server_timeout"></marker>
- <tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="manager_server_timeout"></marker>
+ <c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
<item>
- <p>Asynchroneous request cleanup time. For every requests,
+ <p>Asynchronous request cleanup time. For every requests,
some info is stored internally, in order to be able to
deliver the reply (when it arrives) to the proper destination.
If the reply arrives, this info will be deleted. But if
@@ -634,44 +637,44 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>30000</c>.</p>
</item>
- <marker id="manager_config"></marker>
- <tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="manager_config"></marker>
+ <c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP manager. </p>
<p>For defaults see the options in <c>manager_config_opt()</c>.</p>
</item>
- <marker id="manager_config_dir"></marker>
- <tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_dir"></marker>
+ <c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager configuration files are stored.</p>
</item>
- <marker id="manager_config_db_dir"></marker>
- <tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_db_dir"></marker>
+ <c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager store persistent data.</p>
</item>
- <marker id="manager_config_repair"></marker>
- <tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="manager_config_repair"></marker>
+ <c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>Defines the repair option for the persistent database (if
and how the table is repaired when opened). </p>
<p>Default is <c>true</c>.</p>
</item>
- <marker id="manager_config_auto_save"></marker>
- <tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="manager_config_auto_save"></marker>
+ <c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="manager_irb"></marker>
- <tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
+ <tag><marker id="manager_irb"></marker>
+ <c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
<item>
<p>This option defines how the manager will handle the sending of
response (acknowledgment) to received inform-requests. </p>
@@ -700,16 +703,16 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>auto</c>.</p>
</item>
- <marker id="manager_mibs"></marker>
- <tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="manager_mibs"></marker>
+ <c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) and defines which MIBs
are initially loaded into the SNMP manager. </p>
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="manager_net_if"></marker>
- <tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_net_if"></marker>
+ <c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_opt() = {module, manager_net_if_module()} |
{verbosity, verbosity()} |
@@ -719,8 +722,8 @@ in so far as it will be converted to the new format if found.
<p>For defaults see the options in <c>manager_net_if_opt()</c>.</p>
</item>
- <marker id="manager_ni_opts"></marker>
- <tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_opts"></marker>
+ <c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -733,8 +736,8 @@ in so far as it will be converted to the new format if found.
<p>For defaults see the options in <c>manager_net_if_option()</c>.</p>
</item>
- <marker id="manager_ni_module"></marker>
- <tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_module"></marker>
+ <c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>The module which handles the network interface part for the
SNMP manager. It must implement the
@@ -742,8 +745,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>snmpm_net_if</c>. </p>
</item>
- <marker id="manager_ni_filter_opts"></marker>
- <tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_opts"></marker>
+ <c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p>
<p>These options are actually specific to the used module.
@@ -753,8 +756,8 @@ in so far as it will be converted to the new format if found.
<c>manager_net_if_filter_option()</c>.</p>
</item>
- <marker id="manager_ni_filter_module"></marker>
- <tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_module"></marker>
+ <c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP manager. Must implement the
@@ -762,16 +765,16 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>snmpm_net_if_filter</c>.</p>
</item>
- <marker id="manager_def_user_module"></marker>
- <tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_module"></marker>
+ <c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
<item>
<p>The module implementing the default user. See the
<seealso marker="snmpm_user">snmpm_user</seealso> behaviour.</p>
<p>Default is <c>snmpm_user_default</c>.</p>
</item>
- <marker id="manager_def_user_data"></marker>
- <tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_data"></marker>
+ <c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
<item>
<p>Data for the default user. Passed to the user when calling
the callback functions.</p>
@@ -782,8 +785,8 @@ in so far as it will be converted to the new format if found.
<marker id="common_types"></marker>
<p>Common config types:</p>
<taglist>
- <marker id="restart_type"></marker>
- <tag><c>restart_type() = permanent | transient | temporary</c></tag>
+ <tag><marker id="restart_type"></marker>
+ <c>restart_type() = permanent | transient | temporary</c></tag>
<item>
<p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso>
documentation for more info.</p>
@@ -791,8 +794,8 @@ in so far as it will be converted to the new format if found.
for the manager.</p>
</item>
- <marker id="db_init_error"></marker>
- <tag><c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
+ <tag><marker id="db_init_error"></marker>
+ <c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
<item>
<p>Defines what to do if the agent is unable to open an
existing database file. <c>terminate</c> means that the
@@ -804,31 +807,31 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>terminate</c>.</p>
</item>
- <marker id="prio"></marker>
- <tag><c><![CDATA[priority() = atom() <optional>]]></c></tag>
+ <tag><marker id="prio"></marker>
+ <c><![CDATA[priority() = atom() <optional>]]></c></tag>
<item>
<p>Defines the Erlang priority for all SNMP processes.</p>
<p>Default is <c>normal</c>.</p>
</item>
- <marker id="versions"></marker>
- <tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag>
+ <tag><marker id="versions"></marker>
+ <c><![CDATA[versions() = [version()] <optional>]]></c></tag>
<item>
<p><c>version() = v1 | v2 | v3</c></p>
<p>Which SNMP versions shall be accepted/used.</p>
<p>Default is <c>[v1,v2,v3]</c>.</p>
</item>
- <marker id="verbosity"></marker>
- <tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
+ <tag><marker id="verbosity"></marker>
+ <c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
<item>
<p>Verbosity for a SNMP process. This specifies now much debug info
is printed.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="bind_to"></marker>
- <tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
+ <tag><marker id="bind_to"></marker>
+ <c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if binds to the IP address.
If <c>false</c>, net_if listens on any IP address on the host
@@ -836,8 +839,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="no_reuse"></marker>
- <tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
+ <tag><marker id="no_reuse"></marker>
+ <c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if does not specify that the IP
and port address should be reusable. If <c>false</c>,
@@ -845,30 +848,30 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="recbuf"></marker>
- <tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="recbuf"></marker>
+ <c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
<item>
<p>Receive buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="sndbuf"></marker>
- <tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="sndbuf"></marker>
+ <c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
<item>
<p>Send buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="note_store"></marker>
- <tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
+ <tag><marker id="note_store"></marker>
+ <c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
<item>
<p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the SNMP note store.</p>
<p>For defaults see the options in <c>note_store_opt()</c>.</p>
</item>
- <marker id="ns_timeout"></marker>
- <tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="ns_timeout"></marker>
+ <c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Note cleanup time. When storing a note in the note store,
each note is given lifetime. Every <c>timeout</c> the note_store
@@ -877,8 +880,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>30000</c>.</p>
</item>
- <marker id="audit_trail_log"></marker>
- <tag><c><![CDATA[audit_trail_log() [audit_trail_log_opt()] <optional>]]></c></tag>
+ <tag><marker id="audit_trail_log"></marker>
+ <c><![CDATA[audit_trail_log() [audit_trail_log_opt()] <optional>]]></c></tag>
<item>
<p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p>
<p>If present, this option specifies the options for the
@@ -888,8 +891,8 @@ in so far as it will be converted to the new format if found.
<p>If not present, audit trail logging is not used.</p>
</item>
- <marker id="atl_type"></marker>
- <tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
+ <tag><marker id="atl_type"></marker>
+ <c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
<item>
<p>Specifies what type of an audit trail log should be used.
The effect of the type is actually different for the the agent
@@ -910,16 +913,16 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>read_write</c>.</p>
</item>
- <marker id="atl_dir"></marker>
- <tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="atl_dir"></marker>
+ <c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Specifies where the audit trail log should be stored.</p>
<p>If <c>audit_trail_log</c> specifies that logging should take
place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_size"></marker>
- <tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
+ <tag><marker id="atl_size"></marker>
+ <c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
<item>
<p>Specifies the size of the audit
trail log. This parameter is sent to <c>disk_log</c>. </p>
@@ -927,8 +930,8 @@ in so far as it will be converted to the new format if found.
take place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_repair"></marker>
- <tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
+ <tag><marker id="atl_repair"></marker>
+ <c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
<item>
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
@@ -940,8 +943,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>true</c>.</p>
</item>
- <marker id="atl_seqno"></marker>
- <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
+ <tag><marker id="atl_seqno"></marker>
+ <c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
<item>
<p>Specifies if the audit trail log entries will be (sequence)
numbered or not. The range of the sequence numbers are according
diff --git a/lib/snmp/doc/src/snmp_def_instr_functions.xml b/lib/snmp/doc/src/snmp_def_instr_functions.xml
index 20d2180c2d..2317f27196 100644
--- a/lib/snmp/doc/src/snmp_def_instr_functions.xml
+++ b/lib/snmp/doc/src/snmp_def_instr_functions.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_framework_mib.xml b/lib/snmp/doc/src/snmp_framework_mib.xml
index 3b4eb52ec2..9fba76baab 100644
--- a/lib/snmp/doc/src/snmp_framework_mib.xml
+++ b/lib/snmp/doc/src/snmp_framework_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_generic.xml b/lib/snmp/doc/src/snmp_generic.xml
index d4c65ba832..75271fb002 100644
--- a/lib/snmp/doc/src/snmp_generic.xml
+++ b/lib/snmp/doc/src/snmp_generic.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_impl_example_agent.xml b/lib/snmp/doc/src/snmp_impl_example_agent.xml
index 1260d7d432..912f339e0d 100644
--- a/lib/snmp/doc/src/snmp_impl_example_agent.xml
+++ b/lib/snmp/doc/src/snmp_impl_example_agent.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_impl_example_manager.xml b/lib/snmp/doc/src/snmp_impl_example_manager.xml
index 03ea54b1bf..789c6c169e 100644
--- a/lib/snmp/doc/src/snmp_impl_example_manager.xml
+++ b/lib/snmp/doc/src/snmp_impl_example_manager.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_index.xml b/lib/snmp/doc/src/snmp_index.xml
index 5d333e2fec..74792629b6 100644
--- a/lib/snmp/doc/src/snmp_index.xml
+++ b/lib/snmp/doc/src/snmp_index.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_instr_functions.xml b/lib/snmp/doc/src/snmp_instr_functions.xml
index dcfaf145d3..0dc76d3603 100644
--- a/lib/snmp/doc/src/snmp_instr_functions.xml
+++ b/lib/snmp/doc/src/snmp_instr_functions.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_intro.xml b/lib/snmp/doc/src/snmp_intro.xml
index 663e269e4b..691bc162ee 100644
--- a/lib/snmp/doc/src/snmp_intro.xml
+++ b/lib/snmp/doc/src/snmp_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_manager_config_files.xml b/lib/snmp/doc/src/snmp_manager_config_files.xml
index d8bd4b0f3a..ca7bc3bfb3 100644
--- a/lib/snmp/doc/src/snmp_manager_config_files.xml
+++ b/lib/snmp/doc/src/snmp_manager_config_files.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_manager_funct_descr.xml b/lib/snmp/doc/src/snmp_manager_funct_descr.xml
index 65a2ec069d..30df618eb6 100644
--- a/lib/snmp/doc/src/snmp_manager_funct_descr.xml
+++ b/lib/snmp/doc/src/snmp_manager_funct_descr.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_manager_netif.xml b/lib/snmp/doc/src/snmp_manager_netif.xml
index 97cedf00c0..98d4e7fd96 100644
--- a/lib/snmp/doc/src/snmp_manager_netif.xml
+++ b/lib/snmp/doc/src/snmp_manager_netif.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -74,8 +75,7 @@
<p>In this section a <c>Domain</c> field is the transport domain i.e
one of <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv6</c>,
and an <c>Addr</c> field is an
- <c>{<seealso marker="kernel:inet#type-ip_address">IpAddr</seealso>,
- IpPort}</c> tuple.</p>
+ <c>{</c><seealso marker="kernel:inet#type-ip_address"><c>IpAddr</c></seealso><c>,IpPort}</c> tuple.</p>
<p>Net if must send the following message when it receives an
SNMP PDU from the network that is aimed for the MasterAgent:
diff --git a/lib/snmp/doc/src/snmp_mib_compiler.xml b/lib/snmp/doc/src/snmp_mib_compiler.xml
index db0d7a344e..ad93cc86c4 100644
--- a/lib/snmp/doc/src/snmp_mib_compiler.xml
+++ b/lib/snmp/doc/src/snmp_mib_compiler.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_notification_mib.xml b/lib/snmp/doc/src/snmp_notification_mib.xml
index 963fffe98c..cbb117d71a 100644
--- a/lib/snmp/doc/src/snmp_notification_mib.xml
+++ b/lib/snmp/doc/src/snmp_notification_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_pdus.xml b/lib/snmp/doc/src/snmp_pdus.xml
index 2051ab291b..82900c2f59 100644
--- a/lib/snmp/doc/src/snmp_pdus.xml
+++ b/lib/snmp/doc/src/snmp_pdus.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_standard_mib.xml b/lib/snmp/doc/src/snmp_standard_mib.xml
index 7c9bfdb6fe..bc3abf5fa8 100644
--- a/lib/snmp/doc/src/snmp_standard_mib.xml
+++ b/lib/snmp/doc/src/snmp_standard_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_target_mib.xml b/lib/snmp/doc/src/snmp_target_mib.xml
index a076ff2d8e..fa85d586b9 100644
--- a/lib/snmp/doc/src/snmp_target_mib.xml
+++ b/lib/snmp/doc/src/snmp_target_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_user_based_sm_mib.xml b/lib/snmp/doc/src/snmp_user_based_sm_mib.xml
index e4eec88c57..ffff1b6b4f 100644
--- a/lib/snmp/doc/src/snmp_user_based_sm_mib.xml
+++ b/lib/snmp/doc/src/snmp_user_based_sm_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmp_view_based_acm_mib.xml b/lib/snmp/doc/src/snmp_view_based_acm_mib.xml
index 0e6e7144b4..bdd669b8b2 100644
--- a/lib/snmp/doc/src/snmp_view_based_acm_mib.xml
+++ b/lib/snmp/doc/src/snmp_view_based_acm_mib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml
index d484a6b7cf..c84eeec524 100644
--- a/lib/snmp/doc/src/snmpa.xml
+++ b/lib/snmp/doc/src/snmpa.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -621,12 +622,12 @@ notification_delivery_info() = #snmpa_notification_delivery_info{}
<p>Converts an Audit Trail Log to a readable format and
prints it on stdio.
<c>LogName</c> defaults to "snmpa_log".
- <c>LogFile</c> defaults to "snmpa.log".
+ <c>LogFile</c> defaults to "snmpa.log".</p>
<p>The <c>Block</c> option indicates if the log should be blocked
during conversion. This could be usefull when converting large
logs (when otherwise the log could wrap during conversion).
Defaults to <c>true</c>. </p>
- See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
+ <p>See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
for more info.</p>
<marker id="change_log_size"></marker>
diff --git a/lib/snmp/doc/src/snmpa_conf.xml b/lib/snmp/doc/src/snmpa_conf.xml
index 2780cec156..2f9579261a 100644
--- a/lib/snmp/doc/src/snmpa_conf.xml
+++ b/lib/snmp/doc/src/snmpa_conf.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_discovery_handler.xml b/lib/snmp/doc/src/snmpa_discovery_handler.xml
index 309a21ec32..ccc69112c1 100644
--- a/lib/snmp/doc/src/snmpa_discovery_handler.xml
+++ b/lib/snmp/doc/src/snmpa_discovery_handler.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_error.xml b/lib/snmp/doc/src/snmpa_error.xml
index 2cc44a9e79..cfebb36ed3 100644
--- a/lib/snmp/doc/src/snmpa_error.xml
+++ b/lib/snmp/doc/src/snmpa_error.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_error_io.xml b/lib/snmp/doc/src/snmpa_error_io.xml
index fc90db4bf9..908dcc974d 100644
--- a/lib/snmp/doc/src/snmpa_error_io.xml
+++ b/lib/snmp/doc/src/snmpa_error_io.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_error_logger.xml b/lib/snmp/doc/src/snmpa_error_logger.xml
index b2bf1c4181..c39e07ed5f 100644
--- a/lib/snmp/doc/src/snmpa_error_logger.xml
+++ b/lib/snmp/doc/src/snmpa_error_logger.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_error_report.xml b/lib/snmp/doc/src/snmpa_error_report.xml
index f58287da08..5c91df9e57 100644
--- a/lib/snmp/doc/src/snmpa_error_report.xml
+++ b/lib/snmp/doc/src/snmpa_error_report.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_local_db.xml b/lib/snmp/doc/src/snmpa_local_db.xml
index e617aa0893..feca939124 100644
--- a/lib/snmp/doc/src/snmpa_local_db.xml
+++ b/lib/snmp/doc/src/snmpa_local_db.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_mib_data.xml b/lib/snmp/doc/src/snmpa_mib_data.xml
index 95a33e603e..1ef71d5cbe 100644
--- a/lib/snmp/doc/src/snmpa_mib_data.xml
+++ b/lib/snmp/doc/src/snmpa_mib_data.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_mib_storage.xml b/lib/snmp/doc/src/snmpa_mib_storage.xml
index 791fbc80fe..a4ce5891d2 100644
--- a/lib/snmp/doc/src/snmpa_mib_storage.xml
+++ b/lib/snmp/doc/src/snmpa_mib_storage.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_mpd.xml b/lib/snmp/doc/src/snmpa_mpd.xml
index 518100d30c..4c2f12020b 100644
--- a/lib/snmp/doc/src/snmpa_mpd.xml
+++ b/lib/snmp/doc/src/snmpa_mpd.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_network_interface.xml b/lib/snmp/doc/src/snmpa_network_interface.xml
index 5fc51b1e53..ffa006768d 100644
--- a/lib/snmp/doc/src/snmpa_network_interface.xml
+++ b/lib/snmp/doc/src/snmpa_network_interface.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_network_interface_filter.xml b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
index eb640e1bc3..0c26914c91 100644
--- a/lib/snmp/doc/src/snmpa_network_interface_filter.xml
+++ b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml b/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml
index 814f02a14c..da0328402b 100644
--- a/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml
+++ b/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_notification_filter.xml b/lib/snmp/doc/src/snmpa_notification_filter.xml
index accce286bd..b2c9a0912e 100644
--- a/lib/snmp/doc/src/snmpa_notification_filter.xml
+++ b/lib/snmp/doc/src/snmpa_notification_filter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpa_supervisor.xml b/lib/snmp/doc/src/snmpa_supervisor.xml
index 8fc178b97b..d272118b04 100644
--- a/lib/snmp/doc/src/snmpa_supervisor.xml
+++ b/lib/snmp/doc/src/snmpa_supervisor.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml
index 8eb490d391..fb526ee4dc 100644
--- a/lib/snmp/doc/src/snmpc.xml
+++ b/lib/snmp/doc/src/snmpc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpc_cmd.xml b/lib/snmp/doc/src/snmpc_cmd.xml
index e14b9f8e25..2c906a2a51 100644
--- a/lib/snmp/doc/src/snmpc_cmd.xml
+++ b/lib/snmp/doc/src/snmpc_cmd.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index ff90e49968..ab288fd020 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -1240,12 +1241,12 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<p>Converts an Audit Trail Log to a readable text file.
<c>OutFile</c> defaults to "./snmpm_log.txt".
<c>LogName</c> defaults to "snmpm_log".
- <c>LogFile</c> defaults to "snmpm.log".
+ <c>LogFile</c> defaults to "snmpm.log".</p>
<p>The <c>Block</c> argument indicates if the log should be blocked
during conversion. This could be usefull when converting large
logs (when otherwise the log could wrap during conversion).
Defaults to <c>true</c>. </p>
- See <seealso marker="snmp#log_to_txt">snmp:log_to_txt</seealso>
+ <p>See <seealso marker="snmp#log_to_txt">snmp:log_to_txt</seealso>
for more info.</p>
<marker id="log_to_io"></marker>
@@ -1279,12 +1280,12 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<p>Converts an Audit Trail Log to a readable format and
prints it on stdio.
<c>LogName</c> defaults to "snmpm_log".
- <c>LogFile</c> defaults to "snmpm.log".
+ <c>LogFile</c> defaults to "snmpm.log".</p>
<p>The <c>Block</c> argument indicates if the log should be blocked
during conversion. This could be usefull when converting large
logs (when otherwise the log could wrap during conversion).
Defaults to <c>true</c>. </p>
- See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
+ <p>See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
for more info.</p>
<marker id="change_log_size"></marker>
diff --git a/lib/snmp/doc/src/snmpm_conf.xml b/lib/snmp/doc/src/snmpm_conf.xml
index 8635fb705b..815ad2e87a 100644
--- a/lib/snmp/doc/src/snmpm_conf.xml
+++ b/lib/snmp/doc/src/snmpm_conf.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpm_mpd.xml b/lib/snmp/doc/src/snmpm_mpd.xml
index c23b2b6833..4efaafd578 100644
--- a/lib/snmp/doc/src/snmpm_mpd.xml
+++ b/lib/snmp/doc/src/snmpm_mpd.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpm_network_interface.xml b/lib/snmp/doc/src/snmpm_network_interface.xml
index bea6b46dc7..6b4598ed88 100644
--- a/lib/snmp/doc/src/snmpm_network_interface.xml
+++ b/lib/snmp/doc/src/snmpm_network_interface.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpm_network_interface_filter.xml b/lib/snmp/doc/src/snmpm_network_interface_filter.xml
index 1ef4f29c0f..2706f6df09 100644
--- a/lib/snmp/doc/src/snmpm_network_interface_filter.xml
+++ b/lib/snmp/doc/src/snmpm_network_interface_filter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/doc/src/snmpm_user.xml b/lib/snmp/doc/src/snmpm_user.xml
index a4492839cd..cb2ecb0c58 100644
--- a/lib/snmp/doc/src/snmpm_user.xml
+++ b/lib/snmp/doc/src/snmpm_user.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/snmp/examples/Makefile b/lib/snmp/examples/Makefile
index 341107ce30..854a6e6f8d 100644
--- a/lib/snmp/examples/Makefile
+++ b/lib/snmp/examples/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/examples/ex1/Makefile b/lib/snmp/examples/ex1/Makefile
index 8d10476b30..2631fdd7ff 100644
--- a/lib/snmp/examples/ex1/Makefile
+++ b/lib/snmp/examples/ex1/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/examples/ex1/ex1.erl b/lib/snmp/examples/ex1/ex1.erl
index 3618cd3b8c..c525ae4d6a 100644
--- a/lib/snmp/examples/ex1/ex1.erl
+++ b/lib/snmp/examples/ex1/ex1.erl
@@ -3,16 +3,17 @@
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
%%</legalnotice>
diff --git a/lib/snmp/examples/ex2/Makefile b/lib/snmp/examples/ex2/Makefile
index a85ff8e4e2..9259a59c46 100644
--- a/lib/snmp/examples/ex2/Makefile
+++ b/lib/snmp/examples/ex2/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/examples/ex2/snmp_ex2_manager.erl b/lib/snmp/examples/ex2/snmp_ex2_manager.erl
index a9dcc09b77..38189fa518 100644
--- a/lib/snmp/examples/ex2/snmp_ex2_manager.erl
+++ b/lib/snmp/examples/ex2/snmp_ex2_manager.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl b/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl
index 81939dd614..fecf817fa0 100644
--- a/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl
+++ b/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/examples/subdirs.mk b/lib/snmp/examples/subdirs.mk
index 9f4b69951e..62cba219cd 100644
--- a/lib/snmp/examples/subdirs.mk
+++ b/lib/snmp/examples/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/include/SNMPv2-TC.hrl b/lib/snmp/include/SNMPv2-TC.hrl
index 231be39220..54ead21a35 100644
--- a/lib/snmp/include/SNMPv2-TC.hrl
+++ b/lib/snmp/include/SNMPv2-TC.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/include/snmp_tables.hrl b/lib/snmp/include/snmp_tables.hrl
index 4eea5ec282..888539a282 100644
--- a/lib/snmp/include/snmp_tables.hrl
+++ b/lib/snmp/include/snmp_tables.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/include/snmp_types.hrl b/lib/snmp/include/snmp_types.hrl
index 399379a49b..0a7379c790 100644
--- a/lib/snmp/include/snmp_types.hrl
+++ b/lib/snmp/include/snmp_types.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/mibs/Makefile.in b/lib/snmp/mibs/Makefile.in
index e7ca540cc6..eea0d4aa63 100644
--- a/lib/snmp/mibs/Makefile.in
+++ b/lib/snmp/mibs/Makefile.in
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/priv/conf/Makefile b/lib/snmp/priv/conf/Makefile
index 341107ce30..854a6e6f8d 100644
--- a/lib/snmp/priv/conf/Makefile
+++ b/lib/snmp/priv/conf/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/priv/conf/agent/Makefile b/lib/snmp/priv/conf/agent/Makefile
index 3082889dc8..5e9b922d04 100644
--- a/lib/snmp/priv/conf/agent/Makefile
+++ b/lib/snmp/priv/conf/agent/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/priv/conf/agent/files.mk b/lib/snmp/priv/conf/agent/files.mk
index 2f81515af9..8e6c80f3a2 100644
--- a/lib/snmp/priv/conf/agent/files.mk
+++ b/lib/snmp/priv/conf/agent/files.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/priv/conf/manager/Makefile b/lib/snmp/priv/conf/manager/Makefile
index a04c227754..b88ed0a11c 100644
--- a/lib/snmp/priv/conf/manager/Makefile
+++ b/lib/snmp/priv/conf/manager/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/priv/conf/manager/files.mk b/lib/snmp/priv/conf/manager/files.mk
index 61dde77d93..9ead147aff 100644
--- a/lib/snmp/priv/conf/manager/files.mk
+++ b/lib/snmp/priv/conf/manager/files.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/priv/conf/subdirs.mk b/lib/snmp/priv/conf/subdirs.mk
index b3e159b0e4..7d8d40887f 100644
--- a/lib/snmp/priv/conf/subdirs.mk
+++ b/lib/snmp/priv/conf/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/Makefile b/lib/snmp/src/Makefile
index 341107ce30..854a6e6f8d 100644
--- a/lib/snmp/src/Makefile
+++ b/lib/snmp/src/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/agent/Makefile b/lib/snmp/src/agent/Makefile
index beed696648..89037b3ea8 100644
--- a/lib/snmp/src/agent/Makefile
+++ b/lib/snmp/src/agent/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/agent/depend.mk b/lib/snmp/src/agent/depend.mk
index b4ca8a2d9f..e9964f5151 100644
--- a/lib/snmp/src/agent/depend.mk
+++ b/lib/snmp/src/agent/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/agent/modules.mk b/lib/snmp/src/agent/modules.mk
index 34765475b9..b2f1d5cc93 100644
--- a/lib/snmp/src/agent/modules.mk
+++ b/lib/snmp/src/agent/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index 4546c343b7..dbd9f468d7 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index 6ff9224d34..80ebba6c90 100644
--- a/lib/snmp/src/agent/snmp_framework_mib.erl
+++ b/lib/snmp/src/agent/snmp_framework_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl
index 3195ca2500..ec6b7161ea 100644
--- a/lib/snmp/src/agent/snmp_generic.erl
+++ b/lib/snmp/src/agent/snmp_generic.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmp_generic_mnesia.erl b/lib/snmp/src/agent/snmp_generic_mnesia.erl
index 7fd6501977..051566e43d 100644
--- a/lib/snmp/src/agent/snmp_generic_mnesia.erl
+++ b/lib/snmp/src/agent/snmp_generic_mnesia.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmp_index.erl b/lib/snmp/src/agent/snmp_index.erl
index 1902fe2613..5e03c530f1 100644
--- a/lib/snmp/src/agent/snmp_index.erl
+++ b/lib/snmp/src/agent/snmp_index.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl
index 31c7735226..15ecbcc5d9 100644
--- a/lib/snmp/src/agent/snmp_notification_mib.erl
+++ b/lib/snmp/src/agent/snmp_notification_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmp_shadow_table.erl b/lib/snmp/src/agent/snmp_shadow_table.erl
index 34543d542b..f9181f70a7 100644
--- a/lib/snmp/src/agent/snmp_shadow_table.erl
+++ b/lib/snmp/src/agent/snmp_shadow_table.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -76,7 +77,7 @@ delete_time_stamp_table() ->
end.
update(Name, UpdateFunc, Interval) ->
- CurrentTime = get_time(),
+ CurrentTime = snmp_misc:now(ms),
case mnesia:dirty_read({time_stamp, Name}) of
[#time_stamp{data = Expire}] when CurrentTime =< Expire -> ok;
_ ->
@@ -117,9 +118,6 @@ table_func(Op, RowIndex, Cols,
update(Name, UpdateFunc, Interval),
snmp_generic:table_func(Op, RowIndex, Cols, {Name, mnesia}).
-get_time() ->
- {M,S,U} = erlang:now(),
- 1000000000 * M + 1000 * S + (U div 1000).
%%-----------------------------------------------------------------
%% Urrk.
@@ -183,5 +181,3 @@ delete_table(Tab) ->
error_msg(F, A) ->
?snmpa_error(F, A).
-
-
diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl
index aace3fd413..bfe471178d 100644
--- a/lib/snmp/src/agent/snmp_standard_mib.erl
+++ b/lib/snmp/src/agent/snmp_standard_mib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -546,8 +547,9 @@ dummy(_Op) -> ok.
%%-----------------------------------------------------------------
snmp_set_serial_no(new) ->
snmp_generic:variable_func(new, {snmpSetSerialNo, volatile}),
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
Val = random:uniform(2147483648) - 1,
snmp_generic:variable_func(set, Val, {snmpSetSerialNo, volatile});
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index ef9503cda8..e65fa7f340 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -346,13 +347,6 @@ check_target_params(X) ->
error({invalid_target_params, X}).
-
-%% maybe_create_table(Name) ->
-%% case snmpa_local_db:table_exists(db(Name)) of
-%% true -> ok;
-%% _ -> snmpa_local_db:table_create(db(Name))
-%% end.
-
init_tabs(Addrs, Params) ->
?vdebug("create target address table",[]),
AddrDB = db(snmpTargetAddrTable),
@@ -679,8 +673,9 @@ snmpTargetSpinLock(print) ->
snmpTargetSpinLock(new) ->
snmp_generic:variable_func(new, {snmpTargetSpinLock, volatile}),
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
Val = random:uniform(2147483648) - 1,
snmp_generic:variable_func(set, Val, {snmpTargetSpinLock, volatile});
@@ -1080,5 +1075,3 @@ error(Reason) ->
config_err(F, A) ->
snmpa_error:config_err("[TARGET-MIB]: " ++ F, A).
-
-
diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
index 69dce337ba..f6e4fd3951 100644
--- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
+++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -439,8 +440,9 @@ usmUserSpinLock(print) ->
usmUserSpinLock(new) ->
snmp_generic:variable_func(new, {usmUserSpinLock, volatile}),
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
Val = random:uniform(2147483648) - 1,
snmp_generic:variable_func(set, Val, {usmUserSpinLock, volatile});
@@ -1191,29 +1193,7 @@ extract_new_key(Hash, OldKey, KeyChange) ->
-define(i8(Int), Int band 255).
mk_random(Len) when Len =< 20 ->
- %% Use of yield():
- %% This will either schedule another process, or fail and invoke
- %% the error_handler (in old versions). In either case, it is
- %% safe to assume that now, reductions and garbage_collection have
- %% changed in a non-deterministically way.
- {_,_,A} = erlang:now(),
- catch erlang:yield(),
- {_,_,B} = erlang:now(),
- catch erlang:yield(),
- {_,_,C} = erlang:now(),
- {D,_} = erlang:statistics(reductions),
- {E,_} = erlang:statistics(runtime),
- {F,_} = erlang:statistics(wall_clock),
- {G,H,_} = erlang:statistics(garbage_collection),
- catch erlang:yield(),
- {_,_,C2} = erlang:now(),
- {D2,_} = erlang:statistics(reductions),
- {_,H2,_} = erlang:statistics(garbage_collection),
- %% X(N) means we can use N bits from variable X:
- %% A(16) B(16) C(16) D(16) E(8) F(16) G(8) H(16)
- Rnd20 = [?i16(A),?i16(B),?i16(C),?i16(D),?i8(E),?i16(F),
- ?i8(G),?i16(H),?i16(C2),?i16(D2),?i16(H2)],
- lists:sublist(Rnd20, Len).
+ binary_to_list(crypto:strong_rand_bytes(Len)).
split(0, Rest, FirstRev) ->
{lists:reverse(FirstRev), Rest};
diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
index 722bd7ac5b..9e6aa74d45 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -33,6 +34,8 @@
%% Internal exports
-export([check_vacm/1]).
+%%
+-export([emask2imask/1]).
-include("snmp_types.hrl").
@@ -845,8 +848,9 @@ vacmViewSpinLock(print) ->
vacmViewSpinLock(new) ->
snmp_generic:variable_func(new, volatile_db(vacmViewSpinLock)),
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
Val = random:uniform(2147483648) - 1,
snmp_generic:variable_func(set, Val, volatile_db(vacmViewSpinLock));
@@ -1133,4 +1137,3 @@ error(Reason) ->
config_err(F, A) ->
snmpa_error:config_err("[VIEW-BASED-ACM-MIB]: " ++ F, A).
-
diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl
index aea63effe6..7c70404e02 100644
--- a/lib/snmp/src/agent/snmpa.erl
+++ b/lib/snmp/src/agent/snmpa.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_acm.erl b/lib/snmp/src/agent/snmpa_acm.erl
index 42a0d4d6a3..0264c6a992 100644
--- a/lib/snmp/src/agent/snmpa_acm.erl
+++ b/lib/snmp/src/agent/snmpa_acm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -279,7 +280,7 @@ validate_mib_view(Oid, MibView) ->
end.
get_largest_family([{SubTree, Mask, Type} | T], Oid, Res) ->
- case check_mask(Oid, SubTree, Mask) of
+ case check_mask(Oid, SubTree, snmp_view_based_acm_mib:emask2imask(Mask)) of
true -> get_largest_family(T, Oid, add_res(length(SubTree), SubTree,
Type, Res));
false -> get_largest_family(T, Oid, Res)
@@ -344,7 +345,7 @@ validate_all_mib_view([], _MibView) ->
%% intelligent.
%%-----------------------------------------------------------------
is_definitely_not_in_mib_view(Oid, [{SubTree, Mask,?view_included}|T]) ->
- case check_maybe_mask(Oid, SubTree, Mask) of
+ case check_maybe_mask(Oid, SubTree, snmp_view_based_acm_mib:emask2imask(Mask)) of
true -> false;
false -> is_definitely_not_in_mib_view(Oid, T)
end;
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index 6d3f1cca4a..bada50a820 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_agent_sup.erl b/lib/snmp/src/agent/snmpa_agent_sup.erl
index 1c6632e065..f6f218366f 100644
--- a/lib/snmp/src/agent/snmpa_agent_sup.erl
+++ b/lib/snmp/src/agent/snmpa_agent_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_app.erl b/lib/snmp/src/agent/snmpa_app.erl
index 4e65e8e283..89d1efd0a1 100644
--- a/lib/snmp/src/agent/snmpa_app.erl
+++ b/lib/snmp/src/agent/snmpa_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_atl.hrl b/lib/snmp/src/agent/snmpa_atl.hrl
index ec6beb3542..06d36dbb06 100644
--- a/lib/snmp/src/agent/snmpa_atl.hrl
+++ b/lib/snmp/src/agent/snmpa_atl.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_authentication_service.erl b/lib/snmp/src/agent/snmpa_authentication_service.erl
index b5ff8460c6..36845c83b2 100644
--- a/lib/snmp/src/agent/snmpa_authentication_service.erl
+++ b/lib/snmp/src/agent/snmpa_authentication_service.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index 534d0e447b..ebefa945c5 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_discovery_handler.erl b/lib/snmp/src/agent/snmpa_discovery_handler.erl
index cf38583054..7f84601200 100644
--- a/lib/snmp/src/agent/snmpa_discovery_handler.erl
+++ b/lib/snmp/src/agent/snmpa_discovery_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_discovery_handler_default.erl b/lib/snmp/src/agent/snmpa_discovery_handler_default.erl
index 12a27993ab..89b30b3054 100644
--- a/lib/snmp/src/agent/snmpa_discovery_handler_default.erl
+++ b/lib/snmp/src/agent/snmpa_discovery_handler_default.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_error.erl b/lib/snmp/src/agent/snmpa_error.erl
index db2b8d0178..06d61de517 100644
--- a/lib/snmp/src/agent/snmpa_error.erl
+++ b/lib/snmp/src/agent/snmpa_error.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_error_io.erl b/lib/snmp/src/agent/snmpa_error_io.erl
index 54cdb6baac..848869188f 100644
--- a/lib/snmp/src/agent/snmpa_error_io.erl
+++ b/lib/snmp/src/agent/snmpa_error_io.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_error_logger.erl b/lib/snmp/src/agent/snmpa_error_logger.erl
index b1124fd728..50165d79cd 100644
--- a/lib/snmp/src/agent/snmpa_error_logger.erl
+++ b/lib/snmp/src/agent/snmpa_error_logger.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_error_report.erl b/lib/snmp/src/agent/snmpa_error_report.erl
index 35c02edcab..6f3508c8b7 100644
--- a/lib/snmp/src/agent/snmpa_error_report.erl
+++ b/lib/snmp/src/agent/snmpa_error_report.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_general_db.erl b/lib/snmp/src/agent/snmpa_general_db.erl
index a06604c9cf..7892a4c033 100644
--- a/lib/snmp/src/agent/snmpa_general_db.erl
+++ b/lib/snmp/src/agent/snmpa_general_db.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl
index 6537562d44..b340f0d262 100644
--- a/lib/snmp/src/agent/snmpa_internal.hrl
+++ b/lib/snmp/src/agent/snmpa_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl
index 292c370d51..feab855b2e 100644
--- a/lib/snmp/src/agent/snmpa_local_db.erl
+++ b/lib/snmp/src/agent/snmpa_local_db.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib.erl b/lib/snmp/src/agent/snmpa_mib.erl
index 5b523447c5..2f58922e2c 100644
--- a/lib/snmp/src/agent/snmpa_mib.erl
+++ b/lib/snmp/src/agent/snmpa_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_data.erl b/lib/snmp/src/agent/snmpa_mib_data.erl
index 4d8a12b6c6..5614a431d6 100644
--- a/lib/snmp/src/agent/snmpa_mib_data.erl
+++ b/lib/snmp/src/agent/snmpa_mib_data.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_data_ttln.erl b/lib/snmp/src/agent/snmpa_mib_data_ttln.erl
index d367e8f13f..312372b41b 100644
--- a/lib/snmp/src/agent/snmpa_mib_data_ttln.erl
+++ b/lib/snmp/src/agent/snmpa_mib_data_ttln.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_data_tttn.erl b/lib/snmp/src/agent/snmpa_mib_data_tttn.erl
index 90ddf4869f..849c9b37d9 100644
--- a/lib/snmp/src/agent/snmpa_mib_data_tttn.erl
+++ b/lib/snmp/src/agent/snmpa_mib_data_tttn.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_lib.erl b/lib/snmp/src/agent/snmpa_mib_lib.erl
index 529a65a1f1..3006b3c0a8 100644
--- a/lib/snmp/src/agent/snmpa_mib_lib.erl
+++ b/lib/snmp/src/agent/snmpa_mib_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_storage.erl b/lib/snmp/src/agent/snmpa_mib_storage.erl
index 5c3f76d89b..ea166ed79c 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl
index e84e18e7ea..53c69b8d45 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl
index 04faf46864..a2cceb2fa5 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl
index 192b5aa26e..998743f133 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_misc_sup.erl b/lib/snmp/src/agent/snmpa_misc_sup.erl
index 488d3f7921..50570d508e 100644
--- a/lib/snmp/src/agent/snmpa_misc_sup.erl
+++ b/lib/snmp/src/agent/snmpa_misc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 642b1f7fc5..b440d57d03 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -75,8 +76,9 @@
init(Vsns) ->
?vlog("init -> entry with"
"~n Vsns: ~p", [Vsns]),
- {A,B,C} = erlang:now(),
- random:seed(A,B,C),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
ets:insert(snmp_agent_table, {msg_id, random:uniform(2147483647)}),
ets:insert(snmp_agent_table, {req_id, random:uniform(2147483647)}),
init_counters(),
@@ -771,21 +773,7 @@ generate_v3_report_msg(MsgID, MsgSecurityModel, Data, LocalEngineID,
ContextEngineID, ContextName, SecData},
LocalEngineID, Log).
-%% req_id(#scopedPdu{data = #pdu{request_id = ReqId}}) ->
-%% ?vtrace("Report ReqId: ~p",[ReqId]),
-%% ReqId;
-%% req_id(_) ->
-%% 0. % RFC2572, 7.1.3.c.4
-
-%% maybe_generate_discovery1_report_msg() ->
-%% case (catch DiscoveryHandler:handle_discovery1(Ip, Udp, EngineId)) of
-%% {ok, Entry} when is_record(Entry, snmp_discovery_data1) ->
-%% ok;
-%% ignore ->
-%% ok;
-%% {error, Reason} ->
-
%% Response to stage 1 discovery message (terminating, i.e. from the manager)
generate_discovery1_report_msg(MsgID, MsgSecurityModel,
SecName, SecLevel,
diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl
index 57d63bab5b..ecf9498ca9 100644
--- a/lib/snmp/src/agent/snmpa_net_if.erl
+++ b/lib/snmp/src/agent/snmpa_net_if.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -674,7 +675,7 @@ handle_recv(
#state{mpd_state = MpdState, note_store = NS, log = Log} = S,
#transport{socket = Socket} = Transport,
From, Packet) ->
- put(n1, erlang:now()),
+ put(n1, erlang:monotonic_time(micro_seconds)),
LogF =
fun(Type, Data) ->
log(Log, Type, Data, From)
@@ -1379,15 +1380,7 @@ do_close_log(_) ->
%%% DEBUG FUNCTIONS
%%%-----------------------------------------------------------------
time_in_agent() ->
- subtr(erlang:now(), get(n1)).
-
-subtr({X1,Y1,Z1}, {X1,Y1,Z2}) ->
- Z1 - Z2;
-subtr({X1,Y1,Z1}, {X1,Y2,Z2}) ->
- ((Y1-Y2) * 1000000) + (Z1 - Z2);
-subtr({X1,Y1,Z1}, {X2,Y2,Z2}) ->
- ((X1 - X2) * 1000000000000) + ((Y1 - Y2) * 1000000) + (Z1 - Z2).
-
+ erlang:monotonic_time(micro_seconds) - get(n1).
%% ----------------------------------------------------------------
@@ -1637,10 +1630,3 @@ get_port_info(Id) ->
%% ----------------------------------------------------------------
-
-% i(F) ->
-% i(F, []).
-
-% i(F, A) ->
-% io:format("~p: " ++ F ++ "~n", [?MODULE|A]).
-
diff --git a/lib/snmp/src/agent/snmpa_net_if_filter.erl b/lib/snmp/src/agent/snmpa_net_if_filter.erl
index dd77b143d0..5f447ae5c7 100644
--- a/lib/snmp/src/agent/snmpa_net_if_filter.erl
+++ b/lib/snmp/src/agent/snmpa_net_if_filter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_network_interface.erl b/lib/snmp/src/agent/snmpa_network_interface.erl
index 887ea22549..a9f17f274b 100644
--- a/lib/snmp/src/agent/snmpa_network_interface.erl
+++ b/lib/snmp/src/agent/snmpa_network_interface.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_network_interface_filter.erl b/lib/snmp/src/agent/snmpa_network_interface_filter.erl
index 90aa54a271..3ad840e798 100644
--- a/lib/snmp/src/agent/snmpa_network_interface_filter.erl
+++ b/lib/snmp/src/agent/snmpa_network_interface_filter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_notification_delivery_info_receiver.erl b/lib/snmp/src/agent/snmpa_notification_delivery_info_receiver.erl
index b9ec5ff05e..29686ea757 100644
--- a/lib/snmp/src/agent/snmpa_notification_delivery_info_receiver.erl
+++ b/lib/snmp/src/agent/snmpa_notification_delivery_info_receiver.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_notification_filter.erl b/lib/snmp/src/agent/snmpa_notification_filter.erl
index 199cf725fd..6eea857721 100644
--- a/lib/snmp/src/agent/snmpa_notification_filter.erl
+++ b/lib/snmp/src/agent/snmpa_notification_filter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_set.erl b/lib/snmp/src/agent/snmpa_set.erl
index 0f85d0aaa0..fd99304991 100644
--- a/lib/snmp/src/agent/snmpa_set.erl
+++ b/lib/snmp/src/agent/snmpa_set.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_set_lib.erl b/lib/snmp/src/agent/snmpa_set_lib.erl
index f5218d5409..2d14b719dd 100644
--- a/lib/snmp/src/agent/snmpa_set_lib.erl
+++ b/lib/snmp/src/agent/snmpa_set_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_set_mechanism.erl b/lib/snmp/src/agent/snmpa_set_mechanism.erl
index 4561fb035b..b8bf3a9aa8 100644
--- a/lib/snmp/src/agent/snmpa_set_mechanism.erl
+++ b/lib/snmp/src/agent/snmpa_set_mechanism.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl
index 77ed54bee4..128c5f875d 100644
--- a/lib/snmp/src/agent/snmpa_supervisor.erl
+++ b/lib/snmp/src/agent/snmpa_supervisor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_svbl.erl b/lib/snmp/src/agent/snmpa_svbl.erl
index 9c2910580e..53bbce7707 100644
--- a/lib/snmp/src/agent/snmpa_svbl.erl
+++ b/lib/snmp/src/agent/snmpa_svbl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_symbolic_store.erl b/lib/snmp/src/agent/snmpa_symbolic_store.erl
index a922d62ba8..cffb6bcd1c 100644
--- a/lib/snmp/src/agent/snmpa_symbolic_store.erl
+++ b/lib/snmp/src/agent/snmpa_symbolic_store.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_target_cache.erl b/lib/snmp/src/agent/snmpa_target_cache.erl
index 391d711dc5..04d2a121ba 100644
--- a/lib/snmp/src/agent/snmpa_target_cache.erl
+++ b/lib/snmp/src/agent/snmpa_target_cache.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index a79b150f57..eea2b05eb7 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl
index 719ea4e356..fb616cd9ef 100644
--- a/lib/snmp/src/agent/snmpa_usm.erl
+++ b/lib/snmp/src/agent/snmpa_usm.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -645,8 +646,9 @@ get_des_salt() ->
ets:insert(snmp_agent_table, {usm_des_salt, 0}),
0;
_ -> % it doesn't exist, initialize
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
R = random:uniform(4294967295),
ets:insert(snmp_agent_table, {usm_des_salt, R}),
R
@@ -677,8 +679,9 @@ get_aes_salt() ->
ets:insert(snmp_agent_table, {usm_aes_salt, 0}),
0;
_ -> % it doesn't exist, initialize
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
R = random:uniform(36893488147419103231),
ets:insert(snmp_agent_table, {usm_aes_salt, R}),
R
diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl
index dadcf32543..f9df52010b 100644
--- a/lib/snmp/src/agent/snmpa_vacm.erl
+++ b/lib/snmp/src/agent/snmpa_vacm.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -305,8 +306,8 @@ dump_table() ->
%% time dumping the table.
unique_table_name(Pre) ->
%% We want something that is guaranteed to be unique,
- %% therefor we use erlang:now() instead of os:timestamp()
- unique_table_name(Pre, erlang:now()).
+ %% therefor we use erlang:timestamp() instead of os:timestamp()
+ unique_table_name(Pre, erlang:timestamp()).
unique_table_name(Pre, {_A, _B, C} = Now) ->
{Date, Time} = calendar:now_to_datetime(Now),
@@ -445,6 +446,3 @@ gc_tab(Oid) ->
user_err(F, A) ->
snmpa_error:user_err(F, A).
-
-% config_err(F, A) ->
-% snmpa_error:config_err(F, A).
diff --git a/lib/snmp/src/agent/snmpa_vacm.hrl b/lib/snmp/src/agent/snmpa_vacm.hrl
index 681591d212..20506f8715 100644
--- a/lib/snmp/src/agent/snmpa_vacm.hrl
+++ b/lib/snmp/src/agent/snmpa_vacm.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/app/Makefile b/lib/snmp/src/app/Makefile
index b8cc4b8754..7972d9549d 100644
--- a/lib/snmp/src/app/Makefile
+++ b/lib/snmp/src/app/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/app/depend.mk b/lib/snmp/src/app/depend.mk
index 1080cb5693..4a9cc17490 100644
--- a/lib/snmp/src/app/depend.mk
+++ b/lib/snmp/src/app/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/app/modules.mk b/lib/snmp/src/app/modules.mk
index 678f15de5c..fa42614a24 100644
--- a/lib/snmp/src/app/modules.mk
+++ b/lib/snmp/src/app/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/app/snmp.app.src b/lib/snmp/src/app/snmp.app.src
index cbd292e4c3..b593e9ea84 100644
--- a/lib/snmp/src/app/snmp.app.src
+++ b/lib/snmp/src/app/snmp.app.src
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -137,5 +138,5 @@
%% before snmp.
{applications, [kernel, stdlib]},
{mod, {snmp_app, []}},
- {runtime_dependencies, ["stdlib-2.0","runtime_tools-1.8.14","mnesia-4.12",
+ {runtime_dependencies, ["stdlib-2.5","runtime_tools-1.8.14","mnesia-4.12",
"kernel-3.0","erts-6.0","crypto-3.3"]}]}.
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 081163b368..ca61782639 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -1,64 +1,24 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-
+%% -*- erlang -*-
{"%VSN%",
%% ----- U p g r a d e -------------------------------------------------------
-
%% Instruction examples:
%% {restart_application, snmp}
%% {load_module, snmp_pdus, soft_purge, soft_purge, []}
%% {update, snmpa_local_db, soft, soft_purge, soft_purge, []}
%% {add_module, snmpm_net_if_mt}
[
- {"5.1.1", [{restart_application, snmp}]},
- {"5.1", [ % Only compiler changes
- ]},
- {"5.0", [{restart_application, snmp}]},
- {"4.25.1", [{restart_application, snmp}]},
- {"4.25.0.1", [{restart_application, snmp}]},
- {"4.25.0.0.1", [{restart_application, snmp}]},
- {"4.25", [{restart_application, snmp}]},
- {"4.24.2", [{restart_application, snmp}]},
- {"4.24.1", [{restart_application, snmp}]},
- {"4.24", [{restart_application, snmp}]}
- ],
-
+ {<<"5\\..*">>, [{restart_application, snmp}]},
+ {<<"4\\..*">>, [{restart_application, snmp}]}
+ ],
+
%% ------D o w n g r a d e ---------------------------------------------------
-
%% Instruction examples:
%% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
-
+
[
- {"5.1.1", [{restart_application, snmp}]},
- {"5.1", [ % Only compiler changes
- ]},
- {"5.0", [{restart_application, snmp}]},
- {"4.25.1", [{restart_application, snmp}]},
- {"4.25.0.1", [{restart_application, snmp}]},
- {"4.25.0.0.1", [{restart_application, snmp}]},
- {"4.25", [{restart_application, snmp}]},
- {"4.24.2", [{restart_application, snmp}]},
- {"4.24.1", [{restart_application, snmp}]},
- {"4.24", [{restart_application, snmp}]}
- ]
-
-}.
+ {<<"5\\..*">>, [{restart_application, snmp}]},
+ {<<"4\\..*">>, [{restart_application, snmp}]}
+ ]
+}.
diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl
index 8b3a8af77d..3c65f40bc7 100644
--- a/lib/snmp/src/app/snmp.erl
+++ b/lib/snmp/src/app/snmp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/app/snmp_app.erl b/lib/snmp/src/app/snmp_app.erl
index 28a6fef7e9..8b948850dd 100644
--- a/lib/snmp/src/app/snmp_app.erl
+++ b/lib/snmp/src/app/snmp_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/app/snmp_app_sup.erl b/lib/snmp/src/app/snmp_app_sup.erl
index d0c190b51f..32b69b4bbf 100644
--- a/lib/snmp/src/app/snmp_app_sup.erl
+++ b/lib/snmp/src/app/snmp_app_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/app/snmp_internal.hrl b/lib/snmp/src/app/snmp_internal.hrl
index f04fa4dd53..9a1bb4b67c 100644
--- a/lib/snmp/src/app/snmp_internal.hrl
+++ b/lib/snmp/src/app/snmp_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile
index f63fc18997..54f2e229b9 100644
--- a/lib/snmp/src/compile/Makefile
+++ b/lib/snmp/src/compile/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk
index 2f8a07aba7..427ad4cda3 100644
--- a/lib/snmp/src/compile/depend.mk
+++ b/lib/snmp/src/compile/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-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.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/compile/modules.mk b/lib/snmp/src/compile/modules.mk
index 399e4f865e..547cc3438e 100644
--- a/lib/snmp/src/compile/modules.mk
+++ b/lib/snmp/src/compile/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index 2f065dddac..db1f9ee61b 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -409,8 +410,9 @@ get_verbosity(Options) ->
%%----------------------------------------------------------------------
init(From, MibFileName, Options) ->
- {A,B,C} = now(),
- random:seed(A,B,C),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
put(options, Options),
put(verbosity, get_verbosity(Options)),
put(description, get_description(Options)),
diff --git a/lib/snmp/src/compile/snmpc.hrl b/lib/snmp/src/compile/snmpc.hrl
index 1c0808d065..9157ef13f0 100644
--- a/lib/snmp/src/compile/snmpc.hrl
+++ b/lib/snmp/src/compile/snmpc.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src
index 6eb95be35e..903b035d13 100644
--- a/lib/snmp/src/compile/snmpc.src
+++ b/lib/snmp/src/compile/snmpc.src
@@ -5,16 +5,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl
index 0f6393eeef..3b1b1594c9 100644
--- a/lib/snmp/src/compile/snmpc_lib.erl
+++ b/lib/snmp/src/compile/snmpc_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/compile/snmpc_lib.hrl b/lib/snmp/src/compile/snmpc_lib.hrl
index 35ec9abd03..0f65fc1820 100644
--- a/lib/snmp/src/compile/snmpc_lib.hrl
+++ b/lib/snmp/src/compile/snmpc_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc_mib_gram.yrl b/lib/snmp/src/compile/snmpc_mib_gram.yrl
index 4fd504e34b..b152f23d05 100644
--- a/lib/snmp/src/compile/snmpc_mib_gram.yrl
+++ b/lib/snmp/src/compile/snmpc_mib_gram.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc_mib_to_hrl.erl b/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
index e8c46a0521..e71530b40e 100644
--- a/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
+++ b/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc_misc.erl b/lib/snmp/src/compile/snmpc_misc.erl
index 557f3e0f6b..68600bc97a 100644
--- a/lib/snmp/src/compile/snmpc_misc.erl
+++ b/lib/snmp/src/compile/snmpc_misc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc_misc.hrl b/lib/snmp/src/compile/snmpc_misc.hrl
index c29f2eb9e5..e09ec2712c 100644
--- a/lib/snmp/src/compile/snmpc_misc.hrl
+++ b/lib/snmp/src/compile/snmpc_misc.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/compile/snmpc_tok.erl b/lib/snmp/src/compile/snmpc_tok.erl
index e238b256d0..14f88cc9ae 100644
--- a/lib/snmp/src/compile/snmpc_tok.erl
+++ b/lib/snmp/src/compile/snmpc_tok.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/Makefile b/lib/snmp/src/manager/Makefile
index c76dbacf90..382f83b78e 100644
--- a/lib/snmp/src/manager/Makefile
+++ b/lib/snmp/src/manager/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/manager/depend.mk b/lib/snmp/src/manager/depend.mk
index 60f61b0d3b..651a6e537d 100644
--- a/lib/snmp/src/manager/depend.mk
+++ b/lib/snmp/src/manager/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/manager/modules.mk b/lib/snmp/src/manager/modules.mk
index d46545ea3f..0f13e26423 100644
--- a/lib/snmp/src/manager/modules.mk
+++ b/lib/snmp/src/manager/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index 8976322c4e..446280b8bd 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -520,7 +521,7 @@ sync_get(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) ->
-%% --- asynchroneous get-request ---
+%% --- asynchronous get-request ---
%%
%% The reply will be delivered to the user
%% through a call to handle_pdu/5
@@ -588,7 +589,7 @@ sync_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) ->
%% </BACKWARD-COMPAT>
-%% --- asynchroneous get_next-request ---
+%% --- asynchronous get_next-request ---
%%
async_get_next2(UserId, TargetName, Oids) ->
@@ -654,7 +655,7 @@ sync_set(UserId, TargetName, Context, VarsAndVals, Timeout, ExtraInfo) ->
%% </BACKWARD-COMPAT>
-%% --- asynchroneous set-request ---
+%% --- asynchronous set-request ---
%%
async_set2(UserId, TargetName, VarsAndVals) ->
@@ -746,7 +747,7 @@ sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout,
%% </BACKWARD-COMPAT>
-%% --- asynchroneous get-bulk ---
+%% --- asynchronous get-bulk ---
%%
async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) ->
diff --git a/lib/snmp/src/manager/snmpm_atl.hrl b/lib/snmp/src/manager/snmpm_atl.hrl
index d99ee05ae6..f407b399cf 100644
--- a/lib/snmp/src/manager/snmpm_atl.hrl
+++ b/lib/snmp/src/manager/snmpm_atl.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl
index 087ef6c6ea..0abc5ae88b 100644
--- a/lib/snmp/src/manager/snmpm_conf.erl
+++ b/lib/snmp/src/manager/snmpm_conf.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index 5cab81baf6..e5c0f27bd6 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/manager/snmpm_internal.hrl b/lib/snmp/src/manager/snmpm_internal.hrl
index 53ad41c6b0..72f277faf6 100644
--- a/lib/snmp/src/manager/snmpm_internal.hrl
+++ b/lib/snmp/src/manager/snmpm_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_misc_sup.erl b/lib/snmp/src/manager/snmpm_misc_sup.erl
index 1a5d7676df..835216b30b 100644
--- a/lib/snmp/src/manager/snmpm_misc_sup.erl
+++ b/lib/snmp/src/manager/snmpm_misc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl
index f8a7441c0a..191dc2c281 100644
--- a/lib/snmp/src/manager/snmpm_mpd.erl
+++ b/lib/snmp/src/manager/snmpm_mpd.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -67,8 +68,9 @@
%%%-----------------------------------------------------------------
init(Vsns) ->
?vdebug("init -> entry with ~p", [Vsns]),
- {A,B,C} = erlang:now(),
- random:seed(A,B,C),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
snmpm_config:cre_counter(msg_id, random:uniform(2147483647)),
snmpm_config:cre_counter(req_id, random:uniform(2147483647)),
init_counters(),
@@ -896,17 +898,6 @@ get_agent_engine_id(Name) ->
is_known_engine_id(EngineID, {Addr, Port}) ->
snmpm_config:is_known_engine_id(EngineID, Addr, Port).
-%% is_known_engine_id(EngineID, Addr, Port) ->
-%% snmpm_config:is_known_engine_id(EngineID, Addr, Port).
-
-% get_agent_engine_id(Addr, Port) ->
-% case snmpm_config:get_agent_engine_id(Addr, Port) of
-% {ok, Id} ->
-% Id;
-% _Error ->
-% ""
-% end.
-
%%-----------------------------------------------------------------
%% Sequence number (msg-id & req-id) functions
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index 0e1c51c609..93c987eb0f 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -489,11 +490,6 @@ handle_call({verbosity, Verbosity}, _From, State) ->
put(verbosity, Verbosity),
{reply, ok, State};
-%% handle_call({system_info_updated, What}, _From, State) ->
-%% ?vlog("received system_info_updated request with What = ~p", [What]),
-%% {NewState, Reply} = handle_system_info_updated(State, What),
-%% {reply, Reply, NewState};
-
handle_call(get_log_type, _From, State) ->
?vlog("received get-log-type request", []),
Reply = (catch handle_get_log_type(State)),
@@ -816,7 +812,7 @@ handle_inform_request(
ok;
[] ->
RePdu = make_response_pdu(Pdu),
- Expire = t() + To,
+ Expire = snmp_misc:now(ms) + To,
Rec = {Key, Expire, {Vsn, ACM, RePdu}},
ets:insert(snmpm_inform_request_table, Rec)
end.
@@ -876,7 +872,7 @@ maybe_send_inform_response(
handle_inform_response_gc(#state{irb = IRB} = State) ->
ets:safe_fixtable(snmpm_inform_request_table, true),
- do_irgc(ets:first(snmpm_inform_request_table), t()),
+ do_irgc(ets:first(snmpm_inform_request_table), snmp_misc:now(ms)),
ets:safe_fixtable(snmpm_inform_request_table, false),
State#state{irgc = irgc_start(IRB)}.
@@ -1023,110 +1019,6 @@ handle_disk_log(_Log, _Info, State) ->
State.
-%% mk_discovery_msg('version-3', Pdu, _VsnHdr, UserName) ->
-%% ScopedPDU = #scopedPdu{contextEngineID = "",
-%% contextName = "",
-%% data = Pdu},
-%% Bytes = snmp_pdus:enc_scoped_pdu(ScopedPDU),
-%% MsgID = get(msg_id),
-%% put(msg_id,MsgID+1),
-%% UsmSecParams =
-%% #usmSecurityParameters{msgAuthoritativeEngineID = "",
-%% msgAuthoritativeEngineBoots = 0,
-%% msgAuthoritativeEngineTime = 0,
-%% msgUserName = UserName,
-%% msgPrivacyParameters = "",
-%% msgAuthenticationParameters = ""},
-%% SecBytes = snmp_pdus:enc_usm_security_parameters(UsmSecParams),
-%% PduType = Pdu#pdu.type,
-%% Hdr = #v3_hdr{msgID = MsgID,
-%% msgMaxSize = 1000,
-%% msgFlags = snmp_misc:mk_msg_flags(PduType, 0),
-%% msgSecurityModel = ?SEC_USM,
-%% msgSecurityParameters = SecBytes},
-%% Msg = #message{version = 'version-3', vsn_hdr = Hdr, data = Bytes},
-%% case (catch snmp_pdus:enc_message_only(Msg)) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% L when list(L) ->
-%% {Msg, L}
-%% end;
-%% mk_discovery_msg(Version, Pdu, {Com, _, _, _, _}, UserName) ->
-%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu},
-%% case catch snmp_pdus:enc_message(Msg) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% L when list(L) ->
-%% {Msg, L}
-%% end.
-
-
-%% mk_msg('version-3', Pdu, {Context, User, EngineID, CtxEngineId, SecLevel},
-%% MsgData) ->
-%% %% Code copied from snmp_mpd.erl
-%% {MsgId, SecName, SecData} =
-%% if
-%% tuple(MsgData), Pdu#pdu.type == 'get-response' ->
-%% MsgData;
-%% true ->
-%% Md = get(msg_id),
-%% put(msg_id, Md + 1),
-%% {Md, User, []}
-%% end,
-%% ScopedPDU = #scopedPdu{contextEngineID = CtxEngineId,
-%% contextName = Context,
-%% data = Pdu},
-%% ScopedPDUBytes = snmp_pdus:enc_scoped_pdu(ScopedPDU),
-
-%% PduType = Pdu#pdu.type,
-%% V3Hdr = #v3_hdr{msgID = MsgId,
-%% msgMaxSize = 1000,
-%% msgFlags = snmp_misc:mk_msg_flags(PduType, SecLevel),
-%% msgSecurityModel = ?SEC_USM},
-%% Message = #message{version = 'version-3', vsn_hdr = V3Hdr,
-%% data = ScopedPDUBytes},
-%% SecEngineID = case PduType of
-%% 'get-response' -> snmp_framework_mib:get_engine_id();
-%% _ -> EngineID
-%% end,
-%% case catch snmp_usm:generate_outgoing_msg(Message, SecEngineID,
-%% SecName, SecData, SecLevel) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% {error, Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% Packet ->
-%% Packet
-%% end;
-%% mk_msg(Version, Pdu, {Com, _User, _EngineID, _Ctx, _SecLevel}, _SecData) ->
-%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu},
-%% case catch snmp_pdus:enc_message(Msg) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% B when list(B) ->
-%% B
-%% end.
-
-
-%% handle_system_info_updated(#state{log = {Log, _OldType}} = State,
-%% audit_trail_log_type = _What) ->
-%% %% Just to make sure, check that ATL is actually enabled
-%% case snmpm_config:system_info(audit_trail_log) of
-%% {ok, true} ->
-%% {ok, Type} = snmpm_config:system_info(audit_trail_log_type),
-%% NewState = State#state{log = {Log, Type}},
-%% {NewState, ok};
-%% _ ->
-%% {State, {error, {adt_not_enabled}}}
-%% end;
-%% handle_system_info_updated(_State, _What) ->
-%% ok.
-
handle_get_log_type(#state{log = {_Log, Value}} = State) ->
%% Just to make sure, check that ATL is actually enabled
case snmpm_config:system_info(audit_trail_log) of
@@ -1257,13 +1149,6 @@ maybe_process_extra_info(_ExtraInfo) ->
%% -------------------------------------------------------------------
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-
-%% -------------------------------------------------------------------
-
%% info_msg(F, A) ->
%% ?snmpm_info("NET-IF server: " ++ F, A).
@@ -1301,8 +1186,6 @@ proc_mem(P) when is_pid(P) ->
_ ->
undefined
end.
-%% proc_mem(_) ->
-%% undefined.
get_port_info(Id) ->
@@ -1382,20 +1265,6 @@ counters() ->
inc(Name) -> inc(Name, 1).
inc(Name, N) -> snmpm_config:incr_stats_counter(Name, N).
-%% get_counters() ->
-%% Counters = counters(),
-%% get_counters(Counters, []).
-
-%% get_counters([], Acc) ->
-%% lists:reverse(Acc);
-%% get_counters([Counter|Counters], Acc) ->
-%% case snmpm_config:get_stats_counter(Counter) of
-%% {ok, CounterVal} ->
-%% get_counters(Counters, [{Counter, CounterVal}|Acc]);
-%% _ ->
-%% get_counters(Counters, Acc)
-%% end.
-
%% ----------------------------------------------------------------
diff --git a/lib/snmp/src/manager/snmpm_net_if_filter.erl b/lib/snmp/src/manager/snmpm_net_if_filter.erl
index d96ae5c145..bcc9f97f4c 100644
--- a/lib/snmp/src/manager/snmpm_net_if_filter.erl
+++ b/lib/snmp/src/manager/snmpm_net_if_filter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl
index 62f6023657..72bd69c612 100644
--- a/lib/snmp/src/manager/snmpm_net_if_mt.erl
+++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/manager/snmpm_network_interface.erl b/lib/snmp/src/manager/snmpm_network_interface.erl
index b830d45ce7..dd4e762d84 100644
--- a/lib/snmp/src/manager/snmpm_network_interface.erl
+++ b/lib/snmp/src/manager/snmpm_network_interface.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_network_interface_filter.erl b/lib/snmp/src/manager/snmpm_network_interface_filter.erl
index ae8b7cfce1..604994756d 100644
--- a/lib/snmp/src/manager/snmpm_network_interface_filter.erl
+++ b/lib/snmp/src/manager/snmpm_network_interface_filter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 8fc3359159..c8d7fa1e8b 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -467,27 +468,6 @@ cancel_async_request(UserId, ReqId) ->
call({cancel_async_request, UserId, ReqId}).
-%% discovery(UserId, BAddr) ->
-%% discovery(UserId, BAddr, ?SNMP_AGENT_PORT, [],
-%% ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).
-
-%% discovery(UserId, BAddr, Config) when is_list(Config) ->
-%% discovery(UserId, BAddr, ?SNMP_AGENT_PORT, Config,
-%% ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO);
-
-%% discovery(UserId, BAddr, Expire) when is_integer(Expire) ->
-%% discovery(UserId, BAddr, ?SNMP_AGENT_PORT, [], Expire, ?EXTRA_INFO).
-
-%% discovery(UserId, BAddr, Config, Expire) ->
-%% discovery(UserId, BAddr, ?SNMP_AGENT_PORT, Config, Expire, ?EXTRA_INFO).
-
-%% discovery(UserId, BAddr, Port, Config, Expire) ->
-%% discovery(UserId, BAddr, Port, Config, Expire, ?EXTRA_INFO).
-
-%% discovery(UserId, BAddr, Port, Config, Expire, ExtraInfo) ->
-%% call({discovery, self(), UserId, BAddr, Port, Config, Expire, ExtraInfo}).
-
-
verbosity(Verbosity) ->
case ?vvalidate(Verbosity) of
Verbosity ->
@@ -927,14 +907,6 @@ handle_call({cancel_async_request, UserId, ReqId}, _From, State) ->
{reply, Reply, State};
-%% handle_call({discovery, Pid, UserId, BAddr, Port, Config, Expire, ExtraInfo},
-%% _From, State) ->
-%% ?vlog("received discovery request", []),
-%% Reply = (catch handle_discovery(Pid, UserId, BAddr, Port, Config,
-%% Expire, ExtraInfo, State)),
-%% {reply, Reply, State};
-
-
handle_call({load_mib, Mib}, _From, State) ->
?vlog("received load_mib request", []),
case snmpm_config:load_mib(Mib) of
@@ -988,13 +960,6 @@ handle_call(is_started, _From, State) ->
IsStarted = is_started(State),
{reply, IsStarted, State};
-%% handle_call({system_info_updated, Target, What}, _From, State) ->
-%% ?vlog("received system_info_updated request: "
-%% "~n Target: ~p"
-%% "~n What: ~p", [Target, What]),
-%% Reply = handle_system_info_updated(State, Target, What),
-%% {reply, Reply, State};
-
handle_call(get_log_type, _From, State) ->
?vlog("received get_log_type request", []),
Reply = handle_get_log_type(State),
@@ -1042,11 +1007,6 @@ handle_info({snmp_error, ReqId, Reason, Domain, Addr}, State) ->
handle_snmp_error(Domain, Addr, ReqId, Reason, State),
{noreply, State};
-%% handle_info({snmp_error, ReqId, Pdu, Reason, Addr, Port}, State) ->
-%% ?vlog("received snmp_error message", []),
-%% handle_snmp_error(Pdu, ReqId, Reason, Addr, Port, State),
-%% {noreply, State};
-
handle_info({snmp_pdu, Pdu, Domain, Addr}, State) ->
?vlog("received snmp_pdu message", []),
@@ -1411,7 +1371,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
address = Addr,
type = get,
data = MsgData,
- expire = t() + Expire},
+ expire = snmp_misc:now(ms) + Expire},
ets:insert(snmpm_request_table, Req),
gct_activate(State#state.gct),
@@ -1460,7 +1420,7 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) ->
address = Addr,
type = get_next,
data = MsgData,
- expire = t() + Expire},
+ expire = snmp_misc:now(ms) + Expire},
ets:insert(snmpm_request_table, Req),
gct_activate(State#state.gct),
@@ -1516,7 +1476,7 @@ handle_async_get_bulk(Pid,
address = Addr,
type = get_bulk,
data = MsgData,
- expire = t() + Expire},
+ expire = snmp_misc:now(ms) + Expire},
ets:insert(snmpm_request_table, Req),
gct_activate(State#state.gct),
{ok, ReqId};
@@ -1564,7 +1524,7 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) ->
address = Addr,
type = set,
data = MsgData,
- expire = t() + Expire},
+ expire = snmp_misc:now(ms) + Expire},
ets:insert(snmpm_request_table, Req),
gct_activate(State#state.gct),
@@ -1600,18 +1560,6 @@ handle_cancel_async_request(UserId, ReqId, _State) ->
?vlog("handle_cancel_async_request -> not found", []),
{error, not_found}
end.
-
-
-%% handle_system_info_updated(#state{net_if = Pid, net_if_mod = Mod} = _State,
-%% net_if = _Target, What) ->
-%% case (catch Mod:system_info_updated(Pid, What)) of
-%% {'EXIT', _} ->
-%% {error, not_supported};
-%% Else ->
-%% Else
-%% end;
-%% handle_system_info_updated(_State, Target, What) ->
-%% {error, {bad_target, Target, What}}.
handle_get_log_type(#state{net_if = Pid, net_if_mod = Mod}) ->
case (catch Mod:get_log_type(Pid)) of
@@ -1629,47 +1577,6 @@ handle_set_log_type(#state{net_if = Pid, net_if_mod = Mod}, NewType) ->
Else
end.
-
-%% handle_discovery(Pid, UserId, BAddr, Port, Config, Expire, ExtraInfo, State) ->
-%% ?vtrace("handle_discovery -> entry with"
-%% "~n Pid: ~p"
-%% "~n UserId: ~p"
-%% "~n BAddr: ~p"
-%% "~n Port: ~p"
-%% "~n Config: ~p"
-%% "~n Expire: ~p",
-%% [Pid, UserId, BAddr, Port, Config, Expire]),
-%% case agent_data(default, default, "", Config) of
-%% {ok, Addr, Port, Vsn, MsgData} ->
-%% ?vtrace("handle_discovery -> send a ~p disco message", [Vsn]),
-%% ReqId = send_discovery(Vsn, MsgData, BAddr, Port, ExtraInfo,
-%% State),
-%% ?vdebug("handle_discovery -> ReqId: ~p", [ReqId]),
-%% MonRef = erlang:monitor(process, Pid),
-%% ?vtrace("handle_discovery -> MonRef: ~p", [MonRef]),
-%% Req = #request{id = ReqId,
-%% user_id = UserId,
-%% target = TargetName,
-%% addr = BAddr,
-%% port = Port,
-%% type = get,
-%% data = MsgData,
-%% mon = MonRef,
-%% discovery = true,
-%% expire = t() + Expire},
-%% ets:insert(snmpm_request_table, Req),
-%% gct_activate(State#state.gct),
-%% {ok, ReqId};
-
-%% Error ->
-%% ?vinfo("failed retrieving agent data for discovery (get):"
-%% "~n BAddr: ~p"
-%% "~n Port: ~p"
-%% "~n Error: ~p", [BAddr, Port, Error]),
-%% Error
-%% end.
-
-
handle_sync_timeout(ReqId, From, State) ->
?vtrace("handle_sync_timeout -> entry with"
"~n ReqId: ~p"
@@ -1693,7 +1600,7 @@ handle_sync_timeout(ReqId, From, State) ->
Req = Req0#request{ref = undefined,
mon = undefined,
from = undefined,
- expire = t()},
+ expire = snmp_misc:now(ms)},
ets:insert(snmpm_request_table, Req),
gct_activate(State#state.gct),
ok;
@@ -3026,7 +2933,7 @@ cancel_timer(Ref) ->
handle_gc(GCT) ->
ets:safe_fixtable(snmpm_request_table, true),
- case do_gc(ets:first(snmpm_request_table), t()) of
+ case do_gc(ets:first(snmpm_request_table), snmp_misc:now(ms)) of
0 ->
gct_deactivate(GCT);
_ ->
@@ -3100,23 +3007,11 @@ send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, ExtraInfo,
Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo),
Pdu#pdu.request_id.
-%% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo,
-%% #state{net_if = NetIf,
-%% net_if_mod = Mod}) ->
-%% Pdu = make_discovery_pdu(),
-%% Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
-%% Pdu#pdu.request_id.
-
-
%%----------------------------------------------------------------------
%%
%%----------------------------------------------------------------------
-%% make_discovery_pdu() ->
-%% Oids = [?sysObjectID_instance, ?sysDescr_instance, ?sysUpTime_instance],
-%% make_pdu_impl(get, Oids).
-
make_pdu(set, VarsAndVals, MiniMIB) ->
VBs = [var_and_value_to_varbind(VAV, MiniMIB) || VAV <- VarsAndVals],
make_pdu_impl(set, VBs);
@@ -3399,7 +3294,7 @@ gct_init(#gct{parent = Parent, timeout = Timeout} = State) ->
gct(State, Timeout).
gct(#gct{parent = Parent, state = active} = State, Timeout) ->
- T = t(),
+ T = snmp_misc:now(ms),
receive
{stop, Parent} ->
ok;
@@ -3457,7 +3352,7 @@ gct(#gct{parent = Parent, state = idle} = State, Timeout) ->
end.
new_timeout(T1, T2) ->
- case T1 - (t() - T2) of
+ case T1 - (snmp_misc:now(ms) - T2) of
T when (T > 0) ->
T;
_ ->
@@ -3477,11 +3372,6 @@ maybe_demonitor(undefined) ->
maybe_demonitor(MonRef) ->
erlang:demonitor(MonRef).
-%% Time in milli seconds
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
mk_target_name(Domain, Addr, Config) ->
snmpm_config:mk_target_name(Domain, Addr, Config).
@@ -3520,12 +3410,6 @@ call(Req) ->
call(Req, To) ->
gen_server:call(?SERVER, Req, To).
-%% cast(Msg) ->
-%% gen_server:cast(?SERVER, Msg).
-
-%% info_msg(F, A) ->
-%% ?snmpm_info("Server: " ++ F, A).
-
warning_msg(F, A) ->
?snmpm_warning("Server: " ++ F, A).
@@ -3601,20 +3485,3 @@ note_store_info(Pid) ->
%%----------------------------------------------------------------------
-
-
-%%----------------------------------------------------------------------
-%% Debug
-%%----------------------------------------------------------------------
-
-% sz(L) when is_list(L) ->
-% length(lists:flatten(L));
-% sz(B) when is_binary(B) ->
-% size(B).
-
-%% p(F) ->
-%% p(F, []).
-
-%% p(F, A) ->
-%% io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
-
diff --git a/lib/snmp/src/manager/snmpm_server_sup.erl b/lib/snmp/src/manager/snmpm_server_sup.erl
index 16238e4aaf..e8c2790db3 100644
--- a/lib/snmp/src/manager/snmpm_server_sup.erl
+++ b/lib/snmp/src/manager/snmpm_server_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_supervisor.erl b/lib/snmp/src/manager/snmpm_supervisor.erl
index 8f43310c14..5654c01c6a 100644
--- a/lib/snmp/src/manager/snmpm_supervisor.erl
+++ b/lib/snmp/src/manager/snmpm_supervisor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_user.erl b/lib/snmp/src/manager/snmpm_user.erl
index 8e5a874f77..366e40cbb9 100644
--- a/lib/snmp/src/manager/snmpm_user.erl
+++ b/lib/snmp/src/manager/snmpm_user.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_user_default.erl b/lib/snmp/src/manager/snmpm_user_default.erl
index b827713f27..f4f78d49b6 100644
--- a/lib/snmp/src/manager/snmpm_user_default.erl
+++ b/lib/snmp/src/manager/snmpm_user_default.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_user_old.erl b/lib/snmp/src/manager/snmpm_user_old.erl
index 69b1470790..c490421d6e 100644
--- a/lib/snmp/src/manager/snmpm_user_old.erl
+++ b/lib/snmp/src/manager/snmpm_user_old.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_usm.erl b/lib/snmp/src/manager/snmpm_usm.erl
index 0a8a6436a3..c7a28f5d68 100644
--- a/lib/snmp/src/manager/snmpm_usm.erl
+++ b/lib/snmp/src/manager/snmpm_usm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/manager/snmpm_usm.hrl b/lib/snmp/src/manager/snmpm_usm.hrl
index 1939ad6ed9..7a0d225aff 100644
--- a/lib/snmp/src/manager/snmpm_usm.hrl
+++ b/lib/snmp/src/manager/snmpm_usm.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/misc/Makefile b/lib/snmp/src/misc/Makefile
index 698c341268..c71ecf994e 100644
--- a/lib/snmp/src/misc/Makefile
+++ b/lib/snmp/src/misc/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/misc/depend.mk b/lib/snmp/src/misc/depend.mk
index dea0f75048..3f8e6701b9 100644
--- a/lib/snmp/src/misc/depend.mk
+++ b/lib/snmp/src/misc/depend.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/misc/modules.mk b/lib/snmp/src/misc/modules.mk
index 32092aaae2..c22f3604b7 100644
--- a/lib/snmp/src/misc/modules.mk
+++ b/lib/snmp/src/misc/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index 153c8070c2..6264d79cec 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1004,6 +1005,8 @@ check_imask(IMask) when is_list(IMask) ->
do_check_imask(IMask),
{ok, IMask}.
+do_check_imask([]) ->
+ ok;
do_check_imask([0|IMask]) ->
do_check_imask(IMask);
do_check_imask([1|IMask]) ->
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index 17dfcd70b4..2b6bfdcb56 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/misc/snmp_debug.hrl b/lib/snmp/src/misc/snmp_debug.hrl
index dc916ac96a..86445893b6 100644
--- a/lib/snmp/src/misc/snmp_debug.hrl
+++ b/lib/snmp/src/misc/snmp_debug.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index 4b22281b89..09863dea60 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/misc/snmp_mini_mib.erl b/lib/snmp/src/misc/snmp_mini_mib.erl
index d80270d5c2..bc9596f64f 100644
--- a/lib/snmp/src/misc/snmp_mini_mib.erl
+++ b/lib/snmp/src/misc/snmp_mini_mib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/misc/snmp_misc.erl b/lib/snmp/src/misc/snmp_misc.erl
index c36cee2a53..1f847b7a29 100644
--- a/lib/snmp/src/misc/snmp_misc.erl
+++ b/lib/snmp/src/misc/snmp_misc.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -101,21 +102,14 @@ sleep(Time) ->
%% Returns time in ms = sec/1000
% now() -> now(ms).
now(ms) ->
- Now = erlang:now(),
- element(1,Now)*1000000000+
- element(2,Now)*1000+
- (element(3,Now) div 1000);
+ erlang:monotonic_time(milli_seconds);
+
%% Returns time in cs = sec/100
now(cs) ->
- Now = erlang:now(),
- element(1,Now)*100000000+
- element(2,Now)*100+
- (element(3,Now) div 10000);
+ erlang:monotonic_time(100);
+
now(sec) ->
- Now = erlang:now(),
- element(1,Now)*1000000+
- element(2,Now)+
- (element(3,Now) div 1000000).
+ erlang:monotonic_time(seconds).
is_crypto_supported(Alg) ->
@@ -479,7 +473,3 @@ format_val('OBJECT IDENTIFIER', _, Val, MiniMib) ->
io_lib:format("~w", [NVal]);
format_val(_, _, Val, _MiniMib) ->
io_lib:format("~p", [Val]).
-
-
-
-
diff --git a/lib/snmp/src/misc/snmp_note_store.erl b/lib/snmp/src/misc/snmp_note_store.erl
index 608fdcd9ca..74bdd34931 100644
--- a/lib/snmp/src/misc/snmp_note_store.erl
+++ b/lib/snmp/src/misc/snmp_note_store.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl
index 90fa4c0dea..8045a94ff6 100644
--- a/lib/snmp/src/misc/snmp_pdus.erl
+++ b/lib/snmp/src/misc/snmp_pdus.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/misc/snmp_usm.erl b/lib/snmp/src/misc/snmp_usm.erl
index 32198deb8b..8443b009d9 100644
--- a/lib/snmp/src/misc/snmp_usm.erl
+++ b/lib/snmp/src/misc/snmp_usm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/src/misc/snmp_verbosity.erl b/lib/snmp/src/misc/snmp_verbosity.erl
index f27c31db03..edfb52a474 100644
--- a/lib/snmp/src/misc/snmp_verbosity.erl
+++ b/lib/snmp/src/misc/snmp_verbosity.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -69,7 +70,7 @@ print2(_Verbosity,Format,Arguments) ->
timestamp() ->
- format_timestamp(now()).
+ format_timestamp(os:timestamp()).
format_timestamp({_N1, _N2, N3} = Now) ->
{Date, Time} = calendar:now_to_datetime(Now),
@@ -162,4 +163,3 @@ validate(log) -> log;
validate(debug) -> debug;
validate(trace) -> trace;
validate(_) -> silence.
-
diff --git a/lib/snmp/src/misc/snmp_verbosity.hrl b/lib/snmp/src/misc/snmp_verbosity.hrl
index 934d32831f..950b5aa444 100644
--- a/lib/snmp/src/misc/snmp_verbosity.hrl
+++ b/lib/snmp/src/misc/snmp_verbosity.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/src/subdirs.mk b/lib/snmp/src/subdirs.mk
index 1cbcd04b54..e5a437ccfe 100644
--- a/lib/snmp/src/subdirs.mk
+++ b/lib/snmp/src/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/subdirs.mk b/lib/snmp/subdirs.mk
index 850d7d8284..caa4b8baf2 100644
--- a/lib/snmp/subdirs.mk
+++ b/lib/snmp/subdirs.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2003-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile
index a9bbe7fe62..3261982a32 100644
--- a/lib/snmp/test/Makefile
+++ b/lib/snmp/test/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1997-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/test/exp/snmp_agent_bl_test.erl b/lib/snmp/test/exp/snmp_agent_bl_test.erl
index 263319aa5d..186a1d0fec 100644
--- a/lib/snmp/test/exp/snmp_agent_bl_test.erl
+++ b/lib/snmp/test/exp/snmp_agent_bl_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/exp/snmp_agent_ms_test.erl b/lib/snmp/test/exp/snmp_agent_ms_test.erl
index 340b95f512..3415fcc8e6 100644
--- a/lib/snmp/test/exp/snmp_agent_ms_test.erl
+++ b/lib/snmp/test/exp/snmp_agent_ms_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/exp/snmp_agent_mt_test.erl b/lib/snmp/test/exp/snmp_agent_mt_test.erl
index 33d104305a..89815e1044 100644
--- a/lib/snmp/test/exp/snmp_agent_mt_test.erl
+++ b/lib/snmp/test/exp/snmp_agent_mt_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/exp/snmp_agent_v1_test.erl b/lib/snmp/test/exp/snmp_agent_v1_test.erl
index 5379d6d8cf..ec243747df 100644
--- a/lib/snmp/test/exp/snmp_agent_v1_test.erl
+++ b/lib/snmp/test/exp/snmp_agent_v1_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/exp/snmp_agent_v2_test.erl b/lib/snmp/test/exp/snmp_agent_v2_test.erl
index dc3d2efbb3..ce95d0b5cd 100644
--- a/lib/snmp/test/exp/snmp_agent_v2_test.erl
+++ b/lib/snmp/test/exp/snmp_agent_v2_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/exp/snmp_agent_v3_test.erl b/lib/snmp/test/exp/snmp_agent_v3_test.erl
index b0bc6384e8..1ba06209b2 100644
--- a/lib/snmp/test/exp/snmp_agent_v3_test.erl
+++ b/lib/snmp/test/exp/snmp_agent_v3_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/klas3.erl b/lib/snmp/test/klas3.erl
index 4cbd852b2d..eb0c41bf77 100644
--- a/lib/snmp/test/klas3.erl
+++ b/lib/snmp/test/klas3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index 1bf08a9729..16a570706a 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/snmp/test/sa.erl b/lib/snmp/test/sa.erl
index fee50c0e8c..3e34fb2328 100644
--- a/lib/snmp/test/sa.erl
+++ b/lib/snmp/test/sa.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_SUITE.erl b/lib/snmp/test/snmp_SUITE.erl
index 6fabf6410f..43f6b1abff 100644
--- a/lib/snmp/test/snmp_SUITE.erl
+++ b/lib/snmp/test/snmp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_agent_mibs_test.erl b/lib/snmp/test/snmp_agent_mibs_test.erl
index f7dae64e3f..a03c2b8534 100644
--- a/lib/snmp/test/snmp_agent_mibs_test.erl
+++ b/lib/snmp/test/snmp_agent_mibs_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_agent_nfilter_test.erl b/lib/snmp/test/snmp_agent_nfilter_test.erl
index f08060cee3..16a9903198 100644
--- a/lib/snmp/test/snmp_agent_nfilter_test.erl
+++ b/lib/snmp/test/snmp_agent_nfilter_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index b4770ad0a9..412d62c6a1 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -426,10 +427,6 @@
-include_lib("snmp/include/snmp_types.hrl").
-include_lib("snmp/src/agent/snmpa_atl.hrl").
-%% -include_lib("snmp/include/SNMP-COMMUNITY-MIB.hrl").
-%% -include_lib("snmp/include/SNMP-VIEW-BASED-ACM-MIB.hrl").
-%% -include_lib("snmp/include/SNMP-USER-BASED-SM-MIB.hrl").
-
-define(klas1, [1,3,6,1,2,1,7]).
-define(klas2, [1,3,6,1,2,1,9]).
@@ -1612,7 +1609,8 @@ app_dir(App) ->
create_local_db_dir(Config) when is_list(Config) ->
?P(create_local_db_dir),
DataDir = snmp_test_lib:lookup(data_dir, Config),
- T = erlang:now(),
+ UName = erlang:unique_integer([positive]),
+ T = {UName, UName, UName},
[As,Bs,Cs] = [integer_to_list(I) || I <- tuple_to_list(T)],
DbDir = filename:join([DataDir, As, Bs, Cs]),
ok = del_dir(DbDir, 3),
@@ -2448,10 +2446,6 @@ mul_cases() ->
].
-%% multiple_reqs_3(_X) ->
-%% {req, [], {conf, init_mul, mul_cases_3(), finish_mul}}.
-
-
mul_cases_2() ->
[
mul_get_2,
@@ -3200,19 +3194,18 @@ v1_get_next_p() ->
%% 4.1.3:2
gn([[tTooBig]]),
io:format("We currently don't handle tooBig correct!!!\n"),
-% ?line ?expect3(tooBig, 0, [{[tTooBig], 'NULL'}]),
+
?line ?expect3(tooBig, 0, any),
%% 4.1.3:3
gn([[tGenErr1]]),
-% ?line expect(40, genErr, 1, [{[tGenErr1], 'NULL'}]),
+
?line ?expect3(genErr, 1, any),
gn([[tGenErr2]]),
-% ?line ?expect3(genErr, 1, [{[tGenErr2], 'NULL'}]),
+
?line ?expect3(genErr, 1, any),
gn([[sysDescr], [tGenErr3]]),
-% ?line ?expect3(genErr, 2, [{[sysDescr], 'NULL'},
-% {[tGenErr3], 'NULL'}]).
+
?line ?expect3(genErr, 2, any).
v1_set_p() ->
@@ -3451,8 +3444,7 @@ v2_set_p() ->
%% Req. OLD-SNMPEA-MIB
table_test() ->
io:format("Testing simple get, next and set on communityTable...~n"),
-%% {[147,214,36,45], "public", 2, readWrite}.
-%% {[147,214,36,45], "standard trap", 2, read}.
+
Key1c3 = [intCommunityViewIndex,get(mip),is("public")],
Key2c3 = [intCommunityViewIndex,get(mip),is("standard trap")],
Key1c4 = [intCommunityAccess,get(mip),is("public")],
@@ -3620,8 +3612,6 @@ notify(Pid, What) ->
%% Req: system group, OLD-SNMPEA-MIB, Klas1
big_test() ->
- %% put(sname, {?MODULE, big_test}),
- %% put(verbosity, trace),
?DBG("big_test -> testing simple next/get/set @ master agent...",[]),
simple_standard_test(),
@@ -5691,8 +5681,7 @@ loop_mib_1(suite) -> [];
loop_mib_1(Config) when is_list(Config) ->
?P(loop_mib_1),
?LOG("loop_mib_1 -> initiate case",[]),
- %% snmpa:verbosity(master_agent,debug),
- %% snmpa:verbosity(mib_server,info),
+
{_SaNode, _MgrNode, _MibDir} = init_case(Config),
?DBG("loop_mib_1 -> ~n"
"\tSaNode: ~p~n"
@@ -6643,7 +6632,6 @@ otp8395({init, Config}) when is_list(Config) ->
%%
{ok, AgentNode} = start_node(agent),
- %% {ok, SubAgentNode} = start_node(sub_agent),
{ok, ManagerNode} = start_node(manager),
%% --
@@ -6654,16 +6642,9 @@ otp8395({init, Config}) when is_list(Config) ->
AgentMnesiaDir = join([AgentDbDir, "mnesia"]),
mnesia_init(AgentNode, AgentMnesiaDir),
- %% SubAgentDir = ?config(sub_agent_dir, Config),
- %% SubAgentMnesiaDir = join([SubAgentDir, "mnesia"]),
- %% mnesia_init(SubAgentNode, SubAgentMnesiaDir),
-
- %% ok = mnesia_create_schema(AgentNode, [AgentNode, SubAgentNode]),
- %% ok = mnesia:create_schema([AgentNode, SubAgentNode]),
mnesia_create_schema(AgentNode, [AgentNode]),
mnesia_start(AgentNode),
- %% mnesia_start(SubAgentNode),
%% --
%% Host & IP
@@ -6749,11 +6730,6 @@ otp8395({fin, Config}) when is_list(Config) ->
?DBG("otp8395(fin) -> stop agent node", []),
stop_node(AgentNode),
-
- %% SubAgentNode = ?config(sub_agent_node, Config),
- %% stop_node(SubAgentNode),
-
-
%% -
%% Stop the manager node
%%
@@ -6970,20 +6946,6 @@ process_options(Defaults, _Opts) ->
%% process_options(Defaults, Opts, []).
Defaults.
-%% process_options([], _Opts, Acc) ->
-%% lists:reverse(Acc);
-%% process_options([{Key, DefaultValue}|Defaults], Opts, Acc) ->
-%% case lists:keysearch(Key, 1, Opts) of
-%% {value, {Key, Value}} when is_list->
-
-
-%% snmp_app_env_init(Node, Entity, Conf) ->
-%% rpc:call(Node, snmp_app_env_init, [Entity, Conf]).
-
-%% snmp_app_env_init(Entity, Conf) ->
-%% application:unload(snmp),
-%% application:load(snmp),
-%% application:set_env(snmp, Entity, Conf).
start_stdalone_agent(Node, Config) ->
rpc:call(Node, ?MODULE, start_stdalone_agent, [Config]).
@@ -7063,9 +7025,6 @@ do_info(MaNode) ->
tree_size_bytes,
db_memory]}],
verify_info(Info, Keys),
- %% OldInfo = snmpa:old_info_format(Info),
- %% ?DBG("info_test1 -> OldInfo: ~n~p", [OldInfo]),
- %% verify_old_info(OldInfo),
ok.
verify_info([], []) ->
@@ -7107,21 +7066,6 @@ verify_subinfo(Info0, [Key|Keys]) ->
Info ->
verify_subinfo(Info, Keys)
end.
-
-%% verify_old_info(Info) ->
-%% Keys = [vsns, subagents, loaded_mibs,
-%% tree_size_bytes, process_memory, db_memory],
-%% verify_old_info(Keys, Info).
-
-%% verify_old_info([], _) ->
-%% ok;
-%% verify_old_info([Key|Keys], Info) ->
-%% case lists:keymember(Key, 1, Info) of
-%% true ->
-%% verify_old_info(Keys, Info);
-%% false ->
-%% ?FAIL({missing_old_info, Key})
-%% end.
%% Index String - string used in index
is(S) -> [length(S) | S].
@@ -7184,8 +7128,6 @@ rewrite_usm_mgr(Dir, ShaKey, DesKey) ->
reset_usm_mgr(Dir) ->
snmp_agent_test_lib:reset_usm_mgr(Dir).
-%% update_community(Vsns, Dir) ->
-%% snmp_agent_test_lib:update_community(Vsns, Dir).
update_vacm(Vsn, Dir) ->
snmp_agent_test_lib:update_vacm(Vsn, Dir).
@@ -7196,8 +7138,6 @@ write_community_conf(Dir, Conf) ->
write_target_addr_conf(Dir, Conf) ->
snmp_agent_test_lib:write_target_addr_conf(Dir, Conf).
-%% write_target_addr_conf(Dir, ManagerIp, UDP, Vsns) ->
-%% snmp_agent_test_lib:write_target_addr_conf(Dir, ManagerIp, UDP, Vsns).
rewrite_target_addr_conf(Dir, NewPort) ->
snmp_agent_test_lib:rewrite_target_addr_conf(Dir, NewPort).
@@ -7218,10 +7158,6 @@ reset_target_params_conf(Dir) ->
write_notify_conf(Dir) ->
snmp_agent_test_lib:write_notify_conf(Dir).
-%% write_view_conf(Dir) ->
-%% snmp_agent_test_lib:write_view_conf(Dir).
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
copy_file(From, To) ->
@@ -7381,9 +7317,6 @@ lists_key1search(Key, List) when is_atom(Key) ->
end.
-%% regs() ->
-%% lists:sort(registered()).
-
%% ------
join(Parts) ->
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 333fe6eb66..8ea7b2e081 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_app_test.erl b/lib/snmp/test/snmp_app_test.erl
index 9b13e7cf1a..3b5b196ad6 100644
--- a/lib/snmp/test/snmp_app_test.erl
+++ b/lib/snmp/test/snmp_app_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -32,8 +33,6 @@
modules/1,
exportall/1,
app_depend/1,
- undef_funcs/1,
-
start_and_stop_empty/1,
start_and_stop_with_agent/1,
@@ -59,7 +58,6 @@ all() ->
modules,
exportall,
app_depend,
- undef_funcs,
{group, start_and_stop}
],
Cases.
@@ -131,9 +129,6 @@ end_per_suite(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test server callbacks
-init_per_testcase(undef_funcs, Config) ->
- Config2 = lists:keydelete(watchdog, 1, Config),
- [{watchdog, ?WD_START(?MINS(10))} | Config2];
init_per_testcase(_Case, Config) ->
Config.
@@ -293,88 +288,6 @@ check_apps([App|Apps]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-undef_funcs(suite) ->
- [];
-undef_funcs(doc) ->
- [];
-undef_funcs(Config) when is_list(Config) ->
- App = snmp,
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
- Root = code:root_dir(),
- LibDir = code:lib_dir(App),
- EbinDir = filename:join([LibDir,"ebin"]),
- XRefTestName = undef_funcs_make_name(App, xref_test_name),
- {ok, XRef} = xref:start(XRefTestName),
- ok = xref:set_default(XRef,
- [{verbose,false},{warnings,false}]),
- XRefName = undef_funcs_make_name(App, xref_name),
- {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}),
- {ok, App} = xref:replace_application(XRef, App, EbinDir),
- {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
- xref:stop(XRef),
- analyze_undefined_function_calls(Undefs, Mods, []).
-
-valid_undef(crypto = CalledMod) ->
- case (catch CalledMod:version()) of
- Version when is_list(Version) ->
- %% The called module was crypto and the version
- %% function returns a valid value.
- %% This means that the function is
- %% actually undefined...
- true;
- _ ->
- %% The called module was crypto but the version
- %% function does *not* return a valid value.
- %% This means the crypto was not actually not
- %% build, which is an case snmp handles.
- false
- end;
-valid_undef(_) ->
- true.
-
-
-analyze_undefined_function_calls([], _, []) ->
- ok;
-analyze_undefined_function_calls([], _, AppUndefs) ->
- exit({suite_failed, {undefined_function_calls, AppUndefs}});
-analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
- AppModules, AppUndefs) ->
- %% Check that this module is our's
- case lists:member(Mod,AppModules) of
- true ->
- {Calling,Called} = AppUndef,
- {Mod1,Func1,Ar1} = Calling,
- {Mod2,Func2,Ar2} = Called,
- %% If the called module is crypto, then we will *not*
- %% fail if crypto is not built (since crypto is actually
- %% not built for all platforms)
- case valid_undef(Mod2) of
- true ->
- io:format("undefined function call: "
- "~n ~w:~w/~w calls ~w:~w/~w~n",
- [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
- analyze_undefined_function_calls(
- Undefs, AppModules, [AppUndef|AppUndefs]);
- false ->
- io:format("skipping ~p (calling ~w:~w/~w)~n",
- [Mod, Mod2, Func2, Ar2]),
- analyze_undefined_function_calls(Undefs,
- AppModules, AppUndefs)
- end;
- false ->
- io:format("dropping ~p~n", [Mod]),
- analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
- end.
-
-%% This function is used simply to avoid cut-and-paste errors later...
-undef_funcs_make_name(App, PostFix) ->
- list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/snmp/test/snmp_appup_mgr.erl b/lib/snmp/test/snmp_appup_mgr.erl
index 6648ce9dbe..c19cffdec1 100644
--- a/lib/snmp/test/snmp_appup_mgr.erl
+++ b/lib/snmp/test/snmp_appup_mgr.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -140,7 +141,7 @@ handle_req(#agent{host = Host, port = Port}, Reqs) ->
{ok, ReqId} = snmpm:ag(?USER_ID, Host, Port, Oids),
p("issued get-request (~w) for: ~s", [ReqId, oid_descs(Descs)]),
ReqTimer = erlang:send_after(?REQ_TIMEOUT, self(), {req_timeout, ReqId}),
- {ReqId, erlang:now(), ReqTimer}.
+ {ReqId, erlang:monotonic_time(micro_seconds), ReqTimer}.
oid_descs([]) ->
[];
@@ -163,7 +164,7 @@ handle_req_timeout(#state{ids = IDs0} = State, ReqId) ->
handle_snmp(#state{ids = IDs0} = S, {error, ReqId, Reason}) ->
case lists:keysearch(ReqId, 1, IDs0) of
{value, {ReqId, T, Ref}} ->
- Diff = timer:now_diff(erlang:now(), T),
+ Diff = erlang:monotonic_time(micro_seconds) - T,
p("SNMP error regarding outstanding request after ~w microsec:"
"~n ReqId: ~w"
"~n Reason: ~w", [Diff, ReqId, Reason]),
@@ -187,7 +188,7 @@ handle_snmp(State, {agent, Addr, Port, SnmpInfo}) ->
handle_snmp(#state{ids = IDs0} = S, {pdu, Addr, Port, ReqId, SnmpResponse}) ->
case lists:keysearch(ReqId, 1, IDs0) of
{value, {ReqId, T, Ref}} ->
- Diff = timer:now_diff(erlang:now(), T),
+ Diff = erlang:monotonic_time(micro_seconds) - T,
p("SNMP pdu regarding outstanding request after ~w microsec:"
"~n ReqId: ~w"
"~n Addr: ~w"
diff --git a/lib/snmp/test/snmp_appup_test.erl b/lib/snmp/test/snmp_appup_test.erl
index 021d42a978..47cbd5fe8c 100644
--- a/lib/snmp/test/snmp_appup_test.erl
+++ b/lib/snmp/test/snmp_appup_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl
index 1840d37dfd..c83c4e0fed 100644
--- a/lib/snmp/test/snmp_compiler_test.erl
+++ b/lib/snmp/test/snmp_compiler_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_conf_test.erl b/lib/snmp/test/snmp_conf_test.erl
index 7f5d11c0e7..1d514cd1d2 100644
--- a/lib/snmp/test/snmp_conf_test.erl
+++ b/lib/snmp/test/snmp_conf_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -117,7 +118,7 @@ check_mandatory(Config) when is_list(Config) ->
{b, mandatory},
{d, {value, 20202}},
{e, {value, "kalle"}}],
- ?line {ok, L1} = verify_mandatory(A1, B1),
+ ?line {ok, _L1} = verify_mandatory(A1, B1),
?DBG("check_mandatory -> L1: ~p", [L1]),
A2 = [{a, hej}, {c, 10}, {d, 10101}, {f, 10.88}],
B2 = [{a, {value, hejsan}},
diff --git a/lib/snmp/test/snmp_log_test.erl b/lib/snmp/test/snmp_log_test.erl
index fb7285110f..b204522ee0 100644
--- a/lib/snmp/test/snmp_log_test.erl
+++ b/lib/snmp/test/snmp_log_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -633,11 +634,11 @@ log_to_txt3(Config) when is_list(Config) ->
log_reader_log_to(Reader,
fun() ->
I = disk_log:info(Log),
- T1 = t(),
+ T1 = snmp_misc:now(ms),
R = snmp_log:log_to_txt(Log, LogFile, Dir,
Mibs, TxtFile),
- T2 = t(),
- io:format(user,
+ T2 = snmp_misc:now(ms),
+ io:format(user,
"Time converting file: ~w ms~n",
[T2 - T1]),
{R, I}
@@ -704,10 +705,10 @@ log_writer_start(Name, File, Size, Repair) ->
log_writer_stop(Pid) ->
Pid ! {stop, self()},
- _T1 = t(),
+ _T1 = snmp_misc:now(ms),
receive
{'EXIT', Pid, normal} ->
- _T2 = t(),
+ _T2 = snmp_misc:now(ms),
?DBG("it took ~w ms to stop the writer", [_T2 - _T1]),
ok
after 60000 ->
@@ -721,10 +722,10 @@ log_writer_info(Pid) ->
log_writer_sleep(Pid, Time) ->
Pid ! {sleep, Time, self()},
- _T1 = t(),
+ _T1 = snmp_misc:now(ms),
receive
{sleeping, Pid} ->
- _T2 = t(),
+ _T2 = snmp_misc:now(ms),
?DBG("it took ~w ms to put the writer to sleep", [_T2 - _T1]),
ok;
{'EXIT', Pid, Reason} ->
@@ -793,10 +794,10 @@ lp(F, A) ->
log_reader_start() ->
Pid = spawn_link(?MODULE, log_reader_main, [self()]),
- _T1 = t(),
+ _T1 = snmp_misc:now(ms),
receive
{started, Pid} ->
- _T2 = t(),
+ _T2 = snmp_misc:now(ms),
?DBG("it took ~w ms to start the reader", [_T2 - _T1]),
{ok, Pid};
{'EXIT', Pid, Reason} ->
@@ -807,10 +808,10 @@ log_reader_start() ->
log_reader_stop(Pid) ->
Pid ! {stop, self()},
- _T1 = t(),
+ _T1 = snmp_misc:now(ms),
receive
{'EXIT', Pid, normal} ->
- _T2 = t(),
+ _T2 = snmp_misc:now(ms),
?DBG("it took ~w ms to put the reader to eleep", [_T2 - _T1]),
ok
after 1000 ->
@@ -1124,8 +1125,3 @@ join(D, F) ->
p(Case) ->
io:format(user, "test case: ~w~n", [Case]).
-
-%% Time in milli sec
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl
index f37e957dae..47e150e8e8 100644
--- a/lib/snmp/test/snmp_manager_config_test.erl
+++ b/lib/snmp/test/snmp_manager_config_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -2169,7 +2170,6 @@ register_usm_user_using_function(Conf) when is_list(Conf) ->
%% --
p("done"),
ok.
-%% ?SKIP(not_yet_implemented).
%%
@@ -2259,8 +2259,9 @@ create_and_increment(Conf) when is_list(Conf) ->
?line {ok, _Pid} = snmpm_config:start_link(Opts),
%% Random init
- {A,B,C} = erlang:now(),
- random:seed(A,B,C),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
StartVal = random:uniform(2147483647),
IncVal = 42,
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index fa90872172..3d05e5791f 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_manager_user.erl b/lib/snmp/test/snmp_manager_user.erl
index 46c2b316be..256ea6a834 100644
--- a/lib/snmp/test/snmp_manager_user.erl
+++ b/lib/snmp/test/snmp_manager_user.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_manager_user_old.erl b/lib/snmp/test/snmp_manager_user_old.erl
index d5ffabee0b..0f0f026eca 100644
--- a/lib/snmp/test/snmp_manager_user_old.erl
+++ b/lib/snmp/test/snmp_manager_user_old.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_manager_user_test.erl b/lib/snmp/test/snmp_manager_user_test.erl
index 2633793bce..a0cdcdef4d 100644
--- a/lib/snmp/test/snmp_manager_user_test.erl
+++ b/lib/snmp/test/snmp_manager_user_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_manager_user_test_lib.erl b/lib/snmp/test/snmp_manager_user_test_lib.erl
index bf8fff7c4c..a547f78efb 100644
--- a/lib/snmp/test/snmp_manager_user_test_lib.erl
+++ b/lib/snmp/test/snmp_manager_user_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_note_store_test.erl b/lib/snmp/test/snmp_note_store_test.erl
index 24ba88f986..902d37b0d7 100644
--- a/lib/snmp/test/snmp_note_store_test.erl
+++ b/lib/snmp/test/snmp_note_store_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_pdus_test.erl b/lib/snmp/test/snmp_pdus_test.erl
index 7d649b1dad..bfbd031646 100644
--- a/lib/snmp/test/snmp_pdus_test.erl
+++ b/lib/snmp/test/snmp_pdus_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl
index 5e611340a3..290f1bc31a 100644
--- a/lib/snmp/test/snmp_test_lib.erl
+++ b/lib/snmp/test/snmp_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,7 @@
lookup/2,
replace_config/3, set_config/3, get_config/2, get_config/3]).
-export([fail/3, skip/3]).
--export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]).
+-export([hours/1, minutes/1, seconds/1, sleep/1]).
-export([flush_mqueue/0, trap_exit/0, trap_exit/1]).
-export([ping/1, local_nodes/0, nodes_on/1]).
-export([start_node/2]).
@@ -334,14 +335,6 @@ skip(Reason, Module, Line) ->
%% Time related function
%%
-millis() ->
- erlang:now().
-
-millis_diff(A,B) ->
- T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000),
- T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000),
- T1 - T2.
-
hours(N) -> trunc(N * 1000 * 60 * 60).
minutes(N) -> trunc(N * 1000 * 60).
seconds(N) -> trunc(N * 1000).
@@ -628,4 +621,3 @@ format_timestamp({_N1, _N2, N3} = Now) ->
io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w ~w",
[YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
lists:flatten(FormatDate).
-
diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl
index 9b7609b831..7acebee1f1 100644
--- a/lib/snmp/test/snmp_test_lib.hrl
+++ b/lib/snmp/test/snmp_test_lib.hrl
@@ -1,21 +1,22 @@
-%%<copyright>
-%% <year>2002-2014</year>
-%% <holder>Ericsson AB, All Rights Reserved</holder>
-%%</copyright>
-%%<legalnotice>
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-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.
%%
%% The Initial Developer of the Original Code is Ericsson AB.
-%%</legalnotice>
+%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% Purpose: Define common macros for testing
@@ -73,8 +74,6 @@
-endif.
-define(SLEEP(MSEC), snmp_test_lib:sleep(MSEC)).
--define(M(), snmp_test_lib:millis()).
--define(MDIFF(A,B), snmp_test_lib:millis_diff(A,B)).
%% - Process utility macros -
@@ -149,4 +148,3 @@
-define(PRINT(P,F,A),
snmp_test_lib:print(P,?MODULE,?LINE,F,A)).
-
diff --git a/lib/snmp/test/snmp_test_manager.erl b/lib/snmp/test/snmp_test_manager.erl
index 6d8673eecd..294f0e8240 100644
--- a/lib/snmp/test/snmp_test_manager.erl
+++ b/lib/snmp/test/snmp_test_manager.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl
index 8cb6ec588e..36637d5cf4 100644
--- a/lib/snmp/test/snmp_test_mgr.erl
+++ b/lib/snmp/test/snmp_test_mgr.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -188,8 +189,9 @@ receive_trap(Timeout) ->
init({Options, CallerPid}) ->
put(sname, mgr),
put(verbosity, debug),
- {A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer()),
case (catch is_options_ok(Options)) of
true ->
put(debug, get_value(debug, Options, false)),
@@ -1135,4 +1137,3 @@ d(_,_F,_A) ->
formated_timestamp() ->
snmp_test_lib:formated_timestamp().
-
diff --git a/lib/snmp/test/snmp_test_mgr_counter_server.erl b/lib/snmp/test/snmp_test_mgr_counter_server.erl
index db31e0380b..a72eefd6e5 100644
--- a/lib/snmp/test/snmp_test_mgr_counter_server.erl
+++ b/lib/snmp/test/snmp_test_mgr_counter_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl
index 5274dcacd9..0a0e3be9aa 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_test_server.erl b/lib/snmp/test/snmp_test_server.erl
index ffbd2126a3..8b22d6943a 100644
--- a/lib/snmp/test/snmp_test_server.erl
+++ b/lib/snmp/test/snmp_test_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_test_suite.erl b/lib/snmp/test/snmp_test_suite.erl
index 77aaa508ad..07c93d062c 100644
--- a/lib/snmp/test/snmp_test_suite.erl
+++ b/lib/snmp/test/snmp_test_suite.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
index 2f96493ac5..95f4a7518b 100644
--- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper
index f806ab5c12..8bd8e1ab4a 100755
--- a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2014-2014. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/lib/snmp/test/test1.erl b/lib/snmp/test/test1.erl
index 23cfaf6aaa..82555af11f 100644
--- a/lib/snmp/test/test1.erl
+++ b/lib/snmp/test/test1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/test2.erl b/lib/snmp/test/test2.erl
index a33208af7b..2bfae95c8d 100644
--- a/lib/snmp/test/test2.erl
+++ b/lib/snmp/test/test2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/snmp/test/test_config/Makefile b/lib/snmp/test/test_config/Makefile
index d65bb8abe2..6e78350e9f 100644
--- a/lib/snmp/test/test_config/Makefile
+++ b/lib/snmp/test/test_config/Makefile
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/lib/snmp/test/test_config/modules.mk b/lib/snmp/test/test_config/modules.mk
index 3d084cef01..64244be7fe 100644
--- a/lib/snmp/test/test_config/modules.mk
+++ b/lib/snmp/test/test_config/modules.mk
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2004-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/lib/snmp/test/test_config/snmp_test_config.erl b/lib/snmp/test/test_config/snmp_test_config.erl
index 550a276c4c..80fac0c772 100644
--- a/lib/snmp/test/test_config/snmp_test_config.erl
+++ b/lib/snmp/test/test_config/snmp_test_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 67adf0a34f..f60cbbfaa7 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -4,20 +4,21 @@
#
# Copyright Ericsson AB 1997-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
APPLICATION = snmp
-SNMP_VSN = 5.1.2
+SNMP_VSN = 5.2.2
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/ssh/Makefile b/lib/ssh/Makefile
index b8c7eebcc1..839aada22f 100644
--- a/lib/ssh/Makefile
+++ b/lib/ssh/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile
index 0e79d9979f..c0707f8004 100644
--- a/lib/ssh/doc/src/Makefile
+++ b/lib/ssh/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/ssh/doc/src/book.xml b/lib/ssh/doc/src/book.xml
index c031d872d7..33b1e0036b 100644
--- a/lib/ssh/doc/src/book.xml
+++ b/lib/ssh/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ssh/doc/src/introduction.xml b/lib/ssh/doc/src/introduction.xml
index b42910cb34..187d458092 100644
--- a/lib/ssh/doc/src/introduction.xml
+++ b/lib/ssh/doc/src/introduction.xml
@@ -9,47 +9,198 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>Introduction</title>
<prepared>OTP team</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>introduction.xml</file>
</header>
-
+ <p>SSH is a protocol for secure remote logon and
+ other secure network services over an insecure network.</p>
<section>
- <title>Purpose</title>
+ <title>Scope and Purpose</title>
- <p>Secure Shell (SSH) is a protocol for secure remote login and
- other secure network services over an insecure network. SSH
- provides a single, full-duplex, byte-oriented connection between
+ <p>SSH provides a single, full-duplex, and byte-oriented connection between
client and server. The protocol also provides privacy, integrity,
- server authentication and man-in-the-middle protection.</p>
-
- <p>The Erlang SSH application is an implementation of the SSH
- protocol in Erlang which offers API functions to write customized
- SSH clients and servers as well as making the Erlang shell
- available via SSH. Also included in the SSH application are an
- SFTP (SSH File Transfer Protocol) client <seealso
- marker="ssh_sftp">ssh_sftp</seealso> and server <seealso
- marker="ssh_sftp">ssh_sftpd</seealso>.</p>
+ server authentication, and man-in-the-middle protection.</p>
+
+ <p>The <c>ssh</c> application is an implementation of the SSH Transport, Connection and Authentication
+ Layer Protocols in Erlang. It provides the following:</p>
+ <list type="bulleted">
+ <item>API functions to write customized SSH clients and servers applications</item>
+ <item>The Erlang shell available over SSH</item>
+ <item>An SFTP client (<seealso marker="ssh_sftp">ssh_sftp</seealso>)
+ and server (<seealso marker="ssh_sftp">ssh_sftpd</seealso>)</item>
+ </list>
</section>
<section>
<title>Prerequisites</title>
- <p>It is assumed that the reader is familiar with the concepts of <seealso marker="doc/design_principles:des_princ">OTP</seealso>
- and has a basic understanding of <url href="http://en.wikipedia.org/wiki/Public-key_cryptography">public keys</url>.</p>
+ <p>It is assumed that the reader is familiar with the Erlang programming language,
+ concepts of <em>OTP</em>, and has a basic understanding of <em>public keys</em>.</p>
+ </section>
+
+<section>
+ <title>SSH Protocol Overview</title>
+
+ <p>Conceptually, the SSH protocol can be partitioned into four
+ layers:</p>
+
+ <image file="SSH_protocols.png">
+ <icaption>SSH Protocol Architecture</icaption>
+ </image>
+
+ <section>
+ <title>Transport Protocol</title>
+
+ <p>The SSH Transport Protocol is a secure, low-level transport.
+ It provides strong encryption, cryptographic host
+ authentication, and integrity protection. A minimum of
+ Message Authentication Code (MAC) and encryption
+ algorithms are supported. For details, see the
+ <seealso marker="ssh">ssh(3)</seealso> manual page in <c>ssh</c>.</p>
+ </section>
+
+ <section>
+ <title>Authentication Protocol</title>
+
+ <p>The SSH Authentication Protocol is a general-purpose user
+ authentication protocol run over the SSH Transport Layer
+ Protocol. The <c>ssh</c> application supports user authentication as follows:
+ </p>
+ <list type="bulleted">
+ <item>
+ Using public key technology. RSA and DSA, X509-certificates
+ are not supported.
+ </item>
+ <item>
+ Using keyboard-interactive authentication.
+ This is suitable for interactive authentication methods
+ that do not need any special software support on the client side.
+ Instead, all authentication data is entered from the keyboard.
+ </item>
+ <item>
+ Using a pure password-based authentication scheme.
+ Here, the plain text password is encrypted before sent
+ over the network.
+ </item>
+ </list>
+ <p>Several configuration options for
+ authentication handling are available in
+ <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso>
+ and <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</p>
+ <p>
+ The public key handling can be customized by implementing
+ the following behaviours from <c>ssh</c>:</p>
+ <list type="bulleted">
+ <item>Module
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso>.
+ </item>
+ <item>Module
+ <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Connection Protocol</title>
+
+ <p>The SSH Connection Protocol provides application-support
+ services over the transport pipe, for example, channel multiplexing,
+ flow control, remote program execution, signal propagation, and
+ connection forwarding. Functions for handling the SSH
+ Connection Protocol can be found in the module <seealso
+ marker="ssh_connection">ssh_connection</seealso> in <c>ssh</c>.
+ </p>
+ </section>
+
+ <section>
+ <title>Channels</title>
+
+ <p>All terminal sessions, forwarded connections, and so on, are
+ channels. Multiple channels are multiplexed into a single
+ connection. All channels are flow-controlled. This means that no
+ data is sent to a channel peer until a message is received to
+ indicate that window space is available.
+ The <em>initial window size</em> specifies how many bytes of channel
+ data that can be sent to the channel peer without adjusting the
+ window. Typically, an SSH client opens a channel, sends data (commands),
+ receives data (control information), and then closes the channel.
+ The <seealso marker="ssh_channel">ssh_channel</seealso> behaviour
+ handles generic parts of SSH channel management. This makes it easy
+ to write your own SSH client/server processes that use flow-control
+ and thus opens for more focus on the application logic.
+ </p>
+
+ <p>Channels come in the following three flavors:</p>
+
+ <list type="bulleted">
+ <item><em>Subsystem</em> - Named services that can be run as
+ part of an SSH server, such as SFTP <seealso
+ marker="ssh_sftpd">(ssh_sftpd)</seealso>, that is built into the
+ SSH daemon (server) by default, but it can be disabled. The Erlang <c>ssh</c>
+ daemon can be configured to run any Erlang-
+ implemented SSH subsystem.
+ </item>
+ <item><em>Shell</em> - Interactive shell. By default the
+ Erlang daemon runs the Erlang shell. The shell can be customized by
+ providing your own read-eval-print loop. You can also provide your
+ own Command-Line Interface (CLI) implementation,
+ but that is much more work.
+ </item>
+ <item><em>Exec</em> - One-time remote execution of commands. See function
+ <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>
+ for more information.</item>
+ </list>
+ </section>
+
+
+
</section>
+ <section>
+ <title>Where to Find More Information</title>
+ <p>
+ For detailed information about the SSH protocol, refer to the
+ following Request for Comments(RFCs):
+ </p>
+
+ <list type="bulleted">
+ <item><url href="http://www.ietf.org/rfc/rfc4250.txt">RFC 4250</url> -
+ Protocol Assigned Numbers</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4251.txt">RFC 4251</url> -
+ Protocol Architecture</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4252.txt">RFC 4252</url> -
+ Authentication Protocol</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4253.txt">RFC 4253</url> -
+ 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> -
+ Public Key File Format</item>
+ </list>
+ </section>
</chapter>
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index c77ee1e77a..5f2cd19cda 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2014</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,6 +30,584 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Documentation correction of <c>ssh_sftp:position/4</c></p>
+ <p>
+ Thanks to Rabbe Fogelholm.</p>
+ <p>
+ Own Id: OTP-13305 Aux Id: ERL-87 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The authentication method 'keyboard-interactive' failed
+ in the Erlang client when the server after successful
+ authentication continued by asking for zero more
+ passwords.</p>
+ <p>
+ Own Id: OTP-13225</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Better error handling in ssh_file. There was some rare
+ errors when a NFS-mounted file was opened by ssh_file and
+ then remotely deleted during reading. That caused an
+ endless loop. </p>
+ <p>
+ That bug is now fixed.</p>
+ <p>
+ Own Id: OTP-12699 Aux Id: OTP-11688 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug in the compression algorithm
+ <p>
+ Own Id: OTP-12759</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to start more than one daemon with a
+ file descriptor given in option fd. Each daemon must of
+ course have a unique file descriptor.</p>
+ <p>
+ Own Id: OTP-12966 Aux Id: seq12945 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug that caused the option <c>dh_gex_limit</c> to
+ be ignored.</p>
+ <p>
+ Own Id: OTP-13029</p>
+ </item>
+ <item>
+ <p>
+ A problem is fixed with the <c>ssh:connect</c> option
+ <c>pref_public_key_algs</c> specifying user keys.</p>
+ <p>
+ Own Id: OTP-13158</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Document updates in the ssh reference manual: app doc
+ file and ssh_connection.</p>
+ <p>
+ Own Id: OTP-12003</p>
+ </item>
+ <item>
+ <p>
+ The authorization phase is made stateful to prevent ssh
+ acting on messages sent in wrong order.</p>
+ <p>
+ Own Id: OTP-12787</p>
+ </item>
+ <item>
+ <p>
+ Testcases for bad message lengths and for bad subfield
+ lengths added.</p>
+ <p>
+ Own Id: OTP-12792 Aux Id: Codenomicon #5214, 6166 </p>
+ </item>
+ <item>
+ <p>
+ The 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384' and
+ 'ecdsa-sha2-nistp521' signature algorithms for ssh are
+ implemented. See RFC 5656.</p>
+ <p>
+ Own Id: OTP-12936</p>
+ </item>
+ <item>
+ <p>
+ The crypto algorithms 'aes192-ctr' and 'aes256-ctr' are
+ implemented. See RFC 4344.</p>
+ <p>
+ Own Id: OTP-12939</p>
+ </item>
+ <item>
+ <p>
+ The ciphers and macs AEAD_AES_128_GCM and
+ AEAD_AES_256_GCM are implemented but not enabled per
+ default. See the SSH App Reference Manual and RFC5647 for
+ details.</p>
+ <p>
+ The ciphers [email protected] and
+ [email protected] are also implemented and available
+ in the default configuration.</p>
+ <p>
+ Own Id: OTP-13018</p>
+ </item>
+ <item>
+ <p>
+ The ssh:daemon option dh_gex_groups is extended to read a
+ user provided ssh moduli file with generator-modulus
+ pairs. The file is in openssh format.</p>
+ <p>
+ Own Id: OTP-13052 Aux Id: OTP-13054 </p>
+ </item>
+ <item>
+ <p>
+ There is now a file (public_key/priv/moduli) which lists
+ size-generator-modulus triples. The purpose is to give
+ servers the possibility to select the crypto primes
+ randomly among a list of pregenerated triples. This
+ reduces the risk for some attacks on diffie-hellman
+ negotiation.</p>
+ <p>
+ See the reference manual for public_key:dh_gex_group/4
+ where the handling of this is described.</p>
+ <p>
+ The ssh server (ssh:daemon) uses this.</p>
+ <p>
+ Own Id: OTP-13054 Aux Id: OTP-13052 </p>
+ </item>
+ <item>
+ <p>
+ The ssh:daemon option pwdfun now also takes a fun/4. This
+ enables the user to 1) check userid-password in another
+ way than the builtin algorithm, 2) implement rate
+ limiting per user or source IP or IP+Port, and 3)
+ implement blocking of missbehaving peers.</p>
+ <p>
+ The old fun/2 still works as previously.</p>
+ <p>
+ Own Id: OTP-13055 Aux Id: OTP-13053 </p>
+ </item>
+ <item>
+ <p>
+ There is now a new option to make the server limit the
+ size range of moduli available for the diffie-hellman
+ group exchange negotiation. See option <c>
+ {dh_gex_limits,{Min,Max}}</c> in ssh:daemon/3.</p>
+ <p>
+ Own Id: OTP-13066</p>
+ </item>
+ <item>
+ <p>
+ Ecdh key exchange now validates compressed and
+ uncompressed keys as defined in rfc5656</p>
+ <p>
+ Own Id: OTP-13067</p>
+ </item>
+ <item>
+ <p>
+ Search order for the .ssh directory are changed so
+ <c>$HOME</c> is tried before
+ <c>init:get_argument(home)</c>.</p>
+ <p>
+ Own Id: OTP-13109</p>
+ </item>
+ <item>
+ <p>
+ The sftp receive window handling is optimized so it will
+ not update the remote end too often. This makes "sftp
+ mget" considerable faster.</p>
+ <p>
+ Own Id: OTP-13130</p>
+ </item>
+ <item>
+ <p>
+ The option <c>key_cb</c> is extended to take an optional
+ list that is passed to the callback module as an option.
+ With this it is possible to have different keys depending
+ on which host that is connected. Another possibility is
+ to write a callback module that fetches keys etc from a
+ database.</p>
+ <p>
+ Thanks to Vipin Nair.</p>
+ <p>
+ Own Id: OTP-13156</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.3</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ SSH_MSG_KEX_DH_GEX_REQUEST_OLD implemented to make PuTTY
+ work with erl server.</p>
+ <p>
+ Own Id: OTP-13140</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add a 1024 group to the list of key group-exchange groups</p>
+ <p>
+ Own Id: OTP-13046</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A new option <c>max_channels</c> limits the number of
+ channels with active server-side subsystems that are
+ accepted.</p>
+ <p>
+ Own Id: OTP-13036</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Send an understandable disconnect message when the key
+ exchange phase can't find a common algorithm. There are
+ also some test cases added.</p>
+ <p>
+ Own Id: OTP-11531</p>
+ </item>
+ <item>
+ <p>
+ The third parameter in <c>ssh_sftp:write_file</c> is now
+ accepting iolists again. Unicode handling adjusted.</p>
+ <p>
+ Own Id: OTP-12853 Aux Id: seq12891 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ First part of ssh test suite re-organization and
+ extension.</p>
+ <p>
+ Own Id: OTP-12230</p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithms 'ecdh-sha2-nistp256',
+ 'ecdh-sha2-nistp384' and 'ecdh-sha2-nistp521' are
+ implemented. See RFC 5656.</p>
+ <p>
+ This raises the security level considerably.</p>
+ <p>
+ Own Id: OTP-12622 Aux Id: OTP-12671, OTP-12672 </p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithm 'diffie-hellman-group14-sha1'
+ is implemented. See RFC 4253.</p>
+ <p>
+ This raises the security level.</p>
+ <p>
+ Own Id: OTP-12671 Aux Id: OTP-12672, OTP-12622 </p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithms
+ 'diffie-hellman-group-exchange-sha1' and
+ 'diffie-hellman-group-exchange-sha256' are implemented.
+ See RFC 4419.</p>
+ <p>
+ This raises the security level.</p>
+ <p>
+ Own Id: OTP-12672 Aux Id: OTP-12671, OTP-12622 </p>
+ </item>
+ <item>
+ <p>
+ Adding random length extra padding as recommended in RFC
+ 4253 section 6.</p>
+ <p>
+ Own Id: OTP-12831</p>
+ </item>
+ <item>
+ <p>
+ New test library for low-level protocol testing. There is
+ also a test suite using it for some preliminary tests.
+ The intention is to build on that for more testing of
+ individual ssh messages. See
+ <c>lib/ssh/test/ssh_trpt_test_lib.erl</c> and
+ <c>ssh_protocol_SUITE.erl</c> in the same directory.</p>
+ <p>
+ Own Id: OTP-12858</p>
+ </item>
+ <item>
+ <p>
+ Increased default values for
+ diffie-hellman-group-exchange-sha* to Min = 1024, N =
+ 6144, Max = 8192.</p>
+ <p>
+ Added 6144 and 8192 bit default gex groups.</p>
+ <p>
+ Own Id: OTP-12937</p>
+ </item>
+ <item>
+ <p>
+ The mac algorithm 'hmac-sha2-512' is implemented. See RFC
+ 6668.</p>
+ <p>
+ Own Id: OTP-12938</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Ssh crashed if a message was sent on a channel with
+ packet_size = 0.</p>
+ <p>
+ A new option for ssh:daemon is also introduced:
+ <c>minimal_remote_max_packet_size</c>. This option sets
+ the least max packet size declaration that the daemon
+ will accept from a client. The default value is 0 to
+ maintain compatibility with OpenSSH and the rfc:s.</p>
+ <p>
+ Own Id: OTP-12645 Aux Id: seq12816 </p>
+ </item>
+ <item>
+ <p>
+ Included test of the 'e' and 'f' parameters in
+ diffie-hellman key exchange as specified in rfc 4253
+ section 8.</p>
+ <p>
+ Own Id: OTP-12649</p>
+ </item>
+ <item>
+ <p>
+ Fixes the bug that once the <c>rekey_limit</c> bytes (by
+ default, 1GB) had been transmitted the connection was
+ rekeyed every minute, not after the next transferred
+ 'rekey_limit' chunk.</p>
+ <p>
+ Thanks to Simon Cornish for the report and the fix!</p>
+ <p>
+ Own Id: OTP-12692</p>
+ </item>
+ <item>
+ <p>
+ Fixes a bug that causes an SFTP connection to always fail
+ when {timeout, Timeout} option is used with
+ ssh_sftp:start_channel.</p>
+ <p>
+ Thanks to Simon Cornish</p>
+ <p>
+ Own Id: OTP-12708</p>
+ </item>
+ <item>
+ <p>
+ Fix various ssh key exchange problems.</p>
+ <p>
+ Thanks to Simon Cornish</p>
+ <p>
+ Own Id: OTP-12760 Aux Id: <url
+ href="https://github.com/erlang/otp/pull/715">pull req
+ 715</url> </p>
+ </item>
+ <item>
+ <p>
+ The options <c>system_dir</c> and <c>user_dir</c> assumes
+ that the value is a path to a directory which is
+ readable. This is now checked early, so <c>ssh:daemon</c>
+ and <c>ssh:connect</c> will fail with an error message
+ immediately.</p>
+ <p>
+ Own Id: OTP-12788</p>
+ </item>
+ <item>
+ <p>
+ A daemon now checks that a client doesn't try to
+ authorize with methods not in the option auth_methods.</p>
+ <p>
+ Own Id: OTP-12790</p>
+ </item>
+ <item>
+ <p>
+ Disconnectfun now should trigger on all disconnects.</p>
+ <p>
+ Own Id: OTP-12811</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Better usage of binary matching in ssh_auth.erl and
+ ssh_message.erl</p>
+ <p>
+ Own Id: OTP-11697</p>
+ </item>
+ <item>
+ <p>
+ A new option 'preferred_algorithms' is available for
+ <c>ssh:daemon</c> and <c>ssh:connect</c>.</p>
+ <p>
+ This option defines the algorithms presented to the peer
+ in the algorithm negotiation phase of the ssh protocol. </p>
+ <p>
+ The default list can be obtained from the new function
+ <c>ssh:default_algorithms/0</c>.</p>
+ <p>
+ *** INCOMPATIBILITY with removed undocumented options
+ 'role' and 'compression' ***</p>
+ <p>
+ Own Id: OTP-12029</p>
+ </item>
+ <item>
+ <p>
+ The internal group to user_drv protocol has been changed
+ to be synchronous in order to guarantee that output sent
+ to a process implementing the user_drv protocol is
+ printed before replying. This protocol is used by the
+ standard_output device and the ssh application when
+ acting as a client. </p>
+ <p>
+ This change changes the previous unlimited buffer when
+ printing to standard_io and other devices that end up in
+ user_drv to 1KB.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12240</p>
+ </item>
+ <item>
+ <p>
+ If ssh_connection:subsystem/4 fails we do not want to
+ crash but rather terminate gracefully.</p>
+ <p>
+ Own Id: OTP-12648 Aux Id: seq12834 </p>
+ </item>
+ <item>
+ <p>
+ New option <c>id_string</c> for <c>ssh:daemon</c> and
+ <c>ssh:connect</c> for limiting banner grabbing attempts.</p>
+ <p>
+ The possible values are: <c>{id_string,string()}</c> and
+ <c>{id_string,random}</c>. The latter will make ssh
+ generate a random nonsence id-string for each new
+ connection.</p>
+ <p>
+ Own Id: OTP-12659</p>
+ </item>
+ <item>
+ <p>
+ To enable the ssh daemon to run in a virtualized
+ environment, where there can be more that one server that
+ has the same ip-address and port, we add a new option
+ profile.</p>
+ <p>
+ Own Id: OTP-12675</p>
+ </item>
+ <item>
+ <p>
+ Upgrade test suite added.</p>
+ <p>
+ Own Id: OTP-12676</p>
+ </item>
+ <item>
+ <p>
+ A new option for handling the SSH_MSG_DEBUG message's
+ printouts. A fun could be given in the options that will
+ be called whenever the SSH_MSG_DEBUG message arrives.
+ This enables the user to format the printout or just
+ discard it.</p>
+ <p>
+ Own Id: OTP-12738 Aux Id: seq12860 </p>
+ </item>
+ <item>
+ <p>
+ Testcase improvements and corrections:</p>
+ <p>
+ * Add testcases for the <c>disconnectfun</c> option on
+ both server and client sides</p>
+ <p>
+ * Timeout testcases adjusted for slow machines where they
+ sometimes failed</p>
+ <p>
+ Own Id: OTP-12786</p>
+ </item>
+ <item>
+ <p>
+ The option <c>disconnectfun</c> can now be used both on
+ the client and server side.</p>
+ <p>
+ Own Id: OTP-12789</p>
+ </item>
+ <item>
+ <p>
+ A new option unknown_msgfun/2 for ssh:connect and
+ ssh:daemon for handling unknown messages. With the option
+ it is possible to intercept before an INFO log message is
+ generated.</p>
+ <p>
+ One usage is to filter out messages that are not wanted
+ in the error logger as info reports. An example of such a
+ message is the 'etimedout' tcp error message that will be
+ received if a connection has keep_alive and the peer is
+ restarted.</p>
+ <p>
+ Own Id: OTP-12813 Aux Id: seq12881 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 3.2.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -41,13 +620,13 @@
</item>
<item>
<p>
- Made Codenomicon Defensics test suite pass: <list>
+ Made Codenomicon Defensics test suite pass:</p> <list>
<item>limit number of algorithms in kexinit
message</item> <item>check 'e' and 'f' parameters in
kexdh</item> <item>implement 'keyboard-interactive' user
authentication on server side</item> <item> return plain
text message to bad version exchange message</item>
- </list></p>
+ </list>
<p>
Own Id: OTP-12784</p>
</item>
diff --git a/lib/ssh/doc/src/part_notes.xml b/lib/ssh/doc/src/part_notes.xml
index c5cc163717..664cadce57 100644
--- a/lib/ssh/doc/src/part_notes.xml
+++ b/lib/ssh/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ssh/doc/src/ref_man.xml b/lib/ssh/doc/src/ref_man.xml
index 55339298e8..4a2f043948 100644
--- a/lib/ssh/doc/src/ref_man.xml
+++ b/lib/ssh/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -28,8 +29,8 @@
<file>ref_man.xml</file>
</header>
<description>
- <p>The SSH application is an erlang implementation of the
- secure shell protocol (SSH) as defined by RFC 4250 - 4254</p>
+ <p>The <c>ssh</c> application is an Erlang implementation of the
+ Secure Shell Protocol (SSH) as defined by RFC 4250 - 4254.</p>
</description>
<xi:include href="ssh_app.xml"/>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index 501668ca78..850557444d 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,72 +4,118 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2014</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssh</title>
+ <prepared></prepared>
+ <docno></docno>
<date>2007-10-06</date>
+ <rev></rev>
</header>
<module>ssh</module>
- <modulesummary>Main API of the SSH application</modulesummary>
+ <modulesummary>Main API of the ssh application</modulesummary>
<description>
- <p>Interface module for the SSH application. </p>
+ <p>Interface module for the <c>ssh</c> application.</p>
+ <p>See <seealso marker="ssh:SSH_app#supported">ssh(6)</seealso> for details of supported version,
+ algorithms and unicode support.</p>
</description>
- <section>
- <title>SSH</title>
-
- <list type="bulleted">
- <item>SSH requires the crypto and public_key applications.</item>
- <item>Supported SSH version is 2.0 </item>
- <item>Supported MAC algorithms: hmac-sha2-256 and hmac-sha1</item>
- <item>Supported encryption algorithms: aes128-ctr, aes128-cb and 3des-cbc</item>
- <item>Supports unicode filenames if the emulator and the underlaying OS supports it. See the DESCRIPTION section in <seealso marker="kernel:file">file</seealso> for information about this subject</item>
- <item>Supports unicode in shell and cli</item>
- </list>
-
+ <section>
+ <title>OPTIONS</title>
+ <p>The exact behaviour of some functions can be adjusted with the use of options which are documented together
+ with the functions. Generally could each option be used at most one time in each function call. If given two or more
+ times, the effect is not predictable unless explicitly documented.</p>
+ <p>The options are of different kinds:</p>
+ <taglist>
+ <tag>Limits</tag>
+ <item><p>which alters limits in the system, for example number of simultaneous login attempts.</p></item>
+
+ <tag>Timeouts</tag>
+ <item><p>which give some defined behaviour if too long time elapses before a given event or action,
+ for example time to wait for an answer.</p></item>
+
+ <tag>Callbacks</tag>
+ <item><p>which gives the caller of the function the possibility to execute own code on some events,
+ for example calling an own logging function or to perform an own login function</p></item>
+
+ <tag>Behaviour</tag>
+ <item><p>which changes the systems behaviour.</p></item>
+ </taglist>
</section>
-
+
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
<p>Type definitions that are used more than once in
- this module and/or abstractions to indicate the intended use of the data
- type:</p>
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = [byte()]</c></p>
- <p><c>ssh_daemon_ref() - opaque to the user
- returned by ssh:daemon/[1,2,3]</c></p>
- <p><c>ssh_connection_ref() - opaque to the user
- returned by ssh:connect/3</c></p>
- <p><c>ip_address() - inet::ip_address()</c></p>
- <p><c>subsystem_spec() = {subsystem_name(),
- {channel_callback(), channel_init_args()}} </c></p>
- <p><c>subsystem_name() = string() </c></p>
- <p><c>channel_callback() = atom() - Name of the erlang module
- implementing the subsystem using the ssh_channel behavior see</c>
- <seealso marker="ssh_channel">ssh_channel(3)</seealso></p>
- <p><c>channel_init_args() = list()</c></p>
- </section>
+ this module, or abstractions to indicate the intended use of the data
+ type, or both:</p>
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p><c>[byte()]</c></p></item>
+ <tag><c>ssh_daemon_ref() =</c></tag>
+ <item><p>opaque() -
+ as returned by <c>ssh:daemon/[1,2,3]</c></p></item>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() - as returned by <c>ssh:connect/3</c></p></item>
+ <tag><c>ip_address() =</c></tag>
+ <item><p><c>inet::ip_address</c></p></item>
+ <tag><c>subsystem_spec() =</c></tag>
+ <item><p><c>{subsystem_name(),
+ {channel_callback(), channel_init_args()}}</c></p></item>
+ <tag><c>subsystem_name() =</c></tag>
+ <item><p><c>string()</c></p></item>
+ <tag><c>channel_callback() =</c></tag>
+ <item><p><c>atom()</c> - Name of the Erlang module
+ implementing the subsystem using the <c>ssh_channel</c> behavior, see
+ <seealso marker="ssh_channel">ssh_channel(3)</seealso></p></item>
+ <tag><c>key_cb() =</c></tag>
+ <item>
+ <p><c>atom() | {atom(), list()}</c></p>
+ <p><c>atom()</c> - Name of the erlang module implementing the behaviours
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> or
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> as the
+ case maybe.</p>
+ <p><c>list()</c> - List of options that can be passed to the callback module.</p>
+ </item>
+ <tag><c>channel_init_args() =</c></tag>
+ <item><p><c>list()</c></p></item>
+
+ <tag><c>algs_list() =</c></tag>
+ <item><p><c>list( alg_entry() )</c></p></item>
+
+ <tag><c>alg_entry() =</c></tag>
+ <item><p><c>{kex, simple_algs()} | {public_key, simple_algs()} | {cipher, double_algs()} | {mac, double_algs()} | {compression, double_algs()}</c></p></item>
+
+ <tag><c>simple_algs() =</c></tag>
+ <item><p><c>list( atom() )</c></p></item>
+
+ <tag><c>double_algs() =</c></tag>
+ <item><p><c>[{client2serverlist,simple_algs()},{server2client,simple_algs()}] | simple_algs()</c></p></item>
+ </taglist>
+</section>
<funcs>
<func>
<name>close(ConnectionRef) -> ok </name>
- <fsummary>Closes an SSH connection</fsummary>
+ <fsummary>Closes an SSH connection.</fsummary>
<type>
<v>ConnectionRef = ssh_connection_ref()</v>
</type>
@@ -81,104 +127,172 @@
<name>connect(Host, Port, Options) -> </name>
<name>connect(Host, Port, Options, Timeout) -> {ok,
ssh_connection_ref()} | {error, Reason}</name>
- <fsummary>Connect to an ssh server.</fsummary>
+ <fsummary>Connects to an SSH server.</fsummary>
<type>
<v>Host = string()</v>
<v>Port = integer()</v>
- <d>The default is <c><![CDATA[22]]></c>, the assigned well known port
+ <d><c><![CDATA[22]]></c> is default, the assigned well-known port
number for SSH.</d>
<v>Options = [{Option, Value}]</v>
- <v>Timeout = infinity | integer(milliseconds)</v>
- <d>Negotiation timeout, for connection timeout use the option <c>{connect_timeout, timeout()}</c>.</d>
+ <v>Timeout = infinity | integer()</v>
+ <d>Negotiation time-out in milli-seconds. The default value is <c>infinity</c>.
+ For connection time-out, use option <c>{connect_timeout, timeout()}</c>.</d>
</type>
<desc>
<p>Connects to an SSH server. No channel is started. This is done
by calling
- <seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/[2, 4]</seealso>.</p>
- <p>Options are:</p>
+ <seealso marker="ssh_connection#session_channel/2">
+ ssh_connection:session_channel/[2, 4]</seealso>.</p>
+ <p>Options:</p>
<taglist>
<tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
- <item> IP version to use.</item>
+ <item>
+ <p>IP version to use.</p>
+ </item>
<tag><c><![CDATA[{user_dir, string()}]]></c></tag>
<item>
- <p>Sets the user directory i.e. the directory containing
- ssh configuration files for the user such as
+ <p>Sets the user directory, that is, the directory containing
+ <c>ssh</c> configuration files for the user, such as
<c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa,
- id_dsa]]></c> and
+ id_dsa]]></c>, and
<c><![CDATA[authorized_key]]></c>. Defaults to the
directory normally referred to as
- <c><![CDATA[~/.ssh]]></c> </p>
+ <c><![CDATA[~/.ssh]]></c>.</p>
</item>
<tag><c><![CDATA[{dsa_pass_phrase, string()}]]></c></tag>
<item>
- <p>If the user dsa key is protected by a passphrase it can be
+ <p>If the user DSA key is protected by a passphrase, it can be
supplied with this option.
</p>
</item>
<tag><c><![CDATA[{rsa_pass_phrase, string()}]]></c></tag>
<item>
- <p>If the user rsa key is protected by a passphrase it can be
+ <p>If the user RSA key is protected by a passphrase, it can be
supplied with this option.
</p>
</item>
<tag><c><![CDATA[{silently_accept_hosts, boolean()}]]></c></tag>
<item>
- <p>When true hosts are added to the
+ <p>When <c>true</c>, hosts are added to the
file <c><![CDATA[known_hosts]]></c> without asking the user.
- Defaults to false.
+ Defaults to <c>false</c>.
</p>
</item>
<tag><c><![CDATA[{user_interaction, boolean()}]]></c></tag>
<item>
- <p>If false disables the client to connect to the server
- if any user interaction is needed such as accepting that
- the server will be added to the <c>known_hosts</c> file or
- supplying a password. Defaults to true.
+ <p>If <c>false</c>, disables the client to connect to the server
+ if any user interaction is needed, such as accepting
+ the server to be added to the <c>known_hosts</c> file, or
+ supplying a password. Defaults to <c>true</c>.
Even if user interaction is allowed it can be
- suppressed by other options such as silently_accept_hosts and
- password. Do note that it may not always be desirable to use
- those options from a security point of view.</p>
+ suppressed by other options, such as <c>silently_accept_hosts</c>
+ and <c>password</c>. However, those optins are not always desirable
+ to use from a security point of view.</p>
+ </item>
+
+ <tag><c><![CDATA[{disconnectfun, fun(Reason:term()) -> _}]]></c></tag>
+ <item>
+ <p>Provides a fun to implement your own logging when a server disconnects the client.</p>
+ </item>
+
+ <tag><c><![CDATA[{unexpectedfun, fun(Message:term(), Peer) -> report | skip }]]></c></tag>
+ <item>
+ <p>Provides a fun to implement your own logging or other action when an unexpected message arrives.
+ If the fun returns <c>report</c> the usual info report is issued but if <c>skip</c> is returned no
+ report is generated.</p>
+ <p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
</item>
+
<tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></tag>
<item>
+ <note>
+ <p>This option will be removed in OTP 20, but is kept for compatibility. It is ignored if
+ the preferred <c>pref_public_key_algs</c> option is used.</p>
+ </note>
<p>Sets the preferred public key algorithm to use for user
- authentication. If the the preferred algorithm fails for
- some reason, the other algorithm is tried. The default is
- to try <c><![CDATA['ssh-rsa']]></c> first.</p>
+ authentication. If the preferred algorithm fails,
+ the other algorithm is tried. If <c>{public_key_alg, 'ssh-rsa'}</c> is set, it is translated
+ to <c>{pref_public_key_algs, ['ssh-rsa','ssh-dss']}</c>. If it is
+ <c>{public_key_alg, 'ssh-dss'}</c>, it is translated
+ to <c>{pref_public_key_algs, ['ssh-dss','ssh-rsa']}</c>.
+ </p>
</item>
+
<tag><c><![CDATA[{pref_public_key_algs, list()}]]></c></tag>
<item>
- <p>List of public key algorithms to try to use, 'ssh-rsa' and 'ssh-dss' available.
- Will override <c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></p>
+ <p>List of user (client) public key algorithms to try to use.</p>
+ <p>The default value is
+ <c><![CDATA[['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521'] ]]></c>
+ </p>
+ <p>If there is no public key of a specified type available, the corresponding entry is ignored.</p>
+ </item>
+
+ <tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
+ <item>
+ <p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
+ be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
+ </p>
+ <p>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
+ <p>Here is an example of this option:</p>
+ <code>
+{preferred_algorithms,
+ [{public_key,['ssh-rsa','ssh-dss']},
+ {cipher,[{client2server,['aes128-ctr']},
+ {server2client,['aes128-cbc','3des-cbc']}]},
+ {mac,['hmac-sha2-256','hmac-sha1']},
+ {compression,[none,zlib]}
+}
+</code>
+ <p>The example specifies different algorithms in the two directions (client2server and server2client),
+ for cipher but specifies the same algorithms for mac and compression in both directions.
+ The kex (key exchange) is implicit but public_key is set explicitly.</p>
+
+ <warning>
+ <p>Changing the values can make a connection less secure. Do not change unless you
+ know exactly what you are doing. If you do not understand the values then you
+ are not supposed to change them.</p>
+ </warning>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),I=integer(),Max=integer()}}]]></c></tag>
+ <item>
+ <p>Sets the three diffie-hellman-group-exchange parameters that guides the connected server in choosing a group.
+ See RFC 4419 for the function of thoose. The default value is <c>{1024, 6144, 8192}</c>.
+ </p>
</item>
+
<tag><c><![CDATA[{connect_timeout, timeout()}]]></c></tag>
<item>
- <p>Sets a timeout on the transport layer
- connection. Defaults to <c>infinity</c>.</p>
+ <p>Sets a time-out on the transport layer
+ connection. For <c>gen_tcp</c> the time is in milli-seconds and the default value is
+ <c>infinity</c>.</p>
</item>
<tag><c><![CDATA[{user, string()}]]></c></tag>
<item>
- <p>Provides a user name. If this option is not given, ssh
+ <p>Provides a username. If this option is not given, <c>ssh</c>
reads from the environment (<c><![CDATA[LOGNAME]]></c> or
- <c><![CDATA[USER]]></c> on unix,
+ <c><![CDATA[USER]]></c> on UNIX,
<c><![CDATA[USERNAME]]></c> on Windows).</p>
</item>
<tag><c><![CDATA[{password, string()}]]></c></tag>
<item>
- <p>Provide a password for password authentication. If
- this option is not given, the user will be asked for a
- password if the password authentication method is
+ <p>Provides a password for password authentication.
+ If this option is not given, the user is asked for a
+ password, if the password authentication method is
attempted.</p>
</item>
- <tag><c><![CDATA[{key_cb, atom()}]]></c></tag>
+ <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
- <p>Module implementing the behaviour <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso>.
- Can be used to customize the handling of public keys.
+ <p>Module implementing the behaviour <seealso
+ marker="ssh_client_key_api">ssh_client_key_api</seealso>. Can be used to
+ customize the handling of public keys. If callback options are provided
+ along with the module name, they are made available to the callback
+ module via the options passed to it under the key 'key_cb_private'.
</p>
</item>
<tag><c><![CDATA[{quiet_mode, atom() = boolean()}]]></c></tag>
<item>
- <p>If true, the client will not print out anything on authorization.</p>
+ <p>If <c>true</c>, the client does not print anything on authorization.</p>
</item>
<tag><c><![CDATA[{id_string, random | string()}]]></c></tag>
@@ -191,17 +305,17 @@
<tag><c><![CDATA[{fd, file_descriptor()}]]></c></tag>
<item>
- <p>Allow an existing file descriptor to be used
- (simply passed on to the transport protocol).</p></item>
+ <p>Allows an existing file descriptor to be used
+ (by passing it on to the transport protocol).</p></item>
<tag><c><![CDATA[{rekey_limit, integer()}]]></c></tag>
<item>
- <p>Provide, in bytes, when rekeying should be initiated,
- defaults to one time each GB and one time per hour.</p>
+ <p>Provides, in bytes, when rekeying is to be initiated.
+ Defaults to once per each GB and once per hour.</p>
</item>
<tag><c><![CDATA[{idle_time, integer()}]]></c></tag>
<item>
- <p>Sets a timeout on connection when no channels are active, default is infinity</p></item>
-
+ <p>Sets a time-out on a connection when no channels are active.
+ Defaults to <c>infinity</c>.</p></item>
<tag><c><![CDATA[{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}]]></c></tag>
<item>
<p>Provide a fun to implement your own logging of the SSH message SSH_MSG_DEBUG. The last three parameters are from the message, see RFC4253, section 11.3. The <c>ConnectionRef</c> is the reference to the connection on which the message arrived. The return value from the fun is not checked.</p>
@@ -215,18 +329,17 @@
<func>
<name>connection_info(ConnectionRef, [Option]) ->[{Option,
- Value}] </name>
- <fsummary> Retrieves information about a connection. </fsummary>
+ Value}]</name>
+ <fsummary>Retrieves information about a connection.</fsummary>
<type>
<v>Option = client_version | server_version | user | peer | sockname </v>
<v>Value = [option_value()] </v>
- <v>option_value() = {{Major::integer(), Minor::integer()}, VersionString::string()} | User::string() |
- Peer::{inet:hostname(), {inet::ip_adress(), inet::port_number()}} |
- Sockname::{inet::ip_adress(), inet::port_number()} () </v>
+ <v>option_value() = {{Major::integer(), Minor::integer()}, VersionString::string()} |
+ User::string() | Peer::{inet:hostname(), {inet::ip_adress(), inet::port_number()}} |
+ Sockname::{inet::ip_adress(), inet::port_number()}</v>
</type>
<desc>
- <p> Retrieves information about a connection.
- </p>
+ <p>Retrieves information about a connection.</p>
</desc>
</func>
@@ -247,111 +360,248 @@
<desc>
<p>Starts a server listening for SSH connections on the given
port.</p>
- <p>Options are:</p>
+ <p>Options:</p>
<taglist>
<tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
- <item> IP version to use when the host address is specified as <c>any</c>. </item>
+ <item><p>IP version to use when the host address is specified as <c>any</c>.</p></item>
<tag><c><![CDATA[{subsystems, [subsystem_spec()]}]]></c></tag>
<item>
- Provides specifications for handling of subsystems. The
- "sftp" subsystem spec can be retrieved by calling
- ssh_sftpd:subsystem_spec/1. If the subsystems option is
- not present the value of
- <c>[ssh_sftpd:subsystem_spec([])]</c> will be used. It is
- of course possible to set the option to the empty list if
- you do not want the daemon to run any subsystems at all.
+ <p>Provides specifications for handling of subsystems. The
+ "sftp" subsystem specification is retrieved by calling
+ <c>ssh_sftpd:subsystem_spec/1</c>. If the subsystems option is
+ not present, the value of
+ <c>[ssh_sftpd:subsystem_spec([])]</c> is used.
+ The option can be set to the empty list if
+ you do not want the daemon to run any subsystems.</p>
</item>
<tag><c><![CDATA[{shell, {Module, Function, Args} |
fun(string() = User) - > pid() | fun(string() = User,
ip_address() = PeerAddr) -> pid()}]]></c></tag>
<item>
- Defines the read-eval-print loop used when a shell is
- requested by the client. Default is to use the erlang shell:
- <c><![CDATA[{shell, start, []}]]></c>
+ <p>Defines the read-eval-print loop used when a shell is
+ requested by the client. The default is to use the Erlang shell:
+ <c><![CDATA[{shell, start, []}]]></c></p>
</item>
<tag><c><![CDATA[{ssh_cli, {channel_callback(),
channel_init_args()} | no_cli}]]></c></tag>
<item>
- Provides your own CLI implementation, i.e. a channel callback
- module that implements a shell and command execution. Note
- that you may customize the shell read-eval-print loop using the
- option <c>shell</c> which is much less work than implementing
- your own CLI channel. If set to <c>no_cli</c> you will disable
- CLI channels and only subsystem channels will be allowed.
+ <p>Provides your own CLI implementation, that is, a channel callback
+ module that implements a shell and command execution. The shell
+ read-eval-print loop can be customized, using the
+ option <c>shell</c>. This means less work than implementing
+ an own CLI channel. If set to <c>no_cli</c>, the CLI channels
+ are disabled and only subsystem channels are allowed.</p>
</item>
- <tag><c><![CDATA[{user_dir, String}]]></c></tag>
+ <tag><c><![CDATA[{user_dir, string()}]]></c></tag>
<item>
- <p>Sets the user directory i.e. the directory containing
- ssh configuration files for the user such as
+ <p>Sets the user directory. That is, the directory containing
+ <c>ssh</c> configuration files for the user, such as
<c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa,
- id_dsa]]></c> and
+ id_dsa]]></c>, and
<c><![CDATA[authorized_key]]></c>. Defaults to the
directory normally referred to as
- <c><![CDATA[~/.ssh]]></c> </p>
+ <c><![CDATA[~/.ssh]]></c>.</p>
</item>
<tag><c><![CDATA[{system_dir, string()}]]></c></tag>
<item>
<p>Sets the system directory, containing the host key files
- that identifies the host keys for ssh. The default is
- <c><![CDATA[/etc/ssh]]></c>, note that for security reasons
- this directory is normally only accessible by the root user.</p>
+ that identify the host keys for <c>ssh</c>. Defaults to
+ <c><![CDATA[/etc/ssh]]></c>. For security reasons,
+ this directory is normally accessible only to the root user.</p>
</item>
+
<tag><c><![CDATA[{auth_methods, string()}]]></c></tag>
<item>
- <p>Comma separated string that determines which
- authentication methodes that the server should support and
- in what order they will be tried. Defaults to
+ <p>Comma-separated string that determines which
+ authentication methods that the server is to support and
+ in what order they are tried. Defaults to
<c><![CDATA["publickey,keyboard-interactive,password"]]></c></p>
</item>
+
+ <tag><c><![CDATA[{auth_method_kb_interactive_data, PromptTexts}]]></c>
+ <br/><c>where:</c>
+ <br/><c>PromptTexts = kb_int_tuple() | fun(Peer::{IP::tuple(),Port::integer()}, User::string(), Service::string()) -> kb_int_tuple()</c>
+ <br/><c>kb_int_tuple() = {Name::string(), Instruction::string(), Prompt::string(), Echo::boolean()}</c>
+ </tag>
+ <item>
+ <p>Sets the text strings that the daemon sends to the client for presentation to the user when using <c>keyboar-interactive</c> authentication. If the fun/3 is used, it is called when the actual authentication occurs and may therefore return dynamic data like time, remote ip etc.</p>
+ <p>The parameter <c>Echo</c> guides the client about need to hide the password.</p>
+ <p>The default value is:
+ <c>{auth_method_kb_interactive_data, {"SSH server", "Enter password for \""++User++"\"", "password: ", false}></c></p>
+ </item>
+
<tag><c><![CDATA[{user_passwords, [{string() = User,
string() = Password}]}]]></c></tag>
<item>
- <p>Provide passwords for password authentication.They will
- be used when someone tries to connect to the server and
- public key user authentication fails. The option provides
- a list of valid user names and the corresponding password.
+ <p>Provides passwords for password authentication. The passwords
+ are used when someone tries to connect to the server and
+ public key user-authentication fails. The option provides
+ a list of valid usernames and the corresponding passwords.
</p>
</item>
<tag><c><![CDATA[{password, string()}]]></c></tag>
<item>
- <p>Provide a global password that will authenticate any
+ <p>Provides a global password that authenticates any
user. From a security perspective this option makes
the server very vulnerable.</p>
</item>
- <tag><c><![CDATA[{pwdfun, fun(User::string(), password::string()) -> boolean()}]]></c></tag>
+
+ <tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
+ <item>
+ <p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
+ be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
+ </p>
+ <p>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
+ <p>Here is an example of this option:</p>
+ <code>
+{preferred_algorithms,
+ [{public_key,['ssh-rsa','ssh-dss']},
+ {cipher,[{client2server,['aes128-ctr']},
+ {server2client,['aes128-cbc','3des-cbc']}]},
+ {mac,['hmac-sha2-256','hmac-sha1']},
+ {compression,[none,zlib]}
+}
+</code>
+ <p>The example specifies different algorithms in the two directions (client2server and server2client),
+ for cipher but specifies the same algorithms for mac and compression in both directions.
+ The kex (key exchange) is implicit but public_key is set explicitly.</p>
+
+ <warning>
+ <p>Changing the values can make a connection less secure. Do not change unless you
+ know exactly what you are doing. If you do not understand the values then you
+ are not supposed to change them.</p>
+ </warning>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_groups, [{Size=integer(),G=integer(),P=integer()}] | {file,filename()} {ssh_moduli_file,filename()} }]]></c></tag>
+ <item>
+ <p>Defines the groups the server may choose among when diffie-hellman-group-exchange is negotiated.
+ See RFC 4419 for details. The three variants of this option are:
+ </p>
+ <taglist>
+ <tag><c>{Size=integer(),G=integer(),P=integer()}</c></tag>
+ <item>The groups are given explicitly in this list. There may be several elements with the same <c>Size</c>.
+ In such a case, the server will choose one randomly in the negotiated Size.
+ </item>
+ <tag><c>{file,filename()}</c></tag>
+ <item>The file must have one or more three-tuples <c>{Size=integer(),G=integer(),P=integer()}</c>
+ terminated by a dot. The file is read when the daemon starts.
+ </item>
+ <tag><c>{ssh_moduli_file,filename()}</c></tag>
+ <item>The file must be in
+ <seealso marker="public_key:public_key#dh_gex_group/4">ssh-keygen moduli file format</seealso>.
+ The file is read when the daemon starts.
+ </item>
+ </taglist>
+ <p>The default list is fetched from the
+ <seealso marker="public_key:public_key#dh_gex_group/4">public_key</seealso> application.
+ </p>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),Max=integer()}}]]></c></tag>
+ <item>
+ <p>Limits what a client can ask for in diffie-hellman-group-exchange.
+ The limits will be
+ <c>{MaxUsed = min(MaxClient,Max), MinUsed = max(MinClient,Min)}</c> where <c>MaxClient</c> and
+ <c>MinClient</c> are the values proposed by a connecting client.
+ </p>
+ <p>The default value is <c>{0,infinity}</c>.
+ </p>
+ <p>If <c>MaxUsed &lt; MinUsed</c> in a key exchange, it will fail with a disconnect.
+ </p>
+ <p>See RFC 4419 for the function of the Max and Min values.</p>
+ </item>
+
+ <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string(), PeerAddress::{ip_adress(),port_number()}, State::any()) -> boolean() | disconnect | {boolean(),any()} }]]></c></tag>
+ <item>
+ <p>Provides a function for password validation. This could used for calling an external system or if
+ passwords should be stored as a hash. The fun returns:
+ </p>
+ <list type="bulleted">
+ <item><c>true</c> if the user and password is valid and</item>
+ <item><c>false</c> otherwise.</item>
+ </list>
+ <p>This fun can also be used to make delays in authentication tries for example by calling
+ <seealso marker="stdlib:timer#sleep/1">timer:sleep/1</seealso>. To facilitate counting of failed tries
+ the <c>State</c> variable could be used. This state is per connection only. The first time the pwdfun
+ is called for a connection, the <c>State</c> variable has the value <c>undefined</c>.
+ The pwdfun can return - in addition to the values above - a new state
+ as:
+ </p>
+ <list type="bulleted">
+ <item><c>{true, NewState:any()}</c> if the user and password is valid or</item>
+ <item><c>{false, NewState:any()}</c> if the user or password is invalid</item>
+ </list>
+ <p>A third usage is to block login attempts from a missbehaving peer. The <c>State</c> described above
+ can be used for this. In addition to the responses above, the following return value is introduced:
+ </p>
+ <list type="bulleted">
+ <item><c>disconnect</c> if the connection should be closed immediately after sending a SSH_MSG_DISCONNECT
+ message.</item>
+ </list>
+ </item>
+
+ <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string()) -> boolean()}]]></c></tag>
<item>
- <p>Provide a function for password validation. This is called
- with user and password as strings, and should return
+ <p>Provides a function for password validation. This function is called
+ with user and password as strings, and returns
<c><![CDATA[true]]></c> if the password is valid and
<c><![CDATA[false]]></c> otherwise.</p>
+ <p>This option (<c>{pwdfun,fun/2}</c>) is the same as a subset of the previous
+ (<c>{pwdfun,fun/4}</c>). It is kept for compatibility.</p>
</item>
<tag><c><![CDATA[{negotiation_timeout, integer()}]]></c></tag>
<item>
- <p>Max time in milliseconds for the authentication negotiation. The default value is 2 minutes. If the client fails to login within this time, the connection is closed.
+ <p>Maximum time in milliseconds for the authentication negotiation.
+ Defaults to 120000 (2 minutes). If the client fails to log in within this time,
+ the connection is closed.
</p>
</item>
<tag><c><![CDATA[{max_sessions, pos_integer()}]]></c></tag>
<item>
- <p>The maximum number of simultaneous sessions that are accepted at any time for this daemon. This includes sessions that are being authorized. So if set to <c>N</c>, and <c>N</c> clients have connected but not started the login process, the <c>N+1</c> connection attempt will be aborted. If <c>N</c> connections are authenticated and still logged in, no more loggins will be accepted until one of the existing ones log out.
+ <p>The maximum number of simultaneous sessions that are accepted at any time
+ for this daemon. This includes sessions that are being authorized.
+ Thus, if set to <c>N</c>, and <c>N</c> clients have connected but not started
+ the login process, connection attempt <c>N+1</c> is aborted.
+ If <c>N</c> connections are authenticated and still logged in, no more logins
+ are accepted until one of the existing ones log out.
</p>
- <p>The counter is per listening port, so if two daemons are started, one with <c>{max_sessions,N}</c> and the other with <c>{max_sessions,M}</c> there will be in total <c>N+M</c> connections accepted for the whole ssh application.
+ <p>The counter is per listening port. Thus, if two daemons are started, one with
+ <c>{max_sessions,N}</c> and the other with <c>{max_sessions,M}</c>, in total
+ <c>N+M</c> connections are accepted for the whole <c>ssh</c> application.
</p>
- <p>Note that if <c>parallel_login</c> is <c>false</c>, only one client at a time may be in the authentication phase.
+ <p>Notice that if <c>parallel_login</c> is <c>false</c>, only one client
+ at a time can be in the authentication phase.
</p>
- <p>As default, the option is not set. This means that the number is not limited.
+ <p>By default, this option is not set. This means that the number is not limited.
+ </p>
+ </item>
+
+ <tag><c><![CDATA[{max_channels, pos_integer()}]]></c></tag>
+ <item>
+ <p>The maximum number of channels with active remote subsystem that are accepted for
+ each connection to this daemon</p>
+ <p>By default, this option is not set. This means that the number is not limited.
</p>
</item>
+
<tag><c><![CDATA[{parallel_login, boolean()}]]></c></tag>
<item>
- <p>If set to false (the default value), only one login is handled a time. If set to true, an unlimited number of login attempts will be allowed simultanously.
+ <p>If set to false (the default value), only one login is handled at a time.
+ If set to true, an unlimited number of login attempts are allowed simultaneously.
</p>
- <p>If the <c>max_sessions</c> option is set to <c>N</c> and <c>parallel_login</c> is set to <c>true</c>, the max number of simultaneous login attempts at any time is limited to <c>N-K</c> where <c>K</c> is the number of authenticated connections present at this daemon.
+ <p>If the <c>max_sessions</c> option is set to <c>N</c> and <c>parallel_login</c>
+ is set to <c>true</c>, the maximum number of simultaneous login attempts at any time is
+ limited to <c>N-K</c>, where <c>K</c> is the number of authenticated connections present
+ at this daemon.
</p>
<warning>
- <p>Do not enable <c>parallel_logins</c> without protecting the server by other means, for example the <c>max_sessions</c> option or a firewall configuration. If set to <c>true</c>, there is no protection against DOS attacks.</p>
+ <p>Do not enable <c>parallel_logins</c> without protecting the server by other means,
+ for example, by the <c>max_sessions</c> option or a firewall configuration. If set to
+ <c>true</c>, there is no protection against DOS attacks.</p>
</warning>
</item>
@@ -369,27 +619,53 @@
</p>
</item>
- <tag><c><![CDATA[{key_cb, atom()}]]></c></tag>
+ <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
- <p>Module implementing the behaviour <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
- Can be used to customize the handling of public keys.
+ <p>Module implementing the behaviour <seealso
+ marker="ssh_server_key_api">ssh_server_key_api</seealso>. Can be used to
+ customize the handling of public keys. If callback options are provided
+ along with the module name, they are made available to the callback
+ module via the options passed to it under the key 'key_cb_private'.
+ </p>
+ </item>
+
+ <tag><c>{profile, atom()}</c></tag>
+ <item>
+ <p>Used together with <c>ip-address</c> and <c>port</c> to
+ uniquely identify a ssh daemon. This can be useful in a
+ virtualized environment, where there can be more that one
+ server that has the same <c>ip-address</c> and
+ <c>port</c>. If this property is not explicitly set, it is
+ assumed that the the <c>ip-address</c> and <c>port</c>
+ uniquely identifies the SSH daemon.
</p>
</item>
+
<tag><c><![CDATA[{fd, file_descriptor()}]]></c></tag>
<item>
- <p>Allow an existing file-descriptor to be used
- (simply passed on to the transport protocol).</p></item>
- <tag><c><![CDATA[{failfun, fun(User::string(), PeerAddress::ip_address(), Reason::term()) -> _}]]></c></tag>
+ <p>Allows an existing file-descriptor to be used
+ (passed on to the transport protocol).</p></item>
+ <tag><c><![CDATA[{failfun, fun(User::string(),
+ PeerAddress::ip_address(), Reason::term()) -> _}]]></c></tag>
<item>
- <p>Provide a fun to implement your own logging when a user fails to authenticate.</p>
+ <p>Provides a fun to implement your own logging when a user fails to authenticate.</p>
</item>
- <tag><c><![CDATA[{connectfun, fun(User::string(), PeerAddress::ip_address(), Method::string()) ->_}]]></c></tag>
+ <tag><c><![CDATA[{connectfun, fun(User::string(), PeerAddress::ip_address(),
+ Method::string()) ->_}]]></c></tag>
<item>
- <p>Provide a fun to implement your own logging when a user authenticates to the server.</p>
+ <p>Provides a fun to implement your own logging when a user authenticates to the server.</p>
</item>
<tag><c><![CDATA[{disconnectfun, fun(Reason:term()) -> _}]]></c></tag>
<item>
- <p>Provide a fun to implement your own logging when a user disconnects from the server.</p>
+ <p>Provides a fun to implement your own logging when a user disconnects from the server.</p>
+ </item>
+
+ <tag><c><![CDATA[{unexpectedfun, fun(Message:term(), Peer) -> report | skip }]]></c></tag>
+ <item>
+ <p>Provides a fun to implement your own logging or other action when an unexpected message arrives.
+ If the fun returns <c>report</c> the usual info report is issued but if <c>skip</c> is returned no
+ report is generated.</p>
+ <p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
</item>
<tag><c><![CDATA[{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}]]></c></tag>
@@ -403,21 +679,41 @@
</desc>
</func>
+ <func>
+ <name>default_algorithms() -> algs_list()</name>
+ <fsummary>Get a list declaring the supported algorithms</fsummary>
+ <desc>
+ <p>Returns a key-value list, where the keys are the different types of algorithms and the values are the
+ algorithms themselves. An example:</p>
+ <code>
+20> ssh:default_algorithms().
+[{kex,['diffie-hellman-group1-sha1']},
+ {public_key,['ssh-rsa','ssh-dss']},
+ {cipher,[{client2server,['aes128-ctr','aes128-cbc','3des-cbc']},
+ {server2client,['aes128-ctr','aes128-cbc','3des-cbc']}]},
+ {mac,[{client2server,['hmac-sha2-256','hmac-sha1']},
+ {server2client,['hmac-sha2-256','hmac-sha1']}]},
+ {compression,[{client2server,[none,zlib]},
+ {server2client,[none,zlib]}]}]
+21>
+</code>
+ </desc>
+ </func>
<func>
<name>shell(Host) -> </name>
<name>shell(Host, Option) -> </name>
<name>shell(Host, Port, Option) -> _</name>
- <fsummary> </fsummary>
+ <fsummary>Starts an interactive shell over an SSH server.</fsummary>
<type>
- <v> Host = string()</v>
- <v> Port = integer()</v>
- <v> Options - see ssh:connect/3</v>
+ <v>Host = string()</v>
+ <v>Port = integer()</v>
+ <v>Options - see ssh:connect/3</v>
</type>
<desc>
- <p>Starts an interactive shell via an SSH server on the
+ <p>Starts an interactive shell over an SSH server on the
given <c>Host</c>. The function waits for user input,
- and will not return until the remote shell is ended (i.e.
+ and does not return until the remote shell is ended (that is,
exit from the shell).
</p>
</desc>
@@ -426,28 +722,29 @@
<func>
<name>start() -> </name>
<name>start(Type) -> ok | {error, Reason}</name>
- <fsummary>Starts the SSH application. </fsummary>
+ <fsummary>Starts the SSH application.</fsummary>
<type>
<v>Type = permanent | transient | temporary</v>
<v>Reason = term() </v>
</type>
<desc>
- <p>Utility function that starts crypto, public_key and the SSH
- application. Defult type is temporary.
- See also <seealso marker="kernel:application">application(3)</seealso>
- </p>
+ <p>Utility function that starts the applications <c>crypto</c>, <c>public_key</c>,
+ and <c>ssh</c>. Default type is <c>temporary</c>.
+ For more information, see the <seealso marker="kernel:application">application(3)</seealso>
+ manual page in <c>kernel</c>.</p>
</desc>
</func>
<func>
<name>stop() -> ok | {error, Reason}</name>
- <fsummary>Stops the SSH application.</fsummary>
+ <fsummary>Stops the <c>ssh</c> application.</fsummary>
<type>
<v>Reason = term()</v>
</type>
<desc>
- <p>Stops the SSH application. See also
- <seealso marker="kernel:application">application(3)</seealso></p>
+ <p>Stops the <c>ssh</c> application.
+ For more information, see the <seealso marker="kernel:application">application(3)</seealso>
+ manual page in <c>kernel</c>.</p>
</desc>
</func>
@@ -471,7 +768,7 @@
<name>stop_listener(DaemonRef) -> </name>
<name>stop_listener(Address, Port) -> ok </name>
<fsummary>Stops the listener, but leaves existing connections started
- by the listener up and running.</fsummary>
+ by the listener operational.</fsummary>
<type>
<v>DaemonRef = ssh_daemon_ref()</v>
<v>Address = ip_address()</v>
@@ -479,7 +776,7 @@
</type>
<desc>
<p>Stops the listener, but leaves existing connections started
- by the listener up and running.</p>
+ by the listener operational.</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_app.xml b/lib/ssh/doc/src/ssh_app.xml
index a1d2402790..f6ce44c015 100644
--- a/lib/ssh/doc/src/ssh_app.xml
+++ b/lib/ssh/doc/src/ssh_app.xml
@@ -4,97 +4,316 @@
<appref>
<header>
<copyright>
- <year>2012</year><year>2013</year>
+ <year>2012</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>SSH</title>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>ssh_app.xml</file>
</header>
<app>SSH</app>
- <appsummary>The ssh application implements the SSH (Secure Shell) protocol and
- provides an SFTP (SSH File Transfer Protocol) client and server. </appsummary>
+ <appsummary>The ssh application implements the Secure Shell (SSH) protocol and
+ provides an SSH File Transfer Protocol (SFTP) client and server.</appsummary>
+ <description>
+ <p>The <c>ssh</c> application is an implementation of the SSH protocol in Erlang.
+ <c>ssh</c> offers API functions to write customized SSH clients and servers as well as
+ making the Erlang shell available over SSH. An SFTP client, <c>ssh_sftp</c>, and server,
+ <c>ssh_sftpd</c>, are also included.</p>
+ </description>
- <section>
+ <section>
<title>DEPENDENCIES</title>
- <p>The ssh application uses the Erlang applications public_key and
- crypto to handle public keys and encryption, hence these
- applications needs to be loaded for the ssh application to work. In
- an embedded environment that means they need to be started with
- application:start/[1,2] before the ssh application is started.
+ <p>The <c>ssh</c> application uses the applications
+ <seealso marker="public_key:public_key">public_key</seealso> and
+ <seealso marker="crypto:crypto">crypto</seealso>
+ to handle public keys and encryption. Hence, these
+ applications must be loaded for the <c>ssh</c> application to work. In
+ an embedded environment this means that they must be started with
+ <seealso marker="kernel:application#start/1">application:start/1,2</seealso> before the
+ <c>ssh</c> application is started.
</p>
</section>
- <section>
+ <section>
<title>CONFIGURATION</title>
- <p>The ssh application does not currently have an application
- specific configuration file as described in application(3),
- however it will by default use the following configuration files
- from openssh: known_hosts, authorized_keys, authorized_keys2,
- id_dsa and id_rsa, ssh_host_dsa_key and ssh_host_rsa_key. By
- default Erlang SSH will look for id_dsa, id_rsa, known_hosts
- and authorized_keys in ~/.ssh, and the host key files in /etc/ssh
- . These locations may be changed by the options user_dir and
- system_dir. Public key handling may also be customized by
- providing a callback module implementing the behaviors
- <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and
- <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
- </p>
+ <p>The <c>ssh</c> application does not have an application-
+ specific configuration file, as described in <seealso marker="kernel:application">application(3)</seealso>.
+ However, by default it use the following configuration files
+ from OpenSSH:</p>
+ <list type="bulleted">
+ <item><c>known_hosts</c></item>
+ <item><c>authorized_keys</c></item>
+ <item><c>authorized_keys2</c></item>
+ <item><c>id_dsa</c></item>
+ <item><c>id_rsa</c></item>
+ <item><c>id_ecdsa</c></item>
+ <item><c>ssh_host_dsa_key</c></item>
+ <item><c>ssh_host_rsa_key</c></item>
+ <item><c>ssh_host_ecdsa_key</c></item>
+ </list>
+ <p>By default, <c>ssh</c> looks for <c>id_dsa</c>, <c>id_rsa</c>,
+ <c>id_ecdsa_key</c>,
+ <c>known_hosts</c>, and <c>authorized_keys</c> in ~/.ssh,
+ and for the host key files in <c>/etc/ssh</c>. These locations can be changed
+ by the options <c>user_dir</c> and <c>system_dir</c>.
+ </p>
+ <p>Public key handling can also be customized through a callback module that
+ implements the behaviors
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and
+ <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
+ </p>
- <section>
- <title>PUBLIC KEYS</title>
- <p>
- id_dsa and id_rsa are the users private key files, note that
- the public key is part of the private key so the ssh
- application will not use the id_&lt;*>.pub files. These are
- for the users convenience when he/she needs to convey their
+ </section>
+ <section>
+ <title>Public Keys</title>
+ <p><c>id_dsa</c>, <c>id_rsa</c> and <c>id_ecdsa</c> are the users private key files.
+ Notice that the public key is part of the private key so the <c>ssh</c>
+ application does not use the <c>id_&lt;*>.pub</c> files. These are
+ for the user's convenience when it is needed to convey the user's
public key.
</p>
- </section>
-
- <section>
- <title>KNOW HOSTS</title>
- <p>The known_hosts file contains a list of approved servers and
- their public keys. Once a server is listed, it can be verified
+ </section>
+ <section>
+ <title>Known Hosts</title>
+ <p>The <c>known_hosts</c> file contains a list of approved servers and
+ their public keys. Once a server is listed, it can be verified
without user interaction.
</p>
- </section>
-
- <section>
- <title>AUTHORIZED KEYS</title>
- <p>The authorized key file keeps track of the user's authorized
+ </section>
+ <section>
+ <title>Authorized Keys</title>
+ <p>The <c>authorized_key</c> file keeps track of the user's authorized
public keys. The most common use of this file is to let users
- log in without entering their password which is supported by the
- Erlang SSH daemon.
+ log in without entering their password, which is supported by the
+ Erlang <c>ssh</c> daemon.
</p>
- </section>
-
- <section>
- <title>HOST KEYS</title>
- <p>Currently rsa and dsa host keys are supported and are
- expected to be found in files named ssh_host_rsa_key and
- ssh_host_dsa_key.
+ </section>
+ <section>
+ <title>Host Keys</title>
+ <p>RSA and DSA host keys are supported and are
+ expected to be found in files named <c>ssh_host_rsa_key</c>,
+ <c>ssh_host_dsa_key</c> and <c>ssh_host_ecdsa_key</c>.
</p>
- </section>
+ </section>
+ <section>
+ <title>ERROR LOGGER AND EVENT HANDLERS</title>
+ <p>The <c>ssh</c> application uses the default <seealso marker="kernel:error_logger">OTP error logger</seealso> to log unexpected errors or print information about special events.</p>
+ </section>
+
+ <section>
+ <marker id="supported"/>
+ <title>SUPPORTED SPECIFICATIONS AND STANDARDS</title>
+ <p>The supported SSH version is 2.0.</p>
+ </section>
+ <section>
+ <title>Algorithms</title>
+ <p>The actual set of algorithms may vary depending on which OpenSSL crypto library that is installed on the machine.
+ For the list on a particular installation, use the command
+ <seealso marker="ssh:ssh#default_algorithms/0">ssh:default_algorithms/0</seealso>.
+ The user may override the default algorithm configuration both on the server side and the client side.
+ See the option <c>preferred_algorithms</c> in the <seealso marker="ssh:ssh#daemon/1">ssh:daemon/1,2,3</seealso> and
+ <seealso marker="ssh:ssh#connect/3">ssh:connect/3,4</seealso> functions.
+ </p>
+
+ <p>Supported algorithms are:</p>
+
+ <taglist>
+ <tag>Key exchange algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>ecdh-sha2-nistp256</item>
+ <item>ecdh-sha2-nistp384</item>
+ <item>ecdh-sha2-nistp521</item>
+ <item>diffie-hellman-group-exchange-sha1</item>
+ <item>diffie-hellman-group-exchange-sha256</item>
+ <item>diffie-hellman-group14-sha1</item>
+ <item>diffie-hellman-group1-sha1</item>
+ </list>
+ </item>
+
+ <tag>Public key algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>ecdsa-sha2-nistp256</item>
+ <item>ecdsa-sha2-nistp384</item>
+ <item>ecdsa-sha2-nistp521</item>
+ <item>ssh-rsa</item>
+ <item>ssh-dss</item>
+ </list>
+ </item>
+
+ <tag>MAC algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>hmac-sha2-256</item>
+ <item>hmac-sha2-512</item>
+ <item>hmac-sha1</item>
+ </list>
+ </item>
+
+ <tag>Encryption algorithms (ciphers)</tag>
+ <item>
+ <list type="bulleted">
+ <item>[email protected] (AEAD_AES_128_GCM)</item>
+ <item>[email protected] (AEAD_AES_256_GCM)</item>
+ <item>aes128-ctr</item>
+ <item>aes192-ctr</item>
+ <item>aes256-ctr</item>
+ <item>aes128-cbc</item>
+ <item>3des-cbc</item>
+ </list>
+ <p>Following the internet de-facto standard, the cipher and mac algorithm AEAD_AES_128_GCM is selected when the
+ cipher [email protected] is negotiated. The cipher and mac algorithm AEAD_AES_256_GCM is selected when the
+ cipher [email protected] is negotiated.
+ </p>
+ <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso>
+ for more information.
+ </p>
+ </item>
+
+ <tag>Compression algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>none</item>
+ <item>[email protected]</item>
+ <item>zlib</item>
+ </list>
+ </item>
+ </taglist>
+ </section>
+ <section>
+ <title>Unicode support</title>
+ <p>Unicode filenames are supported if the emulator and the underlaying OS support it. See section DESCRIPTION in the
+ <seealso marker="kernel:file">file</seealso> manual page in <c>kernel</c> for information about this subject.
+ </p>
+ <p>The shell and the cli both support unicode.
+ </p>
+ </section>
+
+ <section>
+ <title>Rfcs</title>
+ <p>The following rfc:s are supported:</p>
+ <list type="bulleted">
+ <item><url href="https://tools.ietf.org/html/rfc4251">RFC 4251</url>, The Secure Shell (SSH) Protocol Architecture.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>9.4.6 Host-Based Authentication</item>
+ <item>9.5.2 Proxy Forwarding</item>
+ <item>9.5.3 X11 Forwarding</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4252">RFC 4252</url>, The Secure Shell (SSH) Authentication Protocol.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>9. Host-Based Authentication: "hostbased"</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, The Secure Shell (SSH) Transport Layer Protocol.
+ <p></p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4254">RFC 4254</url>, The Secure Shell (SSH) Connection Protocol.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>6.3. X11 Forwarding</item>
+ <item>7. TCP/IP Port Forwarding</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4256">RFC 4256</url>, Generic Message Exchange Authentication for
+ the Secure Shell Protocol (SSH).
+ <p>Except</p>
+ <list type="bulleted">
+ <item><c>num-prompts > 1</c></item>
+ <item>password changing</item>
+ <item>other identification methods than userid-password</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url>, Diffie-Hellman Group Exchange for
+ the Secure Shell (SSH) Transport Layer Protocol.
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4716">RFC 4716</url>, The Secure Shell (SSH) Public Key File Format.
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc5647">RFC 5647</url>, AES Galois Counter Mode for
+ the Secure Shell Transport Layer Protocol.
+ <p><marker id="rfc5647_note"/>There is an ambiguity in the synchronized selection of cipher and mac algorithm.
+ This is resolved by OpenSSH in the ciphers [email protected] and [email protected] which are implemented.
+ If the explicit ciphers and macs AEAD_AES_128_GCM or AEAD_AES_256_GCM are needed,
+ they could be enabled with the option preferred_algorithms.
+ </p>
+ <warning>
+ <p>
+ If the client or the server is not Erlang/OTP, it is the users responsibility to check that
+ other implementation has the same interpretation of AEAD_AES_*_GCM as the Erlang/OTP SSH before
+ enabling them. The aes*[email protected] variants are always safe to use since they lack the
+ ambiguity.
+ </p>
+ </warning>
+ <p>The second paragraph in section 5.1 is resolved as:</p>
+ <list type="ordered">
+ <item>If the negotiated cipher is AEAD_AES_128_GCM, the mac algorithm is set to AEAD_AES_128_GCM.</item>
+ <item>If the negotiated cipher is AEAD_AES_256_GCM, the mac algorithm is set to AEAD_AES_256_GCM.</item>
+ <item>If the mac algorithm is AEAD_AES_128_GCM, the cipher is set to AEAD_AES_128_GCM.</item>
+ <item>If the mac algorithm is AEAD_AES_256_GCM, the cipher is set to AEAD_AES_256_GCM.</item>
+ </list>
+ <p>The first rule that matches when read in order from the top is applied</p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc5656">RFC 5656</url>, Elliptic Curve Algorithm Integration in
+ the Secure Shell Transport Layer.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>5. ECMQV Key Exchange</item>
+ <item>6.4. ECMQV Key Exchange and Verification Method Name</item>
+ <item>7.2. ECMQV Message Numbers</item>
+ <item>10.2. Recommended Curves</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc6668">RFC 6668</url>, SHA-2 Data Integrity Verification for
+ the Secure Shell (SSH) Transport Layer Protocol
+ <p>Comment: Defines hmac-sha2-256 and hmac-sha2-512
+ </p>
+ </item>
+
+ </list>
+
</section>
<section>
<title>SEE ALSO</title>
- <p>application(3)</p>
+ <p><seealso marker="kernel:application">application(3)</seealso></p>
</section>
</appref>
diff --git a/lib/ssh/doc/src/ssh_channel.xml b/lib/ssh/doc/src/ssh_channel.xml
index a52a6a115e..abfe590647 100644
--- a/lib/ssh/doc/src/ssh_channel.xml
+++ b/lib/ssh/doc/src/ssh_channel.xml
@@ -9,83 +9,99 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_channel</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
</header>
<module>ssh_channel</module>
<modulesummary>-behaviour(ssh_channel).
</modulesummary>
<description>
<p>SSH services (clients and servers) are implemented as channels
- that are multiplexed over an SSH connection and communicates via
+ that are multiplexed over an SSH connection and communicates over
the <url href="http://www.ietf.org/rfc/rfc4254.txt"> SSH
Connection Protocol</url>. This module provides a callback API
- that takes care of generic channel aspects such as flow control
- and close messages and lets the callback functions take care of
+ that takes care of generic channel aspects, such as flow control
+ and close messages. It lets the callback functions take care of
the service (application) specific parts. This behavior also ensures
that the channel process honors the principal of an OTP-process so
that it can be part of a supervisor tree. This is a requirement of
channel processes implementing a subsystem that will be added to
- the SSH applications supervisor tree.
+ the <c>ssh</c> applications supervisor tree.
</p>
- <note> <p>When implementing a SSH subsystem use the
- <c>-behaviour(ssh_daemon_channel).</c> instead of <c>-behaviour(ssh_channel).</c>
- as the only relevant callback functions for subsystems are
- init/1, handle_ssh_msg/2, handle_msg/2 and terminate/2, so the ssh_daemon_channel
- behaviour is limited version of the ssh_channel behaviour.
- </p> </note>
+ <note><p>When implementing an <c>ssh</c> subsystem, use
+ <c>-behaviour(ssh_daemon_channel)</c> instead of <c>-behaviour(ssh_channel)</c>.
+ The reason is that the only relevant callback functions for subsystems are
+ <c>init/1</c>, <c>handle_ssh_msg/2</c>, <c>handle_msg/2</c>, and <c>terminate/2</c>.
+ So, the <c>ssh_daemon_channel</c> behaviour is a limited version of the
+ <c>ssh_channel</c> behaviour.
+ </p></note>
</description>
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data
- type:</p>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both:</p>
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = list of ASCII characters</c></p>
- <p><c>timeout() = infinity | integer() - in milliseconds.</c></p>
- <p><c>ssh_connection_ref() - opaque to the user returned by
- ssh:connect/3 or sent to an SSH channel process</c></p>
- <p><c>ssh_channel_id() = integer() </c></p>
- <p><c>ssh_data_type_code() = 1 ("stderr") | 0 ("normal") are
- currently valid values see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 5.2.</c></p>
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p>list of ASCII characters</p></item>
+ <tag><c>timeout() =</c></tag>
+ <item><p><c>infinity | integer()</c> in milliseconds</p></item>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() -as returned by
+ <c>ssh:connect/3</c> or sent to an SSH channel process</p></item>
+ <tag><c>ssh_channel_id() =</c></tag>
+ <item><p><c>integer()</c></p></item>
+ <tag><c>ssh_data_type_code() =</c></tag>
+ <item><p><c>1</c> ("stderr") | <c>0</c> ("normal") are
+ the valid values,
+ see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>
+ Section 5.2</p></item>
+ </taglist>
</section>
<funcs>
<func>
<name>call(ChannelRef, Msg) -></name>
<name>call(ChannelRef, Msg, Timeout) -> Reply | {error, Reason}</name>
- <fsummary> Makes a synchronous call to a channel.</fsummary>
+ <fsummary>Makes a synchronous call to a channel.</fsummary>
<type>
<v>ChannelRef = pid() </v>
- <d>As returned by start_link/4 </d>
- <v>Msg = term() </v>
- <v>Timeout = timeout() </v>
- <v>Reply = term() </v>
- <v>Reason = closed | timeout </v>
+ <d>As returned by <seealso marker = "#start_link-4">ssh_channel:start_link/4</seealso></d>
+ <v>Msg = term()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reply = term()</v>
+ <v>Reason = closed | timeout</v>
</type>
<desc>
<p>Makes a synchronous call to the channel process by sending
- a message and waiting until a reply arrives or a timeout
- occurs. The channel will call <seealso marker =
+ a message and waiting until a reply arrives, or a time-out
+ occurs. The channel calls <seealso marker =
"#Module:handle_call-3">Module:handle_call/3</seealso>
- to handle the message. If the channel process does not exist
+ to handle the message. If the channel process does not exist,
<c>{error, closed}</c> is returned.
</p>
</desc>
@@ -96,14 +112,14 @@
<fsummary>Sends an asynchronous message to the channel
ChannelRef and returns ok.</fsummary>
<type>
- <v>ChannelRef = pid() </v>
- <d>As returned by start_link/4 </d>
- <v>Msg = term() </v>
+ <v>ChannelRef = pid()</v>
+ <d>As returned by <seealso marker = "#start_link-4">ssh_channel:start_link/4</seealso></d>
+ <v>Msg = term()</v>
</type>
<desc>
<p>Sends an asynchronous message to the channel process and
returns ok immediately, ignoring if the destination node or
- channel process does not exist. The channel will call
+ channel process does not exist. The channel calls
<seealso marker = "#Module:handle_cast-2">Module:handle_cast/2</seealso>
to handle the message.
</p>
@@ -112,31 +128,32 @@
<func>
<name>enter_loop(State) -> _ </name>
- <fsummary> Makes an existing process an ssh_channel process. </fsummary>
+ <fsummary>Makes an existing process an ssh_channel process.</fsummary>
<type>
- <v> State = term() - as returned by <seealso marker = "#init-1">ssh_channel:init/1</seealso></v>
+ <v>State = term()</v>
+ <d>as returned by <seealso marker = "#init-1">ssh_channel:init/1</seealso></d>
</type>
<desc>
- <p> Makes an existing process an <c>ssh_channel</c>
- process. Does not return, instead the calling process will
- enter the <c>ssh_channel</c> process receive loop and become an
- <c>ssh_channel process.</c> The process must have been started using
- one of the start functions in proc_lib, see <seealso
- marker="stdlib:proc_lib">proc_lib(3)</seealso>. The
- user is responsible for any initialization of the process
- and needs to call <seealso marker = "#init-1">ssh_channel:init/1</seealso>
+ <p>Makes an existing process an <c>ssh_channel</c>
+ process. Does not return, instead the calling process
+ enters the <c>ssh_channel</c> process receive loop and become an
+ <c>ssh_channel process</c>. The process must have been started using
+ one of the start functions in <c>proc_lib</c>, see the <seealso
+ marker="stdlib:proc_lib">proc_lib(3)</seealso> manual page in <c>stdlib</c>.
+ The user is responsible for any initialization of the process
+ and must call <seealso marker = "#init-1">ssh_channel:init/1</seealso>.
</p>
</desc>
</func>
<func>
<name>init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name>
- <fsummary> Initiates a ssh_channel process.</fsummary>
+ <fsummary>Initiates an <c>ssh_channel</c> process.</fsummary>
<type>
<v>Options = [{Option, Value}]</v>
<v>State = term()</v>
- <v>Timeout = timeout() </v>
- <v>Reason = term() </v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
</type>
<desc>
<p>
@@ -144,48 +161,47 @@
</p>
<taglist>
<tag><c><![CDATA[{channel_cb, atom()}]]></c></tag>
- <item>The module that implements the channel behaviour.</item>
+ <item><p>The module that implements the channel behaviour.</p></item>
<tag><c><![CDATA[{init_args(), list()}]]></c></tag>
- <item> The list of arguments to the callback module's
- init function.</item>
+ <item><p>The list of arguments to the <c>init</c> function of the callback module.</p></item>
<tag><c><![CDATA[{cm, connection_ref()}]]></c></tag>
- <item> Reference to the ssh connection as returned by <seealso
- marker="ssh#connect-3">ssh:connect/3</seealso></item>
+ <item><p>Reference to the <c>ssh</c> connection as returned by <seealso
+ marker="ssh#connect-3">ssh:connect/3</seealso></p></item>
<tag><c><![CDATA[{channel_id, channel_id()}]]></c></tag>
- <item> Id of the SSH channel.</item>
+ <item><p>Id of the <c>ssh</c> channel.</p></item>
</taglist>
<note><p>This function is normally not called by the
- user. The user only needs to call if for some reason the
+ user. The user only needs to call if the
channel process needs to be started with help of
<c>proc_lib</c> instead of calling
<c>ssh_channel:start/4</c> or
- <c>ssh_channel:start_link/4</c> </p>
+ <c>ssh_channel:start_link/4</c>.</p>
</note>
</desc>
</func>
<func>
<name>reply(Client, Reply) -> _</name>
- <fsummary>Send a reply to a client.</fsummary>
+ <fsummary>Sends a reply to a client.</fsummary>
<type>
- <v>Client - opaque to the user, see explanation below</v>
+ <v>Client = opaque()</v>
<v>Reply = term()</v>
</type>
<desc>
- <p>This function can be used by a channel to explicitly send a
+ <p>This function can be used by a channel to send a
reply to a client that called <c>call/[2,3]</c> when the reply
cannot be defined in the return value of
<seealso marker ="#Module:handle_call-3">Module:handle_call/3</seealso>.</p>
<p><c>Client</c> must be the <c>From</c> argument provided to
the callback function <c>handle_call/3</c>.
<c>Reply</c> is an arbitrary term,
- which will be given back to the client as the return value of
- <seealso marker="#call-2">ssh_channel:call/[2,3].</seealso>></p>
+ which is given back to the client as the return value of
+ <seealso marker="#call-2">ssh_channel:call/[2,3].</seealso></p>
</desc>
</func>
@@ -193,24 +209,25 @@
<name>start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> </name>
<name>start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) ->
{ok, ChannelRef} | {error, Reason}</name>
- <fsummary> Starts a processes that handles a SSH channel. </fsummary>
+ <fsummary>Starts a process that handles an SSH channel.</fsummary>
<type>
<v>SshConnection = ssh_connection_ref()</v>
- <v>ChannelId = ssh_channel_id() </v>
- <d> As returned by cannot be defined in the return value of
- <seealso marker ="ssh_connection#session_channel/2">ssh_connection:session_channel/[2,4]</seealso></d>
+ <v>ChannelId = ssh_channel_id()</v>
+ <d>As returned by
+ <seealso marker ="ssh_connection#session_channel/2">
+ ssh_connection:session_channel/[2,4]</seealso>.</d>
<v>ChannelCb = atom()</v>
- <d> The name of the module implementing the service specific parts
+ <d>Name of the module implementing the service-specific parts
of the channel.</d>
<v>CbInitArgs = [term()]</v>
- <d>Argument list for the init function in the callback module. </d>
+ <d>Argument list for the <c>init</c> function in the callback module.</d>
<v>ChannelRef = pid()</v>
</type>
<desc>
- <p>Starts a processes that handles an SSH channel. It will be
- called internally by the SSH daemon or explicitly by the SSH
- client implementations. The behavior will set the
- <c>trap_exit</c> flag to true.
+ <p>Starts a process that handles an SSH channel. It is
+ called internally, by the <c>ssh</c> daemon, or explicitly by the <c>ssh</c>
+ client implementations. The behavior sets the
+ <c>trap_exit</c> flag to <c>true</c>.
</p>
</desc>
</func>
@@ -219,19 +236,19 @@
<section>
<marker id="cb_timeouts"></marker>
- <title> CALLBACK TIMEOUTS</title>
+ <title>CALLBACK TIME-OUTS</title>
- <p>The timeout values that may be returned by the callback functions
- has the same semantics as in a <seealso marker="stdlib:gen_server">gen_server</seealso>
- If the timeout occurs <seealso marker="#Module:handle_msg-2">handle_msg/2</seealso>
- will be called as <c>handle_msg(timeout, State). </c></p>
+ <p>The time-out values that can be returned by the callback functions
+ have the same semantics as in a <seealso marker="stdlib:gen_server">gen_server</seealso>.
+ If the time-out occurs, <seealso marker="#Module:handle_msg-2">handle_msg/2</seealso>
+ is called as <c>handle_msg(timeout, State)</c>.</p>
</section>
<funcs>
<func>
<name>Module:code_change(OldVsn, State, Extra) -> {ok,
NewState}</name>
- <fsummary> Converts process state when code is changed.</fsummary>
+ <fsummary>Converts process state when code is changed.</fsummary>
<type>
<v>OldVsn = term()</v>
<d>In the case of an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and
@@ -241,31 +258,31 @@
<c>Module</c>. If no such attribute is defined, the version is
the checksum of the BEAM file.</d>
<v>State = term()</v>
- <d>The internal state of the channel.</d>
+ <d>Internal state of the channel.</d>
<v>Extra = term()</v>
- <d>Passed as-is from the <c>{advanced,Extra}</c>
+ <d>Passed "as-is" from the <c>{advanced,Extra}</c>
part of the update instruction.</d>
</type>
<desc>
- <p> Converts process state when code is changed.</p>
+ <p>Converts process state when code is changed.</p>
- <p>This function is called by a client side channel when it
- should update its internal state during a release
- upgrade/downgrade, i.e. when the instruction
- <c>{update,Module,Change,...}</c> where
- <c>Change={advanced,Extra}</c> is given in the <c>appup</c>
- file. See <seealso marker="doc/design_principles:release_handling#instr">OTP
- Design Principles</seealso> for more information.
+ <p>This function is called by a client-side channel when it
+ is to update its internal state during a release
+ upgrade or downgrade, that is, when the instruction
+ <c>{update,Module,Change,...}</c>, where
+ <c>Change={advanced,Extra}</c>, is given in the <c>appup</c>
+ file. For more information, refer to Section 9.11.6
+ Release Handling Instructions in the
+ <seealso marker="doc/design_principles:release_handling#instr">System Documentation</seealso>.
</p>
<note><p>Soft upgrade according to the OTP release concept
is not straight forward for the server side, as subsystem
- channel processes are spawned by the SSH application and
- hence added to its supervisor tree. It could be possible to
- upgrade the subsystem channels, when upgrading the user
- application, if the callback functions can handle two
- versions of the state, but this function can not be used in
- the normal way.</p>
+ channel processes are spawned by the <c>ssh</c> application and
+ hence added to its supervisor tree. The subsystem channels can
+ be upgraded when upgrading the user application, if the callback
+ functions can handle two versions of the state, but this function
+ cannot be used in the normal way.</p>
</note>
</desc>
@@ -274,36 +291,38 @@
<func>
<name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} |
{stop, Reason}</name>
- <fsummary> Makes necessary initializations and returns the
+ <fsummary>Makes necessary initializations and returns the
initial channel state if the initializations succeed.</fsummary>
<type>
- <v> Args = term() </v>
- <d> Last argument to ssh_channel:start_link/4.</d>
- <v> State = term() </v>
- <v> Reason = term() </v>
+ <v>Args = term()</v>
+ <d>Last argument to <c>ssh_channel:start_link/4</c>.</d>
+ <v>State = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p> Makes necessary initializations and returns the initial channel
+ <p>Makes necessary initializations and returns the initial channel
state if the initializations succeed.
</p>
- <p>For more detailed information on timeouts see the section
- <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
+ <p>For more detailed information on time-outs, see Section
+ <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>. </p>
</desc>
</func>
<func>
<name>Module:handle_call(Msg, From, State) -> Result</name>
- <fsummary> Handles messages sent by calling
- <c>ssh_channel:call/[2,3]</c></fsummary>
+ <fsummary>Handles messages sent by calling
+ <c>ssh_channel:call/[2,3]</c>.</fsummary>
<type>
<v>Msg = term()</v>
- <v>From = opaque to the user should be used as argument to
- ssh_channel:reply/2</v>
+ <v>From = opaque()</v>
+ <d>Is to be used as argument to
+ <seealso marker="#reply-2">ssh_channel:reply/2</seealso></d>
<v>State = term()</v>
<v>Result = {reply, Reply, NewState} | {reply, Reply, NewState, timeout()}
| {noreply, NewState} | {noreply , NewState, timeout()}
| {stop, Reason, Reply, NewState} | {stop, Reason, NewState} </v>
- <v>Reply = term() - will be the return value of ssh_channel:call/[2,3]</v>
+ <v>Reply = term()</v>
+ <d>Will be the return value of <seealso marker="#call-2">ssh_channel:call/[2,3]</seealso></d>
<v>NewState = term()</v>
<v>Reason = term()</v>
</type>
@@ -311,15 +330,15 @@
<p>Handles messages sent by calling
<seealso marker="#call-2">ssh_channel:call/[2,3]</seealso>
</p>
- <p>For more detailed information on timeouts see the section
- <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
+ <p>For more detailed information on time-outs,, see Section
+ <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>.</p>
</desc>
</func>
<func>
<name>Module:handle_cast(Msg, State) -> Result</name>
- <fsummary> Handles messages sent by calling
- <c>ssh_channel:cact/2</c></fsummary>
+ <fsummary>Handles messages sent by calling
+ <c>ssh_channel:cact/2</c>.</fsummary>
<type>
<v>Msg = term()</v>
<v>State = term()</v>
@@ -329,11 +348,11 @@
<v>Reason = term()</v>
</type>
<desc>
- <p> Handles messages sent by calling
- <c>ssh_channel:cast/2</c>
+ <p>Handles messages sent by calling
+ <c>ssh_channel:cast/2</c>.
</p>
- <p>For more detailed information on timeouts see the section
- <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
+ <p>For more detailed information on time-outs, see Section
+ <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>.</p>
</desc>
</func>
@@ -341,33 +360,33 @@
<name>Module:handle_msg(Msg, State) -> {ok, State} |
{stop, ChannelId, State}</name>
- <fsummary> Handle other messages than SSH connection protocol,
- call or cast messages sent to the channel.</fsummary>
+ <fsummary>Handles other messages than SSH connection protocol,
+ call, or cast messages sent to the channel.</fsummary>
<type>
<v>Msg = timeout | term()</v>
<v>ChannelId = ssh_channel_id()</v>
<v>State = term() </v>
</type>
<desc>
- <p>Handle other messages than ssh connection protocol, call or
+ <p>Handles other messages than SSH Connection Protocol, call, or
cast messages sent to the channel.
</p>
- <p> Possible erlang 'EXIT'-messages should be handled by this
- function and all channels should handle the following message.</p>
+ <p>Possible Erlang 'EXIT' messages is to be handled by this
+ function and all channels are to handle the following message.</p>
<taglist>
<tag><c><![CDATA[{ssh_channel_up, ssh_channel_id(),
ssh_connection_ref()}]]></c></tag>
- <item>This is the first messages that will be received by
- the channel, it is sent just before the <seealso
+ <item><p>This is the first message that the channel receives.
+ It is sent just before the <seealso
marker="#init-1">ssh_channel:init/1</seealso> function
- returns successfully. This is especially useful if the
+ returns successfully. This is especially useful if the
server wants to send a message to the client without first
receiving a message from it. If the message is not
- useful for your particular scenario just ignore it by
- immediately returning {ok, State}.
- </item>
+ useful for your particular scenario, ignore it by
+ immediately returning <c>{ok, State}</c>.
+ </p></item>
</taglist>
</desc>
</func>
@@ -375,42 +394,44 @@
<func>
<name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop,
ChannelId, State}</name>
- <fsummary> Handles ssh connection protocol messages. </fsummary>
+ <fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary>
<type>
- <v>Msg = <seealso marker="ssh_connection"> ssh_connection:event() </seealso> </v>
+ <v>Msg = ssh_connection:event()</v>
<v>ChannelId = ssh_channel_id()</v>
<v>State = term()</v>
</type>
<desc>
- <p> Handles SSH connection protocol messages that may need
- service specific attention.
+ <p>Handles SSH Connection Protocol messages that may need
+ service-specific attention. For details,
+ see <seealso marker="ssh_connection"> ssh_connection:event()</seealso>.
</p>
- <p> The following message is completely taken care of by the
- SSH channel behavior</p>
+ <p>The following message is taken care of by the
+ <c>ssh_channel</c> behavior.</p>
<taglist>
<tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
- <item> The channel behavior will send a close message to the
- other side if such a message has not already been sent and
- then terminate the channel with reason normal.</item>
+ <item><p>The channel behavior sends a close message to the
+ other side, if such a message has not already been sent.
+ Then it terminates the channel with reason <c>normal</c>.</p></item>
</taglist>
</desc>
</func>
<func>
<name>Module:terminate(Reason, State) -> _</name>
- <fsummary> </fsummary>
+ <fsummary>Does cleaning up before channel process termination.
+ </fsummary>
<type>
<v>Reason = term()</v>
<v>State = term()</v>
</type>
<desc>
<p>This function is called by a channel process when it is
- about to terminate. Before this function is called <seealso
+ about to terminate. Before this function is called, <seealso
marker="ssh_connection#close-2"> ssh_connection:close/2
- </seealso> will be called if it has not been called earlier.
- This function should do any necessary cleaning
+ </seealso> is called, if it has not been called earlier.
+ This function does any necessary cleaning
up. When it returns, the channel process terminates with
reason <c>Reason</c>. The return value is ignored.
</p>
diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml
index f3d05a8980..6b8932e5a7 100644
--- a/lib/ssh/doc/src/ssh_client_key_api.xml
+++ b/lib/ssh/doc/src/ssh_client_key_api.xml
@@ -9,116 +9,127 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_client_key_api</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
</header>
<module>ssh_client_key_api</module>
<modulesummary>
-behaviour(ssh_client_key_api).
</modulesummary>
<description>
- <p> Behavior describing the API for an SSH client's public key handling.
- By implementing the callbacks defined.
- in this behavior it is possible to customize the SSH client's public key
- handling. By default the SSH application implements this behavior
- with help of the standard openssh files, see <seealso marker="SSH_app"> ssh(6)</seealso>. </p>
+ <p>Behavior describing the API for public key handling of an SSH client. By implementing
+ the callbacks defined in this behavior, the public key handling of an SSH client can
+ be customized. By default the <c>ssh</c> application implements this behavior
+ with help of the standard OpenSSH files,
+ see the <seealso marker="SSH_app"> ssh(6)</seealso> application manual.</p>
</description>
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data
- type. For more details on public key data types
- see the <seealso marker="public_key:public_key_records"> public_key user's guide.</seealso>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both. For more details on public key data types,
+ refer to Section 2 Public Key Records in the
+ <seealso marker="public_key:public_key_records"> public_key user's guide:</seealso>
</p>
-
- <p> boolean() = true | false</p>
- <p> string() = [byte()] </p>
- <p> public_key() = #'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</p>
- <p> private_key() = #'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</p>
- <p> public_key_algorithm() = 'ssh-rsa'| 'ssh-dss' | atom()</p>
-
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p><c>[byte()]</c></p></item>
+ <tag><c>public_key() =</c></tag>
+ <item><p><c>#'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</c></p></item>
+ <tag><c>private_key() =</c></tag>
+ <item><p><c>#'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</c></p></item>
+ <tag><c>public_key_algorithm() =</c></tag>
+ <item><p><c>'ssh-rsa'| 'ssh-dss' | atom()</c></p></item>
+ </taglist>
</section>
<funcs>
<func>
<name>Module:add_host_key(HostNames, Key, ConnectOptions) -> ok | {error, Reason}</name>
- <fsummary>Adds a host key to the set of trusted host keys</fsummary>
+ <fsummary>Adds a host key to the set of trusted host keys.</fsummary>
<type>
<v>HostNames = string()</v>
- <d>Description of the host that owns the <c>PublicKey</c></d>
+ <d>Description of the host that owns the <c>PublicKey</c>.</d>
- <v>Key = public_key() </v>
- <d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
+ <v>Key = public_key()</v>
+ <d>Normally an RSA or DSA public key, but handling of other public keys can be added.</d>
- <v>ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
- <v>Reason = term() </v>
+ <v>ConnectOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
+ <v>Reason = term().</v>
</type>
<desc>
- <p> Adds a host key to the set of trusted host keys</p>
+ <p>Adds a host key to the set of trusted host keys.</p>
</desc>
</func>
<func>
<name>Module:is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name>
- <fsummary>Checks if a host key is trusted</fsummary>
+ <fsummary>Checks if a host key is trusted.</fsummary>
<type>
<v>Key = public_key() </v>
- <d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
+ <d>Normally an RSA or DSA public key, but handling of other public keys can be added.</d>
<v>Host = string()</v>
- <d>Description of the host</d>
+ <d>Description of the host.</d>
<v>Algorithm = public_key_algorithm()</v>
- <d> Host key algorithm. Should support 'ssh-rsa'| 'ssh-dss' but additional algorithms
+ <d>Host key algorithm. Is to support <c>'ssh-rsa'| 'ssh-dss'</c>, but more algorithms
can be handled.</d>
- <v> ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
+ <v>ConnectOptions = proplists:proplist() </v>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso>.</d>
- <v> Result = boolean()</v>
+ <v>Result = boolean()</v>
</type>
<desc>
- <p>Checks if a host key is trusted</p>
+ <p>Checks if a host key is trusted.</p>
</desc>
</func>
<func>
<name>Module:user_key(Algorithm, ConnectOptions) ->
{ok, PrivateKey} | {error, Reason}</name>
- <fsummary>Fetches the users "public key" matching the <c>Algorithm</c>.</fsummary>
+ <fsummary>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</fsummary>
<type>
<v>Algorithm = public_key_algorithm()</v>
- <d> Host key algorithm. Should support 'ssh-rsa'| 'ssh-dss' but additional algorithms
+ <d>Host key algorithm. Is to support <c>'ssh-rsa'| 'ssh-dss'</c> but more algorithms
can be handled.</d>
- <v> ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
+ <v>ConnectOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
- <v> PrivateKey = private_key()</v>
- <d> The private key of the user matching the <c>Algorithm</c></d>
+ <v>PrivateKey = private_key()</v>
+ <d>Private key of the user matching the <c>Algorithm</c>.</d>
- <v>Reason = term() </v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Fetches the users "public key" matching the <c>Algorithm</c>.
- <note><p>The private key contains the public key</p></note>
- </p>
+ <p>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</p>
+ <note><p>The private key contains the public key.</p></note>
+
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml
index 5e2926dfa6..150d46a9a2 100644
--- a/lib/ssh/doc/src/ssh_connection.xml
+++ b/lib/ssh/doc/src/ssh_connection.xml
@@ -5,175 +5,194 @@
<header>
<copyright>
<year>2008</year>
- <year>2014</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_connection</title>
+ <prepared></prepared>
+ <docno></docno>
<date></date>
+ <rev></rev>
</header>
<module>ssh_connection</module>
- <modulesummary>This module provides API functions to send <url href="http://www.ietf.org/rfc/rfc4254.txt"> SSH Connection Protocol </url>
- events to the other side of an SSH channel.
+ <modulesummary>
+ This module provides API functions to send SSH Connection Protocol
+ events to the other side of an SSH channel.
</modulesummary>
<description>
- <p>The SSH Connection Protocol is used by clients and servers
- (i.e. SSH channels) to communicate over the SSH connection. The
- API functions in this module sends SSH Connection Protocol events
- that are received as messages by the remote channel.
- In the case that the receiving channel is an Erlang process the
- message will be on the following format
- <c><![CDATA[{ssh_cm, ssh_connection_ref(), ssh_event_msg()}]]></c>. If the <seealso
- marker="ssh_channel">ssh_channel</seealso> behavior is used to
- implement the channel process these will be handled by
- <seealso
- marker="ssh_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2 </seealso>.</p>
+ <p>The <url href="http://www.ietf.org/rfc/rfc4254.txt">SSH Connection Protocol</url>
+ is used by clients and servers, that is, SSH channels, to communicate over the
+ SSH connection. The API functions in this module send SSH Connection Protocol events,
+ which are received as messages by the remote channel.
+ If the receiving channel is an Erlang process, the
+ messages have the format
+ <c><![CDATA[{ssh_cm, ssh_connection_ref(), ssh_event_msg()}]]></c>.
+ If the <seealso marker="ssh_channel">ssh_channel</seealso> behavior is used to
+ implement the channel process, these messages are handled by
+ <seealso marker="ssh_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2</seealso>.</p>
</description>
<section>
- <title>DATA TYPES </title>
-
- <p>Type definitions that are used more than once in this module and/or
- abstractions to indicate the intended use of the data type:</p>
-
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = list of ASCII characters</c></p>
- <p><c>timeout() = infinity | integer() - in milliseconds.</c></p>
- <p><c>ssh_connection_ref() - opaque to the user returned by
- ssh:connect/3 or sent to an SSH channel processes</c></p>
- <p><c>ssh_channel_id() = integer() </c></p>
- <p><c>ssh_data_type_code() = 1 ("stderr") | 0 ("normal") are
- currently valid values see</c> <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 5.2.</p>
- <p><c>ssh_request_status() = success | failure</c></p>
- <p><c>event() = {ssh_cm, ssh_connection_ref(), ssh_event_msg()} </c></p>
- <p><c>ssh_event_msg() = data_events() | status_events() | terminal_events() </c></p>
- <p><c>reason() = timeout | closed </c></p>
+ <title>DATA TYPES</title>
+
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both:</p>
+
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false </c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p>list of ASCII characters</p></item>
+ <tag><c>timeout() =</c></tag>
+ <item><p><c>infinity | integer()</c> in milliseconds</p></item>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() -as returned by
+ <c>ssh:connect/3</c> or sent to an SSH channel processes</p></item>
+ <tag><c>ssh_channel_id() =</c></tag>
+ <item><p><c>integer()</c></p></item>
+ <tag><c>ssh_data_type_code() =</c></tag>
+ <item><p><c>1</c> ("stderr") | <c>0</c> ("normal") are
+ valid values, see
+ <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> Section 5.2.</p></item>
+ <tag><c>ssh_request_status() =</c></tag>
+ <item><p> <c>success | failure</c></p></item>
+ <tag><c>event() =</c></tag>
+ <item><p><c>{ssh_cm, ssh_connection_ref(), ssh_event_msg()}</c></p></item>
+ <tag><c>ssh_event_msg() =</c></tag>
+ <item><p><c>data_events() | status_events() | terminal_events()</c></p></item>
+ <tag><c>reason() =</c></tag>
+ <item><p><c>timeout | closed</c></p></item>
+ </taglist>
<taglist>
- <tag><b>data_events()</b></tag>
+ <tag><em>data_events()</em></tag>
<item>
<taglist>
- <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}]]></c></tag>
- <item> Data has arrived on the channel. This event is sent as
- result of calling <seealso marker="ssh_connection#send-3"> ssh_connection:send/[3,4,5] </seealso></item>
+ <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}]]></c></tag>
+ <item><p>Data has arrived on the channel. This event is sent as a
+ result of calling <seealso marker="ssh_connection#send-3">
+ ssh_connection:send/[3,4,5]</seealso>.</p></item>
<tag><c><![CDATA[{eof, ssh_channel_id()}]]></c></tag>
- <item>Indicates that the other side will not send any more
- data. This event is sent as result of calling <seealso
- marker="ssh_connection#send_eof-2"> ssh_connection:send_eof/2</seealso>
- </item>
+ <item><p>Indicates that the other side sends no more data.
+ This event is sent as a result of calling <seealso
+ marker="ssh_connection#send_eof-2"> ssh_connection:send_eof/2</seealso>.
+ </p></item>
</taglist>
</item>
- <tag><b>status_events()</b></tag>
+ <tag><em>status_events()</em></tag>
<item>
<taglist>
<tag><c><![CDATA[{signal, ssh_channel_id(), ssh_signal()}]]></c></tag>
- <item>A signal can be delivered to the remote process/service
- using the following message. Some systems will not support
- signals, in which case they should ignore this message. There is
- currently no funtion to generate this event as the signals
- refered to are on OS-level and not something generated by an
- Erlang program.</item>
-
- <tag><c><![CDATA[{exit_signal, ssh_channel_id(), string() = ExitSignal, string() = ErrorMsg,
- string() = LanguageString}]]></c></tag>
-
- <item>A remote execution may terminate violently due to a signal
- then this message may be received. For details on valid string
- values see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> section 6.10. Special case of the signals
- mentioned above.</item>
-
- <tag><c><![CDATA[{exit_status, ssh_channel_id(), integer() = ExitStatus}]]></c></tag>
- <item> When the command running at the other end terminates, the
+ <item><p>A signal can be delivered to the remote process/service
+ using the following message. Some systems do not support
+ signals, in which case they are to ignore this message. There is
+ currently no function to generate this event as the signals
+ referred to are on OS-level and not something generated by an
+ Erlang program.</p></item>
+
+ <tag><c><![CDATA[{exit_signal, ssh_channel_id(), ExitSignal :: string(), ErrorMsg ::string(),
+ LanguageString :: string()}]]></c></tag>
+
+ <item><p>A remote execution can terminate violently because of a signal.
+ Then this message can be received. For details on valid string
+ values, see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>
+ Section 6.10, which shows a special case of these signals.</p></item>
+
+ <tag><c><![CDATA[{exit_status, ssh_channel_id(), ExitStatus :: integer()}]]></c></tag>
+ <item><p>When the command running at the other end terminates, the
following message can be sent to return the exit status of the
- command. A zero 'exit_status' usually means that the command
- terminated successfully. This event is sent as result of calling
+ command. A zero <c>exit_status</c> usually means that the command
+ terminated successfully. This event is sent as a result of calling
<seealso marker="ssh_connection#exit_status-3">
- ssh_connection:exit_status/3</seealso></item>
+ ssh_connection:exit_status/3</seealso>.</p></item>
<tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
- <item> This event is sent as result of calling
- <seealso marker="ssh_connection#close-2">ssh_connection:close/2</seealso> Both the handling of this
- event and sending of it will be taken care of by the
- <seealso marker="ssh_channel">ssh_channel</seealso> behavior.</item>
+ <item><p>This event is sent as a result of calling
+ <seealso marker="ssh_connection#close-2">ssh_connection:close/2</seealso>.
+ Both the handling of this event and sending it are taken care of by the
+ <seealso marker="ssh_channel">ssh_channel</seealso> behavior.</p></item>
</taglist>
</item>
- <tag><b>terminal_events()</b></tag>
+ <tag><em>terminal_events()</em></tag>
<item>
- <p> Channels implementing a shell and command execution on the
- server side should handle the following messages that may be sent by client channel processes. </p>
+ <p>Channels implementing a shell and command execution on the
+ server side are to handle the following messages that can be sent by client-
+ channel processes.</p>
- <note> <p>Events that includes a <c> WantReply</c> expects the event handling
- process to call <seealso marker="ssh_connection#reply_request-4">ssh_connection:reply_request/4</seealso>
- with the boolean value of <c> WantReply</c> as the second
- argument. </p></note>
+ <p>Events that include a <c>WantReply</c> expect the event handling
+ process to call <seealso marker="ssh_connection#reply_request-4">
+ ssh_connection:reply_request/4</seealso>
+ with the boolean value of <c>WantReply</c> as the second argument.</p>
<taglist>
- <tag><c><![CDATA[{env, ssh_channel_id(), boolean() = WantReply,
- string() = Var, string() = Value}]]></c></tag>
- <item> Environment variables may be passed to the shell/command
- to be started later. This event is sent as result of calling <seealso
- marker="ssh_connection#setenv-5"> ssh_connection:setenv/5</seealso>
- </item>
+ <tag><c><![CDATA[{env, ssh_channel_id(), WantReply :: boolean(),
+ Var ::string(), Value :: string()}]]></c></tag>
+ <item><p>Environment variables can be passed to the shell/command
+ to be started later. This event is sent as a result of calling <seealso
+ marker="ssh_connection#setenv-5"> ssh_connection:setenv/5</seealso>.
+ </p></item>
<tag><c><![CDATA[{pty, ssh_channel_id(),
- boolean() = WantReply, {string() = Terminal, integer() = CharWidth,
- integer() = RowHeight, integer() = PixelWidth, integer() = PixelHeight,
- [{atom() | integer() = Opcode,
- integer() = Value}] = TerminalModes}}]]></c></tag>
- <item>A pseudo-terminal has been requested for the
- session. Terminal is the value of the TERM environment
- variable value (e.g., vt100). Zero dimension parameters must
- be ignored. The character/row dimensions override the pixel
- dimensions (when nonzero). Pixel dimensions refer to the
- drawable area of the window. The <c>Opcode</c> in the
+ WantReply :: boolean(), {Terminal :: string(), CharWidth :: integer(),
+ RowHeight :: integer(), PixelWidth :: integer(), PixelHeight :: integer(),
+ TerminalModes :: [{Opcode :: atom() | integer(),
+ Value :: integer()}]}}]]></c></tag>
+ <item><p>A pseudo-terminal has been requested for the
+ session. <c>Terminal</c> is the value of the TERM environment
+ variable value, that is, <c>vt100</c>. Zero dimension parameters must
+ be ignored. The character/row dimensions override the pixel
+ dimensions (when non-zero). Pixel dimensions refer to the
+ drawable area of the window. <c>Opcode</c> in the
<c>TerminalModes</c> list is the mnemonic name, represented
- as an lowercase erlang atom, defined in
- <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 8.
- It may also be an opcode if the mnemonic name is not listed in the
- RFC. Example <c>OP code: 53, mnemonic name ECHO erlang atom:
- echo</c>.This event is sent as result of calling <seealso
- marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso></item>
-
- <tag><c><![CDATA[{shell, boolean() = WantReply}]]></c></tag>
- <item> This message will request that the user's default shell
- be started at the other end. This event is sent as result of calling <seealso
- marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>
- </item>
-
- <tag><c><![CDATA[{window_change, ssh_channel_id(), integer() = CharWidth,
- integer() = RowHeight, integer() = PixWidth, integer() = PixHeight}]]></c></tag>
- <item> When the window (terminal) size changes on the client
- side, it MAY send a message to the server side to inform it of
- the new dimensions. There is currently no API function to generate this
- event.</item>
+ as a lowercase Erlang atom, defined in
+ <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>, Section 8.
+ It can also be an <c>Opcode</c> if the mnemonic name is not listed in the
+ RFC. Example: <c>OP code: 53, mnemonic name ECHO erlang atom:
+ echo</c>. This event is sent as a result of calling <seealso
+ marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso>.</p></item>
+
+ <tag><c><![CDATA[{shell, WantReply :: boolean()}]]></c></tag>
+ <item><p>This message requests that the user default shell
+ is started at the other end. This event is sent as a result of calling
+ <seealso marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>.
+ </p></item>
+
+ <tag><c><![CDATA[{window_change, ssh_channel_id(), CharWidth() :: integer(),
+ RowHeight :: integer(), PixWidth :: integer(), PixHeight :: integer()}]]></c></tag>
+ <item><p>When the window (terminal) size changes on the client
+ side, it <em>can</em> send a message to the server side to inform it of
+ the new dimensions. No API function generates this event.</p></item>
<tag><c><![CDATA[{exec, ssh_channel_id(),
- boolean() = WantReply, string() = Cmd}]]></c></tag>
- <item> This message will request that the server starts
- execution of the given command. This event is sent as result of calling <seealso
- marker="ssh_connection#exec-4">ssh_connection:exec/4 </seealso>
- </item>
+ WantReply :: boolean(), Cmd :: string()}]]></c></tag>
+ <item><p>This message requests that the server starts
+ execution of the given command. This event is sent as a result of calling <seealso
+ marker="ssh_connection#exec-4">ssh_connection:exec/4 </seealso>.
+ </p></item>
</taglist>
</item>
</taglist>
@@ -183,80 +202,83 @@
<func>
<name>adjust_window(ConnectionRef, ChannelId, NumOfBytes) -> ok</name>
- <fsummary>Adjusts the SSH flowcontrol window. </fsummary>
+ <fsummary>Adjusts the SSH flow control window.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id() </v>
- <v> NumOfBytes = integer()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>NumOfBytes = integer()</v>
</type>
<desc>
- <p>Adjusts the SSH flowcontrol window. This shall be done by both client and server side channel processes.</p>
+ <p>Adjusts the SSH flow control window. This is to be done by both the
+ client- and server-side channel processes.</p>
- <note><p>Channels implemented with the <seealso marker="ssh_channel"> ssh_channel
- behavior</seealso> will normaly not need to call this function as flow control
- will be handled by the behavior. The behavior will adjust the window every time
+ <note><p>Channels implemented with the <seealso marker="ssh_channel"> ssh_channel</seealso>
+ behavior do not normally need to call this function as flow control
+ is handled by the behavior. The behavior adjusts the window every time
the callback <seealso marker="ssh_channel#Module:handle_ssh_msg-2">
- handle_ssh_msg/2 </seealso> has returned after processing channel data</p> </note>
+ handle_ssh_msg/2</seealso> returns after processing channel data.</p></note>
</desc>
</func>
<func>
<name>close(ConnectionRef, ChannelId) -> ok</name>
- <fsummary>Sends a close message on the channel <c>ChannelId</c>. </fsummary>
+ <fsummary>Sends a close message on the channel <c>ChannelId</c>.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
- <p>A server or client channel process can choose to close their session by sending a close event.
+ <p>A server- or client-channel process can choose to close their session by
+ sending a close event.
</p>
- <note><p>This function will be called by the ssh_channel
- behavior when the channel is terminated see <seealso
- marker="ssh_channel"> ssh_channel(3) </seealso> so channels implemented with the
- behavior should not call this function explicitly.</p></note>
+ <note><p>This function is called by the <c>ssh_channel</c>
+ behavior when the channel is terminated, see <seealso
+ marker="ssh_channel"> ssh_channel(3)</seealso>. Thus, channels implemented
+ with the behavior are not to call this function explicitly.</p></note>
</desc>
</func>
<func>
- <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() | {error, reason()} </name>
- <fsummary>Request that the server start the execution of the given command. </fsummary>
+ <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Requests that the server starts the execution of the given command.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Command = string()</v>
- <v>Timeout = timeout() </v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Command = string()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p>Should be called by a client channel process to request that the server starts execution of the
- given command, the result will be several messages according to the following pattern. Note
- that the last message will be a channel close message, as the exec request is a one time
- execution that closes the channel when it is done.</p>
+ <p>Is to be called by a client-channel process to request that the server starts
+ executing the given command. The result is several messages according to the
+ following pattern. The last message is a channel close message, as the <c>exec</c>
+ request is a one-time execution that closes the channel when it is done.</p>
<taglist>
- <tag><c> N x {ssh_cm, ssh_connection_ref(),
- {data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}} </c></tag>
- <item>The result of executing the command may be only one line
- or thousands of lines depending on the command.</item>
+ <tag><c>N x {ssh_cm, ssh_connection_ref(),
+ {data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}}</c></tag>
+ <item><p>The result of executing the command can be only one line
+ or thousands of lines depending on the command.</p></item>
<tag><c>0 or 1 x {ssh_cm, ssh_connection_ref(), {eof, ssh_channel_id()}}</c></tag>
- <item>Indicates that no more data will be sent.</item>
+ <item><p>Indicates that no more data is to be sent.</p></item>
<tag><c>0 or 1 x {ssh_cm,
ssh_connection_ref(), {exit_signal,
- ssh_channel_id(), string() = ExitSignal, string() = ErrorMsg, string() = LanguageString}}</c></tag>
- <item>Not all systems send signals. For details on valid string
- values see RFC 4254 section 6.10 </item>
+ ssh_channel_id(), ExitSignal :: string(), ErrorMsg :: string(), LanguageString :: string()}}</c></tag>
+ <item><p>Not all systems send signals. For details on valid string
+ values, see RFC 4254, Section 6.10</p></item>
<tag><c>0 or 1 x {ssh_cm, ssh_connection_ref(), {exit_status,
- ssh_channel_id(), integer() = ExitStatus}}</c></tag>
- <item>It is recommended by the <c>ssh connection protocol</c> that this
- message shall be sent, but that may not always be the case.</item>
+ ssh_channel_id(), ExitStatus :: integer()}}</c></tag>
+ <item><p>It is recommended by the SSH Connection Protocol to send this
+ message, but that is not always the case.</p></item>
- <tag><c> 1 x {ssh_cm, ssh_connection_ref(),
+ <tag><c>1 x {ssh_cm, ssh_connection_ref(),
{closed, ssh_channel_id()}}</c></tag>
- <item>Indicates that the ssh channel started for the
- execution of the command has now been shutdown.</item>
+ <item><p>Indicates that the <c>ssh_channel</c> started for the
+ execution of the command has now been shut down.</p></item>
</taglist>
</desc>
</func>
@@ -265,78 +287,72 @@
<name>exit_status(ConnectionRef, ChannelId, Status) -> ok</name>
<fsummary>Sends the exit status of a command to the client.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Status = integer()</v>
+ <v>ConnectionRef = ssh_connection_ref() </v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Status = integer()</v>
</type>
<desc>
- <p>Should be called by a server channel process to sends the exit status of a command to the client.</p>
+ <p>Is to be called by a server-channel process to send the exit status of a command
+ to the client.</p>
</desc>
</func>
<func>
- <name>ptty_alloc(ConnectionRef, ChannelId, Options) -> </name>
- <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() | {error, reason()} </name>
- <fsummary>Send status replies to requests that want such replies. </fsummary>
+ <name>ptty_alloc(ConnectionRef, ChannelId, Options) -></name>
+ <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Sends an SSH Connection Protocol <c>pty_req</c>,
+ to allocate a pseudo-terminal.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Options = proplists:proplist()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Options = proplists:proplist()</v>
</type>
<desc>
- <p> Sends a SSH Connection Protocol pty_req, to allocate a pseudo tty.
- Should be called by a SSH client process.
- Options are:
- </p>
+ <p>Sends an SSH Connection Protocol <c>pty_req</c>, to allocate a pseudo-terminal.
+ Is to be called by an SSH client process.</p>
+ <p>Options:</p>
<taglist>
<tag>{term, string()}</tag>
- <item>
- Defaults to os:getenv("TERM") or "vt100" if it is undefined.
- </item>
+ <item><p>Defaults to <em>os:getenv("TERM")</em> or <em>vt100</em>
+ if it is undefined.</p></item>
+
<tag>{width, integer()}</tag>
- <item>
- Defaults to 80 if pixel_width is not defined.
- </item>
+ <item><p>Defaults to 80 if <c>pixel_width</c> is not defined.</p></item>
+
<tag>{height, integer()}</tag>
- <item>
- Defaults to 24 if pixel_height is not defined.
- </item>
+ <item><p>Defaults to 24 if <c>pixel_height</c> is not defined.</p></item>
+
<tag>{pixel_width, integer()}</tag>
- <item>
- Is disregarded if width is defined.
- </item>
+ <item><p>Is disregarded if <c>width</c> is defined.</p></item>
+
<tag>{pixel_height, integer()}</tag>
- <item>
- Is disregarded if height is defined.
- </item>
+ <item><p>Is disregarded if <c>height</c> is defined.</p></item>
+
<tag>{pty_opts, [{posix_atom(), integer()}]}</tag>
- <item>
- Option may be an empty list, otherwise
- see possible POSIX names in section 8 in <url href="http://www.ietf.org/rfc/rfc4254.txt"> RFC 4254</url>.
+ <item><p>Option can be an empty list. Otherwise, see possible <em>POSIX</em> names
+ in Section 8 in <url href="http://www.ietf.org/rfc/rfc4254.txt"> RFC 4254</url>.</p>
</item>
</taglist>
-
</desc>
</func>
- <func>
+ <func>
<name>reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name>
- <fsummary>Send status replies to requests that want such replies. </fsummary>
+ <fsummary>Sends status replies to requests that want such replies.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> WantReply = boolean()</v>
- <v> Status = ssh_request_status() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>WantReply = boolean()</v>
+ <v>Status = ssh_request_status()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
<p>Sends status replies to requests where the requester has
- stated that they want a status report e.i .<c> WantReply = true</c>,
- if <c> WantReply</c> is false calling this function will be a
- "noop". Should be called while handling an ssh connection
- protocol message containing a <c>WantReply</c> boolean
- value.
- </p>
+ stated that it wants a status report, that is, <c>WantReply = true</c>.
+ If <c>WantReply</c> is <c>false</c>, calling this function becomes a
+ "noop". Is to be called while handling an SSH Connection
+ Protocol message containing a <c>WantReply</c> boolean value.</p>
</desc>
</func>
@@ -346,98 +362,103 @@
<name>send(ConnectionRef, ChannelId, Type, Data) -></name>
<name>send(ConnectionRef, ChannelId, Type, Data, TimeOut) ->
ok | {error, timeout} | {error, closed}</name>
- <fsummary>Sends channel data </fsummary>
+ <fsummary>Sends channel data.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Data = binary()</v>
- <v> Type = ssh_data_type_code()</v>
- <v> Timeout = timeout()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Data = binary()</v>
+ <v>Type = ssh_data_type_code()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p>Should be called by client- and server channel processes to send data to each other.
+ <p>Is to be called by client- and server-channel processes to send data to each other.
+ </p>
+ <p>The function <seealso marker="ssh:ssh_connection#subsystem/4">subsystem/4</seealso> and subsequent
+ calls of <c>send/3,4,5</c> must be executed in the same process.
</p>
</desc>
</func>
<func>
<name>send_eof(ConnectionRef, ChannelId) -> ok | {error, closed}</name>
- <fsummary>Sends eof on the channel <c>ChannelId</c>. </fsummary>
+ <fsummary>Sends EOF on channel <c>ChannelId</c>.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
- <p>Sends eof on the channel <c>ChannelId</c>.
- </p>
+ <p>Sends EOF on channel <c>ChannelId</c>.</p>
</desc>
</func>
<func>
- <name>session_channel(ConnectionRef, Timeout) -> </name>
+ <name>session_channel(ConnectionRef, Timeout) -></name>
<name>session_channel(ConnectionRef, InitialWindowSize,
MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, reason()}</name>
- <fsummary>Opens a channel for a ssh session. </fsummary>
+ <fsummary>Opens a channel for an SSH session.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref()</v>
- <v> InitialWindowSize = integer() </v>
- <v> MaxPacketSize = integer() </v>
- <v> Timeout = timeout()</v>
- <v> Reason = term() </v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>InitialWindowSize = integer()</v>
+ <v>MaxPacketSize = integer()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
</type>
<desc>
<p>Opens a channel for an SSH session. The channel id returned from this function
- is the id used as input to the other funtions in this module.
- </p>
+ is the id used as input to the other functions in this module.</p>
</desc>
</func>
<func>
- <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() | {error, reason()} </name>
- <fsummary> Environment variables may be passed to the
+ <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Environment variables can be passed to the
shell/command to be started later.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Var = string()</v>
- <v> Value = string()</v>
- <v> Timeout = timeout()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Var = string()</v>
+ <v>Value = string()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p> Environment variables may be passed before starting the
- shell/command. Should be called by a client channel processes.
- </p>
+ <p>Environment variables can be passed before starting the
+ shell/command. Is to be called by a client channel processes.</p>
</desc>
</func>
<func>
<name>shell(ConnectionRef, ChannelId) -> ssh_request_status() | {error, closed}
</name>
- <fsummary> Requests that the user's default shell (typically
- defined in /etc/passwd in UNIX systems) shall be executed at the server
- end. </fsummary>
+ <fsummary>Requests that the user default shell (typically defined in
+ /etc/passwd in Unix systems) is to be executed at the server end.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
- <p> Should be called by a client channel process to request that the user's default shell (typically
- defined in /etc/passwd in UNIX systems) shall be executed at the server end.
- </p>
+ <p>Is to be called by a client channel process to request that the user default
+ shell (typically defined in /etc/passwd in Unix systems) is executed
+ at the server end.</p>
</desc>
</func>
<func>
- <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() | {error, reason()} </name>
- <fsummary> </fsummary>
+ <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Requests to execute a predefined subsystem on the server.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Subsystem = string()</v>
- <v> Timeout = timeout()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Subsystem = string()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p> Should be called by a client channel process for requesting to execute a predefined subsystem on the server.
+ <p>Is to be called by a client-channel process for requesting to execute a predefined
+ subsystem on the server.
+ </p>
+ <p>The function <c>subsystem/4</c> and subsequent calls of
+ <seealso marker="ssh:ssh_connection#send/3">send/3,4,5</seealso> must be executed in the same process.
</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_server_key_api.xml b/lib/ssh/doc/src/ssh_server_key_api.xml
index f7133e4ba5..a0694ca8d9 100644
--- a/lib/ssh/doc/src/ssh_server_key_api.xml
+++ b/lib/ssh/doc/src/ssh_server_key_api.xml
@@ -5,86 +5,100 @@
<header>
<copyright>
<year>2012</year>
- <year>2013</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_server_key_api</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
</header>
<module>ssh_server_key_api</module>
<modulesummary>
-behaviour(ssh_server_key_api).
</modulesummary>
<description>
- <p> Behaviour describing the API for an SSH server's public key handling. By implementing the callbacks defined
- in this behavior it is possible to customize the SSH server's public key
- handling. By default the SSH application implements this behavior
- with help of the standard openssh files, see <seealso marker="SSH_app"> ssh(6)</seealso>.</p>
+ <p>Behaviour describing the API for public key handling of an SSH server. By implementing
+ the callbacks defined in this behavior, the public key handling of an SSH server can
+ be customized. By default the SSH application implements this behavior
+ with help of the standard OpenSSH files,
+ see the <seealso marker="SSH_app"> ssh(6)</seealso> application manual.</p>
</description>
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data
- type. For more details on public key data types
- see the <seealso marker="public_key:public_key_records"> public_key user's guide.</seealso>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both. For more details on public key data types,
+ refer to Section 2 Public Key Records in the
+ <seealso marker="public_key:public_key_records"> public_key user's guide</seealso>.
</p>
- <p> boolean() = true | false</p>
- <p> string() = [byte()]</p>
- <p> public_key() = #'RSAPublicKey'{} | {integer(), #'Dss-Parms'{}} | term()</p>
- <p> private_key() = #'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</p>
- <p> public_key_algorithm() = 'ssh-rsa' | 'ssh-dss' | atom()</p>
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p><c>[byte()]</c></p></item>
+ <tag><c>public_key() =</c></tag>
+ <item><p><c>#'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</c></p></item>
+ <tag><c>private_key() =</c></tag>
+ <item><p><c>#'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</c></p></item>
+ <tag><c>public_key_algorithm() =</c></tag>
+ <item><p><c>'ssh-rsa'| 'ssh-dss' | atom()</c></p></item>
+ </taglist>
</section>
-
+
<funcs>
<func>
<name>Module:host_key(Algorithm, DaemonOptions) ->
{ok, Key} | {error, Reason}</name>
- <fsummary>Fetches the hosts private key </fsummary>
+ <fsummary>Fetches the host’s private key.</fsummary>
<type>
<v>Algorithm = public_key_algorithm()</v>
- <d> Host key algorithm. Should support 'ssh-rsa' | 'ssh-dss' but additional algorithms
+ <d>Host key algorithm. Is to support <c>'ssh-rsa' | 'ssh-dss'</c>, but more algorithms
can be handled.</d>
- <v> DaemonOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso></d>
- <v> Key = private_key()</v>
- <d> The private key of the host matching the <c>Algorithm</c></d>
- <v>Reason = term() </v>
+ <v>DaemonOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</d>
+ <v>Key = private_key()</v>
+ <d>Private key of the host matching the <c>Algorithm</c>.</d>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Fetches the hosts private key</p>
+ <p>Fetches the private key of the host.</p>
</desc>
</func>
<func>
<name>Module:is_auth_key(Key, User, DaemonOptions) -> Result</name>
- <fsummary> Checks if the user key is authorized</fsummary>
+ <fsummary>Checks if the user key is authorized.</fsummary>
<type>
- <v> Key = public_key() </v>
- <d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
- <v> User = string()</v>
- <d> The user owning the public key</d>
- <v> DaemonOptions = proplists:proplist() </v>
- <d> Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso></d>
- <v> Result = boolean()</v>
+ <v>Key = public_key()</v>
+ <d>Normally an RSA or DSA public key, but handling of other public keys can be added</d>
+ <v>User = string()</v>
+ <d>User owning the public key.</d>
+ <v>DaemonOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</d>
+ <v>Result = boolean()</v>
</type>
<desc>
- <p> Checks if the user key is authorized </p>
+ <p>Checks if the user key is authorized.</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml
index ab111562f9..f4b41b74f3 100644
--- a/lib/ssh/doc/src/ssh_sftp.xml
+++ b/lib/ssh/doc/src/ssh_sftp.xml
@@ -4,150 +4,196 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2014</year>
+ <year>2005</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssh_sftp</title>
<prepared>OTP</prepared>
+ <docno></docno>
<date>2005-09-22</date>
+ <rev></rev>
<file>ssh_sftp.sgml</file>
</header>
<module>ssh_sftp</module>
<modulesummary>SFTP client.</modulesummary>
<description>
- <p>This module implements an SFTP (SSH FTP) client. SFTP is a
+ <p>This module implements an SSH FTP (SFTP) client. SFTP is a
secure, encrypted file transfer service available for
SSH.</p>
</description>
<section>
- <title>DATA TYPES </title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data type:
+ <title>DATA TYPES</title>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data type, or both:
</p>
- <p><c>ssh_connection_ref() - opaque to the user
- returned by ssh:connect/3</c></p>
- <p><c>timeout() = infinity | integer() - in milliseconds.</c></p>
+
+ <taglist>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() - as returned by <c>ssh:connect/3</c></p></item>
+ <tag><c>timeout()</c></tag>
+ <item><p>= <c>infinity | integer() in milliseconds. Default infinity.</c></p></item>
+ </taglist>
</section>
<section>
- <title>TIMEOUTS </title>
- <p>If the request functions for the SFTP channel return {error, timeout}
- it does not guarantee that the request did not reach the server and was
- not performed, it only means that we did not receive an answer from the
- server within the time that was expected.</p>
+ <title>Time-outs</title>
+ <p>If the request functions for the SFTP channel return <c>{error, timeout}</c>,
+ it does not guarantee that the request never reached the server and was
+ not performed. It only means that no answer was received from the
+ server within the expected time.</p>
</section>
<funcs>
+ <func>
+ <name>apread(ChannelPid, Handle, Position, Len) -> {async, N} | {error, Reason}</name>
+ <fsummary>Reads asynchronously from an open file.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>N = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc><p>The <c><![CDATA[apread]]></c> function reads from a specified position,
+ combining the <c><![CDATA[position]]></c> and <c><![CDATA[aread]]></c> functions.</p>
+ <p><seealso marker="#apread-4">ssh_sftp:apread/4</seealso></p> </desc>
+ </func>
+
+ <func>
+ <name>apwrite(ChannelPid, Handle, Position, Data) -> ok | {error, Reason}</name>
+ <fsummary>Writes asynchronously to an open file.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>Data = binary()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p><c><![CDATA[apwrite]]></c> writes on a specified position, combining
+ the <c><![CDATA[position]]></c> and <c><![CDATA[awrite]]></c> operations.</p>
+ <p><seealso marker="#awrite-3">ssh_sftp:awrite/3</seealso> </p></desc>
+ </func>
+
+ <func>
+ <name>aread(ChannelPid, Handle, Len) -> {async, N} | {error, Error}</name>
+ <fsummary>Reads asynchronously from an open file.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>N = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Reads from an open file, without waiting for the result. If the
+ handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where <c>N</c>
+ is a term guaranteed to be unique between calls of <c><![CDATA[aread]]></c>.
+ The actual data is sent as a message to the calling process. This
+ message has the form <c><![CDATA[{async_reply, N, Result}]]></c>, where
+ <c><![CDATA[Result]]></c> is the result from the read, either <c><![CDATA[{ok, Data}]]></c>,
+ <c><![CDATA[eof]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
+ </desc>
+ </func>
+
+
+
<func>
- <name>start_channel(ConnectionRef) -> </name>
- <name>start_channel(ConnectionRef, Options) -> </name>
- <name>start_channel(Host, Options) -></name>
- <name>start_channel(Host, Port, Options) -> {ok, Pid} | {ok, Pid, ConnectionRef} |
- {error, Reason}</name>
- <fsummary>Starts a SFTP client</fsummary>
+ <name>awrite(ChannelPid, Handle, Data) -> ok | {error, Reason}</name>
+ <fsummary>Writes asynchronously to an open file.</fsummary>
<type>
- <v>Host = string()</v>
- <v>ConnectionRef = ssh_connection_ref()</v>
- <v>Port = integer()</v>
- <v>Options = [{Option, Value}]</v>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>Data = binary()</v>
+ <v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>If no connection reference is provided, a connection is set
- up and the new connection is returned. An SSH channel process
- is started to handle the communication with the SFTP server.
- The returned pid for this process should be used as input to
- all other API functions in this module.</p>
-
- <p>Options are:</p>
- <taglist>
- <tag><c><![CDATA[{timeout, timeout()}]]></c></tag>
- <item>
- <p>The timeout is passed to the ssh_channel start function,
- and defaults to infinity.</p>
- </item>
- <tag>
- <p><c><![CDATA[{sftp_vsn, integer()}]]></c></p>
- </tag>
- <item>
- <p>
- Desired SFTP protocol version.
- The actual version will be the minimum of
- the desired version and the maximum supported
- versions by the SFTP server.
- </p>
- </item>
- </taglist>
- <p>All other options are directly passed to
- <seealso marker="ssh">ssh:connect/3</seealso> or ignored if a
- connection is already provided. </p>
+ <p>Writes to an open file, without waiting for the result. If the
+ handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where <c>N</c>
+ is a term guaranteed to be unique between calls of
+ <c><![CDATA[awrite]]></c>. The result of the <c><![CDATA[write]]></c> operation is sent
+ as a message to the calling process. This message has the form
+ <c><![CDATA[{async_reply, N, Result}]]></c>, where <c><![CDATA[Result]]></c> is the result
+ from the write, either <c><![CDATA[ok]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
</desc>
</func>
<func>
- <name>stop_channel(ChannelPid) -> ok</name>
- <fsummary>Stops the SFTP client channel.</fsummary>
+ <name>close(ChannelPid, Handle) -></name>
+ <name>close(ChannelPid, Handle, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Closes an open handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Stops an SFTP channel. Does not close the SSH connetion.
- Use <seealso marker="ssh">ssh:close/1</seealso> to close it.</p>
+ <p>Closes a handle to an open file or directory on the server.</p>
</desc>
</func>
-
+
<func>
- <name>read_file(ChannelPid, File) -> </name>
- <name>read_file(ChannelPid, File, Timeout) -> {ok, Data} | {error, Reason}</name>
- <fsummary>Read a file</fsummary>
+ <name>delete(ChannelPid, Name) -></name>
+ <name>delete(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Deletes a file.</fsummary>
<type>
- <v>ChannelPid = pid()</v>
- <v>File = string()</v>
- <v>Data = binary()</v>
+ <v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
<v>Timeout = timeout()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Reads a file from the server, and returns the data in a binary,
- like <c><![CDATA[file:read_file/1]]></c>.</p>
+ <p>Deletes the file specified by <c><![CDATA[Name]]></c>, like
+ <seealso marker="kernel:file#delete-1">file:delete/1</seealso></p>
</desc>
</func>
+
<func>
- <name>write_file(ChannelPid, File, Iolist) -> </name>
- <name>write_file(ChannelPid, File, Iolist, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Write a file</fsummary>
+ <name>del_dir(ChannelPid, Name) -></name>
+ <name>del_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Deletes an empty directory.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>File = string()</v>
- <v>Iolist = iolist()</v>
+ <v>Name = string()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes a file to the server, like
- <c><![CDATA[file:write_file/2]]></c>. The file is created if
- it does not exist or is owerwritten if it does.</p>
+ <p>Deletes a directory specified by <c><![CDATA[Name]]></c>.
+ The directory must be empty before it can be successfully deleted.
+ </p>
</desc>
</func>
- <func>
- <name>list_dir(ChannelPid, Path) -> </name>
+
+ <func>
+ <name>list_dir(ChannelPid, Path) -></name>
<name>list_dir(ChannelPid, Path, Timeout) -> {ok, Filenames} | {error, Reason}</name>
- <fsummary>List directory</fsummary>
+ <fsummary>Lists the directory.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Path = string()</v>
@@ -161,10 +207,45 @@
filenames as a list of strings.</p>
</desc>
</func>
+
<func>
- <name>open(ChannelPid, File, Mode) -> </name>
+ <name>make_dir(ChannelPid, Name) -></name>
+ <name>make_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Creates a directory.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Creates a directory specified by <c><![CDATA[Name]]></c>. <c><![CDATA[Name]]></c>
+ must be a full path to a new directory. The directory can only be
+ created in an existing directory.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>make_symlink(ChannelPid, Name, Target) -></name>
+ <name>make_symlink(ChannelPid, Name, Target, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Creates a symbolic link.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
+ <v>Target = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Creates a symbolic link pointing to <c><![CDATA[Target]]></c> with the
+ name <c><![CDATA[Name]]></c>, like
+ <seealso marker="kernel:file#make_symlink-2">file:make_symlink/2</seealso></p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(ChannelPid, File, Mode) -></name>
<name>open(ChannelPid, File, Mode, Timeout) -> {ok, Handle} | {error, Reason}</name>
- <fsummary>Open a file and return a handle</fsummary>
+ <fsummary>Opens a file and returns a handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>File = string()</v>
@@ -175,14 +256,14 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Opens a file on the server, and returns a handle that
+ <p>Opens a file on the server and returns a handle, which
can be used for reading or writing.</p>
</desc>
</func>
<func>
- <name>opendir(ChannelPid, Path) -> </name>
+ <name>opendir(ChannelPid, Path) -></name>
<name>opendir(ChannelPid, Path, Timeout) -> {ok, Handle} | {error, Reason}</name>
- <fsummary>Open a directory and return a handle</fsummary>
+ <fsummary>Opens a directory and returns a handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Path = string()</v>
@@ -190,7 +271,7 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Opens a handle to a directory on the server, the handle
+ <p>Opens a handle to a directory on the server. The handle
can be used for reading directory contents.</p>
</desc>
</func>
@@ -198,14 +279,15 @@
<func>
<name>open_tar(ChannelPid, Path, Mode) -></name>
<name>open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, Reason}</name>
- <fsummary>Opens a tar file on the server to which <v>ChannelPid</v> is connected and returns a handle</fsummary>
+ <fsummary>Opens a tar file on the server to which <c>ChannelPid</c>
+ is connected and returns a handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Path = string()</v>
- <v>Mode = [read] | [write] | [read,EncryptOpt] | [write,DecryptOpt] </v>
+ <v>Mode = [read] | [write] | [read,EncryptOpt] | [write,DecryptOpt]</v>
<v>EncryptOpt = {crypto,{InitFun,EncryptFun,CloseFun}}</v>
<v>DecryptOpt = {crypto,{InitFun,DecryptFun}}</v>
- <v>InitFun = (fun() -> {ok,CryptoState}) | (fun() -> {ok,CryptoState,ChunkSize}) </v>
+ <v>InitFun = (fun() -> {ok,CryptoState}) | (fun() -> {ok,CryptoState,ChunkSize})</v>
<v>CryptoState = any()</v>
<v>ChunkSize = undefined | pos_integer()</v>
<v>EncryptFun = (fun(PlainBin,CryptoState) -> EncryptResult)</v>
@@ -219,113 +301,86 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Opens a handle to a tar file on the server associated with <c>ChannelPid</c>. The handle
- can be used for remote tar creation and extraction as defined by the
- <seealso marker="stdlib:erl_tar#init/3">erl_tar:init/3</seealso> function.
+ <p>Opens a handle to a tar file on the server, associated with <c>ChannelPid</c>.
+ The handle can be used for remote tar creation and extraction, as defined by the
+ <seealso marker="stdlib:erl_tar#init-3">erl_tar:init/3</seealso> function.
</p>
- <p>An example of writing and then reading a tar file:</p>
- <code type="none">
- {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:add(HandleWrite, .... ),
- ...
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:close(HandleWrite),
-
- %% And for reading
- {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]),
- {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
- ok = erl_tar:close(HandleRead),
- </code>
-
- <p>The <c>crypto</c> mode option is applied to the generated stream of bytes just prior to sending
- them to the sftp server. This is intended for encryption but could of course be used for other
+
+ <p> For code exampel see Section
+ <seealso marker="using_ssh">SFTP Client with TAR Compression and Encryption</seealso> in
+ the ssh Users Guide. </p>
+
+ <p>The <c>crypto</c> mode option is applied to the generated stream of bytes prior to sending
+ them to the SFTP server. This is intended for encryption but can be used for other
purposes.
</p>
<p>The <c>InitFun</c> is applied once
- prior to any other crypto operation. The returned <c>CryptoState</c> is then folded into
- repeated applications of the <c>EncryptFun</c> or <c>DecryptFun</c>. The binary returned
- from those Funs are sent further to the remote sftp server. Finally - if doing encryption
- - the <c>CloseFun</c> is applied to the last piece of data. The <c>CloseFun</c> is
+ prior to any other <c>crypto</c> operation. The returned <c>CryptoState</c> is then folded into
+ repeated applications of the <c>EncryptFun</c> or <c>DecryptFun</c>. The binary returned
+ from those funs are sent further to the remote SFTP server. Finally, if doing encryption,
+ the <c>CloseFun</c> is applied to the last piece of data. The <c>CloseFun</c> is
responsible for padding (if needed) and encryption of that last piece.
</p>
<p>The <c>ChunkSize</c> defines the size of the <c>PlainBin</c>s that <c>EncodeFun</c> is applied
- to. If the <c>ChunkSize</c> is <c>undefined</c> the size of the <c>PlainBin</c>s varies because
- this is inteded for stream crypto while a fixed <c>ChunkSize</c> is intended for block crypto. It
- is possible to change the <c>ChunkSize</c>s in the return from the <c>EncryptFun</c> or
- <c>DecryptFun</c>. It is in fact possible to change the value between <c>pos_integer()</c> and
- <c>undefined</c>.
+ to. If the <c>ChunkSize</c> is <c>undefined</c>, the size of the <c>PlainBin</c>s varies,
+ because this is intended for stream crypto, whereas a fixed <c>ChunkSize</c> is intended for block crypto.
+ <c>ChunkSize</c>s can be changed in the return from the <c>EncryptFun</c> or
+ <c>DecryptFun</c>. The value can be changed between <c>pos_integer()</c> and <c>undefined</c>.
</p>
- <p>The write and read example above can be extended with encryption and decryption:</p>
- <code type="none">
- %% First three parameters depending on which crypto type we select:
- Key = &lt;&lt;"This is a 256 bit key. abcdefghi">>,
- Ivec0 = crypto:rand_bytes(16),
- DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc
-
- %% Initialization of the CryptoState, in this case it is the Ivector.
- InitFun = fun() -> {ok, Ivec0, DataSize} end,
-
- %% How to encrypt:
- EncryptFun =
- fun(PlainBin,Ivec) ->
- EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
- {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
- end,
-
- %% What to do with the very last block:
- CloseFun =
- fun(PlainBin, Ivec) ->
- EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
- pad(16,PlainBin) %% Last chunk
- ),
- {ok, EncryptedBin}
- end,
-
- Cw = {InitFun,EncryptFun,CloseFun},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:add(HandleWrite, .... ),
- ...
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:close(HandleWrite),
-
- %% And for decryption (in this crypto example we could use the same InitFun
- %% as for encryption):
- DecryptFun =
- fun(EncryptedBin,Ivec) ->
- PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
- {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
- end,
-
- Cr = {InitFun,DecryptFun},
- {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]),
- {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
- ok = erl_tar:close(HandleRead),
- </code>
+
</desc>
</func>
<func>
- <name>close(ChannelPid, Handle) -> </name>
- <name>close(ChannelPid, Handle, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Close an open handle</fsummary>
+ <name>position(ChannelPid, Handle, Location) -></name>
+ <name>position(ChannelPid, Handle, Location, Timeout) -> {ok, NewPosition} | {error, Reason}</name>
+ <fsummary>Sets the file position of a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
+ <v>Location = Offset
+ | {bof, Offset} | {cur, Offset} | {eof, Offset} | bof | cur | eof</v>
+ <v>Offset = integer()</v>
<v>Timeout = timeout()</v>
+ <v>NewPosition = integer()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Closes a handle to an open file or directory on the server.</p>
+ <p>Sets the file position of the file referenced by <c><![CDATA[Handle]]></c>.
+ Returns <c><![CDATA[{ok, NewPosition}]]></c> (as an absolute offset) if
+ successful, otherwise <c><![CDATA[{error, Reason}]]></c>. <c><![CDATA[Location]]></c> is
+ one of the following:</p>
+ <taglist>
+ <tag><c><![CDATA[Offset]]></c></tag>
+ <item>
+ <p>The same as <c><![CDATA[{bof, Offset}]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[{bof, Offset}]]></c></tag>
+ <item>
+ <p>Absolute offset.</p>
+ </item>
+ <tag><c><![CDATA[{cur, Offset}]]></c></tag>
+ <item>
+ <p>Offset from the current position.</p>
+ </item>
+ <tag><c><![CDATA[{eof, Offset}]]></c></tag>
+ <item>
+ <p>Offset from the end of file.</p>
+ </item>
+ <tag><c><![CDATA[bof | cur | eof]]></c></tag>
+ <item>
+ <p>The same as eariler with <c><![CDATA[Offset]]></c> 0,
+ that is, <c><![CDATA[{bof, 0} | {cur, 0} | {eof, 0}]]></c>.
+ </p>
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
- <name>read(ChannelPid, Handle, Len) -> </name>
- <name>read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, Error}</name>
- <name>pread(ChannelPid, Handle, Position, Len) -> </name>
+ <name>pread(ChannelPid, Handle, Position, Len) -></name>
<name>pread(ChannelPid, Handle, Position, Len, Timeout) -> {ok, Data} | eof | {error, Error}</name>
- <fsummary>Read from an open file</fsummary>
+ <fsummary>Reads from an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
@@ -336,161 +391,114 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Reads <c><![CDATA[Len]]></c> bytes from the file referenced by
- <c><![CDATA[Handle]]></c>. Returns <c><![CDATA[{ok, Data}]]></c>, <c><![CDATA[eof]]></c>, or
- <c><![CDATA[{error, Reason}]]></c>. If the file is opened with <c><![CDATA[binary]]></c>,
- <c><![CDATA[Data]]></c> is a binary, otherwise it is a string.</p>
- <p>If the file is read past eof, only the remaining bytes
- will be read and returned. If no bytes are read, <c><![CDATA[eof]]></c>
- is returned.</p>
- <p>The <c><![CDATA[pread]]></c> function reads from a specified position,
- combining the <c><![CDATA[position]]></c> and <c><![CDATA[read]]></c> functions.</p>
+ <p>The <c><![CDATA[pread]]></c> function reads from a specified position,
+ combining the <c><![CDATA[position]]></c> and <c><![CDATA[read]]></c> functions.</p>
+ <p><seealso marker="#read-4">ssh_sftp:read/4</seealso></p>
</desc>
</func>
+
<func>
- <name>aread(ChannelPid, Handle, Len) -> {async, N} | {error, Error}</name>
- <name>apread(ChannelPid, Handle, Position, Len) -> {async, N} | {error, Error}</name>
- <fsummary>Read asynchronously from an open file</fsummary>
+ <name>pwrite(ChannelPid, Handle, Position, Data) -> ok</name>
+ <name>pwrite(ChannelPid, Handle, Position, Data, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Writes to an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
<v>Position = integer()</v>
- <v>Len = integer()</v>
- <v>N = term()</v>
+ <v>Data = iolist()</v>
+ <v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Reads from an open file, without waiting for the result. If the
- handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where N
- is a term guaranteed to be unique between calls of <c><![CDATA[aread]]></c>.
- The actual data is sent as a message to the calling process. This
- message has the form <c><![CDATA[{async_reply, N, Result}]]></c>, where
- <c><![CDATA[Result]]></c> is the result from the read, either <c><![CDATA[{ok, Data}]]></c>,
- or <c><![CDATA[eof]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
- <p>The <c><![CDATA[apread]]></c> function reads from a specified position,
- combining the <c><![CDATA[position]]></c> and <c><![CDATA[aread]]></c> functions.</p>
+ <p>The <c><![CDATA[pread]]></c> function writes to a specified position,
+ combining the <c><![CDATA[position]]></c> and <c><![CDATA[write]]></c> functions.</p>
+ <p><seealso marker="#write-3">ssh_sftp:write/3</seealso></p>
</desc>
</func>
- <func>
- <name>write(ChannelPid, Handle, Data) -></name>
- <name>write(ChannelPid, Handle, Data, Timeout) -> ok | {error, Error}</name>
- <name>pwrite(ChannelPid, Handle, Position, Data) -> ok </name>
- <name>pwrite(ChannelPid, Handle, Position, Data, Timeout) -> ok | {error, Error}</name>
- <fsummary>Write to an open file</fsummary>
+
+
+ <func>
+ <name>read(ChannelPid, Handle, Len) -></name>
+ <name>read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, Error}</name>
+ <fsummary>Reads from an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
<v>Position = integer()</v>
- <v>Data = iolist()</v>
+ <v>Len = integer()</v>
<v>Timeout = timeout()</v>
+ <v>Data = string() | binary()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes<c><![CDATA[data]]></c> to the file referenced by <c><![CDATA[Handle]]></c>.
- The file should be opened with <c><![CDATA[write]]></c> or <c><![CDATA[append]]></c>
- flag. Returns <c><![CDATA[ok]]></c> if successful or S<c><![CDATA[{error, Reason}]]></c>
- otherwise.</p>
- <p>Typical error reasons are:</p>
- <taglist>
- <tag><c><![CDATA[ebadf]]></c></tag>
- <item>
- <p>The file is not opened for writing.</p>
- </item>
- <tag><c><![CDATA[enospc]]></c></tag>
- <item>
- <p>There is a no space left on the device.</p>
- </item>
- </taglist>
+ <p>Reads <c><![CDATA[Len]]></c> bytes from the file referenced by
+ <c><![CDATA[Handle]]></c>. Returns <c><![CDATA[{ok, Data}]]></c>, <c><![CDATA[eof]]></c>, or
+ <c><![CDATA[{error, Reason}]]></c>. If the file is opened with <c><![CDATA[binary]]></c>,
+ <c><![CDATA[Data]]></c> is a binary, otherwise it is a string.</p>
+ <p>If the file is read past <c>eof</c>, only the remaining bytes
+ are read and returned. If no bytes are read, <c><![CDATA[eof]]></c>
+ is returned.</p>
</desc>
</func>
- <func>
- <name>awrite(ChannelPid, Handle, Data) -> ok | {error, Reason} </name>
- <name>apwrite(ChannelPid, Handle, Position, Data) -> ok | {error, Reason}</name>
- <fsummary>Write asynchronously to an open file</fsummary>
+
+ <func>
+ <name>read_file(ChannelPid, File) -></name>
+ <name>read_file(ChannelPid, File, Timeout) -> {ok, Data} | {error, Reason}</name>
+ <fsummary>Reads a file.</fsummary>
<type>
- <v>ChannelPid = pid()</v>
- <v>Handle = term()</v>
- <v>Position = integer()</v>
- <v>Len = integer()</v>
+ <v>ChannelPid = pid()</v>
+ <v>File = string()</v>
<v>Data = binary()</v>
<v>Timeout = timeout()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Writes to an open file, without waiting for the result. If the
- handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where N
- is a term guaranteed to be unique between calls of
- <c><![CDATA[awrite]]></c>. The result of the <c><![CDATA[write]]></c> operation is sent
- as a message to the calling process. This message has the form
- <c><![CDATA[{async_reply, N, Result}]]></c>, where <c><![CDATA[Result]]></c> is the result
- from the write, either <c><![CDATA[ok]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
- <p>The <c><![CDATA[apwrite]]></c> writes on a specified position, combining
- the <c><![CDATA[position]]></c> and <c><![CDATA[awrite]]></c> operations.</p>
+ <p>Reads a file from the server, and returns the data in a binary,
+ like
+ <seealso marker="kernel:file#read_file-1">file:read_file/1</seealso></p>
</desc>
</func>
- <func>
- <name>position(ChannelPid, Handle, Location) -> </name>
- <name>position(ChannelPid, Handle, Location, Timeout) -> {ok, NewPosition | {error, Error}</name>
- <fsummary>Seek position in open file</fsummary>
+
+ <func>
+ <name>read_file_info(ChannelPid, Name) -></name>
+ <name>read_file_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, Reason}</name>
+ <fsummary>Gets information about a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
<v>Handle = term()</v>
- <v>Location = Offset | {bof, Offset} | {cur, Offset} | {eof, Offset} | bof | cur | eof</v>
- <v>Offset = integer()</v>
<v>Timeout = timeout()</v>
- <v>NewPosition = integer()</v>
+ <v>FileInfo = record()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Sets the file position of the file referenced by <c><![CDATA[Handle]]></c>.
- Returns <c><![CDATA[{ok, NewPosition}]]></c> (as an absolute offset) if
- successful, otherwise <c><![CDATA[{error, Reason}]]></c>. <c><![CDATA[Location]]></c> is
- one of the following:</p>
- <taglist>
- <tag><c><![CDATA[Offset]]></c></tag>
- <item>
- <p>The same as <c><![CDATA[{bof, Offset}]]></c>.</p>
- </item>
- <tag><c><![CDATA[{bof, Offset}]]></c></tag>
- <item>
- <p>Absolute offset.</p>
- </item>
- <tag><c><![CDATA[{cur, Offset}]]></c></tag>
- <item>
- <p>Offset from the current position.</p>
- </item>
- <tag><c><![CDATA[{eof, Offset}]]></c></tag>
- <item>
- <p>Offset from the end of file.</p>
- </item>
- <tag><c><![CDATA[bof | cur | eof]]></c></tag>
- <item>
- <p>The same as above with <c><![CDATA[Offset]]></c> 0.</p>
- </item>
- </taglist>
+ <p>Returns a <c><![CDATA[file_info]]></c> record from the file specified by
+ <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>,
+ like <seealso marker="kernel:file#read_file_info-2">file:read_file_info/2</seealso></p>
</desc>
</func>
- <func>
- <name>read_file_info(ChannelPid, Name) -> </name>
- <name>read_file_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, Reason}</name>
- <fsummary>Get information about a file</fsummary>
+
+ <func>
+ <name>read_link(ChannelPid, Name) -></name>
+ <name>read_link(ChannelPid, Name, Timeout) -> {ok, Target} | {error, Reason}</name>
+ <fsummary>Reads symbolic link.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
- <v>Handle = term()</v>
- <v>Timeout = timeout()</v>
- <v>FileInfo = record()</v>
+ <v>Target = string()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Returns a <c><![CDATA[file_info]]></c> record from the file specified by
- <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>, like <c><![CDATA[file:read_file_info/2]]></c>.</p>
+ <p>Reads the link target from the symbolic link specified
+ by <c><![CDATA[name]]></c>, like
+ <seealso marker="kernel:file#read_link-1">file:read_link/1</seealso></p>
</desc>
</func>
- <func>
+
+ <func>
<name>read_link_info(ChannelPid, Name) -> {ok, FileInfo} | {error, Reason}</name>
<name>read_link_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, Reason}</name>
- <fsummary>Get information about a symbolic link</fsummary>
+ <fsummary>Gets information about a symbolic link.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
@@ -502,120 +510,154 @@
<desc>
<p>Returns a <c><![CDATA[file_info]]></c> record from the symbolic
link specified by <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>, like
- <c><![CDATA[file:read_link_info/2]]></c>.</p>
+ <seealso marker="kernel:file#read_link_info-2">file:read_link_info/2</seealso></p>
</desc>
</func>
+
<func>
- <name>write_file_info(ChannelPid, Name, Info) -> </name>
- <name>write_file_info(ChannelPid, Name, Info, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Write information for a file</fsummary>
+ <name>rename(ChannelPid, OldName, NewName) -> </name>
+ <name>rename(ChannelPid, OldName, NewName, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Renames a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>Name = string()</v>
- <v>Info = record()</v>
+ <v>OldName = string()</v>
+ <v>NewName = string()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes file information from a <c><![CDATA[file_info]]></c> record to the
- file specified by <c><![CDATA[Name]]></c>, like <c><![CDATA[file:write_file_info]]></c>.</p>
- </desc>
- </func>
- <func>
- <name>read_link(ChannelPid, Name) -> </name>
- <name>read_link(ChannelPid, Name, Timeout) -> {ok, Target} | {error, Reason}</name>
- <fsummary>Read symbolic link</fsummary>
- <type>
- <v>ChannelPid = pid()</v>
- <v>Name = string()</v>
- <v>Target = string()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Reads the link target from the symbolic link specified
- by <c><![CDATA[name]]></c>, like <c><![CDATA[file:read_link/1]]></c>.</p>
+ <p>Renames a file named <c><![CDATA[OldName]]></c> and gives it the name
+ <c><![CDATA[NewName]]></c>, like
+ <seealso marker="kernel:file#rename-2">file:rename/2</seealso></p>
</desc>
</func>
+
<func>
- <name>make_symlink(ChannelPid, Name, Target) -> </name>
- <name>make_symlink(ChannelPid, Name, Target, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Create symbolic link</fsummary>
+ <name>start_channel(ConnectionRef) -></name>
+ <name>start_channel(ConnectionRef, Options) -></name>
+ <name>start_channel(Host, Options) -></name>
+ <name>start_channel(Host, Port, Options) -> {ok, Pid} | {ok, Pid, ConnectionRef} |
+ {error, Reason}</name>
+ <fsummary>Starts an SFTP client.</fsummary>
<type>
- <v>ChannelPid = pid()</v>
- <v>Name = string()</v>
- <v>Target = string()</v>
+ <v>Host = string()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>Port = integer()</v>
+ <v>Options = [{Option, Value}]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Creates a symbolic link pointing to <c><![CDATA[Target]]></c> with the
- name <c><![CDATA[Name]]></c>, like <c><![CDATA[file:make_symlink/2]]></c>.</p>
+ <p>If no connection reference is provided, a connection is set
+ up, and the new connection is returned. An SSH channel process
+ is started to handle the communication with the SFTP server.
+ The returned <c>pid</c> for this process is to be used as input to
+ all other API functions in this module.</p>
+
+ <p>Options:</p>
+ <taglist>
+ <tag><c><![CDATA[{timeout, timeout()}]]></c></tag>
+ <item>
+ <p>The time-out is passed to the <c>ssh_channel</c> start function,
+ and defaults to <c>infinity</c>.</p>
+ </item>
+ <tag>
+ <c><![CDATA[{sftp_vsn, integer()}]]></c>
+ </tag>
+ <item>
+ <p>
+ Desired SFTP protocol version.
+ The actual version is the minimum of
+ the desired version and the maximum supported
+ versions by the SFTP server.
+ </p>
+ </item>
+ </taglist>
+ <p>All other options are directly passed to
+ <seealso marker="ssh">ssh:connect/3</seealso> or ignored if a
+ connection is already provided.</p>
</desc>
</func>
- <func>
- <name>rename(ChannelPid, OldName, NewName) -> </name>
- <name>rename(ChannelPid, OldName, NewName, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Rename a file</fsummary>
+
+ <func>
+ <name>stop_channel(ChannelPid) -> ok</name>
+ <fsummary>Stops the SFTP client channel.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>OldName = string()</v>
- <v>NewName = string()</v>
- <v>Timeout = timeout()</v>
- <v>Reason = term()</v>
</type>
<desc>
- <p>Renames a file named <c><![CDATA[OldName]]></c>, and gives it the name
- <c><![CDATA[NewName]]></c>, like <c><![CDATA[file:rename/2]]></c></p>
+ <p>Stops an SFTP channel. Does not close the SSH connection.
+ Use <seealso marker="ssh#close-1">ssh:close/1</seealso> to close it.</p>
</desc>
</func>
+
<func>
- <name>delete(ChannelPid, Name) -> </name>
- <name>delete(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Delete a file</fsummary>
+ <name>write(ChannelPid, Handle, Data) -></name>
+ <name>write(ChannelPid, Handle, Data, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Writes to an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>Name = string()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Data = iolist()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Deletes the file specified by <c><![CDATA[Name]]></c>, like
- <c><![CDATA[file:delete/1]]></c></p>
+ <p>Writes <c><![CDATA[data]]></c> to the file referenced by <c><![CDATA[Handle]]></c>.
+ The file is to be opened with <c><![CDATA[write]]></c> or <c><![CDATA[append]]></c>
+ flag. Returns <c><![CDATA[ok]]></c> if successful or <c><![CDATA[{error, Reason}]]></c>
+ otherwise.</p>
+ <p>Typical error reasons:</p>
+ <taglist>
+ <tag><c><![CDATA[ebadf]]></c></tag>
+ <item>
+ <p>File is not opened for writing.</p>
+ </item>
+ <tag><c><![CDATA[enospc]]></c></tag>
+ <item>
+ <p>No space is left on the device.</p>
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
- <name>make_dir(ChannelPid, Name) -> </name>
- <name>make_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Create a directory</fsummary>
+ <name>write_file(ChannelPid, File, Iolist) -></name>
+ <name>write_file(ChannelPid, File, Iolist, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Writes a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>Name = string()</v>
+ <v>File = string()</v>
+ <v>Iolist = iolist()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Creates a directory specified by <c><![CDATA[Name]]></c>. <c><![CDATA[Name]]></c> should
- be a full path to a new directory. The directory can only be
- created in an existing directory.</p>
+ <p>Writes a file to the server, like <seealso
+ marker="kernel:file#write_file-2">file:write_file/2</seealso> The
+ file is created if it does not exist. The file is overwritten
+ if it exists.</p>
</desc>
</func>
+
<func>
- <name>del_dir(ChannelPid, Name) -> </name>
- <name>del_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Delete an empty directory</fsummary>
+ <name>write_file_info(ChannelPid, Name, Info) -></name>
+ <name>write_file_info(ChannelPid, Name, Info, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Writes information for a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
+ <v>Info = record()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Deletes a directory specified by <c><![CDATA[Name]]></c>.
- Note that the directory must be empty before it can be successfully deleted
- </p>
+ <p>Writes file information from a <c><![CDATA[file_info]]></c> record to the
+ file specified by <c><![CDATA[Name]]></c>, like
+ <seealso marker="kernel:file#write_file_info-2">file:write_file_info/[2,3]</seealso></p>
</desc>
</func>
-
</funcs>
-
+
</erlref>
diff --git a/lib/ssh/doc/src/ssh_sftpd.xml b/lib/ssh/doc/src/ssh_sftpd.xml
index 81c2acc575..cf50fb1b23 100644
--- a/lib/ssh/doc/src/ssh_sftpd.xml
+++ b/lib/ssh/doc/src/ssh_sftpd.xml
@@ -8,81 +8,88 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssh_sftpd</title>
+ <prepared></prepared>
+ <docno></docno>
<date>2005-09-22</date>
+ <rev></rev>
<file>ssh_sftpd.sgml</file>
</header>
<module>ssh_sftpd</module>
- <modulesummary>Specifies the channel process to handle an sftp subsystem.</modulesummary>
+ <modulesummary>Specifies the channel process to handle an SFTP subsystem.</modulesummary>
<description>
- <p>Specifies a channel process to handle a sftp subsystem.</p>
+ <p>Specifies a channel process to handle an SFTP subsystem.</p>
</description>
<section>
- <title>DATA TYPES </title>
- <p><c>subsystem_spec() = {subsystem_name(), {channel_callback(), channel_init_args()}} </c></p>
- <p><c>subsystem_name() = "sftp"</c></p>
- <p><c>channel_callback() = atom()</c> - Name of the erlang module implementing the
- subsystem using the ssh_channel behavior see
- <seealso marker="ssh_channel">ssh_channel(3)</seealso></p>
- <p><c> channel_init_args() = list() - The one given as argument to function
- subsystem_spec/1.</c></p>
+ <title>DATA TYPES</title>
+ <taglist>
+ <tag><c>subsystem_spec() =</c></tag>
+ <item><p><c>{subsystem_name(), {channel_callback(), channel_init_args()}}</c></p></item>
+ <tag><c>subsystem_name() =</c></tag>
+ <item><p><c>"sftp"</c></p></item>
+ <tag><c>channel_callback() =</c></tag>
+ <item><p><c>atom()</c> - Name of the Erlang module implementing the subsystem using the
+ <c>ssh_channel</c> behavior, see the
+ <seealso marker="ssh_channel">ssh_channel(3)</seealso> manual page.</p></item>
+ <tag><c>channel_init_args() =</c></tag>
+ <item><p><c>list()</c> - The one given as argument to function <c>subsystem_spec/1</c>.</p></item>
+ </taglist>
</section>
<funcs>
<func>
<name>subsystem_spec(Options) -> subsystem_spec()</name>
- <fsummary>Returns the subsystem specification that allows an ssh daemon to handle the subsystem "sftp".</fsummary>
+ <fsummary>Returns the subsystem specification that allows an SSH daemon to handle the subsystem "sftp".</fsummary>
<type>
<v>Options = [{Option, Value}]</v>
</type>
<desc>
- <p>Should be used together with ssh:daemon/[1,2,3]</p>
- <p>Options are:</p>
+ <p>Is to be used together with <c>ssh:daemon/[1,2,3]</c></p>
+ <p>Options:</p>
<taglist>
<tag><c><![CDATA[{cwd, String}]]></c></tag>
<item>
- <p>Sets the initial current working directory for the
- server.</p>
+ <p>Sets the initial current working directory for the server.</p>
</item>
<tag><c><![CDATA[{file_handler, CallbackModule}]]></c></tag>
<item>
<p>Determines which module to call for accessing
- the file server. The default value is <c>ssh_sftpd_file</c> that uses the
- <seealso marker="kernel:file">file</seealso> and <seealso marker="stdlib:filelib">filelib</seealso> API:s to access the standard OTP file
- server. This option may be used to plug in
+ the file server. The default value is <c>ssh_sftpd_file</c>, which uses the
+ <seealso marker="kernel:file">file</seealso> and <seealso marker="stdlib:filelib">filelib</seealso>
+ APIs to access the standard OTP file server. This option can be used to plug in
other file servers.</p>
</item>
<tag><c><![CDATA[{max_files, Integer}]]></c></tag>
<item>
<p>The default value is <c>0</c>, which means that there is no upper limit.
- If supplied, the number of filenames returned to the sftp client per <c>READDIR</c>
+ If supplied, the number of filenames returned to the SFTP client per <c>READDIR</c>
request is limited to at most the given value.</p>
</item>
<tag><c><![CDATA[{root, String}]]></c></tag>
<item>
- <p>Sets the sftp root directory. The user will then not be
- able to see any files above this root. If for instance
- the root is set to <c>/tmp</c> the user will see this
- directory as <c>/</c> and if the user does cd <c>/etc</c>
- the user will end up in <c>/tmp/etc</c>.
+ <p>Sets the SFTP root directory. Then the user cannot see any files
+ above this root. If, for example, the root directory is set to <c>/tmp</c>,
+ then the user sees this directory as <c>/</c>. If the user then writes
+ <c>cd /etc</c>, the user moves to <c>/tmp/etc</c>.
</p>
</item>
<tag><c><![CDATA[{sftpd_vsn, integer()}]]></c></tag>
<item>
- <p>Sets the sftp version to use, defaults to 5. Version 6 is under
+ <p>Sets the SFTP version to use. Defaults to 5. Version 6 is under
development and limited.</p>
</item>
</taglist>
diff --git a/lib/ssh/doc/src/usersguide.xml b/lib/ssh/doc/src/usersguide.xml
index 8ab14c2945..7c925a3762 100644
--- a/lib/ssh/doc/src/usersguide.xml
+++ b/lib/ssh/doc/src/usersguide.xml
@@ -8,30 +8,32 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>SSH User's Guide</title>
<prepared>OTP Team</prepared>
+ <docno></docno>
<date>2012-10-11</date>
+ <rev></rev>
<file>usersguide.xml</file>
</header>
<description>
- <p>The <em>SSH</em> application implements the SSH (Secure Shell) protocol and
- provides an SFTP (Secret File Transfer Protocol) client and server.
+ <p>The Erlang Secure Shell (SSH) application, <c>ssh</c>, implements the SSH Transport Layer Protocol and
+ provides SSH File Transfer Protocol (SFTP) clients and servers.
</p>
</description>
<xi:include href="introduction.xml"/>
- <xi:include href="ssh_protocol.xml"/>
<xi:include href="using_ssh.xml"/>
</part>
diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml
index 46178d4018..6826f20fb3 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -9,77 +9,84 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Getting started</title>
+ <title>Getting Started</title>
+ <prepared></prepared>
+ <docno></docno>
+ <approved></approved>
+ <date></date>
+ <rev></rev>
<file>using_ssh.xml</file>
</header>
<section>
- <title> General information</title>
- <p>The examples in the following sections use the utility function
- <seealso marker="ssh#start-0"> ssh:start/0 </seealso> that starts
- all needed applications (crypto, public_key and ssh). All examples
- are run in an Erlang shell, or in a bash shell using openssh to
- illustrate how the erlang ssh application can be used. The
- examples are run as the user otptest on a local network where the
- user is authorized to login in over ssh to the host "tarlop". If
- nothing else is stated it is persumed that the otptest user has an
- entry in tarlop's authorized_keys file (may log in via ssh without
- entering a password). Also tarlop is a known host in the user
- otptest's known_hosts file so that host verification can be done
- without user interaction.
+ <title>General Information</title>
+ <p>The following examples use the utility function
+ <seealso marker="ssh#start-0"> ssh:start/0</seealso> to start
+ all needed applications (<c>crypto</c>, <c>public_key</c>, and <c>ssh</c>).
+ All examples are run in an Erlang shell, or in a bash shell, using <em>openssh</em>
+ to illustrate how the <c>ssh</c> application can be used. The
+ examples are run as the user <c>otptest</c> on a local network where the
+ user is authorized to log in over <c>ssh</c> to the host <em>tarlop</em>.
+ </p>
+ <p>If nothing else is stated, it is presumed that the <c>otptest</c> user
+ has an entry in the <em>authorized_keys</em> file of <em>tarlop</em>
+ (allowed to log in over <c>ssh</c> without entering a password).
+ Also, <em>tarlop</em> is a known host in the <c>known_hosts</c>
+ file of the user <c>otptest</c>. This means that host-verification
+ can be done without user-interaction.
</p>
</section>
<section>
- <title>Using the Erlang SSH Terminal Client</title>
+ <title>Using the Erlang ssh Terminal Client</title>
- <p>The user otptest, that has bash as default shell, uses the
- ssh:shell/1 client to connect to the openssh daemon running on a
- host called tarlop. Note that currently this client is very simple
- and you should not be expected to be as fancy as the openssh
- client.</p>
+ <p>The user <c>otptest</c>, which has bash as default shell, uses the
+ <c>ssh:shell/1</c> client to connect to the <em>openssh</em> daemon running on a
+ host called <em>tarlop</em>:</p>
<code type="erl" >
1> ssh:start().
ok
2> {ok, S} = ssh:shell("tarlop").
- >pwd
+ otptest@tarlop:> pwd
/home/otptest
- >exit
+ otptest@tarlop:> exit
logout
3>
</code>
</section>
<section>
- <title>Running an Erlang SSH Daemon </title>
+ <marker id="Running an Erlang ssh Daemon"></marker>
+ <title>Running an Erlang ssh Daemon</title>
- <p> The option system_dir must be a directory containing a host
- key file and it defaults to /etc/ssh. For details see section
+ <p>The <c>system_dir</c> option must be a directory containing a host
+ key file and it defaults to <c>/etc/ssh</c>. For details, see Section
Configuration Files in <seealso
marker="SSH_app">ssh(6)</seealso>.
</p>
- <note><p>Normally the /etc/ssh directory is only readable by root. </p>
+ <note><p>Normally, the <c>/etc/ssh</c> directory is only readable by root.</p>
</note>
- <p> The option user_dir defaults to the users ~/.ssh directory</p>
+ <p>The option <c>user_dir</c> defaults to directory <c>users ~/.ssh</c>.</p>
- <p>In the following example we generate new keys and host keys as
- to be able to run the example without having root privileges</p>
+ <p><em>Step 1.</em> To run the example without root privileges,
+ generate new keys and host keys:</p>
<code>
$bash> ssh-keygen -t rsa -f /tmp/ssh_daemon/ssh_host_rsa_key
@@ -88,19 +95,22 @@
[...]
</code>
- <p>Create the file /tmp/otptest_user/.ssh/authorized_keys and add the content
- of /tmp/otptest_user/.ssh/id_rsa.pub Now we can do</p>
+ <p><em>Step 2.</em> Create the file <c>/tmp/otptest_user/.ssh/authorized_keys</c>
+ and add the content of <c>/tmp/otptest_user/.ssh/id_rsa.pub</c>.</p>
+
+ <p><em>Step 3.</em> Start the Erlang <c>ssh</c> daemon:</p>
<code type="erl">
1> ssh:start().
ok
- 2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
- {user_dir, "/tmp/otptest_user/.ssh"}]).
+ 2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
+ {user_dir, "/tmp/otptest_user/.ssh"}]).
{ok,&lt;0.54.0>}
3>
</code>
- <p>Use the openssh client from a shell to connect to the Erlang ssh daemon.</p>
+ <p><em>Step 4.</em> Use the <em>openssh</em> client from a shell to connect
+ to the Erlang <c>ssh</c> daemon:</p>
<code>
$bash> ssh tarlop -p 8989 -i /tmp/otptest_user/.ssh/id_rsa\
@@ -113,9 +123,12 @@
1>
</code>
- <p>There are two ways of shutting down an SSH daemon</p>
+ <p>There are two ways of shutting down an <c>ssh</c> daemon,
+ see <em>Step 5a</em> and <em>Step 5b</em>.</p>
- <p>1: Stops the listener, but leaves existing connections started by the listener up and running.</p>
+ <p><em>Step 5a.</em> Shut down the Erlang <c>ssh</c> daemon so that it
+ stops the listener but leaves existing connections, started by the listener,
+ operational:</p>
<code type="erl">
3> ssh:stop_listener(Sshd).
@@ -123,7 +136,8 @@
4>
</code>
- <p>2: Stops the listener and all connections started by the listener.</p>
+ <p><em>Step 5b.</em> Shut down the Erlang <c>ssh</c> daemon so that it
+ stops the listener and all connections started by the listener:</p>
<code type="erl">
3> ssh:stop_daemon(Sshd)
@@ -134,17 +148,18 @@
</section>
<section>
- <title>One Time Execution</title>
+ <title>One-Time Execution</title>
- <p>In the following example the Erlang shell is the client process
- that receives the channel replies. </p>
+ <p>In the following example, the Erlang shell is the client process
+ that receives the channel replies.</p>
- <note><p> If you run this example
- in your environment you may get fewer or more messages back as
- this depends on the OS and shell on the machine running the ssh
- daemon. See also <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>
+ <note><p>The number of received messages in this example depends on which OS
+ and which shell that is used on the machine running the <c>ssh</c> daemon.
+ See also <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>.
</p></note>
+ <p>Do a one-time execution of a remote command over <c>ssh</c>:</p>
+
<code type="erl" >
1> ssh:start().
ok
@@ -162,7 +177,8 @@
6>
</code>
- <p>Note only the channel is closed the connection is still up and can handle other channels</p>
+ <p>Notice that only the channel is closed. The connection is still up and can
+ handle other channels:</p>
<code type="erl" >
6> {ok, NewChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
@@ -172,19 +188,22 @@
</section>
<section>
- <title>SFTP (SSH File Transport Protocol) server</title>
+ <title>SFTP Server</title>
+
+ <p>Start the Erlang <c>ssh</c> daemon with the SFTP subsystem:</p>
<code type="erl" >
1> ssh:start().
ok
- 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
- {user_dir, "/tmp/otptest_user/.ssh"},
- {subsystems, [ssh_sftpd:subsystem_spec([{cwd, "/tmp/sftp/example"}])]}]).
+ 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
+ {user_dir, "/tmp/otptest_user/.ssh"},
+ {subsystems, [ssh_sftpd:subsystem_spec([{cwd, "/tmp/sftp/example"}])
+ ]}]).
{ok,&lt;0.54.0>}
3>
</code>
- <p> Run the openssh sftp client</p>
+ <p>Run the OpenSSH SFTP client:</p>
<code type="erl">
$bash> sftp -oPort=8989 -o IdentityFile=/tmp/otptest_user/.ssh/id_rsa\
@@ -197,7 +216,9 @@
</section>
<section>
- <title>SFTP (SSH File Transport Protocol) client</title>
+ <title>SFTP Client</title>
+
+ <p>Fetch a file with the Erlang SFTP client:</p>
<code type="erl" >
1> ssh:start().
@@ -210,10 +231,77 @@
</section>
<section>
- <title>Creating a subsystem</title>
+ <title>SFTP Client with TAR Compression and Encryption</title>
+
+ <p>Example of writing and then reading a tar file follows:</p>
+ <code type="erl">
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ...
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:close(HandleWrite),
+
+ %% And for reading
+ {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]),
+ {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
+ ok = erl_tar:close(HandleRead),
+ </code>
+
+ <p>The previous write and read example can be extended with encryption and decryption as follows:</p>
+ <code type="erl">
+%% First three parameters depending on which crypto type we select:
+Key = &lt;&lt;"This is a 256 bit key. abcdefghi">>,
+Ivec0 = crypto:strong_rand_bytes(16),
+DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc
+
+%% Initialization of the CryptoState, in this case it is the Ivector.
+InitFun = fun() -> {ok, Ivec0, DataSize} end,
+
+%% How to encrypt:
+EncryptFun =
+ fun(PlainBin,Ivec) ->
+ EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
+ {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
+ end,
+
+%% What to do with the very last block:
+CloseFun =
+ fun(PlainBin, Ivec) ->
+ EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
+ pad(16,PlainBin) %% Last chunk
+ ),
+ {ok, EncryptedBin}
+ end,
+
+Cw = {InitFun,EncryptFun,CloseFun},
+{ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
+ok = erl_tar:add(HandleWrite, .... ),
+ok = erl_tar:add(HandleWrite, .... ),
+...
+ok = erl_tar:add(HandleWrite, .... ),
+ok = erl_tar:close(HandleWrite),
+
+%% And for decryption (in this crypto example we could use the same InitFun
+%% as for encryption):
+DecryptFun =
+ fun(EncryptedBin,Ivec) ->
+ PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
+ {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
+ end,
+
+Cr = {InitFun,DecryptFun},
+{ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]),
+{ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
+ok = erl_tar:close(HandleRead),
+ </code>
+ </section>
+
+ <section>
+ <title>Creating a Subsystem</title>
- <p>A very small SSH subsystem that echos N bytes could be implemented like this.
- See also <seealso marker="ssh_channel"> ssh_channel(3)</seealso> </p>
+ <p>A small <c>ssh</c> subsystem that echoes N bytes can be implemented as shown
+ in the following example:</p>
<code type="erl" >
-module(ssh_echo_server).
@@ -267,14 +355,16 @@ terminate(_Reason, _State) ->
ok.
</code>
- <p>And run like this on the host tarlop with the keys generated in section 3.3</p>
+ <p>The subsystem can be run on the host <em>tarlop</em> with the generated keys,
+ as described in Section <seealso marker="#Running an Erlang ssh Daemon">
+ Running an Erlang ssh Daemon</seealso>:</p>
<code type="erl" >
1> ssh:start().
ok
- 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
- {user_dir, "/tmp/otptest_user/.ssh"}
- {subsystems, [{"echo_n", {ssh_echo_server, [10]}}]}]).
+ 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
+ {user_dir, "/tmp/otptest_user/.ssh"}
+ {subsystems, [{"echo_n", {ssh_echo_server, [10]}}]}]).
{ok,&lt;0.54.0>}
3>
</code>
@@ -293,6 +383,7 @@ terminate(_Reason, _State) ->
{ssh_msg, &lt;0.57.0>, {closed, 0}}
7> {error, closed} = ssh_connection:send(ConnectionRef, ChannelId, "10", infinity).
</code>
+<p>See also <seealso marker="ssh_channel"> ssh_channel(3)</seealso>.</p>
</section>
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps
deleted file mode 100644
index d766a933b4..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps
+++ /dev/null
@@ -1,3315 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:31:26 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Protocol Architecture) s
-5 613 M
-( draft-ietf-secsh-architecture-15.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network. This document describes the) s
-5 261 M
-( architecture of the SSH protocol, as well as the notation and) s
-5 250 M
-( terminology used in SSH protocol documents. It also discusses the SSH) s
-5 239 M
-( algorithm naming system that allows local extensions. The SSH) s
-5 228 M
-( protocol consists of three major components: The Transport Layer) s
-5 217 M
-( Protocol provides server authentication, confidentiality, and) s
-5 206 M
-( integrity with perfect forward secrecy. The User Authentication) s
-5 195 M
-( Protocol authenticates the client to the server. The Connection) s
-5 184 M
-( Protocol multiplexes the encrypted tunnel into several logical) s
-5 173 M
-( channels. Details of these protocols are described in separate) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( documents.) s
-5 668 M
-(Table of Contents) s
-5 646 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 635 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 624 M
-( 3. Specification of Requirements . . . . . . . . . . . . . . . 3) s
-5 613 M
-( 4. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 602 M
-( 4.1 Host Keys . . . . . . . . . . . . . . . . . . . . . . . . . 4) s
-5 591 M
-( 4.2 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 580 M
-( 4.3 Policy Issues . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 569 M
-( 4.4 Security Properties . . . . . . . . . . . . . . . . . . . . 6) s
-5 558 M
-( 4.5 Packet Size and Overhead . . . . . . . . . . . . . . . . . . 6) s
-5 547 M
-( 4.6 Localization and Character Set Support . . . . . . . . . . . 7) s
-5 536 M
-( 5. Data Type Representations Used in the SSH Protocols . . . . 8) s
-5 525 M
-( 6. Algorithm Naming . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 514 M
-( 7. Message Numbers . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 503 M
-( 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . 11) s
-5 492 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . . 12) s
-5 481 M
-( 9.1 Pseudo-Random Number Generation . . . . . . . . . . . . . . 12) s
-5 470 M
-( 9.2 Transport . . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 459 M
-( 9.2.1 Confidentiality . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 448 M
-( 9.2.2 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 16) s
-5 437 M
-( 9.2.3 Replay . . . . . . . . . . . . . . . . . . . . . . . . . . . 16) s
-5 426 M
-( 9.2.4 Man-in-the-middle . . . . . . . . . . . . . . . . . . . . . 17) s
-5 415 M
-( 9.2.5 Denial-of-service . . . . . . . . . . . . . . . . . . . . . 19) s
-5 404 M
-( 9.2.6 Covert Channels . . . . . . . . . . . . . . . . . . . . . . 19) s
-5 393 M
-( 9.2.7 Forward Secrecy . . . . . . . . . . . . . . . . . . . . . . 20) s
-5 382 M
-( 9.3 Authentication Protocol . . . . . . . . . . . . . . . . . . 20) s
-5 371 M
-( 9.3.1 Weak Transport . . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 360 M
-( 9.3.2 Debug messages . . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 349 M
-( 9.3.3 Local security policy . . . . . . . . . . . . . . . . . . . 21) s
-5 338 M
-( 9.3.4 Public key authentication . . . . . . . . . . . . . . . . . 22) s
-5 327 M
-( 9.3.5 Password authentication . . . . . . . . . . . . . . . . . . 22) s
-5 316 M
-( 9.3.6 Host based authentication . . . . . . . . . . . . . . . . . 23) s
-5 305 M
-( 9.4 Connection protocol . . . . . . . . . . . . . . . . . . . . 23) s
-5 294 M
-( 9.4.1 End point security . . . . . . . . . . . . . . . . . . . . . 23) s
-5 283 M
-( 9.4.2 Proxy forwarding . . . . . . . . . . . . . . . . . . . . . . 23) s
-5 272 M
-( 9.4.3 X11 forwarding . . . . . . . . . . . . . . . . . . . . . . . 24) s
-5 261 M
-( Normative References . . . . . . . . . . . . . . . . . . . . 24) s
-5 250 M
-( Informative References . . . . . . . . . . . . . . . . . . . 25) s
-5 239 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 27) s
-5 228 M
-( Intellectual Property and Copyright Statements . . . . . . . 28) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 536 M
-( services over an insecure network. It consists of three major) s
-5 525 M
-( components:) s
-5 514 M
-( o The Transport Layer Protocol [SSH-TRANS] provides server) s
-5 503 M
-( authentication, confidentiality, and integrity. It may optionally) s
-5 492 M
-( also provide compression. The transport layer will typically be) s
-5 481 M
-( run over a TCP/IP connection, but might also be used on top of any) s
-5 470 M
-( other reliable data stream.) s
-5 459 M
-( o The User Authentication Protocol [SSH-USERAUTH] authenticates the) s
-5 448 M
-( client-side user to the server. It runs over the transport layer) s
-5 437 M
-( protocol.) s
-5 426 M
-( o The Connection Protocol [SSH-CONNECT] multiplexes the encrypted) s
-5 415 M
-( tunnel into several logical channels. It runs over the user) s
-5 404 M
-( authentication protocol.) s
-5 382 M
-( The client sends a service request once a secure transport layer) s
-5 371 M
-( connection has been established. A second service request is sent) s
-5 360 M
-( after user authentication is complete. This allows new protocols to) s
-5 349 M
-( be defined and coexist with the protocols listed above.) s
-5 327 M
-( The connection protocol provides channels that can be used for a wide) s
-5 316 M
-( range of purposes. Standard methods are provided for setting up) s
-5 305 M
-( secure interactive shell sessions and for forwarding \("tunneling"\)) s
-5 294 M
-( arbitrary TCP/IP ports and X11 connections.) s
-5 272 M
-(3. Specification of Requirements) s
-5 250 M
-( All documents related to the SSH protocols shall use the keywords) s
-5 239 M
-( "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",) s
-5 228 M
-( "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" to describe) s
-5 217 M
-( requirements. They are to be interpreted as described in [RFC2119].) s
-5 195 M
-(4. Architecture) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(4.1 Host Keys) s
-5 668 M
-( Each server host SHOULD have a host key. Hosts MAY have multiple) s
-5 657 M
-( host keys using multiple different algorithms. Multiple hosts MAY) s
-5 646 M
-( share the same host key. If a host has keys at all, it MUST have at) s
-5 635 M
-( least one key using each REQUIRED public key algorithm \(DSS) s
-5 624 M
-( [FIPS-186]\).) s
-5 602 M
-( The server host key is used during key exchange to verify that the) s
-5 591 M
-( client is really talking to the correct server. For this to be) s
-5 580 M
-( possible, the client must have a priori knowledge of the server's) s
-5 569 M
-( public host key.) s
-5 547 M
-( Two different trust models can be used:) s
-5 536 M
-( o The client has a local database that associates each host name \(as) s
-5 525 M
-( typed by the user\) with the corresponding public host key. This) s
-5 514 M
-( method requires no centrally administered infrastructure, and no) s
-5 503 M
-( third-party coordination. The downside is that the database of) s
-5 492 M
-( name-to-key associations may become burdensome to maintain.) s
-5 481 M
-( o The host name-to-key association is certified by some trusted) s
-5 470 M
-( certification authority. The client only knows the CA root key,) s
-5 459 M
-( and can verify the validity of all host keys certified by accepted) s
-5 448 M
-( CAs.) s
-5 426 M
-( The second alternative eases the maintenance problem, since) s
-5 415 M
-( ideally only a single CA key needs to be securely stored on the) s
-5 404 M
-( client. On the other hand, each host key must be appropriately) s
-5 393 M
-( certified by a central authority before authorization is possible.) s
-5 382 M
-( Also, a lot of trust is placed on the central infrastructure.) s
-5 360 M
-( The protocol provides the option that the server name - host key) s
-5 349 M
-( association is not checked when connecting to the host for the first) s
-5 338 M
-( time. This allows communication without prior communication of host) s
-5 327 M
-( keys or certification. The connection still provides protection) s
-5 316 M
-( against passive listening; however, it becomes vulnerable to active) s
-5 305 M
-( man-in-the-middle attacks. Implementations SHOULD NOT normally allow) s
-5 294 M
-( such connections by default, as they pose a potential security) s
-5 283 M
-( problem. However, as there is no widely deployed key infrastructure) s
-5 272 M
-( available on the Internet yet, this option makes the protocol much) s
-5 261 M
-( more usable during the transition time until such an infrastructure) s
-5 250 M
-( emerges, while still providing a much higher level of security than) s
-5 239 M
-( that offered by older solutions \(e.g. telnet [RFC-854] and rlogin) s
-5 228 M
-( [RFC-1282]\).) s
-5 206 M
-( Implementations SHOULD try to make the best effort to check host) s
-5 195 M
-( keys. An example of a possible strategy is to only accept a host key) s
-5 184 M
-( without checking the first time a host is connected, save the key in) s
-5 173 M
-( a local database, and compare against that key on all future) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( connections to that host.) s
-5 668 M
-( Implementations MAY provide additional methods for verifying the) s
-5 657 M
-( correctness of host keys, e.g. a hexadecimal fingerprint derived from) s
-5 646 M
-( the SHA-1 hash of the public key. Such fingerprints can easily be) s
-5 635 M
-( verified by using telephone or other external communication channels.) s
-5 613 M
-( All implementations SHOULD provide an option to not accept host keys) s
-5 602 M
-( that cannot be verified.) s
-5 580 M
-( We believe that ease of use is critical to end-user acceptance of) s
-5 569 M
-( security solutions, and no improvement in security is gained if the) s
-5 558 M
-( new solutions are not used. Thus, providing the option not to check) s
-5 547 M
-( the server host key is believed to improve the overall security of) s
-5 536 M
-( the Internet, even though it reduces the security of the protocol in) s
-5 525 M
-( configurations where it is allowed.) s
-5 503 M
-(4.2 Extensibility) s
-5 481 M
-( We believe that the protocol will evolve over time, and some) s
-5 470 M
-( organizations will want to use their own encryption, authentication) s
-5 459 M
-( and/or key exchange methods. Central registration of all extensions) s
-5 448 M
-( is cumbersome, especially for experimental or classified features.) s
-5 437 M
-( On the other hand, having no central registration leads to conflicts) s
-5 426 M
-( in method identifiers, making interoperability difficult.) s
-5 404 M
-( We have chosen to identify algorithms, methods, formats, and) s
-5 393 M
-( extension protocols with textual names that are of a specific format.) s
-5 382 M
-( DNS names are used to create local namespaces where experimental or) s
-5 371 M
-( classified extensions can be defined without fear of conflicts with) s
-5 360 M
-( other implementations.) s
-5 338 M
-( One design goal has been to keep the base protocol as simple as) s
-5 327 M
-( possible, and to require as few algorithms as possible. However, all) s
-5 316 M
-( implementations MUST support a minimal set of algorithms to ensure) s
-5 305 M
-( interoperability \(this does not imply that the local policy on all) s
-5 294 M
-( hosts would necessary allow these algorithms\). The mandatory) s
-5 283 M
-( algorithms are specified in the relevant protocol documents.) s
-5 261 M
-( Additional algorithms, methods, formats, and extension protocols can) s
-5 250 M
-( be defined in separate drafts. See Section Algorithm Naming \(Section) s
-5 239 M
-( 6\) for more information.) s
-5 217 M
-(4.3 Policy Issues) s
-5 195 M
-( The protocol allows full negotiation of encryption, integrity, key) s
-5 184 M
-( exchange, compression, and public key algorithms and formats.) s
-5 173 M
-( Encryption, integrity, public key, and compression algorithms can be) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( different for each direction.) s
-5 668 M
-( The following policy issues SHOULD be addressed in the configuration) s
-5 657 M
-( mechanisms of each implementation:) s
-5 646 M
-( o Encryption, integrity, and compression algorithms, separately for) s
-5 635 M
-( each direction. The policy MUST specify which is the preferred) s
-5 624 M
-( algorithm \(e.g. the first algorithm listed in each category\).) s
-5 613 M
-( o Public key algorithms and key exchange method to be used for host) s
-5 602 M
-( authentication. The existence of trusted host keys for different) s
-5 591 M
-( public key algorithms also affects this choice.) s
-5 580 M
-( o The authentication methods that are to be required by the server) s
-5 569 M
-( for each user. The server's policy MAY require multiple) s
-5 558 M
-( authentication for some or all users. The required algorithms MAY) s
-5 547 M
-( depend on the location where the user is trying to log in from.) s
-5 536 M
-( o The operations that the user is allowed to perform using the) s
-5 525 M
-( connection protocol. Some issues are related to security; for) s
-5 514 M
-( example, the policy SHOULD NOT allow the server to start sessions) s
-5 503 M
-( or run commands on the client machine, and MUST NOT allow) s
-5 492 M
-( connections to the authentication agent unless forwarding such) s
-5 481 M
-( connections has been requested. Other issues, such as which TCP/) s
-5 470 M
-( IP ports can be forwarded and by whom, are clearly issues of local) s
-5 459 M
-( policy. Many of these issues may involve traversing or bypassing) s
-5 448 M
-( firewalls, and are interrelated with the local security policy.) s
-5 426 M
-(4.4 Security Properties) s
-5 404 M
-( The primary goal of the SSH protocol is improved security on the) s
-5 393 M
-( Internet. It attempts to do this in a way that is easy to deploy,) s
-5 382 M
-( even at the cost of absolute security.) s
-5 371 M
-( o All encryption, integrity, and public key algorithms used are) s
-5 360 M
-( well-known, well-established algorithms.) s
-5 349 M
-( o All algorithms are used with cryptographically sound key sizes) s
-5 338 M
-( that are believed to provide protection against even the strongest) s
-5 327 M
-( cryptanalytic attacks for decades.) s
-5 316 M
-( o All algorithms are negotiated, and in case some algorithm is) s
-5 305 M
-( broken, it is easy to switch to some other algorithm without) s
-5 294 M
-( modifying the base protocol.) s
-5 272 M
-( Specific concessions were made to make wide-spread fast deployment) s
-5 261 M
-( easier. The particular case where this comes up is verifying that) s
-5 250 M
-( the server host key really belongs to the desired host; the protocol) s
-5 239 M
-( allows the verification to be left out \(but this is NOT RECOMMENDED\).) s
-5 228 M
-( This is believed to significantly improve usability in the short) s
-5 217 M
-( term, until widespread Internet public key infrastructures emerge.) s
-5 195 M
-(4.5 Packet Size and Overhead) s
-5 173 M
-( Some readers will worry about the increase in packet size due to new) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( headers, padding, and MAC. The minimum packet size is in the order) s
-5 679 M
-( of 28 bytes \(depending on negotiated algorithms\). The increase is) s
-5 668 M
-( negligible for large packets, but very significant for one-byte) s
-5 657 M
-( packets \(telnet-type sessions\). There are, however, several factors) s
-5 646 M
-( that make this a non-issue in almost all cases:) s
-5 635 M
-( o The minimum size of a TCP/IP header is 32 bytes. Thus, the) s
-5 624 M
-( increase is actually from 33 to 51 bytes \(roughly\).) s
-5 613 M
-( o The minimum size of the data field of an Ethernet packet is 46) s
-5 602 M
-( bytes [RFC-894]. Thus, the increase is no more than 5 bytes. When) s
-5 591 M
-( Ethernet headers are considered, the increase is less than 10) s
-5 580 M
-( percent.) s
-5 569 M
-( o The total fraction of telnet-type data in the Internet is) s
-5 558 M
-( negligible, even with increased packet sizes.) s
-5 536 M
-( The only environment where the packet size increase is likely to have) s
-5 525 M
-( a significant effect is PPP [RFC-1134] over slow modem lines \(PPP) s
-5 514 M
-( compresses the TCP/IP headers, emphasizing the increase in packet) s
-5 503 M
-( size\). However, with modern modems, the time needed to transfer is in) s
-5 492 M
-( the order of 2 milliseconds, which is a lot faster than people can) s
-5 481 M
-( type.) s
-5 459 M
-( There are also issues related to the maximum packet size. To) s
-5 448 M
-( minimize delays in screen updates, one does not want excessively) s
-5 437 M
-( large packets for interactive sessions. The maximum packet size is) s
-5 426 M
-( negotiated separately for each channel.) s
-5 404 M
-(4.6 Localization and Character Set Support) s
-5 382 M
-( For the most part, the SSH protocols do not directly pass text that) s
-5 371 M
-( would be displayed to the user. However, there are some places where) s
-5 360 M
-( such data might be passed. When applicable, the character set for the) s
-5 349 M
-( data MUST be explicitly specified. In most places, ISO 10646 with) s
-5 338 M
-( UTF-8 encoding is used [RFC-2279]. When applicable, a field is also) s
-5 327 M
-( provided for a language tag [RFC-3066].) s
-5 305 M
-( One big issue is the character set of the interactive session. There) s
-5 294 M
-( is no clear solution, as different applications may display data in) s
-5 283 M
-( different formats. Different types of terminal emulation may also be) s
-5 272 M
-( employed in the client, and the character set to be used is) s
-5 261 M
-( effectively determined by the terminal emulation. Thus, no place is) s
-5 250 M
-( provided for directly specifying the character set or encoding for) s
-5 239 M
-( terminal session data. However, the terminal emulation type \(e.g.) s
-5 228 M
-( "vt100"\) is transmitted to the remote site, and it implicitly) s
-5 217 M
-( specifies the character set and encoding. Applications typically use) s
-5 206 M
-( the terminal type to determine what character set they use, or the) s
-5 195 M
-( character set is determined using some external means. The terminal) s
-5 184 M
-( emulation may also allow configuring the default character set. In) s
-5 173 M
-( any case, the character set for the terminal session is considered) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( primarily a client local issue.) s
-5 668 M
-( Internal names used to identify algorithms or protocols are normally) s
-5 657 M
-( never displayed to users, and must be in US-ASCII.) s
-5 635 M
-( The client and server user names are inherently constrained by what) s
-5 624 M
-( the server is prepared to accept. They might, however, occasionally) s
-5 613 M
-( be displayed in logs, reports, etc. They MUST be encoded using ISO) s
-5 602 M
-( 10646 UTF-8, but other encodings may be required in some cases. It) s
-5 591 M
-( is up to the server to decide how to map user names to accepted user) s
-5 580 M
-( names. Straight bit-wise binary comparison is RECOMMENDED.) s
-5 558 M
-( For localization purposes, the protocol attempts to minimize the) s
-5 547 M
-( number of textual messages transmitted. When present, such messages) s
-5 536 M
-( typically relate to errors, debugging information, or some externally) s
-5 525 M
-( configured data. For data that is normally displayed, it SHOULD be) s
-5 514 M
-( possible to fetch a localized message instead of the transmitted) s
-5 503 M
-( message by using a numerical code. The remaining messages SHOULD be) s
-5 492 M
-( configurable.) s
-5 470 M
-(5. Data Type Representations Used in the SSH Protocols) s
-5 459 M
-( byte) s
-5 437 M
-( A byte represents an arbitrary 8-bit value \(octet\) [RFC-1700].) s
-5 426 M
-( Fixed length data is sometimes represented as an array of bytes,) s
-5 415 M
-( written byte[n], where n is the number of bytes in the array.) s
-5 393 M
-( boolean) s
-5 371 M
-( A boolean value is stored as a single byte. The value 0) s
-5 360 M
-( represents FALSE, and the value 1 represents TRUE. All non-zero) s
-5 349 M
-( values MUST be interpreted as TRUE; however, applications MUST NOT) s
-5 338 M
-( store values other than 0 and 1.) s
-5 316 M
-( uint32) s
-5 294 M
-( Represents a 32-bit unsigned integer. Stored as four bytes in the) s
-5 283 M
-( order of decreasing significance \(network byte order\). For) s
-5 272 M
-( example, the value 699921578 \(0x29b7f4aa\) is stored as 29 b7 f4) s
-5 261 M
-( aa.) s
-5 239 M
-( uint64) s
-5 217 M
-( Represents a 64-bit unsigned integer. Stored as eight bytes in) s
-5 206 M
-( the order of decreasing significance \(network byte order\).) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( string) s
-5 668 M
-( Arbitrary length binary string. Strings are allowed to contain) s
-5 657 M
-( arbitrary binary data, including null characters and 8-bit) s
-5 646 M
-( characters. They are stored as a uint32 containing its length) s
-5 635 M
-( \(number of bytes that follow\) and zero \(= empty string\) or more) s
-5 624 M
-( bytes that are the value of the string. Terminating null) s
-5 613 M
-( characters are not used.) s
-5 591 M
-( Strings are also used to store text. In that case, US-ASCII is) s
-5 580 M
-( used for internal names, and ISO-10646 UTF-8 for text that might) s
-5 569 M
-( be displayed to the user. The terminating null character SHOULD) s
-5 558 M
-( NOT normally be stored in the string.) s
-5 536 M
-( For example, the US-ASCII string "testing" is represented as 00 00) s
-5 525 M
-( 00 07 t e s t i n g. The UTF8 mapping does not alter the encoding) s
-5 514 M
-( of US-ASCII characters.) s
-5 492 M
-( mpint) s
-5 470 M
-( Represents multiple precision integers in two's complement format,) s
-5 459 M
-( stored as a string, 8 bits per byte, MSB first. Negative numbers) s
-5 448 M
-( have the value 1 as the most significant bit of the first byte of) s
-5 437 M
-( the data partition. If the most significant bit would be set for a) s
-5 426 M
-( positive number, the number MUST be preceded by a zero byte.) s
-5 415 M
-( Unnecessary leading bytes with the value 0 or 255 MUST NOT be) s
-5 404 M
-( included. The value zero MUST be stored as a string with zero) s
-5 393 M
-( bytes of data.) s
-5 371 M
-( By convention, a number that is used in modular computations in) s
-5 360 M
-( Z_n SHOULD be represented in the range 0 <= x < n.) s
-5 338 M
-( Examples:) s
-5 327 M
-( value \(hex\) representation \(hex\)) s
-5 316 M
-( ---------------------------------------------------------------) s
-5 305 M
-( 0 00 00 00 00) s
-5 294 M
-( 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7) s
-5 283 M
-( 80 00 00 00 02 00 80) s
-5 272 M
-( -1234 00 00 00 02 ed cc) s
-5 261 M
-( -deadbeef 00 00 00 05 ff 21 52 41 11) s
-5 217 M
-( name-list) s
-5 195 M
-( A string containing a comma separated list of names. A name list) s
-5 184 M
-( is represented as a uint32 containing its length \(number of bytes) s
-5 173 M
-( that follow\) followed by a comma-separated list of zero or more) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( names. A name MUST be non-zero length, and it MUST NOT contain a) s
-5 679 M
-( comma \(','\). Context may impose additional restrictions on the) s
-5 668 M
-( names; for example, the names in a list may have to be valid) s
-5 657 M
-( algorithm identifier \(see Algorithm Naming below\), or [RFC-3066]) s
-5 646 M
-( language tags. The order of the names in a list may or may not be) s
-5 635 M
-( significant, also depending on the context where the list is is) s
-5 624 M
-( used. Terminating NUL characters are not used, neither for the) s
-5 613 M
-( individual names, nor for the list as a whole.) s
-5 591 M
-( Examples:) s
-5 580 M
-( value representation \(hex\)) s
-5 569 M
-( ---------------------------------------) s
-5 558 M
-( \(\), the empty list 00 00 00 00) s
-5 547 M
-( \("zlib"\) 00 00 00 04 7a 6c 69 62) s
-5 536 M
-( \("zlib", "none"\) 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65) s
-5 481 M
-(6. Algorithm Naming) s
-5 459 M
-( The SSH protocols refer to particular hash, encryption, integrity,) s
-5 448 M
-( compression, and key exchange algorithms or protocols by names.) s
-5 437 M
-( There are some standard algorithms that all implementations MUST) s
-5 426 M
-( support. There are also algorithms that are defined in the protocol) s
-5 415 M
-( specification but are OPTIONAL. Furthermore, it is expected that) s
-5 404 M
-( some organizations will want to use their own algorithms.) s
-5 382 M
-( In this protocol, all algorithm identifiers MUST be printable) s
-5 371 M
-( US-ASCII non-empty strings no longer than 64 characters. Names MUST) s
-5 360 M
-( be case-sensitive.) s
-5 338 M
-( There are two formats for algorithm names:) s
-5 327 M
-( o Names that do not contain an at-sign \(@\) are reserved to be) s
-5 316 M
-( assigned by IETF consensus \(RFCs\). Examples include `3des-cbc',) s
-5 305 M
-( `sha-1', `hmac-sha1', and `zlib' \(the quotes are not part of the) s
-5 294 M
-( name\). Names of this format MUST NOT be used without first) s
-5 283 M
-( registering them. Registered names MUST NOT contain an at-sign) s
-5 272 M
-( \(@\) or a comma \(,\).) s
-5 261 M
-( o Anyone can define additional algorithms by using names in the) s
-5 250 M
-( format name@domainname, e.g. "[email protected]". The) s
-5 239 M
-( format of the part preceding the at sign is not specified; it MUST) s
-5 228 M
-( consist of US-ASCII characters except at-sign and comma. The part) s
-5 217 M
-( following the at-sign MUST be a valid fully qualified internet) s
-5 206 M
-( domain name [RFC-1034] controlled by the person or organization) s
-5 195 M
-( defining the name. It is up to each domain how it manages its) s
-5 184 M
-( local namespace.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(7. Message Numbers) s
-5 668 M
-( SSH packets have message numbers in the range 1 to 255. These numbers) s
-5 657 M
-( have been allocated as follows:) s
-5 624 M
-( Transport layer protocol:) s
-5 602 M
-( 1 to 19 Transport layer generic \(e.g. disconnect, ignore, debug,) s
-5 591 M
-( etc.\)) s
-5 580 M
-( 20 to 29 Algorithm negotiation) s
-5 569 M
-( 30 to 49 Key exchange method specific \(numbers can be reused for) s
-5 558 M
-( different authentication methods\)) s
-5 536 M
-( User authentication protocol:) s
-5 514 M
-( 50 to 59 User authentication generic) s
-5 503 M
-( 60 to 79 User authentication method specific \(numbers can be) s
-5 492 M
-( reused for different authentication methods\)) s
-5 470 M
-( Connection protocol:) s
-5 448 M
-( 80 to 89 Connection protocol generic) s
-5 437 M
-( 90 to 127 Channel related messages) s
-5 415 M
-( Reserved for client protocols:) s
-5 393 M
-( 128 to 191 Reserved) s
-5 371 M
-( Local extensions:) s
-5 349 M
-( 192 to 255 Local extensions) s
-5 305 M
-(8. IANA Considerations) s
-5 283 M
-( The initial state of the IANA registry is detailed in [SSH-NUMBERS].) s
-5 261 M
-( Allocation of the following types of names in the SSH protocols is) s
-5 250 M
-( assigned by IETF consensus:) s
-5 239 M
-( o SSH encryption algorithm names,) s
-5 228 M
-( o SSH MAC algorithm names,) s
-5 217 M
-( o SSH public key algorithm names \(public key algorithm also implies) s
-5 206 M
-( encoding and signature/encryption capability\),) s
-5 195 M
-( o SSH key exchange method names, and) s
-5 184 M
-( o SSH protocol \(service\) names.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( These names MUST be printable US-ASCII strings, and MUST NOT contain) s
-5 679 M
-( the characters at-sign \('@'\), comma \(','\), or whitespace or control) s
-5 668 M
-( characters \(ASCII codes 32 or less\). Names are case-sensitive, and) s
-5 657 M
-( MUST NOT be longer than 64 characters.) s
-5 635 M
-( Names with the at-sign \('@'\) in them are allocated by the owner of) s
-5 624 M
-( DNS name after the at-sign \(hierarchical allocation in [RFC-2343]\),) s
-5 613 M
-( otherwise the same restrictions as above.) s
-5 591 M
-( Each category of names listed above has a separate namespace.) s
-5 580 M
-( However, using the same name in multiple categories SHOULD be avoided) s
-5 569 M
-( to minimize confusion.) s
-5 547 M
-( Message numbers \(see Section Message Numbers \(Section 7\)\) in the) s
-5 536 M
-( range of 0..191 are allocated via IETF consensus; message numbers in) s
-5 525 M
-( the 192..255 range \(the "Local extensions" set\) are reserved for) s
-5 514 M
-( private use.) s
-5 492 M
-(9. Security Considerations) s
-5 470 M
-( In order to make the entire body of Security Considerations more) s
-5 459 M
-( accessible, Security Considerations for the transport,) s
-5 448 M
-( authentication, and connection documents have been gathered here.) s
-5 426 M
-( The transport protocol [1] provides a confidential channel over an) s
-5 415 M
-( insecure network. It performs server host authentication, key) s
-5 404 M
-( exchange, encryption, and integrity protection. It also derives a) s
-5 393 M
-( unique session id that may be used by higher-level protocols.) s
-5 371 M
-( The authentication protocol [2] provides a suite of mechanisms which) s
-5 360 M
-( can be used to authenticate the client user to the server.) s
-5 349 M
-( Individual mechanisms specified in the in authentication protocol use) s
-5 338 M
-( the session id provided by the transport protocol and/or depend on) s
-5 327 M
-( the security and integrity guarantees of the transport protocol.) s
-5 305 M
-( The connection protocol [3] specifies a mechanism to multiplex) s
-5 294 M
-( multiple streams [channels] of data over the confidential and) s
-5 283 M
-( authenticated transport. It also specifies channels for accessing an) s
-5 272 M
-( interactive shell, for 'proxy-forwarding' various external protocols) s
-5 261 M
-( over the secure transport \(including arbitrary TCP/IP protocols\), and) s
-5 250 M
-( for accessing secure 'subsystems' on the server host.) s
-5 228 M
-(9.1 Pseudo-Random Number Generation) s
-5 206 M
-( This protocol binds each session key to the session by including) s
-5 195 M
-( random, session specific data in the hash used to produce session) s
-5 184 M
-( keys. Special care should be taken to ensure that all of the random) s
-5 173 M
-( numbers are of good quality. If the random data here \(e.g., DH) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( parameters\) are pseudo-random then the pseudo-random number generator) s
-5 679 M
-( should be cryptographically secure \(i.e., its next output not easily) s
-5 668 M
-( guessed even when knowing all previous outputs\) and, furthermore,) s
-5 657 M
-( proper entropy needs to be added to the pseudo-random number) s
-5 646 M
-( generator. RFC 1750 [1750] offers suggestions for sources of random) s
-5 635 M
-( numbers and entropy. Implementors should note the importance of) s
-5 624 M
-( entropy and the well-meant, anecdotal warning about the difficulty in) s
-5 613 M
-( properly implementing pseudo-random number generating functions.) s
-5 591 M
-( The amount of entropy available to a given client or server may) s
-5 580 M
-( sometimes be less than what is required. In this case one must) s
-5 569 M
-( either resort to pseudo-random number generation regardless of) s
-5 558 M
-( insufficient entropy or refuse to run the protocol. The latter is) s
-5 547 M
-( preferable.) s
-5 525 M
-(9.2 Transport) s
-5 503 M
-(9.2.1 Confidentiality) s
-5 481 M
-( It is beyond the scope of this document and the Secure Shell Working) s
-5 470 M
-( Group to analyze or recommend specific ciphers other than the ones) s
-5 459 M
-( which have been established and accepted within the industry. At the) s
-5 448 M
-( time of this writing, ciphers commonly in use include 3DES, ARCFOUR,) s
-5 437 M
-( twofish, serpent and blowfish. AES has been accepted by The) s
-5 426 M
-( published as a US Federal Information Processing Standards [FIPS-197]) s
-5 415 M
-( and the cryptographic community as being acceptable for this purpose) s
-5 404 M
-( as well has accepted AES. As always, implementors and users should) s
-5 393 M
-( check current literature to ensure that no recent vulnerabilities) s
-5 382 M
-( have been found in ciphers used within products. Implementors should) s
-5 371 M
-( also check to see which ciphers are considered to be relatively) s
-5 360 M
-( stronger than others and should recommend their use to users over) s
-5 349 M
-( relatively weaker ciphers. It would be considered good form for an) s
-5 338 M
-( implementation to politely and unobtrusively notify a user that a) s
-5 327 M
-( stronger cipher is available and should be used when a weaker one is) s
-5 316 M
-( actively chosen.) s
-5 294 M
-( The "none" cipher is provided for debugging and SHOULD NOT be used) s
-5 283 M
-( except for that purpose. It's cryptographic properties are) s
-5 272 M
-( sufficiently described in RFC 2410, which will show that its use does) s
-5 261 M
-( not meet the intent of this protocol.) s
-5 239 M
-( The relative merits of these and other ciphers may also be found in) s
-5 228 M
-( current literature. Two references that may provide information on) s
-5 217 M
-( the subject are [SCHNEIER] and [KAUFMAN,PERLMAN,SPECINER]. Both of) s
-5 206 M
-( these describe the CBC mode of operation of certain ciphers and the) s
-5 195 M
-( weakness of this scheme. Essentially, this mode is theoretically) s
-5 184 M
-( vulnerable to chosen cipher-text attacks because of the high) s
-5 173 M
-( predictability of the start of packet sequence. However, this attack) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( is still deemed difficult and not considered fully practicable) s
-5 679 M
-( especially if relatively longer block sizes are used.) s
-5 657 M
-( Additionally, another CBC mode attack may be mitigated through the) s
-5 646 M
-( insertion of packets containing SSH_MSG_IGNORE. Without this) s
-5 635 M
-( technique, a specific attack may be successful. For this attack) s
-5 624 M
-( \(commonly known as the Rogaway attack) s
-5 613 M
-( [ROGAWAY],[DAI],[BELLARE,KOHNO,NAMPREMPRE]\) to work, the attacker) s
-5 602 M
-( would need to know the IV of the next block that is going to be) s
-5 591 M
-( encrypted. In CBC mode that is the output of the encryption of the) s
-5 580 M
-( previous block. If the attacker does not have any way to see the) s
-5 569 M
-( packet yet \(i.e it is in the internal buffers of the ssh) s
-5 558 M
-( implementation or even in the kernel\) then this attack will not work.) s
-5 547 M
-( If the last packet has been sent out to the network \(i.e the attacker) s
-5 536 M
-( has access to it\) then he can use the attack.) s
-5 514 M
-( In the optimal case an implementor would need to add an extra packet) s
-5 503 M
-( only if the packet has been sent out onto the network and there are) s
-5 492 M
-( no other packets waiting for transmission. Implementors may wish to) s
-5 481 M
-( check to see if there are any unsent packets awaiting transmission,) s
-5 470 M
-( but unfortunately it is not normally easy to obtain this information) s
-5 459 M
-( from the kernel or buffers. If there are not, then a packet) s
-5 448 M
-( containing SSH_MSG_IGNORE SHOULD be sent. If a new packet is added) s
-5 437 M
-( to the stream every time the attacker knows the IV that is supposed) s
-5 426 M
-( to be used for the next packet, then the attacker will not be able to) s
-5 415 M
-( guess the correct IV, thus the attack will never be successfull.) s
-5 393 M
-( As an example, consider the following case:) s
-5 360 M
-( Client Server) s
-5 349 M
-( ------ ------) s
-5 338 M
-( TCP\(seq=x, len=500\) ->) s
-5 327 M
-( contains Record 1) s
-5 305 M
-( [500 ms passes, no ACK]) s
-5 283 M
-( TCP\(seq=x, len=1000\) ->) s
-5 272 M
-( contains Records 1,2) s
-5 250 M
-( ACK) s
-5 217 M
-( 1. The Nagle algorithm + TCP retransmits mean that the two records) s
-5 206 M
-( get coalesced into a single TCP segment) s
-5 195 M
-( 2. Record 2 is *not* at the beginning of the TCP segment and never) s
-5 184 M
-( will be, since it gets ACKed.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( 3. Yet, the attack is possible because Record 1 has already been) s
-5 679 M
-( seen.) s
-5 657 M
-( As this example indicates, it's totally unsafe to use the existence) s
-5 646 M
-( of unflushed data in the TCP buffers proper as a guide to whether you) s
-5 635 M
-( need an empty packet, since when you do the second write\(\), the) s
-5 624 M
-( buffers will contain the un-ACKed Record 1.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( On the other hand, it's perfectly safe to have the following) s
-5 679 M
-( situation:) s
-5 646 M
-( Client Server) s
-5 635 M
-( ------ ------) s
-5 624 M
-( TCP\(seq=x, len=500\) ->) s
-5 613 M
-( contains SSH_MSG_IGNORE) s
-5 591 M
-( TCP\(seq=y, len=500\) ->) s
-5 580 M
-( contains Data) s
-5 558 M
-( Provided that the IV for second SSH Record is fixed after the data for) s
-5 547 M
-( the Data packet is determined -i.e. you do:) s
-5 536 M
-( read from user) s
-5 525 M
-( encrypt null packet) s
-5 514 M
-( encrypt data packet) s
-5 481 M
-(9.2.2 Data Integrity) s
-5 459 M
-( This protocol does allow the Data Integrity mechanism to be disabled.) s
-5 448 M
-( Implementors SHOULD be wary of exposing this feature for any purpose) s
-5 437 M
-( other than debugging. Users and administrators SHOULD be explicitly) s
-5 426 M
-( warned anytime the "none" MAC is enabled.) s
-5 404 M
-( So long as the "none" MAC is not used, this protocol provides data) s
-5 393 M
-( integrity.) s
-5 371 M
-( Because MACs use a 32 bit sequence number, they might start to leak) s
-5 360 M
-( information after 2**32 packets have been sent. However, following) s
-5 349 M
-( the rekeying recommendations should prevent this attack. The) s
-5 338 M
-( transport protocol [1] recommends rekeying after one gigabyte of) s
-5 327 M
-( data, and the smallest possible packet is 16 bytes. Therefore,) s
-5 316 M
-( rekeying SHOULD happen after 2**28 packets at the very most.) s
-5 294 M
-(9.2.3 Replay) s
-5 272 M
-( The use of a MAC other than 'none' provides integrity and) s
-5 261 M
-( authentication. In addition, the transport protocol provides a) s
-5 250 M
-( unique session identifier \(bound in part to pseudo-random data that) s
-5 239 M
-( is part of the algorithm and key exchange process\) that can be used) s
-5 228 M
-( by higher level protocols to bind data to a given session and prevent) s
-5 217 M
-( replay of data from prior sessions. For example, the authentication) s
-5 206 M
-( protocol uses this to prevent replay of signatures from previous) s
-5 195 M
-( sessions. Because public key authentication exchanges are) s
-5 184 M
-( cryptographically bound to the session \(i.e., to the initial key) s
-5 173 M
-( exchange\) they cannot be successfully replayed in other sessions.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( Note that the session ID can be made public without harming the) s
-5 679 M
-( security of the protocol.) s
-5 657 M
-( If two session happen to have the same session ID [hash of key) s
-5 646 M
-( exchanges] then packets from one can be replayed against the other.) s
-5 635 M
-( It must be stressed that the chances of such an occurrence are,) s
-5 624 M
-( needless to say, minimal when using modern cryptographic methods.) s
-5 613 M
-( This is all the more so true when specifying larger hash function) s
-5 602 M
-( outputs and DH parameters.) s
-5 580 M
-( Replay detection using monotonically increasing sequence numbers as) s
-5 569 M
-( input to the MAC, or HMAC in some cases, is described in [RFC2085] />) s
-5 558 M
-( [RFC2246], [RFC2743], [RFC1964], [RFC2025], and [RFC1510]. The) s
-5 547 M
-( underlying construct is discussed in [RFC2104]. Essentially a) s
-5 536 M
-( different sequence number in each packet ensures that at least this) s
-5 525 M
-( one input to the MAC function will be unique and will provide a) s
-5 514 M
-( nonrecurring MAC output that is not predictable to an attacker. If) s
-5 503 M
-( the session stays active long enough, however, this sequence number) s
-5 492 M
-( will wrap. This event may provide an attacker an opportunity to) s
-5 481 M
-( replay a previously recorded packet with an identical sequence number) s
-5 470 M
-( but only if the peers have not rekeyed since the transmission of the) s
-5 459 M
-( first packet with that sequence number. If the peers have rekeyed,) s
-5 448 M
-( then the replay will be detected as the MAC check will fail. For) s
-5 437 M
-( this reason, it must be emphasized that peers MUST rekey before a) s
-5 426 M
-( wrap of the sequence numbers. Naturally, if an attacker does attempt) s
-5 415 M
-( to replay a captured packet before the peers have rekeyed, then the) s
-5 404 M
-( receiver of the duplicate packet will not be able to validate the MAC) s
-5 393 M
-( and it will be discarded. The reason that the MAC will fail is) s
-5 382 M
-( because the receiver will formulate a MAC based upon the packet) s
-5 371 M
-( contents, the shared secret, and the expected sequence number. Since) s
-5 360 M
-( the replayed packet will not be using that expected sequence number) s
-5 349 M
-( \(the sequence number of the replayed packet will have already been) s
-5 338 M
-( passed by the receiver\) then the calculated MAC will not match the) s
-5 327 M
-( MAC received with the packet.) s
-5 305 M
-(9.2.4 Man-in-the-middle) s
-5 283 M
-( This protocol makes no assumptions nor provisions for an) s
-5 272 M
-( infrastructure or means for distributing the public keys of hosts. It) s
-5 261 M
-( is expected that this protocol will sometimes be used without first) s
-5 250 M
-( verifying the association between the server host key and the server) s
-5 239 M
-( host name. Such usage is vulnerable to man-in-the-middle attacks.) s
-5 228 M
-( This section describes this and encourages administrators and users) s
-5 217 M
-( to understand the importance of verifying this association before any) s
-5 206 M
-( session is initiated.) s
-5 184 M
-( There are three cases of man-in-the-middle attacks to consider. The) s
-5 173 M
-( first is where an attacker places a device between the client and the) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( server before the session is initiated. In this case, the attack) s
-5 679 M
-( device is trying to mimic the legitimate server and will offer its) s
-5 668 M
-( public key to the client when the client initiates a session. If it) s
-5 657 M
-( were to offer the public key of the server, then it would not be able) s
-5 646 M
-( to decrypt or sign the transmissions between the legitimate server) s
-5 635 M
-( and the client unless it also had access to the private-key of the) s
-5 624 M
-( host. The attack device will also, simultaneously to this, initiate) s
-5 613 M
-( a session to the legitimate server masquerading itself as the client.) s
-5 602 M
-( If the public key of the server had been securely distributed to the) s
-5 591 M
-( client prior to that session initiation, the key offered to the) s
-5 580 M
-( client by the attack device will not match the key stored on the) s
-5 569 M
-( client. In that case, the user SHOULD be given a warning that the) s
-5 558 M
-( offered host key does not match the host key cached on the client.) s
-5 547 M
-( As described in Section 3.1 of [ARCH], the user may be free to accept) s
-5 536 M
-( the new key and continue the session. It is RECOMMENDED that the) s
-5 525 M
-( warning provide sufficient information to the user of the client) s
-5 514 M
-( device so they may make an informed decision. If the user chooses to) s
-5 503 M
-( continue the session with the stored public-key of the server \(not) s
-5 492 M
-( the public-key offered at the start of the session\), then the session) s
-5 481 M
-( specific data between the attacker and server will be different) s
-5 470 M
-( between the client-to-attacker session and the attacker-to-server) s
-5 459 M
-( sessions due to the randomness discussed above. From this, the) s
-5 448 M
-( attacker will not be able to make this attack work since the attacker) s
-5 437 M
-( will not be able to correctly sign packets containing this session) s
-5 426 M
-( specific data from the server since he does not have the private key) s
-5 415 M
-( of that server.) s
-5 393 M
-( The second case that should be considered is similar to the first) s
-5 382 M
-( case in that it also happens at the time of connection but this case) s
-5 371 M
-( points out the need for the secure distribution of server public) s
-5 360 M
-( keys. If the server public keys are not securely distributed then) s
-5 349 M
-( the client cannot know if it is talking to the intended server. An) s
-5 338 M
-( attacker may use social engineering techniques to pass off server) s
-5 327 M
-( keys to unsuspecting users and may then place a man-in-the-middle) s
-5 316 M
-( attack device between the legitimate server and the clients. If this) s
-5 305 M
-( is allowed to happen then the clients will form client-to-attacker) s
-5 294 M
-( sessions and the attacker will form attacker-to-server sessions and) s
-5 283 M
-( will be able to monitor and manipulate all of the traffic between the) s
-5 272 M
-( clients and the legitimate servers. Server administrators are) s
-5 261 M
-( encouraged to make host key fingerprints available for checking by) s
-5 250 M
-( some means whose security does not rely on the integrity of the) s
-5 239 M
-( actual host keys. Possible mechanisms are discussed in Section 3.1) s
-5 228 M
-( of [SSH-ARCH] and may also include secured Web pages, physical pieces) s
-5 217 M
-( of paper, etc. Implementors SHOULD provide recommendations on how) s
-5 206 M
-( best to do this with their implementation. Because the protocol is) s
-5 195 M
-( extensible, future extensions to the protocol may provide better) s
-5 184 M
-( mechanisms for dealing with the need to know the server's host key) s
-5 173 M
-( before connecting. For example, making the host key fingerprint) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( available through a secure DNS lookup, or using kerberos over gssapi) s
-5 679 M
-( during key exchange to authenticate the server are possibilities.) s
-5 657 M
-( In the third man-in-the-middle case, attackers may attempt to) s
-5 646 M
-( manipulate packets in transit between peers after the session has) s
-5 635 M
-( been established. As described in the Replay part of this section, a) s
-5 624 M
-( successful attack of this nature is very improbable. As in the) s
-5 613 M
-( Replay section, this reasoning does assume that the MAC is secure and) s
-5 602 M
-( that it is infeasible to construct inputs to a MAC algorithm to give) s
-5 591 M
-( a known output. This is discussed in much greater detail in Section) s
-5 580 M
-( 6 of RFC 2104. If the MAC algorithm has a vulnerability or is weak) s
-5 569 M
-( enough, then the attacker may be able to specify certain inputs to) s
-5 558 M
-( yield a known MAC. With that they may be able to alter the contents) s
-5 547 M
-( of a packet in transit. Alternatively the attacker may be able to) s
-5 536 M
-( exploit the algorithm vulnerability or weakness to find the shared) s
-5 525 M
-( secret by reviewing the MACs from captured packets. In either of) s
-5 514 M
-( those cases, an attacker could construct a packet or packets that) s
-5 503 M
-( could be inserted into an SSH stream. To prevent that, implementors) s
-5 492 M
-( are encouraged to utilize commonly accepted MAC algorithms and) s
-5 481 M
-( administrators are encouraged to watch current literature and) s
-5 470 M
-( discussions of cryptography to ensure that they are not using a MAC) s
-5 459 M
-( algorithm that has a recently found vulnerability or weakness.) s
-5 437 M
-( In summary, the use of this protocol without a reliable association) s
-5 426 M
-( of the binding between a host and its host keys is inherently) s
-5 415 M
-( insecure and is NOT RECOMMENDED. It may however be necessary in) s
-5 404 M
-( non-security critical environments, and will still provide protection) s
-5 393 M
-( against passive attacks. Implementors of protocols and applications) s
-5 382 M
-( running on top of this protocol should keep this possibility in mind.) s
-5 360 M
-(9.2.5 Denial-of-service) s
-5 338 M
-( This protocol is designed to be used over a reliable transport. If) s
-5 327 M
-( transmission errors or message manipulation occur, the connection is) s
-5 316 M
-( closed. The connection SHOULD be re-established if this occurs.) s
-5 305 M
-( Denial of service attacks of this type \("wire cutter"\) are almost) s
-5 294 M
-( impossible to avoid.) s
-5 272 M
-( In addition, this protocol is vulnerable to Denial of Service attacks) s
-5 261 M
-( because an attacker can force the server to go through the CPU and) s
-5 250 M
-( memory intensive tasks of connection setup and key exchange without) s
-5 239 M
-( authenticating. Implementors SHOULD provide features that make this) s
-5 228 M
-( more difficult. For example, only allowing connections from a subset) s
-5 217 M
-( of IPs known to have valid users.) s
-5 195 M
-(9.2.6 Covert Channels) s
-5 173 M
-( The protocol was not designed to eliminate covert channels. For) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( example, the padding, SSH_MSG_IGNORE messages, and several other) s
-5 679 M
-( places in the protocol can be used to pass covert information, and) s
-5 668 M
-( the recipient has no reliable way to verify whether such information) s
-5 657 M
-( is being sent.) s
-5 635 M
-(9.2.7 Forward Secrecy) s
-5 613 M
-( It should be noted that the Diffie-Hellman key exchanges may provide) s
-5 602 M
-( perfect forward secrecy \(PFS\). PFS is essentially defined as the) s
-5 591 M
-( cryptographic property of a key-establishment protocol in which the) s
-5 580 M
-( compromise of a session key or long-term private key after a given) s
-5 569 M
-( session does not cause the compromise of any earlier session. [ANSI) s
-5 558 M
-( T1.523-2001] SSHv2 sessions resulting from a key exchange using) s
-5 547 M
-( diffie-hellman-group1-sha1 are secure even if private keying/) s
-5 536 M
-( authentication material is later revealed, but not if the session) s
-5 525 M
-( keys are revealed. So, given this definition of PFS, SSHv2 does have) s
-5 514 M
-( PFS. It is hoped that all other key exchange mechanisms proposed and) s
-5 503 M
-( used in the future will also provide PFS. This property is not) s
-5 492 M
-( commuted to any of the applications or protocols using SSH as a) s
-5 481 M
-( transport however. The transport layer of SSH provides) s
-5 470 M
-( confidentiality for password authentication and other methods that) s
-5 459 M
-( rely on secret data.) s
-5 437 M
-( Of course, if the DH private parameters for the client and server are) s
-5 426 M
-( revealed then the session key is revealed, but these items can be) s
-5 415 M
-( thrown away after the key exchange completes. It's worth pointing) s
-5 404 M
-( out that these items should not be allowed to end up on swap space) s
-5 393 M
-( and that they should be erased from memory as soon as the key) s
-5 382 M
-( exchange completes.) s
-5 360 M
-(9.3 Authentication Protocol) s
-5 338 M
-( The purpose of this protocol is to perform client user) s
-5 327 M
-( authentication. It assumes that this run over a secure transport) s
-5 316 M
-( layer protocol, which has already authenticated the server machine,) s
-5 305 M
-( established an encrypted communications channel, and computed a) s
-5 294 M
-( unique session identifier for this session.) s
-5 272 M
-( Several authentication methods with different security) s
-5 261 M
-( characteristics are allowed. It is up to the server's local policy) s
-5 250 M
-( to decide which methods \(or combinations of methods\) it is willing to) s
-5 239 M
-( accept for each user. Authentication is no stronger than the weakest) s
-5 228 M
-( combination allowed.) s
-5 206 M
-( The server may go into a "sleep" period after repeated unsuccessful) s
-5 195 M
-( authentication attempts to make key search more difficult for) s
-5 184 M
-( attackers. Care should be taken so that this doesn't become a) s
-5 173 M
-( self-denial of service vector.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(9.3.1 Weak Transport) s
-5 668 M
-( If the transport layer does not provide confidentiality,) s
-5 657 M
-( authentication methods that rely on secret data SHOULD be disabled.) s
-5 646 M
-( If it does not provide strong integrity protection, requests to) s
-5 635 M
-( change authentication data \(e.g. a password change\) SHOULD be) s
-5 624 M
-( disabled to prevent an attacker from modifying the ciphertext) s
-5 613 M
-( without being noticed, or rendering the new authentication data) s
-5 602 M
-( unusable \(denial of service\).) s
-5 580 M
-( The assumption as stated above that the Authentication Protocol only) s
-5 569 M
-( run over a secure transport that has previously authenticated the) s
-5 558 M
-( server is very important to note. People deploying SSH are reminded) s
-5 547 M
-( of the consequences of man-in-the-middle attacks if the client does) s
-5 536 M
-( not have a very strong a priori association of the server with the) s
-5 525 M
-( host key of that server. Specifically for the case of the) s
-5 514 M
-( Authentication Protocol the client may form a session to a) s
-5 503 M
-( man-in-the-middle attack device and divulge user credentials such as) s
-5 492 M
-( their username and password. Even in the cases of authentication) s
-5 481 M
-( where no user credentials are divulged, an attacker may still gain) s
-5 470 M
-( information they shouldn't have by capturing key-strokes in much the) s
-5 459 M
-( same way that a honeypot works.) s
-5 437 M
-(9.3.2 Debug messages) s
-5 415 M
-( Special care should be taken when designing debug messages. These) s
-5 404 M
-( messages may reveal surprising amounts of information about the host) s
-5 393 M
-( if not properly designed. Debug messages can be disabled \(during) s
-5 382 M
-( user authentication phase\) if high security is required.) s
-5 371 M
-( Administrators of host machines should make all attempts to) s
-5 360 M
-( compartmentalize all event notification messages and protect them) s
-5 349 M
-( from unwarranted observation. Developers should be aware of the) s
-5 338 M
-( sensitive nature of some of the normal event messages and debug) s
-5 327 M
-( messages and may want to provide guidance to administrators on ways) s
-5 316 M
-( to keep this information away from unauthorized people. Developers) s
-5 305 M
-( should consider minimizing the amount of sensitive information) s
-5 294 M
-( obtainable by users during the authentication phase in accordance) s
-5 283 M
-( with the local policies. For this reason, it is RECOMMENDED that) s
-5 272 M
-( debug messages be initially disabled at the time of deployment and) s
-5 261 M
-( require an active decision by an administrator to allow them to be) s
-5 250 M
-( enabled. It is also RECOMMENDED that a message expressing this) s
-5 239 M
-( concern be presented to the administrator of a system when the action) s
-5 228 M
-( is taken to enable debugging messages.) s
-5 206 M
-(9.3.3 Local security policy) s
-5 184 M
-( Implementer MUST ensure that the credentials provided validate the) s
-5 173 M
-( professed user and also MUST ensure that the local policy of the) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( server permits the user the access requested. In particular, because) s
-5 679 M
-( of the flexible nature of the SSH connection protocol, it may not be) s
-5 668 M
-( possible to determine the local security policy, if any, that should) s
-5 657 M
-( apply at the time of authentication because the kind of service being) s
-5 646 M
-( requested is not clear at that instant. For example, local policy) s
-5 635 M
-( might allow a user to access files on the server, but not start an) s
-5 624 M
-( interactive shell. However, during the authentication protocol, it is) s
-5 613 M
-( not known whether the user will be accessing files or attempting to) s
-5 602 M
-( use an interactive shell, or even both. In any event, where local) s
-5 591 M
-( security policy for the server host exists, it MUST be applied and) s
-5 580 M
-( enforced correctly.) s
-5 558 M
-( Implementors are encouraged to provide a default local policy and) s
-5 547 M
-( make its parameters known to administrators and users. At the) s
-5 536 M
-( discretion of the implementors, this default policy may be along the) s
-5 525 M
-( lines of 'anything goes' where there are no restrictions placed upon) s
-5 514 M
-( users, or it may be along the lines of 'excessively restrictive' in) s
-5 503 M
-( which case the administrators will have to actively make changes to) s
-5 492 M
-( this policy to meet their needs. Alternatively, it may be some) s
-5 481 M
-( attempt at providing something practical and immediately useful to) s
-5 470 M
-( the administrators of the system so they don't have to put in much) s
-5 459 M
-( effort to get SSH working. Whatever choice is made MUST be applied) s
-5 448 M
-( and enforced as required above.) s
-5 426 M
-(9.3.4 Public key authentication) s
-5 404 M
-( The use of public-key authentication assumes that the client host has) s
-5 393 M
-( not been compromised. It also assumes that the private-key of the) s
-5 382 M
-( server host has not been compromised.) s
-5 360 M
-( This risk can be mitigated by the use of passphrases on private keys;) s
-5 349 M
-( however, this is not an enforceable policy. The use of smartcards,) s
-5 338 M
-( or other technology to make passphrases an enforceable policy is) s
-5 327 M
-( suggested.) s
-5 305 M
-( The server could require both password and public-key authentication,) s
-5 294 M
-( however, this requires the client to expose its password to the) s
-5 283 M
-( server \(see section on password authentication below.\)) s
-5 261 M
-(9.3.5 Password authentication) s
-5 239 M
-( The password mechanism as specified in the authentication protocol) s
-5 228 M
-( assumes that the server has not been compromised. If the server has) s
-5 217 M
-( been compromised, using password authentication will reveal a valid) s
-5 206 M
-( username / password combination to the attacker, which may lead to) s
-5 195 M
-( further compromises.) s
-5 173 M
-( This vulnerability can be mitigated by using an alternative form of) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( authentication. For example, public-key authentication makes no) s
-5 679 M
-( assumptions about security on the server.) s
-5 657 M
-(9.3.6 Host based authentication) s
-5 635 M
-( Host based authentication assumes that the client has not been) s
-5 624 M
-( compromised. There are no mitigating strategies, other than to use) s
-5 613 M
-( host based authentication in combination with another authentication) s
-5 602 M
-( method.) s
-5 580 M
-(9.4 Connection protocol) s
-5 558 M
-(9.4.1 End point security) s
-5 536 M
-( End point security is assumed by the connection protocol. If the) s
-5 525 M
-( server has been compromised, any terminal sessions, port forwarding,) s
-5 514 M
-( or systems accessed on the host are compromised. There are no) s
-5 503 M
-( mitigating factors for this.) s
-5 481 M
-( If the client end point has been compromised, and the server fails to) s
-5 470 M
-( stop the attacker at the authentication protocol, all services) s
-5 459 M
-( exposed \(either as subsystems or through forwarding\) will be) s
-5 448 M
-( vulnerable to attack. Implementors SHOULD provide mechanisms for) s
-5 437 M
-( administrators to control which services are exposed to limit the) s
-5 426 M
-( vulnerability of other services.) s
-5 404 M
-( These controls might include controlling which machines and ports can) s
-5 393 M
-( be target in 'port-forwarding' operations, which users are allowed to) s
-5 382 M
-( use interactive shell facilities, or which users are allowed to use) s
-5 371 M
-( exposed subsystems.) s
-5 349 M
-(9.4.2 Proxy forwarding) s
-5 327 M
-( The SSH connection protocol allows for proxy forwarding of other) s
-5 316 M
-( protocols such as SNMP, POP3, and HTTP. This may be a concern for) s
-5 305 M
-( network administrators who wish to control the access of certain) s
-5 294 M
-( applications by users located outside of their physical location.) s
-5 283 M
-( Essentially, the forwarding of these protocols may violate site) s
-5 272 M
-( specific security policies as they may be undetectably tunneled) s
-5 261 M
-( through a firewall. Implementors SHOULD provide an administrative) s
-5 250 M
-( mechanism to control the proxy forwarding functionality so that site) s
-5 239 M
-( specific security policies may be upheld.) s
-5 217 M
-( In addition, a reverse proxy forwarding functionality is available,) s
-5 206 M
-( which again can be used to bypass firewall controls.) s
-5 184 M
-( As indicated above, end-point security is assumed during proxy) s
-5 173 M
-( forwarding operations. Failure of end-point security will compromise) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( all data passed over proxy forwarding.) s
-5 668 M
-(9.4.3 X11 forwarding) s
-5 646 M
-( Another form of proxy forwarding provided by the ssh connection) s
-5 635 M
-( protocol is the forwarding of the X11 protocol. If end-point) s
-5 624 M
-( security has been compromised, X11 forwarding may allow attacks) s
-5 613 M
-( against the X11 server. Users and administrators should, as a matter) s
-5 602 M
-( of course, use appropriate X11 security mechanisms to prevent) s
-5 591 M
-( unauthorized use of the X11 server. Implementors, administrators and) s
-5 580 M
-( users who wish to further explore the security mechanisms of X11 are) s
-5 569 M
-( invited to read [SCHEIFLER] and analyze previously reported problems) s
-5 558 M
-( with the interactions between SSH forwarding and X11 in CERT) s
-5 547 M
-( vulnerabilities VU#363181 and VU#118892 [CERT].) s
-5 525 M
-( X11 display forwarding with SSH, by itself, is not sufficient to) s
-5 514 M
-( correct well known problems with X11 security [VENEMA]. However, X11) s
-5 503 M
-( display forwarding in SSHv2 \(or other, secure protocols\), combined) s
-5 492 M
-( with actual and pseudo-displays which accept connections only over) s
-5 481 M
-( local IPC mechanisms authorized by permissions or ACLs, does correct) s
-5 470 M
-( many X11 security problems as long as the "none" MAC is not used. It) s
-5 459 M
-( is RECOMMENDED that X11 display implementations default to allowing) s
-5 448 M
-( display opens only over local IPC. It is RECOMMENDED that SSHv2) s
-5 437 M
-( server implementations that support X11 forwarding default to) s
-5 426 M
-( allowing display opens only over local IPC. On single-user systems) s
-5 415 M
-( it might be reasonable to default to allowing local display opens) s
-5 404 M
-( over TCP/IP.) s
-5 382 M
-( Implementors of the X11 forwarding protocol SHOULD implement the) s
-5 371 M
-( magic cookie access checking spoofing mechanism as described in) s
-5 360 M
-( [ssh-connect] as an additional mechanism to prevent unauthorized use) s
-5 349 M
-( of the proxy.) s
-5 327 M
-(Normative References) s
-5 305 M
-( [SSH-ARCH]) s
-5 294 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 283 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 261 M
-( [SSH-TRANS]) s
-5 250 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 239 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 217 M
-( [SSH-USERAUTH]) s
-5 206 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 195 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 173 M
-( [SSH-CONNECT]) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 679 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 657 M
-( [SSH-NUMBERS]) s
-5 646 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 635 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 624 M
-( 2003.) s
-5 602 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 591 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 569 M
-(Informative References) s
-5 547 M
-( [FIPS-186]) s
-5 536 M
-( Federal Information Processing Standards Publication,) s
-5 525 M
-( "FIPS PUB 186, Digital Signature Standard", May 1994.) s
-5 503 M
-( [FIPS-197]) s
-5 492 M
-( National Institue of Standards and Technology, "FIPS 197,) s
-5 481 M
-( Specification for the Advanced Encryption Standard",) s
-5 470 M
-( November 2001.) s
-5 448 M
-( [ANSI T1.523-2001]) s
-5 437 M
-( American National Standards Insitute, Inc., "Telecom) s
-5 426 M
-( Glossary 2000", February 2001.) s
-5 404 M
-( [SCHEIFLER]) s
-5 393 M
-( Scheifler, R., "X Window System : The Complete Reference) s
-5 382 M
-( to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital) s
-5 371 M
-( Press ISBN 1555580882, Feburary 1992.) s
-5 349 M
-( [RFC0854] Postel, J. and J. Reynolds, "Telnet Protocol) s
-5 338 M
-( Specification", STD 8, RFC 854, May 1983.) s
-5 316 M
-( [RFC0894] Hornig, C., "Standard for the transmission of IP datagrams) s
-5 305 M
-( over Ethernet networks", STD 41, RFC 894, April 1984.) s
-5 283 M
-( [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",) s
-5 272 M
-( STD 13, RFC 1034, November 1987.) s
-5 250 M
-( [RFC1134] Perkins, D., "Point-to-Point Protocol: A proposal for) s
-5 239 M
-( multi-protocol transmission of datagrams over) s
-5 228 M
-( Point-to-Point links", RFC 1134, November 1989.) s
-5 206 M
-( [RFC1282] Kantor, B., "BSD Rlogin", RFC 1282, December 1991.) s
-5 184 M
-( [RFC1510] Kohl, J. and B. Neuman, "The Kerberos Network) s
-5 173 M
-( Authentication Service \(V5\)", RFC 1510, September 1993.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", RFC 1700,) s
-5 679 M
-( October 1994.) s
-5 657 M
-( [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness) s
-5 646 M
-( Recommendations for Security", RFC 1750, December 1994.) s
-5 624 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 613 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 591 M
-( [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC) s
-5 580 M
-( 1964, June 1996.) s
-5 558 M
-( [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism) s
-5 547 M
-( \(SPKM\)", RFC 2025, October 1996.) s
-5 525 M
-( [RFC2085] Oehler, M. and R. Glenn, "HMAC-MD5 IP Authentication with) s
-5 514 M
-( Replay Prevention", RFC 2085, February 1997.) s
-5 492 M
-( [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:) s
-5 481 M
-( Keyed-Hashing for Message Authentication", RFC 2104,) s
-5 470 M
-( February 1997.) s
-5 448 M
-( [RFC2246] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A.) s
-5 437 M
-( and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246,) s
-5 426 M
-( January 1999.) s
-5 404 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 393 M
-( 10646", RFC 2279, January 1998.) s
-5 371 M
-( [RFC2410] Glenn, R. and S. Kent, "The NULL Encryption Algorithm and) s
-5 360 M
-( Its Use With IPsec", RFC 2410, November 1998.) s
-5 338 M
-( [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an) s
-5 327 M
-( IANA Considerations Section in RFCs", BCP 26, RFC 2434,) s
-5 316 M
-( October 1998.) s
-5 294 M
-( [RFC2743] Linn, J., "Generic Security Service Application Program) s
-5 283 M
-( Interface Version 2, Update 1", RFC 2743, January 2000.) s
-5 261 M
-( [SCHNEIER]) s
-5 250 M
-( Schneier, B., "Applied Cryptography Second Edition:) s
-5 239 M
-( protocols algorithms and source in code in C", 1996.) s
-5 217 M
-( [KAUFMAN,PERLMAN,SPECINER]) s
-5 206 M
-( Kaufman, C., Perlman, R. and M. Speciner, "Network) s
-5 195 M
-( Security: PRIVATE Communication in a PUBLIC World", 1995.) s
-5 173 M
-( [CERT] CERT Coordination Center, The., "http://www.cert.org/nav/) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( index_red.html".) s
-5 668 M
-( [VENEMA] Venema, W., "Murphy's Law and Computer Security",) s
-5 657 M
-( Proceedings of 6th USENIX Security Symposium, San Jose CA) s
-5 646 M
-( http://www.usenix.org/publications/library/proceedings/) s
-5 635 M
-( sec96/venema.html, July 1996.) s
-5 613 M
-( [ROGAWAY] Rogaway, P., "Problems with Proposed IP Cryptography",) s
-5 602 M
-( Unpublished paper http://www.cs.ucdavis.edu/~rogaway/) s
-5 591 M
-( papers/draft-rogaway-ipsec-comments-00.txt, 1996.) s
-5 569 M
-( [DAI] Dai, W., "An attack against SSH2 protocol", Email to the) s
-5 558 M
-( SECSH Working Group [email protected] ftp://) s
-5 547 M
-( ftp.ietf.org/ietf-mail-archive/secsh/2002-02.mail, Feb) s
-5 536 M
-( 2002.) s
-5 514 M
-( [BELLARE,KOHNO,NAMPREMPRE]) s
-5 503 M
-( Bellaire, M., Kohno, T. and C. Namprempre, "Authenticated) s
-5 492 M
-( Encryption in SSH: Fixing the SSH Binary Packet Protocol",) s
-5 481 M
-( , Sept 2002.) s
-5 448 M
-(Authors' Addresses) s
-5 426 M
-( Tatu Ylonen) s
-5 415 M
-( SSH Communications Security Corp) s
-5 404 M
-( Fredrikinkatu 42) s
-5 393 M
-( HELSINKI FIN-00100) s
-5 382 M
-( Finland) s
-5 360 M
-( EMail: [email protected]) s
-5 327 M
-( Darren J. Moffat \(editor\)) s
-5 316 M
-( Sun Microsystems, Inc) s
-5 305 M
-( 17 Network Circle) s
-5 294 M
-( Menlo Park CA 94025) s
-5 283 M
-( USA) s
-5 261 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-showpage
-PStoPSsaved restore
-%%Trailer
-%%Pages: 29
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt b/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt
deleted file mode 100644
index 18070e8485..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt
+++ /dev/null
@@ -1,1624 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Protocol Architecture
- draft-ietf-secsh-architecture-15.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. This document describes the
- architecture of the SSH protocol, as well as the notation and
- terminology used in SSH protocol documents. It also discusses the SSH
- algorithm naming system that allows local extensions. The SSH
- protocol consists of three major components: The Transport Layer
- Protocol provides server authentication, confidentiality, and
- integrity with perfect forward secrecy. The User Authentication
- Protocol authenticates the client to the server. The Connection
- Protocol multiplexes the encrypted tunnel into several logical
- channels. Details of these protocols are described in separate
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- documents.
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Specification of Requirements . . . . . . . . . . . . . . . 3
- 4. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 3
- 4.1 Host Keys . . . . . . . . . . . . . . . . . . . . . . . . . 4
- 4.2 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 5
- 4.3 Policy Issues . . . . . . . . . . . . . . . . . . . . . . . 5
- 4.4 Security Properties . . . . . . . . . . . . . . . . . . . . 6
- 4.5 Packet Size and Overhead . . . . . . . . . . . . . . . . . . 6
- 4.6 Localization and Character Set Support . . . . . . . . . . . 7
- 5. Data Type Representations Used in the SSH Protocols . . . . 8
- 6. Algorithm Naming . . . . . . . . . . . . . . . . . . . . . . 10
- 7. Message Numbers . . . . . . . . . . . . . . . . . . . . . . 11
- 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . 11
- 9. Security Considerations . . . . . . . . . . . . . . . . . . 12
- 9.1 Pseudo-Random Number Generation . . . . . . . . . . . . . . 12
- 9.2 Transport . . . . . . . . . . . . . . . . . . . . . . . . . 13
- 9.2.1 Confidentiality . . . . . . . . . . . . . . . . . . . . . . 13
- 9.2.2 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 16
- 9.2.3 Replay . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
- 9.2.4 Man-in-the-middle . . . . . . . . . . . . . . . . . . . . . 17
- 9.2.5 Denial-of-service . . . . . . . . . . . . . . . . . . . . . 19
- 9.2.6 Covert Channels . . . . . . . . . . . . . . . . . . . . . . 19
- 9.2.7 Forward Secrecy . . . . . . . . . . . . . . . . . . . . . . 20
- 9.3 Authentication Protocol . . . . . . . . . . . . . . . . . . 20
- 9.3.1 Weak Transport . . . . . . . . . . . . . . . . . . . . . . . 21
- 9.3.2 Debug messages . . . . . . . . . . . . . . . . . . . . . . . 21
- 9.3.3 Local security policy . . . . . . . . . . . . . . . . . . . 21
- 9.3.4 Public key authentication . . . . . . . . . . . . . . . . . 22
- 9.3.5 Password authentication . . . . . . . . . . . . . . . . . . 22
- 9.3.6 Host based authentication . . . . . . . . . . . . . . . . . 23
- 9.4 Connection protocol . . . . . . . . . . . . . . . . . . . . 23
- 9.4.1 End point security . . . . . . . . . . . . . . . . . . . . . 23
- 9.4.2 Proxy forwarding . . . . . . . . . . . . . . . . . . . . . . 23
- 9.4.3 X11 forwarding . . . . . . . . . . . . . . . . . . . . . . . 24
- Normative References . . . . . . . . . . . . . . . . . . . . 24
- Informative References . . . . . . . . . . . . . . . . . . . 25
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 27
- Intellectual Property and Copyright Statements . . . . . . . 28
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. It consists of three major
- components:
- o The Transport Layer Protocol [SSH-TRANS] provides server
- authentication, confidentiality, and integrity. It may optionally
- also provide compression. The transport layer will typically be
- run over a TCP/IP connection, but might also be used on top of any
- other reliable data stream.
- o The User Authentication Protocol [SSH-USERAUTH] authenticates the
- client-side user to the server. It runs over the transport layer
- protocol.
- o The Connection Protocol [SSH-CONNECT] multiplexes the encrypted
- tunnel into several logical channels. It runs over the user
- authentication protocol.
-
- The client sends a service request once a secure transport layer
- connection has been established. A second service request is sent
- after user authentication is complete. This allows new protocols to
- be defined and coexist with the protocols listed above.
-
- The connection protocol provides channels that can be used for a wide
- range of purposes. Standard methods are provided for setting up
- secure interactive shell sessions and for forwarding ("tunneling")
- arbitrary TCP/IP ports and X11 connections.
-
-3. Specification of Requirements
-
- All documents related to the SSH protocols shall use the keywords
- "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
- "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" to describe
- requirements. They are to be interpreted as described in [RFC2119].
-
-4. Architecture
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-4.1 Host Keys
-
- Each server host SHOULD have a host key. Hosts MAY have multiple
- host keys using multiple different algorithms. Multiple hosts MAY
- share the same host key. If a host has keys at all, it MUST have at
- least one key using each REQUIRED public key algorithm (DSS
- [FIPS-186]).
-
- The server host key is used during key exchange to verify that the
- client is really talking to the correct server. For this to be
- possible, the client must have a priori knowledge of the server's
- public host key.
-
- Two different trust models can be used:
- o The client has a local database that associates each host name (as
- typed by the user) with the corresponding public host key. This
- method requires no centrally administered infrastructure, and no
- third-party coordination. The downside is that the database of
- name-to-key associations may become burdensome to maintain.
- o The host name-to-key association is certified by some trusted
- certification authority. The client only knows the CA root key,
- and can verify the validity of all host keys certified by accepted
- CAs.
-
- The second alternative eases the maintenance problem, since
- ideally only a single CA key needs to be securely stored on the
- client. On the other hand, each host key must be appropriately
- certified by a central authority before authorization is possible.
- Also, a lot of trust is placed on the central infrastructure.
-
- The protocol provides the option that the server name - host key
- association is not checked when connecting to the host for the first
- time. This allows communication without prior communication of host
- keys or certification. The connection still provides protection
- against passive listening; however, it becomes vulnerable to active
- man-in-the-middle attacks. Implementations SHOULD NOT normally allow
- such connections by default, as they pose a potential security
- problem. However, as there is no widely deployed key infrastructure
- available on the Internet yet, this option makes the protocol much
- more usable during the transition time until such an infrastructure
- emerges, while still providing a much higher level of security than
- that offered by older solutions (e.g. telnet [RFC-854] and rlogin
- [RFC-1282]).
-
- Implementations SHOULD try to make the best effort to check host
- keys. An example of a possible strategy is to only accept a host key
- without checking the first time a host is connected, save the key in
- a local database, and compare against that key on all future
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- connections to that host.
-
- Implementations MAY provide additional methods for verifying the
- correctness of host keys, e.g. a hexadecimal fingerprint derived from
- the SHA-1 hash of the public key. Such fingerprints can easily be
- verified by using telephone or other external communication channels.
-
- All implementations SHOULD provide an option to not accept host keys
- that cannot be verified.
-
- We believe that ease of use is critical to end-user acceptance of
- security solutions, and no improvement in security is gained if the
- new solutions are not used. Thus, providing the option not to check
- the server host key is believed to improve the overall security of
- the Internet, even though it reduces the security of the protocol in
- configurations where it is allowed.
-
-4.2 Extensibility
-
- We believe that the protocol will evolve over time, and some
- organizations will want to use their own encryption, authentication
- and/or key exchange methods. Central registration of all extensions
- is cumbersome, especially for experimental or classified features.
- On the other hand, having no central registration leads to conflicts
- in method identifiers, making interoperability difficult.
-
- We have chosen to identify algorithms, methods, formats, and
- extension protocols with textual names that are of a specific format.
- DNS names are used to create local namespaces where experimental or
- classified extensions can be defined without fear of conflicts with
- other implementations.
-
- One design goal has been to keep the base protocol as simple as
- possible, and to require as few algorithms as possible. However, all
- implementations MUST support a minimal set of algorithms to ensure
- interoperability (this does not imply that the local policy on all
- hosts would necessary allow these algorithms). The mandatory
- algorithms are specified in the relevant protocol documents.
-
- Additional algorithms, methods, formats, and extension protocols can
- be defined in separate drafts. See Section Algorithm Naming (Section
- 6) for more information.
-
-4.3 Policy Issues
-
- The protocol allows full negotiation of encryption, integrity, key
- exchange, compression, and public key algorithms and formats.
- Encryption, integrity, public key, and compression algorithms can be
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- different for each direction.
-
- The following policy issues SHOULD be addressed in the configuration
- mechanisms of each implementation:
- o Encryption, integrity, and compression algorithms, separately for
- each direction. The policy MUST specify which is the preferred
- algorithm (e.g. the first algorithm listed in each category).
- o Public key algorithms and key exchange method to be used for host
- authentication. The existence of trusted host keys for different
- public key algorithms also affects this choice.
- o The authentication methods that are to be required by the server
- for each user. The server's policy MAY require multiple
- authentication for some or all users. The required algorithms MAY
- depend on the location where the user is trying to log in from.
- o The operations that the user is allowed to perform using the
- connection protocol. Some issues are related to security; for
- example, the policy SHOULD NOT allow the server to start sessions
- or run commands on the client machine, and MUST NOT allow
- connections to the authentication agent unless forwarding such
- connections has been requested. Other issues, such as which TCP/
- IP ports can be forwarded and by whom, are clearly issues of local
- policy. Many of these issues may involve traversing or bypassing
- firewalls, and are interrelated with the local security policy.
-
-4.4 Security Properties
-
- The primary goal of the SSH protocol is improved security on the
- Internet. It attempts to do this in a way that is easy to deploy,
- even at the cost of absolute security.
- o All encryption, integrity, and public key algorithms used are
- well-known, well-established algorithms.
- o All algorithms are used with cryptographically sound key sizes
- that are believed to provide protection against even the strongest
- cryptanalytic attacks for decades.
- o All algorithms are negotiated, and in case some algorithm is
- broken, it is easy to switch to some other algorithm without
- modifying the base protocol.
-
- Specific concessions were made to make wide-spread fast deployment
- easier. The particular case where this comes up is verifying that
- the server host key really belongs to the desired host; the protocol
- allows the verification to be left out (but this is NOT RECOMMENDED).
- This is believed to significantly improve usability in the short
- term, until widespread Internet public key infrastructures emerge.
-
-4.5 Packet Size and Overhead
-
- Some readers will worry about the increase in packet size due to new
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- headers, padding, and MAC. The minimum packet size is in the order
- of 28 bytes (depending on negotiated algorithms). The increase is
- negligible for large packets, but very significant for one-byte
- packets (telnet-type sessions). There are, however, several factors
- that make this a non-issue in almost all cases:
- o The minimum size of a TCP/IP header is 32 bytes. Thus, the
- increase is actually from 33 to 51 bytes (roughly).
- o The minimum size of the data field of an Ethernet packet is 46
- bytes [RFC-894]. Thus, the increase is no more than 5 bytes. When
- Ethernet headers are considered, the increase is less than 10
- percent.
- o The total fraction of telnet-type data in the Internet is
- negligible, even with increased packet sizes.
-
- The only environment where the packet size increase is likely to have
- a significant effect is PPP [RFC-1134] over slow modem lines (PPP
- compresses the TCP/IP headers, emphasizing the increase in packet
- size). However, with modern modems, the time needed to transfer is in
- the order of 2 milliseconds, which is a lot faster than people can
- type.
-
- There are also issues related to the maximum packet size. To
- minimize delays in screen updates, one does not want excessively
- large packets for interactive sessions. The maximum packet size is
- negotiated separately for each channel.
-
-4.6 Localization and Character Set Support
-
- For the most part, the SSH protocols do not directly pass text that
- would be displayed to the user. However, there are some places where
- such data might be passed. When applicable, the character set for the
- data MUST be explicitly specified. In most places, ISO 10646 with
- UTF-8 encoding is used [RFC-2279]. When applicable, a field is also
- provided for a language tag [RFC-3066].
-
- One big issue is the character set of the interactive session. There
- is no clear solution, as different applications may display data in
- different formats. Different types of terminal emulation may also be
- employed in the client, and the character set to be used is
- effectively determined by the terminal emulation. Thus, no place is
- provided for directly specifying the character set or encoding for
- terminal session data. However, the terminal emulation type (e.g.
- "vt100") is transmitted to the remote site, and it implicitly
- specifies the character set and encoding. Applications typically use
- the terminal type to determine what character set they use, or the
- character set is determined using some external means. The terminal
- emulation may also allow configuring the default character set. In
- any case, the character set for the terminal session is considered
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- primarily a client local issue.
-
- Internal names used to identify algorithms or protocols are normally
- never displayed to users, and must be in US-ASCII.
-
- The client and server user names are inherently constrained by what
- the server is prepared to accept. They might, however, occasionally
- be displayed in logs, reports, etc. They MUST be encoded using ISO
- 10646 UTF-8, but other encodings may be required in some cases. It
- is up to the server to decide how to map user names to accepted user
- names. Straight bit-wise binary comparison is RECOMMENDED.
-
- For localization purposes, the protocol attempts to minimize the
- number of textual messages transmitted. When present, such messages
- typically relate to errors, debugging information, or some externally
- configured data. For data that is normally displayed, it SHOULD be
- possible to fetch a localized message instead of the transmitted
- message by using a numerical code. The remaining messages SHOULD be
- configurable.
-
-5. Data Type Representations Used in the SSH Protocols
- byte
-
- A byte represents an arbitrary 8-bit value (octet) [RFC-1700].
- Fixed length data is sometimes represented as an array of bytes,
- written byte[n], where n is the number of bytes in the array.
-
- boolean
-
- A boolean value is stored as a single byte. The value 0
- represents FALSE, and the value 1 represents TRUE. All non-zero
- values MUST be interpreted as TRUE; however, applications MUST NOT
- store values other than 0 and 1.
-
- uint32
-
- Represents a 32-bit unsigned integer. Stored as four bytes in the
- order of decreasing significance (network byte order). For
- example, the value 699921578 (0x29b7f4aa) is stored as 29 b7 f4
- aa.
-
- uint64
-
- Represents a 64-bit unsigned integer. Stored as eight bytes in
- the order of decreasing significance (network byte order).
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- string
-
- Arbitrary length binary string. Strings are allowed to contain
- arbitrary binary data, including null characters and 8-bit
- characters. They are stored as a uint32 containing its length
- (number of bytes that follow) and zero (= empty string) or more
- bytes that are the value of the string. Terminating null
- characters are not used.
-
- Strings are also used to store text. In that case, US-ASCII is
- used for internal names, and ISO-10646 UTF-8 for text that might
- be displayed to the user. The terminating null character SHOULD
- NOT normally be stored in the string.
-
- For example, the US-ASCII string "testing" is represented as 00 00
- 00 07 t e s t i n g. The UTF8 mapping does not alter the encoding
- of US-ASCII characters.
-
- mpint
-
- Represents multiple precision integers in two's complement format,
- stored as a string, 8 bits per byte, MSB first. Negative numbers
- have the value 1 as the most significant bit of the first byte of
- the data partition. If the most significant bit would be set for a
- positive number, the number MUST be preceded by a zero byte.
- Unnecessary leading bytes with the value 0 or 255 MUST NOT be
- included. The value zero MUST be stored as a string with zero
- bytes of data.
-
- By convention, a number that is used in modular computations in
- Z_n SHOULD be represented in the range 0 <= x < n.
-
- Examples:
- value (hex) representation (hex)
- ---------------------------------------------------------------
- 0 00 00 00 00
- 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7
- 80 00 00 00 02 00 80
- -1234 00 00 00 02 ed cc
- -deadbeef 00 00 00 05 ff 21 52 41 11
-
-
-
- name-list
-
- A string containing a comma separated list of names. A name list
- is represented as a uint32 containing its length (number of bytes
- that follow) followed by a comma-separated list of zero or more
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- names. A name MUST be non-zero length, and it MUST NOT contain a
- comma (','). Context may impose additional restrictions on the
- names; for example, the names in a list may have to be valid
- algorithm identifier (see Algorithm Naming below), or [RFC-3066]
- language tags. The order of the names in a list may or may not be
- significant, also depending on the context where the list is is
- used. Terminating NUL characters are not used, neither for the
- individual names, nor for the list as a whole.
-
- Examples:
- value representation (hex)
- ---------------------------------------
- (), the empty list 00 00 00 00
- ("zlib") 00 00 00 04 7a 6c 69 62
- ("zlib", "none") 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65
-
-
-
-
-6. Algorithm Naming
-
- The SSH protocols refer to particular hash, encryption, integrity,
- compression, and key exchange algorithms or protocols by names.
- There are some standard algorithms that all implementations MUST
- support. There are also algorithms that are defined in the protocol
- specification but are OPTIONAL. Furthermore, it is expected that
- some organizations will want to use their own algorithms.
-
- In this protocol, all algorithm identifiers MUST be printable
- US-ASCII non-empty strings no longer than 64 characters. Names MUST
- be case-sensitive.
-
- There are two formats for algorithm names:
- o Names that do not contain an at-sign (@) are reserved to be
- assigned by IETF consensus (RFCs). Examples include `3des-cbc',
- `sha-1', `hmac-sha1', and `zlib' (the quotes are not part of the
- name). Names of this format MUST NOT be used without first
- registering them. Registered names MUST NOT contain an at-sign
- (@) or a comma (,).
- o Anyone can define additional algorithms by using names in the
- format name@domainname, e.g. "[email protected]". The
- format of the part preceding the at sign is not specified; it MUST
- consist of US-ASCII characters except at-sign and comma. The part
- following the at-sign MUST be a valid fully qualified internet
- domain name [RFC-1034] controlled by the person or organization
- defining the name. It is up to each domain how it manages its
- local namespace.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-7. Message Numbers
-
- SSH packets have message numbers in the range 1 to 255. These numbers
- have been allocated as follows:
-
-
- Transport layer protocol:
-
- 1 to 19 Transport layer generic (e.g. disconnect, ignore, debug,
- etc.)
- 20 to 29 Algorithm negotiation
- 30 to 49 Key exchange method specific (numbers can be reused for
- different authentication methods)
-
- User authentication protocol:
-
- 50 to 59 User authentication generic
- 60 to 79 User authentication method specific (numbers can be
- reused for different authentication methods)
-
- Connection protocol:
-
- 80 to 89 Connection protocol generic
- 90 to 127 Channel related messages
-
- Reserved for client protocols:
-
- 128 to 191 Reserved
-
- Local extensions:
-
- 192 to 255 Local extensions
-
-
-
-8. IANA Considerations
-
- The initial state of the IANA registry is detailed in [SSH-NUMBERS].
-
- Allocation of the following types of names in the SSH protocols is
- assigned by IETF consensus:
- o SSH encryption algorithm names,
- o SSH MAC algorithm names,
- o SSH public key algorithm names (public key algorithm also implies
- encoding and signature/encryption capability),
- o SSH key exchange method names, and
- o SSH protocol (service) names.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- These names MUST be printable US-ASCII strings, and MUST NOT contain
- the characters at-sign ('@'), comma (','), or whitespace or control
- characters (ASCII codes 32 or less). Names are case-sensitive, and
- MUST NOT be longer than 64 characters.
-
- Names with the at-sign ('@') in them are allocated by the owner of
- DNS name after the at-sign (hierarchical allocation in [RFC-2343]),
- otherwise the same restrictions as above.
-
- Each category of names listed above has a separate namespace.
- However, using the same name in multiple categories SHOULD be avoided
- to minimize confusion.
-
- Message numbers (see Section Message Numbers (Section 7)) in the
- range of 0..191 are allocated via IETF consensus; message numbers in
- the 192..255 range (the "Local extensions" set) are reserved for
- private use.
-
-9. Security Considerations
-
- In order to make the entire body of Security Considerations more
- accessible, Security Considerations for the transport,
- authentication, and connection documents have been gathered here.
-
- The transport protocol [1] provides a confidential channel over an
- insecure network. It performs server host authentication, key
- exchange, encryption, and integrity protection. It also derives a
- unique session id that may be used by higher-level protocols.
-
- The authentication protocol [2] provides a suite of mechanisms which
- can be used to authenticate the client user to the server.
- Individual mechanisms specified in the in authentication protocol use
- the session id provided by the transport protocol and/or depend on
- the security and integrity guarantees of the transport protocol.
-
- The connection protocol [3] specifies a mechanism to multiplex
- multiple streams [channels] of data over the confidential and
- authenticated transport. It also specifies channels for accessing an
- interactive shell, for 'proxy-forwarding' various external protocols
- over the secure transport (including arbitrary TCP/IP protocols), and
- for accessing secure 'subsystems' on the server host.
-
-9.1 Pseudo-Random Number Generation
-
- This protocol binds each session key to the session by including
- random, session specific data in the hash used to produce session
- keys. Special care should be taken to ensure that all of the random
- numbers are of good quality. If the random data here (e.g., DH
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- parameters) are pseudo-random then the pseudo-random number generator
- should be cryptographically secure (i.e., its next output not easily
- guessed even when knowing all previous outputs) and, furthermore,
- proper entropy needs to be added to the pseudo-random number
- generator. RFC 1750 [1750] offers suggestions for sources of random
- numbers and entropy. Implementors should note the importance of
- entropy and the well-meant, anecdotal warning about the difficulty in
- properly implementing pseudo-random number generating functions.
-
- The amount of entropy available to a given client or server may
- sometimes be less than what is required. In this case one must
- either resort to pseudo-random number generation regardless of
- insufficient entropy or refuse to run the protocol. The latter is
- preferable.
-
-9.2 Transport
-
-9.2.1 Confidentiality
-
- It is beyond the scope of this document and the Secure Shell Working
- Group to analyze or recommend specific ciphers other than the ones
- which have been established and accepted within the industry. At the
- time of this writing, ciphers commonly in use include 3DES, ARCFOUR,
- twofish, serpent and blowfish. AES has been accepted by The
- published as a US Federal Information Processing Standards [FIPS-197]
- and the cryptographic community as being acceptable for this purpose
- as well has accepted AES. As always, implementors and users should
- check current literature to ensure that no recent vulnerabilities
- have been found in ciphers used within products. Implementors should
- also check to see which ciphers are considered to be relatively
- stronger than others and should recommend their use to users over
- relatively weaker ciphers. It would be considered good form for an
- implementation to politely and unobtrusively notify a user that a
- stronger cipher is available and should be used when a weaker one is
- actively chosen.
-
- The "none" cipher is provided for debugging and SHOULD NOT be used
- except for that purpose. It's cryptographic properties are
- sufficiently described in RFC 2410, which will show that its use does
- not meet the intent of this protocol.
-
- The relative merits of these and other ciphers may also be found in
- current literature. Two references that may provide information on
- the subject are [SCHNEIER] and [KAUFMAN,PERLMAN,SPECINER]. Both of
- these describe the CBC mode of operation of certain ciphers and the
- weakness of this scheme. Essentially, this mode is theoretically
- vulnerable to chosen cipher-text attacks because of the high
- predictability of the start of packet sequence. However, this attack
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- is still deemed difficult and not considered fully practicable
- especially if relatively longer block sizes are used.
-
- Additionally, another CBC mode attack may be mitigated through the
- insertion of packets containing SSH_MSG_IGNORE. Without this
- technique, a specific attack may be successful. For this attack
- (commonly known as the Rogaway attack
- [ROGAWAY],[DAI],[BELLARE,KOHNO,NAMPREMPRE]) to work, the attacker
- would need to know the IV of the next block that is going to be
- encrypted. In CBC mode that is the output of the encryption of the
- previous block. If the attacker does not have any way to see the
- packet yet (i.e it is in the internal buffers of the ssh
- implementation or even in the kernel) then this attack will not work.
- If the last packet has been sent out to the network (i.e the attacker
- has access to it) then he can use the attack.
-
- In the optimal case an implementor would need to add an extra packet
- only if the packet has been sent out onto the network and there are
- no other packets waiting for transmission. Implementors may wish to
- check to see if there are any unsent packets awaiting transmission,
- but unfortunately it is not normally easy to obtain this information
- from the kernel or buffers. If there are not, then a packet
- containing SSH_MSG_IGNORE SHOULD be sent. If a new packet is added
- to the stream every time the attacker knows the IV that is supposed
- to be used for the next packet, then the attacker will not be able to
- guess the correct IV, thus the attack will never be successfull.
-
- As an example, consider the following case:
-
-
- Client Server
- ------ ------
- TCP(seq=x, len=500) ->
- contains Record 1
-
- [500 ms passes, no ACK]
-
- TCP(seq=x, len=1000) ->
- contains Records 1,2
-
- ACK
-
-
- 1. The Nagle algorithm + TCP retransmits mean that the two records
- get coalesced into a single TCP segment
- 2. Record 2 is *not* at the beginning of the TCP segment and never
- will be, since it gets ACKed.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- 3. Yet, the attack is possible because Record 1 has already been
- seen.
-
- As this example indicates, it's totally unsafe to use the existence
- of unflushed data in the TCP buffers proper as a guide to whether you
- need an empty packet, since when you do the second write(), the
- buffers will contain the un-ACKed Record 1.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- On the other hand, it's perfectly safe to have the following
- situation:
-
-
- Client Server
- ------ ------
- TCP(seq=x, len=500) ->
- contains SSH_MSG_IGNORE
-
- TCP(seq=y, len=500) ->
- contains Data
-
- Provided that the IV for second SSH Record is fixed after the data for
- the Data packet is determined -i.e. you do:
- read from user
- encrypt null packet
- encrypt data packet
-
-
-9.2.2 Data Integrity
-
- This protocol does allow the Data Integrity mechanism to be disabled.
- Implementors SHOULD be wary of exposing this feature for any purpose
- other than debugging. Users and administrators SHOULD be explicitly
- warned anytime the "none" MAC is enabled.
-
- So long as the "none" MAC is not used, this protocol provides data
- integrity.
-
- Because MACs use a 32 bit sequence number, they might start to leak
- information after 2**32 packets have been sent. However, following
- the rekeying recommendations should prevent this attack. The
- transport protocol [1] recommends rekeying after one gigabyte of
- data, and the smallest possible packet is 16 bytes. Therefore,
- rekeying SHOULD happen after 2**28 packets at the very most.
-
-9.2.3 Replay
-
- The use of a MAC other than 'none' provides integrity and
- authentication. In addition, the transport protocol provides a
- unique session identifier (bound in part to pseudo-random data that
- is part of the algorithm and key exchange process) that can be used
- by higher level protocols to bind data to a given session and prevent
- replay of data from prior sessions. For example, the authentication
- protocol uses this to prevent replay of signatures from previous
- sessions. Because public key authentication exchanges are
- cryptographically bound to the session (i.e., to the initial key
- exchange) they cannot be successfully replayed in other sessions.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- Note that the session ID can be made public without harming the
- security of the protocol.
-
- If two session happen to have the same session ID [hash of key
- exchanges] then packets from one can be replayed against the other.
- It must be stressed that the chances of such an occurrence are,
- needless to say, minimal when using modern cryptographic methods.
- This is all the more so true when specifying larger hash function
- outputs and DH parameters.
-
- Replay detection using monotonically increasing sequence numbers as
- input to the MAC, or HMAC in some cases, is described in [RFC2085] />
- [RFC2246], [RFC2743], [RFC1964], [RFC2025], and [RFC1510]. The
- underlying construct is discussed in [RFC2104]. Essentially a
- different sequence number in each packet ensures that at least this
- one input to the MAC function will be unique and will provide a
- nonrecurring MAC output that is not predictable to an attacker. If
- the session stays active long enough, however, this sequence number
- will wrap. This event may provide an attacker an opportunity to
- replay a previously recorded packet with an identical sequence number
- but only if the peers have not rekeyed since the transmission of the
- first packet with that sequence number. If the peers have rekeyed,
- then the replay will be detected as the MAC check will fail. For
- this reason, it must be emphasized that peers MUST rekey before a
- wrap of the sequence numbers. Naturally, if an attacker does attempt
- to replay a captured packet before the peers have rekeyed, then the
- receiver of the duplicate packet will not be able to validate the MAC
- and it will be discarded. The reason that the MAC will fail is
- because the receiver will formulate a MAC based upon the packet
- contents, the shared secret, and the expected sequence number. Since
- the replayed packet will not be using that expected sequence number
- (the sequence number of the replayed packet will have already been
- passed by the receiver) then the calculated MAC will not match the
- MAC received with the packet.
-
-9.2.4 Man-in-the-middle
-
- This protocol makes no assumptions nor provisions for an
- infrastructure or means for distributing the public keys of hosts. It
- is expected that this protocol will sometimes be used without first
- verifying the association between the server host key and the server
- host name. Such usage is vulnerable to man-in-the-middle attacks.
- This section describes this and encourages administrators and users
- to understand the importance of verifying this association before any
- session is initiated.
-
- There are three cases of man-in-the-middle attacks to consider. The
- first is where an attacker places a device between the client and the
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- server before the session is initiated. In this case, the attack
- device is trying to mimic the legitimate server and will offer its
- public key to the client when the client initiates a session. If it
- were to offer the public key of the server, then it would not be able
- to decrypt or sign the transmissions between the legitimate server
- and the client unless it also had access to the private-key of the
- host. The attack device will also, simultaneously to this, initiate
- a session to the legitimate server masquerading itself as the client.
- If the public key of the server had been securely distributed to the
- client prior to that session initiation, the key offered to the
- client by the attack device will not match the key stored on the
- client. In that case, the user SHOULD be given a warning that the
- offered host key does not match the host key cached on the client.
- As described in Section 3.1 of [ARCH], the user may be free to accept
- the new key and continue the session. It is RECOMMENDED that the
- warning provide sufficient information to the user of the client
- device so they may make an informed decision. If the user chooses to
- continue the session with the stored public-key of the server (not
- the public-key offered at the start of the session), then the session
- specific data between the attacker and server will be different
- between the client-to-attacker session and the attacker-to-server
- sessions due to the randomness discussed above. From this, the
- attacker will not be able to make this attack work since the attacker
- will not be able to correctly sign packets containing this session
- specific data from the server since he does not have the private key
- of that server.
-
- The second case that should be considered is similar to the first
- case in that it also happens at the time of connection but this case
- points out the need for the secure distribution of server public
- keys. If the server public keys are not securely distributed then
- the client cannot know if it is talking to the intended server. An
- attacker may use social engineering techniques to pass off server
- keys to unsuspecting users and may then place a man-in-the-middle
- attack device between the legitimate server and the clients. If this
- is allowed to happen then the clients will form client-to-attacker
- sessions and the attacker will form attacker-to-server sessions and
- will be able to monitor and manipulate all of the traffic between the
- clients and the legitimate servers. Server administrators are
- encouraged to make host key fingerprints available for checking by
- some means whose security does not rely on the integrity of the
- actual host keys. Possible mechanisms are discussed in Section 3.1
- of [SSH-ARCH] and may also include secured Web pages, physical pieces
- of paper, etc. Implementors SHOULD provide recommendations on how
- best to do this with their implementation. Because the protocol is
- extensible, future extensions to the protocol may provide better
- mechanisms for dealing with the need to know the server's host key
- before connecting. For example, making the host key fingerprint
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- available through a secure DNS lookup, or using kerberos over gssapi
- during key exchange to authenticate the server are possibilities.
-
- In the third man-in-the-middle case, attackers may attempt to
- manipulate packets in transit between peers after the session has
- been established. As described in the Replay part of this section, a
- successful attack of this nature is very improbable. As in the
- Replay section, this reasoning does assume that the MAC is secure and
- that it is infeasible to construct inputs to a MAC algorithm to give
- a known output. This is discussed in much greater detail in Section
- 6 of RFC 2104. If the MAC algorithm has a vulnerability or is weak
- enough, then the attacker may be able to specify certain inputs to
- yield a known MAC. With that they may be able to alter the contents
- of a packet in transit. Alternatively the attacker may be able to
- exploit the algorithm vulnerability or weakness to find the shared
- secret by reviewing the MACs from captured packets. In either of
- those cases, an attacker could construct a packet or packets that
- could be inserted into an SSH stream. To prevent that, implementors
- are encouraged to utilize commonly accepted MAC algorithms and
- administrators are encouraged to watch current literature and
- discussions of cryptography to ensure that they are not using a MAC
- algorithm that has a recently found vulnerability or weakness.
-
- In summary, the use of this protocol without a reliable association
- of the binding between a host and its host keys is inherently
- insecure and is NOT RECOMMENDED. It may however be necessary in
- non-security critical environments, and will still provide protection
- against passive attacks. Implementors of protocols and applications
- running on top of this protocol should keep this possibility in mind.
-
-9.2.5 Denial-of-service
-
- This protocol is designed to be used over a reliable transport. If
- transmission errors or message manipulation occur, the connection is
- closed. The connection SHOULD be re-established if this occurs.
- Denial of service attacks of this type ("wire cutter") are almost
- impossible to avoid.
-
- In addition, this protocol is vulnerable to Denial of Service attacks
- because an attacker can force the server to go through the CPU and
- memory intensive tasks of connection setup and key exchange without
- authenticating. Implementors SHOULD provide features that make this
- more difficult. For example, only allowing connections from a subset
- of IPs known to have valid users.
-
-9.2.6 Covert Channels
-
- The protocol was not designed to eliminate covert channels. For
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- example, the padding, SSH_MSG_IGNORE messages, and several other
- places in the protocol can be used to pass covert information, and
- the recipient has no reliable way to verify whether such information
- is being sent.
-
-9.2.7 Forward Secrecy
-
- It should be noted that the Diffie-Hellman key exchanges may provide
- perfect forward secrecy (PFS). PFS is essentially defined as the
- cryptographic property of a key-establishment protocol in which the
- compromise of a session key or long-term private key after a given
- session does not cause the compromise of any earlier session. [ANSI
- T1.523-2001] SSHv2 sessions resulting from a key exchange using
- diffie-hellman-group1-sha1 are secure even if private keying/
- authentication material is later revealed, but not if the session
- keys are revealed. So, given this definition of PFS, SSHv2 does have
- PFS. It is hoped that all other key exchange mechanisms proposed and
- used in the future will also provide PFS. This property is not
- commuted to any of the applications or protocols using SSH as a
- transport however. The transport layer of SSH provides
- confidentiality for password authentication and other methods that
- rely on secret data.
-
- Of course, if the DH private parameters for the client and server are
- revealed then the session key is revealed, but these items can be
- thrown away after the key exchange completes. It's worth pointing
- out that these items should not be allowed to end up on swap space
- and that they should be erased from memory as soon as the key
- exchange completes.
-
-9.3 Authentication Protocol
-
- The purpose of this protocol is to perform client user
- authentication. It assumes that this run over a secure transport
- layer protocol, which has already authenticated the server machine,
- established an encrypted communications channel, and computed a
- unique session identifier for this session.
-
- Several authentication methods with different security
- characteristics are allowed. It is up to the server's local policy
- to decide which methods (or combinations of methods) it is willing to
- accept for each user. Authentication is no stronger than the weakest
- combination allowed.
-
- The server may go into a "sleep" period after repeated unsuccessful
- authentication attempts to make key search more difficult for
- attackers. Care should be taken so that this doesn't become a
- self-denial of service vector.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-9.3.1 Weak Transport
-
- If the transport layer does not provide confidentiality,
- authentication methods that rely on secret data SHOULD be disabled.
- If it does not provide strong integrity protection, requests to
- change authentication data (e.g. a password change) SHOULD be
- disabled to prevent an attacker from modifying the ciphertext
- without being noticed, or rendering the new authentication data
- unusable (denial of service).
-
- The assumption as stated above that the Authentication Protocol only
- run over a secure transport that has previously authenticated the
- server is very important to note. People deploying SSH are reminded
- of the consequences of man-in-the-middle attacks if the client does
- not have a very strong a priori association of the server with the
- host key of that server. Specifically for the case of the
- Authentication Protocol the client may form a session to a
- man-in-the-middle attack device and divulge user credentials such as
- their username and password. Even in the cases of authentication
- where no user credentials are divulged, an attacker may still gain
- information they shouldn't have by capturing key-strokes in much the
- same way that a honeypot works.
-
-9.3.2 Debug messages
-
- Special care should be taken when designing debug messages. These
- messages may reveal surprising amounts of information about the host
- if not properly designed. Debug messages can be disabled (during
- user authentication phase) if high security is required.
- Administrators of host machines should make all attempts to
- compartmentalize all event notification messages and protect them
- from unwarranted observation. Developers should be aware of the
- sensitive nature of some of the normal event messages and debug
- messages and may want to provide guidance to administrators on ways
- to keep this information away from unauthorized people. Developers
- should consider minimizing the amount of sensitive information
- obtainable by users during the authentication phase in accordance
- with the local policies. For this reason, it is RECOMMENDED that
- debug messages be initially disabled at the time of deployment and
- require an active decision by an administrator to allow them to be
- enabled. It is also RECOMMENDED that a message expressing this
- concern be presented to the administrator of a system when the action
- is taken to enable debugging messages.
-
-9.3.3 Local security policy
-
- Implementer MUST ensure that the credentials provided validate the
- professed user and also MUST ensure that the local policy of the
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- server permits the user the access requested. In particular, because
- of the flexible nature of the SSH connection protocol, it may not be
- possible to determine the local security policy, if any, that should
- apply at the time of authentication because the kind of service being
- requested is not clear at that instant. For example, local policy
- might allow a user to access files on the server, but not start an
- interactive shell. However, during the authentication protocol, it is
- not known whether the user will be accessing files or attempting to
- use an interactive shell, or even both. In any event, where local
- security policy for the server host exists, it MUST be applied and
- enforced correctly.
-
- Implementors are encouraged to provide a default local policy and
- make its parameters known to administrators and users. At the
- discretion of the implementors, this default policy may be along the
- lines of 'anything goes' where there are no restrictions placed upon
- users, or it may be along the lines of 'excessively restrictive' in
- which case the administrators will have to actively make changes to
- this policy to meet their needs. Alternatively, it may be some
- attempt at providing something practical and immediately useful to
- the administrators of the system so they don't have to put in much
- effort to get SSH working. Whatever choice is made MUST be applied
- and enforced as required above.
-
-9.3.4 Public key authentication
-
- The use of public-key authentication assumes that the client host has
- not been compromised. It also assumes that the private-key of the
- server host has not been compromised.
-
- This risk can be mitigated by the use of passphrases on private keys;
- however, this is not an enforceable policy. The use of smartcards,
- or other technology to make passphrases an enforceable policy is
- suggested.
-
- The server could require both password and public-key authentication,
- however, this requires the client to expose its password to the
- server (see section on password authentication below.)
-
-9.3.5 Password authentication
-
- The password mechanism as specified in the authentication protocol
- assumes that the server has not been compromised. If the server has
- been compromised, using password authentication will reveal a valid
- username / password combination to the attacker, which may lead to
- further compromises.
-
- This vulnerability can be mitigated by using an alternative form of
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 22]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- authentication. For example, public-key authentication makes no
- assumptions about security on the server.
-
-9.3.6 Host based authentication
-
- Host based authentication assumes that the client has not been
- compromised. There are no mitigating strategies, other than to use
- host based authentication in combination with another authentication
- method.
-
-9.4 Connection protocol
-
-9.4.1 End point security
-
- End point security is assumed by the connection protocol. If the
- server has been compromised, any terminal sessions, port forwarding,
- or systems accessed on the host are compromised. There are no
- mitigating factors for this.
-
- If the client end point has been compromised, and the server fails to
- stop the attacker at the authentication protocol, all services
- exposed (either as subsystems or through forwarding) will be
- vulnerable to attack. Implementors SHOULD provide mechanisms for
- administrators to control which services are exposed to limit the
- vulnerability of other services.
-
- These controls might include controlling which machines and ports can
- be target in 'port-forwarding' operations, which users are allowed to
- use interactive shell facilities, or which users are allowed to use
- exposed subsystems.
-
-9.4.2 Proxy forwarding
-
- The SSH connection protocol allows for proxy forwarding of other
- protocols such as SNMP, POP3, and HTTP. This may be a concern for
- network administrators who wish to control the access of certain
- applications by users located outside of their physical location.
- Essentially, the forwarding of these protocols may violate site
- specific security policies as they may be undetectably tunneled
- through a firewall. Implementors SHOULD provide an administrative
- mechanism to control the proxy forwarding functionality so that site
- specific security policies may be upheld.
-
- In addition, a reverse proxy forwarding functionality is available,
- which again can be used to bypass firewall controls.
-
- As indicated above, end-point security is assumed during proxy
- forwarding operations. Failure of end-point security will compromise
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 23]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- all data passed over proxy forwarding.
-
-9.4.3 X11 forwarding
-
- Another form of proxy forwarding provided by the ssh connection
- protocol is the forwarding of the X11 protocol. If end-point
- security has been compromised, X11 forwarding may allow attacks
- against the X11 server. Users and administrators should, as a matter
- of course, use appropriate X11 security mechanisms to prevent
- unauthorized use of the X11 server. Implementors, administrators and
- users who wish to further explore the security mechanisms of X11 are
- invited to read [SCHEIFLER] and analyze previously reported problems
- with the interactions between SSH forwarding and X11 in CERT
- vulnerabilities VU#363181 and VU#118892 [CERT].
-
- X11 display forwarding with SSH, by itself, is not sufficient to
- correct well known problems with X11 security [VENEMA]. However, X11
- display forwarding in SSHv2 (or other, secure protocols), combined
- with actual and pseudo-displays which accept connections only over
- local IPC mechanisms authorized by permissions or ACLs, does correct
- many X11 security problems as long as the "none" MAC is not used. It
- is RECOMMENDED that X11 display implementations default to allowing
- display opens only over local IPC. It is RECOMMENDED that SSHv2
- server implementations that support X11 forwarding default to
- allowing display opens only over local IPC. On single-user systems
- it might be reasonable to default to allowing local display opens
- over TCP/IP.
-
- Implementors of the X11 forwarding protocol SHOULD implement the
- magic cookie access checking spoofing mechanism as described in
- [ssh-connect] as an additional mechanism to prevent unauthorized use
- of the proxy.
-
-Normative References
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 24]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative References
-
- [FIPS-186]
- Federal Information Processing Standards Publication,
- "FIPS PUB 186, Digital Signature Standard", May 1994.
-
- [FIPS-197]
- National Institue of Standards and Technology, "FIPS 197,
- Specification for the Advanced Encryption Standard",
- November 2001.
-
- [ANSI T1.523-2001]
- American National Standards Insitute, Inc., "Telecom
- Glossary 2000", February 2001.
-
- [SCHEIFLER]
- Scheifler, R., "X Window System : The Complete Reference
- to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital
- Press ISBN 1555580882, Feburary 1992.
-
- [RFC0854] Postel, J. and J. Reynolds, "Telnet Protocol
- Specification", STD 8, RFC 854, May 1983.
-
- [RFC0894] Hornig, C., "Standard for the transmission of IP datagrams
- over Ethernet networks", STD 41, RFC 894, April 1984.
-
- [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
- STD 13, RFC 1034, November 1987.
-
- [RFC1134] Perkins, D., "Point-to-Point Protocol: A proposal for
- multi-protocol transmission of datagrams over
- Point-to-Point links", RFC 1134, November 1989.
-
- [RFC1282] Kantor, B., "BSD Rlogin", RFC 1282, December 1991.
-
- [RFC1510] Kohl, J. and B. Neuman, "The Kerberos Network
- Authentication Service (V5)", RFC 1510, September 1993.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 25]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", RFC 1700,
- October 1994.
-
- [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness
- Recommendations for Security", RFC 1750, December 1994.
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC
- 1964, June 1996.
-
- [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism
- (SPKM)", RFC 2025, October 1996.
-
- [RFC2085] Oehler, M. and R. Glenn, "HMAC-MD5 IP Authentication with
- Replay Prevention", RFC 2085, February 1997.
-
- [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
- [RFC2246] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A.
- and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246,
- January 1999.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [RFC2410] Glenn, R. and S. Kent, "The NULL Encryption Algorithm and
- Its Use With IPsec", RFC 2410, November 1998.
-
- [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
- IANA Considerations Section in RFCs", BCP 26, RFC 2434,
- October 1998.
-
- [RFC2743] Linn, J., "Generic Security Service Application Program
- Interface Version 2, Update 1", RFC 2743, January 2000.
-
- [SCHNEIER]
- Schneier, B., "Applied Cryptography Second Edition:
- protocols algorithms and source in code in C", 1996.
-
- [KAUFMAN,PERLMAN,SPECINER]
- Kaufman, C., Perlman, R. and M. Speciner, "Network
- Security: PRIVATE Communication in a PUBLIC World", 1995.
-
- [CERT] CERT Coordination Center, The., "http://www.cert.org/nav/
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 26]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- index_red.html".
-
- [VENEMA] Venema, W., "Murphy's Law and Computer Security",
- Proceedings of 6th USENIX Security Symposium, San Jose CA
- http://www.usenix.org/publications/library/proceedings/
- sec96/venema.html, July 1996.
-
- [ROGAWAY] Rogaway, P., "Problems with Proposed IP Cryptography",
- Unpublished paper http://www.cs.ucdavis.edu/~rogaway/
- papers/draft-rogaway-ipsec-comments-00.txt, 1996.
-
- [DAI] Dai, W., "An attack against SSH2 protocol", Email to the
- SECSH Working Group [email protected] ftp://
- ftp.ietf.org/ietf-mail-archive/secsh/2002-02.mail, Feb
- 2002.
-
- [BELLARE,KOHNO,NAMPREMPRE]
- Bellaire, M., Kohno, T. and C. Namprempre, "Authenticated
- Encryption in SSH: Fixing the SSH Binary Packet Protocol",
- , Sept 2002.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park CA 94025
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 27]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 28]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 29] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps
deleted file mode 100644
index 7a386724c2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps
+++ /dev/null
@@ -1,2557 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:33:02 2003
-%%Orientation: Portrait
-%%Pages: 11 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Editor, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Connection Protocol) s
-5 613 M
-( draft-ietf-secsh-connect-18.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network.) s
-5 250 M
-( This document describes the SSH Connection Protocol. It provides) s
-5 239 M
-( interactive login sessions, remote execution of commands, forwarded) s
-5 228 M
-( TCP/IP connections, and forwarded X11 connections. All of these) s
-5 217 M
-( channels are multiplexed into a single encrypted tunnel.) s
-5 195 M
-( The SSH Connection Protocol has been designed to run on top of the) s
-5 184 M
-( SSH transport layer and user authentication protocols.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 646 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 635 M
-( 4. Global Requests . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 624 M
-( 5. Channel Mechanism . . . . . . . . . . . . . . . . . . . . . 4) s
-5 613 M
-( 5.1 Opening a Channel . . . . . . . . . . . . . . . . . . . . . 4) s
-5 602 M
-( 5.2 Data Transfer . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 591 M
-( 5.3 Closing a Channel . . . . . . . . . . . . . . . . . . . . . 6) s
-5 580 M
-( 5.4 Channel-Specific Requests . . . . . . . . . . . . . . . . . 7) s
-5 569 M
-( 6. Interactive Sessions . . . . . . . . . . . . . . . . . . . . 8) s
-5 558 M
-( 6.1 Opening a Session . . . . . . . . . . . . . . . . . . . . . 8) s
-5 547 M
-( 6.2 Requesting a Pseudo-Terminal . . . . . . . . . . . . . . . . 8) s
-5 536 M
-( 6.3 X11 Forwarding . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 525 M
-( 6.3.1 Requesting X11 Forwarding . . . . . . . . . . . . . . . . . 9) s
-5 514 M
-( 6.3.2 X11 Channels . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 503 M
-( 6.4 Environment Variable Passing . . . . . . . . . . . . . . . . 10) s
-5 492 M
-( 6.5 Starting a Shell or a Command . . . . . . . . . . . . . . . 10) s
-5 481 M
-( 6.6 Session Data Transfer . . . . . . . . . . . . . . . . . . . 11) s
-5 470 M
-( 6.7 Window Dimension Change Message . . . . . . . . . . . . . . 12) s
-5 459 M
-( 6.8 Local Flow Control . . . . . . . . . . . . . . . . . . . . . 12) s
-5 448 M
-( 6.9 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 12) s
-5 437 M
-( 6.10 Returning Exit Status . . . . . . . . . . . . . . . . . . . 13) s
-5 426 M
-( 7. TCP/IP Port Forwarding . . . . . . . . . . . . . . . . . . . 14) s
-5 415 M
-( 7.1 Requesting Port Forwarding . . . . . . . . . . . . . . . . . 14) s
-5 404 M
-( 7.2 TCP/IP Forwarding Channels . . . . . . . . . . . . . . . . . 15) s
-5 393 M
-( 8. Encoding of Terminal Modes . . . . . . . . . . . . . . . . . 16) s
-5 382 M
-( 9. Summary of Message Numbers . . . . . . . . . . . . . . . . . 18) s
-5 371 M
-( 10. Security Considerations . . . . . . . . . . . . . . . . . . 18) s
-5 360 M
-( 11. iana cONSiderations . . . . . . . . . . . . . . . . . . . . 19) s
-5 349 M
-( 12. Intellectual Property . . . . . . . . . . . . . . . . . . . 19) s
-5 338 M
-( Normative References . . . . . . . . . . . . . . . . . . . . 19) s
-5 327 M
-( Informative References . . . . . . . . . . . . . . . . . . . 20) s
-5 316 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20) s
-5 305 M
-( Intellectual Property and Copyright Statements . . . . . . . 21) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH Connection Protocol has been designed to run on top of the) s
-5 536 M
-( SSH transport layer and user authentication protocols. It provides) s
-5 525 M
-( interactive login sessions, remote execution of commands, forwarded) s
-5 514 M
-( TCP/IP connections, and forwarded X11 connections. The service name) s
-5 503 M
-( for this protocol is "ssh-connection".) s
-5 481 M
-( This document should be read only after reading the SSH architecture) s
-5 470 M
-( document [SSH-ARCH]. This document freely uses terminology and) s
-5 459 M
-( notation from the architecture document without reference or further) s
-5 448 M
-( explanation.) s
-5 426 M
-(3. Conventions Used in This Document) s
-5 404 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 393 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 382 M
-( described in [RFC2119].) s
-5 360 M
-( The used data types and terminology are specified in the architecture) s
-5 349 M
-( document [SSH-ARCH].) s
-5 327 M
-( The architecture document also discusses the algorithm naming) s
-5 316 M
-( conventions that MUST be used with the SSH protocols.) s
-5 294 M
-(4. Global Requests) s
-5 272 M
-( There are several kinds of requests that affect the state of the) s
-5 261 M
-( remote end "globally", independent of any channels. An example is a) s
-5 250 M
-( request to start TCP/IP forwarding for a specific port. All such) s
-5 239 M
-( requests use the following format.) s
-5 217 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 206 M
-( string request name \(restricted to US-ASCII\)) s
-5 195 M
-( boolean want reply) s
-5 184 M
-( ... request-specific data follows) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( Request names follow the DNS extensibility naming convention outlined) s
-5 679 M
-( in [SSH-ARCH].) s
-5 657 M
-( The recipient will respond to this message with) s
-5 646 M
-( SSH_MSG_REQUEST_SUCCESS or SSH_MSG_REQUEST_FAILURE if `want reply' is) s
-5 635 M
-( TRUE.) s
-5 613 M
-( byte SSH_MSG_REQUEST_SUCCESS) s
-5 602 M
-( ..... response specific data) s
-5 580 M
-( Usually the response specific data is non-existent.) s
-5 558 M
-( If the recipient does not recognize or support the request, it simply) s
-5 547 M
-( responds with SSH_MSG_REQUEST_FAILURE.) s
-5 525 M
-( byte SSH_MSG_REQUEST_FAILURE) s
-5 492 M
-(5. Channel Mechanism) s
-5 470 M
-( All terminal sessions, forwarded connections, etc. are channels.) s
-5 459 M
-( Either side may open a channel. Multiple channels are multiplexed) s
-5 448 M
-( into a single connection.) s
-5 426 M
-( Channels are identified by numbers at each end. The number referring) s
-5 415 M
-( to a channel may be different on each side. Requests to open a) s
-5 404 M
-( channel contain the sender's channel number. Any other) s
-5 393 M
-( channel-related messages contain the recipient's channel number for) s
-5 382 M
-( the channel.) s
-5 360 M
-( Channels are flow-controlled. No data may be sent to a channel until) s
-5 349 M
-( a message is received to indicate that window space is available.) s
-5 327 M
-(5.1 Opening a Channel) s
-5 305 M
-( When either side wishes to open a new channel, it allocates a local) s
-5 294 M
-( number for the channel. It then sends the following message to the) s
-5 283 M
-( other side, and includes the local channel number and initial window) s
-5 272 M
-( size in the message.) s
-5 250 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 239 M
-( string channel type \(restricted to US-ASCII\)) s
-5 228 M
-( uint32 sender channel) s
-5 217 M
-( uint32 initial window size) s
-5 206 M
-( uint32 maximum packet size) s
-5 195 M
-( ... channel type specific data follows) s
-5 173 M
-( The channel type is a name as described in the SSH architecture) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( document, with similar extension mechanisms. `sender channel' is a) s
-5 679 M
-( local identifier for the channel used by the sender of this message.) s
-5 668 M
-( `initial window size' specifies how many bytes of channel data can be) s
-5 657 M
-( sent to the sender of this message without adjusting the window.) s
-5 646 M
-( `Maximum packet size' specifies the maximum size of an individual) s
-5 635 M
-( data packet that can be sent to the sender \(for example, one might) s
-5 624 M
-( want to use smaller packets for interactive connections to get better) s
-5 613 M
-( interactive response on slow links\).) s
-5 591 M
-( The remote side then decides whether it can open the channel, and) s
-5 580 M
-( responds with either) s
-5 558 M
-( byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION) s
-5 547 M
-( uint32 recipient channel) s
-5 536 M
-( uint32 sender channel) s
-5 525 M
-( uint32 initial window size) s
-5 514 M
-( uint32 maximum packet size) s
-5 503 M
-( ... channel type specific data follows) s
-5 481 M
-( where `recipient channel' is the channel number given in the original) s
-5 470 M
-( open request, and `sender channel' is the channel number allocated by) s
-5 459 M
-( the other side, or) s
-5 437 M
-( byte SSH_MSG_CHANNEL_OPEN_FAILURE) s
-5 426 M
-( uint32 recipient channel) s
-5 415 M
-( uint32 reason code) s
-5 404 M
-( string additional textual information \(ISO-10646 UTF-8 [RFC2279]\)) s
-5 393 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 371 M
-( If the recipient of the SSH_MSG_CHANNEL_OPEN message does not support) s
-5 360 M
-( the specified channel type, it simply responds with) s
-5 349 M
-( SSH_MSG_CHANNEL_OPEN_FAILURE. The client MAY show the additional) s
-5 338 M
-( information to the user. If this is done, the client software should) s
-5 327 M
-( take the precautions discussed in [SSH-ARCH].) s
-5 305 M
-( The following reason codes are defined:) s
-5 283 M
-( #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1) s
-5 272 M
-( #define SSH_OPEN_CONNECT_FAILED 2) s
-5 261 M
-( #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3) s
-5 250 M
-( #define SSH_OPEN_RESOURCE_SHORTAGE 4) s
-5 217 M
-(5.2 Data Transfer) s
-5 195 M
-( The window size specifies how many bytes the other party can send) s
-5 184 M
-( before it must wait for the window to be adjusted. Both parties use) s
-5 173 M
-( the following message to adjust the window.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_CHANNEL_WINDOW_ADJUST) s
-5 679 M
-( uint32 recipient channel) s
-5 668 M
-( uint32 bytes to add) s
-5 646 M
-( After receiving this message, the recipient MAY send the given number) s
-5 635 M
-( of bytes more than it was previously allowed to send; the window size) s
-5 624 M
-( is incremented.) s
-5 602 M
-( Data transfer is done with messages of the following type.) s
-5 580 M
-( byte SSH_MSG_CHANNEL_DATA) s
-5 569 M
-( uint32 recipient channel) s
-5 558 M
-( string data) s
-5 536 M
-( The maximum amount of data allowed is the current window size. The) s
-5 525 M
-( window size is decremented by the amount of data sent. Both parties) s
-5 514 M
-( MAY ignore all extra data sent after the allowed window is empty.) s
-5 492 M
-( Additionally, some channels can transfer several types of data. An) s
-5 481 M
-( example of this is stderr data from interactive sessions. Such data) s
-5 470 M
-( can be passed with SSH_MSG_CHANNEL_EXTENDED_DATA messages, where a) s
-5 459 M
-( separate integer specifies the type of the data. The available types) s
-5 448 M
-( and their interpretation depend on the type of the channel.) s
-5 426 M
-( byte SSH_MSG_CHANNEL_EXTENDED_DATA) s
-5 415 M
-( uint32 recipient_channel) s
-5 404 M
-( uint32 data_type_code) s
-5 393 M
-( string data) s
-5 371 M
-( Data sent with these messages consumes the same window as ordinary) s
-5 360 M
-( data.) s
-5 338 M
-( Currently, only the following type is defined.) s
-5 316 M
-( #define SSH_EXTENDED_DATA_STDERR 1) s
-5 283 M
-(5.3 Closing a Channel) s
-5 261 M
-( When a party will no longer send more data to a channel, it SHOULD) s
-5 250 M
-( send SSH_MSG_CHANNEL_EOF.) s
-5 228 M
-( byte SSH_MSG_CHANNEL_EOF) s
-5 217 M
-( uint32 recipient_channel) s
-5 195 M
-( No explicit response is sent to this message; however, the) s
-5 184 M
-( application may send EOF to whatever is at the other end of the) s
-5 173 M
-( channel. Note that the channel remains open after this message, and) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( more data may still be sent in the other direction. This message) s
-5 679 M
-( does not consume window space and can be sent even if no window space) s
-5 668 M
-( is available.) s
-5 646 M
-( When either party wishes to terminate the channel, it sends) s
-5 635 M
-( SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST) s
-5 624 M
-( send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this) s
-5 613 M
-( message for the channel. The channel is considered closed for a) s
-5 602 M
-( party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and) s
-5 591 M
-( the party may then reuse the channel number. A party MAY send) s
-5 580 M
-( SSH_MSG_CHANNEL_CLOSE without having sent or received) s
-5 569 M
-( SSH_MSG_CHANNEL_EOF.) s
-5 547 M
-( byte SSH_MSG_CHANNEL_CLOSE) s
-5 536 M
-( uint32 recipient_channel) s
-5 514 M
-( This message does not consume window space and can be sent even if no) s
-5 503 M
-( window space is available.) s
-5 481 M
-( It is recommended that any data sent before this message is delivered) s
-5 470 M
-( to the actual destination, if possible.) s
-5 448 M
-(5.4 Channel-Specific Requests) s
-5 426 M
-( Many channel types have extensions that are specific to that) s
-5 415 M
-( particular channel type. An example is requesting a pty \(pseudo) s
-5 404 M
-( terminal\) for an interactive session.) s
-5 382 M
-( All channel-specific requests use the following format.) s
-5 360 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 349 M
-( uint32 recipient channel) s
-5 338 M
-( string request type \(restricted to US-ASCII\)) s
-5 327 M
-( boolean want reply) s
-5 316 M
-( ... type-specific data) s
-5 294 M
-( If want reply is FALSE, no response will be sent to the request.) s
-5 283 M
-( Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS) s
-5 272 M
-( or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation) s
-5 261 M
-( messages. If the request is not recognized or is not supported for) s
-5 250 M
-( the channel, SSH_MSG_CHANNEL_FAILURE is returned.) s
-5 228 M
-( This message does not consume window space and can be sent even if no) s
-5 217 M
-( window space is available. Request types are local to each channel) s
-5 206 M
-( type.) s
-5 184 M
-( The client is allowed to send further messages without waiting for) s
-5 173 M
-( the response to the request.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( request type names follow the DNS extensibility naming convention) s
-5 679 M
-( outlined in [SSH-ARCH]) s
-5 657 M
-( byte SSH_MSG_CHANNEL_SUCCESS) s
-5 646 M
-( uint32 recipient_channel) s
-5 613 M
-( byte SSH_MSG_CHANNEL_FAILURE) s
-5 602 M
-( uint32 recipient_channel) s
-5 580 M
-( These messages do not consume window space and can be sent even if no) s
-5 569 M
-( window space is available.) s
-5 547 M
-(6. Interactive Sessions) s
-5 525 M
-( A session is a remote execution of a program. The program may be a) s
-5 514 M
-( shell, an application, a system command, or some built-in subsystem.) s
-5 503 M
-( It may or may not have a tty, and may or may not involve X11) s
-5 492 M
-( forwarding. Multiple sessions can be active simultaneously.) s
-5 470 M
-(6.1 Opening a Session) s
-5 448 M
-( A session is started by sending the following message.) s
-5 426 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 415 M
-( string "session") s
-5 404 M
-( uint32 sender channel) s
-5 393 M
-( uint32 initial window size) s
-5 382 M
-( uint32 maximum packet size) s
-5 360 M
-( Client implementations SHOULD reject any session channel open) s
-5 349 M
-( requests to make it more difficult for a corrupt server to attack the) s
-5 338 M
-( client.) s
-5 316 M
-(6.2 Requesting a Pseudo-Terminal) s
-5 294 M
-( A pseudo-terminal can be allocated for the session by sending the) s
-5 283 M
-( following message.) s
-5 261 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 250 M
-( uint32 recipient_channel) s
-5 239 M
-( string "pty-req") s
-5 228 M
-( boolean want_reply) s
-5 217 M
-( string TERM environment variable value \(e.g., vt100\)) s
-5 206 M
-( uint32 terminal width, characters \(e.g., 80\)) s
-5 195 M
-( uint32 terminal height, rows \(e.g., 24\)) s
-5 184 M
-( uint32 terminal width, pixels \(e.g., 640\)) s
-5 173 M
-( uint32 terminal height, pixels \(e.g., 480\)) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( string encoded terminal modes) s
-5 668 M
-( The encoding of terminal modes is described in Section Encoding of) s
-5 657 M
-( Terminal Modes \(Section 8\). Zero dimension parameters MUST be) s
-5 646 M
-( ignored. The character/row dimensions override the pixel dimensions) s
-5 635 M
-( \(when nonzero\). Pixel dimensions refer to the drawable area of the) s
-5 624 M
-( window.) s
-5 602 M
-( The dimension parameters are only informational.) s
-5 580 M
-( The client SHOULD ignore pty requests.) s
-5 558 M
-(6.3 X11 Forwarding) s
-5 536 M
-(6.3.1 Requesting X11 Forwarding) s
-5 514 M
-( X11 forwarding may be requested for a session by sending) s
-5 492 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 481 M
-( uint32 recipient channel) s
-5 470 M
-( string "x11-req") s
-5 459 M
-( boolean want reply) s
-5 448 M
-( boolean single connection) s
-5 437 M
-( string x11 authentication protocol) s
-5 426 M
-( string x11 authentication cookie) s
-5 415 M
-( uint32 x11 screen number) s
-5 393 M
-( It is recommended that the authentication cookie that is sent be a) s
-5 382 M
-( fake, random cookie, and that the cookie is checked and replaced by) s
-5 371 M
-( the real cookie when a connection request is received.) s
-5 349 M
-( X11 connection forwarding should stop when the session channel is) s
-5 338 M
-( closed; however, already opened forwardings should not be) s
-5 327 M
-( automatically closed when the session channel is closed.) s
-5 305 M
-( If `single connection' is TRUE, only a single connection should be) s
-5 294 M
-( forwarded. No more connections will be forwarded after the first, or) s
-5 283 M
-( after the session channel has been closed.) s
-5 261 M
-( The "x11 authentication protocol" is the name of the X11) s
-5 250 M
-( authentication method used, e.g. "MIT-MAGIC-COOKIE-1".) s
-5 228 M
-( The x11 authentication cookie MUST be hexadecimal encoded.) s
-5 206 M
-( X Protocol is documented in [SCHEIFLER].) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(6.3.2 X11 Channels) s
-5 668 M
-( X11 channels are opened with a channel open request. The resulting) s
-5 657 M
-( channels are independent of the session, and closing the session) s
-5 646 M
-( channel does not close the forwarded X11 channels.) s
-5 624 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 613 M
-( string "x11") s
-5 602 M
-( uint32 sender channel) s
-5 591 M
-( uint32 initial window size) s
-5 580 M
-( uint32 maximum packet size) s
-5 569 M
-( string originator address \(e.g. "192.168.7.38"\)) s
-5 558 M
-( uint32 originator port) s
-5 536 M
-( The recipient should respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION) s
-5 525 M
-( or SSH_MSG_CHANNEL_OPEN_FAILURE.) s
-5 503 M
-( Implementations MUST reject any X11 channel open requests if they) s
-5 492 M
-( have not requested X11 forwarding.) s
-5 470 M
-(6.4 Environment Variable Passing) s
-5 448 M
-( Environment variables may be passed to the shell/command to be) s
-5 437 M
-( started later. Uncontrolled setting of environment variables in a) s
-5 426 M
-( privileged process can be a security hazard. It is recommended that) s
-5 415 M
-( implementations either maintain a list of allowable variable names or) s
-5 404 M
-( only set environment variables after the server process has dropped) s
-5 393 M
-( sufficient privileges.) s
-5 371 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 360 M
-( uint32 recipient channel) s
-5 349 M
-( string "env") s
-5 338 M
-( boolean want reply) s
-5 327 M
-( string variable name) s
-5 316 M
-( string variable value) s
-5 283 M
-(6.5 Starting a Shell or a Command) s
-5 261 M
-( Once the session has been set up, a program is started at the remote) s
-5 250 M
-( end. The program can be a shell, an application program or a) s
-5 239 M
-( subsystem with a host-independent name. Only one of these requests) s
-5 228 M
-( can succeed per channel.) s
-5 206 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 195 M
-( uint32 recipient channel) s
-5 184 M
-( string "shell") s
-5 173 M
-( boolean want reply) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( This message will request the user's default shell \(typically defined) s
-5 679 M
-( in /etc/passwd in UNIX systems\) to be started at the other end.) s
-5 657 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 646 M
-( uint32 recipient channel) s
-5 635 M
-( string "exec") s
-5 624 M
-( boolean want reply) s
-5 613 M
-( string command) s
-5 591 M
-( This message will request the server to start the execution of the) s
-5 580 M
-( given command. The command string may contain a path. Normal) s
-5 569 M
-( precautions MUST be taken to prevent the execution of unauthorized) s
-5 558 M
-( commands.) s
-5 536 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 525 M
-( uint32 recipient channel) s
-5 514 M
-( string "subsystem") s
-5 503 M
-( boolean want reply) s
-5 492 M
-( string subsystem name) s
-5 470 M
-( This last form executes a predefined subsystem. It is expected that) s
-5 459 M
-( these will include a general file transfer mechanism, and possibly) s
-5 448 M
-( other features. Implementations may also allow configuring more such) s
-5 437 M
-( mechanisms. As the user's shell is usually used to execute the) s
-5 426 M
-( subsystem, it is advisable for the subsystem protocol to have a) s
-5 415 M
-( "magic cookie" at the beginning of the protocol transaction to) s
-5 404 M
-( distinguish it from arbitrary output generated by shell) s
-5 393 M
-( initialization scripts etc. This spurious output from the shell may) s
-5 382 M
-( be filtered out either at the server or at the client.) s
-5 360 M
-( The server SHOULD not halt the execution of the protocol stack when) s
-5 349 M
-( starting a shell or a program. All input and output from these SHOULD) s
-5 338 M
-( be redirected to the channel or to the encrypted tunnel.) s
-5 316 M
-( It is RECOMMENDED to request and check the reply for these messages.) s
-5 305 M
-( The client SHOULD ignore these messages.) s
-5 283 M
-( Subsystem names follow the DNS extensibility naming convention) s
-5 272 M
-( outlined in [SSH-ARCH].) s
-5 250 M
-(6.6 Session Data Transfer) s
-5 228 M
-( Data transfer for a session is done using SSH_MSG_CHANNEL_DATA and) s
-5 217 M
-( SSH_MSG_CHANNEL_EXTENDED_DATA packets and the window mechanism. The) s
-5 206 M
-( extended data type SSH_EXTENDED_DATA_STDERR has been defined for) s
-5 195 M
-( stderr data.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(6.7 Window Dimension Change Message) s
-5 668 M
-( When the window \(terminal\) size changes on the client side, it MAY) s
-5 657 M
-( send a message to the other side to inform it of the new dimensions.) s
-5 635 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 624 M
-( uint32 recipient_channel) s
-5 613 M
-( string "window-change") s
-5 602 M
-( boolean FALSE) s
-5 591 M
-( uint32 terminal width, columns) s
-5 580 M
-( uint32 terminal height, rows) s
-5 569 M
-( uint32 terminal width, pixels) s
-5 558 M
-( uint32 terminal height, pixels) s
-5 536 M
-( No response SHOULD be sent to this message.) s
-5 514 M
-(6.8 Local Flow Control) s
-5 492 M
-( On many systems, it is possible to determine if a pseudo-terminal is) s
-5 481 M
-( using control-S/control-Q flow control. When flow control is) s
-5 470 M
-( allowed, it is often desirable to do the flow control at the client) s
-5 459 M
-( end to speed up responses to user requests. This is facilitated by) s
-5 448 M
-( the following notification. Initially, the server is responsible for) s
-5 437 M
-( flow control. \(Here, again, client means the side originating the) s
-5 426 M
-( session, and server means the other side.\)) s
-5 404 M
-( The message below is used by the server to inform the client when it) s
-5 393 M
-( can or cannot perform flow control \(control-S/control-Q processing\).) s
-5 382 M
-( If `client can do' is TRUE, the client is allowed to do flow control) s
-5 371 M
-( using control-S and control-Q. The client MAY ignore this message.) s
-5 349 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 338 M
-( uint32 recipient channel) s
-5 327 M
-( string "xon-xoff") s
-5 316 M
-( boolean FALSE) s
-5 305 M
-( boolean client can do) s
-5 283 M
-( No response is sent to this message.) s
-5 261 M
-(6.9 Signals) s
-5 239 M
-( A signal can be delivered to the remote process/service using the) s
-5 228 M
-( following message. Some systems may not implement signals, in which) s
-5 217 M
-( case they SHOULD ignore this message.) s
-5 195 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 184 M
-( uint32 recipient channel) s
-5 173 M
-( string "signal") s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( boolean FALSE) s
-5 679 M
-( string signal name without the "SIG" prefix.) s
-5 657 M
-( Signal names will be encoded as discussed in the "exit-signal") s
-5 646 M
-( SSH_MSG_CHANNEL_REQUEST.) s
-5 624 M
-(6.10 Returning Exit Status) s
-5 602 M
-( When the command running at the other end terminates, the following) s
-5 591 M
-( message can be sent to return the exit status of the command.) s
-5 580 M
-( Returning the status is RECOMMENDED. No acknowledgment is sent for) s
-5 569 M
-( this message. The channel needs to be closed with) s
-5 558 M
-( SSH_MSG_CHANNEL_CLOSE after this message.) s
-5 536 M
-( The client MAY ignore these messages.) s
-5 514 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 503 M
-( uint32 recipient_channel) s
-5 492 M
-( string "exit-status") s
-5 481 M
-( boolean FALSE) s
-5 470 M
-( uint32 exit_status) s
-5 448 M
-( The remote command may also terminate violently due to a signal.) s
-5 437 M
-( Such a condition can be indicated by the following message. A zero) s
-5 426 M
-( exit_status usually means that the command terminated successfully.) s
-5 404 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 393 M
-( uint32 recipient channel) s
-5 382 M
-( string "exit-signal") s
-5 371 M
-( boolean FALSE) s
-5 360 M
-( string signal name without the "SIG" prefix.) s
-5 349 M
-( boolean core dumped) s
-5 338 M
-( string error message \(ISO-10646 UTF-8\)) s
-5 327 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 305 M
-( The signal name is one of the following \(these are from [POSIX]\)) s
-5 283 M
-( ABRT) s
-5 272 M
-( ALRM) s
-5 261 M
-( FPE) s
-5 250 M
-( HUP) s
-5 239 M
-( ILL) s
-5 228 M
-( INT) s
-5 217 M
-( KILL) s
-5 206 M
-( PIPE) s
-5 195 M
-( QUIT) s
-5 184 M
-( SEGV) s
-5 173 M
-( TERM) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( USR1) s
-5 679 M
-( USR2) s
-5 657 M
-( Additional signal names MAY be sent in the format "sig-name@xyz",) s
-5 646 M
-( where `sig-name' and `xyz' may be anything a particular implementor) s
-5 635 M
-( wants \(except the `@' sign\). However, it is suggested that if a) s
-5 624 M
-( `configure' script is used, the non-standard signal names it finds be) s
-5 613 M
-( encoded as "[email protected]", where `SIG' is the signal name) s
-5 602 M
-( without the "SIG" prefix, and `xyz' be the host type, as determined) s
-5 591 M
-( by `config.guess'.) s
-5 569 M
-( The `error message' contains an additional explanation of the error) s
-5 558 M
-( message. The message may consist of multiple lines. The client) s
-5 547 M
-( software MAY display this message to the user. If this is done, the) s
-5 536 M
-( client software should take the precautions discussed in [SSH-ARCH].) s
-5 514 M
-(7. TCP/IP Port Forwarding) s
-5 492 M
-(7.1 Requesting Port Forwarding) s
-5 470 M
-( A party need not explicitly request forwardings from its own end to) s
-5 459 M
-( the other direction. However, if it wishes that connections to a) s
-5 448 M
-( port on the other side be forwarded to the local side, it must) s
-5 437 M
-( explicitly request this.) s
-5 404 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 393 M
-( string "tcpip-forward") s
-5 382 M
-( boolean want reply) s
-5 371 M
-( string address to bind \(e.g. "0.0.0.0"\)) s
-5 360 M
-( uint32 port number to bind) s
-5 338 M
-( `Address to bind' and `port number to bind' specify the IP address) s
-5 327 M
-( and port to which the socket to be listened is bound. The address) s
-5 316 M
-( should be "0.0.0.0" if connections are allowed from anywhere. \(Note) s
-5 305 M
-( that the client can still filter connections based on information) s
-5 294 M
-( passed in the open request.\)) s
-5 272 M
-( Implementations should only allow forwarding privileged ports if the) s
-5 261 M
-( user has been authenticated as a privileged user.) s
-5 239 M
-( Client implementations SHOULD reject these messages; they are) s
-5 228 M
-( normally only sent by the client.) s
-5 195 M
-( If a client passes 0 as port number to bind and has want reply TRUE) s
-5 184 M
-( then the server allocates the next available unprivileged port number) s
-5 173 M
-( and replies with the following message, otherwise there is no) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( response specific data.) s
-5 657 M
-( byte SSH_MSG_GLOBAL_REQUEST_SUCCESS) s
-5 646 M
-( uint32 port that was bound on the server) s
-5 624 M
-( A port forwarding can be cancelled with the following message. Note) s
-5 613 M
-( that channel open requests may be received until a reply to this) s
-5 602 M
-( message is received.) s
-5 580 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 569 M
-( string "cancel-tcpip-forward") s
-5 558 M
-( boolean want reply) s
-5 547 M
-( string address_to_bind \(e.g. "127.0.0.1"\)) s
-5 536 M
-( uint32 port number to bind) s
-5 514 M
-( Client implementations SHOULD reject these messages; they are) s
-5 503 M
-( normally only sent by the client.) s
-5 481 M
-(7.2 TCP/IP Forwarding Channels) s
-5 459 M
-( When a connection comes to a port for which remote forwarding has) s
-5 448 M
-( been requested, a channel is opened to forward the port to the other) s
-5 437 M
-( side.) s
-5 415 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 404 M
-( string "forwarded-tcpip") s
-5 393 M
-( uint32 sender channel) s
-5 382 M
-( uint32 initial window size) s
-5 371 M
-( uint32 maximum packet size) s
-5 360 M
-( string address that was connected) s
-5 349 M
-( uint32 port that was connected) s
-5 338 M
-( string originator IP address) s
-5 327 M
-( uint32 originator port) s
-5 305 M
-( Implementations MUST reject these messages unless they have) s
-5 294 M
-( previously requested a remote TCP/IP port forwarding with the given) s
-5 283 M
-( port number.) s
-5 261 M
-( When a connection comes to a locally forwarded TCP/IP port, the) s
-5 250 M
-( following packet is sent to the other side. Note that these messages) s
-5 239 M
-( MAY be sent also for ports for which no forwarding has been) s
-5 228 M
-( explicitly requested. The receiving side must decide whether to) s
-5 217 M
-( allow the forwarding.) s
-5 195 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 184 M
-( string "direct-tcpip") s
-5 173 M
-( uint32 sender channel) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( uint32 initial window size) s
-5 679 M
-( uint32 maximum packet size) s
-5 668 M
-( string host to connect) s
-5 657 M
-( uint32 port to connect) s
-5 646 M
-( string originator IP address) s
-5 635 M
-( uint32 originator port) s
-5 613 M
-( `Host to connect' and `port to connect' specify the TCP/IP host and) s
-5 602 M
-( port where the recipient should connect the channel. `Host to) s
-5 591 M
-( connect' may be either a domain name or a numeric IP address.) s
-5 569 M
-( `Originator IP address' is the numeric IP address of the machine) s
-5 558 M
-( where the connection request comes from, and `originator port' is the) s
-5 547 M
-( port on the originator host from where the connection came from.) s
-5 525 M
-( Forwarded TCP/IP channels are independent of any sessions, and) s
-5 514 M
-( closing a session channel does not in any way imply that forwarded) s
-5 503 M
-( connections should be closed.) s
-5 481 M
-( Client implementations SHOULD reject direct TCP/IP open requests for) s
-5 470 M
-( security reasons.) s
-5 448 M
-(8. Encoding of Terminal Modes) s
-5 426 M
-( Terminal modes \(as passed in a pty request\) are encoded into a byte) s
-5 415 M
-( stream. It is intended that the coding be portable across different) s
-5 404 M
-( environments.) s
-5 382 M
-( The tty mode description is a stream of bytes. The stream consists) s
-5 371 M
-( of opcode-argument pairs. It is terminated by opcode TTY_OP_END \(0\).) s
-5 360 M
-( Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255) s
-5 349 M
-( are not yet defined, and cause parsing to stop \(they should only be) s
-5 338 M
-( used after any other data\).) s
-5 316 M
-( The client SHOULD put in the stream any modes it knows about, and the) s
-5 305 M
-( server MAY ignore any modes it does not know about. This allows some) s
-5 294 M
-( degree of machine-independence, at least between systems that use a) s
-5 283 M
-( POSIX-like tty interface. The protocol can support other systems as) s
-5 272 M
-( well, but the client may need to fill reasonable values for a number) s
-5 261 M
-( of parameters so the server pty gets set to a reasonable mode \(the) s
-5 250 M
-( server leaves all unspecified mode bits in their default values, and) s
-5 239 M
-( only some combinations make sense\).) s
-5 217 M
-( The following opcodes have been defined. The naming of opcodes) s
-5 206 M
-( mostly follows the POSIX terminal mode flags.) s
-5 184 M
-( 0 TTY_OP_END Indicates end of options.) s
-5 173 M
-( 1 VINTR Interrupt character; 255 if none. Similarly for the) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( other characters. Not all of these characters are) s
-5 679 M
-( supported on all systems.) s
-5 668 M
-( 2 VQUIT The quit character \(sends SIGQUIT signal on POSIX) s
-5 657 M
-( systems\).) s
-5 646 M
-( 3 VERASE Erase the character to left of the cursor.) s
-5 635 M
-( 4 VKILL Kill the current input line.) s
-5 624 M
-( 5 VEOF End-of-file character \(sends EOF from the terminal\).) s
-5 613 M
-( 6 VEOL End-of-line character in addition to carriage return) s
-5 602 M
-( and/or linefeed.) s
-5 591 M
-( 7 VEOL2 Additional end-of-line character.) s
-5 580 M
-( 8 VSTART Continues paused output \(normally control-Q\).) s
-5 569 M
-( 9 VSTOP Pauses output \(normally control-S\).) s
-5 558 M
-( 10 VSUSP Suspends the current program.) s
-5 547 M
-( 11 VDSUSP Another suspend character.) s
-5 536 M
-( 12 VREPRINT Reprints the current input line.) s
-5 525 M
-( 13 VWERASE Erases a word left of cursor.) s
-5 514 M
-( 14 VLNEXT Enter the next character typed literally, even if it) s
-5 503 M
-( is a special character) s
-5 492 M
-( 15 VFLUSH Character to flush output.) s
-5 481 M
-( 16 VSWTCH Switch to a different shell layer.) s
-5 470 M
-( 17 VSTATUS Prints system status line \(load, command, pid etc\).) s
-5 459 M
-( 18 VDISCARD Toggles the flushing of terminal output.) s
-5 448 M
-( 30 IGNPAR The ignore parity flag. The parameter SHOULD be 0 if) s
-5 437 M
-( this flag is FALSE set, and 1 if it is TRUE.) s
-5 426 M
-( 31 PARMRK Mark parity and framing errors.) s
-5 415 M
-( 32 INPCK Enable checking of parity errors.) s
-5 404 M
-( 33 ISTRIP Strip 8th bit off characters.) s
-5 393 M
-( 34 INLCR Map NL into CR on input.) s
-5 382 M
-( 35 IGNCR Ignore CR on input.) s
-5 371 M
-( 36 ICRNL Map CR to NL on input.) s
-5 360 M
-( 37 IUCLC Translate uppercase characters to lowercase.) s
-5 349 M
-( 38 IXON Enable output flow control.) s
-5 338 M
-( 39 IXANY Any char will restart after stop.) s
-5 327 M
-( 40 IXOFF Enable input flow control.) s
-5 316 M
-( 41 IMAXBEL Ring bell on input queue full.) s
-5 305 M
-( 50 ISIG Enable signals INTR, QUIT, [D]SUSP.) s
-5 294 M
-( 51 ICANON Canonicalize input lines.) s
-5 283 M
-( 52 XCASE Enable input and output of uppercase characters by) s
-5 272 M
-( preceding their lowercase equivalents with `\\'.) s
-5 261 M
-( 53 ECHO Enable echoing.) s
-5 250 M
-( 54 ECHOE Visually erase chars.) s
-5 239 M
-( 55 ECHOK Kill character discards current line.) s
-5 228 M
-( 56 ECHONL Echo NL even if ECHO is off.) s
-5 217 M
-( 57 NOFLSH Don't flush after interrupt.) s
-5 206 M
-( 58 TOSTOP Stop background jobs from output.) s
-5 195 M
-( 59 IEXTEN Enable extensions.) s
-5 184 M
-( 60 ECHOCTL Echo control characters as ^\(Char\).) s
-5 173 M
-( 61 ECHOKE Visual erase for line kill.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( 62 PENDIN Retype pending input.) s
-5 679 M
-( 70 OPOST Enable output processing.) s
-5 668 M
-( 71 OLCUC Convert lowercase to uppercase.) s
-5 657 M
-( 72 ONLCR Map NL to CR-NL.) s
-5 646 M
-( 73 OCRNL Translate carriage return to newline \(output\).) s
-5 635 M
-( 74 ONOCR Translate newline to carriage return-newline) s
-5 624 M
-( \(output\).) s
-5 613 M
-( 75 ONLRET Newline performs a carriage return \(output\).) s
-5 602 M
-( 90 CS7 7 bit mode.) s
-5 591 M
-( 91 CS8 8 bit mode.) s
-5 580 M
-( 92 PARENB Parity enable.) s
-5 569 M
-( 93 PARODD Odd parity, else even.) s
-5 547 M
-( 128 TTY_OP_ISPEED Specifies the input baud rate in bits per second.) s
-5 536 M
-( 129 TTY_OP_OSPEED Specifies the output baud rate in bits per second.) s
-5 503 M
-(9. Summary of Message Numbers) s
-5 481 M
-( #define SSH_MSG_GLOBAL_REQUEST 80) s
-5 470 M
-( #define SSH_MSG_REQUEST_SUCCESS 81) s
-5 459 M
-( #define SSH_MSG_REQUEST_FAILURE 82) s
-5 448 M
-( #define SSH_MSG_CHANNEL_OPEN 90) s
-5 437 M
-( #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91) s
-5 426 M
-( #define SSH_MSG_CHANNEL_OPEN_FAILURE 92) s
-5 415 M
-( #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93) s
-5 404 M
-( #define SSH_MSG_CHANNEL_DATA 94) s
-5 393 M
-( #define SSH_MSG_CHANNEL_EXTENDED_DATA 95) s
-5 382 M
-( #define SSH_MSG_CHANNEL_EOF 96) s
-5 371 M
-( #define SSH_MSG_CHANNEL_CLOSE 97) s
-5 360 M
-( #define SSH_MSG_CHANNEL_REQUEST 98) s
-5 349 M
-( #define SSH_MSG_CHANNEL_SUCCESS 99) s
-5 338 M
-( #define SSH_MSG_CHANNEL_FAILURE 100) s
-5 305 M
-(10. Security Considerations) s
-5 283 M
-( This protocol is assumed to run on top of a secure, authenticated) s
-5 272 M
-( transport. User authentication and protection against network-level) s
-5 261 M
-( attacks are assumed to be provided by the underlying protocols.) s
-5 239 M
-( It is RECOMMENDED that implementations disable all the potentially) s
-5 228 M
-( dangerous features \(e.g. agent forwarding, X11 forwarding, and TCP/IP) s
-5 217 M
-( forwarding\) if the host key has changed.) s
-5 195 M
-( Full security considerations for this protocol are provided in) s
-5 184 M
-( Section 8 of [SSH-ARCH]) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(11. iana cONSiderations) s
-5 668 M
-( This document is part of a set, the IANA considerations for the SSH) s
-5 657 M
-( protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],) s
-5 646 M
-( [SSH-CONNECT] are detailed in [SSH-NUMBERS].) s
-5 624 M
-(12. Intellectual Property) s
-5 602 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 591 M
-( intellectual property or other rights that might be claimed to) s
-5 580 M
-( pertain to the implementation or use of the technology described in) s
-5 569 M
-( this document or the extent to which any license under such rights) s
-5 558 M
-( might or might not be available; neither does it represent that it) s
-5 547 M
-( has made any effort to identify any such rights. Information on the) s
-5 536 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 525 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 514 M
-( claims of rights made available for publication and any assurances of) s
-5 503 M
-( licenses to be made available, or the result of an attempt made to) s
-5 492 M
-( obtain a general license or permission for the use of such) s
-5 481 M
-( proprietary rights by implementers or users of this specification can) s
-5 470 M
-( be obtained from the IETF Secretariat.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 393 M
-(Normative References) s
-5 371 M
-( [SSH-ARCH]) s
-5 360 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 349 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 327 M
-( [SSH-TRANS]) s
-5 316 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 305 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 283 M
-( [SSH-USERAUTH]) s
-5 272 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 261 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 239 M
-( [SSH-CONNECT]) s
-5 228 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 217 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 195 M
-( [SSH-NUMBERS]) s
-5 184 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 173 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( 2003.) s
-5 668 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 657 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 635 M
-(Informative References) s
-5 613 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 602 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 580 M
-( [RFC1884] Hinden, R. and S. Deering, "IP Version 6 Addressing) s
-5 569 M
-( Architecture", RFC 1884, December 1995.) s
-5 547 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 536 M
-( 10646", RFC 2279, January 1998.) s
-5 514 M
-( [SCHEIFLER]) s
-5 503 M
-( Scheifler, R., "X Window System : The Complete Reference) s
-5 492 M
-( to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital) s
-5 481 M
-( Press ISBN 1555580882, Feburary 1992.) s
-5 459 M
-( [POSIX] ISO/IEC, 9945-1., "Information technology -- Portable) s
-5 448 M
-( Operating System Interface \(POSIX\)-Part 1: System) s
-5 437 M
-( Application Program Interface \(API\) C Language", ANSI/IEE) s
-5 426 M
-( Std 1003.1, July 1996.) s
-5 393 M
-(Authors' Addresses) s
-5 371 M
-( Tatu Ylonen) s
-5 360 M
-( SSH Communications Security Corp) s
-5 349 M
-( Fredrikinkatu 42) s
-5 338 M
-( HELSINKI FIN-00100) s
-5 327 M
-( Finland) s
-5 305 M
-( EMail: [email protected]) s
-5 272 M
-( Darren J. Moffat \(editor\)) s
-5 261 M
-( Sun Microsystems, Inc) s
-5 250 M
-( 17 Network Circle) s
-5 239 M
-( Menlo Park CA 94025) s
-5 228 M
-( USA) s
-5 206 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 22
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt b/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt
deleted file mode 100644
index 1cb8ad6409..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt
+++ /dev/null
@@ -1,1232 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Editor, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Connection Protocol
- draft-ietf-secsh-connect-18.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network.
-
- This document describes the SSH Connection Protocol. It provides
- interactive login sessions, remote execution of commands, forwarded
- TCP/IP connections, and forwarded X11 connections. All of these
- channels are multiplexed into a single encrypted tunnel.
-
- The SSH Connection Protocol has been designed to run on top of the
- SSH transport layer and user authentication protocols.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 4. Global Requests . . . . . . . . . . . . . . . . . . . . . . 3
- 5. Channel Mechanism . . . . . . . . . . . . . . . . . . . . . 4
- 5.1 Opening a Channel . . . . . . . . . . . . . . . . . . . . . 4
- 5.2 Data Transfer . . . . . . . . . . . . . . . . . . . . . . . 5
- 5.3 Closing a Channel . . . . . . . . . . . . . . . . . . . . . 6
- 5.4 Channel-Specific Requests . . . . . . . . . . . . . . . . . 7
- 6. Interactive Sessions . . . . . . . . . . . . . . . . . . . . 8
- 6.1 Opening a Session . . . . . . . . . . . . . . . . . . . . . 8
- 6.2 Requesting a Pseudo-Terminal . . . . . . . . . . . . . . . . 8
- 6.3 X11 Forwarding . . . . . . . . . . . . . . . . . . . . . . . 9
- 6.3.1 Requesting X11 Forwarding . . . . . . . . . . . . . . . . . 9
- 6.3.2 X11 Channels . . . . . . . . . . . . . . . . . . . . . . . . 10
- 6.4 Environment Variable Passing . . . . . . . . . . . . . . . . 10
- 6.5 Starting a Shell or a Command . . . . . . . . . . . . . . . 10
- 6.6 Session Data Transfer . . . . . . . . . . . . . . . . . . . 11
- 6.7 Window Dimension Change Message . . . . . . . . . . . . . . 12
- 6.8 Local Flow Control . . . . . . . . . . . . . . . . . . . . . 12
- 6.9 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 6.10 Returning Exit Status . . . . . . . . . . . . . . . . . . . 13
- 7. TCP/IP Port Forwarding . . . . . . . . . . . . . . . . . . . 14
- 7.1 Requesting Port Forwarding . . . . . . . . . . . . . . . . . 14
- 7.2 TCP/IP Forwarding Channels . . . . . . . . . . . . . . . . . 15
- 8. Encoding of Terminal Modes . . . . . . . . . . . . . . . . . 16
- 9. Summary of Message Numbers . . . . . . . . . . . . . . . . . 18
- 10. Security Considerations . . . . . . . . . . . . . . . . . . 18
- 11. iana cONSiderations . . . . . . . . . . . . . . . . . . . . 19
- 12. Intellectual Property . . . . . . . . . . . . . . . . . . . 19
- Normative References . . . . . . . . . . . . . . . . . . . . 19
- Informative References . . . . . . . . . . . . . . . . . . . 20
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20
- Intellectual Property and Copyright Statements . . . . . . . 21
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH Connection Protocol has been designed to run on top of the
- SSH transport layer and user authentication protocols. It provides
- interactive login sessions, remote execution of commands, forwarded
- TCP/IP connections, and forwarded X11 connections. The service name
- for this protocol is "ssh-connection".
-
- This document should be read only after reading the SSH architecture
- document [SSH-ARCH]. This document freely uses terminology and
- notation from the architecture document without reference or further
- explanation.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119].
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH].
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-4. Global Requests
-
- There are several kinds of requests that affect the state of the
- remote end "globally", independent of any channels. An example is a
- request to start TCP/IP forwarding for a specific port. All such
- requests use the following format.
-
- byte SSH_MSG_GLOBAL_REQUEST
- string request name (restricted to US-ASCII)
- boolean want reply
- ... request-specific data follows
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- Request names follow the DNS extensibility naming convention outlined
- in [SSH-ARCH].
-
- The recipient will respond to this message with
- SSH_MSG_REQUEST_SUCCESS or SSH_MSG_REQUEST_FAILURE if `want reply' is
- TRUE.
-
- byte SSH_MSG_REQUEST_SUCCESS
- ..... response specific data
-
- Usually the response specific data is non-existent.
-
- If the recipient does not recognize or support the request, it simply
- responds with SSH_MSG_REQUEST_FAILURE.
-
- byte SSH_MSG_REQUEST_FAILURE
-
-
-5. Channel Mechanism
-
- All terminal sessions, forwarded connections, etc. are channels.
- Either side may open a channel. Multiple channels are multiplexed
- into a single connection.
-
- Channels are identified by numbers at each end. The number referring
- to a channel may be different on each side. Requests to open a
- channel contain the sender's channel number. Any other
- channel-related messages contain the recipient's channel number for
- the channel.
-
- Channels are flow-controlled. No data may be sent to a channel until
- a message is received to indicate that window space is available.
-
-5.1 Opening a Channel
-
- When either side wishes to open a new channel, it allocates a local
- number for the channel. It then sends the following message to the
- other side, and includes the local channel number and initial window
- size in the message.
-
- byte SSH_MSG_CHANNEL_OPEN
- string channel type (restricted to US-ASCII)
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- ... channel type specific data follows
-
- The channel type is a name as described in the SSH architecture
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- document, with similar extension mechanisms. `sender channel' is a
- local identifier for the channel used by the sender of this message.
- `initial window size' specifies how many bytes of channel data can be
- sent to the sender of this message without adjusting the window.
- `Maximum packet size' specifies the maximum size of an individual
- data packet that can be sent to the sender (for example, one might
- want to use smaller packets for interactive connections to get better
- interactive response on slow links).
-
- The remote side then decides whether it can open the channel, and
- responds with either
-
- byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
- uint32 recipient channel
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- ... channel type specific data follows
-
- where `recipient channel' is the channel number given in the original
- open request, and `sender channel' is the channel number allocated by
- the other side, or
-
- byte SSH_MSG_CHANNEL_OPEN_FAILURE
- uint32 recipient channel
- uint32 reason code
- string additional textual information (ISO-10646 UTF-8 [RFC2279])
- string language tag (as defined in [RFC3066])
-
- If the recipient of the SSH_MSG_CHANNEL_OPEN message does not support
- the specified channel type, it simply responds with
- SSH_MSG_CHANNEL_OPEN_FAILURE. The client MAY show the additional
- information to the user. If this is done, the client software should
- take the precautions discussed in [SSH-ARCH].
-
- The following reason codes are defined:
-
- #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
- #define SSH_OPEN_CONNECT_FAILED 2
- #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3
- #define SSH_OPEN_RESOURCE_SHORTAGE 4
-
-
-5.2 Data Transfer
-
- The window size specifies how many bytes the other party can send
- before it must wait for the window to be adjusted. Both parties use
- the following message to adjust the window.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- byte SSH_MSG_CHANNEL_WINDOW_ADJUST
- uint32 recipient channel
- uint32 bytes to add
-
- After receiving this message, the recipient MAY send the given number
- of bytes more than it was previously allowed to send; the window size
- is incremented.
-
- Data transfer is done with messages of the following type.
-
- byte SSH_MSG_CHANNEL_DATA
- uint32 recipient channel
- string data
-
- The maximum amount of data allowed is the current window size. The
- window size is decremented by the amount of data sent. Both parties
- MAY ignore all extra data sent after the allowed window is empty.
-
- Additionally, some channels can transfer several types of data. An
- example of this is stderr data from interactive sessions. Such data
- can be passed with SSH_MSG_CHANNEL_EXTENDED_DATA messages, where a
- separate integer specifies the type of the data. The available types
- and their interpretation depend on the type of the channel.
-
- byte SSH_MSG_CHANNEL_EXTENDED_DATA
- uint32 recipient_channel
- uint32 data_type_code
- string data
-
- Data sent with these messages consumes the same window as ordinary
- data.
-
- Currently, only the following type is defined.
-
- #define SSH_EXTENDED_DATA_STDERR 1
-
-
-5.3 Closing a Channel
-
- When a party will no longer send more data to a channel, it SHOULD
- send SSH_MSG_CHANNEL_EOF.
-
- byte SSH_MSG_CHANNEL_EOF
- uint32 recipient_channel
-
- No explicit response is sent to this message; however, the
- application may send EOF to whatever is at the other end of the
- channel. Note that the channel remains open after this message, and
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- more data may still be sent in the other direction. This message
- does not consume window space and can be sent even if no window space
- is available.
-
- When either party wishes to terminate the channel, it sends
- SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
- send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
- message for the channel. The channel is considered closed for a
- party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
- the party may then reuse the channel number. A party MAY send
- SSH_MSG_CHANNEL_CLOSE without having sent or received
- SSH_MSG_CHANNEL_EOF.
-
- byte SSH_MSG_CHANNEL_CLOSE
- uint32 recipient_channel
-
- This message does not consume window space and can be sent even if no
- window space is available.
-
- It is recommended that any data sent before this message is delivered
- to the actual destination, if possible.
-
-5.4 Channel-Specific Requests
-
- Many channel types have extensions that are specific to that
- particular channel type. An example is requesting a pty (pseudo
- terminal) for an interactive session.
-
- All channel-specific requests use the following format.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string request type (restricted to US-ASCII)
- boolean want reply
- ... type-specific data
-
- If want reply is FALSE, no response will be sent to the request.
- Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS
- or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation
- messages. If the request is not recognized or is not supported for
- the channel, SSH_MSG_CHANNEL_FAILURE is returned.
-
- This message does not consume window space and can be sent even if no
- window space is available. Request types are local to each channel
- type.
-
- The client is allowed to send further messages without waiting for
- the response to the request.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- request type names follow the DNS extensibility naming convention
- outlined in [SSH-ARCH]
-
- byte SSH_MSG_CHANNEL_SUCCESS
- uint32 recipient_channel
-
-
- byte SSH_MSG_CHANNEL_FAILURE
- uint32 recipient_channel
-
- These messages do not consume window space and can be sent even if no
- window space is available.
-
-6. Interactive Sessions
-
- A session is a remote execution of a program. The program may be a
- shell, an application, a system command, or some built-in subsystem.
- It may or may not have a tty, and may or may not involve X11
- forwarding. Multiple sessions can be active simultaneously.
-
-6.1 Opening a Session
-
- A session is started by sending the following message.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "session"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
-
- Client implementations SHOULD reject any session channel open
- requests to make it more difficult for a corrupt server to attack the
- client.
-
-6.2 Requesting a Pseudo-Terminal
-
- A pseudo-terminal can be allocated for the session by sending the
- following message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "pty-req"
- boolean want_reply
- string TERM environment variable value (e.g., vt100)
- uint32 terminal width, characters (e.g., 80)
- uint32 terminal height, rows (e.g., 24)
- uint32 terminal width, pixels (e.g., 640)
- uint32 terminal height, pixels (e.g., 480)
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- string encoded terminal modes
-
- The encoding of terminal modes is described in Section Encoding of
- Terminal Modes (Section 8). Zero dimension parameters MUST be
- ignored. The character/row dimensions override the pixel dimensions
- (when nonzero). Pixel dimensions refer to the drawable area of the
- window.
-
- The dimension parameters are only informational.
-
- The client SHOULD ignore pty requests.
-
-6.3 X11 Forwarding
-
-6.3.1 Requesting X11 Forwarding
-
- X11 forwarding may be requested for a session by sending
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "x11-req"
- boolean want reply
- boolean single connection
- string x11 authentication protocol
- string x11 authentication cookie
- uint32 x11 screen number
-
- It is recommended that the authentication cookie that is sent be a
- fake, random cookie, and that the cookie is checked and replaced by
- the real cookie when a connection request is received.
-
- X11 connection forwarding should stop when the session channel is
- closed; however, already opened forwardings should not be
- automatically closed when the session channel is closed.
-
- If `single connection' is TRUE, only a single connection should be
- forwarded. No more connections will be forwarded after the first, or
- after the session channel has been closed.
-
- The "x11 authentication protocol" is the name of the X11
- authentication method used, e.g. "MIT-MAGIC-COOKIE-1".
-
- The x11 authentication cookie MUST be hexadecimal encoded.
-
- X Protocol is documented in [SCHEIFLER].
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-6.3.2 X11 Channels
-
- X11 channels are opened with a channel open request. The resulting
- channels are independent of the session, and closing the session
- channel does not close the forwarded X11 channels.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "x11"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- string originator address (e.g. "192.168.7.38")
- uint32 originator port
-
- The recipient should respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION
- or SSH_MSG_CHANNEL_OPEN_FAILURE.
-
- Implementations MUST reject any X11 channel open requests if they
- have not requested X11 forwarding.
-
-6.4 Environment Variable Passing
-
- Environment variables may be passed to the shell/command to be
- started later. Uncontrolled setting of environment variables in a
- privileged process can be a security hazard. It is recommended that
- implementations either maintain a list of allowable variable names or
- only set environment variables after the server process has dropped
- sufficient privileges.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "env"
- boolean want reply
- string variable name
- string variable value
-
-
-6.5 Starting a Shell or a Command
-
- Once the session has been set up, a program is started at the remote
- end. The program can be a shell, an application program or a
- subsystem with a host-independent name. Only one of these requests
- can succeed per channel.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "shell"
- boolean want reply
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- This message will request the user's default shell (typically defined
- in /etc/passwd in UNIX systems) to be started at the other end.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "exec"
- boolean want reply
- string command
-
- This message will request the server to start the execution of the
- given command. The command string may contain a path. Normal
- precautions MUST be taken to prevent the execution of unauthorized
- commands.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "subsystem"
- boolean want reply
- string subsystem name
-
- This last form executes a predefined subsystem. It is expected that
- these will include a general file transfer mechanism, and possibly
- other features. Implementations may also allow configuring more such
- mechanisms. As the user's shell is usually used to execute the
- subsystem, it is advisable for the subsystem protocol to have a
- "magic cookie" at the beginning of the protocol transaction to
- distinguish it from arbitrary output generated by shell
- initialization scripts etc. This spurious output from the shell may
- be filtered out either at the server or at the client.
-
- The server SHOULD not halt the execution of the protocol stack when
- starting a shell or a program. All input and output from these SHOULD
- be redirected to the channel or to the encrypted tunnel.
-
- It is RECOMMENDED to request and check the reply for these messages.
- The client SHOULD ignore these messages.
-
- Subsystem names follow the DNS extensibility naming convention
- outlined in [SSH-ARCH].
-
-6.6 Session Data Transfer
-
- Data transfer for a session is done using SSH_MSG_CHANNEL_DATA and
- SSH_MSG_CHANNEL_EXTENDED_DATA packets and the window mechanism. The
- extended data type SSH_EXTENDED_DATA_STDERR has been defined for
- stderr data.
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-6.7 Window Dimension Change Message
-
- When the window (terminal) size changes on the client side, it MAY
- send a message to the other side to inform it of the new dimensions.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "window-change"
- boolean FALSE
- uint32 terminal width, columns
- uint32 terminal height, rows
- uint32 terminal width, pixels
- uint32 terminal height, pixels
-
- No response SHOULD be sent to this message.
-
-6.8 Local Flow Control
-
- On many systems, it is possible to determine if a pseudo-terminal is
- using control-S/control-Q flow control. When flow control is
- allowed, it is often desirable to do the flow control at the client
- end to speed up responses to user requests. This is facilitated by
- the following notification. Initially, the server is responsible for
- flow control. (Here, again, client means the side originating the
- session, and server means the other side.)
-
- The message below is used by the server to inform the client when it
- can or cannot perform flow control (control-S/control-Q processing).
- If `client can do' is TRUE, the client is allowed to do flow control
- using control-S and control-Q. The client MAY ignore this message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "xon-xoff"
- boolean FALSE
- boolean client can do
-
- No response is sent to this message.
-
-6.9 Signals
-
- A signal can be delivered to the remote process/service using the
- following message. Some systems may not implement signals, in which
- case they SHOULD ignore this message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "signal"
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- boolean FALSE
- string signal name without the "SIG" prefix.
-
- Signal names will be encoded as discussed in the "exit-signal"
- SSH_MSG_CHANNEL_REQUEST.
-
-6.10 Returning Exit Status
-
- When the command running at the other end terminates, the following
- message can be sent to return the exit status of the command.
- Returning the status is RECOMMENDED. No acknowledgment is sent for
- this message. The channel needs to be closed with
- SSH_MSG_CHANNEL_CLOSE after this message.
-
- The client MAY ignore these messages.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "exit-status"
- boolean FALSE
- uint32 exit_status
-
- The remote command may also terminate violently due to a signal.
- Such a condition can be indicated by the following message. A zero
- exit_status usually means that the command terminated successfully.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "exit-signal"
- boolean FALSE
- string signal name without the "SIG" prefix.
- boolean core dumped
- string error message (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- The signal name is one of the following (these are from [POSIX])
-
- ABRT
- ALRM
- FPE
- HUP
- ILL
- INT
- KILL
- PIPE
- QUIT
- SEGV
- TERM
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- USR1
- USR2
-
- Additional signal names MAY be sent in the format "sig-name@xyz",
- where `sig-name' and `xyz' may be anything a particular implementor
- wants (except the `@' sign). However, it is suggested that if a
- `configure' script is used, the non-standard signal names it finds be
- encoded as "[email protected]", where `SIG' is the signal name
- without the "SIG" prefix, and `xyz' be the host type, as determined
- by `config.guess'.
-
- The `error message' contains an additional explanation of the error
- message. The message may consist of multiple lines. The client
- software MAY display this message to the user. If this is done, the
- client software should take the precautions discussed in [SSH-ARCH].
-
-7. TCP/IP Port Forwarding
-
-7.1 Requesting Port Forwarding
-
- A party need not explicitly request forwardings from its own end to
- the other direction. However, if it wishes that connections to a
- port on the other side be forwarded to the local side, it must
- explicitly request this.
-
-
- byte SSH_MSG_GLOBAL_REQUEST
- string "tcpip-forward"
- boolean want reply
- string address to bind (e.g. "0.0.0.0")
- uint32 port number to bind
-
- `Address to bind' and `port number to bind' specify the IP address
- and port to which the socket to be listened is bound. The address
- should be "0.0.0.0" if connections are allowed from anywhere. (Note
- that the client can still filter connections based on information
- passed in the open request.)
-
- Implementations should only allow forwarding privileged ports if the
- user has been authenticated as a privileged user.
-
- Client implementations SHOULD reject these messages; they are
- normally only sent by the client.
-
-
- If a client passes 0 as port number to bind and has want reply TRUE
- then the server allocates the next available unprivileged port number
- and replies with the following message, otherwise there is no
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- response specific data.
-
-
- byte SSH_MSG_GLOBAL_REQUEST_SUCCESS
- uint32 port that was bound on the server
-
- A port forwarding can be cancelled with the following message. Note
- that channel open requests may be received until a reply to this
- message is received.
-
- byte SSH_MSG_GLOBAL_REQUEST
- string "cancel-tcpip-forward"
- boolean want reply
- string address_to_bind (e.g. "127.0.0.1")
- uint32 port number to bind
-
- Client implementations SHOULD reject these messages; they are
- normally only sent by the client.
-
-7.2 TCP/IP Forwarding Channels
-
- When a connection comes to a port for which remote forwarding has
- been requested, a channel is opened to forward the port to the other
- side.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "forwarded-tcpip"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- string address that was connected
- uint32 port that was connected
- string originator IP address
- uint32 originator port
-
- Implementations MUST reject these messages unless they have
- previously requested a remote TCP/IP port forwarding with the given
- port number.
-
- When a connection comes to a locally forwarded TCP/IP port, the
- following packet is sent to the other side. Note that these messages
- MAY be sent also for ports for which no forwarding has been
- explicitly requested. The receiving side must decide whether to
- allow the forwarding.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "direct-tcpip"
- uint32 sender channel
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- uint32 initial window size
- uint32 maximum packet size
- string host to connect
- uint32 port to connect
- string originator IP address
- uint32 originator port
-
- `Host to connect' and `port to connect' specify the TCP/IP host and
- port where the recipient should connect the channel. `Host to
- connect' may be either a domain name or a numeric IP address.
-
- `Originator IP address' is the numeric IP address of the machine
- where the connection request comes from, and `originator port' is the
- port on the originator host from where the connection came from.
-
- Forwarded TCP/IP channels are independent of any sessions, and
- closing a session channel does not in any way imply that forwarded
- connections should be closed.
-
- Client implementations SHOULD reject direct TCP/IP open requests for
- security reasons.
-
-8. Encoding of Terminal Modes
-
- Terminal modes (as passed in a pty request) are encoded into a byte
- stream. It is intended that the coding be portable across different
- environments.
-
- The tty mode description is a stream of bytes. The stream consists
- of opcode-argument pairs. It is terminated by opcode TTY_OP_END (0).
- Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255
- are not yet defined, and cause parsing to stop (they should only be
- used after any other data).
-
- The client SHOULD put in the stream any modes it knows about, and the
- server MAY ignore any modes it does not know about. This allows some
- degree of machine-independence, at least between systems that use a
- POSIX-like tty interface. The protocol can support other systems as
- well, but the client may need to fill reasonable values for a number
- of parameters so the server pty gets set to a reasonable mode (the
- server leaves all unspecified mode bits in their default values, and
- only some combinations make sense).
-
- The following opcodes have been defined. The naming of opcodes
- mostly follows the POSIX terminal mode flags.
-
- 0 TTY_OP_END Indicates end of options.
- 1 VINTR Interrupt character; 255 if none. Similarly for the
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- other characters. Not all of these characters are
- supported on all systems.
- 2 VQUIT The quit character (sends SIGQUIT signal on POSIX
- systems).
- 3 VERASE Erase the character to left of the cursor.
- 4 VKILL Kill the current input line.
- 5 VEOF End-of-file character (sends EOF from the terminal).
- 6 VEOL End-of-line character in addition to carriage return
- and/or linefeed.
- 7 VEOL2 Additional end-of-line character.
- 8 VSTART Continues paused output (normally control-Q).
- 9 VSTOP Pauses output (normally control-S).
- 10 VSUSP Suspends the current program.
- 11 VDSUSP Another suspend character.
- 12 VREPRINT Reprints the current input line.
- 13 VWERASE Erases a word left of cursor.
- 14 VLNEXT Enter the next character typed literally, even if it
- is a special character
- 15 VFLUSH Character to flush output.
- 16 VSWTCH Switch to a different shell layer.
- 17 VSTATUS Prints system status line (load, command, pid etc).
- 18 VDISCARD Toggles the flushing of terminal output.
- 30 IGNPAR The ignore parity flag. The parameter SHOULD be 0 if
- this flag is FALSE set, and 1 if it is TRUE.
- 31 PARMRK Mark parity and framing errors.
- 32 INPCK Enable checking of parity errors.
- 33 ISTRIP Strip 8th bit off characters.
- 34 INLCR Map NL into CR on input.
- 35 IGNCR Ignore CR on input.
- 36 ICRNL Map CR to NL on input.
- 37 IUCLC Translate uppercase characters to lowercase.
- 38 IXON Enable output flow control.
- 39 IXANY Any char will restart after stop.
- 40 IXOFF Enable input flow control.
- 41 IMAXBEL Ring bell on input queue full.
- 50 ISIG Enable signals INTR, QUIT, [D]SUSP.
- 51 ICANON Canonicalize input lines.
- 52 XCASE Enable input and output of uppercase characters by
- preceding their lowercase equivalents with `\'.
- 53 ECHO Enable echoing.
- 54 ECHOE Visually erase chars.
- 55 ECHOK Kill character discards current line.
- 56 ECHONL Echo NL even if ECHO is off.
- 57 NOFLSH Don't flush after interrupt.
- 58 TOSTOP Stop background jobs from output.
- 59 IEXTEN Enable extensions.
- 60 ECHOCTL Echo control characters as ^(Char).
- 61 ECHOKE Visual erase for line kill.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- 62 PENDIN Retype pending input.
- 70 OPOST Enable output processing.
- 71 OLCUC Convert lowercase to uppercase.
- 72 ONLCR Map NL to CR-NL.
- 73 OCRNL Translate carriage return to newline (output).
- 74 ONOCR Translate newline to carriage return-newline
- (output).
- 75 ONLRET Newline performs a carriage return (output).
- 90 CS7 7 bit mode.
- 91 CS8 8 bit mode.
- 92 PARENB Parity enable.
- 93 PARODD Odd parity, else even.
-
- 128 TTY_OP_ISPEED Specifies the input baud rate in bits per second.
- 129 TTY_OP_OSPEED Specifies the output baud rate in bits per second.
-
-
-9. Summary of Message Numbers
-
- #define SSH_MSG_GLOBAL_REQUEST 80
- #define SSH_MSG_REQUEST_SUCCESS 81
- #define SSH_MSG_REQUEST_FAILURE 82
- #define SSH_MSG_CHANNEL_OPEN 90
- #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
- #define SSH_MSG_CHANNEL_OPEN_FAILURE 92
- #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
- #define SSH_MSG_CHANNEL_DATA 94
- #define SSH_MSG_CHANNEL_EXTENDED_DATA 95
- #define SSH_MSG_CHANNEL_EOF 96
- #define SSH_MSG_CHANNEL_CLOSE 97
- #define SSH_MSG_CHANNEL_REQUEST 98
- #define SSH_MSG_CHANNEL_SUCCESS 99
- #define SSH_MSG_CHANNEL_FAILURE 100
-
-
-10. Security Considerations
-
- This protocol is assumed to run on top of a secure, authenticated
- transport. User authentication and protection against network-level
- attacks are assumed to be provided by the underlying protocols.
-
- It is RECOMMENDED that implementations disable all the potentially
- dangerous features (e.g. agent forwarding, X11 forwarding, and TCP/IP
- forwarding) if the host key has changed.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-11. iana cONSiderations
-
- This document is part of a set, the IANA considerations for the SSH
- protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],
- [SSH-CONNECT] are detailed in [SSH-NUMBERS].
-
-12. Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementers or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-Normative References
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative References
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1884] Hinden, R. and S. Deering, "IP Version 6 Addressing
- Architecture", RFC 1884, December 1995.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [SCHEIFLER]
- Scheifler, R., "X Window System : The Complete Reference
- to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital
- Press ISBN 1555580882, Feburary 1992.
-
- [POSIX] ISO/IEC, 9945-1., "Information technology -- Portable
- Operating System Interface (POSIX)-Part 1: System
- Application Program Interface (API) C Language", ANSI/IEE
- Std 1003.1, July 1996.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park CA 94025
- USA
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps
deleted file mode 100644
index 06c91bf8cd..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps
+++ /dev/null
@@ -1,2853 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Wed Nov 12 12:26:07 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft S. Lehtinen) s
-5 679 M
-(Expires: April 1, 2002 SSH Communications Security Corp) s
-5 668 M
-( October 2001) s
-5 635 M
-( SSH File Transfer Protocol) s
-5 624 M
-( draft-ietf-secsh-filexfer-02.txt) s
-5 602 M
-(Status of this Memo) s
-5 580 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 569 M
-( all provisions of Section 10 of RFC2026.) s
-5 547 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 536 M
-( Task Force \(IETF\), its areas, and its working groups. Note that) s
-5 525 M
-( other groups may also distribute working documents as Internet-) s
-5 514 M
-( Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on April 1, 2002.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2001\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( The SSH File Transfer Protocol provides secure file transfer) s
-5 272 M
-( functionality over any reliable data stream. It is the standard file) s
-5 261 M
-( transfer protocol for use with the SSH2 protocol. This document) s
-5 250 M
-( describes the file transfer protocol and its interface to the SSH2) s
-5 239 M
-( protocol suite.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Use with the SSH Connection Protocol . . . . . . . . . . . . 4) s
-5 646 M
-( 3. General Packet Format . . . . . . . . . . . . . . . . . . . 5) s
-5 635 M
-( 4. Protocol Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 624 M
-( 5. File Attributes . . . . . . . . . . . . . . . . . . . . . . 8) s
-5 613 M
-( 6. Requests From the Client to the Server . . . . . . . . . . . 10) s
-5 602 M
-( 6.1 Request Synchronization and Reordering . . . . . . . . . . . 10) s
-5 591 M
-( 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 580 M
-( 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . . 11) s
-5 569 M
-( 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . . 13) s
-5 558 M
-( 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . . 14) s
-5 547 M
-( 6.6 Creating and Deleting Directories . . . . . . . . . . . . . 15) s
-5 536 M
-( 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . . 15) s
-5 525 M
-( 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . . 16) s
-5 514 M
-( 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . . 17) s
-5 503 M
-( 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . . 18) s
-5 492 M
-( 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . . 18) s
-5 481 M
-( 7. Responses from the Server to the Client . . . . . . . . . . 20) s
-5 470 M
-( 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . . 24) s
-5 459 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . . 25) s
-5 448 M
-( 10. Changes from previous protocol versions . . . . . . . . . . 26) s
-5 437 M
-( 10.1 Changes between versions 3 and 2 . . . . . . . . . . . . . . 26) s
-5 426 M
-( 10.2 Changes between versions 2 and 1 . . . . . . . . . . . . . . 26) s
-5 415 M
-( 10.3 Changes between versions 1 and 0 . . . . . . . . . . . . . . 26) s
-5 404 M
-( 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . . 27) s
-5 393 M
-( References . . . . . . . . . . . . . . . . . . . . . . . . . 28) s
-5 382 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 28) s
-5 371 M
-( Full Copyright Statement . . . . . . . . . . . . . . . . . . 29) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(1. Introduction) s
-5 668 M
-( This protocol provides secure file transfer \(and more generally file) s
-5 657 M
-( system access\) functionality over a reliable data stream, such as a) s
-5 646 M
-( channel in the SSH2 protocol [3].) s
-5 624 M
-( This protocol is designed so that it could be used to implement a) s
-5 613 M
-( secure remote file system service, as well as a secure file transfer) s
-5 602 M
-( service.) s
-5 580 M
-( This protocol assumes that it runs over a secure channel, and that) s
-5 569 M
-( the server has already authenticated the user at the client end, and) s
-5 558 M
-( that the identity of the client user is externally available to the) s
-5 547 M
-( server implementation.) s
-5 525 M
-( In general, this protocol follows a simple request-response model.) s
-5 514 M
-( Each request and response contains a sequence number and multiple) s
-5 503 M
-( requests may be pending simultaneously. There are a relatively large) s
-5 492 M
-( number of different request messages, but a small number of possible) s
-5 481 M
-( response messages. Each request has one or more response messages) s
-5 470 M
-( that may be returned in result \(e.g., a read either returns data or) s
-5 459 M
-( reports error status\).) s
-5 437 M
-( The packet format descriptions in this specification follow the) s
-5 426 M
-( notation presented in the secsh architecture draft.[3].) s
-5 404 M
-( Even though this protocol is described in the context of the SSH2) s
-5 393 M
-( protocol, this protocol is general and independent of the rest of the) s
-5 382 M
-( SSH2 protocol suite. It could be used in a number of different) s
-5 371 M
-( applications, such as secure file transfer over TLS RFC 2246 [1] and) s
-5 360 M
-( transfer of management information in VPN applications.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(2. Use with the SSH Connection Protocol) s
-5 668 M
-( When used with the SSH2 Protocol suite, this protocol is intended to) s
-5 657 M
-( be used from the SSH Connection Protocol [5] as a subsystem, as) s
-5 646 M
-( described in section ``Starting a Shell or a Command''. The) s
-5 635 M
-( subsystem name used with this protocol is "sftp".) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(3. General Packet Format) s
-5 668 M
-( All packets transmitted over the secure connection are of the) s
-5 657 M
-( following format:) s
-5 635 M
-( uint32 length) s
-5 624 M
-( byte type) s
-5 613 M
-( byte[length - 1] data payload) s
-5 591 M
-( That is, they are just data preceded by 32-bit length and 8-bit type) s
-5 580 M
-( fields. The `length' is the length of the data area, and does not) s
-5 569 M
-( include the `length' field itself. The format and interpretation of) s
-5 558 M
-( the data area depends on the packet type.) s
-5 536 M
-( All packet descriptions below only specify the packet type and the) s
-5 525 M
-( data that goes into the data field. Thus, they should be prefixed by) s
-5 514 M
-( the `length' and `type' fields.) s
-5 492 M
-( The maximum size of a packet is in practice determined by the client) s
-5 481 M
-( \(the maximum size of read or write requests that it sends, plus a few) s
-5 470 M
-( bytes of packet overhead\). All servers SHOULD support packets of at) s
-5 459 M
-( least 34000 bytes \(where the packet size refers to the full length,) s
-5 448 M
-( including the header above\). This should allow for reads and writes) s
-5 437 M
-( of at most 32768 bytes.) s
-5 415 M
-( There is no limit on the number of outstanding \(non-acknowledged\)) s
-5 404 M
-( requests that the client may send to the server. In practice this is) s
-5 393 M
-( limited by the buffering available on the data stream and the queuing) s
-5 382 M
-( performed by the server. If the server's queues are full, it should) s
-5 371 M
-( not read any more data from the stream, and flow control will prevent) s
-5 360 M
-( the client from sending more requests. Note, however, that while) s
-5 349 M
-( there is no restriction on the protocol level, the client's API may) s
-5 338 M
-( provide a limit in order to prevent infinite queuing of outgoing) s
-5 327 M
-( requests at the client.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The following values are defined for packet types.) s
-5 668 M
-( #define SSH_FXP_INIT 1) s
-5 657 M
-( #define SSH_FXP_VERSION 2) s
-5 646 M
-( #define SSH_FXP_OPEN 3) s
-5 635 M
-( #define SSH_FXP_CLOSE 4) s
-5 624 M
-( #define SSH_FXP_READ 5) s
-5 613 M
-( #define SSH_FXP_WRITE 6) s
-5 602 M
-( #define SSH_FXP_LSTAT 7) s
-5 591 M
-( #define SSH_FXP_FSTAT 8) s
-5 580 M
-( #define SSH_FXP_SETSTAT 9) s
-5 569 M
-( #define SSH_FXP_FSETSTAT 10) s
-5 558 M
-( #define SSH_FXP_OPENDIR 11) s
-5 547 M
-( #define SSH_FXP_READDIR 12) s
-5 536 M
-( #define SSH_FXP_REMOVE 13) s
-5 525 M
-( #define SSH_FXP_MKDIR 14) s
-5 514 M
-( #define SSH_FXP_RMDIR 15) s
-5 503 M
-( #define SSH_FXP_REALPATH 16) s
-5 492 M
-( #define SSH_FXP_STAT 17) s
-5 481 M
-( #define SSH_FXP_RENAME 18) s
-5 470 M
-( #define SSH_FXP_READLINK 19) s
-5 459 M
-( #define SSH_FXP_SYMLINK 20) s
-5 448 M
-( #define SSH_FXP_STATUS 101) s
-5 437 M
-( #define SSH_FXP_HANDLE 102) s
-5 426 M
-( #define SSH_FXP_DATA 103) s
-5 415 M
-( #define SSH_FXP_NAME 104) s
-5 404 M
-( #define SSH_FXP_ATTRS 105) s
-5 393 M
-( #define SSH_FXP_EXTENDED 200) s
-5 382 M
-( #define SSH_FXP_EXTENDED_REPLY 201) s
-5 360 M
-( Additional packet types should only be defined if the protocol) s
-5 349 M
-( version number \(see Section ``Protocol Initialization''\) is) s
-5 338 M
-( incremented, and their use MUST be negotiated using the version) s
-5 327 M
-( number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY) s
-5 316 M
-( packets can be used to implement vendor-specific extensions. See) s
-5 305 M
-( Section ``Vendor-Specific-Extensions'' for more details.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(4. Protocol Initialization) s
-5 668 M
-( When the file transfer protocol starts, it first sends a SSH_FXP_INIT) s
-5 657 M
-( \(including its version number\) packet to the server. The server) s
-5 646 M
-( responds with a SSH_FXP_VERSION packet, supplying the lowest of its) s
-5 635 M
-( own and the client's version number. Both parties should from then) s
-5 624 M
-( on adhere to particular version of the protocol.) s
-5 602 M
-( The SSH_FXP_INIT packet \(from client to server\) has the following) s
-5 591 M
-( data:) s
-5 569 M
-( uint32 version) s
-5 558 M
-( <extension data>) s
-5 536 M
-( The SSH_FXP_VERSION packet \(from server to client\) has the following) s
-5 525 M
-( data:) s
-5 503 M
-( uint32 version) s
-5 492 M
-( <extension data>) s
-5 470 M
-( The version number of the protocol specified in this document is 3.) s
-5 459 M
-( The version number should be incremented for each incompatible) s
-5 448 M
-( revision of this protocol.) s
-5 426 M
-( The extension data in the above packets may be empty, or may be a) s
-5 415 M
-( sequence of) s
-5 393 M
-( string extension_name) s
-5 382 M
-( string extension_data) s
-5 360 M
-( pairs \(both strings MUST always be present if one is, but the) s
-5 349 M
-( `extension_data' string may be of zero length\). If present, these) s
-5 338 M
-( strings indicate extensions to the baseline protocol. The) s
-5 327 M
-( `extension_name' field\(s\) identify the name of the extension. The) s
-5 316 M
-( name should be of the form "name@domain", where the domain is the DNS) s
-5 305 M
-( domain name of the organization defining the extension. Additional) s
-5 294 M
-( names that are not of this format may be defined later by the IETF.) s
-5 283 M
-( Implementations MUST silently ignore any extensions whose name they) s
-5 272 M
-( do not recognize.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(5. File Attributes) s
-5 668 M
-( A new compound data type is defined for encoding file attributes. It) s
-5 657 M
-( is basically just a combination of elementary types, but is defined) s
-5 646 M
-( once because of the non-trivial description of the fields and to) s
-5 635 M
-( ensure maintainability.) s
-5 613 M
-( The same encoding is used both when returning file attributes from) s
-5 602 M
-( the server and when sending file attributes to the server. When) s
-5 591 M
-( sending it to the server, the flags field specifies which attributes) s
-5 580 M
-( are included, and the server will use default values for the) s
-5 569 M
-( remaining attributes \(or will not modify the values of remaining) s
-5 558 M
-( attributes\). When receiving attributes from the server, the flags) s
-5 547 M
-( specify which attributes are included in the returned data. The) s
-5 536 M
-( server normally returns all attributes it knows about.) s
-5 514 M
-( uint32 flags) s
-5 503 M
-( uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE) s
-5 492 M
-( uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID) s
-5 481 M
-( uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID) s
-5 470 M
-( uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS) s
-5 459 M
-( uint32 atime present only if flag SSH_FILEXFER_ACMODTIME) s
-5 448 M
-( uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME) s
-5 437 M
-( uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED) s
-5 426 M
-( string extended_type) s
-5 415 M
-( string extended_data) s
-5 404 M
-( ... more extended data \(extended_type - extended_data pairs\),) s
-5 393 M
-( so that number of pairs equals extended_count) s
-5 371 M
-( The `flags' specify which of the fields are present. Those fields) s
-5 360 M
-( for which the corresponding flag is not set are not present \(not) s
-5 349 M
-( included in the packet\). New flags can only be added by incrementing) s
-5 338 M
-( the protocol version number \(or by using the extension mechanism) s
-5 327 M
-( described below\).) s
-5 305 M
-( The `size' field specifies the size of the file in bytes.) s
-5 283 M
-( The `uid' and `gid' fields contain numeric Unix-like user and group) s
-5 272 M
-( identifiers, respectively.) s
-5 250 M
-( The `permissions' field contains a bit mask of file permissions as) s
-5 239 M
-( defined by posix [1].) s
-5 217 M
-( The `atime' and `mtime' contain the access and modification times of) s
-5 206 M
-( the files, respectively. They are represented as seconds from Jan 1,) s
-5 195 M
-( 1970 in UTC.) s
-5 173 M
-( The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( mechanism for vendor-specific extensions. If the flag is specified,) s
-5 679 M
-( then the `extended_count' field is present. It specifies the number) s
-5 668 M
-( of extended_type-extended_data pairs that follow. Each of these) s
-5 657 M
-( pairs specifies an extended attribute. For each of the attributes,) s
-5 646 M
-( the extended_type field should be a string of the format) s
-5 635 M
-( "name@domain", where "domain" is a valid, registered domain name and) s
-5 624 M
-( "name" identifies the method. The IETF may later standardize certain) s
-5 613 M
-( names that deviate from this format \(e.g., that do not contain the) s
-5 602 M
-( "@" sign\). The interpretation of `extended_data' depends on the) s
-5 591 M
-( type. Implementations SHOULD ignore extended data fields that they) s
-5 580 M
-( do not understand.) s
-5 558 M
-( Additional fields can be added to the attributes by either defining) s
-5 547 M
-( additional bits to the flags field to indicate their presence, or by) s
-5 536 M
-( defining extended attributes for them. The extended attributes) s
-5 525 M
-( mechanism is recommended for most purposes; additional flags bits) s
-5 514 M
-( should only be defined by an IETF standards action that also) s
-5 503 M
-( increments the protocol version number. The use of such new fields) s
-5 492 M
-( MUST be negotiated by the version number in the protocol exchange.) s
-5 481 M
-( It is a protocol error if a packet with unsupported protocol bits is) s
-5 470 M
-( received.) s
-5 448 M
-( The flags bits are defined to have the following values:) s
-5 426 M
-( #define SSH_FILEXFER_ATTR_SIZE 0x00000001) s
-5 415 M
-( #define SSH_FILEXFER_ATTR_UIDGID 0x00000002) s
-5 404 M
-( #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004) s
-5 393 M
-( #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008) s
-5 382 M
-( #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6. Requests From the Client to the Server) s
-5 668 M
-( Requests from the client to the server represent the various file) s
-5 657 M
-( system operations. Each request begins with an `id' field, which is) s
-5 646 M
-( a 32-bit identifier identifying the request \(selected by the client\).) s
-5 635 M
-( The same identifier will be returned in the response to the request.) s
-5 624 M
-( One possible implementation of it is a monotonically increasing) s
-5 613 M
-( request sequence number \(modulo 2^32\).) s
-5 591 M
-( Many operations in the protocol operate on open files. The) s
-5 580 M
-( SSH_FXP_OPEN request can return a file handle \(which is an opaque) s
-5 569 M
-( variable-length string\) which may be used to access the file later) s
-5 558 M
-( \(e.g. in a read operation\). The client MUST NOT send requests the) s
-5 547 M
-( server with bogus or closed handles. However, the server MUST) s
-5 536 M
-( perform adequate checks on the handle in order to avoid security) s
-5 525 M
-( risks due to fabricated handles.) s
-5 503 M
-( This design allows either stateful and stateless server) s
-5 492 M
-( implementation, as well as an implementation which caches state) s
-5 481 M
-( between requests but may also flush it. The contents of the file) s
-5 470 M
-( handle string are entirely up to the server and its design. The) s
-5 459 M
-( client should not modify or attempt to interpret the file handle) s
-5 448 M
-( strings.) s
-5 426 M
-( The file handle strings MUST NOT be longer than 256 bytes.) s
-5 404 M
-(6.1 Request Synchronization and Reordering) s
-5 382 M
-( The protocol and implementations MUST process requests relating to) s
-5 371 M
-( the same file in the order in which they are received. In other) s
-5 360 M
-( words, if an application submits multiple requests to the server, the) s
-5 349 M
-( results in the responses will be the same as if it had sent the) s
-5 338 M
-( requests one at a time and waited for the response in each case. For) s
-5 327 M
-( example, the server may process non-overlapping read/write requests) s
-5 316 M
-( to the same file in parallel, but overlapping reads and writes cannot) s
-5 305 M
-( be reordered or parallelized. However, there are no ordering) s
-5 294 M
-( restrictions on the server for processing requests from two different) s
-5 283 M
-( file transfer connections. The server may interleave and parallelize) s
-5 272 M
-( them at will.) s
-5 250 M
-( There are no restrictions on the order in which responses to) s
-5 239 M
-( outstanding requests are delivered to the client, except that the) s
-5 228 M
-( server must ensure fairness in the sense that processing of no) s
-5 217 M
-( request will be indefinitely delayed even if the client is sending) s
-5 206 M
-( other requests so that there are multiple outstanding requests all) s
-5 195 M
-( the time.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6.2 File Names) s
-5 668 M
-( This protocol represents file names as strings. File names are) s
-5 657 M
-( assumed to use the slash \('/'\) character as a directory separator.) s
-5 635 M
-( File names starting with a slash are "absolute", and are relative to) s
-5 624 M
-( the root of the file system. Names starting with any other character) s
-5 613 M
-( are relative to the user's default directory \(home directory\). Note) s
-5 602 M
-( that identifying the user is assumed to take place outside of this) s
-5 591 M
-( protocol.) s
-5 569 M
-( Servers SHOULD interpret a path name component ".." as referring to) s
-5 558 M
-( the parent directory, and "." as referring to the current directory.) s
-5 547 M
-( If the server implementation limits access to certain parts of the) s
-5 536 M
-( file system, it must be extra careful in parsing file names when) s
-5 525 M
-( enforcing such restrictions. There have been numerous reported) s
-5 514 M
-( security bugs where a ".." in a path name has allowed access outside) s
-5 503 M
-( the intended area.) s
-5 481 M
-( An empty path name is valid, and it refers to the user's default) s
-5 470 M
-( directory \(usually the user's home directory\).) s
-5 448 M
-( Otherwise, no syntax is defined for file names by this specification.) s
-5 437 M
-( Clients should not make any other assumptions; however, they can) s
-5 426 M
-( splice path name components returned by SSH_FXP_READDIR together) s
-5 415 M
-( using a slash \('/'\) as the separator, and that will work as expected.) s
-5 393 M
-( It is understood that the lack of well-defined semantics for file) s
-5 382 M
-( names may cause interoperability problems between clients and servers) s
-5 371 M
-( using radically different operating systems. However, this approach) s
-5 360 M
-( is known to work acceptably with most systems, and alternative) s
-5 349 M
-( approaches that e.g. treat file names as sequences of structured) s
-5 338 M
-( components are quite complicated.) s
-5 316 M
-(6.3 Opening, Creating, and Closing Files) s
-5 294 M
-( Files are opened and created using the SSH_FXP_OPEN message, whose) s
-5 283 M
-( data part is as follows:) s
-5 261 M
-( uint32 id) s
-5 250 M
-( string filename) s
-5 239 M
-( uint32 pflags) s
-5 228 M
-( ATTRS attrs) s
-5 206 M
-( The `id' field is the request identifier as for all requests.) s
-5 184 M
-( The `filename' field specifies the file name. See Section ``File) s
-5 173 M
-( Names'' for more information.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The `pflags' field is a bitmask. The following bits have been) s
-5 679 M
-( defined.) s
-5 657 M
-( #define SSH_FXF_READ 0x00000001) s
-5 646 M
-( #define SSH_FXF_WRITE 0x00000002) s
-5 635 M
-( #define SSH_FXF_APPEND 0x00000004) s
-5 624 M
-( #define SSH_FXF_CREAT 0x00000008) s
-5 613 M
-( #define SSH_FXF_TRUNC 0x00000010) s
-5 602 M
-( #define SSH_FXF_EXCL 0x00000020) s
-5 580 M
-( These have the following meanings:) s
-5 558 M
-( SSH_FXF_READ) s
-5 547 M
-( Open the file for reading.) s
-5 525 M
-( SSH_FXF_WRITE) s
-5 514 M
-( Open the file for writing. If both this and SSH_FXF_READ are) s
-5 503 M
-( specified, the file is opened for both reading and writing.) s
-5 481 M
-( SSH_FXF_APPEND) s
-5 470 M
-( Force all writes to append data at the end of the file.) s
-5 448 M
-( SSH_FXF_CREAT) s
-5 437 M
-( If this flag is specified, then a new file will be created if one) s
-5 426 M
-( does not already exist \(if O_TRUNC is specified, the new file will) s
-5 415 M
-( be truncated to zero length if it previously exists\).) s
-5 393 M
-( SSH_FXF_TRUNC) s
-5 382 M
-( Forces an existing file with the same name to be truncated to zero) s
-5 371 M
-( length when creating a file by specifying SSH_FXF_CREAT.) s
-5 360 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 338 M
-( SSH_FXF_EXCL) s
-5 327 M
-( Causes the request to fail if the named file already exists.) s
-5 316 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 294 M
-( The `attrs' field specifies the initial attributes for the file.) s
-5 283 M
-( Default values will be used for those attributes that are not) s
-5 272 M
-( specified. See Section ``File Attributes'' for more information.) s
-5 250 M
-( Regardless the server operating system, the file will always be) s
-5 239 M
-( opened in "binary" mode \(i.e., no translations between different) s
-5 228 M
-( character sets and newline encodings\).) s
-5 206 M
-( The response to this message will be either SSH_FXP_HANDLE \(if the) s
-5 195 M
-( operation is successful\) or SSH_FXP_STATUS \(if the operation fails\).) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( A file is closed by using the SSH_FXP_CLOSE request. Its data field) s
-5 679 M
-( has the following format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string handle) s
-5 624 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 613 M
-( previously returned in the response to SSH_FXP_OPEN or) s
-5 602 M
-( SSH_FXP_OPENDIR. The handle becomes invalid immediately after this) s
-5 591 M
-( request has been sent.) s
-5 569 M
-( The response to this request will be a SSH_FXP_STATUS message. One) s
-5 558 M
-( should note that on some server platforms even a close can fail.) s
-5 547 M
-( This can happen e.g. if the server operating system caches writes,) s
-5 536 M
-( and an error occurs while flushing cached writes during the close.) s
-5 514 M
-(6.4 Reading and Writing) s
-5 492 M
-( Once a file has been opened, it can be read using the SSH_FXP_READ) s
-5 481 M
-( message, which has the following format:) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string handle) s
-5 437 M
-( uint64 offset) s
-5 426 M
-( uint32 len) s
-5 404 M
-( where `id' is the request identifier, `handle' is an open file handle) s
-5 393 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) relative) s
-5 382 M
-( to the beginning of the file from where to start reading, and `len') s
-5 371 M
-( is the maximum number of bytes to read.) s
-5 349 M
-( In response to this request, the server will read as many bytes as it) s
-5 338 M
-( can from the file \(up to `len'\), and return them in a SSH_FXP_DATA) s
-5 327 M
-( message. If an error occurs or EOF is encountered before reading any) s
-5 316 M
-( data, the server will respond with SSH_FXP_STATUS. For normal disk) s
-5 305 M
-( files, it is guaranteed that this will read the specified number of) s
-5 294 M
-( bytes, or up to end of file. For e.g. device files this may return) s
-5 283 M
-( fewer bytes than requested.) s
-5 261 M
-( Writing to a file is achieved using the SSH_FXP_WRITE message, which) s
-5 250 M
-( has the following format:) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string handle) s
-5 206 M
-( uint64 offset) s
-5 195 M
-( string data) s
-5 173 M
-( where `id' is a request identifier, `handle' is a file handle) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) from the) s
-5 679 M
-( beginning of the file where to start writing, and `data' is the data) s
-5 668 M
-( to be written.) s
-5 646 M
-( The write will extend the file if writing beyond the end of the file.) s
-5 635 M
-( It is legal to write way beyond the end of the file; the semantics) s
-5 624 M
-( are to write zeroes from the end of the file to the specified offset) s
-5 613 M
-( and then the data. On most operating systems, such writes do not) s
-5 602 M
-( allocate disk space but instead leave "holes" in the file.) s
-5 580 M
-( The server responds to a write request with a SSH_FXP_STATUS message.) s
-5 558 M
-(6.5 Removing and Renaming Files) s
-5 536 M
-( Files can be removed using the SSH_FXP_REMOVE message. It has the) s
-5 525 M
-( following format:) s
-5 503 M
-( uint32 id) s
-5 492 M
-( string filename) s
-5 470 M
-( where `id' is the request identifier and `filename' is the name of) s
-5 459 M
-( the file to be removed. See Section ``File Names'' for more) s
-5 448 M
-( information. This request cannot be used to remove directories.) s
-5 426 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 415 M
-( message.) s
-5 393 M
-( Files \(and directories\) can be renamed using the SSH_FXP_RENAME) s
-5 382 M
-( message. Its data is as follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( string oldpath) s
-5 338 M
-( string newpath) s
-5 316 M
-( where `id' is the request identifier, `oldpath' is the name of an) s
-5 305 M
-( existing file or directory, and `newpath' is the new name for the) s
-5 294 M
-( file or directory. It is an error if there already exists a file) s
-5 283 M
-( with the name specified by newpath. The server may also fail rename) s
-5 272 M
-( requests in other situations, for example if `oldpath' and `newpath') s
-5 261 M
-( point to different file systems on the server.) s
-5 239 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 228 M
-( message.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6.6 Creating and Deleting Directories) s
-5 668 M
-( New directories can be created using the SSH_FXP_MKDIR request. It) s
-5 657 M
-( has the following format:) s
-5 635 M
-( uint32 id) s
-5 624 M
-( string path) s
-5 613 M
-( ATTRS attrs) s
-5 591 M
-( where `id' is the request identifier, `path' and `attrs' specifies) s
-5 580 M
-( the modifications to be made to its attributes. See Section ``File) s
-5 569 M
-( Names'' for more information on file names. Attributes are discussed) s
-5 558 M
-( in more detail in Section ``File Attributes''. specifies the) s
-5 547 M
-( directory to be created. An error will be returned if a file or) s
-5 536 M
-( directory with the specified path already exists. The server will) s
-5 525 M
-( respond to this request with a SSH_FXP_STATUS message.) s
-5 503 M
-( Directories can be removed using the SSH_FXP_RMDIR request, which) s
-5 492 M
-( has the following format:) s
-5 470 M
-( uint32 id) s
-5 459 M
-( string path) s
-5 437 M
-( where `id' is the request identifier, and `path' specifies the) s
-5 426 M
-( directory to be removed. See Section ``File Names'' for more) s
-5 415 M
-( information on file names. An error will be returned if no directory) s
-5 404 M
-( with the specified path exists, or if the specified directory is not) s
-5 393 M
-( empty, or if the path specified a file system object other than a) s
-5 382 M
-( directory. The server responds to this request with a SSH_FXP_STATUS) s
-5 371 M
-( message.) s
-5 349 M
-(6.7 Scanning Directories) s
-5 327 M
-( The files in a directory can be listed using the SSH_FXP_OPENDIR and) s
-5 316 M
-( SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one) s
-5 305 M
-( or more file names with full file attributes for each file. The) s
-5 294 M
-( client should call SSH_FXP_READDIR repeatedly until it has found the) s
-5 283 M
-( file it is looking for or until the server responds with a) s
-5 272 M
-( SSH_FXP_STATUS message indicating an error \(normally SSH_FX_EOF if) s
-5 261 M
-( there are no more files in the directory\). The client should then) s
-5 250 M
-( close the handle using the SSH_FXP_CLOSE request.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The SSH_FXP_OPENDIR opens a directory for reading. It has the) s
-5 679 M
-( following format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string path) s
-5 624 M
-( where `id' is the request identifier and `path' is the path name of) s
-5 613 M
-( the directory to be listed \(without any trailing slash\). See Section) s
-5 602 M
-( ``File Names'' for more information on file names. This will return) s
-5 591 M
-( an error if the path does not specify a directory or if the directory) s
-5 580 M
-( is not readable. The server will respond to this request with either) s
-5 569 M
-( a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.) s
-5 547 M
-( Once the directory has been successfully opened, files \(and) s
-5 536 M
-( directories\) contained in it can be listed using SSH_FXP_READDIR) s
-5 525 M
-( requests. These are of the format) s
-5 503 M
-( uint32 id) s
-5 492 M
-( string handle) s
-5 470 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 459 M
-( returned by SSH_FXP_OPENDIR. \(It is a protocol error to attempt to) s
-5 448 M
-( use an ordinary file handle returned by SSH_FXP_OPEN.\)) s
-5 426 M
-( The server responds to this request with either a SSH_FXP_NAME or a) s
-5 415 M
-( SSH_FXP_STATUS message. One or more names may be returned at a time.) s
-5 404 M
-( Full status information is returned for each name in order to speed) s
-5 393 M
-( up typical directory listings.) s
-5 371 M
-( When the client no longer wishes to read more names from the) s
-5 360 M
-( directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle) s
-5 349 M
-( should be closed regardless of whether an error has occurred or not.) s
-5 327 M
-(6.8 Retrieving File Attributes) s
-5 305 M
-( Very often, file attributes are automatically returned by) s
-5 294 M
-( SSH_FXP_READDIR. However, sometimes there is need to specifically) s
-5 283 M
-( retrieve the attributes for a named file. This can be done using the) s
-5 272 M
-( SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.) s
-5 250 M
-( SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT) s
-5 239 M
-( follows symbolic links on the server, whereas SSH_FXP_LSTAT does not) s
-5 228 M
-( follow symbolic links. Both have the same format:) s
-5 206 M
-( uint32 id) s
-5 195 M
-( string path) s
-5 173 M
-( where `id' is the request identifier, and `path' specifies the file) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( system object for which status is to be returned. The server) s
-5 679 M
-( responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 657 M
-( SSH_FXP_FSTAT differs from the others in that it returns status) s
-5 646 M
-( information for an open file \(identified by the file handle\). Its) s
-5 635 M
-( format is as follows:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string handle) s
-5 580 M
-( where `id' is the request identifier and `handle' is a file handle) s
-5 569 M
-( returned by SSH_FXP_OPEN. The server responds to this request with) s
-5 558 M
-( SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 536 M
-(6.9 Setting File Attributes) s
-5 514 M
-( File attributes may be modified using the SSH_FXP_SETSTAT and) s
-5 503 M
-( SSH_FXP_FSETSTAT requests. These requests are used for operations) s
-5 492 M
-( such as changing the ownership, permissions or access times, as well) s
-5 481 M
-( as for truncating a file.) s
-5 459 M
-( The SSH_FXP_SETSTAT request is of the following format:) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string path) s
-5 415 M
-( ATTRS attrs) s
-5 393 M
-( where `id' is the request identifier, `path' specifies the file) s
-5 382 M
-( system object \(e.g. file or directory\) whose attributes are to be) s
-5 371 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 360 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 349 M
-( ``File Attributes''.) s
-5 327 M
-( An error will be returned if the specified file system object does) s
-5 316 M
-( not exist or the user does not have sufficient rights to modify the) s
-5 305 M
-( specified attributes. The server responds to this request with a) s
-5 294 M
-( SSH_FXP_STATUS message.) s
-5 272 M
-( The SSH_FXP_FSETSTAT request modifies the attributes of a file which) s
-5 261 M
-( is already open. It has the following format:) s
-5 239 M
-( uint32 id) s
-5 228 M
-( string handle) s
-5 217 M
-( ATTRS attrs) s
-5 195 M
-( where `id' is the request identifier, `handle' \(MUST be returned by) s
-5 184 M
-( SSH_FXP_OPEN\) identifies the file whose attributes are to be) s
-5 173 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 679 M
-( ``File Attributes''. The server will respond to this request with) s
-5 668 M
-( SSH_FXP_STATUS.) s
-5 646 M
-(6.10 Dealing with Symbolic links) s
-5 624 M
-( The SSH_FXP_READLINK request may be used to read the target of a) s
-5 613 M
-( symbolic link. It would have a data part as follows:) s
-5 591 M
-( uint32 id) s
-5 580 M
-( string path) s
-5 558 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 547 M
-( name of the symlink to be read.) s
-5 525 M
-( The server will respond with a SSH_FXP_NAME packet containing only) s
-5 514 M
-( one name and a dummy attributes value. The name in the returned) s
-5 503 M
-( packet contains the target of the link. If an error occurs, the) s
-5 492 M
-( server may respond with SSH_FXP_STATUS.) s
-5 470 M
-( The SSH_FXP_SYMLINK request will create a symbolic link on the) s
-5 459 M
-( server. It is of the following format) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string linkpath) s
-5 415 M
-( string targetpath) s
-5 393 M
-( where `id' is the request identifier, `linkpath' specifies the path) s
-5 382 M
-( name of the symlink to be created and `targetpath' specifies the) s
-5 371 M
-( target of the symlink. The server shall respond with a) s
-5 360 M
-( SSH_FXP_STATUS indicating either success \(SSH_FX_OK\) or an error) s
-5 349 M
-( condition.) s
-5 327 M
-(6.11 Canonicalizing the Server-Side Path Name) s
-5 305 M
-( The SSH_FXP_REALPATH request can be used to have the server) s
-5 294 M
-( canonicalize any given path name to an absolute path. This is useful) s
-5 283 M
-( for converting path names containing ".." components or relative) s
-5 272 M
-( pathnames without a leading slash into absolute paths. The format of) s
-5 261 M
-( the request is as follows:) s
-5 239 M
-( uint32 id) s
-5 228 M
-( string path) s
-5 206 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 195 M
-( name to be canonicalized. The server will respond with a) s
-5 184 M
-( SSH_FXP_NAME packet containing only one name and a dummy attributes) s
-5 173 M
-( value. The name is the returned packet will be in canonical form.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( If an error occurs, the server may also respond with SSH_FXP_STATUS.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(7. Responses from the Server to the Client) s
-5 668 M
-( The server responds to the client using one of a few response) s
-5 657 M
-( packets. All requests can return a SSH_FXP_STATUS response upon) s
-5 646 M
-( failure. When the operation is successful, any of the responses may) s
-5 635 M
-( be returned \(depending on the operation\). If no data needs to be) s
-5 624 M
-( returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK) s
-5 613 M
-( status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used) s
-5 602 M
-( to return a file handle \(for SSH_FXP_OPEN and SSH_FXP_OPENDIR) s
-5 591 M
-( requests\), SSH_FXP_DATA is used to return data from SSH_FXP_READ,) s
-5 580 M
-( SSH_FXP_NAME is used to return one or more file names from a) s
-5 569 M
-( SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is) s
-5 558 M
-( used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and) s
-5 547 M
-( SSH_FXP_FSTAT requests.) s
-5 525 M
-( Exactly one response will be returned for each request. Each) s
-5 514 M
-( response packet contains a request identifier which can be used to) s
-5 503 M
-( match each response with the corresponding request. Note that it is) s
-5 492 M
-( legal to have several requests outstanding simultaneously, and the) s
-5 481 M
-( server is allowed to send responses to them in a different order from) s
-5 470 M
-( the order in which the requests were sent \(the result of their) s
-5 459 M
-( execution, however, is guaranteed to be as if they had been processed) s
-5 448 M
-( one at a time in the order in which the requests were sent\).) s
-5 426 M
-( Response packets are of the same general format as request packets.) s
-5 415 M
-( Each response packet begins with the request identifier.) s
-5 393 M
-( The format of the data portion of the SSH_FXP_STATUS response is as) s
-5 382 M
-( follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( uint32 error/status code) s
-5 338 M
-( string error message \(ISO-10646 UTF-8 [RFC-2279]\)) s
-5 327 M
-( string language tag \(as defined in [RFC-1766]\)) s
-5 305 M
-( where `id' is the request identifier, and `error/status code') s
-5 294 M
-( indicates the result of the requested operation. The value SSH_FX_OK) s
-5 283 M
-( indicates success, and all other values indicate failure.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( Currently, the following values are defined \(other values may be) s
-5 679 M
-( defined by future versions of this protocol\):) s
-5 657 M
-( #define SSH_FX_OK 0) s
-5 646 M
-( #define SSH_FX_EOF 1) s
-5 635 M
-( #define SSH_FX_NO_SUCH_FILE 2) s
-5 624 M
-( #define SSH_FX_PERMISSION_DENIED 3) s
-5 613 M
-( #define SSH_FX_FAILURE 4) s
-5 602 M
-( #define SSH_FX_BAD_MESSAGE 5) s
-5 591 M
-( #define SSH_FX_NO_CONNECTION 6) s
-5 580 M
-( #define SSH_FX_CONNECTION_LOST 7) s
-5 569 M
-( #define SSH_FX_OP_UNSUPPORTED 8) s
-5 547 M
-( SSH_FX_OK) s
-5 536 M
-( Indicates successful completion of the operation.) s
-5 514 M
-( SSH_FX_EOF) s
-5 503 M
-( indicates end-of-file condition; for SSH_FX_READ it means that no) s
-5 492 M
-( more data is available in the file, and for SSH_FX_READDIR it) s
-5 481 M
-( indicates that no more files are contained in the directory.) s
-5 459 M
-( SSH_FX_NO_SUCH_FILE) s
-5 448 M
-( is returned when a reference is made to a file which should exist) s
-5 437 M
-( but doesn't.) s
-5 415 M
-( SSH_FX_PERMISSION_DENIED) s
-5 404 M
-( is returned when the authenticated user does not have sufficient) s
-5 393 M
-( permissions to perform the operation.) s
-5 371 M
-( SSH_FX_FAILURE) s
-5 360 M
-( is a generic catch-all error message; it should be returned if an) s
-5 349 M
-( error occurs for which there is no more specific error code) s
-5 338 M
-( defined.) s
-5 316 M
-( SSH_FX_BAD_MESSAGE) s
-5 305 M
-( may be returned if a badly formatted packet or protocol) s
-5 294 M
-( incompatibility is detected.) s
-5 272 M
-( SSH_FX_NO_CONNECTION) s
-5 261 M
-( is a pseudo-error which indicates that the client has no) s
-5 250 M
-( connection to the server \(it can only be generated locally by the) s
-5 239 M
-( client, and MUST NOT be returned by servers\).) s
-5 217 M
-( SSH_FX_CONNECTION_LOST) s
-5 206 M
-( is a pseudo-error which indicates that the connection to the) s
-5 195 M
-( server has been lost \(it can only be generated locally by the) s
-5 184 M
-( client, and MUST NOT be returned by servers\).) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( SSH_FX_OP_UNSUPPORTED) s
-5 679 M
-( indicates that an attempt was made to perform an operation which) s
-5 668 M
-( is not supported for the server \(it may be generated locally by) s
-5 657 M
-( the client if e.g. the version number exchange indicates that a) s
-5 646 M
-( required feature is not supported by the server, or it may be) s
-5 635 M
-( returned by the server if the server does not implement an) s
-5 624 M
-( operation\).) s
-5 602 M
-( The SSH_FXP_HANDLE response has the following format:) s
-5 580 M
-( uint32 id) s
-5 569 M
-( string handle) s
-5 547 M
-( where `id' is the request identifier, and `handle' is an arbitrary) s
-5 536 M
-( string that identifies an open file or directory on the server. The) s
-5 525 M
-( handle is opaque to the client; the client MUST NOT attempt to) s
-5 514 M
-( interpret or modify it in any way. The length of the handle string) s
-5 503 M
-( MUST NOT exceed 256 data bytes.) s
-5 481 M
-( The SSH_FXP_DATA response has the following format:) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string data) s
-5 426 M
-( where `id' is the request identifier, and `data' is an arbitrary byte) s
-5 415 M
-( string containing the requested data. The data string may be at most) s
-5 404 M
-( the number of bytes requested in a SSH_FXP_READ request, but may also) s
-5 393 M
-( be shorter if end of file is reached or if the read is from something) s
-5 382 M
-( other than a regular file.) s
-5 360 M
-( The SSH_FXP_NAME response has the following format:) s
-5 338 M
-( uint32 id) s
-5 327 M
-( uint32 count) s
-5 316 M
-( repeats count times:) s
-5 305 M
-( string filename) s
-5 294 M
-( string longname) s
-5 283 M
-( ATTRS attrs) s
-5 261 M
-( where `id' is the request identifier, `count' is the number of names) s
-5 250 M
-( returned in this response, and the remaining fields repeat `count') s
-5 239 M
-( times \(so that all three fields are first included for the first) s
-5 228 M
-( file, then for the second file, etc\). In the repeated part,) s
-5 217 M
-( `filename' is a file name being returned \(for SSH_FXP_READDIR, it) s
-5 206 M
-( will be a relative name within the directory, without any path) s
-5 195 M
-( components; for SSH_FXP_REALPATH it will be an absolute path name\),) s
-5 184 M
-( `longname' is an expanded format for the file name, similar to what) s
-5 173 M
-( is returned by "ls -l" on Unix systems, and `attrs' is the attributes) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( of the file as described in Section ``File Attributes''.) s
-5 668 M
-( The format of the `longname' field is unspecified by this protocol.) s
-5 657 M
-( It MUST be suitable for use in the output of a directory listing) s
-5 646 M
-( command \(in fact, the recommended operation for a directory listing) s
-5 635 M
-( command is to simply display this data\). However, clients SHOULD NOT) s
-5 624 M
-( attempt to parse the longname field for file attributes; they SHOULD) s
-5 613 M
-( use the attrs field instead.) s
-5 591 M
-( The recommended format for the longname field is as follows:) s
-5 569 M
-( -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer) s
-5 558 M
-( 1234567890 123 12345678 12345678 12345678 123456789012) s
-5 536 M
-( Here, the first line is sample output, and the second field indicates) s
-5 525 M
-( widths of the various fields. Fields are separated by spaces. The) s
-5 514 M
-( first field lists file permissions for user, group, and others; the) s
-5 503 M
-( second field is link count; the third field is the name of the user) s
-5 492 M
-( who owns the file; the fourth field is the name of the group that) s
-5 481 M
-( owns the file; the fifth field is the size of the file in bytes; the) s
-5 470 M
-( sixth field \(which actually may contain spaces, but is fixed to 12) s
-5 459 M
-( characters\) is the file modification time, and the seventh field is) s
-5 448 M
-( the file name. Each field is specified to be a minimum of certain) s
-5 437 M
-( number of character positions \(indicated by the second line above\),) s
-5 426 M
-( but may also be longer if the data does not fit in the specified) s
-5 415 M
-( length.) s
-5 393 M
-( The SSH_FXP_ATTRS response has the following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ATTRS attrs) s
-5 338 M
-( where `id' is the request identifier, and `attrs' is the returned) s
-5 327 M
-( file attributes as described in Section ``File Attributes''.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(8. Vendor-Specific Extensions) s
-5 668 M
-( The SSH_FXP_EXTENDED request provides a generic extension mechanism) s
-5 657 M
-( for adding vendor-specific commands. The request has the following) s
-5 646 M
-( format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string extended-request) s
-5 602 M
-( ... any request-specific data ...) s
-5 580 M
-( where `id' is the request identifier, and `extended-request' is a) s
-5 569 M
-( string of the format "name@domain", where domain is an internet) s
-5 558 M
-( domain name of the vendor defining the request. The rest of the) s
-5 547 M
-( request is completely vendor-specific, and servers should only) s
-5 536 M
-( attempt to interpret it if they recognize the `extended-request') s
-5 525 M
-( name.) s
-5 503 M
-( The server may respond to such requests using any of the response) s
-5 492 M
-( packets defined in Section ``Responses from the Server to the) s
-5 481 M
-( Client''. Additionally, the server may also respond with a) s
-5 470 M
-( SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does) s
-5 459 M
-( not recognize the `extended-request' name, then the server MUST) s
-5 448 M
-( respond with SSH_FXP_STATUS with error/status set to) s
-5 437 M
-( SSH_FX_OP_UNSUPPORTED.) s
-5 415 M
-( The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary) s
-5 404 M
-( extension-specific data from the server to the client. It is of the) s
-5 393 M
-( following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ... any request-specific data ...) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(9. Security Considerations) s
-5 668 M
-( This protocol assumes that it is run over a secure channel and that) s
-5 657 M
-( the endpoints of the channel have been authenticated. Thus, this) s
-5 646 M
-( protocol assumes that it is externally protected from network-level) s
-5 635 M
-( attacks.) s
-5 613 M
-( This protocol provides file system access to arbitrary files on the) s
-5 602 M
-( server \(only constrained by the server implementation\). It is the) s
-5 591 M
-( responsibility of the server implementation to enforce any access) s
-5 580 M
-( controls that may be required to limit the access allowed for any) s
-5 569 M
-( particular user \(the user being authenticated externally to this) s
-5 558 M
-( protocol, typically using the SSH User Authentication Protocol [6].) s
-5 536 M
-( Care must be taken in the server implementation to check the validity) s
-5 525 M
-( of received file handle strings. The server should not rely on them) s
-5 514 M
-( directly; it MUST check the validity of each handle before relying on) s
-5 503 M
-( it.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(10. Changes from previous protocol versions) s
-5 668 M
-( The SSH File Transfer Protocol has changed over time, before it's) s
-5 657 M
-( standardization. The following is a description of the incompatible) s
-5 646 M
-( changes between different versions.) s
-5 624 M
-(10.1 Changes between versions 3 and 2) s
-5 602 M
-( o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.) s
-5 580 M
-( o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were) s
-5 569 M
-( added.) s
-5 547 M
-( o The SSH_FXP_STATUS message was changed to include fields `error) s
-5 536 M
-( message' and `language tag'.) s
-5 503 M
-(10.2 Changes between versions 2 and 1) s
-5 481 M
-( o The SSH_FXP_RENAME message was added.) s
-5 448 M
-(10.3 Changes between versions 1 and 0) s
-5 426 M
-( o Implementation changes, no actual protocol changes.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(11. Trademark Issues) s
-5 668 M
-( "ssh" is a registered trademark of SSH Communications Security Corp) s
-5 657 M
-( in the United States and/or other countries.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(References) s
-5 668 M
-( [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and) s
-5 657 M
-( P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January) s
-5 646 M
-( 1999.) s
-5 624 M
-( [2] Institute of Electrical and Electronics Engineers, "Information) s
-5 613 M
-( Technology - Portable Operating System Interface \(POSIX\) - Part) s
-5 602 M
-( 1: System Application Program Interface \(API\) [C Language]",) s
-5 591 M
-( IEEE Standard 1003.2, 1996.) s
-5 569 M
-( [3] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 558 M
-( Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-) s
-5 547 M
-( architecture-09 \(work in progress\), July 2001.) s
-5 525 M
-( [4] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 514 M
-( Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-) s
-5 503 M
-( architecture-09 \(work in progress\), July 2001.) s
-5 481 M
-( [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 470 M
-( Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-11) s
-5 459 M
-( \(work in progress\), July 2001.) s
-5 437 M
-( [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 426 M
-( Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-) s
-5 415 M
-( userauth-11 \(work in progress\), July 2001.) s
-5 382 M
-(Authors' Addresses) s
-5 360 M
-( Tatu Ylonen) s
-5 349 M
-( SSH Communications Security Corp) s
-5 338 M
-( Fredrikinkatu 42) s
-5 327 M
-( HELSINKI FIN-00100) s
-5 316 M
-( Finland) s
-5 294 M
-( EMail: [email protected]) s
-5 261 M
-( Sami Lehtinen) s
-5 250 M
-( SSH Communications Security Corp) s
-5 239 M
-( Fredrikinkatu 42) s
-5 228 M
-( HELSINKI FIN-00100) s
-5 217 M
-( Finland) s
-5 195 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(Full Copyright Statement) s
-5 668 M
-( Copyright \(C\) The Internet Society \(2001\). All Rights Reserved.) s
-5 646 M
-( This document and translations of it may be copied and furnished to) s
-5 635 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 624 M
-( or assist in its implementation may be prepared, copied, published) s
-5 613 M
-( and distributed, in whole or in part, without restriction of any) s
-5 602 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 591 M
-( included on all such copies and derivative works. However, this) s
-5 580 M
-( document itself may not be modified in any way, such as by removing) s
-5 569 M
-( the copyright notice or references to the Internet Society or other) s
-5 558 M
-( Internet organizations, except as needed for the purpose of) s
-5 547 M
-( developing Internet standards in which case the procedures for) s
-5 536 M
-( copyrights defined in the Internet Standards process must be) s
-5 525 M
-( followed, or as required to translate it into languages other than) s
-5 514 M
-( English.) s
-5 492 M
-( The limited permissions granted above are perpetual and will not be) s
-5 481 M
-( revoked by the Internet Society or its successors or assigns.) s
-5 459 M
-( This document and the information contained herein is provided on an) s
-5 448 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 437 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 426 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 415 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 404 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 382 M
-(Acknowledgement) s
-5 360 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 349 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 30 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 30
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt
deleted file mode 100644
index c4ec8c1125..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt
+++ /dev/null
@@ -1,1627 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft S. Lehtinen
-Expires: April 1, 2002 SSH Communications Security Corp
- October 2001
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-02.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on April 1, 2002.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . . 5
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . . 7
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . . 8
- 6. Requests From the Client to the Server . . . . . . . . . . . 10
- 6.1 Request Synchronization and Reordering . . . . . . . . . . . 10
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . . 11
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . . 13
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . . 14
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . . 15
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . . 15
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . . 16
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . . 17
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . . 18
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . . 18
- 7. Responses from the Server to the Client . . . . . . . . . . 20
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . . 24
- 9. Security Considerations . . . . . . . . . . . . . . . . . . 25
- 10. Changes from previous protocol versions . . . . . . . . . . 26
- 10.1 Changes between versions 3 and 2 . . . . . . . . . . . . . . 26
- 10.2 Changes between versions 2 and 1 . . . . . . . . . . . . . . 26
- 10.3 Changes between versions 1 and 0 . . . . . . . . . . . . . . 26
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . . 27
- References . . . . . . . . . . . . . . . . . . . . . . . . . 28
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 28
- Full Copyright Statement . . . . . . . . . . . . . . . . . . 29
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [3].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft.[3].
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [5] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The following values are defined for packet types.
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, it first sends a SSH_FXP_INIT
- (including its version number) packet to the server. The server
- responds with a SSH_FXP_VERSION packet, supplying the lowest of its
- own and the client's version number. Both parties should from then
- on adhere to particular version of the protocol.
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
- <extension data>
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- The version number of the protocol specified in this document is 3.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
- The extension data in the above packets may be empty, or may be a
- sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes. It
- is basically just a combination of elementary types, but is defined
- once because of the non-trivial description of the fields and to
- ensure maintainability.
-
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID
- uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID
- uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- uint32 atime present only if flag SSH_FILEXFER_ACMODTIME
- uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME
- uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The `size' field specifies the size of the file in bytes.
-
- The `uid' and `gid' fields contain numeric Unix-like user and group
- identifiers, respectively.
-
- The `permissions' field contains a bit mask of file permissions as
- defined by posix [1].
-
- The `atime' and `mtime' contain the access and modification times of
- the files, respectively. They are represented as seconds from Jan 1,
- 1970 in UTC.
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_UIDGID 0x00000002
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation of it is a monotonically increasing
- request sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
- uint32 id
- string filename
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
- Regardless the server operating system, the file will always be
- opened in "binary" mode (i.e., no translations between different
- character sets and newline encodings).
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the SSH_FXP_READ
- message, which has the following format:
-
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS. For normal disk
- files, it is guaranteed that this will read the specified number of
- bytes, or up to end of file. For e.g. device files this may return
- fewer bytes than requested.
-
- Writing to a file is achieved using the SSH_FXP_WRITE message, which
- has the following format:
-
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath
- string newpath
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path
- ATTRS attrs
-
- where `id' is the request identifier, `path' and `attrs' specifies
- the modifications to be made to its attributes. See Section ``File
- Names'' for more information on file names. Attributes are discussed
- in more detail in Section ``File Attributes''. specifies the
- directory to be created. An error will be returned if a file or
- directory with the specified path already exists. The server will
- respond to this request with a SSH_FXP_STATUS message.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which
- has the following format:
-
- uint32 id
- string path
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names. An error will be returned if no directory
- with the specified path exists, or if the specified directory is not
- empty, or if the path specified a file system object other than a
- directory. The server responds to this request with a SSH_FXP_STATUS
- message.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path
-
- where `id' is the request identifier, and `path' specifies the file
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
- uint32 id
- string path
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
- uint32 id
- string linkpath
- string targetpath
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing only one name and a dummy attributes
- value. The name is the returned packet will be in canonical form.
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- If an error occurs, the server may also respond with SSH_FXP_STATUS.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which should exist
- but doesn't.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
- The SSH_FXP_NAME response has the following format:
-
- uint32 id
- uint32 count
- repeats count times:
- string filename
- string longname
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- `longname' is an expanded format for the file name, similar to what
- is returned by "ls -l" on Unix systems, and `attrs' is the attributes
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- of the file as described in Section ``File Attributes''.
-
- The format of the `longname' field is unspecified by this protocol.
- It MUST be suitable for use in the output of a directory listing
- command (in fact, the recommended operation for a directory listing
- command is to simply display this data). However, clients SHOULD NOT
- attempt to parse the longname field for file attributes; they SHOULD
- use the attrs field instead.
-
- The recommended format for the longname field is as follows:
-
- -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
- 1234567890 123 12345678 12345678 12345678 123456789012
-
- Here, the first line is sample output, and the second field indicates
- widths of the various fields. Fields are separated by spaces. The
- first field lists file permissions for user, group, and others; the
- second field is link count; the third field is the name of the user
- who owns the file; the fourth field is the name of the group that
- owns the file; the fifth field is the size of the file in bytes; the
- sixth field (which actually may contain spaces, but is fixed to 12
- characters) is the file modification time, and the seventh field is
- the file name. Each field is specified to be a minimum of certain
- number of character positions (indicated by the second line above),
- but may also be longer if the data does not fit in the specified
- length.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [6].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.2 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.3 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [3] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-
- architecture-09 (work in progress), July 2001.
-
- [4] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-
- architecture-09 (work in progress), July 2001.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-11
- (work in progress), July 2001.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-
- userauth-11 (work in progress), July 2001.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 29]
-
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps
deleted file mode 100644
index 6a40cd6067..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps
+++ /dev/null
@@ -1,3511 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Wed Nov 12 12:18:50 2003
-%%Orientation: Portrait
-%%Pages: 18 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Secure Shell Working Group J. Galbraith) s
-5 690 M
-(Internet-Draft VanDyke Software) s
-5 679 M
-(Expires: April 16, 2003 T. Ylonen) s
-5 668 M
-( S. Lehtinen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( October 16, 2002) s
-5 613 M
-( SSH File Transfer Protocol) s
-5 602 M
-( draft-ietf-secsh-filexfer-03.txt) s
-5 580 M
-(Status of this Memo) s
-5 558 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 547 M
-( all provisions of Section 10 of RFC2026.) s
-5 525 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 514 M
-( Task Force \(IETF\), its areas, and its working groups. Note that) s
-5 503 M
-( other groups may also distribute working documents as Internet-) s
-5 492 M
-( Drafts.) s
-5 470 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 459 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 448 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 437 M
-( material or to cite them other than as "work in progress.") s
-5 415 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 404 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 382 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 371 M
-( http://www.ietf.org/shadow.html.) s
-5 349 M
-( This Internet-Draft will expire on April 16, 2003.) s
-5 327 M
-(Copyright Notice) s
-5 305 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 283 M
-(Abstract) s
-5 261 M
-( The SSH File Transfer Protocol provides secure file transfer) s
-5 250 M
-( functionality over any reliable data stream. It is the standard file) s
-5 239 M
-( transfer protocol for use with the SSH2 protocol. This document) s
-5 228 M
-( describes the file transfer protocol and its interface to the SSH2) s
-5 217 M
-( protocol suite.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4) s
-5 646 M
-( 3. General Packet Format . . . . . . . . . . . . . . . . . . 5) s
-5 635 M
-( 4. Protocol Initialization . . . . . . . . . . . . . . . . . 7) s
-5 624 M
-( 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 613 M
-( 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 602 M
-( 4.3 Determining Server Newline Convention . . . . . . . . . . 8) s
-5 591 M
-( 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 9) s
-5 580 M
-( 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 569 M
-( 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 558 M
-( 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 547 M
-( 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 10) s
-5 536 M
-( 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 525 M
-( 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 514 M
-( 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 503 M
-( 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 12) s
-5 492 M
-( 6. Requests From the Client to the Server . . . . . . . . . . 13) s
-5 481 M
-( 6.1 Request Synchronization and Reordering . . . . . . . . . . 13) s
-5 470 M
-( 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 14) s
-5 459 M
-( 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 14) s
-5 448 M
-( 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 17) s
-5 437 M
-( 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 18) s
-5 426 M
-( 6.6 Creating and Deleting Directories . . . . . . . . . . . . 19) s
-5 415 M
-( 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 19) s
-5 404 M
-( 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 20) s
-5 393 M
-( 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 21) s
-5 382 M
-( 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 22) s
-5 371 M
-( 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 23) s
-5 360 M
-( 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 23) s
-5 349 M
-( 7. Responses from the Server to the Client . . . . . . . . . 24) s
-5 338 M
-( 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 28) s
-5 327 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . 29) s
-5 316 M
-( 10. Changes from previous protocol versions . . . . . . . . . 30) s
-5 305 M
-( 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 30) s
-5 294 M
-( 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 31) s
-5 283 M
-( 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 31) s
-5 272 M
-( 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 31) s
-5 261 M
-( 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 32) s
-5 250 M
-( References . . . . . . . . . . . . . . . . . . . . . . . . 33) s
-5 239 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . 33) s
-5 228 M
-( Full Copyright Statement . . . . . . . . . . . . . . . . . 35) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(1. Introduction) s
-5 668 M
-( This protocol provides secure file transfer \(and more generally file) s
-5 657 M
-( system access\) functionality over a reliable data stream, such as a) s
-5 646 M
-( channel in the SSH2 protocol [5].) s
-5 624 M
-( This protocol is designed so that it could be used to implement a) s
-5 613 M
-( secure remote file system service, as well as a secure file transfer) s
-5 602 M
-( service.) s
-5 580 M
-( This protocol assumes that it runs over a secure channel, and that) s
-5 569 M
-( the server has already authenticated the user at the client end, and) s
-5 558 M
-( that the identity of the client user is externally available to the) s
-5 547 M
-( server implementation.) s
-5 525 M
-( In general, this protocol follows a simple request-response model.) s
-5 514 M
-( Each request and response contains a sequence number and multiple) s
-5 503 M
-( requests may be pending simultaneously. There are a relatively large) s
-5 492 M
-( number of different request messages, but a small number of possible) s
-5 481 M
-( response messages. Each request has one or more response messages) s
-5 470 M
-( that may be returned in result \(e.g., a read either returns data or) s
-5 459 M
-( reports error status\).) s
-5 437 M
-( The packet format descriptions in this specification follow the) s
-5 426 M
-( notation presented in the secsh architecture draft. [5]) s
-5 404 M
-( Even though this protocol is described in the context of the SSH2) s
-5 393 M
-( protocol, this protocol is general and independent of the rest of the) s
-5 382 M
-( SSH2 protocol suite. It could be used in a number of different) s
-5 371 M
-( applications, such as secure file transfer over TLS RFC 2246 [1] and) s
-5 360 M
-( transfer of management information in VPN applications.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(2. Use with the SSH Connection Protocol) s
-5 668 M
-( When used with the SSH2 Protocol suite, this protocol is intended to) s
-5 657 M
-( be used from the SSH Connection Protocol [7] as a subsystem, as) s
-5 646 M
-( described in section ``Starting a Shell or a Command''. The) s
-5 635 M
-( subsystem name used with this protocol is "sftp".) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(3. General Packet Format) s
-5 668 M
-( All packets transmitted over the secure connection are of the) s
-5 657 M
-( following format:) s
-5 635 M
-( uint32 length) s
-5 624 M
-( byte type) s
-5 613 M
-( byte[length - 1] data payload) s
-5 591 M
-( That is, they are just data preceded by 32-bit length and 8-bit type) s
-5 580 M
-( fields. The `length' is the length of the data area, and does not) s
-5 569 M
-( include the `length' field itself. The format and interpretation of) s
-5 558 M
-( the data area depends on the packet type.) s
-5 536 M
-( All packet descriptions below only specify the packet type and the) s
-5 525 M
-( data that goes into the data field. Thus, they should be prefixed by) s
-5 514 M
-( the `length' and `type' fields.) s
-5 492 M
-( The maximum size of a packet is in practice determined by the client) s
-5 481 M
-( \(the maximum size of read or write requests that it sends, plus a few) s
-5 470 M
-( bytes of packet overhead\). All servers SHOULD support packets of at) s
-5 459 M
-( least 34000 bytes \(where the packet size refers to the full length,) s
-5 448 M
-( including the header above\). This should allow for reads and writes) s
-5 437 M
-( of at most 32768 bytes.) s
-5 415 M
-( There is no limit on the number of outstanding \(non-acknowledged\)) s
-5 404 M
-( requests that the client may send to the server. In practice this is) s
-5 393 M
-( limited by the buffering available on the data stream and the queuing) s
-5 382 M
-( performed by the server. If the server's queues are full, it should) s
-5 371 M
-( not read any more data from the stream, and flow control will prevent) s
-5 360 M
-( the client from sending more requests. Note, however, that while) s
-5 349 M
-( there is no restriction on the protocol level, the client's API may) s
-5 338 M
-( provide a limit in order to prevent infinite queuing of outgoing) s
-5 327 M
-( requests at the client.) s
-5 305 M
-( The following values are defined for packet types.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( #define SSH_FXP_INIT 1) s
-5 679 M
-( #define SSH_FXP_VERSION 2) s
-5 668 M
-( #define SSH_FXP_OPEN 3) s
-5 657 M
-( #define SSH_FXP_CLOSE 4) s
-5 646 M
-( #define SSH_FXP_READ 5) s
-5 635 M
-( #define SSH_FXP_WRITE 6) s
-5 624 M
-( #define SSH_FXP_LSTAT 7) s
-5 613 M
-( #define SSH_FXP_FSTAT 8) s
-5 602 M
-( #define SSH_FXP_SETSTAT 9) s
-5 591 M
-( #define SSH_FXP_FSETSTAT 10) s
-5 580 M
-( #define SSH_FXP_OPENDIR 11) s
-5 569 M
-( #define SSH_FXP_READDIR 12) s
-5 558 M
-( #define SSH_FXP_REMOVE 13) s
-5 547 M
-( #define SSH_FXP_MKDIR 14) s
-5 536 M
-( #define SSH_FXP_RMDIR 15) s
-5 525 M
-( #define SSH_FXP_REALPATH 16) s
-5 514 M
-( #define SSH_FXP_STAT 17) s
-5 503 M
-( #define SSH_FXP_RENAME 18) s
-5 492 M
-( #define SSH_FXP_READLINK 19) s
-5 481 M
-( #define SSH_FXP_SYMLINK 20) s
-5 459 M
-( #define SSH_FXP_STATUS 101) s
-5 448 M
-( #define SSH_FXP_HANDLE 102) s
-5 437 M
-( #define SSH_FXP_DATA 103) s
-5 426 M
-( #define SSH_FXP_NAME 104) s
-5 415 M
-( #define SSH_FXP_ATTRS 105) s
-5 393 M
-( #define SSH_FXP_EXTENDED 200) s
-5 382 M
-( #define SSH_FXP_EXTENDED_REPLY 201) s
-5 360 M
-( RESERVED_FOR_EXTENSIONS 210-255) s
-5 338 M
-( Additional packet types should only be defined if the protocol) s
-5 327 M
-( version number \(see Section ``Protocol Initialization''\) is) s
-5 316 M
-( incremented, and their use MUST be negotiated using the version) s
-5 305 M
-( number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY) s
-5 294 M
-( packets can be used to implement vendor-specific extensions. See) s
-5 283 M
-( Section ``Vendor-Specific-Extensions'' for more details.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(4. Protocol Initialization) s
-5 668 M
-( When the file transfer protocol starts, the client first sends a) s
-5 657 M
-( SSH_FXP_INIT \(including its version number\) packet to the server.) s
-5 646 M
-( The server responds with a SSH_FXP_VERSION packet, supplying the) s
-5 635 M
-( lowest of its own and the client's version number. Both parties) s
-5 624 M
-( should from then on adhere to particular version of the protocol.) s
-5 602 M
-( The version number of the protocol specified in this document is 4.) s
-5 591 M
-( The version number should be incremented for each incompatible) s
-5 580 M
-( revision of this protocol.) s
-5 558 M
-(4.1 Client Initialization) s
-5 536 M
-( The SSH_FXP_INIT packet \(from client to server\) has the following) s
-5 525 M
-( data:) s
-5 503 M
-( uint32 version) s
-5 481 M
-( Version 3 of this protocol allowed clients to include extensions in) s
-5 470 M
-( the SSH_FXP_INIT packet; however, this can cause interoperability) s
-5 459 M
-( problems with version 1 and version 2 servers because the client must) s
-5 448 M
-( send this packet before knowing the servers version.) s
-5 426 M
-( In this version of the protocol, clients MUST use the) s
-5 415 M
-( SSH_FXP_EXTENDED packet to send extensions to the server after) s
-5 404 M
-( version exchange has completed. Clients MUST NOT include extensions) s
-5 393 M
-( in the version packet. This will prevent interoperability problems) s
-5 382 M
-( with older servers) s
-5 360 M
-(4.2 Server Initialization) s
-5 338 M
-( The SSH_FXP_VERSION packet \(from server to client\) has the following) s
-5 327 M
-( data:) s
-5 305 M
-( uint32 version) s
-5 294 M
-( <extension data>) s
-5 272 M
-( 'version' is the lower of the protocol version supported by the) s
-5 261 M
-( server and the version number received from the client.) s
-5 239 M
-( The extension data may be empty, or may be a sequence of) s
-5 217 M
-( string extension_name) s
-5 206 M
-( string extension_data) s
-5 184 M
-( pairs \(both strings MUST always be present if one is, but the) s
-5 173 M
-( `extension_data' string may be of zero length\). If present, these) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( strings indicate extensions to the baseline protocol. The) s
-5 679 M
-( `extension_name' field\(s\) identify the name of the extension. The) s
-5 668 M
-( name should be of the form "name@domain", where the domain is the DNS) s
-5 657 M
-( domain name of the organization defining the extension. Additional) s
-5 646 M
-( names that are not of this format may be defined later by the IETF.) s
-5 635 M
-( Implementations MUST silently ignore any extensions whose name they) s
-5 624 M
-( do not recognize.) s
-5 602 M
-(4.3 Determining Server Newline Convention) s
-5 580 M
-( In order to correctly process text files in a cross platform) s
-5 569 M
-( compatible way, the newline convention must be converted from that of) s
-5 558 M
-( the server to that of the client, or, during an upload, from that of) s
-5 547 M
-( the client to that of the server.) s
-5 525 M
-( Versions 3 and prior of this protocol made no provisions for) s
-5 514 M
-( processing text files. Many clients implemented some sort of) s
-5 503 M
-( conversion algorithm, but without either a 'canonical' on the wire) s
-5 492 M
-( format or knowledge of the servers newline convention, correct) s
-5 481 M
-( conversion was not always possible.) s
-5 459 M
-( Starting with Version 4, the SSH_FXF_TEXT file open flag \(Section) s
-5 448 M
-( 6.3\) makes it possible to request that the server translate a file to) s
-5 437 M
-( a 'canonical' on the wire format. This format uses \\r\\n as the line) s
-5 426 M
-( separator.) s
-5 404 M
-( Servers for systems using multiple newline characters \(for example,) s
-5 393 M
-( Mac OS X or VMS\) or systems using counted records, MUST translate to) s
-5 382 M
-( the canonical form.) s
-5 360 M
-( However, to ease the burden of implementation on servers that use a) s
-5 349 M
-( single, simple separator sequence, the following extension allows the) s
-5 338 M
-( canonical format to be changed.) s
-5 316 M
-( string "newline") s
-5 305 M
-( string new-canonical-separator \(usually "\\r" or "\\n" or "\\r\\n"\)) s
-5 283 M
-( All clients MUST support this extension.) s
-5 261 M
-( When processing text files, clients SHOULD NOT translate any) s
-5 250 M
-( character or sequence that is not an exact match of the servers) s
-5 239 M
-( newline separator.) s
-5 217 M
-( In particular, if the newline sequence being used is the canonical) s
-5 206 M
-( "\\r\\n" sequence, a lone \\r or a lone \\n SHOULD be written through) s
-5 195 M
-( without change.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(5. File Attributes) s
-5 668 M
-( A new compound data type is defined for encoding file attributes.) s
-5 657 M
-( The same encoding is used both when returning file attributes from) s
-5 646 M
-( the server and when sending file attributes to the server. When) s
-5 635 M
-( sending it to the server, the flags field specifies which attributes) s
-5 624 M
-( are included, and the server will use default values for the) s
-5 613 M
-( remaining attributes \(or will not modify the values of remaining) s
-5 602 M
-( attributes\). When receiving attributes from the server, the flags) s
-5 591 M
-( specify which attributes are included in the returned data. The) s
-5 580 M
-( server normally returns all attributes it knows about.) s
-5 558 M
-( uint32 flags) s
-5 547 M
-( byte type always present) s
-5 536 M
-( uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE) s
-5 525 M
-( string owner present only if flag SSH_FILEXFER_ATTR_OWNERGROUP) s
-5 514 M
-( string group present only if flag SSH_FILEXFER_ATTR_OWNERGROUP) s
-5 503 M
-( uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS) s
-5 492 M
-( uint32 atime present only if flag SSH_FILEXFER_ATTR_ACCESSTIME) s
-5 481 M
-( uint32 createtime present only if flag SSH_FILEXFER_ATTR_CREATETIME) s
-5 470 M
-( uint32 mtime present only if flag SSH_FILEXFER_ATTR_MODIFYTIME) s
-5 459 M
-( string acl present only if flag SSH_FILEXFER_ATTR_ACL) s
-5 448 M
-( uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED) s
-5 437 M
-( string extended_type) s
-5 426 M
-( string extended_data) s
-5 415 M
-( ... more extended data \(extended_type - extended_data pairs\),) s
-5 404 M
-( so that number of pairs equals extended_count) s
-5 371 M
-(5.1 Flags) s
-5 349 M
-( The `flags' specify which of the fields are present. Those fields) s
-5 338 M
-( for which the corresponding flag is not set are not present \(not) s
-5 327 M
-( included in the packet\). New flags can only be added by incrementing) s
-5 316 M
-( the protocol version number \(or by using the extension mechanism) s
-5 305 M
-( described below\).) s
-5 283 M
-( The flags bits are defined to have the following values:) s
-5 261 M
-( #define SSH_FILEXFER_ATTR_SIZE 0x00000001) s
-5 250 M
-( #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004) s
-5 239 M
-( #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008) s
-5 228 M
-( #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010) s
-5 217 M
-( #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020) s
-5 206 M
-( #define SSH_FILEXFER_ATTR_ACL 0x00000040) s
-5 195 M
-( #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080) s
-5 184 M
-( #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( In previous versions of this protocol flags value 0x00000002 was) s
-5 679 M
-( SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP) s
-5 668 M
-( was given a new value in order to ease implementation burden.) s
-5 657 M
-( 0x00000002 MUST NOT appear in the mask. Some future version of this) s
-5 646 M
-( protocol may reuse flag 0x00000002.) s
-5 624 M
-(5.2 Type) s
-5 602 M
-( The type field is always present. The following types are defined:) s
-5 580 M
-( #define SSH_FILEXFER_TYPE_REGULAR 1) s
-5 569 M
-( #define SSH_FILEXFER_TYPE_DIRECTORY 2) s
-5 558 M
-( #define SSH_FILEXFER_TYPE_SYMLINK 3) s
-5 547 M
-( #define SSH_FILEXFER_TYPE_SPECIAL 4) s
-5 536 M
-( #define SSH_FILEXFER_TYPE_UNKNOWN 5) s
-5 514 M
-( On a POSIX system, these values would be derived from the permission) s
-5 503 M
-( field.) s
-5 481 M
-(5.3 Size) s
-5 459 M
-( The `size' field specifies the size of the file on disk, in bytes.) s
-5 448 M
-( If it is present during file creation, it should be considered a hint) s
-5 437 M
-( as to the files eventual size.) s
-5 415 M
-( Files opened with the SSH_FXF_TEXT flag may have a size that is) s
-5 404 M
-( greater or less than the value of the size field.) s
-5 382 M
-(5.4 Owner and Group) s
-5 360 M
-( The `owner' and `group' fields are represented as UTF-8 strings; this) s
-5 349 M
-( is the form used by NFS v4. See NFS version 4 Protocol. [3] The) s
-5 338 M
-( following text is selected quotations from section 5.6.) s
-5 316 M
-( To avoid a representation that is tied to a particular underlying) s
-5 305 M
-( implementation at the client or server, the use of UTF-8 strings has) s
-5 294 M
-( been chosen. The string should be of the form user@dns_domain".) s
-5 283 M
-( This will allow for a client and server that do not use the same) s
-5 272 M
-( local representation the ability to translate to a common syntax that) s
-5 261 M
-( can be interpreted by both. In the case where there is no) s
-5 250 M
-( translation available to the client or server, the attribute value) s
-5 239 M
-( must be constructed without the "@". Therefore, the absence of the @) s
-5 228 M
-( from the owner or owner_group attribute signifies that no translation) s
-5 217 M
-( was available and the receiver of the attribute should not place any) s
-5 206 M
-( special meaning with the attribute value. Even though the attribute) s
-5 195 M
-( value can not be translated, it may still be useful. In the case of) s
-5 184 M
-( a client, the attribute string may be used for local display of) s
-5 173 M
-( ownership.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(5.5 Permissions) s
-5 668 M
-( The `permissions' field contains a bit mask of file permissions as) s
-5 657 M
-( defined by POSIX [1].) s
-5 635 M
-(5.6 Times) s
-5 613 M
-( The 'atime', 'createtime', and 'mtime' contain the access, creation,) s
-5 602 M
-( and modification times of the files, respectively. They are) s
-5 591 M
-( represented as seconds from Jan 1, 1970 in UTC.) s
-5 569 M
-(5.7 ACL) s
-5 547 M
-( The 'ACL' field contains an ACL similar to that defined in section) s
-5 536 M
-( 5.9 of NFS version 4 Protocol [3].) s
-5 514 M
-( uint32 ace-count) s
-5 492 M
-( repeated ace-count time:) s
-5 481 M
-( uint32 ace-type) s
-5 470 M
-( uint32 ace-flag) s
-5 459 M
-( uint32 ace-mask) s
-5 448 M
-( string who [UTF-8]) s
-5 426 M
-( ace-type is one of the following four values \(taken from NFS Version) s
-5 415 M
-( 4 Protocol [3]:) s
-5 393 M
-( const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;) s
-5 382 M
-( const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;) s
-5 371 M
-( const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;) s
-5 360 M
-( const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;) s
-5 338 M
-( ace-flag is a combination of the following flag values. See NFS) s
-5 327 M
-( Version 4 Protocol [3] section 5.9.2:) s
-5 305 M
-( const ACE4_FILE_INHERIT_ACE = 0x00000001;) s
-5 294 M
-( const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;) s
-5 283 M
-( const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;) s
-5 272 M
-( const ACE4_INHERIT_ONLY_ACE = 0x00000008;) s
-5 261 M
-( const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;) s
-5 250 M
-( const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;) s
-5 239 M
-( const ACE4_IDENTIFIER_GROUP = 0x00000040;) s
-5 217 M
-( ace-mask is any combination of the following flags \(taken from NFS) s
-5 206 M
-( Version 4 Protocol [3] section 5.9.3:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( const ACE4_READ_DATA = 0x00000001;) s
-5 679 M
-( const ACE4_LIST_DIRECTORY = 0x00000001;) s
-5 668 M
-( const ACE4_WRITE_DATA = 0x00000002;) s
-5 657 M
-( const ACE4_ADD_FILE = 0x00000002;) s
-5 646 M
-( const ACE4_APPEND_DATA = 0x00000004;) s
-5 635 M
-( const ACE4_ADD_SUBDIRECTORY = 0x00000004;) s
-5 624 M
-( const ACE4_READ_NAMED_ATTRS = 0x00000008;) s
-5 613 M
-( const ACE4_WRITE_NAMED_ATTRS = 0x00000010;) s
-5 602 M
-( const ACE4_EXECUTE = 0x00000020;) s
-5 591 M
-( const ACE4_DELETE_CHILD = 0x00000040;) s
-5 580 M
-( const ACE4_READ_ATTRIBUTES = 0x00000080;) s
-5 569 M
-( const ACE4_WRITE_ATTRIBUTES = 0x00000100;) s
-5 558 M
-( const ACE4_DELETE = 0x00010000;) s
-5 547 M
-( const ACE4_READ_ACL = 0x00020000;) s
-5 536 M
-( const ACE4_WRITE_ACL = 0x00040000;) s
-5 525 M
-( const ACE4_WRITE_OWNER = 0x00080000;) s
-5 514 M
-( const ACE4_SYNCHRONIZE = 0x00100000;) s
-5 492 M
-( who is a UTF-8 string of the form described in 'Owner and Group') s
-5 481 M
-( \(Section 5.4\)) s
-5 459 M
-(5.8 Extended attributes) s
-5 437 M
-( The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension) s
-5 426 M
-( mechanism for vendor-specific extensions. If the flag is specified,) s
-5 415 M
-( then the `extended_count' field is present. It specifies the number) s
-5 404 M
-( of extended_type-extended_data pairs that follow. Each of these) s
-5 393 M
-( pairs specifies an extended attribute. For each of the attributes,) s
-5 382 M
-( the extended_type field should be a string of the format) s
-5 371 M
-( "name@domain", where "domain" is a valid, registered domain name and) s
-5 360 M
-( "name" identifies the method. The IETF may later standardize certain) s
-5 349 M
-( names that deviate from this format \(e.g., that do not contain the) s
-5 338 M
-( "@" sign\). The interpretation of `extended_data' depends on the) s
-5 327 M
-( type. Implementations SHOULD ignore extended data fields that they) s
-5 316 M
-( do not understand.) s
-5 294 M
-( Additional fields can be added to the attributes by either defining) s
-5 283 M
-( additional bits to the flags field to indicate their presence, or by) s
-5 272 M
-( defining extended attributes for them. The extended attributes) s
-5 261 M
-( mechanism is recommended for most purposes; additional flags bits) s
-5 250 M
-( should only be defined by an IETF standards action that also) s
-5 239 M
-( increments the protocol version number. The use of such new fields) s
-5 228 M
-( MUST be negotiated by the version number in the protocol exchange.) s
-5 217 M
-( It is a protocol error if a packet with unsupported protocol bits is) s
-5 206 M
-( received.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(6. Requests From the Client to the Server) s
-5 668 M
-( Requests from the client to the server represent the various file) s
-5 657 M
-( system operations. Each request begins with an `id' field, which is) s
-5 646 M
-( a 32-bit identifier identifying the request \(selected by the client\).) s
-5 635 M
-( The same identifier will be returned in the response to the request.) s
-5 624 M
-( One possible implementation is a monotonically increasing request) s
-5 613 M
-( sequence number \(modulo 2^32\).) s
-5 591 M
-( Many operations in the protocol operate on open files. The) s
-5 580 M
-( SSH_FXP_OPEN request can return a file handle \(which is an opaque) s
-5 569 M
-( variable-length string\) which may be used to access the file later) s
-5 558 M
-( \(e.g. in a read operation\). The client MUST NOT send requests the) s
-5 547 M
-( server with bogus or closed handles. However, the server MUST) s
-5 536 M
-( perform adequate checks on the handle in order to avoid security) s
-5 525 M
-( risks due to fabricated handles.) s
-5 503 M
-( This design allows either stateful and stateless server) s
-5 492 M
-( implementation, as well as an implementation which caches state) s
-5 481 M
-( between requests but may also flush it. The contents of the file) s
-5 470 M
-( handle string are entirely up to the server and its design. The) s
-5 459 M
-( client should not modify or attempt to interpret the file handle) s
-5 448 M
-( strings.) s
-5 426 M
-( The file handle strings MUST NOT be longer than 256 bytes.) s
-5 404 M
-(6.1 Request Synchronization and Reordering) s
-5 382 M
-( The protocol and implementations MUST process requests relating to) s
-5 371 M
-( the same file in the order in which they are received. In other) s
-5 360 M
-( words, if an application submits multiple requests to the server, the) s
-5 349 M
-( results in the responses will be the same as if it had sent the) s
-5 338 M
-( requests one at a time and waited for the response in each case. For) s
-5 327 M
-( example, the server may process non-overlapping read/write requests) s
-5 316 M
-( to the same file in parallel, but overlapping reads and writes cannot) s
-5 305 M
-( be reordered or parallelized. However, there are no ordering) s
-5 294 M
-( restrictions on the server for processing requests from two different) s
-5 283 M
-( file transfer connections. The server may interleave and parallelize) s
-5 272 M
-( them at will.) s
-5 250 M
-( There are no restrictions on the order in which responses to) s
-5 239 M
-( outstanding requests are delivered to the client, except that the) s
-5 228 M
-( server must ensure fairness in the sense that processing of no) s
-5 217 M
-( request will be indefinitely delayed even if the client is sending) s
-5 206 M
-( other requests so that there are multiple outstanding requests all) s
-5 195 M
-( the time.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(6.2 File Names) s
-5 668 M
-( This protocol represents file names as strings. File names are) s
-5 657 M
-( assumed to use the slash \('/'\) character as a directory separator.) s
-5 635 M
-( File names starting with a slash are "absolute", and are relative to) s
-5 624 M
-( the root of the file system. Names starting with any other character) s
-5 613 M
-( are relative to the user's default directory \(home directory\). Note) s
-5 602 M
-( that identifying the user is assumed to take place outside of this) s
-5 591 M
-( protocol.) s
-5 569 M
-( Servers SHOULD interpret a path name component ".." as referring to) s
-5 558 M
-( the parent directory, and "." as referring to the current directory.) s
-5 547 M
-( If the server implementation limits access to certain parts of the) s
-5 536 M
-( file system, it must be extra careful in parsing file names when) s
-5 525 M
-( enforcing such restrictions. There have been numerous reported) s
-5 514 M
-( security bugs where a ".." in a path name has allowed access outside) s
-5 503 M
-( the intended area.) s
-5 481 M
-( An empty path name is valid, and it refers to the user's default) s
-5 470 M
-( directory \(usually the user's home directory\).) s
-5 448 M
-( Otherwise, no syntax is defined for file names by this specification.) s
-5 437 M
-( Clients should not make any other assumptions; however, they can) s
-5 426 M
-( splice path name components returned by SSH_FXP_READDIR together) s
-5 415 M
-( using a slash \('/'\) as the separator, and that will work as expected.) s
-5 393 M
-( In order to comply with IETF Policy on Character Sets and Languages) s
-5 382 M
-( [2], all filenames are to be encoded in UTF-8. The shortest valid) s
-5 371 M
-( UTF-8 encoding of the UNICODE data MUST be used. The server is) s
-5 360 M
-( responsible for converting the UNICODE data to whatever canonical) s
-5 349 M
-( form it requires.) s
-5 327 M
-( For example, if the server requires that precomposed characters) s
-5 316 M
-( always be used, the server MUST NOT assume the filename as sent by) s
-5 305 M
-( the client has this attribute, but must do this normalization itself.) s
-5 283 M
-( It is understood that the lack of well-defined semantics for file) s
-5 272 M
-( names may cause interoperability problems between clients and servers) s
-5 261 M
-( using radically different operating systems. However, this approach) s
-5 250 M
-( is known to work acceptably with most systems, and alternative) s
-5 239 M
-( approaches that e.g. treat file names as sequences of structured) s
-5 228 M
-( components are quite complicated.) s
-5 206 M
-(6.3 Opening, Creating, and Closing Files) s
-5 184 M
-( Files are opened and created using the SSH_FXP_OPEN message, whose) s
-5 173 M
-( data part is as follows:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( string filename [UTF-8]) s
-5 668 M
-( uint32 pflags) s
-5 657 M
-( ATTRS attrs) s
-5 635 M
-( The `id' field is the request identifier as for all requests.) s
-5 613 M
-( The `filename' field specifies the file name. See Section ``File) s
-5 602 M
-( Names'' for more information.) s
-5 580 M
-( The `pflags' field is a bitmask. The following bits have been) s
-5 569 M
-( defined.) s
-5 547 M
-( #define SSH_FXF_READ 0x00000001) s
-5 536 M
-( #define SSH_FXF_WRITE 0x00000002) s
-5 525 M
-( #define SSH_FXF_APPEND 0x00000004) s
-5 514 M
-( #define SSH_FXF_CREAT 0x00000008) s
-5 503 M
-( #define SSH_FXF_TRUNC 0x00000010) s
-5 492 M
-( #define SSH_FXF_EXCL 0x00000020) s
-5 481 M
-( #define SSH_FXF_TEXT 0x00000040) s
-5 459 M
-( These have the following meanings:) s
-5 437 M
-( SSH_FXF_READ) s
-5 426 M
-( Open the file for reading.) s
-5 404 M
-( SSH_FXF_WRITE) s
-5 393 M
-( Open the file for writing. If both this and SSH_FXF_READ are) s
-5 382 M
-( specified, the file is opened for both reading and writing.) s
-5 360 M
-( SSH_FXF_APPEND) s
-5 349 M
-( Force all writes to append data at the end of the file. The) s
-5 338 M
-( offset parameter to write will be ignored.) s
-5 316 M
-( SSH_FXF_CREAT) s
-5 305 M
-( If this flag is specified, then a new file will be created if one) s
-5 294 M
-( does not already exist \(if O_TRUNC is specified, the new file will) s
-5 283 M
-( be truncated to zero length if it previously exists\).) s
-5 261 M
-( SSH_FXF_TRUNC) s
-5 250 M
-( Forces an existing file with the same name to be truncated to zero) s
-5 239 M
-( length when creating a file by specifying SSH_FXF_CREAT.) s
-5 228 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 206 M
-( SSH_FXF_EXCL) s
-5 195 M
-( Causes the request to fail if the named file already exists.) s
-5 184 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FXF_TEXT) s
-5 679 M
-( Indicates that the server should treat the file as text and) s
-5 668 M
-( convert it to the canonical newline convention in use. \(See) s
-5 657 M
-( Determining Server Newline Convention. \(Section 4.3\)) s
-5 635 M
-( When a file is opened with the FXF_TEXT flag, the offset field in) s
-5 624 M
-( both the read and write function are ignored.) s
-5 602 M
-( Servers MUST correctly process multiple parallel reads and writes) s
-5 591 M
-( correctly in this mode. Naturally, it is permissible for them to) s
-5 580 M
-( do this by serializing the requests. It would not be possible for) s
-5 569 M
-( a client to reliably detect a server that does not implement) s
-5 558 M
-( parallel writes in time to prevent damage.) s
-5 536 M
-( Clients SHOULD use the SSH_FXF_APPEND flag to append data to a) s
-5 525 M
-( text file rather then using write with a calculated offset.) s
-5 503 M
-( To support seeks on text file the following SSH_FXP_EXTENDED) s
-5 492 M
-( packet is defined.) s
-5 448 M
-( string "text-seek") s
-5 437 M
-( string file-handle) s
-5 426 M
-( uint64 line-number) s
-5 404 M
-( line-number is the index of the line number to seek to, where byte) s
-5 393 M
-( 0 in the file is line number 0, and the byte directly following) s
-5 382 M
-( the first newline sequence in the file is line number 1 and so on.) s
-5 360 M
-( The response to a "text-seek" request is an SSH_FXP_STATUS) s
-5 349 M
-( message.) s
-5 327 M
-( An attempt to seek past the end-of-file should result in a) s
-5 316 M
-( SSH_FX_EOF status.) s
-5 294 M
-( Servers SHOULD support at least one "text-seek" in order to) s
-5 283 M
-( support resume. However, a client MUST be prepared to receive) s
-5 272 M
-( SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.) s
-5 261 M
-( The client can then try a fall-back strategy, if it has one.) s
-5 239 M
-( Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned) s
-5 228 M
-( for read or write operations that are not sequential.) s
-5 206 M
-( The `attrs' field specifies the initial attributes for the file.) s
-5 195 M
-( Default values will be used for those attributes that are not) s
-5 184 M
-( specified. See Section ``File Attributes'' for more information.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( The response to this message will be either SSH_FXP_HANDLE \(if the) s
-5 679 M
-( operation is successful\) or SSH_FXP_STATUS \(if the operation fails\).) s
-5 657 M
-( A file is closed by using the SSH_FXP_CLOSE request. Its data field) s
-5 646 M
-( has the following format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string handle) s
-5 591 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 580 M
-( previously returned in the response to SSH_FXP_OPEN or) s
-5 569 M
-( SSH_FXP_OPENDIR. The handle becomes invalid immediately after this) s
-5 558 M
-( request has been sent.) s
-5 536 M
-( The response to this request will be a SSH_FXP_STATUS message. One) s
-5 525 M
-( should note that on some server platforms even a close can fail.) s
-5 514 M
-( This can happen e.g. if the server operating system caches writes,) s
-5 503 M
-( and an error occurs while flushing cached writes during the close.) s
-5 481 M
-(6.4 Reading and Writing) s
-5 459 M
-( Once a file has been opened, it can be read using the SSH_FXP_READ) s
-5 448 M
-( message, which has the following format:) s
-5 426 M
-( uint32 id) s
-5 415 M
-( string handle) s
-5 404 M
-( uint64 offset) s
-5 393 M
-( uint32 len) s
-5 371 M
-( where `id' is the request identifier, `handle' is an open file handle) s
-5 360 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) relative) s
-5 349 M
-( to the beginning of the file from where to start reading, and `len') s
-5 338 M
-( is the maximum number of bytes to read.) s
-5 316 M
-( In response to this request, the server will read as many bytes as it) s
-5 305 M
-( can from the file \(up to `len'\), and return them in a SSH_FXP_DATA) s
-5 294 M
-( message. If an error occurs or EOF is encountered before reading any) s
-5 283 M
-( data, the server will respond with SSH_FXP_STATUS. For normal disk) s
-5 272 M
-( files, it is guaranteed that this will read the specified number of) s
-5 261 M
-( bytes, or up to end of file. For e.g. device files this may return) s
-5 250 M
-( fewer bytes than requested.) s
-5 228 M
-( Writing to a file is achieved using the SSH_FXP_WRITE message, which) s
-5 217 M
-( has the following format:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( string handle) s
-5 668 M
-( uint64 offset) s
-5 657 M
-( string data) s
-5 635 M
-( where `id' is a request identifier, `handle' is a file handle) s
-5 624 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) from the) s
-5 613 M
-( beginning of the file where to start writing, and `data' is the data) s
-5 602 M
-( to be written.) s
-5 580 M
-( The write will extend the file if writing beyond the end of the file.) s
-5 569 M
-( It is legal to write way beyond the end of the file; the semantics) s
-5 558 M
-( are to write zeroes from the end of the file to the specified offset) s
-5 547 M
-( and then the data. On most operating systems, such writes do not) s
-5 536 M
-( allocate disk space but instead leave "holes" in the file.) s
-5 514 M
-( The server responds to a write request with a SSH_FXP_STATUS message.) s
-5 492 M
-(6.5 Removing and Renaming Files) s
-5 470 M
-( Files can be removed using the SSH_FXP_REMOVE message. It has the) s
-5 459 M
-( following format:) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string filename [UTF-8]) s
-5 404 M
-( where `id' is the request identifier and `filename' is the name of) s
-5 393 M
-( the file to be removed. See Section ``File Names'' for more) s
-5 382 M
-( information. This request cannot be used to remove directories.) s
-5 360 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 349 M
-( message.) s
-5 327 M
-( Files \(and directories\) can be renamed using the SSH_FXP_RENAME) s
-5 316 M
-( message. Its data is as follows:) s
-5 294 M
-( uint32 id) s
-5 283 M
-( string oldpath [UTF-8]) s
-5 272 M
-( string newpath [UTF-8]) s
-5 250 M
-( where `id' is the request identifier, `oldpath' is the name of an) s
-5 239 M
-( existing file or directory, and `newpath' is the new name for the) s
-5 228 M
-( file or directory. It is an error if there already exists a file) s
-5 217 M
-( with the name specified by newpath. The server may also fail rename) s
-5 206 M
-( requests in other situations, for example if `oldpath' and `newpath') s
-5 195 M
-( point to different file systems on the server.) s
-5 173 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( message.) s
-5 668 M
-(6.6 Creating and Deleting Directories) s
-5 646 M
-( New directories can be created using the SSH_FXP_MKDIR request. It) s
-5 635 M
-( has the following format:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string path [UTF-8]) s
-5 591 M
-( ATTRS attrs) s
-5 569 M
-( where `id' is the request identifier.) s
-5 547 M
-( `path' specifies the directory to be created. See Section ``File) s
-5 536 M
-( Names'' for more information on file names.) s
-5 514 M
-( `attrs' specifies the attributes that should be applied to it upon) s
-5 503 M
-( creation. Attributes are discussed in more detail in Section ``File) s
-5 492 M
-( Attributes''.) s
-5 470 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 459 M
-( message. If a file or directory with the specified path already) s
-5 448 M
-( exists, an error will be returned.) s
-5 426 M
-( Directories can be removed using the SSH_FXP_RMDIR request, which has) s
-5 415 M
-( the following format:) s
-5 393 M
-( uint32 id) s
-5 382 M
-( string path [UTF-8]) s
-5 360 M
-( where `id' is the request identifier, and `path' specifies the) s
-5 349 M
-( directory to be removed. See Section ``File Names'' for more) s
-5 338 M
-( information on file names.) s
-5 316 M
-( The server responds to this request with a SSH_FXP_STATUS message.) s
-5 305 M
-( Errors may be returned from this operation for various reasons,) s
-5 294 M
-( including, but not limited to, the path does not exist, the path does) s
-5 283 M
-( not refer to a directory object, the directory is not empty, or the) s
-5 272 M
-( user has insufficient access or permission to perform the requested) s
-5 261 M
-( operation.) s
-5 239 M
-(6.7 Scanning Directories) s
-5 217 M
-( The files in a directory can be listed using the SSH_FXP_OPENDIR and) s
-5 206 M
-( SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one) s
-5 195 M
-( or more file names with full file attributes for each file. The) s
-5 184 M
-( client should call SSH_FXP_READDIR repeatedly until it has found the) s
-5 173 M
-( file it is looking for or until the server responds with a) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FXP_STATUS message indicating an error \(normally SSH_FX_EOF if) s
-5 679 M
-( there are no more files in the directory\). The client should then) s
-5 668 M
-( close the handle using the SSH_FXP_CLOSE request.) s
-5 646 M
-( The SSH_FXP_OPENDIR opens a directory for reading. It has the) s
-5 635 M
-( following format:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string path [UTF-8]) s
-5 580 M
-( where `id' is the request identifier and `path' is the path name of) s
-5 569 M
-( the directory to be listed \(without any trailing slash\). See Section) s
-5 558 M
-( ``File Names'' for more information on file names. This will return) s
-5 547 M
-( an error if the path does not specify a directory or if the directory) s
-5 536 M
-( is not readable. The server will respond to this request with either) s
-5 525 M
-( a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.) s
-5 503 M
-( Once the directory has been successfully opened, files \(and) s
-5 492 M
-( directories\) contained in it can be listed using SSH_FXP_READDIR) s
-5 481 M
-( requests. These are of the format) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string handle) s
-5 426 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 415 M
-( returned by SSH_FXP_OPENDIR. \(It is a protocol error to attempt to) s
-5 404 M
-( use an ordinary file handle returned by SSH_FXP_OPEN.\)) s
-5 382 M
-( The server responds to this request with either a SSH_FXP_NAME or a) s
-5 371 M
-( SSH_FXP_STATUS message. One or more names may be returned at a time.) s
-5 360 M
-( Full status information is returned for each name in order to speed) s
-5 349 M
-( up typical directory listings.) s
-5 327 M
-( If there are no more names available to be read, the server MUST) s
-5 316 M
-( respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.) s
-5 294 M
-( When the client no longer wishes to read more names from the) s
-5 283 M
-( directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle) s
-5 272 M
-( should be closed regardless of whether an error has occurred or not.) s
-5 250 M
-(6.8 Retrieving File Attributes) s
-5 228 M
-( Very often, file attributes are automatically returned by) s
-5 217 M
-( SSH_FXP_READDIR. However, sometimes there is need to specifically) s
-5 206 M
-( retrieve the attributes for a named file. This can be done using the) s
-5 195 M
-( SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.) s
-5 173 M
-( SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( follows symbolic links on the server, whereas SSH_FXP_LSTAT does not) s
-5 679 M
-( follow symbolic links. Both have the same format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string path [UTF-8]) s
-5 635 M
-( uint32 flags) s
-5 613 M
-( where `id' is the request identifier, and `path' specifies the file) s
-5 602 M
-( system object for which status is to be returned. The server) s
-5 591 M
-( responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 569 M
-( The flags field specify the attribute flags in which the client has) s
-5 558 M
-( particular interest. This is a hint to the server. For example,) s
-5 547 M
-( because retrieving owner / group and acl information can be an) s
-5 536 M
-( expensive operation under some operating systems, the server may) s
-5 525 M
-( choose not to retrieve this information unless the client expresses a) s
-5 514 M
-( specific interest in it.) s
-5 492 M
-( The client has no guarantee the server will provide all the fields) s
-5 481 M
-( that it has expressed an interest in.) s
-5 459 M
-( SSH_FXP_FSTAT differs from the others in that it returns status) s
-5 448 M
-( information for an open file \(identified by the file handle\). Its) s
-5 437 M
-( format is as follows:) s
-5 415 M
-( uint32 id) s
-5 404 M
-( string handle) s
-5 393 M
-( uint32 flags) s
-5 371 M
-( where `id' is the request identifier and `handle' is a file handle) s
-5 360 M
-( returned by SSH_FXP_OPEN. The server responds to this request with) s
-5 349 M
-( SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 327 M
-(6.9 Setting File Attributes) s
-5 305 M
-( File attributes may be modified using the SSH_FXP_SETSTAT and) s
-5 294 M
-( SSH_FXP_FSETSTAT requests. These requests are used for operations) s
-5 283 M
-( such as changing the ownership, permissions or access times, as well) s
-5 272 M
-( as for truncating a file.) s
-5 250 M
-( The SSH_FXP_SETSTAT request is of the following format:) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string path [UTF-8]) s
-5 206 M
-( ATTRS attrs) s
-5 184 M
-( where `id' is the request identifier, `path' specifies the file) s
-5 173 M
-( system object \(e.g. file or directory\) whose attributes are to be) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 679 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 668 M
-( ``File Attributes''.) s
-5 646 M
-( An error will be returned if the specified file system object does) s
-5 635 M
-( not exist or the user does not have sufficient rights to modify the) s
-5 624 M
-( specified attributes. The server responds to this request with a) s
-5 613 M
-( SSH_FXP_STATUS message.) s
-5 591 M
-( The SSH_FXP_FSETSTAT request modifies the attributes of a file which) s
-5 580 M
-( is already open. It has the following format:) s
-5 558 M
-( uint32 id) s
-5 547 M
-( string handle) s
-5 536 M
-( ATTRS attrs) s
-5 514 M
-( where `id' is the request identifier, `handle' \(MUST be returned by) s
-5 503 M
-( SSH_FXP_OPEN\) identifies the file whose attributes are to be) s
-5 492 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 481 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 470 M
-( ``File Attributes''. The server will respond to this request with) s
-5 459 M
-( SSH_FXP_STATUS.) s
-5 437 M
-(6.10 Dealing with Symbolic links) s
-5 415 M
-( The SSH_FXP_READLINK request may be used to read the target of a) s
-5 404 M
-( symbolic link. It would have a data part as follows:) s
-5 382 M
-( uint32 id) s
-5 371 M
-( string path [UTF-8]) s
-5 349 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 338 M
-( name of the symlink to be read.) s
-5 316 M
-( The server will respond with a SSH_FXP_NAME packet containing only) s
-5 305 M
-( one name and a dummy attributes value. The name in the returned) s
-5 294 M
-( packet contains the target of the link. If an error occurs, the) s
-5 283 M
-( server may respond with SSH_FXP_STATUS.) s
-5 261 M
-( The SSH_FXP_SYMLINK request will create a symbolic link on the) s
-5 250 M
-( server. It is of the following format) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string linkpath [UTF-8]) s
-5 206 M
-( string targetpath [UTF-8]) s
-5 184 M
-( where `id' is the request identifier, `linkpath' specifies the path) s
-5 173 M
-( name of the symlink to be created and `targetpath' specifies the) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( target of the symlink. The server shall respond with a) s
-5 679 M
-( SSH_FXP_STATUS indicating either success \(SSH_FX_OK\) or an error) s
-5 668 M
-( condition.) s
-5 646 M
-(6.11 Canonicalizing the Server-Side Path Name) s
-5 624 M
-( The SSH_FXP_REALPATH request can be used to have the server) s
-5 613 M
-( canonicalize any given path name to an absolute path. This is useful) s
-5 602 M
-( for converting path names containing ".." components or relative) s
-5 591 M
-( pathnames without a leading slash into absolute paths. The format of) s
-5 580 M
-( the request is as follows:) s
-5 558 M
-( uint32 id) s
-5 547 M
-( string path [UTF-8]) s
-5 525 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 514 M
-( name to be canonicalized. The server will respond with a) s
-5 503 M
-( SSH_FXP_NAME packet containing the name in canonical form and a dummy) s
-5 492 M
-( attributes value. If an error occurs, the server may also respond) s
-5 481 M
-( with SSH_FXP_STATUS.) s
-5 459 M
-(6.11.1 Best practice for dealing with paths) s
-5 437 M
-( The client SHOULD treat the results of SSH_FXP_REALPATH as a) s
-5 426 M
-( canonical absolute path, even if the path does not appear to be) s
-5 415 M
-( absolute. A client that use REALPATH\("."\) and treats the result as) s
-5 404 M
-( absolute, even if there is no leading slash, will continue to) s
-5 393 M
-( function correctly, even when talking to a Windows NT or VMS style) s
-5 382 M
-( system, where absolute paths may not begin with a slash.) s
-5 360 M
-( For example, if the client wishes to change directory up, and the) s
-5 349 M
-( server has returned "c:/x/y/z" from REALPATH, the client SHOULD use) s
-5 338 M
-( "c:/x/y/z/..".) s
-5 316 M
-( As a second example, if the client wishes to open the file "x.txt" in) s
-5 305 M
-( the current directory, and server has returned "dka100:/x/y/z" as the) s
-5 294 M
-( canonical path of the directory, the client SHOULD open "dka100:/x/y/) s
-5 283 M
-( z/x.txt") s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(7. Responses from the Server to the Client) s
-5 668 M
-( The server responds to the client using one of a few response) s
-5 657 M
-( packets. All requests can return a SSH_FXP_STATUS response upon) s
-5 646 M
-( failure. When the operation is successful, any of the responses may) s
-5 635 M
-( be returned \(depending on the operation\). If no data needs to be) s
-5 624 M
-( returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK) s
-5 613 M
-( status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used) s
-5 602 M
-( to return a file handle \(for SSH_FXP_OPEN and SSH_FXP_OPENDIR) s
-5 591 M
-( requests\), SSH_FXP_DATA is used to return data from SSH_FXP_READ,) s
-5 580 M
-( SSH_FXP_NAME is used to return one or more file names from a) s
-5 569 M
-( SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is) s
-5 558 M
-( used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and) s
-5 547 M
-( SSH_FXP_FSTAT requests.) s
-5 525 M
-( Exactly one response will be returned for each request. Each) s
-5 514 M
-( response packet contains a request identifier which can be used to) s
-5 503 M
-( match each response with the corresponding request. Note that it is) s
-5 492 M
-( legal to have several requests outstanding simultaneously, and the) s
-5 481 M
-( server is allowed to send responses to them in a different order from) s
-5 470 M
-( the order in which the requests were sent \(the result of their) s
-5 459 M
-( execution, however, is guaranteed to be as if they had been processed) s
-5 448 M
-( one at a time in the order in which the requests were sent\).) s
-5 426 M
-( Response packets are of the same general format as request packets.) s
-5 415 M
-( Each response packet begins with the request identifier.) s
-5 393 M
-( The format of the data portion of the SSH_FXP_STATUS response is as) s
-5 382 M
-( follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( uint32 error/status code) s
-5 338 M
-( string error message \(ISO-10646 UTF-8 [RFC-2279]\)) s
-5 327 M
-( string language tag \(as defined in [RFC-1766]\)) s
-5 305 M
-( where `id' is the request identifier, and `error/status code') s
-5 294 M
-( indicates the result of the requested operation. The value SSH_FX_OK) s
-5 283 M
-( indicates success, and all other values indicate failure.) s
-5 261 M
-( Currently, the following values are defined \(other values may be) s
-5 250 M
-( defined by future versions of this protocol\):) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( #define SSH_FX_OK 0) s
-5 679 M
-( #define SSH_FX_EOF 1) s
-5 668 M
-( #define SSH_FX_NO_SUCH_FILE 2) s
-5 657 M
-( #define SSH_FX_PERMISSION_DENIED 3) s
-5 646 M
-( #define SSH_FX_FAILURE 4) s
-5 635 M
-( #define SSH_FX_BAD_MESSAGE 5) s
-5 624 M
-( #define SSH_FX_NO_CONNECTION 6) s
-5 613 M
-( #define SSH_FX_CONNECTION_LOST 7) s
-5 602 M
-( #define SSH_FX_OP_UNSUPPORTED 8) s
-5 591 M
-( #define SSH_FX_INVALID_HANDLE 9) s
-5 580 M
-( #define SSH_FX_NO_SUCH_PATH 10) s
-5 569 M
-( #define SSH_FX_FILE_ALREADY_EXISTS 11) s
-5 558 M
-( #define SSH_FX_WRITE_PROTECT 12) s
-5 536 M
-( SSH_FX_OK) s
-5 525 M
-( Indicates successful completion of the operation.) s
-5 503 M
-( SSH_FX_EOF) s
-5 492 M
-( indicates end-of-file condition; for SSH_FX_READ it means that no) s
-5 481 M
-( more data is available in the file, and for SSH_FX_READDIR it) s
-5 470 M
-( indicates that no more files are contained in the directory.) s
-5 448 M
-( SSH_FX_NO_SUCH_FILE) s
-5 437 M
-( is returned when a reference is made to a file which does not) s
-5 426 M
-( exist.) s
-5 404 M
-( SSH_FX_PERMISSION_DENIED) s
-5 393 M
-( is returned when the authenticated user does not have sufficient) s
-5 382 M
-( permissions to perform the operation.) s
-5 360 M
-( SSH_FX_FAILURE) s
-5 349 M
-( is a generic catch-all error message; it should be returned if an) s
-5 338 M
-( error occurs for which there is no more specific error code) s
-5 327 M
-( defined.) s
-5 305 M
-( SSH_FX_BAD_MESSAGE) s
-5 294 M
-( may be returned if a badly formatted packet or protocol) s
-5 283 M
-( incompatibility is detected.) s
-5 261 M
-( SSH_FX_NO_CONNECTION) s
-5 250 M
-( is a pseudo-error which indicates that the client has no) s
-5 239 M
-( connection to the server \(it can only be generated locally by the) s
-5 228 M
-( client, and MUST NOT be returned by servers\).) s
-5 206 M
-( SSH_FX_CONNECTION_LOST) s
-5 195 M
-( is a pseudo-error which indicates that the connection to the) s
-5 184 M
-( server has been lost \(it can only be generated locally by the) s
-5 173 M
-( client, and MUST NOT be returned by servers\).) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FX_OP_UNSUPPORTED) s
-5 679 M
-( indicates that an attempt was made to perform an operation which) s
-5 668 M
-( is not supported for the server \(it may be generated locally by) s
-5 657 M
-( the client if e.g. the version number exchange indicates that a) s
-5 646 M
-( required feature is not supported by the server, or it may be) s
-5 635 M
-( returned by the server if the server does not implement an) s
-5 624 M
-( operation\).) s
-5 602 M
-( SSH_FX_INVALID_HANDLE) s
-5 591 M
-( The handle value was invalid.) s
-5 569 M
-( SSH_FX_NO_SUCH_PATH) s
-5 558 M
-( The file path does not exist or is invalid.) s
-5 536 M
-( SSH_FX_FILE_ALREADY_EXISTS) s
-5 525 M
-( The file already exists.) s
-5 503 M
-( SSH_FX_WRITE_PROTECT) s
-5 492 M
-( The file is on read only media, or the media is write protected.) s
-5 470 M
-( The SSH_FXP_HANDLE response has the following format:) s
-5 448 M
-( uint32 id) s
-5 437 M
-( string handle) s
-5 415 M
-( where `id' is the request identifier, and `handle' is an arbitrary) s
-5 404 M
-( string that identifies an open file or directory on the server. The) s
-5 393 M
-( handle is opaque to the client; the client MUST NOT attempt to) s
-5 382 M
-( interpret or modify it in any way. The length of the handle string) s
-5 371 M
-( MUST NOT exceed 256 data bytes.) s
-5 349 M
-( The SSH_FXP_DATA response has the following format:) s
-5 327 M
-( uint32 id) s
-5 316 M
-( string data) s
-5 294 M
-( where `id' is the request identifier, and `data' is an arbitrary byte) s
-5 283 M
-( string containing the requested data. The data string may be at most) s
-5 272 M
-( the number of bytes requested in a SSH_FXP_READ request, but may also) s
-5 261 M
-( be shorter if end of file is reached or if the read is from something) s
-5 250 M
-( other than a regular file.) s
-5 228 M
-( The SSH_FXP_NAME response has the following format:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( uint32 count) s
-5 668 M
-( repeats count times:) s
-5 657 M
-( string filename [UTF-8]) s
-5 646 M
-( ATTRS attrs) s
-5 624 M
-( where `id' is the request identifier, `count' is the number of names) s
-5 613 M
-( returned in this response, and the remaining fields repeat `count') s
-5 602 M
-( times \(so that all three fields are first included for the first) s
-5 591 M
-( file, then for the second file, etc\). In the repeated part,) s
-5 580 M
-( `filename' is a file name being returned \(for SSH_FXP_READDIR, it) s
-5 569 M
-( will be a relative name within the directory, without any path) s
-5 558 M
-( components; for SSH_FXP_REALPATH it will be an absolute path name\),) s
-5 547 M
-( and `attrs' is the attributes of the file as described in Section) s
-5 536 M
-( ``File Attributes''.) s
-5 514 M
-( The SSH_FXP_ATTRS response has the following format:) s
-5 492 M
-( uint32 id) s
-5 481 M
-( ATTRS attrs) s
-5 459 M
-( where `id' is the request identifier, and `attrs' is the returned) s
-5 448 M
-( file attributes as described in Section ``File Attributes''.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(8. Vendor-Specific Extensions) s
-5 668 M
-( The SSH_FXP_EXTENDED request provides a generic extension mechanism) s
-5 657 M
-( for adding vendor-specific commands. The request has the following) s
-5 646 M
-( format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string extended-request) s
-5 602 M
-( ... any request-specific data ...) s
-5 580 M
-( where `id' is the request identifier, and `extended-request' is a) s
-5 569 M
-( string of the format "name@domain", where domain is an internet) s
-5 558 M
-( domain name of the vendor defining the request. The rest of the) s
-5 547 M
-( request is completely vendor-specific, and servers should only) s
-5 536 M
-( attempt to interpret it if they recognize the `extended-request') s
-5 525 M
-( name.) s
-5 503 M
-( The server may respond to such requests using any of the response) s
-5 492 M
-( packets defined in Section ``Responses from the Server to the) s
-5 481 M
-( Client''. Additionally, the server may also respond with a) s
-5 470 M
-( SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does) s
-5 459 M
-( not recognize the `extended-request' name, then the server MUST) s
-5 448 M
-( respond with SSH_FXP_STATUS with error/status set to) s
-5 437 M
-( SSH_FX_OP_UNSUPPORTED.) s
-5 415 M
-( The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary) s
-5 404 M
-( extension-specific data from the server to the client. It is of the) s
-5 393 M
-( following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ... any request-specific data ...) s
-5 338 M
-( There is a range of packet types reserved for use by extensions. In) s
-5 327 M
-( order to avoid collision, extensions that turn on the use of) s
-5 316 M
-( additional packet types should determine those numbers dynamically.) s
-5 294 M
-( The suggested way of doing this is have an extension request from the) s
-5 283 M
-( client to the server that enables the extension; the extension) s
-5 272 M
-( response from the server to the client would specify the actual type) s
-5 261 M
-( values to use, in additional to any other data.) s
-5 239 M
-( Extension authors should be mindful of the limited range of packet) s
-5 228 M
-( types available \(there are only 45 values available\) and avoid) s
-5 217 M
-( requiring a new packet type where possible.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(9. Security Considerations) s
-5 668 M
-( This protocol assumes that it is run over a secure channel and that) s
-5 657 M
-( the endpoints of the channel have been authenticated. Thus, this) s
-5 646 M
-( protocol assumes that it is externally protected from network-level) s
-5 635 M
-( attacks.) s
-5 613 M
-( This protocol provides file system access to arbitrary files on the) s
-5 602 M
-( server \(only constrained by the server implementation\). It is the) s
-5 591 M
-( responsibility of the server implementation to enforce any access) s
-5 580 M
-( controls that may be required to limit the access allowed for any) s
-5 569 M
-( particular user \(the user being authenticated externally to this) s
-5 558 M
-( protocol, typically using the SSH User Authentication Protocol [8].) s
-5 536 M
-( Care must be taken in the server implementation to check the validity) s
-5 525 M
-( of received file handle strings. The server should not rely on them) s
-5 514 M
-( directly; it MUST check the validity of each handle before relying on) s
-5 503 M
-( it.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 30 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(10. Changes from previous protocol versions) s
-5 668 M
-( The SSH File Transfer Protocol has changed over time, before it's) s
-5 657 M
-( standardization. The following is a description of the incompatible) s
-5 646 M
-( changes between different versions.) s
-5 624 M
-(10.1 Changes between versions 4 and 3) s
-5 602 M
-( Many of the changes between version 4 and version 3 are to the) s
-5 591 M
-( attribute structure to make it more flexible for non-unix platforms.) s
-5 569 M
-( o Make all filenames UTF-8.) s
-5 547 M
-( o Added 'newline' extension.) s
-5 525 M
-( o Made file attribute owner and group strings so they can actually) s
-5 514 M
-( be used on disparate systems.) s
-5 492 M
-( o Added createtime field, and added separate flags for atime,) s
-5 481 M
-( createtime, and mtime so they can be set separately.) s
-5 459 M
-( o Split the file type out of the permissions field and into it's own) s
-5 448 M
-( field \(which is always present.\)) s
-5 426 M
-( o Added acl attribute.) s
-5 404 M
-( o Added SSH_FXF_TEXT file open flag.) s
-5 382 M
-( o Added flags field to the get stat commands so that the client can) s
-5 371 M
-( specifically request information the server might not normally) s
-5 360 M
-( included for performance reasons.) s
-5 338 M
-( o Removed the long filename from the names structure-- it can now be) s
-5 327 M
-( built from information available in the attrs structure.) s
-5 305 M
-( o Added reserved range of packet numbers for extensions.) s
-5 283 M
-( o Added several additional error codes.) s
-5 261 M
-( o Change the way version negotiate works slightly. Previously, if) s
-5 250 M
-( the client version were higher than the server version, the server) s
-5 239 M
-( was supposed to 'echo back' the clients version. The server now) s
-5 228 M
-( sends it's own version and the lower of the two is considered to) s
-5 217 M
-( be the one in use.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 30]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (30,31) 16
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 31 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(10.2 Changes between versions 3 and 2) s
-5 668 M
-( o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.) s
-5 646 M
-( o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were) s
-5 635 M
-( added.) s
-5 613 M
-( o The SSH_FXP_STATUS message was changed to include fields `error) s
-5 602 M
-( message' and `language tag'.) s
-5 569 M
-(10.3 Changes between versions 2 and 1) s
-5 547 M
-( o The SSH_FXP_RENAME message was added.) s
-5 514 M
-(10.4 Changes between versions 1 and 0) s
-5 492 M
-( o Implementation changes, no actual protocol changes.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 31]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 32 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(11. Trademark Issues) s
-5 668 M
-( "ssh" is a registered trademark of SSH Communications Security Corp) s
-5 657 M
-( in the United States and/or other countries.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 32]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (32,33) 17
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 33 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(References) s
-5 668 M
-( [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and) s
-5 657 M
-( P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January) s
-5 646 M
-( 1999.) s
-5 624 M
-( [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",) s
-5 613 M
-( BCP 18, RFC 2277, January 1998.) s
-5 591 M
-( [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,) s
-5 580 M
-( C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC) s
-5 569 M
-( 3010, December 2000.) s
-5 547 M
-( [4] Institute of Electrical and Electronics Engineers, "Information) s
-5 536 M
-( Technology - Portable Operating System Interface \(POSIX\) - Part) s
-5 525 M
-( 1: System Application Program Interface \(API\) [C Language]",) s
-5 514 M
-( IEEE Standard 1003.2, 1996.) s
-5 492 M
-( [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 481 M
-( Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-) s
-5 470 M
-( architecture-13 \(work in progress\), September 2002.) s
-5 448 M
-( [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 437 M
-( Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-) s
-5 426 M
-( transport-15 \(work in progress\), September 2002.) s
-5 404 M
-( [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 393 M
-( Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16) s
-5 382 M
-( \(work in progress\), September 2002.) s
-5 360 M
-( [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 349 M
-( Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-) s
-5 338 M
-( userauth-16 \(work in progress\), September 2002.) s
-5 305 M
-(Authors' Addresses) s
-5 283 M
-( Joseph Galbraith) s
-5 272 M
-( VanDyke Software) s
-5 261 M
-( 4848 Tramway Ridge Blvd) s
-5 250 M
-( Suite 101) s
-5 239 M
-( Albuquerque, NM 87111) s
-5 228 M
-( US) s
-5 206 M
-( Phone: +1 505 332 5700) s
-5 195 M
-( EMail: [email protected]) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 33]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 34 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( Tatu Ylonen) s
-5 679 M
-( SSH Communications Security Corp) s
-5 668 M
-( Fredrikinkatu 42) s
-5 657 M
-( HELSINKI FIN-00100) s
-5 646 M
-( Finland) s
-5 624 M
-( EMail: [email protected]) s
-5 591 M
-( Sami Lehtinen) s
-5 580 M
-( SSH Communications Security Corp) s
-5 569 M
-( Fredrikinkatu 42) s
-5 558 M
-( HELSINKI FIN-00100) s
-5 547 M
-( Finland) s
-5 525 M
-( EMail: [email protected]) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 34]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (34,35) 18
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 35 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(Full Copyright Statement) s
-5 668 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 646 M
-( This document and translations of it may be copied and furnished to) s
-5 635 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 624 M
-( or assist in its implementation may be prepared, copied, published) s
-5 613 M
-( and distributed, in whole or in part, without restriction of any) s
-5 602 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 591 M
-( included on all such copies and derivative works. However, this) s
-5 580 M
-( document itself may not be modified in any way, such as by removing) s
-5 569 M
-( the copyright notice or references to the Internet Society or other) s
-5 558 M
-( Internet organizations, except as needed for the purpose of) s
-5 547 M
-( developing Internet standards in which case the procedures for) s
-5 536 M
-( copyrights defined in the Internet Standards process must be) s
-5 525 M
-( followed, or as required to translate it into languages other than) s
-5 514 M
-( English.) s
-5 492 M
-( The limited permissions granted above are perpetual and will not be) s
-5 481 M
-( revoked by the Internet Society or its successors or assigns.) s
-5 459 M
-( This document and the information contained herein is provided on an) s
-5 448 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 437 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 426 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 415 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 404 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 382 M
-(Acknowledgement) s
-5 360 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 349 M
-( Internet Society.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 35]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 36 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 36
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt
deleted file mode 100644
index 83960ae976..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt
+++ /dev/null
@@ -1,1962 +0,0 @@
-
-
-
-Secure Shell Working Group J. Galbraith
-Internet-Draft VanDyke Software
-Expires: April 16, 2003 T. Ylonen
- S. Lehtinen
- SSH Communications Security Corp
- October 16, 2002
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-03.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on April 16, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . 5
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . 7
- 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 7
- 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 7
- 4.3 Determining Server Newline Convention . . . . . . . . . . 8
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 9
- 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 9
- 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 10
- 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 12
- 6. Requests From the Client to the Server . . . . . . . . . . 13
- 6.1 Request Synchronization and Reordering . . . . . . . . . . 13
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 14
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 14
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 17
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 18
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . 19
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 19
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 20
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 21
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 22
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 23
- 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 23
- 7. Responses from the Server to the Client . . . . . . . . . 24
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 28
- 9. Security Considerations . . . . . . . . . . . . . . . . . 29
- 10. Changes from previous protocol versions . . . . . . . . . 30
- 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 30
- 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 31
- 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 31
- 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 31
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 32
- References . . . . . . . . . . . . . . . . . . . . . . . . 33
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . 33
- Full Copyright Statement . . . . . . . . . . . . . . . . . 35
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [5].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft. [5]
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [7] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
- The following values are defined for packet types.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
-
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
-
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- RESERVED_FOR_EXTENSIONS 210-255
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, the client first sends a
- SSH_FXP_INIT (including its version number) packet to the server.
- The server responds with a SSH_FXP_VERSION packet, supplying the
- lowest of its own and the client's version number. Both parties
- should from then on adhere to particular version of the protocol.
-
- The version number of the protocol specified in this document is 4.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
-4.1 Client Initialization
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
-
- Version 3 of this protocol allowed clients to include extensions in
- the SSH_FXP_INIT packet; however, this can cause interoperability
- problems with version 1 and version 2 servers because the client must
- send this packet before knowing the servers version.
-
- In this version of the protocol, clients MUST use the
- SSH_FXP_EXTENDED packet to send extensions to the server after
- version exchange has completed. Clients MUST NOT include extensions
- in the version packet. This will prevent interoperability problems
- with older servers
-
-4.2 Server Initialization
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- 'version' is the lower of the protocol version supported by the
- server and the version number received from the client.
-
- The extension data may be empty, or may be a sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-4.3 Determining Server Newline Convention
-
- In order to correctly process text files in a cross platform
- compatible way, the newline convention must be converted from that of
- the server to that of the client, or, during an upload, from that of
- the client to that of the server.
-
- Versions 3 and prior of this protocol made no provisions for
- processing text files. Many clients implemented some sort of
- conversion algorithm, but without either a 'canonical' on the wire
- format or knowledge of the servers newline convention, correct
- conversion was not always possible.
-
- Starting with Version 4, the SSH_FXF_TEXT file open flag (Section
- 6.3) makes it possible to request that the server translate a file to
- a 'canonical' on the wire format. This format uses \r\n as the line
- separator.
-
- Servers for systems using multiple newline characters (for example,
- Mac OS X or VMS) or systems using counted records, MUST translate to
- the canonical form.
-
- However, to ease the burden of implementation on servers that use a
- single, simple separator sequence, the following extension allows the
- canonical format to be changed.
-
- string "newline"
- string new-canonical-separator (usually "\r" or "\n" or "\r\n")
-
- All clients MUST support this extension.
-
- When processing text files, clients SHOULD NOT translate any
- character or sequence that is not an exact match of the servers
- newline separator.
-
- In particular, if the newline sequence being used is the canonical
- "\r\n" sequence, a lone \r or a lone \n SHOULD be written through
- without change.
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes.
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- byte type always present
- uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- string owner present only if flag SSH_FILEXFER_ATTR_OWNERGROUP
- string group present only if flag SSH_FILEXFER_ATTR_OWNERGROUP
- uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- uint32 atime present only if flag SSH_FILEXFER_ATTR_ACCESSTIME
- uint32 createtime present only if flag SSH_FILEXFER_ATTR_CREATETIME
- uint32 mtime present only if flag SSH_FILEXFER_ATTR_MODIFYTIME
- string acl present only if flag SSH_FILEXFER_ATTR_ACL
- uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
-
-5.1 Flags
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
- #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
- #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
- #define SSH_FILEXFER_ATTR_ACL 0x00000040
- #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- In previous versions of this protocol flags value 0x00000002 was
- SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP
- was given a new value in order to ease implementation burden.
- 0x00000002 MUST NOT appear in the mask. Some future version of this
- protocol may reuse flag 0x00000002.
-
-5.2 Type
-
- The type field is always present. The following types are defined:
-
- #define SSH_FILEXFER_TYPE_REGULAR 1
- #define SSH_FILEXFER_TYPE_DIRECTORY 2
- #define SSH_FILEXFER_TYPE_SYMLINK 3
- #define SSH_FILEXFER_TYPE_SPECIAL 4
- #define SSH_FILEXFER_TYPE_UNKNOWN 5
-
- On a POSIX system, these values would be derived from the permission
- field.
-
-5.3 Size
-
- The `size' field specifies the size of the file on disk, in bytes.
- If it is present during file creation, it should be considered a hint
- as to the files eventual size.
-
- Files opened with the SSH_FXF_TEXT flag may have a size that is
- greater or less than the value of the size field.
-
-5.4 Owner and Group
-
- The `owner' and `group' fields are represented as UTF-8 strings; this
- is the form used by NFS v4. See NFS version 4 Protocol. [3] The
- following text is selected quotations from section 5.6.
-
- To avoid a representation that is tied to a particular underlying
- implementation at the client or server, the use of UTF-8 strings has
- been chosen. The string should be of the form user@dns_domain".
- This will allow for a client and server that do not use the same
- local representation the ability to translate to a common syntax that
- can be interpreted by both. In the case where there is no
- translation available to the client or server, the attribute value
- must be constructed without the "@". Therefore, the absence of the @
- from the owner or owner_group attribute signifies that no translation
- was available and the receiver of the attribute should not place any
- special meaning with the attribute value. Even though the attribute
- value can not be translated, it may still be useful. In the case of
- a client, the attribute string may be used for local display of
- ownership.
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-5.5 Permissions
-
- The `permissions' field contains a bit mask of file permissions as
- defined by POSIX [1].
-
-5.6 Times
-
- The 'atime', 'createtime', and 'mtime' contain the access, creation,
- and modification times of the files, respectively. They are
- represented as seconds from Jan 1, 1970 in UTC.
-
-5.7 ACL
-
- The 'ACL' field contains an ACL similar to that defined in section
- 5.9 of NFS version 4 Protocol [3].
-
- uint32 ace-count
-
- repeated ace-count time:
- uint32 ace-type
- uint32 ace-flag
- uint32 ace-mask
- string who [UTF-8]
-
- ace-type is one of the following four values (taken from NFS Version
- 4 Protocol [3]:
-
- const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;
- const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;
- const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;
- const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;
-
- ace-flag is a combination of the following flag values. See NFS
- Version 4 Protocol [3] section 5.9.2:
-
- const ACE4_FILE_INHERIT_ACE = 0x00000001;
- const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;
- const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;
- const ACE4_INHERIT_ONLY_ACE = 0x00000008;
- const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;
- const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;
- const ACE4_IDENTIFIER_GROUP = 0x00000040;
-
- ace-mask is any combination of the following flags (taken from NFS
- Version 4 Protocol [3] section 5.9.3:
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- const ACE4_READ_DATA = 0x00000001;
- const ACE4_LIST_DIRECTORY = 0x00000001;
- const ACE4_WRITE_DATA = 0x00000002;
- const ACE4_ADD_FILE = 0x00000002;
- const ACE4_APPEND_DATA = 0x00000004;
- const ACE4_ADD_SUBDIRECTORY = 0x00000004;
- const ACE4_READ_NAMED_ATTRS = 0x00000008;
- const ACE4_WRITE_NAMED_ATTRS = 0x00000010;
- const ACE4_EXECUTE = 0x00000020;
- const ACE4_DELETE_CHILD = 0x00000040;
- const ACE4_READ_ATTRIBUTES = 0x00000080;
- const ACE4_WRITE_ATTRIBUTES = 0x00000100;
- const ACE4_DELETE = 0x00010000;
- const ACE4_READ_ACL = 0x00020000;
- const ACE4_WRITE_ACL = 0x00040000;
- const ACE4_WRITE_OWNER = 0x00080000;
- const ACE4_SYNCHRONIZE = 0x00100000;
-
- who is a UTF-8 string of the form described in 'Owner and Group'
- (Section 5.4)
-
-5.8 Extended attributes
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation is a monotonically increasing request
- sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- In order to comply with IETF Policy on Character Sets and Languages
- [2], all filenames are to be encoded in UTF-8. The shortest valid
- UTF-8 encoding of the UNICODE data MUST be used. The server is
- responsible for converting the UNICODE data to whatever canonical
- form it requires.
-
- For example, if the server requires that precomposed characters
- always be used, the server MUST NOT assume the filename as sent by
- the client has this attribute, but must do this normalization itself.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- string filename [UTF-8]
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- #define SSH_FXF_TEXT 0x00000040
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file. The
- offset parameter to write will be ignored.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FXF_TEXT
- Indicates that the server should treat the file as text and
- convert it to the canonical newline convention in use. (See
- Determining Server Newline Convention. (Section 4.3)
-
- When a file is opened with the FXF_TEXT flag, the offset field in
- both the read and write function are ignored.
-
- Servers MUST correctly process multiple parallel reads and writes
- correctly in this mode. Naturally, it is permissible for them to
- do this by serializing the requests. It would not be possible for
- a client to reliably detect a server that does not implement
- parallel writes in time to prevent damage.
-
- Clients SHOULD use the SSH_FXF_APPEND flag to append data to a
- text file rather then using write with a calculated offset.
-
- To support seeks on text file the following SSH_FXP_EXTENDED
- packet is defined.
-
-
-
- string "text-seek"
- string file-handle
- uint64 line-number
-
- line-number is the index of the line number to seek to, where byte
- 0 in the file is line number 0, and the byte directly following
- the first newline sequence in the file is line number 1 and so on.
-
- The response to a "text-seek" request is an SSH_FXP_STATUS
- message.
-
- An attempt to seek past the end-of-file should result in a
- SSH_FX_EOF status.
-
- Servers SHOULD support at least one "text-seek" in order to
- support resume. However, a client MUST be prepared to receive
- SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.
- The client can then try a fall-back strategy, if it has one.
-
- Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned
- for read or write operations that are not sequential.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the SSH_FXP_READ
- message, which has the following format:
-
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS. For normal disk
- files, it is guaranteed that this will read the specified number of
- bytes, or up to end of file. For e.g. device files this may return
- fewer bytes than requested.
-
- Writing to a file is achieved using the SSH_FXP_WRITE message, which
- has the following format:
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename [UTF-8]
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath [UTF-8]
- string newpath [UTF-8]
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- message.
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier.
-
- `path' specifies the directory to be created. See Section ``File
- Names'' for more information on file names.
-
- `attrs' specifies the attributes that should be applied to it upon
- creation. Attributes are discussed in more detail in Section ``File
- Attributes''.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message. If a file or directory with the specified path already
- exists, an error will be returned.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which has
- the following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names.
-
- The server responds to this request with a SSH_FXP_STATUS message.
- Errors may be returned from this operation for various reasons,
- including, but not limited to, the path does not exist, the path does
- not refer to a directory object, the directory is not empty, or the
- user has insufficient access or permission to perform the requested
- operation.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- If there are no more names available to be read, the server MUST
- respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path [UTF-8]
- uint32 flags
-
- where `id' is the request identifier, and `path' specifies the file
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- The flags field specify the attribute flags in which the client has
- particular interest. This is a hint to the server. For example,
- because retrieving owner / group and acl information can be an
- expensive operation under some operating systems, the server may
- choose not to retrieve this information unless the client expresses a
- specific interest in it.
-
- The client has no guarantee the server will provide all the fields
- that it has expressed an interest in.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
- uint32 flags
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
- uint32 id
- string linkpath [UTF-8]
- string targetpath [UTF-8]
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing the name in canonical form and a dummy
- attributes value. If an error occurs, the server may also respond
- with SSH_FXP_STATUS.
-
-6.11.1 Best practice for dealing with paths
-
- The client SHOULD treat the results of SSH_FXP_REALPATH as a
- canonical absolute path, even if the path does not appear to be
- absolute. A client that use REALPATH(".") and treats the result as
- absolute, even if there is no leading slash, will continue to
- function correctly, even when talking to a Windows NT or VMS style
- system, where absolute paths may not begin with a slash.
-
- For example, if the client wishes to change directory up, and the
- server has returned "c:/x/y/z" from REALPATH, the client SHOULD use
- "c:/x/y/z/..".
-
- As a second example, if the client wishes to open the file "x.txt" in
- the current directory, and server has returned "dka100:/x/y/z" as the
- canonical path of the directory, the client SHOULD open "dka100:/x/y/
- z/x.txt"
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- #define SSH_FX_INVALID_HANDLE 9
- #define SSH_FX_NO_SUCH_PATH 10
- #define SSH_FX_FILE_ALREADY_EXISTS 11
- #define SSH_FX_WRITE_PROTECT 12
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which does not
- exist.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- SSH_FX_INVALID_HANDLE
- The handle value was invalid.
-
- SSH_FX_NO_SUCH_PATH
- The file path does not exist or is invalid.
-
- SSH_FX_FILE_ALREADY_EXISTS
- The file already exists.
-
- SSH_FX_WRITE_PROTECT
- The file is on read only media, or the media is write protected.
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
- The SSH_FXP_NAME response has the following format:
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- uint32 count
- repeats count times:
- string filename [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- and `attrs' is the attributes of the file as described in Section
- ``File Attributes''.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
- There is a range of packet types reserved for use by extensions. In
- order to avoid collision, extensions that turn on the use of
- additional packet types should determine those numbers dynamically.
-
- The suggested way of doing this is have an extension request from the
- client to the server that enables the extension; the extension
- response from the server to the client would specify the actual type
- values to use, in additional to any other data.
-
- Extension authors should be mindful of the limited range of packet
- types available (there are only 45 values available) and avoid
- requiring a new packet type where possible.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [8].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 29]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 4 and 3
-
- Many of the changes between version 4 and version 3 are to the
- attribute structure to make it more flexible for non-unix platforms.
-
- o Make all filenames UTF-8.
-
- o Added 'newline' extension.
-
- o Made file attribute owner and group strings so they can actually
- be used on disparate systems.
-
- o Added createtime field, and added separate flags for atime,
- createtime, and mtime so they can be set separately.
-
- o Split the file type out of the permissions field and into it's own
- field (which is always present.)
-
- o Added acl attribute.
-
- o Added SSH_FXF_TEXT file open flag.
-
- o Added flags field to the get stat commands so that the client can
- specifically request information the server might not normally
- included for performance reasons.
-
- o Removed the long filename from the names structure-- it can now be
- built from information available in the attrs structure.
-
- o Added reserved range of packet numbers for extensions.
-
- o Added several additional error codes.
-
- o Change the way version negotiate works slightly. Previously, if
- the client version were higher than the server version, the server
- was supposed to 'echo back' the clients version. The server now
- sends it's own version and the lower of the two is considered to
- be the one in use.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 30]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-10.2 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.3 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.4 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 31]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 32]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",
- BCP 18, RFC 2277, January 1998.
-
- [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,
- C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC
- 3010, December 2000.
-
- [4] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-
- architecture-13 (work in progress), September 2002.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-
- transport-15 (work in progress), September 2002.
-
- [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16
- (work in progress), September 2002.
-
- [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-
- userauth-16 (work in progress), September 2002.
-
-
-Authors' Addresses
-
- Joseph Galbraith
- VanDyke Software
- 4848 Tramway Ridge Blvd
- Suite 101
- Albuquerque, NM 87111
- US
-
- Phone: +1 505 332 5700
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 33]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 34]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 35]
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt
deleted file mode 100644
index 9f51883cd2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt
+++ /dev/null
@@ -1,2130 +0,0 @@
-
-
-
-Secure Shell Working Group J. Galbraith
-Internet-Draft VanDyke Software
-Expires: June 18, 2003 T. Ylonen
- S. Lehtinen
- SSH Communications Security Corp
- December 18, 2002
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-04.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as
- Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on June 18, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . 5
- 3.1 The use of stderr in the server . . . . . . . . . . . . . 6
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . 8
- 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 8
- 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 8
- 4.3 Determining Server Newline Convention . . . . . . . . . . 9
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 10
- 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 11
- 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 14
- 6. Requests From the Client to the Server . . . . . . . . . . 15
- 6.1 Request Synchronization and Reordering . . . . . . . . . . 15
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 16
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 16
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 19
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 20
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . 21
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 21
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 22
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 23
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 24
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 25
- 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 25
- 7. Responses from the Server to the Client . . . . . . . . . 26
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 30
- 9. Security Considerations . . . . . . . . . . . . . . . . . 31
- 10. Changes from previous protocol versions . . . . . . . . . 32
- 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 32
- 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 33
- 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 33
- 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 33
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 34
- References . . . . . . . . . . . . . . . . . . . . . . . . 35
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . 35
- Intellectual Property and Copyright Statements . . . . . . 37
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [5].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft. [5]
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [7] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
- The following values are defined for packet types.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
-
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
-
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- RESERVED_FOR_EXTENSIONS 210-255
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-3.1 The use of stderr in the server
-
- Packets are sent and received on stdout and stdin. Data sent on
- stderr by the server SHOULD be considered debug or supplemental error
- information, and MAY be displayed to the user.
-
- For example, during initialization, there is no client request
- active, so errors or warning information cannot be sent to the client
- as part of the SFTP protocol at this early stage. However, the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- errors or warnings MAY be sent as stderr text.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, the client first sends a
- SSH_FXP_INIT (including its version number) packet to the server.
- The server responds with a SSH_FXP_VERSION packet, supplying the
- lowest of its own and the client's version number. Both parties
- should from then on adhere to particular version of the protocol.
-
- The version number of the protocol specified in this document is 4.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
-4.1 Client Initialization
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
-
- Version 3 of this protocol allowed clients to include extensions in
- the SSH_FXP_INIT packet; however, this can cause interoperability
- problems with version 1 and version 2 servers because the client must
- send this packet before knowing the servers version.
-
- In this version of the protocol, clients MUST use the
- SSH_FXP_EXTENDED packet to send extensions to the server after
- version exchange has completed. Clients MUST NOT include extensions
- in the version packet. This will prevent interoperability problems
- with older servers
-
-4.2 Server Initialization
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- 'version' is the lower of the protocol version supported by the
- server and the version number received from the client.
-
- The extension data may be empty, or may be a sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-4.3 Determining Server Newline Convention
-
- In order to correctly process text files in a cross platform
- compatible way, the newline convention must be converted from that of
- the server to that of the client, or, during an upload, from that of
- the client to that of the server.
-
- Versions 3 and prior of this protocol made no provisions for
- processing text files. Many clients implemented some sort of
- conversion algorithm, but without either a 'canonical' on the wire
- format or knowledge of the servers newline convention, correct
- conversion was not always possible.
-
- Starting with Version 4, the SSH_FXF_TEXT file open flag (Section
- 6.3) makes it possible to request that the server translate a file to
- a 'canonical' on the wire format. This format uses \r\n as the line
- separator.
-
- Servers for systems using multiple newline characters (for example,
- Mac OS X or VMS) or systems using counted records, MUST translate to
- the canonical form.
-
- However, to ease the burden of implementation on servers that use a
- single, simple separator sequence, the following extension allows the
- canonical format to be changed.
-
- string "newline"
- string new-canonical-separator (usually "\r" or "\n" or "\r\n")
-
- All clients MUST support this extension.
-
- When processing text files, clients SHOULD NOT translate any
- character or sequence that is not an exact match of the servers
- newline separator.
-
- In particular, if the newline sequence being used is the canonical
- "\r\n" sequence, a lone \r or a lone \n SHOULD be written through
- without change.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes.
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- byte type always present
- uint64 size present only if flag SIZE
- string owner present only if flag OWNERGROUP
- string group present only if flag OWNERGROUP
- uint32 permissions present only if flag PERMISSIONS
- uint64 atime present only if flag ACCESSTIME
- uint32 atime_nseconds present only if flag SUBSECOND_TIMES
- uint64 createtime present only if flag CREATETIME
- uint32 createtime_nseconds present only if flag SUBSECOND_TIMES
- uint64 mtime present only if flag MODIFYTIME
- uint32 mtime_nseconds present only if flag SUBSECOND_TIMES
- string acl present only if flag ACL
- uint32 extended_count present only if flag EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
-
-5.1 Flags
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The flags bits are defined to have the following values:
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000040
- #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
- #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
- #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
- #define SSH_FILEXFER_ATTR_ACL 0x00000040
- #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
- #define SSH_FILEXFER_ATTR_SUBSECOND_TIMES 0x00000100
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
- In previous versions of this protocol flags value 0x00000002 was
- SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP
- was given a new value in order to ease implementation burden.
- 0x00000002 MUST NOT appear in the mask. Some future version of this
- protocol may reuse flag 0x00000002.
-
-5.2 Type
-
- The type field is always present. The following types are defined:
-
- #define SSH_FILEXFER_TYPE_REGULAR 1
- #define SSH_FILEXFER_TYPE_DIRECTORY 2
- #define SSH_FILEXFER_TYPE_SYMLINK 3
- #define SSH_FILEXFER_TYPE_SPECIAL 4
- #define SSH_FILEXFER_TYPE_UNKNOWN 5
-
- On a POSIX system, these values would be derived from the permission
- field.
-
-5.3 Size
-
- The `size' field specifies the size of the file on disk, in bytes.
- If it is present during file creation, it should be considered a hint
- as to the files eventual size.
-
- Files opened with the SSH_FXF_TEXT flag may have a size that is
- greater or less than the value of the size field.
-
-5.4 Owner and Group
-
- The `owner' and `group' fields are represented as UTF-8 strings; this
- is the form used by NFS v4. See NFS version 4 Protocol. [3] The
- following text is selected quotations from section 5.6.
-
- To avoid a representation that is tied to a particular underlying
- implementation at the client or server, the use of UTF-8 strings has
- been chosen. The string should be of the form user@dns_domain".
- This will allow for a client and server that do not use the same
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- local representation the ability to translate to a common syntax that
- can be interpreted by both. In the case where there is no
- translation available to the client or server, the attribute value
- must be constructed without the "@". Therefore, the absence of the @
- from the owner or owner_group attribute signifies that no translation
- was available and the receiver of the attribute should not place any
- special meaning with the attribute value. Even though the attribute
- value can not be translated, it may still be useful. In the case of
- a client, the attribute string may be used for local display of
- ownership.
-
-5.5 Permissions
-
- The `permissions' field contains a bit mask of file permissions as
- defined by POSIX [1].
-
-5.6 Times
-
- The 'atime', 'createtime', and 'mtime' contain the access, creation,
- and modification times of the files, respectively. They are
- represented as seconds from Jan 1, 1970 in UTC.
-
- A negative value indicates number of seconds before Jan 1, 1970. In
- both cases, if the SSH_FILEXFER_ATTR_SUBSECOND_TIMES flag is set, the
- nseconds field is to be added to the seconds field for the final time
- representation. For example, if the time to be represented is
- one-half second before 0 hour January 1, 1970, the seconds field
- would have a value of negative one (-1) and the nseconds fields would
- have a value of one-half second (500000000). Values greater than
- 999,999,999 for nseconds are considered invalid.
-
-5.7 ACL
-
- The 'ACL' field contains an ACL similar to that defined in section
- 5.9 of NFS version 4 Protocol [3].
-
- uint32 ace-count
-
- repeated ace-count time:
- uint32 ace-type
- uint32 ace-flag
- uint32 ace-mask
- string who [UTF-8]
-
- ace-type is one of the following four values (taken from NFS Version
- 4 Protocol [3]:
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;
- const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;
- const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;
- const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;
-
- ace-flag is a combination of the following flag values. See NFS
- Version 4 Protocol [3] section 5.9.2:
-
- const ACE4_FILE_INHERIT_ACE = 0x00000001;
- const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;
- const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;
- const ACE4_INHERIT_ONLY_ACE = 0x00000008;
- const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;
- const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;
- const ACE4_IDENTIFIER_GROUP = 0x00000040;
-
- ace-mask is any combination of the following flags (taken from NFS
- Version 4 Protocol [3] section 5.9.3:
-
- const ACE4_READ_DATA = 0x00000001;
- const ACE4_LIST_DIRECTORY = 0x00000001;
- const ACE4_WRITE_DATA = 0x00000002;
- const ACE4_ADD_FILE = 0x00000002;
- const ACE4_APPEND_DATA = 0x00000004;
- const ACE4_ADD_SUBDIRECTORY = 0x00000004;
- const ACE4_READ_NAMED_ATTRS = 0x00000008;
- const ACE4_WRITE_NAMED_ATTRS = 0x00000010;
- const ACE4_EXECUTE = 0x00000020;
- const ACE4_DELETE_CHILD = 0x00000040;
- const ACE4_READ_ATTRIBUTES = 0x00000080;
- const ACE4_WRITE_ATTRIBUTES = 0x00000100;
- const ACE4_DELETE = 0x00010000;
- const ACE4_READ_ACL = 0x00020000;
- const ACE4_WRITE_ACL = 0x00040000;
- const ACE4_WRITE_OWNER = 0x00080000;
- const ACE4_SYNCHRONIZE = 0x00100000;
-
- who is a UTF-8 string of the form described in 'Owner and Group'
- (Section 5.4)
-
- Also, as per '5.9.4 ACE who' [3] there are several identifiers that
- need to be understood universally. Some of these identifiers cannot
- be understood when an client access the server, but have meaning when
- a local process accesses the file. The ability to display and modify
- these permissions is permitted over SFTP.
-
- OWNER The owner of the file.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- GROUP The group associated with the file.
-
- EVERYONE The world.
-
- INTERACTIVE Accessed from an interactive terminal.
-
- NETWORK Accessed via the network.
-
- DIALUP Accessed as a dialup user to the server.
-
- BATCH Accessed from a batch job.
-
- ANONYMOUS Accessed without any authentication.
-
- AUTHENTICATED Any authenticated user (opposite of ANONYMOUS).
-
- SERVICE Access from a system service.
-
- To avoid conflict, these special identifiers are distinguish by an
- appended "@" and should appear in the form "xxxx@" (note: no domain
- name after the "@"). For example: ANONYMOUS@.
-
-5.8 Extended attributes
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation is a monotonically increasing request
- sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- In order to comply with IETF Policy on Character Sets and Languages
- [2], all filenames are to be encoded in UTF-8. The shortest valid
- UTF-8 encoding of the UNICODE data MUST be used. The server is
- responsible for converting the UNICODE data to whatever canonical
- form it requires.
-
- For example, if the server requires that precomposed characters
- always be used, the server MUST NOT assume the filename as sent by
- the client has this attribute, but must do this normalization itself.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string filename [UTF-8]
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- #define SSH_FXF_TEXT 0x00000040
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file. The
- offset parameter to write will be ignored.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- SSH_FXF_TEXT
- Indicates that the server should treat the file as text and
- convert it to the canonical newline convention in use. (See
- Determining Server Newline Convention. (Section 4.3)
-
- When a file is opened with the FXF_TEXT flag, the offset field in
- both the read and write function are ignored.
-
- Servers MUST correctly process multiple parallel reads and writes
- correctly in this mode. Naturally, it is permissible for them to
- do this by serializing the requests. It would not be possible for
- a client to reliably detect a server that does not implement
- parallel writes in time to prevent damage.
-
- Clients SHOULD use the SSH_FXF_APPEND flag to append data to a
- text file rather then using write with a calculated offset.
-
- To support seeks on text file the following SSH_FXP_EXTENDED
- packet is defined.
-
-
-
- string "text-seek"
- string file-handle
- uint64 line-number
-
- line-number is the index of the line number to seek to, where byte
- 0 in the file is line number 0, and the byte directly following
- the first newline sequence in the file is line number 1 and so on.
-
- The response to a "text-seek" request is an SSH_FXP_STATUS
- message.
-
- An attempt to seek past the end-of-file should result in a
- SSH_FX_EOF status.
-
- Servers SHOULD support at least one "text-seek" in order to
- support resume. However, a client MUST be prepared to receive
- SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.
- The client can then try a fall-back strategy, if it has one.
-
- Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned
- for read or write operations that are not sequential.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the following
- message:
-
- byte SSH_FXP_READ
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS.
-
- For normal disk files, it is normally guaranteed that this will read
- the specified number of bytes, or up to end of file. However, if the
- read length is very long, the server may truncate it if it doesn't
- support packets of that length. See General Packet Format (Section
- 3).
-
- For e.g. device files this may return fewer bytes than requested.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- Writing to a file is achieved using the following message:
-
- byte SSH_FXP_WRITE
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename [UTF-8]
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath [UTF-8]
- string newpath [UTF-8]
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier.
-
- `path' specifies the directory to be created. See Section ``File
- Names'' for more information on file names.
-
- `attrs' specifies the attributes that should be applied to it upon
- creation. Attributes are discussed in more detail in Section ``File
- Attributes''.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message. If a file or directory with the specified path already
- exists, an error will be returned.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which has
- the following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names.
-
- The server responds to this request with a SSH_FXP_STATUS message.
- Errors may be returned from this operation for various reasons,
- including, but not limited to, the path does not exist, the path does
- not refer to a directory object, the directory is not empty, or the
- user has insufficient access or permission to perform the requested
- operation.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- If there are no more names available to be read, the server MUST
- respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path [UTF-8]
- uint32 flags
-
- where `id' is the request identifier, and `path' specifies the file
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- The flags field specify the attribute flags in which the client has
- particular interest. This is a hint to the server. For example,
- because retrieving owner / group and acl information can be an
- expensive operation under some operating systems, the server may
- choose not to retrieve this information unless the client expresses a
- specific interest in it.
-
- The client has no guarantee the server will provide all the fields
- that it has expressed an interest in.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
- uint32 flags
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string linkpath [UTF-8]
- string targetpath [UTF-8]
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing the name in canonical form and a dummy
- attributes value. If an error occurs, the server may also respond
- with SSH_FXP_STATUS.
-
-6.11.1 Best practice for dealing with paths
-
- The client SHOULD treat the results of SSH_FXP_REALPATH as a
- canonical absolute path, even if the path does not appear to be
- absolute. A client that use REALPATH(".") and treats the result as
- absolute, even if there is no leading slash, will continue to
- function correctly, even when talking to a Windows NT or VMS style
- system, where absolute paths may not begin with a slash.
-
- For example, if the client wishes to change directory up, and the
- server has returned "c:/x/y/z" from REALPATH, the client SHOULD use
- "c:/x/y/z/..".
-
- As a second example, if the client wishes to open the file "x.txt" in
- the current directory, and server has returned "dka100:/x/y/z" as the
- canonical path of the directory, the client SHOULD open "dka100:/x/y/
- z/x.txt"
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- #define SSH_FX_INVALID_HANDLE 9
- #define SSH_FX_NO_SUCH_PATH 10
- #define SSH_FX_FILE_ALREADY_EXISTS 11
- #define SSH_FX_WRITE_PROTECT 12
- #define SSH_FX_NO_MEDIA 13
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which does not
- exist.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- client, and MUST NOT be returned by servers).
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- SSH_FX_INVALID_HANDLE
- The handle value was invalid.
-
- SSH_FX_NO_SUCH_PATH
- The file path does not exist or is invalid.
-
- SSH_FX_FILE_ALREADY_EXISTS
- The file already exists.
-
- SSH_FX_WRITE_PROTECT
- The file is on read only media, or the media is write protected.
-
- SSH_FX_NO_MEDIA
- The requested operation can not be completed because there is no
- media available in the drive.
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- The SSH_FXP_NAME response has the following format:
-
- uint32 id
- uint32 count
- repeats count times:
- string filename [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- and `attrs' is the attributes of the file as described in Section
- ``File Attributes''.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 29]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
- There is a range of packet types reserved for use by extensions. In
- order to avoid collision, extensions that turn on the use of
- additional packet types should determine those numbers dynamically.
-
- The suggested way of doing this is have an extension request from the
- client to the server that enables the extension; the extension
- response from the server to the client would specify the actual type
- values to use, in additional to any other data.
-
- Extension authors should be mindful of the limited range of packet
- types available (there are only 45 values available) and avoid
- requiring a new packet type where possible.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 30]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [8].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 31]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 4 and 3
-
- Many of the changes between version 4 and version 3 are to the
- attribute structure to make it more flexible for non-unix platforms.
-
- o Clarify the use of stderr by the server.
-
- o Clarify handling of very large read requests by the server.
-
- o Make all filenames UTF-8.
-
- o Added 'newline' extension.
-
- o Made time fields 64 bit, and optionally have nanosecond resultion.
-
- o Made file attribute owner and group strings so they can actually
- be used on disparate systems.
-
- o Added createtime field, and added separate flags for atime,
- createtime, and mtime so they can be set separately.
-
- o Split the file type out of the permissions field and into it's own
- field (which is always present.)
-
- o Added acl attribute.
-
- o Added SSH_FXF_TEXT file open flag.
-
- o Added flags field to the get stat commands so that the client can
- specifically request information the server might not normally
- included for performance reasons.
-
- o Removed the long filename from the names structure-- it can now be
- built from information available in the attrs structure.
-
- o Added reserved range of packet numbers for extensions.
-
- o Added several additional error codes.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 32]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-10.2 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.3 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.4 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 33]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 34]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",
- BCP 18, RFC 2277, January 1998.
-
- [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,
- C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC
- 3010, December 2000.
-
- [4] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture",
- draft-ietf-secsh-architecture-13 (work in progress), September
- 2002.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol",
- draft-ietf-secsh-transport-15 (work in progress), September
- 2002.
-
- [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16
- (work in progress), September 2002.
-
- [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol",
- draft-ietf-secsh-userauth-16 (work in progress), September 2002.
-
-
-Authors' Addresses
-
- Joseph Galbraith
- VanDyke Software
- 4848 Tramway Ridge Blvd
- Suite 101
- Albuquerque, NM 87111
- US
-
- Phone: +1 505 332 5700
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 35]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 36]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 37]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 38]
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps
deleted file mode 100644
index d692285b4e..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps
+++ /dev/null
@@ -1,3205 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:35:14 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Editor, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Transport Layer Protocol) s
-5 613 M
-( draft-ietf-secsh-transport-17.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network.) s
-5 250 M
-( This document describes the SSH transport layer protocol which) s
-5 239 M
-( typically runs on top of TCP/IP. The protocol can be used as a basis) s
-5 228 M
-( for a number of secure network services. It provides strong) s
-5 217 M
-( encryption, server authentication, and integrity protection. It may) s
-5 206 M
-( also provide compression.) s
-5 184 M
-( Key exchange method, public key algorithm, symmetric encryption) s
-5 173 M
-( algorithm, message authentication algorithm, and hash algorithm are) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( all negotiated.) s
-5 668 M
-( This document also describes the Diffie-Hellman key exchange method) s
-5 657 M
-( and the minimal set of algorithms that are needed to implement the) s
-5 646 M
-( SSH transport layer protocol.) s
-5 624 M
-(Table of Contents) s
-5 602 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 591 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 580 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 569 M
-( 4. Connection Setup . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 558 M
-( 4.1 Use over TCP/IP . . . . . . . . . . . . . . . . . . . . . . 4) s
-5 547 M
-( 4.2 Protocol Version Exchange . . . . . . . . . . . . . . . . . 4) s
-5 536 M
-( 4.3 Compatibility With Old SSH Versions . . . . . . . . . . . . 4) s
-5 525 M
-( 4.3.1 Old Client, New Server . . . . . . . . . . . . . . . . . . . 5) s
-5 514 M
-( 4.3.2 New Client, Old Server . . . . . . . . . . . . . . . . . . . 5) s
-5 503 M
-( 5. Binary Packet Protocol . . . . . . . . . . . . . . . . . . . 5) s
-5 492 M
-( 5.1 Maximum Packet Length . . . . . . . . . . . . . . . . . . . 6) s
-5 481 M
-( 5.2 Compression . . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 470 M
-( 5.3 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 459 M
-( 5.4 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 448 M
-( 5.5 Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 10) s
-5 437 M
-( 5.6 Public Key Algorithms . . . . . . . . . . . . . . . . . . . 11) s
-5 426 M
-( 6. Key Exchange . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 415 M
-( 6.1 Algorithm Negotiation . . . . . . . . . . . . . . . . . . . 13) s
-5 404 M
-( 6.2 Output from Key Exchange . . . . . . . . . . . . . . . . . . 16) s
-5 393 M
-( 6.3 Taking Keys Into Use . . . . . . . . . . . . . . . . . . . . 17) s
-5 382 M
-( 7. Diffie-Hellman Key Exchange . . . . . . . . . . . . . . . . 18) s
-5 371 M
-( 7.1 diffie-hellman-group1-sha1 . . . . . . . . . . . . . . . . . 19) s
-5 360 M
-( 8. Key Re-Exchange . . . . . . . . . . . . . . . . . . . . . . 20) s
-5 349 M
-( 9. Service Request . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 338 M
-( 10. Additional Messages . . . . . . . . . . . . . . . . . . . . 21) s
-5 327 M
-( 10.1 Disconnection Message . . . . . . . . . . . . . . . . . . . 22) s
-5 316 M
-( 10.2 Ignored Data Message . . . . . . . . . . . . . . . . . . . . 22) s
-5 305 M
-( 10.3 Debug Message . . . . . . . . . . . . . . . . . . . . . . . 23) s
-5 294 M
-( 10.4 Reserved Messages . . . . . . . . . . . . . . . . . . . . . 23) s
-5 283 M
-( 11. Summary of Message Numbers . . . . . . . . . . . . . . . . . 23) s
-5 272 M
-( 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 24) s
-5 261 M
-( 13. Security Considerations . . . . . . . . . . . . . . . . . . 24) s
-5 250 M
-( 14. Intellectual Property . . . . . . . . . . . . . . . . . . . 24) s
-5 239 M
-( 15. Additional Information . . . . . . . . . . . . . . . . . . . 24) s
-5 228 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 26) s
-5 217 M
-( Normative . . . . . . . . . . . . . . . . . . . . . . . . . 25) s
-5 206 M
-( Informative . . . . . . . . . . . . . . . . . . . . . . . . 25) s
-5 195 M
-( A. Contibutors . . . . . . . . . . . . . . . . . . . . . . . . 27) s
-5 184 M
-( Intellectual Property and Copyright Statements . . . . . . . 28) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH transport layer is a secure low level transport protocol. It) s
-5 536 M
-( provides strong encryption, cryptographic host authentication, and) s
-5 525 M
-( integrity protection.) s
-5 503 M
-( Authentication in this protocol level is host-based; this protocol) s
-5 492 M
-( does not perform user authentication. A higher level protocol for) s
-5 481 M
-( user authentication can be designed on top of this protocol.) s
-5 459 M
-( The protocol has been designed to be simple, flexible, to allow) s
-5 448 M
-( parameter negotiation, and to minimize the number of round-trips.) s
-5 437 M
-( Key exchange method, public key algorithm, symmetric encryption) s
-5 426 M
-( algorithm, message authentication algorithm, and hash algorithm are) s
-5 415 M
-( all negotiated. It is expected that in most environments, only 2) s
-5 404 M
-( round-trips will be needed for full key exchange, server) s
-5 393 M
-( authentication, service request, and acceptance notification of) s
-5 382 M
-( service request. The worst case is 3 round-trips.) s
-5 360 M
-(3. Conventions Used in This Document) s
-5 338 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 327 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 316 M
-( described in [RFC2119].) s
-5 294 M
-( The used data types and terminology are specified in the architecture) s
-5 283 M
-( document [SSH-ARCH].) s
-5 261 M
-( The architecture document also discusses the algorithm naming) s
-5 250 M
-( conventions that MUST be used with the SSH protocols.) s
-5 228 M
-(4. Connection Setup) s
-5 206 M
-( SSH works over any 8-bit clean, binary-transparent transport. The) s
-5 195 M
-( underlying transport SHOULD protect against transmission errors as) s
-5 184 M
-( such errors cause the SSH connection to terminate.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The client initiates the connection.) s
-5 668 M
-(4.1 Use over TCP/IP) s
-5 646 M
-( When used over TCP/IP, the server normally listens for connections on) s
-5 635 M
-( port 22. This port number has been registered with the IANA, and has) s
-5 624 M
-( been officially assigned for SSH.) s
-5 602 M
-(4.2 Protocol Version Exchange) s
-5 580 M
-( When the connection has been established, both sides MUST send an) s
-5 569 M
-( identification string of the form "SSH-protoversion-softwareversion) s
-5 558 M
-( comments", followed by carriage return and newline characters \(ASCII) s
-5 547 M
-( 13 and 10, respectively\). Both sides MUST be able to process) s
-5 536 M
-( identification strings without carriage return character. No null) s
-5 525 M
-( character is sent. The maximum length of the string is 255) s
-5 514 M
-( characters, including the carriage return and newline.) s
-5 492 M
-( The part of the identification string preceding carriage return and) s
-5 481 M
-( newline is used in the Diffie-Hellman key exchange \(see Section) s
-5 470 M
-( Section 7\).) s
-5 448 M
-( The server MAY send other lines of data before sending the version) s
-5 437 M
-( string. Each line SHOULD be terminated by a carriage return and) s
-5 426 M
-( newline. Such lines MUST NOT begin with "SSH-", and SHOULD be) s
-5 415 M
-( encoded in ISO-10646 UTF-8 [RFC2279] \(language is not specified\).) s
-5 404 M
-( Clients MUST be able to process such lines; they MAY be silently) s
-5 393 M
-( ignored, or MAY be displayed to the client user; if they are) s
-5 382 M
-( displayed, control character filtering discussed in [SSH-ARCH] SHOULD) s
-5 371 M
-( be used. The primary use of this feature is to allow TCP-wrappers to) s
-5 360 M
-( display an error message before disconnecting.) s
-5 338 M
-( Version strings MUST consist of printable US-ASCII characters, not) s
-5 327 M
-( including whitespaces or a minus sign \(-\). The version string is) s
-5 316 M
-( primarily used to trigger compatibility extensions and to indicate) s
-5 305 M
-( the capabilities of an implementation. The comment string should) s
-5 294 M
-( contain additional information that might be useful in solving user) s
-5 283 M
-( problems.) s
-5 261 M
-( The protocol version described in this document is 2.0.) s
-5 239 M
-( Key exchange will begin immediately after sending this identifier.) s
-5 228 M
-( All packets following the identification string SHALL use the binary) s
-5 217 M
-( packet protocol, to be described below.) s
-5 195 M
-(4.3 Compatibility With Old SSH Versions) s
-5 173 M
-( During the transition period, it is important to be able to work in a) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( way that is compatible with the installed SSH clients and servers) s
-5 679 M
-( that use an older version of the protocol. Information in this) s
-5 668 M
-( section is only relevant for implementations supporting compatibility) s
-5 657 M
-( with SSH versions 1.x. There is no standards track or informational) s
-5 646 M
-( draft available that defines the SSH 1.x protocol. The only known) s
-5 635 M
-( documentation of the 1.x protocol is contained in README files that) s
-5 624 M
-( are shipped along with the source code.) s
-5 602 M
-(4.3.1 Old Client, New Server) s
-5 580 M
-( Server implementations MAY support a configurable "compatibility") s
-5 569 M
-( flag that enables compatibility with old versions. When this flag is) s
-5 558 M
-( on, the server SHOULD identify its protocol version as "1.99".) s
-5 547 M
-( Clients using protocol 2.0 MUST be able to identify this as identical) s
-5 536 M
-( to "2.0". In this mode the server SHOULD NOT send the carriage) s
-5 525 M
-( return character \(ASCII 13\) after the version identification string.) s
-5 503 M
-( In the compatibility mode the server SHOULD NOT send any further data) s
-5 492 M
-( after its initialization string until it has received an) s
-5 481 M
-( identification string from the client. The server can then determine) s
-5 470 M
-( whether the client is using an old protocol, and can revert to the) s
-5 459 M
-( old protocol if required. In the compatibility mode, the server MUST) s
-5 448 M
-( NOT send additional data before the version string.) s
-5 426 M
-( When compatibility with old clients is not needed, the server MAY) s
-5 415 M
-( send its initial key exchange data immediately after the) s
-5 404 M
-( identification string.) s
-5 382 M
-(4.3.2 New Client, Old Server) s
-5 360 M
-( Since the new client MAY immediately send additional data after its) s
-5 349 M
-( identification string \(before receiving server's identification\), the) s
-5 338 M
-( old protocol may already have been corrupted when the client learns) s
-5 327 M
-( that the server is old. When this happens, the client SHOULD close) s
-5 316 M
-( the connection to the server, and reconnect using the old protocol.) s
-5 294 M
-(5. Binary Packet Protocol) s
-5 272 M
-( Each packet is in the following format:) s
-5 250 M
-( uint32 packet_length) s
-5 239 M
-( byte padding_length) s
-5 228 M
-( byte[n1] payload; n1 = packet_length - padding_length - 1) s
-5 217 M
-( byte[n2] random padding; n2 = padding_length) s
-5 206 M
-( byte[m] mac \(message authentication code\); m = mac_length) s
-5 184 M
-( packet_length) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The length of the packet \(bytes\), not including MAC or the) s
-5 679 M
-( packet_length field itself.) s
-5 657 M
-( padding_length) s
-5 646 M
-( Length of padding \(bytes\).) s
-5 624 M
-( payload) s
-5 613 M
-( The useful contents of the packet. If compression has been) s
-5 602 M
-( negotiated, this field is compressed. Initially, compression) s
-5 591 M
-( MUST be "none".) s
-5 569 M
-( random padding) s
-5 558 M
-( Arbitrary-length padding, such that the total length of) s
-5 547 M
-( \(packet_length || padding_length || payload || padding\) is a) s
-5 536 M
-( multiple of the cipher block size or 8, whichever is larger.) s
-5 525 M
-( There MUST be at least four bytes of padding. The padding) s
-5 514 M
-( SHOULD consist of random bytes. The maximum amount of padding) s
-5 503 M
-( is 255 bytes.) s
-5 481 M
-( mac) s
-5 470 M
-( Message authentication code. If message authentication has) s
-5 459 M
-( been negotiated, this field contains the MAC bytes. Initially,) s
-5 448 M
-( the MAC algorithm MUST be "none".) s
-5 415 M
-( Note that length of the concatenation of packet length, padding) s
-5 404 M
-( length, payload, and padding MUST be a multiple of the cipher block) s
-5 393 M
-( size or 8, whichever is larger. This constraint MUST be enforced) s
-5 382 M
-( even when using stream ciphers. Note that the packet length field is) s
-5 371 M
-( also encrypted, and processing it requires special care when sending) s
-5 360 M
-( or receiving packets.) s
-5 338 M
-( The minimum size of a packet is 16 \(or the cipher block size,) s
-5 327 M
-( whichever is larger\) bytes \(plus MAC\); implementations SHOULD decrypt) s
-5 316 M
-( the length after receiving the first 8 \(or cipher block size,) s
-5 305 M
-( whichever is larger\) bytes of a packet.) s
-5 283 M
-(5.1 Maximum Packet Length) s
-5 261 M
-( All implementations MUST be able to process packets with uncompressed) s
-5 250 M
-( payload length of 32768 bytes or less and total packet size of 35000) s
-5 239 M
-( bytes or less \(including length, padding length, payload, padding,) s
-5 228 M
-( and MAC.\). The maximum of 35000 bytes is an arbitrary chosen value) s
-5 217 M
-( larger than uncompressed size. Implementations SHOULD support longer) s
-5 206 M
-( packets, where they might be needed, e.g. if an implementation wants) s
-5 195 M
-( to send a very large number of certificates. Such packets MAY be) s
-5 184 M
-( sent if the version string indicates that the other party is able to) s
-5 173 M
-( process them. However, implementations SHOULD check that the packet) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( length is reasonable for the implementation to avoid) s
-5 679 M
-( denial-of-service and/or buffer overflow attacks.) s
-5 657 M
-(5.2 Compression) s
-5 635 M
-( If compression has been negotiated, the payload field \(and only it\)) s
-5 624 M
-( will be compressed using the negotiated algorithm. The length field) s
-5 613 M
-( and MAC will be computed from the compressed payload. Encryption will) s
-5 602 M
-( be done after compression.) s
-5 580 M
-( Compression MAY be stateful, depending on the method. Compression) s
-5 569 M
-( MUST be independent for each direction, and implementations MUST) s
-5 558 M
-( allow independently choosing the algorithm for each direction.) s
-5 536 M
-( The following compression methods are currently defined:) s
-5 514 M
-( none REQUIRED no compression) s
-5 503 M
-( zlib OPTIONAL ZLIB \(LZ77\) compression) s
-5 481 M
-( The "zlib" compression is described in [RFC1950] and in [RFC1951].) s
-5 470 M
-( The compression context is initialized after each key exchange, and) s
-5 459 M
-( is passed from one packet to the next with only a partial flush being) s
-5 448 M
-( performed at the end of each packet. A partial flush means that the) s
-5 437 M
-( current compressed block is ended and all data will be output. If the) s
-5 426 M
-( current block is not a stored block, one or more empty blocks are) s
-5 415 M
-( added after the current block to ensure that there are at least 8) s
-5 404 M
-( bits counting from the start of the end-of-block code of the current) s
-5 393 M
-( block to the end of the packet payload.) s
-5 371 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 349 M
-(5.3 Encryption) s
-5 327 M
-( An encryption algorithm and a key will be negotiated during the key) s
-5 316 M
-( exchange. When encryption is in effect, the packet length, padding) s
-5 305 M
-( length, payload and padding fields of each packet MUST be encrypted) s
-5 294 M
-( with the given algorithm.) s
-5 272 M
-( The encrypted data in all packets sent in one direction SHOULD be) s
-5 261 M
-( considered a single data stream. For example, initialization vectors) s
-5 250 M
-( SHOULD be passed from the end of one packet to the beginning of the) s
-5 239 M
-( next packet. All ciphers SHOULD use keys with an effective key length) s
-5 228 M
-( of 128 bits or more.) s
-5 206 M
-( The ciphers in each direction MUST run independently of each other,) s
-5 195 M
-( and implementations MUST allow independently choosing the algorithm) s
-5 184 M
-( for each direction \(if multiple algorithms are allowed by local) s
-5 173 M
-( policy\).) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The following ciphers are currently defined:) s
-5 668 M
-( 3des-cbc REQUIRED three-key 3DES in CBC mode) s
-5 657 M
-( blowfish-cbc OPTIONALi Blowfish in CBC mode) s
-5 646 M
-( twofish256-cbc OPTIONAL Twofish in CBC mode,) s
-5 635 M
-( with 256-bit key) s
-5 624 M
-( twofish-cbc OPTIONAL alias for "twofish256-cbc" \(this) s
-5 613 M
-( is being retained for) s
-5 602 M
-( historical reasons\)) s
-5 591 M
-( twofish192-cbc OPTIONAL Twofish with 192-bit key) s
-5 580 M
-( twofish128-cbc OPTIONAL Twofish with 128-bit key) s
-5 569 M
-( aes256-cbc OPTIONAL AES \(Rijndael\) in CBC mode,) s
-5 558 M
-( with 256-bit key) s
-5 547 M
-( aes192-cbc OPTIONAL AES with 192-bit key) s
-5 536 M
-( aes128-cbc RECOMMENDED AES with 128-bit key) s
-5 525 M
-( serpent256-cbc OPTIONAL Serpent in CBC mode, with) s
-5 514 M
-( 256-bit key) s
-5 503 M
-( serpent192-cbc OPTIONAL Serpent with 192-bit key) s
-5 492 M
-( serpent128-cbc OPTIONAL Serpent with 128-bit key) s
-5 481 M
-( arcfour OPTIONAL the ARCFOUR stream cipher) s
-5 470 M
-( idea-cbc OPTIONAL IDEA in CBC mode) s
-5 459 M
-( cast128-cbc OPTIONAL CAST-128 in CBC mode) s
-5 448 M
-( none OPTIONAL no encryption; NOT RECOMMENDED) s
-5 426 M
-( The "3des-cbc" cipher is three-key triple-DES) s
-5 415 M
-( \(encrypt-decrypt-encrypt\), where the first 8 bytes of the key are) s
-5 404 M
-( used for the first encryption, the next 8 bytes for the decryption,) s
-5 393 M
-( and the following 8 bytes for the final encryption. This requires 24) s
-5 382 M
-( bytes of key data \(of which 168 bits are actually used\). To) s
-5 371 M
-( implement CBC mode, outer chaining MUST be used \(i.e., there is only) s
-5 360 M
-( one initialization vector\). This is a block cipher with 8 byte) s
-5 349 M
-( blocks. This algorithm is defined in [FIPS-46-3]) s
-5 327 M
-( The "blowfish-cbc" cipher is Blowfish in CBC mode, with 128 bit keys) s
-5 316 M
-( [SCHNEIER]. This is a block cipher with 8 byte blocks.) s
-5 294 M
-( The "twofish-cbc" or "twofish256-cbc" cipher is Twofish in CBC mode,) s
-5 283 M
-( with 256 bit keys as described [TWOFISH]. This is a block cipher with) s
-5 272 M
-( 16 byte blocks.) s
-5 250 M
-( The "twofish192-cbc" cipher. Same as above but with 192-bit key.) s
-5 228 M
-( The "twofish128-cbc" cipher. Same as above but with 128-bit key.) s
-5 206 M
-( The "aes256-cbc" cipher is AES \(Advanced Encryption Standard\)) s
-5 195 M
-( [FIPS-197], formerly Rijndael, in CBC mode. This version uses 256-bit) s
-5 184 M
-( key.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The "aes192-cbc" cipher. Same as above but with 192-bit key.) s
-5 668 M
-( The "aes128-cbc" cipher. Same as above but with 128-bit key.) s
-5 646 M
-( The "serpent256-cbc" cipher in CBC mode, with 256-bit key as) s
-5 635 M
-( described in the Serpent AES submission.) s
-5 613 M
-( The "serpent192-cbc" cipher. Same as above but with 192-bit key.) s
-5 591 M
-( The "serpent128-cbc" cipher. Same as above but with 128-bit key.) s
-5 569 M
-( The "arcfour" is the Arcfour stream cipher with 128 bit keys. The) s
-5 558 M
-( Arcfour cipher is believed to be compatible with the RC4 cipher) s
-5 547 M
-( [SCHNEIER]. RC4 is a registered trademark of RSA Data Security Inc.) s
-5 536 M
-( Arcfour \(and RC4\) has problems with weak keys, and should be used) s
-5 525 M
-( with caution.) s
-5 503 M
-( The "idea-cbc" cipher is the IDEA cipher in CBC mode [SCHNEIER].) s
-5 481 M
-( The "cast128-cbc" cipher is the CAST-128 cipher in CBC mode) s
-5 470 M
-( [RFC2144].) s
-5 448 M
-( The "none" algorithm specifies that no encryption is to be done.) s
-5 437 M
-( Note that this method provides no confidentiality protection, and it) s
-5 426 M
-( is not recommended. Some functionality \(e.g. password) s
-5 415 M
-( authentication\) may be disabled for security reasons if this cipher) s
-5 404 M
-( is chosen.) s
-5 382 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 360 M
-(5.4 Data Integrity) s
-5 338 M
-( Data integrity is protected by including with each packet a message) s
-5 327 M
-( authentication code \(MAC\) that is computed from a shared secret,) s
-5 316 M
-( packet sequence number, and the contents of the packet.) s
-5 294 M
-( The message authentication algorithm and key are negotiated during) s
-5 283 M
-( key exchange. Initially, no MAC will be in effect, and its length) s
-5 272 M
-( MUST be zero. After key exchange, the selected MAC will be computed) s
-5 261 M
-( before encryption from the concatenation of packet data:) s
-5 239 M
-( mac = MAC\(key, sequence_number || unencrypted_packet\)) s
-5 217 M
-( where unencrypted_packet is the entire packet without MAC \(the length) s
-5 206 M
-( fields, payload and padding\), and sequence_number is an implicit) s
-5 195 M
-( packet sequence number represented as uint32. The sequence number is) s
-5 184 M
-( initialized to zero for the first packet, and is incremented after) s
-5 173 M
-( every packet \(regardless of whether encryption or MAC is in use\). It) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( is never reset, even if keys/algorithms are renegotiated later. It) s
-5 679 M
-( wraps around to zero after every 2^32 packets. The packet sequence) s
-5 668 M
-( number itself is not included in the packet sent over the wire.) s
-5 646 M
-( The MAC algorithms for each direction MUST run independently, and) s
-5 635 M
-( implementations MUST allow choosing the algorithm independently for) s
-5 624 M
-( both directions.) s
-5 602 M
-( The MAC bytes resulting from the MAC algorithm MUST be transmitted) s
-5 591 M
-( without encryption as the last part of the packet. The number of MAC) s
-5 580 M
-( bytes depends on the algorithm chosen.) s
-5 558 M
-( The following MAC algorithms are currently defined:) s
-5 536 M
-( hmac-sha1 REQUIRED HMAC-SHA1 \(digest length = key) s
-5 525 M
-( length = 20\)) s
-5 514 M
-( hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 \(digest) s
-5 503 M
-( length = 12, key length = 20\)) s
-5 492 M
-( hmac-md5 OPTIONAL HMAC-MD5 \(digest length = key) s
-5 481 M
-( length = 16\)) s
-5 470 M
-( hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 \(digest) s
-5 459 M
-( length = 12, key length = 16\)) s
-5 448 M
-( none OPTIONAL no MAC; NOT RECOMMENDED) s
-5 426 M
-( Figure 1) s
-5 404 M
-( The "hmac-*" algorithms are described in [RFC2104] The "*-n" MACs use) s
-5 393 M
-( only the first n bits of the resulting value.) s
-5 371 M
-( The hash algorithms are described in [SCHNEIER].) s
-5 349 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 327 M
-(5.5 Key Exchange Methods) s
-5 305 M
-( The key exchange method specifies how one-time session keys are) s
-5 294 M
-( generated for encryption and for authentication, and how the server) s
-5 283 M
-( authentication is done.) s
-5 261 M
-( Only one REQUIRED key exchange method has been defined:) s
-5 239 M
-( diffie-hellman-group1-sha1 REQUIRED) s
-5 217 M
-( This method is described later in this document.) s
-5 195 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(5.6 Public Key Algorithms) s
-5 668 M
-( This protocol has been designed to be able to operate with almost any) s
-5 657 M
-( public key format, encoding, and algorithm \(signature and/or) s
-5 646 M
-( encryption\).) s
-5 624 M
-( There are several aspects that define a public key type:) s
-5 613 M
-( o Key format: how is the key encoded and how are certificates) s
-5 602 M
-( represented. The key blobs in this protocol MAY contain) s
-5 591 M
-( certificates in addition to keys.) s
-5 580 M
-( o Signature and/or encryption algorithms. Some key types may not) s
-5 569 M
-( support both signing and encryption. Key usage may also be) s
-5 558 M
-( restricted by policy statements in e.g. certificates. In this) s
-5 547 M
-( case, different key types SHOULD be defined for the different) s
-5 536 M
-( policy alternatives.) s
-5 525 M
-( o Encoding of signatures and/or encrypted data. This includes but is) s
-5 514 M
-( not limited to padding, byte order, and data formats.) s
-5 492 M
-( The following public key and/or certificate formats are currently defined:) s
-5 470 M
-( ssh-dss REQUIRED sign Raw DSS Key) s
-5 459 M
-( ssh-rsa RECOMMENDED sign Raw RSA Key) s
-5 448 M
-( x509v3-sign-rsa OPTIONAL sign X.509 certificates \(RSA key\)) s
-5 437 M
-( x509v3-sign-dss OPTIONAL sign X.509 certificates \(DSS key\)) s
-5 426 M
-( spki-sign-rsa OPTIONAL sign SPKI certificates \(RSA key\)) s
-5 415 M
-( spki-sign-dss OPTIONAL sign SPKI certificates \(DSS key\)) s
-5 404 M
-( pgp-sign-rsa OPTIONAL sign OpenPGP certificates \(RSA key\)) s
-5 393 M
-( pgp-sign-dss OPTIONAL sign OpenPGP certificates \(DSS key\)) s
-5 371 M
-( Additional key types may be defined as specified in [SSH-ARCH].) s
-5 349 M
-( The key type MUST always be explicitly known \(from algorithm) s
-5 338 M
-( negotiation or some other source\). It is not normally included in) s
-5 327 M
-( the key blob.) s
-5 305 M
-( Certificates and public keys are encoded as follows:) s
-5 283 M
-( string certificate or public key format identifier) s
-5 272 M
-( byte[n] key/certificate data) s
-5 250 M
-( The certificate part may have be a zero length string, but a public) s
-5 239 M
-( key is required. This is the public key that will be used for) s
-5 228 M
-( authentication; the certificate sequence contained in the certificate) s
-5 217 M
-( blob can be used to provide authorization.) s
-5 195 M
-( Public key / certifcate formats that do not explicitly specify a) s
-5 184 M
-( signature format identifier MUST use the public key / certificate) s
-5 173 M
-( format identifier as the signature identifier.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( Signatures are encoded as follows:) s
-5 679 M
-( string signature format identifier \(as specified by the) s
-5 668 M
-( public key / cert format\)) s
-5 657 M
-( byte[n] signature blob in format specific encoding.) s
-5 624 M
-( The "ssh-dss" key format has the following specific encoding:) s
-5 602 M
-( string "ssh-dss") s
-5 591 M
-( mpint p) s
-5 580 M
-( mpint q) s
-5 569 M
-( mpint g) s
-5 558 M
-( mpint y) s
-5 536 M
-( Here the p, q, g, and y parameters form the signature key blob.) s
-5 514 M
-( Signing and verifying using this key format is done according to the) s
-5 503 M
-( Digital Signature Standard [FIPS-186] using the SHA-1 hash. A) s
-5 492 M
-( description can also be found in [SCHNEIER].) s
-5 470 M
-( The resulting signature is encoded as follows:) s
-5 448 M
-( string "ssh-dss") s
-5 437 M
-( string dss_signature_blob) s
-5 415 M
-( dss_signature_blob is encoded as a string containing r followed by s) s
-5 404 M
-( \(which are 160 bits long integers, without lengths or padding,) s
-5 393 M
-( unsigned and in network byte order\).) s
-5 371 M
-( The "ssh-rsa" key format has the following specific encoding:) s
-5 349 M
-( string "ssh-rsa") s
-5 338 M
-( mpint e) s
-5 327 M
-( mpint n) s
-5 305 M
-( Here the e and n parameters form the signature key blob.) s
-5 283 M
-( Signing and verifying using this key format is done according to) s
-5 272 M
-( [SCHNEIER] and [PKCS1] using the SHA-1 hash.) s
-5 250 M
-( The resulting signature is encoded as follows:) s
-5 228 M
-( string "ssh-rsa") s
-5 217 M
-( string rsa_signature_blob) s
-5 195 M
-( rsa_signature_blob is encoded as a string containing s \(which is an) s
-5 184 M
-( integer, without lengths or padding, unsigned and in network byte) s
-5 173 M
-( order\).) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The "spki-sign-rsa" method indicates that the certificate blob) s
-5 679 M
-( contains a sequence of SPKI certificates. The format of SPKI) s
-5 668 M
-( certificates is described in [RFC2693]. This method indicates that) s
-5 657 M
-( the key \(or one of the keys in the certificate\) is an RSA-key.) s
-5 635 M
-( The "spki-sign-dss". As above, but indicates that the key \(or one of) s
-5 624 M
-( the keys in the certificate\) is a DSS-key.) s
-5 602 M
-( The "pgp-sign-rsa" method indicates the certificates, the public key,) s
-5 591 M
-( and the signature are in OpenPGP compatible binary format) s
-5 580 M
-( \([RFC2440]\). This method indicates that the key is an RSA-key.) s
-5 558 M
-( The "pgp-sign-dss". As above, but indicates that the key is a) s
-5 547 M
-( DSS-key.) s
-5 525 M
-(6. Key Exchange) s
-5 503 M
-( Key exchange begins by each side sending lists of supported) s
-5 492 M
-( algorithms. Each side has a preferred algorithm in each category, and) s
-5 481 M
-( it is assumed that most implementations at any given time will use) s
-5 470 M
-( the same preferred algorithm. Each side MAY guess which algorithm) s
-5 459 M
-( the other side is using, and MAY send an initial key exchange packet) s
-5 448 M
-( according to the algorithm if appropriate for the preferred method.) s
-5 426 M
-( Guess is considered wrong, if:) s
-5 415 M
-( o the kex algorithm and/or the host key algorithm is guessed wrong) s
-5 404 M
-( \(server and client have different preferred algorithm\), or) s
-5 393 M
-( o if any of the other algorithms cannot be agreed upon \(the) s
-5 382 M
-( procedure is defined below in Section Section 6.1\).) s
-5 360 M
-( Otherwise, the guess is considered to be right and the optimistically) s
-5 349 M
-( sent packet MUST be handled as the first key exchange packet.) s
-5 327 M
-( However, if the guess was wrong, and a packet was optimistically sent) s
-5 316 M
-( by one or both parties, such packets MUST be ignored \(even if the) s
-5 305 M
-( error in the guess would not affect the contents of the initial) s
-5 294 M
-( packet\(s\)\), and the appropriate side MUST send the correct initial) s
-5 283 M
-( packet.) s
-5 261 M
-( Server authentication in the key exchange MAY be implicit. After a) s
-5 250 M
-( key exchange with implicit server authentication, the client MUST) s
-5 239 M
-( wait for response to its service request message before sending any) s
-5 228 M
-( further data.) s
-5 206 M
-(6.1 Algorithm Negotiation) s
-5 184 M
-( Key exchange begins by each side sending the following packet:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_KEXINIT) s
-5 679 M
-( byte[16] cookie \(random bytes\)) s
-5 668 M
-( string kex_algorithms) s
-5 657 M
-( string server_host_key_algorithms) s
-5 646 M
-( string encryption_algorithms_client_to_server) s
-5 635 M
-( string encryption_algorithms_server_to_client) s
-5 624 M
-( string mac_algorithms_client_to_server) s
-5 613 M
-( string mac_algorithms_server_to_client) s
-5 602 M
-( string compression_algorithms_client_to_server) s
-5 591 M
-( string compression_algorithms_server_to_client) s
-5 580 M
-( string languages_client_to_server) s
-5 569 M
-( string languages_server_to_client) s
-5 558 M
-( boolean first_kex_packet_follows) s
-5 547 M
-( uint32 0 \(reserved for future extension\)) s
-5 525 M
-( Each of the algorithm strings MUST be a comma-separated list of) s
-5 514 M
-( algorithm names \(see ''Algorithm Naming'' in [SSH-ARCH]\). Each) s
-5 503 M
-( supported \(allowed\) algorithm MUST be listed in order of preference.) s
-5 481 M
-( The first algorithm in each list MUST be the preferred \(guessed\)) s
-5 470 M
-( algorithm. Each string MUST contain at least one algorithm name.) s
-5 437 M
-( cookie) s
-5 426 M
-( The cookie MUST be a random value generated by the sender. Its) s
-5 415 M
-( purpose is to make it impossible for either side to fully) s
-5 404 M
-( determine the keys and the session identifier.) s
-5 382 M
-( kex_algorithms) s
-5 371 M
-( Key exchange algorithms were defined above. The first) s
-5 360 M
-( algorithm MUST be the preferred \(and guessed\) algorithm. If) s
-5 349 M
-( both sides make the same guess, that algorithm MUST be used.) s
-5 338 M
-( Otherwise, the following algorithm MUST be used to choose a key) s
-5 327 M
-( exchange method: iterate over client's kex algorithms, one at a) s
-5 316 M
-( time. Choose the first algorithm that satisfies the following) s
-5 305 M
-( conditions:) s
-5 294 M
-( + the server also supports the algorithm,) s
-5 283 M
-( + if the algorithm requires an encryption-capable host key,) s
-5 272 M
-( there is an encryption-capable algorithm on the server's) s
-5 261 M
-( server_host_key_algorithms that is also supported by the) s
-5 250 M
-( client, and) s
-5 239 M
-( + if the algorithm requires a signature-capable host key,) s
-5 228 M
-( there is a signature-capable algorithm on the server's) s
-5 217 M
-( server_host_key_algorithms that is also supported by the) s
-5 206 M
-( client.) s
-5 195 M
-( + If no algorithm satisfying all these conditions can be) s
-5 184 M
-( found, the connection fails, and both sides MUST disconnect.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( server_host_key_algorithms) s
-5 679 M
-( List of the algorithms supported for the server host key. The) s
-5 668 M
-( server lists the algorithms for which it has host keys; the) s
-5 657 M
-( client lists the algorithms that it is willing to accept.) s
-5 646 M
-( \(There MAY be multiple host keys for a host, possibly with) s
-5 635 M
-( different algorithms.\)) s
-5 613 M
-( Some host keys may not support both signatures and encryption) s
-5 602 M
-( \(this can be determined from the algorithm\), and thus not all) s
-5 591 M
-( host keys are valid for all key exchange methods.) s
-5 569 M
-( Algorithm selection depends on whether the chosen key exchange) s
-5 558 M
-( algorithm requires a signature or encryption capable host key.) s
-5 547 M
-( It MUST be possible to determine this from the public key) s
-5 536 M
-( algorithm name. The first algorithm on the client's list that) s
-5 525 M
-( satisfies the requirements and is also supported by the server) s
-5 514 M
-( MUST be chosen. If there is no such algorithm, both sides MUST) s
-5 503 M
-( disconnect.) s
-5 481 M
-( encryption_algorithms) s
-5 470 M
-( Lists the acceptable symmetric encryption algorithms in order) s
-5 459 M
-( of preference. The chosen encryption algorithm to each) s
-5 448 M
-( direction MUST be the first algorithm on the client's list) s
-5 437 M
-( that is also on the server's list. If there is no such) s
-5 426 M
-( algorithm, both sides MUST disconnect.) s
-5 404 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 393 M
-( acceptable. The defined algorithm names are listed in Section) s
-5 382 M
-( Section 5.3.) s
-5 360 M
-( mac_algorithms) s
-5 349 M
-( Lists the acceptable MAC algorithms in order of preference.) s
-5 338 M
-( The chosen MAC algorithm MUST be the first algorithm on the) s
-5 327 M
-( client's list that is also on the server's list. If there is) s
-5 316 M
-( no such algorithm, both sides MUST disconnect.) s
-5 294 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 283 M
-( acceptable. The MAC algorithm names are listed in Section) s
-5 272 M
-( Figure 1.) s
-5 250 M
-( compression_algorithms) s
-5 239 M
-( Lists the acceptable compression algorithms in order of) s
-5 228 M
-( preference. The chosen compression algorithm MUST be the first) s
-5 217 M
-( algorithm on the client's list that is also on the server's) s
-5 206 M
-( list. If there is no such algorithm, both sides MUST) s
-5 195 M
-( disconnect.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 679 M
-( acceptable. The compression algorithm names are listed in) s
-5 668 M
-( Section Section 5.2.) s
-5 646 M
-( languages) s
-5 635 M
-( This is a comma-separated list of language tags in order of) s
-5 624 M
-( preference [RFC3066]. Both parties MAY ignore this list. If) s
-5 613 M
-( there are no language preferences, this list SHOULD be empty.) s
-5 602 M
-( Language tags SHOULD NOT be present unless they are known to be) s
-5 591 M
-( needed by the sending party.) s
-5 569 M
-( first_kex_packet_follows) s
-5 558 M
-( Indicates whether a guessed key exchange packet follows. If a) s
-5 547 M
-( guessed packet will be sent, this MUST be TRUE. If no guessed) s
-5 536 M
-( packet will be sent, this MUST be FALSE.) s
-5 514 M
-( After receiving the SSH_MSG_KEXINIT packet from the other side,) s
-5 503 M
-( each party will know whether their guess was right. If the) s
-5 492 M
-( other party's guess was wrong, and this field was TRUE, the) s
-5 481 M
-( next packet MUST be silently ignored, and both sides MUST then) s
-5 470 M
-( act as determined by the negotiated key exchange method. If) s
-5 459 M
-( the guess was right, key exchange MUST continue using the) s
-5 448 M
-( guessed packet.) s
-5 426 M
-( After the KEXINIT packet exchange, the key exchange algorithm is run.) s
-5 415 M
-( It may involve several packet exchanges, as specified by the key) s
-5 404 M
-( exchange method.) s
-5 382 M
-(6.2 Output from Key Exchange) s
-5 360 M
-( The key exchange produces two values: a shared secret K, and an) s
-5 349 M
-( exchange hash H. Encryption and authentication keys are derived from) s
-5 338 M
-( these. The exchange hash H from the first key exchange is) s
-5 327 M
-( additionally used as the session identifier, which is a unique) s
-5 316 M
-( identifier for this connection. It is used by authentication methods) s
-5 305 M
-( as a part of the data that is signed as a proof of possession of a) s
-5 294 M
-( private key. Once computed, the session identifier is not changed,) s
-5 283 M
-( even if keys are later re-exchanged.) s
-5 250 M
-( Each key exchange method specifies a hash function that is used in) s
-5 239 M
-( the key exchange. The same hash algorithm MUST be used in key) s
-5 228 M
-( derivation. Here, we'll call it HASH.) s
-5 195 M
-( Encryption keys MUST be computed as HASH of a known value and K as) s
-5 184 M
-( follows:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( o Initial IV client to server: HASH\(K || H || "A" || session_id\)) s
-5 679 M
-( \(Here K is encoded as mpint and "A" as byte and session_id as raw) s
-5 668 M
-( data."A" means the single character A, ASCII 65\).) s
-5 657 M
-( o Initial IV server to client: HASH\(K || H || "B" || session_id\)) s
-5 646 M
-( o Encryption key client to server: HASH\(K || H || "C" || session_id\)) s
-5 635 M
-( o Encryption key server to client: HASH\(K || H || "D" || session_id\)) s
-5 624 M
-( o Integrity key client to server: HASH\(K || H || "E" || session_id\)) s
-5 613 M
-( o Integrity key server to client: HASH\(K || H || "F" || session_id\)) s
-5 591 M
-( Key data MUST be taken from the beginning of the hash output. 128) s
-5 580 M
-( bits \(16 bytes\) MUST be used for algorithms with variable-length) s
-5 569 M
-( keys. The only variable key length algorithm defined in this document) s
-5 558 M
-( is arcfour\). For other algorithms, as many bytes as are needed are) s
-5 547 M
-( taken from the beginning of the hash value. If the key length needed) s
-5 536 M
-( is longer than the output of the HASH, the key is extended by) s
-5 525 M
-( computing HASH of the concatenation of K and H and the entire key so) s
-5 514 M
-( far, and appending the resulting bytes \(as many as HASH generates\) to) s
-5 503 M
-( the key. This process is repeated until enough key material is) s
-5 492 M
-( available; the key is taken from the beginning of this value. In) s
-5 481 M
-( other words:) s
-5 459 M
-( K1 = HASH\(K || H || X || session_id\) \(X is e.g. "A"\)) s
-5 448 M
-( K2 = HASH\(K || H || K1\)) s
-5 437 M
-( K3 = HASH\(K || H || K1 || K2\)) s
-5 426 M
-( ...) s
-5 415 M
-( key = K1 || K2 || K3 || ...) s
-5 393 M
-( This process will lose entropy if the amount of entropy in K is) s
-5 382 M
-( larger than the internal state size of HASH.) s
-5 360 M
-(6.3 Taking Keys Into Use) s
-5 338 M
-( Key exchange ends by each side sending an SSH_MSG_NEWKEYS message.) s
-5 327 M
-( This message is sent with the old keys and algorithms. All messages) s
-5 316 M
-( sent after this message MUST use the new keys and algorithms.) s
-5 283 M
-( When this message is received, the new keys and algorithms MUST be) s
-5 272 M
-( taken into use for receiving.) s
-5 239 M
-( This message is the only valid message after key exchange, in) s
-5 228 M
-( addition to SSH_MSG_DEBUG, SSH_MSG_DISCONNECT and SSH_MSG_IGNORE) s
-5 217 M
-( messages. The purpose of this message is to ensure that a party is) s
-5 206 M
-( able to respond with a disconnect message that the other party can) s
-5 195 M
-( understand if something goes wrong with the key exchange.) s
-5 184 M
-( Implementations MUST NOT accept any other messages after key exchange) s
-5 173 M
-( before receiving SSH_MSG_NEWKEYS.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_NEWKEYS) s
-5 657 M
-(7. Diffie-Hellman Key Exchange) s
-5 635 M
-( The Diffie-Hellman key exchange provides a shared secret that can not) s
-5 624 M
-( be determined by either party alone. The key exchange is combined) s
-5 613 M
-( with a signature with the host key to provide host authentication.) s
-5 580 M
-( In the following description \(C is the client, S is the server; p is) s
-5 569 M
-( a large safe prime, g is a generator for a subgroup of GF\(p\), and q) s
-5 558 M
-( is the order of the subgroup; V_S is S's version string; V_C is C's) s
-5 547 M
-( version string; K_S is S's public host key; I_C is C's KEXINIT) s
-5 536 M
-( message and I_S S's KEXINIT message which have been exchanged before) s
-5 525 M
-( this part begins\):) s
-5 492 M
-( 1. C generates a random number x \(1 < x < q\) and computes e = g^x) s
-5 481 M
-( mod p. C sends "e" to S.) s
-5 459 M
-( 2. S generates a random number y \(0 < y < q\) and computes f = g^y) s
-5 448 M
-( mod p. S receives "e". It computes K = e^y mod p, H = hash\(V_C) s
-5 437 M
-( || V_S || I_C || I_S || K_S || e || f || K\) \(these elements are) s
-5 426 M
-( encoded according to their types; see below\), and signature s on) s
-5 415 M
-( H with its private host key. S sends "K_S || f || s" to C. The) s
-5 404 M
-( signing operation may involve a second hashing operation.) s
-5 382 M
-( 3. C verifies that K_S really is the host key for S \(e.g. using) s
-5 371 M
-( certificates or a local database\). C is also allowed to accept) s
-5 360 M
-( the key without verification; however, doing so will render the) s
-5 349 M
-( protocol insecure against active attacks \(but may be desirable) s
-5 338 M
-( for practical reasons in the short term in many environments\). C) s
-5 327 M
-( then computes K = f^x mod p, H = hash\(V_C || V_S || I_C || I_S ||) s
-5 316 M
-( K_S || e || f || K\), and verifies the signature s on H.) s
-5 294 M
-( Either side MUST NOT send or accept e or f values that are not in the) s
-5 283 M
-( range [1, p-1]. If this condition is violated, the key exchange) s
-5 272 M
-( fails.) s
-5 239 M
-( This is implemented with the following messages. The hash algorithm) s
-5 228 M
-( for computing the exchange hash is defined by the method name, and is) s
-5 217 M
-( called HASH. The public key algorithm for signing is negotiated with) s
-5 206 M
-( the KEXINIT messages.) s
-5 184 M
-( First, the client sends the following:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_KEXDH_INIT) s
-5 679 M
-( mpint e) s
-5 646 M
-( The server responds with the following:) s
-5 624 M
-( byte SSH_MSG_KEXDH_REPLY) s
-5 613 M
-( string server public host key and certificates \(K_S\)) s
-5 602 M
-( mpint f) s
-5 591 M
-( string signature of H) s
-5 569 M
-( The hash H is computed as the HASH hash of the concatenation of the) s
-5 558 M
-( following:) s
-5 536 M
-( string V_C, the client's version string \(CR and NL excluded\)) s
-5 525 M
-( string V_S, the server's version string \(CR and NL excluded\)) s
-5 514 M
-( string I_C, the payload of the client's SSH_MSG_KEXINIT) s
-5 503 M
-( string I_S, the payload of the server's SSH_MSG_KEXINIT) s
-5 492 M
-( string K_S, the host key) s
-5 481 M
-( mpint e, exchange value sent by the client) s
-5 470 M
-( mpint f, exchange value sent by the server) s
-5 459 M
-( mpint K, the shared secret) s
-5 437 M
-( This value is called the exchange hash, and it is used to) s
-5 426 M
-( authenticate the key exchange. The exchange hash SHOULD be kept) s
-5 415 M
-( secret.) s
-5 382 M
-( The signature algorithm MUST be applied over H, not the original) s
-5 371 M
-( data. Most signature algorithms include hashing and additional) s
-5 360 M
-( padding. For example, "ssh-dss" specifies SHA-1 hashing; in that) s
-5 349 M
-( case, the data is first hashed with HASH to compute H, and H is then) s
-5 338 M
-( hashed with SHA-1 as part of the signing operation.) s
-5 316 M
-(7.1 diffie-hellman-group1-sha1) s
-5 294 M
-( The "diffie-hellman-group1-sha1" method specifies Diffie-Hellman key) s
-5 283 M
-( exchange with SHA-1 as HASH, and Oakley group 14 [RFC3526] \(2048-bit) s
-5 272 M
-( MODP Group\). It is included below in hexadecimal and decimal.) s
-5 250 M
-( The prime p is equal to 2^1024 - 2^960 - 1 + 2^64 * floor\( 2^894 Pi +) s
-5 239 M
-( 129093 \). Its hexadecimal value is:) s
-5 217 M
-( FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1) s
-5 206 M
-( 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD) s
-5 195 M
-( EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245) s
-5 184 M
-( E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED) s
-5 173 M
-( EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( FFFFFFFF FFFFFFFF.) s
-5 668 M
-( In decimal, this value is:) s
-5 646 M
-( 179769313486231590770839156793787453197860296048756011706444) s
-5 635 M
-( 423684197180216158519368947833795864925541502180565485980503) s
-5 624 M
-( 646440548199239100050792877003355816639229553136239076508735) s
-5 613 M
-( 759914822574862575007425302077447712589550957937778424442426) s
-5 602 M
-( 617334727629299387668709205606050270810842907692932019128194) s
-5 591 M
-( 467627007.) s
-5 569 M
-( The generator used with this prime is g = 2. The group order q is \(p) s
-5 558 M
-( - 1\) / 2.) s
-5 536 M
-(8. Key Re-Exchange) s
-5 514 M
-( Key re-exchange is started by sending an SSH_MSG_KEXINIT packet when) s
-5 503 M
-( not already doing a key exchange \(as described in Section Section) s
-5 492 M
-( 6.1\). When this message is received, a party MUST respond with its) s
-5 481 M
-( own SSH_MSG_KEXINIT message except when the received SSH_MSG_KEXINIT) s
-5 470 M
-( already was a reply. Either party MAY initiate the re-exchange, but) s
-5 459 M
-( roles MUST NOT be changed \(i.e., the server remains the server, and) s
-5 448 M
-( the client remains the client\).) s
-5 415 M
-( Key re-exchange is performed using whatever encryption was in effect) s
-5 404 M
-( when the exchange was started. Encryption, compression, and MAC) s
-5 393 M
-( methods are not changed before a new SSH_MSG_NEWKEYS is sent after) s
-5 382 M
-( the key exchange \(as in the initial key exchange\). Re-exchange is) s
-5 371 M
-( processed identically to the initial key exchange, except for the) s
-5 360 M
-( session identifier that will remain unchanged. It is permissible to) s
-5 349 M
-( change some or all of the algorithms during the re-exchange. Host) s
-5 338 M
-( keys can also change. All keys and initialization vectors are) s
-5 327 M
-( recomputed after the exchange. Compression and encryption contexts) s
-5 316 M
-( are reset.) s
-5 283 M
-( It is recommended that the keys are changed after each gigabyte of) s
-5 272 M
-( transmitted data or after each hour of connection time, whichever) s
-5 261 M
-( comes sooner. However, since the re-exchange is a public key) s
-5 250 M
-( operation, it requires a fair amount of processing power and should) s
-5 239 M
-( not be performed too often.) s
-5 206 M
-( More application data may be sent after the SSH_MSG_NEWKEYS packet) s
-5 195 M
-( has been sent; key exchange does not affect the protocols that lie) s
-5 184 M
-( above the SSH transport layer.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(9. Service Request) s
-5 668 M
-( After the key exchange, the client requests a service. The service is) s
-5 657 M
-( identified by a name. The format of names and procedures for defining) s
-5 646 M
-( new names are defined in [SSH-ARCH].) s
-5 613 M
-( Currently, the following names have been reserved:) s
-5 591 M
-( ssh-userauth) s
-5 580 M
-( ssh-connection) s
-5 558 M
-( Similar local naming policy is applied to the service names, as is) s
-5 547 M
-( applied to the algorithm names; a local service should use the) s
-5 536 M
-( "servicename@domain" syntax.) s
-5 514 M
-( byte SSH_MSG_SERVICE_REQUEST) s
-5 503 M
-( string service name) s
-5 481 M
-( If the server rejects the service request, it SHOULD send an) s
-5 470 M
-( appropriate SSH_MSG_DISCONNECT message and MUST disconnect.) s
-5 437 M
-( When the service starts, it may have access to the session identifier) s
-5 426 M
-( generated during the key exchange.) s
-5 393 M
-( If the server supports the service \(and permits the client to use) s
-5 382 M
-( it\), it MUST respond with the following:) s
-5 360 M
-( byte SSH_MSG_SERVICE_ACCEPT) s
-5 349 M
-( string service name) s
-5 327 M
-( Message numbers used by services should be in the area reserved for) s
-5 316 M
-( them \(see Section 6 in [SSH-ARCH]\). The transport level will) s
-5 305 M
-( continue to process its own messages.) s
-5 272 M
-( Note that after a key exchange with implicit server authentication,) s
-5 261 M
-( the client MUST wait for response to its service request message) s
-5 250 M
-( before sending any further data.) s
-5 228 M
-(10. Additional Messages) s
-5 206 M
-( Either party may send any of the following messages at any time.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(10.1 Disconnection Message) s
-5 668 M
-( byte SSH_MSG_DISCONNECT) s
-5 657 M
-( uint32 reason code) s
-5 646 M
-( string description [RFC2279]) s
-5 635 M
-( string language tag [RFC3066]) s
-5 613 M
-( This message causes immediate termination of the connection. All) s
-5 602 M
-( implementations MUST be able to process this message; they SHOULD be) s
-5 591 M
-( able to send this message.) s
-5 569 M
-( The sender MUST NOT send or receive any data after this message, and) s
-5 558 M
-( the recipient MUST NOT accept any data after receiving this message.) s
-5 547 M
-( The description field gives a more specific explanation in a) s
-5 536 M
-( human-readable form. The error code gives the reason in a more) s
-5 525 M
-( machine-readable format \(suitable for localization\), and can have the) s
-5 514 M
-( following values:) s
-5 492 M
-( #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1) s
-5 481 M
-( #define SSH_DISCONNECT_PROTOCOL_ERROR 2) s
-5 470 M
-( #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3) s
-5 459 M
-( #define SSH_DISCONNECT_RESERVED 4) s
-5 448 M
-( #define SSH_DISCONNECT_MAC_ERROR 5) s
-5 437 M
-( #define SSH_DISCONNECT_COMPRESSION_ERROR 6) s
-5 426 M
-( #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7) s
-5 415 M
-( #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8) s
-5 404 M
-( #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9) s
-5 393 M
-( #define SSH_DISCONNECT_CONNECTION_LOST 10) s
-5 382 M
-( #define SSH_DISCONNECT_BY_APPLICATION 11) s
-5 371 M
-( #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12) s
-5 360 M
-( #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13) s
-5 349 M
-( #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14) s
-5 338 M
-( #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15) s
-5 316 M
-( If the description string is displayed, control character filtering) s
-5 305 M
-( discussed in [SSH-ARCH] should be used to avoid attacks by sending) s
-5 294 M
-( terminal control characters.) s
-5 272 M
-(10.2 Ignored Data Message) s
-5 250 M
-( byte SSH_MSG_IGNORE) s
-5 239 M
-( string data) s
-5 217 M
-( All implementations MUST understand \(and ignore\) this message at any) s
-5 206 M
-( time \(after receiving the protocol version\). No implementation is) s
-5 195 M
-( required to send them. This message can be used as an additional) s
-5 184 M
-( protection measure against advanced traffic analysis techniques.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(10.3 Debug Message) s
-5 668 M
-( byte SSH_MSG_DEBUG) s
-5 657 M
-( boolean always_display) s
-5 646 M
-( string message [RFC2279]) s
-5 635 M
-( string language tag [RFC3066]) s
-5 613 M
-( All implementations MUST understand this message, but they are) s
-5 602 M
-( allowed to ignore it. This message is used to pass the other side) s
-5 591 M
-( information that may help debugging. If always_display is TRUE, the) s
-5 580 M
-( message SHOULD be displayed. Otherwise, it SHOULD NOT be displayed) s
-5 569 M
-( unless debugging information has been explicitly requested by the) s
-5 558 M
-( user.) s
-5 525 M
-( The message doesn't need to contain a newline. It is, however,) s
-5 514 M
-( allowed to consist of multiple lines separated by CRLF \(Carriage) s
-5 503 M
-( Return - Line Feed\) pairs.) s
-5 470 M
-( If the message string is displayed, terminal control character) s
-5 459 M
-( filtering discussed in [SSH-ARCH] should be used to avoid attacks by) s
-5 448 M
-( sending terminal control characters.) s
-5 426 M
-(10.4 Reserved Messages) s
-5 404 M
-( An implementation MUST respond to all unrecognized messages with an) s
-5 393 M
-( SSH_MSG_UNIMPLEMENTED message in the order in which the messages were) s
-5 382 M
-( received. Such messages MUST be otherwise ignored. Later protocol) s
-5 371 M
-( versions may define other meanings for these message types.) s
-5 349 M
-( byte SSH_MSG_UNIMPLEMENTED) s
-5 338 M
-( uint32 packet sequence number of rejected message) s
-5 305 M
-(11. Summary of Message Numbers) s
-5 283 M
-( The following message numbers have been defined in this protocol:) s
-5 261 M
-( #define SSH_MSG_DISCONNECT 1) s
-5 250 M
-( #define SSH_MSG_IGNORE 2) s
-5 239 M
-( #define SSH_MSG_UNIMPLEMENTED 3) s
-5 228 M
-( #define SSH_MSG_DEBUG 4) s
-5 217 M
-( #define SSH_MSG_SERVICE_REQUEST 5) s
-5 206 M
-( #define SSH_MSG_SERVICE_ACCEPT 6) s
-5 184 M
-( #define SSH_MSG_KEXINIT 20) s
-5 173 M
-( #define SSH_MSG_NEWKEYS 21) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( /* Numbers 30-49 used for kex packets.) s
-5 679 M
-( Different kex methods may reuse message numbers in) s
-5 668 M
-( this range. */) s
-5 646 M
-( #define SSH_MSG_KEXDH_INIT 30) s
-5 635 M
-( #define SSH_MSG_KEXDH_REPLY 31) s
-5 602 M
-(12. IANA Considerations) s
-5 580 M
-( This document is part of a set, the IANA considerations for the SSH) s
-5 569 M
-( protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],) s
-5 558 M
-( [SSH-CONNECT] are detailed in [SSH-NUMBERS].) s
-5 536 M
-(13. Security Considerations) s
-5 514 M
-( This protocol provides a secure encrypted channel over an insecure) s
-5 503 M
-( network. It performs server host authentication, key exchange,) s
-5 492 M
-( encryption, and integrity protection. It also derives a unique) s
-5 481 M
-( session id that may be used by higher-level protocols.) s
-5 459 M
-( Full security considerations for this protocol are provided in) s
-5 448 M
-( Section 8 of [SSH-ARCH]) s
-5 426 M
-(14. Intellectual Property) s
-5 404 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 393 M
-( intellectual property or other rights that might be claimed to) s
-5 382 M
-( pertain to the implementation or use of the technology described in) s
-5 371 M
-( this document or the extent to which any license under such rights) s
-5 360 M
-( might or might not be available; neither does it represent that it) s
-5 349 M
-( has made any effort to identify any such rights. Information on the) s
-5 338 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 327 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 316 M
-( claims of rights made available for publication and any assurances of) s
-5 305 M
-( licenses to be made available, or the result of an attempt made to) s
-5 294 M
-( obtain a general license or permission for the use of such) s
-5 283 M
-( proprietary rights by implementers or users of this specification can) s
-5 272 M
-( be obtained from the IETF Secretariat.) s
-5 250 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 239 M
-( regard to some or all of the specification contained in this) s
-5 228 M
-( document. For more information consult the online list of claimed) s
-5 217 M
-( rights.) s
-5 195 M
-(15. Additional Information) s
-5 173 M
-( The current document editor is: [email protected]. Comments on) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( this internet draft should be sent to the IETF SECSH working group,) s
-5 679 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 657 M
-(Normative) s
-5 635 M
-( [SSH-ARCH]) s
-5 624 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 613 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 591 M
-( [SSH-TRANS]) s
-5 580 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 569 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 547 M
-( [SSH-USERAUTH]) s
-5 536 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 525 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 503 M
-( [SSH-CONNECT]) s
-5 492 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 481 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 459 M
-( [SSH-NUMBERS]) s
-5 448 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 437 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 426 M
-( 2003.) s
-5 404 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 393 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 371 M
-(Informative) s
-5 349 M
-( [FIPS-186]) s
-5 338 M
-( Federal Information Processing Standards Publication,) s
-5 327 M
-( "FIPS PUB 186, Digital Signature Standard", May 1994.) s
-5 305 M
-( [FIPS-197]) s
-5 294 M
-( NIST, "FIPS PUB 197 Advanced Encryption Standard \(AES\)",) s
-5 283 M
-( November 2001.) s
-5 261 M
-( [FIPS-46-3]) s
-5 250 M
-( U.S. Dept. of Commerce, "FIPS PUB 46-3, Data Encryption) s
-5 239 M
-( Standard \(DES\)", October 1999.) s
-5 217 M
-( [RFC2459] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet) s
-5 206 M
-( X.509 Public Key Infrastructure Certificate and CRL) s
-5 195 M
-( Profile", RFC 2459, January 1999.) s
-5 173 M
-( [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( STD 13, RFC 1034, November 1987.) s
-5 668 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 657 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 635 M
-( [RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format) s
-5 624 M
-( Specification version 3.3", RFC 1950, May 1996.) s
-5 602 M
-( [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification) s
-5 591 M
-( version 1.3", RFC 1951, May 1996.) s
-5 569 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 558 M
-( 10646", RFC 2279, January 1998.) s
-5 536 M
-( [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:) s
-5 525 M
-( Keyed-Hashing for Message Authentication", RFC 2104,) s
-5 514 M
-( February 1997.) s
-5 492 M
-( [RFC2144] Adams, C., "The CAST-128 Encryption Algorithm", RFC 2144,) s
-5 481 M
-( May 1997.) s
-5 459 M
-( [RFC2440] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,) s
-5 448 M
-( "OpenPGP Message Format", RFC 2440, November 1998.) s
-5 426 M
-( [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas,) s
-5 415 M
-( B. and T. Ylonen, "SPKI Certificate Theory", RFC 2693,) s
-5 404 M
-( September 1999.) s
-5 382 M
-( [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential \(MODP\)) s
-5 371 M
-( Diffie-Hellman groups for Internet Key Exchange \(IKE\)",) s
-5 360 M
-( RFC 3526, May 2003.) s
-5 338 M
-( [SCHNEIER]) s
-5 327 M
-( Schneier, B., "Applied Cryptography Second Edition:) s
-5 316 M
-( protocols algorithms and source in code in C", 1996.) s
-5 294 M
-( [TWOFISH] Schneier, B., "The Twofish Encryptions Algorithm: A) s
-5 283 M
-( 128-Bit Block Cipher, 1st Edition", March 1999.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(Authors' Addresses) s
-5 668 M
-( Tatu Ylonen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( Fredrikinkatu 42) s
-5 635 M
-( HELSINKI FIN-00100) s
-5 624 M
-( Finland) s
-5 602 M
-( EMail: [email protected]) s
-5 569 M
-( Darren J. Moffat \(editor\)) s
-5 558 M
-( Sun Microsystems, Inc) s
-5 547 M
-( 17 Network Circle) s
-5 536 M
-( Menlo Park 95025) s
-5 525 M
-( USA) s
-5 503 M
-( EMail: [email protected]) s
-5 481 M
-(Appendix A. Contibutors) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-showpage
-PStoPSsaved restore
-%%Trailer
-%%Pages: 29
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt b/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt
deleted file mode 100644
index 9073ea52b2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt
+++ /dev/null
@@ -1,1624 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Editor, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Transport Layer Protocol
- draft-ietf-secsh-transport-17.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network.
-
- This document describes the SSH transport layer protocol which
- typically runs on top of TCP/IP. The protocol can be used as a basis
- for a number of secure network services. It provides strong
- encryption, server authentication, and integrity protection. It may
- also provide compression.
-
- Key exchange method, public key algorithm, symmetric encryption
- algorithm, message authentication algorithm, and hash algorithm are
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- all negotiated.
-
- This document also describes the Diffie-Hellman key exchange method
- and the minimal set of algorithms that are needed to implement the
- SSH transport layer protocol.
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 4. Connection Setup . . . . . . . . . . . . . . . . . . . . . . 3
- 4.1 Use over TCP/IP . . . . . . . . . . . . . . . . . . . . . . 4
- 4.2 Protocol Version Exchange . . . . . . . . . . . . . . . . . 4
- 4.3 Compatibility With Old SSH Versions . . . . . . . . . . . . 4
- 4.3.1 Old Client, New Server . . . . . . . . . . . . . . . . . . . 5
- 4.3.2 New Client, Old Server . . . . . . . . . . . . . . . . . . . 5
- 5. Binary Packet Protocol . . . . . . . . . . . . . . . . . . . 5
- 5.1 Maximum Packet Length . . . . . . . . . . . . . . . . . . . 6
- 5.2 Compression . . . . . . . . . . . . . . . . . . . . . . . . 7
- 5.3 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 7
- 5.4 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 9
- 5.5 Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 10
- 5.6 Public Key Algorithms . . . . . . . . . . . . . . . . . . . 11
- 6. Key Exchange . . . . . . . . . . . . . . . . . . . . . . . . 13
- 6.1 Algorithm Negotiation . . . . . . . . . . . . . . . . . . . 13
- 6.2 Output from Key Exchange . . . . . . . . . . . . . . . . . . 16
- 6.3 Taking Keys Into Use . . . . . . . . . . . . . . . . . . . . 17
- 7. Diffie-Hellman Key Exchange . . . . . . . . . . . . . . . . 18
- 7.1 diffie-hellman-group1-sha1 . . . . . . . . . . . . . . . . . 19
- 8. Key Re-Exchange . . . . . . . . . . . . . . . . . . . . . . 20
- 9. Service Request . . . . . . . . . . . . . . . . . . . . . . 21
- 10. Additional Messages . . . . . . . . . . . . . . . . . . . . 21
- 10.1 Disconnection Message . . . . . . . . . . . . . . . . . . . 22
- 10.2 Ignored Data Message . . . . . . . . . . . . . . . . . . . . 22
- 10.3 Debug Message . . . . . . . . . . . . . . . . . . . . . . . 23
- 10.4 Reserved Messages . . . . . . . . . . . . . . . . . . . . . 23
- 11. Summary of Message Numbers . . . . . . . . . . . . . . . . . 23
- 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 24
- 13. Security Considerations . . . . . . . . . . . . . . . . . . 24
- 14. Intellectual Property . . . . . . . . . . . . . . . . . . . 24
- 15. Additional Information . . . . . . . . . . . . . . . . . . . 24
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 26
- Normative . . . . . . . . . . . . . . . . . . . . . . . . . 25
- Informative . . . . . . . . . . . . . . . . . . . . . . . . 25
- A. Contibutors . . . . . . . . . . . . . . . . . . . . . . . . 27
- Intellectual Property and Copyright Statements . . . . . . . 28
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH transport layer is a secure low level transport protocol. It
- provides strong encryption, cryptographic host authentication, and
- integrity protection.
-
- Authentication in this protocol level is host-based; this protocol
- does not perform user authentication. A higher level protocol for
- user authentication can be designed on top of this protocol.
-
- The protocol has been designed to be simple, flexible, to allow
- parameter negotiation, and to minimize the number of round-trips.
- Key exchange method, public key algorithm, symmetric encryption
- algorithm, message authentication algorithm, and hash algorithm are
- all negotiated. It is expected that in most environments, only 2
- round-trips will be needed for full key exchange, server
- authentication, service request, and acceptance notification of
- service request. The worst case is 3 round-trips.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119].
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH].
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-4. Connection Setup
-
- SSH works over any 8-bit clean, binary-transparent transport. The
- underlying transport SHOULD protect against transmission errors as
- such errors cause the SSH connection to terminate.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The client initiates the connection.
-
-4.1 Use over TCP/IP
-
- When used over TCP/IP, the server normally listens for connections on
- port 22. This port number has been registered with the IANA, and has
- been officially assigned for SSH.
-
-4.2 Protocol Version Exchange
-
- When the connection has been established, both sides MUST send an
- identification string of the form "SSH-protoversion-softwareversion
- comments", followed by carriage return and newline characters (ASCII
- 13 and 10, respectively). Both sides MUST be able to process
- identification strings without carriage return character. No null
- character is sent. The maximum length of the string is 255
- characters, including the carriage return and newline.
-
- The part of the identification string preceding carriage return and
- newline is used in the Diffie-Hellman key exchange (see Section
- Section 7).
-
- The server MAY send other lines of data before sending the version
- string. Each line SHOULD be terminated by a carriage return and
- newline. Such lines MUST NOT begin with "SSH-", and SHOULD be
- encoded in ISO-10646 UTF-8 [RFC2279] (language is not specified).
- Clients MUST be able to process such lines; they MAY be silently
- ignored, or MAY be displayed to the client user; if they are
- displayed, control character filtering discussed in [SSH-ARCH] SHOULD
- be used. The primary use of this feature is to allow TCP-wrappers to
- display an error message before disconnecting.
-
- Version strings MUST consist of printable US-ASCII characters, not
- including whitespaces or a minus sign (-). The version string is
- primarily used to trigger compatibility extensions and to indicate
- the capabilities of an implementation. The comment string should
- contain additional information that might be useful in solving user
- problems.
-
- The protocol version described in this document is 2.0.
-
- Key exchange will begin immediately after sending this identifier.
- All packets following the identification string SHALL use the binary
- packet protocol, to be described below.
-
-4.3 Compatibility With Old SSH Versions
-
- During the transition period, it is important to be able to work in a
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- way that is compatible with the installed SSH clients and servers
- that use an older version of the protocol. Information in this
- section is only relevant for implementations supporting compatibility
- with SSH versions 1.x. There is no standards track or informational
- draft available that defines the SSH 1.x protocol. The only known
- documentation of the 1.x protocol is contained in README files that
- are shipped along with the source code.
-
-4.3.1 Old Client, New Server
-
- Server implementations MAY support a configurable "compatibility"
- flag that enables compatibility with old versions. When this flag is
- on, the server SHOULD identify its protocol version as "1.99".
- Clients using protocol 2.0 MUST be able to identify this as identical
- to "2.0". In this mode the server SHOULD NOT send the carriage
- return character (ASCII 13) after the version identification string.
-
- In the compatibility mode the server SHOULD NOT send any further data
- after its initialization string until it has received an
- identification string from the client. The server can then determine
- whether the client is using an old protocol, and can revert to the
- old protocol if required. In the compatibility mode, the server MUST
- NOT send additional data before the version string.
-
- When compatibility with old clients is not needed, the server MAY
- send its initial key exchange data immediately after the
- identification string.
-
-4.3.2 New Client, Old Server
-
- Since the new client MAY immediately send additional data after its
- identification string (before receiving server's identification), the
- old protocol may already have been corrupted when the client learns
- that the server is old. When this happens, the client SHOULD close
- the connection to the server, and reconnect using the old protocol.
-
-5. Binary Packet Protocol
-
- Each packet is in the following format:
-
- uint32 packet_length
- byte padding_length
- byte[n1] payload; n1 = packet_length - padding_length - 1
- byte[n2] random padding; n2 = padding_length
- byte[m] mac (message authentication code); m = mac_length
-
- packet_length
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The length of the packet (bytes), not including MAC or the
- packet_length field itself.
-
- padding_length
- Length of padding (bytes).
-
- payload
- The useful contents of the packet. If compression has been
- negotiated, this field is compressed. Initially, compression
- MUST be "none".
-
- random padding
- Arbitrary-length padding, such that the total length of
- (packet_length || padding_length || payload || padding) is a
- multiple of the cipher block size or 8, whichever is larger.
- There MUST be at least four bytes of padding. The padding
- SHOULD consist of random bytes. The maximum amount of padding
- is 255 bytes.
-
- mac
- Message authentication code. If message authentication has
- been negotiated, this field contains the MAC bytes. Initially,
- the MAC algorithm MUST be "none".
-
-
- Note that length of the concatenation of packet length, padding
- length, payload, and padding MUST be a multiple of the cipher block
- size or 8, whichever is larger. This constraint MUST be enforced
- even when using stream ciphers. Note that the packet length field is
- also encrypted, and processing it requires special care when sending
- or receiving packets.
-
- The minimum size of a packet is 16 (or the cipher block size,
- whichever is larger) bytes (plus MAC); implementations SHOULD decrypt
- the length after receiving the first 8 (or cipher block size,
- whichever is larger) bytes of a packet.
-
-5.1 Maximum Packet Length
-
- All implementations MUST be able to process packets with uncompressed
- payload length of 32768 bytes or less and total packet size of 35000
- bytes or less (including length, padding length, payload, padding,
- and MAC.). The maximum of 35000 bytes is an arbitrary chosen value
- larger than uncompressed size. Implementations SHOULD support longer
- packets, where they might be needed, e.g. if an implementation wants
- to send a very large number of certificates. Such packets MAY be
- sent if the version string indicates that the other party is able to
- process them. However, implementations SHOULD check that the packet
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- length is reasonable for the implementation to avoid
- denial-of-service and/or buffer overflow attacks.
-
-5.2 Compression
-
- If compression has been negotiated, the payload field (and only it)
- will be compressed using the negotiated algorithm. The length field
- and MAC will be computed from the compressed payload. Encryption will
- be done after compression.
-
- Compression MAY be stateful, depending on the method. Compression
- MUST be independent for each direction, and implementations MUST
- allow independently choosing the algorithm for each direction.
-
- The following compression methods are currently defined:
-
- none REQUIRED no compression
- zlib OPTIONAL ZLIB (LZ77) compression
-
- The "zlib" compression is described in [RFC1950] and in [RFC1951].
- The compression context is initialized after each key exchange, and
- is passed from one packet to the next with only a partial flush being
- performed at the end of each packet. A partial flush means that the
- current compressed block is ended and all data will be output. If the
- current block is not a stored block, one or more empty blocks are
- added after the current block to ensure that there are at least 8
- bits counting from the start of the end-of-block code of the current
- block to the end of the packet payload.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.3 Encryption
-
- An encryption algorithm and a key will be negotiated during the key
- exchange. When encryption is in effect, the packet length, padding
- length, payload and padding fields of each packet MUST be encrypted
- with the given algorithm.
-
- The encrypted data in all packets sent in one direction SHOULD be
- considered a single data stream. For example, initialization vectors
- SHOULD be passed from the end of one packet to the beginning of the
- next packet. All ciphers SHOULD use keys with an effective key length
- of 128 bits or more.
-
- The ciphers in each direction MUST run independently of each other,
- and implementations MUST allow independently choosing the algorithm
- for each direction (if multiple algorithms are allowed by local
- policy).
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The following ciphers are currently defined:
-
- 3des-cbc REQUIRED three-key 3DES in CBC mode
- blowfish-cbc OPTIONALi Blowfish in CBC mode
- twofish256-cbc OPTIONAL Twofish in CBC mode,
- with 256-bit key
- twofish-cbc OPTIONAL alias for "twofish256-cbc" (this
- is being retained for
- historical reasons)
- twofish192-cbc OPTIONAL Twofish with 192-bit key
- twofish128-cbc OPTIONAL Twofish with 128-bit key
- aes256-cbc OPTIONAL AES (Rijndael) in CBC mode,
- with 256-bit key
- aes192-cbc OPTIONAL AES with 192-bit key
- aes128-cbc RECOMMENDED AES with 128-bit key
- serpent256-cbc OPTIONAL Serpent in CBC mode, with
- 256-bit key
- serpent192-cbc OPTIONAL Serpent with 192-bit key
- serpent128-cbc OPTIONAL Serpent with 128-bit key
- arcfour OPTIONAL the ARCFOUR stream cipher
- idea-cbc OPTIONAL IDEA in CBC mode
- cast128-cbc OPTIONAL CAST-128 in CBC mode
- none OPTIONAL no encryption; NOT RECOMMENDED
-
- The "3des-cbc" cipher is three-key triple-DES
- (encrypt-decrypt-encrypt), where the first 8 bytes of the key are
- used for the first encryption, the next 8 bytes for the decryption,
- and the following 8 bytes for the final encryption. This requires 24
- bytes of key data (of which 168 bits are actually used). To
- implement CBC mode, outer chaining MUST be used (i.e., there is only
- one initialization vector). This is a block cipher with 8 byte
- blocks. This algorithm is defined in [FIPS-46-3]
-
- The "blowfish-cbc" cipher is Blowfish in CBC mode, with 128 bit keys
- [SCHNEIER]. This is a block cipher with 8 byte blocks.
-
- The "twofish-cbc" or "twofish256-cbc" cipher is Twofish in CBC mode,
- with 256 bit keys as described [TWOFISH]. This is a block cipher with
- 16 byte blocks.
-
- The "twofish192-cbc" cipher. Same as above but with 192-bit key.
-
- The "twofish128-cbc" cipher. Same as above but with 128-bit key.
-
- The "aes256-cbc" cipher is AES (Advanced Encryption Standard)
- [FIPS-197], formerly Rijndael, in CBC mode. This version uses 256-bit
- key.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The "aes192-cbc" cipher. Same as above but with 192-bit key.
-
- The "aes128-cbc" cipher. Same as above but with 128-bit key.
-
- The "serpent256-cbc" cipher in CBC mode, with 256-bit key as
- described in the Serpent AES submission.
-
- The "serpent192-cbc" cipher. Same as above but with 192-bit key.
-
- The "serpent128-cbc" cipher. Same as above but with 128-bit key.
-
- The "arcfour" is the Arcfour stream cipher with 128 bit keys. The
- Arcfour cipher is believed to be compatible with the RC4 cipher
- [SCHNEIER]. RC4 is a registered trademark of RSA Data Security Inc.
- Arcfour (and RC4) has problems with weak keys, and should be used
- with caution.
-
- The "idea-cbc" cipher is the IDEA cipher in CBC mode [SCHNEIER].
-
- The "cast128-cbc" cipher is the CAST-128 cipher in CBC mode
- [RFC2144].
-
- The "none" algorithm specifies that no encryption is to be done.
- Note that this method provides no confidentiality protection, and it
- is not recommended. Some functionality (e.g. password
- authentication) may be disabled for security reasons if this cipher
- is chosen.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.4 Data Integrity
-
- Data integrity is protected by including with each packet a message
- authentication code (MAC) that is computed from a shared secret,
- packet sequence number, and the contents of the packet.
-
- The message authentication algorithm and key are negotiated during
- key exchange. Initially, no MAC will be in effect, and its length
- MUST be zero. After key exchange, the selected MAC will be computed
- before encryption from the concatenation of packet data:
-
- mac = MAC(key, sequence_number || unencrypted_packet)
-
- where unencrypted_packet is the entire packet without MAC (the length
- fields, payload and padding), and sequence_number is an implicit
- packet sequence number represented as uint32. The sequence number is
- initialized to zero for the first packet, and is incremented after
- every packet (regardless of whether encryption or MAC is in use). It
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- is never reset, even if keys/algorithms are renegotiated later. It
- wraps around to zero after every 2^32 packets. The packet sequence
- number itself is not included in the packet sent over the wire.
-
- The MAC algorithms for each direction MUST run independently, and
- implementations MUST allow choosing the algorithm independently for
- both directions.
-
- The MAC bytes resulting from the MAC algorithm MUST be transmitted
- without encryption as the last part of the packet. The number of MAC
- bytes depends on the algorithm chosen.
-
- The following MAC algorithms are currently defined:
-
- hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
- length = 20)
- hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
- length = 12, key length = 20)
- hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
- length = 16)
- hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
- length = 12, key length = 16)
- none OPTIONAL no MAC; NOT RECOMMENDED
-
- Figure 1
-
- The "hmac-*" algorithms are described in [RFC2104] The "*-n" MACs use
- only the first n bits of the resulting value.
-
- The hash algorithms are described in [SCHNEIER].
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.5 Key Exchange Methods
-
- The key exchange method specifies how one-time session keys are
- generated for encryption and for authentication, and how the server
- authentication is done.
-
- Only one REQUIRED key exchange method has been defined:
-
- diffie-hellman-group1-sha1 REQUIRED
-
- This method is described later in this document.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-5.6 Public Key Algorithms
-
- This protocol has been designed to be able to operate with almost any
- public key format, encoding, and algorithm (signature and/or
- encryption).
-
- There are several aspects that define a public key type:
- o Key format: how is the key encoded and how are certificates
- represented. The key blobs in this protocol MAY contain
- certificates in addition to keys.
- o Signature and/or encryption algorithms. Some key types may not
- support both signing and encryption. Key usage may also be
- restricted by policy statements in e.g. certificates. In this
- case, different key types SHOULD be defined for the different
- policy alternatives.
- o Encoding of signatures and/or encrypted data. This includes but is
- not limited to padding, byte order, and data formats.
-
- The following public key and/or certificate formats are currently defined:
-
- ssh-dss REQUIRED sign Raw DSS Key
- ssh-rsa RECOMMENDED sign Raw RSA Key
- x509v3-sign-rsa OPTIONAL sign X.509 certificates (RSA key)
- x509v3-sign-dss OPTIONAL sign X.509 certificates (DSS key)
- spki-sign-rsa OPTIONAL sign SPKI certificates (RSA key)
- spki-sign-dss OPTIONAL sign SPKI certificates (DSS key)
- pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
- pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
-
- Additional key types may be defined as specified in [SSH-ARCH].
-
- The key type MUST always be explicitly known (from algorithm
- negotiation or some other source). It is not normally included in
- the key blob.
-
- Certificates and public keys are encoded as follows:
-
- string certificate or public key format identifier
- byte[n] key/certificate data
-
- The certificate part may have be a zero length string, but a public
- key is required. This is the public key that will be used for
- authentication; the certificate sequence contained in the certificate
- blob can be used to provide authorization.
-
- Public key / certifcate formats that do not explicitly specify a
- signature format identifier MUST use the public key / certificate
- format identifier as the signature identifier.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- Signatures are encoded as follows:
- string signature format identifier (as specified by the
- public key / cert format)
- byte[n] signature blob in format specific encoding.
-
-
- The "ssh-dss" key format has the following specific encoding:
-
- string "ssh-dss"
- mpint p
- mpint q
- mpint g
- mpint y
-
- Here the p, q, g, and y parameters form the signature key blob.
-
- Signing and verifying using this key format is done according to the
- Digital Signature Standard [FIPS-186] using the SHA-1 hash. A
- description can also be found in [SCHNEIER].
-
- The resulting signature is encoded as follows:
-
- string "ssh-dss"
- string dss_signature_blob
-
- dss_signature_blob is encoded as a string containing r followed by s
- (which are 160 bits long integers, without lengths or padding,
- unsigned and in network byte order).
-
- The "ssh-rsa" key format has the following specific encoding:
-
- string "ssh-rsa"
- mpint e
- mpint n
-
- Here the e and n parameters form the signature key blob.
-
- Signing and verifying using this key format is done according to
- [SCHNEIER] and [PKCS1] using the SHA-1 hash.
-
- The resulting signature is encoded as follows:
-
- string "ssh-rsa"
- string rsa_signature_blob
-
- rsa_signature_blob is encoded as a string containing s (which is an
- integer, without lengths or padding, unsigned and in network byte
- order).
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The "spki-sign-rsa" method indicates that the certificate blob
- contains a sequence of SPKI certificates. The format of SPKI
- certificates is described in [RFC2693]. This method indicates that
- the key (or one of the keys in the certificate) is an RSA-key.
-
- The "spki-sign-dss". As above, but indicates that the key (or one of
- the keys in the certificate) is a DSS-key.
-
- The "pgp-sign-rsa" method indicates the certificates, the public key,
- and the signature are in OpenPGP compatible binary format
- ([RFC2440]). This method indicates that the key is an RSA-key.
-
- The "pgp-sign-dss". As above, but indicates that the key is a
- DSS-key.
-
-6. Key Exchange
-
- Key exchange begins by each side sending lists of supported
- algorithms. Each side has a preferred algorithm in each category, and
- it is assumed that most implementations at any given time will use
- the same preferred algorithm. Each side MAY guess which algorithm
- the other side is using, and MAY send an initial key exchange packet
- according to the algorithm if appropriate for the preferred method.
-
- Guess is considered wrong, if:
- o the kex algorithm and/or the host key algorithm is guessed wrong
- (server and client have different preferred algorithm), or
- o if any of the other algorithms cannot be agreed upon (the
- procedure is defined below in Section Section 6.1).
-
- Otherwise, the guess is considered to be right and the optimistically
- sent packet MUST be handled as the first key exchange packet.
-
- However, if the guess was wrong, and a packet was optimistically sent
- by one or both parties, such packets MUST be ignored (even if the
- error in the guess would not affect the contents of the initial
- packet(s)), and the appropriate side MUST send the correct initial
- packet.
-
- Server authentication in the key exchange MAY be implicit. After a
- key exchange with implicit server authentication, the client MUST
- wait for response to its service request message before sending any
- further data.
-
-6.1 Algorithm Negotiation
-
- Key exchange begins by each side sending the following packet:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_KEXINIT
- byte[16] cookie (random bytes)
- string kex_algorithms
- string server_host_key_algorithms
- string encryption_algorithms_client_to_server
- string encryption_algorithms_server_to_client
- string mac_algorithms_client_to_server
- string mac_algorithms_server_to_client
- string compression_algorithms_client_to_server
- string compression_algorithms_server_to_client
- string languages_client_to_server
- string languages_server_to_client
- boolean first_kex_packet_follows
- uint32 0 (reserved for future extension)
-
- Each of the algorithm strings MUST be a comma-separated list of
- algorithm names (see ''Algorithm Naming'' in [SSH-ARCH]). Each
- supported (allowed) algorithm MUST be listed in order of preference.
-
- The first algorithm in each list MUST be the preferred (guessed)
- algorithm. Each string MUST contain at least one algorithm name.
-
-
- cookie
- The cookie MUST be a random value generated by the sender. Its
- purpose is to make it impossible for either side to fully
- determine the keys and the session identifier.
-
- kex_algorithms
- Key exchange algorithms were defined above. The first
- algorithm MUST be the preferred (and guessed) algorithm. If
- both sides make the same guess, that algorithm MUST be used.
- Otherwise, the following algorithm MUST be used to choose a key
- exchange method: iterate over client's kex algorithms, one at a
- time. Choose the first algorithm that satisfies the following
- conditions:
- + the server also supports the algorithm,
- + if the algorithm requires an encryption-capable host key,
- there is an encryption-capable algorithm on the server's
- server_host_key_algorithms that is also supported by the
- client, and
- + if the algorithm requires a signature-capable host key,
- there is a signature-capable algorithm on the server's
- server_host_key_algorithms that is also supported by the
- client.
- + If no algorithm satisfying all these conditions can be
- found, the connection fails, and both sides MUST disconnect.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- server_host_key_algorithms
- List of the algorithms supported for the server host key. The
- server lists the algorithms for which it has host keys; the
- client lists the algorithms that it is willing to accept.
- (There MAY be multiple host keys for a host, possibly with
- different algorithms.)
-
- Some host keys may not support both signatures and encryption
- (this can be determined from the algorithm), and thus not all
- host keys are valid for all key exchange methods.
-
- Algorithm selection depends on whether the chosen key exchange
- algorithm requires a signature or encryption capable host key.
- It MUST be possible to determine this from the public key
- algorithm name. The first algorithm on the client's list that
- satisfies the requirements and is also supported by the server
- MUST be chosen. If there is no such algorithm, both sides MUST
- disconnect.
-
- encryption_algorithms
- Lists the acceptable symmetric encryption algorithms in order
- of preference. The chosen encryption algorithm to each
- direction MUST be the first algorithm on the client's list
- that is also on the server's list. If there is no such
- algorithm, both sides MUST disconnect.
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The defined algorithm names are listed in Section
- Section 5.3.
-
- mac_algorithms
- Lists the acceptable MAC algorithms in order of preference.
- The chosen MAC algorithm MUST be the first algorithm on the
- client's list that is also on the server's list. If there is
- no such algorithm, both sides MUST disconnect.
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The MAC algorithm names are listed in Section
- Figure 1.
-
- compression_algorithms
- Lists the acceptable compression algorithms in order of
- preference. The chosen compression algorithm MUST be the first
- algorithm on the client's list that is also on the server's
- list. If there is no such algorithm, both sides MUST
- disconnect.
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The compression algorithm names are listed in
- Section Section 5.2.
-
- languages
- This is a comma-separated list of language tags in order of
- preference [RFC3066]. Both parties MAY ignore this list. If
- there are no language preferences, this list SHOULD be empty.
- Language tags SHOULD NOT be present unless they are known to be
- needed by the sending party.
-
- first_kex_packet_follows
- Indicates whether a guessed key exchange packet follows. If a
- guessed packet will be sent, this MUST be TRUE. If no guessed
- packet will be sent, this MUST be FALSE.
-
- After receiving the SSH_MSG_KEXINIT packet from the other side,
- each party will know whether their guess was right. If the
- other party's guess was wrong, and this field was TRUE, the
- next packet MUST be silently ignored, and both sides MUST then
- act as determined by the negotiated key exchange method. If
- the guess was right, key exchange MUST continue using the
- guessed packet.
-
- After the KEXINIT packet exchange, the key exchange algorithm is run.
- It may involve several packet exchanges, as specified by the key
- exchange method.
-
-6.2 Output from Key Exchange
-
- The key exchange produces two values: a shared secret K, and an
- exchange hash H. Encryption and authentication keys are derived from
- these. The exchange hash H from the first key exchange is
- additionally used as the session identifier, which is a unique
- identifier for this connection. It is used by authentication methods
- as a part of the data that is signed as a proof of possession of a
- private key. Once computed, the session identifier is not changed,
- even if keys are later re-exchanged.
-
-
- Each key exchange method specifies a hash function that is used in
- the key exchange. The same hash algorithm MUST be used in key
- derivation. Here, we'll call it HASH.
-
-
- Encryption keys MUST be computed as HASH of a known value and K as
- follows:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- o Initial IV client to server: HASH(K || H || "A" || session_id)
- (Here K is encoded as mpint and "A" as byte and session_id as raw
- data."A" means the single character A, ASCII 65).
- o Initial IV server to client: HASH(K || H || "B" || session_id)
- o Encryption key client to server: HASH(K || H || "C" || session_id)
- o Encryption key server to client: HASH(K || H || "D" || session_id)
- o Integrity key client to server: HASH(K || H || "E" || session_id)
- o Integrity key server to client: HASH(K || H || "F" || session_id)
-
- Key data MUST be taken from the beginning of the hash output. 128
- bits (16 bytes) MUST be used for algorithms with variable-length
- keys. The only variable key length algorithm defined in this document
- is arcfour). For other algorithms, as many bytes as are needed are
- taken from the beginning of the hash value. If the key length needed
- is longer than the output of the HASH, the key is extended by
- computing HASH of the concatenation of K and H and the entire key so
- far, and appending the resulting bytes (as many as HASH generates) to
- the key. This process is repeated until enough key material is
- available; the key is taken from the beginning of this value. In
- other words:
-
- K1 = HASH(K || H || X || session_id) (X is e.g. "A")
- K2 = HASH(K || H || K1)
- K3 = HASH(K || H || K1 || K2)
- ...
- key = K1 || K2 || K3 || ...
-
- This process will lose entropy if the amount of entropy in K is
- larger than the internal state size of HASH.
-
-6.3 Taking Keys Into Use
-
- Key exchange ends by each side sending an SSH_MSG_NEWKEYS message.
- This message is sent with the old keys and algorithms. All messages
- sent after this message MUST use the new keys and algorithms.
-
-
- When this message is received, the new keys and algorithms MUST be
- taken into use for receiving.
-
-
- This message is the only valid message after key exchange, in
- addition to SSH_MSG_DEBUG, SSH_MSG_DISCONNECT and SSH_MSG_IGNORE
- messages. The purpose of this message is to ensure that a party is
- able to respond with a disconnect message that the other party can
- understand if something goes wrong with the key exchange.
- Implementations MUST NOT accept any other messages after key exchange
- before receiving SSH_MSG_NEWKEYS.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_NEWKEYS
-
-
-7. Diffie-Hellman Key Exchange
-
- The Diffie-Hellman key exchange provides a shared secret that can not
- be determined by either party alone. The key exchange is combined
- with a signature with the host key to provide host authentication.
-
-
- In the following description (C is the client, S is the server; p is
- a large safe prime, g is a generator for a subgroup of GF(p), and q
- is the order of the subgroup; V_S is S's version string; V_C is C's
- version string; K_S is S's public host key; I_C is C's KEXINIT
- message and I_S S's KEXINIT message which have been exchanged before
- this part begins):
-
-
- 1. C generates a random number x (1 < x < q) and computes e = g^x
- mod p. C sends "e" to S.
-
- 2. S generates a random number y (0 < y < q) and computes f = g^y
- mod p. S receives "e". It computes K = e^y mod p, H = hash(V_C
- || V_S || I_C || I_S || K_S || e || f || K) (these elements are
- encoded according to their types; see below), and signature s on
- H with its private host key. S sends "K_S || f || s" to C. The
- signing operation may involve a second hashing operation.
-
- 3. C verifies that K_S really is the host key for S (e.g. using
- certificates or a local database). C is also allowed to accept
- the key without verification; however, doing so will render the
- protocol insecure against active attacks (but may be desirable
- for practical reasons in the short term in many environments). C
- then computes K = f^x mod p, H = hash(V_C || V_S || I_C || I_S ||
- K_S || e || f || K), and verifies the signature s on H.
-
- Either side MUST NOT send or accept e or f values that are not in the
- range [1, p-1]. If this condition is violated, the key exchange
- fails.
-
-
- This is implemented with the following messages. The hash algorithm
- for computing the exchange hash is defined by the method name, and is
- called HASH. The public key algorithm for signing is negotiated with
- the KEXINIT messages.
-
- First, the client sends the following:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_KEXDH_INIT
- mpint e
-
-
- The server responds with the following:
-
- byte SSH_MSG_KEXDH_REPLY
- string server public host key and certificates (K_S)
- mpint f
- string signature of H
-
- The hash H is computed as the HASH hash of the concatenation of the
- following:
-
- string V_C, the client's version string (CR and NL excluded)
- string V_S, the server's version string (CR and NL excluded)
- string I_C, the payload of the client's SSH_MSG_KEXINIT
- string I_S, the payload of the server's SSH_MSG_KEXINIT
- string K_S, the host key
- mpint e, exchange value sent by the client
- mpint f, exchange value sent by the server
- mpint K, the shared secret
-
- This value is called the exchange hash, and it is used to
- authenticate the key exchange. The exchange hash SHOULD be kept
- secret.
-
-
- The signature algorithm MUST be applied over H, not the original
- data. Most signature algorithms include hashing and additional
- padding. For example, "ssh-dss" specifies SHA-1 hashing; in that
- case, the data is first hashed with HASH to compute H, and H is then
- hashed with SHA-1 as part of the signing operation.
-
-7.1 diffie-hellman-group1-sha1
-
- The "diffie-hellman-group1-sha1" method specifies Diffie-Hellman key
- exchange with SHA-1 as HASH, and Oakley group 14 [RFC3526] (2048-bit
- MODP Group). It is included below in hexadecimal and decimal.
-
- The prime p is equal to 2^1024 - 2^960 - 1 + 2^64 * floor( 2^894 Pi +
- 129093 ). Its hexadecimal value is:
-
- FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
- 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
- EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
- E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
- EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- FFFFFFFF FFFFFFFF.
-
- In decimal, this value is:
-
- 179769313486231590770839156793787453197860296048756011706444
- 423684197180216158519368947833795864925541502180565485980503
- 646440548199239100050792877003355816639229553136239076508735
- 759914822574862575007425302077447712589550957937778424442426
- 617334727629299387668709205606050270810842907692932019128194
- 467627007.
-
- The generator used with this prime is g = 2. The group order q is (p
- - 1) / 2.
-
-8. Key Re-Exchange
-
- Key re-exchange is started by sending an SSH_MSG_KEXINIT packet when
- not already doing a key exchange (as described in Section Section
- 6.1). When this message is received, a party MUST respond with its
- own SSH_MSG_KEXINIT message except when the received SSH_MSG_KEXINIT
- already was a reply. Either party MAY initiate the re-exchange, but
- roles MUST NOT be changed (i.e., the server remains the server, and
- the client remains the client).
-
-
- Key re-exchange is performed using whatever encryption was in effect
- when the exchange was started. Encryption, compression, and MAC
- methods are not changed before a new SSH_MSG_NEWKEYS is sent after
- the key exchange (as in the initial key exchange). Re-exchange is
- processed identically to the initial key exchange, except for the
- session identifier that will remain unchanged. It is permissible to
- change some or all of the algorithms during the re-exchange. Host
- keys can also change. All keys and initialization vectors are
- recomputed after the exchange. Compression and encryption contexts
- are reset.
-
-
- It is recommended that the keys are changed after each gigabyte of
- transmitted data or after each hour of connection time, whichever
- comes sooner. However, since the re-exchange is a public key
- operation, it requires a fair amount of processing power and should
- not be performed too often.
-
-
- More application data may be sent after the SSH_MSG_NEWKEYS packet
- has been sent; key exchange does not affect the protocols that lie
- above the SSH transport layer.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-9. Service Request
-
- After the key exchange, the client requests a service. The service is
- identified by a name. The format of names and procedures for defining
- new names are defined in [SSH-ARCH].
-
-
- Currently, the following names have been reserved:
-
- ssh-userauth
- ssh-connection
-
- Similar local naming policy is applied to the service names, as is
- applied to the algorithm names; a local service should use the
- "servicename@domain" syntax.
-
- byte SSH_MSG_SERVICE_REQUEST
- string service name
-
- If the server rejects the service request, it SHOULD send an
- appropriate SSH_MSG_DISCONNECT message and MUST disconnect.
-
-
- When the service starts, it may have access to the session identifier
- generated during the key exchange.
-
-
- If the server supports the service (and permits the client to use
- it), it MUST respond with the following:
-
- byte SSH_MSG_SERVICE_ACCEPT
- string service name
-
- Message numbers used by services should be in the area reserved for
- them (see Section 6 in [SSH-ARCH]). The transport level will
- continue to process its own messages.
-
-
- Note that after a key exchange with implicit server authentication,
- the client MUST wait for response to its service request message
- before sending any further data.
-
-10. Additional Messages
-
- Either party may send any of the following messages at any time.
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-10.1 Disconnection Message
-
- byte SSH_MSG_DISCONNECT
- uint32 reason code
- string description [RFC2279]
- string language tag [RFC3066]
-
- This message causes immediate termination of the connection. All
- implementations MUST be able to process this message; they SHOULD be
- able to send this message.
-
- The sender MUST NOT send or receive any data after this message, and
- the recipient MUST NOT accept any data after receiving this message.
- The description field gives a more specific explanation in a
- human-readable form. The error code gives the reason in a more
- machine-readable format (suitable for localization), and can have the
- following values:
-
- #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
- #define SSH_DISCONNECT_PROTOCOL_ERROR 2
- #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
- #define SSH_DISCONNECT_RESERVED 4
- #define SSH_DISCONNECT_MAC_ERROR 5
- #define SSH_DISCONNECT_COMPRESSION_ERROR 6
- #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
- #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
- #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
- #define SSH_DISCONNECT_CONNECTION_LOST 10
- #define SSH_DISCONNECT_BY_APPLICATION 11
- #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
- #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
- #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
- #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
-
- If the description string is displayed, control character filtering
- discussed in [SSH-ARCH] should be used to avoid attacks by sending
- terminal control characters.
-
-10.2 Ignored Data Message
-
- byte SSH_MSG_IGNORE
- string data
-
- All implementations MUST understand (and ignore) this message at any
- time (after receiving the protocol version). No implementation is
- required to send them. This message can be used as an additional
- protection measure against advanced traffic analysis techniques.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-10.3 Debug Message
-
- byte SSH_MSG_DEBUG
- boolean always_display
- string message [RFC2279]
- string language tag [RFC3066]
-
- All implementations MUST understand this message, but they are
- allowed to ignore it. This message is used to pass the other side
- information that may help debugging. If always_display is TRUE, the
- message SHOULD be displayed. Otherwise, it SHOULD NOT be displayed
- unless debugging information has been explicitly requested by the
- user.
-
-
- The message doesn't need to contain a newline. It is, however,
- allowed to consist of multiple lines separated by CRLF (Carriage
- Return - Line Feed) pairs.
-
-
- If the message string is displayed, terminal control character
- filtering discussed in [SSH-ARCH] should be used to avoid attacks by
- sending terminal control characters.
-
-10.4 Reserved Messages
-
- An implementation MUST respond to all unrecognized messages with an
- SSH_MSG_UNIMPLEMENTED message in the order in which the messages were
- received. Such messages MUST be otherwise ignored. Later protocol
- versions may define other meanings for these message types.
-
- byte SSH_MSG_UNIMPLEMENTED
- uint32 packet sequence number of rejected message
-
-
-11. Summary of Message Numbers
-
- The following message numbers have been defined in this protocol:
-
- #define SSH_MSG_DISCONNECT 1
- #define SSH_MSG_IGNORE 2
- #define SSH_MSG_UNIMPLEMENTED 3
- #define SSH_MSG_DEBUG 4
- #define SSH_MSG_SERVICE_REQUEST 5
- #define SSH_MSG_SERVICE_ACCEPT 6
-
- #define SSH_MSG_KEXINIT 20
- #define SSH_MSG_NEWKEYS 21
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 23]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- /* Numbers 30-49 used for kex packets.
- Different kex methods may reuse message numbers in
- this range. */
-
- #define SSH_MSG_KEXDH_INIT 30
- #define SSH_MSG_KEXDH_REPLY 31
-
-
-12. IANA Considerations
-
- This document is part of a set, the IANA considerations for the SSH
- protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],
- [SSH-CONNECT] are detailed in [SSH-NUMBERS].
-
-13. Security Considerations
-
- This protocol provides a secure encrypted channel over an insecure
- network. It performs server host authentication, key exchange,
- encryption, and integrity protection. It also derives a unique
- session id that may be used by higher-level protocols.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-14. Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementers or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-15. Additional Information
-
- The current document editor is: [email protected]. Comments on
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 24]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- this internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-Normative
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative
-
- [FIPS-186]
- Federal Information Processing Standards Publication,
- "FIPS PUB 186, Digital Signature Standard", May 1994.
-
- [FIPS-197]
- NIST, "FIPS PUB 197 Advanced Encryption Standard (AES)",
- November 2001.
-
- [FIPS-46-3]
- U.S. Dept. of Commerce, "FIPS PUB 46-3, Data Encryption
- Standard (DES)", October 1999.
-
- [RFC2459] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet
- X.509 Public Key Infrastructure Certificate and CRL
- Profile", RFC 2459, January 1999.
-
- [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 25]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- STD 13, RFC 1034, November 1987.
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format
- Specification version 3.3", RFC 1950, May 1996.
-
- [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification
- version 1.3", RFC 1951, May 1996.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
- [RFC2144] Adams, C., "The CAST-128 Encryption Algorithm", RFC 2144,
- May 1997.
-
- [RFC2440] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,
- "OpenPGP Message Format", RFC 2440, November 1998.
-
- [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas,
- B. and T. Ylonen, "SPKI Certificate Theory", RFC 2693,
- September 1999.
-
- [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential (MODP)
- Diffie-Hellman groups for Internet Key Exchange (IKE)",
- RFC 3526, May 2003.
-
- [SCHNEIER]
- Schneier, B., "Applied Cryptography Second Edition:
- protocols algorithms and source in code in C", 1996.
-
- [TWOFISH] Schneier, B., "The Twofish Encryptions Algorithm: A
- 128-Bit Block Cipher, 1st Edition", March 1999.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 26]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park 95025
- USA
-
-
-Appendix A. Contibutors
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 27]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 28]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 29] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps
deleted file mode 100644
index be5799dbce..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps
+++ /dev/null
@@ -1,1881 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:35:32 2003
-%%Orientation: Portrait
-%%Pages: 8 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 2, 2003 D. Moffat, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( September 2002) s
-5 624 M
-( SSH Authentication Protocol) s
-5 613 M
-( draft-ietf-secsh-userauth-18.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 2, 2003.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network. This document describes the SSH) s
-5 261 M
-( authentication protocol framework and public key, password, and) s
-5 250 M
-( host-based client authentication methods. Additional authentication) s
-5 239 M
-( methods are described in separate documents. The SSH authentication) s
-5 228 M
-( protocol runs on top of the SSH transport layer protocol and provides) s
-5 217 M
-( a single authenticated tunnel for the SSH connection protocol.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 646 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 635 M
-( 3.1 The Authentication Protocol Framework . . . . . . . . . . . 3) s
-5 624 M
-( 3.1.1 Authentication Requests . . . . . . . . . . . . . . . . . . 4) s
-5 613 M
-( 3.1.2 Responses to Authentication Requests . . . . . . . . . . . . 5) s
-5 602 M
-( 3.1.3 The "none" Authentication Request . . . . . . . . . . . . . 6) s
-5 591 M
-( 3.1.4 Completion of User Authentication . . . . . . . . . . . . . 6) s
-5 580 M
-( 3.1.5 Banner Message . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 569 M
-( 3.2 Authentication Protocol Message Numbers . . . . . . . . . . 7) s
-5 558 M
-( 3.3 Public Key Authentication Method: publickey . . . . . . . . 8) s
-5 547 M
-( 3.4 Password Authentication Method: password . . . . . . . . . . 10) s
-5 536 M
-( 3.5 Host-Based Authentication: hostbased . . . . . . . . . . . . 11) s
-5 525 M
-( 4. Security Considerations . . . . . . . . . . . . . . . . . . 12) s
-5 514 M
-( Normative . . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 503 M
-( Informative . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 492 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 14) s
-5 481 M
-( Intellectual Property and Copyright Statements . . . . . . . 15) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH authentication protocol is a general-purpose user) s
-5 536 M
-( authentication protocol. It is intended to be run over the SSH) s
-5 525 M
-( transport layer protocol [SSH-TRANS]. This protocol assumes that the) s
-5 514 M
-( underlying protocols provide integrity and confidentiality) s
-5 503 M
-( protection.) s
-5 481 M
-( This document should be read only after reading the SSH architecture) s
-5 470 M
-( document [SSH-ARCH]. This document freely uses terminology and) s
-5 459 M
-( notation from the architecture document without reference or further) s
-5 448 M
-( explanation.) s
-5 426 M
-( The service name for this protocol is "ssh-userauth".) s
-5 404 M
-( When this protocol starts, it receives the session identifier from) s
-5 393 M
-( the lower-level protocol \(this is the exchange hash H from the first) s
-5 382 M
-( key exchange\). The session identifier uniquely identifies this) s
-5 371 M
-( session and is suitable for signing in order to prove ownership of a) s
-5 360 M
-( private key. This protocol also needs to know whether the lower-level) s
-5 349 M
-( protocol provides confidentiality protection.) s
-5 327 M
-(3. Conventions Used in This Document) s
-5 305 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 294 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 283 M
-( described in [RFC2119]) s
-5 261 M
-( The used data types and terminology are specified in the architecture) s
-5 250 M
-( document [SSH-ARCH]) s
-5 228 M
-( The architecture document also discusses the algorithm naming) s
-5 217 M
-( conventions that MUST be used with the SSH protocols.) s
-5 195 M
-(3.1 The Authentication Protocol Framework) s
-5 173 M
-( The server drives the authentication by telling the client which) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authentication methods can be used to continue the exchange at any) s
-5 679 M
-( given time. The client has the freedom to try the methods listed by) s
-5 668 M
-( the server in any order. This gives the server complete control over) s
-5 657 M
-( the authentication process if desired, but also gives enough) s
-5 646 M
-( flexibility for the client to use the methods it supports or that are) s
-5 635 M
-( most convenient for the user, when multiple methods are offered by) s
-5 624 M
-( the server.) s
-5 602 M
-( Authentication methods are identified by their name, as defined in) s
-5 591 M
-( [SSH-ARCH]. The "none" method is reserved, and MUST NOT be listed as) s
-5 580 M
-( supported. However, it MAY be sent by the client. The server MUST) s
-5 569 M
-( always reject this request, unless the client is to be allowed in) s
-5 558 M
-( without any authentication, in which case the server MUST accept this) s
-5 547 M
-( request. The main purpose of sending this request is to get the list) s
-5 536 M
-( of supported methods from the server.) s
-5 514 M
-( The server SHOULD have a timeout for authentication, and disconnect) s
-5 503 M
-( if the authentication has not been accepted within the timeout) s
-5 492 M
-( period. The RECOMMENDED timeout period is 10 minutes. Additionally,) s
-5 481 M
-( the implementation SHOULD limit the number of failed authentication) s
-5 470 M
-( attempts a client may perform in a single session \(the RECOMMENDED) s
-5 459 M
-( limit is 20 attempts\). If the threshold is exceeded, the server) s
-5 448 M
-( SHOULD disconnect.) s
-5 426 M
-(3.1.1 Authentication Requests) s
-5 404 M
-( All authentication requests MUST use the following message format.) s
-5 393 M
-( Only the first few fields are defined; the remaining fields depend on) s
-5 382 M
-( the authentication method.) s
-5 360 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 349 M
-( string user name \(in ISO-10646 UTF-8 encoding [RFC2279]\)) s
-5 338 M
-( string service name \(in US-ASCII\)) s
-5 327 M
-( string method name \(US-ASCII\)) s
-5 316 M
-( The rest of the packet is method-specific.) s
-5 294 M
-( The user name and service are repeated in every new authentication) s
-5 283 M
-( attempt, and MAY change. The server implementation MUST carefully) s
-5 272 M
-( check them in every message, and MUST flush any accumulated) s
-5 261 M
-( authentication states if they change. If it is unable to flush some) s
-5 250 M
-( authentication state, it MUST disconnect if the user or service name) s
-5 239 M
-( changes.) s
-5 217 M
-( The service name specifies the service to start after authentication.) s
-5 206 M
-( There may be several different authenticated services provided. If) s
-5 195 M
-( the requested service is not available, the server MAY disconnect) s
-5 184 M
-( immediately or at any later time. Sending a proper disconnect) s
-5 173 M
-( message is RECOMMENDED. In any case, if the service does not exist,) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authentication MUST NOT be accepted.) s
-5 668 M
-( If the requested user does not exist, the server MAY disconnect, or) s
-5 657 M
-( MAY send a bogus list of acceptable authentication methods, but never) s
-5 646 M
-( accept any. This makes it possible for the server to avoid) s
-5 635 M
-( disclosing information on which accounts exist. In any case, if the) s
-5 624 M
-( user does not exist, the authentication request MUST NOT be accepted.) s
-5 602 M
-( While there is usually little point for clients to send requests that) s
-5 591 M
-( the server does not list as acceptable, sending such requests is not) s
-5 580 M
-( an error, and the server SHOULD simply reject requests that it does) s
-5 569 M
-( not recognize.) s
-5 547 M
-( An authentication request MAY result in a further exchange of) s
-5 536 M
-( messages. All such messages depend on the authentication method) s
-5 525 M
-( used, and the client MAY at any time continue with a new) s
-5 514 M
-( SSH_MSG_USERAUTH_REQUEST message, in which case the server MUST) s
-5 503 M
-( abandon the previous authentication attempt and continue with the new) s
-5 492 M
-( one.) s
-5 470 M
-(3.1.2 Responses to Authentication Requests) s
-5 448 M
-( If the server rejects the authentication request, it MUST respond) s
-5 437 M
-( with the following:) s
-5 415 M
-( byte SSH_MSG_USERAUTH_FAILURE) s
-5 404 M
-( string authentications that can continue) s
-5 393 M
-( boolean partial success) s
-5 371 M
-( "Authentications that can continue" is a comma-separated list of) s
-5 360 M
-( authentication method names that may productively continue the) s
-5 349 M
-( authentication dialog.) s
-5 327 M
-( It is RECOMMENDED that servers only include those methods in the list) s
-5 316 M
-( that are actually useful. However, it is not illegal to include) s
-5 305 M
-( methods that cannot be used to authenticate the user.) s
-5 283 M
-( Already successfully completed authentications SHOULD NOT be included) s
-5 272 M
-( in the list, unless they really should be performed again for some) s
-5 261 M
-( reason.) s
-5 239 M
-( "Partial success" MUST be TRUE if the authentication request to which) s
-5 228 M
-( this is a response was successful. It MUST be FALSE if the request) s
-5 217 M
-( was not successfully processed.) s
-5 195 M
-( When the server accepts authentication, it MUST respond with the) s
-5 184 M
-( following:) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( byte SSH_MSG_USERAUTH_SUCCESS) s
-5 668 M
-( Note that this is not sent after each step in a multi-method) s
-5 657 M
-( authentication sequence, but only when the authentication is) s
-5 646 M
-( complete.) s
-5 624 M
-( The client MAY send several authentication requests without waiting) s
-5 613 M
-( for responses from previous requests. The server MUST process each) s
-5 602 M
-( request completely and acknowledge any failed requests with a) s
-5 591 M
-( SSH_MSG_USERAUTH_FAILURE message before processing the next request.) s
-5 569 M
-( A request that results in further exchange of messages will be) s
-5 558 M
-( aborted by a second request. It is not possible to send a second) s
-5 547 M
-( request without waiting for a response from the server, if the first) s
-5 536 M
-( request will result in further exchange of messages. No) s
-5 525 M
-( SSH_MSG_USERAUTH_FAILURE message will be sent for the aborted method.) s
-5 503 M
-( SSH_MSG_USERAUTH_SUCCESS MUST be sent only once. When) s
-5 492 M
-( SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication) s
-5 481 M
-( requests received after that SHOULD be silently ignored.) s
-5 459 M
-( Any non-authentication messages sent by the client after the request) s
-5 448 M
-( that resulted in SSH_MSG_USERAUTH_SUCCESS being sent MUST be passed) s
-5 437 M
-( to the service being run on top of this protocol. Such messages can) s
-5 426 M
-( be identified by their message numbers \(see Section Message Numbers) s
-5 415 M
-( \(Section 3.2\)\).) s
-5 393 M
-(3.1.3 The "none" Authentication Request) s
-5 371 M
-( A client may request a list of authentication methods that may) s
-5 360 M
-( continue by using the "none" authentication method.) s
-5 338 M
-( If no authentication at all is needed for the user, the server MUST) s
-5 327 M
-( return SSH_MSG_USERAUTH_SUCCESS. Otherwise, the server MUST return) s
-5 316 M
-( SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of) s
-5 305 M
-( authentication methods that can continue.) s
-5 283 M
-( This method MUST NOT be listed as supported by the server.) s
-5 261 M
-(3.1.4 Completion of User Authentication) s
-5 239 M
-( Authentication is complete when the server has responded with) s
-5 228 M
-( SSH_MSG_USERAUTH_SUCCESS; all authentication related messages) s
-5 217 M
-( received after sending this message SHOULD be silently ignored.) s
-5 195 M
-( After sending SSH_MSG_USERAUTH_SUCCESS, the server starts the) s
-5 184 M
-( requested service.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(3.1.5 Banner Message) s
-5 668 M
-( In some jurisdictions, sending a warning message before) s
-5 657 M
-( authentication may be relevant for getting legal protection. Many) s
-5 646 M
-( UNIX machines, for example, normally display text from `/etc/issue',) s
-5 635 M
-( or use "tcp wrappers" or similar software to display a banner before) s
-5 624 M
-( issuing a login prompt.) s
-5 602 M
-( The SSH server may send a SSH_MSG_USERAUTH_BANNER message at any time) s
-5 591 M
-( before authentication is successful. This message contains text to) s
-5 580 M
-( be displayed to the client user before authentication is attempted.) s
-5 569 M
-( The format is as follows:) s
-5 547 M
-( byte SSH_MSG_USERAUTH_BANNER) s
-5 536 M
-( string message \(ISO-10646 UTF-8\)) s
-5 525 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 503 M
-( The client SHOULD by default display the message on the screen.) s
-5 492 M
-( However, since the message is likely to be sent for every login) s
-5 481 M
-( attempt, and since some client software will need to open a separate) s
-5 470 M
-( window for this warning, the client software may allow the user to) s
-5 459 M
-( explicitly disable the display of banners from the server. The) s
-5 448 M
-( message may consist of multiple lines.) s
-5 426 M
-( If the message string is displayed, control character filtering) s
-5 415 M
-( discussed in [SSH-ARCH] SHOULD be used to avoid attacks by sending) s
-5 404 M
-( terminal control characters.) s
-5 382 M
-(3.2 Authentication Protocol Message Numbers) s
-5 360 M
-( All message numbers used by this authentication protocol are in the) s
-5 349 M
-( range from 50 to 79, which is part of the range reserved for) s
-5 338 M
-( protocols running on top of the SSH transport layer protocol.) s
-5 316 M
-( Message numbers of 80 and higher are reserved for protocols running) s
-5 305 M
-( after this authentication protocol, so receiving one of them before) s
-5 294 M
-( authentication is complete is an error, to which the server MUST) s
-5 283 M
-( respond by disconnecting \(preferably with a proper disconnect message) s
-5 272 M
-( sent first to ease troubleshooting\).) s
-5 250 M
-( After successful authentication, such messages are passed to the) s
-5 239 M
-( higher-level service.) s
-5 217 M
-( These are the general authentication message codes:) s
-5 195 M
-( #define SSH_MSG_USERAUTH_REQUEST 50) s
-5 184 M
-( #define SSH_MSG_USERAUTH_FAILURE 51) s
-5 173 M
-( #define SSH_MSG_USERAUTH_SUCCESS 52) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( #define SSH_MSG_USERAUTH_BANNER 53) s
-5 668 M
-( In addition to the above, there is a range of message numbers) s
-5 657 M
-( \(60..79\) reserved for method-specific messages. These messages are) s
-5 646 M
-( only sent by the server \(client sends only SSH_MSG_USERAUTH_REQUEST) s
-5 635 M
-( messages\). Different authentication methods reuse the same message) s
-5 624 M
-( numbers.) s
-5 602 M
-(3.3 Public Key Authentication Method: publickey) s
-5 580 M
-( The only REQUIRED authentication method is public key authentication.) s
-5 569 M
-( All implementations MUST support this method; however, not all users) s
-5 558 M
-( need to have public keys, and most local policies are not likely to) s
-5 547 M
-( require public key authentication for all users in the near future.) s
-5 525 M
-( With this method, the possession of a private key serves as) s
-5 514 M
-( authentication. This method works by sending a signature created) s
-5 503 M
-( with a private key of the user. The server MUST check that the key) s
-5 492 M
-( is a valid authenticator for the user, and MUST check that the) s
-5 481 M
-( signature is valid. If both hold, the authentication request MUST be) s
-5 470 M
-( accepted; otherwise it MUST be rejected. \(Note that the server MAY) s
-5 459 M
-( require additional authentications after successful authentication.\)) s
-5 437 M
-( Private keys are often stored in an encrypted form at the client) s
-5 426 M
-( host, and the user must supply a passphrase before the signature can) s
-5 415 M
-( be generated. Even if they are not, the signing operation involves) s
-5 404 M
-( some expensive computation. To avoid unnecessary processing and user) s
-5 393 M
-( interaction, the following message is provided for querying whether) s
-5 382 M
-( authentication using the key would be acceptable.) s
-5 360 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 349 M
-( string user name) s
-5 338 M
-( string service) s
-5 327 M
-( string "publickey") s
-5 316 M
-( boolean FALSE) s
-5 305 M
-( string public key algorithm name) s
-5 294 M
-( string public key blob) s
-5 272 M
-( Public key algorithms are defined in the transport layer) s
-5 261 M
-( specification [SSH-TRANS]. The public key blob may contain) s
-5 250 M
-( certificates.) s
-5 228 M
-( Any public key algorithm may be offered for use in authentication.) s
-5 217 M
-( In particular, the list is not constrained by what was negotiated) s
-5 206 M
-( during key exchange. If the server does not support some algorithm,) s
-5 195 M
-( it MUST simply reject the request.) s
-5 173 M
-( The server MUST respond to this message with either) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( SSH_MSG_USERAUTH_FAILURE or with the following:) s
-5 668 M
-( byte SSH_MSG_USERAUTH_PK_OK) s
-5 657 M
-( string public key algorithm name from the request) s
-5 646 M
-( string public key blob from the request) s
-5 624 M
-( To perform actual authentication, the client MAY then send a) s
-5 613 M
-( signature generated using the private key. The client MAY send the) s
-5 602 M
-( signature directly without first verifying whether the key is) s
-5 591 M
-( acceptable. The signature is sent using the following packet:) s
-5 569 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 558 M
-( string user name) s
-5 547 M
-( string service) s
-5 536 M
-( string "publickey") s
-5 525 M
-( boolean TRUE) s
-5 514 M
-( string public key algorithm name) s
-5 503 M
-( string public key to be used for authentication) s
-5 492 M
-( string signature) s
-5 470 M
-( Signature is a signature by the corresponding private key over the) s
-5 459 M
-( following data, in the following order:) s
-5 437 M
-( string session identifier) s
-5 426 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 415 M
-( string user name) s
-5 404 M
-( string service) s
-5 393 M
-( string "publickey") s
-5 382 M
-( boolean TRUE) s
-5 371 M
-( string public key algorithm name) s
-5 360 M
-( string public key to be used for authentication) s
-5 338 M
-( When the server receives this message, it MUST check whether the) s
-5 327 M
-( supplied key is acceptable for authentication, and if so, it MUST) s
-5 316 M
-( check whether the signature is correct.) s
-5 294 M
-( If both checks succeed, this method is successful. Note that the) s
-5 283 M
-( server may require additional authentications. The server MUST) s
-5 272 M
-( respond with SSH_MSG_USERAUTH_SUCCESS \(if no more authentications are) s
-5 261 M
-( needed\), or SSH_MSG_USERAUTH_FAILURE \(if the request failed, or more) s
-5 250 M
-( authentications are needed\).) s
-5 228 M
-( The following method-specific message numbers are used by the) s
-5 217 M
-( publickey authentication method.) s
-5 195 M
-( /* Key-based */) s
-5 184 M
-( #define SSH_MSG_USERAUTH_PK_OK 60) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(3.4 Password Authentication Method: password) s
-5 668 M
-( Password authentication uses the following packets. Note that a) s
-5 657 M
-( server MAY request the user to change the password. All) s
-5 646 M
-( implementations SHOULD support password authentication.) s
-5 624 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 613 M
-( string user name) s
-5 602 M
-( string service) s
-5 591 M
-( string "password") s
-5 580 M
-( boolean FALSE) s
-5 569 M
-( string plaintext password \(ISO-10646 UTF-8\)) s
-5 547 M
-( Note that the password is encoded in ISO-10646 UTF-8. It is up to) s
-5 536 M
-( the server how it interprets the password and validates it against) s
-5 525 M
-( the password database. However, if the client reads the password in) s
-5 514 M
-( some other encoding \(e.g., ISO 8859-1 \(ISO Latin1\)\), it MUST convert) s
-5 503 M
-( the password to ISO-10646 UTF-8 before transmitting, and the server) s
-5 492 M
-( MUST convert the password to the encoding used on that system for) s
-5 481 M
-( passwords.) s
-5 459 M
-( Note that even though the cleartext password is transmitted in the) s
-5 448 M
-( packet, the entire packet is encrypted by the transport layer. Both) s
-5 437 M
-( the server and the client should check whether the underlying) s
-5 426 M
-( transport layer provides confidentiality \(i.e., if encryption is) s
-5 415 M
-( being used\). If no confidentiality is provided \(none cipher\),) s
-5 404 M
-( password authentication SHOULD be disabled. If there is no) s
-5 393 M
-( confidentiality or no MAC, password change SHOULD be disabled.) s
-5 371 M
-( Normally, the server responds to this message with success or) s
-5 360 M
-( failure. However, if the password has expired the server SHOULD) s
-5 349 M
-( indicate this by responding with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.) s
-5 338 M
-( In anycase the server MUST NOT allow an expired password to be used) s
-5 327 M
-( for authentication.) s
-5 305 M
-( byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) s
-5 294 M
-( string prompt \(ISO-10646 UTF-8\)) s
-5 283 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 261 M
-( In this case, the client MAY continue with a different authentication) s
-5 250 M
-( method, or request a new password from the user and retry password) s
-5 239 M
-( authentication using the following message. The client MAY also send) s
-5 228 M
-( this message instead of the normal password authentication request) s
-5 217 M
-( without the server asking for it.) s
-5 195 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 184 M
-( string user name) s
-5 173 M
-( string service) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( string "password") s
-5 679 M
-( boolean TRUE) s
-5 668 M
-( string plaintext old password \(ISO-10646 UTF-8\)) s
-5 657 M
-( string plaintext new password \(ISO-10646 UTF-8\)) s
-5 635 M
-( The server must reply to request message with) s
-5 624 M
-( SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another) s
-5 613 M
-( SSH_MSG_USERAUTH_PASSWD_CHANGEREQ. The meaning of these is as) s
-5 602 M
-( follows:) s
-5 580 M
-( SSH_MSG_USERAUTH_SUCCESS The password has been changed, and) s
-5 569 M
-( authentication has been successfully completed.) s
-5 547 M
-( SSH_MSG_USERAUTH_FAILURE with partial success The password has) s
-5 536 M
-( been changed, but more authentications are needed.) s
-5 514 M
-( SSH_MSG_USERAUTH_FAILURE without partial success The password has) s
-5 503 M
-( not been changed. Either password changing was not supported, or) s
-5 492 M
-( the old password was bad. Note that if the server has already) s
-5 481 M
-( sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, we know that it supports) s
-5 470 M
-( changing the password.) s
-5 448 M
-( SSH_MSG_USERAUTH_CHANGEREQ The password was not changed because) s
-5 437 M
-( the new password was not acceptable \(e.g. too easy to guess\).) s
-5 415 M
-( The following method-specific message numbers are used by the) s
-5 404 M
-( password authentication method.) s
-5 382 M
-( #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60) s
-5 349 M
-(3.5 Host-Based Authentication: hostbased) s
-5 327 M
-( Some sites wish to allow authentication based on the host where the) s
-5 316 M
-( user is coming from, and the user name on the remote host. While) s
-5 305 M
-( this form of authentication is not suitable for high-security sites,) s
-5 294 M
-( it can be very convenient in many environments. This form of) s
-5 283 M
-( authentication is OPTIONAL. When used, special care SHOULD be taken) s
-5 272 M
-( to prevent a regular user from obtaining the private host key.) s
-5 250 M
-( The client requests this form of authentication by sending the) s
-5 239 M
-( following message. It is similar to the UNIX "rhosts" and) s
-5 228 M
-( "hosts.equiv" styles of authentication, except that the identity of) s
-5 217 M
-( the client host is checked more rigorously.) s
-5 195 M
-( This method works by having the client send a signature created with) s
-5 184 M
-( the private key of the client host, which the server checks with that) s
-5 173 M
-( host's public key. Once the client host's identity is established,) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authorization \(but no further authentication\) is performed based on) s
-5 679 M
-( the user names on the server and the client, and the client host) s
-5 668 M
-( name.) s
-5 646 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 635 M
-( string user name) s
-5 624 M
-( string service) s
-5 613 M
-( string "hostbased") s
-5 602 M
-( string public key algorithm for host key) s
-5 591 M
-( string public host key and certificates for client host) s
-5 580 M
-( string client host name \(FQDN; US-ASCII\)) s
-5 569 M
-( string user name on the client host \(ISO-10646 UTF-8\)) s
-5 558 M
-( string signature) s
-5 536 M
-( Public key algorithm names for use in "public key algorithm for host) s
-5 525 M
-( key" are defined in the transport layer specification. The "public) s
-5 514 M
-( host key for client host" may include certificates.) s
-5 492 M
-( Signature is a signature with the private host key of the following) s
-5 481 M
-( data, in this order:) s
-5 459 M
-( string session identifier) s
-5 448 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 437 M
-( string user name) s
-5 426 M
-( string service) s
-5 415 M
-( string "hostbased") s
-5 404 M
-( string public key algorithm for host key) s
-5 393 M
-( string public host key and certificates for client host) s
-5 382 M
-( string client host name \(FQDN; US-ASCII\)) s
-5 371 M
-( string user name on the client host\(ISO-10646 UTF-8\)) s
-5 349 M
-( The server MUST verify that the host key actually belongs to the) s
-5 338 M
-( client host named in the message, that the given user on that host is) s
-5 327 M
-( allowed to log in, and that the signature is a valid signature on the) s
-5 316 M
-( appropriate value by the given host key. The server MAY ignore the) s
-5 305 M
-( client user name, if it wants to authenticate only the client host.) s
-5 283 M
-( It is RECOMMENDED that whenever possible, the server perform) s
-5 272 M
-( additional checks to verify that the network address obtained from) s
-5 261 M
-( the \(untrusted\) network matches the given client host name. This) s
-5 250 M
-( makes exploiting compromised host keys more difficult. Note that) s
-5 239 M
-( this may require special handling for connections coming through a) s
-5 228 M
-( firewall.) s
-5 206 M
-(4. Security Considerations) s
-5 184 M
-( The purpose of this protocol is to perform client user) s
-5 173 M
-( authentication. It assumed that this runs over a secure transport) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( layer protocol, which has already authenticated the server machine,) s
-5 679 M
-( established an encrypted communications channel, and computed a) s
-5 668 M
-( unique session identifier for this session. The transport layer) s
-5 657 M
-( provides forward secrecy for password authentication and other) s
-5 646 M
-( methods that rely on secret data.) s
-5 624 M
-( Full security considerations for this protocol are provided in) s
-5 613 M
-( Section 8 of [SSH-ARCH]) s
-5 591 M
-(Normative) s
-5 569 M
-( [SSH-ARCH]) s
-5 558 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 547 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 525 M
-( [SSH-TRANS]) s
-5 514 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 503 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 481 M
-( [SSH-USERAUTH]) s
-5 470 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 459 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 437 M
-( [SSH-CONNECT]) s
-5 426 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 415 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 393 M
-( [SSH-NUMBERS]) s
-5 382 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 371 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 360 M
-( 2003.) s
-5 338 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 327 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 305 M
-(Informative) s
-5 283 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 272 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 250 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 239 M
-( 10646", RFC 2279, January 1998.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Authors' Addresses) s
-5 668 M
-( Tatu Ylonen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( Fredrikinkatu 42) s
-5 635 M
-( HELSINKI FIN-00100) s
-5 624 M
-( Finland) s
-5 602 M
-( EMail: [email protected]) s
-5 569 M
-( Darren J. Moffat \(editor\)) s
-5 558 M
-( Sun Microsystems, Inc) s
-5 547 M
-( 17 Network Circle) s
-5 536 M
-( Menlo Park 95025) s
-5 525 M
-( USA) s
-5 503 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 16
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt b/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt
deleted file mode 100644
index 9dae578a35..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt
+++ /dev/null
@@ -1,896 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 2, 2003 D. Moffat, Ed.
- Sun Microsystems, Inc
- September 2002
-
-
- SSH Authentication Protocol
- draft-ietf-secsh-userauth-18.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 2, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. This document describes the SSH
- authentication protocol framework and public key, password, and
- host-based client authentication methods. Additional authentication
- methods are described in separate documents. The SSH authentication
- protocol runs on top of the SSH transport layer protocol and provides
- a single authenticated tunnel for the SSH connection protocol.
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 1]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 3.1 The Authentication Protocol Framework . . . . . . . . . . . 3
- 3.1.1 Authentication Requests . . . . . . . . . . . . . . . . . . 4
- 3.1.2 Responses to Authentication Requests . . . . . . . . . . . . 5
- 3.1.3 The "none" Authentication Request . . . . . . . . . . . . . 6
- 3.1.4 Completion of User Authentication . . . . . . . . . . . . . 6
- 3.1.5 Banner Message . . . . . . . . . . . . . . . . . . . . . . . 7
- 3.2 Authentication Protocol Message Numbers . . . . . . . . . . 7
- 3.3 Public Key Authentication Method: publickey . . . . . . . . 8
- 3.4 Password Authentication Method: password . . . . . . . . . . 10
- 3.5 Host-Based Authentication: hostbased . . . . . . . . . . . . 11
- 4. Security Considerations . . . . . . . . . . . . . . . . . . 12
- Normative . . . . . . . . . . . . . . . . . . . . . . . . . 13
- Informative . . . . . . . . . . . . . . . . . . . . . . . . 13
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 14
- Intellectual Property and Copyright Statements . . . . . . . 15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 2]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH authentication protocol is a general-purpose user
- authentication protocol. It is intended to be run over the SSH
- transport layer protocol [SSH-TRANS]. This protocol assumes that the
- underlying protocols provide integrity and confidentiality
- protection.
-
- This document should be read only after reading the SSH architecture
- document [SSH-ARCH]. This document freely uses terminology and
- notation from the architecture document without reference or further
- explanation.
-
- The service name for this protocol is "ssh-userauth".
-
- When this protocol starts, it receives the session identifier from
- the lower-level protocol (this is the exchange hash H from the first
- key exchange). The session identifier uniquely identifies this
- session and is suitable for signing in order to prove ownership of a
- private key. This protocol also needs to know whether the lower-level
- protocol provides confidentiality protection.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119]
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH]
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-3.1 The Authentication Protocol Framework
-
- The server drives the authentication by telling the client which
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 3]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authentication methods can be used to continue the exchange at any
- given time. The client has the freedom to try the methods listed by
- the server in any order. This gives the server complete control over
- the authentication process if desired, but also gives enough
- flexibility for the client to use the methods it supports or that are
- most convenient for the user, when multiple methods are offered by
- the server.
-
- Authentication methods are identified by their name, as defined in
- [SSH-ARCH]. The "none" method is reserved, and MUST NOT be listed as
- supported. However, it MAY be sent by the client. The server MUST
- always reject this request, unless the client is to be allowed in
- without any authentication, in which case the server MUST accept this
- request. The main purpose of sending this request is to get the list
- of supported methods from the server.
-
- The server SHOULD have a timeout for authentication, and disconnect
- if the authentication has not been accepted within the timeout
- period. The RECOMMENDED timeout period is 10 minutes. Additionally,
- the implementation SHOULD limit the number of failed authentication
- attempts a client may perform in a single session (the RECOMMENDED
- limit is 20 attempts). If the threshold is exceeded, the server
- SHOULD disconnect.
-
-3.1.1 Authentication Requests
-
- All authentication requests MUST use the following message format.
- Only the first few fields are defined; the remaining fields depend on
- the authentication method.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name (in ISO-10646 UTF-8 encoding [RFC2279])
- string service name (in US-ASCII)
- string method name (US-ASCII)
- The rest of the packet is method-specific.
-
- The user name and service are repeated in every new authentication
- attempt, and MAY change. The server implementation MUST carefully
- check them in every message, and MUST flush any accumulated
- authentication states if they change. If it is unable to flush some
- authentication state, it MUST disconnect if the user or service name
- changes.
-
- The service name specifies the service to start after authentication.
- There may be several different authenticated services provided. If
- the requested service is not available, the server MAY disconnect
- immediately or at any later time. Sending a proper disconnect
- message is RECOMMENDED. In any case, if the service does not exist,
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 4]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authentication MUST NOT be accepted.
-
- If the requested user does not exist, the server MAY disconnect, or
- MAY send a bogus list of acceptable authentication methods, but never
- accept any. This makes it possible for the server to avoid
- disclosing information on which accounts exist. In any case, if the
- user does not exist, the authentication request MUST NOT be accepted.
-
- While there is usually little point for clients to send requests that
- the server does not list as acceptable, sending such requests is not
- an error, and the server SHOULD simply reject requests that it does
- not recognize.
-
- An authentication request MAY result in a further exchange of
- messages. All such messages depend on the authentication method
- used, and the client MAY at any time continue with a new
- SSH_MSG_USERAUTH_REQUEST message, in which case the server MUST
- abandon the previous authentication attempt and continue with the new
- one.
-
-3.1.2 Responses to Authentication Requests
-
- If the server rejects the authentication request, it MUST respond
- with the following:
-
- byte SSH_MSG_USERAUTH_FAILURE
- string authentications that can continue
- boolean partial success
-
- "Authentications that can continue" is a comma-separated list of
- authentication method names that may productively continue the
- authentication dialog.
-
- It is RECOMMENDED that servers only include those methods in the list
- that are actually useful. However, it is not illegal to include
- methods that cannot be used to authenticate the user.
-
- Already successfully completed authentications SHOULD NOT be included
- in the list, unless they really should be performed again for some
- reason.
-
- "Partial success" MUST be TRUE if the authentication request to which
- this is a response was successful. It MUST be FALSE if the request
- was not successfully processed.
-
- When the server accepts authentication, it MUST respond with the
- following:
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 5]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- byte SSH_MSG_USERAUTH_SUCCESS
-
- Note that this is not sent after each step in a multi-method
- authentication sequence, but only when the authentication is
- complete.
-
- The client MAY send several authentication requests without waiting
- for responses from previous requests. The server MUST process each
- request completely and acknowledge any failed requests with a
- SSH_MSG_USERAUTH_FAILURE message before processing the next request.
-
- A request that results in further exchange of messages will be
- aborted by a second request. It is not possible to send a second
- request without waiting for a response from the server, if the first
- request will result in further exchange of messages. No
- SSH_MSG_USERAUTH_FAILURE message will be sent for the aborted method.
-
- SSH_MSG_USERAUTH_SUCCESS MUST be sent only once. When
- SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication
- requests received after that SHOULD be silently ignored.
-
- Any non-authentication messages sent by the client after the request
- that resulted in SSH_MSG_USERAUTH_SUCCESS being sent MUST be passed
- to the service being run on top of this protocol. Such messages can
- be identified by their message numbers (see Section Message Numbers
- (Section 3.2)).
-
-3.1.3 The "none" Authentication Request
-
- A client may request a list of authentication methods that may
- continue by using the "none" authentication method.
-
- If no authentication at all is needed for the user, the server MUST
- return SSH_MSG_USERAUTH_SUCCESS. Otherwise, the server MUST return
- SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of
- authentication methods that can continue.
-
- This method MUST NOT be listed as supported by the server.
-
-3.1.4 Completion of User Authentication
-
- Authentication is complete when the server has responded with
- SSH_MSG_USERAUTH_SUCCESS; all authentication related messages
- received after sending this message SHOULD be silently ignored.
-
- After sending SSH_MSG_USERAUTH_SUCCESS, the server starts the
- requested service.
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 6]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-3.1.5 Banner Message
-
- In some jurisdictions, sending a warning message before
- authentication may be relevant for getting legal protection. Many
- UNIX machines, for example, normally display text from `/etc/issue',
- or use "tcp wrappers" or similar software to display a banner before
- issuing a login prompt.
-
- The SSH server may send a SSH_MSG_USERAUTH_BANNER message at any time
- before authentication is successful. This message contains text to
- be displayed to the client user before authentication is attempted.
- The format is as follows:
-
- byte SSH_MSG_USERAUTH_BANNER
- string message (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- The client SHOULD by default display the message on the screen.
- However, since the message is likely to be sent for every login
- attempt, and since some client software will need to open a separate
- window for this warning, the client software may allow the user to
- explicitly disable the display of banners from the server. The
- message may consist of multiple lines.
-
- If the message string is displayed, control character filtering
- discussed in [SSH-ARCH] SHOULD be used to avoid attacks by sending
- terminal control characters.
-
-3.2 Authentication Protocol Message Numbers
-
- All message numbers used by this authentication protocol are in the
- range from 50 to 79, which is part of the range reserved for
- protocols running on top of the SSH transport layer protocol.
-
- Message numbers of 80 and higher are reserved for protocols running
- after this authentication protocol, so receiving one of them before
- authentication is complete is an error, to which the server MUST
- respond by disconnecting (preferably with a proper disconnect message
- sent first to ease troubleshooting).
-
- After successful authentication, such messages are passed to the
- higher-level service.
-
- These are the general authentication message codes:
-
- #define SSH_MSG_USERAUTH_REQUEST 50
- #define SSH_MSG_USERAUTH_FAILURE 51
- #define SSH_MSG_USERAUTH_SUCCESS 52
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 7]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- #define SSH_MSG_USERAUTH_BANNER 53
-
- In addition to the above, there is a range of message numbers
- (60..79) reserved for method-specific messages. These messages are
- only sent by the server (client sends only SSH_MSG_USERAUTH_REQUEST
- messages). Different authentication methods reuse the same message
- numbers.
-
-3.3 Public Key Authentication Method: publickey
-
- The only REQUIRED authentication method is public key authentication.
- All implementations MUST support this method; however, not all users
- need to have public keys, and most local policies are not likely to
- require public key authentication for all users in the near future.
-
- With this method, the possession of a private key serves as
- authentication. This method works by sending a signature created
- with a private key of the user. The server MUST check that the key
- is a valid authenticator for the user, and MUST check that the
- signature is valid. If both hold, the authentication request MUST be
- accepted; otherwise it MUST be rejected. (Note that the server MAY
- require additional authentications after successful authentication.)
-
- Private keys are often stored in an encrypted form at the client
- host, and the user must supply a passphrase before the signature can
- be generated. Even if they are not, the signing operation involves
- some expensive computation. To avoid unnecessary processing and user
- interaction, the following message is provided for querying whether
- authentication using the key would be acceptable.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean FALSE
- string public key algorithm name
- string public key blob
-
- Public key algorithms are defined in the transport layer
- specification [SSH-TRANS]. The public key blob may contain
- certificates.
-
- Any public key algorithm may be offered for use in authentication.
- In particular, the list is not constrained by what was negotiated
- during key exchange. If the server does not support some algorithm,
- it MUST simply reject the request.
-
- The server MUST respond to this message with either
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 8]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- SSH_MSG_USERAUTH_FAILURE or with the following:
-
- byte SSH_MSG_USERAUTH_PK_OK
- string public key algorithm name from the request
- string public key blob from the request
-
- To perform actual authentication, the client MAY then send a
- signature generated using the private key. The client MAY send the
- signature directly without first verifying whether the key is
- acceptable. The signature is sent using the following packet:
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean TRUE
- string public key algorithm name
- string public key to be used for authentication
- string signature
-
- Signature is a signature by the corresponding private key over the
- following data, in the following order:
-
- string session identifier
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean TRUE
- string public key algorithm name
- string public key to be used for authentication
-
- When the server receives this message, it MUST check whether the
- supplied key is acceptable for authentication, and if so, it MUST
- check whether the signature is correct.
-
- If both checks succeed, this method is successful. Note that the
- server may require additional authentications. The server MUST
- respond with SSH_MSG_USERAUTH_SUCCESS (if no more authentications are
- needed), or SSH_MSG_USERAUTH_FAILURE (if the request failed, or more
- authentications are needed).
-
- The following method-specific message numbers are used by the
- publickey authentication method.
-
- /* Key-based */
- #define SSH_MSG_USERAUTH_PK_OK 60
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 9]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-3.4 Password Authentication Method: password
-
- Password authentication uses the following packets. Note that a
- server MAY request the user to change the password. All
- implementations SHOULD support password authentication.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "password"
- boolean FALSE
- string plaintext password (ISO-10646 UTF-8)
-
- Note that the password is encoded in ISO-10646 UTF-8. It is up to
- the server how it interprets the password and validates it against
- the password database. However, if the client reads the password in
- some other encoding (e.g., ISO 8859-1 (ISO Latin1)), it MUST convert
- the password to ISO-10646 UTF-8 before transmitting, and the server
- MUST convert the password to the encoding used on that system for
- passwords.
-
- Note that even though the cleartext password is transmitted in the
- packet, the entire packet is encrypted by the transport layer. Both
- the server and the client should check whether the underlying
- transport layer provides confidentiality (i.e., if encryption is
- being used). If no confidentiality is provided (none cipher),
- password authentication SHOULD be disabled. If there is no
- confidentiality or no MAC, password change SHOULD be disabled.
-
- Normally, the server responds to this message with success or
- failure. However, if the password has expired the server SHOULD
- indicate this by responding with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.
- In anycase the server MUST NOT allow an expired password to be used
- for authentication.
-
- byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
- string prompt (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- In this case, the client MAY continue with a different authentication
- method, or request a new password from the user and retry password
- authentication using the following message. The client MAY also send
- this message instead of the normal password authentication request
- without the server asking for it.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 10]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- string "password"
- boolean TRUE
- string plaintext old password (ISO-10646 UTF-8)
- string plaintext new password (ISO-10646 UTF-8)
-
- The server must reply to request message with
- SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another
- SSH_MSG_USERAUTH_PASSWD_CHANGEREQ. The meaning of these is as
- follows:
-
- SSH_MSG_USERAUTH_SUCCESS The password has been changed, and
- authentication has been successfully completed.
-
- SSH_MSG_USERAUTH_FAILURE with partial success The password has
- been changed, but more authentications are needed.
-
- SSH_MSG_USERAUTH_FAILURE without partial success The password has
- not been changed. Either password changing was not supported, or
- the old password was bad. Note that if the server has already
- sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, we know that it supports
- changing the password.
-
- SSH_MSG_USERAUTH_CHANGEREQ The password was not changed because
- the new password was not acceptable (e.g. too easy to guess).
-
- The following method-specific message numbers are used by the
- password authentication method.
-
- #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60
-
-
-3.5 Host-Based Authentication: hostbased
-
- Some sites wish to allow authentication based on the host where the
- user is coming from, and the user name on the remote host. While
- this form of authentication is not suitable for high-security sites,
- it can be very convenient in many environments. This form of
- authentication is OPTIONAL. When used, special care SHOULD be taken
- to prevent a regular user from obtaining the private host key.
-
- The client requests this form of authentication by sending the
- following message. It is similar to the UNIX "rhosts" and
- "hosts.equiv" styles of authentication, except that the identity of
- the client host is checked more rigorously.
-
- This method works by having the client send a signature created with
- the private key of the client host, which the server checks with that
- host's public key. Once the client host's identity is established,
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 11]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authorization (but no further authentication) is performed based on
- the user names on the server and the client, and the client host
- name.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "hostbased"
- string public key algorithm for host key
- string public host key and certificates for client host
- string client host name (FQDN; US-ASCII)
- string user name on the client host (ISO-10646 UTF-8)
- string signature
-
- Public key algorithm names for use in "public key algorithm for host
- key" are defined in the transport layer specification. The "public
- host key for client host" may include certificates.
-
- Signature is a signature with the private host key of the following
- data, in this order:
-
- string session identifier
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "hostbased"
- string public key algorithm for host key
- string public host key and certificates for client host
- string client host name (FQDN; US-ASCII)
- string user name on the client host(ISO-10646 UTF-8)
-
- The server MUST verify that the host key actually belongs to the
- client host named in the message, that the given user on that host is
- allowed to log in, and that the signature is a valid signature on the
- appropriate value by the given host key. The server MAY ignore the
- client user name, if it wants to authenticate only the client host.
-
- It is RECOMMENDED that whenever possible, the server perform
- additional checks to verify that the network address obtained from
- the (untrusted) network matches the given client host name. This
- makes exploiting compromised host keys more difficult. Note that
- this may require special handling for connections coming through a
- firewall.
-
-4. Security Considerations
-
- The purpose of this protocol is to perform client user
- authentication. It assumed that this runs over a secure transport
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 12]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- layer protocol, which has already authenticated the server machine,
- established an encrypted communications channel, and computed a
- unique session identifier for this session. The transport layer
- provides forward secrecy for password authentication and other
- methods that rely on secret data.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-Normative
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 13]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park 95025
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 14]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 15]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 16] \ No newline at end of file
diff --git a/lib/ssh/examples/Makefile b/lib/ssh/examples/Makefile
index 9280c42076..d7d47eb3ae 100644
--- a/lib/ssh/examples/Makefile
+++ b/lib/ssh/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/ssh/examples/ssh_device.erl b/lib/ssh/examples/ssh_device.erl
index f6be812915..17e3721541 100644
--- a/lib/ssh/examples/ssh_device.erl
+++ b/lib/ssh/examples/ssh_device.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/examples/ssh_sample_cli.erl b/lib/ssh/examples/ssh_sample_cli.erl
index 6f3092e567..2d8aa428ec 100644
--- a/lib/ssh/examples/ssh_sample_cli.erl
+++ b/lib/ssh/examples/ssh_sample_cli.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 90d71107ad..b44c8eef35 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -66,7 +67,6 @@ MODULES= \
ssh_file \
ssh_io \
ssh_info \
- ssh_math \
ssh_message \
ssh_no_io \
ssh_sftp \
@@ -75,7 +75,7 @@ MODULES= \
ssh_transport \
ssh_xfer
-PUBLIC_HRL_FILES= ssh.hrl ssh_userauth.hrl ssh_xfer.hrl
+HRL_FILES =
ERL_FILES= \
$(MODULES:%=%.erl) \
@@ -95,7 +95,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
+INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl ssh.hrl ssh_userauth.hrl ssh_xfer.hrl
# ----------------------------------------------------
# FLAGS
@@ -140,7 +140,82 @@ release_spec: opt
$(INSTALL_DATA) $(BEHAVIOUR_TARGET_FILES) $(TARGET_FILES) $(APP_TARGET) \
$(APPUP_TARGET) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/include"
- $(INSTALL_DATA) $(PUBLIC_HRL_FILES) "$(RELSYSDIR)/include"
+
release_docs_spec:
+
+deps:
+ erlc -M $(ERL_FILES) \
+ | sed 's@$(ERL_TOP)/lib@../..@g' \
+ | sed 's/\.$(EMULATOR)/\.$$\(EMULATOR\)/' \
+ | sed 's@^ssh_@$$(EBIN)/ssh_@'
+
+ssh.$(EMULATOR): ssh.erl ssh.hrl ssh_connect.hrl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ../../kernel/include/file.hrl
+$(EBIN)/ssh_sup.$(EMULATOR): ssh_sup.erl
+sshc_sup.$(EMULATOR): sshc_sup.erl
+sshd_sup.$(EMULATOR): sshd_sup.erl ssh.hrl
+$(EBIN)/ssh_connection_sup.$(EMULATOR): ssh_connection_sup.erl
+$(EBIN)/ssh_connection.$(EMULATOR): ssh_connection.erl ssh.hrl ssh_connect.hrl \
+ ssh_transport.hrl
+$(EBIN)/ssh_connection_handler.$(EMULATOR): ssh_connection_handler.erl ssh.hrl \
+ ssh_transport.hrl ssh_auth.hrl ssh_connect.hrl
+$(EBIN)/ssh_shell.$(EMULATOR): ssh_shell.erl ssh_connect.hrl
+$(EBIN)/ssh_system_sup.$(EMULATOR): ssh_system_sup.erl ssh.hrl
+$(EBIN)/ssh_subsystem_sup.$(EMULATOR): ssh_subsystem_sup.erl
+$(EBIN)/ssh_channel_sup.$(EMULATOR): ssh_channel_sup.erl
+$(EBIN)/ssh_acceptor_sup.$(EMULATOR): ssh_acceptor_sup.erl ssh.hrl
+$(EBIN)/ssh_acceptor.$(EMULATOR): ssh_acceptor.erl ssh.hrl
+$(EBIN)/ssh_app.$(EMULATOR): ssh_app.erl
+$(EBIN)/ssh_auth.$(EMULATOR): ssh_auth.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl ssh_auth.hrl ssh_transport.hrl
+$(EBIN)/ssh_bits.$(EMULATOR): ssh_bits.erl ssh.hrl
+$(EBIN)/ssh_cli.$(EMULATOR): ssh_cli.erl ssh.hrl ssh_connect.hrl
+$(EBIN)/ssh_file.$(EMULATOR): ssh_file.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ../../kernel/include/file.hrl ssh.hrl
+$(EBIN)/ssh_io.$(EMULATOR): ssh_io.erl ssh.hrl
+$(EBIN)/ssh_info.$(EMULATOR): ssh_info.erl
+$(EBIN)/ssh_message.$(EMULATOR): ssh_message.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl ssh_connect.hrl ssh_auth.hrl ssh_transport.hrl
+$(EBIN)/ssh_no_io.$(EMULATOR): ssh_no_io.erl ssh_transport.hrl
+$(EBIN)/ssh_sftp.$(EMULATOR): ssh_sftp.erl \
+ ../../kernel/include/file.hrl ssh.hrl \
+ ssh_xfer.hrl
+$(EBIN)/ssh_sftpd.$(EMULATOR): ssh_sftpd.erl \
+ ../../kernel/include/file.hrl ssh.hrl \
+ ssh_xfer.hrl
+$(EBIN)/ssh_sftpd_file.$(EMULATOR): ssh_sftpd_file.erl
+$(EBIN)/ssh_transport.$(EMULATOR): ssh_transport.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ../../kernel/include/inet.hrl \
+ ssh_transport.hrl ssh.hrl
+$(EBIN)/ssh_xfer.$(EMULATOR): ssh_xfer.erl ssh.hrl ssh_xfer.hrl
+$(EBIN)/ssh_sftpd_file_api.$(EMULATOR): ssh_sftpd_file_api.erl
+$(EBIN)/ssh_channel.$(EMULATOR): ssh_channel.erl ssh_connect.hrl
+$(EBIN)/ssh_daemon_channel.$(EMULATOR): ssh_daemon_channel.erl
+$(EBIN)/ssh_client_key_api.$(EMULATOR): ssh_client_key_api.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl
+$(EBIN)/ssh_server_key_api.$(EMULATOR): ssh_server_key_api.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl
+
diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src
index bc01c539e0..4a76fd9cd3 100644
--- a/lib/ssh/src/ssh.app.src
+++ b/lib/ssh/src/ssh.app.src
@@ -24,7 +24,6 @@
ssh_file,
ssh_io,
ssh_info,
- ssh_math,
ssh_no_io,
ssh_server_key_api,
ssh_sftp,
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index e76c110c04..e38cecf226 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 7ed17618e7..54f94acbdc 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,12 +25,16 @@
-include("ssh.hrl").
-include("ssh_connect.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include_lib("kernel/include/file.hrl").
-export([start/0, start/1, stop/0, connect/3, connect/4, close/1, connection_info/2,
channel_info/3,
daemon/1, daemon/2, daemon/3,
- stop_listener/1, stop_listener/2, stop_daemon/1, stop_daemon/2,
- shell/1, shell/2, shell/3]).
+ default_algorithms/0,
+ stop_listener/1, stop_listener/2, stop_listener/3,
+ stop_daemon/1, stop_daemon/2, stop_daemon/3,
+ shell/1, shell/2, shell/3
+ ]).
%%--------------------------------------------------------------------
-spec start() -> ok | {error, term()}.
@@ -113,9 +118,9 @@ channel_info(ConnectionRef, ChannelId, Options) ->
ssh_connection_handler:channel_info(ConnectionRef, ChannelId, Options).
%%--------------------------------------------------------------------
--spec daemon(integer()) -> {ok, pid()}.
--spec daemon(integer(), proplists:proplist()) -> {ok, pid()}.
--spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()}.
+-spec daemon(integer()) -> {ok, pid()} | {error, term()}.
+-spec daemon(integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
+-spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
%% Description: Starts a server listening for SSH connections
%% on the given port.
@@ -157,7 +162,9 @@ daemon(HostAddr, Port, Options0) ->
stop_listener(SysSup) ->
ssh_system_sup:stop_listener(SysSup).
stop_listener(Address, Port) ->
- ssh_system_sup:stop_listener(Address, Port).
+ stop_listener(Address, Port, ?DEFAULT_PROFILE).
+stop_listener(Address, Port, Profile) ->
+ ssh_system_sup:stop_listener(Address, Port, Profile).
%%--------------------------------------------------------------------
-spec stop_daemon(pid()) -> ok.
@@ -169,8 +176,9 @@ stop_listener(Address, Port) ->
stop_daemon(SysSup) ->
ssh_system_sup:stop_system(SysSup).
stop_daemon(Address, Port) ->
- ssh_system_sup:stop_system(Address, Port).
-
+ ssh_system_sup:stop_system(Address, Port, ?DEFAULT_PROFILE).
+stop_daemon(Address, Port, Profile) ->
+ ssh_system_sup:stop_system(Address, Port, Profile).
%%--------------------------------------------------------------------
-spec shell(string()) -> _.
-spec shell(string(), proplists:proplist()) -> _.
@@ -208,6 +216,11 @@ shell(Host, Port, Options) ->
end.
%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+default_algorithms() ->
+ ssh_transport:default_algorithms().
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
fix_idle_time(SshOptions) ->
@@ -222,11 +235,29 @@ start_daemon(Host, Port, Options, Inet) ->
{error, _Reason} = Error ->
Error;
{SocketOptions, SshOptions}->
- do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions])
+ try
+ do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions])
+ catch
+ throw:bad_fd -> {error,bad_fd};
+ _C:_E -> {error,{cannot_start_daemon,_C,_E}}
+ end
end.
-do_start_daemon(Host, Port, Options, SocketOptions) ->
- case ssh_system_sup:system_supervisor(Host, Port) of
+do_start_daemon(Host0, Port0, Options, SocketOptions) ->
+ {Host,Port} = try
+ case proplists:get_value(fd, SocketOptions) of
+ undefined ->
+ {Host0,Port0};
+ Fd when Port0==0 ->
+ find_hostport(Fd);
+ _ ->
+ {Host0,Port0}
+ end
+ catch
+ _:_ -> throw(bad_fd)
+ end,
+ Profile = proplists:get_value(profile, Options, ?DEFAULT_PROFILE),
+ case ssh_system_sup:system_supervisor(Host, Port, Profile) of
undefined ->
%% It would proably make more sense to call the
%% address option host but that is a too big change at the
@@ -258,8 +289,17 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
end
end.
+find_hostport(Fd) ->
+ %% Using internal functions inet:open/8 and inet:close/0.
+ %% Don't try this at home unless you know what you are doing!
+ {ok,S} = inet:open(Fd, {0,0,0,0}, 0, [], tcp, inet, stream, inet_tcp),
+ {ok, HostPort} = inet:sockname(S),
+ ok = inet:close(S),
+ HostPort.
+
+
handle_options(Opts) ->
- try handle_option(proplists:unfold(Opts), [], []) of
+ try handle_option(algs_compatibility(proplists:unfold(Opts)), [], []) of
{Inet, Ssh} ->
{handle_ip(Inet), Ssh}
catch
@@ -267,6 +307,30 @@ handle_options(Opts) ->
Error
end.
+
+algs_compatibility(Os0) ->
+ %% Take care of old options 'public_key_alg' and 'pref_public_key_algs'
+ case proplists:get_value(public_key_alg, Os0) of
+ undefined ->
+ Os0;
+ A when is_atom(A) ->
+ %% Skip public_key_alg if pref_public_key_algs is defined:
+ Os = lists:keydelete(public_key_alg, 1, Os0),
+ case proplists:get_value(pref_public_key_algs,Os) of
+ undefined when A == 'ssh-rsa' ; A==ssh_rsa ->
+ [{pref_public_key_algs,['ssh-rsa','ssh-dss']} | Os];
+ undefined when A == 'ssh-dss' ; A==ssh_dsa ->
+ [{pref_public_key_algs,['ssh-dss','ssh-rsa']} | Os];
+ undefined ->
+ throw({error, {eoptions, {public_key_alg,A} }});
+ _ ->
+ Os
+ end;
+ V ->
+ throw({error, {eoptions, {public_key_alg,V} }})
+ end.
+
+
handle_option([], SocketOptions, SshOptions) ->
{SocketOptions, SshOptions};
handle_option([{system_dir, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -279,8 +343,6 @@ handle_option([{silently_accept_hosts, _} = Opt | Rest], SocketOptions, SshOptio
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{user_interaction, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{public_key_alg, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{connect_timeout, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{user, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -295,11 +357,13 @@ handle_option([{user_passwords, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{pwdfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{key_cb, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{role, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{compression, _} = Opt | Rest], SocketOptions, SshOptions) ->
+handle_option([{key_cb, {Module, Options}} | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option({key_cb, Module}),
+ handle_ssh_priv_option({key_cb_private, Options}) |
+ SshOptions]);
+handle_option([{key_cb, Module} | Rest], SocketOptions, SshOptions) ->
+ handle_option([{key_cb, {Module, []}} | Rest], SocketOptions, SshOptions);
+handle_option([{keyboard_interact_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
%%Backwards compatibility
handle_option([{allow_user_interaction, Value} | Rest], SocketOptions, SshOptions) ->
@@ -310,6 +374,8 @@ handle_option([{connectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{disconnectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{unexpectedfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{failfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{ssh_msg_debug_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -335,6 +401,12 @@ handle_option([{auth_method_kb_interactive_data, _} = Opt | Rest], SocketOptions
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{pref_public_key_algs, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{preferred_algorithms,_} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{dh_gex_groups,_} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{dh_gex_limits,_} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{quiet_mode, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{idle_time, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -343,16 +415,23 @@ handle_option([{rekey_limit, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{max_sessions, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{max_channels, _} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{negotiation_timeout, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{parallel_login, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
+%% (Is handled by proplists:unfold above:)
+%% handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
+%% handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
handle_option([{minimal_remote_max_packet_size, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{id_string, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{profile, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{max_random_length_padding, _Bool} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions).
@@ -360,25 +439,83 @@ handle_option([Opt | Rest], SocketOptions, SshOptions) ->
handle_ssh_option({minimal_remote_max_packet_size, Value} = Opt) when is_integer(Value), Value >=0 ->
Opt;
handle_ssh_option({system_dir, Value} = Opt) when is_list(Value) ->
- Opt;
+ check_dir(Opt);
handle_ssh_option({user_dir, Value} = Opt) when is_list(Value) ->
- Opt;
+ check_dir(Opt);
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({user_interaction, Value} = Opt) when is_boolean(Value) ->
Opt;
-handle_ssh_option({public_key_alg, ssh_dsa}) ->
- {public_key_alg, 'ssh-dss'};
-handle_ssh_option({public_key_alg, ssh_rsa}) ->
- {public_key_alg, 'ssh-rsa'};
-handle_ssh_option({public_key_alg, Value} = Opt) when Value == 'ssh-rsa'; Value == 'ssh-dss' ->
+handle_ssh_option({preferred_algorithms,[_|_]} = Opt) ->
+ handle_pref_algs(Opt);
+
+handle_ssh_option({dh_gex_groups,L0}) when is_list(L0) ->
+ {dh_gex_groups,
+ collect_per_size(
+ lists:foldl(
+ fun({N,G,P}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,{G,P}}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,GPs}, Acc) when is_list(GPs) ->
+ lists:foldr(fun({Gi,Pi}, Acci) when is_integer(Gi),Gi>0,
+ is_integer(Pi),Pi>0 ->
+ [{N,{Gi,Pi}} | Acci]
+ end, Acc, GPs)
+ end, [], L0))};
+
+handle_ssh_option({dh_gex_groups,{Tag,File=[C|_]}}=Opt) when is_integer(C), C>0,
+ Tag == file ;
+ Tag == ssh_moduli_file ->
+ {ok,GroupDefs} =
+ case Tag of
+ file ->
+ file:consult(File);
+ ssh_moduli_file ->
+ case file:open(File,[read]) of
+ {ok,D} ->
+ try
+ {ok,Moduli} = read_moduli_file(D, 1, []),
+ file:close(D),
+ {ok, Moduli}
+ catch
+ _:_ ->
+ throw({error, {{eoptions, Opt}, "Bad format in file "++File}})
+ end;
+ {error,enoent} ->
+ throw({error, {{eoptions, Opt}, "File not found:"++File}});
+ {error,Error} ->
+ throw({error, {{eoptions, Opt}, io_lib:format("Error reading file ~s: ~p",[File,Error])}})
+ end
+ end,
+
+ try
+ handle_ssh_option({dh_gex_groups,GroupDefs})
+ catch
+ _:_ ->
+ throw({error, {{eoptions, Opt}, "Bad format in file: "++File}})
+ end;
+
+
+handle_ssh_option({dh_gex_limits,{Min,Max}} = Opt) when is_integer(Min), Min>0,
+ is_integer(Max), Max>=Min ->
+ %% Server
+ Opt;
+handle_ssh_option({dh_gex_limits,{Min,I,Max}} = Opt) when is_integer(Min), Min>0,
+ is_integer(I), I>=Min,
+ is_integer(Max), Max>=I ->
+ %% Client
Opt;
handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), length(Value) >= 1 ->
- case handle_pref_algs(Value, []) of
+ case handle_user_pref_pubkey_algs(Value, []) of
{true, NewOpts} ->
- NewOpts;
+ {pref_public_key_algs, NewOpts};
_ ->
throw({error, {eoptions, Opt}})
end;
@@ -386,6 +523,8 @@ handle_ssh_option({connect_timeout, Value} = Opt) when is_integer(Value); Value
Opt;
handle_ssh_option({max_sessions, Value} = Opt) when is_integer(Value), Value>0 ->
Opt;
+handle_ssh_option({max_channels, Value} = Opt) when is_integer(Value), Value>0 ->
+ Opt;
handle_ssh_option({negotiation_timeout, Value} = Opt) when is_integer(Value); Value == infinity ->
Opt;
handle_ssh_option({parallel_login, Value} = Opt) when Value==true ; Value==false ->
@@ -400,10 +539,17 @@ handle_ssh_option({password, Value} = Opt) when is_list(Value) ->
Opt;
handle_ssh_option({user_passwords, Value} = Opt) when is_list(Value)->
Opt;
-handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value) ->
+handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,2) ->
+ Opt;
+handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,4) ->
Opt;
handle_ssh_option({key_cb, Value} = Opt) when is_atom(Value) ->
Opt;
+handle_ssh_option({key_cb, {CallbackMod, CallbackOptions}} = Opt) when is_atom(CallbackMod),
+ is_list(CallbackOptions) ->
+ Opt;
+handle_ssh_option({keyboard_interact_fun, Value} = Opt) when is_function(Value,3) ->
+ Opt;
handle_ssh_option({compression, Value} = Opt) when is_atom(Value) ->
Opt;
handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module),
@@ -424,7 +570,9 @@ handle_ssh_option({infofun, Value} = Opt) when is_function(Value) ->
Opt;
handle_ssh_option({connectfun, Value} = Opt) when is_function(Value) ->
Opt;
-handle_ssh_option({disconnectfun , Value} = Opt) when is_function(Value) ->
+handle_ssh_option({disconnectfun, Value} = Opt) when is_function(Value) ->
+ Opt;
+handle_ssh_option({unexpectedfun, Value} = Opt) when is_function(Value,2) ->
Opt;
handle_ssh_option({failfun, Value} = Opt) when is_function(Value) ->
Opt;
@@ -458,9 +606,17 @@ handle_ssh_option({id_string, random}) ->
{id_string, {random,2,5}}; %% 2 - 5 random characters
handle_ssh_option({id_string, ID} = Opt) when is_list(ID) ->
Opt;
+handle_ssh_option({max_random_length_padding, Value} = Opt) when is_integer(Value),
+ Value =< 255 ->
+ Opt;
+handle_ssh_option({profile, Value} = Opt) when is_atom(Value) ->
+ Opt;
handle_ssh_option(Opt) ->
throw({error, {eoptions, Opt}}).
+handle_ssh_priv_option({key_cb_private, Value} = Opt) when is_list(Value) ->
+ Opt.
+
handle_inet_option({active, _} = Opt) ->
throw({error, {{eoptions, Opt}, "SSH has built in flow control, "
"and active is handled internally, user is not allowed"
@@ -474,23 +630,83 @@ handle_inet_option({reuseaddr, _} = Opt) ->
%% Option verified by inet
handle_inet_option(Opt) ->
Opt.
+
+
%% Check preferred algs
-handle_pref_algs([], Acc) ->
- {true, lists:reverse(Acc)};
-handle_pref_algs([H|T], Acc) ->
- case H of
- ssh_dsa ->
- handle_pref_algs(T, ['ssh-dss'| Acc]);
- ssh_rsa ->
- handle_pref_algs(T, ['ssh-rsa'| Acc]);
- 'ssh-dss' ->
- handle_pref_algs(T, ['ssh-dss'| Acc]);
- 'ssh-rsa' ->
- handle_pref_algs(T, ['ssh-rsa'| Acc]);
- _ ->
- false
+
+handle_pref_algs({preferred_algorithms,Algs}) ->
+ try alg_duplicates(Algs, [], []) of
+ [] ->
+ {preferred_algorithms,
+ [try ssh_transport:supported_algorithms(Key)
+ of
+ DefAlgs -> handle_pref_alg(Key,Vals,DefAlgs)
+ catch
+ _:_ -> throw({error, {{eoptions, {preferred_algorithms,Key}},
+ "Bad preferred_algorithms key"}})
+ end || {Key,Vals} <- Algs]
+ };
+
+ Dups ->
+ throw({error, {{eoptions, {preferred_algorithms,Dups}}, "Duplicates found"}})
+ catch
+ _:_ ->
+ throw({error, {{eoptions, preferred_algorithms}, "Malformed"}})
end.
+alg_duplicates([{K,V}|KVs], Ks, Dups0) ->
+ Dups =
+ case lists:member(K,Ks) of
+ true ->
+ [K|Dups0];
+ false ->
+ Dups0
+ end,
+ case V--lists:usort(V) of
+ [] ->
+ alg_duplicates(KVs, [K|Ks], Dups);
+ Ds ->
+ alg_duplicates(KVs, [K|Ks], Dups++Ds)
+ end;
+alg_duplicates([], _Ks, Dups) ->
+ Dups.
+
+handle_pref_alg(Key,
+ Vs=[{client2server,C2Ss=[_|_]},{server2client,S2Cs=[_|_]}],
+ [{client2server,Sup_C2Ss},{server2client,Sup_S2Cs}]
+ ) ->
+ chk_alg_vs(Key, C2Ss, Sup_C2Ss),
+ chk_alg_vs(Key, S2Cs, Sup_S2Cs),
+ {Key, Vs};
+
+handle_pref_alg(Key,
+ Vs=[{server2client,[_|_]},{client2server,[_|_]}],
+ Sup=[{client2server,_},{server2client,_}]
+ ) ->
+ handle_pref_alg(Key, lists:reverse(Vs), Sup);
+
+handle_pref_alg(Key,
+ Vs=[V|_],
+ Sup=[{client2server,_},{server2client,_}]
+ ) when is_atom(V) ->
+ handle_pref_alg(Key, [{client2server,Vs},{server2client,Vs}], Sup);
+
+handle_pref_alg(Key,
+ Vs=[V|_],
+ Sup=[S|_]
+ ) when is_atom(V), is_atom(S) ->
+ chk_alg_vs(Key, Vs, Sup),
+ {Key, Vs};
+
+handle_pref_alg(Key, Vs, _) ->
+ throw({error, {{eoptions, {preferred_algorithms,[{Key,Vs}]}}, "Badly formed list"}}).
+
+chk_alg_vs(OptKey, Values, SupportedValues) ->
+ case (Values -- SupportedValues) of
+ [] -> Values;
+ Bad -> throw({error, {{eoptions, {OptKey,Bad}}, "Unsupported value(s) found"}})
+ end.
+
handle_ip(Inet) -> %% Default to ipv4
case lists:member(inet, Inet) of
true ->
@@ -503,4 +719,74 @@ handle_ip(Inet) -> %% Default to ipv4
[inet | Inet]
end
end.
-
+
+check_dir({_,Dir} = Opt) ->
+ case directory_exist_readable(Dir) of
+ ok ->
+ Opt;
+ {error,Error} ->
+ throw({error, {eoptions,{Opt,Error}}})
+ end.
+
+directory_exist_readable(Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, #file_info{type = directory,
+ access = Access}} ->
+ case Access of
+ read -> ok;
+ read_write -> ok;
+ _ -> {error, eacces}
+ end;
+
+ {ok, #file_info{}}->
+ {error, enotdir};
+
+ {error, Error} ->
+ {error, Error}
+ end.
+
+
+
+collect_per_size(L) ->
+ lists:foldr(
+ fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
+ ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
+ end, [], lists:sort(L)).
+
+read_moduli_file(D, I, Acc) ->
+ case io:get_line(D,"") of
+ {error,Error} ->
+ {error,Error};
+ eof ->
+ {ok, Acc};
+ "#" ++ _ -> read_moduli_file(D, I+1, Acc);
+ <<"#",_/binary>> -> read_moduli_file(D, I+1, Acc);
+ Data ->
+ Line = if is_binary(Data) -> binary_to_list(Data);
+ is_list(Data) -> Data
+ end,
+ try
+ [_Time,_Type,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
+ M = {list_to_integer(Size),
+ {list_to_integer(G), list_to_integer(P,16)}
+ },
+ read_moduli_file(D, I+1, [M|Acc])
+ catch
+ _:_ ->
+ read_moduli_file(D, I+1, Acc)
+ end
+ end.
+
+handle_user_pref_pubkey_algs([], Acc) ->
+ {true, lists:reverse(Acc)};
+handle_user_pref_pubkey_algs([H|T], Acc) ->
+ case lists:member(H, ?SUPPORTED_USER_KEYS) of
+ true ->
+ handle_user_pref_pubkey_algs(T, [H| Acc]);
+
+ false when H==ssh_dsa -> handle_user_pref_pubkey_algs(T, ['ssh-dss'| Acc]);
+ false when H==ssh_rsa -> handle_user_pref_pubkey_algs(T, ['ssh-rsa'| Acc]);
+
+ false ->
+ false
+ end.
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 0c4d34f89c..f88098819d 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,20 +29,26 @@
-define(SSH_DEFAULT_PORT, 22).
-define(SSH_MAX_PACKET_SIZE, (256*1024)).
--define(SSH_LENGHT_INDICATOR_SIZE, 4).
-define(REKEY_TIMOUT, 3600000).
-define(REKEY_DATA_TIMOUT, 60000).
+-define(DEFAULT_PROFILE, default).
+
+-define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
+-define(SUPPORTED_USER_KEYS, ['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521']).
-define(FALSE, 0).
-define(TRUE, 1).
%% basic binary constructors
--define(BOOLEAN(X), X:8/unsigned-big-integer).
--define(BYTE(X), X:8/unsigned-big-integer).
--define(UINT16(X), X:16/unsigned-big-integer).
--define(UINT32(X), X:32/unsigned-big-integer).
--define(UINT64(X), X:64/unsigned-big-integer).
+-define(BOOLEAN(X), (X):8/unsigned-big-integer).
+-define(BYTE(X), (X):8/unsigned-big-integer).
+-define(UINT16(X), (X):16/unsigned-big-integer).
+-define(UINT32(X), (X):32/unsigned-big-integer).
+-define(UINT64(X), (X):64/unsigned-big-integer).
-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+-define(DEC_BIN(X,Len), ?UINT32(Len), X:Len/binary ).
+-define(DEC_MPINT(I,Len), ?UINT32(Len), I:Len/big-signed-integer-unit:8 ).
+
%% building macros
-define(boolean(X),
case X of
@@ -122,15 +129,18 @@
recv_sequence = 0,
keyex_key,
keyex_info,
+ random_length_padding = 255, % From RFC 4253 section 6.
%% User auth
user,
service,
userauth_quiet_mode, % boolean()
- userauth_supported_methods , %
- userauth_methods,
+ userauth_supported_methods, % string() eg "keyboard-interactive,password"
+ userauth_methods, % list( string() ) eg ["keyboard-interactive", "password"]
+ kb_tries_left = 0, % integer(), num tries left for "keyboard-interactive"
userauth_preference,
available_host_keys,
+ pwdfun_user_state,
authenticated = false
}).
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 34988f17b6..d94dedf1bf 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,6 +22,8 @@
-module(ssh_acceptor).
+-include("ssh.hrl").
+
%% Internal application API
-export([start_link/5,
number_of_connections/1]).
@@ -53,7 +56,12 @@ acceptor_init(Parent, Port, Address, SockOpts, Opts, AcceptTimeout) ->
error
end.
-do_socket_listen(Callback, Port, Opts) ->
+do_socket_listen(Callback, Port0, Opts) ->
+ Port =
+ case proplists:get_value(fd, Opts) of
+ undefined -> Port0;
+ _ -> 0
+ end,
case Callback:listen(Port, Opts) of
{error, nxdomain} ->
Callback:listen(Port, lists:delete(inet6, Opts));
@@ -82,8 +90,10 @@ acceptor_loop(Callback, Port, Address, Opts, ListenSocket, AcceptTimeout) ->
end.
handle_connection(Callback, Address, Port, Options, Socket) ->
- SystemSup = ssh_system_sup:system_supervisor(Address, Port),
SSHopts = proplists:get_value(ssh_opts, Options, []),
+ Profile = proplists:get_value(profile, SSHopts, ?DEFAULT_PROFILE),
+ SystemSup = ssh_system_sup:system_supervisor(Address, Port, Profile),
+
MaxSessions = proplists:get_value(max_sessions,SSHopts,infinity),
case number_of_connections(SystemSup) < MaxSessions of
true ->
diff --git a/lib/ssh/src/ssh_acceptor_sup.erl b/lib/ssh/src/ssh_acceptor_sup.erl
index 46fdef07d0..a3dc64850f 100644
--- a/lib/ssh/src/ssh_acceptor_sup.erl
+++ b/lib/ssh/src/ssh_acceptor_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,7 +27,9 @@
-module(ssh_acceptor_sup).
-behaviour(supervisor).
--export([start_link/1, start_child/2, stop_child/3]).
+-include("ssh.hrl").
+
+-export([start_link/1, start_child/2, stop_child/4]).
%% Supervisor callback
-export([init/1]).
@@ -45,14 +48,16 @@ start_child(AccSup, ServerOpts) ->
{error, already_present} ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- stop_child(AccSup, Address, Port),
+ Profile = proplists:get_value(profile,
+ proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ stop_child(AccSup, Address, Port, Profile),
supervisor:start_child(AccSup, Spec);
Reply ->
Reply
end.
-stop_child(AccSup, Address, Port) ->
- Name = id(Address, Port),
+stop_child(AccSup, Address, Port, Profile) ->
+ Name = id(Address, Port, Profile),
case supervisor:terminate_child(AccSup, Name) of
ok ->
supervisor:delete_child(AccSup, Name);
@@ -77,7 +82,8 @@ child_spec(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
Timeout = proplists:get_value(timeout, ServerOpts, ?DEFAULT_TIMEOUT),
- Name = id(Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = id(Address, Port, Profile),
SocketOpts = proplists:get_value(socket_opts, ServerOpts),
StartFunc = {ssh_acceptor, start_link, [Port, Address,
[{active, false},
@@ -89,6 +95,11 @@ child_spec(ServerOpts) ->
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Address, Port) ->
- {ssh_acceptor_sup, Address, Port}.
+id(Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ {ssh_acceptor_sup, any, Port, Profile};
+ false ->
+ {ssh_acceptor_sup, Address, Port, Profile}
+ end.
diff --git a/lib/ssh/src/ssh_app.erl b/lib/ssh/src/ssh_app.erl
index 38659b1a2d..1a11938dd9 100644
--- a/lib/ssh/src/ssh_app.erl
+++ b/lib/ssh/src/ssh_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 9d1ab14ce9..b71bed033a 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,27 +41,29 @@ publickey_msg([Alg, #ssh{user = User,
session_id = SessionId,
service = Service,
opts = Opts} = Ssh]) ->
-
Hash = sha, %% Maybe option?!
KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
-
case KeyCb:user_key(Alg, Opts) of
- {ok, Key} ->
- StrAlgo = algorithm_string(Alg),
- PubKeyBlob = encode_public_key(Key),
- SigData = build_sig_data(SessionId,
- User, Service, PubKeyBlob, StrAlgo),
- Sig = ssh_transport:sign(SigData, Hash, Key),
- SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "publickey",
- data = [?TRUE,
- ?string(StrAlgo),
- ?binary(PubKeyBlob),
- ?binary(SigBlob)]},
- Ssh);
+ {ok, PrivKey} ->
+ StrAlgo = atom_to_list(Alg),
+ case encode_public_key(StrAlgo, ssh_transport:extract_public_key(PrivKey)) of
+ not_ok ->
+ not_ok;
+ PubKeyBlob ->
+ SigData = build_sig_data(SessionId,
+ User, Service, PubKeyBlob, StrAlgo),
+ Sig = ssh_transport:sign(SigData, Hash, PrivKey),
+ SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "publickey",
+ data = [?TRUE,
+ ?string(StrAlgo),
+ ?binary(PubKeyBlob),
+ ?binary(SigBlob)]},
+ Ssh)
+ end;
_Error ->
not_ok
end.
@@ -115,33 +118,21 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
service = "ssh-connection",
method = "none",
data = <<>>},
- case proplists:get_value(pref_public_key_algs, Opts, false) of
- false ->
- FirstAlg = proplists:get_value(public_key_alg, Opts, ?PREFERRED_PK_ALG),
- SecondAlg = other_alg(FirstAlg),
- Prefs = method_preference(FirstAlg, SecondAlg),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"});
- Algs ->
- FirstAlg = lists:nth(1, Algs),
- case length(Algs) =:= 2 of
- true ->
- SecondAlg = other_alg(FirstAlg),
- Prefs = method_preference(FirstAlg, SecondAlg),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"});
- _ ->
- Prefs = method_preference(FirstAlg),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"})
- end
- end;
+ Algs0 = proplists:get_value(pref_public_key_algs, Opts, ?SUPPORTED_USER_KEYS),
+ %% The following line is not strictly correct. The call returns the
+ %% supported HOST key types while we are interested in USER keys. However,
+ %% they "happens" to be the same (for now). This could change....
+ %% There is no danger as long as the set of user keys is a subset of the set
+ %% of host keys.
+ CryptoSupported = ssh_transport:supported_algorithms(public_key),
+ Algs = [A || A <- Algs0,
+ lists:member(A, CryptoSupported)],
+
+ Prefs = method_preference(Algs),
+ ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
+ userauth_preference = Prefs,
+ userauth_methods = none,
+ service = "ssh-connection"});
{error, no_user} ->
ErrStr = "Could not determine the users name",
throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_ILLEGAL_USER_NAME,
@@ -168,7 +159,7 @@ userauth_request_msg(#ssh{userauth_methods = Methods,
not_ok ->
userauth_request_msg(Ssh);
Result ->
- Result
+ {Pref,Result}
end;
false ->
userauth_request_msg(Ssh)
@@ -185,17 +176,18 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "password",
data = <<?FALSE, ?UINT32(Sz), BinPwd:Sz/binary>>}, _,
- #ssh{opts = Opts} = Ssh) ->
+ #ssh{opts = Opts,
+ userauth_supported_methods = Methods} = Ssh) ->
Password = unicode:characters_to_list(BinPwd),
- case check_password(User, Password, Opts) of
- true ->
+ case check_password(User, Password, Opts, Ssh) of
+ {true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
- false ->
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = "",
- partial_success = false}, Ssh)}
+ authentications = Methods,
+ partial_success = false}, Ssh1)}
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -207,7 +199,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
%% ?UINT32(Sz2), NewBinPwd:Sz2/binary
>>
}, _,
- Ssh) ->
+ #ssh{userauth_supported_methods = Methods} = Ssh) ->
%% Password change without us having sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ (because we never do)
%% RFC 4252 says:
%% SSH_MSG_USERAUTH_FAILURE without partial success - The password
@@ -216,7 +208,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
{not_authorized, {User, {error,"Password change not supported"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = "",
+ authentications = Methods,
partial_success = false}, Ssh)};
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -232,7 +224,9 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "publickey",
data = Data},
- SessionId, #ssh{opts = Opts} = Ssh) ->
+ SessionId,
+ #ssh{opts = Opts,
+ userauth_supported_methods = Methods} = Ssh) ->
<<?BYTE(HaveSig), ?UINT32(ALen), BAlg:ALen/binary,
?UINT32(KLen), KeyBlob:KLen/binary, SigWLen/binary>> = Data,
Alg = binary_to_list(BAlg),
@@ -247,7 +241,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
false ->
{not_authorized, {User, undefined},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications="publickey,password",
+ authentications = Methods,
partial_success = false}, Ssh)}
end;
?FALSE ->
@@ -261,49 +255,59 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "keyboard-interactive",
data = _},
- _, #ssh{opts = Opts} = Ssh) ->
- %% RFC4256
- %% The data field contains:
- %% - language tag (deprecated). If =/=[] SHOULD use it however. We skip
- %% it for simplicity.
- %% - submethods. "... the user can give a hint of which actual methods
- %% he wants to use. ...". It's a "MAY use" so we skip
- %% it. It also needs an understanding between the client
- %% and the server.
- %%
- %% "The server MUST reply with an SSH_MSG_USERAUTH_SUCCESS,
- %% SSH_MSG_USERAUTH_FAILURE, or SSH_MSG_USERAUTH_INFO_REQUEST message."
- Default = {"SSH server",
- "Enter password for \""++User++"\"",
- "pwd: ",
- false},
-
- {Name, Instruction, Prompt, Echo} =
- case proplists:get_value(auth_method_kb_interactive_data, Opts) of
- undefined ->
- Default;
- {_,_,_,_}=V ->
- V;
- F when is_function(F) ->
- {_,PeerName} = Ssh#ssh.peer,
- F(PeerName, User, "ssh-connection")
- end,
- EchoEnc = case Echo of
- true -> <<?TRUE>>;
- false -> <<?FALSE>>
- end,
- Msg = #ssh_msg_userauth_info_request{name = unicode:characters_to_list(Name),
- instruction = unicode:characters_to_list(Instruction),
- language_tag = "",
- num_prompts = 1,
- data = <<?STRING(unicode:characters_to_binary(Prompt)),
- EchoEnc/binary
- >>
- },
- {not_authorized, {User, undefined},
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- opts = [{max_kb_tries,3},{kb_userauth_info_msg,Msg}|Opts]
- })};
+ _, #ssh{opts = Opts,
+ kb_tries_left = KbTriesLeft,
+ userauth_supported_methods = Methods} = Ssh) ->
+ case KbTriesLeft of
+ N when N<1 ->
+ {not_authorized, {User, {authmethod, "keyboard-interactive"}},
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh)};
+
+ _ ->
+ %% RFC4256
+ %% The data field contains:
+ %% - language tag (deprecated). If =/=[] SHOULD use it however. We skip
+ %% it for simplicity.
+ %% - submethods. "... the user can give a hint of which actual methods
+ %% he wants to use. ...". It's a "MAY use" so we skip
+ %% it. It also needs an understanding between the client
+ %% and the server.
+ %%
+ %% "The server MUST reply with an SSH_MSG_USERAUTH_SUCCESS,
+ %% SSH_MSG_USERAUTH_FAILURE, or SSH_MSG_USERAUTH_INFO_REQUEST message."
+ Default = {"SSH server",
+ "Enter password for \""++User++"\"",
+ "password: ",
+ false},
+
+ {Name, Instruction, Prompt, Echo} =
+ case proplists:get_value(auth_method_kb_interactive_data, Opts) of
+ undefined ->
+ Default;
+ {_,_,_,_}=V ->
+ V;
+ F when is_function(F) ->
+ {_,PeerName} = Ssh#ssh.peer,
+ F(PeerName, User, "ssh-connection")
+ end,
+ EchoEnc = case Echo of
+ true -> <<?TRUE>>;
+ false -> <<?FALSE>>
+ end,
+ Msg = #ssh_msg_userauth_info_request{name = unicode:characters_to_list(Name),
+ instruction = unicode:characters_to_list(Instruction),
+ language_tag = "",
+ num_prompts = 1,
+ data = <<?STRING(unicode:characters_to_binary(Prompt)),
+ EchoEnc/binary
+ >>
+ },
+ {not_authorized, {User, undefined},
+ ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User
+ })}
+ end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
@@ -314,6 +318,8 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
#ssh_msg_userauth_failure{authentications = Methods,
partial_success = false}, Ssh)}.
+
+
handle_userauth_info_request(
#ssh_msg_userauth_info_request{name = Name,
instruction = Instr,
@@ -330,33 +336,20 @@ handle_userauth_info_request(
handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1,
data = <<?UINT32(Sz), Password:Sz/binary>>},
- #ssh{opts = Opts0,
- user = User} = Ssh) ->
- NumTriesLeft = proplists:get_value(max_kb_tries, Opts0, 0) - 1,
- Opts = lists:keydelete(max_kb_tries,1,Opts0),
- case check_password(User, unicode:characters_to_list(Password), Opts) of
- true ->
+ #ssh{opts = Opts,
+ kb_tries_left = KbTriesLeft,
+ user = User,
+ userauth_supported_methods = Methods} = Ssh) ->
+ case check_password(User, unicode:characters_to_list(Password), Opts, Ssh) of
+ {true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
- false when NumTriesLeft > 0 ->
- UserAuthInfoMsg =
- (proplists:get_value(kb_userauth_info_msg,Opts))
- #ssh_msg_userauth_info_request{name = "",
- instruction =
- lists:concat(
- ["Bad user or password, try again. ",
- integer_to_list(NumTriesLeft),
- " tries left."])},
- {not_authorized, {User, undefined},
- ssh_transport:ssh_packet(UserAuthInfoMsg,
- Ssh#ssh{opts = [{max_kb_tries,NumTriesLeft}|Opts]})};
-
- false ->
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = "",
+ authentications = Methods,
partial_success = false},
- Ssh#ssh{opts = lists:keydelete(kb_userauth_info_msg,1,Opts)}
+ Ssh1#ssh{kb_tries_left = max(KbTriesLeft-1, 0)}
)}
end;
@@ -367,20 +360,23 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{},
"keyboard-interactive",
language = "en"}).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-method_preference(Alg1, Alg2) ->
- [{"publickey", ?MODULE, publickey_msg, [Alg1]},
- {"publickey", ?MODULE, publickey_msg,[Alg2]},
- {"password", ?MODULE, password_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ].
-method_preference(Alg1) ->
- [{"publickey", ?MODULE, publickey_msg, [Alg1]},
- {"password", ?MODULE, password_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ].
+method_preference(Algs) ->
+ lists:foldr(fun(A, Acc) ->
+ [{"publickey", ?MODULE, publickey_msg, [A]} | Acc]
+ end,
+ [{"password", ?MODULE, password_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
+ ],
+ Algs).
user_name(Opts) ->
Env = case os:type() of
@@ -401,13 +397,34 @@ user_name(Opts) ->
{ok, User}
end.
-check_password(User, Password, Opts) ->
+check_password(User, Password, Opts, Ssh) ->
case proplists:get_value(pwdfun, Opts) of
undefined ->
Static = get_password_option(Opts, User),
- Password == Static;
- Cheker ->
- Cheker(User, Password)
+ {Password == Static, Ssh};
+
+ Checker when is_function(Checker,2) ->
+ {Checker(User, Password), Ssh};
+
+ Checker when is_function(Checker,4) ->
+ #ssh{pwdfun_user_state = PrivateState,
+ peer = {_,PeerAddr={_,_}}
+ } = Ssh,
+ case Checker(User, Password, PeerAddr, PrivateState) of
+ true ->
+ {true,Ssh};
+ false ->
+ {false,Ssh};
+ {true,NewState} ->
+ {true, Ssh#ssh{pwdfun_user_state=NewState}};
+ {false,NewState} ->
+ {false, Ssh#ssh{pwdfun_user_state=NewState}};
+ disconnect ->
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
+ description =
+ "Unable to connect using the available authentication methods",
+ language = ""})
+ end
end.
get_password_option(Opts, User) ->
@@ -444,10 +461,7 @@ build_sig_data(SessionId, User, Service, KeyBlob, Alg) ->
?binary(KeyBlob)],
list_to_binary(Sig).
-algorithm_string('ssh-rsa') ->
- "ssh-rsa";
-algorithm_string('ssh-dss') ->
- "ssh-dss".
+
decode_keyboard_interactive_prompts(_NumPrompts, Data) ->
ssh_message:decode_keyboard_interactive_prompts(Data, []).
@@ -463,19 +477,19 @@ keyboard_interact_get_responses(_, undefined, Password, _, _, _, _, _,
1) when Password =/= undefined ->
[Password]; %% Password auth implemented with keyboard-interaction and passwd is known
keyboard_interact_get_responses(_, _, _, _, _, _, _, _, 0) ->
- [""];
+ [];
keyboard_interact_get_responses(false, undefined, undefined, _, _, _, [Prompt|_], Opts, _) ->
ssh_no_io:read_line(Prompt, Opts); %% Throws error as keyboard interaction is not allowed
keyboard_interact_get_responses(true, undefined, _,IoCb, Name, Instr, PromptInfos, Opts, _) ->
keyboard_interact(IoCb, Name, Instr, PromptInfos, Opts);
-keyboard_interact_get_responses(true, Fun, _, Name, Instr, PromptInfos, _, _, NumPrompts) ->
+keyboard_interact_get_responses(true, Fun, _Pwd, _IoCb, Name, Instr, PromptInfos, _Opts, NumPrompts) ->
keyboard_interact_fun(Fun, Name, Instr, PromptInfos, NumPrompts).
keyboard_interact(IoCb, Name, Instr, Prompts, Opts) ->
- if Name /= "" -> IoCb:format("~s", [Name]);
+ if Name /= "" -> IoCb:format("~s~n", [Name]);
true -> ok
end,
- if Instr /= "" -> IoCb:format("~s", [Instr]);
+ if Instr /= "" -> IoCb:format("~s~n", [Instr]);
true -> ok
end,
lists:map(fun({Prompt, true}) -> IoCb:read_line(Prompt, Opts);
@@ -498,33 +512,18 @@ keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
language = "en"}})
end.
-other_alg('ssh-rsa') ->
- 'ssh-dss';
-other_alg('ssh-dss') ->
- 'ssh-rsa'.
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), BinE:Len1/binary,
- ?UINT32(Len2), BinN:Len2/binary>>
- ,"ssh-rsa") ->
- E = ssh_bits:erlint(Len1, BinE),
- N = ssh_bits:erlint(Len2, BinN),
- {ok, #'RSAPublicKey'{publicExponent = E, modulus = N}};
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), BinP:Len1/binary,
- ?UINT32(Len2), BinQ:Len2/binary,
- ?UINT32(Len3), BinG:Len3/binary,
- ?UINT32(Len4), BinY:Len4/binary>>
- , "ssh-dss") ->
- P = ssh_bits:erlint(Len1, BinP),
- Q = ssh_bits:erlint(Len2, BinQ),
- G = ssh_bits:erlint(Len3, BinG),
- Y = ssh_bits:erlint(Len4, BinY),
- {ok, {Y, #'Dss-Parms'{p = P, q = Q, g = G}}};
-
-decode_public_key_v2(_, _) ->
- {error, bad_format}.
-
-encode_public_key(#'RSAPrivateKey'{publicExponent = E, modulus = N}) ->
- ssh_bits:encode(["ssh-rsa",E,N], [string,mpint,mpint]);
-encode_public_key(#'DSAPrivateKey'{p = P, q = Q, g = G, y = Y}) ->
- ssh_bits:encode(["ssh-dss",P,Q,G,Y], [string,mpint,mpint,mpint,mpint]).
+decode_public_key_v2(Bin, _Type) ->
+ try
+ public_key:ssh_decode(Bin, ssh2_pubkey)
+ of
+ Key -> {ok, Key}
+ catch
+ _:_ -> {error, bad_format}
+ end.
+
+encode_public_key(_Alg, Key) ->
+ try
+ public_key:ssh_encode(Key, ssh2_pubkey)
+ catch
+ _:_ -> not_ok
+ end.
diff --git a/lib/ssh/src/ssh_auth.hrl b/lib/ssh/src/ssh_auth.hrl
index 6cd8e6bf14..449bc4fa45 100644
--- a/lib/ssh/src/ssh_auth.hrl
+++ b/lib/ssh/src/ssh_auth.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,9 +22,6 @@
%%% Description: Ssh User Authentication Protocol
--define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
-
--define(PREFERRED_PK_ALG, 'ssh-rsa').
-define(SSH_MSG_USERAUTH_REQUEST, 50).
-define(SSH_MSG_USERAUTH_FAILURE, 51).
diff --git a/lib/ssh/src/ssh_bits.erl b/lib/ssh/src/ssh_bits.erl
index 8aaff93b9f..4da3a6018b 100644
--- a/lib/ssh/src/ssh_bits.erl
+++ b/lib/ssh/src/ssh_bits.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,7 +27,7 @@
-include("ssh.hrl").
-export([encode/2]).
--export([mpint/1, erlint/2, string/1, name_list/1]).
+-export([mpint/1, string/1, name_list/1]).
-export([random/1]).
-define(name_list(X),
@@ -145,11 +146,7 @@ enc(Xs, ['...'| []], _Offset) ->
enc([], [],_) ->
[].
-erlint(Len, BinInt) ->
- Sz = Len*8,
- <<Int:Sz/big-signed-integer>> = BinInt,
- Int.
-
+
%%
%% Create a binary with constant bytes
%%
diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl
index 5c24f362b1..d15a2c8eba 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_channel_sup.erl b/lib/ssh/src/ssh_channel_sup.erl
index ee37ed35f8..7c381553b8 100644
--- a/lib/ssh/src/ssh_channel_sup.erl
+++ b/lib/ssh/src/ssh_channel_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 18841e3d2d..71f62a960e 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -98,7 +99,7 @@ handle_ssh_msg({ssh_cm, ConnectionHandler,
Pty = Pty0#ssh_pty{width = Width, height = Height,
pixel_width = PixWidth,
pixel_height = PixHeight},
- {Chars, NewBuf} = io_request({window_change, Pty0}, Buf, Pty),
+ {Chars, NewBuf} = io_request({window_change, Pty0}, Buf, Pty, undefined),
write_chars(ConnectionHandler, ChannelId, Chars),
{ok, State#state{pty = Pty, buf = NewBuf}};
@@ -188,7 +189,7 @@ handle_msg({Group, tty_geometry}, #state{group = Group,
handle_msg({Group, Req}, #state{group = Group, buf = Buf, pty = Pty,
cm = ConnectionHandler,
channel = ChannelId} = State) ->
- {Chars, NewBuf} = io_request(Req, Buf, Pty),
+ {Chars, NewBuf} = io_request(Req, Buf, Pty, Group),
write_chars(ConnectionHandler, ChannelId, Chars),
{ok, State#state{buf = NewBuf}};
@@ -263,40 +264,49 @@ eval(Error) ->
%%% displaying device...
%%% We are *not* really unicode aware yet, we just filter away characters
%%% beyond the latin1 range. We however handle the unicode binaries...
-io_request({window_change, OldTty}, Buf, Tty) ->
+io_request({window_change, OldTty}, Buf, Tty, _Group) ->
window_change(Tty, OldTty, Buf);
-io_request({put_chars, Cs}, Buf, Tty) ->
+io_request({put_chars, Cs}, Buf, Tty, _Group) ->
put_chars(bin_to_list(Cs), Buf, Tty);
-io_request({put_chars, unicode, Cs}, Buf, Tty) ->
+io_request({put_chars, unicode, Cs}, Buf, Tty, _Group) ->
put_chars(unicode:characters_to_list(Cs,unicode), Buf, Tty);
-io_request({insert_chars, Cs}, Buf, Tty) ->
+io_request({insert_chars, Cs}, Buf, Tty, _Group) ->
insert_chars(bin_to_list(Cs), Buf, Tty);
-io_request({insert_chars, unicode, Cs}, Buf, Tty) ->
+io_request({insert_chars, unicode, Cs}, Buf, Tty, _Group) ->
insert_chars(unicode:characters_to_list(Cs,unicode), Buf, Tty);
-io_request({move_rel, N}, Buf, Tty) ->
+io_request({move_rel, N}, Buf, Tty, _Group) ->
move_rel(N, Buf, Tty);
-io_request({delete_chars,N}, Buf, Tty) ->
+io_request({delete_chars,N}, Buf, Tty, _Group) ->
delete_chars(N, Buf, Tty);
-io_request(beep, Buf, _Tty) ->
+io_request(beep, Buf, _Tty, _Group) ->
{[7], Buf};
%% New in R12
-io_request({get_geometry,columns},Buf,Tty) ->
+io_request({get_geometry,columns},Buf,Tty, _Group) ->
{ok, Tty#ssh_pty.width, Buf};
-io_request({get_geometry,rows},Buf,Tty) ->
+io_request({get_geometry,rows},Buf,Tty, _Group) ->
{ok, Tty#ssh_pty.height, Buf};
-io_request({requests,Rs}, Buf, Tty) ->
- io_requests(Rs, Buf, Tty, []);
-io_request(tty_geometry, Buf, Tty) ->
- io_requests([{move_rel, 0}, {put_chars, unicode, [10]}], Buf, Tty, []);
+io_request({requests,Rs}, Buf, Tty, Group) ->
+ io_requests(Rs, Buf, Tty, [], Group);
+io_request(tty_geometry, Buf, Tty, Group) ->
+ io_requests([{move_rel, 0}, {put_chars, unicode, [10]}],
+ Buf, Tty, [], Group);
%{[], Buf};
-io_request(_R, Buf, _Tty) ->
+
+%% New in 18
+io_request({put_chars_sync, Class, Cs, Reply}, Buf, Tty, Group) ->
+ %% We handle these asynchronous for now, if we need output guarantees
+ %% we have to handle these synchronously
+ Group ! {reply, Reply},
+ io_request({put_chars, Class, Cs}, Buf, Tty, Group);
+
+io_request(_R, Buf, _Tty, _Group) ->
{[], Buf}.
-io_requests([R|Rs], Buf, Tty, Acc) ->
- {Chars, NewBuf} = io_request(R, Buf, Tty),
- io_requests(Rs, NewBuf, Tty, [Acc|Chars]);
-io_requests([], Buf, _Tty, Acc) ->
+io_requests([R|Rs], Buf, Tty, Acc, Group) ->
+ {Chars, NewBuf} = io_request(R, Buf, Tty, Group),
+ io_requests(Rs, NewBuf, Tty, [Acc|Chars], Group);
+io_requests([], Buf, _Tty, Acc, _Group) ->
{Acc, Buf}.
%%% return commands for cursor navigation, assume everything is ansi
diff --git a/lib/ssh/src/ssh_client_key.erl b/lib/ssh/src/ssh_client_key.erl
index 2c48884dc2..0758865ad1 100644
--- a/lib/ssh/src/ssh_client_key.erl
+++ b/lib/ssh/src/ssh_client_key.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_client_key_api.erl b/lib/ssh/src/ssh_client_key_api.erl
index a17c7cbc77..7fe97b6c13 100644
--- a/lib/ssh/src/ssh_client_key_api.erl
+++ b/lib/ssh/src/ssh_client_key_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index d14f7ce27d..9f9f3de8fa 100644
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -247,6 +248,9 @@
local_id, %% local channel id
recv_window_size,
+ recv_window_pending = 0, %% Sum of window size updates that has not
+ %% yet been sent. This limits the number
+ %% of sent update msgs.
recv_packet_size,
recv_close = false,
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index 654b9d4bde..a34478732c 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -196,15 +197,16 @@ reply_request(_,false, _, _) ->
%%--------------------------------------------------------------------
ptty_alloc(ConnectionHandler, Channel, Options) ->
ptty_alloc(ConnectionHandler, Channel, Options, infinity).
-ptty_alloc(ConnectionHandler, Channel, Options, TimeOut) ->
+ptty_alloc(ConnectionHandler, Channel, Options0, TimeOut) ->
+ Options = backwards_compatible(Options0, []),
{Width, PixWidth} = pty_default_dimensions(width, Options),
- {Hight, PixHight} = pty_default_dimensions(hight, Options),
+ {Height, PixHeight} = pty_default_dimensions(height, Options),
pty_req(ConnectionHandler, Channel,
- proplists:get_value(term, Options, default_term()),
+ proplists:get_value(term, Options, os:getenv("TERM", ?DEFAULT_TERMINAL)),
proplists:get_value(width, Options, Width),
- proplists:get_value(hight, Options, Hight),
+ proplists:get_value(height, Options, Height),
proplists:get_value(pixel_widh, Options, PixWidth),
- proplists:get_value(pixel_hight, Options, PixHight),
+ proplists:get_value(pixel_height, Options, PixHeight),
proplists:get_value(pty_opts, Options, []), TimeOut
).
%%--------------------------------------------------------------------
@@ -660,7 +662,7 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
ReplyMsg = {subsystem, ChannelId, WantReply, binary_to_list(SsName)},
try
- {ok, Pid} = start_subsytem(SsName, Connection, Channel0, ReplyMsg),
+ {ok, Pid} = start_subsystem(SsName, Connection, Channel0, ReplyMsg),
erlang:monitor(process, Pid),
Channel = Channel0#channel{user = Pid},
ssh_channel:cache_update(Cache, Channel),
@@ -933,14 +935,27 @@ encode_ip(Addr) when is_list(Addr) ->
end
end.
-start_channel(Cb, Id, Args, SubSysSup) ->
- start_channel(Cb, Id, Args, SubSysSup, undefined).
+start_channel(Cb, Id, Args, SubSysSup, Opts) ->
+ start_channel(Cb, Id, Args, SubSysSup, undefined, Opts).
-start_channel(Cb, Id, Args, SubSysSup, Exec) ->
+start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) ->
ChildSpec = child_spec(Cb, Id, Args, Exec),
ChannelSup = ssh_subsystem_sup:channel_supervisor(SubSysSup),
+ assert_limit_num_channels_not_exceeded(ChannelSup, Opts),
ssh_channel_sup:start_child(ChannelSup, ChildSpec).
+assert_limit_num_channels_not_exceeded(ChannelSup, Opts) ->
+ MaxNumChannels = proplists:get_value(max_channels, Opts, infinity),
+ NumChannels = length([x || {_,_,worker,[ssh_channel]} <-
+ supervisor:which_children(ChannelSup)]),
+ if
+ %% Note that NumChannels is BEFORE starting a new one
+ NumChannels < MaxNumChannels ->
+ ok;
+ true ->
+ throw(max_num_channels_exceeded)
+ end.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -996,17 +1011,19 @@ child_spec(Callback, Id, Args, Exec) ->
start_cli(#connection{cli_spec = no_cli}, _) ->
{error, cli_disabled};
-start_cli(#connection{cli_spec = {CbModule, Args}, exec = Exec,
+start_cli(#connection{options = Options,
+ cli_spec = {CbModule, Args},
+ exec = Exec,
sub_system_supervisor = SubSysSup}, ChannelId) ->
- start_channel(CbModule, ChannelId, Args, SubSysSup, Exec).
+ start_channel(CbModule, ChannelId, Args, SubSysSup, Exec, Options).
-start_subsytem(BinName, #connection{options = Options,
+start_subsystem(BinName, #connection{options = Options,
sub_system_supervisor = SubSysSup},
#channel{local_id = ChannelId}, _ReplyMsg) ->
Name = binary_to_list(BinName),
case check_subsystem(Name, Options) of
{Callback, Opts} when is_atom(Callback), Callback =/= none ->
- start_channel(Callback, ChannelId, Opts, SubSysSup);
+ start_channel(Callback, ChannelId, Opts, SubSysSup, Options);
{Other, _} when Other =/= none ->
{error, legacy_option_not_supported}
end.
@@ -1340,10 +1357,11 @@ decode_ip(Addr) when is_binary(Addr) ->
{ok,A} -> A
end.
-default_term() ->
- case os:getenv("TERM") of
- false ->
- ?DEFAULT_TERMINAL;
- Str when is_list(Str)->
- Str
- end.
+backwards_compatible([], Acc) ->
+ Acc;
+backwards_compatible([{hight, Value} | Rest], Acc) ->
+ backwards_compatible(Rest, [{height, Value} | Acc]);
+backwards_compatible([{pixel_hight, Value} | Rest], Acc) ->
+ backwards_compatible(Rest, [{height, Value} | Acc]);
+backwards_compatible([Value| Rest], Acc) ->
+ backwards_compatible(Rest, [ Value | Acc]).
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index f751094211..ce1931e4f4 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,7 +34,7 @@
-include("ssh_transport.hrl").
-include("ssh_auth.hrl").
-include("ssh_connect.hrl").
-
+-compile(export_all).
-export([start_link/3]).
%% Internal application API
@@ -45,8 +46,13 @@
get_print_info/1]).
%% gen_fsm callbacks
--export([hello/2, kexinit/2, key_exchange/2, new_keys/2,
- userauth/2, connected/2,
+-export([hello/2, kexinit/2, key_exchange/2,
+ key_exchange_dh_gex_init/2, key_exchange_dh_gex_reply/2,
+ new_keys/2,
+ service_request/2, connected/2,
+ userauth/2,
+ userauth_keyboard_interactive/2,
+ userauth_keyboard_interactive_info_response/2,
error/2]).
-export([init/1, handle_event/3,
@@ -70,6 +76,8 @@
undecoded_packet_length, % integer()
key_exchange_init_msg, % #ssh_msg_kexinit{}
renegotiate = false, % boolean()
+ last_size_rekey = 0,
+ event_queue = [],
connection_queue,
address,
port,
@@ -77,11 +85,21 @@
recbuf
}).
--type state_name() :: hello | kexinit | key_exchange | new_keys | userauth | connection.
+-type state_name() :: hello | kexinit | key_exchange | key_exchange_dh_gex_init |
+ key_exchange_dh_gex_reply | new_keys | service_request |
+ userauth | userauth_keyboard_interactive |
+ userauth_keyboard_interactive_info_response |
+ connection.
+
-type gen_fsm_state_return() :: {next_state, state_name(), term()} |
{next_state, state_name(), term(), timeout()} |
{stop, term(), term()}.
+-type gen_fsm_sync_return() :: {next_state, state_name(), term()} |
+ {next_state, state_name(), term(), timeout()} |
+ {reply, term(), state_name(), term()} |
+ {stop, term(), term(), term()}.
+
%%====================================================================
%% Internal application API
%%====================================================================
@@ -409,59 +427,91 @@ key_exchange(#ssh_msg_kexdh_reply{} = Msg,
send_msg(NewKeys, State),
{next_state, new_keys, next_packet(State#state{ssh_params = Ssh})};
+key_exchange(#ssh_msg_kex_dh_gex_request{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
+ send_msg(GexGroup, State),
+ {next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+
+key_exchange(#ssh_msg_kex_dh_gex_request_old{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
+ send_msg(GexGroup, State),
+ {next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+
key_exchange(#ssh_msg_kex_dh_gex_group{} = Msg,
+ #state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
+ {ok, KexGexInit, Ssh} = ssh_transport:handle_kex_dh_gex_group(Msg, Ssh0),
+ send_msg(KexGexInit, State),
+ {next_state, key_exchange_dh_gex_reply, next_packet(State#state{ssh_params = Ssh})};
+
+key_exchange(#ssh_msg_kex_ecdh_init{} = Msg,
#state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
- {ok, NextKexMsg, Ssh1} = ssh_transport:handle_kex_dh_gex_group(Msg, Ssh0),
- send_msg(NextKexMsg, State),
+ {ok, KexEcdhReply, Ssh1} = ssh_transport:handle_kex_ecdh_init(Msg, Ssh0),
+ send_msg(KexEcdhReply, State),
{ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
send_msg(NewKeys, State),
{next_state, new_keys, next_packet(State#state{ssh_params = Ssh})};
-key_exchange(#ssh_msg_kex_dh_gex_request{} = Msg,
+key_exchange(#ssh_msg_kex_ecdh_reply{} = Msg,
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
- {ok, NextKexMsg, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
- send_msg(NextKexMsg, State),
- {next_state, new_keys, next_packet(State#state{ssh_params = Ssh})};
+ {ok, NewKeys, Ssh} = ssh_transport:handle_kex_ecdh_reply(Msg, Ssh0),
+ send_msg(NewKeys, State),
+ {next_state, new_keys, next_packet(State#state{ssh_params = Ssh})}.
-key_exchange(#ssh_msg_kex_dh_gex_reply{} = Msg,
- #state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
- {ok, NewKeys, Ssh} = ssh_transport:handle_kex_dh_gex_reply(Msg, Ssh0),
+%%--------------------------------------------------------------------
+-spec key_exchange_dh_gex_init(#ssh_msg_kex_dh_gex_init{}, #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
+key_exchange_dh_gex_init(#ssh_msg_kex_dh_gex_init{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, KexGexReply, Ssh1} = ssh_transport:handle_kex_dh_gex_init(Msg, Ssh0),
+ send_msg(KexGexReply, State),
+ {ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
send_msg(NewKeys, State),
{next_state, new_keys, next_packet(State#state{ssh_params = Ssh})}.
%%--------------------------------------------------------------------
+-spec key_exchange_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{}, #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
+key_exchange_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{} = Msg,
+ #state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
+ {ok, NewKeys, Ssh1} = ssh_transport:handle_kex_dh_gex_reply(Msg, Ssh0),
+ send_msg(NewKeys, State),
+ {next_state, new_keys, next_packet(State#state{ssh_params = Ssh1})}.
+
+%%--------------------------------------------------------------------
-spec new_keys(#ssh_msg_newkeys{}, #state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
new_keys(#ssh_msg_newkeys{} = Msg, #state{ssh_params = Ssh0} = State0) ->
{ok, Ssh} = ssh_transport:handle_new_keys(Msg, Ssh0),
- {NextStateName, State} =
- after_new_keys(State0#state{ssh_params = Ssh}),
- {next_state, NextStateName, next_packet(State)}.
+ after_new_keys(next_packet(State0#state{ssh_params = Ssh})).
%%--------------------------------------------------------------------
--spec userauth(#ssh_msg_service_request{} | #ssh_msg_service_accept{} |
- #ssh_msg_userauth_request{} | #ssh_msg_userauth_info_request{} |
- #ssh_msg_userauth_info_response{} | #ssh_msg_userauth_success{} |
- #ssh_msg_userauth_failure{} | #ssh_msg_userauth_banner{},
- #state{}) -> gen_fsm_state_return().
+-spec service_request(#ssh_msg_service_request{} | #ssh_msg_service_accept{},
+ #state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
-
-userauth(#ssh_msg_service_request{name = "ssh-userauth"} = Msg,
+service_request(#ssh_msg_service_request{name = "ssh-userauth"} = Msg,
#state{ssh_params = #ssh{role = server,
session_id = SessionId} = Ssh0} = State) ->
{ok, {Reply, Ssh}} = ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0),
send_msg(Reply, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-userauth(#ssh_msg_service_accept{name = "ssh-userauth"},
- #state{ssh_params = #ssh{role = client,
- service = "ssh-userauth"} = Ssh0} =
- State) ->
+service_request(#ssh_msg_service_accept{name = "ssh-userauth"},
+ #state{ssh_params = #ssh{role = client,
+ service = "ssh-userauth"} = Ssh0} =
+ State) ->
{Msg, Ssh} = ssh_auth:init_userauth_request_msg(Ssh0),
send_msg(Msg, State),
- {next_state, userauth, next_packet(State#state{auth_user = Ssh#ssh.user, ssh_params = Ssh})};
+ {next_state, userauth, next_packet(State#state{auth_user = Ssh#ssh.user, ssh_params = Ssh})}.
+%%--------------------------------------------------------------------
+-spec userauth(#ssh_msg_userauth_request{} | #ssh_msg_userauth_info_request{} |
+ #ssh_msg_userauth_info_response{} | #ssh_msg_userauth_success{} |
+ #ssh_msg_userauth_failure{} | #ssh_msg_userauth_banner{},
+ #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
userauth(#ssh_msg_userauth_request{service = "ssh-connection",
method = "none"} = Msg,
#state{ssh_params = #ssh{session_id = SessionId, role = server,
@@ -478,43 +528,28 @@ userauth(#ssh_msg_userauth_request{service = "ssh-connection",
service = "ssh-connection",
peer = {_, Address}} = Ssh0,
opts = Opts, starter = Pid} = State) ->
- case ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0) of
- {authorized, User, {Reply, Ssh}} ->
- send_msg(Reply, State),
- Pid ! ssh_connected,
- connected_fun(User, Address, Method, Opts),
- {next_state, connected,
- next_packet(State#state{auth_user = User, ssh_params = Ssh})};
- {not_authorized, {User, Reason}, {Reply, Ssh}} ->
- retry_fun(User, Address, Reason, Opts),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ case lists:member(Method, Ssh0#ssh.userauth_methods) of
+ true ->
+ case ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0) of
+ {authorized, User, {Reply, Ssh}} ->
+ send_msg(Reply, State),
+ Pid ! ssh_connected,
+ connected_fun(User, Address, Method, Opts),
+ {next_state, connected,
+ next_packet(State#state{auth_user = User, ssh_params = Ssh#ssh{authenticated = true}})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} when Method == "keyboard-interactive" ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
+ false ->
+ userauth(Msg#ssh_msg_userauth_request{method="none"}, State)
end;
-userauth(#ssh_msg_userauth_info_request{} = Msg,
- #state{ssh_params = #ssh{role = client,
- io_cb = IoCb} = Ssh0} = State) ->
- {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, IoCb, Ssh0),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-
-userauth(#ssh_msg_userauth_info_response{} = Msg,
- #state{ssh_params = #ssh{role = server,
- peer = {_, Address}} = Ssh0,
- opts = Opts, starter = Pid} = State) ->
- case ssh_auth:handle_userauth_info_response(Msg, Ssh0) of
- {authorized, User, {Reply, Ssh}} ->
- send_msg(Reply, State),
- Pid ! ssh_connected,
- connected_fun(User, Address, "keyboard-interactive", Opts),
- {next_state, connected,
- next_packet(State#state{auth_user = User, ssh_params = Ssh})};
- {not_authorized, {User, Reason}, {Reply, Ssh}} ->
- retry_fun(User, Address, Reason, Opts),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
- end;
-
userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client} = Ssh,
starter = Pid} = State) ->
Pid ! ssh_connected,
@@ -541,19 +576,25 @@ userauth(#ssh_msg_userauth_failure{authentications = Methodes},
{disconnect, DisconnectMsg, {Msg, Ssh}} ->
send_msg(Msg, State),
handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
- {Msg, Ssh} ->
+ {"keyboard-interactive", {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {_Method, {Msg, Ssh}} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
%% The prefered authentication method failed try next method
-userauth(#ssh_msg_userauth_failure{},
+userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
case ssh_auth:userauth_request_msg(Ssh0) of
{disconnect, DisconnectMsg,{Msg, Ssh}} ->
send_msg(Msg, State),
handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
- {Msg, Ssh} ->
+ {"keyboard-interactive", {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {_Method, {Msg, Ssh}} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
@@ -568,15 +609,63 @@ userauth(#ssh_msg_userauth_banner{message = Msg},
io:format("~s", [Msg]),
{next_state, userauth, next_packet(State)}.
+
+
+userauth_keyboard_interactive(#ssh_msg_userauth_info_request{} = Msg,
+ #state{ssh_params = #ssh{role = client,
+ io_cb = IoCb} = Ssh0} = State) ->
+ {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, IoCb, Ssh0),
+ send_msg(Reply, State),
+ {next_state, userauth_keyboard_interactive_info_response, next_packet(State#state{ssh_params = Ssh})};
+
+userauth_keyboard_interactive(#ssh_msg_userauth_info_response{} = Msg,
+ #state{ssh_params = #ssh{role = server,
+ peer = {_, Address}} = Ssh0,
+ opts = Opts, starter = Pid} = State) ->
+ case ssh_auth:handle_userauth_info_response(Msg, Ssh0) of
+ {authorized, User, {Reply, Ssh}} ->
+ send_msg(Reply, State),
+ Pid ! ssh_connected,
+ connected_fun(User, Address, "keyboard-interactive", Opts),
+ {next_state, connected,
+ next_packet(State#state{auth_user = User, ssh_params = Ssh#ssh{authenticated = true}})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
+userauth_keyboard_interactive(Msg = #ssh_msg_userauth_failure{},
+ #state{ssh_params = Ssh0 =
+ #ssh{role = client,
+ userauth_preference = Prefs0}}
+ = State) ->
+ Prefs = [{Method,M,F,A} || {Method,M,F,A} <- Prefs0,
+ Method =/= "keyboard-interactive"],
+ userauth(Msg, State#state{ssh_params = Ssh0#ssh{userauth_preference=Prefs}}).
+
+
+
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_failure{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth(Msg, State);
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_success{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth(Msg, State);
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_info_request{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth_keyboard_interactive(Msg, State).
+
%%--------------------------------------------------------------------
-spec connected({#ssh_msg_kexinit{}, binary()}, %%| %% #ssh_msg_kexdh_init{},
#state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
-connected({#ssh_msg_kexinit{}, _Payload} = Event, State) ->
- kexinit(Event, State#state{renegotiate = true}).
-%% ;
-%% connected(#ssh_msg_kexdh_init{} = Event, State) ->
-%% key_exchange(Event, State#state{renegotiate = true}).
+connected({#ssh_msg_kexinit{}, _Payload} = Event, #state{ssh_params = Ssh0} = State0) ->
+ {KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh0),
+ State = State0#state{ssh_params = Ssh,
+ key_exchange_init_msg = KeyInitMsg,
+ renegotiate = true},
+ send_msg(SshPacket, State),
+ kexinit(Event, State).
%%--------------------------------------------------------------------
-spec handle_event(#ssh_msg_disconnect{} | #ssh_msg_ignore{} | #ssh_msg_debug{} |
@@ -605,33 +694,6 @@ handle_event(#ssh_msg_debug{always_display = Display, message = DbgMsg, language
handle_event(#ssh_msg_unimplemented{}, StateName, State) ->
{next_state, StateName, next_packet(State)};
-handle_event({adjust_window, ChannelId, Bytes}, StateName,
- #state{connection_state =
- #connection{channel_cache = Cache}} = State0) ->
- State =
- case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{recv_window_size = WinSize, remote_id = Id} = Channel ->
- ssh_channel:cache_update(Cache, Channel#channel{recv_window_size =
- WinSize + Bytes}),
- Msg = ssh_connection:channel_adjust_window_msg(Id, Bytes),
- send_replies([{connection_reply, Msg}], State0);
- undefined ->
- State0
- end,
- {next_state, StateName, next_packet(State)};
-
-handle_event({reply_request, success, ChannelId}, StateName,
- #state{connection_state =
- #connection{channel_cache = Cache}} = State0) ->
- State = case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{remote_id = RemoteId} ->
- Msg = ssh_connection:channel_success_msg(RemoteId),
- send_replies([{connection_reply, Msg}], State0);
- undefined ->
- State0
- end,
- {next_state, StateName, State};
-
handle_event(renegotiate, connected, #state{ssh_params = Ssh0}
= State) ->
{KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh0),
@@ -643,13 +705,13 @@ handle_event(renegotiate, connected, #state{ssh_params = Ssh0}
renegotiate = true})};
handle_event(renegotiate, StateName, State) ->
- timer:apply_after(?REKEY_TIMOUT, gen_fsm, send_all_state_event, [self(), renegotiate]),
- %% Allready in keyexcahange so ignore
+ %% Already in key-exchange so safe to ignore
{next_state, StateName, State};
%% Rekey due to sent data limit reached?
handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
- {ok, [{send_oct,Sent}]} = inet:getstat(State#state.socket, [send_oct]),
+ {ok, [{send_oct,Sent0}]} = inet:getstat(State#state.socket, [send_oct]),
+ Sent = Sent0 - State#state.last_size_rekey,
MaxSent = proplists:get_value(rekey_limit, State#state.opts, 1024000000),
timer:apply_after(?REKEY_DATA_TIMOUT, gen_fsm, send_all_state_event, [self(), data_size]),
case Sent >= MaxSent of
@@ -659,11 +721,59 @@ handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
{next_state, kexinit,
next_packet(State#state{ssh_params = Ssh,
key_exchange_init_msg = KeyInitMsg,
- renegotiate = true})};
+ renegotiate = true,
+ last_size_rekey = Sent0})};
_ ->
{next_state, connected, next_packet(State)}
end;
handle_event(data_size, StateName, State) ->
+ %% Already in key-exchange so safe to ignore
+ {next_state, StateName, State};
+
+handle_event(Event, StateName, State) when StateName /= connected ->
+ Events = [{event, Event} | State#state.event_queue],
+ {next_state, StateName, State#state{event_queue = Events}};
+
+handle_event({adjust_window, ChannelId, Bytes}, StateName,
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State0) ->
+ State =
+ case ssh_channel:cache_lookup(Cache, ChannelId) of
+ #channel{recv_window_size = WinSize,
+ recv_window_pending = Pending,
+ recv_packet_size = PktSize} = Channel
+ when (WinSize-Bytes) >= 2*PktSize ->
+ %% The peer can send at least two more *full* packet, no hurry.
+ ssh_channel:cache_update(Cache,
+ Channel#channel{recv_window_pending = Pending + Bytes}),
+ State0;
+
+ #channel{recv_window_size = WinSize,
+ recv_window_pending = Pending,
+ remote_id = Id} = Channel ->
+ %% Now we have to update the window - we can't receive so many more pkts
+ ssh_channel:cache_update(Cache,
+ Channel#channel{recv_window_size =
+ WinSize + Bytes + Pending,
+ recv_window_pending = 0}),
+ Msg = ssh_connection:channel_adjust_window_msg(Id, Bytes + Pending),
+ send_replies([{connection_reply, Msg}], State0);
+
+ undefined ->
+ State0
+ end,
+ {next_state, StateName, next_packet(State)};
+
+handle_event({reply_request, success, ChannelId}, StateName,
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State0) ->
+ State = case ssh_channel:cache_lookup(Cache, ChannelId) of
+ #channel{remote_id = RemoteId} ->
+ Msg = ssh_connection:channel_success_msg(RemoteId),
+ send_replies([{connection_reply, Msg}], State0);
+ undefined ->
+ State0
+ end,
{next_state, StateName, State};
handle_event({request, ChannelPid, ChannelId, Type, Data}, StateName, State0) ->
@@ -694,8 +804,62 @@ handle_event({unknown, Data}, StateName, State) ->
sockname]} | {channel_info, channel_id(), [recv_window |
send_window]} |
{close, channel_id()} | stop, term(), state_name(), #state{})
- -> gen_fsm_state_return().
+ -> gen_fsm_sync_return().
%%--------------------------------------------------------------------
+handle_sync_event(get_print_info, _From, StateName, State) ->
+ Reply =
+ try
+ {inet:sockname(State#state.socket),
+ inet:peername(State#state.socket)
+ }
+ of
+ {{ok,Local}, {ok,Remote}} -> {{Local,Remote},io_lib:format("statename=~p",[StateName])};
+ _ -> {{"-",0},"-"}
+ catch
+ _:_ -> {{"?",0},"?"}
+ end,
+ {reply, Reply, StateName, State};
+
+handle_sync_event({connection_info, Options}, _From, StateName, State) ->
+ Info = ssh_info(Options, State, []),
+ {reply, Info, StateName, State};
+
+handle_sync_event({channel_info, ChannelId, Options}, _From, StateName,
+ #state{connection_state = #connection{channel_cache = Cache}} = State) ->
+ case ssh_channel:cache_lookup(Cache, ChannelId) of
+ #channel{} = Channel ->
+ Info = ssh_channel_info(Options, Channel, []),
+ {reply, Info, StateName, State};
+ undefined ->
+ {reply, [], StateName, State}
+ end;
+
+handle_sync_event({info, ChannelPid}, _From, StateName,
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State) ->
+ Result = ssh_channel:cache_foldl(
+ fun(Channel, Acc) when ChannelPid == all;
+ Channel#channel.user == ChannelPid ->
+ [Channel | Acc];
+ (_, Acc) ->
+ Acc
+ end, [], Cache),
+ {reply, {ok, Result}, StateName, State};
+
+handle_sync_event(stop, _, _StateName, #state{connection_state = Connection0,
+ role = Role} = State0) ->
+ {disconnect, _Reason, {{replies, Replies}, Connection}} =
+ ssh_connection:handle_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "User closed down connection",
+ language = "en"}, Connection0, Role),
+ State = send_replies(Replies, State0),
+ {stop, normal, ok, State#state{connection_state = Connection}};
+
+
+handle_sync_event(Event, From, StateName, State) when StateName /= connected ->
+ Events = [{sync, Event, From} | State#state.event_queue],
+ {next_state, StateName, State#state{event_queue = Events}};
+
handle_sync_event({request, ChannelPid, ChannelId, Type, Data, Timeout}, From, StateName, State0) ->
{{replies, Replies}, State1} = handle_request(ChannelPid,
ChannelId, Type, Data,
@@ -798,46 +962,6 @@ handle_sync_event({recv_window, ChannelId}, _From, StateName,
end,
{reply, Reply, StateName, next_packet(State)};
-handle_sync_event(get_print_info, _From, StateName, State) ->
- Reply =
- try
- {inet:sockname(State#state.socket),
- inet:peername(State#state.socket)
- }
- of
- {{ok,Local}, {ok,Remote}} -> {{Local,Remote},io_lib:format("statename=~p",[StateName])};
- _ -> {{"-",0},"-"}
- catch
- _:_ -> {{"?",0},"?"}
- end,
- {reply, Reply, StateName, State};
-
-handle_sync_event({connection_info, Options}, _From, StateName, State) ->
- Info = ssh_info(Options, State, []),
- {reply, Info, StateName, State};
-
-handle_sync_event({channel_info, ChannelId, Options}, _From, StateName,
- #state{connection_state = #connection{channel_cache = Cache}} = State) ->
- case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{} = Channel ->
- Info = ssh_channel_info(Options, Channel, []),
- {reply, Info, StateName, State};
- undefined ->
- {reply, [], StateName, State}
- end;
-
-handle_sync_event({info, ChannelPid}, _From, StateName,
- #state{connection_state =
- #connection{channel_cache = Cache}} = State) ->
- Result = ssh_channel:cache_foldl(
- fun(Channel, Acc) when ChannelPid == all;
- Channel#channel.user == ChannelPid ->
- [Channel | Acc];
- (_, Acc) ->
- Acc
- end, [], Cache),
- {reply, {ok, Result}, StateName, State};
-
handle_sync_event({close, ChannelId}, _, StateName,
#state{connection_state =
#connection{channel_cache = Cache}} = State0) ->
@@ -852,19 +976,7 @@ handle_sync_event({close, ChannelId}, _, StateName,
undefined ->
State0
end,
- {reply, ok, StateName, next_packet(State)};
-
-handle_sync_event(stop, _, _StateName, #state{connection_state = Connection0,
- role = Role,
- opts = Opts} = State0) ->
- {disconnect, Reason, {{replies, Replies}, Connection}} =
- ssh_connection:handle_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "User closed down connection",
- language = "en"}, Connection0, Role),
- State = send_replies(Replies, State0),
- SSHOpts = proplists:get_value(ssh_opts, Opts),
- disconnect_fun(Reason, SSHOpts),
- {stop, normal, ok, State#state{connection_state = Connection}}.
+ {reply, ok, StateName, next_packet(State)}.
%%--------------------------------------------------------------------
-spec handle_info({atom(), port(), binary()} | {atom(), port()} |
@@ -881,57 +993,55 @@ handle_info({Protocol, Socket, Info}, hello,
transport_protocol = Protocol} = State) ->
event({info_line, Info}, hello, State);
-handle_info({Protocol, Socket, Data}, Statename,
+handle_info({Protocol, Socket, Data}, StateName,
#state{socket = Socket,
transport_protocol = Protocol,
- ssh_params = #ssh{decrypt_block_size = BlockSize,
- recv_mac_size = MacSize} = Ssh0,
- decoded_data_buffer = <<>>,
- encoded_data_buffer = EncData0} = State0) ->
-
- %% Implementations SHOULD decrypt the length after receiving the
- %% first 8 (or cipher block size, whichever is larger) bytes of a
- %% packet. (RFC 4253: Section 6 - Binary Packet Protocol)
- case size(EncData0) + size(Data) >= erlang:max(8, BlockSize) of
- true ->
- {Ssh, SshPacketLen, DecData, EncData} =
-
- ssh_transport:decrypt_first_block(<<EncData0/binary,
- Data/binary>>, Ssh0),
- case SshPacketLen > ?SSH_MAX_PACKET_SIZE of
- true ->
- DisconnectMsg =
- #ssh_msg_disconnect{code =
- ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad packet length "
- ++ integer_to_list(SshPacketLen),
- language = "en"},
- handle_disconnect(DisconnectMsg, State0);
- false ->
- RemainingSshPacketLen =
- (SshPacketLen + ?SSH_LENGHT_INDICATOR_SIZE) -
- BlockSize + MacSize,
- State = State0#state{ssh_params = Ssh},
- handle_ssh_packet_data(RemainingSshPacketLen,
- DecData, EncData, Statename,
- State)
- end;
- false ->
- {next_state, Statename,
- next_packet(State0#state{encoded_data_buffer =
- <<EncData0/binary, Data/binary>>})}
- end;
-
-handle_info({Protocol, Socket, Data}, Statename,
- #state{socket = Socket,
- transport_protocol = Protocol,
- decoded_data_buffer = DecData,
- encoded_data_buffer = EncData,
- undecoded_packet_length = Len} =
- State) when is_integer(Len) ->
- handle_ssh_packet_data(Len, DecData, <<EncData/binary, Data/binary>>,
- Statename, State);
+ ssh_params = Ssh0,
+ decoded_data_buffer = DecData0,
+ encoded_data_buffer = EncData0,
+ undecoded_packet_length = RemainingSshPacketLen0} = State0) ->
+ Encoded = <<EncData0/binary, Data/binary>>,
+ try ssh_transport:handle_packet_part(DecData0, Encoded, RemainingSshPacketLen0, Ssh0)
+ of
+ {get_more, DecBytes, EncDataRest, RemainingSshPacketLen, Ssh1} ->
+ {next_state, StateName,
+ next_packet(State0#state{encoded_data_buffer = EncDataRest,
+ decoded_data_buffer = DecBytes,
+ undecoded_packet_length = RemainingSshPacketLen,
+ ssh_params = Ssh1})};
+ {decoded, MsgBytes, EncDataRest, Ssh1} ->
+ generate_event(MsgBytes, StateName,
+ State0#state{ssh_params = Ssh1,
+ %% Important to be set for
+ %% next_packet
+%%% FIXME: the following three seem to always be set in generate_event!
+ decoded_data_buffer = <<>>,
+ undecoded_packet_length = undefined,
+ encoded_data_buffer = EncDataRest},
+ EncDataRest);
+ {bad_mac, Ssh1} ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad mac",
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0#state{ssh_params=Ssh1});
+ {error, {exceeds_max_size,PacketLen}} ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet length "
+ ++ integer_to_list(PacketLen),
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0)
+ catch
+ _:_ ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet",
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0)
+ end;
+
handle_info({CloseTag, _Socket}, _StateName,
#state{transport_close_tag = CloseTag,
ssh_params = #ssh{role = _Role, opts = _Opts}} = State) ->
@@ -969,15 +1079,38 @@ handle_info({check_cache, _ , _},
#connection{channel_cache = Cache}} = State) ->
{next_state, StateName, check_cache(State, Cache)};
-handle_info(UnexpectedMessage, StateName, #state{ssh_params = SshParams} = State) ->
- Msg = lists:flatten(io_lib:format(
- "Unexpected message '~p' received in state '~p'\n"
- "Role: ~p\n"
- "Peer: ~p\n"
- "Local Address: ~p\n", [UnexpectedMessage, StateName,
- SshParams#ssh.role, SshParams#ssh.peer,
- proplists:get_value(address, SshParams#ssh.opts)])),
- error_logger:info_report(Msg),
+handle_info(UnexpectedMessage, StateName, #state{opts = Opts,
+ ssh_params = SshParams} = State) ->
+ case unexpected_fun(UnexpectedMessage, Opts, SshParams) of
+ report ->
+ Msg = lists:flatten(
+ io_lib:format(
+ "Unexpected message '~p' received in state '~p'\n"
+ "Role: ~p\n"
+ "Peer: ~p\n"
+ "Local Address: ~p\n", [UnexpectedMessage, StateName,
+ SshParams#ssh.role, SshParams#ssh.peer,
+ proplists:get_value(address, SshParams#ssh.opts)])),
+ error_logger:info_report(Msg);
+
+ skip ->
+ ok;
+
+ Other ->
+ Msg = lists:flatten(
+ io_lib:format("Call to fun in 'unexpectedfun' failed:~n"
+ "Return: ~p\n"
+ "Message: ~p\n"
+ "Role: ~p\n"
+ "Peer: ~p\n"
+ "Local Address: ~p\n", [Other, UnexpectedMessage,
+ SshParams#ssh.role,
+ element(2,SshParams#ssh.peer),
+ proplists:get_value(address, SshParams#ssh.opts)]
+ )),
+
+ error_logger:error_report(Msg)
+ end,
{next_state, StateName, State}.
%%--------------------------------------------------------------------
@@ -986,7 +1119,7 @@ handle_info(UnexpectedMessage, StateName, #state{ssh_params = SshParams} = State
terminate(normal, _, #state{transport_cb = Transport,
connection_state = Connection,
socket = Socket}) ->
- terminate_subsytem(Connection),
+ terminate_subsystem(Connection),
(catch Transport:close(Socket)),
ok;
@@ -1015,7 +1148,7 @@ terminate({shutdown, _}, StateName, State) ->
terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
connection_state = Connection} = State) ->
- terminate_subsytem(Connection),
+ terminate_subsystem(Connection),
log_error(Reason),
DisconnectMsg =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
@@ -1026,10 +1159,10 @@ terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
terminate(normal, StateName, State#state{ssh_params = Ssh}).
-terminate_subsytem(#connection{system_supervisor = SysSup,
+terminate_subsystem(#connection{system_supervisor = SysSup,
sub_system_supervisor = SubSysSup}) when is_pid(SubSysSup) ->
ssh_system_sup:stop_subsystem(SysSup, SubSysSup);
-terminate_subsytem(_) ->
+terminate_subsystem(_) ->
ok.
format_status(normal, [_, State]) ->
@@ -1129,13 +1262,16 @@ init_ssh(client = Role, Vsn, Version, Options, Socket) ->
opts = Options,
userauth_supported_methods = AuthMethods,
peer = {PeerName, PeerAddr},
- available_host_keys = supported_host_keys(Role, KeyCb, Options)
+ available_host_keys = supported_host_keys(Role, KeyCb, Options),
+ random_length_padding = proplists:get_value(max_random_length_padding,
+ Options,
+ (#ssh{})#ssh.random_length_padding)
};
init_ssh(server = Role, Vsn, Version, Options, Socket) ->
-
AuthMethods = proplists:get_value(auth_methods, Options,
?SUPPORTED_AUTH_METHODS),
+ AuthMethodsAsList = string:tokens(AuthMethods, ","),
{ok, PeerAddr} = inet:peername(Socket),
KeyCb = proplists:get_value(key_cb, Options, ssh_file),
@@ -1146,60 +1282,45 @@ init_ssh(server = Role, Vsn, Version, Options, Socket) ->
io_cb = proplists:get_value(io_cb, Options, ssh_io),
opts = Options,
userauth_supported_methods = AuthMethods,
+ userauth_methods = AuthMethodsAsList,
+ kb_tries_left = 3,
peer = {undefined, PeerAddr},
- available_host_keys = supported_host_keys(Role, KeyCb, Options)
+ available_host_keys = supported_host_keys(Role, KeyCb, Options),
+ random_length_padding = proplists:get_value(max_random_length_padding,
+ Options,
+ (#ssh{})#ssh.random_length_padding)
}.
supported_host_keys(client, _, Options) ->
try
- case extract_algs(proplists:get_value(pref_public_key_algs, Options, false), []) of
- false ->
- ["ssh-rsa", "ssh-dss"];
- Algs ->
- Algs
+ case proplists:get_value(public_key,
+ proplists:get_value(preferred_algorithms,Options,[])
+ ) of
+ undefined ->
+ ssh_transport:default_algorithms(public_key);
+ L ->
+ L -- (L--ssh_transport:default_algorithms(public_key))
end
+ of
+ [] ->
+ {stop, {shutdown, "No public key algs"}};
+ Algs ->
+ [atom_to_list(A) || A<-Algs]
catch
exit:Reason ->
{stop, {shutdown, Reason}}
end;
supported_host_keys(server, KeyCb, Options) ->
- lists:foldl(fun(Type, Acc) ->
- case available_host_key(KeyCb, Type, Options) of
- {error, _} ->
- Acc;
- Alg ->
- [Alg | Acc]
- end
- end, [],
- %% Prefered alg last so no need to reverse
- ["ssh-dss", "ssh-rsa"]).
-extract_algs(false, _) ->
- false;
-extract_algs([],[]) ->
- false;
-extract_algs([], NewList) ->
- lists:reverse(NewList);
-extract_algs([H|T], NewList) ->
- case H of
- 'ssh-dss' ->
- extract_algs(T, ["ssh-dss"|NewList]);
- 'ssh-rsa' ->
- extract_algs(T, ["ssh-rsa"|NewList])
- end.
-available_host_key(KeyCb, "ssh-dss"= Alg, Opts) ->
- case KeyCb:host_key('ssh-dss', Opts) of
- {ok, _} ->
- Alg;
- Other ->
- Other
- end;
-available_host_key(KeyCb, "ssh-rsa" = Alg, Opts) ->
- case KeyCb:host_key('ssh-rsa', Opts) of
- {ok, _} ->
- Alg;
- Other ->
- Other
- end.
+ [atom_to_list(A) || A <- proplists:get_value(public_key,
+ proplists:get_value(preferred_algorithms,Options,[]),
+ ssh_transport:default_algorithms(public_key)
+ ),
+ available_host_key(KeyCb, A, Options)
+ ].
+
+%% Alg :: atom()
+available_host_key(KeyCb, Alg, Opts) ->
+ element(1, catch KeyCb:host_key(Alg, Opts)) == ok.
send_msg(Msg, #state{socket = Socket, transport_cb = Transport}) ->
Transport:send(Socket, Msg).
@@ -1257,7 +1378,7 @@ event(Event, StateName, State) ->
handle_disconnect(DisconnectMsg, State);
throw:{ErrorToDisplay, #ssh_msg_disconnect{} = DisconnectMsg} ->
handle_disconnect(DisconnectMsg, State, ErrorToDisplay);
- _:_ ->
+ _C:_Error ->
handle_disconnect(#ssh_msg_disconnect{code = error_code(StateName),
description = "Invalid state",
language = "en"}, State)
@@ -1273,7 +1394,6 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
#state{
role = Role,
starter = User,
- opts = Opts,
renegotiate = Renegotiation,
connection_state = Connection0} = State0, EncData)
when Byte == ?SSH_MSG_GLOBAL_REQUEST;
@@ -1290,41 +1410,57 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
Byte == ?SSH_MSG_CHANNEL_REQUEST;
Byte == ?SSH_MSG_CHANNEL_SUCCESS;
Byte == ?SSH_MSG_CHANNEL_FAILURE ->
- ConnectionMsg = ssh_message:decode(Msg),
- State1 = generate_event_new_state(State0, EncData),
- try ssh_connection:handle_msg(ConnectionMsg, Connection0, Role) of
- {{replies, Replies}, Connection} ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- {next_state, StateName, next_packet(State)};
- {noreply, Connection} ->
- {next_state, StateName, next_packet(State1#state{connection_state = Connection})};
- {disconnect, {_, Reason}, {{replies, Replies}, Connection}} when
- Role == client andalso ((StateName =/= connected) and (not Renegotiation)) ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- User ! {self(), not_connected, Reason},
- {stop, {shutdown, normal},
- next_packet(State#state{connection_state = Connection})};
- {disconnect, Reason, {{replies, Replies}, Connection}} ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- SSHOpts = proplists:get_value(ssh_opts, Opts),
- disconnect_fun(Reason, SSHOpts),
- {stop, {shutdown, normal}, State#state{connection_state = Connection}}
+ try
+ ssh_message:decode(Msg)
+ of
+ ConnectionMsg ->
+ State1 = generate_event_new_state(State0, EncData),
+ try ssh_connection:handle_msg(ConnectionMsg, Connection0, Role) of
+ {{replies, Replies0}, Connection} ->
+ if StateName == connected ->
+ Replies = Replies0,
+ State2 = State1;
+ true ->
+ {ConnReplies, Replies} =
+ lists:splitwith(fun not_connected_filter/1, Replies0),
+ Q = State1#state.event_queue ++ ConnReplies,
+ State2 = State1#state{ event_queue = Q }
+ end,
+ State = send_replies(Replies, State2#state{connection_state = Connection}),
+ {next_state, StateName, next_packet(State)};
+ {noreply, Connection} ->
+ {next_state, StateName, next_packet(State1#state{connection_state = Connection})};
+ {disconnect, {_, Reason}, {{replies, Replies}, Connection}} when
+ Role == client andalso ((StateName =/= connected) and (not Renegotiation)) ->
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ User ! {self(), not_connected, Reason},
+ {stop, {shutdown, normal},
+ next_packet(State#state{connection_state = Connection})};
+ {disconnect, _Reason, {{replies, Replies}, Connection}} ->
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ {stop, {shutdown, normal}, State#state{connection_state = Connection}}
+ catch
+ _:Error ->
+ {disconnect, _Reason, {{replies, Replies}, Connection}} =
+ ssh_connection:handle_msg(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "Internal error",
+ language = "en"}, Connection0, Role),
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ {stop, {shutdown, Error}, State#state{connection_state = Connection}}
+ end
+
catch
- _:Error ->
- {disconnect, Reason, {{replies, Replies}, Connection}} =
- ssh_connection:handle_msg(
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "Internal error",
- language = "en"}, Connection0, Role),
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- SSHOpts = proplists:get_value(ssh_opts, Opts),
- disconnect_fun(Reason, SSHOpts),
- {stop, {shutdown, Error}, State#state{connection_state = Connection}}
+ _:_ ->
+ handle_disconnect(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet received",
+ language = ""}, State0)
end;
generate_event(Msg, StateName, State0, EncData) ->
try
- Event = ssh_message:decode(Msg),
+ Event = ssh_message:decode(set_prefix_if_trouble(Msg,State0)),
State = generate_event_new_state(State0, EncData),
case Event of
#ssh_msg_kexinit{} ->
@@ -1334,7 +1470,7 @@ generate_event(Msg, StateName, State0, EncData) ->
event(Event, StateName, State)
end
catch
- _:_ ->
+ _C:_E ->
DisconnectMsg =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
description = "Encountered unexpected input",
@@ -1343,6 +1479,26 @@ generate_event(Msg, StateName, State0, EncData) ->
end.
+set_prefix_if_trouble(Msg = <<?BYTE(Op),_/binary>>, #state{ssh_params=SshParams})
+ when Op == 30;
+ Op == 31
+ ->
+ case catch atom_to_list(kex(SshParams)) of
+ "ecdh-sha2-" ++ _ ->
+ <<"ecdh",Msg/binary>>;
+ "diffie-hellman-group-exchange-" ++ _ ->
+ <<"dh_gex",Msg/binary>>;
+ "diffie-hellman-group" ++ _ ->
+ <<"dh",Msg/binary>>;
+ _ ->
+ Msg
+ end;
+set_prefix_if_trouble(Msg, _) ->
+ Msg.
+
+kex(#ssh{algorithms=#alg{kex=Kex}}) -> Kex;
+kex(_) -> undefined.
+
handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From,
#state{connection_state =
@@ -1437,6 +1593,7 @@ new_channel_id(#state{connection_state = #connection{channel_id_seed = Id} =
= State) ->
{Id, State#state{connection_state =
Connection#connection{channel_id_seed = Id + 1}}}.
+
generate_event_new_state(#state{ssh_params =
#ssh{recv_sequence = SeqNum0}
= Ssh} = State, EncData) ->
@@ -1467,66 +1624,43 @@ next_packet(#state{socket = Socket} = State) ->
State.
after_new_keys(#state{renegotiate = true} = State) ->
- {connected, State#state{renegotiate = false}};
+ State1 = State#state{renegotiate = false, event_queue = []},
+ lists:foldr(fun after_new_keys_events/2, {next_state, connected, State1}, State#state.event_queue);
after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = client} = Ssh0} = State) ->
{Msg, Ssh} = ssh_auth:service_request_msg(Ssh0),
send_msg(Msg, State),
- {userauth, State#state{ssh_params = Ssh}};
+ {next_state, service_request, State#state{ssh_params = Ssh}};
after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = server}} = State) ->
- {userauth, State}.
-
-handle_ssh_packet_data(RemainingSshPacketLen, DecData, EncData, StateName,
- State) ->
- EncSize = size(EncData),
- case RemainingSshPacketLen > EncSize of
- true ->
- {next_state, StateName,
- next_packet(State#state{decoded_data_buffer = DecData,
- encoded_data_buffer = EncData,
- undecoded_packet_length =
- RemainingSshPacketLen})};
- false ->
- handle_ssh_packet(RemainingSshPacketLen, StateName,
- State#state{decoded_data_buffer = DecData,
- encoded_data_buffer = EncData})
-
- end.
-
-handle_ssh_packet(Length, StateName, #state{decoded_data_buffer = DecData0,
- encoded_data_buffer = EncData0,
- ssh_params = Ssh0,
- transport_protocol = _Protocol,
- socket = _Socket} = State0) ->
- try
- {Ssh1, DecData, EncData, Mac} =
- ssh_transport:unpack(EncData0, Length, Ssh0),
- SshPacket = <<DecData0/binary, DecData/binary>>,
- case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of
- true ->
- PacketData = ssh_transport:msg_data(SshPacket),
- {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData),
- generate_event(Msg, StateName,
- State0#state{ssh_params = Ssh1,
- %% Important to be set for
- %% next_packet
- decoded_data_buffer = <<>>},
- EncData);
- false ->
- DisconnectMsg =
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad mac",
- language = "en"},
- handle_disconnect(DisconnectMsg, State0)
- end
- catch _:_ ->
- Disconnect =
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad input",
- language = "en"},
- handle_disconnect(Disconnect, State0)
- end.
+ {next_state, service_request, State}.
+
+after_new_keys_events({sync, _Event, From}, {stop, _Reason, _StateData}=Terminator) ->
+ gen_fsm:reply(From, {error, closed}),
+ Terminator;
+after_new_keys_events(_, {stop, _Reason, _StateData}=Terminator) ->
+ Terminator;
+after_new_keys_events({sync, Event, From}, {next_state, StateName, StateData}) ->
+ case handle_sync_event(Event, From, StateName, StateData) of
+ {reply, Reply, NextStateName, NewStateData} ->
+ gen_fsm:reply(From, Reply),
+ {next_state, NextStateName, NewStateData};
+ {next_state, NextStateName, NewStateData}->
+ {next_state, NextStateName, NewStateData};
+ {stop, Reason, Reply, NewStateData} ->
+ gen_fsm:reply(From, Reply),
+ {stop, Reason, NewStateData}
+ end;
+after_new_keys_events({event, Event}, {next_state, StateName, StateData}) ->
+ case handle_event(Event, StateName, StateData) of
+ {next_state, NextStateName, NewStateData}->
+ {next_state, NextStateName, NewStateData};
+ {stop, Reason, NewStateData} ->
+ {stop, Reason, NewStateData}
+ end;
+after_new_keys_events({connection_reply, _Data} = Reply, {StateName, State}) ->
+ NewState = send_replies([Reply], State),
+ {next_state, StateName, NewState}.
handle_disconnect(DisconnectMsg, State) ->
@@ -1537,12 +1671,14 @@ handle_disconnect(#ssh_msg_disconnect{} = DisconnectMsg, State, Error) ->
handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, role = Role} = State0) ->
{disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role),
State = send_replies(disconnect_replies(Type, Msg, Replies), State0),
+ disconnect_fun(Desc, State#state.opts),
{stop, {shutdown, Desc}, State#state{connection_state = Connection}}.
handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0,
role = Role} = State0, ErrorMsg) ->
{disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role),
State = send_replies(disconnect_replies(Type, Msg, Replies), State0),
+ disconnect_fun(Desc, State#state.opts),
{stop, {shutdown, {Desc, ErrorMsg}}, State#state{connection_state = Connection}}.
disconnect_replies(own, Msg, Replies) ->
@@ -1636,6 +1772,11 @@ log_error(Reason) ->
error_logger:error_report(Report),
"Internal error".
+not_connected_filter({connection_reply, _Data}) ->
+ true;
+not_connected_filter(_) ->
+ false.
+
send_replies([], State) ->
State;
send_replies([{connection_reply, Data} | Rest], #state{ssh_params = Ssh0} = State) ->
@@ -1656,6 +1797,8 @@ send_reply({flow_control, Cache, Channel, From, Msg}) ->
send_reply({flow_control, From, Msg}) ->
gen_fsm:reply(From, Msg).
+disconnect_fun({disconnect,Msg}, Opts) ->
+ disconnect_fun(Msg, Opts);
disconnect_fun(_, undefined) ->
ok;
disconnect_fun(Reason, Opts) ->
@@ -1666,6 +1809,15 @@ disconnect_fun(Reason, Opts) ->
catch Fun(Reason)
end.
+unexpected_fun(UnexpectedMessage, Opts, #ssh{peer={_,Peer}}) ->
+ case proplists:get_value(unexpectedfun, Opts) of
+ undefined ->
+ report;
+ Fun ->
+ catch Fun(UnexpectedMessage, Peer)
+ end.
+
+
check_cache(#state{opts = Opts} = State, Cache) ->
%% Check the number of entries in Cache
case proplists:get_value(size, ets:info(Cache)) of
diff --git a/lib/ssh/src/ssh_connection_sup.erl b/lib/ssh/src/ssh_connection_sup.erl
index c5abc8f23b..e8d0d49668 100644
--- a/lib/ssh/src/ssh_connection_sup.erl
+++ b/lib/ssh/src/ssh_connection_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/src/ssh_daemon_channel.erl b/lib/ssh/src/ssh_daemon_channel.erl
index ab3efbcaff..560e8246de 100644
--- a/lib/ssh/src/ssh_daemon_channel.erl
+++ b/lib/ssh/src/ssh_daemon_channel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index 5692138a8a..3e066c453d 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -51,8 +52,20 @@ host_key(Algorithm, Opts) ->
%% so probably we could hardcod Password = ignore, but
%% we keep it as an undocumented option for now.
Password = proplists:get_value(identity_pass_phrase(Algorithm), Opts, ignore),
- decode(File, Password).
-
+ case decode(File, Password) of
+ {ok,Key} ->
+ case {Key,Algorithm} of
+ {#'RSAPrivateKey'{}, 'ssh-rsa'} -> {ok,Key};
+ {#'DSAPrivateKey'{}, 'ssh-dss'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp256r1'}}, 'ecdsa-sha2-nistp256'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp384r1'}}, 'ecdsa-sha2-nistp384'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp521r1'}}, 'ecdsa-sha2-nistp521'} -> {ok,Key};
+ _ ->
+ {error,bad_keytype_in_file}
+ end;
+ Other ->
+ Other
+ end.
is_auth_key(Key, User,Opts) ->
case lookup_user_key(Key, User, Opts) of
@@ -80,16 +93,15 @@ user_key(Algorithm, Opts) ->
%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-file_base_name('ssh-rsa') ->
- "ssh_host_rsa_key";
-file_base_name('ssh-dss') ->
- "ssh_host_dsa_key";
-file_base_name(_) ->
- "ssh_host_key".
+file_base_name('ssh-rsa' ) -> "ssh_host_rsa_key";
+file_base_name('ssh-dss' ) -> "ssh_host_dsa_key";
+file_base_name('ecdsa-sha2-nistp256') -> "ssh_host_ecdsa_key";
+file_base_name('ecdsa-sha2-nistp384') -> "ssh_host_ecdsa_key";
+file_base_name('ecdsa-sha2-nistp521') -> "ssh_host_ecdsa_key";
+file_base_name(_ ) -> "ssh_host_key".
decode(File, Password) ->
- try
- {ok, decode_ssh_file(read_ssh_file(File), Password)}
+ try {ok, decode_ssh_file(read_ssh_file(File), Password)}
catch
throw:Reason ->
{error, Reason};
@@ -209,29 +221,32 @@ do_lookup_host_key(KeyToMatch, Host, Alg, Opts) ->
{ok, Fd} ->
Res = lookup_host_key_fd(Fd, KeyToMatch, Host, Alg),
file:close(Fd),
- {ok, Res};
- {error, enoent} -> {error, not_found};
- Error -> Error
+ Res;
+ {error, enoent} ->
+ {error, not_found};
+ Error ->
+ Error
end.
-identity_key_filename('ssh-dss') ->
- "id_dsa";
-identity_key_filename('ssh-rsa') ->
- "id_rsa".
-
-identity_pass_phrase("ssh-dss") ->
- dsa_pass_phrase;
-identity_pass_phrase('ssh-dss') ->
- dsa_pass_phrase;
-identity_pass_phrase('ssh-rsa') ->
- rsa_pass_phrase;
-identity_pass_phrase("ssh-rsa") ->
- rsa_pass_phrase.
-
+identity_key_filename('ssh-dss' ) -> "id_dsa";
+identity_key_filename('ssh-rsa' ) -> "id_rsa";
+identity_key_filename('ecdsa-sha2-nistp256') -> "id_ecdsa";
+identity_key_filename('ecdsa-sha2-nistp384') -> "id_ecdsa";
+identity_key_filename('ecdsa-sha2-nistp521') -> "id_ecdsa".
+
+identity_pass_phrase("ssh-dss" ) -> dsa_pass_phrase;
+identity_pass_phrase("ssh-rsa" ) -> rsa_pass_phrase;
+identity_pass_phrase("ecdsa-sha2-"++_) -> ecdsa_pass_phrase;
+identity_pass_phrase(P) when is_atom(P) ->
+ identity_pass_phrase(atom_to_list(P)).
+
lookup_host_key_fd(Fd, KeyToMatch, Host, KeyType) ->
case io:get_line(Fd, '') of
eof ->
{error, not_found};
+ {error,Error} ->
+ %% Rare... For example NFS errors
+ {error,Error};
Line ->
case ssh_decode_line(Line, known_hosts) of
[{Key, Attributes}] ->
@@ -252,7 +267,7 @@ handle_host(Fd, KeyToMatch, Host, HostList, Key, KeyType) ->
Host1 = host_name(Host),
case lists:member(Host1, HostList) andalso key_match(Key, KeyType) of
true when KeyToMatch == Key ->
- Key;
+ {ok,Key};
_ ->
lookup_host_key_fd(Fd, KeyToMatch, Host, KeyType)
end.
@@ -266,6 +281,13 @@ key_match(#'RSAPublicKey'{}, 'ssh-rsa') ->
true;
key_match({_, #'Dss-Parms'{}}, 'ssh-dss') ->
true;
+key_match({#'ECPoint'{},{namedCurve,Curve}}, Alg) ->
+ case atom_to_list(Alg) of
+ "ecdsa-sha2-"++IdS ->
+ Curve == public_key:ssh_curvename2oid(list_to_binary(IdS));
+ _ ->
+ false
+ end;
key_match(_, _) ->
false.
@@ -292,6 +314,9 @@ lookup_user_key_fd(Fd, Key) ->
case io:get_line(Fd, '') of
eof ->
{error, not_found};
+ {error,Error} ->
+ %% Rare... For example NFS errors
+ {error,Error};
Line ->
case ssh_decode_line(Line, auth_keys) of
[{AuthKey, _}] ->
@@ -311,8 +336,18 @@ is_auth_key(Key, Key) ->
is_auth_key(_,_) ->
false.
-default_user_dir()->
- {ok,[[Home|_]]} = init:get_argument(home),
+
+default_user_dir() ->
+ try
+ default_user_dir(os:getenv("HOME"))
+ catch
+ _:_ ->
+ default_user_dir(init:get_argument(home))
+ end.
+
+default_user_dir({ok,[[Home|_]]}) ->
+ default_user_dir(Home);
+default_user_dir(Home) when is_list(Home) ->
UserDir = filename:join(Home, ".ssh"),
ok = filelib:ensure_dir(filename:join(UserDir, "dummy")),
{ok,Info} = file:read_file_info(UserDir),
diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl
index 30df32c4fd..4e6e25bc70 100644
--- a/lib/ssh/src/ssh_info.erl
+++ b/lib/ssh/src/ssh_info.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -79,7 +80,7 @@ print_clients(D) ->
print_client(D, {undefined,Pid,supervisor,[ssh_connection_handler]}) ->
{{Local,Remote},_Str} = ssh_connection_handler:get_print_info(Pid),
- io:format(D, " Local=~s Remote=~s~n",[fmt_host_port(Local),fmt_host_port(Remote)]);
+ io:format(D, " Local=~s Remote=~s ConnectionRef=~p~n",[fmt_host_port(Local),fmt_host_port(Remote),Pid]);
print_client(D, Other) ->
io:format(D, " [[Other 1: ~p]]~n",[Other]).
@@ -134,10 +135,11 @@ walk_sups(D, StartPid) ->
io:format(D, "Start at ~p, ~s.~n",[StartPid,dead_or_alive(StartPid)]),
walk_sups(D, children(StartPid), _Indent=?inc(0)).
-walk_sups(D, [H={_,Pid,SupOrWorker,_}|T], Indent) ->
+walk_sups(D, [H={_,Pid,_,_}|T], Indent) ->
indent(D, Indent), io:format(D, '~200p ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]),
- case SupOrWorker of
- supervisor -> walk_sups(D, children(Pid), ?inc(Indent));
+ case H of
+ {_,_,supervisor,[ssh_connection_handler]} -> ok;
+ {_,Pid,supervisor,_} -> walk_sups(D, children(Pid), ?inc(Indent));
_ -> ok
end,
walk_sups(D, T, Indent);
@@ -187,7 +189,7 @@ line(D, Len, Char) ->
datetime() ->
- {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(now()),
+ {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(erlang:timestamp()),
lists:flatten(io_lib:format('~4w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w UTC',[YYYY,MM,DD, H,M,S])).
diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl
index 97e2dee27a..a5e627fdb3 100644
--- a/lib/ssh/src/ssh_io.erl
+++ b/lib/ssh/src/ssh_io.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_math.erl b/lib/ssh/src/ssh_math.erl
deleted file mode 100644
index 569c1cb58d..0000000000
--- a/lib/ssh/src/ssh_math.erl
+++ /dev/null
@@ -1,41 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-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%
-%%
-
-%%
-
-%%% Description: SSH math utilities
-
--module(ssh_math).
-
--export([ipow/3]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%
-%% INTEGER utils
-%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% calculate A^B mod M
-ipow(A, B, M) when M > 0, B >= 0 ->
- crypto:bytes_to_integer(crypto:mod_pow(A, B, M)).
-
-
-
-
-
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 66e7717095..b6c4496be2 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,7 @@
-include("ssh_auth.hrl").
-include("ssh_transport.hrl").
--export([encode/1, decode/1, encode_host_key/1, decode_keyboard_interactive_prompts/2]).
+-export([encode/1, decode/1, decode_keyboard_interactive_prompts/2]).
encode(#ssh_msg_global_request{
name = Name,
@@ -226,8 +227,8 @@ encode(#ssh_msg_kexdh_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Signature),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Signature),
ssh_bits:encode([?SSH_MSG_KEXDH_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_kex_dh_gex_request{
@@ -236,7 +237,7 @@ encode(#ssh_msg_kex_dh_gex_request{
max = Max
}) ->
ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REQUEST, Min, N, Max],
- [byte, uint32, uint32, uint32, uint32]);
+ [byte, uint32, uint32, uint32]);
encode(#ssh_msg_kex_dh_gex_request_old{n = N}) ->
ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REQUEST_OLD, N],
[byte, uint32]);
@@ -254,9 +255,17 @@ encode(#ssh_msg_kex_dh_gex_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Signature),
- ssh_bits:encode([?SSH_MSG_KEXDH_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Signature),
+ ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
+
+encode(#ssh_msg_kex_ecdh_init{q_c = Q_c}) ->
+ ssh_bits:encode([?SSH_MSG_KEX_ECDH_INIT, Q_c], [byte, mpint]);
+
+encode(#ssh_msg_kex_ecdh_reply{public_host_key = Key, q_s = Q_s, h_sig = Sign}) ->
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Sign),
+ ssh_bits:encode([?SSH_MSG_KEX_ECDH_REPLY, EncKey, Q_s, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_ignore{data = Data}) ->
ssh_bits:encode([?SSH_MSG_IGNORE, Data], [byte, string]);
@@ -271,8 +280,7 @@ encode(#ssh_msg_debug{always_display = Bool,
%% Connection Messages
-decode(<<?BYTE(?SSH_MSG_GLOBAL_REQUEST), ?UINT32(Len), Name:Len/binary,
- ?BYTE(Bool), Data/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_GLOBAL_REQUEST), ?DEC_BIN(Name,__0), ?BYTE(Bool), Data/binary>>) ->
#ssh_msg_global_request{
name = Name,
want_reply = erl_boolean(Bool),
@@ -283,8 +291,7 @@ decode(<<?BYTE(?SSH_MSG_REQUEST_SUCCESS), Data/binary>>) ->
decode(<<?BYTE(?SSH_MSG_REQUEST_FAILURE)>>) ->
#ssh_msg_request_failure{};
decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN),
- ?UINT32(Len), Type:Len/binary,
- ?UINT32(Sender), ?UINT32(Window), ?UINT32(Max),
+ ?DEC_BIN(Type,__0), ?UINT32(Sender), ?UINT32(Window), ?UINT32(Max),
Data/binary>>) ->
#ssh_msg_channel_open{
channel_type = binary_to_list(Type),
@@ -304,7 +311,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN_CONFIRMATION), ?UINT32(Recipient), ?UINT32(
data = Data
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN_FAILURE), ?UINT32(Recipient), ?UINT32(Reason),
- ?UINT32(Len0), Desc:Len0/binary, ?UINT32(Len1), Lang:Len1/binary >>) ->
+ ?DEC_BIN(Desc,__0), ?DEC_BIN(Lang,__1) >> ) ->
#ssh_msg_channel_open_failure{
recipient_channel = Recipient,
reason = Reason,
@@ -317,13 +324,13 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_WINDOW_ADJUST), ?UINT32(Recipient), ?UINT32(Byte
bytes_to_add = Bytes
};
-decode(<<?BYTE(?SSH_MSG_CHANNEL_DATA), ?UINT32(Recipient), ?UINT32(Len), Data:Len/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_CHANNEL_DATA), ?UINT32(Recipient), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_channel_data{
recipient_channel = Recipient,
data = Data
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_EXTENDED_DATA), ?UINT32(Recipient),
- ?UINT32(DataType), ?UINT32(Len), Data:Len/binary>>) ->
+ ?UINT32(DataType), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_channel_extended_data{
recipient_channel = Recipient,
data_type_code = DataType,
@@ -338,8 +345,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_CLOSE), ?UINT32(Recipient)>>) ->
recipient_channel = Recipient
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_REQUEST), ?UINT32(Recipient),
- ?UINT32(Len), RequestType:Len/binary,
- ?BYTE(Bool), Data/binary>>) ->
+ ?DEC_BIN(RequestType,__0), ?BYTE(Bool), Data/binary>>) ->
#ssh_msg_channel_request{
recipient_channel = Recipient,
request_type = unicode:characters_to_list(RequestType),
@@ -357,9 +363,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_FAILURE), ?UINT32(Recipient)>>) ->
%%% Auth Messages
decode(<<?BYTE(?SSH_MSG_USERAUTH_REQUEST),
- ?UINT32(Len0), User:Len0/binary,
- ?UINT32(Len1), Service:Len1/binary,
- ?UINT32(Len2), Method:Len2/binary,
+ ?DEC_BIN(User,__0), ?DEC_BIN(Service,__1), ?DEC_BIN(Method,__2),
Data/binary>>) ->
#ssh_msg_userauth_request{
user = unicode:characters_to_list(User),
@@ -369,7 +373,7 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_REQUEST),
};
decode(<<?BYTE(?SSH_MSG_USERAUTH_FAILURE),
- ?UINT32(Len0), Auths:Len0/binary,
+ ?DEC_BIN(Auths,__0),
?BYTE(Bool)>>) ->
#ssh_msg_userauth_failure {
authentications = unicode:characters_to_list(Auths),
@@ -379,16 +383,14 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_FAILURE),
decode(<<?BYTE(?SSH_MSG_USERAUTH_SUCCESS)>>) ->
#ssh_msg_userauth_success{};
-decode(<<?BYTE(?SSH_MSG_USERAUTH_BANNER),
- ?UINT32(Len0), Banner:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_BANNER), ?DEC_BIN(Banner,__0), ?DEC_BIN(Lang,__1) >>) ->
#ssh_msg_userauth_banner{
message = Banner,
language = Lang
};
-decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
- ?UINT32(Len1), Inst:Len1/binary, ?UINT32(Len2), Lang:Len2/binary,
+decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST),
+ ?DEC_BIN(Name,__0), ?DEC_BIN(Inst,__1), ?DEC_BIN(Lang,__2),
?UINT32(NumPromtps), Data/binary>>) ->
#ssh_msg_userauth_info_request{
name = Name,
@@ -398,15 +400,14 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
data = Data};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?UINT32(Len0), Prompt:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?DEC_BIN(Prompt,__0), ?DEC_BIN(Lang,__1) >>) ->
#ssh_msg_userauth_passwd_changereq{
prompt = Prompt,
languge = Lang
};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?UINT32(Len), Alg:Len/binary, KeyBlob/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?DEC_BIN(Alg,__0), KeyBlob/binary>>) ->
#ssh_msg_userauth_pk_ok{
algorithm_name = Alg,
key_blob = KeyBlob
@@ -421,47 +422,71 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_RESPONSE), ?UINT32(Num), Data/binary>>) ->
decode(<<?BYTE(?SSH_MSG_KEXINIT), Cookie:128, Data/binary>>) ->
decode_kex_init(Data, [Cookie, ssh_msg_kexinit], 10);
-decode(<<?BYTE(?SSH_MSG_KEXDH_INIT), ?UINT32(Len), E:Len/binary>>) ->
- #ssh_msg_kexdh_init{e = erlint(Len, E)
+decode(<<"dh",?BYTE(?SSH_MSG_KEXDH_INIT), ?DEC_MPINT(E,__0)>>) ->
+ #ssh_msg_kexdh_init{e = E
};
+
+decode(<<"dh", ?BYTE(?SSH_MSG_KEXDH_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
+ #ssh_msg_kexdh_reply{
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
+ f = F,
+ h_sig = decode_signature(Hashsign)
+ };
+
decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST), ?UINT32(Min), ?UINT32(N), ?UINT32(Max)>>) ->
#ssh_msg_kex_dh_gex_request{
min = Min,
n = N,
max = Max
};
-decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST_OLD), ?UINT32(N)>>) ->
+
+decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST_OLD), ?UINT32(N)>>) ->
#ssh_msg_kex_dh_gex_request_old{
n = N
};
-decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_GROUP),
- ?UINT32(Len0), Prime:Len0/big-signed-integer-unit:8,
- ?UINT32(Len1), Generator:Len1/big-signed-integer-unit:8>>) ->
+
+decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_GROUP), ?DEC_MPINT(Prime,__0), ?DEC_MPINT(Generator,__1) >>) ->
#ssh_msg_kex_dh_gex_group{
p = Prime,
g = Generator
};
-decode(<<?BYTE(?SSH_MSG_KEXDH_REPLY), ?UINT32(Len0), Key:Len0/binary,
- ?UINT32(Len1), F:Len1/binary,
- ?UINT32(Len2), Hashsign:Len2/binary>>) ->
- #ssh_msg_kexdh_reply{
- public_host_key = decode_host_key(Key),
- f = erlint(Len1, F),
- h_sig = decode_sign(Hashsign)
+
+decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_INIT), ?DEC_MPINT(E,__0)>>) ->
+ #ssh_msg_kex_dh_gex_init{
+ e = E
+ };
+
+decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
+ #ssh_msg_kex_dh_gex_reply{
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
+ f = F,
+ h_sig = decode_signature(Hashsign)
};
-decode(<<?SSH_MSG_SERVICE_REQUEST, ?UINT32(Len0), Service:Len0/binary>>) ->
+decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_INIT), ?DEC_MPINT(Q_c,__0)>>) ->
+ #ssh_msg_kex_ecdh_init{
+ q_c = Q_c
+ };
+
+decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_REPLY),
+ ?DEC_BIN(Key,__1), ?DEC_MPINT(Q_s,__2), ?DEC_BIN(Sig,__3)>>) ->
+ #ssh_msg_kex_ecdh_reply{
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
+ q_s = Q_s,
+ h_sig = decode_signature(Sig)
+ };
+
+decode(<<?SSH_MSG_SERVICE_REQUEST, ?DEC_BIN(Service,__0)>>) ->
#ssh_msg_service_request{
name = unicode:characters_to_list(Service)
};
-decode(<<?SSH_MSG_SERVICE_ACCEPT, ?UINT32(Len0), Service:Len0/binary>>) ->
+decode(<<?SSH_MSG_SERVICE_ACCEPT, ?DEC_BIN(Service,__0)>>) ->
#ssh_msg_service_accept{
name = unicode:characters_to_list(Service)
};
-decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
- ?UINT32(Len0), Desc:Len0/binary, ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code), ?DEC_BIN(Desc,__0), ?DEC_BIN(Lang,__1)>>) ->
#ssh_msg_disconnect{
code = Code,
description = unicode:characters_to_list(Desc),
@@ -469,8 +494,7 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
};
%% Accept bad disconnects from ancient openssh clients that doesn't send language tag. Use english as a work-around.
-decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
- ?UINT32(Len0), Desc:Len0/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code), ?DEC_BIN(Desc,__0)>>) ->
#ssh_msg_disconnect{
code = Code,
description = unicode:characters_to_list(Desc),
@@ -480,21 +504,25 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
decode(<<?SSH_MSG_NEWKEYS>>) ->
#ssh_msg_newkeys{};
-decode(<<?BYTE(?SSH_MSG_IGNORE), ?UINT32(Len), Data:Len/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_IGNORE), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_ignore{data = Data};
decode(<<?BYTE(?SSH_MSG_UNIMPLEMENTED), ?UINT32(Seq)>>) ->
#ssh_msg_unimplemented{sequence = Seq};
-decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?UINT32(Len0), Msg:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?DEC_BIN(Msg,__0), ?DEC_BIN(Lang,__1)>>) ->
#ssh_msg_debug{always_display = erl_boolean(Bool),
message = Msg,
language = Lang}.
+%%%================================================================
+%%%
+%%% Helper functions
+%%%
+
decode_keyboard_interactive_prompts(<<>>, Acc) ->
lists:reverse(Acc);
-decode_keyboard_interactive_prompts(<<?UINT32(Len), Prompt:Len/binary, ?BYTE(Bool), Bin/binary>>,
+decode_keyboard_interactive_prompts(<<?DEC_BIN(Prompt,__0), ?BYTE(Bool), Bin/binary>>,
Acc) ->
decode_keyboard_interactive_prompts(Bin, [{Prompt, erl_boolean(Bool)} | Acc]).
@@ -510,45 +538,25 @@ decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) ->
%% See rfc 4253 7.1
X = 0,
list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
-decode_kex_init(<<?UINT32(Len), Data:Len/binary, Rest/binary>>, Acc, N) ->
+decode_kex_init(<<?DEC_BIN(Data,__0), Rest/binary>>, Acc, N) ->
Names = string:tokens(unicode:characters_to_list(Data), ","),
decode_kex_init(Rest, [Names | Acc], N -1).
-erlint(MPIntSize, MPIntValue) ->
- Bits = MPIntSize * 8,
- <<Integer:Bits/integer>> = MPIntValue,
- Integer.
-decode_sign(<<?UINT32(Len), _Alg:Len/binary, ?UINT32(_), Signature/binary>>) ->
+%%%================================================================
+%%%
+%%% Signature decode/encode
+%%%
+
+decode_signature(<<?DEC_BIN(_Alg,__0), ?UINT32(_), Signature/binary>>) ->
Signature.
-decode_host_key(<<?UINT32(Len), Alg:Len/binary, Rest/binary>>) ->
- decode_host_key(Alg, Rest).
-
-decode_host_key(<<"ssh-rsa">>, <<?UINT32(Len0), E:Len0/binary,
- ?UINT32(Len1), N:Len1/binary>>) ->
- #'RSAPublicKey'{publicExponent = erlint(Len0, E),
- modulus = erlint(Len1, N)};
-
-decode_host_key(<<"ssh-dss">>,
- <<?UINT32(Len0), P:Len0/binary,
- ?UINT32(Len1), Q:Len1/binary,
- ?UINT32(Len2), G:Len2/binary,
- ?UINT32(Len3), Y:Len3/binary>>) ->
- {erlint(Len3, Y), #'Dss-Parms'{p = erlint(Len0, P), q = erlint(Len1, Q),
- g = erlint(Len2, G)}}.
-
-encode_host_key(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]);
-encode_host_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]).
-encode_sign(#'RSAPrivateKey'{}, Signature) ->
+
+encode_signature(#'RSAPublicKey'{}, Signature) ->
ssh_bits:encode(["ssh-rsa", Signature],[string, binary]);
-encode_sign(#'DSAPrivateKey'{}, Signature) ->
- ssh_bits:encode(["ssh-dss", Signature],[string, binary]).
+encode_signature({_, #'Dss-Parms'{}}, Signature) ->
+ ssh_bits:encode(["ssh-dss", Signature],[string, binary]);
+encode_signature({#'ECPoint'{}, {namedCurve,OID}}, Signature) ->
+ CurveName = public_key:oid2ssh_curvename(OID),
+ ssh_bits:encode([<<"ecdsa-sha2-",CurveName/binary>>, Signature], [binary,binary]).
+
diff --git a/lib/ssh/src/ssh_no_io.erl b/lib/ssh/src/ssh_no_io.erl
index 825a0d4af5..e8d1afd0ed 100644
--- a/lib/ssh/src/ssh_no_io.erl
+++ b/lib/ssh/src/ssh_no_io.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/src/ssh_server_key.erl b/lib/ssh/src/ssh_server_key.erl
index 8140114990..4ab326374a 100644
--- a/lib/ssh/src/ssh_server_key.erl
+++ b/lib/ssh/src/ssh_server_key.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_server_key_api.erl b/lib/ssh/src/ssh_server_key_api.erl
index 4fd660ecb5..7c05d82c03 100644
--- a/lib/ssh/src/ssh_server_key_api.erl
+++ b/lib/ssh/src/ssh_server_key_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index 613f8f25b2..dbacf730cc 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -111,7 +112,7 @@ start_channel(Cm, Opts) when is_pid(Cm) ->
TimeOut
end;
{error, Reason} ->
- {error, Reason};
+ {error, format_channel_start_error(Reason)};
ignore ->
{error, ignore}
end;
@@ -136,7 +137,7 @@ start_channel(Host, Port, Opts) ->
TimeOut
end;
{error, Reason} ->
- {error, Reason};
+ {error, format_channel_start_error(Reason)};
ignore ->
{error, ignore}
end;
@@ -438,7 +439,7 @@ write_file(Pid, Name, List) ->
write_file(Pid, Name, List, ?FILEOP_TIMEOUT).
write_file(Pid, Name, List, FileOpTimeout) when is_list(List) ->
- write_file(Pid, Name, unicode:characters_to_binary(List), FileOpTimeout);
+ write_file(Pid, Name, list_to_binary(List), FileOpTimeout);
write_file(Pid, Name, Bin, FileOpTimeout) ->
case open(Pid, Name, [write, binary], FileOpTimeout) of
{ok, Handle} ->
@@ -491,9 +492,9 @@ init([Cm, ChannelId, Options]) ->
inf = new_inf(),
opts = Options}};
failure ->
- {stop, "server failed to start sftp subsystem"};
+ {stop, {shutdown, "server failed to start sftp subsystem"}};
Error ->
- {stop, Error}
+ {stop, {shutdown, Error}}
end.
%%--------------------------------------------------------------------
@@ -508,12 +509,12 @@ init([Cm, ChannelId, Options]) ->
%%--------------------------------------------------------------------
handle_call({{timeout, infinity}, wait_for_version_negotiation}, From,
#state{xf = #ssh_xfer{vsn = undefined} = Xf} = State) ->
- {noreply, State#state{xf = Xf#ssh_xfer{vsn = From}}};
+ {noreply, State#state{xf = Xf#ssh_xfer{vsn = {wait, From, undefined}}}};
handle_call({{timeout, Timeout}, wait_for_version_negotiation}, From,
#state{xf = #ssh_xfer{vsn = undefined} = Xf} = State) ->
- timer:send_after(Timeout, {timeout, undefined, From}),
- {noreply, State#state{xf = Xf#ssh_xfer{vsn = From}}};
+ TRef = erlang:send_after(Timeout, self(), {timeout, undefined, From}),
+ {noreply, State#state{xf = Xf#ssh_xfer{vsn = {wait, From, TRef}}}};
handle_call({_, wait_for_version_negotiation}, _, State) ->
{reply, ok, State};
@@ -610,8 +611,7 @@ do_handle_call({pread,Async,Handle,At,Length}, From, State) ->
fun({ok,Data}, State2) ->
case get_mode(Handle, State2) of
binary -> {{ok,Data}, State2};
- text ->
- {{ok,unicode:characters_to_list(Data)}, State2}
+ text -> {{ok,binary_to_list(Data)}, State2}
end;
(Rep, State2) ->
{Rep, State2}
@@ -865,7 +865,12 @@ do_handle_reply(#state{xf = Xf} = State,
case Xf#ssh_xfer.vsn of
undefined ->
ok;
- From ->
+ {wait, From, TRef} ->
+ if is_reference(TRef) ->
+ erlang:cancel_timer(TRef);
+ true ->
+ ok
+ end,
ssh_channel:reply(From, ok)
end,
State#state{xf = Xf#ssh_xfer{vsn = Version, ext = Ext}, rep_buf = Rest};
@@ -1412,3 +1417,8 @@ open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, ChunkSize) ->
BufHandle = make_ref(),
call(Pid, {put_bufinf,BufHandle,BufInfo}, FileOpTimeout),
{ok,BufHandle}.
+
+format_channel_start_error({shutdown, Reason}) ->
+ Reason;
+format_channel_start_error(Reason) ->
+ Reason.
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 04ae6b11e2..819cba697e 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,6 +30,7 @@
-include("ssh.hrl").
-include("ssh_xfer.hrl").
+-include("ssh_connect.hrl"). %% For ?DEFAULT_PACKET_SIZE and ?DEFAULT_WINDOW_SIZE
%%--------------------------------------------------------------------
%% External exports
@@ -46,6 +48,7 @@
file_handler, % atom() - callback module
file_state, % state for the file callback module
max_files, % integer >= 0 max no files sent during READDIR
+ options, % from the subsystem declaration
handles % list of open handles
%% handle is either {<int>, directory, {Path, unread|eof}} or
%% {<int>, file, {Path, IoDevice}}
@@ -120,6 +123,7 @@ init(Options) ->
MaxLength = proplists:get_value(max_files, Options, 0),
Vsn = proplists:get_value(sftpd_vsn, Options, 5),
{ok, State#state{cwd = CWD, root = Root, max_files = MaxLength,
+ options = Options,
handles = [], pending = <<>>,
xf = #ssh_xfer{vsn = Vsn, ext = []}}}.
@@ -163,7 +167,9 @@ handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State) ->
%% Description: Handles other messages
%%--------------------------------------------------------------------
handle_msg({ssh_channel_up, ChannelId, ConnectionManager},
- #state{xf =Xf} = State) ->
+ #state{xf = Xf,
+ options = Options} = State) ->
+ maybe_increase_recv_window(ConnectionManager, ChannelId, Options),
{ok, State#state{xf = Xf#ssh_xfer{cm = ConnectionManager,
channel = ChannelId}}}.
@@ -933,3 +939,18 @@ rename(Path, Path2, ReqId, State0) ->
{Status, FS1} = FileMod:rename(Path, Path2, FS0),
State1 = State0#state{file_state = FS1},
send_status(Status, ReqId, State1).
+
+
+maybe_increase_recv_window(ConnectionManager, ChannelId, Options) ->
+ WantedRecvWindowSize =
+ proplists:get_value(recv_window_size, Options, 1000000),
+ NumPkts = WantedRecvWindowSize div ?DEFAULT_PACKET_SIZE,
+ Increment = NumPkts*?DEFAULT_PACKET_SIZE - ?DEFAULT_WINDOW_SIZE,
+
+ if
+ Increment > 0 ->
+ ssh_connection:adjust_window(ConnectionManager, ChannelId,
+ Increment);
+ Increment =< 0 ->
+ do_nothing
+ end.
diff --git a/lib/ssh/src/ssh_sftpd_file.erl b/lib/ssh/src/ssh_sftpd_file.erl
index 91ba228e38..a287e8891b 100644
--- a/lib/ssh/src/ssh_sftpd_file.erl
+++ b/lib/ssh/src/ssh_sftpd_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_sftpd_file_api.erl b/lib/ssh/src/ssh_sftpd_file_api.erl
index 83d90907f5..c61d4e7ecf 100644
--- a/lib/ssh/src/ssh_sftpd_file_api.erl
+++ b/lib/ssh/src/ssh_sftpd_file_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/src/ssh_shell.erl b/lib/ssh/src/ssh_shell.erl
index 8031450617..22ad4da948 100644
--- a/lib/ssh/src/ssh_shell.erl
+++ b/lib/ssh/src/ssh_shell.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_subsystem_sup.erl b/lib/ssh/src/ssh_subsystem_sup.erl
index e8855b09ac..ebe33ec7da 100644
--- a/lib/ssh/src/ssh_subsystem_sup.erl
+++ b/lib/ssh/src/ssh_subsystem_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_sup.erl b/lib/ssh/src/ssh_sup.erl
index 6d2b9c107d..649ea00a06 100644
--- a/lib/ssh/src/ssh_sup.erl
+++ b/lib/ssh/src/ssh_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index 660fe8bb65..18a5d8071a 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,13 +29,15 @@
-behaviour(supervisor).
+-include("ssh.hrl").
+
-export([start_link/1, stop_listener/1,
- stop_listener/2, stop_system/1,
- stop_system/2, system_supervisor/2,
+ stop_listener/3, stop_system/1,
+ stop_system/3, system_supervisor/3,
subsystem_supervisor/1, channel_supervisor/1,
connection_supervisor/1,
- acceptor_supervisor/1, start_subsystem/2, restart_subsystem/2,
- restart_acceptor/2, stop_subsystem/2]).
+ acceptor_supervisor/1, start_subsystem/2, restart_subsystem/3,
+ restart_acceptor/3, stop_subsystem/2]).
%% Supervisor callback
-export([init/1]).
@@ -45,14 +48,15 @@
start_link(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- Name = make_name(Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = make_name(Address, Port, Profile),
supervisor:start_link({local, Name}, ?MODULE, [ServerOpts]).
stop_listener(SysSup) ->
stop_acceptor(SysSup).
-stop_listener(Address, Port) ->
- Name = make_name(Address, Port),
+stop_listener(Address, Port, Profile) ->
+ Name = make_name(Address, Port, Profile),
stop_acceptor(whereis(Name)).
stop_system(SysSup) ->
@@ -60,12 +64,12 @@ stop_system(SysSup) ->
spawn(fun() -> sshd_sup:stop_child(Name) end),
ok.
-stop_system(Address, Port) ->
- spawn(fun() -> sshd_sup:stop_child(Address, Port) end),
+stop_system(Address, Port, Profile) ->
+ spawn(fun() -> sshd_sup:stop_child(Address, Port, Profile) end),
ok.
-system_supervisor(Address, Port) ->
- Name = make_name(Address, Port),
+system_supervisor(Address, Port, Profile) ->
+ Name = make_name(Address, Port, Profile),
whereis(Name).
subsystem_supervisor(SystemSup) ->
@@ -103,9 +107,9 @@ stop_subsystem(SystemSup, SubSys) ->
end.
-restart_subsystem(Address, Port) ->
- SysSupName = make_name(Address, Port),
- SubSysName = id(ssh_subsystem_sup, Address, Port),
+restart_subsystem(Address, Port, Profile) ->
+ SysSupName = make_name(Address, Port, Profile),
+ SubSysName = id(ssh_subsystem_sup, Address, Port, Profile),
case supervisor:terminate_child(SysSupName, SubSysName) of
ok ->
supervisor:restart_child(SysSupName, SubSysName);
@@ -113,9 +117,9 @@ restart_subsystem(Address, Port) ->
Error
end.
-restart_acceptor(Address, Port) ->
- SysSupName = make_name(Address, Port),
- AcceptorName = id(ssh_acceptor_sup, Address, Port),
+restart_acceptor(Address, Port, Profile) ->
+ SysSupName = make_name(Address, Port, Profile),
+ AcceptorName = id(ssh_acceptor_sup, Address, Port, Profile),
supervisor:restart_child(SysSupName, AcceptorName).
%%%=========================================================================
@@ -137,7 +141,8 @@ child_specs(ServerOpts) ->
ssh_acceptor_child_spec(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- Name = id(ssh_acceptor_sup, Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = id(ssh_acceptor_sup, Address, Port, Profile),
StartFunc = {ssh_acceptor_sup, start_link, [ServerOpts]},
Restart = transient,
Shutdown = infinity,
@@ -155,12 +160,23 @@ ssh_subsystem_child_spec(ServerOpts) ->
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Sup, Address, Port) ->
- {Sup, Address, Port}.
-
-make_name(Address, Port) ->
- list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_sup",
- [Address, Port]))).
+id(Sup, Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ {Sup, any, Port, Profile};
+ false ->
+ {Sup, Address, Port, Profile}
+ end.
+
+make_name(Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_~p_sup",
+ [any, Port, Profile])));
+ false ->
+ list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_~p_sup",
+ [Address, Port, Profile])))
+ end.
ssh_subsystem_sup([{_, Child, _, [ssh_subsystem_sup]} | _]) ->
Child;
@@ -178,3 +194,4 @@ stop_acceptor(Sup) ->
supervisor:which_children(Sup)],
supervisor:terminate_child(AcceptorSup, Name).
+
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 6c0873fd9e..18037b8461 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,18 +31,109 @@
-include("ssh.hrl").
-export([versions/2, hello_version_msg/1]).
--export([next_seqnum/1, decrypt_first_block/2, decrypt_blocks/3,
- is_valid_mac/3,
+-export([next_seqnum/1,
+ supported_algorithms/0, supported_algorithms/1,
+ default_algorithms/0, default_algorithms/1,
+ handle_packet_part/4,
handle_hello_version/1,
key_exchange_init_msg/1,
key_init/3, new_keys_message/1,
handle_kexinit_msg/3, handle_kexdh_init/2,
- handle_kex_dh_gex_group/2, handle_kex_dh_gex_reply/2,
+ handle_kex_dh_gex_group/2, handle_kex_dh_gex_init/2, handle_kex_dh_gex_reply/2,
handle_new_keys/2, handle_kex_dh_gex_request/2,
handle_kexdh_reply/2,
- unpack/3, decompress/2, ssh_packet/2, pack/2, msg_data/1,
+ handle_kex_ecdh_init/2,
+ handle_kex_ecdh_reply/2,
+ extract_public_key/1,
+ ssh_packet/2, pack/2,
sign/3, verify/4]).
+%%% For test suites
+-export([pack/3]).
+-export([decompress/2, decrypt_blocks/3, is_valid_mac/3 ]). % FIXME: remove
+
+%%%----------------------------------------------------------------------------
+%%%
+%%% There is a difference between supported and default algorithms. The
+%%% SUPPORTED algorithms can be handled (maybe untested...). The DEFAULT ones
+%%% are announced in ssh_msg_kexinit and in ssh:default_algorithms/0 to the
+%%% user.
+%%%
+%%% A supported algorithm can be requested in the option 'preferred_algorithms',
+%%% but may give unexpected results before being promoted to default.
+%%%
+%%% This makes it possible to add experimental algorithms (in supported_algorithms)
+%%% and test them without letting the default users know about them.
+%%%
+
+default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].
+
+algo_classes() -> [kex, public_key, cipher, mac, compression].
+
+
+default_algorithms(cipher) ->
+ supported_algorithms(cipher, same(['AEAD_AES_128_GCM',
+ 'AEAD_AES_256_GCM']));
+default_algorithms(mac) ->
+ supported_algorithms(mac, same(['AEAD_AES_128_GCM',
+ 'AEAD_AES_256_GCM']));
+default_algorithms(Alg) ->
+ supported_algorithms(Alg, []).
+
+
+supported_algorithms() -> [{K,supported_algorithms(K)} || K <- algo_classes()].
+
+supported_algorithms(kex) ->
+ select_crypto_supported(
+ [
+ {'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]},
+ {'ecdh-sha2-nistp384', [{public_keys,ecdh}, {ec_curve,secp384r1}, {hashs,sha384}]},
+ {'diffie-hellman-group14-sha1', [{public_keys,dh}, {hashs,sha}]},
+ {'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]},
+ {'diffie-hellman-group-exchange-sha1', [{public_keys,dh}, {hashs,sha}]},
+ {'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]},
+ {'diffie-hellman-group1-sha1', [{public_keys,dh}, {hashs,sha}]}
+ ]);
+supported_algorithms(public_key) ->
+ select_crypto_supported(
+ [{'ecdsa-sha2-nistp256', [{public_keys,ecdsa}, {hashs,sha256}, {ec_curve,secp256r1}]},
+ {'ecdsa-sha2-nistp384', [{public_keys,ecdsa}, {hashs,sha384}, {ec_curve,secp384r1}]},
+ {'ecdsa-sha2-nistp521', [{public_keys,ecdsa}, {hashs,sha512}, {ec_curve,secp521r1}]},
+ {'ssh-rsa', [{public_keys,rsa}, {hashs,sha} ]},
+ {'ssh-dss', [{public_keys,dss}, {hashs,sha} ]}
+ ]);
+
+supported_algorithms(cipher) ->
+ same(
+ select_crypto_supported(
+ [{'aes256-ctr', [{ciphers,{aes_ctr,256}}]},
+ {'aes192-ctr', [{ciphers,{aes_ctr,192}}]},
+ {'aes128-ctr', [{ciphers,{aes_ctr,128}}]},
+ {'aes128-cbc', [{ciphers,aes_cbc128}]},
+ {'[email protected]', [{ciphers,{aes_gcm,128}}]},
+ {'[email protected]', [{ciphers,{aes_gcm,256}}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
+ {'3des-cbc', [{ciphers,des3_cbc}]}
+ ]
+ ));
+supported_algorithms(mac) ->
+ same(
+ select_crypto_supported(
+ [{'hmac-sha2-256', [{hashs,sha256}]},
+ {'hmac-sha2-512', [{hashs,sha512}]},
+ {'hmac-sha1', [{hashs,sha}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]}
+ ]
+ ));
+supported_algorithms(compression) ->
+ same(['none',
+ 'zlib'
+ ]).
+
+%%%----------------------------------------------------------------------------
versions(client, Options)->
Vsn = proplists:get_value(vsn, Options, ?DEFAULT_CLIENT_VERSION),
{Vsn, format_version(Vsn, software_version(Options))};
@@ -70,7 +162,7 @@ ssh_vsn() ->
_:_ -> ""
end.
-random_id(Nlo, Nup) ->
+random_id(Nlo, Nup) ->
[crypto:rand_uniform($a,$z+1) || _<- lists:duplicate(crypto:rand_uniform(Nlo,Nup+1),x) ].
hello_version_msg(Data) ->
@@ -79,12 +171,6 @@ hello_version_msg(Data) ->
next_seqnum(SeqNum) ->
(SeqNum + 1) band 16#ffffffff.
-decrypt_first_block(Bin, #ssh{decrypt_block_size = BlockSize} = Ssh0) ->
- <<EncBlock:BlockSize/binary, EncData/binary>> = Bin,
- {Ssh, <<?UINT32(PacketLen), _/binary>> = DecData} =
- decrypt(Ssh0, EncBlock),
- {Ssh, PacketLen, DecData, EncData}.
-
decrypt_blocks(Bin, Length, Ssh0) ->
<<EncBlocks:Length/binary, EncData/binary>> = Bin,
{Ssh, DecData} = decrypt(Ssh0, EncBlocks),
@@ -128,62 +214,45 @@ key_exchange_init_msg(Ssh0) ->
kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs}) ->
Random = ssh_bits:random(16),
- Compression = case proplists:get_value(compression, Opts, none) of
- openssh_zlib -> ["[email protected]", "none"];
- zlib -> ["zlib", "none"];
- none -> ["none", "zlib"]
- end,
- kexinit_messsage(Role, Random, Compression, HostKeyAlgs).
+ PrefAlgs =
+ case proplists:get_value(preferred_algorithms,Opts) of
+ undefined ->
+ default_algorithms();
+ Algs0 ->
+ Algs0
+ end,
+ kexinit_message(Role, Random, PrefAlgs, HostKeyAlgs).
key_init(client, Ssh, Value) ->
Ssh#ssh{c_keyinit = Value};
key_init(server, Ssh, Value) ->
Ssh#ssh{s_keyinit = Value}.
-available_ssh_algos() ->
- Supports = crypto:supports(),
- CipherAlgos = [{aes_ctr, "aes128-ctr"}, {aes_cbc128, "aes128-cbc"}, {des3_cbc, "3des-cbc"}],
- Ciphers = [SshAlgo ||
- {CryptoAlgo, SshAlgo} <- CipherAlgos,
- lists:member(CryptoAlgo, proplists:get_value(ciphers, Supports, []))],
- HashAlgos = [{sha256, "hmac-sha2-256"}, {sha, "hmac-sha1"}],
- Hashs = [SshAlgo ||
- {CryptoAlgo, SshAlgo} <- HashAlgos,
- lists:member(CryptoAlgo, proplists:get_value(hashs, Supports, []))],
- {Ciphers, Hashs}.
-
-kexinit_messsage(client, Random, Compression, HostKeyAlgs) ->
- {CipherAlgs, HashAlgs} = available_ssh_algos(),
- #ssh_msg_kexinit{
- cookie = Random,
- kex_algorithms = ["diffie-hellman-group1-sha1"],
- server_host_key_algorithms = HostKeyAlgs,
- encryption_algorithms_client_to_server = CipherAlgs,
- encryption_algorithms_server_to_client = CipherAlgs,
- mac_algorithms_client_to_server = HashAlgs,
- mac_algorithms_server_to_client = HashAlgs,
- compression_algorithms_client_to_server = Compression,
- compression_algorithms_server_to_client = Compression,
- languages_client_to_server = [],
- languages_server_to_client = []
- };
-kexinit_messsage(server, Random, Compression, HostKeyAlgs) ->
- {CipherAlgs, HashAlgs} = available_ssh_algos(),
+kexinit_message(_Role, Random, Algs, HostKeyAlgs) ->
#ssh_msg_kexinit{
cookie = Random,
- kex_algorithms = ["diffie-hellman-group1-sha1"],
+ kex_algorithms = to_strings( get_algs(kex,Algs) ),
server_host_key_algorithms = HostKeyAlgs,
- encryption_algorithms_client_to_server = CipherAlgs,
- encryption_algorithms_server_to_client = CipherAlgs,
- mac_algorithms_client_to_server = HashAlgs,
- mac_algorithms_server_to_client = HashAlgs,
- compression_algorithms_client_to_server = Compression,
- compression_algorithms_server_to_client = Compression,
+ encryption_algorithms_client_to_server = c2s(cipher,Algs),
+ encryption_algorithms_server_to_client = s2c(cipher,Algs),
+ mac_algorithms_client_to_server = c2s(mac,Algs),
+ mac_algorithms_server_to_client = s2c(mac,Algs),
+ compression_algorithms_client_to_server = c2s(compression,Algs),
+ compression_algorithms_server_to_client = s2c(compression,Algs),
languages_client_to_server = [],
languages_server_to_client = []
}.
+c2s(Key, Algs) -> x2y(client2server, Key, Algs).
+s2c(Key, Algs) -> x2y(server2client, Key, Algs).
+
+x2y(DirectionKey, Key, Algs) -> to_strings(proplists:get_value(DirectionKey, get_algs(Key,Algs))).
+
+get_algs(Key, Algs) -> proplists:get_value(Key, Algs, default_algorithms(Key)).
+
+to_strings(L) -> lists:map(fun erlang:atom_to_list/1, L).
+
new_keys_message(Ssh0) ->
{SshPacket, Ssh} =
ssh_packet(#ssh_msg_newkeys{}, Ssh0),
@@ -198,154 +267,411 @@ handle_kexinit_msg(#ssh_msg_kexinit{} = CounterPart, #ssh_msg_kexinit{} = Own,
Ssh0#ssh{algorithms = Algoritms});
_ ->
%% TODO: Correct code?
- throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
description = "Selection of key exchange"
" algorithm failed",
- language = "en"})
+ language = ""})
end;
handle_kexinit_msg(#ssh_msg_kexinit{} = CounterPart, #ssh_msg_kexinit{} = Own,
#ssh{role = server} = Ssh) ->
{ok, Algoritms} = select_algorithm(server, CounterPart, Own),
- {ok, Ssh#ssh{algorithms = Algoritms}}.
+ case verify_algorithm(Algoritms) of
+ true ->
+ {ok, Ssh#ssh{algorithms = Algoritms}};
+ _ ->
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Selection of key exchange"
+ " algorithm failed",
+ language = ""})
+ end.
%% TODO: diffie-hellman-group14-sha1 should also be supported.
%% Maybe check more things ...
-verify_algorithm(#alg{kex = 'diffie-hellman-group1-sha1'}) ->
- true;
-verify_algorithm(#alg{kex = 'diffie-hellman-group-exchange-sha1'}) ->
- true;
-verify_algorithm(_) ->
- false.
-key_exchange_first_msg('diffie-hellman-group1-sha1', Ssh0) ->
- {G, P} = dh_group1(),
- {Private, Public} = dh_gen_key(G, P, 1024),
+verify_algorithm(#alg{kex = undefined}) -> false;
+verify_algorithm(#alg{hkey = undefined}) -> false;
+verify_algorithm(#alg{send_mac = undefined}) -> false;
+verify_algorithm(#alg{recv_mac = undefined}) -> false;
+verify_algorithm(#alg{encrypt = undefined}) -> false;
+verify_algorithm(#alg{decrypt = undefined}) -> false;
+verify_algorithm(#alg{compress = undefined}) -> false;
+verify_algorithm(#alg{decompress = undefined}) -> false;
+verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex)).
+
+%%%----------------------------------------------------------------
+%%%
+%%% Key exchange initialization
+%%%
+key_exchange_first_msg(Kex, Ssh0) when Kex == 'diffie-hellman-group1-sha1' ;
+ Kex == 'diffie-hellman-group14-sha1' ->
+ {G, P} = dh_group(Kex),
+ {Public, Private} = generate_key(dh, [P,G]),
{SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_init{e = Public}, Ssh0),
{ok, SshPacket,
Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}}}};
-key_exchange_first_msg('diffie-hellman-group-exchange-sha1', Ssh0) ->
- Min = ?DEFAULT_DH_GROUP_MIN,
- NBits = ?DEFAULT_DH_GROUP_NBITS,
- Max = ?DEFAULT_DH_GROUP_MAX,
+key_exchange_first_msg(Kex, Ssh0=#ssh{opts=Opts}) when Kex == 'diffie-hellman-group-exchange-sha1' ;
+ Kex == 'diffie-hellman-group-exchange-sha256' ->
+ {Min,NBits,Max} =
+ proplists:get_value(dh_gex_limits, Opts, {?DEFAULT_DH_GROUP_MIN,
+ ?DEFAULT_DH_GROUP_NBITS,
+ ?DEFAULT_DH_GROUP_MAX}),
{SshPacket, Ssh1} =
ssh_packet(#ssh_msg_kex_dh_gex_request{min = Min,
- n = NBits, max = Max},
+ n = NBits,
+ max = Max},
Ssh0),
{ok, SshPacket,
- Ssh1#ssh{keyex_info = {Min, Max, NBits}}}.
-
-
-handle_kexdh_init(#ssh_msg_kexdh_init{e = E}, Ssh0) ->
- {G, P} = dh_group1(),
+ Ssh1#ssh{keyex_info = {Min, Max, NBits}}};
+
+key_exchange_first_msg(Kex, Ssh0) when Kex == 'ecdh-sha2-nistp256' ;
+ Kex == 'ecdh-sha2-nistp384' ;
+ Kex == 'ecdh-sha2-nistp521' ->
+ Curve = ecdh_curve(Kex),
+ {Public, Private} = generate_key(ecdh, Curve),
+ {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kex_ecdh_init{q_c=Public}, Ssh0),
+ {ok, SshPacket,
+ Ssh1#ssh{keyex_key = {{Public,Private},Curve}}}.
+
+%%%----------------------------------------------------------------
+%%%
+%%% diffie-hellman-group1-sha1
+%%% diffie-hellman-group14-sha1
+%%%
+handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
+ Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
+ %% server
+ {G, P} = dh_group(Kex),
if
1=<E, E=<(P-1) ->
- {Private, Public} = dh_gen_key(G, P, 1024),
- K = ssh_math:ipow(E, Private, P),
- Key = get_host_key(Ssh0),
- H = kex_h(Ssh0, Key, E, Public, K),
- H_SIG = sign_host_key(Ssh0, Key, H),
- {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_reply{public_host_key = Key,
- f = Public,
- h_sig = H_SIG
- }, Ssh0),
-
+ {Public, Private} = generate_key(dh, [P,G]),
+ K = compute_key(dh, E, Private, [P,G]),
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh1} =
+ ssh_packet(#ssh_msg_kexdh_reply{public_host_key = MyPubHostKey,
+ f = Public,
+ h_sig = H_SIG
+ }, Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
shared_secret = K,
exchanged_hash = H,
session_id = sid(Ssh1, H)}};
+
true ->
- Error = {error,bad_e_from_peer},
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed, 'f' out of bounds",
- language = "en"},
- throw({Error, Disconnect})
+ throw({{error,bad_e_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'e' out of bounds",
+ language = ""}
+ })
end.
+handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = PeerPubHostKey,
+ f = F,
+ h_sig = H_SIG},
+ #ssh{keyex_key = {{Private, Public}, {G, P}}} = Ssh0) ->
+ %% client
+ if
+ 1=<F, F=<(P-1)->
+ K = compute_key(dh, F, Private, [P,G]),
+ H = kex_h(Ssh0, PeerPubHostKey, Public, F, K),
+
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
+ ok ->
+ {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)}};
+ Error ->
+ throw({Error,
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed",
+ language = "en"}
+ })
+ end;
+
+ true ->
+ throw({{error,bad_f_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = ""}
+ })
+ end.
+
+
+%%%----------------------------------------------------------------
+%%%
+%%% diffie-hellman-group-exchange-sha1
+%%%
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min0,
+ n = NBits,
+ max = Max0},
+ Ssh0=#ssh{opts=Opts}) when Min0=<NBits, NBits=<Max0 ->
+ %% server
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request_old{n = NBits},
+ Ssh0=#ssh{opts=Opts}) ->
+ %% server
+ %%
+ %% This message was in the draft-00 of rfc4419
+ %% (https://tools.ietf.org/html/draft-ietf-secsh-dh-group-exchange-00)
+ %% In later drafts and the rfc is "is used for backward compatibility".
+ %% Unfortunatly the rfc does not specify how to treat the parameter n
+ %% if there is no group of that modulus length :(
+ %% The draft-00 however specifies that n is the "... number of bits
+ %% the subgroup should have at least".
+ %% Further, it says that "Servers and clients SHOULD support groups
+ %% with a modulus length of k bits, where 1024 <= k <= 8192."
+ %%
+ Min0 = NBits,
+ Max0 = 8192,
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {-1, -1, NBits} % flag for kex_h hash calc
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
+handle_kex_dh_gex_request(_, _) ->
+ throw({{error,bad_ssh_msg_kex_dh_gex_request},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, bad values in ssh_msg_kex_dh_gex_request",
+ language = ""}
+ }).
+
+
+adjust_gex_min_max(Min0, Max0, Opts) ->
+ case proplists:get_value(dh_gex_limits, Opts) of
+ undefined ->
+ {Min0, Max0};
+ {Min1, Max1} ->
+ Min2 = max(Min0, Min1),
+ Max2 = min(Max0, Max1),
+ if
+ Min2 =< Max2 ->
+ {Min2, Max2};
+ Max2 < Min2 ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group possible",
+ language = ""})
+ end
+ end.
+
+
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
- {Private, Public} = dh_gen_key(G,P,1024),
+ %% client
+ {Public, Private} = generate_key(dh, [P,G]),
{SshPacket, Ssh1} =
- ssh_packet(#ssh_msg_kex_dh_gex_init{e = Public}, Ssh0),
+ ssh_packet(#ssh_msg_kex_dh_gex_init{e = Public}, Ssh0), % Pub = G^Priv mod P (def)
+
{ok, SshPacket,
Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}}}}.
+handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
+ #ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}} =
+ Ssh0) ->
+ %% server
+ if
+ 1=<E, E=<(P-1) ->
+ K = compute_key(dh, E, Private, [P,G]),
+ if
+ 1<K, K<(P-1) ->
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, Min, NBits, Max, P, G, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = MyPubHostKey,
+ f = Public,
+ h_sig = H_SIG}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)
+ }};
+ true ->
+ throw({{error,bad_K},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'K' out of bounds",
+ language = ""}
+ })
+ end;
+ true ->
+ throw({{error,bad_e_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'e' out of bounds",
+ language = ""}
+ })
+ end.
+
+handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostKey,
+ f = F,
+ h_sig = H_SIG},
+ #ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}} =
+ Ssh0) ->
+ %% client
+ if
+ 1=<F, F=<(P-1)->
+ K = compute_key(dh, F, Private, [P,G]),
+ if
+ 1<K, K<(P-1) ->
+ H = kex_h(Ssh0, PeerPubHostKey, Min, NBits, Max, P, G, Public, F, K),
+
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
+ ok ->
+ {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)}};
+ _Error ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed",
+ language = ""}
+ )
+ end;
+
+ true ->
+ throw({{error,bad_K},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'K' out of bounds",
+ language = ""}
+ })
+ end;
+ true ->
+ throw({{error,bad_f_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = ""}
+ })
+ end.
+
+%%%----------------------------------------------------------------
+%%%
+%%% diffie-hellman-ecdh-sha2-*
+%%%
+handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
+ Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
+ %% at server
+ Curve = ecdh_curve(Kex),
+ {MyPublic, MyPrivate} = generate_key(ecdh, Curve),
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, Curve, MyPubHostKey, PeerPublic, MyPublic, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh1} =
+ ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = MyPubHostKey,
+ q_s = MyPublic,
+ h_sig = H_SIG},
+ Ssh0),
+ {ok, SshPacket, Ssh1#ssh{keyex_key = {{MyPublic,MyPrivate},Curve},
+ shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh1, H)}}
+ catch
+ _:_ ->
+ throw({{error,invalid_peer_public_key},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Peer ECDH public key is invalid",
+ language = ""}
+ })
+ end.
+
+handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = PeerPubHostKey,
+ q_s = PeerPublic,
+ h_sig = H_SIG},
+ #ssh{keyex_key = {{MyPublic,MyPrivate}, Curve}} = Ssh0
+ ) ->
+ %% at client
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ H = kex_h(Ssh0, Curve, PeerPubHostKey, MyPublic, PeerPublic, K),
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
+ ok ->
+ {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)}};
+ Error ->
+ throw({Error,
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed",
+ language = ""}
+ })
+ end
+ catch
+ _:_ ->
+ throw({{error,invalid_peer_public_key},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Peer ECDH public key is invalid",
+ language = ""}
+ })
+ end.
+
+
+%%%----------------------------------------------------------------
handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
try install_alg(Ssh0) of
#ssh{} = Ssh ->
{ok, Ssh}
catch
- error:_Error -> %% TODO: Throw earlier ....
+ _C:_Error -> %% TODO: Throw earlier ....
throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
description = "Install alg failed",
language = "en"})
end.
-
-%% %% Select algorithms
-handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey, f = F,
- h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {_G, P}}} = Ssh0) when 1=<F, F=<(P-1)->
- K = ssh_math:ipow(F, Private, P),
- H = kex_h(Ssh0, HostKey, Public, F, K),
-
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
- ok ->
- {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
- Error ->
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed",
- language = "en"},
- throw({Error, Disconnect})
- end;
-handle_kexdh_reply(#ssh_msg_kexdh_reply{}, _SSH) ->
- Error = {error,bad_f_from_peer},
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed, 'f' out of bounds",
- language = "en"},
- throw({Error, Disconnect}).
-
-
-handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = _Min,
- n = _NBits,
- max = _Max}, Ssh0) ->
- {G,P} = dh_group1(), %% TODO real imp this seems to be a hack?!
- {Private, Public} = dh_gen_key(G, P, 1024),
- {SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
- {ok, SshPacket,
- Ssh#ssh{keyex_key = {{Private, Public}, {G, P}}}}.
-
-handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
- f = F,
- h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}} =
- Ssh0) ->
- K = ssh_math:ipow(F, Private, P),
- H = kex_h(Ssh0, HostKey, Min, NBits, Max, P, G, Public, F, K),
-
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
- ok ->
- {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
- _Error ->
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed",
- language = "en"},
- throw(Disconnect)
- end.
-
%% select session id
sid(#ssh{session_id = undefined}, H) ->
H;
@@ -359,33 +685,49 @@ get_host_key(SSH) ->
#ssh{key_cb = Mod, opts = Opts, algorithms = ALG} = SSH,
case Mod:host_key(ALG#alg.hkey, Opts) of
- {ok, #'RSAPrivateKey'{} = Key} ->
- Key;
- {ok, #'DSAPrivateKey'{} = Key} ->
- Key;
+ {ok, #'RSAPrivateKey'{} = Key} -> Key;
+ {ok, #'DSAPrivateKey'{} = Key} -> Key;
+ {ok, #'ECPrivateKey'{} = Key} -> Key;
Result ->
exit({error, {Result, unsupported_key_type}})
end.
-sign_host_key(_Ssh, #'RSAPrivateKey'{} = Private, H) ->
- Hash = sha, %% Option ?!
- _Signature = sign(H, Hash, Private);
-sign_host_key(_Ssh, #'DSAPrivateKey'{} = Private, H) ->
- Hash = sha, %% Option ?!
- _RawSignature = sign(H, Hash, Private).
+sign_host_key(_Ssh, PrivateKey, H) ->
+ sign(H, sign_host_key_sha(PrivateKey), PrivateKey).
+
+sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve,OID}}) -> sha(OID);
+sign_host_key_sha(#'RSAPrivateKey'{}) -> sha;
+sign_host_key_sha(#'DSAPrivateKey'{}) -> sha.
+
+
+extract_public_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
+ #'RSAPublicKey'{modulus = N, publicExponent = E};
+extract_public_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
+ {Y, #'Dss-Parms'{p=P, q=Q, g=G}};
+extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
+ publicKey = Q}) ->
+ {#'ECPoint'{point=Q}, {namedCurve,OID}}.
+
verify_host_key(SSH, PublicKey, Digest, Signature) ->
- case verify(Digest, sha, Signature, PublicKey) of
+ case verify(Digest, host_key_sha(PublicKey), Signature, PublicKey) of
false ->
{error, bad_signature};
true ->
known_host_key(SSH, PublicKey, public_algo(PublicKey))
end.
-public_algo(#'RSAPublicKey'{}) ->
- 'ssh-rsa';
-public_algo({_, #'Dss-Parms'{}}) ->
- 'ssh-dss'.
+
+host_key_sha(#'RSAPublicKey'{}) -> sha;
+host_key_sha({_, #'Dss-Parms'{}}) -> sha;
+host_key_sha({#'ECPoint'{},{namedCurve,OID}}) -> sha(OID).
+
+public_algo(#'RSAPublicKey'{}) -> 'ssh-rsa';
+public_algo({_, #'Dss-Parms'{}}) -> 'ssh-dss';
+public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
+ Curve = public_key:oid2ssh_curvename(OID),
+ list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
+
accepted_host(Ssh, PeerName, Opts) ->
case proplists:get_value(silently_accept_hosts, Opts, false) of
@@ -418,8 +760,12 @@ known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
%% The first algorithm in each list MUST be the preferred (guessed)
%% algorithm. Each string MUST contain at least one algorithm name.
select_algorithm(Role, Client, Server) ->
- {Encrypt, Decrypt} = select_encrypt_decrypt(Role, Client, Server),
- {SendMac, RecvMac} = select_send_recv_mac(Role, Client, Server),
+ {Encrypt0, Decrypt0} = select_encrypt_decrypt(Role, Client, Server),
+ {SendMac0, RecvMac0} = select_send_recv_mac(Role, Client, Server),
+
+ {Encrypt, SendMac} = aead_gcm_simultan(Encrypt0, SendMac0),
+ {Decrypt, RecvMac} = aead_gcm_simultan(Decrypt0, RecvMac0),
+
{Compression, Decompression} =
select_compression_decompression(Role, Client, Server),
@@ -450,6 +796,38 @@ select_algorithm(Role, Client, Server) ->
s_lng = S_Lng},
{ok, Alg}.
+
+%%% It is an agreed problem with RFC 5674 that if the selection is
+%%% Cipher = AEAD_AES_x_GCM and
+%%% Mac = AEAD_AES_y_GCM (where x =/= y)
+%%% then it is undefined what length should be selected.
+%%%
+%%% If only one of the two lengths (128,256) is available, I claim that
+%%% there is no such ambiguity.
+
+%%% From https://anongit.mindrot.org/openssh.git/plain/PROTOCOL
+%%% (read Nov 20, 2015)
+%%% 1.6 transport: AES-GCM
+%%%
+%%% OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
+%%% Because of problems with the specification of the key exchange
+%%% the behaviour of OpenSSH differs from the RFC as follows:
+%%%
+%%% AES-GCM is only negotiated as the cipher algorithms
+%%% "[email protected]" or "[email protected]" and never as
+%%% an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
+%%% the exchanged MAC algorithms are ignored and there doesn't have to be
+%%% a matching MAC.
+
+aead_gcm_simultan('[email protected]', _) -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan('[email protected]', _) -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan('AEAD_AES_128_GCM', _) -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan('AEAD_AES_256_GCM', _) -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan(_, 'AEAD_AES_128_GCM') -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan(_, 'AEAD_AES_256_GCM') -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan(Cipher, Mac) -> {Cipher,Mac}.
+
+
select_encrypt_decrypt(client, Client, Server) ->
Encrypt =
select(Client#ssh_msg_kexinit.encryption_algorithms_client_to_server,
@@ -484,18 +862,18 @@ select_compression_decompression(client, Client, Server) ->
Compression =
select(Client#ssh_msg_kexinit.compression_algorithms_client_to_server,
Server#ssh_msg_kexinit.compression_algorithms_client_to_server),
- Decomprssion =
+ Decompression =
select(Client#ssh_msg_kexinit.compression_algorithms_server_to_client,
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
- {Compression, Decomprssion};
+ {Compression, Decompression};
select_compression_decompression(server, Client, Server) ->
- Decomprssion =
+ Decompression =
select(Client#ssh_msg_kexinit.compression_algorithms_client_to_server,
Server#ssh_msg_kexinit.compression_algorithms_client_to_server),
Compression =
select(Client#ssh_msg_kexinit.compression_algorithms_server_to_client,
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
- {Compression, Decomprssion}.
+ {Compression, Decompression}.
install_alg(SSH) ->
SSH1 = alg_final(SSH),
@@ -537,14 +915,15 @@ alg_final(SSH0) ->
{ok,SSH6} = decompress_final(SSH5),
SSH6.
-select_all(CL, SL) when length(CL) + length(SL) < 50 ->
+select_all(CL, SL) when length(CL) + length(SL) < ?MAX_NUM_ALGORITHMS ->
A = CL -- SL, %% algortihms only used by client
%% algorithms used by client and server (client pref)
lists:map(fun(ALG) -> list_to_atom(ALG) end, (CL -- A));
-select_all(_CL, _SL) ->
+select_all(CL, SL) ->
+ Err = lists:concat(["Received too many algorithms (",length(CL),"+",length(SL)," >= ",?MAX_NUM_ALGORITHMS,")."]),
throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Too many algorithms",
- language = "en"}).
+ description = Err,
+ language = ""}).
select([], []) ->
@@ -565,58 +944,147 @@ ssh_packet(Msg, Ssh) ->
BinMsg = ssh_message:encode(Msg),
pack(BinMsg, Ssh).
-pack(Data0, #ssh{encrypt_block_size = BlockSize,
- send_sequence = SeqNum, send_mac = MacAlg,
- send_mac_key = MacKey}
- = Ssh0) when is_binary(Data0) ->
- {Ssh1, Data} = compress(Ssh0, Data0),
- PL = (BlockSize - ((4 + 1 + size(Data)) rem BlockSize)) rem BlockSize,
- PaddingLen = if PL < 4 -> PL + BlockSize;
- true -> PL
- end,
- Padding = ssh_bits:random(PaddingLen),
- PacketLen = 1 + PaddingLen + size(Data),
- PacketData = <<?UINT32(PacketLen),?BYTE(PaddingLen),
- Data/binary, Padding/binary>>,
- {Ssh2, EncPacket} = encrypt(Ssh1, PacketData),
- MAC = mac(MacAlg, MacKey, SeqNum, PacketData),
- Packet = [EncPacket, MAC],
- Ssh = Ssh2#ssh{send_sequence = (SeqNum+1) band 16#ffffffff},
- {Packet, Ssh}.
-
-unpack(EncodedSoFar, ReminingLenght, #ssh{recv_mac_size = MacSize} = Ssh0) ->
- SshLength = ReminingLenght - MacSize,
- {NoMac, Mac, Rest} = case MacSize of
- 0 ->
- <<NoMac0:SshLength/binary,
- Rest0/binary>> = EncodedSoFar,
- {NoMac0, <<>>, Rest0};
- _ ->
- <<NoMac0:SshLength/binary,
- Mac0:MacSize/binary,
- Rest0/binary>> = EncodedSoFar,
- {NoMac0, Mac0, Rest0}
- end,
- {Ssh1, DecData, <<>>} =
- case SshLength of
- 0 ->
- {Ssh0, <<>>, <<>>};
- _ ->
- decrypt_blocks(NoMac, SshLength, Ssh0)
+pack(Data, Ssh=#ssh{}) ->
+ pack(Data, Ssh, 0).
+
+%%% Note: pack/3 is only to be called from tests that wants
+%%% to deliberetly send packets with wrong PacketLength!
+%%% Use pack/2 for all other purposes!
+pack(PlainText,
+ #ssh{send_sequence = SeqNum,
+ send_mac = MacAlg,
+ send_mac_key = MacKey,
+ encrypt = CryptoAlg} = Ssh0, PacketLenDeviationForTests) when is_binary(PlainText) ->
+
+ {Ssh1, CompressedPlainText} = compress(Ssh0, PlainText),
+ {EcryptedPacket, MAC, Ssh3} =
+ case pkt_type(CryptoAlg) of
+ common ->
+ PaddingLen = padding_length(4+1+size(CompressedPlainText), Ssh0),
+ Padding = ssh_bits:random(PaddingLen),
+ PlainPacketLen = 1 + PaddingLen + size(CompressedPlainText) + PacketLenDeviationForTests,
+ PlainPacketData = <<?UINT32(PlainPacketLen),?BYTE(PaddingLen), CompressedPlainText/binary, Padding/binary>>,
+ {Ssh2, EcryptedPacket0} = encrypt(Ssh1, PlainPacketData),
+ MAC0 = mac(MacAlg, MacKey, SeqNum, PlainPacketData),
+ {EcryptedPacket0, MAC0, Ssh2};
+ aead ->
+ PaddingLen = padding_length(1+size(CompressedPlainText), Ssh0),
+ Padding = ssh_bits:random(PaddingLen),
+ PlainPacketLen = 1 + PaddingLen + size(CompressedPlainText) + PacketLenDeviationForTests,
+ PlainPacketData = <<?BYTE(PaddingLen), CompressedPlainText/binary, Padding/binary>>,
+ {Ssh2, {EcryptedPacket0,MAC0}} = encrypt(Ssh1, {<<?UINT32(PlainPacketLen)>>,PlainPacketData}),
+ {<<?UINT32(PlainPacketLen),EcryptedPacket0/binary>>, MAC0, Ssh2}
end,
- {Ssh1, DecData, Rest, Mac}.
+ FinalPacket = [EcryptedPacket, MAC],
+ Ssh = Ssh3#ssh{send_sequence = (SeqNum+1) band 16#ffffffff},
+ {FinalPacket, Ssh}.
+
+
+padding_length(Size, #ssh{encrypt_block_size = BlockSize,
+ random_length_padding = RandomLengthPadding}) ->
+ PL = (BlockSize - (Size rem BlockSize)) rem BlockSize,
+ MinPaddingLen = if PL < 4 -> PL + BlockSize;
+ true -> PL
+ end,
+ PadBlockSize = max(BlockSize,4),
+ MaxExtraBlocks = (max(RandomLengthPadding,MinPaddingLen) - MinPaddingLen) div PadBlockSize,
+ ExtraPaddingLen = try crypto:rand_uniform(0,MaxExtraBlocks)*PadBlockSize
+ catch _:_ -> 0
+ end,
+ MinPaddingLen + ExtraPaddingLen.
+
+
+
+handle_packet_part(<<>>, Encrypted0, undefined, #ssh{decrypt = CryptoAlg} = Ssh0) ->
+ %% New ssh packet
+ case get_length(pkt_type(CryptoAlg), Encrypted0, Ssh0) of
+ get_more ->
+ %% too short to get the length
+ {get_more, <<>>, Encrypted0, undefined, Ssh0};
+
+ {ok, PacketLen, _, _, _} when PacketLen > ?SSH_MAX_PACKET_SIZE ->
+ %% far too long message than expected
+ {error, {exceeds_max_size,PacketLen}};
+
+ {ok, PacketLen, Decrypted, Encrypted1,
+ #ssh{recv_mac_size = MacSize} = Ssh1} ->
+ %% enough bytes so we got the length and can calculate how many
+ %% more bytes to expect for a full packet
+ TotalNeeded = (4 + PacketLen + MacSize),
+ handle_packet_part(Decrypted, Encrypted1, TotalNeeded, Ssh1)
+ end;
-msg_data(PacketData) ->
- <<Len:32, PaddingLen:8, _/binary>> = PacketData,
- DataLen = Len - PaddingLen - 1,
- <<_:32, _:8, Data:DataLen/binary,
- _:PaddingLen/binary>> = PacketData,
- Data.
+handle_packet_part(DecryptedPfx, EncryptedBuffer, TotalNeeded, Ssh0)
+ when (size(DecryptedPfx)+size(EncryptedBuffer)) < TotalNeeded ->
+ %% need more bytes to finalize the packet
+ {get_more, DecryptedPfx, EncryptedBuffer, TotalNeeded, Ssh0};
+
+handle_packet_part(DecryptedPfx, EncryptedBuffer, TotalNeeded,
+ #ssh{recv_mac_size = MacSize,
+ decrypt = CryptoAlg} = Ssh0) ->
+ %% enough bytes to decode the packet.
+ DecryptLen = TotalNeeded - size(DecryptedPfx) - MacSize,
+ <<EncryptedSfx:DecryptLen/binary, Mac:MacSize/binary, NextPacketBytes/binary>> = EncryptedBuffer,
+ case pkt_type(CryptoAlg) of
+ common ->
+ {Ssh1, DecryptedSfx} = decrypt(Ssh0, EncryptedSfx),
+ DecryptedPacket = <<DecryptedPfx/binary, DecryptedSfx/binary>>,
+ case is_valid_mac(Mac, DecryptedPacket, Ssh1) of
+ false ->
+ {bad_mac, Ssh1};
+ true ->
+ {Ssh, DecompressedPayload} = decompress(Ssh1, payload(DecryptedPacket)),
+ {decoded, DecompressedPayload, NextPacketBytes, Ssh}
+ end;
+ aead ->
+ PacketLenBin = DecryptedPfx,
+ case decrypt(Ssh0, {PacketLenBin,EncryptedSfx,Mac}) of
+ {Ssh1, error} ->
+ {bad_mac, Ssh1};
+ {Ssh1, DecryptedSfx} ->
+ DecryptedPacket = <<DecryptedPfx/binary, DecryptedSfx/binary>>,
+ {Ssh, DecompressedPayload} = decompress(Ssh1, payload(DecryptedPacket)),
+ {decoded, DecompressedPayload, NextPacketBytes, Ssh}
+ end
+ end.
+
+
+get_length(common, EncryptedBuffer, #ssh{decrypt_block_size = BlockSize} = Ssh0) ->
+ case size(EncryptedBuffer) >= erlang:max(8, BlockSize) of
+ true ->
+ <<EncBlock:BlockSize/binary, EncryptedRest/binary>> = EncryptedBuffer,
+ {Ssh,
+ <<?UINT32(PacketLen),_/binary>> = Decrypted} = decrypt(Ssh0, EncBlock),
+ {ok, PacketLen, Decrypted, EncryptedRest, Ssh};
+ false ->
+ get_more
+ end;
+get_length(aead, EncryptedBuffer, Ssh) ->
+ case size(EncryptedBuffer) >= 4 of
+ true ->
+ <<?UINT32(PacketLen), EncryptedRest/binary>> = EncryptedBuffer,
+ {ok, PacketLen, <<?UINT32(PacketLen)>>, EncryptedRest, Ssh};
+ false ->
+ get_more
+ end.
+
+pkt_type('AEAD_AES_128_GCM') -> aead;
+pkt_type('AEAD_AES_256_GCM') -> aead;
+pkt_type(_) -> common.
+
+payload(<<PacketLen:32, PaddingLen:8, PayloadAndPadding/binary>>) ->
+ PayloadLen = PacketLen - PaddingLen - 1,
+ <<Payload:PayloadLen/binary, _/binary>> = PayloadAndPadding,
+ Payload.
sign(SigData, Hash, #'DSAPrivateKey'{} = Key) ->
DerSignature = public_key:sign(SigData, Hash, Key),
#'Dss-Sig-Value'{r = R, s = S} = public_key:der_decode('Dss-Sig-Value', DerSignature),
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>>;
+sign(SigData, Hash, Key = #'ECPrivateKey'{}) ->
+ DerEncodedSign = public_key:sign(SigData, Hash, Key),
+ #'ECDSA-Sig-Value'{r=R, s=S} = public_key:der_decode('ECDSA-Sig-Value', DerEncodedSign),
+ ssh_bits:encode([R,S], [mpint,mpint]);
sign(SigData, Hash, Key) ->
public_key:sign(SigData, Hash, Key).
@@ -624,59 +1092,48 @@ verify(PlainText, Hash, Sig, {_, #'Dss-Parms'{}} = Key) ->
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> = Sig,
Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
public_key:verify(PlainText, Hash, Signature, Key);
+verify(PlainText, Hash, Sig, {#'ECPoint'{},_} = Key) ->
+ <<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
+ ?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> = Sig,
+ Sval = #'ECDSA-Sig-Value'{r=R, s=S},
+ DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
+ public_key:verify(PlainText, Hash, DerEncodedSig, Key);
verify(PlainText, Hash, Sig, Key) ->
public_key:verify(PlainText, Hash, Sig, Key).
-%% public key algorithms
-%%
-%% ssh-dss REQUIRED sign Raw DSS Key
-%% ssh-rsa RECOMMENDED sign Raw RSA Key
-%% x509v3-sign-rsa OPTIONAL sign X.509 certificates (RSA key)
-%% x509v3-sign-dss OPTIONAL sign X.509 certificates (DSS key)
-%% spki-sign-rsa OPTIONAL sign SPKI certificates (RSA key)
-%% spki-sign-dss OPTIONAL sign SPKI certificates (DSS key)
-%% pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
-%% pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
-%%
-
-%% key exchange
-%%
-%% diffie-hellman-group1-sha1 REQUIRED
-%%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Encryption
%%
-%% chiphers
-%%
-%% 3des-cbc REQUIRED
-%% three-key 3DES in CBC mode
-%% blowfish-cbc OPTIONAL Blowfish in CBC mode
-%% twofish256-cbc OPTIONAL Twofish in CBC mode,
-%% with 256-bit key
-%% twofish-cbc OPTIONAL alias for "twofish256-cbc" (this
-%% is being retained for
-%% historical reasons)
-%% twofish192-cbc OPTIONAL Twofish with 192-bit key
-%% twofish128-cbc OPTIONAL Twofish with 128-bit key
-%% aes256-cbc OPTIONAL AES in CBC mode,
-%% with 256-bit key
-%% aes192-cbc OPTIONAL AES with 192-bit key
-%% aes128-cbc RECOMMENDED AES with 128-bit key
-%% serpent256-cbc OPTIONAL Serpent in CBC mode, with
-%% 256-bit key
-%% serpent192-cbc OPTIONAL Serpent with 192-bit key
-%% serpent128-cbc OPTIONAL Serpent with 128-bit key
-%% arcfour OPTIONAL the ARCFOUR stream cipher
-%% idea-cbc OPTIONAL IDEA in CBC mode
-%% cast128-cbc OPTIONAL CAST-128 in CBC mode
-%% none OPTIONAL no encryption; NOT RECOMMENDED
+%% Encryption
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
encrypt_init(#ssh{encrypt = none} = Ssh) ->
{ok, Ssh};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
encrypt_init(#ssh{encrypt = '3des-cbc', role = client} = Ssh) ->
IV = hash(Ssh, "A", 64),
<<K1:8/binary, K2:8/binary, K3:8/binary>> = hash(Ssh, "C", 192),
@@ -702,18 +1159,46 @@ encrypt_init(#ssh{encrypt = 'aes128-cbc', role = server} = Ssh) ->
encrypt_block_size = 16,
encrypt_ctx = IV}};
encrypt_init(#ssh{encrypt = 'aes128-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
+ IV = hash(Ssh, "A", 128),
<<K:16/binary>> = hash(Ssh, "C", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes192-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:24/binary>> = hash(Ssh, "C", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes256-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
encrypt_init(#ssh{encrypt = 'aes128-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
+ IV = hash(Ssh, "B", 128),
<<K:16/binary>> = hash(Ssh, "D", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes192-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:24/binary>> = hash(Ssh, "D", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes256-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
encrypt_ctx = State}}.
encrypt_final(Ssh) ->
@@ -725,6 +1210,18 @@ encrypt_final(Ssh) ->
encrypt(#ssh{encrypt = none} = Ssh, Data) ->
{Ssh, Data};
+encrypt(#ssh{encrypt = 'AEAD_AES_128_GCM',
+ encrypt_keys = K,
+ encrypt_ctx = IV0} = Ssh, Data={_AAD,_Ptext}) ->
+ Enc = {_Ctext,_Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, Data),
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
+encrypt(#ssh{encrypt = 'AEAD_AES_256_GCM',
+ encrypt_keys = K,
+ encrypt_ctx = IV0} = Ssh, Data={_AAD,_Ptext}) ->
+ Enc = {_Ctext,_Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, Data),
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
encrypt(#ssh{encrypt = '3des-cbc',
encrypt_keys = {K1,K2,K3},
encrypt_ctx = IV0} = Ssh, Data) ->
@@ -740,6 +1237,14 @@ encrypt(#ssh{encrypt = 'aes128-cbc',
encrypt(#ssh{encrypt = 'aes128-ctr',
encrypt_ctx = State0} = Ssh, Data) ->
{State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc};
+encrypt(#ssh{encrypt = 'aes192-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc};
+encrypt(#ssh{encrypt = 'aes256-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
{Ssh#ssh{encrypt_ctx = State}, Enc}.
@@ -749,6 +1254,30 @@ encrypt(#ssh{encrypt = 'aes128-ctr',
decrypt_init(#ssh{decrypt = none} = Ssh) ->
{ok, Ssh};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
decrypt_init(#ssh{decrypt = '3des-cbc', role = client} = Ssh) ->
{IV, KD} = {hash(Ssh, "B", 64),
hash(Ssh, "D", 192)},
@@ -780,12 +1309,40 @@ decrypt_init(#ssh{decrypt = 'aes128-ctr', role = client} = Ssh) ->
{ok, Ssh#ssh{decrypt_keys = K,
decrypt_block_size = 16,
decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes192-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:24/binary>> = hash(Ssh, "D", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes256-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
decrypt_init(#ssh{decrypt = 'aes128-ctr', role = server} = Ssh) ->
IV = hash(Ssh, "A", 128),
<<K:16/binary>> = hash(Ssh, "C", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{decrypt_keys = K,
decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes192-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:24/binary>> = hash(Ssh, "C", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes256-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
decrypt_ctx = State}}.
@@ -795,8 +1352,22 @@ decrypt_final(Ssh) ->
decrypt_ctx = undefined,
decrypt_block_size = 8}}.
+decrypt(Ssh, <<>>) ->
+ {Ssh, <<>>};
decrypt(#ssh{decrypt = none} = Ssh, Data) ->
{Ssh, Data};
+decrypt(#ssh{decrypt = 'AEAD_AES_128_GCM',
+ decrypt_keys = K,
+ decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
+ Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
+decrypt(#ssh{decrypt = 'AEAD_AES_256_GCM',
+ decrypt_keys = K,
+ decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
+ Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
decrypt(#ssh{decrypt = '3des-cbc', decrypt_keys = Keys,
decrypt_ctx = IV0} = Ssh, Data) ->
{K1, K2, K3} = Keys,
@@ -811,8 +1382,20 @@ decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key,
decrypt(#ssh{decrypt = 'aes128-ctr',
decrypt_ctx = State0} = Ssh, Data) ->
{State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc};
+decrypt(#ssh{decrypt = 'aes192-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc};
+decrypt(#ssh{decrypt = 'aes256-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
{Ssh#ssh{decrypt_ctx = State}, Enc}.
+
+next_gcm_iv(<<Fixed:32, InvCtr:64>>) -> <<Fixed:32, (InvCtr+1):64>>.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compression
%%
@@ -895,49 +1478,54 @@ decompress(#ssh{decompress = '[email protected]', decompress_ctx = Context, authe
{Ssh, list_to_binary(Decompressed)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% MAC calculation
%%
-%% hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
-%% length = 20)
-%% hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
-%% length = 12, key length = 20)
-%% hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
-%% length = 16)
-%% hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
-%% length = 12, key length = 16)
-%% none OPTIONAL no MAC; NOT RECOMMENDED
+%% MAC calculation
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
send_mac_init(SSH) ->
- case SSH#ssh.role of
- client ->
- KeySize =mac_key_size(SSH#ssh.send_mac),
- Key = hash(SSH, "E", KeySize),
- {ok, SSH#ssh { send_mac_key = Key }};
- server ->
- KeySize = mac_key_size(SSH#ssh.send_mac),
- Key = hash(SSH, "F", KeySize),
- {ok, SSH#ssh { send_mac_key = Key }}
+ case pkt_type(SSH#ssh.send_mac) of
+ common ->
+ case SSH#ssh.role of
+ client ->
+ KeySize = mac_key_size(SSH#ssh.send_mac),
+ Key = hash(SSH, "E", KeySize),
+ {ok, SSH#ssh { send_mac_key = Key }};
+ server ->
+ KeySize = mac_key_size(SSH#ssh.send_mac),
+ Key = hash(SSH, "F", KeySize),
+ {ok, SSH#ssh { send_mac_key = Key }}
+ end;
+ aead ->
+ %% Not applicable
+ {ok, SSH}
end.
send_mac_final(SSH) ->
- {ok, SSH#ssh { send_mac = none, send_mac_key = undefined }}.
+ {ok, SSH#ssh {send_mac = none,
+ send_mac_key = undefined }}.
+
recv_mac_init(SSH) ->
- case SSH#ssh.role of
- client ->
- Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
- {ok, SSH#ssh { recv_mac_key = Key }};
- server ->
- Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
- {ok, SSH#ssh { recv_mac_key = Key }}
+ case pkt_type(SSH#ssh.recv_mac) of
+ common ->
+ case SSH#ssh.role of
+ client ->
+ Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
+ {ok, SSH#ssh { recv_mac_key = Key }};
+ server ->
+ Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
+ {ok, SSH#ssh { recv_mac_key = Key }}
+ end;
+ aead ->
+ %% Not applicable
+ {ok, SSH}
end.
recv_mac_final(SSH) ->
{ok, SSH#ssh { recv_mac = none, recv_mac_key = undefined }}.
-mac(none, _ , _, _) ->
+mac(none, _ , _, _) ->
<<>>;
mac('hmac-sha1', Key, SeqNum, Data) ->
crypto:hmac(sha, Key, [<<?UINT32(SeqNum)>>, Data]);
@@ -948,7 +1536,9 @@ mac('hmac-md5', Key, SeqNum, Data) ->
mac('hmac-md5-96', Key, SeqNum, Data) ->
crypto:hmac(md5, Key, [<<?UINT32(SeqNum)>>, Data], mac_digest_size('hmac-md5-96'));
mac('hmac-sha2-256', Key, SeqNum, Data) ->
- crypto:hmac(sha256, Key, [<<?UINT32(SeqNum)>>, Data]).
+ crypto:hmac(sha256, Key, [<<?UINT32(SeqNum)>>, Data]);
+mac('hmac-sha2-512', Key, SeqNum, Data) ->
+ crypto:hmac(sha512, Key, [<<?UINT32(SeqNum)>>, Data]).
%% return N hash bytes (HASH)
hash(SSH, Char, Bits) ->
@@ -956,8 +1546,20 @@ hash(SSH, Char, Bits) ->
case SSH#ssh.kex of
'diffie-hellman-group1-sha1' ->
fun(Data) -> crypto:hash(sha, Data) end;
+ 'diffie-hellman-group14-sha1' ->
+ fun(Data) -> crypto:hash(sha, Data) end;
+
'diffie-hellman-group-exchange-sha1' ->
fun(Data) -> crypto:hash(sha, Data) end;
+ 'diffie-hellman-group-exchange-sha256' ->
+ fun(Data) -> crypto:hash(sha256, Data) end;
+
+ 'ecdh-sha2-nistp256' ->
+ fun(Data) -> crypto:hash(sha256,Data) end;
+ 'ecdh-sha2-nistp384' ->
+ fun(Data) -> crypto:hash(sha384,Data) end;
+ 'ecdh-sha2-nistp521' ->
+ fun(Data) -> crypto:hash(sha512,Data) end;
_ ->
exit({bad_algorithm,SSH#ssh.kex})
end,
@@ -981,22 +1583,36 @@ hash(K, H, Ki, N, HASH) ->
hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HASH).
kex_h(SSH, Key, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), E,F,K],
+ KeyBin, E,F,K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
- crypto:hash(sha,L).
-
+ crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
+%% crypto:hash(sha,L).
+
+kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
+ L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
+ SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
+ KeyBin, Q_c, Q_s, K],
+ [string,string,binary,binary,binary,
+ mpint,mpint,mpint]),
+ crypto:hash(sha(Curve), L).
kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = if Min==-1; Max==-1 ->
+ %% flag from 'ssh_msg_kex_dh_gex_request_old'
+ %% It was like this before that message was supported,
+ %% why?
Ts = [string,string,binary,binary,binary,
uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), NBits, Prime, Gen, E,F,K],
+ KeyBin, NBits, Prime, Gen, E,F,K],
Ts);
true ->
Ts = [string,string,binary,binary,binary,
@@ -1004,16 +1620,30 @@ kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Min, NBits, Max,
+ KeyBin, Min, NBits, Max,
Prime, Gen, E,F,K], Ts)
end,
- crypto:hash(sha,L).
+ crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
+
+sha(secp256r1) -> sha256;
+sha(secp384r1) -> sha384;
+sha(secp521r1) -> sha512;
+sha('diffie-hellman-group1-sha1') -> sha;
+sha('diffie-hellman-group14-sha1') -> sha;
+sha('diffie-hellman-group-exchange-sha1') -> sha;
+sha('diffie-hellman-group-exchange-sha256') -> sha256;
+sha(?'secp256r1') -> sha(secp256r1);
+sha(?'secp384r1') -> sha(secp384r1);
+sha(?'secp521r1') -> sha(secp521r1).
+
+
mac_key_size('hmac-sha1') -> 20*8;
mac_key_size('hmac-sha1-96') -> 20*8;
mac_key_size('hmac-md5') -> 16*8;
mac_key_size('hmac-md5-96') -> 16*8;
mac_key_size('hmac-sha2-256')-> 32*8;
+mac_key_size('hmac-sha2-512')-> 512;
mac_key_size(none) -> 0.
mac_digest_size('hmac-sha1') -> 20;
@@ -1021,6 +1651,9 @@ mac_digest_size('hmac-sha1-96') -> 12;
mac_digest_size('hmac-md5') -> 20;
mac_digest_size('hmac-md5-96') -> 12;
mac_digest_size('hmac-sha2-256') -> 32;
+mac_digest_size('hmac-sha2-512') -> 64;
+mac_digest_size('AEAD_AES_128_GCM') -> 16;
+mac_digest_size('AEAD_AES_256_GCM') -> 16;
mac_digest_size(none) -> 0.
peer_name({Host, _}) ->
@@ -1032,12 +1665,91 @@ peer_name({Host, _}) ->
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dh_group1() ->
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF}.
+dh_group('diffie-hellman-group1-sha1') -> ?dh_group1;
+dh_group('diffie-hellman-group14-sha1') -> ?dh_group14.
-dh_gen_key(G, P, _) ->
- {Public, Private} = crypto:generate_key(dh, [P, G]),
- {crypto:bytes_to_integer(Private), crypto:bytes_to_integer(Public)}.
+%%%----------------------------------------------------------------
+generate_key(Algorithm, Args) ->
+ {Public,Private} = crypto:generate_key(Algorithm, Args),
+ {crypto:bytes_to_integer(Public), crypto:bytes_to_integer(Private)}.
+
+
+compute_key(Algorithm, OthersPublic, MyPrivate, Args) ->
+ Shared = crypto:compute_key(Algorithm, OthersPublic, MyPrivate, Args),
+ crypto:bytes_to_integer(Shared).
+
+
+ecdh_curve('ecdh-sha2-nistp256') -> secp256r1;
+ecdh_curve('ecdh-sha2-nistp384') -> secp384r1;
+ecdh_curve('ecdh-sha2-nistp521') -> secp521r1.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Utils for default_algorithms/1 and supported_algorithms/1
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+supported_algorithms(Key, [{client2server,BL1},{server2client,BL2}]) ->
+ [{client2server,As1},{server2client,As2}] = supported_algorithms(Key),
+ [{client2server,As1--BL1},{server2client,As2--BL2}];
+supported_algorithms(Key, BlackList) ->
+ supported_algorithms(Key) -- BlackList.
+
+
+select_crypto_supported(L) ->
+ Sup = [{ec_curve,crypto_supported_curves()} | crypto:supports()],
+ [Name || {Name,CryptoRequires} <- L,
+ crypto_supported(CryptoRequires, Sup)].
+
+crypto_supported_curves() ->
+ try crypto:ec_curves()
+ catch _:_ -> []
+ end.
+
+crypto_supported(Conditions, Supported) ->
+ lists:all( fun({Tag,CryptoName}) when is_atom(CryptoName) ->
+ crypto_name_supported(Tag,CryptoName,Supported);
+ ({Tag,{Name,Len}}) when is_integer(Len) ->
+ crypto_name_supported(Tag,Name,Supported) andalso
+ len_supported(Name,Len)
+ end, Conditions).
+
+crypto_name_supported(Tag, CryptoName, Supported) ->
+ lists:member(CryptoName, proplists:get_value(Tag,Supported,[])).
+
+len_supported(Name, Len) ->
+ try
+ case Name of
+ aes_ctr ->
+ {_, <<_/binary>>} =
+ %% Test encryption
+ crypto:stream_encrypt(crypto:stream_init(Name, <<0:Len>>, <<0:128>>), <<"">>);
+ aes_gcm ->
+ {<<_/binary>>, <<_/binary>>} =
+ crypto:block_encrypt(Name,
+ _Key = <<0:Len>>,
+ _IV = <<0:12/unsigned-unit:8>>,
+ {<<"AAD">>,"PT"})
+ end
+ of
+ _ -> true
+ catch
+ _:_ -> false
+ end.
+
+
+same(Algs) -> [{client2server,Algs}, {server2client,Algs}].
+
+
+%% default_algorithms(kex) -> % Example of how to disable an algorithm
+%% supported_algorithms(kex, ['ecdh-sha2-nistp521']);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Other utils
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
trim_tail(Str) ->
lists:reverse(trim_head(lists:reverse(Str))).
diff --git a/lib/ssh/src/ssh_transport.hrl b/lib/ssh/src/ssh_transport.hrl
index 27d3e32355..fd43326f0d 100644
--- a/lib/ssh/src/ssh_transport.hrl
+++ b/lib/ssh/src/ssh_transport.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -28,9 +29,12 @@
-define(DEFAULT_CLIENT_VERSION, {2, 0}).
-define(DEFAULT_SERVER_VERSION, {2, 0}).
--define(DEFAULT_DH_GROUP_MIN, 512).
--define(DEFAULT_DH_GROUP_NBITS, 1024).
--define(DEFAULT_DH_GROUP_MAX, 4096).
+
+-define(MAX_NUM_ALGORITHMS, 200).
+
+-define(DEFAULT_DH_GROUP_MIN, 1024).
+-define(DEFAULT_DH_GROUP_NBITS, 2048).
+-define(DEFAULT_DH_GROUP_MAX, 8192).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -108,8 +112,9 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% diffie-hellman-group1-sha1
--define(SSH_MSG_KEXDH_INIT, 30).
+%% diffie-hellman-group1-sha1 | diffie-hellman-group14-sha1
+
+-define(SSH_MSG_KEXDH_INIT, 30).
-define(SSH_MSG_KEXDH_REPLY, 31).
-record(ssh_msg_kexdh_init,
@@ -133,7 +138,7 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% diffie-hellman-group-exchange-sha1
+%% diffie-hellman-group-exchange-sha1 | diffie-hellman-group-exchange-sha256
-define(SSH_MSG_KEX_DH_GEX_REQUEST_OLD, 30).
-define(SSH_MSG_KEX_DH_GEX_REQUEST, 34).
-define(SSH_MSG_KEX_DH_GEX_GROUP, 31).
@@ -170,7 +175,36 @@
h_sig
}).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% KEY ECDH messages
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% ecdh-sha2-nistp256 | ecdh-sha2-nistp384 | ecdh-sha2-nistp521
+
+-define(SSH_MSG_KEX_ECDH_INIT, 30).
+-define(SSH_MSG_KEX_ECDH_REPLY, 31).
+
+-record(ssh_msg_kex_ecdh_init,
+ {
+ q_c % string (client's ephemeral public key octet string)
+ }).
+
+-record(ssh_msg_kex_ecdh_reply,
+ {
+ public_host_key, % string (server's public host key) (k_s)
+ q_s, % string (server's ephemeral public key octet string)
+ h_sig % string (the signature on the exchange hash)
+ }).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
%% error codes
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
-define(SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT, 1).
-define(SSH_DISCONNECT_PROTOCOL_ERROR, 2).
-define(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, 3).
@@ -188,48 +222,20 @@
-define(SSH_DISCONNECT_ILLEGAL_USER_NAME, 15).
-%%%----------------------------------------------------------------------
-%%% # DH_14_xxx
-%%% Description: Oakley group 14 prime numbers and generator. Used in
-%%% diffie-hellman-group1-sha1 key exchange method.
-%%%----------------------------------------------------------------------
-%%%----------------------------------------------------------------------
-%%% # DH_14_P
-%%% Description: Prime for this group
-%%%----------------------------------------------------------------------
-
--define(DH_14_P,
- <<000,000,000,129,000,255,255,255,255,255,255,255,255,201,015,218,
- 162,033,104,194,052,196,198,098,139,128,220,028,209,041,002,078,
- 008,138,103,204,116,002,011,190,166,059,019,155,034,081,074,008,
- 121,142,052,004,221,239,149,025,179,205,058,067,027,048,043,010,
- 109,242,095,020,055,079,225,053,109,109,081,194,069,228,133,181,
- 118,098,094,126,198,244,076,066,233,166,055,237,107,011,255,092,
- 182,244,006,183,237,238,056,107,251,090,137,159,165,174,159,036,
- 017,124,075,031,230,073,040,102,081,236,230,083,129,255,255,255,
- 255,255,255,255,255>>).
-
-%%%----------------------------------------------------------------------
-%%% # DH_14_G
-%%% Description: Generator for DH_14_P.
-%%%----------------------------------------------------------------------
-
--define(DH_14_G, <<0,0,0,1,2>>).
-
-%%%----------------------------------------------------------------------
-%%% # DH_14_Q
-%%% Description: Group order (DH_14_P - 1) / 2.
-%%%----------------------------------------------------------------------
-
--define(DH_14_Q,
- <<000,000,000,128,127,255,255,255,255,255,255,255,228,135,237,081,
- 016,180,097,026,098,099,049,069,192,110,014,104,148,129,039,004,
- 069,051,230,058,001,005,223,083,029,137,205,145,040,165,004,060,
- 199,026,002,110,247,202,140,217,230,157,033,141,152,021,133,054,
- 249,047,138,027,167,240,154,182,182,168,225,034,242,066,218,187,
- 049,047,063,099,122,038,033,116,211,027,246,181,133,255,174,091,
- 122,003,091,246,247,028,053,253,173,068,207,210,215,079,146,008,
- 190,037,143,243,036,148,051,040,246,115,041,192,255,255,255,255,
- 255,255,255,255>>).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% groups
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%% rfc 2489, ch 6.2
+%%% Size 1024
+-define(dh_group1,
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF}).
+
+%%% rfc 3526, ch3
+%%% Size 2048
+-define(dh_group14,
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF}).
-endif. % -ifdef(ssh_transport).
diff --git a/lib/ssh/src/ssh_userauth.hrl b/lib/ssh/src/ssh_userauth.hrl
index 7c38719d92..935999b9d1 100644
--- a/lib/ssh/src/ssh_userauth.hrl
+++ b/lib/ssh/src/ssh_userauth.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl
index 2743b704f1..b8dff1c533 100644
--- a/lib/ssh/src/ssh_xfer.erl
+++ b/lib/ssh/src/ssh_xfer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/ssh_xfer.hrl b/lib/ssh/src/ssh_xfer.hrl
index 8dc9a40f92..fe1405ccae 100644
--- a/lib/ssh/src/ssh_xfer.hrl
+++ b/lib/ssh/src/ssh_xfer.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/sshc_sup.erl b/lib/ssh/src/sshc_sup.erl
index e6b4b681a4..8ee6aacfb5 100644
--- a/lib/ssh/src/sshc_sup.erl
+++ b/lib/ssh/src/sshc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/src/sshd_sup.erl b/lib/ssh/src/sshd_sup.erl
index 60222f5172..7975b146fb 100644
--- a/lib/ssh/src/sshd_sup.erl
+++ b/lib/ssh/src/sshd_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,8 +27,10 @@
-behaviour(supervisor).
+-include("ssh.hrl").
+
-export([start_link/1, start_child/1, stop_child/1,
- stop_child/2, system_name/1]).
+ stop_child/3, system_name/1]).
%% Supervisor callback
-export([init/1]).
@@ -40,13 +43,14 @@ start_link(Servers) ->
start_child(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- case ssh_system_sup:system_supervisor(Address, Port) of
+ Port = proplists:get_value(port, ServerOpts),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ case ssh_system_sup:system_supervisor(Address, Port, Profile) of
undefined ->
Spec = child_spec(Address, Port, ServerOpts),
case supervisor:start_child(?MODULE, Spec) of
{error, already_present} ->
- Name = id(Address, Port),
+ Name = id(Address, Port, Profile),
supervisor:delete_child(?MODULE, Name),
supervisor:start_child(?MODULE, Spec);
Reply ->
@@ -60,8 +64,8 @@ start_child(ServerOpts) ->
stop_child(Name) ->
supervisor:terminate_child(?MODULE, Name).
-stop_child(Address, Port) ->
- Name = id(Address, Port),
+stop_child(Address, Port, Profile) ->
+ Name = id(Address, Port, Profile),
stop_child(Name).
system_name(SysSup) ->
@@ -87,7 +91,8 @@ init([Servers]) ->
%%% Internal functions
%%%=========================================================================
child_spec(Address, Port, ServerOpts) ->
- Name = id(Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = id(Address, Port,Profile),
StartFunc = {ssh_system_sup, start_link, [ServerOpts]},
Restart = temporary,
Shutdown = infinity,
@@ -95,8 +100,13 @@ child_spec(Address, Port, ServerOpts) ->
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Address, Port) ->
- {server, ssh_system_sup, Address, Port}.
+id(Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ {server, ssh_system_sup, any, Port, Profile};
+ false ->
+ {server, ssh_system_sup, Address, Port, Profile}
+ end.
system_name([], _ ) ->
undefined;
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index 740dbd0235..9cd98f069f 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -31,16 +32,27 @@ VSN=$(GS_VSN)
# ----------------------------------------------------
MODULES= \
- ssh_test_lib \
+ ssh_algorithms_SUITE \
+ ssh_options_SUITE \
+ ssh_renegotiate_SUITE \
ssh_basic_SUITE \
- ssh_to_openssh_SUITE \
+ ssh_benchmark_SUITE \
+ ssh_connection_SUITE \
+ ssh_protocol_SUITE \
ssh_sftp_SUITE \
ssh_sftpd_SUITE \
ssh_sftpd_erlclient_SUITE \
- ssh_connection_SUITE \
+ ssh_sup_SUITE \
+ ssh_to_openssh_SUITE \
+ ssh_upgrade_SUITE \
+ ssh_test_lib \
+ ssh_key_cb \
+ ssh_key_cb_options \
+ ssh_trpt_test_lib \
ssh_echo_server \
ssh_peername_sockname_server \
- ssh_test_cli
+ ssh_test_cli \
+ ssh_relay
HRL_FILES_NEEDED_IN_TEST= \
$(ERL_TOP)/lib/ssh/src/ssh.hrl \
@@ -116,7 +128,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)"
$(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)"
- $(INSTALL_DATA) ssh.spec ssh.cover "$(RELSYSDIR)"
+ $(INSTALL_DATA) ssh.spec ssh_bench.spec ssh.cover "$(RELSYSDIR)"
$(INSTALL_DATA) $(HRL_FILES_NEEDED_IN_TEST) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server.erl b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
index 123b48412b..4fcb5aea69 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_server.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
index 57ea2012c1..803c8aa2ad 100644
--- a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/test/property_test/ssh_eqc_subsys.erl b/lib/ssh/test/property_test/ssh_eqc_subsys.erl
index e4b6af166f..3b395b9285 100644
--- a/lib/ssh/test/property_test/ssh_eqc_subsys.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_subsys.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/test/ssh.spec b/lib/ssh/test/ssh.spec
index 8de0fe44e4..0076fc275e 100644
--- a/lib/ssh/test/ssh.spec
+++ b/lib/ssh/test/ssh.spec
@@ -1,7 +1,6 @@
{suites,"../ssh_test",all}.
-{skip_cases,"../ssh_test",ssh_ssh_SUITE,
- [ssh],
- "Current implementation is timingdependent and\nhence will succeed/fail on a whim"}.
-{skip_cases,"../ssh_test",ssh_ssh_SUITE,
- [ssh_compressed],
- "Current implementation is timingdependent hence will succeed/fail on a whim"}.
+
+{skip_suites, "../ssh_test", [ssh_benchmark_SUITE],
+ "Benchmarks run separately"}.
+
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl
new file mode 100644
index 0000000000..49ed15698c
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE.erl
@@ -0,0 +1,376 @@
+%%
+%% %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.
+%% 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(ssh_algorithms_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(TIMEOUT, 50000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,10}}].
+
+all() ->
+ %% [{group,kex},{group,cipher}... etc
+ [{group,C} || C <- tags()].
+
+
+groups() ->
+ ErlAlgos = extract_algos(ssh:default_algorithms()),
+ SshcAlgos = extract_algos(ssh_test_lib:default_algorithms(sshc)),
+ SshdAlgos = extract_algos(ssh_test_lib:default_algorithms(sshd)),
+
+ DoubleAlgos =
+ [{Tag, double(Algs)} || {Tag,Algs} <- ErlAlgos,
+ length(Algs) > 1,
+ lists:member(Tag, two_way_tags())],
+ TagGroupSet =
+ [{Tag, [], group_members_for_tag(Tag,Algs,DoubleAlgos)}
+ || {Tag,Algs} <- ErlAlgos,
+ lists:member(Tag,tags())
+ ],
+
+ AlgoTcSet =
+ [{Alg, [parallel], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos)}
+ || {Tag,Algs} <- ErlAlgos ++ DoubleAlgos,
+ Alg <- Algs],
+
+ TagGroupSet ++ AlgoTcSet.
+
+tags() -> [kex,cipher,mac,compression].
+two_way_tags() -> [cipher,mac,compression].
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ct:log("os:getenv(\"HOME\") = ~p~n"
+ "init:get_argument(home) = ~p",
+ [os:getenv("HOME"), init:get_argument(home)]),
+ ct:log("~n~n"
+ "OS ssh:~n=======~n~p~n~n~n"
+ "Erl ssh:~n========~n~p~n~n~n"
+ "Installed ssh client:~n=====================~n~p~n~n~n"
+ "Installed ssh server:~n=====================~n~p~n~n~n"
+ "Misc values:~n============~n"
+ " -- Default dh group exchange parameters ({min,def,max}): ~p~n"
+ " -- dh_default_groups: ~p~n"
+ " -- Max num algorithms: ~p~n"
+ ,[os:cmd("ssh -V"),
+ ssh:default_algorithms(),
+ ssh_test_lib:default_algorithms(sshc),
+ ssh_test_lib:default_algorithms(sshd),
+ {?DEFAULT_DH_GROUP_MIN,?DEFAULT_DH_GROUP_NBITS,?DEFAULT_DH_GROUP_MAX},
+ public_key:dh_gex_group_sizes(),
+ ?MAX_NUM_ALGORITHMS
+ ]),
+ ct:log("all() ->~n ~p.~n~ngroups()->~n ~p.~n",[all(),groups()]),
+ ssh:start(),
+ [{std_simple_sftp_size,25000} % Sftp transferred data size
+ | setup_pubkey(Config)].
+
+end_per_suite(_Config) ->
+ ssh:stop().
+
+
+init_per_group(Group, Config) ->
+ case lists:member(Group, tags()) of
+ true ->
+ %% A tag group
+ Tag = Group,
+ ct:comment("==== ~p ====",[Tag]),
+ Config;
+ false ->
+ %% An algorithm group
+ Tag = proplists:get_value(name,
+ hd(?config(tc_group_path, Config))),
+ Alg = Group,
+ PA =
+ case split(Alg) of
+ [_] ->
+ [Alg];
+ [A1,A2] ->
+ [{client2server,[A1]},
+ {server2client,[A2]}]
+ end,
+ ct:log("Init tests for tag=~p alg=~p",[Tag,PA]),
+ PrefAlgs = {preferred_algorithms,[{Tag,PA}]},
+ start_std_daemon([PrefAlgs],
+ [{pref_algs,PrefAlgs} | Config])
+ end.
+
+end_per_group(_Alg, Config) ->
+ case ?config(srvr_pid,Config) of
+ Pid when is_pid(Pid) ->
+ ssh:stop_daemon(Pid),
+ ct:log("stopped ~p",[?config(srvr_addr,Config)]);
+ _ ->
+ ok
+ end.
+
+
+
+init_per_testcase(sshc_simple_exec, Config) ->
+ start_pubkey_daemon([?config(pref_algs,Config)], Config);
+
+init_per_testcase(_TC, Config) ->
+ Config.
+
+
+end_per_testcase(sshc_simple_exec, Config) ->
+ case ?config(srvr_pid,Config) of
+ Pid when is_pid(Pid) ->
+ ssh:stop_daemon(Pid),
+ ct:log("stopped ~p",[?config(srvr_addr,Config)]);
+ _ ->
+ ok
+ end;
+end_per_testcase(_TC, Config) ->
+ Config.
+
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+%% A simple sftp transfer
+simple_sftp(Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_sftp(Host, Port, Config).
+
+%%--------------------------------------------------------------------
+%% A simple exec call
+simple_exec(Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_exec(Host, Port, Config).
+
+%%--------------------------------------------------------------------
+%% Testing if no group matches
+simple_exec_groups_no_match_too_small(Config) ->
+ try simple_exec_group({400,500,600}, Config)
+ of
+ _ -> ct:fail("Exec though no group available")
+ catch
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
+ ok
+ end.
+
+simple_exec_groups_no_match_too_large(Config) ->
+ try simple_exec_group({9200,9500,9700}, Config)
+ of
+ _ -> ct:fail("Exec though no group available")
+ catch
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+%% Testing all default groups
+simple_exec_groups(Config) ->
+ Sizes = interpolate( public_key:dh_gex_group_sizes() ),
+ lists:foreach(
+ fun(Sz) ->
+ ct:log("Try size ~p",[Sz]),
+ ct:comment(Sz),
+ case simple_exec_group(Sz, Config) of
+ expected -> ct:log("Size ~p ok",[Sz]);
+ _ -> ct:log("Size ~p not ok",[Sz])
+ end
+ end, Sizes),
+ ct:comment("~p",[lists:map(fun({_,I,_}) -> I;
+ (I) -> I
+ end,Sizes)]).
+
+
+interpolate([I1,I2|Is]) ->
+ OneThird = (I2-I1) div 3,
+ [I1,
+ {I1, I1 + OneThird, I2},
+ {I1, I1 + 2*OneThird, I2} | interpolate([I2|Is])];
+interpolate(Is) ->
+ Is.
+
+%%--------------------------------------------------------------------
+%% Use the ssh client of the OS to connect
+sshc_simple_exec(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
+ {Host,Port} = ?config(srvr_addr, Config),
+ Cmd = lists:concat(["ssh -p ",Port,
+ " -C -o UserKnownHostsFile=",KnownHosts,
+ " ",Host," 1+1."]),
+ ct:log("~p",[Cmd]),
+ SshPort = open_port({spawn, Cmd}, [binary]),
+ Expect = <<"2\n">>,
+ receive
+ {SshPort, {data,Expect}} ->
+ ct:log("Got expected ~p from ~p",[Expect,SshPort]),
+ catch port_close(SshPort),
+ ok
+ after ?TIMEOUT ->
+ ct:fail("Did not receive answer")
+ end.
+
+%%--------------------------------------------------------------------
+%% Connect to the ssh server of the OS
+sshd_simple_exec(_Config) ->
+ ConnectionRef = ssh_test_lib:connect(22, [{silently_accept_hosts, true},
+ {user_interaction, false}]),
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId0,
+ "echo testing", infinity),
+ Data0 = {ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(Data0) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0);
+ {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}}
+ = ExitStatus0} ->
+ ct:log("0: Collected data ~p", [ExitStatus0]),
+ ssh_test_lib:receive_exec_result(Data0,
+ ConnectionRef, ChannelId0);
+ Other0 ->
+ ct:fail(Other0)
+ end,
+
+ {ok, ChannelId1} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId1,
+ "echo testing1", infinity),
+ Data1 = {ssh_cm, ConnectionRef, {data, ChannelId1, 0, <<"testing1\n">>}},
+ case ssh_test_lib:receive_exec_result(Data1) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1);
+ {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId1, 0}}
+ = ExitStatus1} ->
+ ct:log("0: Collected data ~p", [ExitStatus1]),
+ ssh_test_lib:receive_exec_result(Data1,
+ ConnectionRef, ChannelId1);
+ Other1 ->
+ ct:fail(Other1)
+ end,
+ ssh:close(ConnectionRef).
+
+
+%%%================================================================
+%%%
+%%% Lib functions
+%%%
+
+%%%----------------------------------------------------------------
+%%%
+%%% For construction of the result of all/0 and groups/0
+%%%
+group_members_for_tag(Tag, Algos, DoubleAlgos) ->
+ [{group,Alg} || Alg <- Algos++proplists:get_value(Tag,DoubleAlgos,[])].
+
+double(Algs) -> [concat(A1,A2) || A1 <- Algs,
+ A2 <- Algs,
+ A1 =/= A2].
+
+concat(A1, A2) -> list_to_atom(lists:concat([A1," + ",A2])).
+
+split(Alg) -> ssh_test_lib:to_atoms(string:tokens(atom_to_list(Alg), " + ")).
+
+specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos) ->
+ [simple_exec, simple_sftp] ++
+ case supports(Tag, Alg, SshcAlgos) of
+ true ->
+ case ssh_test_lib:ssh_type() of
+ openSSH ->
+ [sshc_simple_exec];
+ _ ->
+ []
+ end;
+ false ->
+ []
+ end ++
+ case supports(Tag, Alg, SshdAlgos) of
+ true ->
+ [sshd_simple_exec];
+ _ ->
+ []
+ end ++
+ case {Tag,Alg} of
+ {kex,_} when Alg == 'diffie-hellman-group-exchange-sha1' ;
+ Alg == 'diffie-hellman-group-exchange-sha256' ->
+ [simple_exec_groups,
+ simple_exec_groups_no_match_too_large,
+ simple_exec_groups_no_match_too_small
+ ];
+ _ ->
+ []
+ end.
+
+supports(Tag, Alg, Algos) ->
+ lists:all(fun(A) ->
+ lists:member(A, proplists:get_value(Tag, Algos,[]))
+ end,
+ split(Alg)).
+
+
+extract_algos(Spec) ->
+ [{Tag,get_atoms(List)} || {Tag,List} <- Spec].
+
+get_atoms(L) ->
+ lists:usort(
+ [ A || X <- L,
+ A <- case X of
+ {_,L1} when is_list(L1) -> L1;
+ Y when is_atom(Y) -> [Y]
+ end]).
+
+%%%----------------------------------------------------------------
+%%%
+%%% Test case related
+%%%
+start_std_daemon(Opts, Config) ->
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, Opts),
+ ct:log("started ~p:~p ~p",[Host,Port,Opts]),
+ [{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
+
+start_pubkey_daemon(Opts, Config) ->
+ {Pid, Host, Port} = ssh_test_lib:std_daemon1(Config, Opts),
+ ct:log("started1 ~p:~p ~p",[Host,Port,Opts]),
+ [{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
+
+
+setup_pubkey(Config) ->
+ DataDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, UserDir),
+ ssh_test_lib:setup_rsa(DataDir, UserDir),
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
+ Config.
+
+
+simple_exec_group(I, Config) when is_integer(I) ->
+ simple_exec_group({I,I,I}, Config);
+simple_exec_group({Min,I,Max}, Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_exec(Host, Port, Config,
+ [{dh_gex_limits,{Min,I,Max}}]).
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key
index 51ab6fbd88..51ab6fbd88 100644
--- a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key.pub
index 4dbb1305b0..4dbb1305b0 100644
--- a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key.pub
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key.pub
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index fa7b426545..094d28e879 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,9 +24,52 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/inet.hrl").
+-include_lib("kernel/include/file.hrl").
%% Note: This directive should only be used in test suites.
--compile(export_all).
+%%-compile(export_all).
+
+%%% Test cases
+-export([
+ app_test/1,
+ appup_test/1,
+ cli/1,
+ close/1,
+ daemon_already_started/1,
+ daemon_opt_fd/1,
+ multi_daemon_opt_fd/1,
+ double_close/1,
+ exec/1,
+ exec_compressed/1,
+ exec_key_differs1/1,
+ exec_key_differs2/1,
+ exec_key_differs3/1,
+ exec_key_differs_fail/1,
+ idle_time/1,
+ inet6_option/1,
+ inet_option/1,
+ internal_error/1,
+ known_hosts/1,
+ misc_ssh_options/1,
+ openssh_zlib_basic_test/1,
+ packet_size_zero/1,
+ pass_phrase/1,
+ peername_sockname/1,
+ send/1,
+ shell/1,
+ shell_no_unicode/1,
+ shell_unicode_string/1,
+ ssh_info_print/1,
+ key_callback/1,
+ key_callback_options/1
+ ]).
+
+%%% Common test callbacks
+-export([suite/0, all/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
+ ]).
-define(NEWLINE, <<"\r\n">>).
@@ -34,74 +78,64 @@
%%--------------------------------------------------------------------
suite() ->
- [{ct_hooks,[ts_install_cth]}].
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,10}}].
all() ->
[app_test,
appup_test,
{group, dsa_key},
{group, rsa_key},
+ {group, ecdsa_sha2_nistp256_key},
+ {group, ecdsa_sha2_nistp384_key},
+ {group, ecdsa_sha2_nistp521_key},
{group, dsa_pass_key},
{group, rsa_pass_key},
+ {group, host_user_key_differs},
+ {group, key_cb},
{group, internal_error},
daemon_already_started,
- server_password_option,
- server_userpassword_option,
double_close,
- ssh_connect_timeout,
- ssh_connect_arg4_timeout,
+ daemon_opt_fd,
+ multi_daemon_opt_fd,
packet_size_zero,
- ssh_daemon_minimal_remote_max_packet_size_option,
- ssh_msg_debug_fun_option_client,
- ssh_msg_debug_fun_option_server,
- id_string_no_opt_client,
- id_string_own_string_client,
- id_string_random_client,
- id_string_no_opt_server,
- id_string_own_string_server,
- id_string_random_server,
- {group, hardening_tests}
+ ssh_info_print
].
groups() ->
[{dsa_key, [], basic_tests()},
{rsa_key, [], basic_tests()},
+ {ecdsa_sha2_nistp256_key, [], basic_tests()},
+ {ecdsa_sha2_nistp384_key, [], basic_tests()},
+ {ecdsa_sha2_nistp521_key, [], basic_tests()},
+ {host_user_key_differs, [], [exec_key_differs1,
+ exec_key_differs2,
+ exec_key_differs3,
+ exec_key_differs_fail]},
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
- {internal_error, [], [internal_error]},
- {hardening_tests, [], [ssh_connect_nonegtimeout_connected_parallel,
- ssh_connect_nonegtimeout_connected_sequential,
- ssh_connect_negtimeout_parallel,
- ssh_connect_negtimeout_sequential,
- max_sessions_ssh_connect_parallel,
- max_sessions_ssh_connect_sequential,
- max_sessions_sftp_start_channel_parallel,
- max_sessions_sftp_start_channel_sequential
- ]}
+ {key_cb, [], [key_callback, key_callback_options]},
+ {internal_error, [], [internal_error]}
].
basic_tests() ->
[send, close, peername_sockname,
- exec, exec_compressed, shell, cli, known_hosts,
- idle_time, rekey, openssh_zlib_basic_test,
- misc_ssh_options, inet_option].
+ exec, exec_compressed,
+ shell, shell_no_unicode, shell_unicode_string,
+ cli, known_hosts,
+ idle_time, openssh_zlib_basic_test,
+ misc_ssh_options, inet_option, inet6_option].
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- case catch crypto:start() of
- ok ->
- Config;
- _Else ->
- {skip, "Crypto could not be started!"}
- end.
+ Config.
+
end_per_suite(_Config) ->
- ssh:stop(),
- crypto:stop().
+ ssh:stop().
+
%%--------------------------------------------------------------------
-init_per_group(hardening_tests, Config) ->
- init_per_group(dsa_key, Config);
init_per_group(dsa_key, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -112,6 +146,39 @@ init_per_group(rsa_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_rsa(DataDir, PrivDir),
Config;
+init_per_group(ecdsa_sha2_nistp256_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp256',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp384_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp384',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("384", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp521_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp521',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("521", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(rsa_pass_key, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -122,17 +189,77 @@ init_per_group(dsa_pass_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa_pass_pharse(DataDir, PrivDir, "Password"),
[{pass_phrase, {dsa_pass_phrase, "Password"}}| Config];
+init_per_group(host_user_key_differs, Config) ->
+ Data = ?config(data_dir, Config),
+ Sys = filename:join(?config(priv_dir, Config), system_rsa),
+ SysUsr = filename:join(Sys, user),
+ Usr = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+ file:make_dir(Sys),
+ file:make_dir(SysUsr),
+ file:make_dir(Usr),
+ file:copy(filename:join(Data, "ssh_host_rsa_key"), filename:join(Sys, "ssh_host_rsa_key")),
+ file:copy(filename:join(Data, "ssh_host_rsa_key.pub"), filename:join(Sys, "ssh_host_rsa_key.pub")),
+ file:copy(filename:join(Data, "id_ecdsa256"), filename:join(Usr, "id_ecdsa")),
+ file:copy(filename:join(Data, "id_ecdsa256.pub"), filename:join(Usr, "id_ecdsa.pub")),
+ ssh_test_lib:setup_ecdsa_auth_keys("256", Usr, SysUsr),
+ ssh_test_lib:setup_rsa_known_host(Sys, Usr),
+ Config;
+init_per_group(key_cb, Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config;
init_per_group(internal_error, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa(DataDir, PrivDir),
file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")),
Config;
+init_per_group(dir_options, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ %% Make unreadable dir:
+ Dir_unreadable = filename:join(PrivDir, "unread"),
+ ok = file:make_dir(Dir_unreadable),
+ {ok,F1} = file:read_file_info(Dir_unreadable),
+ ok = file:write_file_info(Dir_unreadable,
+ F1#file_info{mode = F1#file_info.mode band (bnot 8#00444)}),
+ %% Make readable file:
+ File_readable = filename:join(PrivDir, "file"),
+ ok = file:write_file(File_readable, <<>>),
+
+ %% Check:
+ case {file:read_file_info(Dir_unreadable),
+ file:read_file_info(File_readable)} of
+ {{ok, Id=#file_info{type=directory, access=Md}},
+ {ok, If=#file_info{type=regular, access=Mf}}} ->
+ AccessOK =
+ case {Md, Mf} of
+ {read, _} -> false;
+ {read_write, _} -> false;
+ {_, read} -> true;
+ {_, read_write} -> true;
+ _ -> false
+ end,
+
+ case AccessOK of
+ true ->
+ %% Save:
+ [{unreadable_dir, Dir_unreadable},
+ {readable_file, File_readable}
+ | Config];
+ false ->
+ ct:log("File#file_info : ~p~n"
+ "Dir#file_info : ~p",[If,Id]),
+ {skip, "File or dir mode settings failed"}
+ end;
+
+ NotDirFile ->
+ ct:log("{Dir,File} -> ~p",[NotDirFile]),
+ {skip, "File/Dir creation failed"}
+ end;
init_per_group(_, Config) ->
Config.
-end_per_group(hardening_tests, Config) ->
- end_per_group(dsa_key, Config);
end_per_group(dsa_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -149,6 +276,10 @@ end_per_group(rsa_pass_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_rsa(PrivDir),
Config;
+end_per_group(key_cb, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:clean_dsa(PrivDir),
+ Config;
end_per_group(internal_error, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -157,6 +288,33 @@ end_per_group(internal_error, Config) ->
end_per_group(_, Config) ->
Config.
%%--------------------------------------------------------------------
+init_per_testcase(TC, Config) when TC==shell_no_unicode ;
+ TC==shell_unicode_string ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ SysDir = ?config(data_dir, Config),
+ ssh:start(),
+ Sftpd = {_Pid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {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"}]),
+ 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()]),
+ wait_for_erlang_first_line([{io,IO}, {shell,Shell}, {sftpd, Sftpd} | Config]);
+
+init_per_testcase(inet6_option, Config) ->
+ case ssh_test_lib:has_inet6_address() of
+ true ->
+ init_per_testcase('__default__', Config);
+ false ->
+ {skip,"No ipv6 interface address"}
+ end;
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -166,6 +324,15 @@ end_per_testcase(TestCase, Config) when TestCase == server_password_option;
UserDir = filename:join(?config(priv_dir, Config), nopubkey),
ssh_test_lib:del_dirs(UserDir),
end_per_testcase(Config);
+end_per_testcase(TC, Config) when TC==shell_no_unicode ;
+ TC==shell_unicode_string ->
+ case ?config(sftpd, Config) of
+ {Pid, _, _} ->
+ ssh:stop_daemon(Pid),
+ ssh:stop();
+ _ ->
+ ssh:stop()
+ end;
end_per_testcase(_TestCase, Config) ->
end_per_testcase(Config).
end_per_testcase(_Config) ->
@@ -175,21 +342,18 @@ end_per_testcase(_Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-app_test() ->
- [{doc, "App lication consistency test."}].
+%%% Application consistency test.
app_test(Config) when is_list(Config) ->
?t:app_test(ssh),
ok.
%%--------------------------------------------------------------------
-appup_test() ->
- [{doc, "Appup file consistency test."}].
+%%% Appup file consistency test.
appup_test(Config) when is_list(Config) ->
ok = ?t:appup_test(ssh).
%%--------------------------------------------------------------------
-misc_ssh_options() ->
- [{doc, "Test that we can set some misc options not tested elsewhere, "
- "some options not yet present are not decided if we should support or "
- "if they need thier own test case."}].
+%%% Test that we can set some misc options not tested elsewhere
+%%% some options not yet present are not decided if we should support or
+%%% if they need thier own test case.
misc_ssh_options(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -203,8 +367,7 @@ misc_ssh_options(Config) when is_list(Config) ->
basic_test([{client_opts, CMiscOpt1}, {server_opts, SMiscOpt1}]).
%%--------------------------------------------------------------------
-inet_option() ->
- [{doc, "Test configuring IPv4"}].
+%%% Test configuring IPv4
inet_option(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -220,8 +383,7 @@ inet_option(Config) when is_list(Config) ->
{server_opts, [{inet, inet} | ServerOpts]}]).
%%--------------------------------------------------------------------
-inet6_option() ->
- [{doc, "Test configuring IPv6"}].
+%%% Test configuring IPv6
inet6_option(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -237,8 +399,7 @@ inet6_option(Config) when is_list(Config) ->
{server_opts, [{inet, inet6} | ServerOpts]}]).
%%--------------------------------------------------------------------
-exec() ->
- [{doc, "Test api function ssh_connection:exec"}].
+%%% Test api function ssh_connection:exec
exec(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -276,40 +437,46 @@ exec(Config) when is_list(Config) ->
ct:fail(Other1)
end,
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1),
+ ssh:close(ConnectionRef),
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-exec_compressed() ->
- [{doc, "Test that compression option works"}].
+%%% Test that compression option works
exec_compressed(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {compression, zlib},
- {failfun, fun ssh_test_lib:failfun/2}]),
+ case ssh_test_lib:ssh_supports(zlib, compression) of
+ false ->
+ {skip, "zlib compression is not supported"};
+
+ true ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {preferred_algorithms,[{compression, [zlib]}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false}]),
- {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId,
- "1+1.", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"2\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ok;
- Other ->
- ct:fail(Other)
- end,
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
- ssh:stop_daemon(Pid).
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId,
+ "1+1.", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"2\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end,
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
+ end.
%%--------------------------------------------------------------------
-idle_time() ->
- [{doc, "Idle timeout test"}].
+%%% Idle timeout test
idle_time(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -329,31 +496,9 @@ idle_time(Config) ->
{error, closed} = ssh_connection:session_channel(ConnectionRef, 1000)
end,
ssh:stop_daemon(Pid).
-%%--------------------------------------------------------------------
-rekey() ->
- [{doc, "Idle timeout test"}].
-rekey(Config) ->
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2},
- {rekey_limit, 0}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {rekey_limit, 0}]),
- receive
- after 200000 ->
- %%By this time rekeying would have been done
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid)
- end.
%%--------------------------------------------------------------------
-shell() ->
- [{doc, "Test that ssh:shell/2 works"}].
+%%% Test that ssh:shell/2 works
shell(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -369,21 +514,99 @@ shell(Config) when is_list(Config) ->
{'EXIT', _, _} ->
ct:fail(no_ssh_connection);
ErlShellStart ->
- ct:pal("Erlang shell start: ~p~n", [ErlShellStart]),
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
do_shell(IO, Shell)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test that we could user different types of host pubkey and user pubkey
+exec_key_differs1(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp256']).
+
+exec_key_differs2(Config) -> exec_key_differs(Config, ['ssh-dss','ecdsa-sha2-nistp256']).
+
+exec_key_differs3(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp384','ecdsa-sha2-nistp256']).
+
+
+
+exec_key_differs(Config, UserPKAlgs) ->
+ case lists:usort(['ssh-rsa'|UserPKAlgs])
+ -- ssh_transport:supported_algorithms(public_key)
+ of
+ [] ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system_rsa),
+ SystemUserDir = filename:join(SystemDir, user),
+ UserDir = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, SystemUserDir},
+ {preferred_algorithms,
+ [{public_key,['ssh-rsa']}]}]),
+ 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}
+ ]),
+
+
+ receive
+ {'EXIT', _, _} ->
+ ct:fail(no_ssh_connection);
+ ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
+ do_shell(IO, Shell)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end;
+
+ UnsupportedPubKeys ->
+ {skip, io_lib:format("~p unsupported",[UnsupportedPubKeys])}
+ end.
+
+%%--------------------------------------------------------------------
+exec_key_differs_fail(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system_rsa),
+ SystemUserDir = filename:join(SystemDir, user),
+ UserDir = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, SystemUserDir},
+ {preferred_algorithms,
+ [{public_key,['ssh-rsa']}]}]),
+ 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']}]),
+ receive
+ {'EXIT', _, _} ->
+ ok;
+ ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
+ ct:fail(connection_not_rejected)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
-cli() ->
- [{doc, ""}].
cli(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
-
+
+ TmpDir = filename:join(?config(priv_dir,Config), "tmp"),
+ ok = ssh_test_lib:del_dirs(TmpDir),
+ ok = file:make_dir(TmpDir),
+
{_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
{password, "morot"},
- {ssh_cli, {ssh_test_cli, [cli]}},
+ {ssh_cli, {ssh_test_cli, [cli,TmpDir]}},
{subsystems, []},
{failfun, fun ssh_test_lib:failfun/2}]),
ct:sleep(500),
@@ -401,17 +624,20 @@ cli(Config) when is_list(Config) ->
{ssh_cm, ConnectionRef,
{data,0,0, <<"\r\nYou are accessing a dummy, type \"q\" to exit\r\n\n">>}} ->
ok = ssh_connection:send(ConnectionRef, ChannelId, <<"q">>)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId}} ->
ok
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
-daemon_already_started() ->
- [{doc, "Test that get correct error message if you try to start a daemon",
- "on an adress that already runs a daemon see also seq10667"}].
+%%% Test that get correct error message if you try to start a daemon
+%%% on an adress that already runs a daemon see also seq10667
daemon_already_started(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
UserDir = ?config(priv_dir, Config),
@@ -426,166 +652,7 @@ daemon_already_started(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-server_password_option() ->
- [{doc, "validate to server that uses the 'password' option"}].
-server_password_option(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"}]),
-
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
-
- Reason = "Unable to connect using the available authentication methods",
-
- {error, Reason} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "vego"},
- {password, "foo"},
- {user_interaction, false},
- {user_dir, UserDir}]),
-
- ct:pal("Test of wrong password: Error msg: ~p ~n", [Reason]),
-
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-
-server_userpassword_option() ->
- [{doc, "validate to server that uses the 'password' option"}].
-server_userpassword_option(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, PrivDir},
- {user_passwords, [{"vego", "morot"}]}]),
-
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "vego"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
- ssh:close(ConnectionRef),
-
- Reason = "Unable to connect using the available authentication methods",
-
- {error, Reason} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
- {error, Reason} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "vego"},
- {password, "foo"},
- {user_interaction, false},
- {user_dir, UserDir}]),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-ssh_msg_debug_fun_option_client() ->
- [{doc, "validate client that uses the 'ssh_msg_debug_fun' option"}].
-ssh_msg_debug_fun_option_client(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"},
- {failfun, fun ssh_test_lib:failfun/2}]),
- Parent = self(),
- DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
-
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_dir, UserDir},
- {user_interaction, false},
- {ssh_msg_debug_fun,DbgFun}]),
- %% Beware, implementation knowledge:
- gen_fsm:send_all_state_event(ConnectionRef,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
- receive
- {msg_dbg,X={ConnectionRef,false,<<"Hello">>,<<>>}} ->
- ct:log("Got expected dbg msg ~p",[X]),
- ssh:stop_daemon(Pid);
- {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
- ct:log("Got dbg msg but bad ConnectionRef (~p expected) ~p",[ConnectionRef,X]),
- ssh:stop_daemon(Pid),
- {fail, "Bad ConnectionRef received"};
- {msg_dbg,X} ->
- ct:log("Got bad dbg msg ~p",[X]),
- ssh:stop_daemon(Pid),
- {fail,"Bad msg received"}
- after 1000 ->
- ssh:stop_daemon(Pid),
- {fail,timeout}
- end.
-
-%%--------------------------------------------------------------------
-ssh_msg_debug_fun_option_server() ->
- [{doc, "validate client that uses the 'ssh_msg_debug_fun' option"}].
-ssh_msg_debug_fun_option_server(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
-
- Parent = self(),
- DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
- ConnFun = fun(_,_,_) -> Parent ! {connection_pid,self()} end,
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"},
- {failfun, fun ssh_test_lib:failfun/2},
- {connectfun, ConnFun},
- {ssh_msg_debug_fun, DbgFun}]),
- _ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_dir, UserDir},
- {user_interaction, false}]),
- receive
- {connection_pid,Server} ->
- %% Beware, implementation knowledge:
- gen_fsm:send_all_state_event(Server,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
- receive
- {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
- ct:log("Got expected dbg msg ~p",[X]),
- ssh:stop_daemon(Pid);
- {msg_dbg,X} ->
- ct:log("Got bad dbg msg ~p",[X]),
- ssh:stop_daemon(Pid),
- {fail,"Bad msg received"}
- after 3000 ->
- ssh:stop_daemon(Pid),
- {fail,timeout2}
- end
- after 3000 ->
- ssh:stop_daemon(Pid),
- {fail,timeout1}
- end.
-
-%%--------------------------------------------------------------------
-known_hosts() ->
- [{doc, "check that known_hosts is updated correctly"}].
+%%% check that known_hosts is updated correctly
known_hosts(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -611,8 +678,7 @@ known_hosts(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-pass_phrase() ->
- [{doc, "Test that we can use keyes protected by pass phrases"}].
+%%% Test that we can use keyes protected by pass phrases
pass_phrase(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -631,27 +697,75 @@ pass_phrase(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+%%% Test that we can use key callback
+key_callback(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NoPubKeyDir = filename:join(UserDir, "nopubkey"),
+ file:make_dir(NoPubKeyDir),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ ConnectOpts = [{silently_accept_hosts, true},
+ {user_dir, NoPubKeyDir},
+ {user_interaction, false},
+ {key_cb, ssh_key_cb}],
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, ConnectOpts),
+
+ {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% Test that we can use key callback with callback options
+key_callback_options(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ NoPubKeyDir = filename:join(UserDir, "nopubkey"),
+ file:make_dir(NoPubKeyDir),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok, PrivKey} = file:read_file(filename:join(UserDir, "id_dsa")),
+
+ ConnectOpts = [{silently_accept_hosts, true},
+ {user_dir, NoPubKeyDir},
+ {user_interaction, false},
+ {key_cb, {ssh_key_cb_options, [{priv_key, PrivKey}]}}],
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, ConnectOpts),
+
+ {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh:stop_daemon(Pid).
+
-internal_error() ->
- [{doc,"Test that client does not hang if disconnects due to internal error"}].
+%%--------------------------------------------------------------------
+%%% Test that client does not hang if disconnects due to internal error
internal_error(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
{error, Error} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false}]),
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
check_error(Error),
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-send() ->
- [{doc, "Test ssh_connection:send/3"}].
+%%% Test ssh_connection:send/3
send(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -671,8 +785,7 @@ send(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-peername_sockname() ->
- [{doc, "Test ssh:connection_info([peername, sockname])"}].
+%%% Test ssh:connection_info([peername, sockname])
peername_sockname(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -694,13 +807,13 @@ peername_sockname(Config) when is_list(Config) ->
ssh:connection_info(ConnectionRef, [peer]),
[{sockname, {HostSockClient,PortSockClient} = ClientSock}] =
ssh:connection_info(ConnectionRef, [sockname]),
- ct:pal("Client: ~p ~p", [ClientPeer, ClientSock]),
+ ct:log("Client: ~p ~p", [ClientPeer, ClientSock]),
receive
{ssh_cm, ConnectionRef, {data, ChannelId, _, Response}} ->
{PeerNameSrv,SockNameSrv} = binary_to_term(Response),
{HostPeerSrv,PortPeerSrv} = PeerNameSrv,
{HostSockSrv,PortSockSrv} = SockNameSrv,
- ct:pal("Server: ~p ~p", [PeerNameSrv, SockNameSrv]),
+ ct:log("Server: ~p ~p", [PeerNameSrv, SockNameSrv]),
host_equal(HostPeerSrv, HostSockClient),
PortPeerSrv = PortSockClient,
host_equal(HostSockSrv, HostPeerClient),
@@ -708,7 +821,7 @@ peername_sockname(Config) when is_list(Config) ->
host_equal(HostSockSrv, Host),
PortSockSrv = Port
after 10000 ->
- throw(timeout)
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
host_equal(H1, H2) ->
@@ -722,8 +835,7 @@ ips(Name) when is_list(Name) ->
%%--------------------------------------------------------------------
-close() ->
- [{doc, "Client receives close when server closes"}].
+%%% Client receives close when server closes
close(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -743,12 +855,11 @@ close(Config) when is_list(Config) ->
{ssh_cm, Client,{closed, ChannelId}} ->
ok
after 5000 ->
- ct:fail(timeout)
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
-double_close() ->
- [{doc, "Simulate that we try to close an already closed connection"}].
+%%% Simulate that we try to close an already closed connection
double_close(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -769,90 +880,66 @@ double_close(Config) when is_list(Config) ->
ok = ssh:close(CM).
%%--------------------------------------------------------------------
-ssh_connect_timeout() ->
- [{doc, "Test connect_timeout option in ssh:connect/4"}].
-ssh_connect_timeout(_Config) ->
- ConnTimeout = 2000,
- {error,{faked_transport,connect,TimeoutToTransport}} =
- ssh:connect("localhost", 12345,
- [{transport,{tcp,?MODULE,tcp_closed}},
- {connect_timeout,ConnTimeout}],
- 1000),
- case TimeoutToTransport of
- ConnTimeout -> ok;
- Other ->
- ct:log("connect_timeout is ~p but transport received ~p",[ConnTimeout,Other]),
- {fail,"ssh:connect/4 wrong connect_timeout received in transport"}
- end.
+daemon_opt_fd(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+
+ {ok,S1} = gen_tcp:listen(0,[]),
+ {ok,Fd1} = prim_inet:getfd(S1),
-%% Help for the test above
-connect(_Host, _Port, _Opts, Timeout) ->
- {error, {faked_transport,connect,Timeout}}.
+ {ok,Pid1} = ssh:daemon(0, [{system_dir, SystemDir},
+ {fd,Fd1},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,{_Host1,Port1}} = inet:sockname(S1),
+ {ok, C1} = ssh:connect("localhost", Port1, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ exit(C1, {shutdown, normal}),
+ ssh:stop_daemon(Pid1),
+ gen_tcp:close(S1).
%%--------------------------------------------------------------------
-ssh_connect_arg4_timeout() ->
- [{doc, "Test fourth argument in ssh:connect/4"}].
-ssh_connect_arg4_timeout(_Config) ->
- Timeout = 1000,
- Parent = self(),
- %% start the server
- Server = spawn(fun() ->
- {ok,Sl} = gen_tcp:listen(0,[]),
- {ok,{_,Port}} = inet:sockname(Sl),
- Parent ! {port,self(),Port},
- Rsa = gen_tcp:accept(Sl),
- ct:log("Server gen_tcp:accept got ~p",[Rsa]),
- receive after 2*Timeout -> ok end %% let client timeout first
- end),
-
- %% Get listening port
- Port = receive
- {port,Server,ServerPort} -> ServerPort
- end,
-
- %% try to connect with a timeout, but "supervise" it
- Client = spawn(fun() ->
- T0 = now(),
- Rc = ssh:connect("localhost",Port,[],Timeout),
- ct:log("Client ssh:connect got ~p",[Rc]),
- Parent ! {done,self(),Rc,T0}
- end),
-
- %% Wait for client reaction on the connection try:
- receive
- {done, Client, {error,timeout}, T0} ->
- Msp = ms_passed(T0, now()),
- exit(Server,hasta_la_vista___baby),
- Low = 0.9*Timeout,
- High = 1.1*Timeout,
- ct:log("Timeout limits: ~.4f - ~.4f ms, timeout "
- "was ~.4f ms, expected ~p ms",[Low,High,Msp,Timeout]),
- %%ct:log("Timeout limits: ~p--~p, my timeout was ~p, expected ~p",[Low,High,Msp0,Timeout]),
- if
- Low<Msp, Msp<High -> ok;
- true -> {fail, "timeout not within limits"}
- end;
+multi_daemon_opt_fd(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
- {done, Client, {error,Other}, _T0} ->
- ct:log("Error message \"~p\" from the client is unexpected.",[{error,Other}]),
- {fail, "Unexpected error message"};
-
- {done, Client, {ok,_Ref}, _T0} ->
- {fail,"ssh-connected ???"}
- after
- 5000 ->
- exit(Server,hasta_la_vista___baby),
- exit(Client,hasta_la_vista___baby),
- {fail, "Didn't timeout"}
- end.
+ Test =
+ fun() ->
+ {ok,S} = gen_tcp:listen(0,[]),
+ {ok,Fd} = prim_inet:getfd(S),
-%% Help function
-%% N2-N1
-ms_passed(N1={_,_,M1}, N2={_,_,M2}) ->
- {0,{0,Min,Sec}} = calendar:time_difference(calendar:now_to_local_time(N1),
- calendar:now_to_local_time(N2)),
- 1000 * (Min*60 + Sec + (M2-M1)/1000000).
+ {ok,Pid} = ssh:daemon(0, [{system_dir, SystemDir},
+ {fd,Fd},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,{_Host,Port}} = inet:sockname(S),
+ {ok, C} = ssh:connect("localhost", Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ {S,Pid,C}
+ end,
+
+ Tests = [Test(),Test(),Test(),Test(),Test(),Test()],
+
+ [begin
+ gen_tcp:close(S),
+ ssh:stop_daemon(Pid),
+ exit(C, {shutdown, normal})
+ end || {S,Pid,C} <- Tests].
%%--------------------------------------------------------------------
packet_size_zero(Config) ->
@@ -879,317 +966,139 @@ packet_size_zero(Config) ->
receive
{ssh_cm,Conn,{data,Chan,_Type,_Msg1}} = M ->
- ct:pal("Got ~p",[M]),
+ ct:log("Got ~p",[M]),
ct:fail(doesnt_obey_max_packet_size_0)
after 5000 ->
ok
end.
%%--------------------------------------------------------------------
-ssh_daemon_minimal_remote_max_packet_size_option(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
-
- {Server, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {user_passwords, [{"vego", "morot"}]},
- {failfun, fun ssh_test_lib:failfun/2},
- {minimal_remote_max_packet_size, 14}]),
- Conn =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {user, "vego"},
- {password, "morot"}]),
-
- %% Try the limits of the minimal_remote_max_packet_size:
- {ok, _ChannelId} = ssh_connection:session_channel(Conn, 100, 14, infinity),
- {open_error,_,"Maximum packet size below 14 not supported",_} =
- ssh_connection:session_channel(Conn, 100, 13, infinity),
-
- ssh:close(Conn),
- ssh:stop_daemon(Server).
-
-%%--------------------------------------------------------------------
-id_string_no_opt_client(Config) ->
- {Server, Host, Port} = fake_daemon(Config),
- {error,_} = ssh:connect(Host, Port, []),
- receive
- {id,Server,"SSH-2.0-Erlang/"++Vsn} ->
- true = expected_ssh_vsn(Vsn);
- {id,Server,Other} ->
- ct:fail("Unexpected id: ~s.",[Other])
- end.
-
-%%--------------------------------------------------------------------
-id_string_own_string_client(Config) ->
- {Server, Host, Port} = fake_daemon(Config),
- {error,_} = ssh:connect(Host, Port, [{id_string,"Pelle"}]),
- receive
- {id,Server,"SSH-2.0-Pelle\r\n"} ->
- ok;
- {id,Server,Other} ->
- ct:fail("Unexpected id: ~s.",[Other])
- end.
-
-%%--------------------------------------------------------------------
-id_string_random_client(Config) ->
- {Server, Host, Port} = fake_daemon(Config),
- {error,_} = ssh:connect(Host, Port, [{id_string,random}]),
- receive
- {id,Server,Id="SSH-2.0-Erlang"++_} ->
- ct:fail("Unexpected id: ~s.",[Id]);
- {id,Server,Rnd="SSH-2.0-"++_} ->
- ct:log("Got ~s.",[Rnd]);
- {id,Server,Id} ->
- ct:fail("Unexpected id: ~s.",[Id])
- end.
-
-%%--------------------------------------------------------------------
-id_string_no_opt_server(Config) ->
- {_Server, Host, Port} = std_daemon(Config, []),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false}]),
- {ok,"SSH-2.0-Erlang/"++Vsn} = gen_tcp:recv(S1, 0, 2000),
- true = expected_ssh_vsn(Vsn).
-
+shell_no_unicode(Config) ->
+ new_do_shell(?config(io,Config),
+ [new_prompt,
+ {type,"io:format(\"hej ~p~n\",[42])."},
+ {expect,"hej 42"},
+ {expect,"ok"},
+ new_prompt,
+ {type,"exit()."}
+ ]).
+
%%--------------------------------------------------------------------
-id_string_own_string_server(Config) ->
- {_Server, Host, Port} = std_daemon(Config, [{id_string,"Olle"}]),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false}]),
- {ok,"SSH-2.0-Olle\r\n"} = gen_tcp:recv(S1, 0, 2000).
+shell_unicode_string(Config) ->
+ new_do_shell(?config(io,Config),
+ [new_prompt,
+ {type,"io:format(\"こにちわ~ts~n\",[\"四二\"])."},
+ {expect,"こにちわ四二"},
+ {expect,"ok"},
+ new_prompt,
+ {type,"exit()."}
+ ]).
%%--------------------------------------------------------------------
-id_string_random_server(Config) ->
- {_Server, Host, Port} = std_daemon(Config, [{id_string,random}]),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false}]),
- {ok,"SSH-2.0-"++Rnd} = gen_tcp:recv(S1, 0, 2000),
- case Rnd of
- "Erlang"++_ -> ct:log("Id=~p",[Rnd]),
- {fail,got_default_id};
- "Olle\r\n" -> {fail,got_previous_tests_value};
- _ -> ct:log("Got ~s.",[Rnd])
- end.
+%%% Test basic connection with openssh_zlib
+openssh_zlib_basic_test(Config) ->
+ case ssh_test_lib:ssh_supports(['[email protected]',none], compression) of
+ {false,L} ->
+ {skip, io_lib:format("~p compression is not supported",[L])};
-%%--------------------------------------------------------------------
-ssh_connect_negtimeout_parallel(Config) -> ssh_connect_negtimeout(Config,true).
-ssh_connect_negtimeout_sequential(Config) -> ssh_connect_negtimeout(Config,false).
-
-ssh_connect_negtimeout(Config, Parallel) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- NegTimeOut = 2000, % ms
- ct:log("Parallel: ~p",[Parallel]),
+ true ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
- {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {parallel_login, Parallel},
- {negotiation_timeout, NegTimeOut},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- {ok,Socket} = gen_tcp:connect(Host, Port, []),
- ct:pal("And now sleeping 1.2*NegTimeOut (~p ms)...", [round(1.2 * NegTimeOut)]),
- receive after round(1.2 * NegTimeOut) -> ok end,
-
- case inet:sockname(Socket) of
- {ok,_} -> ct:fail("Socket not closed");
- {error,_} -> ok
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {preferred_algorithms,[{compression, ['[email protected]']}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {preferred_algorithms,[{compression, ['[email protected]',
+ none]}]}
+ ]),
+ ok = ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
end.
%%--------------------------------------------------------------------
-ssh_connect_nonegtimeout_connected_parallel() ->
- [{doc, "Test that ssh connection does not timeout if the connection is established (parallel)"}].
-ssh_connect_nonegtimeout_connected_parallel(Config) ->
- ssh_connect_nonegtimeout_connected(Config, true).
-
-ssh_connect_nonegtimeout_connected_sequential() ->
- [{doc, "Test that ssh connection does not timeout if the connection is established (non-parallel)"}].
-ssh_connect_nonegtimeout_connected_sequential(Config) ->
- ssh_connect_nonegtimeout_connected(Config, false).
-
-
-ssh_connect_nonegtimeout_connected(Config, Parallel) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- NegTimeOut = 20000, % ms
- ct:log("Parallel: ~p",[Parallel]),
-
- {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {parallel_login, Parallel},
- {negotiation_timeout, NegTimeOut},
- {failfun, fun ssh_test_lib:failfun/2}]),
- ct:pal("~p Listen ~p:~p",[_Pid,_Host,Port]),
- ct:sleep(500),
-
- IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
- receive
- Error = {'EXIT', _, _} ->
- ct:pal("~p",[Error]),
- ct:fail(no_ssh_connection);
- ErlShellStart ->
- ct:pal("---Erlang shell start: ~p~n", [ErlShellStart]),
- one_shell_op(IO, NegTimeOut),
- one_shell_op(IO, NegTimeOut),
- ct:pal("And now sleeping 1.2*NegTimeOut (~p ms)...", [round(1.2 * NegTimeOut)]),
- receive after round(1.2 * NegTimeOut) -> ok end,
- one_shell_op(IO, NegTimeOut)
- end,
- exit(Shell, kill).
-
+ssh_info_print(Config) ->
+ %% Just check that ssh_print:info() crashes
+ PrivDir = ?config(priv_dir, Config),
+ PrintFile = filename:join(PrivDir,info),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
-one_shell_op(IO, TimeOut) ->
- ct:pal("One shell op: Waiting for prompter"),
+ Parent = self(),
+ UnexpFun = fun(Msg,_Peer) ->
+ Parent ! {unexpected,Msg,self()},
+ skip
+ end,
+ ConnFun = fun(_,_,_) -> Parent ! {connect,self()} end,
+
+ {DaemonRef, Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {unexpectedfun, UnexpFun},
+ {connectfun, ConnFun},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ClientConnRef1 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {unexpectedfun, UnexpFun},
+ {user_interaction, false}]),
+ ClientConnRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {unexpectedfun, UnexpFun},
+ {user_interaction, false}]),
receive
- ErlPrompt0 -> ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
- after TimeOut -> ct:fail("Timeout waiting for promter")
+ {connect,DaemonConnRef} ->
+ ct:log("DaemonRef=~p, DaemonConnRef=~p, ClientConnRefs=~p",[DaemonRef, DaemonConnRef,
+ [ClientConnRef1,ClientConnRef2]
+ ])
+ after 2000 ->
+ ok
end,
- IO ! {input, self(), "2*3*7.\r\n"},
- receive
- Echo0 -> ct:log("Echo: ~p ~n", [Echo0])
- after TimeOut -> ct:fail("Timeout waiting for echo")
- end,
+ {ok,D} = file:open(PrintFile, write),
+ ssh_info:print(D),
+ ok = file:close(D),
- receive
- ?NEWLINE -> ct:log("NEWLINE received", [])
- after TimeOut ->
- receive Any1 -> ct:log("Bad NEWLINE: ~p",[Any1])
- after 0 -> ct:fail("Timeout waiting for NEWLINE")
- end
- end,
+ {ok,Bin} = file:read_file(PrintFile),
+ ct:log("~s",[Bin]),
receive
- Result0 -> ct:log("Result: ~p~n", [Result0])
- after TimeOut -> ct:fail("Timeout waiting for result")
- end.
-
-%%--------------------------------------------------------------------
-
-openssh_zlib_basic_test() ->
- [{doc, "Test basic connection with openssh_zlib"}].
-openssh_zlib_basic_test(Config) ->
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {compression, openssh_zlib}]),
- ok = ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-
-max_sessions_ssh_connect_parallel(Config) ->
- max_sessions(Config, true, connect_fun(ssh__connect,Config)).
-max_sessions_ssh_connect_sequential(Config) ->
- max_sessions(Config, false, connect_fun(ssh__connect,Config)).
-
-max_sessions_sftp_start_channel_parallel(Config) ->
- max_sessions(Config, true, connect_fun(ssh_sftp__start_channel, Config)).
-max_sessions_sftp_start_channel_sequential(Config) ->
- max_sessions(Config, false, connect_fun(ssh_sftp__start_channel, Config)).
-
-
-%%%---- helpers:
-connect_fun(ssh__connect, Config) ->
- fun(Host,Port) ->
- ssh_test_lib:connect(Host, Port,
- [{silently_accept_hosts, true},
- {user_dir, ?config(priv_dir,Config)},
- {user_interaction, false},
- {user, "carni"},
- {password, "meat"}
- ])
- %% ssh_test_lib returns R when ssh:connect returns {ok,R}
- end;
-connect_fun(ssh_sftp__start_channel, _Config) ->
- fun(Host,Port) ->
- {ok,_Pid,ConnRef} =
- ssh_sftp:start_channel(Host, Port,
- [{silently_accept_hosts, true},
- {user, "carni"},
- {password, "meat"}
- ]),
- ConnRef
+ {unexpected, Msg, Pid} ->
+ ct:log("~p got unexpected msg ~p",[Pid,Msg]),
+ ct:log("process_info(~p) = ~n~p",[Pid,process_info(Pid)]),
+ ok = ssh:close(ClientConnRef1),
+ ok = ssh:close(ClientConnRef2),
+ ok = ssh:stop_daemon(DaemonRef),
+ {fail,"unexpected msg"}
+ after 1000 ->
+ ok = ssh:close(ClientConnRef1),
+ ok = ssh:close(ClientConnRef2),
+ ok = ssh:stop_daemon(DaemonRef)
end.
-max_sessions(Config, ParallelLogin, Connect0) when is_function(Connect0,2) ->
- Connect = fun(Host,Port) ->
- R = Connect0(Host,Port),
- ct:pal("Connect(~p,~p) -> ~p",[Host,Port,R]),
- R
- end,
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- MaxSessions = 5,
- {Pid, Host, Port} = ssh_test_lib:daemon([
- {system_dir, SystemDir},
- {user_dir, UserDir},
- {user_passwords, [{"carni", "meat"}]},
- {parallel_login, ParallelLogin},
- {max_sessions, MaxSessions}
- ]),
- ct:pal("~p Listen ~p:~p for max ~p sessions",[Pid,Host,Port,MaxSessions]),
- try [Connect(Host,Port) || _ <- lists:seq(1,MaxSessions)]
- of
- Connections ->
- %% Step 1 ok: could set up max_sessions connections
- ct:log("Connections up: ~p",[Connections]),
- [_|_] = Connections,
-
- %% Now try one more than alowed:
- ct:pal("Info Report might come here...",[]),
- try Connect(Host,Port)
- of
- _ConnectionRef1 ->
- ssh:stop_daemon(Pid),
- {fail,"Too many connections accepted"}
- catch
- error:{badmatch,{error,"Connection closed"}} ->
- %% Step 2 ok: could not set up max_sessions+1 connections
- %% This is expected
- %% Now stop one connection and try to open one more
- ok = ssh:close(hd(Connections)),
- try Connect(Host,Port)
- of
- _ConnectionRef1 ->
- %% Step 3 ok: could set up one more connection after killing one
- %% Thats good.
- ssh:stop_daemon(Pid),
- ok
- catch
- error:{badmatch,{error,"Connection closed"}} ->
- %% Bad indeed. Could not set up one more connection even after killing
- %% one existing. Very bad.
- ssh:stop_daemon(Pid),
- {fail,"Does not decrease # active sessions"}
- end
- end
- catch
- error:{badmatch,{error,"Connection closed"}} ->
- ssh:stop_daemon(Pid),
- {fail,"Too few connections accepted"}
- end.
-
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
-
%% Due to timing the error message may or may not be delivered to
%% the "tcp-application" before the socket closed message is recived
check_error("Invalid state") ->
ok;
check_error("Connection closed") ->
ok;
+check_error("Selection of key exchange algorithm failed") ->
+ ok;
check_error(Error) ->
ct:fail(Error).
@@ -1205,28 +1114,38 @@ basic_test(Config) ->
do_shell(IO, Shell) ->
receive
ErlPrompt0 ->
- ct:pal("Erlang prompt: ~p~n", [ErlPrompt0])
+ ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
end,
IO ! {input, self(), "1+1.\r\n"},
receive
Echo0 ->
- ct:pal("Echo: ~p ~n", [Echo0])
+ ct:log("Echo: ~p ~n", [Echo0])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
?NEWLINE ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
Result0 = <<"2">> ->
- ct:pal("Result: ~p~n", [Result0])
+ ct:log("Result: ~p~n", [Result0])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
?NEWLINE ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
ErlPrompt1 ->
- ct:pal("Erlang prompt: ~p~n", [ErlPrompt1])
+ ct:log("Erlang prompt: ~p~n", [ErlPrompt1])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
exit(Shell, kill).
%%Does not seem to work in the testserver!
@@ -1237,7 +1156,7 @@ do_shell(IO, Shell) ->
%% end,
%% receive
%% Echo1 ->
- %% ct:pal("Echo: ~p ~n", [Echo1])
+ %% ct:log("Echo: ~p ~n", [Echo1])
%% end,
%% receive
%% ?NEWLINE ->
@@ -1245,7 +1164,7 @@ do_shell(IO, Shell) ->
%% end,
%% receive
%% Result1 ->
- %% ct:pal("Result: ~p~n", [Result1])
+ %% ct:log("Result: ~p~n", [Result1])
%% end,
%% receive
%% {'EXIT', Shell, killed} ->
@@ -1253,44 +1172,90 @@ do_shell(IO, Shell) ->
%% end.
-std_daemon(Config, ExtraOpts) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- {_Server, _Host, _Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2} | ExtraOpts]).
-
-expected_ssh_vsn(Str) ->
- try
- {ok,L} = application:get_all_key(ssh),
- proplists:get_value(vsn,L,"")++"\r\n"
- of
- Str -> true;
- "\r\n" -> true;
- _ -> false
- catch
- _:_ -> true %% ssh not started so we dont't know
+%%--------------------------------------------------------------------
+wait_for_erlang_first_line(Config) ->
+ receive
+ {'EXIT', _, _} ->
+ {fail,no_ssh_connection};
+ <<"Eshell ",_/binary>> = _ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [_ErlShellStart]),
+ Config;
+ Other ->
+ ct:log("Unexpected answer from ssh server: ~p",[Other]),
+ {fail,unexpected_answer}
+ after 10000 ->
+ ct:log("No answer from ssh-server"),
+ {fail,timeout}
end.
-
-
-fake_daemon(_Config) ->
- Parent = self(),
- %% start the server
- Server = spawn(fun() ->
- {ok,Sl} = gen_tcp:listen(0,[]),
- {ok,{Host,Port}} = inet:sockname(Sl),
- Parent ! {sockname,self(),Host,Port},
- Rsa = gen_tcp:accept(Sl),
- ct:log("Server gen_tcp:accept got ~p",[Rsa]),
- {ok,S} = Rsa,
- receive
- {tcp, S, Id} -> Parent ! {id,self(),Id}
- end
- end),
- %% Get listening host and port
+
+
+
+new_do_shell(IO, List) -> new_do_shell(IO, 0, List).
+
+new_do_shell(IO, N, [new_prompt|More]) ->
+ new_do_shell(IO, N+1, More);
+
+new_do_shell(IO, N, Ops=[{Order,Arg}|More]) ->
+ Pfx = prompt_prefix(),
+ PfxSize = size(Pfx),
receive
- {sockname,Server,ServerHost,ServerPort} -> {Server, ServerHost, ServerPort}
+ _X = <<"\r\n">> ->
+ ct:log("Skip newline ~p",[_X]),
+ new_do_shell(IO, N, Ops);
+
+ <<Pfx:PfxSize/binary,P1,"> ">> when (P1-$0)==N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+
+ <<Pfx:PfxSize/binary,P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+
+ <<Pfx:PfxSize/binary,P1,P2,P3,"> ">> when (P1-$0)*100 + (P2-$0)*10 + (P3-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+
+ Err when element(1,Err)==error ->
+ ct:fail("new_do_shell error: ~p~n",[Err]);
+
+ RecBin when Order==expect ; Order==expect_echo ->
+ ct:log("received ~p",[RecBin]),
+ RecStr = string:strip(unicode:characters_to_list(RecBin)),
+ ExpStr = string:strip(Arg),
+ case lists:prefix(ExpStr, RecStr) of
+ true when Order==expect ->
+ ct:log("Matched ~ts",[RecStr]),
+ new_do_shell(IO, N, More);
+ true when Order==expect_echo ->
+ ct:log("Matched echo ~ts",[RecStr]),
+ new_do_shell(IO, N, More);
+ false ->
+ ct:fail("*** Expected ~p, but got ~p",[string:strip(ExpStr),RecStr])
+ end
+ after 30000 ->
+ ct:log("Meassage queue of ~p:~n~p",
+ [self(), erlang:process_info(self(), messages)]),
+ case Order of
+ expect -> ct:fail("timeout, expected ~p",[string:strip(Arg)]);
+ type -> ct:fail("timeout, no prompt")
+ end
+ end;
+
+new_do_shell(_, _, []) ->
+ ok.
+
+prompt_prefix() ->
+ case node() of
+ nonode@nohost -> <<>>;
+ Node -> list_to_binary(
+ lists:concat(["(",Node,")"]))
end.
+
+new_do_shell_prompt(IO, N, type, Str, More) ->
+ ct:log("Matched prompt ~p to trigger sending of next line to server",[N]),
+ IO ! {input, self(), Str++"\r\n"},
+ ct:log("Promt '~p> ', Sent ~ts",[N,Str++"\r\n"]),
+ new_do_shell(IO, N, [{expect_echo,Str}|More]); % expect echo of the sent line
+new_do_shell_prompt(IO, N, Op, Str, More) ->
+ ct:log("Matched prompt ~p",[N]),
+ new_do_shell(IO, N, [{Op,Str}|More]).
+
+%%--------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_bench.spec b/lib/ssh/test/ssh_bench.spec
new file mode 100644
index 0000000000..029f0bd074
--- /dev/null
+++ b/lib/ssh/test/ssh_bench.spec
@@ -0,0 +1 @@
+{suites,"../ssh_test",[ssh_benchmark_SUITE]}.
diff --git a/lib/ssh/test/ssh_benchmark_SUITE.erl b/lib/ssh/test/ssh_benchmark_SUITE.erl
new file mode 100644
index 0000000000..fe90da3028
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE.erl
@@ -0,0 +1,536 @@
+%%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssh_benchmark_SUITE).
+-compile(export_all).
+
+-include_lib("common_test/include/ct_event.hrl").
+-include_lib("common_test/include/ct.hrl").
+
+-include_lib("ssh/src/ssh.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_connect.hrl").
+-include_lib("ssh/src/ssh_userauth.hrl").
+
+
+suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]}].
+%%suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() -> [{group, opensshc_erld}
+%% {group, erlc_opensshd}
+ ].
+
+groups() ->
+ [{opensshc_erld, [{repeat, 3}], [openssh_client_shell,
+ openssh_client_sftp]}
+ ].
+
+
+init_per_suite(Config) ->
+ catch ssh:stop(),
+ try
+ report_client_algorithms(),
+ ok = ssh:start(),
+ {ok,TracerPid} = erlang_trace(),
+ [{tracer_pid,TracerPid} | init_sftp_dirs(Config)]
+ catch
+ C:E ->
+ {skip, io_lib:format("Couldn't start ~p:~p",[C,E])}
+ end.
+
+end_per_suite(_Config) ->
+ catch ssh:stop(),
+ ok.
+
+
+
+init_per_group(opensshc_erld, Config) ->
+ case ssh_test_lib:ssh_type() of
+ openSSH ->
+ DataDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, UserDir),
+ ssh_test_lib:setup_rsa(DataDir, UserDir),
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
+ Common = ssh_test_lib:intersect_bi_dir(
+ ssh_test_lib:intersection(ssh:default_algorithms(),
+ ssh_test_lib:default_algorithms(sshc))),
+ [{c_kexs, ssh_test_lib:sshc(kex)},
+ {c_ciphers, ssh_test_lib:sshc(cipher)},
+ {common_algs, Common}
+ | Config];
+ _ ->
+ {skip, "No OpenSsh client found"}
+ end;
+
+init_per_group(erlc_opensshd, _) ->
+ {skip, "Group erlc_opensshd not implemented"};
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+
+init_per_testcase(_Func, Conf) ->
+ Conf.
+
+end_per_testcase(_Func, _Conf) ->
+ ok.
+
+
+init_sftp_dirs(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ SrcDir = filename:join(UserDir, "sftp_src"),
+ ok = file:make_dir(SrcDir),
+ SrcFile = "big_data",
+ DstDir = filename:join(UserDir, "sftp_dst"),
+ ok = file:make_dir(DstDir),
+ N = 100 * 1024*1024,
+ ok = file:write_file(filename:join(SrcDir,SrcFile), crypto:rand_bytes(N)),
+ [{sftp_src_dir,SrcDir}, {sftp_dst_dir,DstDir}, {src_file,SrcFile}, {sftp_size,N}
+ | Config].
+
+%%%================================================================
+openssh_client_shell(Config) ->
+ lists:foreach(
+ fun(PrefAlgs=[{kex,[Kex]}]) when Kex == 'diffie-hellman-group-exchange-sha256' ->
+ lists:foreach(
+ fun(Grp) ->
+ openssh_client_shell(Config,
+ [{preferred_algorithms, PrefAlgs},
+ {dh_gex_groups, [Grp]}
+ ])
+ end, moduli());
+ (PrefAlgs) ->
+ openssh_client_shell(Config,
+ [{preferred_algorithms, PrefAlgs}])
+ end, variants(kex,Config) ++ variants(cipher,Config)
+ ).
+
+
+openssh_client_shell(Config, Options) ->
+ SystemDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ KnownHosts = filename:join(UserDir, "known_hosts"),
+
+ {ok, TracerPid} = erlang_trace(),
+ {ServerPid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SystemDir},
+ {public_key_alg, ssh_dsa},
+ {failfun, fun ssh_test_lib:failfun/2} |
+ Options]),
+ ct:sleep(500),
+
+ Data = lists:duplicate(100000, $a),
+ Cmd = lists:concat(["ssh -p ",Port,
+ " -o UserKnownHostsFile=", KnownHosts,
+ " -o \"StrictHostKeyChecking no\"",
+ " localhost '\"",Data,"\"'."]),
+%% ct:pal("Cmd ="++Cmd),
+
+ Parent = self(),
+ SlavePid = spawn(fun() ->
+ Parent ! {self(),os:cmd(Cmd)}
+ end),
+ receive
+ {SlavePid, _ClientResponse} ->
+%% ct:pal("ClientResponse = ~p",[_ClientResponse]),
+ {ok, List} = get_trace_list(TracerPid),
+ Times = find_times(List, [accept_to_hello, kex, kex_to_auth, auth, to_prompt]),
+ Algs = find_algs(List),
+ ct:pal("Algorithms = ~p~n~nTimes = ~p",[Algs,Times]),
+ lists:foreach(
+ fun({Tag,Value,Unit}) ->
+ EventData =
+ case Tag of
+ {A,B} when A==encrypt ; A==decrypt ->
+ [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Cipher ",A," ",B," [",Unit,"]"])}
+ ];
+ kex ->
+ KexAlgStr = fmt_alg(Algs#alg.kex, List),
+ [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Erl server kex ",KexAlgStr," [",Unit,"]"])}
+ ];
+ _ when is_atom(Tag) ->
+ [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Erl server ",Tag," [",Unit,"]"])}
+ ]
+ end,
+ ct:pal("ct_event:notify ~p",[EventData]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = EventData})
+ end, Times),
+ ssh:stop_daemon(ServerPid),
+ ok
+ after 10000 ->
+ ssh:stop_daemon(ServerPid),
+ exit(SlavePid, kill),
+ {fail, timeout}
+ end.
+
+
+%%%================================================================
+openssh_client_sftp(Config) ->
+ lists:foreach(
+ fun(PrefAlgs) ->
+ openssh_client_sftp(Config, [{preferred_algorithms,PrefAlgs}])
+ end, variants(cipher,Config)).
+
+
+openssh_client_sftp(Config, Options) ->
+ SystemDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ SftpSrcDir = ?config(sftp_src_dir, Config),
+ SrcFile = ?config(src_file, Config),
+ SrcSize = ?config(sftp_size, Config),
+ KnownHosts = filename:join(UserDir, "known_hosts"),
+
+ {ok, TracerPid} = erlang_trace(),
+ {ServerPid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SystemDir},
+ {public_key_alg, ssh_dsa},
+ {subsystems,[ssh_sftpd:subsystem_spec([%{cwd, SftpSrcDir},
+ {root, SftpSrcDir}])]},
+ {failfun, fun ssh_test_lib:failfun/2}
+ | Options]),
+ ct:sleep(500),
+ Cmd = lists:concat(["sftp",
+ " -b -",
+ " -P ",Port,
+ " -o UserKnownHostsFile=", KnownHosts,
+ " -o \"StrictHostKeyChecking no\"",
+ " localhost:",SrcFile
+ ]),
+%% ct:pal("Cmd = ~p",[Cmd]),
+
+ Parent = self(),
+ SlavePid = spawn(fun() ->
+ Parent ! {self(),os:cmd(Cmd)}
+ end),
+ receive
+ {SlavePid, _ClientResponse} ->
+ ct:pal("ClientResponse = ~p",[_ClientResponse]),
+ {ok, List} = get_trace_list(TracerPid),
+%%ct:pal("List=~p",[List]),
+ Times = find_times(List, [channel_open_close]),
+ Algs = find_algs(List),
+ ct:pal("Algorithms = ~p~n~nTimes = ~p",[Algs,Times]),
+ lists:foreach(
+ fun({{A,B},Value,Unit}) when A==encrypt ; A==decrypt ->
+ Data = [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Sftp Cipher ",A," ",B," [",Unit,"]"])}
+ ],
+ ct:pal("sftp ct_event:notify ~p",[Data]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = Data});
+ ({channel_open_close,Value,Unit}) ->
+ Cipher = fmt_alg(Algs#alg.encrypt, List),
+ Data = [{value, round( (1024*Value) / SrcSize )},
+ {suite, ?MODULE},
+ {name, mk_name(["Sftp transfer ",Cipher," [",Unit," per kbyte]"])}
+ ],
+ ct:pal("sftp ct_event:notify ~p",[Data]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = Data});
+ (_) ->
+ skip
+ end, Times),
+ ssh:stop_daemon(ServerPid),
+ ok
+ after 10000 ->
+ ssh:stop_daemon(ServerPid),
+ exit(SlavePid, kill),
+ {fail, timeout}
+ end.
+
+%%%================================================================
+variants(Tag, Config) ->
+ TagType =
+ case proplists:get_value(Tag, ssh:default_algorithms()) of
+ [{_,_}|_] -> one_way;
+ [A|_] when is_atom(A) -> two_way
+ end,
+ [ [{Tag,tag_value(TagType,Alg)}]
+ || Alg <- proplists:get_value(Tag, ?config(common_algs,Config))
+ ].
+
+tag_value(two_way, Alg) -> [Alg];
+tag_value(one_way, Alg) -> [{client2server,[Alg]},
+ {server2client,[Alg]}].
+
+%%%----------------------------------------------------------------
+fmt_alg(Alg, List) when is_atom(Alg) ->
+ fmt_alg(atom_to_list(Alg), List);
+fmt_alg(Alg = "diffie-hellman-group-exchange-sha" ++ _, List) ->
+ try
+ integer_to_list(find_gex_size_string(List))
+ of
+ GexSize -> lists:concat([Alg," ",GexSize])
+ catch
+ _:_ -> Alg
+ end;
+fmt_alg(Alg, _List) ->
+ Alg.
+
+%%%----------------------------------------------------------------
+mk_name(Name) -> [char(C) || C <- lists:concat(Name)].
+
+char($-) -> $_;
+char(C) -> C.
+
+%%%----------------------------------------------------------------
+find_times(L, Xs) ->
+ [find_time(X,L) || X <- Xs] ++
+ function_algs_times_sizes([{ssh_transport,encrypt,2},
+ {ssh_transport,decrypt,2},
+ {ssh_message,decode,1},
+ {ssh_message,encode,1}], L).
+
+-record(call, {
+ mfa,
+ pid,
+ t_call,
+ t_return,
+ args,
+ result
+ }).
+
+%%%----------------
+-define(send(M), fun(C=#call{mfa = {ssh_message,encode,1},
+ args = [M]}) ->
+ C#call.t_return
+ end).
+
+-define(recv(M), fun(C=#call{mfa = {ssh_message,decode,1},
+ result = M}) ->
+ C#call.t_call
+ end).
+
+find_time(accept_to_hello, L) ->
+ [T0,T1] = find([fun(C=#call{mfa = {ssh_acceptor,handle_connection,5}}) ->
+ C#call.t_call
+ end,
+ fun(C=#call{mfa = {ssh_connection_handler,hello,_},
+ args = [socket_control|_]}) ->
+ C#call.t_return
+ end
+ ], L, []),
+ {accept_to_hello, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(kex, L) ->
+ [T0,T1] = find([fun(C=#call{mfa = {ssh_connection_handler,hello,_},
+ args = [socket_control|_]}) ->
+ C#call.t_call
+ end,
+ ?send(#ssh_msg_newkeys{})
+ ], L, []),
+ {kex, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(kex_to_auth, L) ->
+ [T0,T1] = find([?send(#ssh_msg_newkeys{}),
+ ?recv(#ssh_msg_userauth_request{})
+ ], L, []),
+ {kex_to_auth, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(auth, L) ->
+ [T0,T1] = find([?recv(#ssh_msg_userauth_request{}),
+ ?send(#ssh_msg_userauth_success{})
+ ], L, []),
+ {auth, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(to_prompt, L) ->
+ [T0,T1] = find([fun(C=#call{mfa = {ssh_acceptor,handle_connection,5}}) ->
+ C#call.t_call
+ end,
+ ?recv(#ssh_msg_channel_request{request_type="env"})
+ ], L, []),
+ {to_prompt, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(channel_open_close, L) ->
+ [T0,T1] = find([?recv(#ssh_msg_channel_request{request_type="subsystem"}),
+ ?send(#ssh_msg_channel_close{})
+ ], L, []),
+ {channel_open_close, now2micro_sec(now_diff(T1,T0)), microsec}.
+
+
+
+find([F|Fs], [C|Cs], Acc) when is_function(F,1) ->
+ try
+ F(C)
+ of
+ T -> find(Fs, Cs, [T|Acc])
+ catch
+ _:_ -> find([F|Fs], Cs, Acc)
+ end;
+find([], _, Acc) ->
+ lists:reverse(Acc).
+
+
+find_algs(L) ->
+ {value, #call{result={ok,Algs}}} =
+ lists:keysearch({ssh_transport,select_algorithm,3}, #call.mfa, L),
+ Algs.
+
+find_gex_size_string(L) ->
+ %% server
+ {value, #call{result={ok,{Size, _}}}} =
+ lists:keysearch({public_key,dh_gex_group,4}, #call.mfa, L),
+ Size.
+
+%%%----------------
+function_algs_times_sizes(EncDecs, L) ->
+ Raw = [begin
+ {Tag,Size} = function_ats_result(EncDec, C),
+ {Tag, Size, now2micro_sec(now_diff(T1,T0))}
+ end
+ || EncDec <- EncDecs,
+ C = #call{mfa = ED,
+ % args = Args, %%[S,Data],
+ t_call = T0,
+ t_return = T1} <- L,
+ ED == EncDec
+ ],
+ [{Alg, round(1024*Time/Size), "microsec per kbyte"} % Microseconds per 1k bytes.
+ || {Alg,Size,Time} <- lists:foldl(fun increment/2, [], Raw)].
+
+function_ats_result({ssh_transport,encrypt,2}, #call{args=[S,Data]}) ->
+ {{encrypt,S#ssh.encrypt}, size(Data)};
+function_ats_result({ssh_transport,decrypt,2}, #call{args=[S,Data]}) ->
+ {{decrypt,S#ssh.decrypt}, size(Data)};
+function_ats_result({ssh_message,encode,1}, #call{result=Data}) ->
+ {encode, size(Data)};
+function_ats_result({ssh_message,decode,1}, #call{args=[Data]}) ->
+ {decode, size(Data)}.
+
+
+increment({Alg,Sz,T}, [{Alg,SumSz,SumT}|Acc]) ->
+ [{Alg,SumSz+Sz,SumT+T} | Acc];
+increment(Spec, [X|Acc]) ->
+ [X | increment(Spec,Acc)]; % Not so many Alg, 2 or 3
+increment({Alg,Sz,T},[]) ->
+ [{Alg,Sz,T}].
+
+%%%----------------------------------------------------------------
+%%%
+%%% API for the traceing
+%%%
+get_trace_list(TracerPid) ->
+ TracerPid ! {get_trace_list,self()},
+ receive
+ {trace_list,L} -> {ok, pair_events(lists:reverse(L))}
+ after 5000 -> {error,no_reply}
+ end.
+
+erlang_trace() ->
+ TracerPid = spawn(fun trace_loop/0),
+ 0 = erlang:trace(new, true, [call,timestamp,{tracer,TracerPid}]),
+ [init_trace(MFA, tp(MFA))
+ || MFA <- [{ssh_acceptor,handle_connection,5},
+ {ssh_connection_handler,hello,2},
+ {ssh_message,encode,1},
+ {ssh_message,decode,1},
+ {ssh_transport,select_algorithm,3},
+ {ssh_transport,encrypt,2},
+ {ssh_transport,decrypt,2},
+ {ssh_message,encode,1},
+ {ssh_message,decode,1},
+ {public_key,dh_gex_group,4} % To find dh_gex group size
+ ]],
+ {ok, TracerPid}.
+
+tp({_M,_F,Arity}) ->
+ [{lists:duplicate(Arity,'_'), [], [{return_trace}]}].
+
+%%%----------------------------------------------------------------
+init_trace(MFA = {Module,_,_}, TP) ->
+ case code:is_loaded(Module) of
+ false -> code:load_file(Module);
+ _ -> ok
+ end,
+ erlang:trace_pattern(MFA, TP, [local]).
+
+
+trace_loop() ->
+ trace_loop([]).
+
+trace_loop(L) ->
+ receive
+ {get_trace_list, From} ->
+ From ! {trace_list, L},
+ trace_loop(L);
+ Ev ->
+ trace_loop([Ev|L])
+ end.
+
+pair_events(L) ->
+ pair_events(L, []).
+
+pair_events([{trace_ts,Pid,call,{M,F,Args},TS0} | L], Acc) ->
+ Arity = length(Args),
+ {ReturnValue,TS1} = find_return(Pid, {M,F,Arity}, L),
+ pair_events(L, [#call{mfa = {M,F,Arity},
+ pid = Pid,
+ t_call = TS0,
+ t_return = TS1,
+ args = Args,
+ result = ReturnValue} | Acc]);
+pair_events([_|L], Acc) ->
+ pair_events(L, Acc);
+pair_events([], Acc) ->
+ lists:reverse(Acc).
+
+
+find_return(Pid, MFA,
+ [{trace_ts, Pid, return_from, MFA, ReturnValue, TS}|_]) ->
+ {ReturnValue, TS};
+find_return(Pid, MFA, [_|L]) ->
+ find_return(Pid, MFA, L);
+find_return(_, _, []) ->
+ {undefined, undefined}.
+
+%%%----------------------------------------------------------------
+report_client_algorithms() ->
+ try
+ ssh_test_lib:extract_algos( ssh_test_lib:default_algorithms(sshc) )
+ of
+ ClientAlgs ->
+ ct:pal("The client supports:~n~p",[ClientAlgs])
+ catch
+ Cls:Err ->
+ ct:pal("Testing client about algorithms failed:~n~p ~p",[Cls,Err])
+ end.
+
+%%%----------------------------------------------------------------
+
+
+now2sec({A,B,C}) -> A*1000000 + B + C/1000000.
+
+now2micro_sec({A,B,C}) -> (A*1000000 + B)*1000000 + C.
+
+now_diff({A1,B1,C1}, {A0,B0,C0}) -> {A1-A0, B1-B0, C1-C0}.
+
+%%%================================================================
+moduli() ->
+ [{1023, 5, 16#CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D182EB7},
+ {2047, 5, 16#F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE5E381EF},
+ {4095, 2, 16#C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BA7321EB},
+ {6143, 5, 16#FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C3BEB637},
+ {8191, 2, 16#DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE37347869A3}].
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa b/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa b/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index e3871b3feb..6e90faf0e8 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,6 +22,7 @@
-module(ssh_connection_SUITE).
-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_connect.hrl").
-compile(export_all).
@@ -34,6 +36,9 @@
%% suite() ->
%% [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [{timetrap,{minutes,2}}].
+
all() ->
[
{group, openssh},
@@ -46,7 +51,8 @@ all() ->
gracefull_invalid_long_start,
gracefull_invalid_long_start_no_nl,
stop_listener,
- start_subsystem_on_closed_channel
+ start_subsystem_on_closed_channel,
+ max_channels_option
].
groups() ->
[{openssh, [], payload() ++ ptty()}].
@@ -64,23 +70,19 @@ ptty() ->
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- case catch crypto:start() of
- ok ->
- Config;
- _Else ->
- {skip, "Crypto could not be started!"}
- end.
+ Config.
-end_per_suite(_Config) ->
- crypto:stop().
+end_per_suite(Config) ->
+ Config.
%%--------------------------------------------------------------------
-init_per_group(openssh, _Config) ->
+init_per_group(openssh, Config) ->
case gen_tcp:connect("localhost", 22, []) of
{error,econnrefused} ->
{skip,"No openssh deamon"};
{ok, Socket} ->
- gen_tcp:close(Socket)
+ gen_tcp:close(Socket),
+ ssh_test_lib:openssh_sanity_check(Config)
end;
init_per_group(_, Config) ->
Config.
@@ -92,7 +94,7 @@ end_per_group(_, Config) ->
init_per_testcase(_TestCase, Config) ->
%% To make sure we start clean as it is not certain that
%% end_per_testcase will be run!
- ssh:stop(),
+ end_per_testcase(Config),
ssh:start(),
Config.
@@ -115,20 +117,28 @@ simple_exec(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"testing\n">>}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% receive close messages
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -150,20 +160,28 @@ small_cat(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {data, ChannelId0, 0, Data}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% receive close messages
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
big_cat() ->
@@ -182,7 +200,7 @@ big_cat(Config) when is_list(Config) ->
%% pre-adjust receive window so the other end doesn't block
ssh_connection:adjust_window(ConnectionRef, ChannelId0, size(Data)),
- ct:pal("sending ~p byte binary~n",[size(Data)]),
+ ct:log("sending ~p byte binary~n",[size(Data)]),
ok = ssh_connection:send(ConnectionRef, ChannelId0, Data, 10000),
ok = ssh_connection:send_eof(ConnectionRef, ChannelId0),
@@ -193,10 +211,10 @@ big_cat(Config) when is_list(Config) ->
{ok, Other} ->
case size(Data) =:= size(Other) of
true ->
- ct:pal("received and sent data are same"
+ ct:log("received and sent data are same"
"size but do not match~n",[]);
false ->
- ct:pal("sent ~p but only received ~p~n",
+ ct:log("sent ~p but only received ~p~n",
[size(Data), size(Other)])
end,
ct:fail(receive_data_mismatch);
@@ -207,11 +225,15 @@ big_cat(Config) when is_list(Config) ->
%% receive close messages (eof already consumed)
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
- ok
+ ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -230,14 +252,20 @@ send_after_exit(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, _ExitStatus}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
case ssh_connection:send(ConnectionRef, ChannelId0, Data, 2000) of
{error, closed} -> ok;
@@ -269,7 +297,7 @@ ptty_alloc(Config) when is_list(Config) ->
{user_interaction, false}]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId,
- [{term, default_term()}, {width, 70}, {high, 20}]),
+ [{term, os:getenv("TERM", ?DEFAULT_TERMINAL)}, {width, 70}, {height, 20}]),
ssh:close(ConnectionRef).
@@ -282,7 +310,7 @@ ptty_alloc_pixel(Config) when is_list(Config) ->
{user_interaction, false}]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId,
- [{term, default_term()}, {pixel_widh, 630}, {pixel_hight, 470}]),
+ [{term, os:getenv("TERM", ?DEFAULT_TERMINAL)}, {pixel_widh, 630}, {pixel_hight, 470}]),
ssh:close(ConnectionRef).
%%--------------------------------------------------------------------
@@ -446,11 +474,13 @@ gracefull_invalid_version(Config) when is_list(Config) ->
ok = gen_tcp:send(S, ["SSH-8.-1","\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
gracefull_invalid_start(Config) when is_list(Config) ->
@@ -466,11 +496,13 @@ gracefull_invalid_start(Config) when is_list(Config) ->
ok = gen_tcp:send(S, ["foobar","\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
gracefull_invalid_long_start(Config) when is_list(Config) ->
@@ -486,11 +518,13 @@ gracefull_invalid_long_start(Config) when is_list(Config) ->
ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -507,11 +541,13 @@ gracefull_invalid_long_start_no_nl(Config) when is_list(Config) ->
ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
stop_listener() ->
@@ -602,6 +638,88 @@ start_subsystem_on_closed_channel(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+max_channels_option() ->
+ [{doc, "Test max_channels option"}].
+
+max_channels_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {max_channels, 3},
+ {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}
+ ]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId1} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId2} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId3} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId4} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId5} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, _ChannelId6} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ %%%---- shell
+ ok = ssh_connection:shell(ConnectionRef,ChannelId0),
+ receive
+ {ssh_cm,ConnectionRef, {data, ChannelId0, 0, <<"Eshell",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("CLI Timeout")
+ end,
+
+ %%%---- subsystem "echo_n"
+ success = ssh_connection:subsystem(ConnectionRef, ChannelId1, "echo_n", infinity),
+
+ %%%---- exec #1
+ success = ssh_connection:exec(ConnectionRef, ChannelId2, "testing1.\n", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, ChannelId2, 0, <<"testing1",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec #1 Timeout")
+ end,
+
+ %%%---- ptty
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId3, []),
+
+ %%%---- exec #2
+ failure = ssh_connection:exec(ConnectionRef, ChannelId4, "testing2.\n", infinity),
+
+ %%%---- close the shell
+ ok = ssh_connection:send(ConnectionRef, ChannelId0, "exit().\n", 5000),
+
+ %%%---- wait for the subsystem to terminate
+ receive
+ {ssh_cm,ConnectionRef,{closed,ChannelId0}} -> ok
+ after 5000 ->
+ ct:log("Timeout waiting for '{ssh_cm,~p,{closed,~p}}'~n"
+ "Message queue:~n~p",
+ [ConnectionRef,ChannelId0,erlang:process_info(self(),messages)]),
+ ct:fail("exit Timeout",[])
+ end,
+
+ %%%---- exec #3
+ success = ssh_connection:exec(ConnectionRef, ChannelId5, "testing3.\n", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, ChannelId5, 0, <<"testing3",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec #3 Timeout")
+ end,
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
big_cat_rx(ConnectionRef, ChannelId) ->
@@ -647,11 +765,3 @@ ssh_exec(Cmd) ->
spawn(fun() ->
io:format(Cmd ++ "\n")
end).
-
-default_term() ->
- case os:getenv("TERM") of
- false ->
- "vt100";
- Str when is_list(Str)->
- Str
- end.
diff --git a/lib/ssh/test/ssh_echo_server.erl b/lib/ssh/test/ssh_echo_server.erl
index 315ffecfd7..96c9aad135 100644
--- a/lib/ssh/test/ssh_echo_server.erl
+++ b/lib/ssh/test/ssh_echo_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/test/ssh_key_cb.erl b/lib/ssh/test/ssh_key_cb.erl
new file mode 100644
index 0000000000..388ec2ecc1
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb.erl
@@ -0,0 +1,45 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb).
+-behaviour(ssh_client_key_api).
+-compile(export_all).
+
+add_host_key(_, _, _) ->
+ ok.
+
+is_host_key(_, _, _, _) ->
+ true.
+
+user_key('ssh-dss', Opts) ->
+ UserDir = proplists:get_value(user_dir, Opts),
+ KeyFile = filename:join(filename:dirname(UserDir), "id_dsa"),
+ {ok, KeyBin} = file:read_file(KeyFile),
+ [Entry] = public_key:pem_decode(KeyBin),
+ Key = public_key:pem_entry_decode(Entry),
+ {ok, Key};
+
+user_key(_Alg, _Opt) ->
+ {error, "Not Supported"}.
diff --git a/lib/ssh/test/ssh_key_cb_options.erl b/lib/ssh/test/ssh_key_cb_options.erl
new file mode 100644
index 0000000000..afccb34f0f
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb_options.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb_options).
+-behaviour(ssh_client_key_api).
+-compile(export_all).
+
+add_host_key(_, _, _) ->
+ ok.
+
+is_host_key(_, _, _, _) ->
+ true.
+
+user_key('ssh-dss', Opts) ->
+ KeyCbOpts = proplists:get_value(key_cb_private, Opts),
+ KeyBin = proplists:get_value(priv_key, KeyCbOpts),
+ [Entry] = public_key:pem_decode(KeyBin),
+ Key = public_key:pem_entry_decode(Entry),
+ {ok, Key};
+
+user_key(_Alg, _Opt) ->
+ {error, "Not Supported"}.
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
new file mode 100644
index 0000000000..ba0107efd6
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -0,0 +1,1187 @@
+%%
+%% %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.
+%% 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(ssh_options_SUITE).
+
+%%% This test suite tests different options for the ssh functions
+
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/file.hrl").
+
+
+%%% Test cases
+-export([connectfun_disconnectfun_client/1,
+ disconnectfun_option_client/1,
+ disconnectfun_option_server/1,
+ id_string_no_opt_client/1,
+ id_string_no_opt_server/1,
+ id_string_own_string_client/1,
+ id_string_own_string_server/1,
+ id_string_random_client/1,
+ id_string_random_server/1,
+ max_sessions_sftp_start_channel_parallel/1,
+ max_sessions_sftp_start_channel_sequential/1,
+ max_sessions_ssh_connect_parallel/1,
+ max_sessions_ssh_connect_sequential/1,
+ server_password_option/1,
+ server_userpassword_option/1,
+ server_pwdfun_option/1,
+ server_pwdfun_4_option/1,
+ server_pwdfun_4_option_repeat/1,
+ ssh_connect_arg4_timeout/1,
+ ssh_connect_negtimeout_parallel/1,
+ ssh_connect_negtimeout_sequential/1,
+ ssh_connect_nonegtimeout_connected_parallel/1,
+ ssh_connect_nonegtimeout_connected_sequential/1,
+ ssh_connect_timeout/1, connect/4,
+ ssh_daemon_minimal_remote_max_packet_size_option/1,
+ ssh_msg_debug_fun_option_client/1,
+ ssh_msg_debug_fun_option_server/1,
+ system_dir_option/1,
+ unexpectedfun_option_client/1,
+ unexpectedfun_option_server/1,
+ user_dir_option/1,
+ connectfun_disconnectfun_server/1
+ ]).
+
+%%% Common test callbacks
+-export([suite/0, all/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
+ ]).
+
+
+-define(NEWLINE, <<"\r\n">>).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,6}}].
+
+all() ->
+ [connectfun_disconnectfun_server,
+ connectfun_disconnectfun_client,
+ server_password_option,
+ server_userpassword_option,
+ server_pwdfun_option,
+ server_pwdfun_4_option,
+ server_pwdfun_4_option_repeat,
+ {group, dir_options},
+ ssh_connect_timeout,
+ ssh_connect_arg4_timeout,
+ ssh_daemon_minimal_remote_max_packet_size_option,
+ ssh_msg_debug_fun_option_client,
+ ssh_msg_debug_fun_option_server,
+ disconnectfun_option_server,
+ disconnectfun_option_client,
+ unexpectedfun_option_server,
+ unexpectedfun_option_client,
+ id_string_no_opt_client,
+ id_string_own_string_client,
+ id_string_random_client,
+ id_string_no_opt_server,
+ id_string_own_string_server,
+ id_string_random_server,
+ {group, hardening_tests}
+ ].
+
+groups() ->
+ [{hardening_tests, [], [ssh_connect_nonegtimeout_connected_parallel,
+ ssh_connect_nonegtimeout_connected_sequential,
+ ssh_connect_negtimeout_parallel,
+ ssh_connect_negtimeout_sequential,
+ max_sessions_ssh_connect_parallel,
+ max_sessions_ssh_connect_sequential,
+ max_sessions_sftp_start_channel_parallel,
+ max_sessions_sftp_start_channel_sequential
+ ]},
+ {dir_options, [], [user_dir_option,
+ system_dir_option]}
+ ].
+
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ssh:stop().
+
+%%--------------------------------------------------------------------
+init_per_group(hardening_tests, Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config;
+init_per_group(dir_options, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ %% Make unreadable dir:
+ Dir_unreadable = filename:join(PrivDir, "unread"),
+ ok = file:make_dir(Dir_unreadable),
+ {ok,F1} = file:read_file_info(Dir_unreadable),
+ ok = file:write_file_info(Dir_unreadable,
+ F1#file_info{mode = F1#file_info.mode band (bnot 8#00444)}),
+ %% Make readable file:
+ File_readable = filename:join(PrivDir, "file"),
+ ok = file:write_file(File_readable, <<>>),
+
+ %% Check:
+ case {file:read_file_info(Dir_unreadable),
+ file:read_file_info(File_readable)} of
+ {{ok, Id=#file_info{type=directory, access=Md}},
+ {ok, If=#file_info{type=regular, access=Mf}}} ->
+ AccessOK =
+ case {Md, Mf} of
+ {read, _} -> false;
+ {read_write, _} -> false;
+ {_, read} -> true;
+ {_, read_write} -> true;
+ _ -> false
+ end,
+
+ case AccessOK of
+ true ->
+ %% Save:
+ [{unreadable_dir, Dir_unreadable},
+ {readable_file, File_readable}
+ | Config];
+ false ->
+ ct:log("File#file_info : ~p~n"
+ "Dir#file_info : ~p",[If,Id]),
+ {skip, "File or dir mode settings failed"}
+ end;
+
+ NotDirFile ->
+ ct:log("{Dir,File} -> ~p",[NotDirFile]),
+ {skip, "File/Dir creation failed"}
+ end;
+init_per_group(_, Config) ->
+ Config.
+
+end_per_group(_, Config) ->
+ Config.
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ ssh:start(),
+ Config.
+
+end_per_testcase(TestCase, Config) when TestCase == server_password_option;
+ TestCase == server_userpassword_option;
+ TestCase == server_pwdfun_option;
+ TestCase == server_pwdfun_4_option ->
+ UserDir = filename:join(?config(priv_dir, Config), nopubkey),
+ ssh_test_lib:del_dirs(UserDir),
+ end_per_testcase(Config);
+end_per_testcase(_TestCase, Config) ->
+ end_per_testcase(Config).
+
+end_per_testcase(_Config) ->
+ ssh:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+
+%%% validate to server that uses the 'password' option
+server_password_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ ct:log("Test of wrong password: Error msg: ~p ~n", [Reason]),
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% validate to server that uses the 'password' option
+server_userpassword_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {user_passwords, [{"vego", "morot"}]}]),
+
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%%% validate to server that uses the 'pwdfun' option
+server_pwdfun_option(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ CHKPWD = fun("foo",Pwd) -> Pwd=="bar";
+ (_,_) -> false
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {pwdfun,CHKPWD}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% validate to server that uses the 'pwdfun/4' option
+server_pwdfun_4_option(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ PWDFUN = fun("foo",Pwd,{_,_},undefined) -> Pwd=="bar";
+ ("fie",Pwd,{_,_},undefined) -> {Pwd=="bar",new_state};
+ ("bandit",_,_,_) -> disconnect;
+ (_,_,_,_) -> false
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {pwdfun,PWDFUN}]),
+ ConnectionRef1 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef1),
+
+ ConnectionRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "fie"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef2),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "fie"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "bandit"},
+ {password, "pwd breaking"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+server_pwdfun_4_option_repeat(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ %% Test that the state works
+ Parent = self(),
+ PWDFUN = fun("foo",P="bar",_,S) -> Parent!{P,S},true;
+ (_,P,_,S=undefined) -> Parent!{P,S},{false,1};
+ (_,P,_,S) -> Parent!{P,S}, {false,S+1}
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {auth_methods,"keyboard-interactive"},
+ {pwdfun,PWDFUN}]),
+
+ %% Try with passwords "incorrect", "Bad again" and finally "bar"
+ KIFFUN = fun(_,_,_) ->
+ K={k,self()},
+ case get(K) of
+ undefined ->
+ put(K,1),
+ ["incorrect"];
+ 2 ->
+ put(K,3),
+ ["bar"];
+ S->
+ put(K,S+1),
+ ["Bad again"]
+ end
+ end,
+
+ ConnectionRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {keyboard_interact_fun, KIFFUN},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef2),
+ ssh:stop_daemon(Pid),
+
+ lists:foreach(fun(Expect) ->
+ receive
+ Expect -> ok;
+ Other -> ct:fail("Expect: ~p~nReceived ~p",[Expect,Other])
+ after
+ 2000 -> ct:fail("Timeout expecting ~p",[Expect])
+ end
+ end, [{"incorrect",undefined},
+ {"Bad again",1},
+ {"bar",2}]).
+
+%%--------------------------------------------------------------------
+system_dir_option(Config) ->
+ DirUnread = proplists:get_value(unreadable_dir,Config),
+ FileRead = proplists:get_value(readable_file,Config),
+
+ case ssh_test_lib:daemon([{system_dir, DirUnread}]) of
+ {error,{eoptions,{{system_dir,DirUnread},eacces}}} ->
+ ok;
+ {Pid1,_Host1,Port1} when is_pid(Pid1),is_integer(Port1) ->
+ ssh:stop_daemon(Pid1),
+ ct:fail("Didn't detect that dir is unreadable", [])
+ end,
+
+ case ssh_test_lib:daemon([{system_dir, FileRead}]) of
+ {error,{eoptions,{{system_dir,FileRead},enotdir}}} ->
+ ok;
+ {Pid2,_Host2,Port2} when is_pid(Pid2),is_integer(Port2) ->
+ ssh:stop_daemon(Pid2),
+ ct:fail("Didn't detect that option is a plain file", [])
+ end.
+
+
+user_dir_option(Config) ->
+ DirUnread = proplists:get_value(unreadable_dir,Config),
+ FileRead = proplists:get_value(readable_file,Config),
+ %% Any port will do (beware, implementation knowledge!):
+ Port = 65535,
+
+ case ssh:connect("localhost", Port, [{user_dir, DirUnread}]) of
+ {error,{eoptions,{{user_dir,DirUnread},eacces}}} ->
+ ok;
+ {error,econnrefused} ->
+ ct:fail("Didn't detect that dir is unreadable", [])
+ end,
+
+ case ssh:connect("localhost", Port, [{user_dir, FileRead}]) of
+ {error,{eoptions,{{user_dir,FileRead},enotdir}}} ->
+ ok;
+ {error,econnrefused} ->
+ ct:fail("Didn't detect that option is a plain file", [])
+ end.
+
+%%--------------------------------------------------------------------
+%%% validate client that uses the 'ssh_msg_debug_fun' option
+ssh_msg_debug_fun_option_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ Parent = self(),
+ DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
+
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {ssh_msg_debug_fun,DbgFun}]),
+ %% Beware, implementation knowledge:
+ gen_fsm:send_all_state_event(ConnectionRef,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
+ receive
+ {msg_dbg,X={ConnectionRef,false,<<"Hello">>,<<>>}} ->
+ ct:log("Got expected dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid);
+ {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
+ ct:log("Got dbg msg but bad ConnectionRef (~p expected) ~p",[ConnectionRef,X]),
+ ssh:stop_daemon(Pid),
+ {fail, "Bad ConnectionRef received"};
+ {msg_dbg,X} ->
+ ct:log("Got bad dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid),
+ {fail,"Bad msg received"}
+ after 1000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+connectfun_disconnectfun_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ Ref = make_ref(),
+ ConnFun = fun(_,_,_) -> Parent ! {connect,Ref} end,
+ DiscFun = fun(R) -> Parent ! {disconnect,Ref,R} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {disconnectfun, DiscFun},
+ {connectfun, ConnFun}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ receive
+ {connect,Ref} ->
+ ssh:close(ConnectionRef),
+ receive
+ {disconnect,Ref,R} ->
+ ct:log("Disconnect result: ~p",[R]),
+ ssh:stop_daemon(Pid)
+ after 2000 ->
+ {fail, "No disconnectfun action"}
+ end
+ after 2000 ->
+ {fail, "No connectfun action"}
+ end.
+
+%%--------------------------------------------------------------------
+connectfun_disconnectfun_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ Ref = make_ref(),
+ DiscFun = fun(R) -> Parent ! {disconnect,Ref,R} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {disconnectfun, DiscFun},
+ {user_interaction, false}]),
+ ssh:stop_daemon(Pid),
+ receive
+ {disconnect,Ref,R} ->
+ ct:log("Disconnect result: ~p",[R])
+ after 2000 ->
+ {fail, "No disconnectfun action"}
+ end.
+
+%%--------------------------------------------------------------------
+%%% validate client that uses the 'ssh_msg_debug_fun' option
+ssh_msg_debug_fun_option_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
+ ConnFun = fun(_,_,_) -> Parent ! {connection_pid,self()} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {connectfun, ConnFun},
+ {ssh_msg_debug_fun, DbgFun}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ receive
+ {connection_pid,Server} ->
+ %% Beware, implementation knowledge:
+ gen_fsm:send_all_state_event(Server,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
+ receive
+ {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
+ ct:log("Got expected dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid);
+ {msg_dbg,X} ->
+ ct:log("Got bad dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid),
+ {fail,"Bad msg received"}
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout2}
+ end
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout1}
+ end.
+
+%%--------------------------------------------------------------------
+disconnectfun_option_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ DisConnFun = fun(Reason) -> Parent ! {disconnect,Reason} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {disconnectfun, DisConnFun}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ ssh:close(ConnectionRef),
+ receive
+ {disconnect,Reason} ->
+ ct:log("Server detected disconnect: ~p",[Reason]),
+ ssh:stop_daemon(Pid),
+ ok
+ after 3000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
+ {fail,"Timeout waiting for disconnect"}
+ end.
+
+%%--------------------------------------------------------------------
+disconnectfun_option_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ DisConnFun = fun(Reason) -> Parent ! {disconnect,Reason} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {disconnectfun, DisConnFun}]),
+ ssh:stop_daemon(Pid),
+ receive
+ {disconnect,Reason} ->
+ ct:log("Client detected disconnect: ~p",[Reason]),
+ ok
+ after 3000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
+ {fail,"Timeout waiting for disconnect"}
+ end.
+
+%%--------------------------------------------------------------------
+unexpectedfun_option_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ ConnFun = fun(_,_,_) -> Parent ! {connection_pid,self()} end,
+ UnexpFun = fun(Msg,Peer) ->
+ Parent ! {unexpected,Msg,Peer,self()},
+ skip
+ end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {connectfun, ConnFun},
+ {unexpectedfun, UnexpFun}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ receive
+ {connection_pid,Server} ->
+ %% Beware, implementation knowledge:
+ Server ! unexpected_message,
+ receive
+ {unexpected, unexpected_message, {{_,_,_,_},_}, _} -> ok;
+ {unexpected, unexpected_message, Peer, _} -> ct:fail("Bad peer ~p",[Peer]);
+ M = {unexpected, _, _, _} -> ct:fail("Bad msg ~p",[M])
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout2}
+ end
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout1}
+ end.
+
+%%--------------------------------------------------------------------
+unexpectedfun_option_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ UnexpFun = fun(Msg,Peer) ->
+ Parent ! {unexpected,Msg,Peer,self()},
+ skip
+ end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {unexpectedfun, UnexpFun}]),
+ %% Beware, implementation knowledge:
+ ConnectionRef ! unexpected_message,
+
+ receive
+ {unexpected, unexpected_message, {{_,_,_,_},_}, ConnectionRef} ->
+ ok;
+ {unexpected, unexpected_message, Peer, ConnectionRef} ->
+ ct:fail("Bad peer ~p",[Peer]);
+ M = {unexpected, _, _, _} ->
+ ct:fail("Bad msg ~p",[M])
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test connect_timeout option in ssh:connect/4
+ssh_connect_timeout(_Config) ->
+ ConnTimeout = 2000,
+ {error,{faked_transport,connect,TimeoutToTransport}} =
+ ssh:connect("localhost", 12345,
+ [{transport,{tcp,?MODULE,tcp_closed}},
+ {connect_timeout,ConnTimeout}],
+ 1000),
+ case TimeoutToTransport of
+ ConnTimeout -> ok;
+ Other ->
+ ct:log("connect_timeout is ~p but transport received ~p",[ConnTimeout,Other]),
+ {fail,"ssh:connect/4 wrong connect_timeout received in transport"}
+ end.
+
+%% Plugin function for the test above
+connect(_Host, _Port, _Opts, Timeout) ->
+ {error, {faked_transport,connect,Timeout}}.
+
+%%--------------------------------------------------------------------
+%%% Test fourth argument in ssh:connect/4
+ssh_connect_arg4_timeout(_Config) ->
+ Timeout = 1000,
+ Parent = self(),
+ %% start the server
+ Server = spawn(fun() ->
+ {ok,Sl} = gen_tcp:listen(0,[]),
+ {ok,{_,Port}} = inet:sockname(Sl),
+ Parent ! {port,self(),Port},
+ Rsa = gen_tcp:accept(Sl),
+ ct:log("Server gen_tcp:accept got ~p",[Rsa]),
+ receive after 2*Timeout -> ok end %% let client timeout first
+ end),
+
+ %% Get listening port
+ Port = receive
+ {port,Server,ServerPort} -> ServerPort
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end,
+
+ %% try to connect with a timeout, but "supervise" it
+ Client = spawn(fun() ->
+ T0 = erlang:monotonic_time(),
+ Rc = ssh:connect("localhost",Port,[],Timeout),
+ ct:log("Client ssh:connect got ~p",[Rc]),
+ Parent ! {done,self(),Rc,T0}
+ end),
+
+ %% Wait for client reaction on the connection try:
+ receive
+ {done, Client, {error,timeout}, T0} ->
+ Msp = ms_passed(T0),
+ exit(Server,hasta_la_vista___baby),
+ Low = 0.9*Timeout,
+ High = 2.5*Timeout,
+ ct:log("Timeout limits: ~.4f - ~.4f ms, timeout "
+ "was ~.4f ms, expected ~p ms",[Low,High,Msp,Timeout]),
+ if
+ Low<Msp, Msp<High -> ok;
+ true -> {fail, "timeout not within limits"}
+ end;
+
+ {done, Client, {error,Other}, _T0} ->
+ ct:log("Error message \"~p\" from the client is unexpected.",[{error,Other}]),
+ {fail, "Unexpected error message"};
+
+ {done, Client, {ok,_Ref}, _T0} ->
+ {fail,"ssh-connected ???"}
+ after
+ 5000 ->
+ exit(Server,hasta_la_vista___baby),
+ exit(Client,hasta_la_vista___baby),
+ {fail, "Didn't timeout"}
+ end.
+
+%% Help function, elapsed milliseconds since T0
+ms_passed(T0) ->
+ %% OTP 18
+ erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native,
+ micro_seconds) / 1000.
+
+%%--------------------------------------------------------------------
+ssh_daemon_minimal_remote_max_packet_size_option(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+
+ {Server, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {minimal_remote_max_packet_size, 14}]),
+ Conn =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {user, "vego"},
+ {password, "morot"}]),
+
+ %% Try the limits of the minimal_remote_max_packet_size:
+ {ok, _ChannelId} = ssh_connection:session_channel(Conn, 100, 14, infinity),
+ {open_error,_,"Maximum packet size below 14 not supported",_} =
+ ssh_connection:session_channel(Conn, 100, 13, infinity),
+
+ ssh:close(Conn),
+ ssh:stop_daemon(Server).
+
+%%--------------------------------------------------------------------
+%% This test try every algorithm by connecting to an Erlang server
+id_string_no_opt_client(Config) ->
+ {Server, _Host, Port} = fake_daemon(Config),
+ {error,_} = ssh:connect("localhost", Port, [], 1000),
+ receive
+ {id,Server,"SSH-2.0-Erlang/"++Vsn} ->
+ true = expected_ssh_vsn(Vsn);
+ {id,Server,Other} ->
+ ct:fail("Unexpected id: ~s.",[Other])
+ after 5000 ->
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+id_string_own_string_client(Config) ->
+ {Server, _Host, Port} = fake_daemon(Config),
+ {error,_} = ssh:connect("localhost", Port, [{id_string,"Pelle"}], 1000),
+ receive
+ {id,Server,"SSH-2.0-Pelle\r\n"} ->
+ ok;
+ {id,Server,Other} ->
+ ct:fail("Unexpected id: ~s.",[Other])
+ after 5000 ->
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+id_string_random_client(Config) ->
+ {Server, _Host, Port} = fake_daemon(Config),
+ {error,_} = ssh:connect("localhost", Port, [{id_string,random}], 1000),
+ receive
+ {id,Server,Id="SSH-2.0-Erlang"++_} ->
+ ct:fail("Unexpected id: ~s.",[Id]);
+ {id,Server,Rnd="SSH-2.0-"++_} ->
+ ct:log("Got correct ~s",[Rnd]);
+ {id,Server,Id} ->
+ ct:fail("Unexpected id: ~s.",[Id])
+ after 5000 ->
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+id_string_no_opt_server(Config) ->
+ {_Server, Host, Port} = ssh_test_lib:std_daemon(Config, []),
+ {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,"SSH-2.0-Erlang/"++Vsn} = gen_tcp:recv(S1, 0, 2000),
+ true = expected_ssh_vsn(Vsn).
+
+%%--------------------------------------------------------------------
+id_string_own_string_server(Config) ->
+ {_Server, Host, Port} = ssh_test_lib:std_daemon(Config, [{id_string,"Olle"}]),
+ {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,"SSH-2.0-Olle\r\n"} = gen_tcp:recv(S1, 0, 2000).
+
+%%--------------------------------------------------------------------
+id_string_random_server(Config) ->
+ {_Server, Host, Port} = ssh_test_lib:std_daemon(Config, [{id_string,random}]),
+ {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,"SSH-2.0-"++Rnd} = gen_tcp:recv(S1, 0, 2000),
+ case Rnd of
+ "Erlang"++_ -> ct:log("Id=~p",[Rnd]),
+ {fail,got_default_id};
+ "Olle\r\n" -> {fail,got_previous_tests_value};
+ _ -> ct:log("Got ~s.",[Rnd])
+ end.
+
+%%--------------------------------------------------------------------
+ssh_connect_negtimeout_parallel(Config) -> ssh_connect_negtimeout(Config,true).
+ssh_connect_negtimeout_sequential(Config) -> ssh_connect_negtimeout(Config,false).
+
+ssh_connect_negtimeout(Config, Parallel) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NegTimeOut = 2000, % ms
+ ct:log("Parallel: ~p",[Parallel]),
+
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,Socket} = gen_tcp:connect(Host, Port, []),
+
+ Factor = 2,
+ ct:log("And now sleeping ~p*NegTimeOut (~p ms)...", [Factor, round(Factor * NegTimeOut)]),
+ ct:sleep(round(Factor * NegTimeOut)),
+
+ case inet:sockname(Socket) of
+ {ok,_} -> ct:fail("Socket not closed");
+ {error,_} -> ok
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test that ssh connection does not timeout if the connection is established (parallel)
+ssh_connect_nonegtimeout_connected_parallel(Config) ->
+ ssh_connect_nonegtimeout_connected(Config, true).
+
+%%% Test that ssh connection does not timeout if the connection is established (non-parallel)
+ssh_connect_nonegtimeout_connected_sequential(Config) ->
+ ssh_connect_nonegtimeout_connected(Config, false).
+
+
+ssh_connect_nonegtimeout_connected(Config, Parallel) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NegTimeOut = 20000, % ms
+ ct:log("Parallel: ~p",[Parallel]),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ct:log("~p Listen ~p:~p",[_Pid,_Host,Port]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ receive
+ Error = {'EXIT', _, _} ->
+ ct:log("~p",[Error]),
+ ct:fail(no_ssh_connection);
+ ErlShellStart ->
+ ct:log("---Erlang shell start: ~p~n", [ErlShellStart]),
+ one_shell_op(IO, NegTimeOut),
+ one_shell_op(IO, NegTimeOut),
+
+ Factor = 2,
+ ct:log("And now sleeping ~p*NegTimeOut (~p ms)...", [Factor, round(Factor * NegTimeOut)]),
+ ct:sleep(round(Factor * NegTimeOut)),
+
+ one_shell_op(IO, NegTimeOut)
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end,
+ exit(Shell, kill).
+
+
+one_shell_op(IO, TimeOut) ->
+ ct:log("One shell op: Waiting for prompter"),
+ receive
+ ErlPrompt0 -> ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
+ after TimeOut -> ct:fail("Timeout waiting for promter")
+ end,
+
+ IO ! {input, self(), "2*3*7.\r\n"},
+ receive
+ Echo0 -> ct:log("Echo: ~p ~n", [Echo0])
+ after TimeOut -> ct:fail("Timeout waiting for echo")
+ end,
+
+ receive
+ ?NEWLINE -> ct:log("NEWLINE received", [])
+ after TimeOut ->
+ receive Any1 -> ct:log("Bad NEWLINE: ~p",[Any1])
+ after 0 -> ct:fail("Timeout waiting for NEWLINE")
+ end
+ end,
+
+ receive
+ Result0 -> ct:log("Result: ~p~n", [Result0])
+ after TimeOut -> ct:fail("Timeout waiting for result")
+ end.
+
+%%--------------------------------------------------------------------
+max_sessions_ssh_connect_parallel(Config) ->
+ max_sessions(Config, true, connect_fun(ssh__connect,Config)).
+max_sessions_ssh_connect_sequential(Config) ->
+ max_sessions(Config, false, connect_fun(ssh__connect,Config)).
+
+max_sessions_sftp_start_channel_parallel(Config) ->
+ max_sessions(Config, true, connect_fun(ssh_sftp__start_channel, Config)).
+max_sessions_sftp_start_channel_sequential(Config) ->
+ max_sessions(Config, false, connect_fun(ssh_sftp__start_channel, Config)).
+
+
+%%%---- helpers:
+connect_fun(ssh__connect, Config) ->
+ fun(Host,Port) ->
+ ssh_test_lib:connect(Host, Port,
+ [{silently_accept_hosts, true},
+ {user_dir, ?config(priv_dir,Config)},
+ {user_interaction, false},
+ {user, "carni"},
+ {password, "meat"}
+ ])
+ %% ssh_test_lib returns R when ssh:connect returns {ok,R}
+ end;
+connect_fun(ssh_sftp__start_channel, _Config) ->
+ fun(Host,Port) ->
+ {ok,_Pid,ConnRef} =
+ ssh_sftp:start_channel(Host, Port,
+ [{silently_accept_hosts, true},
+ {user, "carni"},
+ {password, "meat"}
+ ]),
+ ConnRef
+ end.
+
+
+max_sessions(Config, ParallelLogin, Connect0) when is_function(Connect0,2) ->
+ Connect = fun(Host,Port) ->
+ R = Connect0(Host,Port),
+ ct:log("Connect(~p,~p) -> ~p",[Host,Port,R]),
+ R
+ end,
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ MaxSessions = 5,
+ {Pid, Host, Port} = ssh_test_lib:daemon([
+ {system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{"carni", "meat"}]},
+ {parallel_login, ParallelLogin},
+ {max_sessions, MaxSessions}
+ ]),
+ ct:log("~p Listen ~p:~p for max ~p sessions",[Pid,Host,Port,MaxSessions]),
+ try [Connect(Host,Port) || _ <- lists:seq(1,MaxSessions)]
+ of
+ Connections ->
+ %% Step 1 ok: could set up max_sessions connections
+ ct:log("Connections up: ~p",[Connections]),
+ [_|_] = Connections,
+
+ %% Now try one more than alowed:
+ ct:log("Info Report might come here...",[]),
+ try Connect(Host,Port)
+ of
+ _ConnectionRef1 ->
+ ssh:stop_daemon(Pid),
+ {fail,"Too many connections accepted"}
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ %% Step 2 ok: could not set up max_sessions+1 connections
+ %% This is expected
+ %% Now stop one connection and try to open one more
+ ok = ssh:close(hd(Connections)),
+ receive after 250 -> ok end, % sleep so the supervisor has time to count down. Not nice...
+ try Connect(Host,Port)
+ of
+ _ConnectionRef1 ->
+ %% Step 3 ok: could set up one more connection after killing one
+ %% Thats good.
+ ssh:stop_daemon(Pid),
+ ok
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ %% Bad indeed. Could not set up one more connection even after killing
+ %% one existing. Very bad.
+ ssh:stop_daemon(Pid),
+ {fail,"Does not decrease # active sessions"}
+ end
+ end
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ ssh:stop_daemon(Pid),
+ {fail,"Too few connections accepted"}
+ end.
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+expected_ssh_vsn(Str) ->
+ try
+ {ok,L} = application:get_all_key(ssh),
+ proplists:get_value(vsn,L,"")++"\r\n"
+ of
+ Str -> true;
+ "\r\n" -> true;
+ _ -> false
+ catch
+ _:_ -> true %% ssh not started so we dont't know
+ end.
+
+
+fake_daemon(_Config) ->
+ Parent = self(),
+ %% start the server
+ Server = spawn(fun() ->
+ {ok,Sl} = gen_tcp:listen(0,[{packet,line}]),
+ {ok,{Host,Port}} = inet:sockname(Sl),
+ ct:log("fake_daemon listening on ~p:~p~n",[Host,Port]),
+ Parent ! {sockname,self(),Host,Port},
+ Rsa = gen_tcp:accept(Sl),
+ ct:log("Server gen_tcp:accept got ~p",[Rsa]),
+ {ok,S} = Rsa,
+ receive
+ {tcp, S, Id} -> Parent ! {id,self(),Id}
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end
+ end),
+ %% Get listening host and port
+ receive
+ {sockname,Server,ServerHost,ServerPort} -> {Server, ServerHost, ServerPort}
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_dsa b/lib/ssh/test/ssh_options_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_rsa b/lib/ssh/test/ssh_options_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_peername_sockname_server.erl b/lib/ssh/test/ssh_peername_sockname_server.erl
index bc505695d3..88c96fe444 100644
--- a/lib/ssh/test/ssh_peername_sockname_server.erl
+++ b/lib/ssh/test/ssh_peername_sockname_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/test/ssh_property_test_SUITE.erl b/lib/ssh/test/ssh_property_test_SUITE.erl
index ffad8ebbb7..2278719f6a 100644
--- a/lib/ssh/test/ssh_property_test_SUITE.erl
+++ b/lib/ssh/test/ssh_property_test_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
new file mode 100644
index 0000000000..44da0f4d6f
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -0,0 +1,705 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_protocol_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/inet.hrl").
+-include_lib("ssh/src/ssh.hrl"). % ?UINT32, ?BYTE, #ssh{} ...
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_auth.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(NEWLINE, <<"\r\n">>).
+-define(REKEY_DATA_TMO, 65000).
+
+-define(v(Key, Config), proplists:get_value(Key, Config)).
+-define(v(Key, Config, Default), proplists:get_value(Key, Config, Default)).
+
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,2}}].
+
+all() ->
+ [{group,tool_tests},
+ {group,kex},
+ {group,service_requests},
+ {group,authentication},
+ {group,packet_size_error},
+ {group,field_size_error}
+ ].
+
+groups() ->
+ [{tool_tests, [], [lib_works_as_client,
+ lib_works_as_server,
+ lib_match,
+ lib_no_match
+ ]},
+ {packet_size_error, [], [packet_length_too_large,
+ packet_length_too_short]},
+
+ {field_size_error, [], [service_name_length_too_large,
+ service_name_length_too_short]},
+
+ {kex, [], [no_common_alg_server_disconnects,
+ no_common_alg_client_disconnects,
+ gex_client_init_option_groups,
+ gex_server_gex_limit,
+ gex_client_init_option_groups_moduli_file,
+ gex_client_init_option_groups_file,
+ gex_client_old_request_exact,
+ gex_client_old_request_noexact
+ ]},
+ {service_requests, [], [bad_service_name,
+ bad_long_service_name,
+ bad_very_long_service_name,
+ empty_service_name,
+ bad_service_name_then_correct
+ ]},
+ {authentication, [], [client_handles_keyboard_interactive_0_pwds
+ ]}
+ ].
+
+
+init_per_suite(Config) ->
+ start_std_daemon( setup_dirs( start_apps(Config))).
+
+end_per_suite(Config) ->
+ stop_apps(Config).
+
+
+
+init_per_testcase(no_common_alg_server_disconnects, Config) ->
+ start_std_daemon(Config, [{preferred_algorithms,[{public_key,['ssh-rsa']}]}]);
+
+init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
+ TC == gex_client_init_option_groups_moduli_file ;
+ TC == gex_client_init_option_groups_file ;
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ Opts = case TC of
+ gex_client_init_option_groups ->
+ [{dh_gex_groups, [{2345, 3, 41}]}];
+ gex_client_init_option_groups_file ->
+ DataDir = ?config(data_dir, Config),
+ F = filename:join(DataDir, "dh_group_test"),
+ [{dh_gex_groups, {file,F}}];
+ gex_client_init_option_groups_moduli_file ->
+ DataDir = ?config(data_dir, Config),
+ F = filename:join(DataDir, "dh_group_test.moduli"),
+ [{dh_gex_groups, {ssh_moduli_file,F}}];
+ _ when TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ [{dh_gex_groups, [{ 500, 3, 17},
+ {1000, 7, 91},
+ {3000, 5, 61}]},
+ {dh_gex_limits,{500,1500}}
+ ];
+ _ ->
+ []
+ end,
+ start_std_daemon(Config,
+ [{preferred_algorithms, ssh:default_algorithms()}
+ | Opts]);
+init_per_testcase(_TestCase, Config) ->
+ check_std_daemon_works(Config, ?LINE).
+
+end_per_testcase(no_common_alg_server_disconnects, Config) ->
+ stop_std_daemon(Config);
+end_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
+ TC == gex_client_init_option_groups_moduli_file ;
+ TC == gex_client_init_option_groups_file ;
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ stop_std_daemon(Config);
+end_per_testcase(_TestCase, Config) ->
+ check_std_daemon_works(Config, ?LINE).
+
+%%%--------------------------------------------------------------------
+%%% Test Cases --------------------------------------------------------
+%%%--------------------------------------------------------------------
+
+%%%--------------------------------------------------------------------
+%%% Connect to an erlang server and check that the testlib acts as a client.
+lib_works_as_client(Config) ->
+ %% Connect and negotiate keys
+ {ok,InitialState} = ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]}]
+ ),
+ {ok,AfterKexState} = connect_and_kex(Config, InitialState),
+
+ %% Do the authentcation
+ {User,Pwd} = server_user_password(Config),
+ {ok,EndState} =
+ ssh_trpt_test_lib:exec(
+ [{send, #ssh_msg_service_request{name = "ssh-userauth"}},
+ {match, #ssh_msg_service_accept{name = "ssh-userauth"}, receive_msg},
+ {send, #ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "password",
+ data = <<?BOOLEAN(?FALSE),
+ ?STRING(unicode:characters_to_binary(Pwd))>>
+ }},
+ {match, #ssh_msg_userauth_success{_='_'}, receive_msg}
+ ], AfterKexState),
+
+ %% Disconnect
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{send, #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "End of the fun",
+ language = ""
+ }},
+ close_socket
+ ], EndState).
+
+
+%%--------------------------------------------------------------------
+%%% Connect an erlang client and check that the testlib can act as a server.
+lib_works_as_server(Config) ->
+ {User,_Pwd} = server_user_password(Config),
+
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+
+ %% Start a process handling one connection on the server side:
+ spawn_link(
+ fun() ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_messages]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)}]},
+ receive_hello,
+ {send, hello},
+
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+
+ {match, #ssh_msg_kexdh_init{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_reply},
+
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg},
+
+ {match, #ssh_msg_service_request{name="ssh-userauth"}, receive_msg},
+ {send, #ssh_msg_service_accept{name="ssh-userauth"}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="none",
+ user=User,
+ _='_'}, receive_msg},
+
+ {send, #ssh_msg_userauth_failure{authentications = "password",
+ partial_success = false}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="password",
+ user=User,
+ _='_'}, receive_msg},
+ {send, #ssh_msg_userauth_success{}},
+ close_socket,
+ print_state
+ ],
+ InitialState)
+ end),
+
+ %% and finally connect to it with a regular Erlang SSH client:
+ {ok,_} = std_connect(HostPort, Config,
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]}]
+ ).
+
+%%--------------------------------------------------------------------
+%%% Matching
+lib_match(_Config) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec([{set_options, [print_ops]},
+ {match, abc, abc},
+ {match, '$a', {cde,fgh}},
+ {match, {cde,fgh}, '$a'},
+ {match, '_', {cde,fgh}},
+ {match, [a,'$a',b], [a,{cde,fgh},b]},
+ {match, [a,'$a'|'$b'], [a,{cde,fgh},b,c]},
+ {match, '$b', [b,c]}
+ ]).
+
+%%--------------------------------------------------------------------
+%%% Not matching
+lib_no_match(_Config) ->
+ case ssh_trpt_test_lib:exec([{set_options, [print_ops]},
+ {match, '$x', b},
+ {match, a, '$x'}])
+ of
+ {ok,_} -> {fail,"Unexpected match"};
+ {error, {_Op,{expected,a,b},_State}} -> ok
+ end.
+
+%%--------------------------------------------------------------------
+%%% Algo negotiation fail. This should result in a ssh_msg_disconnect
+%%% being sent from the server.
+no_common_alg_server_disconnects(Config) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, {print_messages,detail}]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{public_key,['ssh-dss']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, ssh_msg_kexinit}, % with server unsupported 'ssh-dss' !
+ {match, disconnect(), receive_msg}
+ ]
+ ).
+
+%%--------------------------------------------------------------------
+%%% Algo negotiation fail. This should result in a ssh_msg_disconnect
+%%% being sent from the client.
+no_common_alg_client_disconnects(Config) ->
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+ Parent = self(),
+
+ %% Start a process handling one connection on the server side:
+ Pid =
+ spawn_link(
+ fun() ->
+ Parent !
+ {result,self(),
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, {print_messages,detail}]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)}]},
+ receive_hello,
+ {send, hello},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kexinit{ % with unsupported "SOME-UNSUPPORTED"
+ cookie = 247381486335508958743193106082599558706,
+ kex_algorithms = ["diffie-hellman-group1-sha1"],
+ server_host_key_algorithms = ["SOME-UNSUPPORTED"], % SIC!
+ encryption_algorithms_client_to_server = ["aes128-ctr"],
+ encryption_algorithms_server_to_client = ["aes128-ctr"],
+ mac_algorithms_client_to_server = ["hmac-sha2-256"],
+ mac_algorithms_server_to_client = ["hmac-sha2-256"],
+ compression_algorithms_client_to_server = ["none"],
+ compression_algorithms_server_to_client = ["none"],
+ languages_client_to_server = [],
+ languages_server_to_client = [],
+ first_kex_packet_follows = false,
+ reserved = 0
+ }},
+ {match, disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED), receive_msg}
+ ],
+ InitialState)
+ }
+ end),
+
+ %% and finally connect to it with a regular Erlang SSH client
+ %% which of course does not support SOME-UNSUPPORTED as pub key algo:
+ Result = std_connect(HostPort, Config, [{preferred_algorithms,[{public_key,['ssh-dss']}]}]),
+ ct:log("Result of connect is ~p",[Result]),
+
+ receive
+ {result,Pid,{ok,_}} ->
+ ok;
+ {result,Pid,{error,{Op,ExecResult,S}}} ->
+ ct:log("ERROR!~nOp = ~p~nExecResult = ~p~nState =~n~s",
+ [Op,ExecResult,ssh_trpt_test_lib:format_msg(S)]),
+ {fail, ExecResult};
+ X ->
+ ct:log("¤¤¤¤¤"),
+ ct:fail(X)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+%%%--------------------------------------------------------------------
+gex_client_init_option_groups(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {3,41}).
+
+gex_client_init_option_groups_file(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {5,61}).
+
+gex_client_init_option_groups_moduli_file(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {5,16#B7}).
+
+gex_server_gex_limit(Config) ->
+ do_gex_client_init(Config, {1000, 3000, 4000},
+ {7,91}).
+
+
+do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kex_dh_gex_request{min = Min,
+ n = N,
+ max = Max}},
+ {match, #ssh_msg_kex_dh_gex_group{p=P, g=G, _='_'}, receive_msg}
+ ]
+ ).
+
+%%%--------------------------------------------------------------------
+gex_client_old_request_exact(Config) -> do_gex_client_init_old(Config, 500, {3,17}).
+gex_client_old_request_noexact(Config) -> do_gex_client_init_old(Config, 800, {7,91}).
+
+do_gex_client_init_old(Config, N, {G,P}) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kex_dh_gex_request_old{n = N}},
+ {match, #ssh_msg_kex_dh_gex_group{p=P, g=G, _='_'}, receive_msg}
+ ]
+ ).
+
+%%%--------------------------------------------------------------------
+bad_service_name(Config) ->
+ bad_service_name(Config, "kfglkjf").
+
+bad_long_service_name(Config) ->
+ bad_service_name(Config,
+ lists:duplicate(?SSH_MAX_PACKET_SIZE div 2, $a)).
+
+bad_very_long_service_name(Config) ->
+ bad_service_name(Config,
+ lists:duplicate(4*?SSH_MAX_PACKET_SIZE, $a)).
+
+empty_service_name(Config) ->
+ bad_service_name(Config, "").
+
+bad_service_name_then_correct(Config) ->
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, #ssh_msg_service_request{name = "kdjglkfdjgkldfjglkdfjglkfdjglkj"}},
+ {send, #ssh_msg_service_request{name = "ssh-connection"}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+
+bad_service_name(Config, Name) ->
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, #ssh_msg_service_request{name = Name}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+packet_length_too_large(Config) -> bad_packet_length(Config, +4).
+
+packet_length_too_short(Config) -> bad_packet_length(Config, -4).
+
+bad_packet_length(Config, LengthExcess) ->
+ PacketFun =
+ fun(Msg, Ssh) ->
+ BinMsg = ssh_message:encode(Msg),
+ ssh_transport:pack(BinMsg, Ssh, LengthExcess)
+ end,
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, {special,
+ #ssh_msg_service_request{name="ssh-userauth"},
+ PacketFun}},
+ %% Prohibit remote decoder starvation:
+ {send, #ssh_msg_service_request{name="ssh-userauth"}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+service_name_length_too_large(Config) -> bad_service_name_length(Config, +4).
+
+service_name_length_too_short(Config) -> bad_service_name_length(Config, -4).
+
+
+bad_service_name_length(Config, LengthExcess) ->
+ PacketFun =
+ fun(#ssh_msg_service_request{name=Service}, Ssh) ->
+ BinName = list_to_binary(Service),
+ BinMsg =
+ <<?BYTE(?SSH_MSG_SERVICE_REQUEST),
+ %% A bad string encoding of Service:
+ ?UINT32(size(BinName)+LengthExcess), BinName/binary
+ >>,
+ ssh_transport:pack(BinMsg, Ssh)
+ end,
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, {special,
+ #ssh_msg_service_request{name="ssh-userauth"},
+ PacketFun} },
+ %% Prohibit remote decoder starvation:
+ {send, #ssh_msg_service_request{name="ssh-userauth"}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+%%% This is due to a fault report (OTP-13255) with OpenSSH-6.6.1
+client_handles_keyboard_interactive_0_pwds(Config) ->
+ {User,_Pwd} = server_user_password(Config),
+
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+
+ %% Start a process handling one connection on the server side:
+ spawn_link(
+ fun() ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_messages]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)}]},
+ receive_hello,
+ {send, hello},
+
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+
+ {match, #ssh_msg_kexdh_init{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_reply},
+
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg},
+
+ {match, #ssh_msg_service_request{name="ssh-userauth"}, receive_msg},
+ {send, #ssh_msg_service_accept{name="ssh-userauth"}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="none",
+ user=User,
+ _='_'}, receive_msg},
+ {send, #ssh_msg_userauth_failure{authentications = "keyboard-interactive",
+ partial_success = false}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="keyboard-interactive",
+ user=User,
+ _='_'}, receive_msg},
+ {send, #ssh_msg_userauth_info_request{name = "",
+ instruction = "",
+ language_tag = "",
+ num_prompts = 1,
+ data = <<0,0,0,10,80,97,115,115,119,111,114,100,58,32,0>>
+ }},
+ {match, #ssh_msg_userauth_info_response{num_responses = 1,
+ _='_'}, receive_msg},
+
+ %% the next is strange, but openssh 6.6.1 does this and this is what this testcase is about
+ {send, #ssh_msg_userauth_info_request{name = "",
+ instruction = "",
+ language_tag = "",
+ num_prompts = 0,
+ data = <<>>
+ }},
+ {match, #ssh_msg_userauth_info_response{num_responses = 0,
+ data = <<>>,
+ _='_'}, receive_msg},
+ %% Here we know that the tested fault is fixed
+ {send, #ssh_msg_userauth_success{}},
+ close_socket,
+ print_state
+ ],
+ InitialState)
+ end),
+
+ %% and finally connect to it with a regular Erlang SSH client:
+ {ok,_} = std_connect(HostPort, Config,
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]}]
+ ).
+
+
+%%%================================================================
+%%%==== Internal functions ========================================
+%%%================================================================
+
+%%%---- init_suite and end_suite ---------------------------------------
+start_apps(Config) ->
+ catch ssh:stop(),
+ ok = ssh:start(),
+ Config.
+
+stop_apps(_Config) ->
+ ssh:stop().
+
+
+setup_dirs(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ Config.
+
+system_dir(Config) -> filename:join(?config(priv_dir, Config), system).
+
+user_dir(Config) -> ?config(priv_dir, Config).
+
+%%%----------------------------------------------------------------
+start_std_daemon(Config) ->
+ start_std_daemon(Config, []).
+
+start_std_daemon(Config, ExtraOpts) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ UserPasswords = [{"user1","pwd1"}],
+ Options = [%%{preferred_algorithms,[{public_key,['ssh-rsa']}]}, %% For some test cases
+ {system_dir, system_dir(Config)},
+ {user_dir, UserDir},
+ {user_passwords, UserPasswords},
+ {failfun, fun ssh_test_lib:failfun/2}
+ | ExtraOpts],
+ Ref = {Server, Host, Port} = ssh_test_lib:daemon(Options),
+ ct:log("Std server ~p started at ~p:~p~nOptions=~p",[Server, Host, Port, Options]),
+ [{server,Ref}, {user_passwords, UserPasswords} | Config].
+
+
+stop_std_daemon(Config) ->
+ ssh:stop_daemon(server_pid(Config)),
+ ct:log("Std server ~p at ~p:~p stopped", [server_pid(Config), server_host(Config), server_port(Config)]),
+ lists:keydelete(server, 1, Config).
+
+
+check_std_daemon_works(Config, Line) ->
+ case std_connect(Config) of
+ {ok,C} ->
+ ct:log("Server ~p:~p ~p is ok at line ~p",
+ [server_host(Config), server_port(Config),
+ server_pid(Config), Line]),
+ ok = ssh:close(C),
+ Config;
+ Error = {error,_} ->
+ ct:fail("Standard server ~p:~p ~p is ill at line ~p: ~p",
+ [server_host(Config), server_port(Config),
+ server_pid(Config), Line, Error])
+ end.
+
+server_pid(Config) -> element(1,?v(server,Config)).
+server_host(Config) -> element(2,?v(server,Config)).
+server_port(Config) -> element(3,?v(server,Config)).
+
+server_user_password(Config) -> server_user_password(1, Config).
+
+server_user_password(N, Config) -> lists:nth(N, ?v(user_passwords,Config)).
+
+
+std_connect(Config) ->
+ std_connect({server_host(Config), server_port(Config)}, Config).
+
+std_connect({Host,Port}, Config) ->
+ std_connect({Host,Port}, Config, []).
+
+std_connect({Host,Port}, Config, Opts) ->
+ std_connect(Host, Port, Config, Opts).
+
+std_connect(Host, Port, Config, Opts) ->
+ {User,Pwd} = server_user_password(Config),
+ ssh:connect(Host, Port,
+ %% Prefere User's Opts to the default opts
+ [O || O = {Tag,_} <- [{user,User},{password,Pwd},
+ {silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false}],
+ not lists:keymember(Tag, 1, Opts)
+ ] ++ Opts,
+ 30000).
+
+%%%----------------------------------------------------------------
+connect_and_kex(Config) ->
+ connect_and_kex(Config, ssh_trpt_test_lib:exec([]) ).
+
+connect_and_kex(Config, InitialState) ->
+ ssh_trpt_test_lib:exec(
+ [{connect,
+ server_host(Config),server_port(Config),
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]},
+ {silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false}]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_init},
+ {match,# ssh_msg_kexdh_reply{_='_'}, receive_msg},
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg}
+ ],
+ InitialState).
+
+%%%----------------------------------------------------------------
+
+%%% For matching peer disconnection
+disconnect() ->
+ disconnect('_').
+
+disconnect(Code) ->
+ {'or',[#ssh_msg_disconnect{code = Code,
+ _='_'},
+ tcp_closed,
+ {tcp_error,econnaborted}
+ ]}.
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
new file mode 100644
index 0000000000..2887bb4b60
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
@@ -0,0 +1,3 @@
+{2222, 5, 61}.
+{1111, 7, 91}.
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
new file mode 100644
index 0000000000..f6995ba4c9
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
@@ -0,0 +1,3 @@
+20151021104105 2 6 100 2222 5 B7
+20151021104106 2 6 100 1111 5 4F
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_relay.erl b/lib/ssh/test/ssh_relay.erl
new file mode 100644
index 0000000000..28000fbb97
--- /dev/null
+++ b/lib/ssh/test/ssh_relay.erl
@@ -0,0 +1,407 @@
+%%%-------------------------------------------------------------------
+%%% @author Simon Cornish <[email protected]>
+%%% @copyright (C) 2015, Simon Cornish
+%%% @doc
+%%% Provide manipulatable TCP-level relaying for testing SSH
+%%% @end
+%%% Created : 7 May 2015 by Simon Cornish <[email protected]>
+%%%-------------------------------------------------------------------
+-module(ssh_relay).
+
+-behaviour(gen_server).
+
+%% API
+-export([start_link/4]).
+-export([stop/1]).
+-export([hold/4, release/2, release_next/3]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-record(hold, {
+ port,
+ n,
+ tmo,
+ tref,
+ q = []
+ }).
+
+-record(state, {
+ local_addr,
+ local_port,
+ peer_addr,
+ peer_port,
+ lpid,
+ local,
+ peer,
+ tx_hold,
+ rx_hold
+ }).
+
+-define(ACCEPT_TMO, 200).
+%%%===================================================================
+%%% API
+%%%===================================================================
+%%--------------------------------------------------------------------
+%% @doc
+%% Hold N (or 'all') messages in given direction.
+%% Messages will be released after the N+1th message or
+%% Tmo ms or 'infinity'
+%%
+%% Dir is 'tx' for direction local -> peer
+%% and 'rx' for direction peer -> local
+%%
+%% An Error, ealready, is returned if there is already a hold
+%% in the given direction
+%%
+%% @spec hold(Srv, Dir, N, Tmo) -> ok | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+hold(Srv, Dir, N, Tmo) ->
+ gen_server:call(Srv, {hold, Dir, N, Tmo}).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Release all held messages in given direction.
+%%
+%% An Error, enoent, is returned if there is no hold
+%% in the given direction
+%%
+%% @spec release(Srv, Dir) -> ok | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+release(Srv, Dir) ->
+ gen_server:call(Srv, {release, Dir}).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Release all held messages in given direction after the
+%% next message in the trigger direction
+%%
+%% An Error, enoent, is returned if there is no hold
+%% in the given direction
+%%
+%% @spec release_next(Srv, Dir, TriggerDir) -> ok | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+release_next(Srv, Dir, TriggerDir) ->
+ gen_server:call(Srv, {release_next, Dir, TriggerDir}).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Starts the server
+%%
+%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+start_link(ListenAddr, ListenPort, PeerAddr, PeerPort) ->
+ gen_server:start_link(?MODULE, [ListenAddr, ListenPort, PeerAddr, PeerPort], []).
+
+stop(Srv) ->
+ unlink(Srv),
+ Srv ! stop.
+
+%%%===================================================================
+%%% gen_server callbacks
+%%%===================================================================
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Initializes the server
+%%
+%% @spec init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% @end
+%%--------------------------------------------------------------------
+init([ListenAddr, ListenPort, PeerAddr, PeerPort | _Options]) ->
+ IfAddr = case ListenAddr of
+ {0,0,0,0} ->
+ [];
+ _ ->
+ [{ifaddr, ListenAddr}]
+ end,
+ case gen_tcp:listen(ListenPort, [{reuseaddr, true}, {backlog, 1}, {active, false}, binary | IfAddr]) of
+ {ok, LSock} ->
+ Parent = self(),
+ {LPid, _LMod} = spawn_monitor(fun() -> listen(Parent, LSock) end),
+ S = #state{local_addr = ListenAddr,
+ local_port = ListenPort,
+ lpid = LPid,
+ peer_addr = PeerAddr,
+ peer_port = PeerPort
+ },
+ {ok, S};
+ Error ->
+ {stop, Error}
+ end.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Handling call messages
+%%
+%% @spec handle_call(Request, From, State) ->
+%% {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} |
+%% {stop, Reason, State}
+%% @end
+%%--------------------------------------------------------------------
+handle_call({hold, Dir, N, Tmo}, _From, State) ->
+ case Dir of
+ tx ->
+ do_hold(#state.tx_hold, State#state.peer, N, Tmo, State);
+ rx ->
+ do_hold(#state.rx_hold, State#state.local, N, Tmo, State);
+ _ ->
+ {reply, {error, einval}, State}
+ end;
+handle_call({release, Dir}, _From, State) ->
+ case Dir of
+ tx ->
+ do_release(#state.tx_hold, State);
+ rx ->
+ do_release(#state.rx_hold, State);
+ _ ->
+ {reply, {error, einval}, State}
+ end;
+handle_call({release_next, _Dir, _TriggerDir}, _From, State) ->
+ {reply, {error, nyi}, State};
+
+handle_call(Request, _From, State) ->
+ Reply = {unhandled, Request},
+ {reply, Reply, State}.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Handling cast messages
+%%
+%% @spec handle_cast(Msg, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%% @end
+%%--------------------------------------------------------------------
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Handling all non call/cast messages
+%%
+%% @spec handle_info(Info, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%% @end
+%%--------------------------------------------------------------------
+handle_info({tcp, Local, Data}, S) when S#state.local == Local ->
+ S1 = do_local(Data, S),
+ {noreply, S1};
+
+handle_info({tcp_error, Local, Error}, S) when S#state.local == Local ->
+ S1 = do_local({error, Error}, S),
+ {noreply, S1};
+
+handle_info({tcp_closed, Local}, S) when S#state.local == Local ->
+ S1 = do_local(closed, S),
+ {noreply, S1};
+
+handle_info({tcp, Peer, Data}, S) when S#state.peer == Peer ->
+ S1 = do_peer(Data, S),
+ {noreply, S1};
+
+handle_info({tcp_error, Peer, Error}, S) when S#state.peer == Peer ->
+ S1 = do_peer({error, Error}, S),
+ {noreply, S1};
+
+handle_info({tcp_closed, Peer}, S) when S#state.peer == Peer ->
+ S1 = do_peer(closed, S),
+ {noreply, S1};
+
+handle_info({accept, Local}, S) ->
+ S1 = do_accept(Local, S),
+ {noreply, S1};
+
+handle_info({activate, Local}, State) ->
+ inet:setopts(Local, [{active, true}]),
+ {noreply, State};
+
+handle_info({release, Pos}, S) ->
+ {reply, _, S1} = do_release(Pos,S),
+ {noreply, S1};
+
+handle_info(stop, State) ->
+ {stop, normal, State};
+
+handle_info({'DOWN', _Ref, _process, LPid, Reason}, S) when S#state.lpid == LPid ->
+ io:format("Acceptor has finished: ~p~n", [Reason]),
+ {noreply, S};
+
+handle_info(_Info, State) ->
+ io:format("Unhandled info: ~p~n", [_Info]),
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% This function is called by a gen_server when it is about to
+%% terminate. It should be the opposite of Module:init/1 and do any
+%% necessary cleaning up. When it returns, the gen_server terminates
+%% with Reason. The return value is ignored.
+%%
+%% @spec terminate(Reason, State) -> void()
+%% @end
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Convert process state when code is changed
+%%
+%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
+%% @end
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+do_hold(Pos, _Port, _N, _Tmo, S) when element(Pos, S) /= undefined ->
+ {reply, {error, ealready}, S};
+do_hold(Pos, Port, N, Tmo, S) ->
+ TRef = if is_integer(Tmo) andalso Tmo > 0 ->
+ erlang:send_after(Tmo, self(), {release, Pos});
+ true ->
+ undefined
+ end,
+ Hold = #hold{port = Port, n = N, tmo = Tmo, tref = TRef},
+ {reply, ok, setelement(Pos, S, Hold)}.
+
+do_release(HPos, S) when element(HPos, S) == undefined ->
+ {reply, {error, enoent}, S};
+do_release(HPos, S) ->
+ #hold{port = Port, tref = TRef, q = Q} = element(HPos, S),
+ lists:foreach(fun(M) -> gen_tcp:send(Port, M), erlang:yield() end, Q),
+ catch erlang:cancel_timer(TRef),
+ receive
+ {release, HPos} -> ok
+ after 0 ->
+ ok
+ end,
+ {reply, ok, setelement(HPos, S, undefined)}.
+
+listen(Parent, LSock) ->
+ monitor(process, Parent),
+ do_listen(Parent, LSock).
+
+do_listen(Parent, LSock) ->
+ %% So annoying there is no select-like sematic for this
+ case gen_tcp:accept(LSock, ?ACCEPT_TMO) of
+ {ok, Sock} ->
+ Parent ! {accept, Sock},
+ gen_tcp:controlling_process(Sock, Parent),
+ Parent ! {activate, Sock},
+ do_flush(Parent, Sock),
+ gen_tcp:close(LSock);
+ {error, timeout} ->
+ receive
+ DOWN when element(1, DOWN) == 'DOWN' ->
+ ok;
+ stop ->
+ ok
+ after 1 ->
+ do_listen(Parent, LSock)
+ end;
+ Error ->
+ gen_tcp:close(LSock),
+ exit({accept,Error})
+ end.
+
+do_flush(Parent, Sock) ->
+ receive
+ {Tcp, Sock, _} = Msg when Tcp == tcp; Tcp == tcp_error ->
+ Parent ! Msg,
+ do_flush(Parent, Sock);
+ {tcp_closed, Sock} = Msg ->
+ Parent ! Msg,
+ do_flush(Parent, Sock)
+ after 1 ->
+ ok
+ end.
+
+do_accept(Local, S) ->
+ case gen_tcp:connect(S#state.peer_addr, S#state.peer_port, [{active, true}, binary]) of
+ {ok, Peer} ->
+ S#state{local = Local, peer = Peer};
+ Error ->
+ exit({connect, Error})
+ end.
+
+do_local(Data, S) when is_binary(Data) ->
+ TxH = S#state.tx_hold,
+ if TxH == undefined ->
+ gen_tcp:send(S#state.peer, Data),
+ S;
+ TxH#hold.n == 0 ->
+ lists:foreach(fun(M) -> gen_tcp:send(S#state.peer, M) end, TxH#hold.q),
+ gen_tcp:send(S#state.peer, Data),
+ catch erlang:cancel_timer(TxH#hold.tref),
+ TxP = #state.tx_hold,
+ receive
+ {release, TxP} ->
+ ok
+ after 0 ->
+ ok
+ end,
+ S#state{tx_hold = undefined};
+ true ->
+ Q = TxH#hold.q ++ [Data],
+ N = if is_integer(TxH#hold.n) ->
+ TxH#hold.n -1;
+ true ->
+ TxH#hold.n
+ end,
+ S#state{tx_hold = TxH#hold{q = Q, n = N}}
+ end;
+do_local(Error, _S) ->
+ exit({local, Error}).
+
+do_peer(Data, S) when is_binary(Data) ->
+ RxH = S#state.rx_hold,
+ if RxH == undefined ->
+ gen_tcp:send(S#state.local, Data),
+ S;
+ RxH#hold.n == 0 ->
+ lists:foreach(fun(M) -> gen_tcp:send(S#state.local, M) end, RxH#hold.q),
+ gen_tcp:send(S#state.local, Data),
+ catch erlang:cancel_timer(RxH#hold.tref),
+ RxP = #state.rx_hold,
+ receive
+ {release, RxP} ->
+ ok
+ after 0 ->
+ ok
+ end,
+ S#state{rx_hold = undefined};
+ true ->
+ Q = RxH#hold.q ++ [Data],
+ N = if is_integer(RxH#hold.n) ->
+ RxH#hold.n -1;
+ true ->
+ RxH#hold.n
+ end,
+ S#state{rx_hold = RxH#hold{q = Q, n = N}}
+ end;
+do_peer(Error, _S) ->
+ exit({peer, Error}).
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
new file mode 100644
index 0000000000..6d2c97aa68
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -0,0 +1,250 @@
+%%
+%% %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.
+%% 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(ssh_renegotiate_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(REKEY_DATA_TMO, 65000).
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() -> [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,12}}].
+
+
+all() -> [{group,default_algs},
+ {group,aes_gcm}
+ ].
+
+groups() -> [{default_algs, [], tests()},
+ {aes_gcm, [], tests()}
+ ].
+
+tests() -> [rekey, rekey_limit, renegotiate1, renegotiate2].
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ssh:stop().
+
+%%--------------------------------------------------------------------
+init_per_group(aes_gcm, Config) ->
+ case lists:member({client2server,['[email protected]']},
+ ssh_transport:supported_algorithms(cipher)) of
+ true ->
+ [{preferred_algorithms, [{cipher,[{client2server,['[email protected]']},
+ {server2client,['[email protected]']}]}]}
+ | Config];
+ false ->
+ {skip, "aes_gcm not supported"}
+ end;
+init_per_group(_, Config) ->
+ [{preferred_algorithms, ssh:default_algorithms()} | Config].
+
+
+end_per_group(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ ssh:start(),
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ssh:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+%%% Idle timeout test
+
+rekey(Config) ->
+ {Pid, Host, Port} =
+ ssh_test_lib:std_daemon(Config,
+ [{rekey_limit, 0}]),
+ ConnectionRef =
+ ssh_test_lib:std_connect(Config, Host, Port,
+ [{rekey_limit, 0}]),
+ Kex1 = get_kex_init(ConnectionRef),
+ receive
+ after ?REKEY_DATA_TMO ->
+ %%By this time rekeying would have been done
+ Kex2 = get_kex_init(ConnectionRef),
+ false = (Kex2 == Kex1),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
+ end.
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying by data volume
+
+rekey_limit(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "rekey.data"),
+
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, 6000},
+ {max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = get_kex_init(ConnectionRef),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex1 = 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),
+
+ false = (Kex2 == Kex1),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ ok = ssh_sftp:write_file(SftpPid, DataFile, "hi\n"),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying with simulataneous send request
+
+renegotiate1(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "renegotiate1.data"),
+
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ RPort = ssh_test_lib:inet_port(),
+ {ok,RelayPid} = ssh_relay:start_link({0,0,0,0}, RPort, Host, DPort),
+
+
+ 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),
+
+ {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
+
+ ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
+
+ ssh_relay:hold(RelayPid, rx, 20, 1000),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
+
+ timer:sleep(2000),
+
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ ssh_relay:stop(RelayPid),
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying with inflight messages from peer
+
+renegotiate2(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "renegotiate2.data"),
+
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ RPort = ssh_test_lib:inet_port(),
+ {ok,RelayPid} = ssh_relay:start_link({0,0,0,0}, RPort, Host, DPort),
+
+ 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),
+
+ {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
+
+ ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
+
+ ssh_relay:hold(RelayPid, rx, 20, infinity),
+ spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
+ %% need a small pause here to ensure ssh_sftp:write is executed
+ ct:sleep(10),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ ssh_relay:release(RelayPid, rx),
+
+ timer:sleep(2000),
+
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ ssh_relay:stop(RelayPid),
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%% 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_renegotiate_SUITE_data/id_dsa b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index cb74a27638..c2b04d7a05 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,99 +27,166 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
-% Default timetrap timeout
+ % Default timetrap timeout
-define(default_timeout, ?t:minutes(1)).
--define(USER, "Alladin").
--define(PASSWD, "Sesame").
-
--define(tar_file_name, "sftp_tar_test.tar").
-
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
suite() ->
- [{ct_hooks,[ts_install_cth]}].
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,2}}].
+
all() ->
- [{group, erlang_server},
- {group, openssh_server},
- sftp_nonexistent_subsystem
+ [{group, not_unicode},
+ {group, unicode}
].
init_per_suite(Config) ->
- case (catch crypto:start()) of
- ok ->
- ssh:start(),
- Config;
- _ ->
- {skip,"Could not start crypto!"}
- end.
-
-end_per_suite(Config) ->
- ssh:stop(),
- crypto:stop(),
+ ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p",
+ [file:native_name_encoding(),io:getopts()]),
+ ssh:start(),
Config.
+end_per_suite(_onfig) ->
+ ssh:stop().
+
%%--------------------------------------------------------------------
groups() ->
- [{erlang_server, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, write_big_file, sftp_read_big_file,
- rename_file, mk_rm_dir, remove_file, links,
- retrieve_attributes, set_attributes, async_read,
- async_write, position, pos_read, pos_write, version_option,
+ [{not_unicode, [], [{group,erlang_server},
+ {group,openssh_server},
+ sftp_nonexistent_subsystem]},
+
+ {unicode, [], [{group,erlang_server},
+ {group,openssh_server},
+ sftp_nonexistent_subsystem]},
+
+ {erlang_server, [], [{group,write_read_tests},
+ version_option,
{group,remote_tar}]},
- {openssh_server, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, write_big_file, sftp_read_big_file,
- rename_file, mk_rm_dir, remove_file, links,
- retrieve_attributes, set_attributes, async_read,
- async_write, position, pos_read, pos_write,
+ {openssh_server, [], [{group,write_read_tests},
{group,remote_tar}]},
- {remote_tar, [], [create_empty_tar, files_to_tar, big_file_to_tar, files_chunked_to_tar,
+ {remote_tar, [], [create_empty_tar,
+ ascii_filename_ascii_contents_to_tar,
+ ascii_filename_unicode_contents_to_tar,
+ unicode_filename_ascii_contents_to_tar,
+ files_to_tar,
+ big_file_to_tar, files_chunked_to_tar,
directory_to_tar, binaries_to_tar, null_crypto_tar,
simple_crypto_tar_small, simple_crypto_tar_big,
read_tar, read_null_crypto_tar, read_crypto_tar,
aes_cbc256_crypto_tar, aes_ctr_stream_crypto_tar
- ]}
+ ]},
+
+ {write_read_tests, [], [open_close_file, open_close_dir, read_file, read_dir,
+ write_file, write_file_iolist, write_big_file, sftp_read_big_file,
+ rename_file, mk_rm_dir, remove_file, links,
+ retrieve_attributes, set_attributes, async_read,
+ async_write, position, pos_read, pos_write
+ ]}
].
-
+
+init_per_group(not_unicode, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ [{user, "Alladin"},
+ {passwd, "Sesame"},
+ {data, <<"Hello world!">>},
+ {filename, filename:join(PrivDir, "sftp.txt")},
+ {testfile, filename:join(PrivDir, "test.txt")},
+ {linktest, filename:join(PrivDir, "link_test.txt")},
+ {tar_filename, filename:join(PrivDir, "sftp_tar_test.tar")},
+ {tar_F1_txt, "f1.txt"},
+ {datadir_tar, filename:join(DataDir,"sftp_tar_test_data")}
+ | Config];
+
+init_per_group(unicode, Config) ->
+ case file:native_name_encoding() of
+ utf8 ->
+ ct:comment("Begin ~p",[grps(Config)]),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ NewConfig =
+ [{user, "åke高兴"},
+ {passwd, "ärlig日本じん"},
+ {data, <<"foobar å 一二三四いちにさんち">>},
+ {filename, filename:join(PrivDir, "sftp瑞点.txt")},
+ {testfile, filename:join(PrivDir, "testハンス.txt")},
+ {linktest, filename:join(PrivDir, "link_test語.txt")},
+ {tar_filename, filename:join(PrivDir, "sftp_tar_test一二三.tar")},
+ {tar_F1_txt, "F一.txt"},
+ {tar_F3_txt, "f3.txt"},
+ {tar_F4_txt, "g四.txt"},
+ {datadir_tar, filename:join(DataDir,"sftp_tar_test_data_高兴")}
+ | lists:foldl(fun(K,Cf) -> lists:keydelete(K,1,Cf) end,
+ Config,
+ [user, passwd, data,
+ filename, testfile, linktest,
+ tar_filename, tar_F1_txt, datadir_tar
+ ]
+ )
+ ],
+ FN = fn(?config(tar_F1_txt,NewConfig), NewConfig),
+ case catch file:read_file(FN) of
+ {ok,FN_contents} ->
+ ct:log("Readable file:read_file(~tp) ->~n~tp",[FN,FN_contents]),
+ NewConfig;
+ Other ->
+ ct:log("Unreadable file:read_file(~tp) ->~n~p",[FN,Other]),
+ {skip, "Not unicode file reading"}
+ end;
+
+ _ ->
+ {skip, "Not unicode file encoding"}
+ end;
init_per_group(erlang_server, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
PrivDir = ?config(priv_dir, Config),
SysDir = ?config(data_dir, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
Sftpd = {_, HostX, PortX} =
ssh_test_lib:daemon([{system_dir, SysDir},
{user_dir, PrivDir},
{user_passwords,
- [{?USER, ?PASSWD}]}]),
+ [{User, Passwd}]}]),
[{peer, {fmt_host(HostX),PortX}}, {group, erlang_server}, {sftpd, Sftpd} | Config];
init_per_group(openssh_server, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
Host = ssh_test_lib:hostname(),
- case (catch ssh_sftp:start_channel(Host,
+ case (catch ssh_sftp:start_channel(Host,
[{user_interaction, false},
{silently_accept_hosts, true}])) of
{ok, _ChannelPid, Connection} ->
[{peer, {_HostName,{IPx,Portx}}}] = ssh:connection_info(Connection,[peer]),
ssh:close(Connection),
[{peer, {fmt_host(IPx),Portx}}, {group, openssh_server} | Config];
+ {error,"Key exchange failed"} ->
+ {skip, "openssh server doesn't support the tested kex algorithm"};
_ ->
{skip, "No openssh server"}
end;
init_per_group(remote_tar, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
{Host,Port} = ?config(peer, Config),
ct:log("Server (~p) at ~p:~p",[?config(group,Config),Host,Port]),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
{ok, Connection} =
case ?config(group, Config) of
erlang_server ->
ssh:connect(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
+ [{user, User},
+ {password, Passwd},
{user_interaction, false},
{silently_accept_hosts, true}]);
openssh_server ->
@@ -127,11 +195,23 @@ init_per_group(remote_tar, Config) ->
{silently_accept_hosts, true}])
end,
[{remote_tar, true},
- {connection, Connection} | Config].
+ {connection, Connection} | Config];
+
+init_per_group(write_read_tests, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
+ Config.
+
+grps(Config) ->
+ proplists:get_all_values(
+ name,
+ lists:flatten([proplists:get_value(tc_group_properties,Config,[]),
+ proplists:get_value(tc_group_path,Config,[])])).
end_per_group(erlang_server, Config) ->
+ ct:comment("End ~p",[grps(Config)]),
Config;
end_per_group(_, Config) ->
+ ct:comment("End ~p",[grps(Config)]),
Config.
%%--------------------------------------------------------------------
@@ -139,11 +219,13 @@ end_per_group(_, Config) ->
init_per_testcase(sftp_nonexistent_subsystem, Config) ->
PrivDir = ?config(priv_dir, Config),
SysDir = ?config(data_dir, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
Sftpd = ssh_test_lib:daemon([{system_dir, SysDir},
{user_dir, PrivDir},
{subsystems, []},
{user_passwords,
- [{?USER, ?PASSWD}]}
+ [{User, Passwd}]}
]),
[{sftpd, Sftpd} | Config];
@@ -153,11 +235,13 @@ init_per_testcase(version_option, Config) ->
TmpConfig = lists:keydelete(sftp, 1, TmpConfig0),
Dog = ct:timetrap(?default_timeout),
{_,Host, Port} = ?config(sftpd, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
{ok, ChannelPid, Connection} =
ssh_sftp:start_channel(Host, Port,
[{sftp_vsn, 3},
- {user, ?USER},
- {password, ?PASSWD},
+ {user, User},
+ {password, Passwd},
{user_interaction, false},
{silently_accept_hosts, true}]),
Sftp = {ChannelPid, Connection},
@@ -167,7 +251,9 @@ init_per_testcase(Case, Config0) ->
prep(Config0),
Config1 = lists:keydelete(watchdog, 1, Config0),
Config2 = lists:keydelete(sftp, 1, Config1),
- Dog = ct:timetrap(?default_timeout),
+ Dog = ct:timetrap(2 * ?default_timeout),
+ User = ?config(user, Config0),
+ Passwd = ?config(passwd, Config0),
Config =
case ?config(group,Config2) of
@@ -175,10 +261,11 @@ init_per_testcase(Case, Config0) ->
{_,Host, Port} = ?config(sftpd, Config2),
{ok, ChannelPid, Connection} =
ssh_sftp:start_channel(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
+ [{user, User},
+ {password, Passwd},
{user_interaction, false},
- {silently_accept_hosts, true}]),
+ {silently_accept_hosts, true}]
+ ),
Sftp = {ChannelPid, Connection},
[{sftp, Sftp}, {watchdog, Dog} | Config2];
openssh_server when Case == links ->
@@ -206,8 +293,7 @@ init_per_testcase(Case, Config0) ->
end_per_testcase(sftp_nonexistent_subsystem, Config) ->
Config;
end_per_testcase(rename_file, Config) ->
- PrivDir = ?config(priv_dir, Config),
- NewFileName = filename:join(PrivDir, "test.txt"),
+ NewFileName = ?config(testfile, Config),
file:delete(NewFileName),
end_per_testcase(Config);
end_per_testcase(_, Config) ->
@@ -225,8 +311,7 @@ end_per_testcase(Config) ->
open_close_file() ->
[{doc, "Test API functions open/3 and close/2"}].
open_close_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
@@ -247,7 +332,7 @@ open_close_dir() ->
open_close_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{ok, Handle} = ssh_sftp:opendir(Sftp, PrivDir),
ok = ssh_sftp:close(Sftp, Handle),
@@ -257,8 +342,7 @@ open_close_dir(Config) when is_list(Config) ->
read_file() ->
[{doc, "Test API funtion read_file/2"}].
read_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Data} = ssh_sftp:read_file(Sftp, FileName),
{ok, Data} = ssh_sftp:read_file(Sftp, FileName),
@@ -271,14 +355,13 @@ read_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("sftp list dir: ~p~n", [Files]).
+ ct:log("sftp list dir: ~p~n", [Files]).
%%--------------------------------------------------------------------
write_file() ->
[{doc, "Test API function write_file/2"}].
write_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary("Hej hopp!"),
@@ -286,11 +369,31 @@ write_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
+write_file_iolist() ->
+ [{doc, "Test API function write_file/2 with iolists"}].
+write_file_iolist(Config) when is_list(Config) ->
+ FileName = ?config(filename, Config),
+ {Sftp, _} = ?config(sftp, Config),
+
+ Data = list_to_binary("Hej hopp!"),
+ lists:foreach(
+ fun(D) ->
+ ssh_sftp:write_file(Sftp, FileName, [D]),
+ Expected = if is_binary(D) -> D;
+ is_list(D) -> list_to_binary(D)
+ end,
+ {ok, Expected} = file:read_file(FileName)
+ end,
+ [Data, [Data,Data], [[Data],[Data]], [[[Data]],[[[[Data]],Data]]],
+ [[[[Data]],Data],binary_to_list(Data)],
+ [[[[Data]],Data],[[binary_to_list(Data)],[[binary_to_list(Data)]]]]
+ ]).
+
+%%--------------------------------------------------------------------
write_big_file() ->
[{doc, "Test API function write_file/2 with big data"}].
write_big_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary(lists:duplicate(750000,"a")),
@@ -301,8 +404,7 @@ write_big_file(Config) when is_list(Config) ->
sftp_read_big_file() ->
[{doc, "Test API function read_file/2 with big data"}].
sftp_read_big_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary(lists:duplicate(750000,"a")),
@@ -315,7 +417,7 @@ remove_file() ->
[{doc,"Test API function delete/2"}].
remove_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
@@ -329,17 +431,17 @@ rename_file() ->
[{doc, "Test API function rename_file/2"}].
rename_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
- NewFileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(filename, Config),
+ NewFileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~p, Files: ~p~n", [FileName, Files]),
+ ct:log("FileName: ~p, Files: ~p~n", [FileName, Files]),
true = lists:member(filename:basename(FileName), Files),
false = lists:member(filename:basename(NewFileName), Files),
ok = ssh_sftp:rename(Sftp, FileName, NewFileName),
{ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~p, Files: ~p~n", [FileName, NewFiles]),
+ ct:log("FileName: ~p, Files: ~p~n", [FileName, NewFiles]),
false = lists:member(filename:basename(FileName), NewFiles),
true = lists:member(filename:basename(NewFileName), NewFiles).
@@ -350,7 +452,7 @@ mk_rm_dir() ->
mk_rm_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
-
+
DirName = filename:join(PrivDir, "test"),
ok = ssh_sftp:make_dir(Sftp, DirName),
ok = ssh_sftp:del_dir(Sftp, DirName),
@@ -367,9 +469,8 @@ links(Config) when is_list(Config) ->
{skip, "Links are not fully supported by windows"};
_ ->
{Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
- LinkFileName = filename:join(PrivDir, "link_test.txt"),
+ FileName = ?config(filename, Config),
+ LinkFileName = ?config(linktest, Config),
ok = ssh_sftp:make_symlink(Sftp, LinkFileName, FileName),
{ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName)
@@ -379,22 +480,20 @@ links(Config) when is_list(Config) ->
retrieve_attributes() ->
[{doc, "Test API function read_file_info/3"}].
retrieve_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, FileInfo} = ssh_sftp:read_file_info(Sftp, FileName),
{ok, NewFileInfo} = file:read_file_info(FileName),
%% TODO comparison. There are some differences now is that ok?
- ct:pal("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]).
+ ct:log("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]).
%%--------------------------------------------------------------------
set_attributes() ->
[{doc,"Test API function write_file_info/3"}].
set_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
{ok,Fd} = file:open(FileName, write),
@@ -410,26 +509,26 @@ async_read() ->
[{doc,"Test API aread/3"}].
async_read(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]),
{async, Ref} = ssh_sftp:aread(Sftp, Handle, 20),
receive
{async_reply, Ref, {ok, Data}} ->
- ct:pal("Data: ~p~n", [Data]),
+ ct:log("Data: ~p~n", [Data]),
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
async_write() ->
[{doc,"Test API awrite/3"}].
async_write(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
Data = list_to_binary("foobar"),
{async, Ref} = ssh_sftp:awrite(Sftp, Handle, Data),
@@ -446,8 +545,7 @@ async_write(Config) when is_list(Config) ->
position() ->
[{doc, "Test API functions position/3"}].
position(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary("1234567890"),
@@ -476,8 +574,7 @@ position(Config) when is_list(Config) ->
pos_read() ->
[{doc,"Test API functions pread/3 and apread/3"}].
pos_read(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary("Hej hopp!"),
ssh_sftp:write_file(Sftp, FileName, [Data]),
@@ -492,6 +589,8 @@ pos_read(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
NewData1 = "hopp",
@@ -502,8 +601,7 @@ pos_read(Config) when is_list(Config) ->
pos_write() ->
[{doc,"Test API functions pwrite/4 and apwrite/4"}].
pos_write(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
@@ -518,6 +616,8 @@ pos_write(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
ok = ssh_sftp:pwrite(Sftp, Handle, eof, list_to_binary("!")),
@@ -530,10 +630,13 @@ sftp_nonexistent_subsystem() ->
[{doc, "Try to execute sftp subsystem on a server that does not support it"}].
sftp_nonexistent_subsystem(Config) when is_list(Config) ->
{_,Host, Port} = ?config(sftpd, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
{error,"server failed to start sftp subsystem"} =
ssh_sftp:start_channel(Host, Port,
[{user_interaction, false},
- {user, ?USER}, {password, ?PASSWD},
+ {user, User},
+ {password, Passwd},
{silently_accept_hosts, true}]).
%%--------------------------------------------------------------------
@@ -545,25 +648,66 @@ version_option(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
create_empty_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
erl_tar:close(Handle),
{ChPid,_} = ?config(sftp,Config),
{ok, #file_info{type=regular}} =
- ssh_sftp:read_file_info(ChPid,fnp(?tar_file_name,Config)).
+ ssh_sftp:read_file_info(ChPid, TarFileName).
%%--------------------------------------------------------------------
files_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ F1 = ?config(tar_F1_txt, Config),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose]),
ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]),
ok = erl_tar:close(Handle),
- chk_tar(["f1.txt", "f2.txt"], Config).
+ chk_tar([F1, "f2.txt"], Config).
+
+%%--------------------------------------------------------------------
+ascii_filename_ascii_contents_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar(["f2.txt"], Config).
+
+%%--------------------------------------------------------------------
+ascii_filename_unicode_contents_to_tar(Config) ->
+ case ?config(tar_F3_txt, Config) of
+ undefined ->
+ {skip, "Unicode test"};
+ Fn ->
+ ChPid2 = ?config(channel_pid2, Config),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ ok = erl_tar:add(Handle, fn(Fn,Config), Fn, [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar([Fn], Config)
+ end.
+
+%%--------------------------------------------------------------------
+unicode_filename_ascii_contents_to_tar(Config) ->
+ case ?config(tar_F4_txt, Config) of
+ undefined ->
+ {skip, "Unicode test"};
+ Fn ->
+ ChPid2 = ?config(channel_pid2, Config),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ ok = erl_tar:add(Handle, fn(Fn,Config), Fn, [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar([Fn], Config)
+ end.
%%--------------------------------------------------------------------
big_file_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose]),
ok = erl_tar:close(Handle),
chk_tar(["big.txt"], Config).
@@ -572,23 +716,27 @@ big_file_to_tar(Config) ->
%%--------------------------------------------------------------------
files_chunked_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ F1 = ?config(tar_F1_txt, Config),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:close(Handle),
- chk_tar(["f1.txt"], Config).
+ chk_tar([F1], Config).
%%--------------------------------------------------------------------
directory_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
ok = erl_tar:add(Handle, fn("d1",Config), "d1", [verbose]),
ok = erl_tar:close(Handle),
chk_tar(["d1"], Config).
-
+
%%--------------------------------------------------------------------
binaries_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
Bin = <<"A binary">>,
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
ok = erl_tar:close(Handle),
@@ -601,13 +749,15 @@ null_crypto_tar(Config) ->
Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=5} end,
Cend = fun(Bin,_CState) -> {ok,Bin} end,
C = {Cinit,Cenc,Cend},
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]),
Bin = <<"A binary">>,
+ F1 = ?config(tar_F1_txt, Config),
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]),
ok = erl_tar:close(Handle),
- chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config).
+ chk_tar([{"b1",Bin}, F1, "big.txt"], Config).
%%--------------------------------------------------------------------
simple_crypto_tar_small(Config) ->
@@ -617,12 +767,14 @@ simple_crypto_tar_small(Config) ->
Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_Size=4} end,
Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
C = {Cinit,Cenc,Cend},
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]),
Bin = <<"A binary">>,
+ F1 = ?config(tar_F1_txt, Config),
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:close(Handle),
- chk_tar([{"b1",Bin}, "f1.txt"], Config, [{crypto,{Cinit,Cdec}}]).
+ chk_tar([{"b1",Bin}, F1], Config, [{crypto,{Cinit,Cdec}}]).
%%--------------------------------------------------------------------
simple_crypto_tar_big(Config) ->
@@ -632,18 +784,20 @@ simple_crypto_tar_big(Config) ->
Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_SendSize=4} end,
Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
C = {Cinit,Cenc,Cend},
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]),
Bin = <<"A binary">>,
+ F1 = ?config(tar_F1_txt, Config),
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]),
ok = erl_tar:close(Handle),
- chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config, [{crypto,{Cinit,Cdec}}]).
+ chk_tar([{"b1",Bin}, F1, "big.txt"], Config, [{crypto,{Cinit,Cdec}}]).
stuff(Bin) -> << <<C,C>> || <<C>> <= Bin >>.
-
+
unstuff(Bin) -> << <<C>> || <<C,C>> <= Bin >>.
-
+
%%--------------------------------------------------------------------
read_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
@@ -651,7 +805,8 @@ read_tar(Config) ->
[{"b1",<<"A binary">>},
{"b2",list_to_binary(lists:duplicate(750000,"a"))}
]),
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
|| {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -673,7 +828,8 @@ read_null_crypto_tar(Config) ->
Cw = {Cinitw,Cenc,Cendw},
Cr = {Cinitr,Cdec},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
|| {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -696,7 +852,8 @@ read_crypto_tar(Config) ->
Cw = {Cinitw,Cenc,Cendw},
Cr = {Cinitr,Cdec},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
|| {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -735,7 +892,8 @@ aes_cbc256_crypto_tar(Config) ->
end,
Cw = {Cinitw,Cenc,Cendw},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -777,7 +935,8 @@ aes_ctr_stream_crypto_tar(Config) ->
end,
Cw = {Cinitw,Cenc,Cendw},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -788,18 +947,18 @@ aes_ctr_stream_crypto_tar(Config) ->
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
prep(Config) ->
- PrivDir = ?config(priv_dir, Config),
- TestFile = filename:join(PrivDir, "sftp.txt"),
- TestFile1 = filename:join(PrivDir, "test.txt"),
- TestLink = filename:join(PrivDir, "link_test.txt"),
+ DataDir = ?config(data_dir, Config),
+ TestFile = ?config(filename, Config),
+ TestFile1 = ?config(testfile, Config),
+ TestLink = ?config(linktest, Config),
+ TarFileName = ?config(tar_filename, Config),
file:delete(TestFile),
file:delete(TestFile1),
file:delete(TestLink),
- file:delete(fnp(?tar_file_name,Config)),
+ file:delete(TarFileName),
%% Initial config
- DataDir = ?config(data_dir, Config),
FileName = filename:join(DataDir, "sftp.txt"),
file:copy(FileName, TestFile),
Mode = 8#00400 bor 8#00200 bor 8#00040, % read & write owner, read group
@@ -807,13 +966,12 @@ prep(Config) ->
ok = file:write_file_info(TestFile,
FileInfo#file_info{mode = Mode}).
-
-
chk_tar(Items, Config) ->
chk_tar(Items, Config, []).
chk_tar(Items, Config, Opts) ->
- chk_tar(Items, fnp(?tar_file_name,Config), Config, Opts).
+ TarFileName = ?config(tar_filename, Config),
+ chk_tar(Items, TarFileName, Config, Opts).
chk_tar(Items, TarFileName, Config, Opts) when is_list(Opts) ->
tar_size(TarFileName, Config),
@@ -844,7 +1002,7 @@ analyze_report([E={NameE,BinE}|Es], [A={NameA,BinA}|As]) ->
NameE < NameA ->
[["Component ",NameE," is missing.\n\n"]
| analyze_report(Es,[A|As])];
-
+
NameE > NameA ->
[["Component ",NameA," is not expected.\n\n"]
| analyze_report([E|Es],As)];
@@ -857,7 +1015,7 @@ analyze_report([], [{NameA,_BinA}|As]) ->
[["Component ",NameA," not expected.\n\n"] | analyze_report([],As)];
analyze_report([], []) ->
"".
-
+
tar_size(TarFileName, Config) ->
{ChPid,_} = ?config(sftp,Config),
{ok,Data} = ssh_sftp:read_file(ChPid, TarFileName),
@@ -886,14 +1044,9 @@ read_item_contents(ItemName, FileName) ->
end.
fn(Name, Config) ->
- Dir = ?config(data_dir, Config),
- filename:join([Dir,"sftp_tar_test_data",Name]).
-
-fnp(Name, Config) ->
- Dir = ?config(priv_dir, Config),
- filename:join([Dir,Name]).
-
+ Dir = ?config(datadir_tar, Config),
+ filename:join(Dir,Name).
fmt_host({A,B,C,D}) -> lists:concat([A,".",B,".",C,".",D]);
fmt_host(S) -> S.
-
+
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt
new file mode 100644
index 0000000000..e6076a05b5
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt
@@ -0,0 +1 @@
+你好
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt
new file mode 100644
index 0000000000..f597b69d4c
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt
@@ -0,0 +1,16384 @@
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f1 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f1
new file mode 100644
index 0000000000..1bafa9761e
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f1
@@ -0,0 +1 @@
+And hi from the subdirectory too!
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f2 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f2
new file mode 100644
index 0000000000..8566adaeef
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f2
@@ -0,0 +1 @@
+one more file
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt
new file mode 100644
index 0000000000..d18c6b11fc
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt
@@ -0,0 +1 @@
+How are you?
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt
new file mode 100644
index 0000000000..e6076a05b5
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt
@@ -0,0 +1 @@
+你好
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt
new file mode 100644
index 0000000000..d18c6b11fc
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt
@@ -0,0 +1 @@
+How are you?
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 0ce8eec906..45439ce0fa 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -43,6 +44,9 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{minutes,3}}].
+
all() ->
[open_close_file,
open_close_dir,
@@ -68,27 +72,21 @@ groups() ->
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- case (catch crypto:start()) of
- ok ->
- DataDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- %% to make sure we don't use public-key-auth
- %% this should be tested by other test suites
- UserDir = filename:join(?config(priv_dir, Config), nopubkey),
- file:make_dir(UserDir),
- Config;
- _ ->
- {skip,"Could not start crypto!"}
- end.
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ %% to make sure we don't use public-key-auth
+ %% this should be tested by other test suites
+ UserDir = filename:join(?config(priv_dir, Config), nopubkey),
+ file:make_dir(UserDir),
+ Config.
end_per_suite(Config) ->
SysDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(SysDir),
UserDir = filename:join(?config(priv_dir, Config), nopubkey),
file:del_dir(UserDir),
- ssh:stop(),
- crypto:stop().
+ ssh:stop().
%%--------------------------------------------------------------------
@@ -150,7 +148,7 @@ init_per_testcase(TestCase, Config) ->
{ok, <<?SSH_FXP_VERSION, ?UINT32(Version), _Ext/binary>>, _}
= reply(Cm, Channel),
- ct:pal("Client: ~p Server ~p~n", [ProtocolVer, Version]),
+ ct:log("Client: ~p Server ~p~n", [ProtocolVer, Version]),
[{sftp, {Cm, Channel}}, {sftpd, Sftpd }| Config].
@@ -416,7 +414,7 @@ real_path(Config) when is_list(Config) ->
RealPath = filename:absname(binary_to_list(Path)),
AbsPrivDir = filename:absname(PrivDir),
- ct:pal("Path: ~p PrivDir: ~p~n", [RealPath, AbsPrivDir]),
+ ct:log("Path: ~p PrivDir: ~p~n", [RealPath, AbsPrivDir]),
true = RealPath == AbsPrivDir
end.
@@ -445,7 +443,7 @@ links(Config) when is_list(Config) ->
true = binary_to_list(Path) == FileName,
- ct:pal("Path: ~p~n", [binary_to_list(Path)])
+ ct:log("Path: ~p~n", [binary_to_list(Path)])
end.
%%--------------------------------------------------------------------
@@ -546,10 +544,10 @@ set_attributes(Config) when is_list(Config) ->
%% Can not test that NewPermissions = Permissions as
%% on Unix platforms, other bits than those listed in the
%% API may be set.
- ct:pal("Org: ~p New: ~p~n", [OrigPermissions, NewPermissions]),
+ ct:log("Org: ~p New: ~p~n", [OrigPermissions, NewPermissions]),
true = OrigPermissions =/= NewPermissions,
- ct:pal("Try to open the file"),
+ ct:log("Try to open the file"),
NewReqId = 2,
{ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId), Handle/binary>>, _} =
open_file(FileName, Cm, Channel, NewReqId,
@@ -561,7 +559,7 @@ set_attributes(Config) when is_list(Config) ->
NewReqId1 = 3,
- ct:pal("Set original permissions on the now open file"),
+ ct:log("Set original permissions on the now open file"),
{ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId1),
?UINT32(?SSH_FX_OK), _/binary>>, _} =
@@ -681,6 +679,8 @@ reply(Cm, Channel, RBuf) ->
closed;
{ssh_cm, Cm, Msg} ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -784,7 +784,7 @@ read_dir(Handle, Cm, Channel, ReqId) ->
case reply(Cm, Channel) of
{ok, <<?SSH_FXP_NAME, ?UINT32(ReqId), ?UINT32(Count),
?UINT32(Len), Listing:Len/binary, _/binary>>, _} ->
- ct:pal("Count: ~p Listing: ~p~n",
+ ct:log("Count: ~p Listing: ~p~n",
[Count, binary_to_list(Listing)]),
read_dir(Handle, Cm, Channel, ReqId);
{ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId),
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
index cc34cc0793..02a2ac4cf9 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -35,7 +36,9 @@
%%--------------------------------------------------------------------
suite() ->
- [{ct_hooks,[ts_install_cth]}].
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,2}}].
+
all() ->
[close_file,
@@ -52,28 +55,22 @@ groups() ->
init_per_suite(Config) ->
catch ssh:stop(),
- case catch crypto:start() of
- ok ->
- DataDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- FileAlt = filename:join(DataDir, "ssh_sftpd_file_alt.erl"),
- c:c(FileAlt),
- FileName = filename:join(DataDir, "test.txt"),
- {ok, FileInfo} = file:read_file_info(FileName),
- ok = file:write_file_info(FileName,
- FileInfo#file_info{mode = 8#400}),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- Config;
- _Else ->
- {skip,"Could not start ssh!"}
- end.
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ FileAlt = filename:join(DataDir, "ssh_sftpd_file_alt.erl"),
+ c:c(FileAlt),
+ FileName = filename:join(DataDir, "test.txt"),
+ {ok, FileInfo} = file:read_file_info(FileName),
+ ok = file:write_file_info(FileName,
+ FileInfo#file_info{mode = 8#400}),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config.
end_per_suite(Config) ->
UserDir = filename:join(?config(priv_dir, Config), nopubkey),
file:del_dir(UserDir),
SysDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(SysDir),
- crypto:stop(),
ok.
%%--------------------------------------------------------------------
@@ -157,7 +154,7 @@ close_file(Config) when is_list(Config) ->
NumOfPorts = length(erlang:ports()),
- ct:pal("Number of open ports: ~p~n", [NumOfPorts]),
+ ct:log("Number of open ports: ~p~n", [NumOfPorts]),
{ok, <<_/binary>>} = ssh_sftp:read_file(Sftp, FileName),
@@ -253,14 +250,14 @@ root_dir(Config) when is_list(Config) ->
{ok, Bin} = ssh_sftp:read_file(Sftp, FileName),
{ok, Listing} =
ssh_sftp:list_dir(Sftp, "."),
- ct:pal("Listing: ~p~n", [Listing]).
+ ct:log("Listing: ~p~n", [Listing]).
%%--------------------------------------------------------------------
list_dir_limited(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
{ok, Listing} =
ssh_sftp:list_dir(Sftp, "."),
- ct:pal("Listing: ~p~n", [Listing]).
+ ct:log("Listing: ~p~n", [Listing]).
%%--------------------------------------------------------------------
ver6_basic() ->
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
index 8ad383d8c9..4f494cf829 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssh/test/ssh_sup_SUITE.erl b/lib/ssh/test/ssh_sup_SUITE.erl
new file mode 100644
index 0000000000..18e91a9af3
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE.erl
@@ -0,0 +1,197 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssh_sup_SUITE).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(WAIT_FOR_SHUTDOWN, 500).
+-define(USER, "Alladin").
+-define(PASSWD, "Sesame").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,1}}].
+
+all() ->
+ [default_tree, sshc_subtree, sshd_subtree, sshd_subtree_profile].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_suite(Config) ->
+ Port = ssh_test_lib:inet_port(node()),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ [{userdir, UserDir},{port, Port}, {host, "localhost"}, {host_ip, any} | Config].
+
+end_per_suite(_) ->
+ ok.
+
+init_per_testcase(sshc_subtree, Config) ->
+ ssh:start(),
+ SystemDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]}]),
+ [{server, {Pid, Host, Port}} | Config];
+init_per_testcase(Case, Config) ->
+ end_per_testcase(Case, Config),
+ ssh:start(),
+ Config.
+end_per_testcase(sshc_subtree, Config) ->
+ {Pid,_,_} = ?config(server, Config),
+ ssh:stop_daemon(Pid),
+ ssh:stop();
+end_per_testcase(_, _Config) ->
+ ssh:stop().
+
+%%-------------------------------------------------------------------------
+%% Test cases
+%%-------------------------------------------------------------------------
+default_tree() ->
+ [{doc, "Makes sure the correct processes are started and linked,"
+ "in the default case."}].
+default_tree(Config) when is_list(Config) ->
+ TopSupChildren = supervisor:which_children(ssh_sup),
+ 2 = length(TopSupChildren),
+ {value, {sshc_sup, _, supervisor,[sshc_sup]}} =
+ lists:keysearch(sshc_sup, 1, TopSupChildren),
+ {value, {sshd_sup, _,supervisor,[sshd_sup]}} =
+ lists:keysearch(sshd_sup, 1, TopSupChildren),
+ [] = supervisor:which_children(sshc_sup),
+ [] = supervisor:which_children(sshd_sup).
+
+sshc_subtree() ->
+ [{doc, "Make sure the sshc subtree is correct"}].
+sshc_subtree(Config) when is_list(Config) ->
+ {_Pid, Host, Port} = ?config(server, Config),
+ UserDir = ?config(userdir, Config),
+
+ [] = supervisor:which_children(sshc_sup),
+ {ok, Pid1} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD},{user_dir, UserDir}]),
+ [{_, _,supervisor,[ssh_connection_handler]}] =
+ supervisor:which_children(sshc_sup),
+ {ok, Pid2} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD}, {user_dir, UserDir}]),
+ [{_,_,supervisor,[ssh_connection_handler]},
+ {_,_,supervisor,[ssh_connection_handler]}] =
+ supervisor:which_children(sshc_sup),
+ ssh:close(Pid1),
+ [{_,_,supervisor,[ssh_connection_handler]}] =
+ supervisor:which_children(sshc_sup),
+ ssh:close(Pid2),
+ ct:sleep(?WAIT_FOR_SHUTDOWN),
+ [] = supervisor:which_children(sshc_sup).
+
+sshd_subtree() ->
+ [{doc, "Make sure the sshd subtree is correct"}].
+sshd_subtree(Config) when is_list(Config) ->
+ HostIP = ?config(host_ip, Config),
+ Port = ?config(port, Config),
+ SystemDir = ?config(data_dir, Config),
+ ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]}]),
+ [{{server,ssh_system_sup, HostIP, Port, ?DEFAULT_PROFILE},
+ Daemon, supervisor,
+ [ssh_system_sup]}] =
+ supervisor:which_children(sshd_sup),
+ check_sshd_system_tree(Daemon, Config),
+ ssh:stop_daemon(HostIP, Port),
+ ct:sleep(?WAIT_FOR_SHUTDOWN),
+ [] = supervisor:which_children(sshd_sup).
+
+sshd_subtree_profile() ->
+ [{doc, "Make sure the sshd subtree using profile option is correct"}].
+sshd_subtree_profile(Config) when is_list(Config) ->
+ HostIP = ?config(host_ip, Config),
+ Port = ?config(port, Config),
+ Profile = ?config(profile, Config),
+ SystemDir = ?config(data_dir, Config),
+
+ {ok, _} = ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]},
+ {profile, Profile}]),
+ [{{server,ssh_system_sup, HostIP,Port,Profile},
+ Daemon, supervisor,
+ [ssh_system_sup]}] =
+ supervisor:which_children(sshd_sup),
+ check_sshd_system_tree(Daemon, Config),
+ ssh:stop_daemon(HostIP, Port, Profile),
+ ct:sleep(?WAIT_FOR_SHUTDOWN),
+ [] = supervisor:which_children(sshd_sup).
+
+
+check_sshd_system_tree(Daemon, Config) ->
+ Host = ?config(host, Config),
+ Port = ?config(port, Config),
+ UserDir = ?config(userdir, Config),
+ {ok, Client} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD},{user_dir, UserDir}]),
+
+ [{_,SubSysSup, supervisor,[ssh_subsystem_sup]},
+ {{ssh_acceptor_sup,_,_,_}, AccSup, supervisor,[ssh_acceptor_sup]}]
+ = supervisor:which_children(Daemon),
+
+ [{{server,ssh_connection_sup, _,_},
+ ConnectionSup, supervisor,
+ [ssh_connection_sup]},
+ {{server,ssh_channel_sup,_ ,_},
+ ChannelSup,supervisor,
+ [ssh_channel_sup]}] = supervisor:which_children(SubSysSup),
+
+ [{{ssh_acceptor_sup,_,_,_},_,worker,[ssh_acceptor]}] =
+ supervisor:which_children(AccSup),
+
+ [{_, _, worker,[ssh_connection_handler]}] =
+ supervisor:which_children(ConnectionSup),
+
+ [] = supervisor:which_children(ChannelSup),
+
+ ssh_sftp:start_channel(Client),
+
+ [{_, _,worker,[ssh_channel]}] =
+ supervisor:which_children(ChannelSup),
+ ssh:close(Client).
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/id_dsa b/lib/ssh/test/ssh_sup_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/id_rsa b/lib/ssh/test/ssh_sup_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_test_cli.erl b/lib/ssh/test/ssh_test_cli.erl
index cd9ad5f2ff..697ddb730d 100644
--- a/lib/ssh/test/ssh_test_cli.erl
+++ b/lib/ssh/test/ssh_test_cli.erl
@@ -4,20 +4,25 @@
-record(state, {
type,
+ tmpdir,
id,
ref,
port
}).
-init([Type]) ->
- {ok, #state{type = Type}}.
+
+init([Type]) -> init([Type,"/tmp"]);
+
+init([Type,TmpDir]) ->
+ {ok, #state{type = Type,
+ tmpdir = TmpDir}}.
handle_msg({ssh_channel_up, Id, Ref}, S) ->
User = get_ssh_user(Ref),
ok = ssh_connection:send(Ref,
Id,
<< "\r\nYou are accessing a dummy, type \"q\" to exit\r\n\n" >>),
- Port = run_portprog(User, S#state.type),
+ Port = run_portprog(User, S#state.type, S#state.tmpdir),
{ok, S#state{port = Port, id = Id, ref = Ref}};
handle_msg({Port, {data, Data}}, S = #state{port = Port}) ->
@@ -68,10 +73,10 @@ handle_ssh_msg({ssh_cm, _, {exit_signal, Id, _, _, _}},
terminate(_Why, _S) ->
nop.
-run_portprog(User, cli) ->
+run_portprog(User, cli, TmpDir) ->
Pty_bin = os:find_executable("cat"),
open_port({spawn_executable, Pty_bin},
- [stream, {cd, "/tmp"}, {env, [{"USER", User}]},
+ [stream, {cd, TmpDir}, {env, [{"USER", User}]},
{args, []}, binary,
exit_status, use_stdio, stderr_to_stdout]).
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index b8abf5e80e..5f91fb627a 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,6 +27,8 @@
-include_lib("public_key/include/public_key.hrl").
-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+
-define(TIMEOUT, 50000).
@@ -64,6 +67,62 @@ daemon(Host, Port, Options) ->
end.
+std_daemon(Config, ExtraOpts) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ std_daemon1(Config,
+ ExtraOpts ++
+ [{user_dir, UserDir},
+ {user_passwords, [{"usr1","pwd1"}]}]).
+
+std_daemon1(Config, ExtraOpts) ->
+ SystemDir = ?config(data_dir, Config),
+ {_Server, _Host, _Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2}
+ | ExtraOpts]).
+
+std_connect(Config, Host, Port, ExtraOpts) ->
+ UserDir = ?config(priv_dir, Config),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "usr1"},
+ {password, "pwd1"},
+ {user_interaction, false}
+ | ExtraOpts]).
+
+std_simple_sftp(Host, Port, Config) ->
+ std_simple_sftp(Host, Port, Config, []).
+
+std_simple_sftp(Host, Port, Config, Opts) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "test.data"),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ {ok, ChannelRef} = ssh_sftp:start_channel(ConnectionRef),
+ Data = crypto:rand_bytes(proplists:get_value(std_simple_sftp_size,Config,10)),
+ ok = ssh_sftp:write_file(ChannelRef, DataFile, Data),
+ {ok,ReadData} = file:read_file(DataFile),
+ ok = ssh:close(ConnectionRef),
+ Data == ReadData.
+
+std_simple_exec(Host, Port, Config) ->
+ std_simple_exec(Host, Port, Config, []).
+
+std_simple_exec(Host, Port, Config, Opts) ->
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId, "23+21-2.", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"42\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end,
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ ssh:close(ConnectionRef).
+
start_shell(Port, IOServer, UserDir) ->
start_shell(Port, IOServer, UserDir, []).
@@ -96,16 +155,16 @@ loop_io_server(TestCase, Buff0) ->
{input, TestCase, Line} ->
loop_io_server(TestCase, Buff0 ++ [Line]);
{io_request, From, ReplyAs, Request} ->
-%%ct:pal("~p",[{io_request, From, ReplyAs, Request}]),
{ok, Reply, Buff} = io_request(Request, TestCase, From,
ReplyAs, Buff0),
-%%ct:pal("io_request(~p)-->~p",[Request,{ok, Reply, Buff}]),
io_reply(From, ReplyAs, Reply),
loop_io_server(TestCase, Buff);
- {'EXIT',_, _} ->
- erlang:display('ssh_test_lib:loop_io_server/2 EXIT'),
+ {'EXIT',_, _} = _Exit ->
+%% ct:log("ssh_test_lib:loop_io_server/2 got ~p",[_Exit]),
ok
- end.
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
io_request({put_chars, Chars}, TestCase, _, _, Buff) ->
reply(TestCase, Chars),
@@ -133,27 +192,29 @@ io_request({get_line, _Enc,_}, _, _, _, [Line | Buff]) ->
io_reply(_, _, []) ->
ok;
io_reply(From, ReplyAs, Reply) ->
-%%ct:pal("io_reply ~p sending ~p ! ~p",[self(),From, {io_reply, ReplyAs, Reply}]),
+%%ct:log("io_reply ~p sending ~p ! ~p",[self(),From, {io_reply, ReplyAs, Reply}]),
From ! {io_reply, ReplyAs, Reply}.
reply(_, []) ->
ok;
reply(TestCase, Result) ->
-%%ct:pal("reply ~p sending ~p ! ~p",[self(), TestCase, Result]),
+%%ct:log("reply ~p sending ~p ! ~p",[self(), TestCase, Result]),
TestCase ! Result.
receive_exec_result(Msg) ->
- ct:pal("Expect data! ~p", [Msg]),
+ ct:log("Expect data! ~p", [Msg]),
receive
{ssh_cm,_,{data,_,1, Data}} ->
- ct:pal("StdErr: ~p~n", [Data]),
+ ct:log("StdErr: ~p~n", [Data]),
receive_exec_result(Msg);
Msg ->
- ct:pal("1: Collected data ~p", [Msg]),
+ ct:log("1: Collected data ~p", [Msg]),
expected;
Other ->
- ct:pal("Other ~p", [Other]),
+ ct:log("Other ~p", [Other]),
{unexpected_msg, Other}
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -164,15 +225,15 @@ receive_exec_end(ConnectionRef, ChannelId) ->
case receive_exec_result(ExitStatus) of
{unexpected_msg, Eof} -> %% Open ssh seems to not allways send these messages
%% in the same order!
- ct:pal("2: Collected data ~p", [Eof]),
+ ct:log("2: Collected data ~p", [Eof]),
case receive_exec_result(ExitStatus) of
expected ->
expected = receive_exec_result(Closed);
{unexpected_msg, Closed} ->
- ct:pal("3: Collected data ~p", [Closed])
+ ct:log("3: Collected data ~p", [Closed])
end;
expected ->
- ct:pal("4: Collected data ~p", [ExitStatus]),
+ ct:log("4: Collected data ~p", [ExitStatus]),
expected = receive_exec_result(Eof),
expected = receive_exec_result(Closed);
Other ->
@@ -234,6 +295,7 @@ setup_dsa(DataDir, UserDir) ->
file:make_dir(System),
file:copy(filename:join(DataDir, "ssh_host_dsa_key"), filename:join(System, "ssh_host_dsa_key")),
file:copy(filename:join(DataDir, "ssh_host_dsa_key.pub"), filename:join(System, "ssh_host_dsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_dsa_known_host(DataDir, UserDir),
setup_dsa_auth_keys(DataDir, UserDir).
@@ -242,10 +304,21 @@ setup_rsa(DataDir, UserDir) ->
System = filename:join(UserDir, "system"),
file:make_dir(System),
file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key.pub")),
+ file:copy(filename:join(DataDir, "ssh_host_rsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_rsa_known_host(DataDir, UserDir),
setup_rsa_auth_keys(DataDir, UserDir).
+setup_ecdsa(Size, DataDir, UserDir) ->
+ file:copy(filename:join(DataDir, "id_ecdsa"++Size), filename:join(UserDir, "id_ecdsa")),
+ System = filename:join(UserDir, "system"),
+ file:make_dir(System),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size), filename:join(System, "ssh_host_ecdsa_key")),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
+ setup_ecdsa_known_host(Size, System, UserDir),
+ setup_ecdsa_auth_keys(Size, UserDir, UserDir).
+
clean_dsa(UserDir) ->
del_dirs(filename:join(UserDir, "system")),
file:delete(filename:join(UserDir,"id_dsa")),
@@ -297,6 +370,11 @@ setup_rsa_known_host(SystemDir, UserDir) ->
[{Key, _}] = public_key:ssh_decode(SshBin, public_key),
setup_known_hosts(Key, UserDir).
+setup_ecdsa_known_host(_Size, SystemDir, UserDir) ->
+ {ok, SshBin} = file:read_file(filename:join(SystemDir, "ssh_host_ecdsa_key.pub")),
+ [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
+ setup_known_hosts(Key, UserDir).
+
setup_known_hosts(Key, UserDir) ->
{ok, Hostname} = inet:gethostname(),
{ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
@@ -324,6 +402,14 @@ setup_rsa_auth_keys(Dir, UserDir) ->
PKey = #'RSAPublicKey'{publicExponent = E, modulus = N},
setup_auth_keys([{ PKey, [{comment, "Test"}]}], UserDir).
+setup_ecdsa_auth_keys(_Size, Dir, UserDir) ->
+ {ok, Pem} = file:read_file(filename:join(Dir, "id_ecdsa")),
+ ECDSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
+ #'ECPrivateKey'{publicKey = Q,
+ parameters = Param = {namedCurve,_Id0}} = ECDSA,
+ PKey = #'ECPoint'{point = Q},
+ setup_auth_keys([{ {PKey,Param}, [{comment, "Test"}]}], UserDir).
+
setup_auth_keys(Keys, Dir) ->
AuthKeys = public_key:ssh_encode(Keys, auth_keys),
AuthKeysFile = filename:join(Dir, "authorized_keys"),
@@ -358,3 +444,249 @@ do_inet_port(Node) ->
{ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
{ok, Port} = rpc:call(Node, inet, port, [Socket]),
{Port, Socket}.
+
+openssh_sanity_check(Config) ->
+ ssh:start(),
+ case ssh:connect("localhost", 22, [{password,""}]) of
+ {ok, Pid} ->
+ ssh:close(Pid),
+ ssh:stop(),
+ Config;
+ Err ->
+ Str = lists:append(io_lib:format("~p", [Err])),
+ ssh:stop(),
+ {skip, Str}
+ end.
+
+openssh_supports(ClientOrServer, Tag, Alg) when ClientOrServer == sshc ;
+ ClientOrServer == sshd ->
+ SSH_algos = ssh_test_lib:default_algorithms(ClientOrServer),
+ L = proplists:get_value(Tag, SSH_algos, []),
+ lists:member(Alg, L) orelse
+ lists:member(Alg, proplists:get_value(client2server, L, [])) orelse
+ lists:member(Alg, proplists:get_value(server2client, L, [])).
+
+%%--------------------------------------------------------------------
+%% Check if we have a "newer" ssh client that supports these test cases
+
+ssh_client_supports_Q() ->
+ ErlPort = open_port({spawn, "ssh -Q cipher"}, [exit_status, stderr_to_stdout]),
+ 0 == check_ssh_client_support2(ErlPort).
+
+check_ssh_client_support2(P) ->
+ receive
+ {P, {data, _A}} ->
+ check_ssh_client_support2(P);
+ {P, {exit_status, E}} ->
+ E
+ after 5000 ->
+
+ ct:log("Openssh command timed out ~n"),
+ -1
+ end.
+
+%%%--------------------------------------------------------------------
+%%% Probe a server or a client about algorithm support
+
+default_algorithms(sshd) ->
+ default_algorithms(sshd, "localhost", 22);
+
+default_algorithms(sshc) ->
+ default_algorithms(sshc, []).
+
+default_algorithms(sshd, Host, Port) ->
+ try run_fake_ssh(
+ ssh_trpt_test_lib:exec(
+ [{connect,Host,Port, [{silently_accept_hosts, true},
+ {user_interaction, false}]}]))
+ catch
+ _C:_E ->
+ ct:log("***~p:~p: ~p:~p",[?MODULE,?LINE,_C,_E]),
+ []
+ end.
+
+default_algorithms(sshc, DaemonOptions) ->
+ Parent = self(),
+ %% Start a process handling one connection on the server side:
+ Srvr =
+ spawn_link(
+ fun() ->
+ Parent !
+ {result, self(),
+ try
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ Parent ! {hostport,self(),ssh_trpt_test_lib:server_host_port(InitialState)},
+ run_fake_ssh(
+ ssh_trpt_test_lib:exec([{accept, DaemonOptions}],
+ InitialState))
+ catch
+ _C:_E ->
+ ct:log("***~p:~p: ~p:~p",[?MODULE,?LINE,_C,_E]),
+ []
+ end}
+ end),
+
+ receive
+ {hostport,Srvr,{_Host,Port}} ->
+ spawn(fun()-> os:cmd(lists:concat(["ssh -o \"StrictHostKeyChecking no\" -p ",Port," localhost"])) end)
+ after ?TIMEOUT ->
+ ct:fail("No server respons 1")
+ end,
+
+ receive
+ {result,Srvr,L} ->
+ L
+ after ?TIMEOUT ->
+ ct:fail("No server respons 2")
+ end.
+
+run_fake_ssh({ok,InitialState}) ->
+ KexInitPattern =
+ #ssh_msg_kexinit{
+ kex_algorithms = '$kex_algorithms',
+ server_host_key_algorithms = '$server_host_key_algorithms',
+ encryption_algorithms_client_to_server = '$encryption_algorithms_client_to_server',
+ encryption_algorithms_server_to_client = '$encryption_algorithms_server_to_client',
+ mac_algorithms_client_to_server = '$mac_algorithms_client_to_server',
+ mac_algorithms_server_to_client = '$mac_algorithms_server_to_client',
+ compression_algorithms_client_to_server = '$compression_algorithms_client_to_server',
+ compression_algorithms_server_to_client = '$compression_algorithms_server_to_client',
+ _ = '_'
+ },
+ {ok,E} = ssh_trpt_test_lib:exec([{set_options,[silent]},
+ {send, hello},
+ receive_hello,
+ {send, ssh_msg_kexinit},
+ {match, KexInitPattern, receive_msg},
+ close_socket
+ ],
+ InitialState),
+ [Kex, PubKey, EncC2S, EncS2C, MacC2S, MacS2C, CompC2S, CompS2C] =
+ ssh_trpt_test_lib:instantiate(['$kex_algorithms',
+ '$server_host_key_algorithms',
+ '$encryption_algorithms_client_to_server',
+ '$encryption_algorithms_server_to_client',
+ '$mac_algorithms_client_to_server',
+ '$mac_algorithms_server_to_client',
+ '$compression_algorithms_client_to_server',
+ '$compression_algorithms_server_to_client'
+ ], E),
+ [{kex, to_atoms(Kex)},
+ {public_key, to_atoms(PubKey)},
+ {cipher, [{client2server, to_atoms(EncC2S)},
+ {server2client, to_atoms(EncS2C)}]},
+ {mac, [{client2server, to_atoms(MacC2S)},
+ {server2client, to_atoms(MacS2C)}]},
+ {compression, [{client2server, to_atoms(CompC2S)},
+ {server2client, to_atoms(CompS2C)}]}].
+
+
+%%%----------------------------------------------------------------
+extract_algos(Spec) ->
+ [{Tag,get_atoms(List)} || {Tag,List} <- Spec].
+
+get_atoms(L) ->
+ lists:usort(
+ [ A || X <- L,
+ A <- case X of
+ {_,L1} when is_list(L1) -> L1;
+ Y when is_atom(Y) -> [Y]
+ end]).
+
+
+intersection(AlgoSpec1, AlgoSpec2) -> intersect(sort_spec(AlgoSpec1), sort_spec(AlgoSpec2)).
+
+intersect([{Tag,S1}|Ss1], [{Tag,S2}|Ss2]) ->
+ [{Tag,intersect(S1,S2)} | intersect(Ss1,Ss2)];
+intersect(L1=[A1|_], L2=[A2|_]) when is_atom(A1),is_atom(A2) ->
+ Diff = L1 -- L2,
+ L1 -- Diff;
+intersect(_, _) ->
+ [].
+
+intersect_bi_dir([{Tag,[{client2server,L1},{server2client,L2}]}|T]) ->
+ [{Tag,intersect(L1,L2)} | intersect_bi_dir(T)];
+intersect_bi_dir([H={_,[A|_]}|T]) when is_atom(A) ->
+ [H | intersect_bi_dir(T)];
+intersect_bi_dir([]) ->
+ [].
+
+
+sort_spec(L = [{_,_}|_] ) -> [{Tag,sort_spec(Es)} || {Tag,Es} <- L];
+sort_spec(L) -> lists:usort(L).
+
+%%--------------------------------------------------------------------
+sshc(Tag) ->
+ to_atoms(
+ string:tokens(os:cmd(lists:concat(["ssh -Q ",Tag])), "\n")
+ ).
+
+ssh_type() ->
+ case os:find_executable("ssh") of
+ false -> not_found;
+ _ ->
+ case os:cmd("ssh -V") of
+ "OpenSSH" ++ _ ->
+ openSSH;
+ Str ->
+ ct:log("ssh client ~p is unknown",[Str]),
+ unknown
+ end
+ end.
+
+algo_intersection([], _) -> [];
+algo_intersection(_, []) -> [];
+algo_intersection(L1=[A1|_], L2=[A2|_]) when is_atom(A1), is_atom(A2) ->
+ true = lists:all(fun erlang:is_atom/1, L1++L2),
+ lists:foldr(fun(A,Acc) ->
+ case lists:member(A,L2) of
+ true -> [A|Acc];
+ false -> Acc
+ end
+ end, [], L1);
+algo_intersection([{K,V1}|T1], L2) ->
+ case lists:keysearch(K,1,L2) of
+ {value, {K,V2}} ->
+ [{K,algo_intersection(V1,V2)} | algo_intersection(T1,L2)];
+ false ->
+ algo_intersection(T1,L2)
+ end;
+algo_intersection(_, _) ->
+ [].
+
+
+to_atoms(L) -> lists:map(fun erlang:list_to_atom/1, L).
+
+%%%----------------------------------------------------------------
+ssh_supports(Alg, SshDefaultAlg_tag) ->
+ SupAlgs =
+ case proplists:get_value(SshDefaultAlg_tag,
+ ssh:default_algorithms()) of
+ [{_K1,L1}, {_K2,L2}] ->
+ lists:usort(L1++L2);
+ L ->
+ L
+ end,
+ if
+ is_atom(Alg) ->
+ lists:member(Alg, SupAlgs);
+ is_list(Alg) ->
+ case Alg--SupAlgs of
+ [] ->
+ true;
+ UnSup ->
+ {false,UnSup}
+ end
+ end.
+
+%%%----------------------------------------------------------------
+has_inet6_address() ->
+ try
+ [throw(6) || {ok,L} <- [inet:getifaddrs()],
+ {_,L1} <- L,
+ {addr,{_,_,_,_,_,_,_,_}} <- L1]
+ of
+ [] -> false
+ catch
+ throw:6 -> true
+ end.
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index af70eeb46c..2788bc6b58 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -32,6 +33,9 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{minutes,1}}].
+
all() ->
case os:find_executable("ssh") of
false ->
@@ -44,36 +48,26 @@ all() ->
groups() ->
[{erlang_client, [], [erlang_shell_client_openssh_server,
- erlang_client_openssh_server_exec,
erlang_client_openssh_server_exec_compressed,
erlang_client_openssh_server_setenv,
erlang_client_openssh_server_publickey_rsa,
erlang_client_openssh_server_publickey_dsa,
erlang_client_openssh_server_password,
+ erlang_client_openssh_server_kexs,
erlang_client_openssh_server_nonexistent_subsystem
]},
- {erlang_server, [], [erlang_server_openssh_client_exec,
- erlang_server_openssh_client_exec_compressed,
- erlang_server_openssh_client_pulic_key_dsa,
- erlang_server_openssh_client_cipher_suites,
- erlang_server_openssh_client_macs]}
+ {erlang_server, [], [erlang_server_openssh_client_public_key_dsa]}
].
init_per_suite(Config) ->
- case catch crypto:start() of
- ok ->
- case gen_tcp:connect("localhost", 22, []) of
- {error,econnrefused} ->
- {skip,"No openssh deamon"};
- _ ->
- Config
- end;
- _Else ->
- {skip,"Could not start crypto!"}
+ case gen_tcp:connect("localhost", 22, []) of
+ {error,econnrefused} ->
+ {skip,"No openssh deamon"};
+ _ ->
+ ssh_test_lib:openssh_sanity_check(Config)
end.
end_per_suite(_Config) ->
- crypto:stop(),
ok.
init_per_group(erlang_server, Config) ->
@@ -81,6 +75,11 @@ init_per_group(erlang_server, Config) ->
UserDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa_known_host(DataDir, UserDir),
Config;
+init_per_group(erlang_client, Config) ->
+ CommonAlgs = ssh_test_lib:algo_intersection(
+ ssh:default_algorithms(),
+ ssh_test_lib:default_algorithms(sshd)),
+ [{common_algs,CommonAlgs} | Config];
init_per_group(_, Config) ->
Config.
@@ -91,12 +90,11 @@ end_per_group(erlang_server, Config) ->
end_per_group(_, Config) ->
Config.
-init_per_testcase(erlang_server_openssh_client_cipher_suites, Config) ->
- check_ssh_client_support(Config);
-
-init_per_testcase(erlang_server_openssh_client_macs, Config) ->
- check_ssh_client_support(Config);
+init_per_testcase(erlang_server_openssh_client_public_key_dsa, Config) ->
+ chk_key(sshc, 'ssh-dss', ".ssh/id_dsa", Config);
+init_per_testcase(erlang_client_openssh_server_publickey_dsa, Config) ->
+ chk_key(sshd, 'ssh-dss', ".ssh/id_dsa", Config);
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -105,6 +103,27 @@ end_per_testcase(_TestCase, _Config) ->
ssh:stop(),
ok.
+
+chk_key(Pgm, Name, File, Config) ->
+ case ssh_test_lib:openssh_supports(Pgm, public_key, Name) of
+ false ->
+ {skip,lists:concat(["openssh client does not support ",Name])};
+ true ->
+ {ok,[[Home]]} = init:get_argument(home),
+ KeyFile = filename:join(Home, File),
+ case file:read_file(KeyFile) of
+ {ok, Pem} ->
+ case public_key:pem_decode(Pem) of
+ [{_,_, not_encrypted}] ->
+ init_per_testcase('__default__',Config);
+ _ ->
+ {skip, {error, "Has pass phrase can not be used by automated test case"}}
+ end;
+ _ ->
+ {skip, lists:concat(["no ~/",File])}
+ end
+ end.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -138,7 +157,7 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) ->
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0);
{unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}}
= ExitStatus0} ->
- ct:pal("0: Collected data ~p", [ExitStatus0]),
+ ct:log("0: Collected data ~p", [ExitStatus0]),
ssh_test_lib:receive_exec_result(Data0,
ConnectionRef, ChannelId0);
Other0 ->
@@ -154,7 +173,7 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) ->
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1);
{unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId1, 0}}
= ExitStatus1} ->
- ct:pal("0: Collected data ~p", [ExitStatus1]),
+ ct:log("0: Collected data ~p", [ExitStatus1]),
ssh_test_lib:receive_exec_result(Data1,
ConnectionRef, ChannelId1);
Other1 ->
@@ -166,184 +185,81 @@ erlang_client_openssh_server_exec_compressed() ->
[{doc, "Test that compression option works"}].
erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) ->
- ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
- {user_interaction, false},
- {compression, zlib}]),
- {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId,
- "echo testing", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
- {unexpected_msg,{ssh_cm, ConnectionRef,
- {exit_status, ChannelId, 0}} = ExitStatus} ->
- ct:pal("0: Collected data ~p", [ExitStatus]),
- ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId);
- Other ->
- ct:fail(Other)
+ CompressAlgs = [zlib, '[email protected]',none],
+ case ssh_test_lib:ssh_supports(CompressAlgs, compression) of
+ {false,L} ->
+ {skip, io_lib:format("~p compression is not supported",[L])};
+
+ true ->
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {preferred_algorithms,
+ [{compression,CompressAlgs}]}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId,
+ "echo testing", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
+ {unexpected_msg,{ssh_cm, ConnectionRef,
+ {exit_status, ChannelId, 0}} = ExitStatus} ->
+ ct:log("0: Collected data ~p", [ExitStatus]),
+ ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId);
+ Other ->
+ ct:fail(Other)
+ end
end.
%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec() ->
- [{doc, "Test that exec command works."}].
-
-erlang_server_openssh_client_exec(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " 1+1.",
-
- ct:pal("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
-
- end,
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_cipher_suites() ->
- [{doc, "Test that we can connect with different cipher suites."}].
-
-erlang_server_openssh_client_cipher_suites(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Supports = crypto:supports(),
- Ciphers = proplists:get_value(ciphers, Supports),
- Tests = [
- {"3des-cbc", lists:member(des3_cbc, Ciphers)},
- {"aes128-cbc", lists:member(aes_cbc128, Ciphers)},
- {"aes128-ctr", lists:member(aes_ctr, Ciphers)},
- {"aes256-cbc", false}
- ],
- lists:foreach(fun({Cipher, Expect}) ->
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " " ++
- " -c " ++ Cipher ++ " 1+1.",
-
- ct:pal("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- case Expect of
- true ->
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
- end;
- false ->
- receive
- {SshPort,{data, <<"no matching cipher found", _/binary>>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive no matching cipher message")
- end
- end
- end, Tests),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_macs() ->
- [{doc, "Test that we can connect with different MACs."}].
-
-erlang_server_openssh_client_macs(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Supports = crypto:supports(),
- Hashs = proplists:get_value(hashs, Supports),
- MACs = [{"hmac-sha1", lists:member(sha, Hashs)},
- {"hmac-sha2-256", lists:member(sha256, Hashs)},
- {"hmac-md5-96", false},
- {"hmac-ripemd160", false}],
- lists:foreach(fun({MAC, Expect}) ->
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " " ++
- " -o MACs=" ++ MAC ++ " 1+1.",
-
- ct:pal("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- case Expect of
- true ->
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
- end;
- false ->
- receive
- {SshPort,{data, <<"no matching mac found", _/binary>>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive no matching mac message")
- end
- end
- end, MACs),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec_compressed() ->
- [{doc, "Test that exec command works."}].
-
-erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {compression, zlib},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- ct:sleep(500),
-
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " -C "++ Host ++ " 1+1.",
- SshPort = open_port({spawn, Cmd}, [binary]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
-
- end,
- ssh:stop_daemon(Pid).
+erlang_client_openssh_server_kexs() ->
+ [{doc, "Test that we can connect with different KEXs."}].
+
+erlang_client_openssh_server_kexs(Config) when is_list(Config) ->
+ KexAlgos = try proplists:get_value(kex, ?config(common_algs,Config))
+ catch _:_ -> []
+ end,
+ comment(KexAlgos),
+ case KexAlgos of
+ [] -> {skip, "No common kex algorithms"};
+ _ ->
+ Success =
+ lists:foldl(
+ fun(Kex, Acc) ->
+ ConnectionRef =
+ ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {preferred_algorithms,
+ [{kex,[Kex]}]}]),
+
+ {ok, ChannelId} =
+ ssh_connection:session_channel(ConnectionRef, infinity),
+ success =
+ ssh_connection:exec(ConnectionRef, ChannelId,
+ "echo testing", infinity),
+
+ ExpectedData = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(ExpectedData) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ Acc;
+ {unexpected_msg,{ssh_cm, ConnectionRef,
+ {exit_status, ChannelId, 0}} = ExitStatus} ->
+ ct:log("0: Collected data ~p", [ExitStatus]),
+ ssh_test_lib:receive_exec_result(ExpectedData, ConnectionRef, ChannelId),
+ Acc;
+ Other ->
+ ct:log("~p failed: ~p",[Kex,Other]),
+ false
+ end
+ end, true, KexAlgos),
+ case Success of
+ true ->
+ ok;
+ false ->
+ {fail, "Kex failed for one or more algos"}
+ end
+ end.
%%--------------------------------------------------------------------
erlang_client_openssh_server_setenv() ->
@@ -373,11 +289,11 @@ erlang_client_openssh_server_setenv(Config) when is_list(Config) ->
{data,0,1, UnxpectedData}}} ->
%% Some os may return things as
%% ENV_TEST: Undefined variable.\n"
- ct:pal("UnxpectedData: ~p", [UnxpectedData]),
+ ct:log("UnxpectedData: ~p", [UnxpectedData]),
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
{unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}}
= ExitStatus} ->
- ct:pal("0: Collected data ~p", [ExitStatus]),
+ ct:log("0: Collected data ~p", [ExitStatus]),
ssh_test_lib:receive_exec_result(Data,
ConnectionRef, ChannelId);
Other ->
@@ -419,31 +335,20 @@ erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) ->
erlang_client_openssh_server_publickey_dsa() ->
[{doc, "Validate using dsa publickey."}].
erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) ->
- {ok,[[Home]]} = init:get_argument(home),
- KeyFile = filename:join(Home, ".ssh/id_dsa"),
- case file:read_file(KeyFile) of
- {ok, Pem} ->
- case public_key:pem_decode(Pem) of
- [{_,_, not_encrypted}] ->
- ConnectionRef =
- ssh_test_lib:connect(?SSH_DEFAULT_PORT,
- [{public_key_alg, ssh_dsa},
- {user_interaction, false},
- silently_accept_hosts]),
- {ok, Channel} =
- ssh_connection:session_channel(ConnectionRef, infinity),
- ok = ssh_connection:close(ConnectionRef, Channel),
- ok = ssh:close(ConnectionRef);
- _ ->
- {skip, {error, "Has pass phrase can not be used by automated test case"}}
- end;
- _ ->
- {skip, "no ~/.ssh/id_dsa"}
- end.
+ ConnectionRef =
+ ssh_test_lib:connect(?SSH_DEFAULT_PORT,
+ [{public_key_alg, ssh_dsa},
+ {user_interaction, false},
+ silently_accept_hosts]),
+ {ok, Channel} =
+ ssh_connection:session_channel(ConnectionRef, infinity),
+ ok = ssh_connection:close(ConnectionRef, Channel),
+ ok = ssh:close(ConnectionRef).
+
%%--------------------------------------------------------------------
-erlang_server_openssh_client_pulic_key_dsa() ->
+erlang_server_openssh_client_public_key_dsa() ->
[{doc, "Validate using dsa publickey."}].
-erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
+erlang_server_openssh_client_public_key_dsa(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
KnownHosts = filename:join(PrivDir, "known_hosts"),
@@ -451,21 +356,25 @@ erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{public_key_alg, ssh_dsa},
{failfun, fun ssh_test_lib:failfun/2}]),
-
+
ct:sleep(500),
Cmd = "ssh -p " ++ integer_to_list(Port) ++
" -o UserKnownHostsFile=" ++ KnownHosts ++
" " ++ Host ++ " 1+1.",
- SshPort = open_port({spawn, Cmd}, [binary]),
+ SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
receive
- {SshPort,{data, <<"2\n">>}} ->
+ {SshPort,{data, <<"2\n">>}} ->
ok
after ?TIMEOUT ->
- ct:fail("Did not receive answer")
+ receive
+ X -> ct:fail("Received: ~p",[X])
+ after 0 ->
+ ct:fail("Did not receive answer")
+ end
end,
- ssh:stop_daemon(Pid).
+ ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
erlang_client_openssh_server_password() ->
@@ -475,12 +384,12 @@ erlang_client_openssh_server_password(Config) when is_list(Config) ->
UserDir = ?config(data_dir, Config),
{error, Reason0} =
ssh:connect(any, ?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
- ct:pal("Test of user foo that does not exist. "
+ ct:log("Test of user foo that does not exist. "
"Error msg: ~p~n", [Reason0]),
User = string:strip(os:cmd("whoami"), right, $\n),
@@ -494,10 +403,10 @@ erlang_client_openssh_server_password(Config) when is_list(Config) ->
{password, "foo"},
{user_interaction, false},
{user_dir, UserDir}]),
- ct:pal("Test of wrong Pasword. "
+ ct:log("Test of wrong Pasword. "
"Error msg: ~p~n", [Reason1]);
_ ->
- ct:pal("Whoami failed reason: ~n", [])
+ ct:log("Whoami failed reason: ~n", [])
end.
%%--------------------------------------------------------------------
@@ -525,34 +434,41 @@ erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config)
receive_hej() ->
receive
<<"Hej", _binary>> = Hej ->
- ct:pal("Expected result: ~p~n", [Hej]);
+ ct:log("Expected result: ~p~n", [Hej]);
<<"Hej\n", _binary>> = Hej ->
- ct:pal("Expected result: ~p~n", [Hej]);
+ ct:log("Expected result: ~p~n", [Hej]);
<<"Hej\r\n", _/binary>> = Hej ->
- ct:pal("Expected result: ~p~n", [Hej]);
+ ct:log("Expected result: ~p~n", [Hej]);
Info ->
Lines = binary:split(Info, [<<"\r\n">>], [global]),
case lists:member(<<"Hej">>, Lines) of
true ->
- ct:pal("Expected result found in lines: ~p~n", [Lines]),
+ ct:log("Expected result found in lines: ~p~n", [Lines]),
ok;
false ->
- ct:pal("Extra info: ~p~n", [Info]),
+ ct:log("Extra info: ~p~n", [Info]),
receive_hej()
end
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
receive_logout() ->
receive
<<"logout">> ->
+ extra_logout(),
receive
<<"Connection closed">> ->
ok
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end;
Info ->
- ct:pal("Extra info when logging out: ~p~n", [Info]),
+ ct:log("Extra info when logging out: ~p~n", [Info]),
receive_logout()
- end.
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
receive_normal_exit(Shell) ->
receive
@@ -562,29 +478,30 @@ receive_normal_exit(Shell) ->
receive_normal_exit(Shell);
Other ->
ct:fail({unexpected_msg, Other})
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+extra_logout() ->
+ receive
+ <<"logout">> ->
+ ok
+ after 500 ->
+ ok
end.
-%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
%% Check if we have a "newer" ssh client that supports these test cases
-%%--------------------------------------------------------------------
check_ssh_client_support(Config) ->
- Port = open_port({spawn, "ssh -Q cipher"}, [exit_status, stderr_to_stdout]),
- case check_ssh_client_support2(Port) of
- 0 -> % exit status from command (0 == ok)
+ case ssh_test_lib:ssh_client_supports_Q() of
+ true ->
ssh:start(),
Config;
_ ->
{skip, "test case not supported by ssh client"}
end.
-check_ssh_client_support2(P) ->
- receive
- {P, {data, _A}} ->
- check_ssh_client_support2(P);
- {P, {exit_status, E}} ->
- E
- after 5000 ->
- ct:pal("Openssh command timed out ~n"),
- -1
- end.
+comment(AtomList) ->
+ ct:comment(
+ string:join(lists:map(fun erlang:atom_to_list/1, AtomList),
+ ", ")).
diff --git a/lib/ssh/test/ssh_trpt_test_lib.erl b/lib/ssh/test/ssh_trpt_test_lib.erl
new file mode 100644
index 0000000000..4269529ae8
--- /dev/null
+++ b/lib/ssh/test/ssh_trpt_test_lib.erl
@@ -0,0 +1,772 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssh_trpt_test_lib).
+
+%%-compile(export_all).
+
+-export([exec/1, exec/2,
+ instantiate/2,
+ format_msg/1,
+ server_host_port/1
+ ]
+ ).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh.hrl"). % ?UINT32, ?BYTE, #ssh{} ...
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_auth.hrl").
+
+%%%----------------------------------------------------------------
+-record(s, {
+ socket,
+ listen_socket,
+ opts = [],
+ timeout = 5000, % ms
+ seen_hello = false,
+ enc = <<>>,
+ ssh = #ssh{}, % #ssh{}
+ alg_neg = {undefined,undefined}, % {own_kexinit, peer_kexinit}
+ alg, % #alg{}
+ vars = dict:new(),
+ reply = [], % Some repy msgs are generated hidden in ssh_transport :[
+ prints = [],
+ return_value
+ }).
+
+-define(role(S), ((S#s.ssh)#ssh.role) ).
+
+
+server_host_port(S=#s{}) ->
+ {Host,Port} = ok(inet:sockname(S#s.listen_socket)),
+ {host(Host), Port}.
+
+
+%%% Options: {print_messages, false} true|detail
+%%% {print_seqnums,false} true
+%%% {print_ops,false} true
+
+exec(L) -> exec(L, #s{}).
+
+exec(L, S) when is_list(L) -> lists:foldl(fun exec/2, S, L);
+
+exec(Op, S0=#s{}) ->
+ S1 = init_op_traces(Op, S0),
+ try seqnum_trace(
+ op(Op, S1))
+ of
+ S = #s{} ->
+ case proplists:get_value(silent,S#s.opts) of
+ true -> ok;
+ _ -> print_traces(S)
+ end,
+ {ok,S}
+ catch
+ {fail,Reason,Se} ->
+ report_trace('', Reason, Se),
+ {error,{Op,Reason,Se}};
+
+ throw:Term ->
+ report_trace(throw, Term, S1),
+ throw(Term);
+
+ error:Error ->
+ report_trace(error, Error, S1),
+ error(Error);
+
+ exit:Exit ->
+ report_trace(exit, Exit, S1),
+ exit(Exit)
+ end;
+exec(Op, {ok,S=#s{}}) -> exec(Op, S);
+exec(_, Error) -> Error.
+
+
+%%%---- Server ops
+op(listen, S) when ?role(S) == undefined -> op({listen,0}, S);
+
+op({listen,Port}, S) when ?role(S) == undefined ->
+ S#s{listen_socket = ok(gen_tcp:listen(Port, mangle_opts([]))),
+ ssh = (S#s.ssh)#ssh{role=server}
+ };
+
+op({accept,Opts}, S) when ?role(S) == server ->
+ {ok,Socket} = gen_tcp:accept(S#s.listen_socket, S#s.timeout),
+ {Host,_Port} = ok(inet:sockname(Socket)),
+ S#s{socket = Socket,
+ ssh = init_ssh(server,Socket,[{host,host(Host)}|Opts]),
+ return_value = ok};
+
+%%%---- Client ops
+op({connect,Host,Port,Opts}, S) when ?role(S) == undefined ->
+ Socket = ok(gen_tcp:connect(host(Host), Port, mangle_opts([]))),
+ S#s{socket = Socket,
+ ssh = init_ssh(client, Socket, [{host,host(Host)}|Opts]),
+ return_value = ok};
+
+%%%---- ops for both client and server
+op(close_socket, S) ->
+ catch tcp_gen:close(S#s.socket),
+ catch tcp_gen:close(S#s.listen_socket),
+ S#s{socket = undefined,
+ listen_socket = undefined,
+ return_value = ok};
+
+op({set_options,Opts}, S) ->
+ S#s{opts = Opts};
+
+op({send,X}, S) ->
+ send(S, instantiate(X,S));
+
+op(receive_hello, S0) when S0#s.seen_hello =/= true ->
+ case recv(S0) of
+ S1=#s{return_value={hello,_}} -> S1;
+ S1=#s{} -> op(receive_hello, receive_wait(S1))
+ end;
+
+op(receive_msg, S) when S#s.seen_hello == true ->
+ try recv(S)
+ catch
+ {tcp,Exc} ->
+ S1 = opt(print_messages, S,
+ fun(X) when X==true;X==detail -> {"Recv~n~p~n",[Exc]} end),
+ S1#s{return_value=Exc}
+ end;
+
+
+op({expect,timeout,E}, S0) ->
+ try op(E, S0)
+ of
+ S=#s{} -> fail({expected,timeout,S#s.return_value}, S)
+ catch
+ {receive_timeout,_} -> S0#s{return_value=timeout}
+ end;
+
+op({match,M,E}, S0) ->
+ {Val,S2} = op_val(E, S0),
+ case match(M, Val, S2) of
+ {true,S3} ->
+ opt(print_ops,S3,
+ fun(true) ->
+ case dict:fold(
+ fun(K,V,Acc) ->
+ case dict:find(K,S0#s.vars) of
+ error -> [{K,V}|Acc];
+ _ -> Acc
+ end
+ end, [], S3#s.vars)
+ of
+ [] -> {"Matches! No new bindings.",[]};
+ New ->
+ Width = lists:max([length(atom_to_list(K)) || {K,_} <- New]),
+ {lists:flatten(
+ ["Matches! New bindings:~n" |
+ [io_lib:format(" ~*s = ~p~n",[Width,K,V]) || {K,V}<-New]]),
+ []}
+ end
+ end);
+ false ->
+ fail({expected,M,Val},
+ opt(print_ops,S2,fun(true) -> {"nomatch!!~n",[]} end)
+ )
+ end;
+
+op({print,E}, S0) ->
+ {Val,S} = op_val(E, S0),
+ io:format("Result of ~p ~p =~n~s~n",[?role(S0),E,format_msg(Val)]),
+ S;
+
+op(print_state, S) ->
+ io:format("State(~p)=~n~s~n",[?role(S), format_msg(S)]),
+ S;
+
+op('$$', S) ->
+ %% For matching etc
+ S.
+
+
+op_val(E, S0) ->
+ case catch op(E, S0) of
+ {'EXIT',{function_clause,[{ssh_trpt_test_lib,op,[E,S0],_}|_]}} ->
+ {instantiate(E,S0), S0};
+ S=#s{} ->
+ {S#s.return_value, S};
+ F={fail,receive_timeout,_St} ->
+ throw(F)
+ end.
+
+
+fail(Reason, {Fmt,Args}, S) when is_list(Fmt), is_list(Args) ->
+ fail(Reason, save_prints({Fmt,Args}, S)).
+
+fail(Reason, S) ->
+ throw({fail, Reason, S}).
+
+%%%----------------------------------------------------------------
+%% No optimizations :)
+
+match('$$', V, S) ->
+ match(S#s.return_value, V, S);
+
+match('_', _, S) ->
+ {true, S};
+
+match({'or',[P]}, V, S) -> match(P,V,S);
+match({'or',[Ph|Pt]}, V, S) ->
+ case match(Ph,V,S) of
+ false -> match({'or',Pt}, V, S);
+ {true,S} -> {true,S}
+ end;
+
+match(P, V, S) when is_atom(P) ->
+ case atom_to_list(P) of
+ "$"++_ ->
+ %% Variable
+ case dict:find(P,S#s.vars) of
+ {ok,Val} -> match(Val, V, S);
+ error -> {true,S#s{vars = dict:store(P,V,S#s.vars)}}
+ end;
+ _ when P==V ->
+ {true,S};
+ _ ->
+ false
+ end;
+
+match(P, V, S) when P==V ->
+ {true, S};
+
+match(P, V, S) when is_tuple(P),
+ is_tuple(V) ->
+ match(tuple_to_list(P), tuple_to_list(V), S);
+
+match([Hp|Tp], [Hv|Tv], S0) ->
+ case match(Hp, Hv, S0) of
+ {true,S} -> match(Tp, Tv, S);
+ false -> false
+ end;
+
+match(_, _, _) ->
+ false.
+
+
+
+instantiate('$$', S) ->
+ S#s.return_value; % FIXME: What if $$ or $... in return_value?
+
+instantiate(A, S) when is_atom(A) ->
+ case atom_to_list(A) of
+ "$"++_ ->
+ %% Variable
+ case dict:find(A,S#s.vars) of
+ {ok,Val} -> Val; % FIXME: What if $$ or $... in Val?
+ error -> throw({unbound,A})
+ end;
+ _ ->
+ A
+ end;
+
+instantiate(T, S) when is_tuple(T) ->
+ list_to_tuple( instantiate(tuple_to_list(T),S) );
+
+instantiate([H|T], S) ->
+ [instantiate(H,S) | instantiate(T,S)];
+
+instantiate(X, _S) ->
+ X.
+
+%%%================================================================
+%%%
+init_ssh(Role, Socket, Options0) ->
+ Options = [{user_interaction,false}
+ | Options0],
+ ssh_connection_handler:init_ssh(Role,
+ {2,0},
+ lists:concat(["SSH-2.0-ErlangTestLib ",Role]),
+ Options, Socket).
+
+mangle_opts(Options) ->
+ SysOpts = [{reuseaddr, true},
+ {active, false},
+ {mode, binary}
+ ],
+ SysOpts ++ lists:foldl(fun({K,_},Opts) ->
+ lists:keydelete(K,1,Opts)
+ end, Options, SysOpts).
+
+host({0,0,0,0}) -> "localhost";
+host(H) -> H.
+
+%%%----------------------------------------------------------------
+send(S=#s{ssh=C}, hello) ->
+ Hello = case ?role(S) of
+ client -> C#ssh.c_version;
+ server -> C#ssh.s_version
+ end ++ "\r\n",
+ send(S, list_to_binary(Hello));
+
+send(S0, ssh_msg_kexinit) ->
+ {Msg, _Bytes, _C0} = ssh_transport:key_exchange_init_msg(S0#s.ssh),
+ send(S0, Msg);
+
+send(S0=#s{alg_neg={undefined,PeerMsg}}, Msg=#ssh_msg_kexinit{}) ->
+ S1 = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ S2 = case PeerMsg of
+ #ssh_msg_kexinit{} ->
+ try ssh_transport:handle_kexinit_msg(PeerMsg, Msg, S1#s.ssh) of
+ {ok,Cx} when ?role(S1) == server ->
+ S1#s{alg = Cx#ssh.algorithms};
+ {ok,_NextKexMsgBin,Cx} when ?role(S1) == client ->
+ S1#s{alg = Cx#ssh.algorithms}
+ catch
+ Class:Exc ->
+ save_prints({"Algoritm negotiation failed at line ~p:~p~n~p:~s~nPeer: ~s~n Own: ~s~n",
+ [?MODULE,?LINE,Class,format_msg(Exc),format_msg(PeerMsg),format_msg(Msg)]},
+ S1)
+ end;
+ undefined ->
+ S1
+ end,
+ {Bytes, C} = ssh_transport:ssh_packet(Msg, S2#s.ssh),
+ send_bytes(Bytes, S2#s{return_value = Msg,
+ alg_neg = {Msg,PeerMsg},
+ ssh = C});
+
+send(S0, ssh_msg_kexdh_init) when ?role(S0) == client ->
+ {OwnMsg, PeerMsg} = S0#s.alg_neg,
+ {ok, NextKexMsgBin, C} =
+ try ssh_transport:handle_kexinit_msg(PeerMsg, OwnMsg, S0#s.ssh)
+ catch
+ Class:Exc ->
+ fail("Algoritm negotiation failed!",
+ {"Algoritm negotiation failed at line ~p:~p~n~p:~s~nPeer: ~s~n Own: ~s",
+ [?MODULE,?LINE,Class,format_msg(Exc),format_msg(PeerMsg),format_msg(OwnMsg)]},
+ S0)
+ end,
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail ->
+ #ssh{keyex_key = {{_Private, Public}, {_G, _P}}} = C,
+ Msg = #ssh_msg_kexdh_init{e = Public},
+ {"Send (reconstructed)~n~s~n",[format_msg(Msg)]}
+ end),
+ send_bytes(NextKexMsgBin, S#s{ssh = C});
+
+send(S0, ssh_msg_kexdh_reply) ->
+ Bytes = proplists:get_value(ssh_msg_kexdh_reply, S0#s.reply),
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail ->
+ {{_Private, Public}, _} = (S0#s.ssh)#ssh.keyex_key,
+ Msg = #ssh_msg_kexdh_reply{public_host_key = 'Key',
+ f = Public,
+ h_sig = 'H_SIG'
+ },
+ {"Send (reconstructed)~n~s~n",[format_msg(Msg)]}
+ end),
+ send_bytes(Bytes, S#s{return_value = Bytes});
+
+send(S0, Line) when is_binary(Line) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send line~n~p~n",[Line]} end),
+ send_bytes(Line, S#s{return_value = Line});
+
+send(S0, {special,Msg,PacketFun}) when is_tuple(Msg),
+ is_function(PacketFun,2) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ {Packet, C} = PacketFun(Msg, S#s.ssh),
+ send_bytes(Packet, S#s{ssh = C, %%inc_send_seq_num(C),
+ return_value = Msg});
+
+send(S0, Msg) when is_tuple(Msg) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ {Packet, C} = ssh_transport:ssh_packet(Msg, S#s.ssh),
+ send_bytes(Packet, S#s{ssh = C, %%inc_send_seq_num(C),
+ return_value = Msg}).
+
+send_bytes(B, S0) ->
+ S = opt(print_messages, S0, fun(detail) -> {"Send bytes~n~p~n",[B]} end),
+ ok(gen_tcp:send(S#s.socket, B)),
+ S.
+
+%%%----------------------------------------------------------------
+recv(S0 = #s{}) ->
+ S1 = receive_poll(S0),
+ case S1#s.seen_hello of
+ {more,Seen} ->
+ %% Has received parts of a line. Has not seen a complete hello.
+ try_find_crlf(Seen, S1);
+ false ->
+ %% Must see hello before binary messages
+ try_find_crlf(<<>>, S1);
+ true ->
+ %% Has seen hello, therefore no more crlf-messages are alowed.
+ S = receive_binary_msg(S1),
+ case PeerMsg = S#s.return_value of
+ #ssh_msg_kexinit{} ->
+ case S#s.alg_neg of
+ {undefined,undefined} ->
+ S#s{alg_neg = {undefined,PeerMsg}};
+
+ {undefined,_} ->
+ fail("2 kexint received!!", S);
+
+ {OwnMsg, _} ->
+ try ssh_transport:handle_kexinit_msg(PeerMsg, OwnMsg, S#s.ssh) of
+ {ok,C} when ?role(S) == server ->
+ S#s{alg_neg = {OwnMsg, PeerMsg},
+ alg = C#ssh.algorithms,
+ ssh = C};
+ {ok,_NextKexMsgBin,C} when ?role(S) == client ->
+ S#s{alg_neg = {OwnMsg, PeerMsg},
+ alg = C#ssh.algorithms}
+ catch
+ Class:Exc ->
+ save_prints({"Algoritm negotiation failed at line ~p:~p~n~p:~s~nPeer: ~s~n Own: ~s~n",
+ [?MODULE,?LINE,Class,format_msg(Exc),format_msg(PeerMsg),format_msg(OwnMsg)]},
+ S#s{alg_neg = {OwnMsg, PeerMsg}})
+ end
+ end;
+
+ #ssh_msg_kexdh_init{} -> % Always the server
+ {ok, Reply, C} = ssh_transport:handle_kexdh_init(PeerMsg, S#s.ssh),
+ S#s{ssh = C,
+ reply = [{ssh_msg_kexdh_reply,Reply} | S#s.reply]
+ };
+ #ssh_msg_kexdh_reply{} ->
+ {ok, _NewKeys, C} = ssh_transport:handle_kexdh_reply(PeerMsg, S#s.ssh),
+ S#s{ssh=C#ssh{send_sequence=S#s.ssh#ssh.send_sequence}}; % Back the number
+ #ssh_msg_newkeys{} ->
+ {ok, C} = ssh_transport:handle_new_keys(PeerMsg, S#s.ssh),
+ S#s{ssh=C};
+ _ ->
+ S
+ end
+ end.
+
+%%%================================================================
+try_find_crlf(Seen, S0) ->
+ case erlang:decode_packet(line,S0#s.enc,[]) of
+ {more,_} ->
+ Line = <<Seen/binary,(S0#s.enc)/binary>>,
+ S0#s{seen_hello = {more,Line},
+ enc = <<>>, % didn't find a complete line
+ % -> no more characters to test
+ return_value = {more,Line}
+ };
+ {ok,Used,Rest} ->
+ Line = <<Seen/binary,Used/binary>>,
+ case handle_hello(Line, S0) of
+ false ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Recv info~n~p~n",[Line]} end),
+ S#s{seen_hello = false,
+ enc = Rest,
+ return_value = {info,Line}};
+ S1=#s{} ->
+ S = opt(print_messages, S1,
+ fun(X) when X==true;X==detail -> {"Recv hello~n~p~n",[Line]} end),
+ S#s{seen_hello = true,
+ enc = Rest,
+ return_value = {hello,Line}}
+ end
+ end.
+
+
+handle_hello(Bin, S=#s{ssh=C}) ->
+ case {ssh_transport:handle_hello_version(binary_to_list(Bin)),
+ ?role(S)}
+ of
+ {{undefined,_}, _} -> false;
+ {{Vp,Vs}, client} -> S#s{ssh = C#ssh{s_vsn=Vp, s_version=Vs}};
+ {{Vp,Vs}, server} -> S#s{ssh = C#ssh{c_vsn=Vp, c_version=Vs}}
+ end.
+
+receive_binary_msg(S0=#s{ssh=C0=#ssh{decrypt_block_size = BlockSize,
+ recv_mac_size = MacSize
+ }
+ }) ->
+ case size(S0#s.enc) >= max(8,BlockSize) of
+ false ->
+ %% Need more bytes to decode the packet_length field
+ Remaining = max(8,BlockSize) - size(S0#s.enc),
+ receive_binary_msg( receive_wait(Remaining, S0) );
+ true ->
+ %% Has enough bytes to decode the packet_length field
+ {_, <<?UINT32(PacketLen), _/binary>>, _} =
+ ssh_transport:decrypt_blocks(S0#s.enc, BlockSize, C0), % FIXME: BlockSize should be at least 4
+
+ %% FIXME: Check that ((4+PacketLen) rem BlockSize) == 0 ?
+
+ S1 = if
+ PacketLen > ?SSH_MAX_PACKET_SIZE ->
+ fail({too_large_message,PacketLen},S0); % FIXME: disconnect
+
+ ((4+PacketLen) rem BlockSize) =/= 0 ->
+ fail(bad_packet_length_modulo, S0); % FIXME: disconnect
+
+ size(S0#s.enc) >= (4 + PacketLen + MacSize) ->
+ %% has the whole packet
+ S0;
+
+ true ->
+ %% need more bytes to get have the whole packet
+ Remaining = (4 + PacketLen + MacSize) - size(S0#s.enc),
+ receive_wait(Remaining, S0)
+ end,
+
+ %% Decrypt all, including the packet_length part (re-use the initial #ssh{})
+ {C1, SshPacket = <<?UINT32(_),?BYTE(PadLen),Tail/binary>>, EncRest} =
+ ssh_transport:decrypt_blocks(S1#s.enc, PacketLen+4, C0),
+
+ PayloadLen = PacketLen - 1 - PadLen,
+ <<CompressedPayload:PayloadLen/binary, _Padding:PadLen/binary>> = Tail,
+
+ {C2, Payload} = ssh_transport:decompress(C1, CompressedPayload),
+
+ <<Mac:MacSize/binary, Rest/binary>> = EncRest,
+
+ case {ssh_transport:is_valid_mac(Mac, SshPacket, C2),
+ catch ssh_message:decode(set_prefix_if_trouble(Payload,S1))}
+ of
+ {false, _} -> fail(bad_mac,S1);
+ {_, {'EXIT',_}} -> fail(decode_failed,S1);
+
+ {true, Msg} ->
+ C3 = case Msg of
+ #ssh_msg_kexinit{} ->
+ ssh_transport:key_init(opposite_role(C2), C2, Payload);
+ _ ->
+ C2
+ end,
+ S2 = opt(print_messages, S1,
+ fun(X) when X==true;X==detail -> {"Recv~n~s~n",[format_msg(Msg)]} end),
+ S3 = opt(print_messages, S2,
+ fun(detail) -> {"decrypted bytes ~p~n",[SshPacket]} end),
+ S3#s{ssh = inc_recv_seq_num(C3),
+ enc = Rest,
+ return_value = Msg
+ }
+ end
+ end.
+
+
+set_prefix_if_trouble(Msg = <<?BYTE(Op),_/binary>>, #s{alg=#alg{kex=Kex}})
+ when Op == 30;
+ Op == 31
+ ->
+ case catch atom_to_list(Kex) of
+ "ecdh-sha2-" ++ _ ->
+ <<"ecdh",Msg/binary>>;
+ "diffie-hellman-group-exchange-" ++ _ ->
+ <<"dh_gex",Msg/binary>>;
+ "diffie-hellman-group" ++ _ ->
+ <<"dh",Msg/binary>>;
+ _ ->
+ Msg
+ end;
+set_prefix_if_trouble(Msg, _) ->
+ Msg.
+
+
+receive_poll(S=#s{socket=Sock}) ->
+ inet:setopts(Sock, [{active,once}]),
+ receive
+ {tcp,Sock,Data} ->
+ receive_poll( S#s{enc = <<(S#s.enc)/binary,Data/binary>>} );
+ {tcp_closed,Sock} ->
+ throw({tcp,tcp_closed});
+ {tcp_error, Sock, Reason} ->
+ throw({tcp,{tcp_error,Reason}})
+ after 0 ->
+ S
+ end.
+
+receive_wait(S=#s{socket=Sock,
+ timeout=Timeout}) ->
+ inet:setopts(Sock, [{active,once}]),
+ receive
+ {tcp,Sock,Data} ->
+ S#s{enc = <<(S#s.enc)/binary,Data/binary>>};
+ {tcp_closed,Sock} ->
+ throw({tcp,tcp_closed});
+ {tcp_error, Sock, Reason} ->
+ throw({tcp,{tcp_error,Reason}})
+ after Timeout ->
+ fail(receive_timeout,S)
+ end.
+
+receive_wait(N, S=#s{socket=Sock,
+ timeout=Timeout,
+ enc=Enc0}) when N>0 ->
+ inet:setopts(Sock, [{active,once}]),
+ receive
+ {tcp,Sock,Data} ->
+ receive_wait(N-size(Data), S#s{enc = <<Enc0/binary,Data/binary>>});
+ {tcp_closed,Sock} ->
+ throw({tcp,tcp_closed});
+ {tcp_error, Sock, Reason} ->
+ throw({tcp,{tcp_error,Reason}})
+ after Timeout ->
+ fail(receive_timeout, S)
+ end;
+receive_wait(_N, S) ->
+ S.
+
+%% random_padding_len(PaddingLen1, ChunkSize) ->
+%% MaxAdditionalRandomPaddingLen = % max 255 bytes padding totaö
+%% (255 - PaddingLen1) - ((255 - PaddingLen1) rem ChunkSize),
+%% AddLen0 = crypto:rand_uniform(0,MaxAdditionalRandomPaddingLen),
+%% AddLen0 - (AddLen0 rem ChunkSize). % preserve the blocking
+
+inc_recv_seq_num(C=#ssh{recv_sequence=N}) -> C#ssh{recv_sequence=(N+1) band 16#ffffffff}.
+%%%inc_send_seq_num(C=#ssh{send_sequence=N}) -> C#ssh{send_sequence=(N+1) band 16#ffffffff}.
+
+opposite_role(#ssh{role=R}) -> opposite_role(R);
+opposite_role(client) -> server;
+opposite_role(server) -> client.
+
+ok(ok) -> ok;
+ok({ok,R}) -> R;
+ok({error,E}) -> erlang:error(E).
+
+
+%%%================================================================
+%%%
+%%% Formating of records
+%%%
+
+format_msg(M) -> format_msg(M, 0).
+
+format_msg(M, I0) ->
+ case fields(M) of
+ undefined -> io_lib:format('~p',[M]);
+ Fields ->
+ [Name|Args] = tuple_to_list(M),
+ Head = io_lib:format('#~p{',[Name]),
+ I = lists:flatlength(Head)+I0,
+ NL = io_lib:format('~n~*c',[I,$ ]),
+ Sep = io_lib:format(',~n~*c',[I,$ ]),
+ Tail = [begin
+ S0 = io_lib:format('~p = ',[F]),
+ I1 = I + lists:flatlength(S0),
+ [S0,format_msg(A,I1)]
+ end
+ || {F,A} <- lists:zip(Fields,Args)],
+ [[Head|string:join(Tail,Sep)],NL,"}"]
+ end.
+
+fields(M) ->
+ case M of
+ #ssh_msg_debug{} -> record_info(fields, ssh_msg_debug);
+ #ssh_msg_disconnect{} -> record_info(fields, ssh_msg_disconnect);
+ #ssh_msg_ignore{} -> record_info(fields, ssh_msg_ignore);
+ #ssh_msg_kex_dh_gex_group{} -> record_info(fields, ssh_msg_kex_dh_gex_group);
+ #ssh_msg_kex_dh_gex_init{} -> record_info(fields, ssh_msg_kex_dh_gex_init);
+ #ssh_msg_kex_dh_gex_reply{} -> record_info(fields, ssh_msg_kex_dh_gex_reply);
+ #ssh_msg_kex_dh_gex_request{} -> record_info(fields, ssh_msg_kex_dh_gex_request);
+ #ssh_msg_kex_dh_gex_request_old{} -> record_info(fields, ssh_msg_kex_dh_gex_request_old);
+ #ssh_msg_kexdh_init{} -> record_info(fields, ssh_msg_kexdh_init);
+ #ssh_msg_kexdh_reply{} -> record_info(fields, ssh_msg_kexdh_reply);
+ #ssh_msg_kexinit{} -> record_info(fields, ssh_msg_kexinit);
+ #ssh_msg_newkeys{} -> record_info(fields, ssh_msg_newkeys);
+ #ssh_msg_service_accept{} -> record_info(fields, ssh_msg_service_accept);
+ #ssh_msg_service_request{} -> record_info(fields, ssh_msg_service_request);
+ #ssh_msg_unimplemented{} -> record_info(fields, ssh_msg_unimplemented);
+ #ssh_msg_userauth_request{} -> record_info(fields, ssh_msg_userauth_request);
+ #ssh_msg_userauth_failure{} -> record_info(fields, ssh_msg_userauth_failure);
+ #ssh_msg_userauth_success{} -> record_info(fields, ssh_msg_userauth_success);
+ #ssh_msg_userauth_banner{} -> record_info(fields, ssh_msg_userauth_banner);
+ #ssh_msg_userauth_passwd_changereq{} -> record_info(fields, ssh_msg_userauth_passwd_changereq);
+ #ssh_msg_userauth_pk_ok{} -> record_info(fields, ssh_msg_userauth_pk_ok);
+ #ssh_msg_userauth_info_request{} -> record_info(fields, ssh_msg_userauth_info_request);
+ #ssh_msg_userauth_info_response{} -> record_info(fields, ssh_msg_userauth_info_response);
+ #s{} -> record_info(fields, s);
+ #ssh{} -> record_info(fields, ssh);
+ #alg{} -> record_info(fields, alg);
+ _ -> undefined
+ end.
+
+%%%================================================================
+%%%
+%%% Trace handling
+%%%
+
+init_op_traces(Op, S0) ->
+ opt(print_ops, S0#s{prints=[]},
+ fun(true) ->
+ case ?role(S0) of
+ undefined -> {"-- ~p~n",[Op]};
+ Role -> {"-- ~p ~p~n",[Role,Op]}
+ end
+ end
+ ).
+
+report_trace(Class, Term, S) ->
+ print_traces(
+ opt(print_ops, S,
+ fun(true) -> {"~s ~p",[Class,Term]} end)
+ ).
+
+seqnum_trace(S) ->
+ opt(print_seqnums, S,
+ fun(true) when S#s.ssh#ssh.send_sequence =/= S#s.ssh#ssh.send_sequence,
+ S#s.ssh#ssh.recv_sequence =/= S#s.ssh#ssh.recv_sequence ->
+ {"~p seq num: send ~p->~p, recv ~p->~p~n",
+ [?role(S),
+ S#s.ssh#ssh.send_sequence, S#s.ssh#ssh.send_sequence,
+ S#s.ssh#ssh.recv_sequence, S#s.ssh#ssh.recv_sequence
+ ]};
+ (true) when S#s.ssh#ssh.send_sequence =/= S#s.ssh#ssh.send_sequence ->
+ {"~p seq num: send ~p->~p~n",
+ [?role(S),
+ S#s.ssh#ssh.send_sequence, S#s.ssh#ssh.send_sequence]};
+ (true) when S#s.ssh#ssh.recv_sequence =/= S#s.ssh#ssh.recv_sequence ->
+ {"~p seq num: recv ~p->~p~n",
+ [?role(S),
+ S#s.ssh#ssh.recv_sequence, S#s.ssh#ssh.recv_sequence]}
+ end).
+
+print_traces(S) when S#s.prints == [] -> S;
+print_traces(S) ->
+ Len = length(S#s.prints),
+ ct:log("~s",
+ [lists:foldl(
+ fun({Fmt,Args}, Acc) ->
+ [case Len-length(Acc)-1 of
+ 0 ->
+ io_lib:format(Fmt,Args);
+ _N ->
+ io_lib:format(lists:concat(['~p --------~n',Fmt]),
+ [Len-length(Acc)-1|Args])
+ end | Acc]
+ end, "", S#s.prints)]
+ ).
+
+opt(Flag, S, Fun) when is_function(Fun,1) ->
+ try Fun(proplists:get_value(Flag,S#s.opts))
+ of P={Fmt,Args} when is_list(Fmt), is_list(Args) ->
+ save_prints(P, S)
+ catch _:_ ->
+ S
+ end.
+
+save_prints({Fmt,Args}, S) ->
+ S#s{prints = [{Fmt,Args}|S#s.prints]}.
diff --git a/lib/ssh/test/ssh_unicode_SUITE.erl b/lib/ssh/test/ssh_unicode_SUITE.erl
deleted file mode 100644
index cc916673b3..0000000000
--- a/lib/ssh/test/ssh_unicode_SUITE.erl
+++ /dev/null
@@ -1,587 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%% gerl +fnu
-%% ct:run_test([{suite,"ssh_unicode_SUITE"}, {logdir,"LOG"}]).
-
--module(ssh_unicode_SUITE).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
--include_lib("kernel/include/file.hrl").
-
-% Default timetrap timeout
--define(default_timeout, ?t:minutes(1)).
-
--define(USER, "åke高兴").
--define(PASSWD, "ärlig日本じん").
--define('sftp.txt', "sftp瑞点.txt").
--define('test.txt', "testハンス.txt").
--define('link_test.txt', "link_test語.txt").
-
--define(bindata, unicode:characters_to_binary("foobar å 一二三四いちにさんち") ).
-
--define(NEWLINE, <<"\r\n">>).
-
-%%--------------------------------------------------------------------
-%% Common Test interface functions -----------------------------------
-%%--------------------------------------------------------------------
-
-%% suite() ->
-%% [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [{group, sftp},
- {group, shell}
- ].
-
-
-init_per_suite(Config) ->
- case {file:native_name_encoding(), (catch crypto:start())} of
- {utf8, ok} ->
- ssh:start(),
- Config;
- {utf8, _} ->
- {skip,"Could not start crypto!"};
- _ ->
- {skip,"Not unicode filename enabled emulator"}
- end.
-
-end_per_suite(Config) ->
- ssh:stop(),
- crypto:stop(),
- Config.
-
-%%--------------------------------------------------------------------
-groups() ->
- [{shell, [], [shell_no_unicode, shell_unicode_string]},
- {sftp, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, rename_file, mk_rm_dir, remove_file, links,
- retrieve_attributes, set_attributes, async_read, async_read_bin,
- async_write
- %% , position, pos_read, pos_write
- ]}].
-
-init_per_group(Group, Config) when Group==sftp
- ; Group==shell ->
- PrivDir = ?config(priv_dir, Config),
- SysDir = ?config(data_dir, Config),
- Sftpd =
- ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, PrivDir},
- {user_passwords, [{?USER, ?PASSWD}]}]),
- [{group,Group}, {sftpd, Sftpd} | Config];
-
-init_per_group(Group, Config) ->
- [{group,Group} | Config].
-
-
-end_per_group(erlang_server, Config) ->
- Config;
-end_per_group(_, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-init_per_testcase(_Case, Config) ->
- prep(Config),
- TmpConfig0 = lists:keydelete(watchdog, 1, Config),
- TmpConfig = lists:keydelete(sftp, 1, TmpConfig0),
- Dog = ct:timetrap(?default_timeout),
-
- case ?config(group, Config) of
- sftp ->
- {_Pid, Host, Port} = ?config(sftpd, Config),
- {ok, ChannelPid, Connection} =
- ssh_sftp:start_channel(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
- {user_interaction, false},
- {silently_accept_hosts, true}]),
- Sftp = {ChannelPid, Connection},
- [{sftp, Sftp}, {watchdog, Dog} | TmpConfig];
- shell ->
- UserDir = ?config(priv_dir, Config),
- process_flag(trap_exit, true),
- {_Pid, _Host, Port} = ?config(sftpd, Config),
- ct:sleep(500),
- IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
- [{silently_accept_hosts, true},
- {user,?USER},{password,?PASSWD}]),
-%%ct:pal("IO=~p, Shell=~p, self()=~p",[IO,Shell,self()]),
- wait_for_erlang_first_line([{io,IO}, {shell,Shell} | Config])
- end.
-
-
-wait_for_erlang_first_line(Config) ->
- receive
- {'EXIT', _, _} ->
- {fail,no_ssh_connection};
- <<"Eshell ",_/binary>> = ErlShellStart ->
-%% ct:pal("Erlang shell start: ~p~n", [ErlShellStart]),
- Config;
- Other ->
- ct:pal("Unexpected answer from ssh server: ~p",[Other]),
- {fail,unexpected_answer}
- after 10000 ->
- ct:pal("No answer from ssh-server"),
- {fail,timeout}
- end.
-
-
-
-end_per_testcase(rename_file, Config) ->
- PrivDir = ?config(priv_dir, Config),
- NewFileName = filename:join(PrivDir, ?'test.txt'),
- file:delete(NewFileName),
- end_per_testcase(Config);
-end_per_testcase(_TC, Config) ->
- end_per_testcase(Config).
-
-end_per_testcase(Config) ->
- catch exit(?config(shell,Config), kill),
- case ?config(sftp, Config) of
- {Sftp, Connection} ->
- ssh_sftp:stop_channel(Sftp),
- ssh:close(Connection);
- _ ->
- ok
- end.
-
-%%--------------------------------------------------------------------
-%% Test Cases --------------------------------------------------------
-
--define(chk_expected(Received,Expected),
- (fun(R_,E_) when R_==E_ -> ok;
- (R_,E_) -> ct:pal("Expected: ~p~nReceived: ~p~n", [E_,R_]),
- E_ = R_
- end)(Received,Expected)).
-
--define(receive_chk(Ref,Expected),
- (fun(E__) ->
- receive
- {async_reply, Ref, Received} when Received==E__ ->
- ?chk_expected(Received, E__);
- {async_reply, Ref, Received} when Received=/=E__ ->
- ct:pal("Expected: ~p~nReceived: ~p~n", [E__,Received]),
- E__ = Received;
- Msg ->
- ct:pal("Expected (Ref=~p): ~p", [Ref,E__]),
- ct:fail(Msg)
- end
- end)(Expected)).
-
-%%--------------------------------------------------------------------
-
-
-open_close_file() ->
- [{doc, "Test API functions open/3 and close/2"}].
-open_close_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- lists:foreach(
- fun(Mode) ->
- ct:log("Mode: ~p",[Mode]),
- %% list_dir(PrivDir),
- ok = open_close_file(Sftp, FileName, Mode)
- end,
- [
- [read],
- [write],
- [write, creat],
- [write, trunc],
- [append],
- [read, binary]
- ]).
-
-open_close_file(Server, File, Mode) ->
- {ok, Handle} = ssh_sftp:open(Server, File, Mode),
- ok = ssh_sftp:close(Server, Handle).
-
-%%--------------------------------------------------------------------
-open_close_dir() ->
- [{doc, "Test API functions opendir/2 and close/2"}].
-open_close_dir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- {Sftp, _} = ?config(sftp, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
-
- {ok, Handle} = ssh_sftp:opendir(Sftp, PrivDir),
- ok = ssh_sftp:close(Sftp, Handle),
- {error, _} = ssh_sftp:opendir(Sftp, FileName).
-
-%%--------------------------------------------------------------------
-read_file() ->
- [{doc, "Test API funtion read_file/2"}].
-read_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
- ?chk_expected(ssh_sftp:read_file(Sftp,FileName), file:read_file(FileName)).
-
-%%--------------------------------------------------------------------
-read_dir() ->
- [{doc,"Test API function list_dir/2"}].
-read_dir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- {Sftp, _} = ?config(sftp, Config),
- {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("sftp list dir: ~ts~n", [Files]).
-
-%%--------------------------------------------------------------------
-write_file() ->
- [{doc, "Test API function write_file/2"}].
-write_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
- ok = ssh_sftp:write_file(Sftp, FileName, [?bindata]),
- ?chk_expected(file:read_file(FileName), {ok,?bindata}).
-
-%%--------------------------------------------------------------------
-remove_file() ->
- [{doc,"Test API function delete/2"}].
-remove_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- true = lists:member(filename:basename(FileName), Files),
- ok = ssh_sftp:delete(Sftp, FileName),
- {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir),
- false = lists:member(filename:basename(FileName), NewFiles),
- {error, _} = ssh_sftp:delete(Sftp, FileName).
-%%--------------------------------------------------------------------
-rename_file() ->
- [{doc, "Test API function rename_file/2"}].
-rename_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- NewFileName = filename:join(PrivDir, ?'test.txt'),
-
- {Sftp, _} = ?config(sftp, Config),
- {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~ts~nFiles: ~ts~n", [FileName, [[$\n,$ ,F]||F<-Files] ]),
- true = lists:member(filename:basename(FileName), Files),
- false = lists:member(filename:basename(NewFileName), Files),
- ok = ssh_sftp:rename(Sftp, FileName, NewFileName),
- {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~ts, Files: ~ts~n", [FileName, [[$\n,F]||F<-NewFiles] ]),
-
- false = lists:member(filename:basename(FileName), NewFiles),
- true = lists:member(filename:basename(NewFileName), NewFiles).
-
-%%--------------------------------------------------------------------
-mk_rm_dir() ->
- [{doc,"Test API functions make_dir/2, del_dir/2"}].
-mk_rm_dir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- {Sftp, _} = ?config(sftp, Config),
-
- DirName = filename:join(PrivDir, "test"),
- ok = ssh_sftp:make_dir(Sftp, DirName),
- ok = ssh_sftp:del_dir(Sftp, DirName),
- NewDirName = filename:join(PrivDir, "foo/bar"),
- {error, _} = ssh_sftp:make_dir(Sftp, NewDirName),
- {error, _} = ssh_sftp:del_dir(Sftp, PrivDir).
-
-%%--------------------------------------------------------------------
-links() ->
- [{doc,"Tests API function make_symlink/3"}].
-links(Config) when is_list(Config) ->
- case os:type() of
- {win32, _} ->
- {skip, "Links are not fully supported by windows"};
- _ ->
- {Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- LinkFileName = filename:join(PrivDir, ?'link_test.txt'),
-
- ok = ssh_sftp:make_symlink(Sftp, LinkFileName, FileName),
- {ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName)
- end.
-
-%%--------------------------------------------------------------------
-retrieve_attributes() ->
- [{doc, "Test API function read_file_info/3"}].
-retrieve_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
-
- {Sftp, _} = ?config(sftp, Config),
- {ok, FileInfo} = ssh_sftp:read_file_info(Sftp, FileName),
- {ok, NewFileInfo} = file:read_file_info(FileName),
-
- %% TODO comparison. There are some differences now is that ok?
- ct:pal("SFTP: ~p~nFILE: ~p~n", [FileInfo, NewFileInfo]).
-
-%%--------------------------------------------------------------------
-set_attributes() ->
- [{doc,"Test API function write_file_info/3"}].
-set_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
-
- {Sftp, _} = ?config(sftp, Config),
- {ok,Fd} = file:open(FileName, write),
- io:put_chars(Fd,"foo"),
- ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#400}),
- {error, eacces} = file:write_file(FileName, "hello again"),
- ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#600}),
- ok = file:write_file(FileName, "hello again").
-
-%%--------------------------------------------------------------------
-
-async_read() ->
- [{doc,"Test API aread/3"}].
-async_read(Config) when is_list(Config) ->
- do_async_read(Config, false).
-
-async_read_bin() ->
- [{doc,"Test API aread/3"}].
-async_read_bin(Config) when is_list(Config) ->
- do_async_read(Config, true).
-
-do_async_read(Config, BinaryFlag) ->
- {Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {ok,ExpDataBin} = file:read_file(FileName),
- ExpData = case BinaryFlag of
- true -> ExpDataBin;
- false -> binary_to_list(ExpDataBin)
- end,
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read|case BinaryFlag of
- true -> [binary];
- false -> []
- end]),
- {async, Ref} = ssh_sftp:aread(Sftp, Handle, 20),
- ?receive_chk(Ref, {ok,ExpData}).
-
-%%--------------------------------------------------------------------
-async_write() ->
- [{doc,"Test API awrite/3"}].
-async_write(Config) when is_list(Config) ->
- {Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
- Expected = ?bindata,
- {async, Ref} = ssh_sftp:awrite(Sftp, Handle, Expected),
-
- receive
- {async_reply, Ref, ok} ->
- {ok, Data} = file:read_file(FileName),
- ?chk_expected(Data, Expected);
- Msg ->
- ct:fail(Msg)
- end.
-
-%%--------------------------------------------------------------------
-
-position() ->
- [{doc, "Test API functions position/3"}].
-position(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- Data = list_to_binary("1234567890"),
- ssh_sftp:write_file(Sftp, FileName, [Data]),
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]),
-
- {ok, 3} = ssh_sftp:position(Sftp, Handle, {bof, 3}),
- {ok, "4"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 10} = ssh_sftp:position(Sftp, Handle, eof),
- eof = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 6} = ssh_sftp:position(Sftp, Handle, {bof, 6}),
- {ok, "7"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 9} = ssh_sftp:position(Sftp, Handle, {cur, 2}),
- {ok, "0"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 0} = ssh_sftp:position(Sftp, Handle, bof),
- {ok, "1"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 1} = ssh_sftp:position(Sftp, Handle, cur),
- {ok, "2"} = ssh_sftp:read(Sftp, Handle, 1).
-
-%%--------------------------------------------------------------------
-pos_read() ->
- [{doc,"Test API functions pread/3 and apread/3"}].
-pos_read(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {Sftp, _} = ?config(sftp, Config),
- Data = ?bindata,
- ssh_sftp:write_file(Sftp, FileName, [Data]),
-
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]),
- {async, Ref} = ssh_sftp:apread(Sftp, Handle, {bof,5}, 4),
-
- ?receive_chk(Ref, {ok,binary_part(Data,5,4)}),
- ?chk_expected(ssh_sftp:pread(Sftp,Handle,{bof,4},4), {ok,binary_part(Data,4,4)}).
-
-
-%%--------------------------------------------------------------------
-pos_write() ->
- [{doc,"Test API functions pwrite/4 and apwrite/4"}].
-pos_write(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
-
- Data = unicode:characters_to_list("再见"),
- ssh_sftp:write_file(Sftp, FileName, [Data]),
-
- NewData = unicode:characters_to_list(" さようなら"),
- {async, Ref} = ssh_sftp:apwrite(Sftp, Handle, {bof, 2}, NewData),
- ?receive_chk(Ref, ok),
-
- ok = ssh_sftp:pwrite(Sftp, Handle, eof, unicode:characters_to_list(" adjö ")),
-
- ?chk_expected(ssh_sftp:read_file(Sftp,FileName),
- {ok,unicode:characters_to_binary("再见 さようなら adjö ")}).
-
-%%--------------------------------------------------------------------
-sftp_nonexistent_subsystem() ->
- [{doc, "Try to execute sftp subsystem on a server that does not support it"}].
-sftp_nonexistent_subsystem(Config) when is_list(Config) ->
- {_,Host, Port} = ?config(sftpd, Config),
- {error,"server failed to start sftp subsystem"} =
- ssh_sftp:start_channel(Host, Port,
- [{user_interaction, false},
- {user, ?USER},
- {password, ?PASSWD},
- {silently_accept_hosts, true}]).
-
-%%--------------------------------------------------------------------
-shell_no_unicode(Config) ->
- do_shell(?config(io,Config),
- [new_prompt,
- {type,"io:format(\"hej ~p~n\",[42])."},
- {expect,"hej 42"}
- ]).
-
-%%--------------------------------------------------------------------
-shell_unicode_string(Config) ->
- do_shell(?config(io,Config),
- [new_prompt,
- {type,"io:format(\"こにちわ~ts~n\",[\"四二\"])."},
- {expect,"こにちわ四二"},
- {expect,"ok"}
- ]).
-
-%%--------------------------------------------------------------------
-%% Internal functions ------------------------------------------------
-%%--------------------------------------------------------------------
-prep(Config) ->
- PrivDir = ?config(priv_dir, Config),
- TestFile = filename:join(PrivDir, ?'sftp.txt'),
- TestFile1 = filename:join(PrivDir, ?'test.txt'),
- TestLink = filename:join(PrivDir, ?'link_test.txt'),
-
- file:delete(TestFile),
- file:delete(TestFile1),
- file:delete(TestLink),
-
- %% Initial config
- DataDir = ?config(data_dir, Config),
- FileName = filename:join(DataDir, ?'sftp.txt'),
- {ok,_BytesCopied} = file:copy(FileName, TestFile),
- Mode = 8#00400 bor 8#00200 bor 8#00040, % read & write owner, read group
- {ok, FileInfo} = file:read_file_info(TestFile),
- ok = file:write_file_info(TestFile,
- FileInfo#file_info{mode = Mode}).
-
-
-%% list_dir(Dir) ->
-%% ct:pal("prep/1: ls(~p):~n~p~n~ts",[Dir, file:list_dir(Dir),
-%% begin
-%% {ok,DL} = file:list_dir(Dir),
-%% [[$\n|FN] || FN <- DL]
-%% end]).
-
-
-%%--------------------------------------------------------------------
-do_shell(IO, List) -> do_shell(IO, 0, List).
-
-do_shell(IO, N, [new_prompt|More]) ->
- do_shell(IO, N+1, More);
-
-do_shell(IO, N, Ops=[{Order,Arg}|More]) ->
- receive
- X = <<"\r\n">> ->
-%% ct:pal("Skip newline ~p",[X]),
- do_shell(IO, N, Ops);
-
- <<P1,"> ">> when (P1-$0)==N ->
- do_shell_prompt(IO, N, Order, Arg, More);
-
- <<P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
- do_shell_prompt(IO, N, Order, Arg, More);
-
- Err when element(1,Err)==error ->
- ct:fail("do_shell error: ~p~n",[Err]);
-
- RecBin when Order==expect ; Order==expect_echo ->
-%% ct:pal("received ~p",[RecBin]),
- RecStr = string:strip(unicode:characters_to_list(RecBin)),
- ExpStr = string:strip(Arg),
- case lists:prefix(ExpStr, RecStr) of
- true when Order==expect ->
- ct:pal("Matched ~ts",[RecStr]),
- do_shell(IO, N, More);
- true when Order==expect_echo ->
- ct:pal("Matched echo ~ts",[RecStr]),
- do_shell(IO, N, More);
- false ->
- ct:fail("*** Expected ~p, but got ~p",[string:strip(ExpStr),RecStr])
- end
- after 10000 ->
- case Order of
- expect -> ct:fail("timeout, expected ~p",[string:strip(Arg)]);
- type -> ct:fail("timeout, no prompt")
- end
- end;
-
-do_shell(_, _, []) ->
- ok.
-
-
-do_shell_prompt(IO, N, type, Str, More) ->
-%% ct:pal("Matched prompt ~p to trigger sending of next line to server",[N]),
- IO ! {input, self(), Str++"\r\n"},
- ct:pal("Promt '~p> ', Sent ~ts",[N,Str++"\r\n"]),
- do_shell(IO, N, [{expect_echo,Str}|More]); % expect echo of the sent line
-do_shell_prompt(IO, N, Op, Str, More) ->
-%% ct:pal("Matched prompt ~p",[N]),
- do_shell(IO, N, [{Op,Str}|More]).
-
-%%--------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt b/lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt
deleted file mode 100644
index 3eaaddca21..0000000000
--- a/lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt
+++ /dev/null
@@ -1 +0,0 @@
-åäöÅÄÖ瑞語
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt b/lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt
deleted file mode 100644
index 3eaaddca21..0000000000
--- a/lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt
+++ /dev/null
@@ -1 +0,0 @@
-åäöÅÄÖ瑞語
diff --git a/lib/ssh/test/ssh_upgrade_SUITE.erl b/lib/ssh/test/ssh_upgrade_SUITE.erl
new file mode 100644
index 0000000000..bf8874b118
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE.erl
@@ -0,0 +1,200 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-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.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssh_upgrade_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-record(state, {
+ config,
+ root_dir,
+ server,
+ client,
+ connection,
+ soft
+ }).
+
+
+%%%================================================================
+%%%
+%%% CommonTest callbacks
+%%%
+suite() ->
+ [{timetrap,{minutes,2}}].
+
+all() ->
+ [
+ minor_upgrade,
+ major_upgrade
+ ].
+
+init_per_suite(Config0) ->
+ case ct_release_test:init(Config0) of
+ {skip, Reason} ->
+ {skip, Reason};
+ Config ->
+ ssh:start(),
+ Config
+ end.
+
+end_per_suite(Config) ->
+ ct_release_test:cleanup(Config),
+ ssh:stop(),
+ UserDir = ?config(priv_dir, Config),
+ ssh_test_lib:clean_rsa(UserDir).
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%%================================================================
+%%%
+%%% Test cases
+%%%
+major_upgrade(Config) when is_list(Config) ->
+ ct_release_test:upgrade(ssh, major,{?MODULE, #state{config = Config}}, Config).
+
+minor_upgrade(Config) when is_list(Config) ->
+ ct_release_test:upgrade(ssh, minor,{?MODULE, #state{config = Config}}, Config).
+
+%%%================================================================
+%%%
+%%% ct_release_test callbacks
+%%%
+
+%%%----------------------------------------------------------------
+%%% Initialyze system before upgrade test starts.
+%%% Called by ct_release_test:upgrade/4
+upgrade_init(CTData, State) ->
+ {ok, AppUp={_, _, Up, _Down}} = ct_release_test:get_appup(CTData, ssh),
+ ct:log("AppUp: ~p", [AppUp]),
+ ct:log("Up: ~p", [Up]),
+ case Soft = is_soft(Up) of
+ %% It is symmetrical, if upgrade is soft so is downgrade
+ true ->
+ setup_server_client(State#state{soft = Soft});
+ false ->
+ State#state{soft = Soft}
+ end.
+
+%%%----------------------------------------------------------------
+%%% Check that upgrade was successful
+%%% Called by ct_release_test:upgrade/4
+upgrade_upgraded(_, #state{soft=false} = State) ->
+ test_hard(State, "upgrade");
+
+upgrade_upgraded(_, State) ->
+ test_soft(State, "upgrade1").
+
+%%%----------------------------------------------------------------
+%%% Check that downgrade was successful.
+%%% Called by ct_release_test:upgrade/4
+upgrade_downgraded(_, #state{soft=false} = State) ->
+ test_hard(State, "downgrade");
+
+upgrade_downgraded(_, #state{soft=true} = State) ->
+ test_soft(State, "downgrade1").
+
+%%%================================================================
+%%%
+%%% Private functions
+%%%
+
+is_soft([{restart_application, ssh}]) ->
+ false;
+is_soft(_) ->
+ true.
+
+
+test_hard(State0, FileName) ->
+ ct:log("test_hard State0=~p, FileName=~p",[State0, FileName]),
+ State = setup_server_client(State0),
+ test_connection(FileName, random_contents(), State).
+
+test_soft(State0, FileName) ->
+ ct:log("test_soft State0=~p, FileName=~p",[State0, FileName]),
+ State = test_connection(FileName, random_contents(), State0),
+ setup_server_client( close(State) ).
+
+
+setup_server_client(#state{config=Config} = State) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ FtpRootDir = filename:join(PrivDir, "ftp_root"),
+ catch file:make_dir(FtpRootDir),
+
+ SFTP = ssh_sftpd:subsystem_spec([{root,FtpRootDir},{cwd,FtpRootDir}]),
+
+ {Server,Host,Port} = ssh_test_lib:daemon([{system_dir,DataDir},
+ {user_passwords,[{"hej","hopp"}]},
+ {subsystems,[SFTP]}]),
+
+ {ok, ChannelPid, Connection} =
+ ssh_sftp:start_channel(Host, Port, [{user_interaction,false},
+ {silently_accept_hosts,true},
+ {user_dir,DataDir},
+ {user,"hej"},
+ {password,"hopp"}]),
+ State#state{server = Server,
+ client = ChannelPid,
+ connection = Connection}.
+
+
+test_connection(FileName, FileContents,
+ #state{client = ChannelPid,
+ root_dir = FtpRootDir} = State) ->
+ ct:log("test_connection Writing with ssh_sftp:write_file",[]),
+ case ssh_sftp:write_file(ChannelPid, FileName, FileContents) of
+ ok ->
+ case ssh_sftp:read_file(ChannelPid, FileName) of
+ {ok,FileContents} ->
+ State;
+ {ok,Unexpected} ->
+ ct:fail("Expected ~p but got ~p from sftp:read_file(~p,..) in RootDir ~p",
+ [FileContents,Unexpected,FileName,FtpRootDir]
+ );
+ Other ->
+ ct:fail("ssh_sftp:read_file(~p,~p) -> ~p~n"
+ "ssh_sftp:list_dir(~p,\".\") -> ~p",
+ [ChannelPid,FileName,Other,
+ ChannelPid, catch ssh_sftp:list_dir(ChannelPid, ".")])
+ end;
+
+ Other ->
+ ct:fail("ssh_sftp:write_file(~p,~p,~p) -> ~p",[ChannelPid,FileName,FileContents,Other])
+ end.
+
+
+close(#state{server = Server,
+ connection = Connection} = State) ->
+ ssh:close(Connection),
+ ssh:stop_daemon(Server),
+ State#state{server = undefined,
+ client = undefined,
+ connection = undefined}.
+
+
+random_contents() -> list_to_binary( random_chars(3) ).
+
+random_chars(N) -> [crypto:rand_uniform($a,$z) || _<-lists:duplicate(N,x)].
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa b/lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa b/lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts b/lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts
@@ -0,0 +1 @@
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 9d486f8890..41b42d454b 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 3.2.4
+SSH_VSN = 4.2.2
+
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/Makefile b/lib/ssl/Makefile
index a7a95004a6..c3b7af5bcd 100644
--- a/lib/ssl/Makefile
+++ b/lib/ssl/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile
index fb12499ef7..669062779e 100644
--- a/lib/ssl/doc/src/Makefile
+++ b/lib/ssl/doc/src/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2012. All Rights Reserved.
+# Copyright Ericsson AB 1999-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -37,7 +38,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# Target Specs
# ----------------------------------------------------
XML_APPLICATION_FILES = refman.xml
-XML_REF3_FILES = ssl.xml ssl_session_cache_api.xml
+XML_REF3_FILES = ssl.xml ssl_crl_cache.xml ssl_crl_cache_api.xml ssl_session_cache_api.xml
XML_REF6_FILES = ssl_app.xml
XML_PART_FILES = release_notes.xml usersguide.xml
diff --git a/lib/ssl/doc/src/book.xml b/lib/ssl/doc/src/book.xml
index 317997b22b..a0890a028d 100644
--- a/lib/ssl/doc/src/book.xml
+++ b/lib/ssl/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index fe0606b1a3..5b0b5ead20 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -25,7 +26,451 @@
<file>notes.xml</file>
</header>
<p>This document describes the changes made to the SSL application.</p>
- <section><title>SSL 6.0.1</title>
+
+
+<section><title>SSL 7.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct ssl:prf/5 to use the negotiated cipher suite's
+ prf function in ssl:prf/5 instead of the default prf.</p>
+ <p>
+ Own Id: OTP-13546</p>
+ </item>
+ <item>
+ <p>
+ Timeouts may have the value 0, guards have been corrected
+ to allow this</p>
+ <p>
+ Own Id: OTP-13635</p>
+ </item>
+ <item>
+ <p>
+ Change of internal handling of hash sign pairs as the
+ used one enforced to much restrictions making some valid
+ combinations unavailable.</p>
+ <p>
+ Own Id: OTP-13670</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Create a little randomness in sending of session
+ invalidation messages, to mitigate load when whole table
+ is invalidated.</p>
+ <p>
+ Own Id: OTP-13490</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 7.3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct cipher suites conversion and gaurd expression.
+ Caused problems with GCM cipher suites and client side
+ option to set signature_algorithms extention values.</p>
+ <p>
+ Own Id: OTP-13525</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 7.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Corrections to cipher suite handling using the 3 and 4
+ tuple format in addition to commit
+ 89d7e21cf4ae988c57c8ef047bfe85127875c70c</p>
+ <p>
+ Own Id: OTP-13511</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Make values for the TLS-1.2 signature_algorithms
+ extension configurable</p>
+ <p>
+ Own Id: OTP-13261</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure there is only one poller validator at a time
+ for validating the session cache.</p>
+ <p>
+ Own Id: OTP-13185</p>
+ </item>
+ <item>
+ <p>
+ A timing related issue could cause ssl to hang,
+ especially happened with newer versions of OpenSSL in
+ combination with ECC ciphers.</p>
+ <p>
+ Own Id: OTP-13253</p>
+ </item>
+ <item>
+ <p>
+ Work around a race condition in the TLS distribution
+ start.</p>
+ <p>
+ Own Id: OTP-13268</p>
+ </item>
+ <item>
+ <p>
+ Big handshake messages are now correctly fragmented in
+ the TLS record layer.</p>
+ <p>
+ Own Id: OTP-13306</p>
+ </item>
+ <item>
+ <p>
+ Improve portability of ECC tests in Crypto and SSL for
+ "exotic" OpenSSL versions.</p>
+ <p>
+ Own Id: OTP-13311</p>
+ </item>
+ <item>
+ <p>
+ Certificate extensions marked as critical are ignored
+ when using verify_none</p>
+ <p>
+ Own Id: OTP-13377</p>
+ </item>
+ <item>
+ <p>
+ If a certificate doesn't contain a CRL Distribution
+ Points extension, and the relevant CRL is not in the
+ cache, and the <c>crl_check</c> option is not set to
+ <c>best_effort</c> , the revocation check should fail.</p>
+ <p>
+ Own Id: OTP-13378</p>
+ </item>
+ <item>
+ <p>
+ Enable TLS distribution over IPv6</p>
+ <p>
+ Own Id: OTP-13391</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improve error reporting for TLS distribution</p>
+ <p>
+ Own Id: OTP-13219</p>
+ </item>
+ <item>
+ <p>
+ Include options from connect, listen and accept in
+ <c>connection_information/1,2</c></p>
+ <p>
+ Own Id: OTP-13232</p>
+ </item>
+ <item>
+ <p>
+ Allow adding extra options for outgoing TLS distribution
+ connections, as supported for plain TCP connections.</p>
+ <p>
+ Own Id: OTP-13285</p>
+ </item>
+ <item>
+ <p>
+ Use loopback as server option in TLS-distribution module</p>
+ <p>
+ Own Id: OTP-13300</p>
+ </item>
+ <item>
+ <p>
+ Verify certificate signature against original certificate
+ binary.</p>
+ <p>
+ This avoids bugs due to encoding errors when re-encoding
+ a decode certificate. As there exists several decode step
+ and using of different ASN.1 specification this is a risk
+ worth avoiding.</p>
+ <p>
+ Own Id: OTP-13334</p>
+ </item>
+ <item>
+ <p>
+ Use <c>application:ensure_all_started/2</c> instead of
+ hard-coding dependencies</p>
+ <p>
+ Own Id: OTP-13363</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Honor distribution port range options</p>
+ <p>
+ Own Id: OTP-12838</p>
+ </item>
+ <item>
+ <p>
+ Correct supervisor specification in TLS distribution.</p>
+ <p>
+ Own Id: OTP-13134</p>
+ </item>
+ <item>
+ <p>
+ Correct cache timeout</p>
+ <p>
+ Own Id: OTP-13141</p>
+ </item>
+ <item>
+ <p>
+ Avoid crash and restart of ssl process when key file does
+ not exist.</p>
+ <p>
+ Own Id: OTP-13144</p>
+ </item>
+ <item>
+ <p>
+ Enable passing of raw socket options on the format
+ {raw,_,_,_} to the underlying socket.</p>
+ <p>
+ Own Id: OTP-13166</p>
+ </item>
+ <item>
+ <p>
+ Hibernation with small or a zero timeout will now work as
+ expected</p>
+ <p>
+ Own Id: OTP-13189</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add upper limit for session cache, configurable on ssl
+ application level.</p>
+ <p>
+ If upper limit is reached, invalidate the current cache
+ entries, e.i the session lifetime is the max time a
+ session will be keept, but it may be invalidated earlier
+ if the max limit for the table is reached. This will keep
+ the ssl manager process well behaved, not exhusting
+ memeory. Invalidating the entries will incrementally
+ empty the cache to make room for fresh sessions entries.</p>
+ <p>
+ Own Id: OTP-12392</p>
+ </item>
+ <item>
+ <p>
+ Use new time functions to measure passed time.</p>
+ <p>
+ Own Id: OTP-12457</p>
+ </item>
+ <item>
+ <p>
+ Improved error handling in TLS distribution</p>
+ <p>
+ Own Id: OTP-13142</p>
+ </item>
+ <item>
+ <p>
+ Distribution over TLS now honors the nodelay distribution
+ flag</p>
+ <p>
+ Own Id: OTP-13143</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 7.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add DER encoded ECPrivateKey as valid input format for
+ key option.</p>
+ <p>
+ Own Id: OTP-12974</p>
+ </item>
+ <item>
+ <p>
+ Correct return value of default session callback module</p>
+ <p>
+ This error had the symptom that the client check for
+ unique session would always fail, potentially making the
+ client session table grow a lot and causing long setup
+ times.</p>
+ <p>
+ Own Id: OTP-12980</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add possibility to downgrade an SSL/TLS connection to a
+ tcp connection, and give back the socket control to a
+ user process.</p>
+ <p>
+ This also adds the possibility to specify a timeout to
+ the ssl:close function.</p>
+ <p>
+ Own Id: OTP-11397</p>
+ </item>
+ <item>
+ <p>
+ Add application setting to be able to change fatal alert
+ shutdown timeout, also shorten the default timeout. The
+ fatal alert timeout is the number of milliseconds between
+ sending of a fatal alert and closing the connection.
+ Waiting a little while improves the peers chances to
+ properly receiving the alert so it may shutdown
+ gracefully.</p>
+ <p>
+ Own Id: OTP-12832</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 7.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Ignore signature_algorithm (TLS 1.2 extension) sent to
+ TLS 1.0 or TLS 1.1 server</p>
+ <p>
+ Own Id: OTP-12670</p>
+ </item>
+ <item>
+ <p>
+ Improve error handling in TLS distribution module to
+ avoid lingering sockets.</p>
+ <p>
+ Own Id: OTP-12799 Aux Id: Tom Briden </p>
+ </item>
+ <item>
+ <p>
+ Add option {client_renegotiation, boolean()} option to
+ the server-side of the SSL application.</p>
+ <p>
+ Own Id: OTP-12815</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add new API functions to handle CRL-verification</p>
+ <p>
+ Own Id: OTP-10362 Aux Id: kunagi-215 [126] </p>
+ </item>
+ <item>
+ <p>
+ Remove default support for SSL-3.0, due to Poodle
+ vunrability in protocol specification.</p>
+ <p>
+ Add padding check for TLS-1.0 to remove Poodle
+ vunrability from TLS 1.0, also add the option
+ padding_check. This option only affects TLS-1.0
+ connections and if set to false it disables the block
+ cipher padding check to be able to interoperate with
+ legacy software.</p>
+ <p>
+ Remove default support for RC4 cipher suites, as they are
+ consider too weak.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12390</p>
+ </item>
+ <item>
+ <p>
+ Add support for TLS ALPN (Application-Layer Protocol
+ Negotiation) extension.</p>
+ <p>
+ Own Id: OTP-12580</p>
+ </item>
+ <item>
+ <p>
+ Add SNI (Server Name Indication) support for the server
+ side.</p>
+ <p>
+ Own Id: OTP-12736</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 6.0.1.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Gracefully ignore proprietary hash_sign algorithms</p>
+ <p>
+ Own Id: OTP-12829</p>
+ </item>
+ </list>
+ </section>
+</section>
+
+
+<section><title>SSL 6.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ssl/doc/src/pkix_certs.xml b/lib/ssl/doc/src/pkix_certs.xml
index cfbc6b08d7..a5793af5ca 100644
--- a/lib/ssl/doc/src/pkix_certs.xml
+++ b/lib/ssl/doc/src/pkix_certs.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ssl/doc/src/refman.xml b/lib/ssl/doc/src/refman.xml
index ae11198edb..317da00414 100644
--- a/lib/ssl/doc/src/refman.xml
+++ b/lib/ssl/doc/src/refman.xml
@@ -4,20 +4,21 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1999</year><year>2013</year>
+ <year>1999</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -28,23 +29,10 @@
<rev>B</rev>
<file>refman.sgml</file>
</header>
- <description>
- <p>The <em>SSL</em> application provides secure communication over
- sockets.
- </p>
- <p>This product includes software developed by the OpenSSL Project for
- use in the OpenSSL Toolkit (http://www.openssl.org/).
- </p>
- <p>This product includes cryptographic software written by Eric Young
- </p>
- <p>This product includes software written by Tim Hudson
- </p>
- <p>For full OpenSSL and SSLeay license texts, see <seealso marker="licenses#licenses">Licenses</seealso>.</p>
- </description>
<xi:include href="ssl_app.xml"/>
<xi:include href="ssl.xml"/>
+ <xi:include href="ssl_crl_cache.xml"/>
+ <xi:include href="ssl_crl_cache_api.xml"/>
<xi:include href="ssl_session_cache_api.xml"/>
</application>
diff --git a/lib/ssl/doc/src/release_notes.xml b/lib/ssl/doc/src/release_notes.xml
index 123e8e1451..4c9b18f900 100644
--- a/lib/ssl/doc/src/release_notes.xml
+++ b/lib/ssl/doc/src/release_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 0c042f8571..e831f73530 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -8,254 +8,277 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssl</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
<file>ssl.xml</file>
</header>
<module>ssl</module>
<modulesummary>Interface Functions for Secure Socket Layer</modulesummary>
<description>
- <p>This module contains interface functions to the Secure Socket
- Layer.
+ <p>
+ This module contains interface functions for the SSL/TLS protocol.
+ For detailed information about the supported standards see
+ <seealso marker="ssl_app">ssl(6)</seealso>.
</p>
</description>
-
+
<section>
- <title>SSL</title>
+ <title>DATA TYPES</title>
+ <p>The following data types are used in the functions for SSL:</p>
- <list type="bulleted">
- <item>ssl requires the crypto and public_key applications.</item>
- <item>Supported SSL/TLS-versions are SSL-3.0, TLS-1.0,
- TLS-1.1 and TLS-1.2.</item>
- <item>For security reasons sslv2 is not supported.</item>
- <item>Ephemeral Diffie-Hellman cipher suites are supported
- but not Diffie Hellman Certificates cipher suites.</item>
- <item>Elliptic Curve cipher suites are supported if crypto
- supports it and named curves are used.
+ <taglist>
+
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+
+ <tag><c>option() =</c></tag>
+ <item><p><c>socketoption() | ssloption() | transportoption()</c></p>
</item>
- <item>Export cipher suites are not supported as the
- U.S. lifted its export restrictions in early 2000.</item>
- <item>IDEA cipher suites are not supported as they have
- become deprecated by the latest TLS spec so there is not any
- real motivation to implement them.</item>
- <item>CRL and policy certificate extensions are not supported
- yet. However CRL verification is supported by public_key, only not integrated
- in ssl yet. </item>
- <item>Support for 'Server Name Indication' extension client side
- (RFC 6066 section 3).</item>
- </list>
-
- </section>
-
- <section>
- <title>COMMON DATA TYPES</title>
- <p>The following data types are used in the functions below:
- </p>
- <p><c>boolean() = true | false</c></p>
+ <tag><c>socketoption() =</c></tag>
+ <item><p><c>proplists:property()</c></p>
+ <p>The default socket options are
+ <c>[{mode,list},{packet, 0},{header, 0},{active, true}]</c>.</p>
+ <p>For valid options, see the
+ <seealso marker="kernel:inet">inet(3)</seealso> and
+ <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso> manual pages
+ in Kernel.</p></item>
- <p><c>option() = socketoption() | ssloption() | transportoption()</c></p>
+ <tag><marker id="type-ssloption"/><c>ssloption() =</c></tag>
+ <item>
+ <p><c>{verify, verify_type()}</c></p>
+ <p><c>| {verify_fun, {fun(), term()}}</c></p>
+ <p><c>| {fail_if_no_peer_cert, boolean()}</c></p>
+ <p><c>| {depth, integer()}</c></p>
+ <p><c>| {cert, public_key:der_encoded()}</c></p>
+ <p><c>| {certfile, path()}</c></p>
+ <p><c>| {key, {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey'
+ | 'PrivateKeyInfo', public_key:der_encoded()}}</c></p>
+ <p><c>| {keyfile, path()}</c></p>
+ <p><c>| {password, string()}</c></p>
+ <p><c>| {cacerts, [public_key:der_encoded()]}</c></p>
+ <p><c>| {cacertfile, path()}</c></p>
+ <p><c>| {dh, public_key:der_encoded()}</c></p>
+ <p><c>| {dhfile, path()}</c></p>
+ <p><c>| {ciphers, ciphers()}</c></p>
+ <p><c>| {user_lookup_fun, {fun(), term()}}, {psk_identity, string()},
+ {srp_identity, {string(), string()}}</c></p>
+ <p><c>| {reuse_sessions, boolean()}</c></p>
+ <p><c>| {reuse_session, fun()} {next_protocols_advertised, [binary()]}</c></p>
+ <p><c>| {client_preferred_next_protocols, {client | server,
+ [binary()]} | {client | server, [binary()], binary()}}</c></p>
+ <p><c>| {log_alert, boolean()}</c></p>
+ <p><c>| {server_name_indication, hostname() | disable}</c></p>
+ <p><c>| {sni_hosts, [{hostname(), ssloptions()}]}</c></p>
+ <p><c>| {sni_fun, SNIfun::fun()}</c></p>
+ </item>
+
+ <tag><c>transportoption() =</c></tag>
+ <item><p><c>{cb_info, {CallbackModule::atom(), DataTag::atom(),
+
+ ClosedTag::atom(), ErrTag:atom()}}</c></p>
+ <p>Defaults to <c>{gen_tcp, tcp, tcp_closed, tcp_error}</c>. Can be used
+ to customize the transport layer. The callback module must implement a
+ reliable transport protocol, behave as <c>gen_tcp</c>, and have functions
+ corresponding to <c>inet:setopts/2</c>, <c>inet:getopts/2</c>,
+ <c>inet:peername/1</c>, <c>inet:sockname/1</c>, and <c>inet:port/1</c>.
+ The callback <c>gen_tcp</c> is treated specially and calls <c>inet</c>
+ directly.</p>
+ <taglist>
+ <tag><c>CallbackModule =</c></tag>
+ <item><p><c>atom()</c></p></item>
+ <tag><c>DataTag =</c></tag>
+ <item><p><c>atom()</c></p>
+ <p>Used in socket data message.</p></item>
+ <tag><c>ClosedTag =</c></tag>
+ <item><p><c>atom()</c></p>
+ <p>Used in socket close message.</p></item>
+ </taglist>
+ </item>
- <p><c>socketoption() = proplists:property() - The default socket options are
- [{mode,list},{packet, 0},{header, 0},{active, true}].
- </c></p>
+ <tag><c>verify_type() =</c></tag>
+ <item><p><c>verify_none | verify_peer</c></p></item>
- <p>For valid options
- see <seealso marker="kernel:inet">inet(3)</seealso> and
- <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>.
- </p>
-
- <p><marker id="type-ssloption"></marker><c>ssloption() = {verify, verify_type()} |
- {verify_fun, {fun(), term()}} |
- {fail_if_no_peer_cert, boolean()}
- {depth, integer()} |
- {cert, der_encoded()}| {certfile, path()} |
- {key, {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey' |'PrivateKeyInfo', der_encoded()}} |
- {keyfile, path()} | {password, string()} |
- {cacerts, [der_encoded()]} | {cacertfile, path()} |
- |{dh, der_encoded()} | {dhfile, path()} | {ciphers, ciphers()} |
- {user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity, {string(), string()}} |
- {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()}
- {next_protocols_advertised, [binary()]} |
- {client_preferred_next_protocols, {client | server, [binary()]} | {client | server, [binary()], binary()}} |
- {log_alert, boolean()} | {server_name_indication, hostname() | disable}
- </c></p>
-
- <p><c>transportoption() = {cb_info, {CallbackModule::atom(), DataTag::atom(), ClosedTag::atom(), ErrTag:atom()}}
- - defaults to {gen_tcp, tcp, tcp_closed, tcp_error}. Can be used to customize
- the transport layer. The callback module must implement a reliable transport
- protocol and behave as gen_tcp and in addition have functions corresponding to
- inet:setopts/2, inet:getopts/2, inet:peername/1, inet:sockname/1 and inet:port/1.
- The callback gen_tcp is treated specially and will call inet directly.
- </c></p>
-
- <p><c>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CallbackModule =
- atom()</c>
- </p> <p><c>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTag =
- atom() - tag used in socket data message.</c></p>
- <p><c>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClosedTag = atom() - tag used in
- socket close message.</c></p>
-
- <p><c>verify_type() = verify_none | verify_peer</c></p>
-
- <p><c>path() = string() - representing a file path.</c></p>
+ <tag><c>path() =</c></tag>
+ <item><p><c>string()</c></p>
+ <p>Represents a file path.</p></item>
- <p><c>der_encoded() = binary() -Asn1 DER encoded entity as an erlang binary.</c></p>
-
- <p><c>host() = hostname() | ipaddress()</c></p>
-
- <p><c>hostname() = string()</c></p>
-
- <p><c>
- ip_address() = {N1,N2,N3,N4} % IPv4
- | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6 </c></p>
+ <tag><c>public_key:der_encoded() =</c></tag>
+ <item><p><c>binary()</c></p>
+ <p>ASN.1 DER-encoded entity as an Erlang binary.</p></item>
- <p><c>sslsocket() - opaque to the user. </c></p>
-
- <p><c>protocol() = sslv3 | tlsv1 | 'tlsv1.1' | 'tlsv1.2' </c></p>
-
- <p><c>ciphers() = [ciphersuite()] | string() (according to old API)</c></p>
-
- <p><c>ciphersuite() =
- {key_exchange(), cipher(), hash()}</c></p>
-
- <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa | dh_anon
- | psk | dhe_psk | rsa_psk | srp_anon | srp_dss | srp_rsa
- | ecdh_anon | ecdh_ecdsa | ecdhe_ecdsa | ecdh_rsa | ecdhe_rsa
- </c></p>
+ <tag><c>host() =</c></tag>
+ <item><p><c>hostname() | ipaddress()</c></p></item>
+
+ <tag><c>hostname() =</c></tag>
+ <item><p><c>string()</c></p></item>
+
+ <tag><c>ip_address() =</c></tag>
+ <item><p><c>{N1,N2,N3,N4} % IPv4 | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6
+ </c></p></item>
+
+ <tag><c>sslsocket() =</c></tag>
+ <item><p>opaque()</p></item>
+
+ <tag><marker id="type-protocol"/><c>protocol() =</c></tag>
+ <item><p><c>sslv3 | tlsv1 | 'tlsv1.1' | 'tlsv1.2'</c></p></item>
+
+ <tag><c>ciphers() =</c></tag>
+ <item><p><c>= [ciphersuite()] | string()</c></p>
+ <p>According to old API.</p></item>
+
+ <tag><c>ciphersuite() =</c></tag>
+
+ <item><p><c>{key_exchange(), cipher(), MAC::hash()} |
+ {key_exchange(), cipher(), MAC::hash(), PRF::hash()}</c></p></item>
+
+ <tag><c>key_exchange()=</c></tag>
+ <item><p><c>rsa | dhe_dss | dhe_rsa | dh_anon | psk | dhe_psk
+ | rsa_psk | srp_anon | srp_dss | srp_rsa | ecdh_anon | ecdh_ecdsa
+ | ecdhe_ecdsa | ecdh_rsa | ecdhe_rsa</c></p></item>
+
+ <tag><c>cipher() =</c></tag>
+ <item><p><c>rc4_128 | des_cbc | '3des_ede_cbc'
+ | aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm</c></p></item>
- <p><c>cipher() = rc4_128 | des_cbc | '3des_ede_cbc'
- | aes_128_cbc | aes_256_cbc </c></p>
+ <tag><c>hash() =</c></tag>
+ <item><p><c>md5 | sha | sha224 | sha256 | sha348 | sha512</c></p></item>
- <p> <c>hash() = md5 | sha
- </c></p>
+ <tag><c>prf_random() =</c></tag>
+ <item><p><c>client_random | server_random</c></p></item>
- <p><c>prf_random() = client_random | server_random
- </c></p>
+ <tag><c>srp_param_type() =</c></tag>
+ <item><p><c>srp_1024 | srp_1536 | srp_2048 | srp_3072
+ | srp_4096 | srp_6144 | srp_8192</c></p></item>
- <p><c>srp_param_type() = srp_1024 | srp_1536 | srp_2048 | srp_3072
- | srp_4096 | srp_6144 | srp_8192</c></p>
+ <tag><c>SNIfun::fun()</c></tag>
+ <item><p><c>= fun(ServerName :: string()) -> ssloptions()</c></p></item>
+ </taglist>
</section>
<section>
<title>SSL OPTION DESCRIPTIONS - COMMON for SERVER and CLIENT</title>
- <p>Options described here are options that are have the same
- meaning in the client and the server.
- </p>
+ <p>The following options have the same meaning in the client and
+ the server:</p>
<taglist>
- <tag>{cert, der_encoded()}</tag>
- <item> The DER encoded users certificate. If this option
- is supplied it will override the certfile option.</item>
+ <tag><c>{cert, public_key:der_encoded()}</c></tag>
+ <item><p>The DER-encoded users certificate. If this option
+ is supplied, it overrides option <c>certfile</c>.</p></item>
- <tag>{certfile, path()}</tag>
- <item>Path to a file containing the user's PEM encoded certificate.</item>
+ <tag><c>{certfile, path()}</c></tag>
+ <item><p>Path to a file containing the user certificate.</p></item>
- <tag>{key, {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey' |'PrivateKeyInfo', der_encoded()}}</tag>
- <item> The DER encoded users private key. If this option
- is supplied it will override the keyfile option.</item>
+ <tag><c>{key, {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey'
+ |'PrivateKeyInfo', public_key:der_encoded()}}</c></tag>
+ <item><p>The DER-encoded user's private key. If this option
+ is supplied, it overrides option <c>keyfile</c>.</p></item>
- <tag>{keyfile, path()}</tag>
- <item>Path to file containing user's
- private PEM encoded key. As PEM-files may contain several
- entries this option defaults to the same file as given by
- certfile option.</item>
-
- <tag>{password, string()}</tag>
- <item>String containing the user's password.
- Only used if the private keyfile is password protected.
- </item>
-
- <tag>{cacerts, [der_encoded()]}</tag>
- <item> The DER encoded trusted certificates. If this option
- is supplied it will override the cacertfile option.</item>
-
- <tag>{ciphers, ciphers()}</tag>
- <item>The cipher suites that should be supported. The function
+ <tag><c>{keyfile, path()}</c></tag>
+ <item><p>Path to the file containing the user's
+ private PEM-encoded key. As PEM-files can contain several
+ entries, this option defaults to the same file as given by
+ option <c>certfile</c>.</p></item>
+
+ <tag><c>{password, string()}</c></tag>
+ <item><p>String containing the user's password. Only used if the
+ private keyfile is password-protected.</p></item>
+
+ <tag><c>{ciphers, ciphers()}</c></tag>
+ <item><p>Supported cipher suites. The function
<c>cipher_suites/0</c> can be used to find all ciphers that are
- supported by default. <c>cipher_suites(all)</c> may be called
- to find all available cipher suites.
- Pre-Shared Key (<url href="http://www.ietf.org/rfc/rfc4279.txt">RFC 4279</url> and
+ supported by default. <c>cipher_suites(all)</c> can be called
+ to find all available cipher suites. Pre-Shared Key
+ (<url href="http://www.ietf.org/rfc/rfc4279.txt">RFC 4279</url> and
<url href="http://www.ietf.org/rfc/rfc5487.txt">RFC 5487</url>),
- Secure Remote Password (<url href="http://www.ietf.org/rfc/rfc5054.txt">RFC 5054</url>)
+ Secure Remote Password
+ (<url href="http://www.ietf.org/rfc/rfc5054.txt">RFC 5054</url>), RC4 cipher suites,
and anonymous cipher suites only work if explicitly enabled by
- this option and they are supported/enabled by the peer also.
- Note that anonymous cipher suites are supported for testing purposes
- only and should not be used when security matters.
- </item>
-
- <tag>{ssl_imp, new | old}</tag>
- <item>No longer has any meaning as the old implementation has
- been removed, it will be ignored.
- </item>
-
- <tag>{secure_renegotiate, boolean()}</tag>
- <item>Specifies if to reject renegotiation attempt that does
- not live up to <url href="http://www.ietf.org/rfc/rfc5746.txt">RFC 5746</url>. By default secure_renegotiate is
- set to false i.e. secure renegotiation will be used if possible
- but it will fallback to unsecure renegotiation if the peer
- does not support <url href="http://www.ietf.org/rfc/rfc5746.txt">RFC 5746</url>.
+ this option; they are supported/enabled by the peer also.
+ Anonymous cipher suites are supported for testing purposes
+ only and are not be used when security matters.</p></item>
+
+ <tag><c>{secure_renegotiate, boolean()}</c></tag>
+ <item><p>Specifies if to reject renegotiation attempt that does
+ not live up to
+ <url href="http://www.ietf.org/rfc/rfc5746.txt">RFC 5746</url>.
+ By default <c>secure_renegotiate</c> is set to <c>false</c>,
+ that is, secure renegotiation is used if possible,
+ but it falls back to insecure renegotiation if the peer
+ does not support
+ <url href="http://www.ietf.org/rfc/rfc5746.txt">RFC 5746</url>.</p>
</item>
- <tag>{depth, integer()}</tag>
- <item>
- The depth is the maximum number of non-self-issued
- intermediate certificates that may follow the peer certificate
- in a valid certification path. So if depth is 0 the PEER must
- be signed by the trusted ROOT-CA directly, if 1 the path can
- be PEER, CA, ROOT-CA, if it is 2 PEER, CA, CA, ROOT-CA and so
- on. The default value is 1.
- </item>
+ <tag><c>{depth, integer()}</c></tag>
+ <item><p>Maximum number of non-self-issued
+ intermediate certificates that can follow the peer certificate
+ in a valid certification path. So, if depth is 0 the PEER must
+ be signed by the trusted ROOT-CA directly; if 1 the path can
+ be PEER, CA, ROOT-CA; if 2 the path can be PEER, CA, CA,
+ ROOT-CA, and so on. The default value is 1.</p></item>
- <tag>{verify_fun, {Verifyfun :: fun(), InitialUserState :: term()}}</tag>
- <item>
- <p>The verification fun should be defined as:</p>
+ <tag><c>{verify_fun, {Verifyfun :: fun(), InitialUserState ::
+ term()}}</c></tag>
+ <item><p>The verification fun is to be defined as follows:</p>
<code>
-fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
+fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | {revoked,
+atom()}} |
{extension, #'Extension'{}}, InitialUserState :: term()) ->
{valid, UserState :: term()} | {valid_peer, UserState :: term()} |
{fail, Reason :: term()} | {unknown, UserState :: term()}.
</code>
- <p>The verify fun will be called during the X509-path
- validation when an error or an extension unknown to the ssl
- application is encountered. Additionally it will be called
+ <p>The verification fun is called during the X509-path
+ validation when an error or an extension unknown to the SSL
+ application is encountered. It is also called
when a certificate is considered valid by the path validation
to allow access to each certificate in the path to the user
- application. Note that it will differentiate between the
- peer certificate and CA certificates by using valid_peer or
- valid as the second argument to the verify fun. See <seealso
- marker="public_key:cert_records">the public_key User's
- Guide</seealso> for definition of #'OTPCertificate'{} and
- #'Extension'{}.</p>
-
- <p>If the verify callback fun returns {fail, Reason}, the
- verification process is immediately stopped and an alert is
- sent to the peer and the TLS/SSL handshake is terminated. If
- the verify callback fun returns {valid, UserState}, the
- verification process is continued. If the verify callback fun
- always returns {valid, UserState}, the TLS/SSL handshake will
- not be terminated with respect to verification failures and
- the connection will be established. If called with an
- extension unknown to the user application, the return value
- {unknown, UserState} should be used.</p>
-
- <p>The default verify_fun option in verify_peer mode:</p>
+ application. It differentiates between the peer
+ certificate and the CA certificates by using <c>valid_peer</c> or
+ <c>valid</c> as second argument to the verification fun. See the
+ <seealso marker="public_key:public_key_records">public_key User's
+ Guide</seealso> for definition of <c>#'OTPCertificate'{}</c> and
+ <c>#'Extension'{}</c>.</p>
+
+ <list type="bulleted">
+ <item><p>If the verify callback fun returns <c>{fail, Reason}</c>,
+ the verification process is immediately stopped, an alert is
+ sent to the peer, and the TLS/SSL handshake terminates.</p></item>
+ <item><p>If the verify callback fun returns <c>{valid, UserState}</c>,
+ the verification process continues.</p></item>
+ <item><p>If the verify callback fun always returns
+ <c>{valid, UserState}</c>, the TLS/SSL handshake does not
+ terminate regarding verification failures and the connection is
+ established.</p></item>
+ <item><p>If called with an extension unknown to the user application,
+ return value <c>{unknown, UserState}</c> is to be used.</p>
+
+ <p>Note that if the fun returns <c>unknown</c> for an extension marked
+ as critical, validation will fail.</p>
+ </item>
+ </list>
+
+ <p>Default option <c>verify_fun</c> in <c>verify_peer mode</c>:</p>
<code>
{fun(_,{bad_cert, _} = Reason, _) ->
@@ -269,11 +292,13 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | {revo
end, []}
</code>
- <p>The default verify_fun option in verify_none mode:</p>
+ <p>Default option <c>verify_fun</c> in mode <c>verify_none</c>:</p>
<code>
{fun(_,{bad_cert, _}, UserState) ->
{valid, UserState};
+ (_,{extension, #'Extension'{critical = true}}, UserState) ->
+ {valid, UserState};
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
@@ -283,49 +308,88 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | {revo
end, []}
</code>
- <p>Possible path validation errors are given on the form {bad_cert, Reason} where Reason is:</p>
+ <p>The possible path validation errors are given on form
+ <c>{bad_cert, Reason}</c> where <c>Reason</c> is:</p>
<taglist>
- <tag>unknown_ca</tag>
- <item>No trusted CA was found in the trusted store. The trusted CA is
- normally a so called ROOT CA that is a self-signed cert. Trust may
- be claimed for an intermediat CA (trusted anchor does not have to be self signed
- according to X-509) by using the option <c>partial_chain</c></item>
-
- <tag>selfsigned_peer</tag>
- <item>The chain consisted only of one self-signed certificate.</item>
-
- <tag>PKIX X-509-path validation error</tag>
- <item> Possible such reasons see <seealso
- marker="public_key:public_key#pkix_path_validation-3"> public_key:pkix_path_validation/3 </seealso></item>
+ <tag><c>unknown_ca</c></tag>
+ <item><p>No trusted CA was found in the trusted store. The trusted CA is
+ normally a so called ROOT CA, which is a self-signed certificate. Trust can
+ be claimed for an intermediate CA (trusted anchor does not have to be
+ self-signed according to X-509) by using option <c>partial_chain</c>.</p>
+ </item>
+
+ <tag><c>selfsigned_peer</c></tag>
+ <item><p>The chain consisted only of one self-signed certificate.</p></item>
+
+ <tag><c>PKIX X-509-path validation error</c></tag>
+ <item><p>For possible reasons, see <seealso
+marker="public_key:public_key#pkix_path_validation-3">public_key:pkix_path_validation/3</seealso>
+ </p></item>
</taglist>
-
</item>
- <tag>{partial_chain, fun(Chain::[DerCert]) -> {trusted_ca, DerCert} | unknown_ca </tag>
+ <tag><c>{crl_check, boolean() | peer | best_effort }</c></tag>
<item>
- Claim an intermediat CA in the chain as trusted. TLS will then perform the public_key:pkix_path_validation/3
- with the selected CA as trusted anchor and the rest of the chain.
- </item>
+ Perform CRL (Certificate Revocation List) verification
+ <seealso marker="public_key:public_key#pkix_crls_validate-3">
+ (public_key:pkix_crls_validate/3)</seealso> on all the certificates during the path validation
+ <seealso
+ marker="public_key:public_key#pkix_path_validation-3">(public_key:pkix_path_validation/3)
+ </seealso>
+ of the certificate chain. Defaults to false.
+
+ <p><c>peer</c> - check is only performed on
+ the peer certificate.</p>
- <tag>{versions, [protocol()]}</tag>
- <item>TLS protocol versions that will be supported by started clients and servers.
- This option overrides the application environment option <c>protocol_version</c>. If the
- environment option is not set it defaults to all versions supported by the SSL application. See also
- <seealso marker="ssl:ssl_app">ssl(6)</seealso>
- </item>
+ <p><c>best_effort</c> - if certificate revocation status can not be determined
+ it will be accepted as valid.</p>
- <tag>{hibernate_after, integer()|undefined}</tag>
- <item>When an integer-value is specified, the <c>ssl_connection</c>
- will go into hibernation after the specified number of milliseconds
- of inactivity, thus reducing its memory footprint. When
- <c>undefined</c> is specified (this is the default), the process
- will never go into hibernation.
+ <p>The CA certificates specified for the connection will be used to
+ construct the certificate chain validating the CRLs.</p>
+
+ <p>The CRLs will be fetched from a local or external cache see
+ <seealso marker="ssl:ssl_crl_cache_api">ssl_crl_cache_api(3)</seealso>.</p>
</item>
- <tag>{user_lookup_fun, {Lookupfun :: fun(), UserState :: term()}}</tag>
+ <tag><c>{crl_cache, {Module :: atom(), {DbHandle :: internal | term(), Args :: list()}}}</c></tag>
<item>
- <p>The lookup fun should be defined as:</p>
+ <p>Module defaults to ssl_crl_cache with <c> DbHandle </c> internal and an
+ empty argument list. The following arguments may be specified for the internal cache.</p>
+ <taglist>
+ <tag><c>{http, timeout()}</c></tag>
+ <item><p>
+ Enables fetching of CRLs specified as http URIs in<seealso
+ marker="public_key:public_key_records"> X509 certificate extensions.</seealso>
+ Requires the OTP inets application.</p>
+ </item>
+ </taglist>
+ </item>
+
+ <tag><c>{partial_chain, fun(Chain::[DerCert]) -> {trusted_ca, DerCert} |
+ unknown_ca }</c></tag>
+ <item><p>Claim an intermediate CA in the chain as trusted. TLS then
+ performs <seealso
+ marker="public_key:public_key#pkix_path_validation-3">public_key:pkix_path_validation/3</seealso>
+ with the selected CA as trusted anchor and the rest of the chain.</p></item>
+
+ <tag><c>{versions, [protocol()]}</c></tag>
+ <item><p>TLS protocol versions supported by started clients and servers.
+ This option overrides the application environment option
+ <c>protocol_version</c>. If the environment option is not set, it defaults
+ to all versions, except SSL-3.0, supported by the SSL application.
+ See also <seealso marker="ssl:ssl_app">ssl(6).</seealso></p></item>
+
+ <tag><c>{hibernate_after, integer()|undefined}</c></tag>
+ <item><p>When an integer-value is specified, <c>ssl_connection</c>
+ goes into hibernation after the specified number of milliseconds
+ of inactivity, thus reducing its memory footprint. When
+ <c>undefined</c> is specified (this is the default), the process
+ never goes into hibernation.</p></item>
+
+ <tag><c>{user_lookup_fun, {Lookupfun :: fun(), UserState :: term()}}</c></tag>
+ <item><p>The lookup fun is to defined as follows:</p>
+
<code>
fun(psk, PSKIdentity ::string(), UserState :: term()) ->
{ok, SharedSecret :: binary()} | error;
@@ -333,104 +397,120 @@ fun(srp, Username :: string(), UserState :: term()) ->
{ok, {SRPParams :: srp_param_type(), Salt :: binary(), DerivedKey :: binary()}} | error.
</code>
- <p>For Pre-Shared Key (PSK) cipher suites, the lookup fun will
- be called by the client and server to determine the shared
- secret. When called by the client, PSKIdentity will be set to the
- hint presented by the server or undefined. When called by the
- server, PSKIdentity is the identity presented by the client.
- </p>
-
- <p>For Secure Remote Password (SRP), the fun will only be used by the server to obtain
- parameters that it will use to generate its session keys. <c>DerivedKey</c> should be
- derived according to <url href="http://tools.ietf.org/html/rfc2945#section-3"> RFC 2945</url> and
- <url href="http://tools.ietf.org/html/rfc5054#section-2.4"> RFC 5054</url>:
- <c>crypto:sha([Salt, crypto:sha([Username, &lt;&lt;$:&gt;&gt;, Password])]) </c>
+ <p>For Pre-Shared Key (PSK) cipher suites, the lookup fun is
+ called by the client and server to determine the shared
+ secret. When called by the client, <c>PSKIdentity</c> is set to the
+ hint presented by the server or to undefined. When called by the
+ server, <c>PSKIdentity</c> is the identity presented by the client.</p>
+
+ <p>For Secure Remote Password (SRP), the fun is only used by the server to
+ obtain parameters that it uses to generate its session keys.
+ <c>DerivedKey</c> is to be derived according to
+ <url href="http://tools.ietf.org/html/rfc2945#section-3"> RFC 2945</url> and
+ <url href="http://tools.ietf.org/html/rfc5054#section-2.4"> RFC 5054</url>:
+ <c>crypto:sha([Salt, crypto:sha([Username, &lt;&lt;$:&gt;&gt;, Password])])</c>
</p>
</item>
- <tag>{padding_check, boolean()}</tag>
- <item>
- <p> This option only affects TLS-1.0 connections.
- If set to false it disables the block cipher padding check
- to be able to interoperate with legacy software.
- </p>
-
- <warning><p> Using this option makes TLS vulnerable to
- the Poodle attack</p></warning>
-
- </item>
-
+ <tag><c>{padding_check, boolean()}</c></tag>
+ <item><p>Affects TLS-1.0 connections only.
+ If set to <c>false</c>, it disables the block cipher padding check
+ to be able to interoperate with legacy software.</p></item>
+
</taglist>
-
+
+ <warning><p>Using <c>{padding_check, boolean()}</c> makes TLS
+ vulnerable to the Poodle attack.</p></warning>
</section>
<section>
<title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title>
- <p>Options described here are client specific or has a slightly different
- meaning in the client than in the server.</p>
+ <p>The following options are client-specific or have a slightly different
+ meaning in the client than in the server:</p>
<taglist>
- <tag>{verify, verify_type()}</tag>
- <item> In verify_none mode the default behavior will be to
- allow all x509-path validation errors. See also the verify_fun
- option.
- </item>
- <tag>{reuse_sessions, boolean()}</tag>
- <item>Specifies if client should try to reuse sessions
- when possible.
+
+ <tag><c>{verify, verify_type()}</c></tag>
+ <item><p>In mode <c>verify_none</c> the default behavior is to allow
+ all x509-path validation errors. See also option <c>verify_fun</c>.</p>
</item>
+
+ <tag><c>{reuse_sessions, boolean()}</c></tag>
+ <item><p>Specifies if the client is to try to reuse sessions
+ when possible.</p></item>
+
+ <tag><c>{cacerts, [public_key:der_encoded()]}</c></tag>
+ <item><p>The DER-encoded trusted certificates. If this option
+ is supplied it overrides option <c>cacertfile</c>.</p></item>
- <tag>{cacertfile, path()}</tag>
- <item>The path to a file containing PEM encoded CA certificates. The CA
+ <tag><c>{cacertfile, path()}</c></tag>
+ <item><p>Path to a file containing PEM-encoded CA certificates. The CA
certificates are used during server authentication and when building the
- client certificate chain.
- </item>
-
- <tag>{client_preferred_next_protocols, {Precedence :: server | client, ClientPrefs :: [binary()]}}</tag>
- <tag>{client_preferred_next_protocols, {Precedence :: server | client, ClientPrefs :: [binary()], Default :: binary()}}</tag>
+ client certificate chain.</p>
+ </item>
+
+ <tag><c>{alpn_advertised_protocols, [binary()]}</c></tag>
+ <item>
+ <p>The list of protocols supported by the client to be sent to the
+ server to be used for an Application-Layer Protocol Negotiation (ALPN).
+ If the server supports ALPN then it will choose a protocol from this
+ list; otherwise it will fail the connection with a "no_application_protocol"
+ alert. A server that does not support ALPN will ignore this value.</p>
+
+ <p>The list of protocols must not contain an empty binary.</p>
+
+ <p>The negotiated protocol can be retrieved using the <c>negotiated_protocol/1</c> function.</p>
+ </item>
+
+ <tag><c>{client_preferred_next_protocols, {Precedence :: server | client, ClientPrefs :: [binary()]}}</c><br/>
+ <c>{client_preferred_next_protocols, {Precedence :: server | client, ClientPrefs :: [binary()], Default :: binary()}}</c></tag>
<item>
- <p>Indicates the client will try to perform Next Protocol
+ <p>Indicates that the client is to try to perform Next Protocol
Negotiation.</p>
- <p>If precedence is server the negotiated protocol will be the
- first protocol that appears on the server advertised list that is
+ <p>If precedence is server, the negotiated protocol is the
+ first protocol to be shown on the server advertised list, which is
also on the client preference list.</p>
- <p>If precedence is client the negotiated protocol will be the
- first protocol that appears on the client preference list that is
+ <p>If precedence is client, the negotiated protocol is the
+ first protocol to be shown on the client preference list, which is
also on the server advertised list.</p>
<p>If the client does not support any of the server advertised
- protocols or the server does not advertise any protocols the
- client will fallback to the first protocol in its list or if a
- default is supplied it will fallback to that instead. If the
- server does not support Next Protocol Negotiation the
- connection will be aborted if no default protocol is supplied.</p>
+ protocols or the server does not advertise any protocols, the
+ client falls back to the first protocol in its list or to the
+ default protocol (if a default is supplied). If the
+ server does not support Next Protocol Negotiation, the
+ connection terminates if no default protocol is supplied.</p>
</item>
- <tag>{psk_identity, string()}</tag>
- <item>Specifies the identity the client presents to the server. The matching secret is
- found by calling the user_look_fun.
- </item>
- <tag>{srp_identity, {Username :: string(), Password :: string()}</tag>
- <item>Specifies the Username and Password to use to authenticate to the server.
+ <tag><c>{psk_identity, string()}</c></tag>
+ <item><p>Specifies the identity the client presents to the server.
+ The matching secret is found by calling <c>user_lookup_fun</c>.</p>
</item>
- <tag>{server_name_indication, hostname()}</tag>
- <tag>{server_name_indication, disable}</tag>
+
+ <tag><c>{srp_identity, {Username :: string(), Password :: string()}
+ </c></tag>
+ <item><p>Specifies the username and password to use to authenticate
+ to the server.</p></item>
+
+ <tag><c>{server_name_indication, hostname()}</c></tag>
+ <item><p>Can be specified when upgrading a TCP socket to a TLS
+ socket to use the TLS Server Name Indication extension.</p></item>
+
+ <tag><c>{server_name_indication, disable}</c></tag>
<item>
- <p>This option can be specified when upgrading a TCP socket to a TLS
- socket to use the TLS Server Name Indication extension.</p>
- <p>When starting a TLS connection without upgrade the Server Name
- Indication extension will be sent if possible, this option may also be
+ <p>When starting a TLS connection without upgrade, the Server Name
+ Indication extension is sent if possible. This option can be
used to disable that behavior.</p>
</item>
- <tag>{fallback, boolean()}</tag>
+ <tag><c>{fallback, boolean()}</c></tag>
<item>
<p> Send special cipher suite TLS_FALLBACK_SCSV to avoid undesired TLS version downgrade.
Defaults to false</p>
<warning><p>Note this option is not needed in normal TLS usage and should not be used
- to implement new clients. But legacy clients that that retries connections in the following manner</p>
+ to implement new clients. But legacy clients that retries connections in the following manner</p>
<p><c> ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1', 'sslv3']}])</c></p>
<p><c> ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1', 'sslv3']}, {fallback, true}])</c></p>
@@ -441,130 +521,215 @@ fun(srp, Username :: string(), UserState :: term()) ->
be supported by the server for the prevention to work.
</p></warning>
</item>
-
- </taglist>
+ <tag><marker id="client_signature_algs"/><c>{signature_algs, [{hash(), ecdsa | rsa | dsa}]}</c></tag>
+ <item>
+ <p>In addition to the algorithms negotiated by the cipher
+ suite used for key exchange, payload encryption, message
+ authentication and pseudo random calculation, the TLS signature
+ algorithm extension <url
+ href="http://www.ietf.org/rfc/rfc5246.txt">Section 7.4.1.4.1 in RFC 5246</url> may be
+ used, from TLS 1.2, to negotiate which signature algorithm to use during the
+ TLS handshake. If no lower TLS versions than 1.2 are supported,
+ the client will send a TLS signature algorithm extension
+ with the algorithms specified by this option.
+ Defaults to
+
+ <code>[
+%% SHA2
+{sha512, ecdsa},
+{sha512, rsa},
+{sha384, ecdsa},
+{sha384, rsa},
+{sha256, ecdsa},
+{sha256, rsa},
+{sha224, ecdsa},
+{sha224, rsa},
+%% SHA
+{sha, ecdsa},
+{sha, rsa},
+{sha, dsa},
+%% MD5
+{md5, rsa}
+]</code>
+
+ The algorithms should be in the preferred order.
+ Selected signature algorithm can restrict which hash functions
+ that may be selected.
+ </p>
+ </item>
+ </taglist>
</section>
-
+
<section>
<title>SSL OPTION DESCRIPTIONS - SERVER SIDE</title>
- <p>Options described here are server specific or has a slightly different
- meaning in the server than in the client.</p>
+ <p>The following options are server-specific or have a slightly different
+ meaning in the server than in the client:</p>
<taglist>
+
+ <tag><c>{cacerts, [public_key:der_encoded()]}</c></tag>
+ <item><p>The DER-encoded trusted certificates. If this option
+ is supplied it overrides option <c>cacertfile</c>.</p></item>
- <tag>{cacertfile, path()}</tag>
- <item>The path to a file containing PEM encoded CA
+ <tag><c>{cacertfile, path()}</c></tag>
+ <item><p>Path to a file containing PEM-encoded CA
certificates. The CA certificates are used to build the server
- certificate chain, and for client authentication. Also the CAs
- are used in the list of acceptable client CAs passed to the
- client when a certificate is requested. May be omitted if there
- is no need to verify the client and if there are not any
- intermediate CAs for the server certificate.
- </item>
+ certificate chain and for client authentication. The CAs are
+ also used in the list of acceptable client CAs passed to the
+ client when a certificate is requested. Can be omitted if there
+ is no need to verify the client and if there are no
+ intermediate CAs for the server certificate.</p></item>
- <tag>{dh, der_encoded()}</tag>
- <item>The DER encoded Diffie Hellman parameters. If this option
- is supplied it will override the dhfile option.
+ <tag><c>{dh, public_key:der_encoded()}</c></tag>
+ <item><p>The DER-encoded Diffie-Hellman parameters. If specified,
+ it overrides option <c>dhfile</c>.</p></item>
+
+ <tag><c>{dhfile, path()}</c></tag>
+ <item><p>Path to a file containing PEM-encoded Diffie Hellman parameters
+ to be used by the server if a cipher suite using Diffie Hellman key
+ exchange is negotiated. If not specified, default parameters are used.
+ </p></item>
+
+ <tag><c>{verify, verify_type()}</c></tag>
+ <item><p>A server only does x509-path validation in mode <c>verify_peer</c>,
+ as it then sends a certificate request to the client
+ (this message is not sent if the verify option is <c>verify_none</c>).
+ You can then also want to specify option <c>fail_if_no_peer_cert</c>.
+ </p></item>
+
+ <tag><c>{fail_if_no_peer_cert, boolean()}</c></tag>
+ <item><p>Used together with <c>{verify, verify_peer}</c> by an SSL server.
+ If set to <c>true</c>, the server fails if the client does not have
+ a certificate to send, that is, sends an empty certificate. If set to
+ <c>false</c>, it fails only if the client sends an invalid
+ certificate (an empty certificate is considered valid). Defaults to false.</p>
</item>
- <tag>{dhfile, path()}</tag>
- <item>Path to file containing PEM encoded Diffie Hellman parameters,
- for the server to use if a cipher suite using Diffie Hellman key exchange
- is negotiated. If not specified default parameters will be used.
- </item>
-
- <tag>{verify, verify_type()}</tag>
- <item>Servers only do the x509-path validation in verify_peer
- mode, as it then will send a certificate request to the client
- (this message is not sent if the verify option is verify_none)
- and you may then also want to specify the option
- fail_if_no_peer_cert.
- </item>
+ <tag><c>{reuse_sessions, boolean()}</c></tag>
+ <item><p>Specifies if the server is to agree to reuse sessions
+ when requested by the clients. See also option <c>reuse_session</c>.
+ </p></item>
+
+ <tag><c>{reuse_session, fun(SuggestedSessionId,
+ PeerCert, Compression, CipherSuite) -> boolean()}</c></tag>
+ <item><p>Enables the SSL server to have a local policy
+ for deciding if a session is to be reused or not.
+ Meaningful only if <c>reuse_sessions</c> is set to <c>true</c>.
+ <c>SuggestedSessionId</c> is a <c>binary()</c>, <c>PeerCert</c> is
+ a DER-encoded certificate, <c>Compression</c> is an enumeration integer,
+ and <c>CipherSuite</c> is of type <c>ciphersuite()</c>.</p></item>
+
+ <tag><c>{alpn_preferred_protocols, [binary()]}</c></tag>
+ <item>
+ <p>Indicates the server will try to perform Application-Layer
+ Protocol Negotiation (ALPN).</p>
- <tag>{fail_if_no_peer_cert, boolean()}</tag>
- <item>Used together with {verify, verify_peer} by an ssl server.
- If set to true, the server will fail if the client does not have
- a certificate to send, i.e. sends a empty certificate, if set to
- false it will only fail if the client sends an invalid
- certificate (an empty certificate is considered valid).
- </item>
+ <p>The list of protocols is in order of preference. The protocol
+ negotiated will be the first in the list that matches one of the
+ protocols advertised by the client. If no protocol matches, the
+ server will fail the connection with a "no_application_protocol" alert.</p>
- <tag>{reuse_sessions, boolean()}</tag>
- <item>Specifies if the server should agree to reuse sessions
- when the clients request to do so. See also the reuse_session
- option.
+ <p>The negotiated protocol can be retrieved using the <c>negotiated_protocol/1</c> function.</p>
</item>
- <tag>{reuse_session, fun(SuggestedSessionId,
- PeerCert, Compression, CipherSuite) -> boolean()}</tag>
- <item>Enables the ssl server to have a local policy
- for deciding if a session should be reused or not,
- only meaningful if <c>reuse_sessions</c> is set to true.
- SuggestedSessionId is a binary(), PeerCert is a DER encoded
- certificate, Compression is an enumeration integer
- and CipherSuite is of type ciphersuite().
- </item>
-
- <tag>{next_protocols_advertised, Protocols :: [binary()]}</tag>
- <item>The list of protocols to send to the client if the client indicates
- it supports the Next Protocol extension. The client may select a protocol
+ <tag><c>{next_protocols_advertised, Protocols :: [binary()]}</c></tag>
+ <item><p>List of protocols to send to the client if the client indicates that
+ it supports the Next Protocol extension. The client can select a protocol
that is not on this list. The list of protocols must not contain an empty
- binary. If the server negotiates a Next Protocol it can be accessed
- using <c>negotiated_next_protocol/1</c> method.
+ binary. If the server negotiates a Next Protocol, it can be accessed
+ using the <c>negotiated_next_protocol/1</c> method.</p></item>
+
+ <tag><c>{psk_identity, string()}</c></tag>
+ <item><p>Specifies the server identity hint, which the server presents to
+ the client.</p></item>
+
+ <tag><c>{log_alert, boolean()}</c></tag>
+ <item><p>If set to <c>false</c>, error reports are not displayed.</p></item>
+
+ <tag><c>{honor_cipher_order, boolean()}</c></tag>
+ <item><p>If set to <c>true</c>, use the server preference for cipher
+ selection. If set to <c>false</c> (the default), use the client
+ preference.</p></item>
+
+ <tag><c>{sni_hosts, [{hostname(), ssloptions()}]}</c></tag>
+ <item><p>If the server receives a SNI (Server Name Indication) from the client
+ matching a host listed in the <c>sni_hosts</c> option, the specific options for
+ that host will override previously specified options.
+
+ The option <c>sni_fun</c>, and <c>sni_hosts</c> are mutually exclusive.</p></item>
+
+ <tag><c>{sni_fun, SNIfun::fun()}</c></tag>
+ <item><p>If the server receives a SNI (Server Name Indication) from the client,
+ the given function will be called to retrieve <c>ssloptions()</c> for the indicated server.
+ These options will be merged into predefined <c>ssloptions()</c>.
+
+ The function should be defined as:
+ <c>fun(ServerName :: string()) -> ssloptions()</c>
+ and can be specified as a fun or as named <c>fun module:function/1</c>
+
+ The option <c>sni_fun</c>, and <c>sni_hosts</c> are mutually exclusive.</p></item>
+
+ <tag><c>{client_renegotiation, boolean()}</c></tag>
+ <item>In protocols that support client-initiated renegotiation, the cost
+ of resources of such an operation is higher for the server than the
+ client. This can act as a vector for denial of service attacks. The SSL
+ application already takes measures to counter-act such attempts,
+ but client-initiated renegotiation can be strictly disabled by setting
+ this option to <c>false</c>. The default value is <c>true</c>.
+ Note that disabling renegotiation can result in long-lived connections
+ becoming unusable due to limits on the number of messages the underlying
+ cipher suite can encipher.
</item>
- <tag>{psk_identity, string()}</tag>
- <item>Specifies the server identity hint the server presents to the client.
- </item>
- <tag>{log_alert, boolean()}</tag>
- <item>If false, error reports will not be displayed.</item>
- <tag>{honor_cipher_order, boolean()}</tag>
+ <tag><c>{honor_cipher_order, boolean()}</c></tag>
<item>If true, use the server's preference for cipher 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
+ negotiation, introduced in TLS-1.2. The algorithms will also be offered to the client if a
+ client certificate is requested. For more details see the <seealso marker="#client_signature_algs">corresponding client option</seealso>.
+ </p> </item>
+
</taglist>
</section>
<section>
<title>General</title>
- <p>When an ssl socket is in active mode (the default), data from the
+ <p>When an SSL socket is in active mode (the default), data from the
socket is delivered to the owner of the socket in the form of
- messages:
- </p>
+ messages:</p>
+
<list type="bulleted">
- <item>{ssl, Socket, Data}
- </item>
- <item>{ssl_closed, Socket}
- </item>
- <item>
- {ssl_error, Socket, Reason}
- </item>
+ <item><p><c>{ssl, Socket, Data}</c></p></item>
+ <item><p><c>{ssl_closed, Socket}</c></p></item>
+ <item><p><c>{ssl_error, Socket, Reason}</c></p></item>
</list>
-
- <p>A <c>Timeout</c> argument specifies a timeout in milliseconds. The
- default value for a <c>Timeout</c> argument is <c>infinity</c>.
- </p>
+
+ <p>A <c>Timeout</c> argument specifies a time-out in milliseconds. The
+ default value for argument <c>Timeout</c> is <c>infinity</c>.</p>
</section>
<funcs>
<func>
<name>cipher_suites() -></name>
<name>cipher_suites(Type) -> ciphers()</name>
- <fsummary> Returns a list of supported cipher suites</fsummary>
+ <fsummary>Returns a list of supported cipher suites.</fsummary>
<type>
<v>Type = erlang | openssl | all</v>
-
</type>
<desc><p>Returns a list of supported cipher suites.
- cipher_suites() is equivalent to cipher_suites(erlang).
- Type openssl is provided for backwards compatibility with
- old ssl that used openssl. cipher_suites(all) returns
+ <c>cipher_suites()</c> is equivalent to <c>cipher_suites(erlang).</c>
+ Type <c>openssl</c> is provided for backwards compatibility with the
+ old SSL, which used OpenSSL. <c>cipher_suites(all)</c> returns
all available cipher suites. The cipher suites not present
- in cipher_suites(erlang) but in included in cipher_suites(all)
- will not be used unless explicitly configured by the user.
- </p>
+ in <c>cipher_suites(erlang)</c> but included in
+ <c>cipher_suites(all)</c> are not used unless explicitly configured
+ by the user.</p>
</desc>
</func>
@@ -584,17 +749,17 @@ fun(srp, Username :: string(), UserState :: term()) ->
<name>connect(Socket, SslOptions) -> </name>
<name>connect(Socket, SslOptions, Timeout) -> {ok, SslSocket}
| {error, Reason}</name>
- <fsummary> Upgrades a gen_tcp, or
- equivalent, connected socket to an ssl socket. </fsummary>
+ <fsummary>Upgrades a <c>gen_tcp</c>, or
+ equivalent, connected socket to an SSL socket.</fsummary>
<type>
- <v>Socket = socket()</v>
- <v>SslOptions = [ssloption()]</v>
+ <v>Socket = socket()</v>
+ <v>SslOptions = [ssloption()]</v>
<v>Timeout = integer() | infinity</v>
<v>SslSocket = sslsocket()</v>
<v>Reason = term()</v>
</type>
- <desc> <p>Upgrades a gen_tcp, or equivalent,
- connected socket to an ssl socket i.e. performs the
+ <desc><p>Upgrades a <c>gen_tcp</c>, or equivalent,
+ connected socket to an SSL socket, that is, performs the
client-side ssl handshake.</p>
</desc>
</func>
@@ -603,7 +768,7 @@ fun(srp, Username :: string(), UserState :: term()) ->
<name>connect(Host, Port, Options) -></name>
<name>connect(Host, Port, Options, Timeout) ->
{ok, SslSocket} | {error, Reason}</name>
- <fsummary>Opens an ssl connection to Host, Port. </fsummary>
+ <fsummary>Opens an SSL connection to <c>Host</c>, <c>Port</c>.</fsummary>
<type>
<v>Host = host()</v>
<v>Port = integer()</v>
@@ -612,72 +777,107 @@ fun(srp, Username :: string(), UserState :: term()) ->
<v>SslSocket = sslsocket()</v>
<v>Reason = term()</v>
</type>
- <desc> <p>Opens an ssl connection to Host, Port.</p> </desc>
+ <desc><p>Opens an SSL connection to <c>Host</c>, <c>Port</c>.</p></desc>
</func>
<func>
<name>close(SslSocket) -> ok | {error, Reason}</name>
- <fsummary>Close an ssl connection</fsummary>
+ <fsummary>Closes an SSL connection.</fsummary>
<type>
<v>SslSocket = sslsocket()</v>
<v>Reason = term()</v>
</type>
- <desc><p>Close an ssl connection.</p>
+ <desc><p>Closes an SSL connection.</p>
</desc>
</func>
<func>
+ <name>close(SslSocket, How) -> ok | {ok, port()} | {error, Reason}</name>
+ <fsummary>Closes an SSL connection.</fsummary>
+ <type>
+ <v>SslSocket = sslsocket()</v>
+ <v>How = timeout() | {NewController::pid(), timeout()} </v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><p>Closes or downgrades an SSL connection. In the latter case the transport
+ connection will be handed over to the <c>NewController</c> process after receiving
+ the TLS close alert from the peer. The returned transport socket will have
+ the following options set: <c>[{active, false}, {packet, 0}, {mode, binary}]</c></p>
+ </desc>
+ </func>
+
+ <func>
<name>controlling_process(SslSocket, NewOwner) ->
ok | {error, Reason}</name>
-
<fsummary>Assigns a new controlling process to the
- ssl-socket.</fsummary>
-
+ SSL socket.</fsummary>
<type>
<v>SslSocket = sslsocket()</v>
<v>NewOwner = pid()</v>
<v>Reason = term()</v>
</type>
- <desc><p>Assigns a new controlling process to the ssl-socket. A
- controlling process is the owner of an ssl-socket, and receives
- all messages from the socket.</p>
+ <desc><p>Assigns a new controlling process to the SSL socket. A
+ controlling process is the owner of an SSL socket, and receives
+ all messages from the socket.</p>
</desc>
</func>
<func>
- <name>connection_info(SslSocket) ->
- {ok, {ProtocolVersion, CipherSuite}} | {error, Reason} </name>
- <fsummary>Returns the negotiated protocol version and cipher suite.
+ <name>connection_information(SslSocket) ->
+ {ok, Result} | {error, Reason} </name>
+ <fsummary>Returns all the connection information.
</fsummary>
<type>
- <v>CipherSuite = ciphersuite()</v>
- <v>ProtocolVersion = protocol()</v>
+ <v>Item = protocol | cipher_suite | sni_hostname | 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>
</type>
- <desc><p>Returns the negotiated protocol version and cipher suite.</p>
+ <desc><p>Returns all relevant information about the connection, ssl options that
+ are undefined will be filtered out.</p>
</desc>
</func>
- <func>
+ <func>
+ <name>connection_information(SslSocket, Items) ->
+ {ok, Result} | {error, Reason} </name>
+ <fsummary>Returns the requested connection information.
+ </fsummary>
+ <type>
+ <v>Items = [Item]</v>
+ <v>Item = protocol | cipher_suite | sni_hostname | 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>
+ </type>
+ <desc><p>Returns the requested information items about the connection,
+ if they are defined.</p>
+ <note><p>If only undefined options are requested the
+ resulting list can be empty.</p></note>
+ </desc>
+ </func>
+
+ <func>
<name>format_error(Reason) -> string()</name>
- <fsummary>Return an error string.</fsummary>
+ <fsummary>Returns an error string.</fsummary>
<type>
<v>Reason = term()</v>
</type>
<desc>
- <p>Presents the error returned by an ssl function as a printable string.</p>
+ <p>Presents the error returned by an SSL function as a printable string.</p>
</desc>
</func>
<func>
<name>getopts(Socket, OptionNames) ->
{ok, [socketoption()]} | {error, Reason}</name>
- <fsummary>Get the value of the specified options.</fsummary>
+ <fsummary>Gets the values of the specified options.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>OptionNames = [atom()]</v>
</type>
<desc>
- <p>Get the value of the specified socket options.
+ <p>Gets the values of the specified socket options.
</p>
</desc>
</func>
@@ -685,34 +885,49 @@ fun(srp, Username :: string(), UserState :: term()) ->
<func>
<name>listen(Port, Options) ->
{ok, ListenSocket} | {error, Reason}</name>
- <fsummary>Creates an ssl listen socket.</fsummary>
+ <fsummary>Creates an SSL listen socket.</fsummary>
<type>
<v>Port = integer()</v>
<v>Options = options()</v>
<v>ListenSocket = sslsocket()</v>
</type>
<desc>
- <p>Creates an ssl listen socket.</p>
+ <p>Creates an SSL listen socket.</p>
</desc>
</func>
<func>
+ <name>negotiated_protocol(Socket) -> {ok, Protocol} | {error, protocol_not_negotiated}</name>
+ <fsummary>Returns the protocol negotiated through ALPN or NPN extensions.</fsummary>
+ <type>
+ <v>Socket = sslsocket()</v>
+ <v>Protocol = binary()</v>
+ </type>
+ <desc>
+ <p>
+ Returns the protocol negotiated through ALPN or NPN extensions.
+ </p>
+ </desc>
+ </func>
+
+ <func>
<name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name>
- <fsummary>Return the peer certificate.</fsummary>
+ <fsummary>Returns the peer certificate.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Cert = binary()</v>
</type>
<desc>
- <p>The peer certificate is returned as a DER encoded binary.
- The certificate can be decoded with <c>public_key:pkix_decode_cert/2</c>.
- </p>
+ <p>The peer certificate is returned as a DER-encoded binary.
+ The certificate can be decoded with
+ <c>public_key:pkix_decode_cert/2</c>.</p>
</desc>
</func>
+
<func>
<name>peername(Socket) -> {ok, {Address, Port}} |
{error, Reason}</name>
- <fsummary>Return peer address and port.</fsummary>
+ <fsummary>Returns the peer address and port.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Address = ipaddress()</v>
@@ -722,12 +937,32 @@ fun(srp, Username :: string(), UserState :: term()) ->
<p>Returns the address and port number of the peer.</p>
</desc>
</func>
+
+ <func>
+ <name>prf(Socket, Secret, Label, Seed, WantedLength) -> {ok, binary()} | {error, reason()}</name>
+ <fsummary>Uses a session Pseudo-Random Function to generate key material.</fsummary>
+ <type>
+ <v>Socket = sslsocket()</v>
+ <v>Secret = binary() | master_secret</v>
+ <v>Label = binary()</v>
+ <v>Seed = [binary() | prf_random()]</v>
+ <v>WantedLength = non_neg_integer()</v>
+ </type>
+ <desc>
+ <p>Uses the Pseudo-Random Function (PRF) of a TLS session to generate
+ extra key material. It either takes user-generated values for
+ <c>Secret</c> and <c>Seed</c> or atoms directing it to use a specific
+ value from the session security parameters.</p>
+ <p>Can only be used with TLS connections; <c>{error, undefined}</c>
+ is returned for SSLv3 connections.</p>
+ </desc>
+ </func>
<func>
<name>recv(Socket, Length) -> </name>
<name>recv(Socket, Length, Timeout) -> {ok, Data} | {error,
Reason}</name>
- <fsummary>Receive data on a socket.</fsummary>
+ <fsummary>Receives data on a socket.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Length = integer()</v>
@@ -735,63 +970,43 @@ fun(srp, Username :: string(), UserState :: term()) ->
<v>Data = [char()] | binary()</v>
</type>
<desc>
- <p>This function receives a packet from a socket in passive
- mode. A closed socket is indicated by a return value
+ <p>Receives a packet from a socket in passive
+ mode. A closed socket is indicated by return value
<c>{error, closed}</c>.</p>
- <p>The <c>Length</c> argument is only meaningful when
- the socket is in <c>raw</c> mode and denotes the number of
+ <p>Argument <c>Length</c> is meaningful only when
+ the socket is in mode <c>raw</c> and denotes the number of
bytes to read. If <c>Length</c> = 0, all available bytes are
returned. If <c>Length</c> &gt; 0, exactly <c>Length</c>
bytes are returned, or an error; possibly discarding less
than <c>Length</c> bytes of data when the socket gets closed
from the other side.</p>
- <p>The optional <c>Timeout</c> parameter specifies a timeout in
+ <p>Optional argument <c>Timeout</c> specifies a time-out in
milliseconds. The default value is <c>infinity</c>.</p>
</desc>
</func>
<func>
- <name>prf(Socket, Secret, Label, Seed, WantedLength) -> {ok, binary()} | {error, reason()}</name>
- <fsummary>Use a sessions pseudo random function to generate key material.</fsummary>
- <type>
- <v>Socket = sslsocket()</v>
- <v>Secret = binary() | master_secret</v>
- <v>Label = binary()</v>
- <v>Seed = [binary() | prf_random()]</v>
- <v>WantedLength = non_neg_integer()</v>
- </type>
- <desc>
- <p>Use the pseudo random function (PRF) of a TLS session to generate
- additional key material. It either takes user generated values for
- <c>Secret</c> and <c>Seed</c> or atoms directing it use a specific
- value from the session security parameters.</p>
- <p>This function can only be used with TLS connections, <c>{error, undefined}</c>
- is returned for SSLv3 connections.</p>
- </desc>
- </func>
-
- <func>
<name>renegotiate(Socket) -> ok | {error, Reason}</name>
- <fsummary> Initiates a new handshake.</fsummary>
+ <fsummary>Initiates a new handshake.</fsummary>
<type>
<v>Socket = sslsocket()</v>
</type>
<desc><p>Initiates a new handshake. A notable return value is
<c>{error, renegotiation_rejected}</c> indicating that the peer
- refused to go through with the renegotiation but the connection
+ refused to go through with the renegotiation, but the connection
is still active using the previously negotiated session.</p>
</desc>
</func>
<func>
<name>send(Socket, Data) -> ok | {error, Reason}</name>
- <fsummary>Write data to a socket.</fsummary>
+ <fsummary>Writes data to a socket.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Data = iodata()</v>
</type>
<desc>
- <p>Writes <c>Data</c> to <c>Socket</c>. </p>
+ <p>Writes <c>Data</c> to <c>Socket</c>.</p>
<p>A notable return value is <c>{error, closed}</c> indicating that
the socket is closed.</p>
</desc>
@@ -799,31 +1014,31 @@ fun(srp, Username :: string(), UserState :: term()) ->
<func>
<name>setopts(Socket, Options) -> ok | {error, Reason}</name>
- <fsummary>Set socket options.</fsummary>
+ <fsummary>Sets socket options.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Options = [socketoption]()</v>
</type>
<desc>
- <p>Sets options according to <c>Options</c> for the socket
- <c>Socket</c>. </p>
+ <p>Sets options according to <c>Options</c> for socket
+ <c>Socket</c>.</p>
</desc>
</func>
<func>
<name>shutdown(Socket, How) -> ok | {error, Reason}</name>
- <fsummary>Immediately close a socket</fsummary>
+ <fsummary>Immediately closes a socket.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>How = read | write | read_write</v>
<v>Reason = reason()</v>
</type>
<desc>
- <p>Immediately close a socket in one or two directions.</p>
+ <p>Immediately closes a socket in one or two directions.</p>
<p><c>How == write</c> means closing the socket for writing,
reading from it is still possible.</p>
<p>To be able to handle that the peer has done a shutdown on
- the write side, the <c>{exit_on_close, false}</c> option
+ the write side, option <c>{exit_on_close, false}</c>
is useful.</p>
</desc>
</func>
@@ -831,16 +1046,16 @@ fun(srp, Username :: string(), UserState :: term()) ->
<func>
<name>ssl_accept(Socket) -> </name>
<name>ssl_accept(Socket, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Perform server-side SSL/TLS handshake</fsummary>
+ <fsummary>Performs server-side SSL/TLS handshake.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Timeout = integer()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p> Performs the SSL/TLS server-side handshake <c>Socket</c> is a socket as returned
- by <seealso
- marker="#transport_accept-2">ssl:transport_accept/[1,2]</seealso>
+ <p>Performs the SSL/TLS server-side handshake.</p>
+ <p><c>Socket</c> is a socket as returned by
+ <seealso marker="#transport_accept-2">ssl:transport_accept/[1,2]</seealso>
</p>
</desc>
</func>
@@ -848,7 +1063,7 @@ fun(srp, Username :: string(), UserState :: term()) ->
<func>
<name>ssl_accept(Socket, SslOptions) -> </name>
<name>ssl_accept(Socket, SslOptions, Timeout) -> {ok, Socket} | ok | {error, Reason}</name>
- <fsummary>Perform server-side SSL/TLS handshake</fsummary>
+ <fsummary>Performs server-side SSL/TLS handshake.</fsummary>
<type>
<v>Socket = socket() | sslsocket() </v>
<v>SslOptions = ssloptions()</v>
@@ -856,17 +1071,19 @@ fun(srp, Username :: string(), UserState :: term()) ->
<v>Reason = term()</v>
</type>
<desc>
- <p> If <c>Socket</c> is a socket() - upgrades a gen_tcp, or equivalent, socket to an ssl socket
- i.e. performs the SSL/TLS server-side handshake and returns the ssl socket.
- </p>
+ <p>If <c>Socket</c> is a <c>socket()</c>: upgrades a <c>gen_tcp</c>,
+ or equivalent, socket to an SSL socket, that is, performs
+ the SSL/TLS server-side handshake and returns the SSL socket.</p>
- <warning><p>Note that the listen socket should be in {active, false} mode
+ <warning><p>The listen socket is to be in mode <c>{active, false}</c>
before telling the client that the server is ready to upgrade
- by calling this function, otherwise the upgrade may
- or may not succeed depending on timing.</p></warning>
+ by calling this function, else the upgrade succeeds or does not
+ succeed depending on timing.</p></warning>
- <p> If <c>Socket</c> is an sslsocket() - provides additional SSL/TLS options to those specified in <seealso
- marker="#listen-2">ssl:listen/2 </seealso> and then performs the SSL/TLS handshake.
+ <p>If <c>Socket</c> is an <c>sslsocket()</c>: provides extra SSL/TLS
+ options to those specified in
+ <seealso marker="#listen-2">ssl:listen/2 </seealso> and then performs
+ the SSL/TLS handshake.
</p>
</desc>
</func>
@@ -874,14 +1091,14 @@ fun(srp, Username :: string(), UserState :: term()) ->
<func>
<name>sockname(Socket) -> {ok, {Address, Port}} |
{error, Reason}</name>
- <fsummary>Return the local address and port.</fsummary>
+ <fsummary>Returns the local address and port.</fsummary>
<type>
<v>Socket = sslsocket()</v>
<v>Address = ipaddress()</v>
<v>Port = integer()</v>
</type>
<desc>
- <p>Returns the local address and port number of the socket
+ <p>Returns the local address and port number of socket
<c>Socket</c>.</p>
</desc>
</func>
@@ -889,22 +1106,21 @@ fun(srp, Username :: string(), UserState :: term()) ->
<func>
<name>start() -> </name>
<name>start(Type) -> ok | {error, Reason}</name>
- <fsummary>Starts the Ssl application. </fsummary>
+ <fsummary>Starts the SSL application.</fsummary>
<type>
- <v>Type = permanent | transient | temporary</v>
+ <v>Type = permanent | transient | temporary</v>
</type>
<desc>
- <p>Starts the Ssl application. Default type
- is temporary.
- <seealso marker="kernel:application">application(3)</seealso></p>
+ <p>Starts the SSL application. Default type
+ is <c>temporary</c>.</p>
</desc>
</func>
+
<func>
<name>stop() -> ok </name>
- <fsummary>Stops the Ssl application.</fsummary>
+ <fsummary>Stops the SSL application.</fsummary>
<desc>
- <p>Stops the Ssl application.
- <seealso marker="kernel:application">application(3)</seealso></p>
+ <p>Stops the SSL application.</p>
</desc>
</func>
@@ -912,8 +1128,8 @@ fun(srp, Username :: string(), UserState :: term()) ->
<name>transport_accept(ListenSocket) -></name>
<name>transport_accept(ListenSocket, Timeout) ->
{ok, NewSocket} | {error, Reason}</name>
- <fsummary>Accept an incoming connection and
- prepare for <c>ssl_accept</c></fsummary>
+ <fsummary>Accepts an incoming connection and
+ prepares for <c>ssl_accept</c>.</fsummary>
<type>
<v>ListenSocket = NewSocket = sslsocket()</v>
<v>Timeout = integer()</v>
@@ -922,66 +1138,66 @@ fun(srp, Username :: string(), UserState :: term()) ->
<desc>
<p>Accepts an incoming connection request on a listen socket.
<c>ListenSocket</c> must be a socket returned from
- <seealso
- marker="#listen-2"> ssl:listen/2</seealso>.
- The socket returned should be passed to
+ <seealso marker="#listen-2"> ssl:listen/2</seealso>.
+ The socket returned is to be passed to
<seealso marker="#ssl_accept-2"> ssl:ssl_accept[2,3]</seealso>
- to complete handshaking i.e
+ to complete handshaking, that is,
establishing the SSL/TLS connection.</p>
<warning>
<p>The socket returned can only be used with
- <seealso marker="#ssl_accept-2"> ssl:ssl_accept[2,3]</seealso>
- no traffic can be sent or received before that call.</p>
+ <seealso marker="#ssl_accept-2"> ssl:ssl_accept[2,3]</seealso>.
+ No traffic can be sent or received before that call.</p>
</warning>
<p>The accepted socket inherits the options set for
- <c>ListenSocket</c> in <seealso
- marker="#listen-2"> ssl:listen/2</seealso>.</p>
+ <c>ListenSocket</c> in
+ <seealso marker="#listen-2"> ssl:listen/2</seealso>.</p>
<p>The default
value for <c>Timeout</c> is <c>infinity</c>. If
- <c>Timeout</c> is specified, and no connection is accepted
+ <c>Timeout</c> is specified and no connection is accepted
within the given time, <c>{error, timeout}</c> is
returned.</p>
</desc>
</func>
<func>
- <name>versions() ->
- [{SslAppVer, SupportedSslVer, AvailableSslVsn}]</name>
+ <name>versions() -> [versions_info()]</name>
<fsummary>Returns version information relevant for the
- ssl application.</fsummary>
- <type>
- <v>SslAppVer = string()</v>
- <v>SupportedSslVer = [protocol()]</v>
- <v>AvailableSslVsn = [protocol()]</v>
- </type>
- <desc>
- <p>
- Returns version information relevant for the
- ssl application.</p>
- </desc>
- </func>
- <func>
- <name>negotiated_next_protocol(Socket) -> {ok, Protocol} | {error, next_protocol_not_negotiated}</name>
- <fsummary>Returns the Next Protocol negotiated.</fsummary>
+ SSL application.</fsummary>
<type>
- <v>Socket = sslsocket()</v>
- <v>Protocol = binary()</v>
+ <v>versions_info() = {app_vsn, string()} | {supported | available, [protocol()] </v>
</type>
<desc>
- <p>
- Returns the Next Protocol negotiated.
- </p>
+ <p>Returns version information relevant for the SSL
+ application.</p>
+ <taglist>
+ <tag><c>app_vsn</c></tag>
+ <item>The application version of the SSL application.</item>
+
+ <tag><c>supported</c></tag>
+ <item>TLS/SSL versions supported by default.
+ Overridden by a version option on
+ <seealso marker="#connect-2"> connect/[2,3,4]</seealso>,
+ <seealso marker="#listen-2"> listen/2</seealso>, and <seealso
+ marker="#ssl_accept-2">ssl_accept/[1,2,3]</seealso>.
+ For the negotiated TLS/SSL version, see <seealso
+ marker="#connection_information-1">ssl:connection_information/1
+ </seealso>.</item>
+
+ <tag><c>available</c></tag>
+ <item>All TLS/SSL versions supported by the SSL application.
+ TLS 1.2 requires sufficient support from the Crypto
+ application.</item>
+ </taglist>
</desc>
</func>
-
+
</funcs>
<section>
<title>SEE ALSO</title>
- <p><seealso marker="kernel:inet">inet(3) </seealso> and
- <seealso marker="kernel:gen_tcp">gen_tcp(3) </seealso>
+ <p><seealso marker="kernel:inet">inet(3)</seealso> and
+ <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>
</p>
</section>
</erlref>
-
diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml
index f1377cabda..6c82e32a74 100644
--- a/lib/ssl/doc/src/ssl_app.xml
+++ b/lib/ssl/doc/src/ssl_app.xml
@@ -8,80 +8,108 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssl</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
<file>ssl_app.sgml</file>
</header>
<app>ssl</app>
- <appsummary>The SSL application provides secure communication over
+ <appsummary>The ssl application provides secure communication over
sockets.</appsummary>
+ <description>
+ <p>
+ The ssl application is an implementation of the SSL/TLS protocol in Erlang.
+ </p>
+ <list type="bulleted">
+ <item>Supported SSL/TLS-versions are SSL-3.0, TLS-1.0,
+ TLS-1.1, and TLS-1.2.</item>
+ <item>For security reasons SSL-2.0 is not supported.</item>
+ <item>For security reasons SSL-3.0 is no longer supported by default,
+ but can be configured.</item>
+ <item>Ephemeral Diffie-Hellman cipher suites are supported,
+ but not Diffie Hellman Certificates cipher suites.</item>
+ <item>Elliptic Curve cipher suites are supported if the Crypto
+ application supports it and named curves are used.
+ </item>
+ <item>Export cipher suites are not supported as the
+ U.S. lifted its export restrictions in early 2000.</item>
+ <item>IDEA cipher suites are not supported as they have
+ become deprecated by the latest TLS specification so it is not
+ motivated to implement them.</item>
+ <item>CRL validation is supported.</item>
+ <item>Policy certificate extensions are not supported.</item>
+ <item>'Server Name Indication' extension client side
+ (RFC 6066, Section 3) is supported.</item>
+ </list>
+ </description>
+
<section>
<title>DEPENDENCIES</title>
- <p>The ssl application uses the Erlang applications public_key and
- crypto to handle public keys and encryption, hence these
- applications needs to be loaded for the ssl application to work. In
- an embedded environment that means they need to be started with
- application:start/[1,2] before the ssl application is started.
- </p>
+ <p>The SSL application uses the <c>public_key</c> and
+ Crypto application to handle public keys and encryption, hence
+ these applications must be loaded for the SSL application to work.
+ In an embedded environment this means they must be started with
+ <c>application:start/[1,2]</c> before the SSL application is
+ started.</p>
</section>
<section>
- <title>ENVIRONMENT</title>
- <p>The following application environment configuration parameters
- are defined for the SSL application. See <seealso
- marker="kernel:application">application(3)</seealso>for more
- information about configuration parameters.
- </p>
- <p>Note that the environment parameters can be set on the command line,
- for instance,</p>
- <p><c>erl ... -ssl protocol_version '[sslv3, tlsv1]' ...</c>.
- </p>
+ <title>CONFIGURATION</title>
+ <p>The application environment configuration parameters in this section
+ are defined for the SSL application. For more information
+ about configuration parameters, see the
+ <seealso marker="kernel:application">application(3)</seealso>
+ manual page in Kernel.</p>
+
+ <p>The environment parameters can be set on the command line,
+ for example:</p>
+
+ <p><c>erl -ssl protocol_version "['tlsv1.2', 'tlsv1.1']"</c></p>
+
<taglist>
- <tag><c><![CDATA[protocol_version = [sslv3|tlsv1] <optional>]]></c>.</tag>
- <item>
- <p>Protocol that will be supported by started clients and
- servers. If this option is not set it will default to all
- protocols currently supported by the erlang ssl application.
- Note that this option may be overridden by the version option
- to ssl:connect/[2,3] and ssl:listen/2.
- </p>
- </item>
+ <tag><c>protocol_version = </c><seealso marker="ssl#type-protocol">ssl:protocol()</seealso><c><![CDATA[<optional>]]></c></tag>
+ <item><p>Protocol supported by started clients and
+ servers. If this option is not set, it defaults to all
+ protocols currently supported by the SSL application.
+ This option can be overridden by the version option
+ to <c>ssl:connect/[2,3]</c> and <c>ssl:listen/2</c>.</p></item>
<tag><c><![CDATA[session_lifetime = integer() <optional>]]></c></tag>
- <item>
- <p>The lifetime of session data in seconds.
- </p>
- </item>
+ <item><p>Maximum lifetime of the session data in seconds.</p></item>
- <tag><c><![CDATA[session_cb = atom() <optional>]]></c></tag>
- <item>
- <p>
- Name of session cache callback module that implements
- the ssl_session_cache_api behavior, defaults to
- ssl_session_cache.erl.
- </p>
- </item>
+ <tag><c><![CDATA[session_cb = atom() <optional>]]></c></tag>
+ <item><p>Name of the session cache callback module that implements
+ the <c>ssl_session_cache_api</c> behavior. Defaults to
+ <c>ssl_session_cache</c>.</p></item>
- <tag><c><![CDATA[session_cb_init_args = list() <optional>]]></c></tag>
- <item>
- <p>
- List of arguments to the init function in session cache
- callback module, defaults to [].
- </p>
- </item>
+ <tag><c><![CDATA[session_cb_init_args = proplist:proplist() <optional>]]></c></tag>
+
+ <item><p>List of extra user-defined arguments to the <c>init</c> function
+ in the session cache callback module. Defaults to <c>[]</c>.</p></item>
+
+ <tag><c><![CDATA[session_cache_client_max = integer() <optional>]]></c><br/>
+ <c><![CDATA[session_cache_server_max = integer() <optional>]]></c></tag>
+ <item><p>Limits the growth of the clients/servers session cache,
+ if the maximum number of sessions is reached, the current cache entries will
+ be invalidated regardless of their remaining lifetime. Defaults to 1000.
+ </p></item>
<tag><c><![CDATA[ssl_pem_cache_clean = integer() <optional>]]></c></tag>
<item>
@@ -92,10 +120,29 @@
marker="ssl#clear_pem_cache-0">ssl:clear_pem_cache/0</seealso>
</item>
+ <tag><c><![CDATA[alert_timeout = integer() <optional>]]></c></tag>
+ <item>
+ <p>
+ Number of milliseconds between sending of a fatal alert and
+ closing the connection. Waiting a little while improves the
+ peers chances to properly receiving the alert so it may
+ shutdown gracefully. Defaults to 5000 milliseconds.
+ </p>
+ </item>
+
+
</taglist>
</section>
<section>
+ <title>ERROR LOGGER AND EVENT HANDLERS</title>
+ <p>The SSL application uses the default <seealso
+ marker="kernel:error_logger">OTP error logger</seealso> to log
+ unexpected errors and TLS alerts. The logging of TLS alerts may be
+ turned off with the <c>log_alert</c> option. </p>
+ </section>
+
+ <section>
<title>SEE ALSO</title>
<p><seealso marker="kernel:application">application(3)</seealso></p>
</section>
diff --git a/lib/ssl/doc/src/ssl_crl_cache.xml b/lib/ssl/doc/src/ssl_crl_cache.xml
new file mode 100644
index 0000000000..7a67de3971
--- /dev/null
+++ b/lib/ssl/doc/src/ssl_crl_cache.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2015</year><year>2015</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+ </legalnotice>
+ <title>ssl_crl_cache</title>
+ <file>ssl_crl_cache.xml</file>
+ </header>
+
+ <module>ssl_crl_cache</module>
+ <modulesummary>CRL cache </modulesummary>
+ <description>
+ <p>
+ Implements an internal CRL (Certificate Revocation List) cache.
+ In addition to implementing the <seealso
+ marker="ssl_crl_cache_api"> ssl_crl_cache_api</seealso> behaviour
+ the following functions are available.
+ </p>
+ </description>
+
+ <funcs>
+ <func>
+ <name>delete(Entries) -> ok | {error, Reason} </name>
+ <fsummary> </fsummary>
+ <type>
+ <v> Entries = <seealso marker="inets:http_uri">http_uri:uri() </seealso> | {file, string()} | {der, [<seealso
+ marker="public_key:public_key"> public_key:der_encoded() </seealso>]}</v>
+ <v> Reason = term()</v>
+ </type>
+ <desc>
+ <p>Delete CRLs from the ssl applications local cache. </p>
+ </desc>
+ </func>
+ <func>
+ <name>insert(CRLSrc) -> ok | {error, Reason}</name>
+ <name>insert(URI, CRLSrc) -> ok | {error, Reason}</name>
+ <fsummary> </fsummary>
+ <type>
+ <v> CRLSrc = {file, string()} | {der, [ <seealso
+ marker="public_key:public_key"> public_key:der_encoded() </seealso> ]}</v>
+ <v> URI = <seealso marker="inets:http_uri">http_uri:uri() </seealso> </v>
+ <v> Reason = term()</v>
+ </type>
+ <desc>
+ <p>Insert CRLs into the ssl applications local cache. </p>
+ </desc>
+ </func>
+ </funcs>
+</erlref> \ No newline at end of file
diff --git a/lib/ssl/doc/src/ssl_crl_cache_api.xml b/lib/ssl/doc/src/ssl_crl_cache_api.xml
new file mode 100644
index 0000000000..03ac010bfe
--- /dev/null
+++ b/lib/ssl/doc/src/ssl_crl_cache_api.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2015</year><year>2015</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+ </legalnotice>
+ <title>ssl_crl_cache_api</title>
+ <file>ssl_crl_cache_api.xml</file>
+ </header>
+
+ <module>ssl_crl_cache_api</module>
+ <modulesummary>API for a SSL/TLS CRL (Certificate Revocation List) cache.</modulesummary>
+ <description>
+ <p>
+ When SSL/TLS performs certificate path validation according to
+ <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280 </url>
+ it should also perform CRL validation checks. To enable the CRL
+ checks the application needs access to CRLs. A database of CRLs
+ can be set up in many different ways. This module provides the
+ behavior of the API needed to integrate an arbitrary CRL cache
+ with the erlang ssl application. It is also used by the
+ application itself to provide a simple default implementation of
+ a CRL cache.
+ </p>
+ </description>
+
+ <section>
+ <title>DATA TYPES</title>
+
+ <p>The following data types are used in the functions below:
+ </p>
+
+ <taglist>
+
+ <tag><c>cache_ref() =</c></tag>
+ <item>opaque()</item>
+ <tag><c>dist_point() =</c></tag>
+ <item><p>#'DistributionPoint'{} see <seealso
+ marker="public_key:public_key_records"> X509 certificates records</seealso></p></item>
+
+ </taglist>
+
+ </section>
+ <funcs>
+ <func>
+ <name>fresh_crl(DistributionPoint, CRL) -> FreshCRL</name>
+ <fsummary> <c>fun fresh_crl/2 </c> will be used as input option <c>update_crl</c> to
+ public_key:pkix_crls_validate/3 </fsummary>
+ <type>
+ <v> DistributionPoint = dist_point() </v>
+ <v> CRL = [<seealso
+ marker="public_key:public_key">public_key:der_encoded()</seealso>] </v>
+ <v> FreshCRL = [<seealso
+ marker="public_key:public_key">public_key:der_encoded()</seealso>] </v>
+ </type>
+ <desc>
+ <p> <c>fun fresh_crl/2 </c> will be used as input option <c>update_crl</c> to
+ <seealso marker="public_key:public_key#pkix_crls_validate-3">public_key:pkix_crls_validate/3 </seealso> </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>lookup(DistributionPoint, DbHandle) -> not_available | CRLs </name>
+ <fsummary> </fsummary>
+ <type>
+ <v> DistributionPoint = dist_point() </v>
+ <v> DbHandle = cache_ref() </v>
+ <v> CRLs = [<seealso
+ marker="public_key:public_key">public_key:der_encoded()</seealso>] </v>
+ </type>
+ <desc> <p>Lookup the CRLs belonging to the distribution point <c> Distributionpoint</c>.
+ This function may choose to only look in the cache or to follow distribution point
+ links depending on how the cache is administrated. </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>select(Issuer, DbHandle) -> CRLs </name>
+ <fsummary>Select the CRLs in the cache that are issued by <c>Issuer</c></fsummary>
+ <type>
+ <v> Issuer = <seealso
+ marker="public_key:public_key">public_key:issuer_name()</seealso></v>
+ <v> DbHandle = cache_ref() </v>
+ </type>
+ <desc>
+ <p>Select the CRLs in the cache that are issued by <c>Issuer</c> </p>
+ </desc>
+ </func>
+ </funcs>
+</erlref>
diff --git a/lib/ssl/doc/src/ssl_distribution.xml b/lib/ssl/doc/src/ssl_distribution.xml
index 4b4d042f70..dc04d446b0 100644
--- a/lib/ssl/doc/src/ssl_distribution.xml
+++ b/lib/ssl/doc/src/ssl_distribution.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,23 +32,20 @@
<rev>B</rev>
<file>ssl_distribution.xml</file>
</header>
- <p>This chapter describes how the Erlang distribution can use
- SSL to get additional verification and security.
- </p>
+ <p>This section describes how the Erlang distribution can use
+ SSL to get extra verification and security.</p>
- <section>
- <title>Introduction</title>
- <p>The Erlang distribution can in theory use almost any connection
- based protocol as bearer. A module that implements the protocol
- specific parts of the connection setup is however needed. The
- default distribution module is <c>inet_tcp_dist</c> which is
- included in the Kernel application. When starting an
+ <p>The Erlang distribution can in theory use almost any
+ connection-based protocol as bearer. However, a module that
+ implements the protocol-specific parts of the connection setup is
+ needed. The default distribution module is <c>inet_tcp_dist</c>
+ in the Kernel application. When starting an
Erlang node distributed, <c>net_kernel</c> uses this module to
- setup listen ports and connections. </p>
+ set up listen ports and connections.</p>
- <p>In the SSL application there is an additional distribution
- module, <c>inet_tls_dist</c> which can be used as an
- alternative. All distribution connections will be using SSL and
+ <p>In the SSL application, an exra 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
this distribution module.</p>
@@ -55,35 +53,45 @@
SSL connection setup. Erlang node cookies are however always
used, as they can be used to differentiate between two different
Erlang networks.</p>
- <p>Setting up Erlang distribution over SSL involves some simple but
- necessary steps:</p>
+
+ <p>To set up Erlang distribution over SSL:</p>
<list type="bulleted">
- <item>Building boot scripts including the SSL application</item>
- <item>Specifying the distribution module for net_kernel</item>
- <item>Specifying security options and other SSL options</item>
+ <item><em>Step 1:</em> Build boot scripts including the
+ SSL application.</item>
+ <item><em>Step 2:</em> Specify the distribution module for
+ <c>net_kernel</c>.</item>
+ <item><em>Step 3:</em> Specify the security options and other
+ SSL options.</item>
+ <item><em>Step 4:</em> Set up the environment to always use SSL.</item>
</list>
- <p>The rest of this chapter describes the above mentioned steps in
- more detail.</p>
- </section>
+
+ <p>The following sections describe these steps.</p>
<section>
- <title>Building boot scripts including the SSL application</title>
+ <title>Building Boot Scripts Including the ssl Application</title>
<p>Boot scripts are built using the <c>systools</c> utility in the
- SASL application. Refer to the SASL documentations
- for more information on systools. This is only an example of
+ <c>sasl</c> application. For more information on <c>systools</c>,
+ see the <c>sasl</c> documentation. This is only an example of
what can be done.</p>
- <p>The simplest boot script possible includes only the Kernel
- and STDLIB applications. Such a script is located in the
- Erlang distributions bin directory. The source for the script
- can be found under the Erlang installation top directory under
- <c><![CDATA[releases/<OTP version>/start_clean.rel]]></c>. Copy that
- script to another location (and preferably another name)
- and add the applications crypto, public_key and SSL with their current version numbers
- after the STDLIB application.</p>
- <p>An example .rel file with SSL added may look like this:</p>
+ <p>The simplest boot script possible includes only the Kernel
+ and STDLIB applications. Such a script is located in the
+ <c>bin</c> directory of the Erlang distribution. The source for the
+ script is found under the Erlang installation top directory under
+ <c><![CDATA[releases/<OTP version>/start_clean.rel]]></c>.</p>
+
+ <p>Do the following:</p>
+ <list type="bulleted">
+ <item><p>Copy that script to another location (and preferably another
+ name).</p></item>
+ <item><p>Add the applications Crypto, Public Key, and
+ SSL with their current version numbers after the
+ STDLIB application.</p></item>
+ </list>
+ <p>The following shows an example <c>.rel</c> file with SSL
+ added:</p>
<code type="none">
{release, {"OTP APN 181 01","R15A"}, {erts, "5.9"},
[{kernel,"2.15"},
@@ -94,23 +102,29 @@
]}.
</code>
- <p>Note that the version numbers surely will differ in your system.
- Whenever one of the applications included in the script is
- upgraded, the script has to be changed.</p>
- <p>Assuming the above .rel file is stored in a file
- <c>start_ssl.rel</c> in the current directory, a boot script
- can be built like this:</p>
+ <p>The version numbers differ in your system. Whenever one of the
+ applications included in the script is upgraded, change the script.</p>
+ <p>Do the following:</p>
+ <list type="bulleted">
+ <item><p>Build the boot script.</p>
+ <p>Assuming the <c>.rel file</c> is stored in a file
+ <c>start_ssl.rel</c> in the current directory, a boot script
+ can be built as follows:</p></item>
+ </list>
<code type="none">
1> systools:make_script("start_ssl",[]). </code>
- <p>There will now be a file <c>start_ssl.boot</c> in the current
- directory. To test the boot script, start Erlang with the
- <c>-boot</c> command line parameter specifying this boot script
- (with its full path but without the <c>.boot</c> suffix), in
- Unix it could look like this:</p>
- <p></p>
+ <p>There is now a <c>start_ssl.boot</c> file in the current
+ directory.</p>
+ <p>Do the following:</p>
+ <list type="bulleted">
+ <item><p>Test the boot script. To do this, start Erlang with the
+ <c>-boot</c> command-line parameter specifying this boot script
+ (with its full path, but without the <c>.boot</c> suffix). In
+ UNIX it can look as follows:</p></item>
+ </list>
<code type="none"><![CDATA[
$ erl -boot /home/me/ssl/start_ssl
Erlang (BEAM) emulator version 5.0
@@ -118,86 +132,99 @@ Erlang (BEAM) emulator version 5.0
Eshell V5.0 (abort with ^G)
1> whereis(ssl_manager).
<0.41.0> ]]></code>
- <p>The <c>whereis</c> function call verifies that the SSL
- application is really started.</p>
- <p>As an alternative to building a bootscript, one can explicitly
+ <p>The <c>whereis</c> function-call verifies that the SSL
+ application is started.</p>
+
+ <p>As an alternative to building a bootscript, you can explicitly
add the path to the SSL <c>ebin</c> directory on the command
- line. This is done with the command line option <c>-pa</c>. This
+ line. This is done with command-line option <c>-pa</c>. This
works as the SSL application does not need to be started for the
distribution to come up, as a clone of the SSL application is
- hooked into the kernel application, so as long as the
- SSL applications code can be reached, the distribution will
- start. The <c>-pa</c> method is only recommended for testing
- purposes.</p>
+ hooked into the Kernel application. So, as long as the
+ SSL application code can be reached, the distribution starts.
+ The <c>-pa</c> method is only recommended for testing purposes.</p>
- <note><p>Note that the clone of the SSL application is necessary to
+ <note><p>The clone of the SSL application must
enable the use of the SSL code in such an early bootstage as
- needed to setup the distribution, however this will make it
+ needed to set up the distribution. However, this makes it
impossible to soft upgrade the SSL application.</p></note>
</section>
<section>
- <title>Specifying distribution module for net_kernel</title>
+ <title>Specifying Distribution Module for net_kernel</title>
<p>The distribution module for SSL is named <c>inet_tls_dist</c>
- and is specified on the command line with the <c>-proto_dist</c>
- option. The argument to <c>-proto_dist</c> should be the module
- name without the <c>_dist</c> suffix, so this distribution
+ and is specified on the command line with option <c>-proto_dist</c>.
+ The argument to <c>-proto_dist</c> is to be the module
+ name without suffix <c>_dist</c>. So, this distribution
module is specified with <c>-proto_dist inet_tls</c> on the
command line.</p>
- <p></p>
- <p>Extending the command line from above gives us the following:</p>
+ <p>Extending the command line gives the following:</p>
<code type="none">
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls </code>
-<p>For the distribution to actually be started, we need to give
-the emulator a name as well:</p>
+<p>For the distribution to be started, give the emulator a name as well:</p>
<code type="none">
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls -sname ssl_test
Erlang (BEAM) emulator version 5.0 [source]
Eshell V5.0 (abort with ^G)
(ssl_test@myhost)1> </code>
- <p>Note however that a node started in this way will refuse to talk
- to other nodes, as no ssl parameters are supplied
- (see below).</p>
+
+ <p>However, a node started in this way refuses to talk
+ to other nodes, as no SSL parameters are supplied
+ (see the next section).</p>
</section>
<section>
- <title>Specifying SSL options</title> <p>For SSL to work, at least
- a public key and certificate needs to be specified for the server
- side. In the following example the PEM-files consists of two
- entries the servers certificate and its private key.</p>
-
- <p>On the <c>erl</c> command line one can specify options that the
- SSL distribution will add when creating a socket.</p>
-
- <p>One can specify the simpler SSL options certfile, keyfile,
- password, cacertfile, verify, reuse_sessions,
- secure_renegotiate, depth, hibernate_after and ciphers (use old
- string format) by adding the prefix server_ or client_ to the
- option name. The server can also take the options dhfile and
- fail_if_no_peer_cert (also prefixed).
- <c>client_</c>-prfixed options are used when the distribution initiates a
- connection to another node and the <c>server_</c>-prefixed options are used
- when accepting a connection from a remote node. </p>
-
- <p> More complex options such as verify_fun are not available at
- the moment but a mechanism to handle such options may be added in
- a future release. </p>
-
- <p> Raw socket options such as packet and size must not be specified on
- the command line</p>.
-
- <p>The command line argument for specifying the SSL options is named
- <c>-ssl_dist_opt</c> and should be followed by pairs of
- SSL options and their values. The <c>-ssl_dist_opt</c> argument can
+ <title>Specifying SSL Options</title>
+ <p>For SSL to work, at least
+ a public key and a certificate must be specified for the server
+ side. In the following example, the PEM-files consist of two
+ entries, the server certificate and its private key.</p>
+
+ <p>On the <c>erl</c> command line you can specify options that the
+ SSL distribution adds when creating a socket.</p>
+
+ <p>The simplest SSL options in the following list can be specified
+ by adding the
+ prefix <c>server_</c> or <c>client_</c> to the option name:</p>
+ <list type="bulleted">
+ <item><c>certfile</c></item>
+ <item><c>keyfile</c></item>
+ <item><c>password</c></item>
+ <item><c>cacertfile</c></item>
+ <item><c>verify</c></item>
+ <item><c>reuse_sessions</c></item>
+ <item><c>secure_renegotiate</c></item>
+ <item><c>depth</c></item>
+ <item><c>hibernate_after</c></item>
+ <item><c>ciphers</c> (use old string format)</item>
+ </list>
+
+ <p>The server can also take the options <c>dhfile</c> and
+ <c>fail_if_no_peer_cert</c> (also prefixed).</p>
+
+ <p><c>client_</c>-prefixed options are used when the distribution
+ initiates a connection to another node. <c>server_</c>-prefixed
+ options are used when accepting a connection from a remote node.</p>
+
+ <p>More complex options, such as <c>verify_fun</c>, are currently not
+ available, but a mechanism to handle such options may be added in
+ a future release.</p>
+
+ <p>Raw socket options, such as <c>packet</c> and <c>size</c> must not
+ be specified on the command line.</p>
+
+ <p>The command-line argument for specifying the SSL options is named
+ <c>-ssl_dist_opt</c> and is to be followed by pairs of
+ SSL options and their values. Argument <c>-ssl_dist_opt</c> can
be repeated any number of times.</p>
- <p>An example command line would now look something like this
+ <p>An example command line can now look as follows
(line breaks in the command are for readability,
- they should not be there when typed):</p>
+ and are not be there when typed):</p>
<code type="none">
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls
-ssl_dist_opt server_certfile "/home/me/ssl/erlserver.pem"
@@ -207,20 +234,20 @@ Erlang (BEAM) emulator version 5.0 [source]
Eshell V5.0 (abort with ^G)
(ssl_test@myhost)1> </code>
- <p>A node started in this way will be fully functional, using SSL
+ <p>A node started in this way is fully functional, using SSL
as the distribution protocol.</p>
</section>
<section>
- <title>Setting up environment to always use SSL</title>
- <p>A convenient way to specify arguments to Erlang is to use the
- <c>ERL_FLAGS</c> environment variable. All the flags needed to
- use SSL distribution can be specified in that variable and will
- then be interpreted as command line arguments for all
+ <title>Setting up Environment to Always Use SSL</title>
+ <p>A convenient way to specify arguments to Erlang is to use environment
+ variable <c>ERL_FLAGS</c>. All the flags needed to
+ use the SSL distribution can be specified in that variable and are
+ then interpreted as command-line arguments for all
subsequent invocations of Erlang.</p>
- <p></p>
- <p>In a Unix (Bourne) shell it could look like this (line breaks for
- readability, they should not be there when typed):</p>
+
+ <p>In a Unix (Bourne) shell, it can look as follows (line breaks are for
+ readability, they are not to be there when typed):</p>
<code type="none">
$ ERL_FLAGS="-boot /home/me/ssl/start_ssl -proto_dist inet_tls
-ssl_dist_opt server_certfile /home/me/ssl/erlserver.pem
@@ -240,7 +267,31 @@ Eshell V5.0 (abort with ^G)
{ssl_dist_opt,["server_secure_renegotiate","true",
"client_secure_renegotiate","true"]
{home,["/home/me"]}] </code>
+
<p>The <c>init:get_arguments()</c> call verifies that the correct
- arguments are supplied to the emulator. </p>
+ arguments are supplied to the emulator.</p>
+ </section>
+
+ <section>
+ <title>Using SSL distribution over IPv6</title>
+ <p>It is possible to use SSL distribution over IPv6 instead of
+ IPv4. To do this, pass the option <c>-proto_dist inet6_tls</c>
+ instead of <c>-proto_dist inet_tls</c> when starting Erlang,
+ either on the command line or in the <c>ERL_FLAGS</c> environment
+ variable.</p>
+
+ <p>An example command line with this option would look like this:</p>
+ <code type="none">
+$ erl -boot /home/me/ssl/start_ssl -proto_dist inet6_tls
+ -ssl_dist_opt server_certfile "/home/me/ssl/erlserver.pem"
+ -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true
+ -sname ssl_test
+Erlang (BEAM) emulator version 5.0 [source]
+
+Eshell V5.0 (abort with ^G)
+(ssl_test@myhost)1> </code>
+
+ <p>A node started in this way will only be able to communicate with
+ other nodes using SSL distribution over IPv6.</p>
</section>
</chapter>
diff --git a/lib/ssl/doc/src/ssl_introduction.xml b/lib/ssl/doc/src/ssl_introduction.xml
new file mode 100644
index 0000000000..d3e39dbb01
--- /dev/null
+++ b/lib/ssl/doc/src/ssl_introduction.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2015</year>
+ <year>2015</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>Introduction</title>
+ <prepared>OTP team</prepared>
+ <docno></docno>
+ <date>2015-03-05</date>
+ <rev>A</rev>
+ <file>ssl_introduction.xml</file>
+ </header>
+
+ <section>
+ <title>Purpose</title>
+ <p>Transport Layer Security (TLS) and its predecessor, the Secure
+ Sockets Layer (SSL), are cryptographic protocols designed to
+ provide communications security over a computer network. The protocols use
+ use X.509 certificates and hence public key (asymmetric) cryptography to
+ authenticate the counterpart with whom they communicate,
+ and to exchange a symmetric key for payload encryption. The protocol provides
+ data/message confidentiality (encryption), integrity (through message authentication code checks)
+ and host verification (through certificate path validation).</p>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang
+ programming language, the concepts of OTP, and has a basic
+ understanding of SSL/TLS.</p>
+ </section>
+
+</chapter>
diff --git a/lib/ssl/doc/src/ssl_protocol.xml b/lib/ssl/doc/src/ssl_protocol.xml
index 80d9cc4ee8..31a22db58b 100644
--- a/lib/ssl/doc/src/ssl_protocol.xml
+++ b/lib/ssl/doc/src/ssl_protocol.xml
@@ -4,50 +4,60 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Transport Layer Security (TLS) and its predecessor, Secure Socket Layer (SSL)</title>
+ <title>TLS and its Predecessor, SSL</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>ssl_protocol.xml</file>
</header>
- <p>The erlang SSL application currently implements the protocol SSL/TLS
- for currently supported versions see <seealso marker="ssl">ssl(3)</seealso>
+ <p>The Erlang SSL application implements the SSL/TLS protocol
+ for the currently supported versions, see the
+ <seealso marker="ssl">ssl(3)</seealso> manual page.
</p>
- <p>By default erlang SSL is run over the TCP/IP protocol even
- though you could plug in any other reliable transport protocol
- with the same API as gen_tcp.</p>
+ <p>By default SSL/TLS is run over the TCP/IP protocol even
+ though you can plug in any other reliable transport protocol
+ with the same Application Programming Interface (API) as the
+ <c>gen_tcp</c> module in Kernel.</p>
- <p>If a client and server wants to use an upgrade mechanism, such as
- defined by RFC2817, to upgrade a regular TCP/IP connection to an SSL
- connection the erlang SSL API supports this. This can be useful for
- things such as supporting HTTP and HTTPS on the same port and
+ <p>If a client and a server wants to use an upgrade mechanism, such as
+ defined by RFC 2817, to upgrade a regular TCP/IP connection to an SSL
+ connection, this is supported by the Erlang SSL application API. This can be
+ useful for, for example, supporting HTTP and HTTPS on the same port and
implementing virtual hosting.
</p>
<section>
- <title>Security overview</title>
+ <title>Security Overview</title>
- <p>To achieve authentication and privacy the client and server will
- perform a TLS Handshake procedure before transmitting or receiving
- any data. During the handshake they agree on a protocol version and
- cryptographic algorithms, they generate shared secrets using public
- key cryptographics and optionally authenticate each other with
+ <p>To achieve authentication and privacy, the client and server
+ perform a TLS handshake procedure before transmitting or receiving
+ any data. During the handshake, they agree on a protocol version and
+ cryptographic algorithms, generate shared secrets using public
+ key cryptographies, and optionally authenticate each other with
digital certificates.</p>
</section>
@@ -55,20 +65,21 @@
<title>Data Privacy and Integrity</title>
<p>A <em>symmetric key</em> algorithm has one key only. The key is
- used for both encryption and decryption. These algorithms are fast
- compared to public key algorithms (using two keys, a public and a
- private one) and are therefore typically used for encrypting bulk
+ used for both encryption and decryption. These algorithms are fast,
+ compared to public key algorithms (using two keys, one public and one
+ private) and are therefore typically used for encrypting bulk
data.
</p>
<p>The keys for the symmetric encryption are generated uniquely
for each connection and are based on a secret negotiated
- in the TLS handshake. </p>
+ in the TLS handshake.</p>
- <p>The TLS handshake protocol and data transfer is run on top of
- the TLS Record Protocol that uses a keyed-hash MAC (Message
- Authenticity Code), or HMAC, to protect the message's data
- integrity. From the TLS RFC "A Message Authentication Code is a
+ <p>The TLS handshake protocol and data transfer is run on top of
+ the TLS Record Protocol, which uses a keyed-hash Message
+ Authenticity Code (MAC), or a Hash-based MAC (HMAC),
+ to protect the message data
+ integrity. From the TLS RFC: "A Message Authentication Code is a
one-way hash computed from a message and some secret data. It is
difficult to forge without knowing the secret data. Its purpose is
to detect if the message has been altered."
@@ -82,40 +93,43 @@
passport. The holder of the certificate is called the
<em>subject</em>. The certificate is signed
with the private key of the issuer of the certificate. A chain
- of trust is build by having the issuer in its turn being
- certified by another certificate and so on until you reach the
- so called root certificate that is self signed i.e. issued
+ of trust is built by having the issuer in its turn being
+ certified by another certificate, and so on, until you reach the
+ so called root certificate, which is self-signed, that is, issued
by itself.</p>
- <p>Certificates are issued by <em>certification
- authorities</em> (<em>CA</em>s) only. There are a handful of
- top CAs in the world that issue root certificates. You can
- examine the certificates of several of them by clicking
+ <p>Certificates are issued by Certification Authorities (CAs) only.
+ A handful of top CAs in the world issue root certificates. You can
+ examine several of these certificates by clicking
through the menus of your web browser.
</p>
</section>
<section>
- <title>Authentication of Sender</title>
+ <title>Peer Authentication</title>
- <p>Authentication of the sender is done by public key path
- validation as defined in RFC 3280. Simplified that means that
- each certificate in the certificate chain is issued by the one
- before, the certificates attributes are valid ones, and the
- root cert is a trusted cert that is present in the trusted
- certs database kept by the peer.</p>
+ <p>Authentication of the peer is done by public key path
+ validation as defined in RFC 3280. This means basically
+ the following:</p>
+ <list type="bulleted">
+ <item>Each certificate in the certificate chain is issued by the
+ previous one.</item>
+ <item>The certificates attributes are valid.</item>
+ <item>The root certificate is a trusted certificate that is present
+ in the trusted certificate database kept by the peer.</item>
+ </list>
- <p>The server will always send a certificate chain as part of
- the TLS handshake, but the client will only send one if
- the server requests it. If the client does not have
- an appropriate certificate it may send an "empty" certificate
+ <p>The server always sends a certificate chain as part of
+ the TLS handshake, but the client only sends one if requested
+ by the server. If the client does not have
+ an appropriate certificate, it can send an "empty" certificate
to the server.</p>
- <p>The client may choose to accept some path evaluation errors
- for instance a web browser may ask the user if they want to
- accept an unknown CA root certificate. The server, if it request
- a certificate, will on the other hand not accept any path validation
- errors. It is configurable if the server should accept
+ <p>The client can choose to accept some path evaluation errors,
+ for example, a web browser can ask the user whether to
+ accept an unknown CA root certificate. The server, if it requests
+ a certificate, does however not accept any path validation
+ errors. It is configurable if the server is to accept
or reject an "empty" certificate as response to
a certificate request.</p>
</section>
@@ -123,25 +137,24 @@
<section>
<title>TLS Sessions</title>
- <p>From the TLS RFC "A TLS session is an association between a
- client and a server. Sessions are created by the handshake
+ <p>From the TLS RFC: "A TLS session is an association between a
+ client and a server. Sessions are created by the handshake
protocol. Sessions define a set of cryptographic security
parameters, which can be shared among multiple
connections. Sessions are used to avoid the expensive negotiation
of new security parameters for each connection."</p>
<p>Session data is by default kept by the SSL application in a
- memory storage hence session data will be lost at application
- restart or takeover. Users may define their own callback module
+ memory storage, hence session data is lost at application
+ restart or takeover. Users can define their own callback module
to handle session data storage if persistent data storage is
- required. Session data will also be invalidated after 24 hours
- from it was saved, for security reasons. It is of course
- possible to configure the amount of time the session data should be
- saved.</p>
+ required. Session data is also invalidated after 24 hours
+ from it was saved, for security reasons. The amount of time the
+ session data is to be saved can be configured.</p>
- <p>SSL clients will by default try to reuse an available session,
- SSL servers will by default agree to reuse sessions when clients
- ask to do so.</p>
+ <p>By default the SSL clients try to reuse an available session and
+ by default the SSL servers agree to reuse sessions when clients
+ ask for it.</p>
</section>
</chapter>
diff --git a/lib/ssl/doc/src/ssl_session_cache_api.xml b/lib/ssl/doc/src/ssl_session_cache_api.xml
index 82de1784ca..b85d8fb284 100644
--- a/lib/ssl/doc/src/ssl_session_cache_api.xml
+++ b/lib/ssl/doc/src/ssl_session_cache_api.xml
@@ -4,59 +4,76 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2013</year>
+ <year>1999</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssl</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
<file>ssl_session_cache_api.xml</file>
</header>
<module>ssl_session_cache_api</module>
- <modulesummary>Defines the API for the TLS session cache so
- that the data storage scheme can be replaced by
- defining a new callback module implementing this API.</modulesummary>
+ <modulesummary>TLS session cache API</modulesummary>
+ <description>
+ <p>
+ Defines the API for the TLS session cache so
+ that the data storage scheme can be replaced by
+ defining a new callback module implementing this API.
+ </p>
+ </description>
<section>
- <title>Common Data Types</title>
+ <title>DATA TYPES</title>
- <p>The following data types are used in the functions below:
- </p>
+ <p>The following data types are used in the functions for
+ <c>ssl_session_cache_api</c>:</p>
- <p><c>cache_ref() = opaque()</c></p>
-
- <p><c>key() = {partialkey(), session_id()}</c></p>
-
- <p><c>partialkey() = opaque()</c></p>
-
- <p><c>session_id() = binary()</c></p>
+ <taglist>
+ <tag><c>cache_ref() =</c></tag>
+ <item><p><c>opaque()</c></p></item>
+
+ <tag><c>key() =</c></tag>
+ <item><p><c>{partialkey(), session_id()}</c></p></item>
+
+ <tag><c>partialkey() =</c></tag>
+ <item><p><c>opaque()</c></p></item>
+
+ <tag><c>session_id() =</c></tag>
+ <item><p><c>binary()</c></p></item>
+
+ <tag><c>session()</c> =</tag>
+ <item><p><c>opaque()</c></p></item>
+ </taglist>
- <p><c>session() = opaque()</c></p>
-
</section>
<funcs>
<func>
<name>delete(Cache, Key) -> _</name>
- <fsummary></fsummary>
+ <fsummary>Deletes a cache entry.</fsummary>
<type>
- <v> Cache = cache_ref()</v>
- <v> Key = key()</v>
+ <v>Cache = cache_ref()</v>
+ <v>Key = key()</v>
</type>
<desc>
- <p> Deletes a cache entry. Will only be called from the cache
+ <p>Deletes a cache entry. Is only called from the cache
handling process.
</p>
</desc>
@@ -69,41 +86,50 @@
<v></v>
</type>
<desc>
- <p>Calls Fun(Elem, AccIn) on successive elements of the
- cache, starting with AccIn == Acc0. Fun/2 must return a new
- accumulator which is passed to the next call. The function returns
- the final value of the accumulator. Acc0 is returned if the cache is
- empty.
+ <p>Calls <c>Fun(Elem, AccIn)</c> on successive elements of the
+ cache, starting with <c>AccIn == Acc0</c>. <c>Fun/2</c> must
+ return a new accumulator, which is passed to the next call.
+ The function returns the final value of the accumulator.
+ <c>Acc0</c> is returned if the cache is empty.
</p>
</desc>
</func>
<func>
- <name>init() -> opaque() </name>
- <fsummary>Return cache reference</fsummary>
+ <name>init(Args) -> opaque() </name>
+ <fsummary>Returns cache reference.</fsummary>
<type>
- <v></v>
+ <v>Args = proplists:proplist()</v>
</type>
<desc>
+ <p>Includes property <c>{role, client | server}</c>.
+ Currently this is the only predefined property,
+ there can also be user-defined properties. See also
+ application environment variable
+ <seealso marker="ssl_app">session_cb_init_args</seealso>.
+ </p>
<p>Performs possible initializations of the cache and returns
- a reference to it that will be used as parameter to the other
- api functions. Will be called by the cache handling processes
- init function, hence putting the same requirements on it as
- a normal process init function.
+ a reference to it that is used as parameter to the other
+ API functions. Is called by the cache handling processes
+ <c>init</c> function, hence putting the same requirements on it
+ as a normal process <c>init</c> function. This function is
+ called twice when starting the SSL application, once with
+ the role client and once with the role server, as the SSL
+ application must be prepared to take on both roles.
</p>
</desc>
</func>
<func>
<name>lookup(Cache, Key) -> Entry</name>
- <fsummary> Looks up a cache entry.</fsummary>
+ <fsummary>Looks up a cache entry.</fsummary>
<type>
- <v> Cache = cache_ref()</v>
- <v> Key = key()</v>
- <v> Entry = session() | undefined </v>
+ <v>Cache = cache_ref()</v>
+ <v>Key = key()</v>
+ <v>Entry = session() | undefined</v>
</type>
<desc>
- <p>Looks up a cache entry. Should be callable from any
+ <p>Looks up a cache entry. Is to be callable from any
process.
</p>
</desc>
@@ -111,14 +137,14 @@
<func>
<name>select_session(Cache, PartialKey) -> [session()]</name>
- <fsummary>>Selects sessions that could be reused.</fsummary>
+ <fsummary>Selects sessions that can be reused.</fsummary>
<type>
- <v> Cache = cache_ref()</v>
- <v> PartialKey = partialkey()</v>
- <v> Session = session()</v>
+ <v>Cache = cache_ref()</v>
+ <v>PartialKey = partialkey()</v>
+ <v>Session = session()</v>
</type>
<desc>
- <p>Selects sessions that could be reused. Should be callable
+ <p>Selects sessions that can be reused. Is to be callable
from any process.
</p>
</desc>
@@ -129,7 +155,7 @@
<fsummary>Called by the process that handles the cache when it
is about to terminate.</fsummary>
<type>
- <v>Cache = term() - as returned by init/0</v>
+ <v>Cache = term() - as returned by init/0</v>
</type>
<desc>
<p>Takes care of possible cleanup that is needed when the
@@ -140,15 +166,15 @@
<func>
<name>update(Cache, Key, Session) -> _</name>
- <fsummary> Caches a new session or updates a already cached one.</fsummary>
+ <fsummary>Caches a new session or updates an already cached one.</fsummary>
<type>
- <v> Cache = cache_ref()</v>
- <v> Key = key()</v>
- <v> Session = session()</v>
+ <v>Cache = cache_ref()</v>
+ <v>Key = key()</v>
+ <v>Session = session()</v>
</type>
<desc>
- <p> Caches a new session or updates a already cached one. Will
- only be called from the cache handling process.
+ <p>Caches a new session or updates an already cached one. Is
+ only called from the cache handling process.
</p>
</desc>
</func>
diff --git a/lib/ssl/doc/src/usersguide.xml b/lib/ssl/doc/src/usersguide.xml
index b1c7190085..7bd0ae5c4c 100644
--- a/lib/ssl/doc/src/usersguide.xml
+++ b/lib/ssl/doc/src/usersguide.xml
@@ -8,29 +8,33 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>SSL User's Guide</title>
<prepared>OTP Team</prepared>
+ <docno></docno>
<date>2003-05-26</date>
+ <rev></rev>
<file>usersguide.sgml</file>
</header>
<description>
- <p>The <em>SSL</em> application provides secure communication over
+ <p>The Secure Socket Layer (SSL) application provides secure communication over
sockets.
</p>
</description>
+ <xi:include href="ssl_introduction.xml"/>
<xi:include href="ssl_protocol.xml"/>
<xi:include href="using_ssl.xml"/>
<xi:include href="ssl_distribution.xml"/>
diff --git a/lib/ssl/doc/src/using_ssl.xml b/lib/ssl/doc/src/using_ssl.xml
index cce388d02a..b6a4bb5bec 100644
--- a/lib/ssl/doc/src/using_ssl.xml
+++ b/lib/ssl/doc/src/using_ssl.xml
@@ -8,139 +8,145 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Using the SSL API</title>
+ <title>Using SSL API</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>using_ssl.xml</file>
</header>
-
- <section>
- <title>General information</title>
- <p>To see relevant version information for ssl you can
- call ssl:versions/0</p>
+ <p>To see relevant version information for ssl, call
+ <seealso marker="ssl:ssl#versions-0"><c>ssl:versions/0</c></seealso>
+ .</p>
- <p>To see all supported cipher suites
- call ssl:cipher_suites/0. Note that available cipher suites
- for a connection will depend on your certificate. It is also
- possible to specify a specific cipher suite(s) that you
- want your connection to use. Default is to use the strongest
- available.</p>
-
- </section>
+ <p>To see all supported cipher suites, call <seealso marker="ssl:ssl#cipher_suites-1"><c>ssl:cipher_suites(all)</c> </seealso>.
+ The available cipher suites for a connection depend on your certificate.
+ Specific cipher suites that you want your connection to use can also be
+ specified. Default is to use the strongest available.</p>
<section>
- <title>Setting up connections</title>
+ <title>Setting up Connections</title>
- <p>Here follows some small example of how to set up client/server connections
- using the erlang shell. The returned value of the sslsocket has been abbreviated with
- <c>[...]</c> as it can be fairly large and is opaque.</p>
+ <p>This section shows a small example of how to set up client/server connections
+ using the Erlang shell. The returned value of the <c>sslsocket</c> is abbreviated
+ with <c>[...]</c> as it can be fairly large and is opaque.</p>
<section>
- <title>Minmal example</title>
+ <title>Minimal Example</title>
- <note><p> The minimal setup is not the most secure setup of ssl.</p>
+ <note><p> The minimal setup is not the most secure setup of SSL.</p>
</note>
-
- <p> Start server side</p>
+
+ <p>To set up client/server connections:</p>
+
+ <p><em>Step 1:</em> Start the server side:</p>
<code type="erl">1 server> ssl:start().
ok</code>
- <p>Create an ssl listen socket</p>
+ <p><em>Step 2:</em> Create an SSL listen socket:</p>
<code type="erl">2 server> {ok, ListenSocket} =
ssl:listen(9999, [{certfile, "cert.pem"}, {keyfile, "key.pem"},{reuseaddr, true}]).
{ok,{sslsocket, [...]}}</code>
- <p>Do a transport accept on the ssl listen socket</p>
+ <p><em>Step 3:</em> Do a transport accept on the SSL listen socket:</p>
<code type="erl">3 server> {ok, Socket} = ssl:transport_accept(ListenSocket).
{ok,{sslsocket, [...]}}</code>
- <p>Start client side</p>
+ <p><em>Step 4:</em> Start the client side:</p>
<code type="erl">1 client> ssl:start().
ok</code>
<code type="erl">2 client> {ok, Socket} = ssl:connect("localhost", 9999, [], infinity).
{ok,{sslsocket, [...]}}</code>
- <p>Do the ssl handshake</p>
+ <p><em>Step 5:</em> Do the SSL handshake:</p>
<code type="erl">4 server> ok = ssl:ssl_accept(Socket).
ok</code>
- <p>Send a messag over ssl</p>
+ <p><em>Step 6:</em> Send a message over SSL:</p>
<code type="erl">5 server> ssl:send(Socket, "foo").
ok</code>
- <p>Flush the shell message queue to see that we got the message
- sent on the server side</p>
+ <p><em>Step 7:</em> Flush the shell message queue to see that the message
+ was sent on the server side:</p>
<code type="erl">3 client> flush().
Shell got {ssl,{sslsocket,[...]},"foo"}
ok</code>
</section>
<section>
- <title>Upgrade example</title>
+ <title>Upgrade Example</title>
- <note><p> To upgrade a TCP/IP connection to an ssl connection the
- client and server have to aggre to do so. Agreement
- may be accompliced by using a protocol such the one used by HTTP
- specified in RFC 2817.</p> </note>
+ <note><p>To upgrade a TCP/IP connection to an SSL connection, the
+ client and server must agree to do so. The agreement
+ can be accomplished by using a protocol, for example, the one used by HTTP
+ specified in RFC 2817.</p></note>
+
+ <p>To upgrade to an SSL connection:</p>
- <p>Start server side</p>
+ <p><em>Step 1:</em> Start the server side:</p>
<code type="erl">1 server> ssl:start().
ok</code>
- <p>Create a normal tcp listen socket</p>
+ <p><em>Step 2:</em> Create a normal TCP listen socket:</p>
<code type="erl">2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true}]).
{ok, #Port&lt;0.475&gt;}</code>
- <p>Accept client connection</p>
+ <p><em>Step 3:</em> Accept client connection:</p>
<code type="erl">3 server> {ok, Socket} = gen_tcp:accept(ListenSocket).
{ok, #Port&lt;0.476&gt;}</code>
- <p>Start client side</p>
+ <p><em>Step 4:</em> Start the client side:</p>
<code type="erl">1 client> ssl:start().
ok</code>
<code type="erl">2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999, [], infinity).</code>
- <p>Make sure active is set to false before trying
- to upgrade a connection to an ssl connection, otherwhise
- ssl handshake messages may be deliverd to the wrong process.</p>
+ <p><em>Step 5:</em> Ensure <c>active</c> is set to <c>false</c> before trying
+ to upgrade a connection to an SSL connection, otherwise
+ SSL handshake messages can be delivered to the wrong process:</p>
<code type="erl">4 server> inet:setopts(Socket, [{active, false}]).
ok</code>
- <p>Do the ssl handshake.</p>
+ <p><em>Step 6:</em> Do the SSL handshake:</p>
<code type="erl">5 server> {ok, SSLSocket} = ssl:ssl_accept(Socket, [{cacertfile, "cacerts.pem"},
{certfile, "cert.pem"}, {keyfile, "key.pem"}]).
{ok,{sslsocket,[...]}}</code>
- <p> Upgrade to an ssl connection. Note that the client and server
- must agree upon the upgrade and the server must call
- ssl:accept/2 before the client calls ssl:connect/3.</p>
+ <p><em>Step 7:</em> Upgrade to an SSL connection. The client and server
+ must agree upon the upgrade. The server must call
+ <c>ssl:accept/2</c> before the client calls <c>ssl:connect/3.</c></p>
<code type="erl">3 client>{ok, SSLSocket} = ssl:connect(Socket, [{cacertfile, "cacerts.pem"},
{certfile, "cert.pem"}, {keyfile, "key.pem"}], infinity).
{ok,{sslsocket,[...]}}</code>
- <p>Send a messag over ssl</p>
+ <p><em>Step 8:</em> Send a message over SSL:</p>
<code type="erl">4 client> ssl:send(SSLSocket, "foo").
ok</code>
- <p>Set active true on the ssl socket</p>
+ <p><em>Step 9:</em> Set <c>active true</c> on the SSL socket:</p>
<code type="erl">4 server> ssl:setopts(SSLSocket, [{active, true}]).
ok</code>
- <p>Flush the shell message queue to see that we got the message
- sent on the client side</p>
+ <p><em>Step 10:</em> Flush the shell message queue to see that the message
+ was sent on the client side:</p>
<code type="erl">5 server> flush().
Shell got {ssl,{sslsocket,[...]},"foo"}
ok</code>
diff --git a/lib/ssl/examples/certs/Makefile b/lib/ssl/examples/certs/Makefile
index be2546fe82..797abb04ef 100644
--- a/lib/ssl/examples/certs/Makefile
+++ b/lib/ssl/examples/certs/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ssl/examples/src/Makefile b/lib/ssl/examples/src/Makefile
index 3e033c08d9..e14ef321c7 100644
--- a/lib/ssl/examples/src/Makefile
+++ b/lib/ssl/examples/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/ssl/examples/src/client_server.erl b/lib/ssl/examples/src/client_server.erl
index 133a1764bc..019b5130d2 100644
--- a/lib/ssl/examples/src/client_server.erl
+++ b/lib/ssl/examples/src/client_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -25,9 +26,7 @@
start() ->
%% Start ssl application
- application:start(crypto),
- application:start(public_key),
- application:start(ssl),
+ {ok, StartedApps} = application:ensure_all_started(ssl),
%% Let the current process be the server that listens and accepts
%% Listen
@@ -51,7 +50,8 @@ start() ->
ssl:close(ASock),
io:fwrite("Listen: closing and terminating.~n"),
ssl:close(LSock),
- application:stop(ssl).
+
+ lists:foreach(fun application:stop/1, lists:reverse(StartedApps)).
%% Client connect
diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile
index 0c00a650b9..7a7a373487 100644
--- a/lib/ssl/src/Makefile
+++ b/lib/ssl/src/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2014. All Rights Reserved.
+# Copyright Ericsson AB 1999-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -38,7 +39,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/ssl-$(VSN)
# ----------------------------------------------------
BEHAVIOUR_MODULES= \
- ssl_session_cache_api
+ ssl_session_cache_api \
+ ssl_crl_cache_api
MODULES= \
ssl \
@@ -49,6 +51,7 @@ MODULES= \
ssl_dist_sup\
ssl_sup \
inet_tls_dist \
+ inet6_tls_dist \
ssl_certificate\
ssl_pkix_db\
ssl_cipher \
@@ -65,6 +68,8 @@ MODULES= \
ssl_manager \
ssl_session \
ssl_session_cache \
+ ssl_crl\
+ ssl_crl_cache \
ssl_socket \
ssl_listen_tracker_sup \
tls_record \
@@ -164,5 +169,5 @@ $(EBIN)/ssl_session_cache.$(EMULATOR): ssl_internal.hrl ssl_handshake.hrl
$(EBIN)/ssl_session_cache_api.$(EMULATOR): ssl_internal.hrl ssl_handshake.hrl
$(EBIN)/ssl_ssl3.$(EMULATOR): ssl_internal.hrl ssl_record.hrl ssl_cipher.hrl
$(EBIN)/ssl_tls1.$(EMULATOR): ssl_internal.hrl ssl_record.hrl ssl_cipher.hrl
-
+$(EBIN)/ssl_cache.$(EMULATOR): ssl_cache.erl ssl_internal.hrl ../../public_key/include/public_key.hrl
diff --git a/lib/ssl/src/dtls.erl b/lib/ssl/src/dtls.erl
index 780bddeb10..14aefd4989 100644
--- a/lib/ssl/src/dtls.erl
+++ b/lib/ssl/src/dtls.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index 508983ddac..e490de7eeb 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -144,9 +145,9 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, User, CbInfo]) ->
process_flag(trap_exit, true),
State0 = initial_state(Role, Host, Port, Socket, Options, User, CbInfo),
Handshake = ssl_handshake:init_handshake_history(),
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ TimeStamp = erlang:monotonic_time(),
try ssl_config:init(SSLOpts0, Role) of
- {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, OwnCert, Key, DHParams} ->
+ {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbInfo, OwnCert, Key, DHParams} ->
Session = State0#state.session,
State = State0#state{
tls_handshake_history = Handshake,
@@ -155,6 +156,7 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, User, CbInfo]) ->
file_ref_db = FileRefHandle,
cert_db_ref = Ref,
cert_db = CertDbHandle,
+ crl_db = CRLDbInfo,
session_cache = CacheHandle,
private_key = Key,
diffie_hellman_params = DHParams},
@@ -194,8 +196,7 @@ hello(start, #state{host = Host, port = Port, role = client,
{Record, State} = next_record(State1),
next_state(hello, hello, Record, State);
-hello(Hello = #client_hello{client_version = ClientVersion,
- extensions = #hello_extensions{hash_signs = HashSigns}},
+hello(Hello = #client_hello{client_version = ClientVersion},
State = #state{connection_states = ConnectionStates0,
port = Port, session = #session{own_certificate = Cert} = Session0,
renegotiation = {Renegotiation, _},
@@ -207,9 +208,7 @@ hello(Hello = #client_hello{client_version = ClientVersion,
{Version, {Type, Session},
ConnectionStates,
#hello_extensions{ec_point_formats = EcPointFormats,
- elliptic_curves = EllipticCurves} = ServerHelloExt} ->
- HashSign = ssl_handshake:select_hashsign(HashSigns, Cert,
- dtls_v1:corresponding_tls_version(Version)),
+ elliptic_curves = EllipticCurves} = ServerHelloExt, HashSign} ->
ssl_connection:hello({common_client_hello, Type, ServerHelloExt, HashSign},
State#state{connection_states = ConnectionStates,
negotiated_version = Version,
@@ -227,9 +226,9 @@ hello(Hello,
case dtls_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
handle_own_alert(Alert, ReqVersion, hello, State);
- {Version, NewId, ConnectionStates, NextProtocol} ->
+ {Version, NewId, ConnectionStates, ProtoExt, Protocol} ->
ssl_connection:handle_session(Hello,
- Version, NewId, ConnectionStates, NextProtocol, State)
+ Version, NewId, ConnectionStates, ProtoExt, Protocol, State)
end;
hello(Msg, State) ->
@@ -513,6 +512,7 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
user_data_buffer = <<>>,
session_cache_cb = SessionCacheCb,
renegotiation = {false, first},
+ allow_renegotiate = SSLOptions#ssl_options.client_renegotiation,
start_or_recv_from = undefined,
send_queue = queue:new(),
protocol_cb = ?MODULE
diff --git a/lib/ssl/src/dtls_connection.hrl b/lib/ssl/src/dtls_connection.hrl
index 08707dc8de..b74801b50a 100644
--- a/lib/ssl/src/dtls_connection.hrl
+++ b/lib/ssl/src/dtls_connection.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/dtls_connection_sup.erl b/lib/ssl/src/dtls_connection_sup.erl
index 0b4711cfb4..cf50537869 100644
--- a/lib/ssl/src/dtls_connection_sup.erl
+++ b/lib/ssl/src/dtls_connection_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl
index 31d525b295..50c84b712f 100644
--- a/lib/ssl/src/dtls_handshake.erl
+++ b/lib/ssl/src/dtls_handshake.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(dtls_handshake).
@@ -93,7 +94,10 @@ hello(#server_hello{server_version = Version, random = Random,
hello(#client_hello{client_version = ClientVersion}, _Options, {_,_,_,_,ConnectionStates,_}, _Renegotiation) ->
%% Return correct typ to make dialyzer happy until we have time to make the real imp.
- {ClientVersion, {new, #session{}}, ConnectionStates, #hello_extensions{}}.
+ HashSigns = tls_v1:default_signature_algs(dtls_v1:corresponding_tls_version(ClientVersion)),
+ {ClientVersion, {new, #session{}}, ConnectionStates, #hello_extensions{},
+ %% Placeholder for real hasign handling
+ hd(HashSigns)}.
%% hello(Address, Port,
%% #ssl_tls{epoch = _Epoch, sequence_number = _Seq,
@@ -181,8 +185,8 @@ handle_server_hello_extensions(Version, SessionId, Random, CipherSuite,
SslOpt, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
Alert;
- {ConnectionStates, Protocol} ->
- {Version, SessionId, ConnectionStates, Protocol}
+ {ConnectionStates, ProtoExt, Protocol} ->
+ {Version, SessionId, ConnectionStates, ProtoExt, Protocol}
end.
dtls_fragment(Mss, MsgType, Len, MsgSeq, Bin, Offset, Acc)
diff --git a/lib/ssl/src/dtls_handshake.hrl b/lib/ssl/src/dtls_handshake.hrl
index 3b57575b6d..be32112120 100644
--- a/lib/ssl/src/dtls_handshake.hrl
+++ b/lib/ssl/src/dtls_handshake.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl
index ae35dd7ea4..2530d66052 100644
--- a/lib/ssl/src/dtls_record.erl
+++ b/lib/ssl/src/dtls_record.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -120,6 +121,26 @@ get_dtls_records_aux(Data, Acc) ->
end.
encode_plain_text(Type, Version, Data,
+ #connection_states{current_write =
+ #connection_state{
+ epoch = Epoch,
+ sequence_number = Seq,
+ compression_state=CompS0,
+ security_parameters=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ compression_algorithm=CompAlg}
+ }= WriteState0} = ConnectionStates) ->
+ {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
+ WriteState1 = WriteState0#connection_state{compression_state = CompS1},
+ AAD = calc_aad(Type, Version, Epoch, Seq),
+ {CipherFragment, WriteState} = ssl_record:cipher_aead(dtls_v1:corresponding_tls_version(Version),
+ Comp, WriteState1, AAD),
+ CipherText = encode_tls_cipher_text(Type, Version, Epoch, Seq, CipherFragment),
+ {CipherText, ConnectionStates#connection_states{current_write =
+ WriteState#connection_state{sequence_number = Seq +1}}};
+
+encode_plain_text(Type, Version, Data,
#connection_states{current_write=#connection_state{
epoch = Epoch,
sequence_number = Seq,
@@ -141,16 +162,44 @@ decode_cipher_text(#ssl_tls{type = Type, version = Version,
sequence_number = Seq,
fragment = CipherFragment} = CipherText,
#connection_states{current_read =
- #connection_state{compression_state = CompressionS0,
- security_parameters = SecParams} = ReadState0}
- = ConnnectionStates0) ->
- CompressAlg = SecParams#security_parameters.compression_algorithm,
+ #connection_state{
+ compression_state = CompressionS0,
+ security_parameters=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ compression_algorithm=CompAlg}
+ } = ReadState0}= ConnnectionStates0) ->
+ AAD = calc_aad(Type, Version, Epoch, Seq),
+ case ssl_record:decipher_aead(dtls_v1:corresponding_tls_version(Version),
+ CipherFragment, ReadState0, AAD) of
+ {PlainFragment, ReadState1} ->
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
+ PlainFragment, CompressionS0),
+ ConnnectionStates = ConnnectionStates0#connection_states{
+ current_read = ReadState1#connection_state{
+ compression_state = CompressionS1}},
+ {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end;
+
+decode_cipher_text(#ssl_tls{type = Type, version = Version,
+ epoch = Epoch,
+ sequence_number = Seq,
+ fragment = CipherFragment} = CipherText,
+ #connection_states{current_read =
+ #connection_state{
+ compression_state = CompressionS0,
+ security_parameters=
+ #security_parameters{
+ compression_algorithm=CompAlg}
+ } = ReadState0}= ConnnectionStates0) ->
{PlainFragment, Mac, ReadState1} = ssl_record:decipher(dtls_v1:corresponding_tls_version(Version),
CipherFragment, ReadState0, true),
MacHash = calc_mac_hash(ReadState1, Type, Version, Epoch, Seq, PlainFragment),
case ssl_record:is_correct_mac(Mac, MacHash) of
true ->
- {Plain, CompressionS1} = ssl_record:uncompress(CompressAlg,
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
PlainFragment, CompressionS0),
ConnnectionStates = ConnnectionStates0#connection_states{
current_read = ReadState1#connection_state{
@@ -368,3 +417,7 @@ calc_mac_hash(#connection_state{mac_secret = MacSecret,
mac_hash(Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
dtls_v1:mac_hash(Version, MacAlg, MacSecret, SeqNo, Type,
Length, Fragment).
+
+calc_aad(Type, {MajVer, MinVer}, Epoch, SeqNo) ->
+ NewSeq = (Epoch bsl 48) + SeqNo,
+ <<NewSeq:64/integer, ?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer)>>.
diff --git a/lib/ssl/src/dtls_record.hrl b/lib/ssl/src/dtls_record.hrl
index edb77fb2b1..ab59a5fea1 100644
--- a/lib/ssl/src/dtls_record.hrl
+++ b/lib/ssl/src/dtls_record.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/dtls_v1.erl b/lib/ssl/src/dtls_v1.erl
index 5a7ab32887..99cedd2adc 100644
--- a/lib/ssl/src/dtls_v1.erl
+++ b/lib/ssl/src/dtls_v1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssl/src/inet6_tls_dist.erl b/lib/ssl/src/inet6_tls_dist.erl
new file mode 100644
index 0000000000..ffd7296f93
--- /dev/null
+++ b/lib/ssl/src/inet6_tls_dist.erl
@@ -0,0 +1,46 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(inet6_tls_dist).
+
+-export([childspecs/0, listen/1, accept/1, accept_connection/5,
+ setup/5, close/1, select/1]).
+
+childspecs() ->
+ inet_tls_dist:childspecs().
+
+select(Node) ->
+ inet_tls_dist:gen_select(inet6_tcp, Node).
+
+listen(Name) ->
+ inet_tls_dist:gen_listen(inet6_tcp, Name).
+
+accept(Listen) ->
+ inet_tls_dist:gen_accept(inet6_tcp, Listen).
+
+accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+ inet_tls_dist:gen_accept_connection(inet6_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime).
+
+setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
+ inet_tls_dist:gen_setup(inet6_tcp, Node, Type, MyNode, LongOrShortNames,SetupTime).
+
+close(Socket) ->
+ inet_tls_dist:close(Socket).
diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index 7367b5c224..ec26142a75 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,18 +24,28 @@
-export([childspecs/0, listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+%% Generalized dist API
+-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
+ gen_setup/6, gen_select/2]).
+
-include_lib("kernel/include/net_address.hrl").
-include_lib("kernel/include/dist.hrl").
-include_lib("kernel/include/dist_util.hrl").
childspecs() ->
{ok, [{ssl_dist_sup,{ssl_dist_sup, start_link, []},
- permanent, 2000, worker, [ssl_dist_sup]}]}.
+ permanent, infinity, supervisor, [ssl_dist_sup]}]}.
select(Node) ->
+ gen_select(inet_tcp, Node).
+
+gen_select(Driver, Node) ->
case split_node(atom_to_list(Node), $@, []) of
- [_,_Host] ->
- true;
+ [_, Host] ->
+ case inet:getaddr(Host, Driver:family()) of
+ {ok, _} -> true;
+ _ -> false
+ end;
_ ->
false
end.
@@ -45,23 +56,35 @@ is_node_name(_) ->
false.
listen(Name) ->
- ssl_tls_dist_proxy:listen(Name).
+ gen_listen(inet_tcp, Name).
+
+gen_listen(Driver, Name) ->
+ ssl_tls_dist_proxy:listen(Driver, Name).
accept(Listen) ->
- ssl_tls_dist_proxy:accept(Listen).
+ gen_accept(inet_tcp, Listen).
+
+gen_accept(Driver, Listen) ->
+ ssl_tls_dist_proxy:accept(Driver, Listen).
accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+ gen_accept_connection(inet_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime).
+
+gen_accept_connection(Driver, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
Kernel = self(),
- spawn_link(fun() -> do_accept(Kernel, AcceptPid, Socket,
+ spawn_link(fun() -> do_accept(Driver, Kernel, AcceptPid, Socket,
MyNode, Allowed, SetupTime) end).
setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
+ gen_setup(inet_tcp, Node, Type, MyNode, LongOrShortNames,SetupTime).
+
+gen_setup(Driver, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
Kernel = self(),
- spawn_opt(fun() -> do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) end, [link, {priority, max}]).
+ spawn_opt(fun() -> do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) end, [link, {priority, max}]).
-do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
- [Name, Address] = splitnode(Node, LongOrShortNames),
- case inet:getaddr(Address, inet) of
+do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
+ [Name, Address] = splitnode(Driver, Node, LongOrShortNames),
+ case inet:getaddr(Address, Driver:family()) of
{ok, Ip} ->
Timer = dist_util:start_timer(SetupTime),
case erl_epmd:port_please(Name, Ip) of
@@ -69,41 +92,41 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
?trace("port_please(~p) -> version ~p~n",
[Node,Version]),
dist_util:reset_timer(Timer),
- case ssl_tls_dist_proxy:connect(Ip, TcpPort) of
+ case ssl_tls_dist_proxy:connect(Driver, Ip, TcpPort) of
{ok, Socket} ->
HSData = connect_hs_data(Kernel, Node, MyNode, Socket,
Timer, Version, Ip, TcpPort, Address,
Type),
dist_util:handshake_we_started(HSData);
- _ ->
+ Other ->
%% Other Node may have closed since
%% port_please !
?trace("other node (~p) "
"closed since port_please.~n",
[Node]),
- ?shutdown(Node)
+ ?shutdown2(Node, {shutdown, {connect_failed, Other}})
end;
- _ ->
+ Other ->
?trace("port_please (~p) "
"failed.~n", [Node]),
- ?shutdown(Node)
+ ?shutdown2(Node, {shutdown, {port_please_failed, Other}})
end;
- _Other ->
+ Other ->
?trace("inet_getaddr(~p) "
"failed (~p).~n", [Node,Other]),
- ?shutdown(Node)
+ ?shutdown2(Node, {shutdown, {inet_getaddr_failed, Other}})
end.
close(Socket) ->
gen_tcp:close(Socket),
ok.
-do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
process_flag(priority, max),
receive
{AcceptPid, controller} ->
Timer = dist_util:start_timer(SetupTime),
- case check_ip(Socket) of
+ case check_ip(Driver, Socket) of
true ->
HSData = accept_hs_data(Kernel, MyNode, Socket, Timer, Allowed),
dist_util:handshake_other_started(HSData);
@@ -117,12 +140,12 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
%% Do only accept new connection attempts from nodes at our
%% own LAN, if the check_ip environment parameter is true.
%% ------------------------------------------------------------
-check_ip(Socket) ->
+check_ip(Driver, Socket) ->
case application:get_env(check_ip) of
{ok, true} ->
case get_ifs(Socket) of
{ok, IFs, IP} ->
- check_ip(IFs, IP);
+ check_ip(Driver, IFs, IP);
_ ->
?shutdown(no_node)
end;
@@ -141,37 +164,21 @@ get_ifs(Socket) ->
Error
end.
-check_ip([{OwnIP, _, Netmask}|IFs], PeerIP) ->
- case {mask(Netmask, PeerIP), mask(Netmask, OwnIP)} of
+check_ip(Driver, [{OwnIP, _, Netmask}|IFs], PeerIP) ->
+ case {Driver:mask(Netmask, PeerIP), Driver:mask(Netmask, OwnIP)} of
{M, M} -> true;
_ -> check_ip(IFs, PeerIP)
end;
-check_ip([], PeerIP) ->
+check_ip(_Driver, [], PeerIP) ->
{false, PeerIP}.
-mask({M1,M2,M3,M4}, {IP1,IP2,IP3,IP4}) ->
- {M1 band IP1,
- M2 band IP2,
- M3 band IP3,
- M4 band IP4};
-
-mask({M1,M2,M3,M4, M5, M6, M7, M8}, {IP1,IP2,IP3,IP4, IP5, IP6, IP7, IP8}) ->
- {M1 band IP1,
- M2 band IP2,
- M3 band IP3,
- M4 band IP4,
- M5 band IP5,
- M6 band IP6,
- M7 band IP7,
- M8 band IP8}.
-
%% If Node is illegal terminate the connection setup!!
-splitnode(Node, LongOrShortNames) ->
+splitnode(Driver, Node, LongOrShortNames) ->
case split_node(atom_to_list(Node), $@, []) of
[Name|Tail] when Tail =/= [] ->
Host = lists:append(Tail),
- check_node(Name, Node, Host, LongOrShortNames);
+ check_node(Driver, Name, Node, Host, LongOrShortNames);
[_] ->
error_logger:error_msg("** Nodename ~p illegal, no '@' character **~n",
[Node]),
@@ -181,15 +188,20 @@ splitnode(Node, LongOrShortNames) ->
?shutdown(Node)
end.
-check_node(Name, Node, Host, LongOrShortNames) ->
+check_node(Driver, Name, Node, Host, LongOrShortNames) ->
case split_node(Host, $., []) of
[_] when LongOrShortNames == longnames ->
- error_logger:error_msg("** System running to use "
- "fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node);
+ case Driver:parse_address(Host) of
+ {ok, _} ->
+ [Name, Host];
+ _ ->
+ error_logger:error_msg("** System running to use "
+ "fully qualified "
+ "hostnames **~n"
+ "** Hostname ~s is illegal **~n",
+ [Host]),
+ ?shutdown(Node)
+ end;
[_, _ | _] when LongOrShortNames == shortnames ->
error_logger:error_msg("** System NOT running to use fully qualified "
"hostnames **~n"
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index 36681e2897..1a2bf90ccf 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -31,6 +31,7 @@
ssl_listen_tracker_sup,
%% Erlang Distribution over SSL/TLS
inet_tls_dist,
+ inet6_tls_dist,
ssl_tls_dist_proxy,
ssl_dist_sup,
%% SSL/TLS session handling
@@ -39,6 +40,10 @@
ssl_manager,
ssl_pkix_db,
ssl_certificate,
+ %% CRL handling
+ ssl_crl,
+ ssl_crl_cache,
+ ssl_crl_cache_api,
%% App structure
ssl_app,
ssl_sup,
@@ -49,7 +54,7 @@
{applications, [crypto, public_key, kernel, stdlib]},
{env, []},
{mod, {ssl_app, []}},
- {runtime_dependencies, ["stdlib-2.0","public_key-0.22","kernel-3.0",
- "erts-6.0","crypto-3.3"]}]}.
+ {runtime_dependencies, ["stdlib-2.0","public_key-1.0","kernel-3.0",
+ "erts-7.0","crypto-3.3", "inets-5.10.7"]}]}.
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index d100e41930..11728128c4 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,16 +1,16 @@
%% -*- erlang -*-
{"%VSN%",
[
- {<<"6.0">>, [{load_module, ssl_handshake, soft_purge, soft_purge, []}]},
- {<<"5\\.3\\.[1-7]($|\\..*)">>, [{restart_application, ssl}]},
- {<<"5\\.[0-2]($|\\..*)">>, [{restart_application, ssl}]},
+ {<<"7\\..*">>, [{restart_application, ssl}]},
+ {<<"6\\..*">>, [{restart_application, ssl}]},
+ {<<"5\\..*">>, [{restart_application, ssl}]},
{<<"4\\..*">>, [{restart_application, ssl}]},
{<<"3\\..*">>, [{restart_application, ssl}]}
],
[
- {<<"6.0">>, [{load_module, ssl_handshake, soft_purge, soft_purge, []}]},
- {<<"5\\.3\\.[1-7]($|\\..*)">>, [{restart_application, ssl}]},
- {<<"5\\.[0-2]($|\\..*)">>, [{restart_application, ssl}]},
+ {<<"7\\..*">>, [{restart_application, ssl}]},
+ {<<"6\\..*">>, [{restart_application, ssl}]},
+ {<<"5\\..*">>, [{restart_application, ssl}]},
{<<"4\\..*">>, [{restart_application, ssl}]},
{<<"3\\..*">>, [{restart_application, ssl}]}
]
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 5f4ad7f013..97a1e2b5a8 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,14 +34,18 @@
listen/2, transport_accept/1, transport_accept/2,
ssl_accept/1, ssl_accept/2, ssl_accept/3,
controlling_process/2, peername/1, peercert/1, sockname/1,
- close/1, shutdown/2, recv/2, recv/3, send/2, getopts/2, setopts/2
+ close/1, close/2, shutdown/2, recv/2, recv/3, send/2, getopts/2, setopts/2
]).
%% SSL/TLS protocol handling
--export([cipher_suites/0, cipher_suites/1, suite_definition/1,
+-export([cipher_suites/0, cipher_suites/1,
connection_info/1, versions/0, session_info/1, format_error/1,
- renegotiate/1, prf/5, negotiated_next_protocol/1]).
+ renegotiate/1, prf/5, negotiated_protocol/1, negotiated_next_protocol/1,
+ connection_information/1, connection_information/2]).
%% Misc
--export([random_bytes/1]).
+-export([random_bytes/1, handle_options/2]).
+
+-deprecated({negotiated_next_protocol, 1, next_major_release}).
+-deprecated({connection_info, 1, next_major_release}).
-include("ssl_api.hrl").
-include("ssl_internal.hrl").
@@ -55,22 +60,19 @@
-spec start() -> ok | {error, reason()}.
-spec start(permanent | transient | temporary) -> ok | {error, reason()}.
%%
-%% Description: Utility function that starts the ssl,
-%% crypto and public_key applications. Default type
-%% is temporary. see application(3)
+%% Description: Utility function that starts the ssl and applications
+%% that it depends on.
+%% see application(3)
%%--------------------------------------------------------------------
start() ->
- application:start(crypto),
- application:start(asn1),
- application:start(public_key),
- application:start(ssl).
-
+ start(temporary).
start(Type) ->
- application:start(crypto, Type),
- application:start(asn1),
- application:start(public_key, Type),
- application:start(ssl, Type).
-
+ case application:ensure_all_started(ssl, Type) of
+ {ok, _} ->
+ ok;
+ Other ->
+ Other
+ end.
%%--------------------------------------------------------------------
-spec stop() -> ok.
%%
@@ -94,12 +96,13 @@ stop() ->
connect(Socket, SslOptions) when is_port(Socket) ->
connect(Socket, SslOptions, infinity).
-connect(Socket, SslOptions0, Timeout) when is_port(Socket) ->
+connect(Socket, SslOptions0, Timeout) when is_port(Socket),
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
{Transport,_,_,_} = proplists:get_value(cb_info, SslOptions0,
{gen_tcp, tcp, tcp_closed, tcp_error}),
EmulatedOptions = ssl_socket:emulated_options(),
{ok, SocketValues} = ssl_socket:getopts(Transport, Socket, EmulatedOptions),
- try handle_options(SslOptions0 ++ SocketValues) of
+ try handle_options(SslOptions0 ++ SocketValues, client) of
{ok, #config{transport_info = CbInfo, ssl = SslOptions, emulated = EmOpts,
connection_cb = ConnectionCb}} ->
@@ -120,8 +123,8 @@ connect(Socket, SslOptions0, Timeout) when is_port(Socket) ->
connect(Host, Port, Options) ->
connect(Host, Port, Options, infinity).
-connect(Host, Port, Options, Timeout) ->
- try handle_options(Options) of
+connect(Host, Port, Options, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
+ try handle_options(Options, client) of
{ok, Config} ->
do_connect(Host,Port,Config,Timeout)
catch
@@ -139,7 +142,7 @@ listen(_Port, []) ->
{error, nooptions};
listen(Port, Options0) ->
try
- {ok, Config} = handle_options(Options0),
+ {ok, Config} = handle_options(Options0, server),
ConnectionCb = connection_cb(Options0),
#config{transport_info = {Transport, _, _, _}, inet_user = Options, connection_cb = ConnectionCb,
ssl = SslOpts, emulated = EmOpts} = Config,
@@ -170,7 +173,7 @@ transport_accept(#sslsocket{pid = {ListenSocket,
#config{transport_info = {Transport,_,_, _} =CbInfo,
connection_cb = ConnectionCb,
ssl = SslOpts,
- emulated = Tracker}}}, Timeout) ->
+ emulated = Tracker}}}, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
case Transport:accept(ListenSocket, Timeout) of
{ok, Socket} ->
{ok, EmOpts} = ssl_socket:get_emulated_opts(Tracker),
@@ -203,29 +206,31 @@ transport_accept(#sslsocket{pid = {ListenSocket,
ssl_accept(ListenSocket) ->
ssl_accept(ListenSocket, infinity).
-ssl_accept(#sslsocket{} = Socket, Timeout) ->
+ssl_accept(#sslsocket{} = Socket, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
ssl_connection:handshake(Socket, Timeout);
-
-ssl_accept(ListenSocket, SslOptions) when is_port(ListenSocket) ->
+
+ssl_accept(ListenSocket, SslOptions) when is_port(ListenSocket) ->
ssl_accept(ListenSocket, SslOptions, infinity).
-ssl_accept(#sslsocket{} = Socket, [], Timeout) ->
+ssl_accept(#sslsocket{} = Socket, [], Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
ssl_accept(#sslsocket{} = Socket, Timeout);
-ssl_accept(#sslsocket{fd = {_, _, _, Tracker}} = Socket, SslOpts0, Timeout) ->
- try
- {ok, EmOpts, InheritedSslOpts} = ssl_socket:get_all_opts(Tracker),
+ssl_accept(#sslsocket{fd = {_, _, _, Tracker}} = Socket, SslOpts0, Timeout) when
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
+ try
+ {ok, EmOpts, InheritedSslOpts} = ssl_socket:get_all_opts(Tracker),
SslOpts = handle_options(SslOpts0, InheritedSslOpts),
ssl_connection:handshake(Socket, {SslOpts, emulated_socket_options(EmOpts, #socket_options{})}, Timeout)
catch
Error = {error, _Reason} -> Error
end;
-ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) ->
+ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket),
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
{Transport,_,_,_} =
proplists:get_value(cb_info, SslOptions, {gen_tcp, tcp, tcp_closed, tcp_error}),
EmulatedOptions = ssl_socket:emulated_options(),
{ok, SocketValues} = ssl_socket:getopts(Transport, Socket, EmulatedOptions),
ConnetionCb = connection_cb(SslOptions),
- try handle_options(SslOptions ++ SocketValues) of
+ try handle_options(SslOptions ++ SocketValues, server) of
{ok, #config{transport_info = CbInfo, ssl = SslOpts, emulated = EmOpts}} ->
ok = ssl_socket:setopts(Transport, Socket, ssl_socket:internal_inet_values()),
{ok, Port} = ssl_socket:port(Transport, Socket),
@@ -242,11 +247,27 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) ->
%% Description: Close an ssl connection
%%--------------------------------------------------------------------
close(#sslsocket{pid = Pid}) when is_pid(Pid) ->
- ssl_connection:close(Pid);
+ ssl_connection:close(Pid, {close, ?DEFAULT_TIMEOUT});
close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_, _, _}}}}) ->
Transport:close(ListenSocket).
%%--------------------------------------------------------------------
+-spec close(#sslsocket{}, timeout() | {pid(), integer()}) -> term().
+%%
+%% Description: Close an ssl connection
+%%--------------------------------------------------------------------
+close(#sslsocket{pid = TLSPid},
+ {Pid, Timeout} = DownGrade) when is_pid(TLSPid),
+ is_pid(Pid),
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
+ ssl_connection:close(TLSPid, {close, DownGrade});
+close(#sslsocket{pid = TLSPid}, Timeout) when is_pid(TLSPid),
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
+ ssl_connection:close(TLSPid, {close, Timeout});
+close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_, _, _}}}}, _) ->
+ Transport:close(ListenSocket).
+
+%%--------------------------------------------------------------------
-spec send(#sslsocket{}, iodata()) -> ok | {error, reason()}.
%%
%% Description: Sends data over the ssl connection
@@ -264,7 +285,8 @@ send(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport, _, _, _}
%%--------------------------------------------------------------------
recv(Socket, Length) ->
recv(Socket, Length, infinity).
-recv(#sslsocket{pid = Pid}, Length, Timeout) when is_pid(Pid) ->
+recv(#sslsocket{pid = Pid}, Length, Timeout) when is_pid(Pid),
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
ssl_connection:recv(Pid, Length, Timeout);
recv(#sslsocket{pid = {Listen,
#config{transport_info = {Transport, _, _, _}}}}, _,_) when is_port(Listen)->
@@ -284,16 +306,50 @@ controlling_process(#sslsocket{pid = {Listen,
is_pid(NewOwner) ->
Transport:controlling_process(Listen, NewOwner).
+
%%--------------------------------------------------------------------
+-spec connection_information(#sslsocket{}) -> {ok, list()} | {error, reason()}.
+%%
+%% Description: Return SSL information for the connection
+%%--------------------------------------------------------------------
+connection_information(#sslsocket{pid = Pid}) when is_pid(Pid) ->
+ case ssl_connection:connection_information(Pid) of
+ {ok, Info} ->
+ {ok, [Item || Item = {_Key, Value} <- Info, Value =/= undefined]};
+ Error ->
+ Error
+ end;
+connection_information(#sslsocket{pid = {Listen, _}}) when is_port(Listen) ->
+ {error, enotconn}.
+
+%%--------------------------------------------------------------------
+-spec connection_information(#sslsocket{}, [atom()]) -> {ok, list()} | {error, reason()}.
+%%
+%% Description: Return SSL information for the connection
+%%--------------------------------------------------------------------
+connection_information(#sslsocket{} = SSLSocket, Items) ->
+ case connection_information(SSLSocket) of
+ {ok, Info} ->
+ {ok, [Item || Item = {Key, Value} <- Info, lists:member(Key, Items),
+ Value =/= undefined]};
+ Error ->
+ Error
+ end.
+
+%%--------------------------------------------------------------------
+%% Deprecated
-spec connection_info(#sslsocket{}) -> {ok, {tls_record:tls_atom_version(), ssl_cipher:erl_cipher_suite()}} |
{error, reason()}.
%%
%% Description: Returns ssl protocol and cipher used for the connection
%%--------------------------------------------------------------------
-connection_info(#sslsocket{pid = Pid}) when is_pid(Pid) ->
- ssl_connection:info(Pid);
-connection_info(#sslsocket{pid = {Listen, _}}) when is_port(Listen) ->
- {error, enotconn}.
+connection_info(#sslsocket{} = SSLSocket) ->
+ case connection_information(SSLSocket) of
+ {ok, Result} ->
+ {ok, {proplists:get_value(protocol, Result), proplists:get_value(cipher_suite, Result)}};
+ Error ->
+ Error
+ end.
%%--------------------------------------------------------------------
-spec peername(#sslsocket{}) -> {ok, {inet:ip_address(), inet:port_number()}} | {error, reason()}.
@@ -321,13 +377,13 @@ peercert(#sslsocket{pid = {Listen, _}}) when is_port(Listen) ->
{error, enotconn}.
%%--------------------------------------------------------------------
--spec suite_definition(ssl_cipher:cipher_suite()) -> ssl_cipher:erl_cipher_suite().
+-spec negotiated_protocol(#sslsocket{}) -> {ok, binary()} | {error, reason()}.
%%
-%% Description: Return erlang cipher suite definition.
+%% Description: Returns the protocol that has been negotiated. If no
+%% protocol has been negotiated will return {error, protocol_not_negotiated}
%%--------------------------------------------------------------------
-suite_definition(S) ->
- {KeyExchange, Cipher, Hash, _} = ssl_cipher:suite_definition(S),
- {KeyExchange, Cipher, Hash}.
+negotiated_protocol(#sslsocket{pid = Pid}) ->
+ ssl_connection:negotiated_protocol(Pid).
%%--------------------------------------------------------------------
-spec negotiated_next_protocol(#sslsocket{}) -> {ok, binary()} | {error, reason()}.
@@ -335,8 +391,13 @@ suite_definition(S) ->
%% Description: Returns the next protocol that has been negotiated. If no
%% protocol has been negotiated will return {error, next_protocol_not_negotiated}
%%--------------------------------------------------------------------
-negotiated_next_protocol(#sslsocket{pid = Pid}) ->
- ssl_connection:negotiated_next_protocol(Pid).
+negotiated_next_protocol(Socket) ->
+ case negotiated_protocol(Socket) of
+ {error, protocol_not_negotiated} ->
+ {error, next_protocol_not_negotiated};
+ Res ->
+ Res
+ end.
%%--------------------------------------------------------------------
-spec cipher_suites(erlang | openssl | all) -> [ssl_cipher:erl_cipher_suite()] |
@@ -345,7 +406,7 @@ negotiated_next_protocol(#sslsocket{pid = Pid}) ->
%%--------------------------------------------------------------------
cipher_suites(erlang) ->
Version = tls_record:highest_protocol_version([]),
- ssl_cipher:filter_suites([suite_definition(S)
+ ssl_cipher:filter_suites([ssl_cipher:erl_suite_definition(S)
|| S <- ssl_cipher:suites(Version)]);
cipher_suites(openssl) ->
Version = tls_record:highest_protocol_version([]),
@@ -353,12 +414,8 @@ cipher_suites(openssl) ->
|| S <- ssl_cipher:filter_suites(ssl_cipher:suites(Version))];
cipher_suites(all) ->
Version = tls_record:highest_protocol_version([]),
- Supported = ssl_cipher:all_suites(Version)
- ++ ssl_cipher:anonymous_suites()
- ++ ssl_cipher:psk_suites(Version)
- ++ ssl_cipher:srp_suites(),
- ssl_cipher:filter_suites([suite_definition(S) || S <- Supported]).
-
+ ssl_cipher:filter_suites([ssl_cipher:erl_suite_definition(S)
+ || S <-ssl_cipher:all_suites(Version)]).
cipher_suites() ->
cipher_suites(erlang).
@@ -454,7 +511,7 @@ session_info(#sslsocket{pid = {Listen,_}}) when is_port(Listen) ->
versions() ->
Vsns = tls_record:supported_protocol_versions(),
SupportedVsns = [tls_record:protocol_version(Vsn) || Vsn <- Vsns],
- AvailableVsns = ?ALL_SUPPORTED_VERSIONS,
+ AvailableVsns = ?ALL_AVAILABLE_VERSIONS,
%% TODO Add DTLS versions when supported
[{ssl_app, ?VSN}, {supported, SupportedVsns}, {available, AvailableVsns}].
@@ -569,7 +626,8 @@ handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
cacertfile = CaCertFile0} = InheritedSslOpts) ->
RecordCB = record_cb(Protocol),
CaCerts = handle_option(cacerts, Opts0, CaCerts0),
- {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder} = handle_verify_options(Opts0, CaCerts),
+ {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder,
+ VerifyClientOnce} = handle_verify_options(Opts0, CaCerts),
CaCertFile = case proplists:get_value(cacertfile, Opts0, CaCertFile0) of
undefined ->
CaCertDefault;
@@ -582,11 +640,12 @@ handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
verify = Verify,
verify_fun = VerifyFun,
partial_chain = PartialChainHanlder,
- fail_if_no_peer_cert = FailIfNoPeerCert},
+ fail_if_no_peer_cert = FailIfNoPeerCert,
+ verify_client_once = VerifyClientOnce},
SslOpts1 = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
end, Opts0, [cacerts, cacertfile, verify, verify_fun, partial_chain,
- fail_if_no_peer_cert]),
+ fail_if_no_peer_cert, verify_client_once]),
case handle_option(versions, SslOpts1, []) of
[] ->
new_ssl_options(SslOpts1, NewVerifyOpts, RecordCB);
@@ -594,10 +653,10 @@ handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
Versions = [RecordCB:protocol_version(Vsn) || Vsn <- Value],
new_ssl_options(proplists:delete(versions, SslOpts1),
NewVerifyOpts#ssl_options{versions = Versions}, record_cb(Protocol))
- end.
+ end;
%% Handle all options in listen and connect
-handle_options(Opts0) ->
+handle_options(Opts0, Role) ->
Opts = proplists:expand([{binary, [{mode, binary}]},
{list, [{mode, list}]}], Opts0),
assert_proplist(Opts),
@@ -606,7 +665,7 @@ handle_options(Opts0) ->
ReuseSessionFun = fun(_, _, _, _) -> true end,
CaCerts = handle_option(cacerts, Opts, undefined),
- {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder} =
+ {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder, VerifyClientOnce} =
handle_verify_options(Opts, CaCerts),
CertFile = handle_option(certfile, Opts, <<>>),
@@ -625,7 +684,7 @@ handle_options(Opts0) ->
verify_fun = VerifyFun,
partial_chain = PartialChainHanlder,
fail_if_no_peer_cert = FailIfNoPeerCert,
- verify_client_once = handle_option(verify_client_once, Opts, false),
+ verify_client_once = VerifyClientOnce,
depth = handle_option(depth, Opts, 1),
cert = handle_option(cert, Opts, undefined),
certfile = CertFile,
@@ -641,13 +700,24 @@ handle_options(Opts0) ->
srp_identity = handle_option(srp_identity, Opts, undefined),
ciphers = handle_cipher_option(proplists:get_value(ciphers, Opts, []),
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)),
+ RecordCb:highest_protocol_version(Versions)),
%% Server side option
reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun),
reuse_sessions = handle_option(reuse_sessions, Opts, true),
secure_renegotiate = handle_option(secure_renegotiate, Opts, false),
+ client_renegotiation = handle_option(client_renegotiation, Opts,
+ default_option_role(server, true, Role),
+ server, Role),
renegotiate_at = handle_option(renegotiate_at, Opts, ?DEFAULT_RENEGOTIATE_AT),
hibernate_after = handle_option(hibernate_after, Opts, undefined),
erl_dist = handle_option(erl_dist, Opts, false),
+ alpn_advertised_protocols =
+ handle_option(alpn_advertised_protocols, Opts, undefined),
+ alpn_preferred_protocols =
+ handle_option(alpn_preferred_protocols, Opts, undefined),
next_protocols_advertised =
handle_option(next_protocols_advertised, Opts, undefined),
next_protocol_selector =
@@ -655,10 +725,20 @@ handle_options(Opts0) ->
handle_option(client_preferred_next_protocols, Opts, undefined)),
log_alert = handle_option(log_alert, Opts, true),
server_name_indication = handle_option(server_name_indication, Opts, undefined),
- honor_cipher_order = handle_option(honor_cipher_order, Opts, false),
+ sni_hosts = handle_option(sni_hosts, Opts, []),
+ sni_fun = handle_option(sni_fun, Opts, undefined),
+ honor_cipher_order = handle_option(honor_cipher_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),
- fallback = proplists:get_value(fallback, Opts, false)
+ fallback = handle_option(fallback, Opts,
+ proplists:get_value(fallback, Opts,
+ default_option_role(client,
+ false, Role)),
+ client, Role),
+ crl_check = handle_option(crl_check, Opts, false),
+ crl_cache = handle_option(crl_cache, Opts, {ssl_crl_cache, {internal, []}})
},
CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}),
@@ -667,12 +747,13 @@ handle_options(Opts0) ->
depth, cert, certfile, key, keyfile,
password, cacerts, cacertfile, dh, dhfile,
user_lookup_fun, psk_identity, srp_identity, ciphers,
- reuse_session, reuse_sessions, ssl_imp,
+ reuse_session, reuse_sessions, ssl_imp, client_renegotiation,
cb_info, renegotiate_at, secure_renegotiate, hibernate_after,
- erl_dist, next_protocols_advertised,
+ erl_dist, alpn_advertised_protocols, sni_hosts, sni_fun,
+ alpn_preferred_protocols, next_protocols_advertised,
client_preferred_next_protocols, log_alert,
- server_name_indication, honor_cipher_order, padding_check,
- fallback],
+ server_name_indication, honor_cipher_order, padding_check, crl_check, crl_cache,
+ fallback, signature_algs],
SockOpts = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
@@ -685,11 +766,29 @@ handle_options(Opts0) ->
inet_user = SockOpts, transport_info = CbInfo, connection_cb = ConnetionCb
}}.
+
+
+handle_option(OptionName, Opts, Default, Role, Role) ->
+ handle_option(OptionName, Opts, Default);
+handle_option(_, _, undefined = Value, _, _) ->
+ Value.
+
+handle_option(sni_fun, Opts, Default) ->
+ OptFun = validate_option(sni_fun,
+ proplists:get_value(sni_fun, Opts, Default)),
+ OptHosts = proplists:get_value(sni_hosts, Opts, undefined),
+ case {OptFun, OptHosts} of
+ {Default, _} ->
+ Default;
+ {_, undefined} ->
+ OptFun;
+ _ ->
+ throw({error, {conflict_options, [sni_fun, sni_hosts]}})
+ end;
handle_option(OptionName, Opts, Default) ->
validate_option(OptionName,
proplists:get_value(OptionName, Opts, Default)).
-
validate_option(versions, Versions) ->
validate_versions(Versions, Versions);
validate_option(verify, Value)
@@ -741,6 +840,7 @@ validate_option(key, {KeyType, Value}) when is_binary(Value),
KeyType == dsa; %% Backwards compatibility
KeyType == 'RSAPrivateKey';
KeyType == 'DSAPrivateKey';
+ KeyType == 'ECPrivateKey';
KeyType == 'PrivateKeyInfo' ->
{KeyType, Value};
@@ -796,6 +896,8 @@ validate_option(reuse_sessions, Value) when is_boolean(Value) ->
validate_option(secure_renegotiate, Value) when is_boolean(Value) ->
Value;
+validate_option(client_renegotiation, Value) when is_boolean(Value) ->
+ Value;
validate_option(renegotiate_at, Value) when is_integer(Value) ->
erlang:min(Value, ?DEFAULT_RENEGOTIATE_AT);
@@ -805,6 +907,20 @@ validate_option(hibernate_after, Value) when is_integer(Value), Value >= 0 ->
Value;
validate_option(erl_dist,Value) when is_boolean(Value) ->
Value;
+validate_option(Opt, Value)
+ when Opt =:= alpn_advertised_protocols orelse Opt =:= alpn_preferred_protocols,
+ is_list(Value) ->
+ case tls_record:highest_protocol_version([]) of
+ {3,0} ->
+ throw({error, {options, {not_supported_in_sslv3, {Opt, Value}}}});
+ _ ->
+ validate_binary_list(Opt, Value),
+ Value
+ end;
+validate_option(Opt, Value)
+ when Opt =:= alpn_advertised_protocols orelse Opt =:= alpn_preferred_protocols,
+ Value =:= undefined ->
+ undefined;
validate_option(client_preferred_next_protocols = Opt, {Precedence, PreferredProtocols} = Value)
when is_list(PreferredProtocols) ->
case tls_record:highest_protocol_version([]) of
@@ -848,15 +964,53 @@ validate_option(server_name_indication, disable) ->
disable;
validate_option(server_name_indication, undefined) ->
undefined;
+validate_option(sni_hosts, []) ->
+ [];
+validate_option(sni_hosts, [{Hostname, SSLOptions} | Tail]) when is_list(Hostname) ->
+ RecursiveSNIOptions = proplists:get_value(sni_hosts, SSLOptions, undefined),
+ case RecursiveSNIOptions of
+ undefined ->
+ [{Hostname, validate_options(SSLOptions)} | validate_option(sni_hosts, Tail)];
+ _ ->
+ throw({error, {options, {sni_hosts, RecursiveSNIOptions}}})
+ end;
+validate_option(sni_fun, undefined) ->
+ undefined;
+validate_option(sni_fun, Fun) when is_function(Fun) ->
+ Fun;
validate_option(honor_cipher_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) ->
Value;
+validate_option(crl_check, Value) when is_boolean(Value) ->
+ Value;
+validate_option(crl_check, Value) when (Value == best_effort) or (Value == peer) ->
+ Value;
+validate_option(crl_cache, {Cb, {_Handle, Options}} = Value) when is_atom(Cb) and is_list(Options) ->
+ Value;
validate_option(Opt, Value) ->
throw({error, {options, {Opt, Value}}}).
+handle_hashsigns_option(Value, {Major, Minor} = Version) when is_list(Value)
+ andalso Major >= 3 andalso Minor >= 3->
+ case tls_v1:signature_algs(Version, Value) of
+ [] ->
+ throw({error, {options, no_supported_algorithms, {signature_algs, Value}}});
+ _ ->
+ Value
+ end;
+handle_hashsigns_option(_, {Major, Minor} = Version) when Major >= 3 andalso Minor >= 3->
+ handle_hashsigns_option(tls_v1:default_signature_algs(Version), Version);
+handle_hashsigns_option(_, _Version) ->
+ undefined.
+
+validate_options([]) ->
+ [];
+validate_options([{Opt, Value} | Tail]) ->
+ [{Opt, validate_option(Opt, Value)} | validate_options(Tail)].
+
validate_npn_ordering(client) ->
ok;
validate_npn_ordering(server) ->
@@ -951,18 +1105,12 @@ binary_cipher_suites(Version, []) ->
%% Defaults to all supported suites that does
%% not require explicit configuration
ssl_cipher:filter_suites(ssl_cipher:suites(Version));
-binary_cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> %% Backwards compatibility
- Ciphers = [{KeyExchange, Cipher, Hash} || {KeyExchange, Cipher, Hash, _} <- Ciphers0],
- binary_cipher_suites(Version, Ciphers);
-binary_cipher_suites(Version, [{_,_,_}| _] = Ciphers0) ->
+binary_cipher_suites(Version, [Tuple|_] = Ciphers0) when is_tuple(Tuple) ->
Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
binary_cipher_suites(Version, Ciphers);
binary_cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
- All = ssl_cipher:suites(Version)
- ++ ssl_cipher:anonymous_suites()
- ++ ssl_cipher:psk_suites(Version)
- ++ ssl_cipher:srp_suites(),
+ All = ssl_cipher:all_suites(Version),
case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, All)] of
[] ->
%% Defaults to all supported suites that does
@@ -1067,6 +1215,8 @@ assert_proplist([]) ->
assert_proplist([{Key,_} | Rest]) when is_atom(Key) ->
assert_proplist(Rest);
%% Handle exceptions
+assert_proplist([{raw,_,_,_} | Rest]) ->
+ assert_proplist(Rest);
assert_proplist([inet | Rest]) ->
assert_proplist(Rest);
assert_proplist([inet6 | Rest]) ->
@@ -1091,7 +1241,8 @@ emulated_socket_options(InetValues, #socket_options{
new_ssl_options([], #ssl_options{} = Opts, _) ->
Opts;
new_ssl_options([{verify_client_once, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
- new_ssl_options(Rest, Opts#ssl_options{verify_client_once = validate_option(verify_client_once, Value)}, RecordCB);
+ new_ssl_options(Rest, Opts#ssl_options{verify_client_once =
+ validate_option(verify_client_once, Value)}, RecordCB);
new_ssl_options([{depth, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest, Opts#ssl_options{depth = validate_option(depth, Value)}, RecordCB);
new_ssl_options([{cert, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
@@ -1128,8 +1279,14 @@ new_ssl_options([{renegotiate_at, Value} | Rest], #ssl_options{} = Opts, RecordC
new_ssl_options(Rest, Opts#ssl_options{ renegotiate_at = validate_option(renegotiate_at, Value)}, RecordCB);
new_ssl_options([{secure_renegotiate, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest, Opts#ssl_options{secure_renegotiate = validate_option(secure_renegotiate, Value)}, RecordCB);
+new_ssl_options([{client_renegotiation, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{client_renegotiation = validate_option(client_renegotiation, Value)}, RecordCB);
new_ssl_options([{hibernate_after, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest, Opts#ssl_options{hibernate_after = validate_option(hibernate_after, Value)}, RecordCB);
+new_ssl_options([{alpn_advertised_protocols, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{alpn_advertised_protocols = validate_option(alpn_advertised_protocols, Value)}, RecordCB);
+new_ssl_options([{alpn_preferred_protocols, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{alpn_preferred_protocols = validate_option(alpn_preferred_protocols, Value)}, RecordCB);
new_ssl_options([{next_protocols_advertised, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest, Opts#ssl_options{next_protocols_advertised = validate_option(next_protocols_advertised, Value)}, RecordCB);
new_ssl_options([{client_preferred_next_protocols, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
@@ -1141,6 +1298,13 @@ 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([{signature_algs, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest,
+ Opts#ssl_options{signature_algs =
+ handle_hashsigns_option(Value,
+ RecordCB:highest_protocol_version())},
+ RecordCB);
+
new_ssl_options([{Key, Value} | _Rest], #ssl_options{}, _) ->
throw({error, {options, {Key, Value}}}).
@@ -1149,6 +1313,12 @@ handle_verify_options(Opts, CaCerts) ->
DefaultVerifyNoneFun =
{fun(_,{bad_cert, _}, UserState) ->
{valid, UserState};
+ (_,{extension, #'Extension'{critical = true}}, UserState) ->
+ %% This extension is marked as critical, so
+ %% certificate verification should fail if we don't
+ %% understand the extension. However, this is
+ %% `verify_none', so let's accept it anyway.
+ {valid, UserState};
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
@@ -1164,28 +1334,35 @@ handle_verify_options(Opts, CaCerts) ->
PartialChainHanlder = handle_option(partial_chain, Opts,
fun(_) -> unknown_ca end),
+ VerifyClientOnce = handle_option(verify_client_once, Opts, false),
+
%% Handle 0, 1, 2 for backwards compatibility
case proplists:get_value(verify, Opts, verify_none) of
0 ->
{verify_none, false,
ca_cert_default(verify_none, VerifyNoneFun, CaCerts),
- VerifyNoneFun, PartialChainHanlder};
+ VerifyNoneFun, PartialChainHanlder, VerifyClientOnce};
1 ->
{verify_peer, false,
ca_cert_default(verify_peer, UserVerifyFun, CaCerts),
- UserVerifyFun, PartialChainHanlder};
+ UserVerifyFun, PartialChainHanlder, VerifyClientOnce};
2 ->
{verify_peer, true,
ca_cert_default(verify_peer, UserVerifyFun, CaCerts),
- UserVerifyFun, PartialChainHanlder};
+ UserVerifyFun, PartialChainHanlder, VerifyClientOnce};
verify_none ->
{verify_none, false,
ca_cert_default(verify_none, VerifyNoneFun, CaCerts),
- VerifyNoneFun, PartialChainHanlder};
+ VerifyNoneFun, PartialChainHanlder, VerifyClientOnce};
verify_peer ->
{verify_peer, UserFailIfNoPeerCert,
ca_cert_default(verify_peer, UserVerifyFun, CaCerts),
- UserVerifyFun, PartialChainHanlder};
+ UserVerifyFun, PartialChainHanlder, VerifyClientOnce};
Value ->
throw({error, {options, {verify, Value}}})
end.
+
+default_option_role(Role, Value, Role) ->
+ Value;
+default_option_role(_,_,_) ->
+ undefined.
diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl
index 9e372f739a..3e35e24527 100644
--- a/lib/ssl/src/ssl_alert.erl
+++ b/lib/ssl/src/ssl_alert.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -163,5 +164,7 @@ description_txt(?UNKNOWN_PSK_IDENTITY) ->
"unknown psk identity";
description_txt(?INAPPROPRIATE_FALLBACK) ->
"inappropriate fallback";
+description_txt(?NO_APPLICATION_PROTOCOL) ->
+ "no application protocol";
description_txt(Enum) ->
lists:flatten(io_lib:format("unsupported/unknown alert: ~p", [Enum])).
diff --git a/lib/ssl/src/ssl_alert.hrl b/lib/ssl/src/ssl_alert.hrl
index a3619e4a35..8c4bd08d31 100644
--- a/lib/ssl/src/ssl_alert.hrl
+++ b/lib/ssl/src/ssl_alert.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -69,6 +70,8 @@
%% bad_certificate_hash_value(114),
%% RFC 4366
%% unknown_psk_identity(115),
+%% RFC 7301
+%% no_application_protocol(120),
%% (255)
%% } AlertDescription;
@@ -103,6 +106,7 @@
-define(BAD_CERTIFICATE_STATUS_RESPONSE, 113).
-define(BAD_CERTIFICATE_HASH_VALUE, 114).
-define(UNKNOWN_PSK_IDENTITY, 115).
+-define(NO_APPLICATION_PROTOCOL, 120).
-define(ALERT_REC(Level,Desc), #alert{level=Level,description=Desc,where={?FILE, ?LINE}}).
diff --git a/lib/ssl/src/ssl_api.hrl b/lib/ssl/src/ssl_api.hrl
index 22185ff60a..ceef7b0438 100644
--- a/lib/ssl/src/ssl_api.hrl
+++ b/lib/ssl/src/ssl_api.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -49,6 +50,8 @@
{srp_identity, {string(), string()}} |
{ciphers, ciphers()} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} |
{reuse_session, fun()} | {hibernate_after, integer()|undefined} |
+ {alpn_advertised_protocols, [binary()]} |
+ {alpn_preferred_protocols, [binary()]} |
{next_protocols_advertised, list(binary())} |
{client_preferred_next_protocols, binary(), client | server, list(binary())}.
diff --git a/lib/ssl/src/ssl_app.erl b/lib/ssl/src/ssl_app.erl
index 0c475a6d01..191300b0a1 100644
--- a/lib/ssl/src/ssl_app.erl
+++ b/lib/ssl/src/ssl_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index 30d224fee2..e9dc5764a3 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014 All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015 All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,7 +34,8 @@
-export([trusted_cert_and_path/4,
certificate_chain/3,
file_to_certificats/2,
- validate_extension/3,
+ file_to_crls/2,
+ validate/3,
is_valid_extkey_usage/2,
is_valid_key_usage/2,
select_extension/2,
@@ -54,15 +56,15 @@
%% errors. Returns {RootCert, Path, VerifyErrors}
%%--------------------------------------------------------------------
trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef, PartialChainHandler) ->
- Path = [Cert | _] = lists:reverse(CertChain),
- OtpCert = public_key:pkix_decode_cert(Cert, otp),
+ Path = [BinCert | _] = lists:reverse(CertChain),
+ OtpCert = public_key:pkix_decode_cert(BinCert, otp),
SignedAndIssuerID =
case public_key:pkix_is_self_signed(OtpCert) of
true ->
{ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self),
{self, IssuerId};
false ->
- other_issuer(OtpCert, CertDbHandle)
+ other_issuer(OtpCert, BinCert, CertDbHandle)
end,
case SignedAndIssuerID of
@@ -83,16 +85,19 @@ trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef, PartialChainHandler) -
end.
%%--------------------------------------------------------------------
--spec certificate_chain(undefined | binary(), db_handle(), certdb_ref()) ->
- {error, no_cert} | {ok, [der_cert()]}.
+-spec certificate_chain(undefined | binary() | #'OTPCertificate'{} , db_handle(), certdb_ref()) ->
+ {error, no_cert} | {ok, #'OTPCertificate'{} | undefined, [der_cert()]}.
%%
%% Description: Return the certificate chain to send to peer.
%%--------------------------------------------------------------------
certificate_chain(undefined, _, _) ->
{error, no_cert};
-certificate_chain(OwnCert, CertDbHandle, CertsDbRef) ->
+certificate_chain(OwnCert, CertDbHandle, CertsDbRef) when is_binary(OwnCert) ->
ErlCert = public_key:pkix_decode_cert(OwnCert, otp),
- certificate_chain(ErlCert, OwnCert, CertDbHandle, CertsDbRef, [OwnCert]).
+ certificate_chain(ErlCert, OwnCert, CertDbHandle, CertsDbRef, [OwnCert]);
+certificate_chain(OwnCert, CertDbHandle, CertsDbRef) ->
+ DerCert = public_key:pkix_encode('OTPCertificate', OwnCert, otp),
+ certificate_chain(OwnCert, DerCert, CertDbHandle, CertsDbRef, [DerCert]).
%%--------------------------------------------------------------------
-spec file_to_certificats(binary(), term()) -> [der_cert()].
%%
@@ -101,29 +106,39 @@ certificate_chain(OwnCert, CertDbHandle, CertsDbRef) ->
file_to_certificats(File, DbHandle) ->
{ok, List} = ssl_manager:cache_pem_file(File, DbHandle),
[Bin || {'Certificate', Bin, not_encrypted} <- List].
+
+%%--------------------------------------------------------------------
+-spec file_to_crls(binary(), term()) -> [der_cert()].
+%%
+%% Description: Return list of DER encoded certificates.
+%%--------------------------------------------------------------------
+file_to_crls(File, DbHandle) ->
+ {ok, List} = ssl_manager:cache_pem_file(File, DbHandle),
+ [Bin || {'CertificateList', Bin, not_encrypted} <- List].
+
%%--------------------------------------------------------------------
--spec validate_extension(term(), {extension, #'Extension'{}} | {bad_cert, atom()} | valid,
- term()) -> {valid, term()} |
- {fail, tuple()} |
- {unknown, term()}.
+-spec validate(term(), {extension, #'Extension'{}} | {bad_cert, atom()} | valid,
+ term()) -> {valid, term()} |
+ {fail, tuple()} |
+ {unknown, term()}.
%%
%% Description: Validates ssl/tls specific extensions
%%--------------------------------------------------------------------
-validate_extension(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage',
- extnValue = KeyUse}}, Role) ->
+validate(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage',
+ extnValue = KeyUse}}, {Role, _,_, _, _}) ->
case is_valid_extkey_usage(KeyUse, Role) of
true ->
{valid, Role};
false ->
{fail, {bad_cert, invalid_ext_key_usage}}
end;
-validate_extension(_, {bad_cert, _} = Reason, _) ->
- {fail, Reason};
-validate_extension(_, {extension, _}, Role) ->
+validate(_, {extension, _}, Role) ->
{unknown, Role};
-validate_extension(_, valid, Role) ->
+validate(_, {bad_cert, _} = Reason, _) ->
+ {fail, Reason};
+validate(_, valid, Role) ->
{valid, Role};
-validate_extension(_, valid_peer, Role) ->
+validate(_, valid_peer, Role) ->
{valid, Role}.
%%--------------------------------------------------------------------
@@ -172,7 +187,7 @@ public_key_type(?'id-ecPublicKey') ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-certificate_chain(OtpCert, _Cert, CertDbHandle, CertsDbRef, Chain) ->
+certificate_chain(OtpCert, BinCert, CertDbHandle, CertsDbRef, Chain) ->
IssuerAndSelfSigned =
case public_key:pkix_is_self_signed(OtpCert) of
true ->
@@ -185,7 +200,7 @@ certificate_chain(OtpCert, _Cert, CertDbHandle, CertsDbRef, Chain) ->
{_, true = SelfSigned} ->
certificate_chain(CertDbHandle, CertsDbRef, Chain, ignore, ignore, SelfSigned);
{{error, issuer_not_found}, SelfSigned} ->
- case find_issuer(OtpCert, CertDbHandle) of
+ case find_issuer(OtpCert, BinCert, CertDbHandle) of
{ok, {SerialNr, Issuer}} ->
certificate_chain(CertDbHandle, CertsDbRef, Chain,
SerialNr, Issuer, SelfSigned);
@@ -194,14 +209,14 @@ certificate_chain(OtpCert, _Cert, CertDbHandle, CertsDbRef, Chain) ->
%% certificate. The verification of the
%% cert chain will fail if guess is
%% incorrect.
- {ok, lists:reverse(Chain)}
+ {ok, undefined, lists:reverse(Chain)}
end;
{{ok, {SerialNr, Issuer}}, SelfSigned} ->
certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, SelfSigned)
end.
-certificate_chain(_,_, Chain, _SerialNr, _Issuer, true) ->
- {ok, lists:reverse(Chain)};
+certificate_chain(_, _, [RootCert | _] = Chain, _, _, true) ->
+ {ok, RootCert, lists:reverse(Chain)};
certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) ->
case ssl_manager:lookup_trusted_cert(CertDbHandle, CertsDbRef,
@@ -214,15 +229,15 @@ certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned
%% The trusted cert may be obmitted from the chain as the
%% counter part needs to have it anyway to be able to
%% verify it.
- {ok, lists:reverse(Chain)}
+ {ok, undefined, lists:reverse(Chain)}
end.
-find_issuer(OtpCert, CertDbHandle) ->
+find_issuer(OtpCert, BinCert, CertDbHandle) ->
IsIssuerFun =
fun({_Key, {_Der, #'OTPCertificate'{} = ErlCertCandidate}}, Acc) ->
case public_key:pkix_is_issuer(OtpCert, ErlCertCandidate) of
true ->
- case verify_cert_signer(OtpCert, ErlCertCandidate#'OTPCertificate'.tbsCertificate) of
+ case verify_cert_signer(BinCert, ErlCertCandidate#'OTPCertificate'.tbsCertificate) of
true ->
throw(public_key:pkix_issuer_id(ErlCertCandidate, self));
false ->
@@ -250,9 +265,9 @@ is_valid_extkey_usage(KeyUse, server) ->
%% Server wants to verify client
is_valid_key_usage(KeyUse, ?'id-kp-clientAuth').
-verify_cert_signer(OtpCert, SignerTBSCert) ->
+verify_cert_signer(BinCert, SignerTBSCert) ->
PublicKey = public_key(SignerTBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo),
- public_key:pkix_verify(public_key:pkix_encode('OTPCertificate', OtpCert, otp), PublicKey).
+ public_key:pkix_verify(BinCert, PublicKey).
public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'id-ecPublicKey',
parameters = Params},
@@ -266,12 +281,12 @@ public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorith
subjectPublicKey = Key}) ->
{Key, Params}.
-other_issuer(OtpCert, CertDbHandle) ->
+other_issuer(OtpCert, BinCert, CertDbHandle) ->
case public_key:pkix_issuer_id(OtpCert, other) of
{ok, IssuerId} ->
{other, IssuerId};
{error, issuer_not_found} ->
- case find_issuer(OtpCert, CertDbHandle) of
+ case find_issuer(OtpCert, BinCert, CertDbHandle) of
{ok, IssuerId} ->
{other, IssuerId};
Other ->
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index bec0055353..af53d4abf9 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -33,21 +34,27 @@
-include_lib("public_key/include/public_key.hrl").
-export([security_parameters/2, security_parameters/3, suite_definition/1,
- decipher/6, cipher/5, suite/1, suites/1, all_suites/1,
- ec_keyed_suites/0, anonymous_suites/0, psk_suites/1, srp_suites/0,
- openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1,
+ erl_suite_definition/1,
+ cipher_init/3, decipher/6, cipher/5, decipher_aead/6, cipher_aead/6,
+ suite/1, suites/1, all_suites/1,
+ ec_keyed_suites/0, anonymous_suites/1, psk_suites/1, srp_suites/0,
+ rc4_suites/1, openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1,
hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2, is_fallback/1]).
-export_type([cipher_suite/0,
erl_cipher_suite/0, openssl_cipher_suite/0,
- key_algo/0]).
+ hash/0, key_algo/0, sign_algo/0]).
-type cipher() :: null |rc4_128 | idea_cbc | des40_cbc | des_cbc | '3des_ede_cbc'
- | aes_128_cbc | aes_256_cbc.
+ | aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm | chacha20_poly1305.
-type hash() :: null | sha | md5 | sha224 | sha256 | sha384 | sha512.
+-type sign_algo() :: rsa | dsa | ecdsa.
-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa| ecdh_ecdsa | ecdh_rsa| srp_rsa| srp_dss | psk | dhe_psk | rsa_psk | dh_anon | ecdh_anon | srp_anon.
--type erl_cipher_suite() :: {key_algo(), cipher(), hash()}.
--type int_cipher_suite() :: {key_algo(), cipher(), hash(), hash() | default_prf}.
+-type erl_cipher_suite() :: {key_algo(), cipher(), hash()} % Pre TLS 1.2
+ %% TLS 1.2, internally PRE TLS 1.2 will use default_prf
+ | {key_algo(), cipher(), hash(), hash() | default_prf}.
+
+
-type cipher_suite() :: binary().
-type cipher_enum() :: integer().
-type openssl_cipher_suite() :: string().
@@ -87,20 +94,32 @@ security_parameters(Version, CipherSuite, SecParams) ->
hash_size = hash_size(Hash)}.
%%--------------------------------------------------------------------
+-spec cipher_init(cipher_enum(), binary(), binary()) -> #cipher_state{}.
+%%
+%% Description: Initializes the #cipher_state according to BCA
+%%-------------------------------------------------------------------
+cipher_init(?RC4, IV, Key) ->
+ State = crypto:stream_init(rc4, Key),
+ #cipher_state{iv = IV, key = Key, state = State};
+cipher_init(?AES_GCM, IV, Key) ->
+ <<Nonce:64>> = ssl:random_bytes(8),
+ #cipher_state{iv = IV, key = Key, nonce = Nonce};
+cipher_init(_BCA, IV, Key) ->
+ #cipher_state{iv = IV, key = Key}.
+
+%%--------------------------------------------------------------------
-spec cipher(cipher_enum(), #cipher_state{}, binary(), iodata(), ssl_record:ssl_version()) ->
{binary(), #cipher_state{}}.
%%
%% Description: Encrypts the data and the MAC using chipher described
%% by cipher_enum() and updating the cipher state
+%% Used for "MAC then Cipher" suites where first an HMAC of the
+%% data is calculated and the data plus the HMAC is ecncrypted.
%%-------------------------------------------------------------------
cipher(?NULL, CipherState, <<>>, Fragment, _Version) ->
GenStreamCipherList = [Fragment, <<>>],
{GenStreamCipherList, CipherState};
-cipher(?RC4, CipherState, Mac, Fragment, _Version) ->
- State0 = case CipherState#cipher_state.state of
- undefined -> crypto:stream_init(rc4, CipherState#cipher_state.key);
- S -> S
- end,
+cipher(?RC4, CipherState = #cipher_state{state = State0}, Mac, Fragment, _Version) ->
GenStreamCipherList = [Fragment, Mac],
{State1, T} = crypto:stream_encrypt(State0, GenStreamCipherList),
{T, CipherState#cipher_state{state = State1}};
@@ -112,13 +131,40 @@ cipher(?'3DES', CipherState, Mac, Fragment, Version) ->
block_cipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) ->
crypto:block_encrypt(des3_cbc, [K1, K2, K3], IV, T)
end, block_size(des_cbc), CipherState, Mac, Fragment, Version);
-cipher(?AES, CipherState, Mac, Fragment, Version) ->
+cipher(?AES_CBC, CipherState, Mac, Fragment, Version) ->
block_cipher(fun(Key, IV, T) when byte_size(Key) =:= 16 ->
crypto:block_encrypt(aes_cbc128, Key, IV, T);
(Key, IV, T) when byte_size(Key) =:= 32 ->
crypto:block_encrypt(aes_cbc256, Key, IV, T)
end, block_size(aes_128_cbc), CipherState, Mac, Fragment, Version).
+%%--------------------------------------------------------------------
+-spec cipher_aead(cipher_enum(), #cipher_state{}, integer(), binary(), iodata(), ssl_record:ssl_version()) ->
+ {binary(), #cipher_state{}}.
+%%
+%% Description: Encrypts the data and protects associated data (AAD) using chipher
+%% described by cipher_enum() and updating the cipher state
+%% Use for suites that use authenticated encryption with associated data (AEAD)
+%%-------------------------------------------------------------------
+cipher_aead(?AES_GCM, CipherState, SeqNo, AAD, Fragment, Version) ->
+ aead_cipher(aes_gcm, CipherState, SeqNo, AAD, Fragment, Version);
+cipher_aead(?CHACHA20_POLY1305, CipherState, SeqNo, AAD, Fragment, Version) ->
+ aead_cipher(chacha20_poly1305, CipherState, SeqNo, AAD, Fragment, Version).
+
+aead_cipher(chacha20_poly1305, #cipher_state{key=Key} = CipherState, SeqNo, AAD0, Fragment, _Version) ->
+ CipherLen = erlang:iolist_size(Fragment),
+ AAD = <<AAD0/binary, ?UINT16(CipherLen)>>,
+ Nonce = <<SeqNo:64/integer>>,
+ {Content, CipherTag} = crypto:block_encrypt(chacha20_poly1305, Key, Nonce, {AAD, Fragment}),
+ {<<Content/binary, CipherTag/binary>>, CipherState};
+aead_cipher(Type, #cipher_state{key=Key, iv = IV0, nonce = Nonce} = CipherState, _SeqNo, AAD0, Fragment, _Version) ->
+ CipherLen = erlang:iolist_size(Fragment),
+ AAD = <<AAD0/binary, ?UINT16(CipherLen)>>,
+ <<Salt:4/bytes, _/binary>> = IV0,
+ IV = <<Salt/binary, Nonce:64/integer>>,
+ {Content, CipherTag} = crypto:block_encrypt(Type, Key, IV, {AAD, Fragment}),
+ {<<Nonce:64/integer, Content/binary, CipherTag/binary>>, CipherState#cipher_state{nonce = Nonce + 1}}.
+
build_cipher_block(BlockSz, Mac, Fragment) ->
TotSz = byte_size(Mac) + erlang:iolist_size(Fragment) + 1,
{PaddingLength, Padding} = get_padding(TotSz, BlockSz),
@@ -148,14 +194,12 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
%%
%% Description: Decrypts the data and the MAC using cipher described
%% by cipher_enum() and updating the cipher state.
+%% Used for "MAC then Cipher" suites where first the data is decrypted
+%% and the an HMAC of the decrypted data is checked
%%-------------------------------------------------------------------
decipher(?NULL, _HashSz, CipherState, Fragment, _, _) ->
{Fragment, <<>>, CipherState};
-decipher(?RC4, HashSz, CipherState, Fragment, _, _) ->
- State0 = case CipherState#cipher_state.state of
- undefined -> crypto:stream_init(rc4, CipherState#cipher_state.key);
- S -> S
- end,
+decipher(?RC4, HashSz, CipherState = #cipher_state{state = State0}, Fragment, _, _) ->
try crypto:stream_decrypt(State0, Fragment) of
{State, Text} ->
GSC = generic_stream_cipher_from_bin(Text, HashSz),
@@ -179,13 +223,26 @@ decipher(?'3DES', HashSz, CipherState, Fragment, Version, PaddingCheck) ->
block_decipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) ->
crypto:block_decrypt(des3_cbc, [K1, K2, K3], IV, T)
end, CipherState, HashSz, Fragment, Version, PaddingCheck);
-decipher(?AES, HashSz, CipherState, Fragment, Version, PaddingCheck) ->
+decipher(?AES_CBC, HashSz, CipherState, Fragment, Version, PaddingCheck) ->
block_decipher(fun(Key, IV, T) when byte_size(Key) =:= 16 ->
crypto:block_decrypt(aes_cbc128, Key, IV, T);
(Key, IV, T) when byte_size(Key) =:= 32 ->
crypto:block_decrypt(aes_cbc256, Key, IV, T)
end, CipherState, HashSz, Fragment, Version, PaddingCheck).
+%%--------------------------------------------------------------------
+-spec decipher_aead(cipher_enum(), #cipher_state{}, integer(), binary(), binary(), ssl_record:ssl_version()) ->
+ {binary(), binary(), #cipher_state{}} | #alert{}.
+%%
+%% Description: Decrypts the data and checks the associated data (AAD) MAC using
+%% cipher described by cipher_enum() and updating the cipher state.
+%% Use for suites that use authenticated encryption with associated data (AEAD)
+%%-------------------------------------------------------------------
+decipher_aead(?AES_GCM, CipherState, SeqNo, AAD, Fragment, Version) ->
+ aead_decipher(aes_gcm, CipherState, SeqNo, AAD, Fragment, Version);
+decipher_aead(?CHACHA20_POLY1305, CipherState, SeqNo, AAD, Fragment, Version) ->
+ aead_decipher(chacha20_poly1305, CipherState, SeqNo, AAD, Fragment, Version).
+
block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
HashSz, Fragment, Version, PaddingCheck) ->
try
@@ -215,6 +272,35 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
%% bad_record_mac alert to hide the specific type of the error."
?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
end.
+
+aead_ciphertext_to_state(chacha20_poly1305, SeqNo, _IV, AAD0, Fragment, _Version) ->
+ CipherLen = size(Fragment) - 16,
+ <<CipherText:CipherLen/bytes, CipherTag:16/bytes>> = Fragment,
+ AAD = <<AAD0/binary, ?UINT16(CipherLen)>>,
+ Nonce = <<SeqNo:64/integer>>,
+ {Nonce, AAD, CipherText, CipherTag};
+aead_ciphertext_to_state(_, _SeqNo, <<Salt:4/bytes, _/binary>>, AAD0, Fragment, _Version) ->
+ CipherLen = size(Fragment) - 24,
+ <<ExplicitNonce:8/bytes, CipherText:CipherLen/bytes, CipherTag:16/bytes>> = Fragment,
+ AAD = <<AAD0/binary, ?UINT16(CipherLen)>>,
+ Nonce = <<Salt/binary, ExplicitNonce/binary>>,
+ {Nonce, AAD, CipherText, CipherTag}.
+
+aead_decipher(Type, #cipher_state{key = Key, iv = IV} = CipherState,
+ SeqNo, AAD0, Fragment, Version) ->
+ try
+ {Nonce, AAD, CipherText, CipherTag} = aead_ciphertext_to_state(Type, SeqNo, IV, AAD0, Fragment, Version),
+ case crypto:block_decrypt(Type, Key, Nonce, {AAD, CipherText, CipherTag}) of
+ Content when is_binary(Content) ->
+ {Content, CipherState};
+ _ ->
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end
+ catch
+ _:_ ->
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end.
+
%%--------------------------------------------------------------------
-spec suites(ssl_record:ssl_version()) -> [cipher_suite()].
%%
@@ -227,16 +313,27 @@ suites({3, N}) ->
all_suites(Version) ->
suites(Version)
- ++ ssl_cipher:anonymous_suites()
- ++ ssl_cipher:psk_suites(Version)
- ++ ssl_cipher:srp_suites().
+ ++ anonymous_suites(Version)
+ ++ psk_suites(Version)
+ ++ srp_suites()
+ ++ rc4_suites(Version).
%%--------------------------------------------------------------------
--spec anonymous_suites() -> [cipher_suite()].
+-spec anonymous_suites(ssl_record:ssl_version() | integer()) -> [cipher_suite()].
%%
%% Description: Returns a list of the anonymous cipher suites, only supported
%% if explicitly set by user. Intended only for testing.
%%--------------------------------------------------------------------
-anonymous_suites() ->
+
+anonymous_suites({3, N}) ->
+ anonymous_suites(N);
+
+anonymous_suites(N)
+ when N >= 3 ->
+ [?TLS_DH_anon_WITH_AES_128_GCM_SHA256,
+ ?TLS_DH_anon_WITH_AES_256_GCM_SHA384
+ ] ++ anonymous_suites(0);
+
+anonymous_suites(_) ->
[?TLS_DH_anon_WITH_RC4_128_MD5,
?TLS_DH_anon_WITH_DES_CBC_SHA,
?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
@@ -260,13 +357,20 @@ psk_suites({3, N}) ->
psk_suites(N)
when N >= 3 ->
- psk_suites(0) ++
- [?TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
- ?TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
- ?TLS_PSK_WITH_AES_128_CBC_SHA256];
+ [
+ ?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
+ ?TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
+ ?TLS_PSK_WITH_AES_128_CBC_SHA256
+ ] ++ psk_suites(0);
psk_suites(_) ->
[?TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
@@ -298,9 +402,27 @@ srp_suites() ->
?TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA].
+%%--------------------------------------------------------------------
+-spec rc4_suites(Version::ssl_record:ssl_version()) -> [cipher_suite()].
+%%
+%% Description: Returns a list of the RSA|(ECDH/RSA)| (ECDH/ECDSA)
+%% with RC4 cipher suites, only supported if explicitly set by user.
+%% Are not considered secure any more. Other RC4 suites already
+%% belonged to the user configured only category.
+%%--------------------------------------------------------------------
+rc4_suites({3, 0}) ->
+ [?TLS_RSA_WITH_RC4_128_SHA,
+ ?TLS_RSA_WITH_RC4_128_MD5];
+rc4_suites({3, N}) when N =< 3 ->
+ [?TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+ ?TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ ?TLS_RSA_WITH_RC4_128_SHA,
+ ?TLS_RSA_WITH_RC4_128_MD5,
+ ?TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+ ?TLS_ECDH_RSA_WITH_RC4_128_SHA].
%%--------------------------------------------------------------------
--spec suite_definition(cipher_suite()) -> int_cipher_suite().
+-spec suite_definition(cipher_suite()) -> erl_cipher_suite().
%%
%% Description: Return erlang cipher suite definition.
%% Note: Currently not supported suites are commented away.
@@ -418,6 +540,19 @@ suite_definition(?TLS_RSA_PSK_WITH_AES_256_CBC_SHA) ->
%%% TLS 1.2 PSK Cipher Suites RFC 5487
+suite_definition(?TLS_PSK_WITH_AES_128_GCM_SHA256) ->
+ {psk, aes_128_gcm, null, sha256};
+suite_definition(?TLS_PSK_WITH_AES_256_GCM_SHA384) ->
+ {psk, aes_256_gcm, null, sha384};
+suite_definition(?TLS_DHE_PSK_WITH_AES_128_GCM_SHA256) ->
+ {dhe_psk, aes_128_gcm, null, sha256};
+suite_definition(?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384) ->
+ {dhe_psk, aes_256_gcm, null, sha384};
+suite_definition(?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256) ->
+ {rsa_psk, aes_128_gcm, null, sha256};
+suite_definition(?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384) ->
+ {rsa_psk, aes_256_gcm, null, sha384};
+
suite_definition(?TLS_PSK_WITH_AES_128_CBC_SHA256) ->
{psk, aes_128_cbc, sha256, default_prf};
suite_definition(?TLS_PSK_WITH_AES_256_CBC_SHA384) ->
@@ -537,7 +672,73 @@ suite_definition(?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) ->
suite_definition(?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256) ->
{ecdh_rsa, aes_128_cbc, sha256, sha256};
suite_definition(?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384) ->
- {ecdh_rsa, aes_256_cbc, sha384, sha384}.
+ {ecdh_rsa, aes_256_cbc, sha384, sha384};
+
+%% RFC 5288 AES-GCM Cipher Suites
+suite_definition(?TLS_RSA_WITH_AES_128_GCM_SHA256) ->
+ {rsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_RSA_WITH_AES_256_GCM_SHA384) ->
+ {rsa, aes_256_gcm, null, sha384};
+suite_definition(?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) ->
+ {dhe_rsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384) ->
+ {dhe_rsa, aes_256_gcm, null, sha384};
+suite_definition(?TLS_DH_RSA_WITH_AES_128_GCM_SHA256) ->
+ {dh_rsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_DH_RSA_WITH_AES_256_GCM_SHA384) ->
+ {dh_rsa, aes_256_gcm, null, sha384};
+suite_definition(?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256) ->
+ {dhe_dss, aes_128_gcm, null, sha256};
+suite_definition(?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384) ->
+ {dhe_dss, aes_256_gcm, null, sha384};
+suite_definition(?TLS_DH_DSS_WITH_AES_128_GCM_SHA256) ->
+ {dh_dss, aes_128_gcm, null, sha256};
+suite_definition(?TLS_DH_DSS_WITH_AES_256_GCM_SHA384) ->
+ {dh_dss, aes_256_gcm, null, sha384};
+suite_definition(?TLS_DH_anon_WITH_AES_128_GCM_SHA256) ->
+ {dh_anon, aes_128_gcm, null, sha256};
+suite_definition(?TLS_DH_anon_WITH_AES_256_GCM_SHA384) ->
+ {dh_anon, aes_256_gcm, null, sha384};
+
+%% RFC 5289 ECC AES-GCM Cipher Suites
+suite_definition(?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) ->
+ {ecdhe_ecdsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) ->
+ {ecdhe_ecdsa, aes_256_gcm, null, sha384};
+suite_definition(?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256) ->
+ {ecdh_ecdsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384) ->
+ {ecdh_ecdsa, aes_256_gcm, null, sha384};
+suite_definition(?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) ->
+ {ecdhe_rsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) ->
+ {ecdhe_rsa, aes_256_gcm, null, sha384};
+suite_definition(?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256) ->
+ {ecdh_rsa, aes_128_gcm, null, sha256};
+suite_definition(?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384) ->
+ {ecdh_rsa, aes_256_gcm, null, sha384};
+
+%% draft-agl-tls-chacha20poly1305-04 Chacha20/Poly1305 Suites
+suite_definition(?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) ->
+ {ecdhe_rsa, chacha20_poly1305, null, sha256};
+suite_definition(?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) ->
+ {ecdhe_ecdsa, chacha20_poly1305, null, sha256};
+suite_definition(?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256) ->
+ {dhe_rsa, chacha20_poly1305, null, sha256}.
+
+%%--------------------------------------------------------------------
+-spec erl_suite_definition(cipher_suite()) -> erl_cipher_suite().
+%%
+%% Description: Return erlang cipher suite definition. Filters last value
+%% for now (compatibility reasons).
+%%--------------------------------------------------------------------
+erl_suite_definition(S) ->
+ case suite_definition(S) of
+ {KeyExchange, Cipher, Hash, default_prf} ->
+ {KeyExchange, Cipher, Hash};
+ Suite ->
+ Suite
+ end.
%%--------------------------------------------------------------------
-spec suite(erl_cipher_suite()) -> cipher_suite().
@@ -641,6 +842,19 @@ suite({rsa_psk, aes_256_cbc,sha}) ->
%%% TLS 1.2 PSK Cipher Suites RFC 5487
+suite({psk, aes_128_gcm, null, sha256}) ->
+ ?TLS_PSK_WITH_AES_128_GCM_SHA256;
+suite({psk, aes_256_gcm, null, sha384}) ->
+ ?TLS_PSK_WITH_AES_256_GCM_SHA384;
+suite({dhe_psk, aes_128_gcm, null, sha256}) ->
+ ?TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
+suite({dhe_psk, aes_256_gcm, null, sha384}) ->
+ ?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
+suite({rsa_psk, aes_128_gcm, null, sha256}) ->
+ ?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256;
+suite({rsa_psk, aes_256_gcm, null, sha384}) ->
+ ?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384;
+
suite({psk, aes_128_cbc, sha256}) ->
?TLS_PSK_WITH_AES_128_CBC_SHA256;
suite({psk, aes_256_cbc, sha384}) ->
@@ -745,22 +959,75 @@ suite({ecdh_anon, aes_256_cbc, sha}) ->
?TLS_ECDH_anon_WITH_AES_256_CBC_SHA;
%%% RFC 5289 EC TLS suites
-suite({ecdhe_ecdsa, aes_128_cbc, sha256}) ->
+suite({ecdhe_ecdsa, aes_128_cbc, sha256, sha256}) ->
?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
-suite({ecdhe_ecdsa, aes_256_cbc, sha384}) ->
+suite({ecdhe_ecdsa, aes_256_cbc, sha384, sha384}) ->
?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
-suite({ecdh_ecdsa, aes_128_cbc, sha256}) ->
+suite({ecdh_ecdsa, aes_128_cbc, sha256, sha256}) ->
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
-suite({ecdh_ecdsa, aes_256_cbc, sha384}) ->
+suite({ecdh_ecdsa, aes_256_cbc, sha384, sha384}) ->
?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
-suite({ecdhe_rsa, aes_128_cbc, sha256}) ->
+suite({ecdhe_rsa, aes_128_cbc, sha256, sha256}) ->
?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
-suite({ecdhe_rsa, aes_256_cbc, sha384}) ->
+suite({ecdhe_rsa, aes_256_cbc, sha384, sha384}) ->
?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
-suite({ecdh_rsa, aes_128_cbc, sha256}) ->
+suite({ecdh_rsa, aes_128_cbc, sha256, sha256}) ->
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
-suite({ecdh_rsa, aes_256_cbc, sha384}) ->
- ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384.
+suite({ecdh_rsa, aes_256_cbc, sha384, sha384}) ->
+ ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
+
+%% RFC 5288 AES-GCM Cipher Suites
+suite({rsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_RSA_WITH_AES_128_GCM_SHA256;
+suite({rsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_RSA_WITH_AES_256_GCM_SHA384;
+suite({dhe_rsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
+suite({dhe_rsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
+suite({dh_rsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_DH_RSA_WITH_AES_128_GCM_SHA256;
+suite({dh_rsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_DH_RSA_WITH_AES_256_GCM_SHA384;
+suite({dhe_dss, aes_128_gcm, null, sha256}) ->
+ ?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256;
+suite({dhe_dss, aes_256_gcm, null, sha384}) ->
+ ?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384;
+suite({dh_dss, aes_128_gcm, null, sha256}) ->
+ ?TLS_DH_DSS_WITH_AES_128_GCM_SHA256;
+suite({dh_dss, aes_256_gcm, null, sha384}) ->
+ ?TLS_DH_DSS_WITH_AES_256_GCM_SHA384;
+suite({dh_anon, aes_128_gcm, null, sha256}) ->
+ ?TLS_DH_anon_WITH_AES_128_GCM_SHA256;
+suite({dh_anon, aes_256_gcm, null, sha384}) ->
+ ?TLS_DH_anon_WITH_AES_256_GCM_SHA384;
+
+%% RFC 5289 ECC AES-GCM Cipher Suites
+suite({ecdhe_ecdsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
+suite({ecdhe_ecdsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
+suite({ecdh_ecdsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
+suite({ecdh_ecdsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
+suite({ecdhe_rsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+suite({ecdhe_rsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
+suite({ecdh_rsa, aes_128_gcm, null, sha256}) ->
+ ?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
+suite({ecdh_rsa, aes_256_gcm, null, sha384}) ->
+ ?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
+
+
+%% draft-agl-tls-chacha20poly1305-04 Chacha20/Poly1305 Suites
+suite({ecdhe_rsa, chacha20_poly1305, null, sha256}) ->
+ ?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+suite({ecdhe_ecdsa, chacha20_poly1305, null, sha256}) ->
+ ?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
+suite({dhe_rsa, chacha20_poly1305, null, sha256}) ->
+ ?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256.
%%--------------------------------------------------------------------
-spec openssl_suite(openssl_cipher_suite()) -> cipher_suite().
@@ -875,7 +1142,47 @@ openssl_suite("ECDHE-RSA-AES256-SHA384") ->
openssl_suite("ECDH-RSA-AES128-SHA256") ->
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
openssl_suite("ECDH-RSA-AES256-SHA384") ->
- ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384.
+ ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
+
+%% RFC 5288 AES-GCM Cipher Suites
+openssl_suite("AES128-GCM-SHA256") ->
+ ?TLS_RSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("AES256-GCM-SHA384") ->
+ ?TLS_RSA_WITH_AES_256_GCM_SHA384;
+openssl_suite("DHE-RSA-AES128-GCM-SHA256") ->
+ ?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("DHE-RSA-AES256-GCM-SHA384") ->
+ ?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
+openssl_suite("DH-RSA-AES128-GCM-SHA256") ->
+ ?TLS_DH_RSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("DH-RSA-AES256-GCM-SHA384") ->
+ ?TLS_DH_RSA_WITH_AES_256_GCM_SHA384;
+openssl_suite("DHE-DSS-AES128-GCM-SHA256") ->
+ ?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256;
+openssl_suite("DHE-DSS-AES256-GCM-SHA384") ->
+ ?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384;
+openssl_suite("DH-DSS-AES128-GCM-SHA256") ->
+ ?TLS_DH_DSS_WITH_AES_128_GCM_SHA256;
+openssl_suite("DH-DSS-AES256-GCM-SHA384") ->
+ ?TLS_DH_DSS_WITH_AES_256_GCM_SHA384;
+
+%% RFC 5289 ECC AES-GCM Cipher Suites
+openssl_suite("ECDHE-ECDSA-AES128-GCM-SHA256") ->
+ ?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("ECDHE-ECDSA-AES256-GCM-SHA384") ->
+ ?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
+openssl_suite("ECDH-ECDSA-AES128-GCM-SHA256") ->
+ ?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("ECDH-ECDSA-AES256-GCM-SHA384") ->
+ ?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
+openssl_suite("ECDHE-RSA-AES128-GCM-SHA256") ->
+ ?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("ECDHE-RSA-AES256-GCM-SHA384") ->
+ ?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
+openssl_suite("ECDH-RSA-AES128-GCM-SHA256") ->
+ ?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
+openssl_suite("ECDH-RSA-AES256-GCM-SHA384") ->
+ ?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384.
%%--------------------------------------------------------------------
-spec openssl_suite_name(cipher_suite()) -> openssl_cipher_suite().
@@ -1012,6 +1319,46 @@ openssl_suite_name(?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256) ->
openssl_suite_name(?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384) ->
"ECDH-RSA-AES256-SHA384";
+%% RFC 5288 AES-GCM Cipher Suites
+openssl_suite_name(?TLS_RSA_WITH_AES_128_GCM_SHA256) ->
+ "AES128-GCM-SHA256";
+openssl_suite_name(?TLS_RSA_WITH_AES_256_GCM_SHA384) ->
+ "AES256-GCM-SHA384";
+openssl_suite_name(?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) ->
+ "DHE-RSA-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384) ->
+ "DHE-RSA-AES256-GCM-SHA384";
+openssl_suite_name(?TLS_DH_RSA_WITH_AES_128_GCM_SHA256) ->
+ "DH-RSA-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_DH_RSA_WITH_AES_256_GCM_SHA384) ->
+ "DH-RSA-AES256-GCM-SHA384";
+openssl_suite_name(?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256) ->
+ "DHE-DSS-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384) ->
+ "DHE-DSS-AES256-GCM-SHA384";
+openssl_suite_name(?TLS_DH_DSS_WITH_AES_128_GCM_SHA256) ->
+ "DH-DSS-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_DH_DSS_WITH_AES_256_GCM_SHA384) ->
+ "DH-DSS-AES256-GCM-SHA384";
+
+%% RFC 5289 ECC AES-GCM Cipher Suites
+openssl_suite_name(?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) ->
+ "ECDHE-ECDSA-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) ->
+ "ECDHE-ECDSA-AES256-GCM-SHA384";
+openssl_suite_name(?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256) ->
+ "ECDH-ECDSA-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384) ->
+ "ECDH-ECDSA-AES256-GCM-SHA384";
+openssl_suite_name(?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) ->
+ "ECDHE-RSA-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) ->
+ "ECDHE-RSA-AES256-GCM-SHA384";
+openssl_suite_name(?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256) ->
+ "ECDH-RSA-AES128-GCM-SHA256";
+openssl_suite_name(?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384) ->
+ "ECDH-RSA-AES256-GCM-SHA384";
+
%% No oppenssl name
openssl_suite_name(Cipher) ->
suite_definition(Cipher).
@@ -1056,18 +1403,14 @@ filter(DerCert, Ciphers) ->
%%
%% Description: Filter suites for algorithms supported by crypto.
%%-------------------------------------------------------------------
-filter_suites(Suites = [{_,_,_}|_]) ->
+filter_suites(Suites = [Value|_]) when is_tuple(Value) ->
Algos = crypto:supports(),
+ Hashs = proplists:get_value(hashs, Algos),
lists:filter(fun({KeyExchange, Cipher, Hash}) ->
is_acceptable_keyexchange(KeyExchange, proplists:get_value(public_keys, Algos)) andalso
is_acceptable_cipher(Cipher, proplists:get_value(ciphers, Algos)) andalso
- is_acceptable_hash(Hash, proplists:get_value(hashs, Algos))
- end, Suites);
-
-filter_suites(Suites = [{_,_,_,_}|_]) ->
- Algos = crypto:supports(),
- Hashs = proplists:get_value(hashs, Algos),
- lists:filter(fun({KeyExchange, Cipher, Hash, Prf}) ->
+ is_acceptable_hash(Hash, proplists:get_value(hashs, Algos));
+ ({KeyExchange, Cipher, Hash, Prf}) ->
is_acceptable_keyexchange(KeyExchange, proplists:get_value(public_keys, Algos)) andalso
is_acceptable_cipher(Cipher, proplists:get_value(ciphers, Algos)) andalso
is_acceptable_hash(Hash, Hashs) andalso
@@ -1095,6 +1438,13 @@ is_acceptable_keyexchange(KeyExchange, Algos)
is_acceptable_keyexchange(_, _) ->
true.
+is_acceptable_cipher(Cipher, Algos)
+ when Cipher == aes_128_gcm;
+ Cipher == aes_256_gcm ->
+ proplists:get_bool(aes_gcm, Algos);
+is_acceptable_cipher(Cipher, Algos)
+ when Cipher == chacha20_poly1305 ->
+ proplists:get_bool(Cipher, Algos);
is_acceptable_cipher(_, _) ->
true.
@@ -1125,7 +1475,12 @@ bulk_cipher_algorithm('3des_ede_cbc') ->
?'3DES';
bulk_cipher_algorithm(Cipher) when Cipher == aes_128_cbc;
Cipher == aes_256_cbc ->
- ?AES.
+ ?AES_CBC;
+bulk_cipher_algorithm(Cipher) when Cipher == aes_128_gcm;
+ Cipher == aes_256_gcm ->
+ ?AES_GCM;
+bulk_cipher_algorithm(chacha20_poly1305) ->
+ ?CHACHA20_POLY1305.
type(Cipher) when Cipher == null;
Cipher == rc4_128 ->
@@ -1135,7 +1490,11 @@ type(Cipher) when Cipher == des_cbc;
Cipher == '3des_ede_cbc';
Cipher == aes_128_cbc;
Cipher == aes_256_cbc ->
- ?BLOCK.
+ ?BLOCK;
+type(Cipher) when Cipher == aes_128_gcm;
+ Cipher == aes_256_gcm;
+ Cipher == chacha20_poly1305 ->
+ ?AEAD.
key_material(null) ->
0;
@@ -1148,6 +1507,12 @@ key_material('3des_ede_cbc') ->
key_material(aes_128_cbc) ->
16;
key_material(aes_256_cbc) ->
+ 32;
+key_material(aes_128_gcm) ->
+ 16;
+key_material(aes_256_gcm) ->
+ 32;
+key_material(chacha20_poly1305) ->
32.
expanded_key_material(null) ->
@@ -1159,7 +1524,10 @@ expanded_key_material(Cipher) when Cipher == des_cbc ->
expanded_key_material('3des_ede_cbc') ->
24;
expanded_key_material(Cipher) when Cipher == aes_128_cbc;
- Cipher == aes_256_cbc ->
+ Cipher == aes_256_cbc;
+ Cipher == aes_128_gcm;
+ Cipher == aes_256_gcm;
+ Cipher == chacha20_poly1305 ->
unknown.
@@ -1168,16 +1536,25 @@ effective_key_bits(null) ->
effective_key_bits(des_cbc) ->
56;
effective_key_bits(Cipher) when Cipher == rc4_128;
- Cipher == aes_128_cbc ->
+ Cipher == aes_128_cbc;
+ Cipher == aes_128_gcm ->
128;
effective_key_bits('3des_ede_cbc') ->
168;
-effective_key_bits(aes_256_cbc) ->
+effective_key_bits(Cipher) when Cipher == aes_256_cbc;
+ Cipher == aes_256_gcm;
+ Cipher == chacha20_poly1305 ->
256.
iv_size(Cipher) when Cipher == null;
- Cipher == rc4_128 ->
+ Cipher == rc4_128;
+ Cipher == chacha20_poly1305->
0;
+
+iv_size(Cipher) when Cipher == aes_128_gcm;
+ Cipher == aes_256_gcm ->
+ 4;
+
iv_size(Cipher) ->
block_size(Cipher).
@@ -1186,7 +1563,10 @@ block_size(Cipher) when Cipher == des_cbc;
8;
block_size(Cipher) when Cipher == aes_128_cbc;
- Cipher == aes_256_cbc ->
+ Cipher == aes_256_cbc;
+ Cipher == aes_128_gcm;
+ Cipher == aes_256_gcm;
+ Cipher == chacha20_poly1305 ->
16.
prf_algorithm(default_prf, {3, N}) when N >= 3 ->
@@ -1209,7 +1589,9 @@ hash_algorithm(?SHA) -> sha;
hash_algorithm(?SHA224) -> sha224;
hash_algorithm(?SHA256) -> sha256;
hash_algorithm(?SHA384) -> sha384;
-hash_algorithm(?SHA512) -> sha512.
+hash_algorithm(?SHA512) -> sha512;
+hash_algorithm(Other) when is_integer(Other) andalso ((Other >= 7) and (Other =< 223)) -> unassigned;
+hash_algorithm(Other) when is_integer(Other) andalso ((Other >= 224) and (Other =< 255)) -> Other.
sign_algorithm(anon) -> ?ANON;
sign_algorithm(rsa) -> ?RSA;
@@ -1218,7 +1600,9 @@ sign_algorithm(ecdsa) -> ?ECDSA;
sign_algorithm(?ANON) -> anon;
sign_algorithm(?RSA) -> rsa;
sign_algorithm(?DSA) -> dsa;
-sign_algorithm(?ECDSA) -> ecdsa.
+sign_algorithm(?ECDSA) -> ecdsa;
+sign_algorithm(Other) when is_integer(Other) andalso ((Other >= 4) and (Other =< 223)) -> unassigned;
+sign_algorithm(Other) when is_integer(Other) andalso ((Other >= 224) and (Other =< 255)) -> Other.
hash_size(null) ->
0;
@@ -1342,10 +1726,15 @@ dhe_rsa_suites() ->
?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- ?TLS_DHE_RSA_WITH_DES_CBC_SHA].
+ ?TLS_DHE_RSA_WITH_DES_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256].
psk_rsa_suites() ->
- [?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
+ [?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
?TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
?TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
?TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
@@ -1365,7 +1754,9 @@ rsa_suites() ->
?TLS_RSA_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_RC4_128_SHA,
?TLS_RSA_WITH_RC4_128_MD5,
- ?TLS_RSA_WITH_DES_CBC_SHA].
+ ?TLS_RSA_WITH_DES_CBC_SHA,
+ ?TLS_RSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_RSA_WITH_AES_256_GCM_SHA384].
ecdh_rsa_suites() ->
[?TLS_ECDH_RSA_WITH_NULL_SHA,
@@ -1374,7 +1765,9 @@ ecdh_rsa_suites() ->
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
- ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384].
+ ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384].
ecdhe_rsa_suites() ->
[?TLS_ECDHE_RSA_WITH_NULL_SHA,
@@ -1383,7 +1776,10 @@ ecdhe_rsa_suites() ->
?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- ?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384].
+ ?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256].
dsa_signed_suites() ->
dhe_dss_suites() ++ srp_dss_suites().
@@ -1394,7 +1790,9 @@ dhe_dss_suites() ->
?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
?TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA].
+ ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ ?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384].
srp_dss_suites() ->
[?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
@@ -1418,7 +1816,9 @@ ecdh_ecdsa_suites() ->
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
- ?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384].
+ ?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384].
ecdhe_ecdsa_suites() ->
[?TLS_ECDHE_ECDSA_WITH_NULL_SHA,
@@ -1427,7 +1827,10 @@ ecdhe_ecdsa_suites() ->
?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
- ?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384].
+ ?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256].
filter_keyuse(OtpCert, Ciphers, Suites, SignSuites) ->
TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl
index 3e50563f0a..8e8f3d9c67 100644
--- a/lib/ssl/src/ssl_cipher.hrl
+++ b/lib/ssl/src/ssl_cipher.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -46,7 +47,8 @@
-record(cipher_state, {
iv,
key,
- state
+ state,
+ nonce
}).
%%% TLS_NULL_WITH_NULL_NULL is specified and is the initial state of a
@@ -399,6 +401,24 @@
%%% TLS 1.2 PSK Cipher Suites RFC 5487
+%% TLS_PSK_WITH_AES_128_GCM_SHA256 = {0x00,0xA8};
+-define(TLS_PSK_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#A8)>>).
+
+%% TLS_PSK_WITH_AES_256_GCM_SHA384 = {0x00,0xA9};
+-define(TLS_PSK_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#A9)>>).
+
+%% TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = {0x00,0xAA};
+-define(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#AA)>>).
+
+%% TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = {0x00,0xAB};
+-define(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#AB)>>).
+
+%% TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = {0x00,0xAC};
+-define(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#AC)>>).
+
+%% TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = {0x00,0xAD};
+-define(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#AD)>>).
+
%% TLS_PSK_WITH_AES_128_CBC_SHA256 = {0x00,0xAE};
-define(TLS_PSK_WITH_AES_128_CBC_SHA256, <<?BYTE(16#00), ?BYTE(16#AE)>>).
@@ -464,4 +484,79 @@
%% TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = { 0xC0,0x22 };
-define(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, <<?BYTE(16#C0), ?BYTE(16#22)>>).
+%%% AES-GCM Cipher Suites RFC 5288
+
+%% TLS_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0x9C}
+-define(TLS_RSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#9C)>>).
+
+%% TLS_RSA_WITH_AES_256_GCM_SHA384 = {0x00,0x9D}
+-define(TLS_RSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#9D)>>).
+
+%% TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0x9E}
+-define(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#9E)>>).
+
+%% TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = {0x00,0x9F}
+-define(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#9F)>>).
+
+%% TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0xA0}
+-define(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#A0)>>).
+
+%% TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = {0x00,0xA1}
+-define(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#A1)>>).
+
+%% TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = {0x00,0xA2}
+-define(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#A2)>>).
+
+%% TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = {0x00,0xA3}
+-define(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#A3)>>).
+
+%% TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = {0x00,0xA4}
+-define(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#A4)>>).
+
+%% TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = {0x00,0xA5}
+-define(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#A5)>>).
+
+%% TLS_DH_anon_WITH_AES_128_GCM_SHA256 = {0x00,0xA6}
+-define(TLS_DH_anon_WITH_AES_128_GCM_SHA256, <<?BYTE(16#00), ?BYTE(16#A6)>>).
+
+%% TLS_DH_anon_WITH_AES_256_GCM_SHA384 = {0x00,0xA7}
+-define(TLS_DH_anon_WITH_AES_256_GCM_SHA384, <<?BYTE(16#00), ?BYTE(16#A7)>>).
+
+%%% ECC AES-GCM Cipher Suites RFC 5289
+
+%% TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = {0xC0,0x2B};
+-define(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#C0), ?BYTE(16#2B)>>).
+
+%% TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = {0xC0,0x2C};
+-define(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#C0), ?BYTE(16#2C)>>).
+
+%% TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = {0xC0,0x2D};
+-define(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#C0), ?BYTE(16#2D)>>).
+
+%% TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = {0xC0,0x2E};
+-define(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#C0), ?BYTE(16#2E)>>).
+
+%% TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = {0xC0,0x2F};
+-define(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#C0), ?BYTE(16#2F)>>).
+
+%% TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = {0xC0,0x30};
+-define(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#C0), ?BYTE(16#30)>>).
+
+%% TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = {0xC0,0x31};
+-define(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, <<?BYTE(16#C0), ?BYTE(16#31)>>).
+
+%% TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = {0xC0,0x32};
+-define(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, <<?BYTE(16#C0), ?BYTE(16#32)>>).
+
+%%% Chacha20/Poly1305 Suites draft-agl-tls-chacha20poly1305-04
+
+%% TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = {0xcc, 0x13}
+-define(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, <<?BYTE(16#CC), ?BYTE(16#13)>>).
+
+%% TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = {0xcc, 0x14}
+-define(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, <<?BYTE(16#CC), ?BYTE(16#14)>>).
+
+%% TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = {0xcc, 0x15}
+-define(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, <<?BYTE(16#CC), ?BYTE(16#15)>>).
+
-endif. % -ifdef(ssl_cipher).
diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl
index 545b8aa0f6..0652d029c3 100644
--- a/lib/ssl/src/ssl_config.erl
+++ b/lib/ssl/src/ssl_config.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,13 +32,13 @@ init(SslOpts, Role) ->
init_manager_name(SslOpts#ssl_options.erl_dist),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, OwnCert}
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbHandle, OwnCert}
= init_certificates(SslOpts, Role),
PrivateKey =
init_private_key(PemCacheHandle, SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile,
SslOpts#ssl_options.password, Role),
DHParams = init_diffie_hellman(PemCacheHandle, SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, CacheHandle, OwnCert, PrivateKey, DHParams}.
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, CacheHandle, CRLDbHandle, OwnCert, PrivateKey, DHParams}.
init_manager_name(false) ->
put(ssl_manager, ssl_manager:manager_name(normal));
@@ -46,9 +47,11 @@ init_manager_name(true) ->
init_certificates(#ssl_options{cacerts = CaCerts,
cacertfile = CACertFile,
- certfile = CertFile,
- cert = Cert}, Role) ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle} =
+ certfile = CertFile,
+ cert = Cert,
+ crl_cache = CRLCache
+ }, Role) ->
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo} =
try
Certs = case CaCerts of
undefined ->
@@ -56,39 +59,40 @@ init_certificates(#ssl_options{cacerts = CaCerts,
_ ->
{der, CaCerts}
end,
- {ok, _, _, _, _, _} = ssl_manager:connection_init(Certs, Role)
+ {ok, _, _, _, _, _, _} = ssl_manager:connection_init(Certs, Role, CRLCache)
catch
_:Reason ->
file_error(CACertFile, {cacertfile, Reason})
end,
init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle,
- CacheHandle, CertFile, Role).
+ CacheHandle, CRLDbInfo, CertFile, Role).
-init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, <<>>, _) ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, undefined};
+init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle,
+ CRLDbInfo, <<>>, _) ->
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo, undefined};
init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle,
- CacheHandle, CertFile, client) ->
+ CacheHandle, CRLDbInfo, CertFile, client) ->
try
%% Ignoring potential proxy-certificates see:
%% http://dev.globus.org/wiki/Security/ProxyFileFormat
[OwnCert|_] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, OwnCert}
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo, OwnCert}
catch _Error:_Reason ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, undefined}
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo, undefined}
end;
init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle,
- PemCacheHandle, CacheRef, CertFile, server) ->
+ PemCacheHandle, CacheRef, CRLDbInfo, CertFile, server) ->
try
[OwnCert|_] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, OwnCert}
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CRLDbInfo, OwnCert}
catch
_:Reason ->
file_error(CertFile, {certfile, Reason})
end;
-init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, _, _) ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, Cert}.
+init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CRLDbInfo, _, _) ->
+ {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CRLDbInfo, Cert}.
init_private_key(_, undefined, <<>>, _Password, _Client) ->
undefined;
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index b6059eac58..0f0072ba34 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,12 +41,13 @@
socket_control/4, socket_control/5]).
%% User Events
--export([send/2, recv/3, close/1, shutdown/2,
- new_user/2, get_opts/2, set_opts/2, info/1, session_info/1,
- peer_certificate/1, renegotiation/1, negotiated_next_protocol/1, prf/5
+-export([send/2, recv/3, close/2, shutdown/2,
+ new_user/2, get_opts/2, set_opts/2, session_info/1,
+ peer_certificate/1, renegotiation/1, negotiated_protocol/1, prf/5,
+ connection_information/1
]).
--export([handle_session/6]).
+-export([handle_session/7]).
%% SSL FSM state functions
-export([hello/3, abbreviated/3, certify/3, cipher/3, connection/3]).
@@ -161,18 +163,27 @@ recv(Pid, Length, Timeout) ->
sync_send_all_state_event(Pid, {recv, Length, Timeout}).
%%--------------------------------------------------------------------
--spec close(pid()) -> ok | {error, reason()}.
+-spec connection_information(pid()) -> {ok, list()} | {error, reason()}.
+%%
+%% Description: Get the SNI hostname
+%%--------------------------------------------------------------------
+connection_information(Pid) when is_pid(Pid) ->
+ sync_send_all_state_event(Pid, connection_information).
+
+%%--------------------------------------------------------------------
+-spec close(pid(), {close, Timeout::integer() |
+ {NewController::pid(), Timeout::integer()}}) ->
+ ok | {ok, port()} | {error, reason()}.
%%
%% Description: Close an ssl connection
%%--------------------------------------------------------------------
-close(ConnectionPid) ->
- case sync_send_all_state_event(ConnectionPid, close) of
+close(ConnectionPid, How) ->
+ case sync_send_all_state_event(ConnectionPid, How) of
{error, closed} ->
ok;
Other ->
Other
end.
-
%%--------------------------------------------------------------------
-spec shutdown(pid(), atom()) -> ok | {error, reason()}.
%%
@@ -191,12 +202,12 @@ new_user(ConnectionPid, User) ->
sync_send_all_state_event(ConnectionPid, {new_user, User}).
%%--------------------------------------------------------------------
--spec negotiated_next_protocol(pid()) -> {ok, binary()} | {error, reason()}.
+-spec negotiated_protocol(pid()) -> {ok, binary()} | {error, reason()}.
%%
%% Description: Returns the negotiated protocol
%%--------------------------------------------------------------------
-negotiated_next_protocol(ConnectionPid) ->
- sync_send_all_state_event(ConnectionPid, negotiated_next_protocol).
+negotiated_protocol(ConnectionPid) ->
+ sync_send_all_state_event(ConnectionPid, negotiated_protocol).
%%--------------------------------------------------------------------
-spec get_opts(pid(), list()) -> {ok, list()} | {error, reason()}.
@@ -214,14 +225,6 @@ set_opts(ConnectionPid, Options) ->
sync_send_all_state_event(ConnectionPid, {set_opts, Options}).
%%--------------------------------------------------------------------
--spec info(pid()) -> {ok, {atom(), tuple()}} | {error, reason()}.
-%%
-%% Description: Returns ssl protocol and cipher used for the connection
-%%--------------------------------------------------------------------
-info(ConnectionPid) ->
- sync_send_all_state_event(ConnectionPid, info).
-
-%%--------------------------------------------------------------------
-spec session_info(pid()) -> {ok, list()} | {error, reason()}.
%%
%% Description: Returns info about the ssl session
@@ -258,27 +261,26 @@ prf(ConnectionPid, Secret, Label, Seed, WantedLength) ->
handle_session(#server_hello{cipher_suite = CipherSuite,
compression_method = Compression},
- Version, NewId, ConnectionStates, NextProtocol,
+ Version, NewId, ConnectionStates, ProtoExt, Protocol0,
#state{session = #session{session_id = OldId},
- negotiated_version = ReqVersion} = State0) ->
+ negotiated_version = ReqVersion,
+ negotiated_protocol = CurrentProtocol} = State0) ->
{KeyAlgorithm, _, _, _} =
ssl_cipher:suite_definition(CipherSuite),
PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm),
-
- NewNextProtocol = case NextProtocol of
- undefined ->
- State0#state.next_protocol;
- _ ->
- NextProtocol
- end,
-
+
+ {ExpectNPN, Protocol} = case Protocol0 of
+ undefined -> {false, CurrentProtocol};
+ _ -> {ProtoExt =:= npn, Protocol0}
+ end,
+
State = State0#state{key_algorithm = KeyAlgorithm,
negotiated_version = Version,
connection_states = ConnectionStates,
premaster_secret = PremasterSecret,
- expecting_next_protocol_negotiation = NextProtocol =/= undefined,
- next_protocol = NewNextProtocol},
+ expecting_next_protocol_negotiation = ExpectNPN,
+ negotiated_protocol = Protocol},
case ssl_session:is_new(OldId, NewId) of
true ->
@@ -302,13 +304,9 @@ hello(#hello_request{}, #state{role = client} = State0, Connection) ->
{Record, State} = Connection:next_record(State0),
Connection:next_state(hello, hello, Record, State);
-hello({common_client_hello, Type, ServerHelloExt, NegotiatedHashSign},
+hello({common_client_hello, Type, ServerHelloExt},
State, Connection) ->
- do_server_hello(Type, ServerHelloExt,
- %% Note NegotiatedHashSign is only negotiated for real if
- %% if TLS version is at least TLS-1.2
- State#state{hashsign_algorithm = NegotiatedHashSign}, Connection);
-
+ do_server_hello(Type, ServerHelloExt, State, Connection);
hello(timeout, State, _) ->
{next_state, hello, State, hibernate};
@@ -371,7 +369,7 @@ abbreviated(#finished{verify_data = Data} = Finished,
abbreviated(#next_protocol{selected_protocol = SelectedProtocol},
#state{role = server, expecting_next_protocol_negotiation = true} = State0,
Connection) ->
- {Record, State} = Connection:next_record(State0#state{next_protocol = SelectedProtocol}),
+ {Record, State} = Connection:next_record(State0#state{negotiated_protocol = SelectedProtocol}),
Connection:next_state(abbreviated, abbreviated, Record, State#state{expecting_next_protocol_negotiation = false});
abbreviated(timeout, State, _) ->
@@ -411,11 +409,15 @@ certify(#certificate{} = Cert,
role = Role,
cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
+ crl_db = CRLDbInfo,
ssl_options = Opts} = State, Connection) ->
- case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef, Opts#ssl_options.depth,
+ case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef,
+ Opts#ssl_options.depth,
Opts#ssl_options.verify,
Opts#ssl_options.verify_fun,
Opts#ssl_options.partial_chain,
+ Opts#ssl_options.crl_check,
+ CRLDbInfo,
Role) of
{PeerCert, PublicKeyInfo} ->
handle_peer_cert(Role, PeerCert, PublicKeyInfo,
@@ -436,7 +438,8 @@ certify(#server_key_exchange{exchange_keys = Keys},
Alg == srp_dss; Alg == srp_rsa; Alg == srp_anon ->
Params = ssl_handshake:decode_server_key(Keys, Alg, Version),
- HashSign = negotiated_hashsign(Params#server_key_params.hashsign, Alg, Version),
+ %% Use negotiated value if TLS-1.2 otherwhise return default
+ HashSign = negotiated_hashsign(Params#server_key_params.hashsign, Alg, PubKeyInfo, Version),
case is_anonymous(Alg) of
true ->
calculate_secret(Params#server_key_params.params,
@@ -458,11 +461,18 @@ certify(#server_key_exchange{} = Msg,
certify(#certificate_request{hashsign_algorithms = HashSigns},
#state{session = #session{own_certificate = Cert},
- negotiated_version = Version} = State0, Connection) ->
- HashSign = ssl_handshake:select_hashsign(HashSigns, Cert, Version),
- {Record, State} = Connection:next_record(State0#state{client_certificate_requested = true}),
- Connection:next_state(certify, certify, Record,
- State#state{cert_hashsign_algorithm = HashSign});
+ key_algorithm = KeyExAlg,
+ ssl_options = #ssl_options{signature_algs = SupportedHashSigns},
+ negotiated_version = Version} = State0, Connection) ->
+
+ case ssl_handshake:select_hashsign(HashSigns, Cert, KeyExAlg, SupportedHashSigns, Version) of
+ #alert {} = Alert ->
+ Connection:handle_own_alert(Alert, Version, certify, State0);
+ NegotiatedHashSign ->
+ {Record, State} = Connection:next_record(State0#state{client_certificate_requested = true}),
+ Connection:next_state(certify, certify, Record,
+ State#state{cert_hashsign_algorithm = NegotiatedHashSign})
+ end;
%% PSK and RSA_PSK might bypass the Server-Key-Exchange
certify(#server_hello_done{},
@@ -570,13 +580,15 @@ cipher(#hello_request{}, State0, Connection) ->
cipher(#certificate_verify{signature = Signature, hashsign_algorithm = CertHashSign},
#state{role = server,
- public_key_info = {Algo, _, _} =PublicKeyInfo,
+ key_algorithm = KexAlg,
+ public_key_info = PublicKeyInfo,
negotiated_version = Version,
session = #session{master_secret = MasterSecret},
tls_handshake_history = Handshake
} = State0, Connection) ->
-
- HashSign = ssl_handshake:select_hashsign_algs(CertHashSign, Algo, Version),
+
+ %% Use negotiated value if TLS-1.2 otherwhise return default
+ HashSign = negotiated_hashsign(CertHashSign, KexAlg, PublicKeyInfo, Version),
case ssl_handshake:certificate_verify(Signature, PublicKeyInfo,
Version, HashSign, MasterSecret, Handshake) of
valid ->
@@ -589,7 +601,7 @@ cipher(#certificate_verify{signature = Signature, hashsign_algorithm = CertHashS
%% client must send a next protocol message if we are expecting it
cipher(#finished{}, #state{role = server, expecting_next_protocol_negotiation = true,
- next_protocol = undefined, negotiated_version = Version} = State0,
+ negotiated_protocol = undefined, negotiated_version = Version} = State0,
Connection) ->
Connection:handle_own_alert(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), Version, cipher, State0);
@@ -619,7 +631,7 @@ cipher(#finished{verify_data = Data} = Finished,
cipher(#next_protocol{selected_protocol = SelectedProtocol},
#state{role = server, expecting_next_protocol_negotiation = true,
expecting_finished = true} = State0, Connection) ->
- {Record, State} = Connection:next_record(State0#state{next_protocol = SelectedProtocol}),
+ {Record, State} = Connection:next_record(State0#state{negotiated_protocol = SelectedProtocol}),
Connection:next_state(cipher, cipher, Record, State#state{expecting_next_protocol_negotiation = false});
cipher(timeout, State, _) ->
@@ -701,12 +713,12 @@ handle_sync_event({start, Timeout}, StartFrom, StateName, #state{role = Role, s
{stop, normal, {error, Error}, State0}
end;
-handle_sync_event(close, _, StateName, #state{protocol_cb = Connection} = State) ->
- %% Run terminate before returning
- %% so that the reuseaddr inet-option will work
- %% as intended.
- (catch Connection:terminate(user_close, StateName, State)),
- {stop, normal, ok, State#state{terminated = true}};
+handle_sync_event({close, _} = Close, _, StateName, #state{protocol_cb = Connection} = State) ->
+ %% Run terminate before returning so that the reuseaddr
+ %% inet-option and possible downgrade will work as intended.
+ Result = Connection:terminate(Close, StateName, State),
+ {stop, normal, Result, State#state{terminated = true}};
+
handle_sync_event({shutdown, How0}, _, StateName,
#state{transport_cb = Transport,
negotiated_version = Version,
@@ -755,10 +767,10 @@ handle_sync_event({get_opts, OptTags}, _From, StateName,
socket_options = SockOpts} = State) ->
OptsReply = get_socket_opts(Transport, Socket, OptTags, SockOpts, []),
{reply, OptsReply, StateName, State, get_timeout(State)};
-handle_sync_event(negotiated_next_protocol, _From, StateName, #state{next_protocol = undefined} = State) ->
- {reply, {error, next_protocol_not_negotiated}, StateName, State, get_timeout(State)};
-handle_sync_event(negotiated_next_protocol, _From, StateName, #state{next_protocol = NextProtocol} = State) ->
- {reply, {ok, NextProtocol}, StateName, State, get_timeout(State)};
+handle_sync_event(negotiated_protocol, _From, StateName, #state{negotiated_protocol = undefined} = State) ->
+ {reply, {error, protocol_not_negotiated}, StateName, State, get_timeout(State)};
+handle_sync_event(negotiated_protocol, _From, StateName, #state{negotiated_protocol = SelectedProtocol} = State) ->
+ {reply, {ok, SelectedProtocol}, StateName, State, get_timeout(State)};
handle_sync_event({set_opts, Opts0}, _From, StateName0,
#state{socket_options = Opts1,
protocol_cb = Connection,
@@ -809,7 +821,8 @@ handle_sync_event({prf, Secret, Label, Seed, WantedLength}, _, StateName,
SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{master_secret = MasterSecret,
client_random = ClientRandom,
- server_random = ServerRandom} = SecParams,
+ server_random = ServerRandom,
+ prf_algorithm = PRFAlgorithm} = SecParams,
Reply = try
SecretToUse = case Secret of
_ when is_binary(Secret) -> Secret;
@@ -820,29 +833,32 @@ handle_sync_event({prf, Secret, Label, Seed, WantedLength}, _, StateName,
(client_random, Acc) -> [ClientRandom|Acc];
(server_random, Acc) -> [ServerRandom|Acc]
end, [], Seed)),
- ssl_handshake:prf(Version, SecretToUse, Label, SeedToUse, WantedLength)
+ ssl_handshake:prf(Version, PRFAlgorithm, SecretToUse, Label, SeedToUse, WantedLength)
catch
exit:_ -> {error, badarg};
error:Reason -> {error, Reason}
end,
{reply, Reply, StateName, State, get_timeout(State)};
-handle_sync_event(info, _, StateName,
- #state{negotiated_version = Version,
- session = #session{cipher_suite = Suite}} = State) ->
-
- AtomVersion = tls_record:protocol_version(Version),
- {reply, {ok, {AtomVersion, ssl:suite_definition(Suite)}},
- StateName, State, get_timeout(State)};
handle_sync_event(session_info, _, StateName,
#state{session = #session{session_id = Id,
cipher_suite = Suite}} = State) ->
{reply, [{session_id, Id},
- {cipher_suite, ssl:suite_definition(Suite)}],
+ {cipher_suite, ssl_cipher:erl_suite_definition(Suite)}],
StateName, State, get_timeout(State)};
handle_sync_event(peer_certificate, _, StateName,
#state{session = #session{peer_certificate = Cert}}
= State) ->
- {reply, {ok, Cert}, StateName, State, get_timeout(State)}.
+ {reply, {ok, Cert}, StateName, State, get_timeout(State)};
+handle_sync_event(connection_information, _, StateName, State) ->
+ Info = connection_info(State),
+ {reply, {ok, Info}, StateName, State, get_timeout(State)}.
+
+connection_info(#state{sni_hostname = SNIHostname,
+ session = #session{cipher_suite = CipherSuite},
+ negotiated_version = Version, ssl_options = Opts}) ->
+ [{protocol, tls_record:protocol_version(Version)},
+ {cipher_suite, ssl_cipher:erl_suite_definition(CipherSuite)},
+ {sni_hostname, SNIHostname}] ++ ssl_options_list(Opts).
handle_info({ErrorTag, Socket, econnaborted}, StateName,
#state{socket = Socket, transport_cb = Transport,
@@ -900,41 +916,46 @@ terminate(_, _, #state{terminated = true}) ->
%% we want to guarantee that Transport:close has been called
%% when ssl:close/1 returns.
ok;
-terminate({shutdown, transport_closed}, StateName, #state{send_queue = SendQueue,
- renegotiation = Renegotiate} = State) ->
- handle_unrecv_data(StateName, State),
+terminate({shutdown, transport_closed} = Reason,
+ _StateName, #state{send_queue = SendQueue, protocol_cb = Connection,
+ socket = Socket, transport_cb = Transport,
+ renegotiation = Renegotiate} = State) ->
handle_trusted_certs_db(State),
notify_senders(SendQueue),
- notify_renegotiater(Renegotiate);
-
-terminate({shutdown, own_alert}, _StateName, #state{send_queue = SendQueue,
- renegotiation = Renegotiate} = State) ->
+ notify_renegotiater(Renegotiate),
+ Connection:close(Reason, Socket, Transport, undefined, undefined);
+terminate({shutdown, own_alert}, _StateName, #state{send_queue = SendQueue, protocol_cb = Connection,
+ socket = Socket, transport_cb = Transport,
+ renegotiation = Renegotiate} = State) ->
handle_trusted_certs_db(State),
notify_senders(SendQueue),
- notify_renegotiater(Renegotiate);
+ notify_renegotiater(Renegotiate),
+ case application:get_env(ssl, alert_timeout) of
+ {ok, Timeout} when is_integer(Timeout) ->
+ Connection:close({timeout, Timeout}, Socket, Transport, undefined, undefined);
+ _ ->
+ Connection:close({timeout, ?DEFAULT_TIMEOUT}, Socket, Transport, undefined, undefined)
+ end;
terminate(Reason, connection, #state{negotiated_version = Version,
protocol_cb = Connection,
- connection_states = ConnectionStates,
+ connection_states = ConnectionStates0,
+ ssl_options = #ssl_options{padding_check = Check},
transport_cb = Transport, socket = Socket,
send_queue = SendQueue, renegotiation = Renegotiate} = State) ->
handle_trusted_certs_db(State),
notify_senders(SendQueue),
notify_renegotiater(Renegotiate),
- BinAlert = terminate_alert(Reason, Version, ConnectionStates),
+ {BinAlert, ConnectionStates} = terminate_alert(Reason, Version, ConnectionStates0),
Transport:send(Socket, BinAlert),
- case Connection of
- tls_connection ->
- tls_connection:workaround_transport_delivery_problems(Socket, Transport);
- _ ->
- ok
- end;
-terminate(_Reason, _StateName, #state{transport_cb = Transport,
+ Connection:close(Reason, Socket, Transport, ConnectionStates, Check);
+
+terminate(Reason, _StateName, #state{transport_cb = Transport, protocol_cb = Connection,
socket = Socket, send_queue = SendQueue,
renegotiation = Renegotiate} = State) ->
handle_trusted_certs_db(State),
notify_senders(SendQueue),
notify_renegotiater(Renegotiate),
- Transport:close(Socket).
+ Connection:close(Reason, Socket, Transport, undefined, undefined).
format_status(normal, [_, State]) ->
[{data, [{"StateData", State}]}];
@@ -964,10 +985,10 @@ format_status(terminate, [_, State]) ->
%%% Internal functions
%%--------------------------------------------------------------------
ssl_config(Opts, Role, State) ->
- {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, OwnCert, Key, DHParams} =
+ {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbInfo, OwnCert, Key, DHParams} =
ssl_config:init(Opts, Role),
Handshake = ssl_handshake:init_handshake_history(),
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ TimeStamp = erlang:monotonic_time(),
Session = State#state.session,
State#state{tls_handshake_history = Handshake,
session = Session#session{own_certificate = OwnCert,
@@ -975,6 +996,7 @@ ssl_config(Opts, Role, State) ->
file_ref_db = FileRefHandle,
cert_db_ref = Ref,
cert_db = CertDbHandle,
+ crl_db = CRLDbInfo,
session_cache = CacheHandle,
private_key = Key,
diffie_hellman_params = DHParams,
@@ -1433,7 +1455,8 @@ rsa_psk_key_exchange(Version, PskIdentity, PremasterSecret, PublicKeyInfo = {Alg
rsa_psk_key_exchange(_, _, _, _) ->
throw (?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)).
-request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
+request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer,
+ signature_algs = SupportedHashSigns},
connection_states = ConnectionStates0,
cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
@@ -1441,7 +1464,9 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
#connection_state{security_parameters =
#security_parameters{cipher_suite = CipherSuite}} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version),
+ HashSigns = ssl_handshake:available_signature_algs(SupportedHashSigns, Version, [Version]),
+ Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef,
+ HashSigns, Version),
State = Connection:send_handshake(Msg, State0),
State#state{client_certificate_requested = true};
@@ -1479,11 +1504,11 @@ finalize_handshake(State0, StateName, Connection) ->
next_protocol(#state{role = server} = State, _) ->
State;
-next_protocol(#state{next_protocol = undefined} = State, _) ->
+next_protocol(#state{negotiated_protocol = undefined} = State, _) ->
State;
next_protocol(#state{expecting_next_protocol_negotiation = false} = State, _) ->
State;
-next_protocol(#state{next_protocol = NextProtocol} = State0, Connection) ->
+next_protocol(#state{negotiated_protocol = NextProtocol} = State0, Connection) ->
NextProtocolMessage = ssl_handshake:next_protocol(NextProtocol),
Connection:send_handshake(NextProtocolMessage, State0).
@@ -1756,37 +1781,24 @@ get_timeout(#state{ssl_options=#ssl_options{hibernate_after = undefined}}) ->
get_timeout(#state{ssl_options=#ssl_options{hibernate_after = HibernateAfter}}) ->
HibernateAfter.
-terminate_alert(Reason, Version, ConnectionStates) when Reason == normal;
- Reason == user_close ->
- {BinAlert, _} = ssl_alert:encode(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
- Version, ConnectionStates),
- BinAlert;
-terminate_alert({shutdown, _}, Version, ConnectionStates) ->
- {BinAlert, _} = ssl_alert:encode(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
- Version, ConnectionStates),
- BinAlert;
+terminate_alert(normal, Version, ConnectionStates) ->
+ ssl_alert:encode(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+ Version, ConnectionStates);
+terminate_alert({Reason, _}, Version, ConnectionStates) when Reason == close;
+ Reason == shutdown ->
+ ssl_alert:encode(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+ Version, ConnectionStates);
terminate_alert(_, Version, ConnectionStates) ->
- {BinAlert, _} = ssl_alert:encode(?ALERT_REC(?FATAL, ?INTERNAL_ERROR),
- Version, ConnectionStates),
- BinAlert.
-
-handle_unrecv_data(StateName, #state{socket = Socket, transport_cb = Transport,
- protocol_cb = Connection} = State) ->
- ssl_socket:setopts(Transport, Socket, [{active, false}]),
- case Transport:recv(Socket, 0, 0) of
- {error, closed} ->
- ok;
- {ok, Data} ->
- Connection:handle_close_alert(Data, StateName, State)
- end.
+ ssl_alert:encode(?ALERT_REC(?FATAL, ?INTERNAL_ERROR),
+ Version, ConnectionStates).
handle_trusted_certs_db(#state{ssl_options = #ssl_options{cacertfile = <<>>, cacerts = []}}) ->
%% No trusted certs specified
ok;
handle_trusted_certs_db(#state{cert_db_ref = Ref,
cert_db = CertDb,
- ssl_options = #ssl_options{cacertfile = <<>>}}) ->
+ ssl_options = #ssl_options{cacertfile = <<>>}}) when CertDb =/= undefined ->
%% Certs provided as DER directly can not be shared
%% with other connections and it is safe to delete them when the connection ends.
ssl_pkix_db:remove_trusted_certs(Ref, CertDb);
@@ -1879,14 +1891,40 @@ make_premaster_secret({MajVer, MinVer}, rsa) ->
make_premaster_secret(_, _) ->
undefined.
-negotiated_hashsign(undefined, Alg, Version) ->
+negotiated_hashsign(undefined, KexAlg, PubKeyInfo, Version) ->
%% Not negotiated choose default
- case is_anonymous(Alg) of
+ case is_anonymous(KexAlg) of
true ->
{null, anon};
false ->
- ssl_handshake:select_hashsign_algs(Alg, Version)
+ {PubAlg, _, _} = PubKeyInfo,
+ ssl_handshake:select_hashsign_algs(undefined, PubAlg, Version)
end;
-negotiated_hashsign(HashSign = {_, _}, _, _) ->
+negotiated_hashsign(HashSign = {_, _}, _, _, _) ->
HashSign.
+ssl_options_list(SslOptions) ->
+ Fileds = record_info(fields, ssl_options),
+ Values = tl(tuple_to_list(SslOptions)),
+ ssl_options_list(Fileds, Values, []).
+
+ssl_options_list([],[], Acc) ->
+ lists:reverse(Acc);
+%% Skip internal options, only return user options
+ssl_options_list([protocol | Keys], [_ | Values], Acc) ->
+ ssl_options_list(Keys, Values, Acc);
+ssl_options_list([erl_dist | Keys], [_ | Values], Acc) ->
+ ssl_options_list(Keys, Values, Acc);
+ssl_options_list([renegotiate_at | Keys], [_ | Values], Acc) ->
+ ssl_options_list(Keys, Values, Acc);
+ssl_options_list([ciphers = Key | Keys], [Value | Values], Acc) ->
+ ssl_options_list(Keys, Values,
+ [{Key, lists:map(
+ fun(Suite) ->
+ ssl_cipher:erl_suite_definition(Suite)
+ end, Value)}
+ | Acc]);
+ssl_options_list([Key | Keys], [Value | Values], Acc) ->
+ ssl_options_list(Keys, Values, [{Key, Value} | Acc]).
+
+
diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl
index b9a1ef3a84..9a58f2b8f7 100644
--- a/lib/ssl/src/ssl_connection.hrl
+++ b/lib/ssl/src/ssl_connection.hrl
@@ -1,19 +1,19 @@
-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2013-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
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% http://www.apache.org/licenses/LICENSE-2.0
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -53,6 +53,7 @@
session :: #session{} | secret_printout(),
session_cache :: db_handle(),
session_cache_cb :: atom(),
+ crl_db :: term(),
negotiated_version :: ssl_record:ssl_version(),
client_certificate_requested = false :: boolean(),
key_algorithm :: ssl_cipher:key_algo(),
@@ -78,9 +79,10 @@
allow_renegotiate = true ::boolean(),
expecting_next_protocol_negotiation = false ::boolean(),
expecting_finished = false ::boolean(),
- next_protocol = undefined :: undefined | binary(),
+ negotiated_protocol = undefined :: undefined | binary(),
client_ecc, % {Curves, PointFmt}
- tracker :: pid() %% Tracker process for listen socket
+ tracker :: pid(), %% Tracker process for listen socket
+ sni_hostname = undefined
}).
-define(DEFAULT_DIFFIE_HELLMAN_PARAMS,
diff --git a/lib/ssl/src/ssl_crl.erl b/lib/ssl/src/ssl_crl.erl
new file mode 100644
index 0000000000..faf5007b16
--- /dev/null
+++ b/lib/ssl/src/ssl_crl.erl
@@ -0,0 +1,81 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+
+%----------------------------------------------------------------------
+%% Purpose: CRL handling
+%%----------------------------------------------------------------------
+
+-module(ssl_crl).
+
+-include("ssl_alert.hrl").
+-include("ssl_internal.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-export([trusted_cert_and_path/3]).
+
+trusted_cert_and_path(CRL, {SerialNumber, Issuer},{Db, DbRef} = DbHandle) ->
+ case ssl_pkix_db:lookup_trusted_cert(Db, DbRef, SerialNumber, Issuer) of
+ undefined ->
+ trusted_cert_and_path(CRL, issuer_not_found, DbHandle);
+ {ok, {_, OtpCert}} ->
+ {ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef),
+ {ok, Root, lists:reverse(Chain)}
+ end;
+
+trusted_cert_and_path(CRL, issuer_not_found, {Db, DbRef} = DbHandle) ->
+ try find_issuer(CRL, DbHandle) of
+ OtpCert ->
+ {ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef),
+ {ok, Root, lists:reverse(Chain)}
+ catch
+ throw:_ ->
+ {error, issuer_not_found}
+ end.
+
+find_issuer(CRL, {Db,_}) ->
+ Issuer = public_key:pkix_normalize_name(public_key:pkix_crl_issuer(CRL)),
+ IsIssuerFun =
+ fun({_Key, {_Der,ErlCertCandidate}}, Acc) ->
+ verify_crl_issuer(CRL, ErlCertCandidate, Issuer, Acc);
+ (_, Acc) ->
+ Acc
+ end,
+
+ try ssl_pkix_db:foldl(IsIssuerFun, issuer_not_found, Db) of
+ issuer_not_found ->
+ {error, issuer_not_found}
+ catch
+ {ok, IssuerCert} ->
+ IssuerCert
+ end.
+
+
+verify_crl_issuer(CRL, ErlCertCandidate, Issuer, NotIssuer) ->
+ TBSCert = ErlCertCandidate#'OTPCertificate'.tbsCertificate,
+ case public_key:pkix_normalize_name(TBSCert#'OTPTBSCertificate'.subject) of
+ Issuer ->
+ case public_key:pkix_crl_verify(CRL, ErlCertCandidate) of
+ true ->
+ throw({ok, ErlCertCandidate});
+ false ->
+ NotIssuer
+ end;
+ _ ->
+ NotIssuer
+ end.
diff --git a/lib/ssl/src/ssl_crl_cache.erl b/lib/ssl/src/ssl_crl_cache.erl
new file mode 100644
index 0000000000..60e7427737
--- /dev/null
+++ b/lib/ssl/src/ssl_crl_cache.erl
@@ -0,0 +1,180 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+
+%----------------------------------------------------------------------
+%% Purpose: Simple default CRL cache
+%%----------------------------------------------------------------------
+
+-module(ssl_crl_cache).
+
+-include("ssl_internal.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-behaviour(ssl_crl_cache_api).
+
+-export([lookup/2, select/2, fresh_crl/2]).
+-export([insert/1, insert/2, delete/1]).
+
+%%====================================================================
+%% Cache callback API
+%%====================================================================
+
+lookup(#'DistributionPoint'{distributionPoint = {fullName, Names}},
+ CRLDbInfo) ->
+ get_crls(Names, CRLDbInfo);
+lookup(_,_) ->
+ not_available.
+
+select(Issuer, {{_Cache, Mapping},_}) ->
+ case ssl_pkix_db:lookup(Issuer, Mapping) of
+ undefined ->
+ [];
+ CRLs ->
+ CRLs
+ end.
+
+fresh_crl(#'DistributionPoint'{distributionPoint = {fullName, Names}}, CRL) ->
+ case get_crls(Names, undefined) of
+ not_available ->
+ CRL;
+ [NewCRL] ->
+ NewCRL
+ end.
+
+%%====================================================================
+%% API
+%%====================================================================
+
+insert(CRLs) ->
+ insert(?NO_DIST_POINT, CRLs).
+
+insert(URI, {file, File}) when is_list(URI) ->
+ case file:read_file(File) of
+ {ok, PemBin} ->
+ PemEntries = public_key:pem_decode(PemBin),
+ CRLs = [ CRL || {'CertificateList', CRL, not_encrypted}
+ <- PemEntries],
+ do_insert(URI, CRLs);
+ Error ->
+ Error
+ end;
+insert(URI, {der, CRLs}) ->
+ do_insert(URI, CRLs).
+
+delete({file, File}) ->
+ case file:read_file(File) of
+ {ok, PemBin} ->
+ PemEntries = public_key:pem_decode(PemBin),
+ CRLs = [ CRL || {'CertificateList', CRL, not_encrypted}
+ <- PemEntries],
+ ssl_manager:delete_crls({?NO_DIST_POINT, CRLs});
+ Error ->
+ Error
+ end;
+delete({der, CRLs}) ->
+ ssl_manager:delete_crls({?NO_DIST_POINT, CRLs});
+
+delete(URI) ->
+ case http_uri:parse(URI) of
+ {ok, {http, _, _ , _, Path,_}} ->
+ ssl_manager:delete_crls(string:strip(Path, left, $/));
+ _ ->
+ {error, {only_http_distribution_points_supported, URI}}
+ end.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+do_insert(URI, CRLs) ->
+ case http_uri:parse(URI) of
+ {ok, {http, _, _ , _, Path,_}} ->
+ ssl_manager:insert_crls(string:strip(Path, left, $/), CRLs);
+ _ ->
+ {error, {only_http_distribution_points_supported, URI}}
+ end.
+
+get_crls([], _) ->
+ not_available;
+get_crls([{uniformResourceIdentifier, "http"++_ = URL} | Rest],
+ CRLDbInfo) ->
+ case cache_lookup(URL, CRLDbInfo) of
+ [] ->
+ handle_http(URL, Rest, CRLDbInfo);
+ CRLs ->
+ CRLs
+ end;
+get_crls([ _| Rest], CRLDbInfo) ->
+ %% unsupported CRL location
+ get_crls(Rest, CRLDbInfo).
+
+http_lookup(URL, Rest, CRLDbInfo, Timeout) ->
+ case application:ensure_started(inets) of
+ ok ->
+ http_get(URL, Rest, CRLDbInfo, Timeout);
+ _ ->
+ get_crls(Rest, CRLDbInfo)
+ end.
+
+http_get(URL, Rest, CRLDbInfo, Timeout) ->
+ case httpc:request(get, {URL, [{"connection", "close"}]},
+ [{timeout, Timeout}], [{body_format, binary}]) of
+ {ok, {_Status, _Headers, Body}} ->
+ case Body of
+ <<"-----BEGIN", _/binary>> ->
+ Pem = public_key:pem_decode(Body),
+ lists:filtermap(fun({'CertificateList',
+ CRL, not_encrypted}) ->
+ {true, CRL};
+ (_) ->
+ false
+ end, Pem);
+ _ ->
+ try public_key:der_decode('CertificateList', Body) of
+ _ ->
+ [Body]
+ catch
+ _:_ ->
+ get_crls(Rest, CRLDbInfo)
+ end
+ end;
+ {error, _Reason} ->
+ get_crls(Rest, CRLDbInfo)
+ end.
+
+cache_lookup(_, undefined) ->
+ [];
+cache_lookup(URL, {{Cache, _}, _}) ->
+ {ok, {_, _, _ , _, Path,_}} = http_uri:parse(URL),
+ case ssl_pkix_db:lookup(string:strip(Path, left, $/), Cache) of
+ undefined ->
+ [];
+ CRLs ->
+ CRLs
+ end.
+
+handle_http(URI, Rest, {_, [{http, Timeout}]} = CRLDbInfo) ->
+ CRLs = http_lookup(URI, Rest, CRLDbInfo, Timeout),
+ %% Uncomment to improve performance, but need to
+ %% implement cache limit and or cleaning to prevent
+ %% DoS attack possibilities
+ %%insert(URI, {der, CRLs}),
+ CRLs;
+handle_http(_, Rest, CRLDbInfo) ->
+ get_crls(Rest, CRLDbInfo).
+
diff --git a/lib/ssl/src/ssl_crl_cache_api.erl b/lib/ssl/src/ssl_crl_cache_api.erl
new file mode 100644
index 0000000000..d7b31f280e
--- /dev/null
+++ b/lib/ssl/src/ssl_crl_cache_api.erl
@@ -0,0 +1,31 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_crl_cache_api).
+
+-include_lib("public_key/include/public_key.hrl").
+
+-type db_handle() :: term().
+
+-callback lookup(#'DistributionPoint'{}, db_handle()) -> not_available | [public_key:der_encoded()].
+-callback select(term(), db_handle()) -> [public_key:der_encoded()].
+-callback fresh_crl(#'DistributionPoint'{}, public_key:der_encoded()) -> public_key:der_encoded().
diff --git a/lib/ssl/src/ssl_dist_sup.erl b/lib/ssl/src/ssl_dist_sup.erl
index 58efeaf892..435ad27a44 100644
--- a/lib/ssl/src/ssl_dist_sup.erl
+++ b/lib/ssl/src/ssl_dist_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -69,7 +70,7 @@ connection_manager_child_spec() ->
Name = ssl_connection_dist,
StartFunc = {tls_connection_sup, start_link_dist, []},
Restart = permanent,
- Shutdown = 4000,
+ Shutdown = infinity,
Modules = [tls_connection_sup],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 29b64f7a81..235d6efbb6 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -45,11 +46,11 @@
%% Handshake messages
-export([hello_request/0, server_hello/4, server_hello_done/0,
- certificate/4, certificate_request/4, key_exchange/3,
+ certificate/4, certificate_request/5, key_exchange/3,
finished/5, next_protocol/1]).
%% Handle handshake messages
--export([certify/8, client_certificate_verify/6, certificate_verify/6, verify_signature/5,
+-export([certify/10, client_certificate_verify/6, certificate_verify/6, verify_signature/5,
master_secret/5, server_key_exchange_hash/2, verify_connection/6,
init_handshake_history/0, update_handshake_history/2, verify_server_key/5
]).
@@ -63,8 +64,8 @@
]).
%% Cipher suites handling
--export([available_suites/2, cipher_suites/2,
- select_session/10, supported_ecc/1]).
+-export([available_suites/2, available_signature_algs/3, cipher_suites/2,
+ select_session/11, supported_ecc/1]).
%% Extensions handling
-export([client_hello_extensions/6,
@@ -73,8 +74,8 @@
]).
%% MISC
--export([select_version/3, prf/5, select_hashsign/3,
- select_hashsign_algs/2, select_hashsign_algs/3,
+-export([select_version/3, prf/6, select_hashsign/5,
+ select_hashsign_algs/3,
premaster_secret/2, premaster_secret/3, premaster_secret/4]).
%%====================================================================
@@ -119,7 +120,8 @@ server_hello(SessionId, Version, ConnectionStates, Extensions) ->
server_hello_done() ->
#server_hello_done{}.
-client_hello_extensions(Host, Version, CipherSuites, SslOpts, ConnectionStates, Renegotiation) ->
+client_hello_extensions(Host, Version, CipherSuites,
+ #ssl_options{signature_algs = SupportedHashSigns, versions = AllVersions} = SslOpts, ConnectionStates, Renegotiation) ->
{EcPointFormats, EllipticCurves} =
case advertises_ec_ciphers(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites)) of
true ->
@@ -133,9 +135,10 @@ client_hello_extensions(Host, Version, CipherSuites, SslOpts, ConnectionStates,
renegotiation_info = renegotiation_info(tls_record, client,
ConnectionStates, Renegotiation),
srp = SRP,
- hash_signs = advertised_hash_signs(Version),
+ signature_algs = available_signature_algs(SupportedHashSigns, Version, AllVersions),
ec_point_formats = EcPointFormats,
elliptic_curves = EllipticCurves,
+ alpn = encode_alpn(SslOpts#ssl_options.alpn_advertised_protocols, Renegotiation),
next_protocol_negotiation =
encode_client_protocol_negotiation(SslOpts#ssl_options.next_protocol_selector,
Renegotiation),
@@ -149,7 +152,7 @@ client_hello_extensions(Host, Version, CipherSuites, SslOpts, ConnectionStates,
certificate(OwnCert, CertDbHandle, CertDbRef, client) ->
Chain =
case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of
- {ok, CertChain} ->
+ {ok, _, CertChain} ->
CertChain;
{error, _} ->
%% If no suitable certificate is available, the client
@@ -161,7 +164,7 @@ certificate(OwnCert, CertDbHandle, CertDbRef, client) ->
certificate(OwnCert, CertDbHandle, CertDbRef, server) ->
case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of
- {ok, Chain} ->
+ {ok, _, Chain} ->
#certificate{asn1_certificates = Chain};
{error, _} ->
?ALERT_REC(?FATAL, ?INTERNAL_ERROR)
@@ -201,14 +204,14 @@ client_certificate_verify(OwnCert, MasterSecret, Version,
end.
%%--------------------------------------------------------------------
--spec certificate_request(ssl_cipher:cipher_suite(), db_handle(), certdb_ref(), ssl_record:ssl_version()) ->
- #certificate_request{}.
+-spec certificate_request(ssl_cipher:cipher_suite(), db_handle(),
+ certdb_ref(), #hash_sign_algos{}, ssl_record:ssl_version()) ->
+ #certificate_request{}.
%%
%% Description: Creates a certificate_request message, called by the server.
%%--------------------------------------------------------------------
-certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version) ->
+certificate_request(CipherSuite, CertDbHandle, CertDbRef, HashSigns, Version) ->
Types = certificate_types(ssl_cipher:suite_definition(CipherSuite), Version),
- HashSigns = advertised_hash_signs(Version),
Authorities = certificate_authorities(CertDbHandle, CertDbRef),
#certificate_request{
certificate_types = Types,
@@ -242,7 +245,7 @@ key_exchange(client, _Version, {dh, PublicKey}) ->
dh_public = PublicKey}
};
-key_exchange(client, _Version, {ecdh, #'ECPrivateKey'{publicKey = {0, ECPublicKey}}}) ->
+key_exchange(client, _Version, {ecdh, #'ECPrivateKey'{publicKey = ECPublicKey}}) ->
#client_key_exchange{
exchange_keys = #client_ec_diffie_hellman_public{
dh_public = ECPublicKey}
@@ -283,7 +286,7 @@ key_exchange(server, Version, {dh, {PublicKey, _},
enc_server_key_exchange(Version, ServerDHParams, HashSign,
ClientRandom, ServerRandom, PrivateKey);
-key_exchange(server, Version, {ecdh, #'ECPrivateKey'{publicKey = {0, ECPublicKey},
+key_exchange(server, Version, {ecdh, #'ECPrivateKey'{publicKey = ECPublicKey,
parameters = ECCurve}, HashSign,
ClientRandom, ServerRandom, PrivateKey}) ->
ServerECParams = #server_ecdh_params{curve = ECCurve, public = ECPublicKey},
@@ -349,6 +352,9 @@ verify_server_key(#server_key_params{params_bin = EncParams,
%%
%% Description: Checks that the certificate_verify message is valid.
%%--------------------------------------------------------------------
+certificate_verify(_, _, _, undefined, _, _) ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE);
+
certificate_verify(Signature, PublicKeyInfo, Version,
HashSign = {HashAlgo, _}, MasterSecret, {_, Handshake}) ->
Hash = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake),
@@ -377,55 +383,31 @@ verify_signature(_Version, Hash, _HashAlgo, Signature, {?rsaEncryption, PubKey,
end;
verify_signature(_Version, Hash, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) ->
public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams});
-verify_signature(_Version, Hash, {HashAlgo, ecdsa}, Signature,
+verify_signature(_, Hash, {HashAlgo, _SignAlg}, Signature,
{?'id-ecPublicKey', PublicKey, PublicKeyParams}) ->
public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}).
+
%%--------------------------------------------------------------------
-spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit,
- verify_peer | verify_none, {fun(), term}, fun(),
+ verify_peer | verify_none, {fun(), term}, fun(), term(), term(),
client | server) -> {der_cert(), public_key_info()} | #alert{}.
%%
%% Description: Handles a certificate handshake message
%%--------------------------------------------------------------------
certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef,
- MaxPathLen, _Verify, VerifyFunAndState, PartialChain, Role) ->
+ MaxPathLen, _Verify, ValidationFunAndState0, PartialChain, CRLCheck, CRLDbHandle, Role) ->
[PeerCert | _] = ASN1Certs,
-
- ValidationFunAndState =
- case VerifyFunAndState of
- undefined ->
- {fun(OtpCert, ExtensionOrVerifyResult, SslState) ->
- ssl_certificate:validate_extension(OtpCert,
- ExtensionOrVerifyResult, SslState)
- end, Role};
- {Fun, UserState0} ->
- {fun(OtpCert, {extension, _} = Extension, {SslState, UserState}) ->
- case ssl_certificate:validate_extension(OtpCert,
- Extension,
- SslState) of
- {valid, NewSslState} ->
- {valid, {NewSslState, UserState}};
- {fail, Reason} ->
- apply_user_fun(Fun, OtpCert, Reason, UserState,
- SslState);
- {unknown, _} ->
- apply_user_fun(Fun, OtpCert,
- Extension, UserState, SslState)
- end;
- (OtpCert, VerifyResult, {SslState, UserState}) ->
- apply_user_fun(Fun, OtpCert, VerifyResult, UserState,
- SslState)
- end, {Role, UserState0}}
- end,
+
+ ValidationFunAndState = validation_fun_and_state(ValidationFunAndState0, Role,
+ CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle),
try
- {TrustedErlCert, CertPath} =
+ {TrustedCert, CertPath} =
ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef, PartialChain),
- case public_key:pkix_path_validation(TrustedErlCert,
- CertPath,
- [{max_path_length,
- MaxPathLen},
+ case public_key:pkix_path_validation(TrustedCert,
+ CertPath,
+ [{max_path_length, MaxPathLen},
{verify_fun, ValidationFunAndState}]) of
{ok, {PublicKeyInfo,_}} ->
{PeerCert, PublicKeyInfo};
@@ -582,54 +564,58 @@ server_key_exchange_hash(md5sha, Value) ->
server_key_exchange_hash(Hash, Value) ->
crypto:hash(Hash, Value).
%%--------------------------------------------------------------------
--spec prf(ssl_record:ssl_version(), binary(), binary(), [binary()], non_neg_integer()) ->
+-spec prf(ssl_record:ssl_version(), non_neg_integer(), binary(), binary(), [binary()], non_neg_integer()) ->
{ok, binary()} | {error, undefined}.
%%
%% Description: use the TLS PRF to generate key material
%%--------------------------------------------------------------------
-prf({3,0}, _, _, _, _) ->
+prf({3,0}, _, _, _, _, _) ->
{error, undefined};
-prf({3,1}, Secret, Label, Seed, WantedLength) ->
- {ok, tls_v1:prf(?MD5SHA, Secret, Label, Seed, WantedLength)};
-prf({3,_N}, Secret, Label, Seed, WantedLength) ->
- {ok, tls_v1:prf(?SHA256, Secret, Label, Seed, WantedLength)}.
+prf({3,_N}, PRFAlgo, Secret, Label, Seed, WantedLength) ->
+ {ok, tls_v1:prf(PRFAlgo, Secret, Label, Seed, WantedLength)}.
%%--------------------------------------------------------------------
--spec select_hashsign(#hash_sign_algos{}| undefined, undefined | binary(), ssl_record:ssl_version()) ->
- {atom(), atom()} | undefined.
+-spec select_hashsign(#hash_sign_algos{} | undefined, undefined | binary(),
+ atom(), [atom()], ssl_record:ssl_version()) ->
+ {atom(), atom()} | undefined | #alert{}.
%%
-%% Description:
+%% Description: Handles signature_algorithms extension
%%--------------------------------------------------------------------
-select_hashsign(_, undefined, _Version) ->
+select_hashsign(_, undefined, _, _, _Version) ->
{null, anon};
-select_hashsign(undefined, Cert, Version) ->
+%% The signature_algorithms extension was introduced with TLS 1.2. Ignore it if we have
+%% negotiated a lower version.
+select_hashsign(HashSigns, Cert, KeyExAlgo,
+ undefined, {Major, Minor} = Version) when Major >= 3 andalso Minor >= 3->
+ select_hashsign(HashSigns, Cert, KeyExAlgo, tls_v1:default_signature_algs(Version), Version);
+select_hashsign(#hash_sign_algos{hash_sign_algos = HashSigns}, Cert, KeyExAlgo, SupportedHashSigns,
+ {Major, Minor}) when Major >= 3 andalso Minor >= 3 ->
#'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
#'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
- select_hashsign_algs(undefined, Algo, Version);
-select_hashsign(#hash_sign_algos{hash_sign_algos = HashSigns}, Cert, Version) ->
- #'OTPCertificate'{tbsCertificate = TBSCert} =public_key:pkix_decode_cert(Cert, otp),
- #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
- DefaultHashSign = {_, Sign} = select_hashsign_algs(undefined, Algo, Version),
- case lists:filter(fun({sha, dsa}) ->
+ Sign = cert_sign(Algo),
+ case lists:filter(fun({sha, dsa = S}) when S == Sign ->
true;
({_, dsa}) ->
false;
- ({Hash, S}) when S == Sign ->
- ssl_cipher:is_acceptable_hash(Hash,
- proplists:get_value(hashs, crypto:supports()));
+ ({_, _} = Algos) ->
+ is_acceptable_hash_sign(Algos, Sign, KeyExAlgo, SupportedHashSigns);
(_) ->
false
end, HashSigns) of
[] ->
- DefaultHashSign;
- [HashSign| _] ->
+ ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY);
+ [HashSign | _] ->
HashSign
- end.
+ end;
+select_hashsign(_, Cert, _, _, Version) ->
+ #'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
+ #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
+ select_hashsign_algs(undefined, Algo, Version).
%%--------------------------------------------------------------------
--spec select_hashsign_algs(#hash_sign_algos{}| undefined, oid(), ssl_record:ssl_version()) ->
+-spec select_hashsign_algs({atom(), atom()}| undefined, oid(), ssl_record:ssl_version()) ->
{atom(), atom()}.
%% Description: For TLS 1.2 hash function and signature algorithm pairs can be
@@ -662,24 +648,6 @@ select_hashsign_algs(undefined, ?rsaEncryption, _) ->
select_hashsign_algs(undefined, ?'id-dsa', _) ->
{sha, dsa}.
--spec select_hashsign_algs(atom(), ssl_record:ssl_version()) -> {atom(), atom()}.
-%% Wrap function to keep the knowledge of the default values in
-%% one place only
-select_hashsign_algs(Alg, Version) when (Alg == rsa orelse
- Alg == dhe_rsa orelse
- Alg == dh_rsa orelse
- Alg == ecdhe_rsa orelse
- Alg == ecdh_rsa orelse
- Alg == srp_rsa) ->
- select_hashsign_algs(undefined, ?rsaEncryption, Version);
-select_hashsign_algs(Alg, Version) when (Alg == dhe_dss orelse
- Alg == dh_dss orelse
- Alg == srp_dss) ->
- select_hashsign_algs(undefined, ?'id-dsa', Version);
-select_hashsign_algs(Alg, Version) when (Alg == ecdhe_ecdsa orelse
- Alg == ecdh_ecdsa) ->
- select_hashsign_algs(undefined, ?'id-ecPublicKey', Version).
-
%%--------------------------------------------------------------------
-spec master_secret(atom(), ssl_record:ssl_version(), #session{} | binary(), #connection_states{},
client | server) -> {binary(), #connection_states{}} | #alert{}.
@@ -791,6 +759,11 @@ encode_hello_extensions([], Acc) ->
Size = byte_size(Acc),
<<?UINT16(Size), Acc/binary>>;
+encode_hello_extensions([#alpn{extension_data = ExtensionData} | Rest], Acc) ->
+ Len = byte_size(ExtensionData),
+ ExtLen = Len + 2,
+ encode_hello_extensions(Rest, <<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len),
+ ExtensionData/binary, Acc/binary>>);
encode_hello_extensions([#next_protocol_negotiation{extension_data = ExtensionData} | Rest], Acc) ->
Len = byte_size(ExtensionData),
encode_hello_extensions(Rest, <<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len),
@@ -889,6 +862,25 @@ decode_client_key(ClientKey, Type, Version) ->
decode_server_key(ServerKey, Type, Version) ->
dec_server_key(ServerKey, key_exchange_alg(Type), Version).
+%%
+%% Description: Encode and decode functions for ALPN extension data.
+%%--------------------------------------------------------------------
+
+%% While the RFC opens the door to allow ALPN during renegotiation, in practice
+%% this does not work and it is recommended to ignore any ALPN extension during
+%% renegotiation, as done here.
+encode_alpn(_, true) ->
+ undefined;
+encode_alpn(undefined, _) ->
+ undefined;
+encode_alpn(Protocols, _) ->
+ #alpn{extension_data = lists:foldl(fun encode_protocol/2, <<>>, Protocols)}.
+
+decode_alpn(undefined) ->
+ undefined;
+decode_alpn(#alpn{extension_data=Data}) ->
+ decode_protocols(Data, []).
+
encode_client_protocol_negotiation(undefined, _) ->
undefined;
encode_client_protocol_negotiation(_, false) ->
@@ -1059,9 +1051,56 @@ available_suites(UserSuites, Version) ->
lists:member(Suite, ssl_cipher:all_suites(Version))
end, UserSuites).
-available_suites(ServerCert, UserSuites, Version, Curve) ->
+available_suites(ServerCert, UserSuites, Version, undefined, Curve) ->
ssl_cipher:filter(ServerCert, available_suites(UserSuites, Version))
- -- unavailable_ecc_suites(Curve).
+ -- unavailable_ecc_suites(Curve);
+available_suites(ServerCert, UserSuites, Version, HashSigns, Curve) ->
+ Suites = available_suites(ServerCert, UserSuites, Version, undefined, Curve),
+ filter_hashsigns(Suites, [ssl_cipher:suite_definition(Suite) || Suite <- Suites], HashSigns, []).
+filter_hashsigns([], [], _, Acc) ->
+ lists:reverse(Acc);
+filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns,
+ Acc) when KeyExchange == dhe_ecdsa;
+ KeyExchange == ecdhe_ecdsa ->
+ do_filter_hashsigns(ecdsa, Suite, Suites, Algos, HashSigns, Acc);
+
+filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns,
+ Acc) when KeyExchange == rsa;
+ KeyExchange == dhe_rsa;
+ KeyExchange == ecdhe_rsa;
+ KeyExchange == srp_rsa;
+ KeyExchange == rsa_psk ->
+ do_filter_hashsigns(rsa, Suite, Suites, Algos, HashSigns, Acc);
+filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns, Acc) when
+ KeyExchange == dhe_dss;
+ KeyExchange == srp_dss ->
+ do_filter_hashsigns(dsa, Suite, Suites, Algos, HashSigns, Acc);
+filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns, Acc) when
+ KeyExchange == dh_dss;
+ KeyExchange == dh_rsa;
+ KeyExchange == dh_ecdsa;
+ KeyExchange == ecdh_rsa;
+ KeyExchange == ecdh_ecdsa ->
+ %% Fixed DH certificates MAY be signed with any hash/signature
+ %% algorithm pair appearing in the hash_sign extension. The names
+ %% DH_DSS, DH_RSA, ECDH_ECDSA, and ECDH_RSA are historical.
+ filter_hashsigns(Suites, Algos, HashSigns, [Suite| Acc]);
+filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns, Acc) when
+ KeyExchange == dh_anon;
+ KeyExchange == ecdh_anon;
+ KeyExchange == srp_anon;
+ KeyExchange == psk;
+ KeyExchange == dhe_psk ->
+ %% In this case hashsigns is not used as the kexchange is anonaymous
+ filter_hashsigns(Suites, Algos, HashSigns, [Suite| Acc]).
+
+do_filter_hashsigns(SignAlgo, Suite, Suites, Algos, HashSigns, Acc) ->
+ case lists:keymember(SignAlgo, 2, HashSigns) of
+ true ->
+ filter_hashsigns(Suites, Algos, HashSigns, [Suite| Acc]);
+ false ->
+ filter_hashsigns(Suites, Algos, HashSigns, Acc)
+ end.
unavailable_ecc_suites(no_curve) ->
ssl_cipher:ec_keyed_suites();
@@ -1073,17 +1112,17 @@ cipher_suites(Suites, false) ->
cipher_suites(Suites, true) ->
Suites.
-select_session(SuggestedSessionId, CipherSuites, Compressions, Port, #session{ecc = ECCCurve} =
+select_session(SuggestedSessionId, CipherSuites, HashSigns, Compressions, Port, #session{ecc = ECCCurve} =
Session, Version,
- #ssl_options{ciphers = UserSuites, honor_cipher_order = HCO} = SslOpts,
+ #ssl_options{ciphers = UserSuites, honor_cipher_order = HonorCipherOrder} = SslOpts,
Cache, CacheCb, Cert) ->
{SessionId, Resumed} = ssl_session:server_id(Port, SuggestedSessionId,
SslOpts, Cert,
Cache, CacheCb),
case Resumed of
undefined ->
- Suites = available_suites(Cert, UserSuites, Version, ECCCurve),
- CipherSuite = select_cipher_suite(CipherSuites, Suites, HCO),
+ Suites = available_suites(Cert, UserSuites, Version, HashSigns, ECCCurve),
+ CipherSuite = select_cipher_suite(CipherSuites, Suites, HonorCipherOrder),
Compression = select_compression(Compressions),
{new, Session#session{session_id = SessionId,
cipher_suite = CipherSuite,
@@ -1151,8 +1190,10 @@ handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
#hello_extensions{renegotiation_info = Info,
srp = SRP,
ec_point_formats = ECCFormat,
+ alpn = ALPN,
next_protocol_negotiation = NextProtocolNegotiation}, Version,
- #ssl_options{secure_renegotiate = SecureRenegotation} = Opts,
+ #ssl_options{secure_renegotiate = SecureRenegotation,
+ alpn_preferred_protocols = ALPNPreferredProtocols} = Opts,
#session{cipher_suite = NegotiatedCipherSuite,
compression_method = Compression} = Session0,
ConnectionStates0, Renegotiation) ->
@@ -1161,19 +1202,34 @@ handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
Random, NegotiatedCipherSuite,
ClientCipherSuites, Compression,
ConnectionStates0, Renegotiation, SecureRenegotation),
- ProtocolsToAdvertise = handle_next_protocol_extension(NextProtocolNegotiation, Renegotiation, Opts),
-
+
ServerHelloExtensions = #hello_extensions{
renegotiation_info = renegotiation_info(RecordCB, server,
ConnectionStates, Renegotiation),
- ec_point_formats = server_ecc_extension(Version, ECCFormat),
- next_protocol_negotiation =
- encode_protocols_advertised_on_server(ProtocolsToAdvertise)
+ ec_point_formats = server_ecc_extension(Version, ECCFormat)
},
- {Session, ConnectionStates, ServerHelloExtensions}.
+
+ %% If we receive an ALPN extension and have ALPN configured for this connection,
+ %% we handle it. Otherwise we check for the NPN extension.
+ if
+ ALPN =/= undefined, ALPNPreferredProtocols =/= undefined ->
+ case handle_alpn_extension(ALPNPreferredProtocols, decode_alpn(ALPN)) of
+ #alert{} = Alert ->
+ Alert;
+ Protocol ->
+ {Session, ConnectionStates, Protocol,
+ ServerHelloExtensions#hello_extensions{alpn=encode_alpn([Protocol], Renegotiation)}}
+ end;
+ true ->
+ ProtocolsToAdvertise = handle_next_protocol_extension(NextProtocolNegotiation, Renegotiation, Opts),
+ {Session, ConnectionStates, undefined,
+ ServerHelloExtensions#hello_extensions{next_protocol_negotiation=
+ encode_protocols_advertised_on_server(ProtocolsToAdvertise)}}
+ end.
handle_server_hello_extensions(RecordCB, Random, CipherSuite, Compression,
#hello_extensions{renegotiation_info = Info,
+ alpn = ALPN,
next_protocol_negotiation = NextProtocolNegotiation}, Version,
#ssl_options{secure_renegotiate = SecureRenegotation,
next_protocol_selector = NextProtoSelector},
@@ -1182,11 +1238,23 @@ handle_server_hello_extensions(RecordCB, Random, CipherSuite, Compression,
CipherSuite, undefined,
Compression, ConnectionStates0,
Renegotiation, SecureRenegotation),
- case handle_next_protocol(NextProtocolNegotiation, NextProtoSelector, Renegotiation) of
- #alert{} = Alert ->
- Alert;
- Protocol ->
- {ConnectionStates, Protocol}
+
+ %% If we receive an ALPN extension then this is the protocol selected,
+ %% otherwise handle the NPN extension.
+ case decode_alpn(ALPN) of
+ %% ServerHello contains exactly one protocol: the one selected.
+ %% We also ignore the ALPN extension during renegotiation (see encode_alpn/2).
+ [Protocol] when not Renegotiation ->
+ {ConnectionStates, alpn, Protocol};
+ undefined ->
+ case handle_next_protocol(NextProtocolNegotiation, NextProtoSelector, Renegotiation) of
+ #alert{} = Alert ->
+ Alert;
+ Protocol ->
+ {ConnectionStates, npn, Protocol}
+ end;
+ _ -> %% {error, _Reason} or a list of 0/2+ protocols.
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)
end.
select_version(RecordCB, ClientVersion, Versions) ->
@@ -1291,13 +1359,14 @@ handle_renegotiation_info(_RecordCB, ConnectionStates, SecureRenegotation) ->
hello_extensions_list(#hello_extensions{renegotiation_info = RenegotiationInfo,
srp = SRP,
- hash_signs = HashSigns,
+ signature_algs = HashSigns,
ec_point_formats = EcPointFormats,
elliptic_curves = EllipticCurves,
+ alpn = ALPN,
next_protocol_negotiation = NextProtocolNegotiation,
sni = Sni}) ->
[Ext || Ext <- [RenegotiationInfo, SRP, HashSigns,
- EcPointFormats, EllipticCurves, NextProtocolNegotiation, Sni], Ext =/= undefined].
+ EcPointFormats, EllipticCurves, ALPN, NextProtocolNegotiation, Sni], Ext =/= undefined].
srp_user(#ssl_options{srp_identity = {UserName, _}}) ->
#srp{username = UserName};
@@ -1376,15 +1445,66 @@ sni1(Hostname) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+validation_fun_and_state({Fun, UserState0}, Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle) ->
+ {fun(OtpCert, {extension, _} = Extension, {SslState, UserState}) ->
+ case ssl_certificate:validate(OtpCert,
+ Extension,
+ SslState) of
+ {valid, NewSslState} ->
+ {valid, {NewSslState, UserState}};
+ {fail, Reason} ->
+ apply_user_fun(Fun, OtpCert, Reason, UserState,
+ SslState);
+ {unknown, _} ->
+ apply_user_fun(Fun, OtpCert,
+ Extension, UserState, SslState)
+ end;
+ (OtpCert, VerifyResult, {SslState, UserState}) ->
+ apply_user_fun(Fun, OtpCert, VerifyResult, UserState,
+ SslState)
+ end, {{Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle}, UserState0}};
+validation_fun_and_state(undefined, Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle) ->
+ {fun(OtpCert, {extension, _} = Extension, SslState) ->
+ ssl_certificate:validate(OtpCert,
+ Extension,
+ SslState);
+ (OtpCert, VerifyResult, SslState) when (VerifyResult == valid) or (VerifyResult == valid_peer) ->
+ case crl_check(OtpCert, CRLCheck, CertDbHandle, CertDbRef, CRLDbHandle, VerifyResult) of
+ valid ->
+ {VerifyResult, SslState};
+ Reason ->
+ {fail, Reason}
+ end;
+ (OtpCert, VerifyResult, SslState) ->
+ ssl_certificate:validate(OtpCert,
+ VerifyResult,
+ SslState)
+ end, {Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle}}.
+
+apply_user_fun(Fun, OtpCert, VerifyResult, UserState0,
+ {_, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle} = SslState) when
+ (VerifyResult == valid) or (VerifyResult == valid_peer) ->
+ case Fun(OtpCert, VerifyResult, UserState0) of
+ {Valid, UserState} when (Valid == valid) or (Valid == valid_peer) ->
+ case crl_check(OtpCert, CRLCheck, CertDbHandle, CertDbRef, CRLDbHandle, VerifyResult) of
+ valid ->
+ {Valid, {SslState, UserState}};
+ Result ->
+ apply_user_fun(Fun, OtpCert, Result, UserState, SslState)
+ end;
+ {fail, _} = Fail ->
+ Fail
+ end;
apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) ->
case Fun(OtpCert, ExtensionOrError, UserState0) of
- {valid, UserState} ->
- {valid, {SslState, UserState}};
+ {Valid, UserState} when (Valid == valid) or (Valid == valid_peer)->
+ {Valid, {SslState, UserState}};
{fail, _} = Fail ->
Fail;
{unknown, UserState} ->
{unknown, {SslState, UserState}}
end.
+
path_validation_alert({bad_cert, cert_expired}) ->
?ALERT_REC(?FATAL, ?CERTIFICATE_EXPIRED);
path_validation_alert({bad_cert, invalid_issuer}) ->
@@ -1395,8 +1515,10 @@ path_validation_alert({bad_cert, name_not_permitted}) ->
?ALERT_REC(?FATAL, ?BAD_CERTIFICATE);
path_validation_alert({bad_cert, unknown_critical_extension}) ->
?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE);
-path_validation_alert({bad_cert, cert_revoked}) ->
+path_validation_alert({bad_cert, {revoked, _}}) ->
?ALERT_REC(?FATAL, ?CERTIFICATE_REVOKED);
+path_validation_alert({bad_cert, revocation_status_undetermined}) ->
+ ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE);
path_validation_alert({bad_cert, selfsigned_peer}) ->
?ALERT_REC(?FATAL, ?BAD_CERTIFICATE);
path_validation_alert({bad_cert, unknown_ca}) ->
@@ -1437,6 +1559,7 @@ calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) ->
master_secret(_RecordCB, Version, MasterSecret,
#security_parameters{
+ bulk_cipher_algorithm = BCA,
client_random = ClientRandom,
server_random = ServerRandom,
hash_size = HashSize,
@@ -1455,8 +1578,8 @@ master_secret(_RecordCB, Version, MasterSecret,
ssl_record:set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret,
Role, ConnStates1),
- ClientCipherState = #cipher_state{iv = ClientIV, key = ClientWriteKey},
- ServerCipherState = #cipher_state{iv = ServerIV, key = ServerWriteKey},
+ ClientCipherState = ssl_cipher:cipher_init(BCA, ClientIV, ClientWriteKey),
+ ServerCipherState = ssl_cipher:cipher_init(BCA, ServerIV, ServerWriteKey),
{MasterSecret,
ssl_record:set_pending_cipher_state(ConnStates2, ClientCipherState,
ServerCipherState, Role)}.
@@ -1681,6 +1804,10 @@ dec_server_key_signature(_, _, _) ->
dec_hello_extensions(<<>>, Acc) ->
Acc;
+dec_hello_extensions(<<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len), ExtensionData:Len/binary, Rest/binary>>, Acc)
+ when Len + 2 =:= ExtLen ->
+ ALPN = #alpn{extension_data = ExtensionData},
+ dec_hello_extensions(Rest, Acc#hello_extensions{alpn = ALPN});
dec_hello_extensions(<<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len), ExtensionData:Len/binary, Rest/binary>>, Acc) ->
NextP = #next_protocol_negotiation{extension_data = ExtensionData},
dec_hello_extensions(Rest, Acc#hello_extensions{next_protocol_negotiation = NextP});
@@ -1707,7 +1834,7 @@ dec_hello_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
<<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData,
HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} ||
<<?BYTE(Hash), ?BYTE(Sign)>> <= SignAlgoList],
- dec_hello_extensions(Rest, Acc#hello_extensions{hash_signs =
+ dec_hello_extensions(Rest, Acc#hello_extensions{signature_algs =
#hash_sign_algos{hash_sign_algos = HashSignAlgos}});
dec_hello_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
@@ -1761,18 +1888,19 @@ dec_sni(<<?BYTE(_), ?UINT16(Len), _:Len, Rest/binary>>) -> dec_sni(Rest);
dec_sni(_) -> undefined.
decode_next_protocols({next_protocol_negotiation, Protocols}) ->
- decode_next_protocols(Protocols, []).
-decode_next_protocols(<<>>, Acc) ->
+ decode_protocols(Protocols, []).
+
+decode_protocols(<<>>, Acc) ->
lists:reverse(Acc);
-decode_next_protocols(<<?BYTE(Len), Protocol:Len/binary, Rest/binary>>, Acc) ->
+decode_protocols(<<?BYTE(Len), Protocol:Len/binary, Rest/binary>>, Acc) ->
case Len of
0 ->
- {error, invalid_next_protocols};
+ {error, invalid_protocols};
_ ->
- decode_next_protocols(Rest, [Protocol|Acc])
+ decode_protocols(Rest, [Protocol|Acc])
end;
-decode_next_protocols(_Bytes, _Acc) ->
- {error, invalid_next_protocols}.
+decode_protocols(_Bytes, _Acc) ->
+ {error, invalid_protocols}.
%% encode/decode stream of certificate data to/from list of certificate data
certs_to_list(ASN1Certs) ->
@@ -1806,7 +1934,7 @@ from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) ->
key_exchange_alg(rsa) ->
?KEY_EXCHANGE_RSA;
key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss;
- Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon ->
+ Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon ->
?KEY_EXCHANGE_DIFFIE_HELLMAN;
key_exchange_alg(Alg) when Alg == ecdhe_rsa; Alg == ecdh_rsa;
Alg == ecdhe_ecdsa; Alg == ecdh_ecdsa;
@@ -1826,6 +1954,17 @@ key_exchange_alg(_) ->
%%-------------Extension handling --------------------------------
+%% Receive protocols, choose one from the list, return it.
+handle_alpn_extension(_, {error, _Reason}) ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE);
+handle_alpn_extension([], _) ->
+ ?ALERT_REC(?FATAL, ?NO_APPLICATION_PROTOCOL);
+handle_alpn_extension([ServerProtocol|Tail], ClientProtocols) ->
+ case lists:member(ServerProtocol, ClientProtocols) of
+ true -> ServerProtocol;
+ false -> handle_alpn_extension(Tail, ClientProtocols)
+ end.
+
handle_next_protocol(undefined,
_NextProtocolSelector, _Renegotiating) ->
undefined;
@@ -1904,27 +2043,16 @@ is_member(Suite, SupportedSuites) ->
select_compression(_CompressionMetodes) ->
?NULL.
--define(TLSEXT_SIGALG_RSA(MD), {MD, rsa}).
--define(TLSEXT_SIGALG_DSA(MD), {MD, dsa}).
--define(TLSEXT_SIGALG_ECDSA(MD), {MD, ecdsa}).
-
--define(TLSEXT_SIGALG(MD), ?TLSEXT_SIGALG_ECDSA(MD), ?TLSEXT_SIGALG_RSA(MD)).
-
-advertised_hash_signs({Major, Minor}) when Major >= 3 andalso Minor >= 3 ->
- HashSigns = [?TLSEXT_SIGALG(sha512),
- ?TLSEXT_SIGALG(sha384),
- ?TLSEXT_SIGALG(sha256),
- ?TLSEXT_SIGALG(sha224),
- ?TLSEXT_SIGALG(sha),
- ?TLSEXT_SIGALG_DSA(sha),
- ?TLSEXT_SIGALG_RSA(md5)],
- CryptoSupport = crypto:supports(),
- HasECC = proplists:get_bool(ecdsa, proplists:get_value(public_keys, CryptoSupport)),
- Hashs = proplists:get_value(hashs, CryptoSupport),
- #hash_sign_algos{hash_sign_algos =
- lists:filter(fun({Hash, ecdsa}) -> HasECC andalso proplists:get_bool(Hash, Hashs);
- ({Hash, _}) -> proplists:get_bool(Hash, Hashs) end, HashSigns)};
-advertised_hash_signs(_) ->
+available_signature_algs(undefined, _, _) ->
+ undefined;
+available_signature_algs(SupportedHashSigns, {Major, Minor}, AllVersions) when Major >= 3 andalso Minor >= 3 ->
+ case tls_record:lowest_protocol_version(AllVersions) of
+ {3, 3} ->
+ #hash_sign_algos{hash_sign_algos = SupportedHashSigns};
+ _ ->
+ undefined
+ end;
+available_signature_algs(_, _, _) ->
undefined.
psk_secret(PSKIdentity, PSKLookup) ->
@@ -1955,3 +2083,89 @@ handle_psk_identity(_PSKIdentity, LookupFun)
error;
handle_psk_identity(PSKIdentity, {Fun, UserState}) ->
Fun(psk, PSKIdentity, UserState).
+
+crl_check(_, false, _,_,_, _) ->
+ valid;
+crl_check(_, peer, _, _,_, valid) -> %% Do not check CAs with this option.
+ valid;
+crl_check(OtpCert, Check, CertDbHandle, CertDbRef, {Callback, CRLDbHandle}, _) ->
+ Options = [{issuer_fun, {fun(_DP, CRL, Issuer, DBInfo) ->
+ ssl_crl:trusted_cert_and_path(CRL, Issuer, DBInfo)
+ end, {CertDbHandle, CertDbRef}}},
+ {update_crl, fun(DP, CRL) -> Callback:fresh_crl(DP, CRL) end}
+ ],
+ case dps_and_crls(OtpCert, Callback, CRLDbHandle, ext) of
+ no_dps ->
+ crl_check_same_issuer(OtpCert, Check,
+ dps_and_crls(OtpCert, Callback, CRLDbHandle, same_issuer),
+ Options);
+ DpsAndCRLs -> %% This DP list may be empty if relevant CRLs existed
+ %% but could not be retrived, will result in {bad_cert, revocation_status_undetermined}
+ case public_key:pkix_crls_validate(OtpCert, DpsAndCRLs, Options) of
+ {bad_cert, revocation_status_undetermined} ->
+ crl_check_same_issuer(OtpCert, Check, dps_and_crls(OtpCert, Callback,
+ CRLDbHandle, same_issuer), Options);
+ Other ->
+ Other
+ end
+ end.
+
+crl_check_same_issuer(OtpCert, best_effort, Dps, Options) ->
+ case public_key:pkix_crls_validate(OtpCert, Dps, Options) of
+ {bad_cert, revocation_status_undetermined} ->
+ valid;
+ Other ->
+ Other
+ end;
+crl_check_same_issuer(OtpCert, _, Dps, Options) ->
+ public_key:pkix_crls_validate(OtpCert, Dps, Options).
+
+dps_and_crls(OtpCert, Callback, CRLDbHandle, ext) ->
+ case public_key:pkix_dist_points(OtpCert) of
+ [] ->
+ no_dps;
+ DistPoints ->
+ distpoints_lookup(DistPoints, Callback, CRLDbHandle)
+ end;
+
+dps_and_crls(OtpCert, Callback, CRLDbHandle, same_issuer) ->
+ DP = #'DistributionPoint'{distributionPoint = {fullName, GenNames}} =
+ public_key:pkix_dist_point(OtpCert),
+ CRLs = lists:flatmap(fun({directoryName, Issuer}) ->
+ Callback:select(Issuer, CRLDbHandle);
+ (_) ->
+ []
+ end, GenNames),
+ [{DP, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs].
+
+distpoints_lookup([], _, _) ->
+ [];
+distpoints_lookup([DistPoint | Rest], Callback, CRLDbHandle) ->
+ case Callback:lookup(DistPoint, CRLDbHandle) of
+ not_available ->
+ distpoints_lookup(Rest, Callback, CRLDbHandle);
+ CRLs ->
+ [{DistPoint, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs]
+ end.
+
+cert_sign(?rsaEncryption) ->
+ rsa;
+cert_sign(?'id-ecPublicKey') ->
+ ecdsa;
+cert_sign(?'id-dsa') ->
+ dsa;
+cert_sign(Alg) ->
+ {_, Sign} =public_key:pkix_sign_types(Alg),
+ Sign.
+
+is_acceptable_hash_sign({_, Sign} = Algos, Sign, _, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign(Algos,_, KeyExAlgo, SupportedHashSigns) when KeyExAlgo == dh_ecdsa;
+ KeyExAlgo == ecdh_rsa;
+ KeyExAlgo == ecdh_ecdsa ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign(_,_,_,_) ->
+ false.
+is_acceptable_hash_sign(Algos, SupportedHashSigns) ->
+ lists:member(Algos, SupportedHashSigns).
+
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index 80284faef0..b74a65939b 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -94,7 +95,8 @@
-record(hello_extensions, {
renegotiation_info,
- hash_signs, % supported combinations of hashes/signature algos
+ signature_algs, % supported combinations of hashes/signature algos
+ alpn,
next_protocol_negotiation = undefined, % [binary()]
srp,
ec_point_formats,
@@ -301,6 +303,14 @@
}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Application-Layer Protocol Negotiation RFC 7301
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-define(ALPN_EXT, 16).
+
+-record(alpn, {extension_data}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Next Protocol Negotiation
%% (http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-02)
%% (http://technotes.googlecode.com/git/nextprotoneg.html)
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index 88105cac5a..20f0b7d0da 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -61,17 +62,25 @@
-define(CDR_HDR_SIZE, 12).
-define(DEFAULT_TIMEOUT, 5000).
+-define(NO_DIST_POINT, "http://dummy/no_distribution_point").
+-define(NO_DIST_POINT_PATH, "dummy/no_distribution_point").
%% Common enumerate values in for SSL-protocols
-define(NULL, 0).
-define(TRUE, 0).
-define(FALSE, 1).
--define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1, sslv3]).
--define(MIN_SUPPORTED_VERSIONS, ['tlsv1.1', tlsv1, sslv3]).
+%% sslv3 is considered insecure due to lack of padding check (Poodle attack)
+%% Keep as interop with legacy software but do not support as default
+-define(ALL_AVAILABLE_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1, sslv3]).
+-define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1]).
+-define(MIN_SUPPORTED_VERSIONS, ['tlsv1.1', tlsv1]).
-define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
-define(MIN_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
+-define('24H_in_msec', 86400000).
+-define('24H_in_sec', 86400).
+
-record(ssl_options, {
protocol :: tls | dtls,
versions :: [ssl_record:ssl_version()], %% ssl_record:atom_version() in API
@@ -105,21 +114,29 @@
reuse_sessions :: boolean(),
renegotiate_at,
secure_renegotiate,
+ client_renegotiation,
%% undefined if not hibernating, or number of ms of
%% inactivity after which ssl_connection will go into
%% hibernation
hibernate_after :: boolean(),
%% This option should only be set to true by inet_tls_dist
erl_dist = false :: boolean(),
- next_protocols_advertised = undefined, %% [binary()],
+ alpn_advertised_protocols = undefined :: [binary()] | undefined ,
+ alpn_preferred_protocols = undefined :: [binary()] | undefined,
+ next_protocols_advertised = undefined :: [binary()] | undefined,
next_protocol_selector = undefined, %% fun([binary()]) -> binary())
log_alert :: boolean(),
server_name_indication = undefined,
+ sni_hosts :: [{inet:hostname(), [tuple()]}],
+ sni_fun :: function() | undefined,
%% Should the server prefer its own cipher order over the one provided by
%% the client?
- honor_cipher_order = false,
- padding_check = true,
- fallback = false
+ honor_cipher_order = false :: boolean(),
+ padding_check = true :: boolean(),
+ fallback = false :: boolean(),
+ crl_check :: boolean() | peer | best_effort,
+ crl_cache,
+ signature_algs
}).
-record(socket_options,
diff --git a/lib/ssl/src/ssl_listen_tracker_sup.erl b/lib/ssl/src/ssl_listen_tracker_sup.erl
index 29f40e846d..f9a0ba331e 100644
--- a/lib/ssl/src/ssl_listen_tracker_sup.erl
+++ b/lib/ssl/src/ssl_listen_tracker_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index c4f1f7f193..8ed29cc6b0 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,10 +27,11 @@
%% Internal application API
-export([start_link/1, start_link_dist/1,
- connection_init/2, cache_pem_file/2,
+ connection_init/3, cache_pem_file/2,
lookup_trusted_cert/4,
new_session_id/1, clean_cert_db/2,
register_session/2, register_session/3, invalidate_session/2,
+ insert_crls/2, insert_crls/3, delete_crls/1, delete_crls/2,
invalidate_session/3, invalidate_pem/1, clear_pem_cache/0, manager_name/1]).
% Spawn export
@@ -44,24 +46,28 @@
-include_lib("kernel/include/file.hrl").
-record(state, {
- session_cache,
- session_cache_cb,
- session_lifetime,
- certificate_db,
- session_validation_timer,
+ session_cache_client :: db_handle(),
+ session_cache_server :: db_handle(),
+ session_cache_cb :: atom(),
+ session_lifetime :: integer(),
+ certificate_db :: db_handle(),
+ session_validation_timer :: reference(),
last_delay_timer = {undefined, undefined},%% Keep for testing purposes
- last_pem_check,
- clear_pem_cache
+ last_pem_check :: erlang:timestamp(),
+ clear_pem_cache :: integer(),
+ session_cache_client_max :: integer(),
+ session_cache_server_max :: integer(),
+ session_server_invalidator :: undefined | pid(),
+ session_client_invalidator :: undefined | pid()
}).
--define('24H_in_msec', 86400000).
--define('24H_in_sec', 86400).
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
-define(SESSION_VALIDATION_INTERVAL, 60000).
-define(CLEAR_PEM_CACHE, 120000).
-define(CLEAN_SESSION_DB, 60000).
-define(CLEAN_CERT_DB, 500).
--define(NOT_TO_BIG, 10).
+-define(DEFAULT_MAX_SESSION_CACHE, 1000).
+-define(LOAD_MITIGATION, 10).
%%====================================================================
%% API
@@ -86,7 +92,8 @@ manager_name(dist) ->
%%--------------------------------------------------------------------
start_link(Opts) ->
DistMangerName = manager_name(normal),
- gen_server:start_link({local, DistMangerName}, ?MODULE, [DistMangerName, Opts], []).
+ gen_server:start_link({local, DistMangerName},
+ ?MODULE, [DistMangerName, Opts], []).
%%--------------------------------------------------------------------
-spec start_link_dist(list()) -> {ok, pid()} | ignore | {error, term()}.
@@ -96,22 +103,25 @@ start_link(Opts) ->
%%--------------------------------------------------------------------
start_link_dist(Opts) ->
DistMangerName = manager_name(dist),
- gen_server:start_link({local, DistMangerName}, ?MODULE, [DistMangerName, Opts], []).
+ gen_server:start_link({local, DistMangerName},
+ ?MODULE, [DistMangerName, Opts], []).
%%--------------------------------------------------------------------
--spec connection_init(binary()| {der, list()}, client | server) ->
- {ok, certdb_ref(), db_handle(), db_handle(), db_handle(), db_handle()}.
+-spec connection_init(binary()| {der, list()}, client | server,
+ {Cb :: atom(), Handle:: term()}) ->
+ {ok, certdb_ref(), db_handle(), db_handle(),
+ db_handle(), db_handle(), CRLInfo::term()}.
%%
%% Description: Do necessary initializations for a new connection.
%%--------------------------------------------------------------------
-connection_init({der, _} = Trustedcerts, Role) ->
- call({connection_init, Trustedcerts, Role});
+connection_init({der, _} = Trustedcerts, Role, CRLCache) ->
+ call({connection_init, Trustedcerts, Role, CRLCache});
-connection_init(<<>> = Trustedcerts, Role) ->
- call({connection_init, Trustedcerts, Role});
+connection_init(<<>> = Trustedcerts, Role, CRLCache) ->
+ call({connection_init, Trustedcerts, Role, CRLCache});
-connection_init(Trustedcerts, Role) ->
- call({connection_init, Trustedcerts, Role}).
+connection_init(Trustedcerts, Role, CRLCache) ->
+ call({connection_init, Trustedcerts, Role, CRLCache}).
%%--------------------------------------------------------------------
-spec cache_pem_file(binary(), term()) -> {ok, term()} | {error, reason()}.
@@ -123,7 +133,7 @@ cache_pem_file(File, DbHandle) ->
[{Content,_}] ->
{ok, Content};
[Content] ->
- {ok, Content};
+ {ok, Content};
undefined ->
call({cache_pem, File})
end.
@@ -164,7 +174,8 @@ new_session_id(Port) ->
%% be called by ssl-connection processes.
%%--------------------------------------------------------------------
clean_cert_db(Ref, File) ->
- erlang:send_after(?CLEAN_CERT_DB, get(ssl_manager), {clean_cert_db, Ref, File}),
+ erlang:send_after(?CLEAN_CERT_DB, get(ssl_manager),
+ {clean_cert_db, Ref, File}),
ok.
%%--------------------------------------------------------------------
@@ -186,17 +197,36 @@ register_session(Port, Session) ->
%%--------------------------------------------------------------------
-spec invalidate_session(host(), inet:port_number(), #session{}) -> ok.
invalidate_session(Host, Port, Session) ->
+ load_mitigation(),
cast({invalidate_session, Host, Port, Session}).
-spec invalidate_session(inet:port_number(), #session{}) -> ok.
invalidate_session(Port, Session) ->
+ load_mitigation(),
cast({invalidate_session, Port, Session}).
-
-spec invalidate_pem(File::binary()) -> ok.
invalidate_pem(File) ->
cast({invalidate_pem, File}).
+insert_crls(Path, CRLs)->
+ insert_crls(Path, CRLs, normal).
+insert_crls(?NO_DIST_POINT_PATH = Path, CRLs, ManagerType)->
+ put(ssl_manager, manager_name(ManagerType)),
+ cast({insert_crls, Path, CRLs});
+insert_crls(Path, CRLs, ManagerType)->
+ put(ssl_manager, manager_name(ManagerType)),
+ call({insert_crls, Path, CRLs}).
+
+delete_crls(Path)->
+ delete_crls(Path, normal).
+delete_crls(?NO_DIST_POINT_PATH = Path, ManagerType)->
+ put(ssl_manager, manager_name(ManagerType)),
+ cast({delete_crls, Path});
+delete_crls(Path, ManagerType)->
+ put(ssl_manager, manager_name(ManagerType)),
+ call({delete_crls, Path}).
+
%%====================================================================
%% gen_server callbacks
%%====================================================================
@@ -215,18 +245,30 @@ init([Name, Opts]) ->
SessionLifeTime =
proplists:get_value(session_lifetime, Opts, ?'24H_in_sec'),
CertDb = ssl_pkix_db:create(),
- SessionCache = CacheCb:init(proplists:get_value(session_cb_init_args, Opts, [])),
+ ClientSessionCache =
+ CacheCb:init([{role, client} |
+ proplists:get_value(session_cb_init_args, Opts, [])]),
+ ServerSessionCache =
+ CacheCb:init([{role, server} |
+ proplists:get_value(session_cb_init_args, Opts, [])]),
Timer = erlang:send_after(SessionLifeTime * 1000 + 5000,
self(), validate_sessions),
Interval = pem_check_interval(),
erlang:send_after(Interval, self(), clear_pem_cache),
{ok, #state{certificate_db = CertDb,
- session_cache = SessionCache,
+ session_cache_client = ClientSessionCache,
+ session_cache_server = ServerSessionCache,
session_cache_cb = CacheCb,
session_lifetime = SessionLifeTime,
session_validation_timer = Timer,
last_pem_check = os:timestamp(),
- clear_pem_cache = Interval
+ clear_pem_cache = Interval,
+ session_cache_client_max =
+ max_session_cache_size(session_cache_client_max),
+ session_cache_server_max =
+ max_session_cache_size(session_cache_server_max),
+ session_client_invalidator = undefined,
+ session_server_invalidator = undefined
}}.
%%--------------------------------------------------------------------
@@ -240,32 +282,39 @@ init([Name, Opts]) ->
%%
%% Description: Handling call messages
%%--------------------------------------------------------------------
-handle_call({{connection_init, <<>>, _Role}, _Pid}, _From,
- #state{certificate_db = [CertDb, FileRefDb, PemChace],
- session_cache = Cache} = State) ->
- Result = {ok, make_ref(),CertDb, FileRefDb, PemChace, Cache},
- {reply, Result, State};
-
-handle_call({{connection_init, Trustedcerts, _Role}, Pid}, _From,
- #state{certificate_db = [CertDb, FileRefDb, PemChace] = Db,
- session_cache = Cache} = State) ->
- Result =
- try
- {ok, Ref} = ssl_pkix_db:add_trusted_certs(Pid, Trustedcerts, Db),
- {ok, Ref, CertDb, FileRefDb, PemChace, Cache}
- catch
- _:Reason ->
- {error, Reason}
- end,
- {reply, Result, State};
-
-handle_call({{new_session_id,Port}, _},
+handle_call({{connection_init, <<>>, Role, {CRLCb, UserCRLDb}}, _Pid}, _From,
+ #state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) ->
+ Ref = make_ref(),
+ Result = {ok, Ref, CertDb, FileRefDb, PemChace,
+ session_cache(Role, State), {CRLCb, crl_db_info(Db, UserCRLDb)}},
+ {reply, Result, State#state{certificate_db = Db}};
+
+handle_call({{connection_init, Trustedcerts, Role, {CRLCb, UserCRLDb}}, Pid}, _From,
+ #state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) ->
+ case add_trusted_certs(Pid, Trustedcerts, Db) of
+ {ok, Ref} ->
+ {reply, {ok, Ref, CertDb, FileRefDb, PemChace, session_cache(Role, State),
+ {CRLCb, crl_db_info(Db, UserCRLDb)}}, State};
+ {error, _} = Error ->
+ {reply, Error, State}
+ end;
+
+handle_call({{insert_crls, Path, CRLs}, _}, _From,
+ #state{certificate_db = Db} = State) ->
+ ssl_pkix_db:add_crls(Db, Path, CRLs),
+ {reply, ok, State};
+
+handle_call({{delete_crls, CRLsOrPath}, _}, _From,
+ #state{certificate_db = Db} = State) ->
+ ssl_pkix_db:remove_crls(Db, CRLsOrPath),
+ {reply, ok, State};
+
+handle_call({{new_session_id, Port}, _},
_, #state{session_cache_cb = CacheCb,
- session_cache = Cache} = State) ->
+ session_cache_server = Cache} = State) ->
Id = new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb),
{reply, Id, State};
-
handle_call({{cache_pem,File}, _Pid}, _,
#state{certificate_db = Db} = State) ->
try ssl_pkix_db:cache_pem_file(File, Db) of
@@ -275,7 +324,8 @@ handle_call({{cache_pem,File}, _Pid}, _,
_:Reason ->
{reply, {error, Reason}, State}
end;
-handle_call({unconditionally_clear_pem_cache, _},_, #state{certificate_db = [_,_,PemChace]} = State) ->
+handle_call({unconditionally_clear_pem_cache, _},_,
+ #state{certificate_db = [_,_,PemChace | _]} = State) ->
ssl_pkix_db:clear(PemChace),
{reply, ok, State}.
@@ -287,36 +337,38 @@ handle_call({unconditionally_clear_pem_cache, _},_, #state{certificate_db = [_,_
%%
%% Description: Handling cast messages
%%--------------------------------------------------------------------
-handle_cast({register_session, Host, Port, Session},
- #state{session_cache = Cache,
- session_cache_cb = CacheCb} = State) ->
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
- NewSession = Session#session{time_stamp = TimeStamp},
- CacheCb:update(Cache, {{Host, Port},
- NewSession#session.session_id}, NewSession),
+handle_cast({register_session, Host, Port, Session}, State0) ->
+ State = ssl_client_register_session(Host, Port, Session, State0),
{noreply, State};
-handle_cast({register_session, Port, Session},
- #state{session_cache = Cache,
- session_cache_cb = CacheCb} = State) ->
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
- NewSession = Session#session{time_stamp = TimeStamp},
- CacheCb:update(Cache, {Port, NewSession#session.session_id}, NewSession),
+handle_cast({register_session, Port, Session}, State0) ->
+ State = server_register_session(Port, Session, State0),
{noreply, State};
handle_cast({invalidate_session, Host, Port,
#session{session_id = ID} = Session},
- #state{session_cache = Cache,
+ #state{session_cache_client = Cache,
session_cache_cb = CacheCb} = State) ->
invalidate_session(Cache, CacheCb, {{Host, Port}, ID}, Session, State);
handle_cast({invalidate_session, Port, #session{session_id = ID} = Session},
- #state{session_cache = Cache,
+ #state{session_cache_server = Cache,
session_cache_cb = CacheCb} = State) ->
invalidate_session(Cache, CacheCb, {Port, ID}, Session, State);
+
+handle_cast({insert_crls, Path, CRLs},
+ #state{certificate_db = Db} = State) ->
+ ssl_pkix_db:add_crls(Db, Path, CRLs),
+ {noreply, State};
+
+handle_cast({delete_crls, CRLsOrPath},
+ #state{certificate_db = Db} = State) ->
+ ssl_pkix_db:remove_crls(Db, CRLsOrPath),
+ {noreply, State};
+
handle_cast({invalidate_pem, File},
- #state{certificate_db = [_, _, PemCache]} = State) ->
+ #state{certificate_db = [_, _, PemCache | _]} = State) ->
ssl_pkix_db:remove(File, PemCache),
{noreply, State}.
@@ -329,21 +381,27 @@ handle_cast({invalidate_pem, File},
%% Description: Handling all non call/cast messages
%%-------------------------------------------------------------------
handle_info(validate_sessions, #state{session_cache_cb = CacheCb,
- session_cache = Cache,
- session_lifetime = LifeTime
+ session_cache_client = ClientCache,
+ session_cache_server = ServerCache,
+ session_lifetime = LifeTime,
+ session_client_invalidator = Client,
+ session_server_invalidator = Server
} = State) ->
Timer = erlang:send_after(?SESSION_VALIDATION_INTERVAL,
self(), validate_sessions),
- start_session_validator(Cache, CacheCb, LifeTime),
- {noreply, State#state{session_validation_timer = Timer}};
+ CPid = start_session_validator(ClientCache, CacheCb, LifeTime, Client),
+ SPid = start_session_validator(ServerCache, CacheCb, LifeTime, Server),
+ {noreply, State#state{session_validation_timer = Timer,
+ session_client_invalidator = CPid,
+ session_server_invalidator = SPid}};
-handle_info({delayed_clean_session, Key}, #state{session_cache = Cache,
- session_cache_cb = CacheCb
- } = State) ->
+
+handle_info({delayed_clean_session, Key, Cache}, #state{session_cache_cb = CacheCb
+ } = State) ->
CacheCb:delete(Cache, Key),
{noreply, State};
-handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace],
+handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace | _],
clear_pem_cache = Interval,
last_pem_check = CheckPoint} = State) ->
NewCheckPoint = os:timestamp(),
@@ -351,9 +409,8 @@ handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace],
erlang:send_after(Interval, self(), clear_pem_cache),
{noreply, State#state{last_pem_check = NewCheckPoint}};
-
handle_info({clean_cert_db, Ref, File},
- #state{certificate_db = [CertDb,RefDb, PemCache]} = State) ->
+ #state{certificate_db = [CertDb,RefDb, PemCache | _]} = State) ->
case ssl_pkix_db:lookup(Ref, RefDb) of
undefined -> %% Alredy cleaned
@@ -363,10 +420,10 @@ handle_info({clean_cert_db, Ref, File},
end,
{noreply, State};
-handle_info({'EXIT', _, _}, State) ->
- %% Session validator died!! Do we need to take any action?
- %% maybe error log
- {noreply, State};
+handle_info({'EXIT', Pid, _}, #state{session_client_invalidator = Pid} = State) ->
+ {noreply, State#state{session_client_invalidator = undefined}};
+handle_info({'EXIT', Pid, _}, #state{session_server_invalidator = Pid} = State) ->
+ {noreply, State#state{session_server_invalidator = undefined}};
handle_info(_Info, State) ->
{noreply, State}.
@@ -380,12 +437,14 @@ handle_info(_Info, State) ->
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, #state{certificate_db = Db,
- session_cache = SessionCache,
+ session_cache_client = ClientSessionCache,
+ session_cache_server = ServerSessionCache,
session_cache_cb = CacheCb,
session_validation_timer = Timer}) ->
erlang:cancel_timer(Timer),
ssl_pkix_db:remove(Db),
- CacheCb:terminate(SessionCache),
+ catch CacheCb:terminate(ClientSessionCache),
+ catch CacheCb:terminate(ServerSessionCache),
ok.
%%--------------------------------------------------------------------
@@ -421,9 +480,11 @@ validate_session(Port, Session, LifeTime) ->
invalidate_session(Port, Session)
end.
-start_session_validator(Cache, CacheCb, LifeTime) ->
+start_session_validator(Cache, CacheCb, LifeTime, undefined) ->
spawn_link(?MODULE, init_session_validator,
- [[get(ssl_manager), Cache, CacheCb, LifeTime]]).
+ [[get(ssl_manager), Cache, CacheCb, LifeTime]]);
+start_session_validator(_,_,_, Pid) ->
+ Pid.
init_session_validator([SslManagerName, Cache, CacheCb, LifeTime]) ->
put(ssl_manager, SslManagerName),
@@ -445,7 +506,15 @@ delay_time() ->
?CLEAN_SESSION_DB
end.
-invalidate_session(Cache, CacheCb, Key, Session, #state{last_delay_timer = LastTimer} = State) ->
+max_session_cache_size(CacheType) ->
+ case application:get_env(ssl, CacheType) of
+ {ok, Size} when is_integer(Size) ->
+ Size;
+ _ ->
+ ?DEFAULT_MAX_SESSION_CACHE
+ end.
+
+invalidate_session(Cache, CacheCb, Key, Session, State) ->
case CacheCb:lookup(Cache, Key) of
undefined -> %% Session is already invalidated
{noreply, State};
@@ -453,15 +522,23 @@ invalidate_session(Cache, CacheCb, Key, Session, #state{last_delay_timer = LastT
CacheCb:delete(Cache, Key),
{noreply, State};
_ ->
- %% When a registered session is invalidated we need to wait a while before deleting
- %% it as there might be pending connections that rightfully needs to look
- %% up the session data but new connections should not get to use this session.
- CacheCb:update(Cache, Key, Session#session{is_resumable = false}),
- TRef =
- erlang:send_after(delay_time(), self(), {delayed_clean_session, Key}),
- {noreply, State#state{last_delay_timer = last_delay_timer(Key, TRef, LastTimer)}}
+ delayed_invalidate_session(CacheCb, Cache, Key, Session, State)
end.
+delayed_invalidate_session(CacheCb, Cache, Key, Session,
+ #state{last_delay_timer = LastTimer} = State) ->
+ %% When a registered session is invalidated we need to
+ %% wait a while before deleting it as there might be
+ %% pending connections that rightfully needs to look up
+ %% the session data but new connections should not get to
+ %% use this session.
+ CacheCb:update(Cache, Key, Session#session{is_resumable = false}),
+ TRef =
+ erlang:send_after(delay_time(), self(),
+ {delayed_clean_session, Key, Cache}),
+ {noreply, State#state{last_delay_timer =
+ last_delay_timer(Key, TRef, LastTimer)}}.
+
last_delay_timer({{_,_},_}, TRef, {LastServer, _}) ->
{LastServer, TRef};
last_delay_timer({_,_}, TRef, {_, LastClient}) ->
@@ -480,12 +557,12 @@ new_id(Port, Tries, Cache, CacheCb) ->
Id = crypto:rand_bytes(?NUM_OF_SESSION_ID_BYTES),
case CacheCb:lookup(Cache, {Port, Id}) of
undefined ->
- Now = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ Now = erlang:monotonic_time(),
%% New sessions can not be set to resumable
%% until handshake is compleate and the
%% other session values are set.
CacheCb:update(Cache, {Port, Id}, #session{session_id = Id,
- is_resumable = false,
+ is_resumable = new,
time_stamp = Now}),
Id;
_ ->
@@ -507,6 +584,84 @@ clean_cert_db(Ref, CertDb, RefDb, PemCache, File) ->
ok
end.
+ssl_client_register_session(Host, Port, Session, #state{session_cache_client = Cache,
+ session_cache_cb = CacheCb,
+ session_cache_client_max = Max,
+ session_client_invalidator = Pid0} = State) ->
+ TimeStamp = erlang:monotonic_time(),
+ NewSession = Session#session{time_stamp = TimeStamp},
+
+ case CacheCb:select_session(Cache, {Host, Port}) of
+ no_session ->
+ Pid = do_register_session({{Host, Port},
+ NewSession#session.session_id},
+ NewSession, Max, Pid0, Cache, CacheCb),
+ State#state{session_client_invalidator = Pid};
+ Sessions ->
+ register_unique_session(Sessions, NewSession, {Host, Port}, State)
+ end.
+
+server_register_session(Port, Session, #state{session_cache_server_max = Max,
+ session_cache_server = Cache,
+ session_cache_cb = CacheCb,
+ session_server_invalidator = Pid0} = State) ->
+ TimeStamp = erlang:monotonic_time(),
+ NewSession = Session#session{time_stamp = TimeStamp},
+ Pid = do_register_session({Port, NewSession#session.session_id},
+ NewSession, Max, Pid0, Cache, CacheCb),
+ State#state{session_server_invalidator = Pid}.
+
+do_register_session(Key, Session, Max, Pid, Cache, CacheCb) ->
+ try CacheCb:size(Cache) of
+ N when N > Max ->
+ invalidate_session_cache(Pid, CacheCb, Cache);
+ _ ->
+ CacheCb:update(Cache, Key, Session),
+ Pid
+ catch
+ error:undef ->
+ CacheCb:update(Cache, Key, Session),
+ Pid
+ end.
+
+
+%% Do not let dumb clients create a gigantic session table
+%% for itself creating big delays at connection time.
+register_unique_session(Sessions, Session, PartialKey,
+ #state{session_cache_client_max = Max,
+ session_cache_client = Cache,
+ session_cache_cb = CacheCb,
+ session_client_invalidator = Pid0} = State) ->
+ case exists_equivalent(Session , Sessions) of
+ true ->
+ State;
+ false ->
+ Pid = do_register_session({PartialKey,
+ Session#session.session_id},
+ Session, Max, Pid0, Cache, CacheCb),
+ State#state{session_client_invalidator = Pid}
+ end.
+
+exists_equivalent(_, []) ->
+ false;
+exists_equivalent(#session{
+ peer_certificate = PeerCert,
+ own_certificate = OwnCert,
+ compression_method = Compress,
+ cipher_suite = CipherSuite,
+ srp_username = SRP,
+ ecc = ECC} ,
+ [#session{
+ peer_certificate = PeerCert,
+ own_certificate = OwnCert,
+ compression_method = Compress,
+ cipher_suite = CipherSuite,
+ srp_username = SRP,
+ ecc = ECC} | _]) ->
+ true;
+exists_equivalent(Session, [ _ | Rest]) ->
+ exists_equivalent(Session, Rest).
+
start_pem_cache_validator(PemCache, CheckPoint) ->
spawn_link(?MODULE, init_pem_cache_validator,
[[get(ssl_manager), PemCache, CheckPoint]]).
@@ -539,6 +694,39 @@ pem_check_interval() ->
end.
is_before_checkpoint(Time, CheckPoint) ->
- calendar:datetime_to_gregorian_seconds(calendar:now_to_datetime(CheckPoint)) -
+ calendar:datetime_to_gregorian_seconds(
+ calendar:now_to_datetime(CheckPoint)) -
calendar:datetime_to_gregorian_seconds(Time) > 0.
+add_trusted_certs(Pid, Trustedcerts, Db) ->
+ try
+ ssl_pkix_db:add_trusted_certs(Pid, Trustedcerts, Db)
+ catch
+ _:Reason ->
+ {error, Reason}
+ end.
+
+session_cache(client, #state{session_cache_client = Cache}) ->
+ Cache;
+session_cache(server, #state{session_cache_server = Cache}) ->
+ Cache.
+
+crl_db_info([_,_,_,Local], {internal, Info}) ->
+ {Local, Info};
+crl_db_info(_, UserCRLDb) ->
+ UserCRLDb.
+
+%% Only start a session invalidator if there is not
+%% one already active
+invalidate_session_cache(undefined, CacheCb, Cache) ->
+ start_session_validator(Cache, CacheCb, {invalidate_before, erlang:monotonic_time()}, undefined);
+invalidate_session_cache(Pid, _CacheCb, _Cache) ->
+ Pid.
+
+load_mitigation() ->
+ MSec = rand:uniform(?LOAD_MITIGATION),
+ receive
+ after
+ MSec ->
+ continue
+ end.
diff --git a/lib/ssl/src/ssl_pkix_db.erl b/lib/ssl/src/ssl_pkix_db.erl
index 8531445ba4..b16903d7c7 100644
--- a/lib/ssl/src/ssl_pkix_db.erl
+++ b/lib/ssl/src/ssl_pkix_db.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,9 +28,9 @@
-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/file.hrl").
--export([create/0, remove/1, add_trusted_certs/3,
+-export([create/0, add_crls/3, remove_crls/2, remove/1, add_trusted_certs/3,
remove_trusted_certs/2, insert/3, remove/2, clear/1, db_size/1,
- ref_count/3, lookup_trusted_cert/4, foldl/3,
+ ref_count/3, lookup_trusted_cert/4, foldl/3, select_cert_by_issuer/2,
lookup_cached_pem/2, cache_pem_file/2, cache_pem_file/3,
lookup/2]).
@@ -51,16 +52,24 @@ create() ->
ets:new(ssl_otp_cacertificate_db, [set, public]),
%% Let connection processes call ref_count/3 directly
ets:new(ssl_otp_ca_file_ref, [set, public]),
- ets:new(ssl_otp_pem_cache, [set, protected])
+ ets:new(ssl_otp_pem_cache, [set, protected]),
+ %% Default cache
+ {ets:new(ssl_otp_crl_cache, [set, protected]),
+ ets:new(ssl_otp_crl_issuer_mapping, [bag, protected])}
].
%%--------------------------------------------------------------------
--spec remove([db_handle()]) -> ok.
+-spec remove([db_handle()]) -> ok.
%%
%% Description: Removes database db
%%--------------------------------------------------------------------
remove(Dbs) ->
- lists:foreach(fun(Db) ->
+ lists:foreach(fun({Db0, Db1}) ->
+ true = ets:delete(Db0),
+ true = ets:delete(Db1);
+ (undefined) ->
+ ok;
+ (Db) ->
true = ets:delete(Db)
end, Dbs).
@@ -81,7 +90,7 @@ lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) ->
{ok, Certs}
end.
-lookup_cached_pem([_, _, PemChache], File) ->
+lookup_cached_pem([_, _, PemChache | _], File) ->
lookup_cached_pem(PemChache, File);
lookup_cached_pem(PemChache, File) ->
lookup(File, PemChache).
@@ -94,12 +103,12 @@ lookup_cached_pem(PemChache, File) ->
%% runtime database. Returns Ref that should be handed to lookup_trusted_cert
%% together with the cert serialnumber and issuer.
%%--------------------------------------------------------------------
-add_trusted_certs(_Pid, {der, DerList}, [CerDb, _,_]) ->
+add_trusted_certs(_Pid, {der, DerList}, [CertDb, _,_ | _]) ->
NewRef = make_ref(),
- add_certs_from_der(DerList, NewRef, CerDb),
+ add_certs_from_der(DerList, NewRef, CertDb),
{ok, NewRef};
-add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache] = Db) ->
+add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache | _] = Db) ->
case lookup_cached_pem(Db, File) of
[{_Content, Ref}] ->
ref_count(Ref, RefDb, 1),
@@ -118,14 +127,15 @@ add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache] = Db) ->
%% Description: Cache file as binary in DB
%%--------------------------------------------------------------------
-spec cache_pem_file(binary(), [db_handle()]) -> {ok, term()}.
-cache_pem_file(File, [_CertsDb, _RefDb, PemChache]) ->
+cache_pem_file(File, [_CertsDb, _RefDb, PemChache | _]) ->
{ok, PemBin} = file:read_file(File),
Content = public_key:pem_decode(PemBin),
insert(File, Content, PemChache),
{ok, Content}.
+
-spec cache_pem_file(reference(), binary(), [db_handle()]) -> {ok, term()}.
-cache_pem_file(Ref, File, [_CertsDb, _RefDb, PemChache]) ->
+cache_pem_file(Ref, File, [_CertsDb, _RefDb, PemChache| _]) ->
{ok, PemBin} = file:read_file(File),
Content = public_key:pem_decode(PemBin),
insert(File, {Content, Ref}, PemChache),
@@ -149,6 +159,15 @@ remove(Key, Db) ->
ok.
%%--------------------------------------------------------------------
+-spec remove(term(), term(), db_handle()) -> ok.
+%%
+%% Description: Removes an element in a <Db>.
+%%--------------------------------------------------------------------
+remove(Key, Data, Db) ->
+ ets:delete_object(Db, {Key, Data}),
+ ok.
+
+%%--------------------------------------------------------------------
-spec lookup(term(), db_handle()) -> [term()] | undefined.
%%
%% Description: Looks up an element in a <Db>.
@@ -175,6 +194,10 @@ lookup(Key, Db) ->
foldl(Fun, Acc0, Cache) ->
ets:foldl(Fun, Acc0, Cache).
+
+select_cert_by_issuer(Cache, Issuer) ->
+ ets:select(Cache, [{{{'_','_', Issuer},{'_', '$1'}},[],['$$']}]).
+
%%--------------------------------------------------------------------
-spec ref_count(term(), db_handle(), integer()) -> integer().
%%
@@ -244,9 +267,39 @@ add_certs(Cert, Ref, CertsDb) ->
error_logger:info_report(Report)
end.
-new_trusted_cert_entry(File, [CertsDb, RefDb, _] = Db) ->
+new_trusted_cert_entry(File, [CertsDb, RefDb, _ | _] = Db) ->
Ref = make_ref(),
update_counter(Ref, 1, RefDb),
{ok, Content} = cache_pem_file(Ref, File, Db),
add_certs_from_pem(Content, Ref, CertsDb),
{ok, Ref}.
+
+add_crls([_,_,_, {_, Mapping} | _], ?NO_DIST_POINT, CRLs) ->
+ [add_crls(CRL, Mapping) || CRL <- CRLs];
+add_crls([_,_,_, {Cache, Mapping} | _], Path, CRLs) ->
+ insert(Path, CRLs, Cache),
+ [add_crls(CRL, Mapping) || CRL <- CRLs].
+
+add_crls(CRL, Mapping) ->
+ insert(crl_issuer(CRL), CRL, Mapping).
+
+remove_crls([_,_,_, {_, Mapping} | _], {?NO_DIST_POINT, CRLs}) ->
+ [rm_crls(CRL, Mapping) || CRL <- CRLs];
+
+remove_crls([_,_,_, {Cache, Mapping} | _], Path) ->
+ case lookup(Path, Cache) of
+ undefined ->
+ ok;
+ CRLs ->
+ remove(Path, Cache),
+ [rm_crls(CRL, Mapping) || CRL <- CRLs]
+ end.
+
+rm_crls(CRL, Mapping) ->
+ remove(crl_issuer(CRL), CRL, Mapping).
+
+crl_issuer(DerCRL) ->
+ CRL = public_key:der_decode('CertificateList', DerCRL),
+ TBSCRL = CRL#'CertificateList'.tbsCertList,
+ TBSCRL#'TBSCertList'.issuer.
+
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 025a46bf65..ce6b8fb84f 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -48,7 +49,8 @@
-export([compress/3, uncompress/3, compressions/0]).
%% Payload encryption/decryption
--export([cipher/4, decipher/4, is_correct_mac/2]).
+-export([cipher/4, decipher/4, is_correct_mac/2,
+ cipher_aead/4, decipher_aead/4]).
-export_type([ssl_version/0, ssl_atom_version/0]).
@@ -309,9 +311,19 @@ set_pending_cipher_state(#connection_states{pending_read = Read,
%%
%% Description: Encodes a handshake message to send on the ssl-socket.
%%--------------------------------------------------------------------
-encode_handshake(Frag, Version, ConnectionStates) ->
- encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates).
-
+encode_handshake(Frag, Version,
+ #connection_states{current_write =
+ #connection_state{
+ security_parameters =
+ #security_parameters{bulk_cipher_algorithm = BCA}}} =
+ ConnectionStates) ->
+ case iolist_size(Frag) of
+ N when N > ?MAX_PLAIN_TEXT_LENGTH ->
+ Data = split_bin(iolist_to_binary(Frag), ?MAX_PLAIN_TEXT_LENGTH, Version, BCA),
+ encode_iolist(?HANDSHAKE, Data, Version, ConnectionStates);
+ _ ->
+ encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates)
+ end.
%%--------------------------------------------------------------------
-spec encode_alert_record(#alert{}, ssl_version(), #connection_states{}) ->
{iolist(), #connection_states{}}.
@@ -376,6 +388,23 @@ cipher(Version, Fragment,
{CipherFragment, CipherS1} =
ssl_cipher:cipher(BulkCipherAlgo, CipherS0, MacHash, Fragment, Version),
{CipherFragment, WriteState0#connection_state{cipher_state = CipherS1}}.
+%%--------------------------------------------------------------------
+-spec cipher_aead(ssl_version(), iodata(), #connection_state{}, MacHash::binary()) ->
+ {CipherFragment::binary(), #connection_state{}}.
+%%
+%% Description: Payload encryption
+%%--------------------------------------------------------------------
+cipher_aead(Version, Fragment,
+ #connection_state{cipher_state = CipherS0,
+ sequence_number = SeqNo,
+ security_parameters=
+ #security_parameters{bulk_cipher_algorithm =
+ BulkCipherAlgo}
+ } = WriteState0, AAD) ->
+
+ {CipherFragment, CipherS1} =
+ ssl_cipher:cipher_aead(BulkCipherAlgo, CipherS0, SeqNo, AAD, Fragment, Version),
+ {CipherFragment, WriteState0#connection_state{cipher_state = CipherS1}}.
%%--------------------------------------------------------------------
-spec decipher(ssl_version(), binary(), #connection_state{}, boolean()) -> {binary(), binary(), #connection_state{}} | #alert{}.
@@ -397,6 +426,25 @@ decipher(Version, CipherFragment,
Alert
end.
%%--------------------------------------------------------------------
+-spec decipher_aead(ssl_version(), binary(), #connection_state{}, binary()) -> {binary(), binary(), #connection_state{}} | #alert{}.
+%%
+%% Description: Payload decryption
+%%--------------------------------------------------------------------
+decipher_aead(Version, CipherFragment,
+ #connection_state{sequence_number = SeqNo,
+ security_parameters =
+ #security_parameters{bulk_cipher_algorithm =
+ BulkCipherAlgo},
+ cipher_state = CipherS0
+ } = ReadState, AAD) ->
+ case ssl_cipher:decipher_aead(BulkCipherAlgo, CipherS0, SeqNo, AAD, CipherFragment, Version) of
+ {PlainFragment, CipherS1} ->
+ CS1 = ReadState#connection_state{cipher_state = CipherS1},
+ {PlainFragment, CS1};
+ #alert{} = Alert ->
+ Alert
+ end.
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
empty_connection_state(ConnectionEnd) ->
diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl
index 6aab35d6da..af77378f44 100644
--- a/lib/ssl/src/ssl_record.hrl
+++ b/lib/ssl/src/ssl_record.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -90,11 +91,14 @@
-define('3DES', 4).
-define(DES40, 5).
-define(IDEA, 6).
--define(AES, 7).
+-define(AES_CBC, 7).
+-define(AES_GCM, 8).
+-define(CHACHA20_POLY1305, 9).
%% CipherType
-define(STREAM, 0).
-define(BLOCK, 1).
+-define(AEAD, 2).
%% IsExportable
%-define(TRUE, 0). %% Already defined by ssl_internal.hrl
diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl
index a24b2d9444..2b24bff5ff 100644
--- a/lib/ssl/src/ssl_session.erl
+++ b/lib/ssl/src/ssl_session.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -30,8 +31,6 @@
%% Internal application API
-export([is_new/2, client_id/4, server_id/6, valid_session/2]).
--define('24H_in_sec', 8640).
-
-type seconds() :: integer().
%%--------------------------------------------------------------------
@@ -62,13 +61,16 @@ client_id(ClientInfo, Cache, CacheCb, OwnCert) ->
SessionId
end.
--spec valid_session(#session{}, seconds()) -> boolean().
+-spec valid_session(#session{}, seconds() | {invalidate_before, integer()}) -> boolean().
%%
%% Description: Check that the session has not expired
%%--------------------------------------------------------------------
+valid_session(#session{time_stamp = TimeStamp}, {invalidate_before, Before}) ->
+ TimeStamp > Before;
valid_session(#session{time_stamp = TimeStamp}, LifeTime) ->
- Now = calendar:datetime_to_gregorian_seconds({date(), time()}),
- Now - TimeStamp < LifeTime.
+ Now = erlang:monotonic_time(),
+ Lived = erlang:convert_time_unit(Now-TimeStamp, native, seconds),
+ Lived < LifeTime.
server_id(Port, <<>>, _SslOpts, _Cert, _, _) ->
{ssl_manager:new_session_id(Port), undefined};
@@ -99,14 +101,14 @@ select_session([], _, _) ->
no_session;
select_session(Sessions, #ssl_options{ciphers = Ciphers}, OwnCert) ->
IsNotResumable =
- fun([_Id, Session]) ->
+ fun(Session) ->
not (resumable(Session#session.is_resumable) andalso
lists:member(Session#session.cipher_suite, Ciphers)
andalso (OwnCert == Session#session.own_certificate))
end,
case lists:dropwhile(IsNotResumable, Sessions) of
[] -> no_session;
- [[Id, _]|_] -> Id
+ [Session | _] -> Session#session.session_id
end.
is_resumable(_, _, #ssl_options{reuse_sessions = false}, _, _, _, _) ->
diff --git a/lib/ssl/src/ssl_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl
index 5c6ee3c54c..9585e613e6 100644
--- a/lib/ssl/src/ssl_session_cache.erl
+++ b/lib/ssl/src/ssl_session_cache.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,13 +27,13 @@
-include("ssl_internal.hrl").
-export([init/1, terminate/1, lookup/2, update/3, delete/2, foldl/3,
- select_session/2]).
+ select_session/2, size/1]).
%%--------------------------------------------------------------------
%% Description: Return table reference. Called by ssl_manager process.
%%--------------------------------------------------------------------
-init(_) ->
- ets:new(cache_name(), [ordered_set, protected]).
+init(Options) ->
+ ets:new(cache_name(proplists:get_value(role, Options)), [ordered_set, protected]).
%%--------------------------------------------------------------------
%% Description: Handles cache table at termination of ssl manager.
@@ -82,10 +83,16 @@ foldl(Fun, Acc0, Cache) ->
%%--------------------------------------------------------------------
select_session(Cache, PartialKey) ->
ets:select(Cache,
- [{{{PartialKey,'$1'}, '$2'},[],['$$']}]).
+ [{{{PartialKey,'_'}, '$1'},[],['$1']}]).
+
+%%--------------------------------------------------------------------
+%% Description: Returns the cache size
+%%--------------------------------------------------------------------
+size(Cache) ->
+ ets:info(Cache, size).
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-cache_name() ->
- ssl_otp_session_cache.
+cache_name(Name) ->
+ list_to_atom(atom_to_list(Name) ++ "_ssl_otp_session_cache").
diff --git a/lib/ssl/src/ssl_session_cache_api.erl b/lib/ssl/src/ssl_session_cache_api.erl
index f2b22b0f1b..8f62c25be5 100644
--- a/lib/ssl/src/ssl_session_cache_api.erl
+++ b/lib/ssl/src/ssl_session_cache_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -32,3 +33,4 @@
-callback delete(db_handle(), key()) -> any().
-callback foldl(fun(), term(), db_handle()) -> term().
-callback select_session(db_handle(), {host(), inet:port_number()} | inet:port_number()) -> [#session{}].
+-callback size(db_handle()) -> integer().
diff --git a/lib/ssl/src/ssl_socket.erl b/lib/ssl/src/ssl_socket.erl
index 55eb569b20..a5487bfb5c 100644
--- a/lib/ssl/src/ssl_socket.erl
+++ b/lib/ssl/src/ssl_socket.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssl/src/ssl_srp.hrl b/lib/ssl/src/ssl_srp.hrl
index af56a91194..f543866085 100644
--- a/lib/ssl/src/ssl_srp.hrl
+++ b/lib/ssl/src/ssl_srp.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/ssl_sup.erl b/lib/ssl/src/ssl_sup.erl
index 7cccf8d5a5..950a6e0944 100644
--- a/lib/ssl/src/ssl_sup.erl
+++ b/lib/ssl/src/ssl_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssl/src/ssl_tls_dist_proxy.erl b/lib/ssl/src/ssl_tls_dist_proxy.erl
index a22af6b960..4c789793ec 100644
--- a/lib/ssl/src/ssl_tls_dist_proxy.erl
+++ b/lib/ssl/src/ssl_tls_dist_proxy.erl
@@ -3,23 +3,24 @@
%%
%% Copyright Ericsson AB 2011-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(ssl_tls_dist_proxy).
--export([listen/1, accept/1, connect/2, get_tcp_address/1]).
+-export([listen/2, accept/2, connect/3, get_tcp_address/1]).
-export([init/1, start_link/0, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3, ssl_options/2]).
@@ -38,14 +39,63 @@
%% Internal application API
%%====================================================================
-listen(Name) ->
- gen_server:call(?MODULE, {listen, Name}, infinity).
+listen(Driver, Name) ->
+ gen_server:call(?MODULE, {listen, Driver, Name}, infinity).
+
+accept(Driver, Listen) ->
+ gen_server:call(?MODULE, {accept, Driver, Listen}, infinity).
+
+connect(Driver, Ip, Port) ->
+ gen_server:call(?MODULE, {connect, Driver, Ip, Port}, infinity).
+
+
+do_listen(Options) ->
+ {First,Last} = case application:get_env(kernel,inet_dist_listen_min) of
+ {ok,N} when is_integer(N) ->
+ case application:get_env(kernel,
+ inet_dist_listen_max) of
+ {ok,M} when is_integer(M) ->
+ {N,M};
+ _ ->
+ {N,N}
+ end;
+ _ ->
+ {0,0}
+ end,
+ do_listen(First, Last, listen_options([{backlog,128}|Options])).
+
+do_listen(First,Last,_) when First > Last ->
+ {error,eaddrinuse};
+do_listen(First,Last,Options) ->
+ case gen_tcp:listen(First, Options) of
+ {error, eaddrinuse} ->
+ do_listen(First+1,Last,Options);
+ Other ->
+ Other
+ end.
-accept(Listen) ->
- gen_server:call(?MODULE, {accept, Listen}, infinity).
+listen_options(Opts0) ->
+ Opts1 =
+ case application:get_env(kernel, inet_dist_use_interface) of
+ {ok, Ip} ->
+ [{ip, Ip} | Opts0];
+ _ ->
+ Opts0
+ end,
+ case application:get_env(kernel, inet_dist_listen_options) of
+ {ok,ListenOpts} ->
+ ListenOpts ++ Opts1;
+ _ ->
+ Opts1
+ end.
-connect(Ip, Port) ->
- gen_server:call(?MODULE, {connect, Ip, Port}, infinity).
+connect_options(Opts) ->
+ case application:get_env(kernel, inet_dist_connect_options) of
+ {ok,ConnectOpts} ->
+ lists:ukeysort(1, ConnectOpts ++ Opts);
+ _ ->
+ Opts
+ end.
%%====================================================================
%% gen_server callbacks
@@ -58,29 +108,34 @@ init([]) ->
process_flag(priority, max),
{ok, #state{}}.
-handle_call({listen, Name}, _From, State) ->
- case gen_tcp:listen(0, [{active, false}, {packet,?PPRE}]) of
+handle_call({listen, Driver, Name}, _From, State) ->
+ case gen_tcp:listen(0, [{active, false}, {packet,?PPRE}, {ip, loopback}]) of
{ok, Socket} ->
- {ok, World} = gen_tcp:listen(0, [{active, false}, binary, {packet,?PPRE}]),
+ {ok, World} = do_listen([{active, false}, binary, {packet,?PPRE}, {reuseaddr, true},
+ Driver:family()]),
{ok, TcpAddress} = get_tcp_address(Socket),
{ok, WorldTcpAddress} = get_tcp_address(World),
{_,Port} = WorldTcpAddress#net_address.address,
- {ok, Creation} = erl_epmd:register_node(Name, Port),
- {reply, {ok, {Socket, TcpAddress, Creation}},
- State#state{listen={Socket, World}}};
+ case erl_epmd:register_node(Name, Port) of
+ {ok, Creation} ->
+ {reply, {ok, {Socket, TcpAddress, Creation}},
+ State#state{listen={Socket, World}}};
+ {error, _} = Error ->
+ {reply, Error, State}
+ end;
Error ->
{reply, Error, State}
end;
-handle_call({accept, Listen}, {From, _}, State = #state{listen={_, World}}) ->
+handle_call({accept, _Driver, Listen}, {From, _}, State = #state{listen={_, World}}) ->
Self = self(),
ErtsPid = spawn_link(fun() -> accept_loop(Self, erts, Listen, From) end),
WorldPid = spawn_link(fun() -> accept_loop(Self, world, World, Listen) end),
{reply, ErtsPid, State#state{accept_loop={ErtsPid, WorldPid}}};
-handle_call({connect, Ip, Port}, {From, _}, State) ->
+handle_call({connect, Driver, Ip, Port}, {From, _}, State) ->
Me = self(),
- Pid = spawn_link(fun() -> setup_proxy(Ip, Port, Me) end),
+ Pid = spawn_link(fun() -> setup_proxy(Driver, Ip, Port, Me) end),
receive
{Pid, go_ahead, LPort} ->
Res = {ok, Socket} = try_connect(LPort),
@@ -133,6 +188,7 @@ accept_loop(Proxy, erts = Type, Listen, Extra) ->
Extra ! {accept,self(),Socket,inet,proxy},
receive
{_Kernel, controller, Pid} ->
+ inet:setopts(Socket, [nodelay()]),
ok = gen_tcp:controlling_process(Socket, Pid),
flush_old_controller(Pid, Socket),
Pid ! {self(), controller};
@@ -149,6 +205,7 @@ accept_loop(Proxy, world = Type, Listen, Extra) ->
case gen_tcp:accept(Listen) of
{ok, Socket} ->
Opts = get_ssl_options(server),
+ wait_for_code_server(),
case ssl:ssl_accept(Socket, Opts) of
{ok, SslSocket} ->
PairHandler =
@@ -157,6 +214,11 @@ accept_loop(Proxy, world = Type, Listen, Extra) ->
end),
ok = ssl:controlling_process(SslSocket, PairHandler),
flush_old_controller(PairHandler, SslSocket);
+ {error, {options, _}} = Error ->
+ %% Bad options: that's probably our fault. Let's log that.
+ error_logger:error_msg("Cannot accept TLS distribution connection: ~s~n",
+ [ssl:format_error(Error)]),
+ gen_tcp:close(Socket);
_ ->
gen_tcp:close(Socket)
end;
@@ -165,20 +227,50 @@ accept_loop(Proxy, world = Type, Listen, Extra) ->
end,
accept_loop(Proxy, Type, Listen, Extra).
+wait_for_code_server() ->
+ %% This is an ugly hack. Upgrading a socket to TLS requires the
+ %% crypto module to be loaded. Loading the crypto module triggers
+ %% its on_load function, which calls code:priv_dir/1 to find the
+ %% directory where its NIF library is. However, distribution is
+ %% started earlier than the code server, so the code server is not
+ %% necessarily started yet, and code:priv_dir/1 might fail because
+ %% of that, if we receive an incoming connection on the
+ %% distribution port early enough.
+ %%
+ %% If the on_load function of a module fails, the module is
+ %% unloaded, and the function call that triggered loading it fails
+ %% with 'undef', which is rather confusing.
+ %%
+ %% Thus, the ssl_tls_dist_proxy process will terminate, and be
+ %% restarted by ssl_dist_sup. However, it won't have any memory
+ %% of being asked by net_kernel to listen for incoming
+ %% connections. Hence, the node will believe that it's open for
+ %% distribution, but it actually isn't.
+ %%
+ %% So let's avoid that by waiting for the code server to start.
+ case whereis(code_server) of
+ undefined ->
+ timer:sleep(10),
+ wait_for_code_server();
+ Pid when is_pid(Pid) ->
+ ok
+ end.
+
try_connect(Port) ->
- case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {packet,?PPRE}]) of
+ case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {packet,?PPRE}, nodelay()]) of
R = {ok, _S} ->
R;
{error, _R} ->
try_connect(Port)
end.
-setup_proxy(Ip, Port, Parent) ->
+setup_proxy(Driver, Ip, Port, Parent) ->
process_flag(trap_exit, true),
- Opts = get_ssl_options(client),
- case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}] ++ Opts) of
+ Opts = connect_options(get_ssl_options(client)),
+ case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}, nodelay(),
+ Driver:family()] ++ Opts) of
{ok, World} ->
- {ok, ErtsL} = gen_tcp:listen(0, [{active, true}, {ip, {127,0,0,1}}, binary, {packet,?PPRE}]),
+ {ok, ErtsL} = gen_tcp:listen(0, [{active, true}, {ip, loopback}, binary, {packet,?PPRE}]),
{ok, #net_address{address={_,LPort}}} = get_tcp_address(ErtsL),
Parent ! {self(), go_ahead, LPort},
case gen_tcp:accept(ErtsL) of
@@ -188,29 +280,50 @@ setup_proxy(Ip, Port, Parent) ->
Err ->
Parent ! {self(), Err}
end;
+ {error, {options, _}} = Err ->
+ %% Bad options: that's probably our fault. Let's log that.
+ error_logger:error_msg("Cannot open TLS distribution connection: ~s~n",
+ [ssl:format_error(Err)]),
+ Parent ! {self(), Err};
Err ->
Parent ! {self(), Err}
end.
+
+%% we may not always want the nodelay behaviour
+%% %% for performance reasons
+
+nodelay() ->
+ case application:get_env(kernel, dist_nodelay) of
+ undefined ->
+ {nodelay, true};
+ {ok, true} ->
+ {nodelay, true};
+ {ok, false} ->
+ {nodelay, false};
+ _ ->
+ {nodelay, true}
+ end.
+
setup_connection(World, ErtsListen) ->
process_flag(trap_exit, true),
{ok, TcpAddress} = get_tcp_address(ErtsListen),
{_Addr,Port} = TcpAddress#net_address.address,
- {ok, Erts} = gen_tcp:connect({127,0,0,1}, Port, [{active, true}, binary, {packet,?PPRE}]),
- ssl:setopts(World, [{active,true}, {packet,?PPRE}]),
+ {ok, Erts} = gen_tcp:connect({127,0,0,1}, Port, [{active, true}, binary, {packet,?PPRE}, nodelay()]),
+ ssl:setopts(World, [{active,true}, {packet,?PPRE}, nodelay()]),
loop_conn_setup(World, Erts).
loop_conn_setup(World, Erts) ->
receive
{ssl, World, Data = <<$a, _/binary>>} ->
gen_tcp:send(Erts, Data),
- ssl:setopts(World, [{packet,?PPOST}]),
- inet:setopts(Erts, [{packet,?PPOST}]),
+ ssl:setopts(World, [{packet,?PPOST}, nodelay()]),
+ inet:setopts(Erts, [{packet,?PPOST}, nodelay()]),
loop_conn(World, Erts);
{tcp, Erts, Data = <<$a, _/binary>>} ->
ssl:send(World, Data),
- ssl:setopts(World, [{packet,?PPOST}]),
- inet:setopts(Erts, [{packet,?PPOST}]),
+ ssl:setopts(World, [{packet,?PPOST}, nodelay()]),
+ inet:setopts(Erts, [{packet,?PPOST}, nodelay()]),
loop_conn(World, Erts);
{ssl, World, Data = <<_, _/binary>>} ->
gen_tcp:send(Erts, Data),
@@ -227,7 +340,10 @@ loop_conn_setup(World, Erts) ->
{tcp_closed, Erts} ->
ssl:close(World);
{ssl_closed, World} ->
- gen_tcp:close(Erts)
+ gen_tcp:close(Erts);
+ {ssl_error, World, _} ->
+
+ ssl:close(World)
end.
loop_conn(World, Erts) ->
@@ -241,7 +357,9 @@ loop_conn(World, Erts) ->
{tcp_closed, Erts} ->
ssl:close(World);
{ssl_closed, World} ->
- gen_tcp:close(Erts)
+ gen_tcp:close(Erts);
+ {ssl_error, World, _} ->
+ ssl:close(World)
end.
get_ssl_options(Type) ->
diff --git a/lib/ssl/src/ssl_v2.erl b/lib/ssl/src/ssl_v2.erl
index 07876366f1..1764da5c63 100644
--- a/lib/ssl/src/ssl_v2.erl
+++ b/lib/ssl/src/ssl_v2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/ssl_v3.erl b/lib/ssl/src/ssl_v3.erl
index 68f7f5dee2..f169059a75 100644
--- a/lib/ssl/src/ssl_v3.erl
+++ b/lib/ssl/src/ssl_v3.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -143,9 +144,7 @@ suites() ->
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
- %%?TLS_RSA_WITH_IDEA_CBC_SHA,
- ?TLS_RSA_WITH_RC4_128_SHA,
- ?TLS_RSA_WITH_RC4_128_MD5,
+ ?TLS_DHE_RSA_WITH_DES_CBC_SHA,
?TLS_RSA_WITH_DES_CBC_SHA
].
diff --git a/lib/ssl/src/tls.erl b/lib/ssl/src/tls.erl
index c829129250..d4cb8788bf 100644
--- a/lib/ssl/src/tls.erl
+++ b/lib/ssl/src/tls.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 77d3aa7889..93716d31b8 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -53,7 +54,7 @@
%% Alert and close handling
-export([send_alert/2, handle_own_alert/4, handle_close_alert/3,
handle_normal_shutdown/3, handle_unexpected_message/3,
- workaround_transport_delivery_problems/2, alert_user/6, alert_user/9
+ close/5, alert_user/6, alert_user/9
]).
%% Data handling
@@ -167,9 +168,10 @@ hello(start, #state{host = Host, port = Port, role = client,
Cache, CacheCb, Renegotiation, Cert),
Version = Hello#client_hello.client_version,
+ HelloVersion = tls_record:lowest_protocol_version(SslOpts#ssl_options.versions),
Handshake0 = ssl_handshake:init_handshake_history(),
{BinMsg, ConnectionStates, Handshake} =
- encode_handshake(Hello, Version, ConnectionStates0, Handshake0),
+ encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0),
Transport:send(Socket, BinMsg),
State1 = State0#state{connection_states = ConnectionStates,
negotiated_version = Version, %% Requested version
@@ -180,29 +182,37 @@ hello(start, #state{host = Host, port = Port, role = client,
next_state(hello, hello, Record, State);
hello(Hello = #client_hello{client_version = ClientVersion,
- extensions = #hello_extensions{hash_signs = HashSigns,
- ec_point_formats = EcPointFormats,
+ extensions = #hello_extensions{ec_point_formats = EcPointFormats,
elliptic_curves = EllipticCurves}},
State = #state{connection_states = ConnectionStates0,
port = Port, session = #session{own_certificate = Cert} = Session0,
renegotiation = {Renegotiation, _},
session_cache = Cache,
session_cache_cb = CacheCb,
+ negotiated_protocol = CurrentProtocol,
+ key_algorithm = KeyExAlg,
ssl_options = SslOpts}) ->
+
case tls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
- ConnectionStates0, Cert}, Renegotiation) of
+ ConnectionStates0, Cert, KeyExAlg}, Renegotiation) of
+ #alert{} = Alert ->
+ handle_own_alert(Alert, ClientVersion, hello, State);
{Version, {Type, Session},
- ConnectionStates, ServerHelloExt} ->
- HashSign = ssl_handshake:select_hashsign(HashSigns, Cert, Version),
- ssl_connection:hello({common_client_hello, Type, ServerHelloExt, HashSign},
+ ConnectionStates, Protocol0, ServerHelloExt, HashSign} ->
+ Protocol = case Protocol0 of
+ undefined -> CurrentProtocol;
+ _ -> Protocol0
+ end,
+ ssl_connection:hello({common_client_hello, Type, ServerHelloExt},
State#state{connection_states = ConnectionStates,
negotiated_version = Version,
+ hashsign_algorithm = HashSign,
session = Session,
- client_ecc = {EllipticCurves, EcPointFormats}}, ?MODULE);
- #alert{} = Alert ->
- handle_own_alert(Alert, ClientVersion, hello, State)
+ client_ecc = {EllipticCurves, EcPointFormats},
+ negotiated_protocol = Protocol}, ?MODULE)
end;
-hello(Hello,
+
+hello(Hello = #server_hello{},
#state{connection_states = ConnectionStates0,
negotiated_version = ReqVersion,
role = client,
@@ -211,9 +221,9 @@ hello(Hello,
case tls_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
handle_own_alert(Alert, ReqVersion, hello, State);
- {Version, NewId, ConnectionStates, NextProtocol} ->
+ {Version, NewId, ConnectionStates, ProtoExt, Protocol} ->
ssl_connection:handle_session(Hello,
- Version, NewId, ConnectionStates, NextProtocol, State)
+ Version, NewId, ConnectionStates, ProtoExt, Protocol, State)
end;
hello(Msg, State) ->
@@ -384,12 +394,30 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions, Tracker}, Us
user_data_buffer = <<>>,
session_cache_cb = SessionCacheCb,
renegotiation = {false, first},
+ allow_renegotiate = SSLOptions#ssl_options.client_renegotiation,
start_or_recv_from = undefined,
send_queue = queue:new(),
protocol_cb = ?MODULE,
tracker = Tracker
}.
+
+update_ssl_options_from_sni(OrigSSLOptions, SNIHostname) ->
+ SSLOption =
+ case OrigSSLOptions#ssl_options.sni_fun of
+ undefined ->
+ proplists:get_value(SNIHostname,
+ OrigSSLOptions#ssl_options.sni_hosts);
+ SNIFun ->
+ SNIFun(SNIHostname)
+ end,
+ case SSLOption of
+ undefined ->
+ undefined;
+ _ ->
+ ssl:handle_options(SSLOption, OrigSSLOptions)
+ end.
+
next_state(Current,_, #alert{} = Alert, #state{negotiated_version = Version} = State) ->
handle_own_alert(Alert, Version, Current, State);
@@ -418,15 +446,17 @@ next_state(Current, Next, #ssl_tls{type = ?HANDSHAKE, fragment = Data},
%% This message should not be included in handshake
%% message hashes. Already in negotiation so it will be ignored!
?MODULE:SName(Packet, State);
- ({#client_hello{} = Packet, Raw}, {next_state, connection = SName, State}) ->
+ ({#client_hello{} = Packet, Raw}, {next_state, connection = SName, HState0}) ->
+ HState = handle_sni_extension(Packet, HState0),
Version = Packet#client_hello.client_version,
Hs0 = ssl_handshake:init_handshake_history(),
Hs1 = ssl_handshake:update_handshake_history(Hs0, Raw),
- ?MODULE:SName(Packet, State#state{tls_handshake_history=Hs1,
- renegotiation = {true, peer}});
- ({Packet, Raw}, {next_state, SName, State = #state{tls_handshake_history=Hs0}}) ->
+ ?MODULE:SName(Packet, HState#state{tls_handshake_history=Hs1,
+ renegotiation = {true, peer}});
+ ({Packet, Raw}, {next_state, SName, HState0 = #state{tls_handshake_history=Hs0}}) ->
+ HState = handle_sni_extension(Packet, HState0),
Hs1 = ssl_handshake:update_handshake_history(Hs0, Raw),
- ?MODULE:SName(Packet, State#state{tls_handshake_history=Hs1});
+ ?MODULE:SName(Packet, HState#state{tls_handshake_history=Hs1});
(_, StopState) -> StopState
end,
try
@@ -734,6 +764,8 @@ handle_tls_handshake(Handle, StateName,
case Handle(Packet, FsmReturn) of
{next_state, NextStateName, State, _Timeout} ->
handle_tls_handshake(Handle, NextStateName, State);
+ {next_state, NextStateName, State} ->
+ handle_tls_handshake(Handle, NextStateName, State);
{stop, _,_} = Stop ->
Stop
end;
@@ -895,8 +927,7 @@ handle_own_alert(Alert, Version, StateName,
try %% Try to tell the other side
{BinMsg, _} =
ssl_alert:encode(Alert, Version, ConnectionStates),
- Transport:send(Socket, BinMsg),
- workaround_transport_delivery_problems(Socket, Transport)
+ Transport:send(Socket, BinMsg)
catch _:_ -> %% Can crash if we are in a uninitialized state
ignore
end,
@@ -948,21 +979,57 @@ invalidate_session(client, Host, Port, Session) ->
invalidate_session(server, _, Port, Session) ->
ssl_manager:invalidate_session(Port, Session).
-workaround_transport_delivery_problems(Socket, gen_tcp = Transport) ->
+%% User downgrades connection
+%% When downgrading an TLS connection to a transport connection
+%% we must recive the close message before releasing the
+%% transport socket.
+close({close, {Pid, Timeout}}, Socket, Transport, ConnectionStates, Check) when is_pid(Pid) ->
+ ssl_socket:setopts(Transport, Socket, [{active, false}, {packet, ssl_tls}]),
+ case Transport:recv(Socket, 0, Timeout) of
+ {ok, {ssl_tls, Socket, ?ALERT, Version, Fragment}} ->
+ case tls_record:decode_cipher_text(#ssl_tls{type = ?ALERT,
+ version = Version,
+ fragment = Fragment
+ }, ConnectionStates, Check) of
+ {#ssl_tls{fragment = Plain}, _} ->
+ [Alert| _] = decode_alerts(Plain),
+ downgrade(Alert, Transport, Socket, Pid)
+ end;
+ {error, timeout} ->
+ {error, timeout};
+ _ ->
+ {error, no_tls_close}
+ end;
+%% User closes or recursive call!
+close({close, Timeout}, Socket, Transport = gen_tcp, _,_) ->
+ ssl_socket:setopts(Transport, Socket, [{active, false}]),
+ Transport:shutdown(Socket, write),
+ _ = Transport:recv(Socket, 0, Timeout),
+ ok;
+%% Peer closed socket
+close({shutdown, transport_closed}, Socket, Transport = gen_tcp, ConnectionStates, Check) ->
+ close({close, 0}, Socket, Transport, ConnectionStates, Check);
+%% We generate fatal alert
+close({shutdown, own_alert}, Socket, Transport = gen_tcp, ConnectionStates, Check) ->
%% Standard trick to try to make sure all
%% data sent to the tcp port is really delivered to the
%% peer application before tcp port is closed so that the peer will
%% get the correct TLS alert message and not only a transport close.
- ssl_socket:setopts(Transport, Socket, [{active, false}]),
- Transport:shutdown(Socket, write),
- %% Will return when other side has closed or after 30 s
+ %% Will return when other side has closed or after timout millisec
%% e.g. we do not want to hang if something goes wrong
%% with the network but we want to maximise the odds that
%% peer application gets all data sent on the tcp connection.
- Transport:recv(Socket, 0, 30000);
-workaround_transport_delivery_problems(Socket, Transport) ->
+ close({close, ?DEFAULT_TIMEOUT}, Socket, Transport, ConnectionStates, Check);
+%% Other
+close(_, Socket, Transport, _,_) ->
Transport:close(Socket).
-
+downgrade(#alert{description = ?CLOSE_NOTIFY}, Transport, Socket, Pid) ->
+ ssl_socket:setopts(Transport, Socket, [{active, false}, {packet, 0}, {mode, binary}]),
+ Transport:controlling_process(Socket, Pid),
+ {ok, Socket};
+downgrade(_, _,_,_) ->
+ {error, no_tls_close}.
+
convert_state(#state{ssl_options = Options} = State, up, "5.3.5", "5.3.6") ->
State#state{ssl_options = convert_options_partial_chain(Options, up)};
convert_state(#state{ssl_options = Options} = State, down, "5.3.6", "5.3.5") ->
@@ -973,3 +1040,33 @@ convert_options_partial_chain(Options, up) ->
list_to_tuple(Head ++ [{partial_chain, fun(_) -> unknown_ca end}] ++ Tail);
convert_options_partial_chain(Options, down) ->
list_to_tuple(proplists:delete(partial_chain, tuple_to_list(Options))).
+
+handle_sni_extension(#client_hello{extensions = HelloExtensions}, State0) ->
+ case HelloExtensions#hello_extensions.sni of
+ undefined ->
+ State0;
+ #sni{hostname = Hostname} ->
+ NewOptions = update_ssl_options_from_sni(State0#state.ssl_options, Hostname),
+ case NewOptions of
+ undefined ->
+ State0;
+ _ ->
+ {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbHandle, OwnCert, Key, DHParams} =
+ ssl_config:init(NewOptions, State0#state.role),
+ State0#state{
+ session = State0#state.session#session{own_certificate = OwnCert},
+ file_ref_db = FileRefHandle,
+ cert_db_ref = Ref,
+ cert_db = CertDbHandle,
+ crl_db = CRLDbHandle,
+ session_cache = CacheHandle,
+ private_key = Key,
+ diffie_hellman_params = DHParams,
+ ssl_options = NewOptions,
+ sni_hostname = Hostname
+ }
+ end
+ end;
+handle_sni_extension(_, State0) ->
+ State0.
+
diff --git a/lib/ssl/src/tls_connection.hrl b/lib/ssl/src/tls_connection.hrl
index 2beecbb84d..3a416401d8 100644
--- a/lib/ssl/src/tls_connection.hrl
+++ b/lib/ssl/src/tls_connection.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/tls_connection_sup.erl b/lib/ssl/src/tls_connection_sup.erl
index 7a637c212a..34579a8803 100644
--- a/lib/ssl/src/tls_connection_sup.erl
+++ b/lib/ssl/src/tls_connection_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl
index b0b6d5a8e3..f34eebb0e4 100644
--- a/lib/ssl/src/tls_handshake.erl
+++ b/lib/ssl/src/tls_handshake.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -55,7 +56,7 @@ client_hello(Host, Port, ConnectionStates,
Version = tls_record:highest_protocol_version(Versions),
Pending = ssl_record:pending_connection_state(ConnectionStates, read),
SecParams = Pending#connection_state.security_parameters,
- AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version),
+ AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version),
Extensions = ssl_handshake:client_hello_extensions(Host, Version,
AvailableCipherSuites,
SslOpts, ConnectionStates, Renegotiation),
@@ -78,12 +79,14 @@ client_hello(Host, Port, ConnectionStates,
%%--------------------------------------------------------------------
-spec hello(#server_hello{} | #client_hello{}, #ssl_options{},
#connection_states{} | {inet:port_number(), #session{}, db_handle(),
- atom(), #connection_states{}, binary() | undefined},
+ atom(), #connection_states{},
+ binary() | undefined, ssl_cipher:key_algo()},
boolean()) ->
- {tls_record:tls_version(), session_id(), #connection_states{}, binary() | undefined}|
- {tls_record:tls_version(), {resumed | new, #session{}}, #connection_states{},
- [binary()] | undefined,
- [ssl_handshake:oid()] | undefined, [ssl_handshake:oid()] | undefined} |
+ {tls_record:tls_version(), session_id(),
+ #connection_states{}, alpn | npn, binary() | undefined}|
+ {tls_record:tls_version(), {resumed | new, #session{}},
+ #connection_states{}, binary() | undefined,
+ #hello_extensions{}, {ssl_cipher:hash(), ssl_cipher:sign_algo()} | undefined} |
#alert{}.
%%
%% Description: Handles a recieved hello message
@@ -146,26 +149,35 @@ get_tls_handshake(Version, Data, Buffer) ->
%%% Internal functions
%%--------------------------------------------------------------------
handle_client_hello(Version, #client_hello{session_id = SugesstedId,
- cipher_suites = CipherSuites,
- compression_methods = Compressions,
- random = Random,
- extensions = #hello_extensions{elliptic_curves = Curves} = HelloExt},
- #ssl_options{versions = Versions} = SslOpts,
- {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) ->
+ cipher_suites = CipherSuites,
+ compression_methods = Compressions,
+ random = Random,
+ extensions = #hello_extensions{elliptic_curves = Curves,
+ signature_algs = ClientHashSigns} = HelloExt},
+ #ssl_options{versions = Versions,
+ signature_algs = SupportedHashSigns} = SslOpts,
+ {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert, _}, Renegotiation) ->
case tls_record:is_acceptable_version(Version, Versions) of
true ->
+ AvailableHashSigns = available_signature_algs(ClientHashSigns, SupportedHashSigns, Cert, Version),
ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)),
{Type, #session{cipher_suite = CipherSuite} = Session1}
- = ssl_handshake:select_session(SugesstedId, CipherSuites, Compressions,
+ = ssl_handshake:select_session(SugesstedId, CipherSuites, AvailableHashSigns, Compressions,
Port, Session0#session{ecc = ECCCurve}, Version,
SslOpts, Cache, CacheCb, Cert),
case CipherSuite of
no_suite ->
?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY);
_ ->
- handle_client_hello_extensions(Version, Type, Random, CipherSuites, HelloExt,
- SslOpts, Session1, ConnectionStates0,
- Renegotiation)
+ {KeyExAlg,_,_,_} = ssl_cipher:suite_definition(CipherSuite),
+ case ssl_handshake:select_hashsign(ClientHashSigns, Cert, KeyExAlg, SupportedHashSigns, Version) of
+ #alert{} = Alert ->
+ Alert;
+ HashSign ->
+ handle_client_hello_extensions(Version, Type, Random, CipherSuites, HelloExt,
+ SslOpts, Session1, ConnectionStates0,
+ Renegotiation, HashSign)
+ end
end;
false ->
?ALERT_REC(?FATAL, ?PROTOCOL_VERSION)
@@ -242,12 +254,14 @@ enc_handshake(HandshakeMsg, Version) ->
handle_client_hello_extensions(Version, Type, Random, CipherSuites,
- HelloExt, SslOpts, Session0, ConnectionStates0, Renegotiation) ->
+ HelloExt, SslOpts, Session0, ConnectionStates0, Renegotiation, HashSign) ->
try ssl_handshake:handle_client_hello_extensions(tls_record, Random, CipherSuites,
HelloExt, Version, SslOpts,
Session0, ConnectionStates0, Renegotiation) of
- {Session, ConnectionStates, ServerHelloExt} ->
- {Version, {Type, Session}, ConnectionStates, ServerHelloExt}
+ #alert{} = Alert ->
+ Alert;
+ {Session, ConnectionStates, Protocol, ServerHelloExt} ->
+ {Version, {Type, Session}, ConnectionStates, Protocol, ServerHelloExt, HashSign}
catch throw:Alert ->
Alert
end.
@@ -260,7 +274,18 @@ handle_server_hello_extensions(Version, SessionId, Random, CipherSuite,
SslOpt, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
Alert;
- {ConnectionStates, Protocol} ->
- {Version, SessionId, ConnectionStates, Protocol}
+ {ConnectionStates, ProtoExt, Protocol} ->
+ {Version, SessionId, ConnectionStates, ProtoExt, Protocol}
end.
+available_signature_algs(undefined, SupportedHashSigns, _, {Major, Minor}) when
+ (Major >= 3) andalso (Minor >= 3) ->
+ SupportedHashSigns;
+available_signature_algs(#hash_sign_algos{hash_sign_algos = ClientHashSigns}, SupportedHashSigns,
+ _, {Major, Minor}) when (Major >= 3) andalso (Minor >= 3) ->
+ sets:to_list(sets:intersection(sets:from_list(ClientHashSigns),
+ sets:from_list(SupportedHashSigns)));
+available_signature_algs(_, _, _, _) ->
+ undefined.
+
+
diff --git a/lib/ssl/src/tls_handshake.hrl b/lib/ssl/src/tls_handshake.hrl
index 1646e5b6f2..5867f9f9ff 100644
--- a/lib/ssl/src/tls_handshake.hrl
+++ b/lib/ssl/src/tls_handshake.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index 168b2c8fd3..9348c8bbdd 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,8 +41,9 @@
-export([encode_plain_text/4]).
%% Protocol version handling
--export([protocol_version/1, lowest_protocol_version/2,
- highest_protocol_version/1, is_higher/2, supported_protocol_versions/0,
+-export([protocol_version/1, lowest_protocol_version/1, lowest_protocol_version/2,
+ highest_protocol_version/1, highest_protocol_version/2,
+ is_higher/2, supported_protocol_versions/0,
is_acceptable_version/1, is_acceptable_version/2]).
-export_type([tls_version/0, tls_atom_version/0]).
@@ -132,6 +134,23 @@ encode_plain_text(Type, Version, Data,
sequence_number = Seq,
compression_state=CompS0,
security_parameters=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ compression_algorithm=CompAlg}
+ }= WriteState0} = ConnectionStates) ->
+ {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
+ WriteState1 = WriteState0#connection_state{compression_state = CompS1},
+ AAD = calc_aad(Type, Version, WriteState1),
+ {CipherFragment, WriteState} = ssl_record:cipher_aead(Version, Comp, WriteState1, AAD),
+ CipherText = encode_tls_cipher_text(Type, Version, CipherFragment),
+ {CipherText, ConnectionStates#connection_states{current_write = WriteState#connection_state{sequence_number = Seq +1}}};
+
+encode_plain_text(Type, Version, Data,
+ #connection_states{current_write =
+ #connection_state{
+ sequence_number = Seq,
+ compression_state=CompS0,
+ security_parameters=
#security_parameters{compression_algorithm=CompAlg}
}= WriteState0} = ConnectionStates) ->
{Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
@@ -154,14 +173,39 @@ decode_cipher_text(#ssl_tls{type = Type, version = Version,
compression_state = CompressionS0,
sequence_number = Seq,
security_parameters=
- #security_parameters{compression_algorithm = CompressAlg}
+ #security_parameters{
+ cipher_type = ?AEAD,
+ compression_algorithm=CompAlg}
+ } = ReadState0} = ConnnectionStates0, _) ->
+ AAD = calc_aad(Type, Version, ReadState0),
+ case ssl_record:decipher_aead(Version, CipherFragment, ReadState0, AAD) of
+ {PlainFragment, ReadState1} ->
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
+ PlainFragment, CompressionS0),
+ ConnnectionStates = ConnnectionStates0#connection_states{
+ current_read = ReadState1#connection_state{
+ sequence_number = Seq + 1,
+ compression_state = CompressionS1}},
+ {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end;
+
+decode_cipher_text(#ssl_tls{type = Type, version = Version,
+ fragment = CipherFragment} = CipherText,
+ #connection_states{current_read =
+ #connection_state{
+ compression_state = CompressionS0,
+ sequence_number = Seq,
+ security_parameters=
+ #security_parameters{compression_algorithm=CompAlg}
} = ReadState0} = ConnnectionStates0, PaddingCheck) ->
case ssl_record:decipher(Version, CipherFragment, ReadState0, PaddingCheck) of
{PlainFragment, Mac, ReadState1} ->
MacHash = calc_mac_hash(Type, Version, PlainFragment, ReadState1),
case ssl_record:is_correct_mac(Mac, MacHash) of
true ->
- {Plain, CompressionS1} = ssl_record:uncompress(CompressAlg,
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
PlainFragment, CompressionS0),
ConnnectionStates = ConnnectionStates0#connection_states{
current_read = ReadState1#connection_state{
@@ -214,6 +258,18 @@ lowest_protocol_version(Version = {M,_},
Version;
lowest_protocol_version(_,Version) ->
Version.
+
+%%--------------------------------------------------------------------
+-spec lowest_protocol_version([tls_version()]) -> tls_version().
+%%
+%% Description: Lowest protocol version present in a list
+%%--------------------------------------------------------------------
+lowest_protocol_version([]) ->
+ lowest_protocol_version();
+lowest_protocol_version(Versions) ->
+ [Ver | Vers] = Versions,
+ lowest_list_protocol_version(Ver, Vers).
+
%%--------------------------------------------------------------------
-spec highest_protocol_version([tls_version()]) -> tls_version().
%%
@@ -223,19 +279,29 @@ highest_protocol_version([]) ->
highest_protocol_version();
highest_protocol_version(Versions) ->
[Ver | Vers] = Versions,
- highest_protocol_version(Ver, Vers).
+ highest_list_protocol_version(Ver, Vers).
-highest_protocol_version(Version, []) ->
+%%--------------------------------------------------------------------
+-spec highest_protocol_version(tls_version(), tls_version()) -> tls_version().
+%%
+%% Description: Highest protocol version of two given versions
+%%--------------------------------------------------------------------
+highest_protocol_version(Version = {M, N}, {M, O}) when N > O ->
+ Version;
+highest_protocol_version({M, _},
+ Version = {M, _}) ->
Version;
-highest_protocol_version(Version = {N, M}, [{N, O} | Rest]) when M > O ->
- highest_protocol_version(Version, Rest);
-highest_protocol_version({M, _}, [Version = {M, _} | Rest]) ->
- highest_protocol_version(Version, Rest);
-highest_protocol_version(Version = {M,_}, [{N,_} | Rest]) when M > N ->
- highest_protocol_version(Version, Rest);
-highest_protocol_version(_, [Version | Rest]) ->
- highest_protocol_version(Version, Rest).
+highest_protocol_version(Version = {M,_},
+ {N, _}) when M > N ->
+ Version;
+highest_protocol_version(_,Version) ->
+ Version.
+%%--------------------------------------------------------------------
+-spec is_higher(V1 :: tls_version(), V2::tls_version()) -> boolean().
+%%
+%% Description: Is V1 > V2
+%%--------------------------------------------------------------------
is_higher({M, N}, {M, O}) when N > O ->
true;
is_higher({M, _}, {N, _}) when M > N ->
@@ -276,8 +342,17 @@ supported_protocol_versions([]) ->
Vsns;
supported_protocol_versions([_|_] = Vsns) ->
- Vsns.
-
+ case sufficient_tlsv1_2_crypto_support() of
+ true ->
+ Vsns;
+ false ->
+ case Vsns -- ['tlsv1.2'] of
+ [] ->
+ ?MIN_SUPPORTED_VERSIONS;
+ NewVsns ->
+ NewVsns
+ end
+ end.
%%--------------------------------------------------------------------
%%
%% Description: ssl version 2 is not acceptable security risks are too big.
@@ -300,6 +375,17 @@ is_acceptable_version(_,_) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+
+lowest_list_protocol_version(Ver, []) ->
+ Ver;
+lowest_list_protocol_version(Ver1, [Ver2 | Rest]) ->
+ lowest_list_protocol_version(lowest_protocol_version(Ver1, Ver2), Rest).
+
+highest_list_protocol_version(Ver, []) ->
+ Ver;
+highest_list_protocol_version(Ver1, [Ver2 | Rest]) ->
+ highest_list_protocol_version(highest_protocol_version(Ver1, Ver2), Rest).
+
encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) ->
Length = erlang:iolist_size(Fragment),
[<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment].
@@ -318,6 +404,10 @@ mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment)
highest_protocol_version() ->
highest_protocol_version(supported_protocol_versions()).
+lowest_protocol_version() ->
+ lowest_protocol_version(supported_protocol_versions()).
+
+
sufficient_tlsv1_2_crypto_support() ->
CryptoSupport = crypto:supports(),
proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)).
@@ -331,3 +421,7 @@ calc_mac_hash(Type, Version,
mac_hash(Version, SecPars#security_parameters.mac_algorithm,
MacSecret, SeqNo, Type,
Length, PlainFragment).
+
+calc_aad(Type, {MajVer, MinVer},
+ #connection_state{sequence_number = SeqNo}) ->
+ <<SeqNo:64/integer, ?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer)>>.
diff --git a/lib/ssl/src/tls_record.hrl b/lib/ssl/src/tls_record.hrl
index 30d7343074..3c5cdd3f7a 100644
--- a/lib/ssl/src/tls_record.hrl
+++ b/lib/ssl/src/tls_record.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 7a5f9c1b38..543bd33833 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,8 @@
-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, oid_to_enum/1, enum_to_oid/1,
+ default_signature_algs/1, signature_algs/2]).
%%====================================================================
%% Internal application API
@@ -208,38 +210,103 @@ suites(Minor) when Minor == 1; Minor == 2 ->
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
-
- ?TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- ?TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- ?TLS_RSA_WITH_RC4_128_SHA,
- ?TLS_RSA_WITH_RC4_128_MD5,
?TLS_DHE_RSA_WITH_DES_CBC_SHA,
- ?TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- ?TLS_ECDH_RSA_WITH_RC4_128_SHA,
-
?TLS_RSA_WITH_DES_CBC_SHA
];
suites(3) ->
[
+ ?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+ ?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+
+ ?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+ ?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
?TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
?TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+ ?TLS_RSA_WITH_AES_256_GCM_SHA384,
?TLS_RSA_WITH_AES_256_CBC_SHA256,
+ ?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ ?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+ ?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
?TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+ ?TLS_RSA_WITH_AES_128_GCM_SHA256,
?TLS_RSA_WITH_AES_128_CBC_SHA256
+
+ %% not supported
+ %% ?TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
+ %% ?TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
+ %% ?TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
+ %% ?TLS_DH_DSS_WITH_AES_128_GCM_SHA256
] ++ suites(2).
+
+
+signature_algs({3, 3}, HashSigns) ->
+ CryptoSupports = crypto:supports(),
+ Hashes = proplists:get_value(hashs, CryptoSupports),
+ PubKeys = proplists:get_value(public_keys, CryptoSupports),
+ Supported = lists:foldl(fun({Hash, dsa = Sign} = Alg, Acc) ->
+ case proplists:get_bool(dss, PubKeys)
+ andalso proplists:get_bool(Hash, Hashes)
+ andalso is_pair(Hash, Sign, Hashes)
+ of
+ true ->
+ [Alg | Acc];
+ false ->
+ Acc
+ end;
+ ({Hash, Sign} = Alg, Acc) ->
+ case proplists:get_bool(Sign, PubKeys)
+ andalso proplists:get_bool(Hash, Hashes)
+ andalso is_pair(Hash, Sign, Hashes)
+ of
+ true ->
+ [Alg | Acc];
+ false ->
+ Acc
+ end
+ end, [], HashSigns),
+ lists:reverse(Supported).
+
+default_signature_algs({3, 3} = Version) ->
+ Default = [%% SHA2
+ {sha512, ecdsa},
+ {sha512, rsa},
+ {sha384, ecdsa},
+ {sha384, rsa},
+ {sha256, ecdsa},
+ {sha256, rsa},
+ {sha224, ecdsa},
+ {sha224, rsa},
+ %% SHA
+ {sha, ecdsa},
+ {sha, rsa},
+ {sha, dsa},
+ %% MD5
+ {md5, rsa}],
+ signature_algs(Version, Default);
+default_signature_algs(_) ->
+ undefined.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -324,6 +391,17 @@ finished_label(client) ->
finished_label(server) ->
<<"server finished">>.
+is_pair(sha, dsa, _) ->
+ true;
+is_pair(_, dsa, _) ->
+ false;
+is_pair(Hash, ecdsa, Hashs) ->
+ AtLeastSha = Hashs -- [md2,md4,md5],
+ lists:member(Hash, AtLeastSha);
+is_pair(Hash, rsa, Hashs) ->
+ AtLeastMd5 = Hashs -- [md2,md4],
+ lists:member(Hash, AtLeastMd5).
+
%% list ECC curves in prefered order
ecc_curves(_Minor) ->
TLSCurves = [sect571r1,sect571k1,secp521r1,brainpoolP512r1,
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 0d241707d9..999df320a3 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -36,7 +37,9 @@ VSN=$(GS_VSN)
MODULES = \
ssl_test_lib \
+ ssl_alpn_handshake_SUITE \
ssl_basic_SUITE \
+ ssl_bench_SUITE \
ssl_cipher_SUITE \
ssl_certificate_verify_SUITE\
ssl_crl_SUITE\
@@ -50,6 +53,8 @@ MODULES = \
ssl_session_cache_SUITE \
ssl_to_openssl_SUITE \
ssl_ECC_SUITE \
+ ssl_upgrade_SUITE\
+ ssl_sni_SUITE \
make_certs\
erl_make_certs
@@ -131,7 +136,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)"
$(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) "$(RELSYSDIR)"
- $(INSTALL_DATA) ssl.spec ssl.cover "$(RELSYSDIR)"
+ $(INSTALL_DATA) ssl.spec ssl_bench.spec ssl.cover "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl
index daf4466f11..f5cada9021 100644
--- a/lib/ssl/test/erl_make_certs.erl
+++ b/lib/ssl/test/erl_make_certs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -114,7 +115,7 @@ verify_signature(DerEncodedCert, DerKey, _KeyParams) ->
#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} ->
public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}});
#'ECPrivateKey'{version = _Version, privateKey = _PrivKey,
- parameters = Params, publicKey = {0, PubKey}} ->
+ parameters = Params, publicKey = PubKey} ->
public_key:pkix_verify(DerEncodedCert, {#'ECPoint'{point = PubKey}, Params})
end.
@@ -204,7 +205,7 @@ issuer_der(Issuer) ->
Subject.
subject(undefined, IsRootCA) ->
- User = if IsRootCA -> "RootCA"; true -> user() end,
+ User = if IsRootCA -> "RootCA"; true -> os:getenv("USER", "test_user") end,
Opts = [{email, User ++ "@erlang.org"},
{name, User},
{city, "Stockholm"},
@@ -215,14 +216,6 @@ subject(undefined, IsRootCA) ->
subject(Opts, _) ->
subject(Opts).
-user() ->
- case os:getenv("USER") of
- false ->
- "test_user";
- User ->
- User
- end.
-
subject(SubjectOpts) when is_list(SubjectOpts) ->
Encode = fun(Opt) ->
{Type,Value} = subject_enc(Opt),
@@ -300,7 +293,7 @@ publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) ->
publickey(#'ECPrivateKey'{version = _Version,
privateKey = _PrivKey,
parameters = Params,
- publicKey = {0, PubKey}}) ->
+ publicKey = PubKey}) ->
Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-ecPublicKey', parameters=Params},
#'OTPSubjectPublicKeyInfo'{algorithm = Algo,
subjectPublicKey = #'ECPoint'{point = PubKey}}.
@@ -341,7 +334,9 @@ make_key(dsa, _Opts) ->
gen_dsa2(128, 20); %% Bytes i.e. {1024, 160}
make_key(ec, _Opts) ->
%% (OBS: for testing only)
- gen_ec2(secp256k1).
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ NamedCurve = pubkey_cert_records:namedCurves(CurveOid),
+ gen_ec2(NamedCurve).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% RSA key generation (OBS: for testing only)
@@ -409,9 +404,9 @@ gen_ec2(CurveId) ->
{PubKey, PrivKey} = crypto:generate_key(ecdh, CurveId),
#'ECPrivateKey'{version = 1,
- privateKey = binary_to_list(PrivKey),
+ privateKey = PrivKey,
parameters = {namedCurve, pubkey_cert_records:namedCurves(CurveId)},
- publicKey = {0, PubKey}}.
+ publicKey = PubKey}.
%% See fips_186-3.pdf
dsa_search(T, P0, Q, Iter) when Iter > 0 ->
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
index 15a7e118ff..5eebf773a7 100644
--- a/lib/ssl/test/make_certs.erl
+++ b/lib/ssl/test/make_certs.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -81,7 +82,7 @@ all(DataDir, PrivDir, C = #config{}) ->
create_rnd(DataDir, PrivDir), % For all requests
rootCA(PrivDir, "erlangCA", C),
intermediateCA(PrivDir, "otpCA", "erlangCA", C),
- endusers(PrivDir, "otpCA", ["client", "server", "revoked"], C),
+ endusers(PrivDir, "otpCA", ["client", "server", "revoked", "a.server", "b.server"], C),
endusers(PrivDir, "erlangCA", ["localhost"], C),
%% Create keycert files
SDir = filename:join([PrivDir, "server"]),
@@ -115,16 +116,16 @@ do_append_files([F|Fs], RF) ->
do_append_files(Fs, RF).
rootCA(Root, Name, C) ->
- create_ca_dir(Root, Name, ca_cnf(C#config{commonName = Name})),
- create_self_signed_cert(Root, Name, req_cnf(C#config{commonName = Name}), C),
+ create_ca_dir(Root, Name, ca_cnf(Root, C#config{commonName = Name})),
+ create_self_signed_cert(Root, Name, req_cnf(Root, C#config{commonName = Name}), C),
file:copy(filename:join([Root, Name, "cert.pem"]), filename:join([Root, Name, "cacerts.pem"])),
gencrl(Root, Name, C).
intermediateCA(Root, CA, ParentCA, C) ->
- create_ca_dir(Root, CA, ca_cnf(C#config{commonName = CA})),
+ create_ca_dir(Root, CA, ca_cnf(Root, C#config{commonName = CA})),
CARoot = filename:join([Root, CA]),
CnfFile = filename:join([CARoot, "req.cnf"]),
- file:write_file(CnfFile, req_cnf(C#config{commonName = CA})),
+ file:write_file(CnfFile, req_cnf(Root, C#config{commonName = CA})),
KeyFile = filename:join([CARoot, "private", "key.pem"]),
ReqFile = filename:join([CARoot, "req.pem"]),
create_req(Root, CnfFile, KeyFile, ReqFile, C),
@@ -146,7 +147,7 @@ enduser(Root, CA, User, C) ->
UsrRoot = filename:join([Root, User]),
file:make_dir(UsrRoot),
CnfFile = filename:join([UsrRoot, "req.cnf"]),
- file:write_file(CnfFile, req_cnf(C#config{commonName = User})),
+ file:write_file(CnfFile, req_cnf(Root, C#config{commonName = User})),
KeyFile = filename:join([UsrRoot, "key.pem"]),
ReqFile = filename:join([UsrRoot, "req.pem"]),
create_req(Root, CnfFile, KeyFile, ReqFile, C),
@@ -324,8 +325,9 @@ eval_cmd(Port, Cmd) ->
ok
end,
receive
- {Port, {exit_status, Status}} when Status /= 0 ->
- %% io:fwrite("exit status: ~w~n", [Status]),
+ {Port, {exit_status, 0}} ->
+ ok;
+ {Port, {exit_status, Status}} ->
exit({eval_cmd, Cmd, Status})
after 0 ->
ok
@@ -335,10 +337,10 @@ eval_cmd(Port, Cmd) ->
%% Contents of configuration files
%%
-req_cnf(C) ->
+req_cnf(Root, C) ->
["# Purpose: Configuration for requests (end users and CAs)."
"\n"
- "ROOTDIR = $ENV::ROOTDIR\n"
+ "ROOTDIR = " ++ Root ++ "\n"
"\n"
"[req]\n"
@@ -369,10 +371,10 @@ req_cnf(C) ->
"subjectKeyIdentifier = hash\n"
"subjectAltName = email:copy\n"].
-ca_cnf(C) ->
+ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
["# Purpose: Configuration for CAs.\n"
"\n"
- "ROOTDIR = $ENV::ROOTDIR\n"
+ "ROOTDIR = " ++ Root ++ "\n"
"default_ca = ca\n"
"\n"
@@ -446,5 +448,83 @@ ca_cnf(C) ->
"subjectAltName = email:copy\n"
"issuerAltName = issuer:copy\n"
"crlDistributionPoints=@crl_section\n"
- ].
+ ];
+
+ca_cnf(Root, C = #config{issuing_distribution_point = false}) ->
+ ["# Purpose: Configuration for CAs.\n"
+ "\n"
+ "ROOTDIR = " ++ Root ++ "\n"
+ "default_ca = ca\n"
+ "\n"
+
+ "[ca]\n"
+ "dir = $ROOTDIR/", C#config.commonName, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n",
+ ["crlnumber = $dir/crlnumber\n" || C#config.v2_crls],
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
+ "\n"
+ "x509_extensions = user_cert\n",
+ ["crl_extensions = crl_ext\n" || C#config.v2_crls],
+ "unique_subject = no\n"
+ "default_days = 3600\n"
+ "default_md = md5\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
+ "\n"
+ "[policy_match]\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
+ "\n"
+
+ "[crl_ext]\n"
+ "authorityKeyIdentifier=keyid:always,issuer:always\n",
+ %["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point],
+
+ %"[idpsec]\n"
+ %"fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n"
+
+ "[user_cert]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ %"crlDistributionPoints=@crl_section\n"
+
+ %%"[crl_section]\n"
+ %% intentionally invalid
+ %%"URI.1=http://localhost/",C#config.commonName,"/crl.pem\n"
+ %%"URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n"
+ %%"\n"
+
+ "[user_cert_digital_signature_only]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = digitalSignature\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ "\n"
+
+ "[ca_cert]\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid:always,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ %"crlDistributionPoints=@crl_section\n"
+ ].
diff --git a/lib/ssl/test/ssl.spec b/lib/ssl/test/ssl.spec
index fc7c1bbb82..86e14c033e 100644
--- a/lib/ssl/test/ssl.spec
+++ b/lib/ssl/test/ssl.spec
@@ -1 +1,4 @@
{suites,"../ssl_test",all}.
+{skip_cases, "../ssl_test",
+ ssl_bench_SUITE, [setup_sequential, setup_concurrent, payload_simple],
+ "Benchmarks run separately"}.
diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl
index 3566a8a0a5..75b639b23b 100644
--- a/lib/ssl/test/ssl_ECC_SUITE.erl
+++ b/lib/ssl/test/ssl_ECC_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.2
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,8 +32,6 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[
{group, 'tlsv1.2'},
@@ -47,7 +46,7 @@ groups() ->
{'tlsv1', [], all_versions_groups()},
{'erlang_server', [], key_cert_combinations()},
{'erlang_client', [], key_cert_combinations()},
- {'erlang', [], key_cert_combinations()}
+ {'erlang', [], key_cert_combinations() ++ misc()}
].
all_versions_groups ()->
@@ -66,16 +65,17 @@ key_cert_combinations() ->
client_rsa_server_ecdsa
].
+misc()->
+ [client_ecdsa_server_ecdsa_with_raw_key].
+
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
end_per_suite(Config0),
try crypto:start() of
ok ->
%% make rsa certs using oppenssl
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- ct:log("Make certs ~p~n", [Result]),
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
Config1 = ssl_test_lib:make_ecdsa_cert(Config0),
Config2 = ssl_test_lib:make_ecdh_rsa_cert(Config1),
ssl_test_lib:cert_options(Config2)
@@ -146,6 +146,7 @@ init_per_testcase(TestCase, Config) ->
ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]),
end_per_testcase(TestCase, Config),
ssl:start(),
+ ct:timetrap({seconds, 15}),
Config.
end_per_testcase(_TestCase, Config) ->
@@ -191,6 +192,32 @@ client_rsa_server_ecdsa(Config) when is_list(Config) ->
SOpts = ?config(server_ecdsa_verify_opts, Config),
basic_test(COpts, SOpts, Config).
+client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdsa_opts, Config),
+ SOpts = ?config(server_ecdsa_verify_opts, Config),
+ ServerCert = proplists:get_value(certfile, SOpts),
+ ServerKeyFile = proplists:get_value(keyfile, SOpts),
+ {ok, PemBin} = file:read_file(ServerKeyFile),
+ PemEntries = public_key:pem_decode(PemBin),
+ {'ECPrivateKey', Key, not_encrypted} = proplists:lookup('ECPrivateKey', PemEntries),
+ ServerKey = {'ECPrivateKey', Key},
+ ServerCA = proplists:get_value(cacertfile, SOpts),
+ ClientCert = proplists:get_value(certfile, COpts),
+ ClientKey = proplists:get_value(keyfile, COpts),
+ ClientCA = proplists:get_value(cacertfile, COpts),
+ SType = ?config(server_type, Config),
+ CType = ?config(client_type, Config),
+ {Server, Port} = start_server_with_raw_key(SType,
+ ClientCA, ServerCA,
+ ServerCert,
+ ServerKey,
+ Config),
+ Client = start_client(CType, Port, ServerCA, ClientCA,
+ ClientCert,
+ ClientKey, Config),
+ check_result(Server, SType, Client, CType),
+ close(Server, Client).
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
@@ -221,10 +248,13 @@ start_client(openssl, Port, CA, OwnCa, Cert, Key, Config) ->
PrivDir = ?config(priv_dir, Config),
NewCA = new_ca(filename:join(PrivDir, "new_ca.pem"), CA, OwnCa),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -verify 2 -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ Cert ++ " -CAfile " ++ NewCA
- ++ " -key " ++ Key ++ " -host localhost -msg -debug",
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ Exe = "openssl",
+ Args = ["s_client", "-verify", "2", "-port", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", Cert, "-CAfile", NewCA,
+ "-key", Key, "-host","localhost", "-msg", "-debug"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, "Hello world"),
OpenSslPort;
start_client(erlang, Port, CA, _, Cert, Key, Config) ->
@@ -243,16 +273,14 @@ start_server(openssl, CA, OwnCa, Cert, Key, Config) ->
Port = ssl_test_lib:inet_port(node()),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -verify 2 -cert " ++ Cert ++ " -CAfile " ++ NewCA
- ++ " -key " ++ Key ++ " -msg -debug",
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- ssl_test_lib:wait_for_openssl_server(),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-verify", "2", "-cert", Cert, "-CAfile", NewCA,
+ "-key", Key, "-msg", "-debug"],
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, "Hello world"),
{OpenSslPort, Port};
-
start_server(erlang, CA, _, Cert, Key, Config) ->
-
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -263,6 +291,17 @@ start_server(erlang, CA, _, 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, CA, _, Cert, Key, Config) ->
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ send_recv_result_active,
+ []}},
+ {options,
+ [{verify, verify_peer}, {cacertfile, CA},
+ {certfile, Cert}, {key, Key}]}]),
+ {Server, ssl_test_lib:inet_port(Server)}.
check_result(Server, erlang, Client, erlang) ->
ssl_test_lib:check_result(Server, ok, Client, ok);
diff --git a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
new file mode 100644
index 0000000000..f5469ec8e0
--- /dev/null
+++ b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
@@ -0,0 +1,419 @@
+%%
+%% %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.
+%% 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(ssl_alpn_handshake_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+
+-define(SLEEP, 500).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'}].
+
+groups() ->
+ [
+ {'tlsv1.2', [], alpn_tests()},
+ {'tlsv1.1', [], alpn_tests()},
+ {'tlsv1', [], alpn_tests()},
+ {'sslv3', [], alpn_not_supported()}
+ ].
+
+alpn_tests() ->
+ [empty_protocols_are_not_allowed,
+ protocols_must_be_a_binary_list,
+ empty_client,
+ empty_server,
+ empty_client_empty_server,
+ no_matching_protocol,
+ client_alpn_and_server_alpn,
+ client_alpn_and_server_no_support,
+ client_no_support_and_server_alpn,
+ client_alpn_npn_and_server_alpn,
+ client_alpn_npn_and_server_alpn_npn,
+ client_alpn_and_server_alpn_npn,
+ client_renegotiate,
+ session_reused
+ ].
+
+alpn_not_supported() ->
+ [alpn_not_supported_client,
+ alpn_not_supported_server
+ ].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl:start(),
+ {ok, _} = make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config)),
+ ssl_test_lib:cert_options(Config)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+empty_protocols_are_not_allowed(Config) when is_list(Config) ->
+ {error, {options, {alpn_preferred_protocols, {invalid_protocol, <<>>}}}}
+ = (catch ssl:listen(9443,
+ [{alpn_preferred_protocols, [<<"foo/1">>, <<"">>]}])),
+ {error, {options, {alpn_advertised_protocols, {invalid_protocol, <<>>}}}}
+ = (catch ssl:connect({127,0,0,1}, 9443,
+ [{alpn_advertised_protocols, [<<"foo/1">>, <<"">>]}])).
+
+%--------------------------------------------------------------------------------
+
+protocols_must_be_a_binary_list(Config) when is_list(Config) ->
+ Option1 = {alpn_preferred_protocols, hello},
+ {error, {options, Option1}} = (catch ssl:listen(9443, [Option1])),
+ Option2 = {alpn_preferred_protocols, [<<"foo/1">>, hello]},
+ {error, {options, {alpn_preferred_protocols, {invalid_protocol, hello}}}}
+ = (catch ssl:listen(9443, [Option2])),
+ Option3 = {alpn_advertised_protocols, hello},
+ {error, {options, Option3}} = (catch ssl:connect({127,0,0,1}, 9443, [Option3])),
+ Option4 = {alpn_advertised_protocols, [<<"foo/1">>, hello]},
+ {error, {options, {alpn_advertised_protocols, {invalid_protocol, hello}}}}
+ = (catch ssl:connect({127,0,0,1}, 9443, [Option4])).
+
+%--------------------------------------------------------------------------------
+
+empty_client(Config) when is_list(Config) ->
+ run_failing_handshake(Config,
+ [{alpn_advertised_protocols, []}],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"spdy/3">>, <<"http/2">>]}],
+ {connect_failed,{tls_alert,"no application protocol"}}).
+
+%--------------------------------------------------------------------------------
+
+empty_server(Config) when is_list(Config) ->
+ run_failing_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
+ [{alpn_preferred_protocols, []}],
+ {connect_failed,{tls_alert,"no application protocol"}}).
+
+%--------------------------------------------------------------------------------
+
+empty_client_empty_server(Config) when is_list(Config) ->
+ run_failing_handshake(Config,
+ [{alpn_advertised_protocols, []}],
+ [{alpn_preferred_protocols, []}],
+ {connect_failed,{tls_alert,"no application protocol"}}).
+
+%--------------------------------------------------------------------------------
+
+no_matching_protocol(Config) when is_list(Config) ->
+ run_failing_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"spdy/3">>, <<"http/2">>]}],
+ {connect_failed,{tls_alert,"no application protocol"}}).
+
+%--------------------------------------------------------------------------------
+
+client_alpn_and_server_alpn(Config) when is_list(Config) ->
+ run_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}],
+ {ok, <<"http/1.1">>}).
+
+%--------------------------------------------------------------------------------
+
+client_alpn_and_server_no_support(Config) when is_list(Config) ->
+ run_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
+ [],
+ {error, protocol_not_negotiated}).
+
+%--------------------------------------------------------------------------------
+
+client_no_support_and_server_alpn(Config) when is_list(Config) ->
+ run_handshake(Config,
+ [],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}],
+ {error, protocol_not_negotiated}).
+
+%--------------------------------------------------------------------------------
+
+client_alpn_npn_and_server_alpn(Config) when is_list(Config) ->
+ run_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]},
+ {client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"spdy/3">>}}],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}],
+ {ok, <<"http/1.1">>}).
+
+%--------------------------------------------------------------------------------
+
+client_alpn_npn_and_server_alpn_npn(Config) when is_list(Config) ->
+ run_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]},
+ {client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"spdy/3">>}}],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]},
+ {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.0">>]}],
+ {ok, <<"http/1.1">>}).
+
+%--------------------------------------------------------------------------------
+
+client_alpn_and_server_alpn_npn(Config) when is_list(Config) ->
+ run_handshake(Config,
+ [{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
+ [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]},
+ {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.0">>]}],
+ {ok, <<"http/1.1">>}).
+
+%--------------------------------------------------------------------------------
+
+client_renegotiate(Config) when is_list(Config) ->
+ Data = "hello world",
+
+ ClientOpts0 = ?config(client_opts, Config),
+ ClientOpts = [{alpn_advertised_protocols, [<<"http/1.0">>]}] ++ ClientOpts0,
+ ServerOpts0 = ?config(server_opts, Config),
+ ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++ ServerOpts0,
+ ExpectedProtocol = {ok, <<"http/1.0">>},
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, ssl_receive_and_assert_alpn, [ExpectedProtocol, Data]}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, assert_alpn_and_renegotiate_and_send_data, [ExpectedProtocol, Data]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok).
+
+%--------------------------------------------------------------------------------
+
+session_reused(Config) when is_list(Config)->
+ ClientOpts0 = ?config(client_opts, Config),
+ ClientOpts = [{alpn_advertised_protocols, [<<"http/1.0">>]}] ++ ClientOpts0,
+ ServerOpts0 = ?config(server_opts, Config),
+ ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++ ServerOpts0,
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result_msg, []}},
+ {options, ClientOpts}]),
+
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+
+ %% Make sure session is registered
+ ct:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ ct:fail(Other)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ssl_test_lib:close(Client1).
+
+%--------------------------------------------------------------------------------
+
+alpn_not_supported_client(Config) when is_list(Config) ->
+ ClientOpts0 = ?config(client_opts, Config),
+ PrefProtocols = {client_preferred_next_protocols,
+ {client, [<<"http/1.0">>], <<"http/1.1">>}},
+ ClientOpts = [PrefProtocols] ++ ClientOpts0,
+ {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, 8888}, {host, Hostname},
+ {from, self()}, {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, {error,
+ {options,
+ {not_supported_in_sslv3, PrefProtocols}}}).
+
+%--------------------------------------------------------------------------------
+
+alpn_not_supported_server(Config) when is_list(Config)->
+ ServerOpts0 = ?config(server_opts, Config),
+ AdvProtocols = {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]},
+ ServerOpts = [AdvProtocols] ++ ServerOpts0,
+
+ {error, {options, {not_supported_in_sslv3, AdvProtocols}}} = ssl:listen(0, ServerOpts).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+run_failing_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedResult) ->
+ ClientOpts = ClientExtraOpts ++ ?config(client_opts, Config),
+ ServerOpts = ServerExtraOpts ++ ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, placeholder, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ ExpectedResult
+ = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, placeholder, []}},
+ {options, ClientOpts}]).
+
+run_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) ->
+ Data = "hello world",
+
+ ClientOpts0 = ?config(client_opts, Config),
+ ClientOpts = ClientExtraOpts ++ ClientOpts0,
+ ServerOpts0 = ?config(server_opts, Config),
+ ServerOpts = ServerExtraOpts ++ ServerOpts0,
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, ssl_receive_and_assert_alpn, [ExpectedProtocol, Data]}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, ssl_send_and_assert_alpn, [ExpectedProtocol, Data]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok).
+
+assert_alpn(Socket, Protocol) ->
+ ct:log("Negotiated Protocol ~p, Expecting: ~p ~n",
+ [ssl:negotiated_protocol(Socket), Protocol]),
+ Protocol = ssl:negotiated_protocol(Socket).
+
+assert_alpn_and_renegotiate_and_send_data(Socket, Protocol, Data) ->
+ assert_alpn(Socket, Protocol),
+ ct:log("Renegotiating ~n", []),
+ ok = ssl:renegotiate(Socket),
+ ssl:send(Socket, Data),
+ assert_alpn(Socket, Protocol),
+ ok.
+
+ssl_send_and_assert_alpn(Socket, Protocol, Data) ->
+ assert_alpn(Socket, Protocol),
+ ssl_send(Socket, Data).
+
+ssl_receive_and_assert_alpn(Socket, Protocol, Data) ->
+ assert_alpn(Socket, Protocol),
+ ssl_receive(Socket, Data).
+
+ssl_send(Socket, Data) ->
+ ct:log("Connection info: ~p~n",
+ [ssl:connection_information(Socket)]),
+ ssl:send(Socket, Data).
+
+ssl_receive(Socket, Data) ->
+ ssl_receive(Socket, Data, []).
+
+ssl_receive(Socket, Data, Buffer) ->
+ ct:log("Connection info: ~p~n",
+ [ssl:connection_information(Socket)]),
+ receive
+ {ssl, Socket, MoreData} ->
+ ct:log("Received ~p~n",[MoreData]),
+ NewBuffer = Buffer ++ MoreData,
+ case NewBuffer of
+ Data ->
+ ssl:send(Socket, "Got it"),
+ ok;
+ _ ->
+ ssl_receive(Socket, Data, NewBuffer)
+ end;
+ Other ->
+ ct:fail({unexpected_message, Other})
+ after 4000 ->
+ ct:fail({did_not_get, Data})
+ end.
+
+connection_info_result(Socket) ->
+ ssl:connection_information(Socket).
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index df9432a43b..a07739d3de 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.2
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,9 +35,7 @@
-include("tls_record.hrl").
-include("tls_handshake.hrl").
--define('24H_in_sec', 86400).
--define(TIMEOUT, 60000).
--define(LONG_TIMEOUT, 600000).
+-define(TIMEOUT, 20000).
-define(EXPIRE, 10).
-define(SLEEP, 500).
-define(RENEGOTIATION_DISABLE_TIME, 12000).
@@ -45,9 +44,6 @@
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[
{group, basic},
@@ -62,10 +58,10 @@ all() ->
groups() ->
[{basic, [], basic_tests()},
{options, [], options_tests()},
- {'tlsv1.2', [], all_versions_groups()},
+ {'tlsv1.2', [], all_versions_groups() ++ [conf_signature_algs, no_common_signature_algs]},
{'tlsv1.1', [], all_versions_groups()},
{'tlsv1', [], all_versions_groups() ++ rizzo_tests()},
- {'sslv3', [], all_versions_groups() ++ rizzo_tests()},
+ {'sslv3', [], all_versions_groups() ++ rizzo_tests() ++ [ciphersuite_vs_version]},
{api,[], api_tests()},
{session, [], session_tests()},
{renegotiate, [], renegotiate_tests()},
@@ -91,13 +87,16 @@ basic_tests() ->
connect_twice,
connect_dist,
clear_pem_cache,
- fallback
+ defaults,
+ fallback,
+ cipher_format
].
options_tests() ->
[der_input,
misc_ssl_options,
ssl_options_not_proplist,
+ raw_ssl_option,
socket_options,
invalid_inet_get_option,
invalid_inet_get_option_not_list,
@@ -117,13 +116,13 @@ options_tests() ->
tcp_reuseaddr,
honor_server_cipher_order,
honor_client_cipher_order,
- ciphersuite_vs_version,
unordered_protocol_versions_server,
unordered_protocol_versions_client
].
api_tests() ->
[connection_info,
+ connection_information,
peername,
peercert,
peercert_with_client_cert,
@@ -132,18 +131,22 @@ api_tests() ->
controlling_process,
upgrade,
upgrade_with_timeout,
+ downgrade,
+ close_with_timeout,
shutdown,
shutdown_write,
shutdown_both,
shutdown_error,
hibernate,
+ hibernate_right_away,
listen_socket,
ssl_accept_timeout,
ssl_recv_timeout,
versions_option,
server_name_indication_option,
accept_pool,
- new_options_in_accept
+ new_options_in_accept,
+ prf
].
session_tests() ->
@@ -162,10 +165,12 @@ renegotiate_tests() ->
client_no_wrap_sequence_number,
server_no_wrap_sequence_number,
renegotiate_dos_mitigate_active,
- renegotiate_dos_mitigate_passive].
+ renegotiate_dos_mitigate_passive,
+ renegotiate_dos_mitigate_absolute].
cipher_tests() ->
[cipher_suites,
+ cipher_suites_mix,
ciphers_rsa_signed_certs,
ciphers_rsa_signed_certs_openssl_names,
ciphers_dsa_signed_certs,
@@ -178,6 +183,9 @@ cipher_tests() ->
srp_cipher_suites,
srp_anon_cipher_suites,
srp_dsa_cipher_suites,
+ rc4_rsa_cipher_suites,
+ rc4_ecdh_rsa_cipher_suites,
+ rc4_ecdsa_cipher_suites,
default_reject_anonymous].
cipher_tests_ec() ->
@@ -205,22 +213,17 @@ rizzo_tests() ->
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
- Dog = ct:timetrap(?LONG_TIMEOUT *2),
catch crypto:stop(),
try crypto:start() of
ok ->
ssl:start(),
%% make rsa certs using oppenssl
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- ct:log("Make certs ~p~n", [Result]),
-
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
Config1 = ssl_test_lib:make_dsa_cert(Config0),
Config2 = ssl_test_lib:make_ecdsa_cert(Config1),
- Config3 = ssl_test_lib:make_ecdh_rsa_cert(Config2),
- Config = ssl_test_lib:cert_options(Config3),
- [{watchdog, Dog} | Config]
+ Config = ssl_test_lib:make_ecdh_rsa_cert(Config2),
+ ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
end.
@@ -253,6 +256,7 @@ init_per_testcase(Case, Config) when Case == unordered_protocol_versions_client
Case == unordered_protocol_versions_server->
case proplists:get_value(supported, ssl:versions()) of
['tlsv1.2' | _] ->
+ ct:timetrap({seconds, 5}),
Config;
_ ->
{skip, "TLS 1.2 need but not supported on this platform"}
@@ -264,15 +268,16 @@ init_per_testcase(protocol_versions, Config) ->
%% For backwards compatibility sslv2 should be filtered out.
application:set_env(ssl, protocol_version, [sslv2, sslv3, tlsv1]),
ssl:start(),
+ ct:timetrap({seconds, 5}),
Config;
-init_per_testcase(reuse_session_expired, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
+init_per_testcase(reuse_session_expired, Config) ->
ssl:stop(),
application:load(ssl),
application:set_env(ssl, session_lifetime, ?EXPIRE),
application:set_env(ssl, session_delay_cleanup_time, 500),
ssl:start(),
+ ct:timetrap({seconds, 30}),
Config;
init_per_testcase(empty_protocol_versions, Config) ->
@@ -280,24 +285,95 @@ init_per_testcase(empty_protocol_versions, Config) ->
application:load(ssl),
application:set_env(ssl, protocol_version, []),
ssl:start(),
+ ct:timetrap({seconds, 5}),
Config;
init_per_testcase(fallback, Config) ->
case tls_record:highest_protocol_version([]) of
{3, N} when N > 1 ->
+ ct:timetrap({seconds, 5}),
Config;
_ ->
{skip, "Not relevant if highest supported version is less than 3.2"}
end;
-%% init_per_testcase(different_ca_peer_sign, Config0) ->
-%% ssl_test_lib:make_mix_cert(Config0);
+init_per_testcase(TestCase, Config) when TestCase == client_renegotiate;
+ TestCase == server_renegotiate;
+ TestCase == client_secure_renegotiate;
+ TestCase == client_renegotiate_reused_session;
+ TestCase == server_renegotiate_reused_session;
+ TestCase == client_no_wrap_sequence_number;
+ TestCase == server_no_wrap_sequence_number;
+ TestCase == renegotiate_dos_mitigate_active;
+ TestCase == renegotiate_dos_mitigate_passive;
+ TestCase == renegotiate_dos_mitigate_absolute ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 30}),
+ Config;
-init_per_testcase(_TestCase, Config0) ->
+init_per_testcase(TestCase, Config) when TestCase == psk_cipher_suites;
+ TestCase == psk_with_hint_cipher_suites;
+ TestCase == ciphers_rsa_signed_certs;
+ TestCase == ciphers_rsa_signed_certs_openssl_names;
+ TestCase == versions_option,
+ TestCase == tcp_connect_big ->
ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+
+ ct:timetrap({seconds, 30}),
+ Config;
+init_per_testcase(rizzo, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 40}),
+ Config;
+init_per_testcase(prf, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 40}),
+ case ?config(tc_group_path, Config) of
+ [] -> Prop = [];
+ [Prop] -> Prop
+ end,
+ case ?config(name, Prop) of
+ undefined -> TlsVersions = [sslv3, tlsv1, 'tlsv1.1', 'tlsv1.2'];
+ TlsVersion when is_atom(TlsVersion) ->
+ TlsVersions = [TlsVersion]
+ end,
+ PRFS=[md5, sha, sha256, sha384, sha512],
+ %All are the result of running tls_v1:prf(PrfAlgo, <<>>, <<>>, <<>>, 16)
+ %with the specified PRF algorithm
+ ExpectedPrfResults=
+ [{md5, <<96,139,180,171,236,210,13,10,28,32,2,23,88,224,235,199>>},
+ {sha, <<95,3,183,114,33,169,197,187,231,243,19,242,220,228,70,151>>},
+ {sha256, <<166,249,145,171,43,95,158,232,6,60,17,90,183,180,0,155>>},
+ {sha384, <<153,182,217,96,186,130,105,85,65,103,123,247,146,91,47,106>>},
+ {sha512, <<145,8,98,38,243,96,42,94,163,33,53,49,241,4,127,28>>},
+ %TLS 1.0 and 1.1 PRF:
+ {md5sha, <<63,136,3,217,205,123,200,177,251,211,17,229,132,4,173,80>>}],
+ TestPlan = prf_create_plan(TlsVersions, PRFS, ExpectedPrfResults),
+ [{prf_test_plan, TestPlan} | Config];
+
+init_per_testcase(TestCase, Config) when TestCase == ssl_accept_timeout;
+ TestCase == client_closes_socket;
+ TestCase == downgrade ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 15}),
+ Config;
+init_per_testcase(clear_pem_cache, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 20}),
+ Config;
+init_per_testcase(raw_ssl_option, Config) ->
+ ct:timetrap({seconds, 5}),
+ case os:type() of
+ {unix,linux} ->
+ Config;
+ _ ->
+ {skip, "Raw options are platform-specific"}
+ end;
+
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 5}),
+ Config.
end_per_testcase(reuse_session_expired, Config) ->
application:unset_env(ssl, session_lifetime),
@@ -347,7 +423,7 @@ alerts(Config) when is_list(Config) ->
end, Alerts).
%%--------------------------------------------------------------------
new_options_in_accept() ->
- [{doc,"Test that you can set ssl options in ssl_accept/3 and not tcp upgrade"}].
+ [{doc,"Test that you can set ssl options in ssl_accept/3 and not only in tcp upgrade"}].
new_options_in_accept(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
ServerOpts0 = ?config(server_dsa_opts, Config),
@@ -365,7 +441,9 @@ new_options_in_accept(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{mfa, {?MODULE, connection_info_result, []}},
- {options, [{versions, [sslv3]} | ClientOpts]}]),
+ {options, [{versions, [sslv3]},
+ {ciphers,[{rsa,rc4_128,sha}
+ ]} | ClientOpts]}]),
ct:log("Testcase ~p, Client ~p Server ~p ~n",
[self(), Client, Server]),
@@ -377,9 +455,28 @@ new_options_in_accept(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+prf() ->
+ [{doc,"Test that ssl:prf/5 uses the negotiated PRF."}].
+prf(Config) when is_list(Config) ->
+ TestPlan = ?config(prf_test_plan, Config),
+ case TestPlan of
+ [] -> ct:fail({error, empty_prf_test_plan});
+ _ -> lists:foreach(fun(Suite) ->
+ lists:foreach(
+ fun(Test) ->
+ V = ?config(tls_ver, Test),
+ C = ?config(ciphers, Test),
+ E = ?config(expected, Test),
+ P = ?config(prf, Test),
+ prf_run_test(Config, V, C, E, P)
+ end, Suite)
+ end, TestPlan)
+ end.
+
+%%--------------------------------------------------------------------
connection_info() ->
- [{doc,"Test the API function ssl:connection_info/1"}].
+ [{doc,"Test the API function ssl:connection_information/1"}].
connection_info(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
@@ -395,7 +492,7 @@ connection_info(Config) when is_list(Config) ->
{from, self()},
{mfa, {?MODULE, connection_info_result, []}},
{options,
- [{ciphers,[{rsa,rc4_128,sha,no_export}]} |
+ [{ciphers,[{rsa,des_cbc,sha}]} |
ClientOpts]}]),
ct:log("Testcase ~p, Client ~p Server ~p ~n",
@@ -404,13 +501,44 @@ connection_info(Config) when is_list(Config) ->
Version =
tls_record:protocol_version(tls_record:highest_protocol_version([])),
- ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha}}},
+ ServerMsg = ClientMsg = {ok, {Version, {rsa, des_cbc, sha}}},
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+connection_information() ->
+ [{doc,"Test the API function ssl:connection_information/1"}].
+connection_information(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_information_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_information_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ServerMsg = ClientMsg = ok,
ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
%%--------------------------------------------------------------------
protocol_versions() ->
[{doc,"Test to set a list of protocol versions in app environment."}].
@@ -633,7 +761,7 @@ clear_pem_cache(Config) when is_list(Config) ->
{status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
- [_,FilRefDb, _] = element(5, State),
+ [_,FilRefDb |_] = element(6, State),
{Server, Client} = basic_verify_test_no_close(Config),
2 = ets:info(FilRefDb, size),
ssl:clear_pem_cache(),
@@ -680,6 +808,14 @@ fallback(Config) when is_list(Config) ->
Client, {error,{tls_alert,"inappropriate fallback"}}).
%%--------------------------------------------------------------------
+cipher_format() ->
+ [{doc, "Test that cipher conversion from tuples to binarys works"}].
+cipher_format(Config) when is_list(Config) ->
+ {ok, Socket} = ssl:listen(0, [{ciphers, ssl:cipher_suites()}]),
+ ssl:close(Socket).
+
+%%--------------------------------------------------------------------
+
peername() ->
[{doc,"Test API function peername/1"}].
@@ -830,6 +966,31 @@ cipher_suites(Config) when is_list(Config) ->
[_|_] =ssl:cipher_suites(openssl).
%%--------------------------------------------------------------------
+cipher_suites_mix() ->
+ [{doc,"Test to have old and new cipher suites at the same time"}].
+
+cipher_suites_mix(Config) when is_list(Config) ->
+ CipherSuites = [{ecdh_rsa,aes_128_cbc,sha256,sha256}, {rsa,aes_128_cbc,sha}],
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{ciphers, CipherSuites} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
socket_options() ->
[{doc,"Test API function getopts/2 and setopts/2"}].
@@ -1116,6 +1277,23 @@ ssl_options_not_proplist(Config) when is_list(Config) ->
BadOption]).
%%--------------------------------------------------------------------
+raw_ssl_option() ->
+ [{doc,"Ensure that a single 'raw' option is passed to ssl:listen correctly."}].
+
+raw_ssl_option(Config) when is_list(Config) ->
+ % 'raw' option values are platform-specific; these are the Linux values:
+ IpProtoTcp = 6,
+ % Use TCP_KEEPIDLE, because (e.g.) TCP_MAXSEG can't be read back reliably.
+ TcpKeepIdle = 4,
+ KeepAliveTimeSecs = 55,
+ LOptions = [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}],
+ {ok, LSocket} = ssl:listen(0, LOptions),
+ % Per http://www.erlang.org/doc/man/inet.html#getopts-2, we have to specify
+ % exactly which raw option we want, and the size of the buffer.
+ {ok, [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}]} = ssl:getopts(LSocket, [{raw, IpProtoTcp, TcpKeepIdle, 4}]).
+
+
+%%--------------------------------------------------------------------
versions() ->
[{doc,"Test API function versions/0"}].
@@ -1371,6 +1549,53 @@ upgrade_with_timeout(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+downgrade() ->
+ [{doc,"Test that you can downgarde an ssl connection to an tcp connection"}].
+downgrade(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_downgrade, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_downgrade, []}},
+ {options, [{active, false} |ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+close_with_timeout() ->
+ [{doc,"Test normal (not downgrade) ssl:close/2"}].
+close_with_timeout(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_close, []}},
+ {options,[{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_close, []}},
+ {options, [{active, false} |ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok).
+
+
+%%--------------------------------------------------------------------
tcp_connect() ->
[{doc,"Test what happens when a tcp tries to connect, i,e. a bad (ssl) packet is sent first"}].
@@ -1408,6 +1633,7 @@ tcp_connect_big(Config) when is_list(Config) ->
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
TcpOpts = [binary, {reuseaddr, true}],
+ Rand = crypto:rand_bytes(?MAX_CIPHER_TEXT_LENGTH+1),
Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
{from, self()},
{timeout, 5000},
@@ -1419,7 +1645,6 @@ tcp_connect_big(Config) when is_list(Config) ->
{ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
ct:log("Testcase ~p connected to Server ~p ~n", [self(), Server]),
- Rand = crypto:rand_bytes(?MAX_CIPHER_TEXT_LENGTH+1),
gen_tcp:send(Socket, <<?BYTE(0),
?BYTE(3), ?BYTE(1), ?UINT16(?MAX_CIPHER_TEXT_LENGTH), Rand/binary>>),
@@ -1811,6 +2036,32 @@ srp_dsa_cipher_suites(Config) when is_list(Config) ->
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
Ciphers = ssl_test_lib:srp_dss_suites(),
run_suites(Ciphers, Version, Config, srp_dsa).
+%%-------------------------------------------------------------------
+rc4_rsa_cipher_suites()->
+ [{doc, "Test the RC4 ciphersuites"}].
+rc4_rsa_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
+ Version = tls_record:protocol_version(NVersion),
+ Ciphers = ssl_test_lib:rc4_suites(NVersion),
+ run_suites(Ciphers, Version, Config, rc4_rsa).
+%-------------------------------------------------------------------
+rc4_ecdh_rsa_cipher_suites()->
+ [{doc, "Test the RC4 ciphersuites"}].
+rc4_ecdh_rsa_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
+ Version = tls_record:protocol_version(NVersion),
+ Ciphers = ssl_test_lib:rc4_suites(NVersion),
+ run_suites(Ciphers, Version, Config, rc4_ecdh_rsa).
+
+%%-------------------------------------------------------------------
+rc4_ecdsa_cipher_suites()->
+ [{doc, "Test the RC4 ciphersuites"}].
+rc4_ecdsa_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
+ Version = tls_record:protocol_version(NVersion),
+ Ciphers = ssl_test_lib:rc4_suites(NVersion),
+ run_suites(Ciphers, Version, Config, rc4_ecdsa).
+
%%--------------------------------------------------------------------
default_reject_anonymous()->
[{doc,"Test that by default anonymous cipher suites are rejected "}].
@@ -2371,7 +2622,7 @@ der_input(Config) when is_list(Config) ->
{status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
- [CADb | _] = element(5, State),
+ [CADb | _] = element(6, State),
[] = ets:tab2list(CADb).
%%--------------------------------------------------------------------
@@ -2539,6 +2790,16 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
ssl_test_lib:close(Client1).
%%--------------------------------------------------------------------
+defaults(Config) when is_list(Config)->
+ [_,
+ {supported, Supported},
+ {available, Available}]
+ = ssl:versions(),
+ true = lists:member(sslv3, Available),
+ false = lists:member(sslv3, Supported),
+ false = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites()),
+ true = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites(all)).
+%%--------------------------------------------------------------------
reuseaddr() ->
[{doc,"Test reuseaddr option"}].
@@ -2663,6 +2924,8 @@ honor_cipher_order(Config, Honor, ServerCiphers, ClientCiphers, Expected) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+ciphersuite_vs_version() ->
+ [{doc,"Test a SSLv3 client can not negotiate a TLSv* cipher suite."}].
ciphersuite_vs_version(Config) when is_list(Config) ->
{_ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -2693,7 +2956,61 @@ ciphersuite_vs_version(Config) when is_list(Config) ->
_ ->
ct:fail({unexpected_server_hello, ServerHello})
end.
-
+
+%%--------------------------------------------------------------------
+conf_signature_algs() ->
+ [{doc,"Test to set the signature_algs option on both client and server"}].
+conf_signature_algs(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false}, {signature_algs, [{sha256, rsa}]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false}, {signature_algs, [{sha256, rsa}]} | ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+no_common_signature_algs() ->
+ [{doc,"Set the signature_algs option so that there client and server does not share any hash sign algorithms"}].
+no_common_signature_algs(Config) when is_list(Config) ->
+
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{signature_algs, [{sha256, rsa}]}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{signature_algs, [{sha384, rsa}]}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "insufficient security"}},
+ Client, {error, {tls_alert, "insufficient security"}}).
+
%%--------------------------------------------------------------------
dont_crash_on_handshake_garbage() ->
@@ -2773,6 +3090,43 @@ hibernate(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+
+hibernate_right_away() ->
+ [{doc,"Check that an SSL connection that is configured to hibernate "
+ "after 0 or 1 milliseconds hibernates as soon as possible and not "
+ "crashes"}].
+
+hibernate_right_away(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ StartServerOpts = [{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}],
+ StartClientOpts = [return_socket,
+ {node, ClientNode},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}}],
+
+ Server1 = ssl_test_lib:start_server(StartServerOpts),
+ Port1 = ssl_test_lib:inet_port(Server1),
+ {Client1, #sslsocket{}} = ssl_test_lib:start_client(StartClientOpts ++
+ [{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1),
+
+ Server2 = ssl_test_lib:start_server(StartServerOpts),
+ Port2 = ssl_test_lib:inet_port(Server2),
+ {Client2, #sslsocket{}} = ssl_test_lib:start_client(StartClientOpts ++
+ [{port, Port2}, {options, [{hibernate_after, 1}|ClientOpts]}]),
+ ssl_test_lib:close(Server2),
+ ssl_test_lib:close(Client2).
+
+%%--------------------------------------------------------------------
listen_socket() ->
[{doc,"Check error handling and inet compliance when calling API functions with listen sockets."}].
@@ -2788,7 +3142,7 @@ listen_socket(Config) ->
{error, enotconn} = ssl:send(ListenSocket, <<"data">>),
{error, enotconn} = ssl:recv(ListenSocket, 0),
- {error, enotconn} = ssl:connection_info(ListenSocket),
+ {error, enotconn} = ssl:connection_information(ListenSocket),
{error, enotconn} = ssl:peername(ListenSocket),
{error, enotconn} = ssl:peercert(ListenSocket),
{error, enotconn} = ssl:session_info(ListenSocket),
@@ -2955,8 +3309,36 @@ renegotiate_dos_mitigate_passive(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+renegotiate_dos_mitigate_absolute() ->
+ [{doc, "Mitigate DOS computational attack by not allowing client to initiate renegotiation"}].
+renegotiate_dos_mitigate_absolute(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{client_renegotiation, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_rejected,
+ []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
tcp_error_propagation_in_active_mode() ->
- [{doc,"Test that process recives {ssl_error, Socket, closed} when tcp error ocurres"}].
+ [{doc,"Test that process recives {ssl_error, Socket, closed} when tcp error occurs"}].
tcp_error_propagation_in_active_mode(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
@@ -3325,8 +3707,84 @@ basic_test(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+prf_create_plan(TlsVersions, PRFs, Results) ->
+ lists:foldl(fun(Ver, Acc) ->
+ A = prf_ciphers_and_expected(Ver, PRFs, Results),
+ [A|Acc]
+ end, [], TlsVersions).
+prf_ciphers_and_expected(TlsVer, PRFs, Results) ->
+ case TlsVer of
+ TlsVer when TlsVer == sslv3 orelse TlsVer == tlsv1
+ orelse TlsVer == 'tlsv1.1' ->
+ Ciphers = ssl:cipher_suites(),
+ {_, Expected} = lists:keyfind(md5sha, 1, Results),
+ [[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected}, {prf, md5sha}]];
+ 'tlsv1.2' ->
+ lists:foldl(
+ fun(PRF, Acc) ->
+ Ciphers = prf_get_ciphers(TlsVer, PRF),
+ case Ciphers of
+ [] ->
+ ct:log("No ciphers for PRF algorithm ~p. Skipping.", [PRF]),
+ Acc;
+ Ciphers ->
+ {_, Expected} = lists:keyfind(PRF, 1, Results),
+ [[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected},
+ {prf, PRF}] | Acc]
+ end
+ end, [], PRFs)
+ end.
+prf_get_ciphers(TlsVer, PRF) ->
+ case TlsVer of
+ 'tlsv1.2' ->
+ lists:filter(
+ fun(C) when tuple_size(C) == 4 andalso
+ element(4, C) == PRF ->
+ true;
+ (_) -> false
+ end, ssl:cipher_suites())
+ end.
+prf_run_test(_, TlsVer, [], _, Prf) ->
+ ct:fail({error, cipher_list_empty, TlsVer, Prf});
+prf_run_test(Config, TlsVer, Ciphers, Expected, Prf) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ BaseOpts = [{active, true}, {versions, [TlsVer]}, {ciphers, Ciphers}],
+ ServerOpts = BaseOpts ++ ?config(server_opts, Config),
+ ClientOpts = BaseOpts ++ ?config(client_opts, Config),
+ Server = ssl_test_lib:start_server(
+ [{node, ServerNode}, {port, 0}, {from, self()},
+ {mfa, {?MODULE, prf_verify_value, [TlsVer, Expected, Prf]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client(
+ [{node, ClientNode}, {port, Port},
+ {host, Hostname}, {from, self()},
+ {mfa, {?MODULE, prf_verify_value, [TlsVer, Expected, Prf]}},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+prf_verify_value(Socket, TlsVer, Expected, Algo) ->
+ Ret = ssl:prf(Socket, <<>>, <<>>, [<<>>], 16),
+ case TlsVer of
+ sslv3 ->
+ case Ret of
+ {error, undefined} -> ok;
+ _ ->
+ {error, {expected, {error, undefined},
+ got, Ret, tls_ver, TlsVer, prf_algorithm, Algo}}
+ end;
+ _ ->
+ case Ret of
+ {ok, Expected} -> ok;
+ {ok, Val} -> {error, {expected, Expected, got, Val, tls_ver, TlsVer,
+ prf_algorithm, Algo}}
+ end
+ end.
+
send_recv_result_timeout_client(Socket) ->
{error, timeout} = ssl:recv(Socket, 11, 500),
+ {error, timeout} = ssl:recv(Socket, 11, 0),
ssl:send(Socket, "Hello world"),
receive
Msg ->
@@ -3390,23 +3848,43 @@ renegotiate_reuse_session(Socket, Data) ->
renegotiate(Socket, Data).
renegotiate_immediately(Socket) ->
- receive
+ receive
{ssl, Socket, "Hello world"} ->
ok;
%% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast
{ssl, Socket, "H"} ->
- receive
+ receive
{ssl, Socket, "ello world"} ->
ok
end
end,
ok = ssl:renegotiate(Socket),
{error, renegotiation_rejected} = ssl:renegotiate(Socket),
- ct:sleep(?RENEGOTIATION_DISABLE_TIME +1),
+ ct:sleep(?RENEGOTIATION_DISABLE_TIME + ?SLEEP),
ok = ssl:renegotiate(Socket),
ct:log("Renegotiated again"),
ssl:send(Socket, "Hello world"),
ok.
+
+renegotiate_rejected(Socket) ->
+ receive
+ {ssl, Socket, "Hello world"} ->
+ ok;
+ %% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+ {ssl, Socket, "H"} ->
+ receive
+ {ssl, Socket, "ello world"} ->
+ ok
+ end
+ end,
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ ct:sleep(?RENEGOTIATION_DISABLE_TIME +1),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ ct:log("Failed to renegotiate again"),
+ ssl:send(Socket, "Hello world"),
+ ok.
+
new_config(PrivDir, ServerOpts0) ->
CaCertFile = proplists:get_value(cacertfile, ServerOpts0),
@@ -3726,8 +4204,20 @@ run_suites(Ciphers, Version, Config, Type) ->
?config(server_ecdsa_opts, Config)};
ecdh_rsa ->
{?config(client_opts, Config),
- ?config(server_ecdh_rsa_opts, Config)}
- end,
+ ?config(server_ecdh_rsa_opts, Config)};
+ rc4_rsa ->
+ {?config(client_opts, Config),
+ [{ciphers, Ciphers} |
+ ?config(server_opts, Config)]};
+ rc4_ecdh_rsa ->
+ {?config(client_opts, Config),
+ [{ciphers, Ciphers} |
+ ?config(server_ecdh_rsa_opts, Config)]};
+ rc4_ecdsa ->
+ {?config(client_opts, Config),
+ [{ciphers, Ciphers} |
+ ?config(server_ecdsa_opts, Config)]}
+ end,
Result = lists:map(fun(Cipher) ->
cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end,
@@ -3741,13 +4231,14 @@ run_suites(Ciphers, Version, Config, Type) ->
end.
erlang_cipher_suite(Suite) when is_list(Suite)->
- ssl:suite_definition(ssl_cipher:openssl_suite(Suite));
+ ssl_cipher:erl_suite_definition(ssl_cipher:openssl_suite(Suite));
erlang_cipher_suite(Suite) ->
Suite.
cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
%% process_flag(trap_exit, true),
ct:log("Testing CipherSuite ~p~n", [CipherSuite]),
+ ct:log("Server Opts ~p~n", [ServerOpts]),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
ErlangCipherSuite = erlang_cipher_suite(CipherSuite),
@@ -3761,11 +4252,11 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}},
- {options,
- [{ciphers,[CipherSuite]} |
- ClientOpts]}]),
+ {from, self()},
+ {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
Result = ssl_test_lib:wait_for_result(Server, ok, Client, ok),
@@ -3779,11 +4270,22 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
[{ErlangCipherSuite, Error}]
end.
-connection_info_result(Socket) ->
- ssl:connection_info(Socket).
+connection_information_result(Socket) ->
+ {ok, Info = [_ | _]} = ssl:connection_information(Socket),
+ case length(Info) > 3 of
+ true ->
+ %% Atleast one ssloption() is set
+ ct:log("Info ~p", [Info]),
+ ok;
+ false ->
+ ct:fail(no_ssl_options_returned)
+ end.
+connection_info_result(Socket) ->
+ {ok, Info} = ssl:connection_information(Socket, [protocol, cipher_suite]),
+ {ok, {proplists:get_value(protocol, Info), proplists:get_value(cipher_suite, Info)}}.
version_info_result(Socket) ->
- {ok, {Version, _}} = ssl:connection_info(Socket),
+ {ok, [{version, Version}]} = ssl:connection_information(Socket, [version]),
{ok, Version}.
connect_dist_s(S) ->
@@ -3795,6 +4297,33 @@ connect_dist_c(S) ->
{ok, Test} = ssl:recv(S, 0, 10000),
ok.
+tls_downgrade(Socket) ->
+ ok = ssl_test_lib:send_recv_result(Socket),
+ case ssl:close(Socket, {self(), 10000}) of
+ {ok, TCPSocket} ->
+ inet:setopts(TCPSocket, [{active, true}]),
+ gen_tcp:send(TCPSocket, "Downgraded"),
+ receive
+ {tcp, TCPSocket, <<"Downgraded">>} ->
+ ok;
+ {tcp_closed, TCPSocket} ->
+ ct:pal("Peer timed out, downgrade aborted"),
+ ok;
+ Other ->
+ {error, Other}
+ end;
+ {error, timeout} ->
+ ct:pal("Timed out, downgrade aborted"),
+ ok;
+ Fail ->
+ {error, Fail}
+ end.
+
+tls_close(Socket) ->
+ ok = ssl_test_lib:send_recv_result(Socket),
+ ok = ssl:close(Socket, 5000).
+
+
%% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast
treashold(N, {3,0}) ->
(N div 2) + 1;
@@ -3878,6 +4407,12 @@ first_rsa_suite([{dhe_rsa, _, _} = Suite| _]) ->
Suite;
first_rsa_suite([{rsa, _, _} = Suite| _]) ->
Suite;
+first_rsa_suite([{ecdhe_rsa, _, _, _} = Suite | _]) ->
+ Suite;
+first_rsa_suite([{dhe_rsa, _, _, _} = Suite| _]) ->
+ Suite;
+first_rsa_suite([{rsa, _, _, _} = Suite| _]) ->
+ Suite;
first_rsa_suite([_ | Rest]) ->
first_rsa_suite(Rest).
diff --git a/lib/ssl/test/ssl_bench.spec b/lib/ssl/test/ssl_bench.spec
new file mode 100644
index 0000000000..d2f75b4203
--- /dev/null
+++ b/lib/ssl/test/ssl_bench.spec
@@ -0,0 +1 @@
+{suites,"../ssl_test",[ssl_bench_SUITE]}.
diff --git a/lib/ssl/test/ssl_bench_SUITE.erl b/lib/ssl/test/ssl_bench_SUITE.erl
new file mode 100644
index 0000000000..953356c87c
--- /dev/null
+++ b/lib/ssl/test/ssl_bench_SUITE.erl
@@ -0,0 +1,367 @@
+%%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(ssl_bench_SUITE).
+-compile(export_all).
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(remote_host, "NETMARKS_REMOTE_HOST").
+
+suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]}].
+
+all() -> [{group, setup}, {group, payload}].
+
+groups() ->
+ [{setup, [{repeat, 3}], [setup_sequential, setup_concurrent]},
+ {payload, [{repeat, 3}], [payload_simple]}
+ ].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+init_per_suite(Config) ->
+ try
+ Server = setup(ssl, node()),
+ [{server_node, Server}|Config]
+ catch _:_ ->
+ {skipped, "Benchmark machines only"}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_Func, Conf) ->
+ Conf.
+
+end_per_testcase(_Func, _Conf) ->
+ ok.
+
+
+-define(COUNT, 400).
+-define(TC(Cmd), tc(fun() -> Cmd end, ?MODULE, ?LINE)).
+
+-define(FPROF_CLIENT, false).
+-define(FPROF_SERVER, false).
+-define(EPROF_CLIENT, false).
+-define(EPROF_SERVER, false).
+-define(PERCEPT_SERVER, false).
+
+%% Current numbers gives roughly a testcase per minute on todays hardware..
+
+setup_sequential(Config) ->
+ Server = proplists:get_value(server_node, Config),
+ Server =/= undefined orelse error(no_server),
+ {ok, Result} = do_test(ssl, setup_connection, ?COUNT * 20, 1, Server),
+ ct_event:notify(#event{name = benchmark_data,
+ data=[{value, Result},
+ {suite, "ssl"}, {name, "Sequential setup"}]}),
+ ok.
+
+setup_concurrent(Config) ->
+ Server = proplists:get_value(server_node, Config),
+ Server =/= undefined orelse error(no_server),
+ {ok, Result} = do_test(ssl, setup_connection, ?COUNT, 100, Server),
+ ct_event:notify(#event{name = benchmark_data,
+ data=[{value, Result},
+ {suite, "ssl"}, {name, "Concurrent setup"}]}),
+ ok.
+
+payload_simple(Config) ->
+ Server = proplists:get_value(server_node, Config),
+ Server =/= undefined orelse error(no_server),
+ {ok, Result} = do_test(ssl, payload, ?COUNT*300, 10, Server),
+ ct_event:notify(#event{name = benchmark_data,
+ data=[{value, Result},
+ {suite, "ssl"}, {name, "Payload simple"}]}),
+ ok.
+
+
+ssl() ->
+ test(ssl, ?COUNT, node()).
+
+test(Type, Count, Host) ->
+ Server = setup(Type, Host),
+ (do_test(Type, setup_connection, Count * 20, 1, Server)),
+ (do_test(Type, setup_connection, Count, 100, Server)),
+ (do_test(Type, payload, Count*300, 10, Server)),
+ ok.
+
+do_test(Type, TC, Loop, ParallellConnections, Server) ->
+ _ = ssl:stop(),
+ {ok, _} = ensure_all_started(ssl, []),
+
+ {ok, {SPid, Host, Port}} = rpc:call(Server, ?MODULE, setup_server_init,
+ [Type, TC, Loop, ParallellConnections]),
+ link(SPid),
+ Me = self(),
+ Test = fun(Id) ->
+ CData = client_init(Me, Type, TC, Host, Port),
+ receive
+ go ->
+ ?FPROF_CLIENT andalso Id =:= 1 andalso
+ start_profile(fprof, [self(),new]),
+ ?EPROF_CLIENT andalso Id =:= 1 andalso
+ start_profile(eprof, [ssl_connection_sup, ssl_manager]),
+ ok = ?MODULE:TC(Loop, Type, CData),
+ ?FPROF_CLIENT andalso Id =:= 1 andalso
+ stop_profile(fprof, "test_connection_client_res.fprof"),
+ ?EPROF_CLIENT andalso Id =:= 1 andalso
+ stop_profile(eprof, "test_connection_client_res.eprof"),
+ Me ! self()
+ end
+ end,
+ Spawn = fun(Id) ->
+ Pid = spawn(fun() -> Test(Id) end),
+ receive {Pid, init} -> Pid end
+ end,
+ Pids = [Spawn(Id) || Id <- lists:seq(ParallellConnections, 1, -1)],
+ Run = fun() ->
+ [Pid ! go || Pid <- Pids],
+ [receive Pid -> ok end || Pid <- Pids]
+ end,
+ {TimeInMicro, _} = timer:tc(Run),
+ TotalTests = ParallellConnections * Loop,
+ TestPerSecond = 1000000 * TotalTests div TimeInMicro,
+ io:format("TC ~p ~p ~p ~p 1/s~n", [TC, Type, ParallellConnections, TestPerSecond]),
+ unlink(SPid),
+ SPid ! quit,
+ {ok, TestPerSecond}.
+
+server_init(ssl, setup_connection, _, _, Server) ->
+ {ok, Socket} = ssl:listen(0, ssl_opts(listen)),
+ {ok, {_Host, Port}} = ssl:sockname(Socket),
+ {ok, Host} = inet:gethostname(),
+ ?FPROF_SERVER andalso start_profile(fprof, [whereis(ssl_manager), new]),
+ %%?EPROF_SERVER andalso start_profile(eprof, [ssl_connection_sup, ssl_manager]),
+ ?EPROF_SERVER andalso start_profile(eprof, [ssl_manager]),
+ ?PERCEPT_SERVER andalso percept:profile("/tmp/ssl_server.percept"),
+ Server ! {self(), {init, Host, Port}},
+ Test = fun(TSocket) ->
+ ok = ssl:ssl_accept(TSocket),
+ ssl:close(TSocket)
+ end,
+ setup_server_connection(Socket, Test);
+server_init(ssl, payload, Loop, _, Server) ->
+ {ok, Socket} = ssl:listen(0, ssl_opts(listen)),
+ {ok, {_Host, Port}} = ssl:sockname(Socket),
+ {ok, Host} = inet:gethostname(),
+ Server ! {self(), {init, Host, Port}},
+ Test = fun(TSocket) ->
+ ok = ssl:ssl_accept(TSocket),
+ Size = byte_size(msg()),
+ server_echo(TSocket, Size, Loop),
+ ssl:close(TSocket)
+ end,
+ setup_server_connection(Socket, Test);
+
+server_init(Type, Tc, _, _, Server) ->
+ io:format("No server init code for ~p ~p~n",[Type, Tc]),
+ Server ! {self(), no_init}.
+
+client_init(Master, ssl, setup_connection, Host, Port) ->
+ Master ! {self(), init},
+ {Host, Port, ssl_opts(connect)};
+client_init(Master, ssl, payload, Host, Port) ->
+ {ok, Sock} = ssl:connect(Host, Port, ssl_opts(connect)),
+ Master ! {self(), init},
+ Size = byte_size(msg()),
+ {Sock, Size};
+client_init(_Me, Type, Tc, Host, Port) ->
+ io:format("No client init code for ~p ~p~n",[Type, Tc]),
+ {Host, Port}.
+
+setup_server_connection(LSocket, Test) ->
+ receive quit ->
+ ?FPROF_SERVER andalso stop_profile(fprof, "test_server_res.fprof"),
+ ?EPROF_SERVER andalso stop_profile(eprof, "test_server_res.eprof"),
+ ?PERCEPT_SERVER andalso stop_profile(percept, "/tmp/ssl_server.percept"),
+ ok
+ after 0 ->
+ case ssl:transport_accept(LSocket, 2000) of
+ {ok, TSocket} -> spawn_link(fun() -> Test(TSocket) end);
+ {error, timeout} -> ok
+ end,
+ setup_server_connection(LSocket, Test)
+ end.
+
+server_echo(Socket, Size, Loop) when Loop > 0 ->
+ {ok, Msg} = ssl:recv(Socket, Size),
+ ok = ssl:send(Socket, Msg),
+ server_echo(Socket, Size, Loop-1);
+server_echo(_, _, _) -> ok.
+
+setup_connection(N, ssl, Env = {Host, Port, Opts}) when N > 0 ->
+ case ssl:connect(Host, Port, Opts) of
+ {ok, Sock} ->
+ ssl:close(Sock),
+ setup_connection(N-1, ssl, Env);
+ {error, Error} ->
+ io:format("Error: ~p (~p)~n",[Error, length(erlang:ports())]),
+ setup_connection(N, ssl, Env)
+ end;
+setup_connection(_, _, _) ->
+ ok.
+
+payload(Loop, ssl, D = {Socket, Size}) when Loop > 0 ->
+ ok = ssl:send(Socket, msg()),
+ {ok, _} = ssl:recv(Socket, Size),
+ payload(Loop-1, ssl, D);
+payload(_, _, {Socket, _}) ->
+ ssl:close(Socket).
+
+msg() ->
+ <<"Hello",
+ 0:(512*8),
+ "asdlkjsafsdfoierwlejsdlkfjsdf",
+ 1:(512*8),
+ "asdlkjsafsdfoierwlejsdlkfjsdf">>.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+setup(_Type, nonode@nohost) ->
+ exit(dist_not_enabled);
+setup(Type, _This) ->
+ Host = case os:getenv(?remote_host) of
+ false ->
+ {ok, This} = inet:gethostname(),
+ This;
+ RemHost ->
+ RemHost
+ end,
+ Node = list_to_atom("perf_server@" ++ Host),
+ SlaveArgs = case init:get_argument(pa) of
+ {ok, PaPaths} ->
+ lists:append([" -pa " ++ P || [P] <- PaPaths]);
+ _ -> []
+ end,
+ %% io:format("Slave args: ~p~n",[SlaveArgs]),
+ Prog =
+ case os:find_executable("erl") of
+ false -> "erl";
+ P -> P
+ end,
+ io:format("Prog = ~p~n", [Prog]),
+
+ case net_adm:ping(Node) of
+ pong -> ok;
+ pang ->
+ {ok, Node} = slave:start(Host, perf_server, SlaveArgs, no_link, Prog)
+ end,
+ Path = code:get_path(),
+ true = rpc:call(Node, code, set_path, [Path]),
+ ok = rpc:call(Node, ?MODULE, setup_server, [Type, node()]),
+ io:format("Client (~p) using ~s~n",[node(), code:which(ssl)]),
+ (Node =:= node()) andalso restrict_schedulers(client),
+ Node.
+
+setup_server(_Type, ClientNode) ->
+ (ClientNode =:= node()) andalso restrict_schedulers(server),
+ io:format("Server (~p) using ~s~n",[node(), code:which(ssl)]),
+ ok.
+
+
+ensure_all_started(App, Ack) ->
+ case application:start(App) of
+ ok -> {ok, [App|Ack]};
+ {error, {not_started, Dep}} ->
+ {ok, Ack1} = ensure_all_started(Dep, Ack),
+ ensure_all_started(App, Ack1);
+ {error, {already_started, _}} ->
+ {ok, Ack}
+ end.
+
+setup_server_init(Type, Tc, Loop, PC) ->
+ _ = ssl:stop(),
+ {ok, _} = ensure_all_started(ssl, []),
+ Me = self(),
+ Pid = spawn_link(fun() -> server_init(Type, Tc, Loop, PC, Me) end),
+ Res = receive
+ {Pid, {init, Host, Port}} -> {ok, {Pid, Host, Port}};
+ {Pid, Error} -> {error, Error}
+ end,
+ unlink(Pid),
+ Res.
+
+restrict_schedulers(Type) ->
+ %% We expect this to run on 8 core machine
+ Extra0 = 1,
+ Extra = if (Type =:= server) -> -Extra0; true -> Extra0 end,
+ Scheds = erlang:system_info(schedulers),
+ erlang:system_flag(schedulers_online, (Scheds div 2) + Extra).
+
+tc(Fun, Mod, Line) ->
+ case timer:tc(Fun) of
+ {_,{'EXIT',Reason}} ->
+ io:format("Process EXITED ~p:~p \n", [Mod, Line]),
+ exit(Reason);
+ {_T,R={error,_}} ->
+ io:format("Process Error ~p:~p \n", [Mod, Line]),
+ R;
+ {T,R} ->
+ io:format("~p:~p: Time: ~p\n", [Mod, Line, T]),
+ R
+ end.
+
+start_profile(eprof, Procs) ->
+ profiling = eprof:start_profiling(Procs),
+ io:format("(E)Profiling ...",[]);
+start_profile(fprof, Procs) ->
+ fprof:trace([start, {procs, Procs}]),
+ io:format("(F)Profiling ...",[]).
+
+stop_profile(percept, File) ->
+ percept:stop_profile(),
+ percept:analyze(File),
+ {started, _Host, Port} = percept:start_webserver(),
+ wx:new(),
+ wx_misc:launchDefaultBrowser("http://" ++ net_adm:localhost() ++ ":" ++ integer_to_list(Port)),
+ ok;
+stop_profile(eprof, File) ->
+ profiling_stopped = eprof:stop_profiling(),
+ eprof:log(File),
+ io:format(".analysed => ~s ~n",[File]),
+ eprof:analyze(total),
+ eprof:stop();
+stop_profile(fprof, File) ->
+ fprof:trace(stop),
+ io:format("..collect..",[]),
+ fprof:profile(),
+ fprof:analyse([{dest, File},{totals, true}]),
+ io:format(".analysed => ~s ~n",[File]),
+ fprof:stop(),
+ ok.
+
+ssl_opts(listen) ->
+ [{backlog, 500} | ssl_opts("server")];
+ssl_opts(connect) ->
+ [{verify, verify_peer}
+ | ssl_opts("client")];
+ssl_opts(Role) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ [{active, false},
+ {depth, 2},
+ {reuseaddr, true},
+ {mode,binary},
+ {nodelay, true},
+ {ciphers, [{dhe_rsa,aes_256_cbc,sha}]},
+ {cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
+ {certfile, filename:join([Dir, Role, "cert.pem"])},
+ {keyfile, filename:join([Dir, Role, "key.pem"])}].
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index dab7a941db..d10506cb69 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.2
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,9 +38,6 @@
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[{group, active},
{group, passive},
@@ -68,7 +66,9 @@ tests() ->
invalid_signature_client,
invalid_signature_server,
extended_key_usage_verify_peer,
- extended_key_usage_verify_none].
+ extended_key_usage_verify_none,
+ critical_extension_verify_peer,
+ critical_extension_verify_none].
error_handling_tests()->
[client_with_cert_cipher_suites_handshake,
@@ -77,23 +77,19 @@ error_handling_tests()->
unknown_server_ca_accept_verify_none,
unknown_server_ca_accept_verify_peer,
unknown_server_ca_accept_backwardscompatibility,
- no_authority_key_identifier].
+ no_authority_key_identifier,
+ no_authority_key_identifier_and_nonstandard_encoding].
init_per_suite(Config0) ->
- Dog = ct:timetrap(?LONG_TIMEOUT *2),
catch crypto:stop(),
try crypto:start() of
ok ->
ssl:start(),
%% make rsa certs using oppenssl
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- ct:log("Make certs ~p~n", [Result]),
-
- Config1 = ssl_test_lib:make_dsa_cert(Config0),
- Config = ssl_test_lib:cert_options(Config1),
- [{watchdog, Dog} | Config]
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
+ Config = ssl_test_lib:make_dsa_cert(Config0),
+ ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
end.
@@ -114,6 +110,14 @@ init_per_group(_, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -793,6 +797,121 @@ extended_key_usage_verify_none(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+critical_extension_verify_peer() ->
+ [{doc,"Test cert that has a critical unknown extension in verify_peer mode"}].
+
+critical_extension_verify_peer(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Active = ?config(active, Config),
+ ReceiveFunction = ?config(receive_function, Config),
+
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ NewCertName = integer_to_list(erlang:unique_integer()) ++ ".pem",
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join([PrivDir, "server", NewCertName]),
+ add_critical_netscape_cert_type(ServerCertFile, NewServerCertFile, KeyFile),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ NewClientCertFile = filename:join([PrivDir, "client", NewCertName]),
+ add_critical_netscape_cert_type(ClientCertFile, NewClientCertFile, KeyFile),
+ NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error(
+ [{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{verify, verify_peer}, {active, Active} | NewServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error(
+ [{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{verify, verify_peer}, {active, Active} | NewClientOpts]}]),
+
+ %% This certificate has a critical extension that we don't
+ %% understand. Therefore, verification should fail.
+ tcp_delivery_workaround(Server, {error, {tls_alert, "unsupported certificate"}},
+ Client, {error, {tls_alert, "unsupported certificate"}}),
+
+ ssl_test_lib:close(Server),
+ ok.
+
+%%--------------------------------------------------------------------
+critical_extension_verify_none() ->
+ [{doc,"Test cert that has a critical unknown extension in verify_none mode"}].
+
+critical_extension_verify_none(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Active = ?config(active, Config),
+ ReceiveFunction = ?config(receive_function, Config),
+
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ NewCertName = integer_to_list(erlang:unique_integer()) ++ ".pem",
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join([PrivDir, "server", NewCertName]),
+ add_critical_netscape_cert_type(ServerCertFile, NewServerCertFile, KeyFile),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ NewClientCertFile = filename:join([PrivDir, "client", NewCertName]),
+ add_critical_netscape_cert_type(ClientCertFile, NewClientCertFile, KeyFile),
+ NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server(
+ [{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{verify, verify_none}, {active, Active} | NewServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client(
+ [{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{verify, verify_none}, {active, Active} | NewClientOpts]}]),
+
+ %% This certificate has a critical extension that we don't
+ %% understand. But we're using `verify_none', so verification
+ %% shouldn't fail.
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ok.
+
+add_critical_netscape_cert_type(CertFile, NewCertFile, KeyFile) ->
+ [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
+
+ [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(CertFile),
+ OTPCert = public_key:pkix_decode_cert(DerCert, otp),
+ %% This is the "Netscape Cert Type" extension, telling us that the
+ %% certificate can be used for SSL clients and SSL servers.
+ NetscapeCertTypeExt = #'Extension'{
+ extnID = {2,16,840,1,113730,1,1},
+ critical = true,
+ extnValue = <<3,2,6,192>>},
+ OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
+ Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions,
+ NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{
+ extensions = [NetscapeCertTypeExt] ++ Extensions},
+ NewDerCert = public_key:pkix_sign(NewOTPTbsCert, Key),
+ ssl_test_lib:der_to_pem(NewCertFile, [{'Certificate', NewDerCert, not_encrypted}]),
+ ok.
+
+%%--------------------------------------------------------------------
no_authority_key_identifier() ->
[{doc, "Test cert that does not have authorityKeyIdentifier extension"
" but are present in trusted certs db."}].
@@ -849,6 +968,68 @@ delete_authority_key_extension([Head | Rest], Acc) ->
%%--------------------------------------------------------------------
+no_authority_key_identifier_and_nonstandard_encoding() ->
+ [{doc, "Test cert with nonstandard encoding that does not have"
+ " authorityKeyIdentifier extension but are present in trusted certs db."}].
+
+no_authority_key_identifier_and_nonstandard_encoding(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ NewCertFile = filename:join(PrivDir, "server/new_cert.pem"),
+ [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(CertFile),
+ ServerCert = public_key:pkix_decode_cert(DerCert, plain),
+ ServerTbsCert = ServerCert#'Certificate'.tbsCertificate,
+ Extensions0 = ServerTbsCert#'TBSCertificate'.extensions,
+ %% need to remove authorityKeyIdentifier extension to cause DB lookup by signature
+ Extensions = delete_authority_key_extension(Extensions0, []),
+ NewExtensions = replace_key_usage_extension(Extensions, []),
+ NewServerTbsCert = ServerTbsCert#'TBSCertificate'{extensions = NewExtensions},
+
+ ct:log("Extensions ~p~n, NewExtensions: ~p~n", [Extensions, NewExtensions]),
+
+ TbsDer = public_key:pkix_encode('TBSCertificate', NewServerTbsCert, plain),
+ Sig = public_key:sign(TbsDer, md5, Key),
+ NewServerCert = ServerCert#'Certificate'{tbsCertificate = NewServerTbsCert, signature = Sig},
+ NewDerCert = public_key:pkix_encode('Certificate', NewServerCert, plain),
+ ssl_test_lib:der_to_pem(NewCertFile, [{'Certificate', NewDerCert, not_encrypted}]),
+ NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ send_recv_result_active, []}},
+ {options, [{active, true} | NewServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ send_recv_result_active, []}},
+ {options, [{verify, verify_peer} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+replace_key_usage_extension([], Acc) ->
+ lists:reverse(Acc);
+replace_key_usage_extension([#'Extension'{extnID = ?'id-ce-keyUsage'} = E | Rest], Acc) ->
+ %% A nonstandard DER encoding of [digitalSignature, keyEncipherment]
+ Val = <<3, 2, 0, 16#A0>>,
+ replace_key_usage_extension(Rest, [E#'Extension'{extnValue = Val} | Acc]);
+replace_key_usage_extension([Head | Rest], Acc) ->
+ replace_key_usage_extension(Rest, [Head | Acc]).
+
+%%--------------------------------------------------------------------
+
invalid_signature_server() ->
[{doc,"Test client with invalid signature"}].
diff --git a/lib/ssl/test/ssl_cipher_SUITE.erl b/lib/ssl/test/ssl_cipher_SUITE.erl
index 0e48b674e0..b8096c5d7a 100644
--- a/lib/ssl/test/ssl_cipher_SUITE.erl
+++ b/lib/ssl/test/ssl_cipher_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,14 +30,9 @@
-include("ssl_cipher.hrl").
-include("ssl_alert.hrl").
--define(TIMEOUT, 600000).
-
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[aes_decipher_good, aes_decipher_fail, padding_test].
@@ -61,10 +57,9 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-init_per_testcase(_TestCase, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 5}),
+ Config.
end_per_testcase(_TestCase, Config) ->
Config.
@@ -84,13 +79,11 @@ aes_decipher_good(Config) when is_list(Config) ->
decipher_check_good(HashSz, CipherState, {3,3}).
%%--------------------------------------------------------------------
-
aes_decipher_fail() ->
[{doc,"Decipher a known cryptotext using a incorrect key"}].
aes_decipher_fail(Config) when is_list(Config) ->
HashSz = 32,
-
CipherState = incorrect_cipher_state(),
decipher_check_fail(HashSz, CipherState, {3,0}),
decipher_check_fail(HashSz, CipherState, {3,1}),
@@ -110,37 +103,37 @@ padding_test(Config) when is_list(Config) ->
% Internal functions --------------------------------------------------------
%%--------------------------------------------------------------------
decipher_check_good(HashSz, CipherState, Version) ->
- {Content, NextIV, Mac} = content_nextiv_mac(Version),
- {Content, Mac, #cipher_state{iv = NextIV}} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, aes_fragment(Version), Version, true).
+ {Content, _NextIV, Mac} = content_nextiv_mac(Version),
+ {Content, Mac, _} =
+ ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, aes_fragment(Version), Version, true).
decipher_check_fail(HashSz, CipherState, Version) ->
{Content, NextIV, Mac} = content_nextiv_mac(Version),
true = {Content, Mac, #cipher_state{iv = NextIV}} =/=
- ssl_cipher:decipher(?AES, HashSz, CipherState, aes_fragment(Version), Version, true).
+ ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, aes_fragment(Version), Version, true).
pad_test(HashSz, CipherState, {3,0} = Version) ->
%% 3.0 does not have padding test
{Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
{Content, Mac, #cipher_state{iv = NextIV}} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, true),
+ ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, true),
{Content, Mac, #cipher_state{iv = NextIV}} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, false);
+ ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, false);
pad_test(HashSz, CipherState, {3,1} = Version) ->
%% 3.1 should have padding test, but may be disabled
{Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
BadCont = badpad_content(Content),
{Content, Mac, #cipher_state{iv = NextIV}} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,1}) , {3,1}, false),
+ ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,1}) , {3,1}, false),
{BadCont, Mac, #cipher_state{iv = NextIV}} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,1}), {3,1}, true);
+ ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,1}), {3,1}, true);
pad_test(HashSz, CipherState, Version) ->
%% 3.2 and 3.3 must have padding test
{Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
BadCont = badpad_content(Content),
- {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState,
+ {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES_CBC, HashSz, CipherState,
badpad_aes_fragment(Version), Version, false),
- {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState,
+ {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES_CBC, HashSz, CipherState,
badpad_aes_fragment(Version), Version, true).
aes_fragment({3,N}) when N == 0; N == 1->
@@ -164,7 +157,7 @@ badpad_aes_fragment(_) ->
content_nextiv_mac({3,N}) when N == 0; N == 1 ->
{<<"HELLO\n">>,
- <<33,0, 177,251, 91,44, 247,53, 183,198, 165,63, 20,194, 159,107>>,
+ <<72,196,247,97,62,213,222,109,210,204,217,186,172,184, 197,148>>,
<<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>};
content_nextiv_mac(_) ->
{<<"HELLO\n">>,
@@ -193,3 +186,4 @@ correct_cipher_state() ->
incorrect_cipher_state() ->
#cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>}.
+
diff --git a/lib/ssl/test/ssl_crl_SUITE.erl b/lib/ssl/test/ssl_crl_SUITE.erl
index bad0949ec4..5b86027210 100644
--- a/lib/ssl/test/ssl_crl_SUITE.erl
+++ b/lib/ssl/test/ssl_crl_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,54 +27,41 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("public_key/include/public_key.hrl").
--define(TIMEOUT, 120000).
--define(LONG_TIMEOUT, 600000).
--define(SLEEP, 1000).
--define(OPENSSL_RENEGOTIATE, "R\n").
--define(OPENSSL_QUIT, "Q\n").
--define(OPENSSL_GARBAGE, "P\n").
--define(EXPIRE, 10).
-
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[
- {group, basic},
- {group, v1_crl},
- {group, idp_crl}
+ {group, check_true},
+ {group, check_peer},
+ {group, check_best_effort}
].
groups() ->
- [{basic, [], basic_tests()},
- {v1_crl, [], v1_crl_tests()},
- {idp_crl, [], idp_crl_tests()}].
+ [
+ {check_true, [], [{group, v2_crl},
+ {group, v1_crl},
+ {group, idp_crl}]},
+ {check_peer, [], [{group, v2_crl},
+ {group, v1_crl},
+ {group, idp_crl}]},
+ {check_best_effort, [], [{group, v2_crl},
+ {group, v1_crl},
+ {group, idp_crl}]},
+ {v2_crl, [], basic_tests()},
+ {v1_crl, [], basic_tests()},
+ {idp_crl, [], basic_tests()}].
basic_tests() ->
- [crl_verify_valid, crl_verify_revoked].
-
-v1_crl_tests() ->
- [crl_verify_valid, crl_verify_revoked].
+ [crl_verify_valid, crl_verify_revoked, crl_verify_no_crl].
-idp_crl_tests() ->
- [crl_verify_valid, crl_verify_revoked].
-%%%================================================================
-%%% Suite init/end
-
-init_per_suite(Config0) ->
- Dog = ct:timetrap(?LONG_TIMEOUT *2),
+init_per_suite(Config) ->
case os:find_executable("openssl") of
false ->
{skip, "Openssl not found"};
_ ->
- TLSVersion = ?config(tls_version, Config0),
OpenSSL_version = (catch os:cmd("openssl version")),
- ct:log("TLS version: ~p~nOpenSSL version: ~p~n~n~p:module_info(): ~p~n~nssl:module_info(): ~p~n",
- [TLSVersion, OpenSSL_version, ?MODULE, ?MODULE:module_info(), ssl:module_info()]),
case ssl_test_lib:enough_openssl_crl_support(OpenSSL_version) of
false ->
{skip, io_lib:format("Bad openssl version: ~p",[OpenSSL_version])};
@@ -81,16 +69,14 @@ init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
{ok, Hostname0} = inet:gethostname(),
IPfamily =
case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts,[])) of
true -> inet6;
false -> inet
end,
- [{ipfamily,IPfamily}, {watchdog, Dog}, {openssl_version,OpenSSL_version} | Config0]
- catch _C:_E ->
- ct:log("crypto:start() caught ~p:~p",[_C,_E]),
+ [{ipfamily,IPfamily}, {openssl_version,OpenSSL_version} | Config]
+ catch _:_ ->
{skip, "Crypto did not start"}
end
end
@@ -100,443 +86,228 @@ end_per_suite(_Config) ->
ssl:stop(),
application:stop(crypto).
-%%%================================================================
-%%% Group init/end
-
-init_per_group(Group, Config) ->
- ssl:start(),
- inets:start(),
- CertDir = filename:join(?config(priv_dir, Config), Group),
- DataDir = ?config(data_dir, Config),
- ServerRoot = make_dir_path([?config(priv_dir,Config), Group, tmp]),
- %% start a HTTP server to serve the CRLs
- {ok, Httpd} = inets:start(httpd, [{ipfamily, ?config(ipfamily,Config)},
- {server_name, "localhost"}, {port, 0},
- {server_root, ServerRoot},
- {document_root, CertDir},
- {modules, [mod_get]}
- ]),
- [{port,Port}] = httpd:info(Httpd, [port]),
- ct:log("~p:~p~nHTTPD IP family=~p, port=~p~n", [?MODULE, ?LINE, ?config(ipfamily,Config), Port]),
- CertOpts = [{crl_port,Port}|cert_opts(Group)],
- Result = make_certs:all(DataDir, CertDir, CertOpts),
- ct:log("~p:~p~nmake_certs:all(~n DataDir=~p,~n CertDir=~p,~n ServerRoot=~p~n Opts=~p~n) returned ~p~n", [?MODULE,?LINE,DataDir, CertDir, ServerRoot, CertOpts, Result]),
- [{make_cert_result, Result}, {cert_dir, CertDir}, {httpd, Httpd} | Config].
-
-cert_opts(v1_crl) -> [{v2_crls, false}];
-cert_opts(idp_crl) -> [{issuing_distribution_point, true}];
-cert_opts(_) -> [].
-
-make_dir_path(PathComponents) ->
- lists:foldl(fun(F,P0) -> file:make_dir(P=filename:join(P0,F)), P end,
- "",
- PathComponents).
-
+init_per_group(check_true, Config) ->
+ [{crl_check, true} | Config];
+init_per_group(check_peer, Config) ->
+ [{crl_check, peer} | Config];
+init_per_group(check_best_effort, Config) ->
+ [{crl_check, best_effort} | Config];
+init_per_group(Group, Config0) ->
+ case is_idp(Group) of
+ true ->
+ [{idp_crl, true} | Config0];
+ false ->
+ DataDir = ?config(data_dir, Config0),
+ CertDir = filename:join(?config(priv_dir, Config0), Group),
+ {CertOpts, Config} = init_certs(CertDir, Group, Config0),
+ {ok, _} = make_certs:all(DataDir, CertDir, CertOpts),
+ [{cert_dir, CertDir}, {idp_crl, false} | Config]
+ end.
end_per_group(_GroupName, Config) ->
- case ?config(httpd, Config) of
- undefined -> ok;
- Pid ->
- ct:log("Stop httpd ~p",[Pid]),
- ok = inets:stop(httpd, Pid)
- ,ct:log("Stopped",[])
- end,
- inets:stop(),
+
Config.
+init_per_testcase(Case, Config0) ->
+ case ?config(idp_crl, Config0) of
+ true ->
+ end_per_testcase(Case, Config0),
+ inets:start(),
+ ssl:start(),
+ ServerRoot = make_dir_path([?config(priv_dir, Config0), idp_crl, tmp]),
+ %% start a HTTP server to serve the CRLs
+ {ok, Httpd} = inets:start(httpd, [{ipfamily, ?config(ipfamily, Config0)},
+ {server_name, "localhost"}, {port, 0},
+ {server_root, ServerRoot},
+ {document_root,
+ filename:join(?config(priv_dir, Config0), idp_crl)}
+ ]),
+ [{port,Port}] = httpd:info(Httpd, [port]),
+ Config = [{httpd_port, Port} | Config0],
+ DataDir = ?config(data_dir, Config),
+ CertDir = filename:join(?config(priv_dir, Config0), idp_crl),
+ {CertOpts, Config} = init_certs(CertDir, idp_crl, Config),
+ {ok, _} = make_certs:all(DataDir, CertDir, CertOpts),
+ ct:timetrap({seconds, 6}),
+ [{cert_dir, CertDir} | Config];
+ false ->
+ end_per_testcase(Case, Config0),
+ ssl:start(),
+ Config0
+ end.
+
+end_per_testcase(_, Config) ->
+ case ?config(idp_crl, Config) of
+ true ->
+ ssl:stop(),
+ inets:stop();
+ false ->
+ ssl:stop()
+ end.
+
%%%================================================================
%%% Test cases
+%%%================================================================
crl_verify_valid() ->
[{doc,"Verify a simple valid CRL chain"}].
crl_verify_valid(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
PrivDir = ?config(cert_dir, Config),
- ServerOpts = [{keyfile, filename:join([PrivDir, "server", "key.pem"])},
- {certfile, filename:join([PrivDir, "server", "cert.pem"])},
- {cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])}],
-
+ Check = ?config(crl_check, Config),
+ ServerOpts = [{keyfile, filename:join([PrivDir, "server", "key.pem"])},
+ {certfile, filename:join([PrivDir, "server", "cert.pem"])},
+ {cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])}],
+ ClientOpts = case ?config(idp_crl, Config) of
+ true ->
+ [{cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])},
+ {crl_check, Check},
+ {crl_cache, {ssl_crl_cache, {internal, [{http, 5000}]}}},
+ {verify, verify_peer}];
+ false ->
+ [{cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])},
+ {crl_check, Check},
+ {verify, verify_peer}]
+ end,
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- %{mfa, {ssl_test_lib, no_result, []}},
- {options, ServerOpts}]),
- ct:log("~p:~p~nreturn from ssl_test_lib:start_server:~n~p",[?MODULE,?LINE,Server]),
- Port = ssl_test_lib:inet_port(Server),
-
- CACerts = load_cert(filename:join([PrivDir, "erlangCA", "cacerts.pem"])),
- ClientOpts = [{cacerts, CACerts},
- {verify, verify_peer},
- {verify_fun, {fun validate_function/3, {CACerts, []}}}],
-
-
- ct:log("~p:~p~ncalling ssl_test_lib:start_client",[?MODULE,?LINE]),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_send, [Data]}},
- %{mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
- ct:log("~p:~p~nreturn from ssl_test_lib:start_client:~n~p",[?MODULE,?LINE,Client]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
+ ssl_crl_cache:insert({file, filename:join([PrivDir, "erlangCA", "crl.pem"])}),
+ ssl_crl_cache:insert({file, filename:join([PrivDir, "otpCA", "crl.pem"])}),
+
+ crl_verify_valid(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts).
crl_verify_revoked() ->
- [{doc,"Verify a simple valid CRL chain"}].
-crl_verify_revoked(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
+ [{doc,"Verify a simple CRL chain when peer cert is reveoked"}].
+crl_verify_revoked(Config) when is_list(Config) ->
PrivDir = ?config(cert_dir, Config),
+ Check = ?config(crl_check, Config),
ServerOpts = [{keyfile, filename:join([PrivDir, "revoked", "key.pem"])},
- {certfile, filename:join([PrivDir, "revoked", "cert.pem"])},
- {cacertfile, filename:join([PrivDir, "revoked", "cacerts.pem"])}],
- ct:log("~p:~p~nserver opts ~p~n", [?MODULE,?LINE, ServerOpts]),
+ {certfile, filename:join([PrivDir, "revoked", "cert.pem"])},
+ {cacertfile, filename:join([PrivDir, "revoked", "cacerts.pem"])}],
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- %{mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
+ ssl_crl_cache:insert({file, filename:join([PrivDir, "erlangCA", "crl.pem"])}),
+ ssl_crl_cache:insert({file, filename:join([PrivDir, "otpCA", "crl.pem"])}),
+
+ ClientOpts = case ?config(idp_crl, Config) of
+ true ->
+ [{cacertfile, filename:join([PrivDir, "revoked", "cacerts.pem"])},
+ {crl_cache, {ssl_crl_cache, {internal, [{http, 5000}]}}},
+ {crl_check, Check},
+ {verify, verify_peer}];
+ false ->
+ [{cacertfile, filename:join([PrivDir, "revoked", "cacerts.pem"])},
+ {crl_check, Check},
+ {verify, verify_peer}]
+ end,
+
+ crl_verify_error(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts,
+ "certificate revoked").
+
+crl_verify_no_crl() ->
+ [{doc,"Verify a simple CRL chain when the CRL is missing"}].
+crl_verify_no_crl(Config) when is_list(Config) ->
+ PrivDir = ?config(cert_dir, Config),
+ Check = ?config(crl_check, Config),
+ ServerOpts = [{keyfile, filename:join([PrivDir, "server", "key.pem"])},
+ {certfile, filename:join([PrivDir, "server", "cert.pem"])},
+ {cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])}],
+ ClientOpts = case ?config(idp_crl, Config) of
+ true ->
+ [{cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])},
+ {crl_check, Check},
+ {crl_cache, {ssl_crl_cache, {internal, [{http, 5000}]}}},
+ {verify, verify_peer}];
+ false ->
+ [{cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])},
+ {crl_check, Check},
+ {verify, verify_peer}]
+ end,
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- CACerts = load_cert(filename:join([PrivDir, "erlangCA", "cacerts.pem"])),
- ClientOpts = [{cacerts, CACerts},
- {verify, verify_peer},
- {verify_fun, {fun validate_function/3, {CACerts, []}}}],
+ %% In case we're running an HTTP server that serves CRLs, let's
+ %% rename those files, so the CRL is absent when we try to verify
+ %% it.
+ %%
+ %% If we're not using an HTTP server, we just need to refrain from
+ %% adding the CRLs to the cache manually.
+ rename_crl(filename:join([PrivDir, "erlangCA", "crl.pem"])),
+ rename_crl(filename:join([PrivDir, "otpCA", "crl.pem"])),
+
+ %% The expected outcome when the CRL is missing depends on the
+ %% crl_check setting.
+ case Check of
+ true ->
+ %% The error "revocation status undetermined" gets turned
+ %% into "bad certificate".
+ crl_verify_error(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts,
+ "bad certificate");
+ peer ->
+ crl_verify_error(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts,
+ "bad certificate");
+ best_effort ->
+ %% In "best effort" mode, we consider the certificate not
+ %% to be revoked if we can't find the appropriate CRL.
+ crl_verify_valid(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts)
+ end.
- {connect_failed, _} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+crl_verify_valid(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
- %{mfa, {?MODULE,
- %erlang_ssl_receive, [Data]}},
- {mfa, {ssl_test_lib, no_result, []}},
+ {mfa, {ssl_test_lib,
+ send_recv_result_active, []}},
{options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
- %% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
- process_flag(trap_exit, false).
+ ssl_test_lib:close(Client).
-%%%================================================================
-%%% Lib
+crl_verify_error(Hostname, ServerNode, ServerOpts, ClientNode, ClientOpts, ExpectedAlert) ->
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
-erlang_ssl_receive(Socket, Data) ->
- ct:log("~p:~p~nConnection info: ~p~n",
- [?MODULE,?LINE, ssl:connection_info(Socket)]),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
receive
- {ssl, Socket, Data} ->
- ct:log("~p:~p~nReceived ~p~n",[?MODULE,?LINE, Data]),
- %% open_ssl server sometimes hangs waiting in blocking read
- ssl:send(Socket, "Got it"),
- ok;
- {ssl, Socket, Byte} when length(Byte) == 1 ->
- erlang_ssl_receive(Socket, tl(Data));
- {Port, {data,Debug}} when is_port(Port) ->
- ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]),
- erlang_ssl_receive(Socket,Data);
- Other ->
- ct:fail({unexpected_message, Other})
- after 4000 ->
- ct:fail({did_not_get, Data})
- end.
-
-
-erlang_ssl_send(Socket, Data) ->
- ct:log("~p:~p~nConnection info: ~p~n",
- [?MODULE,?LINE, ssl:connection_info(Socket)]),
- ssl:send(Socket, Data),
- ok.
-
-load_certs(undefined) ->
- undefined;
-load_certs(CertDir) ->
- case file:list_dir(CertDir) of
- {ok, Certs} ->
- load_certs(lists:map(fun(Cert) -> filename:join(CertDir, Cert)
- end, Certs), []);
- {error, _} ->
- undefined
- end.
-
-load_certs([], Acc) ->
- ct:log("~p:~p~nSuccessfully loaded ~p CA certificates~n", [?MODULE,?LINE, length(Acc)]),
- Acc;
-load_certs([Cert|Certs], Acc) ->
- case filelib:is_dir(Cert) of
- true ->
- load_certs(Certs, Acc);
- _ ->
- %ct:log("~p:~p~nLoading certificate ~p~n", [?MODULE,?LINE, Cert]),
- load_certs(Certs, load_cert(Cert) ++ Acc)
- end.
-
-load_cert(Cert) ->
- {ok, Bin} = file:read_file(Cert),
- case filename:extension(Cert) of
- ".der" ->
- %% no decoding necessary
- [Bin];
- _ ->
- %% assume PEM otherwise
- Contents = public_key:pem_decode(Bin),
- [DER || {Type, DER, Cipher} <- Contents, Type == 'Certificate', Cipher == 'not_encrypted']
- end.
-
-%% @doc Validator function for SSL negotiation.
-%%
-validate_function(Cert, valid_peer, State) ->
- ct:log("~p:~p~nvaliding peer ~p with ~p intermediate certs~n",
- [?MODULE,?LINE, get_common_name(Cert),
- length(element(2, State))]),
- %% peer certificate validated, now check the CRL
- Res = (catch check_crl(Cert, State)),
- ct:log("~p:~p~nCRL validate result for ~p: ~p~n",
- [?MODULE,?LINE, get_common_name(Cert), Res]),
- {Res, State};
-validate_function(Cert, valid, {TrustedCAs, IntermediateCerts}=State) ->
- case public_key:pkix_is_self_signed(Cert) of
- true ->
- ct:log("~p:~p~nroot certificate~n",[?MODULE,?LINE]),
- %% this is a root cert, no CRL
- {valid, {TrustedCAs, [Cert|IntermediateCerts]}};
- false ->
- %% check is valid CA certificate, add to the list of
- %% intermediates
- Res = (catch check_crl(Cert, State)),
- ct:log("~p:~p~nCRL intermediate CA validate result for ~p: ~p~n",
- [?MODULE,?LINE, get_common_name(Cert), Res]),
- {Res, {TrustedCAs, [Cert|IntermediateCerts]}}
- end;
-validate_function(_Cert, _Event, State) ->
- %ct:log("~p:~p~nignoring event ~p~n", [?MODULE,?LINE, _Event]),
- {valid, State}.
-
-%% @doc Given a certificate, find CRL distribution points for the given
-%% certificate, fetch, and attempt to validate each CRL through
-%% issuer_function/4.
-%%
-check_crl(Cert, State) ->
- %% pull the CRL distribution point(s) out of the certificate, if any
- ct:log("~p:~p~ncheck_crl(~n Cert=~p,~nState=~p~n)",[?MODULE,?LINE,Cert,State]),
- case pubkey_cert:select_extension(
- ?'id-ce-cRLDistributionPoints',
- pubkey_cert:extensions_list(Cert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.extensions)) of
- undefined ->
- ct:log("~p:~p~nno CRL distribution points for ~p~n",
- [?MODULE,?LINE, get_common_name(Cert)]),
- %% fail; we can't validate if there's no CRL
- no_crl;
- CRLExtension ->
- ct:log("~p:~p~nCRLExtension=~p)",[?MODULE,?LINE,CRLExtension]),
- CRLDistPoints = CRLExtension#'Extension'.extnValue,
- DPointsAndCRLs = lists:foldl(fun(Point, Acc) ->
- %% try to read the CRL over http or from a
- %% local file
- case fetch_point(Point) of
- not_available ->
- ct:log("~p:~p~nfetch_point returned~n~p~n)",[?MODULE,?LINE,not_available]),
- Acc;
- Res ->
- ct:log("~p:~p~nfetch_point returned~n~p~n)",[?MODULE,?LINE,Res]),
- [{Point, Res} | Acc]
- end
- end, [], CRLDistPoints),
- public_key:pkix_crls_validate(Cert,
- DPointsAndCRLs,
- [{issuer_fun,
- {fun issuer_function/4, State}}])
- end.
-
-%% @doc Given a list of distribution points for CRLs, certificates and
-%% both trusted and intermediary certificates, attempt to build and
-%% authority chain back via build_chain to verify that it is valid.
-%%
-issuer_function(_DP, CRL, _Issuer, {TrustedCAs, IntermediateCerts}) ->
- %% XXX the 'Issuer' we get passed here is the AuthorityKeyIdentifier,
- %% which we are not currently smart enough to understand
- %% Read the CA certs out of the file
- ct:log("~p:~p~nissuer_function(~nCRL=~p,~nLast param=~p)",[?MODULE,?LINE,CRL, {TrustedCAs, IntermediateCerts}]),
- Certs = [public_key:pkix_decode_cert(DER, otp) || DER <- TrustedCAs],
- %% get the real issuer out of the CRL
- Issuer = public_key:pkix_normalize_name(
- pubkey_cert_records:transform(
- CRL#'CertificateList'.tbsCertList#'TBSCertList'.issuer, decode)),
- %% assume certificates are ordered from root to tip
- case find_issuer(Issuer, IntermediateCerts ++ Certs) of
- undefined ->
- ct:log("~p:~p~nunable to find certificate matching CRL issuer ~p~n",
- [?MODULE,?LINE, Issuer]),
- error;
- IssuerCert ->
- ct:log("~p:~p~nIssuerCert=~p~n)",[?MODULE,?LINE,IssuerCert]),
- case build_chain({public_key:pkix_encode('OTPCertificate',
- IssuerCert,
- otp),
- IssuerCert}, IntermediateCerts, Certs, []) of
- undefined ->
- error;
- {OTPCert, Path} ->
- {ok, OTPCert, Path}
- end
- end.
-
-%% @doc Attempt to build authority chain back using intermediary
-%% certificates, falling back on trusted certificates if the
-%% intermediary chain of certificates does not fully extend to the
-%% root.
-%%
-%% Returns: {RootCA :: #OTPCertificate{}, Chain :: [der_encoded()]}
-%%
-build_chain({DER, Cert}, IntCerts, TrustedCerts, Acc) ->
- %% check if this cert is self-signed, if it is, we've reached the
- %% root of the chain
- Issuer = public_key:pkix_normalize_name(
- Cert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.issuer),
- Subject = public_key:pkix_normalize_name(
- Cert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subject),
- case Issuer == Subject of
- true ->
- case find_issuer(Issuer, TrustedCerts) of
- undefined ->
- ct:log("~p:~p~nself-signed certificate is NOT trusted~n",[?MODULE,?LINE]),
- undefined;
- TrustedCert ->
- %% return the cert from the trusted list, to prevent
- %% issuer spoofing
- {TrustedCert,
- [public_key:pkix_encode(
- 'OTPCertificate', TrustedCert, otp)|Acc]}
- end;
- false ->
- Match = lists:foldl(
- fun(C, undefined) ->
- S = public_key:pkix_normalize_name(C#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subject),
- %% compare the subject to the current issuer
- case Issuer == S of
- true ->
- %% we've found our man
- {public_key:pkix_encode('OTPCertificate', C, otp), C};
- false ->
- undefined
- end;
- (_E, A) ->
- %% already matched
- A
- end, undefined, IntCerts),
- case Match of
- undefined when IntCerts /= TrustedCerts ->
- %% continue the chain by using the trusted CAs
- ct:log("~p:~p~nRan out of intermediate certs, switching to trusted certs~n",[?MODULE,?LINE]),
- build_chain({DER, Cert}, TrustedCerts, TrustedCerts, Acc);
- undefined ->
- ct:log("Can't construct chain of trust beyond ~p~n",
- [?MODULE,?LINE, get_common_name(Cert)]),
- %% can't find the current cert's issuer
- undefined;
- Match ->
- build_chain(Match, IntCerts, TrustedCerts, [DER|Acc])
- end
- end.
-
-%% @doc Given a certificate and a list of trusted or intermediary
-%% certificates, attempt to find a match in the list or bail with
-%% undefined.
-find_issuer(Issuer, Certs) ->
- lists:foldl(
- fun(OTPCert, undefined) ->
- %% check if this certificate matches the issuer
- Normal = public_key:pkix_normalize_name(
- OTPCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subject),
- case Normal == Issuer of
- true ->
- OTPCert;
- false ->
- undefined
- end;
- (_E, Acc) ->
- %% already found a match
- Acc
- end, undefined, Certs).
-
-%% @doc Find distribution points for a given CRL and then attempt to
-%% fetch the CRL from the first available.
-fetch_point(#'DistributionPoint'{distributionPoint={fullName, Names}}) ->
- Decoded = [{NameType,
- pubkey_cert_records:transform(Name, decode)}
- || {NameType, Name} <- Names],
- ct:log("~p:~p~ncall fetch(~nDecoded=~p~n)",[?MODULE,?LINE,Decoded]),
- fetch(Decoded).
+ {Server, AlertOrClose} ->
+ ct:pal("Server Alert or Close ~p", [AlertOrClose])
+ end,
+ ssl_test_lib:check_result(Client, {error, {tls_alert, ExpectedAlert}}).
-%% @doc Given a list of locations to retrieve a CRL from, attempt to
-%% retrieve either from a file or http resource and bail as soon as
-%% it can be found.
-%%
-%% Currently, only hand a armored PEM or DER encoded file, with
-%% defaulting to DER.
-%%
-fetch([]) ->
- not_available;
-fetch([{uniformResourceIdentifier, "http"++_=URL}|Rest]) ->
- ct:log("~p:~p~ngetting CRL from ~p~n", [?MODULE,?LINE, URL]),
- case httpc:request(get, {URL, []}, [], [{body_format, binary}]) of
- {ok, {_Status, _Headers, Body}} ->
- case Body of
- <<"-----BEGIN", _/binary>> ->
- ct:log("~p:~p~npublic_key:pem_decode,~nBody=~p~n)",[?MODULE,?LINE,Body]),
- [{'CertificateList',
- DER, _}=CertList] = public_key:pem_decode(Body),
- ct:log("~p:~p~npublic_key:pem_entry_decode,~nCertList=~p~n)",[?MODULE,?LINE,CertList]),
- {DER, public_key:pem_entry_decode(CertList)};
- _ ->
- ct:log("~p:~p~npublic_key:pem_entry_decode,~nBody=~p~n)",[?MODULE,?LINE,{'CertificateList', Body, not_encrypted}]),
- %% assume DER encoded
- try
- public_key:pem_entry_decode({'CertificateList', Body, not_encrypted})
- of
- CertList -> {Body, CertList}
- catch
- _C:_E ->
- ct:log("~p:~p~nfailed DER assumption~nRest=~p", [?MODULE,?LINE,Rest]),
- fetch(Rest)
- end
- end;
- {error, _Reason} ->
- ct:log("~p:~p~nfailed to get CRL ~p~n", [?MODULE,?LINE, _Reason]),
- fetch(Rest);
- Other ->
- ct:log("~p:~p~nreally failed to get CRL ~p~n", [?MODULE,?LINE, Other]),
- fetch(Rest)
- end;
-fetch([Loc|Rest]) ->
- %% unsupported CRL location
- ct:log("~p:~p~nunable to fetch CRL from unsupported location ~p~n",
- [?MODULE,?LINE, Loc]),
- fetch(Rest).
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+is_idp(idp_crl) ->
+ true;
+is_idp(_) ->
+ false.
+
+init_certs(_,v1_crl, Config) ->
+ {[{v2_crls, false}], Config};
+init_certs(_, idp_crl, Config) ->
+ Port = ?config(httpd_port, Config),
+ {[{crl_port,Port},
+ {issuing_distribution_point, true}], Config
+ };
+init_certs(_,_,Config) ->
+ {[], Config}.
-%% get the common name attribute out of an OTPCertificate record
-get_common_name(OTPCert) ->
- %% You'd think there'd be an easier way than this giant mess, but I
- %% couldn't find one.
- {rdnSequence, Subject} = OTPCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subject,
- case [Attribute#'AttributeTypeAndValue'.value || [Attribute] <- Subject,
- Attribute#'AttributeTypeAndValue'.type == ?'id-at-commonName'] of
- [Att] ->
- case Att of
- {teletexString, Str} -> Str;
- {printableString, Str} -> Str;
- {utf8String, Bin} -> binary_to_list(Bin)
- end;
- _ ->
- unknown
- end.
+make_dir_path(PathComponents) ->
+ lists:foldl(fun(F,P0) -> file:make_dir(P=filename:join(P0,F)), P end,
+ "",
+ PathComponents).
+rename_crl(Filename) ->
+ file:rename(Filename, Filename ++ ".notfound").
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 1a1b2af8d4..00f9ee8e3c 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -38,12 +39,9 @@
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
all() ->
- [basic, payload, plain_options, plain_verify_options].
+ [basic, payload, plain_options, plain_verify_options, nodelay_option,
+ listen_port_options, listen_options, connect_options, use_interface].
groups() ->
[].
@@ -90,17 +88,15 @@ init_per_testcase(Case, Config) when is_list(Config) ->
common_init(Case, Config).
common_init(Case, Config) ->
- Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
- [{watchdog, Dog},{testcase, Case}|Config].
+ ct:timetrap({seconds, ?DEFAULT_TIMETRAP_SECS}),
+ [{testcase, Case}|Config].
end_per_testcase(Case, Config) when is_list(Config) ->
Flags = proplists:get_value(old_flags, Config),
catch os:putenv("ERL_FLAGS", Flags),
common_end(Case, Config).
-common_end(_, Config) ->
- Dog = ?config(watchdog, Config),
- ?t:timetrap_cancel(Dog),
+common_end(_, _Config) ->
ok.
%%--------------------------------------------------------------------
@@ -255,6 +251,173 @@ plain_verify_options(Config) when is_list(Config) ->
stop_ssl_node(NH1),
stop_ssl_node(NH2),
success(Config).
+%%--------------------------------------------------------------------
+nodelay_option() ->
+ [{doc,"Test specifying dist_nodelay option"}].
+nodelay_option(Config) ->
+ try
+ %% The default is 'true', so try setting it to 'false'.
+ application:set_env(kernel, dist_nodelay, false),
+ basic(Config)
+ after
+ application:unset_env(kernel, dist_nodelay)
+ end.
+
+listen_port_options() ->
+ [{doc, "Test specifying listening ports"}].
+listen_port_options(Config) when is_list(Config) ->
+ %% Start a node, and get the port number it's listening on.
+ NH1 = start_ssl_node(Config),
+ Node1 = NH1#node_handle.nodename,
+ Name1 = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node1)),
+ {ok, NodesPorts} = apply_on_ssl_node(NH1, fun net_adm:names/0),
+ {Name1, Port1} = lists:keyfind(Name1, 1, NodesPorts),
+
+ %% Now start a second node, configuring it to use the same port
+ %% number.
+ PortOpt1 = "-kernel inet_dist_listen_min " ++ integer_to_list(Port1) ++
+ " inet_dist_listen_max " ++ integer_to_list(Port1),
+
+ try start_ssl_node([{additional_dist_opts, PortOpt1} | Config]) of
+ #node_handle{} ->
+ %% If the node was able to start, it didn't take the port
+ %% option into account.
+ exit(unexpected_success)
+ catch
+ exit:{accept_failed, timeout} ->
+ %% The node failed to start, as expected.
+ ok
+ end,
+
+ %% Try again, now specifying a high max port.
+ PortOpt2 = "-kernel inet_dist_listen_min " ++ integer_to_list(Port1) ++
+ " inet_dist_listen_max 65535",
+ NH2 = start_ssl_node([{additional_dist_opts, PortOpt2} | Config]),
+ Node2 = NH2#node_handle.nodename,
+ Name2 = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node2)),
+ {ok, NodesPorts2} = apply_on_ssl_node(NH2, fun net_adm:names/0),
+ {Name2, Port2} = lists:keyfind(Name2, 1, NodesPorts2),
+
+ %% The new port should be higher:
+ if Port2 > Port1 ->
+ ok;
+ true ->
+ error({port, Port2, not_higher_than, Port1})
+ end,
+
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ success(Config).
+%%--------------------------------------------------------------------
+listen_options() ->
+ [{doc, "Test inet_dist_listen_options"}].
+listen_options(Config) when is_list(Config) ->
+ try_setting_priority(fun do_listen_options/2, Config).
+
+do_listen_options(Prio, Config) ->
+ PriorityString0 = "[{priority,"++integer_to_list(Prio)++"}]",
+ PriorityString =
+ case os:cmd("echo [{a,1}]") of
+ "[{a,1}]"++_ ->
+ PriorityString0;
+ _ ->
+ %% Some shells need quoting of [{}]
+ "'"++PriorityString0++"'"
+ end,
+
+ Options = "-kernel inet_dist_listen_options " ++ PriorityString,
+
+ NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ NH2 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ Node2 = NH2#node_handle.nodename,
+
+ pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+
+ PrioritiesNode1 =
+ apply_on_ssl_node(NH1, fun get_socket_priorities/0),
+ PrioritiesNode2 =
+ apply_on_ssl_node(NH2, fun get_socket_priorities/0),
+
+ Elevated1 = [P || P <- PrioritiesNode1, P =:= Prio],
+ ?t:format("Elevated1: ~p~n", [Elevated1]),
+ Elevated2 = [P || P <- PrioritiesNode2, P =:= Prio],
+ ?t:format("Elevated2: ~p~n", [Elevated2]),
+ [_|_] = Elevated1,
+ [_|_] = Elevated2,
+
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ success(Config).
+%%--------------------------------------------------------------------
+connect_options() ->
+ [{doc, "Test inet_dist_connect_options"}].
+connect_options(Config) when is_list(Config) ->
+ try_setting_priority(fun do_connect_options/2, Config).
+
+do_connect_options(Prio, Config) ->
+ PriorityString0 = "[{priority,"++integer_to_list(Prio)++"}]",
+ PriorityString =
+ case os:cmd("echo [{a,1}]") of
+ "[{a,1}]"++_ ->
+ PriorityString0;
+ _ ->
+ %% Some shells need quoting of [{}]
+ "'"++PriorityString0++"'"
+ end,
+
+ Options = "-kernel inet_dist_connect_options " ++ PriorityString,
+
+ NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ NH2 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ Node2 = NH2#node_handle.nodename,
+
+ pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+
+ PrioritiesNode1 =
+ apply_on_ssl_node(NH1, fun get_socket_priorities/0),
+ PrioritiesNode2 =
+ apply_on_ssl_node(NH2, fun get_socket_priorities/0),
+
+ Elevated1 = [P || P <- PrioritiesNode1, P =:= Prio],
+ ?t:format("Elevated1: ~p~n", [Elevated1]),
+ Elevated2 = [P || P <- PrioritiesNode2, P =:= Prio],
+ ?t:format("Elevated2: ~p~n", [Elevated2]),
+ %% Node 1 will have a socket with elevated priority.
+ [_|_] = Elevated1,
+ %% Node 2 will not, since it only applies to outbound connections.
+ [] = Elevated2,
+
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ success(Config).
+%%--------------------------------------------------------------------
+use_interface() ->
+ [{doc, "Test inet_dist_use_interface"}].
+use_interface(Config) when is_list(Config) ->
+ %% Force the node to listen only on the loopback interface.
+ IpString = "'{127,0,0,1}'",
+ Options = "-kernel inet_dist_use_interface " ++ IpString,
+
+ %% Start a node, and get the port number it's listening on.
+ NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ Node1 = NH1#node_handle.nodename,
+ Name = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node1)),
+ {ok, NodesPorts} = apply_on_ssl_node(NH1, fun net_adm:names/0),
+ {Name, Port} = lists:keyfind(Name, 1, NodesPorts),
+
+ %% Now find the socket listening on that port, and check its sockname.
+ Sockets = apply_on_ssl_node(
+ NH1,
+ fun() ->
+ [inet:sockname(P) ||
+ P <- erlang:ports(),
+ {ok, Port} =:= (catch inet:port(P))]
+ end),
+ %% And check that it's actually listening on localhost.
+ [{ok,{{127,0,0,1},Port}}] = Sockets,
+
+ stop_ssl_node(NH1),
+ success(Config).
%%--------------------------------------------------------------------
%%% Internal functions -----------------------------------------------
@@ -269,6 +432,30 @@ tstsrvr_format(Fmt, ArgList) ->
send_to_tstcntrl(Message) ->
send_to_tstsrvr({message, Message}).
+try_setting_priority(TestFun, Config) ->
+ Prio = 1,
+ case gen_udp:open(0, [{priority,Prio}]) of
+ {ok,Socket} ->
+ case inet:getopts(Socket, [priority]) of
+ {ok,[{priority,Prio}]} ->
+ ok = gen_udp:close(Socket),
+ TestFun(Prio, Config);
+ _ ->
+ ok = gen_udp:close(Socket),
+ {skip,
+ "Can not set priority "++integer_to_list(Prio)++
+ " on socket"}
+ end;
+ {error,_} ->
+ {skip, "Can not set priority on socket"}
+ end.
+
+get_socket_priorities() ->
+ [Priority ||
+ {ok,[{priority,Priority}]} <-
+ [inet:getopts(Port, [priority]) ||
+ Port <- erlang:ports(),
+ element(2, erlang:port_info(Port, name)) =:= "tcp_inet"]].
%%
%% test_server side api
@@ -351,17 +538,13 @@ host_name() ->
Host.
mk_node_name(Config) ->
- {A, B, C} = erlang:now(),
+ N = erlang:unique_integer([positive]),
Case = ?config(testcase, Config),
atom_to_list(?MODULE)
++ "_"
++ atom_to_list(Case)
++ "_"
- ++ integer_to_list(A)
- ++ "-"
- ++ integer_to_list(B)
- ++ "-"
- ++ integer_to_list(C).
+ ++ integer_to_list(N).
mk_node_cmdline(ListenPort, Name, Args) ->
Static = "-detached -noinput",
@@ -590,12 +773,10 @@ rand_bin(N) ->
rand_bin(0, Acc) ->
Acc;
rand_bin(N, Acc) ->
- rand_bin(N-1, [random:uniform(256)-1|Acc]).
+ rand_bin(N-1, [rand:uniform(256)-1|Acc]).
make_randfile(Dir) ->
{ok, IoDev} = file:open(filename:join([Dir, "RAND"]), [write]),
- {A, B, C} = erlang:now(),
- random:seed(A, B, C),
ok = file:write(IoDev, rand_bin(1024)),
file:close(IoDev).
@@ -617,7 +798,7 @@ setup_certs(Config) ->
ok = file:make_dir(NodeDir),
ok = file:make_dir(RGenDir),
make_randfile(RGenDir),
- make_certs:all(RGenDir, NodeDir),
+ {ok, _} = make_certs:all(RGenDir, NodeDir),
SDir = filename:join([NodeDir, "server"]),
SC = filename:join([SDir, "cert.pem"]),
SK = filename:join([SDir, "key.pem"]),
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index 8dca733526..d050812208 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,8 +32,6 @@
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() -> [decode_hello_handshake,
decode_single_hello_extension_correctly,
decode_supported_elliptic_curves_hello_extension_correctly,
@@ -40,7 +39,47 @@ all() -> [decode_hello_handshake,
encode_single_hello_sni_extension_correctly,
decode_single_hello_sni_extension_correctly,
decode_empty_server_sni_correctly,
- select_proper_tls_1_2_rsa_default_hashsign].
+ select_proper_tls_1_2_rsa_default_hashsign,
+ ignore_hassign_extension_pre_tls_1_2].
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+end_per_suite(Config) ->
+ Config.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_,Config) ->
+ Config.
+
+init_per_testcase(ignore_hassign_extension_pre_tls_1_2, Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ case is_supported(sha512) of
+ true ->
+ ssl:start(),
+ %% make rsa certs using oppenssl
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
+ Config = ssl_test_lib:cert_options(Config0),
+ ct:timetrap({seconds, 5}),
+ Config;
+ false ->
+ {skip, "Crypto did not support sha512"}
+ end
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end;
+init_per_testcase(_, Config0) ->
+ Config0.
+
+end_per_testcase(ignore_hassign_extension_pre_tls_1_2, _) ->
+ crypto:stop();
+end_per_testcase(_TestCase, Config) ->
+ Config.
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
@@ -121,3 +160,18 @@ select_proper_tls_1_2_rsa_default_hashsign(_Config) ->
{md5sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, {3,2}),
{md5sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, {3,0}).
+
+ignore_hassign_extension_pre_tls_1_2(Config) ->
+ Opts = ?config(server_opts, Config),
+ CertFile = proplists:get_value(certfile, Opts),
+ [{_, Cert, _}] = ssl_test_lib:pem_to_der(CertFile),
+ HashSigns = #hash_sign_algos{hash_sign_algos = [{sha512, rsa}, {sha, dsa}]},
+ {sha512, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,3}), {3,3}),
+ %%% Ignore
+ {md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,2}), {3,2}),
+ {md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,0}), {3,0}).
+
+is_supported(Hash) ->
+ Algos = crypto:supports(),
+ Hashs = proplists:get_value(hashs, Algos),
+ lists:member(Hash, Hashs).
diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
index 30c0a67a36..6b71fe6d28 100644
--- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,8 +30,6 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
@@ -70,10 +69,8 @@ init_per_suite(Config) ->
try crypto:start() of
ok ->
ssl:start(),
- Result =
- (catch make_certs:all(?config(data_dir, Config),
- ?config(priv_dir, Config))),
- ct:log("Make certs ~p~n", [Result]),
+ {ok, _} = make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
@@ -102,6 +99,15 @@ init_per_group(GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -172,7 +178,7 @@ no_client_negotiate_but_server_supports_npn(Config) when is_list(Config) ->
run_npn_handshake(Config,
[],
[{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}],
- {error, next_protocol_not_negotiated}).
+ {error, protocol_not_negotiated}).
%--------------------------------------------------------------------------------
@@ -180,7 +186,7 @@ client_negotiate_server_does_not_support(Config) when is_list(Config) ->
run_npn_handshake(Config,
[{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}],
[],
- {error, next_protocol_not_negotiated}).
+ {error, protocol_not_negotiated}).
%--------------------------------------------------------------------------------
renegotiate_from_client_after_npn_handshake(Config) when is_list(Config) ->
@@ -311,8 +317,8 @@ run_npn_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) ->
assert_npn(Socket, Protocol) ->
ct:log("Negotiated Protocol ~p, Expecting: ~p ~n",
- [ssl:negotiated_next_protocol(Socket), Protocol]),
- Protocol = ssl:negotiated_next_protocol(Socket).
+ [ssl:negotiated_protocol(Socket), Protocol]),
+ Protocol = ssl:negotiated_protocol(Socket).
assert_npn_and_renegotiate_and_send_data(Socket, Protocol, Data) ->
assert_npn(Socket, Protocol),
@@ -332,7 +338,7 @@ ssl_receive_and_assert_npn(Socket, Protocol, Data) ->
ssl_send(Socket, Data) ->
ct:log("Connection info: ~p~n",
- [ssl:connection_info(Socket)]),
+ [ssl:connection_information(Socket)]),
ssl:send(Socket, Data).
ssl_receive(Socket, Data) ->
@@ -340,7 +346,7 @@ ssl_receive(Socket, Data) ->
ssl_receive(Socket, Data, Buffer) ->
ct:log("Connection info: ~p~n",
- [ssl:connection_info(Socket)]),
+ [ssl:connection_information(Socket)]),
receive
{ssl, Socket, MoreData} ->
ct:log("Received ~p~n",[MoreData]),
@@ -360,4 +366,4 @@ ssl_receive(Socket, Data, Buffer) ->
connection_info_result(Socket) ->
- ssl:connection_info(Socket).
+ ssl:connection_information(Socket).
diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl
index 68ff9172e9..fa7187b6c0 100644
--- a/lib/ssl/test/ssl_npn_hello_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -32,9 +33,6 @@
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[encode_and_decode_npn_client_hello_test,
encode_and_decode_npn_server_hello_test,
@@ -43,6 +41,14 @@ all() ->
create_server_hello_with_advertised_protocols_test,
create_server_hello_with_no_advertised_protocols_test].
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index d50498f547..08a66ec07a 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,16 +38,12 @@
-define(uint24(X), << ?UINT24(X) >> ).
-define(uint32(X), << ?UINT32(X) >> ).
-define(uint64(X), << ?UINT64(X) >> ).
--define(TIMEOUT, 120000).
-define(MANY, 1000).
-define(SOME, 50).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[
{group, 'tlsv1.2'},
@@ -140,10 +137,8 @@ init_per_suite(Config) ->
try crypto:start() of
ok ->
ssl:start(),
- Result =
- (catch make_certs:all(?config(data_dir, Config),
- ?config(priv_dir, Config))),
- ct:log("Make certs ~p~n", [Result]),
+ {ok, _} = make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
@@ -172,10 +167,9 @@ init_per_group(GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-init_per_testcase(_TestCase, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 15}),
+ Config.
end_per_testcase(_TestCase, Config) ->
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
index f95eae51b7..fb3890a811 100644
--- a/lib/ssl/test/ssl_payload_SUITE.erl
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,8 +30,6 @@
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[
{group, 'tlsv1.2'},
@@ -72,7 +71,7 @@ init_per_suite(Config) ->
try crypto:start() of
ok ->
ssl:start(),
- make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
+ {ok, _} = make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
@@ -100,10 +99,27 @@ init_per_group(GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-init_per_testcase(_TestCase, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+init_per_testcase(TestCase, Config) when TestCase == server_echos_passive_huge;
+ TestCase == server_echos_active_once_huge;
+ TestCase == server_echos_active_huge;
+ TestCase == client_echos_passive_huge;
+ TestCase == client_echos_active_once_huge;
+ TestCase == client_echos_active_huge ->
+ ct:timetrap({seconds, 90}),
+ Config;
+
+init_per_testcase(TestCase, Config) when TestCase == server_echos_passive_big;
+ TestCase == server_echos_active_once_big;
+ TestCase == server_echos_active_big;
+ TestCase == client_echos_passive_big;
+ TestCase == client_echos_active_once_big;
+ TestCase == client_echos_active_big ->
+ ct:timetrap({seconds, 60}),
+ Config;
+
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 15}),
+ Config.
end_per_testcase(_TestCase, Config) ->
Config.
diff --git a/lib/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl
index 843079e2fe..3e96276258 100644
--- a/lib/ssl/test/ssl_pem_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.2
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -44,11 +45,8 @@ init_per_suite(Config0) ->
ok ->
ssl:start(),
%% make rsa certs using oppenssl
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- ct:log("Make certs ~p~n", [Result]),
-
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
Config1 = ssl_test_lib:make_dsa_cert(Config0),
ssl_test_lib:cert_options(Config1)
catch _:_ ->
@@ -64,15 +62,16 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-init_per_testcase(pem_cleanup, Config) ->
- ssl:stop(),
+init_per_testcase(pem_cleanup = Case, Config) ->
+ end_per_testcase(Case, Config) ,
application:load(ssl),
application:set_env(ssl, ssl_pem_cache_clean, ?CLEANUP_INTERVAL),
ssl:start(),
+ ct:timetrap({minutes, 1}),
Config.
end_per_testcase(_TestCase, Config) ->
- %%ssl:stop(),
+ ssl:stop(),
Config.
%%--------------------------------------------------------------------
@@ -113,9 +112,9 @@ get_pem_cache() ->
{status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
- case element(5, State) of
- [_CertDb, _FileRefDb, PemChace] ->
- PemChace;
+ case element(6, State) of
+ [_CertDb, _FileRefDb, PemCache| _] ->
+ PemCache;
_ ->
undefined
end.
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index c31f6c2d7d..85345c814f 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.2
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,6 +31,7 @@
-define(SLEEP, 500).
-define(TIMEOUT, 60000).
-define(LONG_TIMEOUT, 600000).
+-define(MAX_TABLE_SIZE, 5).
-behaviour(ssl_session_cache_api).
@@ -41,31 +43,27 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[session_cleanup,
session_cache_process_list,
- session_cache_process_mnesia].
+ session_cache_process_mnesia,
+ client_unique_session,
+ max_table_size
+ ].
groups() ->
[].
init_per_suite(Config0) ->
- Dog = ct:timetrap(?LONG_TIMEOUT *2),
catch crypto:stop(),
try crypto:start() of
ok ->
ssl:start(),
- %% make rsa certs using oppenssl
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- ct:log("Make certs ~p~n", [Result]),
-
- Config1 = ssl_test_lib:make_dsa_cert(Config0),
- Config = ssl_test_lib:cert_options(Config1),
- [{watchdog, Dog} | Config]
+ %% make rsa certs using
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
+ Config = ssl_test_lib:make_dsa_cert(Config0),
+ ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
end.
@@ -87,30 +85,41 @@ init_per_testcase(session_cache_process_mnesia, Config) ->
mnesia:start(),
init_customized_session_cache(mnesia, Config);
-init_per_testcase(session_cleanup, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
+init_per_testcase(session_cleanup, Config) ->
ssl:stop(),
application:load(ssl),
application:set_env(ssl, session_lifetime, 5),
application:set_env(ssl, session_delay_cleanup_time, ?DELAY),
ssl:start(),
- [{watchdog, Dog} | Config];
+ ct:timetrap({seconds, 20}),
+ Config;
-init_per_testcase(_TestCase, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+init_per_testcase(client_unique_session, Config) ->
+ ct:timetrap({seconds, 40}),
+ Config;
-init_customized_session_cache(Type, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
+init_per_testcase(max_table_size, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_cache_server_max, ?MAX_TABLE_SIZE),
+ application:set_env(ssl, session_cache_client_max, ?MAX_TABLE_SIZE),
+ application:set_env(ssl, session_delay_cleanup_time, ?DELAY),
+ ssl:start(),
+ ct:timetrap({seconds, 40}),
+ Config.
+
+init_customized_session_cache(Type, Config) ->
ssl:stop(),
application:load(ssl),
application:set_env(ssl, session_cb, ?MODULE),
- application:set_env(ssl, session_cb_init_args, [Type]),
+ application:set_env(ssl, session_cb_init_args, [{type, Type}]),
ssl:start(),
- [{watchdog, Dog} | Config].
+ catch (end_per_testcase(list_to_atom("session_cache_process" ++ atom_to_list(Type)),
+ Config)),
+ ets:new(ssl_test, [named_table, public, set]),
+ ets:insert(ssl_test, {type, Type}),
+ ct:timetrap({seconds, 5}),
+ Config.
end_per_testcase(session_cache_process_list, Config) ->
application:unset_env(ssl, session_cb),
@@ -126,16 +135,55 @@ end_per_testcase(session_cleanup, Config) ->
application:unset_env(ssl, session_delay_cleanup_time),
application:unset_env(ssl, session_lifetime),
end_per_testcase(default_action, Config);
-end_per_testcase(_TestCase, Config) ->
+end_per_testcase(max_table_size, Config) ->
+ application:unset_env(ssl, session_cach_server_max),
+ application:unset_env(ssl, session_cach_client_max),
+ end_per_testcase(default_action, Config);
+end_per_testcase(Case, Config) when Case == session_cache_process_list;
+ Case == session_cache_process_mnesia ->
+ ets:delete(ssl_test),
+ Config;
+end_per_testcase(_, Config) ->
Config.
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
+client_unique_session() ->
+ [{doc, "Test session table does not grow when client "
+ "sets up many connections"}].
+client_unique_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {tcp_options, [{active, false}]},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ LastClient = clients_start(Server,
+ ClientNode, Hostname, Port, ClientOpts, client_unique_session, 20),
+ receive
+ {LastClient, {ok, _}} ->
+ ok
+ end,
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ ClientCache = element(2, State),
+
+ 1 = ssl_session_cache:size(ClientCache),
+
+ ssl_test_lib:close(Server, 500),
+ ssl_test_lib:close(LastClient).
+
session_cleanup() ->
[{doc, "Test that sessions are cleand up eventually, so that the session table "
"does not grow and grow ..."}].
-session_cleanup(Config)when is_list(Config) ->
+session_cleanup(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
@@ -149,9 +197,9 @@ session_cleanup(Config)when is_list(Config) ->
Port = ssl_test_lib:inet_port(Server),
Client =
ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
+ {port, Port}, {host, Hostname},
{mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
+ {from, self()}, {options, ClientOpts}]),
SessionInfo =
receive
{Server, Info} ->
@@ -164,12 +212,13 @@ session_cleanup(Config)when is_list(Config) ->
{status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
- Cache = element(2, State),
- SessionTimer = element(6, State),
+ ClientCache = element(2, State),
+ ServerCache = element(3, State),
+ SessionTimer = element(7, State),
Id = proplists:get_value(session_id, SessionInfo),
- CSession = ssl_session_cache:lookup(Cache, {{Hostname, Port}, Id}),
- SSession = ssl_session_cache:lookup(Cache, {Port, Id}),
+ CSession = ssl_session_cache:lookup(ClientCache, {{Hostname, Port}, Id}),
+ SSession = ssl_session_cache:lookup(ServerCache, {Port, Id}),
true = CSession =/= undefined,
true = SSession =/= undefined,
@@ -185,42 +234,14 @@ session_cleanup(Config)when is_list(Config) ->
ct:sleep(?SLEEP), %% Make sure clean has had time to run
- undefined = ssl_session_cache:lookup(Cache, {{Hostname, Port}, Id}),
- undefined = ssl_session_cache:lookup(Cache, {Port, Id}),
+ undefined = ssl_session_cache:lookup(ClientCache, {{Hostname, Port}, Id}),
+ undefined = ssl_session_cache:lookup(ServerCache, {Port, Id}),
process_flag(trap_exit, false),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-check_timer(Timer) ->
- case erlang:read_timer(Timer) of
- false ->
- {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
- timer:sleep(?SLEEP),
- {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
- ok;
- Int ->
- ct:sleep(Int),
- check_timer(Timer)
- end.
-get_delay_timers() ->
- {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
- [_, _,_, _, Prop] = StatusInfo,
- State = ssl_test_lib:state(Prop),
- case element(7, State) of
- {undefined, undefined} ->
- ct:sleep(?SLEEP),
- get_delay_timers();
- {undefined, _} ->
- ct:sleep(?SLEEP),
- get_delay_timers();
- {_, undefined} ->
- ct:sleep(?SLEEP),
- get_delay_timers();
- DelayTimers ->
- DelayTimers
- end.
%%--------------------------------------------------------------------
session_cache_process_list() ->
[{doc,"Test reuse of sessions (short handshake)"}].
@@ -233,19 +254,55 @@ session_cache_process_mnesia(Config) when is_list(Config) ->
session_cache_process(mnesia,Config).
%%--------------------------------------------------------------------
+
+max_table_size() ->
+ [{doc,"Test max limit on session table"}].
+max_table_size(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {tcp_options, [{active, false}]},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ LastClient = clients_start(Server,
+ ClientNode, Hostname, Port, ClientOpts, max_table_size, 20),
+ receive
+ {LastClient, {ok, _}} ->
+ ok
+ end,
+ ct:sleep(1000),
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ ClientCache = element(2, State),
+ ServerCache = element(3, State),
+ N = ssl_session_cache:size(ServerCache),
+ M = ssl_session_cache:size(ClientCache),
+ ct:pal("~p",[{N, M}]),
+ ssl_test_lib:close(Server, 500),
+ ssl_test_lib:close(LastClient),
+ true = N =< ?MAX_TABLE_SIZE,
+ true = M =< ?MAX_TABLE_SIZE.
+
+%%--------------------------------------------------------------------
%%% Session cache API callbacks
%%--------------------------------------------------------------------
-init([Type]) ->
- ets:new(ssl_test, [named_table, public, set]),
- ets:insert(ssl_test, {type, Type}),
- case Type of
+init(Opts) ->
+ case proplists:get_value(type, Opts) of
list ->
spawn(fun() -> session_loop([]) end);
mnesia ->
mnesia:start(),
- {atomic,ok} = mnesia:create_table(sess_cache, []),
- sess_cache
+ Name = atom_to_list(proplists:get_value(role, Opts)),
+ TabName = list_to_atom(Name ++ "sess_cache"),
+ {atomic,ok} = mnesia:create_table(TabName, []),
+ TabName
end.
session_cb() ->
@@ -258,7 +315,7 @@ terminate(Cache) ->
Cache ! terminate;
mnesia ->
catch {atomic,ok} =
- mnesia:delete_table(sess_cache)
+ mnesia:delete_table(Cache)
end.
lookup(Cache, Key) ->
@@ -268,10 +325,10 @@ lookup(Cache, Key) ->
receive {Cache, Res} -> Res end;
mnesia ->
case mnesia:transaction(fun() ->
- mnesia:read(sess_cache,
+ mnesia:read(Cache,
Key, read)
end) of
- {atomic, [{sess_cache, Key, Value}]} ->
+ {atomic, [{Cache, Key, Value}]} ->
Value;
_ ->
undefined
@@ -285,8 +342,8 @@ update(Cache, Key, Value) ->
mnesia ->
{atomic, ok} =
mnesia:transaction(fun() ->
- mnesia:write(sess_cache,
- {sess_cache, Key, Value}, write)
+ mnesia:write(Cache,
+ {Cache, Key, Value}, write)
end)
end.
@@ -297,7 +354,7 @@ delete(Cache, Key) ->
mnesia ->
{atomic, ok} =
mnesia:transaction(fun() ->
- mnesia:delete(sess_cache, Key)
+ mnesia:delete(Cache, Key)
end)
end.
@@ -308,7 +365,7 @@ foldl(Fun, Acc, Cache) ->
receive {Cache, Res} -> Res end;
mnesia ->
Foldl = fun() ->
- mnesia:foldl(Fun, Acc, sess_cache)
+ mnesia:foldl(Fun, Acc, Cache)
end,
{atomic, Res} = mnesia:transaction(Foldl),
Res
@@ -325,8 +382,8 @@ select_session(Cache, PartialKey) ->
mnesia ->
Sel = fun() ->
mnesia:select(Cache,
- [{{sess_cache,{PartialKey,'$1'}, '$2'},
- [],['$$']}])
+ [{{Cache,{PartialKey,'_'}, '$1'},
+ [],['$1']}])
end,
{atomic, Res} = mnesia:transaction(Sel),
Res
@@ -354,8 +411,8 @@ session_loop(Sess) ->
Pid ! {self(), Res},
session_loop(Sess);
{Pid,select_session,PKey} ->
- Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 ->
- [[Id, Session]|Acc];
+ Sel = fun({{PKey0, _Id},Session}, Acc) when PKey == PKey0 ->
+ [Session | Acc];
(_,Acc) ->
Acc
end,
@@ -370,3 +427,75 @@ session_loop(Sess) ->
session_cache_process(_Type,Config) when is_list(Config) ->
ssl_basic_SUITE:reuse_session(Config).
+
+
+clients_start(_Server, ClientNode, Hostname, Port, ClientOpts, Test, 0) ->
+ %% Make sure session is registered
+ ct:sleep(?SLEEP * 2),
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {from, self()}, {options, test_copts(Test, 0, ClientOpts)}]);
+clients_start(Server, ClientNode, Hostname, Port, ClientOpts, Test, N) ->
+ spawn_link(ssl_test_lib, start_client,
+ [[{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, test_copts(Test, N, ClientOpts)}]]),
+ Server ! listen,
+ wait_for_server(),
+ clients_start(Server, ClientNode, Hostname, Port, ClientOpts, Test, N-1).
+
+connection_info_result(Socket) ->
+ ssl:connection_information(Socket, [protocol, cipher_suite]).
+
+check_timer(Timer) ->
+ case erlang:read_timer(Timer) of
+ false ->
+ {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
+ timer:sleep(?SLEEP),
+ {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
+ ok;
+ Int ->
+ ct:sleep(Int),
+ check_timer(Timer)
+ end.
+
+get_delay_timers() ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ case element(8, State) of
+ {undefined, undefined} ->
+ ct:sleep(?SLEEP),
+ get_delay_timers();
+ {undefined, _} ->
+ ct:sleep(?SLEEP),
+ get_delay_timers();
+ {_, undefined} ->
+ ct:sleep(?SLEEP),
+ get_delay_timers();
+ DelayTimers ->
+ DelayTimers
+ end.
+
+wait_for_server() ->
+ ct:sleep(100).
+
+
+test_copts(_, 0, ClientOpts) ->
+ ClientOpts;
+test_copts(max_table_size, N, ClientOpts) ->
+ Version = tls_record:highest_protocol_version([]),
+ CipherSuites = %%lists:map(fun(X) -> ssl_cipher:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))),
+[ Y|| Y = {Alg,_, _, _} <- lists:map(fun(X) -> ssl_cipher:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))), Alg =/= ecdhe_ecdsa, Alg =/= ecdh_ecdsa, Alg =/= ecdh_rsa, Alg =/= ecdhe_rsa, Alg =/= dhe_dss, Alg =/= dss],
+ case length(CipherSuites) of
+ M when M >= N ->
+ Cipher = lists:nth(N, CipherSuites),
+ ct:pal("~p",[Cipher]),
+ [{ciphers, [Cipher]} | ClientOpts];
+ _ ->
+ ClientOpts
+ end;
+test_copts(_, _, ClientOpts) ->
+ ClientOpts.
diff --git a/lib/ssl/test/ssl_sni_SUITE.erl b/lib/ssl/test/ssl_sni_SUITE.erl
new file mode 100644
index 0000000000..90c2a49e61
--- /dev/null
+++ b/lib/ssl/test/ssl_sni_SUITE.erl
@@ -0,0 +1,190 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssl_sni_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() -> [no_sni_header,
+ sni_match,
+ sni_no_match,
+ no_sni_header_fun,
+ sni_match_fun,
+ sni_no_match_fun].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl:start(),
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
+ ssl_test_lib:cert_options(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]),
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+no_sni_header(Config) ->
+ run_handshake(Config, undefined, undefined, "server").
+
+no_sni_header_fun(Config) ->
+ run_sni_fun_handshake(Config, undefined, undefined, "server").
+
+sni_match(Config) ->
+ run_handshake(Config, "a.server", "a.server", "a.server").
+
+sni_match_fun(Config) ->
+ run_sni_fun_handshake(Config, "a.server", "a.server", "a.server").
+
+sni_no_match(Config) ->
+ run_handshake(Config, "c.server", undefined, "server").
+
+sni_no_match_fun(Config) ->
+ run_sni_fun_handshake(Config, "c.server", undefined, "server").
+
+
+%%--------------------------------------------------------------------
+%% Internal Functions ------------------------------------------------
+%%--------------------------------------------------------------------
+ssl_recv(SSLSocket, Expect) ->
+ ssl_recv(SSLSocket, "", Expect).
+
+ssl_recv(SSLSocket, CurrentData, ExpectedData) ->
+ receive
+ {ssl, SSLSocket, Data} ->
+ NeweData = CurrentData ++ Data,
+ case NeweData of
+ ExpectedData ->
+ ok;
+ _ ->
+ ssl_recv(SSLSocket, NeweData, ExpectedData)
+ end;
+ Other ->
+ ct:fail({unexpected_message, Other})
+ after 4000 ->
+ ct:fail({timeout, CurrentData, ExpectedData})
+ end.
+
+send_and_hostname(SSLSocket) ->
+ ssl:send(SSLSocket, "OK"),
+ case ssl:connection_information(SSLSocket, [sni_hostname]) of
+ {ok, [{sni_hostname, Hostname}]} ->
+ Hostname;
+ {ok, []} ->
+ undefined
+ end.
+
+rdnPart([[#'AttributeTypeAndValue'{type=Type, value=Value} | _] | _], Type) ->
+ Value;
+rdnPart([_ | Tail], Type) ->
+ rdnPart(Tail, Type);
+rdnPart([], _) ->
+ unknown.
+
+rdn_to_string({utf8String, Binary}) ->
+ erlang:binary_to_list(Binary);
+rdn_to_string({printableString, String}) ->
+ String.
+
+recv_and_certificate(SSLSocket) ->
+ ssl_recv(SSLSocket, "OK"),
+ {ok, PeerCert} = ssl:peercert(SSLSocket),
+ #'OTPCertificate'{tbsCertificate = #'OTPTBSCertificate'{subject = {rdnSequence, Subject}}}
+ = public_key:pkix_decode_cert(PeerCert, otp),
+ ct:log("Subject of certificate received from server: ~p", [Subject]),
+ rdn_to_string(rdnPart(Subject, ?'id-at-commonName')).
+
+run_sni_fun_handshake(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
+ ct:log("Start running handshake for sni_fun, Config: ~p, SNIHostname: ~p, "
+ "ExpectedSNIHostname: ~p, ExpectedCN: ~p",
+ [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
+ [{sni_hosts, ServerSNIConf}] = ?config(sni_server_opts, Config),
+ SNIFun = fun(Domain) -> proplists:get_value(Domain, ServerSNIConf, undefined) end,
+ ServerOptions = ?config(server_opts, Config) ++ [{sni_fun, SNIFun}],
+ ClientOptions =
+ case SNIHostname of
+ undefined ->
+ ?config(client_opts, Config);
+ _ ->
+ [{server_name_indication, SNIHostname}] ++ ?config(client_opts, Config)
+ end,
+ ct:log("Options: ~p", [[ServerOptions, ClientOptions]]),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
+ {options, ServerOptions}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname}, {from, self()},
+ {mfa, {?MODULE, recv_and_certificate, []}},
+ {options, ClientOptions}]),
+ ssl_test_lib:check_result(Server, ExpectedSNIHostname, Client, ExpectedCN),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+run_handshake(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
+ ct:log("Start running handshake, Config: ~p, SNIHostname: ~p, "
+ "ExpectedSNIHostname: ~p, ExpectedCN: ~p",
+ [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
+ ServerOptions = ?config(sni_server_opts, Config) ++ ?config(server_opts, Config),
+ ClientOptions =
+ case SNIHostname of
+ undefined ->
+ ?config(client_opts, Config);
+ _ ->
+ [{server_name_indication, SNIHostname}] ++ ?config(client_opts, Config)
+ end,
+ ct:log("Options: ~p", [[ServerOptions, ClientOptions]]),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
+ {options, ServerOptions}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname}, {from, self()},
+ {mfa, {?MODULE, recv_and_certificate, []}},
+ {options, ClientOptions}]),
+ ssl_test_lib:check_result(Server, ExpectedSNIHostname, Client, ExpectedCN),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 74d71263de..ed4bd86665 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -187,6 +188,7 @@ run_client(Opts) ->
Transport = proplists:get_value(transport, Opts, ssl),
Options = proplists:get_value(options, Opts),
ct:log("~p:~p~n~p:connect(~p, ~p)@~p~n", [?MODULE,?LINE, Transport, Host, Port, Node]),
+ ct:log("SSLOpts: ~p", [Options]),
case rpc:call(Node, Transport, connect, [Host, Port, Options]) of
{ok, Socket} ->
Pid ! {connected, Socket},
@@ -224,6 +226,17 @@ run_client(Opts) ->
ct:log("~p:~p~nClient faild several times: connection failed: ~p ~n", [?MODULE,?LINE, Reason]),
Pid ! {self(), {error, Reason}}
end;
+ {error, econnreset = Reason} ->
+ case get(retries) of
+ N when N < 5 ->
+ ct:log("~p:~p~neconnreset retries=~p sleep ~p",[?MODULE,?LINE, N,?SLEEP]),
+ put(retries, N+1),
+ ct:sleep(?SLEEP),
+ run_client(Opts);
+ _ ->
+ ct:log("~p:~p~nClient faild several times: connection failed: ~p ~n", [?MODULE,?LINE, Reason]),
+ Pid ! {self(), {error, Reason}}
+ end;
{error, Reason} ->
ct:log("~p:~p~nClient: connection failed: ~p ~n", [?MODULE,?LINE, Reason]),
Pid ! {connect_failed, Reason};
@@ -239,7 +252,21 @@ close(Pid) ->
receive
{'DOWN', Monitor, process, Pid, Reason} ->
erlang:demonitor(Monitor),
- ct:log("~p:~p~nPid: ~p down due to:~p ~n", [?MODULE,?LINE, Pid, Reason])
+ ct:log("~p:~p~nPid: ~p down due to:~p ~n", [?MODULE,?LINE, Pid, Reason])
+
+ end.
+
+close(Pid, Timeout) ->
+ ct:log("~p:~p~n Close ~p ~n", [?MODULE,?LINE, Pid]),
+ Monitor = erlang:monitor(process, Pid),
+ Pid ! close,
+ receive
+ {'DOWN', Monitor, process, Pid, Reason} ->
+ erlang:demonitor(Monitor),
+ ct:log("~p:~p~nPid: ~p down due to:~p ~n", [?MODULE,?LINE, Pid, Reason])
+ after
+ Timeout ->
+ exit(Pid, kill)
end.
check_result(Server, ServerMsg, Client, ClientMsg) ->
@@ -253,7 +280,6 @@ check_result(Server, ServerMsg, Client, ClientMsg) ->
{Port, {data,Debug}} when is_port(Port) ->
ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]),
check_result(Server, ServerMsg, Client, ClientMsg);
-
Unexpected ->
Reason = {{expected, {Client, ClientMsg}},
{expected, {Server, ServerMsg}}, {got, Unexpected}},
@@ -267,6 +293,9 @@ check_result(Pid, Msg) ->
{Port, {data,Debug}} when is_port(Port) ->
ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]),
check_result(Pid,Msg);
+ %% {Port, {exit_status, Status}} when is_port(Port) ->
+ %% ct:log("~p:~p Exit status: ~p~n",[?MODULE,?LINE, Status]),
+ %% check_result(Pid, Msg);
Unexpected ->
Reason = {{expected, {Pid, Msg}},
{got, Unexpected}},
@@ -351,7 +380,12 @@ cert_options(Config) ->
BadKeyFile = filename:join([?config(priv_dir, Config),
"badkey.pem"]),
PskSharedSecret = <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15>>,
- [{client_opts, [{ssl_imp, new},{reuseaddr, true}]},
+
+ SNIServerACertFile = filename:join([?config(priv_dir, Config), "a.server", "cert.pem"]),
+ SNIServerAKeyFile = filename:join([?config(priv_dir, Config), "a.server", "key.pem"]),
+ SNIServerBCertFile = filename:join([?config(priv_dir, Config), "b.server", "cert.pem"]),
+ SNIServerBKeyFile = filename:join([?config(priv_dir, Config), "b.server", "key.pem"]),
+ [{client_opts, []},
{client_verification_opts, [{cacertfile, ClientCaCertFile},
{certfile, ClientCertFile},
{keyfile, ClientKeyFile},
@@ -411,7 +445,17 @@ cert_options(Config) ->
{server_bad_cert, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
{certfile, BadCertFile}, {keyfile, ServerKeyFile}]},
{server_bad_key, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
- {certfile, ServerCertFile}, {keyfile, BadKeyFile}]}
+ {certfile, ServerCertFile}, {keyfile, BadKeyFile}]},
+ {sni_server_opts, [{sni_hosts, [
+ {"a.server", [
+ {certfile, SNIServerACertFile},
+ {keyfile, SNIServerAKeyFile}
+ ]},
+ {"b.server", [
+ {certfile, SNIServerBCertFile},
+ {keyfile, SNIServerBKeyFile}
+ ]}
+ ]}]}
| Config].
@@ -760,7 +804,12 @@ send_selected_port(_,_,_) ->
rsa_suites(CounterPart) ->
ECC = is_sane_ecc(CounterPart),
- lists:filter(fun({rsa, _, _}) ->
+ FIPS = is_fips(CounterPart),
+ lists:filter(fun({rsa, des_cbc, sha}) when FIPS == true ->
+ false;
+ ({dhe_rsa, des_cbc, sha}) when FIPS == true ->
+ false;
+ ({rsa, _, _}) ->
true;
({dhe_rsa, _, _}) ->
true;
@@ -769,7 +818,17 @@ rsa_suites(CounterPart) ->
(_) ->
false
end,
- ssl:cipher_suites()).
+ common_ciphers(CounterPart)).
+
+common_ciphers(crypto) ->
+ ssl:cipher_suites();
+common_ciphers(openssl) ->
+ OpenSslSuites =
+ string:tokens(string:strip(os:cmd("openssl ciphers"), right, $\n), ":"),
+ [ssl_cipher:erl_suite_definition(S)
+ || S <- ssl_cipher:suites(tls_record:highest_protocol_version([])),
+ lists:member(ssl_cipher:openssl_suite_name(S), OpenSslSuites)
+ ].
rsa_non_signed_suites() ->
lists:filter(fun({rsa, _, _}) ->
@@ -811,48 +870,34 @@ openssl_rsa_suites(CounterPart) ->
false ->
"DSS | ECDHE | ECDH"
end,
- lists:filter(fun(Str) ->
- case re:run(Str, Names,[]) of
- nomatch ->
- false;
- _ ->
- true
- end
- end, Ciphers).
+ lists:filter(fun(Str) -> string_regex_filter(Str, Names)
+ end, Ciphers).
openssl_dsa_suites() ->
Ciphers = ssl:cipher_suites(openssl),
- lists:filter(fun(Str) ->
- case re:run(Str,"DSS",[]) of
- nomatch ->
- false;
- _ ->
- true
- end
+ lists:filter(fun(Str) -> string_regex_filter(Str, "DSS")
end, Ciphers).
openssl_ecdsa_suites() ->
Ciphers = ssl:cipher_suites(openssl),
- lists:filter(fun(Str) ->
- case re:run(Str,"ECDHE-ECDSA",[]) of
- nomatch ->
- false;
- _ ->
- true
- end
+ lists:filter(fun(Str) -> string_regex_filter(Str, "ECDHE-ECDSA")
end, Ciphers).
openssl_ecdh_rsa_suites() ->
Ciphers = ssl:cipher_suites(openssl),
- lists:filter(fun(Str) ->
- case re:run(Str,"ECDH-RSA",[]) of
- nomatch ->
- false;
- _ ->
- true
- end
+ lists:filter(fun(Str) -> string_regex_filter(Str, "ECDH-RSA")
end, Ciphers).
+string_regex_filter(Str, Search) when is_list(Str) ->
+ case re:run(Str, Search, []) of
+ nomatch ->
+ false;
+ _ ->
+ true
+ end;
+string_regex_filter(_Str, _Search) ->
+ false.
+
anonymous_suites() ->
Suites =
[{dh_anon, rc4_128, md5},
@@ -860,6 +905,8 @@ anonymous_suites() ->
{dh_anon, '3des_ede_cbc', sha},
{dh_anon, aes_128_cbc, sha},
{dh_anon, aes_256_cbc, sha},
+ {dh_anon, aes_128_gcm, null, sha256},
+ {dh_anon, aes_256_gcm, null, sha384},
{ecdh_anon,rc4_128,sha},
{ecdh_anon,'3des_ede_cbc',sha},
{ecdh_anon,aes_128_cbc,sha},
@@ -885,8 +932,13 @@ psk_suites() ->
{rsa_psk, aes_128_cbc, sha},
{rsa_psk, aes_256_cbc, sha},
{rsa_psk, aes_128_cbc, sha256},
- {rsa_psk, aes_256_cbc, sha384}
-],
+ {rsa_psk, aes_256_cbc, sha384},
+ {psk, aes_128_gcm, null, sha256},
+ {psk, aes_256_gcm, null, sha384},
+ {dhe_psk, aes_128_gcm, null, sha256},
+ {dhe_psk, aes_256_gcm, null, sha384},
+ {rsa_psk, aes_128_gcm, null, sha256},
+ {rsa_psk, aes_256_gcm, null, sha384}],
ssl_cipher:filter_suites(Suites).
psk_anon_suites() ->
@@ -925,6 +977,10 @@ srp_dss_suites() ->
{srp_dss, aes_256_cbc, sha}],
ssl_cipher:filter_suites(Suites).
+rc4_suites(Version) ->
+ Suites = ssl_cipher:rc4_suites(Version),
+ ssl_cipher:filter_suites(Suites).
+
pem_to_der(File) ->
{ok, PemBin} = file:read_file(File),
public_key:pem_decode(PemBin).
@@ -934,7 +990,8 @@ der_to_pem(File, Entries) ->
file:write_file(File, PemBin).
cipher_result(Socket, Result) ->
- Result = ssl:connection_info(Socket),
+ {ok, Info} = ssl:connection_information(Socket),
+ Result = {ok, {proplists:get_value(protocol, Info), proplists:get_value(cipher_suite, Info)}},
ct:log("~p:~p~nSuccessfull connect: ~p~n", [?MODULE,?LINE, Result]),
%% Importante to send two packets here
%% to properly test "cipher state" handling
@@ -1054,6 +1111,9 @@ is_sane_ecc(openssl) ->
"OpenSSL 1.0.0" ++ _ -> % Known bug in openssl
%% manifests as SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list
false;
+ "OpenSSL 1.0.1l" ++ _ ->
+ %% Breaks signature verification
+ false;
"OpenSSL 0.9.8" ++ _ -> % Does not support ECC
false;
"OpenSSL 0.9.7" ++ _ -> % Does not support ECC
@@ -1074,6 +1134,25 @@ is_sane_ecc(crypto) ->
is_sane_ecc(_) ->
true.
+is_fips(openssl) ->
+ VersionStr = os:cmd("openssl version"),
+ case re:split(VersionStr, "fips") of
+ [_] ->
+ false;
+ _ ->
+ true
+ end;
+is_fips(crypto) ->
+ [{_,_, Bin}] = crypto:info_lib(),
+ case re:split(Bin, <<"fips">>) of
+ [_] ->
+ false;
+ _ ->
+ true
+ end;
+is_fips(_) ->
+ false.
+
cipher_restriction(Config0) ->
case is_sane_ecc(openssl) of
false ->
@@ -1089,52 +1168,63 @@ cipher_restriction(Config0) ->
end.
check_sane_openssl_version(Version) ->
- case {Version, os:cmd("openssl version")} of
- {_, "OpenSSL 1.0.1" ++ _} ->
- true;
- {'tlsv1.2', "OpenSSL 1.0" ++ _} ->
- false;
- {'tlsv1.1', "OpenSSL 1.0" ++ _} ->
- false;
- {'tlsv1.2', "OpenSSL 0" ++ _} ->
- false;
- {'tlsv1.1', "OpenSSL 0" ++ _} ->
- false;
- {_, _} ->
- true
+ case supports_ssl_tls_version(Version) of
+ true ->
+ case {Version, os:cmd("openssl version")} of
+ {_, "OpenSSL 1.0.2" ++ _} ->
+ true;
+ {_, "OpenSSL 1.0.1" ++ _} ->
+ true;
+ {'tlsv1.2', "OpenSSL 1.0" ++ _} ->
+ false;
+ {'tlsv1.1', "OpenSSL 1.0" ++ _} ->
+ false;
+ {'tlsv1.2', "OpenSSL 0" ++ _} ->
+ false;
+ {'tlsv1.1', "OpenSSL 0" ++ _} ->
+ false;
+ {_, _} ->
+ true
+ end;
+ false ->
+ false
end.
-
enough_openssl_crl_support("OpenSSL 0." ++ _) -> false;
enough_openssl_crl_support(_) -> true.
-wait_for_openssl_server() ->
- receive
- {Port, {data, Debug}} when is_port(Port) ->
- ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]),
- %% openssl has started make sure
- %% it will be in accept. Parsing
- %% output is too error prone. (Even
- %% more so than sleep!)
- ct:sleep(?SLEEP)
+wait_for_openssl_server(Port) ->
+ wait_for_openssl_server(Port, 10).
+wait_for_openssl_server(_, 0) ->
+ exit(failed_to_connect_to_openssl);
+wait_for_openssl_server(Port, N) ->
+ case gen_tcp:connect("localhost", Port, []) of
+ {ok, S} ->
+ gen_tcp:close(S);
+ _ ->
+ ct:sleep(?SLEEP),
+ wait_for_openssl_server(Port, N-1)
end.
version_flag(tlsv1) ->
- " -tls1 ";
+ "-tls1";
version_flag('tlsv1.1') ->
- " -tls1_1 ";
+ "-tls1_1";
version_flag('tlsv1.2') ->
- " -tls1_2 ";
+ "-tls1_2";
version_flag(sslv3) ->
- " -ssl3 ".
+ "-ssl3";
+version_flag(sslv2) ->
+ "-ssl2".
filter_suites(Ciphers0) ->
Version = tls_record:highest_protocol_version([]),
Supported0 = ssl_cipher:suites(Version)
- ++ ssl_cipher:anonymous_suites()
+ ++ ssl_cipher:anonymous_suites(Version)
++ ssl_cipher:psk_suites(Version)
- ++ ssl_cipher:srp_suites(),
+ ++ ssl_cipher:srp_suites()
+ ++ ssl_cipher:rc4_suites(Version),
Supported1 = ssl_cipher:filter_suites(Supported0),
- Supported2 = [ssl:suite_definition(S) || S <- Supported1],
+ Supported2 = [ssl_cipher:erl_suite_definition(S) || S <- Supported1],
[Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported2)].
-define(OPENSSL_QUIT, "Q\n").
@@ -1169,3 +1259,31 @@ close_loop(Port, Time, SentClose) ->
ct:log("Timeout~n",[])
end
end.
+
+portable_open_port(Exe, Args) ->
+ AbsPath = os:find_executable(Exe),
+ ct:pal("open_port({spawn_executable, ~p}, [{args, ~p}, stderr_to_stdout]).", [AbsPath, Args]),
+ open_port({spawn_executable, AbsPath},
+ [{args, Args}, stderr_to_stdout]).
+
+supports_ssl_tls_version(Version) ->
+ VersionFlag = version_flag(Version),
+ Exe = "openssl",
+ Args = ["s_client", VersionFlag],
+ Port = ssl_test_lib:portable_open_port(Exe, Args),
+ do_supports_ssl_tls_version(Port).
+
+do_supports_ssl_tls_version(Port) ->
+ receive
+ {Port, {data, "unknown option" ++ _}} ->
+ false;
+ {Port, {data, Data}} ->
+ case lists:member("error", string:tokens(Data, ":")) of
+ true ->
+ false;
+ false ->
+ do_supports_ssl_tls_version(Port)
+ end
+ after 500 ->
+ true
+ end.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index 942c446ec4..6934d7f851 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -25,8 +26,6 @@
-include_lib("common_test/include/ct.hrl").
--define(TIMEOUT, 120000).
--define(LONG_TIMEOUT, 600000).
-define(SLEEP, 1000).
-define(OPENSSL_RENEGOTIATE, "R\n").
-define(OPENSSL_QUIT, "Q\n").
@@ -37,8 +36,6 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
all() ->
[
{group, basic},
@@ -50,9 +47,9 @@ all() ->
groups() ->
[{basic, [], basic_tests()},
- {'tlsv1.2', [], all_versions_tests() ++ npn_tests()},
- {'tlsv1.1', [], all_versions_tests() ++ npn_tests()},
- {'tlsv1', [], all_versions_tests()++ npn_tests()},
+ {'tlsv1.2', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
+ {'tlsv1.1', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
+ {'tlsv1', [], all_versions_tests()++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
{'sslv3', [], all_versions_tests()}].
basic_tests() ->
@@ -79,6 +76,18 @@ all_versions_tests() ->
expired_session,
ssl2_erlang_server_openssl_client].
+alpn_tests() ->
+ [erlang_client_alpn_openssl_server_alpn,
+ erlang_server_alpn_openssl_client_alpn,
+ erlang_client_alpn_openssl_server,
+ erlang_client_openssl_server_alpn,
+ erlang_server_alpn_openssl_client,
+ erlang_server_openssl_client_alpn,
+ erlang_client_alpn_openssl_server_alpn_renegotiate,
+ erlang_server_alpn_openssl_client_alpn_renegotiate,
+ erlang_client_alpn_npn_openssl_server_alpn_npn,
+ erlang_server_alpn_npn_openssl_client_alpn_npn].
+
npn_tests() ->
[erlang_client_openssl_server_npn,
erlang_server_openssl_client_npn,
@@ -89,24 +98,29 @@ npn_tests() ->
erlang_client_openssl_server_npn_only_client,
erlang_client_openssl_server_npn_only_server].
+sni_server_tests() ->
+ [erlang_server_openssl_client_sni_match,
+ erlang_server_openssl_client_sni_match_fun,
+ erlang_server_openssl_client_sni_no_match,
+ erlang_server_openssl_client_sni_no_match_fun,
+ erlang_server_openssl_client_sni_no_header,
+ erlang_server_openssl_client_sni_no_header_fun].
+
init_per_suite(Config0) ->
- Dog = ct:timetrap(?LONG_TIMEOUT *2),
case os:find_executable("openssl") of
false ->
{skip, "Openssl not found"};
_ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
catch crypto:stop(),
try crypto:start() of
ok ->
ssl:start(),
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- ct:log("Make certs ~p~n", [Result]),
+ {ok, _} = make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0)),
Config1 = ssl_test_lib:make_dsa_cert(Config0),
- Config2 = ssl_test_lib:cert_options(Config1),
- Config = [{watchdog, Dog} | Config2],
+ Config = ssl_test_lib:cert_options(Config1),
ssl_test_lib:cipher_restriction(Config)
catch _:_ ->
{skip, "Crypto did not start"}
@@ -135,19 +149,22 @@ init_per_group(GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-init_per_testcase(expired_session, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?EXPIRE * 1000 * 5),
+init_per_testcase(expired_session, Config) ->
+ ct:timetrap(?EXPIRE * 1000 * 5),
ssl:stop(),
application:load(ssl),
application:set_env(ssl, session_lifetime, ?EXPIRE),
ssl:start(),
- [{watchdog, Dog} | Config];
+ Config;
-init_per_testcase(TestCase, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ct:timetrap(?TIMEOUT),
- special_init(TestCase, [{watchdog, Dog} | Config]).
+init_per_testcase(TestCase, Config) when TestCase == ciphers_rsa_signed_certs;
+ TestCase == ciphers_dsa_signed_certs ->
+ ct:timetrap({seconds, 45}),
+ special_init(TestCase, Config);
+
+init_per_testcase(TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ special_init(TestCase, Config).
special_init(TestCase, Config)
when TestCase == erlang_client_openssl_server_renegotiate;
@@ -158,7 +175,42 @@ special_init(TestCase, Config)
check_sane_openssl_renegotaite(Config, Version);
special_init(ssl2_erlang_server_openssl_client, Config) ->
- check_sane_openssl_sslv2(Config);
+ case ssl_test_lib:supports_ssl_tls_version(sslv2) of
+ true ->
+ Config;
+ false ->
+ {skip, "sslv2 not supported by openssl"}
+ end;
+
+special_init(TestCase, Config)
+ when TestCase == erlang_client_alpn_openssl_server_alpn;
+ TestCase == erlang_server_alpn_openssl_client_alpn;
+ TestCase == erlang_client_alpn_openssl_server;
+ TestCase == erlang_client_openssl_server_alpn;
+ TestCase == erlang_server_alpn_openssl_client;
+ TestCase == erlang_server_openssl_client_alpn ->
+ check_openssl_alpn_support(Config);
+
+special_init(TestCase, Config)
+ when TestCase == erlang_client_alpn_openssl_server_alpn_renegotiate;
+ TestCase == erlang_server_alpn_openssl_client_alpn_renegotiate ->
+ {ok, Version} = application:get_env(ssl, protocol_version),
+ case check_sane_openssl_renegotaite(Config, Version) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ check_openssl_alpn_support(Config)
+ end;
+
+special_init(TestCase, Config)
+ when TestCase == erlang_client_alpn_npn_openssl_server_alpn_npn;
+ TestCase == erlang_server_alpn_npn_openssl_client_alpn_npn ->
+ case check_openssl_alpn_support(Config) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ check_openssl_npn_support(Config)
+ end;
special_init(TestCase, Config)
when TestCase == erlang_client_openssl_server_npn;
@@ -179,6 +231,16 @@ special_init(TestCase, Config)
_ ->
check_openssl_npn_support(Config)
end;
+
+special_init(TestCase, Config)
+ when TestCase == erlang_server_openssl_client_sni_match;
+ TestCase == erlang_server_openssl_client_sni_no_match;
+ TestCase == erlang_server_openssl_client_sni_no_header;
+ TestCase == erlang_server_openssl_client_sni_match_fun;
+ TestCase == erlang_server_openssl_client_sni_no_match_fun;
+ TestCase == erlang_server_openssl_client_sni_no_header_fun ->
+ check_openssl_sni_support(Config);
+
special_init(_, Config) ->
Config.
@@ -206,14 +268,13 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile,
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ "-cert", CertFile, "-key", KeyFile],
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -246,13 +307,11 @@ basic_erlang_server_openssl_client(Config) when is_list(Config) ->
{mfa, {?MODULE, erlang_ssl_receive, [Data]}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
-
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
- " -host localhost" ++ workaround_openssl_s_clinent(),
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ Exe = "openssl",
+ Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port) | workaround_openssl_s_clinent()],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
@@ -278,14 +337,14 @@ erlang_client_openssl_server(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile,
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -320,12 +379,12 @@ erlang_server_openssl_client(Config) when is_list(Config) ->
Port = ssl_test_lib:inet_port(Server),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost",
+ Exe = "openssl",
+ Args = ["s_client", "-connect", "localhost: " ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version)],
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
true = port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
@@ -351,16 +410,15 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-CAfile", CaCertFile,
+ "-key", KeyFile, "-Verify", "2", "-msg"],
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
- ++ " -key " ++ KeyFile ++ " -Verify 2 -msg",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
-
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -399,13 +457,14 @@ erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost " ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
- ++ " -key " ++ KeyFile ++ " -msg",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ Exe = "openssl",
+ Args = ["s_client", "-connect", "localhost: " ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,
+ "-CAfile", CaCertFile,
+ "-key", KeyFile, "-msg"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
@@ -435,12 +494,13 @@ erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost -reconnect",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ Exe = "openssl",
+ Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-reconnect"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
@@ -471,14 +531,14 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -520,14 +580,14 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -566,12 +626,12 @@ erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
{options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost -msg",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ Exe = "openssl",
+ Args = ["s_client","-connect", "localhost: " ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-msg"],
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
@@ -601,14 +661,14 @@ erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
-
- ssl_test_lib:wait_for_openssl_server(),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -643,15 +703,15 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
CaCertFile = proplists:get_value(cacertfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
- ++ " -key " ++ KeyFile ++ " -Verify 2",
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-CAfile", CaCertFile,
+ "-key", KeyFile, "-Verify", "2"],
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -694,15 +754,14 @@ erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ClientOpts),
KeyFile = proplists:get_value(keyfile, ClientOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
- ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- true = port_command(OpenSslPort, Data),
-
+ Exe = "openssl",
+ Args = ["s_client", "-cert", CertFile,
+ "-CAfile", CaCertFile,
+ "-key", KeyFile,"-connect", "localhost:" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version)],
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ true = port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
%% Clean close down! Server needs to be closed first !!
@@ -783,14 +842,12 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -839,14 +896,13 @@ expired_session(Config) when is_list(Config) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ "-cert", CertFile,"-key", KeyFile],
- ct:log("openssl cmd: ~p~n", [Cmd]),
-
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client0 =
ssl_test_lib:start_client([{node, ClientNode},
@@ -897,12 +953,11 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
- " -host localhost -ssl2 -msg",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ Exe = "openssl",
+ Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port),
+ "-ssl2", "-msg"],
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
@@ -924,6 +979,128 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
+
+erlang_client_alpn_openssl_server_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_server_alpn_openssl_client_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------------
+
+erlang_client_alpn_openssl_server(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_with_opts(Config,
+ [{alpn_advertised_protocols, [<<"spdy/2">>]}],
+ [],
+ Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------------
+
+erlang_client_openssl_server_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_with_opts(Config,
+ [],
+ ["-alpn", "spdy/2"],
+ Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------------
+
+erlang_server_alpn_openssl_client(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_with_opts(Config,
+ [{alpn_preferred_protocols, [<<"spdy/2">>]}],
+ [],
+ Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------------
+
+erlang_server_openssl_client_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_with_opts(Config,
+ [],
+ ["-alpn", "spdy/2"],
+ Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_client_alpn_openssl_server_alpn_renegotiate(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_server_alpn_openssl_client_alpn_renegotiate(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_client_alpn_npn_openssl_server_alpn_npn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_server_alpn_npn_openssl_client_alpn_npn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_alpn_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok)
+ end),
+ ok.
+
+%%--------------------------------------------------------------------
erlang_client_openssl_server_npn() ->
[{doc,"Test erlang client with openssl server doing npn negotiation"}].
@@ -979,7 +1156,7 @@ erlang_server_openssl_client_npn_renegotiate(Config) when is_list(Config) ->
erlang_client_openssl_server_npn_only_server(Config) when is_list(Config) ->
Data = "From openssl to erlang",
start_erlang_client_and_openssl_server_with_opts(Config, [],
- "-nextprotoneg spdy/2", Data, fun(Server, OpensslPort) ->
+ ["-nextprotoneg", "spdy/2"], Data, fun(Server, OpensslPort) ->
true = port_command(OpensslPort, Data),
ssl_test_lib:check_result(Server, ok)
end),
@@ -991,7 +1168,7 @@ erlang_client_openssl_server_npn_only_client(Config) when is_list(Config) ->
Data = "From openssl to erlang",
start_erlang_client_and_openssl_server_with_opts(Config,
[{client_preferred_next_protocols,
- {client, [<<"spdy/2">>], <<"http/1.1">>}}], "",
+ {client, [<<"spdy/2">>], <<"http/1.1">>}}], [],
Data, fun(Server, OpensslPort) ->
true = port_command(OpensslPort, Data),
ssl_test_lib:check_result(Server, ok)
@@ -1001,7 +1178,7 @@ erlang_client_openssl_server_npn_only_client(Config) when is_list(Config) ->
%%--------------------------------------------------------------------------
erlang_server_openssl_client_npn_only_server(Config) when is_list(Config) ->
Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_with_opts(Config, [{next_protocols_advertised, [<<"spdy/2">>]}], "",
+ start_erlang_server_and_openssl_client_with_opts(Config, [{next_protocols_advertised, [<<"spdy/2">>]}], [],
Data, fun(Server, OpensslPort) ->
true = port_command(OpensslPort, Data),
ssl_test_lib:check_result(Server, ok)
@@ -1010,12 +1187,31 @@ erlang_server_openssl_client_npn_only_server(Config) when is_list(Config) ->
erlang_server_openssl_client_npn_only_client(Config) when is_list(Config) ->
Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_with_opts(Config, [], "-nextprotoneg spdy/2",
+ start_erlang_server_and_openssl_client_with_opts(Config, [], ["-nextprotoneg", "spdy/2"],
Data, fun(Server, OpensslPort) ->
true = port_command(OpensslPort, Data),
ssl_test_lib:check_result(Server, ok)
end),
ok.
+%--------------------------------------------------------------------------
+erlang_server_openssl_client_sni_no_header(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test(Config, undefined, undefined, "server").
+
+erlang_server_openssl_client_sni_no_header_fun(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test_sni_fun(Config, undefined, undefined, "server").
+
+erlang_server_openssl_client_sni_match(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test(Config, "a.server", "a.server", "a.server").
+
+erlang_server_openssl_client_sni_match_fun(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test_sni_fun(Config, "a.server", "a.server", "a.server").
+
+erlang_server_openssl_client_sni_no_match(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test(Config, "c.server", undefined, "server").
+
+erlang_server_openssl_client_sni_no_match_fun(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test_sni_fun(Config, "c.server", undefined, "server").
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
@@ -1042,6 +1238,98 @@ run_suites(Ciphers, Version, Config, Type) ->
ct:fail(cipher_suite_failed_see_test_case_log)
end.
+client_read_check([], _Data) ->
+ ok;
+client_read_check([Hd | T], Data) ->
+ case binary:match(Data, list_to_binary(Hd)) of
+ nomatch ->
+ nomatch;
+ _ ->
+ client_read_check(T, Data)
+ end.
+client_check_result(Port, DataExpected, DataReceived) ->
+ receive
+ {Port, {data, TheData}} ->
+ Data = list_to_binary(TheData),
+ NewData = <<DataReceived/binary, Data/binary>>,
+ ct:log("New Data: ~p", [NewData]),
+ case client_read_check(DataExpected, NewData) of
+ ok ->
+ ok;
+ _ ->
+ client_check_result(Port, DataExpected, NewData)
+ end
+ after 3000 ->
+ ct:fail({"Time out on openSSL Client", {expected, DataExpected},
+ {got, DataReceived}})
+ end.
+client_check_result(Port, DataExpected) ->
+ client_check_result(Port, DataExpected, <<"">>).
+
+send_and_hostname(SSLSocket) ->
+ ssl:send(SSLSocket, "OK"),
+ case ssl:connection_information(SSLSocket, [sni_hostname]) of
+ {ok, []} ->
+ undefined;
+ {ok, [{sni_hostname, Hostname}]} ->
+ Hostname
+ end.
+
+erlang_server_openssl_client_sni_test(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
+ ct:log("Start running handshake, Config: ~p, SNIHostname: ~p, ExpectedSNIHostname: ~p, ExpectedCN: ~p", [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
+ ServerOptions = ?config(sni_server_opts, Config) ++ ?config(server_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
+ {options, ServerOptions}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Exe = "openssl",
+ ClientArgs = case SNIHostname of
+ undefined ->
+ ["s_client", "-connect", Hostname ++ ":" ++ integer_to_list(Port)];
+ _ ->
+ ["s_client", "-connect", Hostname ++ ":" ++ integer_to_list(Port), "-servername", SNIHostname]
+ end,
+ ClientPort = ssl_test_lib:portable_open_port(Exe, ClientArgs),
+
+ %% Client check needs to be done befor server check,
+ %% or server check might consume client messages
+ ExpectedClientOutput = ["OK", "/CN=" ++ ExpectedCN ++ "/"],
+ client_check_result(ClientPort, ExpectedClientOutput),
+ ssl_test_lib:check_result(Server, ExpectedSNIHostname),
+ ssl_test_lib:close_port(ClientPort),
+ ssl_test_lib:close(Server),
+ ok.
+
+
+erlang_server_openssl_client_sni_test_sni_fun(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
+ ct:log("Start running handshake for sni_fun, Config: ~p, SNIHostname: ~p, ExpectedSNIHostname: ~p, ExpectedCN: ~p", [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
+ [{sni_hosts, ServerSNIConf}] = ?config(sni_server_opts, Config),
+ SNIFun = fun(Domain) -> proplists:get_value(Domain, ServerSNIConf, undefined) end,
+ ServerOptions = ?config(server_opts, Config) ++ [{sni_fun, SNIFun}],
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
+ {options, ServerOptions}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Exe = "openssl",
+ ClientArgs = case SNIHostname of
+ undefined ->
+ ["s_client", "-connect", Hostname ++ ":" ++ integer_to_list(Port)];
+ _ ->
+ ["s_client", "-connect", Hostname ++ ":" ++ integer_to_list(Port), "-servername", SNIHostname]
+ end,
+ ClientPort = ssl_test_lib:portable_open_port(Exe, ClientArgs),
+
+ %% Client check needs to be done befor server check,
+ %% or server check might consume client messages
+ ExpectedClientOutput = ["OK", "/CN=" ++ ExpectedCN ++ "/"],
+ client_check_result(ClientPort, ExpectedClientOutput),
+ ssl_test_lib:check_result(Server, ExpectedSNIHostname),
+ ssl_test_lib:close_port(ClientPort),
+ ssl_test_lib:close(Server).
+
+
cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
process_flag(trap_exit, true),
ct:log("Testing CipherSuite ~p~n", [CipherSuite]),
@@ -1051,14 +1339,13 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
- Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(),
+ ssl_test_lib:wait_for_openssl_server(Port),
ConnectionInfo = {ok, {Version, CipherSuite}},
@@ -1114,21 +1401,63 @@ start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, Opens
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server " ++ OpensslServerOpts ++ " -accept " ++
- integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile,
+ Exe = "openssl",
+ Args = case OpensslServerOpts of
+ [] ->
+ ["s_server", "-accept",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,"-key", KeyFile];
+ [Opt, Value] ->
+ ["s_server", Opt, Value, "-accept",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,"-key", KeyFile]
+ end,
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+
+ Callback(Client, OpensslPort),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
- ct:log("openssl cmd: ~p~n", [Cmd]),
+start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts0 = ?config(client_opts, Config),
+ ClientOpts = [{alpn_advertised_protocols, [<<"spdy/2">>]} | ClientOpts0],
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
- ssl_test_lib:wait_for_openssl_server(),
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
+
+ Exe = "openssl",
+ Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
+ erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
{options, ClientOpts}]),
Callback(Client, OpensslPort),
@@ -1139,11 +1468,41 @@ start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, Opens
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
-start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callback) ->
+start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts0 = ?config(server_opts, Config),
+ ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>]} | ServerOpts0],
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
+
+ Exe = "openssl",
+ Args = ["s_client", "-alpn", "http/1.0,spdy/2", "-msg", "-port",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-host", "localhost"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ Callback(Server, OpenSslPort),
+
+ ssl_test_lib:close(Server),
+
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
+
+start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, Callback) ->
process_flag(trap_exit, true),
ServerOpts = ?config(server_opts, Config),
ClientOpts0 = ?config(client_opts, Config),
- ClientOpts = [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}} | ClientOpts0],
+ ClientOpts = [{alpn_advertised_protocols, [<<"spdy/2">>]},
+ {client_preferred_next_protocols, {client, [<<"spdy/3">>, <<"http/1.1">>]}} | ClientOpts0],
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
@@ -1154,20 +1513,85 @@ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callbac
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_server -msg -nextprotoneg http/1.1,spdy/2 -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile,
+ Exe = "openssl",
+ Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-nextprotoneg",
+ "spdy/3", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ ssl_test_lib:wait_for_openssl_server(Port),
- ssl_test_lib:wait_for_openssl_server(),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ClientOpts}]),
+
+ Callback(Client, OpensslPort),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
+
+start_erlang_server_and_openssl_client_for_alpn_npn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts0 = ?config(server_opts, Config),
+ ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>]},
+ {next_protocols_advertised, [<<"spdy/3">>, <<"http/1.1">>]} | ServerOpts0],
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
+ Exe = "openssl",
+ Args = ["s_client", "-alpn", "http/1.1,spdy/2", "-nextprotoneg", "spdy/3",
+ "-msg", "-port", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-host", "localhost"],
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ Callback(Server, OpenSslPort),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
+
+start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts0 = ?config(client_opts, Config),
+ ClientOpts = [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}} | ClientOpts0],
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
+
+ Exe = "openssl",
+ Args = ["s_server", "-msg", "-nextprotoneg", "http/1.1,spdy/2", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {?MODULE,
- erlang_ssl_receive_and_assert_npn, [<<"spdy/2">>, Data]}},
+ erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
{options, ClientOpts}]),
Callback(Client, OpensslPort),
@@ -1188,16 +1612,16 @@ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callbac
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, erlang_ssl_receive_and_assert_npn, [<<"spdy/2">>, Data]}},
+ {mfa, {?MODULE, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -nextprotoneg http/1.0,spdy/2 -msg -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost",
- ct:log("openssl cmd: ~p~n", [Cmd]),
+ Exe = "openssl",
+ Args = ["s_client", "-nextprotoneg", "http/1.0,spdy/2", "-msg", "-connect", "localhost:"
+ ++ integer_to_list(Port), ssl_test_lib:version_flag(Version)],
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
Callback(Server, OpenSslPort),
@@ -1221,12 +1645,12 @@ start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenS
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client " ++ OpenSSLClientOpts ++ " -msg -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -host localhost",
-
- ct:log("openssl cmd: ~p~n", [Cmd]),
+
+ Exe = "openssl",
+ Args = ["s_client"] ++ OpenSSLClientOpts ++ ["-msg", "-connect", "localhost:" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version)],
- OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
Callback(Server, OpenSslPort),
@@ -1236,15 +1660,15 @@ start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenS
process_flag(trap_exit, false).
-erlang_ssl_receive_and_assert_npn(Socket, Protocol, Data) ->
- {ok, Protocol} = ssl:negotiated_next_protocol(Socket),
+erlang_ssl_receive_and_assert_negotiated_protocol(Socket, Protocol, Data) ->
+ {ok, Protocol} = ssl:negotiated_protocol(Socket),
erlang_ssl_receive(Socket, Data),
- {ok, Protocol} = ssl:negotiated_next_protocol(Socket),
+ {ok, Protocol} = ssl:negotiated_protocol(Socket),
ok.
erlang_ssl_receive(Socket, Data) ->
ct:log("Connection info: ~p~n",
- [ssl:connection_info(Socket)]),
+ [ssl:connection_information(Socket)]),
receive
{ssl, Socket, Data} ->
io:format("Received ~p~n",[Data]),
@@ -1258,21 +1682,19 @@ erlang_ssl_receive(Socket, Data) ->
erlang_ssl_receive(Socket,Data);
Other ->
ct:fail({unexpected_message, Other})
- after 4000 ->
- ct:fail({did_not_get, Data})
end.
connection_info(Socket, Version) ->
- case ssl:connection_info(Socket) of
- {ok, {Version, _} = Info} ->
+ case ssl:connection_information(Socket, [version]) of
+ {ok, [{version, Version}] = Info} ->
ct:log("Connection info: ~p~n", [Info]),
ok;
- {ok, {OtherVersion, _}} ->
+ {ok, [{version, OtherVersion}]} ->
{wrong_version, OtherVersion}
end.
connection_info_result(Socket) ->
- ssl:connection_info(Socket).
+ ssl:connection_information(Socket).
delayed_send(Socket, [ErlData, OpenSslData]) ->
@@ -1287,6 +1709,14 @@ server_sent_garbage(Socket) ->
end.
+check_openssl_sni_support(Config) ->
+ HelpText = os:cmd("openssl s_client --help"),
+ case string:str(HelpText, "-servername") of
+ 0 ->
+ {skip, "Current openssl doesn't support SNI"};
+ _ ->
+ Config
+ end.
check_openssl_npn_support(Config) ->
HelpText = os:cmd("openssl s_client --help"),
@@ -1297,6 +1727,15 @@ check_openssl_npn_support(Config) ->
Config
end.
+check_openssl_alpn_support(Config) ->
+ HelpText = os:cmd("openssl s_client --help"),
+ case string:str(HelpText, "alpn") of
+ 0 ->
+ {skip, "Openssl not compiled with alpn support"};
+ _ ->
+ Config
+ end.
+
check_sane_openssl_renegotaite(Config, Version) when Version == 'tlsv1.1';
Version == 'tlsv1.2' ->
case os:cmd("openssl version") of
@@ -1315,7 +1754,9 @@ check_sane_openssl_renegotaite(Config, _) ->
check_sane_openssl_renegotaite(Config).
check_sane_openssl_renegotaite(Config) ->
- case os:cmd("openssl version") of
+ case os:cmd("openssl version") of
+ "OpenSSL 1.0.0" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
"OpenSSL 0.9.8" ++ _ ->
{skip, "Known renegotiation bug in OpenSSL"};
"OpenSSL 0.9.7" ++ _ ->
@@ -1324,30 +1765,6 @@ check_sane_openssl_renegotaite(Config) ->
Config
end.
-check_sane_openssl_sslv2(Config) ->
- Port = open_port({spawn, "openssl s_client -ssl2 "}, [stderr_to_stdout]),
- case supports_sslv2(Port) of
- true ->
- Config;
- false ->
- {skip, "sslv2 not supported by openssl"}
- end.
-
-supports_sslv2(Port) ->
- receive
- {Port, {data, "unknown option -ssl2" ++ _}} ->
- false;
- {Port, {data, Data}} ->
- case lists:member("error", string:tokens(Data, ":")) of
- true ->
- false;
- false ->
- supports_sslv2(Port)
- end
- after 500 ->
- true
- end.
-
workaround_openssl_s_clinent() ->
%% http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683159
%% https://bugs.archlinux.org/task/33919
@@ -1355,13 +1772,13 @@ workaround_openssl_s_clinent() ->
%% explicitly specified
case os:cmd("openssl version") of
"OpenSSL 1.0.1c" ++ _ ->
- " -no_tls1_2 ";
+ ["-no_tls1_2"];
"OpenSSL 1.0.1d" ++ _ ->
- " -no_tls1_2 ";
+ ["-no_tls1_2"];
"OpenSSL 1.0.1e" ++ _ ->
- " -no_tls1_2 ";
+ ["-no_tls1_2"];
"OpenSSL 1.0.1f" ++ _ ->
- " -no_tls1_2 ";
+ ["-no_tls1_2"];
_ ->
- ""
+ []
end.
diff --git a/lib/ssl/test/ssl_upgrade_SUITE.erl b/lib/ssl/test/ssl_upgrade_SUITE.erl
new file mode 100644
index 0000000000..d65bdf6983
--- /dev/null
+++ b/lib/ssl/test/ssl_upgrade_SUITE.erl
@@ -0,0 +1,278 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-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.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssl_upgrade_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-record(state, {
+ config,
+ server,
+ client,
+ soft,
+ result_proxy
+ }).
+
+all() ->
+ [
+ minor_upgrade,
+ major_upgrade
+ ].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try {crypto:start(), erlang:system_info({wordsize, internal}) == erlang:system_info({wordsize, external})} of
+ {ok, true} ->
+ case ct_release_test:init(Config0) of
+ {skip, Reason} ->
+ {skip, Reason};
+ Config ->
+ {ok, _} = make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config)),
+ ssl_test_lib:cert_options(Config)
+ end;
+ {ok, false} ->
+ {skip, "Test server will not handle halfwordemulator correctly. Skip as halfwordemulator is deprecated"}
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(Config) ->
+ ct_release_test:cleanup(Config),
+ crypto:stop().
+
+init_per_testcase(_TestCase, Config) ->
+ ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
+ ct:timetrap({minutes, 1}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+major_upgrade(Config) when is_list(Config) ->
+ ct_release_test:upgrade(ssl, major,{?MODULE, #state{config = Config}}, Config).
+
+minor_upgrade(Config) when is_list(Config) ->
+ ct_release_test:upgrade(ssl, minor,{?MODULE, #state{config = Config}}, Config).
+
+upgrade_init(CTData, #state{config = Config} = State) ->
+ {ok, {_, _, Up, _Down}} = ct_release_test:get_appup(CTData, ssl),
+ ct:pal("Up: ~p", [Up]),
+ Soft = is_soft(Up), %% It is symmetrical, if upgrade is soft so is downgrade
+ Pid = spawn(?MODULE, result_proxy_init, [[]]),
+ case Soft of
+ true ->
+ {Server, Client} = soft_start_connection(Config, Pid),
+ State#state{server = Server, client = Client,
+ soft = Soft,
+ result_proxy = Pid};
+ false ->
+ State#state{soft = Soft, result_proxy = Pid}
+ end.
+
+upgrade_upgraded(_, #state{soft = false, config = Config, result_proxy = Pid} = State) ->
+ ct:pal("Restart upgrade ~n", []),
+ {Server, Client} = restart_start_connection(Config, Pid),
+ Result = check_result(Pid, Server, Client),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ok = Result,
+ State;
+
+upgrade_upgraded(_, #state{server = Server0, client = Client0,
+ config = Config, soft = true,
+ result_proxy = Pid} = State) ->
+ ct:pal("Soft upgrade: ~n", []),
+ Server0 ! changed_version,
+ Client0 ! changed_version,
+ Result = check_result(Pid, Server0, Client0),
+ ssl_test_lib:close(Server0),
+ ssl_test_lib:close(Client0),
+ ok = Result,
+ {Server, Client} = soft_start_connection(Config, Pid),
+ State#state{server = Server, client = Client}.
+
+upgrade_downgraded(_, #state{soft = false, config = Config, result_proxy = Pid} = State) ->
+ ct:pal("Restart downgrade: ~n", []),
+ {Server, Client} = restart_start_connection(Config, Pid),
+ Result = check_result(Pid, Server, Client),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ Pid ! stop,
+ ok = Result,
+ State;
+
+upgrade_downgraded(_, #state{server = Server, client = Client, soft = true, result_proxy = Pid} = State) ->
+ ct:pal("Soft downgrade: ~n", []),
+ Server ! changed_version,
+ Client ! changed_version,
+ Result = check_result(Pid, Server, Client),
+ Pid ! stop,
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ok = Result,
+ State.
+
+use_connection(Socket) ->
+ ssl_test_lib:send_recv_result_active(Socket),
+ receive
+ changed_version ->
+ ssl_test_lib:send_recv_result_active(Socket)
+ end.
+
+soft_start_connection(Config, ResulProxy) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = start_server([{node, ServerNode}, {port, 0},
+ {from, ResulProxy},
+ {mfa, {?MODULE, use_connection, []}},
+ {options, ServerOpts}]),
+
+ Port = inet_port(ResulProxy, Server),
+ Client = start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, ResulProxy},
+ {mfa, {?MODULE, use_connection, []}},
+ {options, ClientOpts}]),
+ {Server, Client}.
+
+restart_start_connection(Config, ResulProxy) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = start_server([{node, ServerNode}, {port, 0},
+ {from, ResulProxy},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = inet_port(ResulProxy, Server),
+ Client = start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, ResulProxy},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+ {Server, Client}.
+
+is_soft([{restart_application, ssl}]) ->
+ false;
+is_soft(_) ->
+ true.
+
+result_proxy_init(Args) ->
+ result_proxy_loop(Args).
+
+result_proxy_loop(Args) ->
+ receive
+ {Pid, {check_result, Server, Client}} ->
+ Result = do_check_result(Server, ok, Client, ok),
+ Pid ! {self(), Result},
+ result_proxy_loop(Args);
+ {Pid, port, Server} ->
+ Port = recv_port(Server),
+ Pid ! Port,
+ result_proxy_loop(Args);
+ {Pid, listen} ->
+ recv_listen(),
+ Pid ! ok,
+ result_proxy_loop(Args);
+ {Pid, connected} ->
+ Connected = recv_connected(),
+ Pid ! Connected,
+ result_proxy_loop(Args)
+ end.
+
+check_result(Pid, Server, Client) ->
+ Pid ! {self(), {check_result, Server, Client}},
+ receive
+ {Pid, Result} ->
+ Result
+ end.
+
+do_check_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ do_check_result(Client, ClientMsg);
+
+ {Client, ClientMsg} ->
+ do_check_result(Server, ServerMsg);
+ Unexpected ->
+ {{expected, {Client, ClientMsg}},
+ {expected, {Server, ServerMsg}}, {got, Unexpected}}
+ end.
+
+do_check_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ Unexpected ->
+ {{expected, {Pid, Msg}},
+ {got, Unexpected}}
+ end.
+
+inet_port(Pid, Server) ->
+ Pid ! {self(), port, Server},
+ receive
+ {port, Port} ->
+ Port
+ end.
+
+recv_port(Server) ->
+ receive
+ {Server, {port, Port}} ->
+ {port, Port}
+ end.
+
+recv_connected() ->
+ receive
+ {connected, _Socket} ->
+ ok;
+ {connect_failed, Reason} ->
+ {connect_failed, Reason}
+ end.
+
+
+start_server(Args) ->
+ Pid = proplists:get_value(from, Args),
+ Result = spawn_link(ssl_test_lib, run_server, [Args]),
+ Pid ! {self(), listen},
+ receive
+ ok ->
+ ok
+ end,
+ Result.
+
+start_client(Args) ->
+ Pid = proplists:get_value(from, Args),
+ Result = spawn_link(ssl_test_lib, run_client_init, [lists:delete(return_socket, Args)]),
+ Pid ! {self(), connected},
+ receive
+ ok ->
+ Result;
+ Reason ->
+ exit(Reason)
+ end.
+
+recv_listen()->
+ receive
+ {listen, up} ->
+ ok
+ end.
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index d5a9a71736..bd6ecebbd4 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 6.0.1
+SSL_VSN = 7.3.3
diff --git a/lib/stdlib/Makefile b/lib/stdlib/Makefile
index 01d299fd32..563a2defa2 100644
--- a/lib/stdlib/Makefile
+++ b/lib/stdlib/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile
index ff77c3eea0..196c86748f 100644
--- a/lib/stdlib/doc/src/Makefile
+++ b/lib/stdlib/doc/src/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+# Copyright Ericsson AB 1997-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -48,6 +49,7 @@ XML_REF3_FILES = \
digraph.xml \
digraph_utils.xml \
epp.xml \
+ erl_anno.xml \
erl_eval.xml \
erl_expand_records.xml \
erl_id_trans.xml \
@@ -76,12 +78,12 @@ XML_REF3_FILES = \
ms_transform.xml \
orddict.xml \
ordsets.xml \
- pg.xml \
pool.xml \
proc_lib.xml \
proplists.xml \
qlc.xml \
queue.xml \
+ rand.xml \
random.xml \
re.xml \
sets.xml \
@@ -101,7 +103,7 @@ XML_REF3_FILES = \
XML_REF6_FILES = stdlib_app.xml
XML_PART_FILES = part.xml part_notes.xml part_notes_history.xml
-XML_CHAPTER_FILES = io_protocol.xml unicode_usage.xml notes.xml notes_history.xml
+XML_CHAPTER_FILES = io_protocol.xml unicode_usage.xml notes.xml notes_history.xml assert_hrl.xml
BOOK_FILES = book.xml
diff --git a/lib/stdlib/doc/src/array.xml b/lib/stdlib/doc/src/array.xml
index b03a2fa0cc..0f33e2621c 100644
--- a/lib/stdlib/doc/src/array.xml
+++ b/lib/stdlib/doc/src/array.xml
@@ -7,16 +7,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -93,9 +94,6 @@ the default value cannot be confused with the values of set entries.</p>
</datatype>
<datatype>
<name name="array" n_vars="0"/>
- <desc>
- <p><c>array()</c> is equivalent to <c>array(term())</c>.</p>
- </desc>
</datatype>
<datatype>
<name name="array_indx"/>
@@ -166,7 +164,7 @@ the default value cannot be confused with the values of set entries.</p>
</fsummary>
<desc><marker id="from_list-1"/>
-<p>Equivalent to <seealso marker="#from_list-2">from_list(<anno>List</anno>, undefined)</seealso>.</p>
+<p>Equivalent to <seealso marker="#from_list-2">from_list(<c><anno>List</anno></c>, undefined)</seealso>.</p>
</desc></func>
<func>
<name name="from_list" arity="2"/>
@@ -186,7 +184,7 @@ the default value cannot be confused with the values of set entries.</p>
</fsummary>
<desc><marker id="from_orddict-1"/>
-<p>Equivalent to <seealso marker="#from_orddict-2">from_orddict(<anno>Orddict</anno>, undefined)</seealso>.</p>
+<p>Equivalent to <seealso marker="#from_orddict-2">from_orddict(<c><anno>Orddict</anno></c>, undefined)</seealso>.</p>
</desc></func>
<func>
<name name="from_orddict" arity="2"/>
diff --git a/lib/stdlib/doc/src/assert_hrl.xml b/lib/stdlib/doc/src/assert_hrl.xml
new file mode 100644
index 0000000000..ef4f928e57
--- /dev/null
+++ b/lib/stdlib/doc/src/assert_hrl.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE fileref SYSTEM "fileref.dtd">
+
+<fileref>
+ <header>
+ <copyright>
+ <year>2012</year><year>2015</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>assert.hrl</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <file>assert.hrl</file>
+ <filesummary>Assert Macros</filesummary>
+ <description>
+ <p>The include file <c>assert.hrl</c> provides macros for inserting
+ assertions in your program code.</p>
+ <p>These macros are defined in the Stdlib include file
+ <c>assert.hrl</c>. Include the following directive in the module
+ from which the function is called:</p>
+ <code type="none">
+-include_lib("stdlib/include/assert.hrl").</code>
+ <p>When an assertion succeeds, the assert macro yields the atom
+ <c>ok</c>. When an assertion fails, an exception of type <c>error</c> is
+ instead generated. The associated error term will have the form
+ <c>{Macro, Info}</c>, where <c>Macro</c> is the name of the macro, for
+ example <c>assertEqual</c>, and <c>Info</c> will be a list of tagged
+ values such as <c>[{module, M}, {line, L}, ...]</c> giving more
+ information about the location and cause of the exception. All entries
+ in the <c>Info</c> list are optional, and you should not rely
+ programatically on any of them being present.</p>
+
+ <p>If the macro <c>NOASSERT</c> is defined when the <c>assert.hrl</c>
+ include file is read by the compiler, the macros will be defined as
+ equivalent to the atom <c>ok</c>. The test will not be performed, and
+ there will be no cost at runtime.</p>
+
+ <p>For example, using <c>erlc</c> to compile your modules, the following
+ will disable 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>A few other macros also have effect on the enabling or disabling of
+ assertions:</p>
+ <list type="bulleted">
+ <item>If <c>NODEBUG</c> is defined, it implies <c>NOASSERT</c>, unless
+ <c>DEBUG</c> is also defined, which is assumed to take
+ precedence.</item>
+ <item>If <c>ASSERT</c> is defined, it overrides <c>NOASSERT</c>, that
+ is, the assertions will remain enabled.</item>
+ </list>
+ <p>If you prefer, you can thus use only <c>DEBUG</c>/<c>NODEBUG</c> as
+ the main flags to control the behaviour of the assertions (which is
+ useful if you have other compiler conditionals or debugging macros
+ controlled by those flags), or you can use <c>ASSERT</c>/<c>NOASSERT</c>
+ to control only the assert macros.</p>
+
+ </description>
+
+ <section>
+ <title>Macros</title>
+ <taglist>
+ <tag><c>assert(BoolExpr)</c></tag>
+ <item><p>Tests that <c>BoolExpr</c> completes normally returning
+ <c>true</c>.</p>
+ </item>
+
+ <tag><c>assertNot(BoolExpr)</c></tag>
+ <item><p>Tests that <c>BoolExpr</c> completes normally returning
+ <c>false</c>.</p>
+ </item>
+
+ <tag><c>assertMatch(GuardedPattern, Expr)</c></tag>
+ <item><p>Tests that <c>Expr</c> completes normally yielding a value
+ that matches <c>GuardedPattern</c>. For example:</p>
+ <code type="none">
+ ?assertMatch({bork, _}, f())</code>
+ <p>Note that a guard <c>when ...</c> can be included:</p>
+ <code type="none">
+ ?assertMatch({bork, X} when X > 0, f())</code>
+ </item>
+
+ <tag><c>assertNotMatch(GuardedPattern, Expr)</c></tag>
+ <item><p>Tests that <c>Expr</c> completes normally yielding a value
+ that does not match <c>GuardedPattern</c>.</p>
+ <p>As in <c>assertMatch</c>, <c>GuardedPattern</c> can have a
+ <c>when</c> part.</p>
+ </item>
+
+ <tag><c>assertEqual(ExpectedValue, Expr)</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>
+ <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>
+ <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 if <c>Expr</c> raises a different exception or if it
+ completes normally returning any value.</p>
+ <p>Note that both <c>Class</c> and <c>Term</c> can be guarded
+ patterns, as in <c>assertMatch</c>.</p>
+ </item>
+
+ <tag><c>assertNotException(Class, Term, Expr)</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>.
+ The assertion succeeds if <c>Expr</c> raises a different exception or
+ if it completes normally returning any value.</p>
+ <p>As in <c>assertException</c>, both <c>Class</c> and <c>Term</c>
+ can be guarded patterns.</p>
+ </item>
+
+ <tag><c>assertError(Term, Expr)</c></tag>
+ <item><p>Equivalent to <c>assertException(error, Term,
+ Expr)</c></p>
+ </item>
+
+ <tag><c>assertExit(Term, Expr)</c></tag>
+ <item><p>Equivalent to <c>assertException(exit, Term, Expr)</c></p>
+ </item>
+
+ <tag><c>assertThrow(Term, Expr)</c></tag>
+ <item><p>Equivalent to <c>assertException(throw, Term, Expr)</c></p>
+ </item>
+
+ </taglist>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="compiler:compile">compile(3)</seealso></p>
+ <p><seealso marker="erts:erlc">erlc(3)</seealso></p>
+ </section>
+</fileref>
diff --git a/lib/stdlib/doc/src/base64.xml b/lib/stdlib/doc/src/base64.xml
index c4982f4eaa..276d28e174 100644
--- a/lib/stdlib/doc/src/base64.xml
+++ b/lib/stdlib/doc/src/base64.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index eb4974a79f..7c89c8b43e 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -70,6 +71,7 @@
using <seealso marker="#strip/1">strip/1</seealso>,
<seealso marker="#strip_files/1">strip_files/1</seealso> and/or
<seealso marker="#strip_release/1">strip_release/1</seealso>.</p>
+ </section>
<section>
<title>Reconstructing source code</title>
<p>Here is an example of how to reconstruct source code from
@@ -151,7 +153,6 @@
keys.</p>
</note>
</section>
- </section>
<datatypes>
<datatype>
@@ -223,6 +224,13 @@
<funcs>
<func>
+ <name name="all_chunks" arity="1"/>
+ <fsummary>Read all chunks from a BEAM file or binary</fsummary>
+ <desc>
+ <p>Reads chunk data for all chunks.</p>
+ </desc>
+ </func>
+ <func>
<name name="chunks" arity="2"/>
<fsummary>Read selected chunks from a BEAM file or binary</fsummary>
<desc>
@@ -250,6 +258,13 @@
</desc>
</func>
<func>
+ <name name="build_module" arity="1"/>
+ <fsummary>Creates a BEAM module from a list of chunks</fsummary>
+ <desc>
+ <p>Builds a BEAM module (as a binary) from a list of chunks.</p>
+ </desc>
+ </func>
+ <func>
<name name="version" arity="1"/>
<fsummary>Read the BEAM file's module version</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/binary.xml b/lib/stdlib/doc/src/binary.xml
index 2410f1f9b8..2682198fe5 100644
--- a/lib/stdlib/doc/src/binary.xml
+++ b/lib/stdlib/doc/src/binary.xml
@@ -5,20 +5,21 @@
<header>
<copyright>
<year>2009</year>
- <year>2013</year>
+ <year>2014</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved on line at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -298,8 +299,8 @@
</func>
<func>
<name name="match" arity="3"/>
- <type name="part"/>
<fsummary>Searches for the first match of a pattern in a binary</fsummary>
+ <type name="part"/>
<desc>
<p>Searches for the first occurrence of <c><anno>Pattern</anno></c> in <c><anno>Subject</anno></c> and
@@ -352,8 +353,8 @@
</func>
<func>
<name name="matches" arity="3"/>
- <type name="part"/>
<fsummary>Searches for all matches of a pattern in a binary</fsummary>
+ <type name="part"/>
<desc>
<p>Works like <c>match/2</c>, but the <c><anno>Subject</anno></c> is searched until
@@ -450,7 +451,7 @@ store(Binary, GBSet) ->
</code>
<p>In this example, we chose to copy the binary content before
- inserting it in the <c>gb_set()</c> if it references a binary more than
+ inserting it in the <c>gb_sets:set()</c> if it references a binary more than
twice the size of the data we're going to keep. Of course
different rules for when copying will apply to different
programs.</p>
@@ -578,6 +579,10 @@ store(Binary, GBSet) ->
<item><p>Removes trailing empty parts of the result (as does trim in <c>re:split/3</c>)</p></item>
+ <tag>trim_all</tag>
+
+ <item><p>Removes all empty parts of the result.</p></item>
+
<tag>global</tag>
<item><p>Repeats the split until the <c><anno>Subject</anno></c> is
diff --git a/lib/stdlib/doc/src/book.xml b/lib/stdlib/doc/src/book.xml
index b1b67d661c..043f6cc19b 100644
--- a/lib/stdlib/doc/src/book.xml
+++ b/lib/stdlib/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/c.xml b/lib/stdlib/doc/src/c.xml
index b49fa6ad67..e5238fa7db 100644
--- a/lib/stdlib/doc/src/c.xml
+++ b/lib/stdlib/doc/src/c.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -120,12 +121,12 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
<name>lc(Files) -> ok</name>
+ <fsummary>Compile a list of files</fsummary>
<type>
<v>Files = [File]</v>
<v>File = <seealso marker="file#type-filename">file:filename()
</seealso></v>
</type>
- <fsummary>Compile a list of files</fsummary>
<desc>
<p>Compiles a list of files by calling <c>compile:file(File, [report_errors, report_warnings])</c> for each <c>File</c>
in <c>Files</c>.</p>
@@ -232,6 +233,14 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</desc>
</func>
<func>
+ <name name="uptime" arity="0"/>
+ <fsummary>Print node uptime</fsummary>
+ <desc>
+ <p>Prints the node uptime (as given by
+ <c>erlang:statistics(wall_clock)</c>), in human-readable form.</p>
+ </desc>
+ </func>
+ <func>
<name>xm(ModSpec) -> void()</name>
<fsummary>Cross reference check a module</fsummary>
<type>
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index e32a639b81..853184dc0f 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -129,11 +130,11 @@
<func>
<name name="date_to_gregorian_days" arity="1"/>
<name name="date_to_gregorian_days" arity="3"/>
+ <fsummary>Compute the number of days from year 0 up to the given date</fsummary>
<type variable="Date" name_i="1"/>
<type variable="Year"/>
<type variable="Month"/>
<type variable="Day"/>
- <fsummary>Compute the number of days from year 0 up to the given date</fsummary>
<desc>
<p>This function computes the number of gregorian days starting
with year 0 and ending at the given date.</p>
@@ -270,7 +271,8 @@
<fsummary>Convert now to local date and time</fsummary>
<desc>
<p>This function returns local date and time converted from
- the return value from <c>erlang:now()</c>.</p>
+ the return value from
+ <seealso marker="erts:erlang#timestamp/0"><c>erlang:timestamp/0</c></seealso>.</p>
</desc>
</func>
<func>
@@ -279,7 +281,8 @@
<fsummary>Convert now to date and time</fsummary>
<desc>
<p>This function returns Universal Coordinated Time (UTC)
- converted from the return value from <c>erlang:now()</c>.</p>
+ converted from the return value from
+ <seealso marker="erts:erlang#timestamp/0"><c>erlang:timestamp/0</c></seealso>.</p>
</desc>
</func>
<func>
@@ -344,11 +347,11 @@
<func>
<name name="valid_date" arity="1"/>
<name name="valid_date" arity="3"/>
+ <fsummary>Check if a date is valid</fsummary>
<type variable="Date" name_i="1"/>
<type variable="Year"/>
<type variable="Month"/>
<type variable="Day"/>
- <fsummary>Check if a date is valid</fsummary>
<desc>
<p>This function checks if a date is a valid.</p>
</desc>
diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml
index 6bbedb0662..48400733d1 100644
--- a/lib/stdlib/doc/src/dets.xml
+++ b/lib/stdlib/doc/src/dets.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -315,20 +316,20 @@
bytes.</p>
</item>
<item>
- <p><c>{filename, <seealso marker="file#type-name">file:name()</seealso>}</c>,
+ <p><c>{filename, </c><seealso marker="file#type-name">file:name()</seealso><c>}</c>,
the name of the file where objects are stored.</p>
</item>
<item>
- <p><c>{keypos, <seealso marker="#type-keypos">keypos()</seealso>}
- </c>, the position of the key.</p>
+ <p><c>{keypos, </c><seealso marker="#type-keypos">keypos()</seealso>
+ <c>}</c>, the position of the key.</p>
</item>
<item>
<p><c>{size, integer() >= 0}</c>, the number of objects stored
in the table.</p>
</item>
<item>
- <p><c>{type, <seealso marker="#type-type">type()</seealso>}</c>,
- the type of the table.</p>
+ <p><c>{type, </c><seealso marker="#type-type">type()</seealso>
+ <c>}</c>, the type of the table.</p>
</item>
</list>
</desc>
@@ -344,12 +345,12 @@
allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access, <seealso marker="#type-access">access()</seealso>}
- </c>, the access mode.</p>
+ <p><c>{access, </c><seealso marker="#type-access">access()</seealso>
+ <c>}</c>, the access mode.</p>
</item>
<item>
- <p><c>{auto_save, <seealso marker="#type-auto_save">
- auto_save()</seealso>}</c>, the auto save interval.</p>
+ <p><c>{auto_save, </c><seealso marker="#type-auto_save">
+ auto_save()</seealso><c>}</c>, the auto save interval.</p>
</item>
<item>
<p><c>{bchunk_format, binary()}</c>, an opaque binary
@@ -398,15 +399,40 @@
kept in RAM.</p>
</item>
<item>
- <p><c>{safe_fixed,</c> SafeFixed<c>}</c>. If the table
- is fixed, SafeFixed is a tuple <c>{FixedAtTime, [{Pid,RefCount}]}</c>. <c>FixedAtTime</c> is the time when
+ <p><c>{safe_fixed_monotonic_time, SafeFixed}</c>. If the table
+ is fixed, <c>SafeFixed</c> is a tuple <c>{FixedAtTime, [{Pid,RefCount}]}</c>.
+ <c>FixedAtTime</c> is the time when
the table was first fixed, and <c>Pid</c> is the pid of
the process that fixes the table <c>RefCount</c> times.
There may be any number of processes in the list. If the
table is not fixed, SafeFixed is the atom <c>false</c>.</p>
+ <p><c>FixedAtTime</c> will correspond to the result
+ returned by
+ <seealso marker="erts:erlang#monotonic_time/0">erlang:monotonic_time/0</seealso>
+ at the time of fixation. The usage of <c>safe_fixed_monotonic_time</c> is
+ <seealso marker="erts:time_correction#Time_Warp_Safe_Code">time warp
+ safe</seealso>.</p>
+ </item>
+ <item>
+ <p>
+ <c>{safe_fixed, SafeFixed}</c>. The same as
+ <c>{safe_fixed_monotonic_time, SafeFixed}</c> with the exception
+ of the format and value of <c>FixedAtTime</c>.
+ </p>
+ <p>
+ <c>FixedAtTime</c> will correspond to the result returned by
+ <seealso marker="erts:erlang#timestamp/0">erlang:timestamp/0</seealso>
+ at the time of fixation. Note that when the system is using
+ single or multi
+ <seealso marker="erts:time_correction#Time_Warp_Modes">time warp
+ modes</seealso> this might produce strange results. This
+ since the usage of <c>safe_fixed</c> is not
+ <seealso marker="erts:time_correction#Time_Warp_Safe_Code">time warp
+ safe</seealso>. Time warp safe code need to use
+ <c>safe_fixed_monotonic_time</c> instead.</p>
</item>
<item>
- <p><c>{version, integer()</c>, the version of the format of
+ <p><c>{version, integer()}</c>, the version of the format of
the table.</p>
</item>
</list>
@@ -729,16 +755,16 @@ ok
tuples where the following values are allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access, <seealso marker="#type-access">
- access()</seealso>}</c>. It is possible to open
+ <p><c>{access, </c><seealso marker="#type-access">
+ access()</seealso><c>}</c>. It is possible to open
existing tables in read-only mode. A table which is opened
in read-only mode is not subjected to the automatic file
reparation algorithm if it is later opened after a crash.
The default value is <c>read_write</c>.</p>
</item>
<item>
- <p><c>{auto_save, <seealso marker="#type-auto_save">
- auto_save()</seealso>}</c>, the auto save
+ <p><c>{auto_save, </c><seealso marker="#type-auto_save">
+ auto_save()</seealso><c>}</c>, the auto save
interval. If the interval is an integer <c>Time</c>, the
table is flushed to disk whenever it is not accessed for
<c>Time</c> milliseconds. A table that has been flushed
@@ -748,18 +774,18 @@ ok
is 180000 (3 minutes).</p>
</item>
<item>
- <p><c>{estimated_no_objects, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>. Equivalent to the
+ <p><c>{estimated_no_objects, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>. Equivalent to the
<c>min_no_slots</c> option.</p>
</item>
<item>
- <p><c>{file, <seealso marker="file#type-name">
- file:name()</seealso>}</c>, the name of the file to be
+ <p><c>{file, </c><seealso marker="file#type-name">
+ file:name()</seealso><c>}</c>, the name of the file to be
opened. The default value is the name of the table.</p>
</item>
<item>
- <p><c>{max_no_slots, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>, the maximum number
+ <p><c>{max_no_slots, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>, the maximum number
of slots that will be used. The default value as well as
the maximal value is 32 M. Note that a higher value may
increase the fragmentation of the table, and conversely,
@@ -768,16 +794,16 @@ ok
9 tables.</p>
</item>
<item>
- <p><c>{min_no_slots, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>. Application
+ <p><c>{min_no_slots, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>. Application
performance can be enhanced with this flag by specifying,
when the table is created, the estimated number of
different keys that will be stored in the table. The
default value as well as the minimum value is 256.</p>
</item>
<item>
- <p><c>{keypos, <seealso marker="#type-keypos">
- keypos()</seealso>}</c>, the position of the
+ <p><c>{keypos, </c><seealso marker="#type-keypos">
+ keypos()</seealso><c>}</c>, the position of the
element of each object to be used as key. The default
value is 1. The ability to explicitly state the key
position is most convenient when we want to store Erlang
@@ -814,12 +840,12 @@ ok
already open.</p>
</item>
<item>
- <p><c>{type, <seealso marker="#type-type">type()</seealso>}</c>,
+ <p><c>{type, </c><seealso marker="#type-type">type()</seealso><c>}</c>,
the type of the table. The default value is <c>set</c>.</p>
</item>
<item>
- <p><c>{version, <seealso marker="#type-version">
- version()</seealso>}</c>, the version of the format
+ <p><c>{version, </c><seealso marker="#type-version">
+ version()</seealso><c>}</c>, the version of the format
used for the table. The default value is <c>9</c>. Tables
on the format used before OTP R8 can be created by giving
the value <c>8</c>. A version 8 table can be converted to
@@ -1035,8 +1061,8 @@ ok
specification that matches all objects.</p>
</item>
<item>
- <p><c>{select, <seealso marker="#type-match_spec">
- match_spec()}</seealso></c>. As for <c>select</c>
+ <p><c>{select, </c><seealso marker="#type-match_spec">
+ match_spec()</seealso><c>}</c>. As for <c>select</c>
the table is traversed by calling <c>dets:select/3</c>
and <c>dets:select/1</c>. The difference is that the
match specification is explicitly given. This is how to
diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml
index 0771682a25..e10531caac 100644
--- a/lib/stdlib/doc/src/dict.xml
+++ b/lib/stdlib/doc/src/dict.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -46,9 +47,6 @@
</datatype>
<datatype>
<name name="dict" n_vars="0"/>
- <desc>
- <p><c>dict()</c> is equivalent to <c>dict(term(), term())</c>.</p>
- </desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/digraph.xml b/lib/stdlib/doc/src/digraph.xml
index 9b9b48584b..291be6c08b 100644
--- a/lib/stdlib/doc/src/digraph.xml
+++ b/lib/stdlib/doc/src/digraph.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -102,13 +103,15 @@
<desc><p>A digraph as returned by <c>new/0,1</c>.</p></desc>
</datatype>
<datatype>
- <name><marker id="type-edge">edge()</marker></name>
+ <name>edge()</name>
+ <desc><p><marker id="type-edge"/></p></desc>
</datatype>
<datatype>
<name name="label"/>
</datatype>
<datatype>
- <name><marker id="type-vertex">vertex()</marker></name>
+ <name>vertex()</name>
+ <desc><p><marker id="type-vertex"/></p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/digraph_utils.xml b/lib/stdlib/doc/src/digraph_utils.xml
index ef6f9d8611..639069543c 100644
--- a/lib/stdlib/doc/src/digraph_utils.xml
+++ b/lib/stdlib/doc/src/digraph_utils.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -121,8 +122,9 @@
<datatypes>
<datatype>
- <name><marker id="type-digraph">digraph()</marker></name>
- <desc><p>A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
+ <name>digraph()</name>
+ <desc><p><marker id="type-digraph"/>
+ A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml
index 452341f7d2..8c901f57ec 100644
--- a/lib/stdlib/doc/src/epp.xml
+++ b/lib/stdlib/doc/src/epp.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -38,7 +39,7 @@
by <c>compile</c> to preprocess macros and include files before
the actual parsing takes place.</p>
<p>The Erlang source file <marker
- id="encoding"><em>encoding</em></marker> is selected by a
+ id="encoding"/><em>encoding</em> is selected by a
comment in one of the first two lines of the source file. The
first string that matches the regular expression
<c>coding\s*[:=]\s*([-a-zA-Z0-9])+</c> selects the encoding. If
diff --git a/lib/stdlib/doc/src/erl_anno.xml b/lib/stdlib/doc/src/erl_anno.xml
new file mode 100644
index 0000000000..ddc8b8c765
--- /dev/null
+++ b/lib/stdlib/doc/src/erl_anno.xml
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2015</year>
+ <year>2015</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>erl_anno</title>
+ <prepared>Hans Bolinder</prepared>
+ <responsible>Kenneth Lundin</responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2015-02-26</date>
+ <rev>A</rev>
+ <file>erl_anno.xml</file>
+ </header>
+ <module>erl_anno</module>
+
+ <modulesummary>
+ Abstract Datatype for the Annotations of the Erlang Compiler
+ </modulesummary>
+
+ <description>
+ <p>This module implements an abstract type that is used by the
+ Erlang Compiler and its helper modules for holding data such as
+ column, line number, and text. The data type is a collection of
+ <marker id="annotations"/><em>annotations</em> as
+ described in the following.</p>
+ <p>The Erlang Token Scanner returns tokens with a subset of
+ the following annotations, depending on the options:</p>
+ <taglist>
+ <tag><c>column</c></tag>
+ <item><p>The column where the token begins.</p></item>
+ <tag><c>location</c></tag>
+ <item><p>The line and column where the token begins, or
+ just the line if the column unknown.</p>
+ </item>
+ <tag><c>text</c></tag>
+ <item><p>The token's text.</p></item>
+ </taglist>
+ <p>From the above the following annotation is derived:</p>
+ <taglist>
+ <tag><c>line</c></tag>
+ <item><p>The line where the token begins.</p></item>
+ </taglist>
+ <p>Furthermore, the following annotations are supported by
+ this module, and used by various modules:</p>
+ <taglist>
+ <tag><c>file</c></tag>
+ <item><p>A filename.</p></item>
+ <tag><c>generated</c></tag>
+ <item><p>A Boolean indicating if the abstract code is
+ compiler generated. The Erlang Compiler does not emit warnings
+ for such code.</p>
+ </item>
+ <tag><c>record</c></tag>
+ <item><p>A Boolean indicating if the origin of the abstract
+ code is a record. Used by Dialyzer to assign types to tuple
+ elements.</p>
+ </item>
+ </taglist>
+ <p>The functions
+ <seealso marker="erl_scan#column/1">column()</seealso>,
+ <seealso marker="erl_scan#end_location/1">end_location()</seealso>,
+ <seealso marker="erl_scan#line/1">line()</seealso>,
+ <seealso marker="erl_scan#location/1">location()</seealso>, and
+ <seealso marker="erl_scan#text/1">text()</seealso>
+ in the <c>erl_scan</c> module can be used for inspecting
+ annotations in tokens.</p>
+ <p>The functions
+ <seealso marker="erl_parse#map_anno/2">map_anno()</seealso>,
+ <seealso marker="erl_parse#fold_anno/3">fold_anno()</seealso>,
+ <seealso marker="erl_parse#mapfold_anno/3">mapfold_anno()</seealso>,
+ <seealso marker="erl_parse#new_anno/1">new_anno()</seealso>,
+ <seealso marker="erl_parse#anno_from_term/1">
+ anno_from_term()</seealso>, and
+ <seealso marker="erl_parse#anno_to_term/1">
+ anno_to_term()</seealso> in the <c>erl_parse</c> module can be
+ used for manipulating annotations in abstract code.
+ </p>
+ </description>
+
+ <datatypes>
+ <datatype>
+ <name>anno()</name>
+ <desc><p><marker id="type-anno"/>A collection of annotations.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="anno_term"></name>
+ <desc>
+ <p>The term representing a collection of annotations. It is
+ either a <c>location()</c> or a list of key-value pairs.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="column"></name>
+ </datatype>
+ <datatype>
+ <name name="line"></name>
+ <desc>
+ <p>To be changed to a non-negative integer in Erlang/OTP 19.0.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="location"></name>
+ </datatype>
+ <datatype>
+ <name name="text"></name>
+ </datatype>
+ </datatypes>
+
+ <funcs>
+ <func>
+ <name name="column" arity="1"/>
+ <fsummary>Return the column</fsummary>
+ <type name="column"></type>
+ <desc>
+ <p>Returns the column of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="end_location" arity="1"/>
+ <fsummary>Return the end location of the text</fsummary>
+ <type name="location"></type>
+ <desc>
+ <p>Returns the end location of the text of the
+ annotations <anno>Anno</anno>. If there is no text,
+ <c>undefined</c> is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="file" arity="1"/>
+ <fsummary>Return the filename</fsummary>
+ <type name="filename"></type>
+ <desc>
+ <p>Returns the filename of the annotations <anno>Anno</anno>.
+ If there is no filename, <c>undefined</c> is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="from_term" arity="1"/>
+ <fsummary>Return annotations given a term</fsummary>
+ <desc>
+ <p>Returns annotations with the representation <anno>Term</anno>.
+ </p>
+ <!--
+ <p>Although it is possible to create new annotations by calling
+ <c>from_term/1</c>, the intention is that one should not do
+ so - the proper way to create annotations is to call
+ <c>new/1</c> and then modify the annotations
+ by calling the <c>set_*</c> functions.</p>
+ -->
+ <p>See also <seealso marker="#to_term/1">to_term()</seealso>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="generated" arity="1"/>
+ <fsummary>Return the generated Boolean</fsummary>
+ <type name="generated"></type>
+ <desc>
+ <p>Returns <c>true</c> if the annotations <anno>Anno</anno>
+ has been marked as generated. The default is to return
+ <c>false</c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="is_anno" arity="1"/>
+ <fsummary>Test for a collection of annotations</fsummary>
+ <desc>
+ <p>Returns <c>true</c> if <anno>Term</anno> is a collection of
+ annotations, <c>false</c> otherwise.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="line" arity="1"/>
+ <fsummary>Return the line</fsummary>
+ <type name="line"></type>
+ <desc>
+ <p>Returns the line of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="location" arity="1"/>
+ <fsummary>Return the location</fsummary>
+ <type name="location"></type>
+ <desc>
+ <p>Returns the location of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="new" arity="1"/>
+ <fsummary>Create a new collection of annotations</fsummary>
+ <type name="location"></type>
+ <desc>
+ <p>Creates a new collection of annotations given a location.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="set_file" arity="2"/>
+ <fsummary>Modify the filename</fsummary>
+ <type name="filename"></type>
+ <desc>
+ <p>Modifies the filename of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="set_generated" arity="2"/>
+ <fsummary>Modify the generated marker</fsummary>
+ <type name="generated"></type>
+ <desc>
+ <p>Modifies the generated marker of the annotations
+ <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="set_line" arity="2"/>
+ <fsummary>Modify the line</fsummary>
+ <type name="line"></type>
+ <desc>
+ <p>Modifies the line of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="set_location" arity="2"/>
+ <fsummary>Modify the location</fsummary>
+ <type name="location"></type>
+ <desc>
+ <p>Modifies the location of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="set_record" arity="2"/>
+ <fsummary>Modify the record marker</fsummary>
+ <type name="record"></type>
+ <desc>
+ <p>Modifies the record marker of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="set_text" arity="2"/>
+ <fsummary>Modify the text</fsummary>
+ <type name="text"></type>
+ <desc>
+ <p>Modifies the text of the annotations <anno>Anno</anno>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="text" arity="1"/>
+ <fsummary>Return the text</fsummary>
+ <type name="text"></type>
+ <desc>
+ <p>Returns the text of the annotations <anno>Anno</anno>.
+ If there is no text, <c>undefined</c> is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="to_term" arity="1"/>
+ <fsummary>Return the term representing a collection of
+ annotations</fsummary>
+ <desc>
+ <p>Returns the term representing the annotations <anno>Anno</anno>.
+ </p>
+ <p>See also <seealso marker="#from_term/1">from_term()</seealso>.
+ </p>
+ </desc>
+ </func>
+ </funcs>
+ <section>
+ <title>See Also</title>
+ <p><seealso marker="erl_scan">erl_scan(3)</seealso>,
+ <seealso marker="erl_parse">erl_parse(3)</seealso>
+ </p>
+ </section>
+</erlref>
diff --git a/lib/stdlib/doc/src/erl_eval.xml b/lib/stdlib/doc/src/erl_eval.xml
index b707dbcc02..ba988e7ca2 100644
--- a/lib/stdlib/doc/src/erl_eval.xml
+++ b/lib/stdlib/doc/src/erl_eval.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/erl_expand_records.xml b/lib/stdlib/doc/src/erl_expand_records.xml
index 1b5ee5de36..497b371434 100644
--- a/lib/stdlib/doc/src/erl_expand_records.xml
+++ b/lib/stdlib/doc/src/erl_expand_records.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/erl_id_trans.xml b/lib/stdlib/doc/src/erl_id_trans.xml
index 0f7042f0c6..30eb213493 100644
--- a/lib/stdlib/doc/src/erl_id_trans.xml
+++ b/lib/stdlib/doc/src/erl_id_trans.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/erl_internal.xml b/lib/stdlib/doc/src/erl_internal.xml
index 54e560f8b9..e1ee50b424 100644
--- a/lib/stdlib/doc/src/erl_internal.xml
+++ b/lib/stdlib/doc/src/erl_internal.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/erl_lint.xml b/lib/stdlib/doc/src/erl_lint.xml
index 1ca58baf9a..318cb5ac19 100644
--- a/lib/stdlib/doc/src/erl_lint.xml
+++ b/lib/stdlib/doc/src/erl_lint.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/erl_parse.xml b/lib/stdlib/doc/src/erl_parse.xml
index cf0bff48cd..0938b5dec3 100644
--- a/lib/stdlib/doc/src/erl_parse.xml
+++ b/lib/stdlib/doc/src/erl_parse.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2014</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -173,8 +174,8 @@
</func>
<func>
<name name="abstract" arity="2"/>
- <type name="encoding_func"/>
<fsummary>Convert an Erlang term into an abstract form</fsummary>
+ <type name="encoding_func"/>
<desc>
<p>Converts the Erlang data structure <c><anno>Data</anno></c> into an
abstract form of type <c><anno>AbsTerm</anno></c>.</p>
@@ -192,6 +193,97 @@
considered a string.</p>
</desc>
</func>
+ <func>
+ <name name="map_anno" arity="2"/>
+ <fsummary>
+ Map a function over the annotations of an abstract form
+ </fsummary>
+ <desc>
+ <p>Modifies the abstract form <anno>Abstr</anno> by applying
+ <anno>Fun</anno> on every collection of annotations of the
+ abstract form. The abstract form is traversed in a
+ depth-first, left-to-right, fashion.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="fold_anno" arity="3"/>
+ <fsummary>
+ Fold a function over the annotations of an abstract form
+ </fsummary>
+ <desc>
+ <p>Updates an accumulator by applying <anno>Fun</anno> on
+ every collection of annotations of the abstract form
+ <anno>Abstr</anno>. The first call to <anno>Fun</anno> has
+ <anno>AccIn</anno> as argument, and the returned accumulator
+ <anno>AccOut</anno> is passed to the next call, and so on.
+ The final value of the accumulator is returned. The abstract
+ form is traversed in a depth-first, left-to-right, fashion.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="mapfold_anno" arity="3"/>
+ <fsummary>
+ Map and fold a function over the annotations of an abstract form
+ </fsummary>
+ <desc>
+ <p>Modifies the abstract form <anno>Abstr</anno> by applying
+ <anno>Fun</anno> on every collection of annotations of the
+ abstract form, while at the same time updating an
+ accumulator. The first call to <anno>Fun</anno> has
+ <anno>AccIn</anno> as second argument, and the returned
+ accumulator <anno>AccOut</anno> is passed to the next call,
+ and so on. The modified abstract form as well as the the
+ final value of the accumulator is returned. The abstract
+ form is traversed in a depth-first, left-to-right, fashion.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="new_anno" arity="1"/>
+ <fsummary>
+ Create new annotations
+ </fsummary>
+ <desc>
+ <p>Creates an abstract form from a term which has the same
+ structure as an abstract form, but <seealso
+ marker="erl_anno#type-location">locations</seealso> where the
+ abstract form has annotations. For each location, <seealso
+ marker="erl_anno#new/1"><c>erl_anno:new/1</c></seealso> is
+ called, and the annotations replace the location.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="anno_from_term" arity="1"/>
+ <fsummary>
+ Return annotations as terms
+ </fsummary>
+ <desc>
+ <p>Assumes that <anno>Term</anno> is a term with the same
+ structure as an abstract form, but with terms, T say, on
+ those places where an abstract form has annotations. Returns
+ an abstract form where every term T has been replaced by the
+ value returned by calling <c>erl_anno:from_term(T)</c>. The
+ term <anno>Term</anno> is traversed in a depth-first,
+ left-to-right, fashion.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="anno_to_term" arity="1"/>
+ <fsummary>
+ Return the representation of annotations
+ </fsummary>
+ <desc>
+ <p>Returns a term where every collection of annotations Anno of
+ <anno>Abstr</anno> has been replaced by the term returned by
+ calling <c>erl_anno:to_term(Anno)</c>. The abstract form is
+ traversed in a depth-first, left-to-right, fashion.
+ </p>
+ </desc>
+ </func>
</funcs>
<section>
@@ -211,8 +303,9 @@
<section>
<title>See Also</title>
<p><seealso marker="io">io(3)</seealso>,
- <seealso marker="erl_scan">erl_scan(3)</seealso>,
- ERTS User's Guide</p>
+ <seealso marker="erl_anno">erl_anno(3)</seealso>,
+ <seealso marker="erl_scan">erl_scan(3)</seealso>,
+ <seealso marker="erts:absform">ERTS User's Guide</seealso></p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/erl_pp.xml b/lib/stdlib/doc/src/erl_pp.xml
index 005c101973..4b8a571c81 100644
--- a/lib/stdlib/doc/src/erl_pp.xml
+++ b/lib/stdlib/doc/src/erl_pp.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -47,8 +48,8 @@
<datatype>
<name name="hook_function"/>
<desc>
- <p>The optional argument <marker id="hook_function">
- <c>HookFunction</c></marker>, shown in the functions described below,
+ <p>The optional argument <marker id="hook_function"/>
+ <c>HookFunction</c>, shown in the functions described below,
defines a function which is called when an unknown form occurs where there
should be a valid expression.</p>
diff --git a/lib/stdlib/doc/src/erl_scan.xml b/lib/stdlib/doc/src/erl_scan.xml
index 855c8fc195..342f491dd0 100644
--- a/lib/stdlib/doc/src/erl_scan.xml
+++ b/lib/stdlib/doc/src/erl_scan.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -120,7 +121,7 @@
<c>string(<anno>String</anno>,
<anno>StartLocation</anno>, [])</c>.</p>
<p><c><anno>StartLocation</anno></c> indicates the initial location
- when scanning starts. If <c><anno>StartLocation</anno></c> is a line
+ when scanning starts. If <c><anno>StartLocation</anno></c> is a line,
<c>attributes()</c> as well as <c><anno>EndLocation</anno></c> and
<c><anno>ErrorLocation</anno></c> will be lines. If
<c><anno>StartLocation</anno></c> is a pair of a line and a column
@@ -132,8 +133,12 @@
line where the token begins, as well as the text of the
token (if the <c>text</c> option is given), all of which can
be accessed by calling <seealso
- marker="#token_info/1">token_info/1,2</seealso> or <seealso
- marker="#attributes_info/1">attributes_info/1,2</seealso>.</p>
+ marker="#token_info/1">token_info/1,2</seealso>, <seealso
+ marker="#attributes_info/1">attributes_info/1,2</seealso>,
+ <seealso marker="#column/1">column/1</seealso>,
+ <seealso marker="#line/1">line/1</seealso>,
+ <seealso marker="#location/1">location/1</seealso>, and
+ <seealso marker="#text/1">text/1</seealso>.</p>
<p>A <em>token</em> is a tuple containing information about
syntactic category, the token attributes, and the actual
terminal symbol. For punctuation characters (e.g. <c>;</c>,
@@ -176,10 +181,10 @@
<func>
<name name="tokens" arity="3"/>
<name name="tokens" arity="4"/>
+ <fsummary>Re-entrant scanner</fsummary>
<type name="char_spec"/>
<type name="return_cont"/>
<type_desc name="return_cont">An opaque continuation</type_desc>
- <fsummary>Re-entrant scanner</fsummary>
<desc>
<p>This is the re-entrant scanner which scans characters until
a <em>dot</em> ('.' followed by a white space) or
@@ -237,6 +242,70 @@
</desc>
</func>
<func>
+ <name name="category" arity="1"/>
+ <fsummary>Return the category</fsummary>
+ <desc>
+ <p>Returns the category of <c><anno>Token</anno></c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="symbol" arity="1"/>
+ <fsummary>Return the symbol</fsummary>
+ <desc>
+ <p>Returns the symbol of <c><anno>Token</anno></c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="column" arity="1"/>
+ <fsummary>Return the column</fsummary>
+ <desc>
+ <p>Returns the column of <c><anno>Token</anno></c>'s
+ collection of annotations.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="end_location" arity="1"/>
+ <fsummary>Return the end location of the text</fsummary>
+ <desc>
+ <p>Returns the end location of the text of
+ <c><anno>Token</anno></c>'s collection of annotations. If
+ there is no text,
+ <c>undefined</c> is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="line" arity="1"/>
+ <fsummary>Return the line</fsummary>
+ <desc>
+ <p>Returns the line of <c><anno>Token</anno></c>'s collection
+ of annotations.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="location" arity="1"/>
+ <fsummary>Return the location</fsummary>
+ <desc>
+ <p>Returns the location of <c><anno>Token</anno></c>'s
+ collection of annotations.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="text" arity="1"/>
+ <fsummary>Return the text</fsummary>
+ <desc>
+ <p>Returns the text of <c><anno>Token</anno></c>'s collection
+ of annotations. If there is no text, <c>undefined</c> is
+ returned.
+ </p>
+ </desc>
+ </func>
+ <func>
<name name="token_info" arity="1"/>
<fsummary>Return information about a token</fsummary>
<desc>
@@ -255,9 +324,9 @@
<func>
<name name="token_info" arity="2" clause_i="1"/>
<name name="token_info" arity="2" clause_i="2"/>
+ <fsummary>Return information about a token</fsummary>
<type name="token_item"/>
<type name="attribute_item"/>
- <fsummary>Return information about a token</fsummary>
<desc>
<p>Returns a list containing information about the token
<c><anno>Token</anno></c>. If one single
@@ -276,28 +345,28 @@
<p>The following <c><anno>TokenInfoTuple</anno></c>s with corresponding
<c><anno>TokenItem</anno></c>s are valid:</p>
<taglist>
- <tag><c>{category, <seealso marker="#type-category">
- category()</seealso>}</c></tag>
+ <tag><c>{category, </c><seealso marker="#type-category">
+ category()</seealso><c>}</c></tag>
<item><p>The category of the token.</p>
</item>
- <tag><c>{column, <seealso marker="#type-column">
- column()</seealso>}</c></tag>
+ <tag><c>{column, </c><seealso marker="#type-column">
+ column()</seealso><c>}</c></tag>
<item><p>The column where the token begins.</p>
</item>
<tag><c>{length, integer() > 0}</c></tag>
<item><p>The length of the token's text.</p>
</item>
- <tag><c>{line, <seealso marker="#type-line">
- line()</seealso>}</c></tag>
+ <tag><c>{line, </c><seealso marker="#type-line">
+ line()</seealso><c>}</c></tag>
<item><p>The line where the token begins.</p>
</item>
- <tag><c>{location, <seealso marker="#type-location">
- location()</seealso>}</c></tag>
+ <tag><c>{location, </c><seealso marker="#type-location">
+ location()</seealso><c>}</c></tag>
<item><p>The line and column where the token begins, or
just the line if the column unknown.</p>
</item>
- <tag><c>{symbol, <seealso marker="#type-symbol">
- symbol()</seealso>}</c></tag>
+ <tag><c>{symbol, </c><seealso marker="#type-symbol">
+ symbol()</seealso><c>}</c></tag>
<item><p>The token's symbol.</p>
</item>
<tag><c>{text, string()}</c></tag>
@@ -347,19 +416,19 @@
<p>The following <c><anno>AttributeInfoTuple</anno></c>s with
corresponding <c><anno>AttributeItem</anno></c>s are valid:</p>
<taglist>
- <tag><c>{column, <seealso marker="#type-column">
- column()</seealso>}</c></tag>
+ <tag><c>{column, </c><seealso marker="#type-column">
+ column()</seealso><c>}</c></tag>
<item><p>The column where the token begins.</p>
</item>
<tag><c>{length, integer() > 0}</c></tag>
<item><p>The length of the token's text.</p>
</item>
- <tag><c>{line, <seealso marker="#type-line">
- line()</seealso>}</c></tag>
+ <tag><c>{line, </c><seealso marker="#type-line">
+ line()</seealso><c>}</c></tag>
<item><p>The line where the token begins.</p>
</item>
- <tag><c>{location, <seealso marker="#type-location">
- location()</seealso>}</c></tag>
+ <tag><c>{location, </c><seealso marker="#type-location">
+ location()</seealso><c>}</c></tag>
<item><p>The line and column where the token begins, or
just the line if the column unknown.</p>
</item>
@@ -417,6 +486,7 @@ Module:format_error(ErrorDescriptor)</code>
<section>
<title>See Also</title>
<p><seealso marker="io">io(3)</seealso>,
- <seealso marker="erl_parse">erl_parse(3)</seealso></p>
+ <seealso marker="erl_anno">erl_anno(3)</seealso>,
+ <seealso marker="erl_parse">erl_parse(3)</seealso></p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml
index 95eefb8f9b..898b55df72 100644
--- a/lib/stdlib/doc/src/erl_tar.xml
+++ b/lib/stdlib/doc/src/erl_tar.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -441,7 +442,7 @@
structure like a file descriptor, a sftp channel id or such. The different <c>Fun</c>
clauses operates on that very term.
</p>
- <p>The fun clauses parameter lists are:
+ <p>The fun clauses parameter lists are:</p>
<taglist>
<tag><c>(write, {UserPrivate,DataToWrite})</c></tag>
<item>Write the term <c>DataToWrite</c> using <c>UserPrivate</c></item>
@@ -456,7 +457,6 @@
<tag><c></c></tag>
<item></item>
</taglist>
- </p>
<p>A complete <c>Fun</c> parameter for reading and writing on files using the
<seealso marker="kernel:file">file module</seealso> could be:
</p>
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index 3df24bf688..447fe51130 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -131,9 +132,10 @@
<name name="access"/>
</datatype>
<datatype>
- <name><marker id="type-continuation">continuation()</marker></name>
+ <name>continuation()</name>
<desc>
- <p>Opaque continuation used by <seealso marker="#select/1">
+ <p><marker id="type-continuation"/>
+ Opaque continuation used by <seealso marker="#select/1">
<c>select/1,3</c></seealso>, <seealso marker="#select_reverse/1">
<c>select_reverse/1,3</c></seealso>, <seealso
marker="#match/1">
@@ -447,15 +449,21 @@ Error: fun containing local Erlang function calls
<item><c>{owner, pid()}</c> <br></br>
The pid of the owner of the table.</item>
- <item><c>{protection, <seealso marker="#type-access">access()</seealso>}</c> <br></br>
+ <item><c>{protection, </c><seealso marker="#type-access">access()</seealso><c>}</c> <br></br>
The table access rights.</item>
<item><c>{size, integer() >= 0</c> <br></br>
The number of objects inserted in the table.</item>
- <item><c>{type, <seealso marker="#type-type">type()</seealso>}</c> <br></br>
+ <item><c>{type, </c><seealso marker="#type-type">type()</seealso><c>}</c> <br></br>
The table type.</item>
+ <item><c>{read_concurrency, boolean()}</c> <br></br>
+
+ Indicates whether the table uses read_concurrency or not.</item>
+ <item><c>{write_concurrency, boolean()}</c> <br></br>
+
+ Indicates whether the table uses write_concurrency or not.</item>
</list>
</desc>
</func>
@@ -480,14 +488,39 @@ Error: fun containing local Erlang function calls
<item><c>Item=fixed, Value=boolean()</c> <br></br>
Indicates if the table is fixed by any process or not.</item>
- <item>
- <p><c>Item=safe_fixed, Value={FirstFixed,Info}|false</c> <br></br>
+ <item><marker id="info_2_safe_fixed_monotonic_time"/>
+ <p><c>Item=safe_fixed|safe_fixed_monotonic_time, Value={FixationTime,Info}|false</c> <br></br>
</p>
- <p>If the table has been fixed using <c>safe_fixtable/2</c>,
- the call returns a tuple where <c>FirstFixed</c> is the
+ <p>If the table has been fixed using
+ <seealso marker="#safe_fixtable/2"><c>safe_fixtable/2</c></seealso>,
+ the call returns a tuple where <c>FixationTime</c> is the
time when the table was first fixed by a process, which
may or may not be one of the processes it is fixed by
right now.</p>
+ <p>The format and value of <c>FixationTime</c> depends on
+ <c>Item</c>:</p>
+ <taglist>
+ <tag><c>safe_fixed</c></tag>
+ <item><p><c>FixationTime</c> will correspond to the result
+ returned by
+ <seealso marker="erts:erlang#timestamp/0">erlang:timestamp/0</seealso>
+ at the time of fixation. Note that when the system is using
+ single or multi
+ <seealso marker="erts:time_correction#Time_Warp_Modes">time warp
+ modes</seealso> this might produce strange results. This
+ since the usage of <c>safe_fixed</c> is not
+ <seealso marker="erts:time_correction#Time_Warp_Safe_Code">time warp
+ safe</seealso>. Time warp safe code need to use
+ <c>safe_fixed_monotonic_time</c> instead.</p></item>
+
+ <tag><c>safe_fixed_monotonic_time</c></tag>
+ <item><p><c>FixationTime</c> will correspond to the result
+ returned by
+ <seealso marker="erts:erlang#monotonic_time/0">erlang:monotonic_time/0</seealso>
+ at the time of fixation. The usage of <c>safe_fixed_monotonic_time</c> is
+ <seealso marker="erts:time_correction#Time_Warp_Safe_Code">time warp
+ safe</seealso>.</p></item>
+ </taglist>
<p><c>Info</c> is a possibly empty lists of tuples
<c>{Pid,RefCount}</c>, one tuple for every process the
table is fixed by right now. <c>RefCount</c> is the value
@@ -603,7 +636,7 @@ ets:is_compiled_ms(Broken).</code>
<p>Returns the last key <c><anno>Key</anno></c> according to Erlang term
order in the table <c>Tab</c> of the <c>ordered_set</c> type.
If the table is of any other type, the function is synonymous
- to <c>first/2</c>. If the table is empty,
+ to <c>first/1</c>. If the table is empty,
<c>'$end_of_table'</c> is returned.</p>
<p>Use <c>prev/2</c> to find preceding keys in the table.</p>
</desc>
@@ -909,7 +942,7 @@ ets:select(Table,MatchSpec),</code>
</item>
<item>
<p><c>{keypos,<anno>Pos</anno>}</c>
- Specfies which element in the stored tuples should be
+ Specifies which element in the stored tuples should be
used as key. By default, it is the first element, i.e.
<c><anno>Pos</anno>=1</c>. However, this is not always appropriate. In
particular, we do not want the first element to be the
@@ -1127,9 +1160,11 @@ clean_all_with_value(Tab,X,Key) ->
table but never releases it, the memory used by the deleted
objects will never be freed. The performance of operations on
the table will also degrade significantly.</p>
- <p>Use <c>info/2</c> to retrieve information about which
- processes have fixed which tables. A system with a lot of
- processes fixing tables may need a monitor which sends alarms
+ <p>Use
+ <seealso marker="#info_2_safe_fixed_monotonic_time"><c>info(Tab,
+ safe_fixed_monotonic_time)</c></seealso> to retrieve information
+ about which processes have fixed which tables. A system with a lot
+ of processes fixing tables may need a monitor which sends alarms
when tables have been fixed for too long.</p>
<p>Note that for tables of the <c>ordered_set</c> type,
<c>safe_fixtable/2</c> is not necessary as calls to
@@ -1429,7 +1464,9 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code>
<p>Whenever the <c>extended_info</c> option is used, it
results in a file not readable by versions of ets prior to
that in stdlib-1.15.1</p>
-
+ <p>The <c>sync</c> option, if set to <c>true</c>, ensures that
+ the content of the file is actually written to the disk before
+ <c>tab2file</c> returns. Default is <c>{sync, false}</c>.</p>
</desc>
</func>
<func>
@@ -1587,6 +1624,21 @@ true</pre>
</desc>
</func>
<func>
+ <name name="take" arity="2"/>
+ <fsummary>Return and remove all objects with a given key from an ETS
+ table.</fsummary>
+ <desc>
+ <p>Returns a list of all objects with the key <c><anno>Key</anno></c> in
+ the table <c><anno>Tab</anno></c> and removes.</p>
+ <p>The given <c><anno>Key</anno></c> is used to identify the object by
+ either <em>comparing equal</em> the key of an object in an
+ <c>ordered_set</c> table, or <em>matching</em> in other types of
+ tables (see <seealso marker="#lookup/2">lookup/2</seealso> and
+ <seealso marker="#new/2">new/2</seealso> for details on the
+ difference).</p>
+ </desc>
+ </func>
+ <func>
<name name="to_dets" arity="2"/>
<fsummary>Fill a Dets table with objects from an ETS table.</fsummary>
<desc>
@@ -1597,15 +1649,19 @@ true</pre>
</func>
<func>
<name name="update_counter" arity="3" clause_i="1"/>
+ <name name="update_counter" arity="4" clause_i="1"/>
<name name="update_counter" arity="3" clause_i="2"/>
+ <name name="update_counter" arity="4" clause_i="2"/>
<name name="update_counter" arity="3" clause_i="3"/>
+ <name name="update_counter" arity="4" clause_i="3"/>
+ <fsummary>Update a counter object in an ETS table.</fsummary>
<type variable="Tab"/>
<type variable="Key"/>
<type variable="UpdateOp" name_i="1"/>
<type variable="Pos" name_i="1"/>
<type variable="Threshold" name_i="1"/>
<type variable="SetValue" name_i="1"/>
- <fsummary>Update a counter object in an ETS table.</fsummary>
+ <type variable="Default"/>
<desc>
<p>This function provides an efficient way to update one or more
counters, without the hassle of having to look up an object, update
@@ -1646,12 +1702,22 @@ true</pre>
<seealso marker="#lookup/2">lookup/2</seealso> and
<seealso marker="#new/2">new/2</seealso>
for details on the difference).</p>
+ <p>If a default object <c><anno>Default</anno></c> is given, it is used
+ as the object to be updated if the key is missing from the table. The
+ value in place of the key is ignored and replaced by the proper key
+ value. The return value is as if the default object had not been used,
+ that is a single updated element or a list of them.</p>
<p>The function will fail with reason <c>badarg</c> if:</p>
<list type="bulleted">
<item>the table is not of type <c>set</c> or
<c>ordered_set</c>,</item>
- <item>no object with the right key exists,</item>
+ <item>no object with the right key exists and no default object were
+ supplied,</item>
<item>the object has the wrong arity,</item>
+ <item>the default object arity is smaller than
+ <c><![CDATA[<keypos>]]></c></item>
+ <item>any field from the default object being updated is not an
+ integer</item>
<item>the element to update is not an integer,</item>
<item>the element to update is also the key, or,</item>
<item>any of <c><anno>Pos</anno></c>, <c><anno>Incr</anno></c>, <c><anno>Threshold</anno></c> or
@@ -1662,11 +1728,11 @@ true</pre>
<func>
<name name="update_element" arity="3" clause_i="1"/>
<name name="update_element" arity="3" clause_i="2"/>
+ <fsummary>Updates the <c>Pos</c>:th element of the object with a given key in an ETS table.</fsummary>
<type variable="Tab"/>
<type variable="Key"/>
<type variable="Value"/>
<type variable="Pos"/>
- <fsummary>Updates the <c>Pos</c>:th element of the object with a given key in an ETS table.</fsummary>
<desc>
<p>This function provides an efficient way to update one or more
elements within an object, without the hassle of having to look up,
diff --git a/lib/stdlib/doc/src/file_sorter.xml b/lib/stdlib/doc/src/file_sorter.xml
index 16572df3c5..f033eebec7 100644
--- a/lib/stdlib/doc/src/file_sorter.xml
+++ b/lib/stdlib/doc/src/file_sorter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -105,9 +106,9 @@
<c>file:get_cwd()</c> is used instead. The names of
temporary files are derived from the Erlang nodename
(<c>node()</c>), the process identifier of the current Erlang
- emulator (<c>os:getpid()</c>), and a timestamp
- (<c>erlang:now()</c>); a typical name would be
- <c>fs_mynode@myhost_1763_1043_337000_266005.17</c>, where
+ emulator (<c>os:getpid()</c>), and a unique integer
+ (<c>erlang:unique_integer([positive])</c>); a typical name would be
+ <c>fs_mynode@myhost_1763_4711.17</c>, where
<c>17</c> is a sequence number. Existing files will be
overwritten. Temporary files are deleted unless some
uncaught EXIT signal occurs.
@@ -222,82 +223,82 @@ output(L) ->
<datatypes>
<datatype>
- <name name="file_name"/><br/>
+ <name name="file_name"/>
</datatype>
<datatype>
- <name name="file_names"/><br/>
+ <name name="file_names"/>
</datatype>
<datatype>
- <name name="i_command"/><br/>
+ <name name="i_command"/>
</datatype>
<datatype>
- <name name="i_reply"/><br/>
+ <name name="i_reply"/>
</datatype>
<datatype>
- <name name="infun"/><br/>
+ <name name="infun"/>
</datatype>
<datatype>
- <name name="input"/><br/>
+ <name name="input"/>
</datatype>
<datatype>
- <name name="input_reply"/><br/>
+ <name name="input_reply"/>
</datatype>
<datatype>
- <name name="o_command"/><br/>
+ <name name="o_command"/>
</datatype>
<datatype>
- <name name="o_reply"/><br/>
+ <name name="o_reply"/>
</datatype>
<datatype>
- <name name="object"/><br/>
+ <name name="object"/>
</datatype>
<datatype>
- <name name="outfun"/><br/>
+ <name name="outfun"/>
</datatype>
<datatype>
- <name name="output"/><br/>
+ <name name="output"/>
</datatype>
<datatype>
- <name name="output_reply"/><br/>
+ <name name="output_reply"/>
</datatype>
<datatype>
- <name name="value"/><br/>
+ <name name="value"/>
</datatype>
<datatype>
- <name name="options"/><br/>
+ <name name="options"/>
</datatype>
<datatype>
- <name name="option"/><br/>
+ <name name="option"/>
</datatype>
<datatype>
- <name name="format"/><br/>
+ <name name="format"/>
</datatype>
<datatype>
- <name name="format_fun"/><br/>
+ <name name="format_fun"/>
</datatype>
<datatype>
- <name name="header_length"/><br/>
+ <name name="header_length"/>
</datatype>
<datatype>
- <name name="key_pos"/><br/>
+ <name name="key_pos"/>
</datatype>
<datatype>
- <name name="no_files"/><br/>
+ <name name="no_files"/>
</datatype>
<datatype>
- <name name="order"/><br/>
+ <name name="order"/>
</datatype>
<datatype>
- <name name="order_fun"/><br/>
+ <name name="order_fun"/>
</datatype>
<datatype>
- <name name="size"/><br/>
+ <name name="size"/>
</datatype>
<datatype>
- <name name="tmp_directory"/><br/>
+ <name name="tmp_directory"/>
</datatype>
<datatype>
- <name name="reason"/><br/>
+ <name name="reason"/>
</datatype>
</datatypes>
diff --git a/lib/stdlib/doc/src/filelib.xml b/lib/stdlib/doc/src/filelib.xml
index 6fa39f97f6..2cf9490f4b 100644
--- a/lib/stdlib/doc/src/filelib.xml
+++ b/lib/stdlib/doc/src/filelib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml
index 49b652f969..1d4ffc10f9 100644
--- a/lib/stdlib/doc/src/filename.xml
+++ b/lib/stdlib/doc/src/filename.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -213,7 +214,7 @@
<desc>
<p>Converts <c><anno>Path</anno></c> to a form accepted by the command shell
and native applications on the current platform. On Windows,
- forward slashes is converted to backward slashes. On all
+ forward slashes are converted to backward slashes. On all
platforms, the name is normalized as done by <c>join/1</c>.</p>
<pre>
19> <input>filename:nativename("/usr/local/bin/").</input> % Unix
diff --git a/lib/stdlib/doc/src/gb_sets.xml b/lib/stdlib/doc/src/gb_sets.xml
index ea96c14472..84609a0f7c 100644
--- a/lib/stdlib/doc/src/gb_sets.xml
+++ b/lib/stdlib/doc/src/gb_sets.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2014</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -120,9 +121,6 @@
</datatype>
<datatype>
<name name="set" n_vars="0"/>
- <desc>
- <p><c>set()</c> is equivalent to <c>set(term())</c>.</p>
- </desc>
</datatype>
<datatype>
<name name="iter" n_vars="1"/>
@@ -130,9 +128,6 @@
</datatype>
<datatype>
<name name="iter" n_vars="0"/>
- <desc>
- <p><c>iter()</c> is equivalent to <c>iter(term())</c>.</p>
- </desc>
</datatype>
</datatypes>
<funcs>
@@ -306,6 +301,17 @@
</desc>
</func>
<func>
+ <name name="iterator_from" arity="2"/>
+ <fsummary>Return an iterator for a set starting from a specified element</fsummary>
+ <desc>
+ <p>Returns an iterator that can be used for traversing the
+ entries of <c><anno>Set</anno></c>; see <c>next/1</c>.
+ The difference as compared to the iterator returned by
+ <c>iterator/1</c> is that the first element greater than
+ or equal to <c><anno>Element</anno></c> is returned.</p>
+ </desc>
+ </func>
+ <func>
<name name="largest" arity="1"/>
<fsummary>Return largest element</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/gb_trees.xml b/lib/stdlib/doc/src/gb_trees.xml
index b2f237e1d7..5d1f27c014 100644
--- a/lib/stdlib/doc/src/gb_trees.xml
+++ b/lib/stdlib/doc/src/gb_trees.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2014</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -64,9 +65,6 @@
</datatype>
<datatype>
<name name="tree" n_vars="0"/>
- <desc>
- <p><c>tree()</c> is equivalent to <c>tree(term(), term())</c>.</p>
- </desc>
</datatype>
<datatype>
<name name="iter" n_vars="2"/>
@@ -74,9 +72,6 @@
</datatype>
<datatype>
<name name="iter" n_vars="0"/>
- <desc>
- <p><c>iter()</c> is equivalent to <c>iter(term(), term())</c>.</p>
- </desc>
</datatype>
</datatypes>
<funcs>
@@ -183,6 +178,17 @@
</desc>
</func>
<func>
+ <name name="iterator_from" arity="2"/>
+ <fsummary>Return an iterator for a tree starting from specified key</fsummary>
+ <desc>
+ <p>Returns an iterator that can be used for traversing the
+ entries of <c><anno>Tree</anno></c>; see <c>next/1</c>.
+ The difference as compared to the iterator returned by
+ <c>iterator/1</c> is that the first key greater than
+ or equal to <c><anno>Key</anno></c> is returned.</p>
+ </desc>
+ </func>
+ <func>
<name name="keys" arity="1"/>
<fsummary>Return a list of the keys in a tree</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml
index b9dfff833e..c4bab45781 100644
--- a/lib/stdlib/doc/src/gen_event.xml
+++ b/lib/stdlib/doc/src/gen_event.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -44,6 +45,7 @@
<pre>
gen_event module Callback module
---------------- ---------------
+gen_event:start
gen_event:start_link -----> -
gen_event:add_handler
@@ -177,7 +179,7 @@ gen_event:stop -----> Module:terminate/2
<name>add_handler(EventMgrRef, Handler, Args) -> Result</name>
<fsummary>Add an event handler to a generic event manager.</fsummary>
<type>
- <v>EventMgr = Name | {Name,Node} | {global,GlobalName}
+ <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName}
| {via,Module,ViaName} | pid()</v>
<v>&nbsp;Name = Node = atom()</v>
<v>&nbsp;GlobalName = ViaName = term()</v>
@@ -223,7 +225,7 @@ gen_event:stop -----> Module:terminate/2
<name>add_sup_handler(EventMgrRef, Handler, Args) -> Result</name>
<fsummary>Add a supervised event handler to a generic event manager.</fsummary>
<type>
- <v>EventMgr = Name | {Name,Node} | {global,GlobalName}
+ <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName}
| {via,Module,ViaName} | pid()</v>
<v>&nbsp;Name = Node = atom()</v>
<v>&nbsp;GlobalName = ViaName = term()</v>
@@ -456,19 +458,37 @@ gen_event:stop -----> Module:terminate/2
</func>
<func>
<name>stop(EventMgrRef) -> ok</name>
+ <name>stop(EventMgrRef, Reason, Timeout) -> ok</name>
<fsummary>Terminate a generic event manager.</fsummary>
<type>
<v>EventMgrRef = Name | {Name,Node} | {global,GlobalName}
| {via,Module,ViaName} | pid()</v>
<v>Name = Node = atom()</v>
<v>GlobalName = ViaName = term()</v>
+ <v>Reason = term()</v>
+ <v>Timeout = int()>0 | infinity</v>
</type>
<desc>
- <p>Terminates the event manager <c>EventMgrRef</c>. Before
- terminating, the event manager will call
- <c>Module:terminate(stop,...)</c> for each installed event
- handler.</p>
- <p>See <c>add_handler/3</c> for a description of the argument.</p>
+ <p>Orders the event manager <c>EventMgrRef</c> to exit with
+ the given <c>Reason</c> and waits for it to
+ terminate. Before terminating, the gen_event will call
+ <seealso marker="#Module:terminate/2">Module:terminate(stop,...)</seealso>
+ for each installed event handler.</p>
+ <p>The function returns <c>ok</c> if the event manager terminates
+ with the expected reason. Any other reason than <c>normal</c>,
+ <c>shutdown</c>, or <c>{shutdown,Term}</c> will cause an
+ error report to be issued using
+ <seealso marker="kernel:error_logger#format/2">error_logger:format/2</seealso>.
+ The default <c>Reason</c> is <c>normal</c>.</p>
+ <p><c>Timeout</c> is an integer greater than zero which
+ specifies how many milliseconds to wait for the event manager to
+ terminate, or the atom <c>infinity</c> to wait
+ indefinitely. The default value is <c>infinity</c>. If the
+ event manager has not terminated within the specified time, a
+ <c>timeout</c> exception is raised.</p>
+ <p>If the process does not exist, a <c>noproc</c> exception
+ is raised.</p>
+ <p>See <c>add_handler/3</c> for a description of <c>EventMgrRef</c>.</p>
</desc>
</func>
</funcs>
@@ -696,7 +716,7 @@ gen_event:stop -----> Module:terminate/2
the purposes described below.</p>
</note>
<p>This function is called by a gen_event process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_event status. <c>Opt</c> is set
@@ -720,7 +740,7 @@ gen_event:stop -----> Module:terminate/2
customises the details of the current state of the event
handler. Any term is allowed for <c>Status</c>. The
gen_event module uses <c>Status</c> as follows:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>When <c>sys:get_status/1,2</c> is called, gen_event
ensures that its return value contains <c>Status</c> in
place of the event handler's actual state term.</item>
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index 848d57f3e6..4d594b8eb2 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -43,8 +44,11 @@
<pre>
gen_fsm module Callback module
-------------- ---------------
+gen_fsm:start
gen_fsm:start_link -----> Module:init/1
+gen_fsm:stop -----> Module:terminate/3
+
gen_fsm:send_event -----> Module:StateName/2
gen_fsm:send_all_state_event -----> Module:handle_event/3
@@ -187,6 +191,39 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
</desc>
</func>
<func>
+ <name>stop(FsmRef) -> ok</name>
+ <name>stop(FsmRef, Reason, Timeout) -> ok</name>
+ <fsummary>Synchronously stop a generic FSM.</fsummary>
+ <type>
+ <v>FsmRef = Name | {Name,Node} | {global,GlobalName}
+ | {via,Module,ViaName} | pid()</v>
+ <v>&nbsp;Node = atom()</v>
+ <v>&nbsp;GlobalName = ViaName = term()</v>
+ <v>Reason = term()</v>
+ <v>Timeout = int()>0 | infinity</v>
+ </type>
+ <desc>
+ <p>Orders a generic FSM to exit with the given <c>Reason</c>
+ and waits for it to terminate. The gen_fsm will call
+ <seealso marker="#Module:terminate/3">Module:terminate/3</seealso>
+ before exiting.</p>
+ <p>The function returns <c>ok</c> if the generic FSM terminates
+ with the expected reason. Any other reason than <c>normal</c>,
+ <c>shutdown</c>, or <c>{shutdown,Term}</c> will cause an
+ error report to be issued using
+ <seealso marker="kernel:error_logger#format/2">error_logger:format/2</seealso>.
+ The default <c>Reason</c> is <c>normal</c>.</p>
+ <p><c>Timeout</c> is an integer greater than zero which
+ specifies how many milliseconds to wait for the generic FSM
+ to terminate, or the atom <c>infinity</c> to wait
+ indefinitely. The default value is <c>infinity</c>. If the
+ generic FSM has not terminated within the specified time, a
+ <c>timeout</c> exception is raised.</p>
+ <p>If the process does not exist, a <c>noproc</c> exception
+ is raised.</p>
+ </desc>
+ </func>
+ <func>
<name>send_event(FsmRef, Event) -> ok</name>
<fsummary>Send an event asynchronously to a generic FSM.</fsummary>
<type>
@@ -302,11 +339,12 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
</desc>
</func>
<func>
- <name>reply(Caller, Reply) -> true</name>
+ <name>reply(Caller, Reply) -> Result</name>
<fsummary>Send a reply to a caller.</fsummary>
<type>
<v>Caller - see below</v>
<v>Reply = term()</v>
+ <v>Result = term()</v>
</type>
<desc>
<p>This function can be used by a gen_fsm to explicitly send a
@@ -321,6 +359,8 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
which will be given back to the client as the return value of
<c>sync_send_event/2,3</c> or
<c>sync_send_all_state_event/2,3</c>.</p>
+ <p>The return value <c>Result</c> is not further defined, and
+ should always be ignored.</p>
</desc>
</func>
<func>
@@ -528,7 +568,8 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
<c>Module:init/1</c> for a description of <c>Timeout</c> and <c>hibernate</c>.</p>
<p>If the function returns <c>{stop,Reason,NewStateData}</c>,
the gen_fsm will call
- <c>Module:terminate(Reason,NewStateData)</c> and terminate.</p>
+ <c>Module:terminate(Reason,StateName,NewStateData)</c> and
+ terminate.</p>
</desc>
</func>
<func>
@@ -614,7 +655,8 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
<c>{stop,Reason,NewStateData}</c>, any reply to <c>From</c>
must be given explicitly using <c>gen_fsm:reply/2</c>.
The gen_fsm will then call
- <c>Module:terminate(Reason,NewStateData)</c> and terminate.</p>
+ <c>Module:terminate(Reason,StateName,NewStateData)</c> and
+ terminate.</p>
</desc>
</func>
<func>
@@ -763,7 +805,7 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
module state data.</p>
</note>
<p>This function is called by a gen_fsm process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_fsm status. <c>Opt</c> is set to
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index 62c0394479..6d04771cd4 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -43,8 +44,11 @@
<pre>
gen_server module Callback module
----------------- ---------------
+gen_server:start
gen_server:start_link -----> Module:init/1
+gen_server:stop -----> Module:terminate/2
+
gen_server:call
gen_server:multi_call -----> Module:handle_call/3
@@ -184,6 +188,40 @@ gen_server:abcast -----> Module:handle_cast/2
</desc>
</func>
<func>
+ <name>stop(ServerRef) -> ok</name>
+ <name>stop(ServerRef, Reason, Timeout) -> ok</name>
+ <fsummary>Synchronously stop a generic server.</fsummary>
+ <type>
+ <v>ServerRef = Name | {Name,Node} | {global,GlobalName}
+ | {via,Module,ViaName} | pid()</v>
+ <v>&nbsp;Node = atom()</v>
+ <v>&nbsp;GlobalName = ViaName = term()</v>
+ <v>Reason = term()</v>
+ <v>Timeout = int()>0 | infinity</v>
+ </type>
+ <desc>
+ <p>Orders a generic server to exit with the
+ given <c>Reason</c> and waits for it to terminate. The
+ gen_server will call
+ <seealso marker="#Module:terminate/2">Module:terminate/2</seealso>
+ before exiting.</p>
+ <p>The function returns <c>ok</c> if the server terminates
+ with the expected reason. Any other reason than <c>normal</c>,
+ <c>shutdown</c>, or <c>{shutdown,Term}</c> will cause an
+ error report to be issued using
+ <seealso marker="kernel:error_logger#format/2">error_logger:format/2</seealso>.
+ The default <c>Reason</c> is <c>normal</c>.</p>
+ <p><c>Timeout</c> is an integer greater than zero which
+ specifies how many milliseconds to wait for the server to
+ terminate, or the atom <c>infinity</c> to wait
+ indefinitely. The default value is <c>infinity</c>. If the
+ server has not terminated within the specified time, a
+ <c>timeout</c> exception is raised.</p>
+ <p>If the process does not exist, a <c>noproc</c> exception
+ is raised.</p>
+ </desc>
+ </func>
+ <func>
<name>call(ServerRef, Request) -> Reply</name>
<name>call(ServerRef, Request, Timeout) -> Reply</name>
<fsummary>Make a synchronous call to a generic server.</fsummary>
@@ -284,7 +322,7 @@ gen_server:abcast -----> Module:handle_cast/2
which may be infinity.</p>
<p>This problem does not exist if all nodes are Erlang nodes.</p>
</warning>
- <p>To avoid that late answers (after the timeout) pollutes
+ <p>To prevent late answers (after the timeout) from polluting
the caller's message queue, a middleman process is used to
do the actual calls. Late answers will then be discarded
when they arrive to a terminated process.</p>
@@ -635,7 +673,7 @@ gen_server:abcast -----> Module:handle_cast/2
module state.</p>
</note>
<p>This function is called by a gen_server process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_server status. <c>Opt</c> is set
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index a28180b42a..4655c8662f 100644
--- a/lib/stdlib/doc/src/io.xml
+++ b/lib/stdlib/doc/src/io.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -131,8 +132,8 @@
<func>
<name name="get_chars" arity="2"/>
<name name="get_chars" arity="3"/>
- <type name="server_no_data"/>
<fsummary>Read a specified number of characters</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads <c><anno>Count</anno></c> characters from standard input
(<c><anno>IoDevice</anno></c>), prompting it with <c><anno>Prompt</anno></c>. It
@@ -161,8 +162,8 @@
<func>
<name name="get_line" arity="1"/>
<name name="get_line" arity="2"/>
- <type name="server_no_data"/>
<fsummary>Read a line</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a line from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. It returns:</p>
@@ -299,8 +300,8 @@
<func>
<name name="read" arity="1"/>
<name name="read" arity="2"/>
- <type name="server_no_data"/>
<fsummary>Read a term</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a term <c><anno>Term</anno></c> from the standard input
(<c><anno>IoDevice</anno></c>), prompting it with <c><anno>Prompt</anno></c>. It
@@ -329,8 +330,8 @@
<func>
<name name="read" arity="3"/>
<name name="read" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read a term</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a term <c><anno>Term</anno></c> from <c><anno>IoDevice</anno></c>, prompting it
with <c><anno>Prompt</anno></c>. Reading starts at location
@@ -505,7 +506,8 @@ ok
<p>Writes the data with standard syntax in the same way as
<c>~w</c>, but breaks terms whose printed representation
is longer than one line into many lines and indents each
- line sensibly. It also tries to detect lists of
+ line sensibly. Left justification is not supported.
+ It also tries to detect lists of
printable characters and to output these as strings. The
Unicode translation modifier is used for determining
what characters are printable. For example:</p>
@@ -696,8 +698,8 @@ ok
<func>
<name name="fread" arity="2"/>
<name name="fread" arity="3"/>
- <type name="server_no_data"/>
<fsummary>Read formatted input</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads characters from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Interprets the characters in
@@ -868,8 +870,8 @@ enter><input>:</input> <input>alan</input> <input>:</input> <input>joe</in
<name name="scan_erl_exprs" arity="2"/>
<name name="scan_erl_exprs" arity="3"/>
<name name="scan_erl_exprs" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read and tokenize Erlang expressions</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads data from the standard input (<c>IoDevice</c>),
prompting it with <c>Prompt</c>. Reading starts at location
@@ -917,8 +919,8 @@ enter><input>1.0er.</input>
<name name="scan_erl_form" arity="2"/>
<name name="scan_erl_form" arity="3"/>
<name name="scan_erl_form" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read and tokenize an Erlang form</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads data from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Starts reading
@@ -937,9 +939,9 @@ enter><input>1.0er.</input>
<name name="parse_erl_exprs" arity="2"/>
<name name="parse_erl_exprs" arity="3"/>
<name name="parse_erl_exprs" arity="4"/>
+ <fsummary>Read, tokenize and parse Erlang expressions</fsummary>
<type name="parse_ret"/>
<type name="server_no_data"/>
- <fsummary>Read, tokenize and parse Erlang expressions</fsummary>
<desc>
<p>Reads data from the standard input
(<c><anno>IoDevice</anno></c>), prompting it with
@@ -988,9 +990,9 @@ enter><input>abc("hey".</input>
<name name="parse_erl_form" arity="2"/>
<name name="parse_erl_form" arity="3"/>
<name name="parse_erl_form" arity="4"/>
+ <fsummary>Read, tokenize and parse an Erlang form</fsummary>
<type name="parse_form_ret"/>
<type name="server_no_data"/>
- <fsummary>Read, tokenize and parse an Erlang form</fsummary>
<desc>
<p>Reads data from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Starts reading at
diff --git a/lib/stdlib/doc/src/io_lib.xml b/lib/stdlib/doc/src/io_lib.xml
index 3312b08064..cd58090dcd 100644
--- a/lib/stdlib/doc/src/io_lib.xml
+++ b/lib/stdlib/doc/src/io_lib.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -59,6 +60,35 @@
<datatype>
<name name="latin1_string"/>
</datatype>
+ <datatype>
+ <name name="format_spec"/>
+ <desc><p>Description:</p>
+ <list type="bulleted">
+ <item><p><c>control_char</c> is the type of control
+ sequence: <c>$P</c>, <c>$w</c>, and so on;</p>
+ </item>
+ <item><p><c>args</c> is a list of the arguments used by the
+ control sequence, or an empty list if the control sequence
+ does not take any arguments;</p>
+ </item>
+ <item><p><c>width</c> is the field width;</p>
+ </item>
+ <item><p><c>adjust</c> is the adjustment;</p>
+ </item>
+ <item><p><c>precision</c> is the precision of the printed
+ argument;</p>
+ </item>
+ <item><p><c>pad_char</c> is the padding character;</p>
+ </item>
+ <item><p><c>encoding</c> is set to <c>true</c> if the translation
+ modifier <c>t</c> is present;</p>
+ </item>
+ <item><p><c>strings</c> is set to <c>false</c> if the modifier
+ <c>l</c> is present.</p>
+ </item>
+ </list>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
@@ -260,6 +290,45 @@
</desc>
</func>
<func>
+ <name name="scan_format" arity="2"/>
+ <fsummary>Parse all control sequences in the format string</fsummary>
+ <desc>
+ <p>Returns a list corresponding to the given format string,
+ where control sequences have been replaced with
+ corresponding tuples. This list can be passed to <seealso
+ marker="#build_text/1">io_lib:build_text/1</seealso> to have
+ the same effect as <c>io_lib:format(Format, Args)</c>, or to
+ <seealso
+ marker="#unscan_format/1">io_lib:unscan_format/1</seealso>
+ in order to get the corresponding pair of <c>Format</c> and
+ <c>Args</c> (with every <c>*</c> and corresponding argument
+ expanded to numeric values).</p>
+ <p>A typical use of this function is to replace unbounded-size
+ control sequences like <c>~w</c> and <c>~p</c> with the
+ depth-limited variants <c>~W</c> and <c>~P</c> before
+ formatting to text, e.g. in a logger.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="unscan_format" arity="1"/>
+ <fsummary>Revert a pre-parsed format list to a plain character list
+ and a list of arguments</fsummary>
+ <desc>
+ <p>See <seealso
+ marker="#scan_format/2">io_lib:scan_format/2</seealso> for
+ details.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="build_text" arity="1"/>
+ <fsummary>Build the output text for a pre-parsed format list</fsummary>
+ <desc>
+ <p>See <seealso
+ marker="#scan_format/2">io_lib:scan_format/2</seealso> for
+ details.</p>
+ </desc>
+ </func>
+ <func>
<name name="indentation" arity="2"/>
<fsummary>Indentation after printing string</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml
index 21da404c35..170dab17ca 100644
--- a/lib/stdlib/doc/src/io_protocol.xml
+++ b/lib/stdlib/doc/src/io_protocol.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/lib.xml b/lib/stdlib/doc/src/lib.xml
index 30f164826c..f4dddf646d 100644
--- a/lib/stdlib/doc/src/lib.xml
+++ b/lib/stdlib/doc/src/lib.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index ee3c51c62c..89ba5238b5 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -176,7 +177,7 @@ filtermap(Fun, List1) ->
false -> Acc;
true -> [Elem|Acc];
{true,Value} -> [Value|Acc]
- end,
+ end
end, [], List1).</code>
<p>Example:</p>
<pre>
@@ -282,8 +283,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keyfind" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Search for an element in a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Searches the list of tuples <c><anno>TupleList</anno></c> for a
tuple whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>.
@@ -310,8 +311,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keymember" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Test for membership of a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Returns <c>true</c> if there is a tuple in <c><anno>TupleList</anno></c>
whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>, otherwise
@@ -345,8 +346,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keysearch" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Search for an element in a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Searches the list of tuples <c><anno>TupleList</anno></c> for a
tuple whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>.
diff --git a/lib/stdlib/doc/src/log_mf_h.xml b/lib/stdlib/doc/src/log_mf_h.xml
index 3ef659f579..eccda516ba 100644
--- a/lib/stdlib/doc/src/log_mf_h.xml
+++ b/lib/stdlib/doc/src/log_mf_h.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/maps.xml b/lib/stdlib/doc/src/maps.xml
index f766c843be..48c1abc2f8 100644
--- a/lib/stdlib/doc/src/maps.xml
+++ b/lib/stdlib/doc/src/maps.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>maps</title>
<prepared>Björn-Egil Dahlberg</prepared>
@@ -33,6 +34,28 @@
<funcs>
<func>
+ <name name="filter" arity="2"/>
+ <fsummary>Choose pairs which satisfy a predicate</fsummary>
+ <desc>
+ <p>
+ Returns a map <c><anno>Map2</anno></c> for which predicate
+ <c><anno>Pred</anno></c> holds true in <c><anno>Map1</anno></c>.
+ </p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if
+ <c><anno>Map1</anno></c> is not a map or with <c>badarg</c> if
+ <c><anno>Pred</anno></c> is not a function of arity 2.
+ </p>
+ <p>Example:</p>
+ <code type="none">
+> M = #{a => 2, b => 3, c=> 4, "a" => 1, "b" => 2, "c" => 4},
+ Pred = fun(K,V) -> is_atom(K) andalso (V rem 2) =:= 0 end,
+ maps:filter(Pred,M).
+#{a => 2,c => 4} </code>
+ </desc>
+ </func>
+
+ <func>
<name name="find" arity="2"/>
<fsummary></fsummary>
<desc>
@@ -40,6 +63,9 @@
Returns a tuple <c>{ok, Value}</c> where <c><anno>Value</anno></c> is the value associated with <c><anno>Key</anno></c>,
or <c>error</c> if no value is associated with <c><anno>Key</anno></c> in <c><anno>Map</anno></c>.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map.
+ </p>
<p>Example:</p>
<code type="none">
> Map = #{"hi" => 42},
@@ -95,8 +121,10 @@
<p>
Returns the value <c><anno>Value</anno></c> associated with <c><anno>Key</anno></c> if
<c><anno>Map</anno></c> contains <c><anno>Key</anno></c>.
- If no value is associated with <c><anno>Key</anno></c> then the call will
- fail with an exception.
+ </p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map,
+ or with a <c>{badkey,Key}</c> exception if no value is associated with <c><anno>Key</anno></c>.
</p>
<p>Example:</p>
<code type="none">
@@ -116,6 +144,10 @@
<c><anno>Map</anno></c> contains <c><anno>Key</anno></c>.
If no value is associated with <c><anno>Key</anno></c> then returns <c><anno>Default</anno></c>.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map.
+
+ </p>
<p>Example:</p>
<code type="none">
> Map = #{ key1 => val1, key2 => val2 }.
@@ -134,7 +166,9 @@ val1
<p>
Returns <c>true</c> if map <c><anno>Map</anno></c> contains <c><anno>Key</anno></c> and returns
<c>false</c> if it does not contain the <c><anno>Key</anno></c>.
- The function will fail with an exception if <c><anno>Map</anno></c> is not a Map.
+ </p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map.
</p>
<p>Example:</p>
<code type="none">
@@ -154,6 +188,9 @@ false</code>
<p>
Returns a complete list of keys, in arbitrary order, which resides within <c><anno>Map</anno></c>.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map.
+ </p>
<p>Example:</p>
<code type="none">
> Map = #{42 => value_three,1337 => "value two","a" => 1},
@@ -189,6 +226,10 @@ false</code>
Merges two maps into a single map <c><anno>Map3</anno></c>. If two keys exists in both maps the
value in <c><anno>Map1</anno></c> will be superseded by the value in <c><anno>Map2</anno></c>.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map1</anno></c> or
+ <c><anno>Map2</anno></c> is not a map.
+ </p>
<p>Example:</p>
<code type="none">
> Map1 = #{a => "value_one", b => "value_two"},
@@ -222,6 +263,10 @@ false</code>
replaced by value <c><anno>Value</anno></c>. The function returns a new map <c><anno>Map2</anno></c> containing the new association and
the old associations in <c><anno>Map1</anno></c>.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map1</anno></c> is not a map.
+ </p>
+
<p>Example:</p>
<code type="none">
> Map = #{"a" => 1}.
@@ -241,6 +286,9 @@ false</code>
The function removes the <c><anno>Key</anno></c>, if it exists, and its associated value from
<c><anno>Map1</anno></c> and returns a new map <c><anno>Map2</anno></c> without key <c><anno>Key</anno></c>.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map1</anno></c> is not a map.
+ </p>
<p>Example:</p>
<code type="none">
> Map = #{"a" => 1}.
@@ -276,6 +324,9 @@ false</code>
The fuction returns a list of pairs representing the key-value associations of <c><anno>Map</anno></c>,
where the pairs, <c>[{K1,V1}, ..., {Kn,Vn}]</c>, are returned in arbitrary order.
</p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map.
+ </p>
<p>Example:</p>
<code type="none">
> Map = #{42 => value_three,1337 => "value two","a" => 1},
@@ -291,8 +342,11 @@ false</code>
<p>
If <c><anno>Key</anno></c> exists in <c><anno>Map1</anno></c> the old associated value is
replaced by value <c><anno>Value</anno></c>. The function returns a new map <c><anno>Map2</anno></c> containing
- the new associated value. If <c><anno>Key</anno></c> does not exist in <c><anno>Map1</anno></c> an exception is
- generated.
+ the new associated value.
+ </p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map1</anno></c> is not a map,
+ or with a <c>{badkey,Key}</c> exception if no value is associated with <c><anno>Key</anno></c>.
</p>
<p>Example:</p>
<code type="none">
@@ -308,7 +362,10 @@ false</code>
<fsummary></fsummary>
<desc>
<p>
- Returns a complete list of values, in arbitrary order, contained in map <c>M</c>.
+ Returns a complete list of values, in arbitrary order, contained in map <c>Map</c>.
+ </p>
+ <p>
+ The call will fail with a <c>{badmap,Map}</c> exception if <c><anno>Map</anno></c> is not a map.
</p>
<p>Example:</p>
<code type="none">
diff --git a/lib/stdlib/doc/src/math.xml b/lib/stdlib/doc/src/math.xml
index 43cd20e726..aee6c3f238 100644
--- a/lib/stdlib/doc/src/math.xml
+++ b/lib/stdlib/doc/src/math.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -67,12 +68,13 @@
<name name="atanh" arity="1"/>
<name name="exp" arity="1"/>
<name name="log" arity="1"/>
+ <name name="log2" arity="1"/>
<name name="log10" arity="1"/>
<name name="pow" arity="2"/>
<name name="sqrt" arity="1"/>
+ <fsummary>Diverse math functions</fsummary>
<type variable="X" name_i="7"/>
<type variable="Y" name_i="7"/>
- <fsummary>Diverse math functions</fsummary>
<desc>
<p>A collection of math functions which return floats. Arguments
are numbers. </p>
diff --git a/lib/stdlib/doc/src/ms_transform.xml b/lib/stdlib/doc/src/ms_transform.xml
index e89dd41f26..22cb39c576 100644
--- a/lib/stdlib/doc/src/ms_transform.xml
+++ b/lib/stdlib/doc/src/ms_transform.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index 301a5ee2e8..5d4f9d912f 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,542 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 2.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix evaluation in matching of bound map key variables in
+ the interpreter.</p>
+ <p>
+ Prior to this patch, the following code would not
+ evaluate: <c>X = key,(fun(#{X := value}) -&gt; true
+ end)(#{X => value})</c></p>
+ <p>
+ Own Id: OTP-13218</p>
+ </item>
+ <item>
+ <p> Fix <c>erl_eval</c> not using non-local function
+ handler. </p>
+ <p>
+ Own Id: OTP-13228 Aux Id: ERL-32 </p>
+ </item>
+ <item>
+ <p> The Erlang Code Linter no longer crashes if there is
+ a <c>-deprecated()</c> attribute but no <c>-module()</c>
+ declaration. </p>
+ <p>
+ Own Id: OTP-13230 Aux Id: ERL-62 </p>
+ </item>
+ <item>
+ <p>
+ The timestamp in the result returned by <c>dets:info(Tab,
+ safe_fixed)</c> was unintentionally broken as a result of
+ the time API rewrites in OTP 18.0. This has now been
+ fixed.</p>
+ <p>
+ Own Id: OTP-13239 Aux Id: OTP-11997 </p>
+ </item>
+ <item>
+ <p>A rare race condition in <c>beam_lib</c> when using
+ encrypted abstract format has been eliminated.</p>
+ <p>
+ Own Id: OTP-13278</p>
+ </item>
+ <item>
+ <p>
+ Improved maps:with/2 and maps:without/2 algorithms</p>
+ <p>
+ The new implementation speeds up the execution
+ significantly for all sizes of input.</p>
+ <p>
+ Own Id: OTP-13376</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Time warp safety improvements.</p>
+ <p>
+ Introduced the options <c>monotonic_timestamp</c>, and
+ <c>strict_monotonic_timestamp</c> to the trace,
+ sequential trace, and system profile functionality. This
+ since the already existing <c>timestamp</c> option is not
+ time warp safe.</p>
+ <p>
+ Introduced the option <c>safe_fixed_monotonic_time</c> to
+ <c>ets:info/2</c> and <c>dets:info/2</c>. This since the
+ already existing <c>safe_fixed</c> option is not time
+ warp safe.</p>
+ <p>
+ Own Id: OTP-13222 Aux Id: OTP-11997 </p>
+ </item>
+ <item>
+ <p>
+ In the shell Ctrl+W (delete word) will no longer consider
+ "." as being part of a word.</p>
+ <p>
+ Own Id: OTP-13281</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 2.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The Erlang Pretty Printer uses <c>::</c> for function
+ type constraints.</p> <p>A bug concerning pretty printing
+ of annotated type union elements in map pair types has
+ been fixed.</p> <p>Some minor issues regarding the
+ documentation of types and specs have been corrected.</p>
+ <p>
+ Own Id: OTP-13084</p>
+ </item>
+ <item>
+ <p> The shell command <c>rp</c> prints strings as lists
+ of integers if pretty printing of lists is set to
+ <c>false</c>. </p>
+ <p>
+ Own Id: OTP-13145</p>
+ </item>
+ <item>
+ <p>
+ The shell would crash if a bit syntax expression with
+ conflicting types were given (e.g. if a field type was
+ given as '<c>integer-binary</c>'). (Thanks to Aleksei
+ Magusev for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13157</p>
+ </item>
+ <item>
+ <p>The <c>rand:export_seed/0</c> would never return
+ '<c>undefined</c>' even if no seed has previously been
+ created. Fixed to return '<c>undefined</c>' if there is
+ no seed in the process dictionary.</p>
+ <p>
+ Own Id: OTP-13162</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add support for the Delete, Home and End keys in the
+ Erlang shell.</p>
+ <p>
+ Own Id: OTP-13032</p>
+ </item>
+ <item>
+ <p><c>beam_lib:all_chunks/1</c> and
+ <c>beam_lib:build_module/1</c> have been documented.</p>
+ <p>
+ Own Id: OTP-13063</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 2.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> In OTP 18.0, <c>qlc</c> does not handle syntax errors
+ well. This bug has been fixed. </p>
+ <p>
+ Own Id: OTP-12946</p>
+ </item>
+ <item>
+ <p>
+ Optimize zip:unzip/2 when uncompressing to memory.</p>
+ <p>
+ Own Id: OTP-12950</p>
+ </item>
+ <item>
+ <p>
+ The <c>stdlib</c> reference manual is updated to show
+ correct information about the return value of
+ <c>gen_fsm:reply/2</c>.</p>
+ <p>
+ Own Id: OTP-12973</p>
+ </item>
+ <item>
+ <p>re:split2,3 and re:replace/3,4 now correctly handles
+ pre-compiled patterns that have been compiled using the
+ '<c>unicode</c>' option.</p>
+ <p>
+ Own Id: OTP-12977</p>
+ </item>
+ <item>
+ <p>
+ Export <c>shell:catch_exception/1</c> as documented.</p>
+ <p>
+ Own Id: OTP-12990</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>A mechanism for limiting the amount of text that the
+ built-in error logger events will produce has been
+ introduced. It is useful for limiting both the size of
+ log files and the CPU time used to produce them.</p>
+ <p>This mechanism is experimental in the sense that it
+ may be changed if it turns out that it does not solve the
+ problem it is supposed to solve. In that case, there may
+ be backward incompatible improvements to this
+ mechanism.</p>
+ <p>See the documentation for the config parameter
+ <c>error_logger_format_depth</c> in the Kernel
+ application for information about how to turn on this
+ feature.</p>
+ <p>
+ Own Id: OTP-12864</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 2.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix handling of single dot in filename:join/2</p>
+ <p>
+ The reference manual says that filename:join(A,B) is
+ equivalent to filename:join([A,B]). In some rare cases
+ this turns out not to be true. For example:</p>
+ <p>
+ <c>filename:join("/a/.","b") -&gt; "/a/./b"</c> vs
+ <c>filename:join(["/a/.","b"]) -&gt; "/a/b"</c>.</p>
+ <p>
+ This has been corrected. A single dot is now only kept if
+ it occurs at the very beginning or the very end of the
+ resulting path.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12158</p>
+ </item>
+ <item>
+ <p>
+ The undocumented option <c>generic_debug</c> for
+ <c>gen_server</c> has been removed.</p>
+ <p>
+ Own Id: OTP-12183</p>
+ </item>
+ <item>
+ <p>
+ erl_lint:icrt_export/4 has been rewritten to make the
+ code really follow the scoping rules of Erlang, and not
+ just in most situations by accident.</p>
+ <p>
+ Own Id: OTP-12186</p>
+ </item>
+ <item>
+ <p>
+ Add 'trim_all' option to binary:split/3</p>
+ <p>
+ This option can be set to remove _ALL_ empty parts of the
+ result of a call to binary:split/3.</p>
+ <p>
+ Own Id: OTP-12301</p>
+ </item>
+ <item>
+ <p> Correct orddict(3) regarding evaluation order of
+ <c>fold()</c> and <c>map()</c>. </p>
+ <p>
+ Own Id: OTP-12651 Aux Id: seq12832 </p>
+ </item>
+ <item>
+ <p>
+ Correct <c>maps</c> module error exceptions </p>
+ <p>
+ Bad input to maps module function will now yield the
+ following exceptions:</p>
+ <list> <item>{badmap, NotMap}, or </item> <item>badarg.</item>
+ </list>
+ <p>
+ Own Id: OTP-12657</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to paste text in JCL mode (using
+ Ctrl-Y) that has been copied in the previous shell
+ session. Also a bug that caused the JCL mode to crash
+ when pasting text has been fixed.</p>
+ <p>
+ Own Id: OTP-12673</p>
+ </item>
+ <item>
+ <p>
+ Add <c>uptime()</c> shell command.</p>
+ <p>
+ Own Id: OTP-12752</p>
+ </item>
+ <item>
+ <p>
+ Cache nowarn_bif_clash functions in erl_lint.</p>
+ <p>
+ This patch stores nowarn_bif_clash in the lint record. By
+ using erlc +'{eprof,lint_module}' when compiling the
+ erlang parser, we noticed the time spent on
+ nowarn_function/2 reduced from 30% to 0.01%.</p>
+ <p>
+ Own Id: OTP-12754</p>
+ </item>
+ <item>
+ <p>
+ Optimize the Erlang Code Linter by using the cached
+ filename information.</p>
+ <p>
+ Own Id: OTP-12772</p>
+ </item>
+ <item>
+ <p>
+ If a child of a simple_one_for_one returns ignore from
+ its start function no longer store the child for any
+ restart type. It is not possible to restart or delete the
+ child because the supervisor is a simple_one_for_one.</p>
+ <p>
+ Own Id: OTP-12793</p>
+ </item>
+ <item>
+ <p>
+ Make <c>ets:file2tab</c> preserve enabled
+ <c>read_concurrency</c> and <c>write_concurrency</c>
+ options for tables.</p>
+ <p>
+ Own Id: OTP-12814</p>
+ </item>
+ <item>
+ <p>
+ There are many cases where user code needs to be able to
+ distinguish between a socket that was closed normally and
+ one that was aborted. Setting the option
+ {show_econnreset, true} enables the user to receive
+ ECONNRESET errors on both active and passive sockets.</p>
+ <p>
+ Own Id: OTP-12841</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Allow maps for supervisor flags and child specs</p>
+ <p>
+ Earlier, supervisor flags and child specs were given as
+ tuples. While this is kept for backwards compatibility,
+ it is now also allowed to give these parameters as maps,
+ see <seealso
+ marker="stdlib:supervisor#sup_flags">sup_flags</seealso>
+ and <seealso
+ marker="stdlib:supervisor#child_spec">child_spec</seealso>.</p>
+ <p>
+ Own Id: OTP-11043</p>
+ </item>
+ <item>
+ <p>
+ A new system message, <c>terminate</c>, is added. This
+ can be sent with <c>sys:terminate/2,3</c>. If the
+ receiving process handles system messages properly it
+ will terminate shortly after receiving this message.</p>
+ <p>
+ The new function <c>proc_lib:stop/1,3</c> utilizes this
+ new system message and monitors the receiving process in
+ order to facilitate a synchronous stop mechanism for
+ 'special processes'.</p>
+ <p>
+ <c>proc_lib:stop/1,3</c> is used by the following
+ functions:</p>
+ <list> <item><c>gen_server:stop/1,3</c> (new)</item>
+ <item><c>gen_fsm:stop/1,3</c> (new)</item>
+ <item><c>gen_event:stop/1,3</c> (modified to be
+ synchronous)</item> <item><c>wx_object:stop/1,3</c>
+ (new)</item> </list>
+ <p>
+ Own Id: OTP-11173 Aux Id: seq12353 </p>
+ </item>
+ <item>
+ <p>
+ Remove the <c>pg</c> module, which has been deprecated
+ through OTP-17, is now removed from the STDLIB
+ application. This module has been marked experimental for
+ more than 15 years, and has largely been superseded by
+ the <c>pg2</c> module from the Kernel application.</p>
+ <p>
+ Own Id: OTP-11907</p>
+ </item>
+ <item>
+ <p>
+ New BIF: <c>erlang:get_keys/0</c>, lists all keys
+ associated with the process dictionary. Note:
+ <c>erlang:get_keys/0</c> is auto-imported.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12151 Aux Id: seq12521 </p>
+ </item>
+ <item>
+ <p> Add three new functions to <c>io_lib</c>--
+ <c>scan_format/2</c>, <c>unscan_format/1</c>, and
+ <c>build_text/1</c>-- which expose the parsed form of the
+ format control sequences to make it possible to easily
+ modify or filter the input to <c>io_lib:format/2</c>.
+ This can e.g. be used in order to replace unbounded-size
+ control sequences like <c>~w</c> or <c>~p</c> with
+ corresponding depth-limited <c>~W</c> and <c>~P</c>
+ before doing the actual formatting. </p>
+ <p>
+ Own Id: OTP-12167</p>
+ </item>
+ <item>
+ <p> Introduce the <c>erl_anno</c> module, an abstraction
+ of the second element of tokens and tuples in the
+ abstract format. </p>
+ <p>
+ Own Id: OTP-12195</p>
+ </item>
+ <item>
+ <p>
+ Support variables as Map keys in expressions and patterns</p>
+ <p>Erlang will accept any expression as keys in Map
+ expressions and it will accept literals or bound
+ variables as keys in Map patterns.</p>
+ <p>
+ Own Id: OTP-12218</p>
+ </item>
+ <item>
+ <p> The last traces of Mnemosyne Rules have been removed.
+ </p>
+ <p>
+ Own Id: OTP-12257</p>
+ </item>
+ <item>
+ <p>
+ Properly support maps in match_specs</p>
+ <p>
+ Own Id: OTP-12270</p>
+ </item>
+ <item>
+ <p>
+ New function <c>ets:take/2</c>. Works the same as
+ <c>ets:delete/2</c> but also returns the deleted
+ object(s).</p>
+ <p>
+ Own Id: OTP-12309</p>
+ </item>
+ <item>
+ <p><c>string:tokens/2</c> is somewhat faster, especially
+ if the list of separators only contains one separator
+ character.</p>
+ <p>
+ Own Id: OTP-12422 Aux Id: seq12774 </p>
+ </item>
+ <item>
+ <p>The documentation of the Abstract Format (in the ERTS
+ User's Guide) has been updated with types and
+ specification. (Thanks to Anthony Ramine.) </p> <p> The
+ explicit representation of parentheses used in types of
+ the abstract format has been removed. Instead the new
+ functions <c>erl_parse:type_inop_prec()</c> and
+ <c>erl_parse:type_preop_prec()</c> can be used for
+ inserting parentheses where needed. </p>
+ <p>
+ Own Id: OTP-12492</p>
+ </item>
+ <item>
+ <p>
+ Prevent zip:zip_open/[12] from leaking file descriptors
+ if parent process dies.</p>
+ <p>
+ Own Id: OTP-12566</p>
+ </item>
+ <item>
+ <p>
+ Add a new random number generator, see <c>rand</c>
+ module. It have better characteristics and an improved
+ interface.</p>
+ <p>
+ Own Id: OTP-12586 Aux Id: OTP-12501, OTP-12502 </p>
+ </item>
+ <item>
+ <p><c>filename:split/1</c> when given an empty binary
+ will now return an empty list, to make it consistent with
+ return value when given an empty list.</p>
+ <p>
+ Own Id: OTP-12716</p>
+ </item>
+ <item>
+ <p>
+ Add <c>sync</c> option to <c>ets:tab2file/3</c>.</p>
+ <p>
+ Own Id: OTP-12737 Aux Id: seq12805 </p>
+ </item>
+ <item>
+ <p> Add functions <c>gb_sets:iterator_from()</c> and
+ <c>gb_trees:iterator_from()</c>. (Thanks to Kirill
+ Kinduk.) </p>
+ <p>
+ Own Id: OTP-12742</p>
+ </item>
+ <item>
+ <p>
+ Add <c>maps:filter/2</c> to maps module.</p>
+ <p>
+ Own Id: OTP-12745</p>
+ </item>
+ <item>
+ <p>
+ Change some internal data structures to Maps in order to
+ speed up compilation time. Measured speed up is around
+ 10%-15%.</p>
+ <p>
+ Own Id: OTP-12774</p>
+ </item>
+ <item>
+ <p> Update <c>orddict</c> to use parameterized types and
+ specs. (Thanks to UENISHI Kota.) </p>
+ <p>
+ Own Id: OTP-12785</p>
+ </item>
+ <item>
+ <p>The assert macros in <c>eunit</c> has been moved out
+ to <c>stdlib/include/assert.hrl</c>. This files get
+ included by <c>eunit.hrl</c>. Thus, nothing changes for
+ eunit users, but the asserts can now also be included
+ separately.</p>
+ <p>
+ Own Id: OTP-12808</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 2.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -476,8 +1013,7 @@
also implemented by the generic behaviours
<c>gen_server</c>, <c>gen_event</c> and <c>gen_fsm</c>.</p>
<p>
- The potential incompatibility refers to</p>
- <p>
+ The potential incompatibility refers to:</p>
<list> <item>The previous behaviour of intercepting the
system message and passing a tuple of size 2 as the last
argument to <c>sys:handle_system_msg/6</c> is no longer
@@ -485,7 +1021,7 @@
<c>StateFun</c> in <c>sys:replace_state/2,3</c> fails is
changed from being totally silent to possibly (if the
callback module does not catch) throw an exception in the
- client process.</item> </list></p>
+ client process.</item> </list>
<p>
(Thanks to James Fish and Steve Vinoski)</p>
<p>
@@ -647,22 +1183,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -1413,13 +1955,15 @@
supervisor or for the problematic child.</p>
<p>
This introduces some incompatibilities in stdlib due to
- new return values from supervisor: <list>
+ new return values from supervisor:</p>
+ <list>
<item>restart_child/2 can now return
{error,restarting}</item> <item>delete_child/2 can now
return {error,restarting}</item> <item>which_children/1
returns a list of {Id,Child,Type,Mods}, where Child, in
addition to the old pid() or 'undefined', now also can be
- 'restarting'.</item> </list></p>
+ 'restarting'.</item>
+ </list>
<p>
*** POTENTIAL INCOMPATIBILITY ***</p>
<p>
@@ -1435,10 +1979,10 @@
Own Id: OTP-9782 Aux Id: seq11964 </p>
</item>
<item>
- <p> Use universal time as base in error logger
+ <p> Use universal time as base in error logger</p>
<p>
Previous conversion used the deprecated
- calendar:local_time_to_universal_time/1 </p></p>
+ calendar:local_time_to_universal_time/1 </p>
<p>
Own Id: OTP-9854</p>
</item>
@@ -2195,10 +2739,10 @@
Own Id: OTP-8989 Aux Id: seq11741 </p>
</item>
<item>
- <p>Fix exception generation in the io module
+ <p>Fix exception generation in the io module</p>
<p>
Some functions did not generate correct badarg exception
- on a badarg exception.</p></p>
+ on a badarg exception.</p>
<p>
Own Id: OTP-9045</p>
</item>
diff --git a/lib/stdlib/doc/src/notes_history.xml b/lib/stdlib/doc/src/notes_history.xml
index 328855f6dd..25641fdf3a 100644
--- a/lib/stdlib/doc/src/notes_history.xml
+++ b/lib/stdlib/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/orddict.xml b/lib/stdlib/doc/src/orddict.xml
index 6d1702bc59..950f688735 100644
--- a/lib/stdlib/doc/src/orddict.xml
+++ b/lib/stdlib/doc/src/orddict.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -48,8 +49,11 @@
<datatypes>
<datatype>
- <name name="orddict"/>
- <desc><p>As returned by new/0.</p></desc>
+ <name name="orddict" n_vars="2"/>
+ <desc><p>Dictionary as returned by <c>new/0</c>.</p></desc>
+ </datatype>
+ <datatype>
+ <name name="orddict" n_vars="0"/>
</datatype>
</datatypes>
@@ -125,8 +129,7 @@
<c><anno>Orddict</anno></c> together with an extra argument <c>Acc</c>
(short for accumulator). <c><anno>Fun</anno></c> must return a new
accumulator which is passed to the next call. <c><anno>Acc0</anno></c> is
- returned if the list is empty. The evaluation order is
- undefined.</p>
+ returned if the list is empty.</p>
</desc>
</func>
<func>
@@ -150,8 +153,7 @@
<fsummary>Map a function over a dictionary</fsummary>
<desc>
<p><c>map</c> calls <c><anno>Fun</anno></c> on successive keys and values
- of <c><anno>Orddict1</anno></c> to return a new value for each key.
- The evaluation order is undefined.</p>
+ of <c><anno>Orddict1</anno></c> to return a new value for each key.</p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/doc/src/ordsets.xml b/lib/stdlib/doc/src/ordsets.xml
index 277c1c32ab..639e041d79 100644
--- a/lib/stdlib/doc/src/ordsets.xml
+++ b/lib/stdlib/doc/src/ordsets.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/part.xml b/lib/stdlib/doc/src/part.xml
index 5589d11e3e..f7074d3404 100644
--- a/lib/stdlib/doc/src/part.xml
+++ b/lib/stdlib/doc/src/part.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/part_notes.xml b/lib/stdlib/doc/src/part_notes.xml
index cdd35ac370..6ceead1af5 100644
--- a/lib/stdlib/doc/src/part_notes.xml
+++ b/lib/stdlib/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/part_notes_history.xml b/lib/stdlib/doc/src/part_notes_history.xml
index 15e0a0f1d3..36792b12e1 100644
--- a/lib/stdlib/doc/src/part_notes_history.xml
+++ b/lib/stdlib/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/pg.xml b/lib/stdlib/doc/src/pg.xml
deleted file mode 100644
index a3b69884b6..0000000000
--- a/lib/stdlib/doc/src/pg.xml
+++ /dev/null
@@ -1,114 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <header>
- <copyright>
- <year>1996</year>
- <year>2014</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>pg</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- </header>
- <module>pg</module>
- <modulesummary>Distributed, Named Process Groups</modulesummary>
- <description>
- <warning>
- <p>This module is deprecated and will be removed in Erlang/OTP 18.</p>
- </warning>
- <p>This (experimental) module implements process groups. A process
- group is a group of processes that can be accessed by a common
- name. For example, a group named <c>foobar</c> can include a set
- of processes as members of this group and they can be located on
- different nodes.</p>
- <p>When messages are sent to the named group, all members of
- the group receive the message. The messages are serialized. If
- the process <c>P1</c> sends the message <c>M1</c> to the group,
- and process <c>P2</c> simultaneously sends message <c>M2</c>, then
- all members of the group receive the two messages in the same
- order. If members of a group terminate, they are automatically
- removed from the group.</p>
- <p>This module is not complete. The module is inspired by the ISIS
- system and the causal order protocol of the ISIS system should
- also be implemented. At the moment, all messages are serialized
- by sending them through a group master process.</p>
- </description>
- <funcs>
- <func>
- <name name="create" arity="1"/>
- <fsummary>Create an empty group</fsummary>
- <desc>
- <p>Creates an empty group named <c><anno>PgName</anno></c> on the current
- node.</p>
- </desc>
- </func>
- <func>
- <name name="create" arity="2"/>
- <fsummary>Create an empty group on another node</fsummary>
- <desc>
- <p>Creates an empty group named <c><anno>PgName</anno></c> on the node
- <c><anno>Node</anno></c>.</p>
- </desc>
- </func>
- <func>
- <name name="join" arity="2"/>
- <fsummary>Join a pid to a process group</fsummary>
- <desc>
- <p>Joins the pid <c><anno>Pid</anno></c> to the process group
- <c><anno>PgName</anno></c>.
- Returns a list of all old members of the group.</p>
- </desc>
- </func>
- <func>
- <name name="send" arity="2"/>
- <fsummary>Send a message to all members of a process group</fsummary>
- <desc>
- <p>Sends the tuple <c>{pg_message, From, PgName, Msg}</c> to
- all members of the process group <c><anno>PgName</anno></c>.</p>
- <p>Failure: <c>{badarg, {<anno>PgName</anno>, <anno>Msg</anno>}}</c>
- if <c><anno>PgName</anno></c> is
- not a process group (a globally registered name).</p>
- </desc>
- </func>
- <func>
- <name name="esend" arity="2"/>
- <fsummary>Send a message to all members of a process group, except ourselves</fsummary>
- <desc>
- <p>Sends the tuple <c>{pg_message, From, PgName, Msg}</c> to
- all members of the process group <c><anno>PgName</anno></c>, except
- ourselves.</p>
- <p>Failure: <c>{badarg, {<anno>PgName</anno>, <anno>Msg</anno>}}</c>
- if <c><anno>PgName</anno></c> is
- not a process group (a globally registered name).</p>
- </desc>
- </func>
- <func>
- <name name="members" arity="1"/>
- <fsummary>Return a list of all members of a process group</fsummary>
- <desc>
- <p>Returns a list of all members of the process group
- <c>PgName</c>.</p>
- </desc>
- </func>
- </funcs>
-</erlref>
-
diff --git a/lib/stdlib/doc/src/pool.xml b/lib/stdlib/doc/src/pool.xml
index 1b903984f9..e9c574038c 100644
--- a/lib/stdlib/doc/src/pool.xml
+++ b/lib/stdlib/doc/src/pool.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/proc_lib.xml b/lib/stdlib/doc/src/proc_lib.xml
index b0bad9d27b..85f0c0c908 100644
--- a/lib/stdlib/doc/src/proc_lib.xml
+++ b/lib/stdlib/doc/src/proc_lib.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -226,6 +227,17 @@ init(Parent) ->
</desc>
</func>
<func>
+ <name name="format" arity="3"/>
+ <fsummary>Format a crash report.</fsummary>
+ <desc>
+ <p>This function can be used by a user defined event handler to
+ format a crash report. When <anno>Depth</anno> is given as an
+ positive integer, it will be used in the format string to
+ limit the output as follows: <c>io_lib:format("~P",
+ [Term,<anno>Depth</anno>])</c>.</p>
+ </desc>
+ </func>
+ <func>
<name name="initial_call" arity="1"/>
<fsummary>Extract the initial call of a <c>proc_lib</c>spawned process.</fsummary>
<desc>
@@ -298,6 +310,40 @@ init(Parent) ->
<c>proc_lib</c> functions.</p>
</desc>
</func>
+ <func>
+ <name name="stop" arity="1"/>
+ <fsummary>Terminate a process synchronously.</fsummary>
+ <type variable="Process"/>
+ <desc>
+ <p>Equivalent to <seealso marker="#stop/3">stop(Process,
+ normal, infinity)</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="stop" arity="3"/>
+ <fsummary>Terminate a process synchronously.</fsummary>
+ <type variable="Process"/>
+ <type variable="Reason"/>
+ <type variable="Timeout"/>
+ <desc>
+ <p>Orders the process to exit with the given <c>Reason</c> and
+ waits for it to terminate.</p>
+ <p>The function returns <c>ok</c> if the process exits with
+ the given <c>Reason</c> within <c>Timeout</c>
+ milliseconds.</p>
+ <p>If the call times out, a <c>timeout</c> exception is
+ raised.</p>
+ <p>If the process does not exist, a <c>noproc</c>
+ exception is raised.</p>
+ <p>The implementation of this function is based on the
+ <c>terminate</c> system message, and requires that the
+ process handles system messages correctly.
+ See <seealso marker="sys">sys(3)</seealso>
+ and <seealso marker="doc/design_principles:spec_proc">OTP
+ Design Principles</seealso> for information about system
+ messages.</p>
+ </desc>
+ </func>
</funcs>
<section>
diff --git a/lib/stdlib/doc/src/proplists.xml b/lib/stdlib/doc/src/proplists.xml
index 1655133b2b..de4fbd3a7f 100644
--- a/lib/stdlib/doc/src/proplists.xml
+++ b/lib/stdlib/doc/src/proplists.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/qlc.xml b/lib/stdlib/doc/src/qlc.xml
index 8682936c08..8101b6458c 100644
--- a/lib/stdlib/doc/src/qlc.xml
+++ b/lib/stdlib/doc/src/qlc.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index 9c994154d4..c1665a1ed4 100644
--- a/lib/stdlib/doc/src/queue.xml
+++ b/lib/stdlib/doc/src/queue.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -95,9 +96,6 @@
</datatype>
<datatype>
<name name="queue" n_vars="0"/>
- <desc>
- <p><c>queue()</c> is equivalent to <c>queue(term())</c>.</p>
- </desc>
</datatype>
</datatypes>
diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml
new file mode 100644
index 0000000000..50057259c6
--- /dev/null
+++ b/lib/stdlib/doc/src/rand.xml
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2015</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.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.
+
+ </legalnotice>
+
+ <title>rand</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>rand.xml</file>
+ </header>
+ <module>rand</module>
+ <modulesummary>Pseudo random number generation</modulesummary>
+ <description>
+ <p>Random number generator.</p>
+
+ <p>The module contains several different algorithms and can be
+ extended with more in the future. The current uniform
+ distribution algorithms uses the
+ <url href="http://xorshift.di.unimi.it">
+ scrambled Xorshift algorithms by Sebastiano Vigna</url> and the
+ normal distribution algorithm uses the
+ <url href="http://www.jstatsoft.org/v05/i08">
+ Ziggurat Method by Marsaglia and Tsang</url>.
+ </p>
+
+ <p>The implemented algorithms are:</p>
+ <taglist>
+ <tag><c>exsplus</c></tag> <item>Xorshift116+, 58 bits precision and period of 2^116-1.</item>
+ <tag><c>exs64</c></tag> <item>Xorshift64*, 64 bits precision and a period of 2^64-1.</item>
+ <tag><c>exs1024</c></tag> <item>Xorshift1024*, 64 bits precision and a period of 2^1024-1.</item>
+ </taglist>
+
+ <p>The current default algorithm is <c>exsplus</c>. The default
+ may change in future. If a specific algorithm is required make
+ sure to always use <seealso marker="#seed-1">seed/1</seealso>
+ to initialize the state.
+ </p>
+
+ <p>Every time a random number is requested, a state is used to
+ calculate it and a new state produced. The state can either be
+ implicit or it can be an explicit argument and return value.
+ </p>
+
+ <p>The functions with implicit state use the process dictionary
+ variable <c>rand_seed</c> to remember the current state.</p>
+
+ <p>If a process calls <seealso marker="#uniform-0">uniform/0</seealso> or
+ <seealso marker="#uniform-1">uniform/1</seealso> without
+ setting a seed first, <seealso marker="#seed-1">seed/1</seealso>
+ is called automatically with the default algorithm and creates a
+ non-constant seed.</p>
+
+ <p>The functions with explicit state never use the process
+ dictionary.</p>
+
+ <p>Examples:</p>
+ <pre>
+ %% Simple usage. Creates and seeds the default algorithm
+ %% with a non-constant seed if not already done.
+ R0 = rand:uniform(),
+ R1 = rand:uniform(),
+
+ %% Use a given algorithm.
+ _ = rand:seed(exs1024),
+ R2 = rand:uniform(),
+
+ %% Use a given algorithm with a constant seed.
+ _ = rand:seed(exs1024, {123, 123534, 345345}),
+ R3 = rand:uniform(),
+
+ %% Use the functional api with non-constant seed.
+ S0 = rand:seed_s(exsplus),
+ {R4, S1} = rand:uniform_s(S0),
+
+ %% Create a standard normal deviate.
+ {SND0, S2} = rand:normal_s(S1),
+ </pre>
+
+ <note><p>This random number generator is not cryptographically
+ strong. If a strong cryptographic random number generator is
+ needed, use one of functions in the
+ <seealso marker="crypto:crypto">crypto</seealso>
+ module, for example <c>crypto:strong_rand_bytes/1</c>.</p></note>
+ </description>
+ <datatypes>
+ <datatype>
+ <name name="alg"/>
+ </datatype>
+
+ <datatype>
+ <name name="state"/>
+ <desc><p>Algorithm dependent state.</p></desc>
+ </datatype>
+
+ <datatype>
+ <name name="export_state"/>
+ <desc><p>Algorithm dependent state which can be printed or saved to file.</p></desc>
+ </datatype>
+ </datatypes>
+
+ <funcs>
+ <func>
+ <name name="seed" arity="1"/>
+ <fsummary>Seed random number generator</fsummary>
+ <desc>
+ <marker id="seed-1"/>
+ <p>Seeds random number generation with the given algorithm and time dependent
+ data if <anno>AlgOrExpState</anno> is an algorithm.</p>
+ <p>Otherwise recreates the exported seed in the process
+ dictionary, and returns the state.
+ <em>See also:</em> <seealso marker="#export_seed-0">export_seed/0</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="seed_s" arity="1"/>
+ <fsummary>Seed random number generator</fsummary>
+ <desc>
+ <p>Seeds random number generation with the given algorithm and time dependent
+ data if <anno>AlgOrExpState</anno> is an algorithm.</p>
+ <p>Otherwise recreates the exported seed and returns the state.
+ <em>See also:</em> <seealso marker="#export_seed-0">export_seed/0</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="seed" arity="2"/>
+ <fsummary>Seed the random number generation</fsummary>
+ <desc>
+ <p>Seeds random number generation with the given algorithm and
+ integers in the process dictionary and returns
+ the state.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="seed_s" arity="2"/>
+ <fsummary>Seed the random number generation</fsummary>
+ <desc>
+ <p>Seeds random number generation with the given algorithm and
+ integers and returns the state.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="export_seed" arity="0"/>
+ <fsummary>Export the random number generation state</fsummary>
+ <desc><marker id="export_seed-0"/>
+ <p>Returns the random number state in an external format.
+ To be used with <seealso marker="#seed-1">seed/1</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="export_seed_s" arity="1"/>
+ <fsummary>Export the random number generation state</fsummary>
+ <desc><marker id="export_seed_s-1"/>
+ <p>Returns the random number generator state in an external format.
+ To be used with <seealso marker="#seed-1">seed/1</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="uniform" arity="0"/>
+ <fsummary>Return a random float</fsummary>
+ <desc>
+ <marker id="uniform-0"/>
+ <p>Returns a random float uniformly distributed in the value
+ range <c>0.0 &lt; <anno>X</anno> &lt; 1.0 </c> and
+ updates the state in the process dictionary.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="uniform_s" arity="1"/>
+ <fsummary>Return a random float</fsummary>
+ <desc>
+ <p>Given a state, <c>uniform_s/1</c> returns a random float
+ uniformly distributed in the value range <c>0.0 &lt;
+ <anno>X</anno> &lt; 1.0</c> and a new state.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="uniform" arity="1"/>
+ <fsummary>Return a random integer</fsummary>
+ <desc>
+ <marker id="uniform-1"/>
+ <p>Given an integer <c><anno>N</anno> >= 1</c>,
+ <c>uniform/1</c> returns a random integer uniformly
+ distributed in the value range
+ <c>1 &lt;= <anno>X</anno> &lt;= <anno>N</anno></c> and
+ updates the state in the process dictionary.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="uniform_s" arity="2"/>
+ <fsummary>Return a random integer</fsummary>
+ <desc>
+ <p>Given an integer <c><anno>N</anno> >= 1</c> and a state,
+ <c>uniform_s/2</c> returns a random integer uniformly
+ distributed in the value range <c>1 &lt;= <anno>X</anno> &lt;=
+ <anno>N</anno></c> and a new state.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="normal" arity="0"/>
+ <fsummary>Return a standard normal distributed random float</fsummary>
+ <desc>
+ <p>Returns a standard normal deviate float (that is, the mean
+ is 0 and the standard deviation is 1) and updates the state in
+ the process dictionary.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="normal_s" arity="1"/>
+ <fsummary>Return a standard normal distributed random float</fsummary>
+ <desc>
+ <p>Given a state, <c>normal_s/1</c> returns a standard normal
+ deviate float (that is, the mean is 0 and the standard
+ deviation is 1) and a new state.</p>
+ </desc>
+ </func>
+
+ </funcs>
+</erlref>
diff --git a/lib/stdlib/doc/src/random.xml b/lib/stdlib/doc/src/random.xml
index e001058e19..fc4f796863 100644
--- a/lib/stdlib/doc/src/random.xml
+++ b/lib/stdlib/doc/src/random.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -47,7 +48,10 @@
tuple of three integers.</p>
<p>It should be noted that this random number generator is not cryptographically
strong. If a strong cryptographic random number generator is needed for
- example <c>crypto:rand_bytes/1</c> could be used instead.</p>
+ example <c>crypto:strong_rand_bytes/1</c> could be used instead.</p>
+ <note><p>The new and improved <seealso
+ marker="stdlib:rand">rand</seealso> module should be used
+ instead of this module.</p></note>
</description>
<datatypes>
<datatype>
@@ -70,12 +74,17 @@
<desc>
<p>Seeds random number generation with integer values in the process
dictionary, and returns the old state.</p>
- <p>One way of obtaining a seed is to use the BIF <c>now/0</c>:</p>
+ <p>One easy way of obtaining a unique value to seed with is to:</p>
<code type="none">
- ...
- {A1,A2,A3} = now(),
- random:seed(A1, A2, A3),
- ...</code>
+random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer())</code>
+ <p>See <seealso marker="erts:erlang#phash2/1">
+ erlang:phash2/1</seealso>, <seealso marker="erts:erlang#node/0">
+ node/0</seealso>, <seealso marker="erts:erlang#monotonic_time/0">
+ erlang:monotonic_time/0</seealso>, and
+ <seealso marker="erts:erlang#unique_integer/0">
+ erlang:unique_integer/0</seealso>) for details.</p>
</desc>
</func>
<func>
@@ -139,7 +148,7 @@
<p>The implementation changed in R15. Upgrading to R15 will break
applications that expect a specific output for a given seed. The output
is still deterministic number series, but different compared to releases
- older than R15. The seed <c>{0,0,0}</c> will for example no longer
+ older than R15. The seed <c>{0,0,0}</c> will, for example, no longer
produce a flawed series of only zeros.</p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 5af1468e9b..8c19926b10 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved on line at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -204,8 +205,8 @@ This option makes it possible to include comments inside complicated patterns. N
</func>
<func>
<name name="run" arity="3"/>
- <type_desc variable="CompileOpt">See <seealso marker="#compile_options">compile/2</seealso> above.</type_desc>
<fsummary>Match a subject against regular expression and capture subpatterns</fsummary>
+ <type_desc variable="CompileOpt">See <seealso marker="#compile_options">compile/2</seealso> above.</type_desc>
<desc>
<p>Executes a regexp matching, returning <c>match/{match,
@@ -880,11 +881,11 @@ nomatch
</desc>
</func>
</funcs>
-
- <marker id="regexp_syntax"></marker>
+
<section>
<title>PERL LIKE REGULAR EXPRESSIONS SYNTAX</title>
- <p>The following sections contain reference material for the
+ <p><marker id="regexp_syntax"></marker>
+ The following sections contain reference material for the
regular expressions used by this module. The regular expression
reference is based on the PCRE documentation, with changes in
cases where the re module behaves differently to the PCRE library.</p>
@@ -2069,7 +2070,7 @@ supported, and an error is given if they are encountered.</p>
<p>By default, in UTF modes, characters with values greater than 255 do not match
any of the POSIX character classes. However, if the PCRE_UCP option is passed
-to <b>pcre_compile()</b>, some of the classes are changed so that Unicode
+to <em>pcre_compile()</em>, some of the classes are changed so that Unicode
character properties are used. This is achieved by replacing the POSIX classes
by other sequences, as follows:</p>
@@ -2077,10 +2078,10 @@ by other sequences, as follows:</p>
<tag>[:alnum:]</tag> <item>becomes <em>\p{Xan}</em></item>
<tag>[:alpha:]</tag> <item>becomes <em>\p{L}</em></item>
<tag>[:blank:]</tag> <item>becomes <em>\h</em></item>
- <tag>[:digit:</tag>] <item>becomes <em>\p{Nd}</em></item>
+ <tag>[:digit:]</tag> <item>becomes <em>\p{Nd}</em></item>
<tag>[:lower:]</tag> <item>becomes <em>\p{Ll}</em></item>
<tag>[:space:]</tag> <item>becomes <em>\p{Xps}</em></item>
- <tag>[:upper:</tag>] <item>becomes <em>\p{Lu}</em></item>
+ <tag>[:upper:]</tag> <item>becomes <em>\p{Lu}</em></item>
<tag>[:word:]</tag> <item>becomes <em>\p{Xwd}</em></item>
</taglist>
@@ -3058,7 +3059,7 @@ default newline convention is in force:</p>
<quote><p> abc #comment \n still comment</p></quote>
-<p>On encountering the # character, <b>pcre_compile()</b> skips along, looking for
+<p>On encountering the # character, <em>pcre_compile()</em> skips along, looking for
a newline in the pattern. The sequence \n is still literal at this stage, so
it does not terminate the comment. Only an actual character with the code value
0x0a (the default newline) does so.</p>
diff --git a/lib/stdlib/doc/src/ref_man.xml b/lib/stdlib/doc/src/ref_man.xml
index 6c35578bdf..82ad78e675 100644
--- a/lib/stdlib/doc/src/ref_man.xml
+++ b/lib/stdlib/doc/src/ref_man.xml
@@ -4,20 +4,21 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -35,6 +36,7 @@
</description>
<xi:include href="stdlib_app.xml"/>
<xi:include href="array.xml"/>
+ <xi:include href="assert_hrl.xml"/>
<xi:include href="base64.xml"/>
<xi:include href="beam_lib.xml"/>
<xi:include href="binary.xml"/>
@@ -45,6 +47,7 @@
<xi:include href="digraph.xml"/>
<xi:include href="digraph_utils.xml"/>
<xi:include href="epp.xml"/>
+ <xi:include href="erl_anno.xml"/>
<xi:include href="erl_eval.xml"/>
<xi:include href="erl_expand_records.xml"/>
<xi:include href="erl_id_trans.xml"/>
@@ -73,12 +76,12 @@
<xi:include href="ms_transform.xml"/>
<xi:include href="orddict.xml"/>
<xi:include href="ordsets.xml"/>
- <xi:include href="pg.xml"/>
<xi:include href="pool.xml"/>
<xi:include href="proc_lib.xml"/>
<xi:include href="proplists.xml"/>
<xi:include href="qlc.xml"/>
<xi:include href="queue.xml"/>
+ <xi:include href="rand.xml"/>
<xi:include href="random.xml"/>
<xi:include href="re.xml"/>
<xi:include href="sets.xml"/>
diff --git a/lib/stdlib/doc/src/sets.xml b/lib/stdlib/doc/src/sets.xml
index c5b8dce4b7..531d18fbef 100644
--- a/lib/stdlib/doc/src/sets.xml
+++ b/lib/stdlib/doc/src/sets.xml
@@ -4,20 +4,21 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2014</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -50,9 +51,6 @@
</datatype>
<datatype>
<name name="set" n_vars="0"/>
- <desc>
- <p><c>set()</c> is equivalent to <c>set(term())</c>.</p>
- </desc>
</datatype>
</datatypes>
<funcs>
@@ -65,7 +63,7 @@
</func>
<func>
<name name="is_set" arity="1"/>
- <fsummary>Test for an <c>Set</c></fsummary>
+ <fsummary>Test for a <c>Set</c></fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Set</anno></c> is a set of
elements, otherwise <c>false</c>.</p>
@@ -80,21 +78,22 @@
</func>
<func>
<name name="to_list" arity="1"/>
- <fsummary>Convert an <c>Set</c>into a list</fsummary>
+ <fsummary>Convert a <c>Set</c>into a list</fsummary>
<desc>
- <p>Returns the elements of <c><anno>Set</anno></c> as a list.</p>
+ <p>Returns the elements of <c><anno>Set</anno></c> as a list.
+ The order of the returned elements is undefined.</p>
</desc>
</func>
<func>
<name name="from_list" arity="1"/>
- <fsummary>Convert a list into an <c>Set</c></fsummary>
+ <fsummary>Convert a list into a <c>Set</c></fsummary>
<desc>
- <p>Returns an set of the elements in <c><anno>List</anno></c>.</p>
+ <p>Returns a set of the elements in <c><anno>List</anno></c>.</p>
</desc>
</func>
<func>
<name name="is_element" arity="2"/>
- <fsummary>Test for membership of an <c>Set</c></fsummary>
+ <fsummary>Test for membership of a <c>Set</c></fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Element</anno></c> is an element of
<c><anno>Set</anno></c>, otherwise <c>false</c>.</p>
@@ -102,7 +101,7 @@
</func>
<func>
<name name="add_element" arity="2"/>
- <fsummary>Add an element to an <c>Set</c></fsummary>
+ <fsummary>Add an element to a <c>Set</c></fsummary>
<desc>
<p>Returns a new set formed from <c><anno>Set1</anno></c> with
<c><anno>Element</anno></c> inserted.</p>
@@ -110,7 +109,7 @@
</func>
<func>
<name name="del_element" arity="2"/>
- <fsummary>Remove an element from an <c>Set</c></fsummary>
+ <fsummary>Remove an element from a <c>Set</c></fsummary>
<desc>
<p>Returns <c><anno>Set1</anno></c>, but with <c><anno>Element</anno></c> removed.</p>
</desc>
@@ -175,7 +174,8 @@
<fsummary>Fold over set elements</fsummary>
<desc>
<p>Fold <c><anno>Function</anno></c> over every element in <c><anno>Set</anno></c>
- returning the final value of the accumulator.</p>
+ returning the final value of the accumulator.
+ The evaluation order is undefined.</p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/doc/src/shell.xml b/lib/stdlib/doc/src/shell.xml
index 3ca80ed900..22a3321298 100644
--- a/lib/stdlib/doc/src/shell.xml
+++ b/lib/stdlib/doc/src/shell.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/shell_default.xml b/lib/stdlib/doc/src/shell_default.xml
index 2355ba92f9..51cd3b62d3 100644
--- a/lib/stdlib/doc/src/shell_default.xml
+++ b/lib/stdlib/doc/src/shell_default.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/slave.xml b/lib/stdlib/doc/src/slave.xml
index f5d0436a20..8c16cbf5b1 100644
--- a/lib/stdlib/doc/src/slave.xml
+++ b/lib/stdlib/doc/src/slave.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml
index 6c97fd0bc0..53f6ca957a 100644
--- a/lib/stdlib/doc/src/sofs.xml
+++ b/lib/stdlib/doc/src/sofs.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -397,8 +398,9 @@ fun(S) -> sofs:partition(1, S) end
</datatype>
<datatype>
<!-- Parameterized opaque types are NYI: -->
- <name><marker id="type-tuple_of">tuple_of(T)</marker></name>
- <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
+ <name>tuple_of(T)</name>
+ <desc><p><marker id="type-tuple_of"/>
+ A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/specs.xml b/lib/stdlib/doc/src/specs.xml
index 60a04ed5e7..0418bf7b22 100644
--- a/lib/stdlib/doc/src/specs.xml
+++ b/lib/stdlib/doc/src/specs.xml
@@ -11,6 +11,7 @@
<xi:include href="../specs/specs_digraph.xml"/>
<xi:include href="../specs/specs_digraph_utils.xml"/>
<xi:include href="../specs/specs_epp.xml"/>
+ <xi:include href="../specs/specs_erl_anno.xml"/>
<xi:include href="../specs/specs_erl_eval.xml"/>
<xi:include href="../specs/specs_erl_expand_records.xml"/>
<xi:include href="../specs/specs_erl_id_trans.xml"/>
@@ -39,12 +40,12 @@
<xi:include href="../specs/specs_ms_transform.xml"/>
<xi:include href="../specs/specs_orddict.xml"/>
<xi:include href="../specs/specs_ordsets.xml"/>
- <xi:include href="../specs/specs_pg.xml"/>
<xi:include href="../specs/specs_pool.xml"/>
<xi:include href="../specs/specs_proc_lib.xml"/>
<xi:include href="../specs/specs_proplists.xml"/>
<xi:include href="../specs/specs_qlc.xml"/>
<xi:include href="../specs/specs_queue.xml"/>
+ <xi:include href="../specs/specs_rand.xml"/>
<xi:include href="../specs/specs_random.xml"/>
<xi:include href="../specs/specs_re.xml"/>
<xi:include href="../specs/specs_sets.xml"/>
diff --git a/lib/stdlib/doc/src/stdlib_app.xml b/lib/stdlib/doc/src/stdlib_app.xml
index de4cc65396..43bcad9098 100644
--- a/lib/stdlib/doc/src/stdlib_app.xml
+++ b/lib/stdlib/doc/src/stdlib_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/string.xml b/lib/stdlib/doc/src/string.xml
index b05d5cbc08..d64db6c7ee 100644
--- a/lib/stdlib/doc/src/string.xml
+++ b/lib/stdlib/doc/src/string.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index 3a5027d595..815bf4a489 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -37,12 +38,12 @@
the <c>gen_event</c>, <c>gen_fsm</c>, or <c>gen_server</c>
behaviours. A supervisor implemented using this module will have
a standard set of interface functions and include functionality
- for tracing and error reporting. Supervisors are used to build an
+ for tracing and error reporting. Supervisors are used to build a
hierarchical process structure called a supervision tree, a
nice way to structure a fault tolerant application. Refer to
<em>OTP Design Principles</em> for more information.</p>
- <p>A supervisor assumes the definition of which child processes to
- supervise to be located in a callback module exporting a
+ <p>A supervisor expects the definition of which child processes to
+ supervise to be specified in a callback module exporting a
pre-defined set of functions.</p>
<p>Unless otherwise stated, all functions in this module will fail
if the specified supervisor does not exist or if bad arguments
@@ -53,18 +54,30 @@
<title>Supervision Principles</title>
<p>The supervisor is responsible for starting, stopping and
monitoring its child processes. The basic idea of a supervisor is
- that it should keep its child processes alive by restarting them
+ that it shall keep its child processes alive by restarting them
when necessary.</p>
- <p>The children of a supervisor is defined as a list of
+ <p>The children of a supervisor are defined as a list of
<em>child specifications</em>. When the supervisor is started, the child
processes are started in order from left to right according to
this list. When the supervisor terminates, it first terminates
its child processes in reversed start order, from right to left.</p>
- <p>A supervisor can have one of the following <em>restart strategies</em>:</p>
+ <marker id="sup_flags"/>
+ <p>The properties of a supervisor are defined by the supervisor
+ flags. This is the type definition for the supervisor flags:
+ </p>
+ <pre>sup_flags() = #{strategy => strategy(), % optional
+ intensity => non_neg_integer(), % optional
+ period => pos_integer()} % optional
+ </pre>
+ <p>A supervisor can have one of the following <em>restart
+ strategies</em>, specified with the <c>strategy</c> key in the
+ above map:
+ </p>
<list type="bulleted">
<item>
<p><c>one_for_one</c> - if one child process terminates and
- should be restarted, only that child process is affected.</p>
+ should be restarted, only that child process is
+ affected. This is the default restart strategy.</p>
</item>
<item>
<p><c>one_for_all</c> - if one child process terminates and
@@ -94,43 +107,53 @@
instead the child specification identifier is used,
<c>terminate_child/2</c> will return
<c>{error,simple_one_for_one}</c>.</p>
- <p>Because a <c>simple_one_for_one</c> supervisor could have many
- children, it shuts them all down at same time. So, order in which they
- are stopped is not defined. For the same reason, it could have an
- overhead with regards to the <c>Shutdown</c> strategy.</p>
+ <p>Because a <c>simple_one_for_one</c> supervisor could have
+ many children, it shuts them all down asynchronously. This
+ means that the children will do their cleanup in parallel,
+ and therefore the order in which they are stopped is not
+ defined.</p>
</item>
</list>
<p>To prevent a supervisor from getting into an infinite loop of
- child process terminations and restarts, a <em>maximum restart frequency</em>
- is defined using two integer values <c>MaxR</c>
- and <c>MaxT</c>. If more than <c>MaxR</c> restarts occur within
- <c>MaxT</c> seconds, the supervisor terminates all child
- processes and then itself.
+ child process terminations and restarts, a <em>maximum restart
+ intensity</em> is defined using two integer values specified
+ with the <c>intensity</c> and <c>period</c> keys in the above
+ 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 will
+ terminate all child processes and then itself. The default value
+ for <c>intensity</c> is <c>1</c>, and the default value
+ for <c>period</c> is <c>5</c>.
</p>
<marker id="child_spec"/>
<p>This is the type definition of a child specification:</p>
- <pre>
-child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
- Id = term()
- StartFunc = {M,F,A}
- M = F = atom()
- A = [term()]
- Restart = permanent | transient | temporary
- Shutdown = brutal_kill | int()>0 | infinity
- Type = worker | supervisor
- Modules = [Module] | dynamic
- Module = atom()</pre>
+ <pre>child_spec() = #{id => child_id(), % mandatory
+ start => mfargs(), % mandatory
+ restart => restart(), % optional
+ shutdown => shutdown(), % optional
+ type => worker(), % optional
+ modules => modules()} % optional</pre>
+ <p>The old tuple format is kept for backwards compatibility,
+ see <seealso marker="#type-child_spec">child_spec()</seealso>,
+ but the map is preferred.
+ </p>
<list type="bulleted">
<item>
- <p><c>Id</c> is a name that is used to identify the child
+ <p><c>id</c> is used to identify the child
specification internally by the supervisor.</p>
+ <p>The <c>id</c> key is mandatory.</p>
+ <p>Note that this identifier on occations has been called
+ "name". As far as possible, the terms "identifier" or "id"
+ are now used but in order to keep backwards compatibility,
+ some occurences of "name" can still be found, for example
+ in error messages.</p>
</item>
<item>
- <p><c>StartFunc</c> defines the function call used to start
- the child process. It should be a module-function-arguments
+ <p><c>start</c> defines the function call used to start the
+ child process. It must be a module-function-arguments
tuple <c>{M,F,A}</c> used as <c>apply(M,F,A)</c>.</p>
<p>The start function <em>must create and link to</em> the child
- process, and should return <c>{ok,Child}</c> or
+ process, and must return <c>{ok,Child}</c> or
<c>{ok,Child,Info}</c> where <c>Child</c> is the pid of
the child process and <c>Info</c> an arbitrary term which is
ignored by the supervisor.</p>
@@ -143,20 +166,23 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
error tuple <c>{error,Error}</c>.</p>
<p>Note that the <c>start_link</c> functions of the different
behaviour modules fulfill the above requirements.</p>
+ <p>The <c>start</c> key is mandatory.</p>
</item>
<item>
- <p><c>Restart</c> defines when a terminated child process
- should be restarted. A <c>permanent</c> child process should
- always be restarted, a <c>temporary</c> child process should
+ <p><c>restart</c> defines when a terminated child process
+ shall be restarted. A <c>permanent</c> child process will
+ always be restarted, a <c>temporary</c> child process will
never be restarted (even when the supervisor's restart strategy
is <c>rest_for_one</c> or <c>one_for_all</c> and a sibling's
death causes the temporary process to be terminated) and a
- <c>transient</c> child process should be restarted only if
+ <c>transient</c> child process will be restarted only if
it terminates abnormally, i.e. with another exit reason
than <c>normal</c>, <c>shutdown</c> or <c>{shutdown,Term}</c>.</p>
+ <p>The <c>restart</c> key is optional. If it is not given, the
+ default value <c>permanent</c> will be used.</p>
</item>
<item>
- <p><c>Shutdown</c> defines how a child process should be
+ <p><c>shutdown</c> defines how a child process shall be
terminated. <c>brutal_kill</c> means the child process will
be unconditionally terminated using <c>exit(Child,kill)</c>.
An integer timeout value means that the supervisor will tell
@@ -166,35 +192,45 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
no exit signal is received within the specified number of milliseconds,
the child process is unconditionally terminated using
<c>exit(Child,kill)</c>.</p>
- <p>If the child process is another supervisor, <c>Shutdown</c>
+ <p>If the child process is another supervisor, the shutdown time
should be set to <c>infinity</c> to give the subtree ample
- time to shutdown. It is also allowed to set it to <c>infinity</c>,
+ time to shut down. It is also allowed to set it to <c>infinity</c>,
if the child process is a worker.</p>
<warning>
- <p>Be careful by setting the <c>Shutdown</c> strategy to
+ <p>Be careful when setting the shutdown time to
<c>infinity</c> when the child process is a worker. Because, in this
situation, the termination of the supervision tree depends on the
child process, it must be implemented in a safe way and its cleanup
procedure must always return.</p>
</warning>
<p>Note that all child processes implemented using the standard
- OTP behavior modules automatically adhere to the shutdown
+ OTP behaviour modules automatically adhere to the shutdown
protocol.</p>
+ <p>The <c>shutdown</c> key is optional. If it is not given,
+ the default value <c>5000</c> will be used if the child is
+ of type <c>worker</c>; and <c>infinity</c> will be used if
+ the child is of type <c>supervisor</c>.</p>
</item>
<item>
- <p><c>Type</c> specifies if the child process is a supervisor or
+ <p><c>type</c> specifies if the child process is a supervisor or
a worker.</p>
+ <p>The <c>type</c> key is optional. If it is not given, the
+ default value <c>worker</c> will be used.</p>
</item>
<item>
- <p><c>Modules</c> is used by the release handler during code
+ <p><c>modules</c> is used by the release handler during code
replacement to determine which processes are using a certain
- module. As a rule of thumb <c>Modules</c> should be a list
- with one element <c>[Module]</c>, where <c>Module</c> is
- the callback module, if the child process is a supervisor,
- gen_server or gen_fsm. If the child process is an event
- manager (gen_event) with a dynamic set of callback modules,
- <c>Modules</c> should be <c>dynamic</c>. See <em>OTP Design Principles</em>
- for more information about release handling.</p>
+ module. As a rule of thumb, if the child process is a
+ <c>supervisor</c>, <c>gen_server</c>, or <c>gen_fsm</c>,
+ this should be a list with one element <c>[Module]</c>,
+ where <c>Module</c> is the callback module. If the child
+ process is an event manager (<c>gen_event</c>) with a
+ dynamic set of callback modules, the value <c>dynamic</c>
+ shall be used. See <em>OTP Design Principles</em> for more
+ information about release handling.</p>
+ <p>The <c>modules</c> key is optional. If it is not given, it
+ defaults to <c>[M]</c>, where <c>M</c> comes from the
+ child's start <c>{M,F,A}</c></p>
</item>
<item>
<p>Internally, the supervisor also keeps track of the pid
@@ -213,11 +249,20 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
</datatype>
<datatype>
<name name="child_spec"/>
+ <desc><p>The tuple format is kept for backwards compatibility
+ only. A map is preferred; see more details
+ <seealso marker="#child_spec">above</seealso>.</p></desc>
</datatype>
<datatype>
<name name="mfargs"/>
- <desc><p><c>A</c> (the argument list) has the value
- <c>undefined</c> if <c>Restart</c> is <c>temporary</c>.</p>
+ <desc>
+ <p>The value <c>undefined</c> for <c><anno>A</anno></c> (the
+ argument list) is only to be used internally
+ in <c>supervisor</c>. If the restart type of the child
+ is <c>temporary</c>, then the process is never to be
+ restarted and therefore there is no need to store the real
+ argument list. The value <c>undefined</c> will then be
+ stored instead.</p>
</desc>
</datatype>
<datatype>
@@ -233,6 +278,12 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<name name="strategy"/>
</datatype>
<datatype>
+ <name name="sup_flags"/>
+ <desc><p>The tuple format is kept for backwards compatibility
+ only. A map is preferred; see more details
+ <seealso marker="#sup_flags">above</seealso>.</p></desc>
+ </datatype>
+ <datatype>
<name name="sup_ref"/>
</datatype>
<datatype>
@@ -253,20 +304,20 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
the supervisor is linked to the calling process (its
supervisor).</p>
<p>The created supervisor process calls <c><anno>Module</anno>:init/1</c> to
- find out about restart strategy, maximum restart frequency
+ find out about restart strategy, maximum restart intensity
and child processes. To ensure a synchronized start-up
procedure, <c>start_link/2,3</c> does not return until
<c><anno>Module</anno>:init/1</c> has returned and all child processes
have been started.</p>
- <p>If <c><anno>SupName</anno>={local,Name}</c> the supervisor is registered
+ <p>If <c><anno>SupName</anno>={local,Name}</c>, the supervisor is registered
locally as <c>Name</c> using <c>register/2</c>. If
<c><anno>SupName</anno>={global,Name}</c> the supervisor is registered
globally as <c>Name</c> using <c>global:register_name/2</c>. If
<c><anno>SupName</anno>={via,<anno>Module</anno>,<anno>Name</anno>}</c> the supervisor
is registered as <c>Name</c> using the registry represented by
- <c>Module</c>. The <c>Module</c> callback should export the functions
+ <c>Module</c>. The <c>Module</c> callback must export the functions
<c>register_name/2</c>, <c>unregister_name/1</c> and <c>send/2</c>,
- which should behave like the corresponding functions in <c>global</c>.
+ which shall behave like the corresponding functions in <c>global</c>.
Thus, <c>{via,global,<anno>Name</anno>}</c> is a valid reference.</p>
<p>If no name is provided, the supervisor is not registered.</p>
<p><c><anno>Module</anno></c> is the name of the callback module.</p>
@@ -274,14 +325,14 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
the argument to <c><anno>Module</anno>:init/1</c>.</p>
<p>If the supervisor and its child processes are successfully
created (i.e. if all child process start functions return
- <c>{ok,Child}</c>, <c>{ok,Child,Info}</c>, or <c>ignore</c>)
+ <c>{ok,Child}</c>, <c>{ok,Child,Info}</c>, or <c>ignore</c>),
the function returns <c>{ok,Pid}</c>, where <c>Pid</c> is
the pid of the supervisor. If there already exists a process
- with the specified <c><anno>SupName</anno></c> the function returns
+ with the specified <c><anno>SupName</anno></c>, the function returns
<c>{error,{already_started,Pid}}</c>, where <c>Pid</c> is
the pid of that process.</p>
<p>If <c><anno>Module</anno>:init/1</c> returns <c>ignore</c>, this function
- returns <c>ignore</c> as well and the supervisor terminates
+ returns <c>ignore</c> as well, and the supervisor terminates
with reason <c>normal</c>.
If <c><anno>Module</anno>:init/1</c> fails or returns an incorrect value,
this function returns <c>{error,Term}</c> where <c>Term</c>
@@ -297,13 +348,12 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<func>
<name name="start_child" arity="2"/>
<fsummary>Dynamically add a child process to a supervisor.</fsummary>
- <type name="child_spec"/>
<type name="startchild_ret"/>
<type name="startchild_err"/>
<desc>
<p>Dynamically adds a child specification to the supervisor
<c><anno>SupRef</anno></c> which starts the corresponding child process.</p>
- <p><marker id="SupRef"><c><anno>SupRef</anno></c></marker> can be:</p>
+ <p><marker id="SupRef"/><c><anno>SupRef</anno></c> can be:</p>
<list type="bulleted">
<item>the pid,</item>
<item><c>Name</c>, if the supervisor is locally registered,</item>
@@ -314,35 +364,41 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<item><c>{via,Module,Name}</c>, if the supervisor is registered
through an alternative process registry.</item>
</list>
- <p><c><anno>ChildSpec</anno></c> should be a valid child specification
+ <p><c><anno>ChildSpec</anno></c> must be a valid child specification
(unless the supervisor is a <c>simple_one_for_one</c>
- supervisor, see below). The child process will be started by
+ supervisor; see below). The child process will be started by
using the start function as defined in the child
specification.</p>
- <p>If the case of a <c>simple_one_for_one</c> supervisor,
+ <p>In the case of a <c>simple_one_for_one</c> supervisor,
the child specification defined in <c>Module:init/1</c> will
- be used and <c><anno>ChildSpec</anno></c> should instead be an arbitrary
+ be used, and <c><anno>ChildSpec</anno></c> shall instead be an arbitrary
list of terms <c><anno>List</anno></c>. The child process will then be
started by appending <c><anno>List</anno></c> to the existing start
function arguments, i.e. by calling
<c>apply(M, F, A++<anno>List</anno>)</c> where <c>{M,F,A}</c> is the start
function defined in the child specification.</p>
<p>If there already exists a child specification with
- the specified <c><anno>Id</anno></c>, <c><anno>ChildSpec</anno></c> is discarded and
+ the specified identifier, <c><anno>ChildSpec</anno></c> is discarded, and
the function returns <c>{error,already_present}</c> or
<c>{error,{already_started,<anno>Child</anno>}}</c>, depending on if
the corresponding child process is running or not.</p>
<p>If the child process start function returns <c>{ok,<anno>Child</anno>}</c>
- or <c>{ok,<anno>Child</anno>,<anno>Info</anno>}</c>, the child specification and pid is
+ or <c>{ok,<anno>Child</anno>,<anno>Info</anno>}</c>, the child specification and pid are
added to the supervisor and the function returns the same
value.</p>
<p>If the child process start function returns <c>ignore</c>,
- the child specification is added to the supervisor, the pid
- is set to <c>undefined</c> and the function returns
- <c>{ok,undefined}</c>.</p>
+ the child specification is added to the supervisor (unless the
+ supervisor is a <c>simple_one_for_one</c> supervisor, see below),
+ the pid is set to <c>undefined</c> and the function returns
+ <c>{ok,undefined}</c>.
+ </p>
+ <p>In the case of a <c>simple_one_for_one</c> supervisor, when a child
+ process start function returns <c>ignore</c> the functions returns
+ <c>{ok,undefined}</c> and no child is added to the supervisor.
+ </p>
<p>If the child process start function returns an error tuple or
an erroneous value, or if it fails, the child specification is
- discarded and the function returns <c>{error,Error}</c> where
+ discarded, and the function returns <c>{error,Error}</c> where
<c>Error</c> is a term containing information about the error
and child specification.</p>
</desc>
@@ -366,7 +422,7 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<p>If the child is temporary, the child specification is deleted as
soon as the process terminates. This means
- that <c>delete_child/2</c> has no meaning
+ that <c>delete_child/2</c> has no meaning,
and <c>restart_child/2</c> can not be used for these
children.</p>
@@ -375,13 +431,13 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
process is alive, but is not a child of the given
supervisor, the function will return
<c>{error,not_found}</c>. If the child specification
- identifier is given instead instead of a <c>pid()</c>, the
+ identifier is given instead of a <c>pid()</c>, the
function will return <c>{error,simple_one_for_one}</c>.</p>
<p>If successful, the function returns <c>ok</c>. If there is
no child specification with the specified <c><anno>Id</anno></c>, the
function returns <c>{error,not_found}</c>.</p>
- <p>See <c>start_child/2</c> for a description of
- <c><anno>SupRef</anno></c>.</p>
+ <p>See <seealso marker="#SupRef"><c>start_child/2</c></seealso>
+ for a description of <c><anno>SupRef</anno></c>.</p>
</desc>
</func>
<func>
@@ -390,15 +446,15 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<desc>
<p>Tells the supervisor <c><anno>SupRef</anno></c> to delete the child
specification identified by <c><anno>Id</anno></c>. The corresponding child
- process must not be running, use <c>terminate_child/2</c> to
+ process must not be running. Use <c>terminate_child/2</c> to
terminate it.</p>
- <p>See <seealso marker="#SupRef"><c>start_child/2</c></seealso> for a description of
- <c>SupRef</c>.</p>
+ <p>See <seealso marker="#SupRef"><c>start_child/2</c></seealso>
+ for a description of <c><anno>SupRef</anno></c>.</p>
<p>If successful, the function returns <c>ok</c>. If the child
specification identified by <c><anno>Id</anno></c> exists but
the corresponding child process is running or about to be restarted,
the function returns <c>{error,running}</c> or
- <c>{error,restarting}</c> respectively. If the child specification
+ <c>{error,restarting}</c>, respectively. If the child specification
identified by <c><anno>Id</anno></c> does not exist, the function
returns <c>{error,not_found}</c>.</p>
</desc>
@@ -410,10 +466,10 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<p>Tells the supervisor <c><anno>SupRef</anno></c> to restart
a child process corresponding to the child specification
identified by <c><anno>Id</anno></c>. The child
- specification must exist and the corresponding child process
+ specification must exist, and the corresponding child process
must not be running.</p>
<p>Note that for temporary children, the child specification
- is automatically deleted when the child terminates, and thus
+ is automatically deleted when the child terminates; thus
it is not possible to restart such children.</p>
<p>See <seealso marker="#SupRef"><c>start_child/2</c></seealso>
for a description of <c>SupRef</c>.</p>
@@ -429,7 +485,7 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
is added to the supervisor and the function returns the same
value.</p>
<p>If the child process start function returns <c>ignore</c>,
- the pid remains set to <c>undefined</c> and the function
+ the pid remains set to <c>undefined</c>, and the function
returns <c>{ok,undefined}</c>.</p>
<p>If the child process start function returns an error tuple
or an erroneous value, or if it fails, the function returns
@@ -462,7 +518,7 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<item>
<p><c><anno>Child</anno></c> - the pid of the corresponding child
process, the atom <c>restarting</c> if the process is about to be
- restarted or <c>undefined</c> if there is no such process.</p>
+ restarted, or <c>undefined</c> if there is no such process.</p>
</item>
<item>
<p><c><anno>Type</anno></c> - as defined in the child specification.</p>
@@ -475,8 +531,8 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
</func>
<func>
<name name="count_children" arity="1"/>
- <fsummary>Return counts for the number of childspecs, active children,
- supervisors and workers.</fsummary>
+ <fsummary>Return counts for the number of child specifications,
+ active children, supervisors, and workers.</fsummary>
<desc>
<p>Returns a property list (see <c>proplists</c>) containing the
counts for each of the following elements of the supervisor's
@@ -487,7 +543,10 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
</item>
<item>
<p><c>active</c> - the count of all actively running child processes
- managed by this supervisor.</p>
+ managed by this supervisor. In the case of <c>simple_one_for_one</c>
+ supervisors, no check is carried out to ensure that each child process
+ is still alive, though the result provided here is likely to be very
+ accurate unless the supervisor is heavily overloaded.</p>
</item>
<item>
<p><c>supervisors</c> - the count of all children marked as
@@ -500,6 +559,8 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
process is still alive.</p>
</item>
</list>
+ <p>See <seealso marker="#SupRef"><c>start_child/2</c></seealso>
+ for a description of <c><anno>SupRef</anno></c>.</p>
</desc>
</func>
<func>
@@ -511,11 +572,23 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
correct, or <c>{error,<anno>Error</anno>}</c> otherwise.</p>
</desc>
</func>
+ <func>
+ <name name="get_childspec" arity="2"/>
+ <fsummary>Return the child specification map for the given
+ child.</fsummary>
+ <desc>
+ <p>Returns the child specification map for the child identified
+ by <c>Id</c> under supervisor <c>SupRef</c>. The returned
+ map contains all keys, both mandatory and optional.</p>
+ <p>See <seealso marker="#SupRef"><c>start_child/2</c></seealso>
+ for a description of <c><anno>SupRef</anno></c>.</p>
+ </desc>
+ </func>
</funcs>
<section>
<title>CALLBACK FUNCTIONS</title>
- <p>The following functions should be exported from a
+ <p>The following functions must be exported from a
<c>supervisor</c> callback module.</p>
</section>
<funcs>
@@ -524,33 +597,37 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<fsummary>Return a supervisor specification.</fsummary>
<type>
<v>Args = term()</v>
- <v>Result = {ok,{{RestartStrategy,MaxR,MaxT},[ChildSpec]}} | ignore</v>
- <v>&nbsp;RestartStrategy = <seealso marker="#type-strategy">strategy()</seealso></v>
- <v>&nbsp;MaxR = integer()>=0</v>
- <v>&nbsp;MaxT = integer()>0</v>
+ <v>Result = {ok,{SupFlags,[ChildSpec]}} | ignore</v>
+ <v>&nbsp;SupFlags = <seealso marker="#type-sup_flags">sup_flags()</seealso></v>
<v>&nbsp;ChildSpec = <seealso marker="#type-child_spec">child_spec()</seealso></v>
</type>
<desc>
<p>Whenever a supervisor is started using
<c>supervisor:start_link/2,3</c>, this function is called by
the new process to find out about restart strategy, maximum
- restart frequency and child specifications.</p>
+ restart intensity, and child specifications.</p>
<p><c>Args</c> is the <c>Args</c> argument provided to the start
function.</p>
- <p><c>RestartStrategy</c> is the restart strategy and
- <c>MaxR</c> and <c>MaxT</c> defines the maximum restart
- frequency of the supervisor. <c>[ChildSpec]</c> is a list of
- valid child specifications defining which child processes
- the supervisor should start and monitor. See the discussion
- about Supervision Principles above.</p>
+ <p><c>SupFlags</c> is the supervisor flags defining the
+ restart strategy and max restart intensity for the
+ supervisor. <c>[ChildSpec]</c> is a list of valid child
+ specifications defining which child processes the supervisor
+ shall start and monitor. See the discussion about
+ Supervision Principles above.</p>
<p>Note that when the restart strategy is
<c>simple_one_for_one</c>, the list of child specifications
must be a list with one child specification only.
- (The <c>Id</c> is ignored). No child process is then started
+ (The child specification identifier is ignored.) No child process is then started
during the initialization phase, but all children are assumed
to be started dynamically using
<c>supervisor:start_child/2</c>.</p>
<p>The function may also return <c>ignore</c>.</p>
+ <p>Note that this function might also be called as a part of a
+ code upgrade procedure. For this reason, the function should
+ not have any side effects. See
+ <seealso marker="doc/design_principles:appup_cookbook#sup">Design
+ Principles</seealso> for more information about code upgrade
+ of supervisors.</p>
</desc>
</func>
</funcs>
diff --git a/lib/stdlib/doc/src/supervisor_bridge.xml b/lib/stdlib/doc/src/supervisor_bridge.xml
index d16b258b6c..d356b4b57e 100644
--- a/lib/stdlib/doc/src/supervisor_bridge.xml
+++ b/lib/stdlib/doc/src/supervisor_bridge.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml
index 19605f325b..d400f72e1d 100644
--- a/lib/stdlib/doc/src/sys.xml
+++ b/lib/stdlib/doc/src/sys.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -237,8 +238,8 @@
<p>These functions are intended only to help with debugging. They are provided for
convenience, allowing developers to avoid having to create their own state extraction
functions and also avoid having to interactively extract state from the return values of
- <c><seealso marker="#get_status-1">get_status/1</seealso></c> or
- <c><seealso marker="#get_status-2">get_status/2</seealso></c> while debugging.</p>
+ <seealso marker="#get_status-1"><c>get_status/1</c></seealso> or
+ <seealso marker="#get_status-2"><c>get_status/2</c></seealso> while debugging.</p>
</note>
<p>The value of <c><anno>State</anno></c> varies for different types of
processes. For a <c>gen_server</c> process, the returned <c><anno>State</anno></c>
@@ -359,6 +360,17 @@
installed.</p>
</desc>
</func>
+ <func>
+ <name name="terminate" arity="2"/>
+ <name name="terminate" arity="3"/>
+ <fsummary>Terminate the process</fsummary>
+ <desc>
+ <p>This function orders the process to terminate with the
+ given <c><anno>Reason</anno></c>. The termination is done
+ asynchronously, so there is no guarantee that the process is
+ actually terminated when the function returns.</p>
+ </desc>
+ </func>
</funcs>
<section>
diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml
index eca9a72d36..7609487300 100644
--- a/lib/stdlib/doc/src/timer.xml
+++ b/lib/stdlib/doc/src/timer.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -84,7 +85,6 @@
<name name="send_after" arity="3"/>
<fsummary>Send <c>Message</c>to <c>Pid</c>after a specified <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>send_after/3</c></tag>
<item>
@@ -98,7 +98,6 @@
<p>Same as <c>send_after(<anno>Time</anno>, self(), <anno>Message</anno>)</c>.</p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -108,7 +107,6 @@
<name name="exit_after" arity="3"/>
<fsummary>Send an exit signal with <c>Reason</c>after a specified <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>exit_after/3</c></tag>
<item>
@@ -129,7 +127,6 @@
<p>Same as <c>exit_after(<anno>Time</anno>, self(), kill)</c>. </p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -146,7 +143,6 @@
<name name="send_interval" arity="3"/>
<fsummary>Send <c>Message</c>repeatedly at intervals of <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>send_interval/3</c></tag>
<item>
@@ -160,7 +156,6 @@
<p>Same as <c>send_interval(<anno>Time</anno>, self(), <anno>Message</anno>)</c>.</p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -191,7 +186,6 @@
Function, Arguments)</c> or <c>apply(Fun, Arguments)</c></fsummary>
<type_desc variable="Time">In microseconds</type_desc>
<desc>
- <p>
<taglist>
<tag><c>tc/3</c></tag>
<item>
@@ -212,17 +206,18 @@
</item>
</taglist>
- </p>
</desc>
</func>
<func>
<name name="now_diff" arity="2"/>
- <fsummary>Calculate time difference between <c>now/0</c>timestamps</fsummary>
+ <fsummary>Calculate time difference between timestamps</fsummary>
<type_desc variable="Tdiff">In microseconds</type_desc>
<desc>
<p>Calculates the time difference <c><anno>Tdiff</anno> = <anno>T2</anno> - <anno>T1</anno></c> in
- <em>microseconds</em>, where <c><anno>T1</anno></c> and <c><anno>T2</anno></c> probably
- are timestamp tuples returned from <c>erlang:now/0</c>.</p>
+ <em>microseconds</em>, where <c><anno>T1</anno></c> and <c><anno>T2</anno></c>
+ are timestamp tuples on the same format as returned from
+ <seealso marker="erts:erlang#timestamp/0"><c>erlang:timestamp/0</c></seealso>,
+ or <seealso marker="kernel:os#timestamp/0"><c>os:timestamp/0</c></seealso>.</p>
</desc>
</func>
<func>
@@ -234,7 +229,7 @@
</func>
<func>
<name name="minutes" arity="1"/>
- <fsummary>Converts <c>Minutes</c>to <c>Milliseconds</c>.</fsummary>
+ <fsummary>Converts <c>Minutes</c> to <c>Milliseconds</c>.</fsummary>
<desc>
<p>Return the number of milliseconds in <c><anno>Minutes</anno></c>.</p>
</desc>
diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index 6f8a289432..966eec49f5 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -132,7 +133,7 @@
<c>latin1</c>, or have characters encoded as one of the
UTF-encodings, which is given as the <c><anno>InEncoding</anno></c>
parameter. Only when the <c><anno>InEncoding</anno></c> is one of the UTF
- encodings, integers in the list are allowed to be grater than
+ encodings, integers in the list are allowed to be greater than
255.</p>
<p>If <c><anno>InEncoding</anno></c> is <c>latin1</c>, the <c><anno>Data</anno></c> parameter
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index 29b8940c62..c4cb193b07 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -850,8 +851,9 @@ Eshell V5.10.1 (abort with ^G)
expected to be in Unicode.</p>
<p>If Unicode file names are enabled, the calls to
<seealso marker="kernel:os#getenv/0"><c>os:getenv/0</c></seealso>,
- <seealso marker="kernel:os#getenv/1"><c>os:getenv/1</c></seealso> and
- <seealso marker="kernel:os#putenv/2"><c>os:putenv/2</c></seealso>
+ <seealso marker="kernel:os#getenv/1"><c>os:getenv/1</c></seealso>,
+ <seealso marker="kernel:os#putenv/2"><c>os:putenv/2</c></seealso> and
+ <seealso marker="kernel:os#unsetenv/1"><c>os:unsetenv/1</c></seealso>
will handle Unicode strings. On Unix-like platforms, the built-in
functions will translate environment variables in UTF-8 to/from
Unicode strings, possibly with code points > 255. On Windows the
diff --git a/lib/stdlib/doc/src/win32reg.xml b/lib/stdlib/doc/src/win32reg.xml
index 8835f931b2..2a5a4a462d 100644
--- a/lib/stdlib/doc/src/win32reg.xml
+++ b/lib/stdlib/doc/src/win32reg.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml
index 48b376743d..186c8ac724 100644
--- a/lib/stdlib/doc/src/zip.xml
+++ b/lib/stdlib/doc/src/zip.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -125,7 +126,7 @@
</datatype>
<datatype>
<name name="filename"/>
- <p>The name of a zip file.</p>
+ <desc><p>The name of a zip file.</p></desc>
</datatype>
<datatype><name name="extension"/></datatype>
<datatype><name name="extension_spec"/></datatype>
@@ -135,6 +136,12 @@
<p>These options are described in <seealso marker="#zip_options">create/3</seealso>.</p>
</desc>
</datatype>
+ <datatype>
+ <name name="handle"/>
+ <desc>
+ <p>As returned by <seealso marker="#zip_open/2">zip_open/2</seealso>.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
@@ -430,6 +437,8 @@
means that subsequently reading files from the archive will be
faster than unzipping files one at a time with <c>unzip</c>.</p>
<p>The archive must be closed with <c>zip_close/1</c>.</p>
+ <p>The <c><anno>ZipHandle</anno></c> will be closed if the
+ process which originally opened the archive dies.</p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/examples/Makefile b/lib/stdlib/examples/Makefile
index 198aceb3a9..743ea87179 100644
--- a/lib/stdlib/examples/Makefile
+++ b/lib/stdlib/examples/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/stdlib/examples/erl_id_trans.erl b/lib/stdlib/examples/erl_id_trans.erl
index e71e26e51a..529ae30862 100644
--- a/lib/stdlib/examples/erl_id_trans.erl
+++ b/lib/stdlib/examples/erl_id_trans.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/stdlib/include/assert.hrl b/lib/stdlib/include/assert.hrl
new file mode 100644
index 0000000000..f913760102
--- /dev/null
+++ b/lib/stdlib/include/assert.hrl
@@ -0,0 +1,261 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright (C) 2004-2014 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
+%%
+%% 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(ASSERT_HRL).
+-define(ASSERT_HRL, true).
+
+%% Asserts are enabled unless NOASSERT is defined, and ASSERT can be used to
+%% override it: if both ASSERT and NOASSERT are defined, then ASSERT takes
+%% precedence, and NOASSERT will become undefined.
+%%
+%% Furthermore, if NODEBUG is defined, it implies NOASSERT, unless DEBUG or
+%% ASSERT are defined.
+%%
+%% If asserts are disabled, all assert macros are defined to be the atom
+%% 'ok'. If asserts are enabled, all assert macros are defined to yield 'ok'
+%% as the result if the test succeeds, and raise an error exception if the
+%% test fails. The error term will then have the form {Name, Info} where
+%% Name is the name of the macro and Info is a list of tagged tuples.
+
+%% allow NODEBUG to imply NOASSERT, unless DEBUG
+-ifdef(NODEBUG).
+-ifndef(DEBUG).
+-ifndef(NOASSERT).
+-define(NOASSERT, true).
+-endif.
+-endif.
+-endif.
+
+%% allow ASSERT to override NOASSERT
+-ifdef(ASSERT).
+-undef(NOASSERT).
+-endif.
+
+%% Assert macros must not depend on any non-kernel or stdlib libraries.
+%%
+%% We must use fun-call wrappers ((fun () -> ... end)()) to avoid
+%% exporting local variables, and furthermore we only use variable names
+%% prefixed with "__", that hopefully will not be bound outside the fun.
+%% It is not possible to nest assert macros.
+
+-ifdef(NOASSERT).
+-define(assert(BoolExpr),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.
+-define(assert(BoolExpr),
+ begin
+ ((fun () ->
+ case (BoolExpr) of
+ true -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??BoolExpr)},
+ {expected, true},
+ case __V of false -> {value, __V};
+ _ -> {not_boolean,__V}
+ end]})
+ end
+ end)())
+ end).
+-endif.
+
+%% This is the inverse case of assert, for convenience.
+-ifdef(NOASSERT).
+-define(assertNot(BoolExpr),ok).
+-else.
+-define(assertNot(BoolExpr),
+ begin
+ ((fun () ->
+ case (BoolExpr) of
+ false -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??BoolExpr)},
+ {expected, false},
+ case __V of true -> {value, __V};
+ _ -> {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).
+-else.
+-define(assertMatch(Guard, Expr),
+ begin
+ ((fun () ->
+ case (Expr) of
+ Guard -> ok;
+ __V -> erlang:error({assertMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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).
+-else.
+-define(assertNotMatch(Guard, Expr),
+ begin
+ ((fun () ->
+ __V = (Expr),
+ case __V of
+ Guard -> erlang:error({assertNotMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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).
+-else.
+-define(assertEqual(Expect, Expr),
+ begin
+ ((fun (__X) ->
+ case (Expr) of
+ __X -> ok;
+ __V -> erlang:error({assertEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {expected, __X},
+ {value, __V}]})
+ end
+ end)(Expect))
+ end).
+-endif.
+
+%% This is the inverse case of assertEqual, for convenience.
+-ifdef(NOASSERT).
+-define(assertNotEqual(Unexpected, Expr), ok).
+-else.
+-define(assertNotEqual(Unexpected, Expr),
+ begin
+ ((fun (__X) ->
+ case (Expr) of
+ __X -> erlang:error({assertNotEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {value, __X}]});
+ _ -> ok
+ end
+ end)(Unexpected))
+ 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).
+-else.
+-define(assertException(Class, Term, Expr),
+ begin
+ ((fun () ->
+ try (Expr) of
+ __V -> erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_success, __V}]})
+ catch
+ Class:Term -> ok;
+ __C:__T ->
+ erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
+-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
+
+%% 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).
+-else.
+-define(assertNotException(Class, Term, Expr),
+ begin
+ ((fun () ->
+ try (Expr) of
+ _ -> ok
+ catch
+ __C:__T ->
+ case __C of
+ Class ->
+ case __T of
+ Term ->
+ erlang:error({assertNotException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {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/include/erl_bits.hrl b/lib/stdlib/include/erl_bits.hrl
index 54ebe58585..8405a55d55 100644
--- a/lib/stdlib/include/erl_bits.hrl
+++ b/lib/stdlib/include/erl_bits.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/include/erl_compile.hrl b/lib/stdlib/include/erl_compile.hrl
index f779c4382c..c5fb491308 100644
--- a/lib/stdlib/include/erl_compile.hrl
+++ b/lib/stdlib/include/erl_compile.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/include/ms_transform.hrl b/lib/stdlib/include/ms_transform.hrl
index 9937d48fef..f8a2d35394 100644
--- a/lib/stdlib/include/ms_transform.hrl
+++ b/lib/stdlib/include/ms_transform.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/include/qlc.hrl b/lib/stdlib/include/qlc.hrl
index 067fb83060..e3513314a0 100644
--- a/lib/stdlib/include/qlc.hrl
+++ b/lib/stdlib/include/qlc.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/include/zip.hrl b/lib/stdlib/include/zip.hrl
index 6e3ed9c78a..5f5abf9df3 100644
--- a/lib/stdlib/include/zip.hrl
+++ b/lib/stdlib/include/zip.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 9ab2cd4134..9f4a446ea0 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2013. All Rights Reserved.
+# Copyright Ericsson AB 1996-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -58,6 +59,7 @@ MODULES= \
edlin \
edlin_expand \
epp \
+ erl_anno \
erl_bits \
erl_compile \
erl_eval \
@@ -97,7 +99,6 @@ MODULES= \
otp_internal \
orddict \
ordsets \
- pg \
re \
pool \
proc_lib \
@@ -105,6 +106,7 @@ MODULES= \
qlc \
qlc_pt \
queue \
+ rand \
random \
sets \
shell \
@@ -121,6 +123,7 @@ MODULES= \
zip
HRL_FILES= \
+ ../include/assert.hrl \
../include/erl_compile.hrl \
../include/erl_bits.hrl \
../include/ms_transform.hrl \
@@ -169,6 +172,7 @@ docs:
# specifications.
primary_bootstrap_compiler: \
$(BOOTSTRAP_COMPILER)/ebin/epp.beam \
+ $(BOOTSTRAP_COMPILER)/ebin/erl_anno.beam \
$(BOOTSTRAP_COMPILER)/ebin/erl_scan.beam \
$(BOOTSTRAP_COMPILER)/ebin/erl_parse.beam \
$(BOOTSTRAP_COMPILER)/ebin/erl_lint.beam \
diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl
index 10d2ccea45..c749dd008b 100644
--- a/lib/stdlib/src/array.erl
+++ b/lib/stdlib/src/array.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -164,7 +165,7 @@
elements :: elements(_) %% the tuple tree
}).
--opaque array() :: array(term()).
+-type array() :: array(term()).
-opaque array(Type) ::
#array{default :: Type, elements :: elements(Type)}.
diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl
index 7bf281bd8a..ac532f7ee0 100644
--- a/lib/stdlib/src/base64.erl
+++ b/lib/stdlib/src/base64.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index 1a7b7d5a5e..503a2b416f 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -307,6 +308,17 @@ make_crypto_key(des3_cbc=Type, String) ->
<<K3:8/binary,IVec:8/binary>> = erlang:md5([First|reverse(String)]),
{Type,[K1,K2,K3],IVec,8}.
+-spec build_module(Chunks) -> {'ok', Binary} when
+ Chunks :: [{chunkid(), dataB()}],
+ Binary :: binary().
+
+build_module(Chunks0) ->
+ Chunks = list_to_binary(build_chunks(Chunks0)),
+ Size = byte_size(Chunks),
+ 0 = Size rem 4, % Assertion: correct padding?
+ {ok, <<"FOR1", (Size+4):32, "BEAM", Chunks/binary>>}.
+
+
%%
%% Local functions
%%
@@ -418,12 +430,6 @@ strip_file(File) ->
end
end.
-build_module(Chunks0) ->
- Chunks = list_to_binary(build_chunks(Chunks0)),
- Size = byte_size(Chunks),
- 0 = Size rem 4, % Assertion: correct padding?
- {ok, <<"FOR1", (Size+4):32, "BEAM", Chunks/binary>>}.
-
build_chunks([{Id, Data} | Chunks]) ->
BId = list_to_binary(Id),
Size = byte_size(Data),
@@ -652,7 +658,13 @@ chunk_to_data(abstract_code=Id, Chunk, File, _Cs, AtomTable, Mod) ->
{'EXIT', _} ->
error({invalid_chunk, File, chunk_name_to_id(Id, File)});
Term ->
- {AtomTable, {Id, Term}}
+ try
+ {AtomTable, {Id, anno_from_term(Term)}}
+ catch
+ _:_ ->
+ error({invalid_chunk, File,
+ chunk_name_to_id(Id, File)})
+ end
end
end;
chunk_to_data(atoms=Id, _Chunk, _File, Cs, AtomTable0, _Mod) ->
@@ -878,7 +890,22 @@ decrypt_abst(Type, Module, File, Id, AtomTable, Bin) ->
decrypt_abst_1({Type,Key,IVec,_BlockSize}, Bin) ->
ok = start_crypto(),
NewBin = crypto:block_decrypt(Type, Key, IVec, Bin),
- binary_to_term(NewBin).
+ Term = binary_to_term(NewBin),
+ anno_from_term(Term).
+
+anno_from_term({raw_abstract_v1, Forms}) ->
+ {raw_abstract_v1, anno_from_forms(Forms)};
+anno_from_term({Tag, Forms}) when Tag =:= abstract_v1; Tag =:= abstract_v2 ->
+ try {Tag, anno_from_forms(Forms)}
+ catch
+ _:_ ->
+ {Tag, Forms}
+ end;
+anno_from_term(T) ->
+ T.
+
+anno_from_forms(Forms) ->
+ [erl_parse:anno_from_term(Form) || Form <- Forms].
start_crypto() ->
case crypto:start() of
@@ -904,7 +931,10 @@ call_crypto_server(Req) ->
end.
call_crypto_server_1(Req) ->
- {ok, _} = gen_server:start({local,?CRYPTO_KEY_SERVER}, ?MODULE, [], []),
+ case gen_server:start({local,?CRYPTO_KEY_SERVER}, ?MODULE, [], []) of
+ {ok, _} -> ok;
+ {error, {already_started, _}} -> ok
+ end,
erlang:yield(),
call_crypto_server(Req).
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
index 8d07a356dd..af00410572 100644
--- a/lib/stdlib/src/binary.erl
+++ b/lib/stdlib/src/binary.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -215,12 +216,13 @@ split(H,N) ->
Subject :: binary(),
Pattern :: binary() | [binary()] | cp(),
Options :: [Option],
- Option :: {scope, part()} | trim | global,
+ Option :: {scope, part()} | trim | global | trim_all,
Parts :: [binary()].
split(Haystack,Needles,Options) ->
try
- {Part,Global,Trim} = get_opts_split(Options,{no,false,false}),
+ {Part,Global,Trim,TrimAll} =
+ get_opts_split(Options,{no,false,false,false}),
Moptlist = case Part of
no ->
[];
@@ -236,20 +238,24 @@ split(Haystack,Needles,Options) ->
Match -> [Match]
end
end,
- do_split(Haystack,MList,0,Trim)
+ do_split(Haystack,MList,0,Trim,TrimAll)
catch
_:_ ->
erlang:error(badarg)
end.
-do_split(H,[],N,true) when N >= byte_size(H) ->
+do_split(H,[],N,true,_) when N >= byte_size(H) ->
+ [];
+do_split(H,[],N,_,true) when N >= byte_size(H) ->
[];
-do_split(H,[],N,_) ->
+do_split(H,[],N,_,_) ->
[binary:part(H,{N,byte_size(H)-N})];
-do_split(H,[{A,B}|T],N,Trim) ->
+do_split(H,[{A,B}|T],N,Trim,TrimAll) ->
case binary:part(H,{N,A-N}) of
+ <<>> when TrimAll == true ->
+ do_split(H,T,A+B,Trim,TrimAll);
<<>> ->
- Rest = do_split(H,T,A+B,Trim),
+ Rest = do_split(H,T,A+B,Trim,TrimAll),
case {Trim, Rest} of
{true,[]} ->
[];
@@ -257,7 +263,7 @@ do_split(H,[{A,B}|T],N,Trim) ->
[<<>> | Rest]
end;
Oth ->
- [Oth | do_split(H,T,A+B,Trim)]
+ [Oth | do_split(H,T,A+B,Trim,TrimAll)]
end.
@@ -346,14 +352,16 @@ splitat(H,N,[I|T]) ->
%% Simple helper functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-get_opts_split([],{Part,Global,Trim}) ->
- {Part,Global,Trim};
-get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim}) ->
- get_opts_split(T,{{A,B},Global,Trim});
-get_opts_split([global | T],{Part,_Global,Trim}) ->
- get_opts_split(T,{Part,true,Trim});
-get_opts_split([trim | T],{Part,Global,_Trim}) ->
- get_opts_split(T,{Part,Global,true});
+get_opts_split([],{Part,Global,Trim,TrimAll}) ->
+ {Part,Global,Trim,TrimAll};
+get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim,TrimAll}) ->
+ get_opts_split(T,{{A,B},Global,Trim,TrimAll});
+get_opts_split([global | T],{Part,_Global,Trim,TrimAll}) ->
+ get_opts_split(T,{Part,true,Trim,TrimAll});
+get_opts_split([trim | T],{Part,Global,_Trim,TrimAll}) ->
+ get_opts_split(T,{Part,Global,true,TrimAll});
+get_opts_split([trim_all | T],{Part,Global,Trim,_TrimAll}) ->
+ get_opts_split(T,{Part,Global,Trim,true});
get_opts_split(_,_) ->
throw(badopt).
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index 9860adf04d..a8844d757d 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,7 +28,7 @@
lc_batch/0, lc_batch/1,
i/3,pid/3,m/0,m/1,
bt/1, q/0,
- erlangrc/0,erlangrc/1,bi/1, flush/0, regs/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]).
-export([display_info/1]).
@@ -65,6 +66,7 @@ help() ->
"q() -- quit - shorthand for init:stop()\n"
"regs() -- information about registered processes\n"
"nregs() -- information about all registered processes\n"
+ "uptime() -- print node uptime\n"
"xm(M) -- cross reference check a module\n"
"y(File) -- generate a Yecc parser\n">>).
@@ -774,6 +776,26 @@ memory() -> erlang:memory().
memory(TypeSpec) -> erlang:memory(TypeSpec).
%%
+%% uptime/0
+%%
+
+-spec uptime() -> 'ok'.
+
+uptime() ->
+ io:format("~s~n", [uptime(get_uptime())]).
+
+uptime({D, {H, M, S}}) ->
+ lists:flatten(
+ [[ io_lib:format("~p days, ", [D]) || D > 0 ],
+ [ io_lib:format("~p hours, ", [H]) || D+H > 0 ],
+ [ io_lib:format("~p minutes and ", [M]) || D+H+M > 0 ],
+ io_lib:format("~p seconds", [S])]).
+
+get_uptime() ->
+ {UpTime, _} = erlang:statistics(wall_clock),
+ calendar:seconds_to_daystime(UpTime div 1000).
+
+%%
%% Cross Reference Check
%%
%%-spec xm(module() | file:filename()) -> xref:m/1 return
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index 0320e0cd0e..074c504e00 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -299,7 +300,7 @@ local_time_to_universal_time_dst(DateTime) ->
%% now_to_universal_time(Now)
%% now_to_datetime(Now)
%%
-%% Convert from now() to UTC.
+%% Convert from erlang:timestamp() to UTC.
%%
%% Args: Now = now(); now() = {MegaSec, Sec, MilliSec}, MegaSec = Sec
%% = MilliSec = integer()
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index a4bd45ea19..2d037ff795 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -371,7 +372,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' | 'size' | 'type' | 'version',
+ | 'safe_fixed' | 'safe_fixed_monotonic_time' | 'size' | 'type' | 'version',
Value :: term().
info(Tab, owner) ->
@@ -1963,7 +1964,9 @@ do_safe_fixtable(Head, Pid, true) ->
case Head#head.fixed of
false ->
link(Pid),
- Fixed = {erlang:now(), [{Pid, 1}]},
+ MonTime = erlang:monotonic_time(),
+ TimeOffset = erlang:time_offset(),
+ Fixed = {{MonTime, TimeOffset}, [{Pid, 1}]},
Ftab = dets_utils:get_freelists(Head),
Head#head{fixed = Fixed, freelists = {Ftab, Ftab}};
{TimeStamp, Counters} ->
@@ -2090,7 +2093,22 @@ finfo(H, no_keys) ->
finfo(H, no_slots) -> {H, (H#head.mod):no_slots(H)};
finfo(H, pid) -> {H, self()};
finfo(H, ram_file) -> {H, H#head.ram_file};
-finfo(H, safe_fixed) -> {H, H#head.fixed};
+finfo(H, safe_fixed) ->
+ {H,
+ case H#head.fixed of
+ false ->
+ false;
+ {{FixMonTime, TimeOffset}, RefList} ->
+ {make_timestamp(FixMonTime, TimeOffset), RefList}
+ end};
+finfo(H, safe_fixed_monotonic_time) ->
+ {H,
+ case H#head.fixed of
+ false ->
+ false;
+ {{FixMonTime, _TimeOffset}, RefList} ->
+ {FixMonTime, RefList}
+ end};
finfo(H, size) ->
case catch write_cache(H) of
{H2, []} ->
@@ -3088,14 +3106,14 @@ update_cache(Head, ToAdd) ->
{Head1, Found, []};
Cache#cache.wrtime =:= undefined ->
%% Empty cache. Schedule a delayed write.
- Now = now(), Me = self(),
+ Now = time_now(), Me = self(),
Call = ?DETS_CALL(Me, {delayed_write, Now}),
erlang:send_after(Cache#cache.delay, Me, Call),
{Head1#head{cache = NewCache#cache{wrtime = Now}}, Found, []};
Size0 =:= 0 ->
%% Empty cache that has been written after the
%% currently scheduled delayed write.
- {Head1#head{cache = NewCache#cache{wrtime = now()}}, Found, []};
+ {Head1#head{cache = NewCache#cache{wrtime = time_now()}}, Found, []};
true ->
%% Cache is not empty, delayed write has been scheduled.
{Head1, Found, []}
@@ -3158,11 +3176,7 @@ delayed_write(Head, WrTime) ->
Head#head{cache = NewCache};
true ->
%% Yes, schedule a new delayed write.
- {MS1,S1,M1} = WrTime,
- {MS2,S2,M2} = LastWrTime,
- WrT = M1+1000000*(S1+1000000*MS1),
- LastWrT = M2+1000000*(S2+1000000*MS2),
- When = round((LastWrT - WrT)/1000), Me = self(),
+ When = round((LastWrTime - WrTime)/1000), Me = self(),
Call = ?DETS_CALL(Me, {delayed_write, LastWrTime}),
erlang:send_after(When, Me, Call),
Head
@@ -3274,6 +3288,19 @@ err(Error) ->
Error
end.
+-compile({inline, [time_now/0]}).
+time_now() ->
+ erlang:monotonic_time(1000000).
+
+make_timestamp(MonTime, TimeOffset) ->
+ ErlangSystemTime = erlang:convert_time_unit(MonTime+TimeOffset,
+ native,
+ micro_seconds),
+ MegaSecs = ErlangSystemTime div 1000000000000,
+ Secs = ErlangSystemTime div 1000000 - MegaSecs*1000000,
+ MicroSecs = ErlangSystemTime rem 1000000,
+ {MegaSecs, Secs, MicroSecs}.
+
%%%%%%%%%%%%%%%%% DEBUG functions %%%%%%%%%%%%%%%%
file_info(FileName) ->
diff --git a/lib/stdlib/src/dets.hrl b/lib/stdlib/src/dets.hrl
index a3f99357a2..be51e1a89c 100644
--- a/lib/stdlib/src/dets.hrl
+++ b/lib/stdlib/src/dets.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/dets_server.erl b/lib/stdlib/src/dets_server.erl
index 3164d40f35..e3c9447c6f 100644
--- a/lib/stdlib/src/dets_server.erl
+++ b/lib/stdlib/src/dets_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/dets_sup.erl b/lib/stdlib/src/dets_sup.erl
index 8ea2ba9b3f..e0087c58b4 100644
--- a/lib/stdlib/src/dets_sup.erl
+++ b/lib/stdlib/src/dets_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/src/dets_utils.erl b/lib/stdlib/src/dets_utils.erl
index 6c176ad513..34a8ddddaa 100644
--- a/lib/stdlib/src/dets_utils.erl
+++ b/lib/stdlib/src/dets_utils.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -447,7 +448,7 @@ reset_cache(C) ->
WrTime =:= undefined ->
WrTime;
true ->
- now()
+ erlang:monotonic_time(1000000)
end,
PK = family(C#cache.cache),
NewC = C#cache{cache = [], csize = 0, inserts = 0, wrtime = NewWrTime},
@@ -746,6 +747,8 @@ all_allocated([{X,Y} | L], _X0, Y0, A) when Y0 < X ->
all_allocated_as_list(Head) ->
all_allocated_as_list(all(get_freelists(Head)), 0, Head#head.base, []).
+-dialyzer({no_improper_lists, all_allocated_as_list/4}).
+
all_allocated_as_list([], _X0, _Y0, []) ->
[];
all_allocated_as_list([], _X0, _Y0, A) ->
diff --git a/lib/stdlib/src/dets_v8.erl b/lib/stdlib/src/dets_v8.erl
index f188502017..1bf53d91b1 100644
--- a/lib/stdlib/src/dets_v8.erl
+++ b/lib/stdlib/src/dets_v8.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -35,6 +36,8 @@
%% 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}]}).
diff --git a/lib/stdlib/src/dets_v9.erl b/lib/stdlib/src/dets_v9.erl
index 2af93ec800..6c406fc03a 100644
--- a/lib/stdlib/src/dets_v9.erl
+++ b/lib/stdlib/src/dets_v9.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -33,6 +34,8 @@
-export([cache_segps/3]).
+-dialyzer(no_improper_lists).
+
-compile({inline, [{max_objsize,1},{maxobjsize,1}]}).
-compile({inline, [{write_segment_file,6}]}).
-compile({inline, [{sz2pos,1},{adjsz,1}]}).
diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl
index cf8fb3114a..f921e28ef6 100644
--- a/lib/stdlib/src/dict.erl
+++ b/lib/stdlib/src/dict.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -70,7 +71,7 @@
}).
--opaque dict() :: dict(_, _).
+-type dict() :: dict(_, _).
-opaque dict(Key, Value) :: #dict{segs :: segs(Key, Value)}.
@@ -332,6 +333,8 @@ update_counter(Key, Incr, D0) when is_number(Incr) ->
D0, Slot),
maybe_expand(D1, Ic).
+-dialyzer({no_improper_lists, counter_bkt/3}).
+
counter_bkt(Key, I, [?kv(Key,Val)|Bkt]) ->
{[?kv(Key,Val+I)|Bkt],0};
counter_bkt(Key, I, [Other|Bkt0]) ->
@@ -417,6 +420,8 @@ on_bucket(F, T, Slot) ->
%% could have implemented map and filter using fold but these are
%% faster. We hope!
+fold_dict(F, Acc, #dict{size=0}) when is_function(F, 3) ->
+ Acc;
fold_dict(F, Acc, D) ->
Segs = D#dict.segs,
fold_segs(F, Acc, Segs, tuple_size(Segs)).
@@ -434,6 +439,8 @@ fold_bucket(F, Acc, [?kv(Key,Val)|Bkt]) ->
fold_bucket(F, F(Key, Val, Acc), Bkt);
fold_bucket(F, Acc, []) when is_function(F, 3) -> Acc.
+map_dict(F, #dict{size=0} = Dict) when is_function(F, 2) ->
+ Dict;
map_dict(F, D) ->
Segs0 = tuple_to_list(D#dict.segs),
Segs1 = map_seg_list(F, Segs0),
@@ -453,6 +460,8 @@ map_bucket(F, [?kv(Key,Val)|Bkt]) ->
[?kv(Key,F(Key, Val))|map_bucket(F, Bkt)];
map_bucket(F, []) when is_function(F, 2) -> [].
+filter_dict(F, #dict{size=0} = Dict) when is_function(F, 2) ->
+ Dict;
filter_dict(F, D) ->
Segs0 = tuple_to_list(D#dict.segs),
{Segs1,Fc} = filter_seg_list(F, Segs0, [], 0),
diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl
index 0c21271529..8a4df95027 100644
--- a/lib/stdlib/src/digraph.erl
+++ b/lib/stdlib/src/digraph.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -36,7 +37,7 @@
-export([get_short_path/3, get_short_cycle/2]).
--export_type([graph/0, d_type/0, vertex/0, edge/0]).
+-export_type([graph/0, d_type/0, vertex/0, edge/0, label/0]).
-record(digraph, {vtab = notable :: ets:tab(),
etab = notable :: ets:tab(),
@@ -337,6 +338,8 @@ edge(G, E) ->
%%
-spec new_edge_id(graph()) -> edge().
+-dialyzer({no_improper_lists, new_edge_id/1}).
+
new_edge_id(G) ->
NT = G#digraph.ntab,
[{'$eid', K}] = ets:lookup(NT, '$eid'),
@@ -349,6 +352,8 @@ new_edge_id(G) ->
%%
-spec new_vertex_id(graph()) -> vertex().
+-dialyzer({no_improper_lists, new_vertex_id/1}).
+
new_vertex_id(G) ->
NT = G#digraph.ntab,
[{'$vid', K}] = ets:lookup(NT, '$vid'),
diff --git a/lib/stdlib/src/digraph_utils.erl b/lib/stdlib/src/digraph_utils.erl
index 011bcd0260..ef4c2e94fe 100644
--- a/lib/stdlib/src/digraph_utils.erl
+++ b/lib/stdlib/src/digraph_utils.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index b3bc5f6d92..0e9c457de2 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -21,7 +22,7 @@
%% A simple Emacs-like line editor.
%% About Latin-1 characters: see the beginning of erl_scan.erl.
--export([init/0,start/1,start/2,edit_line/2,prefix_arg/1]).
+-export([init/0,init/1,start/1,start/2,edit_line/2,prefix_arg/1]).
-export([erase_line/1,erase_inp/1,redraw_line/1]).
-export([length_before/1,length_after/1,prompt/1]).
-export([current_line/1, current_chars/1]).
@@ -44,6 +45,20 @@
init() ->
put(kill_buffer, []).
+init(Pid) ->
+ %% copy the kill_buffer from the process Pid
+ CopiedKillBuf =
+ case erlang:process_info(Pid, dictionary) of
+ {dictionary,Dict} ->
+ case proplists:get_value(kill_buffer, Dict) of
+ undefined -> [];
+ Buf -> Buf
+ end;
+ undefined ->
+ []
+ end,
+ put(kill_buffer, CopiedKillBuf).
+
%% start(Prompt)
%% edit(Characters, Continuation)
%% Return
@@ -212,6 +227,8 @@ key_map($F, meta_o) -> end_of_line;
key_map($\177, none) -> backward_delete_char;
key_map($\177, meta) -> backward_kill_word;
key_map($[, meta) -> meta_left_sq_bracket;
+key_map($H, meta_left_sq_bracket) -> beginning_of_line;
+key_map($F, meta_left_sq_bracket) -> end_of_line;
key_map($D, meta_left_sq_bracket) -> backward_char;
key_map($C, meta_left_sq_bracket) -> forward_char;
% support a few <CTRL>+<CURSOR LEFT|RIGHT> combinations...
@@ -222,8 +239,10 @@ key_map($[, meta_meta) -> meta_csi;
key_map($C, meta_csi) -> forward_word;
key_map($D, meta_csi) -> backward_word;
key_map($1, meta_left_sq_bracket) -> {csi, "1"};
+key_map($3, meta_left_sq_bracket) -> {csi, "3"};
key_map($5, meta_left_sq_bracket) -> {csi, "5"};
key_map($5, {csi, "1;"}) -> {csi, "1;5"};
+key_map($~, {csi, "3"}) -> forward_delete_char;
key_map($C, {csi, "5"}) -> forward_word;
key_map($C, {csi, "1;5"}) -> forward_word;
key_map($D, {csi, "5"}) -> backward_word;
@@ -446,7 +465,6 @@ word_char(C) when C >= $a, C =< $z -> true;
word_char(C) when C >= $ß, C =< $ÿ, C =/= $÷ -> true;
word_char(C) when C >= $0, C =< $9 -> true;
word_char(C) when C =:= $_ -> true;
-word_char(C) when C =:= $. -> true; % accept dot-separated names
word_char(_) -> false.
%% over_white(Chars, InitialStack, InitialCount) ->
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl
index a2b4663219..6dd736da4c 100644
--- a/lib/stdlib/src/edlin_expand.erl
+++ b/lib/stdlib/src/edlin_expand.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 5f8637c118..d3124ac593 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -158,7 +159,7 @@ scan_erl_form(Epp) ->
{'ok', AbsForm} | {'eof', Line} | {error, ErrorInfo} when
Epp :: epp_handle(),
AbsForm :: erl_parse:abstract_form(),
- Line :: erl_scan:line(),
+ Line :: erl_anno:line(),
ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
parse_erl_form(Epp) ->
@@ -220,7 +221,7 @@ format_error(E) -> file:format_error(E).
IncludePath :: [DirectoryName :: file:name()],
Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line},
PredefMacros :: macros(),
- Line :: erl_scan:line(),
+ Line :: erl_anno:line(),
ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(),
OpenError :: file:posix() | badarg | system_limit.
@@ -235,7 +236,7 @@ parse_file(Ifile, Path, Predefs) ->
{'default_encoding', DefEncoding :: source_encoding()} |
'extra'],
Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line},
- Line :: erl_scan:line(),
+ Line :: erl_anno:line(),
ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(),
Extra :: [{'encoding', source_encoding() | 'none'}],
OpenError :: file:posix() | badarg | system_limit.
@@ -257,7 +258,7 @@ parse_file(Ifile, Options) ->
-spec parse_file(Epp) -> [Form] when
Epp :: epp_handle(),
Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line},
- Line :: erl_scan:line(),
+ Line :: erl_anno:line(),
ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
parse_file(Epp) ->
@@ -280,7 +281,7 @@ parse_file(Epp) ->
{error,E} ->
[{error,E}|parse_file(Epp)];
{eof,Location} ->
- [{eof,Location}]
+ [{eof,erl_anno:new(Location)}]
end.
-spec default_encoding() -> source_encoding().
@@ -547,7 +548,8 @@ init_server(Pid, Name, Options, St0) ->
path=Path, macs=Ms1,
default_encoding=DefEncoding},
From = wait_request(St),
- enter_file_reply(From, Name, AtLocation, AtLocation),
+ Anno = erl_anno:new(AtLocation),
+ enter_file_reply(From, Name, Anno, AtLocation, code),
wait_req_scan(St);
{error,E} ->
epp_reply(Pid, {error,E})
@@ -559,15 +561,16 @@ init_server(Pid, Name, Options, St0) ->
predef_macros(File) ->
Machine = list_to_atom(erlang:system_info(machine)),
+ Anno = line1(),
dict:from_list([
- {{atom,'FILE'}, {none,[{string,1,File}]}},
- {{atom,'LINE'}, {none,[{integer,1,1}]}},
+ {{atom,'FILE'}, {none,[{string,Anno,File}]}},
+ {{atom,'LINE'}, {none,[{integer,Anno,1}]}},
{{atom,'MODULE'}, undefined},
{{atom,'MODULE_STRING'}, undefined},
{{atom,'BASE_MODULE'}, undefined},
{{atom,'BASE_MODULE_STRING'}, undefined},
- {{atom,'MACHINE'}, {none,[{atom,1,Machine}]}},
- {{atom,Machine}, {none,[{atom,1,true}]}}
+ {{atom,'MACHINE'}, {none,[{atom,Anno,Machine}]}},
+ {{atom,Machine}, {none,[{atom,Anno,true}]}}
]).
%% user_predef(PreDefMacros, Macros) ->
@@ -595,8 +598,9 @@ user_predef([M|Pdm], Ms) when is_atom(M) ->
{ok,_Def} -> %% Predefined macros
{error,{redefine_predef,M}};
error ->
+ A = line1(),
user_predef(Pdm,
- dict:store({atom,M}, [{none, {none,[{atom,1,true}]}}], Ms))
+ dict:store({atom,M}, [{none, {none,[{atom,A,true}]}}], Ms))
end;
user_predef([Md|_Pdm], _Ms) -> {error,{bad,Md}};
user_predef([], Ms) -> {ok,Ms}.
@@ -645,7 +649,7 @@ wait_req_skip(St, Sis) ->
enter_file(_NewName, Inc, From, St)
when length(St#epp.sstk) >= 8 ->
- epp_reply(From, {error,{abs_loc(Inc),epp,{depth,"include"}}}),
+ epp_reply(From, {error,{loc(Inc),epp,{depth,"include"}}}),
wait_req_scan(St);
enter_file(NewName, Inc, From, St) ->
case file:path_open(St#epp.path, NewName, [read]) of
@@ -653,7 +657,7 @@ enter_file(NewName, Inc, From, St) ->
Loc = start_loc(St#epp.location),
wait_req_scan(enter_file2(NewF, Pname, From, St, Loc));
{error,_E} ->
- epp_reply(From, {error,{abs_loc(Inc),epp,{include,file,NewName}}}),
+ epp_reply(From, {error,{loc(Inc),epp,{include,file,NewName}}}),
wait_req_scan(St)
end.
@@ -661,9 +665,9 @@ enter_file(NewName, Inc, From, St) ->
%% Set epp to use this file and "enter" it.
enter_file2(NewF, Pname, From, St0, AtLocation) ->
- Loc = start_loc(AtLocation),
- enter_file_reply(From, Pname, Loc, AtLocation),
- Ms = dict:store({atom,'FILE'}, {none,[{string,Loc,Pname}]}, St0#epp.macs),
+ Anno = erl_anno:new(AtLocation),
+ enter_file_reply(From, Pname, Anno, AtLocation, code),
+ Ms = dict:store({atom,'FILE'}, {none,[{string,Anno,Pname}]}, St0#epp.macs),
%% update the head of the include path to be the directory of the new
%% source file, so that an included file can always include other files
%% relative to its current location (this is also how C does it); note
@@ -673,16 +677,20 @@ enter_file2(NewF, Pname, From, St0, AtLocation) ->
Path = [filename:dirname(Pname) | tl(St0#epp.path)],
DefEncoding = St0#epp.default_encoding,
_ = set_encoding(NewF, DefEncoding),
- #epp{file=NewF,location=Loc,name=Pname,name2=Pname,delta=0,
+ #epp{file=NewF,location=AtLocation,name=Pname,name2=Pname,delta=0,
sstk=[St0|St0#epp.sstk],path=Path,macs=Ms,
default_encoding=DefEncoding}.
-enter_file_reply(From, Name, Location, AtLocation) ->
- Attr = loc_attr(AtLocation),
- Rep = {ok, [{'-',Attr},{atom,Attr,file},{'(',Attr},
- {string,Attr,file_name(Name)},{',',Attr},
- {integer,Attr,get_line(Location)},{')',Location},
- {dot,Attr}]},
+enter_file_reply(From, Name, LocationAnno, AtLocation, Where) ->
+ Anno0 = loc_anno(AtLocation),
+ Anno = case Where of
+ code -> Anno0;
+ generated -> erl_anno:set_generated(true, Anno0)
+ end,
+ Rep = {ok, [{'-',Anno},{atom,Anno,file},{'(',Anno},
+ {string,Anno,file_name(Name)},{',',Anno},
+ {integer,Anno,get_line(LocationAnno)},{')',LocationAnno},
+ {dot,Anno}]},
epp_reply(From, Rep).
%% Flatten filename to a string. Must be a valid filename.
@@ -710,18 +718,20 @@ leave_file(From, St) ->
#epp{location=OldLoc, delta=Delta, name=OldName,
name2=OldName2} = OldSt,
CurrLoc = add_line(OldLoc, Delta),
+ Anno = erl_anno:new(CurrLoc),
Ms = dict:store({atom,'FILE'},
- {none,[{string,CurrLoc,OldName2}]},
+ {none,[{string,Anno,OldName2}]},
St#epp.macs),
NextSt = OldSt#epp{sstk=Sts,macs=Ms,uses=St#epp.uses},
- enter_file_reply(From, OldName, CurrLoc, CurrLoc),
+ enter_file_reply(From, OldName, Anno, CurrLoc, code),
case OldName2 =:= OldName of
true ->
ok;
false ->
NFrom = wait_request(NextSt),
- enter_file_reply(NFrom, OldName2, OldLoc,
- neg_line(CurrLoc))
+ OldAnno = erl_anno:new(OldLoc),
+ enter_file_reply(NFrom, OldName2, OldAnno,
+ CurrLoc, generated)
end,
wait_req_scan(NextSt);
[] ->
@@ -818,9 +828,9 @@ scan_extends(_Ts, _As, Ms) -> Ms.
%% scan_define(Tokens, DefineToken, From, EppState)
-scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',Lc}|Toks], _Def, From, St)
+scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',_}=Comma|Toks], _Def, From, St)
when Type =:= atom; Type =:= var ->
- case catch macro_expansion(Toks, Lc) of
+ case catch macro_expansion(Toks, Comma) of
Expansion when is_list(Expansion) ->
case dict:find({atom,M}, St#epp.macs) of
{ok, Defs} when is_list(Defs) ->
@@ -910,10 +920,12 @@ macro_ref([]) ->
[];
macro_ref([{'?', _}, {'?', _} | Rest]) ->
macro_ref(Rest);
-macro_ref([{'?', _}, {atom, Lm, A} | Rest]) ->
+macro_ref([{'?', _}, {atom, _, A}=Atom | Rest]) ->
+ Lm = loc(Atom),
Arity = count_args(Rest, Lm, A),
[{{atom, A}, Arity} | macro_ref(Rest)];
-macro_ref([{'?', _}, {var, Lm, A} | Rest]) ->
+macro_ref([{'?', _}, {var, _, A}=Var | Rest]) ->
+ Lm = loc(Var),
Arity = count_args(Rest, Lm, A),
[{{atom, A}, Arity} | macro_ref(Rest)];
macro_ref([_Token | Rest]) ->
@@ -940,7 +952,7 @@ scan_include([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], Inc,
NewName = expand_var(NewName0),
enter_file(NewName, Inc, From, St);
scan_include(_Toks, Inc, From, St) ->
- epp_reply(From, {error,{abs_loc(Inc),epp,{bad,include}}}),
+ epp_reply(From, {error,{loc(Inc),epp,{bad,include}}}),
wait_req_scan(St).
%% scan_include_lib(Tokens, IncludeToken, From, EppState)
@@ -955,7 +967,7 @@ find_lib_dir(NewName) ->
scan_include_lib([{'(',_Llp},{string,_Lf,_NewName0},{')',_Lrp},{dot,_Ld}],
Inc, From, St)
when length(St#epp.sstk) >= 8 ->
- epp_reply(From, {error,{abs_loc(Inc),epp,{depth,"include_lib"}}}),
+ epp_reply(From, {error,{loc(Inc),epp,{depth,"include_lib"}}}),
wait_req_scan(St);
scan_include_lib([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}],
Inc, From, St) ->
@@ -974,18 +986,18 @@ scan_include_lib([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}],
St, Loc));
{error,_E2} ->
epp_reply(From,
- {error,{abs_loc(Inc),epp,
+ {error,{loc(Inc),epp,
{include,lib,NewName}}}),
wait_req_scan(St)
end;
_Error ->
- epp_reply(From, {error,{abs_loc(Inc),epp,
+ epp_reply(From, {error,{loc(Inc),epp,
{include,lib,NewName}}}),
wait_req_scan(St)
end
end;
scan_include_lib(_Toks, Inc, From, St) ->
- epp_reply(From, {error,{abs_loc(Inc),epp,{bad,include_lib}}}),
+ epp_reply(From, {error,{loc(Inc),epp,{bad,include_lib}}}),
wait_req_scan(St).
%% scan_ifdef(Tokens, IfdefToken, From, EppState)
@@ -1088,11 +1100,12 @@ scan_endif(_Toks, Endif, From, St) ->
scan_file([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp},
{dot,_Ld}], Tf, From, St) ->
- enter_file_reply(From, Name, Ln, neg_line(abs_loc(Tf))),
- Ms = dict:store({atom,'FILE'}, {none,[{string,1,Name}]}, St#epp.macs),
+ Anno = erl_anno:new(Ln),
+ enter_file_reply(From, Name, Anno, loc(Tf), generated),
+ Ms = dict:store({atom,'FILE'}, {none,[{string,line1(),Name}]}, St#epp.macs),
Locf = loc(Tf),
NewLoc = new_location(Ln, St#epp.location, Locf),
- Delta = abs(get_line(element(2, Tf)))-Ln + St#epp.delta,
+ Delta = get_line(element(2, Tf))-Ln + St#epp.delta,
wait_req_scan(St#epp{name2=Name,location=NewLoc,delta=Delta,macs=Ms});
scan_file(_Toks, Tf, From, St) ->
epp_reply(From, {error,{loc(Tf),epp,{bad,file}}}),
@@ -1153,7 +1166,7 @@ skip_else(_Else, From, St, Sis) ->
skip_toks(From, St, Sis).
%% macro_pars(Tokens, ArgStack)
-%% macro_expansion(Tokens, Line)
+%% macro_expansion(Tokens, Anno)
%% Extract the macro parameters and the expansion from a macro definition.
macro_pars([{')',_Lp}, {',',Ld}|Ex], Args) ->
@@ -1165,11 +1178,12 @@ macro_pars([{var,_L,Name}, {',',_}|Ts], Args) ->
false = lists:member(Name, Args),
macro_pars(Ts, [Name|Args]).
-macro_expansion([{')',_Lp},{dot,_Ld}], _L0) -> [];
-macro_expansion([{dot,Ld}], _L0) -> throw({error,Ld,missing_parenthesis});
-macro_expansion([T|Ts], _L0) ->
- [T|macro_expansion(Ts, element(2, T))];
-macro_expansion([], L0) -> throw({error,L0,premature_end}).
+macro_expansion([{')',_Lp},{dot,_Ld}], _Anno0) -> [];
+macro_expansion([{dot,_}=Dot], _Anno0) ->
+ throw({error,loc(Dot),missing_parenthesis});
+macro_expansion([T|Ts], _Anno0) ->
+ [T|macro_expansion(Ts, T)];
+macro_expansion([], Anno0) -> throw({error,loc(Anno0),premature_end}).
%% expand_macros(Tokens, Macros)
%% expand_macro(Tokens, MacroToken, RestTokens)
@@ -1239,17 +1253,17 @@ expand_macros([{'?',_Lq},{atom,_Lm,M}=MacT|Toks], Ms) ->
expand_macros(atom, MacT, M, Toks, Ms);
%% Special macros
expand_macros([{'?',_Lq},{var,Lm,'LINE'}=Tok|Toks], Ms) ->
- {line,Line} = erl_scan:token_info(Tok, line),
+ Line = erl_scan:line(Tok),
[{integer,Lm,Line}|expand_macros(Toks, Ms)];
expand_macros([{'?',_Lq},{var,_Lm,M}=MacT|Toks], Ms) ->
expand_macros(atom, MacT, M, Toks, Ms);
%% Illegal macros
expand_macros([{'?',_Lq},Token|_Toks], _Ms) ->
- T = case erl_scan:token_info(Token, text) of
- {text,Text} ->
+ T = case erl_scan:text(Token) of
+ Text when is_list(Text) ->
Text;
undefined ->
- {symbol,Symbol} = erl_scan:token_info(Token, symbol),
+ Symbol = erl_scan:symbol(Token),
io_lib:write(Symbol)
end,
throw({error,loc(Token),{call,[$?|T]}});
@@ -1383,7 +1397,7 @@ expand_arg([], Ts, L, Rest, Bs) ->
%%% stringify(Ts, L) returns a list of one token: a string which when
%%% tokenized would yield the token list Ts.
-%% erl_scan:token_info(T, text) is not backward compatible with this.
+%% erl_scan:text(T) is not backward compatible with this.
%% Note that escaped characters will be replaced by themselves.
token_src({dot, _}) ->
".";
@@ -1456,36 +1470,29 @@ fname_join(Components) ->
filename:join(Components).
%% The line only. (Other tokens may have the column and text as well...)
-loc_attr(Line) when is_integer(Line) ->
- Line;
-loc_attr({Line,_Column}) ->
- Line.
+loc_anno(Line) when is_integer(Line) ->
+ erl_anno:new(Line);
+loc_anno({Line,_Column}) ->
+ erl_anno:new(Line).
loc(Token) ->
- {location,Location} = erl_scan:token_info(Token, location),
- Location.
-
-abs_loc(Token) ->
- loc(setelement(2, Token, abs_line(element(2, Token)))).
-
-neg_line(L) ->
- erl_scan:set_attribute(line, L, fun(Line) -> -abs(Line) end).
+ erl_scan:location(Token).
-abs_line(L) ->
- erl_scan:set_attribute(line, L, fun(Line) -> abs(Line) end).
-
-add_line(L, Offset) ->
- erl_scan:set_attribute(line, L, fun(Line) -> Line+Offset end).
+add_line(Line, Offset) when is_integer(Line) ->
+ Line+Offset;
+add_line({Line, Column}, Offset) ->
+ {Line+Offset, Column}.
start_loc(Line) when is_integer(Line) ->
1;
start_loc({_Line, _Column}) ->
- {1,1}.
+ {1, 1}.
+
+line1() ->
+ erl_anno:new(1).
-get_line(Line) when is_integer(Line) ->
- Line;
-get_line({Line,_Column}) ->
- Line.
+get_line(Anno) ->
+ erl_anno:line(Anno).
%% epp has always output -file attributes when entering and leaving
%% included files (-include, -include_lib). Starting with R11B the
@@ -1525,14 +1532,15 @@ get_line({Line,_Column}) ->
interpret_file_attribute(Forms) ->
interpret_file_attr(Forms, 0, []).
-interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms],
+interpret_file_attr([{attribute,Anno,file,{File,Line}}=Form | Forms],
Delta, Fs) ->
- {line, L} = erl_scan:attributes_info(Loc, line),
+ L = get_line(Anno),
+ Generated = erl_anno:generated(Anno),
if
- L < 0 ->
+ Generated ->
%% -file attribute
- interpret_file_attr(Forms, (abs(L) + Delta) - Line, Fs);
- true ->
+ interpret_file_attr(Forms, (L + Delta) - Line, Fs);
+ not Generated ->
%% -include or -include_lib
% true = L =:= Line,
case Fs of
@@ -1543,11 +1551,11 @@ interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms],
end
end;
interpret_file_attr([Form0 | Forms], Delta, Fs) ->
- F = fun(Attrs) ->
- F2 = fun(L) -> abs(L) + Delta end,
- erl_scan:set_attribute(line, Attrs, F2)
+ F = fun(Anno) ->
+ Line = erl_anno:line(Anno),
+ erl_anno:set_line(Line + Delta, Anno)
end,
- Form = erl_lint:modify_line(Form0, F),
+ Form = erl_parse:map_anno(F, Form0),
[Form | interpret_file_attr(Forms, Delta, Fs)];
interpret_file_attr([], _Delta, _Fs) ->
[].
diff --git a/lib/stdlib/src/erl_anno.erl b/lib/stdlib/src/erl_anno.erl
new file mode 100644
index 0000000000..143318aa55
--- /dev/null
+++ b/lib/stdlib/src/erl_anno.erl
@@ -0,0 +1,459 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(erl_anno).
+
+-export([new/1, is_anno/1]).
+-export([column/1, end_location/1, file/1, generated/1,
+ line/1, location/1, record/1, text/1]).
+-export([set_file/2, set_generated/2, set_line/2, set_location/2,
+ set_record/2, set_text/2]).
+
+%% To be used when necessary to avoid Dialyzer warnings.
+-export([to_term/1, from_term/1]).
+
+-export_type([anno/0, line/0, column/0, location/0, text/0]).
+
+-export_type([anno_term/0]).
+
+-define(LN(L), is_integer(L)).
+-define(COL(C), (is_integer(C) andalso C >= 1)).
+
+%% Location.
+-define(LCOLUMN(C), ?COL(C)).
+-define(LLINE(L), ?LN(L)).
+
+%% Debug: define DEBUG to make sure that annotations are handled as an
+%% opaque type. Note that all abstract code need to be compiled with
+%% DEBUG=true. See also ./erl_pp.erl.
+
+%-define(DEBUG, true).
+
+-type annotation() :: {'file', filename()}
+ | {'generated', generated()}
+ | {'location', location()}
+ | {'record', record()}
+ | {'text', string()}.
+
+-type anno() :: location() | [annotation(), ...].
+-type anno_term() :: term().
+
+-type column() :: pos_integer().
+-type generated() :: boolean().
+-type filename() :: file:filename_all().
+-type line() :: integer().
+-type location() :: line() | {line(), column()}.
+-type record() :: boolean().
+-type text() :: string().
+
+-ifdef(DEBUG).
+%% Anything 'false' accepted by the compiler.
+-define(ALINE(A), is_reference(A)).
+-define(ACOLUMN(A), is_reference(A)).
+-else.
+-define(ALINE(L), ?LN(L)).
+-define(ACOLUMN(C), ?COL(C)).
+-endif.
+
+-spec to_term(Anno) -> anno_term() when
+ Anno :: anno().
+
+-ifdef(DEBUG).
+to_term(Anno) ->
+ simplify(Anno).
+-else.
+to_term(Anno) ->
+ Anno.
+-endif.
+
+-spec from_term(Term) -> Anno when
+ Term :: anno_term(),
+ Anno :: anno().
+
+-ifdef(DEBUG).
+from_term(Term) when is_list(Term) ->
+ Term;
+from_term(Term) ->
+ [{location, Term}].
+-else.
+from_term(Term) ->
+ Term.
+-endif.
+
+-spec new(Location) -> anno() when
+ Location :: location().
+
+new(Line) when ?LLINE(Line) ->
+ new_location(Line);
+new({Line, Column}=Loc) when ?LLINE(Line), ?LCOLUMN(Column) ->
+ new_location(Loc);
+new(Term) ->
+ erlang:error(badarg, [Term]).
+
+-ifdef(DEBUG).
+new_location(Location) ->
+ [{location, Location}].
+-else.
+new_location(Location) ->
+ Location.
+-endif.
+
+-spec is_anno(Term) -> boolean() when
+ Term :: any().
+
+is_anno(Line) when ?ALINE(Line) ->
+ true;
+is_anno({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ true;
+is_anno(Anno) ->
+ (Anno =/= [] andalso
+ is_anno1(Anno) andalso
+ lists:keymember(location, 1, Anno)).
+
+is_anno1([{Item, Value}|Anno]) ->
+ is_anno2(Item, Value) andalso is_anno1(Anno);
+is_anno1(A) ->
+ A =:= [].
+
+is_anno2(location, Line) when ?LN(Line) ->
+ true;
+is_anno2(location, {Line, Column}) when ?LN(Line), ?COL(Column) ->
+ true;
+is_anno2(generated, true) ->
+ true;
+is_anno2(file, Filename) ->
+ is_filename(Filename);
+is_anno2(record, true) ->
+ true;
+is_anno2(text, Text) ->
+ is_string(Text);
+is_anno2(_, _) ->
+ false.
+
+is_filename(T) ->
+ is_list(T) orelse is_binary(T).
+
+is_string(T) ->
+ is_list(T).
+
+-spec column(Anno) -> column() | 'undefined' when
+ Anno :: anno().
+
+column({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ Column;
+column(Line) when ?ALINE(Line) ->
+ undefined;
+column(Anno) ->
+ case location(Anno) of
+ {_Line, Column} ->
+ Column;
+ _Line ->
+ undefined
+ end.
+
+-spec end_location(Anno) -> location() | 'undefined' when
+ Anno :: anno().
+
+end_location(Anno) ->
+ case text(Anno) of
+ undefined ->
+ undefined;
+ Text ->
+ case location(Anno) of
+ {Line, Column} ->
+ end_location(Text, Line, Column);
+ Line ->
+ end_location(Text, Line)
+ end
+ end.
+
+-spec file(Anno) -> filename() | 'undefined' when
+ Anno :: anno().
+
+file(Line) when ?ALINE(Line) ->
+ undefined;
+file({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ undefined;
+file(Anno) ->
+ anno_info(Anno, file).
+
+-spec generated(Anno) -> generated() when
+ Anno :: anno().
+
+generated(Line) when ?ALINE(Line) ->
+ Line =< 0;
+generated({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ Line =< 0;
+generated(Anno) ->
+ _ = anno_info(Anno, generated, false),
+ {location, Location} = lists:keyfind(location, 1, Anno),
+ case Location of
+ {Line, _Column} ->
+ Line =< 0;
+ Line ->
+ Line =< 0
+ end.
+
+-spec line(Anno) -> line() when
+ Anno :: anno().
+
+line(Anno) ->
+ case location(Anno) of
+ {Line, _Column} ->
+ Line;
+ Line ->
+ Line
+ end.
+
+-spec location(Anno) -> location() when
+ Anno :: anno().
+
+location(Line) when ?ALINE(Line) ->
+ abs(Line);
+location({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ {abs(Line), Column};
+location(Anno) ->
+ case anno_info(Anno, location) of
+ Line when Line < 0 ->
+ -Line;
+ {Line, Column} when Line < 0 ->
+ {-Line, Column};
+ Location ->
+ Location
+ end.
+
+-spec record(Anno) -> record() when
+ Anno :: anno().
+
+record(Line) when ?ALINE(Line) ->
+ false;
+record({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ false;
+record(Anno) ->
+ anno_info(Anno, record, false).
+
+-spec text(Anno) -> text() | 'undefined' when
+ Anno :: anno().
+
+text(Line) when ?ALINE(Line) ->
+ undefined;
+text({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) ->
+ undefined;
+text(Anno) ->
+ anno_info(Anno, text).
+
+-spec set_file(File, Anno) -> Anno when
+ File :: filename(),
+ Anno :: anno().
+
+set_file(File, Anno) ->
+ set(file, File, Anno).
+
+-spec set_generated(Generated, Anno) -> Anno when
+ Generated :: generated(),
+ Anno :: anno().
+
+set_generated(true, Line) when ?ALINE(Line) ->
+ -abs(Line);
+set_generated(false, Line) when ?ALINE(Line) ->
+ abs(Line);
+set_generated(true, {Line, Column}) when ?ALINE(Line),
+ ?ACOLUMN(Column) ->
+ {-abs(Line),Column};
+set_generated(false, {Line, Column}) when ?ALINE(Line),
+ ?ACOLUMN(Column) ->
+ {abs(Line),Column};
+set_generated(Generated, Anno) ->
+ _ = set(generated, Generated, Anno),
+ {location, Location} = lists:keyfind(location, 1, Anno),
+ NewLocation =
+ case Location of
+ {Line, Column} when Generated ->
+ {-abs(Line), Column};
+ {Line, Column} when not Generated ->
+ {abs(Line), Column};
+ Line when Generated ->
+ -abs(Line);
+ Line when not Generated ->
+ abs(Line)
+ end,
+ lists:keyreplace(location, 1, Anno, {location, NewLocation}).
+
+-spec set_line(Line, Anno) -> Anno when
+ Line :: line(),
+ Anno :: anno().
+
+set_line(Line, Anno) ->
+ case location(Anno) of
+ {_Line, Column} ->
+ set_location({Line, Column}, Anno);
+ _Line ->
+ set_location(Line, Anno)
+ end.
+
+-spec set_location(Location, Anno) -> Anno when
+ Location :: location(),
+ Anno :: anno().
+
+set_location(Line, L) when ?ALINE(L), ?LLINE(Line) ->
+ new_location(fix_line(Line, L));
+set_location(Line, {L, Column}) when ?ALINE(L), ?ACOLUMN(Column),
+ ?LLINE(Line) ->
+ new_location(fix_line(Line, L));
+set_location({L, C}=Loc, Line) when ?ALINE(Line), ?LLINE(L), ?LCOLUMN(C) ->
+ new_location(fix_location(Loc, Line));
+set_location({L, C}=Loc, {Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column),
+ ?LLINE(L), ?LCOLUMN(C) ->
+ new_location(fix_location(Loc, Line));
+set_location(Location, Anno) ->
+ _ = set(location, Location, Anno),
+ {location, OldLocation} = lists:keyfind(location, 1, Anno),
+ NewLocation =
+ case {Location, OldLocation} of
+ {{_Line, _Column}=Loc, {L, _C}} ->
+ fix_location(Loc, L);
+ {Line, {L, _C}} ->
+ fix_line(Line, L);
+ {{_Line, _Column}=Loc, L} ->
+ fix_location(Loc, L);
+ {Line, L} ->
+ fix_line(Line, L)
+ end,
+ lists:keyreplace(location, 1, Anno, {location, NewLocation}).
+
+fix_location({Line, Column}, OldLine) ->
+ {fix_line(Line, OldLine), Column}.
+
+fix_line(Line, OldLine) when OldLine < 0, Line > 0 ->
+ -Line;
+fix_line(Line, _OldLine) ->
+ Line.
+
+-spec set_record(Record, Anno) -> Anno when
+ Record :: record(),
+ Anno :: anno().
+
+set_record(Record, Anno) ->
+ set(record, Record, Anno).
+
+-spec set_text(Text, Anno) -> Anno when
+ Text :: text(),
+ Anno :: anno().
+
+set_text(Text, Anno) ->
+ set(text, Text, Anno).
+
+set(Item, Value, Anno) ->
+ case {is_settable(Item, Value), Anno} of
+ {true, Line} when ?ALINE(Line) ->
+ set_anno(Item, Value, [{location, Line}]);
+ {true, {L, C}=Location} when ?ALINE(L), ?ACOLUMN(C) ->
+ set_anno(Item, Value, [{location, Location}]);
+ {true, A} when is_list(A), A =/= [] ->
+ set_anno(Item, Value, Anno);
+ _ ->
+ erlang:error(badarg, [Item, Value, Anno])
+ end.
+
+set_anno(Item, Value, Anno) ->
+ case default(Item, Value) of
+ true ->
+ reset(Anno, Item);
+ false ->
+ R = case anno_info(Anno, Item) of
+ undefined ->
+ [{Item, Value}|Anno];
+ _ ->
+ lists:keyreplace(Item, 1, Anno, {Item, Value})
+ end,
+ simplify(R)
+ end.
+
+reset(Anno, Item) ->
+ A = lists:keydelete(Item, 1, Anno),
+ reset_simplify(A).
+
+-ifdef(DEBUG).
+reset_simplify(A) ->
+ A.
+-else.
+reset_simplify(A) ->
+ simplify(A).
+-endif.
+
+simplify([{location, Location}]) ->
+ Location;
+simplify(Anno) ->
+ Anno.
+
+anno_info(Anno, Item, Default) ->
+ try lists:keyfind(Item, 1, Anno) of
+ false ->
+ Default;
+ {Item, Value} ->
+ Value
+ catch
+ _:_ ->
+ erlang:error(badarg, [Anno])
+ end.
+
+anno_info(Anno, Item) ->
+ try lists:keyfind(Item, 1, Anno) of
+ {Item, Value} ->
+ Value;
+ false ->
+ undefined
+ catch
+ _:_ ->
+ erlang:error(badarg, [Anno])
+ end.
+
+end_location("", Line, Column) ->
+ {Line, Column};
+end_location([$\n|String], Line, _Column) ->
+ end_location(String, Line+1, 1);
+end_location([_|String], Line, Column) ->
+ end_location(String, Line, Column+1).
+
+end_location("", Line) ->
+ Line;
+end_location([$\n|String], Line) ->
+ end_location(String, Line+1);
+end_location([_|String], Line) ->
+ end_location(String, Line).
+
+is_settable(file, File) ->
+ is_filename(File);
+is_settable(generated, Boolean) when Boolean; not Boolean ->
+ true;
+is_settable(location, Line) when ?LLINE(Line) ->
+ true;
+is_settable(location, {Line, Column}) when ?LLINE(Line), ?LCOLUMN(Column) ->
+ true;
+is_settable(record, Boolean) when Boolean; not Boolean ->
+ true;
+is_settable(text, Text) ->
+ is_string(Text);
+is_settable(_, _) ->
+ false.
+
+default(generated, false) -> true;
+default(record, false) -> true;
+default(_, _) -> false.
diff --git a/lib/stdlib/src/erl_bits.erl b/lib/stdlib/src/erl_bits.erl
index 62f6d00fae..ddcfcfdf02 100644
--- a/lib/stdlib/src/erl_bits.erl
+++ b/lib/stdlib/src/erl_bits.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl
index caed4d41d6..5ca233cde7 100644
--- a/lib/stdlib/src/erl_compile.erl
+++ b/lib/stdlib/src/erl_compile.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 639ddfc214..40a34aa30f 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -246,18 +247,14 @@ expr({record,_,_,Name,_}, _Bs, _Lf, _Ef, _RBs) ->
%% map
expr({map,_,Binding,Es}, Bs0, Lf, Ef, RBs) ->
{value, Map0, Bs1} = expr(Binding, Bs0, Lf, Ef, none),
- case Map0 of
- #{} ->
- {Vs,Bs2} = eval_map_fields(Es, Bs0, Lf, Ef),
- Map1 = lists:foldl(fun ({map_assoc,K,V}, Mi) ->
- maps:put(K, V, Mi);
- ({map_exact,K,V}, Mi) ->
- maps:update(K, V, Mi)
- end, Map0, Vs),
- ret_expr(Map1, merge_bindings(Bs2, Bs1), RBs);
- _ ->
- erlang:raise(error, {badarg,Map0}, stacktrace())
- end;
+ {Vs,Bs2} = eval_map_fields(Es, Bs0, Lf, Ef),
+ _ = maps:put(k, v, Map0), %Validate map.
+ Map1 = lists:foldl(fun ({map_assoc,K,V}, Mi) ->
+ maps:put(K, V, Mi);
+ ({map_exact,K,V}, Mi) ->
+ maps:update(K, V, Mi)
+ end, Map0, Vs),
+ ret_expr(Map1, merge_bindings(Bs2, Bs1), RBs);
expr({map,_,Es}, Bs0, Lf, Ef, RBs) ->
{Vs,Bs} = eval_map_fields(Es, Bs0, Lf, Ef),
ret_expr(lists:foldl(fun
@@ -418,7 +415,7 @@ expr({call,_,{atom,_,Func},As0}, Bs0, Lf, Ef, RBs) ->
{As,Bs} = expr_list(As0, Bs0, Lf, Ef),
bif(Func, As, Bs, Ef, RBs);
false ->
- local_func(Func, As0, Bs0, Lf, RBs)
+ local_func(Func, As0, Bs0, Lf, Ef, RBs)
end;
expr({call,_,Func0,As0}, Bs0, Lf, Ef, RBs) -> % function or {Mod,Fun}
{value,Func,Bs1} = expr(Func0, Bs0, Lf, Ef, none),
@@ -483,12 +480,13 @@ expr({value,_,Val}, Bs, _Lf, _Ef, RBs) -> % Special case straight values.
find_maxline(LC) ->
put('$erl_eval_max_line', 0),
- F = fun(L) ->
+ F = fun(A) ->
+ L = erl_anno:line(A),
case is_integer(L) and (L > get('$erl_eval_max_line')) of
true -> put('$erl_eval_max_line', L);
false -> ok
end end,
- _ = erl_lint:modify_line(LC, F),
+ _ = erl_parse:map_anno(F, LC),
erase('$erl_eval_max_line').
hide_calls(LC, MaxLine) ->
@@ -498,14 +496,16 @@ hide_calls(LC, MaxLine) ->
%% v/1 and local calls are hidden.
hide({value,L,V}, Id, D) ->
- {{atom,Id,ok}, Id+1, dict:store(Id, {value,L,V}, D)};
+ A = erl_anno:new(Id),
+ {{atom,A,ok}, Id+1, dict:store(Id, {value,L,V}, D)};
hide({call,L,{atom,_,N}=Atom,Args}, Id0, D0) ->
{NArgs, Id, D} = hide(Args, Id0, D0),
C = case erl_internal:bif(N, length(Args)) of
true ->
{call,L,Atom,NArgs};
false ->
- {call,Id,{remote,L,{atom,L,m},{atom,L,f}},NArgs}
+ A = erl_anno:new(Id),
+ {call,A,{remote,L,{atom,L,m},{atom,L,f}},NArgs}
end,
{C, Id+1, dict:store(Id, {call,Atom}, D)};
hide(T0, Id0, D0) when is_tuple(T0) ->
@@ -518,11 +518,23 @@ hide([E0 | Es0], Id0, D0) ->
hide(E, Id, D) ->
{E, Id, D}.
-unhide_calls({atom,Id,ok}, MaxLine, D) when Id > MaxLine ->
- dict:fetch(Id, D);
-unhide_calls({call,Id,{remote,L,_M,_F},Args}, MaxLine, D) when Id > MaxLine ->
- {call,Atom} = dict:fetch(Id, D),
- {call,L,Atom,unhide_calls(Args, MaxLine, D)};
+unhide_calls({atom,A,ok}=E, MaxLine, D) ->
+ L = erl_anno:line(A),
+ if
+ L > MaxLine ->
+ dict:fetch(L, D);
+ true ->
+ E
+ end;
+unhide_calls({call,A,{remote,L,{atom,L,m},{atom,L,f}}=F,Args}, MaxLine, D) ->
+ Line = erl_anno:line(A),
+ if
+ Line > MaxLine ->
+ {call,Atom} = dict:fetch(Line, D),
+ {call,L,Atom,unhide_calls(Args, MaxLine, D)};
+ true ->
+ {call,A,F,unhide_calls(Args, MaxLine, D)}
+ end;
unhide_calls(T, MaxLine, D) when is_tuple(T) ->
list_to_tuple(unhide_calls(tuple_to_list(T), MaxLine, D));
unhide_calls([E | Es], MaxLine, D) ->
@@ -530,33 +542,34 @@ unhide_calls([E | Es], MaxLine, D) ->
unhide_calls(E, _MaxLine, _D) ->
E.
-%% local_func(Function, Arguments, Bindings, LocalFuncHandler, RBs) ->
+%% local_func(Function, Arguments, Bindings, LocalFuncHandler,
+%% ExternalFuncHandler, RBs) ->
%% {value,Value,Bindings} | Value when
%% LocalFuncHandler = {value,F} | {value,F,Eas} |
%% {eval,F} | {eval,F,Eas} | none.
-local_func(Func, As0, Bs0, {value,F}, value) ->
- {As1,_Bs1} = expr_list(As0, Bs0, {value,F}),
+local_func(Func, As0, Bs0, {value,F}, Ef, value) ->
+ {As1,_Bs1} = expr_list(As0, Bs0, {value,F}, Ef),
%% Make tail recursive calls when possible.
F(Func, As1);
-local_func(Func, As0, Bs0, {value,F}, RBs) ->
- {As1,Bs1} = expr_list(As0, Bs0, {value,F}),
+local_func(Func, As0, Bs0, {value,F}, Ef, RBs) ->
+ {As1,Bs1} = expr_list(As0, Bs0, {value,F}, Ef),
ret_expr(F(Func, As1), Bs1, RBs);
-local_func(Func, As0, Bs0, {value,F,Eas}, RBs) ->
+local_func(Func, As0, Bs0, {value,F,Eas}, Ef, RBs) ->
Fun = fun(Name, Args) -> apply(F, [Name,Args|Eas]) end,
- local_func(Func, As0, Bs0, {value, Fun}, RBs);
-local_func(Func, As, Bs, {eval,F}, RBs) ->
+ local_func(Func, As0, Bs0, {value, Fun}, Ef, RBs);
+local_func(Func, As, Bs, {eval,F}, _Ef, RBs) ->
local_func2(F(Func, As, Bs), RBs);
-local_func(Func, As, Bs, {eval,F,Eas}, RBs) ->
+local_func(Func, As, Bs, {eval,F,Eas}, _Ef, RBs) ->
local_func2(apply(F, [Func,As,Bs|Eas]), RBs);
%% These two clauses are for backwards compatibility.
-local_func(Func, As0, Bs0, {M,F}, RBs) ->
- {As1,Bs1} = expr_list(As0, Bs0, {M,F}),
+local_func(Func, As0, Bs0, {M,F}, Ef, RBs) ->
+ {As1,Bs1} = expr_list(As0, Bs0, {M,F}, Ef),
ret_expr(M:F(Func,As1), Bs1, RBs);
-local_func(Func, As, _Bs, {M,F,Eas}, RBs) ->
+local_func(Func, As, _Bs, {M,F,Eas}, _Ef, RBs) ->
local_func2(apply(M, F, [Func,As|Eas]), RBs);
%% Default unknown function handler to undefined function.
-local_func(Func, As0, _Bs0, none, _RBs) ->
+local_func(Func, As0, _Bs0, none, _Ef, _RBs) ->
erlang:raise(error, undef, [{erl_eval,Func,length(As0)}|stacktrace()]).
local_func2({value,V,Bs}, RBs) ->
@@ -1172,7 +1185,7 @@ match_tuple([], _, _, Bs, _BBs) ->
match_map([{map_field_exact, _, K, V}|Fs], Map, Bs0, BBs) ->
Vm = try
- {value, Ke, _} = expr(K, new_bindings()),
+ {value, Ke, _} = expr(K, BBs),
maps:get(Ke,Map)
catch error:_ ->
throw(nomatch)
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index 64a00acd88..bcfeef7321 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -38,8 +39,6 @@
checked_ra=[] % successfully accessed records
}).
--define(REC_OFFSET, 100000000). % A hundred millions. Also in v3_core.
-
-spec(module(AbsForms, CompileOptions) -> AbsForms when
AbsForms :: [erl_parse:abstract_form()],
CompileOptions :: [compile:option()]).
@@ -149,7 +148,7 @@ pattern({record_index,Line,Name,Field}, St) ->
pattern({record,Line0,Name,Pfs}, St0) ->
Fs = record_fields(Name, St0),
{TMs,St1} = pattern_list(pattern_fields(Fs, Pfs), St0),
- Line = record_offset(Line0, St1),
+ Line = mark_record(Line0, St1),
{{tuple,Line,[{atom,Line0,Name} | TMs]},St1};
pattern({bin,Line,Es0}, St0) ->
{Es1,St1} = pattern_bin(Es0, St0),
@@ -243,7 +242,7 @@ record_test_in_guard(Line, Term, Name, St) ->
expr({atom,Line,false}, St);
false ->
Fs = record_fields(Name, St),
- NLine = neg_line(Line),
+ NLine = no_compiler_warning(Line),
expr({call,NLine,{remote,NLine,{atom,NLine,erlang},{atom,NLine,is_record}},
[Term,{atom,Line,Name},{integer,Line,length(Fs)+1}]},
St)
@@ -269,7 +268,7 @@ record_test_in_body(Line, Expr, Name, St0) ->
%% evaluate to a tuple properly.
Fs = record_fields(Name, St0),
{Var,St} = new_var(Line, St0),
- NLine = neg_line(Line),
+ NLine = no_compiler_warning(Line),
expr({block,Line,
[{match,Line,Var,Expr},
{call,NLine,{remote,NLine,{atom,NLine,erlang},
@@ -333,7 +332,7 @@ expr({record_index,Line,Name,F}, St) ->
I = index_expr(Line, F, Name, record_fields(Name, St)),
expr(I, St);
expr({record,Line0,Name,Is}, St) ->
- Line = record_offset(Line0, St),
+ Line = mark_record(Line0, St),
expr({tuple,Line,[{atom,Line0,Name} |
record_inits(record_fields(Name, St), Is)]},
St);
@@ -384,21 +383,11 @@ expr({call,Line,{tuple,_,[{atom,_,erlang},{atom,_,is_record}]},
expr({call,Line,{atom,_La,N}=Atom,As0}, St0) ->
{As,St1} = expr_list(As0, St0),
Ar = length(As),
- case erl_internal:bif(N, Ar) of
- true ->
- {{call,Line,Atom,As},St1};
- false ->
- case imported(N, Ar, St1) of
- {yes,_Mod} ->
- {{call,Line,Atom,As},St1};
- no ->
- case {N,Ar} of
- {record_info,2} ->
- record_info_call(Line, As, St1);
- _ ->
- {{call,Line,Atom,As},St1}
- end
- end
+ case {N,Ar} =:= {record_info,2} andalso not imported(N, Ar, St1) of
+ true ->
+ record_info_call(Line, As, St1);
+ false ->
+ {{call,Line,Atom,As},St1}
end;
expr({call,Line,{remote,Lr,M,F},As0}, St0) ->
{[M1,F1 | As1],St1} = expr_list([M,F | As0], St0),
@@ -469,7 +458,7 @@ strict_record_access(E0, St0) ->
conj([], _E) ->
empty;
conj([{{Name,_Rp},L,R,Sz} | AL], E) ->
- NL = neg_line(L),
+ NL = no_compiler_warning(L),
T1 = {op,NL,'orelse',
{call,NL,
{remote,NL,{atom,NL,erlang},{atom,NL,is_record}},
@@ -585,8 +574,8 @@ strict_get_record_field(Line, R, {atom,_,F}=Index, Name, St0) ->
Fs = record_fields(Name, St),
I = index_expr(F, Fs, 2),
P = record_pattern(2, I, Var, length(Fs)+1, Line, [{atom,Line,Name}]),
- NLine = neg_line(Line),
- RLine = record_offset(NLine, St),
+ NLine = no_compiler_warning(Line),
+ RLine = mark_record(NLine, St),
E = {'case',NLine,R,
[{clause,NLine,[{tuple,RLine,P}],[],[Var]},
{clause,NLine,[{var,NLine,'_'}],[],
@@ -600,7 +589,8 @@ strict_get_record_field(Line, R, {atom,_,F}=Index, Name, St0) ->
I = index_expr(Line, Index, Name, Fs),
{ExpR,St1} = expr(R, St0),
%% Just to make comparison simple:
- ExpRp = erl_lint:modify_line(ExpR, fun(_L) -> 0 end),
+ A0 = erl_anno:new(0),
+ ExpRp = erl_parse:map_anno(fun(_A) -> A0 end, ExpR),
RA = {{Name,ExpRp},Line,ExpR,length(Fs)+1},
St2 = St1#exprec{strict_ra = [RA | St1#exprec.strict_ra]},
{{call,Line,
@@ -701,8 +691,8 @@ record_update(R, Name, Fs, Us0, St0) ->
record_match(R, Name, Lr, Fs, Us, St0) ->
{Ps,News,St1} = record_upd_fs(Fs, Us, St0),
- NLr = neg_line(Lr),
- RLine = record_offset(Lr, St1),
+ NLr = no_compiler_warning(Lr),
+ RLine = mark_record(Lr, St1),
{{'case',Lr,R,
[{clause,Lr,[{tuple,RLine,[{atom,Lr,Name} | Ps]}],[],
[{tuple,RLine,[{atom,Lr,Name} | News]}]},
@@ -733,8 +723,8 @@ record_setel(R, Name, Fs, Us0) ->
Us = [T || {_,T} <- Us2],
Lr = element(2, hd(Us)),
Wildcards = duplicate(length(Fs), {var,Lr,'_'}),
- NLr = neg_line(Lr),
- %% Note: calling record_offset() here is not necessary since it is
+ NLr = no_compiler_warning(Lr),
+ %% Note: calling mark_record() here is not necessary since it is
%% targeted at Dialyzer which always calls the compiler with
%% 'strict_record_updates' meaning that record_setel() will never
%% be called.
@@ -832,10 +822,7 @@ add_imports(Mod, [F | Fs], Is) ->
add_imports(_, [], Is) -> Is.
imported(F, A, St) ->
- case orddict:find({F,A}, St#exprec.imports) of
- {ok,Mod} -> {yes,Mod};
- error -> no
- end.
+ orddict:is_key({F,A}, St#exprec.imports).
%%%
%%% Replace is_record/3 in guards with matching if possible.
@@ -969,12 +956,11 @@ opt_remove_2({call,Line,{atom,_,is_record},
end;
opt_remove_2(A, _) -> A.
-neg_line(L) ->
- erl_parse:set_line(L, fun(Line) -> -abs(Line) end).
+no_compiler_warning(Anno) ->
+ erl_anno:set_generated(true, Anno).
-record_offset(L, St) ->
+mark_record(Anno, St) ->
case lists:member(dialyzer, St#exprec.compile) of
- true when L >= 0 -> L+?REC_OFFSET;
- true when L < 0 -> L-?REC_OFFSET;
- false -> L
+ true -> erl_anno:set_record(true, Anno);
+ false -> Anno
end.
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index edfb097de0..f7711d0ad7 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -51,6 +52,8 @@
type_test/2,new_type_test/2,old_type_test/2,old_bif/2]).
-export([arith_op/2,bool_op/2,comp_op/2,list_op/2,send_op/2,op_type/2]).
+-export([is_type/2]).
+
%%---------------------------------------------------------------------------
%% Erlang builtin functions allowed in guards.
@@ -293,6 +296,7 @@ bif(garbage_collect, 1) -> true;
bif(garbage_collect, 2) -> true;
bif(get, 0) -> true;
bif(get, 1) -> true;
+bif(get_keys, 0) -> true;
bif(get_keys, 1) -> true;
bif(group_leader, 0) -> true;
bif(group_leader, 2) -> true;
@@ -530,3 +534,53 @@ old_bif(unlink, 1) -> true;
old_bif(unregister, 1) -> true;
old_bif(whereis, 1) -> true;
old_bif(Name, A) when is_atom(Name), is_integer(A) -> false.
+
+-spec is_type(Name, NumberOfTypeVariables) -> boolean() when
+ Name :: atom(),
+ NumberOfTypeVariables :: non_neg_integer().
+%% Returns true if Name/NumberOfTypeVariables is a predefined type.
+
+is_type(any, 0) -> true;
+is_type(arity, 0) -> true;
+is_type(atom, 0) -> true;
+is_type(binary, 0) -> true;
+is_type(bitstring, 0) -> true;
+is_type(bool, 0) -> true;
+is_type(boolean, 0) -> true;
+is_type(byte, 0) -> true;
+is_type(char, 0) -> true;
+is_type(float, 0) -> true;
+is_type(function, 0) -> true;
+is_type(identifier, 0) -> true;
+is_type(integer, 0) -> true;
+is_type(iodata, 0) -> true;
+is_type(iolist, 0) -> true;
+is_type(list, 0) -> true;
+is_type(list, 1) -> true;
+is_type(map, 0) -> true;
+is_type(maybe_improper_list, 0) -> true;
+is_type(maybe_improper_list, 2) -> true;
+is_type(mfa, 0) -> true;
+is_type(module, 0) -> true;
+is_type(neg_integer, 0) -> true;
+is_type(nil, 0) -> true;
+is_type(no_return, 0) -> true;
+is_type(node, 0) -> true;
+is_type(non_neg_integer, 0) -> true;
+is_type(none, 0) -> true;
+is_type(nonempty_improper_list, 2) -> true;
+is_type(nonempty_list, 0) -> true;
+is_type(nonempty_list, 1) -> true;
+is_type(nonempty_maybe_improper_list, 0) -> true;
+is_type(nonempty_maybe_improper_list, 2) -> true;
+is_type(nonempty_string, 0) -> true;
+is_type(number, 0) -> true;
+is_type(pid, 0) -> true;
+is_type(port, 0) -> true;
+is_type(pos_integer, 0) -> true;
+is_type(reference, 0) -> true;
+is_type(string, 0) -> true;
+is_type(term, 0) -> true;
+is_type(timeout, 0) -> true;
+is_type(tuple, 0) -> true;
+is_type(_, _) -> false.
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 39cc03cf7a..62b3169a6c 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,6 +35,8 @@
-import(lists, [member/2,map/2,foldl/3,foldr/3,mapfoldl/3,all/2,reverse/1]).
+-deprecated([{modify_line, 2, next_major_release}]).
+
%% bool_option(OnOpt, OffOpt, Default, Options) -> boolean().
%% value_option(Flag, Default, Options) -> Value.
%% value_option(Flag, Default, OnOpt, OnVal, OffOpt, OffVal, Options) ->
@@ -76,7 +79,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
%%-define(DEBUGF(X,Y), io:format(X, Y)).
-define(DEBUGF(X,Y), void).
--type line() :: erl_scan:line(). % a convenient alias
+-type line() :: erl_anno:line(). % a convenient alias
-type fa() :: {atom(), arity()}. % function+arity
-type ta() :: {atom(), arity()}. % type+arity
@@ -97,7 +100,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
%% 'called' and 'exports' contain {Line, {Function, Arity}},
%% the other function collections contain {Function, Arity}.
-record(lint, {state=start :: 'start' | 'attribute' | 'function',
- module=[], %Module
+ module='', %Module
behaviour=[], %Behaviour
exports=gb_sets:empty() :: gb_sets:set(fa()),%Exports
imports=[] :: [fa()], %Imports, an orddict()
@@ -111,25 +114,28 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
defined=gb_sets:empty() %Defined fuctions
:: gb_sets:set(fa()),
on_load=[] :: [fa()], %On-load function
- on_load_line=0 :: line(), %Line for on_load
+ on_load_line=erl_anno:new(0) %Line for on_load
+ :: erl_anno:anno(),
clashes=[], %Exported functions named as BIFs
not_deprecated=[], %Not considered deprecated
func=[], %Current function
warn_format=0, %Warn format calls
enabled_warnings=[], %All enabled warnings (ordset).
+ nowarn_bif_clash=[], %All no warn bif clashes (ordset).
errors=[], %Current errors
warnings=[], %Current warnings
file = "" :: string(), %From last file attribute
recdef_top=false :: boolean(), %true in record initialisation
%outside any fun or lc
xqlc= false :: boolean(), %true if qlc.hrl included
- new = false :: boolean(), %Has user-defined 'new/N'
called= [] :: [{fa(),line()}], %Called functions
usage = #usage{} :: #usage{},
specs = dict:new() %Type specifications
:: dict:dict(mfa(), line()),
callbacks = dict:new() %Callback types
:: dict:dict(mfa(), line()),
+ optional_callbacks = dict:new() %Optional callbacks
+ :: dict:dict(mfa(), line()),
types = dict:new() %Type definitions
:: dict:dict(ta(), #typeinfo{}),
exp_types=gb_sets:empty() %Exported types
@@ -138,7 +144,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
-type lint_state() :: #lint{}.
-type error_description() :: term().
--type error_info() :: {erl_scan:line(), module(), error_description()}.
+-type error_info() :: {erl_anno:line(), module(), error_description()}.
%% format_error(Error)
%% Return a string describing the error.
@@ -225,6 +231,8 @@ format_error({deprecated, MFA, ReplacementMFA, Rel}) ->
[format_mfa(MFA), Rel, format_mfa(ReplacementMFA)]);
format_error({deprecated, {M1, F1, A1}, String}) when is_list(String) ->
io_lib:format("~p:~p/~p: ~s", [M1, F1, A1, String]);
+format_error({deprecated_type, {M1, F1, A1}, String}) when is_list(String) ->
+ io_lib:format("~p:~p~s: ~s", [M1, F1, gen_type_paren(A1), String]);
format_error({removed, MFA, ReplacementMFA, Rel}) ->
io_lib:format("call to ~s will fail, since it was removed in ~s; "
"use ~s", [format_mfa(MFA), Rel, format_mfa(ReplacementMFA)]);
@@ -237,10 +245,7 @@ format_error({too_many_arguments,Arity}) ->
"maximum allowed is ~w", [Arity,?MAX_ARGUMENTS]);
%% --- patterns and guards ---
format_error(illegal_pattern) -> "illegal pattern";
-format_error(illegal_map_key) ->
- "illegal map key";
-format_error({illegal_map_key_variable,K}) ->
- io_lib:format("illegal use of variable ~w in map",[K]);
+format_error(illegal_map_key) -> "illegal map key in pattern";
format_error(illegal_bin_pattern) ->
"binary patterns cannot be matched in parallel using '='";
format_error(illegal_expr) -> "illegal expression";
@@ -288,6 +293,9 @@ format_error({variable_in_record_def,V}) ->
%% --- binaries ---
format_error({undefined_bittype,Type}) ->
io_lib:format("bit type ~w undefined", [Type]);
+format_error({bittype_mismatch,Val1,Val2,What}) ->
+ io_lib:format("conflict in ~s specification for bit field: '~p' and '~p'",
+ [What,Val1,Val2]);
format_error(bittype_unit) ->
"a bit unit size must not be specified unless a size is specified too";
format_error(illegal_bitsize) ->
@@ -313,13 +321,20 @@ format_error({undefined_behaviour,Behaviour}) ->
io_lib:format("behaviour ~w undefined", [Behaviour]);
format_error({undefined_behaviour_callbacks,Behaviour}) ->
io_lib:format("behaviour ~w callback functions are undefined",
- [Behaviour]);
+ [Behaviour]);
format_error({ill_defined_behaviour_callbacks,Behaviour}) ->
io_lib:format("behaviour ~w callback functions erroneously defined",
[Behaviour]);
+format_error({ill_defined_optional_callbacks,Behaviour}) ->
+ io_lib:format("behaviour ~w optional callback functions erroneously defined",
+ [Behaviour]);
format_error({behaviour_info, {_M,F,A}}) ->
io_lib:format("cannot define callback attibute for ~w/~w when "
"behaviour_info is defined",[F,A]);
+format_error({redefine_optional_callback, {F, A}}) ->
+ io_lib:format("optional callback ~w/~w duplicated", [F, A]);
+format_error({undefined_callback, {_M, F, A}}) ->
+ io_lib:format("callback ~w/~w is undefined", [F, A]);
%% --- types and specs ---
format_error({singleton_typevar, Name}) ->
io_lib:format("type variable ~w is only used once (is unbound)", [Name]);
@@ -331,14 +346,10 @@ format_error({undefined_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s undefined", [TypeName, gen_type_paren(Arity)]);
format_error({unused_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s is unused", [TypeName, gen_type_paren(Arity)]);
-%% format_error({new_builtin_type, {TypeName, Arity}}) ->
-%% io_lib:format("type ~w~s is a new builtin type; "
-%% "its (re)definition is allowed only until the next release",
-%% [TypeName, gen_type_paren(Arity)]);
-format_error({new_var_arity_type, TypeName}) ->
- io_lib:format("type ~w is a new builtin type; "
+format_error({new_builtin_type, {TypeName, Arity}}) ->
+ io_lib:format("type ~w~s is a new builtin type; "
"its (re)definition is allowed only until the next release",
- [TypeName]);
+ [TypeName, gen_type_paren(Arity)]);
format_error({builtin_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s is a builtin type; it cannot be redefined",
[TypeName, gen_type_paren(Arity)]);
@@ -352,10 +363,14 @@ format_error({type_syntax, Constr}) ->
io_lib:format("bad ~w type", [Constr]);
format_error({redefine_spec, {M, F, A}}) ->
io_lib:format("spec for ~w:~w/~w already defined", [M, F, A]);
-format_error({redefine_callback, {M, F, A}}) ->
- io_lib:format("callback ~w:~w/~w already defined", [M, F, A]);
-format_error({spec_fun_undefined, {M, F, A}}) ->
- io_lib:format("spec for undefined function ~w:~w/~w", [M, F, A]);
+format_error({redefine_spec, {F, A}}) ->
+ io_lib:format("spec for ~w/~w already defined", [F, A]);
+format_error({redefine_callback, {F, A}}) ->
+ io_lib:format("callback ~w/~w already defined", [F, A]);
+format_error({bad_callback, {M, F, A}}) ->
+ io_lib:format("explicit module not allowed for callback ~w:~w/~w ", [M, F, A]);
+format_error({spec_fun_undefined, {F, A}}) ->
+ io_lib:format("spec for undefined function ~w/~w", [F, A]);
format_error({missing_spec, {F,A}}) ->
io_lib:format("missing specification for function ~w/~w", [F, A]);
format_error(spec_wrong_arity) ->
@@ -383,9 +398,7 @@ format_error({underspecified_opaque, {TypeName, Arity}}) ->
[TypeName, gen_type_paren(Arity)]);
%% --- obsolete? unused? ---
format_error({format_error, {Fmt, Args}}) ->
- io_lib:format(Fmt, Args);
-format_error({mnemosyne, What}) ->
- "mnemosyne " ++ What ++ ", missing transformation".
+ io_lib:format(Fmt, Args).
gen_type_paren(Arity) when is_integer(Arity), Arity >= 0 ->
gen_type_paren_1(Arity, ")").
@@ -421,13 +434,13 @@ exprs(Exprs, BindingsList) ->
exprs_opt(Exprs, BindingsList, Opts) ->
{St0,Vs} = foldl(fun({{record,_SequenceNumber,_Name},Attr0}, {St1,Vs1}) ->
- Attr = zip_file_and_line(Attr0, "none"),
+ Attr = set_file(Attr0, "none"),
{attribute_state(Attr, St1),Vs1};
({V,_}, {St1,Vs1}) ->
{St1,[{V,{bound,unused,[]}} | Vs1]}
end, {start("nofile",Opts),[]}, BindingsList),
Vt = orddict:from_list(Vs),
- {_Evt,St} = exprs(zip_file_and_line(Exprs, "nofile"), Vt, St0),
+ {_Evt,St} = exprs(set_file(Exprs, "nofile"), Vt, St0),
return_status(St).
used_vars(Exprs, BindingsList) ->
@@ -435,7 +448,7 @@ used_vars(Exprs, BindingsList) ->
({V,_Val}, Vs0) -> [{V,{bound,unused,[]}} | Vs0]
end, [], BindingsList),
Vt = orddict:from_list(Vs),
- {Evt,_St} = exprs(zip_file_and_line(Exprs, "nofile"), Vt, start()),
+ {Evt,_St} = exprs(set_file(Exprs, "nofile"), Vt, start()),
{ok, foldl(fun({V,{_,used,_}}, L) -> [V | L];
(_, L) -> L
end, [], Evt)}.
@@ -560,6 +573,7 @@ start(File, Opts) ->
warn_format = value_option(warn_format, 1, warn_format, 1,
nowarn_format, 0, Opts),
enabled_warnings = Enabled,
+ nowarn_bif_clash = nowarn_function(nowarn_bif_clash, Opts),
file = File
}.
@@ -599,34 +613,39 @@ pack_warnings(Ws) ->
%% add_warning(ErrorDescriptor, State) -> State'
%% add_warning(Line, Error, State) -> State'
-add_error(E, St) -> St#lint{errors=[{St#lint.file,E}|St#lint.errors]}.
+add_error(E, St) -> add_lint_error(E, St#lint.file, St).
+
+add_error(Anno, E, St) ->
+ {File,Location} = loc(Anno, St),
+ add_lint_error({Location,erl_lint,E}, File, St).
-add_error(FileLine, E, St) ->
- {File,Location} = loc(FileLine),
- add_error({Location,erl_lint,E}, St#lint{file = File}).
+add_lint_error(E, File, St) ->
+ St#lint{errors=[{File,E}|St#lint.errors]}.
-add_warning(W, St) -> St#lint{warnings=[{St#lint.file,W}|St#lint.warnings]}.
+add_warning(W, St) -> add_lint_warning(W, St#lint.file, St).
add_warning(FileLine, W, St) ->
- {File,Location} = loc(FileLine),
- add_warning({Location,erl_lint,W}, St#lint{file = File}).
-
-loc(L) ->
- case erl_parse:get_attribute(L, location) of
- {location,{{File,Line},Column}} ->
- {File,{Line,Column}};
- {location,{File,Line}} ->
- {File,Line}
+ {File,Location} = loc(FileLine, St),
+ add_lint_warning({Location,erl_lint,W}, File, St).
+
+add_lint_warning(W, File, St) ->
+ St#lint{warnings=[{File,W}|St#lint.warnings]}.
+
+loc(Anno, St) ->
+ Location = erl_anno:location(Anno),
+ case erl_anno:file(Anno) of
+ undefined -> {St#lint.file,Location};
+ File -> {File,Location}
end.
%% forms([Form], State) -> State'
forms(Forms0, St0) ->
Forms = eval_file_attribute(Forms0, St0),
+ %% Annotations from now on include the 'file' item.
Locals = local_functions(Forms),
AutoImportSuppressed = auto_import_suppressed(St0#lint.compile),
StDeprecated = disallowed_compile_flags(Forms,St0),
- %% Line numbers are from now on pairs {File,Line}.
St1 = includes_qlc_hrl(Forms, StDeprecated#lint{locals = Locals,
no_auto = AutoImportSuppressed}),
St2 = bif_clashes(Forms, St1),
@@ -634,8 +653,6 @@ forms(Forms0, St0) ->
St4 = foldl(fun form/2, pre_scan(Forms, St3), Forms),
post_traversal_check(Forms, St4).
-pre_scan([{function,_L,new,_A,_Cs} | Fs], St) ->
- pre_scan(Fs, St#lint{new=true});
pre_scan([{attribute,L,compile,C} | Fs], St) ->
case is_warn_enabled(export_all, St) andalso
member(export_all, lists:flatten([C])) of
@@ -662,15 +679,24 @@ eval_file_attribute(Forms, St) ->
eval_file_attr([{attribute,_L,file,{File,_Line}}=Form | Forms], _File) ->
[Form | eval_file_attr(Forms, File)];
eval_file_attr([Form0 | Forms], File) ->
- Form = zip_file_and_line(Form0, File),
+ Form = set_form_file(Form0, File),
[Form | eval_file_attr(Forms, File)];
eval_file_attr([], _File) ->
[].
-zip_file_and_line(T, File) ->
- F0 = fun(Line) -> {File,Line} end,
- F = fun(L) -> erl_parse:set_line(L, F0) end,
- modify_line(T, F).
+%% Sets the file only on the form. This is used on post-traversal.
+%% For the remaining of the AST we rely on #lint.file.
+
+set_form_file({attribute,L,K,V}, File) ->
+ {attribute,erl_anno:set_file(File, L),K,V};
+set_form_file({function,L,N,A,C}, File) ->
+ {function,erl_anno:set_file(File, L),N,A,C};
+set_form_file(Form, _File) ->
+ Form.
+
+set_file(T, File) ->
+ F = fun(Anno) -> erl_anno:set_file(File, Anno) end,
+ erl_parse:map_anno(F, T).
%% form(Form, State) -> State'
%% Check a form returning the updated State. Handle generic cases here.
@@ -703,7 +729,7 @@ start_state(Form, St) ->
%% attribute_state(Form, State) ->
%% State'
-attribute_state({attribute,_L,module,_M}, #lint{module=[]}=St) ->
+attribute_state({attribute,_L,module,_M}, #lint{module=''}=St) ->
St;
attribute_state({attribute,L,module,_M}, St) ->
add_error(L, redefine_module, St);
@@ -727,6 +753,8 @@ attribute_state({attribute,L,spec,{Fun,Types}}, St) ->
spec_decl(L, Fun, Types, St);
attribute_state({attribute,L,callback,{Fun,Types}}, St) ->
callback_decl(L, Fun, Types, St);
+attribute_state({attribute,L,optional_callbacks,Es}, St) ->
+ optional_callbacks(L, Es, St);
attribute_state({attribute,L,on_load,Val}, St) ->
on_load(L, Val, St);
attribute_state({attribute,_L,_Other,_Val}, St) -> % Ignore others
@@ -738,6 +766,8 @@ attribute_state(Form, St) ->
%% State'
%% Allow for record, type and opaque type definitions and spec
%% declarations to be intersperced within function definitions.
+%% Dialyzer attributes are also allowed everywhere, but are not
+%% checked at all.
function_state({attribute,L,record,{Name,Fields}}, St) ->
record_def(L, Name, Fields, St);
@@ -747,12 +777,12 @@ function_state({attribute,L,opaque,{TypeName,TypeDef,Args}}, St) ->
type_def(opaque, L, TypeName, TypeDef, Args, St);
function_state({attribute,L,spec,{Fun,Types}}, St) ->
spec_decl(L, Fun, Types, St);
+function_state({attribute,_L,dialyzer,_Val}, St) ->
+ St;
function_state({attribute,La,Attr,_Val}, St) ->
add_error(La, {attribute,Attr}, St);
function_state({function,L,N,A,Cs}, St) ->
function(L, N, A, Cs, St);
-function_state({rule,L,_N,_A,_Cs}, St) ->
- add_error(L, {mnemosyne,"rule"}, St);
function_state({eof,L}, St) -> eof(L, St).
%% eof(LastLine, State) ->
@@ -763,8 +793,7 @@ eof(_Line, St0) ->
%% bif_clashes(Forms, State0) -> State.
-bif_clashes(Forms, St) ->
- Nowarn = nowarn_function(nowarn_bif_clash, St#lint.compile),
+bif_clashes(Forms, #lint{nowarn_bif_clash=Nowarn} = St) ->
Clashes0 = [{Name,Arity} || {function,_L,Name,Arity,_Cs} <- Forms,
erl_internal:bif(Name, Arity)],
Clashes = ordsets:subtract(ordsets:from_list(Clashes0), Nowarn),
@@ -788,9 +817,11 @@ not_deprecated(Forms, St0) ->
disallowed_compile_flags(Forms, St0) ->
%% There are (still) no line numbers in St0#lint.compile.
Errors0 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} ||
- {attribute,[{line,{_,L}}],compile,nowarn_bif_clash} <- Forms ],
+ {attribute,A,compile,nowarn_bif_clash} <- Forms,
+ {_,L} <- [loc(A, St0)] ],
Errors1 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} ||
- {attribute,[{line,{_,L}}],compile,{nowarn_bif_clash, {_,_}}} <- Forms ],
+ {attribute,A,compile,{nowarn_bif_clash, {_,_}}} <- Forms,
+ {_,L} <- [loc(A, St0)] ],
Disabled = (not is_warn_enabled(bif_clash, St0)),
Errors = if
Disabled andalso Errors0 =:= [] ->
@@ -834,57 +865,73 @@ check_behaviour(St0) ->
%% Check behaviours for existence and defined functions.
behaviour_check(Bs, St0) ->
- {AllBfs,St1} = all_behaviour_callbacks(Bs, [], St0),
- St = behaviour_missing_callbacks(AllBfs, St1),
+ {AllBfs0, St1} = all_behaviour_callbacks(Bs, [], St0),
+ St = behaviour_missing_callbacks(AllBfs0, St1),
+ Exports = exports(St0),
+ F = fun(Bfs, OBfs) ->
+ [B || B <- Bfs,
+ not lists:member(B, OBfs)
+ orelse gb_sets:is_member(B, Exports)]
+ end,
+ %% After fixing missing callbacks new warnings may be emitted.
+ AllBfs = [{Item,F(Bfs0, OBfs0)} || {Item,Bfs0,OBfs0} <- AllBfs0],
behaviour_conflicting(AllBfs, St).
all_behaviour_callbacks([{Line,B}|Bs], Acc, St0) ->
- {Bfs0,St} = behaviour_callbacks(Line, B, St0),
- all_behaviour_callbacks(Bs, [{{Line,B},Bfs0}|Acc], St);
+ {Bfs0,OBfs0,St} = behaviour_callbacks(Line, B, St0),
+ all_behaviour_callbacks(Bs, [{{Line,B},Bfs0,OBfs0}|Acc], St);
all_behaviour_callbacks([], Acc, St) -> {reverse(Acc),St}.
behaviour_callbacks(Line, B, St0) ->
try B:behaviour_info(callbacks) of
- Funcs when is_list(Funcs) ->
- All = all(fun({FuncName, Arity}) ->
- is_atom(FuncName) andalso is_integer(Arity);
- ({FuncName, Arity, Spec}) ->
- is_atom(FuncName) andalso is_integer(Arity)
- andalso is_list(Spec);
- (_Other) ->
- false
- end,
- Funcs),
- MaybeRemoveSpec = fun({_F,_A}=FA) -> FA;
- ({F,A,_S}) -> {F,A};
- (Other) -> Other
- end,
- if
- All =:= true ->
- {[MaybeRemoveSpec(F) || F <- Funcs], St0};
+ undefined ->
+ St1 = add_warning(Line, {undefined_behaviour_callbacks, B}, St0),
+ {[], [], St1};
+ Funcs ->
+ case is_fa_list(Funcs) of
true ->
+ try B:behaviour_info(optional_callbacks) of
+ undefined ->
+ {Funcs, [], St0};
+ OptFuncs ->
+ %% OptFuncs should always be OK thanks to
+ %% sys_pre_expand.
+ case is_fa_list(OptFuncs) of
+ true ->
+ {Funcs, OptFuncs, St0};
+ false ->
+ W = {ill_defined_optional_callbacks, B},
+ St1 = add_warning(Line, W, St0),
+ {Funcs, [], St1}
+ end
+ catch
+ _:_ ->
+ {Funcs, [], St0}
+ end;
+ false ->
St1 = add_warning(Line,
- {ill_defined_behaviour_callbacks,B},
+ {ill_defined_behaviour_callbacks, B},
St0),
- {[], St1}
- end;
- undefined ->
- St1 = add_warning(Line, {undefined_behaviour_callbacks,B}, St0),
- {[], St1};
- _Other ->
- St1 = add_warning(Line, {ill_defined_behaviour_callbacks,B}, St0),
- {[], St1}
+ {[], [], St1}
+ end
catch
_:_ ->
- St1 = add_warning(Line, {undefined_behaviour,B}, St0),
- {[], St1}
+ St1 = add_warning(Line, {undefined_behaviour, B}, St0),
+ {[], [], St1}
end.
-behaviour_missing_callbacks([{{Line,B},Bfs}|T], St0) ->
+behaviour_missing_callbacks([{{Line,B},Bfs0,OBfs}|T], St0) ->
+ Bfs = ordsets:subtract(ordsets:from_list(Bfs0), ordsets:from_list(OBfs)),
Exports = gb_sets:to_list(exports(St0)),
- Missing = ordsets:subtract(ordsets:from_list(Bfs), Exports),
+ Missing = ordsets:subtract(Bfs, Exports),
St = foldl(fun (F, S0) ->
- add_warning(Line, {undefined_behaviour_func,F,B}, S0)
+ case is_fa(F) of
+ true ->
+ M = {undefined_behaviour_func,F,B},
+ add_warning(Line, M, S0);
+ false ->
+ S0 % ill_defined_behaviour_callbacks
+ end
end, St0, Missing),
behaviour_missing_callbacks(T, St);
behaviour_missing_callbacks([], St) -> St.
@@ -899,7 +946,7 @@ behaviour_conflicting(AllBfs, St) ->
behaviour_add_conflicts(R, St).
behaviour_add_conflicts([{Cb,[{FirstLoc,FirstB}|Cs]}|T], St0) ->
- FirstL = element(2, loc(FirstLoc)),
+ FirstL = element(2, loc(FirstLoc, St0)),
St = behaviour_add_conflict(Cs, Cb, FirstL, FirstB, St0),
behaviour_add_conflicts(T, St);
behaviour_add_conflicts([], St) -> St.
@@ -1046,10 +1093,9 @@ check_undefined_types(#lint{usage=Usage,types=Def}=St0) ->
Used = Usage#usage.used_types,
UTAs = dict:fetch_keys(Used),
Undef = [{TA,dict:fetch(TA, Used)} ||
- {T,_}=TA <- UTAs,
+ TA <- UTAs,
not dict:is_key(TA, Def),
- not is_default_type(TA),
- not is_newly_introduced_var_arity_type(T)],
+ not is_default_type(TA)],
foldl(fun ({TA,L}, St) ->
add_error(L, {undefined_type,TA}, St)
end, St0, Undef).
@@ -1118,7 +1164,7 @@ check_unused_records(Forms, St0) ->
end, St0#lint.records, UsedRecords),
Unused = [{Name,FileLine} ||
{Name,{FileLine,_Fields}} <- dict:to_list(URecs),
- element(1, loc(FileLine)) =:= FirstFile],
+ element(1, loc(FileLine, St0)) =:= FirstFile],
foldl(fun ({N,L}, St) ->
add_warning(L, {unused_record, N}, St)
end, St0, Unused);
@@ -1127,19 +1173,29 @@ check_unused_records(Forms, St0) ->
end.
check_callback_information(#lint{callbacks = Callbacks,
- defined = Defined} = State) ->
- case gb_sets:is_member({behaviour_info,1}, Defined) of
- false -> State;
+ optional_callbacks = OptionalCbs,
+ defined = Defined} = St0) ->
+ OptFun = fun({MFA, Line}, St) ->
+ case dict:is_key(MFA, Callbacks) of
+ true ->
+ St;
+ false ->
+ add_error(Line, {undefined_callback, MFA}, St)
+ end
+ end,
+ St1 = lists:foldl(OptFun, St0, dict:to_list(OptionalCbs)),
+ case gb_sets:is_member({behaviour_info, 1}, Defined) of
+ false -> St1;
true ->
case dict:size(Callbacks) of
- 0 -> State;
+ 0 -> St1;
_ ->
CallbacksList = dict:to_list(Callbacks),
FoldL =
- fun({Fa,Line},St) ->
+ fun({Fa, Line}, St) ->
add_error(Line, {behaviour_info, Fa}, St)
end,
- lists:foldl(FoldL, State, CallbacksList)
+ lists:foldl(FoldL, St1, CallbacksList)
end
end.
@@ -1266,7 +1322,7 @@ imported(F, A, St) ->
error -> no
end.
--spec on_load(line(), fa(), lint_state()) -> lint_state().
+-spec on_load(erl_anno:anno(), fa(), lint_state()) -> lint_state().
%% Check an on_load directive and remember it.
on_load(Line, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0)
@@ -1301,14 +1357,15 @@ check_on_load(St) -> St.
-spec call_function(line(), atom(), arity(), lint_state()) -> lint_state().
%% Add to both called and calls.
-call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func}=St) ->
+call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func,file=File}=St) ->
#usage{calls = Cs} = Usage0,
NA = {F,A},
Usage = case Cs of
undefined -> Usage0;
_ -> Usage0#usage{calls=dict:append(Func, NA, Cs)}
end,
- St#lint{called=[{NA,Line}|Cd], usage=Usage}.
+ Anno = erl_anno:set_file(File, Line),
+ St#lint{called=[{NA,Anno}|Cd], usage=Usage}.
%% function(Line, Name, Arity, Clauses, State) -> State.
@@ -1404,20 +1461,7 @@ pattern({cons,_Line,H,T}, Vt, Old, Bvt, St0) ->
pattern({tuple,_Line,Ps}, Vt, Old, Bvt, St) ->
pattern_list(Ps, Vt, Old, Bvt, St);
pattern({map,_Line,Ps}, Vt, Old, Bvt, St) ->
- foldl(fun
- ({map_field_assoc,L,_,_}, {Psvt,Bvt0,St0}) ->
- {Psvt,Bvt0,add_error(L, illegal_pattern, St0)};
- ({map_field_exact,L,KP,VP}, {Psvt,Bvt0,St0}) ->
- case is_valid_map_key(KP, pattern, St0) of
- true ->
- {Pvt,Bvt1,St1} = pattern(VP, Vt, Old, Bvt, St0),
- {vtmerge_pat(Pvt, Psvt),vtmerge_pat(Bvt0, Bvt1), St1};
- false ->
- {Psvt,Bvt0,add_error(L, illegal_map_key, St0)};
- {false,variable,Var} ->
- {Psvt,Bvt0,add_error(L, {illegal_map_key_variable,Var}, St0)}
- end
- end, {[],[],St}, Ps);
+ pattern_map(Ps, Vt, Old, Bvt, St);
%%pattern({struct,_Line,_Tag,Ps}, Vt, Old, Bvt, St) ->
%% pattern_list(Ps, Vt, Old, Bvt, St);
pattern({record_index,Line,Name,Field}, _Vt, _Old, _Bvt, St) ->
@@ -1571,6 +1615,21 @@ is_pattern_expr_1({op,_Line,Op,A1,A2}) ->
erl_internal:arith_op(Op, 2) andalso all(fun is_pattern_expr/1, [A1,A2]);
is_pattern_expr_1(_Other) -> false.
+pattern_map(Ps, Vt, Old, Bvt, St) ->
+ foldl(fun
+ ({map_field_assoc,L,_,_}, {Psvt,Bvt0,St0}) ->
+ {Psvt,Bvt0,add_error(L, illegal_pattern, St0)};
+ ({map_field_exact,L,K,V}, {Psvt,Bvt0,St0}) ->
+ case is_valid_map_key(K) of
+ true ->
+ {Kvt,St1} = expr(K, Vt, St0),
+ {Vvt,Bvt2,St2} = pattern(V, Vt, Old, Bvt, St1),
+ {vtmerge_pat(vtmerge_pat(Kvt, Vvt), Psvt), vtmerge_pat(Bvt0, Bvt2), St2};
+ false ->
+ {Psvt,Bvt0,add_error(L, illegal_map_key, St0)}
+ end
+ end, {[],[],St}, Ps).
+
%% pattern_bin([Element], VarTable, Old, BinVarTable, State) ->
%% {UpdVarTable,UpdBinVarTable,State}.
%% Check a pattern group. BinVarTable are used binsize variables.
@@ -1919,10 +1978,10 @@ is_guard_test(E) ->
is_guard_test(Expression, Forms) ->
RecordAttributes = [A || A = {attribute, _, record, _D} <- Forms],
St0 = foldl(fun(Attr0, St1) ->
- Attr = zip_file_and_line(Attr0, "none"),
+ Attr = set_file(Attr0, "none"),
attribute_state(Attr, St1)
end, start(), RecordAttributes),
- is_guard_test2(zip_file_and_line(Expression, "nofile"), St0#lint.records).
+ is_guard_test2(set_file(Expression, "nofile"), St0#lint.records).
%% is_guard_test2(Expression, RecordDefs :: dict:dict()) -> boolean().
is_guard_test2({call,Line,{atom,Lr,record},[E,A]}, RDs) ->
@@ -2085,8 +2144,8 @@ expr({'receive',Line,Cs,To,ToEs}, Vt, St0) ->
{Cvt,St3} = icrt_clauses(Cs, Vt, St2),
%% Csvts = [vtnew(Tevt, Vt)|Cvt], %This is just NEW variables!
Csvts = [Tevt|Cvt],
- {Rvt,St4} = icrt_export(Csvts, Vt, {'receive',Line}, St3),
- {vtmerge([Tvt,Tevt,Rvt]),St4};
+ Rvt = icrt_export(Csvts, Vt, {'receive',Line}, St3),
+ {vtmerge([Tvt,Tevt,Rvt]),St3};
expr({'fun',Line,Body}, Vt, St) ->
%%No one can think funs export!
case Body of
@@ -2197,21 +2256,20 @@ expr({'try',Line,Es,Scs,Ccs,As}, Vt, St0) ->
%% passes cannot handle exports in combination with 'after'.
{Evt0,St1} = exprs(Es, Vt, St0),
TryLine = {'try',Line},
- Uvt = vtunsafe(vtnames(vtnew(Evt0, Vt)), TryLine, []),
- Evt1 = vtupdate(Uvt, vtsubtract(Evt0, Uvt)),
+ Uvt = vtunsafe(TryLine, Evt0, Vt),
+ Evt1 = vtupdate(Uvt, Evt0),
{Sccs,St2} = icrt_clauses(Scs++Ccs, TryLine, vtupdate(Evt1, Vt), St1),
Rvt0 = Sccs,
- Rvt1 = vtupdate(vtunsafe(vtnames(vtnew(Rvt0, Vt)), TryLine, []), Rvt0),
+ Rvt1 = vtupdate(vtunsafe(TryLine, Rvt0, Vt), Rvt0),
Evt2 = vtmerge(Evt1, Rvt1),
{Avt0,St} = exprs(As, vtupdate(Evt2, Vt), St2),
- Avt1 = vtupdate(vtunsafe(vtnames(vtnew(Avt0, Vt)), TryLine, []), Avt0),
+ Avt1 = vtupdate(vtunsafe(TryLine, Avt0, Vt), Avt0),
Avt = vtmerge(Evt2, Avt1),
{Avt,St};
expr({'catch',Line,E}, Vt, St0) ->
%% No new variables added, flag new variables as unsafe.
- {Evt,St1} = expr(E, Vt, St0),
- Uvt = vtunsafe(vtnames(vtnew(Evt, Vt)), {'catch',Line}, []),
- {vtupdate(Uvt,vtupdate(Evt, Vt)),St1};
+ {Evt,St} = expr(E, Vt, St0),
+ {vtupdate(vtunsafe({'catch',Line}, Evt, Vt), Evt),St};
expr({match,_Line,P,E}, Vt, St0) ->
{Evt,St1} = expr(E, Vt, St0),
{Pvt,Bvt,St2} = pattern(P, vtupdate(Evt, Vt), St1),
@@ -2224,9 +2282,8 @@ expr({op,Line,Op,L,R}, Vt, St0) when Op =:= 'orelse'; Op =:= 'andalso' ->
{Evt1,St1} = expr(L, Vt, St0),
Vt1 = vtupdate(Evt1, Vt),
{Evt2,St2} = expr(R, Vt1, St1),
- Vt2 = vtmerge(Evt2, Vt1),
- {Vt3,St3} = icrt_export([Vt1,Vt2], Vt1, {Op,Line}, St2),
- {vtmerge(Evt1, Vt3),St3};
+ Evt3 = vtupdate(vtunsafe({Op,Line}, Evt2, Vt1), Evt2),
+ {vtmerge(Evt1, Evt3),St2};
expr({op,_Line,_Op,L,R}, Vt, St) ->
expr_list([L,R], Vt, St); %They see the same variables
%% The following are not allowed to occur anywhere!
@@ -2237,11 +2294,10 @@ expr({remote,Line,_M,_F}, _Vt, St) ->
%% {UsedVarTable,State}
expr_list(Es, Vt, St) ->
- {Vt1,St1} = foldl(fun (E, {Esvt,St0}) ->
- {Evt,St1} = expr(E, Vt, St0),
- {vtmerge_pat(Evt, Esvt),St1}
- end, {[],St}, Es),
- {vtmerge(vtnew(Vt1, Vt), vtold(Vt1, Vt)),St1}.
+ foldl(fun (E, {Esvt,St0}) ->
+ {Evt,St1} = expr(E, Vt, St0),
+ {vtmerge_pat(Evt, Esvt),St1}
+ end, {[],St}, Es).
record_expr(Line, Rec, Vt, St0) ->
St1 = warn_invalid_record(Line, Rec, St0),
@@ -2254,18 +2310,13 @@ check_assoc_fields([{map_field_assoc,_,_,_}|Fs], St) ->
check_assoc_fields([], St) ->
St.
-map_fields([{Tag,Line,K,V}|Fs], Vt, St, F) when Tag =:= map_field_assoc;
- Tag =:= map_field_exact ->
- St1 = case is_valid_map_key(K, St) of
- true -> St;
- false -> add_error(Line, illegal_map_key, St);
- {false,variable,Var} -> add_error(Line, {illegal_map_key_variable,Var}, St)
- end,
- {Pvt,St2} = F([K,V], Vt, St1),
+map_fields([{Tag,_,K,V}|Fs], Vt, St, F) when Tag =:= map_field_assoc;
+ Tag =:= map_field_exact ->
+ {Pvt,St2} = F([K,V], Vt, St),
{Vts,St3} = map_fields(Fs, Vt, St2, F),
{vtupdate(Pvt, Vts),St3};
-map_fields([], Vt, St, _) ->
- {Vt,St}.
+map_fields([], _, St, _) ->
+ {[],St}.
%% warn_invalid_record(Line, Record, State0) -> State
%% Adds warning if the record is invalid.
@@ -2319,21 +2370,14 @@ is_valid_call(Call) ->
_ -> true
end.
-%% is_valid_map_key(K,St) -> true | false | {false, Var::atom()}
-%% check for value expression without variables
-
-is_valid_map_key(K,St) ->
- is_valid_map_key(K,expr,St).
-is_valid_map_key(K,Ctx,St) ->
- case expr(K,[],St) of
- {[],_} ->
- is_valid_map_key_value(K,Ctx);
- {[Var|_],_} ->
- {false,variable,element(1,Var)}
- end.
+%% is_valid_map_key(K,St) -> true | false
+%% variables are allowed for patterns only at the top of the tree
-is_valid_map_key_value(K,Ctx) ->
+is_valid_map_key({var,_,_}) -> true;
+is_valid_map_key(K) -> is_valid_map_key_value(K).
+is_valid_map_key_value(K) ->
case K of
+ {var,_,_} -> false;
{char,_,_} -> true;
{integer,_,_} -> true;
{float,_,_} -> true;
@@ -2341,36 +2385,36 @@ is_valid_map_key_value(K,Ctx) ->
{nil,_} -> true;
{atom,_,_} -> true;
{cons,_,H,T} ->
- is_valid_map_key_value(H,Ctx) andalso
- is_valid_map_key_value(T,Ctx);
+ is_valid_map_key_value(H) andalso
+ is_valid_map_key_value(T);
{tuple,_,Es} ->
foldl(fun(E,B) ->
- B andalso is_valid_map_key_value(E,Ctx)
+ B andalso is_valid_map_key_value(E)
end,true,Es);
{map,_,Arg,Ps} ->
% only check for value expressions to be valid
% invalid map expressions are later checked in
% core and kernel
- is_valid_map_key_value(Arg,Ctx) andalso foldl(fun
+ is_valid_map_key_value(Arg) andalso foldl(fun
({Tag,_,Ke,Ve},B) when Tag =:= map_field_assoc;
- Tag =:= map_field_exact, Ctx =:= expr ->
- B andalso is_valid_map_key_value(Ke,Ctx)
- andalso is_valid_map_key_value(Ve,Ctx);
+ Tag =:= map_field_exact ->
+ B andalso is_valid_map_key_value(Ke)
+ andalso is_valid_map_key_value(Ve);
(_,_) -> false
end,true,Ps);
{map,_,Ps} ->
foldl(fun
({Tag,_,Ke,Ve},B) when Tag =:= map_field_assoc;
- Tag =:= map_field_exact, Ctx =:= expr ->
- B andalso is_valid_map_key_value(Ke,Ctx)
- andalso is_valid_map_key_value(Ve,Ctx);
+ Tag =:= map_field_exact ->
+ B andalso is_valid_map_key_value(Ke)
+ andalso is_valid_map_key_value(Ve);
(_,_) -> false
end, true, Ps);
{record,_,_,Fs} ->
foldl(fun
({record_field,_,Ke,Ve},B) ->
- B andalso is_valid_map_key_value(Ke,Ctx)
- andalso is_valid_map_key_value(Ve,Ctx)
+ B andalso is_valid_map_key_value(Ke)
+ andalso is_valid_map_key_value(Ve)
end,true,Fs);
{bin,_,Es} ->
% only check for value expressions to be valid
@@ -2378,9 +2422,9 @@ is_valid_map_key_value(K,Ctx) ->
% core and kernel
foldl(fun
({bin_element,_,E,_,_},B) ->
- B andalso is_valid_map_key_value(E,Ctx)
+ B andalso is_valid_map_key_value(E)
end,true,Es);
- _ -> false
+ Val -> is_pattern_expr(Val)
end.
%% record_def(Line, RecordName, [RecField], State) -> State.
@@ -2599,7 +2643,7 @@ type_def(_Attr, _Line, {record, _RecName}, Fields, [], St0) ->
%% The record field names and such are checked in the record format.
%% We only need to check the types.
Types = [T || {typed_record_field, _, T} <- Fields],
- check_type({type, -1, product, Types}, St0);
+ check_type({type, nowarn(), product, Types}, St0);
type_def(Attr, Line, TypeName, ProtoType, Args, St0) ->
TypeDefs = St0#lint.types,
Arity = length(Args),
@@ -2608,37 +2652,28 @@ type_def(Attr, Line, TypeName, ProtoType, Args, St0) ->
StoreType =
fun(St) ->
NewDefs = dict:store(TypePair, Info, TypeDefs),
- CheckType = {type, -1, product, [ProtoType|Args]},
+ CheckType = {type, nowarn(), product, [ProtoType|Args]},
check_type(CheckType, St#lint{types=NewDefs})
end,
case is_default_type(TypePair) of
true ->
case is_obsolete_builtin_type(TypePair) of
true -> StoreType(St0);
- false -> add_error(Line, {builtin_type, TypePair}, St0)
-%% case is_newly_introduced_builtin_type(TypePair) of
-%% %% allow some types just for bootstrapping
-%% true ->
-%% Warn = {new_builtin_type, TypePair},
-%% St1 = add_warning(Line, Warn, St0),
-%% StoreType(St1);
-%% false ->
-%% add_error(Line, {builtin_type, TypePair}, St0)
-%% end
+ false ->
+ case is_newly_introduced_builtin_type(TypePair) of
+ %% allow some types just for bootstrapping
+ true ->
+ Warn = {new_builtin_type, TypePair},
+ St1 = add_warning(Line, Warn, St0),
+ StoreType(St1);
+ false ->
+ add_error(Line, {builtin_type, TypePair}, St0)
+ end
end;
false ->
- case
- dict:is_key(TypePair, TypeDefs) orelse
- is_var_arity_type(TypeName)
- of
+ case dict:is_key(TypePair, TypeDefs) of
true ->
- case is_newly_introduced_var_arity_type(TypeName) of
- true ->
- Warn = {new_var_arity_type, TypeName},
- add_warning(Line, Warn, St0);
- false ->
- add_error(Line, {redefine_type, TypePair}, St0)
- end;
+ add_error(Line, {redefine_type, TypePair}, St0);
false ->
St1 = case
Attr =:= opaque andalso
@@ -2673,9 +2708,11 @@ check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) ->
check_type({paren_type, _L, [Type]}, SeenVars, St) ->
check_type(Type, SeenVars, St);
check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]},
- SeenVars, #lint{module=CurrentMod} = St) ->
+ SeenVars, St0) ->
+ St = deprecated_type(L, Mod, Name, Args, St0),
+ CurrentMod = St#lint.module,
case Mod =:= CurrentMod of
- true -> check_type({type, L, Name, Args}, SeenVars, St);
+ true -> check_type({user_type, L, Name, Args}, SeenVars, St);
false ->
lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
check_type(T, AccSeenVars, AccSt)
@@ -2701,7 +2738,7 @@ check_type({type, L, 'fun', [Dom, Range]}, SeenVars, St) ->
{type, _, any} -> St;
_ -> add_error(L, {type_syntax, 'fun'}, St)
end,
- check_type({type, -1, product, [Dom, Range]}, SeenVars, St1);
+ check_type({type, nowarn(), product, [Dom, Range]}, SeenVars, St1);
check_type({type, L, range, [From, To]}, SeenVars, St) ->
St1 =
case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
@@ -2709,13 +2746,16 @@ check_type({type, L, range, [From, To]}, SeenVars, St) ->
_ -> add_error(L, {type_syntax, range}, St)
end,
{SeenVars, St1};
-check_type({type, _L, map, any}, SeenVars, St) -> {SeenVars, St};
+check_type({type, L, map, any}, SeenVars, St) ->
+ %% To get usage right while map/0 is a newly_introduced_builtin_type.
+ St1 = used_type({map, 0}, L, St),
+ {SeenVars, St1};
check_type({type, _L, map, Pairs}, SeenVars, St) ->
lists:foldl(fun(Pair, {AccSeenVars, AccSt}) ->
check_type(Pair, AccSeenVars, AccSt)
end, {SeenVars, St}, Pairs);
-check_type({type, _L, map_field_assoc, Dom, Range}, SeenVars, St) ->
- check_type({type, -1, product, [Dom, Range]}, SeenVars, St);
+check_type({type, _L, map_field_assoc, [Dom, Range]}, SeenVars, St) ->
+ check_type({type, nowarn(), product, [Dom, Range]}, SeenVars, St);
check_type({type, _L, tuple, any}, SeenVars, St) -> {SeenVars, St};
check_type({type, _L, any}, SeenVars, St) -> {SeenVars, St};
check_type({type, L, binary, [Base, Unit]}, SeenVars, St) ->
@@ -2733,41 +2773,39 @@ check_type({type, L, record, [Name|Fields]}, SeenVars, St) ->
check_record_types(L, Atom, Fields, SeenVars, St1);
_ -> {SeenVars, add_error(L, {type_syntax, record}, St)}
end;
-check_type({type, _L, product, Args}, SeenVars, St) ->
+check_type({type, _L, Tag, Args}, SeenVars, St) when Tag =:= product;
+ Tag =:= union;
+ Tag =:= tuple ->
lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
check_type(T, AccSeenVars, AccSt)
end, {SeenVars, St}, Args);
check_type({type, La, TypeName, Args}, SeenVars, St) ->
- #lint{usage=Usage, module = Module, types=Types} = St,
+ #lint{module = Module, types=Types} = St,
Arity = length(Args),
TypePair = {TypeName, Arity},
- St1 = case is_var_arity_type(TypeName) of
- true -> St;
- false ->
- Obsolete = (is_warn_enabled(deprecated_type, St)
- andalso obsolete_builtin_type(TypePair)),
- IsObsolete =
- case Obsolete of
- {deprecated, Repl, _} when element(1, Repl) =/= Module ->
- case dict:find(TypePair, Types) of
- {ok, _} -> false;
- error -> true
- end;
- _ -> false
- end,
- case IsObsolete of
- true ->
+ Obsolete = (is_warn_enabled(deprecated_type, St)
+ andalso obsolete_builtin_type(TypePair)),
+ St1 = case Obsolete of
+ {deprecated, Repl, _} when element(1, Repl) =/= Module ->
+ case dict:find(TypePair, Types) of
+ {ok, _} ->
+ used_type(TypePair, La, St);
+ error ->
{deprecated, Replacement, Rel} = Obsolete,
Tag = deprecated_builtin_type,
W = {Tag, TypePair, Replacement, Rel},
- add_warning(La, W, St);
- false ->
- OldUsed = Usage#usage.used_types,
- UsedTypes = dict:store(TypePair, La, OldUsed),
- St#lint{usage=Usage#usage{used_types=UsedTypes}}
- end
- end,
- check_type({type, -1, product, Args}, SeenVars, St1);
+ add_warning(La, W, St)
+ end;
+ _ -> St
+ end,
+ check_type({type, nowarn(), product, Args}, SeenVars, St1);
+check_type({user_type, L, TypeName, Args}, SeenVars, St) ->
+ Arity = length(Args),
+ TypePair = {TypeName, Arity},
+ St1 = used_type(TypePair, L, St),
+ lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
+ check_type(T, AccSeenVars, AccSt)
+ end, {SeenVars, St1}, Args);
check_type(I, SeenVars, St) ->
case erl_eval:partial_eval(I) of
{integer,_ILn,_Integer} -> {SeenVars, St};
@@ -2809,95 +2847,23 @@ check_record_types([{type, _, field_type, [{atom, AL, FName}, Type]}|Left],
check_record_types([], _Name, _DefFields, SeenVars, St, _SeenFields) ->
{SeenVars, St}.
-is_var_arity_type(tuple) -> true;
-is_var_arity_type(map) -> true;
-is_var_arity_type(product) -> true;
-is_var_arity_type(union) -> true;
-is_var_arity_type(record) -> true;
-is_var_arity_type(_) -> false.
-
-is_default_type({any, 0}) -> true;
-is_default_type({arity, 0}) -> true;
-is_default_type({array, 0}) -> true;
-is_default_type({atom, 0}) -> true;
-is_default_type({atom, 1}) -> true;
-is_default_type({binary, 0}) -> true;
-is_default_type({binary, 2}) -> true;
-is_default_type({bitstring, 0}) -> true;
-is_default_type({bool, 0}) -> true;
-is_default_type({boolean, 0}) -> true;
-is_default_type({byte, 0}) -> true;
-is_default_type({char, 0}) -> true;
-is_default_type({dict, 0}) -> true;
-is_default_type({digraph, 0}) -> true;
-is_default_type({float, 0}) -> true;
-is_default_type({'fun', 0}) -> true;
-is_default_type({'fun', 2}) -> true;
-is_default_type({function, 0}) -> true;
-is_default_type({gb_set, 0}) -> true;
-is_default_type({gb_tree, 0}) -> true;
-is_default_type({identifier, 0}) -> true;
-is_default_type({integer, 0}) -> true;
-is_default_type({integer, 1}) -> true;
-is_default_type({iodata, 0}) -> true;
-is_default_type({iolist, 0}) -> true;
-is_default_type({list, 0}) -> true;
-is_default_type({list, 1}) -> true;
-is_default_type({maybe_improper_list, 0}) -> true;
-is_default_type({maybe_improper_list, 2}) -> true;
-is_default_type({mfa, 0}) -> true;
-is_default_type({module, 0}) -> true;
-is_default_type({neg_integer, 0}) -> true;
-is_default_type({nil, 0}) -> true;
-is_default_type({no_return, 0}) -> true;
-is_default_type({node, 0}) -> true;
-is_default_type({non_neg_integer, 0}) -> true;
-is_default_type({none, 0}) -> true;
-is_default_type({nonempty_list, 0}) -> true;
-is_default_type({nonempty_list, 1}) -> true;
-is_default_type({nonempty_improper_list, 2}) -> true;
-is_default_type({nonempty_maybe_improper_list, 0}) -> true;
-is_default_type({nonempty_maybe_improper_list, 2}) -> true;
-is_default_type({nonempty_string, 0}) -> true;
-is_default_type({number, 0}) -> true;
-is_default_type({pid, 0}) -> true;
-is_default_type({port, 0}) -> true;
-is_default_type({pos_integer, 0}) -> true;
-is_default_type({queue, 0}) -> true;
-is_default_type({range, 2}) -> true;
-is_default_type({reference, 0}) -> true;
-is_default_type({set, 0}) -> true;
-is_default_type({string, 0}) -> true;
-is_default_type({term, 0}) -> true;
-is_default_type({timeout, 0}) -> true;
-is_default_type({var, 1}) -> true;
-is_default_type(_) -> false.
-
-is_newly_introduced_var_arity_type(map) -> true;
-is_newly_introduced_var_arity_type(_) -> false.
-
-%% is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false.
+used_type(TypePair, L, #lint{usage = Usage, file = File} = St) ->
+ OldUsed = Usage#usage.used_types,
+ UsedTypes = dict:store(TypePair, erl_anno:set_file(File, L), OldUsed),
+ St#lint{usage=Usage#usage{used_types=UsedTypes}}.
+
+is_default_type({Name, NumberOfTypeVariables}) ->
+ erl_internal:is_type(Name, NumberOfTypeVariables).
+
+is_newly_introduced_builtin_type({map, 0}) -> true;
+is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false.
is_obsolete_builtin_type(TypePair) ->
obsolete_builtin_type(TypePair) =/= no.
-%% Obsolete in OTP 17.0.
-obsolete_builtin_type({array, 0}) ->
- {deprecated, {array, array, 1}, "OTP 18.0"};
-obsolete_builtin_type({dict, 0}) ->
- {deprecated, {dict, dict, 2}, "OTP 18.0"};
-obsolete_builtin_type({digraph, 0}) ->
- {deprecated, {digraph, graph}, "OTP 18.0"};
-obsolete_builtin_type({gb_set, 0}) ->
- {deprecated, {gb_sets, set, 1}, "OTP 18.0"};
-obsolete_builtin_type({gb_tree, 0}) ->
- {deprecated, {gb_trees, tree, 2}, "OTP 18.0"};
-obsolete_builtin_type({queue, 0}) ->
- {deprecated, {queue, queue, 1}, "OTP 18.0"};
-obsolete_builtin_type({set, 0}) ->
- {deprecated, {sets, set, 1}, "OTP 18.0"};
-obsolete_builtin_type({tid, 0}) ->
- {deprecated, {ets, tid}, "OTP 18.0"};
+%% To keep Dialyzer silent...
+obsolete_builtin_type({1, 255}) ->
+ {deprecated, {2, 255}, ""};
obsolete_builtin_type({Name, A}) when is_atom(Name), is_integer(A) -> no.
%% spec_decl(Line, Fun, Types, State) -> State.
@@ -2909,7 +2875,7 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
end,
St1 = St0#lint{specs = dict:store(MFA, Line, Specs)},
case dict:is_key(MFA, Specs) of
- true -> add_error(Line, {redefine_spec, MFA}, St1);
+ true -> add_error(Line, {redefine_spec, MFA0}, St1);
false -> check_specs(TypeSpecs, Arity, St1)
end.
@@ -2917,16 +2883,50 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
callback_decl(Line, MFA0, TypeSpecs,
St0 = #lint{callbacks = Callbacks, module = Mod}) ->
- MFA = case MFA0 of
- {F, Arity} -> {Mod, F, Arity};
- {_M, _F, Arity} -> MFA0
- end,
- St1 = St0#lint{callbacks = dict:store(MFA, Line, Callbacks)},
- case dict:is_key(MFA, Callbacks) of
- true -> add_error(Line, {redefine_callback, MFA}, St1);
- false -> check_specs(TypeSpecs, Arity, St1)
+ case MFA0 of
+ {_M, _F, _A} -> add_error(Line, {bad_callback, MFA0}, St0);
+ {F, Arity} ->
+ MFA = {Mod, F, Arity},
+ St1 = St0#lint{callbacks = dict:store(MFA, Line, Callbacks)},
+ case dict:is_key(MFA, Callbacks) of
+ true -> add_error(Line, {redefine_callback, MFA0}, St1);
+ false -> check_specs(TypeSpecs, Arity, St1)
+ end
+ end.
+
+%% optional_callbacks(Line, FAs, State) -> State.
+
+optional_callbacks(Line, Term, St0) ->
+ try true = is_fa_list(Term), Term of
+ FAs ->
+ optional_cbs(Line, FAs, St0)
+ catch
+ _:_ ->
+ St0 % ignore others
end.
+optional_cbs(_Line, [], St) ->
+ St;
+optional_cbs(Line, [{F,A}|FAs], St0) ->
+ #lint{optional_callbacks = OptionalCbs, module = Mod} = St0,
+ MFA = {Mod, F, A},
+ St1 = St0#lint{optional_callbacks = dict:store(MFA, Line, OptionalCbs)},
+ St2 = case dict:is_key(MFA, OptionalCbs) of
+ true ->
+ add_error(Line, {redefine_optional_callback, {F,A}}, St1);
+ false ->
+ St1
+ end,
+ optional_cbs(Line, FAs, St2).
+
+is_fa_list([E|L]) -> is_fa(E) andalso is_fa_list(L);
+is_fa_list([]) -> true;
+is_fa_list(_) -> false.
+
+is_fa({FuncName, Arity})
+ when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> true;
+is_fa(_) -> false.
+
check_specs([FunType|Left], Arity, St0) ->
{FunType1, CTypes} =
case FunType of
@@ -2944,16 +2944,22 @@ check_specs([FunType|Left], Arity, St0) ->
true -> St0;
false -> add_error(L, spec_wrong_arity, St0)
end,
- St2 = check_type({type, -1, product, [FunType1|CTypes]}, St1),
+ St2 = check_type({type, nowarn(), product, [FunType1|CTypes]}, St1),
check_specs(Left, Arity, St2);
check_specs([], _Arity, St) ->
St.
+nowarn() ->
+ A0 = erl_anno:new(0),
+ A1 = erl_anno:set_generated(true, A0),
+ erl_anno:set_file("", A1).
+
check_specs_without_function(#lint{module=Mod,defined=Funcs,specs=Specs}=St) ->
- Fun = fun({M, F, A} = MFA, Line, AccSt) when M =:= Mod ->
- case gb_sets:is_element({F, A}, Funcs) of
+ Fun = fun({M, F, A}, Line, AccSt) when M =:= Mod ->
+ FA = {F, A},
+ case gb_sets:is_element(FA, Funcs) of
true -> AccSt;
- false -> add_error(Line, {spec_fun_undefined, MFA}, AccSt)
+ false -> add_error(Line, {spec_fun_undefined, FA}, AccSt)
end;
({_M, _F, _A}, _Line, AccSt) -> AccSt
end,
@@ -2998,7 +3004,7 @@ check_unused_types(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) ->
UsedTypes = gb_sets:from_list(L),
FoldFun =
fun(Type, #typeinfo{line = FileLine}, AccSt) ->
- case loc(FileLine) of
+ case loc(FileLine, AccSt) of
{FirstFile, _} ->
case gb_sets:is_member(Type, UsedTypes) of
true -> AccSt;
@@ -3032,11 +3038,12 @@ check_local_opaque_types(St) ->
dict:fold(FoldFun, St, Ts).
%% icrt_clauses(Clauses, In, ImportVarTable, State) ->
-%% {NewVts,State}.
+%% {UpdVt,State}.
icrt_clauses(Cs, In, Vt, St0) ->
{Csvt,St1} = icrt_clauses(Cs, Vt, St0),
- icrt_export(Csvt, Vt, In, St1).
+ UpdVt = icrt_export(Csvt, Vt, In, St1),
+ {UpdVt,St1}.
%% icrt_clauses(Clauses, ImportVarTable, State) ->
%% {NewVts,State}.
@@ -3046,26 +3053,73 @@ icrt_clauses(Cs, Vt, St) ->
icrt_clause({clause,_Line,H,G,B}, Vt0, St0) ->
{Hvt,Binvt,St1} = head(H, Vt0, St0),
- Vt1 = vtupdate(Hvt, vtupdate(Binvt, Vt0)),
- {Gvt,St2} = guard(G, Vt1, St1),
+ Vt1 = vtupdate(Hvt, Binvt),
+ {Gvt,St2} = guard(G, vtupdate(Vt1, Vt0), St1),
Vt2 = vtupdate(Gvt, Vt1),
- {Bvt,St3} = exprs(B, Vt2, St2),
+ {Bvt,St3} = exprs(B, vtupdate(Vt2, Vt0), St2),
{vtupdate(Bvt, Vt2),St3}.
-icrt_export(Csvt, Vt, In, St) ->
- Vt1 = vtmerge(Csvt),
- All = ordsets:subtract(vintersection(Csvt), vtnames(Vt)),
- Some = ordsets:subtract(vtnames(Vt1), vtnames(Vt)),
- Xvt = vtexport(All, In, []),
- Evt = vtunsafe(ordsets:subtract(Some, All), In, Xvt),
- Unused = vtmerge([unused_vars(Vt0, Vt, St) || Vt0 <- Csvt]),
- %% Exported and unsafe variables may be unused:
- Uvt = vtmerge(Evt, Unused),
- %% Make exported and unsafe unused variables unused in subsequent code:
- Vt2 = vtmerge(Uvt, vtsubtract(Vt1, Uvt)),
- %% Forget about old variables which were not used:
- Vt3 = vtmerge(vtnew(Vt2, Vt), vt_no_unused(vtold(Vt2, Vt))),
- {Vt3,St}.
+icrt_export(Vts, Vt, {Tag,Attrs}, St) ->
+ {_File,Loc} = loc(Attrs, St),
+ icrt_export(lists:merge(Vts), Vt, {Tag,Loc}, length(Vts), []).
+
+icrt_export([{V,{{export,_},_,_}}|Vs0], [{V,{{export,_}=S0,_,Ls}}|Vt],
+ In, I, Acc) ->
+ %% V was an exported variable and has been used in an expression in at least
+ %% one clause. Its state needs to be merged from all clauses to silence any
+ %% exported var warning already emitted.
+ {VVs,Vs} = lists:partition(fun ({K,_}) -> K =:= V end, Vs0),
+ S = foldl(fun ({_,{S1,_,_}}, AccS) -> merge_state(AccS, S1) end, S0, VVs),
+ icrt_export(Vs, Vt, In, I, [{V,{S,used,Ls}}|Acc]);
+icrt_export([{V,_}|Vs0], [{V,{_,_,Ls}}|Vt], In, I, Acc) ->
+ %% V was either unsafe or bound and has now been reused. It may also have
+ %% been an export but as it was not matched by the previous clause, it means
+ %% it has been changed to 'bound' in at least one clause because it was used
+ %% in a pattern.
+ Vs = lists:dropwhile(fun ({K,_}) -> K =:= V end, Vs0),
+ icrt_export(Vs, Vt, In, I, [{V,{bound,used,Ls}}|Acc]);
+icrt_export([{V1,_}|_]=Vs, [{V2,_}|Vt], In, I, Acc) when V1 > V2 ->
+ %% V2 was already in scope and has not been reused in any clause.
+ icrt_export(Vs, Vt, In, I, Acc);
+icrt_export([{V,_}|_]=Vs0, Vt, In, I, Acc) ->
+ %% V is a new variable.
+ {VVs,Vs} = lists:partition(fun ({K,_}) -> K =:= V end, Vs0),
+ F = fun ({_,{S,U,Ls}}, {AccI,AccS0,AccLs0}) ->
+ AccS = case {S,AccS0} of
+ {{unsafe,_},{unsafe,_}} ->
+ %% V was found unsafe in a previous clause, mark
+ %% it as unsafe for the whole parent expression.
+ {unsafe,In};
+ {{unsafe,_},_} ->
+ %% V was unsafe in a clause, keep that state and
+ %% generalize it to the whole expression if it
+ %% is found unsafe in another one.
+ S;
+ _ ->
+ %% V is either bound or exported, keep original
+ %% state.
+ AccS0
+ end,
+ AccLs = case U of
+ used -> AccLs0;
+ unused -> merge_lines(AccLs0, Ls)
+ end,
+ {AccI + 1,AccS,AccLs}
+ end,
+ %% Initial state is exported from the current expression.
+ {Count,S1,Ls} = foldl(F, {0,{export,In},[]}, VVs),
+ S = case Count of
+ I ->
+ %% V was found in all clauses, keep computed state.
+ S1;
+ _ ->
+ %% V was not bound in some clauses, mark as unsafe.
+ {unsafe,In}
+ end,
+ U = case Ls of [] -> used; _ -> unused end,
+ icrt_export(Vs, Vt, In, I, [{V,{S,U,Ls}}|Acc]);
+icrt_export([], _, _, _, Acc) ->
+ reverse(Acc).
handle_comprehension(E, Qs, Vt0, St0) ->
{Vt1, Uvt, St1} = lc_quals(Qs, Vt0, St0),
@@ -3163,7 +3217,8 @@ fun_clauses(Cs, Vt, St) ->
{Cvt,St1} = fun_clause(C, Vt, St0),
{vtmerge(Cvt, Bvt0),St1}
end, {[],St#lint{recdef_top = false}}, Cs),
- {vt_no_unused(vtold(Bvt, Vt)),St2#lint{recdef_top = OldRecDef}}.
+ Uvt = vt_no_unsafe(vt_no_unused(vtold(Bvt, Vt))),
+ {Uvt,St2#lint{recdef_top = OldRecDef}}.
fun_clause({clause,_Line,H,G,B}, Vt0, St0) ->
{Hvt,Binvt,St1} = head(H, Vt0, [], St0), % No imported pattern variables
@@ -3277,19 +3332,24 @@ pat_binsize_var(V, Line, Vt, Bvt, St) ->
%% exported vars are probably safe, warn only if warn_export_vars is
%% set.
-expr_var(V, Line, Vt, St0) ->
+expr_var(V, Line, Vt, St) ->
case orddict:find(V, Vt) of
{ok,{bound,_Usage,Ls}} ->
- {[{V,{bound,used,Ls}}],St0};
+ {[{V,{bound,used,Ls}}],St};
{ok,{{unsafe,In},_Usage,Ls}} ->
{[{V,{bound,used,Ls}}],
- add_error(Line, {unsafe_var,V,In}, St0)};
+ add_error(Line, {unsafe_var,V,In}, St)};
{ok,{{export,From},_Usage,Ls}} ->
- {[{V,{bound,used,Ls}}],
- exported_var(Line, V, From, St0)};
+ case is_warn_enabled(export_vars, St) of
+ true ->
+ {[{V,{bound,used,Ls}}],
+ add_warning(Line, {exported_var,V,From}, St)};
+ false ->
+ {[{V,{{export,From},used,Ls}}],St}
+ end;
error ->
{[{V,{bound,used,[Line]}}],
- add_error(Line, {unbound_var,V}, St0)}
+ add_error(Line, {unbound_var,V}, St)}
end.
exported_var(Line, V, From, St) ->
@@ -3353,17 +3413,12 @@ vtupdate(Uvt, Vt0) ->
{S, merge_used(U1, U2), merge_lines(L1, L2)}
end, Uvt, Vt0).
-%% vtexport([Variable], From, VarTable) -> VarTable.
-%% vtunsafe([Variable], From, VarTable) -> VarTable.
-%% Add the variables to VarTable either as exported from From or as unsafe.
+%% vtunsafe(From, UpdVarTable, VarTable) -> UnsafeVarTable.
+%% Return all new variables in UpdVarTable as unsafe.
-vtexport(Vs, {InTag,FileLine}, Vt0) ->
- {_File,Line} = loc(FileLine),
- vtupdate([{V,{{export,{InTag,Line}},unused,[]}} || V <- Vs], Vt0).
-
-vtunsafe(Vs, {InTag,FileLine}, Vt0) ->
- {_File,Line} = loc(FileLine),
- vtupdate([{V,{{unsafe,{InTag,Line}},unused,[]}} || V <- Vs], Vt0).
+vtunsafe({Tag,FileLine}, Uvt, Vt) ->
+ Line = erl_anno:location(FileLine),
+ [{V,{{unsafe,{Tag,Line}},U,Ls}} || {V,{_,U,Ls}} <- vtnew(Uvt, Vt)].
%% vtmerge(VarTable, VarTable) -> VarTable.
%% Merge two variables tables generating a new vartable. Give priority to
@@ -3416,8 +3471,6 @@ vtsubtract(New, Old) ->
vtold(New, Old) ->
orddict:filter(fun (V, _How) -> orddict:is_key(V, Old) end, New).
-vtnames(Vt) -> [ V || {V,_How} <- Vt ].
-
vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt,
case S of
{unsafe,_} -> false;
@@ -3426,84 +3479,18 @@ vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt,
vt_no_unused(Vt) -> [V || {_,{_,U,_L}}=V <- Vt, U =/= unused].
-%% vunion(VarTable1, VarTable2) -> [VarName].
-%% vunion([VarTable]) -> [VarName].
-%% vintersection(VarTable1, VarTable2) -> [VarName].
-%% vintersection([VarTable]) -> [VarName].
-%% Union/intersection of names of vars in VarTable.
-
--ifdef(NOTUSED).
-vunion(Vs1, Vs2) -> ordsets:union(vtnames(Vs1), vtnames(Vs2)).
-
-vunion(Vss) -> foldl(fun (Vs, Uvs) ->
- ordsets:union(vtnames(Vs), Uvs)
- end, [], Vss).
-
-vintersection(Vs1, Vs2) -> ordsets:intersection(vtnames(Vs1), vtnames(Vs2)).
--endif.
-
-vintersection([Vs]) ->
- vtnames(Vs); %Boundary conditions!!!
-vintersection([Vs|Vss]) ->
- ordsets:intersection(vtnames(Vs), vintersection(Vss));
-vintersection([]) ->
- [].
-
%% copy_expr(Expr, Line) -> Expr.
%% Make a copy of Expr converting all line numbers to Line.
-copy_expr(Expr, Line) ->
- modify_line(Expr, fun(_L) -> Line end).
+copy_expr(Expr, Anno) ->
+ erl_parse:map_anno(fun(_A) -> Anno end, Expr).
%% modify_line(Form, Fun) -> Form
%% modify_line(Expression, Fun) -> Expression
%% Applies Fun to each line number occurrence.
modify_line(T, F0) ->
- modify_line1(T, F0).
-
-%% Forms.
-modify_line1({function,F,A}, _Mf) -> {function,F,A};
-modify_line1({function,M,F,A}, Mf) ->
- {function,modify_line1(M, Mf),modify_line1(F, Mf),modify_line1(A, Mf)};
-modify_line1({attribute,L,record,{Name,Fields}}, Mf) ->
- {attribute,Mf(L),record,{Name,modify_line1(Fields, Mf)}};
-modify_line1({attribute,L,spec,{Fun,Types}}, Mf) ->
- {attribute,Mf(L),spec,{Fun,modify_line1(Types, Mf)}};
-modify_line1({attribute,L,callback,{Fun,Types}}, Mf) ->
- {attribute,Mf(L),callback,{Fun,modify_line1(Types, Mf)}};
-modify_line1({attribute,L,type,{TypeName,TypeDef,Args}}, Mf) ->
- {attribute,Mf(L),type,{TypeName,modify_line1(TypeDef, Mf),
- modify_line1(Args, Mf)}};
-modify_line1({attribute,L,opaque,{TypeName,TypeDef,Args}}, Mf) ->
- {attribute,Mf(L),opaque,{TypeName,modify_line1(TypeDef, Mf),
- modify_line1(Args, Mf)}};
-modify_line1({attribute,L,Attr,Val}, Mf) -> {attribute,Mf(L),Attr,Val};
-modify_line1({warning,W}, _Mf) -> {warning,W};
-modify_line1({error,W}, _Mf) -> {error,W};
-%% Expressions.
-modify_line1({clauses,Cs}, Mf) -> {clauses,modify_line1(Cs, Mf)};
-modify_line1({typed_record_field,Field,Type}, Mf) ->
- {typed_record_field,modify_line1(Field, Mf),modify_line1(Type, Mf)};
-modify_line1({Tag,L}, Mf) -> {Tag,Mf(L)};
-modify_line1({Tag,L,E1}, Mf) ->
- {Tag,Mf(L),modify_line1(E1, Mf)};
-modify_line1({Tag,L,E1,E2}, Mf) ->
- {Tag,Mf(L),modify_line1(E1, Mf),modify_line1(E2, Mf)};
-modify_line1({bin_element,L,E1,E2,TSL}, Mf) ->
- {bin_element,Mf(L),modify_line1(E1, Mf),modify_line1(E2, Mf), TSL};
-modify_line1({Tag,L,E1,E2,E3}, Mf) ->
- {Tag,Mf(L),modify_line1(E1, Mf),modify_line1(E2, Mf),modify_line1(E3, Mf)};
-modify_line1({Tag,L,E1,E2,E3,E4}, Mf) ->
- {Tag,Mf(L),
- modify_line1(E1, Mf),
- modify_line1(E2, Mf),
- modify_line1(E3, Mf),
- modify_line1(E4, Mf)};
-modify_line1([H|T], Mf) ->
- [modify_line1(H, Mf)|modify_line1(T, Mf)];
-modify_line1([], _Mf) -> [];
-modify_line1(E, _Mf) when not is_tuple(E), not is_list(E) -> E.
+ erl_parse:map_anno(F0, T).
%% Check a record_info call. We have already checked that it is not
%% shadowed by an import.
@@ -3545,6 +3532,8 @@ check_qlc_hrl(Line, M, F, As, St) ->
%% deprecated_function(Line, ModName, FuncName, [Arg], State) -> State.
%% Add warning for calls to deprecated functions.
+-dialyzer({no_match, deprecated_function/5}).
+
deprecated_function(Line, M, F, As, St) ->
Arity = length(As),
MFA = {M, F, Arity},
@@ -3573,6 +3562,22 @@ deprecated_function(Line, M, F, As, St) ->
St
end.
+-dialyzer({no_match, deprecated_type/5}).
+
+deprecated_type(L, M, N, As, St) ->
+ NAs = length(As),
+ case otp_internal:obsolete_type(M, N, NAs) of
+ {deprecated, String} when is_list(String) ->
+ case is_warn_enabled(deprecated_type, St) of
+ true ->
+ add_warning(L, {deprecated_type, {M,N,NAs}, String}, St);
+ false ->
+ St
+ end;
+ no ->
+ St
+ end.
+
obsolete_guard({call,Line,{atom,Lr,F},As}, St0) ->
Arity = length(As),
case erl_internal:old_type_test(F, Arity) of
@@ -3800,8 +3805,7 @@ is_autoimport_suppressed(NoAutoSet,{Func,Arity}) ->
gb_sets:is_element({Func,Arity},NoAutoSet).
%% Predicate to find out if a function specific bif-clash suppression (old deprecated) is present
bif_clash_specifically_disabled(St,{F,A}) ->
- Nowarn = nowarn_function(nowarn_bif_clash, St#lint.compile),
- lists:member({F,A},Nowarn).
+ lists:member({F,A},St#lint.nowarn_bif_clash).
%% Predicate to find out if an autoimported guard_bif is not overriden in some way
%% Guard Bif without module name is disallowed if
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 1d4a2a1fef..e82282421e 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -42,7 +43,6 @@ function_call argument_list
exprs guard
atomic strings
prefix_op mult_op add_op list_op comp_op
-rule rule_clauses rule_clause rule_body
binary bin_elements bin_element bit_expr
opt_bit_size_expr bit_size_expr opt_bit_type_list bit_type_list bit_type
top_type top_type_100 top_types type typed_expr typed_attr_val
@@ -54,7 +54,7 @@ bin_base_type bin_unit_type type_200 type_300 type_400 type_500.
Terminals
char integer float atom string var
-'(' ')' ',' '->' ':-' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
+'(' ')' ',' '->' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
'after' 'begin' 'case' 'try' 'catch' 'end' 'fun' 'if' 'of' 'receive' 'when'
'andalso' 'orelse'
'bnot' 'not'
@@ -73,7 +73,6 @@ Rootsymbol form.
form -> attribute dot : '$1'.
form -> function dot : '$1'.
-form -> rule dot : '$1'.
attribute -> '-' atom attr_val : build_attribute('$2', '$3').
attribute -> '-' atom typed_attr_val : build_typed_attribute('$2','$3').
@@ -94,7 +93,7 @@ spec_fun -> atom ':' atom '/' integer '::' : {'$1', '$3', '$5'}.
typed_attr_val -> expr ',' typed_record_fields : {typed_record, '$1', '$3'}.
typed_attr_val -> expr '::' top_type : {type_def, '$1', '$3'}.
-typed_record_fields -> '{' typed_exprs '}' : {tuple, ?line('$1'), '$2'}.
+typed_record_fields -> '{' typed_exprs '}' : {tuple, ?anno('$1'), '$2'}.
typed_exprs -> typed_expr : ['$1'].
typed_exprs -> typed_expr ',' typed_exprs : ['$1'|'$3'].
@@ -107,97 +106,93 @@ type_sigs -> type_sig : ['$1'].
type_sigs -> type_sig ';' type_sigs : ['$1'|'$3'].
type_sig -> fun_type : '$1'.
-type_sig -> fun_type 'when' type_guards : {type, ?line('$1'), bounded_fun,
+type_sig -> fun_type 'when' type_guards : {type, ?anno('$1'), bounded_fun,
['$1','$3']}.
type_guards -> type_guard : ['$1'].
type_guards -> type_guard ',' type_guards : ['$1'|'$3'].
-type_guard -> atom '(' top_types ')' : {type, ?line('$1'), constraint,
+type_guard -> atom '(' top_types ')' : {type, ?anno('$1'), constraint,
['$1', '$3']}.
type_guard -> var '::' top_type : build_def('$1', '$3').
top_types -> top_type : ['$1'].
top_types -> top_type ',' top_types : ['$1'|'$3'].
-top_type -> var '::' top_type_100 : {ann_type, ?line('$1'), ['$1','$3']}.
+top_type -> var '::' top_type_100 : {ann_type, ?anno('$1'), ['$1','$3']}.
top_type -> top_type_100 : '$1'.
top_type_100 -> type_200 : '$1'.
top_type_100 -> type_200 '|' top_type_100 : lift_unions('$1','$3').
-type_200 -> type_300 '..' type_300 : {type, ?line('$1'), range,
- [skip_paren('$1'),
- skip_paren('$3')]}.
+type_200 -> type_300 '..' type_300 : {type, ?anno('$1'), range,
+ ['$1', '$3']}.
type_200 -> type_300 : '$1'.
-type_300 -> type_300 add_op type_400 : ?mkop2(skip_paren('$1'),
- '$2', skip_paren('$3')).
+type_300 -> type_300 add_op type_400 : ?mkop2('$1', '$2', '$3').
type_300 -> type_400 : '$1'.
-type_400 -> type_400 mult_op type_500 : ?mkop2(skip_paren('$1'),
- '$2', skip_paren('$3')).
+type_400 -> type_400 mult_op type_500 : ?mkop2('$1', '$2', '$3').
type_400 -> type_500 : '$1'.
-type_500 -> prefix_op type : ?mkop1('$1', skip_paren('$2')).
+type_500 -> prefix_op type : ?mkop1('$1', '$2').
type_500 -> type : '$1'.
-type -> '(' top_type ')' : {paren_type, ?line('$2'), ['$2']}.
+type -> '(' top_type ')' : '$2'.
type -> var : '$1'.
type -> atom : '$1'.
type -> atom '(' ')' : build_gen_type('$1').
-type -> atom '(' top_types ')' : {type, ?line('$1'),
- normalise('$1'), '$3'}.
-type -> atom ':' atom '(' ')' : {remote_type, ?line('$1'),
+type -> atom '(' top_types ')' : build_type('$1', '$3').
+type -> atom ':' atom '(' ')' : {remote_type, ?anno('$1'),
['$1', '$3', []]}.
-type -> atom ':' atom '(' top_types ')' : {remote_type, ?line('$1'),
+type -> atom ':' atom '(' top_types ')' : {remote_type, ?anno('$1'),
['$1', '$3', '$5']}.
-type -> '[' ']' : {type, ?line('$1'), nil, []}.
-type -> '[' top_type ']' : {type, ?line('$1'), list, ['$2']}.
-type -> '[' top_type ',' '...' ']' : {type, ?line('$1'),
+type -> '[' ']' : {type, ?anno('$1'), nil, []}.
+type -> '[' top_type ']' : {type, ?anno('$1'), list, ['$2']}.
+type -> '[' top_type ',' '...' ']' : {type, ?anno('$1'),
nonempty_list, ['$2']}.
-type -> '#' '{' '}' : {type, ?line('$1'), map, []}.
-type -> '#' '{' map_pair_types '}' : {type, ?line('$1'), map, '$3'}.
-type -> '{' '}' : {type, ?line('$1'), tuple, []}.
-type -> '{' top_types '}' : {type, ?line('$1'), tuple, '$2'}.
-type -> '#' atom '{' '}' : {type, ?line('$1'), record, ['$2']}.
-type -> '#' atom '{' field_types '}' : {type, ?line('$1'),
+type -> '#' '{' '}' : {type, ?anno('$1'), map, []}.
+type -> '#' '{' map_pair_types '}' : {type, ?anno('$1'), map, '$3'}.
+type -> '{' '}' : {type, ?anno('$1'), tuple, []}.
+type -> '{' top_types '}' : {type, ?anno('$1'), tuple, '$2'}.
+type -> '#' atom '{' '}' : {type, ?anno('$1'), record, ['$2']}.
+type -> '#' atom '{' field_types '}' : {type, ?anno('$1'),
record, ['$2'|'$4']}.
type -> binary_type : '$1'.
type -> integer : '$1'.
-type -> 'fun' '(' ')' : {type, ?line('$1'), 'fun', []}.
+type -> 'fun' '(' ')' : {type, ?anno('$1'), 'fun', []}.
type -> 'fun' '(' fun_type_100 ')' : '$3'.
fun_type_100 -> '(' '...' ')' '->' top_type
- : {type, ?line('$1'), 'fun',
- [{type, ?line('$1'), any}, '$5']}.
+ : {type, ?anno('$1'), 'fun',
+ [{type, ?anno('$1'), any}, '$5']}.
fun_type_100 -> fun_type : '$1'.
-fun_type -> '(' ')' '->' top_type : {type, ?line('$1'), 'fun',
- [{type, ?line('$1'), product, []}, '$4']}.
+fun_type -> '(' ')' '->' top_type : {type, ?anno('$1'), 'fun',
+ [{type, ?anno('$1'), product, []}, '$4']}.
fun_type -> '(' top_types ')' '->' top_type
- : {type, ?line('$1'), 'fun',
- [{type, ?line('$1'), product, '$2'},'$5']}.
+ : {type, ?anno('$1'), 'fun',
+ [{type, ?anno('$1'), product, '$2'},'$5']}.
map_pair_types -> map_pair_type : ['$1'].
map_pair_types -> map_pair_type ',' map_pair_types : ['$1'|'$3'].
-map_pair_type -> top_type '=>' top_type : {type, ?line('$2'), map_field_assoc,'$1','$3'}.
+map_pair_type -> top_type '=>' top_type : {type, ?anno('$2'), map_field_assoc,['$1','$3']}.
field_types -> field_type : ['$1'].
field_types -> field_type ',' field_types : ['$1'|'$3'].
-field_type -> atom '::' top_type : {type, ?line('$1'), field_type,
+field_type -> atom '::' top_type : {type, ?anno('$1'), field_type,
['$1', '$3']}.
-binary_type -> '<<' '>>' : {type, ?line('$1'),binary,
- [abstract(0, ?line('$1')),
- abstract(0, ?line('$1'))]}.
-binary_type -> '<<' bin_base_type '>>' : {type, ?line('$1'),binary,
- ['$2', abstract(0, ?line('$1'))]}.
-binary_type -> '<<' bin_unit_type '>>' : {type, ?line('$1'),binary,
- [abstract(0, ?line('$1')), '$2']}.
+binary_type -> '<<' '>>' : {type, ?anno('$1'),binary,
+ [abstract2(0, ?anno('$1')),
+ abstract2(0, ?anno('$1'))]}.
+binary_type -> '<<' bin_base_type '>>' : {type, ?anno('$1'),binary,
+ ['$2', abstract2(0, ?anno('$1'))]}.
+binary_type -> '<<' bin_unit_type '>>' : {type, ?anno('$1'),binary,
+ [abstract2(0, ?anno('$1')), '$2']}.
binary_type -> '<<' bin_base_type ',' bin_unit_type '>>'
- : {type, ?line('$1'), binary, ['$2', '$4']}.
+ : {type, ?anno('$1'), binary, ['$2', '$4']}.
bin_base_type -> var ':' type : build_bin_type(['$1'], '$3').
@@ -213,7 +208,7 @@ function_clauses -> function_clause : ['$1'].
function_clauses -> function_clause ';' function_clauses : ['$1'|'$3'].
function_clause -> atom clause_args clause_guard clause_body :
- {clause,?line('$1'),element(3, '$1'),'$2','$3','$4'}.
+ {clause,?anno('$1'),element(3, '$1'),'$2','$3','$4'}.
clause_args -> argument_list : element(1, '$1').
@@ -224,10 +219,10 @@ clause_guard -> '$empty' : [].
clause_body -> '->' exprs: '$2'.
-expr -> 'catch' expr : {'catch',?line('$1'),'$2'}.
+expr -> 'catch' expr : {'catch',?anno('$1'),'$2'}.
expr -> expr_100 : '$1'.
-expr_100 -> expr_150 '=' expr_100 : {match,?line('$2'),'$1','$3'}.
+expr_100 -> expr_150 '=' expr_100 : {match,?anno('$2'),'$1','$3'}.
expr_100 -> expr_150 '!' expr_100 : ?mkop2('$1', '$2', '$3').
expr_100 -> expr_150 : '$1'.
@@ -263,7 +258,7 @@ expr_700 -> record_expr : '$1'.
expr_700 -> expr_800 : '$1'.
expr_800 -> expr_max ':' expr_max :
- {remote,?line('$2'),'$1','$3'}.
+ {remote,?anno('$2'),'$1','$3'}.
expr_800 -> expr_max : '$1'.
expr_max -> var : '$1'.
@@ -275,7 +270,7 @@ expr_max -> binary_comprehension : '$1'.
expr_max -> tuple : '$1'.
%%expr_max -> struct : '$1'.
expr_max -> '(' expr ')' : '$2'.
-expr_max -> 'begin' exprs 'end' : {block,?line('$1'),'$2'}.
+expr_max -> 'begin' exprs 'end' : {block,?anno('$1'),'$2'}.
expr_max -> if_expr : '$1'.
expr_max -> case_expr : '$1'.
expr_max -> receive_expr : '$1'.
@@ -283,22 +278,22 @@ expr_max -> fun_expr : '$1'.
expr_max -> try_expr : '$1'.
-list -> '[' ']' : {nil,?line('$1')}.
-list -> '[' expr tail : {cons,?line('$1'),'$2','$3'}.
+list -> '[' ']' : {nil,?anno('$1')}.
+list -> '[' expr tail : {cons,?anno('$1'),'$2','$3'}.
-tail -> ']' : {nil,?line('$1')}.
+tail -> ']' : {nil,?anno('$1')}.
tail -> '|' expr ']' : '$2'.
-tail -> ',' expr tail : {cons,?line('$2'),'$2','$3'}.
+tail -> ',' expr tail : {cons,?anno('$2'),'$2','$3'}.
-binary -> '<<' '>>' : {bin,?line('$1'),[]}.
-binary -> '<<' bin_elements '>>' : {bin,?line('$1'),'$2'}.
+binary -> '<<' '>>' : {bin,?anno('$1'),[]}.
+binary -> '<<' bin_elements '>>' : {bin,?anno('$1'),'$2'}.
bin_elements -> bin_element : ['$1'].
bin_elements -> bin_element ',' bin_elements : ['$1'|'$3'].
bin_element -> bit_expr opt_bit_size_expr opt_bit_type_list :
- {bin_element,?line('$1'),'$1','$2','$3'}.
+ {bin_element,?anno('$1'),'$1','$2','$3'}.
bit_expr -> prefix_op expr_max : ?mkop1('$1', '$2').
bit_expr -> expr_max : '$1'.
@@ -319,29 +314,29 @@ bit_size_expr -> expr_max : '$1'.
list_comprehension -> '[' expr '||' lc_exprs ']' :
- {lc,?line('$1'),'$2','$4'}.
+ {lc,?anno('$1'),'$2','$4'}.
binary_comprehension -> '<<' binary '||' lc_exprs '>>' :
- {bc,?line('$1'),'$2','$4'}.
+ {bc,?anno('$1'),'$2','$4'}.
lc_exprs -> lc_expr : ['$1'].
lc_exprs -> lc_expr ',' lc_exprs : ['$1'|'$3'].
lc_expr -> expr : '$1'.
-lc_expr -> expr '<-' expr : {generate,?line('$2'),'$1','$3'}.
-lc_expr -> binary '<=' expr : {b_generate,?line('$2'),'$1','$3'}.
+lc_expr -> expr '<-' expr : {generate,?anno('$2'),'$1','$3'}.
+lc_expr -> binary '<=' expr : {b_generate,?anno('$2'),'$1','$3'}.
-tuple -> '{' '}' : {tuple,?line('$1'),[]}.
-tuple -> '{' exprs '}' : {tuple,?line('$1'),'$2'}.
+tuple -> '{' '}' : {tuple,?anno('$1'),[]}.
+tuple -> '{' exprs '}' : {tuple,?anno('$1'),'$2'}.
%%struct -> atom tuple :
-%% {struct,?line('$1'),element(3, '$1'),element(3, '$2')}.
+%% {struct,?anno('$1'),element(3, '$1'),element(3, '$2')}.
map_expr -> '#' map_tuple :
- {map, ?line('$1'),'$2'}.
+ {map, ?anno('$1'),'$2'}.
map_expr -> expr_max '#' map_tuple :
- {map, ?line('$2'),'$1','$3'}.
+ {map, ?anno('$2'),'$1','$3'}.
map_expr -> map_expr '#' map_tuple :
- {map, ?line('$2'),'$1','$3'}.
+ {map, ?anno('$2'),'$1','$3'}.
map_tuple -> '{' '}' : [].
map_tuple -> '{' map_fields '}' : '$2'.
@@ -353,10 +348,10 @@ map_field -> map_field_assoc : '$1'.
map_field -> map_field_exact : '$1'.
map_field_assoc -> map_key '=>' expr :
- {map_field_assoc,?line('$1'),'$1','$3'}.
+ {map_field_assoc,?anno('$1'),'$1','$3'}.
map_field_exact -> map_key ':=' expr :
- {map_field_exact,?line('$1'),'$1','$3'}.
+ {map_field_exact,?anno('$1'),'$1','$3'}.
map_key -> expr : '$1'.
@@ -366,17 +361,17 @@ map_key -> expr : '$1'.
%% always atoms for the moment, this might change in the future.
record_expr -> '#' atom '.' atom :
- {record_index,?line('$1'),element(3, '$2'),'$4'}.
+ {record_index,?anno('$1'),element(3, '$2'),'$4'}.
record_expr -> '#' atom record_tuple :
- {record,?line('$1'),element(3, '$2'),'$3'}.
+ {record,?anno('$1'),element(3, '$2'),'$3'}.
record_expr -> expr_max '#' atom '.' atom :
- {record_field,?line('$2'),'$1',element(3, '$3'),'$5'}.
+ {record_field,?anno('$2'),'$1',element(3, '$3'),'$5'}.
record_expr -> expr_max '#' atom record_tuple :
- {record,?line('$2'),'$1',element(3, '$3'),'$4'}.
+ {record,?anno('$2'),'$1',element(3, '$3'),'$4'}.
record_expr -> record_expr '#' atom '.' atom :
- {record_field,?line('$2'),'$1',element(3, '$3'),'$5'}.
+ {record_field,?anno('$2'),'$1',element(3, '$3'),'$5'}.
record_expr -> record_expr '#' atom record_tuple :
- {record,?line('$2'),'$1',element(3, '$3'),'$4'}.
+ {record,?anno('$2'),'$1',element(3, '$3'),'$4'}.
record_tuple -> '{' '}' : [].
record_tuple -> '{' record_fields '}' : '$2'.
@@ -384,47 +379,47 @@ record_tuple -> '{' record_fields '}' : '$2'.
record_fields -> record_field : ['$1'].
record_fields -> record_field ',' record_fields : ['$1' | '$3'].
-record_field -> var '=' expr : {record_field,?line('$1'),'$1','$3'}.
-record_field -> atom '=' expr : {record_field,?line('$1'),'$1','$3'}.
+record_field -> var '=' expr : {record_field,?anno('$1'),'$1','$3'}.
+record_field -> atom '=' expr : {record_field,?anno('$1'),'$1','$3'}.
%% N.B. This is called from expr_700.
function_call -> expr_800 argument_list :
- {call,?line('$1'),'$1',element(1, '$2')}.
+ {call,?anno('$1'),'$1',element(1, '$2')}.
-if_expr -> 'if' if_clauses 'end' : {'if',?line('$1'),'$2'}.
+if_expr -> 'if' if_clauses 'end' : {'if',?anno('$1'),'$2'}.
if_clauses -> if_clause : ['$1'].
if_clauses -> if_clause ';' if_clauses : ['$1' | '$3'].
if_clause -> guard clause_body :
- {clause,?line(hd(hd('$1'))),[],'$1','$2'}.
+ {clause,?anno(hd(hd('$1'))),[],'$1','$2'}.
case_expr -> 'case' expr 'of' cr_clauses 'end' :
- {'case',?line('$1'),'$2','$4'}.
+ {'case',?anno('$1'),'$2','$4'}.
cr_clauses -> cr_clause : ['$1'].
cr_clauses -> cr_clause ';' cr_clauses : ['$1' | '$3'].
cr_clause -> expr clause_guard clause_body :
- {clause,?line('$1'),['$1'],'$2','$3'}.
+ {clause,?anno('$1'),['$1'],'$2','$3'}.
receive_expr -> 'receive' cr_clauses 'end' :
- {'receive',?line('$1'),'$2'}.
+ {'receive',?anno('$1'),'$2'}.
receive_expr -> 'receive' 'after' expr clause_body 'end' :
- {'receive',?line('$1'),[],'$3','$4'}.
+ {'receive',?anno('$1'),[],'$3','$4'}.
receive_expr -> 'receive' cr_clauses 'after' expr clause_body 'end' :
- {'receive',?line('$1'),'$2','$4','$5'}.
+ {'receive',?anno('$1'),'$2','$4','$5'}.
fun_expr -> 'fun' atom '/' integer :
- {'fun',?line('$1'),{function,element(3, '$2'),element(3, '$4')}}.
+ {'fun',?anno('$1'),{function,element(3, '$2'),element(3, '$4')}}.
fun_expr -> 'fun' atom_or_var ':' atom_or_var '/' integer_or_var :
- {'fun',?line('$1'),{function,'$2','$4','$6'}}.
+ {'fun',?anno('$1'),{function,'$2','$4','$6'}}.
fun_expr -> 'fun' fun_clauses 'end' :
- build_fun(?line('$1'), '$2').
+ build_fun(?anno('$1'), '$2').
atom_or_var -> atom : '$1'.
atom_or_var -> var : '$1'.
@@ -436,16 +431,16 @@ fun_clauses -> fun_clause : ['$1'].
fun_clauses -> fun_clause ';' fun_clauses : ['$1' | '$3'].
fun_clause -> argument_list clause_guard clause_body :
- {Args,Pos} = '$1',
- {clause,Pos,'fun',Args,'$2','$3'}.
+ {Args,Anno} = '$1',
+ {clause,Anno,'fun',Args,'$2','$3'}.
fun_clause -> var argument_list clause_guard clause_body :
{clause,element(2, '$1'),element(3, '$1'),element(1, '$2'),'$3','$4'}.
try_expr -> 'try' exprs 'of' cr_clauses try_catch :
- build_try(?line('$1'),'$2','$4','$5').
+ build_try(?anno('$1'),'$2','$4','$5').
try_expr -> 'try' exprs try_catch :
- build_try(?line('$1'),'$2',[],'$3').
+ build_try(?anno('$1'),'$2',[],'$3').
try_catch -> 'catch' try_clauses 'end' :
{'$2',[]}.
@@ -458,18 +453,18 @@ try_clauses -> try_clause : ['$1'].
try_clauses -> try_clause ';' try_clauses : ['$1' | '$3'].
try_clause -> expr clause_guard clause_body :
- L = ?line('$1'),
- {clause,L,[{tuple,L,[{atom,L,throw},'$1',{var,L,'_'}]}],'$2','$3'}.
+ A = ?anno('$1'),
+ {clause,A,[{tuple,A,[{atom,A,throw},'$1',{var,A,'_'}]}],'$2','$3'}.
try_clause -> atom ':' expr clause_guard clause_body :
- L = ?line('$1'),
- {clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}.
+ A = ?anno('$1'),
+ {clause,A,[{tuple,A,['$1','$3',{var,A,'_'}]}],'$4','$5'}.
try_clause -> var ':' expr clause_guard clause_body :
- L = ?line('$1'),
- {clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}.
+ A = ?anno('$1'),
+ {clause,A,[{tuple,A,['$1','$3',{var,A,'_'}]}],'$4','$5'}.
-argument_list -> '(' ')' : {[],?line('$1')}.
-argument_list -> '(' exprs ')' : {'$2',?line('$1')}.
+argument_list -> '(' ')' : {[],?anno('$1')}.
+argument_list -> '(' exprs ')' : {'$2',?anno('$1')}.
exprs -> expr : ['$1'].
@@ -486,7 +481,7 @@ atomic -> strings : '$1'.
strings -> string : '$1'.
strings -> string strings :
- {string,?line('$1'),element(3, '$1') ++ element(3, '$2')}.
+ {string,?anno('$1'),element(3, '$1') ++ element(3, '$2')}.
prefix_op -> '+' : '$1'.
prefix_op -> '-' : '$1'.
@@ -521,25 +516,21 @@ comp_op -> '>' : '$1'.
comp_op -> '=:=' : '$1'.
comp_op -> '=/=' : '$1'.
-rule -> rule_clauses : build_rule('$1').
-
-rule_clauses -> rule_clause : ['$1'].
-rule_clauses -> rule_clause ';' rule_clauses : ['$1'|'$3'].
-
-rule_clause -> atom clause_args clause_guard rule_body :
- {clause,?line('$1'),element(3, '$1'),'$2','$3','$4'}.
-
-rule_body -> ':-' lc_exprs: '$2'.
-
-
Erlang code.
-export([parse_form/1,parse_exprs/1,parse_term/1]).
-export([normalise/1,abstract/1,tokens/1,tokens/2]).
-export([abstract/2]).
-export([inop_prec/1,preop_prec/1,func_prec/0,max_prec/0]).
+-export([type_inop_prec/1,type_preop_prec/1]).
+-export([map_anno/2, fold_anno/3, mapfold_anno/3,
+ new_anno/1, anno_to_term/1, anno_from_term/1]).
-export([set_line/2,get_attribute/2,get_attributes/1]).
+-deprecated([{set_line, 2, next_major_release},
+ {get_attribute, 2, next_major_release},
+ {get_attributes, 1, next_major_release}]).
+
%% The following directive is needed for (significantly) faster compilation
%% of the generated .erl file by the HiPE compiler. Please do not remove.
-compile([{hipe,[{regalloc,linear_scan}]}]).
@@ -547,30 +538,31 @@ Erlang code.
-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
error_info/0]).
+%% XXX. To be refined.
-type abstract_clause() :: term().
-type abstract_expr() :: term().
-type abstract_form() :: term().
-type error_description() :: term().
--type error_info() :: {erl_scan:line(), module(), error_description()}.
+-type error_info() :: {erl_anno:line(), module(), error_description()}.
-type token() :: erl_scan:token().
-%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
-%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
+%% mkop(Op, Arg) -> {op,Anno,Op,Arg}.
+%% mkop(Left, Op, Right) -> {op,Anno,Op,Left,Right}.
--define(mkop2(L, OpPos, R),
+-define(mkop2(L, OpAnno, R),
begin
- {Op,Pos} = OpPos,
- {op,Pos,Op,L,R}
+ {Op,Anno} = OpAnno,
+ {op,Anno,Op,L,R}
end).
--define(mkop1(OpPos, A),
+-define(mkop1(OpAnno, A),
begin
- {Op,Pos} = OpPos,
- {op,Pos,Op,A}
+ {Op,Anno} = OpAnno,
+ {op,Anno,Op,A}
end).
-%% keep track of line info in tokens
--define(line(Tup), element(2, Tup)).
+%% keep track of annotation info in tokens
+-define(anno(Tup), element(2, Tup)).
%% Entry points compatible to old erl_parse.
%% These really suck and are only here until Calle gets multiple
@@ -580,10 +572,10 @@ Erlang code.
Tokens :: [token()],
AbsForm :: abstract_form(),
ErrorInfo :: error_info().
-parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
- parse([{'-',L1},{'spec',L2}|Tokens]);
-parse_form([{'-',L1},{atom,L2,callback}|Tokens]) ->
- parse([{'-',L1},{'callback',L2}|Tokens]);
+parse_form([{'-',A1},{atom,A2,spec}|Tokens]) ->
+ parse([{'-',A1},{'spec',A2}|Tokens]);
+parse_form([{'-',A1},{atom,A2,callback}|Tokens]) ->
+ parse([{'-',A1},{'callback',A2}|Tokens]);
parse_form(Tokens) ->
parse(Tokens).
@@ -592,7 +584,8 @@ parse_form(Tokens) ->
ExprList :: [abstract_expr()],
ErrorInfo :: error_info().
parse_exprs(Tokens) ->
- case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
+ A = erl_anno:new(0),
+ case parse([{atom,A,f},{'(',A},{')',A},{'->',A}|Tokens]) of
{ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
{ok,Exprs};
{error,_} = Err -> Err
@@ -603,42 +596,43 @@ parse_exprs(Tokens) ->
Term :: term(),
ErrorInfo :: error_info().
parse_term(Tokens) ->
- case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
- {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[Expr]}]}} ->
+ A = erl_anno:new(0),
+ case parse([{atom,A,f},{'(',A},{')',A},{'->',A}|Tokens]) of
+ {ok,{function,_Af,f,0,[{clause,_Ac,[],[],[Expr]}]}} ->
try normalise(Expr) of
Term -> {ok,Term}
catch
- _:_R -> {error,{?line(Expr),?MODULE,"bad term"}}
+ _:_R -> {error,{location(?anno(Expr)),?MODULE,"bad term"}}
end;
- {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[_E1,E2|_Es]}]}} ->
- {error,{?line(E2),?MODULE,"bad term"}};
+ {ok,{function,_Af,f,A,[{clause,_Ac,[],[],[_E1,E2|_Es]}]}} ->
+ {error,{location(?anno(E2)),?MODULE,"bad term"}};
{error,_} = Err -> Err
end.
-type attributes() :: 'export' | 'file' | 'import' | 'module'
| 'opaque' | 'record' | 'type'.
-build_typed_attribute({atom,La,record},
- {typed_record, {atom,_Ln,RecordName}, RecTuple}) ->
- {attribute,La,record,{RecordName,record_tuple(RecTuple)}};
-build_typed_attribute({atom,La,Attr},
+build_typed_attribute({atom,Aa,record},
+ {typed_record, {atom,_An,RecordName}, RecTuple}) ->
+ {attribute,Aa,record,{RecordName,record_tuple(RecTuple)}};
+build_typed_attribute({atom,Aa,Attr},
{type_def, {call,_,{atom,_,TypeName},Args}, Type})
when Attr =:= 'type' ; Attr =:= 'opaque' ->
case lists:all(fun({var, _, _}) -> true;
(_) -> false
end, Args) of
- true -> {attribute,La,Attr,{TypeName,Type,Args}};
- false -> error_bad_decl(La, Attr)
+ true -> {attribute,Aa,Attr,{TypeName,Type,Args}};
+ false -> error_bad_decl(Aa, Attr)
end;
-build_typed_attribute({atom,La,Attr},_) ->
+build_typed_attribute({atom,Aa,Attr},_) ->
case Attr of
- record -> error_bad_decl(La, record);
- type -> error_bad_decl(La, type);
- opaque -> error_bad_decl(La, opaque);
- _ -> ret_err(La, "bad attribute")
+ record -> error_bad_decl(Aa, record);
+ type -> error_bad_decl(Aa, type);
+ opaque -> error_bad_decl(Aa, opaque);
+ _ -> ret_err(Aa, "bad attribute")
end.
-build_type_spec({Kind,La}, {SpecFun, TypeSpecs})
+build_type_spec({Kind,Aa}, {SpecFun, TypeSpecs})
when (Kind =:= spec) or (Kind =:= callback) ->
NewSpecFun =
case SpecFun of
@@ -653,7 +647,7 @@ build_type_spec({Kind,La}, {SpecFun, TypeSpecs})
%% Old style spec. Allow this for now.
{Mod,Fun,Arity}
end,
- {attribute,La,Kind,{NewSpecFun, TypeSpecs}}.
+ {attribute,Aa,Kind,{NewSpecFun, TypeSpecs}}.
find_arity_from_specs([Spec|_]) ->
%% Use the first spec to find the arity. If all are not the same,
@@ -665,99 +659,111 @@ find_arity_from_specs([Spec|_]) ->
{type, _, 'fun', [{type, _, product, Args},_]} = Fun,
length(Args).
+build_def({var, A, '_'}, _Types) ->
+ ret_err(A, "bad type variable");
build_def(LHS, Types) ->
- IsSubType = {atom, ?line(LHS), is_subtype},
- {type, ?line(LHS), constraint, [IsSubType, [LHS, Types]]}.
+ IsSubType = {atom, ?anno(LHS), is_subtype},
+ {type, ?anno(LHS), constraint, [IsSubType, [LHS, Types]]}.
-lift_unions(T1, {type, _La, union, List}) ->
- {type, ?line(T1), union, [T1|List]};
+lift_unions(T1, {type, _Aa, union, List}) ->
+ {type, ?anno(T1), union, [T1|List]};
lift_unions(T1, T2) ->
- {type, ?line(T1), union, [T1, T2]}.
-
-skip_paren({paren_type,_L,[Type]}) ->
- skip_paren(Type);
-skip_paren(Type) ->
- Type.
+ {type, ?anno(T1), union, [T1, T2]}.
-build_gen_type({atom, La, tuple}) ->
- {type, La, tuple, any};
-build_gen_type({atom, La, map}) ->
- {type, La, map, any};
-build_gen_type({atom, La, Name}) ->
- {type, La, Name, []}.
+build_gen_type({atom, Aa, tuple}) ->
+ {type, Aa, tuple, any};
+build_gen_type({atom, Aa, map}) ->
+ {type, Aa, map, any};
+build_gen_type({atom, Aa, Name}) ->
+ Tag = type_tag(Name, 0),
+ {Tag, Aa, Name, []}.
build_bin_type([{var, _, '_'}|Left], Int) ->
build_bin_type(Left, Int);
build_bin_type([], Int) ->
- skip_paren(Int);
-build_bin_type([{var, La, _}|_], _) ->
- ret_err(La, "Bad binary type").
+ Int;
+build_bin_type([{var, Aa, _}|_], _) ->
+ ret_err(Aa, "Bad binary type").
+
+build_type({atom, A, Name}, Types) ->
+ Tag = type_tag(Name, length(Types)),
+ {Tag, A, Name, Types}.
+
+type_tag(TypeName, NumberOfTypeVariables) ->
+ case erl_internal:is_type(TypeName, NumberOfTypeVariables) of
+ true -> type;
+ false -> user_type
+ end.
+
+abstract2(Term, Anno) ->
+ Line = erl_anno:line(Anno),
+ abstract(Term, Line).
%% build_attribute(AttrName, AttrValue) ->
-%% {attribute,Line,module,Module}
-%% {attribute,Line,export,Exports}
-%% {attribute,Line,import,Imports}
-%% {attribute,Line,record,{Name,Inits}}
-%% {attribute,Line,file,{Name,Line}}
-%% {attribute,Line,Name,Val}
-
-build_attribute({atom,La,module}, Val) ->
+%% {attribute,Anno,module,Module}
+%% {attribute,Anno,export,Exports}
+%% {attribute,Anno,import,Imports}
+%% {attribute,Anno,record,{Name,Inits}}
+%% {attribute,Anno,file,{Name,Line}}
+%% {attribute,Anno,Name,Val}
+
+build_attribute({atom,Aa,module}, Val) ->
case Val of
- [{atom,_Lm,Module}] ->
- {attribute,La,module,Module};
- [{atom,_Lm,Module},ExpList] ->
- {attribute,La,module,{Module,var_list(ExpList)}};
+ [{atom,_Am,Module}] ->
+ {attribute,Aa,module,Module};
+ [{atom,_Am,Module},ExpList] ->
+ {attribute,Aa,module,{Module,var_list(ExpList)}};
_Other ->
- error_bad_decl(La, module)
+ error_bad_decl(Aa, module)
end;
-build_attribute({atom,La,export}, Val) ->
+build_attribute({atom,Aa,export}, Val) ->
case Val of
[ExpList] ->
- {attribute,La,export,farity_list(ExpList)};
- _Other -> error_bad_decl(La, export)
+ {attribute,Aa,export,farity_list(ExpList)};
+ _Other -> error_bad_decl(Aa, export)
end;
-build_attribute({atom,La,import}, Val) ->
+build_attribute({atom,Aa,import}, Val) ->
case Val of
- [{atom,_Lm,Mod},ImpList] ->
- {attribute,La,import,{Mod,farity_list(ImpList)}};
- _Other -> error_bad_decl(La, import)
+ [{atom,_Am,Mod},ImpList] ->
+ {attribute,Aa,import,{Mod,farity_list(ImpList)}};
+ _Other -> error_bad_decl(Aa, import)
end;
-build_attribute({atom,La,record}, Val) ->
+build_attribute({atom,Aa,record}, Val) ->
case Val of
- [{atom,_Ln,Record},RecTuple] ->
- {attribute,La,record,{Record,record_tuple(RecTuple)}};
- _Other -> error_bad_decl(La, record)
+ [{atom,_An,Record},RecTuple] ->
+ {attribute,Aa,record,{Record,record_tuple(RecTuple)}};
+ _Other -> error_bad_decl(Aa, record)
end;
-build_attribute({atom,La,file}, Val) ->
+build_attribute({atom,Aa,file}, Val) ->
case Val of
- [{string,_Ln,Name},{integer,_Ll,Line}] ->
- {attribute,La,file,{Name,Line}};
- _Other -> error_bad_decl(La, file)
+ [{string,_An,Name},{integer,_Al,Line}] ->
+ {attribute,Aa,file,{Name,Line}};
+ _Other -> error_bad_decl(Aa, file)
end;
-build_attribute({atom,La,Attr}, Val) ->
+build_attribute({atom,Aa,Attr}, Val) ->
case Val of
[Expr0] ->
Expr = attribute_farity(Expr0),
- {attribute,La,Attr,term(Expr)};
- _Other -> ret_err(La, "bad attribute")
+ {attribute,Aa,Attr,term(Expr)};
+ _Other -> ret_err(Aa, "bad attribute")
end.
-var_list({cons,_Lc,{var,_,V},Tail}) ->
+var_list({cons,_Ac,{var,_,V},Tail}) ->
[V|var_list(Tail)];
-var_list({nil,_Ln}) -> [];
+var_list({nil,_An}) -> [];
var_list(Other) ->
- ret_err(?line(Other), "bad variable list").
+ ret_err(?anno(Other), "bad variable list").
-attribute_farity({cons,L,H,T}) ->
- {cons,L,attribute_farity(H),attribute_farity(T)};
-attribute_farity({tuple,L,Args0}) ->
+attribute_farity({cons,A,H,T}) ->
+ {cons,A,attribute_farity(H),attribute_farity(T)};
+attribute_farity({tuple,A,Args0}) ->
Args = attribute_farity_list(Args0),
- {tuple,L,Args};
-attribute_farity({map,L,Args0}) ->
+ {tuple,A,Args};
+attribute_farity({map,A,Args0}) ->
Args = attribute_farity_map(Args0),
- {map,L,Args};
-attribute_farity({op,L,'/',{atom,_,_}=Name,{integer,_,_}=Arity}) ->
- {tuple,L,[Name,Arity]};
+ {map,A,Args};
+attribute_farity({op,A,'/',{atom,_,_}=Name,{integer,_,_}=Arity}) ->
+ {tuple,A,[Name,Arity]};
attribute_farity(Other) -> Other.
attribute_farity_list(Args) ->
@@ -765,111 +771,97 @@ attribute_farity_list(Args) ->
%% It is not meaningful to have farity keys.
attribute_farity_map(Args) ->
- [{Op,L,K,attribute_farity(V)} || {Op,L,K,V} <- Args].
+ [{Op,A,K,attribute_farity(V)} || {Op,A,K,V} <- Args].
--spec error_bad_decl(integer(), attributes()) -> no_return().
+-spec error_bad_decl(erl_anno:anno(), attributes()) -> no_return().
-error_bad_decl(L, S) ->
- ret_err(L, io_lib:format("bad ~w declaration", [S])).
+error_bad_decl(Anno, S) ->
+ ret_err(Anno, io_lib:format("bad ~w declaration", [S])).
-farity_list({cons,_Lc,{op,_Lo,'/',{atom,_La,A},{integer,_Li,I}},Tail}) ->
+farity_list({cons,_Ac,{op,_Ao,'/',{atom,_Aa,A},{integer,_Ai,I}},Tail}) ->
[{A,I}|farity_list(Tail)];
-farity_list({nil,_Ln}) -> [];
+farity_list({nil,_An}) -> [];
farity_list(Other) ->
- ret_err(?line(Other), "bad function arity").
+ ret_err(?anno(Other), "bad function arity").
-record_tuple({tuple,_Lt,Fields}) ->
+record_tuple({tuple,_At,Fields}) ->
record_fields(Fields);
record_tuple(Other) ->
- ret_err(?line(Other), "bad record declaration").
+ ret_err(?anno(Other), "bad record declaration").
-record_fields([{atom,La,A}|Fields]) ->
- [{record_field,La,{atom,La,A}}|record_fields(Fields)];
-record_fields([{match,_Lm,{atom,La,A},Expr}|Fields]) ->
- [{record_field,La,{atom,La,A},Expr}|record_fields(Fields)];
+record_fields([{atom,Aa,A}|Fields]) ->
+ [{record_field,Aa,{atom,Aa,A}}|record_fields(Fields)];
+record_fields([{match,_Am,{atom,Aa,A},Expr}|Fields]) ->
+ [{record_field,Aa,{atom,Aa,A},Expr}|record_fields(Fields)];
record_fields([{typed,Expr,TypeInfo}|Fields]) ->
[Field] = record_fields([Expr]),
TypeInfo1 =
case Expr of
{match, _, _, _} -> TypeInfo; %% If we have an initializer.
- {atom, La, _} ->
+ {atom, Aa, _} ->
case has_undefined(TypeInfo) of
false ->
- TypeInfo2 = maybe_add_paren(TypeInfo),
- lift_unions(abstract(undefined, La), TypeInfo2);
+ lift_unions(abstract2(undefined, Aa), TypeInfo);
true ->
TypeInfo
end
end,
[{typed_record_field,Field,TypeInfo1}|record_fields(Fields)];
record_fields([Other|_Fields]) ->
- ret_err(?line(Other), "bad record field");
+ ret_err(?anno(Other), "bad record field");
record_fields([]) -> [].
has_undefined({atom,_,undefined}) ->
true;
has_undefined({ann_type,_,[_,T]}) ->
has_undefined(T);
-has_undefined({paren_type,_,[T]}) ->
- has_undefined(T);
has_undefined({type,_,union,Ts}) ->
lists:any(fun has_undefined/1, Ts);
has_undefined(_) ->
false.
-maybe_add_paren({ann_type,L,T}) ->
- {paren_type,L,[{ann_type,L,T}]};
-maybe_add_paren(T) ->
- T.
-
term(Expr) ->
try normalise(Expr)
- catch _:_R -> ret_err(?line(Expr), "bad attribute")
+ catch _:_R -> ret_err(?anno(Expr), "bad attribute")
end.
-%% build_function([Clause]) -> {function,Line,Name,Arity,[Clause]}
+%% build_function([Clause]) -> {function,Anno,Name,Arity,[Clause]}
build_function(Cs) ->
Name = element(3, hd(Cs)),
Arity = length(element(4, hd(Cs))),
- {function,?line(hd(Cs)),Name,Arity,check_clauses(Cs, Name, Arity)}.
+ {function,?anno(hd(Cs)),Name,Arity,check_clauses(Cs, Name, Arity)}.
-%% build_rule([Clause]) -> {rule,Line,Name,Arity,[Clause]'}
+%% build_fun(Anno, [Clause]) -> {'fun',Anno,{clauses,[Clause]}}.
-build_rule(Cs) ->
- Name = element(3, hd(Cs)),
- Arity = length(element(4, hd(Cs))),
- {rule,?line(hd(Cs)),Name,Arity,check_clauses(Cs, Name, Arity)}.
-
-%% build_fun(Line, [Clause]) -> {'fun',Line,{clauses,[Clause]}}.
-
-build_fun(Line, Cs) ->
+build_fun(Anno, Cs) ->
Name = element(3, hd(Cs)),
Arity = length(element(4, hd(Cs))),
CheckedCs = check_clauses(Cs, Name, Arity),
case Name of
'fun' ->
- {'fun',Line,{clauses,CheckedCs}};
+ {'fun',Anno,{clauses,CheckedCs}};
Name ->
- {named_fun,Line,Name,CheckedCs}
+ {named_fun,Anno,Name,CheckedCs}
end.
check_clauses(Cs, Name, Arity) ->
[case C of
- {clause,L,N,As,G,B} when N =:= Name, length(As) =:= Arity ->
- {clause,L,As,G,B};
- {clause,L,_N,_As,_G,_B} ->
- ret_err(L, "head mismatch")
+ {clause,A,N,As,G,B} when N =:= Name, length(As) =:= Arity ->
+ {clause,A,As,G,B};
+ {clause,A,_N,_As,_G,_B} ->
+ ret_err(A, "head mismatch")
end || C <- Cs].
-build_try(L,Es,Scs,{Ccs,As}) ->
- {'try',L,Es,Scs,Ccs,As}.
+build_try(A,Es,Scs,{Ccs,As}) ->
+ {'try',A,Es,Scs,Ccs,As}.
-spec ret_err(_, _) -> no_return().
-ret_err(L, S) ->
- {location,Location} = get_attribute(L, location),
- return_error(Location, S).
+ret_err(Anno, S) ->
+ return_error(location(Anno), S).
+location(Anno) ->
+ erl_anno:location(Anno).
%% Convert between the abstract form of a term and a term.
@@ -917,7 +909,8 @@ normalise_list([]) ->
Data :: term(),
AbsTerm :: abstract_expr().
abstract(T) ->
- abstract(T, 0, enc_func(epp:default_encoding())).
+ Anno = erl_anno:new(0),
+ abstract(T, Anno, enc_func(epp:default_encoding())).
-type encoding_func() :: fun((non_neg_integer()) -> boolean()).
@@ -927,16 +920,18 @@ abstract(T) ->
Options :: Line | [Option],
Option :: {line, Line} | {encoding, Encoding},
Encoding :: 'latin1' | 'unicode' | 'utf8' | 'none' | encoding_func(),
- Line :: erl_scan:line(),
+ Line :: erl_anno:line(),
AbsTerm :: abstract_expr().
abstract(T, Line) when is_integer(Line) ->
- abstract(T, Line, enc_func(epp:default_encoding()));
+ Anno = erl_anno:new(Line),
+ abstract(T, Anno, enc_func(epp:default_encoding()));
abstract(T, Options) when is_list(Options) ->
Line = proplists:get_value(line, Options, 0),
Encoding = proplists:get_value(encoding, Options,epp:default_encoding()),
EncFunc = enc_func(Encoding),
- abstract(T, Line, EncFunc).
+ Anno = erl_anno:new(Line),
+ abstract(T, Anno, EncFunc).
-define(UNICODE(C),
(C < 16#D800 orelse
@@ -950,53 +945,53 @@ enc_func(none) -> none;
enc_func(Fun) when is_function(Fun, 1) -> Fun;
enc_func(Term) -> erlang:error({badarg, Term}).
-abstract(T, L, _E) when is_integer(T) -> {integer,L,T};
-abstract(T, L, _E) when is_float(T) -> {float,L,T};
-abstract(T, L, _E) when is_atom(T) -> {atom,L,T};
-abstract([], L, _E) -> {nil,L};
-abstract(B, L, _E) when is_bitstring(B) ->
- {bin, L, [abstract_byte(Byte, L) || Byte <- bitstring_to_list(B)]};
-abstract([H|T], L, none=E) ->
- {cons,L,abstract(H, L, E),abstract(T, L, E)};
-abstract(List, L, E) when is_list(List) ->
- abstract_list(List, [], L, E);
-abstract(Tuple, L, E) when is_tuple(Tuple) ->
- {tuple,L,abstract_tuple_list(tuple_to_list(Tuple), L, E)};
-abstract(Map, L, E) when is_map(Map) ->
- {map,L,abstract_map_fields(maps:to_list(Map),L,E)}.
-
-abstract_list([H|T], String, L, E) ->
+abstract(T, A, _E) when is_integer(T) -> {integer,A,T};
+abstract(T, A, _E) when is_float(T) -> {float,A,T};
+abstract(T, A, _E) when is_atom(T) -> {atom,A,T};
+abstract([], A, _E) -> {nil,A};
+abstract(B, A, _E) when is_bitstring(B) ->
+ {bin, A, [abstract_byte(Byte, A) || Byte <- bitstring_to_list(B)]};
+abstract([H|T], A, none=E) ->
+ {cons,A,abstract(H, A, E),abstract(T, A, E)};
+abstract(List, A, E) when is_list(List) ->
+ abstract_list(List, [], A, E);
+abstract(Tuple, A, E) when is_tuple(Tuple) ->
+ {tuple,A,abstract_tuple_list(tuple_to_list(Tuple), A, E)};
+abstract(Map, A, E) when is_map(Map) ->
+ {map,A,abstract_map_fields(maps:to_list(Map),A,E)}.
+
+abstract_list([H|T], String, A, E) ->
case is_integer(H) andalso H >= 0 andalso E(H) of
true ->
- abstract_list(T, [H|String], L, E);
+ abstract_list(T, [H|String], A, E);
false ->
- AbstrList = {cons,L,abstract(H, L, E),abstract(T, L, E)},
- not_string(String, AbstrList, L, E)
+ AbstrList = {cons,A,abstract(H, A, E),abstract(T, A, E)},
+ not_string(String, AbstrList, A, E)
end;
-abstract_list([], String, L, _E) ->
- {string, L, lists:reverse(String)};
-abstract_list(T, String, L, E) ->
- not_string(String, abstract(T, L, E), L, E).
-
-not_string([C|T], Result, L, E) ->
- not_string(T, {cons, L, {integer, L, C}, Result}, L, E);
-not_string([], Result, _L, _E) ->
+abstract_list([], String, A, _E) ->
+ {string, A, lists:reverse(String)};
+abstract_list(T, String, A, E) ->
+ not_string(String, abstract(T, A, E), A, E).
+
+not_string([C|T], Result, A, E) ->
+ not_string(T, {cons, A, {integer, A, C}, Result}, A, E);
+not_string([], Result, _A, _E) ->
Result.
-abstract_tuple_list([H|T], L, E) ->
- [abstract(H, L, E)|abstract_tuple_list(T, L, E)];
-abstract_tuple_list([], _L, _E) ->
+abstract_tuple_list([H|T], A, E) ->
+ [abstract(H, A, E)|abstract_tuple_list(T, A, E)];
+abstract_tuple_list([], _A, _E) ->
[].
-abstract_map_fields(Fs,L,E) ->
- [{map_field_assoc,L,abstract(K,L,E),abstract(V,L,E)}||{K,V}<-Fs].
+abstract_map_fields(Fs,A,E) ->
+ [{map_field_assoc,A,abstract(K,A,E),abstract(V,A,E)}||{K,V}<-Fs].
-abstract_byte(Byte, L) when is_integer(Byte) ->
- {bin_element, L, {integer, L, Byte}, default, default};
-abstract_byte(Bits, L) ->
+abstract_byte(Byte, A) when is_integer(Byte) ->
+ {bin_element, A, {integer, A, Byte}, default, default};
+abstract_byte(Bits, A) ->
Sz = bit_size(Bits),
<<Val:Sz>> = Bits,
- {bin_element, L, {integer, L, Val}, {integer, L, Sz}, default}.
+ {bin_element, A, {integer, A, Val}, {integer, A, Sz}, default}.
%% Generate a list of tokens representing the abstract term.
@@ -1010,32 +1005,32 @@ tokens(Abs) ->
AbsTerm :: abstract_expr(),
MoreTokens :: [token()],
Tokens :: [token()].
-tokens({char,L,C}, More) -> [{char,L,C}|More];
-tokens({integer,L,N}, More) -> [{integer,L,N}|More];
-tokens({float,L,F}, More) -> [{float,L,F}|More];
-tokens({atom,L,A}, More) -> [{atom,L,A}|More];
-tokens({var,L,V}, More) -> [{var,L,V}|More];
-tokens({string,L,S}, More) -> [{string,L,S}|More];
-tokens({nil,L}, More) -> [{'[',L},{']',L}|More];
-tokens({cons,L,Head,Tail}, More) ->
- [{'[',L}|tokens(Head, tokens_tail(Tail, More))];
-tokens({tuple,L,[]}, More) ->
- [{'{',L},{'}',L}|More];
-tokens({tuple,L,[E|Es]}, More) ->
- [{'{',L}|tokens(E, tokens_tuple(Es, ?line(E), More))].
-
-tokens_tail({cons,L,Head,Tail}, More) ->
- [{',',L}|tokens(Head, tokens_tail(Tail, More))];
-tokens_tail({nil,L}, More) ->
- [{']',L}|More];
+tokens({char,A,C}, More) -> [{char,A,C}|More];
+tokens({integer,A,N}, More) -> [{integer,A,N}|More];
+tokens({float,A,F}, More) -> [{float,A,F}|More];
+tokens({atom,Aa,A}, More) -> [{atom,Aa,A}|More];
+tokens({var,A,V}, More) -> [{var,A,V}|More];
+tokens({string,A,S}, More) -> [{string,A,S}|More];
+tokens({nil,A}, More) -> [{'[',A},{']',A}|More];
+tokens({cons,A,Head,Tail}, More) ->
+ [{'[',A}|tokens(Head, tokens_tail(Tail, More))];
+tokens({tuple,A,[]}, More) ->
+ [{'{',A},{'}',A}|More];
+tokens({tuple,A,[E|Es]}, More) ->
+ [{'{',A}|tokens(E, tokens_tuple(Es, ?anno(E), More))].
+
+tokens_tail({cons,A,Head,Tail}, More) ->
+ [{',',A}|tokens(Head, tokens_tail(Tail, More))];
+tokens_tail({nil,A}, More) ->
+ [{']',A}|More];
tokens_tail(Other, More) ->
- L = ?line(Other),
- [{'|',L}|tokens(Other, [{']',L}|More])].
+ A = ?anno(Other),
+ [{'|',A}|tokens(Other, [{']',A}|More])].
-tokens_tuple([E|Es], Line, More) ->
- [{',',Line}|tokens(E, tokens_tuple(Es, ?line(E), More))];
-tokens_tuple([], Line, More) ->
- [{'}',Line}|More].
+tokens_tuple([E|Es], Anno, More) ->
+ [{',',Anno}|tokens(E, tokens_tuple(Es, ?anno(E), More))];
+tokens_tuple([], Anno, More) ->
+ [{'}',Anno}|More].
%% Give the relative precedences of operators.
@@ -1090,6 +1085,39 @@ func_prec() -> {800,700}.
max_prec() -> 900.
+-type prec() :: non_neg_integer().
+
+-type type_inop() :: '::' | '|' | '..' | '+' | '-' | 'bor' | 'bxor'
+ | 'bsl' | 'bsr' | '*' | '/' | 'div' | 'rem' | 'band'.
+
+-type type_preop() :: '+' | '-' | 'bnot' | '#'.
+
+-spec type_inop_prec(type_inop()) -> {prec(), prec(), prec()}.
+
+type_inop_prec('=') -> {150,100,100};
+type_inop_prec('::') -> {160,150,150};
+type_inop_prec('|') -> {180,170,170};
+type_inop_prec('..') -> {300,200,300};
+type_inop_prec('+') -> {400,400,500};
+type_inop_prec('-') -> {400,400,500};
+type_inop_prec('bor') -> {400,400,500};
+type_inop_prec('bxor') -> {400,400,500};
+type_inop_prec('bsl') -> {400,400,500};
+type_inop_prec('bsr') -> {400,400,500};
+type_inop_prec('*') -> {500,500,600};
+type_inop_prec('/') -> {500,500,600};
+type_inop_prec('div') -> {500,500,600};
+type_inop_prec('rem') -> {500,500,600};
+type_inop_prec('band') -> {500,500,600};
+type_inop_prec('#') -> {800,700,800}.
+
+-spec type_preop_prec(type_preop()) -> {prec(), prec()}.
+
+type_preop_prec('+') -> {600,700};
+type_preop_prec('-') -> {600,700};
+type_preop_prec('bnot') -> {600,700};
+type_preop_prec('#') -> {700,800}.
+
%%% [Experimental]. The parser just copies the attributes of the
%%% scanner tokens to the abstract format. This design decision has
%%% been hidden to some extent: use set_line() and get_attribute() to
@@ -1100,13 +1128,168 @@ max_prec() -> 900.
%%% longer apply. To get all present attributes as a property list
%%% get_attributes() should be used.
+-compile({nowarn_deprecated_function,{erl_scan,set_attribute,3}}).
set_line(L, F) ->
erl_scan:set_attribute(line, L, F).
+-compile({nowarn_deprecated_function,{erl_scan,attributes_info,2}}).
get_attribute(L, Name) ->
erl_scan:attributes_info(L, Name).
+-compile({nowarn_deprecated_function,{erl_scan,attributes_info,1}}).
get_attributes(L) ->
erl_scan:attributes_info(L).
+-spec map_anno(Fun, Abstr) -> NewAbstr when
+ Fun :: fun((Anno) -> Anno),
+ Anno :: erl_anno:anno(),
+ Abstr :: abstract_form() | abstract_expr(),
+ NewAbstr :: abstract_form() | abstract_expr().
+
+map_anno(F0, Abstr) ->
+ F = fun(A, Acc) -> {F0(A), Acc} end,
+ {NewAbstr, []} = modify_anno1(Abstr, [], F),
+ NewAbstr.
+
+-spec fold_anno(Fun, Acc0, Abstr) -> NewAbstr when
+ Fun :: fun((Anno, AccIn) -> AccOut),
+ Anno :: erl_anno:anno(),
+ Acc0 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Abstr :: abstract_form() | abstract_expr(),
+ NewAbstr :: abstract_form() | abstract_expr().
+
+fold_anno(F0, Acc0, Abstr) ->
+ F = fun(A, Acc) -> {A, F0(A, Acc)} end,
+ {_, NewAcc} = modify_anno1(Abstr, Acc0, F),
+ NewAcc.
+
+-spec mapfold_anno(Fun, Acc0, Abstr) -> {NewAbstr, Acc1} when
+ Fun :: fun((Anno, AccIn) -> {Anno, AccOut}),
+ Anno :: erl_anno:anno(),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Abstr :: abstract_form() | abstract_expr(),
+ NewAbstr :: abstract_form() | abstract_expr().
+
+mapfold_anno(F, Acc0, Abstr) ->
+ modify_anno1(Abstr, Acc0, F).
+
+-spec new_anno(Term) -> Abstr when
+ Term :: term(),
+ Abstr :: abstract_form() | abstract_expr().
+
+new_anno(Term) ->
+ map_anno(fun erl_anno:new/1, Term).
+
+-spec anno_to_term(Abstr) -> term() when
+ Abstr :: abstract_form() | abstract_expr().
+
+anno_to_term(Abstract) ->
+ map_anno(fun erl_anno:to_term/1, Abstract).
+
+-spec anno_from_term(Term) -> abstract_form() | abstract_expr() when
+ Term :: term().
+
+anno_from_term(Term) ->
+ map_anno(fun erl_anno:from_term/1, Term).
+
+%% Forms.
+%% Recognize what sys_pre_expand does:
+modify_anno1({'fun',A,F,{_,_,_}=Id}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {F1,Ac2} = modify_anno1(F, Ac1, Mf),
+ {{'fun',A1,F1,Id},Ac2};
+modify_anno1({named_fun,A,N,F,{_,_,_}=Id}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {F1,Ac2} = modify_anno1(F, Ac1, Mf),
+ {{named_fun,A1,N,F1,Id},Ac2};
+modify_anno1({attribute,A,N,[V]}, Ac, Mf) ->
+ {{attribute,A1,N1,V1},Ac1} = modify_anno1({attribute,A,N,V}, Ac, Mf),
+ {{attribute,A1,N1,[V1]},Ac1};
+%% End of sys_pre_expand special forms.
+modify_anno1({function,F,A}, Ac, _Mf) ->
+ {{function,F,A},Ac};
+modify_anno1({function,M,F,A}, Ac, Mf) ->
+ {M1,Ac1} = modify_anno1(M, Ac, Mf),
+ {F1,Ac2} = modify_anno1(F, Ac1, Mf),
+ {A1,Ac3} = modify_anno1(A, Ac2, Mf),
+ {{function,M1,F1,A1},Ac3};
+modify_anno1({attribute,A,record,{Name,Fields}}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {Fields1,Ac2} = modify_anno1(Fields, Ac1, Mf),
+ {{attribute,A1,record,{Name,Fields1}},Ac2};
+modify_anno1({attribute,A,spec,{Fun,Types}}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {Types1,Ac2} = modify_anno1(Types, Ac1, Mf),
+ {{attribute,A1,spec,{Fun,Types1}},Ac2};
+modify_anno1({attribute,A,callback,{Fun,Types}}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {Types1,Ac2} = modify_anno1(Types, Ac1, Mf),
+ {{attribute,A1,callback,{Fun,Types1}},Ac2};
+modify_anno1({attribute,A,type,{TypeName,TypeDef,Args}}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {TypeDef1,Ac2} = modify_anno1(TypeDef, Ac1, Mf),
+ {Args1,Ac3} = modify_anno1(Args, Ac2, Mf),
+ {{attribute,A1,type,{TypeName,TypeDef1,Args1}},Ac3};
+modify_anno1({attribute,A,opaque,{TypeName,TypeDef,Args}}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {TypeDef1,Ac2} = modify_anno1(TypeDef, Ac1, Mf),
+ {Args1,Ac3} = modify_anno1(Args, Ac2, Mf),
+ {{attribute,A1,opaque,{TypeName,TypeDef1,Args1}},Ac3};
+modify_anno1({attribute,A,Attr,Val}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {{attribute,A1,Attr,Val},Ac1};
+modify_anno1({warning,W}, Ac, _Mf) ->
+ {{warning,W},Ac};
+modify_anno1({error,W}, Ac, _Mf) ->
+ {{error,W},Ac};
+%% Expressions.
+modify_anno1({clauses,Cs}, Ac, Mf) ->
+ {Cs1,Ac1} = modify_anno1(Cs, Ac, Mf),
+ {{clauses,Cs1},Ac1};
+modify_anno1({typed_record_field,Field,Type}, Ac, Mf) ->
+ {Field1,Ac1} = modify_anno1(Field, Ac, Mf),
+ {Type1,Ac2} = modify_anno1(Type, Ac1, Mf),
+ {{typed_record_field,Field1,Type1},Ac2};
+modify_anno1({Tag,A}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {{Tag,A1},Ac1};
+modify_anno1({Tag,A,E1}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {E11,Ac2} = modify_anno1(E1, Ac1, Mf),
+ {{Tag,A1,E11},Ac2};
+modify_anno1({Tag,A,E1,E2}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {E11,Ac2} = modify_anno1(E1, Ac1, Mf),
+ {E21,Ac3} = modify_anno1(E2, Ac2, Mf),
+ {{Tag,A1,E11,E21},Ac3};
+modify_anno1({bin_element,A,E1,E2,TSL}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {E11,Ac2} = modify_anno1(E1, Ac1, Mf),
+ {E21,Ac3} = modify_anno1(E2, Ac2, Mf),
+ {{bin_element,A1,E11,E21, TSL},Ac3};
+modify_anno1({Tag,A,E1,E2,E3}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {E11,Ac2} = modify_anno1(E1, Ac1, Mf),
+ {E21,Ac3} = modify_anno1(E2, Ac2, Mf),
+ {E31,Ac4} = modify_anno1(E3, Ac3, Mf),
+ {{Tag,A1,E11,E21,E31},Ac4};
+modify_anno1({Tag,A,E1,E2,E3,E4}, Ac, Mf) ->
+ {A1,Ac1} = Mf(A, Ac),
+ {E11,Ac2} = modify_anno1(E1, Ac1, Mf),
+ {E21,Ac3} = modify_anno1(E2, Ac2, Mf),
+ {E31,Ac4} = modify_anno1(E3, Ac3, Mf),
+ {E41,Ac5} = modify_anno1(E4, Ac4, Mf),
+ {{Tag,A1,E11,E21,E31,E41},Ac5};
+modify_anno1([H|T], Ac, Mf) ->
+ {H1,Ac1} = modify_anno1(H, Ac, Mf),
+ {T1,Ac2} = modify_anno1(T, Ac1, Mf),
+ {[H1|T1],Ac2};
+modify_anno1([], Ac, _Mf) -> {[],Ac};
+modify_anno1(E, Ac, _Mf) when not is_tuple(E), not is_list(E) -> {E,Ac}.
+
%% vim: ft=erlang
diff --git a/lib/stdlib/src/erl_posix_msg.erl b/lib/stdlib/src/erl_posix_msg.erl
index 909cc1d102..5eac230631 100644
--- a/lib/stdlib/src/erl_posix_msg.erl
+++ b/lib/stdlib/src/erl_posix_msg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 1fd6d2a8df..c5177aca90 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,12 +23,13 @@
%%% the parser. It does not always produce pretty code.
-export([form/1,form/2,
- attribute/1,attribute/2,function/1,function/2,rule/1,rule/2,
+ attribute/1,attribute/2,function/1,function/2,
guard/1,guard/2,exprs/1,exprs/2,exprs/3,expr/1,expr/2,expr/3,expr/4]).
-import(lists, [append/1,foldr/3,mapfoldl/3,reverse/1,reverse/2]).
-import(io_lib, [write/1,format/2]).
--import(erl_parse, [inop_prec/1,preop_prec/1,func_prec/0,max_prec/0]).
+-import(erl_parse, [inop_prec/1,preop_prec/1,func_prec/0,max_prec/0,
+ type_inop_prec/1, type_preop_prec/1]).
-define(MAXLINE, 72).
@@ -46,6 +48,23 @@
-record(options, {hook, encoding, opts}).
+%-define(DEBUG, true).
+
+-ifdef(DEBUG).
+-define(TEST(T),
+ %% Assumes that erl_anno has been compiled with DEBUG=true.
+ %% erl_pp does not use the annoations, but test it anyway.
+ %% Note: hooks are not handled.
+ _ = try
+ erl_parse:map_anno(fun(A) when is_list(A) -> A end, T)
+ catch
+ _:_ ->
+ erlang:error(badarg, [T])
+ end).
+-else.
+-define(TEST(T), ok).
+-endif.
+
%%%
%%% Exported functions
%%%
@@ -61,6 +80,7 @@ form(Thing) ->
Options :: options()).
form(Thing, Options) ->
+ ?TEST(Thing),
State = state(Options),
frmt(lform(Thing, options(Options), State), State).
@@ -75,6 +95,7 @@ attribute(Thing) ->
Options :: options()).
attribute(Thing, Options) ->
+ ?TEST(Thing),
State = state(Options),
frmt(lattribute(Thing, options(Options), State), State).
@@ -89,14 +110,9 @@ function(F) ->
Options :: options()).
function(F, Options) ->
+ ?TEST(F),
frmt(lfunction(F, options(Options)), state(Options)).
-rule(R) ->
- rule(R, none).
-
-rule(R, Options) ->
- frmt(lrule(R, options(Options)), state(Options)).
-
-spec(guard(Guard) -> io_lib:chars() when
Guard :: [erl_parse:abstract_expr()]).
@@ -108,6 +124,7 @@ guard(Gs) ->
Options :: options()).
guard(Gs, Options) ->
+ ?TEST(Gs),
frmt(lguard(Gs, options(Options)), state(Options)).
-spec(exprs(Expressions) -> io_lib:chars() when
@@ -129,12 +146,14 @@ exprs(Es, Options) ->
Options :: options()).
exprs(Es, I, Options) ->
+ ?TEST(Es),
frmt({seq,[],[],[$,],lexprs(Es, options(Options))}, I, state(Options)).
-spec(expr(Expression) -> io_lib:chars() when
Expression :: erl_parse:abstract_expr()).
expr(E) ->
+ ?TEST(E),
frmt(lexpr(E, 0, options(none)), state(none)).
-spec(expr(Expression, Options) -> io_lib:chars() when
@@ -142,6 +161,7 @@ expr(E) ->
Options :: options()).
expr(E, Options) ->
+ ?TEST(E),
frmt(lexpr(E, 0, options(Options)), state(Options)).
-spec(expr(Expression, Indent, Options) -> io_lib:chars() when
@@ -150,6 +170,7 @@ expr(E, Options) ->
Options :: options()).
expr(E, I, Options) ->
+ ?TEST(E),
frmt(lexpr(E, 0, options(Options)), I, state(Options)).
-spec(expr(Expression, Indent, Precedence, Options) -> io_lib:chars() when
@@ -159,6 +180,7 @@ expr(E, I, Options) ->
Options :: options()).
expr(E, I, P, Options) ->
+ ?TEST(E),
frmt(lexpr(E, P, options(Options)), I, state(Options)).
%%%
@@ -199,8 +221,6 @@ lform({attribute,Line,Name,Arg}, Opts, State) ->
lattribute({attribute,Line,Name,Arg}, Opts, State);
lform({function,Line,Name,Arity,Clauses}, Opts, _State) ->
lfunction({function,Line,Name,Arity,Clauses}, Opts);
-lform({rule,Line,Name,Arity,Clauses}, Opts, _State) ->
- lrule({rule,Line,Name,Arity,Clauses}, Opts);
%% These are specials to make it easier for the compiler.
lform({error,E}, _Opts, _State) ->
leaf(format("~p\n", [{error,E}]));
@@ -221,69 +241,97 @@ lattribute({attribute,_Line,Name,Arg}, Opts, State) ->
[lattribute(Name, Arg, Opts, State),leaf(".\n")].
lattribute(module, {M,Vs}, _Opts, _State) ->
- attr("module",[{var,0,pname(M)},
- foldr(fun(V, C) -> {cons,0,{var,0,V},C}
- end, {nil,0}, Vs)]);
+ A = a0(),
+ attr("module",[{var,A,pname(M)},
+ foldr(fun(V, C) -> {cons,A,{var,A,V},C}
+ end, {nil,A}, Vs)]);
lattribute(module, M, _Opts, _State) ->
- attr("module", [{var,0,pname(M)}]);
+ attr("module", [{var,a0(),pname(M)}]);
lattribute(export, Falist, _Opts, _State) ->
- call({var,0,"-export"}, [falist(Falist)], 0, options(none));
+ call({var,a0(),"-export"}, [falist(Falist)], 0, options(none));
lattribute(import, Name, _Opts, _State) when is_list(Name) ->
- attr("import", [{var,0,pname(Name)}]);
+ attr("import", [{var,a0(),pname(Name)}]);
lattribute(import, {From,Falist}, _Opts, _State) ->
- attr("import",[{var,0,pname(From)},falist(Falist)]);
+ attr("import",[{var,a0(),pname(From)},falist(Falist)]);
+lattribute(export_type, Talist, _Opts, _State) ->
+ call({var,a0(),"-export_type"}, [falist(Talist)], 0, options(none));
+lattribute(optional_callbacks, Falist, Opts, _State) ->
+ ArgL = try falist(Falist)
+ catch _:_ -> abstract(Falist, Opts)
+ end,
+ call({var,a0(),"-optional_callbacks"}, [ArgL], 0, options(none));
lattribute(file, {Name,Line}, _Opts, State) ->
- attr("file", [{var,0,(State#pp.string_fun)(Name)},{integer,0,Line}]);
+ attr("file", [{var,a0(),(State#pp.string_fun)(Name)},{integer,a0(),Line}]);
lattribute(record, {Name,Is}, Opts, _State) ->
Nl = leaf(format("-record(~w,", [Name])),
[{first,Nl,record_fields(Is, Opts)},$)];
-lattribute(Name, Arg, #options{encoding = Encoding}, _State) ->
- attr(write(Name), [erl_parse:abstract(Arg, [{encoding,Encoding}])]).
+lattribute(Name, Arg, Options, _State) ->
+ attr(write(Name), [abstract(Arg, Options)]).
+
+abstract(Arg, #options{encoding = Encoding}) ->
+ erl_parse:abstract(Arg, [{encoding,Encoding}]).
typeattr(Tag, {TypeName,Type,Args}, _Opts) ->
{first,leaf("-"++atom_to_list(Tag)++" "),
- typed(call({atom,0,TypeName}, Args, 0, options(none)), Type)}.
-
-ltype({ann_type,_Line,[V,T]}) ->
- typed(lexpr(V, options(none)), T);
-ltype({paren_type,_Line,[T]}) ->
- [$(,ltype(T),$)];
-ltype({type,_Line,union,Ts}) ->
- {seq,[],[],[' |'],ltypes(Ts)};
-ltype({type,_Line,list,[T]}) ->
+ typed(call({atom,a0(),TypeName}, Args, 0, options(none)), Type)}.
+
+ltype(T) ->
+ ltype(T, 0).
+
+ltype({ann_type,_Line,[V,T]}, Prec) ->
+ {_L,P,_R} = type_inop_prec('::'),
+ E = typed(lexpr(V, options(none)), T),
+ maybe_paren(P, Prec, E);
+ltype({paren_type,_Line,[T]}, P) ->
+ %% Generated before Erlang/OTP 18.
+ ltype(T, P);
+ltype({type,_Line,union,Ts}, Prec) ->
+ {_L,P,R} = type_inop_prec('|'),
+ E = {seq,[],[],[' |'],ltypes(Ts, R)},
+ maybe_paren(P, Prec, E);
+ltype({type,_Line,list,[T]}, _) ->
{seq,$[,$],$,,[ltype(T)]};
-ltype({type,_Line,nonempty_list,[T]}) ->
+ltype({type,_Line,nonempty_list,[T]}, _) ->
{seq,$[,$],[$,],[ltype(T),leaf("...")]};
-ltype({type,Line,nil,[]}) ->
- lexpr({nil,Line}, 0, options(none));
-ltype({type,Line,map,any}) ->
+ltype({type,Line,nil,[]}, _) ->
+ lexpr({nil,Line}, options(none));
+ltype({type,Line,map,any}, _) ->
simple_type({atom,Line,map}, []);
-ltype({type,_Line,map,Pairs}) ->
- map_type(Pairs);
-ltype({type,Line,tuple,any}) ->
+ltype({type,_Line,map,Pairs}, Prec) ->
+ {P,_R} = type_preop_prec('#'),
+ E = map_type(Pairs),
+ maybe_paren(P, Prec, E);
+ltype({type,Line,tuple,any}, _) ->
simple_type({atom,Line,tuple}, []);
-ltype({type,_Line,tuple,Ts}) ->
- tuple_type(Ts, fun ltype/1);
-ltype({type,_Line,record,[{atom,_,N}|Fs]}) ->
- record_type(N, Fs);
-ltype({type,_Line,range,[_I1,_I2]=Es}) ->
- expr_list(Es, '..', fun lexpr/2, options(none));
-ltype({type,_Line,binary,[I1,I2]}) ->
+ltype({type,_Line,tuple,Ts}, _) ->
+ tuple_type(Ts, fun ltype/2);
+ltype({type,_Line,record,[{atom,_,N}|Fs]}, Prec) ->
+ {P,_R} = type_preop_prec('#'),
+ E = record_type(N, Fs),
+ maybe_paren(P, Prec, E);
+ltype({type,_Line,range,[_I1,_I2]=Es}, Prec) ->
+ {_L,P,R} = type_inop_prec('..'),
+ F = fun(E, Opts) -> lexpr(E, R, Opts) end,
+ E = expr_list(Es, '..', F, options(none)),
+ maybe_paren(P, Prec, E);
+ltype({type,_Line,binary,[I1,I2]}, _) ->
binary_type(I1, I2); % except binary()
-ltype({type,_Line,'fun',[]}) ->
+ltype({type,_Line,'fun',[]}, _) ->
leaf("fun()");
-ltype({type,_,'fun',[{type,_,any},_]}=FunType) ->
+ltype({type,_,'fun',[{type,_,any},_]}=FunType, _) ->
[fun_type(['fun',$(], FunType),$)];
-ltype({type,_Line,'fun',[{type,_,product,_},_]}=FunType) ->
+ltype({type,_Line,'fun',[{type,_,product,_},_]}=FunType, _) ->
[fun_type(['fun',$(], FunType),$)];
-ltype({type,Line,T,Ts}) ->
+ltype({type,Line,T,Ts}, _) ->
+ simple_type({atom,Line,T}, Ts);
+ltype({user_type,Line,T,Ts}, _) ->
simple_type({atom,Line,T}, Ts);
-ltype({remote_type,Line,[M,F,Ts]}) ->
+ltype({remote_type,Line,[M,F,Ts]}, _) ->
simple_type({remote,Line,M,F}, Ts);
-ltype({atom,_,T}) ->
+ltype({atom,_,T}, _) ->
leaf(write(T));
-ltype(E) ->
- lexpr(E, 0, options(none)).
+ltype(E, P) ->
+ lexpr(E, P, options(none)).
binary_type(I1, I2) ->
B = [[] || {integer,_,0} <- [I1]] =:= [],
@@ -297,42 +345,26 @@ map_type(Fs) ->
{first,[$#],map_pair_types(Fs)}.
map_pair_types(Fs) ->
- tuple_type(Fs, fun map_pair_type/1).
-
-map_pair_type({type,_Line,map_field_assoc,Ktype,Vtype}) ->
- map_assoc_typed(ltype(Ktype), Vtype).
-
-map_assoc_typed(B, {type,_,union,Ts}) ->
- {first,[B,$\s],{seq,[],[],[],map_assoc_union_type(Ts)}};
-map_assoc_typed(B, Type) ->
- {list,[{cstep,[B," =>"],ltype(Type)}]}.
+ tuple_type(Fs, fun map_pair_type/2).
-map_assoc_union_type([T|Ts]) ->
- [[leaf("=> "),ltype(T)] | ltypes(Ts, fun union_elem/1)].
+map_pair_type({type,_Line,map_field_assoc,[KType,VType]}, Prec) ->
+ {list,[{cstep,[ltype(KType, Prec),leaf(" =>")],ltype(VType, Prec)}]}.
record_type(Name, Fields) ->
{first,[record_name(Name)],field_types(Fields)}.
field_types(Fs) ->
- tuple_type(Fs, fun field_type/1).
+ tuple_type(Fs, fun field_type/2).
-field_type({type,_Line,field_type,[Name,Type]}) ->
+field_type({type,_Line,field_type,[Name,Type]}, _Prec) ->
typed(lexpr(Name, options(none)), Type).
-typed(B, {type,_,union,Ts}) ->
- %% Special layout for :: followed by union.
- {first,[B,$\s],{seq,[],[],[],union_type(Ts)}};
typed(B, Type) ->
- {list,[{cstep,[B,' ::'],ltype(Type)}]}.
-
-union_type([T|Ts]) ->
- [[leaf(":: "),ltype(T)] | ltypes(Ts, fun union_elem/1)].
-
-union_elem(T) ->
- [leaf(" | "),ltype(T)].
+ {_L,_P,R} = type_inop_prec('::'),
+ {list,[{cstep,[B,' ::'],ltype(Type, R)}]}.
tuple_type(Ts, F) ->
- {seq,${,$},[$,],ltypes(Ts, F)}.
+ {seq,${,$},[$,],ltypes(Ts, F, 0)}.
specattr(SpecKind, {FuncSpec,TypeSpecs}) ->
Func = case FuncSpec of
@@ -357,6 +389,9 @@ guard_type(Before, Gs) ->
Gl = {list,[{step,'when',expr_list(Gs, [$,], fun constraint/2, Opts)}]},
{list,[{step,Before,Gl}]}.
+constraint({type,_Line,constraint,[{atom,_,is_subtype},[{var,_,_}=V,Type]]},
+ _Opts) ->
+ typed(lexpr(V, options(none)), Type);
constraint({type,_Line,constraint,[Tag,As]}, _Opts) ->
simple_type(Tag, As).
@@ -369,19 +404,19 @@ type_args({type,_line,product,Ts}) ->
targs(Ts).
simple_type(Tag, Types) ->
- {first,lexpr(Tag, 0, options(none)),targs(Types)}.
+ {first,lexpr(Tag, options(none)),targs(Types)}.
targs(Ts) ->
- {seq,$(,$),[$,],ltypes(Ts)}.
+ {seq,$(,$),[$,],ltypes(Ts, 0)}.
-ltypes(Ts) ->
- ltypes(Ts, fun ltype/1).
+ltypes(Ts, Prec) ->
+ ltypes(Ts, fun ltype/2, Prec).
-ltypes(Ts, F) ->
- [F(T) || T <- Ts].
+ltypes(Ts, F, Prec) ->
+ [F(T, Prec) || T <- Ts].
attr(Name, Args) ->
- call({var,0,format("-~s", [Name])}, Args, 0, options(none)).
+ call({var,a0(),format("-~s", [Name])}, Args, 0, options(none)).
pname(['' | As]) ->
[$. | pname(As)];
@@ -393,9 +428,10 @@ pname(A) when is_atom(A) ->
write(A).
falist([]) ->
- {nil,0};
+ {nil,a0()};
falist([{Name,Arity}|Falist]) ->
- {cons,0,{var,0,format("~w/~w", [Name,Arity])},falist(Falist)}.
+ A = a0(),
+ {cons,A,{var,A,format("~w/~w", [Name,Arity])},falist(Falist)}.
lfunction({function,_Line,Name,_Arity,Cs}, Opts) ->
Cll = nl_clauses(fun (C, H) -> func_clause(Name, C, H) end, $;, Opts, Cs),
@@ -407,19 +443,6 @@ func_clause(Name, {clause,Line,Head,Guard,Body}, Opts) ->
Bl = body(Body, Opts),
{step,Gl,Bl}.
-lrule({rule,_Line,Name,_Arity,Cs}, Opts) ->
- Cll = nl_clauses(fun (C, H) -> rule_clause(Name, C, H) end, $;, Opts, Cs),
- [Cll,leaf(".\n")].
-
-rule_clause(Name, {clause,Line,Head,Guard,Body}, Opts) ->
- Hl = call({atom,Line,Name}, Head, 0, Opts),
- Gl = guard_when(Hl, Guard, Opts, leaf(" :-")),
- Bl = rule_body(Body, Opts),
- {step,Gl,Bl}.
-
-rule_body(Es, Opts) ->
- lc_quals(Es, Opts).
-
guard_when(Before, Guard, Opts) ->
guard_when(Before, Guard, Opts, ' ->').
@@ -1121,6 +1144,9 @@ write_char(C, PP) ->
%% Utilities
%%
+a0() ->
+ erl_anno:new(0).
+
chars_size([C | Es]) when is_integer(C) ->
1 + chars_size(Es);
chars_size([E | Es]) ->
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index 6fd6bb888b..d2f53816b8 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -55,6 +56,15 @@
token_info/1,token_info/2,
attributes_info/1,attributes_info/2,set_attribute/3]).
+-export([column/1,end_location/1,line/1,location/1,text/1,
+ category/1,symbol/1]).
+
+-deprecated([{attributes_info, 1, next_major_release},
+ {attributes_info, 2, next_major_release},
+ {set_attribute, 3, next_major_release},
+ {token_info, 1, next_major_release},
+ {token_info, 2, next_major_release}]).
+
%%% Private
-export([continuation_location/1]).
@@ -78,9 +88,9 @@
-define(SETATTRFUN(F), is_function(F, 1)).
-type category() :: atom().
--type column() :: pos_integer().
--type line() :: integer().
--type location() :: line() | {line(),column()}.
+-type column() :: pos_integer(). % Deprecated
+-type line() :: integer(). % Deprecated
+-type location() :: line() | {line(),column()}. % Deprecated
-type resword_fun() :: fun((atom()) -> boolean()).
-type option() :: 'return' | 'return_white_spaces' | 'return_comments'
| 'text' | {'reserved_word_fun', resword_fun()}.
@@ -197,6 +207,56 @@ continuation_location({erl_scan_continuation,_,no_col,_,Line,_,_,_}) ->
continuation_location({erl_scan_continuation,_,Col,_,Line,_,_,_}) ->
{Line,Col}.
+-spec column(Token) -> erl_anno:column() | 'undefined' when
+ Token :: token().
+
+column(Token) ->
+ erl_anno:column(element(2, Token)).
+
+-spec end_location(Token) -> erl_anno:location() | 'undefined' when
+ Token :: token().
+
+end_location(Token) ->
+ erl_anno:end_location(element(2, Token)).
+
+-spec line(Token) -> erl_anno:line() when
+ Token :: token().
+
+line(Token) ->
+ erl_anno:line(element(2, Token)).
+
+-spec location(Token) -> erl_anno:location() when
+ Token :: token().
+
+location(Token) ->
+ erl_anno:location(element(2, Token)).
+
+-spec text(Token) -> erl_anno:text() | 'undefined' when
+ Token :: token().
+
+text(Token) ->
+ erl_anno:text(element(2, Token)).
+
+-spec category(Token) -> category() when
+ Token :: token().
+
+category({Category,_Anno}) ->
+ Category;
+category({Category,_Anno,_Symbol}) ->
+ Category;
+category(T) ->
+ erlang:error(badarg, [T]).
+
+-spec symbol(Token) -> symbol() when
+ Token :: token().
+
+symbol({Category,_Anno}) ->
+ Category;
+symbol({_Category,_Anno,Symbol}) ->
+ Symbol;
+symbol(T) ->
+ erlang:error(badarg, [T]).
+
-type attribute_item() :: 'column' | 'length' | 'line'
| 'location' | 'text'.
-type info_location() :: location() | term().
@@ -276,7 +336,17 @@ attributes_info({Line,Column}, column=Item) when ?ALINE(Line),
attributes_info(Line, column) when ?ALINE(Line) ->
undefined;
attributes_info(Attrs, column=Item) ->
- attr_info(Attrs, Item);
+ case attr_info(Attrs, Item) of
+ undefined ->
+ case erl_anno:column(Attrs) of
+ undefined ->
+ undefined;
+ Column ->
+ {Item,Column}
+ end;
+ T ->
+ T
+ end;
attributes_info(Attrs, length=Item) ->
case attributes_info(Attrs, text) of
undefined ->
@@ -290,14 +360,26 @@ attributes_info({Line,Column}, line=Item) when ?ALINE(Line),
?COLUMN(Column) ->
{Item,Line};
attributes_info(Attrs, line=Item) ->
- attr_info(Attrs, Item);
+ case attr_info(Attrs, Item) of
+ undefined ->
+ case attr_info(Attrs, location) of
+ {location,{Line,_Column}} ->
+ {Item,Line};
+ {location,Line} ->
+ {Item,Line};
+ undefined ->
+ undefined
+ end;
+ T ->
+ T
+ end;
attributes_info({Line,Column}=Location, location=Item) when ?ALINE(Line),
?COLUMN(Column) ->
{Item,Location};
attributes_info(Line, location=Item) when ?ALINE(Line) ->
{Item,Line};
attributes_info(Attrs, location=Item) ->
- {line,Line} = attributes_info(Attrs, line), % assume line is present
+ {line,Line} = attributes_info(Attrs, line),
case attributes_info(Attrs, column) of
undefined ->
%% If set_attribute() has assigned a term such as {17,42}
@@ -419,12 +501,28 @@ set_attr(line, {Line,Column}, Fun) when ?ALINE(Line), ?COLUMN(Column) ->
[{line,Ln},{column,Column}]
end;
set_attr(line=Tag, Attrs, Fun) when is_list(Attrs) ->
- {line,Line} = lists:keyfind(Tag, 1, Attrs),
- case lists:keyreplace(Tag, 1, Attrs, {line,Fun(Line)}) of
- [{line,Ln}] when ?ALINE(Ln) ->
- Ln;
- As ->
- As
+ case lists:keyfind(Tag, 1, Attrs) of
+ {line,Line} ->
+ case lists:keyreplace(Tag, 1, Attrs, {line,Fun(Line)}) of
+ [{line,Ln}] when ?ALINE(Ln) ->
+ Ln;
+ As ->
+ As
+ end;
+ false ->
+ {location, Location} = lists:keyfind(location, 1, Attrs),
+ Ln = case Location of
+ {Line,Column} when ?ALINE(Line), ?COLUMN(Column) ->
+ {Fun(Line),Column};
+ _ ->
+ Fun(Location)
+ end,
+ case lists:keyreplace(location, 1, Attrs, {location,Ln}) of
+ [{location,Ln}] when ?ALINE(Ln) ->
+ Ln;
+ As ->
+ As
+ end
end;
set_attr(T1, T2, T3) ->
erlang:error(badarg, [T1,T2,T3]).
@@ -599,9 +697,6 @@ scan1("|"=Cs, _St, Line, Col, Toks) ->
%% :=
scan1(":="++Cs, St, Line, Col, Toks) ->
tok2(Cs, St, Line, Col, Toks, ":=", ':=', 2);
-%% :-
-scan1(":-"++Cs, St, Line, Col, Toks) ->
- tok2(Cs, St, Line, Col, Toks, ":-", ':-', 2);
%% :: for typed records
scan1("::"++Cs, St, Line, Col, Toks) ->
tok2(Cs, St, Line, Col, Toks, "::", '::', 2);
@@ -711,17 +806,17 @@ scan_name(Cs, Ncs) ->
-define(STR(St, S), if St#erl_scan.text -> S; true -> [] end).
scan_dot([$%|_]=Cs, St, Line, Col, Toks, Ncs) ->
- Attrs = attributes(Line, Col, St, Ncs),
- {ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 1)};
+ Anno = anno(Line, Col, St, Ncs),
+ {ok,[{dot,Anno}|Toks],Cs,Line,incr_column(Col, 1)};
scan_dot([$\n=C|Cs], St, Line, Col, Toks, Ncs) ->
- Attrs = attributes(Line, Col, St, ?STR(St, Ncs++[C])),
- {ok,[{dot,Attrs}|Toks],Cs,Line+1,new_column(Col, 1)};
+ Anno = anno(Line, Col, St, ?STR(St, Ncs++[C])),
+ {ok,[{dot,Anno}|Toks],Cs,Line+1,new_column(Col, 1)};
scan_dot([C|Cs], St, Line, Col, Toks, Ncs) when ?WHITE_SPACE(C) ->
- Attrs = attributes(Line, Col, St, ?STR(St, Ncs++[C])),
- {ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 2)};
+ Anno = anno(Line, Col, St, ?STR(St, Ncs++[C])),
+ {ok,[{dot,Anno}|Toks],Cs,Line,incr_column(Col, 2)};
scan_dot(eof=Cs, St, Line, Col, Toks, Ncs) ->
- Attrs = attributes(Line, Col, St, Ncs),
- {ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 1)};
+ Anno = anno(Line, Col, St, Ncs),
+ {ok,[{dot,Anno}|Toks],Cs,Line,incr_column(Col, 1)};
scan_dot(Cs, St, Line, Col, Toks, Ncs) ->
tok2(Cs, St, Line, Col, Toks, Ncs, '.', 1).
@@ -776,12 +871,12 @@ scan_nl_tabs(Cs, St, Line, Col, Toks, N) ->
%% stop anyway, nothing is gained by not collecting all white spaces.
scan_nl_white_space([$\n|Cs], #erl_scan{text = false}=St, Line, no_col=Col,
Toks0, Ncs) ->
- Toks = [{white_space,Line,lists:reverse(Ncs)}|Toks0],
+ Toks = [{white_space,anno(Line),lists:reverse(Ncs)}|Toks0],
scan_newline(Cs, St, Line+1, Col, Toks);
scan_nl_white_space([$\n|Cs], St, Line, Col, Toks, Ncs0) ->
Ncs = lists:reverse(Ncs0),
- Attrs = attributes(Line, Col, St, Ncs),
- Token = {white_space,Attrs,Ncs},
+ Anno = anno(Line, Col, St, Ncs),
+ Token = {white_space,Anno,Ncs},
scan_newline(Cs, St, Line+1, new_column(Col, length(Ncs)), [Token|Toks]);
scan_nl_white_space([C|Cs], St, Line, Col, Toks, Ncs) when ?WHITE_SPACE(C) ->
scan_nl_white_space(Cs, St, Line, Col, Toks, [C|Ncs]);
@@ -789,19 +884,20 @@ scan_nl_white_space([]=Cs, _St, Line, Col, Toks, Ncs) ->
{more,{Cs,Col,Toks,Line,Ncs,fun scan_nl_white_space/6}};
scan_nl_white_space(Cs, #erl_scan{text = false}=St, Line, no_col=Col,
Toks, Ncs) ->
- scan1(Cs, St, Line+1, Col, [{white_space,Line,lists:reverse(Ncs)}|Toks]);
+ Anno = anno(Line),
+ scan1(Cs, St, Line+1, Col, [{white_space,Anno,lists:reverse(Ncs)}|Toks]);
scan_nl_white_space(Cs, St, Line, Col, Toks, Ncs0) ->
Ncs = lists:reverse(Ncs0),
- Attrs = attributes(Line, Col, St, Ncs),
- Token = {white_space,Attrs,Ncs},
+ Anno = anno(Line, Col, St, Ncs),
+ Token = {white_space,Anno,Ncs},
scan1(Cs, St, Line+1, new_column(Col, length(Ncs)), [Token|Toks]).
newline_end(Cs, #erl_scan{text = false}=St, Line, no_col=Col,
Toks, _N, Ncs) ->
- scan1(Cs, St, Line+1, Col, [{white_space,Line,Ncs}|Toks]);
+ scan1(Cs, St, Line+1, Col, [{white_space,anno(Line),Ncs}|Toks]);
newline_end(Cs, St, Line, Col, Toks, N, Ncs) ->
- Attrs = attributes(Line, Col, St, Ncs),
- scan1(Cs, St, Line+1, new_column(Col, N), [{white_space,Attrs,Ncs}|Toks]).
+ Anno = anno(Line, Col, St, Ncs),
+ scan1(Cs, St, Line+1, new_column(Col, N), [{white_space,Anno,Ncs}|Toks]).
scan_spcs([$\s|Cs], St, Line, Col, Toks, N) when N < 16 ->
scan_spcs(Cs, St, Line, Col, Toks, N+1);
@@ -850,20 +946,20 @@ scan_char([$\\|Cs]=Cs0, St, Line, Col, Toks) ->
{eof,Ncol} ->
scan_error(char, Line, Col, Line, Ncol, eof);
{nl,Val,Str,Ncs,Ncol} ->
- Attrs = attributes(Line, Col, St, ?STR(St, "$\\"++Str)), %"
- Ntoks = [{char,Attrs,Val}|Toks],
+ Anno = anno(Line, Col, St, ?STR(St, "$\\"++Str)), %"
+ Ntoks = [{char,Anno,Val}|Toks],
scan1(Ncs, St, Line+1, Ncol, Ntoks);
{Val,Str,Ncs,Ncol} ->
- Attrs = attributes(Line, Col, St, ?STR(St, "$\\"++Str)), %"
- Ntoks = [{char,Attrs,Val}|Toks],
+ Anno = anno(Line, Col, St, ?STR(St, "$\\"++Str)), %"
+ Ntoks = [{char,Anno,Val}|Toks],
scan1(Ncs, St, Line, Ncol, Ntoks)
end;
scan_char([$\n=C|Cs], St, Line, Col, Toks) ->
- Attrs = attributes(Line, Col, St, ?STR(St, [$$,C])),
- scan1(Cs, St, Line+1, new_column(Col, 1), [{char,Attrs,C}|Toks]);
+ Anno = anno(Line, Col, St, ?STR(St, [$$,C])),
+ scan1(Cs, St, Line+1, new_column(Col, 1), [{char,Anno,C}|Toks]);
scan_char([C|Cs], St, Line, Col, Toks) when ?UNICODE(C) ->
- Attrs = attributes(Line, Col, St, ?STR(St, [$$,C])),
- scan1(Cs, St, Line, incr_column(Col, 2), [{char,Attrs,C}|Toks]);
+ Anno = anno(Line, Col, St, ?STR(St, [$$,C])),
+ scan1(Cs, St, Line, incr_column(Col, 2), [{char,Anno,C}|Toks]);
scan_char([C|_Cs], _St, Line, Col, _Toks) when ?CHAR(C) ->
scan_error({illegal,character}, Line, Col, Line, incr_column(Col, 1), eof);
scan_char([], _St, Line, Col, Toks) ->
@@ -882,8 +978,8 @@ scan_string(Cs, St, Line, Col, Toks, {Wcs,Str,Line0,Col0}) ->
Estr = string:substr(Nwcs, 1, 16), % Expanded escape chars.
scan_error({string,$\",Estr}, Line0, Col0, Nline, Ncol, Ncs); %"
{Ncs,Nline,Ncol,Nstr,Nwcs} ->
- Attrs = attributes(Line0, Col0, St, Nstr),
- scan1(Ncs, St, Nline, Ncol, [{string,Attrs,Nwcs}|Toks])
+ Anno = anno(Line0, Col0, St, Nstr),
+ scan1(Ncs, St, Nline, Ncol, [{string,Anno,Nwcs}|Toks])
end.
scan_qatom(Cs, St, Line, Col, Toks, {Wcs,Str,Line0,Col0}) ->
@@ -899,8 +995,8 @@ scan_qatom(Cs, St, Line, Col, Toks, {Wcs,Str,Line0,Col0}) ->
{Ncs,Nline,Ncol,Nstr,Nwcs} ->
case catch list_to_atom(Nwcs) of
A when is_atom(A) ->
- Attrs = attributes(Line0, Col0, St, Nstr),
- scan1(Ncs, St, Nline, Ncol, [{atom,Attrs,A}|Toks]);
+ Anno = anno(Line0, Col0, St, Nstr),
+ scan1(Ncs, St, Nline, Ncol, [{atom,Anno,A}|Toks]);
_ ->
scan_error({illegal,atom}, Line0, Col0, Nline, Ncol, Ncs)
end
@@ -1176,28 +1272,28 @@ scan_comment(Cs, St, Line, Col, Toks, Ncs0) ->
tok3(Cs, St, Line, Col, Toks, comment, Ncs, Ncs).
tok2(Cs, #erl_scan{text = false}=St, Line, no_col=Col, Toks, _Wcs, P) ->
- scan1(Cs, St, Line, Col, [{P,Line}|Toks]);
+ scan1(Cs, St, Line, Col, [{P,anno(Line)}|Toks]);
tok2(Cs, St, Line, Col, Toks, Wcs, P) ->
- Attrs = attributes(Line, Col, St, Wcs),
- scan1(Cs, St, Line, incr_column(Col, length(Wcs)), [{P,Attrs}|Toks]).
+ Anno = anno(Line, Col, St, Wcs),
+ scan1(Cs, St, Line, incr_column(Col, length(Wcs)), [{P,Anno}|Toks]).
tok2(Cs, #erl_scan{text = false}=St, Line, no_col=Col, Toks, _Wcs, P, _N) ->
- scan1(Cs, St, Line, Col, [{P,Line}|Toks]);
+ scan1(Cs, St, Line, Col, [{P,anno(Line)}|Toks]);
tok2(Cs, St, Line, Col, Toks, Wcs, P, N) ->
- Attrs = attributes(Line, Col, St, Wcs),
- scan1(Cs, St, Line, incr_column(Col, N), [{P,Attrs}|Toks]).
+ Anno = anno(Line, Col, St, Wcs),
+ scan1(Cs, St, Line, incr_column(Col, N), [{P,Anno}|Toks]).
tok3(Cs, #erl_scan{text = false}=St, Line, no_col=Col, Toks, Item, _S, Sym) ->
- scan1(Cs, St, Line, Col, [{Item,Line,Sym}|Toks]);
+ scan1(Cs, St, Line, Col, [{Item,anno(Line),Sym}|Toks]);
tok3(Cs, St, Line, Col, Toks, Item, String, Sym) ->
- Token = {Item,attributes(Line, Col, St, String),Sym},
+ Token = {Item,anno(Line, Col, St, String),Sym},
scan1(Cs, St, Line, incr_column(Col, length(String)), [Token|Toks]).
tok3(Cs, #erl_scan{text = false}=St, Line, no_col=Col, Toks, Item,
_String, Sym, _Length) ->
- scan1(Cs, St, Line, Col, [{Item,Line,Sym}|Toks]);
+ scan1(Cs, St, Line, Col, [{Item,anno(Line),Sym}|Toks]);
tok3(Cs, St, Line, Col, Toks, Item, String, Sym, Length) ->
- Token = {Item,attributes(Line, Col, St, String),Sym},
+ Token = {Item,anno(Line, Col, St, String),Sym},
scan1(Cs, St, Line, incr_column(Col, Length), [Token|Toks]).
scan_error(Error, Line, Col, EndLine, EndCol, Rest) ->
@@ -1208,23 +1304,28 @@ scan_error(Error, Line, Col, EndLine, EndCol, Rest) ->
scan_error(Error, ErrorLoc, EndLoc, Rest) ->
{{error,{ErrorLoc,?MODULE,Error},EndLoc},Rest}.
--compile({inline,[attributes/4]}).
+-compile({inline,[anno/4]}).
-attributes(Line, no_col, #erl_scan{text = false}, _String) ->
- Line;
-attributes(Line, no_col, #erl_scan{text = true}, String) ->
- [{line,Line},{text,String}];
-attributes(Line, Col, #erl_scan{text = false}, _String) ->
- {Line,Col};
-attributes(Line, Col, #erl_scan{text = true}, String) ->
- [{line,Line},{column,Col},{text,String}].
+anno(Line, no_col, #erl_scan{text = false}, _String) ->
+ anno(Line);
+anno(Line, no_col, #erl_scan{text = true}, String) ->
+ Anno = anno(Line),
+ erl_anno:set_text(String, Anno);
+anno(Line, Col, #erl_scan{text = false}, _String) ->
+ anno({Line, Col});
+anno(Line, Col, #erl_scan{text = true}, String) ->
+ Anno = anno({Line, Col}),
+ erl_anno:set_text(String, Anno).
location(Line, no_col) ->
Line;
location(Line, Col) when is_integer(Col) ->
{Line,Col}.
--compile({inline,[incr_column/2,new_column/2]}).
+-compile({inline,[anno/1,incr_column/2,new_column/2]}).
+
+anno(Location) ->
+ erl_anno:new(Location).
incr_column(no_col=Col, _N) ->
Col;
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index caa3276d09..d0e7a827a8 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -300,7 +301,7 @@ format_error(Term) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
add1(TarFile, Bin, NameInArchive, Opts) when is_binary(Bin) ->
- Now = calendar:now_to_local_time(now()),
+ Now = calendar:now_to_local_time(erlang:timestamp()),
Info = #file_info{size = byte_size(Bin),
type = regular,
access = read_write,
diff --git a/lib/stdlib/src/error_logger_file_h.erl b/lib/stdlib/src/error_logger_file_h.erl
index e9364ed787..fea1656051 100644
--- a/lib/stdlib/src/error_logger_file_h.erl
+++ b/lib/stdlib/src/error_logger_file_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -23,24 +24,28 @@
%%%
%%% A handler that can be connected to the error_logger
-%%% event handler.
-%%% Writes all events formatted to file.
-%%% Handles events tagged error, emulator and info.
+%%% event handler. Writes all events formatted to file.
%%%
%%% It can only be started from error_logger:swap_handler({logfile, File})
-%%% or error_logger:logfile(File)
+%%% or error_logger:logfile(File).
%%%
-export([init/1,
handle_event/2, handle_call/2, handle_info/2,
terminate/2, code_change/3]).
+-record(st,
+ {fd,
+ filename,
+ prev_handler,
+ depth=unlimited :: 'unlimited' | non_neg_integer()}).
+
%% This one is used when we takeover from the simple error_logger.
init({File, {error_logger, Buf}}) ->
case init(File, error_logger) of
- {ok, {Fd, File, PrevHandler}} ->
- write_events(Fd, Buf),
- {ok, {Fd, File, PrevHandler}};
+ {ok, State} ->
+ write_events(State, Buf),
+ {ok, State};
Error ->
Error
end;
@@ -52,49 +57,45 @@ init(File, PrevHandler) ->
process_flag(trap_exit, true),
case file:open(File, [write]) of
{ok,Fd} ->
- {ok, {Fd, File, PrevHandler}};
+ Depth = get_depth(),
+ State = #st{fd=Fd,filename=File,prev_handler=PrevHandler,
+ depth=Depth},
+ {ok, State};
Error ->
Error
end.
-
+
+get_depth() ->
+ case application:get_env(kernel, error_logger_format_depth) of
+ {ok, Depth} when is_integer(Depth) ->
+ max(10, Depth);
+ undefined ->
+ unlimited
+ end.
+
handle_event({_Type, GL, _Msg}, State) when node(GL) =/= node() ->
{ok, State};
-handle_event(Event, {Fd, File, PrevHandler}) ->
- write_event(Fd, tag_event(Event)),
- {ok, {Fd, File, PrevHandler}};
-handle_event(_, State) ->
+handle_event(Event, State) ->
+ write_event(State, Event),
{ok, State}.
-handle_info({'EXIT', Fd, _Reason}, {Fd, _File, PrevHandler}) ->
+handle_info({'EXIT', Fd, _Reason}, #st{fd=Fd,prev_handler=PrevHandler}) ->
case PrevHandler of
[] ->
remove_handler;
_ ->
{swap_handler, install_prev, [], PrevHandler, go_back}
end;
-handle_info({emulator, GL, Chars}, {Fd, File, PrevHandler})
- when node(GL) == node() ->
- write_event(Fd, tag_event({emulator, GL, Chars})),
- {ok, {Fd, File, PrevHandler}};
-handle_info({emulator, noproc, Chars}, {Fd, File, PrevHandler}) ->
- write_event(Fd, tag_event({emulator, noproc, Chars})),
- {ok, {Fd, File, PrevHandler}};
handle_info(_, State) ->
{ok, State}.
-handle_call(filename, {Fd, File, Prev}) ->
- {ok, File, {Fd, File, Prev}};
+handle_call(filename, #st{filename=File}=State) ->
+ {ok, File, State};
handle_call(_Query, State) ->
{ok, {error, bad_query}, State}.
-terminate(_Reason, State) ->
- case State of
- {Fd, _File, _Prev} ->
- ok = file:close(Fd);
- _ ->
- ok
- end,
- [].
+terminate(_Reason, #st{fd=Fd}) ->
+ file:close(Fd).
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
@@ -103,69 +104,73 @@ code_change(_OldVsn, State, _Extra) ->
%%% Misc. functions.
%%% ------------------------------------------------------
-tag_event(Event) ->
- {erlang:universaltime(), Event}.
+write_events(State, [Ev|Es]) ->
+ %% Write the events in reversed order.
+ write_events(State, Es),
+ write_event(State, Ev);
+write_events(_State, []) ->
+ ok.
-write_events(Fd, Events) -> write_events1(Fd, lists:reverse(Events)).
+write_event(#st{fd=Fd}=State, Event) ->
+ case parse_event(Event) of
+ ignore ->
+ ok;
+ {Head,Pid,FormatList} ->
+ Time = maybe_utc(erlang:universaltime()),
+ Header = write_time(Time, Head),
+ Body = format_body(State, FormatList),
+ AtNode = if
+ node(Pid) =/= node() ->
+ ["** at node ",atom_to_list(node(Pid))," **\n"];
+ true ->
+ []
+ end,
+ io:put_chars(Fd, [Header,Body,AtNode])
+ end.
-write_events1(Fd, [Event|Es]) ->
- write_event(Fd, Event),
- write_events1(Fd, Es);
-write_events1(_, []) ->
- ok.
+format_body(State, [{Format,Args}|T]) ->
+ S = try format(State, Format, Args) of
+ S0 ->
+ S0
+ catch
+ _:_ ->
+ format(State, "ERROR: ~p - ~p\n", [Format,Args])
+ end,
+ [S|format_body(State, T)];
+format_body(_State, []) ->
+ [].
-write_event(Fd, {Time, {error, _GL, {Pid, Format, Args}}}) ->
- T = write_time(maybe_utc(Time)),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when is_list(S) ->
- io:format(Fd, T ++ S, []);
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- io:format(Fd, T ++ F, [Format,Args])
- end;
-write_event(Fd, {Time, {emulator, _GL, Chars}}) ->
- T = write_time(maybe_utc(Time)),
- case catch io_lib:format(Chars, []) of
- S when is_list(S) ->
- io:format(Fd, T ++ S, []);
- _ ->
- io:format(Fd, T ++ "ERROR: ~p ~n", [Chars])
- end;
-write_event(Fd, {Time, {info, _GL, {Pid, Info, _}}}) ->
- T = write_time(maybe_utc(Time)),
- io:format(Fd, T ++ add_node("~p~n",Pid),[Info]);
-write_event(Fd, {Time, {error_report, _GL, {Pid, std_error, Rep}}}) ->
- T = write_time(maybe_utc(Time)),
- S = format_report(Rep),
- io:format(Fd, T ++ S ++ add_node("", Pid), []);
-write_event(Fd, {Time, {info_report, _GL, {Pid, std_info, Rep}}}) ->
- T = write_time(maybe_utc(Time), "INFO REPORT"),
- S = format_report(Rep),
- io:format(Fd, T ++ S ++ add_node("", Pid), []);
-write_event(Fd, {Time, {info_msg, _GL, {Pid, Format, Args}}}) ->
- T = write_time(maybe_utc(Time), "INFO REPORT"),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when is_list(S) ->
- io:format(Fd, T ++ S, []);
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- io:format(Fd, T ++ F, [Format,Args])
- end;
-write_event(Fd, {Time, {warning_report, _GL, {Pid, std_warning, Rep}}}) ->
- T = write_time(maybe_utc(Time), "WARNING REPORT"),
- S = format_report(Rep),
- io:format(Fd, T ++ S ++ add_node("", Pid), []);
-write_event(Fd, {Time, {warning_msg, _GL, {Pid, Format, Args}}}) ->
- T = write_time(maybe_utc(Time), "WARNING REPORT"),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when is_list(S) ->
- io:format(Fd, T ++ S, []);
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- io:format(Fd, T ++ F, [Format,Args])
- end;
-write_event(_, _) ->
- ok.
+format(#st{depth=unlimited}, Format, Args) ->
+ io_lib:format(Format, Args);
+format(#st{depth=Depth}, Format0, Args) ->
+ Format1 = io_lib:scan_format(Format0, Args),
+ Format = limit_format(Format1, Depth),
+ io_lib:build_text(Format).
+
+limit_format([#{control_char:=C0}=M0|T], Depth) when C0 =:= $p;
+ C0 =:= $w ->
+ C = C0 - ($a - $A), %To uppercase.
+ #{args:=Args} = M0,
+ M = M0#{control_char:=C,args:=Args++[Depth]},
+ [M|limit_format(T, Depth)];
+limit_format([H|T], Depth) ->
+ [H|limit_format(T, Depth)];
+limit_format([], _) ->
+ [].
+
+parse_event({error, _GL, {Pid, Format, Args}}) ->
+ {"ERROR REPORT",Pid,[{Format,Args}]};
+parse_event({info_msg, _GL, {Pid, Format, Args}}) ->
+ {"INFO REPORT",Pid,[{Format, Args}]};
+parse_event({warning_msg, _GL, {Pid, Format, Args}}) ->
+ {"WARNING REPORT",Pid,[{Format,Args}]};
+parse_event({error_report, _GL, {Pid, std_error, Args}}) ->
+ {"ERROR REPORT",Pid,format_term(Args)};
+parse_event({info_report, _GL, {Pid, std_info, Args}}) ->
+ {"INFO REPORT",Pid,format_term(Args)};
+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
@@ -182,30 +187,27 @@ maybe_utc(Time) ->
maybe_utc(Time, true) -> {utc, Time};
maybe_utc(Time, _) -> {local, calendar:universal_time_to_local_time(Time)}.
-format_report(Rep) when is_list(Rep) ->
- case string_p(Rep) of
+format_term(Term) when is_list(Term) ->
+ case string_p(Term) of
true ->
- io_lib:format("~s~n",[Rep]);
- _ ->
- format_rep(Rep)
+ [{"~s\n",[Term]}];
+ false ->
+ format_term_list(Term)
end;
-format_report(Rep) ->
- io_lib:format("~p~n",[Rep]).
+format_term(Term) ->
+ [{"~p\n",[Term]}].
-format_rep([{Tag,Data}|Rep]) ->
- io_lib:format(" ~p: ~p~n",[Tag,Data]) ++ format_rep(Rep);
-format_rep([Other|Rep]) ->
- io_lib:format(" ~p~n",[Other]) ++ format_rep(Rep);
-format_rep(_) ->
+format_term_list([{Tag,Data}|T]) ->
+ [{" ~p: ~p\n",[Tag,Data]}|format_term_list(T)];
+format_term_list([Data|T]) ->
+ [{" ~p\n",[Data]}|format_term_list(T)];
+format_term_list([]) ->
+ [];
+format_term_list(_) ->
+ %% Continue to allow non-proper lists for now.
+ %% FIXME: Remove this clause in OTP 19.
[].
-add_node(X, Pid) when is_atom(X) ->
- add_node(atom_to_list(X), Pid);
-add_node(X, Pid) when node(Pid) =/= node() ->
- lists:concat([X,"** at node ",node(Pid)," **~n"]);
-add_node(X, _) ->
- X.
-
string_p([]) ->
false;
string_p(Term) ->
@@ -221,15 +223,10 @@ string_p1([$\b|T]) -> string_p1(T);
string_p1([$\f|T]) -> string_p1(T);
string_p1([$\e|T]) -> string_p1(T);
string_p1([H|T]) when is_list(H) ->
- case string_p1(H) of
- true -> string_p1(T);
- _ -> false
- end;
+ string_p1(H) andalso string_p1(T);
string_p1([]) -> true;
string_p1(_) -> false.
-write_time(Time) -> write_time(Time, "ERROR REPORT").
-
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)]);
diff --git a/lib/stdlib/src/error_logger_tty_h.erl b/lib/stdlib/src/error_logger_tty_h.erl
index e92142d154..d2df6681e3 100644
--- a/lib/stdlib/src/error_logger_tty_h.erl
+++ b/lib/stdlib/src/error_logger_tty_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -22,145 +23,180 @@
%%%
%%% A handler that can be connected to the error_logger
-%%% event handler.
-%%% Writes all events formatted to stdout.
-%%% Handles events tagged error, emulator and info.
+%%% event handler. Writes all events formatted to stdout.
%%%
%%% It can only be started from error_logger:swap_handler(tty)
-%%% or error_logger:tty(true)
+%%% or error_logger:tty(true).
%%%
-export([init/1,
handle_event/2, handle_call/2, handle_info/2,
terminate/2, code_change/3]).
--export([write_event/2]).
+-export([write_event/2,write_event/3]).
+
+-record(st,
+ {user,
+ prev_handler,
+ io_mod=io,
+ depth=unlimited}).
%% This one is used when we takeover from the simple error_logger.
init({[], {error_logger, Buf}}) ->
User = set_group_leader(),
- write_events(Buf,io),
- {ok, {User, error_logger}};
+ Depth = get_depth(),
+ State = #st{user=User,prev_handler=error_logger,depth=Depth},
+ write_events(State, Buf),
+ {ok, State};
%% This one is used if someone took over from us, and now wants to
%% go back.
init({[], {error_logger_tty_h, PrevHandler}}) ->
User = set_group_leader(),
- {ok, {User, PrevHandler}};
+ {ok, #st{user=User,prev_handler=PrevHandler}};
%% This one is used when we are started directly.
init([]) ->
User = set_group_leader(),
- {ok, {User, []}}.
+ Depth = get_depth(),
+ {ok, #st{user=User,prev_handler=[],depth=Depth}}.
+
+get_depth() ->
+ case application:get_env(kernel, error_logger_format_depth) of
+ {ok, Depth} when is_integer(Depth) ->
+ max(10, Depth);
+ undefined ->
+ unlimited
+ end.
handle_event({_Type, GL, _Msg}, State) when node(GL) =/= node() ->
{ok, State};
handle_event(Event, State) ->
- ok = write_event(tag_event(Event),io),
+ ok = do_write_event(State, tag_event(Event)),
{ok, State}.
-handle_info({'EXIT', User, _Reason}, {User, PrevHandler}) ->
+handle_info({'EXIT', User, _Reason},
+ #st{user=User,prev_handler=PrevHandler}=State) ->
case PrevHandler of
[] ->
remove_handler;
_ ->
- {swap_handler, install_prev, {User, PrevHandler},
+ {swap_handler, install_prev, State,
PrevHandler, go_back}
end;
-handle_info({emulator, GL, Chars}, State) when node(GL) == node() ->
- ok = write_event(tag_event({emulator, GL, Chars}),io),
- {ok, State};
-handle_info({emulator, noproc, Chars}, State) ->
- ok = write_event(tag_event({emulator, noproc, Chars}),io),
- {ok, State};
handle_info(_, State) ->
{ok, State}.
handle_call(_Query, State) -> {ok, {error, bad_query}, State}.
-% unfortunately, we can't unlink from User - links are not counted!
-% if pid(User) -> unlink(User); true -> ok end,
terminate(install_prev, _State) ->
[];
-terminate(_Reason, {_User, PrevHandler}) ->
+terminate(_Reason, #st{prev_handler=PrevHandler}) ->
{error_logger_tty_h, PrevHandler}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+%% Exported (but unoffical) API.
+write_event(Event, IoMod) ->
+ do_write_event(#st{io_mod=IoMod}, Event).
+
+write_event(Event, IoMod, Depth) ->
+ do_write_event(#st{io_mod=IoMod,depth=Depth}, Event).
+
+
%%% ------------------------------------------------------
%%% Misc. functions.
%%% ------------------------------------------------------
set_group_leader() ->
case whereis(user) of
- User when is_pid(User) -> link(User), group_leader(User,self()), User;
- _ -> false
+ User when is_pid(User) ->
+ link(User),
+ group_leader(User,self()),
+ User;
+ _ ->
+ false
end.
tag_event(Event) ->
{erlang:universaltime(), Event}.
-%% IOMOd is always 'io'
-write_events(Events,IOMod) -> write_events1(lists:reverse(Events),IOMod).
-
-write_events1([Event|Es],IOMod) ->
- ok = write_event(Event,IOMod),
- write_events1(Es,IOMod);
-write_events1([],_IOMod) ->
+write_events(State, [Ev|Es]) ->
+ %% Write the events in reverse order.
+ _ = write_events(State, Es),
+ _ = do_write_event(State, Ev),
+ ok;
+write_events(_State, []) ->
ok.
-write_event({Time, {error, _GL, {Pid, Format, Args}}},IOMod) ->
- T = write_time(maybe_utc(Time)),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when is_list(S) ->
- format(IOMod, T ++ S);
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- format(IOMod, T ++ F, [Format,Args])
- end;
-write_event({Time, {emulator, _GL, Chars}},IOMod) ->
- T = write_time(maybe_utc(Time)),
- case catch io_lib:format(Chars, []) of
- S when is_list(S) ->
- format(IOMod, T ++ S);
- _ ->
- format(IOMod, T ++ "ERROR: ~p ~n", [Chars])
- end;
-write_event({Time, {info, _GL, {Pid, Info, _}}},IOMod) ->
- T = write_time(maybe_utc(Time)),
- format(IOMod, T ++ add_node("~p~n",Pid),[Info]);
-write_event({Time, {error_report, _GL, {Pid, std_error, Rep}}},IOMod) ->
- T = write_time(maybe_utc(Time)),
- S = format_report(Rep),
- format(IOMod, T ++ S ++ add_node("", Pid));
-write_event({Time, {info_report, _GL, {Pid, std_info, Rep}}},IOMod) ->
- T = write_time(maybe_utc(Time), "INFO REPORT"),
- S = format_report(Rep),
- format(IOMod, T ++ S ++ add_node("", Pid));
-write_event({Time, {info_msg, _GL, {Pid, Format, Args}}},IOMod) ->
- T = write_time(maybe_utc(Time), "INFO REPORT"),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when is_list(S) ->
- format(IOMod, T ++ S);
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- format(IOMod, T ++ F, [Format,Args])
- end;
-write_event({Time, {warning_report, _GL, {Pid, std_warning, Rep}}},IOMod) ->
- T = write_time(maybe_utc(Time), "WARNING REPORT"),
- S = format_report(Rep),
- format(IOMod, T ++ S ++ add_node("", Pid));
-write_event({Time, {warning_msg, _GL, {Pid, Format, Args}}},IOMod) ->
- T = write_time(maybe_utc(Time), "WARNING REPORT"),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when is_list(S) ->
- format(IOMod, T ++ S);
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- format(IOMod, T ++ F, [Format,Args])
+do_write_event(State, {Time0, Event}) ->
+ case parse_event(Event) of
+ ignore ->
+ ok;
+ {Head,Pid,FormatList} ->
+ Time = maybe_utc(Time0),
+ Header = write_time(Time, Head),
+ Body = format_body(State, FormatList),
+ AtNode = if
+ node(Pid) =/= node() ->
+ ["** at node ",atom_to_list(node(Pid))," **\n"];
+ true ->
+ []
+ end,
+ Str = [Header,Body,AtNode],
+ case State#st.io_mod of
+ io_lib ->
+ Str;
+ io ->
+ io:put_chars(user, Str)
+ end
end;
-write_event({_Time, _Error},_IOMod) ->
+do_write_event(_, _) ->
ok.
+format_body(State, [{Format,Args}|T]) ->
+ S = try format(State, Format, Args) of
+ S0 ->
+ S0
+ catch
+ _:_ ->
+ format(State, "ERROR: ~p - ~p\n", [Format,Args])
+ end,
+ [S|format_body(State, T)];
+format_body(_State, []) ->
+ [].
+
+format(#st{depth=unlimited}, Format, Args) ->
+ io_lib:format(Format, Args);
+format(#st{depth=Depth}, Format0, Args) ->
+ Format1 = io_lib:scan_format(Format0, Args),
+ Format = limit_format(Format1, Depth),
+ io_lib:build_text(Format).
+
+limit_format([#{control_char:=C0}=M0|T], Depth) when C0 =:= $p;
+ C0 =:= $w ->
+ C = C0 - ($a - $A), %To uppercase.
+ #{args:=Args} = M0,
+ M = M0#{control_char:=C,args:=Args++[Depth]},
+ [M|limit_format(T, Depth)];
+limit_format([H|T], Depth) ->
+ [H|limit_format(T, Depth)];
+limit_format([], _) ->
+ [].
+
+parse_event({error, _GL, {Pid, Format, Args}}) ->
+ {"ERROR REPORT",Pid,[{Format,Args}]};
+parse_event({info_msg, _GL, {Pid, Format, Args}}) ->
+ {"INFO REPORT",Pid,[{Format, Args}]};
+parse_event({warning_msg, _GL, {Pid, Format, Args}}) ->
+ {"WARNING REPORT",Pid,[{Format,Args}]};
+parse_event({error_report, _GL, {Pid, std_error, Args}}) ->
+ {"ERROR REPORT",Pid,format_term(Args)};
+parse_event({info_report, _GL, {Pid, std_info, Args}}) ->
+ {"INFO REPORT",Pid,format_term(Args)};
+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;
@@ -176,33 +212,26 @@ maybe_utc(Time) ->
maybe_utc(Time, true) -> {utc, Time};
maybe_utc(Time, _) -> {local, calendar:universal_time_to_local_time(Time)}.
-format(IOMod, String) -> format(IOMod, String, []).
-format(io_lib, String, Args) -> io_lib:format(String, Args);
-format(io, String, Args) -> io:format(user, String, Args).
-
-format_report(Rep) when is_list(Rep) ->
- case string_p(Rep) of
+format_term(Term) when is_list(Term) ->
+ case string_p(Term) of
true ->
- io_lib:format("~s~n",[Rep]);
- _ ->
- format_rep(Rep)
+ [{"~s\n",[Term]}];
+ false ->
+ format_term_list(Term)
end;
-format_report(Rep) ->
- io_lib:format("~p~n",[Rep]).
-
-format_rep([{Tag,Data}|Rep]) ->
- io_lib:format(" ~p: ~p~n",[Tag,Data]) ++ format_rep(Rep);
-format_rep([Other|Rep]) ->
- io_lib:format(" ~p~n",[Other]) ++ format_rep(Rep);
-format_rep(_) ->
- [].
+format_term(Term) ->
+ [{"~p\n",[Term]}].
-add_node(X, Pid) when is_atom(X) ->
- add_node(atom_to_list(X), Pid);
-add_node(X, Pid) when node(Pid) =/= node() ->
- lists:concat([X,"** at node ",node(Pid)," **~n"]);
-add_node(X, _) ->
- X.
+format_term_list([{Tag,Data}|T]) ->
+ [{" ~p: ~p\n",[Tag,Data]}|format_term_list(T)];
+format_term_list([Data|T]) ->
+ [{" ~p\n",[Data]}|format_term_list(T)];
+format_term_list([]) ->
+ [];
+format_term_list(_) ->
+ %% Continue to allow non-proper lists for now.
+ %% FIXME: Remove this clause in OTP 19.
+ [].
string_p([]) ->
false;
@@ -226,7 +255,6 @@ string_p1([H|T]) when is_list(H) ->
string_p1([]) -> true;
string_p1(_) -> false.
-write_time(Time) -> write_time(Time, "ERROR REPORT").
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)]);
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 6bd0eb8a22..41b49f4a86 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -620,12 +621,13 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) ->
{ok, {attribute,_, module, M} = Form} ->
epp_parse_file(Epp, S2#state{module = M}, [Form, FileForm]);
{ok, _} ->
- ModForm = {attribute,1,module, Module},
+ ModForm = {attribute,a1(),module, Module},
epp_parse_file2(Epp, S2, [ModForm, FileForm], OptModRes);
{error, _} ->
epp_parse_file2(Epp, S2, [FileForm], OptModRes);
- {eof, _LastLine} = Eof ->
- S#state{forms_or_bin = [FileForm, Eof]}
+ {eof, LastLine} ->
+ Anno = anno(LastLine),
+ S#state{forms_or_bin = [FileForm, {eof, Anno}]}
end,
ok = epp:close(Epp),
ok = file:close(Fd),
@@ -644,7 +646,7 @@ check_source(S, CheckOnly) ->
%% Optionally add export of main/1
Forms2 =
case ExpMain of
- false -> [{attribute,0,export, [{main,1}]} | Forms];
+ false -> [{attribute, a0(), export, [{main,1}]} | Forms];
true -> Forms
end,
Forms3 = [FileForm2, ModForm2 | Forms2],
@@ -663,7 +665,8 @@ check_source(S, CheckOnly) ->
end.
pre_def_macros(File) ->
- {MegaSecs, Secs, MicroSecs} = erlang:now(),
+ {MegaSecs, Secs, MicroSecs} = erlang:timestamp(),
+ Unique = erlang:unique_integer([positive]),
Replace = fun(Char) ->
case Char of
$\. -> $\_;
@@ -675,8 +678,9 @@ pre_def_macros(File) ->
CleanBase ++ "__" ++
"escript__" ++
integer_to_list(MegaSecs) ++ "__" ++
- integer_to_list(Secs) ++ "__" ++
- integer_to_list(MicroSecs),
+ integer_to_list(Secs) ++ "__" ++
+ integer_to_list(MicroSecs) ++ "__" ++
+ integer_to_list(Unique),
Module = list_to_atom(ModuleStr),
PreDefMacros = [{'MODULE', Module, redefine},
{'MODULE_STRING', ModuleStr, redefine}],
@@ -720,8 +724,9 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
io:format("~ts:~w: ~ts\n",
[S#state.file,Ln,Mod:format_error(Args)]),
epp_parse_file(Epp, S#state{n_errors = S#state.n_errors + 1}, [Form | Forms]);
- {eof, _LastLine} = Eof ->
- S#state{forms_or_bin = lists:reverse([Eof | Forms])}
+ {eof, LastLine} ->
+ Anno = anno(LastLine),
+ S#state{forms_or_bin = lists:reverse([{eof, Anno} | Forms])}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -776,7 +781,8 @@ interpret(Forms, HasRecs, File, Args) ->
end,
Dict = parse_to_dict(Forms2),
ArgsA = erl_parse:abstract(Args, 0),
- Call = {call,0,{atom,0,main},[ArgsA]},
+ Anno = a0(),
+ Call = {call,Anno,{atom,Anno,main},[ArgsA]},
try
_ = erl_eval:expr(Call,
erl_eval:new_bindings(),
@@ -888,6 +894,15 @@ enc() ->
Enc -> [Enc]
end.
+a0() ->
+ anno(0).
+
+a1() ->
+ anno(1).
+
+anno(L) ->
+ erl_anno:new(L).
+
fatal(Str) ->
throw(Str).
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 93c4f59896..1fca3624dc 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -71,7 +72,8 @@
rename/2, safe_fixtable/2, select/1, select/2, select/3,
select_count/2, select_delete/2, select_reverse/1,
select_reverse/2, select_reverse/3, setopts/2, slot/2,
- update_counter/3, update_element/3]).
+ take/2,
+ update_counter/3, update_counter/4, update_element/3]).
-spec all() -> [Tab] when
Tab :: tab().
@@ -133,7 +135,9 @@ give_away(_, _, _) ->
| {owner, pid()}
| {protection, access()}
| {size, non_neg_integer()}
- | {type, type()}.
+ | {type, type()}
+ | {write_concurrency, boolean()}
+ | {read_concurrency, boolean()}.
info(_) ->
erlang:nif_error(undef).
@@ -142,7 +146,8 @@ info(_) ->
Tab :: tab(),
Item :: compressed | fixed | heir | keypos | memory
| name | named_table | node | owner | protection
- | safe_fixed | size | stats | type,
+ | safe_fixed | safe_fixed_monotonic_time | size | stats | type
+ | write_concurrency | read_concurrency,
Value :: term().
info(_, _) ->
@@ -400,6 +405,14 @@ setopts(_, _) ->
slot(_, _) ->
erlang:nif_error(undef).
+-spec take(Tab, Key) -> [Object] when
+ Tab :: tab(),
+ Key :: term(),
+ Object :: tuple().
+
+take(_, _) ->
+ erlang:nif_error(undef).
+
-spec update_counter(Tab, Key, UpdateOp) -> Result when
Tab :: tab(),
Key :: term(),
@@ -427,6 +440,38 @@ slot(_, _) ->
update_counter(_, _, _) ->
erlang:nif_error(undef).
+-spec update_counter(Tab, Key, UpdateOp, Default) -> Result when
+ Tab :: tab(),
+ Key :: term(),
+ UpdateOp :: {Pos, Incr}
+ | {Pos, Incr, Threshold, SetValue},
+ Pos :: integer(),
+ Incr :: integer(),
+ Threshold :: integer(),
+ SetValue :: integer(),
+ Result :: integer(),
+ Default :: tuple();
+ (Tab, Key, [UpdateOp], Default) -> [Result] when
+ Tab :: tab(),
+ Key :: term(),
+ UpdateOp :: {Pos, Incr}
+ | {Pos, Incr, Threshold, SetValue},
+ Pos :: integer(),
+ Incr :: integer(),
+ Threshold :: integer(),
+ SetValue :: integer(),
+ Result :: integer(),
+ Default :: tuple();
+ (Tab, Key, Incr, Default) -> Result when
+ Tab :: tab(),
+ Key :: term(),
+ Incr :: integer(),
+ Result :: integer(),
+ Default :: tuple().
+
+update_counter(_, _, _, _) ->
+ erlang:nif_error(undef).
+
-spec update_element(Tab, Key, ElementSpec :: {Pos, Value}) -> boolean() when
Tab :: tab(),
Key :: term(),
@@ -695,7 +740,8 @@ do_filter(Tab, Key, F, A, Ack) ->
-record(filetab_options,
{
object_count = false :: boolean(),
- md5sum = false :: boolean()
+ md5sum = false :: boolean(),
+ sync = false :: boolean()
}).
-spec tab2file(Tab, Filename) -> 'ok' | {'error', Reason} when
@@ -710,7 +756,7 @@ tab2file(Tab, File) ->
Tab :: tab(),
Filename :: file:name(),
Options :: [Option],
- Option :: {'extended_info', [ExtInfo]},
+ Option :: {'extended_info', [ExtInfo]} | {'sync', boolean()},
ExtInfo :: 'md5sum' | 'object_count',
Reason :: term().
@@ -791,6 +837,15 @@ tab2file(Tab, File, Options) ->
List ->
LogFun(NewState1,[['$end_of_table',List]])
end,
+ case FtOptions#filetab_options.sync of
+ true ->
+ case disk_log:sync(Name) of
+ ok -> ok;
+ {error, Reason2} -> throw(Reason2)
+ end;
+ false ->
+ ok
+ end,
disk_log:close(Name)
catch
throw:TReason ->
@@ -843,23 +898,24 @@ md5terms(State, [H|T]) ->
{FinState, [B|TL]}.
parse_ft_options(Options) when is_list(Options) ->
- {Opt,Rest} = case (catch lists:keytake(extended_info,1,Options)) of
- false ->
- {[],Options};
- {value,{extended_info,L},R} when is_list(L) ->
- {L,R}
- end,
- case Rest of
- [] ->
- parse_ft_info_options(#filetab_options{}, Opt);
- Other ->
- throw({unknown_option, Other})
- end;
-parse_ft_options(Malformed) ->
+ {ok, parse_ft_options(Options, #filetab_options{}, false)}.
+
+parse_ft_options([], FtOpt, _) ->
+ FtOpt;
+parse_ft_options([{sync,true} | Rest], FtOpt, EI) ->
+ parse_ft_options(Rest, FtOpt#filetab_options{sync = true}, EI);
+parse_ft_options([{sync,false} | Rest], FtOpt, EI) ->
+ parse_ft_options(Rest, FtOpt, EI);
+parse_ft_options([{extended_info,L} | Rest], FtOpt0, false) ->
+ FtOpt1 = parse_ft_info_options(FtOpt0, L),
+ parse_ft_options(Rest, FtOpt1, true);
+parse_ft_options([Other | _], _, _) ->
+ throw({unknown_option, Other});
+parse_ft_options(Malformed, _, _) ->
throw({malformed_option, Malformed}).
parse_ft_info_options(FtOpt,[]) ->
- {ok,FtOpt};
+ FtOpt;
parse_ft_info_options(FtOpt,[object_count | T]) ->
parse_ft_info_options(FtOpt#filetab_options{object_count = true}, T);
parse_ft_info_options(FtOpt,[md5sum | T]) ->
@@ -1253,18 +1309,30 @@ create_tab(I, TabArg) ->
{name, Name} = lists:keyfind(name, 1, I),
{type, Type} = lists:keyfind(type, 1, I),
{protection, P} = lists:keyfind(protection, 1, I),
- {named_table, Val} = lists:keyfind(named_table, 1, I),
{keypos, _Kp} = Keypos = lists:keyfind(keypos, 1, I),
{size, Sz} = lists:keyfind(size, 1, I),
- Comp = case lists:keyfind(compressed, 1, I) of
- {compressed, true} -> [compressed];
- {compressed, false} -> [];
- false -> []
- end,
+ L1 = [Type, P, Keypos],
+ L2 = case lists:keyfind(named_table, 1, I) of
+ {named_table, true} -> [named_table | L1];
+ {named_table, false} -> L1
+ end,
+ L3 = case lists:keyfind(compressed, 1, I) of
+ {compressed, true} -> [compressed | L2];
+ {compressed, false} -> L2;
+ false -> L2
+ end,
+ L4 = case lists:keyfind(write_concurrency, 1, I) of
+ {write_concurrency, _}=Wcc -> [Wcc | L3];
+ _ -> L3
+ end,
+ L5 = case lists:keyfind(read_concurrency, 1, I) of
+ {read_concurrency, _}=Rcc -> [Rcc | L4];
+ false -> L4
+ end,
case TabArg of
[] ->
try
- Tab = ets:new(Name, [Type, P, Keypos] ++ named_table(Val) ++ Comp),
+ Tab = ets:new(Name, L5),
{ok, Tab, Sz}
catch _:_ ->
throw(cannot_create_table)
@@ -1273,8 +1341,6 @@ create_tab(I, TabArg) ->
{ok, TabArg, Sz}
end.
-named_table(true) -> [named_table];
-named_table(false) -> [].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% tabfile_info/1 reads the head information in an ets table dumped to
diff --git a/lib/stdlib/src/eval_bits.erl b/lib/stdlib/src/eval_bits.erl
index 75fe2c00c7..b3698fb3f5 100644
--- a/lib/stdlib/src/eval_bits.erl
+++ b/lib/stdlib/src/eval_bits.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 1999-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl
index 687d72b4bd..0d50392b96 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,6 +28,8 @@
check/1, check/2,
keycheck/2, keycheck/3]).
+-dialyzer(no_improper_lists).
+
-include_lib("kernel/include/file.hrl").
-define(CHUNKSIZE, 16384).
@@ -1425,8 +1428,8 @@ tmp_prefix1(Dir, TmpDirOpt) ->
U = "_",
Node = node(),
Pid = os:getpid(),
- {MSecs,Secs,MySecs} = now(),
- F = lists:concat(["fs_",Node,U,Pid,U,MSecs,U,Secs,U,MySecs,"."]),
+ Unique = erlang:unique_integer([positive]),
+ F = lists:concat(["fs_",Node,U,Pid,U,Unique,"."]),
TmpDir = case TmpDirOpt of
default ->
Dir;
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index daae1fd2d2..51ffd1cff9 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl
index e6bde5673c..008beb8b67 100644
--- a/lib/stdlib/src/filename.erl
+++ b/lib/stdlib/src/filename.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -444,6 +445,8 @@ join1([], RelativeName, [$:|Rest], win32) ->
join1(RelativeName, [], [$:|Rest], win32);
join1([], RelativeName, [$/|Result], OsType) ->
join1(RelativeName, [], [$/|Result], OsType);
+join1([], RelativeName, [$., $/|Result], OsType) ->
+ join1(RelativeName, [], [$/|Result], OsType);
join1([], RelativeName, Result, OsType) ->
join1(RelativeName, [], [$/|Result], OsType);
join1([[_|_]=List|Rest], RelativeName, Result, OsType) ->
@@ -470,6 +473,8 @@ join1b(<<>>, RelativeName, [$:|Rest], win32) ->
join1b(RelativeName, <<>>, [$:|Rest], win32);
join1b(<<>>, RelativeName, [$/|Result], OsType) ->
join1b(RelativeName, <<>>, [$/|Result], OsType);
+join1b(<<>>, RelativeName, [$., $/|Result], OsType) ->
+ join1b(RelativeName, <<>>, [$/|Result], OsType);
join1b(<<>>, RelativeName, Result, OsType) ->
join1b(RelativeName, <<>>, [$/|Result], OsType);
join1b(<<Char,Rest/binary>>, RelativeName, Result, OsType) when is_integer(Char) ->
@@ -644,7 +649,7 @@ split(Name0) ->
unix_splitb(Name) ->
L = binary:split(Name,[<<"/">>],[global]),
LL = case L of
- [<<>>|Rest] ->
+ [<<>>|Rest] when Rest =/= [] ->
[<<"/">>|Rest];
_ ->
L
diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl
index 0a26d0182d..47a8fa6db0 100644
--- a/lib/stdlib/src/gb_sets.erl
+++ b/lib/stdlib/src/gb_sets.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -137,6 +138,10 @@
%% approach is that it does not require the complete list of all
%% elements to be built in memory at one time.
%%
+%% - iterator_from(X, S): returns an iterator that can be used for
+%% traversing the elements of set S greater than or equal to X;
+%% see `next'.
+%%
%% - next(T): returns {X, T1} where X is the smallest element referred
%% to by the iterator T, and T1 is the new iterator to be used for
%% traversing the remaining elements, or the atom `none' if no
@@ -157,8 +162,8 @@
insert/2, add/2, delete/2, delete_any/2, balance/1, union/2,
union/1, intersection/2, intersection/1, is_disjoint/2, difference/2,
is_subset/2, to_list/1, from_list/1, from_ordset/1, smallest/1,
- largest/1, take_smallest/1, take_largest/1, iterator/1, next/1,
- filter/2, fold/3, is_set/1]).
+ largest/1, take_smallest/1, take_largest/1, iterator/1,
+ iterator_from/2, next/1, filter/2, fold/3, is_set/1]).
%% `sets' compatibility aliases:
@@ -199,29 +204,26 @@
-export_type([set/0, set/1, iter/0, iter/1]).
-type gb_set_node(Element) :: 'nil' | {Element, _, _}.
--type gb_set_node() :: gb_set_node(_).
-opaque set(Element) :: {non_neg_integer(), gb_set_node(Element)}.
--opaque set() :: set(_).
+-type set() :: set(_).
-opaque iter(Element) :: [gb_set_node(Element)].
--opaque iter() :: [gb_set_node()].
+-type iter() :: iter(_).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%% gb_sets:set() in OTP 17 only.
-
-spec empty() -> Set when
- Set :: gb_sets:set().
+ Set :: set().
empty() ->
{0, nil}.
-spec new() -> Set when
- Set :: gb_sets:set().
+ Set :: set().
new() -> empty().
-spec is_empty(Set) -> boolean() when
- Set :: gb_sets:set().
+ Set :: set().
is_empty({0, nil}) ->
true;
@@ -229,7 +231,7 @@ is_empty(_) ->
false.
-spec size(Set) -> non_neg_integer() when
- Set :: gb_sets:set().
+ Set :: set().
size({Size, _}) ->
Size.
@@ -502,6 +504,22 @@ iterator({_, L, _} = T, As) ->
iterator(nil, As) ->
As.
+-spec iterator_from(Element, Set) -> Iter when
+ Set :: set(Element),
+ Iter :: iter(Element).
+
+iterator_from(S, {_, T}) ->
+ iterator_from(S, T, []).
+
+iterator_from(S, {K, _, T}, As) when K < S ->
+ iterator_from(S, T, As);
+iterator_from(_, {_, nil, _} = T, As) ->
+ [T | As];
+iterator_from(S, {_, L, _} = T, As) ->
+ iterator_from(S, L, [T | As]);
+iterator_from(_, nil, As) ->
+ As.
+
-spec next(Iter1) -> {Element, Iter2} | 'none' when
Iter1 :: iter(Element),
Iter2 :: iter(Element).
diff --git a/lib/stdlib/src/gb_trees.erl b/lib/stdlib/src/gb_trees.erl
index 7069b61873..c4a20d92a7 100644
--- a/lib/stdlib/src/gb_trees.erl
+++ b/lib/stdlib/src/gb_trees.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -102,6 +103,10 @@
%% approach is that it does not require the complete list of all
%% elements to be built in memory at one time.
%%
+%% - iterator_from(K, T): returns an iterator that can be used for
+%% traversing the entries of tree T with key greater than or
+%% equal to K; see `next'.
+%%
%% - next(S): returns {X, V, S1} where X is the smallest key referred to
%% by the iterator S, and S1 is the new iterator to be used for
%% traversing the remaining entries, or the atom `none' if no entries
@@ -117,7 +122,7 @@
update/3, enter/3, delete/2, delete_any/2, balance/1,
is_defined/2, keys/1, values/1, to_list/1, from_orddict/1,
smallest/1, largest/1, take_smallest/1, take_largest/1,
- iterator/1, next/1, map/2]).
+ iterator/1, iterator_from/2, next/1, map/2]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -156,11 +161,10 @@
-type gb_tree_node(K, V) :: 'nil'
| {K, V, gb_tree_node(K, V), gb_tree_node(K, V)}.
--type gb_tree_node() :: gb_tree_node(_, _).
-opaque tree(Key, Value) :: {non_neg_integer(), gb_tree_node(Key, Value)}.
--opaque tree() :: tree(_, _).
+-type tree() :: tree(_, _).
-opaque iter(Key, Value) :: [gb_tree_node(Key, Value)].
--opaque iter() :: [gb_tree_node()].
+-type iter() :: iter(_, _).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -529,6 +533,29 @@ iterator({_, _, L, _} = T, As) ->
iterator(nil, As) ->
As.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-spec iterator_from(Key, Tree) -> Iter when
+ Tree :: tree(Key, Value),
+ Iter :: iter(Key, Value).
+
+iterator_from(S, {_, T}) ->
+ iterator_1_from(S, T).
+
+iterator_1_from(S, T) ->
+ iterator_from(S, T, []).
+
+iterator_from(S, {K, _, _, T}, As) when K < S ->
+ iterator_from(S, T, As);
+iterator_from(_, {_, _, nil, _} = T, As) ->
+ [T | As];
+iterator_from(S, {_, _, L, _} = T, As) ->
+ iterator_from(S, L, [T | As]);
+iterator_from(_, nil, As) ->
+ As.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
-spec next(Iter1) -> 'none' | {Key, Value, Iter2} when
Iter1 :: iter(Key, Value),
Iter2 :: iter(Key, Value).
diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl
index 63116fa16e..a05c2ce6fd 100644
--- a/lib/stdlib/src/gen.erl
+++ b/lib/stdlib/src/gen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -26,7 +27,7 @@
%%% The standard behaviour should export init_it/6.
%%%-----------------------------------------------------------------
-export([start/5, start/6, debug_options/1,
- call/3, call/4, reply/2]).
+ call/3, call/4, reply/2, stop/1, stop/3]).
-export([init_it/6, init_it/7]).
@@ -145,56 +146,10 @@ init_it2(GenMod, Starter, Parent, Name, Mod, Args, Options) ->
call(Process, Label, Request) ->
call(Process, Label, Request, ?default_timeout).
-%% Local or remote by pid
-call(Pid, Label, Request, Timeout)
- when is_pid(Pid), Timeout =:= infinity;
- is_pid(Pid), is_integer(Timeout), Timeout >= 0 ->
- do_call(Pid, Label, Request, Timeout);
-%% Local by name
-call(Name, Label, Request, Timeout)
- when is_atom(Name), Timeout =:= infinity;
- is_atom(Name), is_integer(Timeout), Timeout >= 0 ->
- case whereis(Name) of
- Pid when is_pid(Pid) ->
- do_call(Pid, Label, Request, Timeout);
- undefined ->
- exit(noproc)
- end;
-%% Global by name
call(Process, Label, Request, Timeout)
- when ((tuple_size(Process) == 2 andalso element(1, Process) == global)
- orelse
- (tuple_size(Process) == 3 andalso element(1, Process) == via))
- andalso
- (Timeout =:= infinity orelse (is_integer(Timeout) andalso Timeout >= 0)) ->
- case where(Process) of
- Pid when is_pid(Pid) ->
- Node = node(Pid),
- try do_call(Pid, Label, Request, Timeout)
- catch
- exit:{nodedown, Node} ->
- %% A nodedown not yet detected by global,
- %% pretend that it was.
- exit(noproc)
- end;
- undefined ->
- exit(noproc)
- end;
-%% Local by name in disguise
-call({Name, Node}, Label, Request, Timeout)
- when Node =:= node(), Timeout =:= infinity;
- Node =:= node(), is_integer(Timeout), Timeout >= 0 ->
- call(Name, Label, Request, Timeout);
-%% Remote by name
-call({_Name, Node}=Process, Label, Request, Timeout)
- when is_atom(Node), Timeout =:= infinity;
- is_atom(Node), is_integer(Timeout), Timeout >= 0 ->
- if
- node() =:= nonode@nohost ->
- exit({nodedown, Node});
- true ->
- do_call(Process, Label, Request, Timeout)
- end.
+ when Timeout =:= infinity; is_integer(Timeout), Timeout >= 0 ->
+ Fun = fun(Pid) -> do_call(Pid, Label, Request, Timeout) end,
+ do_for_proc(Process, Fun).
do_call(Process, Label, Request, Timeout) ->
try erlang:monitor(process, Process) of
@@ -276,6 +231,65 @@ reply({To, Tag}, Reply) ->
Msg = {Tag, Reply},
try To ! Msg catch _:_ -> Msg end.
+%%-----------------------------------------------------------------
+%% Syncronously stop a generic process
+%%-----------------------------------------------------------------
+stop(Process) ->
+ stop(Process, normal, infinity).
+
+stop(Process, Reason, Timeout)
+ when Timeout =:= infinity; is_integer(Timeout), Timeout >= 0 ->
+ Fun = fun(Pid) -> proc_lib:stop(Pid, Reason, Timeout) end,
+ do_for_proc(Process, Fun).
+
+%%-----------------------------------------------------------------
+%% Map different specifications of a process to either Pid or
+%% {Name,Node}. Execute the given Fun with the process as only
+%% argument.
+%% -----------------------------------------------------------------
+
+%% Local or remote by pid
+do_for_proc(Pid, Fun) when is_pid(Pid) ->
+ Fun(Pid);
+%% Local by name
+do_for_proc(Name, Fun) when is_atom(Name) ->
+ case whereis(Name) of
+ Pid when is_pid(Pid) ->
+ Fun(Pid);
+ undefined ->
+ exit(noproc)
+ end;
+%% Global by name
+do_for_proc(Process, Fun)
+ when ((tuple_size(Process) == 2 andalso element(1, Process) == global)
+ orelse
+ (tuple_size(Process) == 3 andalso element(1, Process) == via)) ->
+ case where(Process) of
+ Pid when is_pid(Pid) ->
+ Node = node(Pid),
+ try Fun(Pid)
+ catch
+ exit:{nodedown, Node} ->
+ %% A nodedown not yet detected by global,
+ %% pretend that it was.
+ exit(noproc)
+ end;
+ undefined ->
+ exit(noproc)
+ end;
+%% Local by name in disguise
+do_for_proc({Name, Node}, Fun) when Node =:= node() ->
+ do_for_proc(Name, Fun);
+%% Remote by name
+do_for_proc({_Name, Node} = Process, Fun) when is_atom(Node) ->
+ if
+ node() =:= nonode@nohost ->
+ exit({nodedown, Node});
+ true ->
+ Fun(Process)
+ end.
+
+
%%%-----------------------------------------------------------------
%%% Misc. functions.
%%%-----------------------------------------------------------------
diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl
index 469acdc37c..3d63c19de7 100644
--- a/lib/stdlib/src/gen_event.erl
+++ b/lib/stdlib/src/gen_event.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -31,8 +32,8 @@
%%% Modified by Martin - uses proc_lib, sys and gen!
--export([start/0, start/1, start_link/0, start_link/1, stop/1, notify/2,
- sync_notify/2,
+-export([start/0, start/1, start_link/0, start_link/1, stop/1, stop/3,
+ notify/2, sync_notify/2,
add_handler/3, add_sup_handler/3, delete_handler/3, swap_handler/3,
swap_sup_handler/3, which_handlers/1, call/3, call/4, wake_hib/4]).
@@ -99,6 +100,14 @@
-callback code_change(OldVsn :: (term() | {down, term()}),
State :: term(), Extra :: term()) ->
{ok, NewState :: term()}.
+-callback format_status(Opt, StatusData) -> Status when
+ Opt :: 'normal' | 'terminate',
+ StatusData :: [PDict | State],
+ PDict :: [{Key :: term(), Value :: term()}],
+ State :: term(),
+ Status :: term().
+
+-optional_callbacks([format_status/2]).
%%---------------------------------------------------------------------------
@@ -183,7 +192,11 @@ swap_sup_handler(M, {H1, A1}, {H2, A2}) ->
which_handlers(M) -> rpc(M, which_handlers).
-spec stop(emgr_ref()) -> 'ok'.
-stop(M) -> rpc(M, stop).
+stop(M) ->
+ gen:stop(M).
+
+stop(M, Reason, Timeout) ->
+ gen:stop(M, Reason, Timeout).
rpc(M, Cmd) ->
{ok, Reply} = gen:call(M, self(), Cmd, infinity),
diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl
index 5afe3e8b09..7eabb95548 100644
--- a/lib/stdlib/src/gen_fsm.erl
+++ b/lib/stdlib/src/gen_fsm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -106,6 +107,7 @@
-export([start/3, start/4,
start_link/3, start_link/4,
+ stop/1, stop/3,
send_event/2, sync_send_event/2, sync_send_event/3,
send_all_state_event/2,
sync_send_all_state_event/2, sync_send_all_state_event/3,
@@ -160,6 +162,14 @@
-callback code_change(OldVsn :: term() | {down, term()}, StateName :: atom(),
StateData :: term(), Extra :: term()) ->
{ok, NextStateName :: atom(), NewStateData :: term()}.
+-callback format_status(Opt, StatusData) -> Status when
+ Opt :: 'normal' | 'terminate',
+ StatusData :: [PDict | State],
+ PDict :: [{Key :: term(), Value :: term()}],
+ State :: term(),
+ Status :: term().
+
+-optional_callbacks([format_status/2]).
%%% ---------------------------------------------------
%%% Starts a generic state machine.
@@ -189,6 +199,11 @@ start_link(Mod, Args, Options) ->
start_link(Name, Mod, Args, Options) ->
gen:start(?MODULE, link, Name, Mod, Args, Options).
+stop(Name) ->
+ gen:stop(Name).
+
+stop(Name, Reason, Timeout) ->
+ gen:stop(Name, Reason, Timeout).
send_event({global, Name}, Event) ->
catch global:send(Name, {'$gen_event', Event}),
diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl
index 18ef4a2507..c58b1de609 100644
--- a/lib/stdlib/src/gen_server.erl
+++ b/lib/stdlib/src/gen_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -88,6 +89,7 @@
%% API
-export([start/3, start/4,
start_link/3, start_link/4,
+ stop/1, stop/3,
call/2, call/3,
cast/2, reply/2,
abcast/2, abcast/3,
@@ -137,6 +139,15 @@
-callback code_change(OldVsn :: (term() | {down, term()}), State :: term(),
Extra :: term()) ->
{ok, NewState :: term()} | {error, Reason :: term()}.
+-callback format_status(Opt, StatusData) -> Status when
+ Opt :: 'normal' | 'terminate',
+ StatusData :: [PDict | State],
+ PDict :: [{Key :: term(), Value :: term()}],
+ State :: term(),
+ Status :: term().
+
+-optional_callbacks([format_status/2]).
+
%%% -----------------------------------------------------------------
%%% Starts a generic server.
@@ -168,6 +179,17 @@ start_link(Name, Mod, Args, Options) ->
%% -----------------------------------------------------------------
+%% Stop a generic server and wait for it to terminate.
+%% If the server is located at another node, that node will
+%% be monitored.
+%% -----------------------------------------------------------------
+stop(Name) ->
+ gen:stop(Name).
+
+stop(Name, Reason, Timeout) ->
+ gen:stop(Name, Reason, Timeout).
+
+%% -----------------------------------------------------------------
%% Make a call to a generic server.
%% If the server is located at another node, that node will
%% be monitored.
@@ -849,22 +871,10 @@ opt(_, []) ->
debug_options(Name, Opts) ->
case opt(debug, Opts) of
- {ok, Options} -> dbg_options(Name, Options);
- _ -> dbg_options(Name, [])
+ {ok, Options} -> dbg_opts(Name, Options);
+ _ -> []
end.
-dbg_options(Name, []) ->
- Opts =
- case init:get_argument(generic_debug) of
- error ->
- [];
- _ ->
- [log, statistics]
- end,
- dbg_opts(Name, Opts);
-dbg_options(Name, Opts) ->
- dbg_opts(Name, Opts).
-
dbg_opts(Name, Opts) ->
case catch sys:debug_options(Opts) of
{'EXIT',_} ->
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index b9ace2f442..284f2e5a2b 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -45,7 +46,7 @@
%% ErrorDescription is whatever the I/O-server sends.
-type server_no_data() :: {'error', ErrorDescription :: term()} | 'eof'.
--type location() :: erl_scan:location().
+-type location() :: erl_anno:location().
%%-------------------------------------------------------------------------
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index adc9a0cf5f..ef30f16f18 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -60,6 +61,7 @@
-module(io_lib).
-export([fwrite/2,fread/2,fread/3,format/2]).
+-export([scan_format/2,unscan_format/1,build_text/1]).
-export([print/1,print/4,indentation/2]).
-export([write/1,write/2,write/3,nl/0,format_prompt/1,format_prompt/2]).
@@ -83,7 +85,7 @@
deep_unicode_char_list/1]).
-export_type([chars/0, latin1_string/0, continuation/0,
- fread_error/0, fread_item/0]).
+ fread_error/0, fread_item/0, format_spec/0]).
%%----------------------------------------------------------------------
@@ -108,6 +110,18 @@
-type fread_item() :: string() | atom() | integer() | float().
+-type format_spec() ::
+ #{
+ control_char => char(),
+ args => [any()],
+ width => 'none' | integer(),
+ adjust => 'left' | 'right',
+ precision => 'none' | integer(),
+ pad_char => char(),
+ encoding => 'unicode' | 'latin1',
+ strings => boolean()
+ }.
+
%%----------------------------------------------------------------------
%% Interface calls to sub-modules.
@@ -156,6 +170,31 @@ format(Format, Args) ->
Other
end.
+-spec scan_format(Format, Data) -> FormatList when
+ Format :: io:format(),
+ Data :: [term()],
+ FormatList :: [char() | format_spec()].
+
+scan_format(Format, Args) ->
+ try io_lib_format:scan(Format, Args)
+ catch
+ _:_ -> erlang:error(badarg, [Format, Args])
+ end.
+
+-spec unscan_format(FormatList) -> {Format, Data} when
+ FormatList :: [char() | format_spec()],
+ Format :: io:format(),
+ Data :: [term()].
+
+unscan_format(FormatList) ->
+ io_lib_format:unscan(FormatList).
+
+-spec build_text(FormatList) -> chars() when
+ FormatList :: [char() | format_spec()].
+
+build_text(FormatList) ->
+ io_lib_format:build(FormatList).
+
-spec print(Term) -> chars() when
Term :: term().
@@ -249,6 +288,8 @@ write([H|T], D) ->
end;
write(F, _D) when is_function(F) ->
erlang:fun_to_list(F);
+write(Term, D) when is_map(Term) ->
+ write_map(Term, D);
write(T, D) when is_tuple(T) ->
if
D =:= 1 -> "{...}";
@@ -257,9 +298,7 @@ write(T, D) when is_tuple(T) ->
[write(element(1, T), D-1)|
write_tail(tl(tuple_to_list(T)), D-1, $,)],
$}]
- end;
-%write(Term, D) when is_map(Term) -> write_map(Term, D);
-write(Term, D) -> write_map(Term, D).
+ end.
%% write_tail(List, Depth, CharacterBeforeDots)
%% Test the terminating case first as this looks better with depth.
diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl
index 89ae6fb187..282005da7d 100644
--- a/lib/stdlib/src/io_lib_format.erl
+++ b/lib/stdlib/src/io_lib_format.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -20,10 +21,9 @@
%% Formatting functions of io library.
--export([fwrite/2,fwrite_g/1,indentation/2]).
+-export([fwrite/2,fwrite_g/1,indentation/2,scan/2,unscan/1,build/1]).
-%% fwrite(Format, ArgList) -> string().
-%% Format the arguments in ArgList after string Format. Just generate
+%% Format the arguments in Args after string Format. Just generate
%% an error if there is an error in the arguments.
%%
%% To do the printing command correctly we need to calculate the
@@ -37,15 +37,84 @@
%% and it also splits the handling of the control characters into two
%% parts.
-fwrite(Format, Args) when is_atom(Format) ->
- fwrite(atom_to_list(Format), Args);
-fwrite(Format, Args) when is_binary(Format) ->
- fwrite(binary_to_list(Format), Args);
+-spec fwrite(Format, Data) -> FormatList when
+ Format :: io:format(),
+ Data :: [term()],
+ FormatList :: [char() | io_lib:format_spec()].
+
fwrite(Format, Args) ->
- Cs = collect(Format, Args),
+ build(scan(Format, Args)).
+
+%% Build the output text for a pre-parsed format list.
+
+-spec build(FormatList) -> io_lib:chars() when
+ FormatList :: [char() | io_lib:format_spec()].
+
+build(Cs) ->
Pc = pcount(Cs),
build(Cs, Pc, 0).
+%% Parse all control sequences in the format string.
+
+-spec scan(Format, Data) -> FormatList when
+ Format :: io:format(),
+ Data :: [term()],
+ FormatList :: [char() | io_lib:format_spec()].
+
+scan(Format, Args) when is_atom(Format) ->
+ scan(atom_to_list(Format), Args);
+scan(Format, Args) when is_binary(Format) ->
+ scan(binary_to_list(Format), Args);
+scan(Format, Args) ->
+ collect(Format, Args).
+
+%% Revert a pre-parsed format list to a plain character list and a
+%% list of arguments.
+
+-spec unscan(FormatList) -> {Format, Data} when
+ FormatList :: [char() | io_lib:format_spec()],
+ Format :: io:format(),
+ Data :: [term()].
+
+unscan(Cs) ->
+ {print(Cs), args(Cs)}.
+
+args([#{args := As} | Cs]) ->
+ As ++ args(Cs);
+args([_C | Cs]) ->
+ args(Cs);
+args([]) ->
+ [].
+
+print([#{control_char := C, width := F, adjust := Ad, precision := P,
+ pad_char := Pad, encoding := Encoding, strings := Strings} | Cs]) ->
+ print(C, F, Ad, P, Pad, Encoding, Strings) ++ print(Cs);
+print([C | Cs]) ->
+ [C | print(Cs)];
+print([]) ->
+ [].
+
+print(C, F, Ad, P, Pad, Encoding, Strings) ->
+ [$~] ++ print_field_width(F, Ad) ++ print_precision(P) ++
+ print_pad_char(Pad) ++ print_encoding(Encoding) ++
+ print_strings(Strings) ++ [C].
+
+print_field_width(none, _Ad) -> "";
+print_field_width(F, left) -> integer_to_list(-F);
+print_field_width(F, right) -> integer_to_list(F).
+
+print_precision(none) -> "";
+print_precision(P) -> [$. | integer_to_list(P)].
+
+print_pad_char($\s) -> ""; % default, no need to make explicit
+print_pad_char(Pad) -> [$., Pad].
+
+print_encoding(unicode) -> "t";
+print_encoding(latin1) -> "".
+
+print_strings(false) -> "l";
+print_strings(true) -> "".
+
collect([$~|Fmt0], Args0) ->
{C,Fmt1,Args1} = collect_cseq(Fmt0, Args0),
[C|collect(Fmt1, Args1)];
@@ -60,7 +129,10 @@ collect_cseq(Fmt0, Args0) ->
{Encoding,Fmt4,Args4} = encoding(Fmt3, Args3),
{Strings,Fmt5,Args5} = strings(Fmt4, Args4),
{C,As,Fmt6,Args6} = collect_cc(Fmt5, Args5),
- {{C,As,F,Ad,P,Pad,Encoding,Strings},Fmt6,Args6}.
+ FormatSpec = #{control_char => C, args => As, width => F, adjust => Ad,
+ precision => P, pad_char => Pad, encoding => Encoding,
+ strings => Strings},
+ {FormatSpec,Fmt6,Args6}.
encoding([$t|Fmt],Args) ->
true = hd(Fmt) =/= $l,
@@ -136,17 +208,19 @@ collect_cc([$i|Fmt], [A|Args]) -> {$i,[A],Fmt,Args}.
pcount(Cs) -> pcount(Cs, 0).
-pcount([{$p,_As,_F,_Ad,_P,_Pad,_Enc,_Str}|Cs], Acc) -> pcount(Cs, Acc+1);
-pcount([{$P,_As,_F,_Ad,_P,_Pad,_Enc,_Str}|Cs], Acc) -> pcount(Cs, Acc+1);
+pcount([#{control_char := $p}|Cs], Acc) -> pcount(Cs, Acc+1);
+pcount([#{control_char := $P}|Cs], Acc) -> pcount(Cs, Acc+1);
pcount([_|Cs], Acc) -> pcount(Cs, Acc);
pcount([], Acc) -> Acc.
-%% build([Control], Pc, Indentation) -> string().
+%% build([Control], Pc, Indentation) -> io_lib:chars().
%% Interpret the control structures. Count the number of print
%% remaining and only calculate indentation when necessary. Must also
%% be smart when calculating indentation for characters in format.
-build([{C,As,F,Ad,P,Pad,Enc,Str}|Cs], Pc0, I) ->
+build([#{control_char := C, args := As, width := F, adjust := Ad,
+ precision := P, pad_char := Pad, encoding := Enc,
+ strings := Str} | Cs], Pc0, I) ->
S = control(C, As, F, Ad, P, Pad, Enc, Str, I),
Pc1 = decr_pc(C, Pc0),
if
@@ -162,10 +236,14 @@ decr_pc($p, Pc) -> Pc - 1;
decr_pc($P, Pc) -> Pc - 1;
decr_pc(_, Pc) -> Pc.
-%% indentation(String, Indentation) -> Indentation.
+
%% Calculate the indentation of the end of a string given its start
%% indentation. We assume tabs at 8 cols.
+-spec indentation(String, StartIndent) -> integer() when
+ String :: io_lib:chars(),
+ StartIndent :: integer().
+
indentation([$\n|Cs], _I) -> indentation(Cs, 0);
indentation([$\t|Cs], I) -> indentation(Cs, ((I + 8) div 8) * 8);
indentation([C|Cs], I) when is_integer(C) ->
@@ -366,7 +444,6 @@ float_data([D|Cs], Ds) when D >= $0, D =< $9 ->
float_data([_|Cs], Ds) ->
float_data(Cs, Ds).
-%% fwrite_g(Float)
%% Writes the shortest, correctly rounded string that converts
%% to Float when read back with list_to_float/1.
%%
@@ -374,6 +451,8 @@ float_data([_|Cs], Ds) ->
%% in Proceedings of the SIGPLAN '96 Conference on Programming
%% Language Design and Implementation.
+-spec fwrite_g(float()) -> string().
+
fwrite_g(0.0) ->
"0.0";
fwrite_g(Float) when is_float(Float) ->
@@ -642,7 +721,7 @@ prefixed_integer(Int, F, Adj, Base, Pad, Prefix, Lowercase)
term([Prefix|S], F, Adj, none, Pad)
end.
-%% char(Char, Field, Adjust, Precision, PadChar) -> string().
+%% char(Char, Field, Adjust, Precision, PadChar) -> chars().
char(C, none, _Adj, none, _Pad) -> [C];
char(C, F, _Adj, none, _Pad) -> chars(C, F);
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 491e1f40d7..25555c6f52 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/src/io_lib_pretty.erl b/lib/stdlib/src/io_lib_pretty.erl
index aece06afa6..6309addf57 100644
--- a/lib/stdlib/src/io_lib_pretty.erl
+++ b/lib/stdlib/src/io_lib_pretty.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/lib.erl b/lib/stdlib/src/lib.erl
index 8351376691..eb24516c50 100644
--- a/lib/stdlib/src/lib.erl
+++ b/lib/stdlib/src/lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl
index 6303465d3d..2b4472cdf7 100644
--- a/lib/stdlib/src/lists.erl
+++ b/lib/stdlib/src/lists.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -2266,6 +2267,8 @@ ukeysplit_2(I, Y, EY, [Z | L], R) ->
ukeysplit_2(_I, Y, _EY, [], R) ->
[Y | R].
+-dialyzer({no_improper_lists, ukeymergel/3}).
+
ukeymergel(I, [T1, [H2 | T2], [H3 | T3] | L], Acc) ->
%% The fourth argument, [H2 | H3] (=HdM), may confuse type
%% checkers. Its purpose is to ensure that the tests H2 == HdM
diff --git a/lib/stdlib/src/log_mf_h.erl b/lib/stdlib/src/log_mf_h.erl
index 6b42363979..35723bbc9e 100644
--- a/lib/stdlib/src/log_mf_h.erl
+++ b/lib/stdlib/src/log_mf_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/maps.erl b/lib/stdlib/src/maps.erl
index ba4d6a5c87..43d10f4800 100644
--- a/lib/stdlib/src/maps.erl
+++ b/lib/stdlib/src/maps.erl
@@ -3,47 +3,33 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(maps).
--export([
- fold/3,
- map/2,
- size/1,
- without/2,
- with/2,
- get/3
- ]).
+-export([get/3,filter/2,fold/3, map/2,
+ size/1,
+ without/2, with/2]).
%%% BIFs
--export([
- get/2,
- find/2,
- from_list/1,
- is_key/2,
- keys/1,
- merge/2,
- new/0,
- put/3,
- remove/2,
- to_list/1,
- update/3,
- values/1
- ]).
+-export([get/2, find/2, from_list/1,
+ is_key/2, keys/1, merge/2,
+ new/0, put/3, remove/2,
+ to_list/1, update/3, values/1]).
-spec get(Key,Map) -> Value when
Key :: term(),
@@ -150,13 +136,28 @@ values(_) -> erlang:nif_error(undef).
Value :: term(),
Default :: term().
-get(Key, Map, Default) ->
+get(Key,Map,Default) when is_map(Map) ->
case maps:find(Key, Map) of
{ok, Value} ->
Value;
error ->
Default
- end.
+ end;
+get(Key,Map,Default) ->
+ erlang:error({badmap,Map},[Key,Map,Default]).
+
+
+-spec filter(Pred,Map1) -> Map2 when
+ Pred :: fun((Key, Value) -> boolean()),
+ Key :: term(),
+ Value :: term(),
+ Map1 :: map(),
+ Map2 :: map().
+
+filter(Pred,Map) when is_function(Pred,2), is_map(Map) ->
+ maps:from_list([{K,V}||{K,V}<-maps:to_list(Map),Pred(K,V)]);
+filter(Pred,Map) ->
+ erlang:error(error_type(Map),[Pred,Map]).
-spec fold(Fun,Init,Map) -> Acc when
@@ -169,8 +170,10 @@ get(Key, Map, Default) ->
K :: term(),
V :: term().
-fold(Fun, Init, Map) when is_function(Fun,3), is_map(Map) ->
- lists:foldl(fun({K,V},A) -> Fun(K,V,A) end,Init,maps:to_list(Map)).
+fold(Fun,Init,Map) when is_function(Fun,3), is_map(Map) ->
+ lists:foldl(fun({K,V},A) -> Fun(K,V,A) end,Init,maps:to_list(Map));
+fold(Fun,Init,Map) ->
+ erlang:error(error_type(Map),[Fun,Init,Map]).
-spec map(Fun,Map1) -> Map2 when
Fun :: fun((K, V1) -> V2),
@@ -180,18 +183,19 @@ fold(Fun, Init, Map) when is_function(Fun,3), is_map(Map) ->
V1 :: term(),
V2 :: term().
-map(Fun, Map) when is_function(Fun, 2), is_map(Map) ->
- maps:from_list(lists:map(fun
- ({K,V}) ->
- {K,Fun(K,V)}
- end,maps:to_list(Map))).
+map(Fun,Map) when is_function(Fun, 2), is_map(Map) ->
+ maps:from_list([{K,Fun(K,V)}||{K,V}<-maps:to_list(Map)]);
+map(Fun,Map) ->
+ erlang:error(error_type(Map),[Fun,Map]).
-spec size(Map) -> non_neg_integer() when
Map :: map().
size(Map) when is_map(Map) ->
- erlang:map_size(Map).
+ erlang:map_size(Map);
+size(Val) ->
+ erlang:error({badmap,Val},[Val]).
-spec without(Ks,Map1) -> Map2 when
@@ -200,8 +204,10 @@ size(Map) when is_map(Map) ->
Map2 :: map(),
K :: term().
-without(Ks, M) when is_list(Ks), is_map(M) ->
- maps:from_list([{K,V}||{K,V} <- maps:to_list(M), not lists:member(K, Ks)]).
+without(Ks,M) when is_list(Ks), is_map(M) ->
+ lists:foldl(fun(K, M1) -> ?MODULE:remove(K, M1) end, M, Ks);
+without(Ks,M) ->
+ erlang:error(error_type(M),[Ks,M]).
-spec with(Ks, Map1) -> Map2 when
@@ -210,5 +216,19 @@ without(Ks, M) when is_list(Ks), is_map(M) ->
Map2 :: map(),
K :: term().
-with(Ks, M) when is_list(Ks), is_map(M) ->
- maps:from_list([{K,V}||{K,V} <- maps:to_list(M), lists:member(K, Ks)]).
+with(Ks,Map1) when is_list(Ks), is_map(Map1) ->
+ Fun = fun(K, List) ->
+ case ?MODULE:find(K, Map1) of
+ {ok, V} ->
+ [{K, V} | List];
+ error ->
+ List
+ end
+ end,
+ ?MODULE:from_list(lists:foldl(Fun, [], Ks));
+with(Ks,M) ->
+ erlang:error(error_type(M),[Ks,M]).
+
+
+error_type(M) when is_map(M) -> badarg;
+error_type(V) -> {badmap, V}.
diff --git a/lib/stdlib/src/math.erl b/lib/stdlib/src/math.erl
index 98a70b1644..06dfc01bbb 100644
--- a/lib/stdlib/src/math.erl
+++ b/lib/stdlib/src/math.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,7 +25,7 @@
-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,
- log10/1, pow/2, sqrt/1, erf/1, erfc/1]).
+ log2/1, log10/1, pow/2, sqrt/1, erf/1, erfc/1]).
-spec acos(X) -> float() when
X :: number().
@@ -92,6 +93,11 @@ exp(_) ->
log(_) ->
erlang:nif_error(undef).
+-spec log2(X) -> float() when
+ X :: number().
+log2(_) ->
+ erlang:nif_error(undef).
+
-spec log10(X) -> float() when
X :: number().
log10(_) ->
diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index 97564e2e44..b67b6f75d7 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -822,9 +823,10 @@ th(T,B,OB) when is_tuple(T) ->
th(Nonstruct,B,_OB) ->
{Nonstruct,B}.
-warn_var_clash(Line,Name,OuterBound) ->
+warn_var_clash(Anno,Name,OuterBound) ->
case gb_sets:is_member(Name,OuterBound) of
true ->
+ Line = erl_anno:line(Anno),
add_warning(Line,{?WARN_SHADOW_VAR,Name});
_ ->
ok
@@ -1079,6 +1081,12 @@ normalise({cons,_,Head,Tail}) ->
[normalise(Head)|normalise(Tail)];
normalise({tuple,_,Args}) ->
list_to_tuple(normalise_list(Args));
+normalise({map,_,Pairs0}) ->
+ Pairs1 = lists:map(fun ({map_field_exact,_,K,V}) ->
+ {normalise(K),normalise(V)}
+ end,
+ Pairs0),
+ maps:from_list(Pairs1);
%% Special case for unary +/-.
normalise({op,_,'+',{char,_,I}}) -> I;
normalise({op,_,'+',{integer,_,I}}) -> I;
diff --git a/lib/stdlib/src/orddict.erl b/lib/stdlib/src/orddict.erl
index c98d78b34d..37cf0084f0 100644
--- a/lib/stdlib/src/orddict.erl
+++ b/lib/stdlib/src/orddict.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -25,11 +26,13 @@
-export([store/3,append/3,append_list/3,update/3,update/4,update_counter/3]).
-export([fold/3,map/2,filter/2,merge/3]).
--export_type([orddict/0]).
+-export_type([orddict/0, orddict/2]).
%%---------------------------------------------------------------------------
--type orddict() :: [{Key :: term(), Value :: term()}].
+-type orddict() :: orddict(_, _).
+
+-type orddict(Key, Value) :: [{Key, Value}].
%%---------------------------------------------------------------------------
@@ -38,8 +41,7 @@
new() -> [].
-spec is_key(Key, Orddict) -> boolean() when
- Key :: term(),
- Orddict :: orddict().
+ Orddict :: orddict(Key, Value :: term()).
is_key(Key, [{K,_}|_]) when Key < K -> false;
is_key(Key, [{K,_}|Dict]) when Key > K -> is_key(Key, Dict);
@@ -47,14 +49,14 @@ is_key(_Key, [{_K,_Val}|_]) -> true; %Key == K
is_key(_, []) -> false.
-spec to_list(Orddict) -> List when
- Orddict :: orddict(),
- List :: [{Key :: term(), Value :: term()}].
+ Orddict :: orddict(Key, Value),
+ List :: [{Key, Value}].
to_list(Dict) -> Dict.
-spec from_list(List) -> Orddict when
- List :: [{Key :: term(), Value :: term()}],
- Orddict :: orddict().
+ List :: [{Key, Value}],
+ Orddict :: orddict(Key, Value).
from_list([]) -> [];
from_list([{_,_}]=Pair) -> Pair;
@@ -73,17 +75,13 @@ is_empty([]) -> true;
is_empty([_|_]) -> false.
-spec fetch(Key, Orddict) -> Value when
- Key :: term(),
- Value :: term(),
- Orddict :: orddict().
+ Orddict :: orddict(Key, Value).
fetch(Key, [{K,_}|D]) when Key > K -> fetch(Key, D);
fetch(Key, [{K,Value}|_]) when Key == K -> Value.
-spec find(Key, Orddict) -> {'ok', Value} | 'error' when
- Key :: term(),
- Orddict :: orddict(),
- Value :: term().
+ Orddict :: orddict(Key, Value).
find(Key, [{K,_}|_]) when Key < K -> error;
find(Key, [{K,_}|D]) when Key > K -> find(Key, D);
@@ -91,17 +89,16 @@ find(_Key, [{_K,Value}|_]) -> {ok,Value}; %Key == K
find(_, []) -> error.
-spec fetch_keys(Orddict) -> Keys when
- Orddict :: orddict(),
- Keys :: [term()].
+ Orddict :: orddict(Key, Value :: term()),
+ Keys :: [Key].
fetch_keys([{Key,_}|Dict]) ->
[Key|fetch_keys(Dict)];
fetch_keys([]) -> [].
-spec erase(Key, Orddict1) -> Orddict2 when
- Key :: term(),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
erase(Key, [{K,_}=E|Dict]) when Key < K -> [E|Dict];
erase(Key, [{K,_}=E|Dict]) when Key > K ->
@@ -110,13 +107,11 @@ erase(_Key, [{_K,_Val}|Dict]) -> Dict; %Key == K
erase(_, []) -> [].
-spec store(Key, Value, Orddict1) -> Orddict2 when
- Key :: term(),
- Value :: term(),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
-store(Key, New, [{K,_}=E|Dict]) when Key < K ->
- [{Key,New},E|Dict];
+store(Key, New, [{K,_}|_]=Dict) when Key < K ->
+ [{Key,New}|Dict];
store(Key, New, [{K,_}=E|Dict]) when Key > K ->
[E|store(Key, New, Dict)];
store(Key, New, [{_K,_Old}|Dict]) -> %Key == K
@@ -124,13 +119,11 @@ store(Key, New, [{_K,_Old}|Dict]) -> %Key == K
store(Key, New, []) -> [{Key,New}].
-spec append(Key, Value, Orddict1) -> Orddict2 when
- Key :: term(),
- Value :: term(),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
-append(Key, New, [{K,_}=E|Dict]) when Key < K ->
- [{Key,[New]},E|Dict];
+append(Key, New, [{K,_}|_]=Dict) when Key < K ->
+ [{Key,[New]}|Dict];
append(Key, New, [{K,_}=E|Dict]) when Key > K ->
[E|append(Key, New, Dict)];
append(Key, New, [{_K,Old}|Dict]) -> %Key == K
@@ -138,13 +131,12 @@ append(Key, New, [{_K,Old}|Dict]) -> %Key == K
append(Key, New, []) -> [{Key,[New]}].
-spec append_list(Key, ValList, Orddict1) -> Orddict2 when
- Key :: term(),
- ValList :: [Value :: term()],
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ ValList :: [Value],
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
-append_list(Key, NewList, [{K,_}=E|Dict]) when Key < K ->
- [{Key,NewList},E|Dict];
+append_list(Key, NewList, [{K,_}|_]=Dict) when Key < K ->
+ [{Key,NewList}|Dict];
append_list(Key, NewList, [{K,_}=E|Dict]) when Key > K ->
[E|append_list(Key, NewList, Dict)];
append_list(Key, NewList, [{_K,Old}|Dict]) -> %Key == K
@@ -153,10 +145,9 @@ append_list(Key, NewList, []) ->
[{Key,NewList}].
-spec update(Key, Fun, Orddict1) -> Orddict2 when
- Key :: term(),
- Fun :: fun((Value1 :: term()) -> Value2 :: term()),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Fun :: fun((Value1 :: Value) -> Value2 :: Value),
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
update(Key, Fun, [{K,_}=E|Dict]) when Key > K ->
[E|update(Key, Fun, Dict)];
@@ -164,14 +155,13 @@ update(Key, Fun, [{K,Val}|Dict]) when Key == K ->
[{Key,Fun(Val)}|Dict].
-spec update(Key, Fun, Initial, Orddict1) -> Orddict2 when
- Key :: term(),
- Initial :: term(),
- Fun :: fun((Value1 :: term()) -> Value2 :: term()),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
-
-update(Key, _, Init, [{K,_}=E|Dict]) when Key < K ->
- [{Key,Init},E|Dict];
+ Initial :: Value,
+ Fun :: fun((Value1 :: Value) -> Value2 :: Value),
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
+
+update(Key, _, Init, [{K,_}|_]=Dict) when Key < K ->
+ [{Key,Init}|Dict];
update(Key, Fun, Init, [{K,_}=E|Dict]) when Key > K ->
[E|update(Key, Fun, Init, Dict)];
update(Key, Fun, _Init, [{_K,Val}|Dict]) -> %Key == K
@@ -179,13 +169,12 @@ update(Key, Fun, _Init, [{_K,Val}|Dict]) -> %Key == K
update(Key, _, Init, []) -> [{Key,Init}].
-spec update_counter(Key, Increment, Orddict1) -> Orddict2 when
- Key :: term(),
- Increment :: number(),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value),
+ Increment :: number().
-update_counter(Key, Incr, [{K,_}=E|Dict]) when Key < K ->
- [{Key,Incr},E|Dict];
+update_counter(Key, Incr, [{K,_}|_]=Dict) when Key < K ->
+ [{Key,Incr}|Dict];
update_counter(Key, Incr, [{K,_}=E|Dict]) when Key > K ->
[E|update_counter(Key, Incr, Dict)];
update_counter(Key, Incr, [{_K,Val}|Dict]) -> %Key == K
@@ -193,28 +182,30 @@ update_counter(Key, Incr, [{_K,Val}|Dict]) -> %Key == K
update_counter(Key, Incr, []) -> [{Key,Incr}].
-spec fold(Fun, Acc0, Orddict) -> Acc1 when
- Fun :: fun((Key :: term(), Value :: term(), AccIn :: term()) -> AccOut :: term()),
- Acc0 :: term(),
- Acc1 :: term(),
- Orddict :: orddict().
+ Fun :: fun((Key, Value, AccIn) -> AccOut),
+ Orddict :: orddict(Key, Value),
+ Acc0 :: Acc,
+ Acc1 :: Acc,
+ AccIn :: Acc,
+ AccOut :: Acc.
fold(F, Acc, [{Key,Val}|D]) ->
fold(F, F(Key, Val, Acc), D);
fold(F, Acc, []) when is_function(F, 3) -> Acc.
-spec map(Fun, Orddict1) -> Orddict2 when
- Fun :: fun((Key :: term(), Value1 :: term()) -> Value2 :: term()),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Fun :: fun((Key, Value1) -> Value2),
+ Orddict1 :: orddict(Key, Value1),
+ Orddict2 :: orddict(Key, Value2).
map(F, [{Key,Val}|D]) ->
[{Key,F(Key, Val)}|map(F, D)];
map(F, []) when is_function(F, 2) -> [].
-spec filter(Pred, Orddict1) -> Orddict2 when
- Pred :: fun((Key :: term(), Value :: term()) -> boolean()),
- Orddict1 :: orddict(),
- Orddict2 :: orddict().
+ Pred :: fun((Key, Value) -> boolean()),
+ Orddict1 :: orddict(Key, Value),
+ Orddict2 :: orddict(Key, Value).
filter(F, [{Key,Val}=E|D]) ->
case F(Key, Val) of
@@ -224,10 +215,10 @@ filter(F, [{Key,Val}=E|D]) ->
filter(F, []) when is_function(F, 2) -> [].
-spec merge(Fun, Orddict1, Orddict2) -> Orddict3 when
- Fun :: fun((Key :: term(), Value1 :: term(), Value2 :: term()) -> Value :: term()),
- Orddict1 :: orddict(),
- Orddict2 :: orddict(),
- Orddict3 :: orddict().
+ Fun :: fun((Key, Value1, Value2) -> Value),
+ Orddict1 :: orddict(Key, Value1),
+ Orddict2 :: orddict(Key, Value2),
+ Orddict3 :: orddict(Key, Value).
merge(F, [{K1,_}=E1|D1], [{K2,_}=E2|D2]) when K1 < K2 ->
[E1|merge(F, D1, [E2|D2])];
diff --git a/lib/stdlib/src/ordsets.erl b/lib/stdlib/src/ordsets.erl
index 4a8b1275b2..6010b41006 100644
--- a/lib/stdlib/src/ordsets.erl
+++ b/lib/stdlib/src/ordsets.erl
@@ -3,19 +3,19 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(ordsets).
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index 6c25beabe9..9d394e19d7 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -1,32 +1,35 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(otp_internal).
--export([obsolete/3]).
+-export([obsolete/3, obsolete_type/3]).
%%----------------------------------------------------------------------
+-dialyzer({no_match, obsolete/3}).
+
-type tag() :: 'deprecated' | 'removed'. %% | 'experimental'.
-type mfas() :: mfa() | {atom(), atom(), [byte()]}.
-type release() :: string().
--spec obsolete(atom(), atom(), byte()) ->
+-spec obsolete(module(), atom(), arity()) ->
'no' | {tag(), string()} | {tag(), mfas(), release()}.
obsolete(Module, Name, Arity) ->
@@ -59,6 +62,11 @@ obsolete_1(erl_eval, arg_list, 3) ->
obsolete_1(erlang, hash, 2) ->
{deprecated, {erlang, phash2, 2}};
+obsolete_1(erlang, now, 0) ->
+ {deprecated,
+ "Deprecated BIF. See the \"Time and Time Correction in Erlang\" "
+ "chapter of the ERTS User's Guide for more information."};
+
obsolete_1(calendar, local_time_to_universal_time, 1) ->
{deprecated, {calendar, local_time_to_universal_time_dst, 1}};
@@ -577,8 +585,73 @@ obsolete_1(asn1rt, utf8_binary_to_list, 1) ->
{deprecated,{unicode,characters_to_list,1}};
obsolete_1(asn1rt, utf8_list_to_binary, 1) ->
{deprecated,{unicode,characters_to_binary,1}};
-obsolete_1(pg, _, _) ->
- {deprecated,"deprecated; will be removed in OTP 18"};
+
+%% Added in OTP 18.
+obsolete_1(core_lib, get_anno, 1) ->
+ {deprecated,{cerl,get_ann,1}};
+obsolete_1(core_lib, set_anno, 2) ->
+ {deprecated,{cerl,set_ann,2}};
+obsolete_1(core_lib, is_literal, 1) ->
+ {deprecated,{cerl,is_literal,1}};
+obsolete_1(core_lib, is_literal_list, 1) ->
+ {deprecated,"deprecated; use lists:all(fun cerl:is_literal/1, L)"
+ " instead"};
+obsolete_1(core_lib, literal_value, 1) ->
+ {deprecated,{core_lib,concrete,1}};
+obsolete_1(erl_scan, set_attribute, 3) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use erl_anno:set_line/2 instead"};
+obsolete_1(erl_scan, attributes_info, 1) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use "
+ "erl_anno:{column,line,location,text}/1 instead"};
+obsolete_1(erl_scan, attributes_info, 2) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use "
+ "erl_anno:{column,line,location,text}/1 instead"};
+obsolete_1(erl_scan, token_info, 1) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use "
+ "erl_scan:{category,column,line,location,symbol,text}/1 instead"};
+obsolete_1(erl_scan, token_info, 2) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use "
+ "erl_scan:{category,column,line,location,symbol,text}/1 instead"};
+obsolete_1(erl_parse, set_line, 2) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use erl_anno:set_line/2 instead"};
+obsolete_1(erl_parse, get_attributes, 1) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use "
+ "erl_anno:{column,line,location,text}/1 instead"};
+obsolete_1(erl_parse, get_attribute, 2) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use "
+ "erl_anno:{column,line,location,text}/1 instead"};
+obsolete_1(erl_lint, modify_line, 2) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use erl_parse:map_anno/2 instead"};
+obsolete_1(ssl, negotiated_next_protocol, 1) ->
+ {deprecated,{ssl,negotiated_protocol,1}};
+
+obsolete_1(ssl, connection_info, 1) ->
+ {deprecated, "deprecated; use connection_information/[1,2] instead"};
+
+obsolete_1(httpd_conf, check_enum, 2) ->
+ {deprecated, "deprecated; use lists:member/2 instead"};
+obsolete_1(httpd_conf, clean, 1) ->
+ {deprecated, "deprecated; use sting:strip/1 instead or possible the re module"};
+obsolete_1(httpd_conf, custom_clean, 3) ->
+ {deprecated, "deprecated; use sting:strip/3 instead or possible the re module"};
+obsolete_1(httpd_conf, is_directory, 1) ->
+ {deprecated, "deprecated; use filelib:is_dir/1 instead"};
+obsolete_1(httpd_conf, is_file, 1) ->
+ {deprecated, "deprecated; use filelib:is_file/1 instead"};
+obsolete_1(httpd_conf, make_integer, 1) ->
+ {deprecated, "deprecated; use erlang:list_to_integer/1 instead"};
+
+obsolete_1(overload, _, _) ->
+ {deprecated, "deprecated; will be removed in OTP 19"};
obsolete_1(_, _, _) ->
no.
@@ -626,3 +699,32 @@ is_snmp_agent_function(add_agent_caps, 2) -> true;
is_snmp_agent_function(del_agent_caps, 1) -> true;
is_snmp_agent_function(get_agent_caps, 0) -> true;
is_snmp_agent_function(_, _) -> false.
+
+-dialyzer({no_match, obsolete_type/3}).
+
+-spec obsolete_type(module(), atom(), arity()) ->
+ 'no' | {tag(), string()} | {tag(), mfas(), release()}.
+
+obsolete_type(Module, Name, NumberOfVariables) ->
+ case obsolete_type_1(Module, Name, NumberOfVariables) of
+ {deprecated=Tag,{_,_,_}=Replacement} ->
+ {Tag,Replacement,"in a future release"};
+ {_,String}=Ret when is_list(String) ->
+ Ret;
+ {_,_,_}=Ret ->
+ Ret;
+ no ->
+ no
+ end.
+
+obsolete_type_1(erl_scan,column,0) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use erl_anno:column() instead"};
+obsolete_type_1(erl_scan,line,0) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use erl_anno:line() instead"};
+obsolete_type_1(erl_scan,location,0) ->
+ {deprecated,
+ "deprecated (will be removed in OTP 19); use erl_anno:location() instead"};
+obsolete_type_1(_,_,_) ->
+ no.
diff --git a/lib/stdlib/src/pg.erl b/lib/stdlib/src/pg.erl
deleted file mode 100644
index a41fd329c2..0000000000
--- a/lib/stdlib/src/pg.erl
+++ /dev/null
@@ -1,187 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(pg).
--deprecated(module).
-
-%% pg provides a process group facility. Messages
-%% can be multicasted to all members in the group
-
--export([create/1,
- create/2,
- standby/2,
- join/2,
- send/2,
- esend/2,
- members/1,
- name_to_pid/1,
- master/1]).
-
-
-%% Create a brand new empty process group with the master residing
-%% at the local node
-
--spec create(PgName) -> 'ok' | {'error', Reason} when
- PgName :: term(),
- Reason :: 'already_created' | term().
-
-create(PgName) ->
- catch begin check(PgName),
- Pid = spawn(pg,master,[PgName]),
- global:register_name(PgName,Pid),
- ok end.
-
-%% Create a brand new empty process group with the master
-%% residing at Node
-
--spec create(PgName, Node) -> 'ok' | {'error', Reason} when
- PgName :: term(),
- Node :: node(),
- Reason :: 'already_created' | term().
-
-create(PgName, Node) ->
- catch begin check(PgName),
- Pid = spawn(Node,pg,master,[PgName]),
- global:register_name(PgName,Pid),
- ok end.
-
-%% Have a process on Node that will act as a standby for the process
-%% group manager. So if the node where the manager runs fails, the
-%% process group will continue to function.
-
--spec standby(term(), node()) -> 'ok'.
-
-standby(_PgName, _Node) ->
- ok.
-
-%% Tell process group PgName that Pid is a new member of the group
-%% synchronously return a list of all old members in the group
-
--spec join(PgName, Pid) -> Members when
- PgName :: term(),
- Pid :: pid(),
- Members :: [pid()].
-
-join(PgName, Pid) when is_atom(PgName) ->
- global:send(PgName, {join,self(),Pid}),
- receive
- {_P,{members,Members}} ->
- Members
- end.
-
-%% Multi cast Mess to all members in the group
-
--spec send(PgName, Msg) -> 'ok' when
- PgName :: term(),
- Msg :: term().
-
-send(PgName, Mess) when is_atom(PgName) ->
- global:send(PgName, {send, self(), Mess}),
- ok;
-send(Pg, Mess) when is_pid(Pg) ->
- Pg ! {send,self(),Mess},
- ok.
-
-%% multi cast a message to all members in the group but ourselves
-%% If we are a member
-
--spec esend(PgName, Msg) -> 'ok' when
- PgName :: term(),
- Msg :: term().
-
-esend(PgName, Mess) when is_atom(PgName) ->
- global:send(PgName, {esend,self(),Mess}),
- ok;
-esend(Pg, Mess) when is_pid(Pg) ->
- Pg ! {esend,self(),Mess},
- ok.
-
-%% Return the members of the group
-
--spec members(PgName) -> Members when
- PgName :: term(),
- Members :: [pid()].
-
-members(PgName) when is_atom(PgName) ->
- global:send(PgName, {self() ,members}),
- receive
- {_P,{members,Members}} ->
- Members
- end;
-members(Pg) when is_pid(Pg) ->
- Pg ! {self,members},
- receive
- {_P,{members,Members}} ->
- Members
- end.
-
--spec name_to_pid(atom()) -> pid() | 'undefined'.
-
-name_to_pid(PgName) when is_atom(PgName) ->
- global:whereis_name(PgName).
-
--spec master(term()) -> no_return().
-
-master(PgName) ->
- process_flag(trap_exit, true),
- master_loop(PgName, []).
-
-master_loop(PgName,Members) ->
- receive
- {send,From,Message} ->
- send_all(Members,{pg_message,From,PgName,Message}),
- master_loop(PgName,Members);
- {esend,From,Message} ->
- send_all(lists:delete(From,Members),
- {pg_message,From,PgName,Message}),
- master_loop(PgName,Members);
- {join,From,Pid} ->
- link(Pid),
- send_all(Members,{new_member,PgName,Pid}),
- From ! {self(),{members,Members}},
- master_loop(PgName,[Pid|Members]);
- {From,members} ->
- From ! {self(),{members,Members}},
- master_loop(PgName,Members);
- {'EXIT',From,_} ->
- L =
- case lists:member(From,Members) of
- true ->
- NewMembers = lists:delete(From,Members),
- send_all(NewMembers, {crashed_member,PgName,From}),
- NewMembers;
- false ->
- Members
- end,
- master_loop(PgName,L)
- end.
-
-send_all([], _) -> ok;
-send_all([P|Ps], M) ->
- P ! M,
- send_all(Ps, M).
-
-%% Check if the process group already exists
-
-check(PgName) ->
- case global:whereis_name(PgName) of
- Pid when is_pid(Pid) ->
- throw({error,already_created});
- undefined ->
- ok
- end.
diff --git a/lib/stdlib/src/pool.erl b/lib/stdlib/src/pool.erl
index dfe6318dea..2112337f65 100644
--- a/lib/stdlib/src/pool.erl
+++ b/lib/stdlib/src/pool.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index bf2a4e7ac5..10c476a6f5 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,8 +30,10 @@
start/3, start/4, start/5, start_link/3, start_link/4, start_link/5,
hibernate/3,
init_ack/1, init_ack/2,
- init_p/3,init_p/5,format/1,format/2,initial_call/1,
- translate_initial_call/1]).
+ init_p/3,init_p/5,format/1,format/2,format/3,
+ initial_call/1,
+ translate_initial_call/1,
+ stop/1, stop/3]).
%% Internal exports.
-export([wake_up/3]).
@@ -698,53 +701,118 @@ format(CrashReport) ->
CrashReport :: [term()],
Encoding :: latin1 | unicode | utf8.
-format([OwnReport,LinkReport], Encoding) ->
- OwnFormat = format_report(OwnReport, Encoding),
- LinkFormat = format_report(LinkReport, Encoding),
+format(CrashReport, Encoding) ->
+ format(CrashReport, Encoding, unlimited).
+
+-spec format(CrashReport, Encoding, Depth) -> string() when
+ CrashReport :: [term()],
+ Encoding :: latin1 | unicode | utf8,
+ Depth :: unlimited | pos_integer().
+
+format([OwnReport,LinkReport], Encoding, Depth) ->
+ Extra = {Encoding,Depth},
+ OwnFormat = format_report(OwnReport, Extra),
+ LinkFormat = format_report(LinkReport, Extra),
Str = io_lib:format(" crasher:~n~ts neighbours:~n~ts",
[OwnFormat, LinkFormat]),
lists:flatten(Str).
-format_report(Rep, Enc) when is_list(Rep) ->
- format_rep(Rep,Enc);
-format_report(Rep, Enc) ->
+format_report(Rep, Extra) when is_list(Rep) ->
+ format_rep(Rep, Extra);
+format_report(Rep, {Enc,_}) ->
io_lib:format("~"++modifier(Enc)++"p~n", [Rep]).
-format_rep([{initial_call,InitialCall}|Rep], Enc) ->
- [format_mfa(InitialCall)|format_rep(Rep, Enc)];
-format_rep([{error_info,{Class,Reason,StackTrace}}|Rep], Enc) ->
- [format_exception(Class, Reason, StackTrace, Enc)|format_rep(Rep, Enc)];
-format_rep([{Tag,Data}|Rep], Enc) ->
- [format_tag(Tag, Data)|format_rep(Rep, Enc)];
-format_rep(_, _Enc) ->
+format_rep([{initial_call,InitialCall}|Rep], {_Enc,Depth}=Extra) ->
+ [format_mfa(InitialCall, Depth)|format_rep(Rep, Extra)];
+format_rep([{error_info,{Class,Reason,StackTrace}}|Rep], Extra) ->
+ [format_exception(Class, Reason, StackTrace, Extra)|format_rep(Rep, Extra)];
+format_rep([{Tag,Data}|Rep], Extra) ->
+ [format_tag(Tag, Data, Extra)|format_rep(Rep, Extra)];
+format_rep(_, _Extra) ->
[].
-format_exception(Class, Reason, StackTrace, Enc) ->
- PF = pp_fun(Enc),
+format_exception(Class, Reason, StackTrace, {Enc,_}=Extra) ->
+ PF = pp_fun(Extra),
StackFun = fun(M, _F, _A) -> (M =:= erl_eval) or (M =:= ?MODULE) end,
%% EI = " exception: ",
EI = " ",
[EI, lib:format_exception(1+length(EI), Class, Reason,
StackTrace, StackFun, PF, Enc), "\n"].
-format_mfa({M,F,Args}=StartF) ->
+format_mfa({M,F,Args}=StartF, Depth) ->
try
A = length(Args),
[" initial call: ",atom_to_list(M),$:,atom_to_list(F),$/,
integer_to_list(A),"\n"]
catch
error:_ ->
- format_tag(initial_call, StartF)
+ format_tag(initial_call, StartF, Depth)
end.
-pp_fun(Enc) ->
- P = modifier(Enc) ++ "p",
+pp_fun({Enc,Depth}) ->
+ {Letter,Tl} = case Depth of
+ unlimited -> {"p",[]};
+ _ -> {"P",[Depth]}
+ end,
+ P = modifier(Enc) ++ Letter,
fun(Term, I) ->
- io_lib:format("~." ++ integer_to_list(I) ++ P, [Term])
+ io_lib:format("~." ++ integer_to_list(I) ++ P, [Term|Tl])
end.
-format_tag(Tag, Data) ->
- io_lib:format(" ~p: ~80.18p~n", [Tag, Data]).
+format_tag(Tag, Data, {_Enc,Depth}) ->
+ case Depth of
+ unlimited ->
+ io_lib:format(" ~p: ~80.18p~n", [Tag, Data]);
+ _ ->
+ io_lib:format(" ~p: ~80.18P~n", [Tag, Data, Depth])
+ end.
modifier(latin1) -> "";
modifier(_) -> "t".
+
+
+%%% -----------------------------------------------------------
+%%% Stop a process and wait for it to terminate
+%%% -----------------------------------------------------------
+-spec stop(Process) -> 'ok' when
+ Process :: pid() | RegName | {RegName,node()},
+ RegName :: atom().
+stop(Process) ->
+ stop(Process, normal, infinity).
+
+-spec stop(Process, Reason, Timeout) -> 'ok' when
+ Process :: pid() | RegName | {RegName,node()},
+ RegName :: atom(),
+ Reason :: term(),
+ Timeout :: timeout().
+stop(Process, Reason, Timeout) ->
+ {Pid, Mref} = erlang:spawn_monitor(do_stop(Process, Reason)),
+ receive
+ {'DOWN', Mref, _, _, Reason} ->
+ ok;
+ {'DOWN', Mref, _, _, {noproc,{sys,terminate,_}}} ->
+ exit(noproc);
+ {'DOWN', Mref, _, _, CrashReason} ->
+ exit(CrashReason)
+ after Timeout ->
+ exit(Pid, kill),
+ receive
+ {'DOWN', Mref, _, _, _} ->
+ exit(timeout)
+ end
+ end.
+
+-spec do_stop(Process, Reason) -> Fun when
+ Process :: pid() | RegName | {RegName,node()},
+ RegName :: atom(),
+ Reason :: term(),
+ Fun :: fun(() -> no_return()).
+do_stop(Process, Reason) ->
+ fun() ->
+ Mref = erlang:monitor(process, Process),
+ ok = sys:terminate(Process, Reason, infinity),
+ receive
+ {'DOWN', Mref, _, _, ExitReason} ->
+ exit(ExitReason)
+ end
+ end.
diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl
index 634724019f..1840fa5cc0 100644
--- a/lib/stdlib/src/proplists.erl
+++ b/lib/stdlib/src/proplists.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl
index 002032d48d..1ae7c6cc25 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -50,6 +51,8 @@
-export([template_state/0, aux_name/3, name_suffix/2, vars/1,
var_ufold/2, var_fold/3, all_selections/1]).
+-dialyzer(no_improper_lists).
+
%% When cache=list lists bigger than ?MAX_LIST_SIZE bytes are put on
%% file. Also used when merge join finds big equivalence classes.
-define(MAX_LIST_SIZE, 512*1024).
@@ -1006,7 +1009,7 @@ listify(T) ->
-record(simple_qlc,
{p, % atom(), pattern variable
le,
- line,
+ line :: erl_anno:anno(),
init_value,
optz % #optz
}).
@@ -1148,15 +1151,18 @@ abstract(Info, true=_Flat, NElements, Depth) ->
[{match,_,Expr,Q}] ->
Q;
[{match,_,Expr,Q} | Body] ->
- {block, 0, lists:reverse(Body, [Q])};
+ {block, anno0(), lists:reverse(Body, [Q])};
_ ->
- {block, 0, lists:reverse(Body0, [Expr])}
+ {block, anno0(), lists:reverse(Body0, [Expr])}
end.
-abstract({qlc, E0, Qs0, Opt}, NElements, Depth) ->
+abstract(Info, NElements, Depth) ->
+ abstract1(Info, NElements, Depth, anno1()).
+
+abstract1({qlc, E0, Qs0, Opt}, NElements, Depth, A) ->
Qs = lists:map(fun({generate, P, LE}) ->
- {generate, 1, binary_to_term(P),
- abstract(LE, NElements, Depth)};
+ {generate, A, binary_to_term(P),
+ abstract1(LE, NElements, Depth, A)};
(F) ->
binary_to_term(F)
end, Qs0),
@@ -1165,12 +1171,12 @@ abstract({qlc, E0, Qs0, Opt}, NElements, Depth) ->
[] -> [];
_ -> [abstract_term(Opt, 1)]
end,
- ?QLC_Q(1, 1, 1, 1, {lc,1,E,Qs}, Os);
-abstract({table, {M, F, As0}}, _NElements, _Depth)
+ ?QLC_Q(A, A, A, A, {lc,A,E,Qs}, Os);
+abstract1({table, {M, F, As0}}, _NElements, _Depth, Anno)
when is_atom(M), is_atom(F), is_list(As0) ->
As = [abstract_term(A, 1) || A <- As0],
- {call, 1, {remote, 1, {atom, 1, M}, {atom, 1, F}}, As};
-abstract({table, TableDesc}, _NElements, _Depth) ->
+ {call, Anno, {remote, Anno, {atom, Anno, M}, {atom, Anno, F}}, As};
+abstract1({table, TableDesc}, _NElements, _Depth, _A) ->
case io_lib:deep_char_list(TableDesc) of
true ->
{ok, Tokens, _} = erl_scan:string(lists:flatten(TableDesc++".")),
@@ -1179,27 +1185,28 @@ abstract({table, TableDesc}, _NElements, _Depth) ->
false -> % abstract expression
TableDesc
end;
-abstract({append, Infos}, NElements, Depth) ->
+abstract1({append, Infos}, NElements, Depth, A) ->
As = lists:foldr(fun(Info, As0) ->
- {cons,1,abstract(Info, NElements, Depth),As0}
- end, {nil, 1}, Infos),
- {call, 1, {remote, 1, {atom, 1, ?MODULE}, {atom, 1, append}}, [As]};
-abstract({sort, Info, SortOptions}, NElements, Depth) ->
- {call, 1, {remote, 1, {atom, 1, ?MODULE}, {atom, 1, sort}},
- [abstract(Info, NElements, Depth), abstract_term(SortOptions, 1)]};
-abstract({keysort, Info, Kp, SortOptions}, NElements, Depth) ->
- {call, 1, {remote, 1, {atom, 1, ?MODULE}, {atom, 1, keysort}},
- [abstract_term(Kp, 1), abstract(Info, NElements, Depth),
+ {cons,A,abstract1(Info, NElements, Depth, A),
+ As0}
+ end, {nil, A}, Infos),
+ {call, A, {remote, A, {atom, A, ?MODULE}, {atom, A, append}}, [As]};
+abstract1({sort, Info, SortOptions}, NElements, Depth, A) ->
+ {call, A, {remote, A, {atom, A, ?MODULE}, {atom, A, sort}},
+ [abstract1(Info, NElements, Depth, A), abstract_term(SortOptions, 1)]};
+abstract1({keysort, Info, Kp, SortOptions}, NElements, Depth, A) ->
+ {call, A, {remote, A, {atom, A, ?MODULE}, {atom, A, keysort}},
+ [abstract_term(Kp, 1), abstract1(Info, NElements, Depth, A),
abstract_term(SortOptions, 1)]};
-abstract({list,L,MS}, NElements, Depth) ->
- {call, 1, {remote, 1, {atom, 1, ets}, {atom, 1, match_spec_run}},
- [abstract(L, NElements, Depth),
- {call, 1, {remote, 1, {atom, 1, ets}, {atom, 1, match_spec_compile}},
+abstract1({list,L,MS}, NElements, Depth, A) ->
+ {call, A, {remote, A, {atom, A, ets}, {atom, A, match_spec_run}},
+ [abstract1(L, NElements, Depth, A),
+ {call, A, {remote, A, {atom, A, ets}, {atom, A, match_spec_compile}},
[abstract_term(depth(MS, Depth), 1)]}]};
-abstract({list, L}, NElements, Depth) when NElements =:= infinity;
- NElements >= length(L) ->
+abstract1({list, L}, NElements, Depth, _A) when NElements =:= infinity;
+ NElements >= length(L) ->
abstract_term(depth(L, Depth), 1);
-abstract({list, L}, NElements, Depth) ->
+abstract1({list, L}, NElements, Depth, _A) ->
abstract_term(depth(lists:sublist(L, NElements), Depth) ++ '...', 1).
depth(List, infinity) ->
@@ -1251,14 +1258,14 @@ abstract_term(Term) ->
abstract_term(Term, 0).
abstract_term(Term, Line) ->
- abstr_term(Term, Line).
+ abstr_term(Term, anno(Line)).
abstr_term(Tuple, Line) when is_tuple(Tuple) ->
{tuple,Line,[abstr_term(E, Line) || E <- tuple_to_list(Tuple)]};
abstr_term([_ | _]=L, Line) ->
case io_lib:char_list(L) of
true ->
- erl_parse:abstract(L, Line);
+ erl_parse:abstract(L, erl_anno:line(Line));
false ->
abstr_list(L, Line)
end;
@@ -1285,7 +1292,7 @@ abstr_term(Fun, Line) when is_function(Fun) ->
abstr_term(PPR, Line) when is_pid(PPR); is_port(PPR); is_reference(PPR) ->
{special, Line, lists:flatten(io_lib:write(PPR))};
abstr_term(Simple, Line) ->
- erl_parse:abstract(Simple, Line).
+ erl_parse:abstract(Simple, erl_anno:line(Line)).
abstr_list([H | T], Line) ->
{cons, Line, abstr_term(H, Line), abstr_list(T, Line)};
@@ -1519,7 +1526,7 @@ join_info(Join, QInfo, Qdata, Code) ->
%% Only compared constants (==).
[Cs1_0, Cs2_0]
end,
- L = 0,
+ L = anno0(),
G1_0 = {var,L,'G1'}, G2_0 = {var,L,'G2'},
JP = element(JQNum + 1, Code),
%% Create code for wh1 and wh2 in #join{}:
@@ -1571,7 +1578,7 @@ join_merge_info(QNum, QInfo, Code, G, ExtraConstants) ->
{P, P};
_ ->
{PV, _} = aux_name1('P', 0, abstract_vars(P)),
- L = 0,
+ L = erl_anno:new(0),
V = {var, L, PV},
{V, {match, L, V, P}}
end,
@@ -1579,19 +1586,20 @@ join_merge_info(QNum, QInfo, Code, G, ExtraConstants) ->
LEI = {generate, term_to_binary(M), LEInfo},
TP = term_to_binary(G),
CFs = [begin
- Call = {call,0,{atom,0,element},[{integer,0,Col},EPV]},
- F = list2op([{op,0,Op,abstract_term(Con),Call}
- || {Con,Op} <- ConstOps], 'or'),
+ A = anno0(),
+ Call = {call,A,{atom,A,element},[{integer,A,Col},EPV]},
+ F = list2op([{op,A,Op,abstract_term(Con),Call}
+ || {Con,Op} <- ConstOps], 'or', A),
term_to_binary(F)
end ||
{Col,ConstOps} <- ExtraConstants],
{{I,G}, [{generate, TP, {qlc, DQP, [LEI | CFs], []}}]}
end.
-list2op([E], _Op) ->
+list2op([E], _Op, _Anno) ->
E;
-list2op([E | Es], Op) ->
- {op,0,Op,E,list2op(Es, Op)}.
+list2op([E | Es], Op, Anno) ->
+ {op,Anno,Op,E,list2op(Es, Op, Anno)}.
join_lookup_info(QNum, QInfo, G) ->
{generate, _, LEInfo}=I = lists:nth(QNum, QInfo),
@@ -1704,7 +1712,7 @@ eval_le(LE_fun, GOpt) ->
prep_qlc_lc({simple_v1, PVar, LE_fun, L}, Opt, GOpt, _H) ->
check_lookup_option(Opt, false),
- prep_simple_qlc(PVar, L, eval_le(LE_fun, GOpt), Opt);
+ prep_simple_qlc(PVar, anno(L), eval_le(LE_fun, GOpt), Opt);
prep_qlc_lc({qlc_v1, QFun, CodeF, Qdata0, QOpt}, Opt, GOpt, _H) ->
F = fun(?qual_data(_QNum, _GoI, _SI, fil)=QualData, ModGens) ->
{QualData, ModGens};
@@ -1821,7 +1829,7 @@ may_create_simple(#qlc_opt{unique = Unique, cache = Cache} = Opt,
if
Unique and not IsUnique;
(Cache =/= false) and not IsCached ->
- prep_simple_qlc(?SIMPLE_QVAR, 1, Prep, Opt);
+ prep_simple_qlc(?SIMPLE_QVAR, anno(1), Prep, Opt);
true ->
Prep
end.
@@ -2764,8 +2772,8 @@ tmp_filename(TmpDirOpt) ->
U = "_",
Node = node(),
Pid = os:getpid(),
- {MSecs,Secs,MySecs} = erlang:now(),
- F = lists:concat([?MODULE,U,Node,U,Pid,U,MSecs,U,Secs,U,MySecs]),
+ Unique = erlang:unique_integer(),
+ F = lists:concat([?MODULE,U,Node,U,Pid,U,Unique]),
TmpDir = case TmpDirOpt of
"" ->
{ok, CurDir} = file:get_cwd(),
@@ -3772,6 +3780,15 @@ grd(Fun, Arg) ->
false
end.
+anno0() ->
+ anno(0).
+
+anno1() ->
+ anno(1).
+
+anno(L) ->
+ erl_anno:new(L).
+
family(L) ->
sofs:to_external(sofs:relation_to_family(sofs:relation(L))).
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index b6bb758dfb..9577d17a85 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,7 +40,12 @@
opt % #qlc_opt
}).
--record(state, {imp, maxargs, records, xwarnings = []}).
+-record(state, {imp,
+ maxargs,
+ records,
+ xwarnings = [],
+ intro_vars,
+ node_info}).
%-define(debug, true).
@@ -66,37 +72,49 @@
Options :: [Option],
Option :: type_checker | compile:option()).
-parse_transform(Forms, Options) ->
+parse_transform(Forms0, Options) ->
?DEBUG("qlc Parse Transform~n", []),
- State = #state{imp = is_qlc_q_imported(Forms),
- maxargs = ?COMPILE_MAX_NUM_OF_ARGS,
- records = record_attributes(Forms)},
- case called_from_type_checker(Options) of
- true ->
- %% The returned value should conform to the types, but
- %% need not evaluate to anything meaningful.
- L = 0,
- {tuple,_,Fs0} = abstr(#qlc_lc{}, L),
- F = fun(_Id, LC, A) ->
- Init = simple(L, 'V', LC, L),
- {{tuple,L,set_field(#qlc_lc.lc, Fs0, Init)}, A}
- end,
- {Forms1,ok} = qlc_mapfold(F, ok, Forms, State),
- Forms1;
- false ->
- FormsNoShadows = no_shadows(Forms, State),
- case compile_messages(Forms, FormsNoShadows, Options, State) of
- {[],[],Warnings} ->
- {NewForms, State1} = transform(FormsNoShadows, State),
- ExtraWs = State1#state.xwarnings,
- {[],WForms} = no_duplicates(NewForms, [], Warnings,
- ExtraWs, Options),
- WForms ++ NewForms;
- {E0,Errors,Warnings} ->
- {EForms,WForms} = no_duplicates(Forms, E0++Errors,
- Warnings, [], Options),
- EForms ++ WForms ++ Forms
- end
+ Imported = is_qlc_q_imported(Forms0),
+ {Forms, FormsNoShadows, State} = initiate(Forms0, Imported),
+ NodeInfo = State#state.node_info,
+ try
+ case called_from_type_checker(Options) of
+ true ->
+ %% The returned value should conform to the types, but
+ %% need not evaluate to anything meaningful.
+ L = anno0(),
+ {tuple,_,Fs0} = abstr(#qlc_lc{}, L),
+ F = fun(_Id, LC, A) ->
+ Init = simple(L, 'V', LC, L),
+ {{tuple,L,set_field(#qlc_lc.lc, Fs0, Init)}, A}
+ end,
+ {Forms1,ok} = qlc_mapfold(F, ok, Forms, State),
+ Forms1;
+ false ->
+ case
+ compile_messages(Forms, FormsNoShadows, Options, State)
+ of
+ {[],Warnings} ->
+ ?DEBUG("node info1 ~p~n",
+ [lists:sort(ets:tab2list(NodeInfo))]),
+ {NewForms, State1} =
+ transform(FormsNoShadows, State),
+ ExtraWs = State1#state.xwarnings,
+ {[],WForms} = no_duplicates(NewForms, [], Warnings,
+ ExtraWs, Options),
+ (restore_locations(WForms, State) ++
+ restore_anno(NewForms, NodeInfo));
+ {Errors,Warnings} ->
+ ?DEBUG("node info2 ~p~n",
+ [lists:sort(ets:tab2list(NodeInfo))]),
+ {EForms,WForms} = no_duplicates(FormsNoShadows, Errors,
+ Warnings, [],
+ Options),
+ restore_locations(EForms ++ WForms, State) ++ Forms0
+ end
+ end
+ after
+ true = ets:delete(NodeInfo)
end.
-spec(transform_from_evaluator(LC, Bs) -> Expr when
@@ -124,30 +142,78 @@ called_from_type_checker(Options) ->
lists:member(type_checker, Options).
transform_expression(LC, Bs0, WithLintErrors) ->
- L = 1,
+ L = anno1(),
As = [{var,L,V} || {V,_Val} <- Bs0],
Ar = length(As),
F = {function,L,bar,Ar,[{clause,L,As,[],[?QLC_Q(L, L, L, L, LC, [])]}]},
- Forms = [{attribute,L,file,{"foo",L}},
- {attribute,L,module,foo}, F],
- State = #state{imp = false,
- maxargs = ?EVAL_MAX_NUM_OF_ARGS,
- records = record_attributes(Forms)},
+ Forms0 = [{attribute,L,file,{"foo",L}},
+ {attribute,L,module,foo}, F],
+ {Forms, FormsNoShadows, State} = initiate(Forms0, false),
+ NodeInfo = State#state.node_info,
Options = [],
- FormsNoShadows = no_shadows(Forms, State),
- case compile_messages(Forms, FormsNoShadows, Options, State) of
- {[],[],_Warnings} ->
- {NewForms,_State1} = transform(FormsNoShadows, State),
- {function,L,bar,Ar,[{clause,L,As,[],[NF]}]} =
- lists:last(NewForms),
- {ok,NF};
- {E0,Errors,_Warnings} when WithLintErrors ->
- {not_ok,mforms(error, E0 ++ Errors)};
- {E0,Errors0,_Warnings} ->
- [{error,Reason} | _] = mforms(error, E0++Errors0),
- {not_ok, {error, ?APIMOD, Reason}}
+ try compile_messages(Forms, FormsNoShadows, Options, State) of
+ {Errors0,_Warnings} ->
+ case restore_locations(Errors0, State) of
+ [] ->
+ {NewForms,_State1} = transform(FormsNoShadows, State),
+ NewForms1 = restore_anno(NewForms, NodeInfo),
+ {function,L,bar,Ar,[{clause,L,As,[],[NF]}]} =
+ lists:last(NewForms1),
+ {ok,NF};
+ Errors when WithLintErrors ->
+ {not_ok,mforms(error, Errors)};
+ Errors ->
+ [{error,Reason} | _] = mforms(error, Errors),
+ {not_ok, {error, ?APIMOD, Reason}}
+ end
+ after
+ true = ets:delete(NodeInfo)
end.
+-ifdef(DEBUG).
+-define(ILIM, 0).
+-else.
+-define(ILIM, 255).
+-endif.
+
+initiate(Forms0, Imported) ->
+ NodeInfo = ets:new(?APIMOD, []),
+ true = ets:insert(NodeInfo, {var_n, ?ILIM}),
+ exclude_integers_from_unique_line_numbers(Forms0, NodeInfo),
+ ?DEBUG("node info0 ~p~n",
+ [lists:sort(ets:tab2list(NodeInfo))]),
+ State0 = #state{imp = Imported,
+ maxargs = ?EVAL_MAX_NUM_OF_ARGS,
+ records = record_attributes(Forms0),
+ node_info = NodeInfo},
+ Forms = save_anno(Forms0, NodeInfo),
+ FormsNoShadows = no_shadows(Forms, State0),
+ IntroVars = intro_variables(FormsNoShadows, State0),
+ State = State0#state{intro_vars = IntroVars},
+ {Forms, FormsNoShadows, State}.
+
+%% Make sure restore_locations() does not confuse integers with (the
+%% unique) line numbers.
+exclude_integers_from_unique_line_numbers(Forms, NodeInfo) ->
+ Integers = find_integers(Forms),
+ lists:foreach(fun(I) -> ets:insert(NodeInfo, {I}) end, Integers).
+
+find_integers(Forms) ->
+ F = fun(A) ->
+ Fs1 = erl_parse:map_anno(fun(_) -> A end, Forms),
+ ordsets:from_list(integers(Fs1, []))
+ end,
+ ordsets:to_list(ordsets:intersection(F(anno0()), F(anno1()))).
+
+integers([E | Es], L) ->
+ integers(Es, integers(E, L));
+integers(T, L) when is_tuple(T) ->
+ integers(tuple_to_list(T), L);
+integers(I, L) when is_integer(I), I > ?ILIM ->
+ [I | L];
+integers(_, L) ->
+ L.
+
-define(I(I), {integer, L, I}).
-define(A(A), {atom, L, A}).
-define(V(V), {var, L, V}).
@@ -164,9 +230,15 @@ mforms(Tag, L) ->
%% Avoid duplicated lint warnings and lint errors. Care has been taken
%% not to introduce unused variables in the transformed code.
%%
-no_duplicates(Forms, Errors, Warnings0, ExtraWarnings, Options) ->
+no_duplicates(Forms, Errors, Warnings0, ExtraWarnings0, Options) ->
%% Some mistakes such as "{X} =:= {}" are found by strong
%% validation as well as by qlc. Prefer the warnings from qlc:
+ %% The Compiler and qlc do not agree on the location of errors.
+ %% For now, qlc's messages about failing patterns and filters
+ %% are ignored.
+ ExtraWarnings = [W || W={_File,[{_,qlc,Tag}]} <-
+ ExtraWarnings0,
+ not lists:member(Tag, [nomatch_pattern,nomatch_filter])],
Warnings1 = mforms(Warnings0) --
([{File,[{L,v3_core,nomatch}]} ||
{File,[{L,qlc,M}]} <- mforms(ExtraWarnings),
@@ -185,13 +257,22 @@ mforms(L) ->
lists:sort([{File,[M]} || {File,Ms} <- L, M <- Ms]).
mforms2(Tag, L) ->
- Line = 0,
+ Line = anno0(),
ML = lists:flatmap(fun({File,Ms}) ->
- [[{attribute,Line,file,{File,Line}}, {Tag,M}] ||
+ [[{attribute,Line,file,{File,0}}, {Tag,M}] ||
M <- Ms]
end, lists:sort(L)),
lists:flatten(lists:sort(ML)).
+restore_locations([T | Ts], State) ->
+ [restore_locations(T, State) | restore_locations(Ts, State)];
+restore_locations(T, State) when is_tuple(T) ->
+ list_to_tuple(restore_locations(tuple_to_list(T), State));
+restore_locations(I, State) when I > ?ILIM ->
+ restore_loc(I, State);
+restore_locations(T, _State) ->
+ T.
+
is_qlc_q_imported(Forms) ->
[[] || {attribute,_,import,{?APIMOD,FAs}} <- Forms, {?Q,1} <- FAs] =/= [].
@@ -212,13 +293,20 @@ compile_messages(Forms, FormsNoShadows, Options, State) ->
(_QId, Q, GA, A) ->
{Q,GA,A}
end,
- {_,BGens} = qual_fold(BGenF, [], [], FormsNoShadows, State),
+ {_,BGens} = qual_fold(BGenF, [], [], Forms, State),
GenForm = used_genvar_check(FormsNoShadows, State),
?DEBUG("GenForm = ~ts~n", [catch erl_pp:form(GenForm)]),
- WarnFun = fun(Id, LC, A) -> {tag_lines(LC, get_lcid_no(Id)), A} end,
+ {GEs,_} = compile_forms([GenForm], Options),
+ UsedGenVarMsgs = used_genvar_messages(GEs, State),
+ NodeInfo = State#state.node_info,
+ WarnFun = fun(_Id, LC, A) -> {lc_nodes(LC, NodeInfo), A} end,
{WForms,ok} = qlc_mapfold(WarnFun, ok, Forms, State),
- {Es,Ws} = compile_forms(WForms ++ [GenForm], Options),
- {badarg(Forms, State),tagged_messages(Es)++BGens,tagged_messages(Ws)}.
+ {Es,Ws} = compile_forms(WForms, Options),
+ LcEs = lc_messages(Es, NodeInfo),
+ LcWs = lc_messages(Ws, NodeInfo),
+ Errors = badarg(Forms, State) ++ UsedGenVarMsgs++LcEs++BGens,
+ Warnings = LcWs,
+ {Errors,Warnings}.
badarg(Forms, State) ->
F = fun(_Id, {lc,_L,_E,_Qs}=LC, Es) ->
@@ -230,54 +318,39 @@ badarg(Forms, State) ->
{_,E0} = qlc_mapfold(F, [], Forms, State),
E0.
-tag_lines(E, No) ->
- map_lines(fun(Id) ->
- case is_lcid(Id) of
- true -> Id;
- false -> make_lcid(Id, No)
- end
- end, E).
-
-map_lines(F, E) ->
- erl_lint:modify_line(E, F).
-
-tagged_messages(MsL) ->
- [{File,
- [{Loc,Mod,untag(T)} || {Loc0,Mod,T} <- Ms,
- {true,Loc} <- [tloc(Loc0)]]}
- || {File,Ms} <- MsL]
- ++
+lc_nodes(E, NodeInfo) ->
+ erl_parse:map_anno(fun(Anno) ->
+ N = erl_anno:line(Anno),
+ [{N, Data}] = ets:lookup(NodeInfo, N),
+ NData = Data#{inside_lc => true},
+ true = ets:insert(NodeInfo, {N, NData}),
+ Anno
+ end, E).
+
+used_genvar_messages(MsL, S) ->
[{File,[{Loc,?APIMOD,{used_generator_variable,V}}]}
- || {_, Ms} <- MsL,
+ || {_, Ms} <- MsL,
{XLoc,erl_lint,{unbound_var,_}} <- Ms,
- {Loc,File,V} <- [extra(XLoc)]].
-
-tloc({Id,Column}) ->
- {IsLcid,T} = tloc(Id),
- {IsLcid,{T,Column}};
-tloc(Id) ->
- IsLcid = is_lcid(Id),
- {IsLcid,case IsLcid of
- true -> get_lcid_line(Id);
- false -> any
- end}.
-
-extra({extra,Line,File,V}) ->
- {Line,File,V};
-extra({Line,Column}) ->
- case extra(Line) of
- {L,File,V} -> {{L,Column},File,V};
- Else -> Else
- end;
-extra(Else) ->
- Else.
-
-untag([E | Es]) -> [untag(E) | untag(Es)];
-untag(T) when is_tuple(T) -> list_to_tuple(untag(tuple_to_list(T)));
-untag(E) ->
- case is_lcid(E) of
- true -> get_lcid_line(E);
- false -> E
+ {Loc,File,V} <- [genvar_pos(XLoc, S)]].
+
+lc_messages(MsL, NodeInfo) ->
+ [{File,[{Loc,Mod,T} || {Loc,Mod,T} <- Ms, lc_loc(Loc, NodeInfo)]} ||
+ {File,Ms} <- MsL].
+
+lc_loc(N, NodeInfo) ->
+ case ets:lookup(NodeInfo, N) of
+ [{N, #{inside_lc := true}}] ->
+ true;
+ [{N, _}] ->
+ false
+ end.
+
+genvar_pos(Location, S) ->
+ case ets:lookup(S#state.node_info, Location) of
+ [{Location, #{genvar_pos := Pos}}] ->
+ Pos;
+ [] ->
+ Location
end.
%% -> [{Qid,[variable()]}].
@@ -293,6 +366,7 @@ untag(E) ->
%% variables (unless they are unsafe).
%%
intro_variables(FormsNoShadows, State) ->
+ NodeInfo = State#state.node_info,
Fun = fun(QId, {T,_L,P0,_E0}=Q, {GVs,QIds}, Foo) when T =:= b_generate;
T =:= generate ->
PVs = qlc:var_ufold(fun({var,_,V}) -> {QId,V} end, P0),
@@ -302,10 +376,11 @@ intro_variables(FormsNoShadows, State) ->
%% where E is an LC expression consisting of a
%% template mentioning all variables occurring in F.
Vs = ordsets:to_list(qlc:vars(Filter0)),
- Id = QId#qid.lcid,
- LC1 = embed_vars(intro_set_line({QId,f1}, Vs), Id),
- LC2 = embed_vars(intro_set_line({QId,f2}, Vs), Id),
- AnyLine = -1,
+ AnyLine = anno0(),
+ Vars = [{var,AnyLine,V} || V <- Vs],
+ LC = embed_vars(Vars, AnyLine),
+ LC1 = intro_anno(LC, before, QId, NodeInfo),
+ LC2 = intro_anno(LC, 'after', QId, NodeInfo),
Filter = {block,AnyLine,[LC1,Filter0,LC2]},
{Filter,{GVs,[{QId,[]} | QIds]},Foo}
end,
@@ -317,9 +392,15 @@ intro_variables(FormsNoShadows, State) ->
Es0 = compile_errors(FForms),
%% A variable is bound inside the filter if it is not bound before
%% the filter, but it is bound after the filter (obviously).
- Before = [{QId,V} || {{QId,f1},erl_lint,{unbound_var,V}} <- Es0],
- After = [{QId,V} || {{QId,f2},erl_lint,{unbound_var,V}} <- Es0],
- Unsafe = [{QId,V} || {{QId,f2},erl_lint,{unsafe_var,V,_Where}} <- Es0],
+ Before = [{QId,V} ||
+ {L,erl_lint,{unbound_var,V}} <- Es0,
+ {_L,{QId,before}} <- ets:lookup(NodeInfo, L)],
+ After = [{QId,V} ||
+ {L,erl_lint,{unbound_var,V}} <- Es0,
+ {_L,{QId,'after'}} <- ets:lookup(NodeInfo, L)],
+ Unsafe = [{QId,V} ||
+ {L,erl_lint,{unsafe_var,V,_Where}} <- Es0,
+ {_L,{QId,'after'}} <- ets:lookup(NodeInfo, L)],
?DEBUG("Before = ~p~n", [Before]),
?DEBUG("After = ~p~n", [After]),
?DEBUG("Unsafe = ~p~n", [Unsafe]),
@@ -328,9 +409,14 @@ intro_variables(FormsNoShadows, State) ->
I1 = family(IV ++ GenVars),
sofs:to_external(sofs:family_union(sofs:family(QIds), I1)).
-intro_set_line(Tag, Vars) ->
- L = erl_parse:set_line(1, fun(_) -> Tag end),
- [{var,L,V} || V <- Vars].
+intro_anno(LC, Where, QId, NodeInfo) ->
+ Data = {QId,Where},
+ Fun = fun(Anno) ->
+ Location = erl_anno:location(Anno),
+ true = ets:insert(NodeInfo, {Location,Data}),
+ Anno
+ end,
+ erl_parse:map_anno(Fun, save_anno(LC, NodeInfo)).
compile_errors(FormsNoShadows) ->
case compile_forms(FormsNoShadows, []) of
@@ -341,11 +427,14 @@ compile_errors(FormsNoShadows) ->
lists:flatmap(fun({_File,Es}) -> Es end, Errors)
end.
--define(MAX_NUM_OF_LINES, 23). % assume max 1^23 lines (> 8 millions)
-
compile_forms(Forms0, Options) ->
- Forms = [F || F <- Forms0, element(1, F) =/= eof] ++
- [{eof,1 bsl ?MAX_NUM_OF_LINES}],
+ Exclude = fun(eof) -> true;
+ (warning) -> true;
+ (error) -> true;
+ (_) -> false
+ end,
+ Forms = ([F || F <- Forms0, not Exclude(element(1, F))]
+ ++ [{eof,anno0()}]),
try
case compile:noenv_forms(Forms, compile_options(Options)) of
{ok, _ModName, Ws0} ->
@@ -384,20 +473,23 @@ bitstr_options() ->
%% for each ListExpr. The expression mentions all introduced variables
%% occurring in ListExpr. Running the function through the compiler
%% yields error messages for erroneous use of introduced variables.
-%% The messages have the form
-%% {{extra,LineNo,File,Var},Module,{unbound_var,V}}, where Var is the
-%% original variable name and V is the name invented by no_shadows/2.
%%
used_genvar_check(FormsNoShadows, State) ->
- F = fun(QId, {T, Ln, _P, LE}=Q, {QsIVs0, Exprs0}, IVsSoFar0)
+ NodeInfo = State#state.node_info,
+ F = fun(QId, {T, Ln, _P, LE}=Q, {QsIVs0, Exprs0}, IVsSoFar0)
when T =:= b_generate; T =:= generate ->
- F = fun({var, _, V}=Var) ->
- {var, L, OrigVar} = undo_no_shadows(Var),
- AF = fun(Line) ->
- {extra, Line, get(?QLC_FILE), OrigVar}
- end,
- L2 = erl_parse:set_line(L, AF),
- {var, L2, V}
+ F = fun(Var) ->
+ {var, Anno0, OrigVar} =
+ undo_no_shadows(Var, State),
+ {var, Anno, _} = NewVar = save_anno(Var, NodeInfo),
+ Location0 = erl_anno:location(Anno0),
+ Location = erl_anno:location(Anno),
+ [{Location, Data}] =
+ ets:lookup(NodeInfo, Location),
+ Pos = {Location0,get(?QLC_FILE),OrigVar},
+ NData = Data#{genvar_pos => Pos},
+ true = ets:insert(NodeInfo, {Location, NData}),
+ NewVar
end,
Vs = [Var || {var, _, V}=Var <- qlc:var_fold(F, [], LE),
lists:member(V, IVsSoFar0)],
@@ -411,12 +503,12 @@ used_genvar_check(FormsNoShadows, State) ->
{QsIVs, IVsSoFar} = q_intro_vars(QId, QsIVs0, IVsSoFar0),
{Filter, {QsIVs, Exprs}, IVsSoFar}
end,
- IntroVars = intro_variables(FormsNoShadows, State),
- Acc0 = {IntroVars, [{atom, 0, true}]},
+ Acc0 = {State#state.intro_vars, [{atom, anno0(), true}]},
{_, {[], Exprs}} = qual_fold(F, Acc0, [], FormsNoShadows, State),
FunctionNames = [Name || {function, _, Name, _, _} <- FormsNoShadows],
UniqueFName = qlc:aux_name(used_genvar, 1, sets:from_list(FunctionNames)),
- {function,0,UniqueFName,0,[{clause,0,[],[],lists:reverse(Exprs)}]}.
+ A = anno0(),
+ {function,A,UniqueFName,0,[{clause,A,[],[],lists:reverse(Exprs)}]}.
q_intro_vars(QId, [{QId, IVs} | QsIVs], IVsSoFar) -> {QsIVs, IVs ++ IVsSoFar}.
@@ -514,7 +606,8 @@ q_intro_vars(QId, [{QId, IVs} | QsIVs], IVsSoFar) -> {QsIVs, IVs ++ IVsSoFar}.
%% (calling LEf returns the objects generated by LE).
transform(FormsNoShadows, State) ->
- IntroVars = intro_variables(FormsNoShadows, State),
+ _ = erlang:system_flag(backtrace_depth, 500),
+ IntroVars = State#state.intro_vars,
AllVars = sets:from_list(ordsets:to_list(qlc:vars(FormsNoShadows))),
?DEBUG("AllVars = ~p~n", [sets:to_list(AllVars)]),
F1 = fun(QId, {generate,_,P,LE}, Foo, {GoI,SI}) ->
@@ -588,8 +681,8 @@ transform(FormsNoShadows, State) ->
[{match,L,{var,L,Fun},FunC},
{call,L,{var,L,Fun},As0}]}]}},
{ok, OrigE0} = dict:find(Id, Source),
- OrigE = undo_no_shadows(OrigE0),
- QCode = qcode(OrigE, XQCs, Source, L),
+ OrigE = undo_no_shadows(OrigE0, State),
+ QCode = qcode(OrigE, XQCs, Source, L, State),
Qdata = qdata(XQCs, L),
TemplateInfo =
template_columns(Qs, E, AllIVs, Dependencies, State),
@@ -598,7 +691,7 @@ transform(FormsNoShadows, State) ->
Opt = opt_info(TemplateInfo, SizeInfo, JoinInfo, MSQs, L,
EqColumnConstants, EqualColumnConstants),
LCTuple =
- case qlc_kind(OrigE, Qs) of
+ case qlc_kind(OrigE, Qs, State) of
qlc ->
{tuple,L,[?A(qlc_v1),FunW,QCode,Qdata,Opt]};
{simple, PL, LE, V} ->
@@ -612,7 +705,7 @@ transform(FormsNoShadows, State) ->
end,
{NForms,{[],XW}} = qlc_mapfold(F2, {IntroVars,[]}, ModifiedForms1, State),
display_forms(NForms),
- {restore_line_numbers(NForms), State#state{xwarnings = XW}}.
+ {NForms, State#state{xwarnings = XW}}.
join_kind(Qs, LcL, AllIVs, Dependencies, State) ->
{EqualCols2, EqualColsN} = equal_columns(Qs, AllIVs, Dependencies, State),
@@ -623,20 +716,21 @@ join_kind(Qs, LcL, AllIVs, Dependencies, State) ->
if
EqualColsN =/= []; MatchColsN =/= [] ->
{[],
- [{get(?QLC_FILE),[{abs(LcL),?APIMOD,too_complex_join}]}]};
+ [{get(?QLC_FILE),[{LcL,?APIMOD,too_complex_join}]}]};
EqualCols2 =:= [], MatchCols2 =:= [] ->
{[], []};
length(Tables) > 2 ->
{[],
- [{get(?QLC_FILE),[{abs(LcL),?APIMOD,too_many_joins}]}]};
+ [{get(?QLC_FILE),[{LcL,?APIMOD,too_many_joins}]}]};
EqualCols2 =:= MatchCols2 ->
{EqualCols2, []};
true ->
{{EqualCols2, MatchCols2}, []}
end.
-qlc_kind(OrigE, Qs) ->
- {OrigFilterData, OrigGeneratorData} = qual_data(undo_no_shadows(Qs)),
+qlc_kind(OrigE, Qs, State) ->
+ {OrigFilterData, OrigGeneratorData} =
+ qual_data(undo_no_shadows(Qs, State)),
OrigAllFilters = filters_as_one(OrigFilterData),
{_FilterData, GeneratorData} = qual_data(Qs),
case {OrigE, OrigAllFilters, OrigGeneratorData} of
@@ -663,12 +757,12 @@ warn_failing_qualifiers(Qualifiers, AllIVs, Dependencies, State) ->
lists:foldl(fun({_QId,{fil,_Filter}}, {[]=Frames,Warnings}) ->
{Frames,Warnings};
({_QId,{fil,Filter}}, {Frames,Warnings}) ->
- case filter(set_line(Filter, 0), Frames, BindFun,
+ case filter(reset_anno(Filter), Frames, BindFun,
State, Imported) of
[] ->
{[],
[{get(?QLC_FILE),
- [{abs_loc(element(2, Filter)),?APIMOD,
+ [{loc(element(2, Filter)),?APIMOD,
nomatch_filter}]} | Warnings]};
Frames1 ->
{Frames1,Warnings}
@@ -678,7 +772,7 @@ warn_failing_qualifiers(Qualifiers, AllIVs, Dependencies, State) ->
{failed, _, _} ->
{Frames,
[{get(?QLC_FILE),
- [{abs_loc(element(2, Pattern)),?APIMOD,
+ [{loc(element(2, Pattern)),?APIMOD,
nomatch_pattern}]} | Warnings]};
_ ->
{Frames,Warnings}
@@ -751,8 +845,8 @@ opt_constants(L, ColumnConstants) ->
|| IdNo <- Ns]
++ [{clause,L,[?V('_')],[],[?A(no_column_fun)]}].
-abstr(Term, Line) ->
- erl_parse:abstract(Term, Line).
+abstr(Term, Anno) ->
+ erl_parse:abstract(Term, loc(Anno)).
%% Extra generators are introduced for join.
join_quals(JoinInfo, QCs, L, LcNo, ExtraConstants, AllVars) ->
@@ -837,9 +931,10 @@ join_handle(AP, L, [F, H, O, C], Constants) ->
{{var, _, _}, []} ->
{'fun',L,{clauses,[{clause,L,[H],[],[H]}]}};
_ ->
+ A = anno0(),
G0 = [begin
- Call = {call,0,{atom,0,element},[{integer,0,Col},O]},
- list2op([{op,0,Op,Con,Call} || {Con,Op} <- Cs], 'or')
+ Call = {call,A,{atom,A,element},[{integer,A,Col},O]},
+ list2op([{op,A,Op,Con,Call} || {Con,Op} <- Cs], 'or')
end || {Col,Cs} <- Constants],
G = if G0 =:= [] -> G0; true -> [G0] end,
CC1 = {clause,L,[AP],G,[{cons,L,O,closure({call,L,F,[F,C]},L)}]},
@@ -876,14 +971,15 @@ join_handle_constants(QId, ExtraConstants) ->
%% order the traverse fun would return them.
column_fun(Columns, QualifierNumber, LcL) ->
+ A = anno0(),
ColCls0 =
[begin
true = Vs0 =/= [], % at least one value to look up
Vs1 = list2cons(Vs0),
- Fils1 = {tuple,0,[{atom,0,FTag},
+ Fils1 = {tuple,A,[{atom,A,FTag},
lists:foldr
- (fun(F, A) -> {cons,0,{integer,0,F},A}
- end, {nil,0}, Fils)]},
+ (fun(F, Ac) -> {cons,A,{integer,A,F},Ac}
+ end, {nil,A}, Fils)]},
Tag = case ordsets:to_list(qlc:vars(Vs1)) of
Imp when length(Imp) > 0, % imported vars
length(Vs0) > 1 ->
@@ -891,13 +987,13 @@ column_fun(Columns, QualifierNumber, LcL) ->
_ ->
values
end,
- Vs = {tuple,0,[{atom,0,Tag},Vs1,Fils1]},
- {clause,0,[erl_parse:abstract(Col)],[],[Vs]}
+ Vs = {tuple,A,[{atom,A,Tag},Vs1,Fils1]},
+ {clause,A,[erl_parse:abstract(Col)],[],[Vs]}
end ||
{{CIdNo,Col}, Vs0, {FTag,Fils}} <- Columns,
CIdNo =:= QualifierNumber]
- ++ [{clause,0,[{var,0,'_'}],[],[{atom,0,false}]}],
- ColCls = set_line(ColCls0, LcL),
+ ++ [{clause,A,[{var,A,'_'}],[],[{atom,A,false}]}],
+ ColCls = set_anno(ColCls0, LcL),
{'fun', LcL, {clauses, ColCls}}.
%% Tries to find columns of the template that (1) are equal to (or
@@ -920,7 +1016,7 @@ template_columns(Qs0, E0, AllIVs, Dependencies, State) ->
MatchColumns = eq_columns2(Qs, AllIVs, Dependencies, State),
Equal = template_cols(EqualColumns),
Match = template_cols(MatchColumns),
- L = 0,
+ L = anno0(),
if
Match =:= Equal ->
[{?V('_'), Match}];
@@ -947,7 +1043,7 @@ template_cols(ColumnClasses) ->
template_as_pattern(E) ->
P = simple_template(E),
- {?TID,foo,foo,{gen,P,{nil,0}}}.
+ {?TID,foo,foo,{gen,P,{nil,anno0()}}}.
simple_template({call,L,{remote,_,{atom,_,erlang},{atom,_,element}}=Call,
[{integer,_,I}=A1,A2]}) when I > 0 ->
@@ -1004,10 +1100,10 @@ match_spec_quals(Template, Dependencies, Qualifiers, State) ->
GQId =:= QId2,
{FQId,{fil,F}}=Filter <- Filters, % guard filters only
FQId =:= QId]
- ++ [{GId#qid.no,Pattern,[],{atom,0,true}} ||
+ ++ [{GId#qid.no,Pattern,[],{atom,anno0(),true}} ||
{GId,{gen,Pattern,_}} <- GeneratorData,
lists:member(GId, NoFilterGIds)],
- E = {nil, 0},
+ E = {nil, anno0()},
GF = [{{GNum,Pattern},Filter} ||
{GNum,Pattern,Filter,F} <- Candidates,
no =/= try_ms(E, Pattern, F, State)],
@@ -1024,7 +1120,7 @@ match_spec_quals(Template, Dependencies, Qualifiers, State) ->
%% expressione can be replaced by a match specification.
[{GNum, AbstrMS, all}]
catch _:_ ->
- {TemplVar, _} = anon_var({var,0,'_'}, 0),
+ {TemplVar, _} = anon_var({var,anno0(),'_'}, 0),
[one_gen_match_spec(GNum, Pattern, GFilterData, State, TemplVar) ||
{{GNum,Pattern},GFilterData} <- GFFL]
end.
@@ -1038,7 +1134,7 @@ gen_ms(E, Pattern, GFilterData, State) ->
{ok, MS, AMS} = try_ms(E, Pattern, filters_as_one(GFilterData), State),
case MS of
[{'$1',[true],['$1']}] ->
- {atom, 0, no_match_spec};
+ {atom, anno0(), no_match_spec};
_ ->
AMS
end.
@@ -1060,7 +1156,7 @@ pattern_as_template({match,_,_E,{var,_,_}=V}=P, _TemplVar) ->
pattern_as_template({match,_,{var,_,_}=V,_E}=P, _TemplVar) ->
{V, P};
pattern_as_template(E, TemplVar) ->
- L = 0,
+ L = anno0(),
{TemplVar, {match, L, E, TemplVar}}.
%% Tries to find columns which are compared or matched against
@@ -1203,7 +1299,7 @@ lu_skip(ColConstants, FilterData, PatternFrame, PatternVars,
ColFil = [{Column, FId#qid.no} ||
{FId,{fil,Fil}} <-
filter_list(FilterData, Dependencies, State),
- [] =/= (SFs = safe_filter(set_line(Fil, 0), PatternFrames,
+ [] =/= (SFs = safe_filter(reset_anno(Fil), PatternFrames,
BindFun, State, Imported)),
{GId,PV} <- PatternVars,
[] =/=
@@ -1392,7 +1488,7 @@ join_skip(JoinClasses, FilterData, PatternFrame, PatternVars, Dependencies,
JF = unify(JoinOp, V1, V2, JF2, BindFun, Imported),
%% "Run" the filter:
- SFs = safe_filter(set_line(Fil, 0), PatternFrames,
+ SFs = safe_filter(reset_anno(Fil), PatternFrames,
BindFun, State, Imported),
JImp = qlc:vars([SFs, JF]), % kludge
lists:all(fun(Frame) ->
@@ -1403,7 +1499,7 @@ join_skip(JoinClasses, FilterData, PatternFrame, PatternVars, Dependencies,
filter_info(FilterData, AllIVs, Dependencies, State) ->
FilterList = filter_list(FilterData, Dependencies, State),
- Filter0 = set_line(filters_as_one(FilterList), 0),
+ Filter0 = reset_anno(filters_as_one(FilterList)),
Anon0 = 0,
{Filter, Anon1} = anon_var(Filter0, Anon0),
Imported = ordsets:subtract(qlc:vars(Filter), % anonymous too
@@ -1510,7 +1606,7 @@ pattern(P0, AnonI, Frame0, BindFun, State) ->
catch _:_ -> P0 % template, records already expanded
end,
%% Makes test for equality simple:
- P2 = set_line(P1, 0),
+ P2 = reset_anno(P1),
{P3, AnonN} = anon_var(P2, AnonI),
{P4, F1} = match_in_pattern(tuple2cons(P3), Frame0, BindFun),
{P, F2} = element_calls(P4, F1, BindFun, _Imp=[]), % kludge for templates
@@ -1550,8 +1646,11 @@ anon_var(E, AnonI) ->
(Var, N) -> {Var, N}
end, AnonI, E).
-set_line(T, L) ->
- map_lines(fun(_L) -> L end, T).
+reset_anno(T) ->
+ set_anno(T, anno0()).
+
+set_anno(T, A) ->
+ erl_parse:map_anno(fun(_L) -> A end, T).
-record(fstate, {state, bind_fun, imported}).
@@ -1673,7 +1772,7 @@ frames_to_columns(Fs, PatternVars, DerefFun, SelectorFun, Imp, CompOp) ->
%% same variables have to be the representatives in every frame.)
SizesVarsL =
[begin
- PatVar = {var,0,PV},
+ PatVar = {var,anno0(),PV},
PatternSizes = [pattern_size([F], PatVar, false) ||
F <- Fs],
MaxPZ = lists:max([0 | PatternSizes -- [undefined]]),
@@ -1692,8 +1791,8 @@ frames_to_columns(Fs, PatternVars, DerefFun, SelectorFun, Imp, CompOp) ->
frames2cols(Fs, PatN, PatSizes, Vars, DerefFun, SelectorFun, CompOp) ->
Rs = [ begin
RL = [{{PatN,Col},cons2tuple(element(2, Const))} ||
- {V, Col} <- lists:zip(sublist(Vars, PatSz),
- seq(1, PatSz)),
+ {V, Col} <- lists:zip(lists:sublist(Vars, PatSz),
+ lists:seq(1, PatSz)),
%% Do not handle the case where several
%% values compare equal, e.g. "X =:= 1
%% andalso X == 1.0". Looking up both
@@ -1722,11 +1821,11 @@ frames2cols(Fs, PatN, PatSizes, Vars, DerefFun, SelectorFun, CompOp) ->
[C || {_,Vs}=C <- sofs:to_external(Cs), not col_ignore(Vs, CompOp)].
pat_vars(N) ->
- [unique_var() || _ <- seq(1, N)].
+ [unique_var() || _ <- lists:seq(1, N)].
pat_tuple(Sz, Vars) when is_integer(Sz), Sz > 0 ->
TupleTail = unique_var(),
- {cons_tuple, list2cons(sublist(Vars, Sz) ++ TupleTail)};
+ {cons_tuple, list2cons(lists:sublist(Vars, Sz) ++ TupleTail)};
pat_tuple(_, _Vars) ->
unique_var().
@@ -1740,7 +1839,7 @@ col_ignore(Vs, '==') ->
pattern_sizes(PatternVars, Fs) ->
[{QId#qid.no, Size} ||
{QId,PV} <- PatternVars,
- undefined =/= (Size = pattern_size(Fs, {var,0,PV}, true))].
+ undefined =/= (Size = pattern_size(Fs, {var,anno0(),PV}, true))].
pattern_size(Fs, PatternVar, Exact) ->
Fun = fun(F) -> (deref_pattern(_Imported = []))(PatternVar, F) end,
@@ -1768,7 +1867,8 @@ prep_expr(E, F, S, BF, Imported) ->
element_calls(tuple2cons(expand_expr_records(E, S)), F, BF, Imported).
unify_column(Frame, Var, Col, BindFun, Imported) ->
- Call = {call,0,{atom,0,element},[{integer,0,Col}, {var,0,Var}]},
+ A = anno0(),
+ Call = {call,A,{atom,A,element},[{integer,A,Col}, {var,A,Var}]},
element_calls(Call, Frame, BindFun, Imported).
%% cons_tuple is used for representing {V1, ..., Vi | TupleTail}.
@@ -1800,19 +1900,21 @@ element_calls(E, F, _BF, _Imported) ->
{E, F}.
unique_var() ->
- {var, 0, make_ref()}.
+ {var, anno0(), make_ref()}.
is_unique_var({var, _L, V}) ->
is_reference(V).
expand_pattern_records(P, State) ->
- E = {'case',0,{atom,0,true},[{clause,0,[P],[],[{atom,0,true}]}]},
- {'case',_,_,[{clause,0,[NP],_,_}]} = expand_expr_records(E, State),
+ A = anno0(),
+ E = {'case',A,{atom,A,true},[{clause,A,[P],[],[{atom,A,true}]}]},
+ {'case',_,_,[{clause,A,[NP],_,_}]} = expand_expr_records(E, State),
NP.
expand_expr_records(E, State) ->
RecordDefs = State#state.records,
- Forms = RecordDefs ++ [{function,1,foo,0,[{clause,1,[],[],[pe(E)]}]}],
+ A = anno1(),
+ Forms = RecordDefs ++ [{function,A,foo,0,[{clause,A,[],[],[pe(E)]}]}],
[{function,_,foo,0,[{clause,_,[],[],[NE]}]}] =
erl_expand_records:module(Forms, [no_strict_record_tests]),
NE.
@@ -2126,15 +2228,15 @@ tuple2cons(E) ->
E.
list2cons([E | Es]) ->
- {cons, 0, E, list2cons(Es)};
+ {cons, anno0(), E, list2cons(Es)};
list2cons([]) ->
- {nil, 0};
+ {nil, anno0()};
list2cons(E) ->
E.
%% Returns {..., Variable} if Variable is a tuple tail.
cons2tuple({cons_tuple, Es}) ->
- {tuple, 0, cons2list(Es)};
+ {tuple, anno0(), cons2list(Es)};
cons2tuple(T) when is_tuple(T) ->
list_to_tuple(cons2tuple(tuple_to_list(T)));
cons2tuple([E | Es]) ->
@@ -2173,11 +2275,10 @@ bindings_subset(F1, F2, Imp) ->
%% not to have guard semantics, affected filters will have to be
%% recognized and excluded here as well.
try_ms(E, P, Fltr, State) ->
- L = 1,
+ L = anno1(),
Fun = {'fun',L,{clauses,[{clause,L,[P],[[Fltr]],[E]}]}},
Expr = {call,L,{remote,L,{atom,L,ets},{atom,L,fun2ms}},[Fun]},
- Form0 = {function,L,foo,0,[{clause,L,[],[],[Expr]}]},
- Form = restore_line_numbers(Form0),
+ Form = {function,L,foo,0,[{clause,L,[],[],[Expr]}]},
X = ms_transform:parse_transform(State#state.records ++ [Form], []),
case catch
begin
@@ -2194,11 +2295,11 @@ try_ms(E, P, Fltr, State) ->
end.
filters_as_one([]) ->
- {atom, 0, true};
+ {atom, anno0(), true};
filters_as_one(FilterData) ->
[{_,{fil,Filter1}} | Filters] = lists:reverse(FilterData),
lists:foldr(fun({_QId,{fil,Filter}}, AbstF) ->
- {op,0,'andalso',Filter,AbstF}
+ {op,anno0(),'andalso',Filter,AbstF}
end, Filter1, Filters).
qual_data(Qualifiers) ->
@@ -2233,38 +2334,40 @@ qdata([], L) ->
{nil,L}.
qcon(Cs) ->
- list2cons([{tuple,0,[{integer,0,Col},list2cons(qcon1(ConstOps))]} ||
+ A = anno0(),
+ list2cons([{tuple,A,[{integer,A,Col},list2cons(qcon1(ConstOps))]} ||
{Col,ConstOps} <- Cs]).
qcon1(ConstOps) ->
- [{tuple,0,[Const,abstr(Op, 0)]} || {Const,Op} <- ConstOps].
+ A = anno0(),
+ [{tuple,A,[Const,abstr(Op, A)]} || {Const,Op} <- ConstOps].
%% The original code (in Source) is used for filters and the template
%% since the translated code can have QLCs and we don't want them to
%% be visible.
-qcode(E, QCs, Source, L) ->
+qcode(E, QCs, Source, L, State) ->
CL = [begin
Bin = term_to_binary(C, [compressed]),
{bin, L, [{bin_element, L,
{string, L, binary_to_list(Bin)},
default, default}]}
end || {_,C} <- lists:keysort(1, [{qlc:template_state(),E} |
- qcode(QCs, Source)])],
+ qcode(QCs, Source, State)])],
{'fun', L, {clauses, [{clause, L, [], [], [{tuple, L, CL}]}]}}.
-qcode([{_QId, {_QIvs, {{gen,P,_LE,_GV}, GoI, _SI}}} | QCs], Source) ->
- [{GoI,undo_no_shadows(P)} | qcode(QCs, Source)];
-qcode([{QId, {_QIVs, {{fil,_F}, GoI, _SI}}} | QCs], Source) ->
+qcode([{_QId, {_QIvs, {{gen,P,_LE,_GV}, GoI, _SI}}} | QCs], Source, State) ->
+ [{GoI,undo_no_shadows(P, State)} | qcode(QCs, Source, State)];
+qcode([{QId, {_QIVs, {{fil,_F}, GoI, _SI}}} | QCs], Source, State) ->
{ok,OrigF} = dict:find(QId, Source),
- [{GoI,undo_no_shadows(OrigF)} | qcode(QCs, Source)];
-qcode([], _Source) ->
+ [{GoI,undo_no_shadows(OrigF, State)} | qcode(QCs, Source, State)];
+qcode([], _Source, _State) ->
[].
closure(Code, L) ->
{'fun',L,{clauses,[{clause,L,[],[],[Code]}]}}.
-simple(L, Var, Init, Line) ->
- {tuple,L,[?A(simple_v1),?A(Var),Init,?I(Line)]}.
+simple(L, Var, Init, Anno) ->
+ {tuple,L,[?A(simple_v1),?A(Var),Init,abstr(loc(Anno), Anno)]}.
clauses([{QId,{QIVs,{QualData,GoI,S}}} | QCs], RL, Fun, Go, NGV, E, IVs,St) ->
?DEBUG("QIVs = ~p~n", [QIVs]),
@@ -2426,19 +2529,22 @@ aux_var(Name, LcN, QN, N, AllVars) ->
qlc:aux_name(lists:concat([Name, LcN, '_', QN, '_']), N, AllVars).
no_compiler_warning(L) ->
- erl_parse:set_line(L, fun(Line) -> -abs(Line) end).
+ Anno = erl_anno:new(L),
+ erl_anno:set_generated(true, Anno).
-abs_loc(L) ->
- loc(erl_parse:set_line(L, fun(Line) -> abs(Line) end)).
-
-loc(L) ->
- {location,Location} = erl_parse:get_attribute(L, location),
- Location.
+loc(A) ->
+ erl_anno:location(A).
list2op([E], _Op) ->
E;
list2op([E | Es], Op) ->
- {op,0,Op,E,list2op(Es, Op)}.
+ {op,anno0(),Op,E,list2op(Es, Op)}.
+
+anno0() ->
+ erl_anno:new(0).
+
+anno1() ->
+ erl_anno:new(1).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2491,13 +2597,61 @@ qlcmf(T, _F, _Imp, A, No) ->
occ_vars(E) ->
qlc:var_fold(fun({var,_L,V}) -> V end, [], E).
+%% Every Anno is replaced by a unique number. The number is used in a
+%% table that holds data about the abstract node where Anno resides.
+%% In particular, the original location is kept there, so that the
+%% original abstract code can be re-created.
+save_anno(Abstr, NodeInfo) ->
+ F = fun(Anno) ->
+ N = next_slot(NodeInfo),
+ Location = erl_anno:location(Anno),
+ Data = {N, #{location => Location}},
+ true = ets:insert(NodeInfo, Data),
+ erl_anno:new(N)
+ end,
+ erl_parse:map_anno(F, Abstr).
+
+next_slot(T) ->
+ I = ets:update_counter(T, var_n, 1),
+ case ets:lookup(T, I) of
+ [] ->
+ I;
+ _ ->
+ next_slot(T)
+ end.
+
+restore_anno(Abstr, NodeInfo) ->
+ F = fun(Anno) ->
+ Location = erl_anno:location(Anno),
+ case ets:lookup(NodeInfo, Location) of
+ [{Location, Data}] ->
+ OrigLocation = maps:get(location, Data),
+ erl_anno:set_location(OrigLocation, Anno);
+ [{Location}] -> % generated code
+ Anno;
+ [] ->
+ Anno
+ end
+ end,
+ erl_parse:map_anno(F, Abstr).
+
+restore_loc(Location, #state{node_info = NodeInfo}) ->
+ case ets:lookup(NodeInfo, Location) of
+ [{Location, #{location := OrigLocation}}] ->
+ OrigLocation;
+ [{Location}] ->
+ Location;
+ [] ->
+ Location
+ end.
+
no_shadows(Forms0, State) ->
%% Variables that may shadow other variables are introduced in
%% LCs and Funs. Such variables (call them SV, Shadowing
%% Variables) are now renamed. Each (new) occurrence in a pattern
%% is assigned an index (integer), unique in the file.
%%
- %% The state {LastIndex,ActiveVars,UsedVars,AllVars,Singletons}
+ %% The state {LastIndex,ActiveVars,UsedVars,AllVars,Singletons,State}
%% holds the last index used for each SV (LastIndex), the SVs in
%% the current scope (ActiveVars), used SVs (UsedVars, the indexed
%% name is the key), all variables occurring in the file
@@ -2507,16 +2661,15 @@ no_shadows(Forms0, State) ->
%% the indexed name of an SV occurs in the file, next index is
%% tried (to avoid mixing up introduced names with existing ones).
%%
- %% The original names of variables are kept in the line number
- %% position of the abstract code: {var, {nos, OriginalName, L},
- %% NewName}. undo_no_shadows/1 re-creates the original code.
+ %% The original names of variables are kept in a table in State.
+ %% undo_no_shadows/2 re-creates the original code.
AllVars = sets:from_list(ordsets:to_list(qlc:vars(Forms0))),
?DEBUG("nos AllVars = ~p~n", [sets:to_list(AllVars)]),
VFun = fun(_Id, LC, Vs) -> nos(LC, Vs) end,
LI = ets:new(?APIMOD,[]),
UV = ets:new(?APIMOD,[]),
D0 = dict:new(),
- S1 = {LI, D0, UV, AllVars, []},
+ S1 = {LI, D0, UV, AllVars, [], State},
_ = qlc_mapfold(VFun, S1, Forms0, State),
?DEBUG("UsedIntroVars = ~p~n", [ets:match_object(UV, '_')]),
Singletons = ets:select(UV, ets:fun2ms(fun({K,0}) -> K end)),
@@ -2524,7 +2677,7 @@ no_shadows(Forms0, State) ->
true = ets:delete_all_objects(LI),
true = ets:delete_all_objects(UV),
%% Do it again, this time we know which variables are singletons.
- S2 = {LI, D0, UV, AllVars, Singletons},
+ S2 = {LI, D0, UV, AllVars, Singletons, State},
{Forms,_} = qlc_mapfold(VFun, S2, Forms0, State),
true = ets:delete(LI),
true = ets:delete(UV),
@@ -2568,11 +2721,11 @@ nos({lc,L,E0,Qs0}, S) ->
{Qs, S1} = lists:mapfoldl(F, S, Qs0),
{E, _} = nos(E0, S1),
{{lc,L,E,Qs}, S};
-nos({var,L,V}=Var, {_LI,Vs,UV,_A,_Sg}=S) when V =/= '_' ->
+nos({var,L,V}=Var, {_LI,Vs,UV,_A,_Sg,State}=S) when V =/= '_' ->
case used_var(V, Vs, UV) of
{true, VN} ->
- NL = nos_var(L, V),
- {{var,NL,VN}, S};
+ nos_var(L, V, State),
+ {{var,L,VN}, S};
false ->
{Var, S}
end;
@@ -2590,7 +2743,7 @@ nos_pattern([P0 | Ps0], S0, PVs0) ->
{P, S1, PVs1} = nos_pattern(P0, S0, PVs0),
{Ps, S, PVs} = nos_pattern(Ps0, S1, PVs1),
{[P | Ps], S, PVs};
-nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg}, PVs0) when V =/= '_' ->
+nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' ->
{Name, Vs, PVs} =
case lists:keyfind(V, 1, PVs0) of
{V, VN} ->
@@ -2604,16 +2757,25 @@ nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg}, PVs0) when V =/= '_' ->
end,
{N, Vs1, [{V,VN} | PVs0]}
end,
- NL = nos_var(L, V),
- {{var,NL,Name}, {LI,Vs,UV,A,Sg}, PVs};
+ nos_var(L, V, State),
+ {{var,L,Name}, {LI,Vs,UV,A,Sg,State}, PVs};
nos_pattern(T, S0, PVs0) when is_tuple(T) ->
{TL, S, PVs} = nos_pattern(tuple_to_list(T), S0, PVs0),
{list_to_tuple(TL), S, PVs};
nos_pattern(T, S, PVs) ->
{T, S, PVs}.
-nos_var(L, Name) ->
- erl_parse:set_line(L, fun(Line) -> {nos,Name,Line} end).
+nos_var(Anno, Name, State) ->
+ NodeInfo = State#state.node_info,
+ Location = erl_anno:location(Anno),
+ case ets:lookup(NodeInfo, Location) of
+ [{Location, #{name := _}}] ->
+ true;
+ [{Location, Data}] ->
+ true = ets:insert(NodeInfo, {Location, Data#{name => Name}});
+ [] -> % cannot happen
+ true
+ end.
used_var(V, Vs, UV) ->
case dict:find(V, Vs) of
@@ -2638,69 +2800,30 @@ next_var(V, Vs, AllVars, LI, UV) ->
{VN, NVs}
end.
-undo_no_shadows(E) ->
- var_map(fun undo_no_shadows1/1, E).
-
-undo_no_shadows1({var, L, _}=Var) ->
- case erl_parse:get_attribute(L, line) of
- {line,{nos,V,_VL}} ->
- NL = erl_parse:set_line(L, fun({nos,_V,VL}) -> VL end),
- undo_no_shadows1({var, NL, V});
- _Else ->
- Var
- end.
-
-restore_line_numbers(E) ->
- var_map(fun restore_line_numbers1/1, E).
+undo_no_shadows(E, State) ->
+ var_map(fun(Anno) -> undo_no_shadows1(Anno, State) end, E).
-restore_line_numbers1({var, L, V}=Var) ->
- case erl_parse:get_attribute(L, line) of
- {line,{nos,_,_}} ->
- NL = erl_parse:set_line(L, fun({nos,_V,VL}) -> VL end),
- restore_line_numbers1({var, NL, V});
- _Else ->
+undo_no_shadows1({var, Anno, _}=Var, State) ->
+ Location = erl_anno:location(Anno),
+ NodeInfo = State#state.node_info,
+ case ets:lookup(NodeInfo, Location) of
+ [{Location, #{name := Name}}] ->
+ {var, Anno, Name};
+ _ ->
Var
end.
%% QLC identifier.
%% The first one encountered in the file has No=1.
-make_lcid(Attrs, No) when is_integer(No), No > 0 ->
- F = fun(Line) when is_integer(Line), Line < (1 bsl ?MAX_NUM_OF_LINES) ->
- sgn(Line) * ((No bsl ?MAX_NUM_OF_LINES) + sgn(Line) * Line)
- end,
- erl_parse:set_line(Attrs, F).
-
-is_lcid(Attrs) ->
- try
- {line,Id} = erl_parse:get_attribute(Attrs, line),
- is_integer(Id) andalso (abs(Id) > (1 bsl ?MAX_NUM_OF_LINES))
- catch _:_ ->
- false
- end.
-
-get_lcid_no(IdAttrs) ->
- {line,Id} = erl_parse:get_attribute(IdAttrs, line),
- abs(Id) bsr ?MAX_NUM_OF_LINES.
-
-get_lcid_line(IdAttrs) ->
- {line,Id} = erl_parse:get_attribute(IdAttrs, line),
- sgn(Id) * (abs(Id) band ((1 bsl ?MAX_NUM_OF_LINES) - 1)).
+make_lcid(Anno, No) when is_integer(No), No > 0 ->
+ {No, erl_anno:line(Anno)}.
-sgn(X) when X >= 0 ->
- 1;
-sgn(X) when X < 0 ->
- -1.
+get_lcid_no({No, _Line}) ->
+ No.
-seq(S, E) when S - E =:= 1 ->
- [];
-seq(S, E) ->
- lists:seq(S, E).
-
-sublist(_, 0) ->
- [];
-sublist(L, N) ->
- lists:sublist(L, N).
+get_lcid_line({_No, Line}) ->
+ Line.
qid(LCId, No) ->
#qid{no = No, lcid = LCId}.
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 472d503b99..2e65759d2a 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -48,7 +49,7 @@
-opaque queue(Item) :: {list(Item), list(Item)}.
--opaque queue() :: queue(_).
+-type queue() :: queue(_).
%% Creation, inspection and conversion
diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl
new file mode 100644
index 0000000000..d455abf7b0
--- /dev/null
+++ b/lib/stdlib/src/rand.erl
@@ -0,0 +1,596 @@
+%%
+%% %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%
+%%
+%% =====================================================================
+%% Multiple PRNG module for Erlang/OTP
+%% Copyright (c) 2015 Kenji Rikitake
+%% =====================================================================
+
+-module(rand).
+
+-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,
+ normal/0, normal_s/1
+ ]).
+
+-compile({inline, [exs64_next/1, exsplus_next/1,
+ exs1024_next/1, exs1024_calc/2,
+ get_52/1, normal_kiwi/1]}).
+
+-define(DEFAULT_ALG_HANDLER, exsplus).
+-define(SEED_DICT, rand_seed).
+
+%% =====================================================================
+%% Types
+%% =====================================================================
+
+%% This depends on the algorithm handler function
+-type alg_seed() :: exs64_state() | exsplus_state() | exs1024_state().
+%% This is the algorithm handler function within this module
+-type alg_handler() :: #{type => alg(),
+ max => integer(),
+ next => fun(),
+ uniform => fun(),
+ uniform_n => fun()}.
+
+%% Internal state
+-opaque state() :: {alg_handler(), alg_seed()}.
+-type alg() :: exs64 | exsplus | exs1024.
+-opaque export_state() :: {alg(), alg_seed()}.
+-export_type([alg/0, state/0, export_state/0]).
+
+%% =====================================================================
+%% API
+%% =====================================================================
+
+%% Return algorithm and seed so that RNG state can be recreated with seed/1
+-spec export_seed() -> undefined | export_state().
+export_seed() ->
+ case get(?SEED_DICT) of
+ {#{type:=Alg}, Seed} -> {Alg, Seed};
+ _ -> undefined
+ end.
+
+-spec export_seed_s(state()) -> export_state().
+export_seed_s({#{type:=Alg}, Seed}) -> {Alg, Seed}.
+
+%% seed(Alg) seeds RNG with runtime dependent values
+%% and return the NEW state
+
+%% seed({Alg,Seed}) setup RNG with a previously exported seed
+%% and return the NEW state
+
+-spec seed(AlgOrExpState::alg() | export_state()) -> state().
+seed(Alg) ->
+ R = seed_s(Alg),
+ _ = seed_put(R),
+ R.
+
+-spec seed_s(AlgOrExpState::alg() | export_state()) -> state().
+seed_s(Alg) when is_atom(Alg) ->
+ seed_s(Alg, {erlang:phash2([{node(),self()}]),
+ erlang:system_time(),
+ erlang:unique_integer()});
+seed_s({Alg0, Seed}) ->
+ {Alg,_SeedFun} = mk_alg(Alg0),
+ {Alg, Seed}.
+
+%% seed/2: seeds RNG with the algorithm and given values
+%% and returns the NEW state.
+
+-spec seed(Alg :: alg(), {integer(), integer(), integer()}) -> state().
+seed(Alg0, S0) ->
+ State = seed_s(Alg0, S0),
+ _ = seed_put(State),
+ State.
+
+-spec seed_s(Alg :: alg(), {integer(), integer(), integer()}) -> state().
+seed_s(Alg0, S0 = {_, _, _}) ->
+ {Alg, Seed} = mk_alg(Alg0),
+ AS = Seed(S0),
+ {Alg, AS}.
+
+%%% uniform/0, uniform/1, uniform_s/1, uniform_s/2 are all
+%%% uniformly distributed random numbers.
+
+%% uniform/0: returns a random float X where 0.0 < X < 1.0,
+%% updating the state in the process dictionary.
+
+-spec uniform() -> X::float().
+uniform() ->
+ {X, Seed} = uniform_s(seed_get()),
+ _ = seed_put(Seed),
+ X.
+
+%% uniform/1: given an integer N >= 1,
+%% uniform/1 returns a random integer X where 1 =< X =< N,
+%% updating the state in the process dictionary.
+
+-spec uniform(N :: pos_integer()) -> X::pos_integer().
+uniform(N) ->
+ {X, Seed} = uniform_s(N, seed_get()),
+ _ = seed_put(Seed),
+ X.
+
+%% uniform_s/1: given a state, uniform_s/1
+%% returns a random float X where 0.0 < X < 1.0,
+%% and a new state.
+
+-spec uniform_s(state()) -> {X::float(), NewS :: state()}.
+uniform_s(State = {#{uniform:=Uniform}, _}) ->
+ Uniform(State).
+
+%% uniform_s/2: given an integer N >= 1 and a state, uniform_s/2
+%% uniform_s/2 returns a random integer X where 1 =< X =< N,
+%% and a new state.
+
+-spec uniform_s(N::pos_integer(), state()) -> {X::pos_integer(), NewS::state()}.
+uniform_s(N, State = {#{uniform_n:=Uniform, max:=Max}, _})
+ when 0 < N, N =< Max ->
+ Uniform(N, State);
+uniform_s(N, State0 = {#{uniform:=Uniform}, _})
+ when is_integer(N), 0 < N ->
+ {F, State} = Uniform(State0),
+ {trunc(F * N) + 1, State}.
+
+%% normal/0: returns a random float with standard normal distribution
+%% updating the state in the process dictionary.
+
+-spec normal() -> float().
+normal() ->
+ {X, Seed} = normal_s(seed_get()),
+ _ = seed_put(Seed),
+ X.
+
+%% normal_s/1: returns a random float with standard normal distribution
+%% The Ziggurat Method for generating random variables - Marsaglia and Tsang
+%% Paper and reference code: http://www.jstatsoft.org/v05/i08/
+
+-spec normal_s(state()) -> {float(), NewS :: state()}.
+normal_s(State0) ->
+ {Sign, R, State} = get_52(State0),
+ Idx = R band 16#FF,
+ Idx1 = Idx+1,
+ {Ki, Wi} = normal_kiwi(Idx1),
+ X = R * Wi,
+ case R < Ki of
+ %% Fast path 95% of the time
+ true when Sign =:= 0 -> {X, State};
+ true -> {-X, State};
+ %% Slow path
+ false when Sign =:= 0 -> normal_s(Idx, Sign, X, State);
+ false -> normal_s(Idx, Sign, -X, State)
+ end.
+
+%% =====================================================================
+%% Internal functions
+
+-define(UINT21MASK, 16#00000000001fffff).
+-define(UINT32MASK, 16#00000000ffffffff).
+-define(UINT33MASK, 16#00000001ffffffff).
+-define(UINT39MASK, 16#0000007fffffffff).
+-define(UINT58MASK, 16#03ffffffffffffff).
+-define(UINT64MASK, 16#ffffffffffffffff).
+
+-type uint64() :: 0..16#ffffffffffffffff.
+-type uint58() :: 0..16#03ffffffffffffff.
+
+-spec seed_put(state()) -> undefined | state().
+seed_put(Seed) ->
+ put(?SEED_DICT, Seed).
+
+seed_get() ->
+ case get(?SEED_DICT) of
+ undefined -> seed(?DEFAULT_ALG_HANDLER);
+ Old -> Old % no type checking here
+ end.
+
+%% 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},
+ 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},
+ 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},
+ fun exs1024_seed/1}.
+
+%% =====================================================================
+%% exs64 PRNG: Xorshift64*
+%% Algorithm by Sebastiano Vigna
+%% Reference URL: http://xorshift.di.unimi.it/
+%% =====================================================================
+
+-type exs64_state() :: uint64().
+
+exs64_seed({A1, A2, A3}) ->
+ {V1, _} = exs64_next(((A1 band ?UINT32MASK) * 4294967197 + 1)),
+ {V2, _} = exs64_next(((A2 band ?UINT32MASK) * 4294967231 + 1)),
+ {V3, _} = exs64_next(((A3 band ?UINT32MASK) * 4294967279 + 1)),
+ ((V1 * V2 * V3) rem (?UINT64MASK - 1)) + 1.
+
+%% Advance xorshift64* state for one step and generate 64bit unsigned integer
+-spec exs64_next(exs64_state()) -> {uint64(), exs64_state()}.
+exs64_next(R) ->
+ R1 = R bxor (R bsr 12),
+ R2 = R1 bxor ((R1 band ?UINT39MASK) bsl 25),
+ R3 = R2 bxor (R2 bsr 27),
+ {(R3 * 2685821657736338717) band ?UINT64MASK, R3}.
+
+exs64_uniform({Alg, R0}) ->
+ {V, R1} = exs64_next(R0),
+ {V / 18446744073709551616, {Alg, R1}}.
+
+exs64_uniform(Max, {Alg, R}) ->
+ {V, R1} = exs64_next(R),
+ {(V rem Max) + 1, {Alg, R1}}.
+
+%% =====================================================================
+%% exsplus PRNG: Xorshift116+
+%% Algorithm by Sebastiano Vigna
+%% Reference URL: http://xorshift.di.unimi.it/
+%% 58 bits fits into an immediate on 64bits erlang and is thus much faster.
+%% Modification of the original Xorshift128+ algorithm to 116
+%% by Sebastiano Vigna, a lot of thanks for his help and work.
+%% =====================================================================
+-type exsplus_state() :: nonempty_improper_list(uint58(), uint58()).
+
+-dialyzer({no_improper_lists, exsplus_seed/1}).
+
+exsplus_seed({A1, A2, A3}) ->
+ {_, R1} = exsplus_next([(((A1 * 4294967197) + 1) band ?UINT58MASK)|
+ (((A2 * 4294967231) + 1) band ?UINT58MASK)]),
+ {_, R2} = exsplus_next([(((A3 * 4294967279) + 1) band ?UINT58MASK)|
+ tl(R1)]),
+ R2.
+
+-dialyzer({no_improper_lists, exsplus_next/1}).
+
+%% Advance xorshift116+ state for one step and generate 58bit unsigned integer
+-spec exsplus_next(exsplus_state()) -> {uint58(), exsplus_state()}.
+exsplus_next([S1|S0]) ->
+ %% Note: members s0 and s1 are swapped here
+ S11 = (S1 bxor (S1 bsl 24)) band ?UINT58MASK,
+ S12 = S11 bxor S0 bxor (S11 bsr 11) bxor (S0 bsr 41),
+ {(S0 + S12) band ?UINT58MASK, [S0|S12]}.
+
+exsplus_uniform({Alg, R0}) ->
+ {I, R1} = exsplus_next(R0),
+ {I / (?UINT58MASK+1), {Alg, R1}}.
+
+exsplus_uniform(Max, {Alg, R}) ->
+ {V, R1} = exsplus_next(R),
+ {(V rem Max) + 1, {Alg, R1}}.
+
+%% =====================================================================
+%% exs1024 PRNG: Xorshift1024*
+%% Algorithm by Sebastiano Vigna
+%% Reference URL: http://xorshift.di.unimi.it/
+%% =====================================================================
+
+-type exs1024_state() :: {list(uint64()), list(uint64())}.
+
+exs1024_seed({A1, A2, A3}) ->
+ B1 = (((A1 band ?UINT21MASK) + 1) * 2097131) band ?UINT21MASK,
+ B2 = (((A2 band ?UINT21MASK) + 1) * 2097133) band ?UINT21MASK,
+ B3 = (((A3 band ?UINT21MASK) + 1) * 2097143) band ?UINT21MASK,
+ {exs1024_gen1024((B1 bsl 43) bor (B2 bsl 22) bor (B3 bsl 1) bor 1),
+ []}.
+
+%% Generate a list of 16 64-bit element list
+%% of the xorshift64* random sequence
+%% from a given 64-bit seed.
+%% Note: dependent on exs64_next/1
+-spec exs1024_gen1024(uint64()) -> list(uint64()).
+exs1024_gen1024(R) ->
+ exs1024_gen1024(16, R, []).
+
+exs1024_gen1024(0, _, L) ->
+ L;
+exs1024_gen1024(N, R, L) ->
+ {X, R2} = exs64_next(R),
+ exs1024_gen1024(N - 1, R2, [X|L]).
+
+%% Calculation of xorshift1024*.
+%% exs1024_calc(S0, S1) -> {X, NS1}.
+%% X: random number output
+-spec exs1024_calc(uint64(), uint64()) -> {uint64(), uint64()}.
+exs1024_calc(S0, S1) ->
+ S11 = S1 bxor ((S1 band ?UINT33MASK) bsl 31),
+ S12 = S11 bxor (S11 bsr 11),
+ S01 = S0 bxor (S0 bsr 30),
+ NS1 = S01 bxor S12,
+ {(NS1 * 1181783497276652981) band ?UINT64MASK, NS1}.
+
+%% Advance xorshift1024* state for one step and generate 64bit unsigned integer
+-spec exs1024_next(exs1024_state()) -> {uint64(), exs1024_state()}.
+exs1024_next({[S0,S1|L3], RL}) ->
+ {X, NS1} = exs1024_calc(S0, S1),
+ {X, {[NS1|L3], [S0|RL]}};
+exs1024_next({[H], RL}) ->
+ NL = [H|lists:reverse(RL)],
+ exs1024_next({NL, []}).
+
+exs1024_uniform({Alg, R0}) ->
+ {V, R1} = exs1024_next(R0),
+ {V / 18446744073709551616, {Alg, R1}}.
+
+exs1024_uniform(Max, {Alg, R}) ->
+ {V, R1} = exs1024_next(R),
+ {(V rem Max) + 1, {Alg, R1}}.
+
+%% =====================================================================
+%% Ziggurat cont
+%% =====================================================================
+-define(NOR_R, 3.6541528853610087963519472518).
+-define(NOR_INV_R, 1/?NOR_R).
+
+%% return a {sign, Random51bits, State}
+get_52({Alg=#{next:=Next}, S0}) ->
+ {Int,S1} = Next(S0),
+ {((1 bsl 51) band Int), Int band ((1 bsl 51)-1), {Alg, S1}}.
+
+%% Slow path
+normal_s(0, Sign, X0, State0) ->
+ {U0, S1} = uniform_s(State0),
+ X = -?NOR_INV_R*math:log(U0),
+ {U1, S2} = uniform_s(S1),
+ Y = -math:log(U1),
+ case Y+Y > X*X of
+ false ->
+ normal_s(0, Sign, X0, S2);
+ true when Sign =:= 0 ->
+ {?NOR_R + X, S2};
+ true ->
+ {-?NOR_R - X, S2}
+ end;
+normal_s(Idx, _Sign, X, State0) ->
+ Fi2 = normal_fi(Idx+1),
+ {U0, S1} = uniform_s(State0),
+ case ((normal_fi(Idx) - Fi2)*U0 + Fi2) < math:exp(-0.5*X*X) of
+ true -> {X, S1};
+ false -> normal_s(S1)
+ end.
+
+%% Tables for generating normal_s
+%% ki is zipped with wi (slightly faster)
+normal_kiwi(Indx) ->
+ element(Indx,
+ {{2104047571236786,1.736725412160263e-15}, {0,9.558660351455634e-17},
+ {1693657211986787,1.2708704834810623e-16},{1919380038271141,1.4909740962495474e-16},
+ {2015384402196343,1.6658733631586268e-16},{2068365869448128,1.8136120810119029e-16},
+ {2101878624052573,1.9429720153135588e-16},{2124958784102998,2.0589500628482093e-16},
+ {2141808670795147,2.1646860576895422e-16},{2154644611568301,2.2622940392218116e-16},
+ {2164744887587275,2.353271891404589e-16},{2172897953696594,2.438723455742877e-16},
+ {2179616279372365,2.5194879829274225e-16},{2185247251868649,2.5962199772528103e-16},
+ {2190034623107822,2.6694407473648285e-16},{2194154434521197,2.7395729685142446e-16},
+ {2197736978774660,2.8069646002484804e-16},{2200880740891961,2.871905890411393e-16},
+ {2203661538010620,2.9346417484728883e-16},{2206138681109102,2.9953809336782113e-16},
+ {2208359231806599,3.054303000719244e-16},{2210361007258210,3.111563633892157e-16},
+ {2212174742388539,3.1672988018581815e-16},{2213825672704646,3.2216280350549905e-16},
+ {2215334711002614,3.274657040793975e-16},{2216719334487595,3.326479811684171e-16},
+ {2217994262139172,3.377180341735323e-16},{2219171977965032,3.4268340353119356e-16},
+ {2220263139538712,3.475508873172976e-16},{2221276900117330,3.523266384600203e-16},
+ {2222221164932930,3.5701624633953494e-16},{2223102796829069,3.616248057159834e-16},
+ {2223927782546658,3.661569752965354e-16},{2224701368170060,3.7061702777236077e-16},
+ {2225428170204312,3.75008892787478e-16},{2226112267248242,3.7933619401549554e-16},
+ {2226757276105256,3.836022812967728e-16},{2227366415328399,3.8781025861250247e-16},
+ {2227942558554684,3.919630085325768e-16},{2228488279492521,3.9606321366256378e-16},
+ {2229005890047222,4.001133755254669e-16},{2229497472775193,4.041158312414333e-16},
+ {2229964908627060,4.080727683096045e-16},{2230409900758597,4.119862377480744e-16},
+ {2230833995044585,4.1585816580828064e-16},{2231238597816133,4.1969036444740733e-16},
+ {2231624991250191,4.234845407152071e-16},{2231994346765928,4.272423051889976e-16},
+ {2232347736722750,4.309651795716294e-16},{2232686144665934,4.346546035512876e-16},
+ {2233010474325959,4.383119410085457e-16},{2233321557544881,4.4193848564470665e-16},
+ {2233620161276071,4.455354660957914e-16},{2233906993781271,4.491040505882875e-16},
+ {2234182710130335,4.52645351185714e-16},{2234447917093496,4.561604276690038e-16},
+ {2234703177503020,4.596502910884941e-16},{2234949014150181,4.631159070208165e-16},
+ {2235185913274316,4.665581985600875e-16},{2235414327692884,4.699780490694195e-16},
+ {2235634679614920,4.733763047158324e-16},{2235847363174595,4.767537768090853e-16},
+ {2236052746716837,4.8011124396270155e-16},{2236251174862869,4.834494540935008e-16},
+ {2236442970379967,4.867691262742209e-16},{2236628435876762,4.900709524522994e-16},
+ {2236807855342765,4.933555990465414e-16},{2236981495548562,4.966237084322178e-16},
+ {2237149607321147,4.998759003240909e-16},{2237312426707209,5.031127730659319e-16},
+ {2237470176035652,5.0633490483427195e-16},{2237623064889403,5.095428547633892e-16},
+ {2237771290995388,5.127371639978797e-16},{2237915041040597,5.159183566785736e-16},
+ {2238054491421305,5.190869408670343e-16},{2238189808931712,5.222434094134042e-16},
+ {2238321151397660,5.253882407719454e-16},{2238448668260432,5.285218997682382e-16},
+ {2238572501115169,5.316448383216618e-16},{2238692784207942,5.34757496126473e-16},
+ {2238809644895133,5.378603012945235e-16},{2238923204068402,5.409536709623993e-16},
+ {2239033576548190,5.440380118655467e-16},{2239140871448443,5.471137208817361e-16},
+ {2239245192514958,5.501811855460336e-16},{2239346638439541,5.532407845392784e-16},
+ {2239445303151952,5.56292888151909e-16},{2239541276091442,5.593378587248462e-16},
+ {2239634642459498,5.623760510690043e-16},{2239725483455293,5.65407812864896e-16},
+ {2239813876495186,5.684334850436814e-16},{2239899895417494,5.714534021509204e-16},
+ {2239983610673676,5.744678926941961e-16},{2240065089506935,5.774772794756965e-16},
+ {2240144396119183,5.804818799107686e-16},{2240221591827230,5.834820063333892e-16},
+ {2240296735208969,5.864779662894365e-16},{2240369882240293,5.894700628185872e-16},
+ {2240441086423386,5.924585947256134e-16},{2240510398907004,5.95443856841806e-16},
+ {2240577868599305,5.984261402772028e-16},{2240643542273726,6.014057326642664e-16},
+ {2240707464668391,6.043829183936125e-16},{2240769678579486,6.073579788423606e-16},
+ {2240830224948980,6.103311925956439e-16},{2240889142947082,6.133028356617911e-16},
+ {2240946470049769,6.162731816816596e-16},{2241002242111691,6.192425021325847e-16},
+ {2241056493434746,6.222110665273788e-16},{2241109256832602,6.251791426088e-16},
+ {2241160563691400,6.281469965398895e-16},{2241210444026879,6.311148930905604e-16},
+ {2241258926538122,6.34083095820806e-16},{2241306038658137,6.370518672608815e-16},
+ {2241351806601435,6.400214690888025e-16},{2241396255408788,6.429921623054896e-16},
+ {2241439408989313,6.459642074078832e-16},{2241481290160038,6.489378645603397e-16},
+ {2241521920683062,6.519133937646159e-16},{2241561321300462,6.548910550287415e-16},
+ {2241599511767028,6.578711085350741e-16},{2241636510880960,6.608538148078259e-16},
+ {2241672336512612,6.638394348803506e-16},{2241707005631362,6.668282304624746e-16},
+ {2241740534330713,6.698204641081558e-16},{2241772937851689,6.728163993837531e-16},
+ {2241804230604585,6.758163010371901e-16},{2241834426189161,6.78820435168298e-16},
+ {2241863537413311,6.818290694006254e-16},{2241891576310281,6.848424730550038e-16},
+ {2241918554154466,6.878609173251664e-16},{2241944481475843,6.908846754557169e-16},
+ {2241969368073071,6.939140229227569e-16},{2241993223025298,6.969492376174829e-16},
+ {2242016054702685,6.999906000330764e-16},{2242037870775710,7.030383934552151e-16},
+ {2242058678223225,7.060929041565482e-16},{2242078483339331,7.091544215954873e-16},
+ {2242097291739040,7.122232386196779e-16},{2242115108362774,7.152996516745303e-16},
+ {2242131937479672,7.183839610172063e-16},{2242147782689725,7.214764709364707e-16},
+ {2242162646924736,7.245774899788387e-16},{2242176532448092,7.276873311814693e-16},
+ {2242189440853337,7.308063123122743e-16},{2242201373061537,7.339347561177405e-16},
+ {2242212329317416,7.370729905789831e-16},{2242222309184237,7.4022134917658e-16},
+ {2242231311537397,7.433801711647648e-16},{2242239334556717,7.465498018555889e-16},
+ {2242246375717369,7.497305929136979e-16},{2242252431779415,7.529229026624058e-16},
+ {2242257498775893,7.561270964017922e-16},{2242261571999416,7.5934354673958895e-16},
+ {2242264645987196,7.625726339356756e-16},{2242266714504453,7.658147462610487e-16},
+ {2242267770526109,7.690702803721919e-16},{2242267806216711,7.723396417018299e-16},
+ {2242266812908462,7.756232448671174e-16},{2242264781077289,7.789215140963852e-16},
+ {2242261700316818,7.822348836756411e-16},{2242257559310145,7.855637984161084e-16},
+ {2242252345799276,7.889087141441755e-16},{2242246046552082,7.922700982152271e-16},
+ {2242238647326615,7.956484300529366e-16},{2242230132832625,7.99044201715713e-16},
+ {2242220486690076,8.024579184921259e-16},{2242209691384458,8.058900995272657e-16},
+ {2242197728218684,8.093412784821501e-16},{2242184577261310,8.128120042284501e-16},
+ {2242170217290819,8.163028415809877e-16},{2242154625735679,8.198143720706533e-16},
+ {2242137778609839,8.23347194760605e-16},{2242119650443327,8.26901927108847e-16},
+ {2242100214207556,8.304792058805374e-16},{2242079441234906,8.340796881136629e-16},
+ {2242057301132135,8.377040521420222e-16},{2242033761687079,8.413529986798028e-16},
+ {2242008788768107,8.450272519724097e-16},{2241982346215682,8.487275610186155e-16},
+ {2241954395725356,8.524547008695596e-16},{2241924896721443,8.562094740106233e-16},
+ {2241893806220517,8.599927118327665e-16},{2241861078683830,8.638052762005259e-16},
+ {2241826665857598,8.676480611245582e-16},{2241790516600041,8.715219945473698e-16},
+ {2241752576693881,8.754280402517175e-16},{2241712788642916,8.793671999021043e-16},
+ {2241671091451078,8.833405152308408e-16},{2241627420382235,8.873490703813135e-16},
+ {2241581706698773,8.913939944224086e-16},{2241533877376767,8.954764640495068e-16},
+ {2241483854795281,8.9959770648911e-16},{2241431556397035,9.037590026260118e-16},
+ {2241376894317345,9.079616903740068e-16},{2241319774977817,9.122071683134846e-16},
+ {2241260098640860,9.164968996219135e-16},{2241197758920538,9.208324163262308e-16},
+ {2241132642244704,9.252153239095693e-16},{2241064627262652,9.296473063086417e-16},
+ {2240993584191742,9.341301313425265e-16},{2240919374095536,9.38665656618666e-16},
+ {2240841848084890,9.432558359676707e-16},{2240760846432232,9.479027264651738e-16},
+ {2240676197587784,9.526084961066279e-16},{2240587717084782,9.57375432209745e-16},
+ {2240495206318753,9.622059506294838e-16},{2240398451183567,9.671026058823054e-16},
+ {2240297220544165,9.720681022901626e-16},{2240191264522612,9.771053062707209e-16},
+ {2240080312570155,9.822172599190541e-16},{2239964071293331,9.874071960480671e-16},
+ {2239842221996530,9.926785548807976e-16},{2239714417896699,9.980350026183645e-16},
+ {2239580280957725,1.003480452143618e-15},{2239439398282193,1.0090190861637457e-15},
+ {2239291317986196,1.0146553831467086e-15},{2239135544468203,1.0203941464683124e-15},
+ {2238971532964979,1.0262405372613567e-15},{2238798683265269,1.0322001115486456e-15},
+ {2238616332424351,1.03827886235154e-15},{2238423746288095,1.044483267600047e-15},
+ {2238220109591890,1.0508203448355195e-15},{2238004514345216,1.057297713900989e-15},
+ {2237775946143212,1.06392366906768e-15},{2237533267957822,1.0707072623632994e-15},
+ {2237275200846753,1.0776584002668106e-15},{2237000300869952,1.0847879564403425e-15},
+ {2236706931309099,1.0921079038149563e-15},{2236393229029147,1.0996314701785628e-15},
+ {2236057063479501,1.1073733224935752e-15},{2235695986373246,1.1153497865853155e-15},
+ {2235307169458859,1.1235791107110833e-15},{2234887326941578,1.1320817840164846e-15},
+ {2234432617919447,1.140880924258278e-15},{2233938522519765,1.1500027537839792e-15},
+ {2233399683022677,1.159477189144919e-15},{2232809697779198,1.169338578691096e-15},
+ {2232160850599817,1.17962663529558e-15},{2231443750584641,1.190387629928289e-15},
+ {2230646845562170,1.2016759392543819e-15},{2229755753817986,1.2135560818666897e-15},
+ {2228752329126533,1.2261054417450561e-15},{2227613325162504,1.2394179789163251e-15},
+ {2226308442121174,1.2536093926602567e-15},{2224797391720399,1.268824481425501e-15},
+ {2223025347823832,1.2852479319096109e-15},{2220915633329809,1.3031206634689985e-15},
+ {2218357446087030,1.3227655770195326e-15},{2215184158448668,1.3446300925011171e-15},
+ {2211132412537369,1.3693606835128518e-15},{2205758503851065,1.397943667277524e-15},
+ {2198248265654987,1.4319989869661328e-15},{2186916352102141,1.4744848603597596e-15},
+ {2167562552481814,1.5317872741611144e-15},{2125549880839716,1.6227698675312968e-15}}).
+
+normal_fi(Indx) ->
+ element(Indx,
+ {1.0000000000000000e+00,9.7710170126767082e-01,9.5987909180010600e-01,
+ 9.4519895344229909e-01,9.3206007595922991e-01,9.1999150503934646e-01,
+ 9.0872644005213032e-01,8.9809592189834297e-01,8.8798466075583282e-01,
+ 8.7830965580891684e-01,8.6900868803685649e-01,8.6003362119633109e-01,
+ 8.5134625845867751e-01,8.4291565311220373e-01,8.3471629298688299e-01,
+ 8.2672683394622093e-01,8.1892919160370192e-01,8.1130787431265572e-01,
+ 8.0384948317096383e-01,7.9654233042295841e-01,7.8937614356602404e-01,
+ 7.8234183265480195e-01,7.7543130498118662e-01,7.6863731579848571e-01,
+ 7.6195334683679483e-01,7.5537350650709567e-01,7.4889244721915638e-01,
+ 7.4250529634015061e-01,7.3620759812686210e-01,7.2999526456147568e-01,
+ 7.2386453346862967e-01,7.1781193263072152e-01,7.1183424887824798e-01,
+ 7.0592850133275376e-01,7.0009191813651117e-01,6.9432191612611627e-01,
+ 6.8861608300467136e-01,6.8297216164499430e-01,6.7738803621877308e-01,
+ 6.7186171989708166e-01,6.6639134390874977e-01,6.6097514777666277e-01,
+ 6.5561147057969693e-01,6.5029874311081637e-01,6.4503548082082196e-01,
+ 6.3982027745305614e-01,6.3465179928762327e-01,6.2952877992483625e-01,
+ 6.2445001554702606e-01,6.1941436060583399e-01,6.1442072388891344e-01,
+ 6.0946806492577310e-01,6.0455539069746733e-01,5.9968175261912482e-01,
+ 5.9484624376798689e-01,5.9004799633282545e-01,5.8528617926337090e-01,
+ 5.8055999610079034e-01,5.7586868297235316e-01,5.7121150673525267e-01,
+ 5.6658776325616389e-01,5.6199677581452390e-01,5.5743789361876550e-01,
+ 5.5291049042583185e-01,5.4841396325526537e-01,5.4394773119002582e-01,
+ 5.3951123425695158e-01,5.3510393238045717e-01,5.3072530440366150e-01,
+ 5.2637484717168403e-01,5.2205207467232140e-01,5.1775651722975591e-01,
+ 5.1348772074732651e-01,5.0924524599574761e-01,5.0502866794346790e-01,
+ 5.0083757512614835e-01,4.9667156905248933e-01,4.9253026364386815e-01,
+ 4.8841328470545758e-01,4.8432026942668288e-01,4.8025086590904642e-01,
+ 4.7620473271950547e-01,4.7218153846772976e-01,4.6818096140569321e-01,
+ 4.6420268904817391e-01,4.6024641781284248e-01,4.5631185267871610e-01,
+ 4.5239870686184824e-01,4.4850670150720273e-01,4.4463556539573912e-01,
+ 4.4078503466580377e-01,4.3695485254798533e-01,4.3314476911265209e-01,
+ 4.2935454102944126e-01,4.2558393133802180e-01,4.2183270922949573e-01,
+ 4.1810064983784795e-01,4.1438753404089090e-01,4.1069314827018799e-01,
+ 4.0701728432947315e-01,4.0335973922111429e-01,3.9972031498019700e-01,
+ 3.9609881851583223e-01,3.9249506145931540e-01,3.8890886001878855e-01,
+ 3.8534003484007706e-01,3.8178841087339344e-01,3.7825381724561896e-01,
+ 3.7473608713789086e-01,3.7123505766823922e-01,3.6775056977903225e-01,
+ 3.6428246812900372e-01,3.6083060098964775e-01,3.5739482014578022e-01,
+ 3.5397498080007656e-01,3.5057094148140588e-01,3.4718256395679348e-01,
+ 3.4380971314685055e-01,3.4045225704452164e-01,3.3711006663700588e-01,
+ 3.3378301583071823e-01,3.3047098137916342e-01,3.2717384281360129e-01,
+ 3.2389148237639104e-01,3.2062378495690530e-01,3.1737063802991350e-01,
+ 3.1413193159633707e-01,3.1090755812628634e-01,3.0769741250429189e-01,
+ 3.0450139197664983e-01,3.0131939610080288e-01,2.9815132669668531e-01,
+ 2.9499708779996164e-01,2.9185658561709499e-01,2.8872972848218270e-01,
+ 2.8561642681550159e-01,2.8251659308370741e-01,2.7943014176163772e-01,
+ 2.7635698929566810e-01,2.7329705406857691e-01,2.7025025636587519e-01,
+ 2.6721651834356114e-01,2.6419576399726080e-01,2.6118791913272082e-01,
+ 2.5819291133761890e-01,2.5521066995466168e-01,2.5224112605594190e-01,
+ 2.4928421241852824e-01,2.4633986350126363e-01,2.4340801542275012e-01,
+ 2.4048860594050039e-01,2.3758157443123795e-01,2.3468686187232990e-01,
+ 2.3180441082433859e-01,2.2893416541468023e-01,2.2607607132238020e-01,
+ 2.2323007576391746e-01,2.2039612748015194e-01,2.1757417672433113e-01,
+ 2.1476417525117358e-01,2.1196607630703015e-01,2.0917983462112499e-01,
+ 2.0640540639788071e-01,2.0364274931033485e-01,2.0089182249465656e-01,
+ 1.9815258654577511e-01,1.9542500351413428e-01,1.9270903690358912e-01,
+ 1.9000465167046496e-01,1.8731181422380025e-01,1.8463049242679927e-01,
+ 1.8196065559952254e-01,1.7930227452284767e-01,1.7665532144373500e-01,
+ 1.7401977008183875e-01,1.7139559563750595e-01,1.6878277480121151e-01,
+ 1.6618128576448205e-01,1.6359110823236570e-01,1.6101222343751107e-01,
+ 1.5844461415592431e-01,1.5588826472447920e-01,1.5334316106026283e-01,
+ 1.5080929068184568e-01,1.4828664273257453e-01,1.4577520800599403e-01,
+ 1.4327497897351341e-01,1.4078594981444470e-01,1.3830811644855071e-01,
+ 1.3584147657125373e-01,1.3338602969166913e-01,1.3094177717364430e-01,
+ 1.2850872227999952e-01,1.2608687022018586e-01,1.2367622820159654e-01,
+ 1.2127680548479021e-01,1.1888861344290998e-01,1.1651166562561080e-01,
+ 1.1414597782783835e-01,1.1179156816383801e-01,1.0944845714681163e-01,
+ 1.0711666777468364e-01,1.0479622562248690e-01,1.0248715894193508e-01,
+ 1.0018949876880981e-01,9.7903279038862284e-02,9.5628536713008819e-02,
+ 9.3365311912690860e-02,9.1113648066373634e-02,8.8873592068275789e-02,
+ 8.6645194450557961e-02,8.4428509570353374e-02,8.2223595813202863e-02,
+ 8.0030515814663056e-02,7.7849336702096039e-02,7.5680130358927067e-02,
+ 7.3522973713981268e-02,7.1377949058890375e-02,6.9245144397006769e-02,
+ 6.7124653827788497e-02,6.5016577971242842e-02,6.2921024437758113e-02,
+ 6.0838108349539864e-02,5.8767952920933758e-02,5.6710690106202902e-02,
+ 5.4666461324888914e-02,5.2635418276792176e-02,5.0617723860947761e-02,
+ 4.8613553215868521e-02,4.6623094901930368e-02,4.4646552251294443e-02,
+ 4.2684144916474431e-02,4.0736110655940933e-02,3.8802707404526113e-02,
+ 3.6884215688567284e-02,3.4980941461716084e-02,3.3093219458578522e-02,
+ 3.1221417191920245e-02,2.9365939758133314e-02,2.7527235669603082e-02,
+ 2.5705804008548896e-02,2.3902203305795882e-02,2.2117062707308864e-02,
+ 2.0351096230044517e-02,1.8605121275724643e-02,1.6880083152543166e-02,
+ 1.5177088307935325e-02,1.3497450601739880e-02,1.1842757857907888e-02,
+ 1.0214971439701471e-02,8.6165827693987316e-03,7.0508754713732268e-03,
+ 5.5224032992509968e-03,4.0379725933630305e-03,2.6090727461021627e-03,
+ 1.2602859304985975e-03}).
diff --git a/lib/stdlib/src/random.erl b/lib/stdlib/src/random.erl
index d7b51a151c..8b67cde56c 100644
--- a/lib/stdlib/src/random.erl
+++ b/lib/stdlib/src/random.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -57,11 +58,17 @@ seed() ->
%% seed({A1, A2, A3})
%% Seed random number generation
--spec seed({A1, A2, A3}) -> 'undefined' | ran() when
+-spec seed(SValue) -> 'undefined' | ran() when
+ SValue :: {A1, A2, A3} | integer(),
A1 :: integer(),
A2 :: integer(),
A3 :: integer().
+seed(Int) when is_integer(Int) ->
+ A1 = (Int bsr 16) band 16#fffffff,
+ A2 = Int band 16#ffffff,
+ A3 = (Int bsr 36) bor (A2 bsr 16),
+ seed(A1, A2, A3);
seed({A1, A2, A3}) ->
seed(A1, A2, A3).
diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl
index 7f3cd8f592..80bfe38970 100644
--- a/lib/stdlib/src/re.erl
+++ b/lib/stdlib/src/re.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -131,8 +132,9 @@ split(Subject,RE) ->
split(Subject,RE,Options) ->
try
- {NewOpt,Convert,Unicode,Limit,Strip,Group} =
- process_split_params(Options,iodata,false,-1,false,false),
+ {NewOpt,Convert,Limit,Strip,Group} =
+ process_split_params(Options,iodata,-1,false,false),
+ Unicode = check_for_unicode(RE, Options),
FlatSubject = to_binary(Subject, Unicode),
case compile_split(RE,NewOpt) of
{error,_Err} ->
@@ -323,8 +325,8 @@ replace(Subject,RE,Replacement) ->
replace(Subject,RE,Replacement,Options) ->
try
- {NewOpt,Convert,Unicode} =
- process_repl_params(Options,iodata,false),
+ {NewOpt,Convert} = process_repl_params(Options,iodata),
+ Unicode = check_for_unicode(RE, Options),
FlatSubject = to_binary(Subject, Unicode),
FlatReplacement = to_binary(Replacement, Unicode),
IoList = do_replace(FlatSubject,Subject,RE,FlatReplacement,NewOpt),
@@ -366,65 +368,59 @@ do_replace(FlatSubject,Subject,RE,Replacement,Options) ->
apply_mlist(FlatSubject,Replacement,[Slist])
end.
-process_repl_params([],Convert,Unicode) ->
- {[],Convert,Unicode};
-process_repl_params([unicode|T],C,_U) ->
- {NT,NC,NU} = process_repl_params(T,C,true),
- {[unicode|NT],NC,NU};
-process_repl_params([report_errors|_],_,_) ->
+process_repl_params([],Convert) ->
+ {[],Convert};
+process_repl_params([report_errors|_],_) ->
throw(badopt);
-process_repl_params([{capture,_,_}|_],_,_) ->
+process_repl_params([{capture,_,_}|_],_) ->
throw(badopt);
-process_repl_params([{capture,_}|_],_,_) ->
+process_repl_params([{capture,_}|_],_) ->
throw(badopt);
-process_repl_params([{return,iodata}|T],_C,U) ->
- process_repl_params(T,iodata,U);
-process_repl_params([{return,list}|T],_C,U) ->
- process_repl_params(T,list,U);
-process_repl_params([{return,binary}|T],_C,U) ->
- process_repl_params(T,binary,U);
-process_repl_params([{return,_}|_],_,_) ->
+process_repl_params([{return,iodata}|T],_C) ->
+ process_repl_params(T,iodata);
+process_repl_params([{return,list}|T],_C) ->
+ process_repl_params(T,list);
+process_repl_params([{return,binary}|T],_C) ->
+ process_repl_params(T,binary);
+process_repl_params([{return,_}|_],_) ->
throw(badopt);
-process_repl_params([H|T],C,U) ->
- {NT,NC,NU} = process_repl_params(T,C,U),
- {[H|NT],NC,NU}.
-
-process_split_params([],Convert,Unicode,Limit,Strip,Group) ->
- {[],Convert,Unicode,Limit,Strip,Group};
-process_split_params([unicode|T],C,_U,L,S,G) ->
- {NT,NC,NU,NL,NS,NG} = process_split_params(T,C,true,L,S,G),
- {[unicode|NT],NC,NU,NL,NS,NG};
-process_split_params([trim|T],C,U,_L,_S,G) ->
- process_split_params(T,C,U,-1,true,G);
-process_split_params([{parts,0}|T],C,U,_L,_S,G) ->
- process_split_params(T,C,U,-1,true,G);
-process_split_params([{parts,N}|T],C,U,_L,_S,G) when is_integer(N), N >= 1 ->
- process_split_params(T,C,U,N-1,false,G);
-process_split_params([{parts,infinity}|T],C,U,_L,_S,G) ->
- process_split_params(T,C,U,-1,false,G);
-process_split_params([{parts,_}|_],_,_,_,_,_) ->
+process_repl_params([H|T],C) ->
+ {NT,NC} = process_repl_params(T,C),
+ {[H|NT],NC}.
+
+process_split_params([],Convert,Limit,Strip,Group) ->
+ {[],Convert,Limit,Strip,Group};
+process_split_params([trim|T],C,_L,_S,G) ->
+ process_split_params(T,C,-1,true,G);
+process_split_params([{parts,0}|T],C,_L,_S,G) ->
+ process_split_params(T,C,-1,true,G);
+process_split_params([{parts,N}|T],C,_L,_S,G) when is_integer(N), N >= 1 ->
+ process_split_params(T,C,N-1,false,G);
+process_split_params([{parts,infinity}|T],C,_L,_S,G) ->
+ process_split_params(T,C,-1,false,G);
+process_split_params([{parts,_}|_],_,_,_,_) ->
throw(badopt);
-process_split_params([group|T],C,U,L,S,_G) ->
- process_split_params(T,C,U,L,S,true);
-process_split_params([global|_],_,_,_,_,_) ->
+process_split_params([group|T],C,L,S,_G) ->
+ process_split_params(T,C,L,S,true);
+process_split_params([global|_],_,_,_,_) ->
throw(badopt);
-process_split_params([report_errors|_],_,_,_,_,_) ->
+process_split_params([report_errors|_],_,_,_,_) ->
throw(badopt);
-process_split_params([{capture,_,_}|_],_,_,_,_,_) ->
+process_split_params([{capture,_,_}|_],_,_,_,_) ->
throw(badopt);
-process_split_params([{capture,_}|_],_,_,_,_,_) ->
+process_split_params([{capture,_}|_],_,_,_,_) ->
throw(badopt);
-process_split_params([{return,iodata}|T],_C,U,L,S,G) ->
- process_split_params(T,iodata,U,L,S,G);
-process_split_params([{return,list}|T],_C,U,L,S,G) ->
- process_split_params(T,list,U,L,S,G);
-process_split_params([{return,binary}|T],_C,U,L,S,G) ->
- process_split_params(T,binary,U,L,S,G);
-process_split_params([{return,_}|_],_,_,_,_,_) ->
+process_split_params([{return,iodata}|T],_C,L,S,G) ->
+ process_split_params(T,iodata,L,S,G);
+process_split_params([{return,list}|T],_C,L,S,G) ->
+ process_split_params(T,list,L,S,G);
+process_split_params([{return,binary}|T],_C,L,S,G) ->
+ process_split_params(T,binary,L,S,G);
+process_split_params([{return,_}|_],_,_,_,_) ->
throw(badopt);
-process_split_params([H|T],C,U,L,S,G) ->
- {NT,NC,NU,NL,NS,NG} = process_split_params(T,C,U,L,S,G),
- {[H|NT],NC,NU,NL,NS,NG}.
+process_split_params([H|T],C,L,S,G) ->
+ {NT,NC,NL,NS,NG} = process_split_params(T,C,L,S,G),
+ {[H|NT],NC,NL,NS,NG}.
apply_mlist(Subject,Replacement,Mlist) ->
do_mlist(Subject,Subject,0,precomp_repl(Replacement), Mlist).
diff --git a/lib/stdlib/src/sets.erl b/lib/stdlib/src/sets.erl
index 167a676281..cd435ff49c 100644
--- a/lib/stdlib/src/sets.erl
+++ b/lib/stdlib/src/sets.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -70,7 +71,7 @@
segs :: segs(_) % Segments
}).
--opaque set() :: set(_).
+-type set() :: set(_).
-opaque set(Element) :: #set{segs :: segs(Element)}.
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index 679c13f0cf..ce1d9eb0ff 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -22,7 +23,7 @@
-export([whereis_evaluator/0, whereis_evaluator/1]).
-export([start_restricted/1, stop_restricted/0]).
-export([local_allowed/3, non_local_allowed/3]).
--export([prompt_func/1, strings/1]).
+-export([catch_exception/1, prompt_func/1, strings/1]).
-define(LINEMAX, 30).
-define(CHAR_MAX, 60).
@@ -314,7 +315,8 @@ prompt(N, Eval0, Bs0, RT, Ds0) ->
case get_prompt_func() of
{M,F} ->
L = [{history,N}],
- C = {call,1,{remote,1,{atom,1,M},{atom,1,F}},[{value,1,L}]},
+ A = erl_anno:new(1),
+ C = {call,A,{remote,A,{atom,A,M},{atom,A,F}},[{value,A,L}]},
{V,Eval,Bs,Ds} = shell_cmd([C], Eval0, Bs0, RT, Ds0, pmt),
{Eval,Bs,Ds,case V of
{pmt,Val} ->
@@ -416,7 +418,7 @@ expand_expr({call,_L,{atom,_,v},[N]}, C) ->
{_,undefined,_} ->
no_command(N);
{Ces,V,CommandN} when is_list(Ces) ->
- {value,CommandN,V}
+ {value,erl_anno:new(CommandN),V}
end;
expand_expr({call,L,F,Args}, C) ->
{call,L,expand_expr(F, C),expand_exprs(Args, C)};
@@ -901,7 +903,7 @@ prep_check({call,Line,{atom,_,f},[{var,_,_Name}]}) ->
{atom,Line,ok};
prep_check({value,_CommandN,_Val}) ->
%% erl_lint cannot handle the history expansion {value,_,_}.
- {atom,0,ok};
+ {atom,a0(),ok};
prep_check(T) when is_tuple(T) ->
list_to_tuple(prep_check(tuple_to_list(T)));
prep_check([E | Es]) ->
@@ -913,7 +915,7 @@ expand_records([], E0) ->
E0;
expand_records(UsedRecords, E0) ->
RecordDefs = [Def || {_Name,Def} <- UsedRecords],
- L = 1,
+ L = erl_anno:new(1),
E = prep_rec(E0),
Forms = RecordDefs ++ [{function,L,foo,0,[{clause,L,[],[],[E]}]}],
[{function,L,foo,0,[{clause,L,[],[],[NE]}]}] =
@@ -997,12 +999,7 @@ local_func(rl, [A], Bs0, _Shell, RT, Lf, Ef) ->
{value,list_records(record_defs(RT, listify(Recs))),Bs};
local_func(rp, [A], Bs0, _Shell, RT, Lf, Ef) ->
{[V],Bs} = expr_list([A], Bs0, Lf, Ef),
- Cs = io_lib_pretty:print(V, ([{column, 1},
- {line_length, columns()},
- {depth, -1},
- {max_chars, ?CHAR_MAX},
- {record_print_fun, record_print_fun(RT)}]
- ++ enc())),
+ Cs = pp(V, _Column=1, _Depth=-1, RT),
io:requests([{put_chars, unicode, Cs}, nl]),
{value,ok,Bs};
local_func(rr, [A], Bs0, _Shell, RT, Lf, Ef) ->
@@ -1320,13 +1317,15 @@ list_bindings([{Name,Val}|Bs], RT) ->
case erl_eval:fun_data(Val) of
{fun_data,_FBs,FCs0} ->
FCs = expand_value(FCs0), % looks nicer
- F = {'fun',0,{clauses,FCs}},
- M = {match,0,{var,0,Name},F},
+ A = a0(),
+ F = {'fun',A,{clauses,FCs}},
+ M = {match,A,{var,A,Name},F},
io:fwrite(<<"~ts\n">>, [erl_pp:expr(M, enc())]);
{named_fun_data,_FBs,FName,FCs0} ->
FCs = expand_value(FCs0), % looks nicer
- F = {named_fun,0,FName,FCs},
- M = {match,0,{var,0,Name},F},
+ A = a0(),
+ F = {named_fun,A,FName,FCs},
+ M = {match,A,{var,A,Name},F},
io:fwrite(<<"~ts\n">>, [erl_pp:expr(M, enc())]);
false ->
Namel = io_lib:fwrite(<<"~s = ">>, [Name]),
@@ -1356,13 +1355,18 @@ expand_value(E) ->
%% There is no abstract representation of funs.
try_abstract(V, CommandN) ->
try erl_parse:abstract(V)
- catch _:_ -> {call,0,{atom,0,v},[{integer,0,CommandN}]}
+ catch
+ _:_ ->
+ A = a0(),
+ {call,A,{atom,A,v},[{integer,A,CommandN}]}
end.
%% Rather than listing possibly huge results the calls to v/1 are shown.
prep_list_commands(E) ->
- substitute_v1(fun({value,CommandN,_V}) ->
- {call,0,{atom,0,v},[{integer,0,CommandN}]}
+ A = a0(),
+ substitute_v1(fun({value,Anno,_V}) ->
+ CommandN = erl_anno:line(Anno),
+ {call,A,{atom,A,v},[{integer,A,CommandN}]}
end, E).
substitute_v1(F, {value,_,_}=Value) ->
@@ -1374,6 +1378,9 @@ substitute_v1(F, [E | Es]) ->
substitute_v1(_F, E) ->
E.
+a0() ->
+ erl_anno:new(0).
+
check_and_get_history_and_results() ->
check_env(shell_history_length),
check_env(shell_saved_results),
@@ -1385,9 +1392,9 @@ get_history_and_results() ->
{History, erlang:min(Results, History)}.
pp(V, I, RT) ->
- pp(V, I, RT, enc()).
+ pp(V, I, _Depth=?LINEMAX, RT).
-pp(V, I, RT, Enc) ->
+pp(V, I, D, RT) ->
Strings =
case application:get_env(stdlib, shell_strings) of
{ok, false} ->
@@ -1396,10 +1403,10 @@ pp(V, I, RT, Enc) ->
true
end,
io_lib_pretty:print(V, ([{column, I}, {line_length, columns()},
- {depth, ?LINEMAX}, {max_chars, ?CHAR_MAX},
+ {depth, D}, {max_chars, ?CHAR_MAX},
{strings, Strings},
{record_print_fun, record_print_fun(RT)}]
- ++ Enc)).
+ ++ enc())).
columns() ->
case io:columns() of
diff --git a/lib/stdlib/src/shell_default.erl b/lib/stdlib/src/shell_default.erl
index 3fe359af0e..4ef5e14db1 100644
--- a/lib/stdlib/src/shell_default.erl
+++ b/lib/stdlib/src/shell_default.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,7 +24,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,
- memory/0,memory/1,
+ 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,
xm/1, bt/1, q/0,
@@ -92,6 +93,7 @@ pid(X,Y,Z) -> c:pid(X,Y,Z).
pwd() -> c:pwd().
q() -> c:q().
regs() -> c:regs().
+uptime() -> c:uptime().
xm(Mod) -> c:xm(Mod).
y(File) -> c:y(File).
y(File, Opts) -> c:y(File, Opts).
diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl
index 1898dc8aba..24fc8ce204 100644
--- a/lib/stdlib/src/slave.erl
+++ b/lib/stdlib/src/slave.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -128,7 +129,7 @@ relay1(Pid) ->
%% {error, {already_running, Name@Host}}
-spec start(Host) -> {ok, Node} | {error, Reason} when
- Host :: atom(),
+ Host :: inet:hostname(),
Node :: node(),
Reason :: timeout | no_rsh | {already_running, Node}.
@@ -138,8 +139,8 @@ start(Host) ->
start(Host, Name, [], no_link).
-spec start(Host, Name) -> {ok, Node} | {error, Reason} when
- Host :: atom(),
- Name :: atom(),
+ Host :: inet:hostname(),
+ Name :: atom() | string(),
Node :: node(),
Reason :: timeout | no_rsh | {already_running, Node}.
@@ -147,8 +148,8 @@ start(Host, Name) ->
start(Host, Name, []).
-spec start(Host, Name, Args) -> {ok, Node} | {error, Reason} when
- Host :: atom(),
- Name :: atom(),
+ Host :: inet:hostname(),
+ Name :: atom() | string(),
Args :: string(),
Node :: node(),
Reason :: timeout | no_rsh | {already_running, Node}.
@@ -157,7 +158,7 @@ start(Host, Name, Args) ->
start(Host, Name, Args, no_link).
-spec start_link(Host) -> {ok, Node} | {error, Reason} when
- Host :: atom(),
+ Host :: inet:hostname(),
Node :: node(),
Reason :: timeout | no_rsh | {already_running, Node}.
@@ -167,8 +168,8 @@ start_link(Host) ->
start(Host, Name, [], self()).
-spec start_link(Host, Name) -> {ok, Node} | {error, Reason} when
- Host :: atom(),
- Name :: atom(),
+ Host :: inet:hostname(),
+ Name :: atom() | string(),
Node :: node(),
Reason :: timeout | no_rsh | {already_running, Node}.
@@ -176,8 +177,8 @@ start_link(Host, Name) ->
start_link(Host, Name, []).
-spec start_link(Host, Name, Args) -> {ok, Node} | {error, Reason} when
- Host :: atom(),
- Name :: atom(),
+ Host :: inet:hostname(),
+ Name :: atom() | string(),
Args :: string(),
Node :: node(),
Reason :: timeout | no_rsh | {already_running, Node}.
@@ -210,7 +211,6 @@ start(Host0, Name, Args, LinkTo, Prog) ->
Node :: node().
stop(Node) ->
-% io:format("stop(~p)~n", [Node]),
rpc:call(Node, erlang, halt, []),
ok.
@@ -229,7 +229,6 @@ wait_for_slave(Parent, Host, Name, Node, Args, LinkTo, Prog) ->
Waiter = register_unique_name(0),
case mk_cmd(Host, Name, Args, Waiter, Prog) of
{ok, Cmd} ->
-%% io:format("Command: ~ts~n", [Cmd]),
open_port({spawn, Cmd}, [stream]),
receive
{SlavePid, slave_started} ->
diff --git a/lib/stdlib/src/sofs.erl b/lib/stdlib/src/sofs.erl
index 0bd67db100..bcd1fc11e2 100644
--- a/lib/stdlib/src/sofs.erl
+++ b/lib/stdlib/src/sofs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index aa9899da3b..b8a7973cf2 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -2,18 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -39,6 +40,7 @@
edlin_expand,
epp,
eval_bits,
+ erl_anno,
erl_bits,
erl_compile,
erl_eval,
@@ -77,13 +79,13 @@
orddict,
ordsets,
otp_internal,
- pg,
pool,
proc_lib,
proplists,
qlc,
qlc_pt,
queue,
+ rand,
random,
re,
sets,
@@ -103,7 +105,7 @@
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-2.4","kernel-3.0.2","erts-6.2","crypto-3.3",
+ {runtime_dependencies, ["sasl-2.6","kernel-4.1","erts-7.3","crypto-3.3",
"compiler-5.0"]}
]}.
diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src
index 951dbca68e..8a313591a7 100644
--- a/lib/stdlib/src/stdlib.appup.src
+++ b/lib/stdlib/src/stdlib.appup.src
@@ -1,27 +1,26 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"2\\.[1-3](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3
- {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0
- {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
+ [{<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}], % 17.0-17.5
%% Down to - max one major revision back
- [{<<"2\\.[1-3](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3
- {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0
- {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
+ [{<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}] % 17.0-17.5
}.
diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl
index f9b083a56d..07659ed812 100644
--- a/lib/stdlib/src/string.erl
+++ b/lib/stdlib/src/string.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -221,23 +222,47 @@ substr2([_|String], S) -> substr2(String, S-1).
Tokens :: [Token :: nonempty_string()].
tokens(S, Seps) ->
- tokens1(S, Seps, []).
+ case Seps of
+ [] ->
+ case S of
+ [] -> [];
+ [_|_] -> [S]
+ end;
+ [C] ->
+ tokens_single_1(reverse(S), C, []);
+ [_|_] ->
+ tokens_multiple_1(reverse(S), Seps, [])
+ end.
-tokens1([C|S], Seps, Toks) ->
+tokens_single_1([Sep|S], Sep, Toks) ->
+ tokens_single_1(S, Sep, Toks);
+tokens_single_1([C|S], Sep, Toks) ->
+ tokens_single_2(S, Sep, Toks, [C]);
+tokens_single_1([], _, Toks) ->
+ Toks.
+
+tokens_single_2([Sep|S], Sep, Toks, Tok) ->
+ tokens_single_1(S, Sep, [Tok|Toks]);
+tokens_single_2([C|S], Sep, Toks, Tok) ->
+ tokens_single_2(S, Sep, Toks, [C|Tok]);
+tokens_single_2([], _Sep, Toks, Tok) ->
+ [Tok|Toks].
+
+tokens_multiple_1([C|S], Seps, Toks) ->
case member(C, Seps) of
- true -> tokens1(S, Seps, Toks);
- false -> tokens2(S, Seps, Toks, [C])
+ true -> tokens_multiple_1(S, Seps, Toks);
+ false -> tokens_multiple_2(S, Seps, Toks, [C])
end;
-tokens1([], _Seps, Toks) ->
- reverse(Toks).
+tokens_multiple_1([], _Seps, Toks) ->
+ Toks.
-tokens2([C|S], Seps, Toks, Cs) ->
+tokens_multiple_2([C|S], Seps, Toks, Tok) ->
case member(C, Seps) of
- true -> tokens1(S, Seps, [reverse(Cs)|Toks]);
- false -> tokens2(S, Seps, Toks, [C|Cs])
+ true -> tokens_multiple_1(S, Seps, [Tok|Toks]);
+ false -> tokens_multiple_2(S, Seps, Toks, [C|Tok])
end;
-tokens2([], _Seps, Toks, Cs) ->
- reverse([reverse(Cs)|Toks]).
+tokens_multiple_2([], _Seps, Toks, Tok) ->
+ [Tok|Toks].
-spec chars(Character, Number) -> String when
Character :: char(),
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index ede2742875..cecdebd0c8 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -25,16 +26,19 @@
start_child/2, restart_child/2,
delete_child/2, terminate_child/2,
which_children/1, count_children/1,
- check_childspecs/1]).
+ check_childspecs/1, get_childspec/2]).
%% Internal exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([try_again_restart/2]).
+%% For release_handler only
+-export([get_callback_module/1]).
+
%%--------------------------------------------------------------------------
--export_type([child_spec/0, startchild_ret/0, strategy/0]).
+-export_type([sup_flags/0, child_spec/0, startchild_ret/0, strategy/0]).
%%--------------------------------------------------------------------------
@@ -53,7 +57,13 @@
| {'global', Name :: atom()}
| {'via', Module :: module(), Name :: any()}
| pid().
--type child_spec() :: {Id :: child_id(),
+-type child_spec() :: #{id => child_id(), % mandatory
+ start => mfargs(), % mandatory
+ restart => restart(), % optional
+ shutdown => shutdown(), % optional
+ type => worker(), % optional
+ modules => modules()} % optional
+ | {Id :: child_id(),
StartFunc :: mfargs(),
Restart :: restart(),
Shutdown :: shutdown(),
@@ -63,6 +73,23 @@
-type strategy() :: 'one_for_all' | 'one_for_one'
| 'rest_for_one' | 'simple_one_for_one'.
+-type sup_flags() :: #{strategy => strategy(), % optional
+ intensity => non_neg_integer(), % optional
+ period => pos_integer()} % optional
+ | {RestartStrategy :: strategy(),
+ Intensity :: non_neg_integer(),
+ Period :: pos_integer()}.
+
+%%--------------------------------------------------------------------------
+%% Defaults
+-define(default_flags, #{strategy => one_for_one,
+ intensity => 1,
+ period => 5}).
+-define(default_child_spec, #{restart => permanent,
+ type => worker}).
+%% Default 'shutdown' is 5000 for workers and infinity for supervisors.
+%% Default 'modules' is [M], where M comes from the child's start {M,F,A}.
+
%%--------------------------------------------------------------------------
-record(child, {% pid is undefined when child is not running
@@ -89,6 +116,7 @@
intensity :: non_neg_integer(),
period :: pos_integer(),
restarts = [],
+ dynamic_restarts = 0 :: non_neg_integer(),
module,
args}).
-type state() :: #state{}.
@@ -96,10 +124,7 @@
-define(is_simple(State), State#state.strategy =:= simple_one_for_one).
-callback init(Args :: term()) ->
- {ok, {{RestartStrategy :: strategy(),
- MaxR :: non_neg_integer(),
- MaxT :: non_neg_integer()},
- [ChildSpec :: child_spec()]}}
+ {ok, {SupFlags :: sup_flags(), [ChildSpec :: child_spec()]}}
| ignore.
-define(restarting(_Pid_), {restarting,_Pid_}).
@@ -178,6 +203,14 @@ delete_child(Supervisor, Name) ->
terminate_child(Supervisor, Name) ->
call(Supervisor, {terminate_child, Name}).
+-spec get_childspec(SupRef, Id) -> Result when
+ SupRef :: sup_ref(),
+ Id :: pid() | child_id(),
+ Result :: {'ok', child_spec()} | {'error', Error},
+ Error :: 'not_found'.
+get_childspec(Supervisor, Name) ->
+ call(Supervisor, {get_childspec, Name}).
+
-spec which_children(SupRef) -> [{Id,Child,Type,Modules}] when
SupRef :: sup_ref(),
Id :: child_id() | undefined,
@@ -221,6 +254,17 @@ try_again_restart(Supervisor, Child) ->
cast(Supervisor, Req) ->
gen_server:cast(Supervisor, Req).
+%%%-----------------------------------------------------------------
+%%% Called by release_handler during upgrade
+-spec get_callback_module(Pid) -> Module when
+ Pid :: pid(),
+ Module :: atom().
+get_callback_module(Pid) ->
+ {status, _Pid, {module, _Mod},
+ [_PDict, _SysState, _Parent, _Dbg, Misc]} = sys:get_status(Pid),
+ [_Header, _Data, {data, [{"State", State}]}] = Misc,
+ State#state.module.
+
%%% ---------------------------------------------------
%%%
%%% Initialize the supervisor.
@@ -353,7 +397,7 @@ handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
#child{mfargs = {M, F, A}} = Child,
Args = A ++ EArgs,
case do_start_child_i(M, F, Args) of
- {ok, undefined} when Child#child.restart_type =:= temporary ->
+ {ok, undefined} ->
{reply, {ok, undefined}, State};
{ok, Pid} ->
NState = save_dynamic_child(Child#child.restart_type, Pid, Args, State),
@@ -365,6 +409,15 @@ handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
{reply, What, State}
end;
+handle_call({start_child, ChildSpec}, _From, State) ->
+ case check_childspec(ChildSpec) of
+ {ok, Child} ->
+ {Resp, NState} = handle_start_child(Child, State),
+ {reply, Resp, NState};
+ What ->
+ {reply, {error, What}, State}
+ end;
+
%% terminate_child for simple_one_for_one can only be done with pid
handle_call({terminate_child, Name}, _From, State) when not is_pid(Name),
?is_simple(State) ->
@@ -383,20 +436,10 @@ handle_call({terminate_child, Name}, _From, State) ->
{reply, {error, not_found}, State}
end;
-%%% The requests delete_child and restart_child are invalid for
-%%% simple_one_for_one supervisors.
-handle_call({_Req, _Data}, _From, State) when ?is_simple(State) ->
+%% restart_child request is invalid for simple_one_for_one supervisors
+handle_call({restart_child, _Name}, _From, State) when ?is_simple(State) ->
{reply, {error, simple_one_for_one}, State};
-handle_call({start_child, ChildSpec}, _From, State) ->
- case check_childspec(ChildSpec) of
- {ok, Child} ->
- {Resp, NState} = handle_start_child(Child, State),
- {reply, Resp, NState};
- What ->
- {reply, {error, What}, State}
- end;
-
handle_call({restart_child, Name}, _From, State) ->
case get_child(Name, State) of
{value, Child} when Child#child.pid =:= undefined ->
@@ -418,6 +461,10 @@ handle_call({restart_child, Name}, _From, State) ->
{reply, {error, not_found}, State}
end;
+%% delete_child request is invalid for simple_one_for_one supervisors
+handle_call({delete_child, _Name}, _From, State) when ?is_simple(State) ->
+ {reply, {error, simple_one_for_one}, State};
+
handle_call({delete_child, Name}, _From, State) ->
case get_child(Name, State) of
{value, Child} when Child#child.pid =:= undefined ->
@@ -431,6 +478,14 @@ handle_call({delete_child, Name}, _From, State) ->
{reply, {error, not_found}, State}
end;
+handle_call({get_childspec, Name}, _From, State) ->
+ case get_child(Name, State, ?is_simple(State)) of
+ {value, Child} ->
+ {reply, {ok, child_to_spec(Child)}, State};
+ false ->
+ {reply, {error, not_found}, State}
+ end;
+
handle_call(which_children, _From, #state{children = [#child{restart_type = temporary,
child_type = CT,
modules = Mods}]} =
@@ -464,39 +519,26 @@ handle_call(which_children, _From, State) ->
handle_call(count_children, _From, #state{children = [#child{restart_type = temporary,
child_type = CT}]} = State)
when ?is_simple(State) ->
- {Active, Count} =
- ?SETS:fold(fun(Pid, {Alive, Tot}) ->
- case is_pid(Pid) andalso is_process_alive(Pid) of
- true ->{Alive+1, Tot +1};
- false ->
- {Alive, Tot + 1}
- end
- end, {0, 0}, dynamics_db(temporary, State#state.dynamics)),
+ Sz = ?SETS:size(dynamics_db(temporary, State#state.dynamics)),
Reply = case CT of
- supervisor -> [{specs, 1}, {active, Active},
- {supervisors, Count}, {workers, 0}];
- worker -> [{specs, 1}, {active, Active},
- {supervisors, 0}, {workers, Count}]
+ supervisor -> [{specs, 1}, {active, Sz},
+ {supervisors, Sz}, {workers, 0}];
+ worker -> [{specs, 1}, {active, Sz},
+ {supervisors, 0}, {workers, Sz}]
end,
{reply, Reply, State};
-handle_call(count_children, _From, #state{children = [#child{restart_type = RType,
+handle_call(count_children, _From, #state{dynamic_restarts = Restarts,
+ children = [#child{restart_type = RType,
child_type = CT}]} = State)
when ?is_simple(State) ->
- {Active, Count} =
- ?DICTS:fold(fun(Pid, _Val, {Alive, Tot}) ->
- case is_pid(Pid) andalso is_process_alive(Pid) of
- true ->
- {Alive+1, Tot +1};
- false ->
- {Alive, Tot + 1}
- end
- end, {0, 0}, dynamics_db(RType, State#state.dynamics)),
+ Sz = ?DICTS:size(dynamics_db(RType, State#state.dynamics)),
+ Active = Sz - Restarts,
Reply = case CT of
supervisor -> [{specs, 1}, {active, Active},
- {supervisors, Count}, {workers, 0}];
+ {supervisors, Sz}, {workers, 0}];
worker -> [{specs, 1}, {active, Active},
- {supervisors, 0}, {workers, Count}]
+ {supervisors, 0}, {workers, Sz}]
end,
{reply, Reply, State};
@@ -610,13 +652,11 @@ terminate(_Reason, State) ->
code_change(_, State, _) ->
case (State#state.module):init(State#state.args) of
{ok, {SupFlags, StartSpec}} ->
- case catch check_flags(SupFlags) of
- ok ->
- {Strategy, MaxIntensity, Period} = SupFlags,
- update_childspec(State#state{strategy = Strategy,
- intensity = MaxIntensity,
- period = Period},
- StartSpec);
+ case set_flags(SupFlags, State) of
+ {ok, State1} ->
+ update_childspec(State1, StartSpec);
+ {invalid_type, SupFlags} ->
+ {error, {bad_flags, SupFlags}}; % backwards compatibility
Error ->
{error, Error}
end;
@@ -626,14 +666,6 @@ code_change(_, State, _) ->
Error
end.
-check_flags({Strategy, MaxIntensity, Period}) ->
- validStrategy(Strategy),
- validIntensity(MaxIntensity),
- validPeriod(Period),
- ok;
-check_flags(What) ->
- {bad_flags, What}.
-
update_childspec(State, StartSpec) when ?is_simple(State) ->
case check_startspec(StartSpec) of
{ok, [Child]} ->
@@ -776,8 +808,15 @@ restart(Child, State) ->
{shutdown, remove_child(Child, NState)}
end.
-restart(simple_one_for_one, Child, State) ->
+restart(simple_one_for_one, Child, State0) ->
#child{pid = OldPid, mfargs = {M, F, A}} = Child,
+ State = case OldPid of
+ ?restarting(_) ->
+ NRes = State0#state.dynamic_restarts - 1,
+ State0#state{dynamic_restarts = NRes};
+ _ ->
+ State0
+ end,
Dynamics = ?DICTS:erase(OldPid, dynamics_db(Child#child.restart_type,
State#state.dynamics)),
case do_start_child_i(M, F, A) of
@@ -788,7 +827,9 @@ restart(simple_one_for_one, Child, State) ->
NState = State#state{dynamics = ?DICTS:store(Pid, A, Dynamics)},
{ok, NState};
{error, Error} ->
- NState = State#state{dynamics = ?DICTS:store(restarting(OldPid), A,
+ NRestarts = State#state.dynamic_restarts + 1,
+ NState = State#state{dynamic_restarts = NRestarts,
+ dynamics = ?DICTS:store(restarting(OldPid), A,
Dynamics)},
report_error(start_error, Error, Child, State#state.name),
{try_again, NState}
@@ -1053,7 +1094,7 @@ wait_dynamic_children(#child{restart_type=RType} = Child, Pids, Sz,
{timeout, TRef, kill} ->
?SETS:fold(fun(P, _) -> exit(P, kill) end, ok, Pids),
- wait_dynamic_children(Child, Pids, Sz-1, undefined, EStack)
+ wait_dynamic_children(Child, Pids, Sz, undefined, EStack)
end.
%%-----------------------------------------------------------------
@@ -1188,25 +1229,36 @@ remove_child(Child, State) ->
%% Returns: {ok, state()} | Error
%%-----------------------------------------------------------------
init_state(SupName, Type, Mod, Args) ->
- case catch init_state1(SupName, Type, Mod, Args) of
- {ok, State} ->
- {ok, State};
- Error ->
- Error
+ set_flags(Type, #state{name = supname(SupName,Mod),
+ module = Mod,
+ args = Args}).
+
+set_flags(Flags, State) ->
+ try check_flags(Flags) of
+ #{strategy := Strategy, intensity := MaxIntensity, period := Period} ->
+ {ok, State#state{strategy = Strategy,
+ intensity = MaxIntensity,
+ period = Period}}
+ catch
+ Thrown -> Thrown
end.
-init_state1(SupName, {Strategy, MaxIntensity, Period}, Mod, Args) ->
+check_flags(SupFlags) when is_map(SupFlags) ->
+ do_check_flags(maps:merge(?default_flags,SupFlags));
+check_flags({Strategy, MaxIntensity, Period}) ->
+ check_flags(#{strategy => Strategy,
+ intensity => MaxIntensity,
+ period => Period});
+check_flags(What) ->
+ throw({invalid_type, What}).
+
+do_check_flags(#{strategy := Strategy,
+ intensity := MaxIntensity,
+ period := Period} = Flags) ->
validStrategy(Strategy),
validIntensity(MaxIntensity),
validPeriod(Period),
- {ok, #state{name = supname(SupName,Mod),
- strategy = Strategy,
- intensity = MaxIntensity,
- period = Period,
- module = Mod,
- args = Args}};
-init_state1(_SupName, Type, _, _) ->
- {invalid_type, Type}.
+ Flags.
validStrategy(simple_one_for_one) -> true;
validStrategy(one_for_one) -> true;
@@ -1227,14 +1279,7 @@ supname(N, _) -> N.
%%% ------------------------------------------------------
%%% Check that the children start specification is valid.
-%%% Shall be a six (6) tuple
-%%% {Name, Func, RestartType, Shutdown, ChildType, Modules}
-%%% where Name is an atom
-%%% Func is {Mod, Fun, Args} == {atom(), atom(), list()}
-%%% RestartType is permanent | temporary | transient
-%%% Shutdown = integer() > 0 | infinity | brutal_kill
-%%% ChildType = supervisor | worker
-%%% Modules = [atom()] | dynamic
+%%% Input: [child_spec()]
%%% Returns: {ok, [child_rec()]} | Error
%%% ------------------------------------------------------
@@ -1244,6 +1289,9 @@ check_startspec([ChildSpec|T], Res) ->
case check_childspec(ChildSpec) of
{ok, Child} ->
case lists:keymember(Child#child.name, #child.name, Res) of
+ %% The error message duplicate_child_name is kept for
+ %% backwards compatibility, although
+ %% duplicate_child_id would be more correct.
true -> {duplicate_child_name, Child#child.name};
false -> check_startspec(T, [Child | Res])
end;
@@ -1252,16 +1300,41 @@ check_startspec([ChildSpec|T], Res) ->
check_startspec([], Res) ->
{ok, lists:reverse(Res)}.
+check_childspec(ChildSpec) when is_map(ChildSpec) ->
+ catch do_check_childspec(maps:merge(?default_child_spec,ChildSpec));
check_childspec({Name, Func, RestartType, Shutdown, ChildType, Mods}) ->
- catch check_childspec(Name, Func, RestartType, Shutdown, ChildType, Mods);
+ check_childspec(#{id => Name,
+ start => Func,
+ restart => RestartType,
+ shutdown => Shutdown,
+ type => ChildType,
+ modules => Mods});
check_childspec(X) -> {invalid_child_spec, X}.
-check_childspec(Name, Func, RestartType, Shutdown, ChildType, Mods) ->
+do_check_childspec(#{restart := RestartType,
+ type := ChildType} = ChildSpec)->
+ Name = case ChildSpec of
+ #{id := N} -> N;
+ _ -> throw(missing_id)
+ end,
+ Func = case ChildSpec of
+ #{start := F} -> F;
+ _ -> throw(missing_start)
+ end,
validName(Name),
validFunc(Func),
validRestartType(RestartType),
validChildType(ChildType),
- validShutdown(Shutdown, ChildType),
+ Shutdown = case ChildSpec of
+ #{shutdown := S} -> S;
+ #{type := worker} -> 5000;
+ #{type := supervisor} -> infinity
+ end,
+ validShutdown(Shutdown),
+ Mods = case ChildSpec of
+ #{modules := Ms} -> Ms;
+ _ -> {M,_,_} = Func, [M]
+ end,
validMods(Mods),
{ok, #child{name = Name, mfargs = Func, restart_type = RestartType,
shutdown = Shutdown, child_type = ChildType, modules = Mods}}.
@@ -1282,11 +1355,11 @@ validRestartType(temporary) -> true;
validRestartType(transient) -> true;
validRestartType(RestartType) -> throw({invalid_restart_type, RestartType}).
-validShutdown(Shutdown, _)
+validShutdown(Shutdown)
when is_integer(Shutdown), Shutdown > 0 -> true;
-validShutdown(infinity, _) -> true;
-validShutdown(brutal_kill, _) -> true;
-validShutdown(Shutdown, _) -> throw({invalid_shutdown, Shutdown}).
+validShutdown(infinity) -> true;
+validShutdown(brutal_kill) -> true;
+validShutdown(Shutdown) -> throw({invalid_shutdown, Shutdown}).
validMods(dynamic) -> true;
validMods(Mods) when is_list(Mods) ->
@@ -1299,6 +1372,19 @@ validMods(Mods) when is_list(Mods) ->
Mods);
validMods(Mods) -> throw({invalid_modules, Mods}).
+child_to_spec(#child{name = Name,
+ mfargs = Func,
+ restart_type = RestartType,
+ shutdown = Shutdown,
+ child_type = ChildType,
+ modules = Mods}) ->
+ #{id => Name,
+ start => Func,
+ restart => RestartType,
+ shutdown => Shutdown,
+ type => ChildType,
+ modules => Mods}.
+
%%% ------------------------------------------------------
%%% Add a new restart and calculate if the max restart
%%% intensity has been reached (in that case the supervisor
@@ -1312,7 +1398,7 @@ add_restart(State) ->
I = State#state.intensity,
P = State#state.period,
R = State#state.restarts,
- Now = erlang:now(),
+ Now = erlang:monotonic_time(1),
R1 = add_restart([Now|R], Now, P),
State1 = State#state{restarts = R1},
case length(R1) of
@@ -1332,26 +1418,8 @@ add_restart([R|Restarts], Now, Period) ->
add_restart([], _, _) ->
[].
-inPeriod(Time, Now, Period) ->
- case difference(Time, Now) of
- T when T > Period ->
- false;
- _ ->
- true
- end.
-
-%%
-%% Time = {MegaSecs, Secs, MicroSecs} (NOTE: MicroSecs is ignored)
-%% Calculate the time elapsed in seconds between two timestamps.
-%% If MegaSecs is equal just subtract Secs.
-%% Else calculate the Mega difference and add the Secs difference,
-%% note that Secs difference can be negative, e.g.
-%% {827, 999999, 676} diff {828, 1, 653753} == > 2 secs.
-%%
-difference({TimeM, TimeS, _}, {CurM, CurS, _}) when CurM > TimeM ->
- ((CurM - TimeM) * 1000000) + (CurS - TimeS);
-difference({_, TimeS, _}, {_, CurS, _}) ->
- CurS - TimeS.
+inPeriod(Then, Now, Period) ->
+ Now =< Then + Period.
%%% ------------------------------------------------------
%%% Error and progress reporting.
@@ -1367,14 +1435,14 @@ report_error(Error, Reason, Child, SupName) ->
extract_child(Child) when is_list(Child#child.pid) ->
[{nb_children, length(Child#child.pid)},
- {name, Child#child.name},
+ {id, Child#child.name},
{mfargs, Child#child.mfargs},
{restart_type, Child#child.restart_type},
{shutdown, Child#child.shutdown},
{child_type, Child#child.child_type}];
extract_child(Child) ->
[{pid, Child#child.pid},
- {name, Child#child.name},
+ {id, Child#child.name},
{mfargs, Child#child.mfargs},
{restart_type, Child#child.restart_type},
{shutdown, Child#child.shutdown},
diff --git a/lib/stdlib/src/supervisor_bridge.erl b/lib/stdlib/src/supervisor_bridge.erl
index ff4502f0b9..18218b71ad 100644
--- a/lib/stdlib/src/supervisor_bridge.erl
+++ b/lib/stdlib/src/supervisor_bridge.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl
index d3ba09ce82..a7debb00f5 100644
--- a/lib/stdlib/src/sys.erl
+++ b/lib/stdlib/src/sys.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,6 +25,7 @@
get_state/1, get_state/2,
replace_state/2, replace_state/3,
change_code/4, change_code/5,
+ terminate/2, terminate/3,
log/2, log/3, trace/2, trace/3, statistics/2, statistics/3,
log_to_file/2, log_to_file/3, no_debug/1, no_debug/2,
install/2, install/3, remove/2, remove/3]).
@@ -163,6 +165,19 @@ change_code(Name, Mod, Vsn, Extra) ->
change_code(Name, Mod, Vsn, Extra, Timeout) ->
send_system_msg(Name, {change_code, Mod, Vsn, Extra}, Timeout).
+-spec terminate(Name, Reason) -> 'ok' when
+ Name :: name(),
+ Reason :: term().
+terminate(Name, Reason) ->
+ send_system_msg(Name, {terminate, Reason}).
+
+-spec terminate(Name, Reason, Timeout) -> 'ok' when
+ Name :: name(),
+ Reason :: term(),
+ Timeout :: timeout().
+terminate(Name, Reason, Timeout) ->
+ send_system_msg(Name, {terminate, Reason}, Timeout).
+
%%-----------------------------------------------------------------
%% Debug commands
%%-----------------------------------------------------------------
@@ -298,6 +313,8 @@ mfa(Name, {debug, {Func, Arg2}}) ->
{sys, Func, [Name, Arg2]};
mfa(Name, {change_code, Mod, Vsn, Extra}) ->
{sys, change_code, [Name, Mod, Vsn, Extra]};
+mfa(Name, {terminate, Reason}) ->
+ {sys, terminate, [Name, Reason]};
mfa(Name, Atom) ->
{sys, Atom, [Name]}.
@@ -313,7 +330,7 @@ mfa(Name, Req, Timeout) ->
%% Returns: This function *never* returns! It calls the function
%% Module:system_continue(Parent, NDebug, Misc)
%% there the process continues the execution or
-%% Module:system_terminate(Raeson, Parent, Debug, Misc) if
+%% Module:system_terminate(Reason, Parent, Debug, Misc) if
%% the process should terminate.
%% The Module must export system_continue/3, system_terminate/4
%% and format_status/2 for status information.
@@ -339,7 +356,10 @@ handle_system_msg(SysState, Msg, From, Parent, Mod, Debug, Misc, Hib) ->
suspend_loop(suspended, Parent, Mod, NDebug, NMisc, Hib);
{running, Reply, NDebug, NMisc} ->
_ = gen:reply(From, Reply),
- Mod:system_continue(Parent, NDebug, NMisc)
+ Mod:system_continue(Parent, NDebug, NMisc);
+ {{terminating, Reason}, Reply, NDebug, NMisc} ->
+ _ = gen:reply(From, Reply),
+ Mod:system_terminate(Reason, Parent, NDebug, NMisc)
end.
%%-----------------------------------------------------------------
@@ -419,6 +439,8 @@ do_cmd(SysState, get_status, Parent, Mod, Debug, Misc) ->
do_cmd(SysState, {debug, What}, _Parent, _Mod, Debug, Misc) ->
{Res, NDebug} = debug_cmd(What, Debug),
{SysState, Res, NDebug, Misc};
+do_cmd(_, {terminate, Reason}, _Parent, _Mod, Debug, Misc) ->
+ {{terminating, Reason}, ok, Debug, Misc};
do_cmd(suspended, {change_code, Module, Vsn, Extra}, _Parent,
Mod, Debug, Misc) ->
{Res, NMisc} = do_change_code(Mod, Module, Vsn, Extra, Misc),
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index 72a2dd9616..f7530447bb 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -161,10 +162,11 @@ sleep(T) ->
Time :: integer(),
Value :: term().
tc(F) ->
- Before = os:timestamp(),
+ T1 = erlang:monotonic_time(),
Val = F(),
- After = os:timestamp(),
- {now_diff(After, Before), Val}.
+ T2 = erlang:monotonic_time(),
+ Time = erlang:convert_time_unit(T2 - T1, native, micro_seconds),
+ {Time, Val}.
%%
%% Measure the execution time (in microseconds) for Fun(Args).
@@ -175,10 +177,11 @@ tc(F) ->
Time :: integer(),
Value :: term().
tc(F, A) ->
- Before = os:timestamp(),
+ T1 = erlang:monotonic_time(),
Val = apply(F, A),
- After = os:timestamp(),
- {now_diff(After, Before), Val}.
+ T2 = erlang:monotonic_time(),
+ Time = erlang:convert_time_unit(T2 - T1, native, micro_seconds),
+ {Time, Val}.
%%
%% Measure the execution time (in microseconds) for an MFA.
@@ -190,10 +193,11 @@ tc(F, A) ->
Time :: integer(),
Value :: term().
tc(M, F, A) ->
- Before = os:timestamp(),
+ T1 = erlang:monotonic_time(),
Val = apply(M, F, A),
- After = os:timestamp(),
- {now_diff(After, Before), Val}.
+ T2 = erlang:monotonic_time(),
+ Time = erlang:convert_time_unit(T2 - T1, native, micro_seconds),
+ {Time, Val}.
%%
%% Calculate the time difference (in microseconds) of two
@@ -437,10 +441,8 @@ positive(X) ->
%%
%% system_time() -> time in microseconds
%%
-system_time() ->
- {M,S,U} = erlang:now(),
- 1000000 * (M*1000000 + S) + U.
-
+system_time() ->
+ erlang:monotonic_time(1000000).
send([Pid, Msg]) ->
Pid ! Msg.
diff --git a/lib/stdlib/src/unicode.erl b/lib/stdlib/src/unicode.erl
index 49529cffd4..617da11ba8 100644
--- a/lib/stdlib/src/unicode.erl
+++ b/lib/stdlib/src/unicode.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -560,6 +561,8 @@ do_o_binary(F,L) ->
erlang:iolist_to_binary(List)
end.
+-dialyzer({no_improper_lists, do_o_binary2/2}).
+
do_o_binary2(_F,[]) ->
<<>>;
do_o_binary2(F,[H|T]) ->
diff --git a/lib/stdlib/src/win32reg.erl b/lib/stdlib/src/win32reg.erl
index 48a7e262be..8074b2efda 100644
--- a/lib/stdlib/src/win32reg.erl
+++ b/lib/stdlib/src/win32reg.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -218,12 +219,7 @@ expand([C|Rest], [], Result) ->
expand(Rest, [], [C|Result]);
expand([$%|Rest], Env0, Result) ->
Env = lists:reverse(Env0),
- case os:getenv(Env) of
- false ->
- expand(Rest, [], Result);
- Value ->
- expand(Rest, [], lists:reverse(Value)++Result)
- end;
+ expand(Rest, [], lists:reverse(os:getenv(Env, ""))++Result);
expand([C|Rest], Env, Result) ->
expand(Rest, [C|Env], Result);
expand([], [], Result) ->
diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl
index b768c6d0b9..f8ba6f18e9 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,7 +25,7 @@
list_dir/1, list_dir/2, table/1, table/2,
t/1, tt/1]).
-%% unzipping peicemeal
+%% unzipping piecemeal
-export([openzip_open/1, openzip_open/2,
openzip_get/1, openzip_get/2,
openzip_t/1, openzip_tt/1,
@@ -214,7 +215,9 @@
-type zip_comment() :: #zip_comment{}.
-type zip_file() :: #zip_file{}.
--export_type([create_option/0, filename/0]).
+-opaque handle() :: pid().
+
+-export_type([create_option/0, filename/0, handle/0]).
%% Open a zip archive with options
%%
@@ -500,7 +503,7 @@ do_list_dir(F, Options) ->
-spec(t(Archive) -> ok when
Archive :: file:name() | binary() | ZipHandle,
- ZipHandle :: pid()).
+ ZipHandle :: handle()).
t(F) when is_pid(F) -> zip_t(F);
t(F) when is_record(F, openzip) -> openzip_t(F);
@@ -524,7 +527,7 @@ do_t(F, RawPrint) ->
-spec(tt(Archive) -> ok when
Archive :: file:name() | binary() | ZipHandle,
- ZipHandle :: pid()).
+ ZipHandle :: handle()).
tt(F) when is_pid(F) -> zip_tt(F);
tt(F) when is_record(F, openzip) -> openzip_tt(F);
@@ -1114,15 +1117,19 @@ local_file_header_from_info_method_name(#file_info{mtime = MTime},
file_name_length = length(Name),
extra_field_length = 0}.
+server_init(Parent) ->
+ %% we want to know if our parent dies
+ process_flag(trap_exit, true),
+ server_loop(Parent, not_open).
%% small, simple, stupid zip-archive server
-server_loop(OpenZip) ->
+server_loop(Parent, OpenZip) ->
receive
{From, {open, Archive, Options}} ->
case openzip_open(Archive, Options) of
{ok, NewOpenZip} ->
From ! {self(), {ok, self()}},
- server_loop(NewOpenZip);
+ server_loop(Parent, NewOpenZip);
Error ->
From ! {self(), Error}
end;
@@ -1130,43 +1137,47 @@ server_loop(OpenZip) ->
From ! {self(), openzip_close(OpenZip)};
{From, get} ->
From ! {self(), openzip_get(OpenZip)},
- server_loop(OpenZip);
+ server_loop(Parent, OpenZip);
{From, {get, FileName}} ->
From ! {self(), openzip_get(FileName, OpenZip)},
- server_loop(OpenZip);
+ server_loop(Parent, OpenZip);
{From, list_dir} ->
From ! {self(), openzip_list_dir(OpenZip)},
- server_loop(OpenZip);
+ server_loop(Parent, OpenZip);
{From, {list_dir, Opts}} ->
From ! {self(), openzip_list_dir(OpenZip, Opts)},
- server_loop(OpenZip);
+ server_loop(Parent, OpenZip);
{From, get_state} ->
From ! {self(), OpenZip},
- server_loop(OpenZip);
+ server_loop(Parent, OpenZip);
+ {'EXIT', Parent, Reason} ->
+ _ = openzip_close(OpenZip),
+ exit({parent_died, Reason});
_ ->
{error, bad_msg}
end.
-spec(zip_open(Archive) -> {ok, ZipHandle} | {error, Reason} when
Archive :: file:name() | binary(),
- ZipHandle :: pid(),
+ ZipHandle :: handle(),
Reason :: term()).
zip_open(Archive) -> zip_open(Archive, []).
-spec(zip_open(Archive, Options) -> {ok, ZipHandle} | {error, Reason} when
Archive :: file:name() | binary(),
- ZipHandle :: pid(),
+ ZipHandle :: handle(),
Options :: [Option],
Option :: cooked | memory | {cwd, CWD :: file:filename()},
Reason :: term()).
zip_open(Archive, Options) ->
- Pid = spawn(fun() -> server_loop(not_open) end),
- request(self(), Pid, {open, Archive, Options}).
+ Self = self(),
+ Pid = spawn_link(fun() -> server_init(Self) end),
+ request(Self, Pid, {open, Archive, Options}).
-spec(zip_get(ZipHandle) -> {ok, [Result]} | {error, Reason} when
- ZipHandle :: pid(),
+ ZipHandle :: handle(),
Result :: file:name() | {file:name(), binary()},
Reason :: term()).
@@ -1174,14 +1185,14 @@ zip_get(Pid) when is_pid(Pid) ->
request(self(), Pid, get).
-spec(zip_close(ZipHandle) -> ok | {error, einval} when
- ZipHandle :: pid()).
+ ZipHandle :: handle()).
zip_close(Pid) when is_pid(Pid) ->
request(self(), Pid, close).
-spec(zip_get(FileName, ZipHandle) -> {ok, Result} | {error, Reason} when
FileName :: file:name(),
- ZipHandle :: pid(),
+ ZipHandle :: handle(),
Result :: file:name() | {file:name(), binary()},
Reason :: term()).
@@ -1190,7 +1201,7 @@ zip_get(FileName, Pid) when is_pid(Pid) ->
-spec(zip_list_dir(ZipHandle) -> {ok, Result} | {error, Reason} when
Result :: [zip_comment() | zip_file()],
- ZipHandle :: pid(),
+ ZipHandle :: handle(),
Reason :: term()).
zip_list_dir(Pid) when is_pid(Pid) ->
@@ -1539,57 +1550,35 @@ unix_extra_field_and_var_from_bin(_) ->
%% A pwrite-like function for iolists (used by memory-option)
-split_iolist(B, Pos) when is_binary(B) ->
- split_binary(B, Pos);
-split_iolist(L, Pos) when is_list(L) ->
- splitter([], L, Pos).
+pwrite_binary(B, Pos, Bin) when byte_size(B) =:= Pos ->
+ append_bins(Bin, B);
+pwrite_binary(B, Pos, Bin) ->
+ erlang:iolist_to_binary(pwrite_iolist(B, Pos, Bin)).
-splitter(Left, Right, 0) ->
- {Left, Right};
-splitter(Left, [A | Right], RelPos) when is_list(A) or is_binary(A) ->
- Sz = erlang:iolist_size(A),
- case Sz > RelPos of
- true ->
- {Leftx, Rightx} = split_iolist(A, RelPos),
- {[Left | Leftx], [Rightx, Right]};
- _ ->
- splitter([Left | A], Right, RelPos - Sz)
- end;
-splitter(Left, [A | Right], RelPos) when is_integer(A) ->
- splitter([Left, A], Right, RelPos - 1);
-splitter(Left, Right, RelPos) when is_binary(Right) ->
- splitter(Left, [Right], RelPos).
+append_bins([Bin|Bins], B) when is_binary(Bin) ->
+ append_bins(Bins, <<B/binary, Bin/binary>>);
+append_bins([List|Bins], B) when is_list(List) ->
+ append_bins(Bins, append_bins(List, B));
+append_bins(Bin, B) when is_binary(Bin) ->
+ <<B/binary, Bin/binary>>;
+append_bins([_|_]=List, B) ->
+ <<B/binary, (iolist_to_binary(List))/binary>>;
+append_bins([], B) ->
+ B.
-skip_iolist(B, Pos) when is_binary(B) ->
- case B of
- <<_:Pos/binary, Bin/binary>> -> Bin;
- _ -> <<>>
- end;
-skip_iolist(L, Pos) when is_list(L) ->
- skipper(L, Pos).
-
-skipper(Right, 0) ->
- Right;
-skipper([A | Right], RelPos) when is_list(A) or is_binary(A) ->
- Sz = erlang:iolist_size(A),
- case Sz > RelPos of
- true ->
- Rightx = skip_iolist(A, RelPos),
- [Rightx, Right];
- _ ->
- skip_iolist(Right, RelPos - Sz)
- end;
-skipper([A | Right], RelPos) when is_integer(A) ->
- skip_iolist(Right, RelPos - 1).
+-dialyzer({no_improper_lists, pwrite_iolist/3}).
-pwrite_iolist(Iolist, Pos, Bin) ->
- {Left, Right} = split_iolist(Iolist, Pos),
+pwrite_iolist(B, Pos, Bin) ->
+ {Left, Right} = split_binary(B, Pos),
Sz = erlang:iolist_size(Bin),
- R = skip_iolist(Right, Sz),
+ R = skip_bin(Right, Sz),
[Left, Bin | R].
-pwrite_binary(B, Pos, Bin) ->
- erlang:iolist_to_binary(pwrite_iolist(B, Pos, Bin)).
+skip_bin(B, Pos) when is_binary(B) ->
+ case B of
+ <<_:Pos/binary, Bin/binary>> -> Bin;
+ _ -> <<>>
+ end.
%% ZIP header manipulations
diff --git a/lib/stdlib/test/ExpandTestCaps.erl b/lib/stdlib/test/ExpandTestCaps.erl
index 96c4115354..1e5a1d68c3 100644
--- a/lib/stdlib/test/ExpandTestCaps.erl
+++ b/lib/stdlib/test/ExpandTestCaps.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/ExpandTestCaps1.erl b/lib/stdlib/test/ExpandTestCaps1.erl
index 09ee9f81c4..e7ad0925f1 100644
--- a/lib/stdlib/test/ExpandTestCaps1.erl
+++ b/lib/stdlib/test/ExpandTestCaps1.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index a271229c59..e366c2b755 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -23,12 +23,14 @@ MODULES= \
dummy_via \
edlin_expand_SUITE \
epp_SUITE \
+ erl_anno_SUITE \
erl_eval_SUITE \
erl_expand_records_SUITE \
erl_internal_SUITE \
erl_lint_SUITE \
erl_pp_SUITE \
erl_scan_SUITE \
+ error_logger_h_SUITE \
escript_SUITE \
ets_SUITE \
ets_tough_SUITE \
@@ -53,6 +55,7 @@ MODULES= \
proc_lib_SUITE \
qlc_SUITE \
queue_SUITE \
+ rand_SUITE \
random_SUITE \
re_SUITE \
run_pcre_tests \
@@ -105,7 +108,8 @@ RELSYSDIR = $(RELEASE_PATH)/stdlib_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
- -I$(ERL_TOP)/lib/kernel/include
+ -I$(ERL_TOP)/lib/kernel/include \
+ -I$(ERL_TOP)/lib/stdlib/include
EBIN = .
diff --git a/lib/stdlib/test/array_SUITE.erl b/lib/stdlib/test/array_SUITE.erl
index 1b496bb8ec..ab4ca91f76 100644
--- a/lib/stdlib/test/array_SUITE.erl
+++ b/lib/stdlib/test/array_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/base64_SUITE.erl b/lib/stdlib/test/base64_SUITE.erl
index b0da6408ff..75eebba6c6 100644
--- a/lib/stdlib/test/base64_SUITE.erl
+++ b/lib/stdlib/test/base64_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -29,7 +30,8 @@
%% Test cases must be exported.
-export([base64_encode/1, base64_decode/1, base64_otp_5635/1,
base64_otp_6279/1, big/1, illegal/1, mime_decode/1,
- mime_decode_to_string/1, roundtrip/1]).
+ mime_decode_to_string/1,
+ roundtrip_1/1, roundtrip_2/1, roundtrip_3/1, roundtrip_4/1]).
init_per_testcase(_, Config) ->
Dog = test_server:timetrap(?t:minutes(4)),
@@ -49,10 +51,11 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[base64_encode, base64_decode, base64_otp_5635,
base64_otp_6279, big, illegal, mime_decode, mime_decode_to_string,
- roundtrip].
+ {group, roundtrip}].
groups() ->
- [].
+ [{roundtrip, [parallel],
+ [roundtrip_1, roundtrip_2, roundtrip_3, roundtrip_4]}].
init_per_suite(Config) ->
Config.
@@ -241,21 +244,33 @@ mime_decode_to_string(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-roundtrip(Config) when is_list(Config) ->
- Sizes = lists:seq(1, 255) ++ lists:seq(2400-5, 2440),
- roundtrip_1(Sizes, []).
+roundtrip_1(Config) when is_list(Config) ->
+ do_roundtrip(1).
+
+roundtrip_2(Config) when is_list(Config) ->
+ do_roundtrip(2).
+
+roundtrip_3(Config) when is_list(Config) ->
+ do_roundtrip(3).
+
+roundtrip_4(Config) when is_list(Config) ->
+ do_roundtrip(4).
+
+do_roundtrip(Offset) ->
+ Sizes = lists:seq(Offset, 255, 4) ++ lists:seq(2400-6+Offset, 2440, 4),
+ do_roundtrip_1(Sizes, []).
-roundtrip_1([NextSize|Sizes], Current) ->
+do_roundtrip_1([NextSize|Sizes], Current) ->
Len = length(Current),
io:format("~p", [Len]),
- do_roundtrip(Current),
+ do_roundtrip_2(Current),
Next = random_byte_list(NextSize - Len, Current),
- roundtrip_1(Sizes, Next);
-roundtrip_1([], Last) ->
+ do_roundtrip_1(Sizes, Next);
+do_roundtrip_1([], Last) ->
io:format("~p", [length(Last)]),
- do_roundtrip(Last).
+ do_roundtrip_2(Last).
-do_roundtrip(List) ->
+do_roundtrip_2(List) ->
Bin = list_to_binary(List),
Base64Bin = base64:encode(List),
Base64Bin = base64:encode(Bin),
diff --git a/lib/stdlib/test/beam_lib_SUITE.erl b/lib/stdlib/test/beam_lib_SUITE.erl
index 5df19ca7f1..c102f6e929 100644
--- a/lib/stdlib/test/beam_lib_SUITE.erl
+++ b/lib/stdlib/test/beam_lib_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl
index 32cec0db6f..70c946bdb9 100644
--- a/lib/stdlib/test/binary_module_SUITE.erl
+++ b/lib/stdlib/test/binary_module_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -506,12 +507,35 @@ do_interesting(Module) ->
?line [<<1,2,3>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
[<<4,5>>,<<7>>,<<8>>],
[global,trim]),
+ ?line [<<1,2,3>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],
+ [global,trim_all]),
?line [<<1,2,3,4,5,6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
[<<4,5>>,<<7>>,<<8>>],
[global,trim,{scope,{0,4}}]),
?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
[<<4,5>>,<<7>>,<<8>>],
[global,trim,{scope,{0,5}}]),
+
+ ?line [<<>>,<<>>,<<3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<1>>,<<2>>,<<4,5>>],
+ [global,trim]),
+ ?line [<<3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<1>>,<<2>>,<<4,5>>],
+ [global,trim_all]),
+
+ ?line [<<1,2,3>>,<<>>,<<7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<6>>],
+ [global,trim]),
+ ?line [<<1,2,3>>,<<7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<6>>],
+ [global,trim_all]),
+ ?line [<<>>,<<>>,<<3>>,<<>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<1>>,<<2>>,<<4>>,<<5>>,<<7>>,<<8>>],
+ [global,trim]),
+ ?line [<<3>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<1>>,<<2>>,<<4>>,<<5>>,<<7>>,<<8>>],
+ [global,trim_all]),
?line badarg = ?MASK_ERROR(
Module:replace(<<1,2,3,4,5,6,7,8>>,
[<<4,5>>,<<7>>,<<8>>],<<99>>,
@@ -970,43 +994,51 @@ random_parts(X,N) ->
random_ref_comp(doc) ->
["Test pseudorandomly generated cases against reference imlementation"];
random_ref_comp(Config) when is_list(Config) ->
- ?line put(success_counter,0),
- ?line random:seed({1271,769940,559934}),
- ?line do_random_match_comp(5000,{1,40},{30,1000}),
+ put(success_counter,0),
+ random:seed({1271,769940,559934}),
+ Nr = {1,40},
+ Hr = {30,1000},
+ I1 = 1500,
+ I2 = 5,
+ do_random_match_comp(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_match_comp2(5000,{1,40},{30,1000}),
+ do_random_match_comp2(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_match_comp3(5000,{1,40},{30,1000}),
+ do_random_match_comp3(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_match_comp4(5000,{1,40},{30,1000}),
+ do_random_match_comp4(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_matches_comp(5000,{1,40},{30,1000}),
+ do_random_matches_comp(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_matches_comp2(5000,{1,40},{30,1000}),
+ do_random_matches_comp2(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_matches_comp3(5,{1,40},{30,1000}),
- ?line erts_debug:set_internal_state(available_internal_state,true),
- ?line io:format("oldlimit: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,100)]),
- ?line do_random_match_comp(5000,{1,40},{30,1000}),
- ?line do_random_matches_comp3(5,{1,40},{30,1000}),
- ?line io:format("limit was: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,default)]),
- ?line erts_debug:set_internal_state(available_internal_state,false),
+ do_random_matches_comp3(I2,Nr,Hr),
+ erts_debug:set_internal_state(available_internal_state,true),
+ io:format("oldlimit: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,100)]),
+ do_random_match_comp(I1,Nr,Hr),
+ do_random_matches_comp3(I2,Nr,Hr),
+ io:format("limit was: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,default)]),
+ erts_debug:set_internal_state(available_internal_state,false),
ok.
random_ref_sr_comp(doc) ->
["Test pseudorandomly generated cases against reference imlementation of split and replace"];
random_ref_sr_comp(Config) when is_list(Config) ->
- ?line put(success_counter,0),
- ?line random:seed({1271,769940,559934}),
- ?line do_random_split_comp(5000,{1,40},{30,1000}),
+ put(success_counter,0),
+ random:seed({1271,769940,559934}),
+ Nr = {1,40},
+ Hr = {30,1000},
+ I1 = 1500,
+ do_random_split_comp(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_replace_comp(5000,{1,40},{30,1000}),
+ do_random_replace_comp(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_split_comp2(5000,{1,40},{30,1000}),
+ do_random_split_comp2(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
- ?line do_random_replace_comp2(5000,{1,40},{30,1000}),
+ do_random_replace_comp2(I1,Nr,Hr),
io:format("Number of successes: ~p~n",[get(success_counter)]),
ok.
+
random_ref_fla_comp(doc) ->
["Test pseudorandomly generated cases against reference imlementation of split and replace"];
random_ref_fla_comp(Config) when is_list(Config) ->
@@ -1107,7 +1139,9 @@ do_random_matches_comp3(N,NeedleRange,HaystackRange) ->
Needles = [random_substring(NeedleRange,Haystack) ||
_ <- lists:duplicate(NumNeedles,a)],
RefRes = binref:matches(Haystack,Needles),
- true = do_matches_comp_loop(10000,Needles,Haystack, RefRes),
+ RefRes = binary:matches(Haystack,Needles),
+ Compiled = binary:compile_pattern(Needles),
+ true = do_matches_comp_loop(10000,Compiled,Haystack, RefRes),
do_random_matches_comp3(N-1,NeedleRange,HaystackRange).
do_matches_comp_loop(0,_,_,_) ->
@@ -1137,9 +1171,8 @@ do_matches_comp2(N,H,A) ->
end.
do_matches_comp(N,H) ->
A = ?MASK_ERROR(binref:matches(H,N)),
- B = ?MASK_ERROR(binref:matches(H,binref:compile_pattern(N))),
- C = ?MASK_ERROR(binary:matches(H,N)),
- D = ?MASK_ERROR(binary:matches(make_unaligned(H),
+ B = ?MASK_ERROR(binary:matches(H,N)),
+ C = ?MASK_ERROR(binary:matches(make_unaligned(H),
binary:compile_pattern([make_unaligned2(X) || X <- N]))),
if
A =/= nomatch ->
@@ -1147,14 +1180,14 @@ do_matches_comp(N,H) ->
true ->
ok
end,
- case {(A =:= B), (B =:= C),(C =:= D)} of
- {true,true,true} ->
+ case {(A =:= B), (B =:= C)} of
+ {true,true} ->
true;
_ ->
io:format("Failed to match ~p (needle) against ~s (haystack)~n",
[N,H]),
- io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n",
- [A,B,C,D]),
+ io:format("A:~p,~nB:~p,~n,C:~p,~n",
+ [A,B,C]),
exit(mismatch)
end.
@@ -1196,46 +1229,44 @@ do_random_match_comp4(N,NeedleRange,HaystackRange) ->
do_match_comp(N,H) ->
A = ?MASK_ERROR(binref:match(H,N)),
- B = ?MASK_ERROR(binref:match(H,binref:compile_pattern([N]))),
- C = ?MASK_ERROR(binary:match(make_unaligned(H),N)),
- D = ?MASK_ERROR(binary:match(H,binary:compile_pattern([N]))),
- E = ?MASK_ERROR(binary:match(H,binary:compile_pattern(make_unaligned(N)))),
+ B = ?MASK_ERROR(binary:match(make_unaligned(H),N)),
+ C = ?MASK_ERROR(binary:match(H,binary:compile_pattern([N]))),
+ D = ?MASK_ERROR(binary:match(H,binary:compile_pattern(make_unaligned(N)))),
if
A =/= nomatch ->
put(success_counter,get(success_counter)+1);
true ->
ok
end,
- case {(A =:= B), (B =:= C),(C =:= D),(D =:= E)} of
- {true,true,true,true} ->
+ case {(A =:= B), (B =:= C),(C =:= D)} of
+ {true,true,true} ->
true;
_ ->
io:format("Failed to match ~s (needle) against ~s (haystack)~n",
[N,H]),
- io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p,E:~p.~n",
- [A,B,C,D,E]),
+ io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n",
+ [A,B,C,D]),
exit(mismatch)
end.
do_match_comp3(N,H) ->
A = ?MASK_ERROR(binref:match(H,N)),
- B = ?MASK_ERROR(binref:match(H,binref:compile_pattern(N))),
- C = ?MASK_ERROR(binary:match(H,N)),
- D = ?MASK_ERROR(binary:match(H,binary:compile_pattern(N))),
+ B = ?MASK_ERROR(binary:match(H,N)),
+ C = ?MASK_ERROR(binary:match(H,binary:compile_pattern(N))),
if
A =/= nomatch ->
put(success_counter,get(success_counter)+1);
true ->
ok
end,
- case {(A =:= B), (B =:= C),(C =:= D)} of
- {true,true,true} ->
+ case {(A =:= B),(B =:= C)} of
+ {true,true} ->
true;
_ ->
io:format("Failed to match ~s (needle) against ~s (haystack)~n",
[N,H]),
- io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n",
- [A,B,C,D]),
+ io:format("A:~p,~nB:~p,~n,C:~p.~n",
+ [A,B,C]),
exit(mismatch)
end.
@@ -1247,6 +1278,8 @@ do_random_split_comp(N,NeedleRange,HaystackRange) ->
true = do_split_comp(Needle,Haystack,[]),
true = do_split_comp(Needle,Haystack,[global]),
true = do_split_comp(Needle,Haystack,[global,trim]),
+ true = do_split_comp(Needle,Haystack,[global,trim_all]),
+ true = do_split_comp(Needle,Haystack,[global,trim,trim_all]),
do_random_split_comp(N-1,NeedleRange,HaystackRange).
do_random_split_comp2(0,_,_) ->
ok;
@@ -1257,6 +1290,9 @@ do_random_split_comp2(N,NeedleRange,HaystackRange) ->
_ <- lists:duplicate(NumNeedles,a)],
true = do_split_comp(Needles,Haystack,[]),
true = do_split_comp(Needles,Haystack,[global]),
+ true = do_split_comp(Needles,Haystack,[global,trim]),
+ true = do_split_comp(Needles,Haystack,[global,trim_all]),
+ true = do_split_comp(Needles,Haystack,[global,trim,trim_all]),
do_random_split_comp2(N-1,NeedleRange,HaystackRange).
do_split_comp(N,H,Opts) ->
diff --git a/lib/stdlib/test/binref.erl b/lib/stdlib/test/binref.erl
index 6d96736ef3..a52ea98e5a 100644
--- a/lib/stdlib/test/binref.erl
+++ b/lib/stdlib/test/binref.erl
@@ -155,7 +155,8 @@ split(Haystack,Needles0,Options) ->
true ->
exit(badtype)
end,
- {Part,Global,Trim} = get_opts_split(Options,{nomatch,false,false}),
+ {Part,Global,Trim,TrimAll} =
+ get_opts_split(Options,{nomatch,false,false,false}),
{Start,End,NewStack} =
case Part of
nomatch ->
@@ -180,20 +181,24 @@ split(Haystack,Needles0,Options) ->
[X]
end
end,
- do_split(Haystack,MList,0,Trim)
+ do_split(Haystack,MList,0,Trim,TrimAll)
catch
_:_ ->
erlang:error(badarg)
end.
-do_split(H,[],N,true) when N >= byte_size(H) ->
+do_split(H,[],N,true,_) when N >= byte_size(H) ->
[];
-do_split(H,[],N,_) ->
+do_split(H,[],N,_,true) when N >= byte_size(H) ->
+ [];
+do_split(H,[],N,_,_) ->
[part(H,{N,byte_size(H)-N})];
-do_split(H,[{A,B}|T],N,Trim) ->
+do_split(H,[{A,B}|T],N,Trim,TrimAll) ->
case part(H,{N,A-N}) of
+ <<>> when TrimAll == true ->
+ do_split(H,T,A+B,Trim,TrimAll);
<<>> ->
- Rest = do_split(H,T,A+B,Trim),
+ Rest = do_split(H,T,A+B,Trim,TrimAll),
case {Trim, Rest} of
{true,[]} ->
[];
@@ -201,7 +206,7 @@ do_split(H,[{A,B}|T],N,Trim) ->
[<<>> | Rest]
end;
Oth ->
- [Oth | do_split(H,T,A+B,Trim)]
+ [Oth | do_split(H,T,A+B,Trim,TrimAll)]
end.
@@ -565,14 +570,16 @@ get_opts_match([{scope,{A,B}} | T],_Part) ->
get_opts_match(_,_) ->
throw(badopt).
-get_opts_split([],{Part,Global,Trim}) ->
- {Part,Global,Trim};
-get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim}) ->
- get_opts_split(T,{{A,B},Global,Trim});
-get_opts_split([global | T],{Part,_Global,Trim}) ->
- get_opts_split(T,{Part,true,Trim});
-get_opts_split([trim | T],{Part,Global,_Trim}) ->
- get_opts_split(T,{Part,Global,true});
+get_opts_split([],{Part,Global,Trim,TrimAll}) ->
+ {Part,Global,Trim,TrimAll};
+get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim,TrimAll}) ->
+ get_opts_split(T,{{A,B},Global,Trim,TrimAll});
+get_opts_split([global | T],{Part,_Global,Trim,TrimAll}) ->
+ get_opts_split(T,{Part,true,Trim,TrimAll});
+get_opts_split([trim | T],{Part,Global,_Trim,TrimAll}) ->
+ get_opts_split(T,{Part,Global,true,TrimAll});
+get_opts_split([trim_all | T],{Part,Global,Trim,_TrimAll}) ->
+ get_opts_split(T,{Part,Global,Trim,true});
get_opts_split(_,_) ->
throw(badopt).
diff --git a/lib/stdlib/test/c_SUITE.erl b/lib/stdlib/test/c_SUITE.erl
index a018db9c91..f3a713abfd 100644
--- a/lib/stdlib/test/c_SUITE.erl
+++ b/lib/stdlib/test/c_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/c_SUITE_data/m.erl b/lib/stdlib/test/c_SUITE_data/m.erl
index 59e0d80b83..df1d5f4c01 100644
--- a/lib/stdlib/test/c_SUITE_data/m.erl
+++ b/lib/stdlib/test/c_SUITE_data/m.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index 8192d035ca..498b1f459c 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl
index 3b08ac165e..35e587afcc 100644
--- a/lib/stdlib/test/dets_SUITE.erl
+++ b/lib/stdlib/test/dets_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -1875,9 +1876,33 @@ fixtable(Config, Version) when is_list(Config) ->
{ok, _} = dets:open_file(T, [{type, duplicate_bag} | Args]),
%% In a fixed table, delete and re-insert an object.
ok = dets:insert(T, {1, a, b}),
+ SysBefore = erlang:timestamp(),
+ MonBefore = erlang:monotonic_time(),
dets:safe_fixtable(T, true),
+ MonAfter = erlang:monotonic_time(),
+ SysAfter = erlang:timestamp(),
+ Self = self(),
+ {FixMonTime,[{Self,1}]} = dets:info(T,safe_fixed_monotonic_time),
+ {FixSysTime,[{Self,1}]} = dets:info(T,safe_fixed),
+ true = is_integer(FixMonTime),
+ true = MonBefore =< FixMonTime,
+ true = FixMonTime =< MonAfter,
+ {FstMs,FstS,FstUs} = FixSysTime,
+ true = is_integer(FstMs),
+ true = is_integer(FstS),
+ true = is_integer(FstUs),
+ case erlang:system_info(time_warp_mode) of
+ no_time_warp ->
+ true = timer:now_diff(FixSysTime, SysBefore) >= 0,
+ true = timer:now_diff(SysAfter, FixSysTime) >= 0;
+ _ ->
+ %% ets:info(Tab,safe_fixed) not timewarp safe...
+ ignore
+ end,
ok = dets:match_delete(T, {1, a, b}),
ok = dets:insert(T, {1, a, b}),
+ {FixMonTime,[{Self,1}]} = dets:info(T,safe_fixed_monotonic_time),
+ {FixSysTime,[{Self,1}]} = dets:info(T,safe_fixed),
dets:safe_fixtable(T, false),
1 = length(dets:match_object(T, '_')),
diff --git a/lib/stdlib/test/dict_SUITE.erl b/lib/stdlib/test/dict_SUITE.erl
index 69814e12ce..648154ebbe 100644
--- a/lib/stdlib/test/dict_SUITE.erl
+++ b/lib/stdlib/test/dict_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -25,16 +26,16 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- create/1,store/1]).
+ create/1,store/1,iterate/1]).
-include_lib("test_server/include/test_server.hrl").
--import(lists, [foldl/3,reverse/1]).
+-import(lists, [foldl/3]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [create, store].
+ [create, store, iterate].
groups() ->
[].
@@ -93,6 +94,48 @@ store_1(List, M) ->
D0.
%%%
+%%% Test specifics for gb_trees.
+%%%
+
+iterate(Config) when is_list(Config) ->
+ test_all(fun iterate_1/1).
+
+iterate_1(M) ->
+ case M(module, []) of
+ gb_trees -> iterate_2(M);
+ _ -> ok
+ end,
+ M(empty, []).
+
+iterate_2(M) ->
+ random:seed(1, 2, 42),
+ iter_tree(M, 1000).
+
+iter_tree(_M, 0) ->
+ ok;
+iter_tree(M, N) ->
+ L = [{I, I} || I <- lists:seq(1, N)],
+ T = M(from_list, L),
+ L = lists:reverse(iterate_tree(M, T)),
+ R = random:uniform(N),
+ KV = lists:reverse(iterate_tree_from(M, R, T)),
+ KV = [P || P={K,_} <- L, K >= R],
+ iter_tree(M, N-1).
+
+iterate_tree(M, Tree) ->
+ I = M(iterator, Tree),
+ iterate_tree_1(M, M(next, I), []).
+
+iterate_tree_from(M, Start, Tree) ->
+ I = M(iterator_from, {Start, Tree}),
+ iterate_tree_1(M, M(next, I), []).
+
+iterate_tree_1(_, none, R) ->
+ R;
+iterate_tree_1(M, {K, V, I}, R) ->
+ iterate_tree_1(M, M(next, I), [{K, V} | R]).
+
+%%%
%%% Helper functions.
%%%
diff --git a/lib/stdlib/test/dict_test_lib.erl b/lib/stdlib/test/dict_test_lib.erl
index 4fdb4fa0bd..7c4c3572ae 100644
--- a/lib/stdlib/test/dict_test_lib.erl
+++ b/lib/stdlib/test/dict_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -29,6 +30,9 @@ new(Mod, Eq) ->
(module, []) -> Mod;
(size, D) -> Mod:size(D);
(is_empty, D) -> Mod:is_empty(D);
+ (iterator, S) -> Mod:iterator(S);
+ (iterator_from, {Start, S}) -> Mod:iterator_from(Start, S);
+ (next, I) -> Mod:next(I);
(to_list, D) -> to_list(Mod, D)
end.
diff --git a/lib/stdlib/test/digraph_SUITE.erl b/lib/stdlib/test/digraph_SUITE.erl
index ed01b32a59..9e007fe17d 100644
--- a/lib/stdlib/test/digraph_SUITE.erl
+++ b/lib/stdlib/test/digraph_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/digraph_utils_SUITE.erl b/lib/stdlib/test/digraph_utils_SUITE.erl
index 6b554c2fb7..747ccf322c 100644
--- a/lib/stdlib/test/digraph_utils_SUITE.erl
+++ b/lib/stdlib/test/digraph_utils_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/dummy1_h.erl b/lib/stdlib/test/dummy1_h.erl
index 5b503d5984..5db23872c4 100644
--- a/lib/stdlib/test/dummy1_h.erl
+++ b/lib/stdlib/test/dummy1_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/dummy_h.erl b/lib/stdlib/test/dummy_h.erl
index 7546fe78a0..c81ea984f2 100644
--- a/lib/stdlib/test/dummy_h.erl
+++ b/lib/stdlib/test/dummy_h.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
index 43c980e994..6fdc4c35df 100644
--- a/lib/stdlib/test/edlin_expand_SUITE.erl
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index b17e8bd186..4e5df661b3 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -211,7 +212,7 @@ predef_mac(Config) when is_list(Config) ->
?line File = filename:join(?config(data_dir, Config), "mac3.erl"),
?line {ok, List} = epp:parse_file(File, [], []),
?line [_,
- {attribute, LineCol1, l, Line1},
+ {attribute, Anno, l, Line1},
{attribute, _, f, File},
{attribute, _, machine1, _},
{attribute, _, module, mac3},
@@ -219,13 +220,9 @@ predef_mac(Config) when is_list(Config) ->
{attribute, _, ms, "mac3"},
{attribute, _, machine2, _}
| _] = List,
- ?line case LineCol1 of
- Line1 -> ok;
- {Line1,_} -> ok
- end,
+ Line1 = erl_anno:line(Anno),
ok.
-
variable_1(doc) ->
[];
variable_1(suite) ->
@@ -553,11 +550,7 @@ otp_7702(Config) when is_list(Config) ->
{ok, AC} = beam_lib:chunks(BeamFile, [abstract_code]),
{file_7702,[{abstract_code,{_,Forms}}]} = AC,
- Fun = fun(Attrs) ->
- {line, L} = erl_parse:get_attribute(Attrs, line),
- L
- end,
- Forms2 = [erl_lint:modify_line(Form, Fun) || Form <- Forms],
+ Forms2 = unopaque_forms(Forms),
?line
[{attribute,1,file,_},
_,
@@ -1395,9 +1388,10 @@ otp_10820(Config) when is_list(Config) ->
do_otp_10820(File, C, PC) ->
{ok,Node} = start_node(erl_pp_helper, "+fnu " ++ PC),
ok = rpc:call(Node, file, write_file, [File, C]),
- {ok,[{attribute,1,file,{File,1}},
- {attribute,2,module,any},
- {eof,2}]} = rpc:call(Node, epp, parse_file, [File, [],[]]),
+ {ok, Forms} = rpc:call(Node, epp, parse_file, [File, [],[]]),
+ [{attribute,1,file,{File,1}},
+ {attribute,2,module,any},
+ {eof,2}] = unopaque_forms(Forms),
true = test_server:stop_node(Node),
ok.
@@ -1440,15 +1434,15 @@ encoding(Config) when is_list(Config) ->
{attribute,1,module,encoding},
{error,_},
{error,{2,epp,cannot_parse}},
- {eof,2}]} = epp:parse_file(ErlFile, []),
+ {eof,2}]} = epp_parse_file(ErlFile, []),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,3}]} =
- epp:parse_file(ErlFile, [{default_encoding,latin1}]),
+ epp_parse_file(ErlFile, [{default_encoding,latin1}]),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,3}],[{encoding,none}]} =
- epp:parse_file(ErlFile, [{default_encoding,latin1},extra]),
+ epp_parse_file(ErlFile, [{default_encoding,latin1},extra]),
%% Try a latin-1 file with encoding given in a comment.
C2 = <<"-module(encoding).
@@ -1459,27 +1453,27 @@ encoding(Config) when is_list(Config) ->
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,4}]} =
- epp:parse_file(ErlFile, []),
+ epp_parse_file(ErlFile, []),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,4}]} =
- epp:parse_file(ErlFile, [{default_encoding,latin1}]),
+ epp_parse_file(ErlFile, [{default_encoding,latin1}]),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,4}]} =
- epp:parse_file(ErlFile, [{default_encoding,utf8}]),
+ epp_parse_file(ErlFile, [{default_encoding,utf8}]),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,4}],[{encoding,latin1}]} =
- epp:parse_file(ErlFile, [extra]),
+ epp_parse_file(ErlFile, [extra]),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,4}],[{encoding,latin1}]} =
- epp:parse_file(ErlFile, [{default_encoding,latin1},extra]),
+ epp_parse_file(ErlFile, [{default_encoding,latin1},extra]),
{ok,[{attribute,1,file,_},
{attribute,1,module,encoding},
{eof,4}],[{encoding,latin1}]} =
- epp:parse_file(ErlFile, [{default_encoding,utf8},extra]),
+ epp_parse_file(ErlFile, [{default_encoding,utf8},extra]),
ok.
@@ -1552,6 +1546,17 @@ errs([_|L], File) ->
errs([], _File) ->
[].
+epp_parse_file(File, Opts) ->
+ case epp:parse_file(File, Opts) of
+ {ok, Forms} ->
+ {ok, unopaque_forms(Forms)};
+ {ok, Forms, Other} ->
+ {ok, unopaque_forms(Forms), Other}
+ end.
+
+unopaque_forms(Forms) ->
+ [erl_parse:anno_to_term(Form) || Form <- Forms].
+
run_test(Config, Test0) ->
Test = [<<"-module(epp_test). -compile(export_all). ">>, Test0],
Filename = "epp_test.erl",
diff --git a/lib/stdlib/test/epp_SUITE_data/mac.erl b/lib/stdlib/test/epp_SUITE_data/mac.erl
index e3329d76f9..210c57e033 100644
--- a/lib/stdlib/test/epp_SUITE_data/mac.erl
+++ b/lib/stdlib/test/epp_SUITE_data/mac.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/epp_SUITE_data/mac2.erl b/lib/stdlib/test/epp_SUITE_data/mac2.erl
index 0547cdb8b3..0dd83ece06 100644
--- a/lib/stdlib/test/epp_SUITE_data/mac2.erl
+++ b/lib/stdlib/test/epp_SUITE_data/mac2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/epp_SUITE_data/mac3.erl b/lib/stdlib/test/epp_SUITE_data/mac3.erl
index e5fb964a91..e7a3178db7 100644
--- a/lib/stdlib/test/epp_SUITE_data/mac3.erl
+++ b/lib/stdlib/test/epp_SUITE_data/mac3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/epp_SUITE_data/pmod.erl b/lib/stdlib/test/epp_SUITE_data/pmod.erl
index a4d4843a69..ff0ee81116 100644
--- a/lib/stdlib/test/epp_SUITE_data/pmod.erl
+++ b/lib/stdlib/test/epp_SUITE_data/pmod.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/epp_SUITE_data/variable_1.erl b/lib/stdlib/test/epp_SUITE_data/variable_1.erl
index b178f519a9..cd6a7bb69a 100644
--- a/lib/stdlib/test/epp_SUITE_data/variable_1.erl
+++ b/lib/stdlib/test/epp_SUITE_data/variable_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/epp_SUITE_data/variable_1_include.hrl b/lib/stdlib/test/epp_SUITE_data/variable_1_include.hrl
index 039d72aa49..30df6a3309 100644
--- a/lib/stdlib/test/epp_SUITE_data/variable_1_include.hrl
+++ b/lib/stdlib/test/epp_SUITE_data/variable_1_include.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/epp_SUITE_data/variable_1_include_dir.hrl b/lib/stdlib/test/epp_SUITE_data/variable_1_include_dir.hrl
index 727ccd421b..4e2bd3e41f 100644
--- a/lib/stdlib/test/epp_SUITE_data/variable_1_include_dir.hrl
+++ b/lib/stdlib/test/epp_SUITE_data/variable_1_include_dir.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/erl_anno_SUITE.erl b/lib/stdlib/test/erl_anno_SUITE.erl
new file mode 100644
index 0000000000..66b02151a0
--- /dev/null
+++ b/lib/stdlib/test/erl_anno_SUITE.erl
@@ -0,0 +1,569 @@
+%%
+%% %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
+%%
+%% 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(erl_anno_SUITE).
+
+%-define(debug, true).
+
+-ifdef(debug).
+-include_lib("test_server/include/test_server.hrl").
+-define(format(S, A), io:format(S, A)).
+-else.
+-include_lib("test_server/include/test_server.hrl").
+-define(format(S, A), ok).
+-endif.
+
+-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([new/1, is_anno/1, generated/1, end_location/1, file/1,
+ line/1, location/1, record/1, text/1, bad/1, neg_line/1]).
+
+-export([parse_abstract/1, mapfold_anno/1]).
+
+all() ->
+ [{group, anno}, {group, parse}].
+
+groups() ->
+ [{anno, [], [new, is_anno, generated, end_location, file,
+ line, location, record, text, bad, neg_line]},
+ {parse, [], [parse_abstract, mapfold_anno]}].
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog=?t:timetrap(?t:minutes(1)),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Case, _Config) ->
+ Dog=?config(watchdog, _Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+-define(INFO(T, V), {T, V}).
+
+-dialyzer({no_fail_call, new/1}).
+new(doc) ->
+ ["Test erl_anno:new/1"];
+new(_Config) ->
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:new([{location,1},{text, "text"}])), % badarg
+ ok.
+
+is_anno(doc) ->
+ ["Test erl_anno:is_anno/1"];
+is_anno(_Config) ->
+ false = erl_anno:is_anno(a),
+ false = erl_anno:is_anno({a}),
+ false = erl_anno:is_anno([]),
+ false = erl_anno:is_anno([{location, 1}|{generated, true}]),
+ false = erl_anno:is_anno([{generated,false}]),
+ false = erl_anno:is_anno([{generated,true}]),
+ false = erl_anno:is_anno([{location,1},{file,nofile}]),
+ false = erl_anno:is_anno([{location,1},{text,notext}]),
+
+ true = erl_anno:is_anno(erl_anno:new(1)),
+ A0 = erl_anno:new({1, 17}),
+ true = erl_anno:is_anno(A0),
+ A1 = erl_anno:set_generated(true, A0),
+ true = erl_anno:is_anno(A1),
+ A2 = erl_anno:set_file("", A1),
+ true = erl_anno:is_anno(A2),
+ A3 = erl_anno:set_record(true, A2),
+ true = erl_anno:is_anno(A3),
+ A4 = erl_anno:set_text("text", A3),
+ true = erl_anno:is_anno(A4),
+ A5 = erl_anno:set_file(<<"filename">>, A4),
+ true = erl_anno:is_anno(A5),
+ ok.
+
+generated(doc) ->
+ ["Test 'generated'"];
+generated(_Config) ->
+ test(1, [{generated, true}, {generated, false}]),
+ test(1, [{generated, false}, {generated, true}, {generated, false}]),
+ test({1, 17}, [{generated, false},
+ {generated, true},
+ {generated, false}]),
+ test({1, 17}, [{text, "text", [{end_location, {1, 21}}, {length, 4}]},
+ {generated, false},
+ {generated, true},
+ {generated, false}]),
+ test(1, [{generated, false},
+ {generated, true},
+ {generated, false}]),
+ test(1, [{text, "text", [{end_location, 1}, {length, 4}]},
+ {generated, false},
+ {generated, true},
+ {generated, false}]),
+ ok.
+
+end_location(doc) ->
+ ["Test 'end_location'"];
+end_location(_Config) ->
+ test({1, 17}, [{text, "TEXT", [{end_location, {1, 21}}, {length, 4}]},
+ {text, "TEXT\n", [{end_location, {2, 1}}, {length, 5}]},
+ {text, "TEXT\ntxt", [{end_location, {2, 4}}, {length, 8}]}]),
+ test(1, [{text, "TEXT", [{end_location, 1}, {length, 4}]},
+ {text, "TEXT\n", [{end_location, 2}, {length, 5}]},
+ {text, "TEXT\ntxt", [{end_location, 2}, {length, 8}]}]),
+ ok.
+
+file(doc) ->
+ ["Test 'file'"];
+file(_Config) ->
+ test(1, [{file, "name"}, {file, ""}]),
+ test({1, 17}, [{file, "name"}, {file, ""}]),
+ ok.
+
+line(doc) ->
+ ["Test 'line'"];
+line(_Config) ->
+ test(1, [{line, 17, [{location, 17}]},
+ {location, {9, 8}, [{line, 9}, {column, 8}]},
+ {line, 14, [{location, {14, 8}}]}]),
+ ok.
+
+location(doc) ->
+ ["Test 'location'"];
+location(_Config) ->
+ test(1, [{location, 2, [{line,2}]},
+ {location, {1, 17}, [{line, 1}, {column, 17}]},
+ {location, {9, 6}, [{line, 9}, {column, 6}]},
+ {location, 9, [{column, undefined}]}]),
+ test(1, [{generated, true},
+ {location, 2, [{line,2}]},
+ {location, {1, 17}, [{line, 1}, {column, 17}]},
+ {location, {9, 6}, [{line, 9}, {column, 6}]},
+ {location, 9, [{column, undefined}]}]),
+ test(1, [{record, true},
+ {location, 2, [{line,2}]},
+ {location, {1, 17}, [{line, 1}, {column, 17}]},
+ {location, {9, 6}, [{line, 9}, {column, 6}]},
+ {location, 9, [{column, undefined}]}]),
+ ok.
+
+record(doc) ->
+ ["Test 'record'"];
+record(_Config) ->
+ test({1, 17}, [{record, true}, {record, false}]),
+ test(1, [{record, true}, {record, false}]),
+ test({1, 17}, [{generated, false},
+ {generated, true},
+ {generated, false}]),
+ test({1, 17}, [{text, "text", [{end_location, {1, 21}}, {length, 4}]},
+ {generated, false},
+ {generated, true},
+ {generated, false}]),
+ test(1, [{generated, false},
+ {generated, true},
+ {generated, false}]),
+ test(1, [{text, "text", [{end_location, 1}, {length, 4}]},
+ {generated, false},
+ {generated, true},
+ {generated, false}]),
+ ok.
+
+text(doc) ->
+ ["Test 'text'"];
+text(_Config) ->
+ test(1, [{text, "text", [{end_location, 1}, {length, 4}]},
+ {text, "", [{end_location, 1}, {length, 0}]}]),
+ test({1, 17}, [{text, "text", [{end_location, {1,21}}, {length, 4}]},
+ {text, "", [{end_location, {1,17}}, {length, 0}]}]),
+ ok.
+
+-dialyzer({[no_opaque, no_fail_call], bad/1}).
+bad(doc) ->
+ ["Test bad annotations"];
+bad(_Config) ->
+ Line = erl_anno:new(1),
+ LineColumn = erl_anno:new({1, 17}),
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:set_generated(true, bad)), % 3rd arg not opaque
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:set_generated(false, bad)), % 3rd arg not opaque
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:set_generated(19, Line)),
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:set_generated(19, LineColumn)),
+
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:generated(bad)), % 1st arg not opaque
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:end_location(bad)), % 1st arg not opaque
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:file(bad)), % 1st arg not opaque
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:text(bad)), % 1st arg not opaque
+ {'EXIT', {badarg, _}} =
+ (catch erl_anno:record(bad)), % 1st arg not opaque
+ ok.
+
+neg_line(doc) ->
+ ["Test negative line numbers (OTP 18)"];
+neg_line(_Config) ->
+ neg_line1(false),
+ neg_line1(true),
+ ok.
+
+neg_line1(TextToo) ->
+ Minus8_0 = erl_anno:new(-8),
+ Plus8_0 = erl_anno:new(8),
+ Minus8C_0 = erl_anno:new({-8, 17}),
+ Plus8C_0 = erl_anno:new({8, 17}),
+
+ [Minus8, Plus8, Minus8C, Plus8C] =
+ [case TextToo of
+ true ->
+ erl_anno:set_text("foo", A);
+ false ->
+ A
+ end || A <- [Minus8_0, Plus8_0, Minus8C_0, Plus8C_0]],
+
+ tst(-3, erl_anno:set_location(3, Minus8)),
+ tst(-3, erl_anno:set_location(-3, Plus8)),
+ tst(-3, erl_anno:set_location(-3, Minus8)),
+ tst({-3,9}, erl_anno:set_location({3, 9}, Minus8)),
+ tst({-3,9}, erl_anno:set_location({-3, 9}, Plus8)),
+ tst({-3,9}, erl_anno:set_location({-3, 9}, Minus8)),
+ tst(-3, erl_anno:set_location(3, Minus8C)),
+ tst(-3, erl_anno:set_location(-3, Plus8C)),
+ tst(-3, erl_anno:set_location(-3, Minus8C)),
+ tst({-3,9}, erl_anno:set_location({3, 9}, Minus8C)),
+ tst({-3,9}, erl_anno:set_location({-3, 9}, Plus8C)),
+ tst({-3,9}, erl_anno:set_location({-3, 9}, Minus8C)),
+
+ tst(-8, erl_anno:set_generated(true, Plus8)),
+ tst(-8, erl_anno:set_generated(true, Minus8)),
+ tst({-8,17}, erl_anno:set_generated(true, Plus8C)),
+ tst({-8,17}, erl_anno:set_generated(true, Minus8C)),
+ tst(8, erl_anno:set_generated(false, Plus8)),
+ tst(8, erl_anno:set_generated(false, Minus8)),
+ tst({8,17}, erl_anno:set_generated(false, Plus8C)),
+ tst({8,17}, erl_anno:set_generated(false, Minus8C)),
+
+ tst(-3, erl_anno:set_line(3, Minus8)),
+ tst(-3, erl_anno:set_line(-3, Plus8)),
+ tst(-3, erl_anno:set_line(-3, Minus8)),
+ tst({-3,17}, erl_anno:set_line(3, Minus8C)),
+ tst({-3,17}, erl_anno:set_line(-3, Plus8C)),
+ tst({-3,17}, erl_anno:set_line(-3, Minus8C)),
+ ok.
+
+tst(Term, Anno) ->
+ ?format("Term: ~p\n", [Term]),
+ ?format("Anno: ~p\n", [Anno]),
+ case anno_to_term(Anno) of
+ Term ->
+ ok;
+ Else ->
+ case lists:keyfind(location, 1, Else) of
+ {location, Term} ->
+ ok;
+ _Else2 ->
+ ?format("Else2 ~p\n", [_Else2]),
+ io:format("expected ~p\n got ~p\n", [Term, Else]),
+ exit({Term, Else})
+ end
+ end.
+
+parse_abstract(doc) ->
+ ["Test erl_parse:new_anno/1, erl_parse:anno_to_term/1"
+ ", and erl_parse:anno_from_term/1"];
+parse_abstract(_Config) ->
+ T = sample_term(),
+ A = erl_parse:abstract(T, [{line,17}]),
+ T1 = erl_parse:anno_to_term(A),
+ Abstr = erl_parse:new_anno(T1),
+ T = erl_parse:normalise(Abstr),
+ Abstr2 = erl_parse:anno_from_term(T1),
+ T = erl_parse:normalise(Abstr2),
+ ok.
+
+mapfold_anno(doc) ->
+ ["Test erl_parse:{map_anno/2,fold_anno/3, and mapfold_anno/3}"];
+mapfold_anno(_Config) ->
+ T = sample_term(),
+ Abstr = erl_parse:abstract(T),
+ CF = fun(Anno, {L, D}) ->
+ {erl_anno:new(L), {L+1, dict:store(L, Anno, D)}}
+ end,
+ {U, {N, D}} = erl_parse:mapfold_anno(CF, {1, dict:new()}, Abstr),
+ SeqA = erl_parse:fold_anno(fun(Anno, Acc) -> [Anno|Acc] end, [], U),
+ Seq = [erl_anno:location(A) || A <- SeqA],
+ Seq = lists:seq(N-1, 1, -1),
+ NF = fun(Anno) ->
+ L = erl_anno:location(Anno),
+ dict:fetch(L, D)
+ end,
+ Abstr = erl_parse:map_anno(NF, U),
+ ok.
+
+sample_term() ->
+ %% This is just a sample.
+ {3,a,4.0,"foo",<<"bar">>,#{a => <<19:64/unsigned-little>>},
+ [1000,2000]}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+test(StartLocation, Updates) ->
+ S0 = init(StartLocation),
+ A0 = erl_anno:new(StartLocation),
+ chk(S0, A0, []),
+ eval(Updates, S0, A0).
+
+eval([], _S0, _A0) ->
+ ok;
+eval([{Item, Value}|Updates], S0, A0) ->
+ {S, A} = set(Item, Value, A0, S0, []),
+ eval(Updates, S, A);
+eval([{Item, Value, Secondary}|Updates], S0, A0) ->
+ {S, A} = set(Item, Value, A0, S0, Secondary),
+ eval(Updates, S, A).
+
+init({Line, Column}) ->
+ lists:sort([{location, {Line, Column}} | default()]);
+init(Line) when is_integer(Line) ->
+ lists:sort([{location, Line} | default()]).
+
+set(Item, Value, Anno0, State0, Secondary) ->
+ true = lists:member(Item, primary_items()),
+ ?format("Set '~w' to ~p\n", [Item, Value]),
+ State = set_value(Item, Value, State0),
+ Anno = anno_set(Item, Value, Anno0),
+ ?format("State0 ~p\n", [State0]),
+ ?format("State ~p\n", [State]),
+ ?format("Anno0 ~p\n", [anno_to_term(Anno0)]),
+ ?format("Anno ~p\n", [anno_to_term(Anno)]),
+ chk(State, Anno, Secondary),
+ ok = frame(Anno0, Anno, Secondary),
+ {State, Anno}.
+
+frame(OldAnno, NewAnno, Secondary) ->
+ SecItems = [I || {I, _} <- Secondary],
+ Frame = secondary_items() -- (SecItems ++ primary_items()),
+ ?format("Frame items ~p\n", [Frame]),
+ frame1(Frame, OldAnno, NewAnno).
+
+frame1([], _OldAnno, _NewAnno) ->
+ ok;
+frame1([Item|Items], OldAnno, NewAnno) ->
+ V1 = anno_info(OldAnno, Item),
+ V2 = anno_info(NewAnno, Item),
+ ok = check_value(Item, V1, V2),
+ frame1(Items, OldAnno, NewAnno).
+
+chk(State, Anno, Secondary) ->
+ ok = check_simple(Anno),
+ ok = chk_primary(State, Anno),
+ ok = check_secondary(Secondary, State, Anno).
+
+chk_primary(State, Anno) ->
+ chk_primary(primary_items(), State, Anno).
+
+chk_primary([], _State, _Anno) ->
+ ok;
+chk_primary([Item | Items], State, Anno) ->
+ V1 = primary_value(Item, State),
+ V2 = anno_info(Anno, Item),
+ ok = check_value(Item, V1, V2),
+ chk_primary(Items, State, Anno).
+
+check_secondary([], _State, _Anno) ->
+ ok;
+check_secondary([{Item, _}=V1 | Secondary], State, Anno) ->
+ V2 = anno_info(Anno, Item),
+ case {V1, V2} of
+ {{Item, undefined}, undefined} ->
+ ok;
+ _ ->
+ ok = check_value(Item, V1, V2)
+ end,
+ check_secondary(Secondary, State, Anno).
+
+check_value(Item, V1, V2) ->
+ ?format("~w: V1 ~p\n", [Item, V1]),
+ ?format("~w: V2 ~p\n", [Item, V2]),
+ case V1 =:= V2 of
+ true ->
+ ok;
+ false ->
+ io:format("~w: expected ~p\n got ~p\n", [Item, V1, V2]),
+ exit({V1, V2})
+ end.
+
+check_simple(Anno) ->
+ Term = anno_to_term(Anno),
+ case find_defaults(Term) of
+ [] ->
+ ok;
+ Ds ->
+ io:format("found default values ~w in ~p\n", [Ds, Anno]),
+ exit({defaults, Anno})
+ end,
+ case check_simple1(Term) of
+ true ->
+ ok;
+ false ->
+ io:format("not simple ~p\n", [Anno]),
+ exit({not_simple, Anno})
+ end.
+
+check_simple1(L) when is_integer(L) ->
+ true;
+check_simple1({L, C}) when is_integer(L), is_integer(C) ->
+ true;
+check_simple1(List) ->
+ case lists:sort(List) of
+ [{location, _}] ->
+ false;
+ _ ->
+ true
+ end.
+
+find_defaults(L) when is_list(L) ->
+ [I ||
+ I <- default_items(),
+ {I1, Value} <- L,
+ I =:= I1,
+ Value =:= default_value(I)];
+find_defaults(_) ->
+ [].
+
+anno_to_term(Anno) ->
+ T = erl_anno:to_term(Anno),
+ maybe_sort(T).
+
+maybe_sort(L) when is_list(L) ->
+ lists:sort(L);
+maybe_sort(T) ->
+ T.
+
+anno_set(file, Value, Anno) ->
+ erl_anno:set_file(Value, Anno);
+anno_set(generated, Value, Anno) ->
+ erl_anno:set_generated(Value, Anno);
+anno_set(line, Value, Anno) ->
+ erl_anno:set_line(Value, Anno);
+anno_set(location, Value, Anno) ->
+ erl_anno:set_location(Value, Anno);
+anno_set(record, Value, Anno) ->
+ erl_anno:set_record(Value, Anno);
+anno_set(text, Value, Anno) ->
+ erl_anno:set_text(Value, Anno).
+
+anno_info(Anno, Item) ->
+ Value =
+ case Item of
+ column ->
+ erl_anno:column(Anno);
+ generated ->
+ erl_anno:generated(Anno);
+ end_location ->
+ erl_anno:end_location(Anno);
+ file ->
+ erl_anno:file(Anno);
+ length ->
+ case erl_anno:text(Anno) of
+ undefined ->
+ undefined;
+ Text ->
+ length(Text)
+ end;
+ line ->
+ erl_anno:line(Anno);
+ location ->
+ erl_anno:location(Anno);
+ record ->
+ erl_anno:record(Anno);
+ text ->
+ erl_anno:text(Anno);
+ _ ->
+ erlang:error(badarg, [Anno, Item])
+ end,
+ if
+ Value =:= undefined ->
+ undefined;
+ true ->
+ {Item, Value}
+ end.
+
+%%% Originally 'location' was primary while 'line' and 'column' were
+%%% secondary (their values are determined by 'location'). But since
+%%% set_line() is used kind of frequently, 'line' is also primary,
+%%% and 'location' secondary (depends on 'line'). 'line' need to be
+%%% handled separately.
+
+set_value(line, Line, State) ->
+ {location, Location} = primary_value(location, State),
+ NewLocation = case Location of
+ {_, Column} ->
+ {Line, Column};
+ _ ->
+ Line
+ end,
+ set_value(location, NewLocation, State);
+set_value(Item, Value, State) ->
+ lists:ukeymerge(1, [{Item, Value}], State).
+
+primary_value(line, State) ->
+ {location, Location} = primary_value(location, State),
+ {line, case Location of
+ {Line, _} ->
+ Line;
+ Line ->
+ Line
+ end};
+primary_value(Item, State) ->
+ case lists:keyfind(Item, 1, State) of
+ false ->
+ undefined;
+ Tuple ->
+ Tuple
+ end.
+
+default() ->
+ [{Tag, default_value(Tag)} || Tag <- default_items()].
+
+primary_items() ->
+ [file, generated, line, location, record, text].
+
+secondary_items() ->
+ %% 'length' has not been implemented
+ [column, end_location, length, line, location].
+
+default_items() ->
+ [generated, record].
+
+default_value(generated) -> false;
+default_value(record) -> false.
diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index b55324161b..c21c4e61ee 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
@@ -38,6 +39,7 @@
otp_7550/1,
otp_8133/1,
otp_10622/1,
+ otp_13228/1,
funs/1,
try_catch/1,
eval_expr_5/1,
@@ -82,7 +84,8 @@ all() ->
pattern_expr, match_bin, guard_3, guard_4, guard_5, lc,
simple_cases, unary_plus, apply_atom, otp_5269,
otp_6539, otp_6543, otp_6787, otp_6977, otp_7550,
- otp_8133, otp_10622, funs, try_catch, eval_expr_5, zero_width,
+ otp_8133, otp_10622, otp_13228,
+ funs, try_catch, eval_expr_5, zero_width,
eep37, eep43].
groups() ->
@@ -1041,6 +1044,13 @@ otp_10622(Config) when is_list(Config) ->
ok.
+otp_13228(doc) ->
+ ["OTP-13228. ERL-32: non-local function handler bug."];
+otp_13228(_Config) ->
+ LFH = {value, fun(foo, [io_fwrite]) -> worked end},
+ EFH = {value, fun({io, fwrite}, [atom]) -> io_fwrite end},
+ {value, worked, []} = parse_and_run("foo(io:fwrite(atom)).", LFH, EFH).
+
funs(doc) ->
["Simple cases, just to cover some code."];
funs(suite) ->
@@ -1458,8 +1468,45 @@ eep43(Config) when is_list(Config) ->
"lists:map(fun (X) -> X#{price := 0} end,
[#{hello => 0, price => nil}]).",
[#{hello => 0, price => 0}]),
- error_check("[camembert]#{}.", {badarg,[camembert]}),
+ check(fun () ->
+ Map = #{ <<33:333>> => "wat" },
+ #{ <<33:333>> := "wat" } = Map
+ end,
+ "begin "
+ " Map = #{ <<33:333>> => \"wat\" }, "
+ " #{ <<33:333>> := \"wat\" } = Map "
+ "end.",
+ #{ <<33:333>> => "wat" }),
+ check(fun () ->
+ K1 = 1,
+ K2 = <<42:301>>,
+ K3 = {3,K2},
+ Map = #{ K1 => 1, K2 => 2, K3 => 3, {2,2} => 4},
+ #{ K1 := 1, K2 := 2, K3 := 3, {2,2} := 4} = Map
+ end,
+ "begin "
+ " K1 = 1, "
+ " K2 = <<42:301>>, "
+ " K3 = {3,K2}, "
+ " Map = #{ K1 => 1, K2 => 2, K3 => 3, {2,2} => 4}, "
+ " #{ K1 := 1, K2 := 2, K3 := 3, {2,2} := 4} = Map "
+ "end.",
+ #{ 1 => 1, <<42:301>> => 2, {3,<<42:301>>} => 3, {2,2} => 4}),
+ check(fun () ->
+ X = key,
+ (fun(#{X := value}) -> true end)(#{X => value})
+ end,
+ "begin "
+ " X = key, "
+ " (fun(#{X := value}) -> true end)(#{X => value}) "
+ "end.",
+ true),
+
+ error_check("[camembert]#{}.", {badmap,[camembert]}),
+ error_check("[camembert]#{nonexisting:=v}.", {badmap,[camembert]}),
error_check("#{} = 1.", {badmatch,1}),
+ error_check("[]#{a=>error(bad)}.", bad),
+ error_check("(#{})#{nonexisting:=value}.", {badkey,nonexisting}),
ok.
%% Check the string in different contexts: as is; in fun; from compiled code.
diff --git a/lib/stdlib/test/erl_expand_records_SUITE.erl b/lib/stdlib/test/erl_expand_records_SUITE.erl
index 43e679f7ed..8cec445cb4 100644
--- a/lib/stdlib/test/erl_expand_records_SUITE.erl
+++ b/lib/stdlib/test/erl_expand_records_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/erl_internal_SUITE.erl b/lib/stdlib/test/erl_internal_SUITE.erl
index b6b3c004ea..0d2f535040 100644
--- a/lib/stdlib/test/erl_internal_SUITE.erl
+++ b/lib/stdlib/test/erl_internal_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -51,7 +52,7 @@ end_per_group(_GroupName, Config) ->
-define(default_timeout, ?t:minutes(2)).
init_per_testcase(_Case, Config) ->
- ?line Dog = test_server:timetrap(?default_timeout),
+ Dog = test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
end_per_testcase(_Case, Config) ->
@@ -63,27 +64,50 @@ behav(suite) -> [];
behav(doc) ->
["Check that the behaviour callbacks are correctly defined"];
behav(_) ->
- ?line check_behav_list([{start,2}, {stop,1}],
- application:behaviour_info(callbacks)),
- ?line check_behav_list([{init,1}, {handle_call,3}, {handle_cast,2},
- {handle_info,2}, {terminate,2}, {code_change,3}],
- gen_server:behaviour_info(callbacks)),
- ?line check_behav_list([{init,1}, {handle_event,3}, {handle_sync_event,4},
- {handle_info,3}, {terminate,3}, {code_change,4}],
- gen_fsm:behaviour_info(callbacks)),
- ?line check_behav_list([{init,1}, {handle_event,2}, {handle_call,2},
- {handle_info,2}, {terminate,2}, {code_change,3}],
- gen_event:behaviour_info(callbacks)),
- ?line check_behav_list( [{init,1}, {terminate,2}],
- supervisor_bridge:behaviour_info(callbacks)),
- ?line check_behav_list([{init,1}],
- supervisor:behaviour_info(callbacks)),
- ok.
+ Modules = [application, gen_server, gen_fsm, gen_event,
+ supervisor_bridge, supervisor],
+ lists:foreach(fun check_behav/1, Modules).
+
+check_behav(Module) ->
+ Callbacks = callbacks(Module),
+ Optional = optional_callbacks(Module),
+ check_behav_list(Callbacks, Module:behaviour_info(callbacks)),
+ check_behav_list(Optional, Module:behaviour_info(optional_callbacks)).
check_behav_list([], []) -> ok;
check_behav_list([L | L1], L2) ->
- ?line true = lists:member(L, L2),
- ?line L3 = lists:delete(L, L2),
+ true = lists:member(L, L2),
+ L3 = lists:delete(L, L2),
check_behav_list(L1, L3).
-
+callbacks(application) ->
+ [{start,2}, {stop,1}];
+callbacks(gen_server) ->
+ [{init,1}, {handle_call,3}, {handle_cast,2},
+ {handle_info,2}, {terminate,2}, {code_change,3},
+ {format_status,2}];
+callbacks(gen_fsm) ->
+ [{init,1}, {handle_event,3}, {handle_sync_event,4},
+ {handle_info,3}, {terminate,3}, {code_change,4},
+ {format_status,2}];
+callbacks(gen_event) ->
+ [{init,1}, {handle_event,2}, {handle_call,2},
+ {handle_info,2}, {terminate,2}, {code_change,3},
+ {format_status,2}];
+callbacks(supervisor_bridge) ->
+ [{init,1}, {terminate,2}];
+callbacks(supervisor) ->
+ [{init,1}].
+
+optional_callbacks(application) ->
+ [];
+optional_callbacks(gen_server) ->
+ [{format_status,2}];
+optional_callbacks(gen_fsm) ->
+ [{format_status,2}];
+optional_callbacks(gen_event) ->
+ [{format_status,2}];
+optional_callbacks(supervisor_bridge) ->
+ [];
+optional_callbacks(supervisor) ->
+ [].
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index ea61b2082b..375fb6bc93 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -42,6 +43,7 @@
unused_vars_warn_rec/1,
unused_vars_warn_fun/1,
unused_vars_OTP_4858/1,
+ unused_unsafe_vars_warn/1,
export_vars_warn/1,
shadow_vars/1,
unused_import/1,
@@ -55,7 +57,7 @@
otp_11772/1, otp_11771/1, otp_11872/1,
export_all/1,
bif_clash/1,
- behaviour_basic/1, behaviour_multiple/1,
+ behaviour_basic/1, behaviour_multiple/1, otp_11861/1,
otp_7550/1,
otp_8051/1,
format_warn/1,
@@ -63,7 +65,7 @@
too_many_arguments/1,
basic_errors/1,bin_syntax_errors/1,
predef/1,
- maps/1,maps_type/1
+ maps/1,maps_type/1,otp_11851/1,otp_12195/1, otp_13230/1
]).
% Default timetrap timeout (set in init_per_testcase).
@@ -89,16 +91,16 @@ all() ->
otp_5362, otp_5371, otp_7227, otp_5494, otp_5644,
otp_5878, otp_5917, otp_6585, otp_6885, otp_10436, otp_11254,
otp_11772, otp_11771, otp_11872, export_all,
- bif_clash, behaviour_basic, behaviour_multiple,
+ bif_clash, behaviour_basic, behaviour_multiple, otp_11861,
otp_7550, otp_8051, format_warn, {group, on_load},
too_many_arguments, basic_errors, bin_syntax_errors, predef,
- maps, maps_type].
+ maps, maps_type, otp_11851, otp_12195, otp_13230].
groups() ->
[{unused_vars_warn, [],
[unused_vars_warn_basic, unused_vars_warn_lc,
unused_vars_warn_rec, unused_vars_warn_fun,
- unused_vars_OTP_4858]},
+ unused_vars_OTP_4858, unused_unsafe_vars_warn]},
{on_load, [], [on_load_successful, on_load_failing]}].
init_per_suite(Config) ->
@@ -730,6 +732,48 @@ unused_vars_OTP_4858(Config) when is_list(Config) ->
?line [] = run(Config, Ts),
ok.
+unused_unsafe_vars_warn(Config) when is_list(Config) ->
+ Ts = [{unused_unsafe1,
+ <<"t1() ->
+ UnusedVar1 = unused1,
+ try
+ UnusedVar2 = unused2
+ catch
+ _:_ ->
+ ok
+ end,
+ ok.
+ ">>,
+ [warn_unused_vars],
+ {warnings,[{2,erl_lint,{unused_var,'UnusedVar1'}},
+ {4,erl_lint,{unused_var,'UnusedVar2'}}]}},
+ {unused_unsafe2,
+ <<"t2() ->
+ try
+ X = 1
+ catch
+ _:_ -> ok
+ end.
+ ">>,
+ [warn_unused_vars],
+ {warnings,[{3,erl_lint,{unused_var,'X'}}]}},
+ {unused_unsafe2,
+ <<"t3(X, Y) ->
+ X andalso Y.
+ ">>,
+ [warn_unused_vars],
+ []},
+ {unused_unsafe4,
+ <<"t4() ->
+ _ = (catch X = X = 1),
+ _ = case ok of _ -> fun() -> ok end end,
+ fun (X) -> X end.
+ ">>,
+ [warn_unused_vars],
+ []}],
+ run(Config, Ts),
+ ok.
+
export_vars_warn(doc) ->
"Warnings for exported variables";
export_vars_warn(suite) -> [];
@@ -808,7 +852,19 @@ export_vars_warn(Config) when is_list(Config) ->
[],
{error,[{9,erl_lint,{unbound_var,'B'}}],
[{9,erl_lint,{exported_var,'Y',{'receive',2}}},
- {10,erl_lint,{shadowed_var,'B',generate}}]}}
+ {10,erl_lint,{shadowed_var,'B',generate}}]}},
+
+ {exp4,
+ <<"t(X) ->
+ if true -> Z = X end,
+ case X of
+ 1 -> Z;
+ 2 -> X
+ end,
+ Z = X.
+ ">>,
+ [],
+ {warnings,[{7,erl_lint,{exported_var,'Z',{'if',2}}}]}}
],
?line [] = run(Config, Ts),
ok.
@@ -832,8 +888,15 @@ shadow_vars(Config) when is_list(Config) ->
">>,
[nowarn_shadow_vars],
{error,[{9,erl_lint,{unbound_var,'B'}}],
- [{9,erl_lint,{exported_var,'Y',{'receive',2}}}]}}],
-
+ [{9,erl_lint,{exported_var,'Y',{'receive',2}}}]}},
+ {shadow2,
+ <<"t() ->
+ _ = (catch MS = MS = 1), % MS used unsafe
+ _ = case ok of _ -> fun() -> ok end end,
+ fun (MS) -> MS end. % MS not shadowed here
+ ">>,
+ [],
+ []}],
?line [] = run(Config, Ts),
ok.
@@ -958,6 +1021,45 @@ unsafe_vars(Config) when is_list(Config) ->
[warn_unused_vars],
{errors,[{3,erl_lint,{unsafe_var,'X',{'if',2}}},
{4,erl_lint,{unsafe_var,'X',{'if',2}}}],
+ []}},
+ {unsafe8,
+ <<"t8(X) ->
+ case X of _ -> catch _Y = 1 end,
+ _Y."
+ >>,
+ [],
+ {errors,[{3,erl_lint,{unsafe_var,'_Y',{'catch',2}}}],
+ []}},
+ {unsafe9,
+ <<"t9(X) ->
+ case X of
+ 1 ->
+ catch A = 1, % unsafe only here
+ B = 1,
+ C = 1,
+ D = 1;
+ 2 ->
+ A = 2,
+ % B not bound here
+ C = 2,
+ catch D = 2; % unsafe in two clauses
+ 3 ->
+ A = 3,
+ B = 3,
+ C = 3,
+ catch D = 3; % unsafe in two clauses
+ 4 ->
+ A = 4,
+ B = 4,
+ C = 4,
+ D = 4
+ end,
+ {A,B,C,D}."
+ >>,
+ [],
+ {errors,[{24,erl_lint,{unsafe_var,'A',{'catch',4}}},
+ {24,erl_lint,{unsafe_var,'B',{'case',2}}},
+ {24,erl_lint,{unsafe_var,'D',{'case',2}}}],
[]}}
],
?line [] = run(Config, Ts),
@@ -2648,8 +2750,9 @@ otp_11872(Config) when is_list(Config) ->
t() ->
1.
">>,
- {error,[{6,erl_lint,{undefined_type,{product,0}}}],
- [{8,erl_lint,{new_var_arity_type,map}}]} =
+ {error,[{6,erl_lint,{undefined_type,{product,0}}},
+ {8,erl_lint,{undefined_type,{dict,0}}}],
+ [{8,erl_lint,{new_builtin_type,{map,0}}}]} =
run_test2(Config, Ts, []),
ok.
@@ -3080,6 +3183,193 @@ behaviour_multiple(Config) when is_list(Config) ->
?line [] = run(Config, Ts),
ok.
+otp_11861(doc) ->
+ "OTP-11861. behaviour_info() and -callback.";
+otp_11861(suite) -> [];
+otp_11861(Conf) when is_list(Conf) ->
+ CallbackFiles = [callback1, callback2, callback3,
+ bad_behaviour1, bad_behaviour2],
+ lists:foreach(fun(M) ->
+ F = filename:join(?datadir, M),
+ Opts = [{outdir,?privdir}, return],
+ {ok, M, []} = compile:file(F, Opts)
+ end, CallbackFiles),
+ CodePath = code:get_path(),
+ true = code:add_path(?privdir),
+ Ts = [{otp_11861_1,
+ <<"
+ -export([b1/1]).
+ -behaviour(callback1).
+ -behaviour(callback2).
+
+ -spec b1(atom()) -> integer().
+ b1(A) when is_atom(A)->
+ 3.
+ ">>,
+ [],
+ %% b2/1 is optional in both modules
+ {warnings,[{4,erl_lint,
+ {conflicting_behaviours,{b1,1},callback2,3,callback1}}]}},
+ {otp_11861_2,
+ <<"
+ -export([b2/1]).
+ -behaviour(callback1).
+ -behaviour(callback2).
+
+ -spec b2(integer()) -> atom().
+ b2(I) when is_integer(I)->
+ a.
+ ">>,
+ [],
+ %% b2/1 is optional in callback2, but not in callback1
+ {warnings,[{3,erl_lint,{undefined_behaviour_func,{b1,1},callback1}},
+ {4,erl_lint,
+ {conflicting_behaviours,{b2,1},callback2,3,callback1}}]}},
+ {otp_11861_3,
+ <<"
+ -callback b(_) -> atom().
+ -optional_callbacks({b1,1}). % non-existing and ignored
+ ">>,
+ [],
+ []},
+ {otp_11861_4,
+ <<"
+ -callback b(_) -> atom().
+ -optional_callbacks([{b1,1}]). % non-existing
+ ">>,
+ [],
+ %% No behaviour-info(), but callback.
+ {errors,[{3,erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}},
+ {otp_11861_5,
+ <<"
+ -optional_callbacks([{b1,1}]). % non-existing
+ ">>,
+ [],
+ %% No behaviour-info() and no callback: warning anyway
+ {errors,[{2,erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}},
+ {otp_11861_6,
+ <<"
+ -optional_callbacks([b1/1]). % non-existing
+ behaviour_info(callbacks) -> [{b1,1}].
+ ">>,
+ [],
+ %% behaviour-info() and no callback: warning anyway
+ {errors,[{2,erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}},
+ {otp_11861_7,
+ <<"
+ -optional_callbacks([b1/1]). % non-existing
+ -callback b(_) -> atom().
+ behaviour_info(callbacks) -> [{b1,1}].
+ ">>,
+ [],
+ %% behaviour-info() callback: warning
+ {errors,[{2,erl_lint,{undefined_callback,{lint_test,b1,1}}},
+ {3,erl_lint,{behaviour_info,{lint_test,b,1}}}],
+ []}},
+ {otp_11861_8,
+ <<"
+ -callback b(_) -> atom().
+ -optional_callbacks([b/1, {b, 1}]).
+ ">>,
+ [],
+ {errors,[{3,erl_lint,{redefine_optional_callback,{b,1}}}],[]}},
+ {otp_11861_9,
+ <<"
+ -behaviour(gen_server).
+ -export([handle_call/3,handle_cast/2,handle_info/2,
+ code_change/3, init/1, terminate/2]).
+ handle_call(_, _, _) -> ok.
+ handle_cast(_, _) -> ok.
+ handle_info(_, _) -> ok.
+ code_change(_, _, _) -> ok.
+ init(_) -> ok.
+ terminate(_, _) -> ok.
+ ">>,
+ [],
+ []},
+ {otp_11861_9,
+ <<"
+ -behaviour(gen_server).
+ -export([handle_call/3,handle_cast/2,handle_info/2,
+ code_change/3, init/1, terminate/2, format_status/2]).
+ handle_call(_, _, _) -> ok.
+ handle_cast(_, _) -> ok.
+ handle_info(_, _) -> ok.
+ code_change(_, _, _) -> ok.
+ init(_) -> ok.
+ terminate(_, _) -> ok.
+ format_status(_, _) -> ok. % optional callback
+ ">>,
+ [],
+ %% Nothing...
+ []},
+ {otp_11861_10,
+ <<"
+ -optional_callbacks([{b1,1,bad}]). % badly formed and ignored
+ behaviour_info(callbacks) -> [{b1,1}].
+ ">>,
+ [],
+ []},
+ {otp_11861_11,
+ <<"
+ -behaviour(bad_behaviour1).
+ ">>,
+ [],
+ {warnings,[{2,erl_lint,
+ {ill_defined_behaviour_callbacks,bad_behaviour1}}]}},
+ {otp_11861_12,
+ <<"
+ -behaviour(non_existing_behaviour).
+ ">>,
+ [],
+ {warnings,[{2,erl_lint,
+ {undefined_behaviour,non_existing_behaviour}}]}},
+ {otp_11861_13,
+ <<"
+ -behaviour(bad_behaviour_none).
+ ">>,
+ [],
+ {warnings,[{2,erl_lint,{undefined_behaviour,bad_behaviour_none}}]}},
+ {otp_11861_14,
+ <<"
+ -callback b(_) -> atom().
+ ">>,
+ [],
+ []},
+ {otp_11861_15,
+ <<"
+ -optional_callbacks([{b1,1,bad}]). % badly formed
+ -callback b(_) -> atom().
+ ">>,
+ [],
+ []},
+ {otp_11861_16,
+ <<"
+ -callback b(_) -> atom().
+ -callback b(_) -> atom().
+ ">>,
+ [],
+ {errors,[{3,erl_lint,{redefine_callback,{b,1}}}],[]}},
+ {otp_11861_17,
+ <<"
+ -behaviour(bad_behaviour2).
+ ">>,
+ [],
+ {warnings,[{2,erl_lint,{undefined_behaviour_callbacks,
+ bad_behaviour2}}]}},
+ {otp_11861_18,
+ <<"
+ -export([f1/1]).
+ -behaviour(callback3).
+ f1(_) -> ok.
+ ">>,
+ [],
+ []}
+ ],
+ ?line [] = run(Conf, Ts),
+ true = code:set_path(CodePath),
+ ok.
+
otp_7550(doc) ->
"Test that the new utf8/utf16/utf32 types do not allow size or unit specifiers.";
otp_7550(Config) when is_list(Config) ->
@@ -3145,8 +3435,8 @@ format_warn(Config) when is_list(Config) ->
ok.
format_level(Level, Count, Config) ->
- ?line W = get_compilation_warnings(Config, "format",
- [{warn_format, Level}]),
+ ?line W = get_compilation_result(Config, "format",
+ [{warn_format, Level}]),
%% Pick out the 'format' warnings.
?line FW = lists:filter(fun({_Line, erl_lint, {format_error, _}}) -> true;
(_) -> false
@@ -3314,7 +3604,10 @@ bin_syntax_errors(Config) ->
t(<<X/unit:8>>) -> X;
t(<<X:7/float>>) -> X;
t(<< <<_:8>> >>) -> ok;
- t(<<(x ! y):8/integer>>) -> ok.
+ t(<<(x ! y):8/integer>>) -> ok;
+ t(X) ->
+ {<<X/binary-integer>>,<<X/signed-unsigned-integer>>,
+ <<X/little-big>>,<<X/unit:4-unit:8>>}.
">>,
[],
{error,[{1,erl_lint,illegal_bitsize},
@@ -3323,49 +3616,34 @@ bin_syntax_errors(Config) ->
{4,erl_lint,{undefined_bittype,bad_type}},
{5,erl_lint,bittype_unit},
{7,erl_lint,illegal_pattern},
- {8,erl_lint,illegal_pattern}],
+ {8,erl_lint,illegal_pattern},
+ {10,erl_lint,{bittype_mismatch,integer,binary,"type"}},
+ {10,erl_lint,{bittype_mismatch,unsigned,signed,"sign"}},
+ {11,erl_lint,{bittype_mismatch,8,4,"unit"}},
+ {11,erl_lint,{bittype_mismatch,big,little,"endianness"}}
+ ],
[{6,erl_lint,{bad_bitsize,"float"}}]}}
],
[] = run(Config, Ts),
ok.
predef(doc) ->
- "OTP-10342: Predefined types: array(), digraph(), and so on";
+ "OTP-10342: No longer predefined types: array(), digraph(), and so on";
predef(suite) -> [];
predef(Config) when is_list(Config) ->
- W = get_compilation_warnings(Config, "predef", []),
+ W = get_compilation_result(Config, "predef", []),
[] = W,
- W2 = get_compilation_warnings(Config, "predef2", []),
- Tag = deprecated_builtin_type,
- [{7,erl_lint,{Tag,{array,0},{array,array,1},"OTP 18.0"}},
- {12,erl_lint,{Tag,{dict,0},{dict,dict,2},"OTP 18.0"}},
- {17,erl_lint,{Tag,{digraph,0},{digraph,graph},"OTP 18.0"}},
- {27,erl_lint,{Tag,{gb_set,0},{gb_sets,set,1},"OTP 18.0"}},
- {32,erl_lint,{Tag,{gb_tree,0},{gb_trees,tree,2},"OTP 18.0"}},
- {37,erl_lint,{Tag,{queue,0},{queue,queue,1},"OTP 18.0"}},
- {42,erl_lint,{Tag,{set,0},{sets,set,1},"OTP 18.0"}},
- {47,erl_lint,{Tag,{tid,0},{ets,tid},"OTP 18.0"}}] = W2,
- Ts = [{otp_10342_1,
- <<"-compile(nowarn_deprecated_type).
-
- -spec t(dict()) -> non_neg_integer().
-
- t(D) ->
- erlang:phash2(D, 3000).
- ">>,
- {[nowarn_unused_function]},
- []},
- {otp_10342_2,
- <<"-spec t(dict()) -> non_neg_integer().
-
- t(D) ->
- erlang:phash2(D, 3000).
- ">>,
- {[nowarn_unused_function]},
- {warnings,[{1,erl_lint,
- {deprecated_builtin_type,{dict,0},{dict,dict,2},
- "OTP 18.0"}}]}}],
- [] = run(Config, Ts),
+ %% dict(), digraph() and so on were removed in Erlang/OTP 18.0.
+ E2 = get_compilation_result(Config, "predef2", []),
+ Tag = undefined_type,
+ {[{7,erl_lint,{Tag,{array,0}}},
+ {12,erl_lint,{Tag,{dict,0}}},
+ {17,erl_lint,{Tag,{digraph,0}}},
+ {27,erl_lint,{Tag,{gb_set,0}}},
+ {32,erl_lint,{Tag,{gb_tree,0}}},
+ {37,erl_lint,{Tag,{queue,0}}},
+ {42,erl_lint,{Tag,{set,0}}},
+ {47,erl_lint,{Tag,{tid,0}}}],[]} = E2,
ok.
maps(Config) ->
@@ -3398,7 +3676,8 @@ maps(Config) ->
g := 1 + 1,
h := _,
i := (_X = _Y),
- j := (x ! y) }) ->
+ j := (x ! y),
+ <<0:300>> := 33}) ->
{A,F}.
">>,
[],
@@ -3411,9 +3690,10 @@ maps(Config) ->
{errors,[{1,erl_lint,illegal_map_construction},
{1,erl_lint,{unbound_var,'X'}}],
[]}},
- {errors_in_map_keys,
+ {legal_map_construction,
<<"t(V) -> #{ a => 1,
#{a=>V} => 2,
+ #{{a,V}=>V} => 2,
#{ \"hi\" => wazzup, hi => ho } => yep,
[try a catch _:_ -> b end] => nope,
ok => 1.0,
@@ -3425,11 +3705,7 @@ maps(Config) ->
}.
">>,
[],
- {errors,[{2,erl_lint,{illegal_map_key_variable,'V'}},
- {4,erl_lint,illegal_map_key},
- {6,erl_lint,illegal_map_key},
- {8,erl_lint,illegal_map_key},
- {10,erl_lint,illegal_map_key}],[]}},
+ []},
{errors_in_map_keys_pattern,
<<"t(#{ a := 2,
#{} := A,
@@ -3440,8 +3716,14 @@ maps(Config) ->
A.
">>,
[],
- {errors,[{4,erl_lint,illegal_map_key},
- {6,erl_lint,{illegal_map_key_variable,'V'}}],[]}}],
+ {errors,[{4,erl_lint,illegal_map_construction},
+ {6,erl_lint,illegal_map_key}],[]}},
+ {unused_vars_with_empty_maps,
+ <<"t(Foo, Bar, Baz) -> {#{},#{}}.">>,
+ [warn_unused_variables],
+ {warnings,[{1,erl_lint,{unused_var,'Bar'}},
+ {1,erl_lint,{unused_var,'Baz'}},
+ {1,erl_lint,{unused_var,'Foo'}}]}}],
[] = run(Config, Ts),
ok.
@@ -3470,10 +3752,140 @@ maps_type(Config) when is_list(Config) ->
t(M) -> M.
">>,
[],
- {warnings,[{3,erl_lint,{new_var_arity_type,map}}]}}],
+ {warnings,[{3,erl_lint,{new_builtin_type,{map,0}}}]}}],
[] = run(Config, Ts),
ok.
+otp_11851(doc) ->
+ "OTP-11851: More atoms can be used as type names + bug fixes.";
+otp_11851(Config) when is_list(Config) ->
+ Ts = [
+ {otp_11851_1,
+ <<"-export([t/0]).
+ -type range(A, B) :: A | B.
+
+ -type union(A) :: A.
+
+ -type product() :: integer().
+
+ -type tuple(A) :: A.
+
+ -type map(A) :: A.
+
+ -type record() :: a | b.
+
+ -type integer(A) :: A.
+
+ -type atom(A) :: A.
+
+ -type binary(A, B) :: A | B.
+
+ -type 'fun'() :: integer().
+
+ -type 'fun'(X) :: X.
+
+ -type 'fun'(X, Y) :: X | Y.
+
+ -type all() :: range(atom(), integer()) | union(pid()) | product()
+ | tuple(reference()) | map(function()) | record()
+ | integer(atom()) | atom(integer())
+ | binary(pid(), tuple()) | 'fun'(port())
+ | 'fun'() | 'fun'(<<>>, 'none').
+
+ -spec t() -> all().
+
+ t() ->
+ a.
+ ">>,
+ [],
+ []},
+ {otp_11851_2,
+ <<"-export([a/1, b/1, t/0]).
+
+ -callback b(_) -> integer().
+
+ -callback ?MODULE:a(_) -> integer().
+
+ a(_) -> 3.
+
+ b(_) -> a.
+
+ t()-> a.
+ ">>,
+ [],
+ {errors,[{5,erl_lint,{bad_callback,{lint_test,a,1}}}],[]}},
+ {otp_11851_3,
+ <<"-export([a/1]).
+
+ -spec a(_A) -> boolean() when
+ _ :: atom(),
+ _A :: integer().
+
+ a(_) -> true.
+ ">>,
+ [],
+ {errors,[{4,erl_parse,"bad type variable"}],[]}},
+ {otp_11851_4,
+ <<"
+ -spec a(_) -> ok.
+ -spec a(_) -> ok.
+
+ -spec ?MODULE:a(_) -> ok.
+ -spec ?MODULE:a(_) -> ok.
+ ">>,
+ [],
+ {errors,[{3,erl_lint,{redefine_spec,{a,1}}},
+ {5,erl_lint,{redefine_spec,{lint_test,a,1}}},
+ {6,erl_lint,{redefine_spec,{lint_test,a,1}}},
+ {6,erl_lint,{spec_fun_undefined,{a,1}}}],
+ []}}
+ ],
+ [] = run(Config, Ts),
+ ok.
+
+otp_12195(doc) ->
+ "OTP-12195: Check obsolete types (tailor made for OTP 18).";
+otp_12195(Config) when is_list(Config) ->
+ Ts = [{otp_12195_1,
+ <<"-export_type([r1/0]).
+ -type r1() :: erl_scan:line()
+ | erl_scan:column()
+ | erl_scan:location()
+ | erl_anno:line().">>,
+ [],
+ {warnings,[{2,erl_lint,
+ {deprecated_type,{erl_scan,line,0},
+ "deprecated (will be removed in OTP 19); "
+ "use erl_anno:line() instead"}},
+ {3,erl_lint,
+ {deprecated_type,{erl_scan,column,0},
+ "deprecated (will be removed in OTP 19); use "
+ "erl_anno:column() instead"}},
+ {4,erl_lint,
+ {deprecated_type,{erl_scan,location,0},
+ "deprecated (will be removed in OTP 19); "
+ "use erl_anno:location() instead"}}]}},
+ {otp_12195_2,
+ <<"-export_type([r1/0]).
+ -compile(nowarn_deprecated_type).
+ -type r1() :: erl_scan:line()
+ | erl_scan:column()
+ | erl_scan:location()
+ | erl_anno:line().">>,
+ [],
+ []}],
+ [] = run(Config, Ts),
+ ok.
+
+otp_13230(doc) ->
+ "OTP-13230: -deprecated without -module";
+otp_13230(Config) when is_list(Config) ->
+ Abstr = <<"-deprecated([{frutt,0,next_version}]).">>,
+ {errors,[{1,erl_lint,undefined_module},
+ {1,erl_lint,{bad_deprecated,{frutt,0}}}],
+ []} = run_test2(Config, Abstr, []),
+ ok.
+
run(Config, Tests) ->
F = fun({N,P,Ws,E}, BadL) ->
case catch run_test(Config, P, Ws) of
@@ -3487,9 +3899,9 @@ run(Config, Tests) ->
end,
lists:foldl(F, [], Tests).
-%% Compiles a test file and returns the list of warnings.
+%% Compiles a test file and returns the list of warnings/errors.
-get_compilation_warnings(Conf, Filename, Warnings) ->
+get_compilation_result(Conf, Filename, Warnings) ->
?line DataDir = ?datadir,
?line File = filename:join(DataDir, Filename),
{ok,Bin} = file:read_file(File++".erl"),
@@ -3498,6 +3910,7 @@ get_compilation_warnings(Conf, Filename, Warnings) ->
Test = lists:nthtail(Start+Length, FileS),
case run_test(Conf, Test, Warnings) of
{warnings, Ws} -> Ws;
+ {errors,Es,Ws} -> {Es,Ws};
[] -> []
end.
@@ -3524,22 +3937,35 @@ run_test2(Conf, Test, Warnings0) ->
%% is no reason to produce an output file since we are only
%% interested in the errors and warnings.
- %% Print warnings, call erl_lint:format_error/1.
+ %% Print warnings, call erl_lint:format_error/1. (But note that
+ %% the compiler will ignore failing calls to erl_lint:format_error/1.)
compile:file(File, [binary,report|Opts]),
case compile:file(File, [binary|Opts]) of
- {ok, _M, Code, Ws} when is_binary(Code) -> warnings(File, Ws);
- {error, [{File,Es}], []} -> {errors, Es, []};
- {error, [{File,Es}], [{File,Ws}]} -> {error, Es, Ws};
- {error, [{File,Es1},{File,Es2}], []} -> {errors2, Es1, Es2}
+ {ok, _M, Code, Ws} when is_binary(Code) ->
+ warnings(File, Ws);
+ {error, [{File,Es}], []} ->
+ {errors, call_format_error(Es), []};
+ {error, [{File,Es}], [{File,Ws}]} ->
+ {error, call_format_error(Es), call_format_error(Ws)};
+ {error, [{File,Es1},{File,Es2}], []} ->
+ {errors2, Es1, Es2}
end.
warnings(File, Ws) ->
case lists:append([W || {F, W} <- Ws, F =:= File]) of
- [] -> [];
- L -> {warnings, L}
+ [] ->
+ [];
+ L ->
+ {warnings, call_format_error(L)}
end.
+call_format_error(L) ->
+ %% Smoke test of format_error/1 to make sure that no crashes
+ %% slip through.
+ _ = [Mod:format_error(Term) || {_,Mod,Term} <- L],
+ L.
+
fail() ->
io:format("failed~n"),
?t:fail().
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour1.erl b/lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour1.erl
new file mode 100644
index 0000000000..230f4b4519
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour1.erl
@@ -0,0 +1,6 @@
+-module(bad_behaviour1).
+
+-export([behaviour_info/1]).
+
+behaviour_info(callbacks) ->
+ [{a,1,bad}].
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour2.erl b/lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour2.erl
new file mode 100644
index 0000000000..bb755ce18b
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/bad_behaviour2.erl
@@ -0,0 +1,6 @@
+-module(bad_behaviour2).
+
+-export([behaviour_info/1]).
+
+behaviour_info(callbacks) ->
+ undefined.
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/callback1.erl b/lib/stdlib/test/erl_lint_SUITE_data/callback1.erl
new file mode 100644
index 0000000000..3cc5b51879
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/callback1.erl
@@ -0,0 +1,6 @@
+-module(callback1).
+
+-callback b1(I :: integer()) -> atom().
+-callback b2(A :: atom()) -> integer().
+
+-optional_callbacks([{b2,1}]).
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/callback2.erl b/lib/stdlib/test/erl_lint_SUITE_data/callback2.erl
new file mode 100644
index 0000000000..211cf9f115
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/callback2.erl
@@ -0,0 +1,6 @@
+-module(callback2).
+
+-callback b1(I :: integer()) -> atom().
+-callback b2(A :: atom()) -> integer().
+
+-optional_callbacks([b1/1, b2/1]).
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/callback3.erl b/lib/stdlib/test/erl_lint_SUITE_data/callback3.erl
new file mode 100644
index 0000000000..97b3ecb860
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/callback3.erl
@@ -0,0 +1,8 @@
+-module(callback3).
+
+-export([behaviour_info/1]).
+
+behaviour_info(callbacks) ->
+ [{f1, 1}];
+behaviour_info(_) ->
+ undefined.
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/format.erl b/lib/stdlib/test/erl_lint_SUITE_data/format.erl
index 20c4c5b57f..ede89cd545 100644
--- a/lib/stdlib/test/erl_lint_SUITE_data/format.erl
+++ b/lib/stdlib/test/erl_lint_SUITE_data/format.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/predef.erl b/lib/stdlib/test/erl_lint_SUITE_data/predef.erl
index ee9073aa67..3cb7bf40f1 100644
--- a/lib/stdlib/test/erl_lint_SUITE_data/predef.erl
+++ b/lib/stdlib/test/erl_lint_SUITE_data/predef.erl
@@ -5,8 +5,8 @@
-export_type([array/0, digraph/0, gb_set/0]).
-%% Before Erlang/OTP 17.0 local re-definitions of pre-defined opaque
-%% types were ignored but did not generate any warning.
+%% Since Erlang/OTP 18.0 array() and so on are no longer pre-defined,
+%% so there is nothing special about them at all.
-opaque array() :: atom().
-opaque digraph() :: atom().
-opaque gb_set() :: atom().
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index 927fe0b595..92e2764c65 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -42,7 +43,6 @@
-export([ func/1, call/1, recs/1, try_catch/1, if_then/1,
receive_after/1, bits/1, head_tail/1,
cond1/1, block/1, case1/1, ops/1, messages/1,
- old_mnemosyne_syntax/1,
import_export/1, misc_attrs/1, dialyzer_attrs/1,
hook/1,
neg_indent/1,
@@ -50,7 +50,7 @@
otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1,
otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1,
- otp_10302/1, otp_10820/1, otp_11100/1]).
+ otp_10302/1, otp_10820/1, otp_11100/1, otp_11861/1]).
%% Internal export.
-export([ehook/6]).
@@ -77,13 +77,13 @@ groups() ->
[{expr, [],
[func, call, recs, try_catch, if_then, receive_after,
bits, head_tail, cond1, block, case1, ops,
- messages, old_mnemosyne_syntax, maps_syntax
+ messages, maps_syntax
]},
{attributes, [], [misc_attrs, import_export, dialyzer_attrs]},
{tickets, [],
[otp_6321, otp_6911, otp_6914, otp_8150, otp_8238,
otp_8473, otp_8522, otp_8567, otp_8664, otp_9147,
- otp_10302, otp_10820, otp_11100]}].
+ otp_10302, otp_10820, otp_11100, otp_11861]}].
init_per_suite(Config) ->
Config.
@@ -491,7 +491,7 @@ cond1(Config) when is_list(Config) ->
[{cons,3,{atom,3,a},{cons,3,{atom,3,b},{nil,3}}}]},
{clause,4,[],[[{atom,4,true}]],
[{tuple,5,[{atom,5,x},{atom,5,y}]}]}]},
- ?line CChars = lists:flatten(erl_pp:expr(C)),
+ CChars = flat_expr1(C),
% ?line "cond {foo,bar} -> [a,b]; true -> {x,y} end" = CChars,
?line "cond\n"
" {foo,bar} ->\n"
@@ -558,30 +558,9 @@ messages(Config) when is_list(Config) ->
lists:flatten(erl_pp:form({error,{some,"error"}})),
?line true = "{warning,{some,\"warning\"}}\n" =:=
lists:flatten(erl_pp:form({warning,{some,"warning"}})),
- ?line true = "\n" =:= lists:flatten(erl_pp:form({eof,0})),
- ok.
-
-old_mnemosyne_syntax(Config) when is_list(Config) ->
- %% Since we have kept the ':-' token,
- %% better test that we can pretty print it.
- R = {rule,12,sales,2,
- [{clause,12,
- [{var,12,'E'},{atom,12,employee}],
- [],
- [{generate,13,
- {var,13,'E'},
- {call,13,{atom,13,table},[{atom,13,employee}]}},
- {match,14,
- {record_field,14,{var,14,'E'},{atom,14,salary}},
- {atom,14,sales}}]}]},
- ?line "sales(E, employee) :-\n"
- " E <- table(employee),\n"
- " E.salary = sales.\n" =
- lists:flatten(erl_pp:form(R)),
+ "\n" = flat_form({eof,0}),
ok.
-
-
import_export(suite) ->
[];
import_export(Config) when is_list(Config) ->
@@ -638,59 +617,41 @@ hook(Config) when is_list(Config) ->
do_hook(HookFun) ->
Lc = parse_expr(binary_to_list(<<"[X || X <- [1,2,3]].">>)),
H = HookFun(fun hook/4),
- Expr = {call,0,{atom,0,fff},[{foo,Lc},{foo,Lc},{foo,Lc}]},
+ A0 = erl_anno:new(0),
+ Expr = {call,A0,{atom,A0,fff},[{foo,Lc},{foo,Lc},{foo,Lc}]},
EChars = lists:flatten(erl_pp:expr(Expr, 0, H)),
- Call = {call,0,{atom,0,foo},[Lc]},
- Expr2 = {call,0,{atom,0,fff},[Call,Call,Call]},
+ Call = {call,A0,{atom,A0,foo},[Lc]},
+ Expr2 = {call,A0,{atom,A0,fff},[Call,Call,Call]},
EChars2 = erl_pp:exprs([Expr2]),
?line true = EChars =:= lists:flatten(EChars2),
EsChars = erl_pp:exprs([Expr], H),
?line true = EChars =:= lists:flatten(EsChars),
- F = {function,1,ffff,0,[{clause,1,[],[],[Expr]}]},
+ A1 = erl_anno:new(1),
+ F = {function,A1,ffff,0,[{clause,A1,[],[],[Expr]}]},
FuncChars = lists:flatten(erl_pp:function(F, H)),
- F2 = {function,1,ffff,0,[{clause,1,[],[],[Expr2]}]},
+ F2 = {function,A1,ffff,0,[{clause,A1,[],[],[Expr2]}]},
FuncChars2 = erl_pp:function(F2),
?line true = FuncChars =:= lists:flatten(FuncChars2),
FFormChars = erl_pp:form(F, H),
?line true = FuncChars =:= lists:flatten(FFormChars),
- A = {attribute,1,record,{r,[{record_field,1,{atom,1,a},Expr}]}},
+ A = {attribute,A1,record,{r,[{record_field,A1,{atom,A1,a},Expr}]}},
AChars = lists:flatten(erl_pp:attribute(A, H)),
- A2 = {attribute,1,record,{r,[{record_field,1,{atom,1,a},Expr2}]}},
+ A2 = {attribute,A1,record,{r,[{record_field,A1,{atom,A1,a},Expr2}]}},
AChars2 = erl_pp:attribute(A2),
?line true = AChars =:= lists:flatten(AChars2),
AFormChars = erl_pp:form(A, H),
?line true = AChars =:= lists:flatten(AFormChars),
- R = {rule,0,sales,0,
- [{clause,0,[{var,0,'E'},{atom,0,employee}],[],
- [{generate,2,{var,2,'E'},
- {call,2,{atom,2,table},[{atom,2,employee}]}},
- {match,3,
- {record_field,3,{var,3,'E'},{atom,3,salary}},
- {foo,Expr}}]}]},
- RChars = lists:flatten(erl_pp:rule(R, H)),
- R2 = {rule,0,sales,0,
- [{clause,0,[{var,0,'E'},{atom,0,employee}],[],
- [{generate,2,{var,2,'E'},
- {call,2,{atom,2,table},[{atom,2,employee}]}},
- {match,3,
- {record_field,3,{var,3,'E'},{atom,3,salary}},
- {call,0,{atom,0,foo},[Expr2]}}]}]},
- RChars2 = erl_pp:rule(R2),
- ?line true = RChars =:= lists:flatten(RChars2),
- ARChars = erl_pp:form(R, H),
- ?line true = RChars =:= lists:flatten(ARChars),
-
?line "INVALID-FORM:{foo,bar}:" = lists:flatten(erl_pp:expr({foo,bar})),
%% A list (as before R6), not a list of lists.
- G = [{op,1,'>',{atom,1,a},{foo,{atom,1,b}}}], % not a proper guard
+ G = [{op,A1,'>',{atom,A1,a},{foo,{atom,A1,b}}}], % not a proper guard
GChars = lists:flatten(erl_pp:guard(G, H)),
- G2 = [{op,1,'>',{atom,1,a},
- {call,0,{atom,0,foo},[{atom,1,b}]}}], % not a proper guard
+ G2 = [{op,A1,'>',{atom,A1,a},
+ {call,A0,{atom,A0,foo},[{atom,A1,b}]}}], % not a proper guard
GChars2 = erl_pp:guard(G2),
?line true = GChars =:= lists:flatten(GChars2),
@@ -701,14 +662,14 @@ do_hook(HookFun) ->
?line true = EChars =:= lists:flatten(XEChars2),
%% Note: no leading spaces before "begin".
- Block = {block,0,[{match,0,{var,0,'A'},{integer,0,3}},
- {atom,0,true}]},
+ Block = {block,A0,[{match,A0,{var,A0,'A'},{integer,A0,3}},
+ {atom,A0,true}]},
?line "begin\n A =" ++ _ =
lists:flatten(erl_pp:expr(Block, 17, none)),
%% Special...
?line true =
- "{some,value}" =:= lists:flatten(erl_pp:expr({value,0,{some,value}})),
+ "{some,value}" =:= lists:flatten(erl_pp:expr({value,A0,{some,value}})),
%% Silly...
?line true =
@@ -716,8 +677,8 @@ do_hook(HookFun) ->
flat_expr({'if',0,[{clause,0,[],[],[{atom,0,0}]}]}),
%% More compatibility: before R6
- OldIf = {'if',0,[{clause,0,[],[{atom,0,true}],[{atom,0,b}]}]},
- NewIf = {'if',0,[{clause,0,[],[[{atom,0,true}]],[{atom,0,b}]}]},
+ OldIf = {'if',A0,[{clause,A0,[],[{atom,A0,true}],[{atom,A0,b}]}]},
+ NewIf = {'if',A0,[{clause,A0,[],[[{atom,A0,true}]],[{atom,A0,b}]}]},
OldIfChars = lists:flatten(erl_pp:expr(OldIf)),
NewIfChars = lists:flatten(erl_pp:expr(NewIf)),
?line true = OldIfChars =:= NewIfChars,
@@ -733,7 +694,8 @@ ehook(HE, I, P, H, foo, bar) ->
hook(HE, I, P, H).
hook({foo,E}, I, P, H) ->
- erl_pp:expr({call,0,{atom,0,foo},[E]}, I, P, H).
+ A = erl_anno:new(0),
+ erl_pp:expr({call,A,{atom,A,foo},[E]}, I, P, H).
neg_indent(suite) ->
[];
@@ -816,7 +778,7 @@ otp_6911(Config) when is_list(Config) ->
{var,6,'X'},
[{clause,7,[{atom,7,true}],[],[{integer,7,12}]},
{clause,8,[{atom,8,false}],[],[{integer,8,14}]}]}]}]},
- ?line Chars = lists:flatten(erl_pp:form(F)),
+ Chars = flat_form(F),
?line "thomas(X) ->\n"
" case X of\n"
" true ->\n"
@@ -874,6 +836,7 @@ type_examples() ->
{ex3,<<"-type paren() :: (ann2()). ">>},
{ex4,<<"-type t1() :: atom(). ">>},
{ex5,<<"-type t2() :: [t1()]. ">>},
+ {ex56,<<"-type integer(A) :: A. ">>},
{ex6,<<"-type t3(Atom) :: integer(Atom). ">>},
{ex7,<<"-type '\\'t::4'() :: t3('\\'foobar'). ">>},
{ex8,<<"-type t5() :: {t1(), t3(foo)}. ">>},
@@ -997,6 +960,9 @@ maps_syntax(Config) when is_list(Config) ->
"-compile(export_all).\n"
"-type t1() :: map().\n"
"-type t2() :: #{ atom() => integer(), atom() => float() }.\n"
+ "-type u() :: #{a => (I :: integer()) | (A :: atom()),\n"
+ " (X :: atom()) | (Y :: atom()) =>\n"
+ " (I :: integer()) | (A :: atom())}.\n"
"-spec f1(t1()) -> 'true'.\n"
"f1(M) when is_map(M) -> true.\n"
"-spec f2(t2()) -> integer().\n"
@@ -1125,10 +1091,11 @@ otp_10302(Config) when is_list(Config) ->
Opts = [{hook, fun unicode_hook/4},{encoding,unicode}],
Lc = parse_expr("[X || X <- [\"\x{400}\",\"\xFF\"]]."),
- Expr = {call,0,{atom,0,fff},[{foo,{foo,Lc}},{foo,{foo,Lc}}]},
+ A0 = erl_anno:new(0),
+ Expr = {call,A0,{atom,A0,fff},[{foo,{foo,Lc}},{foo,{foo,Lc}}]},
EChars = lists:flatten(erl_pp:expr(Expr, 0, Opts)),
- Call = {call,0,{atom,0,foo},[{call,0,{atom,0,foo},[Lc]}]},
- Expr2 = {call,0,{atom,0,fff},[Call,Call]},
+ Call = {call,A0,{atom,A0,foo},[{call,A0,{atom,A0,foo},[Lc]}]},
+ Expr2 = {call,A0,{atom,A0,fff},[Call,Call]},
EChars2 = erl_pp:exprs([Expr2], U),
EChars = lists:flatten(EChars2),
[$\x{400},$\x{400}] = [C || C <- EChars, C > 255],
@@ -1138,7 +1105,8 @@ otp_10302(Config) when is_list(Config) ->
ok.
unicode_hook({foo,E}, I, P, H) ->
- erl_pp:expr({call,0,{atom,0,foo},[E]}, I, P, H).
+ A = erl_anno:new(0),
+ erl_pp:expr({call,A,{atom,A,foo},[E]}, I, P, H).
otp_10820(doc) ->
"OTP-10820. Unicode filenames.";
@@ -1178,34 +1146,45 @@ otp_11100(Config) when is_list(Config) ->
%% Cannot trigger the use of the hook function with export/import.
"-export([{fy,a}/b]).\n" =
pf({attribute,1,export,[{{fy,a},b}]}),
+ A1 = erl_anno:new(1),
"-type foo() :: integer(INVALID-FORM:{foo,bar}:).\n" =
- pf({attribute,1,type,{foo,{type,1,integer,[{foo,bar}]},[]}}),
- pf({attribute,1,type,
- {a,{type,1,range,[{integer,1,1},{foo,bar}]},[]}}),
+ pf({attribute,A1,type,{foo,{type,A1,integer,[{foo,bar}]},[]}}),
+ pf({attribute,A1,type,
+ {a,{type,A1,range,[{integer,A1,1},{foo,bar}]},[]}}),
"-type foo(INVALID-FORM:{foo,bar}:) :: A.\n" =
- pf({attribute,1,type,{foo,{var,1,'A'},[{foo,bar}]}}),
- "-type foo() :: (INVALID-FORM:{foo,bar}: :: []).\n" =
- pf({attribute,1,type,
- {foo,{paren_type,1,
- [{ann_type,1,[{foo,bar},{type,1,nil,[]}]}]},
+ pf({attribute,A1,type,{foo,{var,A1,'A'},[{foo,bar}]}}),
+ "-type foo() :: INVALID-FORM:{foo,bar}: :: [].\n" =
+ pf({attribute,A1,type,
+ {foo,{paren_type,A1,
+ [{ann_type,A1,[{foo,bar},{type,A1,nil,[]}]}]},
[]}}),
"-type foo() :: <<_:INVALID-FORM:{foo,bar}:>>.\n" =
- pf({attribute,1,type,
- {foo,{type,1,binary,[{foo,bar},{integer,1,0}]},[]}}),
+ pf({attribute,A1,type,
+ {foo,{type,A1,binary,[{foo,bar},{integer,A1,0}]},[]}}),
"-type foo() :: <<_:10, _:_*INVALID-FORM:{foo,bar}:>>.\n" =
- pf({attribute,1,type,
- {foo,{type,1,binary,[{integer,1,10},{foo,bar}]},[]}}),
+ pf({attribute,A1,type,
+ {foo,{type,A1,binary,[{integer,A1,10},{foo,bar}]},[]}}),
"-type foo() :: #r{INVALID-FORM:{foo,bar}: :: integer()}.\n" =
- pf({attribute,1,type,
- {foo,{type,1,record,
- [{atom,1,r},
- {type,1,field_type,
- [{foo,bar},{type,1,integer,[]}]}]},
+ pf({attribute,A1,type,
+ {foo,{type,A1,record,
+ [{atom,A1,r},
+ {type,A1,field_type,
+ [{foo,bar},{type,A1,integer,[]}]}]},
[]}}),
ok.
+otp_11861(doc) ->
+ "OTP-11861. behaviour_info() and -callback.";
+otp_11861(suite) -> [];
+otp_11861(Config) when is_list(Config) ->
+ "-optional_callbacks([bar/0]).\n" =
+ pf({attribute,3,optional_callbacks,[{bar,0}]}),
+ "-optional_callbacks([{bar,1,bad}]).\n" =
+ pf({attribute,4,optional_callbacks,[{bar,1,bad}]}),
+ ok.
+
pf(Form) ->
- lists:flatten(erl_pp:form(Form,none)).
+ lists:flatten(erl_pp:form(Form, none)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1270,9 +1249,18 @@ strip_module_info(Bin) ->
<<R:Start/binary,_/binary>> = Bin,
R.
-flat_expr(Expr) ->
+flat_expr1(Expr0) ->
+ Expr = erl_parse:new_anno(Expr0),
+ lists:flatten(erl_pp:expr(Expr)).
+
+flat_expr(Expr0) ->
+ Expr = erl_parse:new_anno(Expr0),
lists:flatten(erl_pp:expr(Expr, -1, none)).
+flat_form(Form0) ->
+ Form = erl_parse:new_anno(Form0),
+ lists:flatten(erl_pp:form(Form)).
+
pp_forms(Bin) ->
pp_forms(Bin, none).
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index 9be9f641c8..12ea3d128c 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -138,7 +139,7 @@ iso88591(Config) when is_list(Config) ->
A1s = [$h,$ä,$r],
A2s = [$ö,$r,$e],
%% Test parsing atom and variable characters.
- {ok,Ts1,_} = erl_scan:string(V1s ++ " " ++ V2s ++
+ {ok,Ts1,_} = erl_scan_string(V1s ++ " " ++ V2s ++
"\327" ++
A1s ++ " " ++ A2s),
V1s = atom_to_list(element(3, nth(1, Ts1))),
@@ -151,7 +152,7 @@ iso88591(Config) when is_list(Config) ->
%% Test parsing and printing strings.
S1 = V1s ++ "\327" ++ A1s ++ "\250" ++ A2s,
S1s = "\"" ++ S1 ++ "\"",
- {ok,Ts2,_} = erl_scan:string(S1s),
+ {ok,Ts2,_} = erl_scan_string(S1s),
S1 = element(3, nth(1, Ts2)),
S1s = flatten(print(element(3, nth(1, Ts2)))),
ok %It all worked
@@ -219,14 +220,14 @@ atoms() ->
test_string([39,65,200,39], [{atom,{1,1},'AÈ'}]),
test_string("ärlig östen", [{atom,{1,1},ärlig},{atom,{1,7},östen}]),
?line {ok,[{atom,_,'$a'}],{1,6}} =
- erl_scan:string("'$\\a'", {1,1}),
+ erl_scan_string("'$\\a'", {1,1}),
?line test("'$\\a'"),
ok.
punctuations() ->
L = ["<<", "<-", "<=", "<", ">>", ">=", ">", "->", "--",
"-", "++", "+", "=:=", "=/=", "=<", "=>", "==", "=", "/=",
- "/", "||", "|", ":=", ":-", "::", ":"],
+ "/", "||", "|", ":=", "::", ":"],
%% One token at a time:
[begin
W = list_to_atom(S),
@@ -268,24 +269,24 @@ punctuations() ->
comments() ->
?line test("a %%\n b"),
- ?line {ok,[],1} = erl_scan:string("%"),
+ {ok,[],1} = erl_scan_string("%"),
?line test("a %%\n b"),
{ok,[{atom,{1,1},a},{atom,{2,2},b}],{2,3}} =
- erl_scan:string("a %%\n b",{1,1}),
+ erl_scan_string("a %%\n b", {1,1}),
{ok,[{atom,{1,1},a},{comment,{1,3},"%%"},{atom,{2,2},b}],{2,3}} =
- erl_scan:string("a %%\n b",{1,1}, [return_comments]),
+ erl_scan_string("a %%\n b",{1,1}, [return_comments]),
{ok,[{atom,{1,1},a},
{white_space,{1,2}," "},
{white_space,{1,5},"\n "},
{atom,{2,2},b}],
{2,3}} =
- erl_scan:string("a %%\n b",{1,1},[return_white_spaces]),
+ erl_scan_string("a %%\n b",{1,1},[return_white_spaces]),
{ok,[{atom,{1,1},a},
{white_space,{1,2}," "},
{comment,{1,3},"%%"},
{white_space,{1,5},"\n "},
{atom,{2,2},b}],
- {2,3}} = erl_scan:string("a %%\n b",{1,1},[return]),
+ {2,3}} = erl_scan_string("a %%\n b",{1,1},[return]),
ok.
errors() ->
@@ -337,11 +338,11 @@ base_integers() ->
erl_scan:string(Str)
end || {BS,S} <- [{"3","3"},{"15","f"}, {"12","c"}] ],
- ?line {ok,[{integer,1,239},{'@',1}],1} = erl_scan:string("16#ef@"),
+ {ok,[{integer,1,239},{'@',1}],1} = erl_scan_string("16#ef@"),
{ok,[{integer,{1,1},239},{'@',{1,6}}],{1,7}} =
- erl_scan:string("16#ef@", {1,1}, []),
+ erl_scan_string("16#ef@", {1,1}, []),
{ok,[{integer,{1,1},14},{atom,{1,5},g@}],{1,7}} =
- erl_scan:string("16#eg@", {1,1}, []),
+ erl_scan_string("16#eg@", {1,1}, []),
ok.
@@ -382,8 +383,8 @@ dots() ->
{ok,[{'.',{1,1}},{atom,{1,2},a}],{1,3}}}
],
[begin
- R = erl_scan:string(S),
- R2 = erl_scan:string(S, {1,1}, [])
+ R = erl_scan_string(S),
+ R2 = erl_scan_string(S, {1,1}, [])
end || {S, R, R2} <- Dot],
?line {ok,[{dot,_}=T1],{1,2}} = erl_scan:string(".", {1,1}, text),
@@ -417,7 +418,7 @@ dots() ->
{white_space,{1,4},"\n"},
{dot,{2,1}}],
{2,3}}, ""} =
- erl_scan:tokens(C, "\n. ", {1,1}, return), % any loc, any options
+ erl_scan_tokens(C, "\n. ", {1,1}, return), % any loc, any options
?line [test_string(S, R) ||
{S, R} <- [{".$\n", [{'.',{1,1}},{char,{1,2},$\n}]},
@@ -511,7 +512,7 @@ eof() ->
%% An error before R13A.
%% ?line {done,Err={error,{1,erl_scan,scan},1},eof} =
?line {done,{ok,[{atom,1,abra}],1},eof} =
- erl_scan:tokens(C2, eof, 1),
+ erl_scan_tokens(C2, eof, 1),
%% With column.
?line {more, C3} = erl_scan:tokens([]," \n",{1,1}),
@@ -520,7 +521,7 @@ eof() ->
%% An error before R13A.
%% ?line {done,{error,{{1,1},erl_scan,scan},{1,5}},eof} =
?line {done,{ok,[{atom,_,abra}],{1,5}},eof} =
- erl_scan:tokens(C4, eof, 1),
+ erl_scan_tokens(C4, eof, 1),
%% Robert's scanner returns "" as LeftoverChars;
%% the R12B scanner returns eof as LeftoverChars: (eof is correct)
@@ -528,26 +529,26 @@ eof() ->
%% An error before R13A.
%% ?line {done,{error,{1,erl_scan,scan},1},eof} =
?line {done,{ok,[{atom,1,a}],1},eof} =
- erl_scan:tokens(C5,eof,1),
+ erl_scan_tokens(C5,eof,1),
%% With column.
{more, C6} = erl_scan:tokens([], "a", {1,1}),
%% An error before R13A.
%% {done,{error,{1,erl_scan,scan},1},eof} =
{done,{ok,[{atom,{1,1},a}],{1,2}},eof} =
- erl_scan:tokens(C6,eof,1),
+ erl_scan_tokens(C6,eof,1),
%% A dot followed by eof is special:
?line {more, C} = erl_scan:tokens([], "a.", 1),
- ?line {done,{ok,[{atom,1,a},{dot,1}],1},eof} = erl_scan:tokens(C,eof,1),
- ?line {ok,[{atom,1,foo},{dot,1}],1} = erl_scan:string("foo."),
+ {done,{ok,[{atom,1,a},{dot,1}],1},eof} = erl_scan_tokens(C,eof,1),
+ {ok,[{atom,1,foo},{dot,1}],1} = erl_scan_string("foo."),
%% With column.
{more, CCol} = erl_scan:tokens([], "a.", {1,1}),
{done,{ok,[{atom,{1,1},a},{dot,{1,2}}],{1,3}},eof} =
- erl_scan:tokens(CCol,eof,1),
+ erl_scan_tokens(CCol,eof,1),
{ok,[{atom,{1,1},foo},{dot,{1,4}}],{1,5}} =
- erl_scan:string("foo.", {1,1}, []),
+ erl_scan_string("foo.", {1,1}, []),
ok.
@@ -628,23 +629,23 @@ crashes() ->
options() ->
%% line and column are not options, but tested here
?line {ok,[{atom,1,foo},{white_space,1," "},{comment,1,"% bar"}], 1} =
- erl_scan:string("foo % bar", 1, return),
+ erl_scan_string("foo % bar", 1, return),
?line {ok,[{atom,1,foo},{white_space,1," "}],1} =
- erl_scan:string("foo % bar", 1, return_white_spaces),
+ erl_scan_string("foo % bar", 1, return_white_spaces),
?line {ok,[{atom,1,foo},{comment,1,"% bar"}],1} =
- erl_scan:string("foo % bar", 1, return_comments),
+ erl_scan_string("foo % bar", 1, return_comments),
?line {ok,[{atom,17,foo}],17} =
- erl_scan:string("foo % bar", 17),
+ erl_scan_string("foo % bar", 17),
?line {'EXIT',{function_clause,_}} =
(catch {foo,
erl_scan:string("foo % bar", {a,1}, [])}), % type error
?line {ok,[{atom,_,foo}],{17,18}} =
- erl_scan:string("foo % bar", {17,9}, []),
+ erl_scan_string("foo % bar", {17,9}, []),
?line {'EXIT',{function_clause,_}} =
(catch {foo,
erl_scan:string("foo % bar", {1,0}, [])}), % type error
?line {ok,[{foo,1}],1} =
- erl_scan:string("foo % bar",1, [{reserved_word_fun,
+ erl_scan_string("foo % bar",1, [{reserved_word_fun,
fun(W) -> W =:= foo end}]),
?line {'EXIT',{badarg,_}} =
(catch {foo,
@@ -706,8 +707,9 @@ token_info() ->
attributes_info() ->
?line {'EXIT',_} =
(catch {foo,erl_scan:attributes_info(foo)}), % type error
- ?line [{line,18}] = erl_scan:attributes_info(18),
- ?line {location,19} = erl_scan:attributes_info(19, location),
+ [{line,18}] = erl_scan:attributes_info(erl_anno:new(18)),
+ {location,19} =
+ erl_scan:attributes_info(erl_anno:new(19), location),
?line {ok,[{atom,A0,foo}],_} = erl_scan:string("foo", 19, [text]),
?line {location,19} = erl_scan:attributes_info(A0, location),
@@ -735,7 +737,9 @@ attributes_info() ->
set_attribute() ->
F = fun(Line) -> -Line end,
- ?line -2 = erl_scan:set_attribute(line, 2, F),
+ Anno2 = erl_anno:new(2),
+ A0 = erl_scan:set_attribute(line, Anno2, F),
+ {line, -2} = erl_scan:attributes_info(A0, line),
?line {ok,[{atom,A1,foo}],_} = erl_scan:string("foo", {9,17}),
?line A2 = erl_scan:set_attribute(line, A1, F),
?line {line,-9} = erl_scan:attributes_info(A2, line),
@@ -765,10 +769,15 @@ set_attribute() ->
?line {ok,[{atom,A6,foo}],_} = erl_scan:string("foo", 11, [text]),
?line A7 = erl_scan:set_attribute(line, A6, F2),
- ?line {line,{17,11}} = erl_scan:attributes_info(A7, line),
+ %% Incompatible with pre 18:
+ %% {line,{17,11}} = erl_scan:attributes_info(A7, line),
+ {line,17} = erl_scan:attributes_info(A7, line),
?line {location,{17,11}} = % mixed up
erl_scan:attributes_info(A7, location),
- ?line [{line,{17,11}},{text,"foo"}] =
+ %% Incompatible with pre 18:
+ %% [{line,{17,11}},{text,"foo"}] =
+ %% erl_scan:attributes_info(A7, [line,column,text]),
+ [{line,17},{column,11},{text,"foo"}] =
erl_scan:attributes_info(A7, [line,column,text]),
?line {'EXIT',_} =
@@ -776,9 +785,13 @@ set_attribute() ->
?line {'EXIT',{badarg,_}} =
(catch {foo, erl_scan:set_attribute(column, [], F2)}), % type error
+ Attr10 = erl_anno:new(8),
+ Attr20 = erl_scan:set_attribute(line, Attr10,
+ fun(L) -> {nos,'X',L} end),
%% OTP-9412
- ?line 8 = erl_scan:set_attribute(line, [{line,{nos,'X',8}}],
- fun({nos,_V,VL}) -> VL end),
+ Attr30 = erl_scan:set_attribute(line, Attr20,
+ fun({nos,_V,VL}) -> VL end),
+ 8 = erl_anno:to_term(Attr30),
ok.
column_errors() ->
@@ -812,7 +825,7 @@ white_spaces() ->
{white_space,_," "},
{atom,_,a},
{white_space,_,"\n"}],
- _} = erl_scan:string("\r a\n", {1,1}, return),
+ _} = erl_scan_string("\r a\n", {1,1}, return),
?line test("\r a\n"),
L = "{\"a\nb\", \"a\\nb\",\nabc\r,def}.\n\n",
?line {ok,[{'{',_},
@@ -829,7 +842,7 @@ white_spaces() ->
{'}',_},
{dot,_},
{white_space,_,"\n"}],
- _} = erl_scan:string(L, {1,1}, return),
+ _} = erl_scan_string(L, {1,1}, return),
?line test(L),
?line test("\"\n\"\n"),
?line test("\n\r\n"),
@@ -846,7 +859,7 @@ white_spaces() ->
unicode() ->
?line {ok,[{char,1,83},{integer,1,45}],1} =
- erl_scan:string("$\\12345"), % not unicode
+ erl_scan_string("$\\12345"), % not unicode
?line {error,{1,erl_scan,{illegal,character}},1} =
erl_scan:string([1089]),
@@ -858,7 +871,7 @@ unicode() ->
erl_scan:string("'a"++[1089]++"b'", {1,1}),
?line test("\"a"++[1089]++"b\""),
{ok,[{char,1,1}],1} =
- erl_scan:string([$$,$\\,$^,1089], 1),
+ erl_scan_string([$$,$\\,$^,1089], 1),
{error,{1,erl_scan,Error},1} =
erl_scan:string("\"qa\x{aaa}", 1),
@@ -870,13 +883,13 @@ unicode() ->
erl_scan:string("'qa\\x{aaa}'",{1,1}),
{ok,[{char,1,1089}],1} =
- erl_scan:string([$$,1089], 1),
+ erl_scan_string([$$,1089], 1),
{ok,[{char,1,1089}],1} =
- erl_scan:string([$$,$\\,1089], 1),
+ erl_scan_string([$$,$\\,1089], 1),
Qs = "$\\x{aaa}",
{ok,[{char,1,$\x{aaa}}],1} =
- erl_scan:string(Qs, 1),
+ erl_scan_string(Qs, 1),
{ok,[Q2],{1,9}} =
erl_scan:string("$\\x{aaa}", {1,1}, [text]),
[{category,char},{column,1},{length,8},
@@ -884,19 +897,19 @@ unicode() ->
erl_scan:token_info(Q2),
U1 = "\"\\x{aaa}\"",
- {ok,
- [{string,[{line,1},{column,1},{text,"\"\\x{aaa}\""}],[2730]}],
- {1,10}} = erl_scan:string(U1, {1,1}, [text]),
- {ok,[{string,1,[2730]}],1} = erl_scan:string(U1, 1),
+ {ok,[{string,A1,[2730]}],{1,10}} = erl_scan:string(U1, {1,1}, [text]),
+ [{line,1},{column,1},{text,"\"\\x{aaa}\""}] =
+ erl_scan:attributes_info(A1, [line, column, text]),
+ {ok,[{string,1,[2730]}],1} = erl_scan_string(U1, 1),
U2 = "\"\\x41\\x{fff}\\x42\"",
- {ok,[{string,1,[$\x41,$\x{fff},$\x42]}],1} = erl_scan:string(U2, 1),
+ {ok,[{string,1,[$\x41,$\x{fff},$\x42]}],1} = erl_scan_string(U2, 1),
U3 = "\"a\n\\x{fff}\n\"",
- {ok,[{string,1,[$a,$\n,$\x{fff},$\n]}],3} = erl_scan:string(U3, 1),
+ {ok,[{string,1,[$a,$\n,$\x{fff},$\n]}],3} = erl_scan_string(U3, 1),
U4 = "\"\\^\n\\x{aaa}\\^\n\"",
- {ok,[{string,1,[$\n,$\x{aaa},$\n]}],3} = erl_scan:string(U4, 1),
+ {ok,[{string,1,[$\n,$\x{aaa},$\n]}],3} = erl_scan_string(U4, 1),
%% Keep these tests:
?line test(Qs),
@@ -906,15 +919,15 @@ unicode() ->
?line test(U4),
Str1 = "\"ab" ++ [1089] ++ "cd\"",
- {ok,[{string,1,[$a,$b,1089,$c,$d]}],1} = erl_scan:string(Str1, 1),
+ {ok,[{string,1,[$a,$b,1089,$c,$d]}],1} = erl_scan_string(Str1, 1),
{ok,[{string,{1,1},[$a,$b,1089,$c,$d]}],{1,8}} =
- erl_scan:string(Str1, {1,1}),
+ erl_scan_string(Str1, {1,1}),
?line test(Str1),
Comment = "%% "++[1089],
{ok,[{comment,1,[$%,$%,$\s,1089]}],1} =
- erl_scan:string(Comment, 1, [return]),
+ erl_scan_string(Comment, 1, [return]),
{ok,[{comment,{1,1},[$%,$%,$\s,1089]}],{1,5}} =
- erl_scan:string(Comment, {1,1}, [return]),
+ erl_scan_string(Comment, {1,1}, [return]),
ok.
more_chars() ->
@@ -923,12 +936,12 @@ more_chars() ->
%% All kinds of tests...
?line {ok,[{char,_,123}],{1,4}} =
- erl_scan:string("$\\{",{1,1}),
+ erl_scan_string("$\\{",{1,1}),
?line {more, C1} = erl_scan:tokens([], "$\\{", {1,1}),
?line {done,{ok,[{char,_,123}],{1,4}},eof} =
- erl_scan:tokens(C1, eof, 1),
+ erl_scan_tokens(C1, eof, 1),
?line {ok,[{char,1,123},{atom,1,a},{'}',1}],1} =
- erl_scan:string("$\\{a}"),
+ erl_scan_string("$\\{a}"),
?line {error,{{1,1},erl_scan,char},{1,4}} =
erl_scan:string("$\\x", {1,1}),
@@ -993,11 +1006,11 @@ otp_10302(Config) when is_list(Config) ->
{error,{{1,1},erl_scan,{illegal,atom}},{1,12}} =
erl_scan:string("'qa\\x{aaa}'",{1,1}),
- {ok,[{char,1,1089}],1} = erl_scan:string([$$,1089], 1),
- {ok,[{char,1,1089}],1} = erl_scan:string([$$,$\\,1089],1),
+ {ok,[{char,1,1089}],1} = erl_scan_string([$$,1089], 1),
+ {ok,[{char,1,1089}],1} = erl_scan_string([$$,$\\,1089],1),
Qs = "$\\x{aaa}",
- {ok,[{char,1,2730}],1} = erl_scan:string(Qs,1),
+ {ok,[{char,1,2730}],1} = erl_scan_string(Qs, 1),
{ok,[Q2],{1,9}} = erl_scan:string(Qs,{1,1},[text]),
[{category,char},{column,1},{length,8},
{line,1},{symbol,16#aaa},{text,Qs}] =
@@ -1011,19 +1024,19 @@ otp_10302(Config) when is_list(Config) ->
{symbol,[16#aaa]},{text,U1}] = erl_scan:token_info(T1, Tags),
U2 = "\"\\x41\\x{fff}\\x42\"",
- {ok,[{string,1,[65,4095,66]}],1} = erl_scan:string(U2, 1),
+ {ok,[{string,1,[65,4095,66]}],1} = erl_scan_string(U2, 1),
U3 = "\"a\n\\x{fff}\n\"",
- {ok,[{string,1,[97,10,4095,10]}],3} = erl_scan:string(U3, 1),
+ {ok,[{string,1,[97,10,4095,10]}],3} = erl_scan_string(U3, 1),
U4 = "\"\\^\n\\x{aaa}\\^\n\"",
- {ok,[{string,1,[10,2730,10]}],3} = erl_scan:string(U4, 1,[]),
+ {ok,[{string,1,[10,2730,10]}],3} = erl_scan_string(U4, 1,[]),
Str1 = "\"ab" ++ [1089] ++ "cd\"",
{ok,[{string,1,[97,98,1089,99,100]}],1} =
- erl_scan:string(Str1,1),
+ erl_scan_string(Str1,1),
{ok,[{string,{1,1},[97,98,1089,99,100]}],{1,8}} =
- erl_scan:string(Str1, {1,1}),
+ erl_scan_string(Str1, {1,1}),
OK1 = 16#D800-1,
OK2 = 16#DFFF+1,
@@ -1038,19 +1051,19 @@ otp_10302(Config) when is_list(Config) ->
IllegalL = [Illegal1,Illegal2,Illegal3,Illegal4],
[{ok,[{comment,1,[$%,$%,$\s,OK]}],1} =
- erl_scan:string("%% "++[OK], 1, [return]) ||
+ erl_scan_string("%% "++[OK], 1, [return]) ||
OK <- OKL],
{ok,[{comment,_,[$%,$%,$\s,OK1]}],{1,5}} =
- erl_scan:string("%% "++[OK1], {1,1}, [return]),
+ erl_scan_string("%% "++[OK1], {1,1}, [return]),
[{error,{1,erl_scan,{illegal,character}},1} =
erl_scan:string("%% "++[Illegal], 1, [return]) ||
Illegal <- IllegalL],
{error,{{1,1},erl_scan,{illegal,character}},{1,5}} =
erl_scan:string("%% "++[Illegal1], {1,1}, [return]),
- [{ok,[],1} = erl_scan:string("%% "++[OK], 1, []) ||
+ [{ok,[],1} = erl_scan_string("%% "++[OK], 1, []) ||
OK <- OKL],
- {ok,[],{1,5}} = erl_scan:string("%% "++[OK1], {1,1}, []),
+ {ok,[],{1,5}} = erl_scan_string("%% "++[OK1], {1,1}, []),
[{error,{1,erl_scan,{illegal,character}},1} =
erl_scan:string("%% "++[Illegal], 1, []) ||
Illegal <- IllegalL],
@@ -1058,7 +1071,7 @@ otp_10302(Config) when is_list(Config) ->
erl_scan:string("%% "++[Illegal1], {1,1}, []),
[{ok,[{string,{1,1},[OK]}],{1,4}} =
- erl_scan:string("\""++[OK]++"\"",{1,1}) ||
+ erl_scan_string("\""++[OK]++"\"",{1,1}) ||
OK <- OKL],
[{error,{{1,2},erl_scan,{illegal,character}},{1,3}} =
erl_scan:string("\""++[OK]++"\"",{1,1}) ||
@@ -1069,93 +1082,93 @@ otp_10302(Config) when is_list(Config) ->
Illegal <- IllegalL],
{ok,[{char,{1,1},OK1}],{1,3}} =
- erl_scan:string([$$,OK1],{1,1}),
+ erl_scan_string([$$,OK1],{1,1}),
{error,{{1,1},erl_scan,{illegal,character}},{1,2}} =
erl_scan:string([$$,Illegal1],{1,1}),
{ok,[{char,{1,1},OK1}],{1,4}} =
- erl_scan:string([$$,$\\,OK1],{1,1}),
+ erl_scan_string([$$,$\\,OK1],{1,1}),
{error,{{1,1},erl_scan,{illegal,character}},{1,4}} =
erl_scan:string([$$,$\\,Illegal1],{1,1}),
{ok,[{string,{1,1},[55295]}],{1,5}} =
- erl_scan:string("\"\\"++[OK1]++"\"",{1,1}),
+ erl_scan_string("\"\\"++[OK1]++"\"",{1,1}),
{error,{{1,2},erl_scan,{illegal,character}},{1,4}} =
erl_scan:string("\"\\"++[Illegal1]++"\"",{1,1}),
{ok,[{char,{1,1},OK1}],{1,10}} =
- erl_scan:string("$\\x{D7FF}",{1,1}),
+ erl_scan_string("$\\x{D7FF}",{1,1}),
{error,{{1,1},erl_scan,{illegal,character}},{1,10}} =
erl_scan:string("$\\x{D800}",{1,1}),
%% Not erl_scan, but erl_parse.
- {integer,0,1} = erl_parse:abstract(1),
- Float = 3.14, {float,0,Float} = erl_parse:abstract(Float),
- {nil,0} = erl_parse:abstract([]),
+ {integer,0,1} = erl_parse_abstract(1),
+ Float = 3.14, {float,0,Float} = erl_parse_abstract(Float),
+ {nil,0} = erl_parse_abstract([]),
{bin,0,
[{bin_element,0,{integer,0,1},default,default},
{bin_element,0,{integer,0,2},default,default}]} =
- erl_parse:abstract(<<1,2>>),
+ erl_parse_abstract(<<1,2>>),
{cons,0,{tuple,0,[{atom,0,a}]},{atom,0,b}} =
- erl_parse:abstract([{a} | b]),
- {string,0,"str"} = erl_parse:abstract("str"),
+ erl_parse_abstract([{a} | b]),
+ {string,0,"str"} = erl_parse_abstract("str"),
{cons,0,
{integer,0,$a},
{cons,0,{integer,0,55296},{string,0,"c"}}} =
- erl_parse:abstract("a"++[55296]++"c"),
+ erl_parse_abstract("a"++[55296]++"c"),
Line = 17,
- {integer,Line,1} = erl_parse:abstract(1, Line),
- Float = 3.14, {float,Line,Float} = erl_parse:abstract(Float, Line),
- {nil,Line} = erl_parse:abstract([], Line),
+ {integer,Line,1} = erl_parse_abstract(1, Line),
+ Float = 3.14, {float,Line,Float} = erl_parse_abstract(Float, Line),
+ {nil,Line} = erl_parse_abstract([], Line),
{bin,Line,
[{bin_element,Line,{integer,Line,1},default,default},
{bin_element,Line,{integer,Line,2},default,default}]} =
- erl_parse:abstract(<<1,2>>, Line),
+ erl_parse_abstract(<<1,2>>, Line),
{cons,Line,{tuple,Line,[{atom,Line,a}]},{atom,Line,b}} =
- erl_parse:abstract([{a} | b], Line),
- {string,Line,"str"} = erl_parse:abstract("str", Line),
+ erl_parse_abstract([{a} | b], Line),
+ {string,Line,"str"} = erl_parse_abstract("str", Line),
{cons,Line,
{integer,Line,$a},
{cons,Line,{integer,Line,55296},{string,Line,"c"}}} =
- erl_parse:abstract("a"++[55296]++"c", Line),
+ erl_parse_abstract("a"++[55296]++"c", Line),
Opts1 = [{line,17}],
- {integer,Line,1} = erl_parse:abstract(1, Opts1),
- Float = 3.14, {float,Line,Float} = erl_parse:abstract(Float, Opts1),
- {nil,Line} = erl_parse:abstract([], Opts1),
+ {integer,Line,1} = erl_parse_abstract(1, Opts1),
+ Float = 3.14, {float,Line,Float} = erl_parse_abstract(Float, Opts1),
+ {nil,Line} = erl_parse_abstract([], Opts1),
{bin,Line,
[{bin_element,Line,{integer,Line,1},default,default},
{bin_element,Line,{integer,Line,2},default,default}]} =
- erl_parse:abstract(<<1,2>>, Opts1),
+ erl_parse_abstract(<<1,2>>, Opts1),
{cons,Line,{tuple,Line,[{atom,Line,a}]},{atom,Line,b}} =
- erl_parse:abstract([{a} | b], Opts1),
- {string,Line,"str"} = erl_parse:abstract("str", Opts1),
+ erl_parse_abstract([{a} | b], Opts1),
+ {string,Line,"str"} = erl_parse_abstract("str", Opts1),
{cons,Line,
{integer,Line,$a},
{cons,Line,{integer,Line,55296},{string,Line,"c"}}} =
- erl_parse:abstract("a"++[55296]++"c", Opts1),
+ erl_parse_abstract("a"++[55296]++"c", Opts1),
[begin
- {integer,Line,1} = erl_parse:abstract(1, Opts2),
- Float = 3.14, {float,Line,Float} = erl_parse:abstract(Float, Opts2),
- {nil,Line} = erl_parse:abstract([], Opts2),
+ {integer,Line,1} = erl_parse_abstract(1, Opts2),
+ Float = 3.14, {float,Line,Float} = erl_parse_abstract(Float, Opts2),
+ {nil,Line} = erl_parse_abstract([], Opts2),
{bin,Line,
[{bin_element,Line,{integer,Line,1},default,default},
{bin_element,Line,{integer,Line,2},default,default}]} =
- erl_parse:abstract(<<1,2>>, Opts2),
+ erl_parse_abstract(<<1,2>>, Opts2),
{cons,Line,{tuple,Line,[{atom,Line,a}]},{atom,Line,b}} =
- erl_parse:abstract([{a} | b], Opts2),
- {string,Line,"str"} = erl_parse:abstract("str", Opts2),
+ erl_parse_abstract([{a} | b], Opts2),
+ {string,Line,"str"} = erl_parse_abstract("str", Opts2),
{string,Line,[97,1024,99]} =
- erl_parse:abstract("a"++[1024]++"c", Opts2)
+ erl_parse_abstract("a"++[1024]++"c", Opts2)
end || Opts2 <- [[{encoding,unicode},{line,Line}],
[{encoding,utf8},{line,Line}]]],
{cons,0,
{integer,0,97},
{cons,0,{integer,0,1024},{string,0,"c"}}} =
- erl_parse:abstract("a"++[1024]++"c", [{encoding,latin1}]),
+ erl_parse_abstract("a"++[1024]++"c", [{encoding,latin1}]),
ok.
otp_10990(doc) ->
@@ -1172,13 +1185,13 @@ otp_10992(suite) ->
[];
otp_10992(Config) when is_list(Config) ->
{cons,0,{float,0,42.0},{nil,0}} =
- erl_parse:abstract([42.0], [{encoding,unicode}]),
+ erl_parse_abstract([42.0], [{encoding,unicode}]),
{cons,0,{float,0,42.0},{nil,0}} =
- erl_parse:abstract([42.0], [{encoding,utf8}]),
+ erl_parse_abstract([42.0], [{encoding,utf8}]),
{cons,0,{integer,0,65},{cons,0,{float,0,42.0},{nil,0}}} =
- erl_parse:abstract([$A,42.0], [{encoding,unicode}]),
+ erl_parse_abstract([$A,42.0], [{encoding,unicode}]),
{cons,0,{integer,0,65},{cons,0,{float,0,42.0},{nil,0}}} =
- erl_parse:abstract([$A,42.0], [{encoding,utf8}]),
+ erl_parse_abstract([$A,42.0], [{encoding,utf8}]),
ok.
otp_11807(doc) ->
@@ -1187,29 +1200,72 @@ otp_11807(suite) ->
[];
otp_11807(Config) when is_list(Config) ->
{cons,0,{integer,0,97},{cons,0,{integer,0,98},{nil,0}}} =
- erl_parse:abstract("ab", [{encoding,none}]),
+ erl_parse_abstract("ab", [{encoding,none}]),
{cons,0,{integer,0,-1},{nil,0}} =
- erl_parse:abstract([-1], [{encoding,latin1}]),
+ erl_parse_abstract([-1], [{encoding,latin1}]),
ASCII = fun(I) -> I >= 0 andalso I < 128 end,
- {string,0,"xyz"} = erl_parse:abstract("xyz", [{encoding,ASCII}]),
+ {string,0,"xyz"} = erl_parse_abstract("xyz", [{encoding,ASCII}]),
{cons,0,{integer,0,228},{nil,0}} =
- erl_parse:abstract([228], [{encoding,ASCII}]),
+ erl_parse_abstract([228], [{encoding,ASCII}]),
{cons,0,{integer,0,97},{atom,0,a}} =
- erl_parse:abstract("a"++a, [{encoding,latin1}]),
+ erl_parse_abstract("a"++a, [{encoding,latin1}]),
{'EXIT', {{badarg,bad},_}} = % minor backward incompatibility
(catch erl_parse:abstract("string", [{encoding,bad}])),
ok.
test_string(String, ExpectedWithCol) ->
- {ok, ExpectedWithCol, _EndWithCol} = erl_scan:string(String, {1, 1}, []),
+ {ok, ExpectedWithCol, _EndWithCol} = erl_scan_string(String, {1, 1}, []),
Expected = [ begin
{L,_C} = element(2, T),
setelement(2, T, L)
end
|| T <- ExpectedWithCol ],
- {ok, Expected, _End} = erl_scan:string(String),
+ {ok, Expected, _End} = erl_scan_string(String),
test(String).
+erl_scan_string(String) ->
+ erl_scan_string(String, 1, []).
+
+erl_scan_string(String, StartLocation) ->
+ erl_scan_string(String, StartLocation, []).
+
+erl_scan_string(String, StartLocation, Options) ->
+ case erl_scan:string(String, StartLocation, Options) of
+ {ok, Tokens, EndLocation} ->
+ {ok, unopaque_tokens(Tokens), EndLocation};
+ Else ->
+ Else
+ end.
+
+erl_scan_tokens(C, S, L) ->
+ erl_scan_tokens(C, S, L, []).
+
+erl_scan_tokens(C, S, L, O) ->
+ case erl_scan:tokens(C, S, L, O) of
+ {done, {ok, Ts, End}, R} ->
+ {done, {ok, unopaque_tokens(Ts), End}, R};
+ Else ->
+ Else
+ end.
+
+unopaque_tokens([]) ->
+ [];
+unopaque_tokens([Token|Tokens]) ->
+ Attrs = element(2, Token),
+ Term = erl_anno:to_term(Attrs),
+ T = setelement(2, Token, Term),
+ [T | unopaque_tokens(Tokens)].
+
+erl_parse_abstract(Term) ->
+ erl_parse_abstract(Term, []).
+
+erl_parse_abstract(Term, Options) ->
+ Abstr = erl_parse:abstract(Term, Options),
+ unopaque_abstract(Abstr).
+
+unopaque_abstract(Abstr) ->
+ erl_parse:anno_to_term(Abstr).
+
%% test_string(String, Expected, StartLocation, Options) ->
%% {ok, Expected, _End} = erl_scan:string(String, StartLocation, Options),
%% test(String).
@@ -1359,7 +1415,7 @@ select_tokens(Tokens, Tags) ->
simplify([Token|Tokens]) ->
{line,Line} = erl_scan:token_info(Token, line),
- [setelement(2, Token, Line) | simplify(Tokens)];
+ [setelement(2, Token, erl_anno:new(Line)) | simplify(Tokens)];
simplify([]) ->
[].
diff --git a/lib/stdlib/test/error_logger_forwarder.erl b/lib/stdlib/test/error_logger_forwarder.erl
index 5703ac769a..7ac2cfce82 100644
--- a/lib/stdlib/test/error_logger_forwarder.erl
+++ b/lib/stdlib/test/error_logger_forwarder.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/error_logger_h_SUITE.erl b/lib/stdlib/test/error_logger_h_SUITE.erl
new file mode 100644
index 0000000000..c82b1b62ef
--- /dev/null
+++ b/lib/stdlib/test/error_logger_h_SUITE.erl
@@ -0,0 +1,406 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(error_logger_h_SUITE).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([logfile/1,logfile_truncated/1,tty/1,tty_truncated/1]).
+
+%% Event handler exports.
+-export([init/1,handle_event/2,terminate/2]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [logfile,logfile_truncated,tty,tty_truncated].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+logfile(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LogDir = filename:join(PrivDir, ?MODULE),
+ Log = filename:join(LogDir, "logfile.log"),
+ ok = filelib:ensure_dir(Log),
+
+ Ev = event_templates(),
+
+ do_one_logfile(Log, Ev, unlimited),
+
+ Pa = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ {ok,Node} = start_node(logfile, Pa),
+ error_logger:logfile({open,Log}),
+ ok = rpc:call(Node, erlang, apply, [fun gen_events/1,[Ev]]),
+ AtNode = iolist_to_binary(["** at node ",atom_to_list(Node)," **"]),
+ error_logger:logfile(close),
+ analyse_events(Log, Ev, [AtNode], unlimited),
+
+ [] = [{X, file:pid2name(X)} || X <- processes(), Data <- [process_info(X, [current_function])],
+ Data =/= undefined,
+ element(1, element(2, lists:keyfind(current_function, 1, Data)))
+ =:= file_io_server,
+ file:pid2name(X) =:= {ok, Log}],
+
+ test_server:stop_node(Node),
+
+ cleanup(Log),
+ ok.
+
+logfile_truncated(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LogDir = filename:join(PrivDir, ?MODULE),
+ Log = filename:join(LogDir, "logfile_truncated.log"),
+ ok = filelib:ensure_dir(Log),
+
+ Ev = event_templates(),
+
+ Depth = 20,
+ application:set_env(kernel, error_logger_format_depth, Depth),
+ try
+ do_one_logfile(Log, Ev, Depth)
+ after
+ application:unset_env(kernel, error_logger_format_depth)
+ end,
+
+ cleanup(Log),
+ ok.
+
+do_one_logfile(Log, Ev, Depth) ->
+ error_logger:logfile({open,Log}),
+ gen_events(Ev),
+ error_logger:logfile(close),
+ analyse_events(Log, Ev, [], Depth).
+
+tty(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LogDir = filename:join(PrivDir, ?MODULE),
+ Log = filename:join(LogDir, "tty.log"),
+ ok = filelib:ensure_dir(Log),
+
+ Ev = event_templates(),
+
+ do_one_tty(Log, Ev, unlimited),
+
+ Pa = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ {ok,Node} = start_node(logfile, Pa),
+ tty_log_open(Log),
+ ok = rpc:call(Node, erlang, apply, [fun gen_events/1,[Ev]]),
+ tty_log_close(),
+ AtNode = iolist_to_binary(["** at node ",atom_to_list(Node)," **"]),
+ analyse_events(Log, Ev, [AtNode], unlimited),
+
+ test_server:stop_node(Node),
+
+ cleanup(Log),
+ ok.
+
+tty_truncated(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LogDir = filename:join(PrivDir, ?MODULE),
+ Log = filename:join(LogDir, "tty_truncated.log"),
+ ok = filelib:ensure_dir(Log),
+
+ Ev = event_templates(),
+
+ Depth = 20,
+ application:set_env(kernel, error_logger_format_depth, Depth),
+ try
+ do_one_tty(Log, Ev, Depth)
+ after
+ application:unset_env(kernel, error_logger_format_depth)
+ end,
+
+ cleanup(Log),
+ ok.
+
+do_one_tty(Log, Ev, Depth) ->
+ tty_log_open(Log),
+ gen_events(Ev),
+ tty_log_close(),
+ analyse_events(Log, Ev, [], Depth).
+
+tty_log_open(Log) ->
+ {ok,Fd} = file:open(Log, [write]),
+ Depth = case application:get_env(kernel, error_logger_format_depth) of
+ {ok,D} -> D;
+ _ -> unlimited
+ end,
+ error_logger:add_report_handler(?MODULE, {Fd,Depth}),
+ Fd.
+
+tty_log_close() ->
+ error_logger:delete_report_handler(?MODULE),
+ ok.
+
+event_templates() ->
+ [{error_msg,["Pure error string\n",[]]},
+ {error_msg,["Pure error string with error ~p\n",[]]},
+ {error_msg,["Error string with ~p\n", [format]]},
+ {error_msg,["Error string with bad format ~p\n", []]},
+
+ {error_report,[error_atom]},
+ {error_report,["error string"]},
+ {error_report,[[{error_tag,value},error_value]]},
+
+ {info_msg,["Pure info string\n",[]]},
+ {info_msg,["Pure info string with error ~p\n",[]]},
+ {info_msg,["Pure string with ~p\n", [format]]},
+ {info_msg,["Pure string with bad format ~p\n", []]},
+
+ {info_report,[info_atom]},
+ {info_report,["info string"]},
+ {info_report,[[{info_tag,value},info_value]]},
+
+ {warning_msg,["Pure warning string\n",[]]},
+ {warning_msg,["Pure warning string with error ~p\n",[]]},
+ {warning_msg,["Warning string with ~p\n", [format]]},
+ {warning_msg,["Warning string with bad format ~p\n", []]},
+
+ {warning_report,[warning_atom]},
+ {warning_report,["warning string"]},
+ {warning_report,[[{warning_tag,value},warning_value]]},
+
+ %% Bigger terms.
+ {error_msg,["fairly big: ~p\n",[lists:seq(1, 128)]]},
+ {error_report,[list_to_tuple(lists:seq(1, 100))]},
+ {error_report,[lists:seq(32, 126)]},
+ {error_report,[[{tag,lists:seq(1, 64)}]]}
+ ].
+
+gen_events(Ev) ->
+ io:format("node = ~p\n", [node()]),
+ io:format("group leader = ~p\n", [group_leader()]),
+ io:format("~p\n", [gen_event:which_handlers(error_logger)]),
+ call_error_logger(Ev),
+
+ {Pid,Ref} = spawn_monitor(fun() -> error(ouch) end),
+ receive
+ {'DOWN',Ref,process,Pid,_} ->
+ ok
+ end,
+
+ %% The following calls with a custom type will be ignored.
+ error_logger:error_report(ignored, value),
+ error_logger:warning_report(ignored, value),
+ error_logger:info_report(ignored, value),
+ receive after 100 -> ok end,
+ ok.
+
+analyse_events(Log, Ev, AtNode, Depth) ->
+ {ok,Bin} = file:read_file(Log),
+
+ io:format("*** Contents of log file ***\n\n~s\n", [Bin]),
+
+ Lines = binary:split(Bin, <<"\n">>, [global,trim_all]),
+ io:format("~p\n", [Lines]),
+
+ Rest = match_output(Ev, Lines, AtNode, Depth),
+ io:format("~p\n", [Rest]),
+
+ [] = match_emulator_error(Rest),
+ ok.
+
+
+call_error_logger([{F,Args}|T]) ->
+ apply(error_logger, F, Args),
+ call_error_logger(T);
+call_error_logger([]) -> ok.
+
+
+match_emulator_error([Head,Second,Third,_|Lines]) ->
+ match_head(<<"ERROR">>, Head),
+ {match,[{0,_}]} = re:run(Second,
+ "^Error in process <\\d+[.]\\d+[.]\\d+> on "
+ "node [^ ]* with exit value:"),
+ {match,[{0,_}]} = re:run(Third, "^[{]ouch,"),
+ Lines.
+
+match_output([Item|T], Lines0, AtNode, Depth) ->
+ try match_item(Item, Lines0, AtNode, Depth) of
+ Lines ->
+ match_output(T, Lines, AtNode, Depth)
+ catch
+ C:E ->
+ Stk = erlang:get_stacktrace(),
+ io:format("ITEM: ~p", [Item]),
+ io:format("LINES: ~p", [Lines0]),
+ erlang:raise(C, E, Stk)
+ end;
+match_output([], Lines, _, _) -> Lines.
+
+match_item(Item, Lines, AtNode, Depth) ->
+ case item_type(Item) of
+ {msg,Head,Args} ->
+ match_format(Head, Args, Lines, AtNode, Depth);
+ {report,Head,Args} ->
+ match_term(Head, Args, Lines, AtNode, Depth)
+ end.
+
+item_type({error_msg,Args}) ->
+ {msg,<<"ERROR">>,Args};
+item_type({info_msg,Args}) ->
+ {msg,<<"INFO">>,Args};
+item_type({warning_msg,Args}) ->
+ {msg,<<"WARNING">>,Args};
+item_type({error_report,Args}) ->
+ {report,<<"ERROR">>,Args};
+item_type({info_report,Args}) ->
+ {report,<<"INFO">>,Args};
+item_type({warning_report,Args}) ->
+ {report,<<"WARNING">>,Args}.
+
+match_format(Tag, [Format,Args], [Head|Lines], AtNode, Depth) ->
+ match_head(Tag, Head),
+ Bin = try dl_format(Depth, Format, Args) of
+ Str ->
+ iolist_to_binary(Str)
+ catch
+ _:_ ->
+ S = dl_format(Depth, "ERROR: ~p - ~p~n", [Format,Args]),
+ iolist_to_binary(S)
+ end,
+ Expected0 = binary:split(Bin, <<"\n">>, [global,trim]),
+ Expected = Expected0 ++ AtNode,
+ 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,
+ match_term_lines(Expected, Lines).
+
+match_term_get_expected(List, Depth) when is_list(List) ->
+ Bin = try iolist_to_binary(dl_format(Depth, "~s\n", [List])) of
+ Bin0 -> Bin0
+ catch
+ _:_ ->
+ iolist_to_binary(format_rep(List, Depth))
+ end,
+ binary:split(Bin, <<"\n">>, [global,trim]);
+match_term_get_expected(Term, Depth) ->
+ S = dl_format(Depth, "~p\n", [Term]),
+ Bin = iolist_to_binary(S),
+ binary:split(Bin, <<"\n">>, [global,trim]).
+
+format_rep([{Tag,Data}|Rep], Depth) ->
+ [dl_format(Depth, " ~p: ~p\n", [Tag,Data])|
+ format_rep(Rep, Depth)];
+format_rep([Other|Rep], Depth) ->
+ [dl_format(Depth, " ~p\n", [Other])|
+ format_rep(Rep, Depth)];
+format_rep([], _Depth) -> [].
+
+match_term_lines([Line|T], [Line|Lines]) ->
+ match_term_lines(T, Lines);
+match_term_lines([], Lines) -> Lines.
+
+match_head(Tag, Head) ->
+ Re = <<"^=",Tag/binary,
+ " REPORT==== \\d\\d?-[A-Z][a-z][a-z]-\\d{4}::"
+ "\\d\\d:\\d\\d:\\d\\d ===$">>,
+ {match,_} = re:run(Head, Re).
+
+start_node(Name, Args) ->
+ case test_server:start_node(Name, slave, [{args,Args}]) of
+ {ok,Node} ->
+ {ok,Node};
+ Error ->
+ test_server:fail(Error)
+ end.
+
+cleanup(File) ->
+ %% The point of this test case is not to test file operations.
+ %% Therefore ignore any failures.
+ case file:delete(File) of
+ ok ->
+ ok;
+ {error,Error1} ->
+ io:format("file:delete(~s) failed with error ~p",
+ [File,Error1])
+ end,
+ Dir = filename:dirname(File),
+ case file:del_dir(Dir) of
+ ok ->
+ ok;
+ {error,Error2} ->
+ io:format("file:del_dir(~s) failed with error ~p",
+ [Dir,Error2])
+ end,
+ ok.
+
+
+%% Depth-limited io_lib:format. Intentionally implemented here instead
+%% of using io_lib:scan_format/2 to avoid using the same implementation
+%% as in the error_logger handlers.
+
+dl_format(unlimited, Format, Args) ->
+ io_lib:format(Format, Args);
+dl_format(Depth, Format0, Args0) ->
+ {Format,Args} = dl_format_1(Format0, Args0, Depth, [], []),
+ io_lib:format(Format, Args).
+
+dl_format_1("~p"++Fs, [A|As], Depth, Facc, Acc) ->
+ dl_format_1(Fs, As, Depth, [$P,$~|Facc], [Depth,A|Acc]);
+dl_format_1("~w"++Fs, [A|As], Depth, Facc, Acc) ->
+ dl_format_1(Fs, As, Depth, [$W,$~|Facc], [Depth,A|Acc]);
+dl_format_1("~s"++Fs, [A|As], Depth, Facc, Acc) ->
+ dl_format_1(Fs, As, Depth, [$s,$~|Facc], [A|Acc]);
+dl_format_1([F|Fs], As, Depth, Facc, Aacc) ->
+ dl_format_1(Fs, As, Depth, [F|Facc], Aacc);
+dl_format_1([], [], _, Facc, Aacc) ->
+ {lists:reverse(Facc),lists:reverse(Aacc)}.
+
+%%%
+%%% Our own event handler. There is no way to intercept the output
+%%% from error_logger_tty_h, but we can use the same code by
+%%% calling error_logger_tty_h:write_event/2.
+%%%
+
+init({_,_}=St) ->
+ {ok,St}.
+
+handle_event(Event, {Fd,Depth}=St) ->
+ case error_logger_tty_h:write_event(tag_event(Event), io_lib, Depth) of
+ ok ->
+ ok;
+ Str when is_list(Str) ->
+ io:put_chars(Fd, Str)
+ end,
+ {ok,St}.
+
+terminate(_Reason, {Fd,_}) ->
+ ok = file:close(Fd),
+ [].
+
+tag_event(Event) ->
+ {erlang:universaltime(),Event}.
diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl
index eebfec3336..87ff6a68ff 100644
--- a/lib/stdlib/test/escript_SUITE.erl
+++ b/lib/stdlib/test/escript_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict.erl
index a614817b04..40758e3258 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_app.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_app.erl
index 09b22ea532..a5bb5fa077 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_app.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_sup.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_sup.erl
index 9a6c088552..8ed41a27ce 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_sup.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dict/src/archive_script_dict_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy.erl
index 7c19ebf82f..a6685e8189 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_app.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_app.erl
index c0910d379e..bbfdda7741 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_app.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_sup.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_sup.erl
index 8dff5c9335..389d485f6d 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_sup.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_dummy/src/archive_script_dummy_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main.erl
index d257744cd7..5ea114f25d 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main2.erl b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main2.erl
index 1cddef0e3d..6270a6bb60 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main2.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script/archive_script_main2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl b/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl
index 523621e4f3..6c3ff1c463 100644
--- a/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl
+++ b/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 8dc8b2c291..30a158d9e1 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -47,6 +48,7 @@
-export([ordered/1, ordered_match/1, interface_equality/1,
fixtable_next/1, fixtable_insert/1, rename/1, rename_unnamed/1, evil_rename/1,
update_element/1, update_counter/1, evil_update_counter/1, partly_bound/1, match_heavy/1]).
+-export([update_counter_with_default/1]).
-export([member/1]).
-export([memory/1]).
-export([select_fail/1]).
@@ -77,6 +79,7 @@
-export([otp_10182/1]).
-export([ets_all/1]).
-export([memory_check_summary/1]).
+-export([take/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Convenience for manual testing
@@ -98,7 +101,7 @@
misc1_do/1, safe_fixtable_do/1, info_do/1, dups_do/1, heavy_lookup_do/1,
heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1,
do_heavy_concurrent/1, tab2file2_do/2, exit_large_table_owner_do/2,
- types_do/1, sleeper/0, memory_do/1,
+ types_do/1, sleeper/0, memory_do/1, update_counter_with_default_do/1,
ms_tracee_dummy/1, ms_tracee_dummy/2, ms_tracee_dummy/3, ms_tracee_dummy/4
]).
@@ -115,6 +118,7 @@ init_per_testcase(Case, Config) ->
start_spawn_logger(),
wait_for_test_procs(), %% Ensure previous case cleaned up
Dog=test_server:timetrap(test_server:minutes(20)),
+ put('__ETS_TEST_CASE__', Case),
[{watchdog, Dog}, {test_case, Case} | Config].
end_per_testcase(_Func, Config) ->
@@ -135,7 +139,8 @@ all() ->
{group, heavy}, ordered, ordered_match,
interface_equality, fixtable_next, fixtable_insert,
rename, rename_unnamed, evil_rename, update_element,
- update_counter, evil_update_counter, partly_bound,
+ update_counter, evil_update_counter,
+ update_counter_with_default, partly_bound,
match_heavy, {group, fold}, member, t_delete_object,
t_init_table, t_whitebox, t_delete_all_objects,
t_insert_list, t_test_ms, t_select_delete, t_ets_dets,
@@ -153,6 +158,7 @@ all() ->
otp_9932,
otp_9423,
ets_all,
+ take,
memory_check_summary]. % MUST BE LAST
@@ -212,8 +218,9 @@ memory_check_summary(_Config) ->
ets_test_spawn_logger ! {self(), get_failed_memchecks},
receive {get_failed_memchecks, FailedMemchecks} -> ok end,
io:format("Failed memchecks: ~p\n",[FailedMemchecks]),
- if FailedMemchecks > 3 ->
- ct:fail("Too many failed (~p) memchecks", [FailedMemchecks]);
+ NoFailedMemchecks = length(FailedMemchecks),
+ if NoFailedMemchecks > 3 ->
+ ct:fail("Too many failed (~p) memchecks", [NoFailedMemchecks]);
true ->
ok
end
@@ -1381,7 +1388,7 @@ random_test() ->
{ok,[X]} ->
X;
_ ->
- {A,B,C} = erlang:now(),
+ {A,B,C} = erlang:timestamp(),
random:seed(A,B,C),
get(random_seed)
end,
@@ -1759,6 +1766,14 @@ update_counter_do(Opts) ->
OrdSet = ets_new(ordered_set,[ordered_set | Opts]),
update_counter_for(Set),
update_counter_for(OrdSet),
+ ets:delete_all_objects(Set),
+ ets:delete_all_objects(OrdSet),
+ ets:safe_fixtable(Set, true),
+ ets:safe_fixtable(OrdSet, true),
+ update_counter_for(Set),
+ update_counter_for(OrdSet),
+ ets:safe_fixtable(Set, false),
+ ets:safe_fixtable(OrdSet, false),
ets:delete(Set),
ets:delete(OrdSet),
update_counter_neg(Opts).
@@ -1778,10 +1793,14 @@ update_counter_for(T) ->
?line {NewObj, Ret} = uc_mimic(Obj,Arg3),
ArgHash = erlang:phash2({T,a,Arg3}),
%%io:format("update_counter(~p, ~p, ~p) expecting ~p\n",[T,a,Arg3,Ret]),
+ [DefaultObj] = ets:lookup(T, a),
?line Ret = ets:update_counter(T,a,Arg3),
+ Ret = ets:update_counter(T, b, Arg3, DefaultObj), % Use other key
?line ArgHash = erlang:phash2({T,a,Arg3}),
%%io:format("NewObj=~p~n ",[NewObj]),
?line [NewObj] = ets:lookup(T,a),
+ true = ets:lookup(T, b) =:= [setelement(1, NewObj, b)],
+ ets:delete(T, b),
Myself(NewObj,Times-1,Arg3,Myself)
end,
@@ -2006,6 +2025,44 @@ evil_counter_1(Iter, T) ->
ets:update_counter(T, dracula, 1),
evil_counter_1(Iter-1, T).
+update_counter_with_default(Config) when is_list(Config) ->
+ repeat_for_opts(update_counter_with_default_do).
+
+update_counter_with_default_do(Opts) ->
+ T1 = ets_new(a, [set | Opts]),
+ %% Insert default object.
+ 3 = ets:update_counter(T1, foo, 2, {beaufort,1}),
+ %% Increment.
+ 5 = ets:update_counter(T1, foo, 2, {cabecou,1}),
+ %% Increment with list.
+ [9] = ets:update_counter(T1, foo, [{2,4}], {camembert,1}),
+ %% Same with non-immediate key.
+ 3 = ets:update_counter(T1, {foo,bar}, 2, {{chaource,chevrotin},1}),
+ 5 = ets:update_counter(T1, {foo,bar}, 2, {{cantal,comté},1}),
+ [9] = ets:update_counter(T1, {foo,bar}, [{2,4}], {{emmental,de,savoie},1}),
+ %% Same with ordered set.
+ T2 = ets_new(b, [ordered_set | Opts]),
+ 3 = ets:update_counter(T2, foo, 2, {maroilles,1}),
+ 5 = ets:update_counter(T2, foo, 2, {mimolette,1}),
+ [9] = ets:update_counter(T2, foo, [{2,4}], {morbier,1}),
+ 3 = ets:update_counter(T2, {foo,bar}, 2, {{laguiole},1}),
+ 5 = ets:update_counter(T2, {foo,bar}, 2, {{saint,nectaire},1}),
+ [9] = ets:update_counter(T2, {foo,bar}, [{2,4}], {{rocamadour},1}),
+ %% Arithmetically-equal keys.
+ 3 = ets:update_counter(T2, 1.0, 2, {1,1}),
+ 5 = ets:update_counter(T2, 1, 2, {1,1}),
+ 7 = ets:update_counter(T2, 1, 2, {1.0,1}),
+ %% Same with reversed type difference.
+ 3 = ets:update_counter(T2, 2, 2, {2.0,1}),
+ 5 = ets:update_counter(T2, 2.0, 2, {2.0,1}),
+ 7 = ets:update_counter(T2, 2.0, 2, {2,1}),
+ %% bar is not an integer.
+ {'EXIT',{badarg,_}} = (catch ets:update_counter(T1, qux, 3, {saint,félicien})),
+ %% No third element in default value.
+ {'EXIT',{badarg,_}} = (catch ets:update_counter(T1, qux, [{3,1}], {roquefort,1})),
+
+ ok.
+
fixtable_next(doc) ->
["Check that a first-next sequence always works on a fixed table"];
fixtable_next(suite) ->
@@ -3007,13 +3064,13 @@ time_lookup(Config) when is_list(Config) ->
"~p ets lookups/s",[Values]))}.
time_lookup_do(Opts) ->
- ?line Tab = ets_new(foo,Opts),
- ?line fill_tab(Tab,foo),
- ?line ets:insert(Tab,{{a,key},foo}),
- ?line {Time,_} = ?t:timecall(test_server,do_times,
- [10000,ets,lookup,[Tab,{a,key}]]),
- ?line true = ets:delete(Tab),
- round(10000 / Time). % lookups/s
+ Tab = ets_new(foo,Opts),
+ fill_tab(Tab,foo),
+ ets:insert(Tab,{{a,key},foo}),
+ {Time,_} = ?t:timecall(test_server,do_times,
+ [100000,ets,lookup,[Tab,{a,key}]]),
+ true = ets:delete(Tab),
+ round(100000 / Time). % lookups/s
badlookup(doc) ->
["Check proper return values from bad lookups in existing/non existing "
@@ -3487,12 +3544,9 @@ verify_rescheduling_exit(Config, ForEachData, Flags, Fix, NOTabs, NOProcs) ->
fun () ->
repeat(
fun () ->
- {A, B, C} = now(),
- ?line Name = list_to_atom(
- TestCase
- ++ "-" ++ integer_to_list(A)
- ++ "-" ++ integer_to_list(B)
- ++ "-" ++ integer_to_list(C)),
+ Uniq = erlang:unique_integer([positive]),
+ Name = list_to_atom(TestCase ++ "-" ++
+ integer_to_list(Uniq)),
Tab = ets_new(Name, Flags),
ForEachData(fun(Data) -> ets:insert(Tab, Data) end),
case Fix of
@@ -3770,41 +3824,99 @@ match_object(Config) when is_list(Config) ->
repeat_for_opts(match_object_do).
match_object_do(Opts) ->
- ?line EtsMem = etsmem(),
- ?line Tab = ets_new(foobar, Opts),
- ?line fill_tab(Tab, foo),
- ?line ets:insert(Tab, {{one, 4}, 4}),
- ?line ets:insert(Tab,{{one,5},5}),
- ?line ets:insert(Tab,{{two,4},4}),
- ?line ets:insert(Tab,{{two,5},6}),
- ?line case ets:match_object(Tab, {{one, '_'}, '$0'}) of
+ EtsMem = etsmem(),
+ Tab = ets_new(foobar, Opts),
+ fill_tab(Tab, foo),
+ ets:insert(Tab,{{one,4},4}),
+ ets:insert(Tab,{{one,5},5}),
+ ets:insert(Tab,{{two,4},4}),
+ ets:insert(Tab,{{two,5},6}),
+ ets:insert(Tab, {#{camembert=>cabécou},7}),
+ ets:insert(Tab, {#{"hi"=>"hello","wazzup"=>"awesome","1337"=>"42"},8}),
+ ets:insert(Tab, {#{"hi"=>"hello",#{"wazzup"=>3}=>"awesome","1337"=>"42"},9}),
+ ets:insert(Tab, {#{"hi"=>"hello","wazzup"=>#{"awesome"=>3},"1337"=>"42"},10}),
+ Is = lists:seq(1,100),
+ M1 = maps:from_list([{I,I}||I <- Is]),
+ M2 = maps:from_list([{I,"hi"}||I <- Is]),
+ ets:insert(Tab, {M1,11}),
+ ets:insert(Tab, {M2,12}),
+
+ case ets:match_object(Tab, {{one, '_'}, '$0'}) of
[{{one,5},5},{{one,4},4}] -> ok;
[{{one,4},4},{{one,5},5}] -> ok;
_ -> ?t:fail("ets:match_object() returned something funny.")
end,
- ?line case ets:match_object(Tab, {{two, '$1'}, '$0'}) of
+ case ets:match_object(Tab, {{two, '$1'}, '$0'}) of
[{{two,5},6},{{two,4},4}] -> ok;
[{{two,4},4},{{two,5},6}] -> ok;
_ -> ?t:fail("ets:match_object() returned something funny.")
end,
- ?line case ets:match_object(Tab, {{two, '$9'}, '$4'}) of
+ case ets:match_object(Tab, {{two, '$9'}, '$4'}) of
[{{two,5},6},{{two,4},4}] -> ok;
[{{two,4},4},{{two,5},6}] -> ok;
_ -> ?t:fail("ets:match_object() returned something funny.")
end,
- ?line case ets:match_object(Tab, {{two, '$9'}, '$22'}) of
+ case ets:match_object(Tab, {{two, '$9'}, '$22'}) of
[{{two,5},6},{{two,4},4}] -> ok;
[{{two,4},4},{{two,5},6}] -> ok;
_ -> ?t:fail("ets:match_object() returned something funny.")
end,
- % Check that unsucessful match returns an empty list.
- ?line [] = ets:match_object(Tab, {{three,'$0'}, '$92'}),
+
+ % Check that maps are inspected for variables.
+ [{#{camembert:=cabécou},7}] = ets:match_object(Tab, {#{camembert=>'_'},7}),
+
+ [{#{"hi":="hello",#{"wazzup"=>3}:="awesome","1337":="42"},9}] =
+ ets:match_object(Tab, {#{#{"wazzup"=>3}=>"awesome","hi"=>"hello","1337"=>"42"},9}),
+ [{#{"hi":="hello",#{"wazzup"=>3}:="awesome","1337":="42"},9}] =
+ ets:match_object(Tab, {#{#{"wazzup"=>3}=>"awesome","hi"=>"hello","1337"=>'_'},'_'}),
+ [{#{"hi":="hello","wazzup":=#{"awesome":=3},"1337":="42"},10}] =
+ ets:match_object(Tab, {#{"wazzup"=>'_',"hi"=>'_',"1337"=>'_'},10}),
+
+ %% multiple patterns
+ Pat = {{#{#{"wazzup"=>3}=>"awesome","hi"=>"hello","1337"=>'_'},'$1'},[{is_integer,'$1'}],['$_']},
+ [{#{"hi":="hello",#{"wazzup"=>3}:="awesome","1337":="42"},9}] =
+ ets:select(Tab, [Pat,Pat,Pat,Pat]),
+ case ets:match_object(Tab, {#{"hi"=>"hello","wazzup"=>'_',"1337"=>"42"},'_'}) of
+ [{#{"1337" := "42","hi" := "hello","wazzup" := "awesome"},8},
+ {#{"1337" := "42","hi" := "hello","wazzup" := #{"awesome" := 3}},10}] -> ok;
+ [{#{"1337" := "42","hi" := "hello","wazzup" := #{"awesome" := 3}},10},
+ {#{"1337" := "42","hi" := "hello","wazzup" := "awesome"},8}] -> ok;
+ _ -> ?t:fail("ets:match_object() returned something funny.")
+ end,
+ case ets:match_object(Tab, {#{"hi"=>'_'},'_'}) of
+ [{#{"1337":="42", "hi":="hello"},_},
+ {#{"1337":="42", "hi":="hello"},_},
+ {#{"1337":="42", "hi":="hello"},_}] -> ok;
+ _ -> ?t:fail("ets:match_object() returned something funny.")
+ end,
+
+ %% match large maps
+ [{#{1:=1,2:=2,99:=99,100:=100},11}] = ets:match_object(Tab, {M1,11}),
+ [{#{1:="hi",2:="hi",99:="hi",100:="hi"},12}] = ets:match_object(Tab, {M2,12}),
+ case ets:match_object(Tab, {#{1=>'_',2=>'_'},'_'}) of
+ %% only match a part of the map
+ [{#{1:=1,5:=5,99:=99,100:=100},11},{#{1:="hi",6:="hi",99:="hi"},12}] -> ok;
+ [{#{1:="hi",2:="hi",59:="hi"},12},{#{1:=1,2:=2,39:=39,100:=100},11}] -> ok;
+ _ -> ?t:fail("ets:match_object() returned something funny.")
+ end,
+ case ets:match_object(Tab, {maps:from_list([{I,'_'}||I<-Is]),'_'}) of
+ %% only match a part of the map
+ [{#{1:=1,5:=5,99:=99,100:=100},11},{#{1:="hi",6:="hi",99:="hi"},12}] -> ok;
+ [{#{1:="hi",2:="hi",59:="hi"},12},{#{1:=1,2:=2,39:=39,100:=100},11}] -> ok;
+ _ -> ?t:fail("ets:match_object() returned something funny.")
+ end,
+ {'EXIT',{badarg,_}} = (catch ets:match_object(Tab, {#{'$1'=>'_'},7})),
+ Mve = maps:from_list([{list_to_atom([$$|integer_to_list(I)]),'_'}||I<-Is]),
+ {'EXIT',{badarg,_}} = (catch ets:match_object(Tab, {Mve,11})),
+
+ % Check that unsuccessful match returns an empty list.
+ [] = ets:match_object(Tab, {{three,'$0'}, '$92'}),
% Check that '$0' equals '_'.
Len = length(ets:match_object(Tab, '$0')),
Len = length(ets:match_object(Tab, '_')),
- ?line if Len > 4 -> ok end,
- ?line true = ets:delete(Tab),
- ?line verify_etsmem(EtsMem).
+ if Len > 4 -> ok end,
+ true = ets:delete(Tab),
+ verify_etsmem(EtsMem).
match_object2(suite) -> [];
match_object2(doc) -> ["Tests that db_match_object does not generate "
@@ -3877,15 +3989,37 @@ safe_fixtable_do(Opts) ->
?line true = ets:safe_fixtable(Tab, true),
?line receive after 1 -> ok end,
?line true = ets:safe_fixtable(Tab, false),
- ?line false = ets:info(Tab,safe_fixed),
- ?line true = ets:safe_fixtable(Tab, true),
+ false = ets:info(Tab,safe_fixed_monotonic_time),
+ false = ets:info(Tab,safe_fixed),
+ SysBefore = erlang:timestamp(),
+ MonBefore = erlang:monotonic_time(),
+ true = ets:safe_fixtable(Tab, true),
+ MonAfter = erlang:monotonic_time(),
+ SysAfter = erlang:timestamp(),
Self = self(),
- ?line {{_,_,_},[{Self,1}]} = ets:info(Tab,safe_fixed),
+ {FixMonTime,[{Self,1}]} = ets:info(Tab,safe_fixed_monotonic_time),
+ {FixSysTime,[{Self,1}]} = ets:info(Tab,safe_fixed),
+ true = is_integer(FixMonTime),
+ true = MonBefore =< FixMonTime,
+ true = FixMonTime =< MonAfter,
+ {FstMs,FstS,FstUs} = FixSysTime,
+ true = is_integer(FstMs),
+ true = is_integer(FstS),
+ true = is_integer(FstUs),
+ case erlang:system_info(time_warp_mode) of
+ no_time_warp ->
+ true = timer:now_diff(FixSysTime, SysBefore) >= 0,
+ true = timer:now_diff(SysAfter, FixSysTime) >= 0;
+ _ ->
+ %% ets:info(Tab,safe_fixed) not timewarp safe...
+ ignore
+ end,
%% Test that an unjustified 'unfix' is a no-op.
{Pid,MRef} = my_spawn_monitor(fun() -> true = ets:safe_fixtable(Tab,false) end),
{'DOWN', MRef, process, Pid, normal} = receive M -> M end,
- ?line true = ets:info(Tab,fixed),
- ?line {{_,_,_},[{Self,1}]} = ets:info(Tab,safe_fixed),
+ true = ets:info(Tab,fixed),
+ {FixMonTime,[{Self,1}]} = ets:info(Tab,safe_fixed_monotonic_time),
+ {FixSysTime,[{Self,1}]} = ets:info(Tab,safe_fixed),
%% badarg's
?line {'EXIT', {badarg, _}} = (catch ets:safe_fixtable(Tab, foobar)),
?line true = ets:info(Tab,fixed),
@@ -3931,6 +4065,7 @@ info_do(Opts) ->
?line undefined = ets:info(non_existing_table_xxyy,type),
?line undefined = ets:info(non_existing_table_xxyy,node),
?line undefined = ets:info(non_existing_table_xxyy,named_table),
+ ?line undefined = ets:info(non_existing_table_xxyy,safe_fixed_monotonic_time),
?line undefined = ets:info(non_existing_table_xxyy,safe_fixed),
?line verify_etsmem(EtsMem).
@@ -3969,21 +4104,39 @@ tab2file(doc) -> ["Check the ets:tab2file function on an empty "
"ets table."];
tab2file(suite) -> [];
tab2file(Config) when is_list(Config) ->
- %% Write an empty ets table to a file, read back and check properties.
- ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, set, private,
- {keypos, 2}]),
?line FName = filename:join([?config(priv_dir, Config),"tab2file_case"]),
- ?line ok = ets:tab2file(Tab, FName),
- ?line true = ets:delete(Tab),
+ tab2file_do(FName, []),
+ tab2file_do(FName, [{sync,true}]),
+ tab2file_do(FName, [{sync,false}]),
+ {'EXIT',{{badmatch,{error,_}},_}} = (catch tab2file_do(FName, [{sync,yes}])),
+ {'EXIT',{{badmatch,{error,_}},_}} = (catch tab2file_do(FName, [sync])),
+ ok.
+
+tab2file_do(FName, Opts) ->
+ %% Write an empty ets table to a file, read back and check properties.
+ ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, set, public,
+ {keypos, 2},
+ compressed,
+ {write_concurrency,true},
+ {read_concurrency,true}]),
+ catch file:delete(FName),
+ Res = ets:tab2file(Tab, FName, Opts),
+ true = ets:delete(Tab),
+ ok = Res,
%
?line EtsMem = etsmem(),
?line {ok, Tab2} = ets:file2tab(FName),
- ?line private = ets:info(Tab2, protection),
+ public = ets:info(Tab2, protection),
?line true = ets:info(Tab2, named_table),
?line 2 = ets:info(Tab2, keypos),
?line set = ets:info(Tab2, type),
+ true = ets:info(Tab2, compressed),
+ Smp = erlang:system_info(smp_support),
+ Smp = ets:info(Tab2, read_concurrency),
+ Smp = ets:info(Tab2, write_concurrency),
?line true = ets:delete(Tab2),
?line verify_etsmem(EtsMem).
+
tab2file2(doc) -> ["Check the ets:tab2file function on a ",
"filled set/bag type ets table."];
@@ -4199,7 +4352,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(400,500) ],
+ end || N <- lists:seq(500,600) ],
io:format("~p~n",[Res]),
file:delete(FName),
ok.
@@ -4493,16 +4646,16 @@ build_table2(L1,L2,Num) ->
T.
time_match_object(Tab,Match, Res) ->
- T1 = erlang:now(),
+ T1 = erlang:monotonic_time(micro_seconds),
Res = ets:match_object(Tab,Match),
- T2 = erlang:now(),
- nowdiff(T1,T2).
+ T2 = erlang:monotonic_time(micro_seconds),
+ T2 - T1.
time_match(Tab,Match) ->
- T1 = erlang:now(),
+ T1 = erlang:monotonic_time(micro_seconds),
ets:match(Tab,Match),
- T2 = erlang:now(),
- nowdiff(T1,T2).
+ T2 = erlang:monotonic_time(micro_seconds),
+ T2 - T1.
seventyfive_percent_success(_,S,Fa,0) ->
true = (S > ((S + Fa) * 0.75));
@@ -4527,11 +4680,6 @@ fifty_percent_success({M,F,A},S,Fa,N) ->
end.
-nowtonumber({Mega, Secs, Milli}) ->
- Milli + Secs * 1000000 + Mega * 1000000000000.
-nowdiff(T1,T2) ->
- nowtonumber(T2) - nowtonumber(T1).
-
create_random_string(0) ->
[];
@@ -5000,36 +5148,40 @@ colliding_names(Name) ->
grow_shrink(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
- ?line grow_shrink_0(lists:seq(3071, 5000), EtsMem),
- ?line verify_etsmem(EtsMem).
-grow_shrink_0([N|Ns], EtsMem) ->
- ?line grow_shrink_1(N, [set]),
- ?line grow_shrink_1(N, [ordered_set]),
- %% Verifying ets-memory here takes too long time, since
- %% lock-free allocators were introduced...
- %% ?line verify_etsmem(EtsMem),
- grow_shrink_0(Ns, EtsMem);
-grow_shrink_0([], _) -> ok.
-
-grow_shrink_1(N, Flags) ->
- ?line T = ets_new(a, Flags),
- ?line grow_shrink_2(N, N, T),
- ?line ets:delete(T).
+ Set = ets_new(a, [set]),
+ grow_shrink_0(0, 3071, 3000, 5000, Set),
+ ets:delete(Set),
-grow_shrink_2(0, Orig, T) ->
- List = [{I,a} || I <- lists:seq(1, Orig)],
- List = lists:sort(ets:tab2list(T)),
- grow_shrink_3(Orig, T);
-grow_shrink_2(N, Orig, T) ->
+ %OrdSet = ets_new(a, [ordered_set]),
+ %grow_shrink_0(0, lists:seq(3071, 5000), OrdSet),
+ %ets:delete(OrdSet),
+
+ ?line verify_etsmem(EtsMem).
+
+grow_shrink_0(N, _, _, Max, _) when N >= Max ->
+ ok;
+grow_shrink_0(N0, GrowN, ShrinkN, Max, T) ->
+ N1 = grow_shrink_1(N0, GrowN, ShrinkN, T),
+ grow_shrink_0(N1, GrowN, ShrinkN, Max, T).
+
+grow_shrink_1(N0, GrowN, ShrinkN, T) ->
+ N1 = grow_shrink_2(N0+1, N0 + GrowN, T),
+ grow_shrink_3(N1, N1 - ShrinkN, T).
+
+grow_shrink_2(N, GrowTo, _) when N > GrowTo ->
+ %io:format("Grown to ~p\n", [GrowTo]),
+ GrowTo;
+grow_shrink_2(N, GrowTo, T) ->
true = ets:insert(T, {N,a}),
- grow_shrink_2(N-1, Orig, T).
+ grow_shrink_2(N+1, GrowTo, T).
-grow_shrink_3(0, T) ->
- [] = ets:tab2list(T);
-grow_shrink_3(N, T) ->
+grow_shrink_3(N, ShrinkTo, _) when N =< ShrinkTo ->
+ %io:format("Shrunk to ~p\n", [ShrinkTo]),
+ ShrinkTo;
+grow_shrink_3(N, ShrinkTo, T) ->
true = ets:delete(T, N),
- grow_shrink_3(N-1, T).
+ grow_shrink_3(N-1, ShrinkTo, T).
grow_pseudo_deleted(doc) -> ["Grow a table that still contains pseudo-deleted objects"];
grow_pseudo_deleted(suite) -> [];
@@ -5055,17 +5207,29 @@ grow_pseudo_deleted_do(Type) ->
?line Left = ets:info(T,size),
?line Mult = get_kept_objects(T),
filltabstr(T,Mult),
- my_spawn_opt(fun()-> ?line true = ets:info(T,fixed),
- Self ! start,
- io:format("Starting to filltabstr... ~p\n",[now()]),
- filltabstr(T,Mult,Mult+10000),
- io:format("Done with filltabstr. ~p\n",[now()]),
- Self ! done
- end, [link, {scheduler,2}]),
+ my_spawn_opt(
+ fun() ->
+ true = ets:info(T,fixed),
+ Self ! start,
+ io:put_chars("Starting to filltabstr...\n"),
+ do_tc(fun() ->
+ filltabstr(T, Mult, Mult+10000)
+ end,
+ fun(Elapsed) ->
+ io:format("Done with filltabstr in ~p ms\n",
+ [Elapsed])
+ end),
+ Self ! done
+ end, [link, {scheduler,2}]),
?line start = receive_any(),
- io:format("Unfixing table...~p nitems=~p\n",[now(),ets:info(T,size)]),
- ?line true = ets:safe_fixtable(T,false),
- io:format("Unfix table done. ~p nitems=~p\n",[now(),ets:info(T,size)]),
+ io:format("Unfixing table... nitems=~p\n", [ets:info(T, size)]),
+ do_tc(fun() ->
+ true = ets:safe_fixtable(T, false)
+ end,
+ fun(Elapsed) ->
+ io:format("Unfix table done in ~p ms. nitems=~p\n",
+ [Elapsed,ets:info(T, size)])
+ end),
?line false = ets:info(T,fixed),
?line 0 = get_kept_objects(T),
?line done = receive_any(),
@@ -5095,17 +5259,28 @@ shrink_pseudo_deleted_do(Type) ->
[true]}]),
?line Half = ets:info(T,size),
?line Half = get_kept_objects(T),
- my_spawn_opt(fun()-> ?line true = ets:info(T,fixed),
- Self ! start,
- io:format("Starting to delete... ~p\n",[now()]),
- del_one_by_one_set(T,1,Half+1),
- io:format("Done with delete. ~p\n",[now()]),
- Self ! done
- end, [link, {scheduler,2}]),
+ my_spawn_opt(
+ fun()-> true = ets:info(T,fixed),
+ Self ! start,
+ io:put_chars("Starting to delete... ~p\n"),
+ do_tc(fun() ->
+ del_one_by_one_set(T, 1, Half+1)
+ end,
+ fun(Elapsed) ->
+ io:format("Done with delete in ~p ms.\n",
+ [Elapsed])
+ end),
+ Self ! done
+ end, [link, {scheduler,2}]),
?line start = receive_any(),
- io:format("Unfixing table...~p nitems=~p\n",[now(),ets:info(T,size)]),
- ?line true = ets:safe_fixtable(T,false),
- io:format("Unfix table done. ~p nitems=~p\n",[now(),ets:info(T,size)]),
+ io:format("Unfixing table... nitems=~p\n", [ets:info(T, size)]),
+ do_tc(fun() ->
+ true = ets:safe_fixtable(T, false)
+ end,
+ fun(Elapsed) ->
+ io:format("Unfix table done in ~p ms. nitems=~p\n",
+ [Elapsed,ets:info(T, size)])
+ end),
?line false = ets:info(T,fixed),
?line 0 = get_kept_objects(T),
?line done = receive_any(),
@@ -5258,30 +5433,42 @@ smp_unfix_fix_do() ->
?line Deleted = get_kept_objects(T),
{Child, Mref} =
- my_spawn_opt(fun()-> ?line true = ets:info(T,fixed),
- Parent ! start,
- io:format("Child waiting for table to be unfixed... now=~p mem=~p\n",
- [now(),ets:info(T,memory)]),
- repeat_while(fun()-> ets:info(T,fixed) end),
- io:format("Table unfixed. Child Fixating! now=~p mem=~p\n",
- [now(),ets:info(T,memory)]),
- ?line true = ets:safe_fixtable(T,true),
- repeat_while(fun(Key) when Key =< NumOfObjs ->
- ets:delete(T,Key), {true,Key+1};
- (Key) -> {false,Key}
- end,
- Deleted),
- ?line 0 = ets:info(T,size),
- ?line true = get_kept_objects(T) >= Left,
- ?line done = receive_any()
- end,
- [link, monitor, {scheduler,2}]),
+ my_spawn_opt(
+ fun()->
+ true = ets:info(T,fixed),
+ Parent ! start,
+ io:format("Child waiting for table to be unfixed... mem=~p\n",
+ [ets:info(T, memory)]),
+ do_tc(fun() ->
+ repeat_while(fun()-> ets:info(T, fixed) end)
+ end,
+ fun(Elapsed) ->
+ io:format("Table unfixed in ~p ms."
+ " Child Fixating! mem=~p\n",
+ [Elapsed,ets:info(T,memory)])
+ end),
+ true = ets:safe_fixtable(T,true),
+ repeat_while(fun(Key) when Key =< NumOfObjs ->
+ ets:delete(T,Key), {true,Key+1};
+ (Key) -> {false,Key}
+ end,
+ Deleted),
+ 0 = ets:info(T,size),
+ true = get_kept_objects(T) >= Left,
+ done = receive_any()
+ end,
+ [link, monitor, {scheduler,2}]),
?line start = receive_any(),
?line true = ets:info(T,fixed),
- io:format("Parent starting to unfix... ~p\n",[now()]),
- ets:safe_fixtable(T,false),
- io:format("Parent done with unfix. ~p\n",[now()]),
+ io:put_chars("Parent starting to unfix... ~p\n"),
+ do_tc(fun() ->
+ ets:safe_fixtable(T, false)
+ end,
+ fun(Elapsed) ->
+ io:format("Parent done with unfix in ~p ms.\n",
+ [Elapsed])
+ end),
Child ! done,
{'DOWN', Mref, process, Child, normal} = receive_any(),
?line false = ets:info(T,fixed),
@@ -5368,7 +5555,7 @@ otp_8166_zombie_creator(T,Deleted) ->
[{'=<','$1', Deleted}],
[true]}]),
Pid ! zombies_created,
- repeat_while(fun() -> case ets:info(T,safe_fixed) of
+ repeat_while(fun() -> case ets:info(T,safe_fixed_monotonic_time) of
{_,[_P1,_P2]} ->
false;
_ ->
@@ -5582,6 +5769,43 @@ ets_all_run() ->
ets_all_run().
+take(Config) when is_list(Config) ->
+ %% Simple test for set tables.
+ T1 = ets_new(a, [set]),
+ [] = ets:take(T1, foo),
+ ets:insert(T1, {foo,bar}),
+ [] = ets:take(T1, bar),
+ [{foo,bar}] = ets:take(T1, foo),
+ [] = ets:tab2list(T1),
+ %% Non-immediate key.
+ ets:insert(T1, {{'not',<<"immediate">>},ok}),
+ [{{'not',<<"immediate">>},ok}] = ets:take(T1, {'not',<<"immediate">>}),
+ %% Same with ordered tables.
+ T2 = ets_new(b, [ordered_set]),
+ [] = ets:take(T2, foo),
+ ets:insert(T2, {foo,bar}),
+ [] = ets:take(T2, bar),
+ [{foo,bar}] = ets:take(T2, foo),
+ [] = ets:tab2list(T2),
+ ets:insert(T2, {{'not',<<"immediate">>},ok}),
+ [{{'not',<<"immediate">>},ok}] = ets:take(T2, {'not',<<"immediate">>}),
+ %% Arithmetically-equal keys.
+ ets:insert(T2, [{1.0,float},{2,integer}]),
+ [{1.0,float}] = ets:take(T2, 1),
+ [{2,integer}] = ets:take(T2, 2.0),
+ [] = ets:tab2list(T2),
+ %% Same with bag.
+ T3 = ets_new(c, [bag]),
+ ets:insert(T3, [{1,1},{1,2},{3,3}]),
+ [{1,1},{1,2}] = ets:take(T3, 1),
+ [{3,3}] = ets:take(T3, 3),
+ [] = ets:tab2list(T3),
+ ets:delete(T1),
+ ets:delete(T2),
+ ets:delete(T3),
+ ok.
+
+
%
% Utility functions:
%
@@ -5730,7 +5954,7 @@ verify_etsmem({MemInfo,AllTabs}) ->
io:format("Actual: ~p", [MemInfo2]),
io:format("Changed tables before: ~p\n",[AllTabs -- AllTabs2]),
io:format("Changed tables after: ~p\n", [AllTabs2 -- AllTabs]),
- ets_test_spawn_logger ! failed_memcheck,
+ ets_test_spawn_logger ! {failed_memcheck, get('__ETS_TEST_CASE__')},
{comment, "Failed memory check"}
end.
@@ -5781,8 +6005,8 @@ spawn_logger(Procs, FailedMemchecks) ->
From ! test_procs_synced,
spawn_logger([From], FailedMemchecks);
- failed_memcheck ->
- spawn_logger(Procs, FailedMemchecks+1);
+ {failed_memcheck, TestCase} ->
+ spawn_logger(Procs, [TestCase|FailedMemchecks]);
{Pid, get_failed_memchecks} ->
Pid ! {get_failed_memchecks, FailedMemchecks},
@@ -5802,7 +6026,7 @@ start_spawn_logger() ->
case whereis(ets_test_spawn_logger) of
Pid when is_pid(Pid) -> true;
_ -> register(ets_test_spawn_logger,
- spawn_opt(fun () -> spawn_logger([], 0) end,
+ spawn_opt(fun () -> spawn_logger([], []) end,
[{priority, max}]))
end.
@@ -6246,3 +6470,10 @@ repeat_for_opts_atom2list(compressed) -> [compressed,void].
ets_new(Name, Opts) ->
%%ets:new(Name, [compressed | Opts]).
ets:new(Name, Opts).
+
+do_tc(Do, Report) ->
+ T1 = erlang:monotonic_time(),
+ Do(),
+ T2 = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(T2 - T1, native, milli_seconds),
+ Report(Elapsed).
diff --git a/lib/stdlib/test/ets_tough_SUITE.erl b/lib/stdlib/test/ets_tough_SUITE.erl
index d9d0461575..c6f24fc670 100644
--- a/lib/stdlib/test/ets_tough_SUITE.erl
+++ b/lib/stdlib/test/ets_tough_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/expand_test.erl b/lib/stdlib/test/expand_test.erl
index b9db32c352..6c178a9270 100644
--- a/lib/stdlib/test/expand_test.erl
+++ b/lib/stdlib/test/expand_test.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/expand_test1.erl b/lib/stdlib/test/expand_test1.erl
index 1d375e5677..9f1ea42eb7 100644
--- a/lib/stdlib/test/expand_test1.erl
+++ b/lib/stdlib/test/expand_test1.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/file_sorter_SUITE.erl b/lib/stdlib/test/file_sorter_SUITE.erl
index 74c08912be..e0d9ec1fd7 100644
--- a/lib/stdlib/test/file_sorter_SUITE.erl
+++ b/lib/stdlib/test/file_sorter_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index bd313390b3..01b798faef 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -77,7 +78,8 @@ wildcard_one(Config) when is_list(Config) ->
L = filelib:wildcard(Wc),
L = filelib:wildcard(Wc, erl_prim_loader),
L = filelib:wildcard(Wc, "."),
- L = filelib:wildcard(Wc, Dir)
+ L = filelib:wildcard(Wc, Dir),
+ L = filelib:wildcard(Wc, Dir++"/.")
end),
?line file:set_cwd(OldCwd),
?line ok = file:del_dir(Dir),
diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl
index ecd9cff9f9..fd47da8150 100644
--- a/lib/stdlib/test/filename_SUITE.erl
+++ b/lib/stdlib/test/filename_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -287,38 +288,66 @@ extension(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
join(Config) when is_list(Config) ->
+ %% Whenever joining two elements, test the equivalence between
+ %% join/1 and join/2 (OTP-12158) by using help function
+ %% filename_join/2.
?line "/" = filename:join(["/"]),
?line "/" = filename:join(["//"]),
- ?line "usr/foo.erl" = filename:join("usr","foo.erl"),
- ?line "/src/foo.erl" = filename:join(usr, "/src/foo.erl"),
- ?line "/src/foo.erl" = filename:join(["/src/",'foo.erl']),
- ?line "/src/foo.erl" = filename:join(usr, ["/sr", 'c/foo.erl']),
- ?line "/src/foo.erl" = filename:join("usr", "/src/foo.erl"),
+ "usr/foo.erl" = filename_join("usr","foo.erl"),
+ "/src/foo.erl" = filename_join(usr, "/src/foo.erl"),
+ "/src/foo.erl" = filename_join("/src/",'foo.erl'),
+ "/src/foo.erl" = filename_join(usr, ["/sr", 'c/foo.erl']),
+ "/src/foo.erl" = filename_join("usr", "/src/foo.erl"),
%% Make sure that redundant slashes work too.
?line "a/b/c/d/e/f/g" = filename:join(["a//b/c/////d//e/f/g"]),
- ?line "a/b/c/d/e/f/g" = filename:join(["a//b/c/", "d//e/f/g"]),
- ?line "a/b/c/d/e/f/g" = filename:join(["a//b/c", "d//e/f/g"]),
- ?line "/d/e/f/g" = filename:join(["a//b/c", "/d//e/f/g"]),
- ?line "/d/e/f/g" = filename:join(["a//b/c", "//d//e/f/g"]),
-
- ?line "foo/bar" = filename:join([$f,$o,$o,$/,[]], "bar"),
+ "a/b/c/d/e/f/g" = filename_join("a//b/c/", "d//e/f/g"),
+ "a/b/c/d/e/f/g" = filename_join("a//b/c", "d//e/f/g"),
+ "/d/e/f/g" = filename_join("a//b/c", "/d//e/f/g"),
+ "/d/e/f/g" = filename:join("a//b/c", "//d//e/f/g"),
+
+ "foo/bar" = filename_join([$f,$o,$o,$/,[]], "bar"),
+
+ %% Single dots - should be removed if in the middle of the path,
+ %% but not at the end of the path.
+ "/." = filename:join(["/."]),
+ "/" = filename:join(["/./"]),
+ "/." = filename:join(["/./."]),
+ "./." = filename:join(["./."]),
+
+ "/a/b" = filename_join("/a/.","b"),
+ "/a/b/." = filename_join("/a/.","b/."),
+ "/a/." = filename_join("/a/.","."),
+ "/a/." = filename_join("/a","."),
+ "/a/." = filename_join("/a/.",""),
+ "./." = filename_join("./.","."),
+ "./." = filename_join("./","."),
+ "./." = filename_join("./.",""),
+ "." = filename_join(".",""),
+ "./." = filename_join(".","."),
+
+ %% Trailing slash shall be removed - except the root
+ "/" = filename:join(["/"]),
+ "/" = filename:join(["/./"]),
+ "/a" = filename:join(["/a/"]),
+ "/b" = filename_join("/a/","/b/"),
+ "/a/b" = filename_join("/a/","b/"),
?line case os:type() of
{win32, _} ->
?line "d:/" = filename:join(["D:/"]),
?line "d:/" = filename:join(["D:\\"]),
- ?line "d:/abc" = filename:join(["D:/", "abc"]),
- ?line "d:abc" = filename:join(["D:", "abc"]),
+ "d:/abc" = filename_join("D:/", "abc"),
+ "d:abc" = filename_join("D:", "abc"),
?line "a/b/c/d/e/f/g" =
filename:join(["a//b\\c//\\/\\d/\\e/f\\g"]),
?line "a:usr/foo.erl" =
filename:join(["A:","usr","foo.erl"]),
?line "/usr/foo.erl" =
filename:join(["A:","/usr","foo.erl"]),
- ?line "c:usr" = filename:join("A:","C:usr"),
- ?line "a:usr" = filename:join("A:","usr"),
- ?line "c:/usr" = filename:join("A:", "C:/usr"),
+ "c:usr" = filename_join("A:","C:usr"),
+ "a:usr" = filename_join("A:","usr"),
+ "c:/usr" = filename_join("A:", "C:/usr"),
?line "c:/usr/foo.erl" =
filename:join(["A:","C:/usr","foo.erl"]),
?line "c:usr/foo.erl" =
@@ -329,6 +358,11 @@ join(Config) when is_list(Config) ->
ok
end.
+%% Make sure join([A,B]) is equivalent to join(A,B) (OTP-12158)
+filename_join(A,B) ->
+ Res = filename:join(A,B),
+ Res = filename:join([A,B]).
+
pathtype(Config) when is_list(Config) ->
?line relative = filename:pathtype(".."),
?line relative = filename:pathtype("foo"),
@@ -362,6 +396,8 @@ split(Config) when is_list(Config) ->
?line ["foo", "bar", "hello"]= filename:split("foo////bar//hello"),
?line ["foo", "bar", "hello"]= filename:split(["foo//",'//bar//h',"ello"]),
?line ["foo", "bar", "hello"]= filename:split(["foo//",'//bar//h'|ello]),
+ ["/"] = filename:split("/"),
+ [] = filename:split(""),
case os:type() of
{win32,_} ->
?line ["a:/","msdev","include"] =
@@ -633,6 +669,53 @@ join_bin(Config) when is_list(Config) ->
?line <<"foo/bar">> = filename:join([$f,$o,$o,$/,[]], <<"bar">>),
+ %% Single dots - should be removed if in the middle of the path,
+ %% but not at the end of the path.
+ %% Also test equivalence between join/1 and join/2 (OTP-12158)
+ <<"/.">> = filename:join([<<"/.">>]),
+ <<"/">> = filename:join([<<"/./">>]),
+ <<"/.">> = filename:join([<<"/./.">>]),
+ <<"./.">> = filename:join([<<"./.">>]),
+
+ <<"/a/b">> = filename:join([<<"/a/.">>,<<"b">>]),
+ <<"/a/b">> = filename:join(<<"/a/.">>,<<"b">>),
+
+ <<"/a/b/.">> = filename:join([<<"/a/.">>,<<"b/.">>]),
+ <<"/a/b/.">> = filename:join(<<"/a/.">>,<<"b/.">>),
+
+ <<"/a/.">> = filename:join([<<"/a/.">>,<<".">>]),
+ <<"/a/.">> = filename:join(<<"/a/.">>,<<".">>),
+
+ <<"/a/.">> = filename:join([<<"/a">>,<<".">>]),
+ <<"/a/.">> = filename:join(<<"/a">>,<<".">>),
+
+ <<"/a/.">> = filename:join([<<"/a/.">>,<<"">>]),
+ <<"/a/.">> = filename:join(<<"/a/.">>,<<"">>),
+
+ <<"./.">> = filename:join([<<"./.">>,<<".">>]),
+ <<"./.">> = filename:join(<<"./.">>,<<".">>),
+
+ <<"./.">> = filename:join([<<"./">>,<<".">>]),
+ <<"./.">> = filename:join(<<"./">>,<<".">>),
+
+ <<"./.">> = filename:join([<<"./.">>,<<"">>]),
+ <<"./.">> = filename:join(<<"./.">>,<<"">>),
+
+ <<".">> = filename:join([<<".">>,<<"">>]),
+ <<".">> = filename:join(<<".">>,<<"">>),
+
+ <<"./.">> = filename:join([<<".">>,<<".">>]),
+ <<"./.">> = filename:join(<<".">>,<<".">>),
+
+ %% Trailing slash shall be removed - except the root
+ <<"/">> = filename:join([<<"/">>]),
+ <<"/">> = filename:join([<<"/./">>]),
+ <<"/a">> = filename:join([<<"/a/">>]),
+ <<"/b">> = filename:join([<<"/a/">>,<<"/b/">>]),
+ <<"/b">> = filename:join(<<"/a/">>,<<"/b/">>),
+ <<"/a/b">> = filename:join([<<"/a/">>,<<"b/">>]),
+ <<"/a/b">> = filename:join(<<"/a/">>,<<"b/">>),
+
?line case os:type() of
{win32, _} ->
?line <<"d:/">> = filename:join([<<"D:/">>]),
@@ -687,6 +770,8 @@ split_bin(Config) when is_list(Config) ->
[<<"/">>,<<"usr">>,<<"local">>,<<"bin">>] = filename:split(<<"/usr/local/bin">>),
[<<"foo">>,<<"bar">>]= filename:split(<<"foo/bar">>),
[<<"foo">>, <<"bar">>, <<"hello">>]= filename:split(<<"foo////bar//hello">>),
+ [<<"/">>] = filename:split(<<"/">>),
+ [] = filename:split(<<"">>),
case os:type() of
{win32,_} ->
[<<"a:/">>,<<"msdev">>,<<"include">>] =
diff --git a/lib/stdlib/test/fixtable_SUITE.erl b/lib/stdlib/test/fixtable_SUITE.erl
index 57fe4c4508..cf716032a1 100644
--- a/lib/stdlib/test/fixtable_SUITE.erl
+++ b/lib/stdlib/test/fixtable_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/format_SUITE.erl b/lib/stdlib/test/format_SUITE.erl
index 68e17a0459..77636687cd 100644
--- a/lib/stdlib/test/format_SUITE.erl
+++ b/lib/stdlib/test/format_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl
index 60a1ba8c60..b019f98b69 100644
--- a/lib/stdlib/test/gen_event_SUITE.erl
+++ b/lib/stdlib/test/gen_event_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -106,7 +107,7 @@ start(Config) when is_list(Config) ->
?line {error, {already_started, _}} =
gen_event:start({global, my_dummy_name}),
- exit(Pid6, shutdown),
+ ok = gen_event:stop({global, my_dummy_name}, shutdown, 10000),
receive
{'EXIT', Pid6, shutdown} -> ok
after 10000 ->
@@ -131,90 +132,105 @@ start(Config) when is_list(Config) ->
ok.
-hibernate(suite) -> [];
hibernate(Config) when is_list(Config) ->
- ?line {ok,Pid} = gen_event:start({local, my_dummy_handler}),
- ?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
- ?line [dummy_h] = gen_event:which_handlers(my_dummy_handler),
- ?line true = gen_event:call(my_dummy_handler, dummy_h, hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Pid ! wake,
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line later = gen_event:call(my_dummy_handler, dummy_h, hibernate_later),
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line receive after 2000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Pid ! wake,
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line gen_event:notify(my_dummy_handler,hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line gen_event:notify(my_dummy_handler,wakeup),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line gen_event:notify(my_dummy_handler,hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line gen_event:sync_notify(my_dummy_handler,wakeup),
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line ok = gen_event:sync_notify(my_dummy_handler,hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Pid ! wake,
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line ok = gen_event:add_handler(my_dummy_handler, dummy1_h, [self()]),
- ?line [_,_] = gen_event:which_handlers(my_dummy_handler),
- ?line gen_event:notify(my_dummy_handler,hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line gen_event:notify(my_dummy_handler,wakeup),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Pid ! wake,
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line Pid ! gnurf,
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Pid ! sleep,
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Pid ! wake,
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid,current_function)),
- ?line ok = gen_event:stop(my_dummy_handler),
- ?line {ok,Pid2} = gen_event:start({local, my_dummy_handler}),
- ?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self(),hibernate]),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid2,current_function),
- ?line sys:suspend(my_dummy_handler),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid2,current_function),
- ?line sys:resume(my_dummy_handler),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid2,current_function),
- ?line Pid2 ! wake,
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/=
- erlang:process_info(Pid2,current_function)),
+ {ok,Pid} = gen_event:start({local, my_dummy_handler}),
+ ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
+ [dummy_h] = gen_event:which_handlers(my_dummy_handler),
+ true = gen_event:call(my_dummy_handler, dummy_h, hibernate),
+ is_in_erlang_hibernate(Pid),
+
+ Pid ! wake,
+ is_not_in_erlang_hibernate(Pid),
+ later = gen_event:call(my_dummy_handler, dummy_h, hibernate_later),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ is_in_erlang_hibernate(Pid),
+
+ Pid ! wake,
+ is_not_in_erlang_hibernate(Pid),
+ gen_event:notify(my_dummy_handler, hibernate),
+ is_in_erlang_hibernate(Pid),
+ gen_event:notify(my_dummy_handler, wakeup),
+ is_not_in_erlang_hibernate(Pid),
+ gen_event:notify(my_dummy_handler, hibernate),
+ is_in_erlang_hibernate(Pid),
+ gen_event:sync_notify(my_dummy_handler, wakeup),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ ok = gen_event:sync_notify(my_dummy_handler, hibernate),
+ is_in_erlang_hibernate(Pid),
+
+ Pid ! wake,
+ is_not_in_erlang_hibernate(Pid),
+ ok = gen_event:add_handler(my_dummy_handler, dummy1_h, [self()]),
+ [_,_] = gen_event:which_handlers(my_dummy_handler),
+ gen_event:notify(my_dummy_handler, hibernate),
+ is_in_erlang_hibernate(Pid),
+ gen_event:notify(my_dummy_handler, wakeup),
+ is_in_erlang_hibernate(Pid),
+
+ Pid ! wake,
+ is_not_in_erlang_hibernate(Pid),
+
+ Pid ! gnurf,
+ is_in_erlang_hibernate(Pid),
+
+ Pid ! sleep,
+ is_in_erlang_hibernate(Pid),
+
+ Pid ! wake,
+ is_not_in_erlang_hibernate(Pid),
+ ok = gen_event:stop(my_dummy_handler),
+
+ {ok,Pid2} = gen_event:start({local, my_dummy_handler}),
+ ok = gen_event:add_handler(my_dummy_handler, dummy_h,
+ [self(),hibernate]),
+ is_in_erlang_hibernate(Pid2),
+ sys:suspend(my_dummy_handler),
+ is_in_erlang_hibernate(Pid2),
+ sys:resume(my_dummy_handler),
+ is_in_erlang_hibernate(Pid2),
+
+ Pid2 ! wake,
+ is_not_in_erlang_hibernate(Pid2),
-
- ?line ok = gen_event:stop(my_dummy_handler),
+ ok = gen_event:stop(my_dummy_handler),
ok.
+is_in_erlang_hibernate(Pid) ->
+ receive after 1 -> ok end,
+ is_in_erlang_hibernate_1(200, Pid).
+
+is_in_erlang_hibernate_1(0, Pid) ->
+ io:format("~p\n", [erlang:process_info(Pid, current_function)]),
+ ?t:fail(not_in_erlang_hibernate_3);
+is_in_erlang_hibernate_1(N, Pid) ->
+ {current_function,MFA} = erlang:process_info(Pid, current_function),
+ case MFA of
+ {erlang,hibernate,3} ->
+ ok;
+ _ ->
+ receive after 10 -> ok end,
+ is_in_erlang_hibernate_1(N-1, Pid)
+ end.
+
+is_not_in_erlang_hibernate(Pid) ->
+ receive after 1 -> ok end,
+ is_not_in_erlang_hibernate_1(200, Pid).
+
+is_not_in_erlang_hibernate_1(0, Pid) ->
+ io:format("~p\n", [erlang:process_info(Pid, current_function)]),
+ ?t:fail(not_in_erlang_hibernate_3);
+is_not_in_erlang_hibernate_1(N, Pid) ->
+ {current_function,MFA} = erlang:process_info(Pid, current_function),
+ case MFA of
+ {erlang,hibernate,3} ->
+ receive after 10 -> ok end,
+ is_not_in_erlang_hibernate_1(N-1, Pid);
+ _ ->
+ ok
+ end.
add_handler(doc) -> [];
@@ -396,7 +412,6 @@ notify(Config) when is_list(Config) ->
ok
end,
?line ok = gen_event:notify(my_dummy_handler, {swap_event,dummy1_h,swap}),
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:notify(my_dummy_handler, Event),
?line receive
@@ -429,7 +444,6 @@ notify(Config) when is_list(Config) ->
end,
?line ok = gen_event:notify(my_dummy_handler,
{swap_event, {dummy1_h, 9}, swap}),
- ?t:sleep(1000),
?line [{dummy1_h,9}] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:notify(my_dummy_handler, Event),
?line receive
@@ -469,7 +483,6 @@ notify(Config) when is_list(Config) ->
?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy_h, [self()]),
?line ok = gen_event:notify(my_dummy_handler, {swap_event,dummy1_h,swap}),
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:notify(my_dummy_handler, do_crash),
@@ -480,7 +493,6 @@ notify(Config) when is_list(Config) ->
?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy_h, [self()]),
?line ok = gen_event:notify(my_dummy_handler, {swap_event,dummy1_h,swap}),
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:notify(my_dummy_handler, delete_event),
@@ -513,7 +525,6 @@ sync_notify(Config) when is_list(Config) ->
end,
?line ok = gen_event:sync_notify(my_dummy_handler,
{swap_event, dummy1_h, swap}),
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:sync_notify(my_dummy_handler, Event),
?line receive
@@ -546,7 +557,6 @@ sync_notify(Config) when is_list(Config) ->
end,
?line ok = gen_event:sync_notify(my_dummy_handler,
{swap_event, {dummy1_h, 9}, swap}),
- ?t:sleep(1000),
?line [{dummy1_h,9}] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:sync_notify(my_dummy_handler, Event),
?line receive
@@ -587,7 +597,6 @@ sync_notify(Config) when is_list(Config) ->
?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy_h, [self()]),
?line ok = gen_event:sync_notify(my_dummy_handler,
{swap_event,dummy1_h,swap}),
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:sync_notify(my_dummy_handler, do_crash),
@@ -599,7 +608,6 @@ sync_notify(Config) when is_list(Config) ->
?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy_h, [self()]),
?line ok = gen_event:sync_notify(my_dummy_handler,
{swap_event,dummy1_h,swap}),
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line ok = gen_event:sync_notify(my_dummy_handler, delete_event),
@@ -773,7 +781,6 @@ info(Config) when is_list(Config) ->
ok
end,
?line my_dummy_handler ! {swap_info,dummy1_h,swap},
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line my_dummy_handler ! Info,
?line receive
@@ -805,7 +812,6 @@ info(Config) when is_list(Config) ->
ok
end,
?line my_dummy_handler ! {swap_info,{dummy1_h,2},swap},
- ?t:sleep(1000),
?line [{dummy1_h,2}] = gen_event:which_handlers(my_dummy_handler),
?line my_dummy_handler ! Info,
?line receive
@@ -837,7 +843,6 @@ info(Config) when is_list(Config) ->
ok
end,
?line my_dummy_handler ! {swap_info,dummy1_h,swap},
- ?t:sleep(1000),
?line [dummy1_h] = gen_event:which_handlers(my_dummy_handler),
?line my_dummy_handler ! Info,
?line receive
diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index 39f0442824..e3da1a2271 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,6 +28,9 @@
-export([start1/1, start2/1, start3/1, start4/1, start5/1, start6/1,
start7/1, start8/1, start9/1, start10/1, start11/1, start12/1]).
+-export([stop1/1, stop2/1, stop3/1, stop4/1, stop5/1, stop6/1, stop7/1,
+ stop8/1, stop9/1, stop10/1]).
+
-export([ abnormal1/1, abnormal2/1]).
-export([shutdown/1]).
@@ -66,6 +70,8 @@ groups() ->
[{start, [],
[start1, start2, start3, start4, start5, start6, start7,
start8, start9, start10, start11, start12]},
+ {stop, [],
+ [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]},
{abnormal, [], [abnormal1, abnormal2]},
{sys, [],
[sys1, call_format_status, error_format_status, terminate_crash_format,
@@ -281,6 +287,105 @@ start12(Config) when is_list(Config) ->
ok.
+%% Anonymous, reason 'normal'
+stop1(_Config) ->
+ {ok, Pid} = gen_fsm:start(?MODULE, [], []),
+ ok = gen_fsm:stop(Pid),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_fsm:stop(Pid)),
+ ok.
+
+%% Anonymous, other reason
+stop2(_Config) ->
+ {ok,Pid} = gen_fsm:start(?MODULE, [], []),
+ ok = gen_fsm:stop(Pid, other_reason, infinity),
+ false = erlang:is_process_alive(Pid),
+ ok.
+
+%% Anonymous, invalid timeout
+stop3(_Config) ->
+ {ok,Pid} = gen_fsm:start(?MODULE, [], []),
+ {'EXIT',_} = (catch gen_fsm:stop(Pid, other_reason, invalid_timeout)),
+ true = erlang:is_process_alive(Pid),
+ ok = gen_fsm:stop(Pid),
+ false = erlang:is_process_alive(Pid),
+ ok.
+
+%% Registered name
+stop4(_Config) ->
+ {ok,Pid} = gen_fsm:start({local,to_stop},?MODULE, [], []),
+ ok = gen_fsm:stop(to_stop),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_fsm:stop(to_stop)),
+ ok.
+
+%% Registered name and local node
+stop5(_Config) ->
+ {ok,Pid} = gen_fsm:start({local,to_stop},?MODULE, [], []),
+ ok = gen_fsm:stop({to_stop,node()}),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_fsm:stop({to_stop,node()})),
+ ok.
+
+%% Globally registered name
+stop6(_Config) ->
+ {ok, Pid} = gen_fsm:start({global, to_stop}, ?MODULE, [], []),
+ ok = gen_fsm:stop({global,to_stop}),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_fsm:stop({global,to_stop})),
+ ok.
+
+%% 'via' registered name
+stop7(_Config) ->
+ dummy_via:reset(),
+ {ok, Pid} = gen_fsm:start({via, dummy_via, to_stop},
+ ?MODULE, [], []),
+ ok = gen_fsm:stop({via, dummy_via, to_stop}),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_fsm:stop({via, dummy_via, to_stop})),
+ ok.
+
+%% Anonymous on remote node
+stop8(_Config) ->
+ {ok,Node} = test_server:start_node(gen_fsm_SUITE_stop8,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ {ok, Pid} = rpc:call(Node,gen_fsm,start,[?MODULE,[],[]]),
+ ok = gen_fsm:stop(Pid),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid]),
+ {'EXIT',noproc} = (catch gen_fsm:stop(Pid)),
+ true = test_server:stop_node(Node),
+ {'EXIT',{{nodedown,Node},_}} = (catch gen_fsm:stop(Pid)),
+ ok.
+
+%% Registered name on remote node
+stop9(_Config) ->
+ {ok,Node} = test_server:start_node(gen_fsm_SUITE_stop9,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ {ok, Pid} = rpc:call(Node,gen_fsm,start,[{local,to_stop},?MODULE,[],[]]),
+ ok = gen_fsm:stop({to_stop,Node}),
+ undefined = rpc:call(Node,erlang,whereis,[to_stop]),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid]),
+ {'EXIT',noproc} = (catch gen_fsm:stop({to_stop,Node})),
+ true = test_server:stop_node(Node),
+ {'EXIT',{{nodedown,Node},_}} = (catch gen_fsm:stop({to_stop,Node})),
+ ok.
+
+%% Globally registered name on remote node
+stop10(_Config) ->
+ {ok,Node} = test_server:start_node(gen_fsm_SUITE_stop10,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ {ok, Pid} = rpc:call(Node,gen_fsm,start,[{global,to_stop},?MODULE,[],[]]),
+ global:sync(),
+ ok = gen_fsm:stop({global,to_stop}),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid]),
+ {'EXIT',noproc} = (catch gen_fsm:stop({global,to_stop})),
+ true = test_server:stop_node(Node),
+ {'EXIT',noproc} = (catch gen_fsm:stop({global,to_stop})),
+ ok.
+
%% Check that time outs in calls work
abnormal1(suite) -> [];
abnormal1(Config) when is_list(Config) ->
@@ -492,129 +597,123 @@ replace_state(Config) when is_list(Config) ->
ok.
%% Hibernation
-hibernate(suite) -> [];
hibernate(Config) when is_list(Config) ->
OldFl = process_flag(trap_exit, true),
- ?line {ok, Pid0} = gen_fsm:start_link(?MODULE, hiber_now, []),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid0,current_function),
- ?line stop_it(Pid0),
+ {ok, Pid0} = gen_fsm:start_link(?MODULE, hiber_now, []),
+ is_in_erlang_hibernate(Pid0),
+ stop_it(Pid0),
test_server:messages_get(),
-
- ?line {ok, Pid} = gen_fsm:start_link(?MODULE, hiber, []),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line hibernating = gen_fsm:sync_send_event(Pid,hibernate_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line good_morning = gen_fsm:sync_send_event(Pid,wakeup_sync),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line hibernating = gen_fsm:sync_send_event(Pid,hibernate_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line five_more = gen_fsm:sync_send_event(Pid,snooze_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line good_morning = gen_fsm:sync_send_event(Pid,wakeup_sync),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line ok = gen_fsm:send_event(Pid,hibernate_async),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line ok = gen_fsm:send_event(Pid,wakeup_async),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line ok = gen_fsm:send_event(Pid,hibernate_async),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line ok = gen_fsm:send_event(Pid,snooze_async),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line ok = gen_fsm:send_event(Pid,wakeup_async),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line Pid ! hibernate_later,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line receive after 2000 -> ok end,
- ?line ({current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function)),
- ?line 'alive!' = gen_fsm:sync_send_event(Pid,'alive?'),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line Pid ! hibernate_now,
- ?line receive after 1000 -> ok end,
- ?line ({current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function)),
- ?line 'alive!' = gen_fsm:sync_send_event(Pid,'alive?'),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
-
-
- ?line hibernating = gen_fsm:sync_send_all_state_event(Pid,hibernate_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line good_morning = gen_fsm:sync_send_all_state_event(Pid,wakeup_sync),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line hibernating = gen_fsm:sync_send_all_state_event(Pid,hibernate_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line five_more = gen_fsm:sync_send_all_state_event(Pid,snooze_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line good_morning = gen_fsm:sync_send_all_state_event(Pid,wakeup_sync),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line ok = gen_fsm:send_all_state_event(Pid,hibernate_async),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line ok = gen_fsm:send_all_state_event(Pid,wakeup_async),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line ok = gen_fsm:send_all_state_event(Pid,hibernate_async),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line ok = gen_fsm:send_all_state_event(Pid,snooze_async),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line ok = gen_fsm:send_all_state_event(Pid,wakeup_async),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
-
- ?line hibernating = gen_fsm:sync_send_all_state_event(Pid,hibernate_sync),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line sys:suspend(Pid),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line sys:resume(Pid),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
-
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} =
- erlang:process_info(Pid,current_function),
- ?line good_morning = gen_fsm:sync_send_all_state_event(Pid,wakeup_sync),
- ?line receive after 1000 -> ok end,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line stop_it(Pid),
+ {ok, Pid} = gen_fsm:start_link(?MODULE, hiber, []),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid,current_function)),
+ hibernating = gen_fsm:sync_send_event(Pid, hibernate_sync),
+ is_in_erlang_hibernate(Pid),
+ good_morning = gen_fsm:sync_send_event(Pid, wakeup_sync),
+ is_not_in_erlang_hibernate(Pid),
+ hibernating = gen_fsm:sync_send_event(Pid, hibernate_sync),
+ is_in_erlang_hibernate(Pid),
+ five_more = gen_fsm:sync_send_event(Pid, snooze_sync),
+ is_in_erlang_hibernate(Pid),
+ good_morning = gen_fsm:sync_send_event(Pid, wakeup_sync),
+ is_not_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_event(Pid, hibernate_async),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_event(Pid, wakeup_async),
+ is_not_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_event(Pid, hibernate_async),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_event(Pid, snooze_async),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_event(Pid, wakeup_async),
+ is_not_in_erlang_hibernate(Pid),
+
+ Pid ! hibernate_later,
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ is_in_erlang_hibernate(Pid),
+
+ 'alive!' = gen_fsm:sync_send_event(Pid,'alive?'),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ Pid ! hibernate_now,
+ is_in_erlang_hibernate(Pid),
+
+ 'alive!' = gen_fsm:sync_send_event(Pid,'alive?'),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+
+ hibernating = gen_fsm:sync_send_all_state_event(Pid, hibernate_sync),
+ is_in_erlang_hibernate(Pid),
+ good_morning = gen_fsm:sync_send_all_state_event(Pid, wakeup_sync),
+ is_not_in_erlang_hibernate(Pid),
+ hibernating = gen_fsm:sync_send_all_state_event(Pid, hibernate_sync),
+ is_in_erlang_hibernate(Pid),
+ five_more = gen_fsm:sync_send_all_state_event(Pid, snooze_sync),
+ is_in_erlang_hibernate(Pid),
+ good_morning = gen_fsm:sync_send_all_state_event(Pid, wakeup_sync),
+ is_not_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_all_state_event(Pid, hibernate_async),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_all_state_event(Pid, wakeup_async),
+ is_not_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_all_state_event(Pid, hibernate_async),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_all_state_event(Pid, snooze_async),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_fsm:send_all_state_event(Pid, wakeup_async),
+ is_not_in_erlang_hibernate(Pid),
+
+ hibernating = gen_fsm:sync_send_all_state_event(Pid, hibernate_sync),
+ is_in_erlang_hibernate(Pid),
+ sys:suspend(Pid),
+ is_in_erlang_hibernate(Pid),
+ sys:resume(Pid),
+ is_in_erlang_hibernate(Pid),
+ receive after 1000 -> ok end,
+ is_in_erlang_hibernate(Pid),
+
+ good_morning = gen_fsm:sync_send_all_state_event(Pid, wakeup_sync),
+ is_not_in_erlang_hibernate(Pid),
+ stop_it(Pid),
test_server:messages_get(),
process_flag(trap_exit, OldFl),
ok.
+is_in_erlang_hibernate(Pid) ->
+ receive after 1 -> ok end,
+ is_in_erlang_hibernate_1(200, Pid).
+
+is_in_erlang_hibernate_1(0, Pid) ->
+ io:format("~p\n", [erlang:process_info(Pid, current_function)]),
+ ?t:fail(not_in_erlang_hibernate_3);
+is_in_erlang_hibernate_1(N, Pid) ->
+ {current_function,MFA} = erlang:process_info(Pid, current_function),
+ case MFA of
+ {erlang,hibernate,3} ->
+ ok;
+ _ ->
+ receive after 10 -> ok end,
+ is_in_erlang_hibernate_1(N-1, Pid)
+ end.
+is_not_in_erlang_hibernate(Pid) ->
+ receive after 1 -> ok end,
+ is_not_in_erlang_hibernate_1(200, Pid).
+
+is_not_in_erlang_hibernate_1(0, Pid) ->
+ io:format("~p\n", [erlang:process_info(Pid, current_function)]),
+ ?t:fail(not_in_erlang_hibernate_3);
+is_not_in_erlang_hibernate_1(N, Pid) ->
+ {current_function,MFA} = erlang:process_info(Pid, current_function),
+ case MFA of
+ {erlang,hibernate,3} ->
+ receive after 10 -> ok end,
+ is_not_in_erlang_hibernate_1(N-1, Pid);
+ _ ->
+ ok
+ end.
%%sys1(suite) -> [];
%%sys1(_) ->
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 0f03fda30a..0ae763a48d 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -36,6 +37,9 @@
get_state/1, replace_state/1, call_with_huge_message_queue/1
]).
+-export([stop1/1, stop2/1, stop3/1, stop4/1, stop5/1, stop6/1, stop7/1,
+ stop8/1, stop9/1, stop10/1]).
+
% spawn export
-export([spec_init_local/2, spec_init_global/2, spec_init_via/2,
spec_init_default_timeout/2, spec_init_global_default_timeout/2,
@@ -51,7 +55,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [start, crash, call, cast, cast_fast, info, abcast,
+ [start, {group,stop}, crash, call, cast, cast_fast, info, abcast,
multicall, multicall_down, call_remote1, call_remote2,
call_remote3, call_remote_n1, call_remote_n2,
call_remote_n3, spec_init,
@@ -63,7 +67,8 @@ all() ->
call_with_huge_message_queue].
groups() ->
- [].
+ [{stop, [],
+ [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]}].
init_per_suite(Config) ->
Config.
@@ -237,6 +242,105 @@ start(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+%% Anonymous, reason 'normal'
+stop1(_Config) ->
+ {ok, Pid} = gen_server:start(?MODULE, [], []),
+ ok = gen_server:stop(Pid),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_server:stop(Pid)),
+ ok.
+
+%% Anonymous, other reason
+stop2(_Config) ->
+ {ok,Pid} = gen_server:start(?MODULE, [], []),
+ ok = gen_server:stop(Pid, other_reason, infinity),
+ false = erlang:is_process_alive(Pid),
+ ok.
+
+%% Anonymous, invalid timeout
+stop3(_Config) ->
+ {ok,Pid} = gen_server:start(?MODULE, [], []),
+ {'EXIT',_} = (catch gen_server:stop(Pid, other_reason, invalid_timeout)),
+ true = erlang:is_process_alive(Pid),
+ ok = gen_server:stop(Pid),
+ false = erlang:is_process_alive(Pid),
+ ok.
+
+%% Registered name
+stop4(_Config) ->
+ {ok,Pid} = gen_server:start({local,to_stop},?MODULE, [], []),
+ ok = gen_server:stop(to_stop),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_server:stop(to_stop)),
+ ok.
+
+%% Registered name and local node
+stop5(_Config) ->
+ {ok,Pid} = gen_server:start({local,to_stop},?MODULE, [], []),
+ ok = gen_server:stop({to_stop,node()}),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_server:stop({to_stop,node()})),
+ ok.
+
+%% Globally registered name
+stop6(_Config) ->
+ {ok, Pid} = gen_server:start({global, to_stop}, ?MODULE, [], []),
+ ok = gen_server:stop({global,to_stop}),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_server:stop({global,to_stop})),
+ ok.
+
+%% 'via' registered name
+stop7(_Config) ->
+ dummy_via:reset(),
+ {ok, Pid} = gen_server:start({via, dummy_via, to_stop},
+ ?MODULE, [], []),
+ ok = gen_server:stop({via, dummy_via, to_stop}),
+ false = erlang:is_process_alive(Pid),
+ {'EXIT',noproc} = (catch gen_server:stop({via, dummy_via, to_stop})),
+ ok.
+
+%% Anonymous on remote node
+stop8(_Config) ->
+ {ok,Node} = test_server:start_node(gen_server_SUITE_stop8,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ {ok, Pid} = rpc:call(Node,gen_server,start,[?MODULE,[],[]]),
+ ok = gen_server:stop(Pid),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid]),
+ {'EXIT',noproc} = (catch gen_server:stop(Pid)),
+ true = test_server:stop_node(Node),
+ {'EXIT',{{nodedown,Node},_}} = (catch gen_server:stop(Pid)),
+ ok.
+
+%% Registered name on remote node
+stop9(_Config) ->
+ {ok,Node} = test_server:start_node(gen_server_SUITE_stop9,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ {ok, Pid} = rpc:call(Node,gen_server,start,[{local,to_stop},?MODULE,[],[]]),
+ ok = gen_server:stop({to_stop,Node}),
+ undefined = rpc:call(Node,erlang,whereis,[to_stop]),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid]),
+ {'EXIT',noproc} = (catch gen_server:stop({to_stop,Node})),
+ true = test_server:stop_node(Node),
+ {'EXIT',{{nodedown,Node},_}} = (catch gen_server:stop({to_stop,Node})),
+ ok.
+
+%% Globally registered name on remote node
+stop10(_Config) ->
+ {ok,Node} = test_server:start_node(gen_server_SUITE_stop10,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ {ok, Pid} = rpc:call(Node,gen_server,start,[{global,to_stop},?MODULE,[],[]]),
+ global:sync(),
+ ok = gen_server:stop({global,to_stop}),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid]),
+ {'EXIT',noproc} = (catch gen_server:stop({global,to_stop})),
+ true = test_server:stop_node(Node),
+ {'EXIT',noproc} = (catch gen_server:stop({global,to_stop})),
+ ok.
+
crash(Config) when is_list(Config) ->
?line error_logger_forwarder:register(),
@@ -538,15 +642,13 @@ info(Config) when is_list(Config) ->
end,
ok.
-hibernate(suite) -> [];
hibernate(Config) when is_list(Config) ->
OldFl = process_flag(trap_exit, true),
- ?line {ok, Pid0} =
+ {ok, Pid0} =
gen_server:start_link({local, my_test_name_hibernate0},
- gen_server_SUITE, hibernate, []),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid0,current_function),
- ?line ok = gen_server:call(my_test_name_hibernate0, stop),
+ gen_server_SUITE, hibernate, []),
+ is_in_erlang_hibernate(Pid0),
+ ok = gen_server:call(my_test_name_hibernate0, stop),
receive
{'EXIT', Pid0, stopped} ->
ok
@@ -554,70 +656,66 @@ hibernate(Config) when is_list(Config) ->
test_server:fail(gen_server_did_not_die)
end,
- ?line {ok, Pid} =
+ {ok, Pid} =
gen_server:start_link({local, my_test_name_hibernate},
- gen_server_SUITE, [], []),
+ gen_server_SUITE, [], []),
- ?line ok = gen_server:call(my_test_name_hibernate, started_p),
- ?line true = gen_server:call(my_test_name_hibernate, hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line Parent = self(),
+ ok = gen_server:call(my_test_name_hibernate, started_p),
+ true = gen_server:call(my_test_name_hibernate, hibernate),
+ is_in_erlang_hibernate(Pid),
+ Parent = self(),
Fun = fun() ->
- receive
- go ->
- ok
- end,
- receive
- after 1000 ->
- ok
- end,
- X = erlang:process_info(Pid,current_function),
+ receive go -> ok end,
+ receive after 1000 -> ok end,
+ X = erlang:process_info(Pid, current_function),
Pid ! continue,
Parent ! {result,X}
end,
- ?line Pid2 = spawn_link(Fun),
- ?line true = gen_server:call(my_test_name_hibernate, {hibernate_noreply,Pid2}),
-
- ?line gen_server:cast(my_test_name_hibernate, hibernate_later),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line receive after 2000 -> ok end,
- ?line ({current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function)),
- ?line ok = gen_server:call(my_test_name_hibernate, started_p),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line gen_server:cast(my_test_name_hibernate, hibernate_now),
- ?line receive after 1000 -> ok end,
- ?line ({current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function)),
- ?line ok = gen_server:call(my_test_name_hibernate, started_p),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line Pid ! hibernate_later,
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line receive after 2000 -> ok end,
- ?line ({current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function)),
- ?line ok = gen_server:call(my_test_name_hibernate, started_p),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line Pid ! hibernate_now,
- ?line receive after 1000 -> ok end,
- ?line ({current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function)),
- ?line ok = gen_server:call(my_test_name_hibernate, started_p),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
- ?line receive
- {result,R} ->
- ?line {current_function,{erlang,hibernate,3}} = R
- end,
- ?line true = gen_server:call(my_test_name_hibernate, hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line sys:suspend(my_test_name_hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line sys:resume(my_test_name_hibernate),
- ?line receive after 1000 -> ok end,
- ?line {current_function,{erlang,hibernate,3}} = erlang:process_info(Pid,current_function),
- ?line ok = gen_server:call(my_test_name_hibernate, started_p),
- ?line true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
-
- ?line ok = gen_server:call(my_test_name_hibernate, stop),
+ Pid2 = spawn_link(Fun),
+ true = gen_server:call(my_test_name_hibernate, {hibernate_noreply,Pid2}),
+
+ gen_server:cast(my_test_name_hibernate, hibernate_later),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_server:call(my_test_name_hibernate, started_p),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+
+ gen_server:cast(my_test_name_hibernate, hibernate_now),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_server:call(my_test_name_hibernate, started_p),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+
+ Pid ! hibernate_later,
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_server:call(my_test_name_hibernate, started_p),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+
+ Pid ! hibernate_now,
+ is_in_erlang_hibernate(Pid),
+ ok = gen_server:call(my_test_name_hibernate, started_p),
+ true = ({current_function,{erlang,hibernate,3}} =/=
+ erlang:process_info(Pid, current_function)),
+ receive
+ {result,R} ->
+ {current_function,{erlang,hibernate,3}} = R
+ end,
+
+ true = gen_server:call(my_test_name_hibernate, hibernate),
+ is_in_erlang_hibernate(Pid),
+ sys:suspend(my_test_name_hibernate),
+ is_in_erlang_hibernate(Pid),
+ sys:resume(my_test_name_hibernate),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_server:call(my_test_name_hibernate, started_p),
+ true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)),
+
+ ok = gen_server:call(my_test_name_hibernate, stop),
receive
{'EXIT', Pid, stopped} ->
ok
@@ -627,6 +725,23 @@ hibernate(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+is_in_erlang_hibernate(Pid) ->
+ receive after 1 -> ok end,
+ is_in_erlang_hibernate_1(200, Pid).
+
+is_in_erlang_hibernate_1(0, Pid) ->
+ io:format("~p\n", [erlang:process_info(Pid, current_function)]),
+ ?t:fail(not_in_erlang_hibernate_3);
+is_in_erlang_hibernate_1(N, Pid) ->
+ {current_function,MFA} = erlang:process_info(Pid, current_function),
+ case MFA of
+ {erlang,hibernate,3} ->
+ ok;
+ _ ->
+ receive after 10 -> ok end,
+ is_in_erlang_hibernate_1(N-1, Pid)
+ end.
+
%% --------------------------------------
%% Test gen_server:abcast and handle_cast.
%% Test all different return values from
diff --git a/lib/stdlib/test/id_transform_SUITE.erl b/lib/stdlib/test/id_transform_SUITE.erl
index ee97ffe7b3..1cff990697 100644
--- a/lib/stdlib/test/id_transform_SUITE.erl
+++ b/lib/stdlib/test/id_transform_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -55,47 +56,26 @@ end_per_group(_GroupName, Config) ->
id_transform(doc) -> "Test erl_id_trans.";
id_transform(Config) when is_list(Config) ->
- ?line File=filename:join([code:lib_dir(stdlib),"examples",
- "erl_id_trans.erl"]),
- ?line {ok,erl_id_trans,Bin}=compile:file(File,[binary]),
- ?line {module,erl_id_trans}=code:load_binary(erl_id_trans,File,Bin),
- ?line case test_server:purify_is_running() of
- false ->
- Dog = ct:timetrap(?t:hours(1)),
- ?line Res = run_in_test_suite(),
- ?t:timetrap_cancel(Dog),
- Res;
- true ->
- {skip,"Purify (too slow)"}
- end.
+ File = filename:join([code:lib_dir(stdlib),"examples",
+ "erl_id_trans.erl"]),
+ {ok,erl_id_trans,Bin} = compile:file(File,[binary]),
+ {module,erl_id_trans} = code:load_binary(erl_id_trans, File, Bin),
+ case test_server:purify_is_running() of
+ false ->
+ Dog = ct:timetrap(?t:hours(1)),
+ Res = run_in_test_suite(),
+ ?t:timetrap_cancel(Dog),
+ Res;
+ true ->
+ {skip,"Valgrind (too slow)"}
+ end.
run_in_test_suite() ->
- LibDir = code:lib_dir(),
SuperDir = filename:dirname(filename:dirname(code:which(?MODULE))),
TestDirs = filelib:wildcard(filename:join([SuperDir,"*_test"])),
- {All,Res} = case LibDir of
- "/clearcase/otp/erts/lib" ->
- %% Only test_suites 'cause clearcase is too slow...
- {false,run_list(TestDirs)};
- _ ->
- {true,run_codepath_and(TestDirs)}
- end,
- Comment0 = case All of
- true -> [];
- false -> "Only testsuite directories traversed"
- end,
- case Res of
- {error,Reason} when Comment0 =/= [] ->
- {failed,Comment0++"; "++Reason};
- {error,Reason} ->
- {failed,Reason};
- ok ->
- {comment,Comment0}
- end.
-
-run_codepath_and(DirList) ->
AbsDirs = [filename:absname(X) || X <- code:get_path()],
- run_list(ordsets:from_list([X || X <- AbsDirs] ++ DirList)).
+ Dirs = ordsets:from_list(AbsDirs ++ TestDirs),
+ run_list(Dirs).
run_list(PathL) ->
io:format("Where to search for beam files:\n~p\n", [PathL]),
@@ -122,7 +102,7 @@ run_list(PathL) ->
end,
case length(SevereFailures) of
0 -> ok;
- Len -> {error,integer_to_list(Len)++" failures"}
+ Len -> {failed,integer_to_list(Len)++" failures"}
end.
diff --git a/lib/stdlib/test/id_transform_SUITE_data/External.hrl b/lib/stdlib/test/id_transform_SUITE_data/External.hrl
index c0cd9e68ac..48f9cf7a01 100644
--- a/lib/stdlib/test/id_transform_SUITE_data/External.hrl
+++ b/lib/stdlib/test/id_transform_SUITE_data/External.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/id_transform_SUITE_data/m.hrl b/lib/stdlib/test/id_transform_SUITE_data/m.hrl
index ed485e24be..88fa280c14 100644
--- a/lib/stdlib/test/id_transform_SUITE_data/m.hrl
+++ b/lib/stdlib/test/id_transform_SUITE_data/m.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/id_transform_SUITE_data/m_i.hrl b/lib/stdlib/test/id_transform_SUITE_data/m_i.hrl
index 53a279999e..48ae978cd3 100644
--- a/lib/stdlib/test/id_transform_SUITE_data/m_i.hrl
+++ b/lib/stdlib/test/id_transform_SUITE_data/m_i.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/id_transform_SUITE_data/oe_ex.hrl b/lib/stdlib/test/id_transform_SUITE_data/oe_ex.hrl
index 72a12908df..a3a892dba1 100644
--- a/lib/stdlib/test/id_transform_SUITE_data/oe_ex.hrl
+++ b/lib/stdlib/test/id_transform_SUITE_data/oe_ex.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 2203dd8f51..cb96f8b575 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -28,10 +29,11 @@
manpage/1, otp_6708/1, otp_7084/1, otp_7421/1,
io_lib_collect_line_3_wb/1, cr_whitespace_in_string/1,
io_fread_newlines/1, otp_8989/1, io_lib_fread_literal/1,
- printable_range/1,
+ printable_range/1, bad_printable_range/1,
io_lib_print_binary_depth_one/1, otp_10302/1, otp_10755/1,
otp_10836/1, io_lib_width_too_small/1,
- io_with_huge_message_queue/1]).
+ io_with_huge_message_queue/1, format_string/1,
+ maps/1, coverage/1]).
-export([pretty/2]).
@@ -69,9 +71,10 @@ all() ->
manpage, otp_6708, otp_7084, otp_7421,
io_lib_collect_line_3_wb, cr_whitespace_in_string,
io_fread_newlines, otp_8989, io_lib_fread_literal,
- printable_range,
+ printable_range, bad_printable_range,
io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836,
- io_lib_width_too_small, io_with_huge_message_queue].
+ io_lib_width_too_small, io_with_huge_message_queue,
+ format_string, maps, coverage].
groups() ->
[].
@@ -1035,7 +1038,14 @@ rp(Term, Col, Ll, D, M, RF) ->
lists:flatten(io_lib:format("~s", [R])).
fmt(Fmt, Args) ->
- lists:flatten(io_lib:format(Fmt, Args)).
+ FormatList = io_lib:scan_format(Fmt, Args),
+ {Fmt2, Args2} = io_lib:unscan_format(FormatList),
+ Chars1 = lists:flatten(io_lib:build_text(FormatList)),
+ Chars2 = lists:flatten(io_lib:format(Fmt2, Args2)),
+ Chars3 = lists:flatten(io_lib:format(Fmt, Args)),
+ Chars1 = Chars2,
+ Chars2 = Chars3,
+ Chars3.
rfd(a, 0) ->
[];
@@ -2053,8 +2063,6 @@ printable_range(Suite) when is_list(Suite) ->
[{args, " +pclatin1 -pa " ++ Pa}]),
unicode = rpc:call(UNode,io,printable_range,[]),
latin1 = rpc:call(LNode,io,printable_range,[]),
- {error, _} = test_server:start_node(printable_range_unnicode, slave,
- [{args, " +pcunnicode -pa " ++ Pa}]),
PrettyOptions = [{column,1},
{line_length,109},
{depth,30},
@@ -2062,48 +2070,81 @@ printable_range(Suite) when is_list(Suite) ->
{record_print_fun,
fun(_,_) -> no end},
{encoding,unicode}],
- 1025 = lists:max(lists:flatten(rpc:call(UNode,io_lib_pretty,print,
- [{hello, [1024,1025]},
- PrettyOptions]))),
- 125 = lists:max(lists:flatten(rpc:call(LNode,io_lib_pretty,print,
- [{hello, [1024,1025]},
- PrettyOptions]))),
- 125 = lists:max(lists:flatten(rpc:call(DNode,io_lib_pretty,print,
- [{hello, [1024,1025]},
- PrettyOptions]))),
- 1025 = lists:max(lists:flatten(rpc:call(UNode,io_lib_pretty,print,
- [{hello, <<1024/utf8,1025/utf8>>},
- PrettyOptions]))),
- 125 = lists:max(lists:flatten(rpc:call(LNode,io_lib_pretty,print,
- [{hello, <<1024/utf8,1025/utf8>>},
- PrettyOptions]))),
- 125 = lists:max(lists:flatten(rpc:call(DNode,io_lib_pretty,print,
- [{hello, <<1024/utf8,1025/utf8>>},
- PrettyOptions]))),
+ PrintableControls = "\t\v\b\f\e\r\n",
+
+ 1025 = print_max(UNode, [{hello, [1024,1025]},
+ PrettyOptions]),
+ 125 = print_max(LNode, [{hello, [1024,1025]},
+ PrettyOptions]),
+ 125 = print_max(DNode, [{hello, [1024,1025]},
+ PrettyOptions]),
+ 1025 = print_max(UNode, [{hello, <<1024/utf8,1025/utf8>>},
+ PrettyOptions]),
+ 125 = print_max(LNode, [{hello, <<1024/utf8,1025/utf8>>},
+ PrettyOptions]),
+ 125 = print_max(DNode, [{hello, <<1024/utf8,1025/utf8>>},
+ PrettyOptions]),
+ $v = print_max(UNode, [PrintableControls,PrettyOptions]),
+ $v = print_max(LNode, [PrintableControls,PrettyOptions]),
+ $v = print_max(DNode, [PrintableControls,PrettyOptions]),
+ 16#10FFFF = print_max(UNode,
+ [<<16#10FFFF/utf8,"\t\v\b\f\e\r\n">>,
+ PrettyOptions]),
+ $> = print_max(LNode,
+ [<<16#10FFFF/utf8,"\t\v\b\f\e\r\n">>,
+ PrettyOptions]),
+ $> = print_max(DNode,
+ [<<16#10FFFF/utf8,"\t\v\b\f\e\r\n">>,
+ PrettyOptions]),
- 1025 = lists:max(lists:flatten(rpc:call(UNode,io_lib,format,
- ["~tp",[{hello, [1024,1025]}]]))),
- 125 = lists:max(lists:flatten(rpc:call(LNode,io_lib,format,
- ["~tp",[{hello, [1024,1025]}]]))),
- 125 = lists:max(lists:flatten(rpc:call(DNode,io_lib,format,
- ["~tp",[{hello, [1024,1025]}]]))),
- 1025 = lists:max(lists:flatten(rpc:call(UNode,io_lib,format,
- ["~tp",
- [{hello,
- <<1024/utf8,1025/utf8>>}]]))),
- 125 = lists:max(lists:flatten(rpc:call(LNode,io_lib,format,
- ["~tp",
- [{hello,
- <<1024/utf8,1025/utf8>>}]]))),
- 125 = lists:max(lists:flatten(rpc:call(DNode,io_lib,format,
- ["~tp",
- [{hello,
- <<1024/utf8,1025/utf8>>}]]))),
+ 1025 = format_max(UNode, ["~tp", [{hello, [1024,1025]}]]),
+ 125 = format_max(LNode, ["~tp", [{hello, [1024,1025]}]]),
+ 125 = format_max(DNode, ["~tp", [{hello, [1024,1025]}]]),
+ 1025 = format_max(UNode, ["~tp", [{hello, <<1024/utf8,1025/utf8>>}]]),
+ 125 = format_max(LNode, ["~tp", [{hello, <<1024/utf8,1025/utf8>>}]]),
+ 125 = format_max(DNode, ["~tp", [{hello, <<1024/utf8,1025/utf8>>}]]),
+
+ $\e = format_max(UNode, ["~ts", [PrintableControls]]),
+ $\e = format_max(LNode, ["~ts", [PrintableControls]]),
+ $\e = format_max(DNode, ["~ts", [PrintableControls]]),
+
test_server:stop_node(UNode),
test_server:stop_node(LNode),
test_server:stop_node(DNode),
ok.
+print_max(Node, Args) ->
+ rpc_call_max(Node, io_lib_pretty, print, Args).
+
+format_max(Node, Args) ->
+ rpc_call_max(Node, io_lib, format, Args).
+
+rpc_call_max(Node, M, F, Args) ->
+ lists:max(lists:flatten(rpc:call(Node, M, F, Args))).
+
+%% Make sure that a bad specification for a printable range is rejected.
+bad_printable_range(Config) when is_list(Config) ->
+ Cmd = lists:concat([lib:progname()," +pcunnnnnicode -run erlang halt"]),
+ P = open_port({spawn, Cmd}, [stderr_to_stdout, {line, 200}]),
+ ok = receive
+ {P, {data, {eol , "bad range of printable characters" ++ _}}} ->
+ ok;
+ Other ->
+ Other
+ after 1000 ->
+ timeout
+ end,
+ catch port_close(P),
+ flush_from_port(P),
+ ok.
+
+flush_from_port(P) ->
+ receive {P, _} ->
+ flush_from_port(P)
+ after 0 ->
+ ok
+ end.
+
io_lib_print_binary_depth_one(doc) ->
"Test binaries printed with a depth of one behave correctly";
io_lib_print_binary_depth_one(Suite) when is_list(Suite) ->
@@ -2216,7 +2257,7 @@ compile_file(File, Text, Config) ->
after ok %file:delete(Fname)
end.
-io_lib_width_too_small(Config) ->
+io_lib_width_too_small(_Config) ->
"**" = lists:flatten(io_lib:format("~2.3w", [3.14])),
"**" = lists:flatten(io_lib:format("~2.5w", [3.14])),
ok.
@@ -2224,12 +2265,14 @@ io_lib_width_too_small(Config) ->
%% Test that the time for a huge message queue is not
%% significantly slower than with an empty message queue.
io_with_huge_message_queue(Config) when is_list(Config) ->
- case test_server:is_native(gen) of
- true ->
+ case {test_server:is_native(gen),test_server:is_cover()} of
+ {true,_} ->
{skip,
"gen is native - huge message queue optimization "
"is not implemented"};
- false ->
+ {_,true} ->
+ {skip,"Running under cover"};
+ {false,false} ->
do_io_with_huge_message_queue(Config)
end.
@@ -2237,19 +2280,23 @@ do_io_with_huge_message_queue(Config) ->
PrivDir = ?privdir(Config),
File = filename:join(PrivDir, "slask"),
{ok, F1} = file:open(File, [write]),
-
- {Time,ok} = timer:tc(fun() -> writes(1000, F1) end),
+ Test = fun(Times) ->
+ {Time,ok} = timer:tc(fun() -> writes(Times, F1) end),
+ Time
+ end,
+ {Times,EmptyTime} = calibrate(100, Test),
[self() ! {msg,N} || N <- lists:seq(1, 500000)],
erlang:garbage_collect(),
- {NewTime,ok} = timer:tc(fun() -> writes(1000, F1) end),
+ FullTime = Test(Times),
file:close(F1),
- io:format("Time for empty message queue: ~p", [Time]),
- io:format("Time for huge message queue: ~p", [NewTime]),
+ file:delete(File),
+ io:format("Number of writes: ~p", [Times]),
+ io:format("Time for empty message queue: ~p", [EmptyTime]),
+ io:format("Time for huge message queue: ~p", [FullTime]),
- IsCover = test_server:is_cover(),
- case (NewTime+1) / (Time+1) of
- Q when Q < 10; IsCover ->
+ case (FullTime+1) / (EmptyTime+1) of
+ Q when Q < 10 ->
ok;
Q ->
io:format("Q = ~p", [Q]),
@@ -2257,7 +2304,130 @@ do_io_with_huge_message_queue(Config) ->
end,
ok.
+%% Make sure that the time is not too short. That could cause the
+%% test case to fail.
+calibrate(N, Test) when N =< 100000 ->
+ case Test(N) of
+ Time when Time < 50000 ->
+ calibrate(10*N, Test);
+ Time ->
+ {N,Time}
+ end;
+calibrate(N, _) ->
+ N.
+
writes(0, _) -> ok;
writes(N, F1) ->
file:write(F1, "hello\n"),
writes(N - 1, F1).
+
+format_string(_Config) ->
+ %% All but padding is tested by fmt/2.
+ "xxxxxxsssx" = fmt("~10.4.xs", ["sss"]),
+ "xxxxxxsssx" = fmt("~10.4.*s", [$x, "sss"]),
+ ok.
+
+maps(_Config) ->
+ %% Note that order in which a map is printed is arbitrary. In
+ %% practice, small maps (non-HAMT) are printed in key order, but
+ %% the breakpoint for creating big maps (HAMT) is lower in the
+ %% debug-compiled run-time system than in the optimized run-time
+ %% system.
+ %%
+ %% Therefore, play it completely safe by not assuming any order
+ %% in a map with more than one element.
+
+ "#{}" = fmt("~w", [#{}]),
+ "#{a=>b}" = fmt("~w", [#{a=>b}]),
+ re_fmt(<<"#\\{(a=>b|c=>d),[.][.][.]=>[.][.][.]\\}">>,
+ "~W", [#{a=>b,c=>d},2]),
+ re_fmt(<<"#\\{(a=>b|c=>d|e=>f),[.][.][.]=>[.][.][.],[.][.][.]\\}">>,
+ "~W", [#{a=>b,c=>d,e=>f},2]),
+
+ "#{}" = fmt("~p", [#{}]),
+ "#{a => b}" = fmt("~p", [#{a=>b}]),
+ "#{...}" = fmt("~P", [#{a=>b},1]),
+ re_fmt(<<"#\\{(a => b|c => d),[.][.][.]\\}">>,
+ "~P", [#{a=>b,c=>d},2]),
+ re_fmt(<<"#\\{(a => b|c => d|e => f),[.][.][.]\\}">>,
+ "~P", [#{a=>b,c=>d,e=>f},2]),
+
+ List = [{I,I*I} || I <- lists:seq(1, 20)],
+ Map = maps:from_list(List),
+
+ "#{...}" = fmt("~P", [Map,1]),
+
+ %% Print a map and parse it back to a map.
+ S = fmt("~p\n", [Map]),
+ io:format("~p\n", [S]),
+ Map = parse_map(S),
+
+ %% Smoke test of a map as key.
+ MapAsKey = #{Map => "value"},
+ io:format("~s\n", [fmt("~p", [MapAsKey])]),
+ ok.
+
+re_fmt(Pattern, Format, Args) ->
+ S = list_to_binary(fmt(Format, Args)),
+ case re:run(S, Pattern, [{capture,none}]) of
+ nomatch ->
+ io:format("Pattern: ~s", [Pattern]),
+ io:format("Result: ~s", [S]),
+ ?t:fail();
+ match ->
+ ok
+ end.
+
+%% Parse a map consisting of integer keys and values.
+parse_map(S0) ->
+ S1 = parse_expect(S0, "#{"),
+ {M,S2} = parse_map_1(S1),
+ S = parse_expect(S2, "}"),
+ S = "",
+ M.
+
+parse_map_1(S0) ->
+ {Key,S1} = parse_number(S0),
+ S2 = parse_expect(S1, "=>"),
+ {Val,S3} = parse_number(S2),
+ case S3 of
+ ","++S4 ->
+ S5 = parse_skip_ws(S4),
+ {Map,S} = parse_map_1(S5),
+ {Map#{Key=>Val},S};
+ S ->
+ {#{Key=>Val},S}
+ end.
+
+parse_number(S) ->
+ parse_number(S, none).
+
+parse_number([C|S], Acc0) when $0 =< C, C =< $9 ->
+ Acc = case Acc0 of
+ none -> 0;
+ _ when is_integer(Acc0) -> Acc0
+ end,
+ parse_number(S, Acc*10+C-$0);
+parse_number(S, Acc) ->
+ {Acc,parse_skip_ws(S)}.
+
+parse_expect([H|T1], [H|T2]) ->
+ parse_expect(T1, T2);
+parse_expect(S, []) ->
+ parse_skip_ws(S).
+
+parse_skip_ws([C|S]) when C =< $\s ->
+ parse_skip_ws(S);
+parse_skip_ws(S) ->
+ S.
+
+%% Cover the last uncovered lines for completeness.
+coverage(_Config) ->
+ S1 = io_lib_pretty:print({a,term}, fun(_, _) -> no end),
+ io:format("~s\n", [S1]),
+
+ %% The tuple of arity three will be ignored.
+ S2 = io_lib_pretty:print(lists:seq(1, 100), [{depth,1,1}]),
+ io:format("~s\n", [S2]),
+
+ ok.
diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl
index 76a8109a8d..811c7ed7bb 100644
--- a/lib/stdlib/test/io_proto_SUITE.erl
+++ b/lib/stdlib/test/io_proto_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -69,12 +70,7 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
- Term = case os:getenv("TERM") of
- List when is_list(List) ->
- List;
- _ ->
- "dumb"
- end,
+ Term = os:getenv("TERM", "dumb"),
os:putenv("TERM","vt100"),
[{watchdog, Dog}, {term, Term} | Config].
end_per_testcase(_Case, Config) ->
@@ -481,149 +477,182 @@ unicode_options(Config) when is_list(Config) ->
ok.
-unicode_options_gen(suite) ->
- [];
-unicode_options_gen(doc) ->
- ["Tests various unicode options on random generated files"];
+%% Tests various unicode options on random generated files.
unicode_options_gen(Config) when is_list(Config) ->
- ?line random:seed(1240,900586,553728),
- ?line PrivDir = ?config(priv_dir,Config),
- ?line AllModes = [utf8,utf16,{utf16,big},{utf16,little},utf32,{utf32,big},{utf32,little}],
- ?line FSize = 17*1024,
- ?line NumItersRead = 2,
- ?line NumItersWrite = 2,
- ?line Dir = filename:join([PrivDir,"GENDATA1"]),
- ?line file:make_dir(Dir),
-
- %dbg:tracer(process,{fun(A,_) -> erlang:display(A) end,true}),
- %dbg:tpl(file_io_server,x),
- %dbg:ctpl(file_io_server,cafu),
- %dbg:tp(unicode,x),
-
- DoOneFile1 = fun(Encoding,N,M) ->
- ?dbg({Encoding,M,N}),
- io:format("Read test: Encoding ~p, Chunk size ~p, Iteration ~p~n",[Encoding,M,N]),
- io:format(standard_error,"Read test: Encoding ~p, Chunk size ~p, Iteration ~p\r\n",[Encoding,M,N]),
- ?line Fname = filename:join([Dir,"genfile_"++enc2str(Encoding)++"_"++integer_to_list(N)]),
- ?dbg(?LINE),
- ?line Ulist = random_unicode(FSize),
- ?dbg(?LINE),
- ?line my_write_file(Fname,Ulist,Encoding),
- ?dbg(?LINE),
- ?line {ok,F1} = file:open(Fname,[read,{encoding,Encoding}]),
-
- ?dbg(?LINE),
- ?line Res1 = read_whole_file(fun(FD) -> io:get_line(FD,'') end,F1),
- ?dbg(?LINE),
- ?line Ulist = unicode:characters_to_list(Res1,unicode),
- ?dbg(?LINE),
- ?line file:close(F1),
- ?line {ok,F2} = file:open(Fname, [read,binary,{encoding,Encoding}]),
- ?line Res2 = read_whole_file(fun(FD) -> io:get_chars(FD,'',M) end,F2),
- ?line Ulist = unicode:characters_to_list(Res2,unicode),
- ?dbg(?LINE),
- ?line file:close(F2),
- ?line {ok,F3} = file:open(Fname, [read,binary,{encoding,Encoding}]),
- ?dbg(?LINE),
-%% case {Encoding,M,N} of
-%% {{utf16,little},10,2} ->
-%% dbg:p(F3,call);
-%% _ ->
-%% ok
-%% end,
-
- ?line Res3 = read_whole_file(fun(FD) -> case io:fread(FD,'',"~ts") of {ok,D} -> D; O -> O end end, F3),
- ?dbg(?LINE),
- ?line Ulist2 = [ X || X <- Ulist,
- X =/= $\n, X =/= $ ],
- ?dbg(?LINE),
- ?line Ulist2 = unicode:characters_to_list(Res3,unicode),
- ?dbg(?LINE),
- ?line file:close(F3),
- ?line {ok,F4} = file:open(Fname, [read,{encoding,Encoding}]),
- ?line Res4 = read_whole_file(fun(FD) -> case io:fread(FD,'',"~tc") of {ok,D} -> D; O -> O end end,F4),
- ?line Ulist3 = [ X || X <- Ulist,
- X =/= $\n ],
- ?line Ulist3 = unicode:characters_to_list(Res4,unicode),
- ?dbg(?LINE),
- ?line file:close(F4),
- ?line file:delete(Fname)
- end,
-
- [ [ [ DoOneFile1(E,N,M) || E <- AllModes ] || M <- [10,1000,128,1024,8192,8193] ] || N <- lists:seq(1,NumItersRead)],
- DoOneFile2 = fun(Encoding,N,M) ->
- ?dbg({Encoding,M,N}),
- io:format("Write test: Encoding ~p, Chunk size ~p, Iteration ~p~n",[Encoding,M,N]),
- io:format(standard_error,"Write test: Encoding ~p, Chunk size ~p, Iteration ~p\r\n",[Encoding,M,N]),
- ?line Fname = filename:join([Dir,"genfile_"++enc2str(Encoding)++"_"++integer_to_list(N)]),
- ?dbg(?LINE),
- ?line Ulist = random_unicode(FSize),
- ?dbg(?LINE),
- ?line {ok,F1} = file:open(Fname,[write,{encoding,Encoding}]),
- ?line io:put_chars(F1,Ulist),
- ?line file:close(F1),
- ?line Ulist = my_read_file(Fname,Encoding),
- ?line file:delete(Fname),
- ?line {ok,F2} = file:open(Fname,[write,binary,{encoding,Encoding}]),
- ?line io:put_chars(F2,Ulist),
- ?line file:close(F2),
- ?line Ulist = my_read_file(Fname,Encoding),
- ?line file:delete(Fname),
- ?line {ok,F3} = file:open(Fname,[write,{encoding,Encoding}]),
- ?line LL = string:tokens(Ulist,"\n"),
- ?line Ulist2 = lists:flatten(LL),
- ?line [ io:format(F3,"~ts",[L]) || L <- LL ],
- ?line file:close(F3),
- ?line Ulist2 = my_read_file(Fname,Encoding),
- ?line file:delete(Fname),
- ?line {ok,F4} = file:open(Fname,[write,{encoding,Encoding}]),
- ?line [ io:format(F4,"~tc",[C]) || C <- Ulist ],
- ?line file:close(F4),
- ?line Ulist = my_read_file(Fname,Encoding),
- ?line file:delete(Fname),
- ?line {ok,F5} = file:open(Fname,[write,{encoding,Encoding}]),
- ?line io:put_chars(F5,unicode:characters_to_binary(Ulist)),
- ?line file:close(F5),
- ?line Ulist = my_read_file(Fname,Encoding),
- ?line file:delete(Fname),
- ok
- end,
- [ [ [ DoOneFile2(E,N,M) || E <- AllModes ] || M <- [10,1000,128,1024,8192,8193] ] || N <- lists:seq(1,NumItersWrite)],
+ random:seed(1240, 900586, 553728),
+ PrivDir = ?config(priv_dir, Config),
+ AllModes = [utf8,utf16,{utf16,big},{utf16,little},
+ utf32,{utf32,big},{utf32,little}],
+ FSize = 9*1024,
+ NumItersRead = 2,
+ NumItersWrite = 2,
+ Dir = filename:join(PrivDir, "GENDATA1"),
+ file:make_dir(Dir),
+
+ DoOneFile1 =
+ fun(Encoding, N, M) ->
+ ?dbg({Encoding,M,N}),
+ io:format("Read test: Encoding ~p, Chunk size ~p, Iteration ~p~n",[Encoding,M,N]),
+ io:format(standard_error,
+ "Read test: Encoding ~p, Chunk size ~p, Iteration ~p\r\n",[Encoding,M,N]),
+ Fname = filename:join(Dir,
+ "genfile_"++enc2str(Encoding)++
+ "_"++integer_to_list(N)),
+ Ulist = random_unicode(FSize),
+ Bin = unicode:characters_to_binary(Ulist, utf8, Encoding),
+ ok = file:write_file(Fname, Bin),
+
+ Read1 = fun(FD) -> io:get_line(FD, '') end,
+ Res1 = read_whole_file(Fname,
+ [read,read_ahead,{encoding,Encoding}],
+ Read1),
+
+ Read2 = fun(FD) -> io:get_chars(FD, '', M) end,
+ Res2 = read_whole_file(Fname,
+ [read,binary,
+ read_ahead,{encoding,Encoding}],
+ Read2),
+
+ Read3 = fun(FD) ->
+ case io:fread(FD, '', "~ts") of
+ {ok,D} -> D;
+ Other -> Other end
+ end,
+ Res3 = read_whole_file(Fname,
+ [read,binary,
+ read_ahead,{encoding,Encoding}],
+ Read3),
+
+ Read4 = fun(FD) ->
+ case io:fread(FD, '', "~ts") of
+ {ok,D} -> D;
+ Other -> Other end
+ end,
+ Res4 = read_whole_file(Fname,
+ [read,read_ahead,{encoding,Encoding}],
+ Read4),
+
+ Ulist2 = [X || X <- Ulist, X =/= $\n, X =/= $\s],
+ Ulist3 = [X || X <- Ulist, X =/= $\n],
+ Ulist = done(Res1),
+ Ulist = done(Res2),
+ Ulist2 = done(Res3),
+ Ulist3 = done(Res4),
+
+ file:delete(Fname)
+ end,
+ [ [ [ DoOneFile1(E, N, M) || E <- AllModes ] ||
+ M <- [10,1000,128,1024,8192,8193] ] ||
+ N <- lists:seq(1, NumItersRead) ],
+
+ DoOneFile2 =
+ fun(Encoding,N,M) ->
+ ?dbg({Encoding,M,N}),
+ io:format("Write test: Encoding ~p, Chunk size ~p, Iteration ~p~n",[Encoding,M,N]),
+ io:format(standard_error,
+ "Write test: Encoding ~p, Chunk size ~p, Iteration ~p\r\n",[Encoding,M,N]),
+ Fname = filename:join(Dir,
+ "genfile_"++enc2str(Encoding)++
+ "_"++integer_to_list(N)),
+ Ulist = random_unicode(FSize),
+
+ Res1 = write_read_file(Fname, 1,
+ [write],
+ Encoding,
+ fun(FD) -> io:put_chars(FD, Ulist) end),
+
+ Res2 = write_read_file(Fname, 2,
+ [write,binary],
+ Encoding,
+ fun(FD) -> io:put_chars(FD, Ulist) end),
+
+ Fun3 = fun(FD) ->
+ _ = [io:format(FD, "~tc", [C]) || C <- Ulist],
+ ok
+ end,
+ Res3 = write_read_file(Fname, 3,
+ [write],
+ Encoding,
+ Fun3),
+
+ Fun4 = fun(FD) ->
+ io:put_chars(FD,
+ unicode:characters_to_binary(Ulist))
+ end,
+ Res4 = write_read_file(Fname, 4,
+ [write],
+ Encoding,
+ Fun4),
+
+ LL = string:tokens(Ulist, "\n"),
+ Fun5 = fun(FD) ->
+ _ = [io:format(FD, "~ts", [L]) || L <- LL],
+ ok
+ end,
+ Res5 = write_read_file(Fname, 5,
+ [write],
+ Encoding,
+ Fun5),
+
+ Ulist2 = lists:flatten(LL),
+ ResBin = done(Res1),
+ ResBin = done(Res2),
+ ResBin = done(Res3),
+ ResBin = done(Res4),
+ Ulist = unicode:characters_to_list(ResBin, Encoding),
+
+ ResBin2 = done(Res5),
+ Ulist2 = unicode:characters_to_list(ResBin2, Encoding),
+
+ ok
+ end,
+ [ [ [ DoOneFile2(E, N, M) || E <- AllModes ] ||
+ M <- [10,1000,128,1024,8192,8193] ] ||
+ N <- lists:seq(1, NumItersWrite) ],
ok.
+read_whole_file(Fname, Options, Fun) ->
+ do(fun() ->
+ do_read_whole_file(Fname, Options, Fun)
+ end).
+do_read_whole_file(Fname, Options, Fun) ->
+ {ok,F} = file:open(Fname, Options),
+ Res = do_read_whole_file_1(Fun, F),
+ ok = file:close(F),
+ unicode:characters_to_list(Res, unicode).
-
-read_whole_file(Fun,F) ->
+do_read_whole_file_1(Fun, F) ->
case Fun(F) of
eof ->
[];
{error,Error} ->
- ?dbg(Error),
receive after 10000 -> ok end,
exit(Error);
Other ->
- %?dbg(Other),
- [Other | read_whole_file(Fun,F)]
+ [Other|do_read_whole_file_1(Fun, F)]
end.
-
+write_read_file(Fname0, N, Options, Enc, Writer) ->
+ Fname = Fname0 ++ "_" ++ integer_to_list(N),
+ do(fun() ->
+ do_write_read_file(Fname, Options, Enc, Writer)
+ end).
+
+do_write_read_file(Fname, Options, Encoding, Writer) ->
+ {ok,F} = file:open(Fname, [{encoding,Encoding}|Options]),
+ Writer(F),
+ ok = file:close(F),
+ {ok,Bin} = file:read_file(Fname),
+ ok = file:delete(Fname),
+ Bin.
+
enc2str(Atom) when is_atom(Atom) ->
atom_to_list(Atom);
enc2str({A1,A2}) when is_atom(A1), is_atom(A2) ->
atom_to_list(A1)++"_"++atom_to_list(A2).
-
-
-my_write_file(Filename,UniList,Encoding) ->
- Bin = unicode:characters_to_binary(UniList,utf8,Encoding),
- file:write_file(Filename,Bin).
-
-my_read_file(Filename,Encoding) ->
- {ok,Bin} = file:read_file(Filename),
- unicode:characters_to_list(Bin,Encoding).
-
random_unicode(0) ->
[];
random_unicode(N) ->
@@ -1349,47 +1378,43 @@ rtnode(C,N) ->
rtnode(Commands,Nodename,ErlPrefix) ->
rtnode(Commands,Nodename,ErlPrefix,[]).
rtnode(Commands,Nodename,ErlPrefix,Extra) ->
- ?line case get_progs() of
- {error,_Reason} ->
- ?line {skip,"No runerl present"};
- {RunErl,ToErl,Erl} ->
- ?line case create_tempdir() of
- {error, Reason2} ->
- ?line {skip, Reason2};
- Tempdir ->
- ?line SPid =
- start_runerl_node(RunErl,ErlPrefix++
- "\\\""++Erl++"\\\"",
- Tempdir,Nodename, Extra),
- ?line CPid = start_toerl_server(ToErl,Tempdir),
- ?line erase(getline_skipped),
- ?line Res =
- (catch get_and_put(CPid, Commands,1)),
- ?line case stop_runerl_node(CPid) of
- {error,_} ->
- ?line CPid2 =
- start_toerl_server
- (ToErl,Tempdir),
- ?line erase(getline_skipped),
- ?line ok = get_and_put
- (CPid2,
- [{putline,[7]},
- {sleep,
- timeout(short)},
- {putline,""},
- {getline," -->"},
- {putline,"s"},
- {putline,"c"},
- {putline,""}],1),
- ?line stop_runerl_node(CPid2);
- _ ->
- ?line ok
- end,
- ?line wait_for_runerl_server(SPid),
- ?line ok = ?RM_RF(Tempdir),
- ?line ok = Res
- end
- end.
+ case get_progs() of
+ {error,_Reason} ->
+ {skip,"No runerl present"};
+ {RunErl,ToErl,Erl} ->
+ case create_tempdir() of
+ {error, Reason2} ->
+ {skip, Reason2};
+ Tempdir ->
+ SPid = start_runerl_node(RunErl, ErlPrefix++
+ "\\\""++Erl++"\\\"",
+ Tempdir, Nodename, Extra),
+ CPid = start_toerl_server(ToErl, Tempdir),
+ put(getline_skipped, []),
+ Res = (catch get_and_put(CPid, Commands, 1)),
+ case stop_runerl_node(CPid) of
+ {error,_} ->
+ CPid2 = start_toerl_server(ToErl, Tempdir),
+ put(getline_skipped, []),
+ ok = get_and_put
+ (CPid2,
+ [{putline,[7]},
+ {sleep,
+ timeout(short)},
+ {putline,""},
+ {getline," -->"},
+ {putline,"s"},
+ {putline,"c"},
+ {putline,""}], 1),
+ stop_runerl_node(CPid2);
+ _ ->
+ ok
+ end,
+ wait_for_runerl_server(SPid),
+ ok = ?RM_RF(Tempdir),
+ ok = Res
+ end
+ end.
timeout(long) ->
2 * timeout(normal);
@@ -1433,57 +1458,51 @@ get_and_put(CPid, [{sleep, X}|T],N) ->
after X ->
get_and_put(CPid,T,N+1)
end;
-get_and_put(CPid, [{getline, Match}|T],N) ->
+get_and_put(CPid, [{getline_pred,Pred,Msg}|T]=T0, N)
+ when is_function(Pred) ->
?dbg({getline, Match}),
CPid ! {self(), {get_line, timeout(normal)}},
receive
{get_line, timeout} ->
error_logger:error_msg("~p: getline timeout waiting for \"~s\" "
"(command number ~p, skipped: ~p)~n",
- [?MODULE, Match,N,get(getline_skipped)]),
+ [?MODULE,Msg,N,get(getline_skipped)]),
{error, timeout};
{get_line, Data} ->
?dbg({data,Data}),
- case lists:prefix(Match, Data) of
- true ->
- erase(getline_skipped),
+ case Pred(Data) of
+ yes ->
+ put(getline_skipped, []),
get_and_put(CPid, T,N+1);
- false ->
- case get(getline_skipped) of
- undefined ->
- put(getline_skipped,[Data]);
- List ->
- put(getline_skipped,List ++ [Data])
- end,
- get_and_put(CPid, [{getline, Match}|T],N)
+ no ->
+ error_logger:error_msg("~p: getline match failure "
+ "\"~s\" "
+ "(command number ~p)\n",
+ [?MODULE,Msg,N]),
+ {error, no_match};
+ maybe ->
+ List = get(getline_skipped),
+ put(getline_skipped, List ++ [Data]),
+ get_and_put(CPid, T0, N)
end
end;
+get_and_put(CPid, [{getline, Match}|T],N) ->
+ ?dbg({getline, Match}),
+ F = fun(Data) ->
+ case lists:prefix(Match, Data) of
+ true -> yes;
+ false -> maybe
+ end
+ end,
+ get_and_put(CPid, [{getline_pred,F,Match}|T], N);
get_and_put(CPid, [{getline_re, Match}|T],N) ->
- ?dbg({getline_re, Match}),
- CPid ! {self(), {get_line, timeout(normal)}},
- receive
- {get_line, timeout} ->
- error_logger:error_msg("~p: getline_re timeout waiting for \"~s\" "
- "(command number ~p, skipped: ~p)~n",
- [?MODULE, Match,N,get(getline_skipped)]),
- {error, timeout};
- {get_line, Data} ->
- ?dbg({data,Data}),
- case re:run(Data, Match,[{capture,none}]) of
- match ->
- erase(getline_skipped),
- get_and_put(CPid, T,N+1);
- _ ->
- case get(getline_skipped) of
- undefined ->
- put(getline_skipped,[Data]);
- List ->
- put(getline_skipped,List ++ [Data])
- end,
- get_and_put(CPid, [{getline_re, Match}|T],N)
- end
- end;
-
+ F = fun(Data) ->
+ case re:run(Data, Match, [{capture,none}]) of
+ match -> yes;
+ _ -> maybe
+ end
+ end,
+ get_and_put(CPid, [{getline_pred,F,Match}|T], N);
get_and_put(CPid, [{putline_raw, Line}|T],N) ->
?dbg({putline_raw, Line}),
CPid ! {self(), {send_line, Line}},
@@ -1738,8 +1757,7 @@ toerl_loop(Port,Acc) ->
end.
millistamp() ->
- {Mega, Secs, Micros} = erlang:now(),
- (Micros div 1000) + Secs * 1000 + Mega * 1000000000.
+ erlang:monotonic_time(milli_seconds).
get_data_within(Port, X, Acc) when X =< 0 ->
?dbg({get_data_within, X, Acc, ?LINE}),
@@ -1773,10 +1791,22 @@ get_data_within(Port, Timeout, Acc) ->
end.
get_default_shell() ->
+ Match = fun(Data) ->
+ case lists:prefix("undefined", Data) of
+ true ->
+ yes;
+ false ->
+ case re:run(Data, "<\\d+[.]\\d+[.]\\d+>",
+ [{capture,none}]) of
+ match -> no;
+ _ -> maybe
+ end
+ end
+ end,
try
rtnode([{putline,""},
{putline, "whereis(user_drv)."},
- {getline, "undefined"}],[]),
+ {getline_pred, Match, "matching of user_drv pid"}], []),
old
catch _E:_R ->
?dbg({_E,_R}),
@@ -1937,3 +1967,15 @@ chomp(<<Ch,Rest/binary>>) ->
<<Ch,X/binary>>;
chomp(Atom) ->
Atom.
+
+do(Fun) ->
+ {_,Ref} = spawn_monitor(fun() ->
+ exit(Fun())
+ end),
+ Ref.
+
+done(Ref) ->
+ receive
+ {'DOWN',Ref,process,_,Result} ->
+ Result
+ end.
diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl
index f4589a8e24..a0f7fd2744 100644
--- a/lib/stdlib/test/lists_SUITE.erl
+++ b/lib/stdlib/test/lists_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -37,13 +38,13 @@
% Test cases must be exported.
-export([member/1, reverse/1,
keymember/1, keysearch_keyfind/1,
- keystore/1, keytake/1,
+ keystore/1, keytake/1, keyreplace/1,
append_1/1, append_2/1,
seq_loop/1, seq_2/1, seq_3/1, seq_2_e/1, seq_3_e/1,
sublist_2/1, sublist_3/1, sublist_2_e/1, sublist_3_e/1,
flatten_1/1, flatten_2/1, flatten_1_e/1, flatten_2_e/1,
- dropwhile/1,
+ dropwhile/1, takewhile/1,
sort_1/1, sort_stable/1, merge/1, rmerge/1, sort_rand/1,
usort_1/1, usort_stable/1, umerge/1, rumerge/1,usort_rand/1,
keymerge/1, rkeymerge/1,
@@ -61,7 +62,7 @@
zip_unzip/1, zip_unzip3/1, zipwith/1, zipwith3/1,
filter_partition/1,
otp_5939/1, otp_6023/1, otp_6606/1, otp_7230/1,
- suffix/1, subtract/1, droplast/1]).
+ suffix/1, subtract/1, droplast/1, hof/1]).
%% Sort randomized lists until stopped.
%%
@@ -80,37 +81,51 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [{group, append}, reverse, member, keymember,
- keysearch_keyfind, keystore, keytake, dropwhile, {group,sort},
- {group, usort}, {group, keysort}, {group, ukeysort},
- {group, funsort}, {group, ufunsort}, {group, sublist},
- {group, flatten}, {group, seq}, zip_unzip, zip_unzip3,
- zipwith, zipwith3, filter_partition, {group, tickets},
- suffix, subtract].
+ [{group, append},
+ {group, key},
+ {group,sort},
+ {group, usort},
+ {group, keysort},
+ {group, ukeysort},
+ {group, funsort},
+ {group, ufunsort},
+ {group, sublist},
+ {group, flatten},
+ {group, seq},
+ {group, tickets},
+ {group, zip},
+ {group, misc}].
groups() ->
- [{append, [], [append_1, append_2]},
- {usort, [],
+ [{append, [parallel], [append_1, append_2]},
+ {usort, [parallel],
[umerge, rumerge, usort_1, usort_rand, usort_stable]},
- {keysort, [],
+ {keysort, [parallel],
[keymerge, rkeymerge, keysort_1, keysort_rand,
keysort_i, keysort_stable, keysort_error]},
- {sort,[],[merge, rmerge, sort_1, sort_rand]},
- {ukeysort, [],
+ {key, [parallel], [keymember, keysearch_keyfind, keystore,
+ keytake, keyreplace]},
+ {sort,[parallel],[merge, rmerge, sort_1, sort_rand]},
+ {ukeysort, [parallel],
[ukeymerge, rukeymerge, ukeysort_1, ukeysort_rand,
ukeysort_i, ukeysort_stable, ukeysort_error]},
- {funsort, [],
+ {funsort, [parallel],
[funmerge, rfunmerge, funsort_1, funsort_stable,
funsort_error, funsort_rand]},
- {ufunsort, [],
+ {ufunsort, [parallel],
[ufunmerge, rufunmerge, ufunsort_1, ufunsort_stable,
ufunsort_error, ufunsort_rand]},
- {seq, [], [seq_loop, seq_2, seq_3, seq_2_e, seq_3_e]},
- {sublist, [],
+ {seq, [parallel], [seq_loop, seq_2, seq_3, seq_2_e, seq_3_e]},
+ {sublist, [parallel],
[sublist_2, sublist_3, sublist_2_e, sublist_3_e]},
- {flatten, [],
+ {flatten, [parallel],
[flatten_1, flatten_2, flatten_1_e, flatten_2_e]},
- {tickets, [], [otp_5939, otp_6023, otp_6606, otp_7230]}].
+ {tickets, [parallel], [otp_5939, otp_6023, otp_6606, otp_7230]},
+ {zip, [parallel], [zip_unzip, zip_unzip3, zipwith, zipwith3]},
+ {misc, [parallel], [reverse, member, dropwhile, takewhile,
+ filter_partition, suffix, subtract,
+ hof]}
+ ].
init_per_suite(Config) ->
Config.
@@ -344,6 +359,33 @@ dropwhile(Config) when is_list(Config) ->
ok.
+takewhile(Config) when is_list(Config) ->
+ F = fun(C) -> C =/= $@ end,
+
+ [] = lists:takewhile(F, []),
+ [a] = lists:takewhile(F, [a]),
+ [a,b] = lists:takewhile(F, [a,b]),
+ [a,b,c] = lists:takewhile(F, [a,b,c]),
+
+ [] = lists:takewhile(F, [$@]),
+ [] = lists:takewhile(F, [$@,$@]),
+ [a] = lists:takewhile(F, [a,$@]),
+
+ [$k] = lists:takewhile(F, [$k,$@]),
+ [$k,$l] = lists:takewhile(F, [$k,$l,$@,$@]),
+ [a] = lists:takewhile(F, [a,$@,$@,$@]),
+
+ [] = lists:takewhile(F, [$@,a,$@,b]),
+ [] = lists:takewhile(F, [$@,$@,a,$@,b]),
+ [] = lists:takewhile(F, [$@,$@,$@,a,$@,b]),
+
+ Long = lists:seq(1, 1024),
+ Shorter = lists:seq(1, 400),
+
+ Shorter = lists:takewhile(fun(E) -> E =< 400 end, Long),
+
+ ok.
+
keystore(doc) ->
["OTP-XXX."];
keystore(suite) -> [];
@@ -381,6 +423,17 @@ keytake(Config) when is_list(Config) ->
?line false = lists:keytake(4, 2, L),
ok.
+%% Test lists:keyreplace/4.
+keyreplace(Config) when is_list(Config) ->
+ [{new,42}] = lists:keyreplace(k, 1, [{k,1}], {new,42}),
+ [atom,{new,a,b}] = lists:keyreplace(k, 1, [atom,{k,1}], {new,a,b}),
+ [a,{x,y,z}] = lists:keyreplace(a, 5, [a,{x,y,z}], {no,use}),
+
+ %% Error cases.
+ {'EXIT',_} = (catch lists:keyreplace(k, 1, [], not_tuple)),
+ {'EXIT',_} = (catch lists:keyreplace(k, 0, [], {a,b})),
+ ok.
+
merge(doc) -> ["merge functions"];
merge(suite) -> [];
merge(Config) when is_list(Config) ->
@@ -1704,7 +1757,7 @@ fun_pid(Fun) ->
get_seed() ->
case random:seed() of
undefined ->
- now();
+ erlang:timestamp();
Tuple ->
Tuple
end.
@@ -2325,19 +2378,25 @@ sublist_3_e(Config) when is_list(Config) ->
-define(flatten_error1(X), ?line {'EXIT', _} = (catch lists:flatten(X))).
-define(flatten_error2(X,Y), ?line {'EXIT', _} = (catch lists:flatten(X,Y))).
-flatten_1(doc) -> ["flatten/1"];
-flatten_1(suite) -> [];
+%% Test lists:flatten/1,2 and lists:flatlength/1.
flatten_1(Config) when is_list(Config) ->
- ?line [] = lists:flatten([]),
- ?line [1,2] = lists:flatten([1,2]),
- ?line [1,2] = lists:flatten([1,[2]]),
- ?line [1,2] = lists:flatten([[1],2]),
- ?line [1,2] = lists:flatten([[1],[2]]),
- ?line [1,2] = lists:flatten([[1,2]]),
- ?line [a,b,c,d] = lists:flatten([[a],[b,c,[d]]]),
+ [] = lists_flatten([]),
+ [1,2] = lists_flatten([1,2]),
+ [1,2] = lists_flatten([1,[2]]),
+ [1,2] = lists_flatten([[1],2]),
+ [1,2] = lists_flatten([[1],[2]]),
+ [1,2] = lists_flatten([[1,2]]),
+ [a,b,c,d] = lists_flatten([[a],[b,c,[d]]]),
ok.
+lists_flatten(List) ->
+ Flat = lists:flatten(List),
+ Flat = lists:flatten(List, []),
+ Len = lists:flatlength(List),
+ Len = length(Flat),
+ Flat.
+
flatten_1_e(doc) -> ["flatten/1 error cases"];
flatten_1_e(suite) -> [];
flatten_1_e(Config) when is_list(Config) ->
@@ -2350,11 +2409,11 @@ flatten_1_e(Config) when is_list(Config) ->
%%% clear-cut. Right now, I think that any term should be allowed.
%%% But I also wish this function didn't exist at all.
-flatten_2(doc) -> ["flatten/2"];
-flatten_2(suite) -> [];
+%% Test lists:flatten/2.
flatten_2(Config) when is_list(Config) ->
- ?line [] = lists:flatten([]),
- ?line [a] = lists:flatten([a]),
+ [] = lists:flatten([], []),
+ [a] = lists:flatten([a], []),
+ [a,b,c,[no,flatten]] = lists:flatten([[a,[b,c]]], [[no,flatten]]),
ok.
flatten_2_e(doc) -> ["flatten/2 error cases"];
@@ -2650,3 +2709,40 @@ droplast(Config) when is_list(Config) ->
?line {'EXIT', {function_clause, _}} = (catch lists:droplast(x)),
ok.
+
+%% Briefly test the common high-order functions to ensure they
+%% are covered.
+hof(Config) when is_list(Config) ->
+ L = [1,2,3],
+ [1,4,9] = lists:map(fun(N) -> N*N end, L),
+ [1,4,5,6] = lists:flatmap(fun(1) -> [1];
+ (2) -> [];
+ (3) -> [4,5,6]
+ end, L),
+ [{1,[a]},{2,[b]},{3,[c]}] =
+ lists:keymap(fun(A) -> [A] end, 2, [{1,a},{2,b},{3,c}]),
+
+ [1,3] = lists:filter(fun(N) -> N rem 2 =:= 1 end, L),
+ FilterMapFun = fun(1) -> true;
+ (2) -> {true,42};
+ (3) -> false
+ end,
+ [1,42] = lists:filtermap(FilterMapFun, L),
+ [1,42] = lists:zf(FilterMapFun, L),
+
+ [3,2,1] = lists:foldl(fun(E, A) -> [E|A] end, [], L),
+ [1,2,3] = lists:foldr(fun(E, A) -> [E|A] end, [], L),
+ {[1,4,9],[3,2,1]} = lists:mapfoldl(fun(E, A) ->
+ {E*E,[E|A]}
+ end, [], L),
+ {[1,4,9],[1,2,3]} = lists:mapfoldr(fun(E, A) ->
+ {E*E,[E|A]}
+ end, [], L),
+
+ true = lists:any(fun(N) -> N =:= 2 end, L),
+ false = lists:any(fun(N) -> N =:= 42 end, L),
+
+ true = lists:all(fun(N) -> is_integer(N) end, L),
+ false = lists:all(fun(N) -> N rem 2 =:= 0 end, L),
+
+ ok.
diff --git a/lib/stdlib/test/log_mf_h_SUITE.erl b/lib/stdlib/test/log_mf_h_SUITE.erl
index 2fd05afb11..86af3d4614 100644
--- a/lib/stdlib/test/log_mf_h_SUITE.erl
+++ b/lib/stdlib/test/log_mf_h_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/maps_SUITE.erl b/lib/stdlib/test/maps_SUITE.erl
index dda20a615b..40a8b6ac81 100644
--- a/lib/stdlib/test/maps_SUITE.erl
+++ b/lib/stdlib/test/maps_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -34,13 +35,23 @@
-export([init_per_testcase/2]).
-export([end_per_testcase/2]).
--export([t_get_3/1,t_with_2/1,t_without_2/1]).
+-export([t_get_3/1, t_filter_2/1,
+ t_fold_3/1,t_map_2/1,t_size_1/1,
+ t_with_2/1,t_without_2/1]).
+
+%-define(badmap(V,F,Args), {'EXIT', {{badmap,V}, [{maps,F,Args,_}|_]}}).
+%-define(badarg(F,Args), {'EXIT', {badarg, [{maps,F,Args,_}|_]}}).
+% silly broken hipe
+-define(badmap(V,F,_Args), {'EXIT', {{badmap,V}, [{maps,F,_,_}|_]}}).
+-define(badarg(F,_Args), {'EXIT', {badarg, [{maps,F,_,_}|_]}}).
suite() ->
[{ct_hooks, [ts_install_cth]}].
all() ->
- [t_get_3,t_with_2,t_without_2].
+ [t_get_3,t_filter_2,
+ t_fold_3,t_map_2,t_size_1,
+ t_with_2,t_without_2].
init_per_suite(Config) ->
Config.
@@ -63,6 +74,9 @@ t_get_3(Config) when is_list(Config) ->
value1 = maps:get(key1, Map, DefaultValue),
value2 = maps:get(key2, Map, DefaultValue),
DefaultValue = maps:get(key3, Map, DefaultValue),
+
+ %% error case
+ ?badmap(a,get,[[a,b],a,def]) = (catch maps:get([a,b],id(a),def)),
ok.
t_without_2(_Config) ->
@@ -70,6 +84,11 @@ t_without_2(_Config) ->
M0 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100)]),
M1 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100) -- Ki]),
M1 = maps:without([{k,I}||I <- Ki],M0),
+
+ %% error case
+ ?badmap(a,without,[[a,b],a]) = (catch maps:without([a,b],id(a))),
+ ?badmap(a,without,[{a,b},a]) = (catch maps:without({a,b},id(a))),
+ ?badarg(without,[a,#{}]) = (catch maps:without(a,#{})),
ok.
t_with_2(_Config) ->
@@ -77,4 +96,63 @@ t_with_2(_Config) ->
M0 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100)]),
M1 = maps:from_list([{{k,I},{v,I}}||I<-Ki]),
M1 = maps:with([{k,I}||I <- Ki],M0),
+
+ %% error case
+ ?badmap(a,with,[[a,b],a]) = (catch maps:with([a,b],id(a))),
+ ?badmap(a,with,[{a,b},a]) = (catch maps:with({a,b},id(a))),
+ ?badarg(with,[a,#{}]) = (catch maps:with(a,#{})),
+ ok.
+
+t_filter_2(Config) when is_list(Config) ->
+ M = #{a => 2, b => 3, c=> 4, "a" => 1, "b" => 2, "c" => 4},
+ Pred1 = fun(K,V) -> is_atom(K) andalso (V rem 2) =:= 0 end,
+ Pred2 = fun(K,V) -> is_list(K) andalso (V rem 2) =:= 0 end,
+ #{a := 2,c := 4} = maps:filter(Pred1,M),
+ #{"b" := 2,"c" := 4} = maps:filter(Pred2,M),
+ %% error case
+ ?badmap(a,filter,[_,a]) = (catch maps:filter(fun(_,_) -> ok end,id(a))),
+ ?badarg(filter,[<<>>,#{}]) = (catch maps:filter(id(<<>>),#{})),
+ ok.
+
+t_fold_3(Config) when is_list(Config) ->
+ Vs = lists:seq(1,200),
+ M0 = maps:from_list([{{k,I},I}||I<-Vs]),
+ #{ {k,1} := 1, {k,200} := 200} = M0,
+ Tot0 = lists:sum(Vs),
+ Tot1 = maps:fold(fun({k,_},V,A) -> A + V end, 0, M0),
+ true = Tot0 =:= Tot1,
+
+ %% error case
+ ?badmap(a,fold,[_,0,a]) = (catch maps:fold(fun(_,_,_) -> ok end,0,id(a))),
+ ?badarg(fold,[<<>>,0,#{}]) = (catch maps:fold(id(<<>>),0,#{})),
ok.
+
+t_map_2(Config) when is_list(Config) ->
+ Vs = lists:seq(1,200),
+ M0 = maps:from_list([{{k,I},I}||I<-Vs]),
+ #{ {k,1} := 1, {k,200} := 200} = M0,
+ M1 = maps:map(fun({k,_},V) -> V + 42 end, M0),
+ #{ {k,1} := 43, {k,200} := 242} = M1,
+
+ %% error case
+ ?badmap(a,map,[_,a]) = (catch maps:map(fun(_,_) -> ok end, id(a))),
+ ?badarg(map,[<<>>,#{}]) = (catch maps:map(id(<<>>),#{})),
+ ok.
+
+
+t_size_1(Config) when is_list(Config) ->
+ 0 = maps:size(#{}),
+ 10 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,10)])),
+ 20 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,20)])),
+ 30 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,30)])),
+ 40 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,40)])),
+ 50 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,50)])),
+ 60 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,60)])),
+ 600 = maps:size(maps:from_list([{{"k",I},I}||I<-lists:seq(1,600)])),
+
+ %% error case
+ ?badmap(a,size,[a]) = (catch maps:size(id(a))),
+ ?badmap(<<>>,size,[<<>>]) = (catch maps:size(id(<<>>))),
+ ok.
+
+id(I) -> I.
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index 1577caa80f..f02e82b39c 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/naughty_child.erl b/lib/stdlib/test/naughty_child.erl
index b939436bfc..0ea8f81d38 100644
--- a/lib/stdlib/test/naughty_child.erl
+++ b/lib/stdlib/test/naughty_child.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/proc_lib_SUITE.erl b/lib/stdlib/test/proc_lib_SUITE.erl
index 8dca69bac4..f7a6a38138 100644
--- a/lib/stdlib/test/proc_lib_SUITE.erl
+++ b/lib/stdlib/test/proc_lib_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -27,7 +28,7 @@
init_per_group/2,end_per_group/2,
crash/1, sync_start_nolink/1, sync_start_link/1,
spawn_opt/1, sp1/0, sp2/0, sp3/1, sp4/2, sp5/1,
- hibernate/1]).
+ hibernate/1, stop/1, t_format/1]).
-export([ otp_6345/1, init_dont_hang/1]).
-export([hib_loop/1, awaken/1]).
@@ -38,6 +39,7 @@
-export([otp_6345_init/1, init_dont_hang_init/1]).
+-export([system_terminate/4]).
-ifdef(STANDALONE).
-define(line, noop, ).
@@ -49,7 +51,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[crash, {group, sync_start}, spawn_opt, hibernate,
- {group, tickets}].
+ {group, tickets}, stop, t_format].
groups() ->
[{tickets, [], [otp_6345, init_dont_hang]},
@@ -78,77 +80,123 @@ end_per_group(_GroupName, Config) ->
crash(Config) when is_list(Config) ->
error_logger:add_report_handler(?MODULE, self()),
- Pid = proc_lib:spawn(?MODULE, sp1, []),
- Pid ! die,
- ?line Report = receive
- {crash_report, Pid, Report0} -> Report0
- after 2000 -> test_server:fail(no_crash_report)
- end,
- ?line proc_lib:format(Report),
- ?line [PidRep, []] = Report,
- ?line {value, {initial_call,{?MODULE,sp1,[]}}} =
- lists:keysearch(initial_call, 1, PidRep),
- Self = self(),
- ?line {value, {ancestors,[Self]}} =
- lists:keysearch(ancestors, 1, PidRep),
- ?line {value, {error_info,{exit,die,_StackTrace1}}} =
- lists:keysearch(error_info, 1, PidRep),
-
- F = fun sp1/0,
- Pid1 = proc_lib:spawn(node(), F),
- Pid1 ! die,
- ?line [PidRep1, []] = receive
- {crash_report, Pid1, Report1} -> Report1
- after 2000 -> test_server:fail(no_crash_report)
- end,
- ?line {value, {initial_call,{Fmod,Fname,[]}}} =
- lists:keysearch(initial_call, 1, PidRep1),
- ?line {module,Fmod} = erlang:fun_info(F, module),
- ?line {name,Fname} = erlang:fun_info(F, name),
- ?line {value, {ancestors,[Self]}} =
- lists:keysearch(ancestors, 1, PidRep1),
- ?line {value, {error_info,{exit,die,_StackTrace2}}} =
- lists:keysearch(error_info, 1, PidRep1),
-
- Pid2 = proc_lib:spawn(?MODULE, sp2, []),
- test_server:sleep(100),
- ?line {?MODULE,sp2,[]} = proc_lib:initial_call(Pid2),
- ?line {?MODULE,sp2,0} = proc_lib:translate_initial_call(Pid2),
- Pid2 ! die,
- ?line [Pid2Rep, [{neighbour, LinkRep}]] =
- receive
- {crash_report, Pid2, Report2} -> Report2
- after 2000 -> test_server:fail(no_crash_report)
- end,
- ?line {value, {initial_call,{?MODULE,sp2,[]}}} =
- lists:keysearch(initial_call, 1, Pid2Rep),
- ?line {value, {ancestors,[Self]}} =
- lists:keysearch(ancestors, 1, Pid2Rep),
- ?line {value, {error_info,{exit,die,_StackTrace3}}} =
- lists:keysearch(error_info, 1, Pid2Rep),
- ?line {value, {initial_call,{?MODULE,sp1,[]}}} =
- lists:keysearch(initial_call, 1, LinkRep),
-
%% Make sure that we don't get a crash report if a process
%% terminates with reason 'shutdown' or reason {shutdown,Reason}.
- ?line process_flag(trap_exit, true),
- ?line Pid3 = proc_lib:spawn_link(erlang, apply,
- [fun() -> exit(shutdown) end,[]]),
+ process_flag(trap_exit, true),
+ Pid0 = proc_lib:spawn_link(erlang, apply,
+ [fun() -> exit(shutdown) end,[]]),
+ Pid1 = proc_lib:spawn_link(erlang, apply,
+ [fun() -> exit({shutdown,{a,b,c}}) end,[]]),
+
+ receive {'EXIT',Pid0,shutdown} -> ok end,
+ receive {'EXIT',Pid1,{shutdown,{a,b,c}}} -> ok end,
+ process_flag(trap_exit, false),
+ %% We expect any unexpected messages to be caught below,
+ %% so we don't have explicitly wait some time to be sure.
+
+ %% Spawn export function.
+ Pid2 = proc_lib:spawn(?MODULE, sp1, []),
+ Pid2 ! die,
+ Exp2 = [{initial_call,{?MODULE,sp1,[]}},
+ {ancestors,[self()]},
+ {error_info,{exit,die,{stacktrace}}}],
+ analyse_crash(Pid2, Exp2, []),
- ?line Pid4 = proc_lib:spawn_link(erlang, apply,
- [fun() -> exit({shutdown,{a,b,c}}) end,[]]),
+ %% Spawn fun.
+ F = fun sp1/0,
+ Pid3 = proc_lib:spawn(node(), F),
+ Pid3 ! die,
+ {module,?MODULE} = erlang:fun_info(F, module),
+ {name,Fname} = erlang:fun_info(F, name),
+ Exp3 = [{initial_call,{?MODULE,Fname,[]}},
+ {ancestors,[self()]},
+ {error_info,{exit,die,{stacktrace}}}],
+ analyse_crash(Pid3, Exp3, []),
- ?line receive {'EXIT',Pid3,shutdown} -> ok end,
- ?line receive {'EXIT',Pid4,{shutdown,{a,b,c}}} -> ok end,
- ?line process_flag(trap_exit, false),
+ %% Spawn function with neighbour.
+ Pid4 = proc_lib:spawn(?MODULE, sp2, []),
+ test_server:sleep(100),
+ {?MODULE,sp2,[]} = proc_lib:initial_call(Pid4),
+ {?MODULE,sp2,0} = proc_lib:translate_initial_call(Pid4),
+ Pid4 ! die,
+ Exp4 = [{initial_call,{?MODULE,sp2,[]}},
+ {ancestors,[self()]},
+ {error_info,{exit,die,{stacktrace}}}],
+ Links4 = [[{initial_call,{?MODULE,sp1,[]}},
+ {ancestors,[Pid4,self()]}]],
+ analyse_crash(Pid4, Exp4, Links4),
+
+ %% Make sure that we still get a crash report if the
+ %% process dictionary have been tampered with.
+
+ Pid5 = proc_lib:spawn(erlang, apply,
+ [fun() ->
+ erase(),
+ exit(abnormal)
+ end,[]]),
+ Exp5 = [{initial_call,absent},
+ {ancestors,[]},
+ {error_info,{exit,abnormal,{stacktrace}}}],
+ analyse_crash(Pid5, Exp5, []),
+
+ error_logger:delete_report_handler(?MODULE),
+ ok.
+analyse_crash(Pid, Expected0, ExpLinks) ->
+ Expected = [{pid,Pid}|Expected0],
receive
- Any ->
- ?line ?t:fail({unexpected_message,Any})
- after 2000 ->
- ok
- end.
+ {crash_report, Pid, Report} ->
+ _ = proc_lib:format(Report), %Smoke test.
+ [Crash,Links] = Report,
+ analyse_crash_1(Expected, Crash),
+ analyse_links(ExpLinks, Links);
+ Unexpected ->
+ io:format("~p\n", [Unexpected]),
+ test_server:fail(unexpected_message)
+ after 5000 ->
+ test_server:fail(no_crash_report)
+ end.
+
+analyse_links([H|Es], [{neighbour,N}|Links]) ->
+ analyse_crash_1(H, N),
+ analyse_links(Es, Links);
+analyse_links([], []) ->
+ ok.
+analyse_crash_1([{Key,absent}|T], Report) ->
+ false = lists:keymember(Key, 1, Report),
+ analyse_crash_1(T, Report);
+analyse_crash_1([{Key,Pattern}|T], Report) ->
+ case lists:keyfind(Key, 1, Report) of
+ false ->
+ io:format("~p", [Report]),
+ test_server:fail({missing_key,Key});
+ {Key,Info} ->
+ try
+ match_info(Pattern, Info)
+ catch
+ no_match ->
+ io:format("key: ~p", [Key]),
+ io:format("pattern: ~p", [Pattern]),
+ io:format("actual: ~p", [Report]),
+ test_server:fail(no_match)
+ end,
+ analyse_crash_1(T, Report)
+ end;
+analyse_crash_1([], _Report) ->
+ [].
+
+match_info(T, T) ->
+ ok;
+match_info({stacktrace}, Stk) when is_list(Stk) ->
+ ok;
+match_info([H1|T1], [H2|T2]) ->
+ match_info(H1, H2),
+ match_info(T1, T2);
+match_info(Tuple1, Tuple2) when tuple_size(Tuple1) =:= tuple_size(Tuple2) ->
+ match_info(tuple_to_list(Tuple1), tuple_to_list(Tuple2));
+match_info(_, _) ->
+ throw(no_match).
sync_start_nolink(Config) when is_list(Config) ->
_Pid = spawn_link(?MODULE, sp5, [self()]),
@@ -299,6 +347,7 @@ hibernate(Config) when is_list(Config) ->
?line {value,{initial_call,{?MODULE,hib_loop,[_]}}} =
lists:keysearch(initial_call, 1, Report),
+ error_logger:delete_report_handler(?MODULE),
ok.
hib_loop(LoopData) ->
@@ -361,10 +410,139 @@ init_dont_hang(Config) when is_list(Config) ->
exit(Error)
end.
-init_dont_hang_init(Parent) ->
- 1 = 2.
+init_dont_hang_init(_Parent) ->
+ error(bad_init).
+
+%% Test proc_lib:stop/1,3
+stop(_Config) ->
+ Parent = self(),
+ SysMsgProc =
+ fun() ->
+ receive
+ {system,From,Request} ->
+ sys:handle_system_msg(Request,From,Parent,?MODULE,[],[])
+ end
+ end,
+
+ %% Normal case:
+ %% Process handles system message and terminated with given reason
+ Pid1 = proc_lib:spawn(SysMsgProc),
+ ok = proc_lib:stop(Pid1),
+ false = erlang:is_process_alive(Pid1),
+
+ %% Process does not exit
+ {'EXIT',noproc} = (catch proc_lib:stop(Pid1)),
+
+ %% Badly handled system message
+ DieProc =
+ fun() ->
+ receive
+ {system,_From,_Request} ->
+ exit(die)
+ end
+ end,
+ Pid2 = proc_lib:spawn(DieProc),
+ {'EXIT',{die,_}} = (catch proc_lib:stop(Pid2)),
+
+ %% Hanging process => timeout
+ HangProc =
+ fun() ->
+ receive
+ {system,_From,_Request} ->
+ timer:sleep(5000)
+ end
+ end,
+ Pid3 = proc_lib:spawn(HangProc),
+ {'EXIT',timeout} = (catch proc_lib:stop(Pid3,normal,1000)),
+
+ %% Success case with other reason than 'normal'
+ Pid4 = proc_lib:spawn(SysMsgProc),
+ ok = proc_lib:stop(Pid4,other_reason,infinity),
+ false = erlang:is_process_alive(Pid4),
+
+ %% 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)),
+ false = erlang:is_process_alive(Pid5),
+
+ %% Local registered name
+ Pid6 = proc_lib:spawn(SysMsgProc),
+ register(to_stop,Pid6),
+ ok = proc_lib:stop(to_stop),
+ undefined = whereis(to_stop),
+ false = erlang:is_process_alive(Pid6),
+
+ %% Remote registered name
+ {ok,Node} = test_server:start_node(proc_lib_SUITE_stop,slave,[]),
+ Dir = filename:dirname(code:which(?MODULE)),
+ rpc:call(Node,code,add_path,[Dir]),
+ Pid7 = spawn(Node,SysMsgProc),
+ true = rpc:call(Node,erlang,register,[to_stop,Pid7]),
+ Pid7 = rpc:call(Node,erlang,whereis,[to_stop]),
+ ok = proc_lib:stop({to_stop,Node}),
+ undefined = rpc:call(Node,erlang,whereis,[to_stop]),
+ false = rpc:call(Node,erlang,is_process_alive,[Pid7]),
+
+ %% Local and remote registered name, but non-existing
+ {'EXIT',noproc} = (catch proc_lib:stop(to_stop)),
+ {'EXIT',noproc} = (catch proc_lib:stop({to_stop,Node})),
+
+ true = test_server:stop_node(Node),
+
+ %% Remote registered name, but non-existing node
+ {'EXIT',{{nodedown,Node},_}} = (catch proc_lib:stop({to_stop,Node})),
+ ok.
+
+system_terminate(crash,_Parent,_Deb,_State) ->
+ error({badmatch,2});
+system_terminate(Reason,_Parent,_Deb,_State) ->
+ exit(Reason).
+t_format(_Config) ->
+ error_logger:tty(false),
+ try
+ t_format()
+ after
+ error_logger:tty(true)
+ end,
+ ok.
+
+t_format() ->
+ error_logger:add_report_handler(?MODULE, self()),
+ Pid = proc_lib:spawn(fun t_format_looper/0),
+ HugeData = gb_sets:from_list(lists:seq(1, 100)),
+ Pid ! {die,HugeData},
+ Report = receive
+ {crash_report, Pid, Report0} -> Report0
+ end,
+ Usz = do_test_format(Report, unlimited),
+ Tsz = do_test_format(Report, 20),
+
+ if
+ Tsz >= Usz ->
+ ?t:fail();
+ true ->
+ ok
+ end,
+
+ ok.
+
+do_test_format(Report, Depth) ->
+ io:format("*** Depth = ~p", [Depth]),
+ S0 = proc_lib:format(Report, latin1, Depth),
+ S = lists:flatten(S0),
+ io:put_chars(S),
+ length(S).
+
+t_format_looper() ->
+ receive
+ {die,Data} ->
+ exit(Data);
+ _ ->
+ t_format_looper()
+ end.
%%-----------------------------------------------------------------
%% The error_logger handler used.
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index 37fbb5267b..52fdb69b73 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -73,6 +74,7 @@
otp_5644/1, otp_5195/1, otp_6038_bug/1, otp_6359/1, otp_6562/1,
otp_6590/1, otp_6673/1, otp_6964/1, otp_7114/1, otp_7238/1,
otp_7232/1, otp_7552/1, otp_6674/1, otp_7714/1, otp_11758/1,
+ otp_12946/1,
manpage/1,
@@ -142,7 +144,7 @@ groups() ->
{tickets, [],
[otp_5644, otp_5195, otp_6038_bug, otp_6359, otp_6562,
otp_6590, otp_6673, otp_6964, otp_7114, otp_7232,
- otp_7238, otp_7552, otp_6674, otp_7714, otp_11758]},
+ otp_7238, otp_7552, otp_6674, otp_7714, otp_11758, otp_12946]},
{compat, [], [backward, forward]}].
init_per_suite(Config) ->
@@ -396,7 +398,8 @@ nomatch(Config) when is_list(Config) ->
qlc:q([3 || {3=4} <- []]).
">>,
[],
- {warnings,[{{2,27},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,27},qlc,nomatch_pattern}]}},
+ {warnings,[{2,v3_core,nomatch}]}},
{nomatch2,
<<"nomatch() ->
@@ -407,7 +410,8 @@ nomatch(Config) when is_list(Config) ->
end, [{1},{2}]).
">>,
[],
- {warnings,[{{3,33},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{3,33},qlc,nomatch_pattern}]}},
+ {warnings,[{3,v3_core,nomatch}]}},
{nomatch3,
<<"nomatch() ->
@@ -419,7 +423,8 @@ nomatch(Config) when is_list(Config) ->
end, [{1,2},{2,3}]).
">>,
[],
- {warnings,[{{3,52},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{3,52},qlc,nomatch_pattern}]}},
+ {warnings,[{3,v3_core,nomatch}]}},
{nomatch4,
<<"nomatch() ->
@@ -2487,8 +2492,11 @@ info(Config) when is_list(Config) ->
(catch qlc:info([X || {X} <- []], {n_elements, 0})),
L = lists:seq(1, 1000),
\"[1,2,3,4,5,6,7,8,9,10|'...']\" = qlc:info(L, {n_elements, 10}),
- {cons,1,{integer,1,1},{atom,1,'...'}} =
+ {cons,A1,{integer,A2,1},{atom,A3,'...'}} =
qlc:info(L, [{n_elements, 1},{format,abstract_code}]),
+ 1 = erl_anno:line(A1),
+ 1 = erl_anno:line(A2),
+ 1 = erl_anno:line(A3),
Q = qlc:q([{X} || X <- [a,b,c,d,e,f]]),
{call,_,_,[{cons,_,{atom,_,a},{cons,_,{atom,_,b},{cons,_,{atom,_,c},
{atom,_,'...'}}}},
@@ -2905,7 +2913,8 @@ lookup1(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1},{a}])">>,
- {warnings,[{{2,37},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,37},qlc,nomatch_pattern}]}},
+ []},
<<"etsc(fun(E) ->
Q = qlc:q([X || {X=X,Y=Y}={Y=Y,X=X} <- ets:table(E),
@@ -2933,7 +2942,8 @@ lookup1(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{a},{b}])">>,
- {warnings,[{{2,35},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,35},qlc,nomatch_pattern}]}},
+ []},
{cres,
<<"etsc(fun(E) ->
@@ -2941,7 +2951,8 @@ lookup1(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{a},{b}])">>,
- {warnings,[{{2,35},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,35},qlc,nomatch_pattern}]}},
+ []},
<<"etsc(fun(E) ->
Q = qlc:q([X || X = <<X>> <- ets:table(E)]),
@@ -2988,7 +2999,8 @@ lookup1(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{a,b,c},{d,e,f}])">>,
- {warnings,[{{2,34},qlc,nomatch_pattern}]}}
+ %% {warnings,[{{2,34},qlc,nomatch_pattern}]}}
+ []}
],
?line run(Config, Ts),
@@ -3021,8 +3033,9 @@ lookup2(Config) when is_list(Config) ->
end, [{3,true},{4,true}])">>,
<<"%% Only guards are inspected. No lookup.
- E1 = create_ets(1, 10),
- E2 = ets:new(join, []),
+ E1 = ets:new(e, [ordered_set]),
+ true = ets:insert(E1, [{1,1}, {2,2}, {3,3}, {4,4}, {5,5}]),
+ E2 = ets:new(join, [ordered_set]),
true = ets:insert(E2, [{true,1},{false,2}]),
Q = qlc:q([{X,Z} || {_,X} <- ets:table(E1),
{Y,Z} <- ets:table(E2),
@@ -3051,7 +3064,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1}, {2}])">>,
- {warnings,[{{3,46},qlc,nomatch_filter}]}},
+ %% {warnings,[{{3,46},qlc,nomatch_filter}]}},
+ []},
{cres,
<<"etsc(fun(E) ->
@@ -3060,7 +3074,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1}, {2}])">>,
- {warnings,[{{3,43},qlc,nomatch_filter}]}},
+ %% {warnings,[{{3,43},qlc,nomatch_filter}]}},
+ []},
{cres,
<<"etsc(fun(E) ->
@@ -3069,7 +3084,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1}, {2}])">>,
- {warnings,[{{3,48},qlc,nomatch_filter}]}},
+ %% {warnings,[{{3,48},qlc,nomatch_filter}]}},
+ []},
<<"etsc(fun(E) ->
Q = qlc:q([{X,Y} || {X,Y} <- ets:table(E),
@@ -3084,7 +3100,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{[3]},{[3,4]}])">>,
- {warnings,[{{2,61},qlc,nomatch_filter}]}},
+ %% {warnings,[{{2,61},qlc,nomatch_filter}]}},
+ []},
<<"etsc(fun(E) ->
U = 18,
@@ -3116,7 +3133,8 @@ lookup2(Config) when is_list(Config) ->
[] = lists:sort(qlc:e(Q)),
false = lookup_keys(Q)
end, [{2},{3},{4},{8}])">>,
- {warnings,[{{4,44},qlc,nomatch_filter}]}},
+ %% {warnings,[{{4,44},qlc,nomatch_filter}]}},
+ []},
{cres,
<<"etsc(fun(E) ->
@@ -3126,7 +3144,8 @@ lookup2(Config) when is_list(Config) ->
[] = lists:sort(qlc:e(Q)),
false = lookup_keys(Q)
end, [{2},{3},{4},{8}])">>,
- {warnings,[{{4,35},qlc,nomatch_filter}]}},
+ %% {warnings,[{{4,35},qlc,nomatch_filter}]}},
+ []},
<<"F = fun(U) ->
Q = qlc:q([X || {X} <- [a,b,c],
@@ -3142,7 +3161,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1,1},{2,1}])">>,
- {warnings,[{{2,61},qlc,nomatch_filter}]}},
+ %% {warnings,[{{2,61},qlc,nomatch_filter}]}},
+ []},
<<"Two = 2.0,
etsc(fun(E) ->
@@ -3203,8 +3223,10 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1,b},{2,3}])">>,
+ %% {warnings,[{2,sys_core_fold,nomatch_guard},
+ %% {3,qlc,nomatch_filter},
+ %% {3,sys_core_fold,{eval_failure,badarg}}]}},
{warnings,[{2,sys_core_fold,nomatch_guard},
- {3,qlc,nomatch_filter},
{3,sys_core_fold,{eval_failure,badarg}}]}},
<<"etsc(fun(E) ->
@@ -3227,7 +3249,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{{1}},{{2}}])">>,
- {warnings,[{{4,47},qlc,nomatch_filter}]}},
+ %% {warnings,[{{4,47},qlc,nomatch_filter}]}},
+ []},
{cres,
<<"etsc(fun(E) ->
@@ -3237,7 +3260,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{{1}},{{2}}])">>,
- {warnings,[{{4,47},qlc,nomatch_filter}]}},
+ %% {warnings,[{{4,47},qlc,nomatch_filter}]}},
+ []},
<<"etsc(fun(E) ->
Q = qlc:q([X || {X} <- ets:table(E),
@@ -3297,7 +3321,8 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{3}, {4}])">>,
- {warnings,[{{3,44},qlc,nomatch_filter}]}},
+ %% {warnings,[{{3,44},qlc,nomatch_filter}]}},
+ []},
<<"etsc(fun(E) ->
Q = qlc:q([X || {{X,Y}} <- ets:table(E),
@@ -3418,7 +3443,8 @@ lookup2(Config) when is_list(Config) ->
end, [{1},{2}])">>
],
- ?line run(Config, Ts),
+
+ ok = run(Config, Ts),
TsR = [
%% is_record/2,3:
@@ -3456,7 +3482,8 @@ lookup2(Config) when is_list(Config) ->
end, [{keypos,1}], [#r{}])">>
],
- ?line run(Config, <<"-record(r, {a}).\n">>, TsR),
+
+ ok = run(Config, <<"-record(r, {a}).\n">>, TsR),
Ts2 = [
<<"etsc(fun(E) ->
@@ -3566,7 +3593,6 @@ lookup2(Config) when is_list(Config) ->
[{1,2},{2,2}] = qlc:e(Q),
[2] = lookup_keys(Q)
end, [{keypos,1}], [{1},{2},{3}])">>,
-
<<"%% Matchspec only. No cache.
etsc(fun(E) ->
Q = qlc:q([{X,Y} ||
@@ -3578,7 +3604,7 @@ lookup2(Config) when is_list(Config) ->
{generate,_,
{table,{ets,_,[_,[{traverse,_}]]}}}],[]} =
i(Q),
- [{1,2},{1,3},{2,2},{2,3}] = qlc:e(Q),
+ [{1,2},{1,3},{2,2},{2,3}] = lists:sort(qlc:e(Q)),
false = lookup_keys(Q)
end, [{keypos,1}], [{1},{2},{3}])">>,
<<"%% Matchspec only. Cache
@@ -3592,7 +3618,7 @@ lookup2(Config) when is_list(Config) ->
{generate,_,{qlc,_,
[{generate,_,{table,{ets,_,[_,[{traverse,_}]]}}}],
[{cache,ets}]}}],[]} = i(Q),
- [{1,2},{1,3},{2,2},{2,3}] = qlc:e(Q),
+ [{1,2},{1,3},{2,2},{2,3}] = lists:sort(qlc:e(Q)),
false = lookup_keys(Q)
end, [{keypos,1}], [{1},{2},{3}])">>,
<<"%% An empty list. Always unique and cached.
@@ -3645,7 +3671,7 @@ lookup2(Config) when is_list(Config) ->
],
- ?line run(Config, Ts2),
+ ok = run(Config, Ts2),
LTs = [
<<"etsc(fun(E) ->
@@ -3677,7 +3703,8 @@ lookup2(Config) when is_list(Config) ->
end, [{1,a},{2,b}])">>
],
- ?line run(Config, LTs),
+
+ ok = run(Config, LTs),
ok.
@@ -3700,7 +3727,8 @@ lookup_rec(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{keypos,2}], [#r{a = 17}, #r{a = 3}, #r{a = 5}])">>,
- {warnings,[{{4,44},qlc,nomatch_filter}]}},
+ %% {warnings,[{{4,44},qlc,nomatch_filter}]}},
+ []},
<<"%% Compares an integer and a float.
etsc(fun(E) ->
@@ -4004,7 +4032,8 @@ skip_filters(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1,1},{2,0}])">>,
- {warnings,[{{4,37},qlc,nomatch_filter}]}},
+ %% {warnings,[{{4,37},qlc,nomatch_filter}]}},
+ []},
<<"etsc(fun(E) ->
Q = qlc:q([{A,B,C} ||
@@ -6093,7 +6122,7 @@ otp_6964(Config) when is_list(Config) ->
lists:flatten(qlc:format_error(ErrReply)),
qlc_SUITE:install_error_logger(),
20000 = length(F(warning_msg)),
- {error, joining} = qlc_SUITE:read_error_logger(),
+ {warning, joining} = qlc_SUITE:read_error_logger(),
20000 = length(F(info_msg)),
{info, joining} = qlc_SUITE:read_error_logger(),
20000 = length(F(error_msg)),
@@ -6128,8 +6157,8 @@ otp_6964(Config) when is_list(Config) ->
{error, caching} = qlc_SUITE:read_error_logger(),
{error, caching} = qlc_SUITE:read_error_logger(),
1 = length(F(warning_msg)),
- {error, caching} = qlc_SUITE:read_error_logger(),
- {error, caching} = qlc_SUITE:read_error_logger(),
+ {warning, caching} = qlc_SUITE:read_error_logger(),
+ {warning, caching} = qlc_SUITE:read_error_logger(),
1 = length(F(info_msg)),
{info, caching} = qlc_SUITE:read_error_logger(),
{info, caching} = qlc_SUITE:read_error_logger(),
@@ -6161,7 +6190,7 @@ otp_6964(Config) when is_list(Config) ->
L = F(info_msg),
{info, sorting} = qlc_SUITE:read_error_logger(),
L = F(warning_msg),
- {error, sorting} = qlc_SUITE:read_error_logger(),
+ {warning, sorting} = qlc_SUITE:read_error_logger(),
qlc_SUITE:uninstall_error_logger(),
ets:delete(E1),
ets:delete(E2)">>],
@@ -6188,7 +6217,7 @@ otp_6964(Config) when is_list(Config) ->
R = lists:sort(F(error_msg)),
{error, caching} = qlc_SUITE:read_error_logger(),
R = lists:sort(F(warning_msg)),
- {error, caching} = qlc_SUITE:read_error_logger(),
+ {warning, caching} = qlc_SUITE:read_error_logger(),
qlc_SUITE:uninstall_error_logger(),
ErrReply = F(not_allowed),
{error,qlc,{tmpdir_usage,caching}} = ErrReply,
@@ -6217,8 +6246,9 @@ otp_7238(Config) when is_list(Config) ->
<<"nomatch_1() ->
{qlc:q([X || X={X} <- []]), [t || \"a\"=\"b\" <- []]}.">>,
[],
- {warnings,[{{2,30},qlc,nomatch_pattern},
- {{2,44},v3_core,nomatch}]}},
+ %% {warnings,[{{2,30},qlc,nomatch_pattern},
+ %% {{2,44},v3_core,nomatch}]}},
+ {warnings,[{2,v3_core,nomatch}]}},
%% Not found by qlc...
{nomatch_2,
@@ -6231,7 +6261,8 @@ otp_7238(Config) when is_list(Config) ->
<<"nomatch_3() ->
qlc:q([t || [$a, $b] = \"ba\" <- []]).">>,
[],
- {warnings,[{{2,37},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,37},qlc,nomatch_pattern}]}},
+ {warnings,[{2,v3_core,nomatch}]}},
%% Not found by qlc...
{nomatch_4,
@@ -6252,44 +6283,51 @@ otp_7238(Config) when is_list(Config) ->
qlc:q([X || X <- [],
X =:= {X}]).">>,
[],
- {warnings,[{{3,30},qlc,nomatch_filter}]}},
+ %% {warnings,[{{3,30},qlc,nomatch_filter}]}},
+ []},
{nomatch_7,
<<"nomatch_7() ->
qlc:q([X || {X=Y,{Y}=X} <- []]).">>,
[],
- {warnings,[{{2,28},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,28},qlc,nomatch_pattern}]}},
+ []},
{nomatch_8,
<<"nomatch_8() ->
qlc:q([X || {X={},X=[]} <- []]).">>,
[],
- {warnings,[{{2,28},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,28},qlc,nomatch_pattern}]}},
+ []},
{nomatch_9,
<<"nomatch_9() ->
qlc:q([X || X <- [], X =:= {}, X =:= []]).">>,
[],
- {warnings,[{{2,49},qlc,nomatch_filter}]}},
+ %% {warnings,[{{2,49},qlc,nomatch_filter}]}},
+ []},
{nomatch_10,
<<"nomatch_10() ->
qlc:q([X || X <- [],
((X =:= 1) or (X =:= 2)) and (X =:= 3)]).">>,
[],
- {warnings,[{{3,53},qlc,nomatch_filter}]}},
+ %% {warnings,[{{3,53},qlc,nomatch_filter}]}},
+ []},
{nomatch_11,
<<"nomatch_11() ->
qlc:q([X || X <- [], x =:= []]).">>,
[],
- {warnings,[{{2,39},qlc,nomatch_filter}]}},
+ %% {warnings,[{{2,39},qlc,nomatch_filter}]}},
+ {warnings,[{2,sys_core_fold,nomatch_guard}]}},
{nomatch_12,
<<"nomatch_12() ->
qlc:q([X || X={} <- [], X =:= []]).">>,
[],
- {warnings,[{{2,42},qlc,nomatch_filter}]}},
+ %% {warnings,[{{2,42},qlc,nomatch_filter}]}},
+ []},
{nomatch_13,
<<"nomatch_13() ->
@@ -6297,8 +6335,9 @@ otp_7238(Config) when is_list(Config) ->
X={X} <- [],
Y={Y} <- []]).">>,
[],
- {warnings,[{{3,29},qlc,nomatch_pattern},
- {{4,29},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{3,29},qlc,nomatch_pattern},
+ %% {{4,29},qlc,nomatch_pattern}]}},
+ []},
{nomatch_14,
<<"nomatch_14() ->
@@ -6306,7 +6345,8 @@ otp_7238(Config) when is_list(Config) ->
1 > 0,
1 > X]).">>,
[],
- {warnings,[{{2,29},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,29},qlc,nomatch_pattern}]}},
+ []},
{nomatch_15,
<<"nomatch_15() ->
@@ -6315,7 +6355,8 @@ otp_7238(Config) when is_list(Config) ->
1 > 0,
1 > X]).">>,
[],
- {warnings,[{{2,32},qlc,nomatch_pattern}]}},
+ %% {warnings,[{{2,32},qlc,nomatch_pattern}]}},
+ []},
%% Template warning.
{nomatch_template1,
@@ -6553,18 +6594,19 @@ otp_7238(Config) when is_list(Config) ->
?line run(Config, T2),
T3 = [
- {nomatch_6,
- <<"nomatch_6() ->
- qlc:q([X || X <- [],
- X =:= {X}]).">>,
- [],
- {[],["filter evaluates to 'false'"]}},
-
- {nomatch_7,
- <<"nomatch_7() ->
- qlc:q([X || {X=Y,{Y}=X} <- []]).">>,
- [],
- {[],["pattern cannot possibly match"]}}],
+%% {nomatch_6,
+%% <<"nomatch_6() ->
+%% qlc:q([X || X <- [],
+%% X =:= {X}]).">>,
+%% [],
+%% {[],["filter evaluates to 'false'"]}},
+
+%% {nomatch_7,
+%% <<"nomatch_7() ->
+%% qlc:q([X || {X=Y,{Y}=X} <- []]).">>,
+%% [],
+%% {[],["pattern cannot possibly match"]}}
+ ],
?line compile_format(Config, T3),
%% *Very* simple test - just check that it doesn't crash.
@@ -6822,7 +6864,8 @@ otp_6674(Config) when is_list(Config) ->
A == 192, B =:= 192.0,
{Y} <- [{0},{1},{2}],
X == Y]),
- {block,0,
+ A0 = erl_anno:new(0),
+ {block,A0,
[{match,_,_,
{call,_,_,
[{lc,_,_,
@@ -7112,6 +7155,18 @@ otp_6674(Config) when is_list(Config) ->
?line run(Config, Ts).
+otp_12946(doc) ->
+ ["Syntax error."];
+otp_12946(suite) -> [];
+otp_12946(Config) when is_list(Config) ->
+ Text =
+ <<"-export([init/0]).
+ init() ->
+ ok.
+ y">>,
+ {errors,[{4,erl_parse,_}],[]} = compile_file(Config, Text, []),
+ ok.
+
manpage(doc) ->
"Examples from qlc(3).";
manpage(suite) -> [];
@@ -7392,7 +7447,8 @@ try_old_join_info(Config) ->
{ok, M} = compile:file(File, [{outdir, ?datadir}]),
{module, M} = code:load_abs(filename:rootname(File)),
H = M:create_handle(),
- {block,0,
+ A0 = erl_anno:new(0),
+ {block,A0,
[{match,_,_,
{call,_,_,
[{lc,_,_,
@@ -7772,8 +7828,8 @@ table(List, Indices, KeyPos, ParentFun) ->
end,
FormatFun = fun(all) ->
- L = 17,
- {call,L,{remote,L,{atom,1,?MODULE},{atom,L,the_list}},
+ L = erl_anno:new(17),
+ {call,L,{remote,L,{atom,L,?MODULE},{atom,L,the_list}},
[erl_parse:abstract(List, 17)]};
({lookup, Column, Values}) ->
{?MODULE, list_keys, [Values, Column, List]}
@@ -7891,7 +7947,7 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) ->
{module, _} = code:load_abs(AbsFile, Mod),
Ms0 = erlang:process_info(self(),messages),
- Before = {get(), pps(), ets:all(), Ms0},
+ Before = {{get(), ets:all(), Ms0}, pps()},
%% Prepare the check that the qlc module does not call qlc_pt.
_ = [unload_pt() || {file, Name} <- [code:is_loaded(qlc_pt)],
@@ -7921,12 +7977,29 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) ->
run_test(Config, Extra, Body) ->
run_test(Config, Extra, {cres,Body,[]}).
-wait_for_expected(R, Before, SourceFile, Wait) ->
+wait_for_expected(R, {Strict0,PPS0}=Before, SourceFile, Wait) ->
Ms = erlang:process_info(self(),messages),
- After = {get(), pps(), ets:all(), Ms},
+ After = {_,PPS1} = {{get(), ets:all(), Ms}, pps()},
case {R, After} of
{ok, Before} ->
ok;
+ {ok, {Strict0,_}} ->
+ {Ports0,Procs0} = PPS0,
+ {Ports1,Procs1} = PPS1,
+ case {Ports1 -- Ports0, Procs1 -- Procs0} of
+ {[], []} -> ok;
+ _ when Wait ->
+ timer:sleep(1000),
+ wait_for_expected(R, Before, SourceFile, false);
+ {PortsDiff,ProcsDiff} ->
+ io:format("failure, got ~p~n, expected ~p\n",
+ [PPS1, PPS0]),
+ show("Old port", Ports0 -- Ports1),
+ show("New port", PortsDiff),
+ show("Old proc", Procs0 -- Procs1),
+ show("New proc", ProcsDiff),
+ fail(SourceFile)
+ end;
_ when Wait ->
timer:sleep(1000),
wait_for_expected(R, Before, SourceFile, false);
@@ -7993,7 +8066,7 @@ compile_file(Config, Test0, Opts0) ->
case compile:file(File, Opts) of
{ok, _M, Ws} -> warnings(File, Ws);
{error, [{File,Es}], []} -> {errors, Es, []};
- {error, [{File,Es}], [{File,Ws}]} -> {error, Es, Ws}
+ {error, [{File,Es}], [{File,Ws}]} -> {errors, Es, Ws}
end.
comp_compare(T, T) ->
@@ -8058,6 +8131,17 @@ filename(Name, Config) when is_atom(Name) ->
filename(Name, Config) ->
filename:join(?privdir, Name).
+show(_S, []) ->
+ ok;
+show(S, [{Pid, Name, InitCall}|Pids]) when is_pid(Pid) ->
+ io:format("~s: ~w (~w), ~w: ~p~n",
+ [S, Pid, proc_reg_name(Name), InitCall,
+ erlang:process_info(Pid)]),
+ show(S, Pids);
+show(S, [{Port, _}|Ports]) when is_port(Port)->
+ io:format("~s: ~w: ~p~n", [S, Port, erlang:port_info(Port)]),
+ show(S, Ports).
+
pps() ->
{port_list(), process_list()}.
@@ -8070,6 +8154,9 @@ process_list() ->
safe_second_element(process_info(P, initial_call))} ||
P <- processes(), is_process_alive(P)].
+proc_reg_name({registered_name, Name}) -> Name;
+proc_reg_name([]) -> no_reg_name.
+
safe_second_element({_,Info}) -> Info;
safe_second_element(Other) -> Other.
@@ -8105,6 +8192,8 @@ read_error_logger() ->
{error, Why};
{info, Why} ->
{info, Why};
+ {warning, Why} ->
+ {warning, Why};
{error, Pid, Tuple} ->
{error, Pid, Tuple}
after 1000 ->
@@ -8119,8 +8208,7 @@ read_error_logger() ->
init(Tester) ->
{ok, Tester}.
-handle_event({error, _GL, {_Pid, _Msg, [Why, _]}}, Tester)
- when is_atom(Why) ->
+handle_event({error, _GL, {_Pid, _Msg, [Why, _]}}, Tester) when is_atom(Why) ->
Tester ! {error, Why},
{ok, Tester};
handle_event({error, _GL, {_Pid, _Msg, [P, T]}}, Tester) when is_pid(P) ->
@@ -8129,6 +8217,9 @@ handle_event({error, _GL, {_Pid, _Msg, [P, T]}}, Tester) when is_pid(P) ->
handle_event({info_msg, _GL, {_Pid, _Msg, [Why, _]}}, Tester) ->
Tester ! {info, Why},
{ok, Tester};
+handle_event({warning_msg, _GL, {_Pid, _Msg, [Why, _]}}, Tester) when is_atom(Why) ->
+ Tester ! {warning, Why},
+ {ok, Tester};
handle_event(_Event, State) ->
{ok, State}.
diff --git a/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl b/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl
index 56c998f761..d0cbc65d26 100644
--- a/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl
+++ b/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index 3d3152919a..c965a8b218 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl
new file mode 100644
index 0000000000..03b5ce1a25
--- /dev/null
+++ b/lib/stdlib/test/rand_SUITE.erl
@@ -0,0 +1,540 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.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(rand_SUITE).
+-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([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
+ ]).
+
+-export([test/0, gen/1]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(3)).
+-define(LOOP, 1000000).
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [seed, interval_int, interval_float,
+ api_eq,
+ reference,
+ {group, basic_stats},
+ plugin, measure
+ ].
+
+groups() ->
+ [{basic_stats, [parallel],
+ [basic_stats_uniform_1, basic_stats_uniform_2, basic_stats_normal]}].
+
+init_per_suite(Config) -> Config.
+end_per_suite(_Config) -> ok.
+
+init_per_group(_GroupName, Config) -> Config.
+end_per_group(_GroupName, Config) -> Config.
+
+%% 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).
+
+algs() ->
+ [exs64, exsplus, exs1024].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+seed(doc) ->
+ ["Test that seed and seed_s and export_seed/0 is working."];
+seed(suite) ->
+ [];
+seed(Config) when is_list(Config) ->
+ Algs = algs(),
+ Test = fun(Alg) ->
+ try seed_1(Alg)
+ catch _:Reason ->
+ test_server:fail({Alg, Reason, erlang:get_stacktrace()})
+ end
+ end,
+ [Test(Alg) || Alg <- Algs],
+ ok.
+
+seed_1(Alg) ->
+ %% Check that uniform seeds automatically,
+ _ = rand:uniform(),
+ S00 = get(rand_seed),
+ erase(),
+ _ = rand:uniform(),
+ false = S00 =:= get(rand_seed), %% hopefully
+
+ %% Choosing algo and seed
+ S0 = rand:seed(Alg, {0, 0, 0}),
+ %% Check that (documented?) process_dict variable is correct
+ S0 = get(rand_seed),
+ S0 = rand:seed_s(Alg, {0, 0, 0}),
+ %% Check that process_dict should not be used for seed_s functionality
+ _ = rand:seed_s(Alg, {1, 0, 0}),
+ S0 = get(rand_seed),
+ %% Test export
+ ES0 = rand:export_seed(),
+ ES0 = rand:export_seed_s(S0),
+ S0 = rand:seed(ES0),
+ S0 = rand:seed_s(ES0),
+ %% seed/1 calls should be unique
+ S1 = rand:seed(Alg),
+ false = (S1 =:= rand:seed_s(Alg)),
+ %% Negative integers works
+ _ = rand:seed_s(Alg, {-1,-1,-1}),
+ %% Check that export_seed/1 returns 'undefined' if there is no seed
+ erase(rand_seed),
+ undefined = rand:export_seed(),
+
+ %% Other term do not work
+ {'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())),
+ {'EXIT', _} = (catch rand:seed_s(Alg, {asd, 1, 1})),
+ {'EXIT', _} = (catch rand:seed_s(Alg, {0, 234.1234, 1})),
+ {'EXIT', _} = (catch rand:seed_s(Alg, {0, 234, [1, 123, 123]})),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+api_eq(doc) ->
+ ["Check that both api's are consistent with each other."];
+api_eq(suite) ->
+ [];
+api_eq(_Config) ->
+ Algs = algs(),
+ Small = fun(Alg) ->
+ Seed = rand:seed(Alg),
+ io:format("Seed ~p~n",[rand:export_seed_s(Seed)]),
+ api_eq_1(Seed)
+ end,
+ _ = [Small(Alg) || Alg <- Algs],
+ ok.
+
+api_eq_1(S00) ->
+ Check = fun(_, Seed) ->
+ {V0, S0} = rand:uniform_s(Seed),
+ V0 = rand:uniform(),
+ {V1, S1} = rand:uniform_s(1000000, S0),
+ V1 = rand:uniform(1000000),
+ {V2, S2} = rand:normal_s(S1),
+ V2 = rand:normal(),
+ S2
+ end,
+ S1 = lists:foldl(Check, S00, lists:seq(1, 200)),
+ S1 = get(rand_seed),
+ {V0, S2} = rand:uniform_s(S1),
+ V0 = rand:uniform(),
+ S2 = get(rand_seed),
+
+ Exported = rand:export_seed(),
+ Exported = rand:export_seed_s(S2),
+
+ S3 = lists:foldl(Check, S2, lists:seq(1, 200)),
+ S3 = get(rand_seed),
+
+ S4 = lists:foldl(Check, S3, lists:seq(1, 200)),
+ S4 = get(rand_seed),
+ %% Verify that we do not have loops
+ false = S1 =:= S2,
+ false = S2 =:= S3,
+ false = S3 =:= S4,
+
+ S2 = rand:seed(Exported),
+ S3 = lists:foldl(Check, S2, lists:seq(1, 200)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+interval_int(doc) ->
+ ["Check that uniform/1 returns values within the proper interval."];
+interval_int(suite) ->
+ [];
+interval_int(Config) when is_list(Config) ->
+ Algs = algs(),
+ Small = fun(Alg) ->
+ Seed = rand:seed(Alg),
+ io:format("Seed ~p~n",[rand:export_seed_s(Seed)]),
+ Max = interval_int_1(100000, 7, 0),
+ Max =:= 7 orelse exit({7, Alg, Max})
+ end,
+ _ = [Small(Alg) || Alg <- Algs],
+ %% Test large integers
+ Large = fun(Alg) ->
+ Seed = rand:seed(Alg),
+ io:format("Seed ~p~n",[rand:export_seed_s(Seed)]),
+ Max = interval_int_1(100000, 1 bsl 128, 0),
+ Max > 1 bsl 64 orelse exit({large, Alg, Max})
+ end,
+ [Large(Alg) || Alg <- Algs],
+ ok.
+
+interval_int_1(0, _, Max) -> Max;
+interval_int_1(N, Top, Max) ->
+ X = rand:uniform(Top),
+ if
+ 0 < X, X =< Top ->
+ ok;
+ true ->
+ io:format("X=~p Top=~p 0<~p<~p~n", [X,Top,X,Top]),
+ exit({X, rand:export_seed()})
+ end,
+ interval_int_1(N-1, Top, max(X, Max)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+interval_float(doc) ->
+ ["Check that uniform/0 returns values within the proper interval."];
+interval_float(suite) ->
+ [];
+interval_float(Config) when is_list(Config) ->
+ Algs = algs(),
+ Test = fun(Alg) ->
+ _ = rand:seed(Alg),
+ interval_float_1(100000)
+ end,
+ [Test(Alg) || Alg <- Algs],
+ ok.
+
+interval_float_1(0) -> ok;
+interval_float_1(N) ->
+ X = rand:uniform(),
+ if
+ 0.0 < X, X < 1.0 ->
+ ok;
+ true ->
+ io:format("X=~p 0<~p<1.0~n", [X,X]),
+ exit({X, rand:export_seed()})
+ end,
+ interval_float_1(N-1).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+reference(doc) -> ["Check if exs64 algorithm generates the proper sequence."];
+reference(suite) -> [];
+reference(Config) when is_list(Config) ->
+ [reference_1(Alg) || Alg <- algs()],
+ ok.
+
+reference_1(Alg) ->
+ Refval = reference_val(Alg),
+ Testval = gen(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)]),
+ %% test_server:fail({Alg, Refval -- Testval}),
+ ok
+ end.
+
+gen(Algo) ->
+ Seed = case Algo of
+ exsplus -> %% Printed with orig 'C' code and this seed
+ rand:seed_s({exsplus, [12345678|12345678]});
+ exs64 -> %% Printed with orig 'C' code and this seed
+ rand:seed_s({exs64, 12345678});
+ exs1024 -> %% Printed with orig 'C' code and this seed
+ rand:seed_s({exs1024, {lists:duplicate(16, 12345678), []}});
+ _ ->
+ rand:seed(Algo, {100, 200, 300})
+ end,
+ gen(?LOOP, Seed, []).
+
+gen(N, State0 = {#{max:=Max}, _}, Acc) when N > 0 ->
+ {Random, State} = rand:uniform_s(Max, State0),
+ case N rem (?LOOP div 100) of
+ 0 -> gen(N-1, State, [Random|Acc]);
+ _ -> gen(N-1, State, Acc)
+ end;
+gen(_, _, Acc) -> lists:reverse(Acc).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This just tests the basics so we have not made any serious errors
+%% when making the conversion from the original algorithms.
+%% The algorithms must have good properties to begin with
+%%
+
+%% Check that the algorithms generate sound values.
+
+basic_stats_uniform_1(Config) when is_list(Config) ->
+ [basic_uniform_1(?LOOP, rand:seed_s(Alg), 0.0, array:new([{default, 0}]))
+ || Alg <- algs()],
+ ok.
+
+basic_stats_uniform_2(Config) when is_list(Config) ->
+ [basic_uniform_2(?LOOP, rand:seed_s(Alg), 0, array:new([{default, 0}]))
+ || Alg <- algs()],
+ ok.
+
+basic_stats_normal(Config) when is_list(Config) ->
+ io:format("Testing normal~n",[]),
+ [basic_normal_1(?LOOP, rand:seed_s(Alg), 0, 0) || Alg <- algs()],
+ ok.
+
+basic_uniform_1(N, S0, Sum, A0) when N > 0 ->
+ {X,S} = rand:uniform_s(S0),
+ I = trunc(X*100),
+ A = array:set(I, 1+array:get(I,A0), A0),
+ basic_uniform_1(N-1, S, Sum+X, A);
+basic_uniform_1(0, {#{type:=Alg}, _}, Sum, A) ->
+ AverN = Sum / ?LOOP,
+ io:format("~.10w: Average: ~.4f~n", [Alg, AverN]),
+ Counters = array:to_list(A),
+ Min = lists:min(Counters),
+ Max = lists:max(Counters),
+ io:format("~.10w: Min: ~p Max: ~p~n", [Alg, Min, Max]),
+
+ %% Verify that the basic statistics are ok
+ %% be gentle we don't want to see to many failing tests
+ abs(0.5 - AverN) < 0.005 orelse test_server:fail({average, Alg, AverN}),
+ abs(?LOOP div 100 - Min) < 1000 orelse test_server:fail({min, Alg, Min}),
+ abs(?LOOP div 100 - Max) < 1000 orelse test_server:fail({max, Alg, Max}),
+ ok.
+
+basic_uniform_2(N, S0, Sum, A0) when N > 0 ->
+ {X,S} = rand:uniform_s(100, S0),
+ A = array:set(X-1, 1+array:get(X-1,A0), A0),
+ basic_uniform_2(N-1, S, Sum+X, A);
+basic_uniform_2(0, {#{type:=Alg}, _}, Sum, A) ->
+ AverN = Sum / ?LOOP,
+ io:format("~.10w: Average: ~.4f~n", [Alg, AverN]),
+ Counters = tl(array:to_list(A)),
+ Min = lists:min(Counters),
+ Max = lists:max(Counters),
+ io:format("~.10w: Min: ~p Max: ~p~n", [Alg, Min, Max]),
+
+ %% Verify that the basic statistics are ok
+ %% be gentle we don't want to see to many failing tests
+ abs(50.5 - AverN) < 0.5 orelse test_server:fail({average, Alg, AverN}),
+ abs(?LOOP div 100 - Min) < 1000 orelse test_server:fail({min, Alg, Min}),
+ abs(?LOOP div 100 - Max) < 1000 orelse test_server:fail({max, Alg, Max}),
+ ok.
+
+basic_normal_1(N, S0, Sum, Sq) when N > 0 ->
+ {X,S} = rand:normal_s(S0),
+ basic_normal_1(N-1, S, X+Sum, X*X+Sq);
+basic_normal_1(0, {#{type:=Alg}, _}, Sum, SumSq) ->
+ Mean = Sum / ?LOOP,
+ StdDev = math:sqrt((SumSq - (Sum*Sum/?LOOP))/(?LOOP - 1)),
+ io:format("~.10w: Average: ~7.4f StdDev ~6.4f~n", [Alg, Mean, StdDev]),
+ %% Verify that the basic statistics are ok
+ %% be gentle we don't want to see to many failing tests
+ abs(Mean) < 0.005 orelse test_server:fail({average, Alg, Mean}),
+ abs(StdDev - 1.0) < 0.005 orelse test_server:fail({stddev, Alg, StdDev}),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+plugin(doc) -> ["Test that the user can write algorithms"];
+plugin(suite) -> [];
+plugin(Config) when is_list(Config) ->
+ _ = lists:foldl(fun(_, S0) ->
+ {V1, S1} = rand:uniform_s(10000, S0),
+ true = is_integer(V1),
+ {V2, S2} = rand:uniform_s(S1),
+ true = is_float(V2),
+ S2
+ end, crypto_seed(), lists:seq(1, 200)),
+ ok.
+
+%% Test implementation
+crypto_seed() ->
+ {#{type=>crypto,
+ max=>(1 bsl 64)-1,
+ next=>fun crypto_next/1,
+ uniform=>fun crypto_uniform/1,
+ uniform_n=>fun crypto_uniform_n/2},
+ <<>>}.
+
+%% Be fair and create bignums i.e. 64bits otherwise use 58bits
+crypto_next(<<Num:64, Bin/binary>>) ->
+ {Num, Bin};
+crypto_next(_) ->
+ crypto_next(crypto:rand_bytes((64 div 8)*100)).
+
+crypto_uniform({Api, Data0}) ->
+ {Int, Data} = crypto_next(Data0),
+ {Int / (1 bsl 64), {Api, Data}}.
+
+crypto_uniform_n(N, {Api, Data0}) when N < (1 bsl 64) ->
+ {Int, Data} = crypto_next(Data0),
+ {(Int rem N)+1, {Api, Data}};
+crypto_uniform_n(N, State0) ->
+ {F,State} = crypto_uniform(State0),
+ {trunc(F * N) + 1, State}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Not a test but measures the time characteristics of the different algorithms
+measure(Suite) when is_atom(Suite) -> [];
+measure(_Config) ->
+ Algos = [crypto64|algs()],
+ io:format("RNG uniform integer performance~n",[]),
+ _ = measure_1(random, fun(State) -> {int, random:uniform_s(10000, State)} end),
+ _ = [measure_1(Algo, fun(State) -> {int, rand:uniform_s(10000, State)} end) || Algo <- Algos],
+ io:format("RNG uniform float performance~n",[]),
+ _ = measure_1(random, fun(State) -> {uniform, random:uniform_s(State)} end),
+ _ = [measure_1(Algo, fun(State) -> {uniform, rand:uniform_s(State)} end) || Algo <- Algos],
+ io:format("RNG normal float performance~n",[]),
+ io:format("~.10w: not implemented (too few bits)~n", [random]),
+ _ = [measure_1(Algo, fun(State) -> {normal, rand:normal_s(State)} end) || Algo <- Algos],
+ ok.
+
+measure_1(Algo, Gen) ->
+ Parent = self(),
+ Seed = fun(crypto64) -> crypto_seed();
+ (random) -> random:seed(os:timestamp()), get(random_seed);
+ (Alg) -> rand:seed_s(Alg)
+ end,
+
+ Pid = spawn_link(fun() ->
+ Fun = fun() -> measure_2(?LOOP, Seed(Algo), Gen) end,
+ {Time, ok} = timer:tc(Fun),
+ io:format("~.10w: ~pµs~n", [Algo, Time]),
+ Parent ! {self(), ok},
+ normal
+ end),
+ receive
+ {Pid, Msg} -> Msg
+ end.
+
+measure_2(N, State0, Fun) when N > 0 ->
+ case Fun(State0) of
+ {int, {Random, State}}
+ when is_integer(Random), Random >= 1, Random =< 100000 ->
+ measure_2(N-1, State, Fun);
+ {uniform, {Random, State}} when is_float(Random), Random > 0, Random < 1 ->
+ measure_2(N-1, State, Fun);
+ {normal, {Random, State}} when is_float(Random) ->
+ measure_2(N-1, State, Fun);
+ Res ->
+ exit({error, Res, State0})
+ end;
+measure_2(0, _, _) -> ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Data
+reference_val(exs64) ->
+ [16#3737ad0c703ff6c3,16#3868a78fe71adbbd,16#1f01b62b4338b605,16#50876a917437965f,
+ 16#b2edfe32a10e27fc,16#995924551d8ebae1,16#9f1e6b94e94e0b58,16#27ec029eb0e94f8e,
+ 16#bf654e6df7fe5c,16#b7d5ef7b79be65e3,16#4bdba4d1c159126b,16#a9c816fdc701292c,
+ 16#a377b6c89d85ac8b,16#7abb5cd0e5847a6,16#62666f1fc00a0a90,16#1edc3c3d255a8113,
+ 16#dfc764073767f18e,16#381783d577ca4e34,16#49693588c085ddcb,16#da6fcb16dd5163f3,
+ 16#e2357a703475b1b7,16#aaa84c4924b5985a,16#b8fe07bb2bac1e49,16#23973ac0160ff064,
+ 16#1afbc7b023f5d618,16#9f510f7b7caa2a0f,16#d5b0a57f7f5f1084,16#d8c49b66c5f99a29,
+ 16#e920ac3b598b5213,16#1090d7e27e7a7c76,16#81171917168ee74f,16#f08489a3eb6988e,
+ 16#396260c4f0b2ed46,16#4fd0a6a6caefd5b2,16#423dff07a3b888a,16#12718773ebd99987,
+ 16#e50991e540807cb,16#8cfa03bbaa6679d6,16#55bdf86dfbb92dbf,16#eb7145378cce74a8,
+ 16#71856c224c846595,16#20461588dae6e24d,16#c73b3e63ced74bac,16#775b11813dda0c78,
+ 16#91f358e51068ede0,16#399955ef36766bc2,16#4489ee072e8a38b1,16#ba77759d52321ca0,
+ 16#14f519eab5c53db8,16#1f754bd08e4f34c4,16#99e25ca29b2fcfeb,16#da11927c0d9837f8,
+ 16#1eeb0f87009f5a87,16#a7c444d3b0db1089,16#49c7fbf0714849ad,16#4f2b693e7f8265cb,
+ 16#80e1493cbaa8f256,16#186f345bcac2661e,16#330065ae0c698d26,16#5235ed0432c42e93,
+ 16#429792e31ddb10bb,16#8769054bb6533cff,16#1ab382483444201f,16#2216368786fc7b9,
+ 16#1efea1155216da0b,16#782dc868ba595452,16#2b80f6d159617f48,16#407fc35121b2fa1b,
+ 16#90e8be6e618873d1,16#40ad4ec92a8abf8e,16#34e2890f583f435,16#838c0aef0a5d8427,
+ 16#ed4238f4bd6cbcfa,16#7feed11f7a8bb9f0,16#2b0636a93e26c89d,16#481ad4bea5180646,
+ 16#673e5ad861afe1cc,16#298eeb519d69e74d,16#eb1dd06d168c856,16#4770651519ee7ef9,
+ 16#7456ebf1bcf608f1,16#d6200f6fbd61ce05,16#c0695dfab11ab6aa,16#5bff449249983843,
+ 16#7aba88471474c9ac,16#d7e9e4a21c989e91,16#c5e02ee67ccb7ce1,16#4ea8a3a912246153,
+ 16#f2e6db7c9ce4ec43,16#39498a95d46d2470,16#c5294fcb8cce8aa9,16#a918fe444719f3dc,
+ 16#98225f754762c0c0,16#f0721204f2cb43f5,16#b98e77b099d1f2d1,16#691d6f75aee3386,
+ 16#860c7b2354ec24fd,16#33e007bd0fbcb609,16#7170ae9c20fb3d0,16#31d46938fe383a60];
+
+reference_val(exs1024) ->
+ [16#9c61311d0d4a01fd,16#ce963ef5803b703e,16#545dcffb7b644e1a,16#edd56576a8d778d5,
+ 16#16bee799783c6b45,16#336f0b3caeb417fa,16#29291b8be26dedfa,16#1efed996d2e1b1a8,
+ 16#c5c04757bd2dadf9,16#11aa6d194009c616,16#ab2b3e82bdb38a91,16#5011ee46fd2609eb,
+ 16#766db7e5b701a9bb,16#d42cb2632c419f35,16#107c6a2667bf8557,16#3ffbf922cb306967,
+ 16#1e71e3d024ac5131,16#6fdb368ec67a5f06,16#b0d8e72e7aa6d1c1,16#e5705a02dae89e3b,
+ 16#9c24eb68c086a1d3,16#418de330f55f71f0,16#2917ddeb278bc8d2,16#aeba7fba67208f39,
+ 16#10ceaf40f6af1d8d,16#47a6d06811d33132,16#603a661d6caf720a,16#a28bd0c9bcdacb3c,
+ 16#f44754f006909762,16#6e25e8e67ccc43bc,16#174378ce374a549e,16#b5598ae9f57c4e50,
+ 16#ca85807fbcd51dd,16#1816e58d6c3cc32a,16#1b4d630d3c8e96a6,16#c19b1e92b4efc5bd,
+ 16#665597b20ddd721a,16#fdab4eb21b75c0ae,16#86a612dcfea0756c,16#8fc2da192f9a55f0,
+ 16#d7c954eb1af31b5,16#6f5ee45b1b80101b,16#ebe8ea4e5a67cbf5,16#1cb952026b4c1400,
+ 16#44e62caffe7452c0,16#b591d8f3e6d7cbcf,16#250303f8d77b6f81,16#8ef2199aae4c9b8d,
+ 16#a16baa37a14d7b89,16#c006e4d2b2da158b,16#e6ec7abd54c93b31,16#e6b0d79ae2ab6fa7,
+ 16#93e4b30e4ab7d4cd,16#42a01b6a4ef63033,16#9ab1e94fe94976e,16#426644e1de302a1f,
+ 16#8e58569192200139,16#744f014a090107c1,16#15d056801d467c6c,16#51bdad3a8c30225f,
+ 16#abfc61fb3104bd45,16#c610607122272df7,16#905e67c63116ebfc,16#1e4fd5f443bdc18,
+ 16#1945d1745bc55a4c,16#f7cd2b18989595bb,16#f0d273b2c646a038,16#ee9a6fdc6fd5d734,
+ 16#541a518bdb700518,16#6e67ab9a65361d76,16#bcfadc9bfe5b2e06,16#69fa334cf3c11496,
+ 16#9657df3e0395b631,16#fc0d0442160108ec,16#2ee538da7b1f7209,16#8b20c9fae50a5a9e,
+ 16#a971a4b5c2b3b6a,16#ff6241e32489438e,16#8fd6433f45255777,16#6e6c82f10818b0dc,
+ 16#59a8fad3f6af616b,16#7eac34f43f12221c,16#6e429ec2951723ec,16#9a65179767a45c37,
+ 16#a5f8127d1e6fdf35,16#932c50bc633d8d5c,16#f3bbea4e7ebecb8,16#efc3a2bbf6a8674,
+ 16#451644a99971cb6,16#cf70776d652c150d,16#c1fe0dcb87a25403,16#9523417132b2452e,
+ 16#8f98bc30d06b980e,16#bb4b288ecb8daa9a,16#59e54beb32f78045,16#f9ab1562456b9d66,
+ 16#6435f4130304a793,16#b4bb94c2002e1849,16#49a86d1e4bade982,16#457d63d60ed52b95];
+
+reference_val(exsplus) ->
+ [16#bc76c2e638db,16#15ede2ebb16c9fb,16#185ee2c27d6b88d,16#15d5ee9feafc3a5,
+ 16#1862e91dfce3e6b,16#2c9744b0fb69e46,16#78b21bc01cef6b,16#2d16a2fae6c76ba,
+ 16#13dfccb8ff86bce,16#1d9474c59e23f4d,16#d2f67dcd7f0dd6,16#2b6d489d51a0725,
+ 16#1fa52ef484861d8,16#1ae9e2a38f966d4,16#2264ab1e193acca,16#23bbca085039a05,
+ 16#2b6eea06a0af0e1,16#3ad47fa8866ea20,16#1ec2802d612d855,16#36c1982b134d50,
+ 16#296b6a23f5b75e0,16#c5eeb600a9875c,16#2a3fd51d735f9d4,16#56fafa3593a070,
+ 16#13e9d416ec0423e,16#28101a91b23e9dc,16#32e561eb55ce15a,16#94a7dbba66fe4a,
+ 16#2e1845043bcec1f,16#235f7513a1b5146,16#e37af1bf2d63cb,16#2048033824a1639,
+ 16#c255c750995f7,16#2c7542058e89ee3,16#204dfeefbdb62ba,16#f5a936ec63dd66,
+ 16#33b3b7dbbbd8b90,16#c4f0f79026ffe9,16#20ffee2d37aca13,16#2274f931716be2c,
+ 16#29b883902ba9df1,16#1a838cd5312717f,16#2edfc49ff3dc1d6,16#418145cbec84c2,
+ 16#d2d8f1a17d49f,16#d41637bfa4cc6f,16#24437e03a0f5df8,16#3d1d87919b94a90,
+ 16#20d6997b36769b6,16#16f9d7855cd87ca,16#821ef7e2a062a3,16#2c4d11dc4a2da70,
+ 16#24a3b27f56ed26b,16#144b23c8b97387a,16#34a2ced56930d12,16#21cc0544113a017,
+ 16#3e780771f634fb2,16#146c259c02e7e18,16#1d99e4cfad0ef1,16#fdf3dabefc6b3a,
+ 16#7d0806e4d12dfb,16#3e3ae3580532eae,16#2456544200fbd86,16#f83aad4e88db85,
+ 16#37c134779463b4d,16#21a20bf64b6e735,16#1c0585ac88b69f2,16#1b3fcea8dd30e56,
+ 16#334bc301aefd97,16#37066eb7e80a946,16#15a19a6331b570f,16#35e67fa43c3f7d0,
+ 16#152a4020145fb80,16#8d55139491dfbe,16#21d9cba585c059d,16#31475f363654635,
+ 16#2567b17acb7a104,16#39201be3a7681c5,16#6bc675fd26b601,16#334b93232b1b1e3,
+ 16#357c402cb732c6a,16#362e32efe4db46a,16#8edc7ae3da51e5,16#31573376785eac9,
+ 16#6c6145ffa1169d,16#18ec2c393d45359,16#1f1a5f256e7130c,16#131cc2f49b8004f,
+ 16#36f715a249f4ec2,16#1c27629826c50d3,16#914d9a6648726a,16#27f5bf5ce2301e8,
+ 16#3dd493b8012970f,16#be13bed1e00e5c,16#ceef033b74ae10,16#3da38c6a50abe03,
+ 16#15cbd1a421c7a8c,16#22794e3ec6ef3b1,16#26154d26e7ea99f,16#3a66681359a6ab6].
diff --git a/lib/stdlib/test/random_SUITE.erl b/lib/stdlib/test/random_SUITE.erl
index ac9d1a6c06..738f73ae15 100644
--- a/lib/stdlib/test/random_SUITE.erl
+++ b/lib/stdlib/test/random_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
@@ -82,7 +83,7 @@ seed(suite) ->
[];
seed(Config) when is_list(Config) ->
?line Self = self(),
- ?line Seed = {S1, S2, S3} = now(),
+ Seed = {S1, S2, S3} = erlang:timestamp(),
?line _ = spawn(fun() ->
random:seed(S1,S2,S3),
Rands = lists:foldl(fun
diff --git a/lib/stdlib/test/random_iolist.erl b/lib/stdlib/test/random_iolist.erl
index 8f21b5a3b3..9a0f034e72 100644
--- a/lib/stdlib/test/random_iolist.erl
+++ b/lib/stdlib/test/random_iolist.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/random_unicode_list.erl b/lib/stdlib/test/random_unicode_list.erl
index b8bd719b89..ecafe42318 100644
--- a/lib/stdlib/test/random_unicode_list.erl
+++ b/lib/stdlib/test/random_unicode_list.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl
index 87763cbf92..d78d6153da 100644
--- a/lib/stdlib/test/re_SUITE.erl
+++ b/lib/stdlib/test/re_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,7 +28,7 @@
pcre_compile_workspace_overflow/1,re_infinite_loop/1,
re_backwards_accented/1,opt_dupnames/1,opt_all_names/1,inspect/1,
opt_no_start_optimize/1,opt_never_utf/1,opt_ucp/1,
- match_limit/1,sub_binaries/1]).
+ match_limit/1,sub_binaries/1,copt/1]).
-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -318,32 +319,26 @@ replace_return(doc) ->
["Tests return options of replace together with global searching"];
replace_return(Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(3)),
- ?line {'EXIT',{badarg,_}} = (catch re:replace("na","(a","")),
- ?line <<"nasse">> = re:replace(<<"nisse">>,"i","a",[{return,binary}]),
- ?line <<"ABCÅXABCXA">> = re:replace("ABC\305abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary}]),
-
- ?line [<<"ABCÅ">>,
- <<"X">>,
- <<"ABC">>,
- <<"X">> |
- <<"A">> ] =
- re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,iodata}]),
- ?line "ABCÅXABCXA" = re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,list},unicode]),
- ?line <<65,66,67,195,133,88,65,66,67,88,65>> = re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary},unicode]),
- ?line <<65,66,67,195,133,88,65,66,67,97,98,99,100,65>> = re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[{return,binary},unicode]),
- ?line <<"iXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\9X",[{return,binary}]),
- ?line <<"jXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\10X",[{return,binary}]),
- ?line <<"Xk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\11X",[{return,binary}]),
- ?line <<"9X1">> = re:replace("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g9X",[{return,binary}]),
- ?line <<"0X1">> = re:replace("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g10X",[{return,binary}]),
- ?line <<"X1">> = re:replace("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g11X",[{return,binary}]),
- ?line <<"971">> = re:replace("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g{9}7",[{return,binary}]),
- ?line <<"071">> = re:replace("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g{10}7",[{return,binary}]),
- ?line <<"71">> = re:replace("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g{11}7",[{return,binary}]),
- ?line "a\x{400}bcX" = re:replace("a\x{400}bcd","d","X",[global,{return,list},unicode]),
- ?line <<"a",208,128,"bcX">> = re:replace("a\x{400}bcd","d","X",[global,{return,binary},unicode]),
- ?line "a\x{400}bcd" = re:replace("a\x{400}bcd","Z","X",[global,{return,list},unicode]),
- ?line <<"a",208,128,"bcd">> = re:replace("a\x{400}bcd","Z","X",[global,{return,binary},unicode]),
+ {'EXIT',{badarg,_}} = (catch re:replace("na","(a","")),
+ ok = replacetest(<<"nisse">>,"i","a",[{return,binary}],<<"nasse">>),
+ ok = replacetest("ABC\305abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary}],<<"ABCÅXABCXA">>),
+ ok = replacetest("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,iodata}],[<<"ABCÅ">>,<<"X">>,<<"ABC">>,<<"X">>|<<"A">>]),
+ ok = replacetest("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,list},unicode],"ABCÅXABCXA"),
+ ok = replacetest("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary},unicode],<<65,66,67,195,133,88,65,66,67,88,65>>),
+ ok = replacetest("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[{return,binary},unicode],<<65,66,67,195,133,88,65,66,67,97,98,99,100,65>>),
+ ok = replacetest("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\9X",[{return,binary}],<<"iXk">>),
+ ok = replacetest("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\10X",[{return,binary}],<<"jXk">>),
+ ok = replacetest("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\11X",[{return,binary}],<<"Xk">>),
+ ok = replacetest("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g9X",[{return,binary}],<<"9X1">>),
+ ok = replacetest("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g10X",[{return,binary}],<<"0X1">>),
+ ok = replacetest("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g11X",[{return,binary}],<<"X1">>),
+ ok = replacetest("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g{9}7",[{return,binary}],<<"971">>),
+ ok = replacetest("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g{10}7",[{return,binary}],<<"071">>),
+ ok = replacetest("12345678901","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\g{11}7",[{return,binary}],<<"71">>),
+ ok = replacetest("a\x{400}bcd","d","X",[global,{return,list},unicode],"a\x{400}bcX"),
+ ok = replacetest("a\x{400}bcd","d","X",[global,{return,binary},unicode],<<"a",208,128,"bcX">>),
+ ok = replacetest("a\x{400}bcd","Z","X",[global,{return,list},unicode],"a\x{400}bcd"),
+ ok = replacetest("a\x{400}bcd","Z","X",[global,{return,binary},unicode],<<"a",208,128,"bcd">>),
?t:timetrap_cancel(Dog),
ok.
@@ -388,6 +383,35 @@ crtest(Subject,RE,Options,true,Result) ->
error
end.
+replacetest(Subject,RE,Replacement,Options,Result) ->
+ Result = re:replace(Subject,RE,Replacement,Options),
+ {CompileOptions,ReplaceOptions} = lists:partition(fun copt/1, Options),
+ {ok,MP} = re:compile(RE,CompileOptions),
+ Result = re:replace(Subject,MP,Replacement,ReplaceOptions),
+ ok.
+
+splittest(Subject,RE,Options,Result) ->
+ Result = re:split(Subject,RE,Options),
+ {CompileOptions,SplitOptions} = lists:partition(fun copt/1, Options),
+ {ok,MP} = re:compile(RE,CompileOptions),
+ Result = re:split(Subject,MP,SplitOptions),
+ ok.
+
+copt(caseless) -> true;
+copt(no_start_optimize) -> true;
+copt(never_utf) -> true;
+copt(ucp) -> true;
+copt(dollar_endonly) -> true;
+copt(dotall) -> true;
+copt(extended) -> true;
+copt(firstline) -> true;
+copt(multiline) -> true;
+copt(no_auto_capture) -> true;
+copt(dupnames) -> true;
+copt(ungreedy) -> true;
+copt(unicode) -> true;
+copt(_) -> false.
+
split_autogen(doc) ->
["Test split with autogenerated erlang module"];
split_autogen(Config) when is_list(Config) ->
@@ -400,43 +424,23 @@ split_options(doc) ->
["Test special options to split."];
split_options(Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(1)),
- ?line [[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>]] = re:split("a b c ","( )",[group,trim]),
- ?line [[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>]] = re:split("a b c ","( )",[group,{parts,0}]),
- ?line [[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<>>]] =
- re:split("a b c ","( )",[{parts,infinity},group]),
- ?line [[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<>>]] =
- re:split("a b c ","( )",[group]),
- ?line [[<<>>,<<" ">>],[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],
- [<<"c">>,<<" ">>],[<<"d">>,<<" ">>]] =
- re:split(" a b c d ","( +)",[group,trim]),
- ?line [[<<>>,<<" ">>],[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],
- [<<"c">>,<<" ">>],[<<"d">>,<<" ">>]] =
- re:split(" a b c d ","( +)",[{parts,0},group]),
- ?line [[<<>>,<<" ">>],[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],
- [<<"c">>,<<" ">>],[<<"d">>,<<" ">>],[<<>>]] =
- re:split(" a b c d ","( +)",[{parts,infinity},group]),
- ?line [[<<"a">>,<<" ">>],[<<"b c d">>]] =
- re:split("a b c d","( +)",[{parts,2},group]),
- ?line [[[967]," "],["b c d"]] =
- re:split([967]++" b c d","( +)",
- [{parts,2},group,{return,list},unicode]),
- ?line [[<<207,135>>,<<" ">>],[<<"b c d">>]] =
- re:split([967]++" b c d","( +)",
- [{parts,2},group,{return,binary},unicode]),
- ?line {'EXIT',{badarg,_}} =
- (catch re:split([967]++" b c d","( +)",
- [{parts,2},group,{return,binary}])),
- ?line {'EXIT',{badarg,_}} =
- (catch re:split("a b c d","( +)",[{parts,-2}])),
- ?line {'EXIT',{badarg,_}} =
- (catch re:split("a b c d","( +)",[{parts,banan}])),
- ?line {'EXIT',{badarg,_}} =
- (catch re:split("a b c d","( +)",[{capture,all}])),
- ?line {'EXIT',{badarg,_}} =
- (catch re:split("a b c d","( +)",[{capture,[],binary}])),
+ ok = splittest("a b c ","( )",[group,trim],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>]]),
+ ok = splittest("a b c ","( )",[group,{parts,0}],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>]]),
+ ok = splittest("a b c ","( )",[{parts,infinity},group],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<>>]]),
+ ok = splittest("a b c ","( )",[group],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<>>]]),
+ ok = splittest(" a b c d ","( +)",[group,trim],[[<<>>,<<" ">>],[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<"d">>,<<" ">>]]),
+ ok = splittest(" a b c d ","( +)",[{parts,0},group],[[<<>>,<<" ">>],[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<"d">>,<<" ">>]]),
+ ok = splittest(" a b c d ","( +)",[{parts,infinity},group],[[<<>>,<<" ">>],[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<"d">>,<<" ">>],[<<>>]]),
+ ok = splittest("a b c d","( +)",[{parts,2},group],[[<<"a">>,<<" ">>],[<<"b c d">>]]),
+ ok = splittest([967]++" b c d","( +)",[{parts,2},group,{return,list},unicode],[[[967]," "],["b c d"]]),
+ ok = splittest([967]++" b c d","( +)",[{parts,2},group,{return,binary},unicode],[[<<207,135>>,<<" ">>],[<<"b c d">>]]),
+ {'EXIT',{badarg,_}} = (catch re:split([967]++" b c d","( +)",[{parts,2},group,{return,binary}])),
+ {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{parts,-2}])),
+ {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{parts,banan}])),
+ {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{capture,all}])),
+ {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{capture,[],binary}])),
% Parts 0 is equal to no parts specification (implicit strip)
- ?line ["a"," ","b"," ","c"," ","d"] =
- re:split("a b c d","( *)",[{parts,0},{return,list}]),
+ ok = splittest("a b c d","( *)",[{parts,0},{return,list}],["a"," ","b"," ","c"," ","d"]),
?t:timetrap_cancel(Dog),
ok.
diff --git a/lib/stdlib/test/re_testoutput1_replacement_test.erl b/lib/stdlib/test/re_testoutput1_replacement_test.erl
index e475b180eb..9081a18cd2 100644
--- a/lib/stdlib/test/re_testoutput1_replacement_test.erl
+++ b/lib/stdlib/test/re_testoutput1_replacement_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/re_testoutput1_split_test.erl b/lib/stdlib/test/re_testoutput1_split_test.erl
index af3c3caa48..71728607bc 100644
--- a/lib/stdlib/test/re_testoutput1_split_test.erl
+++ b/lib/stdlib/test/re_testoutput1_split_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/run_pcre_tests.erl b/lib/stdlib/test/run_pcre_tests.erl
index c4a8afc092..1fdc777470 100644
--- a/lib/stdlib/test/run_pcre_tests.erl
+++ b/lib/stdlib/test/run_pcre_tests.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/select_SUITE.erl b/lib/stdlib/test/select_SUITE.erl
index 546c25f954..ead64ffc75 100644
--- a/lib/stdlib/test/select_SUITE.erl
+++ b/lib/stdlib/test/select_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -211,7 +212,7 @@ init_random(Config) ->
{ok,[X]} ->
X;
_ ->
- {A,B,C} = erlang:now(),
+ {A,B,C} = erlang:timestamp(),
random:seed(A,B,C),
get(random_seed)
end,
diff --git a/lib/stdlib/test/sets_SUITE.erl b/lib/stdlib/test/sets_SUITE.erl
index c0cf1fc7e8..972a812072 100644
--- a/lib/stdlib/test/sets_SUITE.erl
+++ b/lib/stdlib/test/sets_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -28,7 +29,7 @@
create/1,add_element/1,del_element/1,
subtract/1,intersection/1,union/1,is_subset/1,
is_set/1,fold/1,filter/1,
- take_smallest/1,take_largest/1]).
+ take_smallest/1,take_largest/1, iterate/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -48,7 +49,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[create, add_element, del_element, subtract,
intersection, union, is_subset, is_set, fold, filter,
- take_smallest, take_largest].
+ take_smallest, take_largest, iterate].
groups() ->
[].
@@ -426,6 +427,44 @@ take_largest_3(S0, List0, M) ->
take_largest_3(S, List, M)
end.
+iterate(Config) when is_list(Config) ->
+ test_all(fun iterate_1/1).
+
+iterate_1(M) ->
+ case M(module, []) of
+ gb_sets -> iterate_2(M);
+ _ -> ok
+ end,
+ M(empty, []).
+
+iterate_2(M) ->
+ random:seed(1, 2, 42),
+ iter_set(M, 1000).
+
+iter_set(_M, 0) ->
+ ok;
+iter_set(M, N) ->
+ L = [I || I <- lists:seq(1, N)],
+ T = M(from_list, L),
+ L = lists:reverse(iterate_set(M, T)),
+ R = random:uniform(N),
+ S = lists:reverse(iterate_set(M, R, T)),
+ S = [E || E <- L, E >= R],
+ iter_set(M, N-1).
+
+iterate_set(M, Set) ->
+ I = M(iterator, Set),
+ iterate_set_1(M, M(next, I), []).
+
+iterate_set(M, Start, Set) ->
+ I = M(iterator_from, {Start, Set}),
+ iterate_set_1(M, M(next, I), []).
+
+iterate_set_1(_, none, R) ->
+ R;
+iterate_set_1(M, {E, I}, R) ->
+ iterate_set_1(M, M(next, I), [E | R]).
+
%%%
%%% Helper functions.
%%%
diff --git a/lib/stdlib/test/sets_test_lib.erl b/lib/stdlib/test/sets_test_lib.erl
index 86f009a8f9..9f153822a2 100644
--- a/lib/stdlib/test/sets_test_lib.erl
+++ b/lib/stdlib/test/sets_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -34,7 +35,10 @@ new(Mod, Eq) ->
(is_empty, S) -> is_empty(Mod, S);
(is_set, S) -> Mod:is_set(S);
(is_subset, {S,Set}) -> is_subset(Mod, Eq, S, Set);
+ (iterator, S) -> Mod:iterator(S);
+ (iterator_from, {Start, S}) -> Mod:iterator_from(Start, S);
(module, []) -> Mod;
+ (next, I) -> Mod:next(I);
(singleton, E) -> singleton(Mod, E);
(size, S) -> Mod:size(S);
(subtract, {S1,S2}) -> subtract(Mod, S1, S2);
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index f841e2c4a6..a9dd6b5817 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -404,13 +405,14 @@ records(Config) when is_list(Config) ->
?line ok = file:write_file(Test, Contents),
RR5 = "rr(\"" ++ Test ++ "\", '_', {d,test1}), rl([test1,test2]).",
- ?line [{attribute,1,record,{test1,_}},ok] = scan(RR5),
+ A1 = erl_anno:new(1),
+ [{attribute,A1,record,{test1,_}},ok] = scan(RR5),
RR6 = "rr(\"" ++ Test ++ "\", '_', {d,test2}), rl([test1,test2]).",
- ?line [{attribute,1,record,{test2,_}},ok] = scan(RR6),
+ [{attribute,A1,record,{test2,_}},ok] = scan(RR6),
RR7 = "rr(\"" ++ Test ++
"\", '_', [{d,test1},{d,test2,17}]), rl([test1,test2]).",
- ?line [{attribute,1,record,{test1,_}},{attribute,1,record,{test2,_}},
- ok] = scan(RR7),
+ [{attribute,A1,record,{test1,_}},{attribute,A1,record,{test2,_}},ok] =
+ scan(RR7),
?line PreReply = scan(<<"rr(prim_file).">>), % preloaded...
?line true = is_list(PreReply),
?line Dir = filename:join(?config(priv_dir, Config), "*.erl"),
diff --git a/lib/stdlib/test/slave_SUITE.erl b/lib/stdlib/test/slave_SUITE.erl
index 1d6a3ac90d..65627b3741 100644
--- a/lib/stdlib/test/slave_SUITE.erl
+++ b/lib/stdlib/test/slave_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/sofs_SUITE.erl b/lib/stdlib/test/sofs_SUITE.erl
index f11c6ec4d6..d23eb3abb9 100644
--- a/lib/stdlib/test/sofs_SUITE.erl
+++ b/lib/stdlib/test/sofs_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl
index 3d09bd27ff..fa9d0f6b55 100644
--- a/lib/stdlib/test/stdlib_SUITE.erl
+++ b/lib/stdlib/test/stdlib_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -22,14 +23,7 @@
-module(stdlib_SUITE).
-include_lib("test_server/include/test_server.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]).
--export([init_per_testcase/2, end_per_testcase/2]).
-
-% Test cases must be exported.
--export([app_test/1, appup_test/1]).
+-compile(export_all).
%%
%% all/1
@@ -37,10 +31,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test, appup_test].
-
-groups() ->
- [].
+ [app_test, appup_test, assert_test].
init_per_suite(Config) ->
Config.
@@ -165,3 +156,68 @@ check_appup([Vsn|Vsns],Instrs,Expected) ->
end;
check_appup([],_,_) ->
ok.
+
+
+-include_lib("stdlib/include/assert.hrl").
+-include_lib("stdlib/include/assert.hrl"). % test repeated inclusion
+assert_test(suite) ->
+ [];
+assert_test(doc) ->
+ ["Assert macros test."];
+assert_test(_Config) ->
+ ok = ?assert(true),
+ {'EXIT',{{assert, _},_}} = (catch ?assert(false)),
+ {'EXIT',{{assert, Info1},_}} = (catch ?assert(0)),
+ {not_boolean,0} = lists:keyfind(not_boolean,1,Info1),
+
+ ok = ?assertNot(false),
+ {'EXIT',{{assert, _},_}} = (catch ?assertNot(true)),
+ {'EXIT',{{assert, Info2},_}} = (catch ?assertNot(0)),
+ {not_boolean,0} = lists:keyfind(not_boolean,1,Info2),
+
+ ok = ?assertMatch({foo,_}, {foo,bar}),
+ {'EXIT',{{assertMatch,_},_}} =
+ (catch ?assertMatch({foo,_}, {foo})),
+
+ ok = ?assertMatch({foo,N} when N > 0, {foo,1}),
+ {'EXIT',{{assertMatch,_},_}} =
+ (catch ?assertMatch({foo,N} when N > 0, {foo,0})),
+
+ ok = ?assertNotMatch({foo,_}, {foo,bar,baz}),
+ {'EXIT',{{assertNotMatch,_},_}} =
+ (catch ?assertNotMatch({foo,_}, {foo,baz})),
+
+ ok = ?assertNotMatch({foo,N} when N > 0, {foo,0}),
+ {'EXIT',{{assertNotMatch,_},_}} =
+ (catch ?assertNotMatch({foo,N} when N > 0, {foo,1})),
+
+ ok = ?assertEqual(1.0, 1.0),
+ {'EXIT',{{assertEqual,_},_}} = (catch ?assertEqual(1, 1.0)),
+
+ ok = ?assertNotEqual(1, 1.0),
+ {'EXIT',{{assertNotEqual,_},_}} = (catch ?assertNotEqual(1.0, 1.0)),
+
+ ok = ?assertException(error, badarith, 1/0),
+ ok = ?assertException(exit, foo, exit(foo)),
+ ok = ?assertException(throw, foo, throw(foo)),
+ ok = ?assertException(throw, {foo,_}, throw({foo,bar})),
+ ok = ?assertException(throw, {foo,N} when N > 0, throw({foo,1})),
+ {'EXIT',{{assertException,Why1},_}} =
+ (catch ?assertException(error, badarith, 0/1)),
+ true = lists:keymember(unexpected_success,1,Why1),
+ {'EXIT',{{assertException,Why2},_}} =
+ (catch ?assertException(error, badarith, 1/length(0))),
+ true = lists:keymember(unexpected_exception,1,Why2),
+ {'EXIT',{{assertException,Why3},_}} =
+ (catch ?assertException(throw, {foo,N} when N > 0, throw({foo,0}))),
+ true = lists:keymember(unexpected_exception,1,Why3),
+
+ ok = ?assertNotException(throw, {foo,baz}, throw({foo,bar})),
+ {'EXIT',{{assertNotException,Why4},_}} =
+ (catch ?assertNotException(throw, {foo,bar}, throw({foo,bar}))),
+ true = lists:keymember(unexpected_exception,1,Why4),
+
+ ok = ?assertError(badarith, 1/0),
+ ok = ?assertExit(foo, exit(foo)),
+ ok = ?assertThrow(foo, throw(foo)),
+ ok.
diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl
index fccd1bef95..53eea6f180 100644
--- a/lib/stdlib/test/string_SUITE.erl
+++ b/lib/stdlib/test/string_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -120,7 +121,7 @@ chr_rchr(suite) ->
chr_rchr(doc) ->
[];
chr_rchr(Config) when is_list(Config) ->
- ?line {_,_,X} = now(),
+ {_,_,X} = erlang:timestamp(),
?line 0 = string:chr("", (X rem (255-32)) + 32),
?line 0 = string:rchr("", (X rem (255-32)) + 32),
?line 1 = string:chr("x", $x),
@@ -144,7 +145,7 @@ str_rstr(suite) ->
str_rstr(doc) ->
[];
str_rstr(Config) when is_list(Config) ->
- ?line {_,_,X} = now(),
+ {_,_,X} = erlang:timestamp(),
?line 0 = string:str("", [(X rem (255-32)) + 32]),
?line 0 = string:rstr("", [(X rem (255-32)) + 32]),
?line 1 = string:str("x", "x"),
@@ -217,21 +218,39 @@ substr(Config) when is_list(Config) ->
?line {'EXIT',_} = (catch string:substr("1234", "1")),
ok.
-tokens(suite) ->
- [];
-tokens(doc) ->
- [];
tokens(Config) when is_list(Config) ->
- ?line [] = string:tokens("",""),
- ?line [] = string:tokens("abc","abc"),
- ?line ["abc"] = string:tokens("abc", ""),
- ?line ["1","2 34","4","5"] = string:tokens("1,2 34,4;5", ";,"),
- %% invalid arg type
- ?line {'EXIT',_} = (catch string:tokens('x,y', ",")),
+ [] = string:tokens("",""),
+ [] = string:tokens("abc","abc"),
+ ["abc"] = string:tokens("abc", ""),
+ ["1","2 34","45","5","6","7"] = do_tokens("1,2 34,45;5,;6;,7", ";,"),
+
%% invalid arg type
- ?line {'EXIT',_} = (catch string:tokens("x,y", ',')),
+ {'EXIT',_} = (catch string:tokens('x,y', ",")),
+ {'EXIT',_} = (catch string:tokens("x,y", ',')),
ok.
+do_tokens(S0, Sep0) ->
+ [H|T] = Sep0,
+ S = [replace_sep(C, T, H) || C <- S0],
+ Sep = [H],
+ io:format("~p ~p\n", [S0,Sep0]),
+ io:format("~p ~p\n", [S,Sep]),
+
+ Res = string:tokens(S0, Sep0),
+ Res = string:tokens(Sep0++S0, Sep0),
+ Res = string:tokens(S0++Sep0, Sep0),
+
+ Res = string:tokens(S, Sep),
+ Res = string:tokens(Sep++S, Sep),
+ Res = string:tokens(S++Sep, Sep),
+
+ Res.
+
+replace_sep(C, Seps, New) ->
+ case lists:member(C, Seps) of
+ true -> New;
+ false -> C
+ end.
chars(suite) ->
[];
diff --git a/lib/stdlib/test/supervisor_1.erl b/lib/stdlib/test/supervisor_1.erl
index 777a48e38b..7a74f51429 100644
--- a/lib/stdlib/test/supervisor_1.erl
+++ b/lib/stdlib/test/supervisor_1.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/supervisor_2.erl b/lib/stdlib/test/supervisor_2.erl
index 60d037f4e0..e3767c1fd4 100644
--- a/lib/stdlib/test/supervisor_2.erl
+++ b/lib/stdlib/test/supervisor_2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/supervisor_3.erl b/lib/stdlib/test/supervisor_3.erl
index 0023219ff3..9ff7df2503 100644
--- a/lib/stdlib/test/supervisor_3.erl
+++ b/lib/stdlib/test/supervisor_3.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index 836ea7c030..903ca76575 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -37,9 +38,13 @@
sup_start_ignore_child/1, sup_start_ignore_temporary_child/1,
sup_start_ignore_temporary_child_start_child/1,
sup_start_ignore_temporary_child_start_child_simple/1,
- sup_start_error_return/1, sup_start_fail/1, sup_stop_infinity/1,
- sup_stop_timeout/1, sup_stop_brutal_kill/1, child_adm/1,
- child_adm_simple/1, child_specs/1, extra_return/1]).
+ sup_start_ignore_permanent_child_start_child_simple/1,
+ sup_start_error_return/1, sup_start_fail/1,
+ sup_start_map/1, sup_start_map_simple/1,
+ sup_start_map_faulty_specs/1,
+ sup_stop_infinity/1, sup_stop_timeout/1, sup_stop_brutal_kill/1,
+ child_adm/1, child_adm_simple/1, child_specs/1, extra_return/1,
+ sup_flags/1]).
%% Tests concept permanent, transient and temporary
-export([ permanent_normal/1, transient_normal/1,
@@ -51,7 +56,8 @@
temporary_abnormal/1, temporary_bystander/1]).
%% Restart strategy tests
--export([ one_for_one/1,
+-export([ multiple_restarts/1,
+ one_for_one/1,
one_for_one_escalation/1, one_for_all/1,
one_for_all_escalation/1, one_for_all_other_child_fails_restart/1,
simple_one_for_one/1, simple_one_for_one_escalation/1,
@@ -61,11 +67,13 @@
%% Misc tests
-export([child_unlink/1, tree/1, count_children/1,
+ count_restarting_children/1,
do_not_save_start_parameters_for_temporary_children/1,
do_not_save_child_specs_for_temporary_children/1,
simple_one_for_one_scale_many_temporary_children/1,
simple_global_supervisor/1, hanging_restart_loop/1,
- hanging_restart_loop_simple/1]).
+ hanging_restart_loop_simple/1, code_change/1, code_change_map/1,
+ code_change_simple/1, code_change_simple_map/1]).
%%-------------------------------------------------------------------------
@@ -73,8 +81,9 @@ suite() ->
[{ct_hooks,[ts_install_cth]}].
all() ->
- [{group, sup_start}, {group, sup_stop}, child_adm,
- child_adm_simple, extra_return, child_specs,
+ [{group, sup_start}, {group, sup_start_map}, {group, sup_stop}, child_adm,
+ child_adm_simple, extra_return, child_specs, sup_flags,
+ multiple_restarts,
{group, restart_one_for_one},
{group, restart_one_for_all},
{group, restart_simple_one_for_one},
@@ -82,10 +91,12 @@ all() ->
{group, normal_termination},
{group, shutdown_termination},
{group, abnormal_termination}, child_unlink, tree,
- count_children, do_not_save_start_parameters_for_temporary_children,
+ count_children, count_restarting_children,
+ do_not_save_start_parameters_for_temporary_children,
do_not_save_child_specs_for_temporary_children,
simple_one_for_one_scale_many_temporary_children, temporary_bystander,
- simple_global_supervisor, hanging_restart_loop, hanging_restart_loop_simple].
+ simple_global_supervisor, hanging_restart_loop, hanging_restart_loop_simple,
+ code_change, code_change_map, code_change_simple, code_change_simple_map].
groups() ->
[{sup_start, [],
@@ -93,7 +104,10 @@ groups() ->
sup_start_ignore_child, sup_start_ignore_temporary_child,
sup_start_ignore_temporary_child_start_child,
sup_start_ignore_temporary_child_start_child_simple,
+ sup_start_ignore_permanent_child_start_child_simple,
sup_start_error_return, sup_start_fail]},
+ {sup_start_map, [],
+ [sup_start_map, sup_start_map_simple, sup_start_map_faulty_specs]},
{sup_stop, [],
[sup_stop_infinity, sup_stop_timeout,
sup_stop_brutal_kill]},
@@ -242,6 +256,27 @@ sup_start_ignore_temporary_child_start_child_simple(Config)
[1,1,0,1] = get_child_counts(sup_test).
%%-------------------------------------------------------------------------
+%% Tests what happens if child's init-callback returns ignore for a
+%% permanent child when child is started with start_child/2, and the
+%% supervisor is simple_one_for_one.
+%% Child spec shall NOT be saved!!!
+sup_start_ignore_permanent_child_start_child_simple(Config)
+ when is_list(Config) ->
+ process_flag(trap_exit, true),
+ Child1 = {child1, {supervisor_1, start_child, [ignore]},
+ permanent, 1000, worker, []},
+ {ok, Pid} = start_link({ok, {{simple_one_for_one, 2, 3600}, [Child1]}}),
+
+ {ok, undefined} = supervisor:start_child(sup_test, []),
+ {ok, CPid2} = supervisor:start_child(sup_test, []),
+
+ [{undefined, CPid2, worker, []}] = supervisor:which_children(sup_test),
+ [1,1,0,1] = get_child_counts(sup_test),
+
+ %% Regression test: check that the supervisor terminates without error.
+ exit(Pid, shutdown),
+ check_exit_reason(Pid, shutdown).
+%%-------------------------------------------------------------------------
%% Tests what happens if init-callback returns a invalid value.
sup_start_error_return(Config) when is_list(Config) ->
process_flag(trap_exit, true),
@@ -256,6 +291,84 @@ sup_start_fail(Config) when is_list(Config) ->
check_exit_reason(Term).
%%-------------------------------------------------------------------------
+%% Tests that the supervisor process starts correctly with map
+%% startspec, and that the full childspec can be read.
+sup_start_map(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ Child1 = #{id=>child1, start=>{supervisor_1, start_child, []}},
+ Child2 = #{id=>child2,
+ start=>{supervisor_1, start_child, []},
+ shutdown=>brutal_kill},
+ Child3 = #{id=>child3,
+ start=>{supervisor_1, start_child, []},
+ type=>supervisor},
+ {ok, Pid} = start_link({ok, {#{}, [Child1,Child2,Child3]}}),
+
+ %% Check default values
+ {ok,#{id:=child1,
+ start:={supervisor_1,start_child,[]},
+ restart:=permanent,
+ shutdown:=5000,
+ type:=worker,
+ modules:=[supervisor_1]}} = supervisor:get_childspec(Pid, child1),
+ {ok,#{id:=child2,
+ start:={supervisor_1,start_child,[]},
+ restart:=permanent,
+ shutdown:=brutal_kill,
+ type:=worker,
+ modules:=[supervisor_1]}} = supervisor:get_childspec(Pid, child2),
+ {ok,#{id:=child3,
+ start:={supervisor_1,start_child,[]},
+ restart:=permanent,
+ shutdown:=infinity,
+ type:=supervisor,
+ modules:=[supervisor_1]}} = supervisor:get_childspec(Pid, child3),
+ {error,not_found} = supervisor:get_childspec(Pid, child4),
+ terminate(Pid, shutdown).
+
+%%-------------------------------------------------------------------------
+%% Tests that the supervisor process starts correctly with map
+%% startspec, and that the full childspec can be read when using
+%% simple_one_for_one strategy.
+sup_start_map_simple(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SupFlags = #{strategy=>simple_one_for_one},
+ ChildSpec = #{id=>undefined,
+ start=>{supervisor_1, start_child, []},
+ restart=>temporary},
+ {ok, Pid} = start_link({ok, {SupFlags, [ChildSpec]}}),
+
+ {ok, Child1} = supervisor:start_child(Pid, []),
+ {ok, Child2} = supervisor:start_child(Pid, []),
+ {ok, Child3} = supervisor:start_child(Pid, []),
+
+ Spec = ChildSpec#{type=>worker, shutdown=>5000, modules=>[supervisor_1]},
+
+ {ok, Spec} = supervisor:get_childspec(Pid, Child1),
+ {ok, Spec} = supervisor:get_childspec(Pid, Child2),
+ {ok, Spec} = supervisor:get_childspec(Pid, Child3),
+ {error,not_found} = supervisor:get_childspec(Pid, self()),
+ terminate(Pid, shutdown).
+
+%%-------------------------------------------------------------------------
+%% Tests that the supervisor produces good error messages when start-
+%% and child specs are faulty.
+sup_start_map_faulty_specs(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ Child1 = #{start=>{supervisor_1, start_child, []}},
+ Child2 = #{id=>child2},
+ Child3 = #{id=>child3,
+ start=>{supervisor_1, start_child, []},
+ silly_flag=>true},
+ Child4 = child4,
+ {error,{start_spec,missing_id}} = start_link({ok, {#{}, [Child1]}}),
+ {error,{start_spec,missing_start}} = start_link({ok, {#{}, [Child2]}}),
+ {ok,Pid} = start_link({ok, {#{}, [Child3]}}),
+ terminate(Pid,shutdown),
+ {error,{start_spec,{invalid_child_spec,child4}}} =
+ start_link({ok, {#{}, [Child4]}}).
+
+%%-------------------------------------------------------------------------
%% See sup_stop/1 when Shutdown = infinity, this walue is allowed for
%% children of type supervisor _AND_ worker.
sup_stop_infinity(Config) when is_list(Config) ->
@@ -479,7 +592,7 @@ child_adm_simple(Config) when is_list(Config) ->
%% Tests child specs, invalid formats should be rejected.
child_specs(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- {ok, _Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}),
+ {ok, Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}),
{error, _} = supervisor:start_child(sup_test, hej),
%% Bad child specs
@@ -509,6 +622,7 @@ child_specs(Config) when is_list(Config) ->
{error, {invalid_modules,dy}}
= supervisor:start_child(sup_test, B5),
+ {error, {badarg, _}} = supervisor:check_childspecs(B1), % should be list
{error, {invalid_mfa,mfa}} = supervisor:check_childspecs([B1]),
{error, {invalid_restart_type,prmanent}} =
supervisor:check_childspecs([B2]),
@@ -524,6 +638,54 @@ child_specs(Config) when is_list(Config) ->
ok = supervisor:check_childspecs([C3]),
ok = supervisor:check_childspecs([C4]),
ok = supervisor:check_childspecs([C5]),
+
+ {error,{duplicate_child_name,child}} = supervisor:check_childspecs([C1,C2]),
+
+ terminate(Pid, shutdown),
+
+ %% Faulty child specs in supervisor start
+ {error, {start_spec, {invalid_mfa, mfa}}} =
+ start_link({ok, {{one_for_one, 2, 3600}, [B1]}}),
+ {error, {start_spec, {invalid_restart_type, prmanent}}} =
+ start_link({ok, {{simple_one_for_one, 2, 3600}, [B2]}}),
+
+ %% simple_one_for_one needs exactly one child
+ {error,{bad_start_spec,[]}} =
+ start_link({ok, {{simple_one_for_one, 2, 3600}, []}}),
+ {error,{bad_start_spec,[C1,C2]}} =
+ start_link({ok, {{simple_one_for_one, 2, 3600}, [C1,C2]}}),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test error handling of supervisor flags
+sup_flags(_Config) ->
+ process_flag(trap_exit,true),
+ {error,{supervisor_data,{invalid_strategy,_}}} =
+ start_link({ok, {{none_for_one, 2, 3600}, []}}),
+ {error,{supervisor_data,{invalid_strategy,_}}} =
+ start_link({ok, {#{strategy=>none_for_one}, []}}),
+ {error,{supervisor_data,{invalid_intensity,_}}} =
+ start_link({ok, {{one_for_one, infinity, 3600}, []}}),
+ {error,{supervisor_data,{invalid_intensity,_}}} =
+ start_link({ok, {#{intensity=>infinity}, []}}),
+ {error,{supervisor_data,{invalid_period,_}}} =
+ start_link({ok, {{one_for_one, 2, 0}, []}}),
+ {error,{supervisor_data,{invalid_period,_}}} =
+ start_link({ok, {#{period=>0}, []}}),
+ {error,{supervisor_data,{invalid_period,_}}} =
+ start_link({ok, {{one_for_one, 2, infinity}, []}}),
+ {error,{supervisor_data,{invalid_period,_}}} =
+ start_link({ok, {#{period=>infinity}, []}}),
+
+ %% SupFlags other than a map or a 3-tuple
+ {error,{supervisor_data,{invalid_type,_}}} =
+ start_link({ok, {{one_for_one, 2}, []}}),
+
+ %% Unexpected flags are ignored
+ {ok,Pid} = start_link({ok,{#{silly_flag=>true},[]}}),
+ terminate(Pid,shutdown),
+
ok.
%%-------------------------------------------------------------------------
@@ -764,6 +926,39 @@ temporary_bystander(_Config) ->
[{child1, _, _, _}] = supervisor:which_children(SupPid2).
%%-------------------------------------------------------------------------
+%% Test restarting a process multiple times, being careful not
+%% to exceed the maximum restart frquency.
+multiple_restarts(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ Child1 = #{id => child1,
+ start => {supervisor_1, start_child, []},
+ restart => permanent,
+ shutdown => brutal_kill,
+ type => worker,
+ modules => []},
+ SupFlags = #{strategy => one_for_one,
+ intensity => 1,
+ period => 1},
+ {ok, SupPid} = start_link({ok, {SupFlags, []}}),
+ {ok, CPid1} = supervisor:start_child(sup_test, Child1),
+
+ %% Terminate the process several times, but being careful
+ %% not to exceed the maximum restart intensity.
+ terminate(SupPid, CPid1, child1, abnormal),
+ _ = [begin
+ receive after 2100 -> ok end,
+ [{_, Pid, _, _}|_] = supervisor:which_children(sup_test),
+ terminate(SupPid, Pid, child1, abnormal)
+ end || _ <- [1,2,3]],
+
+ %% Verify that the supervisor is still alive and clean up.
+ ok = supervisor:terminate_child(SupPid, child1),
+ ok = supervisor:delete_child(SupPid, child1),
+ exit(SupPid, kill),
+ ok.
+
+
+%%-------------------------------------------------------------------------
%% Test the one_for_one base case.
one_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
@@ -1266,6 +1461,54 @@ count_children(Config) when is_list(Config) ->
[1,0,0,0] = get_child_counts(sup_test).
%%-------------------------------------------------------------------------
+%% Test count_children when some children are restarting
+count_restarting_children(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ Child = {child, {supervisor_deadlock, start_child_noreg, []},
+ permanent, brutal_kill, worker, []},
+ %% 2 sek delay on failing restart (see supervisor_deadlock.erl) ->
+ %% MaxR=20, MaxT=10 should ensure a restart loop when starting and
+ %% restarting 3 instances of the child (as below)
+ {ok, SupPid} = start_link({ok, {{simple_one_for_one, 20, 10}, [Child]}}),
+
+ %% Ets table with state read by supervisor_deadlock.erl
+ ets:new(supervisor_deadlock,[set,named_table,public]),
+ ets:insert(supervisor_deadlock,{fail_start,false}),
+
+ [1,0,0,0] = get_child_counts(SupPid),
+ {ok, Ch1_1} = supervisor:start_child(SupPid, []),
+ [1,1,0,1] = get_child_counts(SupPid),
+ {ok, Ch1_2} = supervisor:start_child(SupPid, []),
+ [1,2,0,2] = get_child_counts(SupPid),
+ {ok, Ch1_3} = supervisor:start_child(SupPid, []),
+ [1,3,0,3] = get_child_counts(SupPid),
+
+ supervisor_deadlock:restart_child(Ch1_1),
+ supervisor_deadlock:restart_child(Ch1_2),
+ supervisor_deadlock:restart_child(Ch1_3),
+ test_server:sleep(400),
+ [1,3,0,3] = get_child_counts(SupPid),
+ [Ch2_1, Ch2_2, Ch2_3] = [C || {_,C,_,_} <- supervisor:which_children(SupPid)],
+
+ ets:insert(supervisor_deadlock,{fail_start,true}),
+ supervisor_deadlock:restart_child(Ch2_1),
+ supervisor_deadlock:restart_child(Ch2_2),
+ test_server:sleep(4000), % allow restart to happen before proceeding
+ [1,1,0,3] = get_child_counts(SupPid),
+
+ ets:insert(supervisor_deadlock,{fail_start,false}),
+ test_server:sleep(4000), % allow restart to happen before proceeding
+ [1,3,0,3] = get_child_counts(SupPid),
+
+ ok = supervisor:terminate_child(SupPid, Ch2_3),
+ [1,2,0,2] = get_child_counts(SupPid),
+ [Ch3_1, Ch3_2] = [C || {_,C,_,_} <- supervisor:which_children(SupPid)],
+ ok = supervisor:terminate_child(SupPid, Ch3_1),
+ [1,1,0,1] = get_child_counts(SupPid),
+ ok = supervisor:terminate_child(SupPid, Ch3_2),
+ [1,0,0,0] = get_child_counts(SupPid).
+
+%%-------------------------------------------------------------------------
%% Temporary children shall not be restarted so they should not save
%% start parameters, as it potentially can take up a huge amount of
%% memory for no purpose.
@@ -1647,6 +1890,186 @@ hanging_restart_loop_simple(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
+%% Test the code_change function
+code_change(_Config) ->
+ process_flag(trap_exit, true),
+
+ SupFlags = {one_for_one, 0, 1},
+ {ok, Pid} = start_link({ok, {SupFlags, []}}),
+ [] = supervisor:which_children(Pid),
+
+ %% Change supervisor flags
+ S1 = sys:get_state(Pid),
+ ok = fake_upgrade(Pid,{ok, {{one_for_one, 1, 3}, []}}),
+ S2 = sys:get_state(Pid),
+ true = (S1 /= S2),
+
+ %% Faulty childspec
+ FaultyChild = {child1, permanent, brutal_kill, worker, []}, % missing start
+ {error,{error,{invalid_child_spec,FaultyChild}}} =
+ fake_upgrade(Pid,{ok,{SupFlags,[FaultyChild]}}),
+
+ %% Add child1 and child2
+ Child1 = {child1, {supervisor_1, start_child, []},
+ permanent, 2000, worker, []},
+ Child2 = {child2, {supervisor_1, start_child, []},
+ permanent, brutal_kill, worker, []},
+ ok = fake_upgrade(Pid,{ok,{SupFlags,[Child1,Child2]}}),
+ %% Children are not automatically started
+ {ok,_} = supervisor:restart_child(Pid,child1),
+ {ok,_} = supervisor:restart_child(Pid,child2),
+ [{child2,_,_,_},{child1,_,_,_}] = supervisor:which_children(Pid),
+
+ %% Change child1, remove child2 and add child3
+ Child11 = {child1, {supervisor_1, start_child, []},
+ permanent, 1000, worker, []},
+ Child3 = {child3, {supervisor_1, start_child, []},
+ permanent, brutal_kill, worker, []},
+ ok = fake_upgrade(Pid,{ok, {SupFlags, [Child11,Child3]}}),
+ %% Children are not deleted on upgrade, so it is ok that child2 is
+ %% still here
+ [{child2,_,_,_},{child3,_,_,_},{child1,_,_,_}] =
+ supervisor:which_children(Pid),
+
+ %% Ignore during upgrade
+ ok = fake_upgrade(Pid,ignore),
+
+ %% Error during upgrade
+ {error, faulty_return} = fake_upgrade(Pid,faulty_return),
+
+ %% Faulty flags
+ {error,{error, {invalid_intensity,faulty_intensity}}} =
+ fake_upgrade(Pid,{ok, {{one_for_one,faulty_intensity,1}, []}}),
+ {error,{error,{bad_flags, faulty_flags}}} =
+ fake_upgrade(Pid,{ok, {faulty_flags, []}}),
+
+ terminate(Pid,shutdown).
+
+code_change_map(_Config) ->
+ process_flag(trap_exit, true),
+
+ {ok, Pid} = start_link({ok, {#{}, []}}),
+ [] = supervisor:which_children(Pid),
+
+ %% Change supervisor flags
+ S1 = sys:get_state(Pid),
+ ok = fake_upgrade(Pid,{ok, {#{intensity=>1, period=>3}, []}}),
+ S2 = sys:get_state(Pid),
+ true = (S1 /= S2),
+
+ %% Faulty childspec
+ FaultyChild = #{id=>faulty_child},
+ {error,{error,missing_start}} =
+ fake_upgrade(Pid,{ok,{#{},[FaultyChild]}}),
+
+ %% Add child1 and child2
+ Child1 = #{id=>child1,
+ start=>{supervisor_1, start_child, []},
+ shutdown=>2000},
+ Child2 = #{id=>child2,
+ start=>{supervisor_1, start_child, []}},
+ ok = fake_upgrade(Pid,{ok,{#{},[Child1,Child2]}}),
+ %% Children are not automatically started
+ {ok,_} = supervisor:restart_child(Pid,child1),
+ {ok,_} = supervisor:restart_child(Pid,child2),
+ [{child2,_,_,_},{child1,_,_,_}] = supervisor:which_children(Pid),
+ {ok,#{shutdown:=2000}} = supervisor:get_childspec(Pid,child1),
+
+ %% Change child1, remove child2 and add child3
+ Child11 = #{id=>child1,
+ start=>{supervisor_1, start_child, []},
+ shutdown=>1000},
+ Child3 = #{id=>child3,
+ start=>{supervisor_1, start_child, []}},
+ ok = fake_upgrade(Pid,{ok, {#{}, [Child11,Child3]}}),
+ %% Children are not deleted on upgrade, so it is ok that child2 is
+ %% still here
+ [{child2,_,_,_},{child3,_,_,_},{child1,_,_,_}] =
+ supervisor:which_children(Pid),
+ {ok,#{shutdown:=1000}} = supervisor:get_childspec(Pid,child1),
+
+ %% Ignore during upgrade
+ ok = fake_upgrade(Pid,ignore),
+
+ %% Error during upgrade
+ {error, faulty_return} = fake_upgrade(Pid,faulty_return),
+
+ %% Faulty flags
+ {error,{error, {invalid_intensity,faulty_intensity}}} =
+ fake_upgrade(Pid,{ok, {#{intensity=>faulty_intensity}, []}}),
+
+ terminate(Pid,shutdown).
+
+code_change_simple(_Config) ->
+ process_flag(trap_exit, true),
+
+ SimpleChild1 = {child1,{supervisor_1, start_child, []}, permanent,
+ brutal_kill, worker, []},
+ SimpleFlags = {simple_one_for_one, 0, 1},
+ {ok, SimplePid} = start_link({ok, {SimpleFlags,[SimpleChild1]}}),
+ %% Change childspec
+ SimpleChild11 = {child1,{supervisor_1, start_child, []}, permanent,
+ 1000, worker, []},
+ ok = fake_upgrade(SimplePid,{ok,{SimpleFlags,[SimpleChild11]}}),
+
+ %% Attempt to add child
+ SimpleChild2 = {child2,{supervisor_1, start_child, []}, permanent,
+ brutal_kill, worker, []},
+
+ {error, {error, {ok,[_,_]}}} =
+ fake_upgrade(SimplePid,{ok,{SimpleFlags,[SimpleChild1,SimpleChild2]}}),
+
+ %% Attempt to remove child
+ {error, {error, {ok,[]}}} = fake_upgrade(SimplePid,{ok,{SimpleFlags,[]}}),
+
+ terminate(SimplePid,shutdown),
+ ok.
+
+code_change_simple_map(_Config) ->
+ process_flag(trap_exit, true),
+
+ SimpleChild1 = #{id=>child1,
+ start=>{supervisor_1, start_child, []}},
+ SimpleFlags = #{strategy=>simple_one_for_one},
+ {ok, SimplePid} = start_link({ok, {SimpleFlags,[SimpleChild1]}}),
+ %% Change childspec
+ SimpleChild11 = #{id=>child1,
+ start=>{supervisor_1, start_child, []},
+ shutdown=>1000},
+ ok = fake_upgrade(SimplePid,{ok,{SimpleFlags,[SimpleChild11]}}),
+
+ %% Attempt to add child
+ SimpleChild2 = #{id=>child2,
+ start=>{supervisor_1, start_child, []}},
+ {error, {error, {ok, [_,_]}}} =
+ fake_upgrade(SimplePid,{ok,{SimpleFlags,[SimpleChild1,SimpleChild2]}}),
+
+ %% Attempt to remove child
+ {error, {error, {ok, []}}} =
+ fake_upgrade(SimplePid,{ok,{SimpleFlags,[]}}),
+
+ terminate(SimplePid,shutdown),
+ ok.
+
+fake_upgrade(Pid,NewInitReturn) ->
+ ok = sys:suspend(Pid),
+
+ %% Update state to fake code change
+ %% The #state record in supervisor.erl holds the arguments given
+ %% to the callback init function. By replacing these arguments the
+ %% init function will return something new and by that fake a code
+ %% change (see init function above in this module).
+ Fun = fun(State) ->
+ Size = size(State), % 'args' is the last field in #state.
+ setelement(Size,State,NewInitReturn)
+ end,
+ sys:replace_state(Pid,Fun),
+
+ R = sys:change_code(Pid,gen_server,dummy_vsn,[]),
+ ok = sys:resume(Pid),
+ R.
+
+%%-------------------------------------------------------------------------
terminate(Pid, Reason) when Reason =/= supervisor ->
terminate(dummy, Pid, dummy, Reason).
diff --git a/lib/stdlib/test/supervisor_bridge_SUITE.erl b/lib/stdlib/test/supervisor_bridge_SUITE.erl
index b3056ff41a..b55fbfaf0d 100644
--- a/lib/stdlib/test/supervisor_bridge_SUITE.erl
+++ b/lib/stdlib/test/supervisor_bridge_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/supervisor_deadlock.erl b/lib/stdlib/test/supervisor_deadlock.erl
index 288547a972..8d3d1c6f30 100644
--- a/lib/stdlib/test/supervisor_deadlock.erl
+++ b/lib/stdlib/test/supervisor_deadlock.erl
@@ -11,9 +11,11 @@ init([child]) ->
%% terminates immediately
{ok, []};
[{fail_start, true}] ->
- %% Restart frequency is MaxR=8, MaxT=10, so this will
- %% ensure that restart intensity is not reached -> restart
- %% loop
+ %% A restart frequency of MaxR=8, MaxT=10 should ensure
+ %% that restart intensity is not reached -> restart loop.
+ %% (Note that if we use simple_one_for_one, and start
+ %% 'many' child instances, the restart frequency must be
+ %% ajusted accordingly.)
timer:sleep(2000), % NOTE: this could be a gen_server call timeout
{stop, error}
@@ -41,5 +43,11 @@ code_change(_OldVsn, State, _Extra) ->
start_child() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [child], []).
+start_child_noreg() ->
+ gen_server:start_link(?MODULE, [child], []).
+
restart_child() ->
gen_server:cast(supervisor_deadlock, restart).
+
+restart_child(Pid) ->
+ gen_server:cast(Pid, restart).
diff --git a/lib/stdlib/test/sys_SUITE.erl b/lib/stdlib/test/sys_SUITE.erl
index f38bc87ae5..573fa6f358 100644
--- a/lib/stdlib/test/sys_SUITE.erl
+++ b/lib/stdlib/test/sys_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -202,14 +203,7 @@ spec_proc(Mod) ->
{Mod,system_get_state},{throw,fail}},_}} ->
ok
end,
- Mod:stop(),
- WaitForUnregister = fun W() ->
- case whereis(Mod) of
- undefined -> ok;
- _ -> timer:sleep(10), W()
- end
- end,
- WaitForUnregister(),
+ ok = sys:terminate(Mod, normal),
{ok,_} = Mod:start_link(4),
ok = case catch sys:replace_state(Mod, fun(_) -> {} end) of
{} ->
@@ -218,8 +212,7 @@ spec_proc(Mod) ->
{Mod,system_replace_state},{throw,fail}},_}} ->
ok
end,
- Mod:stop(),
- WaitForUnregister(),
+ ok = sys:terminate(Mod, normal),
{ok,_} = Mod:start_link(4),
StateFun = fun(_) -> error(fail) end,
ok = case catch sys:replace_state(Mod, StateFun) of
@@ -231,7 +224,7 @@ spec_proc(Mod) ->
{'EXIT',{{callback_failed,StateFun,{error,fail}},_}} ->
ok
end,
- Mod:stop().
+ ok = sys:terminate(Mod, normal).
%%%%%%%%%%%%%%%%%%%%
%% Dummy server
diff --git a/lib/stdlib/test/sys_sp1.erl b/lib/stdlib/test/sys_sp1.erl
index e84ffcfa12..b99914f4b7 100644
--- a/lib/stdlib/test/sys_sp1.erl
+++ b/lib/stdlib/test/sys_sp1.erl
@@ -1,23 +1,24 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(sys_sp1).
--export([start_link/1, stop/0]).
+-export([start_link/1]).
-export([alloc/0, free/1]).
-export([init/1]).
-export([system_continue/3, system_terminate/4,
@@ -31,10 +32,6 @@
start_link(NumCh) ->
proc_lib:start_link(?MODULE, init, [[self(),NumCh]]).
-stop() ->
- ?MODULE ! stop,
- ok.
-
alloc() ->
?MODULE ! {self(), alloc},
receive
@@ -70,11 +67,7 @@ loop(Chs, Parent, Deb) ->
loop(Chs2, Parent, Deb2);
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent,
- ?MODULE, Deb, Chs);
- stop ->
- sys:handle_debug(Deb, fun write_debug/3,
- ?MODULE, {in, stop}),
- ok
+ ?MODULE, Deb, Chs)
end.
system_continue(Parent, Deb, Chs) ->
diff --git a/lib/stdlib/test/sys_sp2.erl b/lib/stdlib/test/sys_sp2.erl
index 56a5e4d071..e2784dc3ff 100644
--- a/lib/stdlib/test/sys_sp2.erl
+++ b/lib/stdlib/test/sys_sp2.erl
@@ -1,23 +1,24 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(sys_sp2).
--export([start_link/1, stop/0]).
+-export([start_link/1]).
-export([alloc/0, free/1]).
-export([init/1]).
-export([system_continue/3, system_terminate/4,
@@ -30,10 +31,6 @@
start_link(NumCh) ->
proc_lib:start_link(?MODULE, init, [[self(),NumCh]]).
-stop() ->
- ?MODULE ! stop,
- ok.
-
alloc() ->
?MODULE ! {self(), alloc},
receive
@@ -45,11 +42,6 @@ free(Ch) ->
?MODULE ! {free, Ch},
ok.
-%% can't use 2-tuple for state here as we do in sys_sp1, since the 2-tuple
-%% is not compatible with the backward compatibility handling for
-%% sys:get_state in sys.erl
--record(state, {alloc,free}).
-
init([Parent,NumCh]) ->
register(?MODULE, self()),
Chs = channels(NumCh),
@@ -74,11 +66,7 @@ loop(Chs, Parent, Deb) ->
loop(Chs2, Parent, Deb2);
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent,
- ?MODULE, Deb, Chs);
- stop ->
- sys:handle_debug(Deb, fun write_debug/3,
- ?MODULE, {in, stop}),
- ok
+ ?MODULE, Deb, Chs)
end.
system_continue(Parent, Deb, Chs) ->
@@ -91,17 +79,17 @@ write_debug(Dev, Event, Name) ->
io:format(Dev, "~p event = ~p~n", [Name, Event]).
channels(NumCh) ->
- #state{alloc=[], free=lists:seq(1,NumCh)}.
+ {_Allocated=[], _Free=lists:seq(1,NumCh)}.
-alloc(#state{free=[]}=Channels) ->
- {{error, "no channels available"}, Channels};
-alloc(#state{alloc=Allocated, free=[H|T]}) ->
- {H, #state{alloc=[H|Allocated], free=T}}.
+alloc({_, []}) ->
+ {error, "no channels available"};
+alloc({Allocated, [H|T]}) ->
+ {H, {[H|Allocated], T}}.
-free(Ch, #state{alloc=Alloc, free=Free}=Channels) ->
+free(Ch, {Alloc, Free}=Channels) ->
case lists:member(Ch, Alloc) of
true ->
- #state{alloc=lists:delete(Ch, Alloc), free=[Ch|Free]};
+ {lists:delete(Ch, Alloc), [Ch|Free]};
false ->
Channels
end.
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 9b6d65011e..6da017f818 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -89,7 +90,7 @@ borderline_test(Size, TempDir) ->
?line io:format("Testing size ~p", [Size]),
%% Create a file and archive it.
- ?line {_, _, X0} = erlang:now(),
+ X0 = erlang:monotonic_time(),
?line file:write_file(Name, random_byte_list(X0, Size)),
?line ok = erl_tar:create(Archive, [Name]),
?line ok = file:delete(Name),
diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl
index bea2b3fb2a..057d82fb65 100644
--- a/lib/stdlib/test/timer_SUITE.erl
+++ b/lib/stdlib/test/timer_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -25,14 +26,11 @@
-include_lib("test_server/include/test_server.hrl").
-%% Test suite for timer module. This is a really nasty test it runs a
-%% lot of timeouts and then checks in the end if any of them was
-%% trigggered too early or if any late timeouts was much too
-%% late. What should be added is more testing of the interface
-%% functions I guess. But I don't have time for that now.
+%% Random test of the timer module. This is a really nasty test, as it
+%% runs a lot of timeouts and then checks in the end if any of them
+%% was triggered too early or if any late timeouts was much too late.
%%
-%% Expect it to run for at least 5-10 minutes!
-
+%% Running time on average is about 90 seconds.
%% The main test case in this module is "do_big_test", which
%% orders a large number of timeouts and measures how
@@ -40,15 +38,8 @@
%% also a number of other concurrent processes running "nrev" at the same
%% time. The result is analyzed afterwards by trying to check if the
%% measured values are reasonable. It is hard to determine what is
-%% reasonable on different machines therefore the test can sometimes
-%% fail, even though the timer module is ok. I have checked against
-%% previous versions of the timer module (which contained bugs) and it
-%% seems it fails every time when running the buggy timer modules.
-%%
-%% The solution is to rewrite the test suite. Possible strategies for a
-%% rewrite: smarter math on the measuring data, test cases with varying
-%% amount of load. The test suite should also include tests that test the
-%% interface of the timer module.
+%% reasonable on different machines; therefore the test can sometimes
+%% fail, even though the timer module is ok.
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -89,10 +80,7 @@ report_result(Error) -> ?line test_server:fail(Error).
big_test(N) ->
C = start_collect(),
system_time(), system_time(), system_time(),
- A1 = element(2, erlang:now()),
- A2 = A1 * 3,
- A3 = element(3, erlang:now()),
- random:seed(A1, A2, A3),
+ random:seed(erlang:timestamp()),
random:uniform(100),random:uniform(100),random:uniform(100),
big_loop(C, N, []),
@@ -146,7 +134,7 @@ big_loop(C, N, Pids) ->
%%Pids2=Pids1,
%% wait a little while
- timer:sleep(random:uniform(200)*10),
+ timer:sleep(random:uniform(200)*3),
%% spawn zero, one or two nrev to get some load ;-/
Pids3 = start_nrev(Pids2, random:uniform(100)),
@@ -166,14 +154,14 @@ start_nrev(Pids, _N) ->
start_after_test(Pids, C, 1) ->
- TO1 = random:uniform(100)*100,
+ TO1 = random:uniform(100)*47,
[s_a_t(C, TO1)|Pids];
start_after_test(Pids, C, 2) ->
- TO1 = random:uniform(100)*100,
- TO2 = TO1 div random:uniform(3) + 200,
+ TO1 = random:uniform(100)*47,
+ TO2 = TO1 div random:uniform(3) + 101,
[s_a_t(C, TO1),s_a_t(C, TO2)|Pids];
start_after_test(Pids, C, N) ->
- TO1 = random:uniform(100)*100,
+ TO1 = random:uniform(100)*47,
start_after_test([s_a_t(C, TO1)|Pids], C, N-1).
s_a_t(C, TimeOut) ->
@@ -199,7 +187,7 @@ a_t(C, TimeOut) ->
maybe_start_i_test(Pids, C, 1) ->
%% ok do it
- TOI = random:uniform(100)*100,
+ TOI = random:uniform(53)*49,
CountI = random:uniform(10) + 3, % at least 4 times
[spawn_link(timer_SUITE, i_t, [C, TOI, CountI])|Pids];
maybe_start_i_test(Pids, _C, _) ->
@@ -374,9 +362,7 @@ res_combine({error,Es}, [{error,E}|T]) ->
system_time() ->
- %%element(1, statistics(wall_clock)).
- {M,S,U} = erlang:now(),
- 1000000000 * M + 1000 * S + (U div 1000).
+ erlang:monotonic_time(milli_seconds).
%% ------------------------------------------------------- %%
diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl
index dc751aad16..93fbc3a032 100644
--- a/lib/stdlib/test/timer_simple_SUITE.erl
+++ b/lib/stdlib/test/timer_simple_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -374,7 +375,6 @@ performance(Mod) ->
big_test(M) ->
Load_Pids = start_nrev(20, M), % Increase if more load wanted :)
- apply(M, sleep, [9000]),
LPids = spawn_timers(5, M, 10000, 5),
apply(M, sleep, [4000]),
@@ -483,8 +483,7 @@ append([],X) ->
X.
system_time() ->
- {M,S,U} = erlang:now(),
- 1000000*(M*1000000 + S) + U.
+ erlang:monotonic_time(micro_seconds).
%% ------------------------------------------------------- %%
diff --git a/lib/stdlib/test/unicode_SUITE.erl b/lib/stdlib/test/unicode_SUITE.erl
index 10b29d0d28..8bb2555213 100644
--- a/lib/stdlib/test/unicode_SUITE.erl
+++ b/lib/stdlib/test/unicode_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,13 @@
random_lists/1,
roundtrips/1,
latin1/1,
- exceptions/1, binaries_errors/1]).
+ exceptions/1,
+ binaries_errors_limit/1,
+ ex_binaries_errors_utf8/1,
+ ex_binaries_errors_utf16_little/1,
+ ex_binaries_errors_utf16_big/1,
+ ex_binaries_errors_utf32_little/1,
+ ex_binaries_errors_utf32_big/1]).
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(20)),
@@ -44,10 +51,17 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[utf8_illegal_sequences_bif,
utf16_illegal_sequences_bif, random_lists, roundtrips,
- latin1, exceptions, binaries_errors].
+ latin1, exceptions,
+ binaries_errors_limit,
+ {group,binaries_errors}].
groups() ->
- [].
+ [{binaries_errors,[parallel],
+ [ex_binaries_errors_utf8,
+ ex_binaries_errors_utf16_little,
+ ex_binaries_errors_utf16_big,
+ ex_binaries_errors_utf32_little,
+ ex_binaries_errors_utf32_big]}].
init_per_suite(Config) ->
Config.
@@ -61,15 +75,11 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-binaries_errors(Config) when is_list(Config) ->
+binaries_errors_limit(Config) when is_list(Config) ->
setlimit(10),
ex_binaries_errors_utf8(Config),
setlimit(default),
- ex_binaries_errors_utf8(Config),
- ex_binaries_errors_utf16_little(Config),
- ex_binaries_errors_utf16_big(Config),
- ex_binaries_errors_utf32_little(Config),
- ex_binaries_errors_utf32_big(Config).
+ ok.
ex_binaries_errors_utf8(Config) when is_list(Config) ->
%% Original smoke test, we should not forget the original offset...
@@ -78,8 +88,9 @@ ex_binaries_errors_utf8(Config) when is_list(Config) ->
%% Now, try with longer binary (trapping)
BrokenPart = list_to_binary(lists:seq(128,255)),
BrokenSz = byte_size(BrokenPart),
+ Seq255 = lists:seq(1,255),
[ begin
- OKList = lists:flatten(lists:duplicate(N,lists:seq(1,255))),
+ OKList = lists:flatten(lists:duplicate(N,Seq255)),
OKBin = unicode:characters_to_binary(OKList),
OKLen = length(OKList),
%% Copy to avoid that the binary get's writable
@@ -102,109 +113,84 @@ ex_binaries_errors_utf8(Config) when is_list(Config) ->
ok.
ex_binaries_errors_utf16_little(Config) when is_list(Config) ->
- BrokenPart = << <<X:16/little>> || X <- lists:seq(16#DC00,16#DFFF) >>,
- BrokenSz = byte_size(BrokenPart),
- [ begin
- OKList = lists:flatten(lists:duplicate(N,lists:seq(1,255))),
- OKBin = unicode:characters_to_binary(OKList,unicode,{utf16,little}),
- OKLen = length(OKList),
- %% Copy to avoid that the binary get's writable
- PartlyBroken = binary:copy(<<OKBin/binary, BrokenPart/binary>>),
- PBSz = byte_size(PartlyBroken),
- {error,OKList,DeepBrokenPart} =
- unicode:characters_to_list(PartlyBroken,{utf16,little}),
- BrokenPart = iolist_to_binary(DeepBrokenPart),
- [ begin
- NewList = lists:nthtail(X, OKList),
- NewSz = byte_size(unicode:characters_to_binary(NewList,unicode,{utf16,little})) +
- BrokenSz,
- Chomped = binary:part(PartlyBroken,PBSz - NewSz, NewSz),
- true = (binary:referenced_byte_size(Chomped) =:= PBSz),
- {error,NewList,DeepBrokenPart2} =
- unicode:characters_to_list(Chomped,{utf16,little}),
- BrokenPart = iolist_to_binary(DeepBrokenPart2)
- end || X <- lists:seq(1,OKLen) ]
- end || N <- lists:seq(1,16,3) ],
- ok.
+ ex_binaries_errors_utf16(little).
+
ex_binaries_errors_utf16_big(Config) when is_list(Config) ->
- BrokenPart = << <<X:16/big>> || X <- lists:seq(16#DC00,16#DFFF) >>,
+ ex_binaries_errors_utf16(big).
+
+ex_binaries_errors_utf16(Endian) ->
+ BrokenSeq = lists:seq(16#DC00, 16#DFFF),
+ BrokenPart = case Endian of
+ little ->
+ << <<X:16/little>> || X <- BrokenSeq >>;
+ big ->
+ << <<X:16/big>> || X <- BrokenSeq >>
+ end,
BrokenSz = byte_size(BrokenPart),
+ Seq255 = lists:seq(1, 255),
[ begin
- OKList = lists:flatten(lists:duplicate(N,lists:seq(1,255))),
- OKBin = unicode:characters_to_binary(OKList,unicode,{utf16,big}),
- OKLen = length(OKList),
- %% Copy to avoid that the binary get's writable
- PartlyBroken = binary:copy(<<OKBin/binary, BrokenPart/binary>>),
+ OKList = lists:append(lists:duplicate(N, Seq255)),
+ OKBin = unicode:characters_to_binary(OKList, unicode, {utf16,Endian}),
+ PartlyBroken = iolist_to_binary([OKBin,BrokenPart]),
PBSz = byte_size(PartlyBroken),
{error,OKList,DeepBrokenPart} =
- unicode:characters_to_list(PartlyBroken,{utf16,big}),
+ unicode:characters_to_list(PartlyBroken, {utf16,Endian}),
BrokenPart = iolist_to_binary(DeepBrokenPart),
- [ begin
- NewList = lists:nthtail(X, OKList),
- NewSz = byte_size(unicode:characters_to_binary(NewList,unicode,{utf16,big})) +
- BrokenSz,
- Chomped = binary:part(PartlyBroken,PBSz - NewSz, NewSz),
- true = (binary:referenced_byte_size(Chomped) =:= PBSz),
- {error,NewList,DeepBrokenPart2} =
- unicode:characters_to_list(Chomped,{utf16,big}),
- BrokenPart = iolist_to_binary(DeepBrokenPart2)
- end || X <- lists:seq(1,OKLen) ]
- end || N <- lists:seq(1,16,3) ],
+ utf16_inner_loop(OKList, BrokenPart, BrokenSz,
+ PartlyBroken, PBSz, Endian)
+ end || N <- lists:seq(1, 16, 3) ],
+ ok.
+
+utf16_inner_loop([_|List], BrokenPart, BrokenSz, PartlyBroken, PBSz, Endian) ->
+ Sz = length(List)*2 + BrokenSz,
+ Chomped = binary:part(PartlyBroken, PBSz - Sz, Sz),
+ true = binary:referenced_byte_size(Chomped) =:= PBSz,
+ {error,List,DeepBrokenPart} =
+ unicode:characters_to_list(Chomped, {utf16,Endian}),
+ BrokenPart = iolist_to_binary(DeepBrokenPart),
+ utf16_inner_loop(List, BrokenPart, BrokenSz, PartlyBroken, PBSz, Endian);
+utf16_inner_loop([], _, _, _, _, _) ->
ok.
ex_binaries_errors_utf32_big(Config) when is_list(Config) ->
- BrokenPart = << <<X:32/big>> || X <- lists:seq(16#DC00,16#DFFF) >>,
- BrokenSz = byte_size(BrokenPart),
- [ begin
- OKList = lists:flatten(lists:duplicate(N,lists:seq(1,255))),
- OKBin = unicode:characters_to_binary(OKList,unicode,{utf32,big}),
- OKLen = length(OKList),
- %% Copy to avoid that the binary get's writable
- PartlyBroken = binary:copy(<<OKBin/binary, BrokenPart/binary>>),
- PBSz = byte_size(PartlyBroken),
- {error,OKList,DeepBrokenPart} =
- unicode:characters_to_list(PartlyBroken,{utf32,big}),
- BrokenPart = iolist_to_binary(DeepBrokenPart),
- [ begin
- NewList = lists:nthtail(X, OKList),
- NewSz = byte_size(unicode:characters_to_binary(NewList,unicode,{utf32,big})) +
- BrokenSz,
- Chomped = binary:part(PartlyBroken,PBSz - NewSz, NewSz),
- true = (binary:referenced_byte_size(Chomped) =:= PBSz),
- {error,NewList,DeepBrokenPart2} =
- unicode:characters_to_list(Chomped,{utf32,big}),
- BrokenPart = iolist_to_binary(DeepBrokenPart2)
- end || X <- lists:seq(1,OKLen) ]
- end || N <- lists:seq(1,16,3) ],
- ok.
+ ex_binaries_errors_utf32(big).
ex_binaries_errors_utf32_little(Config) when is_list(Config) ->
- BrokenPart = << <<X:32/little>> || X <- lists:seq(16#DC00,16#DFFF) >>,
+ ex_binaries_errors_utf32(little).
+
+ex_binaries_errors_utf32(Endian) ->
+ BrokenSeq = lists:seq(16#DC00, 16#DFFF),
+ BrokenPart = case Endian of
+ little ->
+ << <<X:32/little>> || X <- BrokenSeq >>;
+ big ->
+ << <<X:32/big>> || X <- BrokenSeq >>
+ end,
BrokenSz = byte_size(BrokenPart),
+ Seq255 = lists:seq(1, 255),
[ begin
- OKList = lists:flatten(lists:duplicate(N,lists:seq(1,255))),
- OKBin = unicode:characters_to_binary(OKList,unicode,{utf32,little}),
- OKLen = length(OKList),
- %% Copy to avoid that the binary get's writable
- PartlyBroken = binary:copy(<<OKBin/binary, BrokenPart/binary>>),
+ OKList = lists:append(lists:duplicate(N, Seq255)),
+ OKBin = unicode:characters_to_binary(OKList, unicode, {utf32,Endian}),
+ PartlyBroken = iolist_to_binary([OKBin,BrokenPart]),
PBSz = byte_size(PartlyBroken),
{error,OKList,DeepBrokenPart} =
- unicode:characters_to_list(PartlyBroken,{utf32,little}),
+ unicode:characters_to_list(PartlyBroken, {utf32,Endian}),
BrokenPart = iolist_to_binary(DeepBrokenPart),
- [ begin
- NewList = lists:nthtail(X, OKList),
- NewSz = byte_size(unicode:characters_to_binary(NewList,unicode,{utf32,little})) +
- BrokenSz,
- Chomped = binary:part(PartlyBroken,PBSz - NewSz, NewSz),
- true = (binary:referenced_byte_size(Chomped) =:= PBSz),
- {error,NewList,DeepBrokenPart2} =
- unicode:characters_to_list(Chomped,{utf32,little}),
- BrokenPart = iolist_to_binary(DeepBrokenPart2)
- end || X <- lists:seq(1,OKLen) ]
- end || N <- lists:seq(1,16,3) ],
+ utf32_inner_loop(OKList, BrokenPart, BrokenSz,
+ PartlyBroken, PBSz, Endian)
+ end || N <- lists:seq(1, 16, 3) ],
ok.
-
+utf32_inner_loop([_|List], BrokenPart, BrokenSz, PartlyBroken, PBSz, Endian) ->
+ Sz = length(List)*4 + BrokenSz,
+ Chomped = binary:part(PartlyBroken, PBSz - Sz, Sz),
+ true = binary:referenced_byte_size(Chomped) =:= PBSz,
+ {error,List,DeepBrokenPart} =
+ unicode:characters_to_list(Chomped, {utf32,Endian}),
+ BrokenPart = iolist_to_binary(DeepBrokenPart),
+ utf32_inner_loop(List, BrokenPart, BrokenSz, PartlyBroken, PBSz, Endian);
+utf32_inner_loop([], _, _, _, _, _) ->
+ ok.
exceptions(Config) when is_list(Config) ->
setlimit(10),
diff --git a/lib/stdlib/test/win32reg_SUITE.erl b/lib/stdlib/test/win32reg_SUITE.erl
index d3984ba67c..6d27ac6387 100644
--- a/lib/stdlib/test/win32reg_SUITE.erl
+++ b/lib/stdlib/test/win32reg_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -48,48 +49,53 @@ init_per_suite(Config) when is_list(Config) ->
end_per_suite(Config) when is_list(Config) ->
Config.
+
long(doc) -> "Test long keys and entries (OTP-3446).";
long(Config) when is_list(Config) ->
- ?line Dog = test_server:timetrap(test_server:seconds(10)),
+ Dog = test_server:timetrap(test_server:seconds(10)),
- ?line LongKey = "software\\" ++
+ LongKey = "software\\" ++
lists:flatten(lists:duplicate(10, "..\\software\\")) ++
"Ericsson\\Erlang",
- ?line {ok,Reg} = win32reg:open([read,write]),
- ?line ok = win32reg:change_key(Reg, "\\hklm"),
- ?line ok = win32reg:change_key(Reg, LongKey),
- ?line {ok,ErlangKey} = win32reg:current_key(Reg),
- io:format("Erlang key: ~s", [ErlangKey]),
+ {ok,Read} = win32reg:open([read]),
+ ok = win32reg:change_key(Read, "\\hklm"),
+
+ ok = win32reg:change_key(Read, LongKey),
+ {ok,ErlangKey} = win32reg:current_key(Read),
+ io:format("Erlang key: ~s~n", [ErlangKey]),
+ ok = win32reg:close(Read),
+ {ok,Reg} = win32reg:open([read, write]),
%% Write a long value and read it back.
- ?line TestKey = "test_key",
- ?line LongValue = lists:concat(["This is a long value generated by the test case ",?MODULE,":long/1. "|lists:duplicate(128, "a")]),
- ?line ok = win32reg:set_value(Reg, TestKey, LongValue),
- ?line {ok,LongValue} = win32reg:value(Reg, TestKey),
+ TestKey = "test_key",
+ LongValue = lists:concat(["This is a long value generated by the test case ",?MODULE,":long/1. "|lists:duplicate(128, "a")]),
+ ok = win32reg:set_value(Reg, TestKey, LongValue),
+ {ok,LongValue} = win32reg:value(Reg, TestKey),
+ io:format("Where ~p Key ~s Value ~s ~n", [win32reg:current_key(Reg), TestKey, LongValue]),
%% Done.
- ?line ok = win32reg:close(Reg),
- ?line test_server:timetrap_cancel(Dog),
+ ok = win32reg:close(Reg),
+ test_server:timetrap_cancel(Dog),
ok.
evil_write(Config) when is_list(Config) ->
- ?line Dog = test_server:timetrap(test_server:seconds(10)),
+ Dog = test_server:timetrap(test_server:seconds(10)),
- ?line Key = "Software\\Ericsson\\Erlang",
- ?line {ok,Reg} = win32reg:open([read,write]),
- ?line ok = win32reg:change_key(Reg, "\\hklm"),
- ?line ok = win32reg:change_key(Reg, Key),
- ?line {ok,ErlangKey} = win32reg:current_key(Reg),
+ Key = "Software\\Ericsson\\Erlang",
+ {ok,Reg} = win32reg:open([read,write]),
+ ok = win32reg:change_key(Reg, "\\hkcu"),
+ ok = win32reg:change_key_create(Reg, Key),
+ {ok,ErlangKey} = win32reg:current_key(Reg),
io:format("Erlang key: ~s", [ErlangKey]),
%% Write keys with different length and read it back.
- ?line TestKey = "test_key " ++ lists:duplicate(128, $a),
+ TestKey = "test_key " ++ lists:duplicate(128, $a),
evil_write_1(Reg, TestKey),
%% Done.
- ?line ok = win32reg:close(Reg),
- ?line test_server:timetrap_cancel(Dog),
+ ok = win32reg:close(Reg),
+ test_server:timetrap_cancel(Dog),
ok.
evil_write_1(Reg, [_|[_|_]=Key]=Key0) ->
diff --git a/lib/stdlib/test/y2k_SUITE.erl b/lib/stdlib/test/y2k_SUITE.erl
index d4d0721abf..9e766e80ab 100644
--- a/lib/stdlib/test/y2k_SUITE.erl
+++ b/lib/stdlib/test/y2k_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index a57641ef62..c275053691 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -23,7 +24,7 @@
bad_zip/1, unzip_from_binary/1, unzip_to_binary/1,
zip_to_binary/1,
unzip_options/1, zip_options/1, list_dir_options/1, aliases/1,
- openzip_api/1, zip_api/1, unzip_jar/1,
+ openzip_api/1, zip_api/1, open_leak/1, unzip_jar/1,
compress_control/1,
foldl/1]).
@@ -38,7 +39,7 @@ all() ->
[borderline, atomic, bad_zip, unzip_from_binary,
unzip_to_binary, zip_to_binary, unzip_options,
zip_options, list_dir_options, aliases, openzip_api,
- zip_api, unzip_jar, compress_control, foldl].
+ zip_api, open_leak, unzip_jar, compress_control, foldl].
groups() ->
[].
@@ -84,7 +85,7 @@ borderline_test(Size, TempDir) ->
io:format("Testing size ~p", [Size]),
%% Create a file and archive it.
- {_, _, X0} = erlang:now(),
+ {_, _, X0} = erlang:timestamp(),
file:write_file(Name, random_byte_list(X0, Size)),
{ok, Archive} = zip:zip(Archive, [Name]),
ok = file:delete(Name),
@@ -318,8 +319,46 @@ zip_api(Config) when is_list(Config) ->
%% Clean up.
delete_files([Names]),
+ ok.
+
+open_leak(doc) ->
+ ["Test that zip doesn't leak processes and ports where the "
+ "controlling process dies without closing an zip opened with "
+ "zip:zip_open/1."];
+open_leak(suite) -> [];
+open_leak(Config) when is_list(Config) ->
+ %% Create a zip archive
+ Zip = "zip.zip",
+ {ok, Zip} = zip:zip(Zip, [], []),
+
+ %% Open archive in a another process that dies immediately.
+ ZipSrv = spawn_zip(Zip, [memory]),
+
+ %% Expect the ZipSrv process to die soon after.
+ true = spawned_zip_dead(ZipSrv),
+
+ %% Clean up.
+ delete_files([Zip]),
+
ok.
+spawn_zip(Zip, Options) ->
+ Self = self(),
+ spawn(fun() -> Self ! zip:zip_open(Zip, Options) end),
+ receive
+ {ok, ZipSrv} ->
+ ZipSrv
+ end.
+
+spawned_zip_dead(ZipSrv) ->
+ Ref = monitor(process, ZipSrv),
+ receive
+ {'DOWN', Ref, _, ZipSrv, _} ->
+ true
+ after 1000 ->
+ false
+ end.
+
unzip_options(doc) ->
["Test options for unzip, only cwd and file_list currently"];
unzip_options(suite) ->
@@ -517,9 +556,10 @@ unzip_to_binary(doc) ->
unzip_to_binary(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
+ WorkDir = filename:join(PrivDir, "unzip_to_binary"),
+ _ = file:make_dir(WorkDir),
- delete_all_in(PrivDir),
- file:set_cwd(PrivDir),
+ ok = file:set_cwd(WorkDir),
Long = filename:join(DataDir, "abc.zip"),
%% Unzip a zip file into a binary
@@ -530,7 +570,7 @@ unzip_to_binary(Config) when is_list(Config) ->
end, FBList),
%% Make sure no files created in cwd
- {ok,[]} = file:list_dir(PrivDir),
+ {ok,[]} = file:list_dir(WorkDir),
ok.
@@ -539,8 +579,10 @@ zip_to_binary(doc) ->
zip_to_binary(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
- delete_all_in(PrivDir),
- file:set_cwd(PrivDir),
+ WorkDir = filename:join(PrivDir, "zip_to_binary"),
+ _ = file:make_dir(WorkDir),
+
+ file:set_cwd(WorkDir),
FileName = "abc.txt",
ZipName = "t.zip",
FilePath = filename:join(DataDir, FileName),
@@ -550,7 +592,7 @@ zip_to_binary(Config) when is_list(Config) ->
{ok, {ZipName, ZipB}} = zip:zip(ZipName, [FileName], [memory]),
%% Make sure no files created in cwd
- {ok,[FileName]} = file:list_dir(PrivDir),
+ {ok,[FileName]} = file:list_dir(WorkDir),
%% Zip to a file
{ok, ZipName} = zip:zip(ZipName, [FileName]),
@@ -568,7 +610,7 @@ zip_to_binary(Config) when is_list(Config) ->
aliases(doc) ->
["Test using the aliases, extract/2, table/2 and create/3"];
aliases(Config) when is_list(Config) ->
- {_, _, X0} = erlang:now(),
+ {_, _, X0} = erlang:timestamp(),
Size = 100,
B = list_to_binary(random_byte_list(X0, Size)),
%% create
@@ -657,11 +699,6 @@ do_delete_files([Item|Rest], Cnt) ->
end,
do_delete_files(Rest, Cnt + DelCnt).
-delete_all_in(Dir) ->
- {ok, Files} = file:list_dir(Dir),
- delete_files(lists:map(fun(F) -> filename:join(Dir,F) end,
- Files)).
-
compress_control(doc) ->
["Test control of which files that should be compressed"];
compress_control(suite) -> [];
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index f57f31c8de..5bac4be9d7 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 2.4
+STDLIB_VSN = 2.8
diff --git a/lib/syntax_tools/Makefile b/lib/syntax_tools/Makefile
index 37e84a80a5..14ae6d4f97 100644
--- a/lib/syntax_tools/Makefile
+++ b/lib/syntax_tools/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/syntax_tools/doc/Makefile b/lib/syntax_tools/doc/Makefile
index d9981de880..87604c4e7f 100644
--- a/lib/syntax_tools/doc/Makefile
+++ b/lib/syntax_tools/doc/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/syntax_tools/doc/overview.edoc b/lib/syntax_tools/doc/overview.edoc
index df02ad0b3a..3111633a99 100644
--- a/lib/syntax_tools/doc/overview.edoc
+++ b/lib/syntax_tools/doc/overview.edoc
@@ -2,79 +2,34 @@
Syntax Tools overview page
-
@author Richard Carlsson <[email protected]>
-@copyright 1997-2004 Richard Carlsson
+@copyright 1997-2014 Richard Carlsson
@version {@version}
-@title Erlang Syntax Tools
+@title Erlang Syntax and Metaprogramming tools
-@doc This package contains modules for handling abstract Erlang syntax
-trees, in a way that is compatible with the "parse trees" of the
-standard library module `erl_parse', together with utilities for reading
-source files in unusual ways and pretty-printing syntax trees. Also
-included is an amazing module merger and renamer called Igor, as well as
-an automatic code-cleaner.
+@doc This package contains modules for handling abstract syntax trees (ASTs)
+in Erlang, in a way that is compatible with the "abstract format" parse
+trees of the stdlib module `erl_parse', together with utilities for reading
+source files, {@link erl_prettypr. pretty-printing syntax trees}, {@link
+igor. merging and renaming modules}, {@link erl_tidy. cleaning up obsolete
+constructs}, and doing {@link merl. metaprogramming} in Erlang.
-<p>The abstract layer (defined in {@link erl_syntax}) is nicely
+The abstract layer (defined in {@link erl_syntax}) is nicely
structured and the node types are context-independent. The layer makes
it possible to transparently attach source-code comments and user
annotations to nodes of the tree. Using the abstract layer makes
applications less sensitive to changes in the {@link //stdlib/erl_parse}
-data structures, only requiring the {@link erl_syntax} module to be
-up-to-date.</p>
+data structures, only requiring the `erl_syntax' module to be up-to-date.
-<p>The pretty printer {@link erl_prettypr} is implemented on top of the
+The pretty printer {@link erl_prettypr} is implemented on top of the
library module {@link prettypr}: this is a powerful and flexible generic
-pretty printing library, which is also distributed separately.</p>
-
-<p>For a short demonstration of parsing and pretty-printing, simply
-compile the included module <a
-href="../examples/demo.erl"><code>demo.erl</code></a>, and execute
-<code>demo:run()</code> from the Erlang shell. It will compile the
-remaining modules and give you further instructions.</p>
-
-<p>Also try the {@link erl_tidy} module, as follows:
-<pre>
- erl_tidy:dir("any-erlang-source-dir", [test, old_guard_tests]).</pre>
-("<code>test</code>" assures that no files are modified).</p>
-
-<p>News in 1.4:
-<ul>
- <li>Added support for {@link erl_syntax:cond_expr/1. cond-expressions},
- {@link erl_syntax:try_expr/4. try-expressions} and
- {@link erl_syntax:class_qualifier/2. class-qualifier patterns}.</li>
- <li>Added support for parameterized modules.</li>
- <li>{@link igor. Igor} is officially included.</li>
- <li>Quick-parse functionality added to {@link epp_dodger}.</li>
-</ul>
-</p>
-
-<p>News in 1.3:
-<ul>
- <li>Added support for qualified names (as used by "packages").</li>
- <li>Various internal changes.</li>
-</ul>
-</p>
+pretty printing library, which is also distributed separately.
-<p>News in 1.2:
-<ul>
- <li>HTML Documentation (generated with EDoc).</li>
- <li>A few bug fixes and some minor interface changes (sorry for any
- inconvenience).</li>
-</ul>
-</p>
+For a short demonstration of parsing and pretty-printing, simply
+compile the included module <a href="../examples/demo.erl">`demo.erl'</a>,
+and execute `demo:run()' from the Erlang shell. It will compile the
+remaining modules and give you further instructions.
-<p>News in 1.1:
-<ul>
- <li>Module {@link erl_tidy}: check or tidy either a single module, or a
- whole directory tree recursively. Rewrites and reformats the code
- without losing comments or expanding macros. Safe mode allows
- generating reports without modifying files.</li>
- <li>Module {@link erl_syntax_lib}: contains support functions for easier
- analysis of the source code structure.</li>
- <li>Module {@link epp_dodger}: Bypasses the Erlang preprocessor - avoids
- macro expansion, file inclusion, conditional compilation, etc.
- Allows you to find/modify particular definitions/applications of
- macros, and other things previously not possible.</li>
-</ul>
-</p>
+Also try the {@link erl_tidy} module, as follows:
+```erl_tidy:dir("any-erlang-source-dir", [test, old_guard_tests]).'''
+(the `test' option assures that no files are modified).
diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile
index 2502bf877a..6aca06424d 100644
--- a/lib/syntax_tools/doc/src/Makefile
+++ b/lib/syntax_tools/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -50,6 +51,8 @@ XML_REF3_FILES = \
erl_syntax_lib.xml \
erl_tidy.xml \
igor.xml \
+ merl.xml \
+ merl_transform.xml \
prettypr.xml
XML_PART_FILES = part.xml part_notes.xml
diff --git a/lib/syntax_tools/doc/src/book.xml b/lib/syntax_tools/doc/src/book.xml
index 6a8a3a3ca6..fb64a7dd21 100644
--- a/lib/syntax_tools/doc/src/book.xml
+++ b/lib/syntax_tools/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 408f6d5bac..9f803264a2 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,27 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 1.7</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Use the new <c>erl_anno</c> module.</p>
+ <p>
+ Own Id: OTP-12732</p>
+ </item>
+ <item>
+ <p>The <c>merl</c> module has been added to the
+ <c>syntax_tools</c> application. The Merl library is a
+ simpler way to work with erl_syntax parse trees.</p>
+ <p>
+ Own Id: OTP-12769</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Syntax_Tools 1.6.18</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/syntax_tools/doc/src/part.xml b/lib/syntax_tools/doc/src/part.xml
index ee8e796561..c111b045da 100644
--- a/lib/syntax_tools/doc/src/part.xml
+++ b/lib/syntax_tools/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/syntax_tools/doc/src/part_notes.xml b/lib/syntax_tools/doc/src/part_notes.xml
index 6962145618..308cf62915 100644
--- a/lib/syntax_tools/doc/src/part_notes.xml
+++ b/lib/syntax_tools/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/syntax_tools/doc/src/ref_man.xml b/lib/syntax_tools/doc/src/ref_man.xml
index 598f656011..65b1725163 100644
--- a/lib/syntax_tools/doc/src/ref_man.xml
+++ b/lib/syntax_tools/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,12 +30,11 @@
</header>
<description>
<p><em>Syntax_Tools</em> contains modules for handling abstract
- Erlang syntax trees, in a way that is compatible with the "parse
- trees" of the STDLIB module <c>erl_parse</c>, together with
- utilities for reading source files in unusual ways and
- pretty-printing syntax trees. Also included is an amazing module
- merger and renamer called Igor, as well as an automatic
- code-cleaner.</p>
+ Erlang syntax trees, in a way that is compatible with the "external
+ format" parse trees of the STDLIB module <c>erl_parse</c>, together
+ with utilities for reading source files, pretty-printing syntax trees,
+ merging and renaming modules, cleaning up obsolete constructs, and
+ doing metaprogramming in Erlang.</p>
</description>
<xi:include href="epp_dodger.xml"/>
<xi:include href="erl_comment_scan.xml"/>
@@ -44,6 +44,8 @@
<xi:include href="erl_syntax_lib.xml"/>
<xi:include href="erl_tidy.xml"/>
<xi:include href="igor.xml"/>
+ <xi:include href="merl.xml"/>
+ <xi:include href="merl_transform.xml"/>
<xi:include href="prettypr.xml"/>
</application>
diff --git a/lib/syntax_tools/examples/Makefile b/lib/syntax_tools/examples/Makefile
index 2724b0899b..f5e96a8285 100644
--- a/lib/syntax_tools/examples/Makefile
+++ b/lib/syntax_tools/examples/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/syntax_tools/examples/merl/Makefile b/lib/syntax_tools/examples/merl/Makefile
new file mode 100644
index 0000000000..13a9703733
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/Makefile
@@ -0,0 +1,22 @@
+EBIN=../../ebin
+INCLUDES=../../include
+SOURCES=merl_build.erl lisp.erl lispc.erl basic.erl basicc.erl
+HEADERS=$(INCLUDES)/merl.hrl
+OBJECTS=$(SOURCES:%.erl=%.beam)
+ERLC_FLAGS=+debug_info -I$(INCLUDES) -pa $(EBIN)
+
+all: $(OBJECTS) test
+
+%.beam: %.erl $(HEADERS) Makefile
+ erlc $(ERLC_FLAGS) -o ./ $<
+
+# additional dependencies due to the parse transform
+lispc.beam basicc.beam: $(EBIN)/merl_transform.beam $(EBIN)/merl.beam
+
+clean:
+ -rm -f $(OBJECTS)
+
+test:
+ erl -noshell -pa $(EBIN) \
+ -eval 'eunit:test([lisp, lispc, basic, basicc],[])' \
+ -s init stop
diff --git a/lib/syntax_tools/examples/merl/basic.erl b/lib/syntax_tools/examples/merl/basic.erl
new file mode 100644
index 0000000000..9030059d11
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/basic.erl
@@ -0,0 +1,77 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Trivial Basic interpreter in Erlang
+
+-module(basic).
+
+-export([run/2]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+-define(INTERPRETED, true).
+-include("basic_test.erl").
+
+run(N, Prog) ->
+ ets:new(var, [private, named_table]),
+ ets:new(line, [private, named_table, ordered_set]),
+ lists:foreach(fun (T) -> ets:insert(line, T) end, Prog),
+ goto(N).
+
+stop(N) ->
+ ets:delete(var),
+ ets:delete(line),
+ N.
+
+goto('$end_of_table') -> stop(0);
+goto(L) ->
+ L1 = ets:next(line, L),
+ %% user-supplied line numbers might not exist
+ case ets:lookup(line, L) of
+ [{_, X}] ->
+ stmt(X, L1);
+ _ ->
+ goto(L1)
+ end.
+
+stmt({print, S, As}, L) -> io:format(S, [expr(A) || A <- As]), goto(L);
+stmt({set, V, X}, L) -> ets:insert(var, {V, expr(X)}), goto(L);
+stmt({goto, X}, _L) -> goto(expr(X));
+stmt({stop, X}, _L) -> stop(expr(X));
+stmt({iff, X, A, B}, _L) ->
+ case expr(X) of
+ 0 -> goto(B);
+ _ -> goto(A)
+ end.
+
+expr(X) when is_number(X) ; is_list(X) ->
+ X;
+expr(X) when is_atom(X) ->
+ case ets:lookup(var, X) of
+ [] -> 0;
+ [{_,V}] -> V
+ end;
+expr({plus, X, Y}) ->
+ expr(X) + expr(Y);
+expr({equal, X, Y}) ->
+ bool(expr(X) == expr(Y));
+expr({gt, X, Y}) ->
+ bool(expr(X) > expr(Y));
+expr({knot, X}) ->
+ case expr(X) of
+ 0 -> 1;
+ _ -> 0
+ end.
+
+bool(true) -> 1;
+bool(false) -> 0.
diff --git a/lib/syntax_tools/examples/merl/basic_test.erl b/lib/syntax_tools/examples/merl/basic_test.erl
new file mode 100644
index 0000000000..ff35de6325
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/basic_test.erl
@@ -0,0 +1,77 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Tests. For including in another module.
+
+%-module(basic_test).
+%-import(basic, run/1)
+
+-export([basic_fib/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+basics_test_() ->
+ [?_assertEqual(42, run(1,[{1,{stop, 42}}])),
+ ?_assertEqual("hello", run(1,[{1,{stop,"hello"}}])),
+ ?_assertEqual(0, run(1,[{1,{print, "hello ~w", [42]}}])),
+ ?_assertEqual(5, run(1,[{1,{stop, {plus, 2, 3}}}])),
+ ?_assertEqual(5, run(1,[{1,{stop,{plus, 8, -3}}}])),
+ ?_assertEqual(0, run(1,[{1,{stop,{equal, 0, 1}}}])),
+ ?_assertEqual(1, run(1,[{1,{stop,{equal, 1, 1}}}])),
+ ?_assertEqual(0, run(1,[{1,{stop,{gt, 0, 1}}}])),
+ ?_assertEqual(0, run(1,[{1,{stop,{gt, 1, 1}}}])),
+ ?_assertEqual(1, run(1,[{1,{stop,{gt, 2, 1}}}])),
+ ?_assertEqual(0, run(1,[{1,{stop,{knot, 42}}}])),
+ ?_assertEqual(1, run(1,[{1,{stop,{knot, 0}}}])),
+ ?_assertEqual(42, run(1,[{1,{set, x, 42}}, {2,{stop,x}}])),
+ ?_assertEqual(17, run(1,[{1,{iff, 1, 2, 3}},
+ {2,{stop, 17}},
+ {3,{stop, 42}}])),
+ ?_assertEqual(42, run(1,[{1,{iff, 0, 2, 3}},
+ {2,{stop, 17}},
+ {3,{stop, 42}}])),
+ ?_assertEqual(17, run(1,[{1,{iff, 1, 2, 3}},
+ {2,{stop, 17}},
+ {3,{stop, -1}}])),
+ ?_assertEqual(42, run(1,[{1,{iff, 0, 2, 3}},
+ {2,{stop, -1}},
+ {3,{stop, 42}}]))
+
+
+ ].
+
+
+fib_test_() ->
+ [?_assertEqual(fib(N), basic_fib(N)) || N <- lists:seq(1,15)
+ ].
+
+
+fib(N) when N > 1 ->
+ fib(N-1) + fib(N-2);
+fib(_) ->
+ 1.
+
+basic_fib(N) ->
+ run(1,
+ [{1,{set,x,0}},
+ {2,{set,a,1}},
+ {3,{set,b,0}},
+ {10,{iff, {equal, x, N}, 20, 30}},
+ {20,{stop,a}},
+ {30,{print,"~w, ~w, ~w\n",[x,a,b]}},
+ {31,{set,t,a}},
+ {32,{set,a,{plus,a,b}}},
+ {33,{set,b,t}},
+ {34,{set,x,{plus,x,1}}},
+ {40,{goto,10}}
+ ]).
diff --git a/lib/syntax_tools/examples/merl/basicc.erl b/lib/syntax_tools/examples/merl/basicc.erl
new file mode 100644
index 0000000000..531ac51538
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/basicc.erl
@@ -0,0 +1,149 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Basic compiler in Erlang.
+
+-module(basicc).
+
+-export([run/2, make_lines/1, bool/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+-define(INTERPRETED, true).
+-include("basic_test.erl").
+
+-include("merl.hrl").
+
+run(N, Prog) ->
+ compile(Prog, tmp),
+ tmp:run(N, Prog).
+
+make_lines(Prog) ->
+ ets:new(line, [private, named_table, ordered_set]),
+ lists:foreach(fun ({L,_}) -> ets:insert(line, {L,label(L)}) end, Prog).
+
+compile(Prog, ModName) ->
+ make_lines(Prog),
+ Fs0 = lists:map(fun ({L, X}) ->
+ {true, label(L),
+ case stmt(X) of
+ {Stmt, false} ->
+ [?Q("() -> _@Stmt")];
+ {Stmt, true} ->
+ Next = case ets:next(line, L) of
+ '$end_of_table' ->
+ ?Q("stop(0)");
+ L1 ->
+ Label = label(L1),
+ ?Q("_@Label@()")
+ end,
+ [?Q("() -> _@Stmt, _@Next")]
+ end}
+ end, Prog),
+ ets:delete(line),
+ Run = ?Q(["(N, Prog) ->",
+ " ets:new(var, [private, named_table]),",
+ " basicc:make_lines(Prog),",
+ " goto(N)"
+ ]),
+ Stop = ?Q(["(R) ->",
+ " ets:delete(var),",
+ " ets:delete(line),",
+ " R"
+ ]),
+ Goto = ?Q(["(L) ->",
+ " case ets:lookup(line, L) of",
+ " [{_, X}] -> apply(tmp, X, []);",
+ " _ ->",
+ " case ets:next(line, L) of",
+ " '$end_of_table' -> stop(0);",
+ " L1 -> goto(L1)",
+ " end",
+ " end"]),
+ Fs = [{true, run, [Run]},
+ {false, stop, [Stop]},
+ {true, goto, [Goto]}
+ | Fs0],
+ Forms = merl_build:module_forms(
+ lists:foldl(fun ({X, Name, Cs}, S) ->
+ merl_build:add_function(X, Name, Cs, S)
+ end,
+ merl_build:init_module(ModName),
+ Fs)),
+ %% %% Write source to file for debugging
+ %% file:write_file(lists:concat([ModName, "_gen.erl"]),
+ %% erl_prettypr:format(erl_syntax:form_list(Forms),
+ %% [{paper,160},{ribbon,80}])),
+ merl:compile_and_load(Forms, [verbose]).
+
+label(L) ->
+ list_to_atom("label_" ++ integer_to_list(L)).
+
+stmt({print, S, As}) ->
+ Exprs = [expr(A) || A <- As],
+ {[?Q(["io:format(_@S@, [_@Exprs])"])], true};
+stmt({set, V, X}) ->
+ Expr = expr(X),
+ {[?Q(["ets:insert(var, {_@V@, _@Expr})"])], true};
+stmt({goto, X}) ->
+ {[jump(X)], false};
+stmt({stop, X}) ->
+ Expr = expr(X),
+ {[?Q(["stop(_@Expr)"])], false};
+stmt({iff, X, A, B}) ->
+ Cond = expr(X),
+ True = jump(A),
+ False = jump(B),
+ {?Q(["case _@Cond of",
+ " 0 -> _@False;",
+ " _ -> _@True",
+ "end"]),
+ false}.
+
+jump(X) ->
+ case ets:lookup(line, X) of
+ [{_, F}] ->
+ ?Q(["_@F@()"]);
+ true ->
+ Expr = expr(X),
+ [?Q(["goto(_@Expr)"])]
+ end.
+
+expr(X) when is_number(X) ; is_list(X) ->
+ ?Q("_@X@");
+expr(X) when is_atom(X) ->
+ ?Q(["case ets:lookup(var, _@X@) of",
+ " [] -> 0;",
+ " [{_,V}] -> V",
+ "end"]);
+expr({plus, X, Y}) ->
+ ExprX = expr(X),
+ ExprY = expr(Y),
+ ?Q("_@ExprX + _@ExprY");
+expr({equal, X, Y}) ->
+ ExprX = expr(X),
+ ExprY = expr(Y),
+ ?Q("basicc:bool(_@ExprX == _@ExprY)");
+expr({gt, X, Y}) ->
+ ExprX = expr(X),
+ ExprY = expr(Y),
+ ?Q("basicc:bool(_@ExprX > _@ExprY)");
+expr({knot, X}) ->
+ Expr = expr(X),
+ ?Q(["case _@Expr of",
+ " 0 -> 1;",
+ " _ -> 0",
+ "end"]).
+
+bool(true) -> 1;
+bool(false) -> 0.
diff --git a/lib/syntax_tools/examples/merl/lisp.erl b/lib/syntax_tools/examples/merl/lisp.erl
new file mode 100644
index 0000000000..371dc6b261
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/lisp.erl
@@ -0,0 +1,160 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Trivial Lisp interpreter in Erlang.
+
+-module(lisp).
+
+-export([eval/1]).
+
+-export([init/0, equal/2, gt/2, knot/1]).
+
+-record(st, {env}).
+
+-define(INTERPRETED, true).
+-include("lisp_test.erl").
+
+eval(P) ->
+ {X, _} = eval(P, init()),
+ X.
+
+init() ->
+ Env = [{print, {builtin, fun do_print/2}}
+ ,{list, {builtin, fun do_list/2}}
+ ,{apply, {builtin, fun do_apply/2}}
+ ,{plus, {builtin, fun do_plus/2}}
+ ,{equal, {builtin, fun do_equal/2}}
+ ,{gt, {builtin, fun do_gt/2}}
+ ,{knot, {builtin, fun do_knot/2}}
+ ,{y, y()}
+ ],
+ #st{env=dict:from_list(Env)}.
+
+eval([lambda, Ps, B], #st{env=E}=St) when is_list(Ps) ->
+ case lists:all(fun is_atom/1, Ps) andalso
+ (length(Ps) =:= length(lists:usort(Ps))) of
+ true -> {{lambda, Ps, B, E}, St};
+ false -> throw(bad_lambda)
+ end;
+eval([lambda | _], _) ->
+ throw(bad_lambda);
+eval([def, A, V, B], #st{env=E0}=St) when is_atom(A) ->
+ {V1, St1} = eval(V, St),
+ E1 = bind(A, V1, E0),
+ {X, St2} = eval(B, St1#st{env=E1}),
+ {X, St2#st{env=E0}};
+eval([def | _], _) ->
+ throw(bad_def);
+eval([quote, A], St) ->
+ {A, St};
+eval([quote | _], _) ->
+ throw(bad_quote);
+eval([iff, X, A, B], St) ->
+ case eval(X, St) of
+ {[], St1} -> eval(B, St1);
+ {_, St1} -> eval(A, St1)
+ end;
+eval([do], _St0) ->
+ throw(bad_do);
+eval([do | As], St0) ->
+ lists:foldl(fun (X, {_,St}) -> eval(X, St) end, {[],St0}, As);
+eval([_|_]=L, St) ->
+ {[F | As], St1} = lists:mapfoldl(fun eval/2, St, L),
+ call(F, As, St1);
+eval(A, St) when is_atom(A) ->
+ {deref(A, St), St};
+eval(C, St) ->
+ {C, St}.
+
+%% UTILITY FUNCTIONS
+
+deref(A, #st{env=E}) ->
+ case dict:find(A, E) of
+ {ok, V} -> V;
+ error -> throw({undefined, A})
+ end.
+
+bind(A, V, E) ->
+ dict:store(A, V, E).
+
+bind_args([P | Ps], [A | As], E) ->
+ bind_args(Ps, As, dict:store(P, A, E));
+bind_args([], [], E) ->
+ E;
+bind_args(_, _, _) ->
+ throw(bad_arity).
+
+call({lambda, Ps, B, E}, As, #st{env=E0}=St) ->
+ {X, St1} = eval(B, St#st{env=bind_args(Ps, As, E)}),
+ {X, St1#st{env=E0}};
+call({builtin, F}, As, St) ->
+ F(As, St);
+call(X, _, _) ->
+ throw({bad_fun, X}).
+
+bool(true) -> 1;
+bool(false) -> [].
+
+%% BUILTINS
+
+y() ->
+ {Y, _} = eval([lambda, [f],
+ [[lambda, [x], [f, [lambda, [y], [[x, x], y]]]],
+ [lambda, [x], [f, [lambda, [y], [[x, x], y]]]]]],
+ #st{env=dict:new()}),
+ Y.
+
+do_print([S | Xs], St) ->
+ io:format(S, Xs),
+ {[], St};
+do_print(_, _) ->
+ throw(bad_print).
+
+do_list(As, St) ->
+ {As, St}.
+
+do_apply([F, As], St) ->
+ call(F, As, St);
+do_apply(_, _) ->
+ throw(bad_apply).
+
+do_plus([X, Y], St) when is_number(X), is_number(Y) ->
+ {X + Y, St};
+do_plus(As, _) ->
+ throw({bad_plus, As}).
+
+do_equal([X, Y], St) ->
+ {equal(X, Y), St};
+do_equal(As, _) ->
+ throw({bad_equal, As}).
+
+equal(X, Y) ->
+ bool(X =:= Y).
+
+do_gt([X, Y], St) ->
+ {gt(X, Y), St};
+do_gt(As, _) ->
+ throw({bad_gt, As}).
+
+gt(X, Y) ->
+ bool(X > Y).
+
+do_knot([X], St) ->
+ {knot(X), St};
+do_knot(As, _) ->
+ throw({bad_gt, As}).
+
+knot([]) ->
+ 1;
+knot(_) ->
+ [].
diff --git a/lib/syntax_tools/examples/merl/lisp_test.erl b/lib/syntax_tools/examples/merl/lisp_test.erl
new file mode 100644
index 0000000000..cab8134b8f
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/lisp_test.erl
@@ -0,0 +1,98 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Tests. For including in another module.
+
+%-module(lisp_test).
+%-import(lisp, eval/1)
+
+-export([fib/1, lisp_fib/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+basics_test_() ->
+ [?_assertEqual(42, eval(42)),
+ ?_assertEqual("hello", eval([quote, "hello"])),
+ ?_assertEqual(print, eval([quote, print])),
+ ?_assertMatch([17,[1,2],42], eval([list,17,[list,1,2],42])),
+ ?_assertEqual([], eval([print, [quote, "hello ~w"], [list, 42]])),
+ ?_assertEqual(5, eval([plus, 2, 3])),
+ ?_assertEqual(5, eval([plus, 8, -3])),
+ ?_assertEqual([], eval([equal, 0, 1])),
+ ?_assertEqual(1, eval([equal, 1, 1])),
+ ?_assertEqual([], eval([gt, 0, 1])),
+ ?_assertEqual([], eval([gt, 1, 1])),
+ ?_assertEqual(1, eval([gt, 2, 1])),
+ ?_assertEqual([], eval([knot, 42])),
+ ?_assertEqual(1, eval([knot, []])),
+ ?_assertEqual(42, eval([do, 17, 42])),
+ ?_assertEqual([], eval([apply, print, [quote, ["~p", [42]]]])),
+ ?_assertEqual(42, eval([iff, [], 17, 42])),
+ ?_assertEqual(17, eval([iff, 1, 17, 42])),
+ ?_assertEqual(42, eval([iff, [], [apply], 42])),
+ ?_assertEqual(17, eval([iff, 1, 17, [apply]])),
+ ?_assertEqual(17, eval([def, foo, 17, foo])),
+ ?_assertEqual(17, eval([def, bar, 42, [def, foo, 17, foo]])),
+ ?_assertEqual(42, eval([def, bar, 42, [def, foo, 17, bar]])),
+ ?_assertEqual(17, eval([def, foo, 42, [def, foo, 17, foo]]))
+ ].
+
+-ifdef(INTERPRETED).
+interpreter_basics_test_() ->
+ [?_assertThrow({undefined, foo}, eval(foo)),
+ ?_assertMatch({builtin,_}, eval(print)),
+ ?_assertThrow(bad_do, eval([do])),
+ ?_assertThrow(bad_apply, eval([apply])),
+ ?_assertThrow({undefined, foo}, eval([def, bar, 17, foo]))
+ ].
+
+interpreter_lambda_test_() ->
+ [?_assertMatch({lambda,_,_,_}, eval([lambda, [], 42])),
+ ?_assertMatch({lambda,_,_,_}, eval([lambda, [x], x])),
+ ?_assertMatch({lambda,_,_,_}, eval([lambda, [x,y], 42]))
+ ].
+-endif.
+
+lambda_test_() ->
+ [?_assertThrow(bad_lambda, eval([lambda])),
+ ?_assertThrow(bad_lambda, eval([lambda, []])),
+ ?_assertThrow(bad_lambda, eval([lambda, [], 17, 42])),
+ ?_assertThrow(bad_lambda, eval([lambda, 17, 42])),
+ ?_assertThrow(bad_lambda, eval([lambda, [17], 42])),
+ ?_assertThrow(bad_lambda, eval([lambda, [foo, foo], 42])),
+ ?_assertEqual(42, eval([[lambda, [x], x], 42])),
+ ?_assertEqual([42, 17], eval([[lambda, [x], [list, x, 17]], 42])),
+ ?_assertEqual([42, 17], eval([def, f, [def, y, 42,
+ [lambda, [x], [list, y, x]]],
+ [f, 17]]))
+ ].
+
+fib_test_() ->
+ [?_assertEqual(fib(N), lisp_fib(N)) || N <- lists:seq(1,15)
+ ].
+
+
+fib(N) when N > 1 ->
+ fib(N-1) + fib(N-2);
+fib(_) ->
+ 1.
+
+lisp_fib(N) ->
+ eval([def, fib,
+ [y, [lambda, [f], [lambda, [x],
+ [iff, [gt, x, 1],
+ [plus, [f, [plus,x,-1]], [f, [plus,x,-2]]],
+ 1]
+ ]]],
+ [fib, N]
+ ]).
diff --git a/lib/syntax_tools/examples/merl/lispc.erl b/lib/syntax_tools/examples/merl/lispc.erl
new file mode 100644
index 0000000000..97072cdab7
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/lispc.erl
@@ -0,0 +1,102 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Lisp compiler in Erlang.
+
+-module(lispc).
+
+-export([eval/1]).
+
+-record(st, {}).
+
+-include("lisp_test.erl").
+
+-include("merl.hrl").
+
+eval(Lisp) ->
+ compile(Lisp, tmp),
+ tmp:eval().
+
+compile(Lisp, ModName) ->
+ {Code, _} = gen(Lisp, #st{}),
+ Main = ?Q(["() ->",
+ " __print = fun (S, Xs) -> io:format(S,Xs), [] end,",
+ " __apply = fun erlang:apply/2,",
+ " __plus = fun erlang:'+'/2,",
+ " __equal = fun lisp:equal/2,",
+ " __gt = fun lisp:gt/2,",
+ " __knot = fun lisp:knot/1,",
+ " __y = fun (F) ->",
+ " (fun (X) -> F(fun (Y) -> (X(X))(Y) end) end)",
+ " (fun (X) -> F(fun (Y) -> (X(X))(Y) end) end)",
+ " end,",
+ " _@Code"]),
+ Forms = merl_build:module_forms(
+ merl_build:add_function(true, eval, [Main],
+ merl_build:init_module(ModName))),
+ %% %% Write source to file for debugging
+ %% file:write_file(lists:concat([ModName, "_gen.erl"]),
+ %% erl_prettypr:format(erl_syntax:form_list(Forms),
+ %% [{paper,160},{ribbon,80}])),
+ merl:compile_and_load(Forms, [verbose]).
+
+var(Atom) ->
+ merl:var(list_to_atom("__" ++ atom_to_list(Atom))).
+
+gen([lambda, Ps, B], St) when is_list(Ps) ->
+ case lists:all(fun is_atom/1, Ps) andalso
+ (length(Ps) =:= length(lists:usort(Ps))) of
+ true ->
+ Vars = [var(P) || P <- Ps],
+ {Body, St1} = gen(B, St),
+ {?Q("fun (_@Vars) -> _@Body end"), St1};
+ false ->
+ throw(bad_lambda)
+ end;
+gen([lambda | _], _) ->
+ throw(bad_lambda);
+gen([def, A, V, B], St) when is_atom(A) ->
+ Var = var(A),
+ {Val, St1} = gen(V, St),
+ {Body, St2} = gen(B, St1),
+ {?Q("(fun (_@Var) -> _@Body end)(_@Val)"), St2};
+gen([def | _], _) ->
+ throw(bad_def);
+gen([quote, A], St) ->
+ {merl:term(A), St};
+gen([quote | _], _) ->
+ throw(bad_quote);
+gen([iff, X, A, B], St) ->
+ {Cond, St1} = gen(X, St),
+ {True, St2} = gen(A, St1),
+ {False, St3} = gen(B, St2),
+ {?Q(["case _@Cond of",
+ " [] -> _@False;",
+ " _ -> _@True",
+ "end"]),
+ St3};
+gen([do], _) ->
+ throw(bad_do);
+gen([do | As], St0) ->
+ {Body, St1} = lists:mapfoldl(fun gen/2, St0, As),
+ {?Q("begin _@Body end"), St1};
+gen([list | As], St0) ->
+ {Elem, St1} = lists:mapfoldl(fun gen/2, St0, As),
+ {?Q("[ _@Elem ]"), St1};
+gen([_|_]=L, St) ->
+ {[F | As], St1} = lists:mapfoldl(fun gen/2, St, L),
+ {?Q("((_@F)(_@As))"), St1};
+gen(A, St) when is_atom(A) ->
+ {var(A), St};
+gen(C, St) ->
+ {merl:term(C), St}.
diff --git a/lib/syntax_tools/examples/merl/merl_build.erl b/lib/syntax_tools/examples/merl/merl_build.erl
new file mode 100644
index 0000000000..c539f8e2af
--- /dev/null
+++ b/lib/syntax_tools/examples/merl/merl_build.erl
@@ -0,0 +1,104 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012 Richard Carlsson
+%% @doc Making it simple to build a module with merl
+
+-module(merl_build).
+
+-export([init_module/1, module_forms/1, add_function/4, add_record/3,
+ add_import/3, add_attribute/3, set_file/2]).
+
+-import(merl, [term/1]).
+
+-include("merl.hrl").
+
+-type filename() :: string().
+
+-record(module, { name :: atom()
+ , file :: filename()
+ , exports=[] :: [{atom(), integer()}]
+ , imports=[] :: [{atom(), [{atom(), integer()}]}]
+ , attributes=[] :: [{filename(), atom(), [term()]}]
+ , records=[] :: [{filename(), atom(),
+ [{atom(), merl:tree()}]}]
+ , functions=[] :: [{filename(), atom(), [merl:tree()]}]
+ }).
+
+%% TODO: init module from a list of forms (from various sources)
+
+%% @doc Create a new module representation, using the given module name.
+init_module(Name) when is_atom(Name) ->
+ %% use the module name as the default file name - better than nothing
+ #module{name=Name, file=atom_to_list(Name)}.
+
+%% @doc Get the list of syntax tree forms for a module representation. This can
+%% be passed to compile/2.
+module_forms(#module{name=Name,
+ exports=Xs,
+ imports=Is,
+ records=Rs,
+ attributes=As,
+ functions=Fs})
+ when is_atom(Name), Name =/= undefined ->
+ Module = ?Q("-module('@Name@')."),
+ Exported = [erl_syntax:arity_qualifier(term(N), term(A))
+ || {N,A} <- ordsets:from_list(Xs)],
+ Export = ?Q("-export(['@_Exported'/1])."),
+ Imports = [?Q("-import('@M@', ['@_NAs'/1]).")
+ || {M, Ns} <- Is,
+ NAs <- [[erl_syntax:arity_qualifier(term(N), term(A))
+ || {N,A} <- ordsets:from_list(Ns)]]
+ ],
+ Attrs = [?Q("-file(\"'@File@\",1). -'@N@'('@T@').")
+ || {File, N, T} <- lists:reverse(As)],
+ Records = [?Q("-file(\"'@File@\",1). -record('@N@',{'@_RFs'=[]}).")
+ || {File, N, Es} <- lists:reverse(Rs),
+ RFs <- [[erl_syntax:record_field(term(F), V)
+ || {F,V} <- Es]]
+ ],
+ Functions = [?Q("-file(\"'@File@\",1). '@_F'() -> [].")
+ || {File, N, Cs} <- lists:reverse(Fs),
+ F <- [erl_syntax:function(term(N), Cs)]],
+ lists:flatten([Module, Export, Imports, Attrs, Records, Functions]).
+
+%% @doc Set the source file name for all subsequently added functions,
+%% records, and attributes.
+set_file(Filename, #module{}=M) ->
+ M#module{file=filename:flatten(Filename)}.
+
+%% @doc Add a function to a module representation.
+add_function(Exported, Name, Clauses,
+ #module{file=File, exports=Xs, functions=Fs}=M)
+ when is_boolean(Exported), is_atom(Name), Clauses =/= [] ->
+ Arity = length(erl_syntax:clause_patterns(hd(Clauses))),
+ Xs1 = case Exported of
+ true -> [{Name,Arity} | Xs];
+ false -> Xs
+ end,
+ M#module{exports=Xs1, functions=[{File, Name, Clauses} | Fs]}.
+
+%% @doc Add a record declaration to a module representation.
+add_record(Name, Fields, #module{file=File, records=Rs}=M)
+ when is_atom(Name) ->
+ M#module{records=[{File, Name, Fields} | Rs]}.
+
+%% @doc Add a "wild" attribute, such as `-compile(Opts)' to a module
+%% representation. Note that such attributes can only have a single argument.
+add_attribute(Name, Term, #module{file=File, attributes=As}=M)
+ when is_atom(Name) ->
+ M#module{attributes=[{File, Name, Term} | As]}.
+
+%% @doc Add an import declaration to a module representation.
+add_import(From, Names, #module{imports=Is}=M)
+ when is_atom(From), is_list(Names) ->
+ M#module{imports=[{From, Names} | Is]}.
diff --git a/lib/syntax_tools/include/merl.hrl b/lib/syntax_tools/include/merl.hrl
new file mode 100644
index 0000000000..e44a78dece
--- /dev/null
+++ b/lib/syntax_tools/include/merl.hrl
@@ -0,0 +1,29 @@
+%% ---------------------------------------------------------------------
+%% Header file for merl
+%%
+%% Licensed under the Apache License, Version 2.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.
+
+-ifndef(MERL_HRL).
+
+
+%% Quoting a piece of code
+-define(Q(Text), merl:quote(?LINE, Text)).
+
+%% Quasi-quoting code, substituting metavariables listed in Env
+-define(Q(Text, Env), merl:qquote(?LINE, Text, Env)).
+
+
+-ifndef(MERL_NO_TRANSFORM).
+-compile({parse_transform, merl_transform}).
+-endif.
+
+
+-endif.
diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile
index c9fbad8f9a..2e91adf8af 100644
--- a/lib/syntax_tools/src/Makefile
+++ b/lib/syntax_tools/src/Makefile
@@ -22,6 +22,9 @@ RELSYSDIR = $(RELEASE_PATH)/lib/syntax_tools-$(VSN)
#
EBIN = ../ebin
+INCLUDE=../include
+
+ERL_COMPILE_FLAGS += -pa $(EBIN) -pa ./ -I$(INCLUDE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
@@ -30,10 +33,15 @@ ERL_COMPILE_FLAGS += +nowarn_shadow_vars +warn_unused_import -Werror # +warn_mis
SOURCES=erl_syntax.erl erl_prettypr.erl erl_syntax_lib.erl \
erl_comment_scan.erl erl_recomment.erl erl_tidy.erl \
- epp_dodger.erl prettypr.erl igor.erl
+ epp_dodger.erl prettypr.erl igor.erl \
+ merl.erl merl_transform.erl
+
+INCLUDE_FILES = merl.hrl
OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
+INCLUDE_DELIVERABLES = $(INCLUDE_FILES:%=$(INCLUDE)/%)
+
APP_FILE= syntax_tools.app
APP_SRC= $(APP_FILE).src
APP_TARGET= $(EBIN)/$(APP_FILE)
@@ -52,6 +60,7 @@ all: $(OBJECTS)
clean:
+ rm -f ./merl_transform.beam
rm -f $(OBJECTS)
rm -f core *~
@@ -64,6 +73,15 @@ realclean: clean
$(EBIN)/%.$(EMULATOR):%.erl
$(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+# special rules and dependencies to apply the transform to itself
+$(EBIN)/merl_transform.beam: $(EBIN)/merl.beam ./merl_transform.beam \
+ ../include/merl.hrl \
+ $(EBIN)/erl_syntax.beam $(EBIN)/erl_syntax_lib.beam
+./merl_transform.beam: ./merl_transform.erl $(EBIN)/merl.beam \
+ ../include/merl.hrl
+ $(V_ERLC) -DMERL_NO_TRANSFORM $(ERL_COMPILE_FLAGS) -o ./ $<
+
+
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
@@ -84,6 +102,8 @@ release_spec: opt
$(INSTALL_DATA) $(OBJECTS) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/src"
$(INSTALL_DATA) $(SOURCES) "$(RELSYSDIR)/src"
+ $(INSTALL_DIR) "$(RELSYSDIR)/include"
+ $(INSTALL_DATA) $(INCLUDE_DELIVERABLES) "$(RELSYSDIR)/include"
release_docs_spec:
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 3ca7a8197e..39c522fd11 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -454,7 +454,7 @@ io_error(L, Desc) ->
{L, ?MODULE, Desc}.
start_pos([T | _Ts], _L) ->
- element(2, T);
+ erl_anno:line(element(2, T));
start_pos([], L) ->
L.
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index 877675772f..81272e62de 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -50,8 +50,7 @@
| fun((erl_syntax:syntaxTree(), _, _) -> prettypr:document()).
-type clause_t() :: 'case_expr' | 'cond_expr' | 'fun_expr'
| 'if_expr' | 'receive_expr' | 'try_expr'
- | {'function', prettypr:document()}
- | {'rule', prettypr:document()}.
+ | {'function', prettypr:document()}.
-record(ctxt, {prec = 0 :: integer(),
sub_indent = 2 :: non_neg_integer(),
@@ -587,8 +586,6 @@ lay_2(Node, Ctxt) ->
make_case_clause(D1, D2, D3, Ctxt);
try_expr ->
make_case_clause(D1, D2, D3, Ctxt);
- {rule, N} ->
- make_rule_clause(N, D1, D2, D3, Ctxt);
undefined ->
%% If a clause is formatted out of context, we
%% use a "fun-expression" clause style.
@@ -851,14 +848,10 @@ lay_2(Node, Ctxt) ->
floating(text(".")),
lay(erl_syntax:record_access_field(Node),
set_prec(Ctxt, PrecR))),
- D3 = case erl_syntax:record_access_type(Node) of
- none ->
- D2;
- T ->
- beside(beside(floating(text("#")),
- lay(T, reset_prec(Ctxt))),
- D2)
- end,
+ T = erl_syntax:record_access_type(Node),
+ D3 = beside(beside(floating(text("#")),
+ lay(T, reset_prec(Ctxt))),
+ D2),
maybe_parentheses(beside(D1, D3), Prec, Ctxt);
record_expr ->
@@ -926,15 +919,6 @@ lay_2(Node, Ctxt) ->
D2 = lay(erl_syntax:map_field_exact_value(Node), Ctxt1),
par([D1, floating(text(":=")), D2], Ctxt1#ctxt.break_indent);
- rule ->
- %% Comments on the name will be repeated; cf.
- %% `function'.
- Ctxt1 = reset_prec(Ctxt),
- D1 = lay(erl_syntax:rule_name(Node), Ctxt1),
- D2 = lay_clauses(erl_syntax:rule_clauses(Node),
- {rule, D1}, Ctxt1),
- beside(D2, floating(text(".")));
-
size_qualifier ->
Ctxt1 = set_prec(Ctxt, max_prec()),
D1 = lay(erl_syntax:size_qualifier_body(Node), Ctxt1),
@@ -1073,10 +1057,6 @@ make_fun_clause_head(N, P, Ctxt) ->
beside(N, D)
end.
-make_rule_clause(N, P, G, B, Ctxt) ->
- D = make_fun_clause_head(N, P, Ctxt),
- append_rule_body(B, append_guard(G, D, Ctxt), Ctxt).
-
make_case_clause(P, G, B, Ctxt) ->
append_clause_body(B, append_guard(G, P, Ctxt), Ctxt).
@@ -1092,9 +1072,6 @@ make_if_clause(_P, G, B, Ctxt) ->
append_clause_body(B, D, Ctxt) ->
append_clause_body(B, D, floating(text(" ->")), Ctxt).
-append_rule_body(B, D, Ctxt) ->
- append_clause_body(B, D, floating(text(" :-")), Ctxt).
-
append_clause_body(B, D, S, Ctxt) ->
sep([beside(D, S), nest(Ctxt#ctxt.break_indent, B)]).
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index 7b2f9f7adb..72e1e2d2f5 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -123,7 +123,6 @@ recomment_forms(Tree, Cs, Insert) ->
form_list ->
Tree1 = erl_syntax:flatten_form_list(Tree),
Node = build_tree(Tree1),
-
%% Here we make a small assumption about the substructure of
%% a `form_list' tree: it has exactly one group of subtrees.
[Node1] = node_subtrees(Node),
@@ -753,7 +752,13 @@ get_line(Node) ->
{_, L, _} when is_integer(L) ->
L;
Pos ->
- exit({bad_position, Pos})
+ try erl_anno:line(Pos) of
+ Line ->
+ Line
+ catch
+ _:_ ->
+ exit({bad_position, Pos})
+ end
end.
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 40372a2106..3f2a3e05dd 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -254,7 +254,6 @@
receive_expr_action/1,
receive_expr_clauses/1,
receive_expr_timeout/1,
- record_access/2,
record_access/3,
record_access_argument/1,
record_access_field/1,
@@ -271,10 +270,6 @@
record_index_expr/2,
record_index_expr_field/1,
record_index_expr_type/1,
- rule/2,
- rule_arity/1,
- rule_clauses/1,
- rule_name/1,
size_qualifier/2,
size_qualifier_argument/1,
size_qualifier_body/1,
@@ -472,19 +467,16 @@
%% <td>record_field</td>
%% </tr><tr>
%% <td>record_index_expr</td>
-%% <td>rule</td>
%% <td>size_qualifier</td>
%% <td>string</td>
-%% </tr><tr>
%% <td>text</td>
+%% </tr><tr>
%% <td>try_expr</td>
%% <td>tuple</td>
%% <td>underscore</td>
-%% </tr><tr>
%% <td>variable</td>
+%% </tr><tr>
%% <td>warning_marker</td>
-%% <td></td>
-%% <td></td>
%% </tr>
%% </table></center>
%%
@@ -540,7 +532,6 @@
%% @see record_expr/2
%% @see record_field/2
%% @see record_index_expr/2
-%% @see rule/2
%% @see size_qualifier/2
%% @see string/1
%% @see text/1
@@ -607,10 +598,8 @@ type(Node) ->
{record, _, _, _, _} -> record_expr;
{record, _, _, _} -> record_expr;
{record_field, _, _, _, _} -> record_access;
- {record_field, _, _, _} -> record_access;
{record_index, _, _, _} -> record_index_expr;
{remote, _, _, _} -> module_qualifier;
- {rule, _, _, _, _} -> rule;
{'try', _, _, _, _, _} -> try_expr;
{tuple, _, _} -> tuple;
_ ->
@@ -693,10 +682,9 @@ is_leaf(Node) ->
%% <td>`comment'</td>
%% <td>`error_marker'</td>
%% <td>`eof_marker'</td>
-%% <td>`form_list'</td>
%% </tr><tr>
+%% <td>`form_list'</td>
%% <td>`function'</td>
-%% <td>`rule'</td>
%% <td>`warning_marker'</td>
%% <td>`text'</td>
%% </tr>
@@ -709,7 +697,6 @@ is_leaf(Node) ->
%% @see error_marker/1
%% @see form_list/1
%% @see function/2
-%% @see rule/2
%% @see warning_marker/1
-spec is_form(syntaxTree()) -> boolean().
@@ -722,7 +709,6 @@ is_form(Node) ->
eof_marker -> true;
error_marker -> true;
form_list -> true;
- rule -> true;
warning_marker -> true;
text -> true;
_ -> false
@@ -3323,6 +3309,11 @@ attribute_arguments(Node) ->
[set_pos(
list(unfold_function_names(Data, Pos)),
Pos)];
+ optional_callbacks ->
+ D = try list(unfold_function_names(Data, Pos))
+ catch _:_ -> abstract(Data)
+ end,
+ [set_pos(D, Pos)];
import ->
{Module, Imports} = Data,
[set_pos(atom(Module), Pos),
@@ -3475,7 +3466,6 @@ module_qualifier_body(Node) ->
%% @see function_clauses/1
%% @see function_arity/1
%% @see is_form/1
-%% @see rule/2
%% Don't use the name 'function' for this record, to avoid confusion with
%% the tuples on the form {function,Name,Arity} used by erl_parse.
@@ -4305,49 +4295,32 @@ record_index_expr_field(Node) ->
%% =====================================================================
-%% @equiv record_access(Argument, none, Field)
-
--spec record_access(syntaxTree(), syntaxTree()) -> syntaxTree().
-
-record_access(Argument, Field) ->
- record_access(Argument, none, Field).
-
-
-%% =====================================================================
-%% @doc Creates an abstract record field access expression. If
-%% `Type' is not `none', the result represents
-%% "<code><em>Argument</em>#<em>Type</em>.<em>Field</em></code>".
-%%
-%% If `Type' is `none', the result represents
-%% "<code><em>Argument</em>.<em>Field</em></code>". This is a special
-%% form only allowed within Mnemosyne queries.
+%% @doc Creates an abstract record field access expression. The result
+%% represents "<code><em>Argument</em>#<em>Type</em>.<em>Field</em></code>".
%%
-%% @see record_access/2
%% @see record_access_argument/1
%% @see record_access_type/1
%% @see record_access_field/1
%% @see record_expr/3
-record(record_access, {argument :: syntaxTree(),
- type :: 'none' | syntaxTree(),
+ type :: syntaxTree(),
field :: syntaxTree()}).
%% type(Node) = record_access
%% data(Node) = #record_access{argument :: Argument, type :: Type,
%% field :: Field}
%%
-%% Argument = Field = syntaxTree()
-%% Type = none | syntaxTree()
+%% Argument = Type = Field = syntaxTree()
%%
%% `erl_parse' representation:
%%
%% {record_field, Pos, Argument, Type, Field}
-%% {record_field, Pos, Argument, Field}
%%
%% Argument = Field = erl_parse()
%% Type = atom()
--spec record_access(syntaxTree(), 'none' | syntaxTree(), syntaxTree()) ->
+-spec record_access(syntaxTree(), syntaxTree(), syntaxTree()) ->
syntaxTree().
record_access(Argument, Type, Field) ->
@@ -4360,16 +4333,11 @@ revert_record_access(Node) ->
Argument = record_access_argument(Node),
Type = record_access_type(Node),
Field = record_access_field(Node),
- if Type =:= none ->
- {record_field, Pos, Argument, Field};
- true ->
- case type(Type) of
- atom ->
- {record_field, Pos,
- Argument, concrete(Type), Field};
- _ ->
- Node
- end
+ case type(Type) of
+ atom ->
+ {record_field, Pos, Argument, concrete(Type), Field};
+ _ ->
+ Node
end.
@@ -4382,8 +4350,6 @@ revert_record_access(Node) ->
record_access_argument(Node) ->
case unwrap(Node) of
- {record_field, _, Argument, _} ->
- Argument;
{record_field, _, Argument, _, _} ->
Argument;
Node1 ->
@@ -4392,21 +4358,14 @@ record_access_argument(Node) ->
%% =====================================================================
-%% @doc Returns the type subtree of a `record_access' node,
-%% if any. If `Node' represents
-%% "<code><em>Argument</em>.<em>Field</em></code>", `none'
-%% is returned, otherwise if `Node' represents
-%% "<code><em>Argument</em>#<em>Type</em>.<em>Field</em></code>",
-%% `Type' is returned.
+%% @doc Returns the type subtree of a `record_access' node.
%%
%% @see record_access/3
--spec record_access_type(syntaxTree()) -> 'none' | syntaxTree().
+-spec record_access_type(syntaxTree()) -> syntaxTree().
record_access_type(Node) ->
case unwrap(Node) of
- {record_field, _, _, _} ->
- none;
{record_field, Pos, _, Type, _} ->
set_pos(atom(Type), Pos);
Node1 ->
@@ -4423,8 +4382,6 @@ record_access_type(Node) ->
record_access_field(Node) ->
case unwrap(Node) of
- {record_field, _, _, Field} ->
- Field;
{record_field, _, _, _, Field} ->
Field;
Node1 ->
@@ -4803,117 +4760,6 @@ binary_comp_body(Node) ->
%% =====================================================================
-%% @doc Creates an abstract Mnemosyne rule. If `Clauses' is
-%% `[C1, ..., Cn]', the results represents
-%% "<code><em>Name</em> <em>C1</em>; ...; <em>Name</em>
-%% <em>Cn</em>.</code>". More exactly, if each `Ci'
-%% represents "<code>(<em>Pi1</em>, ..., <em>Pim</em>) <em>Gi</em> ->
-%% <em>Bi</em></code>", then the result represents
-%% "<code><em>Name</em>(<em>P11</em>, ..., <em>P1m</em>) <em>G1</em> :-
-%% <em>B1</em>; ...; <em>Name</em>(<em>Pn1</em>, ..., <em>Pnm</em>)
-%% <em>Gn</em> :- <em>Bn</em>.</code>". Rules are source code forms.
-%%
-%% @see rule_name/1
-%% @see rule_clauses/1
-%% @see rule_arity/1
-%% @see is_form/1
-%% @see function/2
-
--record(rule, {name :: syntaxTree(), clauses :: [syntaxTree()]}).
-
-%% type(Node) = rule
-%% data(Node) = #rule{name :: Name, clauses :: Clauses}
-%%
-%% Name = syntaxTree()
-%% Clauses = [syntaxTree()]
-%%
-%% (See `function' for notes on why the arity is not stored.)
-%%
-%% `erl_parse' representation:
-%%
-%% {rule, Pos, Name, Arity, Clauses}
-%%
-%% Name = atom()
-%% Arity = integer()
-%% Clauses = [Clause] \ []
-%% Clause = {clause, ...}
-%%
-%% where the number of patterns in each clause should be equal to
-%% the integer `Arity'; see `clause' for documentation on
-%% `erl_parse' clauses.
-
--spec rule(syntaxTree(), [syntaxTree()]) -> syntaxTree().
-
-rule(Name, Clauses) ->
- tree(rule, #rule{name = Name, clauses = Clauses}).
-
-revert_rule(Node) ->
- Name = rule_name(Node),
- Clauses = [revert_clause(C) || C <- rule_clauses(Node)],
- Pos = get_pos(Node),
- case type(Name) of
- atom ->
- A = rule_arity(Node),
- {rule, Pos, concrete(Name), A, Clauses};
- _ ->
- Node
- end.
-
-
-%% =====================================================================
-%% @doc Returns the name subtree of a `rule' node.
-%%
-%% @see rule/2
-
--spec rule_name(syntaxTree()) -> syntaxTree().
-
-rule_name(Node) ->
- case unwrap(Node) of
- {rule, Pos, Name, _, _} ->
- set_pos(atom(Name), Pos);
- Node1 ->
- (data(Node1))#rule.name
- end.
-
-%% =====================================================================
-%% @doc Returns the list of clause subtrees of a `rule' node.
-%%
-%% @see rule/2
-
--spec rule_clauses(syntaxTree()) -> [syntaxTree()].
-
-rule_clauses(Node) ->
- case unwrap(Node) of
- {rule, _, _, _, Clauses} ->
- Clauses;
- Node1 ->
- (data(Node1))#rule.clauses
- end.
-
-%% =====================================================================
-%% @doc Returns the arity of a `rule' node. The result is the
-%% number of parameter patterns in the first clause of the rule;
-%% subsequent clauses are ignored.
-%%
-%% An exception is thrown if `rule_clauses(Node)' returns
-%% an empty list, or if the first element of that list is not a syntax
-%% tree `C' of type `clause' such that
-%% `clause_patterns(C)' is a nonempty list.
-%%
-%% @see rule/2
-%% @see rule_clauses/1
-%% @see clause/3
-%% @see clause_patterns/1
-
--spec rule_arity(syntaxTree()) -> arity().
-
-rule_arity(Node) ->
- %% Note that this never accesses the arity field of
- %% `erl_parse' rule nodes.
- length(clause_patterns(hd(rule_clauses(Node)))).
-
-
-%% =====================================================================
%% @doc Creates an abstract generator. The result represents
%% "<code><em>Pattern</em> &lt;- <em>Body</em></code>".
%%
@@ -6135,6 +5981,13 @@ abstract_tail(H, T) ->
%% {@link char/1} function to explicitly create an abstract
%% character.)
%%
+%% Note: `arity_qualifier' nodes are recognized. This is to follow The
+%% Erlang Parser when it comes to wild attributes: both {F, A} and F/A
+%% are recognized, which makes it possible to turn wild attributes
+%% into recognized attributes without at the same time making it
+%% impossible to compile files using the new syntax with the old
+%% version of the Erlang Compiler.
+%%
%% @see abstract/1
%% @see is_literal/1
%% @see char/1
@@ -6184,6 +6037,20 @@ concrete(Node) ->
{value, concrete(F), []}
end, [], true),
B;
+ arity_qualifier ->
+ A = erl_syntax:arity_qualifier_argument(Node),
+ case erl_syntax:type(A) of
+ integer ->
+ F = erl_syntax:arity_qualifier_body(Node),
+ case erl_syntax:type(F) of
+ atom ->
+ {F, A};
+ _ ->
+ erlang:error({badarg, Node})
+ end;
+ _ ->
+ erlang:error({badarg, Node})
+ end;
_ ->
erlang:error({badarg, Node})
end.
@@ -6377,8 +6244,6 @@ revert_root(Node) ->
revert_record_expr(Node);
record_index_expr ->
revert_record_index_expr(Node);
- rule ->
- revert_rule(Node);
string ->
revert_string(Node);
try_expr ->
@@ -6635,15 +6500,9 @@ subtrees(T) ->
receive_expr_action(T)]
end;
record_access ->
- case record_access_type(T) of
- none ->
- [[record_access_argument(T)],
- [record_access_field(T)]];
- R ->
- [[record_access_argument(T)],
- [R],
- [record_access_field(T)]]
- end;
+ [[record_access_argument(T)],
+ [record_access_type(T)],
+ [record_access_field(T)]];
record_expr ->
case record_expr_argument(T) of
none ->
@@ -6664,8 +6523,6 @@ subtrees(T) ->
record_index_expr ->
[[record_index_expr_type(T)],
[record_index_expr_field(T)]];
- rule ->
- [[rule_name(T)], rule_clauses(T)];
size_qualifier ->
[[size_qualifier_body(T)],
[size_qualifier_argument(T)]];
@@ -6760,8 +6617,6 @@ make_tree(parentheses, [[E]]) -> parentheses(E);
make_tree(prefix_expr, [[F], [A]]) -> prefix_expr(F, A);
make_tree(receive_expr, [C]) -> receive_expr(C);
make_tree(receive_expr, [C, [E], A]) -> receive_expr(C, E, A);
-make_tree(record_access, [[E], [F]]) ->
- record_access(E, F);
make_tree(record_access, [[E], [T], [F]]) ->
record_access(E, T, F);
make_tree(record_expr, [[T], F]) -> record_expr(T, F);
@@ -6770,7 +6625,6 @@ make_tree(record_field, [[N]]) -> record_field(N);
make_tree(record_field, [[N], [E]]) -> record_field(N, E);
make_tree(record_index_expr, [[T], [F]]) ->
record_index_expr(T, F);
-make_tree(rule, [[N], C]) -> rule(N, C);
make_tree(size_qualifier, [[N], [A]]) -> size_qualifier(N, A);
make_tree(try_expr, [B, C, H, A]) -> try_expr(B, C, H, A);
make_tree(tuple, [E]) -> tuple(E).
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index 2f0488abec..5b5b18d15b 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -35,8 +35,7 @@
analyze_function_name/1, analyze_implicit_fun/1,
analyze_import_attribute/1, analyze_module_attribute/1,
analyze_record_attribute/1, analyze_record_expr/1,
- analyze_record_field/1, analyze_rule/1,
- analyze_wild_attribute/1, annotate_bindings/1,
+ analyze_record_field/1, analyze_wild_attribute/1, annotate_bindings/1,
annotate_bindings/2, fold/3, fold_subtrees/3, foldl_listlist/3,
function_name_expansions/1, is_fail_expr/1, limit/2, limit/3,
map/2, map_subtrees/2, mapfold/3, mapfold_subtrees/3,
@@ -527,8 +526,6 @@ vann(Tree, Env) ->
vann_try_expr(Tree, Env);
function ->
vann_function(Tree, Env);
- rule ->
- vann_rule(Tree, Env);
fun_expr ->
vann_fun_expr(Tree, Env);
list_comp ->
@@ -569,15 +566,6 @@ vann_function(Tree, Env) ->
Bound = [],
{ann_bindings(Tree1, Env, Bound, Free), Bound, Free}.
-vann_rule(Tree, Env) ->
- Cs = erl_syntax:rule_clauses(Tree),
- {Cs1, {_, Free}} = vann_clauses(Cs, Env),
- N = erl_syntax:rule_name(Tree),
- {N1, _, _} = vann(N, Env),
- Tree1 = rewrite(Tree, erl_syntax:rule(N1, Cs1)),
- Bound = [],
- {ann_bindings(Tree1, Env, Bound, Free), Bound, Free}.
-
vann_fun_expr(Tree, Env) ->
Cs = erl_syntax:fun_expr_clauses(Tree),
{Cs1, {_, Free}} = vann_clauses(Cs, Env),
@@ -946,7 +934,7 @@ is_fail_expr(E) ->
%%
%% Forms = syntaxTree() | [syntaxTree()]
%% Key = attributes | errors | exports | functions | imports
-%% | module | records | rules | warnings
+%% | module | records | warnings
%%
%% @doc Analyzes a sequence of "program forms". The given
%% `Forms' may be a single syntax tree of type
@@ -1047,16 +1035,6 @@ is_fail_expr(E) ->
%% that each record name occurs at most once in the list. The
%% order of listing is not defined.</dd>
%%
-%% <dt>`{rules, Rules}'</dt>
-%% <dd><ul>
-%% <li>`Rules = [{atom(), integer()}]'</li>
-%% </ul>
-%% `Rules' is a list of the names of the rules that are
-%% defined in `Forms' (cf.
-%% `analyze_rule/1'). We do not guarantee that each
-%% name occurs at most once in the list. The order of listing is
-%% not defined.</dd>
-%%
%% <dt>`{warnings, Warnings}'</dt>
%% <dd><ul>
%% <li>`Warnings = [term()]'</li>
@@ -1074,12 +1052,11 @@ is_fail_expr(E) ->
%% @see analyze_import_attribute/1
%% @see analyze_record_attribute/1
%% @see analyze_function/1
-%% @see analyze_rule/1
%% @see erl_syntax:error_marker_info/1
%% @see erl_syntax:warning_marker_info/1
-type key() :: 'attributes' | 'errors' | 'exports' | 'functions' | 'imports'
- | 'module' | 'records' | 'rules' | 'warnings'.
+ | 'module' | 'records' | 'warnings'.
-type info_pair() :: {key(), term()}.
-spec analyze_forms(erl_syntax:forms()) -> [info_pair()].
@@ -1099,8 +1076,6 @@ collect_form(Node, Info) ->
Info;
{function, Name} ->
finfo_add_function(Name, Info);
- {rule, Name} ->
- finfo_add_rule(Name, Info);
{error_marker, Data} ->
finfo_add_error(Data, Info);
{warning_marker, Data} ->
@@ -1136,8 +1111,7 @@ collect_attribute(_, {N, V}, Info) ->
records = [] :: [{atom(), [{atom(), field_default()}]}],
errors = [] :: [term()],
warnings = [] :: [term()],
- functions = [] :: [{atom(), arity()}],
- rules = [] :: [{atom(), arity()}]}).
+ functions = [] :: [{atom(), arity()}]}).
-type field_default() :: 'none' | erl_syntax:syntaxTree().
@@ -1183,9 +1157,6 @@ finfo_add_warning(R, Info) ->
finfo_add_function(F, Info) ->
Info#forms{functions = [F | Info#forms.functions]}.
-finfo_add_rule(F, Info) ->
- Info#forms{rules = [F | Info#forms.rules]}.
-
finfo_to_list(Info) ->
[{Key, Value}
|| {Key, {value, Value}} <-
@@ -1197,8 +1168,7 @@ finfo_to_list(Info) ->
{records, list_value(Info#forms.records)},
{errors, list_value(Info#forms.errors)},
{warnings, list_value(Info#forms.warnings)},
- {functions, list_value(Info#forms.functions)},
- {rules, list_value(Info#forms.rules)}
+ {functions, list_value(Info#forms.functions)}
]].
list_value([]) ->
@@ -1229,10 +1199,6 @@ list_value(List) ->
%%
%% <dd>where `Info = analyze_function(Node)'.</dd>
%%
-%% <dt>`{rule, Info}'</dt>
-%%
-%% <dd>where `Info = analyze_rule(Node)'.</dd>
-%%
%% <dt>`{warning_marker, Info}'</dt>
%%
%% <dd>where `Info =
@@ -1245,7 +1211,6 @@ list_value(List) ->
%%
%% @see analyze_attribute/1
%% @see analyze_function/1
-%% @see analyze_rule/1
%% @see erl_syntax:is_form/1
%% @see erl_syntax:error_marker_info/1
%% @see erl_syntax:warning_marker_info/1
@@ -1258,8 +1223,6 @@ analyze_form(Node) ->
{attribute, analyze_attribute(Node)};
function ->
{function, analyze_function(Node)};
- rule ->
- {rule, analyze_rule(Node)};
error_marker ->
{error_marker, erl_syntax:error_marker_info(Node)};
warning_marker ->
@@ -1669,7 +1632,7 @@ analyze_record_attribute_tuple(Node) ->
%% <dt>`record_expr':</dt>
%% <dd>`{atom(), [{atom(), Value}]}'</dd>
%% <dt>`record_access':</dt>
-%% <dd>`{atom(), atom()} | atom()'</dd>
+%% <dd>`{atom(), atom()}'</dd>
%% <dt>`record_index_expr':</dt>
%% <dd>`{atom(), atom()}'</dd>
%% </dl>
@@ -1679,9 +1642,7 @@ analyze_record_attribute_tuple(Node) ->
%% listed in the order they appear. (See
%% `analyze_record_field/1' for details on the field
%% descriptors). For a `record_access' node,
-%% `Info' represents the record name and the field name (or
-%% if the record name is not included, only the field name; this is
-%% allowed only in Mnemosyne-query syntax). For a
+%% `Info' represents the record name and the field name. For a
%% `record_index_expr' node, `Info' represents the
%% record name and the name field name.
%%
@@ -1713,18 +1674,14 @@ analyze_record_expr(Node) ->
F = erl_syntax:record_access_field(Node),
case erl_syntax:type(F) of
atom ->
- case erl_syntax:record_access_type(Node) of
- none ->
- {record_access, erl_syntax:atom_value(F)};
- A ->
- case erl_syntax:type(A) of
- atom ->
- {record_access,
- {erl_syntax:atom_value(A),
- erl_syntax:atom_value(F)}};
- _ ->
- throw(syntax_error)
- end
+ A = erl_syntax:record_access_type(Node),
+ case erl_syntax:type(A) of
+ atom ->
+ {record_access,
+ {erl_syntax:atom_value(A),
+ erl_syntax:atom_value(F)}};
+ _ ->
+ throw(syntax_error)
end;
_ ->
throw(syntax_error)
@@ -1835,8 +1792,6 @@ analyze_file_attribute(Node) ->
%% The evaluation throws `syntax_error' if
%% `Node' does not represent a well-formed function
%% definition.
-%%
-%% @see analyze_rule/1
-spec analyze_function(erl_syntax:syntaxTree()) -> {atom(), arity()}.
@@ -1857,37 +1812,6 @@ analyze_function(Node) ->
%% =====================================================================
-%% @spec analyze_rule(Node::syntaxTree()) -> {atom(), integer()}
-%%
-%% @doc Returns the name and arity of a Mnemosyne rule. The result is a
-%% pair `{Name, A}' if `Node' represents a rule
-%% "`Name(<em>P_1</em>, ..., <em>P_A</em>) :- ...'".
-%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed Mnemosyne
-%% rule.
-%%
-%% @see analyze_function/1
-
--spec analyze_rule(erl_syntax:syntaxTree()) -> {atom(), arity()}.
-
-analyze_rule(Node) ->
- case erl_syntax:type(Node) of
- rule ->
- N = erl_syntax:rule_name(Node),
- case erl_syntax:type(N) of
- atom ->
- {erl_syntax:atom_value(N),
- erl_syntax:rule_arity(Node)};
- _ ->
- throw(syntax_error)
- end;
- _ ->
- throw(syntax_error)
- end.
-
-
-%% =====================================================================
%% @spec analyze_implicit_fun(Node::syntaxTree()) -> FunctionName
%%
%% FunctionName = atom() | {atom(), integer()}
diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl
index 38e0c2099b..db7f0939a3 100644
--- a/lib/syntax_tools/src/erl_tidy.erl
+++ b/lib/syntax_tools/src/erl_tidy.erl
@@ -792,16 +792,11 @@ keep_form(Form, Used, Opts) ->
N = erl_syntax_lib:analyze_function(Form),
case sets:is_element(N, Used) of
false ->
- report_removed_def("function", N, Form, Opts),
- false;
- true ->
- true
- end;
- rule ->
- N = erl_syntax_lib:analyze_rule(Form),
- case sets:is_element(N, Used) of
- false ->
- report_removed_def("rule", N, Form, Opts),
+ {F, A} = N,
+ File = proplists:get_value(file, Opts, ""),
+ report({File, erl_syntax:get_pos(Form),
+ "removing unused function `~w/~w'."},
+ [F, A], Opts),
false;
true ->
true
@@ -823,12 +818,6 @@ keep_form(Form, Used, Opts) ->
true
end.
-report_removed_def(Type, {N, A}, Form, Opts) ->
- File = proplists:get_value(file, Opts, ""),
- report({File, erl_syntax:get_pos(Form),
- "removing unused ~s `~w/~w'."},
- [Type, N, A], Opts).
-
collect_functions(Forms) ->
lists:foldl(
fun (F, {Names, Defs}) ->
@@ -837,10 +826,6 @@ collect_functions(Forms) ->
N = erl_syntax_lib:analyze_function(F),
{sets:add_element(N, Names),
dict:store(N, {F, []}, Defs)};
- rule ->
- N = erl_syntax_lib:analyze_rule(F),
- {sets:add_element(N, Names),
- dict:store(N, {F, []}, Defs)};
_ ->
{Names, Defs}
end
@@ -855,11 +840,6 @@ update_forms([F | Fs], Defs, Imports, Opts) ->
{F1, Fs1} = dict:fetch(N, Defs),
[F1 | lists:reverse(Fs1)] ++ update_forms(Fs, Defs, Imports,
Opts);
- rule ->
- N = erl_syntax_lib:analyze_rule(F),
- {F1, Fs1} = dict:fetch(N, Defs),
- [F1 | lists:reverse(Fs1)] ++ update_forms(Fs, Defs, Imports,
- Opts);
attribute ->
[update_attribute(F, Imports, Opts)
| update_forms(Fs, Defs, Imports, Opts)];
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index 0420508f2a..eac5af5540 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -1713,8 +1713,6 @@ transform(Tree, Env, St) ->
transform_function(Tree, Env, St);
implicit_fun ->
transform_implicit_fun(Tree, Env, St);
- rule ->
- transform_rule(Tree, Env, St);
record_expr ->
transform_record(Tree, Env, St);
record_index_expr ->
@@ -1778,27 +1776,6 @@ renaming_note(Name) ->
rename_atom(Node, Atom) ->
rewrite(Node, erl_syntax:atom(Atom)).
-%% Renaming Mnemosyne rules (just like function definitions)
-
-transform_rule(T, Env, St) ->
- {T1, St1} = default_transform(T, Env, St),
- F = erl_syntax_lib:analyze_rule(T1),
- {V, Text} = case (Env#code.map)(F) of
- F ->
- %% Not renamed
- {none, []};
- {Atom, _Arity} ->
- %% Renamed
- Cs = erl_syntax:rule_clauses(T1),
- N = rename_atom(
- erl_syntax:rule_name(T1),
- Atom),
- T2 = rewrite(T1,
- erl_syntax:rule(N, Cs)),
- {{value, T2}, renaming_note(Atom)}
- end,
- {maybe_modified(V, T1, 2, Text, Env), St1}.
-
%% Renaming "implicit fun" expressions (done quietly).
transform_implicit_fun(T, Env, St) ->
diff --git a/lib/syntax_tools/src/merl.erl b/lib/syntax_tools/src/merl.erl
new file mode 100644
index 0000000000..690306c17b
--- /dev/null
+++ b/lib/syntax_tools/src/merl.erl
@@ -0,0 +1,1230 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% Note: EDoc uses @@ and @} as escape sequences, so in the doc text below,
+%% `@@' must be written `@@@@' and `@}' must be written `@@}'.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2010-2015 Richard Carlsson
+%%
+%% @doc Metaprogramming in Erlang.
+%% Merl is a more user friendly interface to the `erl_syntax' module, making
+%% it easy both to build new ASTs from scratch and to
+%% match and decompose existing ASTs. For details that are outside the scope
+%% of Merl itself, please see the documentation of {@link erl_syntax}.
+%%
+%% == Quick start ==
+%%
+%% To enable the full power of Merl, your module needs to include the Merl
+%% header file:
+%% ```-include_lib("syntax_tools/include/merl.hrl").'''
+%%
+%% Then, you can use the `?Q(Text)' macros in your code to create ASTs or match
+%% on existing ASTs. For example:
+%% ```Tuple = ?Q("{foo, 42}"),
+%% ?Q("{foo, _@Number}") = Tuple,
+%% Call = ?Q("foo:bar(_@Number)")'''
+%%
+%% Calling `merl:print(Call)' will then print the following code:
+%% ```foo:bar(42)'''
+%%
+%% The `?Q' macros turn the quoted code fragments into ASTs, and lifts
+%% metavariables such as `_@Tuple' and `_@Number' to the level of your Erlang
+%% code, so you can use the corresponding Erlang variables `Tuple' and `Number'
+%% directly. This is the most straightforward way to use Merl, and in many
+%% cases it's all you need.
+%%
+%% You can even write case switches using `?Q' macros as patterns. For example:
+%% ```case AST of
+%% ?Q("{foo, _@Foo}") -> handle(Foo);
+%% ?Q("{bar, _@Bar}") when erl_syntax:is_integer(Bar) -> handle(Bar);
+%% _ -> handle_default()
+%% end'''
+%%
+%% These case switches only allow `?Q(...)' or `_' as clause patterns, and the
+%% guards may contain any expressions, not just Erlang guard expressions.
+%%
+%% If the macro `MERL_NO_TRANSFORM' is defined before the `merl.hrl' header
+%% file is included, the parse transform used by Merl will be disabled, and in
+%% that case, the match expressions `?Q(...) = ...', case switches using
+%% `?Q(...)' patterns, and automatic metavariables like `_@Tuple' cannot be
+%% used in your code, but the Merl macros and functions still work. To do
+%% metavariable substitution, you need to use the `?Q(Text, Map)' macro, e.g.:
+%% ```Tuple = ?Q("{foo, _@bar, _@baz}", [{bar, Bar}, {baz,Baz}])'''
+%%
+%% The text given to a `?Q(Text)' macro can be either a single string, or a
+%% list of strings. The latter is useful when you need to split a long
+%% expression over multiple lines, e.g.:
+%% ```?Q(["case _@Expr of",
+%% " {foo, X} -> f(X);",
+%% " {bar, X} -> g(X)",
+%% " _ -> h(X)"
+%% "end"])'''
+%% If there is a syntax error somewhere in the text (like the missing semicolon
+%% in the second clause above) this allows Merl to generate an error message
+%% pointing to the exact line in your source code. (Just remember to
+%% comma-separate the strings in the list, otherwise Erlang will concatenate
+%% the string fragments as if they were a single string.)
+%%
+%% == Metavariable syntax ==
+%%
+%% There are several ways to write a metavariable in your quoted code:
+%% <ul>
+%% <li>Atoms starting with `@', for example `` '@foo' '' or `` '@Foo' ''</li>
+%% <li>Variables starting with `_@', for example `_@bar' or `_@Bar'</li>
+%% <li>Strings starting with ``"'@'', for example ``"'@File"''</li>
+%% <li>Integers starting with 909, for example `9091' or `909123'</li>
+%% </ul>
+%% Following the prefix, one or more `_' or `0' characters may be used to
+%% indicate "lifting" of the variable one or more levels, and after that, a `@'
+%% or `9' character indicates a glob metavariable (matching zero or more
+%% elements in a sequence) rather than a normal metavariable. For example:
+%% <ul>
+%% <li>`` '@_foo' '' is lifted one level, and `_@__foo' is lifted two
+%% levels</li>
+%% <li>`_@@@@bar' is a glob variable, and `_@_@bar' is a lifted glob
+%% variable</li>
+%% <li>`90901' is a lifted variable,`90991' is a glob variable, and `9090091'
+%% is a glob variable lifted two levels</li>
+%% </ul>
+%% (Note that the last character in the name is never considered to be a lift
+%% or glob marker, hence, `_@__' and `90900' are only lifted one level, not
+%% two. Also note that globs only matter for matching; when doing
+%% substitutions, a non-glob variable can be used to inject a sequence of
+%% elements, and vice versa.)
+%%
+%% If the name after the prefix and any lift and glob markers is `_' or `0',
+%% the variable is treated as an anonymous catch-all pattern in matches. For
+%% example, `_@_', `_@@@@_', `_@__', or even `_@__@_'.
+%%
+%% Finally, if the name without any prefixes or lift/glob markers begins with
+%% an uppercase character, as in `_@Foo' or `_@_@Foo', it will become a
+%% variable on the Erlang level, and can be used to easily deconstruct and
+%% construct syntax trees:
+%% ```case Input of
+%% ?Q("{foo, _@Number}") -> ?Q("foo:bar(_@Number)");
+%% ...'''
+%% We refer to these as "automatic metavariables". If in addition the name ends
+%% with `@', as in `_@Foo@', the value of the variable as an Erlang term will
+%% be automatically converted to the corresponding abstract syntax tree when
+%% used to construct a larger tree. For example, in:
+%% ```Bar = {bar, 42},
+%% Foo = ?Q("{foo, _@Bar@@}")'''
+%% (where Bar is just some term, not a syntax tree) the result `Foo' will be a
+%% syntax tree representing `{foo, {bar, 42}}'. This avoids the need for
+%% temporary variables in order to inject data, as in
+%% ```TmpBar = erl_syntax:abstract(Bar),
+%% Foo = ?Q("{foo, _@TmpBar}")'''
+%%
+%% If the context requires an integer rather than a variable, an atom, or a
+%% string, you cannot use the uppercase convention to mark an automatic
+%% metavariable. Instead, if the integer (without the `909'-prefix and
+%% lift/glob markers) ends in a `9', the integer will become an Erlang-level
+%% variable prefixed with `Q', and if it ends with `99' it will also be
+%% automatically abstracted. For example, the following will increment the
+%% arity of the exported function f:
+%% ```case Form of
+%% ?Q("-export([f/90919]).") ->
+%% Q2 = erl_syntax:concrete(Q1) + 1,
+%% ?Q("-export([f/909299]).");
+%% ...'''
+%%
+%% == When to use the various forms of metavariables ==
+%%
+%% Merl can only parse a fragment of text if it follows the basic syntactical
+%% rules of Erlang. In most places, a normal Erlang variable can be used as
+%% metavariable, for example:
+%% ```?Q("f(_@Arg)") = Expr'''
+%% but if you want to match on something like the name of a function, you have
+%% to use an atom as metavariable:
+%% ```?Q("'@Name'() -> _@@@@_." = Function'''
+%% (note the anonymous glob variable `_@@@@_' to ignore the function body).
+%%
+%% In some contexts, only a string or an integer is allowed. For example, the
+%% directive `-file(Name, Line)' requires that `Name' is a string literal and
+%% `Line' an integer literal:
+%%
+%% ```?Q("-file(\"'@File\", 9090).") = ?Q("-file(\"foo.erl\", 42).")).'''
+%% This will extract the string literal `"foo.erl"' into the variable `Foo'.
+%% Note the use of the anonymous variable `9090' to ignore the line number. To
+%% match and also bind a metavariable that must be an integer literal, we can
+%% use the convention of ending the integer with a 9, turning it into a
+%% Q-prefixed variable on the Erlang level (see the previous section).
+%%
+%% === Globs ===
+%%
+%% Whenever you want to match out a number of elements in a sequence (zero or
+%% more) rather than a fixed set of elements, you need to use a glob. For
+%% example:
+%% ```?Q("{_@@@@Elements}") = ?Q({a, b, c})'''
+%% will bind Elements to the list of individual syntax trees representing the
+%% atoms `a', `b', and `c'. This can also be used with static prefix and suffix
+%% elements in the sequence. For example:
+%% ```?Q("{a, b, _@@@@Elements}") = ?Q({a, b, c, d})'''
+%% will bind Elements to the list of the `c' and `d' subtrees, and
+%% ```?Q("{_@@@@Elements, c, d}") = ?Q({a, b, c, d})'''
+%% will bind Elements to the list of the `a' and `b' subtrees. You can even use
+%% plain metavariables in the prefix or suffix:
+%% ```?Q("{_@First, _@@@@Rest}") = ?Q({a, b, c})'''
+%% or
+%% ```?Q("{_@@@@_, _@Last}") = ?Q({a, b, c})'''
+%% (ignoring all but the last element). You cannot however have two globs as
+%% part of the same sequence.
+%%
+%% === Lifted metavariables ===
+%%
+%% In some cases, the Erlang syntax rules make it impossible to place a
+%% metavariable directly where you would like it. For example, you cannot
+%% write:
+%% ```?Q("-export([_@@@@Name]).")'''
+%% to match out all name/arity pairs in the export list, or to insert a list of
+%% exports in a declaration, because the Erlang parser only allows elements on
+%% the form `A/I' (where `A' is an atom and `I' an integer) in the export list.
+%% A variable like the above is not allowed, but neither is a single atom or
+%% integer, so `` '@@@@Name' '' or `909919' wouldn't work either.
+%%
+%% What you have to do in such cases is to write your metavariable in a
+%% syntactically valid position, and use lifting markers to denote where it
+%% should really apply, as in:
+%% ```?Q("-export(['@@_@@Name'/0]).")'''
+%% This causes the variable to be lifted (after parsing) to the next higher
+%% level in the syntax tree, replacing that entire subtree. In this case, the
+%% `` '@@_@@Name'/0 '' will be replaced with `` '@@@@Name' '', and the ``/0''
+%% part was just used as dummy notation and will be discarded.
+%%
+%% You may even need to apply lifting more than once. To match the entire
+%% export list as a single syntax tree, you can write:
+%% ```?Q("-export(['@@__Name'/0]).")'''
+%% using two underscores, but with no glob marker this time. This will make the
+%% entire ``['@@__Name'/0]'' part be replaced with `` '@@Name' ''.
+%%
+%% Sometimes, the tree structure of a code fragment isn't very obvious, and
+%% parts of the structure may be invisible when printed as source code. For
+%% instance, a simple function definition like the following:
+%% ```zero() -> 0.'''
+%% consists of the name (the atom `zero'), and a list of clauses containing the
+%% single clause `() -> 0'. The clause consists of an argument list (empty), a
+%% guard (empty), and a body (which is always a list of expressions) containing
+%% the single expression `0'. This means that to match out the name and the
+%% list of clauses of any function, you'll need to use a pattern like
+%% ``?Q("'@Name'() -> _@_@Body.")'', using a dummy clause whose body is a glob
+%% lifted one level.
+%%
+%% To visualize the structure of a syntax tree, you can use the function
+%% `merl:show(T)', which prints a summary. For example, entering
+%% ```merl:show(merl:quote("inc(X, Y) when Y > 0 -> X + Y."))'''
+%% in the Erlang shell will print the following (where the `+' signs separate
+%% groups of subtrees on the same level):
+%% ```function: inc(X, Y) when ... -> X + Y.
+%% atom: inc
+%% +
+%% clause: (X, Y) when ... -> X + Y
+%% variable: X
+%% variable: Y
+%% +
+%% disjunction: Y > 0
+%% conjunction: Y > 0
+%% infix_expr: Y > 0
+%% variable: Y
+%% +
+%% operator: >
+%% +
+%% integer: 0
+%% +
+%% infix_expr: X + Y
+%% variable: X
+%% +
+%% operator: +
+%% +
+%% variable: Y'''
+%%
+%% This shows another important non-obvious case: a clause guard, even if it's
+%% as simple as `Y > 0', always consists of a single disjunction of one or more
+%% conjunctions of tests, much like a tuple of tuples. Thus:
+%% <ul>
+%% <li>``"when _@Guard ->"'' will only match a guard with exactly one
+%% test</li>
+%% <li>``"when _@@@@Guard ->"'' will match a guard with one or more
+%% comma-separated tests (but no semicolons), binding `Guard' to the list
+%% of tests</li>
+%% <li>``"when _@_Guard ->"'' will match just like the previous pattern, but
+%% binds `Guard' to the conjunction subtree</li>
+%% <li>``"when _@_@Guard ->"'' will match an arbitrary nonempty guard,
+%% binding `Guard' to the list of conjunction subtrees</li>
+%% <li>``"when _@__Guard ->"'' will match like the previous pattern, but
+%% binds `Guard' to the whole disjunction subtree</li>
+%% <li>and finally, ``"when _@__@Guard ->"'' will match any clause,
+%% binding `Guard' to `[]' if the guard is empty and to `[Disjunction]'
+%% otherwise</li>
+%% </ul>
+%%
+%% Thus, the following pattern matches all possible clauses:
+%% ```"(_@@Args) when _@__@Guard -> _@@Body"'''
+%% @end
+
+-module(merl).
+
+-export([term/1, var/1, print/1, show/1]).
+
+-export([quote/1, quote/2, qquote/2, qquote/3]).
+
+-export([template/1, tree/1, subst/2, tsubst/2, alpha/2, match/2, switch/2]).
+
+-export([template_vars/1, meta_template/1]).
+
+-export([compile/1, compile/2, compile_and_load/1, compile_and_load/2]).
+
+%% NOTE: this module may not include merl.hrl!
+
+-type tree() :: erl_syntax:syntaxTree().
+
+-type tree_or_trees() :: tree() | [tree()].
+
+-type pattern() :: tree() | template().
+
+-type pattern_or_patterns() :: pattern() | [pattern()].
+
+-type env() :: [{Key::id(), pattern_or_patterns()}].
+
+-type id() :: atom() | integer().
+
+%% A list of strings or binaries is assumed to represent individual lines,
+%% while a flat string or binary represents source code containing newlines.
+-type text() :: string() | binary() | [string()] | [binary()].
+
+-type location() :: erl_anno:location().
+
+
+%% ------------------------------------------------------------------------
+%% Compiling and loading code directly to memory
+
+%% @equiv compile(Code, [])
+compile(Code) ->
+ compile(Code, []).
+
+%% @doc Compile a syntax tree or list of syntax trees representing a module
+%% into a binary BEAM object.
+%% @see compile_and_load/2
+%% @see compile/1
+compile(Code, Options) when not is_list(Code)->
+ case type(Code) of
+ form_list -> compile(erl_syntax:form_list_elements(Code));
+ _ -> compile([Code], Options)
+ end;
+compile(Code, Options0) when is_list(Options0) ->
+ Forms = [erl_syntax:revert(F) || F <- Code],
+ Options = [verbose, report_errors, report_warnings, binary | Options0],
+ compile:noenv_forms(Forms, Options).
+
+
+%% @equiv compile_and_load(Code, [])
+compile_and_load(Code) ->
+ compile_and_load(Code, []).
+
+%% @doc Compile a syntax tree or list of syntax trees representing a module
+%% and load the resulting module into memory.
+%% @see compile/2
+%% @see compile_and_load/1
+compile_and_load(Code, Options) ->
+ case compile(Code, Options) of
+ {ok, ModuleName, Binary} ->
+ _ = code:load_binary(ModuleName, "", Binary),
+ {ok, Binary};
+ Other -> Other
+ end.
+
+
+%% ------------------------------------------------------------------------
+%% Utility functions
+
+
+-spec var(atom()) -> tree().
+
+%% @doc Create a variable.
+
+var(Name) ->
+ erl_syntax:variable(Name).
+
+
+-spec term(term()) -> tree().
+
+%% @doc Create a syntax tree for a constant term.
+
+term(Term) ->
+ erl_syntax:abstract(Term).
+
+
+%% @doc Pretty-print a syntax tree or template to the standard output. This
+%% is a utility function for development and debugging.
+
+print(Ts) when is_list(Ts) ->
+ lists:foreach(fun print/1, Ts);
+print(T) ->
+ io:put_chars(erl_prettypr:format(tree(T))),
+ io:nl().
+
+%% @doc Print the structure of a syntax tree or template to the standard
+%% output. This is a utility function for development and debugging.
+
+show(Ts) when is_list(Ts) ->
+ lists:foreach(fun show/1, Ts);
+show(T) ->
+ io:put_chars(pp(tree(T), 0)),
+ io:nl().
+
+pp(T, I) ->
+ [lists:duplicate(I, $\s),
+ limit(lists:flatten([atom_to_list(type(T)), ": ",
+ erl_prettypr:format(erl_syntax_lib:limit(T,3))]),
+ 79-I),
+ $\n,
+ pp_1(lists:filter(fun (X) -> X =/= [] end, subtrees(T)), I+2)
+ ].
+
+pp_1([G], I) ->
+ pp_2(G, I);
+pp_1([G | Gs], I) ->
+ [pp_2(G, I), lists:duplicate(I, $\s), "+\n" | pp_1(Gs, I)];
+pp_1([], _I) ->
+ [].
+
+pp_2(G, I) ->
+ [pp(E, I) || E <- G].
+
+%% limit string to N characters, stay on a single line and compact whitespace
+limit([$\n | Cs], N) -> limit([$\s | Cs], N);
+limit([$\r | Cs], N) -> limit([$\s | Cs], N);
+limit([$\v | Cs], N) -> limit([$\s | Cs], N);
+limit([$\t | Cs], N) -> limit([$\s | Cs], N);
+limit([$\s, $\s | Cs], N) -> limit([$\s | Cs], N);
+limit([C | Cs], N) when C < 32 -> limit(Cs, N);
+limit([C | Cs], N) when N > 3 -> [C | limit(Cs, N-1)];
+limit([_C1, _C2, _C3, _C4 | _Cs], 3) -> "...";
+limit(Cs, 3) -> Cs;
+limit([_C1, _C2, _C3 | _], 2) -> "..";
+limit(Cs, 2) -> Cs;
+limit([_C1, _C2 | _], 1) -> ".";
+limit(Cs, 1) -> Cs;
+limit(_, _) -> [].
+
+%% ------------------------------------------------------------------------
+%% Parsing and instantiating code fragments
+
+
+-spec qquote(Text::text(), Env::env()) -> tree_or_trees().
+
+%% @doc Parse text and substitute meta-variables.
+%%
+%% @equiv qquote(1, Text, Env)
+
+qquote(Text, Env) ->
+ qquote(1, Text, Env).
+
+
+-spec qquote(StartPos::location(), Text::text(), Env::env()) -> tree_or_trees().
+
+%% @doc Parse text and substitute meta-variables. Takes an initial scanner
+%% starting position as first argument.
+%%
+%% The macro `?Q(Text, Env)' expands to `merl:qquote(?LINE, Text, Env)'.
+%%
+%% @see quote/2
+
+qquote(StartPos, Text, Env) ->
+ subst(quote(StartPos, Text), Env).
+
+
+-spec quote(Text::text()) -> tree_or_trees().
+
+%% @doc Parse text.
+%%
+%% @equiv quote(1, Text)
+
+quote(Text) ->
+ quote(1, Text).
+
+
+-spec quote(StartPos::location(), Text::text()) -> tree_or_trees().
+
+%% @doc Parse text. Takes an initial scanner starting position as first
+%% argument.
+%%
+%% The macro `?Q(Text)' expands to `merl:quote(?LINE, Text, Env)'.
+%%
+%% @see quote/1
+
+quote({Line, Col}, Text)
+ when is_integer(Line), is_integer(Col) ->
+ quote_1(Line, Col, Text);
+quote(StartPos, Text) when is_integer(StartPos) ->
+ quote_1(StartPos, undefined, Text).
+
+quote_1(StartLine, StartCol, Text) ->
+ %% be backwards compatible as far as R12, ignoring any starting column
+ StartPos = case erlang:system_info(version) of
+ "5.6" ++ _ -> StartLine;
+ "5.7" ++ _ -> StartLine;
+ "5.8" ++ _ -> StartLine;
+ _ when StartCol =:= undefined -> StartLine;
+ _ -> {StartLine, StartCol}
+ end,
+ FlatText = flatten_text(Text),
+ {ok, Ts, _} = erl_scan:string(FlatText, StartPos),
+ merge_comments(StartLine, erl_comment_scan:string(FlatText), parse_1(Ts)).
+
+parse_1(Ts) ->
+ %% if dot tokens are present, it is assumed that the text represents
+ %% complete forms, not dot-terminated expressions or similar
+ case split_forms(Ts) of
+ {ok, Fs} -> parse_forms(Fs);
+ error ->
+ parse_2(Ts)
+ end.
+
+split_forms(Ts) ->
+ split_forms(Ts, [], []).
+
+split_forms([{dot,_}=T|Ts], Fs, As) ->
+ split_forms(Ts, [lists:reverse(As, [T]) | Fs], []);
+split_forms([T|Ts], Fs, As) ->
+ split_forms(Ts, Fs, [T|As]);
+split_forms([], Fs, []) ->
+ {ok, lists:reverse(Fs)};
+split_forms([], [], _) ->
+ error; % no dot tokens found - not representing form(s)
+split_forms([], _, [T|_]) ->
+ fail("incomplete form after ~p", [T]).
+
+parse_forms([Ts | Tss]) ->
+ case erl_parse:parse_form(Ts) of
+ {ok, Form} -> [Form | parse_forms(Tss)];
+ {error, R} -> parse_error(R)
+ end;
+parse_forms([]) ->
+ [].
+
+parse_2(Ts) ->
+ %% one or more comma-separated expressions?
+ %% (recall that Ts has no dot tokens if we get to this stage)
+ case erl_parse:parse_exprs(Ts ++ [{dot,0}]) of
+ {ok, Exprs} -> Exprs;
+ {error, E} ->
+ parse_3(Ts ++ [{'end',0}, {dot,0}], [E])
+ end.
+
+parse_3(Ts, Es) ->
+ %% try-clause or clauses?
+ case erl_parse:parse_exprs([{'try',0}, {atom,0,true}, {'catch',0} | Ts]) of
+ {ok, [{'try',_,_,_,_,_}=X]} ->
+ %% get the right kind of qualifiers in the clause patterns
+ erl_syntax:try_expr_handlers(X);
+ {error, E} ->
+ parse_4(Ts, [E|Es])
+ end.
+
+parse_4(Ts, Es) ->
+ %% fun-clause or clauses? (`(a)' is also a pattern, but `(a,b)' isn't,
+ %% so fun-clauses must be tried before normal case-clauses
+ case erl_parse:parse_exprs([{'fun',0} | Ts]) of
+ {ok, [{'fun',_,{clauses,Cs}}]} -> Cs;
+ {error, E} ->
+ parse_5(Ts, [E|Es])
+ end.
+
+parse_5(Ts, Es) ->
+ %% case-clause or clauses?
+ case erl_parse:parse_exprs([{'case',0}, {atom,0,true}, {'of',0} | Ts]) of
+ {ok, [{'case',_,_,Cs}]} -> Cs;
+ {error, E} ->
+ %% select the best error to report
+ parse_error(lists:last(lists:sort([E|Es])))
+ end.
+
+-dialyzer({nowarn_function, parse_error/1}). % no local return
+
+parse_error({L, M, R}) when is_atom(M), is_integer(L) ->
+ fail("~w: ~s", [L, M:format_error(R)]);
+parse_error({{L,C}, M, R}) when is_atom(M), is_integer(L), is_integer(C) ->
+ fail("~w:~w: ~s", [L,C,M:format_error(R)]);
+parse_error({_, M, R}) when is_atom(M) ->
+ fail(M:format_error(R));
+parse_error(R) ->
+ fail("unknown parse error: ~p", [R]).
+
+%% ------------------------------------------------------------------------
+%% Templates, substitution and matching
+
+%% Leaves are normal syntax trees, and inner nodes are tuples
+%% {template,Type,Attrs,Groups} where Groups are lists of lists of nodes.
+%% Metavariables are 1-tuples {VarName}, where VarName is an atom or an
+%% integer. {'_'} and {0} work as anonymous variables in matching. Glob
+%% metavariables are tuples {'*',VarName}, and {'*','_'} and {'*',0} are
+%% anonymous globs.
+
+%% Note that although template() :: tree() | ..., it is implied that these
+%% syntax trees are free from metavariables, so pattern() :: tree() |
+%% template() is in fact a wider type than template().
+
+-type template() :: tree()
+ | {id()}
+ | {'*',id()}
+ | {template, atom(), term(), [[template()]]}.
+
+-type template_or_templates() :: template() | [template()].
+
+-spec template(pattern_or_patterns()) -> template_or_templates().
+
+%% @doc Turn a syntax tree or list of trees into a template or templates.
+%% Templates can be instantiated or matched against, and reverted back to
+%% normal syntax trees using {@link tree/1}. If the input is already a
+%% template, it is not modified further.
+%%
+%% @see subst/2
+%% @see match/2
+%% @see tree/1
+
+template(Trees) when is_list(Trees) ->
+ [template_0(T) || T <- Trees];
+template(Tree) ->
+ template_0(Tree).
+
+template_0({template, _, _, _}=Template) -> Template;
+template_0({'*',_}=Template) -> Template;
+template_0({_}=Template) -> Template;
+template_0(Tree) ->
+ case template_1(Tree) of
+ false -> Tree;
+ {Name} when is_list(Name) ->
+ fail("bad metavariable: '~s'", [tl(Name)]); % drop v/n from name
+ Template -> Template
+ end.
+
+%% returns either a template or a lifted metavariable {String}, or 'false'
+%% if Tree contained no metavariables
+template_1(Tree) ->
+ case subtrees(Tree) of
+ [] ->
+ case metavar(Tree) of
+ {"v_"++Cs}=V when Cs =/= [] -> V; % to be lifted
+ {"n0"++Cs}=V when Cs =/= [] -> V; % to be lifted
+ {"v@"++Cs} when Cs =/= [] -> {'*',list_to_atom(Cs)};
+ {"n9"++Cs} when Cs =/= [] -> {'*',list_to_integer(Cs)};
+ {"v"++Cs} -> {list_to_atom(Cs)};
+ {"n"++Cs} -> {list_to_integer(Cs)};
+ false -> false
+ end;
+ Gs ->
+ case template_2(Gs, [], false) of
+ Gs1 when is_list(Gs1) ->
+ {template, type(Tree), erl_syntax:get_attrs(Tree), Gs1};
+ Other ->
+ Other
+ end
+ end.
+
+template_2([G | Gs], As, Bool) ->
+ case template_3(G, [], false) of
+ {"v_"++Cs}=V when Cs =/= [] -> V; % lift further
+ {"n0"++Cs}=V when Cs =/= [] -> V; % lift further
+ {"v@"++Cs} when Cs =/= [] -> {'*',list_to_atom(Cs)}; % stop
+ {"n9"++Cs} when Cs =/= [] -> {'*',list_to_integer(Cs)}; % stop
+ {"v"++Cs} when is_list(Cs) -> {list_to_atom(Cs)}; % stop
+ {"n"++Cs} when is_list(Cs) -> {list_to_integer(Cs)}; % stop
+ false -> template_2(Gs, [G | As], Bool);
+ G1 -> template_2(Gs, [G1 | As], true)
+ end;
+template_2([], _As, false) -> false;
+template_2([], As, true) -> lists:reverse(As).
+
+template_3([T | Ts], As, Bool) ->
+ case template_1(T) of
+ {"v_"++Cs} when Cs =/= [] -> {"v"++Cs}; % lift
+ {"n0"++Cs} when Cs =/= [] -> {"n"++Cs}; % lift
+ false -> template_3(Ts, [T | As], Bool);
+ T1 -> template_3(Ts, [T1 | As], true)
+ end;
+template_3([], _As, false) -> false;
+template_3([], As, true) -> lists:reverse(As).
+
+
+%% @doc Turn a template into a syntax tree representing the template.
+%% Meta-variables in the template are turned into normal Erlang variables if
+%% their names (after the metavariable prefix characters) begin with an
+%% uppercase character. E.g., `_@Foo' in the template becomes the variable
+%% `Foo' in the meta-template. Furthermore, variables ending with `@' are
+%% automatically wrapped in a call to merl:term/1, so e.g. `_@Foo@ in the
+%% template becomes `merl:term(Foo)' in the meta-template.
+
+-spec meta_template(template_or_templates()) -> tree_or_trees().
+
+meta_template(Templates) when is_list(Templates) ->
+ [meta_template_1(T) || T <- Templates];
+meta_template(Template) ->
+ meta_template_1(Template).
+
+meta_template_1({template, Type, Attrs, Groups}) ->
+ erl_syntax:tuple(
+ [erl_syntax:atom(template),
+ erl_syntax:atom(Type),
+ erl_syntax:abstract(Attrs),
+ erl_syntax:list([erl_syntax:list([meta_template_1(T) || T <- G])
+ || G <- Groups])]);
+meta_template_1({Var}=V) ->
+ meta_template_2(Var, V);
+meta_template_1({'*',Var}=V) ->
+ meta_template_2(Var, V);
+meta_template_1(Leaf) ->
+ erl_syntax:abstract(Leaf).
+
+meta_template_2(Var, V) when is_atom(Var) ->
+ case atom_to_list(Var) of
+ [C|_]=Name when C >= $A, C =< $Z ; C >= $À, C =< $Þ, C /= $× ->
+ case lists:reverse(Name) of
+ "@"++([_|_]=RevRealName) -> % don't allow empty RealName
+ RealName = lists:reverse(RevRealName),
+ erl_syntax:application(erl_syntax:atom(merl),
+ erl_syntax:atom(term),
+ [erl_syntax:variable(RealName)]);
+ _ ->
+ %% plain automatic metavariable
+ erl_syntax:variable(Name)
+ end;
+ _ ->
+ erl_syntax:abstract(V)
+ end;
+meta_template_2(Var, V) when is_integer(Var) ->
+ if Var > 9, (Var rem 10) =:= 9 ->
+ %% at least 2 digits, ends in 9: make it a Q-variable
+ if Var > 99, (Var rem 100) =:= 99 ->
+ %% at least 3 digits, ends in 99: wrap in merl:term/1
+ Name = "Q" ++ integer_to_list(Var div 100),
+ erl_syntax:application(erl_syntax:atom(merl),
+ erl_syntax:atom(term),
+ [erl_syntax:variable(Name)]);
+ true ->
+ %% plain automatic Q-variable
+ Name = integer_to_list(Var div 10),
+ erl_syntax:variable("Q" ++ Name)
+ end;
+ true ->
+ erl_syntax:abstract(V)
+ end.
+
+
+
+-spec template_vars(template_or_templates()) -> [id()].
+
+%% @doc Return an ordered list of the metavariables in the template.
+
+template_vars(Template) ->
+ template_vars(Template, []).
+
+template_vars(Templates, Vars) when is_list(Templates) ->
+ lists:foldl(fun template_vars_1/2, Vars, Templates);
+template_vars(Template, Vars) ->
+ template_vars_1(Template, Vars).
+
+template_vars_1({template, _, _, Groups}, Vars) ->
+ lists:foldl(fun (G, V) -> lists:foldl(fun template_vars_1/2, V, G) end,
+ Vars, Groups);
+template_vars_1({Var}, Vars) ->
+ ordsets:add_element(Var, Vars);
+template_vars_1({'*',Var}, Vars) ->
+ ordsets:add_element(Var, Vars);
+template_vars_1(_, Vars) ->
+ Vars.
+
+
+-spec tree(template_or_templates()) -> tree_or_trees().
+
+%% @doc Revert a template to a normal syntax tree. Any remaining
+%% metavariables are turned into `@'-prefixed atoms or `909'-prefixed
+%% integers.
+%% @see template/1
+
+tree(Templates) when is_list(Templates) ->
+ [tree_1(T) || T <- Templates];
+tree(Template) ->
+ tree_1(Template).
+
+tree_1({template, Type, Attrs, Groups}) ->
+ %% flattening here is needed for templates created via source transforms
+ Gs = [lists:flatten([tree_1(T) || T <- G]) || G <- Groups],
+ erl_syntax:set_attrs(make_tree(Type, Gs), Attrs);
+tree_1({Var}) when is_atom(Var) ->
+ erl_syntax:atom(list_to_atom("@"++atom_to_list(Var)));
+tree_1({Var}) when is_integer(Var) ->
+ erl_syntax:integer(list_to_integer("909"++integer_to_list(Var)));
+tree_1({'*',Var}) when is_atom(Var) ->
+ erl_syntax:atom(list_to_atom("@@"++atom_to_list(Var)));
+tree_1({'*',Var}) when is_integer(Var) ->
+ erl_syntax:integer(list_to_integer("9099"++integer_to_list(Var)));
+tree_1(Leaf) ->
+ Leaf. % any syntax tree, not necessarily atomic (due to substitutions)
+
+
+-spec subst(pattern_or_patterns(), env()) -> tree_or_trees().
+
+%% @doc Substitute metavariables in a pattern or list of patterns, yielding
+%% a syntax tree or list of trees as result. Both for normal metavariables
+%% and glob metavariables, the substituted value may be a single element or
+%% a list of elements. For example, if a list representing `1, 2, 3' is
+%% substituted for `var' in either of `[foo, _@var, bar]' or `[foo, _@@var,
+%% bar]', the result represents `[foo, 1, 2, 3, bar]'.
+
+subst(Trees, Env) when is_list(Trees) ->
+ [subst_0(T, Env) || T <- Trees];
+subst(Tree, Env) ->
+ subst_0(Tree, Env).
+
+subst_0(Tree, Env) ->
+ tree_1(subst_1(template(Tree), Env)).
+
+
+-spec tsubst(pattern_or_patterns(), env()) -> template_or_templates().
+
+%% @doc Like subst/2, but does not convert the result from a template back
+%% to a tree. Useful if you want to do multiple separate substitutions.
+%% @see subst/2
+%% @see tree/1
+
+tsubst(Trees, Env) when is_list(Trees) ->
+ [subst_1(template(T), Env) || T <- Trees];
+tsubst(Tree, Env) ->
+ subst_1(template(Tree), Env).
+
+subst_1({template, Type, Attrs, Groups}, Env) ->
+ Gs1 = [lists:flatten([subst_1(T, Env) || T <- G]) || G <- Groups],
+ {template, Type, Attrs, Gs1};
+subst_1({Var}=V, Env) ->
+ case lists:keyfind(Var, 1, Env) of
+ {Var, TreeOrTrees} -> TreeOrTrees;
+ false -> V
+ end;
+subst_1({'*',Var}=V, Env) ->
+ case lists:keyfind(Var, 1, Env) of
+ {Var, TreeOrTrees} -> TreeOrTrees;
+ false -> V
+ end;
+subst_1(Leaf, _Env) ->
+ Leaf.
+
+
+-spec alpha(pattern_or_patterns(), [{id(), id()}]) -> template_or_templates().
+
+%% @doc Alpha converts a pattern (renames variables). Similar to tsubst/1,
+%% but only renames variables (including globs).
+%% @see tsubst/2
+
+alpha(Trees, Env) when is_list(Trees) ->
+ [alpha_1(template(T), Env) || T <- Trees];
+alpha(Tree, Env) ->
+ alpha_1(template(Tree), Env).
+
+alpha_1({template, Type, Attrs, Groups}, Env) ->
+ Gs1 = [lists:flatten([alpha_1(T, Env) || T <- G]) || G <- Groups],
+ {template, Type, Attrs, Gs1};
+alpha_1({Var}=V, Env) ->
+ case lists:keyfind(Var, 1, Env) of
+ {Var, NewVar} -> {NewVar};
+ false -> V
+ end;
+alpha_1({'*',Var}=V, Env) ->
+ case lists:keyfind(Var, 1, Env) of
+ {Var, NewVar} -> {'*',NewVar};
+ false -> V
+ end;
+alpha_1(Leaf, _Env) ->
+ Leaf.
+
+
+-spec match(pattern_or_patterns(), tree_or_trees()) ->
+ {ok, env()} | error.
+
+%% @doc Match a pattern against a syntax tree (or patterns against syntax
+%% trees) returning an environment mapping variable names to subtrees; the
+%% environment is always sorted on keys. Note that multiple occurrences of
+%% metavariables in the pattern is not allowed, but is not checked.
+%%
+%% @see template/1
+%% @see switch/2
+
+match(Patterns, Trees) when is_list(Patterns), is_list(Trees) ->
+ try {ok, match_1(Patterns, Trees, [])}
+ catch
+ error -> error
+ end;
+match(Patterns, Tree) when is_list(Patterns) -> match(Patterns, [Tree]);
+match(Pattern, Trees) when is_list(Trees) -> match([Pattern], Trees);
+match(Pattern, Tree) ->
+ try {ok, match_template(template(Pattern), Tree, [])}
+ catch
+ error -> error
+ end.
+
+match_1([P|Ps], [T | Ts], Dict) ->
+ match_1(Ps, Ts, match_template(template(P), T, Dict));
+match_1([], [], Dict) ->
+ Dict;
+match_1(_, _, _Dict) ->
+ erlang:error(merl_match_arity).
+
+%% match a template against a syntax tree
+match_template({template, Type, _, Gs}, Tree, Dict) ->
+ case type(Tree) of
+ Type -> match_template_1(Gs, subtrees(Tree), Dict);
+ _ -> throw(error) % type mismatch
+ end;
+match_template({Var}, _Tree, Dict)
+ when Var =:= '_' ; Var =:= 0 ->
+ Dict; % anonymous variable
+match_template({Var}, Tree, Dict) ->
+ orddict:store(Var, Tree, Dict);
+match_template(Tree1, Tree2, Dict) ->
+ %% if Tree1 is not a template, Tree1 and Tree2 are both syntax trees
+ case compare_trees(Tree1, Tree2) of
+ true -> Dict;
+ false -> throw(error) % different trees
+ end.
+
+match_template_1([G1 | Gs1], [G2 | Gs2], Dict) ->
+ match_template_2(G1, G2, match_template_1(Gs1, Gs2, Dict));
+match_template_1([], [], Dict) ->
+ Dict;
+match_template_1(_, _, _Dict) ->
+ throw(error). % shape mismatch
+
+match_template_2([{Var} | Ts1], [_ | Ts2], Dict)
+ when Var =:= '_' ; Var =:= 0 ->
+ match_template_2(Ts1, Ts2, Dict); % anonymous variable
+match_template_2([{Var} | Ts1], [Tree | Ts2], Dict) ->
+ match_template_2(Ts1, Ts2, orddict:store(Var, Tree, Dict));
+match_template_2([{'*',Var} | Ts1], Ts2, Dict) ->
+ match_glob(lists:reverse(Ts1), lists:reverse(Ts2), Var, Dict);
+match_template_2([T1 | Ts1], [T2 | Ts2], Dict) ->
+ match_template_2(Ts1, Ts2, match_template(T1, T2, Dict));
+match_template_2([], [], Dict) ->
+ Dict;
+match_template_2(_, _, _Dict) ->
+ throw(error). % shape mismatch
+
+%% match the tails in reverse order; no further globs allowed
+match_glob([{'*',Var} | _], _, _, _) ->
+ fail("multiple glob variables in same match group: ~w", [Var]);
+match_glob([T1 | Ts1], [T2 | Ts2], Var, Dict) ->
+ match_glob(Ts1, Ts2, Var, match_template(T1, T2, Dict));
+match_glob([], _Group, Var, Dict) when Var =:= '_' ; Var =:= 0 ->
+ Dict; % anonymous glob variable
+match_glob([], Group, Var, Dict) ->
+ orddict:store(Var, lists:reverse(Group), Dict);
+match_glob(_, _, _, _Dict) ->
+ throw(error). % shape mismatch
+
+
+%% compare two syntax trees for equivalence
+compare_trees(T1, T2) ->
+ Type1 = type(T1),
+ case type(T2) of
+ Type1 ->
+ case subtrees(T1) of
+ [] ->
+ case subtrees(T2) of
+ [] -> compare_leaves(Type1, T1, T2);
+ _Gs2 -> false % shape mismatch
+ end;
+ Gs1 ->
+ case subtrees(T2) of
+ [] -> false; % shape mismatch
+ Gs2 -> compare_trees_1(Gs1, Gs2)
+ end
+ end;
+ _Type2 ->
+ false % different tree types
+ end.
+
+compare_trees_1([G1 | Gs1], [G2 | Gs2]) ->
+ compare_trees_2(G1, G2) andalso compare_trees_1(Gs1, Gs2);
+compare_trees_1([], []) ->
+ true;
+compare_trees_1(_, _) ->
+ false. % shape mismatch
+
+compare_trees_2([T1 | Ts1], [T2 | Ts2]) ->
+ compare_trees(T1, T2) andalso compare_trees_2(Ts1, Ts2);
+compare_trees_2([], []) ->
+ true;
+compare_trees_2(_, _) ->
+ false. % shape mismatch
+
+compare_leaves(Type, T1, T2) ->
+ case Type of
+ atom ->
+ erl_syntax:atom_value(T1)
+ =:= erl_syntax:atom_value(T2);
+ char ->
+ erl_syntax:char_value(T1)
+ =:= erl_syntax:char_value(T2);
+ float ->
+ erl_syntax:float_value(T1)
+ =:= erl_syntax:float_value(T2);
+ integer ->
+ erl_syntax:integer_value(T1)
+ =:= erl_syntax:integer_value(T2);
+ string ->
+ erl_syntax:string_value(T1)
+ =:= erl_syntax:string_value(T2);
+ operator ->
+ erl_syntax:operator_name(T1)
+ =:= erl_syntax:operator_name(T2);
+ text ->
+ erl_syntax:text_string(T1)
+ =:= erl_syntax:text_string(T2);
+ variable ->
+ erl_syntax:variable_name(T1)
+ =:= erl_syntax:variable_name(T2);
+ _ ->
+ true % trivially equal nodes
+ end.
+
+
+%% @doc Match against one or more clauses with patterns and optional guards.
+%%
+%% Note that clauses following a default action will be ignored.
+%%
+%% @see match/2
+
+-type switch_clause() ::
+ {pattern_or_patterns(), guarded_actions()}
+ | {pattern_or_patterns(), guard_test(), switch_action()}
+ | default_action().
+
+-type guarded_actions() :: guarded_action() | [guarded_action()].
+
+-type guarded_action() :: switch_action() | {guard_test(), switch_action()}.
+
+-type switch_action() :: fun( (env()) -> any() ).
+
+-type guard_test() :: fun( (env()) -> boolean() ).
+
+-type default_action() :: fun( () -> any() ).
+
+
+-spec switch(tree_or_trees(), [switch_clause()]) -> any().
+
+switch(Trees, [{Patterns, GuardedActions} | Cs]) when is_list(GuardedActions) ->
+ switch_1(Trees, Patterns, GuardedActions, Cs);
+switch(Trees, [{Patterns, GuardedAction} | Cs]) ->
+ switch_1(Trees, Patterns, [GuardedAction], Cs);
+switch(Trees, [{Patterns, Guard, Action} | Cs]) ->
+ switch_1(Trees, Patterns, [{Guard, Action}], Cs);
+switch(_Trees, [Default | _Cs]) when is_function(Default, 0) ->
+ Default();
+switch(_Trees, []) ->
+ erlang:error(merl_switch_clause);
+switch(_Tree, _) ->
+ erlang:error(merl_switch_badarg).
+
+switch_1(Trees, Patterns, GuardedActions, Cs) ->
+ case match(Patterns, Trees) of
+ {ok, Env} ->
+ switch_2(Env, GuardedActions, Trees, Cs);
+ error ->
+ switch(Trees, Cs)
+ end.
+
+switch_2(Env, [{Guard, Action} | Bs], Trees, Cs)
+ when is_function(Guard, 1), is_function(Action, 1) ->
+ case Guard(Env) of
+ true -> Action(Env);
+ false -> switch_2(Env, Bs, Trees, Cs)
+ end;
+switch_2(Env, [Action | _Bs], _Trees, _Cs) when is_function(Action, 1) ->
+ Action(Env);
+switch_2(_Env, [], Trees, Cs) ->
+ switch(Trees, Cs);
+switch_2(_Env, _, _Trees, _Cs) ->
+ erlang:error(merl_switch_badarg).
+
+
+%% ------------------------------------------------------------------------
+%% Internal utility functions
+
+-dialyzer({nowarn_function, fail/1}). % no local return
+
+fail(Text) ->
+ fail(Text, []).
+
+fail(Fs, As) ->
+ throw({error, lists:flatten(io_lib:format(Fs, As))}).
+
+flatten_text([L | _]=Lines) when is_list(L) ->
+ lists:foldr(fun(S, T) -> S ++ [$\n | T] end, "", Lines);
+flatten_text([B | _]=Lines) when is_binary(B) ->
+ lists:foldr(fun(S, T) -> binary_to_list(S) ++ [$\n | T] end, "", Lines);
+flatten_text(Text) when is_binary(Text) ->
+ binary_to_list(Text);
+flatten_text(Text) ->
+ Text.
+
+-spec metavar(tree()) -> {string()} | false.
+
+%% Check if a syntax tree represents a metavariable. If not, 'false' is
+%% returned; otherwise, this returns a 1-tuple with a string containing the
+%% variable name including lift/glob prefixes but without any leading
+%% metavariable prefix, and instead prefixed with "v" for a variable or "i"
+%% for an integer.
+%%
+%% Metavariables are atoms starting with @, variables starting with _@,
+%% strings starting with "'@, or integers starting with 909. Following the
+%% prefix, one or more _ or 0 characters (unless it's the last character in
+%% the name) may be used to indicate "lifting" of the variable one or more
+%% levels , and after that, a @ or 9 character indicates a glob metavariable
+%% rather than a normal metavariable. If the name after the prefix is _ or
+%% 0, the variable is treated as an anonymous catch-all pattern in matches.
+
+metavar(Tree) ->
+ case type(Tree) of
+ atom ->
+ case erl_syntax:atom_name(Tree) of
+ "@" ++ Cs when Cs =/= [] -> {"v"++Cs};
+ _ -> false
+ end;
+ variable ->
+ case erl_syntax:variable_literal(Tree) of
+ "_@" ++ Cs when Cs =/= [] -> {"v"++Cs};
+ _ -> false
+ end;
+ integer ->
+ case erl_syntax:integer_value(Tree) of
+ N when N >= 9090 ->
+ case integer_to_list(N) of
+ "909" ++ Cs -> {"n"++Cs};
+ _ -> false
+ end;
+ _ -> false
+ end;
+ string ->
+ case erl_syntax:string_value(Tree) of
+ "'@" ++ Cs -> {"v"++Cs};
+ _ -> false
+ end;
+ _ ->
+ false
+ end.
+
+%% wrappers around erl_syntax functions to provide more uniform shape of
+%% generic subtrees (maybe this can be fixed in syntax_tools one day)
+
+type(T) ->
+ case erl_syntax:type(T) of
+ nil -> list;
+ Type -> Type
+ end.
+
+subtrees(T) ->
+ case erl_syntax:type(T) of
+ tuple ->
+ [erl_syntax:tuple_elements(T)]; %% don't treat {} as a leaf
+ nil ->
+ [[], []]; %% don't treat [] as a leaf, but as a list
+ list ->
+ case erl_syntax:list_suffix(T) of
+ none ->
+ [erl_syntax:list_prefix(T), []];
+ S ->
+ [erl_syntax:list_prefix(T), [S]]
+ end;
+ binary_field ->
+ [[erl_syntax:binary_field_body(T)],
+ erl_syntax:binary_field_types(T)];
+ clause ->
+ case erl_syntax:clause_guard(T) of
+ none ->
+ [erl_syntax:clause_patterns(T), [],
+ erl_syntax:clause_body(T)];
+ G ->
+ [erl_syntax:clause_patterns(T), [G],
+ erl_syntax:clause_body(T)]
+ end;
+ receive_expr ->
+ case erl_syntax:receive_expr_timeout(T) of
+ none ->
+ [erl_syntax:receive_expr_clauses(T), [], []];
+ E ->
+ [erl_syntax:receive_expr_clauses(T), [E],
+ erl_syntax:receive_expr_action(T)]
+ end;
+ record_expr ->
+ case erl_syntax:record_expr_argument(T) of
+ none ->
+ [[], [erl_syntax:record_expr_type(T)],
+ erl_syntax:record_expr_fields(T)];
+ V ->
+ [[V], [erl_syntax:record_expr_type(T)],
+ erl_syntax:record_expr_fields(T)]
+ end;
+ record_field ->
+ case erl_syntax:record_field_value(T) of
+ none ->
+ [[erl_syntax:record_field_name(T)], []];
+ V ->
+ [[erl_syntax:record_field_name(T)], [V]]
+ end;
+ _ ->
+ erl_syntax:subtrees(T)
+ end.
+
+make_tree(list, [P, []]) -> erl_syntax:list(P);
+make_tree(list, [P, [S]]) -> erl_syntax:list(P, S);
+make_tree(tuple, [E]) -> erl_syntax:tuple(E);
+make_tree(binary_field, [[B], Ts]) -> erl_syntax:binary_field(B, Ts);
+make_tree(clause, [P, [], B]) -> erl_syntax:clause(P, none, B);
+make_tree(clause, [P, [G], B]) -> erl_syntax:clause(P, G, B);
+make_tree(receive_expr, [C, [], _A]) -> erl_syntax:receive_expr(C);
+make_tree(receive_expr, [C, [E], A]) -> erl_syntax:receive_expr(C, E, A);
+make_tree(record_expr, [[], [T], F]) -> erl_syntax:record_expr(T, F);
+make_tree(record_expr, [[E], [T], F]) -> erl_syntax:record_expr(E, T, F);
+make_tree(record_field, [[N], []]) -> erl_syntax:record_field(N);
+make_tree(record_field, [[N], [E]]) -> erl_syntax:record_field(N, E);
+make_tree(Type, Groups) ->
+ erl_syntax:make_tree(Type, Groups).
+
+merge_comments(_StartLine, [], [T]) -> T;
+merge_comments(_StartLine, [], Ts) -> Ts;
+merge_comments(StartLine, Comments, Ts) ->
+ merge_comments(StartLine, Comments, Ts, []).
+
+merge_comments(_StartLine, [], [], [T]) -> T;
+merge_comments(_StartLine, [], [T], []) -> T;
+merge_comments(_StartLine, [], Ts, Acc) ->
+ lists:reverse(Acc, Ts);
+merge_comments(StartLine, Cs, [], Acc) ->
+ merge_comments(StartLine, [], [],
+ [erl_syntax:set_pos(
+ erl_syntax:comment(Indent, Text),
+ StartLine + Line - 1)
+ || {Line, _, Indent, Text} <- Cs] ++ Acc);
+merge_comments(StartLine, [C|Cs], [T|Ts], Acc) ->
+ {Line, _Col, Indent, Text} = C,
+ CommentLine = StartLine + Line - 1,
+ case erl_syntax:get_pos(T) of
+ Pos when Pos < CommentLine ->
+ %% TODO: traverse sub-tree rather than only the top level nodes
+ merge_comments(StartLine, [C|Cs], Ts, [T|Acc]);
+ CommentLine ->
+ Tc = erl_syntax:add_postcomments(
+ [erl_syntax:comment(Indent, Text)], T),
+ merge_comments(StartLine, Cs, [Tc|Ts], Acc);
+ _ ->
+ Tc = erl_syntax:add_precomments(
+ [erl_syntax:comment(Indent, Text)], T),
+ merge_comments(StartLine, Cs, [Tc|Ts], Acc)
+ end.
diff --git a/lib/syntax_tools/src/merl_tests.erl b/lib/syntax_tools/src/merl_tests.erl
new file mode 100644
index 0000000000..c1aae3100e
--- /dev/null
+++ b/lib/syntax_tools/src/merl_tests.erl
@@ -0,0 +1,539 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012-2015 Richard Carlsson
+%% @doc Unit tests for merl.
+%% @private
+
+-module(merl_tests).
+
+%-define(MERL_NO_TRANSFORM, true).
+-include("merl.hrl").
+
+-include_lib("eunit/include/eunit.hrl").
+
+
+%% utilities
+
+f(Ts) when is_list(Ts) ->
+ lists:flatmap(fun erl_prettypr:format/1, Ts);
+f(T) ->
+ erl_prettypr:format(T).
+
+fe(Env) -> [{Key, f(T)} || {Key, T} <- Env].
+
+g_exported_() ->
+ %% for testing the parse transform, autoexported to avoid complaints
+ {ok, merl:quote(?LINE, "42")}.
+
+
+ok({ok, X}) -> X.
+
+
+%%
+%% tests
+%%
+
+parse_error_test_() ->
+ [?_assertThrow({error, "1: syntax error before: '{'" ++ _},
+ f(merl:quote("{")))
+ ].
+
+term_test_() ->
+ [?_assertEqual(tuple, erl_syntax:type(merl:term({}))),
+ ?_assertEqual("{foo, 42}", f(merl:term({foo, 42})))
+ ].
+
+quote_form_test_() ->
+ [?_assertEqual("f(X) -> {ok, X}.",
+ f(?Q("f(X) -> {ok, X}."))),
+ ?_assertEqual("-module(foo).",
+ f(?Q("-module(foo)."))),
+ ?_assertEqual("-import(bar, [f/1, g/2]).",
+ f(?Q("-import(bar, [f/1, g/2])."))),
+ ?_assertEqual(("-module(foo)."
+ "-export([f/1])."
+ "f(X) -> {ok, X}."),
+ f(?Q(["-module(foo).",
+ "-export([f/1]).",
+ "f(X) -> {ok, X}."])))
+ ].
+
+quote_term_test_() ->
+ [?_assertEqual("foo",
+ f(?Q("foo"))),
+ ?_assertEqual("42",
+ f(?Q("42"))),
+ ?_assertEqual("{foo, 42}",
+ f(?Q("{foo, 42}"))),
+ ?_assertEqual(("1" ++ "2" ++ "3"),
+ f(?Q("1, 2, 3"))),
+ ?_assertEqual(("foo" "42" "{}" "true"),
+ f(?Q("foo, 42, {}, (true)")))
+ ].
+
+quote_expr_test_() ->
+ [?_assertEqual("2 + 2",
+ f(?Q("2 + 2"))),
+ ?_assertEqual("f(foo, 42)",
+ f(?Q("f(foo, 42)"))),
+ ?_assertEqual("case X of\n a -> 1;\n b -> 2\nend",
+ f(?Q("case X of a -> 1; b -> 2 end"))),
+ ?_assertEqual(("2 + 2" ++ "f(42)" ++ "catch 22"),
+ f(?Q("2 + 2, f(42), catch 22")))
+ ].
+
+quote_try_clause_test_() ->
+ [?_assertEqual("(error:R) when R =/= foo -> ok",
+ f(?Q("error:R when R =/= foo -> ok"))),
+ %% note that without any context, clauses are printed as fun-clauses
+ ?_assertEqual(("(error:badarg) -> badarg"
+ "(exit:normal) -> normal"
+ "(_) -> other"),
+ f(?Q(["error:badarg -> badarg;",
+ "exit:normal -> normal;"
+ "_ -> other"])))
+ ].
+
+quote_fun_clause_test_() ->
+ [?_assertEqual("(X, Y) when X < Y -> {ok, X}",
+ f(?Q("(X, Y) when X < Y -> {ok, X}"))),
+ ?_assertEqual(("(X, Y) when X < Y -> less"
+ "(X, Y) when X > Y -> greater"
+ "(_, _) -> equal"),
+ f(?Q(["(X, Y) when X < Y -> less;",
+ "(X, Y) when X > Y -> greater;"
+ "(_, _) -> equal"])))].
+
+quote_case_clause_test_() ->
+ [?_assertEqual("({X, Y}) when X < Y -> X",
+ f(?Q("{X, Y} when X < Y -> X"))),
+ ?_assertEqual(("({X, Y}) when X < Y -> -1"
+ "({X, Y}) when X > Y -> 1"
+ "(_) -> 0"),
+ f(?Q(["{X, Y} when X < Y -> -1;",
+ "{X, Y} when X > Y -> 1;"
+ "_ -> 0"])))].
+
+quote_comment_test_() ->
+ [?_assertEqual("%% comment preserved\n"
+ "{foo, 42}",
+ f(?Q(["%% comment preserved",
+ "{foo, 42}"]))),
+ ?_assertEqual("{foo, 42}"
+ "%% comment preserved\n",
+ f(?Q(["{foo, 42}",
+ "%% comment preserved"]))),
+ ?_assertEqual(" % just a comment (with indent)\n",
+ f(?Q(" % just a comment (with indent)")))
+ ].
+
+metavar_test_() ->
+ [?_assertEqual("'@foo'", f(merl:tree(merl:template(?Q("'@foo'"))))),
+ ?_assertEqual("'@foo'", f(merl:tree(merl:template(?Q("_@foo"))))),
+ ?_assertEqual("'@foo'", f(merl:tree(merl:template(?Q("\"'@foo\""))))),
+ ?_assertEqual("{'@foo'}", f(merl:tree(merl:template(?Q("{_@foo}"))))),
+ ?_assertEqual("'@foo'", f(merl:tree(merl:template(?Q("{_@_foo}"))))),
+ ?_assertEqual("909123", f(merl:tree(merl:template(?Q("{9090123}"))))),
+ ?_assertEqual("{'@foo'}",
+ f(merl:tree(merl:template(?Q("{{{_@__foo}}}"))))),
+ ?_assertEqual("{909123}",
+ f(merl:tree(merl:template(?Q("{{{90900123}}}"))))),
+ ?_assertEqual("{'@@foo'}",
+ f(merl:tree(merl:template(?Q("{{{_@__@foo}}}"))))),
+ ?_assertEqual("{9099123}",
+ f(merl:tree(merl:template(?Q("{{{909009123}}}")))))
+ ].
+
+subst_test_() ->
+ [?_assertEqual("42",
+ f(merl:subst(?Q("_@foo"), [{foo, merl:term(42)}]))),
+ ?_assertEqual("'@foo'",
+ f(merl:subst(?Q("_@foo"), []))),
+ ?_assertEqual("{42}",
+ f(merl:subst(?Q("{_@foo}"),
+ [{foo, merl:term(42)}]))),
+ ?_assertEqual("{'@foo'}",
+ f(merl:subst(?Q("{_@foo}"), []))),
+ ?_assertEqual("fun bar/0",
+ f(merl:subst(merl:template(?Q("fun '@foo'/0")),
+ [{foo, merl:term(bar)}]))),
+ ?_assertEqual("fun foo/3",
+ f(merl:subst(merl:template(?Q("fun foo/9091")),
+ [{1, merl:term(3)}]))),
+ ?_assertEqual("[42]",
+ f(merl:subst(merl:template(?Q("[_@foo]")),
+ [{foo, merl:term(42)}]))),
+ ?_assertEqual("[foo, bar]",
+ f(merl:subst(merl:template(?Q("[_@foo]")),
+ [{foo, [merl:term(foo),merl:term(bar)]}]))),
+ ?_assertEqual("{fee, fie, foe, fum}",
+ f(merl:subst(merl:template(?Q("{fee, _@foo, fum}")),
+ [{foo, [merl:term(fie),merl:term(foe)]}]))),
+ ?_assertEqual("[foo, bar]",
+ f(merl:subst(merl:template(?Q("[_@@foo]")),
+ [{foo, [merl:term(foo),merl:term(bar)]}]))),
+ ?_assertEqual("{fee, fie, foe, fum}",
+ f(merl:subst(merl:template(?Q("{fee, _@@foo, fum}")),
+ [{foo, [merl:term(fie),merl:term(foe)]}]))),
+ ?_assertEqual("['@@foo']",
+ f(merl:subst(merl:template(?Q("[_@@foo]")), []))),
+ ?_assertEqual("foo",
+ f(merl:subst(merl:template(?Q("[_@_foo]")),
+ [{foo, merl:term(foo)}]))),
+ ?_assertEqual("{'@foo'}",
+ f(merl:subst(merl:template(?Q("{[_@_foo]}")), []))),
+ ?_assertEqual("{'@@foo'}",
+ f(merl:subst(merl:template(?Q("{[_@_@foo]}")), []))),
+ ?_assertEqual("-export([foo/1, bar/2]).",
+ f(merl:subst(merl:template(?Q("-export(['@_@foo'/0]).")),
+ [{foo, [erl_syntax:arity_qualifier(
+ merl:term(foo),
+ merl:term(1)),
+ erl_syntax:arity_qualifier(
+ merl:term(bar),
+ merl:term(2))
+ ]}
+ ])))
+ ].
+
+match_test_() ->
+ [?_assertEqual({ok, []}, merl:match(?Q("foo"), ?Q("foo"))),
+ ?_assertEqual(error, merl:match(?Q("foo"), ?Q("bar"))),
+ ?_assertEqual({ok,[]}, merl:match(?Q("{foo,42}"), ?Q("{foo,42}"))),
+ ?_assertEqual(error, merl:match(?Q("{foo,42}"), ?Q("{foo,bar}"))),
+ ?_assertEqual({ok,[]}, merl:match(?Q("[foo,[42]]"), ?Q("[foo,[42]]"))),
+ ?_assertEqual(error, merl:match(?Q("[foo,[42]]"), ?Q("[foo,{42}]"))),
+ ?_assertEqual({ok,[]}, merl:match(?Q("[foo,[_@_]]"),
+ ?Q("[foo,[42]]"))),
+ ?_assertEqual({ok,[]}, merl:match(?Q("[foo,[9090]]"),
+ ?Q("[foo,[42]]"))),
+ ?_assertEqual({ok,[]}, merl:match(?Q("{_@_,[_@_,2]}"),
+ ?Q("{foo,[1,2]}"))),
+ ?_assertEqual(error, merl:match(?Q("{_@_,[_@_,2]}"),
+ ?Q("{foo,[1,3]}"))),
+ ?_assertEqual({ok,[]}, merl:match(?Q("[foo,[9090,9090]]"),
+ ?Q("[foo,[1,2]]"))),
+ ?_assertEqual(error, merl:match(?Q("[foo,[9090,9090]]"),
+ ?Q("[foo,[1,2,3]]"))),
+ ?_assertEqual([{foo,"42"}],
+ fe(ok(merl:match(?Q("_@foo"), ?Q("42"))))),
+ ?_assertEqual([{foo,"42"}],
+ fe(ok(merl:match(?Q("{_@foo}"), ?Q("{42}"))))),
+ ?_assertEqual([{1,"0"},{foo,"bar"}],
+ fe(ok(merl:match(?Q("fun '@foo'/9091"),
+ ?Q("fun bar/0"))))),
+ ?_assertEqual([{line,"17"},{text,"\"hello\""}],
+ fe(ok(merl:match(?Q("{_@line, _@text}"),
+ ?Q("{17, \"hello\"}"))))),
+ ?_assertEqual([{line,"17"},{text,"\"hello\""}],
+ fe(ok(merl:match(?Q("foo(_@line, _@text)"),
+ ?Q("foo(17, \"hello\")"))))),
+ ?_assertEqual([{foo,""}],
+ fe(ok(merl:match(?Q("f(_@@foo)"),
+ ?Q("f()"))))),
+ ?_assertEqual([{foo,"fee"}],
+ fe(ok(merl:match(?Q("f(_@@foo)"),
+ ?Q("f(fee)"))))),
+ ?_assertEqual([{foo,"feefiefum"}],
+ fe(ok(merl:match(?Q("f(_@@foo)"),
+ ?Q("f(fee, fie, fum)"))))),
+ ?_assertEqual([{foo,""}],
+ fe(ok(merl:match(?Q("[_@@foo]"),
+ ?Q("[]"))))),
+ ?_assertEqual([{foo,"fee"}],
+ fe(ok(merl:match(?Q("[_@@foo]"),
+ ?Q("[fee]"))))),
+ ?_assertEqual([{foo,"feefiefoefum"}],
+ fe(ok(merl:match(?Q("[_@@foo]"),
+ ?Q("[fee, fie, foe, fum]"))))),
+ ?_assertEqual([{foo,""}],
+ fe(ok(merl:match(?Q("{_@@foo}"),
+ ?Q("{}"))))),
+ ?_assertEqual([{foo,"fee"}],
+ fe(ok(merl:match(?Q("{_@@foo}"),
+ ?Q("{fee}"))))),
+ ?_assertEqual([{foo,"feefiefoefum"}],
+ fe(ok(merl:match(?Q("{_@@foo}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([{foo,"fie"}],
+ fe(ok(merl:match(?Q("{fee, _@@foo}"),
+ ?Q("{fee, fie}"))))),
+ ?_assertEqual([{foo,"fiefoefum"}],
+ fe(ok(merl:match(?Q("{fee, _@@foo}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([{foo,"fie"}],
+ fe(ok(merl:match(?Q("{_@@foo, foe, fum}"),
+ ?Q("{fie, foe, fum}"))))),
+ ?_assertEqual([{foo,"feefie"}],
+ fe(ok(merl:match(?Q("{_@@foo, foe, fum}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([{foo,"fie"}],
+ fe(ok(merl:match(?Q("{fee, _@@foo, fum}"),
+ ?Q("{fee, fie, fum}"))))),
+ ?_assertEqual([{foo,"fiefoe"}],
+ fe(ok(merl:match(?Q("{fee, _@@foo, fum}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([{foo,"fiefoe"},{post,"fum"},{pre,"fee"}],
+ fe(ok(merl:match(?Q("{_@pre, _@@foo, _@post}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertThrow({error, "multiple glob variables"++_},
+ fe(ok(merl:match(?Q("{_@@foo, _@@bar}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([],
+ fe(ok(merl:match(?Q("{fee, _@@_}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([],
+ fe(ok(merl:match(?Q("{_@@_, foe, fum}"),
+ ?Q("{fee, fie, foe, fum}"))))),
+ ?_assertEqual([{post,"fum"},{pre,"fee"}],
+ fe(ok(merl:match(?Q("{_@pre, _@@_, _@post}"),
+ ?Q("{fee, fie, foe, fum}")))))
+ ].
+
+switch_test_() ->
+ [?_assertEqual(42, merl:switch(?Q("foo"), [fun () -> 42 end])),
+ ?_assertEqual(17, merl:switch(?Q("foo"), [fun () -> 17 end,
+ fun () -> 42 end])),
+ ?_assertEqual(17, merl:switch(?Q("foo"), [{?Q("foo"),
+ fun ([]) -> 17 end},
+ fun () -> 42 end])),
+ ?_assertEqual(17,
+ merl:switch(?Q("foo"), [{?Q("bar"), fun ([]) -> 0 end},
+ {?Q("foo"), fun ([]) -> 17 end},
+ fun () -> 42 end])),
+ ?_assertEqual([{foo,"17"}],
+ merl:switch(?Q("{foo,17}"),
+ [{?Q("{bar, _@foo}"), fun (_) -> 0 end},
+ {?Q("{foo, _@foo}"), fun fe/1},
+ fun () -> 42 end])),
+ ?_assertEqual(17,
+ merl:switch(?Q("{foo, 17}"),
+ [{?Q("{foo, _@foo}"),
+ fun ([{foo, X}]) -> f(X) =:= "17" end,
+ fun (_) -> 17 end},
+ fun () -> 42 end])),
+ ?_assertEqual([{foo,"17"}],
+ merl:switch(?Q("{foo, 17}"),
+ [{?Q("{foo, _@foo}"),
+ fun ([{foo, X}]) -> f(X) =:= "42" end,
+ fun (_) -> 0 end},
+ {?Q("{foo, _@foo}"), fun fe/1},
+ fun () -> 42 end])),
+ ?_assertEqual(17,
+ merl:switch(?Q("{foo, 17}"),
+ [{?Q("{foo, _@foo}"),
+ [{fun ([{foo, X}]) -> f(X) =:= "17" end,
+ fun (_) -> 17 end},
+ fun (_) -> 0 end]},
+ fun () -> 42 end])),
+ ?_assertEqual([{foo,"17"}],
+ merl:switch(?Q("{foo, 17}"),
+ [{?Q("{foo, _@foo}"),
+ [{fun ([{foo, X}]) -> f(X) =:= "42" end,
+ fun (_) -> 0 end},
+ fun fe/1]},
+ fun () -> 42 end]))
+ ].
+
+-ifndef(MERL_NO_TRANSFORM).
+
+inline_meta_test_() ->
+ [?_assertEqual("{foo}",
+ f(begin
+ Foo = ?Q("foo"),
+ ?Q("{_@Foo}")
+ end)),
+ ?_assertEqual("{foo, '@bar'}",
+ f(begin
+ Foo = ?Q("foo"),
+ ?Q("{_@Foo,_@bar}")
+ end)),
+ ?_assertEqual("{foo, '@bar'}",
+ f(begin
+ Q1 = ?Q("foo"),
+ ?Q("{90919,_@bar}")
+ end))
+ ].
+
+inline_meta_autoabstract_test_() ->
+ [?_assertEqual("{foo}",
+ f(begin
+ Foo = foo,
+ ?Q("{_@Foo@}")
+ end)),
+ ?_assertEqual("{foo, '@bar@'}",
+ f(begin
+ Foo = foo,
+ ?Q("{_@Foo@,_@bar@}")
+ end)),
+ ?_assertEqual("{foo, '@bar@'}",
+ f(begin
+ Q1 = foo,
+ ?Q("{909199,_@bar@}")
+ end))
+ ].
+
+meta_match_test_() ->
+ [?_assertEqual("{[bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ ?Q("{foo, _@Bar, '@Baz'}") = Tree,
+ ?Q("{_@Bar, _@Baz}")
+ end)),
+ ?_assertEqual("{[bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ ?Q("{foo, 90919, 90929}") = Tree,
+ ?Q("{_@Q1, _@Q2}")
+ end)),
+ ?_assertError({badmatch,error},
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ ?Q("{fie, _@Bar, '@Baz'}") = Tree,
+ ?Q("{_@Bar, _@Baz}")
+ end))
+ ].
+
+meta_case_test_() ->
+ [?_assertEqual("{[bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ case Tree of
+ ?Q("{foo, _@Bar, '@Baz'}") -> ?Q("{_@Bar, _@Baz}")
+ end
+ end)),
+ ?_assertEqual("{foo, [bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ case Tree of
+ ?Q("{fie, _@Bar, '@Baz'}") -> ?Q("{_@Bar, _@Baz}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertError(merl_switch_clause,
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ case Tree of
+ ?Q("{fie, _@Bar, '@Baz'}") -> ?Q("{_@Bar, _@Baz}")
+ end
+ end)),
+ ?_assertEqual("{foo, 4}",
+ f(begin
+ Tree = ?Q("{foo, 3}"),
+ case Tree of
+ ?Q("{foo, _@N}") ->
+ N1 = erl_syntax:concrete(N) + 1,
+ ?Q("{foo, _@N1@}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("-export([f/4]).",
+ f(begin
+ Tree = ?Q("-export([f/3])."),
+ case Tree of
+ ?Q("-export([f/90919]).") ->
+ Q2 = erl_syntax:concrete(Q1) + 1,
+ ?Q("-export([f/909299]).");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("{1, [bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ case Tree of
+ ?Q("{foo, _@Bar, '@Baz'}") ->
+ ?Q("{1, _@Bar, _@Baz}");
+ ?Q("{fie, _@Bar, '@Baz'}") ->
+ ?Q("{2, _@Bar, _@Baz}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("{2, [bar], baz()}",
+ f(begin
+ Tree = ?Q("{fie, [bar], baz()}"),
+ case Tree of
+ ?Q("{foo, _@Bar, '@Baz'}") ->
+ ?Q("{1, _@Bar, _@Baz}");
+ ?Q("{fie, _@Bar, '@Baz'}") ->
+ ?Q("{2, _@Bar, _@Baz}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("{2, baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ case Tree of
+ ?Q("{foo, [_@Bar], '@Baz'}")
+ when erl_syntax:is_atom(Bar, foo) ->
+ ?Q("{1, _@Baz}");
+ ?Q("{foo, [_@Bar], '@Baz'}")
+ when erl_syntax:is_atom(Bar, bar) ->
+ ?Q("{2, _@Baz}");
+ ?Q("{foo, [_@Bar], '@Baz'}") ->
+ ?Q("{3, _@Baz}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("{2, 42}",
+ f(begin
+ Tree = ?Q("{foo, [bar], 42}"),
+ case Tree of
+ ?Q("{foo, [_@Bar], '@Baz'}")
+ when erl_syntax:is_atom(Bar, bar),
+ erl_syntax:is_integer(Baz, 17) ->
+ ?Q("{1, _@Bar}");
+ ?Q("{foo, [_@Bar], '@Baz'}")
+ when erl_syntax:is_atom(Bar, bar),
+ erl_syntax:is_integer(Baz, 42) ->
+ ?Q("{2, _@Baz}");
+ ?Q("{foo, [_@Bar], '@Baz'}") ->
+ ?Q("{3, _@Baz}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("{2, 42}",
+ f(begin
+ Tree = ?Q("{foo, [baz], 42}"),
+ case Tree of
+ ?Q("{foo, [_@Bar], '@Baz'}")
+ when erl_syntax:is_atom(Bar, bar),
+ erl_syntax:is_integer(Baz, 17)
+ ; erl_syntax:is_atom(Bar, baz),
+ erl_syntax:is_integer(Baz, 17) ->
+ ?Q("{1, _@Bar}");
+ ?Q("{foo, [_@Bar], '@Baz'}")
+ when erl_syntax:is_atom(Bar, bar),
+ erl_syntax:is_integer(Baz, 42)
+ ; erl_syntax:is_atom(Bar, baz),
+ erl_syntax:is_integer(Baz, 42) ->
+ ?Q("{2, _@Baz}");
+ ?Q("{foo, [_@Bar], '@Baz'}") ->
+ ?Q("{3, _@Baz}");
+ _ -> Tree
+ end
+ end)),
+ ?_assertEqual("{2, foo, Bar, Baz, Bar(), Baz()}",
+ f(begin
+ Tree = ?Q("foo(Bar, Baz) -> Bar(), Baz()."),
+ case Tree of
+ ?Q("'@Func'(_@Args) -> _@Body.") ->
+ ?Q("{1, _@Func, _@Args, _@Body}");
+ ?Q("'@Func'(_@@Args) -> _@@Body.") ->
+ ?Q("{2, _@Func, _@Args, _@Body}");
+ ?Q("'@Func'(_@Args, Baz) -> _@Body1, _@Body2.") ->
+ ?Q("{3, _@Func, _@Args, _@Body1, _@Body2}")
+ end
+ end))
+ ].
+
+-endif.
diff --git a/lib/syntax_tools/src/merl_transform.erl b/lib/syntax_tools/src/merl_transform.erl
new file mode 100644
index 0000000000..66b06c8137
--- /dev/null
+++ b/lib/syntax_tools/src/merl_transform.erl
@@ -0,0 +1,262 @@
+%% ---------------------------------------------------------------------
+%% Licensed under the Apache License, Version 2.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.
+%%
+%% @author Richard Carlsson <[email protected]>
+%% @copyright 2012-2015 Richard Carlsson
+%% @doc Parse transform for merl. Enables the use of automatic metavariables
+%% and using quasi-quotes in matches and case switches. Also optimizes calls
+%% to functions in `merl' by partially evaluating them, turning strings to
+%% templates, etc., at compile-time.
+%%
+%% Using `-include_lib("syntax_tools/include/merl.hrl").' enables this
+%% transform, unless the macro `MERL_NO_TRANSFORM' is defined first.
+
+-module(merl_transform).
+
+-export([parse_transform/2]).
+
+%% NOTE: We cannot use inline metavariables or any other parse transform
+%% features in this module, because it must be possible to compile it with
+%% the parse transform disabled!
+-include("merl.hrl").
+
+%% TODO: unroll calls to switch? it will probably get messy
+
+%% TODO: use Igor to make resulting code independent of merl at runtime?
+
+parse_transform(Forms, _Options) ->
+ erl_syntax:revert_forms(expand(erl_syntax:form_list(Forms))).
+
+expand(Tree0) ->
+ Tree = pre(Tree0),
+ post(case erl_syntax:subtrees(Tree) of
+ [] ->
+ Tree;
+ Gs ->
+ erl_syntax:update_tree(Tree,
+ [[expand(T) || T <- G] || G <- Gs])
+ end).
+
+pre(T) ->
+ merl:switch(
+ T,
+ [{?Q("merl:quote(_@line, _@text) = _@expr"),
+ fun ([{expr,_}, {line,Line}, {text,Text}]) ->
+ erl_syntax:is_literal(Text) andalso erl_syntax:is_literal(Line)
+ end,
+ fun ([{expr,Expr}, {line,Line}, {text,Text}]) ->
+ pre_expand_match(Expr, erl_syntax:concrete(Line),
+ erl_syntax:concrete(Text))
+ end},
+ {?Q(["case _@expr of",
+ " merl:quote(_@_, _@text) when _@__@_ -> _@@_; _@_@_ -> 0",
+ "end"]),
+ fun case_guard/1,
+ fun (As) -> case_body(As, T) end},
+ fun () -> T end
+ ]).
+
+case_guard([{expr,_}, {text,Text}]) ->
+ erl_syntax:is_literal(Text).
+
+case_body([{expr,Expr}, {text,_Text}], T) ->
+ pre_expand_case(Expr, erl_syntax:case_expr_clauses(T),
+ erl_syntax:get_pos(T)).
+
+post(T) ->
+ merl:switch(
+ T,
+ [{?Q("merl:_@function(_@@args)"),
+ [{fun ([{args, As}, {function, F}]) ->
+ lists:all(fun erl_syntax:is_literal/1, [F|As])
+ end,
+ fun ([{args, As}, {function, F}]) ->
+ Line = erl_syntax:get_pos(F),
+ [F1|As1] = lists:map(fun erl_syntax:concrete/1, [F|As]),
+ eval_call(Line, F1, As1, T)
+ end},
+ fun ([{args, As}, {function, F}]) ->
+ merl:switch(
+ F,
+ [{?Q("qquote"), fun ([]) -> expand_qquote(As, T, 1) end},
+ {?Q("subst"), fun ([]) -> expand_template(F, As, T) end},
+ {?Q("match"), fun ([]) -> expand_template(F, As, T) end},
+ fun () -> T end
+ ])
+ end]},
+ fun () -> T end]).
+
+expand_qquote([Line, Text, Env], T, _) ->
+ case erl_syntax:is_literal(Line) of
+ true ->
+ expand_qquote([Text, Env], T, erl_syntax:concrete(Line));
+ false ->
+ T
+ end;
+expand_qquote([Text, Env], T, Line) ->
+ case erl_syntax:is_literal(Text) of
+ true ->
+ As = [Line, erl_syntax:concrete(Text)],
+ %% expand further if possible
+ expand(merl:qquote(Line, "merl:subst(_@tree, _@env)",
+ [{tree, eval_call(Line, quote, As, T)},
+ {env, Env}]));
+ false ->
+ T
+ end;
+expand_qquote(_As, T, _StartPos) ->
+ T.
+
+expand_template(F, [Pattern | Args], T) ->
+ case erl_syntax:is_literal(Pattern) of
+ true ->
+ Line = erl_syntax:get_pos(Pattern),
+ As = [erl_syntax:concrete(Pattern)],
+ merl:qquote(Line, "merl:_@function(_@pattern, _@args)",
+ [{function, F},
+ {pattern, eval_call(Line, template, As, T)},
+ {args, Args}]);
+ false ->
+ T
+ end;
+expand_template(_F, _As, T) ->
+ T.
+
+eval_call(Line, F, As, T) ->
+ try apply(merl, F, As) of
+ T1 when F =:= quote ->
+ %% lift metavariables in a template to Erlang variables
+ Template = merl:template(T1),
+ Vars = merl:template_vars(Template),
+ case lists:any(fun is_inline_metavar/1, Vars) of
+ true when is_list(T1) ->
+ merl:qquote(Line, "merl:tree([_@template])",
+ [{template, merl:meta_template(Template)}]);
+ true ->
+ merl:qquote(Line, "merl:tree(_@template)",
+ [{template, merl:meta_template(Template)}]);
+ false ->
+ merl:term(T1)
+ end;
+ T1 ->
+ merl:term(T1)
+ catch
+ throw:_Reason -> T
+ end.
+
+pre_expand_match(Expr, Line, Text) ->
+ {Template, Out, _Vars} = rewrite_pattern(Line, Text),
+ merl:qquote(Line, "{ok, _@out} = merl:match(_@template, _@expr)",
+ [{expr, Expr},
+ {out, Out},
+ {template, erl_syntax:abstract(Template)}]).
+
+rewrite_pattern(Line, Text) ->
+ %% we must rewrite the metavariables in the pattern to use lowercase,
+ %% and then use real matching to bind the Erlang-level variables
+ T0 = merl:template(merl:quote(Line, Text)),
+ Vars = [V || V <- merl:template_vars(T0), is_inline_metavar(V)],
+ {merl:alpha(T0, [{V, var_to_tag(V)} || V <- Vars]),
+ erl_syntax:list([erl_syntax:tuple([erl_syntax:abstract(var_to_tag(V)),
+ erl_syntax:variable(var_name(V))])
+ || V <- Vars]),
+ Vars}.
+
+var_name(V) when is_integer(V) ->
+ V1 = if V > 99, (V rem 100) =:= 99 ->
+ V div 100;
+ V > 9, (V rem 10) =:= 9 ->
+ V div 10;
+ true -> V
+ end,
+ list_to_atom("Q" ++ integer_to_list(V1));
+var_name(V) -> V.
+
+var_to_tag(V) when is_integer(V) -> V;
+var_to_tag(V) ->
+ list_to_atom(string:to_lower(atom_to_list(V))).
+
+pre_expand_case(Expr, Clauses, Line) ->
+ merl:qquote(Line, "merl:switch(_@expr, _@clauses)",
+ [{clauses, erl_syntax:list([pre_expand_case_clause(C)
+ || C <- Clauses])},
+ {expr, Expr}]).
+
+pre_expand_case_clause(T) ->
+ %% note that the only allowed non ``?Q(...) -> ...'' clause is ``_ -> ...''
+ merl:switch(
+ T,
+ [{?Q("(merl:quote(_@line, _@text)) when _@__@guard -> _@@body"),
+ fun ([{body,_}, {guard,_}, {line,Line}, {text,Text}]) ->
+ erl_syntax:is_literal(Text) andalso erl_syntax:is_literal(Line)
+ end,
+ fun ([{body,Body}, {guard,Guard}, {line,Line}, {text,Text}]) ->
+ pre_expand_case_clause(Body, Guard, erl_syntax:concrete(Line),
+ erl_syntax:concrete(Text))
+ end},
+ {?Q("_ -> _@@body"),
+ fun (Env) -> merl:qquote("fun () -> _@body end", Env) end}
+ ]).
+
+pre_expand_case_clause(Body, Guard, Line, Text) ->
+ %% this is similar to a meta-match ``?Q("...") = Term''
+ %% (note that the guards may in fact be arbitrary expressions)
+ {Template, Out, Vars} = rewrite_pattern(Line, Text),
+ GuardExprs = rewrite_guard(Guard),
+ Param = [{body, Body},
+ {guard,GuardExprs},
+ {out, Out},
+ {template, erl_syntax:abstract(Template)},
+ {unused, dummy_uses(Vars)}],
+ case GuardExprs of
+ [] ->
+ merl:qquote(Line, ["{_@template, ",
+ " fun (_@out) -> _@unused, _@body end}"],
+ Param);
+ _ ->
+ merl:qquote(Line, ["{_@template, ",
+ " fun (_@out) -> _@unused, _@guard end, ",
+ " fun (_@out) -> _@unused, _@body end}"],
+ Param)
+ end.
+
+%% We have to insert dummy variable uses at the beginning of the "guard" and
+%% "body" function bodies to avoid warnings for unused variables in the
+%% generated code. (Expansions at the Erlang level can't be marked up as
+%% compiler generated to allow later compiler stages to ignore them.)
+dummy_uses(Vars) ->
+ [?Q("_ = _@var", [{var, erl_syntax:variable(var_name(V))}])
+ || V <- Vars].
+
+rewrite_guard([]) -> [];
+rewrite_guard([D]) -> [make_orelse(erl_syntax:disjunction_body(D))].
+
+make_orelse([]) -> [];
+make_orelse([C]) -> make_andalso(erl_syntax:conjunction_body(C));
+make_orelse([C | Cs]) ->
+ ?Q("_@expr orelse _@rest",
+ [{expr, make_andalso(erl_syntax:conjunction_body(C))},
+ {rest, make_orelse(Cs)}]).
+
+make_andalso([E]) -> E;
+make_andalso([E | Es]) ->
+ ?Q("_@expr andalso _@rest", [{expr, E}, {rest, make_andalso(Es)}]).
+
+is_inline_metavar(Var) when is_atom(Var) ->
+ is_erlang_var(atom_to_list(Var));
+is_inline_metavar(Var) when is_integer(Var) ->
+ Var > 9 andalso (Var rem 10) =:= 9;
+is_inline_metavar(_) -> false.
+
+is_erlang_var([C|_]) when C >= $A, C =< $Z ; C >= $À, C =< $Þ, C /= $× ->
+ true;
+is_erlang_var(_) ->
+ false.
diff --git a/lib/syntax_tools/src/syntax_tools.app.src b/lib/syntax_tools/src/syntax_tools.app.src
index 83dcb5fe23..dd4ac46055 100644
--- a/lib/syntax_tools/src/syntax_tools.app.src
+++ b/lib/syntax_tools/src/syntax_tools.app.src
@@ -11,8 +11,11 @@
erl_syntax_lib,
erl_tidy,
igor,
+ merl,
+ merl_transform,
prettypr]},
{registered,[]},
{applications, [stdlib]},
{env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}]}.
+ {runtime_dependencies,
+ ["compiler-6.0","erts-6.0","kernel-3.0","stdlib-2.5"]}]}.
diff --git a/lib/syntax_tools/src/syntax_tools.appup.src b/lib/syntax_tools/src/syntax_tools.appup.src
index 89c25d14d7..59d591a01f 100644
--- a/lib/syntax_tools/src/syntax_tools.appup.src
+++ b/lib/syntax_tools/src/syntax_tools.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/syntax_tools/test/Makefile b/lib/syntax_tools/test/Makefile
index f67e3f8984..569c044b1a 100644
--- a/lib/syntax_tools/test/Makefile
+++ b/lib/syntax_tools/test/Makefile
@@ -6,7 +6,8 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# ----------------------------------------------------
MODULES= \
- syntax_tools_SUITE
+ syntax_tools_SUITE \
+ merl_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/syntax_tools/test/merl_SUITE.erl b/lib/syntax_tools/test/merl_SUITE.erl
new file mode 100644
index 0000000000..125250395a
--- /dev/null
+++ b/lib/syntax_tools/test/merl_SUITE.erl
@@ -0,0 +1,92 @@
+%% ``Licensed under the Apache License, Version 2.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.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+-module(merl_SUITE).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%% include the Merl header file
+-include_lib("syntax_tools/include/merl.hrl").
+
+%% for assert macros
+-include_lib("eunit/include/eunit.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]).
+
+%% Test cases
+-export([merl_smoke_test/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [merl_smoke_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+-define(tokens2str(X), ??X).
+
+merl_smoke_test(Config) when is_list(Config) ->
+ ?assertThrow({error, "1: syntax error before: '{'" ++ _},
+ f(merl:quote("{"))),
+ ?assertEqual(tuple, erl_syntax:type(merl:term({}))),
+ ?assertEqual("{foo, 42}", f(merl:term({foo, 42}))),
+ ?assertEqual("f(X) -> {ok, X}.", f(?Q("f(X) -> {ok, X}."))),
+ ?assertEqual("{foo, 42}", f(?Q("{foo, 42}"))),
+ ?assertEqual("2 + 2", f(?Q("2 + 2"))),
+ ?assertEqual("%% comment preserved\n{foo, 42}",
+ f(?Q(["%% comment preserved", "{foo, 42}"]))),
+ ?assertEqual("'@foo'", f(merl:tree(merl:template(?Q("'@foo'"))))),
+ ?assertEqual("42", f(merl:subst(?Q("_@foo"), [{foo, merl:term(42)}]))),
+ ?assertEqual({ok, []}, merl:match(?Q("foo"), ?Q("foo"))),
+ ?assertEqual(42, merl:switch(?Q("foo"), [fun () -> 42 end])),
+ ?assertEqual("{foo}", f(begin Foo = ?Q("foo"), ?Q("{_@Foo}") end)),
+ ?assertEqual("{foo}", f(begin Foo = foo, ?Q("{_@Foo@}") end)),
+ ?assertEqual("{[bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ ?Q("{foo, _@Bar, '@Baz'}") = Tree,
+ ?Q("{_@Bar, _@Baz}")
+ end)),
+ ?assertEqual("{[bar], baz()}",
+ f(begin
+ Tree = ?Q("{foo, [bar], baz()}"),
+ case Tree of
+ ?Q("{foo, _@Bar, '@Baz'}") -> ?Q("{_@Bar, _@Baz}")
+ end
+ end)),
+ ok.
+
+%% utilities
+
+f(Ts) when is_list(Ts) ->
+ lists:flatmap(fun erl_prettypr:format/1, Ts);
+f(T) ->
+ erl_prettypr:format(T).
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index 3c6b33f459..40e00e0554 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index 1c42ef0ddb..403e90196e 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 1.6.18
+SYNTAX_TOOLS_VSN = 1.7
diff --git a/lib/test_server/Makefile b/lib/test_server/Makefile
index 98e51a0ee6..382749d1fc 100644
--- a/lib/test_server/Makefile
+++ b/lib/test_server/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/test_server/doc/src/Makefile b/lib/test_server/doc/src/Makefile
index 8c7fa99886..8c5418aee5 100644
--- a/lib/test_server/doc/src/Makefile
+++ b/lib/test_server/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2002-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -27,6 +28,10 @@ include ../../vsn.mk
VSN=$(TEST_SERVER_VSN)
APPLICATION=test_server
+DOC_EXTRA_FRONT_PAGE_INFO=Important note: \
+The Test Server application is obsolete and will be removed \
+in the next major OTP release
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
diff --git a/lib/test_server/doc/src/basics_chapter.xml b/lib/test_server/doc/src/basics_chapter.xml
index eba24615cb..9e9f38aab4 100644
--- a/lib/test_server/doc/src/basics_chapter.xml
+++ b/lib/test_server/doc/src/basics_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/book.xml b/lib/test_server/doc/src/book.xml
index 006a2f167d..6eb7daae1a 100644
--- a/lib/test_server/doc/src/book.xml
+++ b/lib/test_server/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/example_chapter.xml b/lib/test_server/doc/src/example_chapter.xml
index 0ebc85da09..ec152fdd6c 100644
--- a/lib/test_server/doc/src/example_chapter.xml
+++ b/lib/test_server/doc/src/example_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -47,7 +48,7 @@
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
- ?line Dog=?t:timetrap(?default_timeout),
+ Dog=?t:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
@@ -72,8 +73,8 @@ not_started_func1(suite) ->
not_started_func1(doc) ->
["Testing function 1 when application is not started"].
not_started_func1(Config) when list(Config) ->
- ?line {error, not_started} = myapp:func1(dummy_ref,1),
- ?line {error, not_started} = myapp:func1(dummy_ref,2),
+ {error, not_started} = myapp:func1(dummy_ref,1),
+ {error, not_started} = myapp:func1(dummy_ref,2),
ok.
not_started_func2(suite) ->
@@ -81,8 +82,8 @@ not_started_func2(suite) ->
not_started_func2(doc) ->
["Testing function 2 when application is not started"].
not_started_func2(Config) when list(Config) ->
- ?line {error, not_started} = myapp:func2(dummy_ref,1),
- ?line {error, not_started} = myapp:func2(dummy_ref,2),
+ {error, not_started} = myapp:func2(dummy_ref,1),
+ {error, not_started} = myapp:func2(dummy_ref,2),
ok.
@@ -90,7 +91,7 @@ not_started_func2(Config) when list(Config) ->
start(doc) ->
["Testing start of my application."];
start(Config) when list(Config) ->
- ?line Ref = myapp:start(),
+ Ref = myapp:start(),
case erlang:whereis(my_main_process) of
Pid when pid(Pid) ->
[{myapp_ref,Ref}|Config];
@@ -105,9 +106,9 @@ func1(suite) ->
func1(doc) ->
["Test that func1 returns ok when argument is 1 and error if argument is 2"];
func1(Config) when list(Config) ->
- ?line Ref = ?config(myapp_ref,Config),
- ?line ok = myapp:func1(Ref,1),
- ?line error = myapp:func1(Ref,2),
+ Ref = ?config(myapp_ref,Config),
+ ok = myapp:func1(Ref,1),
+ error = myapp:func1(Ref,2),
ok.
func2(suite) ->
@@ -115,17 +116,17 @@ func2(suite) ->
func2(doc) ->
["Test that func1 returns ok when argument is 3 and error if argument is 4"];
func2(Config) when list(Config) ->
- ?line Ref = ?config(myapp_ref,Config),
- ?line ok = myapp:func2(Ref,3),
- ?line error = myapp:func2(Ref,4),
+ Ref = ?config(myapp_ref,Config),
+ ok = myapp:func2(Ref,3),
+ error = myapp:func2(Ref,4),
ok.
%% No specification clause needed for a cleanup function in a conf case!!!
stop(doc) ->
["Testing termination of my application"];
stop(Config) when list(Config) ->
- ?line Ref = ?config(myapp_ref,Config),
- ?line ok = myapp:stop(Ref),
+ Ref = ?config(myapp_ref,Config),
+ ok = myapp:stop(Ref),
case erlang:whereis(my_main_process) of
undefined ->
lists:keydelete(myapp_ref,1,Config);
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index e996d2b4a3..9b5df6271a 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,6 +33,113 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.10</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Two new CT hook functions have been added:
+ <c>post_init_per_testcase/4</c> and
+ <c>pre_end_per_testcase/3</c>. With these hook functions,
+ it is possible to perform arbitrary actions (including
+ modifications of test execution, test state and results)
+ immediately before and after the execution of the test
+ case.</p>
+ <p>
+ Own Id: OTP-13242 Aux Id: seq12991 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Test_Server 3.9.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When generating Makefile from Makefile.src,
+ ts_lib:get_arg/4 earlier removed all spaces in the
+ extracted argument. The code was probably meant for
+ removing leading and trailing spaces only, and is now
+ corrected to do so.</p>
+ <p>
+ Own Id: OTP-13015</p>
+ </item>
+ <item>
+ <p>
+ With the Common Test 'create_priv_dir' start option set
+ to 'auto_per_tc', the name of the priv directory for a
+ configuration function could clash with the name of the
+ priv directory for a test case, which would cause Test
+ Server failure. This error has been corrected.</p>
+ <p>
+ Own Id: OTP-13181</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Test_Server 3.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The status of an aborted test due to test suite
+ compilation error has changed from 'auto_skipped' to
+ 'failed'. This affects both the textual log file, event
+ handling and CT hook callbacks. The logging of
+ compilation failures has also been improved, especially
+ in the case of multiple test suites failing compilation.</p>
+ <p>
+ Own Id: OTP-10816</p>
+ </item>
+ <item>
+ <p>
+ The Test Server source code parser (erl2html2) failed to
+ handle the macro tuple in the syntax tree returned by
+ epp_dodger. This error has been corrected.</p>
+ <p>
+ Own Id: OTP-12740</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The Test Server application has been marked as obsolete
+ and will be removed from OTP in the next major release
+ (OTP 19.0).</p>
+ <p>
+ Own Id: OTP-10923 Aux Id: OTP-12705 </p>
+ </item>
+ <item>
+ <p>
+ When running OTP tests using the ts interface, it is now
+ possible to specify so called test categories per OTP
+ application. A test category is represented by a CT test
+ specification and defines an arbitrary subset of existing
+ test suites, groups and cases. Examples of test
+ categories are 'smoke' (smoke tests) and 'bench'
+ (benchmarks). (Call ts:help() for more info). Also,
+ functions for reading terms from the current test
+ specification during test, ct:get_testspec_terms/0 and
+ ct:get_testspec_terms/1, have been implemented.</p>
+ <p>
+ Own Id: OTP-11962</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.8.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -240,7 +348,7 @@
configuration function or test specification term), the
affected test cases get the status <c>user_skipped</c>
instead.</p> <p>This update has meant a few changes that
- may affect Common Test users in various ways: <list>
+ may affect Common Test users in various ways:</p> <list>
<item>The test results and statistics will be affected,
which is important to know when running regression tests
and comparing results to previous test runs.</item>
@@ -260,7 +368,7 @@
<c>auto_skipped</c> rather than <c>user_skipped</c> as
before.</item> <item>The event messages that Common Test
generates during test runs have been affected by this
- update. For details see OTP-11524.</item> </list> </p>
+ update. For details see OTP-11524.</item> </list>
<p>
Own Id: OTP-11305 Aux Id: OTP-11524 </p>
</item>
@@ -387,7 +495,7 @@
that were not opened with the {encoding,utf8} option. If
then the argument contained unicode characters above 255,
the file descriptor would crash. This has been corrected
- by the following modifications: <list> <item> Since the
+ by the following modifications:</p> <list> <item> Since the
'unexpected_io' log file is used only when the test case
HTML file is not available (e.g. between test cases),
this file is now also a HTML file and as other
@@ -409,7 +517,7 @@
path to the last run.&lt;timestamp&gt; directory, is now
dependent on the file name mode of the VM. If file names
are expected to be unicode, then the 'last_name' file is
- UTF-8 encoded, else it is latin1 encoded. </item> </list></p>
+ UTF-8 encoded, else it is latin1 encoded. </item> </list>
<p>
Also, ~tp has been changed back to ~p unless it is
somehow likely that the argument includes strings. It is
@@ -557,7 +665,7 @@
</item>
<item>
<p>
- Update common test modules to handle unicode <list>
+ Update common test modules to handle Unicode:</p> <list>
<item> Use UTF-8 encoding for all HTML files, except the
HTML version of the test suite generated with
erl2html2:convert, which will have the same encoding as
@@ -568,7 +676,7 @@
unicode:characters_to_list and
unicode:characters_to_binary for conversion between
binaries and strings instead of binary_to_list and
- list_to_binary. </item> </list></p>
+ list_to_binary. </item> </list>
</item>
</list>
</section>
diff --git a/lib/test_server/doc/src/notes_history.xml b/lib/test_server/doc/src/notes_history.xml
index 898717cbf0..ca7880d74f 100644
--- a/lib/test_server/doc/src/notes_history.xml
+++ b/lib/test_server/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/part.xml b/lib/test_server/doc/src/part.xml
index 43693ff9cb..685ed16a94 100644
--- a/lib/test_server/doc/src/part.xml
+++ b/lib/test_server/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/part_notes.xml b/lib/test_server/doc/src/part_notes.xml
index e0656942cd..8cb9b6c591 100644
--- a/lib/test_server/doc/src/part_notes.xml
+++ b/lib/test_server/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/part_notes_history.xml b/lib/test_server/doc/src/part_notes_history.xml
index d3ff49830f..468b5aa8ba 100644
--- a/lib/test_server/doc/src/part_notes_history.xml
+++ b/lib/test_server/doc/src/part_notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/ref_man.xml b/lib/test_server/doc/src/ref_man.xml
index cc0e7eaf5c..1b06d9750b 100644
--- a/lib/test_server/doc/src/ref_man.xml
+++ b/lib/test_server/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/run_test_chapter.xml b/lib/test_server/doc/src/run_test_chapter.xml
index 35344255d4..cb5b29c993 100644
--- a/lib/test_server/doc/src/run_test_chapter.xml
+++ b/lib/test_server/doc/src/run_test_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/test_server.xml b/lib/test_server/doc/src/test_server.xml
index ed5569e1fe..96ff6de3ba 100644
--- a/lib/test_server/doc/src/test_server.xml
+++ b/lib/test_server/doc/src/test_server.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -811,46 +812,12 @@ Only valid for peer nodes. Note that slave nodes always
</func>
</funcs>
- <section>
- <title>TEST SUITE LINE NUMBERS</title>
- <p>If a test case fails, the test server can report the exact line
- number at which it failed. There are two ways of doing this,
- either by using the <c>line</c> macro or by using the
- <c>test_server_line</c> parse transform.
- </p>
- <p>The <c>line</c> macro is described under TEST SUITE SUPPORT
- MACROS below. The <c>line</c> macro will only report the last line
- executed when a test case failed.
- </p>
- <p>The <c>test_server_line</c> parse transform is activated by
- including the headerfile <c>test_server_line.hrl</c> in the test
- suite. When doing this, it is important that the
- <c>test_server_line</c> module is in the code path of the erlang
- node compiling the test suite. The parse transform will report a
- history of a maximum of 10 lines when a test case
- fails. Consecutive lines in the same function are not shown.
- </p>
- <p>The attribute <c>-no_lines(FuncList).</c> can be used in the
- test suite to exclude specific functions from the parse
- transform. This is necessary e.g. for functions that are executed
- on old (i.e. &lt;R10B) OTP releases. <c>FuncList = [{Func,Arity}]</c>.
- </p>
- <p>If both the <c>line</c> macro and the parse transform is used in
- the same module, the parse transform will overrule the macro.
- </p>
- </section>
<section>
<title>TEST SUITE SUPPORT MACROS</title>
<p>There are some macros defined in the <c>test_server.hrl</c>
that are quite useful for test suite programmers:
</p>
- <p>The <em>line</em> macro, is quite
- essential when writing test cases. It tells the test server
- exactly what line of code that is being executed, so that it can
- report this line back if the test case fails. Use this macro at
- the beginning of every test case line of code.
- </p>
<p>The <em>config</em> macro, is used to
retrieve information from the <c>Config</c> variable sent to all
test cases. It is used with two arguments, where the first is the
@@ -867,24 +834,20 @@ Only valid for peer nodes. Note that slave nodes always
<item>Whatever added by conf test cases or
<c>init_per_testcase/2</c></item>
</list>
- <p>Examples of the <c>line</c> and <c>config</c> macros can be
- seen in the Examples chapter in the user's guide.
- </p>
- <p>If the <c>line_trace</c> macro is defined, you will get a
- timestamp (<c>erlang:now()</c>) in your minor log for each
- <c>line</c> macro in your suite. This way you can at any time see
- which line is currently being executed, and when the line was
- called.
- </p>
- <p>The <c>line_trace</c> macro can also be used together with the
- <c>test_server_line</c> parse transform described above. A
- timestamp will then be written for each line in the suite, except
- for functions stated in the <c>-no_lines</c> attribute.
- </p>
- <p>The <c>line_trace</c> macro can e.g. be defined as a compile
- option, like this:
- <br></br>
-<c>erlc -W -Dline_trace my_SUITE.erl</c></p>
+ <p>Examples of the <c>config</c> macro can be seen in the Examples chapter
+ in the user's guide.</p>
+ <p>The <em>line</em> and <em>line_trace</em> macros are deprecated, see
+ below.</p>
+ </section>
+
+ <section>
+ <title>TEST SUITE LINE NUMBERS</title>
+ <p>In the past, ERTS did not produce line numbers when generating
+ stacktraces, test_server was thus unable to provide them when reporting
+ test failures. It had instead two different mecanisms to do it: either by
+ using the <c>line</c> macro or by using the <c>test_server_line</c> parse
+ transform. Both are deprecated and should not be used in new tests
+ anymore.</p>
</section>
</erlref>
diff --git a/lib/test_server/doc/src/test_server_app.xml b/lib/test_server/doc/src/test_server_app.xml
index e5481495a2..4830916561 100644
--- a/lib/test_server/doc/src/test_server_app.xml
+++ b/lib/test_server/doc/src/test_server_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml
index 0cda531716..2762997ece 100644
--- a/lib/test_server/doc/src/test_server_ctrl.xml
+++ b/lib/test_server/doc/src/test_server_ctrl.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/test_server/doc/src/test_spec_chapter.xml b/lib/test_server/doc/src/test_spec_chapter.xml
index 342f772f0b..0a62010364 100644
--- a/lib/test_server/doc/src/test_spec_chapter.xml
+++ b/lib/test_server/doc/src/test_spec_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/ts.xml b/lib/test_server/doc/src/ts.xml
index bd5a3cbaa3..60dfdbc545 100644
--- a/lib/test_server/doc/src/ts.xml
+++ b/lib/test_server/doc/src/ts.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/test_server/doc/src/why_test_chapter.xml b/lib/test_server/doc/src/why_test_chapter.xml
index 9b0ffc6f12..3d0e8271b1 100644
--- a/lib/test_server/doc/src/why_test_chapter.xml
+++ b/lib/test_server/doc/src/why_test_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/write_framework_chapter.xml b/lib/test_server/doc/src/write_framework_chapter.xml
index 3a6fda9610..d10b580c34 100644
--- a/lib/test_server/doc/src/write_framework_chapter.xml
+++ b/lib/test_server/doc/src/write_framework_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/doc/src/write_test_chapter.xml b/lib/test_server/doc/src/write_test_chapter.xml
index ce7f76549d..c3e1881b8a 100644
--- a/lib/test_server/doc/src/write_test_chapter.xml
+++ b/lib/test_server/doc/src/write_test_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/test_server/include/test_server.hrl b/lib/test_server/include/test_server.hrl
index 36e7e1f83d..77864ef3b5 100644
--- a/lib/test_server/include/test_server.hrl
+++ b/lib/test_server/include/test_server.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -21,7 +22,7 @@
-line_trace(true).
-define(line,
io:format(lists:concat([?MODULE,",",integer_to_list(?LINE),": ~p"]),
- [erlang:now()]),).
+ [erlang:monotonic_time()-erlang:system_info(start_time)]),).
-else.
-define(line,).
-endif.
diff --git a/lib/test_server/include/test_server_line.hrl b/lib/test_server/include/test_server_line.hrl
index 3c309d3ee5..37da956cd0 100644
--- a/lib/test_server/include/test_server_line.hrl
+++ b/lib/test_server/include/test_server_line.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile
index 35bbad3c22..6a26ee2933 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in
index 8398825d95..001de72a1e 100644
--- a/lib/test_server/src/configure.in
+++ b/lib/test_server/src/configure.in
@@ -4,16 +4,17 @@ dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 1997-2014. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
dnl
diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl
index 50dbbb82ee..e69383acea 100644
--- a/lib/test_server/src/erl2html2.erl
+++ b/lib/test_server/src/erl2html2.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -43,7 +44,7 @@ convert(File, Dest, InclPath) ->
"<html>\n"
"<head>\n"
"<meta http-equiv=\"Content-Type\" content=\"text/html;"
- "charset=",html_encoding(Encoding),"\"/>\n"
+ "charset=",html_encoding(Encoding),"\"/></meta>\n"
"<title>", to_raw_list(File,Encoding), "</title>\n"
"</head>\n\n"
"<body bgcolor=\"white\" text=\"black\""
@@ -109,26 +110,26 @@ parse_file(File, InclPath) ->
Error
end.
-parse_preprocessed_file(Epp,File,InCorrectFile) ->
+parse_preprocessed_file(Epp, File, InCorrectFile) ->
case epp:parse_erl_form(Epp) of
{ok,Form} ->
case Form of
{attribute,_,file,{File,_}} ->
- parse_preprocessed_file(Epp,File,true);
+ parse_preprocessed_file(Epp, File, true);
{attribute,_,file,{_OtherFile,_}} ->
- parse_preprocessed_file(Epp,File,false);
- {function,L,F,A,Cs} when InCorrectFile ->
- {CLs,LastCL} = find_clause_lines(Cs, []),
+ parse_preprocessed_file(Epp, File, false);
+ {function,L,F,A,Cs} when InCorrectFile ->
+ {CLs,LastCL} = find_clause_lines(Cs, []),
%% tl(CLs) cause we know the start line already
- [{atom_to_list(F),A,L,LastCL} | tl(CLs)] ++
- parse_preprocessed_file(Epp,File,true);
+ [{atom_to_list(F),A,get_line(L),LastCL} | tl(CLs)] ++
+ parse_preprocessed_file(Epp, File, true);
_ ->
- parse_preprocessed_file(Epp,File,InCorrectFile)
+ parse_preprocessed_file(Epp, File, InCorrectFile)
end;
{error,Reason={_L,epp,{undefined,_Macro,none}}} ->
throw({error,Reason,InCorrectFile});
{error,_Reason} ->
- parse_preprocessed_file(Epp,File,InCorrectFile);
+ parse_preprocessed_file(Epp, File, InCorrectFile);
{eof,_Location} ->
[]
end.
@@ -147,10 +148,10 @@ parse_non_preprocessed_file(Epp, File, Location) ->
case epp_dodger:parse_form(Epp, Location) of
{ok,Tree,Location1} ->
try erl_syntax:revert(Tree) of
- {function,L,F,A,Cs} ->
- {CLs,LastCL} = find_clause_lines(Cs, []),
+ {function,L,F,A,Cs} ->
+ {CLs,LastCL} = find_clause_lines(Cs, []),
%% tl(CLs) cause we know the start line already
- [{atom_to_list(F),A,L,LastCL} | tl(CLs)] ++
+ [{atom_to_list(F),A,get_line(L),LastCL} | tl(CLs)] ++
parse_non_preprocessed_file(Epp, File, Location1);
_ ->
parse_non_preprocessed_file(Epp, File, Location1)
@@ -163,21 +164,28 @@ parse_non_preprocessed_file(Epp, File, Location) ->
[]
end.
+get_line(Anno) ->
+ erl_anno:line(Anno).
+
%%%-----------------------------------------------------------------
%%% Find the line number of the last expression in the function
find_clause_lines([{clause,CL,_Params,_Op,Exprs}], CLs) -> % last clause
try tuple_to_list(lists:last(Exprs)) of
- [_Type,ExprLine | _] ->
- {lists:reverse([{clause,CL}|CLs]), ExprLine};
+ [_Type,ExprLine | _] when is_integer(ExprLine) ->
+ {lists:reverse([{clause,get_line(CL)}|CLs]), get_line(ExprLine)};
+ [tree,_ | Exprs1] ->
+ find_clause_lines([{clause,CL,undefined,undefined,Exprs1}], CLs);
+ [macro,{_var,ExprLine,_MACRO} | _] when is_integer(ExprLine) ->
+ {lists:reverse([{clause,get_line(CL)}|CLs]), get_line(ExprLine)};
_ ->
- {lists:reverse([{clause,CL}|CLs]), CL}
+ {lists:reverse([{clause,get_line(CL)}|CLs]), get_line(CL)}
catch
_:_ ->
- {lists:reverse([{clause,CL}|CLs]), CL}
+ {lists:reverse([{clause,get_line(CL)}|CLs]), get_line(CL)}
end;
find_clause_lines([{clause,CL,_Params,_Op,_Exprs} | Cs], CLs) ->
- find_clause_lines(Cs, [{clause,CL}|CLs]).
+ find_clause_lines(Cs, [{clause,get_line(CL)}|CLs]).
%%%-----------------------------------------------------------------
%%% Add a link target for each line and one for each function definition.
@@ -185,18 +193,18 @@ build_html(SFd,DFd,Encoding,FuncsAndCs) ->
build_html(SFd,DFd,Encoding,file:read_line(SFd),1,FuncsAndCs,
false,undefined).
-%% function start line found
-build_html(SFd,DFd,Enc,{ok,Str},L0,[{F,A,L0,LastL}|FuncsAndCs],
- _IsFuncDef,_FAndLastL) ->
- FALink = test_server_ctrl:uri_encode(F++"-"++integer_to_list(A),utf8),
- file:write(DFd,["<a name=\"",to_raw_list(FALink,Enc),"\"/>"]),
- build_html(SFd,DFd,Enc,{ok,Str},L0,FuncsAndCs,true,{F,LastL});
%% line of last expression in function found
build_html(SFd,DFd,Enc,{ok,Str},LastL,FuncsAndCs,_IsFuncDef,{F,LastL}) ->
LastLineLink = test_server_ctrl:uri_encode(F++"-last_expr",utf8),
file:write(DFd,["<a name=\"",
to_raw_list(LastLineLink,Enc),"\"/>"]),
build_html(SFd,DFd,Enc,{ok,Str},LastL,FuncsAndCs,true,undefined);
+%% function start line found
+build_html(SFd,DFd,Enc,{ok,Str},L0,[{F,A,L0,LastL}|FuncsAndCs],
+ _IsFuncDef,_FAndLastL) ->
+ FALink = test_server_ctrl:uri_encode(F++"-"++integer_to_list(A),utf8),
+ file:write(DFd,["<a name=\"",to_raw_list(FALink,Enc),"\"/>"]),
+ build_html(SFd,DFd,Enc,{ok,Str},L0,FuncsAndCs,true,{F,LastL});
build_html(SFd,DFd,Enc,{ok,Str},L,[{clause,L}|FuncsAndCs],
_IsFuncDef,FAndLastL) ->
build_html(SFd,DFd,Enc,{ok,Str},L,FuncsAndCs,true,FAndLastL);
diff --git a/lib/test_server/src/test_server.app.src b/lib/test_server/src/test_server.app.src
index 173f7075db..334be8109d 100644
--- a/lib/test_server/src/test_server.app.src
+++ b/lib/test_server/src/test_server.app.src
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
@@ -32,7 +33,7 @@
test_server_break_process]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["tools-2.6.14","stdlib-2.0","runtime_tools-1.8.14",
- "observer-2.0","kernel-3.0","inets-5.10",
- "syntax_tools-1.6.16","erts-6.0"]}]}.
+ {runtime_dependencies, ["tools-2.8","stdlib-2.5","runtime_tools-1.8.16",
+ "observer-2.1","kernel-4.0","inets-6.0",
+ "syntax_tools-1.7","erts-7.0"]}]}.
diff --git a/lib/test_server/src/test_server.appup.src b/lib/test_server/src/test_server.appup.src
index 42c6fe2e46..7c4aa630ae 100644
--- a/lib/test_server/src/test_server.appup.src
+++ b/lib/test_server/src/test_server.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 1c3352550b..919526c5d7 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -1,21 +1,21 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% http://www.apache.org/licenses/LICENSE-2.0
%%
-%% %CopyrightEnd%
+%% 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(test_server).
-define(DEFAULT_TIMETRAP_SECS, 60).
@@ -63,13 +63,11 @@
init_target_info() ->
[$.|Emu] = code:objfile_extension(),
{_, OTPRel} = init:script_id(),
- TestServerDir = filename:absname(filename:dirname(code:which(?MODULE))),
#target_info{os_family=test_server_sup:get_os_family(),
os_type=os:type(),
version=erlang:system_info(version),
system_version=erlang:system_info(system_version),
root_dir=code:root_dir(),
- test_server_dir=TestServerDir,
emulator=Emu,
otp_release=OTPRel,
username=test_server_sup:get_username(),
@@ -178,68 +176,35 @@ module_names(Beams) ->
do_cover_compile(Modules) ->
cover:start(),
- pmap1(fun(M) -> do_cover_compile1(M) end,lists:usort(Modules)),
+ Sticky = prepare_cover_compile(Modules,[]),
+ R = cover:compile_beam(Modules),
+ [warn_compile(Error) || Error <- R,element(1,Error)=/=ok],
+ [code:stick_mod(M) || M <- Sticky],
ok.
-do_cover_compile1(M) ->
+warn_compile({error,{Reason,Module}}) ->
+ io:fwrite("\nWARNING: Could not cover compile ~ts: ~p\n",
+ [Module,{error,Reason}]).
+
+%% Make sure all modules are loaded and unstick if sticky
+prepare_cover_compile([M|Ms],Sticky) ->
case {code:is_sticky(M),code:is_loaded(M)} of
{true,_} ->
code:unstick_mod(M),
- case cover:compile_beam(M) of
- {ok,_} ->
- ok;
- Error ->
- io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n",
- [M,Error])
- end,
- code:stick_mod(M);
+ prepare_cover_compile(Ms,[M|Sticky]);
{false,false} ->
case code:load_file(M) of
{module,_} ->
- do_cover_compile1(M);
+ prepare_cover_compile([M|Ms],Sticky);
Error ->
- io:fwrite("\nWARNING: Could not load ~w: ~p\n",[M,Error])
+ io:fwrite("\nWARNING: Could not load ~w: ~p\n",[M,Error]),
+ prepare_cover_compile(Ms,Sticky)
end;
{false,_} ->
- case cover:compile_beam(M) of
- {ok,_} ->
- ok;
- Error ->
- io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n",
- [M,Error])
- end
- end.
-
-pmap1(Fun,List) ->
- NTot = length(List),
- NProcs = erlang:system_info(schedulers) * 2,
- NPerProc = (NTot div NProcs) + 1,
-
- {[],Pids} =
- lists:foldr(
- fun(_,{L,Ps}) ->
- {L1,L2} = if length(L)>=NPerProc -> lists:split(NPerProc,L);
- true -> {L,[]} % last chunk
- end,
- {P,_Ref} =
- spawn_monitor(fun() ->
- exit(lists:map(Fun,L1))
- end),
- {L2,[P|Ps]}
- end,
- {List,[]},
- lists:seq(1,NProcs)),
- collect(Pids,[]).
-
-collect([],Acc) ->
- lists:append(Acc);
-collect([Pid|Pids],Acc) ->
- receive
- {'DOWN', _Ref, process, Pid, Result} ->
- %% collect(lists:delete(Pid,Pids),[Result|Acc])
- collect(Pids,[Result|Acc])
- end.
-
+ prepare_cover_compile(Ms,Sticky)
+ end;
+prepare_cover_compile([],Sticky) ->
+ Sticky.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% cover_analyse(Dir,#cover{level=Analyse,mods=Modules,stop=Stop) ->
@@ -269,45 +234,40 @@ collect([Pid|Pids],Acc) ->
%% after the test is completed.
cover_analyse(Dir,#cover{level=Analyse,mods=Modules,stop=Stop}) ->
io:fwrite(user, "Cover analysing... ", []),
- DetailsFun =
+ {ATFOk,ATFFail} =
case Analyse of
details ->
case cover:export(filename:join(Dir,"all.coverdata")) of
ok ->
- fun(M) ->
- OutFile = filename:join(Dir,
- atom_to_list(M) ++
- ".COVER.html"),
- case cover:analyse_to_file(M,OutFile,[html]) of
- {ok,_} ->
- {file,OutFile};
- Error ->
- Error
- end
- end;
+ {result,Ok1,Fail1} =
+ cover:analyse_to_file(Modules,[{outdir,Dir},html]),
+ {lists:map(fun(OutFile) ->
+ M = list_to_atom(
+ filename:basename(
+ filename:rootname(OutFile,
+ ".COVER.html")
+ )
+ ),
+ {M,{file,OutFile}}
+ end, Ok1),
+ lists:map(fun({Reason,M}) ->
+ {M,{error,Reason}}
+ end, Fail1)};
Error ->
- fun(_) -> Error end
+ {[],lists:map(fun(M) -> {M,Error} end, Modules)}
end;
overview ->
case cover:export(filename:join(Dir,"all.coverdata")) of
ok ->
- fun(_) -> undefined end;
+ {[],lists:map(fun(M) -> {M,undefined} end, Modules)};
Error ->
- fun(_) -> Error end
+ {[],lists:map(fun(M) -> {M,Error} end, Modules)}
end
end,
- R = pmap2(
- fun(M) ->
- case cover:analyse(M,module) of
- {ok,{M,{Cov,NotCov}}} ->
- {M,{Cov,NotCov,DetailsFun(M)}};
- Err ->
- io:fwrite(user,
- "\nWARNING: Analysis failed for ~w. Reason: ~p\n",
- [M,Err]),
- {M,Err}
- end
- end, Modules),
+ {result,AOk,AFail} = cover:analyse(Modules,module),
+ R0 = merge_analysis_results(AOk,ATFOk++ATFFail,[]) ++
+ [{M,{error,Reason}} || {Reason,M} <- AFail],
+ R = lists:sort(R0),
io:fwrite(user, "done\n\n", []),
case Stop of
@@ -320,19 +280,15 @@ cover_analyse(Dir,#cover{level=Analyse,mods=Modules,stop=Stop}) ->
end,
R.
-pmap2(Fun,List) ->
- Collector = self(),
- Pids = lists:map(fun(E) ->
- spawn(fun() ->
- Collector ! {res,self(),Fun(E)}
- end)
- end, List),
- lists:map(fun(Pid) ->
- receive
- {res,Pid,Res} ->
- Res
- end
- end, Pids).
+merge_analysis_results([{M,{Cov,NotCov}}|T],ATF,Acc) ->
+ case lists:keytake(M,1,ATF) of
+ {value,{_,R},ATF1} ->
+ merge_analysis_results(T,ATF1,[{M,{Cov,NotCov,R}}|Acc]);
+ false ->
+ merge_analysis_results(T,ATF,Acc)
+ end;
+merge_analysis_results([],_,Acc) ->
+ Acc.
do_cover_for_node(Node,CoverFunc) ->
do_cover_for_node(Node,CoverFunc,true).
@@ -453,11 +409,9 @@ run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
Ref = make_ref(),
Pid =
spawn_link(
- fun() ->
- run_test_case_eval(Mod, Func, Args, Name, Ref,
- RunInit, TimetrapData,
- LogOpts, TCCallback)
- end),
+ run_test_case_eval_fun(Mod, Func, Args, Name, Ref,
+ RunInit, TimetrapData,
+ LogOpts, TCCallback)),
put(test_server_detected_fail, []),
St = #st{ref=Ref,pid=Pid,mf={Mod,Func},last_known_loc=unknown,
status=starting,ret_val=[],comment="",timeout=infinity,
@@ -760,10 +714,10 @@ call_end_conf(Mod,Func,TCPid,TCExitReason,Loc,Conf,TVal) ->
Starter ! {self(),{call_end_conf,Data,ok}}
end);
true ->
- do_call_end_conf(Starter,Mod,Func,Data,Conf,TVal)
+ do_call_end_conf(Starter,Mod,Func,Data,TCExitReason,Conf,TVal)
end.
-do_call_end_conf(Starter,Mod,Func,Data,Conf,TVal) ->
+do_call_end_conf(Starter,Mod,Func,Data,TCExitReason,Conf,TVal) ->
EndConfProc =
fun() ->
process_flag(trap_exit,true), % to catch timetraps
@@ -771,16 +725,25 @@ do_call_end_conf(Starter,Mod,Func,Data,Conf,TVal) ->
EndConfApply =
fun() ->
timetrap(TVal),
- try apply(Mod,end_per_testcase,[Func,Conf]) of
+ %% We can't handle fails or skips here
+ %% (neither input nor output). The error can
+ %% be read from Conf though (tc_status).
+ EndConf =
+ case do_init_tc_call(Mod,{end_per_testcase,Func},
+ [Conf],
+ {TCExitReason,[Conf]}) of
+ {_,[EPTCInit]} when is_list(EPTCInit) ->
+ EPTCInit;
+ _ ->
+ Conf
+ end,
+ try apply(Mod,end_per_testcase,[Func,EndConf]) of
_ -> ok
catch
- _:Why ->
+ _:Error ->
timer:sleep(1),
- group_leader() ! {printout,12,
- "WARNING! "
- "~w:end_per_testcase(~w, ~p)"
- " crashed!\n\tReason: ~p\n",
- [Mod,Func,Conf,Why]}
+ print_end_conf_result(Mod,Func,Conf,
+ "crashed",Error)
end,
Supervisor ! {self(),end_conf}
end,
@@ -789,10 +752,7 @@ do_call_end_conf(Starter,Mod,Func,Data,Conf,TVal) ->
{Pid,end_conf} ->
Starter ! {self(),{call_end_conf,Data,ok}};
{'EXIT',Pid,Reason} ->
- group_leader() ! {printout,12,
- "WARNING! ~w:end_per_testcase(~w, ~p)"
- " failed!\n\tReason: ~p\n",
- [Mod,Func,Conf,Reason]},
+ print_end_conf_result(Mod,Func,Conf,"failed",Reason),
Starter ! {self(),{call_end_conf,Data,{error,Reason}}};
{'EXIT',_OtherPid,Reason} ->
%% Probably the parent - not much to do about that
@@ -801,28 +761,55 @@ do_call_end_conf(Starter,Mod,Func,Data,Conf,TVal) ->
end,
spawn_link(EndConfProc).
-spawn_fw_call(Mod,{init_per_testcase,Func},CurrConf,Pid,
- {timetrap_timeout,TVal}=Why,
- Loc,SendTo) ->
+print_end_conf_result(Mod,Func,Conf,Cause,Error) ->
+ Str2Print =
+ fun(NoHTML) when NoHTML == stdout; NoHTML == major ->
+ io_lib:format("WARNING! "
+ "~w:end_per_testcase(~w, ~tp)"
+ " ~s!\n\tReason: ~tp\n",
+ [Mod,Func,Conf,Cause,Error]);
+ (minor) ->
+ ErrorStr = test_server_ctrl:escape_chars(Error),
+ io_lib:format("WARNING! "
+ "~w:end_per_testcase(~w, ~tp)"
+ " ~s!\n\tReason: ~ts\n",
+ [Mod,Func,Conf,Cause,ErrorStr])
+ end,
+ group_leader() ! {printout,12,Str2Print}.
+
+
+spawn_fw_call(Mod,IPTC={init_per_testcase,Func},CurrConf,Pid,
+ Why,Loc,SendTo) ->
FwCall =
fun() ->
Skip = {skip,{failed,{Mod,init_per_testcase,Why}}},
%% if init_per_testcase fails, the test case
%% should be skipped
- try do_end_tc_call(Mod,Func, {Pid,Skip,[CurrConf]}, Why) of
+ try begin do_end_tc_call(Mod,IPTC, {Pid,Skip,[CurrConf]}, Why),
+ do_init_tc_call(Mod,{end_per_testcase,Func},
+ [CurrConf],{ok,[CurrConf]}),
+ do_end_tc_call(Mod,{end_per_testcase,Func},
+ {Pid,Skip,[CurrConf]}, Why) end of
_ -> ok
catch
_:FwEndTCErr ->
exit({fw_notify_done,end_tc,FwEndTCErr})
end,
+ Time = case Why of
+ {timetrap_timeout,TVal} -> TVal/1000;
+ _ -> died
+ end,
+ group_leader() ! {printout,12,
+ "ERROR! ~w:init_per_testcase(~w, ~p)"
+ " failed!\n\tReason: ~tp\n",
+ [Mod,Func,CurrConf,Why]},
%% finished, report back
- SendTo ! {self(),fw_notify_done,
- {TVal/1000,Skip,Loc,[],undefined}}
+ SendTo ! {self(),fw_notify_done,{Time,Skip,Loc,[],undefined}}
end,
spawn_link(FwCall);
-spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid,
- {timetrap_timeout,TVal}=Why,_Loc,SendTo) ->
+spawn_fw_call(Mod,EPTC={end_per_testcase,Func},EndConf,Pid,
+ Why,_Loc,SendTo) ->
FwCall =
fun() ->
{RetVal,Report} =
@@ -836,24 +823,38 @@ spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid,
E = {failed,{Mod,end_per_testcase,Why}},
{Result,E}
end,
- group_leader() ! {printout,12,
- "WARNING! ~w:end_per_testcase(~w, ~p)"
- " failed!\n\tReason: timetrap timeout"
- " after ~w ms!\n", [Mod,Func,EndConf,TVal]},
- FailLoc = proplists:get_value(tc_fail_loc, EndConf),
- try do_end_tc_call(Mod,Func,
- {Pid,Report,[EndConf]}, Why) of
+ {Time,Warn} =
+ case Why of
+ {timetrap_timeout,TVal} ->
+ group_leader() !
+ {printout,12,
+ "WARNING! ~w:end_per_testcase(~w, ~p)"
+ " failed!\n\tReason: timetrap timeout"
+ " after ~w ms!\n", [Mod,Func,EndConf,TVal]},
+ W = "<font color=\"red\">"
+ "WARNING: end_per_testcase timed out!</font>",
+ {TVal/1000,W};
+ _ ->
+ group_leader() !
+ {printout,12,
+ "WARNING! ~w:end_per_testcase(~w, ~p)"
+ " failed!\n\tReason: ~tp\n",
+ [Mod,Func,EndConf,Why]},
+ W = "<font color=\"red\">"
+ "WARNING: end_per_testcase failed!</font>",
+ {died,W}
+ end,
+ try do_end_tc_call(Mod,EPTC,{Pid,Report,[EndConf]}, Why) of
_ -> ok
catch
_:FwEndTCErr ->
exit({fw_notify_done,end_tc,FwEndTCErr})
end,
- Warn = "<font color=\"red\">"
- "WARNING: end_per_testcase timed out!</font>",
+ FailLoc = proplists:get_value(tc_fail_loc, EndConf),
%% finished, report back (if end_per_testcase fails, a warning
%% should be printed as part of the comment)
SendTo ! {self(),fw_notify_done,
- {TVal/1000,RetVal,FailLoc,[],Warn}}
+ {Time,RetVal,FailLoc,[],Warn}}
end,
spawn_link(FwCall);
@@ -876,10 +877,12 @@ spawn_fw_call(FwMod,FwFunc,_,_Pid,{framework_error,FwError},_,SendTo) ->
spawn_link(FwCall);
spawn_fw_call(Mod,Func,CurrConf,Pid,Error,Loc,SendTo) ->
- Func1 = case Func of
- {_InitOrEndPerTC,F} -> F;
- F -> F
- end,
+ {Func1,EndTCFunc} = case Func of
+ CF when CF == init_per_suite; CF == end_per_suite;
+ CF == init_per_group; CF == end_per_group ->
+ {CF,CF};
+ TC -> {TC,{end_per_testcase,TC}}
+ end,
FwCall =
fun() ->
try fw_error_notify(Mod,Func1,[],
@@ -891,8 +894,7 @@ spawn_fw_call(Mod,Func,CurrConf,Pid,Error,Loc,SendTo) ->
FwErrorNotifyErr})
end,
Conf = [{tc_status,{failed,Error}}|CurrConf],
- try do_end_tc_call(Mod,Func1,
- {Pid,Error,[Conf]},Error) of
+ try do_end_tc_call(Mod,EndTCFunc,{Pid,Error,[Conf]},Error) of
_ -> ok
catch
_:FwEndTCErr ->
@@ -949,6 +951,16 @@ job_proxy_msgloop() ->
end,
job_proxy_msgloop().
+-spec run_test_case_eval_fun(_, _, _, _, _, _, _, _, _) ->
+ fun(() -> no_return()).
+run_test_case_eval_fun(Mod, Func, Args, Name, Ref, RunInit,
+ TimetrapData, LogOpts, TCCallback) ->
+ fun () ->
+ run_test_case_eval(Mod, Func, Args, Name, Ref,
+ RunInit, TimetrapData,
+ LogOpts, TCCallback)
+ end.
+
%% A test case is known to have failed if it returns {'EXIT', _} tuple,
%% or sends a message {failed, File, Line} to it's group_leader
@@ -959,32 +971,38 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
Where = [{Mod,Func}],
put(test_server_loc, Where),
- FWInitResult = test_server_sup:framework_call(init_tc,[Mod,Func,Args0],
- {ok,Args0}),
+ FWInitFunc = case RunInit of
+ run_init -> {init_per_testcase,Func};
+ _ -> Func
+ end,
+
+ FWInitResult0 = do_init_tc_call(Mod,FWInitFunc,Args0,{ok,Args0}),
+
set_tc_state(running),
{{Time,Value},Loc,Opts} =
- case FWInitResult of
+ case FWInitResult0 of
{ok,Args} ->
run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback);
Error = {error,_Reason} ->
- NewResult = do_end_tc_call(Mod,Func, {Error,Args0},
+ NewResult = do_end_tc_call(Mod,FWInitFunc, {Error,Args0},
{auto_skip,{failed,Error}}),
{{0,NewResult},Where,[]};
{fail,Reason} ->
- Conf = [{tc_status,{failed,Reason}} | hd(Args0)],
+ Conf = [{tc_status,{failed,Reason}} | hd(Args0)],
fw_error_notify(Mod, Func, Conf, Reason),
- NewResult = do_end_tc_call(Mod,Func, {{error,Reason},[Conf]},
+ NewResult = do_end_tc_call(Mod,FWInitFunc,
+ {{error,Reason},[Conf]},
{fail,Reason}),
{{0,NewResult},Where,[]};
Skip = {SkipType,_Reason} when SkipType == skip;
SkipType == skipped ->
- NewResult = do_end_tc_call(Mod,Func,
+ NewResult = do_end_tc_call(Mod,FWInitFunc,
{Skip,Args0}, Skip),
{{0,NewResult},Where,[]};
AutoSkip = {auto_skip,_Reason} ->
%% special case where a conf case "pretends" to be skipped
NewResult =
- do_end_tc_call(Mod,Func, {AutoSkip,Args0}, AutoSkip),
+ do_end_tc_call(Mod,FWInitFunc, {AutoSkip,Args0}, AutoSkip),
{{0,NewResult},Where,[]}
end,
exit({Ref,Time,Value,Loc,Opts}).
@@ -999,31 +1017,41 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
SkipType == skipped ->
Line = get_loc(),
Conf = [{tc_status,{skipped,Reason}}|hd(Args)],
- NewRes = do_end_tc_call(Mod,Func,
+ NewRes = do_end_tc_call(Mod,{init_per_testcase,Func},
{Skip,[Conf]}, Skip),
{{0,NewRes},Line,[]};
{skip_and_save,Reason,SaveCfg} ->
Line = get_loc(),
Conf = [{tc_status,{skipped,Reason}},
{save_config,SaveCfg}|hd(Args)],
- NewRes = do_end_tc_call(Mod,Func, {{skip,Reason},[Conf]},
+ NewRes = do_end_tc_call(Mod,{init_per_testcase,Func},
+ {{skip,Reason},[Conf]},
{skip,Reason}),
{{0,NewRes},Line,[]};
FailTC = {fail,Reason} -> % user fails the testcase
EndConf = [{tc_status,{failed,Reason}} | hd(Args)],
fw_error_notify(Mod, Func, EndConf, Reason),
- NewRes = do_end_tc_call(Mod,Func,
+ NewRes = do_end_tc_call(Mod,{init_per_testcase,Func},
{{error,Reason},[EndConf]},
FailTC),
{{0,NewRes},[{Mod,Func}],[]};
{ok,NewConf} ->
- %% call user callback function if defined
- NewConf1 =
- user_callback(TCCallback, Mod, Func, init, NewConf),
- %% save current state in controller loop
- set_tc_state(tc, NewConf1),
- %% execute the test case
- {{T,Return},Loc} = {ts_tc(Mod,Func,[NewConf1]), get_loc()},
+ IPTCEndRes = do_end_tc_call(Mod,{init_per_testcase,Func},
+ {ok,[NewConf]}, NewConf),
+ {{T,Return},Loc,NewConf1} =
+ if not is_list(IPTCEndRes) ->
+ %% received skip or fail, not config
+ {{0,IPTCEndRes},undefined,NewConf};
+ true ->
+ %% call user callback function if defined
+ NewConfUC =
+ user_callback(TCCallback, Mod, Func,
+ init, IPTCEndRes),
+ %% save current state in controller loop
+ set_tc_state(tc, NewConfUC),
+ %% execute the test case
+ {ts_tc(Mod,Func,[NewConfUC]),get_loc(),NewConfUC}
+ end,
{EndConf,TSReturn,FWReturn} =
case Return of
{E,TCError} when E=='EXIT' ; E==failed ->
@@ -1049,36 +1077,47 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
%% call user callback function if defined
EndConf1 =
user_callback(TCCallback, Mod, Func, 'end', EndConf),
+
+ %% We can't handle fails or skips here
+ EndConf2 =
+ case do_init_tc_call(Mod,{end_per_testcase,Func},
+ [EndConf1],{ok,[EndConf1]}) of
+ {ok,[EPTCInitRes]} when is_list(EPTCInitRes) ->
+ EPTCInitRes;
+ _ ->
+ EndConf1
+ end,
+
%% update current state in controller loop
- {FWReturn1,TSReturn1,EndConf2} =
- case end_per_testcase(Mod, Func, EndConf1) of
+ {FWReturn1,TSReturn1,EndConf3} =
+ case end_per_testcase(Mod, Func, EndConf2) of
SaveCfg1={save_config,_} ->
{FWReturn,TSReturn,
[SaveCfg1|lists:keydelete(save_config,1,
- EndConf1)]};
+ EndConf2)]};
{fail,ReasonToFail} ->
%% user has failed the testcase
- fw_error_notify(Mod, Func, EndConf1,
+ fw_error_notify(Mod, Func, EndConf2,
ReasonToFail),
{{error,ReasonToFail},
{failed,ReasonToFail},
- EndConf1};
+ EndConf2};
{failed,{_,end_per_testcase,_}} = Failure when
FWReturn == ok ->
%% unexpected termination in end_per_testcase
%% report this as the result to the framework
- {Failure,TSReturn,EndConf1};
+ {Failure,TSReturn,EndConf2};
_ ->
%% test case result should be reported to
%% framework no matter the status of
%% end_per_testcase
- {FWReturn,TSReturn,EndConf1}
+ {FWReturn,TSReturn,EndConf2}
end,
%% clear current state in controller loop
- case do_end_tc_call(Mod,Func,
- {FWReturn1,[EndConf2]}, TSReturn1) of
+ case do_end_tc_call(Mod,{end_per_testcase,Func},
+ {FWReturn1,[EndConf3]}, TSReturn1) of
{failed,Reason} = NewReturn ->
- fw_error_notify(Mod,Func,EndConf2, Reason),
+ fw_error_notify(Mod,Func,EndConf3, Reason),
{{T,NewReturn},[{Mod,Func}],[]};
NewReturn ->
{{T,NewReturn},Loc,[]}
@@ -1104,7 +1143,38 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
{{T,Return2},Loc,Opts}
end.
+do_init_tc_call(Mod, Func, Res, Return) ->
+ test_server_sup:framework_call(init_tc,[Mod,Func,Res],Return).
+
+do_end_tc_call(Mod, IPTC={init_per_testcase,Func}, Res, Return) ->
+ case Return of
+ {NOk,_} when NOk == auto_skip; NOk == fail;
+ NOk == skip ; NOk == skipped ->
+ {_,Args} = Res,
+ IPTCEndRes =
+ case do_end_tc_call1(Mod, IPTC, Res, Return) of
+ IPTCEndConfig when is_list(IPTCEndConfig) ->
+ IPTCEndConfig;
+ _ ->
+ Args
+ end,
+ EPTCInitRes =
+ case do_init_tc_call(Mod,{end_per_testcase,Func},
+ IPTCEndRes,Return) of
+ {ok,EPTCInitConfig} when is_list(EPTCInitConfig) ->
+ {Return,EPTCInitConfig};
+ _ ->
+ Return
+ end,
+ do_end_tc_call1(Mod, {end_per_testcase,Func},
+ EPTCInitRes, Return);
+ _Ok ->
+ do_end_tc_call1(Mod, IPTC, Res, Return)
+ end;
do_end_tc_call(Mod, Func, Res, Return) ->
+ do_end_tc_call1(Mod, Func, Res, Return).
+
+do_end_tc_call1(Mod, Func, Res, Return) ->
FwMod = os:getenv("TEST_SERVER_FRAMEWORK"),
Ref = make_ref(),
if FwMod == "ct_framework" ; FwMod == "undefined"; FwMod == false ->
@@ -1243,7 +1313,7 @@ do_init_per_testcase(Mod, Args) ->
Bad ->
group_leader() ! {printout,12,
"ERROR! init_per_testcase has returned "
- "bad elements in Config: ~p\n",[Bad]},
+ "bad elements in Config: ~tp\n",[Bad]},
{skip,{failed,{Mod,init_per_testcase,bad_return}}}
end;
{fail,_Reason}=Res ->
@@ -1261,25 +1331,33 @@ do_init_per_testcase(Mod, Args) ->
throw:Other ->
set_loc(erlang:get_stacktrace()),
Line = get_loc(),
- FormattedLoc = test_server_sup:format_loc(Line),
- group_leader() ! {printout,12,
- "ERROR! init_per_testcase thrown!\n"
- "\tLocation: ~ts\n\tReason: ~p\n",
- [FormattedLoc, Other]},
+ print_init_conf_result(Line,"thrown",Other),
{skip,{failed,{Mod,init_per_testcase,Other}}};
_:Reason0 ->
Stk = erlang:get_stacktrace(),
Reason = {Reason0,Stk},
set_loc(Stk),
Line = get_loc(),
- FormattedLoc = test_server_sup:format_loc(Line),
- group_leader() ! {printout,12,
- "ERROR! init_per_testcase crashed!\n"
- "\tLocation: ~ts\n\tReason: ~p\n",
- [FormattedLoc,Reason]},
+ print_init_conf_result(Line,"crashed",Reason),
{skip,{failed,{Mod,init_per_testcase,Reason}}}
end.
+print_init_conf_result(Line,Cause,Reason) ->
+ FormattedLoc = test_server_sup:format_loc(Line),
+ Str2Print =
+ fun(NoHTML) when NoHTML == stdout; NoHTML == major ->
+ io_lib:format("ERROR! init_per_testcase ~s!\n"
+ "\tLocation: ~p\n\tReason: ~tp\n",
+ [Cause,Line,Reason]);
+ (minor) ->
+ ReasonStr = test_server_ctrl:escape_chars(Reason),
+ io_lib:format("ERROR! init_per_testcase ~s!\n"
+ "\tLocation: ~ts\n\tReason: ~ts\n",
+ [Cause,FormattedLoc,ReasonStr])
+ end,
+ group_leader() ! {printout,12,Str2Print}.
+
+
end_per_testcase(Mod, Func, Conf) ->
case erlang:function_exported(Mod,end_per_testcase,2) of
true ->
@@ -1314,12 +1392,7 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) ->
comment(io_lib:format("~ts<font color=\"red\">"
"WARNING: ~w thrown!"
"</font>\n",[Comment0,EndFunc])),
- group_leader() ! {printout,12,
- "WARNING: ~w thrown!\n"
- "Reason: ~p\n"
- "Line: ~ts\n",
- [EndFunc, Other,
- test_server_sup:format_loc(get_loc())]},
+ print_end_tc_warning(EndFunc,Other,"thrown",get_loc()),
{failed,{Mod,end_per_testcase,Other}};
Class:Reason ->
Stk = erlang:get_stacktrace(),
@@ -1336,15 +1409,25 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) ->
comment(io_lib:format("~ts<font color=\"red\">"
"WARNING: ~w crashed!"
"</font>\n",[Comment0,EndFunc])),
- group_leader() ! {printout,12,
- "WARNING: ~w crashed!\n"
- "Reason: ~p\n"
- "Line: ~ts\n",
- [EndFunc, Reason,
- test_server_sup:format_loc(get_loc())]},
+ print_end_tc_warning(EndFunc,Reason,"crashed",get_loc()),
{failed,{Mod,end_per_testcase,Why}}
end.
+print_end_tc_warning(EndFunc,Reason,Cause,Loc) ->
+ FormattedLoc = test_server_sup:format_loc(Loc),
+ Str2Print =
+ fun(NoHTML) when NoHTML == stdout; NoHTML == major ->
+ io_lib:format("WARNING: ~w ~s!\n"
+ "Reason: ~tp\nLine: ~p\n",
+ [EndFunc,Cause,Reason,Loc]);
+ (minor) ->
+ ReasonStr = test_server_ctrl:escape_chars(Reason),
+ io_lib:format("WARNING: ~w ~s!\n"
+ "Reason: ~ts\nLine: ~ts\n",
+ [EndFunc,Cause,ReasonStr,FormattedLoc])
+ end,
+ group_leader() ! {printout,12,Str2Print}.
+
get_loc() ->
get(test_server_loc).
@@ -1445,7 +1528,7 @@ lookup_config(Key,Config) ->
%% stack traces. If the name changes, get_loc/1 must be updated!
%%
ts_tc(M, F, A) ->
- Before = erlang:now(),
+ Before = erlang:monotonic_time(),
Result = try
apply(M, F, A)
catch
@@ -1465,12 +1548,8 @@ ts_tc(M, F, A) ->
{'EXIT',Reason}
end
end,
- After = erlang:now(),
- Elapsed =
- (element(1,After)*1000000000000
- +element(2,After)*1000000+element(3,After)) -
- (element(1,Before)*1000000000000
- +element(2,Before)*1000000+element(3,Before)),
+ After = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(After-Before, native, micro_seconds),
{Elapsed, Result}.
set_loc(Stk) ->
@@ -1889,7 +1968,7 @@ time_ms_check(Other) ->
time_ms_apply(Func, TCPid, MultAndScale) ->
{_,GL} = process_info(TCPid, group_leader),
WhoAmI = self(), % either TC or IO server
- T0 = now(),
+ T0 = erlang:monotonic_time(),
UserTTSup =
spawn(fun() ->
user_timetrap_supervisor(Func, WhoAmI, TCPid,
@@ -1922,7 +2001,8 @@ user_timetrap_supervisor(Func, Spawner, TCPid, GL, T0, MultAndScale) ->
receive
{UserTT,Result} ->
demonitor(MonRef, [flush]),
- Elapsed = trunc(timer:now_diff(now(), T0) / 1000),
+ T1 = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(T1-T0, native, milli_seconds),
try time_ms_check(Result) of
TimeVal ->
%% this is the new timetrap value to set (return value
@@ -1990,7 +2070,7 @@ update_user_timetraps(TCPid, StartTime) ->
proplists:delete(TCPid, UserTTs)),
proceed;
{OtherUserTTSup,OtherStartTime} ->
- case timer:now_diff(OtherStartTime, StartTime) of
+ case OtherStartTime - StartTime of
Diff when Diff >= 0 ->
ignore;
_ ->
@@ -2085,10 +2165,19 @@ get_timetrap_info(TCPid, SendToServer) ->
Timers ->
case [Info || {Handle,Pid,Info} <- Timers,
Pid == TCPid, Handle /= infinity] of
- [I|_] ->
- I;
+ [{TVal,true}|_] ->
+ {TVal,{true,test_server:timetrap_scale_factor()}};
+ [{TVal,false}|_] ->
+ {TVal,{false,1}};
[] when SendToServer == true ->
- tc_supervisor_req({get_timetrap_info,TCPid});
+ case tc_supervisor_req({get_timetrap_info,TCPid}) of
+ {TVal,true} ->
+ {TVal,{true,test_server:timetrap_scale_factor()}};
+ {TVal,false} ->
+ {TVal,{false,1}};
+ Error ->
+ Error
+ end;
[] ->
undefined
end
@@ -2445,24 +2534,15 @@ is_release_available(Release) ->
%%
run_on_shielded_node(Fun, CArgs) when is_function(Fun), is_list(CArgs) ->
- {A,B,C} = now(),
- Name = "shielded_node-" ++ integer_to_list(A) ++ "-" ++ integer_to_list(B)
- ++ "-" ++ integer_to_list(C),
+ Nr = erlang:unique_integer([positive]),
+ Name = "shielded_node-" ++ integer_to_list(Nr),
Node = case start_node(Name, slave, [{args, "-hidden " ++ CArgs}]) of
{ok, N} -> N;
Err -> fail({failed_to_start_shielded_node, Err})
end,
Master = self(),
Ref = make_ref(),
- Slave = spawn(Node,
- fun () ->
- start_job_proxy(),
- receive
- Ref ->
- Master ! {Ref, Fun()}
- end,
- receive after infinity -> infinity end
- end),
+ Slave = spawn(Node, start_job_proxy_fun(Master, Fun)),
MRef = erlang:monitor(process, Slave),
Slave ! Ref,
receive
@@ -2477,6 +2557,17 @@ run_on_shielded_node(Fun, CArgs) when is_function(Fun), is_list(CArgs) ->
end
end.
+-spec start_job_proxy_fun(_, _) -> fun(() -> no_return()).
+start_job_proxy_fun(Master, Fun) ->
+ fun () ->
+ start_job_proxy(),
+ receive
+ Ref ->
+ Master ! {Ref, Fun()}
+ end,
+ receive after infinity -> infinity end
+ end.
+
%% Return true if Name or node() is a shielded node
is_shielded(Name) ->
case {cast_to_list(Name),atom_to_list(node())} of
@@ -2506,9 +2597,8 @@ is_cover(Name) ->
%% A filename of the form <Stem><Number> is generated, and the
%% function checks that that file doesn't already exist.
temp_name(Stem) ->
- {A,B,C} = erlang:now(),
- RandomNum = A bxor B bxor C,
- RandomName = Stem ++ integer_to_list(RandomNum),
+ Num = erlang:unique_integer([positive]),
+ RandomName = Stem ++ integer_to_list(Num),
{ok,Files} = file:list_dir(filename:dirname(Stem)),
case lists:member(RandomName,Files) of
true ->
@@ -2538,11 +2628,7 @@ appup_test(App) ->
%% Checks wether the module is natively compiled or not.
is_native(Mod) ->
- case catch Mod:module_info(native_addresses) of
- [_|_] -> true;
- _Other -> false
- end.
-
+ (catch Mod:module_info(native)) =:= true.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% comment(String) -> ok
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 68b03a5987..e0975ab744 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -76,7 +77,7 @@
-export([handle_call/3, handle_cast/2, handle_info/2]).
-export([do_test_cases/4]).
-export([do_spec/2, do_spec_list/2]).
--export([xhtml/2]).
+-export([xhtml/2, escape_chars/1]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -99,7 +100,7 @@
-define(last_link, "last_link").
-define(last_test, "last_test").
-define(html_ext, ".html").
--define(now, erlang:now()).
+-define(now, os:timestamp()).
-define(void_fun, fun() -> ok end).
-define(mod_result(X), if X == skip -> skipped;
@@ -1204,19 +1205,14 @@ init_tester(Mod, Func, Args, Dir, Name, {_,_,MinLev}=Levels,
report_severe_error(Reason) ->
test_server_sup:framework_call(report, [severe_error,Reason]).
-%% timer:tc/3
-ts_tc(M, F, A) ->
- Before = ?now,
- Val = (catch apply(M, F, A)),
- After = ?now,
- Elapsed = elapsed_time(Before, After),
- {Elapsed,Val}.
-
-elapsed_time(Before, After) ->
- (element(1,After)*1000000000000 +
- element(2,After)*1000000 + element(3,After)) -
- (element(1,Before)*1000000000000 +
- element(2,Before)*1000000 + element(3,Before)).
+ts_tc(M,F,A) ->
+ Before = erlang:monotonic_time(),
+ Result = (catch apply(M, F, A)),
+ After = erlang:monotonic_time(),
+ Elapsed = erlang:convert_time_unit(After-Before,
+ native,
+ micro_seconds),
+ {Elapsed, Result}.
start_extra_tools(ExtraTools) ->
start_extra_tools(ExtraTools, []).
@@ -1812,26 +1808,32 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName, MFA) ->
io:put_chars(Fd, "<pre>\n"),
SrcListing = downcase(atom_to_list(Mod)) ++ ?src_listing_ext,
-
- {Info,Arity} =
- if Func == init_per_suite; Func == end_per_suite ->
- {"Config function: ", 1};
- Func == init_per_group; Func == end_per_group ->
- {"Config function: ", 2};
- true ->
- {"Test case: ", 1}
- end,
- case {filelib:is_file(filename:join(LogDir, SrcListing)),
- lists:member(no_src, get(test_server_logopts))} of
- {true,false} ->
- print(Lev, Info ++ "<a href=\"~ts#~ts\">~w:~w/~w</a> "
- "(click for source code)\n",
- [uri_encode(SrcListing),
- uri_encode(atom_to_list(Func)++"-1",utf8),
- Mod,Func,Arity]);
+ case get_fw_mod(?MODULE) of
+ Mod when Func == error_in_suite ->
+ ok;
_ ->
- print(Lev, Info ++ "~w:~w/~w\n", [Mod,Func,Arity])
+ {Info,Arity} =
+ if Func == init_per_suite; Func == end_per_suite ->
+ {"Config function: ", 1};
+ Func == init_per_group; Func == end_per_group ->
+ {"Config function: ", 2};
+ true ->
+ {"Test case: ", 1}
+ end,
+
+ case {filelib:is_file(filename:join(LogDir, SrcListing)),
+ lists:member(no_src, get(test_server_logopts))} of
+ {true,false} ->
+ print(Lev, ["$tc_html",
+ Info ++ "<a href=\"~ts#~ts\">~w:~w/~w</a> "
+ "(click for source code)\n"],
+ [uri_encode(SrcListing),
+ uri_encode(atom_to_list(Func)++"-1",utf8),
+ Mod,Func,Arity]);
+ _ ->
+ print(Lev, ["$tc_html",Info ++ "~w:~w/~w\n"], [Mod,Func,Arity])
+ end
end,
AbsName.
@@ -2025,7 +2027,7 @@ add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod,
PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod,
NextRef, FwMod)];
add_init_and_end_per_suite([SkipCase|Cases], LastMod, LastRef, FwMod)
- when element(1,SkipCase) == skip_case ->
+ when element(1,SkipCase) == skip_case; element(1,SkipCase) == auto_skip_case->
[SkipCase|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)];
add_init_and_end_per_suite([{conf,_,_,_}=Case|Cases], LastMod, LastRef, FwMod) ->
[Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)];
@@ -2490,7 +2492,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
file:set_cwd(filename:dirname(get(test_server_dir))),
After = ?now,
Before = get(test_server_parallel_start_time),
- Elapsed = elapsed_time(Before, After)/1000000,
+ Elapsed = timer:now_diff(After, Before)/1000000,
put(test_server_total_time, Elapsed),
{false,tl(Mode0),undefined,Elapsed,
update_status(Ref, OkSkipFail, Status)};
@@ -2499,7 +2501,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
%% parallel group (io buffering is active)
OkSkipFail = wait_for_cases(Ref),
queue_test_case_io(Ref, self(), 0, Mod, Func),
- Elapsed = elapsed_time(conf_start(Ref, Mode0),?now)/1000000,
+ Elapsed = timer:now_diff(?now, conf_start(Ref, Mode0))/1000000,
case CurrIOHandler of
{Ref,_} ->
%% current_io_handler was set by start conf of this
@@ -2516,12 +2518,12 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
%% this is an end conf for a non-parallel group that's not
%% nested under a parallel group, so no need to buffer io
{false,tl(Mode0),undefined,
- elapsed_time(conf_start(Ref, Mode0),?now)/1000000, Status};
+ timer:now_diff(?now, conf_start(Ref, Mode0))/1000000, Status};
{Ref,_} ->
%% this is an end conf for a non-parallel group nested under
%% a parallel group (io buffering is active)
queue_test_case_io(Ref, self(), 0, Mod, Func),
- Elapsed = elapsed_time(conf_start(Ref, Mode0),?now)/1000000,
+ Elapsed = timer:now_diff(?now, conf_start(Ref, Mode0))/1000000,
case CurrIOHandler of
{Ref,_} ->
%% current_io_handler was set by start conf of this
@@ -2576,7 +2578,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
%% 1. check the TS_RANDOM_SEED env variable
%% 2. check random_seed in process state
%% 3. use value provided with shuffle option
- %% 4. use now() values for seed
+ %% 4. use timestamp() values for seed
case os:getenv("TS_RANDOM_SEED") of
Undef when Undef == false ; Undef == "undefined" ->
case get(test_server_random_seed) of
@@ -3710,8 +3712,8 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
RunDir = filename:dirname(MinorName),
Ext =
if Num == 0 ->
- {_,S,Us} = now(),
- lists:flatten(io_lib:format(".~w.~w", [S,Us]));
+ Int = erlang:unique_integer([positive,monotonic]),
+ lists:flatten(io_lib:format(".cfg.~w", [Int]));
true ->
lists:flatten(io_lib:format(".~w", [Num]))
end,
@@ -3740,7 +3742,10 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
true ->
ok
end,
- print(minor, "Config value:\n\n ~tp\n", [Args2Print]),
+
+ print(minor,
+ escape_chars(io_lib:format("Config value:\n\n ~tp\n", [Args2Print])),
+ []),
print(minor, "Current directory is ~tp\n", [Cwd]),
GrNameStr = case GrName of
@@ -3755,7 +3760,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
"<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
"<td><a href=\"~ts\">~w</a></td>"
- "<td><a href=\"~ts#top\"><</a> <a href=\"~ts#end\">></a></td>",
+ "<td><a href=\"~ts#top\">&lt;</a> <a href=\"~ts#end\">&gt;</a></td>",
[num2str(Num),fw_name(Mod),GrNameStr,EncMinorBase,Func,
EncMinorBase,EncMinorBase]),
@@ -3932,7 +3937,7 @@ progress(skip, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},
{ReportTag,Reason1}}]),
- ReasonStr = reason_to_string(Reason1),
+ ReasonStr = escape_chars(reason_to_string(Reason1)),
ReasonStr1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(ReasonStr,[$\n])]),
ReasonStr2 =
@@ -3951,8 +3956,8 @@ progress(skip, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
"<td>~ts~ts</td></tr>\n",
[Time,Color,ReasonStr2,Comment1]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~ts", [FormatLoc]),
- print(minor, "=== reason = ~ts", [ReasonStr1]),
+ print(minor, "=== Location: ~ts", [FormatLoc]),
+ print(minor, "=== Reason: ~ts", [ReasonStr1]),
Ret;
progress(failed, CaseNum, Mod, Func, GrName, Loc, timetrap_timeout, T,
@@ -3977,8 +3982,8 @@ progress(failed, CaseNum, Mod, Func, GrName, Loc, timetrap_timeout, T,
"<td>~ts</td></tr>\n",
[T/1000,Comment]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~ts", [FormatLoc]),
- print(minor, "=== reason = timetrap timeout", []),
+ print(minor, "=== Location: ~ts", [FormatLoc]),
+ print(minor, "=== Reason: timetrap timeout", []),
failed;
progress(failed, CaseNum, Mod, Func, GrName, Loc, {testcase_aborted,Reason}, _T,
@@ -4003,13 +4008,16 @@ progress(failed, CaseNum, Mod, Func, GrName, Loc, {testcase_aborted,Reason}, _T,
"<td>~ts</td></tr>\n",
[Comment]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~ts", [FormatLoc]),
- print(minor, "=== reason = {testcase_aborted,~p}", [Reason]),
+ print(minor, "=== Location: ~ts", [FormatLoc]),
+ print(minor,
+ escape_chars(io_lib:format("=== Reason: {testcase_aborted,~p}",
+ [Reason])),
+ []),
failed;
progress(failed, CaseNum, Mod, Func, GrName, unknown, Reason, Time,
Comment0, {St0,St1}) ->
- print(major, "=result failed: ~p, ~w", [Reason,unknown]),
+ print(major, "=result failed: ~p, ~w", [Reason,unknown_location]),
print(1, "*** FAILED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},
@@ -4017,7 +4025,7 @@ progress(failed, CaseNum, Mod, Func, GrName, unknown, Reason, Time,
TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
true -> "~w"
end, [Time]),
- ErrorReason = lists:flatten(io_lib:format("~p", [Reason])),
+ ErrorReason = escape_chars(lists:flatten(io_lib:format("~p", [Reason]))),
ErrorReason1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(ErrorReason,[$\n])]),
ErrorReason2 =
@@ -4038,14 +4046,23 @@ progress(failed, CaseNum, Mod, Func, GrName, unknown, Reason, Time,
"<td><font color=\"red\">FAILED</font></td>"
"<td>~ts</td></tr>\n",
[TimeStr,Comment]),
- print(minor, "=== location ~w", [unknown]),
+ print(minor, "=== Location: ~w", [unknown]),
{FStr,FormattedReason} = format_exception(Reason),
- print(minor, "=== reason = " ++ FStr, [FormattedReason]),
+ print(minor,
+ escape_chars(io_lib:format("=== Reason: " ++ FStr, [FormattedReason])),
+ []),
failed;
progress(failed, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
Comment0, {St0,St1}) ->
- print(major, "=result failed: ~p, ~p", [Reason,Loc]),
+ {LocMaj,LocMin} = if Func == error_in_suite ->
+ case get_fw_mod(undefined) of
+ Mod -> {unknown_location,unknown};
+ _ -> {Loc,Loc}
+ end;
+ true -> {Loc,Loc}
+ end,
+ print(major, "=result failed: ~p, ~p", [Reason,LocMaj]),
print(1, "*** FAILED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},
@@ -4058,16 +4075,17 @@ progress(failed, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
"" -> "";
_ -> xhtml("<br>","<br />") ++ to_string(Comment0)
end,
- FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)),
+ FormatLastLoc = test_server_sup:format_loc(get_last_loc(LocMaj)),
print(html,
"<td>" ++ St0 ++ "~ts" ++ St1 ++ "</td>"
"<td><font color=\"red\">FAILED</font></td>"
"<td><font color=\"red\">~ts</font>~ts</td></tr>\n",
[TimeStr,FormatLastLoc,Comment]),
- FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~ts", [FormatLoc]),
+ FormatLoc = test_server_sup:format_loc(LocMin),
+ print(minor, "=== Location: ~ts", [FormatLoc]),
{FStr,FormattedReason} = format_exception(Reason),
- print(minor, "=== reason = " ++ FStr, [FormattedReason]),
+ print(minor, "=== Reason: " ++
+ escape_chars(io_lib:format(FStr, [FormattedReason])), []),
failed;
progress(ok, _CaseNum, Mod, Func, GrName, _Loc, RetVal, Time,
@@ -4096,11 +4114,36 @@ progress(ok, _CaseNum, Mod, Func, GrName, _Loc, RetVal, Time,
"<td><font color=\"green\">Ok</font></td>"
"~ts</tr>\n",
[Time,Comment]),
- print(minor, "=== returned value = ~p", [RetVal]),
+ print(minor,
+ escape_chars(io_lib:format("=== Returned value: ~tp", [RetVal])),
+ []),
ok.
%%--------------------------------------------------------------------
%% various help functions
+escape_chars(Term) when not is_list(Term), not is_binary(Term) ->
+ esc_chars_in_list(io_lib:format("~tp", [Term]));
+escape_chars(List = [Term | _]) when not is_list(Term), not is_integer(Term) ->
+ esc_chars_in_list(io_lib:format("~tp", [List]));
+escape_chars(List) ->
+ esc_chars_in_list(List).
+
+esc_chars_in_list([Bin | Io]) when is_binary(Bin) ->
+ [Bin | esc_chars_in_list(Io)];
+esc_chars_in_list([List | Io]) when is_list(List) ->
+ [esc_chars_in_list(List) | esc_chars_in_list(Io)];
+esc_chars_in_list([$< | Io]) ->
+ ["&lt;" | esc_chars_in_list(Io)];
+esc_chars_in_list([$> | Io]) ->
+ ["&gt;" | esc_chars_in_list(Io)];
+esc_chars_in_list([$& | Io]) ->
+ ["&amp;" | esc_chars_in_list(Io)];
+esc_chars_in_list([Char | Io]) when is_integer(Char) ->
+ [Char | esc_chars_in_list(Io)];
+esc_chars_in_list([]) ->
+ [];
+esc_chars_in_list(Bin) ->
+ Bin.
get_fw_mod(Mod) ->
case get(test_server_framework) of
@@ -4314,6 +4357,10 @@ print(Detail, Format) ->
print(Detail, Format, Args) ->
print(Detail, Format, Args, internal).
+print(Detail, ["$tc_html",Format], Args, Printer) ->
+ Msg = io_lib:format(Format, Args),
+ print_or_buffer(Detail, ["$tc_html",Msg], Printer);
+
print(Detail, Format, Args, Printer) ->
Msg = io_lib:format(Format, Args),
print_or_buffer(Detail, Msg, Printer).
@@ -4684,10 +4731,10 @@ collect_cases({make,InitMFA,CaseList,FinMFA}, St0, Mode) ->
collect_cases({Module, Cases}, St, Mode) when is_list(Cases) ->
case (catch collect_case(Cases, St#cc{mod=Module}, [], Mode)) of
- {ok, NewCases, NewSt} ->
- {ok, NewCases, NewSt};
+ Result = {ok,_,_} ->
+ Result;
Other ->
- {error, Other}
+ {error,Other}
end;
collect_cases({_Mod,_Case}=Spec, St, Mode) ->
@@ -4705,9 +4752,9 @@ collect_case({Mod,{conf,_,_,_,_}=Conf}, St, Mode) ->
collect_case(MFA, St, Mode) ->
case in_skip_list(MFA, St#cc.skip) of
- {true,Comment} ->
+ {true,Comment} when Comment /= make_failed ->
{ok,[{skip_case,{MFA,Comment},Mode}],St};
- false ->
+ _ ->
case MFA of
{Mod,Case} -> collect_case_invoke(Mod, Case, MFA, St, Mode);
{_Mod,_Case,_Args} -> {ok,[MFA],St}
@@ -4769,17 +4816,25 @@ collect_case_subcases(Mod, Case, SubCases, St0, Mode) ->
collect_files(Dir, Pattern, St, Mode) ->
{ok,Cwd} = file:get_cwd(),
Dir1 = filename:join(Cwd, Dir),
- Wc = filename:join([Dir1,Pattern++code:objfile_extension()]),
+ Wc = filename:join([Dir1,Pattern++"{.erl,"++code:objfile_extension()++"}"]),
case catch filelib:wildcard(Wc) of
{'EXIT', Reason} ->
io:format("Could not collect files: ~p~n", [Reason]),
{error,{collect_fail,Dir,Pattern}};
- Mods0 ->
- Mods = [{path_to_module(Mod),all} || Mod <- lists:sort(Mods0)],
- collect_cases(Mods, St, Mode)
+ Files ->
+ %% convert to module names and remove duplicates
+ Mods = lists:foldl(fun(File, Acc) ->
+ Mod = fullname_to_mod(File),
+ case lists:member(Mod, Acc) of
+ true -> Acc;
+ false -> [Mod | Acc]
+ end
+ end, [], Files),
+ Tests = [{Mod,all} || Mod <- lists:sort(Mods)],
+ collect_cases(Tests, St, Mode)
end.
-path_to_module(Path) when is_list(Path) ->
+fullname_to_mod(Path) when is_list(Path) ->
%% If this is called with a binary, then we are probably in +fnu
%% mode and have found a beam file with name encoded as latin1. We
%% will let this crash since it can not work to load such a module
@@ -5548,8 +5603,9 @@ html_header(Title) ->
"<html>\n"
"<head>\n"
"<title>", Title, "</title>\n"
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n"
- "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\"></meta>\n"
+ "<meta http-equiv=\"content-type\" content=\"text/html; "
+ "charset=utf-8\"></meta>\n"
"</head>\n"
"<body bgcolor=\"white\" text=\"black\" "
"link=\"blue\" vlink=\"purple\" alink=\"red\">\n"].
diff --git a/lib/test_server/src/test_server_gl.erl b/lib/test_server/src/test_server_gl.erl
index 1f7317c51d..444cfa595f 100644
--- a/lib/test_server/src/test_server_gl.erl
+++ b/lib/test_server/src/test_server_gl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -36,7 +37,8 @@
reject_io :: boolean(), %Reject I/O requests...
permit_io, %... and exceptions
auto_nl=true :: boolean(), %Automatically add NL
- levels %{Stdout,Major,Minor}
+ levels, %{Stdout,Major,Minor}
+ escape_chars=true %Switch escaping HTML on/off
}).
%% start_link()
@@ -129,6 +131,10 @@ set_props(GL, PropList) ->
%%% Internal functions.
init([]) ->
+ EscChars = case application:get_env(test_server, esc_chars) of
+ {ok,ECBool} -> ECBool;
+ _ -> true
+ end,
{ok,#st{tc_supervisor=none,
minor=none,
minor_monitor=none,
@@ -136,7 +142,8 @@ init([]) ->
reject_io=false,
permit_io=gb_sets:empty(),
auto_nl=true,
- levels={1,19,10}
+ levels={1,19,10},
+ escape_chars=EscChars
}}.
req(GL, Req) ->
@@ -181,7 +188,7 @@ handle_info({io_request,From,ReplyAs,Req}=IoReq, St) ->
try io_req(Req, From, St) of
passthrough ->
group_leader() ! IoReq;
- Data ->
+ {EscapeHtml,Data} ->
case is_io_permitted(From, St) of
false ->
ok;
@@ -192,7 +199,13 @@ handle_info({io_request,From,ReplyAs,Req}=IoReq, St) ->
#st{capture=CapturePid} ->
CapturePid ! {captured,Data}
end,
- output(minor, Data, From, From, St)
+ case EscapeHtml andalso St#st.escape_chars of
+ true ->
+ output(minor, test_server_ctrl:escape_chars(Data),
+ From, From, St);
+ false ->
+ output(minor, Data, From, From, St)
+ end
end,
From ! {io_reply,ReplyAs,ok}
catch
@@ -203,9 +216,20 @@ handle_info({io_request,From,ReplyAs,Req}=IoReq, St) ->
handle_info({structured_io,ClientPid,{Detail,Str}}, St) ->
output(Detail, Str, ClientPid, ClientPid, St),
{noreply,St};
+handle_info({printout,Detail,["$tc_html",Format],Args}, St) ->
+ Str = io_lib:format(Format, Args),
+ output(Detail, ["$tc_html",Str], internal, none, St),
+ {noreply,St};
+handle_info({printout,Detail,Fun}, St) when is_function(Fun)->
+ output(Detail, Fun, internal, none, St),
+ {noreply,St};
handle_info({printout,Detail,Format,Args}, St) ->
Str = io_lib:format(Format, Args),
- output(Detail, Str, internal, none, St),
+ if not St#st.escape_chars ->
+ output(Detail, ["$tc_html",Str], internal, none, St);
+ true ->
+ output(Detail, Str, internal, none, St)
+ end,
{noreply,St};
handle_info(Msg, #st{tc_supervisor=Pid}=St) when is_pid(Pid) ->
%% The process overseeing the testcase process also used to be
@@ -230,25 +254,55 @@ do_set_props([{reject_io_reqs,Bool}|Ps], St) ->
do_set_props(Ps, St#st{reject_io=Bool});
do_set_props([], St) -> St.
-io_req({put_chars,Enc,Bytes}, _, _) when Enc =:= latin1; Enc =:= unicode ->
- unicode:characters_to_list(Bytes, Enc);
+io_req({put_chars,Enc,Str}, _, _) when Enc =:= latin1; Enc =:= unicode ->
+ case Str of
+ ["$tc_html",Str0] ->
+ {false,unicode:characters_to_list(Str0, Enc)};
+ _ ->
+ {true,unicode:characters_to_list(Str, Enc)}
+ end;
io_req({put_chars,Encoding,Mod,Func,[Format,Args]}, _, _) ->
- Str = Mod:Func(Format, Args),
- unicode:characters_to_list(Str, Encoding);
+ case Format of
+ ["$tc_html",Format0] ->
+ Str = Mod:Func(Format0, Args),
+ {false,unicode:characters_to_list(Str, Encoding)};
+ _ ->
+ Str = Mod:Func(Format, Args),
+ {true,unicode:characters_to_list(Str, Encoding)}
+ end;
io_req(_, _, _) -> passthrough.
-output(Level, Str, Sender, From, St) when is_integer(Level) ->
+output(Level, StrOrFun, Sender, From, St) when is_integer(Level) ->
case selected_by_level(Level, stdout, St) of
- true -> output(stdout, Str, Sender, From, St);
- false -> ok
+ true when hd(StrOrFun) == "$tc_html" ->
+ output(stdout, tl(StrOrFun), Sender, From, St);
+ true when is_function(StrOrFun) ->
+ output(stdout, StrOrFun(stdout), Sender, From, St);
+ true ->
+ output(stdout, StrOrFun, Sender, From, St);
+ false ->
+ ok
end,
case selected_by_level(Level, major, St) of
- true -> output(major, Str, Sender, From, St);
- false -> ok
+ true when hd(StrOrFun) == "$tc_html" ->
+ output(major, tl(StrOrFun), Sender, From, St);
+ true when is_function(StrOrFun) ->
+ output(major, StrOrFun(major), Sender, From, St);
+ true ->
+ output(major, StrOrFun, Sender, From, St);
+ false ->
+ ok
end,
case selected_by_level(Level, minor, St) of
- true -> output(minor, Str, Sender, From, St);
- false -> ok
+ true when hd(StrOrFun) == "$tc_html" ->
+ output(minor, tl(StrOrFun), Sender, From, St);
+ true when is_function(StrOrFun) ->
+ output(minor, StrOrFun(minor), Sender, From, St);
+ true ->
+ output(minor, test_server_ctrl:escape_chars(StrOrFun),
+ Sender, From, St);
+ false ->
+ ok
end;
output(stdout, Str, _Sender, From, St) ->
output_to_file(stdout, Str, From, St);
diff --git a/lib/test_server/src/test_server_internal.hrl b/lib/test_server/src/test_server_internal.hrl
index bafeeaabfe..1ec2d83417 100644
--- a/lib/test_server/src/test_server_internal.hrl
+++ b/lib/test_server/src/test_server_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -29,7 +30,6 @@
version, % string()
system_version, % string()
root_dir, % string()
- test_server_dir, % string()
emulator, % string()
otp_release, % string()
username, % string()
diff --git a/lib/test_server/src/test_server_io.erl b/lib/test_server/src/test_server_io.erl
index 62af3d5b28..0d881d0ada 100644
--- a/lib/test_server/src/test_server_io.erl
+++ b/lib/test_server/src/test_server_io.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index acd47788db..37f8941d24 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -120,7 +121,7 @@ start_tracer_node(TraceFile,TI) ->
%%%
trace_nodes(Sock,Nodes) ->
Bin = term_to_binary({add_nodes,Nodes}),
- ok = gen_tcp:send(Sock, [1|Bin]),
+ ok = gen_tcp:send(Sock, tag_trace_message(Bin)),
receive_ack(Sock).
@@ -141,7 +142,7 @@ receive_ack(Sock) ->
%%%
stop_tracer_node(Sock) ->
Bin = term_to_binary(id(stop)),
- ok = gen_tcp:send(Sock, [1|Bin]),
+ ok = gen_tcp:send(Sock, tag_trace_message(Bin)),
receive {tcp_closed,Sock} -> gen_tcp:close(Sock) end,
ok.
@@ -170,7 +171,7 @@ trc([TraceFile, PortAtom, Type]) ->
{packet,2}]) of
{ok,Sock} ->
BinResult = term_to_binary(Result),
- ok = gen_tcp:send(Sock,[1|BinResult]),
+ ok = gen_tcp:send(Sock,tag_trace_message(BinResult)),
trc_loop(Sock,Patterns,Type);
_else ->
ok
@@ -186,7 +187,7 @@ trc_loop(Sock,Patterns,Type) ->
{ok,{add_nodes,Nodes}} ->
add_nodes(Nodes,Patterns,Type),
Bin = term_to_binary(id(ok)),
- ok = gen_tcp:send(Sock, [1|Bin]),
+ ok = gen_tcp:send(Sock, tag_trace_message(Bin)),
trc_loop(Sock,Patterns,Type);
{ok,stop} ->
ttb:stop(),
@@ -306,11 +307,11 @@ start_node_peer(SlaveName, OptList, From, TI) ->
HostStr, " ", WaitPort]),
% Support for erl_crash_dump files..
- CrashFile = filename:join([TI#target_info.test_server_dir,
+ CrashDir = test_server_sup:crash_dump_dir(),
+ CrashFile = filename:join([CrashDir,
"erl_crash_dump."++cast_to_list(SlaveName)]),
CrashArgs = lists:concat([" -env ERL_CRASH_DUMP \"",CrashFile,"\" "]),
FailOnError = start_node_get_option_value(fail_on_error, OptList, true),
- Pa = TI#target_info.test_server_dir,
Prog0 = start_node_get_option_value(erl, OptList, default),
Prog = quote_progname(pick_erl_program(Prog0)),
Args =
@@ -321,7 +322,6 @@ start_node_peer(SlaveName, OptList, From, TI) ->
Cmd = lists:concat([Prog,
" -detached ",
TI#target_info.naming, " ", SlaveName,
- " -pa \"", Pa,"\"",
NodeStarted,
CrashArgs,
" ", Args]),
@@ -353,28 +353,31 @@ start_node_peer(SlaveName, OptList, From, TI) ->
I = "=== Not waiting for node",
gen_server:reply(From,{{ok, Nodename}, HostStr, Cmd, I, []}),
Self = self(),
- spawn_link(
- fun() ->
- wait_for_node_started(LSock,Tmo,undefined,
- Cleanup,TI,Self),
- receive after infinity -> ok end
- end),
+ spawn_link(wait_for_node_started_fun(LSock,Tmo,Cleanup,TI,Self)),
ok
end.
+-spec wait_for_node_started_fun(_, _, _, _, _) -> fun(() -> no_return()).
+wait_for_node_started_fun(LSock, Tmo, Cleanup, TI, Self) ->
+ fun() ->
+ wait_for_node_started(LSock,Tmo,undefined,
+ Cleanup,TI,Self),
+ receive after infinity -> ok end
+ end.
+
%%
%% Slave nodes are started on a remote host if
%% - the option remote is given when calling test_server:start_node/3
%%
-start_node_slave(SlaveName, OptList, From, TI) ->
+start_node_slave(SlaveName, OptList, From, _TI) ->
SuppliedArgs = start_node_get_option_value(args, OptList, []),
Cleanup = start_node_get_option_value(cleanup, OptList, true),
- CrashFile = filename:join([TI#target_info.test_server_dir,
+ CrashDir = test_server_sup:crash_dump_dir(),
+ CrashFile = filename:join([CrashDir,
"erl_crash_dump."++cast_to_list(SlaveName)]),
CrashArgs = lists:concat([" -env ERL_CRASH_DUMP \"",CrashFile,"\" "]),
- Pa = TI#target_info.test_server_dir,
- Args = lists:concat([" -pa \"", Pa, "\" ", SuppliedArgs, CrashArgs]),
+ Args = lists:concat([" ", SuppliedArgs, CrashArgs]),
Prog0 = start_node_get_option_value(erl, OptList, default),
Prog = pick_erl_program(Prog0),
@@ -467,7 +470,11 @@ handle_start_node_return(Version,VsnStr,{started, Node, OVersion, OVsnStr}) ->
node_started([Host,PortAtom]) ->
%% Must spawn a new process because the boot process should not
%% hang forever!!
- spawn(fun() -> node_started(Host,PortAtom) end).
+ spawn(node_started_fun(Host,PortAtom)).
+
+-spec node_started_fun(_, _) -> fun(() -> no_return()).
+node_started_fun(Host,PortAtom) ->
+ fun() -> node_started(Host,PortAtom) end.
%% This process hangs forever, just waiting for the socket to be
%% closed and terminating the node
@@ -481,7 +488,7 @@ node_started(Host,PortAtom) ->
{ok,Sock} ->
Started = term_to_binary({started, node(), Version, VsnStr}),
- ok = gen_tcp:send(Sock, [1|Started]),
+ ok = gen_tcp:send(Sock, tag_trace_message(Started)),
receive _Anyting ->
gen_tcp:close(Sock),
erlang:halt()
@@ -491,8 +498,10 @@ node_started(Host,PortAtom) ->
end.
-
-
+-compile({inline, [tag_trace_message/1]}).
+-dialyzer({no_improper_lists, tag_trace_message/1}).
+tag_trace_message(M) ->
+ [1|M].
% start_which_node(Optlist) -> hostname
start_which_node(Optlist) ->
@@ -618,9 +627,8 @@ do_quote_progname([Prog,Arg|Args]) ->
end.
random_element(L) ->
- {A,B,C} = now(),
- E = lists:sum([A,B,C]) rem length(L),
- lists:nth(E+1, L).
+ random:seed(os:timestamp()),
+ lists:nth(random:uniform(length(L)), L).
find_release(latest) ->
"/usr/local/otp/releases/latest/bin/erl";
diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl
index 15a6fdd1de..c4530ba62f 100644
--- a/lib/test_server/src/test_server_sup.erl
+++ b/lib/test_server/src/test_server_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -125,14 +126,8 @@ messages_get(Msgs) ->
end.
timecall(M, F, A) ->
- Befor = erlang:now(),
- Val = apply(M, F, A),
- After = erlang:now(),
- Elapsed =
- (element(1,After)*1000000+element(2,After)+element(3,After)/1000000)-
- (element(1,Befor)*1000000+element(2,Befor)+element(3,Befor)/1000000),
- {Elapsed, Val}.
-
+ {Elapsed, Val} = timer:tc(M, F, A),
+ {Elapsed / 1000000, Val}.
call_crash(Time,Crash,M,F,A) ->
@@ -599,7 +594,11 @@ cleanup_crash_dumps() ->
delete_files(Dumps).
crash_dump_dir() ->
- filename:dirname(code:which(?MODULE)).
+ %% If no framework is known, then we use current working directory
+ %% - in most cases that will be the same as the default log
+ %% directory.
+ {ok,Dir} = test_server_sup:framework_call(get_log_dir,[],file:get_cwd()),
+ Dir.
tar_crash_dumps() ->
Dir = crash_dump_dir(),
@@ -887,9 +886,8 @@ unique_name() ->
util_loop(State) ->
receive
{From,unique_name} ->
- {_,S,Us} = now(),
- Ms = trunc(Us/1000),
- Name = lists:flatten(io_lib:format("~w.~w", [S,Ms])),
+ Nr = erlang:unique_integer([positive]),
+ Name = integer_to_list(Nr),
if Name == State#util_state.latest_name ->
timer:sleep(1),
self() ! {From,unique_name},
diff --git a/lib/test_server/src/things/distr_startup_SUITE.erl b/lib/test_server/src/things/distr_startup_SUITE.erl
index 0d4e467570..aa84ab007f 100644
--- a/lib/test_server/src/things/distr_startup_SUITE.erl
+++ b/lib/test_server/src/things/distr_startup_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/things/mnesia_power_SUITE.erl b/lib/test_server/src/things/mnesia_power_SUITE.erl
index 281dac7742..e9bc75e583 100644
--- a/lib/test_server/src/things/mnesia_power_SUITE.erl
+++ b/lib/test_server/src/things/mnesia_power_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/things/random_kill_SUITE.erl b/lib/test_server/src/things/random_kill_SUITE.erl
index 4fcd63e3af..917bc2b3d5 100644
--- a/lib/test_server/src/things/random_kill_SUITE.erl
+++ b/lib/test_server/src/things/random_kill_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/things/verify.erl b/lib/test_server/src/things/verify.erl
index eac20c013e..b09d0fbda9 100644
--- a/lib/test_server/src/things/verify.erl
+++ b/lib/test_server/src/things/verify.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl
index d6d2e865e2..8bbdc8f8cf 100644
--- a/lib/test_server/src/ts.erl
+++ b/lib/test_server/src/ts.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -24,15 +25,20 @@
-module(ts).
--export([run/0, run/1, run/2, run/3, run/4, run/5,
- tests/0, tests/1,
+-export([cl_run/1,
+ run/0, run/1, run/2, run/3, run/4, run/5,
+ run_category/1, run_category/2, run_category/3,
+ tests/0, tests/1, suites/1, categories/1,
install/0, install/1,
- bench/0, bench/1, bench/2, benchmarks/0,
- smoke_test/0, smoke_test/1,smoke_test/2, smoke_tests/0,
estone/0, estone/1,
cross_cover_analyse/1,
compile_testcases/0, compile_testcases/1,
help/0]).
+
+%% Functions kept for backwards compatibility
+-export([bench/0, bench/1, bench/2, benchmarks/0,
+ smoke_test/0, smoke_test/1,smoke_test/2, smoke_tests/0]).
+
-export([i/0, l/1, r/0, r/1, r/2, r/3]).
%%%----------------------------------------------------------------------
@@ -82,10 +88,13 @@
-define(
install_help,
[
- " ts:install() - Install TS with no Options.\n"
- " ts:install([Options]) - Install TS with Options\n"
+ " ts:install()\n",
+ " Install ts with no options.\n",
"\n",
- "Installation options supported:\n",
+ " ts:install(Options)\n",
+ " Install ts with a list of options, see below.\n",
+ "\n",
+ "Installation options supported:\n\n",
" {longnames, true} - Use fully qualified hostnames\n",
" {verbose, Level} - Sets verbosity level for TS output (0,1,2), 0 is\n"
" quiet(default).\n"
@@ -110,21 +119,64 @@ help() ->
end.
help(uninstalled) ->
- H = ["TS is not installed yet. To install use:\n\n"],
+ H = ["ts is not yet installed. To install use:\n\n"],
show_help([H,?install_help]);
help(installed) ->
- H = ["Run functions:\n",
- " ts:run() - Run all available tests.\n",
- " ts:run(Spec) - Run all tests in given test spec file.\n",
- " The spec file is actually ../*_test/Spec.spec\n",
- " ts:run([Specs]) - Run all tests in all given test spec files.\n",
- " ts:run(Spec, Mod) - Run a single test suite.\n",
- " ts:run(Spec, Mod, Case)\n",
- " - Run a single test case.\n",
- " All above run functions can have an additional Options argument\n",
- " which is a list of options.\n",
+ H = ["\n",
+ "Run functions:\n\n",
+ " ts:run()\n",
+ " Run the tests for all apps. The tests are defined by the\n",
+ " main test specification for each app: ../App_test/App.spec.\n",
+ "\n",
+ " ts:run(Apps)\n",
+ " Apps = atom() | [atom()]\n",
+ " Run the tests for an app, or set of apps. The tests are\n",
+ " defined by the main test specification for each app:\n",
+ " ../App_test/App.spec.\n",
+ "\n",
+ " ts:run(App, Suites)\n",
+ " App = atom(), Suites = atom() | [atom()]\n",
+ " Run one or more test suites for App (i.e. modules named\n",
+ " *_SUITE.erl, located in ../App_test/).\n",
+ "\n",
+ " ts:run(App, Suite, TestCases)\n",
+ " App = atom(), Suite = atom(),\n",
+ " TestCases = TCs | {testcase,TCs}, TCs = atom() | [atom()]\n",
+ " Run one or more test cases (functions) in Suite.\n",
+ "\n",
+ " ts:run(App, Suite, {group,Groups})\n",
+ " App = atom(), Suite = atom(), Groups = atom() | [atom()]\n",
+ " Run one or more test case groups in Suite.\n",
+ "\n",
+ " ts:run(App, Suite, {group,Group}, {testcase,TestCases})\n",
+ " App = atom(), Suite = atom(), Group = atom(),\n",
+ " TestCases = atom() | [atom()]\n",
+ " Run one or more test cases in a test case group in Suite.\n",
+ "\n",
+ " ts:run_category(TestCategory)\n",
+ " TestCategory = smoke | essential | bench | atom()\n",
+ " Run the specified category of tests for all apps.\n",
+ " For each app, the tests are defined by the specification:\n",
+ " ../App_test/App_TestCategory.spec.\n",
+ "\n",
+ " ts:run_category(Apps, TestCategory)\n",
+ " Apps = atom() | [atom()],\n",
+ " TestCategory = smoke | essential | bench | atom()\n",
+ " Run the specified category of tests for the given app or apps.\n",
"\n",
- "Run options supported:\n",
+ " Note that the test category parameter may have arbitrary value,\n",
+ " but should correspond to an existing test specification with file\n",
+ " name: ../App_test/App_TestCategory.spec.\n",
+ " Predefined categories exist for smoke tests, essential tests and\n",
+ " benchmark tests. The corresponding specs are:\n",
+ " ../*_test/Spec_smoke.spec, ../*_test/Spec_essential.spec and\n",
+ " ../*_test/Spec_bench.spec.\n",
+ "\n",
+ " All above run functions can take an additional last argument,\n",
+ " Options, which is a list of options (e.g. ts:run(App, Options),\n",
+ " or ts:run_category(Apps, TestCategory, Options)).\n",
+ "\n",
+ "Run options supported:\n\n",
" batch - Do not start a new xterm\n",
" {verbose, Level} - Same as the verbosity option for install\n",
" verbose - Same as {verbose, 1}\n",
@@ -143,47 +195,46 @@ help(installed) ->
" files are. The default location is\n"
" tests/test_server/.\n"
"\n",
- "Supported trace information elements\n",
+ "Supported trace information elements:\n\n",
" {tp | tpl, Mod, [] | match_spec()}\n",
" {tp | tpl, Mod, Func, [] | match_spec()}\n",
" {tp | tpl, Mod, Func, Arity, [] | match_spec()}\n",
" {ctp | ctpl, Mod}\n",
" {ctp | ctpl, Mod, Func}\n",
" {ctp | ctpl, Mod, Func, Arity}\n",
+ "\n\n",
+ "Support functions:\n\n",
+ " ts:tests()\n",
+ " Returns all apps available for testing.\n",
+ "\n",
+ " ts:tests(TestCategory)\n",
+ " Returns all apps that provide tests in the given category.\n",
+ "\n",
+ " ts:suites(App)\n",
+ " Returns all available test suites for App,\n",
+ " i.e. ../App_test/*_SUITE.erl\n",
+ "\n",
+ " ts:categories(App)\n",
+ " Returns all test categories available for App.\n",
"\n",
- "Support functions:\n",
- " ts:tests() - Shows all available families of tests.\n",
- " ts:tests(Spec) - Shows all available test modules in Spec,\n",
- " i.e. ../Spec_test/*_SUITE.erl\n",
- " ts:estone() - Run estone_SUITE in kernel application with\n"
- " no run options\n",
- " ts:estone(Opts) - Run estone_SUITE in kernel application with\n"
- " the given run options\n",
- " ts:cross_cover_analyse(Level)\n"
- " - Used after ts:run with option cover or \n"
- " cover_details. Analyses modules specified with\n"
- " a 'cross' statement in the cover spec file.\n"
- " Level can be 'overview' or 'details'.\n",
- " ts:compile_testcases()~n"
- " ts:compile_testcases(Apps)~n"
- " - Compile all testcases for usage in a cross ~n"
- " compile environment."
- " \n"
- "Benchmark functions:\n"
- " ts:benchmarks() - Get all available families of benchmarks\n"
- " ts:bench() - Runs all benchmarks\n"
- " ts:bench(Spec) - Runs all benchmarks in the given spec file.\n"
- " The spec file is actually ../*_test/Spec_bench.spec\n\n"
- " ts:bench can take the same Options argument as ts:run.\n"
- "Smoke test functions:\n"
- " ts:smoke_tests() - Get all available families of smoke tests\n"
- " ts:smoke_test() - Runs all smoke tests\n"
- " ts:smoke_test(Spec)\n"
- " - Runs all smoke tests in the given spec file.\n"
- " The spec file is actually ../*_test/Spec_smoke.spec\n\n"
- " ts:smoke_test can take the same Options argument as ts:run.\n"
- "\n"
- "Installation (already done):\n"
+ " ts:estone()\n",
+ " Runs estone_SUITE in the kernel application with no run options\n",
+ "\n",
+ " ts:estone(Opts)\n",
+ " Runs estone_SUITE in the kernel application with the given\n",
+ " run options\n",
+ "\n",
+ " ts:cross_cover_analyse(Level)\n",
+ " Use after ts:run with option cover or cover_details. Analyses\n",
+ " modules specified with a 'cross' statement in the cover spec file.\n",
+ " Level can be 'overview' or 'details'.\n",
+ "\n",
+ " ts:compile_testcases()\n",
+ " ts:compile_testcases(Apps)\n",
+ " Compiles all test cases for the given apps, for usage in a\n",
+ " cross compilation environment.\n",
+ "\n\n",
+ "Installation (already done):\n\n"
],
show_help([H,?install_help]).
@@ -212,86 +263,138 @@ run_all(_Vars) ->
run_some([], _Opts) ->
ok;
-run_some([{Spec,Mod}|Specs], Opts) ->
- case run(Spec, Mod, Opts) of
+run_some(Apps, Opts) ->
+ case proplists:get_value(test_category, Opts) of
+ bench ->
+ check_and_run(fun(Vars) -> ts_benchmark:run(Apps, Opts, Vars) end);
+ _Other ->
+ run_some1(Apps, Opts)
+ end.
+
+run_some1([], _Opts) ->
+ ok;
+run_some1([{App,Mod}|Apps], Opts) ->
+ case run(App, Mod, Opts) of
ok -> ok;
- Error -> io:format("~p: ~p~n",[{Spec,Mod},Error])
+ Error -> io:format("~p: ~p~n",[{App,Mod},Error])
end,
- run_some(Specs, Opts);
-run_some([Spec|Specs], Opts) ->
- case run(Spec, Opts) of
+ run_some1(Apps, Opts);
+run_some1([App|Apps], Opts) ->
+ case run(App, Opts) of
ok -> ok;
- Error -> io:format("~p: ~p~n",[Spec,Error])
+ Error -> io:format("~p: ~p~n",[App,Error])
end,
- run_some(Specs, Opts).
-
-%% Runs one test spec (interactive).
-run(Testspec) when is_atom(Testspec) ->
- Options=check_test_get_opts(Testspec, []),
- File = atom_to_list(Testspec),
- run_test(File, [{spec,[File++".spec"]}], Options);
+ run_some1(Apps, Opts).
+
+%% This can be used from command line. Both App and
+%% TestCategory must be specified. App may be 'all'
+%% and TestCategory may be 'main'. Examples:
+%% erl -s ts cl_run kernel smoke <options>
+%% erl -s ts cl_run kernel main <options>
+%% erl -s ts cl_run all essential <options>
+%% erl -s ts cl_run all main <options>
+%% When using the 'main' category and running with cover,
+%% one can also use the cross_cover_analysis flag.
+cl_run([App,Cat|Options0]) when is_atom(App) ->
-%% This can be used from command line, e.g.
-%% erl -s ts run all_tests <config>
-%% When using the all_tests flag and running with cover, one can also
-%% use the cross_cover_analysis flag.
-run([all_tests|Config0]) ->
AllAtomsFun = fun(X) when is_atom(X) -> true;
(_) -> false
end,
- Config1 =
- case lists:all(AllAtomsFun,Config0) of
+ Options1 =
+ case lists:all(AllAtomsFun, Options0) of
true ->
%% Could be from command line
- lists:map(fun(Conf)->to_erlang_term(Conf) end,Config0)--[batch];
+ lists:map(fun(Opt) ->
+ to_erlang_term(Opt)
+ end, Options0) -- [batch];
false ->
- Config0--[batch]
+ Options0 -- [batch]
end,
%% Make sure there is exactly one occurence of 'batch'
- Config2 = [batch|Config1],
-
- R = run(tests(),Config2),
-
- case check_for_cross_cover_analysis_flag(Config2) of
+ Options2 = [batch|Options1],
+
+ Result =
+ case {App,Cat} of
+ {all,main} ->
+ run(tests(), Options2);
+ {all,Cat} ->
+ run_category(Cat, Options2);
+ {_,main} ->
+ run(App, Options2);
+ {_,Cat} ->
+ run_category(App, Cat, Options2)
+ end,
+ case check_for_cross_cover_analysis_flag(Options2) of
false ->
ok;
Level ->
cross_cover_analyse(Level)
end,
+ Result.
- R;
+%% run/1
+%% Runs tests for one app (interactive).
+run(App) when is_atom(App) ->
+ Options = check_test_get_opts(App, []),
+ File = atom_to_list(App),
+ run_test(File, [{spec,[File++".spec"]},{allow_user_terms,true}], Options);
-%% ts:run(ListOfTests)
-run(List) when is_list(List) ->
- run(List, [batch]).
-
-run(List, Opts) when is_list(List), is_list(Opts) ->
- run_some(List, Opts);
+%% This can be used from command line, e.g.
+%% erl -s ts run all <options>
+%% erl -s ts run main <options>
+run([all,main|Opts]) ->
+ cl_run([all,main|Opts]);
+run([all|Opts]) ->
+ cl_run([all,main|Opts]);
+run([main|Opts]) ->
+ cl_run([all,main|Opts]);
+%% Backwards compatible
+run([all_tests|Opts]) ->
+ cl_run([all,main|Opts]);
+
+%% run/1
+%% Runs the main tests for all available apps
+run(Apps) when is_list(Apps) ->
+ run(Apps, [batch]).
%% run/2
-%% Runs one test spec with list of suites or with options
-run(Testspec, ModsOrConfig) when is_atom(Testspec),
- is_list(ModsOrConfig) ->
- case is_list_of_suites(ModsOrConfig) of
+%% Runs the main tests for all available apps
+run(Apps, Opts) when is_list(Apps), is_list(Opts) ->
+ run_some(Apps, Opts);
+
+%% Runs tests for one app with list of suites or with options
+run(App, ModsOrOpts) when is_atom(App),
+ is_list(ModsOrOpts) ->
+ case is_list_of_suites(ModsOrOpts) of
false ->
- run(Testspec, {config_list,ModsOrConfig});
+ run(App, {opts_list,ModsOrOpts});
true ->
- run_some([{Testspec,M} || M <- ModsOrConfig],
+ run_some([{App,M} || M <- ModsOrOpts],
[batch])
end;
-run(Testspec, {config_list,Config}) ->
- Options=check_test_get_opts(Testspec, Config),
- IsSmoke=proplists:get_value(smoke,Config),
- File=atom_to_list(Testspec),
+
+run(App, {opts_list,Opts}) ->
+ Options = check_test_get_opts(App, Opts),
+ File = atom_to_list(App),
+
+ %% check if other test category than main has been specified
+ {CatSpecName,TestCat} =
+ case proplists:get_value(test_category, Opts) of
+ undefined ->
+ {"",main};
+ Cat ->
+ {"_" ++ atom_to_list(Cat),Cat}
+ end,
+
WhatToDo =
- case Testspec of
+ case App of
%% Known to exist but fails generic tests below
emulator -> test;
system -> test;
erl_interface -> test;
epmd -> test;
_ ->
- case code:lib_dir(Testspec) of
+ case code:lib_dir(App) of
{error,bad_name} ->
%% Application does not exist
skip;
@@ -313,92 +416,167 @@ run(Testspec, {config_list,Config}) ->
end
end
end,
- Spec =
- case WhatToDo of
- skip ->
- create_skip_spec(Testspec, tests(Testspec));
- test when IsSmoke ->
- File++"_smoke.spec";
- test ->
- File++".spec"
- end,
- run_test(File, [{spec,[Spec]}], Options);
-%% Runs one module in a spec (interactive)
-run(Testspec, Mod) when is_atom(Testspec), is_atom(Mod) ->
- run_test({atom_to_list(Testspec),Mod},
+ case WhatToDo of
+ skip ->
+ SkipSpec = create_skip_spec(App, suites(App)),
+ run_test(File, [{spec,[SkipSpec]}], Options);
+ test when TestCat == bench ->
+ check_and_run(fun(Vars) ->
+ ts_benchmark:run([App], Options, Vars)
+ end);
+ test ->
+ Spec = File ++ CatSpecName ++ ".spec",
+ run_test(File, [{spec,[Spec]},{allow_user_terms,true}], Options)
+ end;
+
+%% Runs one module for an app (interactive)
+run(App, Mod) when is_atom(App), is_atom(Mod) ->
+ run_test({atom_to_list(App),Mod},
[{suite,Mod}],
[interactive]).
%% run/3
-%% Run one module in a spec with Config
-run(Testspec, Mod, Config) when is_atom(Testspec),
- is_atom(Mod),
- is_list(Config) ->
- Options=check_test_get_opts(Testspec, Config),
- run_test({atom_to_list(Testspec),Mod},
+%% Run one module for an app with Opts
+run(App, Mod, Opts) when is_atom(App),
+ is_atom(Mod),
+ is_list(Opts) ->
+ Options = check_test_get_opts(App, Opts),
+ run_test({atom_to_list(App),Mod},
[{suite,Mod}], Options);
-%% Run multiple modules with Config
-run(Testspec, Mods, Config) when is_atom(Testspec),
- is_list(Mods),
- is_list(Config) ->
- run_some([{Testspec,M} || M <- Mods], Config);
+
+%% Run multiple modules with Opts
+run(App, Mods, Opts) when is_atom(App),
+ is_list(Mods),
+ is_list(Opts) ->
+ run_some([{App,M} || M <- Mods], Opts);
+
%% Runs one test case in a module.
-run(Testspec, Mod, Case) when is_atom(Testspec),
- is_atom(Mod),
- is_atom(Case) ->
- Options=check_test_get_opts(Testspec, []),
+run(App, Mod, Case) when is_atom(App),
+ is_atom(Mod),
+ is_atom(Case) ->
+ Options = check_test_get_opts(App, []),
Args = [{suite,Mod},{testcase,Case}],
- run_test(atom_to_list(Testspec), Args, Options);
+ run_test(atom_to_list(App), Args, Options);
+
%% Runs one or more groups in a module.
-run(Testspec, Mod, Grs={group,_Groups}) when is_atom(Testspec),
- is_atom(Mod) ->
- Options=check_test_get_opts(Testspec, []),
+run(App, Mod, Grs={group,_Groups}) when is_atom(App),
+ is_atom(Mod) ->
+ Options = check_test_get_opts(App, []),
Args = [{suite,Mod},Grs],
- run_test(atom_to_list(Testspec), Args, Options);
+ run_test(atom_to_list(App), Args, Options);
+
%% Runs one or more test cases in a module.
-run(Testspec, Mod, TCs={testcase,_Cases}) when is_atom(Testspec),
- is_atom(Mod) ->
- Options=check_test_get_opts(Testspec, []),
+run(App, Mod, TCs={testcase,_Cases}) when is_atom(App),
+ is_atom(Mod) ->
+ Options = check_test_get_opts(App, []),
Args = [{suite,Mod},TCs],
- run_test(atom_to_list(Testspec), Args, Options).
+ run_test(atom_to_list(App), Args, Options).
%% run/4
%% Run one test case in a module with Options.
-run(Testspec, Mod, Case, Config) when is_atom(Testspec),
- is_atom(Mod),
- is_atom(Case),
- is_list(Config) ->
- Options=check_test_get_opts(Testspec, Config),
+run(App, Mod, Case, Opts) when is_atom(App),
+ is_atom(Mod),
+ is_atom(Case),
+ is_list(Opts) ->
+ Options = check_test_get_opts(App, Opts),
Args = [{suite,Mod},{testcase,Case}],
- run_test(atom_to_list(Testspec), Args, Options);
+ run_test(atom_to_list(App), Args, Options);
+
%% Run one or more test cases in a module with Options.
-run(Testspec, Mod, {testcase,Cases}, Config) when is_atom(Testspec),
- is_atom(Mod) ->
- run(Testspec, Mod, Cases, Config);
-run(Testspec, Mod, Cases, Config) when is_atom(Testspec),
- is_atom(Mod),
- is_list(Cases),
- is_list(Config) ->
- Options=check_test_get_opts(Testspec, Config),
+run(App, Mod, {testcase,Cases}, Opts) when is_atom(App),
+ is_atom(Mod) ->
+ run(App, Mod, Cases, Opts);
+run(App, Mod, Cases, Opts) when is_atom(App),
+ is_atom(Mod),
+ is_list(Cases),
+ is_list(Opts) ->
+ Options = check_test_get_opts(App, Opts),
Args = [{suite,Mod},Cases],
- run_test(atom_to_list(Testspec), Args, Options);
+ run_test(atom_to_list(App), Args, Options);
+
+%% Run one or more test cases in a group.
+run(App, Mod, Gr={group,_Group}, {testcase,Cases}) when is_atom(App),
+ is_atom(Mod) ->
+ run(App, Mod, Gr, Cases, [batch]);
+
+
%% Run one or more groups in a module with Options.
-run(Testspec, Mod, Grs={group,_Groups}, Config) when is_atom(Testspec),
- is_atom(Mod) ->
- Options=check_test_get_opts(Testspec, Config),
+run(App, Mod, Grs={group,_Groups}, Opts) when is_atom(App),
+ is_atom(Mod),
+ is_list(Opts) ->
+ Options = check_test_get_opts(App, Opts),
Args = [{suite,Mod},Grs],
- run_test(atom_to_list(Testspec), Args, Options).
+ run_test(atom_to_list(App), Args, Options).
%% run/5
%% Run one or more test cases in a group with Options.
-run(Testspec, Mod, Group, Cases, Config) when is_atom(Testspec),
- is_atom(Mod),
- is_list(Config) ->
+run(App, Mod, Group, Cases, Opts) when is_atom(App),
+ is_atom(Mod),
+ is_list(Opts) ->
Group1 = if is_tuple(Group) -> Group; true -> {group,Group} end,
Cases1 = if is_tuple(Cases) -> Cases; true -> {testcase,Cases} end,
- Options=check_test_get_opts(Testspec, Config),
+ Options = check_test_get_opts(App, Opts),
Args = [{suite,Mod},Group1,Cases1],
- run_test(atom_to_list(Testspec), Args, Options).
+ run_test(atom_to_list(App), Args, Options).
+
+%% run_category/1
+run_category(TestCategory) when is_atom(TestCategory) ->
+ run_category(TestCategory, [batch]).
+
+%% run_category/2
+run_category(TestCategory, Opts) when is_atom(TestCategory),
+ is_list(Opts) ->
+ case ts:tests(TestCategory) of
+ [] ->
+ {error, no_tests_available};
+ Apps ->
+ Opts1 = [{test_category,TestCategory} | Opts],
+ run_some(Apps, Opts1)
+ end;
+
+run_category(Apps, TestCategory) when is_atom(TestCategory) ->
+ run_category(Apps, TestCategory, [batch]).
+
+%% run_category/3
+run_category(App, TestCategory, Opts) ->
+ Apps = if is_atom(App) -> [App];
+ is_list(App) -> App
+ end,
+ Opts1 = [{test_category,TestCategory} | Opts],
+ run_some(Apps, Opts1).
+
+%%-----------------------------------------------------------------
+%% Functions kept for backwards compatibility
+
+bench() ->
+ run_category(bench, []).
+bench(Opts) when is_list(Opts) ->
+ run_category(bench, Opts);
+bench(App) ->
+ run_category(App, bench, []).
+bench(App, Opts) when is_atom(App) ->
+ run_category(App, bench, Opts);
+bench(Apps, Opts) when is_list(Apps) ->
+ run_category(Apps, bench, Opts).
+
+benchmarks() ->
+ tests(bench).
+
+smoke_test() ->
+ run_category(smoke, []).
+smoke_test(Opts) when is_list(Opts) ->
+ run_category(smoke, Opts);
+smoke_test(App) ->
+ run_category(App, smoke, []).
+smoke_test(App, Opts) when is_atom(App) ->
+ run_category(App, smoke, Opts);
+smoke_test(Apps, Opts) when is_list(Apps) ->
+ run_category(Apps, smoke, Opts).
+
+smoke_tests() ->
+ tests(smoke).
+
+%%-----------------------------------------------------------------
is_list_of_suites(List) ->
lists:all(fun(Suite) ->
@@ -416,29 +594,29 @@ is_list_of_suites(List) ->
%% Create a spec to skip all SUITES, this is used when the application
%% to be tested is not part of the OTP release to be tested.
-create_skip_spec(Testspec, SuitesToSkip) ->
+create_skip_spec(App, SuitesToSkip) ->
{ok,Cwd} = file:get_cwd(),
- TestspecString = atom_to_list(Testspec),
- Specname = TestspecString++"_skip.spec",
+ AppString = atom_to_list(App),
+ Specname = AppString++"_skip.spec",
{ok,D} = file:open(filename:join([filename:dirname(Cwd),
- TestspecString++"_test",Specname]),
+ AppString++"_test",Specname]),
[write]),
- TestDir = "\"../"++TestspecString++"_test\"",
+ TestDir = "\"../"++AppString++"_test\"",
io:format(D,"{suites, "++TestDir++", all}.~n",[]),
io:format(D,"{skip_suites, "++TestDir++", ~w, \"Skipped as application"
" is not in path!\"}.",[SuitesToSkip]),
Specname.
-%% Check testspec to be valid and get possible Options
-%% from the config.
-check_test_get_opts(Testspec, Config) ->
- validate_test(Testspec),
- Mode = configmember(batch, {batch, interactive}, Config),
- Vars = configvars(Config),
- Trace = get_config(trace,Config),
- ConfigPath = get_config(config,Config),
- KeepTopcase = configmember(keep_topcase, {keep_topcase,[]}, Config),
- Cover = configcover(Testspec,Config),
+%% Check testspec for App to be valid and get possible options
+%% from the list.
+check_test_get_opts(App, Opts) ->
+ validate_test(App),
+ Mode = configmember(batch, {batch, interactive}, Opts),
+ Vars = configvars(Opts),
+ Trace = get_config(trace,Opts),
+ ConfigPath = get_config(config,Opts),
+ KeepTopcase = configmember(keep_topcase, {keep_topcase,[]}, Opts),
+ Cover = configcover(App,Opts),
lists:flatten([Vars,Mode,Trace,KeepTopcase,Cover,ConfigPath]).
to_erlang_term(Atom) ->
@@ -447,7 +625,7 @@ to_erlang_term(Atom) ->
{ok, Term} = erl_parse:parse_term(Tokens),
Term.
-%% Validate that a Testspec really is a testspec,
+%% Validate that Testspec really is a testspec,
%% and exit if not.
validate_test(Testspec) ->
case lists:member(Testspec, tests()) of
@@ -460,10 +638,10 @@ validate_test(Testspec) ->
exit(self(), {error, test_not_available})
end.
-configvars(Config) ->
- case lists:keysearch(vars, 1, Config) of
+configvars(Opts) ->
+ case lists:keysearch(vars, 1, Opts) of
{value, {vars, List}} ->
- List0 = special_vars(Config),
+ List0 = special_vars(Opts),
Key = fun(T) -> element(1,T) end,
DelDupList =
lists:filter(fun(V) ->
@@ -474,17 +652,17 @@ configvars(Config) ->
end, List),
{vars, [List0|DelDupList]};
_ ->
- {vars, special_vars(Config)}
+ {vars, special_vars(Opts)}
end.
-%% Allow some shortcuts in the Options...
-special_vars(Config) ->
+%% Allow some shortcuts in the options...
+special_vars(Opts) ->
SpecVars =
- case lists:member(verbose, Config) of
+ case lists:member(verbose, Opts) of
true ->
[{verbose, 1}];
false ->
- case lists:keysearch(verbose, 1, Config) of
+ case lists:keysearch(verbose, 1, Opts) of
{value, {verbose, Lvl}} ->
[{verbose, Lvl}];
_ ->
@@ -492,13 +670,13 @@ special_vars(Config) ->
end
end,
SpecVars1 =
- case lists:keysearch(diskless, 1, Config) of
+ case lists:keysearch(diskless, 1, Opts) of
{value,{diskless, true}} ->
[{diskless, true} | SpecVars];
_ ->
SpecVars
end,
- case lists:keysearch(testcase_callback, 1, Config) of
+ case lists:keysearch(testcase_callback, 1, Opts) of
{value,{testcase_callback, CBM, CBF}} ->
[{ts_testcase_callback, {CBM,CBF}} | SpecVars1];
{value,{testcase_callback, CB}} ->
@@ -566,50 +744,31 @@ check_for_cross_cover_analysis_flag([_|Config],Level,CrossFlag) ->
check_for_cross_cover_analysis_flag([],_,_) ->
false.
-%% Returns a list of available test suites.
+%% Returns all available apps.
tests() ->
{ok, Cwd} = file:get_cwd(),
ts_lib:specs(Cwd).
-tests(Spec) ->
+%% Returns all apps that provide tests in the given test category
+tests(main) ->
{ok, Cwd} = file:get_cwd(),
- ts_lib:suites(Cwd, atom_to_list(Spec)).
-
-%% Benchmark related functions
-
-bench() ->
- bench([]).
-
-bench(Opts) when is_list(Opts) ->
- bench(benchmarks(),Opts);
-bench(Spec) ->
- bench([Spec],[]).
-
-bench(Spec, Opts) when is_atom(Spec) ->
- bench([Spec],Opts);
-bench(Specs, Opts) ->
- check_and_run(fun(Vars) -> ts_benchmark:run(Specs, Opts, Vars) end).
-
-benchmarks() ->
- ts_benchmark:benchmarks().
-
-smoke_test() ->
- smoke_test([]).
-
-smoke_test(Opts) when is_list(Opts) ->
- smoke_test(smoke_tests(),Opts);
-smoke_test(Spec) ->
- smoke_test([Spec],[]).
-
-smoke_test(Spec, Opts) when is_atom(Spec) ->
- smoke_test([Spec],Opts);
-smoke_test(Specs, Opts) ->
- run(Specs, [{smoke,true}|Opts]).
+ ts_lib:specs(Cwd);
+tests(bench) ->
+ ts_benchmark:benchmarks();
+tests(TestCategory) ->
+ {ok, Cwd} = file:get_cwd(),
+ ts_lib:specialized_specs(Cwd, atom_to_list(TestCategory)).
+
+%% Returns a list of available test suites for App.
+suites(App) ->
+ {ok, Cwd} = file:get_cwd(),
+ ts_lib:suites(Cwd, atom_to_list(App)).
-smoke_tests() ->
+%% Returns all available test categories for App
+categories(App) ->
{ok, Cwd} = file:get_cwd(),
- ts_lib:specialized_specs(Cwd,"smoke").
+ ts_lib:test_categories(Cwd, atom_to_list(App)).
%%
%% estone/0, estone/1
diff --git a/lib/test_server/src/ts.hrl b/lib/test_server/src/ts.hrl
index 5e829f3575..4c940fdc4f 100644
--- a/lib/test_server/src/ts.hrl
+++ b/lib/test_server/src/ts.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/ts_autoconf_win32.erl b/lib/test_server/src/ts_autoconf_win32.erl
index 4a5c5c7603..288305b406 100644
--- a/lib/test_server/src/ts_autoconf_win32.erl
+++ b/lib/test_server/src/ts_autoconf_win32.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/ts_benchmark.erl b/lib/test_server/src/ts_benchmark.erl
index bd6abc3372..3e55edefb0 100644
--- a/lib/test_server/src/ts_benchmark.erl
+++ b/lib/test_server/src/ts_benchmark.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/src/ts_erl_config.erl b/lib/test_server/src/ts_erl_config.erl
index 2d45d39700..ab7363c106 100644
--- a/lib/test_server/src/ts_erl_config.erl
+++ b/lib/test_server/src/ts_erl_config.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl
index 594e619fbc..600a576820 100644
--- a/lib/test_server/src/ts_install.erl
+++ b/lib/test_server/src/ts_install.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/src/ts_install_cth.erl b/lib/test_server/src/ts_install_cth.erl
index 7746bbed6f..0462e62611 100644
--- a/lib/test_server/src/ts_install_cth.erl
+++ b/lib/test_server/src/ts_install_cth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,6 +41,8 @@
-export([post_end_per_group/4]).
-export([pre_init_per_testcase/3]).
+-export([post_init_per_testcase/4]).
+-export([pre_end_per_testcase/3]).
-export([post_end_per_testcase/4]).
-export([on_tc_fail/3]).
@@ -180,7 +183,22 @@ post_end_per_group(_Group,_Config,Return,State) ->
pre_init_per_testcase(_TC,Config,State) ->
{add_node_name(Config, State), State}.
+-spec post_init_per_testcase(TC :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_init_per_testcase(_TC,_Config,Return,State) ->
+ {Return, State}.
+
%% @doc Called after each test case.
+-spec pre_end_per_testcase(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_testcase(_TC,Config,State) ->
+ {Config, State}.
+
-spec post_end_per_testcase(TC :: atom(),
Config :: config(),
Return :: term(),
@@ -238,12 +256,15 @@ generate_nodenames2(0, _Hosts, Acc) ->
Acc;
generate_nodenames2(N, Hosts, Acc) ->
Host=lists:nth((N rem (length(Hosts)))+1, Hosts),
- Name=list_to_atom(temp_nodename("nod", []) ++ "@" ++ Host),
+ Name=list_to_atom(temp_nodename("nod",N) ++ "@" ++ Host),
generate_nodenames2(N-1, Hosts, [Name|Acc]).
-temp_nodename([], Acc) ->
- lists:flatten(Acc);
-temp_nodename([Chr|Base], Acc) ->
- {A,B,C} = erlang:now(),
- New = [Chr | integer_to_list(Chr bxor A bxor B+A bxor C+B)],
- temp_nodename(Base, [New|Acc]).
+%% We cannot use erlang:unique_integer([positive])
+%% here since this code in run on older test releases as well.
+temp_nodename(Base,I) ->
+ {A,B,C} = os:timestamp(),
+ Nstr = integer_to_list(I),
+ Astr = integer_to_list(A),
+ Bstr = integer_to_list(B),
+ Cstr = integer_to_list(C),
+ Base++Nstr++Astr++Bstr++Cstr.
diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl
index 5368960446..7c3f450194 100644
--- a/lib/test_server/src/ts_lib.erl
+++ b/lib/test_server/src/ts_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -27,7 +28,7 @@
erlang_type/1,
initial_capital/1,
specs/1, suites/2,
- specialized_specs/2,
+ test_categories/2, specialized_specs/2,
subst_file/3, subst/2, print_data/1,
make_non_erlang/2,
maybe_atom_to_list/1, progress/4,
@@ -96,26 +97,47 @@ specialized_specs(Dir,PostFix) ->
Specs = filelib:wildcard(filename:join([filename:dirname(Dir),
"*_test", "*_"++PostFix++".spec"])),
sort_tests([begin
- Base = filename:basename(Name),
- list_to_atom(string:substr(Base,1,string:rstr(Base,"_")-1))
+ DirPart = filename:dirname(Name),
+ AppTest = hd(lists:reverse(filename:split(DirPart))),
+ list_to_atom(string:substr(AppTest, 1, length(AppTest)-5))
end || Name <- Specs]).
specs(Dir) ->
Specs = filelib:wildcard(filename:join([filename:dirname(Dir),
"*_test", "*.{dyn,}spec"])),
- % Filter away all spec which end with {_bench,_smoke}.spec
- NoBench = fun(SpecName) ->
- case lists:reverse(SpecName) of
- "ceps.hcneb_"++_ -> false;
- "ceps.ekoms_"++_ -> false;
- _ -> true
- end
- end,
-
- sort_tests([filename_to_atom(Name) || Name <- Specs, NoBench(Name)]).
-
-suites(Dir, Spec) ->
- Glob=filename:join([filename:dirname(Dir), Spec++"_test",
+ %% Make sure only to include the main spec for each application
+ MainSpecs =
+ lists:flatmap(fun(FullName) ->
+ [Spec,TestDir|_] =
+ lists:reverse(filename:split(FullName)),
+ [_TestSuffix|TDParts] =
+ lists:reverse(string:tokens(TestDir,[$_,$.])),
+ [_SpecSuffix|SParts] =
+ lists:reverse(string:tokens(Spec,[$_,$.])),
+ if TDParts == SParts ->
+ [filename_to_atom(FullName)];
+ true ->
+ []
+ end
+ end, Specs),
+ sort_tests(MainSpecs).
+
+test_categories(Dir, App) ->
+ Specs = filelib:wildcard(filename:join([filename:dirname(Dir),
+ App++"_test", "*.spec"])),
+ lists:flatmap(fun(FullName) ->
+ [Spec,_TestDir|_] =
+ lists:reverse(filename:split(FullName)),
+ case filename:rootname(Spec -- App) of
+ "" ->
+ [];
+ [_Sep | Cat] ->
+ [list_to_atom(Cat)]
+ end
+ end, Specs).
+
+suites(Dir, App) ->
+ Glob=filename:join([filename:dirname(Dir), App++"_test",
"*_SUITE.erl"]),
Suites=filelib:wildcard(Glob),
[filename_to_atom(Name) || Name <- Suites].
@@ -228,12 +250,10 @@ do_test(Rest, Vars, Test) ->
{Result,Comment,Rest2}.
%% extract an argument
-get_arg([$ |Rest], Vars, Stop, Acc) ->
- get_arg(Rest, Vars, Stop, Acc);
get_arg([$(|Rest], Vars, Stop, _) ->
get_arg(Rest, Vars, Stop, []);
get_arg([Stop|Rest], Vars, Stop, Acc) ->
- Arg = lists:reverse(Acc),
+ Arg = string:strip(lists:reverse(Acc)),
Subst = subst(Arg, Vars),
{Subst,Rest};
get_arg([C|Rest], Vars, Stop, Acc) ->
diff --git a/lib/test_server/src/ts_make.erl b/lib/test_server/src/ts_make.erl
index 9cb77ecb12..0178f4d836 100644
--- a/lib/test_server/src/ts_make.erl
+++ b/lib/test_server/src/ts_make.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl
index 18d021f780..188094921d 100644
--- a/lib/test_server/src/ts_run.erl
+++ b/lib/test_server/src/ts_run.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/Makefile b/lib/test_server/test/Makefile
index afccc28662..8eec940505 100644
--- a/lib/test_server/test/Makefile
+++ b/lib/test_server/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/test_server/test/erl2html2_SUITE.erl b/lib/test_server/test/erl2html2_SUITE.erl
index 908985c879..8e9f6e773a 100644
--- a/lib/test_server/test/erl2html2_SUITE.erl
+++ b/lib/test_server/test/erl2html2_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -30,7 +31,7 @@
"<html>\n",
"<head><title>Module ", Src, "</title>\n",
"<meta http-equiv=\"cache-control\" ",
- "content=\"no-cache\">\n",
+ "content=\"no-cache\"></meta>\n",
"</head>\n",
"<body bgcolor=\"white\" text=\"black\" ",
"link=\"blue\" vlink=\"purple\" alink=\"red\">\n"]).
@@ -130,15 +131,7 @@ groups() ->
%% @end
%%--------------------------------------------------------------------
all() ->
- [m1].
-
-%%--------------------------------------------------------------------
-%% @spec TestCase() -> Info
-%% Info = [tuple()]
-%% @end
-%%--------------------------------------------------------------------
-m1() ->
- [].
+ [macros_defined, macros_undefined].
%%--------------------------------------------------------------------
%% @spec TestCase(Config0) ->
@@ -149,19 +142,29 @@ m1() ->
%% Comment = term()
%% @end
%%--------------------------------------------------------------------
-m1(Config) ->
- {Src,Dst} = convert_module("m1",Config),
+macros_defined(Config) ->
+ %% let erl2html2 use epp as parser
+ DataDir = ?config(data_dir,Config),
+ InclDir = filename:join(DataDir, "include"),
+ {Src,Dst} = convert_module("m1",[InclDir],Config),
+ {true,L} = check_line_numbers(Src,Dst),
+ ok = check_link_targets(Src,Dst,L,[{baz,0}],[]),
+ ok.
+
+macros_undefined(Config) ->
+ %% let erl2html2 use epp_dodger as parser
+ {Src,Dst} = convert_module("m1",[],Config),
{true,L} = check_line_numbers(Src,Dst),
- ok = check_link_targets(Src,Dst,L,[{baz,0}]),
+ ok = check_link_targets(Src,Dst,L,[{baz,0}],[{quux,0}]),
ok.
-convert_module(Mod,Config) ->
+convert_module(Mod,InclDirs,Config) ->
DataDir = ?config(data_dir,Config),
PrivDir = ?config(priv_dir,Config),
Src = filename:join(DataDir,Mod++".erl"),
Dst = filename:join(PrivDir,Mod++".erl.html"),
io:format("<a href=\"~s\">~s</a>\n",[Src,filename:basename(Src)]),
- ok = erl2html2:convert(Src, Dst, [], "<html><body>"),
+ ok = erl2html2:convert(Src, Dst, InclDirs, "<html><body>"),
io:format("<a href=\"~s\">~s</a>\n",[Dst,filename:basename(Dst)]),
{Src,Dst}.
@@ -229,36 +232,46 @@ check_line_number(Last,Line,OrigLine) ->
%% function.
%% The test module has -compile(export_all), so all functions are
%% found by listing the exported ones.
-check_link_targets(Src,Dst,L,RmFncs) ->
+check_link_targets(Src,Dst,L,RmFncs,ShouldRemain) ->
Mod = list_to_atom(filename:basename(filename:rootname(Src))),
Exports = Mod:module_info(exports)--[{module_info,0},{module_info,1}|RmFncs],
- {ok,{[],L},_} = xmerl_sax_parser:file(Dst,
- [{event_fun,fun sax_event/3},
- {event_state,{Exports,0}}]),
+ LastExprFuncs = [Func || {Func,_A} <- Exports],
+ {ok,{FAs,Fs,L},_} =
+ xmerl_sax_parser:file(Dst,
+ [{event_fun,fun sax_event/3},
+ {event_state,{Exports,LastExprFuncs,0}}]),
+ true = (length(FAs) == length(ShouldRemain)),
+ [] = [FA || FA <- FAs, not lists:member(FA,ShouldRemain)],
+ [] = [F || F <- Fs, not lists:keymember(F,1,ShouldRemain)],
ok.
sax_event(Event,_Loc,State) ->
sax_event(Event,State).
-sax_event({startElement,_Uri,"a",_QN,Attrs},{Exports,PrevLine}) ->
+sax_event({startElement,_Uri,"a",_QN,Attrs},{Exports,LastExprFuncs,PrevLine}) ->
{_,_,"name",Name} = lists:keyfind("name",3,Attrs),
case catch list_to_integer(Name) of
Line when is_integer(Line) ->
case PrevLine + 1 of
Line ->
-% erlang:display({found_line,Line}),
- {Exports,Line};
+ {Exports,LastExprFuncs,Line};
Other ->
ct:fail({unexpected_line_number_target,Other})
end;
{'EXIT',_} ->
- {match,[FStr,AStr]} =
- re:run(Name,"^(.*)-([0-9]+)$",[{capture,all_but_first,list}]),
+ {match,[FStr,EndStr]} =
+ re:run(Name,"^(.*)-(last_expr|[0-9]+)$",
+ [{capture,all_but_first,list}]),
F = list_to_atom(http_uri:decode(FStr)),
- A = list_to_integer(AStr),
-% erlang:display({found_fnc,F,A}),
- A = proplists:get_value(F,Exports),
- {lists:delete({F,A},Exports),PrevLine}
+ case EndStr of
+ "last_expr" ->
+ true = lists:member(F,LastExprFuncs),
+ {Exports,lists:delete(F,LastExprFuncs),PrevLine};
+ _ ->
+ A = list_to_integer(EndStr),
+ A = proplists:get_value(F,Exports),
+ {lists:delete({F,A},Exports),LastExprFuncs,PrevLine}
+ end
end;
sax_event(_,State) ->
State.
diff --git a/lib/test_server/test/erl2html2_SUITE_data/include/header3.hrl b/lib/test_server/test/erl2html2_SUITE_data/include/header3.hrl
new file mode 100644
index 0000000000..2a20850a3a
--- /dev/null
+++ b/lib/test_server/test/erl2html2_SUITE_data/include/header3.hrl
@@ -0,0 +1 @@
+-define(EPP_SWITCH, on).
diff --git a/lib/test_server/test/erl2html2_SUITE_data/m1.erl b/lib/test_server/test/erl2html2_SUITE_data/m1.erl
index 156f1d0a51..1d405963a5 100644
--- a/lib/test_server/test/erl2html2_SUITE_data/m1.erl
+++ b/lib/test_server/test/erl2html2_SUITE_data/m1.erl
@@ -7,9 +7,15 @@
-include("header1.hrl").
-include("header2.hrl").
+-include("header3.hrl").
-define(MACRO1,value).
+%% This macro is used to select parser in erl2html2.
+%% If EPP_SWITCH is defined epp is used, else epp_dodger.
+epp_switch() ->
+ ?EPP_SWITCH.
+
%%% Comment
foo(x) ->
%% Comment
diff --git a/lib/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl
index d1772ac411..6adf5b8a78 100644
--- a/lib/test_server/test/test_server_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
index 541e8fdefc..79d8defb22 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_break_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_break_SUITE.erl
index d9f009679a..ae9f018bc8 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_break_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_break_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
index 06e0ea80c4..f634bc3a46 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
index ccc0f12bf5..f9cca8653b 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_cover_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_cover_SUITE.erl
index b1ae70a302..ab5ccec7a2 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_cover_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_cover_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
index 9658191289..0385435710 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
index 0faf50a345..847c7b6bdd 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
index 9607d0d689..871bd21ee7 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl
index 03f371fc8c..3a3366218b 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/test/test_server_test_lib.erl b/lib/test_server/test/test_server_test_lib.erl
index 82a702d59f..e2680938e0 100644
--- a/lib/test_server/test/test_server_test_lib.erl
+++ b/lib/test_server/test/test_server_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 2a2ed2b3b0..8c5fc97383 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1 +1 @@
-TEST_SERVER_VSN = 3.8.1
+TEST_SERVER_VSN = 3.10
diff --git a/lib/tools/Makefile b/lib/tools/Makefile
index 685f3398e9..2699ffab51 100644
--- a/lib/tools/Makefile
+++ b/lib/tools/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in
index b1eb69f9dc..66bba229f6 100644
--- a/lib/tools/c_src/Makefile.in
+++ b/lib/tools/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/tools/c_src/erl_memory.c b/lib/tools/c_src/erl_memory.c
index c4e126a7b1..d3a96884db 100644
--- a/lib/tools/c_src/erl_memory.c
+++ b/lib/tools/c_src/erl_memory.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2003-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/tools/c_src/erl_memory_trace_block_table.c b/lib/tools/c_src/erl_memory_trace_block_table.c
index 9c19358f14..ca7cb45a0e 100644
--- a/lib/tools/c_src/erl_memory_trace_block_table.c
+++ b/lib/tools/c_src/erl_memory_trace_block_table.c
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/c_src/erl_memory_trace_block_table.h b/lib/tools/c_src/erl_memory_trace_block_table.h
index 1b1f23c16f..ead3afc8fb 100644
--- a/lib/tools/c_src/erl_memory_trace_block_table.h
+++ b/lib/tools/c_src/erl_memory_trace_block_table.h
@@ -1,13 +1,14 @@
-/* ``The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved via the world wide web at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+/* ``Licensed under the Apache License, Version 2.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.
*
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/doc/src/Makefile b/lib/tools/doc/src/Makefile
index e3a2d64041..c44c9ef4df 100644
--- a/lib/tools/doc/src/Makefile
+++ b/lib/tools/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/tools/doc/src/book.xml b/lib/tools/doc/src/book.xml
index 6260bcdf3a..03afa1fc37 100644
--- a/lib/tools/doc/src/book.xml
+++ b/lib/tools/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/cover.xml b/lib/tools/doc/src/cover.xml
index 07ffa65e3d..15cd784253 100644
--- a/lib/tools/doc/src/cover.xml
+++ b/lib/tools/doc/src/cover.xml
@@ -5,20 +5,21 @@
<header>
<copyright>
<year>2001</year>
- <year>2013</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -138,17 +139,18 @@
</desc>
</func>
<func>
- <name>compile(ModFile) -> Result</name>
- <name>compile(ModFile, Options) -> Result</name>
- <name>compile_module(ModFile) -> Result</name>
- <name>compile_module(ModFile, Options) -> Result</name>
- <fsummary>Compile a module for Cover analysis.</fsummary>
+ <name>compile(ModFiles) -> Result | [Result]</name>
+ <name>compile(ModFiles, Options) -> Result | [Result]</name>
+ <name>compile_module(ModFiles) -> Result | [Result]</name>
+ <name>compile_module(ModFiles, Options) -> Result | [Result]</name>
+ <fsummary>Compile one or more modules for Cover analysis.</fsummary>
<type>
+ <v>ModFiles = ModFile | [ModFile]</v>
<v>ModFile = Module | File</v>
<v>&nbsp;Module = atom()</v>
<v>&nbsp;File = string()</v>
<v>Options = [Option]</v>
- <v>&nbsp;Option = {i,Dir} | {d,Macro} | {d,Macro,Value}</v>
+ <v>&nbsp;Option = {i,Dir} | {d,Macro} | {d,Macro,Value} | export_all</v>
<d>See <c>compile:file/2.</c></d>
<v>Result = {ok,Module} | {error,File} | {error,not_main_node}</v>
</type>
@@ -165,6 +167,9 @@
returns <c>{ok,Module}</c>. Otherwise the function returns
<c>{error,File}</c>. Errors and warnings are printed as they
occur.</p>
+ <p>If a list of <c>ModFiles</c> is given as input, a list
+ of <c>Result</c> will be returned. The order of the returned
+ list is undefined.</p>
<p>Note that the internal database is (re-)initiated during
the compilation, meaning any previously collected coverage data
for the module will be lost.</p>
@@ -194,9 +199,10 @@
</desc>
</func>
<func>
- <name>compile_beam(ModFile) -> Result</name>
- <fsummary>Compile a module for Cover analysis, using an existing beam.</fsummary>
+ <name>compile_beam(ModFiles) -> Result | [Result]</name>
+ <fsummary>Compile one or more modules for Cover analysis, using existing beam(s).</fsummary>
<type>
+ <v>ModFiles = ModFile | [ModFile]</v>
<v>ModFile = Module | BeamFile</v>
<v>&nbsp;Module = atom()</v>
<v>&nbsp;BeamFile = string()</v>
@@ -229,6 +235,9 @@
returned.</p>
<p><c>{error,BeamFile}</c> is returned if the compiled code
can not be loaded on the node.</p>
+ <p>If a list of <c>ModFiles</c> is given as input, a list
+ of <c>Result</c> will be returned. The order of the returned
+ list is undefined.</p>
</desc>
</func>
<func>
@@ -251,16 +260,21 @@
</desc>
</func>
<func>
- <name>analyse(Module) -> {ok,Answer} | {error,Error}</name>
- <name>analyse(Module, Analysis) -> {ok,Answer} | {error,Error}</name>
- <name>analyse(Module, Level) -> {ok,Answer} | {error,Error}</name>
- <name>analyse(Module, Analysis, Level) -> {ok,Answer} | {error,Error}</name>
- <fsummary>Analyse a Cover compiled module.</fsummary>
+ <name>analyse() -> {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Modules) -> OneResult | {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Analysis) -> {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Level) -> {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Modules, Analysis) -> OneResult | {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Modules, Level) -> OneResult | {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Analysis, Level) -> {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse(Modules, Analysis, Level) -> OneResult | {result,Ok,Fail} | {error,not_main_node}</name>
+ <fsummary>Analyse one or more Cover compiled modules.</fsummary>
<type>
- <v>Module = atom()</v>
+ <v>Modules = Module | [Module]</v>
+ <v>Module = atom() </v>
<v>Analysis = coverage | calls</v>
<v>Level = line | clause | function | module</v>
- <v>Answer = {Module,Value} | [{Item,Value}]</v>
+ <v>OneResult = {ok,{Module,Value}} | {ok,[{Item,Value}]} | {error, Error}</v>
<v>&nbsp;Item = Line | Clause | Function</v>
<v>&nbsp;&nbsp;Line = {M,N}</v>
<v>&nbsp;&nbsp;Clause = {M,F,A,C}</v>
@@ -269,49 +283,67 @@
<v>&nbsp;&nbsp;&nbsp;N = A = C = integer()</v>
<v>&nbsp;Value = {Cov,NotCov} | Calls</v>
<v>&nbsp;&nbsp;Cov = NotCov = Calls = integer()</v>
- <v>Error = {not_cover_compiled,Module} | not_main_node</v>
+ <v>&nbsp;Error = {not_cover_compiled,Module}</v>
+ <v>Ok = [{Module,Value}] | [{Item,Value}]</v>
+ <v>Fail = [Error]</v>
</type>
<desc>
- <p>Performs analysis of a Cover compiled module <c>Module</c>, as
+ <p>Performs analysis of one or more Cover compiled modules, as
specified by <c>Analysis</c> and <c>Level</c> (see above), by
examining the contents of the internal database.</p>
<p><c>Analysis</c> defaults to <c>coverage</c> and <c>Level</c>
defaults to <c>function</c>.</p>
- <p>If <c>Module</c> is not Cover compiled, the function returns
- <c>{error,{not_cover_compiled,Module}}</c>.</p>
- <p>HINT: It is possible to issue multiple analyse_to_file commands at
- the same time. </p>
+ <p>If <c>Modules</c> is an atom (one module), the return will
+ be <c>OneResult</c>, else the return will be
+ <c>{result,Ok,Fail}</c>.</p>
+ <p>If <c>Modules</c> is not given, all modules that have data
+ in the cover data table, are analysed. Note that this
+ includes both cover compiled modules and imported
+ modules.</p>
+ <p>If a given module is not Cover compiled, this is indicated
+ by the error reason <c>{not_cover_compiled,Module}</c>.</p>
</desc>
</func>
<func>
- <name>analyse_to_file(Module) -> </name>
- <name>analyse_to_file(Module,Options) -> </name>
- <name>analyse_to_file(Module, OutFile) -> </name>
- <name>analyse_to_file(Module, OutFile, Options) -> {ok,OutFile} | {error,Error}</name>
- <fsummary>Detailed coverage analysis of a Cover compiled module.</fsummary>
+ <name>analyse_to_file() -> {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse_to_file(Modules) -> Answer | {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse_to_file(Options) -> {result,Ok,Fail} | {error,not_main_node}</name>
+ <name>analyse_to_file(Modules,Options) -> Answer | {result,Ok,Fail} | {error,not_main_node}</name>
+ <fsummary>Detailed coverage analysis of one or more Cover compiled modules.</fsummary>
<type>
+ <v>Modules = Module | [Module]</v>
<v>Module = atom()</v>
- <v>OutFile = string()</v>
+ <v>OutFile = OutDir = string()</v>
<v>Options = [Option]</v>
- <v>Option = html</v>
- <v>Error = {not_cover_compiled,Module} | {file,File,Reason} | no_source_code_found | not_main_node</v>
+ <v>Option = html | {outfile,OutFile} | {outdir,OutDir}</v>
+ <v>Answer = {ok,OutFile} | {error,Error}</v>
+ <v>Ok = [OutFile]</v>
+ <v>Fail = [Error]</v>
+ <v>Error = {not_cover_compiled,Module} | {file,File,Reason} | {no_source_code_found,Module}</v>
<v>&nbsp;File = string()</v>
<v>&nbsp;Reason = term()</v>
</type>
<desc>
- <p>Makes a copy <c>OutFile</c> of the source file for a module
- <c>Module</c>, where it for each executable line is specified
+ <p>Makes copies of the source file for the given modules,
+ where it for each executable line is specified
how many times it has been executed.</p>
<p>The output file <c>OutFile</c> defaults to
<c>Module.COVER.out</c>, or <c>Module.COVER.html</c> if the
option <c>html</c> was used.</p>
- <p>If <c>Module</c> is not Cover compiled, the function returns
- <c>{error,{not_cover_compiled,Module}}</c>.</p>
+ <p>If <c>Modules</c> is an atom (one module), the return will
+ be <c>Answer</c>, else the return will be a
+ list, <c>{result,Ok,Fail}</c>.</p>
+ <p>If <c>Modules</c> is not given, all modules that have data
+ in the cover data table, are analysed. Note that this
+ includes both cover compiled modules and imported
+ modules.</p>
+ <p>If a module is not Cover compiled, this is indicated by the
+ error reason <c>{not_cover_compiled,Module}</c>.</p>
<p>If the source file and/or the output file cannot be opened using
<c>file:open/2</c>, the function returns
<c>{error,{file,File,Reason}}</c> where <c>File</c> is the file
name and <c>Reason</c> is the error reason.</p>
- <p>If the module was cover compiled from the <c>.beam</c>
+ <p>If a module was cover compiled from the <c>.beam</c>
file, i.e. using <c>compile_beam/1</c> or
<c>compile_beam_directory/0,1</c>, it is assumed that the
source code can be found in the same directory as the
@@ -322,10 +354,8 @@
joining <c>../src</c> and the tail of the compiled path
below a trailing <c>src</c> component, then the compiled
path itself.
- If no source code is found,
- <c>{error,no_source_code_found}</c> is returned.</p>
- <p>HINT: It is possible to issue multiple analyse_to_file commands at
- the same time. </p>
+ If no source code is found, this is indicated by the error reason
+ <c>{no_source_code_found,Module}</c>.</p>
</desc>
</func>
<func>
@@ -339,7 +369,7 @@
<v>OutFile = string()</v>
<v>Options = [Option]</v>
<v>Option = html</v>
- <v>Error = {not_cover_compiled,Module} | {file,File,Reason} | no_source_code_found | not_main_node</v>
+ <v>Error = {not_cover_compiled,Module} | {file,File,Reason} | {no_source_code_found,Module} | not_main_node</v>
<v>&nbsp;File = string()</v>
<v>&nbsp;Reason = term()</v>
</type>
diff --git a/lib/tools/doc/src/cover_chapter.xml b/lib/tools/doc/src/cover_chapter.xml
index f29f59bee0..2f7f8d8083 100644
--- a/lib/tools/doc/src/cover_chapter.xml
+++ b/lib/tools/doc/src/cover_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/cprof.xml b/lib/tools/doc/src/cprof.xml
index 553597837e..d3be276d28 100644
--- a/lib/tools/doc/src/cprof.xml
+++ b/lib/tools/doc/src/cprof.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -66,7 +67,7 @@
<func>
<name>analyse() -> {AllCallCount, ModAnalysisList}</name>
<name>analyse(Limit) -> {AllCallCount, ModAnalysisList}</name>
- <name>analyse(Mod) -> ModAnlysis</name>
+ <name>analyse(Mod) -> ModAnalysis</name>
<name>analyse(Mod, Limit) -> ModAnalysis</name>
<fsummary>Collect and analyse call counters.</fsummary>
<type>
diff --git a/lib/tools/doc/src/cprof_chapter.xml b/lib/tools/doc/src/cprof_chapter.xml
index 6536d43e0f..0e83dbbfb5 100644
--- a/lib/tools/doc/src/cprof_chapter.xml
+++ b/lib/tools/doc/src/cprof_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml
index 73fd563fbd..8e37d49c99 100644
--- a/lib/tools/doc/src/eprof.xml
+++ b/lib/tools/doc/src/eprof.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -130,13 +131,13 @@
<name>analyze() -> ok</name>
<name>analyze(Type) -> ok</name>
<name>analyze(Type,Options) -> ok</name>
+ <fsummary>Display profiling results per process.</fsummary>
<type>
<v>Type = procs | total</v>
<v>Options = [{filter, Filter} | {sort, Sort}</v>
<v>Filter = [{calls, integer()} | {time, float()}]</v>
<v>Sort = time | calls | mfa</v>
</type>
- <fsummary>Display profiling results per process.</fsummary>
<desc>
<p>Call this function when profiling has been stopped to display
the results per process, that is:</p>
diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml
index 747c41d554..4ecb8feadd 100644
--- a/lib/tools/doc/src/erlang_mode.xml
+++ b/lib/tools/doc/src/erlang_mode.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/erlang_mode_chapter.xml b/lib/tools/doc/src/erlang_mode_chapter.xml
index 3be1d53ca2..e07e7a8176 100644
--- a/lib/tools/doc/src/erlang_mode_chapter.xml
+++ b/lib/tools/doc/src/erlang_mode_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/fprof.xml b/lib/tools/doc/src/fprof.xml
index f83c049fcd..2dfc77fdfc 100644
--- a/lib/tools/doc/src/fprof.xml
+++ b/lib/tools/doc/src/fprof.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/fprof_chapter.xml b/lib/tools/doc/src/fprof_chapter.xml
index 462b3f9579..ecd8f385a5 100644
--- a/lib/tools/doc/src/fprof_chapter.xml
+++ b/lib/tools/doc/src/fprof_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/instrument.xml b/lib/tools/doc/src/instrument.xml
index 3f278b63cd..76583cd03b 100644
--- a/lib/tools/doc/src/instrument.xml
+++ b/lib/tools/doc/src/instrument.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/lcnt.xml b/lib/tools/doc/src/lcnt.xml
index 9754b107fe..c381488f85 100644
--- a/lib/tools/doc/src/lcnt.xml
+++ b/lib/tools/doc/src/lcnt.xml
@@ -9,18 +9,19 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
+ Licensed under the Apache License, Version 2.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.
+
+ The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>lcnt</title>
diff --git a/lib/tools/doc/src/lcnt_chapter.xml b/lib/tools/doc/src/lcnt_chapter.xml
index 1b8595749d..060559c954 100644
--- a/lib/tools/doc/src/lcnt_chapter.xml
+++ b/lib/tools/doc/src/lcnt_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/tools/doc/src/make.xml b/lib/tools/doc/src/make.xml
index f4d64fa9e2..5c2e5e5d62 100644
--- a/lib/tools/doc/src/make.xml
+++ b/lib/tools/doc/src/make.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -75,7 +76,7 @@
Load mode. Loads all recompiled modules.</item>
<item><c>netload</c> <br></br>
- Net load mode. Loads all recompiled modules an all known nodes.</item>
+ Net load mode. Loads all recompiled modules on all known nodes.</item>
</list>
<p>All items in <c>Options</c> that are not make options are assumed
to be compiler options and are passed as-is to
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 38b57b73a9..c62b0607ee 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,6 +31,134 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.8.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>cover:compile_beam/1</c> and
+ <c>cover:compile_beam_directory/1,2</c> crashed when
+ trying to compile a beam file without a <c>'file'</c>
+ attribute. This has been corrected and an error is
+ returned instead.</p>
+ <p>
+ Thanks to Louis-Philippe Gauthier for reporting this bug.</p>
+ <p>
+ Own Id: OTP-13200</p>
+ </item>
+ <item>
+ <p>Fix a bit string comprehension bug in Cover. </p>
+ <p>
+ Own Id: OTP-13277 Aux Id: PR 856 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The emacs mode does not add a newline after the arrow on
+ -callback lines anymore.</p>
+ <p>
+ Own Id: OTP-13042</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If a module includes eunit.hrl, a parse transform adds
+ the function test/0 on line 0 in the module. A bug in
+ OTP-18.0 caused cover:analyse_to_file/1 to fail to insert
+ cover data in the output file when line 0 existed in the
+ cover data table. This is now corrected.</p>
+ <p>
+ Own Id: OTP-12981</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ In order to improve performance of the cover tool, new
+ functions are added for cover compilation and analysis on
+ multiple files. This allows for more parallelisation.</p>
+ <p>
+ Some improvements of the data base access is also done in
+ order to improve the performance when analysing and
+ resetting cover data.</p>
+ <p>
+ Minor incompatibility: An error reason from
+ analyse_to_file is changed from no_source_code_found to
+ {no_source_code_found,Module}.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12330 Aux Id: seq12757 </p>
+ </item>
+ <item>
+ <p>Attempting to do a <c>cover</c> analysis when neither
+ source code nor beam file could be found would hang the
+ <c>cover</c> server. Corrected to return a proper
+ error.</p>
+ <p>
+ Own Id: OTP-12806</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Allow maps for supervisor flags and child specs</p>
+ <p>
+ Earlier, supervisor flags and child specs were given as
+ tuples. While this is kept for backwards compatibility,
+ it is now also allowed to give these parameters as maps,
+ see <seealso
+ marker="stdlib:supervisor#sup_flags">sup_flags</seealso>
+ and <seealso
+ marker="stdlib:supervisor#child_spec">child_spec</seealso>.</p>
+ <p>
+ Own Id: OTP-11043</p>
+ </item>
+ <item>
+ <p>
+ Remove Mnemosyne rules support.</p>
+ <p>
+ Own Id: OTP-12511</p>
+ </item>
+ <item>
+ <p>
+ Add printout of total number of calls and time in eprof</p>
+ <p>
+ Own Id: OTP-12681</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.7.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/doc/src/notes_history.xml b/lib/tools/doc/src/notes_history.xml
index 2058dd8fde..d19aac4d4e 100644
--- a/lib/tools/doc/src/notes_history.xml
+++ b/lib/tools/doc/src/notes_history.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/part.xml b/lib/tools/doc/src/part.xml
index 5b03e1db55..b96586041a 100644
--- a/lib/tools/doc/src/part.xml
+++ b/lib/tools/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/tools/doc/src/part_notes.xml b/lib/tools/doc/src/part_notes.xml
index 3527d5e3d9..c990e973a2 100644
--- a/lib/tools/doc/src/part_notes.xml
+++ b/lib/tools/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/doc/src/part_notes_history.xml b/lib/tools/doc/src/part_notes_history.xml
index 43c0abd05a..dd9c27e872 100644
--- a/lib/tools/doc/src/part_notes_history.xml
+++ b/lib/tools/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/tools/doc/src/ref_man.xml b/lib/tools/doc/src/ref_man.xml
index 7b68e18a75..2d9ca7660a 100644
--- a/lib/tools/doc/src/ref_man.xml
+++ b/lib/tools/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/tools/doc/src/tags.xml b/lib/tools/doc/src/tags.xml
index 0aa0ca8e35..b089f0674b 100644
--- a/lib/tools/doc/src/tags.xml
+++ b/lib/tools/doc/src/tags.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml
index da16efa005..ebf9139f06 100644
--- a/lib/tools/doc/src/xref.xml
+++ b/lib/tools/doc/src/xref.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/tools/doc/src/xref_chapter.xml b/lib/tools/doc/src/xref_chapter.xml
index db9f774186..e7186b9209 100644
--- a/lib/tools/doc/src/xref_chapter.xml
+++ b/lib/tools/doc/src/xref_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile
index 69946be24a..585425e5f1 100644
--- a/lib/tools/emacs/Makefile
+++ b/lib/tools/emacs/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el
index 0adeff1a02..a3c29c520c 100644
--- a/lib/tools/emacs/erlang-eunit.el
+++ b/lib/tools/emacs/erlang-eunit.el
@@ -3,16 +3,17 @@
;;
;; 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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;;
diff --git a/lib/tools/emacs/erlang-skels-old.el b/lib/tools/emacs/erlang-skels-old.el
index b88d7bcc4b..c271cce3cb 100644
--- a/lib/tools/emacs/erlang-skels-old.el
+++ b/lib/tools/emacs/erlang-skels-old.el
@@ -3,16 +3,17 @@
;;
;; 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/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;;
@@ -838,7 +839,7 @@ Please see the function `tempo-define-template'.")
"Config." n n
(erlang-skel-separator 2)
- "%% Function: end_per_suite(Config) -> void()" n
+ "%% Function: end_per_suite(Config) -> term()" n
"%%" n
"%% Config = [tuple()]" n
"%% A list of key/value pairs, holding the test case configuration." n
@@ -867,7 +868,7 @@ Please see the function `tempo-define-template'.")
"Config." n n
(erlang-skel-separator 2)
- "%% Function: end_per_testcase(TestCase, Config) -> void()" n
+ "%% Function: end_per_testcase(TestCase, Config) -> term()" n
"%%" n
"%% TestCase = atom()" n
"%% Name of the test case that is finished." n
@@ -993,7 +994,7 @@ Please see the function `tempo-define-template'.")
"Config." n n
(erlang-skel-separator 2)
- "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n
+ "%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}" n
"%%" n
"%% Config0 = Config1 = [tuple()]" n
"%% A list of key/value pairs, holding the test case configuration." n
@@ -1021,7 +1022,7 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator 2)
"%% Function: end_per_group(GroupName, Config0) ->" n
- "%% void() | {save_config,Config1}" n
+ "%% term() | {save_config,Config1}" n
"%%" n
"%% GroupName = atom()" n
"%% Name of the test case group that is finished." n
@@ -1054,7 +1055,7 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator 2)
"%% Function: end_per_testcase(TestCase, Config0) ->" n
- "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%% term() | {save_config,Config1} | {fail,Reason}" n
"%%" n
"%% TestCase = atom()" n
"%% Name of the test case that is finished." n
@@ -1175,7 +1176,7 @@ Please see the function `tempo-define-template'.")
"Config." n n
(erlang-skel-separator 2)
- "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n
+ "%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}" n
"%% Config0 = Config1 = [tuple()]" n
(erlang-skel-separator 2)
"end_per_suite(_Config) ->" n >
@@ -1193,7 +1194,7 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator 2)
"%% Function: end_per_group(GroupName, Config0) ->" n
- "%% void() | {save_config,Config1}" n
+ "%% term() | {save_config,Config1}" n
"%% GroupName = atom()" n
"%% Config0 = Config1 = [tuple()]" n
(erlang-skel-separator 2)
@@ -1212,7 +1213,7 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator 2)
"%% Function: end_per_testcase(TestCase, Config0) ->" n
- "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%% term() | {save_config,Config1} | {fail,Reason}" n
"%% TestCase = atom()" n
"%% Config0 = Config1 = [tuple()]" n
"%% Reason = term()" n
diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el
index 78929ac510..6880ec733c 100644
--- a/lib/tools/emacs/erlang-skels.el
+++ b/lib/tools/emacs/erlang-skels.el
@@ -1,18 +1,19 @@
;;
;; %CopyrightBegin%
;;
-;; Copyright Ericsson AB 2010. All Rights Reserved.
+;; Copyright Ericsson AB 2010-2014. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;;
@@ -352,26 +353,25 @@ Please see the function `tempo-define-template'.")
"%% @doc" n
"%% Whenever a supervisor is started using supervisor:start_link/[2,3]," n
"%% this function is called by the new process to find out about" n
- "%% restart strategy, maximum restart frequency and child" n
+ "%% restart strategy, maximum restart intensity, and child" n
"%% specifications." n
"%%" n
"%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
"%% ignore |" n
"%% {error, Reason}" n
(erlang-skel-separator-end 2)
- "init([]) ->" n>
- "RestartStrategy = one_for_one," n>
- "MaxRestarts = 1000," n>
- "MaxSecondsBetweenRestarts = 3600," n
- "" n>
- "SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}," n
+ "init([]) ->" n
"" n>
- "Restart = permanent," n>
- "Shutdown = 2000," n>
- "Type = worker," n
+ "SupFlags = #{strategy => one_for_one," n>
+ "intensity => 1," n>
+ "period => 5}," n
"" n>
- "AChild = {'AName', {'AModule', start_link, []}," n>
- "Restart, Shutdown, Type, ['AModule']}," n
+ "AChild = #{id => 'AName'," n>
+ "start => {'AModule', start_link, []}," n>
+ "restart => permanent," n>
+ "shutdown => 5000," n>
+ "type => worker," n>
+ "modules => ['AModule']}," n
"" n>
"{ok, {SupFlags, [AChild]}}." n
n
@@ -379,7 +379,7 @@ Please see the function `tempo-define-template'.")
"%%% Internal functions" n
(erlang-skel-double-separator-end 3)
)
- "*The template of an supervisor behaviour.
+ "*The template of a supervisor behaviour.
Please see the function `tempo-define-template'.")
(defvar erlang-skel-supervisor-bridge
@@ -449,7 +449,7 @@ Please see the function `tempo-define-template'.")
"%%% Internal functions" n
(erlang-skel-double-separator-end 3)
)
- "*The template of an supervisor_bridge behaviour.
+ "*The template of a supervisor_bridge behaviour.
Please see the function `tempo-define-template'.")
(defvar erlang-skel-generic-server
@@ -1235,7 +1235,7 @@ Please see the function `tempo-define-template'.")
"Config." n n
(erlang-skel-separator-start 2)
- "%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}" n
+ "%% @spec end_per_suite(Config0) -> term() | {save_config,Config1}" n
"%% Config0 = Config1 = [tuple()]" n
(erlang-skel-separator-end 2)
"end_per_suite(_Config) ->" n >
@@ -1253,7 +1253,7 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator-start 2)
"%% @spec end_per_group(GroupName, Config0) ->" n
- "%% void() | {save_config,Config1}" n
+ "%% term() | {save_config,Config1}" n
"%% GroupName = atom()" n
"%% Config0 = Config1 = [tuple()]" n
(erlang-skel-separator-end 2)
@@ -1272,7 +1272,7 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator-start 2)
"%% @spec end_per_testcase(TestCase, Config0) ->" n
- "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%% term() | {save_config,Config1} | {fail,Reason}" n
"%% TestCase = atom()" n
"%% Config0 = Config1 = [tuple()]" n
"%% Reason = term()" n
@@ -1413,7 +1413,7 @@ Please see the function `tempo-define-template'.")
"%% A list of key/value pairs, holding configuration data for the group." n
"%%" n
"%% @spec end_per_group(GroupName, Config0) ->" n
- "%% void() | {save_config,Config1}" n
+ "%% term() | {save_config,Config1}" n
(erlang-skel-separator-end 2)
"end_per_group(_GroupName, _Config) ->" n >
"ok." n n
@@ -1447,7 +1447,7 @@ Please see the function `tempo-define-template'.")
"%% A list of key/value pairs, holding the test case configuration." n
"%%" n
"%% @spec end_per_testcase(TestCase, Config0) ->" n
- "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%% term() | {save_config,Config1} | {fail,Reason}" n
(erlang-skel-separator-end 2)
"end_per_testcase(_TestCase, _Config) ->" n >
"ok." n n
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 0c003bab39..466bf139b9 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -9,16 +9,17 @@
;;
;; Copyright Ericsson AB 1996-2014. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; 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%
;;
@@ -880,10 +881,10 @@ resulting regexp is surrounded by \\_< and \\_>."
"dt_restore_tag"
"dt_spread_tag"
"dunlink"
+ "convert_time_unit"
"external_size"
"finish_after_on_load"
"finish_loading"
- "flush_monitor_message"
"format_cpu_topology"
"fun_info"
"fun_info_mfa"
@@ -913,6 +914,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"memory"
"module_info"
"monitor_node"
+ "monotonic_time"
"nif_error"
"phash"
"phash2"
@@ -946,13 +948,17 @@ resulting regexp is surrounded by \\_< and \\_>."
"system_info"
"system_monitor"
"system_profile"
+ "system_time"
"trace"
"trace_delivered"
"trace_info"
"trace_pattern"
+ "time_offset"
+ "timestamp"
"universaltime"
"universaltime_to_localtime"
"universaltime_to_posixtime"
+ "unique_integer"
"yield")
"Erlang built-in functions (BIFs) that needs erlang: prefix"))
@@ -2444,7 +2450,10 @@ This is automagically called by the user level function `indent-region'."
;; Parse the Erlang code from the beginning of the clause to
;; the beginning of the region.
(while (< (point) indent-point)
- (setq state (erlang-partial-parse (point) indent-point state)))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse pt indent-point state))
+ (if (= pt (point))
+ (error "Illegal syntax"))))
;; Indent every line in the region
(while continue
(goto-char indent-point)
@@ -2480,8 +2489,11 @@ This is automagically called by the user level function `indent-region'."
(if (>= from-end (- (point-max) indent-point))
(setq continue nil)
(while (< (point) indent-point)
- (setq state (erlang-partial-parse
- (point) indent-point state))))))))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse
+ pt indent-point state))
+ (if (= pt (point))
+ (error "Illegal syntax")))))))))
(defun erlang-indent-current-buffer ()
@@ -2528,7 +2540,10 @@ Return nil if line starts inside string, t if in a comment."
(goto-char parse-start)
(erlang-beginning-of-clause))
(while (< (point) indent-point)
- (setq state (erlang-partial-parse (point) indent-point state)))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse pt indent-point state))
+ (if (= pt (point))
+ (error "Illegal syntax"))))
(erlang-calculate-stack-indent indent-point state))))
(defun erlang-show-syntactic-information ()
@@ -2698,12 +2713,13 @@ Value is list (stack token-start token-type in-what)."
(erlang-push (list '|| token (current-column)) stack)
(forward-char 2))
- ;; Bit-syntax open paren
- ((looking-at "<<")
+ ;; Bit-syntax open. Note that map syntax allows "<<" to follow ":="
+ ;; or "=>" without intervening whitespace, so handle that case here
+ ((looking-at "\\(:=\\|=>\\)?<<")
(erlang-push (list '<< token (current-column)) stack)
- (forward-char 2))
+ (forward-char (- (match-end 0) (match-beginning 0))))
- ;; Bbit-syntax close paren
+ ;; Bit-syntax close
((looking-at ">>")
(while (memq (car (car stack)) '(|| ->))
(erlang-pop stack))
@@ -4188,7 +4204,10 @@ This function is designed to be a member of a criteria list."
;; Do not return `stop' when inside a list comprehension
;; construction. (The point must be after `||').
(while (< (point) orig-point)
- (setq state (erlang-partial-parse (point) orig-point state)))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse pt orig-point state))
+ (if (= pt (point))
+ (error "Illegal syntax"))))
(if (and (car state) (eq (car (car (car state))) '||))
nil
'stop)))
@@ -4217,7 +4236,7 @@ This function is designed to be a member of a criteria list."
This function is designed to be a member of a criteria list."
(save-excursion
(beginning-of-line)
- (when (save-match-data (looking-at "-\\(spec\\|type\\)"))
+ (when (save-match-data (looking-at "-\\(spec\\|type\\|callback\\)"))
'stop)))
diff --git a/lib/tools/emacs/internal_doc/emacs.sgml b/lib/tools/emacs/internal_doc/emacs.sgml
index 5b28928605..eb6c3b7bb4 100644
--- a/lib/tools/emacs/internal_doc/emacs.sgml
+++ b/lib/tools/emacs/internal_doc/emacs.sgml
@@ -1,15 +1,16 @@
<!DOCTYPE CHAPTER PUBLIC "-//Stork//DTD chapter//EN">
<!--
- ``The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved via the world wide web at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ ``Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented
index 1c1086ca58..1986acadf1 100644
--- a/lib/tools/emacs/test.erl.indented
+++ b/lib/tools/emacs/test.erl.indented
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -32,6 +33,14 @@
-module(test).
-compile(export_all).
+%% Used to cause an "Unbalanced parentheses" error.
+foo(M) ->
+ M#{a :=<<"a">>
+ ,b:=1}.
+foo() ->
+ #{a =><<"a">>
+ ,b=>1}.
+
%% Module attributes should be highlighted
-export([t/1]).
diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig
index a9d09000d2..7e8ad23412 100644
--- a/lib/tools/emacs/test.erl.orig
+++ b/lib/tools/emacs/test.erl.orig
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -32,6 +33,14 @@
-module(test).
-compile(export_all).
+%% Used to cause an "Unbalanced parentheses" error.
+foo(M) ->
+M#{a :=<<"a">>
+,b:=1}.
+foo() ->
+#{a =><<"a">>
+,b=>1}.
+
%% Module attributes should be highlighted
-export([t/1]).
diff --git a/lib/tools/examples/Makefile b/lib/tools/examples/Makefile
index fc14ee54d6..0fcc66d874 100644
--- a/lib/tools/examples/Makefile
+++ b/lib/tools/examples/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/priv/Makefile b/lib/tools/priv/Makefile
index b32ba5820d..aa4aaa2fc8 100644
--- a/lib/tools/priv/Makefile
+++ b/lib/tools/priv/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/src/Makefile b/lib/tools/src/Makefile
index e606b97a48..9fcfb79628 100644
--- a/lib/tools/src/Makefile
+++ b/lib/tools/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index 31754015f7..d16ca7f406 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -77,8 +78,11 @@
compile/1, compile/2, compile_module/1, compile_module/2,
compile_directory/0, compile_directory/1, compile_directory/2,
compile_beam/1, compile_beam_directory/0, compile_beam_directory/1,
- analyse/1, analyse/2, analyse/3, analyze/1, analyze/2, analyze/3,
+ analyse/0, analyse/1, analyse/2, analyse/3,
+ analyze/0, analyze/1, analyze/2, analyze/3,
+ analyse_to_file/0,
analyse_to_file/1, analyse_to_file/2, analyse_to_file/3,
+ analyze_to_file/0,
analyze_to_file/1, analyze_to_file/2, analyze_to_file/3,
async_analyse_to_file/1,async_analyse_to_file/2,
async_analyse_to_file/3, async_analyze_to_file/1,
@@ -109,6 +113,7 @@
line = '_' % integer()
}).
-define(BUMP_REC_NAME,bump).
+-define(CHUNK_SIZE, 20000).
-record(vars, {module, % atom() Module name
@@ -132,7 +137,7 @@
-define(SERVER, cover_server).
%% Line doesn't matter.
--define(BLOCK(Expr), {block,0,[Expr]}).
+-define(BLOCK(Expr), {block,erl_anno:new(0),[Expr]}).
-define(BLOCK1(Expr),
if
element(1, Expr) =:= block ->
@@ -181,10 +186,11 @@ start(Node) when is_atom(Node) ->
start(Nodes) ->
call({start_nodes,remove_myself(Nodes,[])}).
-%% compile(ModFile) ->
-%% compile(ModFile, Options) ->
-%% compile_module(ModFile) -> Result
-%% compile_module(ModFile, Options) -> Result
+%% compile(ModFiles) ->
+%% compile(ModFiles, Options) ->
+%% compile_module(ModFiles) -> Result
+%% compile_module(ModFiles, Options) -> Result
+%% ModFiles = ModFile | [ModFile]
%% ModFile = Module | File
%% Module = atom()
%% File = string()
@@ -198,18 +204,27 @@ compile(ModFile, Options) ->
compile_module(ModFile) when is_atom(ModFile);
is_list(ModFile) ->
compile_module(ModFile, []).
-compile_module(Module, Options) when is_atom(Module), is_list(Options) ->
- compile_module(atom_to_list(Module), Options);
-compile_module(File, Options) when is_list(File), is_list(Options) ->
- WithExt = case filename:extension(File) of
- ".erl" ->
- File;
- _ ->
- File++".erl"
- end,
- AbsFile = filename:absname(WithExt),
- [R] = compile_modules([AbsFile], Options),
- R.
+compile_module(ModFile, Options) when is_atom(ModFile);
+ is_list(ModFile), is_integer(hd(ModFile)) ->
+ [R] = compile_module([ModFile], Options),
+ R;
+compile_module(ModFiles, Options) when is_list(Options) ->
+ AbsFiles =
+ [begin
+ File =
+ case ModFile of
+ _ when is_atom(ModFile) -> atom_to_list(ModFile);
+ _ when is_list(ModFile) -> ModFile
+ end,
+ WithExt = case filename:extension(File) of
+ ".erl" ->
+ File;
+ _ ->
+ File++".erl"
+ end,
+ filename:absname(WithExt)
+ end || ModFile <- ModFiles],
+ compile_modules(AbsFiles, Options).
%% compile_directory() ->
%% compile_directory(Dir) ->
@@ -240,13 +255,14 @@ compile_directory(Dir, Options) when is_list(Dir), is_list(Options) ->
compile_modules(Files,Options) ->
Options2 = filter_options(Options),
- compile_modules(Files,Options2,[]).
+ %% compile_modules(Files,Options2,[]).
+ call({compile, Files, Options2}).
-compile_modules([File|Files], Options, Result) ->
- R = call({compile, File, Options}),
- compile_modules(Files,Options,[R|Result]);
-compile_modules([],_Opts,Result) ->
- lists:reverse(Result).
+%% compile_modules([File|Files], Options, Result) ->
+%% R = call({compile, File, Options}),
+%% compile_modules(Files,Options,[R|Result]);
+%% compile_modules([],_Opts,Result) ->
+%% lists:reverse(Result).
filter_options(Options) ->
lists:filter(fun(Option) ->
@@ -264,30 +280,17 @@ filter_options(Options) ->
%% ModFile - see compile/1
%% Result - see compile/1
%% Reason = non_existing | already_cover_compiled
-compile_beam(Module) when is_atom(Module) ->
- case code:which(Module) of
- non_existing ->
+compile_beam(ModFile0) when is_atom(ModFile0);
+ is_list(ModFile0), is_integer(hd(ModFile0)) ->
+ case compile_beams([ModFile0]) of
+ [{error,{non_existing,_}}] ->
+ %% Backwards compatibility
{error,non_existing};
- ?TAG ->
- compile_beam(Module,?TAG);
- File ->
- compile_beam(Module,File)
+ [Result] ->
+ Result
end;
-compile_beam(File) when is_list(File) ->
- {WithExt,WithoutExt}
- = case filename:rootname(File,".beam") of
- File ->
- {File++".beam",File};
- Rootname ->
- {File,Rootname}
- end,
- AbsFile = filename:absname(WithExt),
- Module = list_to_atom(filename:basename(WithoutExt)),
- compile_beam(Module,AbsFile).
-
-compile_beam(Module,File) ->
- call({compile_beam,Module,File}).
-
+compile_beam(ModFiles) when is_list(ModFiles) ->
+ compile_beams(ModFiles).
%% compile_beam_directory(Dir) -> [Result] | {error,Reason}
@@ -312,19 +315,52 @@ compile_beam_directory(Dir) when is_list(Dir) ->
Error
end.
-compile_beams(Files) ->
- compile_beams(Files,[]).
-compile_beams([File|Files],Result) ->
- R = compile_beam(File),
- compile_beams(Files,[R|Result]);
-compile_beams([],Result) ->
- lists:reverse(Result).
-
+compile_beams(ModFiles0) ->
+ ModFiles = get_mods_and_beams(ModFiles0,[]),
+ call({compile_beams,ModFiles}).
-%% analyse(Module) ->
-%% analyse(Module, Analysis) ->
-%% analyse(Module, Level) ->
-%% analyse(Module, Analysis, Level) -> {ok,Answer} | {error,Error}
+get_mods_and_beams([Module|ModFiles],Acc) when is_atom(Module) ->
+ case code:which(Module) of
+ non_existing ->
+ get_mods_and_beams(ModFiles,[{error,{non_existing,Module}}|Acc]);
+ File ->
+ get_mods_and_beams([{Module,File}|ModFiles],Acc)
+ end;
+get_mods_and_beams([File|ModFiles],Acc) when is_list(File) ->
+ {WithExt,WithoutExt}
+ = case filename:rootname(File,".beam") of
+ File ->
+ {File++".beam",File};
+ Rootname ->
+ {File,Rootname}
+ end,
+ AbsFile = filename:absname(WithExt),
+ Module = list_to_atom(filename:basename(WithoutExt)),
+ get_mods_and_beams([{Module,AbsFile}|ModFiles],Acc);
+get_mods_and_beams([{Module,File}|ModFiles],Acc) ->
+ %% Check for duplicates
+ case lists:keyfind(Module,2,Acc) of
+ {ok,Module,File} ->
+ %% Duplicate, but same file so ignore
+ get_mods_and_beams(ModFiles,Acc);
+ {ok,Module,_OtherFile} ->
+ %% Duplicate and differnet file - error
+ get_mods_and_beams(ModFiles,[{error,{duplicate,Module}}|Acc]);
+ _ ->
+ get_mods_and_beams(ModFiles,[{ok,Module,File}|Acc])
+ end;
+get_mods_and_beams([],Acc) ->
+ lists:reverse(Acc).
+
+
+%% analyse(Modules) ->
+%% analyse(Analysis) ->
+%% analyse(Level) ->
+%% analyse(Modules, Analysis) ->
+%% analyse(Modules, Level) ->
+%% analyse(Analysis, Level)
+%% analyse(Modules, Analysis, Level) -> {ok,Answer} | {error,Error}
+%% Modules = Module | [Module]
%% Module = atom()
%% Analysis = coverage | calls
%% Level = line | clause | function | module
@@ -337,48 +373,74 @@ compile_beams([],Result) ->
%% N = A = C = integer()
%% Value = {Cov,NotCov} | Calls
%% Cov = NotCov = Calls = integer()
-%% Error = {not_cover_compiled,Module}
+%% Error = {not_cover_compiled,Module} | not_main_node
+-define(is_analysis(__A__),
+ (__A__=:=coverage orelse __A__=:=calls)).
+-define(is_level(__L__),
+ (__L__=:=line orelse __L__=:=clause orelse
+ __L__=:=function orelse __L__=:=module)).
+analyse() ->
+ analyse('_').
+
+analyse(Analysis) when ?is_analysis(Analysis) ->
+ analyse('_', Analysis);
+analyse(Level) when ?is_level(Level) ->
+ analyse('_', Level);
analyse(Module) ->
analyse(Module, coverage).
-analyse(Module, Analysis) when Analysis=:=coverage; Analysis=:=calls ->
+
+analyse(Analysis, Level) when ?is_analysis(Analysis) andalso
+ ?is_level(Level) ->
+ analyse('_', Analysis, Level);
+analyse(Module, Analysis) when ?is_analysis(Analysis) ->
analyse(Module, Analysis, function);
-analyse(Module, Level) when Level=:=line; Level=:=clause; Level=:=function;
- Level=:=module ->
+analyse(Module, Level) when ?is_level(Level) ->
analyse(Module, coverage, Level).
-analyse(Module, Analysis, Level) when is_atom(Module),
- Analysis=:=coverage; Analysis=:=calls,
- Level=:=line; Level=:=clause;
- Level=:=function; Level=:=module ->
+
+analyse(Module, Analysis, Level) when ?is_analysis(Analysis),
+ ?is_level(Level) ->
call({{analyse, Analysis, Level}, Module}).
+analyze() -> analyse( ).
analyze(Module) -> analyse(Module).
analyze(Module, Analysis) -> analyse(Module, Analysis).
analyze(Module, Analysis, Level) -> analyse(Module, Analysis, Level).
-%% analyse_to_file(Module) ->
-%% analyse_to_file(Module, Options) ->
-%% analyse_to_file(Module, OutFile) ->
-%% analyse_to_file(Module, OutFile, Options) -> {ok,OutFile} | {error,Error}
+%% analyse_to_file() ->
+%% analyse_to_file(Modules) ->
+%% analyse_to_file(Modules, Options) ->
+%% Modules = Module | [Module]
%% Module = atom()
%% OutFile = string()
%% Options = [Option]
-%% Option = html
+%% Option = html | {outfile,filename()} | {outdir,dirname()}
%% Error = {not_cover_compiled,Module} | no_source_code_found |
%% {file,File,Reason}
%% File = string()
%% Reason = term()
-analyse_to_file(Module) when is_atom(Module) ->
- analyse_to_file(Module, outfilename(Module,[]), []).
-analyse_to_file(Module, []) when is_atom(Module) ->
- analyse_to_file(Module, outfilename(Module,[]), []);
-analyse_to_file(Module, Options) when is_atom(Module),
- is_list(Options), is_atom(hd(Options)) ->
- analyse_to_file(Module, outfilename(Module,Options), Options);
-analyse_to_file(Module, OutFile) when is_atom(Module), is_list(OutFile) ->
- analyse_to_file(Module, OutFile, []).
-analyse_to_file(Module, OutFile, Options) when is_atom(Module), is_list(OutFile) ->
- call({{analyse_to_file, OutFile, Options}, Module}).
-
+%%
+%% Kept for backwards compatibility:
+%% analyse_to_file(Modules, OutFile) ->
+%% analyse_to_file(Modules, OutFile, Options) -> {ok,OutFile} | {error,Error}
+analyse_to_file() ->
+ analyse_to_file('_').
+analyse_to_file(Arg) ->
+ case is_options(Arg) of
+ true ->
+ analyse_to_file('_',Arg);
+ false ->
+ analyse_to_file(Arg,[])
+ end.
+analyse_to_file(Module, OutFile) when is_list(OutFile), is_integer(hd(OutFile)) ->
+ %% Kept for backwards compatibility
+ analyse_to_file(Module, [{outfile,OutFile}]);
+analyse_to_file(Module, Options) when is_list(Options) ->
+ call({{analyse_to_file, Options}, Module}).
+analyse_to_file(Module, OutFile, Options) when is_list(OutFile) ->
+ %% Kept for backwards compatibility
+ analyse_to_file(Module,[{outfile,OutFile}|Options]).
+
+analyze_to_file() -> analyse_to_file().
analyze_to_file(Module) -> analyse_to_file(Module).
analyze_to_file(Module, OptOrOut) -> analyse_to_file(Module, OptOrOut).
analyze_to_file(Module, OutFile, Options) ->
@@ -391,6 +453,15 @@ async_analyse_to_file(Module, OutFileOrOpts) ->
async_analyse_to_file(Module, OutFile, Options) ->
do_spawn(?MODULE, analyse_to_file, [Module, OutFile, Options]).
+is_options([html]) ->
+ true; % this is not 100% safe - could be a module named html...
+is_options([html|Opts]) ->
+ is_options(Opts);
+is_options([{Opt,_}|_]) when Opt==outfile; Opt==outdir ->
+ true;
+is_options(_) ->
+ false.
+
do_spawn(M,F,A) ->
spawn_link(fun() ->
case apply(M,F,A) of
@@ -408,13 +479,16 @@ async_analyze_to_file(Module, OutFileOrOpts) ->
async_analyze_to_file(Module, OutFile, Options) ->
async_analyse_to_file(Module, OutFile, Options).
-outfilename(Module,Opts) ->
- case lists:member(html,Opts) of
- true ->
- atom_to_list(Module)++".COVER.html";
- false ->
- atom_to_list(Module)++".COVER.out"
- end.
+outfilename(undefined, Module, HTML) ->
+ outfilename(Module, HTML);
+outfilename(OutDir, Module, HTML) ->
+ filename:join(OutDir, outfilename(Module, HTML)).
+
+outfilename(Module, true) ->
+ atom_to_list(Module)++".COVER.html";
+outfilename(Module, false) ->
+ atom_to_list(Module)++".COVER.out".
+
%% export(File)
%% export(File,Module) -> ok | {error,Reason}
@@ -559,7 +633,7 @@ init_main(Starter) ->
,{write_concurrency, true}
]),
ets:new(?COVER_CLAUSE_TABLE, [set, public, named_table]),
- ets:new(?BINARY_TABLE, [set, named_table]),
+ ets:new(?BINARY_TABLE, [set, public, named_table]),
ets:new(?COLLECTION_TABLE, [set, public, named_table]),
ets:new(?COLLECTION_CLAUSE_TABLE, [set, public, named_table]),
net_kernel:monitor_nodes(true),
@@ -573,55 +647,19 @@ main_process_loop(State) ->
reply(From, {ok,StartedNodes}),
main_process_loop(State1);
- {From, {compile, File, Options}} ->
- case do_compile(File, Options) of
- {ok, Module} ->
- remote_load_compiled(State#main_state.nodes,[{Module,File}]),
- reply(From, {ok, Module}),
- Compiled = add_compiled(Module, File,
- State#main_state.compiled),
- Imported = remove_imported(Module,State#main_state.imported),
- NewState = State#main_state{compiled = Compiled,
- imported = Imported},
- %% This module (cover) could have been reloaded. Make
- %% sure we run the new code.
- ?MODULE:main_process_loop(NewState);
- error ->
- reply(From, {error, File}),
- main_process_loop(State)
- end;
+ {From, {compile, Files, Options}} ->
+ {R,S} = do_compile(Files, Options, State),
+ reply(From,R),
+ %% This module (cover) could have been reloaded. Make
+ %% sure we run the new code.
+ ?MODULE:main_process_loop(S);
- {From, {compile_beam, Module, BeamFile0}} ->
- Compiled0 = State#main_state.compiled,
- case get_beam_file(Module,BeamFile0,Compiled0) of
- {ok,BeamFile} ->
- UserOptions = get_compile_options(Module,BeamFile),
- {Reply,Compiled} =
- case do_compile_beam(Module,BeamFile,UserOptions) of
- {ok, Module} ->
- remote_load_compiled(State#main_state.nodes,
- [{Module,BeamFile}]),
- C = add_compiled(Module,BeamFile,Compiled0),
- {{ok,Module},C};
- error ->
- {{error, BeamFile}, Compiled0};
- {error,Reason} -> % no abstract code
- {{error, {Reason, BeamFile}}, Compiled0}
- end,
- reply(From,Reply),
- Imported = remove_imported(Module,State#main_state.imported),
- NewState = State#main_state{compiled = Compiled,
- imported = Imported},
- %% This module (cover) could have been reloaded. Make
- %% sure we run the new code.
- ?MODULE:main_process_loop(NewState);
- {error,no_beam} ->
- %% The module has first been compiled from .erl, and now
- %% someone tries to compile it from .beam
- reply(From,
- {error,{already_cover_compiled,no_beam_found,Module}}),
- main_process_loop(State)
- end;
+ {From, {compile_beams, ModsAndFiles}} ->
+ {R,S} = do_compile_beams(ModsAndFiles,State),
+ reply(From,R),
+ %% This module (cover) could have been reloaded. Make
+ %% sure we run the new code.
+ ?MODULE:main_process_loop(S);
{From, {export,OutFile,Module}} ->
spawn(fun() ->
@@ -706,6 +744,16 @@ main_process_loop(State) ->
unregister(?SERVER),
reply(From, ok);
+ {From, {{analyse, Analysis, Level}, '_'}} ->
+ R = analyse_all(Analysis, Level, State),
+ reply(From, R),
+ main_process_loop(State);
+
+ {From, {{analyse, Analysis, Level}, Modules}} when is_list(Modules) ->
+ R = analyse_list(Modules, Analysis, Level, State),
+ reply(From, R),
+ main_process_loop(State);
+
{From, {{analyse, Analysis, Level}, Module}} ->
S = try
Loaded = is_loaded(Module, State),
@@ -722,15 +770,23 @@ main_process_loop(State) ->
end,
main_process_loop(S);
- {From, {{analyse_to_file, OutFile, Opts},Module}} ->
+ {From, {{analyse_to_file, Opts},'_'}} ->
+ R = analyse_all_to_file(Opts, State),
+ reply(From,R),
+ main_process_loop(State);
+
+ {From, {{analyse_to_file, Opts},Modules}} when is_list(Modules) ->
+ R = analyse_list_to_file(Modules, Opts, State),
+ reply(From,R),
+ main_process_loop(State);
+
+ {From, {{analyse_to_file, Opts},Module}} ->
S = try
Loaded = is_loaded(Module, State),
- spawn(fun() ->
- ?SPAWN_DBG(analyse_to_file,
- {Module,OutFile, Opts}),
+ spawn_link(fun() ->
+ ?SPAWN_DBG(analyse_to_file,{Module,Opts}),
do_parallel_analysis_to_file(
- Module, OutFile, Opts,
- Loaded, From, State)
+ Module, Opts, Loaded, From, State)
end),
State
catch throw:Reason ->
@@ -848,11 +904,15 @@ remote_process_loop(State) ->
{remote,collect,Module,CollectorPid} ->
self() ! {remote,collect,Module,CollectorPid, ?SERVER};
- {remote,collect,Module,CollectorPid,From} ->
+ {remote,collect,Modules0,CollectorPid,From} ->
+ Modules = case Modules0 of
+ '_' -> [M || {M,_} <- State#remote_state.compiled];
+ _ -> Modules0
+ end,
spawn(fun() ->
?SPAWN_DBG(remote_collect,
- {Module, CollectorPid, From}),
- do_collect(Module, CollectorPid, From)
+ {Modules, CollectorPid, From}),
+ do_collect(Modules, CollectorPid, From)
end),
remote_process_loop(State);
@@ -893,39 +953,51 @@ remote_process_loop(State) ->
end.
-do_collect(Module, CollectorPid, From) ->
- AllMods =
- case Module of
- '_' -> ets:tab2list(?COVER_CLAUSE_TABLE);
- _ -> ets:lookup(?COVER_CLAUSE_TABLE, Module)
- end,
-
- %% Sending clause by clause in order to avoid large lists
+do_collect(Modules, CollectorPid, From) ->
pmap(
- fun({_Mod,Clauses}) ->
- lists:map(fun(Clause) ->
- send_collected_data(Clause, CollectorPid)
- end,Clauses)
- end,AllMods),
+ fun(Module) ->
+ Pattern = {#bump{module=Module, _='_'}, '$1'},
+ MatchSpec = [{Pattern,[{'=/=','$1',0}],['$_']}],
+ Match = ets:select(?COVER_TABLE,MatchSpec,?CHUNK_SIZE),
+ send_chunks(Match, CollectorPid, [])
+ end,Modules),
CollectorPid ! done,
remote_reply(From, ok).
-send_collected_data({M,F,A,C,_L}, CollectorPid) ->
- Pattern =
- {#bump{module=M, function=F, arity=A, clause=C}, '_'},
- Bumps = ets:match_object(?COVER_TABLE, Pattern),
- %% Reset
- lists:foreach(fun({Bump,_N}) ->
- ets:insert(?COVER_TABLE, {Bump,0})
- end,
- Bumps),
- CollectorPid ! {chunk,Bumps}.
+send_chunks('$end_of_table', _CollectorPid, Mons) ->
+ get_downs(Mons);
+send_chunks({Chunk,Continuation}, CollectorPid, Mons) ->
+ Mon = spawn_monitor(
+ fun() ->
+ lists:foreach(fun({Bump,_N}) ->
+ ets:insert(?COVER_TABLE, {Bump,0})
+ end,
+ Chunk) end),
+ send_chunk(CollectorPid,Chunk),
+ send_chunks(ets:select(Continuation), CollectorPid, [Mon|Mons]).
+
+send_chunk(CollectorPid,Chunk) ->
+ CollectorPid ! {chunk,Chunk,self()},
+ receive continue -> ok end.
+
+get_downs([]) ->
+ ok;
+get_downs(Mons) ->
+ receive
+ {'DOWN', Ref, _Type, Pid, _Reason} = Down ->
+ case lists:member({Pid,Ref},Mons) of
+ true ->
+ get_downs(lists:delete({Pid,Ref},Mons));
+ false ->
+ %% This should be handled somewhere else
+ self() ! Down,
+ get_downs(Mons)
+ end
+ end.
-reload_originals([{Module,_File}|Compiled]) ->
- do_reload_original(Module),
- reload_originals(Compiled);
-reload_originals([]) ->
- ok.
+reload_originals(Compiled) ->
+ Modules = [M || {M,_} <- Compiled],
+ pmap(fun do_reload_original/1, Modules).
do_reload_original(Module) ->
case code:which(Module) of
@@ -946,14 +1018,24 @@ load_compiled([{Module,File,Binary,InitialTable}|Compiled],Acc) ->
%% Make sure the #bump{} records are available *before* the
%% module is loaded.
insert_initial_data(InitialTable),
- NewAcc =
- case code:load_binary(Module, ?TAG, Binary) of
- {module,Module} ->
- add_compiled(Module, File, Acc);
- _ ->
- do_clear(Module),
- Acc
- end,
+ Sticky = case code:is_sticky(Module) of
+ true ->
+ code:unstick_mod(Module),
+ true;
+ false ->
+ false
+ end,
+ NewAcc = case code:load_binary(Module, ?TAG, Binary) of
+ {module,Module} ->
+ add_compiled(Module, File, Acc);
+ _ ->
+ do_clear(Module),
+ Acc
+ end,
+ case Sticky of
+ true -> code:stick_mod(Module);
+ false -> ok
+ end,
load_compiled(Compiled,NewAcc);
load_compiled([],Acc) ->
Acc.
@@ -1068,15 +1150,40 @@ remote_load_compiled(_Nodes, [], [], _ModNum) ->
ok;
remote_load_compiled(Nodes, Compiled, Acc, ModNum)
when Compiled == []; ModNum == ?MAX_MODS ->
+ RemoteLoadData = get_downs_r(Acc),
lists:foreach(
fun(Node) ->
- remote_call(Node,{remote,load_compiled,Acc})
+ remote_call(Node,{remote,load_compiled,RemoteLoadData})
end,
Nodes),
remote_load_compiled(Nodes, Compiled, [], 0);
remote_load_compiled(Nodes, [MF | Rest], Acc, ModNum) ->
remote_load_compiled(
- Nodes, Rest, [get_data_for_remote_loading(MF) | Acc], ModNum + 1).
+ Nodes, Rest,
+ [spawn_job_r(fun() -> get_data_for_remote_loading(MF) end) | Acc],
+ ModNum + 1).
+
+spawn_job_r(Fun) ->
+ spawn_monitor(fun() -> exit(Fun()) end).
+
+get_downs_r([]) ->
+ [];
+get_downs_r(Mons) ->
+ receive
+ {'DOWN', Ref, _Type, Pid, R={_,_,_,_}} ->
+ [R|get_downs_r(lists:delete({Pid,Ref},Mons))];
+ {'DOWN', Ref, _Type, Pid, Reason} = Down ->
+ case lists:member({Pid,Ref},Mons) of
+ true ->
+ %% Something went really wrong - don't hang!
+ exit(Reason);
+ false ->
+ %% This should be handled somewhere else
+ self() ! Down,
+ get_downs_r(Mons)
+ end
+ end.
+
%% Read all data needed for loading a cover compiled module on a remote node
%% Binary is the beam code for the module and InitialTable is the initial
@@ -1113,11 +1220,11 @@ remote_reset(Module,Nodes) ->
Nodes).
%% Collect data from remote nodes - used for analyse or stop(Node)
-remote_collect(Module,Nodes,Stop) ->
+remote_collect(Modules,Nodes,Stop) ->
pmap(fun(Node) ->
?SPAWN_DBG(remote_collect,
- {Module, Nodes, Stop}),
- do_collection(Node, Module, Stop)
+ {Modules, Nodes, Stop}),
+ do_collection(Node, Modules, Stop)
end,
Nodes).
@@ -1138,8 +1245,9 @@ do_collection(Node, Module, Stop) ->
collector_proc() ->
?SPAWN_DBG(collector_proc, []),
receive
- {chunk,Chunk} ->
+ {chunk,Chunk,From} ->
insert_in_collection_table(Chunk),
+ From ! continue,
collector_proc();
done ->
ok
@@ -1259,6 +1367,19 @@ add_compiled(Module, File, [H|Compiled]) ->
add_compiled(Module, File, []) ->
[{Module,File}].
+are_loaded([Module|Modules], State, Loaded, Imported, Error) ->
+ try is_loaded(Module,State) of
+ {loaded,File} ->
+ are_loaded(Modules, State, [{Module,File}|Loaded], Imported, Error);
+ {imported,File,_} ->
+ are_loaded(Modules, State, Loaded, [{Module,File}|Imported], Error)
+ catch throw:_ ->
+ are_loaded(Modules, State, Loaded, Imported,
+ [{not_cover_compiled,Module}|Error])
+ end;
+are_loaded([], _State, Loaded, Imported, Error) ->
+ {Loaded, Imported, Error}.
+
is_loaded(Module, State) ->
case get_file(Module, State#main_state.compiled) of
{ok, File} ->
@@ -1333,18 +1454,75 @@ get_compiled_still_loaded(Nodes,Compiled0) ->
%%%--Compilation---------------------------------------------------------
-%% do_compile(File, Options) -> {ok,Module} | {error,Error}
-do_compile(File, UserOptions) ->
+do_compile_beams(ModsAndFiles, State) ->
+ Result0 = pmap(fun({ok,Module,File}) ->
+ do_compile_beam(Module,File,State);
+ (Error) ->
+ Error
+ end,
+ ModsAndFiles),
+ Compiled = [{M,F} || {ok,M,F} <- Result0],
+ remote_load_compiled(State#main_state.nodes,Compiled),
+ fix_state_and_result(Result0,State,[]).
+
+do_compile_beam(Module,BeamFile0,State) ->
+ case get_beam_file(Module,BeamFile0,State#main_state.compiled) of
+ {ok,BeamFile} ->
+ UserOptions = get_compile_options(Module,BeamFile),
+ case do_compile_beam1(Module,BeamFile,UserOptions) of
+ {ok, Module} ->
+ {ok,Module,BeamFile};
+ error ->
+ {error, BeamFile};
+ {error,Reason} -> % no abstract code or no 'file' attribute
+ {error, {Reason, BeamFile}}
+ end;
+ {error,no_beam} ->
+ %% The module has first been compiled from .erl, and now
+ %% someone tries to compile it from .beam
+ {error,{already_cover_compiled,no_beam_found,Module}}
+ end.
+
+fix_state_and_result([{ok,Module,BeamFile}|Rest],State,Acc) ->
+ Compiled = add_compiled(Module,BeamFile,State#main_state.compiled),
+ Imported = remove_imported(Module,State#main_state.imported),
+ NewState = State#main_state{compiled=Compiled,imported=Imported},
+ fix_state_and_result(Rest,NewState,[{ok,Module}|Acc]);
+fix_state_and_result([Error|Rest],State,Acc) ->
+ fix_state_and_result(Rest,State,[Error|Acc]);
+fix_state_and_result([],State,Acc) ->
+ {lists:reverse(Acc),State}.
+
+
+do_compile(Files, Options, State) ->
+ Result0 = pmap(fun(File) ->
+ do_compile(File, Options)
+ end,
+ Files),
+ Compiled = [{M,F} || {ok,M,F} <- Result0],
+ remote_load_compiled(State#main_state.nodes,Compiled),
+ fix_state_and_result(Result0,State,[]).
+
+do_compile(File, Options) ->
+ case do_compile1(File, Options) of
+ {ok, Module} ->
+ {ok,Module,File};
+ error ->
+ {error,File}
+ end.
+
+%% do_compile1(File, Options) -> {ok,Module} | error
+do_compile1(File, UserOptions) ->
Options = [debug_info,binary,report_errors,report_warnings] ++ UserOptions,
case compile:file(File, Options) of
{ok, Module, Binary} ->
- do_compile_beam(Module,Binary,UserOptions);
+ do_compile_beam1(Module,Binary,UserOptions);
error ->
error
end.
%% Beam is a binary or a .beam file name
-do_compile_beam(Module,Beam,UserOptions) ->
+do_compile_beam1(Module,Beam,UserOptions) ->
%% Clear database
do_clear(Module),
@@ -1359,32 +1537,11 @@ do_compile_beam(Module,Beam,UserOptions) ->
{error,E};
{raw_abstract_v1,Code} ->
Forms0 = epp:interpret_file_attribute(Code),
- {Forms,Vars} = transform(Forms0, Module),
-
- %% We need to recover the source from the compilation
- %% info otherwise the newly compiled module will have
- %% source pointing to the current directory
- SourceInfo = get_source_info(Module, Beam),
-
- %% Compile and load the result
- %% It's necessary to check the result of loading since it may
- %% fail, for example if Module resides in a sticky directory
- {ok, Module, Binary} = compile:forms(Forms, SourceInfo ++ UserOptions),
- case code:load_binary(Module, ?TAG, Binary) of
- {module, Module} ->
-
- %% Store info about all function clauses in database
- InitInfo = lists:reverse(Vars#vars.init_info),
- ets:insert(?COVER_CLAUSE_TABLE, {Module, InitInfo}),
-
- %% Store binary code so it can be loaded on remote nodes
- ets:insert(?BINARY_TABLE, {Module, Binary}),
-
- {ok, Module};
-
- _Error ->
- do_clear(Module),
- error
+ case find_main_filename(Forms0) of
+ {ok,MainFile} ->
+ do_compile_beam2(Module,Beam,UserOptions,Forms0,MainFile);
+ Error ->
+ Error
end;
{_VSN,_Code} ->
%% Wrong version of abstract code. Just report that there
@@ -1401,6 +1558,35 @@ get_abstract_code(Module, Beam) ->
Error -> Error
end.
+do_compile_beam2(Module,Beam,UserOptions,Forms0,MainFile) ->
+ {Forms,Vars} = transform(Forms0, Module, MainFile),
+
+ %% We need to recover the source from the compilation
+ %% info otherwise the newly compiled module will have
+ %% source pointing to the current directory
+ SourceInfo = get_source_info(Module, Beam),
+
+ %% Compile and load the result
+ %% It's necessary to check the result of loading since it may
+ %% fail, for example if Module resides in a sticky directory
+ {ok, Module, Binary} = compile:forms(Forms, SourceInfo ++ UserOptions),
+ case code:load_binary(Module, ?TAG, Binary) of
+ {module, Module} ->
+
+ %% Store info about all function clauses in database
+ InitInfo = lists:reverse(Vars#vars.init_info),
+ ets:insert(?COVER_CLAUSE_TABLE, {Module, InitInfo}),
+
+ %% Store binary code so it can be loaded on remote nodes
+ ets:insert(?BINARY_TABLE, {Module, Binary}),
+
+ {ok, Module};
+
+ _Error ->
+ do_clear(Module),
+ error
+ end.
+
get_source_info(Module, Beam) ->
Compile = get_compile_info(Module, Beam),
case lists:keyfind(source, 1, Compile) of
@@ -1423,8 +1609,7 @@ get_compile_info(Module, Beam) ->
[]
end.
-transform(Code, Module) ->
- MainFile=find_main_filename(Code),
+transform(Code, Module, MainFile) ->
Vars0 = #vars{module=Module},
{ok,MungedForms,Vars} = transform_2(Code,[],Vars0,MainFile,on),
{MungedForms,Vars}.
@@ -1432,9 +1617,12 @@ transform(Code, Module) ->
%% Helpfunction which returns the first found file-attribute, which can
%% be interpreted as the name of the main erlang source file.
find_main_filename([{attribute,_,file,{MainFile,_}}|_]) ->
- MainFile;
+ {ok,MainFile};
find_main_filename([_|Rest]) ->
- find_main_filename(Rest).
+ find_main_filename(Rest);
+find_main_filename([]) ->
+ {error, no_file_attribute}.
+
transform_2([Form0|Forms],MungedForms,Vars,MainFile,Switch) ->
Form = expand(Form0),
@@ -1459,18 +1647,18 @@ expand({clause,Line,Pattern,Guards,Body}, Vs, N) ->
expand({op,_Line,'andalso',ExprL,ExprR}, Vs, N) ->
{ExpandedExprL,N2} = expand(ExprL, Vs, N),
{ExpandedExprR,N3} = expand(ExprR, Vs, N2),
- LineL = element(2, ExpandedExprL),
+ Anno = element(2, ExpandedExprL),
{bool_switch(ExpandedExprL,
ExpandedExprR,
- {atom,LineL,false},
+ {atom,Anno,false},
Vs, N3),
N3 + 1};
expand({op,_Line,'orelse',ExprL,ExprR}, Vs, N) ->
{ExpandedExprL,N2} = expand(ExprL, Vs, N),
{ExpandedExprR,N3} = expand(ExprR, Vs, N2),
- LineL = element(2, ExpandedExprL),
+ Anno = element(2, ExpandedExprL),
{bool_switch(ExpandedExprL,
- {atom,LineL,true},
+ {atom,Anno,true},
ExpandedExprR,
Vs, N3),
N3 + 1};
@@ -1579,7 +1767,7 @@ munge_body(Expr, Vars) ->
munge_body([Expr|Body], Vars, MungedBody, LastExprBumpLines) ->
%% Here is the place to add a call to cover:bump/6!
- Line = element(2, Expr),
+ Line = erl_anno:line(element(2, Expr)),
Lines = Vars#vars.lines,
case lists:member(Line,Lines) of
true -> % already a bump at this line
@@ -1715,17 +1903,18 @@ fix_cls([Cl | Cls], Line, Bump) ->
false ->
{clause,CL,P,G,Body} = Cl,
UniqueVarName = list_to_atom(lists:concat(["$cover$ ",Line])),
- V = {var,0,UniqueVarName},
+ A = erl_anno:new(0),
+ V = {var,A,UniqueVarName},
[Last|Rest] = lists:reverse(Body),
- Body1 = lists:reverse(Rest, [{match,0,V,Last},Bump,V]),
+ Body1 = lists:reverse(Rest, [{match,A,V,Last},Bump,V]),
[{clause,CL,P,G,Body1} | fix_cls(Cls, Line, Bump)]
end.
bumps_line(E, L) ->
try bumps_line1(E, L) catch true -> true end.
-bumps_line1({call,0,{remote,0,{atom,0,ets},{atom,0,update_counter}},
- [{atom,0,?COVER_TABLE},{tuple,0,[_,_,_,_,_,{integer,0,Line}]},_]},
+bumps_line1({call,_,{remote,_,{atom,_,ets},{atom,_,update_counter}},
+ [{atom,_,?COVER_TABLE},{tuple,_,[_,_,_,_,_,{integer,_,Line}]},_]},
Line) ->
throw(true);
bumps_line1([E | Es], Line) ->
@@ -1739,15 +1928,16 @@ bumps_line1(_, _) ->
%%% End of fix of last expression.
bump_call(Vars, Line) ->
- {call,0,{remote,0,{atom,0,ets},{atom,0,update_counter}},
- [{atom,0,?COVER_TABLE},
- {tuple,0,[{atom,0,?BUMP_REC_NAME},
- {atom,0,Vars#vars.module},
- {atom,0,Vars#vars.function},
- {integer,0,Vars#vars.arity},
- {integer,0,Vars#vars.clause},
- {integer,0,Line}]},
- {integer,0,1}]}.
+ A = erl_anno:new(0),
+ {call,A,{remote,A,{atom,A,ets},{atom,A,update_counter}},
+ [{atom,A,?COVER_TABLE},
+ {tuple,A,[{atom,A,?BUMP_REC_NAME},
+ {atom,A,Vars#vars.module},
+ {atom,A,Vars#vars.function},
+ {integer,A,Vars#vars.arity},
+ {integer,A,Vars#vars.clause},
+ {integer,A,Line}]},
+ {integer,A,1}]}.
munge_expr({match,Line,ExprL,ExprR}, Vars) ->
{MungedExprL, Vars2} = munge_expr(ExprL, Vars),
@@ -1815,7 +2005,7 @@ munge_expr({lc,Line,Expr,Qs}, Vars) ->
{{lc,Line,MungedExpr,MungedQs}, Vars3};
munge_expr({bc,Line,Expr,Qs}, Vars) ->
{bin,BLine,[{bin_element,EL,Val,Sz,TSL}|Es]} = Expr,
- Expr2 = {bin,BLine,[{bin_element,EL,?BLOCK1(Val),Sz,TSL}|Es]},
+ Expr2 = {bin,BLine,[{bin_element,EL,Val,Sz,TSL}|Es]},
{MungedExpr,Vars2} = munge_expr(Expr2, Vars),
{MungedQs, Vars3} = munge_qualifiers(Qs, Vars2),
{{bc,Line,MungedExpr,MungedQs}, Vars3};
@@ -1915,10 +2105,21 @@ common_elems(L1, L2) ->
collect(Nodes) ->
%% local node
AllClauses = ets:tab2list(?COVER_CLAUSE_TABLE),
- pmap(fun move_modules/1,AllClauses),
-
+ Mon1 = spawn_monitor(fun() -> pmap(fun move_modules/1,AllClauses) end),
+
%% remote nodes
- remote_collect('_',Nodes,false).
+ Mon2 = spawn_monitor(fun() -> remote_collect('_',Nodes,false) end),
+ get_downs([Mon1,Mon2]).
+
+%% Collect data for a list of modules
+collect(Modules,Nodes) ->
+ MS = [{{'$1','_'},[{'==','$1',M}],['$_']} || M <- Modules],
+ Clauses = ets:select(?COVER_CLAUSE_TABLE,MS),
+ Mon1 = spawn_monitor(fun() -> pmap(fun move_modules/1,Clauses) end),
+
+ %% remote nodes
+ Mon2 = spawn_monitor(fun() -> remote_collect('_',Nodes,false) end),
+ get_downs([Mon1,Mon2]).
%% Collect data for one module
collect(Module,Clauses,Nodes) ->
@@ -1926,25 +2127,26 @@ collect(Module,Clauses,Nodes) ->
move_modules({Module,Clauses}),
%% remote nodes
- remote_collect(Module,Nodes,false).
+ remote_collect([Module],Nodes,false).
%% When analysing, the data from the local ?COVER_TABLE is moved to the
%% ?COLLECTION_TABLE. Resetting data in ?COVER_TABLE
move_modules({Module,Clauses}) ->
ets:insert(?COLLECTION_CLAUSE_TABLE,{Module,Clauses}),
- move_clauses(Clauses).
+ Pattern = {#bump{module=Module, _='_'}, '_'},
+ MatchSpec = [{Pattern,[],['$_']}],
+ Match = ets:select(?COVER_TABLE,MatchSpec,?CHUNK_SIZE),
+ do_move_module(Match).
-move_clauses([{M,F,A,C,_L}|Clauses]) ->
- Pattern = {#bump{module=M, function=F, arity=A, clause=C}, '_'},
- Bumps = ets:match_object(?COVER_TABLE,Pattern),
+do_move_module({Bumps,Continuation}) ->
lists:foreach(fun({Key,Val}) ->
ets:insert(?COVER_TABLE, {Key,0}),
insert_in_collection_table(Key,Val)
end,
Bumps),
- move_clauses(Clauses);
-move_clauses([]) ->
+ do_move_module(ets:select(Continuation));
+do_move_module('$end_of_table') ->
ok.
%% Given a .beam file, find the .erl file. Look first in same directory as
@@ -1962,7 +2164,13 @@ find_source(Module, File0) ->
throw_file(filename:join([BeamDir, "..", "src", Base])),
%% Not in ../src: look for source path in compile info, but
%% first look relative the beam directory.
- Info = lists:keyfind(source, 1, Module:module_info(compile)),
+ Info =
+ try lists:keyfind(source, 1, Module:module_info(compile))
+ catch error:undef ->
+ %% The module might have been imported
+ %% and the beam not available
+ throw({beam, File0})
+ end,
false == Info andalso throw({beam, File0}), %% stripped
{source, SrcFile} = Info,
throw_file(splice(BeamDir, SrcFile)), %% below ../src
@@ -2002,6 +2210,26 @@ splice(BeamDir, SrcFile) ->
revsplit(Path) ->
lists:reverse(filename:split(Path)).
+analyse_list(Modules, Analysis, Level, State) ->
+ {LoadedMF, ImportedMF, Error} = are_loaded(Modules, State, [], [], []),
+ Loaded = [M || {M,_} <- LoadedMF],
+ Imported = [M || {M,_} <- ImportedMF],
+ collect(Loaded, State#main_state.nodes),
+ MS = [{{'$1','_'},[{'==','$1',M}],['$_']} || M <- Loaded ++ Imported],
+ AllClauses = ets:select(?COLLECTION_CLAUSE_TABLE,MS),
+ Fun = fun({Module,Clauses}) ->
+ do_analyse(Module, Analysis, Level, Clauses)
+ end,
+ {result, lists:flatten(pmap(Fun, AllClauses)), Error}.
+
+analyse_all(Analysis, Level, State) ->
+ collect(State#main_state.nodes),
+ AllClauses = ets:tab2list(?COLLECTION_CLAUSE_TABLE),
+ Fun = fun({Module,Clauses}) ->
+ do_analyse(Module, Analysis, Level, Clauses)
+ end,
+ {result, lists:flatten(pmap(Fun, AllClauses)), []}.
+
do_parallel_analysis(Module, Analysis, Level, Loaded, From, State) ->
analyse_info(Module,State#main_state.imported),
C = case Loaded of
@@ -2016,7 +2244,7 @@ do_parallel_analysis(Module, Analysis, Level, Loaded, From, State) ->
Clauses
end,
R = do_analyse(Module, Analysis, Level, C),
- reply(From, R).
+ reply(From, {ok,R}).
%% do_analyse(Module, Analysis, Level, Clauses)-> {ok,Answer} | {error,Error}
%% Clauses = [{Module,Function,Arity,Clause,Lines}]
@@ -2035,37 +2263,44 @@ do_analyse(Module, Analysis, line, _Clauses) ->
{{Module,L}, N}
end
end,
- Answer = lists:keysort(1, lists:map(Fun, Bumps)),
- {ok, Answer};
-do_analyse(_Module, Analysis, clause, Clauses) ->
- Fun = case Analysis of
- coverage ->
- fun({M,F,A,C,Ls}) ->
- Pattern = {#bump{module=M,function=F,arity=A,
- clause=C},0},
- Bumps = ets:match_object(?COLLECTION_TABLE, Pattern),
- NotCov = length(Bumps),
- {{M,F,A,C}, {Ls-NotCov, NotCov}}
- end;
- calls ->
- fun({M,F,A,C,_Ls}) ->
- Pattern = {#bump{module=M,function=F,arity=A,
- clause=C},'_'},
- Bumps = ets:match_object(?COLLECTION_TABLE, Pattern),
- {_Bump, Calls} = hd(lists:keysort(1, Bumps)),
- {{M,F,A,C}, Calls}
- end
- end,
- Answer = lists:map(Fun, Clauses),
- {ok, Answer};
+ lists:keysort(1, lists:map(Fun, Bumps));
+do_analyse(Module, Analysis, clause, _Clauses) ->
+ Pattern = {#bump{module=Module},'_'},
+ Bumps = lists:keysort(1,ets:match_object(?COLLECTION_TABLE, Pattern)),
+ analyse_clause(Analysis,Bumps);
do_analyse(Module, Analysis, function, Clauses) ->
- {ok, ClauseResult} = do_analyse(Module, Analysis, clause, Clauses),
- Result = merge_clauses(ClauseResult, merge_fun(Analysis)),
- {ok, Result};
+ ClauseResult = do_analyse(Module, Analysis, clause, Clauses),
+ merge_clauses(ClauseResult, merge_fun(Analysis));
do_analyse(Module, Analysis, module, Clauses) ->
- {ok, FunctionResult} = do_analyse(Module, Analysis, function, Clauses),
+ FunctionResult = do_analyse(Module, Analysis, function, Clauses),
Result = merge_functions(FunctionResult, merge_fun(Analysis)),
- {ok, {Module,Result}}.
+ {Module,Result}.
+
+analyse_clause(_,[]) ->
+ [];
+analyse_clause(coverage,
+ [{#bump{module=M,function=F,arity=A,clause=C},_}|_]=Bumps) ->
+ analyse_clause_cov(Bumps,{M,F,A,C},0,0,[]);
+analyse_clause(calls,Bumps) ->
+ analyse_clause_calls(Bumps,{x,x,x,x},[]).
+
+analyse_clause_cov([{#bump{module=M,function=F,arity=A,clause=C},N}|Bumps],
+ {M,F,A,C}=Clause,Ls,NotCov,Acc) ->
+ analyse_clause_cov(Bumps,Clause,Ls+1,if N==0->NotCov+1; true->NotCov end,Acc);
+analyse_clause_cov([{#bump{module=M1,function=F1,arity=A1,clause=C1},_}|_]=Bumps,
+ Clause,Ls,NotCov,Acc) ->
+ analyse_clause_cov(Bumps,{M1,F1,A1,C1},0,0,[{Clause,{Ls-NotCov,NotCov}}|Acc]);
+analyse_clause_cov([],Clause,Ls,NotCov,Acc) ->
+ lists:reverse(Acc,[{Clause,{Ls-NotCov,NotCov}}]).
+
+analyse_clause_calls([{#bump{module=M,function=F,arity=A,clause=C},_}|Bumps],
+ {M,F,A,C}=Clause,Acc) ->
+ analyse_clause_calls(Bumps,Clause,Acc);
+analyse_clause_calls([{#bump{module=M1,function=F1,arity=A1,clause=C1},N}|Bumps],
+ _Clause,Acc) ->
+ analyse_clause_calls(Bumps,{M1,F1,A1,C1},[{{M1,F1,A1,C1},N}|Acc]);
+analyse_clause_calls([],_Clause,Acc) ->
+ lists:reverse(Acc).
merge_fun(coverage) ->
fun({Cov1,NotCov1}, {Cov2,NotCov2}) ->
@@ -2094,7 +2329,50 @@ merge_functions([{_MFA,R}|Functions], MFun, Result) ->
merge_functions([], _MFun, Result) ->
Result.
-do_parallel_analysis_to_file(Module, OutFile, Opts, Loaded, From, State) ->
+analyse_list_to_file(Modules, Opts, State) ->
+ {LoadedMF, ImportedMF, Error} = are_loaded(Modules, State, [], [], []),
+ collect([M || {M,_} <- LoadedMF], State#main_state.nodes),
+ OutDir = proplists:get_value(outdir,Opts),
+ HTML = lists:member(html,Opts),
+ Fun = fun({Module,File}) ->
+ OutFile = outfilename(OutDir,Module,HTML),
+ do_analyse_to_file(Module,File,OutFile,HTML,State)
+ end,
+ {Ok,Error1} = split_ok_error(pmap(Fun, LoadedMF++ImportedMF),[],[]),
+ {result,Ok,Error ++ Error1}.
+
+analyse_all_to_file(Opts, State) ->
+ collect(State#main_state.nodes),
+ AllModules = get_all_modules(State),
+ OutDir = proplists:get_value(outdir,Opts),
+ HTML = lists:member(html,Opts),
+ Fun = fun({Module,File}) ->
+ OutFile = outfilename(OutDir,Module,HTML),
+ do_analyse_to_file(Module,File,OutFile,HTML,State)
+ end,
+ {Ok,Error} = split_ok_error(pmap(Fun, AllModules),[],[]),
+ {result,Ok,Error}.
+
+get_all_modules(State) ->
+ get_all_modules(State#main_state.compiled ++ State#main_state.imported,[]).
+get_all_modules([{Module,File}|Rest],Acc) ->
+ get_all_modules(Rest,[{Module,File}|Acc]);
+get_all_modules([{Module,File,_}|Rest],Acc) ->
+ case lists:keymember(Module,1,Acc) of
+ true -> get_all_modules(Rest,Acc);
+ false -> get_all_modules(Rest,[{Module,File}|Acc])
+ end;
+get_all_modules([],Acc) ->
+ Acc.
+
+split_ok_error([{ok,R}|Result],Ok,Error) ->
+ split_ok_error(Result,[R|Ok],Error);
+split_ok_error([{error,R}|Result],Ok,Error) ->
+ split_ok_error(Result,Ok,[R|Error]);
+split_ok_error([],Ok,Error) ->
+ {Ok,Error}.
+
+do_parallel_analysis_to_file(Module, Opts, Loaded, From, State) ->
File = case Loaded of
{loaded, File0} ->
[{Module,Clauses}] =
@@ -2105,24 +2383,32 @@ do_parallel_analysis_to_file(Module, OutFile, Opts, Loaded, From, State) ->
{imported, File0, _} ->
File0
end,
+ HTML = lists:member(html,Opts),
+ OutFile =
+ case proplists:get_value(outfile,Opts) of
+ undefined ->
+ outfilename(proplists:get_value(outdir,Opts),Module,HTML);
+ F ->
+ F
+ end,
+ reply(From, do_analyse_to_file(Module,File,OutFile,HTML,State)).
+
+do_analyse_to_file(Module,File,OutFile,HTML,State) ->
case find_source(Module, File) of
{beam,_BeamFile} ->
- reply(From, {error,no_source_code_found});
+ {error,{no_source_code_found,Module}};
ErlFile ->
analyse_info(Module,State#main_state.imported),
- HTML = lists:member(html,Opts),
- R = do_analyse_to_file(Module,OutFile,
- ErlFile,HTML),
- reply(From, R)
+ do_analyse_to_file1(Module,OutFile,ErlFile,HTML)
end.
-%% do_analyse_to_file(Module,OutFile,ErlFile) -> {ok,OutFile} | {error,Error}
+%% do_analyse_to_file1(Module,OutFile,ErlFile) -> {ok,OutFile} | {error,Error}
%% Module = atom()
%% OutFile = ErlFile = string()
-do_analyse_to_file(Module, OutFile, ErlFile, HTML) ->
- case file:open(ErlFile, [read]) of
+do_analyse_to_file1(Module, OutFile, ErlFile, HTML) ->
+ case file:open(ErlFile, [read,raw,read_ahead]) of
{ok, InFd} ->
- case file:open(OutFile, [write]) of
+ case file:open(OutFile, [write,raw,delayed_write]) of
{ok, OutFd} ->
if HTML ->
Encoding = encoding(ErlFile),
@@ -2160,9 +2446,14 @@ do_analyse_to_file(Module, OutFile, ErlFile, HTML) ->
"**************************************"
"\n\n"]),
- print_lines(Module, InFd, OutFd, 1, HTML),
+ Pattern = {#bump{module=Module,line='$1',_='_'},'$2'},
+ MS = [{Pattern,[{is_integer,'$1'},{'>','$1',0}],[{{'$1','$2'}}]}],
+ CovLines = lists:keysort(1,ets:select(?COLLECTION_TABLE, MS)),
+ print_lines(Module, CovLines, InFd, OutFd, 1, HTML),
- if HTML -> io:format(OutFd,"</pre>\n</body>\n</html>\n",[]);
+ if
+ HTML ->
+ file:write(OutFd, "</pre>\n</body>\n</html>\n");
true -> ok
end,
@@ -2179,21 +2470,19 @@ do_analyse_to_file(Module, OutFile, ErlFile, HTML) ->
{error, {file, ErlFile, Reason}}
end.
-print_lines(Module, InFd, OutFd, L, HTML) ->
- case io:get_line(InFd, '') of
+
+print_lines(Module, CovLines, InFd, OutFd, L, HTML) ->
+ case file:read_line(InFd) of
eof ->
ignore;
- "%"++_=Line -> %Comment line - not executed.
- io:put_chars(OutFd, [tab(),escape_lt_and_gt(Line, HTML)]),
- print_lines(Module, InFd, OutFd, L+1, HTML);
- RawLine ->
+ {ok,"%"++_=Line} -> %Comment line - not executed.
+ file:write(OutFd, [tab(),escape_lt_and_gt(Line, HTML)]),
+ print_lines(Module, CovLines, InFd, OutFd, L+1, HTML);
+ {ok,RawLine} ->
Line = escape_lt_and_gt(RawLine,HTML),
- Pattern = {#bump{module=Module,line=L},'$1'},
- case ets:match(?COLLECTION_TABLE, Pattern) of
- [] ->
- io:put_chars(OutFd, [tab(),Line]);
- Ns ->
- N = lists:foldl(fun([Ni], Nacc) -> Nacc+Ni end, 0, Ns),
+ case CovLines of
+ [{L,N}|CovLines1] ->
+ %% N = lists:foldl(fun([Ni], Nacc) -> Nacc+Ni end, 0, Ns),
if
N=:=0, HTML=:=true ->
LineNoNL = Line -- "\n",
@@ -2201,19 +2490,22 @@ print_lines(Module, InFd, OutFd, L, HTML) ->
%%Str = string:right("0", 6, 32),
RedLine = ["<font color=red>",Str,fill1(),
LineNoNL,"</font>\n"],
- io:put_chars(OutFd, RedLine);
+ file:write(OutFd, RedLine);
N<1000000 ->
Str = string:right(integer_to_list(N), 6, 32),
- io:put_chars(OutFd, [Str,fill1(),Line]);
+ file:write(OutFd, [Str,fill1(),Line]);
N<10000000 ->
Str = integer_to_list(N),
- io:put_chars(OutFd, [Str,fill2(),Line]);
+ file:write(OutFd, [Str,fill2(),Line]);
true ->
Str = integer_to_list(N),
- io:put_chars(OutFd, [Str,fill3(),Line])
- end
- end,
- print_lines(Module, InFd, OutFd, L+1, HTML)
+ file:write(OutFd, [Str,fill3(),Line])
+ end,
+ print_lines(Module, CovLines1, InFd, OutFd, L+1, HTML);
+ _ ->
+ file:write(OutFd, [tab(),Line]),
+ print_lines(Module, CovLines, InFd, OutFd, L+1, HTML)
+ end
end.
tab() -> " | ".
@@ -2223,7 +2515,7 @@ fill3() -> "| ".
%%%--Export--------------------------------------------------------------
do_export(Module, OutFile, From, State) ->
- case file:open(OutFile,[write,binary,raw]) of
+ case file:open(OutFile,[write,binary,raw,delayed_write]) of
{ok,Fd} ->
Reply =
case Module of
@@ -2362,21 +2654,21 @@ do_reset_collection_table(Module) ->
ets:match_delete(?COLLECTION_TABLE, {#bump{module=Module},'_'}).
%% do_reset(Module) -> ok
-%% The reset is done on a per-clause basis to avoid building
+%% The reset is done on ?CHUNK_SIZE number of bumps to avoid building
%% long lists in the case of very large modules
do_reset(Module) ->
- [{Module,Clauses}] = ets:lookup(?COVER_CLAUSE_TABLE, Module),
- do_reset2(Clauses).
+ Pattern = {#bump{module=Module, _='_'}, '$1'},
+ MatchSpec = [{Pattern,[{'=/=','$1',0}],['$_']}],
+ Match = ets:select(?COVER_TABLE,MatchSpec,?CHUNK_SIZE),
+ do_reset2(Match).
-do_reset2([{M,F,A,C,_L}|Clauses]) ->
- Pattern = {#bump{module=M, function=F, arity=A, clause=C}, '_'},
- Bumps = ets:match_object(?COVER_TABLE, Pattern),
+do_reset2({Bumps,Continuation}) ->
lists:foreach(fun({Bump,_N}) ->
ets:insert(?COVER_TABLE, {Bump,0})
end,
Bumps),
- do_reset2(Clauses);
-do_reset2([]) ->
+ do_reset2(ets:select(Continuation));
+do_reset2('$end_of_table') ->
ok.
do_clear(Module) ->
@@ -2419,31 +2711,43 @@ escape_lt_and_gt1([],Acc) ->
escape_lt_and_gt1([H|T],Acc) ->
escape_lt_and_gt1(T,[H|Acc]).
-pmap(Fun, List) ->
- pmap(Fun, List, 20).
-pmap(Fun, List, Limit) ->
- pmap(Fun, List, [], Limit, 0, []).
-pmap(Fun, [E | Rest], Pids, Limit, Cnt, Acc) when Cnt < Limit ->
- Collector = self(),
- Pid = spawn_link(fun() ->
- ?SPAWN_DBG(pmap,E),
- Collector ! {res,self(),Fun(E)}
- end),
- erlang:monitor(process, Pid),
- pmap(Fun, Rest, Pids ++ [Pid], Limit, Cnt + 1, Acc);
-pmap(Fun, List, [Pid | Pids], Limit, Cnt, Acc) ->
- receive
- {'DOWN', _Ref, process, X, _} when is_pid(X) ->
- pmap(Fun, List, [Pid | Pids], Limit, Cnt - 1, Acc);
- {res, Pid, Res} ->
- pmap(Fun, List, Pids, Limit, Cnt, [Res | Acc])
- end;
-pmap(_Fun, [], [], _Limit, 0, Acc) ->
- lists:reverse(Acc);
-pmap(Fun, [], [], Limit, Cnt, Acc) ->
+%%%--Internal functions for parallelization------------------------------
+pmap(Fun,List) ->
+ NTot = length(List),
+ NProcs = erlang:system_info(schedulers) * 2,
+ NPerProc = (NTot div NProcs) + 1,
+ Mons = pmap_spawn(Fun,NPerProc,List,[]),
+ pmap_collect(Mons,[]).
+
+pmap_spawn(_,_,[],Mons) ->
+ Mons;
+pmap_spawn(Fun,NPerProc,List,Mons) ->
+ {L1,L2} = if length(List)>=NPerProc -> lists:split(NPerProc,List);
+ true -> {List,[]} % last chunk
+ end,
+ Mon =
+ spawn_monitor(
+ fun() ->
+ exit({pmap_done,lists:map(Fun,L1)})
+ end),
+ pmap_spawn(Fun,NPerProc,L2,[Mon|Mons]).
+
+pmap_collect([],Acc) ->
+ lists:append(Acc);
+pmap_collect(Mons,Acc) ->
receive
- {'DOWN', _Ref, process, X, _} when is_pid(X) ->
- pmap(Fun, [], [], Limit, Cnt - 1, Acc)
+ {'DOWN', Ref, process, Pid, {pmap_done,Result}} ->
+ pmap_collect(lists:delete({Pid,Ref},Mons),[Result|Acc]);
+ {'DOWN', Ref, process, Pid, Reason} = Down ->
+ case lists:member({Pid,Ref},Mons) of
+ true ->
+ %% Something went really wrong - don't hang!
+ exit(Reason);
+ false ->
+ %% This should be handled somewhere else
+ self() ! Down,
+ pmap_collect(Mons,Acc)
+ end
end.
%%%-----------------------------------------------------------------
diff --git a/lib/tools/src/cover_web.erl b/lib/tools/src/cover_web.erl
index 69f2f3b1aa..ae8b3f25cf 100644
--- a/lib/tools/src/cover_web.erl
+++ b/lib/tools/src/cover_web.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -734,7 +735,7 @@ generate_filename(Prefix) ->
filename:join(Cwd,Prefix ++ "_" ++ ts() ++ ".coverdata").
ts() ->
- {{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(now()),
+ {{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(erlang:timestamp()),
io_lib:format("~4.4.0w~2.2.0w~2.2.0w-~2.2.0w~2.2.0w~2.2.0w",
[Y,M,D,H,Min,S]).
diff --git a/lib/tools/src/cprof.erl b/lib/tools/src/cprof.erl
index b0c3341efa..f6d68f0bf8 100644
--- a/lib/tools/src/cprof.erl
+++ b/lib/tools/src/cprof.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -113,6 +114,7 @@ analyse(Limit) when is_integer(Limit) ->
analyse(M) when is_atom(M) ->
analyse(M, 1).
+-dialyzer({no_improper_lists, analyse/2}).
analyse(M, Limit) when is_atom(M), is_integer(Limit) ->
L0 = [begin
MFA = {M,F,A},
diff --git a/lib/tools/src/eprof.erl b/lib/tools/src/eprof.erl
index bfbbefb473..0357e46a50 100644
--- a/lib/tools/src/eprof.erl
+++ b/lib/tools/src/eprof.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -187,7 +188,7 @@ handle_call({profile_start, Rootset, Pattern, {M,F,A}, Opts}, From, #state{fd =
case set_process_trace(true, [Pid|Rootset], Topts) of
true ->
ok = set_pattern_trace(true, Pattern),
- T0 = now(),
+ T0 = erlang:timestamp(),
ok = execute_profiling(Pid),
{noreply, #state{
profiling = true,
@@ -211,7 +212,7 @@ handle_call({profile_start, Rootset, Pattern, undefined, Opts}, From, #state{ fd
case set_process_trace(true, Rootset, Topts) of
true ->
- T0 = now(),
+ T0 = erlang:timestamp(),
ok = set_pattern_trace(true, Pattern),
{reply, profiling, #state{
profiling = true,
@@ -485,20 +486,22 @@ string_bp_mfa([{Mfa, {Count, Time}}|Mfas], Tus, {MfaW, CountW, PercW, TimeW, TpC
erlang:max(TpCW, length(Stpc))
}, [[Smfa, Scount, Sperc, Stime, Stpc] | Strings]).
-print_bp_mfa(Mfas, {_Tn, Tus}, Fd, Opts) ->
+print_bp_mfa(Mfas, {Tn, Tus}, Fd, Opts) ->
Fmfas = filter_mfa(sort_mfa(Mfas, proplists:get_value(sort, Opts)), proplists:get_value(filter, Opts)),
{{MfaW, CountW, PercW, TimeW, TpCW}, Strs} = string_bp_mfa(Fmfas, Tus),
- Ws = {
- erlang:max(length("FUNCTION"), MfaW),
- erlang:max(length("CALLS"), CountW),
- erlang:max(length(" %"), PercW),
- erlang:max(length("TIME"), TimeW),
- erlang:max(length("uS / CALLS"), TpCW)
- },
- format(Fd, Ws, ["FUNCTION", "CALLS", " %", "TIME", "uS / CALLS"]),
- format(Fd, Ws, ["--------", "-----", "---", "----", "----------"]),
-
+ TnStr = s(Tn),
+ TusStr = s(Tus),
+ TuspcStr = s("~.2f", [divide(Tus,Tn)]),
+ Ws = {erlang:max(length("FUNCTION"), MfaW),
+ lists:max([length("CALLS"), CountW, length(TnStr)]),
+ erlang:max(length(" %"), PercW),
+ lists:max([length("TIME"), TimeW, length(TusStr)]),
+ lists:max([length("uS / CALLS"), TpCW, length(TuspcStr)])},
+ format(Fd, Ws, ["FUNCTION", "CALLS", " %", "TIME", "uS / CALLS"]),
+ format(Fd, Ws, ["--------", "-----", "-------", "----", "----------"]),
lists:foreach(fun (String) -> format(Fd, Ws, String) end, Strs),
+ format(Fd, Ws, [lists:duplicate(N,$-)||N <- tuple_to_list(Ws)]),
+ format(Fd, Ws, ["Total:", TnStr, "100.00%", TusStr, TuspcStr]),
ok.
s({M,F,A}) -> s("~w:~w/~w",[M,F,A]);
diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl
index 75840e54ff..c5c24c8eb3 100644
--- a/lib/tools/src/fprof.erl
+++ b/lib/tools/src/fprof.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -2250,6 +2251,8 @@ do_analyse(Table, Analyse) ->
?dbg(5, "do_analyse_1(_, _) ->~p~n", [Result]),
Result.
+-dialyzer({no_improper_lists, do_analyse_1/2}).
+
do_analyse_1(Table,
#analyse{group_leader = GroupLeader,
dest = Io,
@@ -2623,6 +2626,8 @@ funcstat_pd(Pid, Func1, Func0, Clocks) ->
funcstat_sort_r(FuncstatList, Element) ->
funcstat_sort_r_1(FuncstatList, Element, []).
+-dialyzer({no_improper_lists, funcstat_sort_r_1/3}).
+
funcstat_sort_r_1([], _, R) ->
postsort_r(lists:sort(R));
funcstat_sort_r_1([#funcstat{callers_sum = #clocks{} = Clocks,
@@ -2645,6 +2650,8 @@ funcstat_sort_r_1([#funcstat{callers_sum = #clocks{} = Clocks,
clocks_sort_r(L, E) ->
clocks_sort_r_1(L, E, []).
+-dialyzer({no_improper_lists, clocks_sort_r_1/3}).
+
clocks_sort_r_1([], _, R) ->
postsort_r(lists:sort(R));
clocks_sort_r_1([#clocks{} = C | L], E, R) ->
diff --git a/lib/tools/src/instrument.erl b/lib/tools/src/instrument.erl
index fa8a4a4867..34c5ba04cc 100644
--- a/lib/tools/src/instrument.erl
+++ b/lib/tools/src/instrument.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl
index d5ba8aa52f..3a3cebf3ed 100644
--- a/lib/tools/src/lcnt.erl
+++ b/lib/tools/src/lcnt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -932,7 +933,6 @@ strings(Strings) -> strings(Strings, []).
strings([], Out) -> Out;
strings([{space, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string("~~~ws", [N]), [S]));
strings([{left, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string(" ~~s~~~ws", [N]), [S,""]));
-strings([{format, Format, S} | Ss], Out) -> strings(Ss, Out ++ term2string(Format, [S]));
strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~ts", [S])).
diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl
index c8ef0a04a5..5d5a1ef2bd 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -24,12 +25,20 @@
%% If Emakefile is missing the current directory is used.
-module(make).
--export([all/0,all/1,files/1,files/2]).
+-export([all_or_nothing/0,all/0,all/1,files/1,files/2]).
-include_lib("kernel/include/file.hrl").
-define(MakeOpts,[noexec,load,netload,noload]).
+all_or_nothing() ->
+ case all() of
+ up_to_date ->
+ up_to_date;
+ error ->
+ halt(1)
+ end.
+
all() ->
all([]).
diff --git a/lib/tools/src/tags.erl b/lib/tools/src/tags.erl
index e25db2eb1b..2bc1865503 100644
--- a/lib/tools/src/tags.erl
+++ b/lib/tools/src/tags.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/tools/src/tools.app.src b/lib/tools/src/tools.app.src
index ec5b6f3a82..978b54719c 100644
--- a/lib/tools/src/tools.app.src
+++ b/lib/tools/src/tools.app.src
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -40,8 +41,8 @@
{env, [{file_util_search_methods,[{"", ""}, {"ebin", "esrc"}, {"ebin", "src"}]}
]
},
- {runtime_dependencies, ["webtool-0.8.10","stdlib-2.0","runtime_tools-1.8.14",
- "kernel-3.0","inets-5.10","erts-6.0",
+ {runtime_dependencies, ["webtool-0.8.10","stdlib-2.5","runtime_tools-1.8.14",
+ "kernel-3.0","inets-5.10","erts-7.0",
"compiler-5.0"]}
]
}.
diff --git a/lib/tools/src/tools.appup.src b/lib/tools/src/tools.appup.src
index 9a27456a81..9eee8df184 100644
--- a/lib/tools/src/tools.appup.src
+++ b/lib/tools/src/tools.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/tools/src/xref.erl b/lib/tools/src/xref.erl
index abc184c84d..64add7afbb 100644
--- a/lib/tools/src/xref.erl
+++ b/lib/tools/src/xref.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/tools/src/xref.hrl b/lib/tools/src/xref.hrl
index fa8c5c746d..a83271cbdb 100644
--- a/lib/tools/src/xref.hrl
+++ b/lib/tools/src/xref.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -22,6 +23,8 @@
-define(VAR_EXPR, '$F_EXPR').
-define(MOD_EXPR, '$M_EXPR').
+-define(XREF_END_LINE, (1 bsl 23)).
+
%%% Filenames are stored as directory and basename. A lot of heap can
%%% be saved by keeping only one (or few) copy of the directory name.
diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl
index 30c5f3d12d..88031f6e77 100644
--- a/lib/tools/src/xref_base.erl
+++ b/lib/tools/src/xref_base.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/src/xref_compiler.erl b/lib/tools/src/xref_compiler.erl
index c4b5c04c12..8c87e47c4c 100644
--- a/lib/tools/src/xref_compiler.erl
+++ b/lib/tools/src/xref_compiler.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -924,7 +925,7 @@ format_parse_error(["invalid_operator", Op], Line) ->
format_parse_error(Error, Line) ->
io_lib:format("Parse error~s: ~ts~n", [Line, lists:flatten(Error)]).
-format_line(-1) ->
+format_line(?XREF_END_LINE) ->
" at end of string";
format_line(0) ->
"";
diff --git a/lib/tools/src/xref_parser.yrl b/lib/tools/src/xref_parser.yrl
index 1279ece061..48602bb120 100644
--- a/lib/tools/src/xref_parser.yrl
+++ b/lib/tools/src/xref_parser.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl
index 142d28ebe6..41b93caaeb 100644
--- a/lib/tools/src/xref_reader.erl
+++ b/lib/tools/src/xref_reader.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -77,17 +78,18 @@ forms([], S) ->
form({attribute, Line, xref, Calls}, S) -> % experimental
#xrefr{module = M, function = Fun,
lattrs = L, xattrs = X, battrs = B} = S,
- attr(Calls, Line, M, Fun, L, X, B, S);
+ attr(Calls, erl_anno:line(Line), M, Fun, L, X, B, S);
form({attribute, _Line, _Attr, _Val}, S) ->
S;
-form({function, 0, module_info, 0, _Clauses}, S) ->
+form({function, _, module_info, 0, _Clauses}, S) ->
S;
-form({function, 0, module_info, 1, _Clauses}, S) ->
+form({function, _, module_info, 1, _Clauses}, S) ->
S;
-form({function, Line, Name, Arity, Clauses}, S) ->
+form({function, Anno, Name, Arity, Clauses}, S) ->
MFA0 = {S#xrefr.module, Name, Arity},
MFA = adjust_arity(S, MFA0),
S1 = S#xrefr{function = MFA},
+ Line = erl_anno:line(Anno),
S2 = S1#xrefr{def_at = [{MFA,Line} | S#xrefr.def_at]},
S3 = clauses(Clauses, S2),
S3#xrefr{function = []}.
@@ -305,10 +307,14 @@ fun_args(apply2, [FunArg, Args]) -> {FunArg, Args};
fun_args(1, [FunArg | Args]) -> {FunArg, Args};
fun_args(2, [_Node, FunArg | Args]) -> {FunArg, Args}.
-list2term([A | As]) ->
- {cons, 0, A, list2term(As)};
-list2term([]) ->
- {nil, 0}.
+list2term(L) ->
+ A = erl_anno:new(0),
+ list2term(L, A).
+
+list2term([A | As], Anno) ->
+ {cons, Anno, A, list2term(As)};
+list2term([], Anno) ->
+ {nil, Anno}.
term2list({cons, _Line, H, T}, L, S) ->
term2list(T, [H | L], S);
@@ -335,10 +341,11 @@ handle_call(Locality, Module, Name, Arity, Line, S) ->
handle_call(Locality, To, Line, S, false)
end.
-handle_call(Locality, To0, Line, S, IsUnres) ->
+handle_call(Locality, To0, Anno, S, IsUnres) ->
From = S#xrefr.function,
To = adjust_arity(S, To0),
Call = {From, To},
+ Line = erl_anno:line(Anno),
CallAt = {Call, Line},
S1 = if
IsUnres ->
diff --git a/lib/tools/src/xref_scanner.erl b/lib/tools/src/xref_scanner.erl
index 990f8aa87b..0b14159fbe 100644
--- a/lib/tools/src/xref_scanner.erl
+++ b/lib/tools/src/xref_scanner.erl
@@ -1,24 +1,27 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(xref_scanner).
+-include("xref.hrl").
+
-export([scan/1]).
scan(Chars) ->
@@ -77,7 +80,7 @@ lex([V={var,N,Var} | L]) ->
lex([T | Ts]) ->
[T | lex(Ts)];
lex([]) ->
- [{'$end', -1}].
+ [{'$end', erl_anno:new(?XREF_END_LINE)}].
is_type('Rel') -> true;
is_type('App') -> true;
diff --git a/lib/tools/src/xref_utils.erl b/lib/tools/src/xref_utils.erl
index 49c397a140..f69aa70244 100644
--- a/lib/tools/src/xref_utils.erl
+++ b/lib/tools/src/xref_utils.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -244,6 +245,8 @@ select_last_application_version(AppVs) ->
TL = to_external(partition(1, relation(AppVs))),
[last(keysort(2, L)) || L <- TL].
+-record(scan, {collected = [], errors = [], seen = [], unreadable = []}).
+
%% scan_directory(Directory, Recurse, Collect, Watch) ->
%% {Collected, Errors, Seen, Unreadable}
%%
@@ -260,8 +263,9 @@ select_last_application_version(AppVs) ->
%% Unreadable.
%%
scan_directory(File, Recurse, Collect, Watch) ->
- Init = [[] | {[],[],[]}],
- [L | {E,J,U}] = find_files_dir(File, Recurse, Collect, Watch, Init),
+ Init = #scan{},
+ S = find_files_dir(File, Recurse, Collect, Watch, Init),
+ #scan{collected = L, errors = E, seen = J, unreadable = U} = S,
{reverse(L), reverse(E), reverse(J), reverse(U)}.
%% {Dir, Basename} | false
@@ -575,8 +579,7 @@ find_files_dir(Dir, Recurse, Collect, Watch, L) ->
{ok, Files} ->
find_files(sort(Files), Dir, Recurse, Collect, Watch, L);
{error, Error} ->
- [B | {E,J,U}] = L,
- [B | {[file_error(Dir, Error)|E],J,U}]
+ L#scan{errors = [file_error(Dir, Error)|L#scan.errors]}
end.
find_files([F | Fs], Dir, Recurse, Collect, Watch, L) ->
@@ -587,22 +590,23 @@ find_files([F | Fs], Dir, Recurse, Collect, Watch, L) ->
{ok, {_, directory, _, _}} ->
L;
Info ->
- [B | EJU = {E,J,U}] = L,
+ #scan{collected = B, errors = E,
+ seen = J, unreadable = U} = L,
Ext = filename:extension(File),
C = member(Ext, Collect),
case C of
true ->
case Info of
{ok, {_, file, readable, _}} ->
- [[{Dir,F} | B] | EJU];
+ L#scan{collected = [{Dir,F} | B]};
{ok, {_, file, unreadable, _}} ->
- [B | {E,J,[File|U]}];
+ L#scan{unreadable = [File|U]};
Error ->
- [B | {[Error|E],J,U}]
+ L#scan{errors = [Error|E]}
end;
false ->
case member(Ext, Watch) of
- true -> [B | {E,[File|J],U}];
+ true -> L#scan{seen = [File|J]};
false -> L
end
end
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
index 484cfdf53f..49b86628b7 100644
--- a/lib/tools/test/Makefile
+++ b/lib/tools/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
index 80807b1d38..71570a55fa 100644
--- a/lib/tools/test/cover_SUITE.erl
+++ b/lib/tools/test/cover_SUITE.erl
@@ -1,56 +1,35 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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(cover_SUITE).
--export([all/0, init_per_testcase/2, end_per_testcase/2,
- suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2]).
-
--export([coverage/1, coverage_analysis/1,
- start/1, compile/1, analyse/1, misc/1, stop/1,
- distribution/1, reconnect/1, die_and_reconnect/1,
- dont_reconnect_after_stop/1, stop_node_after_disconnect/1,
- export_import/1,
- otp_5031/1, eif/1, otp_5305/1, otp_5418/1, otp_6115/1, otp_7095/1,
- otp_8188/1, otp_8270/1, otp_8273/1, otp_8340/1,
- otp_10979_hanging_node/1, compile_beam_opts/1, eep37/1]).
-
--export([do_coverage/1]).
+-compile(export_all).
-include_lib("test_server/include/test_server.hrl").
-%%----------------------------------------------------------------------
-%% The following directory structure is assumed:
-%% cwd __________________________________________
-%% | \ \ \ \ \ \ \
-%% a b cc d f d1 compile_beam_____ otp_6115
-%% | \ \ \ \ \ \ \
-%% e crypt v w x d f1 f2
-%% |
-%% y
-%%----------------------------------------------------------------------
-
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
NoStartStop = [eif,otp_5305,otp_5418,otp_7095,otp_8273,
- otp_8340,otp_8188,compile_beam_opts,eep37],
+ otp_8340,otp_8188,compile_beam_opts,eep37,
+ analyse_no_beam, line_0, compile_beam_no_file,
+ otp_13277],
StartStop = [start, compile, analyse, misc, stop,
distribution, reconnect, die_and_reconnect,
dont_reconnect_after_stop, stop_node_after_disconnect,
@@ -170,10 +149,15 @@ compile(Config) when is_list(Config) ->
?line {ok, CWD} = file:get_cwd(),
?line Result2 = cover:compile_directory(CWD),
?line SortedResult = lists:sort(Result2),
- ?line [{error,_DFile},{ok,a},{ok,b},{ok,cc},{ok,f}] = SortedResult,
+ ?line [{error,DFile},{ok,a},{ok,b},{ok,cc},{ok,f}] = SortedResult,
?line [{ok,e}] = cover:compile_directory("d1"),
?line {error,enoent} = cover:compile_directory("d2"),
+ [] = cover:compile([]),
+ Result21 = cover:compile([a,b,"cc.erl",d,"f"]),
+ SortedResult21 = lists:sort(Result21),
+ [{error,DFile},{ok,a},{ok,b},{ok,cc},{ok,f}] = SortedResult21,
+
?line {ok,a} = cover:compile(a),
?line {ok,b} = compile:file(b),
?line code:purge(b),
@@ -213,8 +197,14 @@ compile(Config) when is_list(Config) ->
?line {error,non_existing} = cover:compile_beam(z),
?line [{ok,y}] = cover:compile_beam_directory("d"),
?line Result3 = lists:sort(cover:compile_beam_directory()),
- ?line [{error,{no_abstract_code,_XBeam}},{ok,crypt},{ok,v},{ok,w}] = Result3,
+ ?line [{error,{no_abstract_code,XBeam}},{ok,crypt},{ok,v},{ok,w}] = Result3,
?line {error,enoent} = cover:compile_beam_directory("d2"),
+
+ [] = cover:compile_beam([]),
+ Result31 = cover:compile_beam([crypt,"v.beam",w,"x"]),
+ SortedResult31 = lists:sort(Result31),
+ [{error,{no_abstract_code,XBeam}},{ok,crypt},{ok,v},{ok,w}] = SortedResult31,
+
?line decompile([v,w,y]),
?line Files = lsfiles(),
?line remove(files(Files, ".beam")).
@@ -239,20 +229,22 @@ analyse(Config) when is_list(Config) ->
?line done = a:start(5),
- ?line {ok, {a,{17,2}}} = cover:analyse(a, coverage, module),
- ?line {ok, [{{a,start,1},{6,0}},
- {{a,stop,1},{0,1}},
- {{a,pong,1},{1,0}},
- {{a,loop,3},{5,1}},
- {{a,trycatch,1},{4,0}},
- {{a,exit_kalle,0},{1,0}}]} = cover:analyse(a, coverage, function),
- ?line {ok, [{{a,start,1,1},{6,0}},
- {{a,stop,1,1},{0,1}},
- {{a,pong,1,1},{1,0}},
+ {ok, {a,{17,2}}=ACovMod} = cover:analyse(a, coverage, module),
+ {ok, [{{a,exit_kalle,0},{1,0}},
+ {{a,loop,3},{5,1}},
+ {{a,pong,1},{1,0}},
+ {{a,start,1},{6,0}},
+ {{a,stop,1},{0,1}},
+ {{a,trycatch,1},{4,0}}]=ACovFunc} =
+ cover:analyse(a, coverage, function),
+ {ok, [{{a,exit_kalle,0,1},{1,0}},
{{a,loop,3,1},{3,1}},
{{a,loop,3,2},{2,0}},
- {{a,trycatch,1,1},{4,0}},
- {{a,exit_kalle,0,1},{1,0}}]} = cover:analyse(a, coverage, clause),
+ {{a,pong,1,1},{1,0}},
+ {{a,start,1,1},{6,0}},
+ {{a,stop,1,1},{0,1}},
+ {{a,trycatch,1,1},{4,0}}]=ACovClause} =
+ cover:analyse(a, coverage, clause),
?line {ok, [{{a,9},{1,0}},
{{a,10},{1,0}},
{{a,11},{1,0}},
@@ -271,22 +263,22 @@ analyse(Config) when is_list(Config) ->
{{a,47},{1,0}},
{{a,49},{1,0}},
{{a,51},{1,0}},
- {{a,55},{1,0}}]} = cover:analyse(a, coverage, line),
-
- ?line {ok, {a,15}} = cover:analyse(a, calls, module),
- ?line {ok, [{{a,start,1},1},
- {{a,stop,1},0},
- {{a,pong,1},5},
- {{a,loop,3},6},
- {{a,trycatch,1},2},
- {{a,exit_kalle,0},1}]} = cover:analyse(a, calls, function),
- ?line {ok, [{{a,start,1,1},1},
- {{a,stop,1,1},0},
- {{a,pong,1,1},5},
- {{a,loop,3,1},5},
- {{a,loop,3,2},1},
- {{a,trycatch,1,1},2},
- {{a,exit_kalle,0,1},1}]} = cover:analyse(a, calls, clause),
+ {{a,55},{1,0}}]=ACovLine} = cover:analyse(a, coverage, line),
+
+ {ok, {a,15}=ACallsMod} = cover:analyse(a, calls, module),
+ {ok, [{{a,exit_kalle,0},1},
+ {{a,loop,3},6},
+ {{a,pong,1},5},
+ {{a,start,1},1},
+ {{a,stop,1},0},
+ {{a,trycatch,1},2}]=ACallsFunc} = cover:analyse(a, calls, function),
+ {ok, [{{a,exit_kalle,0,1},1},
+ {{a,loop,3,1},5},
+ {{a,loop,3,2},1},
+ {{a,pong,1,1},5},
+ {{a,start,1,1},1},
+ {{a,stop,1,1},0},
+ {{a,trycatch,1,1},2}]=ACallsClause} = cover:analyse(a, calls, clause),
?line {ok, [{{a,9},1},
{{a,10},1},
{{a,11},1},
@@ -305,27 +297,85 @@ analyse(Config) when is_list(Config) ->
{{a,47},1},
{{a,49},1},
{{a,51},2},
- {{a,55},1}]} = cover:analyse(a, calls, line),
-
- ?line {ok, [{{a,start,1},{6,0}},
- {{a,stop,1},{0,1}},
- {{a,pong,1},{1,0}},
- {{a,loop,3},{5,1}},
- {{a,trycatch,1},{4,0}},
- {{a,exit_kalle,0},{1,0}}]} = cover:analyse(a),
- ?line {ok, {a,{17,2}}} = cover:analyse(a, module),
- ?line {ok, [{{a,start,1},1},
- {{a,stop,1},0},
- {{a,pong,1},5},
- {{a,loop,3},6},
- {{a,trycatch,1},2},
- {{a,exit_kalle,0},1}]} = cover:analyse(a, calls),
+ {{a,55},1}]=ACallsLine} = cover:analyse(a, calls, line),
+
+ {ok,ACovFunc} = cover:analyse(a),
+ {ok,ACovMod} = cover:analyse(a, module),
+ {ok,ACallsFunc} = cover:analyse(a, calls),
?line {ok, "a.COVER.out"} = cover:analyse_to_file(a),
?line {ok, "e.COVER.out"} = cover:analyse_to_file(e),
?line {ok, "a.COVER.html"} = cover:analyse_to_file(a,[html]),
?line {ok, "e.COVER.html"} = cover:analyse_to_file(e,[html]),
+ %% Analyse all modules
+ Modules = cover:modules(),
+ N = length(Modules),
+
+ {result,CovFunc,[]} = cover:analyse(), % default = coverage, function
+ ACovFunc = [A || {{a,_,_},_}=A<-CovFunc],
+
+ {result,CovMod,[]} = cover:analyse(coverage,module),
+ ACovMod = lists:keyfind(a,1,CovMod),
+
+ {result,CovClause,[]} = cover:analyse(coverage,clause),
+ ACovClause = [A || {{a,_,_,_},_}=A<-CovClause],
+
+ {result,CovLine,[]} = cover:analyse(coverage,line),
+ ACovLine = [A || {{a,_},_}=A<-CovLine],
+
+ {result,CallsFunc,[]} = cover:analyse(calls,function),
+ ACallsFunc = [A || {{a,_,_},_}=A<-CallsFunc],
+
+ {result,CallsMod,[]} = cover:analyse(calls,module),
+ ACallsMod = lists:keyfind(a,1,CallsMod),
+
+ {result,CallsClause,[]} = cover:analyse(calls,clause),
+ ACallsClause = [A || {{a,_,_,_},_}=A<-CallsClause],
+
+ {result,CallsLine,[]} = cover:analyse(calls,line),
+ ACallsLine = [A || {{a,_},_}=A<-CallsLine],
+
+ {result,AllToFile,[]} = cover:analyse_to_file(),
+ N = length(AllToFile),
+ true = lists:member("a.COVER.out",AllToFile),
+ {result,AllToFileHtml,[]} = cover:analyse_to_file([html]),
+ N = length(AllToFileHtml),
+ true = lists:member("a.COVER.html",AllToFileHtml),
+
+ %% Analyse list of modules
+ %% Listing all modules so we can compare result with above result
+ %% from analysing all.
+
+ {result,CovFunc1,[]} = cover:analyse(Modules), % default = coverage, function
+ true = lists:sort(CovFunc) == lists:sort(CovFunc1),
+
+ {result,CovMod1,[]} = cover:analyse(Modules,coverage,module),
+ true = lists:sort(CovMod) == lists:sort(CovMod1),
+
+ {result,CovClause1,[]} = cover:analyse(Modules,coverage,clause),
+ true = lists:sort(CovClause) == lists:sort(CovClause1),
+
+ {result,CovLine1,[]} = cover:analyse(Modules,coverage,line),
+ true = lists:sort(CovLine) == lists:sort(CovLine1),
+
+ {result,CallsFunc1,[]} = cover:analyse(Modules,calls,function),
+ true = lists:sort(CallsFunc1) == lists:sort(CallsFunc1),
+
+ {result,CallsMod1,[]} = cover:analyse(Modules,calls,module),
+ true = lists:sort(CallsMod) == lists:sort(CallsMod1),
+
+ {result,CallsClause1,[]} = cover:analyse(Modules,calls,clause),
+ true = lists:sort(CallsClause) == lists:sort(CallsClause1),
+
+ {result,CallsLine1,[]} = cover:analyse(Modules,calls,line),
+ true = lists:sort(CallsLine) == lists:sort(CallsLine1),
+
+ {result,AllToFile1,[]} = cover:analyse_to_file(Modules),
+ true = lists:sort(AllToFile) == lists:sort(AllToFile1),
+ {result,AllToFileHtml1,[]} = cover:analyse_to_file(Modules,[html]),
+ true = lists:sort(AllToFileHtml) == lists:sort(AllToFileHtml1),
+
%% analyse_to_file of file which is compiled from beam
?line {ok,f} = compile:file(f,[debug_info]),
?line code:purge(f),
@@ -348,14 +398,17 @@ analyse(Config) when is_list(Config) ->
{module,z} = code:load_file(z),
{ok,z} = cover:compile_beam(z),
ok = file:delete("z.erl"),
- {error,no_source_code_found} = cover:analyse_to_file(z),
+ {error,{no_source_code_found,z}} = cover:analyse_to_file(z),
+ {result,[],[{no_source_code_found,z}]} = cover:analyse_to_file([z]),
code:purge(z),
code:delete(z),
?line {error,{not_cover_compiled,b}} = cover:analyse(b),
?line {error,{not_cover_compiled,g}} = cover:analyse(g),
+ {result,[],[{not_cover_compiled,b}]} = cover:analyse([b]),
?line {error,{not_cover_compiled,b}} = cover:analyse_to_file(b),
- ?line {error,{not_cover_compiled,g}} = cover:analyse_to_file(g).
+ {error,{not_cover_compiled,g}} = cover:analyse_to_file(g),
+ {result,[],[{not_cover_compiled,g}]} = cover:analyse_to_file([g]).
misc(suite) -> [];
misc(Config) when is_list(Config) ->
@@ -680,6 +733,119 @@ stop_node_after_disconnect(Config) ->
?t:stop_node(N1),
ok.
+distribution_performance(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ Dir = filename:join(PrivDir,"distribution_performance"),
+ AllFiles = filename:join(Dir,"*"),
+ ok = filelib:ensure_dir(AllFiles),
+ code:add_patha(Dir),
+ M = 9, % Generate M modules
+ F = 210, % with F functions
+ C = 10, % and each function of C clauses
+ Mods = generate_modules(M,F,C,Dir),
+
+% ?t:break(""),
+
+ NodeName = cover_SUITE_distribution_performance,
+ {ok,N1} = ?t:start_node(NodeName,peer,[{start_cover,false}]),
+ %% CFun = fun() ->
+ %% [{ok,_} = cover:compile_beam(Mod) || Mod <- Mods]
+ %% end,
+ CFun = fun() -> cover:compile_beam(Mods) end,
+ {CT,_CA} = timer:tc(CFun),
+% erlang:display(_CA),
+ erlang:display({compile,CT}),
+
+ {SNT,_} = timer:tc(fun() -> {ok,[N1]} = cover:start(nodes()) end),
+ erlang:display({start_node,SNT}),
+
+ [1 = rpc:call(N1,Mod,f1,[1]) || Mod <- Mods],
+
+% Fun = fun() -> [cover:analyse(Mod,calls,function) || Mod<-Mods] end,
+% Fun = fun() -> analyse_all(Mods,calls,function) end,
+% Fun = fun() -> cover:analyse('_',calls,function) end,
+ Fun = fun() -> cover:analyse(Mods,calls,function) end,
+
+% Fun = fun() -> [begin cover:analyse_to_file(Mod,[html]) end || Mod<-Mods] end,
+% Fun = fun() -> analyse_all_to_file(Mods,[html]) end,
+% Fun = fun() -> cover:analyse_to_file(Mods,[html]) end,
+% Fun = fun() -> cover:analyse_to_file([html]) end,
+
+% Fun = fun() -> cover:reset() end,
+
+ {AT,_A} = timer:tc(Fun),
+ erlang:display({analyse,AT}),
+% erlang:display(lists:sort([X || X={_MFA,N} <- lists:append([L || {ok,L}<-A]), N=/=0])),
+
+ %% fprof:apply(Fun, [],[{procs,[whereis(cover_server)]}]),
+ %% fprof:profile(),
+ %% fprof:analyse(dest,[]),
+
+ {SNT2,_} = timer:tc(fun() -> ?t:stop_node(N1) end),
+ erlang:display({stop_node,SNT2}),
+
+ code:del_path(Dir),
+ Files = filelib:wildcard(AllFiles),
+ [ok = file:delete(File) || File <- Files],
+ ok = file:del_dir(Dir),
+ ok.
+
+%% Run analysis in parallel
+analyse_all(Mods,Analysis,Level) ->
+ Pids = [begin
+ Pid = spawn(fun() ->
+ {ok,A} = cover:analyse(Mod,Analysis,Level),
+ exit(A)
+ end),
+ erlang:monitor(process,Pid),
+ Pid
+ end || Mod <- Mods],
+ get_downs(Pids,[]).
+
+analyse_all_to_file(Mods,Opts) ->
+ Pids = [begin
+ Pid = cover:async_analyse_to_file(Mod,Opts),
+ erlang:monitor(process,Pid),
+ Pid
+ end || Mod <- Mods],
+ get_downs(Pids,[]).
+
+get_downs([],Acc) ->
+ Acc;
+get_downs(Pids,Acc) ->
+ receive
+ {'DOWN', _Ref, _Type, Pid, A} ->
+ get_downs(lists:delete(Pid,Pids),[A|Acc])
+ end.
+
+generate_modules(0,_,_,_) ->
+ [];
+generate_modules(M,F,C,Dir) ->
+ ModStr = "m" ++ integer_to_list(M),
+ Mod = list_to_atom(ModStr),
+ Src = ["-module(",ModStr,").\n"
+ "-compile(export_all).\n" |
+ generate_functions(F,C)],
+ Erl = filename:join(Dir,ModStr++".erl"),
+ ok = file:write_file(Erl,Src),
+ {ok,Mod} = compile:file(Erl,[{outdir,Dir},debug_info,report]),
+ [Mod | generate_modules(M-1,F,C,Dir)].
+
+generate_functions(0,_) ->
+ [];
+generate_functions(F,C) ->
+ Func = "f" ++ integer_to_list(F),
+ [generate_clauses(C,Func) | generate_functions(F-1,C)].
+
+generate_clauses(0,_) ->
+ [];
+generate_clauses(C,Func) ->
+ CStr = integer_to_list(C),
+ Sep = if C==1 -> "."; true -> ";" end,
+ [Func,"(",CStr,") -> ",CStr,Sep,"\n" |
+ generate_clauses(C-1,Func)].
+
+
export_import(suite) -> [];
export_import(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir, Config),
@@ -788,10 +954,11 @@ otp_5031(Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(10)),
- ?line {ok,N1} = ?t:start_node(cover_SUITE_distribution1,slave,[]),
+ {ok,N1} = ?t:start_node(cover_SUITE_otp_5031,slave,[]),
?line {ok,[N1]} = cover:start(N1),
?line {error,not_main_node} = rpc:call(N1,cover,modules,[]),
?line cover:stop(),
+ ?t:stop_node(N1),
?t:timetrap_cancel(Dog),
ok.
@@ -1005,6 +1172,7 @@ otp_7095(Config) when is_list(Config) ->
ok.
+
otp_8270(doc) ->
["OTP-8270. Bug."];
otp_8270(suite) -> [];
@@ -1020,7 +1188,7 @@ otp_8270(Config) when is_list(Config) ->
?line {ok,N3} = ?t:start_node(cover_n3,slave,As),
timer:sleep(500),
- cover:start(nodes()),
+ {ok,[_,_,_]} = cover:start(nodes()),
Test = <<
"-module(m).\n"
@@ -1058,6 +1226,7 @@ otp_8270(Config) when is_list(Config) ->
?line {N2,true} = {N2,is_list(N2_info)},
?line {N3,true} = {N3,is_list(N3_info)},
+ exit(Pid1,kill),
?line ?t:stop_node(N1),
?line ?t:stop_node(N2),
?line ?t:stop_node(N3),
@@ -1084,7 +1253,7 @@ otp_8340(doc) ->
["OTP-8340. Bug."];
otp_8340(suite) -> [];
otp_8340(Config) when is_list(Config) ->
- ?line [{{t,1},1},{{t,2},1},{{t,4},1}] =
+ ?line [{{t,1},1},{{t,4},1}] =
analyse_expr(<<"<< \n"
" <<3:2, \n"
" SeqId:62>> \n"
@@ -1378,8 +1547,10 @@ comprehension_8188(Cf) ->
" true]. \n" % 2
" two() -> 2">>, Cf), % 1
+ %% The template cannot have a counter since it is not allowed to
+ %% be a block.
?line [{{t,1},1},
- {{t,2},2},
+ %% {{t,2},2},
{{t,3},1},
{{t,4},1},
{{t,5},0},
@@ -1389,7 +1560,7 @@ comprehension_8188(Cf) ->
{{t,13},2},
{{t,14},2}] =
analyse_expr(<<"<< \n" % 1
- " << (X*2) >> || \n" % 2
+ " << (X*2) >> || \n" % 2 (now: 0)
" <<X>> <= << (case two() of\n"
" 2 -> 1;\n" % 1
" _ -> 2\n" % 0
@@ -1404,7 +1575,7 @@ comprehension_8188(Cf) ->
"two() -> 2">>, Cf),
?line [{{t,1},1},
- {{t,2},4},
+ %% {{t,2},4},
{{t,4},1},
{{t,6},1},
{{t,7},0},
@@ -1413,7 +1584,7 @@ comprehension_8188(Cf) ->
{{t,12},4},
{{t,13},1}] =
analyse_expr(<<"<< \n" % 1
- " << (2)\n" % 4
+ " << (2)\n" % 4 (now: 0)
" :(8) >> || \n"
" <<X>> <= << 1,\n" % 1
" (case two() of \n"
@@ -1495,6 +1666,106 @@ compile_beam_opts(Config) when is_list(Config) ->
ok = file:set_cwd(Cwd),
ok.
+analyse_no_beam(doc) ->
+ ["Don't crash if beam is not available"];
+analyse_no_beam(suite) -> [];
+analyse_no_beam(Config) when is_list(Config) ->
+ {ok, Cwd} = file:get_cwd(),
+ ok = file:set_cwd(?config(data_dir, Config)),
+
+ code:purge(t),
+ code:delete(t),
+
+ {ok,_} = file:copy("compile_beam/t.erl", "t.erl"),
+ {ok,t} = compile:file(t, [debug_info]),
+ {module,t} = code:load_file(t),
+ {ok,t} = cover:compile_beam(t),
+ t:f(),
+ ok = cover:export("t.coverdata"),
+
+ code:purge(t),
+ code:delete(t),
+
+ %% this is just so that cover realises (without stopping)
+ %% that this module is not cover compiled any more
+ {error, {not_cover_compiled,t}} = cover:analyse(t),
+
+ %% source and beam not available any more
+ ok = file:delete("t.erl"),
+ ok = file:delete("t.beam"),
+
+ ok = cover:import("t.coverdata"),
+
+ {error,{no_source_code_found,t}} = cover:analyse_to_file(t),
+ {result,[],[{no_source_code_found,t}]} = cover:analyse_to_file([t]),
+
+ ok = file:delete("t.coverdata"),
+ ok = file:set_cwd(Cwd),
+ ok.
+
+%% When including eunit.hrl, a parse transform adds the function
+%% test/0 to line 0 in your module. A bug in OTP-18.0 caused
+%% cover:analyse_to_file/1 to fail to insert cover data in the output
+%% file in this situation. The test below tests that this bug is
+%% corrected.
+line_0(Config) ->
+ ok = file:set_cwd(filename:join(?config(data_dir, Config),
+ "include_eunit_hrl")),
+ {ok, cover_inc_eunit} = compile:file(cover_inc_eunit,[debug_info]),
+ {ok, cover_inc_eunit} = cover:compile_beam(cover_inc_eunit),
+ {ok, CovOut} = cover:analyse_to_file(cover_inc_eunit),
+
+ {ok,Bin} = file:read_file(CovOut),
+ Match = <<"0..| ok.\n">>, % "0.." is missing when bug is there
+ S = byte_size(Bin)-byte_size(Match),
+ <<_:S/binary,Match/binary>> = Bin,
+ ok.
+
+
+%% OTP-13200: Return error instead of crashing when trying to compile
+%% a beam which has no 'file' attribute.
+compile_beam_no_file(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ Dir = filename:join(PrivDir,"compile_beam_no_file"),
+ ok = filelib:ensure_dir(filename:join(Dir,"*")),
+ code:add_patha(Dir),
+ Str = lists:concat(
+ ["-module(nofile).\n"
+ "-compile(export_all).\n"
+ "foo() -> ok.\n"]),
+ TT = do_scan(Str),
+ Forms = [ begin {ok,Y} = erl_parse:parse_form(X),Y end || X <- TT ],
+ {ok,_,Bin} = compile:forms(Forms,[debug_info]),
+ BeamFile = filename:join(Dir,"nofile.beam"),
+ ok = file:write_file(BeamFile,Bin),
+ {error,{no_file_attribute,BeamFile}} = cover:compile_beam(nofile),
+ [{error,{no_file_attribute,BeamFile}}] = cover:compile_beam_directory(Dir),
+ ok.
+
+do_scan([]) ->
+ [];
+do_scan(Str) ->
+ {done,{ok,T,_},C} = erl_scan:tokens([],Str,0),
+ [ T | do_scan(C) ].
+
+otp_13277(doc) ->
+ ["PR 856. Fix a bc bug."];
+otp_13277(Config) ->
+ Test = <<"-module(t).
+ -export([t/0]).
+
+ pad(A, L) ->
+ P = << <<\"#\">> || _ <- lists:seq(1, L) >>,
+ <<A/binary, P/binary>>.
+
+ t() ->
+ pad(<<\"hi\">>, 2).
+ ">>,
+ ?line File = cc_mod(t, Test, Config),
+ ?line <<"hi##">> = t:t(),
+ ?line ok = file:delete(File),
+ ok.
+
%%--Auxiliary------------------------------------------------------------
analyse_expr(Expr, Config) ->
@@ -1572,7 +1843,9 @@ is_unloaded(What) ->
end.
check_f_calls(F1,F2) ->
- {ok,[{{f,f1,0},F1},{{f,f2,0},F2}|_]} = cover:analyse(f,calls,function).
+ {ok,A} = cover:analyse(f,calls,function),
+ {_,F1} = lists:keyfind({f,f1,0},1,A),
+ {_,F2} = lists:keyfind({f,f2,0},1,A).
cover_which_nodes(Expected) ->
case cover:which_nodes() of
diff --git a/lib/tools/test/cover_SUITE_data/cc.erl b/lib/tools/test/cover_SUITE_data/cc.erl
index 587bdbe493..7eb165ef8a 100644
--- a/lib/tools/test/cover_SUITE_data/cc.erl
+++ b/lib/tools/test/cover_SUITE_data/cc.erl
@@ -1,88 +1,17 @@
-module(cc).
--export([epp/1, epp/2, dbg/1, dbg/2, cvr/1, cvr/2]).
--export([p/2, pp/2]).
+-compile(export_all).
-%% epp(Module) - Creates Module.epp which contains all forms of Module
-%% as obtained by using epp.
-%%
-%% dbg(Module) - Creates Module.dbg which contains all forms of Module
-%% as obtained by using beam_lib:chunks/2.
-%%
-%% cvr(Module) - Creates Module.cvr which contains all forms of Module
-%% as obtained by using cover:transform/3.
-%%
+%% This is a dummy module used only for cover compiling. The content
+%% of this module has no meaning for the test.
-epp(Module) ->
- epp(Module, p).
-epp(Module, P) ->
- File = atom_to_list(Module)++".erl",
- {ok,Cwd} = file:get_cwd(),
- {ok, Fd1} = epp:open(File, [Cwd], []),
- {ok, Fd2} = file:open(atom_to_list(Module)++".epp", write),
+foo() ->
+ T = erlang:time(),
+ spawn(fun() -> bar(T) end).
- epp(Fd1, Fd2, P),
-
- epp:close(Fd1),
- file:close(Fd2),
- ok.
-
-epp(Fd1, Fd2, P) ->
- case epp:parse_erl_form(Fd1) of
- {ok, {attribute,Line,Attr,Data}} ->
- epp(Fd1, Fd2, P);
- {ok, Form} when P==p ->
- io:format(Fd2, "~p.~n", [Form]),
- epp(Fd1, Fd2, P);
- {ok, Form} when P==pp ->
- io:format(Fd2, "~p.~n", [erl_pp:form(Form)]),
- epp(Fd1, Fd2, P);
- {eof, Line} ->
- ok
- end.
-
-cvr(Module) ->
- cvr(Module, p).
-cvr(Module, P) ->
- case beam_lib:chunks(Module, [abstract_code]) of
- {ok, {Module, [{abstract_code, no_abstract_code}]}} ->
- {error, {no_debug_info,Module}};
- {ok, {Module, [{abstract_code, {Vsn, Forms}}]}} ->
- Vars = {vars,Module,Vsn, [],
- undefined, undefined, undefined, undefined, undefined,
- undefined,
- false},
- {ok, TForms, _Vars2} = cover:transform(Forms, [], Vars),
- File = atom_to_list(Module)++".cvr",
- apply(?MODULE, P, [File, TForms]);
- Error ->
- Error
+bar(T) ->
+ receive
+ X ->
+ T1 = erlang:time(),
+ io:format("received ~p at ~p. Last time: ~p~n",[X,T1,T]),
+ bar(T1)
end.
-
-dbg(Module) ->
- dbg(Module, p).
-dbg(Module, P) ->
- case beam_lib:chunks(Module, [abstract_code]) of
- {ok, {Module, [{abstract_code, no_abstract_code}]}} ->
- {error, {no_debug_info,Module}};
- {ok, {Module, [{abstract_code, {Vsn, Forms}}]}} ->
- File = atom_to_list(Module)++".dbg",
- apply(?MODULE, P, [File, Forms]);
- Error ->
- Error
- end.
-
-p(File, Forms) ->
- {ok, Fd} = file:open(File, write),
- lists:foreach(fun(Form) ->
- io:format(Fd, "~p.~n", [Form])
- end,
- Forms),
- file:close(Fd).
-
-pp(File, Forms) ->
- {ok, Fd} = file:open(File, write),
- lists:foreach(fun(Form) ->
- io:format(Fd, "~s", [erl_pp:form(Form)])
- end,
- Forms),
- file:close(Fd).
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/t.erl b/lib/tools/test/cover_SUITE_data/compile_beam/t.erl
new file mode 100644
index 0000000000..96dc2f4209
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/t.erl
@@ -0,0 +1,6 @@
+-module(t).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/include_eunit_hrl/cover_inc_eunit.erl b/lib/tools/test/cover_SUITE_data/include_eunit_hrl/cover_inc_eunit.erl
new file mode 100644
index 0000000000..c1fe7939d2
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/include_eunit_hrl/cover_inc_eunit.erl
@@ -0,0 +1,6 @@
+-module(cover_inc_eunit).
+-compile(export_all).
+-include_lib("eunit/include/eunit.hrl").
+
+func() ->
+ ok.
diff --git a/lib/tools/test/cprof_SUITE.erl b/lib/tools/test/cprof_SUITE.erl
index fa4068dade..7b22dea7ed 100644
--- a/lib/tools/test/cprof_SUITE.erl
+++ b/lib/tools/test/cprof_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2002-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/emacs_SUITE.erl b/lib/tools/test/emacs_SUITE.erl
index 657a3002a3..0c2d077e5d 100644
--- a/lib/tools/test/emacs_SUITE.erl
+++ b/lib/tools/test/emacs_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/emem_SUITE.erl b/lib/tools/test/emem_SUITE.erl
index 11fb8bec68..95cda98558 100644
--- a/lib/tools/test/emem_SUITE.erl
+++ b/lib/tools/test/emem_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl
index 04b522de4a..5428643667 100644
--- a/lib/tools/test/eprof_SUITE.erl
+++ b/lib/tools/test/eprof_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl b/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
index a88b6e21f2..4e0c4d3118 100644
--- a/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
+++ b/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
index 1bc4c11b5d..e8f179c630 100644
--- a/lib/tools/test/fprof_SUITE.erl
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/fprof_SUITE_data/foo.erl b/lib/tools/test/fprof_SUITE_data/foo.erl
index eaa8132b1e..6944425980 100644
--- a/lib/tools/test/fprof_SUITE_data/foo.erl
+++ b/lib/tools/test/fprof_SUITE_data/foo.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/test/ignore_cores.erl b/lib/tools/test/ignore_cores.erl
index 8b1ac0fe6c..13f34cd10f 100644
--- a/lib/tools/test/ignore_cores.erl
+++ b/lib/tools/test/ignore_cores.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/instrument_SUITE.erl b/lib/tools/test/instrument_SUITE.erl
index bc886d47c3..3b981a9303 100644
--- a/lib/tools/test/instrument_SUITE.erl
+++ b/lib/tools/test/instrument_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl
index 010dffe138..f3789a4137 100644
--- a/lib/tools/test/lcnt_SUITE.erl
+++ b/lib/tools/test/lcnt_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -97,12 +98,12 @@ t_conflicts_file([File|Files]) ->
{ok, _} = lcnt:start(),
ok = lcnt:load(File),
ok = lcnt:conflicts(),
- THs = [-1, 0, 100, 1000],
+ THs = [-1, 5],
Print = [name , id , type , entry , tries , colls , ratio , time , duration],
Opts = [
[{sort, Sort}, {reverse, Rev}, {max_locks, ML}, {combine, Combine}, {thresholds, [TH]}, {print, [Print]}] ||
- Sort <- [name , id , type , tries , colls , ratio , time , entry],
- ML <- [none, 1 , 32, 4096],
+ Sort <- [name , type , tries , colls , ratio , time],
+ ML <- [none, 32],
Combine <- [true, false],
TH <- [{tries, Tries} || Tries <- THs] ++ [{colls, Colls} || Colls <- THs] ++ [{time, Time} || Time <- THs],
Rev <- [true, false]
@@ -131,12 +132,12 @@ t_locations_file([File|Files]) ->
{ok, _} = lcnt:start(),
ok = lcnt:load(File),
ok = lcnt:locations(),
- THs = [-1, 0, 100, 1000],
+ THs = [-1, 0, 100],
Print = [name , id , type , entry , tries , colls , ratio , time , duration],
Opts = [
[{full_id, Id}, {sort, Sort}, {max_locks, ML}, {combine, Combine}, {thresholds, [TH]}, {print, Print}] ||
Sort <- [name , id , type , tries , colls , ratio , time , entry],
- ML <- [none, 1 , 64],
+ ML <- [none, 64],
Combine <- [true, false],
TH <- [{tries, Tries} || Tries <- THs] ++ [{colls, Colls} || Colls <- THs] ++ [{time, Time} || Time <- THs],
Id <- [true, false]
diff --git a/lib/tools/test/make_SUITE.erl b/lib/tools/test/make_SUITE.erl
index b1a65226de..70bc8502bf 100644
--- a/lib/tools/test/make_SUITE.erl
+++ b/lib/tools/test/make_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/make_SUITE_data/Emakefile b/lib/tools/test/make_SUITE_data/Emakefile
index ae9abb3cbe..9b35a1af93 100644
--- a/lib/tools/test/make_SUITE_data/Emakefile
+++ b/lib/tools/test/make_SUITE_data/Emakefile
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/tools/test/tools_SUITE.erl b/lib/tools/test/tools_SUITE.erl
index e3582b995b..9403124c96 100644
--- a/lib/tools/test/tools_SUITE.erl
+++ b/lib/tools/test/tools_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index 6870aefe5c..ad47b31443 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2000-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 3b3202d38b..70564f05c6 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.7.2
+TOOLS_VSN = 2.8.3
diff --git a/lib/typer/Makefile b/lib/typer/Makefile
index d4396abc9d..dee9805005 100644
--- a/lib/typer/Makefile
+++ b/lib/typer/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/typer/doc/Makefile b/lib/typer/doc/Makefile
index 4ea0137202..822f8f5d03 100644
--- a/lib/typer/doc/Makefile
+++ b/lib/typer/doc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/typer/doc/src/Makefile b/lib/typer/doc/src/Makefile
index 2683c08679..161fbd0752 100644
--- a/lib/typer/doc/src/Makefile
+++ b/lib/typer/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/typer/doc/src/book.xml b/lib/typer/doc/src/book.xml
index 5cc85a3022..fd2bccc0a9 100644
--- a/lib/typer/doc/src/book.xml
+++ b/lib/typer/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/typer/doc/src/notes.xml b/lib/typer/doc/src/notes.xml
index 23e22759d6..21a2a6d597 100644
--- a/lib/typer/doc/src/notes.xml
+++ b/lib/typer/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -30,6 +31,35 @@
</header>
<p>This document describes the changes made to TypEr.</p>
+<section><title>TypEr 0.9.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fix a bug that could result in a crash when printing
+ warnings onto standard error. </p>
+ <p>
+ Own Id: OTP-13010</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>TypEr 0.9.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Properly extract annotations from core code. </p>
+ <p>
+ Own Id: OTP-12727</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>TypEr 0.9.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/typer/doc/src/part_notes.xml b/lib/typer/doc/src/part_notes.xml
index b4ccd3ed77..63086f82c5 100644
--- a/lib/typer/doc/src/part_notes.xml
+++ b/lib/typer/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/typer/doc/src/ref_man.xml b/lib/typer/doc/src/ref_man.xml
index b54a5f5947..f50d79b385 100644
--- a/lib/typer/doc/src/ref_man.xml
+++ b/lib/typer/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/typer/doc/src/typer_app.xml b/lib/typer/doc/src/typer_app.xml
index 469a9be108..2618f4a380 100644
--- a/lib/typer/doc/src/typer_app.xml
+++ b/lib/typer/doc/src/typer_app.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/typer/src/Makefile b/lib/typer/src/Makefile
index a7059de971..620ca21827 100644
--- a/lib/typer/src/Makefile
+++ b/lib/typer/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2006-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/typer/src/typer.appup.src b/lib/typer/src/typer.appup.src
index bebe7a159c..46132dba48 100644
--- a/lib/typer/src/typer.appup.src
+++ b/lib/typer/src/typer.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/typer/src/typer.erl b/lib/typer/src/typer.erl
index 572bf24ca4..562530c868 100644
--- a/lib/typer/src/typer.erl
+++ b/lib/typer/src/typer.erl
@@ -2,18 +2,19 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -405,7 +406,7 @@ get_type({{M, F, A} = MFA, Range, Arg}, CodeServer, Records) ->
case dialyzer_codeserver:lookup_mfa_contract(MFA, CodeServer) of
error ->
{{F, A}, {Range, Arg}};
- {ok, {_FileLine, Contract}} ->
+ {ok, {_FileLine, Contract, _Xtra}} ->
Sig = erl_types:t_fun(Arg, Range),
case dialyzer_contracts:check_contract(Contract, Sig) of
ok -> {{F, A}, {contract, Contract}};
@@ -931,7 +932,9 @@ analyze_one_function({Var, FunBody} = Function, Acc) ->
A = cerl:fname_arity(Var),
TmpDialyzerObj = {{Acc#tmpAcc.module, F, A}, Function},
NewDialyzerObj = Acc#tmpAcc.dialyzerObj ++ [TmpDialyzerObj],
- [_, LineNo, {file, FileName}] = cerl:get_ann(FunBody),
+ Anno = cerl:get_ann(FunBody),
+ LineNo = get_line(Anno),
+ FileName = get_file(Anno),
BaseName = filename:basename(FileName),
FuncInfo = {LineNo, F, A},
OriginalName = Acc#tmpAcc.file,
@@ -951,6 +954,14 @@ analyze_one_function({Var, FunBody} = Function, Acc) ->
incFuncAcc = IncFuncAcc,
dialyzerObj = NewDialyzerObj}.
+get_line([Line|_]) when is_integer(Line) -> Line;
+get_line([_|T]) -> get_line(T);
+get_line([]) -> none.
+
+get_file([{file,File}|_]) -> File;
+get_file([_|T]) -> get_file(T);
+get_file([]) -> "no_file". % should not happen
+
-spec get_dialyzer_plt(analysis()) -> plt().
get_dialyzer_plt(#analysis{plt = PltFile0}) ->
@@ -1001,15 +1012,7 @@ compile_error(Reason) ->
-spec msg(string()) -> 'ok'.
msg(Msg) ->
- case os:type() of
- {unix, _} -> % Output a message on 'stderr', if possible
- P = open_port({fd, 0, 2}, [out]),
- port_command(P, Msg),
- true = port_close(P),
- ok;
- _ -> % win32
- io:format("~s", [Msg])
- end.
+ io:format(standard_error, "~s", [Msg]).
%%--------------------------------------------------------------------
%% Version and help messages.
diff --git a/lib/typer/test/typer_SUITE.erl b/lib/typer/test/typer_SUITE.erl
index 99c4facbad..25f0229640 100644
--- a/lib/typer/test/typer_SUITE.erl
+++ b/lib/typer/test/typer_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/typer/vsn.mk b/lib/typer/vsn.mk
index ce658e257b..507593ef56 100644
--- a/lib/typer/vsn.mk
+++ b/lib/typer/vsn.mk
@@ -1 +1 @@
-TYPER_VSN = 0.9.8
+TYPER_VSN = 0.9.10
diff --git a/lib/webtool/Makefile b/lib/webtool/Makefile
index 27c1986213..9afcb87af2 100644
--- a/lib/webtool/Makefile
+++ b/lib/webtool/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/webtool/doc/src/Makefile b/lib/webtool/doc/src/Makefile
index 32269e9424..57de52a616 100644
--- a/lib/webtool/doc/src/Makefile
+++ b/lib/webtool/doc/src/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -25,6 +26,10 @@ include ../../vsn.mk
VSN=$(WEBTOOL_VSN)
APPLICATION=webtool
+DOC_EXTRA_FRONT_PAGE_INFO=Important note: \
+The Webtool application is obsolete and will be removed \
+in the next major OTP release
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
diff --git a/lib/webtool/doc/src/book.xml b/lib/webtool/doc/src/book.xml
index 913d635b76..feccee7c62 100644
--- a/lib/webtool/doc/src/book.xml
+++ b/lib/webtool/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/webtool/doc/src/notes.xml b/lib/webtool/doc/src/notes.xml
index e571668c91..0ebb66ae3c 100644
--- a/lib/webtool/doc/src/notes.xml
+++ b/lib/webtool/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,39 @@
<p>This document describes the changes made to the Webtool
application.</p>
+<section><title>WebTool 0.9.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Remove dependency to inets <c>mod_include</c> in
+ configuration.</p>
+ <p>
+ Own Id: OTP-13406</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>WebTool 0.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The Webtool application has been marked as obsolete and
+ will be removed from OTP in the next major release (OTP
+ 19.0).</p>
+ <p>
+ Own Id: OTP-10922 Aux Id: OTP-12705 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>WebTool 0.8.10</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/webtool/doc/src/notes_history.xml b/lib/webtool/doc/src/notes_history.xml
index d491063565..792475d948 100644
--- a/lib/webtool/doc/src/notes_history.xml
+++ b/lib/webtool/doc/src/notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/webtool/doc/src/part.xml b/lib/webtool/doc/src/part.xml
index 32275a02d2..b0c4ee310d 100644
--- a/lib/webtool/doc/src/part.xml
+++ b/lib/webtool/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/webtool/doc/src/part_notes.xml b/lib/webtool/doc/src/part_notes.xml
index 75446ee687..db2b790f3f 100644
--- a/lib/webtool/doc/src/part_notes.xml
+++ b/lib/webtool/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/webtool/doc/src/part_notes_history.xml b/lib/webtool/doc/src/part_notes_history.xml
index 6a4a93d399..50ce62e58d 100644
--- a/lib/webtool/doc/src/part_notes_history.xml
+++ b/lib/webtool/doc/src/part_notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/webtool/doc/src/ref_man.xml b/lib/webtool/doc/src/ref_man.xml
index 3fbf289d66..aa81392b11 100644
--- a/lib/webtool/doc/src/ref_man.xml
+++ b/lib/webtool/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/webtool/doc/src/start_webtool.xml b/lib/webtool/doc/src/start_webtool.xml
index d02ddb996c..e9c94c4271 100644
--- a/lib/webtool/doc/src/start_webtool.xml
+++ b/lib/webtool/doc/src/start_webtool.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/webtool/doc/src/webtool.xml b/lib/webtool/doc/src/webtool.xml
index 375607e001..2647518dae 100644
--- a/lib/webtool/doc/src/webtool.xml
+++ b/lib/webtool/doc/src/webtool.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/webtool/doc/src/webtool_chapter.xml b/lib/webtool/doc/src/webtool_chapter.xml
index a233cd6662..160a42f855 100644
--- a/lib/webtool/doc/src/webtool_chapter.xml
+++ b/lib/webtool/doc/src/webtool_chapter.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/webtool/priv/Makefile b/lib/webtool/priv/Makefile
index 6af997c2bb..4963767a4d 100644
--- a/lib/webtool/priv/Makefile
+++ b/lib/webtool/priv/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/webtool/src/Makefile b/lib/webtool/src/Makefile
index af565c8895..a5a8eaf5dc 100644
--- a/lib/webtool/src/Makefile
+++ b/lib/webtool/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/webtool/src/webtool.app.src b/lib/webtool/src/webtool.app.src
index 3d8d11ea60..6b9750c2b4 100644
--- a/lib/webtool/src/webtool.app.src
+++ b/lib/webtool/src/webtool.app.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/webtool/src/webtool.appup.src b/lib/webtool/src/webtool.appup.src
index 9e6f4b9b5b..1394d0d6d5 100644
--- a/lib/webtool/src/webtool.appup.src
+++ b/lib/webtool/src/webtool.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
{"%VSN%",
diff --git a/lib/webtool/src/webtool.erl b/lib/webtool/src/webtool.erl
index 1be903b827..a0f2b5aab0 100644
--- a/lib/webtool/src/webtool.erl
+++ b/lib/webtool/src/webtool.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -582,7 +583,6 @@ rest_of_standard_data() ->
mod_esi,
mod_actions,
mod_cgi,
- mod_include,
mod_dir,
mod_get,
mod_head,
diff --git a/lib/webtool/src/webtool_sup.erl b/lib/webtool/src/webtool_sup.erl
index e299272c20..e4a05c53ae 100644
--- a/lib/webtool/src/webtool_sup.erl
+++ b/lib/webtool/src/webtool_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/webtool/test/webtool_SUITE.erl b/lib/webtool/test/webtool_SUITE.erl
index 64ff221a1b..9e2d9a2e0f 100644
--- a/lib/webtool/test/webtool_SUITE.erl
+++ b/lib/webtool/test/webtool_SUITE.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
+%% ``Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/webtool/vsn.mk b/lib/webtool/vsn.mk
index a79c273d9f..92201282c0 100644
--- a/lib/webtool/vsn.mk
+++ b/lib/webtool/vsn.mk
@@ -1 +1 @@
-WEBTOOL_VSN=0.8.10
+WEBTOOL_VSN=0.9.1
diff --git a/lib/wx/LICENSE.txt b/lib/wx/LICENSE.txt
new file mode 100644
index 0000000000..e454a52586
--- /dev/null
+++ b/lib/wx/LICENSE.txt
@@ -0,0 +1,178 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/lib/wx/Makefile b/lib/wx/Makefile
index 1ec225930e..b3b7aaa8aa 100644
--- a/lib/wx/Makefile
+++ b/lib/wx/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/api_gen/Makefile b/lib/wx/api_gen/Makefile
index 3e41ac7bc5..3fa8f1feee 100644
--- a/lib/wx/api_gen/Makefile
+++ b/lib/wx/api_gen/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -48,7 +49,7 @@ opt: $(WX) $(GL)
$(WX): wxxml_generated $(COMPILER_T) wxapi.conf $(wildcard wx_extra/wx*.c_src) $(wildcard wx_extra/wx*.erl)
erl -noshell -run wx_gen code && touch wx_code_generated
-wxxml_generated: wx_doxygen.conf wx_extra/bugs.h wx_extra/wxe_evth.h
+wxxml_generated: wx_doxygen.conf wx_extra/bugs.h wx_extra/wxe_evth.h wx_extra/added_func.h
sed -e 's|@WXGTK_DIR@|$(WXGTK_DIR)|g' wx_doxygen.conf > wx_doxygen
doxygen wx_doxygen && touch wxxml_generated
diff --git a/lib/wx/api_gen/gen_util.erl b/lib/wx/api_gen/gen_util.erl
index 9b08815bf7..ff245a6359 100644
--- a/lib/wx/api_gen/gen_util.erl
+++ b/lib/wx/api_gen/gen_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -229,16 +230,17 @@ erl_copyright() ->
w("%% Copyright Ericsson AB ~p-~p. All Rights Reserved.~n",
[StartYear, CurrentYear]),
w("%%~n",[]),
- w("%% The contents of this file are subject to the Erlang Public License,~n",[]),
- w("%% Version 1.1, (the \"License\"); you may not use this file except in~n",[]),
- w("%% compliance with the License. You should have received a copy of the~n",[]),
- w("%% Erlang Public License along with this software. If not, it can be~n",[]),
- w("%% retrieved online at http://www.erlang.org/.~n",[]),
+ w("%% Licensed under the Apache License, Version 2.0 (the \"License\");~n",[]),
+ w("%% you may not use this file except in compliance with the License.~n",[]),
+ w("%% You may obtain a copy of the License at~n",[]),
+ w("%%~n",[]),
+ w("%% http://www.apache.org/licenses/LICENSE-2.0~n",[]),
w("%%~n",[]),
- w("%% Software distributed under the License is distributed on an \"AS IS\"~n",[]),
- w("%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n",[]),
- w("%% the License for the specific language governing rights and limitations~n",[]),
- w("%% under the License.~n",[]),
+ w("%% Unless required by applicable law or agreed to in writing, software~n",[]),
+ w("%% distributed under the License is distributed on an \"AS IS\" BASIS,~n",[]),
+ w("%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~n",[]),
+ w("%% See the License for the specific language governing permissions and~n",[]),
+ w("%% limitations under the License.~n",[]),
w("%%~n",[]),
w("%% %CopyrightEnd%~n",[]).
@@ -249,16 +251,17 @@ c_copyright() ->
w(" *~n",[]),
w(" * Copyright Ericsson AB 2008-~p. All Rights Reserved.~n",[CurrentYear]),
w(" *~n",[]),
- w(" * The contents of this file are subject to the Erlang Public License,~n",[]),
- w(" * Version 1.1, (the \"License\"); you may not use this file except in~n",[]),
- w(" * compliance with the License. You should have received a copy of the~n",[]),
- w(" * Erlang Public License along with this software. If not, it can be~n",[]),
- w(" * retrieved online at http://www.erlang.org/.~n",[]),
+ w(" * Licensed under the Apache License, Version 2.0 (the \"License\");~n",[]),
+ w(" * you may not use this file except in compliance with the License.~n",[]),
+ w(" * You may obtain a copy of the License at~n",[]),
+ w(" *~n",[]),
+ w(" * http://www.apache.org/licenses/LICENSE-2.0~n",[]),
w(" *~n",[]),
- w(" * Software distributed under the License is distributed on an \"AS IS\"~n",[]),
- w(" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n",[]),
- w(" * the License for the specific language governing rights and limitations~n",[]),
- w(" * under the License.~n",[]),
+ w(" * Unless required by applicable law or agreed to in writing, software~n",[]),
+ w(" * distributed under the License is distributed on an \"AS IS\" BASIS,~n",[]),
+ w(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~n",[]),
+ w(" * See the License for the specific language governing permissions and~n",[]),
+ w(" * limitations under the License.~n",[]),
w(" *~n",[]),
w(" * %CopyrightEnd% ~n",[]),
w("*/~n",[]).
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
index ea967c958f..ab8f842d31 100644
--- a/lib/wx/api_gen/gl_gen.erl
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -190,7 +191,7 @@ parse_define([#xmlElement{name=initializer,content=Contents}|_R],Def,_Os) ->
try
case Val0 of
"0x" ++ Val1 ->
- _ = http_util:hexlist_to_integer(Val1),
+ _ = list_to_integer(Val1, 16),
Def#def{val=Val1, type=hex};
_ ->
Val = list_to_integer(Val0),
diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl
index 8b2a91b671..f06772dbb2 100644
--- a/lib/wx/api_gen/gl_gen_c.erl
+++ b/lib/wx/api_gen/gl_gen_c.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
index 7c24128d85..84e9600bc0 100644
--- a/lib/wx/api_gen/gl_gen_erl.erl
+++ b/lib/wx/api_gen/gl_gen_erl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -225,10 +226,14 @@ gen_types(Where) ->
w("-type clamp() :: float(). %% 0.0..1.0~n", []),
w("-type offset() :: non_neg_integer(). %% Offset in memory block~n", [])
end,
- w("-type matrix() :: {float(),float(),float(),float(),~n", []),
+ w("-type matrix12() :: {float(),float(),float(),float(),~n", []),
+ w(" float(),float(),float(),float(),~n", []),
+ w(" float(),float(),float(),float()}.~n", []),
+ w("-type matrix16() :: {float(),float(),float(),float(),~n", []),
w(" float(),float(),float(),float(),~n", []),
w(" float(),float(),float(),float(),~n", []),
w(" float(),float(),float(),float()}.~n", []),
+ w("-type matrix() :: matrix12() | matrix16().~n", []),
w("-type mem() :: binary() | tuple(). %% Memory block~n", []),
ok.
@@ -479,10 +484,12 @@ doc_arg_type2(T=#type{single=true}) ->
doc_arg_type3(T);
doc_arg_type2(T=#type{single=undefined}) ->
doc_arg_type3(T);
-doc_arg_type2(T=#type{single={tuple,undefined}}) ->
- "{" ++ doc_arg_type3(T) ++ "}";
+doc_arg_type2(_T=#type{single={tuple,undefined}}) ->
+ "tuple()";
doc_arg_type2(#type{base=float, single={tuple,16}}) ->
"matrix()";
+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(T=#type{single=list}) ->
diff --git a/lib/wx/api_gen/gl_scan_doc.erl b/lib/wx/api_gen/gl_scan_doc.erl
index 80b4826a30..d8bad02abf 100644
--- a/lib/wx/api_gen/gl_scan_doc.erl
+++ b/lib/wx/api_gen/gl_scan_doc.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2012-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%----------------------------------------------------------------------
diff --git a/lib/wx/api_gen/wx_extra/added_func.h b/lib/wx/api_gen/wx_extra/added_func.h
new file mode 100644
index 0000000000..417188cc8a
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/added_func.h
@@ -0,0 +1,41 @@
+// Added 3.0 functionality
+
+class WXDLLIMPEXP_AUI wxAuiTabArt
+{
+public:
+ virtual void SetColour(const wxColour& colour) = 0;
+ virtual void SetActiveColour(const wxColour& colour) = 0;
+};
+
+// Api to get data out of paneinfo
+class WXDLLIMPEXP_AUI wxAuiPaneInfo
+{
+ public:
+ wxString GetName();
+ wxString GetCaption();
+ wxIcon GetIcon();
+
+ wxWindow* GetWindow();
+ wxFrame* GetFrame();
+
+ int GetDirection();
+ int GetLayer();
+ int GetRow();
+ int GetPosition();
+
+ wxPoint GetFloatingPosition();
+ wxSize GetFloatingSize();
+};
+
+class wxToolBar {
+ public:
+ wxToolBarToolBase * AddStretchableSpace();
+ wxToolBarToolBase * InsertStretchableSpace(size_t pos);
+};
+
+
+class wxWindow {
+ public:
+ bool IsDoubleBuffered();
+ void SetDoubleBuffered(bool on);
+};
diff --git a/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src b/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
index 5d20019d8f..08fef1c2ff 100644
--- a/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
+++ b/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
@@ -11,7 +11,7 @@ case 100: { // wxEvtHandler::Connect
int * class_nameLen = (int *) bp; bp += 4;
if(*haveUserData) {
- userData = new wxeErlTerm(Ecmd.bin[0]);
+ userData = new wxeErlTerm(&Ecmd.bin[0]);
}
int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
@@ -42,11 +42,15 @@ case 101: { // wxEvtHandler::Disconnect
int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
if(eventType > 0) {
+ if(recurse_level > 1) {
+ delayed_delete->Append(Ecmd.Save());
+ } else {
bool Result = This->Disconnect((int) *winid,(int) *lastId,eventType,
(wxObjectEventFunction)(wxEventFunction)
&wxeEvtListener::forward,
NULL, Listener);
rt.addBool(Result);
+ }
} else {
rt.addAtom("badarg");
rt.addAtom("event_type");
diff --git a/lib/wx/api_gen/wx_extra/wxEvtHandler.erl b/lib/wx/api_gen/wx_extra/wxEvtHandler.erl
index c9726fd475..85ebc093f5 100644
--- a/lib/wx/api_gen/wx_extra/wxEvtHandler.erl
+++ b/lib/wx/api_gen/wx_extra/wxEvtHandler.erl
@@ -70,6 +70,8 @@ connect(This=#wx_ref{type=ThisT}, EventType, Options) ->
parse_opts([{callback,Fun}|R], Opts) when is_function(Fun) ->
%% Check Fun Arity?
parse_opts(R, Opts#evh{cb=Fun});
+parse_opts([{callback,CB={nospawn, Fun}}|R], Opts) when is_function(Fun) ->
+ parse_opts(R, Opts#evh{cb=CB});
parse_opts([callback|R], Opts) ->
parse_opts(R, Opts#evh{cb=self()});
parse_opts([{userData, UserData}|R],Opts) ->
diff --git a/lib/wx/api_gen/wx_extra/wxListCtrl.c_src b/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
index d6196d11a2..545d5c1c0d 100644
--- a/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/wx/api_gen/wx_extra/wxListCtrl.erl b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
index 99255bc53f..a2ce547f00 100644
--- a/lib/wx/api_gen/wx_extra/wxListCtrl.erl
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/wx/api_gen/wx_extra/wxPrintout.erl b/lib/wx/api_gen/wx_extra/wxPrintout.erl
index 1dfd86ec62..0552b5aa1a 100644
--- a/lib/wx/api_gen/wx_extra/wxPrintout.erl
+++ b/lib/wx/api_gen/wx_extra/wxPrintout.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src b/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
index 50dca4e2bb..a82ebcc46b 100644
--- a/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
+++ b/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/wx/api_gen/wx_extra/wxXmlResource.erl b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
index cd2bea6a1d..2100bbd010 100644
--- a/lib/wx/api_gen/wx_extra/wxXmlResource.erl
+++ b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl
index a60a9a93d5..ec2c35cc0e 100644
--- a/lib/wx/api_gen/wx_gen.erl
+++ b/lib/wx/api_gen/wx_gen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -704,6 +705,8 @@ parse_type2(["unsigned"|R],Info,Opts,T=#type{mod=Mod}) ->
parse_type2(R,Info,Opts,T#type{mod=[unsigned|Mod]});
parse_type2(["int"|R],Info,Opts, T) ->
parse_type2(R,Info,Opts,T#type{name=int,base=int});
+parse_type2(["wxByte"|R],Info,Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=int,base=int});
parse_type2(["char"|R],Info,Opts, T) ->
parse_type2(R,Info,Opts,T#type{name="char",base=int});
parse_type2([N="size_t"|R], Info, Opts, T) ->
@@ -770,14 +773,19 @@ parse_type2([N="wxGridCellCoordsArray"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,base={comp,"wxGridCellCoords",
[{int,"R"},{int,"C"}]},
single=array});
+parse_type2([N="wxAuiPaneInfoArray"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={class,"wxAuiPaneInfo"},
+ single=array});
+
parse_type2([N="wxRect"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"X"},{int,"Y"},
{int,"W"},{int,"H"}]}});
parse_type2([N="wxColour"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,
base={comp,N,[{int,"R"},{int,"G"},{int,"B"},{int,"A"}]}});
-parse_type2([N="wxColor"|R],Info,Opts,T) ->
- parse_type2(R,Info,Opts,T#type{name="wxColour",
+parse_type2(["wxColor"|R],Info,Opts,T) ->
+ N = "wxColour",
+ parse_type2(R,Info,Opts,T#type{name=N,
base={comp,N,[{int,"R"},{int,"G"},{int,"B"},{int,"A"}]}});
parse_type2([N="wxPoint2DDouble"|R],Info,Opts,T) ->
@@ -1195,7 +1203,7 @@ translate_constants(Enums, NotConsts0, Skip0) ->
create_consts([{{enum, Name},Enum = #enum{vals=Vals}}|R], Skip, NotConsts, Acc0) ->
CC = fun(What, Acc) ->
- create_const(What, Skip, NotConsts, Acc)
+ create_const(What, Name, Skip, NotConsts, Acc)
end,
Acc = case Vals of
undefined ->
@@ -1209,17 +1217,17 @@ create_consts([{{enum, Name},Enum = #enum{vals=Vals}}|R], Skip, NotConsts, Acc0)
create_consts(R, Skip, NotConsts, Acc);
create_consts([],_,_,Acc) -> Acc.
-create_const({Name, Val}, Skip, NotConsts, Acc) ->
+create_const({Name, Val}, EnumName, Skip, NotConsts, Acc) ->
case gb_sets:is_member(Name, Skip) of
true -> Acc;
false ->
- case gb_sets:is_member(Name, NotConsts) of
+ case gb_sets:is_member(Name, NotConsts) orelse
+ gb_sets:is_member(EnumName, NotConsts)
+ of
true ->
[#const{name=Name,val=next_id(const),is_const=false}|Acc];
false ->
[#const{name=Name,val=Val,is_const=true}|Acc]
-%% false ->
-%% [#const{name=Name,val=Val}|Acc]
end
end.
@@ -1367,7 +1375,7 @@ extract_enum3([#xmlElement{name=initializer,content=Cs}|_],_Id,[{Name,_}|Acc]) -
try
case Val0 of
["0x" ++ Val1] ->
- Val = http_util:hexlist_to_integer(Val1),
+ Val = list_to_integer(Val1, 16),
{[{Name, Val}|Acc], Val+1};
["1", "<<", Shift] ->
Val = 1 bsl list_to_integer(Shift),
@@ -1423,7 +1431,7 @@ extract_def([#xmlElement{name=param}|_],Name,_) ->
extract_def([#xmlElement{name=initializer,content=Cs}|_R],N,Skip) ->
Val0 = extract_def2(Cs),
case Val0 of
- "0x" ++ Val1 -> {N, http_util:hexlist_to_integer(Val1)};
+ "0x" ++ Val1 -> {N, list_to_integer(Val1, 16)};
_ ->
try
Val = list_to_integer(Val0),
@@ -1445,7 +1453,7 @@ extract_def(_,N,_) ->
throw(N).
extract_def2([#xmlText{value=Val}|R]) ->
- strip_comment(string:strip(Val)) ++ extract_def2(R);
+ string:strip(strip_comment(Val)) ++ extract_def2(R);
extract_def2([#xmlElement{content=Cs}|R]) ->
extract_def2(Cs) ++ extract_def2(R);
extract_def2([]) -> [].
diff --git a/lib/wx/api_gen/wx_gen.hrl b/lib/wx/api_gen/wx_gen.hrl
index 89577b9707..6aa4ed3796 100644
--- a/lib/wx/api_gen/wx_gen.hrl
+++ b/lib/wx/api_gen/wx_gen.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
-record(class,
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 107d064f4a..71b2038c56 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -115,8 +116,13 @@ taylormade_class(#class{name=CName, methods=Ms}) ->
gen_constructors(#class{name=Class, methods=Ms0}) ->
Ms = lists:append(Ms0),
Cs = lists:filter(fun(#method{method_type=MT}) -> MT =:= constructor end, Ms),
- [gen_constructor(Class, Const) || Const <- Cs].
-
+ [gen_constructor(Class, Const) || Const <- Cs],
+ case need_copy_constr(Class) of
+ true ->
+ w(" E~s(~s copy) : ~s(copy) {};~n", [Class, Class, Class]);
+ false ->
+ ignore
+ end.
gen_constructor(_Class, #method{where=merged_c}) -> ok;
gen_constructor(_Class, #method{where=erl_no_opt}) -> ok;
gen_constructor(Class, _M=#method{params=Ps, opts=FOpts}) ->
@@ -144,6 +150,14 @@ gen_constructor(Class, _M=#method{params=Ps, opts=FOpts}) ->
Endif andalso w("#endif~n", []),
ok.
+
+need_copy_constr("wxFont") -> true;
+need_copy_constr("wxIcon") -> true;
+need_copy_constr("wxImage") -> true;
+need_copy_constr("wxBitmap") -> true;
+%%need_copy_constr("wxGraphics" ++ _) -> true;
+need_copy_constr(_) -> false.
+
gen_type(#type{name=Type, ref={pointer,1}, mod=Mod},_) ->
mods(Mod) ++ to_string(Type) ++ " * ";
gen_type(#type{name=Type, ref={pointer,2}, mod=Mod},_) ->
@@ -197,17 +211,17 @@ gen_funcs(Defs) ->
w(" if(recurse_level > 1 && refd->type != 4) {~n"),
w(" delayed_delete->Append(Ecmd.Save());~n"),
w(" } else {~n"),
- w(" ((WxeApp *) wxTheApp)->clearPtr(This);~n"),
- w(" delete_object(This, refd); }~n"),
+ w(" delete_object(This, refd);~n"),
+ w(" ((WxeApp *) wxTheApp)->clearPtr(This);}~n"),
w(" } } break;~n"),
w(" case WXE_REGISTER_OBJECT: {~n"
" registerPid(bp, Ecmd.caller, memenv);~n"
" rt.addAtom(\"ok\");~n"
" break;~n"
" }~n"),
- w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(Ecmd.bin[0]->bin);~n break;~n",[]),
- w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(Ecmd.bin[0]->bin);~n break;~n",[]),
- w(" case WXE_INIT_OPENGL:~n wxe_initOpenGL(rt, bp);~n break;~n",[]),
+ w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(Ecmd.bin[0].bin);~n break;~n",[]),
+ w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(Ecmd.bin[0].bin);~n break;~n",[]),
+ w(" case WXE_INIT_OPENGL:~n wxe_initOpenGL(&rt, bp);~n break;~n",[]),
Res = [gen_class(Class) || Class <- Defs],
@@ -234,7 +248,8 @@ gen_funcs(Defs) ->
w("}} /* The End */~n~n~n"),
UglySkipList = ["wxCaret", "wxCalendarDateAttr",
- "wxFileDataObject", "wxTextDataObject", "wxBitmapDataObject"
+ "wxFileDataObject", "wxTextDataObject", "wxBitmapDataObject",
+ "wxAuiSimpleTabArt"
],
w("bool WxeApp::delete_object(void *ptr, wxeRefData *refd) {~n", []),
@@ -322,12 +337,8 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId
put(current_func, N),
put(bin_count,-1),
?WTC("gen_method"),
- Endif = case lists:keysearch(deprecated, 1, FOpts) of
- {value, {deprecated, IfDef}} ->
- w("#if ~s~n", [IfDef]),
- true;
- _ -> false
- end,
+ Endif1 = gen_if(deprecated, FOpts),
+ Endif2 = gen_if(test_if, FOpts),
w("case ~s: { // ~s::~s~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
Ps1 = declare_variables(void, Ps0),
{Ps2,Align} = decode_arguments(Ps1),
@@ -346,10 +357,19 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId
free_args(),
build_return_vals(T,Ps3),
w(" break;~n}~n", []),
- Endif andalso w("#endif~n", []),
+ Endif1 andalso w("#endif~n", []),
+ Endif2 andalso w("#endif~n", []),
erase(current_func),
M.
+gen_if(What, Opts) ->
+ case lists:keysearch(What, 1, Opts) of
+ {value, {What, IfDef}} ->
+ w("#if ~s~n", [IfDef]),
+ true;
+ _ -> false
+ end.
+
declare_variables(void,Ps) ->
[declare_var(P) || P <- Ps];
declare_variables(T, Ps) ->
@@ -630,10 +650,10 @@ decode_arg(N,#type{name=Type,base=binary,mod=Mod0},Arg,A0) ->
Mod = mods([M || M <- Mod0]),
case Arg of
arg ->
- w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p]->base;~n",
+ w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p].base;~n",
[Mod,Type,N,Mod,Type, next_id(bin_count)]);
opt ->
- w(" ~s = (~s~s*) Ecmd.bin[~p]->base;~n",
+ w(" ~s = (~s~s*) Ecmd.bin[~p].base;~n",
[N,Mod,Type,next_id(bin_count)])
end,
A0;
@@ -643,10 +663,10 @@ decode_arg(N,#type{base={term,"wxTreeItemData"},mod=Mod0},Arg,A0) ->
BinCnt = next_id(bin_count),
case Arg of
arg ->
- w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base);~n",
+ w(" ~s~s * ~s = new ~s(Ecmd.bin[~p].size, Ecmd.bin[~p].base);~n",
[Mod,Type,N,Type,BinCnt,BinCnt]);
opt ->
- w(" ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base);~n",
+ w(" ~s = new ~s(Ecmd.bin[~p].size, Ecmd.bin[~p].base);~n",
[N,Type,BinCnt,BinCnt])
end,
A0;
@@ -655,10 +675,10 @@ decode_arg(N,#type{name=Type,base={term,_},mod=Mod0},Arg,A0) ->
BinCnt = next_id(bin_count),
case Arg of
arg ->
- w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]);~n",
+ w(" ~s~s * ~s = new ~s(&Ecmd.bin[~p]);~n",
[Mod,Type,N,Type,BinCnt]);
opt ->
- w(" ~s = new ~s(Ecmd.bin[~p]);~n",
+ w(" ~s = new ~s(&Ecmd.bin[~p]);~n",
[N,Type,BinCnt])
end,
A0;
@@ -798,18 +818,21 @@ return_res1(#type{name=Type,base={comp,_,_},single=array,by_val=true}) ->
{Type ++ " Result = ", ""};
return_res1(#type{name=Type,single=true,by_val=true, base={class, _}}) ->
%% Temporary memory leak !!!!!!
- case Type of
- "wxImage" -> ok;
- "wxFont" -> ok;
- "wxBitmap" -> ok;
- "wxIcon" -> ok;
- "wxGraphics" ++ _ -> ok;
+ case {need_copy_constr(Type),Type} of
+ {true, _} -> ok;
+ {_, "wxGraphics" ++ _} -> ok;
_ ->
io:format("~s::~s Building return value of temp ~s~n",
[get(current_class),get(current_func),Type])
end,
- {Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
- ++ "3, memenv);"};
+ case need_copy_constr(Type) of
+ true ->
+ {Type ++ " * Result = new E" ++ Type ++ "(", "); newPtr((void *) Result,"
+ ++ "3, memenv);"};
+ false ->
+ {Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
+ ++ "3, memenv);"}
+ end;
return_res1(#type{base={enum,_Type},single=true,by_val=true}) ->
{"int Result = " , ""};
return_res1(#type{name="wxCharBuffer", base={binary,_},single=true,by_val=true}) ->
@@ -831,7 +854,7 @@ call_arg(#param{where=c, alt={length,Alt}}) when is_list(Alt) ->
"*" ++ Alt ++ "Len";
call_arg(#param{where=c, alt={size,Id}}) when is_integer(Id) ->
%% It's a binary
- "Ecmd.bin["++ integer_to_list(Id) ++ "]->size";
+ "Ecmd.bin["++ integer_to_list(Id) ++ "].size";
call_arg(#param{name=N,def=Def,type=#type{by_val=true,single=true,base=Base}})
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
case Def of
@@ -910,11 +933,24 @@ is_dc(Class) ->
Parents = wx_gen_erl:parents(Class),
lists:member("wxDC", Parents) orelse lists:member("wxGraphicsContext", Parents).
-build_return_vals(Type,Ps) ->
+build_return_vals(Type,Ps0) ->
+ Ps = [P || P = #param{in=In} <- Ps0, In =/= true],
HaveType = case Type of void -> 0; _ -> 1 end,
- NoOut = lists:sum([1 || #param{in=In} <- Ps, In =/= true]) + HaveType,
+ NoOut = length(Ps) + HaveType,
OutTupSz = if NoOut > 1 -> NoOut; true -> 0 end,
+ CountFloats = fun(#param{type=#type{base=Float, single=true}}, Acc)
+ when Float =:= float; Float =:= double ->
+ Acc + 1;
+ (_, Acc) ->
+ Acc
+ end,
+ NofFloats = lists:foldl(CountFloats, 1, Ps),
+ case NofFloats > 1 of
+ true -> %%io:format("Floats ~p:~p ~p ~n",[get(current_class),get(current_func), NofFloats]);
+ w(" rt.ensureFloatCount(~p);~n",[NofFloats]);
+ false -> ignore
+ end,
build_ret_types(Type,Ps),
if
OutTupSz > 1 -> w(" rt.addTupleCount(~p);~n",[OutTupSz]);
@@ -923,12 +959,11 @@ build_return_vals(Type,Ps) ->
Ps.
build_ret_types(void,Ps) ->
- Calc = fun(#param{name=N,in=False,type=T}, Free) when False =/= true ->
- case build_ret(N, {arg, False}, T) of
+ Calc = fun(#param{name=N,in=In,type=T}, Free) ->
+ case build_ret(N, {arg, In}, T) of
ok -> Free;
Other -> [Other|Free]
- end;
- (_, Free) -> Free
+ end
end,
lists:foldl(Calc, [], Ps);
build_ret_types(Type,Ps) ->
@@ -936,12 +971,11 @@ build_ret_types(Type,Ps) ->
ok -> [];
FreeStr -> [FreeStr]
end,
- Calc = fun(#param{name=N,in=False,type=T}, FreeAcc) when False =/= true ->
- case build_ret(N, {arg, False}, T) of
+ Calc = fun(#param{name=N,in=In,type=T}, FreeAcc) ->
+ case build_ret(N, {arg, In}, T) of
ok -> FreeAcc;
FreeMe -> [FreeMe|FreeAcc]
- end;
- (_, FreeAcc) -> FreeAcc
+ end
end,
lists:foldl(Calc, Free, Ps).
@@ -975,6 +1009,13 @@ build_ret(Name = "ev->m_scanCode",_,#type{base=bool,single=true,by_val=true}) ->
w(" rt.addBool(~s);~n",[Name]),
w("#else~n rt.addBool(false);~n",[]),
w("#endif~n",[]);
+build_ret(Name = "ev->m_metaDown",_,#type{base=bool,single=true,by_val=true}) ->
+ %% Hardcoded workaround for MAC on 2.9 and later
+ w("#if wxCHECK_VERSION(2,9,0) && defined(_MACOSX)~n", []),
+ w(" rt.addBool(ev->m_rawControlDown);~n",[]),
+ w("#else~n rt.addBool(~s);~n",[Name]),
+ w("#endif~n",[]);
+
build_ret(Name,_,#type{base=bool,single=true,by_val=true}) ->
w(" rt.addBool(~s);~n",[Name]);
build_ret(Name,{arg, both},#type{base=int,single=true,mod=M}) ->
@@ -995,6 +1036,10 @@ build_ret(Name,_,#type{base={comp,_,_},single=array}) ->
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
w(" rt.add(~s[i]);~n }~n",[Name]),
w(" rt.endList(~s.GetCount());~n",[Name]);
+build_ret(Name,_,#type{base={class,Class},single=array}) ->
+ w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
+ w(" rt.addRef(getRef((void *) &~s.Item(i), memenv), \"~s\");~n }~n",[Name, Class]),
+ w(" rt.endList(~s.GetCount());~n",[Name]);
build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
w(" int i=0;~n"),
w(" for(~s::const_iterator it = ~s.begin(); it != ~s.end(); ++it) {~n",
@@ -1009,7 +1054,6 @@ build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
w(" rt.endList(~s.GetCount());~n",[Name]);
build_ret(Name,_,#type{base=float,single=true}) ->
-%% w(" double Temp~s = ~s;~n", [Name,Name]),
w(" rt.addFloat(~s);~n",[Name]);
build_ret(Name,_,#type{base=double,single=true}) ->
w(" rt.addFloat(~s);~n",[Name]);
@@ -1113,6 +1157,7 @@ gen_macros() ->
w("#include <wx/html/htmlcell.h>~n"),
w("#include <wx/filename.h>~n"),
w("#include <wx/sysopt.h>~n"),
+ w("#include <wx/overlay.h>~n"),
w("~n~n", []),
w("#ifndef wxICON_DEFAULT_BITMAP_TYPE~n",[]),
@@ -1248,6 +1293,11 @@ 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"),
+ w(" app->recurse_level++;~n"),
+ w(" app->dispatch_cmds();~n"),
+ w(" app->recurse_level--;~n"),
+ w(" }~n"),
w(" };~n"),
w(" return send_res;~n"),
w(" }~n").
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
index 5ac781b40c..c28b9238dc 100644
--- a/lib/wx/api_gen/wx_gen_erl.erl
+++ b/lib/wx/api_gen/wx_gen_erl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -1168,7 +1169,7 @@ build_enum_ints(#enum{from=From, vals=Vals},Done) ->
const_value(V,_,_) when is_integer(V) -> integer_to_list(V);
const_value(V = "16#" ++ IntList,_,_) ->
- _ = http_util:hexlist_to_integer(IntList), %% ASSERT
+ _ = list_to_integer(IntList, 16), %% ASSERT
V;
const_value(V0, EnumClass, Ignore) ->
try
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index 2e961cce98..b8458e901b 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%
@@ -32,7 +33,11 @@
wxALWAYS_NATIVE_DOUBLE_BUFFER,
wxGAUGE_EMULATE_INDETERMINATE_MODE,
wxTR_DEFAULT_STYLE,
- wxSL_LABELS
+ wxSL_LABELS,
+ wxCURSOR_DEFAULT,
+ wxCURSOR_ARROWWAIT,
+ wxCURSOR_MAX,
+ wxLanguage
]}.
{gvars,
@@ -145,7 +150,12 @@
'ShouldInheritColours','Show','Thaw','TransferDataFromWindow',
'TransferDataToWindow',%'UnregisterHotKey',
'Update','UpdateWindowUI','Validate',
- 'WarpPointer']}.
+ 'WarpPointer',
+ {'SetTransparent', [{test_if, "wxCHECK_VERSION(2,8,12)"}]},
+ {'CanSetTransparent', [{test_if, "wxCHECK_VERSION(2,8,12)"}]},
+ {'IsDoubleBuffered', [{test_if, "wxCHECK_VERSION(3,0,0)"}]},
+ {'SetDoubleBuffered', [{test_if, "wxCHECK_VERSION(3,0,0) && !defined(__WXMAC__)"}]}
+]}.
{class, wxTopLevelWindowGTK, wxWindow,
[{alias, [{wxTopLevelWindowGTK, wxTopLevelWindow}]}],
@@ -362,7 +372,7 @@
{class,wxMirrorDC, wxDC, [], ['wxMirrorDC', '~wxMirrorDC']}.
{class,wxScreenDC, wxDC, [], ['wxScreenDC', '~wxScreenDC']}.
-{class,wxPostScriptDC,wxDC,[],
+{class,wxPostScriptDC,wxDC,[{ifdef, wxUSE_POSTSCRIPT}],
['wxPostScriptDC','~wxPostScriptDC',
{'SetResolution', [{deprecated, "!wxCHECK_VERSION(2,9,0)"}]},
{'GetResolution', [{deprecated, "!wxCHECK_VERSION(2,9,0)"}]}]}.
@@ -488,6 +498,8 @@
{class, wxToolBar, wxControl, [],
['AddControl','AddSeparator','AddTool','AddCheckTool','AddRadioTool',
+ {'AddStretchableSpace', [{test_if, "wxCHECK_VERSION(3,0,0)"}]},
+ {'InsertStretchableSpace', [{test_if, "wxCHECK_VERSION(3,0,0)"}]},
'DeleteTool','DeleteToolByPos','EnableTool','FindById','FindControl',
'FindToolForPosition','GetToolSize','GetToolBitmapSize','GetMargins',
%%'GetToolClientData' , %%'SetToolClientData',
@@ -552,14 +564,14 @@
{"alpha",[in,{base,binary}]},
{{4,pre_hook},
[{c, "if(!static_data) {"
- "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]},
+ "data = (unsigned char *) malloc(Ecmd.bin[0].size);"
+ "memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);}"}]},
{{5,pre_hook},
[{c, "if(!static_data) {"
- " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
- " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
- " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}]}
+ " data = (unsigned char *) malloc(Ecmd.bin[0].size);"
+ " alpha = (unsigned char *) malloc(Ecmd.bin[1].size);"
+ " memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);"
+ " memcpy(alpha,Ecmd.bin[1].base,Ecmd.bin[1].size);}"}]}
]},
'~wxImage',%'AddHandler',
'Blur','BlurHorizontal','BlurVertical',
@@ -571,14 +583,14 @@
{"alpha",[in,{base,binary}]},
{{4,pre_hook},
[{c, "if(!static_data) {"
- "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]},
+ "data = (unsigned char *) malloc(Ecmd.bin[0].size);"
+ "memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);}"}]},
{{5,pre_hook},
[{c, "if(!static_data) {"
- " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
- " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
- " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}]}
+ " data = (unsigned char *) malloc(Ecmd.bin[0].size);"
+ " alpha = (unsigned char *) malloc(Ecmd.bin[1].size);"
+ " memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);"
+ " memcpy(alpha,Ecmd.bin[1].base,Ecmd.bin[1].size);}"}]}
]},
'Destroy','FindFirstUnusedColour', % 'FindHandler',
'GetImageExtWildcard',
@@ -604,14 +616,14 @@
{'SetAlpha', [{{2,"alpha"},[in,{base,binary}, {def, none}]},
{{2,pre_hook},
[{c, "if(!static_data) {"
- "alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]}
+ "alpha = (unsigned char *) malloc(Ecmd.bin[0].size);"
+ "memcpy(alpha,Ecmd.bin[0].base,Ecmd.bin[0].size);}"}]}
]},
{'SetData', [{"data",[in,{base,binary}]},
{pre_hook,
[{c, "if(!static_data) {"
- "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]}
+ "data = (unsigned char *) malloc(Ecmd.bin[0].size);"
+ "memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);}"}]}
]},
'SetMask','SetMaskColour','SetMaskFromImage','SetOption',
'SetPalette',
@@ -1241,7 +1253,8 @@
'SetArtProvider','SetDockSizeConstraint','SetFlags','SetManagedWindow',
'ShowHint','UnInit','Update']}.
-{class, wxAuiPaneInfo, root, [{ifdef, wxUSE_AUI}],
+{class, wxAuiPaneInfo, root,
+ [{ifdef, wxUSE_AUI}],
[
wxAuiPaneInfo,'~wxAuiPaneInfo',
'BestSize','Bottom','BottomDockable','Caption','CaptionVisible',
@@ -1258,7 +1271,44 @@
'MinSize','MinimizeButton','Movable','Name',
'PaneBorder','PinButton','Position','Resizable','Right',
'RightDockable','Row','SafeSet','SetFlag','Show','ToolbarPane',
- 'Top','TopDockable','Window']}.
+ 'Top','TopDockable','Window',
+ %% Extended func
+ %% These are not initilized by default and thus cause crashes
+ %% {'GetName',
+ %% [{pre_hook, [{c, "#if 0\n"}]},
+ %% {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxString Result = This->name"}]}]},
+ %% {'GetCaption',
+ %% [{pre_hook, [{c, "#if 0\n"}]},
+ %% {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxString Result = This->caption"}]}]},
+ %% {'GetIcon',
+ %% [{pre_hook, [{c, "#if 0\n"}]},
+ %% {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxIcon Result = This->icon"}]}]},
+ {'GetWindow',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxWindow* Result = This->window"}]}]},
+ {'GetFrame',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxFrame* Result = This->frame"}]}]},
+ {'GetDirection',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n int Result = This->dock_direction"}]}]},
+ {'GetLayer',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n int Result = This->dock_layer"}]}]},
+ {'GetRow',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n int Result = This->dock_row"}]}]},
+ {'GetPosition',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n int Result = This->dock_pos"}]}]},
+ {'GetFloatingPosition',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxPoint Result = This->floating_pos"}]}]},
+ {'GetFloatingSize',
+ [{pre_hook, [{c, "#if 0\n"}]},
+ {post_hook, [{c, "#endif\n if(!This) throw wxe_badarg(0);\n wxSize Result = This->floating_size"}]}]}
+
+]}.
{class, wxAuiNotebook, wxControl, [{ifdef, wxUSE_AUI}],
['wxAuiNotebook','AddPage',%'AdvanceSelection',
@@ -1277,15 +1327,22 @@
%'Clone','DrawBackground','DrawButton','DrawTab','GetBestTabCtrlSize',
%'GetIndentSize','GetTabSize','SetFlags','SetMeasuringFont',
%'SetNormalFont','SetSelectedFont','SetSizingInfo'%,'ShowWindowList'
+ 'SetFlags', 'SetMeasuringFont', 'SetNormalFont', 'SetSelectedFont',
+ {'SetColour', [{test_if, "wxCHECK_VERSION(3,0,0)"}]},
+ {'SetActiveColour', [{test_if, "wxCHECK_VERSION(3,0,0)"}]}
]}.
{class,wxAuiDockArt, root, [{ifdef, wxUSE_AUI}],
[%% 'wxAuiDockArt','~wxAuiDockArt' %,
%%'DrawBackground','DrawBorder','DrawCaption', %% Pure virtual funcs
%%'DrawGripper','DrawPaneButton','DrawSash',
- %%'GetColor','GetColour','GetFont','GetMetric','SetColor','SetColour','SetFont','SetMetric'
+ 'GetColour','GetFont','GetMetric','SetColour','SetFont','SetMetric'
]}.
+{class,wxAuiSimpleTabArt, wxAuiTabArt, [{ifdef, wxUSE_AUI}],
+ [wxAuiSimpleTabArt]}.
+
+
{class, wxMDIParentFrame, wxFrame, [],
[
'wxMDIParentFrame',
@@ -1355,7 +1412,8 @@
wxEVT_SCROLL_THUMBRELEASE,wxEVT_SCROLL_CHANGED]}],
['GetOrientation','GetPosition']}.
{class, wxScrollWinEvent,wxEvent,
- [{event,
+ [{acc, [{m_commandInt, "GetPosition()"}, {m_extraLong, "GetOrientation()"}]},
+ {event,
[wxEVT_SCROLLWIN_TOP,wxEVT_SCROLLWIN_BOTTOM,wxEVT_SCROLLWIN_LINEUP,
wxEVT_SCROLLWIN_LINEDOWN,wxEVT_SCROLLWIN_PAGEUP,
wxEVT_SCROLLWIN_PAGEDOWN,wxEVT_SCROLLWIN_THUMBTRACK,
@@ -1380,7 +1438,9 @@
'ShiftDown'
]}.
-{class, wxSetCursorEvent, wxEvent, [{event,[wxEVT_SET_CURSOR]}],
+{class, wxSetCursorEvent, wxEvent,
+ [{acc, [{m_x, "GetX()"}, {m_y, "GetY()"}, {m_cursor, "GetCursor()"}]},
+ {event,[wxEVT_SET_CURSOR]}],
['GetCursor','GetX','GetY','HasCursor','SetCursor']}.
{class, wxKeyEvent, wxEvent,
@@ -1395,7 +1455,7 @@
{class, wxSizeEvent, wxEvent, [{event,[wxEVT_SIZE]}],
['GetSize']}.
-{class, wxMoveEvent, wxEvent, [{event,[wxEVT_MOVE]}],
+{class, wxMoveEvent, wxEvent, [{acc, [{m_pos, "GetPosition()"}, {m_rect, "GetRect()"}]}, {event,[wxEVT_MOVE]}],
['GetPosition']}.
{class, wxPaintEvent, wxEvent, [{event,[wxEVT_PAINT]}],[]}.
%%{class, wxNcPaintEvent, wxEvent, [{event,[wxEVT_NC_PAINT]}],[]}.
@@ -1404,28 +1464,28 @@
{event, [wxEVT_ERASE_BACKGROUND]}],
['GetDC']}.
{class, wxFocusEvent, wxEvent,
- [{event,[wxEVT_SET_FOCUS,wxEVT_KILL_FOCUS]}],
+ [{acc, [{m_win, "GetWindow()"}]},
+ {event,[wxEVT_SET_FOCUS,wxEVT_KILL_FOCUS]}],
['GetWindow']}.
{class,wxChildFocusEvent,wxCommandEvent,
[{event,[wxEVT_CHILD_FOCUS]}],
['GetWindow']}.
-%% {class, wxActivateEvent, wxEvent, [{event,
-%% [wxEVT_ACTIVATE,wxEVT_ACTIVATE_APP,wxEVT_HIBERNATE]}],[]}.
-
-%%{class, wxInitDialogEvent, wxEvent, [{event, []}],[]}.
-
-{class, wxMenuEvent, wxEvent,
- [{event, [wxEVT_MENU_OPEN,wxEVT_MENU_CLOSE,wxEVT_MENU_HIGHLIGHT]}],
+{class, wxMenuEvent, wxEvent,
+ [{acc, [{m_menuId, "GetMenuId()"}, {m_menu, "GetMenu()"}]},
+ {event, [wxEVT_MENU_OPEN,wxEVT_MENU_CLOSE,wxEVT_MENU_HIGHLIGHT]}],
['GetMenu','GetMenuId','IsPopup']}.
{class, wxCloseEvent, wxEvent,
[{event, [wxEVT_CLOSE_WINDOW,wxEVT_END_SESSION,wxEVT_QUERY_END_SESSION]}],
['CanVeto','GetLoggingOff','SetCanVeto','SetLoggingOff','Veto']}.
-{class, wxShowEvent, wxEvent, [{event,[wxEVT_SHOW]}],['SetShow','GetShow']}.
-{class, wxIconizeEvent, wxEvent, [{event,[wxEVT_ICONIZE]}],['Iconized']}.
+{class, wxShowEvent, wxEvent, [{acc, [{m_show, "GetShow()"}]},{event,[wxEVT_SHOW]}],['SetShow','GetShow']}.
+{class, wxIconizeEvent, wxEvent, [{acc, [{m_iconized, "Iconized()"}]},{event,[wxEVT_ICONIZE]}],['Iconized']}.
{class, wxMaximizeEvent, wxEvent, [{event,[wxEVT_MAXIMIZE]}],[]}.
-{class, wxJoystickEvent, wxEvent,
- [{event,[wxEVT_JOY_BUTTON_DOWN,wxEVT_JOY_BUTTON_UP,
+{class, wxJoystickEvent, wxEvent,
+ [{acc, [{m_pos, "GetPosition()"},{m_zPosition, "GetZPosition()"},
+ {m_buttonChange, "GetButtonChange()"}, {m_buttonState, "GetButtonState()"},
+ {m_joyStick, "GetJoystick()"}]},
+ {event,[wxEVT_JOY_BUTTON_DOWN,wxEVT_JOY_BUTTON_UP,
wxEVT_JOY_MOVE,wxEVT_JOY_ZMOVE]}],
['ButtonDown','ButtonIsDown','ButtonUp','GetButtonChange','GetButtonState',
'GetJoystick','GetPosition','GetZPosition','IsButton','IsMove','IsZMove']}.
@@ -1463,7 +1523,8 @@
'SetOrigin',
'SetPosition']}.
-{class, wxContextMenuEvent, wxCommandEvent, [{event,[wxEVT_CONTEXT_MENU]}],
+{class, wxContextMenuEvent, wxCommandEvent,
+ [{acc, [{m_pos, "GetPosition()"}]}, {event,[wxEVT_CONTEXT_MENU]}],
['GetPosition','SetPosition']}.
{enum, wxIdleMode, "wxIDLE_"}.
{class, wxIdleEvent, wxEvent, [{event,[wxEVT_IDLE]}],
@@ -1522,7 +1583,8 @@
]}.
{class, wxCalendarEvent, wxDateEvent,
- [{event,[wxEVT_CALENDAR_SEL_CHANGED, wxEVT_CALENDAR_DAY_CHANGED,
+ [{acc, [{m_date, "GetDate()"}, {m_wday, "GetWeekDay()"}]},
+ {event,[wxEVT_CALENDAR_SEL_CHANGED, wxEVT_CALENDAR_DAY_CHANGED,
wxEVT_CALENDAR_MONTH_CHANGED, wxEVT_CALENDAR_YEAR_CHANGED,
wxEVT_CALENDAR_DOUBLECLICKED, wxEVT_CALENDAR_WEEKDAY_CLICKED]}],
[
@@ -1727,8 +1789,9 @@
['GetKeyCode','GetItem','GetKeyEvent','GetLabel','GetOldItem','GetPoint',
'IsEditCancelled','SetToolTip']}.
-{class, wxNotebookEvent, wxNotifyEvent,
- [{event, [wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+{class, wxNotebookEvent, wxNotifyEvent,
+ [{acc, [{m_nSel, "GetSelection()"}, {m_nOldSel, "GetOldSelection()"}]},
+ {event, [wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING]}],
['GetOldSelection','GetSelection','SetOldSelection','SetSelection']}.
@@ -1859,7 +1922,7 @@
]}.
-{class, wxAuiManagerEvent, wxEvent,
+{class, wxAuiManagerEvent, wxEvent,
[{acc, [{button, "GetButton()"},
{dc, "GetDC()"},
{pane, "GetPane()"},
@@ -1869,6 +1932,7 @@
wxEVT_AUI_PANE_CLOSE,
wxEVT_AUI_PANE_MAXIMIZE,
wxEVT_AUI_PANE_RESTORE,
+ {wxEVT_AUI_PANE_ACTIVATED, {test_if, "wxCHECK_VERSION(2,9,5)"}},
wxEVT_AUI_RENDER,
wxEVT_AUI_FIND_MANAGER
]}],
@@ -1915,3 +1979,12 @@
{class, wxPopupTransientWindow, wxPopupWindow, [{ifdef, wxUSE_POPUPWIN}],
['wxPopupTransientWindow', '~wxPopupTransientWindow', 'Popup', 'Dismiss']}.
+
+{class, wxMouseCaptureLostEvent, wxEvent,
+ [{event,[wxEVT_MOUSE_CAPTURE_LOST]}],[]}.
+
+{class, wxOverlay, root, [],
+ ['wxOverlay', '~wxOverlay', 'Reset']}.
+
+{class, wxDCOverlay, root, [],
+ ['wxDCOverlay', '~wxDCOverlay', 'Clear']}.
diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in
index 4a7342f714..09e3390846 100644
--- a/lib/wx/c_src/Makefile.in
+++ b/lib/wx/c_src/Makefile.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/c_src/egl_impl.cpp b/lib/wx/c_src/egl_impl.cpp
index a55a145934..6c7c26f284 100644
--- a/lib/wx/c_src/egl_impl.cpp
+++ b/lib/wx/c_src/egl_impl.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2011-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/egl_impl.h b/lib/wx/c_src/egl_impl.h
index e93e4caefd..8562ae7d96 100644
--- a/lib/wx/c_src/egl_impl.h
+++ b/lib/wx/c_src/egl_impl.h
@@ -3,16 +3,17 @@
*
* 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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/wx/c_src/gen/gl_fdefs.h b/lib/wx/c_src/gen/gl_fdefs.h
index 3e742724aa..3a8ac7287e 100644
--- a/lib/wx/c_src/gen/gl_fdefs.h
+++ b/lib/wx/c_src/gen/gl_fdefs.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/gen/gl_finit.h b/lib/wx/c_src/gen/gl_finit.h
index afe947ed80..53e6666c67 100644
--- a/lib/wx/c_src/gen/gl_finit.h
+++ b/lib/wx/c_src/gen/gl_finit.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp
index 40a2fbac3c..1abd601da9 100644
--- a/lib/wx/c_src/gen/gl_funcs.cpp
+++ b/lib/wx/c_src/gen/gl_funcs.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/gen/glu_finit.h b/lib/wx/c_src/gen/glu_finit.h
index 0e55d48a2a..5685cc633a 100644
--- a/lib/wx/c_src/gen/glu_finit.h
+++ b/lib/wx/c_src/gen/glu_finit.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2012. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h
index 0a3765a910..fc0ae0d9fc 100644
--- a/lib/wx/c_src/gen/wxe_derived_dest.h
+++ b/lib/wx/c_src/gen/wxe_derived_dest.h
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2016. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -85,11 +86,13 @@ class EwxScreenDC : public wxScreenDC {
EwxScreenDC() : wxScreenDC() {};
};
+#if wxUSE_POSTSCRIPT
class EwxPostScriptDC : public wxPostScriptDC {
public: ~EwxPostScriptDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPostScriptDC(const wxPrintData& printData) : wxPostScriptDC(printData) {};
EwxPostScriptDC() : wxPostScriptDC() {};
};
+#endif // wxUSE_POSTSCRIPT
class EwxWindowDC : public wxWindowDC {
public: ~EwxWindowDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
@@ -177,6 +180,7 @@ class EwxBitmap : public wxBitmap {
EwxBitmap(const wxString& filename,wxBitmapType type) : wxBitmap(filename,type) {};
EwxBitmap(const wxImage& image,int depth) : wxBitmap(image,depth) {};
EwxBitmap() : wxBitmap() {};
+ EwxBitmap(wxBitmap copy) : wxBitmap(copy) {};
};
class EwxIcon : public wxIcon {
@@ -184,6 +188,7 @@ class EwxIcon : public wxIcon {
EwxIcon(const wxString& filename,wxBitmapType type,int desiredWidth,int desiredHeight) : wxIcon(filename,type,desiredWidth,desiredHeight) {};
EwxIcon(const wxIconLocation& loc) : wxIcon(loc) {};
EwxIcon() : wxIcon() {};
+ EwxIcon(wxIcon copy) : wxIcon(copy) {};
};
class EwxCursor : public wxCursor {
@@ -212,6 +217,7 @@ class EwxImage : public wxImage {
EwxImage(const wxString& name,const wxString& mimetype,int index) : wxImage(name,mimetype,index) {};
EwxImage(const wxString& name,long type,int index) : wxImage(name,type,index) {};
EwxImage() : wxImage() {};
+ EwxImage(wxImage copy) : wxImage(copy) {};
};
class EwxBrush : public wxBrush {
@@ -297,6 +303,7 @@ class EwxFont : public wxFont {
EwxFont(int size,wxFontFamily family,wxFontStyle style,int weight,bool underlined,const wxString& face,wxFontEncoding encoding) : wxFont(size,family,style,weight,underlined,face,encoding) {};
EwxFont(const wxString& fontname) : wxFont(fontname) {};
EwxFont() : wxFont() {};
+ EwxFont(wxFont copy) : wxFont(copy) {};
};
class EwxToolTip : public wxToolTip {
@@ -786,3 +793,9 @@ class EwxPopupTransientWindow : public wxPopupTransientWindow {
};
#endif // wxUSE_POPUPWIN
+class EwxDCOverlay : public wxDCOverlay {
+ public: ~EwxDCOverlay() {((WxeApp *)wxTheApp)->clearPtr(this);};
+ EwxDCOverlay(wxOverlay& overlay,wxWindowDC * dc,int x,int y,int width,int height) : wxDCOverlay(overlay,dc,x,y,width,height) {};
+ EwxDCOverlay(wxOverlay& overlay,wxWindowDC * dc) : wxDCOverlay(overlay,dc) {};
+};
+
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index 255b36c2fa..4affe2ba53 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -53,254 +54,258 @@ void initEventTable()
struct { int ev_type; int class_id; const char * ev_name;} event_types[] =
{
{wxEVT_NULL, 0, "null"},
- {wxEVT_COMMAND_BUTTON_CLICKED, 164, "command_button_clicked"},
- {wxEVT_COMMAND_CHECKBOX_CLICKED, 164, "command_checkbox_clicked"},
- {wxEVT_COMMAND_CHOICE_SELECTED, 164, "command_choice_selected"},
- {wxEVT_COMMAND_LISTBOX_SELECTED, 164, "command_listbox_selected"},
- {wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, 164, "command_listbox_doubleclicked"},
- {wxEVT_COMMAND_TEXT_UPDATED, 164, "command_text_updated"},
- {wxEVT_COMMAND_TEXT_ENTER, 164, "command_text_enter"},
- {wxEVT_COMMAND_MENU_SELECTED, 164, "command_menu_selected"},
- {wxEVT_COMMAND_SLIDER_UPDATED, 164, "command_slider_updated"},
- {wxEVT_COMMAND_RADIOBOX_SELECTED, 164, "command_radiobox_selected"},
- {wxEVT_COMMAND_RADIOBUTTON_SELECTED, 164, "command_radiobutton_selected"},
- {wxEVT_COMMAND_SCROLLBAR_UPDATED, 164, "command_scrollbar_updated"},
- {wxEVT_COMMAND_VLBOX_SELECTED, 164, "command_vlbox_selected"},
- {wxEVT_COMMAND_COMBOBOX_SELECTED, 164, "command_combobox_selected"},
- {wxEVT_COMMAND_TOOL_RCLICKED, 164, "command_tool_rclicked"},
- {wxEVT_COMMAND_TOOL_ENTER, 164, "command_tool_enter"},
- {wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, 164, "command_checklistbox_toggled"},
- {wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, 164, "command_togglebutton_clicked"},
- {wxEVT_COMMAND_LEFT_CLICK, 164, "command_left_click"},
- {wxEVT_COMMAND_LEFT_DCLICK, 164, "command_left_dclick"},
- {wxEVT_COMMAND_RIGHT_CLICK, 164, "command_right_click"},
- {wxEVT_COMMAND_SET_FOCUS, 164, "command_set_focus"},
- {wxEVT_COMMAND_KILL_FOCUS, 164, "command_kill_focus"},
- {wxEVT_COMMAND_ENTER, 164, "command_enter"},
- {wxEVT_SCROLL_TOP, 165, "scroll_top"},
- {wxEVT_SCROLL_BOTTOM, 165, "scroll_bottom"},
- {wxEVT_SCROLL_LINEUP, 165, "scroll_lineup"},
- {wxEVT_SCROLL_LINEDOWN, 165, "scroll_linedown"},
- {wxEVT_SCROLL_PAGEUP, 165, "scroll_pageup"},
- {wxEVT_SCROLL_PAGEDOWN, 165, "scroll_pagedown"},
- {wxEVT_SCROLL_THUMBTRACK, 165, "scroll_thumbtrack"},
- {wxEVT_SCROLL_THUMBRELEASE, 165, "scroll_thumbrelease"},
- {wxEVT_SCROLL_CHANGED, 165, "scroll_changed"},
- {wxEVT_SCROLLWIN_TOP, 166, "scrollwin_top"},
- {wxEVT_SCROLLWIN_BOTTOM, 166, "scrollwin_bottom"},
- {wxEVT_SCROLLWIN_LINEUP, 166, "scrollwin_lineup"},
- {wxEVT_SCROLLWIN_LINEDOWN, 166, "scrollwin_linedown"},
- {wxEVT_SCROLLWIN_PAGEUP, 166, "scrollwin_pageup"},
- {wxEVT_SCROLLWIN_PAGEDOWN, 166, "scrollwin_pagedown"},
- {wxEVT_SCROLLWIN_THUMBTRACK, 166, "scrollwin_thumbtrack"},
- {wxEVT_SCROLLWIN_THUMBRELEASE, 166, "scrollwin_thumbrelease"},
- {wxEVT_LEFT_DOWN, 167, "left_down"},
- {wxEVT_LEFT_UP, 167, "left_up"},
- {wxEVT_MIDDLE_DOWN, 167, "middle_down"},
- {wxEVT_MIDDLE_UP, 167, "middle_up"},
- {wxEVT_RIGHT_DOWN, 167, "right_down"},
- {wxEVT_RIGHT_UP, 167, "right_up"},
- {wxEVT_MOTION, 167, "motion"},
- {wxEVT_ENTER_WINDOW, 167, "enter_window"},
- {wxEVT_LEAVE_WINDOW, 167, "leave_window"},
- {wxEVT_LEFT_DCLICK, 167, "left_dclick"},
- {wxEVT_MIDDLE_DCLICK, 167, "middle_dclick"},
- {wxEVT_RIGHT_DCLICK, 167, "right_dclick"},
- {wxEVT_MOUSEWHEEL, 167, "mousewheel"},
- {wxEVT_SET_CURSOR, 168, "set_cursor"},
- {wxEVT_CHAR, 169, "char"},
- {wxEVT_CHAR_HOOK, 169, "char_hook"},
- {wxEVT_KEY_DOWN, 169, "key_down"},
- {wxEVT_KEY_UP, 169, "key_up"},
- {wxEVT_SIZE, 170, "size"},
- {wxEVT_MOVE, 171, "move"},
- {wxEVT_PAINT, 172, "paint"},
- {wxEVT_ERASE_BACKGROUND, 173, "erase_background"},
- {wxEVT_SET_FOCUS, 174, "set_focus"},
- {wxEVT_KILL_FOCUS, 174, "kill_focus"},
- {wxEVT_CHILD_FOCUS, 175, "child_focus"},
- {wxEVT_MENU_OPEN, 176, "menu_open"},
- {wxEVT_MENU_CLOSE, 176, "menu_close"},
- {wxEVT_MENU_HIGHLIGHT, 176, "menu_highlight"},
- {wxEVT_CLOSE_WINDOW, 177, "close_window"},
- {wxEVT_END_SESSION, 177, "end_session"},
- {wxEVT_QUERY_END_SESSION, 177, "query_end_session"},
- {wxEVT_SHOW, 178, "show"},
- {wxEVT_ICONIZE, 179, "iconize"},
- {wxEVT_MAXIMIZE, 180, "maximize"},
- {wxEVT_JOY_BUTTON_DOWN, 181, "joy_button_down"},
- {wxEVT_JOY_BUTTON_UP, 181, "joy_button_up"},
- {wxEVT_JOY_MOVE, 181, "joy_move"},
- {wxEVT_JOY_ZMOVE, 181, "joy_zmove"},
- {wxEVT_UPDATE_UI, 182, "update_ui"},
- {wxEVT_SYS_COLOUR_CHANGED, 183, "sys_colour_changed"},
- {wxEVT_MOUSE_CAPTURE_CHANGED, 184, "mouse_capture_changed"},
- {wxEVT_DISPLAY_CHANGED, 185, "display_changed"},
- {wxEVT_PALETTE_CHANGED, 186, "palette_changed"},
- {wxEVT_QUERY_NEW_PALETTE, 187, "query_new_palette"},
- {wxEVT_NAVIGATION_KEY, 188, "navigation_key"},
- {wxEVT_CREATE, 189, "create"},
- {wxEVT_DESTROY, 190, "destroy"},
- {wxEVT_HELP, 191, "help"},
- {wxEVT_DETAILED_HELP, 191, "detailed_help"},
- {wxEVT_CONTEXT_MENU, 192, "context_menu"},
- {wxEVT_IDLE, 193, "idle"},
- {wxEVT_GRID_CELL_LEFT_CLICK, 194, "grid_cell_left_click"},
- {wxEVT_GRID_CELL_RIGHT_CLICK, 194, "grid_cell_right_click"},
- {wxEVT_GRID_CELL_LEFT_DCLICK, 194, "grid_cell_left_dclick"},
- {wxEVT_GRID_CELL_RIGHT_DCLICK, 194, "grid_cell_right_dclick"},
- {wxEVT_GRID_LABEL_LEFT_CLICK, 194, "grid_label_left_click"},
- {wxEVT_GRID_LABEL_RIGHT_CLICK, 194, "grid_label_right_click"},
- {wxEVT_GRID_LABEL_LEFT_DCLICK, 194, "grid_label_left_dclick"},
- {wxEVT_GRID_LABEL_RIGHT_DCLICK, 194, "grid_label_right_dclick"},
- {wxEVT_GRID_ROW_SIZE, 194, "grid_row_size"},
- {wxEVT_GRID_COL_SIZE, 194, "grid_col_size"},
- {wxEVT_GRID_RANGE_SELECT, 194, "grid_range_select"},
- {wxEVT_GRID_CELL_CHANGE, 194, "grid_cell_change"},
- {wxEVT_GRID_SELECT_CELL, 194, "grid_select_cell"},
- {wxEVT_GRID_EDITOR_SHOWN, 194, "grid_editor_shown"},
- {wxEVT_GRID_EDITOR_HIDDEN, 194, "grid_editor_hidden"},
- {wxEVT_GRID_EDITOR_CREATED, 194, "grid_editor_created"},
- {wxEVT_GRID_CELL_BEGIN_DRAG, 194, "grid_cell_begin_drag"},
- {wxEVT_SASH_DRAGGED, 196, "sash_dragged"},
- {wxEVT_COMMAND_LIST_BEGIN_DRAG, 197, "command_list_begin_drag"},
- {wxEVT_COMMAND_LIST_BEGIN_RDRAG, 197, "command_list_begin_rdrag"},
- {wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, 197, "command_list_begin_label_edit"},
- {wxEVT_COMMAND_LIST_END_LABEL_EDIT, 197, "command_list_end_label_edit"},
- {wxEVT_COMMAND_LIST_DELETE_ITEM, 197, "command_list_delete_item"},
- {wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, 197, "command_list_delete_all_items"},
- {wxEVT_COMMAND_LIST_KEY_DOWN, 197, "command_list_key_down"},
- {wxEVT_COMMAND_LIST_INSERT_ITEM, 197, "command_list_insert_item"},
- {wxEVT_COMMAND_LIST_COL_CLICK, 197, "command_list_col_click"},
- {wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, 197, "command_list_col_right_click"},
- {wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, 197, "command_list_col_begin_drag"},
- {wxEVT_COMMAND_LIST_COL_DRAGGING, 197, "command_list_col_dragging"},
- {wxEVT_COMMAND_LIST_COL_END_DRAG, 197, "command_list_col_end_drag"},
- {wxEVT_COMMAND_LIST_ITEM_SELECTED, 197, "command_list_item_selected"},
- {wxEVT_COMMAND_LIST_ITEM_DESELECTED, 197, "command_list_item_deselected"},
- {wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, 197, "command_list_item_right_click"},
- {wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK, 197, "command_list_item_middle_click"},
- {wxEVT_COMMAND_LIST_ITEM_ACTIVATED, 197, "command_list_item_activated"},
- {wxEVT_COMMAND_LIST_ITEM_FOCUSED, 197, "command_list_item_focused"},
- {wxEVT_COMMAND_LIST_CACHE_HINT, 197, "command_list_cache_hint"},
- {wxEVT_DATE_CHANGED, 198, "date_changed"},
- {wxEVT_CALENDAR_SEL_CHANGED, 199, "calendar_sel_changed"},
- {wxEVT_CALENDAR_DAY_CHANGED, 199, "calendar_day_changed"},
- {wxEVT_CALENDAR_MONTH_CHANGED, 199, "calendar_month_changed"},
- {wxEVT_CALENDAR_YEAR_CHANGED, 199, "calendar_year_changed"},
- {wxEVT_CALENDAR_DOUBLECLICKED, 199, "calendar_doubleclicked"},
- {wxEVT_CALENDAR_WEEKDAY_CLICKED, 199, "calendar_weekday_clicked"},
- {wxEVT_COMMAND_FILEPICKER_CHANGED, 200, "command_filepicker_changed"},
- {wxEVT_COMMAND_DIRPICKER_CHANGED, 200, "command_dirpicker_changed"},
- {wxEVT_COMMAND_COLOURPICKER_CHANGED, 201, "command_colourpicker_changed"},
- {wxEVT_COMMAND_FONTPICKER_CHANGED, 202, "command_fontpicker_changed"},
- {wxEVT_STC_CHANGE, 203, "stc_change"},
- {wxEVT_STC_STYLENEEDED, 203, "stc_styleneeded"},
- {wxEVT_STC_CHARADDED, 203, "stc_charadded"},
- {wxEVT_STC_SAVEPOINTREACHED, 203, "stc_savepointreached"},
- {wxEVT_STC_SAVEPOINTLEFT, 203, "stc_savepointleft"},
- {wxEVT_STC_ROMODIFYATTEMPT, 203, "stc_romodifyattempt"},
- {wxEVT_STC_KEY, 203, "stc_key"},
- {wxEVT_STC_DOUBLECLICK, 203, "stc_doubleclick"},
- {wxEVT_STC_UPDATEUI, 203, "stc_updateui"},
- {wxEVT_STC_MODIFIED, 203, "stc_modified"},
- {wxEVT_STC_MACRORECORD, 203, "stc_macrorecord"},
- {wxEVT_STC_MARGINCLICK, 203, "stc_marginclick"},
- {wxEVT_STC_NEEDSHOWN, 203, "stc_needshown"},
- {wxEVT_STC_PAINTED, 203, "stc_painted"},
- {wxEVT_STC_USERLISTSELECTION, 203, "stc_userlistselection"},
- {wxEVT_STC_URIDROPPED, 203, "stc_uridropped"},
- {wxEVT_STC_DWELLSTART, 203, "stc_dwellstart"},
- {wxEVT_STC_DWELLEND, 203, "stc_dwellend"},
- {wxEVT_STC_START_DRAG, 203, "stc_start_drag"},
- {wxEVT_STC_DRAG_OVER, 203, "stc_drag_over"},
- {wxEVT_STC_DO_DROP, 203, "stc_do_drop"},
- {wxEVT_STC_ZOOM, 203, "stc_zoom"},
- {wxEVT_STC_HOTSPOT_CLICK, 203, "stc_hotspot_click"},
- {wxEVT_STC_HOTSPOT_DCLICK, 203, "stc_hotspot_dclick"},
- {wxEVT_STC_CALLTIP_CLICK, 203, "stc_calltip_click"},
- {wxEVT_STC_AUTOCOMP_SELECTION, 203, "stc_autocomp_selection"},
- {wxEVT_COMMAND_TREE_BEGIN_DRAG, 209, "command_tree_begin_drag"},
- {wxEVT_COMMAND_TREE_BEGIN_RDRAG, 209, "command_tree_begin_rdrag"},
- {wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, 209, "command_tree_begin_label_edit"},
- {wxEVT_COMMAND_TREE_END_LABEL_EDIT, 209, "command_tree_end_label_edit"},
- {wxEVT_COMMAND_TREE_DELETE_ITEM, 209, "command_tree_delete_item"},
- {wxEVT_COMMAND_TREE_GET_INFO, 209, "command_tree_get_info"},
- {wxEVT_COMMAND_TREE_SET_INFO, 209, "command_tree_set_info"},
- {wxEVT_COMMAND_TREE_ITEM_EXPANDED, 209, "command_tree_item_expanded"},
- {wxEVT_COMMAND_TREE_ITEM_EXPANDING, 209, "command_tree_item_expanding"},
- {wxEVT_COMMAND_TREE_ITEM_COLLAPSED, 209, "command_tree_item_collapsed"},
- {wxEVT_COMMAND_TREE_ITEM_COLLAPSING, 209, "command_tree_item_collapsing"},
- {wxEVT_COMMAND_TREE_SEL_CHANGED, 209, "command_tree_sel_changed"},
- {wxEVT_COMMAND_TREE_SEL_CHANGING, 209, "command_tree_sel_changing"},
- {wxEVT_COMMAND_TREE_KEY_DOWN, 209, "command_tree_key_down"},
- {wxEVT_COMMAND_TREE_ITEM_ACTIVATED, 209, "command_tree_item_activated"},
- {wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, 209, "command_tree_item_right_click"},
- {wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, 209, "command_tree_item_middle_click"},
- {wxEVT_COMMAND_TREE_END_DRAG, 209, "command_tree_end_drag"},
- {wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, 209, "command_tree_state_image_click"},
- {wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, 209, "command_tree_item_gettooltip"},
- {wxEVT_COMMAND_TREE_ITEM_MENU, 209, "command_tree_item_menu"},
- {wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, 210, "command_notebook_page_changed"},
- {wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, 210, "command_notebook_page_changing"},
- {wxEVT_COMMAND_TEXT_COPY, 216, "command_text_copy"},
- {wxEVT_COMMAND_TEXT_CUT, 216, "command_text_cut"},
- {wxEVT_COMMAND_TEXT_PASTE, 216, "command_text_paste"},
- {wxEVT_COMMAND_SPINCTRL_UPDATED, 217, "command_spinctrl_updated"},
- {wxEVT_SCROLL_LINEUP + wxEVT_USER_FIRST, 165, "spin_up"},
- {wxEVT_SCROLL_LINEDOWN + wxEVT_USER_FIRST, 165, "spin_down"},
- {wxEVT_SCROLL_THUMBTRACK + wxEVT_USER_FIRST, 165, "spin"},
- {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, 219, "command_splitter_sash_pos_changed"},
- {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, 219, "command_splitter_sash_pos_changing"},
- {wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, 219, "command_splitter_doubleclicked"},
- {wxEVT_COMMAND_SPLITTER_UNSPLIT, 219, "command_splitter_unsplit"},
- {wxEVT_COMMAND_HTML_LINK_CLICKED, 221, "command_html_link_clicked"},
- {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 224, "command_auinotebook_page_close"},
- {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 224, "command_auinotebook_page_changed"},
- {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 224, "command_auinotebook_page_changing"},
- {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 224, "command_auinotebook_button"},
- {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 224, "command_auinotebook_begin_drag"},
- {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 224, "command_auinotebook_end_drag"},
- {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 224, "command_auinotebook_drag_motion"},
- {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 224, "command_auinotebook_allow_dnd"},
+ {wxEVT_COMMAND_BUTTON_CLICKED, 165, "command_button_clicked"},
+ {wxEVT_COMMAND_CHECKBOX_CLICKED, 165, "command_checkbox_clicked"},
+ {wxEVT_COMMAND_CHOICE_SELECTED, 165, "command_choice_selected"},
+ {wxEVT_COMMAND_LISTBOX_SELECTED, 165, "command_listbox_selected"},
+ {wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, 165, "command_listbox_doubleclicked"},
+ {wxEVT_COMMAND_TEXT_UPDATED, 165, "command_text_updated"},
+ {wxEVT_COMMAND_TEXT_ENTER, 165, "command_text_enter"},
+ {wxEVT_COMMAND_MENU_SELECTED, 165, "command_menu_selected"},
+ {wxEVT_COMMAND_SLIDER_UPDATED, 165, "command_slider_updated"},
+ {wxEVT_COMMAND_RADIOBOX_SELECTED, 165, "command_radiobox_selected"},
+ {wxEVT_COMMAND_RADIOBUTTON_SELECTED, 165, "command_radiobutton_selected"},
+ {wxEVT_COMMAND_SCROLLBAR_UPDATED, 165, "command_scrollbar_updated"},
+ {wxEVT_COMMAND_VLBOX_SELECTED, 165, "command_vlbox_selected"},
+ {wxEVT_COMMAND_COMBOBOX_SELECTED, 165, "command_combobox_selected"},
+ {wxEVT_COMMAND_TOOL_RCLICKED, 165, "command_tool_rclicked"},
+ {wxEVT_COMMAND_TOOL_ENTER, 165, "command_tool_enter"},
+ {wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, 165, "command_checklistbox_toggled"},
+ {wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, 165, "command_togglebutton_clicked"},
+ {wxEVT_COMMAND_LEFT_CLICK, 165, "command_left_click"},
+ {wxEVT_COMMAND_LEFT_DCLICK, 165, "command_left_dclick"},
+ {wxEVT_COMMAND_RIGHT_CLICK, 165, "command_right_click"},
+ {wxEVT_COMMAND_SET_FOCUS, 165, "command_set_focus"},
+ {wxEVT_COMMAND_KILL_FOCUS, 165, "command_kill_focus"},
+ {wxEVT_COMMAND_ENTER, 165, "command_enter"},
+ {wxEVT_SCROLL_TOP, 166, "scroll_top"},
+ {wxEVT_SCROLL_BOTTOM, 166, "scroll_bottom"},
+ {wxEVT_SCROLL_LINEUP, 166, "scroll_lineup"},
+ {wxEVT_SCROLL_LINEDOWN, 166, "scroll_linedown"},
+ {wxEVT_SCROLL_PAGEUP, 166, "scroll_pageup"},
+ {wxEVT_SCROLL_PAGEDOWN, 166, "scroll_pagedown"},
+ {wxEVT_SCROLL_THUMBTRACK, 166, "scroll_thumbtrack"},
+ {wxEVT_SCROLL_THUMBRELEASE, 166, "scroll_thumbrelease"},
+ {wxEVT_SCROLL_CHANGED, 166, "scroll_changed"},
+ {wxEVT_SCROLLWIN_TOP, 167, "scrollwin_top"},
+ {wxEVT_SCROLLWIN_BOTTOM, 167, "scrollwin_bottom"},
+ {wxEVT_SCROLLWIN_LINEUP, 167, "scrollwin_lineup"},
+ {wxEVT_SCROLLWIN_LINEDOWN, 167, "scrollwin_linedown"},
+ {wxEVT_SCROLLWIN_PAGEUP, 167, "scrollwin_pageup"},
+ {wxEVT_SCROLLWIN_PAGEDOWN, 167, "scrollwin_pagedown"},
+ {wxEVT_SCROLLWIN_THUMBTRACK, 167, "scrollwin_thumbtrack"},
+ {wxEVT_SCROLLWIN_THUMBRELEASE, 167, "scrollwin_thumbrelease"},
+ {wxEVT_LEFT_DOWN, 168, "left_down"},
+ {wxEVT_LEFT_UP, 168, "left_up"},
+ {wxEVT_MIDDLE_DOWN, 168, "middle_down"},
+ {wxEVT_MIDDLE_UP, 168, "middle_up"},
+ {wxEVT_RIGHT_DOWN, 168, "right_down"},
+ {wxEVT_RIGHT_UP, 168, "right_up"},
+ {wxEVT_MOTION, 168, "motion"},
+ {wxEVT_ENTER_WINDOW, 168, "enter_window"},
+ {wxEVT_LEAVE_WINDOW, 168, "leave_window"},
+ {wxEVT_LEFT_DCLICK, 168, "left_dclick"},
+ {wxEVT_MIDDLE_DCLICK, 168, "middle_dclick"},
+ {wxEVT_RIGHT_DCLICK, 168, "right_dclick"},
+ {wxEVT_MOUSEWHEEL, 168, "mousewheel"},
+ {wxEVT_SET_CURSOR, 169, "set_cursor"},
+ {wxEVT_CHAR, 170, "char"},
+ {wxEVT_CHAR_HOOK, 170, "char_hook"},
+ {wxEVT_KEY_DOWN, 170, "key_down"},
+ {wxEVT_KEY_UP, 170, "key_up"},
+ {wxEVT_SIZE, 171, "size"},
+ {wxEVT_MOVE, 172, "move"},
+ {wxEVT_PAINT, 173, "paint"},
+ {wxEVT_ERASE_BACKGROUND, 174, "erase_background"},
+ {wxEVT_SET_FOCUS, 175, "set_focus"},
+ {wxEVT_KILL_FOCUS, 175, "kill_focus"},
+ {wxEVT_CHILD_FOCUS, 176, "child_focus"},
+ {wxEVT_MENU_OPEN, 177, "menu_open"},
+ {wxEVT_MENU_CLOSE, 177, "menu_close"},
+ {wxEVT_MENU_HIGHLIGHT, 177, "menu_highlight"},
+ {wxEVT_CLOSE_WINDOW, 178, "close_window"},
+ {wxEVT_END_SESSION, 178, "end_session"},
+ {wxEVT_QUERY_END_SESSION, 178, "query_end_session"},
+ {wxEVT_SHOW, 179, "show"},
+ {wxEVT_ICONIZE, 180, "iconize"},
+ {wxEVT_MAXIMIZE, 181, "maximize"},
+ {wxEVT_JOY_BUTTON_DOWN, 182, "joy_button_down"},
+ {wxEVT_JOY_BUTTON_UP, 182, "joy_button_up"},
+ {wxEVT_JOY_MOVE, 182, "joy_move"},
+ {wxEVT_JOY_ZMOVE, 182, "joy_zmove"},
+ {wxEVT_UPDATE_UI, 183, "update_ui"},
+ {wxEVT_SYS_COLOUR_CHANGED, 184, "sys_colour_changed"},
+ {wxEVT_MOUSE_CAPTURE_CHANGED, 185, "mouse_capture_changed"},
+ {wxEVT_DISPLAY_CHANGED, 186, "display_changed"},
+ {wxEVT_PALETTE_CHANGED, 187, "palette_changed"},
+ {wxEVT_QUERY_NEW_PALETTE, 188, "query_new_palette"},
+ {wxEVT_NAVIGATION_KEY, 189, "navigation_key"},
+ {wxEVT_CREATE, 190, "create"},
+ {wxEVT_DESTROY, 191, "destroy"},
+ {wxEVT_HELP, 192, "help"},
+ {wxEVT_DETAILED_HELP, 192, "detailed_help"},
+ {wxEVT_CONTEXT_MENU, 193, "context_menu"},
+ {wxEVT_IDLE, 194, "idle"},
+ {wxEVT_GRID_CELL_LEFT_CLICK, 195, "grid_cell_left_click"},
+ {wxEVT_GRID_CELL_RIGHT_CLICK, 195, "grid_cell_right_click"},
+ {wxEVT_GRID_CELL_LEFT_DCLICK, 195, "grid_cell_left_dclick"},
+ {wxEVT_GRID_CELL_RIGHT_DCLICK, 195, "grid_cell_right_dclick"},
+ {wxEVT_GRID_LABEL_LEFT_CLICK, 195, "grid_label_left_click"},
+ {wxEVT_GRID_LABEL_RIGHT_CLICK, 195, "grid_label_right_click"},
+ {wxEVT_GRID_LABEL_LEFT_DCLICK, 195, "grid_label_left_dclick"},
+ {wxEVT_GRID_LABEL_RIGHT_DCLICK, 195, "grid_label_right_dclick"},
+ {wxEVT_GRID_ROW_SIZE, 195, "grid_row_size"},
+ {wxEVT_GRID_COL_SIZE, 195, "grid_col_size"},
+ {wxEVT_GRID_RANGE_SELECT, 195, "grid_range_select"},
+ {wxEVT_GRID_CELL_CHANGE, 195, "grid_cell_change"},
+ {wxEVT_GRID_SELECT_CELL, 195, "grid_select_cell"},
+ {wxEVT_GRID_EDITOR_SHOWN, 195, "grid_editor_shown"},
+ {wxEVT_GRID_EDITOR_HIDDEN, 195, "grid_editor_hidden"},
+ {wxEVT_GRID_EDITOR_CREATED, 195, "grid_editor_created"},
+ {wxEVT_GRID_CELL_BEGIN_DRAG, 195, "grid_cell_begin_drag"},
+ {wxEVT_SASH_DRAGGED, 197, "sash_dragged"},
+ {wxEVT_COMMAND_LIST_BEGIN_DRAG, 198, "command_list_begin_drag"},
+ {wxEVT_COMMAND_LIST_BEGIN_RDRAG, 198, "command_list_begin_rdrag"},
+ {wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, 198, "command_list_begin_label_edit"},
+ {wxEVT_COMMAND_LIST_END_LABEL_EDIT, 198, "command_list_end_label_edit"},
+ {wxEVT_COMMAND_LIST_DELETE_ITEM, 198, "command_list_delete_item"},
+ {wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, 198, "command_list_delete_all_items"},
+ {wxEVT_COMMAND_LIST_KEY_DOWN, 198, "command_list_key_down"},
+ {wxEVT_COMMAND_LIST_INSERT_ITEM, 198, "command_list_insert_item"},
+ {wxEVT_COMMAND_LIST_COL_CLICK, 198, "command_list_col_click"},
+ {wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, 198, "command_list_col_right_click"},
+ {wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, 198, "command_list_col_begin_drag"},
+ {wxEVT_COMMAND_LIST_COL_DRAGGING, 198, "command_list_col_dragging"},
+ {wxEVT_COMMAND_LIST_COL_END_DRAG, 198, "command_list_col_end_drag"},
+ {wxEVT_COMMAND_LIST_ITEM_SELECTED, 198, "command_list_item_selected"},
+ {wxEVT_COMMAND_LIST_ITEM_DESELECTED, 198, "command_list_item_deselected"},
+ {wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, 198, "command_list_item_right_click"},
+ {wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK, 198, "command_list_item_middle_click"},
+ {wxEVT_COMMAND_LIST_ITEM_ACTIVATED, 198, "command_list_item_activated"},
+ {wxEVT_COMMAND_LIST_ITEM_FOCUSED, 198, "command_list_item_focused"},
+ {wxEVT_COMMAND_LIST_CACHE_HINT, 198, "command_list_cache_hint"},
+ {wxEVT_DATE_CHANGED, 199, "date_changed"},
+ {wxEVT_CALENDAR_SEL_CHANGED, 200, "calendar_sel_changed"},
+ {wxEVT_CALENDAR_DAY_CHANGED, 200, "calendar_day_changed"},
+ {wxEVT_CALENDAR_MONTH_CHANGED, 200, "calendar_month_changed"},
+ {wxEVT_CALENDAR_YEAR_CHANGED, 200, "calendar_year_changed"},
+ {wxEVT_CALENDAR_DOUBLECLICKED, 200, "calendar_doubleclicked"},
+ {wxEVT_CALENDAR_WEEKDAY_CLICKED, 200, "calendar_weekday_clicked"},
+ {wxEVT_COMMAND_FILEPICKER_CHANGED, 201, "command_filepicker_changed"},
+ {wxEVT_COMMAND_DIRPICKER_CHANGED, 201, "command_dirpicker_changed"},
+ {wxEVT_COMMAND_COLOURPICKER_CHANGED, 202, "command_colourpicker_changed"},
+ {wxEVT_COMMAND_FONTPICKER_CHANGED, 203, "command_fontpicker_changed"},
+ {wxEVT_STC_CHANGE, 204, "stc_change"},
+ {wxEVT_STC_STYLENEEDED, 204, "stc_styleneeded"},
+ {wxEVT_STC_CHARADDED, 204, "stc_charadded"},
+ {wxEVT_STC_SAVEPOINTREACHED, 204, "stc_savepointreached"},
+ {wxEVT_STC_SAVEPOINTLEFT, 204, "stc_savepointleft"},
+ {wxEVT_STC_ROMODIFYATTEMPT, 204, "stc_romodifyattempt"},
+ {wxEVT_STC_KEY, 204, "stc_key"},
+ {wxEVT_STC_DOUBLECLICK, 204, "stc_doubleclick"},
+ {wxEVT_STC_UPDATEUI, 204, "stc_updateui"},
+ {wxEVT_STC_MODIFIED, 204, "stc_modified"},
+ {wxEVT_STC_MACRORECORD, 204, "stc_macrorecord"},
+ {wxEVT_STC_MARGINCLICK, 204, "stc_marginclick"},
+ {wxEVT_STC_NEEDSHOWN, 204, "stc_needshown"},
+ {wxEVT_STC_PAINTED, 204, "stc_painted"},
+ {wxEVT_STC_USERLISTSELECTION, 204, "stc_userlistselection"},
+ {wxEVT_STC_URIDROPPED, 204, "stc_uridropped"},
+ {wxEVT_STC_DWELLSTART, 204, "stc_dwellstart"},
+ {wxEVT_STC_DWELLEND, 204, "stc_dwellend"},
+ {wxEVT_STC_START_DRAG, 204, "stc_start_drag"},
+ {wxEVT_STC_DRAG_OVER, 204, "stc_drag_over"},
+ {wxEVT_STC_DO_DROP, 204, "stc_do_drop"},
+ {wxEVT_STC_ZOOM, 204, "stc_zoom"},
+ {wxEVT_STC_HOTSPOT_CLICK, 204, "stc_hotspot_click"},
+ {wxEVT_STC_HOTSPOT_DCLICK, 204, "stc_hotspot_dclick"},
+ {wxEVT_STC_CALLTIP_CLICK, 204, "stc_calltip_click"},
+ {wxEVT_STC_AUTOCOMP_SELECTION, 204, "stc_autocomp_selection"},
+ {wxEVT_COMMAND_TREE_BEGIN_DRAG, 210, "command_tree_begin_drag"},
+ {wxEVT_COMMAND_TREE_BEGIN_RDRAG, 210, "command_tree_begin_rdrag"},
+ {wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, 210, "command_tree_begin_label_edit"},
+ {wxEVT_COMMAND_TREE_END_LABEL_EDIT, 210, "command_tree_end_label_edit"},
+ {wxEVT_COMMAND_TREE_DELETE_ITEM, 210, "command_tree_delete_item"},
+ {wxEVT_COMMAND_TREE_GET_INFO, 210, "command_tree_get_info"},
+ {wxEVT_COMMAND_TREE_SET_INFO, 210, "command_tree_set_info"},
+ {wxEVT_COMMAND_TREE_ITEM_EXPANDED, 210, "command_tree_item_expanded"},
+ {wxEVT_COMMAND_TREE_ITEM_EXPANDING, 210, "command_tree_item_expanding"},
+ {wxEVT_COMMAND_TREE_ITEM_COLLAPSED, 210, "command_tree_item_collapsed"},
+ {wxEVT_COMMAND_TREE_ITEM_COLLAPSING, 210, "command_tree_item_collapsing"},
+ {wxEVT_COMMAND_TREE_SEL_CHANGED, 210, "command_tree_sel_changed"},
+ {wxEVT_COMMAND_TREE_SEL_CHANGING, 210, "command_tree_sel_changing"},
+ {wxEVT_COMMAND_TREE_KEY_DOWN, 210, "command_tree_key_down"},
+ {wxEVT_COMMAND_TREE_ITEM_ACTIVATED, 210, "command_tree_item_activated"},
+ {wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, 210, "command_tree_item_right_click"},
+ {wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, 210, "command_tree_item_middle_click"},
+ {wxEVT_COMMAND_TREE_END_DRAG, 210, "command_tree_end_drag"},
+ {wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, 210, "command_tree_state_image_click"},
+ {wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, 210, "command_tree_item_gettooltip"},
+ {wxEVT_COMMAND_TREE_ITEM_MENU, 210, "command_tree_item_menu"},
+ {wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, 211, "command_notebook_page_changed"},
+ {wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, 211, "command_notebook_page_changing"},
+ {wxEVT_COMMAND_TEXT_COPY, 217, "command_text_copy"},
+ {wxEVT_COMMAND_TEXT_CUT, 217, "command_text_cut"},
+ {wxEVT_COMMAND_TEXT_PASTE, 217, "command_text_paste"},
+ {wxEVT_COMMAND_SPINCTRL_UPDATED, 218, "command_spinctrl_updated"},
+ {wxEVT_SCROLL_LINEUP + wxEVT_USER_FIRST, 166, "spin_up"},
+ {wxEVT_SCROLL_LINEDOWN + wxEVT_USER_FIRST, 166, "spin_down"},
+ {wxEVT_SCROLL_THUMBTRACK + wxEVT_USER_FIRST, 166, "spin"},
+ {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, 220, "command_splitter_sash_pos_changed"},
+ {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, 220, "command_splitter_sash_pos_changing"},
+ {wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, 220, "command_splitter_doubleclicked"},
+ {wxEVT_COMMAND_SPLITTER_UNSPLIT, 220, "command_splitter_unsplit"},
+ {wxEVT_COMMAND_HTML_LINK_CLICKED, 222, "command_html_link_clicked"},
+ {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 225, "command_auinotebook_page_close"},
+ {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 225, "command_auinotebook_page_changed"},
+ {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 225, "command_auinotebook_page_changing"},
+ {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 225, "command_auinotebook_button"},
+ {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 225, "command_auinotebook_begin_drag"},
+ {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 225, "command_auinotebook_end_drag"},
+ {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 225, "command_auinotebook_drag_motion"},
+ {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 225, "command_auinotebook_allow_dnd"},
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 224, "command_auinotebook_tab_middle_down"},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 225, "command_auinotebook_tab_middle_down"},
#endif
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 224, "command_auinotebook_tab_middle_up"},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 225, "command_auinotebook_tab_middle_up"},
#endif
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 224, "command_auinotebook_tab_right_down"},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 225, "command_auinotebook_tab_right_down"},
#endif
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 224, "command_auinotebook_tab_right_up"},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 225, "command_auinotebook_tab_right_up"},
#endif
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 224, "command_auinotebook_page_closed"},
+ {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 225, "command_auinotebook_page_closed"},
#endif
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 224, "command_auinotebook_drag_done"},
+ {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 225, "command_auinotebook_drag_done"},
#endif
#if wxCHECK_VERSION(2,8,5)
- {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 224, "command_auinotebook_bg_dclick"},
+ {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 225, "command_auinotebook_bg_dclick"},
+#endif
+ {wxEVT_AUI_PANE_BUTTON, 226, "aui_pane_button"},
+ {wxEVT_AUI_PANE_CLOSE, 226, "aui_pane_close"},
+ {wxEVT_AUI_PANE_MAXIMIZE, 226, "aui_pane_maximize"},
+ {wxEVT_AUI_PANE_RESTORE, 226, "aui_pane_restore"},
+#if wxCHECK_VERSION(2,9,5)
+ {wxEVT_AUI_PANE_ACTIVATED, 226, "aui_pane_activated"},
#endif
- {wxEVT_AUI_PANE_BUTTON, 225, "aui_pane_button"},
- {wxEVT_AUI_PANE_CLOSE, 225, "aui_pane_close"},
- {wxEVT_AUI_PANE_MAXIMIZE, 225, "aui_pane_maximize"},
- {wxEVT_AUI_PANE_RESTORE, 225, "aui_pane_restore"},
- {wxEVT_AUI_RENDER, 225, "aui_render"},
- {wxEVT_AUI_FIND_MANAGER, 225, "aui_find_manager"},
- {wxEVT_TASKBAR_MOVE, 228, "taskbar_move"},
- {wxEVT_TASKBAR_LEFT_DOWN, 228, "taskbar_left_down"},
- {wxEVT_TASKBAR_LEFT_UP, 228, "taskbar_left_up"},
- {wxEVT_TASKBAR_RIGHT_DOWN, 228, "taskbar_right_down"},
- {wxEVT_TASKBAR_RIGHT_UP, 228, "taskbar_right_up"},
- {wxEVT_TASKBAR_LEFT_DCLICK, 228, "taskbar_left_dclick"},
- {wxEVT_TASKBAR_RIGHT_DCLICK, 228, "taskbar_right_dclick"},
- {wxEVT_INIT_DIALOG, 229, "init_dialog"},
- {wxEVT_ACTIVATE, 231, "activate"},
- {wxEVT_ACTIVATE_APP, 231, "activate_app"},
- {wxEVT_HIBERNATE, 231, "hibernate"},
+ {wxEVT_AUI_RENDER, 226, "aui_render"},
+ {wxEVT_AUI_FIND_MANAGER, 226, "aui_find_manager"},
+ {wxEVT_TASKBAR_MOVE, 229, "taskbar_move"},
+ {wxEVT_TASKBAR_LEFT_DOWN, 229, "taskbar_left_down"},
+ {wxEVT_TASKBAR_LEFT_UP, 229, "taskbar_left_up"},
+ {wxEVT_TASKBAR_RIGHT_DOWN, 229, "taskbar_right_down"},
+ {wxEVT_TASKBAR_RIGHT_UP, 229, "taskbar_right_up"},
+ {wxEVT_TASKBAR_LEFT_DCLICK, 229, "taskbar_left_dclick"},
+ {wxEVT_TASKBAR_RIGHT_DCLICK, 229, "taskbar_right_dclick"},
+ {wxEVT_INIT_DIALOG, 230, "init_dialog"},
+ {wxEVT_ACTIVATE, 232, "activate"},
+ {wxEVT_ACTIVATE_APP, 232, "activate_app"},
+ {wxEVT_HIBERNATE, 232, "hibernate"},
+ {wxEVT_MOUSE_CAPTURE_LOST, 235, "mouse_capture_lost"},
{-1, 0, }
};
for(int i=0; event_types[i].ev_type != -1; i++) {
@@ -343,7 +348,7 @@ bool sendevent(wxEvent *event, ErlDrvTermData port)
rt.addRef(cb->obj, cb->class_name);
rt.addExt2Term(cb->user_data);
switch(Etype->cID) {
-case 164: {// wxCommandEvent
+case 165: {// wxCommandEvent
wxCommandEvent * ev = (wxCommandEvent *) event;
evClass = (char*)"wxCommandEvent";
rt.addAtom((char*)"wxCommand");
@@ -354,7 +359,7 @@ case 164: {// wxCommandEvent
rt.addTupleCount(5);
break;
}
-case 165: {// wxScrollEvent or wxSpinEvent
+case 166: {// wxScrollEvent or wxSpinEvent
if(event->IsKindOf(CLASSINFO(wxScrollEvent))) {
wxScrollEvent * ev = (wxScrollEvent *) event;
evClass = (char*)"wxScrollEvent";
@@ -374,14 +379,17 @@ case 165: {// wxScrollEvent or wxSpinEvent
}
break;
}
-case 166: {// wxScrollWinEvent
+case 167: {// wxScrollWinEvent
+ wxScrollWinEvent * ev = (wxScrollWinEvent *) event;
evClass = (char*)"wxScrollWinEvent";
rt.addAtom((char*)"wxScrollWin");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addInt(ev->GetPosition());
+ rt.addInt(ev->GetOrientation());
+ rt.addTupleCount(4);
break;
}
-case 167: {// wxMouseEvent
+case 168: {// wxMouseEvent
wxMouseEvent * ev = (wxMouseEvent *) event;
evClass = (char*)"wxMouseEvent";
rt.addAtom((char*)"wxMouse");
@@ -394,21 +402,31 @@ case 167: {// wxMouseEvent
rt.addBool(ev->m_controlDown);
rt.addBool(ev->m_shiftDown);
rt.addBool(ev->m_altDown);
+#if wxCHECK_VERSION(2,9,0) && defined(_MACOSX)
+ rt.addBool(ev->m_rawControlDown);
+#else
rt.addBool(ev->m_metaDown);
+#endif
rt.addInt(ev->m_wheelRotation);
rt.addInt(ev->m_wheelDelta);
rt.addInt(ev->m_linesPerAction);
rt.addTupleCount(14);
break;
}
-case 168: {// wxSetCursorEvent
+case 169: {// wxSetCursorEvent
+ wxSetCursorEvent * ev = (wxSetCursorEvent *) event;
+ wxCursor * GetCursor = new wxCursor(ev->GetCursor());
+ app->newPtr((void *) GetCursor,3, memenv);
evClass = (char*)"wxSetCursorEvent";
rt.addAtom((char*)"wxSetCursor");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addInt(ev->GetX());
+ rt.addInt(ev->GetY());
+ rt.addRef(getRef((void *)GetCursor,memenv), "wxCursor");
+ rt.addTupleCount(5);
break;
}
-case 169: {// wxKeyEvent
+case 170: {// wxKeyEvent
wxKeyEvent * ev = (wxKeyEvent *) event;
evClass = (char*)"wxKeyEvent";
rt.addAtom((char*)"wxKey");
@@ -419,7 +437,11 @@ case 169: {// wxKeyEvent
rt.addBool(ev->m_controlDown);
rt.addBool(ev->m_shiftDown);
rt.addBool(ev->m_altDown);
+#if wxCHECK_VERSION(2,9,0) && defined(_MACOSX)
+ rt.addBool(ev->m_rawControlDown);
+#else
rt.addBool(ev->m_metaDown);
+#endif
#if !wxCHECK_VERSION(2,9,0)
rt.addBool(ev->m_scanCode);
#else
@@ -431,7 +453,7 @@ case 169: {// wxKeyEvent
rt.addTupleCount(13);
break;
}
-case 170: {// wxSizeEvent
+case 171: {// wxSizeEvent
wxSizeEvent * ev = (wxSizeEvent *) event;
evClass = (char*)"wxSizeEvent";
rt.addAtom((char*)"wxSize");
@@ -441,21 +463,24 @@ case 170: {// wxSizeEvent
rt.addTupleCount(4);
break;
}
-case 171: {// wxMoveEvent
+case 172: {// wxMoveEvent
+ wxMoveEvent * ev = (wxMoveEvent *) event;
evClass = (char*)"wxMoveEvent";
rt.addAtom((char*)"wxMove");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.add(ev->GetPosition());
+ rt.add(ev->GetRect());
+ rt.addTupleCount(4);
break;
}
-case 172: {// wxPaintEvent
+case 173: {// wxPaintEvent
evClass = (char*)"wxPaintEvent";
rt.addAtom((char*)"wxPaint");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 173: {// wxEraseEvent
+case 174: {// wxEraseEvent
wxEraseEvent * ev = (wxEraseEvent *) event;
wxDC * GetDC = ev->GetDC();
evClass = (char*)"wxEraseEvent";
@@ -465,105 +490,122 @@ case 173: {// wxEraseEvent
rt.addTupleCount(3);
break;
}
-case 174: {// wxFocusEvent
+case 175: {// wxFocusEvent
+ wxFocusEvent * ev = (wxFocusEvent *) event;
+ wxWindow * GetWindow = ev->GetWindow();
evClass = (char*)"wxFocusEvent";
rt.addAtom((char*)"wxFocus");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addRef(getRef((void *)GetWindow,memenv), "wxWindow");
+ rt.addTupleCount(3);
break;
}
-case 175: {// wxChildFocusEvent
+case 176: {// wxChildFocusEvent
evClass = (char*)"wxChildFocusEvent";
rt.addAtom((char*)"wxChildFocus");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 176: {// wxMenuEvent
+case 177: {// wxMenuEvent
+ wxMenuEvent * ev = (wxMenuEvent *) event;
+ wxMenu * GetMenu = ev->GetMenu();
evClass = (char*)"wxMenuEvent";
rt.addAtom((char*)"wxMenu");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addInt(ev->GetMenuId());
+ rt.addRef(getRef((void *)GetMenu,memenv), "wxMenu");
+ rt.addTupleCount(4);
break;
}
-case 177: {// wxCloseEvent
+case 178: {// wxCloseEvent
evClass = (char*)"wxCloseEvent";
rt.addAtom((char*)"wxClose");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 178: {// wxShowEvent
+case 179: {// wxShowEvent
+ wxShowEvent * ev = (wxShowEvent *) event;
evClass = (char*)"wxShowEvent";
rt.addAtom((char*)"wxShow");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addBool(ev->GetShow());
+ rt.addTupleCount(3);
break;
}
-case 179: {// wxIconizeEvent
+case 180: {// wxIconizeEvent
+ wxIconizeEvent * ev = (wxIconizeEvent *) event;
evClass = (char*)"wxIconizeEvent";
rt.addAtom((char*)"wxIconize");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addBool(ev->Iconized());
+ rt.addTupleCount(3);
break;
}
-case 180: {// wxMaximizeEvent
+case 181: {// wxMaximizeEvent
evClass = (char*)"wxMaximizeEvent";
rt.addAtom((char*)"wxMaximize");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 181: {// wxJoystickEvent
+case 182: {// wxJoystickEvent
+ wxJoystickEvent * ev = (wxJoystickEvent *) event;
evClass = (char*)"wxJoystickEvent";
rt.addAtom((char*)"wxJoystick");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.add(ev->GetPosition());
+ rt.addInt(ev->GetZPosition());
+ rt.addInt(ev->GetButtonChange());
+ rt.addInt(ev->GetButtonState());
+ rt.addInt(ev->GetJoystick());
+ rt.addTupleCount(7);
break;
}
-case 182: {// wxUpdateUIEvent
+case 183: {// wxUpdateUIEvent
evClass = (char*)"wxUpdateUIEvent";
rt.addAtom((char*)"wxUpdateUI");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 183: {// wxSysColourChangedEvent
+case 184: {// wxSysColourChangedEvent
evClass = (char*)"wxSysColourChangedEvent";
rt.addAtom((char*)"wxSysColourChanged");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 184: {// wxMouseCaptureChangedEvent
+case 185: {// wxMouseCaptureChangedEvent
evClass = (char*)"wxMouseCaptureChangedEvent";
rt.addAtom((char*)"wxMouseCaptureChanged");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 185: {// wxDisplayChangedEvent
+case 186: {// wxDisplayChangedEvent
evClass = (char*)"wxDisplayChangedEvent";
rt.addAtom((char*)"wxDisplayChanged");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 186: {// wxPaletteChangedEvent
+case 187: {// wxPaletteChangedEvent
evClass = (char*)"wxPaletteChangedEvent";
rt.addAtom((char*)"wxPaletteChanged");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 187: {// wxQueryNewPaletteEvent
+case 188: {// wxQueryNewPaletteEvent
evClass = (char*)"wxQueryNewPaletteEvent";
rt.addAtom((char*)"wxQueryNewPalette");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 188: {// wxNavigationKeyEvent
+case 189: {// wxNavigationKeyEvent
wxNavigationKeyEvent * ev = (wxNavigationKeyEvent *) event;
evClass = (char*)"wxNavigationKeyEvent";
rt.addAtom((char*)"wxNavigationKey");
@@ -573,42 +615,44 @@ case 188: {// wxNavigationKeyEvent
rt.addTupleCount(4);
break;
}
-case 189: {// wxWindowCreateEvent
+case 190: {// wxWindowCreateEvent
evClass = (char*)"wxWindowCreateEvent";
rt.addAtom((char*)"wxWindowCreate");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 190: {// wxWindowDestroyEvent
+case 191: {// wxWindowDestroyEvent
evClass = (char*)"wxWindowDestroyEvent";
rt.addAtom((char*)"wxWindowDestroy");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 191: {// wxHelpEvent
+case 192: {// wxHelpEvent
evClass = (char*)"wxHelpEvent";
rt.addAtom((char*)"wxHelp");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 192: {// wxContextMenuEvent
+case 193: {// wxContextMenuEvent
+ wxContextMenuEvent * ev = (wxContextMenuEvent *) event;
evClass = (char*)"wxContextMenuEvent";
rt.addAtom((char*)"wxContextMenu");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.add(ev->GetPosition());
+ rt.addTupleCount(3);
break;
}
-case 193: {// wxIdleEvent
+case 194: {// wxIdleEvent
evClass = (char*)"wxIdleEvent";
rt.addAtom((char*)"wxIdle");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 194: {// wxGridEvent
+case 195: {// wxGridEvent
wxGridEvent * ev = (wxGridEvent *) event;
evClass = (char*)"wxGridEvent";
rt.addAtom((char*)"wxGrid");
@@ -625,7 +669,7 @@ case 194: {// wxGridEvent
rt.addTupleCount(11);
break;
}
-case 196: {// wxSashEvent
+case 197: {// wxSashEvent
wxSashEvent * ev = (wxSashEvent *) event;
evClass = (char*)"wxSashEvent";
rt.addAtom((char*)"wxSash");
@@ -636,7 +680,7 @@ case 196: {// wxSashEvent
rt.addTupleCount(5);
break;
}
-case 197: {// wxListEvent
+case 198: {// wxListEvent
wxListEvent * ev = (wxListEvent *) event;
evClass = (char*)"wxListEvent";
rt.addAtom((char*)"wxList");
@@ -649,7 +693,7 @@ case 197: {// wxListEvent
rt.addTupleCount(7);
break;
}
-case 198: {// wxDateEvent
+case 199: {// wxDateEvent
wxDateEvent * ev = (wxDateEvent *) event;
evClass = (char*)"wxDateEvent";
rt.addAtom((char*)"wxDate");
@@ -658,14 +702,17 @@ case 198: {// wxDateEvent
rt.addTupleCount(3);
break;
}
-case 199: {// wxCalendarEvent
+case 200: {// wxCalendarEvent
+ wxCalendarEvent * ev = (wxCalendarEvent *) event;
evClass = (char*)"wxCalendarEvent";
rt.addAtom((char*)"wxCalendar");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addInt(ev->GetWeekDay());
+ rt.add(ev->GetDate());
+ rt.addTupleCount(4);
break;
}
-case 200: {// wxFileDirPickerEvent
+case 201: {// wxFileDirPickerEvent
wxFileDirPickerEvent * ev = (wxFileDirPickerEvent *) event;
evClass = (char*)"wxFileDirPickerEvent";
rt.addAtom((char*)"wxFileDirPicker");
@@ -674,7 +721,7 @@ case 200: {// wxFileDirPickerEvent
rt.addTupleCount(3);
break;
}
-case 201: {// wxColourPickerEvent
+case 202: {// wxColourPickerEvent
wxColourPickerEvent * ev = (wxColourPickerEvent *) event;
evClass = (char*)"wxColourPickerEvent";
rt.addAtom((char*)"wxColourPicker");
@@ -683,7 +730,7 @@ case 201: {// wxColourPickerEvent
rt.addTupleCount(3);
break;
}
-case 202: {// wxFontPickerEvent
+case 203: {// wxFontPickerEvent
wxFontPickerEvent * ev = (wxFontPickerEvent *) event;
wxFont * GetFont = new wxFont(ev->GetFont());
app->newPtr((void *) GetFont,3, memenv);
@@ -694,7 +741,7 @@ case 202: {// wxFontPickerEvent
rt.addTupleCount(3);
break;
}
-case 203: {// wxStyledTextEvent
+case 204: {// wxStyledTextEvent
wxStyledTextEvent * ev = (wxStyledTextEvent *) event;
evClass = (char*)"wxStyledTextEvent";
rt.addAtom((char*)"wxStyledText");
@@ -722,7 +769,7 @@ case 203: {// wxStyledTextEvent
rt.addTupleCount(22);
break;
}
-case 209: {// wxTreeEvent
+case 210: {// wxTreeEvent
wxTreeEvent * ev = (wxTreeEvent *) event;
evClass = (char*)"wxTreeEvent";
rt.addAtom((char*)"wxTree");
@@ -733,21 +780,24 @@ case 209: {// wxTreeEvent
rt.addTupleCount(5);
break;
}
-case 210: {// wxNotebookEvent
+case 211: {// wxNotebookEvent
+ wxNotebookEvent * ev = (wxNotebookEvent *) event;
evClass = (char*)"wxNotebookEvent";
rt.addAtom((char*)"wxNotebook");
rt.addAtom(Etype->eName);
- rt.addTupleCount(2);
+ rt.addInt(ev->GetSelection());
+ rt.addInt(ev->GetOldSelection());
+ rt.addTupleCount(4);
break;
}
-case 216: {// wxClipboardTextEvent
+case 217: {// wxClipboardTextEvent
evClass = (char*)"wxClipboardTextEvent";
rt.addAtom((char*)"wxClipboardText");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 217: {// wxSpinEvent
+case 218: {// wxSpinEvent
wxSpinEvent * ev = (wxSpinEvent *) event;
evClass = (char*)"wxSpinEvent";
rt.addAtom((char*)"wxSpin");
@@ -756,14 +806,14 @@ case 217: {// wxSpinEvent
rt.addTupleCount(3);
break;
}
-case 219: {// wxSplitterEvent
+case 220: {// wxSplitterEvent
evClass = (char*)"wxSplitterEvent";
rt.addAtom((char*)"wxSplitter");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 221: {// wxHtmlLinkEvent
+case 222: {// wxHtmlLinkEvent
wxHtmlLinkEvent * ev = (wxHtmlLinkEvent *) event;
evClass = (char*)"wxHtmlLinkEvent";
rt.addAtom((char*)"wxHtmlLink");
@@ -772,7 +822,7 @@ case 221: {// wxHtmlLinkEvent
rt.addTupleCount(3);
break;
}
-case 224: {// wxAuiNotebookEvent
+case 225: {// wxAuiNotebookEvent
wxAuiNotebookEvent * ev = (wxAuiNotebookEvent *) event;
wxAuiNotebook * GetDragSource = ev->GetDragSource();
evClass = (char*)"wxAuiNotebookEvent";
@@ -784,7 +834,7 @@ case 224: {// wxAuiNotebookEvent
rt.addTupleCount(5);
break;
}
-case 225: {// wxAuiManagerEvent
+case 226: {// wxAuiManagerEvent
wxAuiManagerEvent * ev = (wxAuiManagerEvent *) event;
wxAuiManager * GetManager = ev->GetManager();
wxAuiPaneInfo * GetPane = ev->GetPane();
@@ -801,21 +851,21 @@ case 225: {// wxAuiManagerEvent
rt.addTupleCount(8);
break;
}
-case 228: {// wxTaskBarIconEvent
+case 229: {// wxTaskBarIconEvent
evClass = (char*)"wxTaskBarIconEvent";
rt.addAtom((char*)"wxTaskBarIcon");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 229: {// wxInitDialogEvent
+case 230: {// wxInitDialogEvent
evClass = (char*)"wxInitDialogEvent";
rt.addAtom((char*)"wxInitDialog");
rt.addAtom(Etype->eName);
rt.addTupleCount(2);
break;
}
-case 231: {// wxActivateEvent
+case 232: {// wxActivateEvent
wxActivateEvent * ev = (wxActivateEvent *) event;
evClass = (char*)"wxActivateEvent";
rt.addAtom((char*)"wxActivate");
@@ -824,6 +874,13 @@ case 231: {// wxActivateEvent
rt.addTupleCount(3);
break;
}
+case 235: {// wxMouseCaptureLostEvent
+ evClass = (char*)"wxMouseCaptureLostEvent";
+ rt.addAtom((char*)"wxMouseCaptureLost");
+ rt.addAtom(Etype->eName);
+ rt.addTupleCount(2);
+ break;
+}
}
rt.addTupleCount(5);
@@ -840,6 +897,11 @@ case 231: {// wxActivateEvent
} else {
send_res = rt.send();
if(cb->skip) event->Skip();
+ if(app->recurse_level < 1) {
+ app->recurse_level++;
+ app->dispatch_cmds();
+ app->recurse_level--;
+ }
};
return send_res;
}
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index 91ce5d810c..03b0baf875 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2016. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -51,8 +52,8 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd)
if(recurse_level > 1 && refd->type != 4) {
delayed_delete->Append(Ecmd.Save());
} else {
- ((WxeApp *) wxTheApp)->clearPtr(This);
- delete_object(This, refd); }
+ delete_object(This, refd);
+ ((WxeApp *) wxTheApp)->clearPtr(This);}
} } break;
case WXE_REGISTER_OBJECT: {
registerPid(bp, Ecmd.caller, memenv);
@@ -60,13 +61,13 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd)
break;
}
case WXE_BIN_INCR:
- driver_binary_inc_refc(Ecmd.bin[0]->bin);
+ driver_binary_inc_refc(Ecmd.bin[0].bin);
break;
case WXE_BIN_DECR:
- driver_binary_dec_refc(Ecmd.bin[0]->bin);
+ driver_binary_dec_refc(Ecmd.bin[0].bin);
break;
case WXE_INIT_OPENGL:
- wxe_initOpenGL(rt, bp);
+ wxe_initOpenGL(&rt, bp);
break;
case 100: { // wxEvtHandler::Connect
@@ -81,7 +82,7 @@ case 100: { // wxEvtHandler::Connect
int * class_nameLen = (int *) bp; bp += 4;
if(*haveUserData) {
- userData = new wxeErlTerm(Ecmd.bin[0]);
+ userData = new wxeErlTerm(&Ecmd.bin[0]);
}
int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
@@ -112,11 +113,15 @@ case 101: { // wxEvtHandler::Disconnect
int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
if(eventType > 0) {
+ if(recurse_level > 1) {
+ delayed_delete->Append(Ecmd.Save());
+ } else {
bool Result = This->Disconnect((int) *winid,(int) *lastId,eventType,
(wxObjectEventFunction)(wxEventFunction)
&wxeEvtListener::forward,
NULL, Listener);
rt.addBool(Result);
+ }
} else {
rt.addAtom("badarg");
rt.addAtom("event_type");
@@ -514,7 +519,7 @@ case wxWindow_GetExtraStyle: { // wxWindow::GetExtraStyle
case wxWindow_GetFont: { // wxWindow::GetFont
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -1663,10 +1668,47 @@ case wxWindow_WarpPointer: { // wxWindow::WarpPointer
This->WarpPointer(*x,*y);
break;
}
+#if wxCHECK_VERSION(2,8,12)
+case wxWindow_SetTransparent: { // wxWindow::SetTransparent
+ wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ int * alpha = (int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ bool Result = This->SetTransparent(*alpha);
+ rt.addBool(Result);
+ break;
+}
+#endif
+#if wxCHECK_VERSION(2,8,12)
+case wxWindow_CanSetTransparent: { // wxWindow::CanSetTransparent
+ wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ bool Result = This->CanSetTransparent();
+ rt.addBool(Result);
+ break;
+}
+#endif
+#if wxCHECK_VERSION(3,0,0)
+case wxWindow_IsDoubleBuffered: { // wxWindow::IsDoubleBuffered
+ wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ bool Result = This->IsDoubleBuffered();
+ rt.addBool(Result);
+ break;
+}
+#endif
+#if wxCHECK_VERSION(3,0,0) && !defined(__WXMAC__)
+case wxWindow_SetDoubleBuffered: { // wxWindow::SetDoubleBuffered
+ wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ bool * on = (bool *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetDoubleBuffered(*on);
+ break;
+}
+#endif
case wxTopLevelWindow_GetIcon: { // wxTopLevelWindow::GetIcon
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- const wxIcon * Result = new wxIcon(This->GetIcon()); newPtr((void *) Result,3, memenv);;
+ const wxIcon * Result = new EwxIcon(This->GetIcon()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
break;
}
@@ -3060,7 +3102,7 @@ case wxGrid_GetCellFont: { // wxGrid::GetCellFont
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetCellFont(*row,*col)); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetCellFont(*row,*col)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -3155,7 +3197,7 @@ case wxGrid_GetDefaultCellBackgroundColour: { // wxGrid::GetDefaultCellBackgroun
case wxGrid_GetDefaultCellFont: { // wxGrid::GetDefaultCellFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetDefaultCellFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetDefaultCellFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -3294,7 +3336,7 @@ case wxGrid_GetLabelBackgroundColour: { // wxGrid::GetLabelBackgroundColour
case wxGrid_GetLabelFont: { // wxGrid::GetLabelFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetLabelFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetLabelFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -5533,6 +5575,7 @@ case wxDC_GetUserScale: { // wxDC::GetUserScale
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->GetUserScale(&x,&y);
+ rt.ensureFloatCount(3);
rt.addFloat(x);
rt.addFloat(y);
rt.addTupleCount(2);
@@ -5854,6 +5897,7 @@ case wxScreenDC_new: { // wxScreenDC::wxScreenDC
rt.addRef(getRef((void *)Result,memenv), "wxScreenDC");
break;
}
+#if wxUSE_POSTSCRIPT
case wxPostScriptDC_new_0: { // wxPostScriptDC::wxPostScriptDC
wxPostScriptDC * Result = new EwxPostScriptDC();
newPtr((void *) Result, 4, memenv);
@@ -5881,6 +5925,7 @@ case wxPostScriptDC_GetResolution: { // wxPostScriptDC::GetResolution
break;
}
#endif
+#endif // wxUSE_POSTSCRIPT
#if !wxCHECK_VERSION(2,9,0)
case wxWindowDC_new_0: { // wxWindowDC::wxWindowDC
wxWindowDC * Result = new EwxWindowDC();
@@ -6430,6 +6475,7 @@ case wxGraphicsContext_GetTextExtent: { // wxGraphicsContext::GetTextExtent
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->GetTextExtent(text,&width,&height,&descent,&externalLeading);
+ rt.ensureFloatCount(5);
rt.addFloat(width);
rt.addFloat(height);
rt.addFloat(descent);
@@ -6575,6 +6621,7 @@ case wxGraphicsMatrix_Get: { // wxGraphicsMatrix::Get
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Get(&a,&b,&c,&d,&tx,&ty);
+ rt.ensureFloatCount(7);
rt.addFloat(a);
rt.addFloat(b);
rt.addFloat(c);
@@ -6676,6 +6723,7 @@ case wxGraphicsMatrix_TransformPoint: { // wxGraphicsMatrix::TransformPoint
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->TransformPoint(&x,&y);
+ rt.ensureFloatCount(3);
rt.addFloat(x);
rt.addFloat(y);
rt.addTupleCount(2);
@@ -6687,6 +6735,7 @@ case wxGraphicsMatrix_TransformDistance: { // wxGraphicsMatrix::TransformDistanc
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->TransformDistance(&dx,&dy);
+ rt.ensureFloatCount(3);
rt.addFloat(dx);
rt.addFloat(dy);
rt.addTupleCount(2);
@@ -7348,7 +7397,7 @@ case wxControlWithItems_Append_2: { // wxControlWithItems::Append
int * itemLen = (int *) bp; bp += 4;
wxString item = wxString(bp, wxConvUTF8);
bp += *itemLen+((8-((0+ *itemLen) & 7)) & 7);
- wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
+ wxeErlTerm * clientData = new wxeErlTerm(&Ecmd.bin[0]);
if(!This) throw wxe_badarg(0);
int Result = This->Append(item,clientData);
rt.addInt(Result);
@@ -7410,7 +7459,7 @@ case wxControlWithItems_getClientData: { // wxControlWithItems::GetClientObject
case wxControlWithItems_setClientData: { // wxControlWithItems::SetClientObject
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
- wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
+ wxeErlTerm * clientData = new wxeErlTerm(&Ecmd.bin[0]);
if(!This) throw wxe_badarg(0);
This->SetClientObject(*n,clientData);
break;
@@ -7461,7 +7510,7 @@ case wxControlWithItems_Insert_3: { // wxControlWithItems::Insert
wxString item = wxString(bp, wxConvUTF8);
bp += *itemLen+((8-((0+ *itemLen) & 7)) & 7);
unsigned int * pos = (unsigned int *) bp; bp += 4;
- wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
+ wxeErlTerm * clientData = new wxeErlTerm(&Ecmd.bin[0]);
if(!This) throw wxe_badarg(0);
int Result = This->Insert(item,*pos,clientData);
rt.addInt(Result);
@@ -8508,6 +8557,25 @@ data = (wxObject *) getPtr(bp,memenv); bp += 4;
rt.addRef(getRef((void *)Result,memenv), "wx");
break;
}
+#if wxCHECK_VERSION(3,0,0)
+case wxToolBar_AddStretchableSpace: { // wxToolBar::AddStretchableSpace
+ wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddStretchableSpace();
+ rt.addRef(getRef((void *)Result,memenv), "wx");
+ break;
+}
+#endif
+#if wxCHECK_VERSION(3,0,0)
+case wxToolBar_InsertStretchableSpace: { // wxToolBar::InsertStretchableSpace
+ wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
+ int * pos = (int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxToolBarToolBase * Result = (wxToolBarToolBase*)This->InsertStretchableSpace(*pos);
+ rt.addRef(getRef((void *)Result,memenv), "wx");
+ break;
+}
+#endif
case wxToolBar_DeleteTool: { // wxToolBar::DeleteTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
@@ -8985,7 +9053,7 @@ case wxBitmap_new_3: { // wxBitmap::wxBitmap
}
case wxBitmap_new_4: { // wxBitmap::wxBitmap
int depth=1;
- const char * bits = (const char*) Ecmd.bin[0]->base;
+ const char * bits = (const char*) Ecmd.bin[0].base;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
while( * (int*) bp) { switch (* (int*) bp) {
@@ -9030,7 +9098,7 @@ case wxBitmap_new_2_1: { // wxBitmap::wxBitmap
case wxBitmap_ConvertToImage: { // wxBitmap::ConvertToImage
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->ConvertToImage()); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->ConvertToImage()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9101,7 +9169,7 @@ case wxBitmap_GetSubBitmap: { // wxBitmap::GetSubBitmap
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->GetSubBitmap(rect)); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->GetSubBitmap(rect)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -9283,7 +9351,7 @@ case wxIconBundle_GetIcon_1_1: { // wxIconBundle::GetIcon
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
- const wxIcon * Result = new wxIcon(This->GetIcon(size)); newPtr((void *) Result,3, memenv);;
+ const wxIcon * Result = new EwxIcon(This->GetIcon(size)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
break;
}
@@ -9297,7 +9365,7 @@ case wxIconBundle_GetIcon_1_0: { // wxIconBundle::GetIcon
} break;
}};
if(!This) throw wxe_badarg(0);
- const wxIcon * Result = new wxIcon(This->GetIcon(size)); newPtr((void *) Result,3, memenv);;
+ const wxIcon * Result = new EwxIcon(This->GetIcon(size)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
break;
}
@@ -9325,7 +9393,7 @@ case wxCursor_new_1_1: { // wxCursor::wxCursor
case wxCursor_new_4: { // wxCursor::wxCursor
int hotSpotX=-1;
int hotSpotY=-1;
- const char * bits = (const char*) Ecmd.bin[0]->base;
+ const char * bits = (const char*) Ecmd.bin[0].base;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
while( * (int*) bp) { switch (* (int*) bp) {
@@ -9436,13 +9504,13 @@ case wxImage_new_4: { // wxImage::wxImage
bool static_data=false;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0].base;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
+ if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0].size);memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);};
wxImage * Result = new EwxImage(*width,*height,data,static_data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
@@ -9452,14 +9520,14 @@ case wxImage_new_5: { // wxImage::wxImage
bool static_data=false;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
- unsigned char * alpha = (unsigned char*) Ecmd.bin[1]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0].base;
+ unsigned char * alpha = (unsigned char*) Ecmd.bin[1].base;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) { data = (unsigned char *) malloc(Ecmd.bin[0]->size); alpha = (unsigned char *) malloc(Ecmd.bin[1]->size); memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size); memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);};
+ if(!static_data) { data = (unsigned char *) malloc(Ecmd.bin[0].size); alpha = (unsigned char *) malloc(Ecmd.bin[1].size); memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size); memcpy(alpha,Ecmd.bin[1].base,Ecmd.bin[1].size);};
wxImage * Result = new EwxImage(*width,*height,data,alpha,static_data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
@@ -9506,7 +9574,7 @@ case wxImage_Blur: { // wxImage::Blur
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Blur(*radius)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Blur(*radius)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9514,7 +9582,7 @@ case wxImage_BlurHorizontal: { // wxImage::BlurHorizontal
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->BlurHorizontal(*radius)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->BlurHorizontal(*radius)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9522,7 +9590,7 @@ case wxImage_BlurVertical: { // wxImage::BlurVertical
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->BlurVertical(*radius)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->BlurVertical(*radius)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9561,7 +9629,7 @@ case wxImage_ConvertToGreyscale: { // wxImage::ConvertToGreyscale
} break;
}};
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->ConvertToGreyscale(lr,lg,lb)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->ConvertToGreyscale(lr,lg,lb)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9571,14 +9639,14 @@ case wxImage_ConvertToMono: { // wxImage::ConvertToMono
unsigned int * g = (unsigned int *) bp; bp += 4;
unsigned int * b = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->ConvertToMono(*r,*g,*b)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->ConvertToMono(*r,*g,*b)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
case wxImage_Copy: { // wxImage::Copy
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Copy()); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Copy()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9603,14 +9671,14 @@ case wxImage_Create_4: { // wxImage::Create
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0].base;
bp += 4; /* Align */
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
+ if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0].size);memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(*width,*height,data,static_data);
rt.addBool(Result);
@@ -9621,15 +9689,15 @@ case wxImage_Create_5: { // wxImage::Create
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
- unsigned char * alpha = (unsigned char*) Ecmd.bin[1]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0].base;
+ unsigned char * alpha = (unsigned char*) Ecmd.bin[1].base;
bp += 4; /* Align */
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) { data = (unsigned char *) malloc(Ecmd.bin[0]->size); alpha = (unsigned char *) malloc(Ecmd.bin[1]->size); memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size); memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);};
+ if(!static_data) { data = (unsigned char *) malloc(Ecmd.bin[0].size); alpha = (unsigned char *) malloc(Ecmd.bin[1].size); memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size); memcpy(alpha,Ecmd.bin[1].base,Ecmd.bin[1].size);};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(*width,*height,data,alpha,static_data);
rt.addBool(Result);
@@ -9800,7 +9868,7 @@ case wxImage_GetSubImage: { // wxImage::GetSubImage
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->GetSubImage(rect)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->GetSubImage(rect)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -9945,7 +10013,7 @@ case wxImage_Mirror: { // wxImage::Mirror
} break;
}};
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Mirror(horizontally)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Mirror(horizontally)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -10026,7 +10094,7 @@ case wxImage_Rotate: { // wxImage::Rotate
} break;
}};
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Rotate(*angle,centre_of_rotation,interpolating,offset_after_rotation)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Rotate(*angle,centre_of_rotation,interpolating,offset_after_rotation)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -10048,7 +10116,7 @@ case wxImage_Rotate90: { // wxImage::Rotate90
} break;
}};
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Rotate90(clockwise)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Rotate90(clockwise)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -10098,7 +10166,7 @@ quality = *(wxImageResizeQuality *) bp; bp += 4;;
} break;
}};
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Scale(*width,*height,quality)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Scale(*width,*height,quality)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -10126,7 +10194,7 @@ case wxImage_Size: { // wxImage::Size
} break;
}};
if(!This) throw wxe_badarg(0);
- wxImage * Result = new wxImage(This->Size(size,pos,r,g,b)); newPtr((void *) Result,3, memenv);;
+ wxImage * Result = new EwxImage(This->Size(size,pos,r,g,b)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
break;
}
@@ -10142,14 +10210,14 @@ case wxImage_SetAlpha_3: { // wxImage::SetAlpha
case wxImage_SetAlpha_2: { // wxImage::SetAlpha
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
- unsigned char * alpha = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * alpha = (unsigned char*) Ecmd.bin[0].base;
bp += 4; /* Align */
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) {alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
+ if(!static_data) {alpha = (unsigned char *) malloc(Ecmd.bin[0].size);memcpy(alpha,Ecmd.bin[0].base,Ecmd.bin[0].size);};
if(!This) throw wxe_badarg(0);
This->SetAlpha(alpha,static_data);
break;
@@ -10157,14 +10225,14 @@ case wxImage_SetAlpha_2: { // wxImage::SetAlpha
case wxImage_SetData_2: { // wxImage::SetData
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0].base;
bp += 4; /* Align */
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
+ if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0].size);memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);};
if(!This) throw wxe_badarg(0);
This->SetData(data,static_data);
break;
@@ -10172,7 +10240,7 @@ case wxImage_SetData_2: { // wxImage::SetData
case wxImage_SetData_4: { // wxImage::SetData
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0].base;
int * new_width = (int *) bp; bp += 4;
int * new_height = (int *) bp; bp += 4;
bp += 4; /* Align */
@@ -10181,7 +10249,7 @@ case wxImage_SetData_4: { // wxImage::SetData
static_data = *(bool *) bp; bp += 4;
} break;
}};
- if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
+ if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0].size);memcpy(data,Ecmd.bin[0].base,Ecmd.bin[0].size);};
if(!This) throw wxe_badarg(0);
This->SetData(data,*new_width,*new_height,static_data);
break;
@@ -10586,7 +10654,7 @@ case wxRegion_Contains_1_1: { // wxRegion::Contains
case wxRegion_ConvertToBitmap: { // wxRegion::ConvertToBitmap
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->ConvertToBitmap()); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->ConvertToBitmap()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -13313,28 +13381,28 @@ validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
case wxBitmapButton_GetBitmapDisabled: { // wxBitmapButton::GetBitmapDisabled
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- const wxBitmap * Result = new wxBitmap(This->GetBitmapDisabled()); newPtr((void *) Result,3, memenv);;
+ const wxBitmap * Result = new EwxBitmap(This->GetBitmapDisabled()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
case wxBitmapButton_GetBitmapFocus: { // wxBitmapButton::GetBitmapFocus
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- const wxBitmap * Result = new wxBitmap(This->GetBitmapFocus()); newPtr((void *) Result,3, memenv);;
+ const wxBitmap * Result = new EwxBitmap(This->GetBitmapFocus()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
case wxBitmapButton_GetBitmapLabel: { // wxBitmapButton::GetBitmapLabel
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- const wxBitmap * Result = new wxBitmap(This->GetBitmapLabel()); newPtr((void *) Result,3, memenv);;
+ const wxBitmap * Result = new EwxBitmap(This->GetBitmapLabel()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
case wxBitmapButton_GetBitmapSelected: { // wxBitmapButton::GetBitmapSelected
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- const wxBitmap * Result = new wxBitmap(This->GetBitmapSelected()); newPtr((void *) Result,3, memenv);;
+ const wxBitmap * Result = new EwxBitmap(This->GetBitmapSelected()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -15452,7 +15520,7 @@ case wxListCtrl_GetItemFont: { // wxListCtrl::GetItemFont
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetItemFont(*item)); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetItemFont(*item)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -15998,7 +16066,7 @@ case wxListItem_GetColumn: { // wxListItem::GetColumn
case wxListItem_GetFont: { // wxListItem::GetFont
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -16345,7 +16413,7 @@ case wxImageList_GetBitmap: { // wxImageList::GetBitmap
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->GetBitmap(*index)); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->GetBitmap(*index)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -16353,7 +16421,7 @@ case wxImageList_GetIcon: { // wxImageList::GetIcon
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxIcon * Result = new wxIcon(This->GetIcon(*index)); newPtr((void *) Result,3, memenv);;
+ wxIcon * Result = new EwxIcon(This->GetIcon(*index)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
break;
}
@@ -16464,7 +16532,7 @@ case wxTextAttr_GetBackgroundColour: { // wxTextAttr::GetBackgroundColour
case wxTextAttr_GetFont: { // wxTextAttr::GetFont
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- const wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
+ const wxFont * Result = new EwxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -18546,7 +18614,7 @@ case wxTreeCtrl_AddRoot: { // wxTreeCtrl::AddRoot
selectedImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0].size, Ecmd.bin[0].base);
bp += 4; /* Align */
} break;
}};
@@ -18573,7 +18641,7 @@ case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
selectedImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0].size, Ecmd.bin[0].base);
bp += 4; /* Align */
} break;
}};
@@ -18810,7 +18878,7 @@ case wxTreeCtrl_GetItemFont: { // wxTreeCtrl::GetItemFont
bp += 4; /* Align */
wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetItemFont(item)); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetItemFont(item)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -18975,7 +19043,7 @@ case wxTreeCtrl_InsertItem: { // wxTreeCtrl::InsertItem
selImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0].size, Ecmd.bin[0].base);
bp += 4; /* Align */
} break;
}};
@@ -19054,7 +19122,7 @@ case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
selectedImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0].size, Ecmd.bin[0].base);
bp += 4; /* Align */
} break;
}};
@@ -19138,7 +19206,7 @@ case wxTreeCtrl_SetItemData: { // wxTreeCtrl::SetItemData
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
- wxETreeItemData * data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ wxETreeItemData * data = new wxETreeItemData(Ecmd.bin[0].size, Ecmd.bin[0].base);
if(!This) throw wxe_badarg(0);
This->SetItemData(item,data);
break;
@@ -19837,7 +19905,7 @@ case wxStaticBitmap_Create: { // wxStaticBitmap::Create
case wxStaticBitmap_GetBitmap: { // wxStaticBitmap::GetBitmap
wxStaticBitmap *This = (wxStaticBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->GetBitmap()); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->GetBitmap()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -20593,21 +20661,21 @@ case wxPalette_new_0: { // wxPalette::wxPalette
break;
}
case wxPalette_new_4: { // wxPalette::wxPalette
- const unsigned char * red = (const unsigned char*) Ecmd.bin[0]->base;
- const unsigned char * green = (const unsigned char*) Ecmd.bin[1]->base;
- const unsigned char * blue = (const unsigned char*) Ecmd.bin[2]->base;
- wxPalette * Result = new EwxPalette(Ecmd.bin[0]->size,red,green,blue);
+ const unsigned char * red = (const unsigned char*) Ecmd.bin[0].base;
+ const unsigned char * green = (const unsigned char*) Ecmd.bin[1].base;
+ const unsigned char * blue = (const unsigned char*) Ecmd.bin[2].base;
+ wxPalette * Result = new EwxPalette(Ecmd.bin[0].size,red,green,blue);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPalette");
break;
}
case wxPalette_Create: { // wxPalette::Create
wxPalette *This = (wxPalette *) getPtr(bp,memenv); bp += 4;
- const unsigned char * red = (const unsigned char*) Ecmd.bin[0]->base;
- const unsigned char * green = (const unsigned char*) Ecmd.bin[1]->base;
- const unsigned char * blue = (const unsigned char*) Ecmd.bin[2]->base;
+ const unsigned char * red = (const unsigned char*) Ecmd.bin[0].base;
+ const unsigned char * green = (const unsigned char*) Ecmd.bin[1].base;
+ const unsigned char * blue = (const unsigned char*) Ecmd.bin[2].base;
if(!This) throw wxe_badarg(0);
- bool Result = This->Create(Ecmd.bin[0]->size,red,green,blue);
+ bool Result = This->Create(Ecmd.bin[0].size,red,green,blue);
rt.addBool(Result);
break;
}
@@ -21527,7 +21595,7 @@ validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
case wxFontPickerCtrl_GetSelectedFont: { // wxFontPickerCtrl::GetSelectedFont
wxFontPickerCtrl *This = (wxFontPickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetSelectedFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetSelectedFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -21905,7 +21973,7 @@ case wxFontData_GetColour: { // wxFontData::GetColour
case wxFontData_GetChosenFont: { // wxFontData::GetChosenFont
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetChosenFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetChosenFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -21919,7 +21987,7 @@ case wxFontData_GetEnableEffects: { // wxFontData::GetEnableEffects
case wxFontData_GetInitialFont: { // wxFontData::GetInitialFont
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetInitialFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetInitialFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -23202,7 +23270,7 @@ case wxXmlResource_LoadBitmap: { // wxXmlResource::LoadBitmap
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->LoadBitmap(name)); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->LoadBitmap(name)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -23258,7 +23326,7 @@ case wxXmlResource_LoadIcon: { // wxXmlResource::LoadIcon
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
- wxIcon * Result = new wxIcon(This->LoadIcon(name)); newPtr((void *) Result,3, memenv);;
+ wxIcon * Result = new EwxIcon(This->LoadIcon(name)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
break;
}
@@ -23729,8 +23797,11 @@ case wxAuiManager_DetachPane: { // wxAuiManager::DetachPane
case wxAuiManager_GetAllPanes: { // wxAuiManager::GetAllPanes
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxAuiPaneInfoArray * Result = &This->GetAllPanes();
- rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfoArray");
+ wxAuiPaneInfoArray Result = This->GetAllPanes();
+ for(unsigned int i=0; i < Result.GetCount(); i++) {
+ rt.addRef(getRef((void *) &Result.Item(i), memenv), "wxAuiPaneInfo");
+ }
+ rt.endList(Result.GetCount());
break;
}
case wxAuiManager_GetArtProvider: { // wxAuiManager::GetArtProvider
@@ -23746,6 +23817,7 @@ case wxAuiManager_GetDockSizeConstraint: { // wxAuiManager::GetDockSizeConstrain
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->GetDockSizeConstraint(&width_pct,&height_pct);
+ rt.ensureFloatCount(3);
rt.addFloat(width_pct);
rt.addFloat(height_pct);
rt.addTupleCount(2);
@@ -24588,6 +24660,102 @@ case wxAuiPaneInfo_Window: { // wxAuiPaneInfo::Window
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
break;
}
+case wxAuiPaneInfo_GetWindow: { // wxAuiPaneInfo::GetWindow
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ wxWindow * Result = (wxWindow*)This->GetWindow();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ wxWindow* Result = This->window;
+ rt.addRef(getRef((void *)Result,memenv), "wxWindow");
+ break;
+}
+case wxAuiPaneInfo_GetFrame: { // wxAuiPaneInfo::GetFrame
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ wxFrame * Result = (wxFrame*)This->GetFrame();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ wxFrame* Result = This->frame;
+ rt.addRef(getRef((void *)Result,memenv), "wxFrame");
+ break;
+}
+case wxAuiPaneInfo_GetDirection: { // wxAuiPaneInfo::GetDirection
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ int Result = This->GetDirection();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ int Result = This->dock_direction;
+ rt.addInt(Result);
+ break;
+}
+case wxAuiPaneInfo_GetLayer: { // wxAuiPaneInfo::GetLayer
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ int Result = This->GetLayer();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ int Result = This->dock_layer;
+ rt.addInt(Result);
+ break;
+}
+case wxAuiPaneInfo_GetRow: { // wxAuiPaneInfo::GetRow
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ int Result = This->GetRow();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ int Result = This->dock_row;
+ rt.addInt(Result);
+ break;
+}
+case wxAuiPaneInfo_GetPosition: { // wxAuiPaneInfo::GetPosition
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ int Result = This->GetPosition();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ int Result = This->dock_pos;
+ rt.addInt(Result);
+ break;
+}
+case wxAuiPaneInfo_GetFloatingPosition: { // wxAuiPaneInfo::GetFloatingPosition
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ wxPoint Result = This->GetFloatingPosition();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ wxPoint Result = This->floating_pos;
+ rt.add(Result);
+ break;
+}
+case wxAuiPaneInfo_GetFloatingSize: { // wxAuiPaneInfo::GetFloatingSize
+ wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
+ #if 0
+;
+ if(!This) throw wxe_badarg(0);
+ wxSize Result = This->GetFloatingSize();
+ #endif
+ if(!This) throw wxe_badarg(0);
+ wxSize Result = This->floating_size;
+ rt.add(Result);
+ break;
+}
#endif // wxUSE_AUI
#if wxUSE_AUI
case wxAuiNotebook_new_0: { // wxAuiNotebook::wxAuiNotebook
@@ -24708,7 +24876,7 @@ case wxAuiNotebook_GetPageBitmap: { // wxAuiNotebook::GetPageBitmap
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page_idx = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->GetPageBitmap(*page_idx)); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->GetPageBitmap(*page_idx)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -24833,8 +25001,128 @@ case wxAuiNotebook_SetUniformBitmapSize: { // wxAuiNotebook::SetUniformBitmapSiz
}
#endif // wxUSE_AUI
#if wxUSE_AUI
+case wxAuiTabArt_SetFlags: { // wxAuiTabArt::SetFlags
+ wxAuiTabArt *This = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
+ unsigned int * flags = (unsigned int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetFlags(*flags);
+ break;
+}
+case wxAuiTabArt_SetMeasuringFont: { // wxAuiTabArt::SetMeasuringFont
+ wxAuiTabArt *This = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
+ wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetMeasuringFont(*font);
+ break;
+}
+case wxAuiTabArt_SetNormalFont: { // wxAuiTabArt::SetNormalFont
+ wxAuiTabArt *This = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
+ wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetNormalFont(*font);
+ break;
+}
+case wxAuiTabArt_SetSelectedFont: { // wxAuiTabArt::SetSelectedFont
+ wxAuiTabArt *This = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
+ wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetSelectedFont(*font);
+ break;
+}
+#if wxCHECK_VERSION(3,0,0)
+case wxAuiTabArt_SetColour: { // wxAuiTabArt::SetColour
+ wxAuiTabArt *This = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
+ int * colourR = (int *) bp; bp += 4;
+ int * colourG = (int *) bp; bp += 4;
+ int * colourB = (int *) bp; bp += 4;
+ int * colourA = (int *) bp; bp += 4;
+ wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
+ if(!This) throw wxe_badarg(0);
+ This->SetColour(colour);
+ break;
+}
+#endif
+#if wxCHECK_VERSION(3,0,0)
+case wxAuiTabArt_SetActiveColour: { // wxAuiTabArt::SetActiveColour
+ wxAuiTabArt *This = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
+ int * colourR = (int *) bp; bp += 4;
+ int * colourG = (int *) bp; bp += 4;
+ int * colourB = (int *) bp; bp += 4;
+ int * colourA = (int *) bp; bp += 4;
+ wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
+ if(!This) throw wxe_badarg(0);
+ This->SetActiveColour(colour);
+ break;
+}
+#endif
+#endif // wxUSE_AUI
+#if wxUSE_AUI
+case wxAuiDockArt_GetColour: { // wxAuiDockArt::GetColour
+ wxAuiDockArt *This = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
+ int * id = (int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxColour Result = This->GetColour(*id);
+ rt.add(Result);
+ break;
+}
+case wxAuiDockArt_GetFont: { // wxAuiDockArt::GetFont
+ wxAuiDockArt *This = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
+ int * id = (int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxFont * Result = new EwxFont(This->GetFont(*id)); newPtr((void *) Result,3, memenv);;
+ rt.addRef(getRef((void *)Result,memenv), "wxFont");
+ break;
+}
+case wxAuiDockArt_GetMetric: { // wxAuiDockArt::GetMetric
+ wxAuiDockArt *This = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
+ int * id = (int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ int Result = This->GetMetric(*id);
+ rt.addInt(Result);
+ break;
+}
+case wxAuiDockArt_SetColour: { // wxAuiDockArt::SetColour
+ wxAuiDockArt *This = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
+ int * id = (int *) bp; bp += 4;
+ int * colourR = (int *) bp; bp += 4;
+ int * colourG = (int *) bp; bp += 4;
+ int * colourB = (int *) bp; bp += 4;
+ int * colourA = (int *) bp; bp += 4;
+ wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
+ if(!This) throw wxe_badarg(0);
+ This->SetColour(*id,colour);
+ break;
+}
+case wxAuiDockArt_SetFont: { // wxAuiDockArt::SetFont
+ wxAuiDockArt *This = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
+ int * id = (int *) bp; bp += 4;
+ wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetFont(*id,*font);
+ break;
+}
+case wxAuiDockArt_SetMetric: { // wxAuiDockArt::SetMetric
+ wxAuiDockArt *This = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
+ int * id = (int *) bp; bp += 4;
+ int * new_val = (int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->SetMetric(*id,*new_val);
+ break;
+}
#endif // wxUSE_AUI
#if wxUSE_AUI
+case wxAuiSimpleTabArt_new: { // wxAuiSimpleTabArt::wxAuiSimpleTabArt
+ wxAuiSimpleTabArt * Result = new wxAuiSimpleTabArt();
+ newPtr((void *) Result, 159, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxAuiSimpleTabArt");
+ break;
+}
+case wxAuiSimpleTabArt_destroy: { // wxAuiSimpleTabArt::destroy
+ wxAuiSimpleTabArt *This = (wxAuiSimpleTabArt *) getPtr(bp,memenv); bp += 4;
+ if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
+ delete This;}
+ break;
+}
#endif // wxUSE_AUI
case wxMDIParentFrame_new_0: { // wxMDIParentFrame::wxMDIParentFrame
wxMDIParentFrame * Result = new EwxMDIParentFrame();
@@ -26420,7 +26708,7 @@ case wxColourPickerEvent_GetColour: { // wxColourPickerEvent::GetColour
case wxFontPickerEvent_GetFont: { // wxFontPickerEvent::GetFont
wxFontPickerEvent *This = (wxFontPickerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -30254,7 +30542,7 @@ case wxStyledTextCtrl_GetUseAntiAliasing: { // wxStyledTextCtrl::GetUseAntiAlias
}
case wxStyledTextCtrl_AddTextRaw: { // wxStyledTextCtrl::AddTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0].base;
if(!This) throw wxe_badarg(0);
This->AddTextRaw(text);
break;
@@ -30262,7 +30550,7 @@ case wxStyledTextCtrl_AddTextRaw: { // wxStyledTextCtrl::AddTextRaw
case wxStyledTextCtrl_InsertTextRaw: { // wxStyledTextCtrl::InsertTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0].base;
if(!This) throw wxe_badarg(0);
This->InsertTextRaw(*pos,text);
break;
@@ -30311,7 +30599,7 @@ case wxStyledTextCtrl_GetTextRangeRaw: { // wxStyledTextCtrl::GetTextRangeRaw
}
case wxStyledTextCtrl_SetTextRaw: { // wxStyledTextCtrl::SetTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0].base;
if(!This) throw wxe_badarg(0);
This->SetTextRaw(text);
break;
@@ -30327,7 +30615,7 @@ case wxStyledTextCtrl_GetTextRaw: { // wxStyledTextCtrl::GetTextRaw
}
case wxStyledTextCtrl_AppendTextRaw: { // wxStyledTextCtrl::AppendTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0].base;
if(!This) throw wxe_badarg(0);
This->AppendTextRaw(text);
break;
@@ -30351,7 +30639,7 @@ case wxArtProvider_GetBitmap: { // wxArtProvider::GetBitmap
bp += 4; /* Align */
} break;
}};
- wxBitmap * Result = new wxBitmap(wxArtProvider::GetBitmap(id,client,size)); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(wxArtProvider::GetBitmap(id,client,size)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -30374,7 +30662,7 @@ case wxArtProvider_GetIcon: { // wxArtProvider::GetIcon
bp += 4; /* Align */
} break;
}};
- wxIcon * Result = new wxIcon(wxArtProvider::GetIcon(id,client,size)); newPtr((void *) Result,3, memenv);;
+ wxIcon * Result = new EwxIcon(wxArtProvider::GetIcon(id,client,size)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
break;
}
@@ -30466,7 +30754,7 @@ case wxNotebookEvent_SetSelection: { // wxNotebookEvent::SetSelection
}
case wxFileDataObject_new: { // wxFileDataObject::wxFileDataObject
wxFileDataObject * Result = new wxFileDataObject();
- newPtr((void *) Result, 212, memenv);
+ newPtr((void *) Result, 213, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFileDataObject");
break;
}
@@ -30502,7 +30790,7 @@ case wxTextDataObject_new: { // wxTextDataObject::wxTextDataObject
} break;
}};
wxTextDataObject * Result = new wxTextDataObject(text);
- newPtr((void *) Result, 213, memenv);
+ newPtr((void *) Result, 214, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextDataObject");
break;
}
@@ -30538,7 +30826,7 @@ case wxTextDataObject_destroy: { // wxTextDataObject::destroy
case wxBitmapDataObject_new_1_1: { // wxBitmapDataObject::wxBitmapDataObject
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxBitmapDataObject * Result = new wxBitmapDataObject(*bitmap);
- newPtr((void *) Result, 214, memenv);
+ newPtr((void *) Result, 215, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmapDataObject");
break;
}
@@ -30550,14 +30838,14 @@ bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
}};
wxBitmapDataObject * Result = new wxBitmapDataObject(*bitmap);
- newPtr((void *) Result, 214, memenv);
+ newPtr((void *) Result, 215, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmapDataObject");
break;
}
case wxBitmapDataObject_GetBitmap: { // wxBitmapDataObject::GetBitmap
wxBitmapDataObject *This = (wxBitmapDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
- wxBitmap * Result = new wxBitmap(This->GetBitmap()); newPtr((void *) Result,3, memenv);;
+ wxBitmap * Result = new EwxBitmap(This->GetBitmap()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
break;
}
@@ -31177,7 +31465,7 @@ case wxSystemSettings_GetColour: { // wxSystemSettings::GetColour
}
case wxSystemSettings_GetFont: { // wxSystemSettings::GetFont
wxSystemFont index = *(wxSystemFont *) bp; bp += 4;;
- wxFont * Result = new wxFont(wxSystemSettings::GetFont(index)); newPtr((void *) Result,3, memenv);;
+ wxFont * Result = new EwxFont(wxSystemSettings::GetFont(index)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
break;
}
@@ -31383,7 +31671,7 @@ case wxAuiManagerEvent_CanVeto: { // wxAuiManagerEvent::CanVeto
}
case wxLogNull_new: { // wxLogNull::wxLogNull
wxLogNull * Result = new wxLogNull();
- newPtr((void *) Result, 226, memenv);
+ newPtr((void *) Result, 227, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxLogNull");
break;
}
@@ -31432,7 +31720,7 @@ case wxTaskBarIcon_SetIcon: { // wxTaskBarIcon::SetIcon
}
case wxLocale_new_0: { // wxLocale::wxLocale
wxLocale * Result = new EwxLocale();
- newPtr((void *) Result, 230, memenv);
+ newPtr((void *) Result, 231, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxLocale");
break;
}
@@ -31446,7 +31734,7 @@ case wxLocale_new_2: { // wxLocale::wxLocale
} break;
}};
wxLocale * Result = new EwxLocale(*language,flags);
- newPtr((void *) Result, 230, memenv);
+ newPtr((void *) Result, 231, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxLocale");
break;
}
@@ -31733,6 +32021,56 @@ case wxPopupTransientWindow_Dismiss: { // wxPopupTransientWindow::Dismiss
break;
}
#endif // wxUSE_POPUPWIN
+case wxOverlay_new: { // wxOverlay::wxOverlay
+ wxOverlay * Result = new wxOverlay();
+ newPtr((void *) Result, 236, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxOverlay");
+ break;
+}
+case wxOverlay_destruct: { // wxOverlay::~wxOverlay
+ wxOverlay *This = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
+ delete This;}
+ break;
+}
+case wxOverlay_Reset: { // wxOverlay::Reset
+ wxOverlay *This = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->Reset();
+ break;
+}
+case wxDCOverlay_new_6: { // wxDCOverlay::wxDCOverlay
+ wxOverlay *overlay = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ wxWindowDC *dc = (wxWindowDC *) getPtr(bp,memenv); bp += 4;
+ int * x = (int *) bp; bp += 4;
+ int * y = (int *) bp; bp += 4;
+ int * width = (int *) bp; bp += 4;
+ int * height = (int *) bp; bp += 4;
+ wxDCOverlay * Result = new EwxDCOverlay(*overlay,dc,*x,*y,*width,*height);
+ newPtr((void *) Result, 237, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxDCOverlay");
+ break;
+}
+case wxDCOverlay_new_2: { // wxDCOverlay::wxDCOverlay
+ wxOverlay *overlay = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ wxWindowDC *dc = (wxWindowDC *) getPtr(bp,memenv); bp += 4;
+ wxDCOverlay * Result = new EwxDCOverlay(*overlay,dc);
+ newPtr((void *) Result, 237, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxDCOverlay");
+ break;
+}
+case wxDCOverlay_destruct: { // wxDCOverlay::~wxDCOverlay
+ wxDCOverlay *This = (wxDCOverlay *) getPtr(bp,memenv); bp += 4;
+ if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
+ delete This;}
+ break;
+}
+case wxDCOverlay_Clear: { // wxDCOverlay::Clear
+ wxDCOverlay *This = (wxDCOverlay *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->Clear();
+ break;
+}
default: {
wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_");
error.addInt((int) Ecmd.op);
@@ -31773,11 +32111,14 @@ bool WxeApp::delete_object(void *ptr, wxeRefData *refd) {
case 101: delete (wxListItemAttr *) ptr; break;
case 103: delete (wxTextAttr *) ptr; break;
case 155: delete (wxAuiPaneInfo *) ptr; break;
- case 212: /* delete (wxFileDataObject *) ptr;These objects must be deleted by owner object */ break;
- case 213: /* delete (wxTextDataObject *) ptr;These objects must be deleted by owner object */ break;
- case 214: /* delete (wxBitmapDataObject *) ptr;These objects must be deleted by owner object */ break;
- case 226: delete (wxLogNull *) ptr; break;
- case 230: delete (EwxLocale *) ptr; return false;
+ case 159: /* delete (wxAuiSimpleTabArt *) ptr;These objects must be deleted by owner object */ break;
+ case 213: /* delete (wxFileDataObject *) ptr;These objects must be deleted by owner object */ break;
+ case 214: /* delete (wxTextDataObject *) ptr;These objects must be deleted by owner object */ break;
+ case 215: /* delete (wxBitmapDataObject *) ptr;These objects must be deleted by owner object */ break;
+ case 227: delete (wxLogNull *) ptr; break;
+ case 231: delete (EwxLocale *) ptr; return false;
+ case 236: delete (wxOverlay *) ptr; break;
+ case 237: delete (EwxDCOverlay *) ptr; return false;
default: delete (wxObject *) ptr; return false;
}
return true;
diff --git a/lib/wx/c_src/gen/wxe_init.cpp b/lib/wx/c_src/gen/wxe_init.cpp
index 3a4bced790..1e432e34ce 100644
--- a/lib/wx/c_src/gen/wxe_init.cpp
+++ b/lib/wx/c_src/gen/wxe_init.cpp
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2015. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -56,6 +57,478 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {
rt.addTupleCount(2);
rt.addAtom("wxMOD_CMD"); rt.addInt(wxMOD_CMD);
rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ABKHAZIAN"); rt.addInt(wxLANGUAGE_ABKHAZIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AFAR"); rt.addInt(wxLANGUAGE_AFAR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AFRIKAANS"); rt.addInt(wxLANGUAGE_AFRIKAANS);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ALBANIAN"); rt.addInt(wxLANGUAGE_ALBANIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AMHARIC"); rt.addInt(wxLANGUAGE_AMHARIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC"); rt.addInt(wxLANGUAGE_ARABIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_ALGERIA"); rt.addInt(wxLANGUAGE_ARABIC_ALGERIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_BAHRAIN"); rt.addInt(wxLANGUAGE_ARABIC_BAHRAIN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_EGYPT"); rt.addInt(wxLANGUAGE_ARABIC_EGYPT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_IRAQ"); rt.addInt(wxLANGUAGE_ARABIC_IRAQ);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_JORDAN"); rt.addInt(wxLANGUAGE_ARABIC_JORDAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_KUWAIT"); rt.addInt(wxLANGUAGE_ARABIC_KUWAIT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_LEBANON"); rt.addInt(wxLANGUAGE_ARABIC_LEBANON);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_LIBYA"); rt.addInt(wxLANGUAGE_ARABIC_LIBYA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_MOROCCO"); rt.addInt(wxLANGUAGE_ARABIC_MOROCCO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_OMAN"); rt.addInt(wxLANGUAGE_ARABIC_OMAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_QATAR"); rt.addInt(wxLANGUAGE_ARABIC_QATAR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_SAUDI_ARABIA"); rt.addInt(wxLANGUAGE_ARABIC_SAUDI_ARABIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_SUDAN"); rt.addInt(wxLANGUAGE_ARABIC_SUDAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_SYRIA"); rt.addInt(wxLANGUAGE_ARABIC_SYRIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_TUNISIA"); rt.addInt(wxLANGUAGE_ARABIC_TUNISIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_UAE"); rt.addInt(wxLANGUAGE_ARABIC_UAE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARABIC_YEMEN"); rt.addInt(wxLANGUAGE_ARABIC_YEMEN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ARMENIAN"); rt.addInt(wxLANGUAGE_ARMENIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ASSAMESE"); rt.addInt(wxLANGUAGE_ASSAMESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AYMARA"); rt.addInt(wxLANGUAGE_AYMARA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AZERI"); rt.addInt(wxLANGUAGE_AZERI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AZERI_CYRILLIC"); rt.addInt(wxLANGUAGE_AZERI_CYRILLIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_AZERI_LATIN"); rt.addInt(wxLANGUAGE_AZERI_LATIN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BASHKIR"); rt.addInt(wxLANGUAGE_BASHKIR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BASQUE"); rt.addInt(wxLANGUAGE_BASQUE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BELARUSIAN"); rt.addInt(wxLANGUAGE_BELARUSIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BENGALI"); rt.addInt(wxLANGUAGE_BENGALI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BHUTANI"); rt.addInt(wxLANGUAGE_BHUTANI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BIHARI"); rt.addInt(wxLANGUAGE_BIHARI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BISLAMA"); rt.addInt(wxLANGUAGE_BISLAMA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BRETON"); rt.addInt(wxLANGUAGE_BRETON);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BULGARIAN"); rt.addInt(wxLANGUAGE_BULGARIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_BURMESE"); rt.addInt(wxLANGUAGE_BURMESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CAMBODIAN"); rt.addInt(wxLANGUAGE_CAMBODIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CATALAN"); rt.addInt(wxLANGUAGE_CATALAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE"); rt.addInt(wxLANGUAGE_CHINESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE_HONGKONG"); rt.addInt(wxLANGUAGE_CHINESE_HONGKONG);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE_MACAU"); rt.addInt(wxLANGUAGE_CHINESE_MACAU);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE_SIMPLIFIED"); rt.addInt(wxLANGUAGE_CHINESE_SIMPLIFIED);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE_SINGAPORE"); rt.addInt(wxLANGUAGE_CHINESE_SINGAPORE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE_TAIWAN"); rt.addInt(wxLANGUAGE_CHINESE_TAIWAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CHINESE_TRADITIONAL"); rt.addInt(wxLANGUAGE_CHINESE_TRADITIONAL);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CORSICAN"); rt.addInt(wxLANGUAGE_CORSICAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CROATIAN"); rt.addInt(wxLANGUAGE_CROATIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_CZECH"); rt.addInt(wxLANGUAGE_CZECH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_DANISH"); rt.addInt(wxLANGUAGE_DANISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_DEFAULT"); rt.addInt(wxLANGUAGE_DEFAULT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_DUTCH"); rt.addInt(wxLANGUAGE_DUTCH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_DUTCH_BELGIAN"); rt.addInt(wxLANGUAGE_DUTCH_BELGIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH"); rt.addInt(wxLANGUAGE_ENGLISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_AUSTRALIA"); rt.addInt(wxLANGUAGE_ENGLISH_AUSTRALIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_BELIZE"); rt.addInt(wxLANGUAGE_ENGLISH_BELIZE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_BOTSWANA"); rt.addInt(wxLANGUAGE_ENGLISH_BOTSWANA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_CANADA"); rt.addInt(wxLANGUAGE_ENGLISH_CANADA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_CARIBBEAN"); rt.addInt(wxLANGUAGE_ENGLISH_CARIBBEAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_DENMARK"); rt.addInt(wxLANGUAGE_ENGLISH_DENMARK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_EIRE"); rt.addInt(wxLANGUAGE_ENGLISH_EIRE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_JAMAICA"); rt.addInt(wxLANGUAGE_ENGLISH_JAMAICA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_NEW_ZEALAND"); rt.addInt(wxLANGUAGE_ENGLISH_NEW_ZEALAND);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_PHILIPPINES"); rt.addInt(wxLANGUAGE_ENGLISH_PHILIPPINES);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_SOUTH_AFRICA"); rt.addInt(wxLANGUAGE_ENGLISH_SOUTH_AFRICA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_TRINIDAD"); rt.addInt(wxLANGUAGE_ENGLISH_TRINIDAD);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_UK"); rt.addInt(wxLANGUAGE_ENGLISH_UK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_US"); rt.addInt(wxLANGUAGE_ENGLISH_US);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ENGLISH_ZIMBABWE"); rt.addInt(wxLANGUAGE_ENGLISH_ZIMBABWE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ESPERANTO"); rt.addInt(wxLANGUAGE_ESPERANTO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ESTONIAN"); rt.addInt(wxLANGUAGE_ESTONIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FAEROESE"); rt.addInt(wxLANGUAGE_FAEROESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FARSI"); rt.addInt(wxLANGUAGE_FARSI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FIJI"); rt.addInt(wxLANGUAGE_FIJI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FINNISH"); rt.addInt(wxLANGUAGE_FINNISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRENCH"); rt.addInt(wxLANGUAGE_FRENCH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRENCH_BELGIAN"); rt.addInt(wxLANGUAGE_FRENCH_BELGIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRENCH_CANADIAN"); rt.addInt(wxLANGUAGE_FRENCH_CANADIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRENCH_LUXEMBOURG"); rt.addInt(wxLANGUAGE_FRENCH_LUXEMBOURG);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRENCH_MONACO"); rt.addInt(wxLANGUAGE_FRENCH_MONACO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRENCH_SWISS"); rt.addInt(wxLANGUAGE_FRENCH_SWISS);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_FRISIAN"); rt.addInt(wxLANGUAGE_FRISIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GALICIAN"); rt.addInt(wxLANGUAGE_GALICIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GEORGIAN"); rt.addInt(wxLANGUAGE_GEORGIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GERMAN"); rt.addInt(wxLANGUAGE_GERMAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GERMAN_AUSTRIAN"); rt.addInt(wxLANGUAGE_GERMAN_AUSTRIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GERMAN_BELGIUM"); rt.addInt(wxLANGUAGE_GERMAN_BELGIUM);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GERMAN_LIECHTENSTEIN"); rt.addInt(wxLANGUAGE_GERMAN_LIECHTENSTEIN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GERMAN_LUXEMBOURG"); rt.addInt(wxLANGUAGE_GERMAN_LUXEMBOURG);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GERMAN_SWISS"); rt.addInt(wxLANGUAGE_GERMAN_SWISS);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GREEK"); rt.addInt(wxLANGUAGE_GREEK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GREENLANDIC"); rt.addInt(wxLANGUAGE_GREENLANDIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GUARANI"); rt.addInt(wxLANGUAGE_GUARANI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_GUJARATI"); rt.addInt(wxLANGUAGE_GUJARATI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_HAUSA"); rt.addInt(wxLANGUAGE_HAUSA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_HEBREW"); rt.addInt(wxLANGUAGE_HEBREW);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_HINDI"); rt.addInt(wxLANGUAGE_HINDI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_HUNGARIAN"); rt.addInt(wxLANGUAGE_HUNGARIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ICELANDIC"); rt.addInt(wxLANGUAGE_ICELANDIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_INDONESIAN"); rt.addInt(wxLANGUAGE_INDONESIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_INTERLINGUA"); rt.addInt(wxLANGUAGE_INTERLINGUA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_INTERLINGUE"); rt.addInt(wxLANGUAGE_INTERLINGUE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_INUKTITUT"); rt.addInt(wxLANGUAGE_INUKTITUT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_INUPIAK"); rt.addInt(wxLANGUAGE_INUPIAK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_IRISH"); rt.addInt(wxLANGUAGE_IRISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ITALIAN"); rt.addInt(wxLANGUAGE_ITALIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ITALIAN_SWISS"); rt.addInt(wxLANGUAGE_ITALIAN_SWISS);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_JAPANESE"); rt.addInt(wxLANGUAGE_JAPANESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_JAVANESE"); rt.addInt(wxLANGUAGE_JAVANESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KANNADA"); rt.addInt(wxLANGUAGE_KANNADA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KASHMIRI"); rt.addInt(wxLANGUAGE_KASHMIRI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KASHMIRI_INDIA"); rt.addInt(wxLANGUAGE_KASHMIRI_INDIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KAZAKH"); rt.addInt(wxLANGUAGE_KAZAKH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KERNEWEK"); rt.addInt(wxLANGUAGE_KERNEWEK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KINYARWANDA"); rt.addInt(wxLANGUAGE_KINYARWANDA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KIRGHIZ"); rt.addInt(wxLANGUAGE_KIRGHIZ);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KIRUNDI"); rt.addInt(wxLANGUAGE_KIRUNDI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KONKANI"); rt.addInt(wxLANGUAGE_KONKANI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KOREAN"); rt.addInt(wxLANGUAGE_KOREAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_KURDISH"); rt.addInt(wxLANGUAGE_KURDISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_LAOTHIAN"); rt.addInt(wxLANGUAGE_LAOTHIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_LATIN"); rt.addInt(wxLANGUAGE_LATIN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_LATVIAN"); rt.addInt(wxLANGUAGE_LATVIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_LINGALA"); rt.addInt(wxLANGUAGE_LINGALA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_LITHUANIAN"); rt.addInt(wxLANGUAGE_LITHUANIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MACEDONIAN"); rt.addInt(wxLANGUAGE_MACEDONIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MALAGASY"); rt.addInt(wxLANGUAGE_MALAGASY);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MALAY"); rt.addInt(wxLANGUAGE_MALAY);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MALAYALAM"); rt.addInt(wxLANGUAGE_MALAYALAM);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM"); rt.addInt(wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MALAY_MALAYSIA"); rt.addInt(wxLANGUAGE_MALAY_MALAYSIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MALTESE"); rt.addInt(wxLANGUAGE_MALTESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MANIPURI"); rt.addInt(wxLANGUAGE_MANIPURI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MAORI"); rt.addInt(wxLANGUAGE_MAORI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MARATHI"); rt.addInt(wxLANGUAGE_MARATHI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MOLDAVIAN"); rt.addInt(wxLANGUAGE_MOLDAVIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_MONGOLIAN"); rt.addInt(wxLANGUAGE_MONGOLIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_NAURU"); rt.addInt(wxLANGUAGE_NAURU);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_NEPALI"); rt.addInt(wxLANGUAGE_NEPALI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_NEPALI_INDIA"); rt.addInt(wxLANGUAGE_NEPALI_INDIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_NORWEGIAN_BOKMAL"); rt.addInt(wxLANGUAGE_NORWEGIAN_BOKMAL);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_NORWEGIAN_NYNORSK"); rt.addInt(wxLANGUAGE_NORWEGIAN_NYNORSK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_OCCITAN"); rt.addInt(wxLANGUAGE_OCCITAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ORIYA"); rt.addInt(wxLANGUAGE_ORIYA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_OROMO"); rt.addInt(wxLANGUAGE_OROMO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_PASHTO"); rt.addInt(wxLANGUAGE_PASHTO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_POLISH"); rt.addInt(wxLANGUAGE_POLISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_PORTUGUESE"); rt.addInt(wxLANGUAGE_PORTUGUESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_PORTUGUESE_BRAZILIAN"); rt.addInt(wxLANGUAGE_PORTUGUESE_BRAZILIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_PUNJABI"); rt.addInt(wxLANGUAGE_PUNJABI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_QUECHUA"); rt.addInt(wxLANGUAGE_QUECHUA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_RHAETO_ROMANCE"); rt.addInt(wxLANGUAGE_RHAETO_ROMANCE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ROMANIAN"); rt.addInt(wxLANGUAGE_ROMANIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_RUSSIAN"); rt.addInt(wxLANGUAGE_RUSSIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_RUSSIAN_UKRAINE"); rt.addInt(wxLANGUAGE_RUSSIAN_UKRAINE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SAMI"); rt.addInt(wxLANGUAGE_SAMI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SAMOAN"); rt.addInt(wxLANGUAGE_SAMOAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SANGHO"); rt.addInt(wxLANGUAGE_SANGHO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SANSKRIT"); rt.addInt(wxLANGUAGE_SANSKRIT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SCOTS_GAELIC"); rt.addInt(wxLANGUAGE_SCOTS_GAELIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SERBIAN"); rt.addInt(wxLANGUAGE_SERBIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SERBIAN_CYRILLIC"); rt.addInt(wxLANGUAGE_SERBIAN_CYRILLIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SERBIAN_LATIN"); rt.addInt(wxLANGUAGE_SERBIAN_LATIN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SERBO_CROATIAN"); rt.addInt(wxLANGUAGE_SERBO_CROATIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SESOTHO"); rt.addInt(wxLANGUAGE_SESOTHO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SETSWANA"); rt.addInt(wxLANGUAGE_SETSWANA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SHONA"); rt.addInt(wxLANGUAGE_SHONA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SINDHI"); rt.addInt(wxLANGUAGE_SINDHI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SINHALESE"); rt.addInt(wxLANGUAGE_SINHALESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SISWATI"); rt.addInt(wxLANGUAGE_SISWATI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SLOVAK"); rt.addInt(wxLANGUAGE_SLOVAK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SLOVENIAN"); rt.addInt(wxLANGUAGE_SLOVENIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SOMALI"); rt.addInt(wxLANGUAGE_SOMALI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH"); rt.addInt(wxLANGUAGE_SPANISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_ARGENTINA"); rt.addInt(wxLANGUAGE_SPANISH_ARGENTINA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_BOLIVIA"); rt.addInt(wxLANGUAGE_SPANISH_BOLIVIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_CHILE"); rt.addInt(wxLANGUAGE_SPANISH_CHILE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_COLOMBIA"); rt.addInt(wxLANGUAGE_SPANISH_COLOMBIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_COSTA_RICA"); rt.addInt(wxLANGUAGE_SPANISH_COSTA_RICA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC"); rt.addInt(wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_ECUADOR"); rt.addInt(wxLANGUAGE_SPANISH_ECUADOR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_EL_SALVADOR"); rt.addInt(wxLANGUAGE_SPANISH_EL_SALVADOR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_GUATEMALA"); rt.addInt(wxLANGUAGE_SPANISH_GUATEMALA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_HONDURAS"); rt.addInt(wxLANGUAGE_SPANISH_HONDURAS);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_MEXICAN"); rt.addInt(wxLANGUAGE_SPANISH_MEXICAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_MODERN"); rt.addInt(wxLANGUAGE_SPANISH_MODERN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_NICARAGUA"); rt.addInt(wxLANGUAGE_SPANISH_NICARAGUA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_PANAMA"); rt.addInt(wxLANGUAGE_SPANISH_PANAMA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_PARAGUAY"); rt.addInt(wxLANGUAGE_SPANISH_PARAGUAY);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_PERU"); rt.addInt(wxLANGUAGE_SPANISH_PERU);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_PUERTO_RICO"); rt.addInt(wxLANGUAGE_SPANISH_PUERTO_RICO);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_URUGUAY"); rt.addInt(wxLANGUAGE_SPANISH_URUGUAY);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_US"); rt.addInt(wxLANGUAGE_SPANISH_US);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SPANISH_VENEZUELA"); rt.addInt(wxLANGUAGE_SPANISH_VENEZUELA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SUNDANESE"); rt.addInt(wxLANGUAGE_SUNDANESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SWAHILI"); rt.addInt(wxLANGUAGE_SWAHILI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SWEDISH"); rt.addInt(wxLANGUAGE_SWEDISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_SWEDISH_FINLAND"); rt.addInt(wxLANGUAGE_SWEDISH_FINLAND);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TAGALOG"); rt.addInt(wxLANGUAGE_TAGALOG);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TAJIK"); rt.addInt(wxLANGUAGE_TAJIK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TAMIL"); rt.addInt(wxLANGUAGE_TAMIL);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TATAR"); rt.addInt(wxLANGUAGE_TATAR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TELUGU"); rt.addInt(wxLANGUAGE_TELUGU);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_THAI"); rt.addInt(wxLANGUAGE_THAI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TIBETAN"); rt.addInt(wxLANGUAGE_TIBETAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TIGRINYA"); rt.addInt(wxLANGUAGE_TIGRINYA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TONGA"); rt.addInt(wxLANGUAGE_TONGA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TSONGA"); rt.addInt(wxLANGUAGE_TSONGA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TURKISH"); rt.addInt(wxLANGUAGE_TURKISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TURKMEN"); rt.addInt(wxLANGUAGE_TURKMEN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_TWI"); rt.addInt(wxLANGUAGE_TWI);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_UIGHUR"); rt.addInt(wxLANGUAGE_UIGHUR);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_UKRAINIAN"); rt.addInt(wxLANGUAGE_UKRAINIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_UNKNOWN"); rt.addInt(wxLANGUAGE_UNKNOWN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_URDU"); rt.addInt(wxLANGUAGE_URDU);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_URDU_INDIA"); rt.addInt(wxLANGUAGE_URDU_INDIA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_URDU_PAKISTAN"); rt.addInt(wxLANGUAGE_URDU_PAKISTAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_USER_DEFINED"); rt.addInt(wxLANGUAGE_USER_DEFINED);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_UZBEK"); rt.addInt(wxLANGUAGE_UZBEK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_UZBEK_CYRILLIC"); rt.addInt(wxLANGUAGE_UZBEK_CYRILLIC);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_UZBEK_LATIN"); rt.addInt(wxLANGUAGE_UZBEK_LATIN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_VALENCIAN"); rt.addInt(wxLANGUAGE_VALENCIAN);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_VIETNAMESE"); rt.addInt(wxLANGUAGE_VIETNAMESE);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_VOLAPUK"); rt.addInt(wxLANGUAGE_VOLAPUK);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_WELSH"); rt.addInt(wxLANGUAGE_WELSH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_WOLOF"); rt.addInt(wxLANGUAGE_WOLOF);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_XHOSA"); rt.addInt(wxLANGUAGE_XHOSA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_YIDDISH"); rt.addInt(wxLANGUAGE_YIDDISH);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_YORUBA"); rt.addInt(wxLANGUAGE_YORUBA);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ZHUANG"); rt.addInt(wxLANGUAGE_ZHUANG);
+ rt.addTupleCount(2);
+ rt.addAtom("wxLANGUAGE_ZULU"); rt.addInt(wxLANGUAGE_ZULU);
+ rt.addTupleCount(2);
+ rt.addAtom("wxCURSOR_ARROWWAIT"); rt.addInt(wxCURSOR_ARROWWAIT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxCURSOR_DEFAULT"); rt.addInt(wxCURSOR_DEFAULT);
+ rt.addTupleCount(2);
+ rt.addAtom("wxCURSOR_MAX"); rt.addInt(wxCURSOR_MAX);
+ rt.addTupleCount(2);
rt.addAtom("wxBLACK"); rt.add(*(wxBLACK));
rt.addTupleCount(2);
rt.addAtom("wxBLACK_BRUSH"); rt.addRef(getRef((void *)wxBLACK_BRUSH,memenv),"wxBrush");
@@ -138,7 +611,7 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {
rt.addTupleCount(2);
rt.addAtom("wxWHITE_PEN"); rt.addRef(getRef((void *)wxWHITE_PEN,memenv),"wxPen");
rt.addTupleCount(2);
- rt.endList(57);
+ rt.endList(293);
rt.addTupleCount(2);
rt.send();
}
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index c8ca9bfe5b..0d3b79b7f9 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -1,18 +1,19 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2016. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -63,6 +64,7 @@
#include <wx/html/htmlcell.h>
#include <wx/filename.h>
#include <wx/sysopt.h>
+#include <wx/overlay.h>
#ifndef wxICON_DEFAULT_BITMAP_TYPE
@@ -239,3154 +241,3189 @@
#define wxWindow_UpdateWindowUI 281
#define wxWindow_Validate 282
#define wxWindow_WarpPointer 283
-#define wxTopLevelWindow_GetIcon 284
-#define wxTopLevelWindow_GetIcons 285
-#define wxTopLevelWindow_GetTitle 286
-#define wxTopLevelWindow_IsActive 287
-#define wxTopLevelWindow_Iconize 288
-#define wxTopLevelWindow_IsFullScreen 289
-#define wxTopLevelWindow_IsIconized 290
-#define wxTopLevelWindow_IsMaximized 291
-#define wxTopLevelWindow_Maximize 292
-#define wxTopLevelWindow_RequestUserAttention 293
-#define wxTopLevelWindow_SetIcon 294
-#define wxTopLevelWindow_SetIcons 295
-#define wxTopLevelWindow_CenterOnScreen 296
-#define wxTopLevelWindow_CentreOnScreen 297
-#define wxTopLevelWindow_SetShape 299
-#define wxTopLevelWindow_SetTitle 300
-#define wxTopLevelWindow_ShowFullScreen 301
-#define wxFrame_new_4 303
-#define wxFrame_new_0 304
-#define wxFrame_destruct 306
-#define wxFrame_Create 307
-#define wxFrame_CreateStatusBar 308
-#define wxFrame_CreateToolBar 309
-#define wxFrame_GetClientAreaOrigin 310
-#define wxFrame_GetMenuBar 311
-#define wxFrame_GetStatusBar 312
-#define wxFrame_GetStatusBarPane 313
-#define wxFrame_GetToolBar 314
-#define wxFrame_ProcessCommand 315
-#define wxFrame_SendSizeEvent 316
-#define wxFrame_SetMenuBar 317
-#define wxFrame_SetStatusBar 318
-#define wxFrame_SetStatusBarPane 319
-#define wxFrame_SetStatusText 320
-#define wxFrame_SetStatusWidths 321
-#define wxFrame_SetToolBar 322
-#define wxMiniFrame_new_0 323
-#define wxMiniFrame_new_4 324
-#define wxMiniFrame_Create 325
-#define wxMiniFrame_destroy 326
-#define wxSplashScreen_new_0 327
-#define wxSplashScreen_new_6 328
-#define wxSplashScreen_destruct 329
-#define wxSplashScreen_GetSplashStyle 330
-#define wxSplashScreen_GetTimeout 331
-#define wxPanel_new_0 332
-#define wxPanel_new_6 333
-#define wxPanel_new_2 334
-#define wxPanel_destruct 335
-#define wxPanel_InitDialog 336
-#define wxPanel_SetFocusIgnoringChildren 337
-#define wxScrolledWindow_new_0 338
-#define wxScrolledWindow_new_2 339
-#define wxScrolledWindow_destruct 340
-#define wxScrolledWindow_CalcScrolledPosition_4 341
-#define wxScrolledWindow_CalcScrolledPosition_1 342
-#define wxScrolledWindow_CalcUnscrolledPosition_4 343
-#define wxScrolledWindow_CalcUnscrolledPosition_1 344
-#define wxScrolledWindow_EnableScrolling 345
-#define wxScrolledWindow_GetScrollPixelsPerUnit 346
-#define wxScrolledWindow_GetViewStart 347
-#define wxScrolledWindow_DoPrepareDC 348
-#define wxScrolledWindow_PrepareDC 349
-#define wxScrolledWindow_Scroll 350
-#define wxScrolledWindow_SetScrollbars 351
-#define wxScrolledWindow_SetScrollRate 352
-#define wxScrolledWindow_SetTargetWindow 353
-#define wxSashWindow_new_0 354
-#define wxSashWindow_new_2 355
-#define wxSashWindow_destruct 356
-#define wxSashWindow_GetSashVisible 357
-#define wxSashWindow_GetMaximumSizeX 358
-#define wxSashWindow_GetMaximumSizeY 359
-#define wxSashWindow_GetMinimumSizeX 360
-#define wxSashWindow_GetMinimumSizeY 361
-#define wxSashWindow_SetMaximumSizeX 362
-#define wxSashWindow_SetMaximumSizeY 363
-#define wxSashWindow_SetMinimumSizeX 364
-#define wxSashWindow_SetMinimumSizeY 365
-#define wxSashWindow_SetSashVisible 366
-#define wxSashLayoutWindow_new_0 367
-#define wxSashLayoutWindow_new_2 368
-#define wxSashLayoutWindow_Create 369
-#define wxSashLayoutWindow_GetAlignment 370
-#define wxSashLayoutWindow_GetOrientation 371
-#define wxSashLayoutWindow_SetAlignment 372
-#define wxSashLayoutWindow_SetDefaultSize 373
-#define wxSashLayoutWindow_SetOrientation 374
-#define wxSashLayoutWindow_destroy 375
-#define wxGrid_new_0 376
-#define wxGrid_new_3 377
-#define wxGrid_new_4 378
-#define wxGrid_destruct 379
-#define wxGrid_AppendCols 380
-#define wxGrid_AppendRows 381
-#define wxGrid_AutoSize 382
-#define wxGrid_AutoSizeColumn 383
-#define wxGrid_AutoSizeColumns 384
-#define wxGrid_AutoSizeRow 385
-#define wxGrid_AutoSizeRows 386
-#define wxGrid_BeginBatch 387
-#define wxGrid_BlockToDeviceRect 388
-#define wxGrid_CanDragColSize 389
-#define wxGrid_CanDragRowSize 390
-#define wxGrid_CanDragGridSize 391
-#define wxGrid_CanEnableCellControl 392
-#define wxGrid_CellToRect_2 393
-#define wxGrid_CellToRect_1 394
-#define wxGrid_ClearGrid 395
-#define wxGrid_ClearSelection 396
-#define wxGrid_CreateGrid 397
-#define wxGrid_DeleteCols 398
-#define wxGrid_DeleteRows 399
-#define wxGrid_DisableCellEditControl 400
-#define wxGrid_DisableDragColSize 401
-#define wxGrid_DisableDragGridSize 402
-#define wxGrid_DisableDragRowSize 403
-#define wxGrid_EnableCellEditControl 404
-#define wxGrid_EnableDragColSize 405
-#define wxGrid_EnableDragGridSize 406
-#define wxGrid_EnableDragRowSize 407
-#define wxGrid_EnableEditing 408
-#define wxGrid_EnableGridLines 409
-#define wxGrid_EndBatch 410
-#define wxGrid_Fit 411
-#define wxGrid_ForceRefresh 412
-#define wxGrid_GetBatchCount 413
-#define wxGrid_GetCellAlignment 414
-#define wxGrid_GetCellBackgroundColour 415
-#define wxGrid_GetCellEditor 416
-#define wxGrid_GetCellFont 417
-#define wxGrid_GetCellRenderer 418
-#define wxGrid_GetCellTextColour 419
-#define wxGrid_GetCellValue_2 420
-#define wxGrid_GetCellValue_1 421
-#define wxGrid_GetColLabelAlignment 422
-#define wxGrid_GetColLabelSize 423
-#define wxGrid_GetColLabelValue 424
-#define wxGrid_GetColMinimalAcceptableWidth 425
-#define wxGrid_GetDefaultCellAlignment 426
-#define wxGrid_GetDefaultCellBackgroundColour 427
-#define wxGrid_GetDefaultCellFont 428
-#define wxGrid_GetDefaultCellTextColour 429
-#define wxGrid_GetDefaultColLabelSize 430
-#define wxGrid_GetDefaultColSize 431
-#define wxGrid_GetDefaultEditor 432
-#define wxGrid_GetDefaultEditorForCell_2 433
-#define wxGrid_GetDefaultEditorForCell_1 434
-#define wxGrid_GetDefaultEditorForType 435
-#define wxGrid_GetDefaultRenderer 436
-#define wxGrid_GetDefaultRendererForCell 437
-#define wxGrid_GetDefaultRendererForType 438
-#define wxGrid_GetDefaultRowLabelSize 439
-#define wxGrid_GetDefaultRowSize 440
-#define wxGrid_GetGridCursorCol 441
-#define wxGrid_GetGridCursorRow 442
-#define wxGrid_GetGridLineColour 443
-#define wxGrid_GridLinesEnabled 444
-#define wxGrid_GetLabelBackgroundColour 445
-#define wxGrid_GetLabelFont 446
-#define wxGrid_GetLabelTextColour 447
-#define wxGrid_GetNumberCols 448
-#define wxGrid_GetNumberRows 449
-#define wxGrid_GetOrCreateCellAttr 450
-#define wxGrid_GetRowMinimalAcceptableHeight 451
-#define wxGrid_GetRowLabelAlignment 452
-#define wxGrid_GetRowLabelSize 453
-#define wxGrid_GetRowLabelValue 454
-#define wxGrid_GetRowSize 455
-#define wxGrid_GetScrollLineX 456
-#define wxGrid_GetScrollLineY 457
-#define wxGrid_GetSelectedCells 458
-#define wxGrid_GetSelectedCols 459
-#define wxGrid_GetSelectedRows 460
-#define wxGrid_GetSelectionBackground 461
-#define wxGrid_GetSelectionBlockTopLeft 462
-#define wxGrid_GetSelectionBlockBottomRight 463
-#define wxGrid_GetSelectionForeground 464
-#define wxGrid_GetViewWidth 465
-#define wxGrid_GetGridWindow 466
-#define wxGrid_GetGridRowLabelWindow 467
-#define wxGrid_GetGridColLabelWindow 468
-#define wxGrid_GetGridCornerLabelWindow 469
-#define wxGrid_HideCellEditControl 470
-#define wxGrid_InsertCols 471
-#define wxGrid_InsertRows 472
-#define wxGrid_IsCellEditControlEnabled 473
-#define wxGrid_IsCurrentCellReadOnly 474
-#define wxGrid_IsEditable 475
-#define wxGrid_IsInSelection_2 476
-#define wxGrid_IsInSelection_1 477
-#define wxGrid_IsReadOnly 478
-#define wxGrid_IsSelection 479
-#define wxGrid_IsVisible_3 480
-#define wxGrid_IsVisible_2 481
-#define wxGrid_MakeCellVisible_2 482
-#define wxGrid_MakeCellVisible_1 483
-#define wxGrid_MoveCursorDown 484
-#define wxGrid_MoveCursorLeft 485
-#define wxGrid_MoveCursorRight 486
-#define wxGrid_MoveCursorUp 487
-#define wxGrid_MoveCursorDownBlock 488
-#define wxGrid_MoveCursorLeftBlock 489
-#define wxGrid_MoveCursorRightBlock 490
-#define wxGrid_MoveCursorUpBlock 491
-#define wxGrid_MovePageDown 492
-#define wxGrid_MovePageUp 493
-#define wxGrid_RegisterDataType 494
-#define wxGrid_SaveEditControlValue 495
-#define wxGrid_SelectAll 496
-#define wxGrid_SelectBlock_5 497
-#define wxGrid_SelectBlock_3 498
-#define wxGrid_SelectCol 499
-#define wxGrid_SelectRow 500
-#define wxGrid_SetCellAlignment_4 501
-#define wxGrid_SetCellAlignment_3 502
-#define wxGrid_SetCellAlignment_1 503
-#define wxGrid_SetCellBackgroundColour_3_0 504
-#define wxGrid_SetCellBackgroundColour_1 505
-#define wxGrid_SetCellBackgroundColour_3_1 506
-#define wxGrid_SetCellEditor 507
-#define wxGrid_SetCellFont 508
-#define wxGrid_SetCellRenderer 509
-#define wxGrid_SetCellTextColour_3_0 510
-#define wxGrid_SetCellTextColour_3_1 511
-#define wxGrid_SetCellTextColour_1 512
-#define wxGrid_SetCellValue_3_0 513
-#define wxGrid_SetCellValue_2 514
-#define wxGrid_SetCellValue_3_1 515
-#define wxGrid_SetColAttr 516
-#define wxGrid_SetColFormatBool 517
-#define wxGrid_SetColFormatNumber 518
-#define wxGrid_SetColFormatFloat 519
-#define wxGrid_SetColFormatCustom 520
-#define wxGrid_SetColLabelAlignment 521
-#define wxGrid_SetColLabelSize 522
-#define wxGrid_SetColLabelValue 523
-#define wxGrid_SetColMinimalWidth 524
-#define wxGrid_SetColMinimalAcceptableWidth 525
-#define wxGrid_SetColSize 526
-#define wxGrid_SetDefaultCellAlignment 527
-#define wxGrid_SetDefaultCellBackgroundColour 528
-#define wxGrid_SetDefaultCellFont 529
-#define wxGrid_SetDefaultCellTextColour 530
-#define wxGrid_SetDefaultEditor 531
-#define wxGrid_SetDefaultRenderer 532
-#define wxGrid_SetDefaultColSize 533
-#define wxGrid_SetDefaultRowSize 534
-#define wxGrid_SetGridCursor 535
-#define wxGrid_SetGridLineColour 536
-#define wxGrid_SetLabelBackgroundColour 537
-#define wxGrid_SetLabelFont 538
-#define wxGrid_SetLabelTextColour 539
-#define wxGrid_SetMargins 540
-#define wxGrid_SetReadOnly 541
-#define wxGrid_SetRowAttr 542
-#define wxGrid_SetRowLabelAlignment 543
-#define wxGrid_SetRowLabelSize 544
-#define wxGrid_SetRowLabelValue 545
-#define wxGrid_SetRowMinimalHeight 546
-#define wxGrid_SetRowMinimalAcceptableHeight 547
-#define wxGrid_SetRowSize 548
-#define wxGrid_SetScrollLineX 549
-#define wxGrid_SetScrollLineY 550
-#define wxGrid_SetSelectionBackground 551
-#define wxGrid_SetSelectionForeground 552
-#define wxGrid_SetSelectionMode 553
-#define wxGrid_ShowCellEditControl 554
-#define wxGrid_XToCol 555
-#define wxGrid_XToEdgeOfCol 556
-#define wxGrid_YToEdgeOfRow 557
-#define wxGrid_YToRow 558
-#define wxGridCellRenderer_Draw 559
-#define wxGridCellRenderer_GetBestSize 560
-#define wxGridCellEditor_Create 561
-#define wxGridCellEditor_IsCreated 562
-#define wxGridCellEditor_SetSize 563
-#define wxGridCellEditor_Show 564
-#define wxGridCellEditor_PaintBackground 565
-#define wxGridCellEditor_BeginEdit 566
-#define wxGridCellEditor_EndEdit 567
-#define wxGridCellEditor_Reset 568
-#define wxGridCellEditor_StartingKey 569
-#define wxGridCellEditor_StartingClick 570
-#define wxGridCellEditor_HandleReturn 571
-#define wxGridCellBoolRenderer_new 572
-#define wxGridCellBoolRenderer_destroy 573
-#define wxGridCellBoolEditor_new 574
-#define wxGridCellBoolEditor_IsTrueValue 575
-#define wxGridCellBoolEditor_UseStringValues 576
-#define wxGridCellBoolEditor_destroy 577
-#define wxGridCellFloatRenderer_new 578
-#define wxGridCellFloatRenderer_GetPrecision 579
-#define wxGridCellFloatRenderer_GetWidth 580
-#define wxGridCellFloatRenderer_SetParameters 581
-#define wxGridCellFloatRenderer_SetPrecision 582
-#define wxGridCellFloatRenderer_SetWidth 583
-#define wxGridCellFloatRenderer_destroy 584
-#define wxGridCellFloatEditor_new 585
-#define wxGridCellFloatEditor_SetParameters 586
-#define wxGridCellFloatEditor_destroy 587
-#define wxGridCellStringRenderer_new 588
-#define wxGridCellStringRenderer_destroy 589
-#define wxGridCellTextEditor_new 590
-#define wxGridCellTextEditor_SetParameters 591
-#define wxGridCellTextEditor_destroy 592
-#define wxGridCellChoiceEditor_new 594
-#define wxGridCellChoiceEditor_SetParameters 595
-#define wxGridCellChoiceEditor_destroy 596
-#define wxGridCellNumberRenderer_new 597
-#define wxGridCellNumberRenderer_destroy 598
-#define wxGridCellNumberEditor_new 599
-#define wxGridCellNumberEditor_GetValue 600
-#define wxGridCellNumberEditor_SetParameters 601
-#define wxGridCellNumberEditor_destroy 602
-#define wxGridCellAttr_SetTextColour 603
-#define wxGridCellAttr_SetBackgroundColour 604
-#define wxGridCellAttr_SetFont 605
-#define wxGridCellAttr_SetAlignment 606
-#define wxGridCellAttr_SetReadOnly 607
-#define wxGridCellAttr_SetRenderer 608
-#define wxGridCellAttr_SetEditor 609
-#define wxGridCellAttr_HasTextColour 610
-#define wxGridCellAttr_HasBackgroundColour 611
-#define wxGridCellAttr_HasFont 612
-#define wxGridCellAttr_HasAlignment 613
-#define wxGridCellAttr_HasRenderer 614
-#define wxGridCellAttr_HasEditor 615
-#define wxGridCellAttr_GetTextColour 616
-#define wxGridCellAttr_GetBackgroundColour 617
-#define wxGridCellAttr_GetFont 618
-#define wxGridCellAttr_GetAlignment 619
-#define wxGridCellAttr_GetRenderer 620
-#define wxGridCellAttr_GetEditor 621
-#define wxGridCellAttr_IsReadOnly 622
-#define wxGridCellAttr_SetDefAttr 623
-#define wxDC_Blit 624
-#define wxDC_CalcBoundingBox 625
-#define wxDC_Clear 626
-#define wxDC_ComputeScaleAndOrigin 627
-#define wxDC_CrossHair 628
-#define wxDC_DestroyClippingRegion 629
-#define wxDC_DeviceToLogicalX 630
-#define wxDC_DeviceToLogicalXRel 631
-#define wxDC_DeviceToLogicalY 632
-#define wxDC_DeviceToLogicalYRel 633
-#define wxDC_DrawArc 634
-#define wxDC_DrawBitmap 635
-#define wxDC_DrawCheckMark 636
-#define wxDC_DrawCircle 637
-#define wxDC_DrawEllipse_2 639
-#define wxDC_DrawEllipse_1 640
-#define wxDC_DrawEllipticArc 641
-#define wxDC_DrawIcon 642
-#define wxDC_DrawLabel 643
-#define wxDC_DrawLine 644
-#define wxDC_DrawLines 645
-#define wxDC_DrawPolygon 647
-#define wxDC_DrawPoint 649
-#define wxDC_DrawRectangle_2 651
-#define wxDC_DrawRectangle_1 652
-#define wxDC_DrawRotatedText 653
-#define wxDC_DrawRoundedRectangle_3 655
-#define wxDC_DrawRoundedRectangle_2 656
-#define wxDC_DrawText 657
-#define wxDC_EndDoc 658
-#define wxDC_EndPage 659
-#define wxDC_FloodFill 660
-#define wxDC_GetBackground 661
-#define wxDC_GetBackgroundMode 662
-#define wxDC_GetBrush 663
-#define wxDC_GetCharHeight 664
-#define wxDC_GetCharWidth 665
-#define wxDC_GetClippingBox 666
-#define wxDC_GetFont 668
-#define wxDC_GetLayoutDirection 669
-#define wxDC_GetLogicalFunction 670
-#define wxDC_GetMapMode 671
-#define wxDC_GetMultiLineTextExtent_4 672
-#define wxDC_GetMultiLineTextExtent_1 673
-#define wxDC_GetPartialTextExtents 674
-#define wxDC_GetPen 675
-#define wxDC_GetPixel 676
-#define wxDC_GetPPI 677
-#define wxDC_GetSize 679
-#define wxDC_GetSizeMM 681
-#define wxDC_GetTextBackground 682
-#define wxDC_GetTextExtent_4 683
-#define wxDC_GetTextExtent_1 684
-#define wxDC_GetTextForeground 686
-#define wxDC_GetUserScale 687
-#define wxDC_GradientFillConcentric_3 688
-#define wxDC_GradientFillConcentric_4 689
-#define wxDC_GradientFillLinear 690
-#define wxDC_LogicalToDeviceX 691
-#define wxDC_LogicalToDeviceXRel 692
-#define wxDC_LogicalToDeviceY 693
-#define wxDC_LogicalToDeviceYRel 694
-#define wxDC_MaxX 695
-#define wxDC_MaxY 696
-#define wxDC_MinX 697
-#define wxDC_MinY 698
-#define wxDC_IsOk 699
-#define wxDC_ResetBoundingBox 700
-#define wxDC_SetAxisOrientation 701
-#define wxDC_SetBackground 702
-#define wxDC_SetBackgroundMode 703
-#define wxDC_SetBrush 704
-#define wxDC_SetClippingRegion_2 706
-#define wxDC_SetClippingRegion_1_1 707
-#define wxDC_SetClippingRegion_1_0 708
-#define wxDC_SetDeviceOrigin 709
-#define wxDC_SetFont 710
-#define wxDC_SetLayoutDirection 711
-#define wxDC_SetLogicalFunction 712
-#define wxDC_SetMapMode 713
-#define wxDC_SetPalette 714
-#define wxDC_SetPen 715
-#define wxDC_SetTextBackground 716
-#define wxDC_SetTextForeground 717
-#define wxDC_SetUserScale 718
-#define wxDC_StartDoc 719
-#define wxDC_StartPage 720
-#define wxMirrorDC_new 721
-#define wxMirrorDC_destroy 722
-#define wxScreenDC_new 723
-#define wxScreenDC_destruct 724
-#define wxPostScriptDC_new_0 725
-#define wxPostScriptDC_new_1 726
-#define wxPostScriptDC_destruct 727
-#define wxPostScriptDC_SetResolution 728
-#define wxPostScriptDC_GetResolution 729
-#define wxWindowDC_new_0 730
-#define wxWindowDC_new_1 731
-#define wxWindowDC_destruct 732
-#define wxClientDC_new_0 733
-#define wxClientDC_new_1 734
-#define wxClientDC_destroy 735
-#define wxPaintDC_new_0 736
-#define wxPaintDC_new_1 737
-#define wxPaintDC_destroy 738
-#define wxMemoryDC_new_1_0 740
-#define wxMemoryDC_new_1_1 741
-#define wxMemoryDC_new_0 742
-#define wxMemoryDC_destruct 744
-#define wxMemoryDC_SelectObject 745
-#define wxMemoryDC_SelectObjectAsSource 746
-#define wxBufferedDC_new_0 747
-#define wxBufferedDC_new_2 748
-#define wxBufferedDC_new_3 749
-#define wxBufferedDC_destruct 750
-#define wxBufferedDC_Init_2 751
-#define wxBufferedDC_Init_3 752
-#define wxBufferedPaintDC_new_3 753
-#define wxBufferedPaintDC_new_2 754
-#define wxBufferedPaintDC_destruct 755
-#define wxGraphicsObject_destruct 756
-#define wxGraphicsObject_GetRenderer 757
-#define wxGraphicsObject_IsNull 758
-#define wxGraphicsContext_destruct 759
-#define wxGraphicsContext_Create_1_1 760
-#define wxGraphicsContext_Create_1_0 761
-#define wxGraphicsContext_Create_0 762
-#define wxGraphicsContext_CreatePen 763
-#define wxGraphicsContext_CreateBrush 764
-#define wxGraphicsContext_CreateRadialGradientBrush 765
-#define wxGraphicsContext_CreateLinearGradientBrush 766
-#define wxGraphicsContext_CreateFont 767
-#define wxGraphicsContext_CreateMatrix 768
-#define wxGraphicsContext_CreatePath 769
-#define wxGraphicsContext_Clip_1 770
-#define wxGraphicsContext_Clip_4 771
-#define wxGraphicsContext_ResetClip 772
-#define wxGraphicsContext_DrawBitmap 773
-#define wxGraphicsContext_DrawEllipse 774
-#define wxGraphicsContext_DrawIcon 775
-#define wxGraphicsContext_DrawLines 776
-#define wxGraphicsContext_DrawPath 777
-#define wxGraphicsContext_DrawRectangle 778
-#define wxGraphicsContext_DrawRoundedRectangle 779
-#define wxGraphicsContext_DrawText_3 780
-#define wxGraphicsContext_DrawText_4_0 781
-#define wxGraphicsContext_DrawText_4_1 782
-#define wxGraphicsContext_DrawText_5 783
-#define wxGraphicsContext_FillPath 784
-#define wxGraphicsContext_StrokePath 785
-#define wxGraphicsContext_GetPartialTextExtents 786
-#define wxGraphicsContext_GetTextExtent 787
-#define wxGraphicsContext_Rotate 788
-#define wxGraphicsContext_Scale 789
-#define wxGraphicsContext_Translate 790
-#define wxGraphicsContext_GetTransform 791
-#define wxGraphicsContext_SetTransform 792
-#define wxGraphicsContext_ConcatTransform 793
-#define wxGraphicsContext_SetBrush_1_1 794
-#define wxGraphicsContext_SetBrush_1_0 795
-#define wxGraphicsContext_SetFont_1 796
-#define wxGraphicsContext_SetFont_2 797
-#define wxGraphicsContext_SetPen_1_0 798
-#define wxGraphicsContext_SetPen_1_1 799
-#define wxGraphicsContext_StrokeLine 800
-#define wxGraphicsContext_StrokeLines 801
-#define wxGraphicsMatrix_Concat 803
-#define wxGraphicsMatrix_Get 805
-#define wxGraphicsMatrix_Invert 806
-#define wxGraphicsMatrix_IsEqual 807
-#define wxGraphicsMatrix_IsIdentity 809
-#define wxGraphicsMatrix_Rotate 810
-#define wxGraphicsMatrix_Scale 811
-#define wxGraphicsMatrix_Translate 812
-#define wxGraphicsMatrix_Set 813
-#define wxGraphicsMatrix_TransformPoint 814
-#define wxGraphicsMatrix_TransformDistance 815
-#define wxGraphicsPath_MoveToPoint_2 816
-#define wxGraphicsPath_MoveToPoint_1 817
-#define wxGraphicsPath_AddArc_6 818
-#define wxGraphicsPath_AddArc_5 819
-#define wxGraphicsPath_AddArcToPoint 820
-#define wxGraphicsPath_AddCircle 821
-#define wxGraphicsPath_AddCurveToPoint_6 822
-#define wxGraphicsPath_AddCurveToPoint_3 823
-#define wxGraphicsPath_AddEllipse 824
-#define wxGraphicsPath_AddLineToPoint_2 825
-#define wxGraphicsPath_AddLineToPoint_1 826
-#define wxGraphicsPath_AddPath 827
-#define wxGraphicsPath_AddQuadCurveToPoint 828
-#define wxGraphicsPath_AddRectangle 829
-#define wxGraphicsPath_AddRoundedRectangle 830
-#define wxGraphicsPath_CloseSubpath 831
-#define wxGraphicsPath_Contains_3 832
-#define wxGraphicsPath_Contains_2 833
-#define wxGraphicsPath_GetBox 835
-#define wxGraphicsPath_GetCurrentPoint 837
-#define wxGraphicsPath_Transform 838
-#define wxGraphicsRenderer_GetDefaultRenderer 839
-#define wxGraphicsRenderer_CreateContext_1_1 840
-#define wxGraphicsRenderer_CreateContext_1_0 841
-#define wxGraphicsRenderer_CreatePen 842
-#define wxGraphicsRenderer_CreateBrush 843
-#define wxGraphicsRenderer_CreateLinearGradientBrush 844
-#define wxGraphicsRenderer_CreateRadialGradientBrush 845
-#define wxGraphicsRenderer_CreateFont 846
-#define wxGraphicsRenderer_CreateMatrix 847
-#define wxGraphicsRenderer_CreatePath 848
-#define wxMenuBar_new_1 850
-#define wxMenuBar_new_0 852
-#define wxMenuBar_destruct 854
-#define wxMenuBar_Append 855
-#define wxMenuBar_Check 856
-#define wxMenuBar_Enable_2 857
-#define wxMenuBar_Enable_1 858
-#define wxMenuBar_EnableTop 859
-#define wxMenuBar_FindMenu 860
-#define wxMenuBar_FindMenuItem 861
-#define wxMenuBar_FindItem 862
-#define wxMenuBar_GetHelpString 863
-#define wxMenuBar_GetLabel_1 864
-#define wxMenuBar_GetLabel_0 865
-#define wxMenuBar_GetLabelTop 866
-#define wxMenuBar_GetMenu 867
-#define wxMenuBar_GetMenuCount 868
-#define wxMenuBar_Insert 869
-#define wxMenuBar_IsChecked 870
-#define wxMenuBar_IsEnabled_1 871
-#define wxMenuBar_IsEnabled_0 872
-#define wxMenuBar_Remove 873
-#define wxMenuBar_Replace 874
-#define wxMenuBar_SetHelpString 875
-#define wxMenuBar_SetLabel_2 876
-#define wxMenuBar_SetLabel_1 877
-#define wxMenuBar_SetLabelTop 878
-#define wxControl_GetLabel 879
-#define wxControl_SetLabel 880
-#define wxControlWithItems_Append_1 881
-#define wxControlWithItems_Append_2 882
-#define wxControlWithItems_appendStrings_1 883
-#define wxControlWithItems_Clear 884
-#define wxControlWithItems_Delete 885
-#define wxControlWithItems_FindString 886
-#define wxControlWithItems_getClientData 887
-#define wxControlWithItems_setClientData 888
-#define wxControlWithItems_GetCount 889
-#define wxControlWithItems_GetSelection 890
-#define wxControlWithItems_GetString 891
-#define wxControlWithItems_GetStringSelection 892
-#define wxControlWithItems_Insert_2 893
-#define wxControlWithItems_Insert_3 894
-#define wxControlWithItems_IsEmpty 895
-#define wxControlWithItems_Select 896
-#define wxControlWithItems_SetSelection 897
-#define wxControlWithItems_SetString 898
-#define wxControlWithItems_SetStringSelection 899
-#define wxMenu_new_2 902
-#define wxMenu_new_1 903
-#define wxMenu_destruct 905
-#define wxMenu_Append_3 906
-#define wxMenu_Append_1 907
-#define wxMenu_Append_4_0 908
-#define wxMenu_Append_4_1 909
-#define wxMenu_AppendCheckItem 910
-#define wxMenu_AppendRadioItem 911
-#define wxMenu_AppendSeparator 912
-#define wxMenu_Break 913
-#define wxMenu_Check 914
-#define wxMenu_Delete_1_0 915
-#define wxMenu_Delete_1_1 916
-#define wxMenu_Destroy_1_0 917
-#define wxMenu_Destroy_1_1 918
-#define wxMenu_Enable 919
-#define wxMenu_FindItem_1 920
-#define wxMenu_FindItem_2 921
-#define wxMenu_FindItemByPosition 922
-#define wxMenu_GetHelpString 923
-#define wxMenu_GetLabel 924
-#define wxMenu_GetMenuItemCount 925
-#define wxMenu_GetMenuItems 926
-#define wxMenu_GetTitle 928
-#define wxMenu_Insert_2 929
-#define wxMenu_Insert_3 930
-#define wxMenu_Insert_5_1 931
-#define wxMenu_Insert_5_0 932
-#define wxMenu_InsertCheckItem 933
-#define wxMenu_InsertRadioItem 934
-#define wxMenu_InsertSeparator 935
-#define wxMenu_IsChecked 936
-#define wxMenu_IsEnabled 937
-#define wxMenu_Prepend_1 938
-#define wxMenu_Prepend_2 939
-#define wxMenu_Prepend_4_1 940
-#define wxMenu_Prepend_4_0 941
-#define wxMenu_PrependCheckItem 942
-#define wxMenu_PrependRadioItem 943
-#define wxMenu_PrependSeparator 944
-#define wxMenu_Remove_1_0 945
-#define wxMenu_Remove_1_1 946
-#define wxMenu_SetHelpString 947
-#define wxMenu_SetLabel 948
-#define wxMenu_SetTitle 949
-#define wxMenuItem_new 950
-#define wxMenuItem_destruct 952
-#define wxMenuItem_Check 953
-#define wxMenuItem_Enable 954
-#define wxMenuItem_GetBitmap 955
-#define wxMenuItem_GetHelp 956
-#define wxMenuItem_GetId 957
-#define wxMenuItem_GetKind 958
-#define wxMenuItem_GetLabel 959
-#define wxMenuItem_GetLabelFromText 960
-#define wxMenuItem_GetMenu 961
-#define wxMenuItem_GetText 962
-#define wxMenuItem_GetSubMenu 963
-#define wxMenuItem_IsCheckable 964
-#define wxMenuItem_IsChecked 965
-#define wxMenuItem_IsEnabled 966
-#define wxMenuItem_IsSeparator 967
-#define wxMenuItem_IsSubMenu 968
-#define wxMenuItem_SetBitmap 969
-#define wxMenuItem_SetHelp 970
-#define wxMenuItem_SetMenu 971
-#define wxMenuItem_SetSubMenu 972
-#define wxMenuItem_SetText 973
-#define wxToolBar_AddControl 974
-#define wxToolBar_AddSeparator 975
-#define wxToolBar_AddTool_5 976
-#define wxToolBar_AddTool_4_0 977
-#define wxToolBar_AddTool_1 978
-#define wxToolBar_AddTool_4_1 979
-#define wxToolBar_AddTool_3 980
-#define wxToolBar_AddTool_6 981
-#define wxToolBar_AddCheckTool 982
-#define wxToolBar_AddRadioTool 983
-#define wxToolBar_DeleteTool 984
-#define wxToolBar_DeleteToolByPos 985
-#define wxToolBar_EnableTool 986
-#define wxToolBar_FindById 987
-#define wxToolBar_FindControl 988
-#define wxToolBar_FindToolForPosition 989
-#define wxToolBar_GetToolSize 990
-#define wxToolBar_GetToolBitmapSize 991
-#define wxToolBar_GetMargins 992
-#define wxToolBar_GetToolEnabled 993
-#define wxToolBar_GetToolLongHelp 994
-#define wxToolBar_GetToolPacking 995
-#define wxToolBar_GetToolPos 996
-#define wxToolBar_GetToolSeparation 997
-#define wxToolBar_GetToolShortHelp 998
-#define wxToolBar_GetToolState 999
-#define wxToolBar_InsertControl 1000
-#define wxToolBar_InsertSeparator 1001
-#define wxToolBar_InsertTool_5 1002
-#define wxToolBar_InsertTool_2 1003
-#define wxToolBar_InsertTool_4 1004
-#define wxToolBar_Realize 1005
-#define wxToolBar_RemoveTool 1006
-#define wxToolBar_SetMargins 1007
-#define wxToolBar_SetToolBitmapSize 1008
-#define wxToolBar_SetToolLongHelp 1009
-#define wxToolBar_SetToolPacking 1010
-#define wxToolBar_SetToolShortHelp 1011
-#define wxToolBar_SetToolSeparation 1012
-#define wxToolBar_ToggleTool 1013
-#define wxStatusBar_new_0 1015
-#define wxStatusBar_new_2 1016
-#define wxStatusBar_destruct 1018
-#define wxStatusBar_Create 1019
-#define wxStatusBar_GetFieldRect 1020
-#define wxStatusBar_GetFieldsCount 1021
-#define wxStatusBar_GetStatusText 1022
-#define wxStatusBar_PopStatusText 1023
-#define wxStatusBar_PushStatusText 1024
-#define wxStatusBar_SetFieldsCount 1025
-#define wxStatusBar_SetMinHeight 1026
-#define wxStatusBar_SetStatusText 1027
-#define wxStatusBar_SetStatusWidths 1028
-#define wxStatusBar_SetStatusStyles 1029
-#define wxBitmap_new_0 1030
-#define wxBitmap_new_3 1031
-#define wxBitmap_new_4 1032
-#define wxBitmap_new_2_0 1033
-#define wxBitmap_new_2_1 1034
-#define wxBitmap_destruct 1035
-#define wxBitmap_ConvertToImage 1036
-#define wxBitmap_CopyFromIcon 1037
-#define wxBitmap_Create 1038
-#define wxBitmap_GetDepth 1039
-#define wxBitmap_GetHeight 1040
-#define wxBitmap_GetPalette 1041
-#define wxBitmap_GetMask 1042
-#define wxBitmap_GetWidth 1043
-#define wxBitmap_GetSubBitmap 1044
-#define wxBitmap_LoadFile 1045
-#define wxBitmap_Ok 1046
-#define wxBitmap_SaveFile 1047
-#define wxBitmap_SetDepth 1048
-#define wxBitmap_SetHeight 1049
-#define wxBitmap_SetMask 1050
-#define wxBitmap_SetPalette 1051
-#define wxBitmap_SetWidth 1052
-#define wxIcon_new_0 1053
-#define wxIcon_new_2 1054
-#define wxIcon_new_1 1055
-#define wxIcon_CopyFromBitmap 1056
-#define wxIcon_destroy 1057
-#define wxIconBundle_new_0 1058
-#define wxIconBundle_new_2 1059
-#define wxIconBundle_new_1_0 1060
-#define wxIconBundle_new_1_1 1061
-#define wxIconBundle_destruct 1062
-#define wxIconBundle_AddIcon_2 1063
-#define wxIconBundle_AddIcon_1 1064
-#define wxIconBundle_GetIcon_1_1 1065
-#define wxIconBundle_GetIcon_1_0 1066
-#define wxCursor_new_0 1067
-#define wxCursor_new_1_0 1068
-#define wxCursor_new_1_1 1069
-#define wxCursor_new_4 1070
-#define wxCursor_destruct 1071
-#define wxCursor_Ok 1072
-#define wxMask_new_0 1073
-#define wxMask_new_2_1 1074
-#define wxMask_new_2_0 1075
-#define wxMask_new_1 1076
-#define wxMask_destruct 1077
-#define wxMask_Create_2_1 1078
-#define wxMask_Create_2_0 1079
-#define wxMask_Create_1 1080
-#define wxImage_new_0 1081
-#define wxImage_new_3_0 1082
-#define wxImage_new_4 1083
-#define wxImage_new_5 1084
-#define wxImage_new_2 1085
-#define wxImage_new_3_1 1086
-#define wxImage_Blur 1087
-#define wxImage_BlurHorizontal 1088
-#define wxImage_BlurVertical 1089
-#define wxImage_ConvertAlphaToMask 1090
-#define wxImage_ConvertToGreyscale 1091
-#define wxImage_ConvertToMono 1092
-#define wxImage_Copy 1093
-#define wxImage_Create_3 1094
-#define wxImage_Create_4 1095
-#define wxImage_Create_5 1096
-#define wxImage_Destroy 1097
-#define wxImage_FindFirstUnusedColour 1098
-#define wxImage_GetImageExtWildcard 1099
-#define wxImage_GetAlpha_2 1100
-#define wxImage_GetAlpha_0 1101
-#define wxImage_GetBlue 1102
-#define wxImage_GetData 1103
-#define wxImage_GetGreen 1104
-#define wxImage_GetImageCount 1105
-#define wxImage_GetHeight 1106
-#define wxImage_GetMaskBlue 1107
-#define wxImage_GetMaskGreen 1108
-#define wxImage_GetMaskRed 1109
-#define wxImage_GetOrFindMaskColour 1110
-#define wxImage_GetPalette 1111
-#define wxImage_GetRed 1112
-#define wxImage_GetSubImage 1113
-#define wxImage_GetWidth 1114
-#define wxImage_HasAlpha 1115
-#define wxImage_HasMask 1116
-#define wxImage_GetOption 1117
-#define wxImage_GetOptionInt 1118
-#define wxImage_HasOption 1119
-#define wxImage_InitAlpha 1120
-#define wxImage_InitStandardHandlers 1121
-#define wxImage_IsTransparent 1122
-#define wxImage_LoadFile_2 1123
-#define wxImage_LoadFile_3 1124
-#define wxImage_Ok 1125
-#define wxImage_RemoveHandler 1126
-#define wxImage_Mirror 1127
-#define wxImage_Replace 1128
-#define wxImage_Rescale 1129
-#define wxImage_Resize 1130
-#define wxImage_Rotate 1131
-#define wxImage_RotateHue 1132
-#define wxImage_Rotate90 1133
-#define wxImage_SaveFile_1 1134
-#define wxImage_SaveFile_2_0 1135
-#define wxImage_SaveFile_2_1 1136
-#define wxImage_Scale 1137
-#define wxImage_Size 1138
-#define wxImage_SetAlpha_3 1139
-#define wxImage_SetAlpha_2 1140
-#define wxImage_SetData_2 1141
-#define wxImage_SetData_4 1142
-#define wxImage_SetMask 1143
-#define wxImage_SetMaskColour 1144
-#define wxImage_SetMaskFromImage 1145
-#define wxImage_SetOption_2_1 1146
-#define wxImage_SetOption_2_0 1147
-#define wxImage_SetPalette 1148
-#define wxImage_SetRGB_5 1149
-#define wxImage_SetRGB_4 1150
-#define wxImage_destroy 1151
-#define wxBrush_new_0 1152
-#define wxBrush_new_2 1153
-#define wxBrush_new_1 1154
-#define wxBrush_destruct 1156
-#define wxBrush_GetColour 1157
-#define wxBrush_GetStipple 1158
-#define wxBrush_GetStyle 1159
-#define wxBrush_IsHatch 1160
-#define wxBrush_IsOk 1161
-#define wxBrush_SetColour_1 1162
-#define wxBrush_SetColour_3 1163
-#define wxBrush_SetStipple 1164
-#define wxBrush_SetStyle 1165
-#define wxPen_new_0 1166
-#define wxPen_new_2 1167
-#define wxPen_destruct 1168
-#define wxPen_GetCap 1169
-#define wxPen_GetColour 1170
-#define wxPen_GetJoin 1171
-#define wxPen_GetStyle 1172
-#define wxPen_GetWidth 1173
-#define wxPen_IsOk 1174
-#define wxPen_SetCap 1175
-#define wxPen_SetColour_1 1176
-#define wxPen_SetColour_3 1177
-#define wxPen_SetJoin 1178
-#define wxPen_SetStyle 1179
-#define wxPen_SetWidth 1180
-#define wxRegion_new_0 1181
-#define wxRegion_new_4 1182
-#define wxRegion_new_2 1183
-#define wxRegion_new_1_1 1184
-#define wxRegion_new_1_0 1186
-#define wxRegion_destruct 1188
-#define wxRegion_Clear 1189
-#define wxRegion_Contains_2 1190
-#define wxRegion_Contains_1_0 1191
-#define wxRegion_Contains_4 1192
-#define wxRegion_Contains_1_1 1193
-#define wxRegion_ConvertToBitmap 1194
-#define wxRegion_GetBox 1195
-#define wxRegion_Intersect_4 1196
-#define wxRegion_Intersect_1_1 1197
-#define wxRegion_Intersect_1_0 1198
-#define wxRegion_IsEmpty 1199
-#define wxRegion_Subtract_4 1200
-#define wxRegion_Subtract_1_1 1201
-#define wxRegion_Subtract_1_0 1202
-#define wxRegion_Offset_2 1203
-#define wxRegion_Offset_1 1204
-#define wxRegion_Union_4 1205
-#define wxRegion_Union_1_2 1206
-#define wxRegion_Union_1_1 1207
-#define wxRegion_Union_1_0 1208
-#define wxRegion_Union_3 1209
-#define wxRegion_Xor_4 1210
-#define wxRegion_Xor_1_1 1211
-#define wxRegion_Xor_1_0 1212
-#define wxAcceleratorTable_new_0 1213
-#define wxAcceleratorTable_new_2 1214
-#define wxAcceleratorTable_destruct 1215
-#define wxAcceleratorTable_Ok 1216
-#define wxAcceleratorEntry_new_1_0 1217
-#define wxAcceleratorEntry_new_1_1 1218
-#define wxAcceleratorEntry_GetCommand 1219
-#define wxAcceleratorEntry_GetFlags 1220
-#define wxAcceleratorEntry_GetKeyCode 1221
-#define wxAcceleratorEntry_Set 1222
-#define wxAcceleratorEntry_destroy 1223
-#define wxCaret_new_3 1228
-#define wxCaret_new_2 1229
-#define wxCaret_destruct 1231
-#define wxCaret_Create_3 1232
-#define wxCaret_Create_2 1233
-#define wxCaret_GetBlinkTime 1234
-#define wxCaret_GetPosition 1236
-#define wxCaret_GetSize 1238
-#define wxCaret_GetWindow 1239
-#define wxCaret_Hide 1240
-#define wxCaret_IsOk 1241
-#define wxCaret_IsVisible 1242
-#define wxCaret_Move_2 1243
-#define wxCaret_Move_1 1244
-#define wxCaret_SetBlinkTime 1245
-#define wxCaret_SetSize_2 1246
-#define wxCaret_SetSize_1 1247
-#define wxCaret_Show 1248
-#define wxSizer_Add_2_1 1249
-#define wxSizer_Add_2_0 1250
-#define wxSizer_Add_3 1251
-#define wxSizer_Add_2_3 1252
-#define wxSizer_Add_2_2 1253
-#define wxSizer_AddSpacer 1254
-#define wxSizer_AddStretchSpacer 1255
-#define wxSizer_CalcMin 1256
-#define wxSizer_Clear 1257
-#define wxSizer_Detach_1_2 1258
-#define wxSizer_Detach_1_1 1259
-#define wxSizer_Detach_1_0 1260
-#define wxSizer_Fit 1261
-#define wxSizer_FitInside 1262
-#define wxSizer_GetChildren 1263
-#define wxSizer_GetItem_2_1 1264
-#define wxSizer_GetItem_2_0 1265
-#define wxSizer_GetItem_1 1266
-#define wxSizer_GetSize 1267
-#define wxSizer_GetPosition 1268
-#define wxSizer_GetMinSize 1269
-#define wxSizer_Hide_2_0 1270
-#define wxSizer_Hide_2_1 1271
-#define wxSizer_Hide_1 1272
-#define wxSizer_Insert_3_1 1273
-#define wxSizer_Insert_3_0 1274
-#define wxSizer_Insert_4 1275
-#define wxSizer_Insert_3_3 1276
-#define wxSizer_Insert_3_2 1277
-#define wxSizer_Insert_2 1278
-#define wxSizer_InsertSpacer 1279
-#define wxSizer_InsertStretchSpacer 1280
-#define wxSizer_IsShown_1_2 1281
-#define wxSizer_IsShown_1_1 1282
-#define wxSizer_IsShown_1_0 1283
-#define wxSizer_Layout 1284
-#define wxSizer_Prepend_2_1 1285
-#define wxSizer_Prepend_2_0 1286
-#define wxSizer_Prepend_3 1287
-#define wxSizer_Prepend_2_3 1288
-#define wxSizer_Prepend_2_2 1289
-#define wxSizer_Prepend_1 1290
-#define wxSizer_PrependSpacer 1291
-#define wxSizer_PrependStretchSpacer 1292
-#define wxSizer_RecalcSizes 1293
-#define wxSizer_Remove_1_1 1294
-#define wxSizer_Remove_1_0 1295
-#define wxSizer_Replace_3_1 1296
-#define wxSizer_Replace_3_0 1297
-#define wxSizer_Replace_2 1298
-#define wxSizer_SetDimension 1299
-#define wxSizer_SetMinSize_2 1300
-#define wxSizer_SetMinSize_1 1301
-#define wxSizer_SetItemMinSize_3_2 1302
-#define wxSizer_SetItemMinSize_2_2 1303
-#define wxSizer_SetItemMinSize_3_1 1304
-#define wxSizer_SetItemMinSize_2_1 1305
-#define wxSizer_SetItemMinSize_3_0 1306
-#define wxSizer_SetItemMinSize_2_0 1307
-#define wxSizer_SetSizeHints 1308
-#define wxSizer_SetVirtualSizeHints 1309
-#define wxSizer_Show_2_2 1310
-#define wxSizer_Show_2_1 1311
-#define wxSizer_Show_2_0 1312
-#define wxSizer_Show_1 1313
-#define wxSizerFlags_new 1314
-#define wxSizerFlags_Align 1315
-#define wxSizerFlags_Border_2 1316
-#define wxSizerFlags_Border_1 1317
-#define wxSizerFlags_Center 1318
-#define wxSizerFlags_Centre 1319
-#define wxSizerFlags_Expand 1320
-#define wxSizerFlags_Left 1321
-#define wxSizerFlags_Proportion 1322
-#define wxSizerFlags_Right 1323
-#define wxSizerFlags_destroy 1324
-#define wxSizerItem_new_5_1 1325
-#define wxSizerItem_new_2_1 1326
-#define wxSizerItem_new_5_0 1327
-#define wxSizerItem_new_2_0 1328
-#define wxSizerItem_new_6 1329
-#define wxSizerItem_new_3 1330
-#define wxSizerItem_new_0 1331
-#define wxSizerItem_destruct 1332
-#define wxSizerItem_CalcMin 1333
-#define wxSizerItem_DeleteWindows 1334
-#define wxSizerItem_DetachSizer 1335
-#define wxSizerItem_GetBorder 1336
-#define wxSizerItem_GetFlag 1337
-#define wxSizerItem_GetMinSize 1338
-#define wxSizerItem_GetPosition 1339
-#define wxSizerItem_GetProportion 1340
-#define wxSizerItem_GetRatio 1341
-#define wxSizerItem_GetRect 1342
-#define wxSizerItem_GetSize 1343
-#define wxSizerItem_GetSizer 1344
-#define wxSizerItem_GetSpacer 1345
-#define wxSizerItem_GetUserData 1346
-#define wxSizerItem_GetWindow 1347
-#define wxSizerItem_IsSizer 1348
-#define wxSizerItem_IsShown 1349
-#define wxSizerItem_IsSpacer 1350
-#define wxSizerItem_IsWindow 1351
-#define wxSizerItem_SetBorder 1352
-#define wxSizerItem_SetDimension 1353
-#define wxSizerItem_SetFlag 1354
-#define wxSizerItem_SetInitSize 1355
-#define wxSizerItem_SetMinSize_1 1356
-#define wxSizerItem_SetMinSize_2 1357
-#define wxSizerItem_SetProportion 1358
-#define wxSizerItem_SetRatio_2 1359
-#define wxSizerItem_SetRatio_1_1 1360
-#define wxSizerItem_SetRatio_1_0 1361
-#define wxSizerItem_SetSizer 1362
-#define wxSizerItem_SetSpacer_1 1363
-#define wxSizerItem_SetSpacer_2 1364
-#define wxSizerItem_SetWindow 1365
-#define wxSizerItem_Show 1366
-#define wxBoxSizer_new 1367
-#define wxBoxSizer_GetOrientation 1368
-#define wxBoxSizer_destroy 1369
-#define wxStaticBoxSizer_new_2 1370
-#define wxStaticBoxSizer_new_3 1371
-#define wxStaticBoxSizer_GetStaticBox 1372
-#define wxStaticBoxSizer_destroy 1373
-#define wxGridSizer_new_4 1374
-#define wxGridSizer_new_2 1375
-#define wxGridSizer_GetCols 1376
-#define wxGridSizer_GetHGap 1377
-#define wxGridSizer_GetRows 1378
-#define wxGridSizer_GetVGap 1379
-#define wxGridSizer_SetCols 1380
-#define wxGridSizer_SetHGap 1381
-#define wxGridSizer_SetRows 1382
-#define wxGridSizer_SetVGap 1383
-#define wxGridSizer_destroy 1384
-#define wxFlexGridSizer_new_4 1385
-#define wxFlexGridSizer_new_2 1386
-#define wxFlexGridSizer_AddGrowableCol 1387
-#define wxFlexGridSizer_AddGrowableRow 1388
-#define wxFlexGridSizer_GetFlexibleDirection 1389
-#define wxFlexGridSizer_GetNonFlexibleGrowMode 1390
-#define wxFlexGridSizer_RemoveGrowableCol 1391
-#define wxFlexGridSizer_RemoveGrowableRow 1392
-#define wxFlexGridSizer_SetFlexibleDirection 1393
-#define wxFlexGridSizer_SetNonFlexibleGrowMode 1394
-#define wxFlexGridSizer_destroy 1395
-#define wxGridBagSizer_new 1396
-#define wxGridBagSizer_Add_3_2 1397
-#define wxGridBagSizer_Add_3_1 1398
-#define wxGridBagSizer_Add_4 1399
-#define wxGridBagSizer_Add_1_0 1400
-#define wxGridBagSizer_Add_2_1 1401
-#define wxGridBagSizer_Add_2_0 1402
-#define wxGridBagSizer_Add_3_0 1403
-#define wxGridBagSizer_Add_1_1 1404
-#define wxGridBagSizer_CalcMin 1405
-#define wxGridBagSizer_CheckForIntersection_2 1406
-#define wxGridBagSizer_CheckForIntersection_3 1407
-#define wxGridBagSizer_FindItem_1_1 1408
-#define wxGridBagSizer_FindItem_1_0 1409
-#define wxGridBagSizer_FindItemAtPoint 1410
-#define wxGridBagSizer_FindItemAtPosition 1411
-#define wxGridBagSizer_FindItemWithData 1412
-#define wxGridBagSizer_GetCellSize 1413
-#define wxGridBagSizer_GetEmptyCellSize 1414
-#define wxGridBagSizer_GetItemPosition_1_2 1415
-#define wxGridBagSizer_GetItemPosition_1_1 1416
-#define wxGridBagSizer_GetItemPosition_1_0 1417
-#define wxGridBagSizer_GetItemSpan_1_2 1418
-#define wxGridBagSizer_GetItemSpan_1_1 1419
-#define wxGridBagSizer_GetItemSpan_1_0 1420
-#define wxGridBagSizer_SetEmptyCellSize 1421
-#define wxGridBagSizer_SetItemPosition_2_2 1422
-#define wxGridBagSizer_SetItemPosition_2_1 1423
-#define wxGridBagSizer_SetItemPosition_2_0 1424
-#define wxGridBagSizer_SetItemSpan_2_2 1425
-#define wxGridBagSizer_SetItemSpan_2_1 1426
-#define wxGridBagSizer_SetItemSpan_2_0 1427
-#define wxGridBagSizer_destroy 1428
-#define wxStdDialogButtonSizer_new 1429
-#define wxStdDialogButtonSizer_AddButton 1430
-#define wxStdDialogButtonSizer_Realize 1431
-#define wxStdDialogButtonSizer_SetAffirmativeButton 1432
-#define wxStdDialogButtonSizer_SetCancelButton 1433
-#define wxStdDialogButtonSizer_SetNegativeButton 1434
-#define wxStdDialogButtonSizer_destroy 1435
-#define wxFont_new_0 1436
-#define wxFont_new_1 1437
-#define wxFont_new_5 1438
-#define wxFont_destruct 1440
-#define wxFont_IsFixedWidth 1441
-#define wxFont_GetDefaultEncoding 1442
-#define wxFont_GetFaceName 1443
-#define wxFont_GetFamily 1444
-#define wxFont_GetNativeFontInfoDesc 1445
-#define wxFont_GetNativeFontInfoUserDesc 1446
-#define wxFont_GetPointSize 1447
-#define wxFont_GetStyle 1448
-#define wxFont_GetUnderlined 1449
-#define wxFont_GetWeight 1450
-#define wxFont_Ok 1451
-#define wxFont_SetDefaultEncoding 1452
-#define wxFont_SetFaceName 1453
-#define wxFont_SetFamily 1454
-#define wxFont_SetPointSize 1455
-#define wxFont_SetStyle 1456
-#define wxFont_SetUnderlined 1457
-#define wxFont_SetWeight 1458
-#define wxToolTip_Enable 1459
-#define wxToolTip_SetDelay 1460
-#define wxToolTip_new 1461
-#define wxToolTip_SetTip 1462
-#define wxToolTip_GetTip 1463
-#define wxToolTip_GetWindow 1464
-#define wxToolTip_destroy 1465
-#define wxButton_new_3 1467
-#define wxButton_new_0 1468
-#define wxButton_destruct 1469
-#define wxButton_Create 1470
-#define wxButton_GetDefaultSize 1471
-#define wxButton_SetDefault 1472
-#define wxButton_SetLabel 1473
-#define wxBitmapButton_new_4 1475
-#define wxBitmapButton_new_0 1476
-#define wxBitmapButton_Create 1477
-#define wxBitmapButton_GetBitmapDisabled 1478
-#define wxBitmapButton_GetBitmapFocus 1480
-#define wxBitmapButton_GetBitmapLabel 1482
-#define wxBitmapButton_GetBitmapSelected 1484
-#define wxBitmapButton_SetBitmapDisabled 1486
-#define wxBitmapButton_SetBitmapFocus 1487
-#define wxBitmapButton_SetBitmapLabel 1488
-#define wxBitmapButton_SetBitmapSelected 1489
-#define wxBitmapButton_destroy 1490
-#define wxToggleButton_new_0 1491
-#define wxToggleButton_new_4 1492
-#define wxToggleButton_Create 1493
-#define wxToggleButton_GetValue 1494
-#define wxToggleButton_SetValue 1495
-#define wxToggleButton_destroy 1496
-#define wxCalendarCtrl_new_0 1497
-#define wxCalendarCtrl_new_3 1498
-#define wxCalendarCtrl_Create 1499
-#define wxCalendarCtrl_destruct 1500
-#define wxCalendarCtrl_SetDate 1501
-#define wxCalendarCtrl_GetDate 1502
-#define wxCalendarCtrl_EnableYearChange 1503
-#define wxCalendarCtrl_EnableMonthChange 1504
-#define wxCalendarCtrl_EnableHolidayDisplay 1505
-#define wxCalendarCtrl_SetHeaderColours 1506
-#define wxCalendarCtrl_GetHeaderColourFg 1507
-#define wxCalendarCtrl_GetHeaderColourBg 1508
-#define wxCalendarCtrl_SetHighlightColours 1509
-#define wxCalendarCtrl_GetHighlightColourFg 1510
-#define wxCalendarCtrl_GetHighlightColourBg 1511
-#define wxCalendarCtrl_SetHolidayColours 1512
-#define wxCalendarCtrl_GetHolidayColourFg 1513
-#define wxCalendarCtrl_GetHolidayColourBg 1514
-#define wxCalendarCtrl_GetAttr 1515
-#define wxCalendarCtrl_SetAttr 1516
-#define wxCalendarCtrl_SetHoliday 1517
-#define wxCalendarCtrl_ResetAttr 1518
-#define wxCalendarCtrl_HitTest 1519
-#define wxCalendarDateAttr_new_0 1520
-#define wxCalendarDateAttr_new_2_1 1521
-#define wxCalendarDateAttr_new_2_0 1522
-#define wxCalendarDateAttr_SetTextColour 1523
-#define wxCalendarDateAttr_SetBackgroundColour 1524
-#define wxCalendarDateAttr_SetBorderColour 1525
-#define wxCalendarDateAttr_SetFont 1526
-#define wxCalendarDateAttr_SetBorder 1527
-#define wxCalendarDateAttr_SetHoliday 1528
-#define wxCalendarDateAttr_HasTextColour 1529
-#define wxCalendarDateAttr_HasBackgroundColour 1530
-#define wxCalendarDateAttr_HasBorderColour 1531
-#define wxCalendarDateAttr_HasFont 1532
-#define wxCalendarDateAttr_HasBorder 1533
-#define wxCalendarDateAttr_IsHoliday 1534
-#define wxCalendarDateAttr_GetTextColour 1535
-#define wxCalendarDateAttr_GetBackgroundColour 1536
-#define wxCalendarDateAttr_GetBorderColour 1537
-#define wxCalendarDateAttr_GetFont 1538
-#define wxCalendarDateAttr_GetBorder 1539
-#define wxCalendarDateAttr_destroy 1540
-#define wxCheckBox_new_4 1542
-#define wxCheckBox_new_0 1543
-#define wxCheckBox_Create 1544
-#define wxCheckBox_GetValue 1545
-#define wxCheckBox_Get3StateValue 1546
-#define wxCheckBox_Is3rdStateAllowedForUser 1547
-#define wxCheckBox_Is3State 1548
-#define wxCheckBox_IsChecked 1549
-#define wxCheckBox_SetValue 1550
-#define wxCheckBox_Set3StateValue 1551
-#define wxCheckBox_destroy 1552
-#define wxCheckListBox_new_0 1553
-#define wxCheckListBox_new_3 1555
-#define wxCheckListBox_Check 1556
-#define wxCheckListBox_IsChecked 1557
-#define wxCheckListBox_destroy 1558
-#define wxChoice_new_3 1561
-#define wxChoice_new_0 1562
-#define wxChoice_destruct 1564
-#define wxChoice_Create 1566
-#define wxChoice_Delete 1567
-#define wxChoice_GetColumns 1568
-#define wxChoice_SetColumns 1569
-#define wxComboBox_new_0 1570
-#define wxComboBox_new_3 1572
-#define wxComboBox_destruct 1573
-#define wxComboBox_Create 1575
-#define wxComboBox_CanCopy 1576
-#define wxComboBox_CanCut 1577
-#define wxComboBox_CanPaste 1578
-#define wxComboBox_CanRedo 1579
-#define wxComboBox_CanUndo 1580
-#define wxComboBox_Copy 1581
-#define wxComboBox_Cut 1582
-#define wxComboBox_GetInsertionPoint 1583
-#define wxComboBox_GetLastPosition 1584
-#define wxComboBox_GetValue 1585
-#define wxComboBox_Paste 1586
-#define wxComboBox_Redo 1587
-#define wxComboBox_Replace 1588
-#define wxComboBox_Remove 1589
-#define wxComboBox_SetInsertionPoint 1590
-#define wxComboBox_SetInsertionPointEnd 1591
-#define wxComboBox_SetSelection_1 1592
-#define wxComboBox_SetSelection_2 1593
-#define wxComboBox_SetValue 1594
-#define wxComboBox_Undo 1595
-#define wxGauge_new_0 1596
-#define wxGauge_new_4 1597
-#define wxGauge_Create 1598
-#define wxGauge_GetBezelFace 1599
-#define wxGauge_GetRange 1600
-#define wxGauge_GetShadowWidth 1601
-#define wxGauge_GetValue 1602
-#define wxGauge_IsVertical 1603
-#define wxGauge_SetBezelFace 1604
-#define wxGauge_SetRange 1605
-#define wxGauge_SetShadowWidth 1606
-#define wxGauge_SetValue 1607
-#define wxGauge_Pulse 1608
-#define wxGauge_destroy 1609
-#define wxGenericDirCtrl_new_0 1610
-#define wxGenericDirCtrl_new_2 1611
-#define wxGenericDirCtrl_destruct 1612
-#define wxGenericDirCtrl_Create 1613
-#define wxGenericDirCtrl_Init 1614
-#define wxGenericDirCtrl_CollapseTree 1615
-#define wxGenericDirCtrl_ExpandPath 1616
-#define wxGenericDirCtrl_GetDefaultPath 1617
-#define wxGenericDirCtrl_GetPath 1618
-#define wxGenericDirCtrl_GetFilePath 1619
-#define wxGenericDirCtrl_GetFilter 1620
-#define wxGenericDirCtrl_GetFilterIndex 1621
-#define wxGenericDirCtrl_GetRootId 1622
-#define wxGenericDirCtrl_GetTreeCtrl 1623
-#define wxGenericDirCtrl_ReCreateTree 1624
-#define wxGenericDirCtrl_SetDefaultPath 1625
-#define wxGenericDirCtrl_SetFilter 1626
-#define wxGenericDirCtrl_SetFilterIndex 1627
-#define wxGenericDirCtrl_SetPath 1628
-#define wxStaticBox_new_4 1630
-#define wxStaticBox_new_0 1631
-#define wxStaticBox_Create 1632
-#define wxStaticBox_destroy 1633
-#define wxStaticLine_new_2 1635
-#define wxStaticLine_new_0 1636
-#define wxStaticLine_Create 1637
-#define wxStaticLine_IsVertical 1638
-#define wxStaticLine_GetDefaultSize 1639
-#define wxStaticLine_destroy 1640
-#define wxListBox_new_3 1643
-#define wxListBox_new_0 1644
-#define wxListBox_destruct 1646
-#define wxListBox_Create 1648
-#define wxListBox_Deselect 1649
-#define wxListBox_GetSelections 1650
-#define wxListBox_InsertItems 1651
-#define wxListBox_IsSelected 1652
-#define wxListBox_Set 1653
-#define wxListBox_HitTest 1654
-#define wxListBox_SetFirstItem_1_0 1655
-#define wxListBox_SetFirstItem_1_1 1656
-#define wxListCtrl_new_0 1657
-#define wxListCtrl_new_2 1658
-#define wxListCtrl_Arrange 1659
-#define wxListCtrl_AssignImageList 1660
-#define wxListCtrl_ClearAll 1661
-#define wxListCtrl_Create 1662
-#define wxListCtrl_DeleteAllItems 1663
-#define wxListCtrl_DeleteColumn 1664
-#define wxListCtrl_DeleteItem 1665
-#define wxListCtrl_EditLabel 1666
-#define wxListCtrl_EnsureVisible 1667
-#define wxListCtrl_FindItem_3_0 1668
-#define wxListCtrl_FindItem_3_1 1669
-#define wxListCtrl_GetColumn 1670
-#define wxListCtrl_GetColumnCount 1671
-#define wxListCtrl_GetColumnWidth 1672
-#define wxListCtrl_GetCountPerPage 1673
-#define wxListCtrl_GetEditControl 1674
-#define wxListCtrl_GetImageList 1675
-#define wxListCtrl_GetItem 1676
-#define wxListCtrl_GetItemBackgroundColour 1677
-#define wxListCtrl_GetItemCount 1678
-#define wxListCtrl_GetItemData 1679
-#define wxListCtrl_GetItemFont 1680
-#define wxListCtrl_GetItemPosition 1681
-#define wxListCtrl_GetItemRect 1682
-#define wxListCtrl_GetItemSpacing 1683
-#define wxListCtrl_GetItemState 1684
-#define wxListCtrl_GetItemText 1685
-#define wxListCtrl_GetItemTextColour 1686
-#define wxListCtrl_GetNextItem 1687
-#define wxListCtrl_GetSelectedItemCount 1688
-#define wxListCtrl_GetTextColour 1689
-#define wxListCtrl_GetTopItem 1690
-#define wxListCtrl_GetViewRect 1691
-#define wxListCtrl_HitTest 1692
-#define wxListCtrl_InsertColumn_2 1693
-#define wxListCtrl_InsertColumn_3 1694
-#define wxListCtrl_InsertItem_1 1695
-#define wxListCtrl_InsertItem_2_1 1696
-#define wxListCtrl_InsertItem_2_0 1697
-#define wxListCtrl_InsertItem_3 1698
-#define wxListCtrl_RefreshItem 1699
-#define wxListCtrl_RefreshItems 1700
-#define wxListCtrl_ScrollList 1701
-#define wxListCtrl_SetBackgroundColour 1702
-#define wxListCtrl_SetColumn 1703
-#define wxListCtrl_SetColumnWidth 1704
-#define wxListCtrl_SetImageList 1705
-#define wxListCtrl_SetItem_1 1706
-#define wxListCtrl_SetItem_4 1707
-#define wxListCtrl_SetItemBackgroundColour 1708
-#define wxListCtrl_SetItemCount 1709
-#define wxListCtrl_SetItemData 1710
-#define wxListCtrl_SetItemFont 1711
-#define wxListCtrl_SetItemImage 1712
-#define wxListCtrl_SetItemColumnImage 1713
-#define wxListCtrl_SetItemPosition 1714
-#define wxListCtrl_SetItemState 1715
-#define wxListCtrl_SetItemText 1716
-#define wxListCtrl_SetItemTextColour 1717
-#define wxListCtrl_SetSingleStyle 1718
-#define wxListCtrl_SetTextColour 1719
-#define wxListCtrl_SetWindowStyleFlag 1720
-#define wxListCtrl_SortItems 1721
-#define wxListCtrl_destroy 1722
-#define wxListView_ClearColumnImage 1723
-#define wxListView_Focus 1724
-#define wxListView_GetFirstSelected 1725
-#define wxListView_GetFocusedItem 1726
-#define wxListView_GetNextSelected 1727
-#define wxListView_IsSelected 1728
-#define wxListView_Select 1729
-#define wxListView_SetColumnImage 1730
-#define wxListItem_new_0 1731
-#define wxListItem_new_1 1732
-#define wxListItem_destruct 1733
-#define wxListItem_Clear 1734
-#define wxListItem_GetAlign 1735
-#define wxListItem_GetBackgroundColour 1736
-#define wxListItem_GetColumn 1737
-#define wxListItem_GetFont 1738
-#define wxListItem_GetId 1739
-#define wxListItem_GetImage 1740
-#define wxListItem_GetMask 1741
-#define wxListItem_GetState 1742
-#define wxListItem_GetText 1743
-#define wxListItem_GetTextColour 1744
-#define wxListItem_GetWidth 1745
-#define wxListItem_SetAlign 1746
-#define wxListItem_SetBackgroundColour 1747
-#define wxListItem_SetColumn 1748
-#define wxListItem_SetFont 1749
-#define wxListItem_SetId 1750
-#define wxListItem_SetImage 1751
-#define wxListItem_SetMask 1752
-#define wxListItem_SetState 1753
-#define wxListItem_SetStateMask 1754
-#define wxListItem_SetText 1755
-#define wxListItem_SetTextColour 1756
-#define wxListItem_SetWidth 1757
-#define wxListItemAttr_new_0 1758
-#define wxListItemAttr_new_3 1759
-#define wxListItemAttr_GetBackgroundColour 1760
-#define wxListItemAttr_GetFont 1761
-#define wxListItemAttr_GetTextColour 1762
-#define wxListItemAttr_HasBackgroundColour 1763
-#define wxListItemAttr_HasFont 1764
-#define wxListItemAttr_HasTextColour 1765
-#define wxListItemAttr_SetBackgroundColour 1766
-#define wxListItemAttr_SetFont 1767
-#define wxListItemAttr_SetTextColour 1768
-#define wxListItemAttr_destroy 1769
-#define wxImageList_new_0 1770
-#define wxImageList_new_3 1771
-#define wxImageList_Add_1 1772
-#define wxImageList_Add_2_0 1773
-#define wxImageList_Add_2_1 1774
-#define wxImageList_Create 1775
-#define wxImageList_Draw 1777
-#define wxImageList_GetBitmap 1778
-#define wxImageList_GetIcon 1779
-#define wxImageList_GetImageCount 1780
-#define wxImageList_GetSize 1781
-#define wxImageList_Remove 1782
-#define wxImageList_RemoveAll 1783
-#define wxImageList_Replace_2 1784
-#define wxImageList_Replace_3 1785
-#define wxImageList_destroy 1786
-#define wxTextAttr_new_0 1787
-#define wxTextAttr_new_2 1788
-#define wxTextAttr_GetAlignment 1789
-#define wxTextAttr_GetBackgroundColour 1790
-#define wxTextAttr_GetFont 1791
-#define wxTextAttr_GetLeftIndent 1792
-#define wxTextAttr_GetLeftSubIndent 1793
-#define wxTextAttr_GetRightIndent 1794
-#define wxTextAttr_GetTabs 1795
-#define wxTextAttr_GetTextColour 1796
-#define wxTextAttr_HasBackgroundColour 1797
-#define wxTextAttr_HasFont 1798
-#define wxTextAttr_HasTextColour 1799
-#define wxTextAttr_GetFlags 1800
-#define wxTextAttr_IsDefault 1801
-#define wxTextAttr_SetAlignment 1802
-#define wxTextAttr_SetBackgroundColour 1803
-#define wxTextAttr_SetFlags 1804
-#define wxTextAttr_SetFont 1805
-#define wxTextAttr_SetLeftIndent 1806
-#define wxTextAttr_SetRightIndent 1807
-#define wxTextAttr_SetTabs 1808
-#define wxTextAttr_SetTextColour 1809
-#define wxTextAttr_destroy 1810
-#define wxTextCtrl_new_3 1812
-#define wxTextCtrl_new_0 1813
-#define wxTextCtrl_destruct 1815
-#define wxTextCtrl_AppendText 1816
-#define wxTextCtrl_CanCopy 1817
-#define wxTextCtrl_CanCut 1818
-#define wxTextCtrl_CanPaste 1819
-#define wxTextCtrl_CanRedo 1820
-#define wxTextCtrl_CanUndo 1821
-#define wxTextCtrl_Clear 1822
-#define wxTextCtrl_Copy 1823
-#define wxTextCtrl_Create 1824
-#define wxTextCtrl_Cut 1825
-#define wxTextCtrl_DiscardEdits 1826
-#define wxTextCtrl_ChangeValue 1827
-#define wxTextCtrl_EmulateKeyPress 1828
-#define wxTextCtrl_GetDefaultStyle 1829
-#define wxTextCtrl_GetInsertionPoint 1830
-#define wxTextCtrl_GetLastPosition 1831
-#define wxTextCtrl_GetLineLength 1832
-#define wxTextCtrl_GetLineText 1833
-#define wxTextCtrl_GetNumberOfLines 1834
-#define wxTextCtrl_GetRange 1835
-#define wxTextCtrl_GetSelection 1836
-#define wxTextCtrl_GetStringSelection 1837
-#define wxTextCtrl_GetStyle 1838
-#define wxTextCtrl_GetValue 1839
-#define wxTextCtrl_IsEditable 1840
-#define wxTextCtrl_IsModified 1841
-#define wxTextCtrl_IsMultiLine 1842
-#define wxTextCtrl_IsSingleLine 1843
-#define wxTextCtrl_LoadFile 1844
-#define wxTextCtrl_MarkDirty 1845
-#define wxTextCtrl_Paste 1846
-#define wxTextCtrl_PositionToXY 1847
-#define wxTextCtrl_Redo 1848
-#define wxTextCtrl_Remove 1849
-#define wxTextCtrl_Replace 1850
-#define wxTextCtrl_SaveFile 1851
-#define wxTextCtrl_SetDefaultStyle 1852
-#define wxTextCtrl_SetEditable 1853
-#define wxTextCtrl_SetInsertionPoint 1854
-#define wxTextCtrl_SetInsertionPointEnd 1855
-#define wxTextCtrl_SetMaxLength 1857
-#define wxTextCtrl_SetSelection 1858
-#define wxTextCtrl_SetStyle 1859
-#define wxTextCtrl_SetValue 1860
-#define wxTextCtrl_ShowPosition 1861
-#define wxTextCtrl_Undo 1862
-#define wxTextCtrl_WriteText 1863
-#define wxTextCtrl_XYToPosition 1864
-#define wxNotebook_new_0 1867
-#define wxNotebook_new_3 1868
-#define wxNotebook_destruct 1869
-#define wxNotebook_AddPage 1870
-#define wxNotebook_AdvanceSelection 1871
-#define wxNotebook_AssignImageList 1872
-#define wxNotebook_Create 1873
-#define wxNotebook_DeleteAllPages 1874
-#define wxNotebook_DeletePage 1875
-#define wxNotebook_RemovePage 1876
-#define wxNotebook_GetCurrentPage 1877
-#define wxNotebook_GetImageList 1878
-#define wxNotebook_GetPage 1880
-#define wxNotebook_GetPageCount 1881
-#define wxNotebook_GetPageImage 1882
-#define wxNotebook_GetPageText 1883
-#define wxNotebook_GetRowCount 1884
-#define wxNotebook_GetSelection 1885
-#define wxNotebook_GetThemeBackgroundColour 1886
-#define wxNotebook_HitTest 1888
-#define wxNotebook_InsertPage 1890
-#define wxNotebook_SetImageList 1891
-#define wxNotebook_SetPadding 1892
-#define wxNotebook_SetPageSize 1893
-#define wxNotebook_SetPageImage 1894
-#define wxNotebook_SetPageText 1895
-#define wxNotebook_SetSelection 1896
-#define wxNotebook_ChangeSelection 1897
-#define wxChoicebook_new_0 1898
-#define wxChoicebook_new_3 1899
-#define wxChoicebook_AddPage 1900
-#define wxChoicebook_AdvanceSelection 1901
-#define wxChoicebook_AssignImageList 1902
-#define wxChoicebook_Create 1903
-#define wxChoicebook_DeleteAllPages 1904
-#define wxChoicebook_DeletePage 1905
-#define wxChoicebook_RemovePage 1906
-#define wxChoicebook_GetCurrentPage 1907
-#define wxChoicebook_GetImageList 1908
-#define wxChoicebook_GetPage 1910
-#define wxChoicebook_GetPageCount 1911
-#define wxChoicebook_GetPageImage 1912
-#define wxChoicebook_GetPageText 1913
-#define wxChoicebook_GetSelection 1914
-#define wxChoicebook_HitTest 1915
-#define wxChoicebook_InsertPage 1916
-#define wxChoicebook_SetImageList 1917
-#define wxChoicebook_SetPageSize 1918
-#define wxChoicebook_SetPageImage 1919
-#define wxChoicebook_SetPageText 1920
-#define wxChoicebook_SetSelection 1921
-#define wxChoicebook_ChangeSelection 1922
-#define wxChoicebook_destroy 1923
-#define wxToolbook_new_0 1924
-#define wxToolbook_new_3 1925
-#define wxToolbook_AddPage 1926
-#define wxToolbook_AdvanceSelection 1927
-#define wxToolbook_AssignImageList 1928
-#define wxToolbook_Create 1929
-#define wxToolbook_DeleteAllPages 1930
-#define wxToolbook_DeletePage 1931
-#define wxToolbook_RemovePage 1932
-#define wxToolbook_GetCurrentPage 1933
-#define wxToolbook_GetImageList 1934
-#define wxToolbook_GetPage 1936
-#define wxToolbook_GetPageCount 1937
-#define wxToolbook_GetPageImage 1938
-#define wxToolbook_GetPageText 1939
-#define wxToolbook_GetSelection 1940
-#define wxToolbook_HitTest 1942
-#define wxToolbook_InsertPage 1943
-#define wxToolbook_SetImageList 1944
-#define wxToolbook_SetPageSize 1945
-#define wxToolbook_SetPageImage 1946
-#define wxToolbook_SetPageText 1947
-#define wxToolbook_SetSelection 1948
-#define wxToolbook_ChangeSelection 1949
-#define wxToolbook_destroy 1950
-#define wxListbook_new_0 1951
-#define wxListbook_new_3 1952
-#define wxListbook_AddPage 1953
-#define wxListbook_AdvanceSelection 1954
-#define wxListbook_AssignImageList 1955
-#define wxListbook_Create 1956
-#define wxListbook_DeleteAllPages 1957
-#define wxListbook_DeletePage 1958
-#define wxListbook_RemovePage 1959
-#define wxListbook_GetCurrentPage 1960
-#define wxListbook_GetImageList 1961
-#define wxListbook_GetPage 1963
-#define wxListbook_GetPageCount 1964
-#define wxListbook_GetPageImage 1965
-#define wxListbook_GetPageText 1966
-#define wxListbook_GetSelection 1967
-#define wxListbook_HitTest 1969
-#define wxListbook_InsertPage 1970
-#define wxListbook_SetImageList 1971
-#define wxListbook_SetPageSize 1972
-#define wxListbook_SetPageImage 1973
-#define wxListbook_SetPageText 1974
-#define wxListbook_SetSelection 1975
-#define wxListbook_ChangeSelection 1976
-#define wxListbook_destroy 1977
-#define wxTreebook_new_0 1978
-#define wxTreebook_new_3 1979
-#define wxTreebook_AddPage 1980
-#define wxTreebook_AdvanceSelection 1981
-#define wxTreebook_AssignImageList 1982
-#define wxTreebook_Create 1983
-#define wxTreebook_DeleteAllPages 1984
-#define wxTreebook_DeletePage 1985
-#define wxTreebook_RemovePage 1986
-#define wxTreebook_GetCurrentPage 1987
-#define wxTreebook_GetImageList 1988
-#define wxTreebook_GetPage 1990
-#define wxTreebook_GetPageCount 1991
-#define wxTreebook_GetPageImage 1992
-#define wxTreebook_GetPageText 1993
-#define wxTreebook_GetSelection 1994
-#define wxTreebook_ExpandNode 1995
-#define wxTreebook_IsNodeExpanded 1996
-#define wxTreebook_HitTest 1998
-#define wxTreebook_InsertPage 1999
-#define wxTreebook_InsertSubPage 2000
-#define wxTreebook_SetImageList 2001
-#define wxTreebook_SetPageSize 2002
-#define wxTreebook_SetPageImage 2003
-#define wxTreebook_SetPageText 2004
-#define wxTreebook_SetSelection 2005
-#define wxTreebook_ChangeSelection 2006
-#define wxTreebook_destroy 2007
-#define wxTreeCtrl_new_2 2010
-#define wxTreeCtrl_new_0 2011
-#define wxTreeCtrl_destruct 2013
-#define wxTreeCtrl_AddRoot 2014
-#define wxTreeCtrl_AppendItem 2015
-#define wxTreeCtrl_AssignImageList 2016
-#define wxTreeCtrl_AssignStateImageList 2017
-#define wxTreeCtrl_Collapse 2018
-#define wxTreeCtrl_CollapseAndReset 2019
-#define wxTreeCtrl_Create 2020
-#define wxTreeCtrl_Delete 2021
-#define wxTreeCtrl_DeleteAllItems 2022
-#define wxTreeCtrl_DeleteChildren 2023
-#define wxTreeCtrl_EditLabel 2024
-#define wxTreeCtrl_EnsureVisible 2025
-#define wxTreeCtrl_Expand 2026
-#define wxTreeCtrl_GetBoundingRect 2027
-#define wxTreeCtrl_GetChildrenCount 2029
-#define wxTreeCtrl_GetCount 2030
-#define wxTreeCtrl_GetEditControl 2031
-#define wxTreeCtrl_GetFirstChild 2032
-#define wxTreeCtrl_GetNextChild 2033
-#define wxTreeCtrl_GetFirstVisibleItem 2034
-#define wxTreeCtrl_GetImageList 2035
-#define wxTreeCtrl_GetIndent 2036
-#define wxTreeCtrl_GetItemBackgroundColour 2037
-#define wxTreeCtrl_GetItemData 2038
-#define wxTreeCtrl_GetItemFont 2039
-#define wxTreeCtrl_GetItemImage_1 2040
-#define wxTreeCtrl_GetItemImage_2 2041
-#define wxTreeCtrl_GetItemText 2042
-#define wxTreeCtrl_GetItemTextColour 2043
-#define wxTreeCtrl_GetLastChild 2044
-#define wxTreeCtrl_GetNextSibling 2045
-#define wxTreeCtrl_GetNextVisible 2046
-#define wxTreeCtrl_GetItemParent 2047
-#define wxTreeCtrl_GetPrevSibling 2048
-#define wxTreeCtrl_GetPrevVisible 2049
-#define wxTreeCtrl_GetRootItem 2050
-#define wxTreeCtrl_GetSelection 2051
-#define wxTreeCtrl_GetSelections 2052
-#define wxTreeCtrl_GetStateImageList 2053
-#define wxTreeCtrl_HitTest 2054
-#define wxTreeCtrl_InsertItem 2056
-#define wxTreeCtrl_IsBold 2057
-#define wxTreeCtrl_IsExpanded 2058
-#define wxTreeCtrl_IsSelected 2059
-#define wxTreeCtrl_IsVisible 2060
-#define wxTreeCtrl_ItemHasChildren 2061
-#define wxTreeCtrl_IsTreeItemIdOk 2062
-#define wxTreeCtrl_PrependItem 2063
-#define wxTreeCtrl_ScrollTo 2064
-#define wxTreeCtrl_SelectItem_1 2065
-#define wxTreeCtrl_SelectItem_2 2066
-#define wxTreeCtrl_SetIndent 2067
-#define wxTreeCtrl_SetImageList 2068
-#define wxTreeCtrl_SetItemBackgroundColour 2069
-#define wxTreeCtrl_SetItemBold 2070
-#define wxTreeCtrl_SetItemData 2071
-#define wxTreeCtrl_SetItemDropHighlight 2072
-#define wxTreeCtrl_SetItemFont 2073
-#define wxTreeCtrl_SetItemHasChildren 2074
-#define wxTreeCtrl_SetItemImage_2 2075
-#define wxTreeCtrl_SetItemImage_3 2076
-#define wxTreeCtrl_SetItemText 2077
-#define wxTreeCtrl_SetItemTextColour 2078
-#define wxTreeCtrl_SetStateImageList 2079
-#define wxTreeCtrl_SetWindowStyle 2080
-#define wxTreeCtrl_SortChildren 2081
-#define wxTreeCtrl_Toggle 2082
-#define wxTreeCtrl_ToggleItemSelection 2083
-#define wxTreeCtrl_Unselect 2084
-#define wxTreeCtrl_UnselectAll 2085
-#define wxTreeCtrl_UnselectItem 2086
-#define wxScrollBar_new_0 2087
-#define wxScrollBar_new_3 2088
-#define wxScrollBar_destruct 2089
-#define wxScrollBar_Create 2090
-#define wxScrollBar_GetRange 2091
-#define wxScrollBar_GetPageSize 2092
-#define wxScrollBar_GetThumbPosition 2093
-#define wxScrollBar_GetThumbSize 2094
-#define wxScrollBar_SetThumbPosition 2095
-#define wxScrollBar_SetScrollbar 2096
-#define wxSpinButton_new_2 2098
-#define wxSpinButton_new_0 2099
-#define wxSpinButton_Create 2100
-#define wxSpinButton_GetMax 2101
-#define wxSpinButton_GetMin 2102
-#define wxSpinButton_GetValue 2103
-#define wxSpinButton_SetRange 2104
-#define wxSpinButton_SetValue 2105
-#define wxSpinButton_destroy 2106
-#define wxSpinCtrl_new_0 2107
-#define wxSpinCtrl_new_2 2108
-#define wxSpinCtrl_Create 2110
-#define wxSpinCtrl_SetValue_1_1 2113
-#define wxSpinCtrl_SetValue_1_0 2114
-#define wxSpinCtrl_GetValue 2116
-#define wxSpinCtrl_SetRange 2118
-#define wxSpinCtrl_SetSelection 2119
-#define wxSpinCtrl_GetMin 2121
-#define wxSpinCtrl_GetMax 2123
-#define wxSpinCtrl_destroy 2124
-#define wxStaticText_new_0 2125
-#define wxStaticText_new_4 2126
-#define wxStaticText_Create 2127
-#define wxStaticText_GetLabel 2128
-#define wxStaticText_SetLabel 2129
-#define wxStaticText_Wrap 2130
-#define wxStaticText_destroy 2131
-#define wxStaticBitmap_new_0 2132
-#define wxStaticBitmap_new_4 2133
-#define wxStaticBitmap_Create 2134
-#define wxStaticBitmap_GetBitmap 2135
-#define wxStaticBitmap_SetBitmap 2136
-#define wxStaticBitmap_destroy 2137
-#define wxRadioBox_new 2138
-#define wxRadioBox_destruct 2140
-#define wxRadioBox_Create 2141
-#define wxRadioBox_Enable_2 2142
-#define wxRadioBox_Enable_1 2143
-#define wxRadioBox_GetSelection 2144
-#define wxRadioBox_GetString 2145
-#define wxRadioBox_SetSelection 2146
-#define wxRadioBox_Show_2 2147
-#define wxRadioBox_Show_1 2148
-#define wxRadioBox_GetColumnCount 2149
-#define wxRadioBox_GetItemHelpText 2150
-#define wxRadioBox_GetItemToolTip 2151
-#define wxRadioBox_GetItemFromPoint 2153
-#define wxRadioBox_GetRowCount 2154
-#define wxRadioBox_IsItemEnabled 2155
-#define wxRadioBox_IsItemShown 2156
-#define wxRadioBox_SetItemHelpText 2157
-#define wxRadioBox_SetItemToolTip 2158
-#define wxRadioButton_new_0 2159
-#define wxRadioButton_new_4 2160
-#define wxRadioButton_Create 2161
-#define wxRadioButton_GetValue 2162
-#define wxRadioButton_SetValue 2163
-#define wxRadioButton_destroy 2164
-#define wxSlider_new_6 2166
-#define wxSlider_new_0 2167
-#define wxSlider_Create 2168
-#define wxSlider_GetLineSize 2169
-#define wxSlider_GetMax 2170
-#define wxSlider_GetMin 2171
-#define wxSlider_GetPageSize 2172
-#define wxSlider_GetThumbLength 2173
-#define wxSlider_GetValue 2174
-#define wxSlider_SetLineSize 2175
-#define wxSlider_SetPageSize 2176
-#define wxSlider_SetRange 2177
-#define wxSlider_SetThumbLength 2178
-#define wxSlider_SetValue 2179
-#define wxSlider_destroy 2180
-#define wxDialog_new_4 2182
-#define wxDialog_new_0 2183
-#define wxDialog_destruct 2185
-#define wxDialog_Create 2186
-#define wxDialog_CreateButtonSizer 2187
-#define wxDialog_CreateStdDialogButtonSizer 2188
-#define wxDialog_EndModal 2189
-#define wxDialog_GetAffirmativeId 2190
-#define wxDialog_GetReturnCode 2191
-#define wxDialog_IsModal 2192
-#define wxDialog_SetAffirmativeId 2193
-#define wxDialog_SetReturnCode 2194
-#define wxDialog_Show 2195
-#define wxDialog_ShowModal 2196
-#define wxColourDialog_new_0 2197
-#define wxColourDialog_new_2 2198
-#define wxColourDialog_destruct 2199
-#define wxColourDialog_Create 2200
-#define wxColourDialog_GetColourData 2201
-#define wxColourData_new_0 2202
-#define wxColourData_new_1 2203
-#define wxColourData_destruct 2204
-#define wxColourData_GetChooseFull 2205
-#define wxColourData_GetColour 2206
-#define wxColourData_GetCustomColour 2208
-#define wxColourData_SetChooseFull 2209
-#define wxColourData_SetColour 2210
-#define wxColourData_SetCustomColour 2211
-#define wxPalette_new_0 2212
-#define wxPalette_new_4 2213
-#define wxPalette_destruct 2215
-#define wxPalette_Create 2216
-#define wxPalette_GetColoursCount 2217
-#define wxPalette_GetPixel 2218
-#define wxPalette_GetRGB 2219
-#define wxPalette_IsOk 2220
-#define wxDirDialog_new 2224
-#define wxDirDialog_destruct 2225
-#define wxDirDialog_GetPath 2226
-#define wxDirDialog_GetMessage 2227
-#define wxDirDialog_SetMessage 2228
-#define wxDirDialog_SetPath 2229
-#define wxFileDialog_new 2233
-#define wxFileDialog_destruct 2234
-#define wxFileDialog_GetDirectory 2235
-#define wxFileDialog_GetFilename 2236
-#define wxFileDialog_GetFilenames 2237
-#define wxFileDialog_GetFilterIndex 2238
-#define wxFileDialog_GetMessage 2239
-#define wxFileDialog_GetPath 2240
-#define wxFileDialog_GetPaths 2241
-#define wxFileDialog_GetWildcard 2242
-#define wxFileDialog_SetDirectory 2243
-#define wxFileDialog_SetFilename 2244
-#define wxFileDialog_SetFilterIndex 2245
-#define wxFileDialog_SetMessage 2246
-#define wxFileDialog_SetPath 2247
-#define wxFileDialog_SetWildcard 2248
-#define wxPickerBase_SetInternalMargin 2249
-#define wxPickerBase_GetInternalMargin 2250
-#define wxPickerBase_SetTextCtrlProportion 2251
-#define wxPickerBase_SetPickerCtrlProportion 2252
-#define wxPickerBase_GetTextCtrlProportion 2253
-#define wxPickerBase_GetPickerCtrlProportion 2254
-#define wxPickerBase_HasTextCtrl 2255
-#define wxPickerBase_GetTextCtrl 2256
-#define wxPickerBase_IsTextCtrlGrowable 2257
-#define wxPickerBase_SetPickerCtrlGrowable 2258
-#define wxPickerBase_SetTextCtrlGrowable 2259
-#define wxPickerBase_IsPickerCtrlGrowable 2260
-#define wxFilePickerCtrl_new_0 2261
-#define wxFilePickerCtrl_new_3 2262
-#define wxFilePickerCtrl_Create 2263
-#define wxFilePickerCtrl_GetPath 2264
-#define wxFilePickerCtrl_SetPath 2265
-#define wxFilePickerCtrl_destroy 2266
-#define wxDirPickerCtrl_new_0 2267
-#define wxDirPickerCtrl_new_3 2268
-#define wxDirPickerCtrl_Create 2269
-#define wxDirPickerCtrl_GetPath 2270
-#define wxDirPickerCtrl_SetPath 2271
-#define wxDirPickerCtrl_destroy 2272
-#define wxColourPickerCtrl_new_0 2273
-#define wxColourPickerCtrl_new_3 2274
-#define wxColourPickerCtrl_Create 2275
-#define wxColourPickerCtrl_GetColour 2276
-#define wxColourPickerCtrl_SetColour_1_1 2277
-#define wxColourPickerCtrl_SetColour_1_0 2278
-#define wxColourPickerCtrl_destroy 2279
-#define wxDatePickerCtrl_new_0 2280
-#define wxDatePickerCtrl_new_3 2281
-#define wxDatePickerCtrl_GetRange 2282
-#define wxDatePickerCtrl_GetValue 2283
-#define wxDatePickerCtrl_SetRange 2284
-#define wxDatePickerCtrl_SetValue 2285
-#define wxDatePickerCtrl_destroy 2286
-#define wxFontPickerCtrl_new_0 2287
-#define wxFontPickerCtrl_new_3 2288
-#define wxFontPickerCtrl_Create 2289
-#define wxFontPickerCtrl_GetSelectedFont 2290
-#define wxFontPickerCtrl_SetSelectedFont 2291
-#define wxFontPickerCtrl_GetMaxPointSize 2292
-#define wxFontPickerCtrl_SetMaxPointSize 2293
-#define wxFontPickerCtrl_destroy 2294
-#define wxFindReplaceDialog_new_0 2297
-#define wxFindReplaceDialog_new_4 2298
-#define wxFindReplaceDialog_destruct 2299
-#define wxFindReplaceDialog_Create 2300
-#define wxFindReplaceDialog_GetData 2301
-#define wxFindReplaceData_new_0 2302
-#define wxFindReplaceData_new_1 2303
-#define wxFindReplaceData_GetFindString 2304
-#define wxFindReplaceData_GetReplaceString 2305
-#define wxFindReplaceData_GetFlags 2306
-#define wxFindReplaceData_SetFlags 2307
-#define wxFindReplaceData_SetFindString 2308
-#define wxFindReplaceData_SetReplaceString 2309
-#define wxFindReplaceData_destroy 2310
-#define wxMultiChoiceDialog_new_0 2311
-#define wxMultiChoiceDialog_new_5 2313
-#define wxMultiChoiceDialog_GetSelections 2314
-#define wxMultiChoiceDialog_SetSelections 2315
-#define wxMultiChoiceDialog_destroy 2316
-#define wxSingleChoiceDialog_new_0 2317
-#define wxSingleChoiceDialog_new_5 2319
-#define wxSingleChoiceDialog_GetSelection 2320
-#define wxSingleChoiceDialog_GetStringSelection 2321
-#define wxSingleChoiceDialog_SetSelection 2322
-#define wxSingleChoiceDialog_destroy 2323
-#define wxTextEntryDialog_new 2324
-#define wxTextEntryDialog_GetValue 2325
-#define wxTextEntryDialog_SetValue 2326
-#define wxTextEntryDialog_destroy 2327
-#define wxPasswordEntryDialog_new 2328
-#define wxPasswordEntryDialog_destroy 2329
-#define wxFontData_new_0 2330
-#define wxFontData_new_1 2331
-#define wxFontData_destruct 2332
-#define wxFontData_EnableEffects 2333
-#define wxFontData_GetAllowSymbols 2334
-#define wxFontData_GetColour 2335
-#define wxFontData_GetChosenFont 2336
-#define wxFontData_GetEnableEffects 2337
-#define wxFontData_GetInitialFont 2338
-#define wxFontData_GetShowHelp 2339
-#define wxFontData_SetAllowSymbols 2340
-#define wxFontData_SetChosenFont 2341
-#define wxFontData_SetColour 2342
-#define wxFontData_SetInitialFont 2343
-#define wxFontData_SetRange 2344
-#define wxFontData_SetShowHelp 2345
-#define wxFontDialog_new_0 2349
-#define wxFontDialog_new_2 2351
-#define wxFontDialog_Create 2353
-#define wxFontDialog_GetFontData 2354
-#define wxFontDialog_destroy 2356
-#define wxProgressDialog_new 2357
-#define wxProgressDialog_destruct 2358
-#define wxProgressDialog_Resume 2359
-#define wxProgressDialog_Update_2 2360
-#define wxProgressDialog_Update_0 2361
-#define wxMessageDialog_new 2362
-#define wxMessageDialog_destruct 2363
-#define wxPageSetupDialog_new 2364
-#define wxPageSetupDialog_destruct 2365
-#define wxPageSetupDialog_GetPageSetupData 2366
-#define wxPageSetupDialog_ShowModal 2367
-#define wxPageSetupDialogData_new_0 2368
-#define wxPageSetupDialogData_new_1_0 2369
-#define wxPageSetupDialogData_new_1_1 2370
-#define wxPageSetupDialogData_destruct 2371
-#define wxPageSetupDialogData_EnableHelp 2372
-#define wxPageSetupDialogData_EnableMargins 2373
-#define wxPageSetupDialogData_EnableOrientation 2374
-#define wxPageSetupDialogData_EnablePaper 2375
-#define wxPageSetupDialogData_EnablePrinter 2376
-#define wxPageSetupDialogData_GetDefaultMinMargins 2377
-#define wxPageSetupDialogData_GetEnableMargins 2378
-#define wxPageSetupDialogData_GetEnableOrientation 2379
-#define wxPageSetupDialogData_GetEnablePaper 2380
-#define wxPageSetupDialogData_GetEnablePrinter 2381
-#define wxPageSetupDialogData_GetEnableHelp 2382
-#define wxPageSetupDialogData_GetDefaultInfo 2383
-#define wxPageSetupDialogData_GetMarginTopLeft 2384
-#define wxPageSetupDialogData_GetMarginBottomRight 2385
-#define wxPageSetupDialogData_GetMinMarginTopLeft 2386
-#define wxPageSetupDialogData_GetMinMarginBottomRight 2387
-#define wxPageSetupDialogData_GetPaperId 2388
-#define wxPageSetupDialogData_GetPaperSize 2389
-#define wxPageSetupDialogData_GetPrintData 2391
-#define wxPageSetupDialogData_IsOk 2392
-#define wxPageSetupDialogData_SetDefaultInfo 2393
-#define wxPageSetupDialogData_SetDefaultMinMargins 2394
-#define wxPageSetupDialogData_SetMarginTopLeft 2395
-#define wxPageSetupDialogData_SetMarginBottomRight 2396
-#define wxPageSetupDialogData_SetMinMarginTopLeft 2397
-#define wxPageSetupDialogData_SetMinMarginBottomRight 2398
-#define wxPageSetupDialogData_SetPaperId 2399
-#define wxPageSetupDialogData_SetPaperSize_1_1 2400
-#define wxPageSetupDialogData_SetPaperSize_1_0 2401
-#define wxPageSetupDialogData_SetPrintData 2402
-#define wxPrintDialog_new_2_0 2403
-#define wxPrintDialog_new_2_1 2404
-#define wxPrintDialog_destruct 2405
-#define wxPrintDialog_GetPrintDialogData 2406
-#define wxPrintDialog_GetPrintDC 2407
-#define wxPrintDialogData_new_0 2408
-#define wxPrintDialogData_new_1_1 2409
-#define wxPrintDialogData_new_1_0 2410
-#define wxPrintDialogData_destruct 2411
-#define wxPrintDialogData_EnableHelp 2412
-#define wxPrintDialogData_EnablePageNumbers 2413
-#define wxPrintDialogData_EnablePrintToFile 2414
-#define wxPrintDialogData_EnableSelection 2415
-#define wxPrintDialogData_GetAllPages 2416
-#define wxPrintDialogData_GetCollate 2417
-#define wxPrintDialogData_GetFromPage 2418
-#define wxPrintDialogData_GetMaxPage 2419
-#define wxPrintDialogData_GetMinPage 2420
-#define wxPrintDialogData_GetNoCopies 2421
-#define wxPrintDialogData_GetPrintData 2422
-#define wxPrintDialogData_GetPrintToFile 2423
-#define wxPrintDialogData_GetSelection 2424
-#define wxPrintDialogData_GetToPage 2425
-#define wxPrintDialogData_IsOk 2426
-#define wxPrintDialogData_SetCollate 2427
-#define wxPrintDialogData_SetFromPage 2428
-#define wxPrintDialogData_SetMaxPage 2429
-#define wxPrintDialogData_SetMinPage 2430
-#define wxPrintDialogData_SetNoCopies 2431
-#define wxPrintDialogData_SetPrintData 2432
-#define wxPrintDialogData_SetPrintToFile 2433
-#define wxPrintDialogData_SetSelection 2434
-#define wxPrintDialogData_SetToPage 2435
-#define wxPrintData_new_0 2436
-#define wxPrintData_new_1 2437
-#define wxPrintData_destruct 2438
-#define wxPrintData_GetCollate 2439
-#define wxPrintData_GetBin 2440
-#define wxPrintData_GetColour 2441
-#define wxPrintData_GetDuplex 2442
-#define wxPrintData_GetNoCopies 2443
-#define wxPrintData_GetOrientation 2444
-#define wxPrintData_GetPaperId 2445
-#define wxPrintData_GetPrinterName 2446
-#define wxPrintData_GetQuality 2447
-#define wxPrintData_IsOk 2448
-#define wxPrintData_SetBin 2449
-#define wxPrintData_SetCollate 2450
-#define wxPrintData_SetColour 2451
-#define wxPrintData_SetDuplex 2452
-#define wxPrintData_SetNoCopies 2453
-#define wxPrintData_SetOrientation 2454
-#define wxPrintData_SetPaperId 2455
-#define wxPrintData_SetPrinterName 2456
-#define wxPrintData_SetQuality 2457
-#define wxPrintPreview_new_2 2460
-#define wxPrintPreview_new_3 2461
-#define wxPrintPreview_destruct 2463
-#define wxPrintPreview_GetCanvas 2464
-#define wxPrintPreview_GetCurrentPage 2465
-#define wxPrintPreview_GetFrame 2466
-#define wxPrintPreview_GetMaxPage 2467
-#define wxPrintPreview_GetMinPage 2468
-#define wxPrintPreview_GetPrintout 2469
-#define wxPrintPreview_GetPrintoutForPrinting 2470
-#define wxPrintPreview_IsOk 2471
-#define wxPrintPreview_PaintPage 2472
-#define wxPrintPreview_Print 2473
-#define wxPrintPreview_RenderPage 2474
-#define wxPrintPreview_SetCanvas 2475
-#define wxPrintPreview_SetCurrentPage 2476
-#define wxPrintPreview_SetFrame 2477
-#define wxPrintPreview_SetPrintout 2478
-#define wxPrintPreview_SetZoom 2479
-#define wxPreviewFrame_new 2480
-#define wxPreviewFrame_destruct 2481
-#define wxPreviewFrame_CreateControlBar 2482
-#define wxPreviewFrame_CreateCanvas 2483
-#define wxPreviewFrame_Initialize 2484
-#define wxPreviewFrame_OnCloseWindow 2485
-#define wxPreviewControlBar_new 2486
-#define wxPreviewControlBar_destruct 2487
-#define wxPreviewControlBar_CreateButtons 2488
-#define wxPreviewControlBar_GetPrintPreview 2489
-#define wxPreviewControlBar_GetZoomControl 2490
-#define wxPreviewControlBar_SetZoomControl 2491
-#define wxPrinter_new 2493
-#define wxPrinter_CreateAbortWindow 2494
-#define wxPrinter_GetAbort 2495
-#define wxPrinter_GetLastError 2496
-#define wxPrinter_GetPrintDialogData 2497
-#define wxPrinter_Print 2498
-#define wxPrinter_PrintDialog 2499
-#define wxPrinter_ReportError 2500
-#define wxPrinter_Setup 2501
-#define wxPrinter_destroy 2502
-#define wxXmlResource_new_1 2503
-#define wxXmlResource_new_2 2504
-#define wxXmlResource_destruct 2505
-#define wxXmlResource_AttachUnknownControl 2506
-#define wxXmlResource_ClearHandlers 2507
-#define wxXmlResource_CompareVersion 2508
-#define wxXmlResource_Get 2509
-#define wxXmlResource_GetFlags 2510
-#define wxXmlResource_GetVersion 2511
-#define wxXmlResource_GetXRCID 2512
-#define wxXmlResource_InitAllHandlers 2513
-#define wxXmlResource_Load 2514
-#define wxXmlResource_LoadBitmap 2515
-#define wxXmlResource_LoadDialog_2 2516
-#define wxXmlResource_LoadDialog_3 2517
-#define wxXmlResource_LoadFrame_2 2518
-#define wxXmlResource_LoadFrame_3 2519
-#define wxXmlResource_LoadIcon 2520
-#define wxXmlResource_LoadMenu 2521
-#define wxXmlResource_LoadMenuBar_2 2522
-#define wxXmlResource_LoadMenuBar_1 2523
-#define wxXmlResource_LoadPanel_2 2524
-#define wxXmlResource_LoadPanel_3 2525
-#define wxXmlResource_LoadToolBar 2526
-#define wxXmlResource_Set 2527
-#define wxXmlResource_SetFlags 2528
-#define wxXmlResource_Unload 2529
-#define wxXmlResource_xrcctrl 2530
-#define wxHtmlEasyPrinting_new 2531
-#define wxHtmlEasyPrinting_destruct 2532
-#define wxHtmlEasyPrinting_GetPrintData 2533
-#define wxHtmlEasyPrinting_GetPageSetupData 2534
-#define wxHtmlEasyPrinting_PreviewFile 2535
-#define wxHtmlEasyPrinting_PreviewText 2536
-#define wxHtmlEasyPrinting_PrintFile 2537
-#define wxHtmlEasyPrinting_PrintText 2538
-#define wxHtmlEasyPrinting_PageSetup 2539
-#define wxHtmlEasyPrinting_SetFonts 2540
-#define wxHtmlEasyPrinting_SetHeader 2541
-#define wxHtmlEasyPrinting_SetFooter 2542
-#define wxGLCanvas_new_2 2544
-#define wxGLCanvas_new_3_1 2545
-#define wxGLCanvas_new_3_0 2546
-#define wxGLCanvas_GetContext 2547
-#define wxGLCanvas_SetCurrent 2549
-#define wxGLCanvas_SwapBuffers 2550
-#define wxGLCanvas_destroy 2551
-#define wxAuiManager_new 2552
-#define wxAuiManager_destruct 2553
-#define wxAuiManager_AddPane_2_1 2554
-#define wxAuiManager_AddPane_3 2555
-#define wxAuiManager_AddPane_2_0 2556
-#define wxAuiManager_DetachPane 2557
-#define wxAuiManager_GetAllPanes 2558
-#define wxAuiManager_GetArtProvider 2559
-#define wxAuiManager_GetDockSizeConstraint 2560
-#define wxAuiManager_GetFlags 2561
-#define wxAuiManager_GetManagedWindow 2562
-#define wxAuiManager_GetManager 2563
-#define wxAuiManager_GetPane_1_1 2564
-#define wxAuiManager_GetPane_1_0 2565
-#define wxAuiManager_HideHint 2566
-#define wxAuiManager_InsertPane 2567
-#define wxAuiManager_LoadPaneInfo 2568
-#define wxAuiManager_LoadPerspective 2569
-#define wxAuiManager_SavePaneInfo 2570
-#define wxAuiManager_SavePerspective 2571
-#define wxAuiManager_SetArtProvider 2572
-#define wxAuiManager_SetDockSizeConstraint 2573
-#define wxAuiManager_SetFlags 2574
-#define wxAuiManager_SetManagedWindow 2575
-#define wxAuiManager_ShowHint 2576
-#define wxAuiManager_UnInit 2577
-#define wxAuiManager_Update 2578
-#define wxAuiPaneInfo_new_0 2579
-#define wxAuiPaneInfo_new_1 2580
-#define wxAuiPaneInfo_destruct 2581
-#define wxAuiPaneInfo_BestSize_1 2582
-#define wxAuiPaneInfo_BestSize_2 2583
-#define wxAuiPaneInfo_Bottom 2584
-#define wxAuiPaneInfo_BottomDockable 2585
-#define wxAuiPaneInfo_Caption 2586
-#define wxAuiPaneInfo_CaptionVisible 2587
-#define wxAuiPaneInfo_Centre 2588
-#define wxAuiPaneInfo_CentrePane 2589
-#define wxAuiPaneInfo_CloseButton 2590
-#define wxAuiPaneInfo_DefaultPane 2591
-#define wxAuiPaneInfo_DestroyOnClose 2592
-#define wxAuiPaneInfo_Direction 2593
-#define wxAuiPaneInfo_Dock 2594
-#define wxAuiPaneInfo_Dockable 2595
-#define wxAuiPaneInfo_Fixed 2596
-#define wxAuiPaneInfo_Float 2597
-#define wxAuiPaneInfo_Floatable 2598
-#define wxAuiPaneInfo_FloatingPosition_1 2599
-#define wxAuiPaneInfo_FloatingPosition_2 2600
-#define wxAuiPaneInfo_FloatingSize_1 2601
-#define wxAuiPaneInfo_FloatingSize_2 2602
-#define wxAuiPaneInfo_Gripper 2603
-#define wxAuiPaneInfo_GripperTop 2604
-#define wxAuiPaneInfo_HasBorder 2605
-#define wxAuiPaneInfo_HasCaption 2606
-#define wxAuiPaneInfo_HasCloseButton 2607
-#define wxAuiPaneInfo_HasFlag 2608
-#define wxAuiPaneInfo_HasGripper 2609
-#define wxAuiPaneInfo_HasGripperTop 2610
-#define wxAuiPaneInfo_HasMaximizeButton 2611
-#define wxAuiPaneInfo_HasMinimizeButton 2612
-#define wxAuiPaneInfo_HasPinButton 2613
-#define wxAuiPaneInfo_Hide 2614
-#define wxAuiPaneInfo_IsBottomDockable 2615
-#define wxAuiPaneInfo_IsDocked 2616
-#define wxAuiPaneInfo_IsFixed 2617
-#define wxAuiPaneInfo_IsFloatable 2618
-#define wxAuiPaneInfo_IsFloating 2619
-#define wxAuiPaneInfo_IsLeftDockable 2620
-#define wxAuiPaneInfo_IsMovable 2621
-#define wxAuiPaneInfo_IsOk 2622
-#define wxAuiPaneInfo_IsResizable 2623
-#define wxAuiPaneInfo_IsRightDockable 2624
-#define wxAuiPaneInfo_IsShown 2625
-#define wxAuiPaneInfo_IsToolbar 2626
-#define wxAuiPaneInfo_IsTopDockable 2627
-#define wxAuiPaneInfo_Layer 2628
-#define wxAuiPaneInfo_Left 2629
-#define wxAuiPaneInfo_LeftDockable 2630
-#define wxAuiPaneInfo_MaxSize_1 2631
-#define wxAuiPaneInfo_MaxSize_2 2632
-#define wxAuiPaneInfo_MaximizeButton 2633
-#define wxAuiPaneInfo_MinSize_1 2634
-#define wxAuiPaneInfo_MinSize_2 2635
-#define wxAuiPaneInfo_MinimizeButton 2636
-#define wxAuiPaneInfo_Movable 2637
-#define wxAuiPaneInfo_Name 2638
-#define wxAuiPaneInfo_PaneBorder 2639
-#define wxAuiPaneInfo_PinButton 2640
-#define wxAuiPaneInfo_Position 2641
-#define wxAuiPaneInfo_Resizable 2642
-#define wxAuiPaneInfo_Right 2643
-#define wxAuiPaneInfo_RightDockable 2644
-#define wxAuiPaneInfo_Row 2645
-#define wxAuiPaneInfo_SafeSet 2646
-#define wxAuiPaneInfo_SetFlag 2647
-#define wxAuiPaneInfo_Show 2648
-#define wxAuiPaneInfo_ToolbarPane 2649
-#define wxAuiPaneInfo_Top 2650
-#define wxAuiPaneInfo_TopDockable 2651
-#define wxAuiPaneInfo_Window 2652
-#define wxAuiNotebook_new_0 2653
-#define wxAuiNotebook_new_2 2654
-#define wxAuiNotebook_AddPage 2655
-#define wxAuiNotebook_Create 2656
-#define wxAuiNotebook_DeletePage 2657
-#define wxAuiNotebook_GetArtProvider 2658
-#define wxAuiNotebook_GetPage 2659
-#define wxAuiNotebook_GetPageBitmap 2660
-#define wxAuiNotebook_GetPageCount 2661
-#define wxAuiNotebook_GetPageIndex 2662
-#define wxAuiNotebook_GetPageText 2663
-#define wxAuiNotebook_GetSelection 2664
-#define wxAuiNotebook_InsertPage 2665
-#define wxAuiNotebook_RemovePage 2666
-#define wxAuiNotebook_SetArtProvider 2667
-#define wxAuiNotebook_SetFont 2668
-#define wxAuiNotebook_SetPageBitmap 2669
-#define wxAuiNotebook_SetPageText 2670
-#define wxAuiNotebook_SetSelection 2671
-#define wxAuiNotebook_SetTabCtrlHeight 2672
-#define wxAuiNotebook_SetUniformBitmapSize 2673
-#define wxAuiNotebook_destroy 2674
-#define wxMDIParentFrame_new_0 2675
-#define wxMDIParentFrame_new_4 2676
-#define wxMDIParentFrame_destruct 2677
-#define wxMDIParentFrame_ActivateNext 2678
-#define wxMDIParentFrame_ActivatePrevious 2679
-#define wxMDIParentFrame_ArrangeIcons 2680
-#define wxMDIParentFrame_Cascade 2681
-#define wxMDIParentFrame_Create 2682
-#define wxMDIParentFrame_GetActiveChild 2683
-#define wxMDIParentFrame_GetClientWindow 2684
-#define wxMDIParentFrame_Tile 2685
-#define wxMDIChildFrame_new_0 2686
-#define wxMDIChildFrame_new_4 2687
-#define wxMDIChildFrame_destruct 2688
-#define wxMDIChildFrame_Activate 2689
-#define wxMDIChildFrame_Create 2690
-#define wxMDIChildFrame_Maximize 2691
-#define wxMDIChildFrame_Restore 2692
-#define wxMDIClientWindow_new_0 2693
-#define wxMDIClientWindow_new_2 2694
-#define wxMDIClientWindow_destruct 2695
-#define wxMDIClientWindow_CreateClient 2696
-#define wxLayoutAlgorithm_new 2697
-#define wxLayoutAlgorithm_LayoutFrame 2698
-#define wxLayoutAlgorithm_LayoutMDIFrame 2699
-#define wxLayoutAlgorithm_LayoutWindow 2700
-#define wxLayoutAlgorithm_destroy 2701
-#define wxEvent_GetId 2702
-#define wxEvent_GetSkipped 2703
-#define wxEvent_GetTimestamp 2704
-#define wxEvent_IsCommandEvent 2705
-#define wxEvent_ResumePropagation 2706
-#define wxEvent_ShouldPropagate 2707
-#define wxEvent_Skip 2708
-#define wxEvent_StopPropagation 2709
-#define wxCommandEvent_getClientData 2710
-#define wxCommandEvent_GetExtraLong 2711
-#define wxCommandEvent_GetInt 2712
-#define wxCommandEvent_GetSelection 2713
-#define wxCommandEvent_GetString 2714
-#define wxCommandEvent_IsChecked 2715
-#define wxCommandEvent_IsSelection 2716
-#define wxCommandEvent_SetInt 2717
-#define wxCommandEvent_SetString 2718
-#define wxScrollEvent_GetOrientation 2719
-#define wxScrollEvent_GetPosition 2720
-#define wxScrollWinEvent_GetOrientation 2721
-#define wxScrollWinEvent_GetPosition 2722
-#define wxMouseEvent_AltDown 2723
-#define wxMouseEvent_Button 2724
-#define wxMouseEvent_ButtonDClick 2725
-#define wxMouseEvent_ButtonDown 2726
-#define wxMouseEvent_ButtonUp 2727
-#define wxMouseEvent_CmdDown 2728
-#define wxMouseEvent_ControlDown 2729
-#define wxMouseEvent_Dragging 2730
-#define wxMouseEvent_Entering 2731
-#define wxMouseEvent_GetButton 2732
-#define wxMouseEvent_GetPosition 2735
-#define wxMouseEvent_GetLogicalPosition 2736
-#define wxMouseEvent_GetLinesPerAction 2737
-#define wxMouseEvent_GetWheelRotation 2738
-#define wxMouseEvent_GetWheelDelta 2739
-#define wxMouseEvent_GetX 2740
-#define wxMouseEvent_GetY 2741
-#define wxMouseEvent_IsButton 2742
-#define wxMouseEvent_IsPageScroll 2743
-#define wxMouseEvent_Leaving 2744
-#define wxMouseEvent_LeftDClick 2745
-#define wxMouseEvent_LeftDown 2746
-#define wxMouseEvent_LeftIsDown 2747
-#define wxMouseEvent_LeftUp 2748
-#define wxMouseEvent_MetaDown 2749
-#define wxMouseEvent_MiddleDClick 2750
-#define wxMouseEvent_MiddleDown 2751
-#define wxMouseEvent_MiddleIsDown 2752
-#define wxMouseEvent_MiddleUp 2753
-#define wxMouseEvent_Moving 2754
-#define wxMouseEvent_RightDClick 2755
-#define wxMouseEvent_RightDown 2756
-#define wxMouseEvent_RightIsDown 2757
-#define wxMouseEvent_RightUp 2758
-#define wxMouseEvent_ShiftDown 2759
-#define wxSetCursorEvent_GetCursor 2760
-#define wxSetCursorEvent_GetX 2761
-#define wxSetCursorEvent_GetY 2762
-#define wxSetCursorEvent_HasCursor 2763
-#define wxSetCursorEvent_SetCursor 2764
-#define wxKeyEvent_AltDown 2765
-#define wxKeyEvent_CmdDown 2766
-#define wxKeyEvent_ControlDown 2767
-#define wxKeyEvent_GetKeyCode 2768
-#define wxKeyEvent_GetModifiers 2769
-#define wxKeyEvent_GetPosition 2772
-#define wxKeyEvent_GetRawKeyCode 2773
-#define wxKeyEvent_GetRawKeyFlags 2774
-#define wxKeyEvent_GetUnicodeKey 2775
-#define wxKeyEvent_GetX 2776
-#define wxKeyEvent_GetY 2777
-#define wxKeyEvent_HasModifiers 2778
-#define wxKeyEvent_MetaDown 2779
-#define wxKeyEvent_ShiftDown 2780
-#define wxSizeEvent_GetSize 2781
-#define wxMoveEvent_GetPosition 2782
-#define wxEraseEvent_GetDC 2783
-#define wxFocusEvent_GetWindow 2784
-#define wxChildFocusEvent_GetWindow 2785
-#define wxMenuEvent_GetMenu 2786
-#define wxMenuEvent_GetMenuId 2787
-#define wxMenuEvent_IsPopup 2788
-#define wxCloseEvent_CanVeto 2789
-#define wxCloseEvent_GetLoggingOff 2790
-#define wxCloseEvent_SetCanVeto 2791
-#define wxCloseEvent_SetLoggingOff 2792
-#define wxCloseEvent_Veto 2793
-#define wxShowEvent_SetShow 2794
-#define wxShowEvent_GetShow 2795
-#define wxIconizeEvent_Iconized 2796
-#define wxJoystickEvent_ButtonDown 2797
-#define wxJoystickEvent_ButtonIsDown 2798
-#define wxJoystickEvent_ButtonUp 2799
-#define wxJoystickEvent_GetButtonChange 2800
-#define wxJoystickEvent_GetButtonState 2801
-#define wxJoystickEvent_GetJoystick 2802
-#define wxJoystickEvent_GetPosition 2803
-#define wxJoystickEvent_GetZPosition 2804
-#define wxJoystickEvent_IsButton 2805
-#define wxJoystickEvent_IsMove 2806
-#define wxJoystickEvent_IsZMove 2807
-#define wxUpdateUIEvent_CanUpdate 2808
-#define wxUpdateUIEvent_Check 2809
-#define wxUpdateUIEvent_Enable 2810
-#define wxUpdateUIEvent_Show 2811
-#define wxUpdateUIEvent_GetChecked 2812
-#define wxUpdateUIEvent_GetEnabled 2813
-#define wxUpdateUIEvent_GetShown 2814
-#define wxUpdateUIEvent_GetSetChecked 2815
-#define wxUpdateUIEvent_GetSetEnabled 2816
-#define wxUpdateUIEvent_GetSetShown 2817
-#define wxUpdateUIEvent_GetSetText 2818
-#define wxUpdateUIEvent_GetText 2819
-#define wxUpdateUIEvent_GetMode 2820
-#define wxUpdateUIEvent_GetUpdateInterval 2821
-#define wxUpdateUIEvent_ResetUpdateTime 2822
-#define wxUpdateUIEvent_SetMode 2823
-#define wxUpdateUIEvent_SetText 2824
-#define wxUpdateUIEvent_SetUpdateInterval 2825
-#define wxMouseCaptureChangedEvent_GetCapturedWindow 2826
-#define wxPaletteChangedEvent_SetChangedWindow 2827
-#define wxPaletteChangedEvent_GetChangedWindow 2828
-#define wxQueryNewPaletteEvent_SetPaletteRealized 2829
-#define wxQueryNewPaletteEvent_GetPaletteRealized 2830
-#define wxNavigationKeyEvent_GetDirection 2831
-#define wxNavigationKeyEvent_SetDirection 2832
-#define wxNavigationKeyEvent_IsWindowChange 2833
-#define wxNavigationKeyEvent_SetWindowChange 2834
-#define wxNavigationKeyEvent_IsFromTab 2835
-#define wxNavigationKeyEvent_SetFromTab 2836
-#define wxNavigationKeyEvent_GetCurrentFocus 2837
-#define wxNavigationKeyEvent_SetCurrentFocus 2838
-#define wxHelpEvent_GetOrigin 2839
-#define wxHelpEvent_GetPosition 2840
-#define wxHelpEvent_SetOrigin 2841
-#define wxHelpEvent_SetPosition 2842
-#define wxContextMenuEvent_GetPosition 2843
-#define wxContextMenuEvent_SetPosition 2844
-#define wxIdleEvent_CanSend 2845
-#define wxIdleEvent_GetMode 2846
-#define wxIdleEvent_RequestMore 2847
-#define wxIdleEvent_MoreRequested 2848
-#define wxIdleEvent_SetMode 2849
-#define wxGridEvent_AltDown 2850
-#define wxGridEvent_ControlDown 2851
-#define wxGridEvent_GetCol 2852
-#define wxGridEvent_GetPosition 2853
-#define wxGridEvent_GetRow 2854
-#define wxGridEvent_MetaDown 2855
-#define wxGridEvent_Selecting 2856
-#define wxGridEvent_ShiftDown 2857
-#define wxNotifyEvent_Allow 2858
-#define wxNotifyEvent_IsAllowed 2859
-#define wxNotifyEvent_Veto 2860
-#define wxSashEvent_GetEdge 2861
-#define wxSashEvent_GetDragRect 2862
-#define wxSashEvent_GetDragStatus 2863
-#define wxListEvent_GetCacheFrom 2864
-#define wxListEvent_GetCacheTo 2865
-#define wxListEvent_GetKeyCode 2866
-#define wxListEvent_GetIndex 2867
-#define wxListEvent_GetColumn 2868
-#define wxListEvent_GetPoint 2869
-#define wxListEvent_GetLabel 2870
-#define wxListEvent_GetText 2871
-#define wxListEvent_GetImage 2872
-#define wxListEvent_GetData 2873
-#define wxListEvent_GetMask 2874
-#define wxListEvent_GetItem 2875
-#define wxListEvent_IsEditCancelled 2876
-#define wxDateEvent_GetDate 2877
-#define wxCalendarEvent_GetWeekDay 2878
-#define wxFileDirPickerEvent_GetPath 2879
-#define wxColourPickerEvent_GetColour 2880
-#define wxFontPickerEvent_GetFont 2881
-#define wxStyledTextEvent_GetPosition 2882
-#define wxStyledTextEvent_GetKey 2883
-#define wxStyledTextEvent_GetModifiers 2884
-#define wxStyledTextEvent_GetModificationType 2885
-#define wxStyledTextEvent_GetText 2886
-#define wxStyledTextEvent_GetLength 2887
-#define wxStyledTextEvent_GetLinesAdded 2888
-#define wxStyledTextEvent_GetLine 2889
-#define wxStyledTextEvent_GetFoldLevelNow 2890
-#define wxStyledTextEvent_GetFoldLevelPrev 2891
-#define wxStyledTextEvent_GetMargin 2892
-#define wxStyledTextEvent_GetMessage 2893
-#define wxStyledTextEvent_GetWParam 2894
-#define wxStyledTextEvent_GetLParam 2895
-#define wxStyledTextEvent_GetListType 2896
-#define wxStyledTextEvent_GetX 2897
-#define wxStyledTextEvent_GetY 2898
-#define wxStyledTextEvent_GetDragText 2899
-#define wxStyledTextEvent_GetDragAllowMove 2900
-#define wxStyledTextEvent_GetDragResult 2901
-#define wxStyledTextEvent_GetShift 2902
-#define wxStyledTextEvent_GetControl 2903
-#define wxStyledTextEvent_GetAlt 2904
-#define utils_wxGetKeyState 2905
-#define utils_wxGetMousePosition 2906
-#define utils_wxGetMouseState 2907
-#define utils_wxSetDetectableAutoRepeat 2908
-#define utils_wxBell 2909
-#define utils_wxFindMenuItemId 2910
-#define utils_wxGenericFindWindowAtPoint 2911
-#define utils_wxFindWindowAtPoint 2912
-#define utils_wxBeginBusyCursor 2913
-#define utils_wxEndBusyCursor 2914
-#define utils_wxIsBusy 2915
-#define utils_wxShutdown 2916
-#define utils_wxShell 2917
-#define utils_wxLaunchDefaultBrowser 2918
-#define utils_wxGetEmailAddress 2919
-#define utils_wxGetUserId 2920
-#define utils_wxGetHomeDir 2921
-#define utils_wxNewId 2922
-#define utils_wxRegisterId 2923
-#define utils_wxGetCurrentId 2924
-#define utils_wxGetOsDescription 2925
-#define utils_wxIsPlatformLittleEndian 2926
-#define utils_wxIsPlatform64Bit 2927
-#define gdicmn_wxDisplaySize 2928
-#define gdicmn_wxSetCursor 2929
-#define wxPrintout_new 2930
-#define wxPrintout_destruct 2931
-#define wxPrintout_GetDC 2932
-#define wxPrintout_GetPageSizeMM 2933
-#define wxPrintout_GetPageSizePixels 2934
-#define wxPrintout_GetPaperRectPixels 2935
-#define wxPrintout_GetPPIPrinter 2936
-#define wxPrintout_GetPPIScreen 2937
-#define wxPrintout_GetTitle 2938
-#define wxPrintout_IsPreview 2939
-#define wxPrintout_FitThisSizeToPaper 2940
-#define wxPrintout_FitThisSizeToPage 2941
-#define wxPrintout_FitThisSizeToPageMargins 2942
-#define wxPrintout_MapScreenSizeToPaper 2943
-#define wxPrintout_MapScreenSizeToPage 2944
-#define wxPrintout_MapScreenSizeToPageMargins 2945
-#define wxPrintout_MapScreenSizeToDevice 2946
-#define wxPrintout_GetLogicalPaperRect 2947
-#define wxPrintout_GetLogicalPageRect 2948
-#define wxPrintout_GetLogicalPageMarginsRect 2949
-#define wxPrintout_SetLogicalOrigin 2950
-#define wxPrintout_OffsetLogicalOrigin 2951
-#define wxStyledTextCtrl_new_2 2952
-#define wxStyledTextCtrl_new_0 2953
-#define wxStyledTextCtrl_destruct 2954
-#define wxStyledTextCtrl_Create 2955
-#define wxStyledTextCtrl_AddText 2956
-#define wxStyledTextCtrl_AddStyledText 2957
-#define wxStyledTextCtrl_InsertText 2958
-#define wxStyledTextCtrl_ClearAll 2959
-#define wxStyledTextCtrl_ClearDocumentStyle 2960
-#define wxStyledTextCtrl_GetLength 2961
-#define wxStyledTextCtrl_GetCharAt 2962
-#define wxStyledTextCtrl_GetCurrentPos 2963
-#define wxStyledTextCtrl_GetAnchor 2964
-#define wxStyledTextCtrl_GetStyleAt 2965
-#define wxStyledTextCtrl_Redo 2966
-#define wxStyledTextCtrl_SetUndoCollection 2967
-#define wxStyledTextCtrl_SelectAll 2968
-#define wxStyledTextCtrl_SetSavePoint 2969
-#define wxStyledTextCtrl_GetStyledText 2970
-#define wxStyledTextCtrl_CanRedo 2971
-#define wxStyledTextCtrl_MarkerLineFromHandle 2972
-#define wxStyledTextCtrl_MarkerDeleteHandle 2973
-#define wxStyledTextCtrl_GetUndoCollection 2974
-#define wxStyledTextCtrl_GetViewWhiteSpace 2975
-#define wxStyledTextCtrl_SetViewWhiteSpace 2976
-#define wxStyledTextCtrl_PositionFromPoint 2977
-#define wxStyledTextCtrl_PositionFromPointClose 2978
-#define wxStyledTextCtrl_GotoLine 2979
-#define wxStyledTextCtrl_GotoPos 2980
-#define wxStyledTextCtrl_SetAnchor 2981
-#define wxStyledTextCtrl_GetCurLine 2982
-#define wxStyledTextCtrl_GetEndStyled 2983
-#define wxStyledTextCtrl_ConvertEOLs 2984
-#define wxStyledTextCtrl_GetEOLMode 2985
-#define wxStyledTextCtrl_SetEOLMode 2986
-#define wxStyledTextCtrl_StartStyling 2987
-#define wxStyledTextCtrl_SetStyling 2988
-#define wxStyledTextCtrl_GetBufferedDraw 2989
-#define wxStyledTextCtrl_SetBufferedDraw 2990
-#define wxStyledTextCtrl_SetTabWidth 2991
-#define wxStyledTextCtrl_GetTabWidth 2992
-#define wxStyledTextCtrl_SetCodePage 2993
-#define wxStyledTextCtrl_MarkerDefine 2994
-#define wxStyledTextCtrl_MarkerSetForeground 2995
-#define wxStyledTextCtrl_MarkerSetBackground 2996
-#define wxStyledTextCtrl_MarkerAdd 2997
-#define wxStyledTextCtrl_MarkerDelete 2998
-#define wxStyledTextCtrl_MarkerDeleteAll 2999
-#define wxStyledTextCtrl_MarkerGet 3000
-#define wxStyledTextCtrl_MarkerNext 3001
-#define wxStyledTextCtrl_MarkerPrevious 3002
-#define wxStyledTextCtrl_MarkerDefineBitmap 3003
-#define wxStyledTextCtrl_MarkerAddSet 3004
-#define wxStyledTextCtrl_MarkerSetAlpha 3005
-#define wxStyledTextCtrl_SetMarginType 3006
-#define wxStyledTextCtrl_GetMarginType 3007
-#define wxStyledTextCtrl_SetMarginWidth 3008
-#define wxStyledTextCtrl_GetMarginWidth 3009
-#define wxStyledTextCtrl_SetMarginMask 3010
-#define wxStyledTextCtrl_GetMarginMask 3011
-#define wxStyledTextCtrl_SetMarginSensitive 3012
-#define wxStyledTextCtrl_GetMarginSensitive 3013
-#define wxStyledTextCtrl_StyleClearAll 3014
-#define wxStyledTextCtrl_StyleSetForeground 3015
-#define wxStyledTextCtrl_StyleSetBackground 3016
-#define wxStyledTextCtrl_StyleSetBold 3017
-#define wxStyledTextCtrl_StyleSetItalic 3018
-#define wxStyledTextCtrl_StyleSetSize 3019
-#define wxStyledTextCtrl_StyleSetFaceName 3020
-#define wxStyledTextCtrl_StyleSetEOLFilled 3021
-#define wxStyledTextCtrl_StyleResetDefault 3022
-#define wxStyledTextCtrl_StyleSetUnderline 3023
-#define wxStyledTextCtrl_StyleSetCase 3024
-#define wxStyledTextCtrl_StyleSetHotSpot 3025
-#define wxStyledTextCtrl_SetSelForeground 3026
-#define wxStyledTextCtrl_SetSelBackground 3027
-#define wxStyledTextCtrl_GetSelAlpha 3028
-#define wxStyledTextCtrl_SetSelAlpha 3029
-#define wxStyledTextCtrl_SetCaretForeground 3030
-#define wxStyledTextCtrl_CmdKeyAssign 3031
-#define wxStyledTextCtrl_CmdKeyClear 3032
-#define wxStyledTextCtrl_CmdKeyClearAll 3033
-#define wxStyledTextCtrl_SetStyleBytes 3034
-#define wxStyledTextCtrl_StyleSetVisible 3035
-#define wxStyledTextCtrl_GetCaretPeriod 3036
-#define wxStyledTextCtrl_SetCaretPeriod 3037
-#define wxStyledTextCtrl_SetWordChars 3038
-#define wxStyledTextCtrl_BeginUndoAction 3039
-#define wxStyledTextCtrl_EndUndoAction 3040
-#define wxStyledTextCtrl_IndicatorSetStyle 3041
-#define wxStyledTextCtrl_IndicatorGetStyle 3042
-#define wxStyledTextCtrl_IndicatorSetForeground 3043
-#define wxStyledTextCtrl_IndicatorGetForeground 3044
-#define wxStyledTextCtrl_SetWhitespaceForeground 3045
-#define wxStyledTextCtrl_SetWhitespaceBackground 3046
-#define wxStyledTextCtrl_GetStyleBits 3047
-#define wxStyledTextCtrl_SetLineState 3048
-#define wxStyledTextCtrl_GetLineState 3049
-#define wxStyledTextCtrl_GetMaxLineState 3050
-#define wxStyledTextCtrl_GetCaretLineVisible 3051
-#define wxStyledTextCtrl_SetCaretLineVisible 3052
-#define wxStyledTextCtrl_GetCaretLineBackground 3053
-#define wxStyledTextCtrl_SetCaretLineBackground 3054
-#define wxStyledTextCtrl_AutoCompShow 3055
-#define wxStyledTextCtrl_AutoCompCancel 3056
-#define wxStyledTextCtrl_AutoCompActive 3057
-#define wxStyledTextCtrl_AutoCompPosStart 3058
-#define wxStyledTextCtrl_AutoCompComplete 3059
-#define wxStyledTextCtrl_AutoCompStops 3060
-#define wxStyledTextCtrl_AutoCompSetSeparator 3061
-#define wxStyledTextCtrl_AutoCompGetSeparator 3062
-#define wxStyledTextCtrl_AutoCompSelect 3063
-#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3064
-#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3065
-#define wxStyledTextCtrl_AutoCompSetFillUps 3066
-#define wxStyledTextCtrl_AutoCompSetChooseSingle 3067
-#define wxStyledTextCtrl_AutoCompGetChooseSingle 3068
-#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3069
-#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3070
-#define wxStyledTextCtrl_UserListShow 3071
-#define wxStyledTextCtrl_AutoCompSetAutoHide 3072
-#define wxStyledTextCtrl_AutoCompGetAutoHide 3073
-#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3074
-#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3075
-#define wxStyledTextCtrl_RegisterImage 3076
-#define wxStyledTextCtrl_ClearRegisteredImages 3077
-#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3078
-#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3079
-#define wxStyledTextCtrl_AutoCompSetMaxWidth 3080
-#define wxStyledTextCtrl_AutoCompGetMaxWidth 3081
-#define wxStyledTextCtrl_AutoCompSetMaxHeight 3082
-#define wxStyledTextCtrl_AutoCompGetMaxHeight 3083
-#define wxStyledTextCtrl_SetIndent 3084
-#define wxStyledTextCtrl_GetIndent 3085
-#define wxStyledTextCtrl_SetUseTabs 3086
-#define wxStyledTextCtrl_GetUseTabs 3087
-#define wxStyledTextCtrl_SetLineIndentation 3088
-#define wxStyledTextCtrl_GetLineIndentation 3089
-#define wxStyledTextCtrl_GetLineIndentPosition 3090
-#define wxStyledTextCtrl_GetColumn 3091
-#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3092
-#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3093
-#define wxStyledTextCtrl_SetIndentationGuides 3094
-#define wxStyledTextCtrl_GetIndentationGuides 3095
-#define wxStyledTextCtrl_SetHighlightGuide 3096
-#define wxStyledTextCtrl_GetHighlightGuide 3097
-#define wxStyledTextCtrl_GetLineEndPosition 3098
-#define wxStyledTextCtrl_GetCodePage 3099
-#define wxStyledTextCtrl_GetCaretForeground 3100
-#define wxStyledTextCtrl_GetReadOnly 3101
-#define wxStyledTextCtrl_SetCurrentPos 3102
-#define wxStyledTextCtrl_SetSelectionStart 3103
-#define wxStyledTextCtrl_GetSelectionStart 3104
-#define wxStyledTextCtrl_SetSelectionEnd 3105
-#define wxStyledTextCtrl_GetSelectionEnd 3106
-#define wxStyledTextCtrl_SetPrintMagnification 3107
-#define wxStyledTextCtrl_GetPrintMagnification 3108
-#define wxStyledTextCtrl_SetPrintColourMode 3109
-#define wxStyledTextCtrl_GetPrintColourMode 3110
-#define wxStyledTextCtrl_FindText 3111
-#define wxStyledTextCtrl_FormatRange 3112
-#define wxStyledTextCtrl_GetFirstVisibleLine 3113
-#define wxStyledTextCtrl_GetLine 3114
-#define wxStyledTextCtrl_GetLineCount 3115
-#define wxStyledTextCtrl_SetMarginLeft 3116
-#define wxStyledTextCtrl_GetMarginLeft 3117
-#define wxStyledTextCtrl_SetMarginRight 3118
-#define wxStyledTextCtrl_GetMarginRight 3119
-#define wxStyledTextCtrl_GetModify 3120
-#define wxStyledTextCtrl_SetSelection 3121
-#define wxStyledTextCtrl_GetSelectedText 3122
-#define wxStyledTextCtrl_GetTextRange 3123
-#define wxStyledTextCtrl_HideSelection 3124
-#define wxStyledTextCtrl_LineFromPosition 3125
-#define wxStyledTextCtrl_PositionFromLine 3126
-#define wxStyledTextCtrl_LineScroll 3127
-#define wxStyledTextCtrl_EnsureCaretVisible 3128
-#define wxStyledTextCtrl_ReplaceSelection 3129
-#define wxStyledTextCtrl_SetReadOnly 3130
-#define wxStyledTextCtrl_CanPaste 3131
-#define wxStyledTextCtrl_CanUndo 3132
-#define wxStyledTextCtrl_EmptyUndoBuffer 3133
-#define wxStyledTextCtrl_Undo 3134
-#define wxStyledTextCtrl_Cut 3135
-#define wxStyledTextCtrl_Copy 3136
-#define wxStyledTextCtrl_Paste 3137
-#define wxStyledTextCtrl_Clear 3138
-#define wxStyledTextCtrl_SetText 3139
-#define wxStyledTextCtrl_GetText 3140
-#define wxStyledTextCtrl_GetTextLength 3141
-#define wxStyledTextCtrl_GetOvertype 3142
-#define wxStyledTextCtrl_SetCaretWidth 3143
-#define wxStyledTextCtrl_GetCaretWidth 3144
-#define wxStyledTextCtrl_SetTargetStart 3145
-#define wxStyledTextCtrl_GetTargetStart 3146
-#define wxStyledTextCtrl_SetTargetEnd 3147
-#define wxStyledTextCtrl_GetTargetEnd 3148
-#define wxStyledTextCtrl_ReplaceTarget 3149
-#define wxStyledTextCtrl_SearchInTarget 3150
-#define wxStyledTextCtrl_SetSearchFlags 3151
-#define wxStyledTextCtrl_GetSearchFlags 3152
-#define wxStyledTextCtrl_CallTipShow 3153
-#define wxStyledTextCtrl_CallTipCancel 3154
-#define wxStyledTextCtrl_CallTipActive 3155
-#define wxStyledTextCtrl_CallTipPosAtStart 3156
-#define wxStyledTextCtrl_CallTipSetHighlight 3157
-#define wxStyledTextCtrl_CallTipSetBackground 3158
-#define wxStyledTextCtrl_CallTipSetForeground 3159
-#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3160
-#define wxStyledTextCtrl_CallTipUseStyle 3161
-#define wxStyledTextCtrl_VisibleFromDocLine 3162
-#define wxStyledTextCtrl_DocLineFromVisible 3163
-#define wxStyledTextCtrl_WrapCount 3164
-#define wxStyledTextCtrl_SetFoldLevel 3165
-#define wxStyledTextCtrl_GetFoldLevel 3166
-#define wxStyledTextCtrl_GetLastChild 3167
-#define wxStyledTextCtrl_GetFoldParent 3168
-#define wxStyledTextCtrl_ShowLines 3169
-#define wxStyledTextCtrl_HideLines 3170
-#define wxStyledTextCtrl_GetLineVisible 3171
-#define wxStyledTextCtrl_SetFoldExpanded 3172
-#define wxStyledTextCtrl_GetFoldExpanded 3173
-#define wxStyledTextCtrl_ToggleFold 3174
-#define wxStyledTextCtrl_EnsureVisible 3175
-#define wxStyledTextCtrl_SetFoldFlags 3176
-#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3177
-#define wxStyledTextCtrl_SetTabIndents 3178
-#define wxStyledTextCtrl_GetTabIndents 3179
-#define wxStyledTextCtrl_SetBackSpaceUnIndents 3180
-#define wxStyledTextCtrl_GetBackSpaceUnIndents 3181
-#define wxStyledTextCtrl_SetMouseDwellTime 3182
-#define wxStyledTextCtrl_GetMouseDwellTime 3183
-#define wxStyledTextCtrl_WordStartPosition 3184
-#define wxStyledTextCtrl_WordEndPosition 3185
-#define wxStyledTextCtrl_SetWrapMode 3186
-#define wxStyledTextCtrl_GetWrapMode 3187
-#define wxStyledTextCtrl_SetWrapVisualFlags 3188
-#define wxStyledTextCtrl_GetWrapVisualFlags 3189
-#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3190
-#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3191
-#define wxStyledTextCtrl_SetWrapStartIndent 3192
-#define wxStyledTextCtrl_GetWrapStartIndent 3193
-#define wxStyledTextCtrl_SetLayoutCache 3194
-#define wxStyledTextCtrl_GetLayoutCache 3195
-#define wxStyledTextCtrl_SetScrollWidth 3196
-#define wxStyledTextCtrl_GetScrollWidth 3197
-#define wxStyledTextCtrl_TextWidth 3198
-#define wxStyledTextCtrl_GetEndAtLastLine 3199
-#define wxStyledTextCtrl_TextHeight 3200
-#define wxStyledTextCtrl_SetUseVerticalScrollBar 3201
-#define wxStyledTextCtrl_GetUseVerticalScrollBar 3202
-#define wxStyledTextCtrl_AppendText 3203
-#define wxStyledTextCtrl_GetTwoPhaseDraw 3204
-#define wxStyledTextCtrl_SetTwoPhaseDraw 3205
-#define wxStyledTextCtrl_TargetFromSelection 3206
-#define wxStyledTextCtrl_LinesJoin 3207
-#define wxStyledTextCtrl_LinesSplit 3208
-#define wxStyledTextCtrl_SetFoldMarginColour 3209
-#define wxStyledTextCtrl_SetFoldMarginHiColour 3210
-#define wxStyledTextCtrl_LineDown 3211
-#define wxStyledTextCtrl_LineDownExtend 3212
-#define wxStyledTextCtrl_LineUp 3213
-#define wxStyledTextCtrl_LineUpExtend 3214
-#define wxStyledTextCtrl_CharLeft 3215
-#define wxStyledTextCtrl_CharLeftExtend 3216
-#define wxStyledTextCtrl_CharRight 3217
-#define wxStyledTextCtrl_CharRightExtend 3218
-#define wxStyledTextCtrl_WordLeft 3219
-#define wxStyledTextCtrl_WordLeftExtend 3220
-#define wxStyledTextCtrl_WordRight 3221
-#define wxStyledTextCtrl_WordRightExtend 3222
-#define wxStyledTextCtrl_Home 3223
-#define wxStyledTextCtrl_HomeExtend 3224
-#define wxStyledTextCtrl_LineEnd 3225
-#define wxStyledTextCtrl_LineEndExtend 3226
-#define wxStyledTextCtrl_DocumentStart 3227
-#define wxStyledTextCtrl_DocumentStartExtend 3228
-#define wxStyledTextCtrl_DocumentEnd 3229
-#define wxStyledTextCtrl_DocumentEndExtend 3230
-#define wxStyledTextCtrl_PageUp 3231
-#define wxStyledTextCtrl_PageUpExtend 3232
-#define wxStyledTextCtrl_PageDown 3233
-#define wxStyledTextCtrl_PageDownExtend 3234
-#define wxStyledTextCtrl_EditToggleOvertype 3235
-#define wxStyledTextCtrl_Cancel 3236
-#define wxStyledTextCtrl_DeleteBack 3237
-#define wxStyledTextCtrl_Tab 3238
-#define wxStyledTextCtrl_BackTab 3239
-#define wxStyledTextCtrl_NewLine 3240
-#define wxStyledTextCtrl_FormFeed 3241
-#define wxStyledTextCtrl_VCHome 3242
-#define wxStyledTextCtrl_VCHomeExtend 3243
-#define wxStyledTextCtrl_ZoomIn 3244
-#define wxStyledTextCtrl_ZoomOut 3245
-#define wxStyledTextCtrl_DelWordLeft 3246
-#define wxStyledTextCtrl_DelWordRight 3247
-#define wxStyledTextCtrl_LineCut 3248
-#define wxStyledTextCtrl_LineDelete 3249
-#define wxStyledTextCtrl_LineTranspose 3250
-#define wxStyledTextCtrl_LineDuplicate 3251
-#define wxStyledTextCtrl_LowerCase 3252
-#define wxStyledTextCtrl_UpperCase 3253
-#define wxStyledTextCtrl_LineScrollDown 3254
-#define wxStyledTextCtrl_LineScrollUp 3255
-#define wxStyledTextCtrl_DeleteBackNotLine 3256
-#define wxStyledTextCtrl_HomeDisplay 3257
-#define wxStyledTextCtrl_HomeDisplayExtend 3258
-#define wxStyledTextCtrl_LineEndDisplay 3259
-#define wxStyledTextCtrl_LineEndDisplayExtend 3260
-#define wxStyledTextCtrl_HomeWrapExtend 3261
-#define wxStyledTextCtrl_LineEndWrap 3262
-#define wxStyledTextCtrl_LineEndWrapExtend 3263
-#define wxStyledTextCtrl_VCHomeWrap 3264
-#define wxStyledTextCtrl_VCHomeWrapExtend 3265
-#define wxStyledTextCtrl_LineCopy 3266
-#define wxStyledTextCtrl_MoveCaretInsideView 3267
-#define wxStyledTextCtrl_LineLength 3268
-#define wxStyledTextCtrl_BraceHighlight 3269
-#define wxStyledTextCtrl_BraceBadLight 3270
-#define wxStyledTextCtrl_BraceMatch 3271
-#define wxStyledTextCtrl_GetViewEOL 3272
-#define wxStyledTextCtrl_SetViewEOL 3273
-#define wxStyledTextCtrl_SetModEventMask 3274
-#define wxStyledTextCtrl_GetEdgeColumn 3275
-#define wxStyledTextCtrl_SetEdgeColumn 3276
-#define wxStyledTextCtrl_SetEdgeMode 3277
-#define wxStyledTextCtrl_GetEdgeMode 3278
-#define wxStyledTextCtrl_GetEdgeColour 3279
-#define wxStyledTextCtrl_SetEdgeColour 3280
-#define wxStyledTextCtrl_SearchAnchor 3281
-#define wxStyledTextCtrl_SearchNext 3282
-#define wxStyledTextCtrl_SearchPrev 3283
-#define wxStyledTextCtrl_LinesOnScreen 3284
-#define wxStyledTextCtrl_UsePopUp 3285
-#define wxStyledTextCtrl_SelectionIsRectangle 3286
-#define wxStyledTextCtrl_SetZoom 3287
-#define wxStyledTextCtrl_GetZoom 3288
-#define wxStyledTextCtrl_GetModEventMask 3289
-#define wxStyledTextCtrl_SetSTCFocus 3290
-#define wxStyledTextCtrl_GetSTCFocus 3291
-#define wxStyledTextCtrl_SetStatus 3292
-#define wxStyledTextCtrl_GetStatus 3293
-#define wxStyledTextCtrl_SetMouseDownCaptures 3294
-#define wxStyledTextCtrl_GetMouseDownCaptures 3295
-#define wxStyledTextCtrl_SetSTCCursor 3296
-#define wxStyledTextCtrl_GetSTCCursor 3297
-#define wxStyledTextCtrl_SetControlCharSymbol 3298
-#define wxStyledTextCtrl_GetControlCharSymbol 3299
-#define wxStyledTextCtrl_WordPartLeft 3300
-#define wxStyledTextCtrl_WordPartLeftExtend 3301
-#define wxStyledTextCtrl_WordPartRight 3302
-#define wxStyledTextCtrl_WordPartRightExtend 3303
-#define wxStyledTextCtrl_SetVisiblePolicy 3304
-#define wxStyledTextCtrl_DelLineLeft 3305
-#define wxStyledTextCtrl_DelLineRight 3306
-#define wxStyledTextCtrl_GetXOffset 3307
-#define wxStyledTextCtrl_ChooseCaretX 3308
-#define wxStyledTextCtrl_SetXCaretPolicy 3309
-#define wxStyledTextCtrl_SetYCaretPolicy 3310
-#define wxStyledTextCtrl_GetPrintWrapMode 3311
-#define wxStyledTextCtrl_SetHotspotActiveForeground 3312
-#define wxStyledTextCtrl_SetHotspotActiveBackground 3313
-#define wxStyledTextCtrl_SetHotspotActiveUnderline 3314
-#define wxStyledTextCtrl_SetHotspotSingleLine 3315
-#define wxStyledTextCtrl_ParaDownExtend 3316
-#define wxStyledTextCtrl_ParaUp 3317
-#define wxStyledTextCtrl_ParaUpExtend 3318
-#define wxStyledTextCtrl_PositionBefore 3319
-#define wxStyledTextCtrl_PositionAfter 3320
-#define wxStyledTextCtrl_CopyRange 3321
-#define wxStyledTextCtrl_CopyText 3322
-#define wxStyledTextCtrl_SetSelectionMode 3323
-#define wxStyledTextCtrl_GetSelectionMode 3324
-#define wxStyledTextCtrl_LineDownRectExtend 3325
-#define wxStyledTextCtrl_LineUpRectExtend 3326
-#define wxStyledTextCtrl_CharLeftRectExtend 3327
-#define wxStyledTextCtrl_CharRightRectExtend 3328
-#define wxStyledTextCtrl_HomeRectExtend 3329
-#define wxStyledTextCtrl_VCHomeRectExtend 3330
-#define wxStyledTextCtrl_LineEndRectExtend 3331
-#define wxStyledTextCtrl_PageUpRectExtend 3332
-#define wxStyledTextCtrl_PageDownRectExtend 3333
-#define wxStyledTextCtrl_StutteredPageUp 3334
-#define wxStyledTextCtrl_StutteredPageUpExtend 3335
-#define wxStyledTextCtrl_StutteredPageDown 3336
-#define wxStyledTextCtrl_StutteredPageDownExtend 3337
-#define wxStyledTextCtrl_WordLeftEnd 3338
-#define wxStyledTextCtrl_WordLeftEndExtend 3339
-#define wxStyledTextCtrl_WordRightEnd 3340
-#define wxStyledTextCtrl_WordRightEndExtend 3341
-#define wxStyledTextCtrl_SetWhitespaceChars 3342
-#define wxStyledTextCtrl_SetCharsDefault 3343
-#define wxStyledTextCtrl_AutoCompGetCurrent 3344
-#define wxStyledTextCtrl_Allocate 3345
-#define wxStyledTextCtrl_FindColumn 3346
-#define wxStyledTextCtrl_GetCaretSticky 3347
-#define wxStyledTextCtrl_SetCaretSticky 3348
-#define wxStyledTextCtrl_ToggleCaretSticky 3349
-#define wxStyledTextCtrl_SetPasteConvertEndings 3350
-#define wxStyledTextCtrl_GetPasteConvertEndings 3351
-#define wxStyledTextCtrl_SelectionDuplicate 3352
-#define wxStyledTextCtrl_SetCaretLineBackAlpha 3353
-#define wxStyledTextCtrl_GetCaretLineBackAlpha 3354
-#define wxStyledTextCtrl_StartRecord 3355
-#define wxStyledTextCtrl_StopRecord 3356
-#define wxStyledTextCtrl_SetLexer 3357
-#define wxStyledTextCtrl_GetLexer 3358
-#define wxStyledTextCtrl_Colourise 3359
-#define wxStyledTextCtrl_SetProperty 3360
-#define wxStyledTextCtrl_SetKeyWords 3361
-#define wxStyledTextCtrl_SetLexerLanguage 3362
-#define wxStyledTextCtrl_GetProperty 3363
-#define wxStyledTextCtrl_GetStyleBitsNeeded 3364
-#define wxStyledTextCtrl_GetCurrentLine 3365
-#define wxStyledTextCtrl_StyleSetSpec 3366
-#define wxStyledTextCtrl_StyleSetFont 3367
-#define wxStyledTextCtrl_StyleSetFontAttr 3368
-#define wxStyledTextCtrl_StyleSetCharacterSet 3369
-#define wxStyledTextCtrl_StyleSetFontEncoding 3370
-#define wxStyledTextCtrl_CmdKeyExecute 3371
-#define wxStyledTextCtrl_SetMargins 3372
-#define wxStyledTextCtrl_GetSelection 3373
-#define wxStyledTextCtrl_PointFromPosition 3374
-#define wxStyledTextCtrl_ScrollToLine 3375
-#define wxStyledTextCtrl_ScrollToColumn 3376
-#define wxStyledTextCtrl_SetVScrollBar 3377
-#define wxStyledTextCtrl_SetHScrollBar 3378
-#define wxStyledTextCtrl_GetLastKeydownProcessed 3379
-#define wxStyledTextCtrl_SetLastKeydownProcessed 3380
-#define wxStyledTextCtrl_SaveFile 3381
-#define wxStyledTextCtrl_LoadFile 3382
-#define wxStyledTextCtrl_DoDragOver 3383
-#define wxStyledTextCtrl_DoDropText 3384
-#define wxStyledTextCtrl_GetUseAntiAliasing 3385
-#define wxStyledTextCtrl_AddTextRaw 3386
-#define wxStyledTextCtrl_InsertTextRaw 3387
-#define wxStyledTextCtrl_GetCurLineRaw 3388
-#define wxStyledTextCtrl_GetLineRaw 3389
-#define wxStyledTextCtrl_GetSelectedTextRaw 3390
-#define wxStyledTextCtrl_GetTextRangeRaw 3391
-#define wxStyledTextCtrl_SetTextRaw 3392
-#define wxStyledTextCtrl_GetTextRaw 3393
-#define wxStyledTextCtrl_AppendTextRaw 3394
-#define wxArtProvider_GetBitmap 3395
-#define wxArtProvider_GetIcon 3396
-#define wxTreeEvent_GetKeyCode 3397
-#define wxTreeEvent_GetItem 3398
-#define wxTreeEvent_GetKeyEvent 3399
-#define wxTreeEvent_GetLabel 3400
-#define wxTreeEvent_GetOldItem 3401
-#define wxTreeEvent_GetPoint 3402
-#define wxTreeEvent_IsEditCancelled 3403
-#define wxTreeEvent_SetToolTip 3404
-#define wxNotebookEvent_GetOldSelection 3405
-#define wxNotebookEvent_GetSelection 3406
-#define wxNotebookEvent_SetOldSelection 3407
-#define wxNotebookEvent_SetSelection 3408
-#define wxFileDataObject_new 3409
-#define wxFileDataObject_AddFile 3410
-#define wxFileDataObject_GetFilenames 3411
-#define wxFileDataObject_destroy 3412
-#define wxTextDataObject_new 3413
-#define wxTextDataObject_GetTextLength 3414
-#define wxTextDataObject_GetText 3415
-#define wxTextDataObject_SetText 3416
-#define wxTextDataObject_destroy 3417
-#define wxBitmapDataObject_new_1_1 3418
-#define wxBitmapDataObject_new_1_0 3419
-#define wxBitmapDataObject_GetBitmap 3420
-#define wxBitmapDataObject_SetBitmap 3421
-#define wxBitmapDataObject_destroy 3422
-#define wxClipboard_new 3424
-#define wxClipboard_destruct 3425
-#define wxClipboard_AddData 3426
-#define wxClipboard_Clear 3427
-#define wxClipboard_Close 3428
-#define wxClipboard_Flush 3429
-#define wxClipboard_GetData 3430
-#define wxClipboard_IsOpened 3431
-#define wxClipboard_Open 3432
-#define wxClipboard_SetData 3433
-#define wxClipboard_UsePrimarySelection 3435
-#define wxClipboard_IsSupported 3436
-#define wxClipboard_Get 3437
-#define wxSpinEvent_GetPosition 3438
-#define wxSpinEvent_SetPosition 3439
-#define wxSplitterWindow_new_0 3440
-#define wxSplitterWindow_new_2 3441
-#define wxSplitterWindow_destruct 3442
-#define wxSplitterWindow_Create 3443
-#define wxSplitterWindow_GetMinimumPaneSize 3444
-#define wxSplitterWindow_GetSashGravity 3445
-#define wxSplitterWindow_GetSashPosition 3446
-#define wxSplitterWindow_GetSplitMode 3447
-#define wxSplitterWindow_GetWindow1 3448
-#define wxSplitterWindow_GetWindow2 3449
-#define wxSplitterWindow_Initialize 3450
-#define wxSplitterWindow_IsSplit 3451
-#define wxSplitterWindow_ReplaceWindow 3452
-#define wxSplitterWindow_SetSashGravity 3453
-#define wxSplitterWindow_SetSashPosition 3454
-#define wxSplitterWindow_SetSashSize 3455
-#define wxSplitterWindow_SetMinimumPaneSize 3456
-#define wxSplitterWindow_SetSplitMode 3457
-#define wxSplitterWindow_SplitHorizontally 3458
-#define wxSplitterWindow_SplitVertically 3459
-#define wxSplitterWindow_Unsplit 3460
-#define wxSplitterWindow_UpdateSize 3461
-#define wxSplitterEvent_GetSashPosition 3462
-#define wxSplitterEvent_GetX 3463
-#define wxSplitterEvent_GetY 3464
-#define wxSplitterEvent_GetWindowBeingRemoved 3465
-#define wxSplitterEvent_SetSashPosition 3466
-#define wxHtmlWindow_new_0 3467
-#define wxHtmlWindow_new_2 3468
-#define wxHtmlWindow_AppendToPage 3469
-#define wxHtmlWindow_GetOpenedAnchor 3470
-#define wxHtmlWindow_GetOpenedPage 3471
-#define wxHtmlWindow_GetOpenedPageTitle 3472
-#define wxHtmlWindow_GetRelatedFrame 3473
-#define wxHtmlWindow_HistoryBack 3474
-#define wxHtmlWindow_HistoryCanBack 3475
-#define wxHtmlWindow_HistoryCanForward 3476
-#define wxHtmlWindow_HistoryClear 3477
-#define wxHtmlWindow_HistoryForward 3478
-#define wxHtmlWindow_LoadFile 3479
-#define wxHtmlWindow_LoadPage 3480
-#define wxHtmlWindow_SelectAll 3481
-#define wxHtmlWindow_SelectionToText 3482
-#define wxHtmlWindow_SelectLine 3483
-#define wxHtmlWindow_SelectWord 3484
-#define wxHtmlWindow_SetBorders 3485
-#define wxHtmlWindow_SetFonts 3486
-#define wxHtmlWindow_SetPage 3487
-#define wxHtmlWindow_SetRelatedFrame 3488
-#define wxHtmlWindow_SetRelatedStatusBar 3489
-#define wxHtmlWindow_ToText 3490
-#define wxHtmlWindow_destroy 3491
-#define wxHtmlLinkEvent_GetLinkInfo 3492
-#define wxSystemSettings_GetColour 3493
-#define wxSystemSettings_GetFont 3494
-#define wxSystemSettings_GetMetric 3495
-#define wxSystemSettings_GetScreenType 3496
-#define wxSystemOptions_GetOption 3497
-#define wxSystemOptions_GetOptionInt 3498
-#define wxSystemOptions_HasOption 3499
-#define wxSystemOptions_IsFalse 3500
-#define wxSystemOptions_SetOption_2_1 3501
-#define wxSystemOptions_SetOption_2_0 3502
-#define wxAuiNotebookEvent_SetSelection 3503
-#define wxAuiNotebookEvent_GetSelection 3504
-#define wxAuiNotebookEvent_SetOldSelection 3505
-#define wxAuiNotebookEvent_GetOldSelection 3506
-#define wxAuiNotebookEvent_SetDragSource 3507
-#define wxAuiNotebookEvent_GetDragSource 3508
-#define wxAuiManagerEvent_SetManager 3509
-#define wxAuiManagerEvent_GetManager 3510
-#define wxAuiManagerEvent_SetPane 3511
-#define wxAuiManagerEvent_GetPane 3512
-#define wxAuiManagerEvent_SetButton 3513
-#define wxAuiManagerEvent_GetButton 3514
-#define wxAuiManagerEvent_SetDC 3515
-#define wxAuiManagerEvent_GetDC 3516
-#define wxAuiManagerEvent_Veto 3517
-#define wxAuiManagerEvent_GetVeto 3518
-#define wxAuiManagerEvent_SetCanVeto 3519
-#define wxAuiManagerEvent_CanVeto 3520
-#define wxLogNull_new 3521
-#define wxLogNull_destroy 3522
-#define wxTaskBarIcon_new 3523
-#define wxTaskBarIcon_destruct 3524
-#define wxTaskBarIcon_PopupMenu 3525
-#define wxTaskBarIcon_RemoveIcon 3526
-#define wxTaskBarIcon_SetIcon 3527
-#define wxLocale_new_0 3528
-#define wxLocale_new_2 3530
-#define wxLocale_destruct 3531
-#define wxLocale_Init 3533
-#define wxLocale_AddCatalog_1 3534
-#define wxLocale_AddCatalog_3 3535
-#define wxLocale_AddCatalogLookupPathPrefix 3536
-#define wxLocale_GetCanonicalName 3537
-#define wxLocale_GetLanguage 3538
-#define wxLocale_GetLanguageName 3539
-#define wxLocale_GetLocale 3540
-#define wxLocale_GetName 3541
-#define wxLocale_GetString_2 3542
-#define wxLocale_GetString_4 3543
-#define wxLocale_GetHeaderValue 3544
-#define wxLocale_GetSysName 3545
-#define wxLocale_GetSystemEncoding 3546
-#define wxLocale_GetSystemEncodingName 3547
-#define wxLocale_GetSystemLanguage 3548
-#define wxLocale_IsLoaded 3549
-#define wxLocale_IsOk 3550
-#define wxActivateEvent_GetActive 3551
-#define wxPopupWindow_new_2 3553
-#define wxPopupWindow_new_0 3554
-#define wxPopupWindow_destruct 3556
-#define wxPopupWindow_Create 3557
-#define wxPopupWindow_Position 3558
-#define wxPopupTransientWindow_new_0 3559
-#define wxPopupTransientWindow_new_2 3560
-#define wxPopupTransientWindow_destruct 3561
-#define wxPopupTransientWindow_Popup 3562
-#define wxPopupTransientWindow_Dismiss 3563
+#define wxWindow_SetTransparent 284
+#define wxWindow_CanSetTransparent 285
+#define wxWindow_IsDoubleBuffered 286
+#define wxWindow_SetDoubleBuffered 287
+#define wxTopLevelWindow_GetIcon 288
+#define wxTopLevelWindow_GetIcons 289
+#define wxTopLevelWindow_GetTitle 290
+#define wxTopLevelWindow_IsActive 291
+#define wxTopLevelWindow_Iconize 292
+#define wxTopLevelWindow_IsFullScreen 293
+#define wxTopLevelWindow_IsIconized 294
+#define wxTopLevelWindow_IsMaximized 295
+#define wxTopLevelWindow_Maximize 296
+#define wxTopLevelWindow_RequestUserAttention 297
+#define wxTopLevelWindow_SetIcon 298
+#define wxTopLevelWindow_SetIcons 299
+#define wxTopLevelWindow_CenterOnScreen 300
+#define wxTopLevelWindow_CentreOnScreen 301
+#define wxTopLevelWindow_SetShape 303
+#define wxTopLevelWindow_SetTitle 304
+#define wxTopLevelWindow_ShowFullScreen 305
+#define wxFrame_new_4 307
+#define wxFrame_new_0 308
+#define wxFrame_destruct 310
+#define wxFrame_Create 311
+#define wxFrame_CreateStatusBar 312
+#define wxFrame_CreateToolBar 313
+#define wxFrame_GetClientAreaOrigin 314
+#define wxFrame_GetMenuBar 315
+#define wxFrame_GetStatusBar 316
+#define wxFrame_GetStatusBarPane 317
+#define wxFrame_GetToolBar 318
+#define wxFrame_ProcessCommand 319
+#define wxFrame_SendSizeEvent 320
+#define wxFrame_SetMenuBar 321
+#define wxFrame_SetStatusBar 322
+#define wxFrame_SetStatusBarPane 323
+#define wxFrame_SetStatusText 324
+#define wxFrame_SetStatusWidths 325
+#define wxFrame_SetToolBar 326
+#define wxMiniFrame_new_0 327
+#define wxMiniFrame_new_4 328
+#define wxMiniFrame_Create 329
+#define wxMiniFrame_destroy 330
+#define wxSplashScreen_new_0 331
+#define wxSplashScreen_new_6 332
+#define wxSplashScreen_destruct 333
+#define wxSplashScreen_GetSplashStyle 334
+#define wxSplashScreen_GetTimeout 335
+#define wxPanel_new_0 336
+#define wxPanel_new_6 337
+#define wxPanel_new_2 338
+#define wxPanel_destruct 339
+#define wxPanel_InitDialog 340
+#define wxPanel_SetFocusIgnoringChildren 341
+#define wxScrolledWindow_new_0 342
+#define wxScrolledWindow_new_2 343
+#define wxScrolledWindow_destruct 344
+#define wxScrolledWindow_CalcScrolledPosition_4 345
+#define wxScrolledWindow_CalcScrolledPosition_1 346
+#define wxScrolledWindow_CalcUnscrolledPosition_4 347
+#define wxScrolledWindow_CalcUnscrolledPosition_1 348
+#define wxScrolledWindow_EnableScrolling 349
+#define wxScrolledWindow_GetScrollPixelsPerUnit 350
+#define wxScrolledWindow_GetViewStart 351
+#define wxScrolledWindow_DoPrepareDC 352
+#define wxScrolledWindow_PrepareDC 353
+#define wxScrolledWindow_Scroll 354
+#define wxScrolledWindow_SetScrollbars 355
+#define wxScrolledWindow_SetScrollRate 356
+#define wxScrolledWindow_SetTargetWindow 357
+#define wxSashWindow_new_0 358
+#define wxSashWindow_new_2 359
+#define wxSashWindow_destruct 360
+#define wxSashWindow_GetSashVisible 361
+#define wxSashWindow_GetMaximumSizeX 362
+#define wxSashWindow_GetMaximumSizeY 363
+#define wxSashWindow_GetMinimumSizeX 364
+#define wxSashWindow_GetMinimumSizeY 365
+#define wxSashWindow_SetMaximumSizeX 366
+#define wxSashWindow_SetMaximumSizeY 367
+#define wxSashWindow_SetMinimumSizeX 368
+#define wxSashWindow_SetMinimumSizeY 369
+#define wxSashWindow_SetSashVisible 370
+#define wxSashLayoutWindow_new_0 371
+#define wxSashLayoutWindow_new_2 372
+#define wxSashLayoutWindow_Create 373
+#define wxSashLayoutWindow_GetAlignment 374
+#define wxSashLayoutWindow_GetOrientation 375
+#define wxSashLayoutWindow_SetAlignment 376
+#define wxSashLayoutWindow_SetDefaultSize 377
+#define wxSashLayoutWindow_SetOrientation 378
+#define wxSashLayoutWindow_destroy 379
+#define wxGrid_new_0 380
+#define wxGrid_new_3 381
+#define wxGrid_new_4 382
+#define wxGrid_destruct 383
+#define wxGrid_AppendCols 384
+#define wxGrid_AppendRows 385
+#define wxGrid_AutoSize 386
+#define wxGrid_AutoSizeColumn 387
+#define wxGrid_AutoSizeColumns 388
+#define wxGrid_AutoSizeRow 389
+#define wxGrid_AutoSizeRows 390
+#define wxGrid_BeginBatch 391
+#define wxGrid_BlockToDeviceRect 392
+#define wxGrid_CanDragColSize 393
+#define wxGrid_CanDragRowSize 394
+#define wxGrid_CanDragGridSize 395
+#define wxGrid_CanEnableCellControl 396
+#define wxGrid_CellToRect_2 397
+#define wxGrid_CellToRect_1 398
+#define wxGrid_ClearGrid 399
+#define wxGrid_ClearSelection 400
+#define wxGrid_CreateGrid 401
+#define wxGrid_DeleteCols 402
+#define wxGrid_DeleteRows 403
+#define wxGrid_DisableCellEditControl 404
+#define wxGrid_DisableDragColSize 405
+#define wxGrid_DisableDragGridSize 406
+#define wxGrid_DisableDragRowSize 407
+#define wxGrid_EnableCellEditControl 408
+#define wxGrid_EnableDragColSize 409
+#define wxGrid_EnableDragGridSize 410
+#define wxGrid_EnableDragRowSize 411
+#define wxGrid_EnableEditing 412
+#define wxGrid_EnableGridLines 413
+#define wxGrid_EndBatch 414
+#define wxGrid_Fit 415
+#define wxGrid_ForceRefresh 416
+#define wxGrid_GetBatchCount 417
+#define wxGrid_GetCellAlignment 418
+#define wxGrid_GetCellBackgroundColour 419
+#define wxGrid_GetCellEditor 420
+#define wxGrid_GetCellFont 421
+#define wxGrid_GetCellRenderer 422
+#define wxGrid_GetCellTextColour 423
+#define wxGrid_GetCellValue_2 424
+#define wxGrid_GetCellValue_1 425
+#define wxGrid_GetColLabelAlignment 426
+#define wxGrid_GetColLabelSize 427
+#define wxGrid_GetColLabelValue 428
+#define wxGrid_GetColMinimalAcceptableWidth 429
+#define wxGrid_GetDefaultCellAlignment 430
+#define wxGrid_GetDefaultCellBackgroundColour 431
+#define wxGrid_GetDefaultCellFont 432
+#define wxGrid_GetDefaultCellTextColour 433
+#define wxGrid_GetDefaultColLabelSize 434
+#define wxGrid_GetDefaultColSize 435
+#define wxGrid_GetDefaultEditor 436
+#define wxGrid_GetDefaultEditorForCell_2 437
+#define wxGrid_GetDefaultEditorForCell_1 438
+#define wxGrid_GetDefaultEditorForType 439
+#define wxGrid_GetDefaultRenderer 440
+#define wxGrid_GetDefaultRendererForCell 441
+#define wxGrid_GetDefaultRendererForType 442
+#define wxGrid_GetDefaultRowLabelSize 443
+#define wxGrid_GetDefaultRowSize 444
+#define wxGrid_GetGridCursorCol 445
+#define wxGrid_GetGridCursorRow 446
+#define wxGrid_GetGridLineColour 447
+#define wxGrid_GridLinesEnabled 448
+#define wxGrid_GetLabelBackgroundColour 449
+#define wxGrid_GetLabelFont 450
+#define wxGrid_GetLabelTextColour 451
+#define wxGrid_GetNumberCols 452
+#define wxGrid_GetNumberRows 453
+#define wxGrid_GetOrCreateCellAttr 454
+#define wxGrid_GetRowMinimalAcceptableHeight 455
+#define wxGrid_GetRowLabelAlignment 456
+#define wxGrid_GetRowLabelSize 457
+#define wxGrid_GetRowLabelValue 458
+#define wxGrid_GetRowSize 459
+#define wxGrid_GetScrollLineX 460
+#define wxGrid_GetScrollLineY 461
+#define wxGrid_GetSelectedCells 462
+#define wxGrid_GetSelectedCols 463
+#define wxGrid_GetSelectedRows 464
+#define wxGrid_GetSelectionBackground 465
+#define wxGrid_GetSelectionBlockTopLeft 466
+#define wxGrid_GetSelectionBlockBottomRight 467
+#define wxGrid_GetSelectionForeground 468
+#define wxGrid_GetViewWidth 469
+#define wxGrid_GetGridWindow 470
+#define wxGrid_GetGridRowLabelWindow 471
+#define wxGrid_GetGridColLabelWindow 472
+#define wxGrid_GetGridCornerLabelWindow 473
+#define wxGrid_HideCellEditControl 474
+#define wxGrid_InsertCols 475
+#define wxGrid_InsertRows 476
+#define wxGrid_IsCellEditControlEnabled 477
+#define wxGrid_IsCurrentCellReadOnly 478
+#define wxGrid_IsEditable 479
+#define wxGrid_IsInSelection_2 480
+#define wxGrid_IsInSelection_1 481
+#define wxGrid_IsReadOnly 482
+#define wxGrid_IsSelection 483
+#define wxGrid_IsVisible_3 484
+#define wxGrid_IsVisible_2 485
+#define wxGrid_MakeCellVisible_2 486
+#define wxGrid_MakeCellVisible_1 487
+#define wxGrid_MoveCursorDown 488
+#define wxGrid_MoveCursorLeft 489
+#define wxGrid_MoveCursorRight 490
+#define wxGrid_MoveCursorUp 491
+#define wxGrid_MoveCursorDownBlock 492
+#define wxGrid_MoveCursorLeftBlock 493
+#define wxGrid_MoveCursorRightBlock 494
+#define wxGrid_MoveCursorUpBlock 495
+#define wxGrid_MovePageDown 496
+#define wxGrid_MovePageUp 497
+#define wxGrid_RegisterDataType 498
+#define wxGrid_SaveEditControlValue 499
+#define wxGrid_SelectAll 500
+#define wxGrid_SelectBlock_5 501
+#define wxGrid_SelectBlock_3 502
+#define wxGrid_SelectCol 503
+#define wxGrid_SelectRow 504
+#define wxGrid_SetCellAlignment_4 505
+#define wxGrid_SetCellAlignment_3 506
+#define wxGrid_SetCellAlignment_1 507
+#define wxGrid_SetCellBackgroundColour_3_0 508
+#define wxGrid_SetCellBackgroundColour_1 509
+#define wxGrid_SetCellBackgroundColour_3_1 510
+#define wxGrid_SetCellEditor 511
+#define wxGrid_SetCellFont 512
+#define wxGrid_SetCellRenderer 513
+#define wxGrid_SetCellTextColour_3_0 514
+#define wxGrid_SetCellTextColour_3_1 515
+#define wxGrid_SetCellTextColour_1 516
+#define wxGrid_SetCellValue_3_0 517
+#define wxGrid_SetCellValue_2 518
+#define wxGrid_SetCellValue_3_1 519
+#define wxGrid_SetColAttr 520
+#define wxGrid_SetColFormatBool 521
+#define wxGrid_SetColFormatNumber 522
+#define wxGrid_SetColFormatFloat 523
+#define wxGrid_SetColFormatCustom 524
+#define wxGrid_SetColLabelAlignment 525
+#define wxGrid_SetColLabelSize 526
+#define wxGrid_SetColLabelValue 527
+#define wxGrid_SetColMinimalWidth 528
+#define wxGrid_SetColMinimalAcceptableWidth 529
+#define wxGrid_SetColSize 530
+#define wxGrid_SetDefaultCellAlignment 531
+#define wxGrid_SetDefaultCellBackgroundColour 532
+#define wxGrid_SetDefaultCellFont 533
+#define wxGrid_SetDefaultCellTextColour 534
+#define wxGrid_SetDefaultEditor 535
+#define wxGrid_SetDefaultRenderer 536
+#define wxGrid_SetDefaultColSize 537
+#define wxGrid_SetDefaultRowSize 538
+#define wxGrid_SetGridCursor 539
+#define wxGrid_SetGridLineColour 540
+#define wxGrid_SetLabelBackgroundColour 541
+#define wxGrid_SetLabelFont 542
+#define wxGrid_SetLabelTextColour 543
+#define wxGrid_SetMargins 544
+#define wxGrid_SetReadOnly 545
+#define wxGrid_SetRowAttr 546
+#define wxGrid_SetRowLabelAlignment 547
+#define wxGrid_SetRowLabelSize 548
+#define wxGrid_SetRowLabelValue 549
+#define wxGrid_SetRowMinimalHeight 550
+#define wxGrid_SetRowMinimalAcceptableHeight 551
+#define wxGrid_SetRowSize 552
+#define wxGrid_SetScrollLineX 553
+#define wxGrid_SetScrollLineY 554
+#define wxGrid_SetSelectionBackground 555
+#define wxGrid_SetSelectionForeground 556
+#define wxGrid_SetSelectionMode 557
+#define wxGrid_ShowCellEditControl 558
+#define wxGrid_XToCol 559
+#define wxGrid_XToEdgeOfCol 560
+#define wxGrid_YToEdgeOfRow 561
+#define wxGrid_YToRow 562
+#define wxGridCellRenderer_Draw 563
+#define wxGridCellRenderer_GetBestSize 564
+#define wxGridCellEditor_Create 565
+#define wxGridCellEditor_IsCreated 566
+#define wxGridCellEditor_SetSize 567
+#define wxGridCellEditor_Show 568
+#define wxGridCellEditor_PaintBackground 569
+#define wxGridCellEditor_BeginEdit 570
+#define wxGridCellEditor_EndEdit 571
+#define wxGridCellEditor_Reset 572
+#define wxGridCellEditor_StartingKey 573
+#define wxGridCellEditor_StartingClick 574
+#define wxGridCellEditor_HandleReturn 575
+#define wxGridCellBoolRenderer_new 576
+#define wxGridCellBoolRenderer_destroy 577
+#define wxGridCellBoolEditor_new 578
+#define wxGridCellBoolEditor_IsTrueValue 579
+#define wxGridCellBoolEditor_UseStringValues 580
+#define wxGridCellBoolEditor_destroy 581
+#define wxGridCellFloatRenderer_new 582
+#define wxGridCellFloatRenderer_GetPrecision 583
+#define wxGridCellFloatRenderer_GetWidth 584
+#define wxGridCellFloatRenderer_SetParameters 585
+#define wxGridCellFloatRenderer_SetPrecision 586
+#define wxGridCellFloatRenderer_SetWidth 587
+#define wxGridCellFloatRenderer_destroy 588
+#define wxGridCellFloatEditor_new 589
+#define wxGridCellFloatEditor_SetParameters 590
+#define wxGridCellFloatEditor_destroy 591
+#define wxGridCellStringRenderer_new 592
+#define wxGridCellStringRenderer_destroy 593
+#define wxGridCellTextEditor_new 594
+#define wxGridCellTextEditor_SetParameters 595
+#define wxGridCellTextEditor_destroy 596
+#define wxGridCellChoiceEditor_new 598
+#define wxGridCellChoiceEditor_SetParameters 599
+#define wxGridCellChoiceEditor_destroy 600
+#define wxGridCellNumberRenderer_new 601
+#define wxGridCellNumberRenderer_destroy 602
+#define wxGridCellNumberEditor_new 603
+#define wxGridCellNumberEditor_GetValue 604
+#define wxGridCellNumberEditor_SetParameters 605
+#define wxGridCellNumberEditor_destroy 606
+#define wxGridCellAttr_SetTextColour 607
+#define wxGridCellAttr_SetBackgroundColour 608
+#define wxGridCellAttr_SetFont 609
+#define wxGridCellAttr_SetAlignment 610
+#define wxGridCellAttr_SetReadOnly 611
+#define wxGridCellAttr_SetRenderer 612
+#define wxGridCellAttr_SetEditor 613
+#define wxGridCellAttr_HasTextColour 614
+#define wxGridCellAttr_HasBackgroundColour 615
+#define wxGridCellAttr_HasFont 616
+#define wxGridCellAttr_HasAlignment 617
+#define wxGridCellAttr_HasRenderer 618
+#define wxGridCellAttr_HasEditor 619
+#define wxGridCellAttr_GetTextColour 620
+#define wxGridCellAttr_GetBackgroundColour 621
+#define wxGridCellAttr_GetFont 622
+#define wxGridCellAttr_GetAlignment 623
+#define wxGridCellAttr_GetRenderer 624
+#define wxGridCellAttr_GetEditor 625
+#define wxGridCellAttr_IsReadOnly 626
+#define wxGridCellAttr_SetDefAttr 627
+#define wxDC_Blit 628
+#define wxDC_CalcBoundingBox 629
+#define wxDC_Clear 630
+#define wxDC_ComputeScaleAndOrigin 631
+#define wxDC_CrossHair 632
+#define wxDC_DestroyClippingRegion 633
+#define wxDC_DeviceToLogicalX 634
+#define wxDC_DeviceToLogicalXRel 635
+#define wxDC_DeviceToLogicalY 636
+#define wxDC_DeviceToLogicalYRel 637
+#define wxDC_DrawArc 638
+#define wxDC_DrawBitmap 639
+#define wxDC_DrawCheckMark 640
+#define wxDC_DrawCircle 641
+#define wxDC_DrawEllipse_2 643
+#define wxDC_DrawEllipse_1 644
+#define wxDC_DrawEllipticArc 645
+#define wxDC_DrawIcon 646
+#define wxDC_DrawLabel 647
+#define wxDC_DrawLine 648
+#define wxDC_DrawLines 649
+#define wxDC_DrawPolygon 651
+#define wxDC_DrawPoint 653
+#define wxDC_DrawRectangle_2 655
+#define wxDC_DrawRectangle_1 656
+#define wxDC_DrawRotatedText 657
+#define wxDC_DrawRoundedRectangle_3 659
+#define wxDC_DrawRoundedRectangle_2 660
+#define wxDC_DrawText 661
+#define wxDC_EndDoc 662
+#define wxDC_EndPage 663
+#define wxDC_FloodFill 664
+#define wxDC_GetBackground 665
+#define wxDC_GetBackgroundMode 666
+#define wxDC_GetBrush 667
+#define wxDC_GetCharHeight 668
+#define wxDC_GetCharWidth 669
+#define wxDC_GetClippingBox 670
+#define wxDC_GetFont 672
+#define wxDC_GetLayoutDirection 673
+#define wxDC_GetLogicalFunction 674
+#define wxDC_GetMapMode 675
+#define wxDC_GetMultiLineTextExtent_4 676
+#define wxDC_GetMultiLineTextExtent_1 677
+#define wxDC_GetPartialTextExtents 678
+#define wxDC_GetPen 679
+#define wxDC_GetPixel 680
+#define wxDC_GetPPI 681
+#define wxDC_GetSize 683
+#define wxDC_GetSizeMM 685
+#define wxDC_GetTextBackground 686
+#define wxDC_GetTextExtent_4 687
+#define wxDC_GetTextExtent_1 688
+#define wxDC_GetTextForeground 690
+#define wxDC_GetUserScale 691
+#define wxDC_GradientFillConcentric_3 692
+#define wxDC_GradientFillConcentric_4 693
+#define wxDC_GradientFillLinear 694
+#define wxDC_LogicalToDeviceX 695
+#define wxDC_LogicalToDeviceXRel 696
+#define wxDC_LogicalToDeviceY 697
+#define wxDC_LogicalToDeviceYRel 698
+#define wxDC_MaxX 699
+#define wxDC_MaxY 700
+#define wxDC_MinX 701
+#define wxDC_MinY 702
+#define wxDC_IsOk 703
+#define wxDC_ResetBoundingBox 704
+#define wxDC_SetAxisOrientation 705
+#define wxDC_SetBackground 706
+#define wxDC_SetBackgroundMode 707
+#define wxDC_SetBrush 708
+#define wxDC_SetClippingRegion_2 710
+#define wxDC_SetClippingRegion_1_1 711
+#define wxDC_SetClippingRegion_1_0 712
+#define wxDC_SetDeviceOrigin 713
+#define wxDC_SetFont 714
+#define wxDC_SetLayoutDirection 715
+#define wxDC_SetLogicalFunction 716
+#define wxDC_SetMapMode 717
+#define wxDC_SetPalette 718
+#define wxDC_SetPen 719
+#define wxDC_SetTextBackground 720
+#define wxDC_SetTextForeground 721
+#define wxDC_SetUserScale 722
+#define wxDC_StartDoc 723
+#define wxDC_StartPage 724
+#define wxMirrorDC_new 725
+#define wxMirrorDC_destroy 726
+#define wxScreenDC_new 727
+#define wxScreenDC_destruct 728
+#define wxPostScriptDC_new_0 729
+#define wxPostScriptDC_new_1 730
+#define wxPostScriptDC_destruct 731
+#define wxPostScriptDC_SetResolution 732
+#define wxPostScriptDC_GetResolution 733
+#define wxWindowDC_new_0 734
+#define wxWindowDC_new_1 735
+#define wxWindowDC_destruct 736
+#define wxClientDC_new_0 737
+#define wxClientDC_new_1 738
+#define wxClientDC_destroy 739
+#define wxPaintDC_new_0 740
+#define wxPaintDC_new_1 741
+#define wxPaintDC_destroy 742
+#define wxMemoryDC_new_1_0 744
+#define wxMemoryDC_new_1_1 745
+#define wxMemoryDC_new_0 746
+#define wxMemoryDC_destruct 748
+#define wxMemoryDC_SelectObject 749
+#define wxMemoryDC_SelectObjectAsSource 750
+#define wxBufferedDC_new_0 751
+#define wxBufferedDC_new_2 752
+#define wxBufferedDC_new_3 753
+#define wxBufferedDC_destruct 754
+#define wxBufferedDC_Init_2 755
+#define wxBufferedDC_Init_3 756
+#define wxBufferedPaintDC_new_3 757
+#define wxBufferedPaintDC_new_2 758
+#define wxBufferedPaintDC_destruct 759
+#define wxGraphicsObject_destruct 760
+#define wxGraphicsObject_GetRenderer 761
+#define wxGraphicsObject_IsNull 762
+#define wxGraphicsContext_destruct 763
+#define wxGraphicsContext_Create_1_1 764
+#define wxGraphicsContext_Create_1_0 765
+#define wxGraphicsContext_Create_0 766
+#define wxGraphicsContext_CreatePen 767
+#define wxGraphicsContext_CreateBrush 768
+#define wxGraphicsContext_CreateRadialGradientBrush 769
+#define wxGraphicsContext_CreateLinearGradientBrush 770
+#define wxGraphicsContext_CreateFont 771
+#define wxGraphicsContext_CreateMatrix 772
+#define wxGraphicsContext_CreatePath 773
+#define wxGraphicsContext_Clip_1 774
+#define wxGraphicsContext_Clip_4 775
+#define wxGraphicsContext_ResetClip 776
+#define wxGraphicsContext_DrawBitmap 777
+#define wxGraphicsContext_DrawEllipse 778
+#define wxGraphicsContext_DrawIcon 779
+#define wxGraphicsContext_DrawLines 780
+#define wxGraphicsContext_DrawPath 781
+#define wxGraphicsContext_DrawRectangle 782
+#define wxGraphicsContext_DrawRoundedRectangle 783
+#define wxGraphicsContext_DrawText_3 784
+#define wxGraphicsContext_DrawText_4_0 785
+#define wxGraphicsContext_DrawText_4_1 786
+#define wxGraphicsContext_DrawText_5 787
+#define wxGraphicsContext_FillPath 788
+#define wxGraphicsContext_StrokePath 789
+#define wxGraphicsContext_GetPartialTextExtents 790
+#define wxGraphicsContext_GetTextExtent 791
+#define wxGraphicsContext_Rotate 792
+#define wxGraphicsContext_Scale 793
+#define wxGraphicsContext_Translate 794
+#define wxGraphicsContext_GetTransform 795
+#define wxGraphicsContext_SetTransform 796
+#define wxGraphicsContext_ConcatTransform 797
+#define wxGraphicsContext_SetBrush_1_1 798
+#define wxGraphicsContext_SetBrush_1_0 799
+#define wxGraphicsContext_SetFont_1 800
+#define wxGraphicsContext_SetFont_2 801
+#define wxGraphicsContext_SetPen_1_0 802
+#define wxGraphicsContext_SetPen_1_1 803
+#define wxGraphicsContext_StrokeLine 804
+#define wxGraphicsContext_StrokeLines 805
+#define wxGraphicsMatrix_Concat 807
+#define wxGraphicsMatrix_Get 809
+#define wxGraphicsMatrix_Invert 810
+#define wxGraphicsMatrix_IsEqual 811
+#define wxGraphicsMatrix_IsIdentity 813
+#define wxGraphicsMatrix_Rotate 814
+#define wxGraphicsMatrix_Scale 815
+#define wxGraphicsMatrix_Translate 816
+#define wxGraphicsMatrix_Set 817
+#define wxGraphicsMatrix_TransformPoint 818
+#define wxGraphicsMatrix_TransformDistance 819
+#define wxGraphicsPath_MoveToPoint_2 820
+#define wxGraphicsPath_MoveToPoint_1 821
+#define wxGraphicsPath_AddArc_6 822
+#define wxGraphicsPath_AddArc_5 823
+#define wxGraphicsPath_AddArcToPoint 824
+#define wxGraphicsPath_AddCircle 825
+#define wxGraphicsPath_AddCurveToPoint_6 826
+#define wxGraphicsPath_AddCurveToPoint_3 827
+#define wxGraphicsPath_AddEllipse 828
+#define wxGraphicsPath_AddLineToPoint_2 829
+#define wxGraphicsPath_AddLineToPoint_1 830
+#define wxGraphicsPath_AddPath 831
+#define wxGraphicsPath_AddQuadCurveToPoint 832
+#define wxGraphicsPath_AddRectangle 833
+#define wxGraphicsPath_AddRoundedRectangle 834
+#define wxGraphicsPath_CloseSubpath 835
+#define wxGraphicsPath_Contains_3 836
+#define wxGraphicsPath_Contains_2 837
+#define wxGraphicsPath_GetBox 839
+#define wxGraphicsPath_GetCurrentPoint 841
+#define wxGraphicsPath_Transform 842
+#define wxGraphicsRenderer_GetDefaultRenderer 843
+#define wxGraphicsRenderer_CreateContext_1_1 844
+#define wxGraphicsRenderer_CreateContext_1_0 845
+#define wxGraphicsRenderer_CreatePen 846
+#define wxGraphicsRenderer_CreateBrush 847
+#define wxGraphicsRenderer_CreateLinearGradientBrush 848
+#define wxGraphicsRenderer_CreateRadialGradientBrush 849
+#define wxGraphicsRenderer_CreateFont 850
+#define wxGraphicsRenderer_CreateMatrix 851
+#define wxGraphicsRenderer_CreatePath 852
+#define wxMenuBar_new_1 854
+#define wxMenuBar_new_0 856
+#define wxMenuBar_destruct 858
+#define wxMenuBar_Append 859
+#define wxMenuBar_Check 860
+#define wxMenuBar_Enable_2 861
+#define wxMenuBar_Enable_1 862
+#define wxMenuBar_EnableTop 863
+#define wxMenuBar_FindMenu 864
+#define wxMenuBar_FindMenuItem 865
+#define wxMenuBar_FindItem 866
+#define wxMenuBar_GetHelpString 867
+#define wxMenuBar_GetLabel_1 868
+#define wxMenuBar_GetLabel_0 869
+#define wxMenuBar_GetLabelTop 870
+#define wxMenuBar_GetMenu 871
+#define wxMenuBar_GetMenuCount 872
+#define wxMenuBar_Insert 873
+#define wxMenuBar_IsChecked 874
+#define wxMenuBar_IsEnabled_1 875
+#define wxMenuBar_IsEnabled_0 876
+#define wxMenuBar_Remove 877
+#define wxMenuBar_Replace 878
+#define wxMenuBar_SetHelpString 879
+#define wxMenuBar_SetLabel_2 880
+#define wxMenuBar_SetLabel_1 881
+#define wxMenuBar_SetLabelTop 882
+#define wxControl_GetLabel 883
+#define wxControl_SetLabel 884
+#define wxControlWithItems_Append_1 885
+#define wxControlWithItems_Append_2 886
+#define wxControlWithItems_appendStrings_1 887
+#define wxControlWithItems_Clear 888
+#define wxControlWithItems_Delete 889
+#define wxControlWithItems_FindString 890
+#define wxControlWithItems_getClientData 891
+#define wxControlWithItems_setClientData 892
+#define wxControlWithItems_GetCount 893
+#define wxControlWithItems_GetSelection 894
+#define wxControlWithItems_GetString 895
+#define wxControlWithItems_GetStringSelection 896
+#define wxControlWithItems_Insert_2 897
+#define wxControlWithItems_Insert_3 898
+#define wxControlWithItems_IsEmpty 899
+#define wxControlWithItems_Select 900
+#define wxControlWithItems_SetSelection 901
+#define wxControlWithItems_SetString 902
+#define wxControlWithItems_SetStringSelection 903
+#define wxMenu_new_2 906
+#define wxMenu_new_1 907
+#define wxMenu_destruct 909
+#define wxMenu_Append_3 910
+#define wxMenu_Append_1 911
+#define wxMenu_Append_4_0 912
+#define wxMenu_Append_4_1 913
+#define wxMenu_AppendCheckItem 914
+#define wxMenu_AppendRadioItem 915
+#define wxMenu_AppendSeparator 916
+#define wxMenu_Break 917
+#define wxMenu_Check 918
+#define wxMenu_Delete_1_0 919
+#define wxMenu_Delete_1_1 920
+#define wxMenu_Destroy_1_0 921
+#define wxMenu_Destroy_1_1 922
+#define wxMenu_Enable 923
+#define wxMenu_FindItem_1 924
+#define wxMenu_FindItem_2 925
+#define wxMenu_FindItemByPosition 926
+#define wxMenu_GetHelpString 927
+#define wxMenu_GetLabel 928
+#define wxMenu_GetMenuItemCount 929
+#define wxMenu_GetMenuItems 930
+#define wxMenu_GetTitle 932
+#define wxMenu_Insert_2 933
+#define wxMenu_Insert_3 934
+#define wxMenu_Insert_5_1 935
+#define wxMenu_Insert_5_0 936
+#define wxMenu_InsertCheckItem 937
+#define wxMenu_InsertRadioItem 938
+#define wxMenu_InsertSeparator 939
+#define wxMenu_IsChecked 940
+#define wxMenu_IsEnabled 941
+#define wxMenu_Prepend_1 942
+#define wxMenu_Prepend_2 943
+#define wxMenu_Prepend_4_1 944
+#define wxMenu_Prepend_4_0 945
+#define wxMenu_PrependCheckItem 946
+#define wxMenu_PrependRadioItem 947
+#define wxMenu_PrependSeparator 948
+#define wxMenu_Remove_1_0 949
+#define wxMenu_Remove_1_1 950
+#define wxMenu_SetHelpString 951
+#define wxMenu_SetLabel 952
+#define wxMenu_SetTitle 953
+#define wxMenuItem_new 954
+#define wxMenuItem_destruct 956
+#define wxMenuItem_Check 957
+#define wxMenuItem_Enable 958
+#define wxMenuItem_GetBitmap 959
+#define wxMenuItem_GetHelp 960
+#define wxMenuItem_GetId 961
+#define wxMenuItem_GetKind 962
+#define wxMenuItem_GetLabel 963
+#define wxMenuItem_GetLabelFromText 964
+#define wxMenuItem_GetMenu 965
+#define wxMenuItem_GetText 966
+#define wxMenuItem_GetSubMenu 967
+#define wxMenuItem_IsCheckable 968
+#define wxMenuItem_IsChecked 969
+#define wxMenuItem_IsEnabled 970
+#define wxMenuItem_IsSeparator 971
+#define wxMenuItem_IsSubMenu 972
+#define wxMenuItem_SetBitmap 973
+#define wxMenuItem_SetHelp 974
+#define wxMenuItem_SetMenu 975
+#define wxMenuItem_SetSubMenu 976
+#define wxMenuItem_SetText 977
+#define wxToolBar_AddControl 978
+#define wxToolBar_AddSeparator 979
+#define wxToolBar_AddTool_5 980
+#define wxToolBar_AddTool_4_0 981
+#define wxToolBar_AddTool_1 982
+#define wxToolBar_AddTool_4_1 983
+#define wxToolBar_AddTool_3 984
+#define wxToolBar_AddTool_6 985
+#define wxToolBar_AddCheckTool 986
+#define wxToolBar_AddRadioTool 987
+#define wxToolBar_AddStretchableSpace 988
+#define wxToolBar_InsertStretchableSpace 989
+#define wxToolBar_DeleteTool 990
+#define wxToolBar_DeleteToolByPos 991
+#define wxToolBar_EnableTool 992
+#define wxToolBar_FindById 993
+#define wxToolBar_FindControl 994
+#define wxToolBar_FindToolForPosition 995
+#define wxToolBar_GetToolSize 996
+#define wxToolBar_GetToolBitmapSize 997
+#define wxToolBar_GetMargins 998
+#define wxToolBar_GetToolEnabled 999
+#define wxToolBar_GetToolLongHelp 1000
+#define wxToolBar_GetToolPacking 1001
+#define wxToolBar_GetToolPos 1002
+#define wxToolBar_GetToolSeparation 1003
+#define wxToolBar_GetToolShortHelp 1004
+#define wxToolBar_GetToolState 1005
+#define wxToolBar_InsertControl 1006
+#define wxToolBar_InsertSeparator 1007
+#define wxToolBar_InsertTool_5 1008
+#define wxToolBar_InsertTool_2 1009
+#define wxToolBar_InsertTool_4 1010
+#define wxToolBar_Realize 1011
+#define wxToolBar_RemoveTool 1012
+#define wxToolBar_SetMargins 1013
+#define wxToolBar_SetToolBitmapSize 1014
+#define wxToolBar_SetToolLongHelp 1015
+#define wxToolBar_SetToolPacking 1016
+#define wxToolBar_SetToolShortHelp 1017
+#define wxToolBar_SetToolSeparation 1018
+#define wxToolBar_ToggleTool 1019
+#define wxStatusBar_new_0 1021
+#define wxStatusBar_new_2 1022
+#define wxStatusBar_destruct 1024
+#define wxStatusBar_Create 1025
+#define wxStatusBar_GetFieldRect 1026
+#define wxStatusBar_GetFieldsCount 1027
+#define wxStatusBar_GetStatusText 1028
+#define wxStatusBar_PopStatusText 1029
+#define wxStatusBar_PushStatusText 1030
+#define wxStatusBar_SetFieldsCount 1031
+#define wxStatusBar_SetMinHeight 1032
+#define wxStatusBar_SetStatusText 1033
+#define wxStatusBar_SetStatusWidths 1034
+#define wxStatusBar_SetStatusStyles 1035
+#define wxBitmap_new_0 1036
+#define wxBitmap_new_3 1037
+#define wxBitmap_new_4 1038
+#define wxBitmap_new_2_0 1039
+#define wxBitmap_new_2_1 1040
+#define wxBitmap_destruct 1041
+#define wxBitmap_ConvertToImage 1042
+#define wxBitmap_CopyFromIcon 1043
+#define wxBitmap_Create 1044
+#define wxBitmap_GetDepth 1045
+#define wxBitmap_GetHeight 1046
+#define wxBitmap_GetPalette 1047
+#define wxBitmap_GetMask 1048
+#define wxBitmap_GetWidth 1049
+#define wxBitmap_GetSubBitmap 1050
+#define wxBitmap_LoadFile 1051
+#define wxBitmap_Ok 1052
+#define wxBitmap_SaveFile 1053
+#define wxBitmap_SetDepth 1054
+#define wxBitmap_SetHeight 1055
+#define wxBitmap_SetMask 1056
+#define wxBitmap_SetPalette 1057
+#define wxBitmap_SetWidth 1058
+#define wxIcon_new_0 1059
+#define wxIcon_new_2 1060
+#define wxIcon_new_1 1061
+#define wxIcon_CopyFromBitmap 1062
+#define wxIcon_destroy 1063
+#define wxIconBundle_new_0 1064
+#define wxIconBundle_new_2 1065
+#define wxIconBundle_new_1_0 1066
+#define wxIconBundle_new_1_1 1067
+#define wxIconBundle_destruct 1068
+#define wxIconBundle_AddIcon_2 1069
+#define wxIconBundle_AddIcon_1 1070
+#define wxIconBundle_GetIcon_1_1 1071
+#define wxIconBundle_GetIcon_1_0 1072
+#define wxCursor_new_0 1073
+#define wxCursor_new_1_0 1074
+#define wxCursor_new_1_1 1075
+#define wxCursor_new_4 1076
+#define wxCursor_destruct 1077
+#define wxCursor_Ok 1078
+#define wxMask_new_0 1079
+#define wxMask_new_2_1 1080
+#define wxMask_new_2_0 1081
+#define wxMask_new_1 1082
+#define wxMask_destruct 1083
+#define wxMask_Create_2_1 1084
+#define wxMask_Create_2_0 1085
+#define wxMask_Create_1 1086
+#define wxImage_new_0 1087
+#define wxImage_new_3_0 1088
+#define wxImage_new_4 1089
+#define wxImage_new_5 1090
+#define wxImage_new_2 1091
+#define wxImage_new_3_1 1092
+#define wxImage_Blur 1093
+#define wxImage_BlurHorizontal 1094
+#define wxImage_BlurVertical 1095
+#define wxImage_ConvertAlphaToMask 1096
+#define wxImage_ConvertToGreyscale 1097
+#define wxImage_ConvertToMono 1098
+#define wxImage_Copy 1099
+#define wxImage_Create_3 1100
+#define wxImage_Create_4 1101
+#define wxImage_Create_5 1102
+#define wxImage_Destroy 1103
+#define wxImage_FindFirstUnusedColour 1104
+#define wxImage_GetImageExtWildcard 1105
+#define wxImage_GetAlpha_2 1106
+#define wxImage_GetAlpha_0 1107
+#define wxImage_GetBlue 1108
+#define wxImage_GetData 1109
+#define wxImage_GetGreen 1110
+#define wxImage_GetImageCount 1111
+#define wxImage_GetHeight 1112
+#define wxImage_GetMaskBlue 1113
+#define wxImage_GetMaskGreen 1114
+#define wxImage_GetMaskRed 1115
+#define wxImage_GetOrFindMaskColour 1116
+#define wxImage_GetPalette 1117
+#define wxImage_GetRed 1118
+#define wxImage_GetSubImage 1119
+#define wxImage_GetWidth 1120
+#define wxImage_HasAlpha 1121
+#define wxImage_HasMask 1122
+#define wxImage_GetOption 1123
+#define wxImage_GetOptionInt 1124
+#define wxImage_HasOption 1125
+#define wxImage_InitAlpha 1126
+#define wxImage_InitStandardHandlers 1127
+#define wxImage_IsTransparent 1128
+#define wxImage_LoadFile_2 1129
+#define wxImage_LoadFile_3 1130
+#define wxImage_Ok 1131
+#define wxImage_RemoveHandler 1132
+#define wxImage_Mirror 1133
+#define wxImage_Replace 1134
+#define wxImage_Rescale 1135
+#define wxImage_Resize 1136
+#define wxImage_Rotate 1137
+#define wxImage_RotateHue 1138
+#define wxImage_Rotate90 1139
+#define wxImage_SaveFile_1 1140
+#define wxImage_SaveFile_2_0 1141
+#define wxImage_SaveFile_2_1 1142
+#define wxImage_Scale 1143
+#define wxImage_Size 1144
+#define wxImage_SetAlpha_3 1145
+#define wxImage_SetAlpha_2 1146
+#define wxImage_SetData_2 1147
+#define wxImage_SetData_4 1148
+#define wxImage_SetMask 1149
+#define wxImage_SetMaskColour 1150
+#define wxImage_SetMaskFromImage 1151
+#define wxImage_SetOption_2_1 1152
+#define wxImage_SetOption_2_0 1153
+#define wxImage_SetPalette 1154
+#define wxImage_SetRGB_5 1155
+#define wxImage_SetRGB_4 1156
+#define wxImage_destroy 1157
+#define wxBrush_new_0 1158
+#define wxBrush_new_2 1159
+#define wxBrush_new_1 1160
+#define wxBrush_destruct 1162
+#define wxBrush_GetColour 1163
+#define wxBrush_GetStipple 1164
+#define wxBrush_GetStyle 1165
+#define wxBrush_IsHatch 1166
+#define wxBrush_IsOk 1167
+#define wxBrush_SetColour_1 1168
+#define wxBrush_SetColour_3 1169
+#define wxBrush_SetStipple 1170
+#define wxBrush_SetStyle 1171
+#define wxPen_new_0 1172
+#define wxPen_new_2 1173
+#define wxPen_destruct 1174
+#define wxPen_GetCap 1175
+#define wxPen_GetColour 1176
+#define wxPen_GetJoin 1177
+#define wxPen_GetStyle 1178
+#define wxPen_GetWidth 1179
+#define wxPen_IsOk 1180
+#define wxPen_SetCap 1181
+#define wxPen_SetColour_1 1182
+#define wxPen_SetColour_3 1183
+#define wxPen_SetJoin 1184
+#define wxPen_SetStyle 1185
+#define wxPen_SetWidth 1186
+#define wxRegion_new_0 1187
+#define wxRegion_new_4 1188
+#define wxRegion_new_2 1189
+#define wxRegion_new_1_1 1190
+#define wxRegion_new_1_0 1192
+#define wxRegion_destruct 1194
+#define wxRegion_Clear 1195
+#define wxRegion_Contains_2 1196
+#define wxRegion_Contains_1_0 1197
+#define wxRegion_Contains_4 1198
+#define wxRegion_Contains_1_1 1199
+#define wxRegion_ConvertToBitmap 1200
+#define wxRegion_GetBox 1201
+#define wxRegion_Intersect_4 1202
+#define wxRegion_Intersect_1_1 1203
+#define wxRegion_Intersect_1_0 1204
+#define wxRegion_IsEmpty 1205
+#define wxRegion_Subtract_4 1206
+#define wxRegion_Subtract_1_1 1207
+#define wxRegion_Subtract_1_0 1208
+#define wxRegion_Offset_2 1209
+#define wxRegion_Offset_1 1210
+#define wxRegion_Union_4 1211
+#define wxRegion_Union_1_2 1212
+#define wxRegion_Union_1_1 1213
+#define wxRegion_Union_1_0 1214
+#define wxRegion_Union_3 1215
+#define wxRegion_Xor_4 1216
+#define wxRegion_Xor_1_1 1217
+#define wxRegion_Xor_1_0 1218
+#define wxAcceleratorTable_new_0 1219
+#define wxAcceleratorTable_new_2 1220
+#define wxAcceleratorTable_destruct 1221
+#define wxAcceleratorTable_Ok 1222
+#define wxAcceleratorEntry_new_1_0 1223
+#define wxAcceleratorEntry_new_1_1 1224
+#define wxAcceleratorEntry_GetCommand 1225
+#define wxAcceleratorEntry_GetFlags 1226
+#define wxAcceleratorEntry_GetKeyCode 1227
+#define wxAcceleratorEntry_Set 1228
+#define wxAcceleratorEntry_destroy 1229
+#define wxCaret_new_3 1234
+#define wxCaret_new_2 1235
+#define wxCaret_destruct 1237
+#define wxCaret_Create_3 1238
+#define wxCaret_Create_2 1239
+#define wxCaret_GetBlinkTime 1240
+#define wxCaret_GetPosition 1242
+#define wxCaret_GetSize 1244
+#define wxCaret_GetWindow 1245
+#define wxCaret_Hide 1246
+#define wxCaret_IsOk 1247
+#define wxCaret_IsVisible 1248
+#define wxCaret_Move_2 1249
+#define wxCaret_Move_1 1250
+#define wxCaret_SetBlinkTime 1251
+#define wxCaret_SetSize_2 1252
+#define wxCaret_SetSize_1 1253
+#define wxCaret_Show 1254
+#define wxSizer_Add_2_1 1255
+#define wxSizer_Add_2_0 1256
+#define wxSizer_Add_3 1257
+#define wxSizer_Add_2_3 1258
+#define wxSizer_Add_2_2 1259
+#define wxSizer_AddSpacer 1260
+#define wxSizer_AddStretchSpacer 1261
+#define wxSizer_CalcMin 1262
+#define wxSizer_Clear 1263
+#define wxSizer_Detach_1_2 1264
+#define wxSizer_Detach_1_1 1265
+#define wxSizer_Detach_1_0 1266
+#define wxSizer_Fit 1267
+#define wxSizer_FitInside 1268
+#define wxSizer_GetChildren 1269
+#define wxSizer_GetItem_2_1 1270
+#define wxSizer_GetItem_2_0 1271
+#define wxSizer_GetItem_1 1272
+#define wxSizer_GetSize 1273
+#define wxSizer_GetPosition 1274
+#define wxSizer_GetMinSize 1275
+#define wxSizer_Hide_2_0 1276
+#define wxSizer_Hide_2_1 1277
+#define wxSizer_Hide_1 1278
+#define wxSizer_Insert_3_1 1279
+#define wxSizer_Insert_3_0 1280
+#define wxSizer_Insert_4 1281
+#define wxSizer_Insert_3_3 1282
+#define wxSizer_Insert_3_2 1283
+#define wxSizer_Insert_2 1284
+#define wxSizer_InsertSpacer 1285
+#define wxSizer_InsertStretchSpacer 1286
+#define wxSizer_IsShown_1_2 1287
+#define wxSizer_IsShown_1_1 1288
+#define wxSizer_IsShown_1_0 1289
+#define wxSizer_Layout 1290
+#define wxSizer_Prepend_2_1 1291
+#define wxSizer_Prepend_2_0 1292
+#define wxSizer_Prepend_3 1293
+#define wxSizer_Prepend_2_3 1294
+#define wxSizer_Prepend_2_2 1295
+#define wxSizer_Prepend_1 1296
+#define wxSizer_PrependSpacer 1297
+#define wxSizer_PrependStretchSpacer 1298
+#define wxSizer_RecalcSizes 1299
+#define wxSizer_Remove_1_1 1300
+#define wxSizer_Remove_1_0 1301
+#define wxSizer_Replace_3_1 1302
+#define wxSizer_Replace_3_0 1303
+#define wxSizer_Replace_2 1304
+#define wxSizer_SetDimension 1305
+#define wxSizer_SetMinSize_2 1306
+#define wxSizer_SetMinSize_1 1307
+#define wxSizer_SetItemMinSize_3_2 1308
+#define wxSizer_SetItemMinSize_2_2 1309
+#define wxSizer_SetItemMinSize_3_1 1310
+#define wxSizer_SetItemMinSize_2_1 1311
+#define wxSizer_SetItemMinSize_3_0 1312
+#define wxSizer_SetItemMinSize_2_0 1313
+#define wxSizer_SetSizeHints 1314
+#define wxSizer_SetVirtualSizeHints 1315
+#define wxSizer_Show_2_2 1316
+#define wxSizer_Show_2_1 1317
+#define wxSizer_Show_2_0 1318
+#define wxSizer_Show_1 1319
+#define wxSizerFlags_new 1320
+#define wxSizerFlags_Align 1321
+#define wxSizerFlags_Border_2 1322
+#define wxSizerFlags_Border_1 1323
+#define wxSizerFlags_Center 1324
+#define wxSizerFlags_Centre 1325
+#define wxSizerFlags_Expand 1326
+#define wxSizerFlags_Left 1327
+#define wxSizerFlags_Proportion 1328
+#define wxSizerFlags_Right 1329
+#define wxSizerFlags_destroy 1330
+#define wxSizerItem_new_5_1 1331
+#define wxSizerItem_new_2_1 1332
+#define wxSizerItem_new_5_0 1333
+#define wxSizerItem_new_2_0 1334
+#define wxSizerItem_new_6 1335
+#define wxSizerItem_new_3 1336
+#define wxSizerItem_new_0 1337
+#define wxSizerItem_destruct 1338
+#define wxSizerItem_CalcMin 1339
+#define wxSizerItem_DeleteWindows 1340
+#define wxSizerItem_DetachSizer 1341
+#define wxSizerItem_GetBorder 1342
+#define wxSizerItem_GetFlag 1343
+#define wxSizerItem_GetMinSize 1344
+#define wxSizerItem_GetPosition 1345
+#define wxSizerItem_GetProportion 1346
+#define wxSizerItem_GetRatio 1347
+#define wxSizerItem_GetRect 1348
+#define wxSizerItem_GetSize 1349
+#define wxSizerItem_GetSizer 1350
+#define wxSizerItem_GetSpacer 1351
+#define wxSizerItem_GetUserData 1352
+#define wxSizerItem_GetWindow 1353
+#define wxSizerItem_IsSizer 1354
+#define wxSizerItem_IsShown 1355
+#define wxSizerItem_IsSpacer 1356
+#define wxSizerItem_IsWindow 1357
+#define wxSizerItem_SetBorder 1358
+#define wxSizerItem_SetDimension 1359
+#define wxSizerItem_SetFlag 1360
+#define wxSizerItem_SetInitSize 1361
+#define wxSizerItem_SetMinSize_1 1362
+#define wxSizerItem_SetMinSize_2 1363
+#define wxSizerItem_SetProportion 1364
+#define wxSizerItem_SetRatio_2 1365
+#define wxSizerItem_SetRatio_1_1 1366
+#define wxSizerItem_SetRatio_1_0 1367
+#define wxSizerItem_SetSizer 1368
+#define wxSizerItem_SetSpacer_1 1369
+#define wxSizerItem_SetSpacer_2 1370
+#define wxSizerItem_SetWindow 1371
+#define wxSizerItem_Show 1372
+#define wxBoxSizer_new 1373
+#define wxBoxSizer_GetOrientation 1374
+#define wxBoxSizer_destroy 1375
+#define wxStaticBoxSizer_new_2 1376
+#define wxStaticBoxSizer_new_3 1377
+#define wxStaticBoxSizer_GetStaticBox 1378
+#define wxStaticBoxSizer_destroy 1379
+#define wxGridSizer_new_4 1380
+#define wxGridSizer_new_2 1381
+#define wxGridSizer_GetCols 1382
+#define wxGridSizer_GetHGap 1383
+#define wxGridSizer_GetRows 1384
+#define wxGridSizer_GetVGap 1385
+#define wxGridSizer_SetCols 1386
+#define wxGridSizer_SetHGap 1387
+#define wxGridSizer_SetRows 1388
+#define wxGridSizer_SetVGap 1389
+#define wxGridSizer_destroy 1390
+#define wxFlexGridSizer_new_4 1391
+#define wxFlexGridSizer_new_2 1392
+#define wxFlexGridSizer_AddGrowableCol 1393
+#define wxFlexGridSizer_AddGrowableRow 1394
+#define wxFlexGridSizer_GetFlexibleDirection 1395
+#define wxFlexGridSizer_GetNonFlexibleGrowMode 1396
+#define wxFlexGridSizer_RemoveGrowableCol 1397
+#define wxFlexGridSizer_RemoveGrowableRow 1398
+#define wxFlexGridSizer_SetFlexibleDirection 1399
+#define wxFlexGridSizer_SetNonFlexibleGrowMode 1400
+#define wxFlexGridSizer_destroy 1401
+#define wxGridBagSizer_new 1402
+#define wxGridBagSizer_Add_3_2 1403
+#define wxGridBagSizer_Add_3_1 1404
+#define wxGridBagSizer_Add_4 1405
+#define wxGridBagSizer_Add_1_0 1406
+#define wxGridBagSizer_Add_2_1 1407
+#define wxGridBagSizer_Add_2_0 1408
+#define wxGridBagSizer_Add_3_0 1409
+#define wxGridBagSizer_Add_1_1 1410
+#define wxGridBagSizer_CalcMin 1411
+#define wxGridBagSizer_CheckForIntersection_2 1412
+#define wxGridBagSizer_CheckForIntersection_3 1413
+#define wxGridBagSizer_FindItem_1_1 1414
+#define wxGridBagSizer_FindItem_1_0 1415
+#define wxGridBagSizer_FindItemAtPoint 1416
+#define wxGridBagSizer_FindItemAtPosition 1417
+#define wxGridBagSizer_FindItemWithData 1418
+#define wxGridBagSizer_GetCellSize 1419
+#define wxGridBagSizer_GetEmptyCellSize 1420
+#define wxGridBagSizer_GetItemPosition_1_2 1421
+#define wxGridBagSizer_GetItemPosition_1_1 1422
+#define wxGridBagSizer_GetItemPosition_1_0 1423
+#define wxGridBagSizer_GetItemSpan_1_2 1424
+#define wxGridBagSizer_GetItemSpan_1_1 1425
+#define wxGridBagSizer_GetItemSpan_1_0 1426
+#define wxGridBagSizer_SetEmptyCellSize 1427
+#define wxGridBagSizer_SetItemPosition_2_2 1428
+#define wxGridBagSizer_SetItemPosition_2_1 1429
+#define wxGridBagSizer_SetItemPosition_2_0 1430
+#define wxGridBagSizer_SetItemSpan_2_2 1431
+#define wxGridBagSizer_SetItemSpan_2_1 1432
+#define wxGridBagSizer_SetItemSpan_2_0 1433
+#define wxGridBagSizer_destroy 1434
+#define wxStdDialogButtonSizer_new 1435
+#define wxStdDialogButtonSizer_AddButton 1436
+#define wxStdDialogButtonSizer_Realize 1437
+#define wxStdDialogButtonSizer_SetAffirmativeButton 1438
+#define wxStdDialogButtonSizer_SetCancelButton 1439
+#define wxStdDialogButtonSizer_SetNegativeButton 1440
+#define wxStdDialogButtonSizer_destroy 1441
+#define wxFont_new_0 1442
+#define wxFont_new_1 1443
+#define wxFont_new_5 1444
+#define wxFont_destruct 1446
+#define wxFont_IsFixedWidth 1447
+#define wxFont_GetDefaultEncoding 1448
+#define wxFont_GetFaceName 1449
+#define wxFont_GetFamily 1450
+#define wxFont_GetNativeFontInfoDesc 1451
+#define wxFont_GetNativeFontInfoUserDesc 1452
+#define wxFont_GetPointSize 1453
+#define wxFont_GetStyle 1454
+#define wxFont_GetUnderlined 1455
+#define wxFont_GetWeight 1456
+#define wxFont_Ok 1457
+#define wxFont_SetDefaultEncoding 1458
+#define wxFont_SetFaceName 1459
+#define wxFont_SetFamily 1460
+#define wxFont_SetPointSize 1461
+#define wxFont_SetStyle 1462
+#define wxFont_SetUnderlined 1463
+#define wxFont_SetWeight 1464
+#define wxToolTip_Enable 1465
+#define wxToolTip_SetDelay 1466
+#define wxToolTip_new 1467
+#define wxToolTip_SetTip 1468
+#define wxToolTip_GetTip 1469
+#define wxToolTip_GetWindow 1470
+#define wxToolTip_destroy 1471
+#define wxButton_new_3 1473
+#define wxButton_new_0 1474
+#define wxButton_destruct 1475
+#define wxButton_Create 1476
+#define wxButton_GetDefaultSize 1477
+#define wxButton_SetDefault 1478
+#define wxButton_SetLabel 1479
+#define wxBitmapButton_new_4 1481
+#define wxBitmapButton_new_0 1482
+#define wxBitmapButton_Create 1483
+#define wxBitmapButton_GetBitmapDisabled 1484
+#define wxBitmapButton_GetBitmapFocus 1486
+#define wxBitmapButton_GetBitmapLabel 1488
+#define wxBitmapButton_GetBitmapSelected 1490
+#define wxBitmapButton_SetBitmapDisabled 1492
+#define wxBitmapButton_SetBitmapFocus 1493
+#define wxBitmapButton_SetBitmapLabel 1494
+#define wxBitmapButton_SetBitmapSelected 1495
+#define wxBitmapButton_destroy 1496
+#define wxToggleButton_new_0 1497
+#define wxToggleButton_new_4 1498
+#define wxToggleButton_Create 1499
+#define wxToggleButton_GetValue 1500
+#define wxToggleButton_SetValue 1501
+#define wxToggleButton_destroy 1502
+#define wxCalendarCtrl_new_0 1503
+#define wxCalendarCtrl_new_3 1504
+#define wxCalendarCtrl_Create 1505
+#define wxCalendarCtrl_destruct 1506
+#define wxCalendarCtrl_SetDate 1507
+#define wxCalendarCtrl_GetDate 1508
+#define wxCalendarCtrl_EnableYearChange 1509
+#define wxCalendarCtrl_EnableMonthChange 1510
+#define wxCalendarCtrl_EnableHolidayDisplay 1511
+#define wxCalendarCtrl_SetHeaderColours 1512
+#define wxCalendarCtrl_GetHeaderColourFg 1513
+#define wxCalendarCtrl_GetHeaderColourBg 1514
+#define wxCalendarCtrl_SetHighlightColours 1515
+#define wxCalendarCtrl_GetHighlightColourFg 1516
+#define wxCalendarCtrl_GetHighlightColourBg 1517
+#define wxCalendarCtrl_SetHolidayColours 1518
+#define wxCalendarCtrl_GetHolidayColourFg 1519
+#define wxCalendarCtrl_GetHolidayColourBg 1520
+#define wxCalendarCtrl_GetAttr 1521
+#define wxCalendarCtrl_SetAttr 1522
+#define wxCalendarCtrl_SetHoliday 1523
+#define wxCalendarCtrl_ResetAttr 1524
+#define wxCalendarCtrl_HitTest 1525
+#define wxCalendarDateAttr_new_0 1526
+#define wxCalendarDateAttr_new_2_1 1527
+#define wxCalendarDateAttr_new_2_0 1528
+#define wxCalendarDateAttr_SetTextColour 1529
+#define wxCalendarDateAttr_SetBackgroundColour 1530
+#define wxCalendarDateAttr_SetBorderColour 1531
+#define wxCalendarDateAttr_SetFont 1532
+#define wxCalendarDateAttr_SetBorder 1533
+#define wxCalendarDateAttr_SetHoliday 1534
+#define wxCalendarDateAttr_HasTextColour 1535
+#define wxCalendarDateAttr_HasBackgroundColour 1536
+#define wxCalendarDateAttr_HasBorderColour 1537
+#define wxCalendarDateAttr_HasFont 1538
+#define wxCalendarDateAttr_HasBorder 1539
+#define wxCalendarDateAttr_IsHoliday 1540
+#define wxCalendarDateAttr_GetTextColour 1541
+#define wxCalendarDateAttr_GetBackgroundColour 1542
+#define wxCalendarDateAttr_GetBorderColour 1543
+#define wxCalendarDateAttr_GetFont 1544
+#define wxCalendarDateAttr_GetBorder 1545
+#define wxCalendarDateAttr_destroy 1546
+#define wxCheckBox_new_4 1548
+#define wxCheckBox_new_0 1549
+#define wxCheckBox_Create 1550
+#define wxCheckBox_GetValue 1551
+#define wxCheckBox_Get3StateValue 1552
+#define wxCheckBox_Is3rdStateAllowedForUser 1553
+#define wxCheckBox_Is3State 1554
+#define wxCheckBox_IsChecked 1555
+#define wxCheckBox_SetValue 1556
+#define wxCheckBox_Set3StateValue 1557
+#define wxCheckBox_destroy 1558
+#define wxCheckListBox_new_0 1559
+#define wxCheckListBox_new_3 1561
+#define wxCheckListBox_Check 1562
+#define wxCheckListBox_IsChecked 1563
+#define wxCheckListBox_destroy 1564
+#define wxChoice_new_3 1567
+#define wxChoice_new_0 1568
+#define wxChoice_destruct 1570
+#define wxChoice_Create 1572
+#define wxChoice_Delete 1573
+#define wxChoice_GetColumns 1574
+#define wxChoice_SetColumns 1575
+#define wxComboBox_new_0 1576
+#define wxComboBox_new_3 1578
+#define wxComboBox_destruct 1579
+#define wxComboBox_Create 1581
+#define wxComboBox_CanCopy 1582
+#define wxComboBox_CanCut 1583
+#define wxComboBox_CanPaste 1584
+#define wxComboBox_CanRedo 1585
+#define wxComboBox_CanUndo 1586
+#define wxComboBox_Copy 1587
+#define wxComboBox_Cut 1588
+#define wxComboBox_GetInsertionPoint 1589
+#define wxComboBox_GetLastPosition 1590
+#define wxComboBox_GetValue 1591
+#define wxComboBox_Paste 1592
+#define wxComboBox_Redo 1593
+#define wxComboBox_Replace 1594
+#define wxComboBox_Remove 1595
+#define wxComboBox_SetInsertionPoint 1596
+#define wxComboBox_SetInsertionPointEnd 1597
+#define wxComboBox_SetSelection_1 1598
+#define wxComboBox_SetSelection_2 1599
+#define wxComboBox_SetValue 1600
+#define wxComboBox_Undo 1601
+#define wxGauge_new_0 1602
+#define wxGauge_new_4 1603
+#define wxGauge_Create 1604
+#define wxGauge_GetBezelFace 1605
+#define wxGauge_GetRange 1606
+#define wxGauge_GetShadowWidth 1607
+#define wxGauge_GetValue 1608
+#define wxGauge_IsVertical 1609
+#define wxGauge_SetBezelFace 1610
+#define wxGauge_SetRange 1611
+#define wxGauge_SetShadowWidth 1612
+#define wxGauge_SetValue 1613
+#define wxGauge_Pulse 1614
+#define wxGauge_destroy 1615
+#define wxGenericDirCtrl_new_0 1616
+#define wxGenericDirCtrl_new_2 1617
+#define wxGenericDirCtrl_destruct 1618
+#define wxGenericDirCtrl_Create 1619
+#define wxGenericDirCtrl_Init 1620
+#define wxGenericDirCtrl_CollapseTree 1621
+#define wxGenericDirCtrl_ExpandPath 1622
+#define wxGenericDirCtrl_GetDefaultPath 1623
+#define wxGenericDirCtrl_GetPath 1624
+#define wxGenericDirCtrl_GetFilePath 1625
+#define wxGenericDirCtrl_GetFilter 1626
+#define wxGenericDirCtrl_GetFilterIndex 1627
+#define wxGenericDirCtrl_GetRootId 1628
+#define wxGenericDirCtrl_GetTreeCtrl 1629
+#define wxGenericDirCtrl_ReCreateTree 1630
+#define wxGenericDirCtrl_SetDefaultPath 1631
+#define wxGenericDirCtrl_SetFilter 1632
+#define wxGenericDirCtrl_SetFilterIndex 1633
+#define wxGenericDirCtrl_SetPath 1634
+#define wxStaticBox_new_4 1636
+#define wxStaticBox_new_0 1637
+#define wxStaticBox_Create 1638
+#define wxStaticBox_destroy 1639
+#define wxStaticLine_new_2 1641
+#define wxStaticLine_new_0 1642
+#define wxStaticLine_Create 1643
+#define wxStaticLine_IsVertical 1644
+#define wxStaticLine_GetDefaultSize 1645
+#define wxStaticLine_destroy 1646
+#define wxListBox_new_3 1649
+#define wxListBox_new_0 1650
+#define wxListBox_destruct 1652
+#define wxListBox_Create 1654
+#define wxListBox_Deselect 1655
+#define wxListBox_GetSelections 1656
+#define wxListBox_InsertItems 1657
+#define wxListBox_IsSelected 1658
+#define wxListBox_Set 1659
+#define wxListBox_HitTest 1660
+#define wxListBox_SetFirstItem_1_0 1661
+#define wxListBox_SetFirstItem_1_1 1662
+#define wxListCtrl_new_0 1663
+#define wxListCtrl_new_2 1664
+#define wxListCtrl_Arrange 1665
+#define wxListCtrl_AssignImageList 1666
+#define wxListCtrl_ClearAll 1667
+#define wxListCtrl_Create 1668
+#define wxListCtrl_DeleteAllItems 1669
+#define wxListCtrl_DeleteColumn 1670
+#define wxListCtrl_DeleteItem 1671
+#define wxListCtrl_EditLabel 1672
+#define wxListCtrl_EnsureVisible 1673
+#define wxListCtrl_FindItem_3_0 1674
+#define wxListCtrl_FindItem_3_1 1675
+#define wxListCtrl_GetColumn 1676
+#define wxListCtrl_GetColumnCount 1677
+#define wxListCtrl_GetColumnWidth 1678
+#define wxListCtrl_GetCountPerPage 1679
+#define wxListCtrl_GetEditControl 1680
+#define wxListCtrl_GetImageList 1681
+#define wxListCtrl_GetItem 1682
+#define wxListCtrl_GetItemBackgroundColour 1683
+#define wxListCtrl_GetItemCount 1684
+#define wxListCtrl_GetItemData 1685
+#define wxListCtrl_GetItemFont 1686
+#define wxListCtrl_GetItemPosition 1687
+#define wxListCtrl_GetItemRect 1688
+#define wxListCtrl_GetItemSpacing 1689
+#define wxListCtrl_GetItemState 1690
+#define wxListCtrl_GetItemText 1691
+#define wxListCtrl_GetItemTextColour 1692
+#define wxListCtrl_GetNextItem 1693
+#define wxListCtrl_GetSelectedItemCount 1694
+#define wxListCtrl_GetTextColour 1695
+#define wxListCtrl_GetTopItem 1696
+#define wxListCtrl_GetViewRect 1697
+#define wxListCtrl_HitTest 1698
+#define wxListCtrl_InsertColumn_2 1699
+#define wxListCtrl_InsertColumn_3 1700
+#define wxListCtrl_InsertItem_1 1701
+#define wxListCtrl_InsertItem_2_1 1702
+#define wxListCtrl_InsertItem_2_0 1703
+#define wxListCtrl_InsertItem_3 1704
+#define wxListCtrl_RefreshItem 1705
+#define wxListCtrl_RefreshItems 1706
+#define wxListCtrl_ScrollList 1707
+#define wxListCtrl_SetBackgroundColour 1708
+#define wxListCtrl_SetColumn 1709
+#define wxListCtrl_SetColumnWidth 1710
+#define wxListCtrl_SetImageList 1711
+#define wxListCtrl_SetItem_1 1712
+#define wxListCtrl_SetItem_4 1713
+#define wxListCtrl_SetItemBackgroundColour 1714
+#define wxListCtrl_SetItemCount 1715
+#define wxListCtrl_SetItemData 1716
+#define wxListCtrl_SetItemFont 1717
+#define wxListCtrl_SetItemImage 1718
+#define wxListCtrl_SetItemColumnImage 1719
+#define wxListCtrl_SetItemPosition 1720
+#define wxListCtrl_SetItemState 1721
+#define wxListCtrl_SetItemText 1722
+#define wxListCtrl_SetItemTextColour 1723
+#define wxListCtrl_SetSingleStyle 1724
+#define wxListCtrl_SetTextColour 1725
+#define wxListCtrl_SetWindowStyleFlag 1726
+#define wxListCtrl_SortItems 1727
+#define wxListCtrl_destroy 1728
+#define wxListView_ClearColumnImage 1729
+#define wxListView_Focus 1730
+#define wxListView_GetFirstSelected 1731
+#define wxListView_GetFocusedItem 1732
+#define wxListView_GetNextSelected 1733
+#define wxListView_IsSelected 1734
+#define wxListView_Select 1735
+#define wxListView_SetColumnImage 1736
+#define wxListItem_new_0 1737
+#define wxListItem_new_1 1738
+#define wxListItem_destruct 1739
+#define wxListItem_Clear 1740
+#define wxListItem_GetAlign 1741
+#define wxListItem_GetBackgroundColour 1742
+#define wxListItem_GetColumn 1743
+#define wxListItem_GetFont 1744
+#define wxListItem_GetId 1745
+#define wxListItem_GetImage 1746
+#define wxListItem_GetMask 1747
+#define wxListItem_GetState 1748
+#define wxListItem_GetText 1749
+#define wxListItem_GetTextColour 1750
+#define wxListItem_GetWidth 1751
+#define wxListItem_SetAlign 1752
+#define wxListItem_SetBackgroundColour 1753
+#define wxListItem_SetColumn 1754
+#define wxListItem_SetFont 1755
+#define wxListItem_SetId 1756
+#define wxListItem_SetImage 1757
+#define wxListItem_SetMask 1758
+#define wxListItem_SetState 1759
+#define wxListItem_SetStateMask 1760
+#define wxListItem_SetText 1761
+#define wxListItem_SetTextColour 1762
+#define wxListItem_SetWidth 1763
+#define wxListItemAttr_new_0 1764
+#define wxListItemAttr_new_3 1765
+#define wxListItemAttr_GetBackgroundColour 1766
+#define wxListItemAttr_GetFont 1767
+#define wxListItemAttr_GetTextColour 1768
+#define wxListItemAttr_HasBackgroundColour 1769
+#define wxListItemAttr_HasFont 1770
+#define wxListItemAttr_HasTextColour 1771
+#define wxListItemAttr_SetBackgroundColour 1772
+#define wxListItemAttr_SetFont 1773
+#define wxListItemAttr_SetTextColour 1774
+#define wxListItemAttr_destroy 1775
+#define wxImageList_new_0 1776
+#define wxImageList_new_3 1777
+#define wxImageList_Add_1 1778
+#define wxImageList_Add_2_0 1779
+#define wxImageList_Add_2_1 1780
+#define wxImageList_Create 1781
+#define wxImageList_Draw 1783
+#define wxImageList_GetBitmap 1784
+#define wxImageList_GetIcon 1785
+#define wxImageList_GetImageCount 1786
+#define wxImageList_GetSize 1787
+#define wxImageList_Remove 1788
+#define wxImageList_RemoveAll 1789
+#define wxImageList_Replace_2 1790
+#define wxImageList_Replace_3 1791
+#define wxImageList_destroy 1792
+#define wxTextAttr_new_0 1793
+#define wxTextAttr_new_2 1794
+#define wxTextAttr_GetAlignment 1795
+#define wxTextAttr_GetBackgroundColour 1796
+#define wxTextAttr_GetFont 1797
+#define wxTextAttr_GetLeftIndent 1798
+#define wxTextAttr_GetLeftSubIndent 1799
+#define wxTextAttr_GetRightIndent 1800
+#define wxTextAttr_GetTabs 1801
+#define wxTextAttr_GetTextColour 1802
+#define wxTextAttr_HasBackgroundColour 1803
+#define wxTextAttr_HasFont 1804
+#define wxTextAttr_HasTextColour 1805
+#define wxTextAttr_GetFlags 1806
+#define wxTextAttr_IsDefault 1807
+#define wxTextAttr_SetAlignment 1808
+#define wxTextAttr_SetBackgroundColour 1809
+#define wxTextAttr_SetFlags 1810
+#define wxTextAttr_SetFont 1811
+#define wxTextAttr_SetLeftIndent 1812
+#define wxTextAttr_SetRightIndent 1813
+#define wxTextAttr_SetTabs 1814
+#define wxTextAttr_SetTextColour 1815
+#define wxTextAttr_destroy 1816
+#define wxTextCtrl_new_3 1818
+#define wxTextCtrl_new_0 1819
+#define wxTextCtrl_destruct 1821
+#define wxTextCtrl_AppendText 1822
+#define wxTextCtrl_CanCopy 1823
+#define wxTextCtrl_CanCut 1824
+#define wxTextCtrl_CanPaste 1825
+#define wxTextCtrl_CanRedo 1826
+#define wxTextCtrl_CanUndo 1827
+#define wxTextCtrl_Clear 1828
+#define wxTextCtrl_Copy 1829
+#define wxTextCtrl_Create 1830
+#define wxTextCtrl_Cut 1831
+#define wxTextCtrl_DiscardEdits 1832
+#define wxTextCtrl_ChangeValue 1833
+#define wxTextCtrl_EmulateKeyPress 1834
+#define wxTextCtrl_GetDefaultStyle 1835
+#define wxTextCtrl_GetInsertionPoint 1836
+#define wxTextCtrl_GetLastPosition 1837
+#define wxTextCtrl_GetLineLength 1838
+#define wxTextCtrl_GetLineText 1839
+#define wxTextCtrl_GetNumberOfLines 1840
+#define wxTextCtrl_GetRange 1841
+#define wxTextCtrl_GetSelection 1842
+#define wxTextCtrl_GetStringSelection 1843
+#define wxTextCtrl_GetStyle 1844
+#define wxTextCtrl_GetValue 1845
+#define wxTextCtrl_IsEditable 1846
+#define wxTextCtrl_IsModified 1847
+#define wxTextCtrl_IsMultiLine 1848
+#define wxTextCtrl_IsSingleLine 1849
+#define wxTextCtrl_LoadFile 1850
+#define wxTextCtrl_MarkDirty 1851
+#define wxTextCtrl_Paste 1852
+#define wxTextCtrl_PositionToXY 1853
+#define wxTextCtrl_Redo 1854
+#define wxTextCtrl_Remove 1855
+#define wxTextCtrl_Replace 1856
+#define wxTextCtrl_SaveFile 1857
+#define wxTextCtrl_SetDefaultStyle 1858
+#define wxTextCtrl_SetEditable 1859
+#define wxTextCtrl_SetInsertionPoint 1860
+#define wxTextCtrl_SetInsertionPointEnd 1861
+#define wxTextCtrl_SetMaxLength 1863
+#define wxTextCtrl_SetSelection 1864
+#define wxTextCtrl_SetStyle 1865
+#define wxTextCtrl_SetValue 1866
+#define wxTextCtrl_ShowPosition 1867
+#define wxTextCtrl_Undo 1868
+#define wxTextCtrl_WriteText 1869
+#define wxTextCtrl_XYToPosition 1870
+#define wxNotebook_new_0 1873
+#define wxNotebook_new_3 1874
+#define wxNotebook_destruct 1875
+#define wxNotebook_AddPage 1876
+#define wxNotebook_AdvanceSelection 1877
+#define wxNotebook_AssignImageList 1878
+#define wxNotebook_Create 1879
+#define wxNotebook_DeleteAllPages 1880
+#define wxNotebook_DeletePage 1881
+#define wxNotebook_RemovePage 1882
+#define wxNotebook_GetCurrentPage 1883
+#define wxNotebook_GetImageList 1884
+#define wxNotebook_GetPage 1886
+#define wxNotebook_GetPageCount 1887
+#define wxNotebook_GetPageImage 1888
+#define wxNotebook_GetPageText 1889
+#define wxNotebook_GetRowCount 1890
+#define wxNotebook_GetSelection 1891
+#define wxNotebook_GetThemeBackgroundColour 1892
+#define wxNotebook_HitTest 1894
+#define wxNotebook_InsertPage 1896
+#define wxNotebook_SetImageList 1897
+#define wxNotebook_SetPadding 1898
+#define wxNotebook_SetPageSize 1899
+#define wxNotebook_SetPageImage 1900
+#define wxNotebook_SetPageText 1901
+#define wxNotebook_SetSelection 1902
+#define wxNotebook_ChangeSelection 1903
+#define wxChoicebook_new_0 1904
+#define wxChoicebook_new_3 1905
+#define wxChoicebook_AddPage 1906
+#define wxChoicebook_AdvanceSelection 1907
+#define wxChoicebook_AssignImageList 1908
+#define wxChoicebook_Create 1909
+#define wxChoicebook_DeleteAllPages 1910
+#define wxChoicebook_DeletePage 1911
+#define wxChoicebook_RemovePage 1912
+#define wxChoicebook_GetCurrentPage 1913
+#define wxChoicebook_GetImageList 1914
+#define wxChoicebook_GetPage 1916
+#define wxChoicebook_GetPageCount 1917
+#define wxChoicebook_GetPageImage 1918
+#define wxChoicebook_GetPageText 1919
+#define wxChoicebook_GetSelection 1920
+#define wxChoicebook_HitTest 1921
+#define wxChoicebook_InsertPage 1922
+#define wxChoicebook_SetImageList 1923
+#define wxChoicebook_SetPageSize 1924
+#define wxChoicebook_SetPageImage 1925
+#define wxChoicebook_SetPageText 1926
+#define wxChoicebook_SetSelection 1927
+#define wxChoicebook_ChangeSelection 1928
+#define wxChoicebook_destroy 1929
+#define wxToolbook_new_0 1930
+#define wxToolbook_new_3 1931
+#define wxToolbook_AddPage 1932
+#define wxToolbook_AdvanceSelection 1933
+#define wxToolbook_AssignImageList 1934
+#define wxToolbook_Create 1935
+#define wxToolbook_DeleteAllPages 1936
+#define wxToolbook_DeletePage 1937
+#define wxToolbook_RemovePage 1938
+#define wxToolbook_GetCurrentPage 1939
+#define wxToolbook_GetImageList 1940
+#define wxToolbook_GetPage 1942
+#define wxToolbook_GetPageCount 1943
+#define wxToolbook_GetPageImage 1944
+#define wxToolbook_GetPageText 1945
+#define wxToolbook_GetSelection 1946
+#define wxToolbook_HitTest 1948
+#define wxToolbook_InsertPage 1949
+#define wxToolbook_SetImageList 1950
+#define wxToolbook_SetPageSize 1951
+#define wxToolbook_SetPageImage 1952
+#define wxToolbook_SetPageText 1953
+#define wxToolbook_SetSelection 1954
+#define wxToolbook_ChangeSelection 1955
+#define wxToolbook_destroy 1956
+#define wxListbook_new_0 1957
+#define wxListbook_new_3 1958
+#define wxListbook_AddPage 1959
+#define wxListbook_AdvanceSelection 1960
+#define wxListbook_AssignImageList 1961
+#define wxListbook_Create 1962
+#define wxListbook_DeleteAllPages 1963
+#define wxListbook_DeletePage 1964
+#define wxListbook_RemovePage 1965
+#define wxListbook_GetCurrentPage 1966
+#define wxListbook_GetImageList 1967
+#define wxListbook_GetPage 1969
+#define wxListbook_GetPageCount 1970
+#define wxListbook_GetPageImage 1971
+#define wxListbook_GetPageText 1972
+#define wxListbook_GetSelection 1973
+#define wxListbook_HitTest 1975
+#define wxListbook_InsertPage 1976
+#define wxListbook_SetImageList 1977
+#define wxListbook_SetPageSize 1978
+#define wxListbook_SetPageImage 1979
+#define wxListbook_SetPageText 1980
+#define wxListbook_SetSelection 1981
+#define wxListbook_ChangeSelection 1982
+#define wxListbook_destroy 1983
+#define wxTreebook_new_0 1984
+#define wxTreebook_new_3 1985
+#define wxTreebook_AddPage 1986
+#define wxTreebook_AdvanceSelection 1987
+#define wxTreebook_AssignImageList 1988
+#define wxTreebook_Create 1989
+#define wxTreebook_DeleteAllPages 1990
+#define wxTreebook_DeletePage 1991
+#define wxTreebook_RemovePage 1992
+#define wxTreebook_GetCurrentPage 1993
+#define wxTreebook_GetImageList 1994
+#define wxTreebook_GetPage 1996
+#define wxTreebook_GetPageCount 1997
+#define wxTreebook_GetPageImage 1998
+#define wxTreebook_GetPageText 1999
+#define wxTreebook_GetSelection 2000
+#define wxTreebook_ExpandNode 2001
+#define wxTreebook_IsNodeExpanded 2002
+#define wxTreebook_HitTest 2004
+#define wxTreebook_InsertPage 2005
+#define wxTreebook_InsertSubPage 2006
+#define wxTreebook_SetImageList 2007
+#define wxTreebook_SetPageSize 2008
+#define wxTreebook_SetPageImage 2009
+#define wxTreebook_SetPageText 2010
+#define wxTreebook_SetSelection 2011
+#define wxTreebook_ChangeSelection 2012
+#define wxTreebook_destroy 2013
+#define wxTreeCtrl_new_2 2016
+#define wxTreeCtrl_new_0 2017
+#define wxTreeCtrl_destruct 2019
+#define wxTreeCtrl_AddRoot 2020
+#define wxTreeCtrl_AppendItem 2021
+#define wxTreeCtrl_AssignImageList 2022
+#define wxTreeCtrl_AssignStateImageList 2023
+#define wxTreeCtrl_Collapse 2024
+#define wxTreeCtrl_CollapseAndReset 2025
+#define wxTreeCtrl_Create 2026
+#define wxTreeCtrl_Delete 2027
+#define wxTreeCtrl_DeleteAllItems 2028
+#define wxTreeCtrl_DeleteChildren 2029
+#define wxTreeCtrl_EditLabel 2030
+#define wxTreeCtrl_EnsureVisible 2031
+#define wxTreeCtrl_Expand 2032
+#define wxTreeCtrl_GetBoundingRect 2033
+#define wxTreeCtrl_GetChildrenCount 2035
+#define wxTreeCtrl_GetCount 2036
+#define wxTreeCtrl_GetEditControl 2037
+#define wxTreeCtrl_GetFirstChild 2038
+#define wxTreeCtrl_GetNextChild 2039
+#define wxTreeCtrl_GetFirstVisibleItem 2040
+#define wxTreeCtrl_GetImageList 2041
+#define wxTreeCtrl_GetIndent 2042
+#define wxTreeCtrl_GetItemBackgroundColour 2043
+#define wxTreeCtrl_GetItemData 2044
+#define wxTreeCtrl_GetItemFont 2045
+#define wxTreeCtrl_GetItemImage_1 2046
+#define wxTreeCtrl_GetItemImage_2 2047
+#define wxTreeCtrl_GetItemText 2048
+#define wxTreeCtrl_GetItemTextColour 2049
+#define wxTreeCtrl_GetLastChild 2050
+#define wxTreeCtrl_GetNextSibling 2051
+#define wxTreeCtrl_GetNextVisible 2052
+#define wxTreeCtrl_GetItemParent 2053
+#define wxTreeCtrl_GetPrevSibling 2054
+#define wxTreeCtrl_GetPrevVisible 2055
+#define wxTreeCtrl_GetRootItem 2056
+#define wxTreeCtrl_GetSelection 2057
+#define wxTreeCtrl_GetSelections 2058
+#define wxTreeCtrl_GetStateImageList 2059
+#define wxTreeCtrl_HitTest 2060
+#define wxTreeCtrl_InsertItem 2062
+#define wxTreeCtrl_IsBold 2063
+#define wxTreeCtrl_IsExpanded 2064
+#define wxTreeCtrl_IsSelected 2065
+#define wxTreeCtrl_IsVisible 2066
+#define wxTreeCtrl_ItemHasChildren 2067
+#define wxTreeCtrl_IsTreeItemIdOk 2068
+#define wxTreeCtrl_PrependItem 2069
+#define wxTreeCtrl_ScrollTo 2070
+#define wxTreeCtrl_SelectItem_1 2071
+#define wxTreeCtrl_SelectItem_2 2072
+#define wxTreeCtrl_SetIndent 2073
+#define wxTreeCtrl_SetImageList 2074
+#define wxTreeCtrl_SetItemBackgroundColour 2075
+#define wxTreeCtrl_SetItemBold 2076
+#define wxTreeCtrl_SetItemData 2077
+#define wxTreeCtrl_SetItemDropHighlight 2078
+#define wxTreeCtrl_SetItemFont 2079
+#define wxTreeCtrl_SetItemHasChildren 2080
+#define wxTreeCtrl_SetItemImage_2 2081
+#define wxTreeCtrl_SetItemImage_3 2082
+#define wxTreeCtrl_SetItemText 2083
+#define wxTreeCtrl_SetItemTextColour 2084
+#define wxTreeCtrl_SetStateImageList 2085
+#define wxTreeCtrl_SetWindowStyle 2086
+#define wxTreeCtrl_SortChildren 2087
+#define wxTreeCtrl_Toggle 2088
+#define wxTreeCtrl_ToggleItemSelection 2089
+#define wxTreeCtrl_Unselect 2090
+#define wxTreeCtrl_UnselectAll 2091
+#define wxTreeCtrl_UnselectItem 2092
+#define wxScrollBar_new_0 2093
+#define wxScrollBar_new_3 2094
+#define wxScrollBar_destruct 2095
+#define wxScrollBar_Create 2096
+#define wxScrollBar_GetRange 2097
+#define wxScrollBar_GetPageSize 2098
+#define wxScrollBar_GetThumbPosition 2099
+#define wxScrollBar_GetThumbSize 2100
+#define wxScrollBar_SetThumbPosition 2101
+#define wxScrollBar_SetScrollbar 2102
+#define wxSpinButton_new_2 2104
+#define wxSpinButton_new_0 2105
+#define wxSpinButton_Create 2106
+#define wxSpinButton_GetMax 2107
+#define wxSpinButton_GetMin 2108
+#define wxSpinButton_GetValue 2109
+#define wxSpinButton_SetRange 2110
+#define wxSpinButton_SetValue 2111
+#define wxSpinButton_destroy 2112
+#define wxSpinCtrl_new_0 2113
+#define wxSpinCtrl_new_2 2114
+#define wxSpinCtrl_Create 2116
+#define wxSpinCtrl_SetValue_1_1 2119
+#define wxSpinCtrl_SetValue_1_0 2120
+#define wxSpinCtrl_GetValue 2122
+#define wxSpinCtrl_SetRange 2124
+#define wxSpinCtrl_SetSelection 2125
+#define wxSpinCtrl_GetMin 2127
+#define wxSpinCtrl_GetMax 2129
+#define wxSpinCtrl_destroy 2130
+#define wxStaticText_new_0 2131
+#define wxStaticText_new_4 2132
+#define wxStaticText_Create 2133
+#define wxStaticText_GetLabel 2134
+#define wxStaticText_SetLabel 2135
+#define wxStaticText_Wrap 2136
+#define wxStaticText_destroy 2137
+#define wxStaticBitmap_new_0 2138
+#define wxStaticBitmap_new_4 2139
+#define wxStaticBitmap_Create 2140
+#define wxStaticBitmap_GetBitmap 2141
+#define wxStaticBitmap_SetBitmap 2142
+#define wxStaticBitmap_destroy 2143
+#define wxRadioBox_new 2144
+#define wxRadioBox_destruct 2146
+#define wxRadioBox_Create 2147
+#define wxRadioBox_Enable_2 2148
+#define wxRadioBox_Enable_1 2149
+#define wxRadioBox_GetSelection 2150
+#define wxRadioBox_GetString 2151
+#define wxRadioBox_SetSelection 2152
+#define wxRadioBox_Show_2 2153
+#define wxRadioBox_Show_1 2154
+#define wxRadioBox_GetColumnCount 2155
+#define wxRadioBox_GetItemHelpText 2156
+#define wxRadioBox_GetItemToolTip 2157
+#define wxRadioBox_GetItemFromPoint 2159
+#define wxRadioBox_GetRowCount 2160
+#define wxRadioBox_IsItemEnabled 2161
+#define wxRadioBox_IsItemShown 2162
+#define wxRadioBox_SetItemHelpText 2163
+#define wxRadioBox_SetItemToolTip 2164
+#define wxRadioButton_new_0 2165
+#define wxRadioButton_new_4 2166
+#define wxRadioButton_Create 2167
+#define wxRadioButton_GetValue 2168
+#define wxRadioButton_SetValue 2169
+#define wxRadioButton_destroy 2170
+#define wxSlider_new_6 2172
+#define wxSlider_new_0 2173
+#define wxSlider_Create 2174
+#define wxSlider_GetLineSize 2175
+#define wxSlider_GetMax 2176
+#define wxSlider_GetMin 2177
+#define wxSlider_GetPageSize 2178
+#define wxSlider_GetThumbLength 2179
+#define wxSlider_GetValue 2180
+#define wxSlider_SetLineSize 2181
+#define wxSlider_SetPageSize 2182
+#define wxSlider_SetRange 2183
+#define wxSlider_SetThumbLength 2184
+#define wxSlider_SetValue 2185
+#define wxSlider_destroy 2186
+#define wxDialog_new_4 2188
+#define wxDialog_new_0 2189
+#define wxDialog_destruct 2191
+#define wxDialog_Create 2192
+#define wxDialog_CreateButtonSizer 2193
+#define wxDialog_CreateStdDialogButtonSizer 2194
+#define wxDialog_EndModal 2195
+#define wxDialog_GetAffirmativeId 2196
+#define wxDialog_GetReturnCode 2197
+#define wxDialog_IsModal 2198
+#define wxDialog_SetAffirmativeId 2199
+#define wxDialog_SetReturnCode 2200
+#define wxDialog_Show 2201
+#define wxDialog_ShowModal 2202
+#define wxColourDialog_new_0 2203
+#define wxColourDialog_new_2 2204
+#define wxColourDialog_destruct 2205
+#define wxColourDialog_Create 2206
+#define wxColourDialog_GetColourData 2207
+#define wxColourData_new_0 2208
+#define wxColourData_new_1 2209
+#define wxColourData_destruct 2210
+#define wxColourData_GetChooseFull 2211
+#define wxColourData_GetColour 2212
+#define wxColourData_GetCustomColour 2214
+#define wxColourData_SetChooseFull 2215
+#define wxColourData_SetColour 2216
+#define wxColourData_SetCustomColour 2217
+#define wxPalette_new_0 2218
+#define wxPalette_new_4 2219
+#define wxPalette_destruct 2221
+#define wxPalette_Create 2222
+#define wxPalette_GetColoursCount 2223
+#define wxPalette_GetPixel 2224
+#define wxPalette_GetRGB 2225
+#define wxPalette_IsOk 2226
+#define wxDirDialog_new 2230
+#define wxDirDialog_destruct 2231
+#define wxDirDialog_GetPath 2232
+#define wxDirDialog_GetMessage 2233
+#define wxDirDialog_SetMessage 2234
+#define wxDirDialog_SetPath 2235
+#define wxFileDialog_new 2239
+#define wxFileDialog_destruct 2240
+#define wxFileDialog_GetDirectory 2241
+#define wxFileDialog_GetFilename 2242
+#define wxFileDialog_GetFilenames 2243
+#define wxFileDialog_GetFilterIndex 2244
+#define wxFileDialog_GetMessage 2245
+#define wxFileDialog_GetPath 2246
+#define wxFileDialog_GetPaths 2247
+#define wxFileDialog_GetWildcard 2248
+#define wxFileDialog_SetDirectory 2249
+#define wxFileDialog_SetFilename 2250
+#define wxFileDialog_SetFilterIndex 2251
+#define wxFileDialog_SetMessage 2252
+#define wxFileDialog_SetPath 2253
+#define wxFileDialog_SetWildcard 2254
+#define wxPickerBase_SetInternalMargin 2255
+#define wxPickerBase_GetInternalMargin 2256
+#define wxPickerBase_SetTextCtrlProportion 2257
+#define wxPickerBase_SetPickerCtrlProportion 2258
+#define wxPickerBase_GetTextCtrlProportion 2259
+#define wxPickerBase_GetPickerCtrlProportion 2260
+#define wxPickerBase_HasTextCtrl 2261
+#define wxPickerBase_GetTextCtrl 2262
+#define wxPickerBase_IsTextCtrlGrowable 2263
+#define wxPickerBase_SetPickerCtrlGrowable 2264
+#define wxPickerBase_SetTextCtrlGrowable 2265
+#define wxPickerBase_IsPickerCtrlGrowable 2266
+#define wxFilePickerCtrl_new_0 2267
+#define wxFilePickerCtrl_new_3 2268
+#define wxFilePickerCtrl_Create 2269
+#define wxFilePickerCtrl_GetPath 2270
+#define wxFilePickerCtrl_SetPath 2271
+#define wxFilePickerCtrl_destroy 2272
+#define wxDirPickerCtrl_new_0 2273
+#define wxDirPickerCtrl_new_3 2274
+#define wxDirPickerCtrl_Create 2275
+#define wxDirPickerCtrl_GetPath 2276
+#define wxDirPickerCtrl_SetPath 2277
+#define wxDirPickerCtrl_destroy 2278
+#define wxColourPickerCtrl_new_0 2279
+#define wxColourPickerCtrl_new_3 2280
+#define wxColourPickerCtrl_Create 2281
+#define wxColourPickerCtrl_GetColour 2282
+#define wxColourPickerCtrl_SetColour_1_1 2283
+#define wxColourPickerCtrl_SetColour_1_0 2284
+#define wxColourPickerCtrl_destroy 2285
+#define wxDatePickerCtrl_new_0 2286
+#define wxDatePickerCtrl_new_3 2287
+#define wxDatePickerCtrl_GetRange 2288
+#define wxDatePickerCtrl_GetValue 2289
+#define wxDatePickerCtrl_SetRange 2290
+#define wxDatePickerCtrl_SetValue 2291
+#define wxDatePickerCtrl_destroy 2292
+#define wxFontPickerCtrl_new_0 2293
+#define wxFontPickerCtrl_new_3 2294
+#define wxFontPickerCtrl_Create 2295
+#define wxFontPickerCtrl_GetSelectedFont 2296
+#define wxFontPickerCtrl_SetSelectedFont 2297
+#define wxFontPickerCtrl_GetMaxPointSize 2298
+#define wxFontPickerCtrl_SetMaxPointSize 2299
+#define wxFontPickerCtrl_destroy 2300
+#define wxFindReplaceDialog_new_0 2303
+#define wxFindReplaceDialog_new_4 2304
+#define wxFindReplaceDialog_destruct 2305
+#define wxFindReplaceDialog_Create 2306
+#define wxFindReplaceDialog_GetData 2307
+#define wxFindReplaceData_new_0 2308
+#define wxFindReplaceData_new_1 2309
+#define wxFindReplaceData_GetFindString 2310
+#define wxFindReplaceData_GetReplaceString 2311
+#define wxFindReplaceData_GetFlags 2312
+#define wxFindReplaceData_SetFlags 2313
+#define wxFindReplaceData_SetFindString 2314
+#define wxFindReplaceData_SetReplaceString 2315
+#define wxFindReplaceData_destroy 2316
+#define wxMultiChoiceDialog_new_0 2317
+#define wxMultiChoiceDialog_new_5 2319
+#define wxMultiChoiceDialog_GetSelections 2320
+#define wxMultiChoiceDialog_SetSelections 2321
+#define wxMultiChoiceDialog_destroy 2322
+#define wxSingleChoiceDialog_new_0 2323
+#define wxSingleChoiceDialog_new_5 2325
+#define wxSingleChoiceDialog_GetSelection 2326
+#define wxSingleChoiceDialog_GetStringSelection 2327
+#define wxSingleChoiceDialog_SetSelection 2328
+#define wxSingleChoiceDialog_destroy 2329
+#define wxTextEntryDialog_new 2330
+#define wxTextEntryDialog_GetValue 2331
+#define wxTextEntryDialog_SetValue 2332
+#define wxTextEntryDialog_destroy 2333
+#define wxPasswordEntryDialog_new 2334
+#define wxPasswordEntryDialog_destroy 2335
+#define wxFontData_new_0 2336
+#define wxFontData_new_1 2337
+#define wxFontData_destruct 2338
+#define wxFontData_EnableEffects 2339
+#define wxFontData_GetAllowSymbols 2340
+#define wxFontData_GetColour 2341
+#define wxFontData_GetChosenFont 2342
+#define wxFontData_GetEnableEffects 2343
+#define wxFontData_GetInitialFont 2344
+#define wxFontData_GetShowHelp 2345
+#define wxFontData_SetAllowSymbols 2346
+#define wxFontData_SetChosenFont 2347
+#define wxFontData_SetColour 2348
+#define wxFontData_SetInitialFont 2349
+#define wxFontData_SetRange 2350
+#define wxFontData_SetShowHelp 2351
+#define wxFontDialog_new_0 2355
+#define wxFontDialog_new_2 2357
+#define wxFontDialog_Create 2359
+#define wxFontDialog_GetFontData 2360
+#define wxFontDialog_destroy 2362
+#define wxProgressDialog_new 2363
+#define wxProgressDialog_destruct 2364
+#define wxProgressDialog_Resume 2365
+#define wxProgressDialog_Update_2 2366
+#define wxProgressDialog_Update_0 2367
+#define wxMessageDialog_new 2368
+#define wxMessageDialog_destruct 2369
+#define wxPageSetupDialog_new 2370
+#define wxPageSetupDialog_destruct 2371
+#define wxPageSetupDialog_GetPageSetupData 2372
+#define wxPageSetupDialog_ShowModal 2373
+#define wxPageSetupDialogData_new_0 2374
+#define wxPageSetupDialogData_new_1_0 2375
+#define wxPageSetupDialogData_new_1_1 2376
+#define wxPageSetupDialogData_destruct 2377
+#define wxPageSetupDialogData_EnableHelp 2378
+#define wxPageSetupDialogData_EnableMargins 2379
+#define wxPageSetupDialogData_EnableOrientation 2380
+#define wxPageSetupDialogData_EnablePaper 2381
+#define wxPageSetupDialogData_EnablePrinter 2382
+#define wxPageSetupDialogData_GetDefaultMinMargins 2383
+#define wxPageSetupDialogData_GetEnableMargins 2384
+#define wxPageSetupDialogData_GetEnableOrientation 2385
+#define wxPageSetupDialogData_GetEnablePaper 2386
+#define wxPageSetupDialogData_GetEnablePrinter 2387
+#define wxPageSetupDialogData_GetEnableHelp 2388
+#define wxPageSetupDialogData_GetDefaultInfo 2389
+#define wxPageSetupDialogData_GetMarginTopLeft 2390
+#define wxPageSetupDialogData_GetMarginBottomRight 2391
+#define wxPageSetupDialogData_GetMinMarginTopLeft 2392
+#define wxPageSetupDialogData_GetMinMarginBottomRight 2393
+#define wxPageSetupDialogData_GetPaperId 2394
+#define wxPageSetupDialogData_GetPaperSize 2395
+#define wxPageSetupDialogData_GetPrintData 2397
+#define wxPageSetupDialogData_IsOk 2398
+#define wxPageSetupDialogData_SetDefaultInfo 2399
+#define wxPageSetupDialogData_SetDefaultMinMargins 2400
+#define wxPageSetupDialogData_SetMarginTopLeft 2401
+#define wxPageSetupDialogData_SetMarginBottomRight 2402
+#define wxPageSetupDialogData_SetMinMarginTopLeft 2403
+#define wxPageSetupDialogData_SetMinMarginBottomRight 2404
+#define wxPageSetupDialogData_SetPaperId 2405
+#define wxPageSetupDialogData_SetPaperSize_1_1 2406
+#define wxPageSetupDialogData_SetPaperSize_1_0 2407
+#define wxPageSetupDialogData_SetPrintData 2408
+#define wxPrintDialog_new_2_0 2409
+#define wxPrintDialog_new_2_1 2410
+#define wxPrintDialog_destruct 2411
+#define wxPrintDialog_GetPrintDialogData 2412
+#define wxPrintDialog_GetPrintDC 2413
+#define wxPrintDialogData_new_0 2414
+#define wxPrintDialogData_new_1_1 2415
+#define wxPrintDialogData_new_1_0 2416
+#define wxPrintDialogData_destruct 2417
+#define wxPrintDialogData_EnableHelp 2418
+#define wxPrintDialogData_EnablePageNumbers 2419
+#define wxPrintDialogData_EnablePrintToFile 2420
+#define wxPrintDialogData_EnableSelection 2421
+#define wxPrintDialogData_GetAllPages 2422
+#define wxPrintDialogData_GetCollate 2423
+#define wxPrintDialogData_GetFromPage 2424
+#define wxPrintDialogData_GetMaxPage 2425
+#define wxPrintDialogData_GetMinPage 2426
+#define wxPrintDialogData_GetNoCopies 2427
+#define wxPrintDialogData_GetPrintData 2428
+#define wxPrintDialogData_GetPrintToFile 2429
+#define wxPrintDialogData_GetSelection 2430
+#define wxPrintDialogData_GetToPage 2431
+#define wxPrintDialogData_IsOk 2432
+#define wxPrintDialogData_SetCollate 2433
+#define wxPrintDialogData_SetFromPage 2434
+#define wxPrintDialogData_SetMaxPage 2435
+#define wxPrintDialogData_SetMinPage 2436
+#define wxPrintDialogData_SetNoCopies 2437
+#define wxPrintDialogData_SetPrintData 2438
+#define wxPrintDialogData_SetPrintToFile 2439
+#define wxPrintDialogData_SetSelection 2440
+#define wxPrintDialogData_SetToPage 2441
+#define wxPrintData_new_0 2442
+#define wxPrintData_new_1 2443
+#define wxPrintData_destruct 2444
+#define wxPrintData_GetCollate 2445
+#define wxPrintData_GetBin 2446
+#define wxPrintData_GetColour 2447
+#define wxPrintData_GetDuplex 2448
+#define wxPrintData_GetNoCopies 2449
+#define wxPrintData_GetOrientation 2450
+#define wxPrintData_GetPaperId 2451
+#define wxPrintData_GetPrinterName 2452
+#define wxPrintData_GetQuality 2453
+#define wxPrintData_IsOk 2454
+#define wxPrintData_SetBin 2455
+#define wxPrintData_SetCollate 2456
+#define wxPrintData_SetColour 2457
+#define wxPrintData_SetDuplex 2458
+#define wxPrintData_SetNoCopies 2459
+#define wxPrintData_SetOrientation 2460
+#define wxPrintData_SetPaperId 2461
+#define wxPrintData_SetPrinterName 2462
+#define wxPrintData_SetQuality 2463
+#define wxPrintPreview_new_2 2466
+#define wxPrintPreview_new_3 2467
+#define wxPrintPreview_destruct 2469
+#define wxPrintPreview_GetCanvas 2470
+#define wxPrintPreview_GetCurrentPage 2471
+#define wxPrintPreview_GetFrame 2472
+#define wxPrintPreview_GetMaxPage 2473
+#define wxPrintPreview_GetMinPage 2474
+#define wxPrintPreview_GetPrintout 2475
+#define wxPrintPreview_GetPrintoutForPrinting 2476
+#define wxPrintPreview_IsOk 2477
+#define wxPrintPreview_PaintPage 2478
+#define wxPrintPreview_Print 2479
+#define wxPrintPreview_RenderPage 2480
+#define wxPrintPreview_SetCanvas 2481
+#define wxPrintPreview_SetCurrentPage 2482
+#define wxPrintPreview_SetFrame 2483
+#define wxPrintPreview_SetPrintout 2484
+#define wxPrintPreview_SetZoom 2485
+#define wxPreviewFrame_new 2486
+#define wxPreviewFrame_destruct 2487
+#define wxPreviewFrame_CreateControlBar 2488
+#define wxPreviewFrame_CreateCanvas 2489
+#define wxPreviewFrame_Initialize 2490
+#define wxPreviewFrame_OnCloseWindow 2491
+#define wxPreviewControlBar_new 2492
+#define wxPreviewControlBar_destruct 2493
+#define wxPreviewControlBar_CreateButtons 2494
+#define wxPreviewControlBar_GetPrintPreview 2495
+#define wxPreviewControlBar_GetZoomControl 2496
+#define wxPreviewControlBar_SetZoomControl 2497
+#define wxPrinter_new 2499
+#define wxPrinter_CreateAbortWindow 2500
+#define wxPrinter_GetAbort 2501
+#define wxPrinter_GetLastError 2502
+#define wxPrinter_GetPrintDialogData 2503
+#define wxPrinter_Print 2504
+#define wxPrinter_PrintDialog 2505
+#define wxPrinter_ReportError 2506
+#define wxPrinter_Setup 2507
+#define wxPrinter_destroy 2508
+#define wxXmlResource_new_1 2509
+#define wxXmlResource_new_2 2510
+#define wxXmlResource_destruct 2511
+#define wxXmlResource_AttachUnknownControl 2512
+#define wxXmlResource_ClearHandlers 2513
+#define wxXmlResource_CompareVersion 2514
+#define wxXmlResource_Get 2515
+#define wxXmlResource_GetFlags 2516
+#define wxXmlResource_GetVersion 2517
+#define wxXmlResource_GetXRCID 2518
+#define wxXmlResource_InitAllHandlers 2519
+#define wxXmlResource_Load 2520
+#define wxXmlResource_LoadBitmap 2521
+#define wxXmlResource_LoadDialog_2 2522
+#define wxXmlResource_LoadDialog_3 2523
+#define wxXmlResource_LoadFrame_2 2524
+#define wxXmlResource_LoadFrame_3 2525
+#define wxXmlResource_LoadIcon 2526
+#define wxXmlResource_LoadMenu 2527
+#define wxXmlResource_LoadMenuBar_2 2528
+#define wxXmlResource_LoadMenuBar_1 2529
+#define wxXmlResource_LoadPanel_2 2530
+#define wxXmlResource_LoadPanel_3 2531
+#define wxXmlResource_LoadToolBar 2532
+#define wxXmlResource_Set 2533
+#define wxXmlResource_SetFlags 2534
+#define wxXmlResource_Unload 2535
+#define wxXmlResource_xrcctrl 2536
+#define wxHtmlEasyPrinting_new 2537
+#define wxHtmlEasyPrinting_destruct 2538
+#define wxHtmlEasyPrinting_GetPrintData 2539
+#define wxHtmlEasyPrinting_GetPageSetupData 2540
+#define wxHtmlEasyPrinting_PreviewFile 2541
+#define wxHtmlEasyPrinting_PreviewText 2542
+#define wxHtmlEasyPrinting_PrintFile 2543
+#define wxHtmlEasyPrinting_PrintText 2544
+#define wxHtmlEasyPrinting_PageSetup 2545
+#define wxHtmlEasyPrinting_SetFonts 2546
+#define wxHtmlEasyPrinting_SetHeader 2547
+#define wxHtmlEasyPrinting_SetFooter 2548
+#define wxGLCanvas_new_2 2550
+#define wxGLCanvas_new_3_1 2551
+#define wxGLCanvas_new_3_0 2552
+#define wxGLCanvas_GetContext 2553
+#define wxGLCanvas_SetCurrent 2555
+#define wxGLCanvas_SwapBuffers 2556
+#define wxGLCanvas_destroy 2557
+#define wxAuiManager_new 2558
+#define wxAuiManager_destruct 2559
+#define wxAuiManager_AddPane_2_1 2560
+#define wxAuiManager_AddPane_3 2561
+#define wxAuiManager_AddPane_2_0 2562
+#define wxAuiManager_DetachPane 2563
+#define wxAuiManager_GetAllPanes 2564
+#define wxAuiManager_GetArtProvider 2565
+#define wxAuiManager_GetDockSizeConstraint 2566
+#define wxAuiManager_GetFlags 2567
+#define wxAuiManager_GetManagedWindow 2568
+#define wxAuiManager_GetManager 2569
+#define wxAuiManager_GetPane_1_1 2570
+#define wxAuiManager_GetPane_1_0 2571
+#define wxAuiManager_HideHint 2572
+#define wxAuiManager_InsertPane 2573
+#define wxAuiManager_LoadPaneInfo 2574
+#define wxAuiManager_LoadPerspective 2575
+#define wxAuiManager_SavePaneInfo 2576
+#define wxAuiManager_SavePerspective 2577
+#define wxAuiManager_SetArtProvider 2578
+#define wxAuiManager_SetDockSizeConstraint 2579
+#define wxAuiManager_SetFlags 2580
+#define wxAuiManager_SetManagedWindow 2581
+#define wxAuiManager_ShowHint 2582
+#define wxAuiManager_UnInit 2583
+#define wxAuiManager_Update 2584
+#define wxAuiPaneInfo_new_0 2585
+#define wxAuiPaneInfo_new_1 2586
+#define wxAuiPaneInfo_destruct 2587
+#define wxAuiPaneInfo_BestSize_1 2588
+#define wxAuiPaneInfo_BestSize_2 2589
+#define wxAuiPaneInfo_Bottom 2590
+#define wxAuiPaneInfo_BottomDockable 2591
+#define wxAuiPaneInfo_Caption 2592
+#define wxAuiPaneInfo_CaptionVisible 2593
+#define wxAuiPaneInfo_Centre 2594
+#define wxAuiPaneInfo_CentrePane 2595
+#define wxAuiPaneInfo_CloseButton 2596
+#define wxAuiPaneInfo_DefaultPane 2597
+#define wxAuiPaneInfo_DestroyOnClose 2598
+#define wxAuiPaneInfo_Direction 2599
+#define wxAuiPaneInfo_Dock 2600
+#define wxAuiPaneInfo_Dockable 2601
+#define wxAuiPaneInfo_Fixed 2602
+#define wxAuiPaneInfo_Float 2603
+#define wxAuiPaneInfo_Floatable 2604
+#define wxAuiPaneInfo_FloatingPosition_1 2605
+#define wxAuiPaneInfo_FloatingPosition_2 2606
+#define wxAuiPaneInfo_FloatingSize_1 2607
+#define wxAuiPaneInfo_FloatingSize_2 2608
+#define wxAuiPaneInfo_Gripper 2609
+#define wxAuiPaneInfo_GripperTop 2610
+#define wxAuiPaneInfo_HasBorder 2611
+#define wxAuiPaneInfo_HasCaption 2612
+#define wxAuiPaneInfo_HasCloseButton 2613
+#define wxAuiPaneInfo_HasFlag 2614
+#define wxAuiPaneInfo_HasGripper 2615
+#define wxAuiPaneInfo_HasGripperTop 2616
+#define wxAuiPaneInfo_HasMaximizeButton 2617
+#define wxAuiPaneInfo_HasMinimizeButton 2618
+#define wxAuiPaneInfo_HasPinButton 2619
+#define wxAuiPaneInfo_Hide 2620
+#define wxAuiPaneInfo_IsBottomDockable 2621
+#define wxAuiPaneInfo_IsDocked 2622
+#define wxAuiPaneInfo_IsFixed 2623
+#define wxAuiPaneInfo_IsFloatable 2624
+#define wxAuiPaneInfo_IsFloating 2625
+#define wxAuiPaneInfo_IsLeftDockable 2626
+#define wxAuiPaneInfo_IsMovable 2627
+#define wxAuiPaneInfo_IsOk 2628
+#define wxAuiPaneInfo_IsResizable 2629
+#define wxAuiPaneInfo_IsRightDockable 2630
+#define wxAuiPaneInfo_IsShown 2631
+#define wxAuiPaneInfo_IsToolbar 2632
+#define wxAuiPaneInfo_IsTopDockable 2633
+#define wxAuiPaneInfo_Layer 2634
+#define wxAuiPaneInfo_Left 2635
+#define wxAuiPaneInfo_LeftDockable 2636
+#define wxAuiPaneInfo_MaxSize_1 2637
+#define wxAuiPaneInfo_MaxSize_2 2638
+#define wxAuiPaneInfo_MaximizeButton 2639
+#define wxAuiPaneInfo_MinSize_1 2640
+#define wxAuiPaneInfo_MinSize_2 2641
+#define wxAuiPaneInfo_MinimizeButton 2642
+#define wxAuiPaneInfo_Movable 2643
+#define wxAuiPaneInfo_Name 2644
+#define wxAuiPaneInfo_PaneBorder 2645
+#define wxAuiPaneInfo_PinButton 2646
+#define wxAuiPaneInfo_Position 2647
+#define wxAuiPaneInfo_Resizable 2648
+#define wxAuiPaneInfo_Right 2649
+#define wxAuiPaneInfo_RightDockable 2650
+#define wxAuiPaneInfo_Row 2651
+#define wxAuiPaneInfo_SafeSet 2652
+#define wxAuiPaneInfo_SetFlag 2653
+#define wxAuiPaneInfo_Show 2654
+#define wxAuiPaneInfo_ToolbarPane 2655
+#define wxAuiPaneInfo_Top 2656
+#define wxAuiPaneInfo_TopDockable 2657
+#define wxAuiPaneInfo_Window 2658
+#define wxAuiPaneInfo_GetWindow 2659
+#define wxAuiPaneInfo_GetFrame 2660
+#define wxAuiPaneInfo_GetDirection 2661
+#define wxAuiPaneInfo_GetLayer 2662
+#define wxAuiPaneInfo_GetRow 2663
+#define wxAuiPaneInfo_GetPosition 2664
+#define wxAuiPaneInfo_GetFloatingPosition 2665
+#define wxAuiPaneInfo_GetFloatingSize 2666
+#define wxAuiNotebook_new_0 2667
+#define wxAuiNotebook_new_2 2668
+#define wxAuiNotebook_AddPage 2669
+#define wxAuiNotebook_Create 2670
+#define wxAuiNotebook_DeletePage 2671
+#define wxAuiNotebook_GetArtProvider 2672
+#define wxAuiNotebook_GetPage 2673
+#define wxAuiNotebook_GetPageBitmap 2674
+#define wxAuiNotebook_GetPageCount 2675
+#define wxAuiNotebook_GetPageIndex 2676
+#define wxAuiNotebook_GetPageText 2677
+#define wxAuiNotebook_GetSelection 2678
+#define wxAuiNotebook_InsertPage 2679
+#define wxAuiNotebook_RemovePage 2680
+#define wxAuiNotebook_SetArtProvider 2681
+#define wxAuiNotebook_SetFont 2682
+#define wxAuiNotebook_SetPageBitmap 2683
+#define wxAuiNotebook_SetPageText 2684
+#define wxAuiNotebook_SetSelection 2685
+#define wxAuiNotebook_SetTabCtrlHeight 2686
+#define wxAuiNotebook_SetUniformBitmapSize 2687
+#define wxAuiNotebook_destroy 2688
+#define wxAuiTabArt_SetFlags 2689
+#define wxAuiTabArt_SetMeasuringFont 2690
+#define wxAuiTabArt_SetNormalFont 2691
+#define wxAuiTabArt_SetSelectedFont 2692
+#define wxAuiTabArt_SetColour 2693
+#define wxAuiTabArt_SetActiveColour 2694
+#define wxAuiDockArt_GetColour 2695
+#define wxAuiDockArt_GetFont 2696
+#define wxAuiDockArt_GetMetric 2697
+#define wxAuiDockArt_SetColour 2698
+#define wxAuiDockArt_SetFont 2699
+#define wxAuiDockArt_SetMetric 2700
+#define wxAuiSimpleTabArt_new 2701
+#define wxAuiSimpleTabArt_destroy 2702
+#define wxMDIParentFrame_new_0 2703
+#define wxMDIParentFrame_new_4 2704
+#define wxMDIParentFrame_destruct 2705
+#define wxMDIParentFrame_ActivateNext 2706
+#define wxMDIParentFrame_ActivatePrevious 2707
+#define wxMDIParentFrame_ArrangeIcons 2708
+#define wxMDIParentFrame_Cascade 2709
+#define wxMDIParentFrame_Create 2710
+#define wxMDIParentFrame_GetActiveChild 2711
+#define wxMDIParentFrame_GetClientWindow 2712
+#define wxMDIParentFrame_Tile 2713
+#define wxMDIChildFrame_new_0 2714
+#define wxMDIChildFrame_new_4 2715
+#define wxMDIChildFrame_destruct 2716
+#define wxMDIChildFrame_Activate 2717
+#define wxMDIChildFrame_Create 2718
+#define wxMDIChildFrame_Maximize 2719
+#define wxMDIChildFrame_Restore 2720
+#define wxMDIClientWindow_new_0 2721
+#define wxMDIClientWindow_new_2 2722
+#define wxMDIClientWindow_destruct 2723
+#define wxMDIClientWindow_CreateClient 2724
+#define wxLayoutAlgorithm_new 2725
+#define wxLayoutAlgorithm_LayoutFrame 2726
+#define wxLayoutAlgorithm_LayoutMDIFrame 2727
+#define wxLayoutAlgorithm_LayoutWindow 2728
+#define wxLayoutAlgorithm_destroy 2729
+#define wxEvent_GetId 2730
+#define wxEvent_GetSkipped 2731
+#define wxEvent_GetTimestamp 2732
+#define wxEvent_IsCommandEvent 2733
+#define wxEvent_ResumePropagation 2734
+#define wxEvent_ShouldPropagate 2735
+#define wxEvent_Skip 2736
+#define wxEvent_StopPropagation 2737
+#define wxCommandEvent_getClientData 2738
+#define wxCommandEvent_GetExtraLong 2739
+#define wxCommandEvent_GetInt 2740
+#define wxCommandEvent_GetSelection 2741
+#define wxCommandEvent_GetString 2742
+#define wxCommandEvent_IsChecked 2743
+#define wxCommandEvent_IsSelection 2744
+#define wxCommandEvent_SetInt 2745
+#define wxCommandEvent_SetString 2746
+#define wxScrollEvent_GetOrientation 2747
+#define wxScrollEvent_GetPosition 2748
+#define wxScrollWinEvent_GetOrientation 2749
+#define wxScrollWinEvent_GetPosition 2750
+#define wxMouseEvent_AltDown 2751
+#define wxMouseEvent_Button 2752
+#define wxMouseEvent_ButtonDClick 2753
+#define wxMouseEvent_ButtonDown 2754
+#define wxMouseEvent_ButtonUp 2755
+#define wxMouseEvent_CmdDown 2756
+#define wxMouseEvent_ControlDown 2757
+#define wxMouseEvent_Dragging 2758
+#define wxMouseEvent_Entering 2759
+#define wxMouseEvent_GetButton 2760
+#define wxMouseEvent_GetPosition 2763
+#define wxMouseEvent_GetLogicalPosition 2764
+#define wxMouseEvent_GetLinesPerAction 2765
+#define wxMouseEvent_GetWheelRotation 2766
+#define wxMouseEvent_GetWheelDelta 2767
+#define wxMouseEvent_GetX 2768
+#define wxMouseEvent_GetY 2769
+#define wxMouseEvent_IsButton 2770
+#define wxMouseEvent_IsPageScroll 2771
+#define wxMouseEvent_Leaving 2772
+#define wxMouseEvent_LeftDClick 2773
+#define wxMouseEvent_LeftDown 2774
+#define wxMouseEvent_LeftIsDown 2775
+#define wxMouseEvent_LeftUp 2776
+#define wxMouseEvent_MetaDown 2777
+#define wxMouseEvent_MiddleDClick 2778
+#define wxMouseEvent_MiddleDown 2779
+#define wxMouseEvent_MiddleIsDown 2780
+#define wxMouseEvent_MiddleUp 2781
+#define wxMouseEvent_Moving 2782
+#define wxMouseEvent_RightDClick 2783
+#define wxMouseEvent_RightDown 2784
+#define wxMouseEvent_RightIsDown 2785
+#define wxMouseEvent_RightUp 2786
+#define wxMouseEvent_ShiftDown 2787
+#define wxSetCursorEvent_GetCursor 2788
+#define wxSetCursorEvent_GetX 2789
+#define wxSetCursorEvent_GetY 2790
+#define wxSetCursorEvent_HasCursor 2791
+#define wxSetCursorEvent_SetCursor 2792
+#define wxKeyEvent_AltDown 2793
+#define wxKeyEvent_CmdDown 2794
+#define wxKeyEvent_ControlDown 2795
+#define wxKeyEvent_GetKeyCode 2796
+#define wxKeyEvent_GetModifiers 2797
+#define wxKeyEvent_GetPosition 2800
+#define wxKeyEvent_GetRawKeyCode 2801
+#define wxKeyEvent_GetRawKeyFlags 2802
+#define wxKeyEvent_GetUnicodeKey 2803
+#define wxKeyEvent_GetX 2804
+#define wxKeyEvent_GetY 2805
+#define wxKeyEvent_HasModifiers 2806
+#define wxKeyEvent_MetaDown 2807
+#define wxKeyEvent_ShiftDown 2808
+#define wxSizeEvent_GetSize 2809
+#define wxMoveEvent_GetPosition 2810
+#define wxEraseEvent_GetDC 2811
+#define wxFocusEvent_GetWindow 2812
+#define wxChildFocusEvent_GetWindow 2813
+#define wxMenuEvent_GetMenu 2814
+#define wxMenuEvent_GetMenuId 2815
+#define wxMenuEvent_IsPopup 2816
+#define wxCloseEvent_CanVeto 2817
+#define wxCloseEvent_GetLoggingOff 2818
+#define wxCloseEvent_SetCanVeto 2819
+#define wxCloseEvent_SetLoggingOff 2820
+#define wxCloseEvent_Veto 2821
+#define wxShowEvent_SetShow 2822
+#define wxShowEvent_GetShow 2823
+#define wxIconizeEvent_Iconized 2824
+#define wxJoystickEvent_ButtonDown 2825
+#define wxJoystickEvent_ButtonIsDown 2826
+#define wxJoystickEvent_ButtonUp 2827
+#define wxJoystickEvent_GetButtonChange 2828
+#define wxJoystickEvent_GetButtonState 2829
+#define wxJoystickEvent_GetJoystick 2830
+#define wxJoystickEvent_GetPosition 2831
+#define wxJoystickEvent_GetZPosition 2832
+#define wxJoystickEvent_IsButton 2833
+#define wxJoystickEvent_IsMove 2834
+#define wxJoystickEvent_IsZMove 2835
+#define wxUpdateUIEvent_CanUpdate 2836
+#define wxUpdateUIEvent_Check 2837
+#define wxUpdateUIEvent_Enable 2838
+#define wxUpdateUIEvent_Show 2839
+#define wxUpdateUIEvent_GetChecked 2840
+#define wxUpdateUIEvent_GetEnabled 2841
+#define wxUpdateUIEvent_GetShown 2842
+#define wxUpdateUIEvent_GetSetChecked 2843
+#define wxUpdateUIEvent_GetSetEnabled 2844
+#define wxUpdateUIEvent_GetSetShown 2845
+#define wxUpdateUIEvent_GetSetText 2846
+#define wxUpdateUIEvent_GetText 2847
+#define wxUpdateUIEvent_GetMode 2848
+#define wxUpdateUIEvent_GetUpdateInterval 2849
+#define wxUpdateUIEvent_ResetUpdateTime 2850
+#define wxUpdateUIEvent_SetMode 2851
+#define wxUpdateUIEvent_SetText 2852
+#define wxUpdateUIEvent_SetUpdateInterval 2853
+#define wxMouseCaptureChangedEvent_GetCapturedWindow 2854
+#define wxPaletteChangedEvent_SetChangedWindow 2855
+#define wxPaletteChangedEvent_GetChangedWindow 2856
+#define wxQueryNewPaletteEvent_SetPaletteRealized 2857
+#define wxQueryNewPaletteEvent_GetPaletteRealized 2858
+#define wxNavigationKeyEvent_GetDirection 2859
+#define wxNavigationKeyEvent_SetDirection 2860
+#define wxNavigationKeyEvent_IsWindowChange 2861
+#define wxNavigationKeyEvent_SetWindowChange 2862
+#define wxNavigationKeyEvent_IsFromTab 2863
+#define wxNavigationKeyEvent_SetFromTab 2864
+#define wxNavigationKeyEvent_GetCurrentFocus 2865
+#define wxNavigationKeyEvent_SetCurrentFocus 2866
+#define wxHelpEvent_GetOrigin 2867
+#define wxHelpEvent_GetPosition 2868
+#define wxHelpEvent_SetOrigin 2869
+#define wxHelpEvent_SetPosition 2870
+#define wxContextMenuEvent_GetPosition 2871
+#define wxContextMenuEvent_SetPosition 2872
+#define wxIdleEvent_CanSend 2873
+#define wxIdleEvent_GetMode 2874
+#define wxIdleEvent_RequestMore 2875
+#define wxIdleEvent_MoreRequested 2876
+#define wxIdleEvent_SetMode 2877
+#define wxGridEvent_AltDown 2878
+#define wxGridEvent_ControlDown 2879
+#define wxGridEvent_GetCol 2880
+#define wxGridEvent_GetPosition 2881
+#define wxGridEvent_GetRow 2882
+#define wxGridEvent_MetaDown 2883
+#define wxGridEvent_Selecting 2884
+#define wxGridEvent_ShiftDown 2885
+#define wxNotifyEvent_Allow 2886
+#define wxNotifyEvent_IsAllowed 2887
+#define wxNotifyEvent_Veto 2888
+#define wxSashEvent_GetEdge 2889
+#define wxSashEvent_GetDragRect 2890
+#define wxSashEvent_GetDragStatus 2891
+#define wxListEvent_GetCacheFrom 2892
+#define wxListEvent_GetCacheTo 2893
+#define wxListEvent_GetKeyCode 2894
+#define wxListEvent_GetIndex 2895
+#define wxListEvent_GetColumn 2896
+#define wxListEvent_GetPoint 2897
+#define wxListEvent_GetLabel 2898
+#define wxListEvent_GetText 2899
+#define wxListEvent_GetImage 2900
+#define wxListEvent_GetData 2901
+#define wxListEvent_GetMask 2902
+#define wxListEvent_GetItem 2903
+#define wxListEvent_IsEditCancelled 2904
+#define wxDateEvent_GetDate 2905
+#define wxCalendarEvent_GetWeekDay 2906
+#define wxFileDirPickerEvent_GetPath 2907
+#define wxColourPickerEvent_GetColour 2908
+#define wxFontPickerEvent_GetFont 2909
+#define wxStyledTextEvent_GetPosition 2910
+#define wxStyledTextEvent_GetKey 2911
+#define wxStyledTextEvent_GetModifiers 2912
+#define wxStyledTextEvent_GetModificationType 2913
+#define wxStyledTextEvent_GetText 2914
+#define wxStyledTextEvent_GetLength 2915
+#define wxStyledTextEvent_GetLinesAdded 2916
+#define wxStyledTextEvent_GetLine 2917
+#define wxStyledTextEvent_GetFoldLevelNow 2918
+#define wxStyledTextEvent_GetFoldLevelPrev 2919
+#define wxStyledTextEvent_GetMargin 2920
+#define wxStyledTextEvent_GetMessage 2921
+#define wxStyledTextEvent_GetWParam 2922
+#define wxStyledTextEvent_GetLParam 2923
+#define wxStyledTextEvent_GetListType 2924
+#define wxStyledTextEvent_GetX 2925
+#define wxStyledTextEvent_GetY 2926
+#define wxStyledTextEvent_GetDragText 2927
+#define wxStyledTextEvent_GetDragAllowMove 2928
+#define wxStyledTextEvent_GetDragResult 2929
+#define wxStyledTextEvent_GetShift 2930
+#define wxStyledTextEvent_GetControl 2931
+#define wxStyledTextEvent_GetAlt 2932
+#define utils_wxGetKeyState 2933
+#define utils_wxGetMousePosition 2934
+#define utils_wxGetMouseState 2935
+#define utils_wxSetDetectableAutoRepeat 2936
+#define utils_wxBell 2937
+#define utils_wxFindMenuItemId 2938
+#define utils_wxGenericFindWindowAtPoint 2939
+#define utils_wxFindWindowAtPoint 2940
+#define utils_wxBeginBusyCursor 2941
+#define utils_wxEndBusyCursor 2942
+#define utils_wxIsBusy 2943
+#define utils_wxShutdown 2944
+#define utils_wxShell 2945
+#define utils_wxLaunchDefaultBrowser 2946
+#define utils_wxGetEmailAddress 2947
+#define utils_wxGetUserId 2948
+#define utils_wxGetHomeDir 2949
+#define utils_wxNewId 2950
+#define utils_wxRegisterId 2951
+#define utils_wxGetCurrentId 2952
+#define utils_wxGetOsDescription 2953
+#define utils_wxIsPlatformLittleEndian 2954
+#define utils_wxIsPlatform64Bit 2955
+#define gdicmn_wxDisplaySize 2956
+#define gdicmn_wxSetCursor 2957
+#define wxPrintout_new 2958
+#define wxPrintout_destruct 2959
+#define wxPrintout_GetDC 2960
+#define wxPrintout_GetPageSizeMM 2961
+#define wxPrintout_GetPageSizePixels 2962
+#define wxPrintout_GetPaperRectPixels 2963
+#define wxPrintout_GetPPIPrinter 2964
+#define wxPrintout_GetPPIScreen 2965
+#define wxPrintout_GetTitle 2966
+#define wxPrintout_IsPreview 2967
+#define wxPrintout_FitThisSizeToPaper 2968
+#define wxPrintout_FitThisSizeToPage 2969
+#define wxPrintout_FitThisSizeToPageMargins 2970
+#define wxPrintout_MapScreenSizeToPaper 2971
+#define wxPrintout_MapScreenSizeToPage 2972
+#define wxPrintout_MapScreenSizeToPageMargins 2973
+#define wxPrintout_MapScreenSizeToDevice 2974
+#define wxPrintout_GetLogicalPaperRect 2975
+#define wxPrintout_GetLogicalPageRect 2976
+#define wxPrintout_GetLogicalPageMarginsRect 2977
+#define wxPrintout_SetLogicalOrigin 2978
+#define wxPrintout_OffsetLogicalOrigin 2979
+#define wxStyledTextCtrl_new_2 2980
+#define wxStyledTextCtrl_new_0 2981
+#define wxStyledTextCtrl_destruct 2982
+#define wxStyledTextCtrl_Create 2983
+#define wxStyledTextCtrl_AddText 2984
+#define wxStyledTextCtrl_AddStyledText 2985
+#define wxStyledTextCtrl_InsertText 2986
+#define wxStyledTextCtrl_ClearAll 2987
+#define wxStyledTextCtrl_ClearDocumentStyle 2988
+#define wxStyledTextCtrl_GetLength 2989
+#define wxStyledTextCtrl_GetCharAt 2990
+#define wxStyledTextCtrl_GetCurrentPos 2991
+#define wxStyledTextCtrl_GetAnchor 2992
+#define wxStyledTextCtrl_GetStyleAt 2993
+#define wxStyledTextCtrl_Redo 2994
+#define wxStyledTextCtrl_SetUndoCollection 2995
+#define wxStyledTextCtrl_SelectAll 2996
+#define wxStyledTextCtrl_SetSavePoint 2997
+#define wxStyledTextCtrl_GetStyledText 2998
+#define wxStyledTextCtrl_CanRedo 2999
+#define wxStyledTextCtrl_MarkerLineFromHandle 3000
+#define wxStyledTextCtrl_MarkerDeleteHandle 3001
+#define wxStyledTextCtrl_GetUndoCollection 3002
+#define wxStyledTextCtrl_GetViewWhiteSpace 3003
+#define wxStyledTextCtrl_SetViewWhiteSpace 3004
+#define wxStyledTextCtrl_PositionFromPoint 3005
+#define wxStyledTextCtrl_PositionFromPointClose 3006
+#define wxStyledTextCtrl_GotoLine 3007
+#define wxStyledTextCtrl_GotoPos 3008
+#define wxStyledTextCtrl_SetAnchor 3009
+#define wxStyledTextCtrl_GetCurLine 3010
+#define wxStyledTextCtrl_GetEndStyled 3011
+#define wxStyledTextCtrl_ConvertEOLs 3012
+#define wxStyledTextCtrl_GetEOLMode 3013
+#define wxStyledTextCtrl_SetEOLMode 3014
+#define wxStyledTextCtrl_StartStyling 3015
+#define wxStyledTextCtrl_SetStyling 3016
+#define wxStyledTextCtrl_GetBufferedDraw 3017
+#define wxStyledTextCtrl_SetBufferedDraw 3018
+#define wxStyledTextCtrl_SetTabWidth 3019
+#define wxStyledTextCtrl_GetTabWidth 3020
+#define wxStyledTextCtrl_SetCodePage 3021
+#define wxStyledTextCtrl_MarkerDefine 3022
+#define wxStyledTextCtrl_MarkerSetForeground 3023
+#define wxStyledTextCtrl_MarkerSetBackground 3024
+#define wxStyledTextCtrl_MarkerAdd 3025
+#define wxStyledTextCtrl_MarkerDelete 3026
+#define wxStyledTextCtrl_MarkerDeleteAll 3027
+#define wxStyledTextCtrl_MarkerGet 3028
+#define wxStyledTextCtrl_MarkerNext 3029
+#define wxStyledTextCtrl_MarkerPrevious 3030
+#define wxStyledTextCtrl_MarkerDefineBitmap 3031
+#define wxStyledTextCtrl_MarkerAddSet 3032
+#define wxStyledTextCtrl_MarkerSetAlpha 3033
+#define wxStyledTextCtrl_SetMarginType 3034
+#define wxStyledTextCtrl_GetMarginType 3035
+#define wxStyledTextCtrl_SetMarginWidth 3036
+#define wxStyledTextCtrl_GetMarginWidth 3037
+#define wxStyledTextCtrl_SetMarginMask 3038
+#define wxStyledTextCtrl_GetMarginMask 3039
+#define wxStyledTextCtrl_SetMarginSensitive 3040
+#define wxStyledTextCtrl_GetMarginSensitive 3041
+#define wxStyledTextCtrl_StyleClearAll 3042
+#define wxStyledTextCtrl_StyleSetForeground 3043
+#define wxStyledTextCtrl_StyleSetBackground 3044
+#define wxStyledTextCtrl_StyleSetBold 3045
+#define wxStyledTextCtrl_StyleSetItalic 3046
+#define wxStyledTextCtrl_StyleSetSize 3047
+#define wxStyledTextCtrl_StyleSetFaceName 3048
+#define wxStyledTextCtrl_StyleSetEOLFilled 3049
+#define wxStyledTextCtrl_StyleResetDefault 3050
+#define wxStyledTextCtrl_StyleSetUnderline 3051
+#define wxStyledTextCtrl_StyleSetCase 3052
+#define wxStyledTextCtrl_StyleSetHotSpot 3053
+#define wxStyledTextCtrl_SetSelForeground 3054
+#define wxStyledTextCtrl_SetSelBackground 3055
+#define wxStyledTextCtrl_GetSelAlpha 3056
+#define wxStyledTextCtrl_SetSelAlpha 3057
+#define wxStyledTextCtrl_SetCaretForeground 3058
+#define wxStyledTextCtrl_CmdKeyAssign 3059
+#define wxStyledTextCtrl_CmdKeyClear 3060
+#define wxStyledTextCtrl_CmdKeyClearAll 3061
+#define wxStyledTextCtrl_SetStyleBytes 3062
+#define wxStyledTextCtrl_StyleSetVisible 3063
+#define wxStyledTextCtrl_GetCaretPeriod 3064
+#define wxStyledTextCtrl_SetCaretPeriod 3065
+#define wxStyledTextCtrl_SetWordChars 3066
+#define wxStyledTextCtrl_BeginUndoAction 3067
+#define wxStyledTextCtrl_EndUndoAction 3068
+#define wxStyledTextCtrl_IndicatorSetStyle 3069
+#define wxStyledTextCtrl_IndicatorGetStyle 3070
+#define wxStyledTextCtrl_IndicatorSetForeground 3071
+#define wxStyledTextCtrl_IndicatorGetForeground 3072
+#define wxStyledTextCtrl_SetWhitespaceForeground 3073
+#define wxStyledTextCtrl_SetWhitespaceBackground 3074
+#define wxStyledTextCtrl_GetStyleBits 3075
+#define wxStyledTextCtrl_SetLineState 3076
+#define wxStyledTextCtrl_GetLineState 3077
+#define wxStyledTextCtrl_GetMaxLineState 3078
+#define wxStyledTextCtrl_GetCaretLineVisible 3079
+#define wxStyledTextCtrl_SetCaretLineVisible 3080
+#define wxStyledTextCtrl_GetCaretLineBackground 3081
+#define wxStyledTextCtrl_SetCaretLineBackground 3082
+#define wxStyledTextCtrl_AutoCompShow 3083
+#define wxStyledTextCtrl_AutoCompCancel 3084
+#define wxStyledTextCtrl_AutoCompActive 3085
+#define wxStyledTextCtrl_AutoCompPosStart 3086
+#define wxStyledTextCtrl_AutoCompComplete 3087
+#define wxStyledTextCtrl_AutoCompStops 3088
+#define wxStyledTextCtrl_AutoCompSetSeparator 3089
+#define wxStyledTextCtrl_AutoCompGetSeparator 3090
+#define wxStyledTextCtrl_AutoCompSelect 3091
+#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3092
+#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3093
+#define wxStyledTextCtrl_AutoCompSetFillUps 3094
+#define wxStyledTextCtrl_AutoCompSetChooseSingle 3095
+#define wxStyledTextCtrl_AutoCompGetChooseSingle 3096
+#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3097
+#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3098
+#define wxStyledTextCtrl_UserListShow 3099
+#define wxStyledTextCtrl_AutoCompSetAutoHide 3100
+#define wxStyledTextCtrl_AutoCompGetAutoHide 3101
+#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3102
+#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3103
+#define wxStyledTextCtrl_RegisterImage 3104
+#define wxStyledTextCtrl_ClearRegisteredImages 3105
+#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3106
+#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3107
+#define wxStyledTextCtrl_AutoCompSetMaxWidth 3108
+#define wxStyledTextCtrl_AutoCompGetMaxWidth 3109
+#define wxStyledTextCtrl_AutoCompSetMaxHeight 3110
+#define wxStyledTextCtrl_AutoCompGetMaxHeight 3111
+#define wxStyledTextCtrl_SetIndent 3112
+#define wxStyledTextCtrl_GetIndent 3113
+#define wxStyledTextCtrl_SetUseTabs 3114
+#define wxStyledTextCtrl_GetUseTabs 3115
+#define wxStyledTextCtrl_SetLineIndentation 3116
+#define wxStyledTextCtrl_GetLineIndentation 3117
+#define wxStyledTextCtrl_GetLineIndentPosition 3118
+#define wxStyledTextCtrl_GetColumn 3119
+#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3120
+#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3121
+#define wxStyledTextCtrl_SetIndentationGuides 3122
+#define wxStyledTextCtrl_GetIndentationGuides 3123
+#define wxStyledTextCtrl_SetHighlightGuide 3124
+#define wxStyledTextCtrl_GetHighlightGuide 3125
+#define wxStyledTextCtrl_GetLineEndPosition 3126
+#define wxStyledTextCtrl_GetCodePage 3127
+#define wxStyledTextCtrl_GetCaretForeground 3128
+#define wxStyledTextCtrl_GetReadOnly 3129
+#define wxStyledTextCtrl_SetCurrentPos 3130
+#define wxStyledTextCtrl_SetSelectionStart 3131
+#define wxStyledTextCtrl_GetSelectionStart 3132
+#define wxStyledTextCtrl_SetSelectionEnd 3133
+#define wxStyledTextCtrl_GetSelectionEnd 3134
+#define wxStyledTextCtrl_SetPrintMagnification 3135
+#define wxStyledTextCtrl_GetPrintMagnification 3136
+#define wxStyledTextCtrl_SetPrintColourMode 3137
+#define wxStyledTextCtrl_GetPrintColourMode 3138
+#define wxStyledTextCtrl_FindText 3139
+#define wxStyledTextCtrl_FormatRange 3140
+#define wxStyledTextCtrl_GetFirstVisibleLine 3141
+#define wxStyledTextCtrl_GetLine 3142
+#define wxStyledTextCtrl_GetLineCount 3143
+#define wxStyledTextCtrl_SetMarginLeft 3144
+#define wxStyledTextCtrl_GetMarginLeft 3145
+#define wxStyledTextCtrl_SetMarginRight 3146
+#define wxStyledTextCtrl_GetMarginRight 3147
+#define wxStyledTextCtrl_GetModify 3148
+#define wxStyledTextCtrl_SetSelection 3149
+#define wxStyledTextCtrl_GetSelectedText 3150
+#define wxStyledTextCtrl_GetTextRange 3151
+#define wxStyledTextCtrl_HideSelection 3152
+#define wxStyledTextCtrl_LineFromPosition 3153
+#define wxStyledTextCtrl_PositionFromLine 3154
+#define wxStyledTextCtrl_LineScroll 3155
+#define wxStyledTextCtrl_EnsureCaretVisible 3156
+#define wxStyledTextCtrl_ReplaceSelection 3157
+#define wxStyledTextCtrl_SetReadOnly 3158
+#define wxStyledTextCtrl_CanPaste 3159
+#define wxStyledTextCtrl_CanUndo 3160
+#define wxStyledTextCtrl_EmptyUndoBuffer 3161
+#define wxStyledTextCtrl_Undo 3162
+#define wxStyledTextCtrl_Cut 3163
+#define wxStyledTextCtrl_Copy 3164
+#define wxStyledTextCtrl_Paste 3165
+#define wxStyledTextCtrl_Clear 3166
+#define wxStyledTextCtrl_SetText 3167
+#define wxStyledTextCtrl_GetText 3168
+#define wxStyledTextCtrl_GetTextLength 3169
+#define wxStyledTextCtrl_GetOvertype 3170
+#define wxStyledTextCtrl_SetCaretWidth 3171
+#define wxStyledTextCtrl_GetCaretWidth 3172
+#define wxStyledTextCtrl_SetTargetStart 3173
+#define wxStyledTextCtrl_GetTargetStart 3174
+#define wxStyledTextCtrl_SetTargetEnd 3175
+#define wxStyledTextCtrl_GetTargetEnd 3176
+#define wxStyledTextCtrl_ReplaceTarget 3177
+#define wxStyledTextCtrl_SearchInTarget 3178
+#define wxStyledTextCtrl_SetSearchFlags 3179
+#define wxStyledTextCtrl_GetSearchFlags 3180
+#define wxStyledTextCtrl_CallTipShow 3181
+#define wxStyledTextCtrl_CallTipCancel 3182
+#define wxStyledTextCtrl_CallTipActive 3183
+#define wxStyledTextCtrl_CallTipPosAtStart 3184
+#define wxStyledTextCtrl_CallTipSetHighlight 3185
+#define wxStyledTextCtrl_CallTipSetBackground 3186
+#define wxStyledTextCtrl_CallTipSetForeground 3187
+#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3188
+#define wxStyledTextCtrl_CallTipUseStyle 3189
+#define wxStyledTextCtrl_VisibleFromDocLine 3190
+#define wxStyledTextCtrl_DocLineFromVisible 3191
+#define wxStyledTextCtrl_WrapCount 3192
+#define wxStyledTextCtrl_SetFoldLevel 3193
+#define wxStyledTextCtrl_GetFoldLevel 3194
+#define wxStyledTextCtrl_GetLastChild 3195
+#define wxStyledTextCtrl_GetFoldParent 3196
+#define wxStyledTextCtrl_ShowLines 3197
+#define wxStyledTextCtrl_HideLines 3198
+#define wxStyledTextCtrl_GetLineVisible 3199
+#define wxStyledTextCtrl_SetFoldExpanded 3200
+#define wxStyledTextCtrl_GetFoldExpanded 3201
+#define wxStyledTextCtrl_ToggleFold 3202
+#define wxStyledTextCtrl_EnsureVisible 3203
+#define wxStyledTextCtrl_SetFoldFlags 3204
+#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3205
+#define wxStyledTextCtrl_SetTabIndents 3206
+#define wxStyledTextCtrl_GetTabIndents 3207
+#define wxStyledTextCtrl_SetBackSpaceUnIndents 3208
+#define wxStyledTextCtrl_GetBackSpaceUnIndents 3209
+#define wxStyledTextCtrl_SetMouseDwellTime 3210
+#define wxStyledTextCtrl_GetMouseDwellTime 3211
+#define wxStyledTextCtrl_WordStartPosition 3212
+#define wxStyledTextCtrl_WordEndPosition 3213
+#define wxStyledTextCtrl_SetWrapMode 3214
+#define wxStyledTextCtrl_GetWrapMode 3215
+#define wxStyledTextCtrl_SetWrapVisualFlags 3216
+#define wxStyledTextCtrl_GetWrapVisualFlags 3217
+#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3218
+#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3219
+#define wxStyledTextCtrl_SetWrapStartIndent 3220
+#define wxStyledTextCtrl_GetWrapStartIndent 3221
+#define wxStyledTextCtrl_SetLayoutCache 3222
+#define wxStyledTextCtrl_GetLayoutCache 3223
+#define wxStyledTextCtrl_SetScrollWidth 3224
+#define wxStyledTextCtrl_GetScrollWidth 3225
+#define wxStyledTextCtrl_TextWidth 3226
+#define wxStyledTextCtrl_GetEndAtLastLine 3227
+#define wxStyledTextCtrl_TextHeight 3228
+#define wxStyledTextCtrl_SetUseVerticalScrollBar 3229
+#define wxStyledTextCtrl_GetUseVerticalScrollBar 3230
+#define wxStyledTextCtrl_AppendText 3231
+#define wxStyledTextCtrl_GetTwoPhaseDraw 3232
+#define wxStyledTextCtrl_SetTwoPhaseDraw 3233
+#define wxStyledTextCtrl_TargetFromSelection 3234
+#define wxStyledTextCtrl_LinesJoin 3235
+#define wxStyledTextCtrl_LinesSplit 3236
+#define wxStyledTextCtrl_SetFoldMarginColour 3237
+#define wxStyledTextCtrl_SetFoldMarginHiColour 3238
+#define wxStyledTextCtrl_LineDown 3239
+#define wxStyledTextCtrl_LineDownExtend 3240
+#define wxStyledTextCtrl_LineUp 3241
+#define wxStyledTextCtrl_LineUpExtend 3242
+#define wxStyledTextCtrl_CharLeft 3243
+#define wxStyledTextCtrl_CharLeftExtend 3244
+#define wxStyledTextCtrl_CharRight 3245
+#define wxStyledTextCtrl_CharRightExtend 3246
+#define wxStyledTextCtrl_WordLeft 3247
+#define wxStyledTextCtrl_WordLeftExtend 3248
+#define wxStyledTextCtrl_WordRight 3249
+#define wxStyledTextCtrl_WordRightExtend 3250
+#define wxStyledTextCtrl_Home 3251
+#define wxStyledTextCtrl_HomeExtend 3252
+#define wxStyledTextCtrl_LineEnd 3253
+#define wxStyledTextCtrl_LineEndExtend 3254
+#define wxStyledTextCtrl_DocumentStart 3255
+#define wxStyledTextCtrl_DocumentStartExtend 3256
+#define wxStyledTextCtrl_DocumentEnd 3257
+#define wxStyledTextCtrl_DocumentEndExtend 3258
+#define wxStyledTextCtrl_PageUp 3259
+#define wxStyledTextCtrl_PageUpExtend 3260
+#define wxStyledTextCtrl_PageDown 3261
+#define wxStyledTextCtrl_PageDownExtend 3262
+#define wxStyledTextCtrl_EditToggleOvertype 3263
+#define wxStyledTextCtrl_Cancel 3264
+#define wxStyledTextCtrl_DeleteBack 3265
+#define wxStyledTextCtrl_Tab 3266
+#define wxStyledTextCtrl_BackTab 3267
+#define wxStyledTextCtrl_NewLine 3268
+#define wxStyledTextCtrl_FormFeed 3269
+#define wxStyledTextCtrl_VCHome 3270
+#define wxStyledTextCtrl_VCHomeExtend 3271
+#define wxStyledTextCtrl_ZoomIn 3272
+#define wxStyledTextCtrl_ZoomOut 3273
+#define wxStyledTextCtrl_DelWordLeft 3274
+#define wxStyledTextCtrl_DelWordRight 3275
+#define wxStyledTextCtrl_LineCut 3276
+#define wxStyledTextCtrl_LineDelete 3277
+#define wxStyledTextCtrl_LineTranspose 3278
+#define wxStyledTextCtrl_LineDuplicate 3279
+#define wxStyledTextCtrl_LowerCase 3280
+#define wxStyledTextCtrl_UpperCase 3281
+#define wxStyledTextCtrl_LineScrollDown 3282
+#define wxStyledTextCtrl_LineScrollUp 3283
+#define wxStyledTextCtrl_DeleteBackNotLine 3284
+#define wxStyledTextCtrl_HomeDisplay 3285
+#define wxStyledTextCtrl_HomeDisplayExtend 3286
+#define wxStyledTextCtrl_LineEndDisplay 3287
+#define wxStyledTextCtrl_LineEndDisplayExtend 3288
+#define wxStyledTextCtrl_HomeWrapExtend 3289
+#define wxStyledTextCtrl_LineEndWrap 3290
+#define wxStyledTextCtrl_LineEndWrapExtend 3291
+#define wxStyledTextCtrl_VCHomeWrap 3292
+#define wxStyledTextCtrl_VCHomeWrapExtend 3293
+#define wxStyledTextCtrl_LineCopy 3294
+#define wxStyledTextCtrl_MoveCaretInsideView 3295
+#define wxStyledTextCtrl_LineLength 3296
+#define wxStyledTextCtrl_BraceHighlight 3297
+#define wxStyledTextCtrl_BraceBadLight 3298
+#define wxStyledTextCtrl_BraceMatch 3299
+#define wxStyledTextCtrl_GetViewEOL 3300
+#define wxStyledTextCtrl_SetViewEOL 3301
+#define wxStyledTextCtrl_SetModEventMask 3302
+#define wxStyledTextCtrl_GetEdgeColumn 3303
+#define wxStyledTextCtrl_SetEdgeColumn 3304
+#define wxStyledTextCtrl_SetEdgeMode 3305
+#define wxStyledTextCtrl_GetEdgeMode 3306
+#define wxStyledTextCtrl_GetEdgeColour 3307
+#define wxStyledTextCtrl_SetEdgeColour 3308
+#define wxStyledTextCtrl_SearchAnchor 3309
+#define wxStyledTextCtrl_SearchNext 3310
+#define wxStyledTextCtrl_SearchPrev 3311
+#define wxStyledTextCtrl_LinesOnScreen 3312
+#define wxStyledTextCtrl_UsePopUp 3313
+#define wxStyledTextCtrl_SelectionIsRectangle 3314
+#define wxStyledTextCtrl_SetZoom 3315
+#define wxStyledTextCtrl_GetZoom 3316
+#define wxStyledTextCtrl_GetModEventMask 3317
+#define wxStyledTextCtrl_SetSTCFocus 3318
+#define wxStyledTextCtrl_GetSTCFocus 3319
+#define wxStyledTextCtrl_SetStatus 3320
+#define wxStyledTextCtrl_GetStatus 3321
+#define wxStyledTextCtrl_SetMouseDownCaptures 3322
+#define wxStyledTextCtrl_GetMouseDownCaptures 3323
+#define wxStyledTextCtrl_SetSTCCursor 3324
+#define wxStyledTextCtrl_GetSTCCursor 3325
+#define wxStyledTextCtrl_SetControlCharSymbol 3326
+#define wxStyledTextCtrl_GetControlCharSymbol 3327
+#define wxStyledTextCtrl_WordPartLeft 3328
+#define wxStyledTextCtrl_WordPartLeftExtend 3329
+#define wxStyledTextCtrl_WordPartRight 3330
+#define wxStyledTextCtrl_WordPartRightExtend 3331
+#define wxStyledTextCtrl_SetVisiblePolicy 3332
+#define wxStyledTextCtrl_DelLineLeft 3333
+#define wxStyledTextCtrl_DelLineRight 3334
+#define wxStyledTextCtrl_GetXOffset 3335
+#define wxStyledTextCtrl_ChooseCaretX 3336
+#define wxStyledTextCtrl_SetXCaretPolicy 3337
+#define wxStyledTextCtrl_SetYCaretPolicy 3338
+#define wxStyledTextCtrl_GetPrintWrapMode 3339
+#define wxStyledTextCtrl_SetHotspotActiveForeground 3340
+#define wxStyledTextCtrl_SetHotspotActiveBackground 3341
+#define wxStyledTextCtrl_SetHotspotActiveUnderline 3342
+#define wxStyledTextCtrl_SetHotspotSingleLine 3343
+#define wxStyledTextCtrl_ParaDownExtend 3344
+#define wxStyledTextCtrl_ParaUp 3345
+#define wxStyledTextCtrl_ParaUpExtend 3346
+#define wxStyledTextCtrl_PositionBefore 3347
+#define wxStyledTextCtrl_PositionAfter 3348
+#define wxStyledTextCtrl_CopyRange 3349
+#define wxStyledTextCtrl_CopyText 3350
+#define wxStyledTextCtrl_SetSelectionMode 3351
+#define wxStyledTextCtrl_GetSelectionMode 3352
+#define wxStyledTextCtrl_LineDownRectExtend 3353
+#define wxStyledTextCtrl_LineUpRectExtend 3354
+#define wxStyledTextCtrl_CharLeftRectExtend 3355
+#define wxStyledTextCtrl_CharRightRectExtend 3356
+#define wxStyledTextCtrl_HomeRectExtend 3357
+#define wxStyledTextCtrl_VCHomeRectExtend 3358
+#define wxStyledTextCtrl_LineEndRectExtend 3359
+#define wxStyledTextCtrl_PageUpRectExtend 3360
+#define wxStyledTextCtrl_PageDownRectExtend 3361
+#define wxStyledTextCtrl_StutteredPageUp 3362
+#define wxStyledTextCtrl_StutteredPageUpExtend 3363
+#define wxStyledTextCtrl_StutteredPageDown 3364
+#define wxStyledTextCtrl_StutteredPageDownExtend 3365
+#define wxStyledTextCtrl_WordLeftEnd 3366
+#define wxStyledTextCtrl_WordLeftEndExtend 3367
+#define wxStyledTextCtrl_WordRightEnd 3368
+#define wxStyledTextCtrl_WordRightEndExtend 3369
+#define wxStyledTextCtrl_SetWhitespaceChars 3370
+#define wxStyledTextCtrl_SetCharsDefault 3371
+#define wxStyledTextCtrl_AutoCompGetCurrent 3372
+#define wxStyledTextCtrl_Allocate 3373
+#define wxStyledTextCtrl_FindColumn 3374
+#define wxStyledTextCtrl_GetCaretSticky 3375
+#define wxStyledTextCtrl_SetCaretSticky 3376
+#define wxStyledTextCtrl_ToggleCaretSticky 3377
+#define wxStyledTextCtrl_SetPasteConvertEndings 3378
+#define wxStyledTextCtrl_GetPasteConvertEndings 3379
+#define wxStyledTextCtrl_SelectionDuplicate 3380
+#define wxStyledTextCtrl_SetCaretLineBackAlpha 3381
+#define wxStyledTextCtrl_GetCaretLineBackAlpha 3382
+#define wxStyledTextCtrl_StartRecord 3383
+#define wxStyledTextCtrl_StopRecord 3384
+#define wxStyledTextCtrl_SetLexer 3385
+#define wxStyledTextCtrl_GetLexer 3386
+#define wxStyledTextCtrl_Colourise 3387
+#define wxStyledTextCtrl_SetProperty 3388
+#define wxStyledTextCtrl_SetKeyWords 3389
+#define wxStyledTextCtrl_SetLexerLanguage 3390
+#define wxStyledTextCtrl_GetProperty 3391
+#define wxStyledTextCtrl_GetStyleBitsNeeded 3392
+#define wxStyledTextCtrl_GetCurrentLine 3393
+#define wxStyledTextCtrl_StyleSetSpec 3394
+#define wxStyledTextCtrl_StyleSetFont 3395
+#define wxStyledTextCtrl_StyleSetFontAttr 3396
+#define wxStyledTextCtrl_StyleSetCharacterSet 3397
+#define wxStyledTextCtrl_StyleSetFontEncoding 3398
+#define wxStyledTextCtrl_CmdKeyExecute 3399
+#define wxStyledTextCtrl_SetMargins 3400
+#define wxStyledTextCtrl_GetSelection 3401
+#define wxStyledTextCtrl_PointFromPosition 3402
+#define wxStyledTextCtrl_ScrollToLine 3403
+#define wxStyledTextCtrl_ScrollToColumn 3404
+#define wxStyledTextCtrl_SetVScrollBar 3405
+#define wxStyledTextCtrl_SetHScrollBar 3406
+#define wxStyledTextCtrl_GetLastKeydownProcessed 3407
+#define wxStyledTextCtrl_SetLastKeydownProcessed 3408
+#define wxStyledTextCtrl_SaveFile 3409
+#define wxStyledTextCtrl_LoadFile 3410
+#define wxStyledTextCtrl_DoDragOver 3411
+#define wxStyledTextCtrl_DoDropText 3412
+#define wxStyledTextCtrl_GetUseAntiAliasing 3413
+#define wxStyledTextCtrl_AddTextRaw 3414
+#define wxStyledTextCtrl_InsertTextRaw 3415
+#define wxStyledTextCtrl_GetCurLineRaw 3416
+#define wxStyledTextCtrl_GetLineRaw 3417
+#define wxStyledTextCtrl_GetSelectedTextRaw 3418
+#define wxStyledTextCtrl_GetTextRangeRaw 3419
+#define wxStyledTextCtrl_SetTextRaw 3420
+#define wxStyledTextCtrl_GetTextRaw 3421
+#define wxStyledTextCtrl_AppendTextRaw 3422
+#define wxArtProvider_GetBitmap 3423
+#define wxArtProvider_GetIcon 3424
+#define wxTreeEvent_GetKeyCode 3425
+#define wxTreeEvent_GetItem 3426
+#define wxTreeEvent_GetKeyEvent 3427
+#define wxTreeEvent_GetLabel 3428
+#define wxTreeEvent_GetOldItem 3429
+#define wxTreeEvent_GetPoint 3430
+#define wxTreeEvent_IsEditCancelled 3431
+#define wxTreeEvent_SetToolTip 3432
+#define wxNotebookEvent_GetOldSelection 3433
+#define wxNotebookEvent_GetSelection 3434
+#define wxNotebookEvent_SetOldSelection 3435
+#define wxNotebookEvent_SetSelection 3436
+#define wxFileDataObject_new 3437
+#define wxFileDataObject_AddFile 3438
+#define wxFileDataObject_GetFilenames 3439
+#define wxFileDataObject_destroy 3440
+#define wxTextDataObject_new 3441
+#define wxTextDataObject_GetTextLength 3442
+#define wxTextDataObject_GetText 3443
+#define wxTextDataObject_SetText 3444
+#define wxTextDataObject_destroy 3445
+#define wxBitmapDataObject_new_1_1 3446
+#define wxBitmapDataObject_new_1_0 3447
+#define wxBitmapDataObject_GetBitmap 3448
+#define wxBitmapDataObject_SetBitmap 3449
+#define wxBitmapDataObject_destroy 3450
+#define wxClipboard_new 3452
+#define wxClipboard_destruct 3453
+#define wxClipboard_AddData 3454
+#define wxClipboard_Clear 3455
+#define wxClipboard_Close 3456
+#define wxClipboard_Flush 3457
+#define wxClipboard_GetData 3458
+#define wxClipboard_IsOpened 3459
+#define wxClipboard_Open 3460
+#define wxClipboard_SetData 3461
+#define wxClipboard_UsePrimarySelection 3463
+#define wxClipboard_IsSupported 3464
+#define wxClipboard_Get 3465
+#define wxSpinEvent_GetPosition 3466
+#define wxSpinEvent_SetPosition 3467
+#define wxSplitterWindow_new_0 3468
+#define wxSplitterWindow_new_2 3469
+#define wxSplitterWindow_destruct 3470
+#define wxSplitterWindow_Create 3471
+#define wxSplitterWindow_GetMinimumPaneSize 3472
+#define wxSplitterWindow_GetSashGravity 3473
+#define wxSplitterWindow_GetSashPosition 3474
+#define wxSplitterWindow_GetSplitMode 3475
+#define wxSplitterWindow_GetWindow1 3476
+#define wxSplitterWindow_GetWindow2 3477
+#define wxSplitterWindow_Initialize 3478
+#define wxSplitterWindow_IsSplit 3479
+#define wxSplitterWindow_ReplaceWindow 3480
+#define wxSplitterWindow_SetSashGravity 3481
+#define wxSplitterWindow_SetSashPosition 3482
+#define wxSplitterWindow_SetSashSize 3483
+#define wxSplitterWindow_SetMinimumPaneSize 3484
+#define wxSplitterWindow_SetSplitMode 3485
+#define wxSplitterWindow_SplitHorizontally 3486
+#define wxSplitterWindow_SplitVertically 3487
+#define wxSplitterWindow_Unsplit 3488
+#define wxSplitterWindow_UpdateSize 3489
+#define wxSplitterEvent_GetSashPosition 3490
+#define wxSplitterEvent_GetX 3491
+#define wxSplitterEvent_GetY 3492
+#define wxSplitterEvent_GetWindowBeingRemoved 3493
+#define wxSplitterEvent_SetSashPosition 3494
+#define wxHtmlWindow_new_0 3495
+#define wxHtmlWindow_new_2 3496
+#define wxHtmlWindow_AppendToPage 3497
+#define wxHtmlWindow_GetOpenedAnchor 3498
+#define wxHtmlWindow_GetOpenedPage 3499
+#define wxHtmlWindow_GetOpenedPageTitle 3500
+#define wxHtmlWindow_GetRelatedFrame 3501
+#define wxHtmlWindow_HistoryBack 3502
+#define wxHtmlWindow_HistoryCanBack 3503
+#define wxHtmlWindow_HistoryCanForward 3504
+#define wxHtmlWindow_HistoryClear 3505
+#define wxHtmlWindow_HistoryForward 3506
+#define wxHtmlWindow_LoadFile 3507
+#define wxHtmlWindow_LoadPage 3508
+#define wxHtmlWindow_SelectAll 3509
+#define wxHtmlWindow_SelectionToText 3510
+#define wxHtmlWindow_SelectLine 3511
+#define wxHtmlWindow_SelectWord 3512
+#define wxHtmlWindow_SetBorders 3513
+#define wxHtmlWindow_SetFonts 3514
+#define wxHtmlWindow_SetPage 3515
+#define wxHtmlWindow_SetRelatedFrame 3516
+#define wxHtmlWindow_SetRelatedStatusBar 3517
+#define wxHtmlWindow_ToText 3518
+#define wxHtmlWindow_destroy 3519
+#define wxHtmlLinkEvent_GetLinkInfo 3520
+#define wxSystemSettings_GetColour 3521
+#define wxSystemSettings_GetFont 3522
+#define wxSystemSettings_GetMetric 3523
+#define wxSystemSettings_GetScreenType 3524
+#define wxSystemOptions_GetOption 3525
+#define wxSystemOptions_GetOptionInt 3526
+#define wxSystemOptions_HasOption 3527
+#define wxSystemOptions_IsFalse 3528
+#define wxSystemOptions_SetOption_2_1 3529
+#define wxSystemOptions_SetOption_2_0 3530
+#define wxAuiNotebookEvent_SetSelection 3531
+#define wxAuiNotebookEvent_GetSelection 3532
+#define wxAuiNotebookEvent_SetOldSelection 3533
+#define wxAuiNotebookEvent_GetOldSelection 3534
+#define wxAuiNotebookEvent_SetDragSource 3535
+#define wxAuiNotebookEvent_GetDragSource 3536
+#define wxAuiManagerEvent_SetManager 3537
+#define wxAuiManagerEvent_GetManager 3538
+#define wxAuiManagerEvent_SetPane 3539
+#define wxAuiManagerEvent_GetPane 3540
+#define wxAuiManagerEvent_SetButton 3541
+#define wxAuiManagerEvent_GetButton 3542
+#define wxAuiManagerEvent_SetDC 3543
+#define wxAuiManagerEvent_GetDC 3544
+#define wxAuiManagerEvent_Veto 3545
+#define wxAuiManagerEvent_GetVeto 3546
+#define wxAuiManagerEvent_SetCanVeto 3547
+#define wxAuiManagerEvent_CanVeto 3548
+#define wxLogNull_new 3549
+#define wxLogNull_destroy 3550
+#define wxTaskBarIcon_new 3551
+#define wxTaskBarIcon_destruct 3552
+#define wxTaskBarIcon_PopupMenu 3553
+#define wxTaskBarIcon_RemoveIcon 3554
+#define wxTaskBarIcon_SetIcon 3555
+#define wxLocale_new_0 3556
+#define wxLocale_new_2 3558
+#define wxLocale_destruct 3559
+#define wxLocale_Init 3561
+#define wxLocale_AddCatalog_1 3562
+#define wxLocale_AddCatalog_3 3563
+#define wxLocale_AddCatalogLookupPathPrefix 3564
+#define wxLocale_GetCanonicalName 3565
+#define wxLocale_GetLanguage 3566
+#define wxLocale_GetLanguageName 3567
+#define wxLocale_GetLocale 3568
+#define wxLocale_GetName 3569
+#define wxLocale_GetString_2 3570
+#define wxLocale_GetString_4 3571
+#define wxLocale_GetHeaderValue 3572
+#define wxLocale_GetSysName 3573
+#define wxLocale_GetSystemEncoding 3574
+#define wxLocale_GetSystemEncodingName 3575
+#define wxLocale_GetSystemLanguage 3576
+#define wxLocale_IsLoaded 3577
+#define wxLocale_IsOk 3578
+#define wxActivateEvent_GetActive 3579
+#define wxPopupWindow_new_2 3581
+#define wxPopupWindow_new_0 3582
+#define wxPopupWindow_destruct 3584
+#define wxPopupWindow_Create 3585
+#define wxPopupWindow_Position 3586
+#define wxPopupTransientWindow_new_0 3587
+#define wxPopupTransientWindow_new_2 3588
+#define wxPopupTransientWindow_destruct 3589
+#define wxPopupTransientWindow_Popup 3590
+#define wxPopupTransientWindow_Dismiss 3591
+#define wxOverlay_new 3592
+#define wxOverlay_destruct 3593
+#define wxOverlay_Reset 3594
+#define wxDCOverlay_new_6 3595
+#define wxDCOverlay_new_2 3596
+#define wxDCOverlay_destruct 3597
+#define wxDCOverlay_Clear 3598
diff --git a/lib/wx/c_src/wxe_callback_impl.cpp b/lib/wx/c_src/wxe_callback_impl.cpp
index 3a59004eb0..eae8e99a95 100644
--- a/lib/wx/c_src/wxe_callback_impl.cpp
+++ b/lib/wx/c_src/wxe_callback_impl.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/wxe_callback_impl.h b/lib/wx/c_src/wxe_callback_impl.h
index ecfcd3db41..829a60af0d 100644
--- a/lib/wx/c_src/wxe_callback_impl.h
+++ b/lib/wx/c_src/wxe_callback_impl.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c
index ea52737fa2..6f027ea25b 100644
--- a/lib/wx/c_src/wxe_driver.c
+++ b/lib/wx/c_src/wxe_driver.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -118,7 +119,11 @@ wxe_driver_start(ErlDrvPort port, char *buff)
ErlDrvTermData term_port = driver_mk_port(port);
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
data->driver_data = NULL;
- data->bin = NULL;
+ data->bin = (WXEBinRef*) driver_alloc(sizeof(WXEBinRef)*DEF_BINS);
+ data->bin[0].from = 0;
+ data->bin[1].from = 0;
+ data->bin[2].from = 0;
+ data->max_bins = DEF_BINS;
data->port_handle = port;
data->port = term_port;
data->pdl = driver_pdl_create(port);
@@ -146,7 +151,12 @@ wxe_driver_stop(ErlDrvData handle)
if(sd->port_handle != WXE_DRV_PORT_HANDLE) {
// fprintf(stderr, "%s:%d: STOP \r\n", __FILE__,__LINE__);
meta_command(DELETE_PORT,sd);
- free(handle);
+ } else {
+ // fprintf(stderr, "%s:%d: STOP \r\n", __FILE__,__LINE__);
+ stop_native_gui(wxe_master);
+ unload_native_gui();
+ free(wxe_master);
+ wxe_master = NULL;
}
}
@@ -154,10 +164,6 @@ static void
wxe_driver_unload(void)
{
// fprintf(stderr, "%s:%d: UNLOAD \r\n", __FILE__,__LINE__);
- stop_native_gui(wxe_master);
- unload_native_gui();
- free(wxe_master);
- wxe_master = NULL;
}
static ErlDrvSSizeT
@@ -207,26 +213,38 @@ static void
standard_outputv(ErlDrvData drv_data, ErlIOVec* ev)
{
wxe_data* sd = (wxe_data *) drv_data;
- WXEBinRef * binref;
+ WXEBinRef * binref = NULL;
ErlDrvBinary* bin;
-
+ int i, max;
+
+ for(i = 0; i < sd->max_bins; i++) {
+ if(sd->bin[i].from == 0) {
+ binref = &sd->bin[i];
+ break;
+ }
+ }
+
+ if(binref == NULL) { /* realloc */
+ max = sd->max_bins + DEF_BINS;
+ driver_realloc(sd->bin, sizeof(WXEBinRef)*max);
+ for(i=sd->max_bins; i < max; i++) {
+ sd->bin[i].from = 0;
+ }
+ binref = &sd->bin[sd->max_bins];
+ sd->max_bins = max;
+ }
+
if(ev->vsize == 2) {
- binref = driver_alloc(sizeof(WXEBinRef));
binref->base = ev->iov[1].iov_base;
binref->size = ev->iov[1].iov_len;
binref->from = driver_caller(sd->port_handle);
bin = ev->binv[1];
driver_binary_inc_refc(bin); /* Otherwise it could get deallocated */
binref->bin = bin;
- binref->next = sd->bin;
- sd->bin = binref;
- } else { /* Empty binary (becomes NULL) */
- binref = driver_alloc(sizeof(WXEBinRef));
+ } else { /* Empty binary (becomes NULL) */
binref->base = NULL;
binref->size = 0;
binref->from = driver_caller(sd->port_handle);
binref->bin = NULL;
- binref->next = sd->bin;
- sd->bin = binref;
}
}
diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h
index e35bbe2118..925078962e 100644
--- a/lib/wx/c_src/wxe_driver.h
+++ b/lib/wx/c_src/wxe_driver.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -37,12 +38,12 @@ typedef struct wxe_bin_ref {
size_t size;
ErlDrvBinary* bin;
ErlDrvTermData from;
- WXEBinRefptr next;
} WXEBinRef;
-typedef struct wxe_data_def {
+typedef struct wxe_data_def {
void * driver_data;
WXEBinRef * bin; /* Argument binaries */
+ Uint32 max_bins;
ErlDrvPort port_handle;
ErlDrvTermData port;
int is_cbport;
@@ -50,6 +51,9 @@ typedef struct wxe_data_def {
} wxe_data;
+/* Number of bins per port should be small */
+#define DEF_BINS 3
+
void init_glexts(wxe_data*);
int load_native_gui();
diff --git a/lib/wx/c_src/wxe_events.h b/lib/wx/c_src/wxe_events.h
index 93b5551123..0908541812 100644
--- a/lib/wx/c_src/wxe_events.h
+++ b/lib/wx/c_src/wxe_events.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp
index a9feb23831..7f2e767a6b 100644
--- a/lib/wx/c_src/wxe_gl.cpp
+++ b/lib/wx/c_src/wxe_gl.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -67,7 +68,7 @@ void dlclose(HMODULE Lib) {
typedef void * DL_LIB_P;
#endif
-void wxe_initOpenGL(wxeReturn rt, char *bp) {
+void wxe_initOpenGL(wxeReturn *rt, char *bp) {
DL_LIB_P LIBhandle;
int (*init_opengl)(void *);
#ifdef _WIN32
@@ -82,9 +83,9 @@ void wxe_initOpenGL(wxeReturn rt, char *bp) {
wxe_gl_dispatch = (WXE_GL_DISPATCH) dlsym(LIBhandle, "egl_dispatch");
if(init_opengl && wxe_gl_dispatch) {
(*init_opengl)(erlCallbacks);
- rt.addAtom((char *) "ok");
- rt.add(wxString::FromAscii("initiated"));
- rt.addTupleCount(2);
+ rt->addAtom((char *) "ok");
+ rt->add(wxString::FromAscii("initiated"));
+ rt->addTupleCount(2);
erl_gl_initiated = TRUE;
} else {
wxString msg;
@@ -95,24 +96,24 @@ void wxe_initOpenGL(wxeReturn rt, char *bp) {
msg += wxT("egl_init_opengl ");
if(!wxe_gl_dispatch)
msg += wxT("egl_dispatch ");
- rt.addAtom((char *) "error");
- rt.add(msg);
- rt.addTupleCount(2);
+ rt->addAtom((char *) "error");
+ rt->add(msg);
+ rt->addTupleCount(2);
}
} else {
wxString msg;
msg.Printf(wxT("Could not load dll: "));
msg += wxString::FromAscii(bp);
- rt.addAtom((char *) "error");
- rt.add(msg);
- rt.addTupleCount(2);
+ rt->addAtom((char *) "error");
+ rt->add(msg);
+ rt->addTupleCount(2);
}
} else {
- rt.addAtom((char *) "ok");
- rt.add(wxString::FromAscii("already initilized"));
- rt.addTupleCount(2);
+ rt->addAtom((char *) "ok");
+ rt->add(wxString::FromAscii("already initilized"));
+ rt->addTupleCount(2);
}
- rt.send();
+ rt->send();
}
void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas)
@@ -132,11 +133,15 @@ void deleteActiveGL(wxGLCanvas *canvas)
}
}
-void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){
+void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins){
if(caller != gl_active) {
wxGLCanvas * current = glc[caller];
- if(current) { gl_active = caller; current->SetCurrent();}
- else {
+ if(current) {
+ if(current != glc[gl_active]) {
+ current->SetCurrent();
+ }
+ gl_active = caller;
+ } else {
ErlDrvTermData rt[] = // Error msg
{ERL_DRV_ATOM, driver_mk_atom((char *) "_egl_error_"),
ERL_DRV_INT, (ErlDrvTermData) op,
@@ -149,12 +154,12 @@ void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){
char * bs[3];
int bs_sz[3];
for(int i=0; i<3; i++) {
- if(bins[i]) {
- bs[i] = bins[i]->base;
- bs_sz[i] = bins[i]->size;
+ if(bins[i].from) {
+ bs[i] = bins[i].base;
+ bs_sz[i] = bins[i].size;
}
- else
- bs[i] = NULL;
+ else
+ break;
}
wxe_gl_dispatch(op, bp, WXE_DRV_PORT_HANDLE, caller, bs, bs_sz);
}
diff --git a/lib/wx/c_src/wxe_gl.h b/lib/wx/c_src/wxe_gl.h
index dc117bf610..45a2a1ac23 100644
--- a/lib/wx/c_src/wxe_gl.h
+++ b/lib/wx/c_src/wxe_gl.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -26,8 +27,8 @@
void activateGL(ErlDrvTermData caller);
void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas);
void deleteActiveGL(wxGLCanvas *canvas);
-void wxe_initOpenGL(wxeReturn, char*);
-void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins[]);
+void wxe_initOpenGL(wxeReturn *, char*);
+void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins);
WX_DECLARE_HASH_MAP(ErlDrvTermData, wxGLCanvas*, wxIntegerHash, wxIntegerEqual, wxeGLC);
extern wxeGLC glc;
diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp
index 15d75080d9..1696b8bd50 100644
--- a/lib/wx/c_src/wxe_helpers.cpp
+++ b/lib/wx/c_src/wxe_helpers.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -24,58 +25,208 @@
* Erlang Commands
* ****************************************************************************/
-wxeCommand::wxeCommand(int fc,char * cbuf,int buflen, wxe_data *sd)
- : wxObject()
+wxeCommand::wxeCommand()
+{
+}
+
+wxeCommand::~wxeCommand()
+{
+ Delete();
+}
+
+void wxeCommand::Delete()
{
- WXEBinRef *temp, *start, *prev;
int n = 0;
- ref_count = 1;
- caller = driver_caller(sd->port_handle);
- port = sd->port;
- op = fc;
- len = buflen;
- bin[0] = NULL;
- bin[1] = NULL;
- bin[2] = NULL;
- if(cbuf) {
- buffer = (char *) driver_alloc(len);
- memcpy((void *) buffer, (void *) cbuf, len);;
-
- temp = sd->bin;
-
- prev = NULL;
- start = temp;
-
- while(temp) {
- if(caller == temp->from) {
- bin[n++] = temp;
- if(prev) {
- prev->next = temp->next;
- } else {
- start = temp->next;
- }
- temp = temp->next;
- } else {
- prev = temp;
- temp = temp->next;
- }
+ if(buffer) {
+ while(bin[n].from) {
+ if(bin[n].bin)
+ driver_free_binary(bin[n].bin);
+ n++;
}
- sd->bin = start;
- } else { // No-op only PING currently
+ if(len > 64)
+ driver_free(buffer);
buffer = NULL;
+ op = -1;
+ }
+}
+
+/* ****************************************************************************
+ * wxeFifo
+ * ****************************************************************************/
+wxeFifo::wxeFifo(unsigned int sz)
+{
+ m_q = (wxeCommand *) driver_alloc(sizeof(wxeCommand) * sz);
+ m_orig_sz = sz;
+ m_max = sz;
+ m_n = 0;
+ m_first = 0;
+ cb_start = 0;
+ m_old = NULL;
+ for(unsigned int i = 0; i < sz; i++) {
+ m_q[i].buffer = NULL;
+ m_q[i].op = -1;
}
}
-wxeCommand::~wxeCommand() {
+wxeFifo::~wxeFifo() {
+ // dealloc all memory buffers
+ driver_free(m_q);
+}
+
+wxeCommand * wxeFifo::Get()
+{
+ unsigned int pos;
+ do {
+ if(m_n <= 0)
+ return NULL;
+
+ pos = m_first++;
+ m_n--;
+ m_first %= m_max;
+ } while(m_q[pos].op == -1);
+ return &m_q[pos];
+}
+
+wxeCommand * wxeFifo::Peek(unsigned int *i)
+{
+ unsigned int pos;
+ do {
+ if(*i >= m_n || m_n <= 0)
+ return NULL;
+ pos = (m_first+*i) % m_max;
+ (*i)++;
+ } while(m_q[pos].op == -1);
+ return &m_q[pos];
+}
+
+
+void wxeFifo::Add(int fc, char * cbuf,int buflen, wxe_data *sd)
+{
+ unsigned int pos;
+ wxeCommand *curr;
+
int n = 0;
- if(buffer) {
- while(bin[n]) {
- if(bin[n]->bin)
- driver_free_binary(bin[n]->bin);
- driver_free(bin[n++]);
+
+ if(m_n == (m_max-1)) { // resize
+ Realloc();
+ }
+
+ pos = (m_first + m_n) % m_max;
+ m_n++;
+
+ curr = &m_q[pos];
+ curr->caller = driver_caller(sd->port_handle);
+ curr->port = sd->port;
+ curr->op = fc;
+ curr->len = buflen;
+ curr->bin[0].from = 0;
+ curr->bin[1].from = 0;
+ curr->bin[2].from = 0;
+
+ if(cbuf) {
+ if(buflen > 64)
+ curr->buffer = (char *) driver_alloc(buflen);
+ else
+ curr->buffer = curr->c_buf;
+ memcpy((void *) curr->buffer, (void *) cbuf, buflen);
+
+ for(unsigned int i=0; i<sd->max_bins; i++) {
+ if(curr->caller == sd->bin[i].from) {
+ sd->bin[i].from = 0; // Mark copied
+ curr->bin[n].bin = sd->bin[i].bin;
+ curr->bin[n].base = sd->bin[i].base;
+ curr->bin[n].size = sd->bin[i].size;
+ curr->bin[n].from = 1;
+ n++;
+ }
}
- driver_free(buffer);
+ } else { // No-op only PING currently
+ curr->buffer = NULL;
+ }
+}
+
+void wxeFifo::Append(wxeCommand *orig)
+{
+ unsigned int pos;
+ wxeCommand *curr;
+ if(m_n == (m_max-1)) { // resize
+ Realloc();
+ }
+
+ pos = (m_first + m_n) % m_max;
+ m_n++;
+
+ curr = &m_q[pos];
+ curr->op = orig->op;
+ if(curr->op == -1) return;
+ curr->caller = orig->caller;
+ curr->port = orig->port;
+ curr->len = orig->len;
+ curr->bin[0] = orig->bin[0];
+ curr->bin[1] = orig->bin[1];
+ curr->bin[2] = orig->bin[2];
+
+ if(orig->len > 64)
+ curr->buffer = orig->buffer;
+ else {
+ curr->buffer = curr->c_buf;
+ memcpy((void *) curr->buffer, (void *) orig->buffer, orig->len);
+ }
+ orig->op = -1;
+ orig->buffer = NULL;
+ orig->bin[0].from = 0;
+}
+
+void wxeFifo::Realloc()
+{
+ unsigned int i;
+ unsigned int growth = m_orig_sz / 2;
+ unsigned int new_sz = growth + m_max;
+ unsigned int max = m_max;
+ unsigned int first = m_first;
+ unsigned int n = m_n;
+ wxeCommand * old = m_q;
+ wxeCommand * queue = (wxeCommand *)driver_alloc(new_sz*sizeof(wxeCommand));
+
+ // fprintf(stderr, "\r\nrealloc qsz %d\r\n", new_sz);fflush(stderr);
+
+ m_max=new_sz;
+ m_first = 0;
+ m_n=0;
+ m_q = queue;
+
+ for(i=0; i < n; i++) {
+ unsigned int pos = (i+first)%max;
+ if(old[pos].op >= 0)
+ Append(&old[pos]);
+ }
+
+ for(i = m_n; i < new_sz; i++) { // Reset the rest
+ m_q[i].buffer = NULL;
+ m_q[i].op = -1;
+ }
+ // Can not free old queue here it can be used in the wx thread
+ m_old = old;
+}
+
+// Strip end of queue if ops are already taken care of, avoids reallocs
+void wxeFifo::Strip()
+{
+ while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op == -1)) {
+ m_n--;
+ }
+}
+
+unsigned int wxeFifo::Cleanup(unsigned int def)
+{
+ if(m_old) {
+ driver_free(m_old);
+ m_old = NULL;
+ // Realloced we need to start from the beginning
+ return 0;
+ } else {
+ return def;
}
}
diff --git a/lib/wx/c_src/wxe_helpers.h b/lib/wx/c_src/wxe_helpers.h
index 659bc666c6..ff949e332b 100644
--- a/lib/wx/c_src/wxe_helpers.h
+++ b/lib/wx/c_src/wxe_helpers.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -39,22 +40,46 @@ class wxeMetaCommand : public wxEvent
ErlDrvPDL pdl;
};
-class wxeCommand : public wxObject
+class wxeCommand
{
public:
- wxeCommand(int fc,char * cbuf,int buflen, wxe_data *);
+ wxeCommand();
virtual ~wxeCommand(); // Use Delete()
- wxeCommand * Save() {ref_count++; return this; };
- void Delete() {if(--ref_count < 1) delete this;};
+ wxeCommand * Save() { return this; };
+ void Delete();
ErlDrvTermData caller;
ErlDrvTermData port;
- WXEBinRef * bin[3];
+ WXEBinRef bin[3];
char * buffer;
int len;
int op;
- int ref_count;
+ char c_buf[64]; // 64b covers 90% of usage
+};
+
+class wxeFifo {
+ public:
+ wxeFifo(unsigned int size);
+ virtual ~wxeFifo();
+
+ void Add(int fc, char * cbuf,int buflen, wxe_data *);
+ void Append(wxeCommand *Other);
+
+ wxeCommand * Get();
+ wxeCommand * Peek(unsigned int *item);
+
+ void Realloc();
+ void Strip();
+ unsigned int Cleanup(unsigned int peek=0);
+
+ unsigned int cb_start;
+ unsigned int m_max;
+ unsigned int m_first;
+ unsigned int m_n;
+ unsigned int m_orig_sz;
+ wxeCommand *m_q;
+ wxeCommand *m_old;
};
class intListElement {
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 0ee52e3af2..f81d0bbbd9 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -55,9 +56,9 @@ extern ErlDrvCond * wxe_batch_locker_c;
extern ErlDrvTermData init_caller;
extern int wxe_status;
-wxList * wxe_batch = NULL;
-wxList * wxe_batch_cb_saved = NULL;
-int wxe_batch_caller = 0; // inside batch if larger than 0
+wxeFifo * wxe_queue = NULL;
+
+unsigned int wxe_needs_signal = 0; // inside batch if larger than 0
/* ************************************************************
* Commands from erlang
@@ -68,38 +69,37 @@ void push_command(int op,char * buf,int len, wxe_data *sd)
{
/* fprintf(stderr, "Op %d %d [%ld] %d\r\n", op, (int) driver_caller(sd->port_handle),
wxe_batch->size(), wxe_batch_caller),fflush(stderr); */
- wxeCommand *Cmd = new wxeCommand(op, buf, len, sd);
erl_drv_mutex_lock(wxe_batch_locker_m);
- wxe_batch->Append(Cmd);
+ wxe_queue->Add(op, buf, len, sd);
- if(wxe_batch_caller > 0) {
+ if(wxe_needs_signal) {
// wx-thread is waiting on batch end in cond_wait
erl_drv_cond_signal(wxe_batch_locker_c);
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
} else {
// wx-thread is waiting gui-events
- if(op == WXE_BATCH_BEGIN) {
- wxe_batch_caller = 1;
- }
- erl_drv_cond_signal(wxe_batch_locker_c);
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
wxWakeUpIdle();
}
- erl_drv_mutex_unlock(wxe_batch_locker_m);
}
void meta_command(int what, wxe_data *sd) {
- if(what == PING_PORT) {
+ if(what == PING_PORT && wxe_status == WXE_INITIATED) {
erl_drv_mutex_lock(wxe_batch_locker_m);
- if(wxe_batch_caller > 0) {
- wxeCommand *Cmd = new wxeCommand(WXE_DEBUG_PING, NULL, 0, sd);
- wxe_batch->Append(Cmd);
+ if(wxe_needs_signal) {
+ wxe_queue->Add(WXE_DEBUG_PING, NULL, 0, sd);
erl_drv_cond_signal(wxe_batch_locker_c);
}
wxWakeUpIdle();
erl_drv_mutex_unlock(wxe_batch_locker_m);
} else {
- if(sd) {
+ if(sd && wxe_status == WXE_INITIATED) {
wxeMetaCommand Cmd(sd, what);
wxTheApp->AddPendingEvent(Cmd);
+ if(what == DELETE_PORT) {
+ driver_free(sd->bin);
+ free(sd);
+ }
}
}
}
@@ -121,12 +121,11 @@ bool WxeApp::OnInit()
{
global_me = new wxeMemEnv();
- wxe_batch = new wxList;
- wxe_batch_cb_saved = new wxList;
+ wxe_queue = new wxeFifo(2000);
cb_buff = NULL;
recurse_level = 0;
- delayed_cleanup = new wxList;
- delayed_delete = new wxList;
+ delayed_delete = new wxeFifo(100);
+ delayed_cleanup = new wxList;
wxe_ps_init2();
// wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED); // Hmm printpreview doesn't work in 2.9 with this
@@ -168,7 +167,9 @@ void WxeApp::MacOpenFile(const wxString &filename) {
#endif
void WxeApp::shutdown(wxeMetaCommand& Ecmd) {
+ wxe_status = WXE_EXITING;
ExitMainLoop();
+ delete wxe_queue;
}
void WxeApp::dummy_close(wxEvent& Ev) {
@@ -177,6 +178,25 @@ void WxeApp::dummy_close(wxEvent& Ev) {
// windows open, and this will kill the erlang, override default handling
}
+void WxeApp::OnAssertFailure(const wxChar *file, int line, const wxChar *cfunc,
+ const wxChar *cond, const wxChar *cmsgUser) {
+ wxString msg;
+ wxString func(cfunc);
+ wxString msgUser(cmsgUser);
+
+ msg.Printf(wxT("wxWidgets Assert failure: %s(%d): \"%s\""),
+ file, line, cond);
+ if ( !func.empty() ) {
+ msg << wxT(" in ") << func << wxT("()");
+ }
+ // and the message itself
+ if ( !msgUser.empty() ) {
+ msg << wxT(" : ") << msgUser;
+ }
+
+ send_msg("error", &msg);
+}
+
// Called by wx thread
void WxeApp::idle(wxIdleEvent& event) {
event.Skip(true);
@@ -197,41 +217,40 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process)
{
WxeApp * app = (WxeApp *) wxTheApp;
ErlDrvMonitor monitor;
+
+ if(wxe_status != WXE_INITIATED)
+ return;
+
// Is thread safe if pdl have been incremented
if(driver_monitor_process(port, process, &monitor) == 0) {
// Should we be able to handle commands when recursing? probably
- erl_drv_mutex_lock(wxe_batch_locker_m);
- //fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr);
+ // fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr);
app->recurse_level++;
- app->dispatch_cb(wxe_batch, wxe_batch_cb_saved, process);
+ app->dispatch_cb(wxe_queue, process);
app->recurse_level--;
- //fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr);
- wxe_batch_caller = 0;
- erl_drv_mutex_unlock(wxe_batch_locker_m);
+ // fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr);
driver_demonitor_process(port, &monitor);
}
}
void WxeApp::dispatch_cmds()
{
- erl_drv_mutex_lock(wxe_batch_locker_m);
+ if(wxe_status != WXE_INITIATED)
+ return;
recurse_level++;
- int level = dispatch(wxe_batch_cb_saved, 0, WXE_STORED);
- dispatch(wxe_batch, level, WXE_NORMAL);
+ // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr);
+ dispatch(wxe_queue);
+ // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr);
recurse_level--;
- wxe_batch_caller = 0;
- erl_drv_mutex_unlock(wxe_batch_locker_m);
+
// Cleanup old memenv's and deleted objects
if(recurse_level == 0) {
- if(delayed_delete->size() > 0)
- for( wxList::compatibility_iterator node = delayed_delete->GetFirst();
- node;
- node = delayed_delete->GetFirst()) {
- wxeCommand *event = (wxeCommand *)node->GetData();
- delayed_delete->Erase(node);
- wxe_dispatch(*event);
- event->Delete();
- }
+ wxeCommand *curr;
+ while((curr = delayed_delete->Get()) != NULL) {
+ wxe_dispatch(*curr);
+ curr->Delete();
+ }
+ delayed_delete->Cleanup();
if(delayed_cleanup->size() > 0)
for( wxList::compatibility_iterator node = delayed_cleanup->GetFirst();
node;
@@ -244,152 +263,122 @@ void WxeApp::dispatch_cmds()
}
}
-// Should have erl_drv_mutex_lock(wxe_batch_locker_m);
-// when entering this function and it should be released
-// afterwards
-int WxeApp::dispatch(wxList * batch, int blevel, int list_type)
+int WxeApp::dispatch(wxeFifo * batch)
{
int ping = 0;
- // erl_drv_mutex_lock(wxe_batch_locker_m); must be locked already
- while(true)
- {
- if (batch->size() > 0) {
- for( wxList::compatibility_iterator node = batch->GetFirst();
- node;
- node = batch->GetFirst())
- {
- wxeCommand *event = (wxeCommand *)node->GetData();
- batch->Erase(node);
- switch(event->op) {
- case WXE_BATCH_END:
- {--blevel; }
- break;
- case WXE_BATCH_BEGIN:
- {blevel++; }
- break;
- case WXE_DEBUG_PING:
- // When in debugger we don't want to hang waiting for a BATCH_END
- // that never comes, because a breakpoint have hit.
- ping++;
- if(ping > 2)
- blevel = 0;
- break;
- case WXE_CB_RETURN:
- // erl_drv_mutex_unlock(wxe_batch_locker_m); should be called after
- // whatever cleaning is necessary
- if(event->len > 0) {
- cb_buff = (char *) driver_alloc(event->len);
- memcpy(cb_buff, event->buffer, event->len);
- }
- return blevel;
- default:
- erl_drv_mutex_unlock(wxe_batch_locker_m);
- if(event->op < OPENGL_START) {
- // fprintf(stderr, " c %d (%d) \r\n", event->op, blevel);
- wxe_dispatch(*event);
- } else {
- gl_dispatch(event->op,event->buffer,event->caller,event->bin);
- }
- erl_drv_mutex_lock(wxe_batch_locker_m);
- break;
- }
- event->Delete();
- }
- } else {
- if((list_type == WXE_STORED) || (blevel <= 0 && list_type == WXE_NORMAL)) {
- // erl_drv_mutex_unlock(wxe_batch_locker_m); should be called after
- // whatever cleaning is necessary
- return blevel;
+ int blevel = 0;
+ wxeCommand *event;
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ while(true) {
+ while((event = batch->Get()) != NULL) {
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
+ switch(event->op) {
+ case WXE_BATCH_END:
+ {--blevel; }
+ break;
+ case WXE_BATCH_BEGIN:
+ {blevel++; }
+ break;
+ case WXE_DEBUG_PING:
+ // When in debugger we don't want to hang waiting for a BATCH_END
+ // that never comes, because a breakpoint have hit.
+ ping++;
+ if(ping > 2)
+ blevel = 0;
+ break;
+ case WXE_CB_RETURN:
+ if(event->len > 0) {
+ cb_buff = (char *) driver_alloc(event->len);
+ memcpy(cb_buff, event->buffer, event->len);
}
- // sleep until something happens
- //fprintf(stderr, "%s:%d sleep %d %d %d %d \r\n", __FILE__, __LINE__, batch->size(), callback_returned, blevel, is_callback);fflush(stderr);
- wxe_batch_caller++;
- while(batch->size() == 0) {
- erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
+ event->Delete();
+ return blevel;
+ default:
+ if(event->op < OPENGL_START) {
+ // fprintf(stderr, " c %d (%d) \r\n", event->op, blevel);
+ wxe_dispatch(*event);
+ } else {
+ gl_dispatch(event->op,event->buffer,event->caller,event->bin);
}
+ break;
}
+ event->Delete();
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ batch->Cleanup();
+ }
+ if(blevel <= 0) {
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
+ return blevel;
+ }
+ // sleep until something happens
+ //fprintf(stderr, "%s:%d sleep %d %d\r\n", __FILE__, __LINE__, batch->m_n, blevel);fflush(stderr);
+ wxe_needs_signal = 1;
+ while(batch->m_n == 0) {
+ erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
}
+ wxe_needs_signal = 0;
+ }
}
-void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) {
- int callback_returned = 0;
+void WxeApp::dispatch_cb(wxeFifo * batch, ErlDrvTermData process) {
+ wxeCommand *event;
+ unsigned int peek;
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ peek = batch->Cleanup(batch->cb_start);
while(true) {
- if (batch->size() > 0) {
- for( wxList::compatibility_iterator node = batch->GetFirst();
- node;
- node = batch->GetFirst())
- {
- wxeCommand *event = (wxeCommand *)node->GetData();
- wxeMemEnv *memenv = getMemEnv(event->port);
- batch->Erase(node);
- // fprintf(stderr, " Ev %d %lu\r\n", event->op, event->caller);
- if(event->caller == process || // Callbacks from CB process only
- event->op == WXE_CB_START || // Event callback start change process
- event->op == WXE_CB_DIED || // Event callback process died
- // Allow connect_cb during CB i.e. msg from wxe_server.
- (memenv && event->caller == memenv->owner))
- {
- switch(event->op) {
- case WXE_BATCH_END:
- case WXE_BATCH_BEGIN:
- case WXE_DEBUG_PING:
- break;
- case WXE_CB_RETURN:
- if(event->len > 0) {
- cb_buff = (char *) driver_alloc(event->len);
- memcpy(cb_buff, event->buffer, event->len);
- } // continue
- case WXE_CB_DIED:
- callback_returned = 1;
- return;
- case WXE_CB_START:
- // CB start from now accept message from CB process only
- process = event->caller;
- break;
- default:
- erl_drv_mutex_unlock(wxe_batch_locker_m);
- size_t start=temp->GetCount();
- if(event->op < OPENGL_START) {
- // fprintf(stderr, " cb %d \r\n", event->op);
- wxe_dispatch(*event);
- } else {
- gl_dispatch(event->op,event->buffer,event->caller,event->bin);
- }
- erl_drv_mutex_lock(wxe_batch_locker_m);
- if(temp->GetCount() > start) {
- // We have recursed dispatch_cb and messages for this
- // callback may be saved on temp list move them
- // to orig list
- for(wxList::compatibility_iterator node = temp->Item(start);
- node;
- node = node->GetNext()) {
- wxeCommand *ev = (wxeCommand *)node->GetData();
- if(ev->caller == process) {
- batch->Append(ev);
- temp->Erase(node);
- }
- }
- }
- if(callback_returned)
- return;
- break;
- }
- event->Delete();
- } else {
- // fprintf(stderr, " save %d \r\n", event->op);
- temp->Append(event);
+ while((event = batch->Peek(&peek)) != NULL) {
+ wxeMemEnv *memenv = getMemEnv(event->port);
+ // fprintf(stderr, " Ev %d %lu\r\n", event->op, event->caller);
+ if(event->caller == process || // Callbacks from CB process only
+ event->op == WXE_CB_START || // Event callback start change process
+ event->op == WXE_CB_DIED || // Event callback process died
+ // Allow connect_cb during CB i.e. msg from wxe_server.
+ (memenv && event->caller == memenv->owner)) {
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
+ switch(event->op) {
+ case WXE_BATCH_END:
+ case WXE_BATCH_BEGIN:
+ case WXE_DEBUG_PING:
+ break;
+ case WXE_CB_RETURN:
+ if(event->len > 0) {
+ cb_buff = (char *) driver_alloc(event->len);
+ memcpy(cb_buff, event->buffer, event->len);
+ } // continue
+ case WXE_CB_DIED:
+ batch->cb_start = 0;
+ event->Delete();
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ batch->Strip();
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
+ return;
+ case WXE_CB_START:
+ // CB start from now accept message from CB process only
+ process = event->caller;
+ break;
+ default:
+ batch->cb_start = peek; // In case of recursive callbacks
+ if(event->op < OPENGL_START) {
+ wxe_dispatch(*event);
+ } else {
+ gl_dispatch(event->op,event->buffer,event->caller,event->bin);
}
+ break;
}
- } else {
- if(callback_returned) {
- return;
- }
- // sleep until something happens
- //fprintf(stderr, "%s:%d sleep %d %d %d %d \r\n", __FILE__, __LINE__, batch->size(), callback_returned, blevel, is_callback);fflush(stderr);
- while(batch->size() == 0) {
- erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
+ event->Delete();
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ peek = batch->Cleanup(peek);
}
}
+ // sleep until something happens
+ // fprintf(stderr, "%s:%d sleep %d %d\r\n", __FILE__, __LINE__,
+ // peek, batch->m_n);fflush(stderr);
+ wxe_needs_signal = 1;
+ while(peek >= batch->m_n) {
+ erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
+ peek = batch->Cleanup(peek);
+ }
+ wxe_needs_signal = 0;
}
}
diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h
index 57bf2e2dba..fd25296c73 100644
--- a/lib/wx/c_src/wxe_impl.h
+++ b/lib/wx/c_src/wxe_impl.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
@@ -46,7 +47,8 @@ typedef wxString wxeLocaleC;
#define WXE_NOT_INITIATED 0
#define WXE_INITIATED 1
-#define WXE_EXITED 2
+#define WXE_EXITING 2
+#define WXE_EXITED 3
#define WXE_ERROR -1
void send_msg(const char *, const wxString *); // For debugging and error msgs
@@ -55,13 +57,18 @@ class WxeApp : public wxApp
{
public:
virtual bool OnInit();
+
+ virtual void OnAssertFailure(const wxChar *file, int line, const wxChar *func,
+ const wxChar *cond, const wxChar *msg);
+
#ifdef _MACOSX
virtual void MacOpenFile(const wxString &filename);
#endif
+
void shutdown(wxeMetaCommand& event);
- int dispatch(wxList *, int, int);
- void dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process);
+ int dispatch(wxeFifo *);
+ void dispatch_cb(wxeFifo * batch, ErlDrvTermData process);
void wxe_dispatch(wxeCommand& event);
@@ -93,7 +100,7 @@ public:
int recurse_level;
wxList * delayed_cleanup;
- wxList * delayed_delete;
+ wxeFifo * delayed_delete;
// Temp container for callbacks
char *cb_buff;
int cb_len;
diff --git a/lib/wx/c_src/wxe_main.cpp b/lib/wx/c_src/wxe_main.cpp
index 2bec2422c9..1d732554ea 100644
--- a/lib/wx/c_src/wxe_main.cpp
+++ b/lib/wx/c_src/wxe_main.cpp
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/wxe_memory.h b/lib/wx/c_src/wxe_memory.h
index 8a48c77154..2dae424cf8 100644
--- a/lib/wx/c_src/wxe_memory.h
+++ b/lib/wx/c_src/wxe_memory.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2014. All Rights Reserved.
*
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
diff --git a/lib/wx/c_src/wxe_ps_init.c b/lib/wx/c_src/wxe_ps_init.c
index d000e242de..7a5b2fabc0 100644
--- a/lib/wx/c_src/wxe_ps_init.c
+++ b/lib/wx/c_src/wxe_ps_init.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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.
+ * Licensed under the Apache License, Version 2.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%
*/
diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp
index aebf6bae1b..2dd7a8478b 100644
--- a/lib/wx/c_src/wxe_return.cpp
+++ b/lib/wx/c_src/wxe_return.cpp
@@ -3,27 +3,23 @@
*
* Copyright Ericsson AB 2008-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/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * 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%
*/
#include "wxe_return.h"
-// see http://docs.wxwidgets.org/stable/wx_wxarray.html#arraymacros
-// this is a magic incantation which must be done!
-#include <wx/arrimpl.cpp>
-WX_DEFINE_OBJARRAY(wxErlDrvTermDataArray);
-
#define INLINE
wxeReturn::wxeReturn (ErlDrvTermData _port,
@@ -31,79 +27,87 @@ wxeReturn::wxeReturn (ErlDrvTermData _port,
bool _isResult) {
port = _port;
caller = _caller;
-
+
isResult = _isResult;
-
- if (isResult) {
- addAtom("_wxe_result_");
- }
+ rtb = buff;
+ rt_max = RT_BUFF_SZ;
+ rt_n = 0;
+ if (isResult) {
+ addAtom("_wxe_result_");
+ }
+}
+
+//clear everything so we can re-use if we want
+void wxeReturn::reset() {
+ rt_n = 0;
+ temp_float.empty();
}
wxeReturn::~wxeReturn () {
- //depending on which version of wxArray we use, we may have to clear it ourselves.
+ if(rtb != buff)
+ driver_free(rtb);
}
-int wxeReturn::send() {
- if ((rt.GetCount() == 2 && isResult) || rt.GetCount() == 0)
- return 1; // not a call bail out
-
- if (isResult) {
- addTupleCount(2);
- }
+int wxeReturn::send() {
+ if ((rt_n == 2 && isResult) || rt_n == 0)
+ return 1; // not a call bail out
- // rt to array
- unsigned int rtLength = rt.GetCount(); //signed int
+ if (isResult) {
+ addTupleCount(2);
+ }
- size_t size = sizeof(ErlDrvTermData)*(rtLength);
-
- ErlDrvTermData* rtData = (ErlDrvTermData *) driver_alloc(size);
- for (unsigned int i=0; i < rtLength; i++) {
- rtData[i] = rt[i];
- }
-
- int res = erl_drv_send_term(port, caller, rtData, rtLength);
- driver_free(rtData);
+ int res = erl_drv_send_term(port, caller, rtb, rt_n);
#ifdef DEBUG
- if(res == -1) {
- fprintf(stderr, "Failed to send return or event msg\r\n");
- }
+ if(res == -1) {
+ fprintf(stderr, "Failed to send return or event msg\r\n");
+ }
#endif
- reset();
- return res;
+ reset();
+ return res;
}
-//clear everything so we can re-use if we want
- void wxeReturn::reset() {
- rt.empty();
- temp_float.empty();
+INLINE
+unsigned int wxeReturn::size() {
+ return rt_n;
}
+
INLINE
-unsigned int wxeReturn::size() {
- return rt.GetCount();
- }
-
+void wxeReturn::ensureFloatCount(size_t n) {
+ temp_float.Alloc(n);
+}
+
INLINE
-void wxeReturn::add(ErlDrvTermData type, ErlDrvTermData data) {
- rt.Add(type);
- rt.Add(data);
+void wxeReturn::do_add(ErlDrvTermData val) {
+ if(rt_n >= rt_max) { // realloc
+ rt_max += RT_BUFF_SZ;
+ if(rtb == buff) {
+ rtb = (ErlDrvTermData *) driver_alloc(rt_max * sizeof(ErlDrvTermData));
+ for(int i = 0; i < RT_BUFF_SZ; i++)
+ rtb[i] = buff[i];
+ } else {
+ rtb = (ErlDrvTermData *) driver_realloc(rtb, rt_max * sizeof(ErlDrvTermData));
+ }
+ }
+ rtb[rt_n++] = val;
}
-// INLINE
-// void wxeReturn::addRef(const void *ptr, const char* className) {
-// unsigned int ref_idx = wxe_app->getRef((void *)ptr, memEnv);
-// addRef(ref_idx, className);
-// }
+INLINE
+void wxeReturn::add(ErlDrvTermData type, ErlDrvTermData data) {
+ do_add(type);
+ do_add(data);
+}
+
INLINE
void wxeReturn::addRef(const unsigned int ref, const char* className) {
addAtom("wx_ref");
addUint(ref);
addAtom(className);
- rt.Add(ERL_DRV_NIL);
+ do_add(ERL_DRV_NIL);
addTupleCount(4);
}
@@ -115,30 +119,30 @@ void wxeReturn::addAtom(const char* atomName) {
INLINE
void wxeReturn::addBinary(const char* buf, const size_t size) {
- rt.Add(ERL_DRV_BUF2BINARY);
- rt.Add((ErlDrvTermData)buf);
- rt.Add((ErlDrvTermData)size);
+ do_add(ERL_DRV_BUF2BINARY);
+ do_add((ErlDrvTermData)buf);
+ do_add((ErlDrvTermData)size);
}
INLINE
void wxeReturn::addExt2Term(wxeErlTerm *term) {
if(term) {
- rt.Add(ERL_DRV_EXT2TERM);
- rt.Add((ErlDrvTermData)term->bin);
- rt.Add((ErlDrvTermData)term->size);
+ do_add(ERL_DRV_EXT2TERM);
+ do_add((ErlDrvTermData)term->bin);
+ do_add((ErlDrvTermData)term->size);
} else {
- rt.Add(ERL_DRV_NIL);
+ do_add(ERL_DRV_NIL);
}
}
INLINE
void wxeReturn::addExt2Term(wxETreeItemData *val) {
if(val) {
- rt.Add(ERL_DRV_EXT2TERM);
- rt.Add((ErlDrvTermData)(val->bin));
- rt.Add((ErlDrvTermData)(val->size));
+ do_add(ERL_DRV_EXT2TERM);
+ do_add((ErlDrvTermData)(val->bin));
+ do_add((ErlDrvTermData)(val->size));
} else
- rt.Add(ERL_DRV_NIL);
+ do_add(ERL_DRV_NIL);
}
INLINE
@@ -168,8 +172,8 @@ void wxeReturn::addTupleCount(unsigned int n) {
INLINE
void wxeReturn::endList(unsigned int n) {
- rt.Add(ERL_DRV_NIL);
- add(ERL_DRV_LIST, (ErlDrvTermData)(n+1));
+ do_add(ERL_DRV_NIL);
+ add(ERL_DRV_LIST, (ErlDrvTermData)(n+1));
}
INLINE
@@ -222,6 +226,7 @@ INLINE
void wxeReturn::add(wxArrayDouble val) {
unsigned int len = val.GetCount();
+ temp_float.Alloc(len);
for (unsigned int i = 0; i< len; i++) {
addFloat(val[i]);
}
diff --git a/lib/wx/c_src/wxe_return.h b/lib/wx/c_src/wxe_return.h
index 80946e2dc6..6c38ae32e1 100644
--- a/lib/wx/c_src/wxe_return.h
+++ b/lib/wx/c_src/wxe_return.h
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2008-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.
+ * Licensed under the Apache License, Version 2.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%
*/
@@ -40,10 +41,7 @@ extern "C" {
#include <wx/html/htmlcell.h>
-// #define send() send_term(__FILE__, __LINE__)
-
-// see http://docs.wxwidgets.org/stable/wx_wxarray.html
-WX_DECLARE_OBJARRAY(ErlDrvTermData, wxErlDrvTermDataArray);
+#define RT_BUFF_SZ 64
class wxeReturn {
@@ -57,7 +55,6 @@ public:
void add(ErlDrvTermData type, ErlDrvTermData data);
- // void addRef(const void *ptr, const char* className);
void addRef(const unsigned int ref, const char* className);
void addAtom(const char* atomName);
@@ -65,8 +62,8 @@ public:
void addExt2Term(wxeErlTerm * term);
void addExt2Term(wxETreeItemData * term);
- void addNil() { rt.Add(ERL_DRV_NIL); };
-
+ void addNil() { do_add(ERL_DRV_NIL); };
+
void addUint(unsigned int n);
void addInt(int n);
@@ -116,6 +113,10 @@ public:
void add(const wxHtmlLinkInfo &val);
+ void do_add(ErlDrvTermData val);
+
+ void ensureFloatCount(size_t n);
+
int send();
void reset();
@@ -127,15 +128,17 @@ private:
inline void addDate(wxDateTime dateTime);
inline void addTime(wxDateTime dateTime);
-
-// WxeApp* wxe_app;
+
ErlDrvTermData caller;
ErlDrvTermData port;
-// wxeMemEnv *memEnv;
- wxErlDrvTermDataArray rt;
wxArrayDouble temp_float;
wxMBConvUTF32 utfConverter;
bool isResult;
+
+ unsigned int rt_max;
+ unsigned int rt_n;
+ ErlDrvTermData *rtb;
+ ErlDrvTermData buff[RT_BUFF_SZ];
};
#endif /* _WXE_RETURN_H */
diff --git a/lib/wx/config.mk.in b/lib/wx/config.mk.in
index 31def7af57..0e98545240 100644
--- a/lib/wx/config.mk.in
+++ b/lib/wx/config.mk.in
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/wx/configure.in b/lib/wx/configure.in
index 4c4d4f41a8..bf27b72aa7 100644
--- a/lib/wx/configure.in
+++ b/lib/wx/configure.in
@@ -4,16 +4,17 @@ dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 2008-2013. All Rights Reserved.
dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
+dnl Licensed under the Apache License, Version 2.0 (the "License");
+dnl you may not use this file except in compliance with the License.
+dnl You may obtain a copy of the License at
dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl
dnl %CopyrightEnd%
@@ -163,14 +164,14 @@ case $host_os in
CPPFLAGS="$CPPFLAGS -D_MACOSX $PTHR_CFLAGS"
;;
mingw32)
- CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0500 -D_WINDOWS -D_UNICODE -DUNICODE"
- CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0500"
+ CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0600 -D_WINDOWS -D_UNICODE -DUNICODE"
+ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600"
AC_MSG_WARN([Reverting to 32-bit time_t])
CPPFLAGS="$CPPFLAGS -D_USE_32BIT_TIME_T"
;;
win32)
- CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0500 -D_WINDOWS -D_UNICODE -DUNICODE"
- CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0500"
+ CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0600 -D_WINDOWS -D_UNICODE -DUNICODE"
+ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600"
;;
*)
CFLAGS="$CFLAGS -Wno-deprecated-declarations"
@@ -441,19 +442,26 @@ else
else
CWXWIN_PROG=`cygpath -d "$PROGRAMFILES" | cygpath -f - 2>/dev/null`
fi
- CWXWIN3=$CWXWIN_PROG/wxWidgets-?.*.*
- CWXWIN4=$CWXWIN_PROG/wxMSW-?.*.*
- CWX_DOCUMENTED="/opt/local/pgm/wxMSW-?.*.* /opt/local/pgm/wxWidgets-?.*.*"
+
+ CWXWIN3="$CWXWIN_PROG/wxWidgets-3.*.* $CWXWIN_PROG/wxWidgets-2.*.*"
+ CWXWIN4="$CWXWIN_PROG/wxMSW-3.*.* $CWXWIN_PROG/wxMSW-2.*.*"
+
+ DOC_OPT=/opt/local/pgm
+ CWX_DOCUMENTED="$DOC_OPT/wxWidgets-2.*.* $DOC_OPT/wxMSW-2.*.*"
+ CWX_DOCUMENTED="$DOC_OPT/wxWidgets-3.*.* $DOC_OPT/wxMSW-3.*.* $CWX_DOCUMENTED"
+
case $ac_cv_sizeof_void_p in
8)
- CWX_DOCUMENTED="/opt/local64/pgm/wxMSW-?.*.* /opt/local64/pgm/wxWidgets-?.*.* $CWX_DOCUMENTED"
+ DOC_OPT64=/opt/local64/pgm
+ CWX_DOCUMENTED="$DOC_OPT64/wxWidgets-2.*.* $DOC_OPT64/wxMSW-2.*.* $CWX_DOCUMENTED"
+ CWX_DOCUMENTED="$DOC_OPT64/wxWidgets-3.*.* $DOC_OPT64/wxMSW-3.*.* $CWX_DOCUMENTED"
;;
*)
true
;;
- esac
-
- CWXPATH="$CWXWIN0 $CWXWIN1 $CWXWIN2 $CWX_DOCUMENTED $CWXWIN3.* $CWXWIN4.*"
+ esac
+
+ CWXPATH="$CWXWIN0 $CWXWIN1 $CWXWIN2 $CWX_DOCUMENTED $CWXWIN3 $CWXWIN4"
for dir in $CWXPATH; do
AC_MSG_NOTICE(Checking: [$dir])
diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile
index 4e6727b6a6..a0684d112d 100644
--- a/lib/wx/doc/src/Makefile
+++ b/lib/wx/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/doc/src/book.xml b/lib/wx/doc/src/book.xml
index 769b204ed6..d438e08749 100644
--- a/lib/wx/doc/src/book.xml
+++ b/lib/wx/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 682ab48ca0..f895540b25 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,6 +32,102 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 1.6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed commands with multiple binaries, such as
+ <c>wxImage:new/4</c>. Added
+ <c>wxWindow:SetDoubleBuffered/1</c>,
+ <c>wxWindow:isDoubleBuffered/1</c>,
+ <c>wxWindow:setTransparent/2</c> and
+ <c>wxWindow:canSetTransparent/1</c>. Fixed timing issues.</p>
+ <p>
+ Own Id: OTP-13404</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Wx 1.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Add wxOverlay and make wxPostScripDC optional to make
+ it easier to build on windows.</p> <p>Correct some
+ function specifications.</p> <p>The driver implementation
+ have been optimized and now invokes commands after events
+ have been sent to erlang.</p>
+ <p>
+ Own Id: OTP-13160</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Wx 1.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Extend AUI functionality.</p>
+ <p>
+ Own Id: OTP-12961</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Wx 1.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The undocumented option <c>generic_debug</c> for
+ <c>gen_server</c> has been removed.</p>
+ <p>
+ Own Id: OTP-12183</p>
+ </item>
+ <item>
+ <p>
+ Remove raise condition where <c>wx</c> could crash during
+ emulator stoppage.</p>
+ <p>
+ Own Id: OTP-12734</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Use wxWidgets-3.0, if found, as default backend on
+ windows.</p>
+ <p>
+ Own Id: OTP-12632</p>
+ </item>
+ <item>
+ <p>
+ Add missing fields in some events records. May require a
+ recompilation of user applications.</p>
+ <p>
+ Own Id: OTP-12660</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 1.3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/wx/doc/src/part.xml b/lib/wx/doc/src/part.xml
index a11473462c..7823c5312b 100644
--- a/lib/wx/doc/src/part.xml
+++ b/lib/wx/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/wx/doc/src/part_notes.xml b/lib/wx/doc/src/part_notes.xml
index 958a273488..d3bdacb432 100644
--- a/lib/wx/doc/src/part_notes.xml
+++ b/lib/wx/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/wx/doc/src/ref_man.xml.src b/lib/wx/doc/src/ref_man.xml.src
index 26706d538b..2c843fa593 100644
--- a/lib/wx/doc/src/ref_man.xml.src
+++ b/lib/wx/doc/src/ref_man.xml.src
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/wx/examples/Makefile b/lib/wx/examples/Makefile
index 48fccc88f7..997c3be6ec 100644
--- a/lib/wx/examples/Makefile
+++ b/lib/wx/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/examples/demo/Makefile b/lib/wx/examples/demo/Makefile
index c60e9c3d50..cdd2e1385b 100644
--- a/lib/wx/examples/demo/Makefile
+++ b/lib/wx/examples/demo/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/examples/demo/demo.erl b/lib/wx/examples/demo/demo.erl
index 2f560096f5..ed826dd3f0 100644
--- a/lib/wx/examples/demo/demo.erl
+++ b/lib/wx/examples/demo/demo.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
@@ -256,9 +257,17 @@ handle_event(#wx{id = Id,
wx_misc:launchDefaultBrowser("http://www.erlang.org/doc/apps/wx/part_frame.html"),
{noreply, State};
?wxID_ABOUT ->
+ WxWVer = io_lib:format("~p.~p.~p.~p",
+ [?wxMAJOR_VERSION, ?wxMINOR_VERSION,
+ ?wxRELEASE_NUMBER, ?wxSUBRELEASE_NUMBER]),
+ application:load(wx),
+ {ok, WxVsn} = application:get_key(wx, vsn),
AboutString =
"Demo of various widgets\n"
- "Authors: Olle & Dan",
+ "Authors: Olle & Dan\n\n" ++
+ "Frontend: wx-" ++ WxVsn ++
+ "\nBackend: wxWidgets-" ++ lists:flatten(WxWVer),
+
wxMessageDialog:showModal(wxMessageDialog:new(State#state.win, AboutString,
[{style,
?wxOK bor
diff --git a/lib/wx/examples/demo/demo_html_tagger.erl b/lib/wx/examples/demo/demo_html_tagger.erl
index 7bb6736fdc..cc24cbaa67 100644
--- a/lib/wx/examples/demo/demo_html_tagger.erl
+++ b/lib/wx/examples/demo/demo_html_tagger.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -267,8 +268,10 @@ normalize_toks(Toks) ->
normalize_tok(Tok) ->
%% this is the portable way ...
- [{_,Type},{_,Line},{_,Col},{_,Txt}] =
- erl_scan:token_info(Tok, [category,line,column,text]),
+ Type = erl_scan:category(Tok),
+ Line = erl_scan:line(Tok),
+ Col = erl_scan:column(Tok),
+ Txt = erl_scan:text(Tok),
Val = {Type,{Line,Col},Txt},
%% io:format("here:X=~p ~p~n",[Tok,Val]),
Val.
diff --git a/lib/wx/examples/demo/ex_aui.erl b/lib/wx/examples/demo/ex_aui.erl
index 70372caad8..7fbf841d16 100644
--- a/lib/wx/examples/demo/ex_aui.erl
+++ b/lib/wx/examples/demo/ex_aui.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
@@ -46,40 +47,54 @@ init(Config) ->
-define(pi, wxAuiPaneInfo).
do_init(Config) ->
- Parent = proplists:get_value(parent, Config),
+ Parent = proplists:get_value(parent, Config),
Panel = wxPanel:new(Parent, []),
%% Setup sizers
MainSizer = wxBoxSizer:new(?wxVERTICAL),
Manager = wxAuiManager:new([{managed_wnd, Panel}]),
-
- Pane = ?pi:new(),
- ?pi:closeButton(Pane),
- ?pi:right(Pane),
- ?pi:dockable(Pane, [{b, true}]),
- ?pi:floatingSize(Pane, 300,200),
- ?pi:minSize(Pane, {50,50}),
- ?pi:paneBorder(Pane),
- ?pi:floatable(Pane, [{b, true}]),
-
- create_pane(Panel, Manager, Pane),
- create_pane(Panel, Manager,
- ?pi:caption(?pi:top(?pi:new(Pane)), "One")),
- create_pane(Panel, Manager,
- ?pi:caption(?pi:left(?pi:new(Pane)), "two")),
- create_pane(Panel, Manager,
- ?pi:caption(?pi:bottom(?pi:new(Pane)), "Three")),
- Pane2 = wxAuiPaneInfo:new(Pane),
- ?pi:centrePane(Pane2),
- create_notebook(Panel, Manager, ?pi:new(Pane2)),
-
- wxPanel:setSizer(Panel, MainSizer),
-
- wxAuiManager:connect(Manager, aui_pane_button, [{skip,true}]),
- wxAuiManager:connect(Manager, aui_pane_maximize, [{skip,true}]),
- wxAuiManager:update(Manager),
- process_flag(trap_exit, true),
- {Panel, #state{parent=Panel, config=Config, aui=Manager}}.
+ try
+ Art = wxAuiManager:getArtProvider(Manager),
+ wxAuiDockArt:setColour(Art, ?wxAUI_DOCKART_BACKGROUND_COLOUR, {200, 100, 100}),
+ wxAuiDockArt:setColour(Art, ?wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR, {200, 100, 100}),
+ wxAuiDockArt:setColour(Art, ?wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR, {100, 200, 100}),
+
+
+ Pane = ?pi:new(),
+ ?pi:closeButton(Pane),
+ ?pi:right(Pane),
+ ?pi:dockable(Pane, [{b, true}]),
+ ?pi:floatingSize(Pane, 300,200),
+ ?pi:minSize(Pane, {50,50}),
+ ?pi:paneBorder(Pane),
+ ?pi:floatable(Pane, [{b, true}]),
+
+ create_pane(Panel, Manager, Pane),
+ create_pane(Panel, Manager,
+ ?pi:caption(?pi:top(?pi:new(Pane)), "One")),
+ create_pane(Panel, Manager,
+ ?pi:caption(?pi:left(?pi:new(Pane)), "two")),
+ create_pane(Panel, Manager,
+ ?pi:caption(?pi:bottom(?pi:new(Pane)), "Three")),
+ Pane2 = wxAuiPaneInfo:new(Pane),
+ ?pi:centrePane(Pane2),
+ create_notebook(Panel, Manager, ?pi:new(Pane2)),
+
+ wxPanel:setSizer(Panel, MainSizer),
+
+ wxAuiManager:connect(Manager, aui_pane_button, [{skip,true}]),
+ wxAuiManager:connect(Manager, aui_pane_maximize, [{skip,true}]),
+ wxAuiManager:update(Manager),
+ process_flag(trap_exit, true),
+ {Panel, #state{parent=Panel, config=Config, aui=Manager}}
+ catch Class:Reason ->
+ ST = erlang:get_stacktrace(),
+ io:format("AUI Crashed ~p ~p~n",[Reason, ST]),
+ wxAuiManager:unInit(Manager),
+ wxAuiManager:destroy(Manager),
+ wxPanel:destroy(Panel),
+ erlang:raise(Class, Reason, ST)
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Callbacks handled as normal gen_server callbacks
@@ -162,6 +177,15 @@ create_notebook(Parent, Manager, Pane) ->
Notebook = wxAuiNotebook:new(Parent, [{style, Style}]),
+ Art = wxAuiSimpleTabArt:new(),
+ case ?wxMAJOR_VERSION > 2 of
+ true ->
+ wxAuiSimpleTabArt:setColour(Art, {200, 0, 0}),
+ wxAuiSimpleTabArt:setActiveColour(Art, {0, 0, 200});
+ false -> ignore
+ end,
+ ok = wxAuiNotebook:setArtProvider(Notebook, Art),
+
Tab1 = wxPanel:new(Notebook, []),
wxPanel:setBackgroundColour(Tab1, ?wxBLACK),
wxButton:new(Tab1, ?wxID_ANY, [{label,"New tab"}]),
diff --git a/lib/wx/examples/demo/ex_button.erl b/lib/wx/examples/demo/ex_button.erl
index 0f3296d0c0..bfa7f785c2 100644
--- a/lib/wx/examples/demo/ex_button.erl
+++ b/lib/wx/examples/demo/ex_button.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_canvas.erl b/lib/wx/examples/demo/ex_canvas.erl
index 8e517ba852..cdc783055c 100644
--- a/lib/wx/examples/demo/ex_canvas.erl
+++ b/lib/wx/examples/demo/ex_canvas.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
@@ -34,7 +35,9 @@
parent,
config,
canvas,
- bitmap
+ bitmap,
+ overlay,
+ pos
}).
start(Config) ->
@@ -59,6 +62,10 @@ do_init(Config) ->
wxPanel:connect(Canvas, paint, [callback]),
wxPanel:connect(Canvas, size),
+ wxPanel:connect(Canvas, left_down),
+ wxPanel:connect(Canvas, left_up),
+ wxPanel:connect(Canvas, motion),
+
wxPanel:connect(Button, command_button_clicked),
%% Add to sizers
@@ -77,7 +84,9 @@ do_init(Config) ->
Bitmap = wxBitmap:new(erlang:max(W,30),erlang:max(30,H)),
{Panel, #state{parent=Panel, config=Config,
- canvas = Canvas, bitmap = Bitmap}}.
+ canvas = Canvas, bitmap = Bitmap,
+ overlay = wxOverlay:new()
+ }}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Sync event from callback events, paint event must be handled in callbacks
@@ -126,11 +135,39 @@ handle_event(#wx{event = #wxCommand{type = command_button_clicked}},
wxBitmap:destroy(Bmp),
{noreply, State};
handle_event(#wx{event = #wxSize{size={W,H}}},
- State = #state{bitmap=Prev}) ->
+ State = #state{bitmap=Prev, canvas=Canvas}) ->
Bitmap = wxBitmap:new(W,H),
- draw(State#state.canvas, Bitmap, fun(DC) -> wxDC:clear(DC) end),
+ draw(Canvas, Bitmap, fun(DC) -> wxDC:clear(DC) end),
wxBitmap:destroy(Prev),
{noreply, State#state{bitmap = Bitmap}};
+
+handle_event(#wx{event = #wxMouse{type=left_down, x=X, y=Y}}, State) ->
+ {noreply, State#state{pos={X,Y}}};
+handle_event(#wx{event = #wxMouse{type=motion, x=X1, y=Y1}},
+ #state{pos=Start, overlay=Overlay, canvas=Canvas} = State) ->
+ case Start of
+ undefined -> ignore;
+ {X0,Y0} ->
+ DC = wxClientDC:new(Canvas),
+ DCO = wxDCOverlay:new(Overlay, DC),
+ wxDCOverlay:clear(DCO),
+ wxDC:setPen(DC, ?wxLIGHT_GREY_PEN),
+ wxDC:setBrush(DC, ?wxTRANSPARENT_BRUSH),
+ wxDC:drawRectangle(DC, {X0,Y0, X1-X0, Y1-Y0}),
+ wxDCOverlay:destroy(DCO),
+ wxClientDC:destroy(DC)
+ end,
+ {noreply, State};
+handle_event(#wx{event = #wxMouse{type=left_up}},
+ #state{overlay=Overlay, canvas=Canvas} = State) ->
+ DC = wxClientDC:new(Canvas),
+ DCO = wxDCOverlay:new(Overlay, DC),
+ wxDCOverlay:clear(DCO),
+ wxDCOverlay:destroy(DCO),
+ wxClientDC:destroy(DC),
+ wxOverlay:reset(Overlay),
+ {noreply, State#state{pos=undefined}};
+
handle_event(Ev = #wx{}, State = #state{}) ->
demo:format(State#state.config, "Got Event ~p\n", [Ev]),
{noreply, State}.
@@ -154,7 +191,8 @@ handle_cast(Msg, State) ->
code_change(_, _, State) ->
{stop, ignore, State}.
-terminate(_Reason, _) ->
+terminate(_Reason, #state{overlay=Overlay}) ->
+ wxOverlay:destroy(Overlay),
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/wx/examples/demo/ex_canvas_paint.erl b/lib/wx/examples/demo/ex_canvas_paint.erl
index 6873724655..90638fcf5b 100644
--- a/lib/wx/examples/demo/ex_canvas_paint.erl
+++ b/lib/wx/examples/demo/ex_canvas_paint.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_choices.erl b/lib/wx/examples/demo/ex_choices.erl
index c8b27f8580..31857e45f1 100644
--- a/lib/wx/examples/demo/ex_choices.erl
+++ b/lib/wx/examples/demo/ex_choices.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_cursor.erl b/lib/wx/examples/demo/ex_cursor.erl
index f8a7cdd01b..207973af96 100644
--- a/lib/wx/examples/demo/ex_cursor.erl
+++ b/lib/wx/examples/demo/ex_cursor.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_dialogs.erl b/lib/wx/examples/demo/ex_dialogs.erl
index 2b9febfb64..03792b2e8d 100644
--- a/lib/wx/examples/demo/ex_dialogs.erl
+++ b/lib/wx/examples/demo/ex_dialogs.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_frame_utils.erl b/lib/wx/examples/demo/ex_frame_utils.erl
index c2273f80e0..68eda8b6b7 100644
--- a/lib/wx/examples/demo/ex_frame_utils.erl
+++ b/lib/wx/examples/demo/ex_frame_utils.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_gauge.erl b/lib/wx/examples/demo/ex_gauge.erl
index 5ec524fc37..9ee9134be1 100644
--- a/lib/wx/examples/demo/ex_gauge.erl
+++ b/lib/wx/examples/demo/ex_gauge.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_gl.erl b/lib/wx/examples/demo/ex_gl.erl
index 6bb2d12dff..2693654136 100644
--- a/lib/wx/examples/demo/ex_gl.erl
+++ b/lib/wx/examples/demo/ex_gl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_graphicsContext.erl b/lib/wx/examples/demo/ex_graphicsContext.erl
index 9047f1d135..3cb6f8a139 100644
--- a/lib/wx/examples/demo/ex_graphicsContext.erl
+++ b/lib/wx/examples/demo/ex_graphicsContext.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_grid.erl b/lib/wx/examples/demo/ex_grid.erl
index 691eede3c4..c062b7bff5 100644
--- a/lib/wx/examples/demo/ex_grid.erl
+++ b/lib/wx/examples/demo/ex_grid.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_htmlWindow.erl b/lib/wx/examples/demo/ex_htmlWindow.erl
index f505dfcfe1..d9fa5310ef 100644
--- a/lib/wx/examples/demo/ex_htmlWindow.erl
+++ b/lib/wx/examples/demo/ex_htmlWindow.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_listCtrl.erl b/lib/wx/examples/demo/ex_listCtrl.erl
index a59b30b15c..e5eb898f29 100644
--- a/lib/wx/examples/demo/ex_listCtrl.erl
+++ b/lib/wx/examples/demo/ex_listCtrl.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/wx/examples/demo/ex_notebook.erl b/lib/wx/examples/demo/ex_notebook.erl
index 69b1e02f6b..1b6a1a0ee4 100644
--- a/lib/wx/examples/demo/ex_notebook.erl
+++ b/lib/wx/examples/demo/ex_notebook.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_pickers.erl b/lib/wx/examples/demo/ex_pickers.erl
index b12d1b3877..8c07609f9d 100644
--- a/lib/wx/examples/demo/ex_pickers.erl
+++ b/lib/wx/examples/demo/ex_pickers.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_popupMenu.erl b/lib/wx/examples/demo/ex_popupMenu.erl
index c0d82444b6..976c51cd20 100644
--- a/lib/wx/examples/demo/ex_popupMenu.erl
+++ b/lib/wx/examples/demo/ex_popupMenu.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_radioBox.erl b/lib/wx/examples/demo/ex_radioBox.erl
index f615b81997..004bbb5290 100644
--- a/lib/wx/examples/demo/ex_radioBox.erl
+++ b/lib/wx/examples/demo/ex_radioBox.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_sashWindow.erl b/lib/wx/examples/demo/ex_sashWindow.erl
index 8057d9b2c3..7d0473ab8f 100644
--- a/lib/wx/examples/demo/ex_sashWindow.erl
+++ b/lib/wx/examples/demo/ex_sashWindow.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_sizers.erl b/lib/wx/examples/demo/ex_sizers.erl
index 5875198d38..07dbaa4c65 100644
--- a/lib/wx/examples/demo/ex_sizers.erl
+++ b/lib/wx/examples/demo/ex_sizers.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_slider.erl b/lib/wx/examples/demo/ex_slider.erl
index 001e04a0f8..839af56aec 100644
--- a/lib/wx/examples/demo/ex_slider.erl
+++ b/lib/wx/examples/demo/ex_slider.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_splitterWindow.erl b/lib/wx/examples/demo/ex_splitterWindow.erl
index 06357d7d08..932027863f 100644
--- a/lib/wx/examples/demo/ex_splitterWindow.erl
+++ b/lib/wx/examples/demo/ex_splitterWindow.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_static.erl b/lib/wx/examples/demo/ex_static.erl
index 1be033eac5..2f36732aed 100644
--- a/lib/wx/examples/demo/ex_static.erl
+++ b/lib/wx/examples/demo/ex_static.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_textCtrl.erl b/lib/wx/examples/demo/ex_textCtrl.erl
index 57088ad878..0674b5ef1c 100644
--- a/lib/wx/examples/demo/ex_textCtrl.erl
+++ b/lib/wx/examples/demo/ex_textCtrl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/demo/ex_treeCtrl.erl b/lib/wx/examples/demo/ex_treeCtrl.erl
index d2ce0cf95e..4c69c7091c 100644
--- a/lib/wx/examples/demo/ex_treeCtrl.erl
+++ b/lib/wx/examples/demo/ex_treeCtrl.erl
@@ -3,16 +3,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/simple/Makefile b/lib/wx/examples/simple/Makefile
index 3f2bf01556..997913f036 100644
--- a/lib/wx/examples/simple/Makefile
+++ b/lib/wx/examples/simple/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/examples/simple/hello.erl b/lib/wx/examples/simple/hello.erl
index 02af1b501f..1dde9b1fd2 100644
--- a/lib/wx/examples/simple/hello.erl
+++ b/lib/wx/examples/simple/hello.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/wx/examples/simple/hello2.erl b/lib/wx/examples/simple/hello2.erl
index af825f2e3c..ac919c7668 100644
--- a/lib/wx/examples/simple/hello2.erl
+++ b/lib/wx/examples/simple/hello2.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/wx/examples/simple/menu.erl b/lib/wx/examples/simple/menu.erl
index 9e6b28b46b..3851e7ca7e 100644
--- a/lib/wx/examples/simple/menu.erl
+++ b/lib/wx/examples/simple/menu.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/wx/examples/simple/minimal.erl b/lib/wx/examples/simple/minimal.erl
index 4782745dfc..fb0eb3c3d9 100644
--- a/lib/wx/examples/simple/minimal.erl
+++ b/lib/wx/examples/simple/minimal.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/wx/examples/sudoku/Makefile b/lib/wx/examples/sudoku/Makefile
index ec900f37e2..56186a8b14 100644
--- a/lib/wx/examples/sudoku/Makefile
+++ b/lib/wx/examples/sudoku/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/examples/sudoku/sudoku.erl b/lib/wx/examples/sudoku/sudoku.erl
index 6749fec30a..0a0cf10d32 100644
--- a/lib/wx/examples/sudoku/sudoku.erl
+++ b/lib/wx/examples/sudoku/sudoku.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/examples/sudoku/sudoku.hrl b/lib/wx/examples/sudoku/sudoku.hrl
index 6bb2eefd07..026b2054c9 100644
--- a/lib/wx/examples/sudoku/sudoku.hrl
+++ b/lib/wx/examples/sudoku/sudoku.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/examples/sudoku/sudoku_board.erl b/lib/wx/examples/sudoku/sudoku_board.erl
index ed9c62b7c8..50b539afa0 100644
--- a/lib/wx/examples/sudoku/sudoku_board.erl
+++ b/lib/wx/examples/sudoku/sudoku_board.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/examples/sudoku/sudoku_game.erl b/lib/wx/examples/sudoku/sudoku_game.erl
index ec705918b3..e3c39b4ec9 100644
--- a/lib/wx/examples/sudoku/sudoku_game.erl
+++ b/lib/wx/examples/sudoku/sudoku_game.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
diff --git a/lib/wx/examples/sudoku/sudoku_gui.erl b/lib/wx/examples/sudoku/sudoku_gui.erl
index 5f3f1a2621..a5d24fa604 100644
--- a/lib/wx/examples/sudoku/sudoku_gui.erl
+++ b/lib/wx/examples/sudoku/sudoku_gui.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/examples/xrc/Makefile b/lib/wx/examples/xrc/Makefile
index 9a976628a7..2028958fa1 100644
--- a/lib/wx/examples/xrc/Makefile
+++ b/lib/wx/examples/xrc/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/wx/examples/xrc/xrc.erl b/lib/wx/examples/xrc/xrc.erl
index 6478171b4f..7f9519a69d 100644
--- a/lib/wx/examples/xrc/xrc.erl
+++ b/lib/wx/examples/xrc/xrc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%
diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl
index 9004a8aa31..a7dc2f2495 100644
--- a/lib/wx/include/gl.hrl
+++ b/lib/wx/include/gl.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/wx/include/glu.hrl b/lib/wx/include/glu.hrl
index dc55c5bb96..e1ba0099b6 100644
--- a/lib/wx/include/glu.hrl
+++ b/lib/wx/include/glu.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl
index 348daf64ce..333ceca50c 100644
--- a/lib/wx/include/wx.hrl
+++ b/lib/wx/include/wx.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -54,7 +55,9 @@
-type wxListEventType() :: command_list_begin_drag | command_list_begin_rdrag | command_list_begin_label_edit | command_list_end_label_edit | command_list_delete_item | command_list_delete_all_items | command_list_key_down | command_list_insert_item | command_list_col_click | command_list_col_right_click | command_list_col_begin_drag | command_list_col_dragging | command_list_col_end_drag | command_list_item_selected | command_list_item_deselected | command_list_item_right_click | command_list_item_middle_click | command_list_item_activated | command_list_item_focused | command_list_cache_hint.
-type wxList() :: #wxList{}. %% Callback event: {@link wxListEvent}
--record(wxNotebook, {type :: wxNotebookEventType()}). %% Callback event: {@link wxNotebookEvent}
+-record(wxNotebook,{type :: wxNotebookEventType(), %% Callback event: {@link wxNotebookEvent}
+ nSel :: integer(),
+ nOldSel :: integer()}).
-type wxNotebookEventType() :: command_notebook_page_changed | command_notebook_page_changing.
-type wxNotebook() :: #wxNotebook{}. %% Callback event: {@link wxNotebookEvent}
@@ -86,7 +89,9 @@
-type wxWindowDestroyEventType() :: destroy.
-type wxWindowDestroy() :: #wxWindowDestroy{}. %% Callback event: {@link wxWindowDestroyEvent}
--record(wxCalendar, {type :: wxCalendarEventType()}). %% Callback event: {@link wxCalendarEvent}
+-record(wxCalendar,{type :: wxCalendarEventType(), %% Callback event: {@link wxCalendarEvent}
+ wday :: wx:wx_enum(),
+ date :: wx:wx_datetime()}).
-type wxCalendarEventType() :: calendar_sel_changed | calendar_day_changed | calendar_month_changed | calendar_year_changed | calendar_doubleclicked | calendar_weekday_clicked.
-type wxCalendar() :: #wxCalendar{}. %% Callback event: {@link wxCalendarEvent}
@@ -100,15 +105,19 @@
-type wxScrollEventType() :: scroll_top | scroll_bottom | scroll_lineup | scroll_linedown | scroll_pageup | scroll_pagedown | scroll_thumbtrack | scroll_thumbrelease | scroll_changed.
-type wxScroll() :: #wxScroll{}. %% Callback event: {@link wxScrollEvent}
--record(wxMenu, {type :: wxMenuEventType()}). %% Callback event: {@link wxMenuEvent}
+-record(wxMenu,{type :: wxMenuEventType(), %% Callback event: {@link wxMenuEvent}
+ menuId :: integer(),
+ menu :: wxMenu:wxMenu()}).
-type wxMenuEventType() :: menu_open | menu_close | menu_highlight.
-type wxMenu() :: #wxMenu{}. %% Callback event: {@link wxMenuEvent}
--record(wxContextMenu, {type :: wxContextMenuEventType()}). %% Callback event: {@link wxContextMenuEvent}
+-record(wxContextMenu,{type :: wxContextMenuEventType(), %% Callback event: {@link wxContextMenuEvent}
+ pos :: {X::integer(), Y::integer()}}).
-type wxContextMenuEventType() :: context_menu.
-type wxContextMenu() :: #wxContextMenu{}. %% Callback event: {@link wxContextMenuEvent}
--record(wxShow, {type :: wxShowEventType()}). %% Callback event: {@link wxShowEvent}
+-record(wxShow,{type :: wxShowEventType(), %% Callback event: {@link wxShowEvent}
+ show :: boolean()}).
-type wxShowEventType() :: show.
-type wxShow() :: #wxShow{}. %% Callback event: {@link wxShowEvent}
@@ -117,16 +126,25 @@
-type wxSpinEventType() :: command_spinctrl_updated | spin_up | spin_down | spin.
-type wxSpin() :: #wxSpin{}. %% Callback event: {@link wxSpinEvent}
--record(wxSetCursor, {type :: wxSetCursorEventType()}). %% Callback event: {@link wxSetCursorEvent}
+-record(wxSetCursor,{type :: wxSetCursorEventType(), %% Callback event: {@link wxSetCursorEvent}
+ x :: integer(),
+ y :: integer(),
+ cursor :: wxCursor:wxCursor()}).
-type wxSetCursorEventType() :: set_cursor.
-type wxSetCursor() :: #wxSetCursor{}. %% Callback event: {@link wxSetCursorEvent}
+-record(wxMouseCaptureLost, {type :: wxMouseCaptureLostEventType()}). %% Callback event: {@link wxMouseCaptureLostEvent}
+-type wxMouseCaptureLostEventType() :: mouse_capture_lost.
+-type wxMouseCaptureLost() :: #wxMouseCaptureLost{}. %% Callback event: {@link wxMouseCaptureLostEvent}
+
-record(wxFontPicker,{type :: wxFontPickerEventType(), %% Callback event: {@link wxFontPickerEvent}
font :: wxFont:wxFont()}).
-type wxFontPickerEventType() :: command_fontpicker_changed.
-type wxFontPicker() :: #wxFontPicker{}. %% Callback event: {@link wxFontPickerEvent}
--record(wxScrollWin, {type :: wxScrollWinEventType()}). %% Callback event: {@link wxScrollWinEvent}
+-record(wxScrollWin,{type :: wxScrollWinEventType(), %% Callback event: {@link wxScrollWinEvent}
+ commandInt :: integer(),
+ extraLong :: integer()}).
-type wxScrollWinEventType() :: scrollwin_top | scrollwin_bottom | scrollwin_lineup | scrollwin_linedown | scrollwin_pageup | scrollwin_pagedown | scrollwin_thumbtrack | scrollwin_thumbrelease.
-type wxScrollWin() :: #wxScrollWin{}. %% Callback event: {@link wxScrollWinEvent}
@@ -147,7 +165,8 @@
-type wxFileDirPickerEventType() :: command_filepicker_changed | command_dirpicker_changed.
-type wxFileDirPicker() :: #wxFileDirPicker{}. %% Callback event: {@link wxFileDirPickerEvent}
--record(wxFocus, {type :: wxFocusEventType()}). %% Callback event: {@link wxFocusEvent}
+-record(wxFocus,{type :: wxFocusEventType(), %% Callback event: {@link wxFocusEvent}
+ win :: wxWindow:wxWindow()}).
-type wxFocusEventType() :: set_focus | kill_focus.
-type wxFocus() :: #wxFocus{}. %% Callback event: {@link wxFocusEvent}
@@ -225,7 +244,8 @@
-type wxSizeEventType() :: size.
-type wxSize() :: #wxSize{}. %% Callback event: {@link wxSizeEvent}
--record(wxIconize, {type :: wxIconizeEventType()}). %% Callback event: {@link wxIconizeEvent}
+-record(wxIconize,{type :: wxIconizeEventType(), %% Callback event: {@link wxIconizeEvent}
+ iconized :: boolean()}).
-type wxIconizeEventType() :: iconize.
-type wxIconize() :: #wxIconize{}. %% Callback event: {@link wxIconizeEvent}
@@ -275,7 +295,7 @@
veto_flag :: boolean(),
canveto_flag :: boolean(),
dc :: wxDC:wxDC()}).
--type wxAuiManagerEventType() :: aui_pane_button | aui_pane_close | aui_pane_maximize | aui_pane_restore | aui_render | aui_find_manager.
+-type wxAuiManagerEventType() :: aui_pane_button | aui_pane_close | aui_pane_maximize | aui_pane_restore | aui_pane_activated | aui_render | aui_find_manager.
-type wxAuiManager() :: #wxAuiManager{}. %% Callback event: {@link wxAuiManagerEvent}
-record(wxInitDialog, {type :: wxInitDialogEventType()}). %% Callback event: {@link wxInitDialogEvent}
@@ -289,7 +309,12 @@
-type wxCommandEventType() :: command_button_clicked | command_checkbox_clicked | command_choice_selected | command_listbox_selected | command_listbox_doubleclicked | command_text_updated | command_text_enter | command_menu_selected | command_slider_updated | command_radiobox_selected | command_radiobutton_selected | command_scrollbar_updated | command_vlbox_selected | command_combobox_selected | command_tool_rclicked | command_tool_enter | command_checklistbox_toggled | command_togglebutton_clicked | command_left_click | command_left_dclick | command_right_click | command_set_focus | command_kill_focus | command_enter.
-type wxCommand() :: #wxCommand{}. %% Callback event: {@link wxCommandEvent}
--record(wxJoystick, {type :: wxJoystickEventType()}). %% Callback event: {@link wxJoystickEvent}
+-record(wxJoystick,{type :: wxJoystickEventType(), %% Callback event: {@link wxJoystickEvent}
+ pos :: {X::integer(), Y::integer()},
+ zPosition :: integer(),
+ buttonChange :: integer(),
+ buttonState :: integer(),
+ joyStick :: integer()}).
-type wxJoystickEventType() :: joy_button_down | joy_button_up | joy_move | joy_zmove.
-type wxJoystick() :: #wxJoystick{}. %% Callback event: {@link wxJoystickEvent}
@@ -297,7 +322,9 @@
-type wxQueryNewPaletteEventType() :: query_new_palette.
-type wxQueryNewPalette() :: #wxQueryNewPalette{}. %% Callback event: {@link wxQueryNewPaletteEvent}
--record(wxMove, {type :: wxMoveEventType()}). %% Callback event: {@link wxMoveEvent}
+-record(wxMove,{type :: wxMoveEventType(), %% Callback event: {@link wxMoveEvent}
+ pos :: {X::integer(), Y::integer()},
+ rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
-type wxMoveEventType() :: move.
-type wxMove() :: #wxMove{}. %% Callback event: {@link wxMoveEvent}
@@ -321,8 +348,8 @@
-type wxTreeEventType() :: command_tree_begin_drag | command_tree_begin_rdrag | command_tree_begin_label_edit | command_tree_end_label_edit | command_tree_delete_item | command_tree_get_info | command_tree_set_info | command_tree_item_expanded | command_tree_item_expanding | command_tree_item_collapsed | command_tree_item_collapsing | command_tree_sel_changed | command_tree_sel_changing | command_tree_key_down | command_tree_item_activated | command_tree_item_right_click | command_tree_item_middle_click | command_tree_end_drag | command_tree_state_image_click | command_tree_item_gettooltip | command_tree_item_menu.
-type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent}
--type event() :: wxActivate() | wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
--type wxEventType() :: wxActivateEventType() | wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
+-type event() :: wxActivate() | wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMouseCaptureLost() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
+-type wxEventType() :: wxActivateEventType() | wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseCaptureLostEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
%% Hardcoded Records
-record(wxMouseState, {x :: integer(), y :: integer(),
@@ -1883,9 +1910,9 @@
-define(wxCURSOR_WAIT, 24).
-define(wxCURSOR_WATCH, 25).
-define(wxCURSOR_BLANK, 26).
--define(wxCURSOR_DEFAULT, 27).
--define(wxCURSOR_ARROWWAIT, 28).
--define(wxCURSOR_MAX, 29).
+-define(wxCURSOR_DEFAULT, wxe_util:get_const(wxCURSOR_DEFAULT)).
+-define(wxCURSOR_ARROWWAIT, wxe_util:get_const(wxCURSOR_ARROWWAIT)).
+-define(wxCURSOR_MAX, wxe_util:get_const(wxCURSOR_MAX)).
% From "generic_2laywin.h"
-define(wxLAYOUT_QUERY, 256).
-define(wxLAYOUT_MRU_LENGTH, 16).
@@ -1986,239 +2013,239 @@
-define(wxIMAGELIST_DRAW_TRANSPARENT, 2).
-define(wxIMAGELIST_DRAW_NORMAL, 1).
% From "intl.h": wxLanguage
--define(wxLANGUAGE_DEFAULT, 0).
--define(wxLANGUAGE_UNKNOWN, 1).
--define(wxLANGUAGE_ABKHAZIAN, 2).
--define(wxLANGUAGE_AFAR, 3).
--define(wxLANGUAGE_AFRIKAANS, 4).
--define(wxLANGUAGE_ALBANIAN, 5).
--define(wxLANGUAGE_AMHARIC, 6).
--define(wxLANGUAGE_ARABIC, 7).
--define(wxLANGUAGE_ARABIC_ALGERIA, 8).
--define(wxLANGUAGE_ARABIC_BAHRAIN, 9).
--define(wxLANGUAGE_ARABIC_EGYPT, 10).
--define(wxLANGUAGE_ARABIC_IRAQ, 11).
--define(wxLANGUAGE_ARABIC_JORDAN, 12).
--define(wxLANGUAGE_ARABIC_KUWAIT, 13).
--define(wxLANGUAGE_ARABIC_LEBANON, 14).
--define(wxLANGUAGE_ARABIC_LIBYA, 15).
--define(wxLANGUAGE_ARABIC_MOROCCO, 16).
--define(wxLANGUAGE_ARABIC_OMAN, 17).
--define(wxLANGUAGE_ARABIC_QATAR, 18).
--define(wxLANGUAGE_ARABIC_SAUDI_ARABIA, 19).
--define(wxLANGUAGE_ARABIC_SUDAN, 20).
--define(wxLANGUAGE_ARABIC_SYRIA, 21).
--define(wxLANGUAGE_ARABIC_TUNISIA, 22).
--define(wxLANGUAGE_ARABIC_UAE, 23).
--define(wxLANGUAGE_ARABIC_YEMEN, 24).
--define(wxLANGUAGE_ARMENIAN, 25).
--define(wxLANGUAGE_ASSAMESE, 26).
--define(wxLANGUAGE_AYMARA, 27).
--define(wxLANGUAGE_AZERI, 28).
--define(wxLANGUAGE_AZERI_CYRILLIC, 29).
--define(wxLANGUAGE_AZERI_LATIN, 30).
--define(wxLANGUAGE_BASHKIR, 31).
--define(wxLANGUAGE_BASQUE, 32).
--define(wxLANGUAGE_BELARUSIAN, 33).
--define(wxLANGUAGE_BENGALI, 34).
--define(wxLANGUAGE_BHUTANI, 35).
--define(wxLANGUAGE_BIHARI, 36).
--define(wxLANGUAGE_BISLAMA, 37).
--define(wxLANGUAGE_BRETON, 38).
--define(wxLANGUAGE_BULGARIAN, 39).
--define(wxLANGUAGE_BURMESE, 40).
--define(wxLANGUAGE_CAMBODIAN, 41).
--define(wxLANGUAGE_CATALAN, 42).
--define(wxLANGUAGE_CHINESE, 43).
--define(wxLANGUAGE_CHINESE_SIMPLIFIED, 44).
--define(wxLANGUAGE_CHINESE_TRADITIONAL, 45).
--define(wxLANGUAGE_CHINESE_HONGKONG, 46).
--define(wxLANGUAGE_CHINESE_MACAU, 47).
--define(wxLANGUAGE_CHINESE_SINGAPORE, 48).
--define(wxLANGUAGE_CHINESE_TAIWAN, 49).
--define(wxLANGUAGE_CORSICAN, 50).
--define(wxLANGUAGE_CROATIAN, 51).
--define(wxLANGUAGE_CZECH, 52).
--define(wxLANGUAGE_DANISH, 53).
--define(wxLANGUAGE_DUTCH, 54).
--define(wxLANGUAGE_DUTCH_BELGIAN, 55).
--define(wxLANGUAGE_ENGLISH, 56).
--define(wxLANGUAGE_ENGLISH_UK, 57).
--define(wxLANGUAGE_ENGLISH_US, 58).
--define(wxLANGUAGE_ENGLISH_AUSTRALIA, 59).
--define(wxLANGUAGE_ENGLISH_BELIZE, 60).
--define(wxLANGUAGE_ENGLISH_BOTSWANA, 61).
--define(wxLANGUAGE_ENGLISH_CANADA, 62).
--define(wxLANGUAGE_ENGLISH_CARIBBEAN, 63).
--define(wxLANGUAGE_ENGLISH_DENMARK, 64).
--define(wxLANGUAGE_ENGLISH_EIRE, 65).
--define(wxLANGUAGE_ENGLISH_JAMAICA, 66).
--define(wxLANGUAGE_ENGLISH_NEW_ZEALAND, 67).
--define(wxLANGUAGE_ENGLISH_PHILIPPINES, 68).
--define(wxLANGUAGE_ENGLISH_SOUTH_AFRICA, 69).
--define(wxLANGUAGE_ENGLISH_TRINIDAD, 70).
--define(wxLANGUAGE_ENGLISH_ZIMBABWE, 71).
--define(wxLANGUAGE_ESPERANTO, 72).
--define(wxLANGUAGE_ESTONIAN, 73).
--define(wxLANGUAGE_FAEROESE, 74).
--define(wxLANGUAGE_FARSI, 75).
--define(wxLANGUAGE_FIJI, 76).
--define(wxLANGUAGE_FINNISH, 77).
--define(wxLANGUAGE_FRENCH, 78).
--define(wxLANGUAGE_FRENCH_BELGIAN, 79).
--define(wxLANGUAGE_FRENCH_CANADIAN, 80).
--define(wxLANGUAGE_FRENCH_LUXEMBOURG, 81).
--define(wxLANGUAGE_FRENCH_MONACO, 82).
--define(wxLANGUAGE_FRENCH_SWISS, 83).
--define(wxLANGUAGE_FRISIAN, 84).
--define(wxLANGUAGE_GALICIAN, 85).
--define(wxLANGUAGE_GEORGIAN, 86).
--define(wxLANGUAGE_GERMAN, 87).
--define(wxLANGUAGE_GERMAN_AUSTRIAN, 88).
--define(wxLANGUAGE_GERMAN_BELGIUM, 89).
--define(wxLANGUAGE_GERMAN_LIECHTENSTEIN, 90).
--define(wxLANGUAGE_GERMAN_LUXEMBOURG, 91).
--define(wxLANGUAGE_GERMAN_SWISS, 92).
--define(wxLANGUAGE_GREEK, 93).
--define(wxLANGUAGE_GREENLANDIC, 94).
--define(wxLANGUAGE_GUARANI, 95).
--define(wxLANGUAGE_GUJARATI, 96).
--define(wxLANGUAGE_HAUSA, 97).
--define(wxLANGUAGE_HEBREW, 98).
--define(wxLANGUAGE_HINDI, 99).
--define(wxLANGUAGE_HUNGARIAN, 100).
--define(wxLANGUAGE_ICELANDIC, 101).
--define(wxLANGUAGE_INDONESIAN, 102).
--define(wxLANGUAGE_INTERLINGUA, 103).
--define(wxLANGUAGE_INTERLINGUE, 104).
--define(wxLANGUAGE_INUKTITUT, 105).
--define(wxLANGUAGE_INUPIAK, 106).
--define(wxLANGUAGE_IRISH, 107).
--define(wxLANGUAGE_ITALIAN, 108).
--define(wxLANGUAGE_ITALIAN_SWISS, 109).
--define(wxLANGUAGE_JAPANESE, 110).
--define(wxLANGUAGE_JAVANESE, 111).
--define(wxLANGUAGE_KANNADA, 112).
--define(wxLANGUAGE_KASHMIRI, 113).
--define(wxLANGUAGE_KASHMIRI_INDIA, 114).
--define(wxLANGUAGE_KAZAKH, 115).
--define(wxLANGUAGE_KERNEWEK, 116).
--define(wxLANGUAGE_KINYARWANDA, 117).
--define(wxLANGUAGE_KIRGHIZ, 118).
--define(wxLANGUAGE_KIRUNDI, 119).
--define(wxLANGUAGE_KONKANI, 120).
--define(wxLANGUAGE_KOREAN, 121).
--define(wxLANGUAGE_KURDISH, 122).
--define(wxLANGUAGE_LAOTHIAN, 123).
--define(wxLANGUAGE_LATIN, 124).
--define(wxLANGUAGE_LATVIAN, 125).
--define(wxLANGUAGE_LINGALA, 126).
--define(wxLANGUAGE_LITHUANIAN, 127).
--define(wxLANGUAGE_MACEDONIAN, 128).
--define(wxLANGUAGE_MALAGASY, 129).
--define(wxLANGUAGE_MALAY, 130).
--define(wxLANGUAGE_MALAYALAM, 131).
--define(wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM, 132).
--define(wxLANGUAGE_MALAY_MALAYSIA, 133).
--define(wxLANGUAGE_MALTESE, 134).
--define(wxLANGUAGE_MANIPURI, 135).
--define(wxLANGUAGE_MAORI, 136).
--define(wxLANGUAGE_MARATHI, 137).
--define(wxLANGUAGE_MOLDAVIAN, 138).
--define(wxLANGUAGE_MONGOLIAN, 139).
--define(wxLANGUAGE_NAURU, 140).
--define(wxLANGUAGE_NEPALI, 141).
--define(wxLANGUAGE_NEPALI_INDIA, 142).
--define(wxLANGUAGE_NORWEGIAN_BOKMAL, 143).
--define(wxLANGUAGE_NORWEGIAN_NYNORSK, 144).
--define(wxLANGUAGE_OCCITAN, 145).
--define(wxLANGUAGE_ORIYA, 146).
--define(wxLANGUAGE_OROMO, 147).
--define(wxLANGUAGE_PASHTO, 148).
--define(wxLANGUAGE_POLISH, 149).
--define(wxLANGUAGE_PORTUGUESE, 150).
--define(wxLANGUAGE_PORTUGUESE_BRAZILIAN, 151).
--define(wxLANGUAGE_PUNJABI, 152).
--define(wxLANGUAGE_QUECHUA, 153).
--define(wxLANGUAGE_RHAETO_ROMANCE, 154).
--define(wxLANGUAGE_ROMANIAN, 155).
--define(wxLANGUAGE_RUSSIAN, 156).
--define(wxLANGUAGE_RUSSIAN_UKRAINE, 157).
--define(wxLANGUAGE_SAMOAN, 158).
--define(wxLANGUAGE_SANGHO, 159).
--define(wxLANGUAGE_SANSKRIT, 160).
--define(wxLANGUAGE_SCOTS_GAELIC, 161).
--define(wxLANGUAGE_SERBIAN, 162).
--define(wxLANGUAGE_SERBIAN_CYRILLIC, 163).
--define(wxLANGUAGE_SERBIAN_LATIN, 164).
--define(wxLANGUAGE_SERBO_CROATIAN, 165).
--define(wxLANGUAGE_SESOTHO, 166).
--define(wxLANGUAGE_SETSWANA, 167).
--define(wxLANGUAGE_SHONA, 168).
--define(wxLANGUAGE_SINDHI, 169).
--define(wxLANGUAGE_SINHALESE, 170).
--define(wxLANGUAGE_SISWATI, 171).
--define(wxLANGUAGE_SLOVAK, 172).
--define(wxLANGUAGE_SLOVENIAN, 173).
--define(wxLANGUAGE_SOMALI, 174).
--define(wxLANGUAGE_SPANISH, 175).
--define(wxLANGUAGE_SPANISH_ARGENTINA, 176).
--define(wxLANGUAGE_SPANISH_BOLIVIA, 177).
--define(wxLANGUAGE_SPANISH_CHILE, 178).
--define(wxLANGUAGE_SPANISH_COLOMBIA, 179).
--define(wxLANGUAGE_SPANISH_COSTA_RICA, 180).
--define(wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC, 181).
--define(wxLANGUAGE_SPANISH_ECUADOR, 182).
--define(wxLANGUAGE_SPANISH_EL_SALVADOR, 183).
--define(wxLANGUAGE_SPANISH_GUATEMALA, 184).
--define(wxLANGUAGE_SPANISH_HONDURAS, 185).
--define(wxLANGUAGE_SPANISH_MEXICAN, 186).
--define(wxLANGUAGE_SPANISH_MODERN, 187).
--define(wxLANGUAGE_SPANISH_NICARAGUA, 188).
--define(wxLANGUAGE_SPANISH_PANAMA, 189).
--define(wxLANGUAGE_SPANISH_PARAGUAY, 190).
--define(wxLANGUAGE_SPANISH_PERU, 191).
--define(wxLANGUAGE_SPANISH_PUERTO_RICO, 192).
--define(wxLANGUAGE_SPANISH_URUGUAY, 193).
--define(wxLANGUAGE_SPANISH_US, 194).
--define(wxLANGUAGE_SPANISH_VENEZUELA, 195).
--define(wxLANGUAGE_SUNDANESE, 196).
--define(wxLANGUAGE_SWAHILI, 197).
--define(wxLANGUAGE_SWEDISH, 198).
--define(wxLANGUAGE_SWEDISH_FINLAND, 199).
--define(wxLANGUAGE_TAGALOG, 200).
--define(wxLANGUAGE_TAJIK, 201).
--define(wxLANGUAGE_TAMIL, 202).
--define(wxLANGUAGE_TATAR, 203).
--define(wxLANGUAGE_TELUGU, 204).
--define(wxLANGUAGE_THAI, 205).
--define(wxLANGUAGE_TIBETAN, 206).
--define(wxLANGUAGE_TIGRINYA, 207).
--define(wxLANGUAGE_TONGA, 208).
--define(wxLANGUAGE_TSONGA, 209).
--define(wxLANGUAGE_TURKISH, 210).
--define(wxLANGUAGE_TURKMEN, 211).
--define(wxLANGUAGE_TWI, 212).
--define(wxLANGUAGE_UIGHUR, 213).
--define(wxLANGUAGE_UKRAINIAN, 214).
--define(wxLANGUAGE_URDU, 215).
--define(wxLANGUAGE_URDU_INDIA, 216).
--define(wxLANGUAGE_URDU_PAKISTAN, 217).
--define(wxLANGUAGE_UZBEK, 218).
--define(wxLANGUAGE_UZBEK_CYRILLIC, 219).
--define(wxLANGUAGE_UZBEK_LATIN, 220).
--define(wxLANGUAGE_VIETNAMESE, 221).
--define(wxLANGUAGE_VOLAPUK, 222).
--define(wxLANGUAGE_WELSH, 223).
--define(wxLANGUAGE_WOLOF, 224).
--define(wxLANGUAGE_XHOSA, 225).
--define(wxLANGUAGE_YIDDISH, 226).
--define(wxLANGUAGE_YORUBA, 227).
--define(wxLANGUAGE_ZHUANG, 228).
--define(wxLANGUAGE_ZULU, 229).
--define(wxLANGUAGE_USER_DEFINED, 230).
--define(wxLANGUAGE_VALENCIAN, 536870911).
--define(wxLANGUAGE_SAMI, 536870912).
+-define(wxLANGUAGE_DEFAULT, wxe_util:get_const(wxLANGUAGE_DEFAULT)).
+-define(wxLANGUAGE_UNKNOWN, wxe_util:get_const(wxLANGUAGE_UNKNOWN)).
+-define(wxLANGUAGE_ABKHAZIAN, wxe_util:get_const(wxLANGUAGE_ABKHAZIAN)).
+-define(wxLANGUAGE_AFAR, wxe_util:get_const(wxLANGUAGE_AFAR)).
+-define(wxLANGUAGE_AFRIKAANS, wxe_util:get_const(wxLANGUAGE_AFRIKAANS)).
+-define(wxLANGUAGE_ALBANIAN, wxe_util:get_const(wxLANGUAGE_ALBANIAN)).
+-define(wxLANGUAGE_AMHARIC, wxe_util:get_const(wxLANGUAGE_AMHARIC)).
+-define(wxLANGUAGE_ARABIC, wxe_util:get_const(wxLANGUAGE_ARABIC)).
+-define(wxLANGUAGE_ARABIC_ALGERIA, wxe_util:get_const(wxLANGUAGE_ARABIC_ALGERIA)).
+-define(wxLANGUAGE_ARABIC_BAHRAIN, wxe_util:get_const(wxLANGUAGE_ARABIC_BAHRAIN)).
+-define(wxLANGUAGE_ARABIC_EGYPT, wxe_util:get_const(wxLANGUAGE_ARABIC_EGYPT)).
+-define(wxLANGUAGE_ARABIC_IRAQ, wxe_util:get_const(wxLANGUAGE_ARABIC_IRAQ)).
+-define(wxLANGUAGE_ARABIC_JORDAN, wxe_util:get_const(wxLANGUAGE_ARABIC_JORDAN)).
+-define(wxLANGUAGE_ARABIC_KUWAIT, wxe_util:get_const(wxLANGUAGE_ARABIC_KUWAIT)).
+-define(wxLANGUAGE_ARABIC_LEBANON, wxe_util:get_const(wxLANGUAGE_ARABIC_LEBANON)).
+-define(wxLANGUAGE_ARABIC_LIBYA, wxe_util:get_const(wxLANGUAGE_ARABIC_LIBYA)).
+-define(wxLANGUAGE_ARABIC_MOROCCO, wxe_util:get_const(wxLANGUAGE_ARABIC_MOROCCO)).
+-define(wxLANGUAGE_ARABIC_OMAN, wxe_util:get_const(wxLANGUAGE_ARABIC_OMAN)).
+-define(wxLANGUAGE_ARABIC_QATAR, wxe_util:get_const(wxLANGUAGE_ARABIC_QATAR)).
+-define(wxLANGUAGE_ARABIC_SAUDI_ARABIA, wxe_util:get_const(wxLANGUAGE_ARABIC_SAUDI_ARABIA)).
+-define(wxLANGUAGE_ARABIC_SUDAN, wxe_util:get_const(wxLANGUAGE_ARABIC_SUDAN)).
+-define(wxLANGUAGE_ARABIC_SYRIA, wxe_util:get_const(wxLANGUAGE_ARABIC_SYRIA)).
+-define(wxLANGUAGE_ARABIC_TUNISIA, wxe_util:get_const(wxLANGUAGE_ARABIC_TUNISIA)).
+-define(wxLANGUAGE_ARABIC_UAE, wxe_util:get_const(wxLANGUAGE_ARABIC_UAE)).
+-define(wxLANGUAGE_ARABIC_YEMEN, wxe_util:get_const(wxLANGUAGE_ARABIC_YEMEN)).
+-define(wxLANGUAGE_ARMENIAN, wxe_util:get_const(wxLANGUAGE_ARMENIAN)).
+-define(wxLANGUAGE_ASSAMESE, wxe_util:get_const(wxLANGUAGE_ASSAMESE)).
+-define(wxLANGUAGE_AYMARA, wxe_util:get_const(wxLANGUAGE_AYMARA)).
+-define(wxLANGUAGE_AZERI, wxe_util:get_const(wxLANGUAGE_AZERI)).
+-define(wxLANGUAGE_AZERI_CYRILLIC, wxe_util:get_const(wxLANGUAGE_AZERI_CYRILLIC)).
+-define(wxLANGUAGE_AZERI_LATIN, wxe_util:get_const(wxLANGUAGE_AZERI_LATIN)).
+-define(wxLANGUAGE_BASHKIR, wxe_util:get_const(wxLANGUAGE_BASHKIR)).
+-define(wxLANGUAGE_BASQUE, wxe_util:get_const(wxLANGUAGE_BASQUE)).
+-define(wxLANGUAGE_BELARUSIAN, wxe_util:get_const(wxLANGUAGE_BELARUSIAN)).
+-define(wxLANGUAGE_BENGALI, wxe_util:get_const(wxLANGUAGE_BENGALI)).
+-define(wxLANGUAGE_BHUTANI, wxe_util:get_const(wxLANGUAGE_BHUTANI)).
+-define(wxLANGUAGE_BIHARI, wxe_util:get_const(wxLANGUAGE_BIHARI)).
+-define(wxLANGUAGE_BISLAMA, wxe_util:get_const(wxLANGUAGE_BISLAMA)).
+-define(wxLANGUAGE_BRETON, wxe_util:get_const(wxLANGUAGE_BRETON)).
+-define(wxLANGUAGE_BULGARIAN, wxe_util:get_const(wxLANGUAGE_BULGARIAN)).
+-define(wxLANGUAGE_BURMESE, wxe_util:get_const(wxLANGUAGE_BURMESE)).
+-define(wxLANGUAGE_CAMBODIAN, wxe_util:get_const(wxLANGUAGE_CAMBODIAN)).
+-define(wxLANGUAGE_CATALAN, wxe_util:get_const(wxLANGUAGE_CATALAN)).
+-define(wxLANGUAGE_CHINESE, wxe_util:get_const(wxLANGUAGE_CHINESE)).
+-define(wxLANGUAGE_CHINESE_SIMPLIFIED, wxe_util:get_const(wxLANGUAGE_CHINESE_SIMPLIFIED)).
+-define(wxLANGUAGE_CHINESE_TRADITIONAL, wxe_util:get_const(wxLANGUAGE_CHINESE_TRADITIONAL)).
+-define(wxLANGUAGE_CHINESE_HONGKONG, wxe_util:get_const(wxLANGUAGE_CHINESE_HONGKONG)).
+-define(wxLANGUAGE_CHINESE_MACAU, wxe_util:get_const(wxLANGUAGE_CHINESE_MACAU)).
+-define(wxLANGUAGE_CHINESE_SINGAPORE, wxe_util:get_const(wxLANGUAGE_CHINESE_SINGAPORE)).
+-define(wxLANGUAGE_CHINESE_TAIWAN, wxe_util:get_const(wxLANGUAGE_CHINESE_TAIWAN)).
+-define(wxLANGUAGE_CORSICAN, wxe_util:get_const(wxLANGUAGE_CORSICAN)).
+-define(wxLANGUAGE_CROATIAN, wxe_util:get_const(wxLANGUAGE_CROATIAN)).
+-define(wxLANGUAGE_CZECH, wxe_util:get_const(wxLANGUAGE_CZECH)).
+-define(wxLANGUAGE_DANISH, wxe_util:get_const(wxLANGUAGE_DANISH)).
+-define(wxLANGUAGE_DUTCH, wxe_util:get_const(wxLANGUAGE_DUTCH)).
+-define(wxLANGUAGE_DUTCH_BELGIAN, wxe_util:get_const(wxLANGUAGE_DUTCH_BELGIAN)).
+-define(wxLANGUAGE_ENGLISH, wxe_util:get_const(wxLANGUAGE_ENGLISH)).
+-define(wxLANGUAGE_ENGLISH_UK, wxe_util:get_const(wxLANGUAGE_ENGLISH_UK)).
+-define(wxLANGUAGE_ENGLISH_US, wxe_util:get_const(wxLANGUAGE_ENGLISH_US)).
+-define(wxLANGUAGE_ENGLISH_AUSTRALIA, wxe_util:get_const(wxLANGUAGE_ENGLISH_AUSTRALIA)).
+-define(wxLANGUAGE_ENGLISH_BELIZE, wxe_util:get_const(wxLANGUAGE_ENGLISH_BELIZE)).
+-define(wxLANGUAGE_ENGLISH_BOTSWANA, wxe_util:get_const(wxLANGUAGE_ENGLISH_BOTSWANA)).
+-define(wxLANGUAGE_ENGLISH_CANADA, wxe_util:get_const(wxLANGUAGE_ENGLISH_CANADA)).
+-define(wxLANGUAGE_ENGLISH_CARIBBEAN, wxe_util:get_const(wxLANGUAGE_ENGLISH_CARIBBEAN)).
+-define(wxLANGUAGE_ENGLISH_DENMARK, wxe_util:get_const(wxLANGUAGE_ENGLISH_DENMARK)).
+-define(wxLANGUAGE_ENGLISH_EIRE, wxe_util:get_const(wxLANGUAGE_ENGLISH_EIRE)).
+-define(wxLANGUAGE_ENGLISH_JAMAICA, wxe_util:get_const(wxLANGUAGE_ENGLISH_JAMAICA)).
+-define(wxLANGUAGE_ENGLISH_NEW_ZEALAND, wxe_util:get_const(wxLANGUAGE_ENGLISH_NEW_ZEALAND)).
+-define(wxLANGUAGE_ENGLISH_PHILIPPINES, wxe_util:get_const(wxLANGUAGE_ENGLISH_PHILIPPINES)).
+-define(wxLANGUAGE_ENGLISH_SOUTH_AFRICA, wxe_util:get_const(wxLANGUAGE_ENGLISH_SOUTH_AFRICA)).
+-define(wxLANGUAGE_ENGLISH_TRINIDAD, wxe_util:get_const(wxLANGUAGE_ENGLISH_TRINIDAD)).
+-define(wxLANGUAGE_ENGLISH_ZIMBABWE, wxe_util:get_const(wxLANGUAGE_ENGLISH_ZIMBABWE)).
+-define(wxLANGUAGE_ESPERANTO, wxe_util:get_const(wxLANGUAGE_ESPERANTO)).
+-define(wxLANGUAGE_ESTONIAN, wxe_util:get_const(wxLANGUAGE_ESTONIAN)).
+-define(wxLANGUAGE_FAEROESE, wxe_util:get_const(wxLANGUAGE_FAEROESE)).
+-define(wxLANGUAGE_FARSI, wxe_util:get_const(wxLANGUAGE_FARSI)).
+-define(wxLANGUAGE_FIJI, wxe_util:get_const(wxLANGUAGE_FIJI)).
+-define(wxLANGUAGE_FINNISH, wxe_util:get_const(wxLANGUAGE_FINNISH)).
+-define(wxLANGUAGE_FRENCH, wxe_util:get_const(wxLANGUAGE_FRENCH)).
+-define(wxLANGUAGE_FRENCH_BELGIAN, wxe_util:get_const(wxLANGUAGE_FRENCH_BELGIAN)).
+-define(wxLANGUAGE_FRENCH_CANADIAN, wxe_util:get_const(wxLANGUAGE_FRENCH_CANADIAN)).
+-define(wxLANGUAGE_FRENCH_LUXEMBOURG, wxe_util:get_const(wxLANGUAGE_FRENCH_LUXEMBOURG)).
+-define(wxLANGUAGE_FRENCH_MONACO, wxe_util:get_const(wxLANGUAGE_FRENCH_MONACO)).
+-define(wxLANGUAGE_FRENCH_SWISS, wxe_util:get_const(wxLANGUAGE_FRENCH_SWISS)).
+-define(wxLANGUAGE_FRISIAN, wxe_util:get_const(wxLANGUAGE_FRISIAN)).
+-define(wxLANGUAGE_GALICIAN, wxe_util:get_const(wxLANGUAGE_GALICIAN)).
+-define(wxLANGUAGE_GEORGIAN, wxe_util:get_const(wxLANGUAGE_GEORGIAN)).
+-define(wxLANGUAGE_GERMAN, wxe_util:get_const(wxLANGUAGE_GERMAN)).
+-define(wxLANGUAGE_GERMAN_AUSTRIAN, wxe_util:get_const(wxLANGUAGE_GERMAN_AUSTRIAN)).
+-define(wxLANGUAGE_GERMAN_BELGIUM, wxe_util:get_const(wxLANGUAGE_GERMAN_BELGIUM)).
+-define(wxLANGUAGE_GERMAN_LIECHTENSTEIN, wxe_util:get_const(wxLANGUAGE_GERMAN_LIECHTENSTEIN)).
+-define(wxLANGUAGE_GERMAN_LUXEMBOURG, wxe_util:get_const(wxLANGUAGE_GERMAN_LUXEMBOURG)).
+-define(wxLANGUAGE_GERMAN_SWISS, wxe_util:get_const(wxLANGUAGE_GERMAN_SWISS)).
+-define(wxLANGUAGE_GREEK, wxe_util:get_const(wxLANGUAGE_GREEK)).
+-define(wxLANGUAGE_GREENLANDIC, wxe_util:get_const(wxLANGUAGE_GREENLANDIC)).
+-define(wxLANGUAGE_GUARANI, wxe_util:get_const(wxLANGUAGE_GUARANI)).
+-define(wxLANGUAGE_GUJARATI, wxe_util:get_const(wxLANGUAGE_GUJARATI)).
+-define(wxLANGUAGE_HAUSA, wxe_util:get_const(wxLANGUAGE_HAUSA)).
+-define(wxLANGUAGE_HEBREW, wxe_util:get_const(wxLANGUAGE_HEBREW)).
+-define(wxLANGUAGE_HINDI, wxe_util:get_const(wxLANGUAGE_HINDI)).
+-define(wxLANGUAGE_HUNGARIAN, wxe_util:get_const(wxLANGUAGE_HUNGARIAN)).
+-define(wxLANGUAGE_ICELANDIC, wxe_util:get_const(wxLANGUAGE_ICELANDIC)).
+-define(wxLANGUAGE_INDONESIAN, wxe_util:get_const(wxLANGUAGE_INDONESIAN)).
+-define(wxLANGUAGE_INTERLINGUA, wxe_util:get_const(wxLANGUAGE_INTERLINGUA)).
+-define(wxLANGUAGE_INTERLINGUE, wxe_util:get_const(wxLANGUAGE_INTERLINGUE)).
+-define(wxLANGUAGE_INUKTITUT, wxe_util:get_const(wxLANGUAGE_INUKTITUT)).
+-define(wxLANGUAGE_INUPIAK, wxe_util:get_const(wxLANGUAGE_INUPIAK)).
+-define(wxLANGUAGE_IRISH, wxe_util:get_const(wxLANGUAGE_IRISH)).
+-define(wxLANGUAGE_ITALIAN, wxe_util:get_const(wxLANGUAGE_ITALIAN)).
+-define(wxLANGUAGE_ITALIAN_SWISS, wxe_util:get_const(wxLANGUAGE_ITALIAN_SWISS)).
+-define(wxLANGUAGE_JAPANESE, wxe_util:get_const(wxLANGUAGE_JAPANESE)).
+-define(wxLANGUAGE_JAVANESE, wxe_util:get_const(wxLANGUAGE_JAVANESE)).
+-define(wxLANGUAGE_KANNADA, wxe_util:get_const(wxLANGUAGE_KANNADA)).
+-define(wxLANGUAGE_KASHMIRI, wxe_util:get_const(wxLANGUAGE_KASHMIRI)).
+-define(wxLANGUAGE_KASHMIRI_INDIA, wxe_util:get_const(wxLANGUAGE_KASHMIRI_INDIA)).
+-define(wxLANGUAGE_KAZAKH, wxe_util:get_const(wxLANGUAGE_KAZAKH)).
+-define(wxLANGUAGE_KERNEWEK, wxe_util:get_const(wxLANGUAGE_KERNEWEK)).
+-define(wxLANGUAGE_KINYARWANDA, wxe_util:get_const(wxLANGUAGE_KINYARWANDA)).
+-define(wxLANGUAGE_KIRGHIZ, wxe_util:get_const(wxLANGUAGE_KIRGHIZ)).
+-define(wxLANGUAGE_KIRUNDI, wxe_util:get_const(wxLANGUAGE_KIRUNDI)).
+-define(wxLANGUAGE_KONKANI, wxe_util:get_const(wxLANGUAGE_KONKANI)).
+-define(wxLANGUAGE_KOREAN, wxe_util:get_const(wxLANGUAGE_KOREAN)).
+-define(wxLANGUAGE_KURDISH, wxe_util:get_const(wxLANGUAGE_KURDISH)).
+-define(wxLANGUAGE_LAOTHIAN, wxe_util:get_const(wxLANGUAGE_LAOTHIAN)).
+-define(wxLANGUAGE_LATIN, wxe_util:get_const(wxLANGUAGE_LATIN)).
+-define(wxLANGUAGE_LATVIAN, wxe_util:get_const(wxLANGUAGE_LATVIAN)).
+-define(wxLANGUAGE_LINGALA, wxe_util:get_const(wxLANGUAGE_LINGALA)).
+-define(wxLANGUAGE_LITHUANIAN, wxe_util:get_const(wxLANGUAGE_LITHUANIAN)).
+-define(wxLANGUAGE_MACEDONIAN, wxe_util:get_const(wxLANGUAGE_MACEDONIAN)).
+-define(wxLANGUAGE_MALAGASY, wxe_util:get_const(wxLANGUAGE_MALAGASY)).
+-define(wxLANGUAGE_MALAY, wxe_util:get_const(wxLANGUAGE_MALAY)).
+-define(wxLANGUAGE_MALAYALAM, wxe_util:get_const(wxLANGUAGE_MALAYALAM)).
+-define(wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM, wxe_util:get_const(wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM)).
+-define(wxLANGUAGE_MALAY_MALAYSIA, wxe_util:get_const(wxLANGUAGE_MALAY_MALAYSIA)).
+-define(wxLANGUAGE_MALTESE, wxe_util:get_const(wxLANGUAGE_MALTESE)).
+-define(wxLANGUAGE_MANIPURI, wxe_util:get_const(wxLANGUAGE_MANIPURI)).
+-define(wxLANGUAGE_MAORI, wxe_util:get_const(wxLANGUAGE_MAORI)).
+-define(wxLANGUAGE_MARATHI, wxe_util:get_const(wxLANGUAGE_MARATHI)).
+-define(wxLANGUAGE_MOLDAVIAN, wxe_util:get_const(wxLANGUAGE_MOLDAVIAN)).
+-define(wxLANGUAGE_MONGOLIAN, wxe_util:get_const(wxLANGUAGE_MONGOLIAN)).
+-define(wxLANGUAGE_NAURU, wxe_util:get_const(wxLANGUAGE_NAURU)).
+-define(wxLANGUAGE_NEPALI, wxe_util:get_const(wxLANGUAGE_NEPALI)).
+-define(wxLANGUAGE_NEPALI_INDIA, wxe_util:get_const(wxLANGUAGE_NEPALI_INDIA)).
+-define(wxLANGUAGE_NORWEGIAN_BOKMAL, wxe_util:get_const(wxLANGUAGE_NORWEGIAN_BOKMAL)).
+-define(wxLANGUAGE_NORWEGIAN_NYNORSK, wxe_util:get_const(wxLANGUAGE_NORWEGIAN_NYNORSK)).
+-define(wxLANGUAGE_OCCITAN, wxe_util:get_const(wxLANGUAGE_OCCITAN)).
+-define(wxLANGUAGE_ORIYA, wxe_util:get_const(wxLANGUAGE_ORIYA)).
+-define(wxLANGUAGE_OROMO, wxe_util:get_const(wxLANGUAGE_OROMO)).
+-define(wxLANGUAGE_PASHTO, wxe_util:get_const(wxLANGUAGE_PASHTO)).
+-define(wxLANGUAGE_POLISH, wxe_util:get_const(wxLANGUAGE_POLISH)).
+-define(wxLANGUAGE_PORTUGUESE, wxe_util:get_const(wxLANGUAGE_PORTUGUESE)).
+-define(wxLANGUAGE_PORTUGUESE_BRAZILIAN, wxe_util:get_const(wxLANGUAGE_PORTUGUESE_BRAZILIAN)).
+-define(wxLANGUAGE_PUNJABI, wxe_util:get_const(wxLANGUAGE_PUNJABI)).
+-define(wxLANGUAGE_QUECHUA, wxe_util:get_const(wxLANGUAGE_QUECHUA)).
+-define(wxLANGUAGE_RHAETO_ROMANCE, wxe_util:get_const(wxLANGUAGE_RHAETO_ROMANCE)).
+-define(wxLANGUAGE_ROMANIAN, wxe_util:get_const(wxLANGUAGE_ROMANIAN)).
+-define(wxLANGUAGE_RUSSIAN, wxe_util:get_const(wxLANGUAGE_RUSSIAN)).
+-define(wxLANGUAGE_RUSSIAN_UKRAINE, wxe_util:get_const(wxLANGUAGE_RUSSIAN_UKRAINE)).
+-define(wxLANGUAGE_SAMOAN, wxe_util:get_const(wxLANGUAGE_SAMOAN)).
+-define(wxLANGUAGE_SANGHO, wxe_util:get_const(wxLANGUAGE_SANGHO)).
+-define(wxLANGUAGE_SANSKRIT, wxe_util:get_const(wxLANGUAGE_SANSKRIT)).
+-define(wxLANGUAGE_SCOTS_GAELIC, wxe_util:get_const(wxLANGUAGE_SCOTS_GAELIC)).
+-define(wxLANGUAGE_SERBIAN, wxe_util:get_const(wxLANGUAGE_SERBIAN)).
+-define(wxLANGUAGE_SERBIAN_CYRILLIC, wxe_util:get_const(wxLANGUAGE_SERBIAN_CYRILLIC)).
+-define(wxLANGUAGE_SERBIAN_LATIN, wxe_util:get_const(wxLANGUAGE_SERBIAN_LATIN)).
+-define(wxLANGUAGE_SERBO_CROATIAN, wxe_util:get_const(wxLANGUAGE_SERBO_CROATIAN)).
+-define(wxLANGUAGE_SESOTHO, wxe_util:get_const(wxLANGUAGE_SESOTHO)).
+-define(wxLANGUAGE_SETSWANA, wxe_util:get_const(wxLANGUAGE_SETSWANA)).
+-define(wxLANGUAGE_SHONA, wxe_util:get_const(wxLANGUAGE_SHONA)).
+-define(wxLANGUAGE_SINDHI, wxe_util:get_const(wxLANGUAGE_SINDHI)).
+-define(wxLANGUAGE_SINHALESE, wxe_util:get_const(wxLANGUAGE_SINHALESE)).
+-define(wxLANGUAGE_SISWATI, wxe_util:get_const(wxLANGUAGE_SISWATI)).
+-define(wxLANGUAGE_SLOVAK, wxe_util:get_const(wxLANGUAGE_SLOVAK)).
+-define(wxLANGUAGE_SLOVENIAN, wxe_util:get_const(wxLANGUAGE_SLOVENIAN)).
+-define(wxLANGUAGE_SOMALI, wxe_util:get_const(wxLANGUAGE_SOMALI)).
+-define(wxLANGUAGE_SPANISH, wxe_util:get_const(wxLANGUAGE_SPANISH)).
+-define(wxLANGUAGE_SPANISH_ARGENTINA, wxe_util:get_const(wxLANGUAGE_SPANISH_ARGENTINA)).
+-define(wxLANGUAGE_SPANISH_BOLIVIA, wxe_util:get_const(wxLANGUAGE_SPANISH_BOLIVIA)).
+-define(wxLANGUAGE_SPANISH_CHILE, wxe_util:get_const(wxLANGUAGE_SPANISH_CHILE)).
+-define(wxLANGUAGE_SPANISH_COLOMBIA, wxe_util:get_const(wxLANGUAGE_SPANISH_COLOMBIA)).
+-define(wxLANGUAGE_SPANISH_COSTA_RICA, wxe_util:get_const(wxLANGUAGE_SPANISH_COSTA_RICA)).
+-define(wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC, wxe_util:get_const(wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC)).
+-define(wxLANGUAGE_SPANISH_ECUADOR, wxe_util:get_const(wxLANGUAGE_SPANISH_ECUADOR)).
+-define(wxLANGUAGE_SPANISH_EL_SALVADOR, wxe_util:get_const(wxLANGUAGE_SPANISH_EL_SALVADOR)).
+-define(wxLANGUAGE_SPANISH_GUATEMALA, wxe_util:get_const(wxLANGUAGE_SPANISH_GUATEMALA)).
+-define(wxLANGUAGE_SPANISH_HONDURAS, wxe_util:get_const(wxLANGUAGE_SPANISH_HONDURAS)).
+-define(wxLANGUAGE_SPANISH_MEXICAN, wxe_util:get_const(wxLANGUAGE_SPANISH_MEXICAN)).
+-define(wxLANGUAGE_SPANISH_MODERN, wxe_util:get_const(wxLANGUAGE_SPANISH_MODERN)).
+-define(wxLANGUAGE_SPANISH_NICARAGUA, wxe_util:get_const(wxLANGUAGE_SPANISH_NICARAGUA)).
+-define(wxLANGUAGE_SPANISH_PANAMA, wxe_util:get_const(wxLANGUAGE_SPANISH_PANAMA)).
+-define(wxLANGUAGE_SPANISH_PARAGUAY, wxe_util:get_const(wxLANGUAGE_SPANISH_PARAGUAY)).
+-define(wxLANGUAGE_SPANISH_PERU, wxe_util:get_const(wxLANGUAGE_SPANISH_PERU)).
+-define(wxLANGUAGE_SPANISH_PUERTO_RICO, wxe_util:get_const(wxLANGUAGE_SPANISH_PUERTO_RICO)).
+-define(wxLANGUAGE_SPANISH_URUGUAY, wxe_util:get_const(wxLANGUAGE_SPANISH_URUGUAY)).
+-define(wxLANGUAGE_SPANISH_US, wxe_util:get_const(wxLANGUAGE_SPANISH_US)).
+-define(wxLANGUAGE_SPANISH_VENEZUELA, wxe_util:get_const(wxLANGUAGE_SPANISH_VENEZUELA)).
+-define(wxLANGUAGE_SUNDANESE, wxe_util:get_const(wxLANGUAGE_SUNDANESE)).
+-define(wxLANGUAGE_SWAHILI, wxe_util:get_const(wxLANGUAGE_SWAHILI)).
+-define(wxLANGUAGE_SWEDISH, wxe_util:get_const(wxLANGUAGE_SWEDISH)).
+-define(wxLANGUAGE_SWEDISH_FINLAND, wxe_util:get_const(wxLANGUAGE_SWEDISH_FINLAND)).
+-define(wxLANGUAGE_TAGALOG, wxe_util:get_const(wxLANGUAGE_TAGALOG)).
+-define(wxLANGUAGE_TAJIK, wxe_util:get_const(wxLANGUAGE_TAJIK)).
+-define(wxLANGUAGE_TAMIL, wxe_util:get_const(wxLANGUAGE_TAMIL)).
+-define(wxLANGUAGE_TATAR, wxe_util:get_const(wxLANGUAGE_TATAR)).
+-define(wxLANGUAGE_TELUGU, wxe_util:get_const(wxLANGUAGE_TELUGU)).
+-define(wxLANGUAGE_THAI, wxe_util:get_const(wxLANGUAGE_THAI)).
+-define(wxLANGUAGE_TIBETAN, wxe_util:get_const(wxLANGUAGE_TIBETAN)).
+-define(wxLANGUAGE_TIGRINYA, wxe_util:get_const(wxLANGUAGE_TIGRINYA)).
+-define(wxLANGUAGE_TONGA, wxe_util:get_const(wxLANGUAGE_TONGA)).
+-define(wxLANGUAGE_TSONGA, wxe_util:get_const(wxLANGUAGE_TSONGA)).
+-define(wxLANGUAGE_TURKISH, wxe_util:get_const(wxLANGUAGE_TURKISH)).
+-define(wxLANGUAGE_TURKMEN, wxe_util:get_const(wxLANGUAGE_TURKMEN)).
+-define(wxLANGUAGE_TWI, wxe_util:get_const(wxLANGUAGE_TWI)).
+-define(wxLANGUAGE_UIGHUR, wxe_util:get_const(wxLANGUAGE_UIGHUR)).
+-define(wxLANGUAGE_UKRAINIAN, wxe_util:get_const(wxLANGUAGE_UKRAINIAN)).
+-define(wxLANGUAGE_URDU, wxe_util:get_const(wxLANGUAGE_URDU)).
+-define(wxLANGUAGE_URDU_INDIA, wxe_util:get_const(wxLANGUAGE_URDU_INDIA)).
+-define(wxLANGUAGE_URDU_PAKISTAN, wxe_util:get_const(wxLANGUAGE_URDU_PAKISTAN)).
+-define(wxLANGUAGE_UZBEK, wxe_util:get_const(wxLANGUAGE_UZBEK)).
+-define(wxLANGUAGE_UZBEK_CYRILLIC, wxe_util:get_const(wxLANGUAGE_UZBEK_CYRILLIC)).
+-define(wxLANGUAGE_UZBEK_LATIN, wxe_util:get_const(wxLANGUAGE_UZBEK_LATIN)).
+-define(wxLANGUAGE_VIETNAMESE, wxe_util:get_const(wxLANGUAGE_VIETNAMESE)).
+-define(wxLANGUAGE_VOLAPUK, wxe_util:get_const(wxLANGUAGE_VOLAPUK)).
+-define(wxLANGUAGE_WELSH, wxe_util:get_const(wxLANGUAGE_WELSH)).
+-define(wxLANGUAGE_WOLOF, wxe_util:get_const(wxLANGUAGE_WOLOF)).
+-define(wxLANGUAGE_XHOSA, wxe_util:get_const(wxLANGUAGE_XHOSA)).
+-define(wxLANGUAGE_YIDDISH, wxe_util:get_const(wxLANGUAGE_YIDDISH)).
+-define(wxLANGUAGE_YORUBA, wxe_util:get_const(wxLANGUAGE_YORUBA)).
+-define(wxLANGUAGE_ZHUANG, wxe_util:get_const(wxLANGUAGE_ZHUANG)).
+-define(wxLANGUAGE_ZULU, wxe_util:get_const(wxLANGUAGE_ZULU)).
+-define(wxLANGUAGE_USER_DEFINED, wxe_util:get_const(wxLANGUAGE_USER_DEFINED)).
+-define(wxLANGUAGE_VALENCIAN, wxe_util:get_const(wxLANGUAGE_VALENCIAN)).
+-define(wxLANGUAGE_SAMI, wxe_util:get_const(wxLANGUAGE_SAMI)).
% From "intl.h": wxLayoutDirection
-define(wxLayout_Default, 0).
-define(wxLayout_LeftToRight, 1).
@@ -4058,7 +4085,3 @@
-define(wxWINDOW_VARIANT_MINI, 2).
-define(wxWINDOW_VARIANT_LARGE, 3).
-define(wxWINDOW_VARIANT_MAX, 4).
-% From "xmlres.h": wxXmlResourceFlags
--define(wxXRC_USE_LOCALE, 1).
--define(wxXRC_NO_SUBCLASSING, 2).
--define(wxXRC_NO_RELOADING, 4).
diff --git a/lib/wx/license.terms b/lib/wx/license.terms
deleted file mode 100644
index 36aa84e332..0000000000
--- a/lib/wx/license.terms
+++ /dev/null
@@ -1,286 +0,0 @@
-ERLANG PUBLIC LICENSE
-Version 1.1
-
-1. Definitions.
-
-1.1. ``Contributor'' means each entity that creates or contributes to
-the creation of Modifications.
-
-1.2. ``Contributor Version'' means the combination of the Original
-Code, prior Modifications used by a Contributor, and the Modifications
-made by that particular Contributor.
-
-1.3. ``Covered Code'' means the Original Code or Modifications or the
-combination of the Original Code and Modifications, in each case
-including portions thereof.
-
-1.4. ``Electronic Distribution Mechanism'' means a mechanism generally
-accepted in the software development community for the electronic
-transfer of data.
-
-1.5. ``Executable'' means Covered Code in any form other than Source
-Code.
-
-1.6. ``Initial Developer'' means the individual or entity identified
-as the Initial Developer in the Source Code notice required by Exhibit
-A.
-
-1.7. ``Larger Work'' means a work which combines Covered Code or
-portions thereof with code not governed by the terms of this License.
-
-1.8. ``License'' means this document.
-
-1.9. ``Modifications'' means any addition to or deletion from the
-substance or structure of either the Original Code or any previous
-Modifications. When Covered Code is released as a series of files, a
-Modification is:
-
-A. Any addition to or deletion from the contents of a file containing
- Original Code or previous Modifications.
-
-B. Any new file that contains any part of the Original Code or
- previous Modifications.
-
-1.10. ``Original Code'' means Source Code of computer software code
-which is described in the Source Code notice required by Exhibit A as
-Original Code, and which, at the time of its release under this
-License is not already Covered Code governed by this License.
-
-1.11. ``Source Code'' means the preferred form of the Covered Code for
-making modifications to it, including all modules it contains, plus
-any associated interface definition files, scripts used to control
-compilation and installation of an Executable, or a list of source
-code differential comparisons against either the Original Code or
-another well known, available Covered Code of the Contributor's
-choice. The Source Code can be in a compressed or archival form,
-provided the appropriate decompression or de-archiving software is
-widely available for no charge.
-
-1.12. ``You'' means an individual or a legal entity exercising rights
-under, and complying with all of the terms of, this License. For legal
-entities,``You'' includes any entity which controls, is controlled by,
-or is under common control with You. For purposes of this definition,
-``control'' means (a) the power, direct or indirect, to cause the
-direction or management of such entity, whether by contract or
-otherwise, or (b) ownership of fifty percent (50%) or more of the
-outstanding shares or beneficial ownership of such entity.
-
-2. Source Code License.
-
-2.1. The Initial Developer Grant.
-The Initial Developer hereby grants You a world-wide, royalty-free,
-non-exclusive license, subject to third party intellectual property
-claims:
-
-(a) to use, reproduce, modify, display, perform, sublicense and
- distribute the Original Code (or portions thereof) with or without
- Modifications, or as part of a Larger Work; and
-
-(b) under patents now or hereafter owned or controlled by Initial
- Developer, to make, have made, use and sell (``Utilize'') the
- Original Code (or portions thereof), but solely to the extent that
- any such patent is reasonably necessary to enable You to Utilize
- the Original Code (or portions thereof) and not to any greater
- extent that may be necessary to Utilize further Modifications or
- combinations.
-
-2.2. Contributor Grant.
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license, subject to third party intellectual property
-claims:
-
-(a) to use, reproduce, modify, display, perform, sublicense and
- distribute the Modifications created by such Contributor (or
- portions thereof) either on an unmodified basis, with other
- Modifications, as Covered Code or as part of a Larger Work; and
-
-(b) under patents now or hereafter owned or controlled by Contributor,
- to Utilize the Contributor Version (or portions thereof), but
- solely to the extent that any such patent is reasonably necessary
- to enable You to Utilize the Contributor Version (or portions
- thereof), and not to any greater extent that may be necessary to
- Utilize further Modifications or combinations.
-
-3. Distribution Obligations.
-
-3.1. Application of License.
-The Modifications which You contribute are governed by the terms of
-this License, including without limitation Section 2.2. The Source
-Code version of Covered Code may be distributed only under the terms
-of this License, and You must include a copy of this License with
-every copy of the Source Code You distribute. You may not offer or
-impose any terms on any Source Code version that alters or restricts
-the applicable version of this License or the recipients' rights
-hereunder. However, You may include an additional document offering
-the additional rights described in Section 3.5.
-
-3.2. Availability of Source Code.
-Any Modification which You contribute must be made available in Source
-Code form under the terms of this License either on the same media as
-an Executable version or via an accepted Electronic Distribution
-Mechanism to anyone to whom you made an Executable version available;
-and if made available via Electronic Distribution Mechanism, must
-remain available for at least twelve (12) months after the date it
-initially became available, or at least six (6) months after a
-subsequent version of that particular Modification has been made
-available to such recipients. You are responsible for ensuring that
-the Source Code version remains available even if the Electronic
-Distribution Mechanism is maintained by a third party.
-
-3.3. Description of Modifications.
-You must cause all Covered Code to which you contribute to contain a
-file documenting the changes You made to create that Covered Code and
-the date of any change. You must include a prominent statement that
-the Modification is derived, directly or indirectly, from Original
-Code provided by the Initial Developer and including the name of the
-Initial Developer in (a) the Source Code, and (b) in any notice in an
-Executable version or related documentation in which You describe the
-origin or ownership of the Covered Code.
-
-3.4. Intellectual Property Matters
-
-(a) Third Party Claims.
- If You have knowledge that a party claims an intellectual property
- right in particular functionality or code (or its utilization
- under this License), you must include a text file with the source
- code distribution titled ``LEGAL'' which describes the claim and
- the party making the claim in sufficient detail that a recipient
- will know whom to contact. If you obtain such knowledge after You
- make Your Modification available as described in Section 3.2, You
- shall promptly modify the LEGAL file in all copies You make
- available thereafter and shall take other steps (such as notifying
- appropriate mailing lists or newsgroups) reasonably calculated to
- inform those who received the Covered Code that new knowledge has
- been obtained.
-
-(b) Contributor APIs.
- If Your Modification is an application programming interface and
- You own or control patents which are reasonably necessary to
- implement that API, you must also include this information in the
- LEGAL file.
-
-3.5. Required Notices.
-You must duplicate the notice in Exhibit A in each file of the Source
-Code, and this License in any documentation for the Source Code, where
-You describe recipients' rights relating to Covered Code. If You
-created one or more Modification(s), You may add your name as a
-Contributor to the notice described in Exhibit A. If it is not
-possible to put such notice in a particular Source Code file due to
-its structure, then you must include such notice in a location (such
-as a relevant directory file) where a user would be likely to look for
-such a notice. You may choose to offer, and to charge a fee for,
-warranty, support, indemnity or liability obligations to one or more
-recipients of Covered Code. However, You may do so only on Your own
-behalf, and not on behalf of the Initial Developer or any
-Contributor. You must make it absolutely clear than any such warranty,
-support, indemnity or liability obligation is offered by You alone,
-and You hereby agree to indemnify the Initial Developer and every
-Contributor for any liability incurred by the Initial Developer or
-such Contributor as a result of warranty, support, indemnity or
-liability terms You offer.
-
-3.6. Distribution of Executable Versions.
-You may distribute Covered Code in Executable form only if the
-requirements of Section 3.1-3.5 have been met for that Covered Code,
-and if You include a notice stating that the Source Code version of
-the Covered Code is available under the terms of this License,
-including a description of how and where You have fulfilled the
-obligations of Section 3.2. The notice must be conspicuously included
-in any notice in an Executable version, related documentation or
-collateral in which You describe recipients' rights relating to the
-Covered Code. You may distribute the Executable version of Covered
-Code under a license of Your choice, which may contain terms different
-from this License, provided that You are in compliance with the terms
-of this License and that the license for the Executable version does
-not attempt to limit or alter the recipient's rights in the Source
-Code version from the rights set forth in this License. If You
-distribute the Executable version under a different license You must
-make it absolutely clear that any terms which differ from this License
-are offered by You alone, not by the Initial Developer or any
-Contributor. You hereby agree to indemnify the Initial Developer and
-every Contributor for any liability incurred by the Initial Developer
-or such Contributor as a result of any such terms You offer.
-
-3.7. Larger Works.
-You may create a Larger Work by combining Covered Code with other code
-not governed by the terms of this License and distribute the Larger
-Work as a single product. In such a case, You must make sure the
-requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Code due to statute
-or regulation then You must: (a) comply with the terms of this License
-to the maximum extent possible; and (b) describe the limitations and
-the code they affect. Such description must be included in the LEGAL
-file described in Section 3.4 and must be included with all
-distributions of the Source Code. Except to the extent prohibited by
-statute or regulation, such description must be sufficiently detailed
-for a recipient of ordinary skill to be able to understand it.
-
-5. Application of this License.
-
-This License applies to code to which the Initial Developer has
-attached the notice in Exhibit A, and to related Covered Code.
-
-6. CONNECTION TO MOZILLA PUBLIC LICENSE
-
-This Erlang License is a derivative work of the Mozilla Public
-License, Version 1.0. It contains terms which differ from the Mozilla
-Public License, Version 1.0.
-
-7. DISCLAIMER OF WARRANTY.
-
-COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN ``AS IS'' BASIS,
-WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
-DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
-NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
-THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE
-IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER
-CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR
-CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART
-OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER
-EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-This License and the rights granted hereunder will terminate
-automatically if You fail to comply with terms herein and fail to cure
-such breach within 30 days of becoming aware of the breach. All
-sublicenses to the Covered Code which are properly granted shall
-survive any termination of this License. Provisions which, by their
-nature, must remain in effect beyond the termination of this License
-shall survive.
-
-9. DISCLAIMER OF LIABILITY
-Any utilization of Covered Code shall not cause the Initial Developer
-or any Contributor to be liable for any damages (neither direct nor
-indirect).
-
-10. MISCELLANEOUS
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision is held to be unenforceable, such
-provision shall be reformed only to the extent necessary to make it
-enforceable. This License shall be construed by and in accordance with
-the substantive laws of Sweden. Any dispute, controversy or claim
-arising out of or relating to this License, or the breach, termination
-or invalidity thereof, shall be subject to the exclusive jurisdiction
-of Swedish courts, with the Stockholm City Court as the first
-instance.
-
-EXHIBIT A.
-
-``The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved via the world wide web at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
-
-The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-AB. All Rights Reserved.''
diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile
index 26574ed86f..b345e34684 100644
--- a/lib/wx/src/Makefile
+++ b/lib/wx/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index a2681732a8..bedd4e9cca 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -52,10 +53,14 @@
-type enum() :: non_neg_integer(). %% See wx/include/gl.hrl
-type clamp() :: float(). %% 0.0..1.0
-type offset() :: non_neg_integer(). %% Offset in memory block
--type matrix() :: {float(),float(),float(),float(),
+-type matrix12() :: {float(),float(),float(),float(),
+ float(),float(),float(),float(),
+ float(),float(),float(),float()}.
+-type matrix16() :: {float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float()}.
+-type matrix() :: matrix12() | matrix16().
-type mem() :: binary() | tuple(). %% Memory block
-export([clearIndex/1,clearColor/4,clear/1,indexMask/1,colorMask/4,alphaFunc/2,
@@ -4288,14 +4293,14 @@ lighti(Light,Pname,Param) ->
%% @doc
%% See {@link lightf/3}
--spec lightfv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: {float()}.
+-spec lightfv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: tuple().
lightfv(Light,Pname,Params) ->
cast(5207, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link lightf/3}
--spec lightiv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec lightiv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: tuple().
lightiv(Light,Pname,Params) ->
cast(5208, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -4459,14 +4464,14 @@ lightModeli(Pname,Param) ->
%% @doc
%% See {@link lightModelf/2}
--spec lightModelfv(Pname, Params) -> ok when Pname :: enum(),Params :: {float()}.
+-spec lightModelfv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
lightModelfv(Pname,Params) ->
cast(5213, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link lightModelf/2}
--spec lightModeliv(Pname, Params) -> ok when Pname :: enum(),Params :: {integer()}.
+-spec lightModeliv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
lightModeliv(Pname,Params) ->
cast(5214, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -4546,14 +4551,14 @@ materiali(Face,Pname,Param) ->
%% @doc
%% See {@link materialf/3}
--spec materialfv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: {float()}.
+-spec materialfv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: tuple().
materialfv(Face,Pname,Params) ->
cast(5217, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link materialf/3}
--spec materialiv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec materialiv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: tuple().
materialiv(Face,Pname,Params) ->
cast(5218, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -5889,21 +5894,21 @@ texGeni(Coord,Pname,Param) ->
%% @doc
%% See {@link texGend/3}
--spec texGendv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texGendv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: tuple().
texGendv(Coord,Pname,Params) ->
cast(5246, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,0:32,
(<< <<C:?GLdouble>> ||C <- tuple_to_list(Params)>>)/binary>>).
%% @doc
%% See {@link texGend/3}
--spec texGenfv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texGenfv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: tuple().
texGenfv(Coord,Pname,Params) ->
cast(5247, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link texGend/3}
--spec texGeniv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texGeniv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: tuple().
texGeniv(Coord,Pname,Params) ->
cast(5248, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -6122,14 +6127,14 @@ texEnvi(Target,Pname,Param) ->
%% replacement. The default value is `?GL_FALSE'.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml">external</a> documentation.
--spec texEnvfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texEnvfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texEnvfv(Target,Pname,Params) ->
cast(5254, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link texEnvfv/3}
--spec texEnviv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texEnviv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texEnviv(Target,Pname,Params) ->
cast(5255, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -6454,14 +6459,14 @@ texParameteri(Target,Pname,Param) ->
%% @doc
%% See {@link texParameterf/3}
--spec texParameterfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texParameterfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterfv(Target,Pname,Params) ->
cast(5260, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link texParameterf/3}
--spec texParameteriv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texParameteriv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameteriv(Target,Pname,Params) ->
cast(5261, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -7608,14 +7613,14 @@ fogi(Pname,Param) ->
%% @doc
%% See {@link fogf/2}
--spec fogfv(Pname, Params) -> ok when Pname :: enum(),Params :: {float()}.
+-spec fogfv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
fogfv(Pname,Params) ->
cast(5306, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link fogf/2}
--spec fogiv(Pname, Params) -> ok when Pname :: enum(),Params :: {integer()}.
+-spec fogiv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
fogiv(Pname,Params) ->
cast(5307, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -8521,24 +8526,24 @@ convolutionFilter2D(Target,Internalformat,Width,Height,Format,Type,Image) ->
%% image were replicated.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionParameter.xml">external</a> documentation.
--spec convolutionParameterf(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {float()}.
+-spec convolutionParameterf(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
convolutionParameterf(Target,Pname,Params) ->
cast(5339, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @equiv convolutionParameterf(Target,Pname,Params)
--spec convolutionParameterfv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: {float()}}.
+-spec convolutionParameterfv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: tuple()}.
convolutionParameterfv(Target,Pname,{Params}) -> convolutionParameterf(Target,Pname,Params).
%% @doc
%% See {@link convolutionParameterf/3}
--spec convolutionParameteri(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec convolutionParameteri(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
convolutionParameteri(Target,Pname,Params) ->
cast(5340, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @equiv convolutionParameteri(Target,Pname,Params)
--spec convolutionParameteriv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: {integer()}}.
+-spec convolutionParameteriv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: tuple()}.
convolutionParameteriv(Target,Pname,{Params}) -> convolutionParameteri(Target,Pname,Params).
%% @doc Copy pixels into a one-dimensional convolution filter
@@ -9670,7 +9675,7 @@ pointParameterf(Pname,Param) ->
%% @doc
%% See {@link pointParameterf/2}
--spec pointParameterfv(Pname, Params) -> ok when Pname :: enum(),Params :: {float()}.
+-spec pointParameterfv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
pointParameterfv(Pname,Params) ->
cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -9683,7 +9688,7 @@ pointParameteri(Pname,Param) ->
%% @doc
%% See {@link pointParameterf/2}
--spec pointParameteriv(Pname, Params) -> ok when Pname :: enum(),Params :: {integer()}.
+-spec pointParameteriv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
pointParameteriv(Pname,Params) ->
cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -11528,7 +11533,7 @@ linkProgram(Program) ->
%% scanned or parsed at this time; they are simply copied into the specified shader object.
%%
%% 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 :: [string()].
+-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)>>).
@@ -12277,7 +12282,7 @@ bindBufferBase(Target,Index,Buffer) ->
%% and the buffer mode is `?GL_INTERLEAVED_ATTRIBS'.
%%
%% 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 :: [string()],BufferMode :: enum().
+-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>>).
@@ -12595,7 +12600,7 @@ uniform4uiv(Location,Value) ->
%% @doc
%% See {@link texParameterf/3}
--spec texParameterIiv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-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,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -12603,7 +12608,7 @@ texParameterIiv(Target,Pname,Params) ->
%% @doc glTexParameterI
%%
%% 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 :: {integer()}.
+-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,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -12650,21 +12655,21 @@ getTexParameterIuiv(Target,Pname) ->
%% and the buffer being cleared is defined. However, this is not an error.
%%
%% 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 :: {integer()}.
+-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,
(<< <<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 :: {integer()}.
+-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,
(<< <<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 :: {float()}.
+-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,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
@@ -13218,7 +13223,7 @@ createShaderObjectARB(ShaderType) ->
%% @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 :: [string()].
+-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)>>).
@@ -13926,7 +13931,7 @@ isVertexArray(Array) ->
%% If an error occurs, nothing is written to `UniformIndices' .
%%
%% 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 :: [string()].
+-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)>>).
@@ -14457,7 +14462,7 @@ deleteNamedStringARB(Name) ->
%% @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 :: [string()].
+-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)>>).
@@ -15616,7 +15621,7 @@ activeShaderProgram(Pipeline,Program) ->
%% @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 :: [string()].
+-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)>>).
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index 5b0c0ed393..5faba48930 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
@@ -50,10 +51,14 @@
-define(GLint64,64/native-signed).
-type vertex() :: {float(), float(), float()}.
-type enum() :: non_neg_integer(). %% See wx/include/gl.hrl or glu.hrl
--type matrix() :: {float(),float(),float(),float(),
+-type matrix12() :: {float(),float(),float(),float(),
+ float(),float(),float(),float(),
+ float(),float(),float(),float()}.
+-type matrix16() :: {float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float()}.
+-type matrix() :: matrix12() | matrix16().
-type mem() :: binary() | tuple(). %% Memory block
-export([tesselate/2,build1DMipmapLevels/9,build1DMipmaps/6,build2DMipmapLevels/10,
diff --git a/lib/wx/src/gen/wxAcceleratorEntry.erl b/lib/wx/src/gen/wxAcceleratorEntry.erl
index a75fd8d8c0..b4ad3adcca 100644
--- a/lib/wx/src/gen/wxAcceleratorEntry.erl
+++ b/lib/wx/src/gen/wxAcceleratorEntry.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAcceleratorTable.erl b/lib/wx/src/gen/wxAcceleratorTable.erl
index 2832d34e3a..3edfee7709 100644
--- a/lib/wx/src/gen/wxAcceleratorTable.erl
+++ b/lib/wx/src/gen/wxAcceleratorTable.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxActivateEvent.erl b/lib/wx/src/gen/wxActivateEvent.erl
index dc03866027..157b25f05a 100644
--- a/lib/wx/src/gen/wxActivateEvent.erl
+++ b/lib/wx/src/gen/wxActivateEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxArtProvider.erl b/lib/wx/src/gen/wxArtProvider.erl
index f1229c7455..7dc170beff 100644
--- a/lib/wx/src/gen/wxArtProvider.erl
+++ b/lib/wx/src/gen/wxArtProvider.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiDockArt.erl b/lib/wx/src/gen/wxAuiDockArt.erl
index 29616b0943..4149b1d424 100644
--- a/lib/wx/src/gen/wxAuiDockArt.erl
+++ b/lib/wx/src/gen/wxAuiDockArt.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -24,7 +25,7 @@
-module(wxAuiDockArt).
-include("wxe.hrl").
--export([]).
+-export([getColour/2,getFont/2,getMetric/2,setColour/3,setFont/3,setMetric/3]).
%% inherited exports
-export([parent_class/1]).
@@ -34,3 +35,58 @@
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-type wxAuiDockArt() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauidockart.html#wxauidockartgetcolour">external documentation</a>.
+-spec getColour(This, Id) -> wx:wx_colour4() when
+ This::wxAuiDockArt(), Id::integer().
+getColour(#wx_ref{type=ThisT,ref=ThisRef},Id)
+ when is_integer(Id) ->
+ ?CLASS(ThisT,wxAuiDockArt),
+ wxe_util:call(?wxAuiDockArt_GetColour,
+ <<ThisRef:32/?UI,Id:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauidockart.html#wxauidockartgetfont">external documentation</a>.
+-spec getFont(This, Id) -> wxFont:wxFont() when
+ This::wxAuiDockArt(), Id::integer().
+getFont(#wx_ref{type=ThisT,ref=ThisRef},Id)
+ when is_integer(Id) ->
+ ?CLASS(ThisT,wxAuiDockArt),
+ wxe_util:call(?wxAuiDockArt_GetFont,
+ <<ThisRef:32/?UI,Id:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauidockart.html#wxauidockartgetmetric">external documentation</a>.
+-spec getMetric(This, Id) -> integer() when
+ This::wxAuiDockArt(), Id::integer().
+getMetric(#wx_ref{type=ThisT,ref=ThisRef},Id)
+ when is_integer(Id) ->
+ ?CLASS(ThisT,wxAuiDockArt),
+ wxe_util:call(?wxAuiDockArt_GetMetric,
+ <<ThisRef:32/?UI,Id:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauidockart.html#wxauidockartsetcolour">external documentation</a>.
+-spec setColour(This, Id, Colour) -> ok when
+ This::wxAuiDockArt(), Id::integer(), Colour::wx:wx_colour().
+setColour(#wx_ref{type=ThisT,ref=ThisRef},Id,Colour)
+ when is_integer(Id),tuple_size(Colour) =:= 3; tuple_size(Colour) =:= 4 ->
+ ?CLASS(ThisT,wxAuiDockArt),
+ wxe_util:cast(?wxAuiDockArt_SetColour,
+ <<ThisRef:32/?UI,Id:32/?UI,(wxe_util:colour_bin(Colour)):16/binary>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauidockart.html#wxauidockartsetfont">external documentation</a>.
+-spec setFont(This, Id, Font) -> ok when
+ This::wxAuiDockArt(), Id::integer(), Font::wxFont:wxFont().
+setFont(#wx_ref{type=ThisT,ref=ThisRef},Id,#wx_ref{type=FontT,ref=FontRef})
+ when is_integer(Id) ->
+ ?CLASS(ThisT,wxAuiDockArt),
+ ?CLASS(FontT,wxFont),
+ wxe_util:cast(?wxAuiDockArt_SetFont,
+ <<ThisRef:32/?UI,Id:32/?UI,FontRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauidockart.html#wxauidockartsetmetric">external documentation</a>.
+-spec setMetric(This, Id, New_val) -> ok when
+ This::wxAuiDockArt(), Id::integer(), New_val::integer().
+setMetric(#wx_ref{type=ThisT,ref=ThisRef},Id,New_val)
+ when is_integer(Id),is_integer(New_val) ->
+ ?CLASS(ThisT,wxAuiDockArt),
+ wxe_util:cast(?wxAuiDockArt_SetMetric,
+ <<ThisRef:32/?UI,Id:32/?UI,New_val:32/?UI>>).
+
diff --git a/lib/wx/src/gen/wxAuiManager.erl b/lib/wx/src/gen/wxAuiManager.erl
index 45da283452..bf22e3091d 100644
--- a/lib/wx/src/gen/wxAuiManager.erl
+++ b/lib/wx/src/gen/wxAuiManager.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -119,7 +120,7 @@ detachPane(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef})
<<ThisRef:32/?UI,WindowRef:32/?UI>>).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauimanager.html#wxauimanagergetallpanes">external documentation</a>.
--spec getAllPanes(This) -> wx:wx_object() when
+-spec getAllPanes(This) -> [wxAuiPaneInfo:wxAuiPaneInfo()] when
This::wxAuiManager().
getAllPanes(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxAuiManager),
diff --git a/lib/wx/src/gen/wxAuiManagerEvent.erl b/lib/wx/src/gen/wxAuiManagerEvent.erl
index 2810a9a077..88e4433f24 100644
--- a/lib/wx/src/gen/wxAuiManagerEvent.erl
+++ b/lib/wx/src/gen/wxAuiManagerEvent.erl
@@ -1,25 +1,26 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauimanagerevent.html">wxAuiManagerEvent</a>.
%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt>
-%% <dd><em>aui_pane_button</em>, <em>aui_pane_close</em>, <em>aui_pane_maximize</em>, <em>aui_pane_restore</em>, <em>aui_render</em>, <em>aui_find_manager</em></dd></dl>
+%% <dd><em>aui_pane_button</em>, <em>aui_pane_close</em>, <em>aui_pane_maximize</em>, <em>aui_pane_restore</em>, <em>aui_pane_activated</em>, <em>aui_render</em>, <em>aui_find_manager</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxAuiManager(). #wxAuiManager{}} event record type.
%%
%% <p>This class is derived (and can use functions) from:
diff --git a/lib/wx/src/gen/wxAuiNotebook.erl b/lib/wx/src/gen/wxAuiNotebook.erl
index fcf70bbc9f..7ec1acb26d 100644
--- a/lib/wx/src/gen/wxAuiNotebook.erl
+++ b/lib/wx/src/gen/wxAuiNotebook.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -36,10 +37,10 @@
setTabCtrlHeight/2,setUniformBitmapSize/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -51,23 +52,24 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setForegroundColour/2,
setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,
setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2,
setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,
setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -348,6 +350,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxAuiNotebookEvent.erl b/lib/wx/src/gen/wxAuiNotebookEvent.erl
index 4578674401..33509e3269 100644
--- a/lib/wx/src/gen/wxAuiNotebookEvent.erl
+++ b/lib/wx/src/gen/wxAuiNotebookEvent.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiPaneInfo.erl b/lib/wx/src/gen/wxAuiPaneInfo.erl
index f4148ed7c3..1f15e9cd39 100644
--- a/lib/wx/src/gen/wxAuiPaneInfo.erl
+++ b/lib/wx/src/gen/wxAuiPaneInfo.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -29,17 +30,19 @@
closeButton/2,defaultPane/1,destroy/1,destroyOnClose/1,destroyOnClose/2,
direction/2,dock/1,dockable/1,dockable/2,fixed/1,float/1,floatable/1,
floatable/2,floatingPosition/2,floatingPosition/3,floatingSize/2,
- floatingSize/3,gripper/1,gripper/2,gripperTop/1,gripperTop/2,hasBorder/1,
- hasCaption/1,hasCloseButton/1,hasFlag/2,hasGripper/1,hasGripperTop/1,
- hasMaximizeButton/1,hasMinimizeButton/1,hasPinButton/1,hide/1,isBottomDockable/1,
- isDocked/1,isFixed/1,isFloatable/1,isFloating/1,isLeftDockable/1,isMovable/1,
- isOk/1,isResizable/1,isRightDockable/1,isShown/1,isToolbar/1,isTopDockable/1,
- layer/2,left/1,leftDockable/1,leftDockable/2,maxSize/2,maxSize/3,maximizeButton/1,
- maximizeButton/2,minSize/2,minSize/3,minimizeButton/1,minimizeButton/2,
- movable/1,movable/2,name/2,new/0,new/1,paneBorder/1,paneBorder/2,pinButton/1,
- pinButton/2,position/2,resizable/1,resizable/2,right/1,rightDockable/1,
- rightDockable/2,row/2,safeSet/2,setFlag/3,show/1,show/2,toolbarPane/1,
- top/1,topDockable/1,topDockable/2,window/2]).
+ floatingSize/3,getDirection/1,getFloatingPosition/1,getFloatingSize/1,
+ getFrame/1,getLayer/1,getPosition/1,getRow/1,getWindow/1,gripper/1,
+ gripper/2,gripperTop/1,gripperTop/2,hasBorder/1,hasCaption/1,hasCloseButton/1,
+ hasFlag/2,hasGripper/1,hasGripperTop/1,hasMaximizeButton/1,hasMinimizeButton/1,
+ hasPinButton/1,hide/1,isBottomDockable/1,isDocked/1,isFixed/1,isFloatable/1,
+ isFloating/1,isLeftDockable/1,isMovable/1,isOk/1,isResizable/1,isRightDockable/1,
+ isShown/1,isToolbar/1,isTopDockable/1,layer/2,left/1,leftDockable/1,
+ leftDockable/2,maxSize/2,maxSize/3,maximizeButton/1,maximizeButton/2,
+ minSize/2,minSize/3,minimizeButton/1,minimizeButton/2,movable/1,movable/2,
+ name/2,new/0,new/1,paneBorder/1,paneBorder/2,pinButton/1,pinButton/2,
+ position/2,resizable/1,resizable/2,right/1,rightDockable/1,rightDockable/2,
+ row/2,safeSet/2,setFlag/3,show/1,show/2,toolbarPane/1,top/1,topDockable/1,
+ topDockable/2,window/2]).
%% inherited exports
-export([parent_class/1]).
@@ -887,6 +890,70 @@ window(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WT,ref=WRef}) ->
wxe_util:call(?wxAuiPaneInfo_Window,
<<ThisRef:32/?UI,WRef:32/?UI>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetwindow">external documentation</a>.
+-spec getWindow(This) -> wxWindow:wxWindow() when
+ This::wxAuiPaneInfo().
+getWindow(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetWindow,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetframe">external documentation</a>.
+-spec getFrame(This) -> wxFrame:wxFrame() when
+ This::wxAuiPaneInfo().
+getFrame(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetFrame,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetdirection">external documentation</a>.
+-spec getDirection(This) -> integer() when
+ This::wxAuiPaneInfo().
+getDirection(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetDirection,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetlayer">external documentation</a>.
+-spec getLayer(This) -> integer() when
+ This::wxAuiPaneInfo().
+getLayer(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetLayer,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetrow">external documentation</a>.
+-spec getRow(This) -> integer() when
+ This::wxAuiPaneInfo().
+getRow(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetRow,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetposition">external documentation</a>.
+-spec getPosition(This) -> integer() when
+ This::wxAuiPaneInfo().
+getPosition(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetPosition,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetfloatingposition">external documentation</a>.
+-spec getFloatingPosition(This) -> {X::integer(), Y::integer()} when
+ This::wxAuiPaneInfo().
+getFloatingPosition(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetFloatingPosition,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauipaneinfo.html#wxauipaneinfogetfloatingsize">external documentation</a>.
+-spec getFloatingSize(This) -> {W::integer(), H::integer()} when
+ This::wxAuiPaneInfo().
+getFloatingSize(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxAuiPaneInfo),
+ wxe_util:call(?wxAuiPaneInfo_GetFloatingSize,
+ <<ThisRef:32/?UI>>).
+
%% @doc Destroys this object, do not use object again
-spec destroy(This::wxAuiPaneInfo()) -> ok.
destroy(Obj=#wx_ref{type=Type}) ->
diff --git a/lib/wx/src/gen/wxAuiSimpleTabArt.erl b/lib/wx/src/gen/wxAuiSimpleTabArt.erl
new file mode 100644
index 0000000000..57d12e2eb4
--- /dev/null
+++ b/lib/wx/src/gen/wxAuiSimpleTabArt.erl
@@ -0,0 +1,67 @@
+%%
+%% %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.
+%% 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%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauisimpletabart.html">wxAuiSimpleTabArt</a>.
+%% <p>This class is derived (and can use functions) from:
+%% <br />{@link wxAuiTabArt}
+%% </p>
+%% @type wxAuiSimpleTabArt(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxAuiSimpleTabArt).
+-include("wxe.hrl").
+-export([destroy/1,new/0]).
+
+%% inherited exports
+-export([parent_class/1,setActiveColour/2,setColour/2,setFlags/2,setMeasuringFont/2,
+ setNormalFont/2,setSelectedFont/2]).
+
+-export_type([wxAuiSimpleTabArt/0]).
+%% @hidden
+parent_class(wxAuiTabArt) -> true;
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxAuiSimpleTabArt() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauisimpletabart.html#wxauisimpletabartwxauisimpletabart">external documentation</a>.
+-spec new() -> wxAuiSimpleTabArt().
+new() ->
+ wxe_util:construct(?wxAuiSimpleTabArt_new,
+ <<>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxAuiSimpleTabArt()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxAuiSimpleTabArt),
+ wxe_util:destroy(?wxAuiSimpleTabArt_destroy,Obj),
+ ok.
+ %% From wxAuiTabArt
+%% @hidden
+setActiveColour(This,Colour) -> wxAuiTabArt:setActiveColour(This,Colour).
+%% @hidden
+setColour(This,Colour) -> wxAuiTabArt:setColour(This,Colour).
+%% @hidden
+setSelectedFont(This,Font) -> wxAuiTabArt:setSelectedFont(This,Font).
+%% @hidden
+setNormalFont(This,Font) -> wxAuiTabArt:setNormalFont(This,Font).
+%% @hidden
+setMeasuringFont(This,Font) -> wxAuiTabArt:setMeasuringFont(This,Font).
+%% @hidden
+setFlags(This,Flags) -> wxAuiTabArt:setFlags(This,Flags).
diff --git a/lib/wx/src/gen/wxAuiTabArt.erl b/lib/wx/src/gen/wxAuiTabArt.erl
index b8f64191d1..80924c0269 100644
--- a/lib/wx/src/gen/wxAuiTabArt.erl
+++ b/lib/wx/src/gen/wxAuiTabArt.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -24,7 +25,8 @@
-module(wxAuiTabArt).
-include("wxe.hrl").
--export([]).
+-export([setActiveColour/2,setColour/2,setFlags/2,setMeasuringFont/2,setNormalFont/2,
+ setSelectedFont/2]).
%% inherited exports
-export([parent_class/1]).
@@ -34,3 +36,57 @@
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-type wxAuiTabArt() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauitabart.html#wxauitabartsetflags">external documentation</a>.
+-spec setFlags(This, Flags) -> ok when
+ This::wxAuiTabArt(), Flags::integer().
+setFlags(#wx_ref{type=ThisT,ref=ThisRef},Flags)
+ when is_integer(Flags) ->
+ ?CLASS(ThisT,wxAuiTabArt),
+ wxe_util:cast(?wxAuiTabArt_SetFlags,
+ <<ThisRef:32/?UI,Flags:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauitabart.html#wxauitabartsetmeasuringfont">external documentation</a>.
+-spec setMeasuringFont(This, Font) -> ok when
+ This::wxAuiTabArt(), Font::wxFont:wxFont().
+setMeasuringFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FontT,ref=FontRef}) ->
+ ?CLASS(ThisT,wxAuiTabArt),
+ ?CLASS(FontT,wxFont),
+ wxe_util:cast(?wxAuiTabArt_SetMeasuringFont,
+ <<ThisRef:32/?UI,FontRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauitabart.html#wxauitabartsetnormalfont">external documentation</a>.
+-spec setNormalFont(This, Font) -> ok when
+ This::wxAuiTabArt(), Font::wxFont:wxFont().
+setNormalFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FontT,ref=FontRef}) ->
+ ?CLASS(ThisT,wxAuiTabArt),
+ ?CLASS(FontT,wxFont),
+ wxe_util:cast(?wxAuiTabArt_SetNormalFont,
+ <<ThisRef:32/?UI,FontRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauitabart.html#wxauitabartsetselectedfont">external documentation</a>.
+-spec setSelectedFont(This, Font) -> ok when
+ This::wxAuiTabArt(), Font::wxFont:wxFont().
+setSelectedFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FontT,ref=FontRef}) ->
+ ?CLASS(ThisT,wxAuiTabArt),
+ ?CLASS(FontT,wxFont),
+ wxe_util:cast(?wxAuiTabArt_SetSelectedFont,
+ <<ThisRef:32/?UI,FontRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauitabart.html#wxauitabartsetcolour">external documentation</a>.
+-spec setColour(This, Colour) -> ok when
+ This::wxAuiTabArt(), Colour::wx:wx_colour().
+setColour(#wx_ref{type=ThisT,ref=ThisRef},Colour)
+ when tuple_size(Colour) =:= 3; tuple_size(Colour) =:= 4 ->
+ ?CLASS(ThisT,wxAuiTabArt),
+ wxe_util:cast(?wxAuiTabArt_SetColour,
+ <<ThisRef:32/?UI,(wxe_util:colour_bin(Colour)):16/binary>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauitabart.html#wxauitabartsetactivecolour">external documentation</a>.
+-spec setActiveColour(This, Colour) -> ok when
+ This::wxAuiTabArt(), Colour::wx:wx_colour().
+setActiveColour(#wx_ref{type=ThisT,ref=ThisRef},Colour)
+ when tuple_size(Colour) =:= 3; tuple_size(Colour) =:= 4 ->
+ ?CLASS(ThisT,wxAuiTabArt),
+ wxe_util:cast(?wxAuiTabArt_SetActiveColour,
+ <<ThisRef:32/?UI,(wxe_util:colour_bin(Colour)):16/binary>>).
+
diff --git a/lib/wx/src/gen/wxBitmap.erl b/lib/wx/src/gen/wxBitmap.erl
index cab56d99f6..988dc5b1af 100644
--- a/lib/wx/src/gen/wxBitmap.erl
+++ b/lib/wx/src/gen/wxBitmap.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBitmapButton.erl b/lib/wx/src/gen/wxBitmapButton.erl
index 326c8044f7..642828b0b0 100644
--- a/lib/wx/src/gen/wxBitmapButton.erl
+++ b/lib/wx/src/gen/wxBitmapButton.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
setBitmapLabel/2,setBitmapSelected/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,24 +51,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDefault/1,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDefault/1,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -228,6 +230,14 @@ setDefault(This) -> wxButton:setDefault(This).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxBitmapDataObject.erl b/lib/wx/src/gen/wxBitmapDataObject.erl
index 1af65960ca..9fcbb4df41 100644
--- a/lib/wx/src/gen/wxBitmapDataObject.erl
+++ b/lib/wx/src/gen/wxBitmapDataObject.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBoxSizer.erl b/lib/wx/src/gen/wxBoxSizer.erl
index a09908b373..04f26f95d9 100644
--- a/lib/wx/src/gen/wxBoxSizer.erl
+++ b/lib/wx/src/gen/wxBoxSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBrush.erl b/lib/wx/src/gen/wxBrush.erl
index 8657b57348..3d6112a351 100644
--- a/lib/wx/src/gen/wxBrush.erl
+++ b/lib/wx/src/gen/wxBrush.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBufferedDC.erl b/lib/wx/src/gen/wxBufferedDC.erl
index e2504bbaaa..5959a3c3ab 100644
--- a/lib/wx/src/gen/wxBufferedDC.erl
+++ b/lib/wx/src/gen/wxBufferedDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBufferedPaintDC.erl b/lib/wx/src/gen/wxBufferedPaintDC.erl
index c3fa80703c..a45ec6540b 100644
--- a/lib/wx/src/gen/wxBufferedPaintDC.erl
+++ b/lib/wx/src/gen/wxBufferedPaintDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxButton.erl b/lib/wx/src/gen/wxButton.erl
index c026b23d6f..c94303bbea 100644
--- a/lib/wx/src/gen/wxButton.erl
+++ b/lib/wx/src/gen/wxButton.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
setLabel/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -178,6 +180,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxCalendarCtrl.erl b/lib/wx/src/gen/wxCalendarCtrl.erl
index 3a9fc4051a..1d4baeed08 100644
--- a/lib/wx/src/gen/wxCalendarCtrl.erl
+++ b/lib/wx/src/gen/wxCalendarCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -37,10 +38,10 @@
setHighlightColours/3,setHoliday/2,setHolidayColours/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -52,24 +53,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -362,6 +364,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxCalendarDateAttr.erl b/lib/wx/src/gen/wxCalendarDateAttr.erl
index 4138d95070..4fde4ddbda 100644
--- a/lib/wx/src/gen/wxCalendarDateAttr.erl
+++ b/lib/wx/src/gen/wxCalendarDateAttr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCalendarEvent.erl b/lib/wx/src/gen/wxCalendarEvent.erl
index d59f7256fa..d0573e584f 100644
--- a/lib/wx/src/gen/wxCalendarEvent.erl
+++ b/lib/wx/src/gen/wxCalendarEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCaret.erl b/lib/wx/src/gen/wxCaret.erl
index e2b503e975..0e648e4e56 100644
--- a/lib/wx/src/gen/wxCaret.erl
+++ b/lib/wx/src/gen/wxCaret.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCheckBox.erl b/lib/wx/src/gen/wxCheckBox.erl
index 85797059f7..2cea4d04b4 100644
--- a/lib/wx/src/gen/wxCheckBox.erl
+++ b/lib/wx/src/gen/wxCheckBox.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,10 +35,10 @@
setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,24 +50,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -215,6 +217,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxCheckListBox.erl b/lib/wx/src/gen/wxCheckListBox.erl
index f90b610eb1..f6013e4863 100644
--- a/lib/wx/src/gen/wxCheckListBox.erl
+++ b/lib/wx/src/gen/wxCheckListBox.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,46 +35,48 @@
-export([check/2,check/3,destroy/1,isChecked/2,new/0,new/2,new/3]).
%% inherited exports
--export([append/2,append/3,appendStrings/2,cacheBestSize/2,captureMouse/1,center/1,
- center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
- centreOnParent/2,clear/1,clearBackground/1,clientToScreen/2,clientToScreen/3,
- close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
- delete/2,deselect/2,destroyChildren/1,disable/1,disconnect/1,disconnect/2,
- disconnect/3,enable/1,enable/2,findString/2,findString/3,findWindow/2,
- fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
- getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
- getChildren/1,getClientData/2,getClientSize/1,getContainingSizer/1,
- getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,
- getFont/1,getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSelection/1,getSelections/1,
- getSize/1,getSizer/1,getString/2,getStringSelection/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,hitTest/2,inheritAttributes/1,initDialog/1,insert/3,insert/4,
- insertItems/3,invalidateBestSize/1,isEmpty/1,isEnabled/1,isExposed/2,
- isExposed/3,isExposed/5,isRetained/1,isSelected/2,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- select/2,set/2,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientData/3,setClientSize/2,setClientSize/3,
- setContainingSizer/2,setCursor/2,setDropTarget/2,setExtraStyle/2,
- setFirstItem/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,
- setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,
- setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setSelection/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setString/3,setStringSelection/2,setThemeEnabled/2,setToolTip/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+-export([append/2,append/3,appendStrings/2,cacheBestSize/2,canSetTransparent/1,
+ captureMouse/1,center/1,center/2,centerOnParent/1,centerOnParent/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
+ clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
+ convertDialogToPixels/2,convertPixelsToDialog/2,delete/2,deselect/2,
+ destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
+ enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientData/2,getClientSize/1,getContainingSizer/1,getCount/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSelection/1,getSelections/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
+ getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,hitTest/2,inheritAttributes/1,initDialog/1,
+ insert/3,insert/4,insertItems/3,invalidateBestSize/1,isDoubleBuffered/1,
+ isEmpty/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,
+ isSelected/2,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
+ makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,select/2,set/2,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientData/3,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFirstItem/2,
+ setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSelection/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,
+ setStringSelection/2,setThemeEnabled/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxCheckListBox/0]).
%% @hidden
@@ -219,6 +222,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxChildFocusEvent.erl b/lib/wx/src/gen/wxChildFocusEvent.erl
index 75a16b4dbe..d97c4b3565 100644
--- a/lib/wx/src/gen/wxChildFocusEvent.erl
+++ b/lib/wx/src/gen/wxChildFocusEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxChoice.erl b/lib/wx/src/gen/wxChoice.erl
index 28a5fe08a3..73867d6597 100644
--- a/lib/wx/src/gen/wxChoice.erl
+++ b/lib/wx/src/gen/wxChoice.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,45 +35,47 @@
setColumns/2]).
%% inherited exports
--export([append/2,append/3,appendStrings/2,cacheBestSize/2,captureMouse/1,center/1,
- center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
- centreOnParent/2,clear/1,clearBackground/1,clientToScreen/2,clientToScreen/3,
- close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
- destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
- freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
- getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
- getClientData/2,getClientSize/1,getContainingSizer/1,getCount/1,getCursor/1,
- getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+-export([append/2,append/3,appendStrings/2,cacheBestSize/2,canSetTransparent/1,
+ captureMouse/1,center/1,center/2,centerOnParent/1,centerOnParent/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
+ clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
+ convertDialogToPixels/2,convertPixelsToDialog/2,destroyChildren/1,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
+ findString/2,findString/3,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientData/2,getClientSize/1,
+ getContainingSizer/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
+ getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
+ getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
getSelection/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- insert/3,insert/4,invalidateBestSize/1,isEmpty/1,isEnabled/1,isExposed/2,
- isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
- moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- select/2,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientData/3,setClientSize/2,setClientSize/3,
- setContainingSizer/2,setCursor/2,setDropTarget/2,setExtraStyle/2,
- setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setSelection/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,
- setStringSelection/2,setThemeEnabled/2,setToolTip/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ insert/3,insert/4,invalidateBestSize/1,isDoubleBuffered/1,isEmpty/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientData/3,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSelection/2,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
+ setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
+ setSizerAndFit/3,setString/3,setStringSelection/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxChoice/0]).
%% @hidden
@@ -234,6 +237,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxChoicebook.erl b/lib/wx/src/gen/wxChoicebook.erl
index 9babfc1a60..37a44a813a 100644
--- a/lib/wx/src/gen/wxChoicebook.erl
+++ b/lib/wx/src/gen/wxChoicebook.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -37,10 +38,10 @@
setPageSize/2,setPageText/3,setSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -52,24 +53,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -382,6 +384,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxClientDC.erl b/lib/wx/src/gen/wxClientDC.erl
index ae16196774..35ad2cc16b 100644
--- a/lib/wx/src/gen/wxClientDC.erl
+++ b/lib/wx/src/gen/wxClientDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxClipboard.erl b/lib/wx/src/gen/wxClipboard.erl
index 7785915c3b..71bc43a791 100644
--- a/lib/wx/src/gen/wxClipboard.erl
+++ b/lib/wx/src/gen/wxClipboard.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxClipboardTextEvent.erl b/lib/wx/src/gen/wxClipboardTextEvent.erl
index 1f551b7d83..659419b73f 100644
--- a/lib/wx/src/gen/wxClipboardTextEvent.erl
+++ b/lib/wx/src/gen/wxClipboardTextEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCloseEvent.erl b/lib/wx/src/gen/wxCloseEvent.erl
index 1aa5d57210..2b2a927fc1 100644
--- a/lib/wx/src/gen/wxCloseEvent.erl
+++ b/lib/wx/src/gen/wxCloseEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxColourData.erl b/lib/wx/src/gen/wxColourData.erl
index 1ec3c3f89d..16569cd490 100644
--- a/lib/wx/src/gen/wxColourData.erl
+++ b/lib/wx/src/gen/wxColourData.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxColourDialog.erl b/lib/wx/src/gen/wxColourDialog.erl
index ef792696e1..15eee30727 100644
--- a/lib/wx/src/gen/wxColourDialog.erl
+++ b/lib/wx/src/gen/wxColourDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([create/2,create/3,destroy/1,getColourData/1,new/0,new/1,new/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -221,6 +223,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxColourPickerCtrl.erl b/lib/wx/src/gen/wxColourPickerCtrl.erl
index 654e8a5055..486441c005 100644
--- a/lib/wx/src/gen/wxColourPickerCtrl.erl
+++ b/lib/wx/src/gen/wxColourPickerCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
-export([create/3,create/4,destroy/1,getColour/1,new/0,new/2,new/3,setColour/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,30 +50,31 @@
getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,isRetained/1,
- isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
- lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,setPickerCtrlGrowable/2,
- setPickerCtrlProportion/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,
- setScrollbar/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTextCtrlGrowable/1,setTextCtrlGrowable/2,setTextCtrlProportion/2,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
+ isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
+ lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
+ moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,
+ setPickerCtrlGrowable/2,setPickerCtrlProportion/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTextCtrlGrowable/1,
+ setTextCtrlGrowable/2,setTextCtrlProportion/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxColourPickerCtrl/0]).
%% @hidden
@@ -219,6 +221,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxColourPickerEvent.erl b/lib/wx/src/gen/wxColourPickerEvent.erl
index 2b0e7df681..933dd1ffae 100644
--- a/lib/wx/src/gen/wxColourPickerEvent.erl
+++ b/lib/wx/src/gen/wxColourPickerEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxComboBox.erl b/lib/wx/src/gen/wxComboBox.erl
index d41d3e1ca3..37d6e71605 100644
--- a/lib/wx/src/gen/wxComboBox.erl
+++ b/lib/wx/src/gen/wxComboBox.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -36,45 +37,47 @@
setSelection/2,setSelection/3,setValue/2,undo/1]).
%% inherited exports
--export([append/2,append/3,appendStrings/2,cacheBestSize/2,captureMouse/1,center/1,
- center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
- centreOnParent/2,clear/1,clearBackground/1,clientToScreen/2,clientToScreen/3,
- close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
- delete/2,destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
- freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
- getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
- getClientData/2,getClientSize/1,getContainingSizer/1,getCount/1,getCursor/1,
- getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+-export([append/2,append/3,appendStrings/2,cacheBestSize/2,canSetTransparent/1,
+ captureMouse/1,center/1,center/2,centerOnParent/1,centerOnParent/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
+ clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
+ convertDialogToPixels/2,convertPixelsToDialog/2,delete/2,destroyChildren/1,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
+ findString/2,findString/3,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientData/2,getClientSize/1,
+ getContainingSizer/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
+ getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
+ getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
getSelection/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- insert/3,insert/4,invalidateBestSize/1,isEmpty/1,isEnabled/1,isExposed/2,
- isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
- moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- select/2,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientData/3,setClientSize/2,setClientSize/3,
- setContainingSizer/2,setCursor/2,setDropTarget/2,setExtraStyle/2,
- setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,setStringSelection/2,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ insert/3,insert/4,invalidateBestSize/1,isDoubleBuffered/1,isEmpty/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientData/3,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setString/3,setStringSelection/2,setThemeEnabled/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxComboBox/0]).
%% @hidden
@@ -369,6 +372,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxCommandEvent.erl b/lib/wx/src/gen/wxCommandEvent.erl
index c0bcf97231..acd0d9e2d9 100644
--- a/lib/wx/src/gen/wxCommandEvent.erl
+++ b/lib/wx/src/gen/wxCommandEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxContextMenuEvent.erl b/lib/wx/src/gen/wxContextMenuEvent.erl
index ff345bb386..4e0729922b 100644
--- a/lib/wx/src/gen/wxContextMenuEvent.erl
+++ b/lib/wx/src/gen/wxContextMenuEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxControl.erl b/lib/wx/src/gen/wxControl.erl
index 7e4f0c59ce..f84ec34b02 100644
--- a/lib/wx/src/gen/wxControl.erl
+++ b/lib/wx/src/gen/wxControl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -31,10 +32,10 @@
-export([getLabel/1,setLabel/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -46,24 +47,25 @@
getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -95,6 +97,14 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxControlWithItems.erl b/lib/wx/src/gen/wxControlWithItems.erl
index 95bd573bdf..d52c7917a2 100644
--- a/lib/wx/src/gen/wxControlWithItems.erl
+++ b/lib/wx/src/gen/wxControlWithItems.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
setString/3,setStringSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,24 +51,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -277,6 +279,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxCursor.erl b/lib/wx/src/gen/wxCursor.erl
index abdde79f71..ee5fec7d4a 100644
--- a/lib/wx/src/gen/wxCursor.erl
+++ b/lib/wx/src/gen/wxCursor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDC.erl b/lib/wx/src/gen/wxDC.erl
index 2a7717b3c3..dad4126493 100644
--- a/lib/wx/src/gen/wxDC.erl
+++ b/lib/wx/src/gen/wxDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDCOverlay.erl b/lib/wx/src/gen/wxDCOverlay.erl
new file mode 100644
index 0000000000..f98e310ba6
--- /dev/null
+++ b/lib/wx/src/gen/wxDCOverlay.erl
@@ -0,0 +1,70 @@
+%%
+%% %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.
+%% 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%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html">wxDCOverlay</a>.
+%% @type wxDCOverlay(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxDCOverlay).
+-include("wxe.hrl").
+-export([clear/1,destroy/1,new/2,new/6]).
+
+%% inherited exports
+-export([parent_class/1]).
+
+-export_type([wxDCOverlay/0]).
+%% @hidden
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxDCOverlay() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html#wxdcoverlaywxdcoverlay">external documentation</a>.
+-spec new(Overlay, Dc) -> wxDCOverlay() when
+ Overlay::wxOverlay:wxOverlay(), Dc::wxWindowDC:wxWindowDC().
+new(#wx_ref{type=OverlayT,ref=OverlayRef},#wx_ref{type=DcT,ref=DcRef}) ->
+ ?CLASS(OverlayT,wxOverlay),
+ ?CLASS(DcT,wxWindowDC),
+ wxe_util:construct(?wxDCOverlay_new_2,
+ <<OverlayRef:32/?UI,DcRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html#wxdcoverlaywxdcoverlay">external documentation</a>.
+-spec new(Overlay, Dc, X, Y, Width, Height) -> wxDCOverlay() when
+ Overlay::wxOverlay:wxOverlay(), Dc::wxWindowDC:wxWindowDC(), X::integer(), Y::integer(), Width::integer(), Height::integer().
+new(#wx_ref{type=OverlayT,ref=OverlayRef},#wx_ref{type=DcT,ref=DcRef},X,Y,Width,Height)
+ when is_integer(X),is_integer(Y),is_integer(Width),is_integer(Height) ->
+ ?CLASS(OverlayT,wxOverlay),
+ ?CLASS(DcT,wxWindowDC),
+ wxe_util:construct(?wxDCOverlay_new_6,
+ <<OverlayRef:32/?UI,DcRef:32/?UI,X:32/?UI,Y:32/?UI,Width:32/?UI,Height:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html#wxdcoverlayclear">external documentation</a>.
+-spec clear(This) -> ok when
+ This::wxDCOverlay().
+clear(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxDCOverlay),
+ wxe_util:cast(?wxDCOverlay_Clear,
+ <<ThisRef:32/?UI>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxDCOverlay()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxDCOverlay),
+ wxe_util:destroy(?wxDCOverlay_destruct,Obj),
+ ok.
diff --git a/lib/wx/src/gen/wxDataObject.erl b/lib/wx/src/gen/wxDataObject.erl
index 6bb1d1b831..7d47c0cad4 100644
--- a/lib/wx/src/gen/wxDataObject.erl
+++ b/lib/wx/src/gen/wxDataObject.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDateEvent.erl b/lib/wx/src/gen/wxDateEvent.erl
index 3456b6e307..6b01c71ade 100644
--- a/lib/wx/src/gen/wxDateEvent.erl
+++ b/lib/wx/src/gen/wxDateEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDatePickerCtrl.erl b/lib/wx/src/gen/wxDatePickerCtrl.erl
index 57d9a59d22..057f91d4e8 100644
--- a/lib/wx/src/gen/wxDatePickerCtrl.erl
+++ b/lib/wx/src/gen/wxDatePickerCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
-export([destroy/1,getRange/3,getValue/1,new/0,new/2,new/3,setRange/3,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,30 +50,31 @@
getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,isRetained/1,
- isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
- lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,setPickerCtrlGrowable/2,
- setPickerCtrlProportion/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,
- setScrollbar/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTextCtrlGrowable/1,setTextCtrlGrowable/2,setTextCtrlProportion/2,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
+ isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
+ lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
+ moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,
+ setPickerCtrlGrowable/2,setPickerCtrlProportion/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTextCtrlGrowable/1,
+ setTextCtrlGrowable/2,setTextCtrlProportion/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxDatePickerCtrl/0]).
%% @hidden
@@ -195,6 +197,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxDialog.erl b/lib/wx/src/gen/wxDialog.erl
index c8d52736f9..c3f4828c68 100644
--- a/lib/wx/src/gen/wxDialog.erl
+++ b/lib/wx/src/gen/wxDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,11 +35,11 @@
new/0,new/3,new/4,setAffirmativeId/2,setReturnCode/2,show/1,show/2,showModal/1]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -52,29 +53,30 @@
getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,
- isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
- lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
- requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setScrollPos/3,setScrollPos/4,
- setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setTitle/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
- setWindowVariant/2,shouldInheritColours/1,showFullScreen/2,showFullScreen/3,
- thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
- updateWindowUI/2,validate/1,warpPointer/3]).
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
+ maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
+ setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ showFullScreen/2,showFullScreen/3,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxDialog/0]).
%% @hidden
@@ -296,6 +298,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxDirDialog.erl b/lib/wx/src/gen/wxDirDialog.erl
index 4611b86fcf..aa7a419bcd 100644
--- a/lib/wx/src/gen/wxDirDialog.erl
+++ b/lib/wx/src/gen/wxDirDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,getMessage/1,getPath/1,new/1,new/2,setMessage/2,setPath/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -229,6 +231,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxDirPickerCtrl.erl b/lib/wx/src/gen/wxDirPickerCtrl.erl
index 14581822c8..fea7ee71a1 100644
--- a/lib/wx/src/gen/wxDirPickerCtrl.erl
+++ b/lib/wx/src/gen/wxDirPickerCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
-export([create/3,create/4,destroy/1,getPath/1,new/0,new/2,new/3,setPath/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,30 +50,31 @@
getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,isRetained/1,
- isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
- lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,setPickerCtrlGrowable/2,
- setPickerCtrlProportion/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,
- setScrollbar/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTextCtrlGrowable/1,setTextCtrlGrowable/2,setTextCtrlProportion/2,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
+ isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
+ lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
+ moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,
+ setPickerCtrlGrowable/2,setPickerCtrlProportion/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTextCtrlGrowable/1,
+ setTextCtrlGrowable/2,setTextCtrlProportion/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxDirPickerCtrl/0]).
%% @hidden
@@ -212,6 +214,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxDisplayChangedEvent.erl b/lib/wx/src/gen/wxDisplayChangedEvent.erl
index 6872a662b6..b5cd85a10a 100644
--- a/lib/wx/src/gen/wxDisplayChangedEvent.erl
+++ b/lib/wx/src/gen/wxDisplayChangedEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEraseEvent.erl b/lib/wx/src/gen/wxEraseEvent.erl
index 62cf8e3f07..638f36a14b 100644
--- a/lib/wx/src/gen/wxEraseEvent.erl
+++ b/lib/wx/src/gen/wxEraseEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEvent.erl b/lib/wx/src/gen/wxEvent.erl
index 595dba3246..285ed6ecbb 100644
--- a/lib/wx/src/gen/wxEvent.erl
+++ b/lib/wx/src/gen/wxEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEvtHandler.erl b/lib/wx/src/gen/wxEvtHandler.erl
index 44b7254cfb..2d0a87f4dd 100644
--- a/lib/wx/src/gen/wxEvtHandler.erl
+++ b/lib/wx/src/gen/wxEvtHandler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -89,6 +90,8 @@ connect(This=#wx_ref{type=ThisT}, EventType, Options) ->
parse_opts([{callback,Fun}|R], Opts) when is_function(Fun) ->
%% Check Fun Arity?
parse_opts(R, Opts#evh{cb=Fun});
+parse_opts([{callback,CB={nospawn, Fun}}|R], Opts) when is_function(Fun) ->
+ parse_opts(R, Opts#evh{cb=CB});
parse_opts([callback|R], Opts) ->
parse_opts(R, Opts#evh{cb=self()});
parse_opts([{userData, UserData}|R],Opts) ->
diff --git a/lib/wx/src/gen/wxFileDataObject.erl b/lib/wx/src/gen/wxFileDataObject.erl
index 02564d45ec..b132e2291b 100644
--- a/lib/wx/src/gen/wxFileDataObject.erl
+++ b/lib/wx/src/gen/wxFileDataObject.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl
index 0867e5d8b7..36ee6463ae 100644
--- a/lib/wx/src/gen/wxFileDialog.erl
+++ b/lib/wx/src/gen/wxFileDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,11 +36,11 @@
setFilename/2,setFilterIndex/2,setMessage/2,setPath/2,setWildcard/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -54,25 +55,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -322,6 +324,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxFileDirPickerEvent.erl b/lib/wx/src/gen/wxFileDirPickerEvent.erl
index a453196ca4..f2e834f2cb 100644
--- a/lib/wx/src/gen/wxFileDirPickerEvent.erl
+++ b/lib/wx/src/gen/wxFileDirPickerEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFilePickerCtrl.erl b/lib/wx/src/gen/wxFilePickerCtrl.erl
index d41c73368d..2b57a5927b 100644
--- a/lib/wx/src/gen/wxFilePickerCtrl.erl
+++ b/lib/wx/src/gen/wxFilePickerCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
-export([create/3,create/4,destroy/1,getPath/1,new/0,new/2,new/3,setPath/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,30 +50,31 @@
getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,isRetained/1,
- isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
- lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,setPickerCtrlGrowable/2,
- setPickerCtrlProportion/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,
- setScrollbar/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTextCtrlGrowable/1,setTextCtrlGrowable/2,setTextCtrlProportion/2,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
+ isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
+ lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
+ moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,
+ setPickerCtrlGrowable/2,setPickerCtrlProportion/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTextCtrlGrowable/1,
+ setTextCtrlGrowable/2,setTextCtrlProportion/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxFilePickerCtrl/0]).
%% @hidden
@@ -216,6 +218,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxFindReplaceData.erl b/lib/wx/src/gen/wxFindReplaceData.erl
index 8f6f975fa7..c31f945d73 100644
--- a/lib/wx/src/gen/wxFindReplaceData.erl
+++ b/lib/wx/src/gen/wxFindReplaceData.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFindReplaceDialog.erl b/lib/wx/src/gen/wxFindReplaceDialog.erl
index 2a3642b0b6..d265e232b3 100644
--- a/lib/wx/src/gen/wxFindReplaceDialog.erl
+++ b/lib/wx/src/gen/wxFindReplaceDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([create/4,create/5,destroy/1,getData/1,new/0,new/3,new/4]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -225,6 +227,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxFlexGridSizer.erl b/lib/wx/src/gen/wxFlexGridSizer.erl
index 3d8884b503..3e191c8f7b 100644
--- a/lib/wx/src/gen/wxFlexGridSizer.erl
+++ b/lib/wx/src/gen/wxFlexGridSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFocusEvent.erl b/lib/wx/src/gen/wxFocusEvent.erl
index 32141c52ec..07e1115ee4 100644
--- a/lib/wx/src/gen/wxFocusEvent.erl
+++ b/lib/wx/src/gen/wxFocusEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFont.erl b/lib/wx/src/gen/wxFont.erl
index d17314fc7c..5b949260a0 100644
--- a/lib/wx/src/gen/wxFont.erl
+++ b/lib/wx/src/gen/wxFont.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFontData.erl b/lib/wx/src/gen/wxFontData.erl
index 24e3e6a768..a3c1f729ab 100644
--- a/lib/wx/src/gen/wxFontData.erl
+++ b/lib/wx/src/gen/wxFontData.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFontDialog.erl b/lib/wx/src/gen/wxFontDialog.erl
index 7805559ca6..de199cfcce 100644
--- a/lib/wx/src/gen/wxFontDialog.erl
+++ b/lib/wx/src/gen/wxFontDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([create/3,destroy/1,getFontData/1,new/0,new/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -197,6 +199,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxFontPickerCtrl.erl b/lib/wx/src/gen/wxFontPickerCtrl.erl
index 199224ab13..c21061e0fe 100644
--- a/lib/wx/src/gen/wxFontPickerCtrl.erl
+++ b/lib/wx/src/gen/wxFontPickerCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,10 +35,10 @@
new/2,new/3,setMaxPointSize/2,setSelectedFont/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,30 +51,31 @@
getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,isRetained/1,
- isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
- lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,setPickerCtrlGrowable/2,
- setPickerCtrlProportion/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,
- setScrollbar/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTextCtrlGrowable/1,setTextCtrlGrowable/2,setTextCtrlProportion/2,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
+ isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
+ lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
+ moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setInternalMargin/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setPickerCtrlGrowable/1,
+ setPickerCtrlGrowable/2,setPickerCtrlProportion/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTextCtrlGrowable/1,
+ setTextCtrlGrowable/2,setTextCtrlProportion/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxFontPickerCtrl/0]).
%% @hidden
@@ -225,6 +227,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxFontPickerEvent.erl b/lib/wx/src/gen/wxFontPickerEvent.erl
index d914ecb0ba..70485149e1 100644
--- a/lib/wx/src/gen/wxFontPickerEvent.erl
+++ b/lib/wx/src/gen/wxFontPickerEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFrame.erl b/lib/wx/src/gen/wxFrame.erl
index 1fe0ed19bd..75860cd9b7 100644
--- a/lib/wx/src/gen/wxFrame.erl
+++ b/lib/wx/src/gen/wxFrame.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -36,11 +37,11 @@
setStatusText/3,setStatusWidths/2,setToolBar/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -54,29 +55,30 @@
getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,
- isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
- lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
- requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setScrollPos/3,setScrollPos/4,
- setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setTitle/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
- setWindowVariant/2,shouldInheritColours/1,show/1,show/2,showFullScreen/2,
- showFullScreen/3,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
+ maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
+ setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ show/1,show/2,showFullScreen/2,showFullScreen/3,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxFrame/0]).
%% @hidden
@@ -373,6 +375,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxGBSizerItem.erl b/lib/wx/src/gen/wxGBSizerItem.erl
index 74e2d8f342..6498a78626 100644
--- a/lib/wx/src/gen/wxGBSizerItem.erl
+++ b/lib/wx/src/gen/wxGBSizerItem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl
index d6071694a2..9d3d13740d 100644
--- a/lib/wx/src/gen/wxGLCanvas.erl
+++ b/lib/wx/src/gen/wxGLCanvas.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -31,10 +32,10 @@
-export([destroy/1,getContext/1,new/1,new/2,new/3,setCurrent/1,swapBuffers/1]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -46,24 +47,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -192,6 +194,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxGauge.erl b/lib/wx/src/gen/wxGauge.erl
index 12be5d32f3..51c35145c4 100644
--- a/lib/wx/src/gen/wxGauge.erl
+++ b/lib/wx/src/gen/wxGauge.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,10 +35,10 @@
setShadowWidth/2,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,24 +50,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -237,6 +239,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxGenericDirCtrl.erl b/lib/wx/src/gen/wxGenericDirCtrl.erl
index 4539438811..bc26a1645e 100644
--- a/lib/wx/src/gen/wxGenericDirCtrl.erl
+++ b/lib/wx/src/gen/wxGenericDirCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
setFilterIndex/2,setPath/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,24 +51,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -295,6 +297,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxGraphicsBrush.erl b/lib/wx/src/gen/wxGraphicsBrush.erl
index daeaa6d183..d8c2dc680f 100644
--- a/lib/wx/src/gen/wxGraphicsBrush.erl
+++ b/lib/wx/src/gen/wxGraphicsBrush.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsContext.erl b/lib/wx/src/gen/wxGraphicsContext.erl
index 3eab7928e1..4fc62f87fb 100644
--- a/lib/wx/src/gen/wxGraphicsContext.erl
+++ b/lib/wx/src/gen/wxGraphicsContext.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsFont.erl b/lib/wx/src/gen/wxGraphicsFont.erl
index 25c585bb8f..b41d018269 100644
--- a/lib/wx/src/gen/wxGraphicsFont.erl
+++ b/lib/wx/src/gen/wxGraphicsFont.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsMatrix.erl b/lib/wx/src/gen/wxGraphicsMatrix.erl
index 74c8b5f7e9..c513b99954 100644
--- a/lib/wx/src/gen/wxGraphicsMatrix.erl
+++ b/lib/wx/src/gen/wxGraphicsMatrix.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsObject.erl b/lib/wx/src/gen/wxGraphicsObject.erl
index 5daeaedc04..abb4d6dc2d 100644
--- a/lib/wx/src/gen/wxGraphicsObject.erl
+++ b/lib/wx/src/gen/wxGraphicsObject.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsPath.erl b/lib/wx/src/gen/wxGraphicsPath.erl
index a4e12bbbea..6d65093775 100644
--- a/lib/wx/src/gen/wxGraphicsPath.erl
+++ b/lib/wx/src/gen/wxGraphicsPath.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsPen.erl b/lib/wx/src/gen/wxGraphicsPen.erl
index a7d0e80ac8..48f995e887 100644
--- a/lib/wx/src/gen/wxGraphicsPen.erl
+++ b/lib/wx/src/gen/wxGraphicsPen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsRenderer.erl b/lib/wx/src/gen/wxGraphicsRenderer.erl
index 10491fc8d7..b4f50e35fe 100644
--- a/lib/wx/src/gen/wxGraphicsRenderer.erl
+++ b/lib/wx/src/gen/wxGraphicsRenderer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGrid.erl b/lib/wx/src/gen/wxGrid.erl
index f26765c7bf..49bd89f188 100644
--- a/lib/wx/src/gen/wxGrid.erl
+++ b/lib/wx/src/gen/wxGrid.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -85,10 +86,10 @@
%% inherited exports
-export([cacheBestSize/2,calcScrolledPosition/2,calcScrolledPosition/3,calcUnscrolledPosition/2,
- calcUnscrolledPosition/3,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+ calcUnscrolledPosition/3,canSetTransparent/1,captureMouse/1,center/1,
+ center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
doPrepareDC/2,enable/1,enable/2,enableScrolling/3,findWindow/2,fitInside/1,
freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
@@ -101,25 +102,26 @@
getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
getToolTip/1,getUpdateRegion/1,getViewStart/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,raise/1,refresh/1,refresh/2,
- refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
- screenToClient/1,screenToClient/2,scroll/3,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,
- setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,
- setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scroll/3,
+ scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6,setScrollbars/5,
+ setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
+ setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
+ setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -2156,6 +2158,14 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxGridBagSizer.erl b/lib/wx/src/gen/wxGridBagSizer.erl
index 75bef85d90..adbc66adca 100644
--- a/lib/wx/src/gen/wxGridBagSizer.erl
+++ b/lib/wx/src/gen/wxGridBagSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellAttr.erl b/lib/wx/src/gen/wxGridCellAttr.erl
index 76e21ef594..4880c1fab2 100644
--- a/lib/wx/src/gen/wxGridCellAttr.erl
+++ b/lib/wx/src/gen/wxGridCellAttr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellBoolEditor.erl b/lib/wx/src/gen/wxGridCellBoolEditor.erl
index c4d6d92618..1308ab84ae 100644
--- a/lib/wx/src/gen/wxGridCellBoolEditor.erl
+++ b/lib/wx/src/gen/wxGridCellBoolEditor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellBoolRenderer.erl b/lib/wx/src/gen/wxGridCellBoolRenderer.erl
index 5a0b16b5df..55f54100f3 100644
--- a/lib/wx/src/gen/wxGridCellBoolRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellBoolRenderer.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellChoiceEditor.erl b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
index a49680ffda..8aa4420ffb 100644
--- a/lib/wx/src/gen/wxGridCellChoiceEditor.erl
+++ b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellEditor.erl b/lib/wx/src/gen/wxGridCellEditor.erl
index 657d65762d..253868300e 100644
--- a/lib/wx/src/gen/wxGridCellEditor.erl
+++ b/lib/wx/src/gen/wxGridCellEditor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellFloatEditor.erl b/lib/wx/src/gen/wxGridCellFloatEditor.erl
index 5cd0bd6cb5..6dd8ec7647 100644
--- a/lib/wx/src/gen/wxGridCellFloatEditor.erl
+++ b/lib/wx/src/gen/wxGridCellFloatEditor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellFloatRenderer.erl b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
index ea3cd0eebe..c0f4157970 100644
--- a/lib/wx/src/gen/wxGridCellFloatRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellNumberEditor.erl b/lib/wx/src/gen/wxGridCellNumberEditor.erl
index 7cc682a10e..e08cade3e0 100644
--- a/lib/wx/src/gen/wxGridCellNumberEditor.erl
+++ b/lib/wx/src/gen/wxGridCellNumberEditor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellNumberRenderer.erl b/lib/wx/src/gen/wxGridCellNumberRenderer.erl
index 840d6da41d..437654f2bb 100644
--- a/lib/wx/src/gen/wxGridCellNumberRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellNumberRenderer.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellRenderer.erl b/lib/wx/src/gen/wxGridCellRenderer.erl
index 5ed4587153..0821f3b632 100644
--- a/lib/wx/src/gen/wxGridCellRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellRenderer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellStringRenderer.erl b/lib/wx/src/gen/wxGridCellStringRenderer.erl
index 966d5affc0..c9d7474988 100644
--- a/lib/wx/src/gen/wxGridCellStringRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellStringRenderer.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellTextEditor.erl b/lib/wx/src/gen/wxGridCellTextEditor.erl
index a024da56c4..303f1e90b6 100644
--- a/lib/wx/src/gen/wxGridCellTextEditor.erl
+++ b/lib/wx/src/gen/wxGridCellTextEditor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridEvent.erl b/lib/wx/src/gen/wxGridEvent.erl
index 2ce526244c..e1fb27bc5b 100644
--- a/lib/wx/src/gen/wxGridEvent.erl
+++ b/lib/wx/src/gen/wxGridEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridSizer.erl b/lib/wx/src/gen/wxGridSizer.erl
index 0be9bb5e57..78fe5b16ed 100644
--- a/lib/wx/src/gen/wxGridSizer.erl
+++ b/lib/wx/src/gen/wxGridSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHelpEvent.erl b/lib/wx/src/gen/wxHelpEvent.erl
index 37b4eed154..20affab33d 100644
--- a/lib/wx/src/gen/wxHelpEvent.erl
+++ b/lib/wx/src/gen/wxHelpEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHtmlEasyPrinting.erl b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
index e4e4849fe7..0a3d79caee 100644
--- a/lib/wx/src/gen/wxHtmlEasyPrinting.erl
+++ b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHtmlLinkEvent.erl b/lib/wx/src/gen/wxHtmlLinkEvent.erl
index c3a201a626..08594c95f0 100644
--- a/lib/wx/src/gen/wxHtmlLinkEvent.erl
+++ b/lib/wx/src/gen/wxHtmlLinkEvent.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHtmlWindow.erl b/lib/wx/src/gen/wxHtmlWindow.erl
index fae80c398c..759b8ba0fd 100644
--- a/lib/wx/src/gen/wxHtmlWindow.erl
+++ b/lib/wx/src/gen/wxHtmlWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -39,10 +40,10 @@
%% inherited exports
-export([cacheBestSize/2,calcScrolledPosition/2,calcScrolledPosition/3,calcUnscrolledPosition/2,
- calcUnscrolledPosition/3,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+ calcUnscrolledPosition/3,canSetTransparent/1,captureMouse/1,center/1,
+ center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
doPrepareDC/2,enable/1,enable/2,enableScrolling/3,findWindow/2,fit/1,
fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
@@ -55,25 +56,26 @@
getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
getToolTip/1,getUpdateRegion/1,getViewStart/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,raise/1,refresh/1,refresh/2,
- refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
- screenToClient/1,screenToClient/2,scroll/3,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,
- setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,
- setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scroll/3,
+ scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6,setScrollbars/5,
+ setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
+ setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
+ setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -369,6 +371,14 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxIcon.erl b/lib/wx/src/gen/wxIcon.erl
index 6986d332d0..82042b0ba2 100644
--- a/lib/wx/src/gen/wxIcon.erl
+++ b/lib/wx/src/gen/wxIcon.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIconBundle.erl b/lib/wx/src/gen/wxIconBundle.erl
index 2ccd722b66..acf98d0a12 100644
--- a/lib/wx/src/gen/wxIconBundle.erl
+++ b/lib/wx/src/gen/wxIconBundle.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIconizeEvent.erl b/lib/wx/src/gen/wxIconizeEvent.erl
index 232e6eb68c..495f636946 100644
--- a/lib/wx/src/gen/wxIconizeEvent.erl
+++ b/lib/wx/src/gen/wxIconizeEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIdleEvent.erl b/lib/wx/src/gen/wxIdleEvent.erl
index e4d6a5a059..4b83b5f50a 100644
--- a/lib/wx/src/gen/wxIdleEvent.erl
+++ b/lib/wx/src/gen/wxIdleEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxImage.erl b/lib/wx/src/gen/wxImage.erl
index b20cc3d613..05d1038eee 100644
--- a/lib/wx/src/gen/wxImage.erl
+++ b/lib/wx/src/gen/wxImage.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxImageList.erl b/lib/wx/src/gen/wxImageList.erl
index 8f33cc78fb..89e0b2cd41 100644
--- a/lib/wx/src/gen/wxImageList.erl
+++ b/lib/wx/src/gen/wxImageList.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxInitDialogEvent.erl b/lib/wx/src/gen/wxInitDialogEvent.erl
index c8fe6042ac..3ab90b947c 100644
--- a/lib/wx/src/gen/wxInitDialogEvent.erl
+++ b/lib/wx/src/gen/wxInitDialogEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxJoystickEvent.erl b/lib/wx/src/gen/wxJoystickEvent.erl
index 12a8df69c2..5d82b629c3 100644
--- a/lib/wx/src/gen/wxJoystickEvent.erl
+++ b/lib/wx/src/gen/wxJoystickEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxKeyEvent.erl b/lib/wx/src/gen/wxKeyEvent.erl
index 6d25b50ea7..6a3b5de502 100644
--- a/lib/wx/src/gen/wxKeyEvent.erl
+++ b/lib/wx/src/gen/wxKeyEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxLayoutAlgorithm.erl b/lib/wx/src/gen/wxLayoutAlgorithm.erl
index c99c6f9a46..6a3e77b3de 100644
--- a/lib/wx/src/gen/wxLayoutAlgorithm.erl
+++ b/lib/wx/src/gen/wxLayoutAlgorithm.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListBox.erl b/lib/wx/src/gen/wxListBox.erl
index 732cd351f2..eaa026839e 100644
--- a/lib/wx/src/gen/wxListBox.erl
+++ b/lib/wx/src/gen/wxListBox.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,45 +35,47 @@
isSelected/2,new/0,new/2,new/3,set/2,setFirstItem/2]).
%% inherited exports
--export([append/2,append/3,appendStrings/2,cacheBestSize/2,captureMouse/1,center/1,
- center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
- centreOnParent/2,clear/1,clearBackground/1,clientToScreen/2,clientToScreen/3,
- close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
- delete/2,destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
- freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
- getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
- getClientData/2,getClientSize/1,getContainingSizer/1,getCount/1,getCursor/1,
- getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+-export([append/2,append/3,appendStrings/2,cacheBestSize/2,canSetTransparent/1,
+ captureMouse/1,center/1,center/2,centerOnParent/1,centerOnParent/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
+ clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
+ convertDialogToPixels/2,convertPixelsToDialog/2,delete/2,destroyChildren/1,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
+ findString/2,findString/3,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientData/2,getClientSize/1,
+ getContainingSizer/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
+ getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
+ getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
getSelection/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- insert/3,insert/4,invalidateBestSize/1,isEmpty/1,isEnabled/1,isExposed/2,
- isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
- moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- select/2,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientData/3,setClientSize/2,setClientSize/3,
- setContainingSizer/2,setCursor/2,setDropTarget/2,setExtraStyle/2,
- setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setSelection/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,
- setStringSelection/2,setThemeEnabled/2,setToolTip/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ insert/3,insert/4,invalidateBestSize/1,isDoubleBuffered/1,isEmpty/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientData/3,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSelection/2,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
+ setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
+ setSizerAndFit/3,setString/3,setStringSelection/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxListBox/0]).
%% @hidden
@@ -277,6 +280,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxListCtrl.erl b/lib/wx/src/gen/wxListCtrl.erl
index f9010eecf9..6750931fdb 100644
--- a/lib/wx/src/gen/wxListCtrl.erl
+++ b/lib/wx/src/gen/wxListCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -46,10 +47,10 @@
setSingleStyle/2,setSingleStyle/3,setTextColour/2,setWindowStyleFlag/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -61,27 +62,28 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowVariant/2,shouldInheritColours/1,show/1,
- show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,
- updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setId/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxListCtrl/0]).
%% @hidden
@@ -868,6 +870,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxListEvent.erl b/lib/wx/src/gen/wxListEvent.erl
index 9ce3b19288..b989f9233c 100644
--- a/lib/wx/src/gen/wxListEvent.erl
+++ b/lib/wx/src/gen/wxListEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListItem.erl b/lib/wx/src/gen/wxListItem.erl
index 5b3c8c2f5f..568eba4c6a 100644
--- a/lib/wx/src/gen/wxListItem.erl
+++ b/lib/wx/src/gen/wxListItem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListItemAttr.erl b/lib/wx/src/gen/wxListItemAttr.erl
index 54f3255e05..0c594ede8f 100644
--- a/lib/wx/src/gen/wxListItemAttr.erl
+++ b/lib/wx/src/gen/wxListItemAttr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListView.erl b/lib/wx/src/gen/wxListView.erl
index b8b10e0e62..288afcee82 100644
--- a/lib/wx/src/gen/wxListView.erl
+++ b/lib/wx/src/gen/wxListView.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
isSelected/2,select/2,select/3,setColumnImage/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -167,6 +169,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxListbook.erl b/lib/wx/src/gen/wxListbook.erl
index 4c8d51c0a3..6ea34e8eb1 100644
--- a/lib/wx/src/gen/wxListbook.erl
+++ b/lib/wx/src/gen/wxListbook.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -37,10 +38,10 @@
setPageSize/2,setPageText/3,setSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -52,24 +53,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -382,6 +384,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxLocale.erl b/lib/wx/src/gen/wxLocale.erl
index a1a418bcee..c0488022e0 100644
--- a/lib/wx/src/gen/wxLocale.erl
+++ b/lib/wx/src/gen/wxLocale.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxLogNull.erl b/lib/wx/src/gen/wxLogNull.erl
index 6e2a3b7100..aa45245cd0 100644
--- a/lib/wx/src/gen/wxLogNull.erl
+++ b/lib/wx/src/gen/wxLogNull.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMDIChildFrame.erl b/lib/wx/src/gen/wxMDIChildFrame.erl
index 11d11e313e..ed29e5431f 100644
--- a/lib/wx/src/gen/wxMDIChildFrame.erl
+++ b/lib/wx/src/gen/wxMDIChildFrame.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,11 +35,11 @@
new/4,restore/1]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -54,26 +55,27 @@
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
- moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,
- setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setStatusBar/2,setStatusBarPane/2,setStatusText/2,setStatusText/3,
- setStatusWidths/2,setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,
+ setStatusBarPane/2,setStatusText/2,setStatusText/3,setStatusWidths/2,
+ setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,setTransparent/2,
setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
@@ -273,6 +275,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxMDIClientWindow.erl b/lib/wx/src/gen/wxMDIClientWindow.erl
index 1710aa54b2..6f10627086 100644
--- a/lib/wx/src/gen/wxMDIClientWindow.erl
+++ b/lib/wx/src/gen/wxMDIClientWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -31,10 +32,10 @@
-export([createClient/2,createClient/3,destroy/1,new/0,new/1,new/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -46,24 +47,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -134,6 +136,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxMDIParentFrame.erl b/lib/wx/src/gen/wxMDIParentFrame.erl
index 35473d09c1..47d9182d60 100644
--- a/lib/wx/src/gen/wxMDIParentFrame.erl
+++ b/lib/wx/src/gen/wxMDIParentFrame.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,11 +36,11 @@
tile/1,tile/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -55,32 +56,32 @@
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
+ releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,
- setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,setMaxSize/2,
- setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setScrollPos/3,setScrollPos/4,
- setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,setStatusBarPane/2,
- setStatusText/2,setStatusText/3,setStatusWidths/2,setThemeEnabled/2,
- setTitle/2,setToolBar/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,showFullScreen/2,showFullScreen/3,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,
+ setStatusBarPane/2,setStatusText/2,setStatusText/3,setStatusWidths/2,
+ setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
+ thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
+ updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxMDIParentFrame/0]).
%% @hidden
@@ -312,6 +313,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxMask.erl b/lib/wx/src/gen/wxMask.erl
index 491dc2db79..343f8e4938 100644
--- a/lib/wx/src/gen/wxMask.erl
+++ b/lib/wx/src/gen/wxMask.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMaximizeEvent.erl b/lib/wx/src/gen/wxMaximizeEvent.erl
index 8db7c8a07a..32abc5536c 100644
--- a/lib/wx/src/gen/wxMaximizeEvent.erl
+++ b/lib/wx/src/gen/wxMaximizeEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMemoryDC.erl b/lib/wx/src/gen/wxMemoryDC.erl
index 8de412bdc7..7fddaa7bf1 100644
--- a/lib/wx/src/gen/wxMemoryDC.erl
+++ b/lib/wx/src/gen/wxMemoryDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenu.erl b/lib/wx/src/gen/wxMenu.erl
index a29480cb5e..a9911e7ded 100644
--- a/lib/wx/src/gen/wxMenu.erl
+++ b/lib/wx/src/gen/wxMenu.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenuBar.erl b/lib/wx/src/gen/wxMenuBar.erl
index 937a5e4afc..5e879da5ed 100644
--- a/lib/wx/src/gen/wxMenuBar.erl
+++ b/lib/wx/src/gen/wxMenuBar.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
setLabelTop/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
@@ -50,24 +51,24 @@
getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isExposed/2,isExposed/3,isExposed/5,
- isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
- makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
- setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isExposed/2,
+ isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,
+ lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
+ moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -339,6 +340,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxMenuEvent.erl b/lib/wx/src/gen/wxMenuEvent.erl
index 7e3905d3e4..e30906fb3d 100644
--- a/lib/wx/src/gen/wxMenuEvent.erl
+++ b/lib/wx/src/gen/wxMenuEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenuItem.erl b/lib/wx/src/gen/wxMenuItem.erl
index 5a7d210d15..94f160c02e 100644
--- a/lib/wx/src/gen/wxMenuItem.erl
+++ b/lib/wx/src/gen/wxMenuItem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMessageDialog.erl b/lib/wx/src/gen/wxMessageDialog.erl
index 71dacf2b42..1fe99b2b88 100644
--- a/lib/wx/src/gen/wxMessageDialog.erl
+++ b/lib/wx/src/gen/wxMessageDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,new/2,new/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -190,6 +192,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxMiniFrame.erl b/lib/wx/src/gen/wxMiniFrame.erl
index 40671d1361..f731cc5416 100644
--- a/lib/wx/src/gen/wxMiniFrame.erl
+++ b/lib/wx/src/gen/wxMiniFrame.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([create/4,create/5,destroy/1,new/0,new/3,new/4]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -53,32 +54,32 @@
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
+ releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,
- setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,setMaxSize/2,
- setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setScrollPos/3,setScrollPos/4,
- setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,setStatusBarPane/2,
- setStatusText/2,setStatusText/3,setStatusWidths/2,setThemeEnabled/2,
- setTitle/2,setToolBar/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,showFullScreen/2,showFullScreen/3,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,
+ setStatusBarPane/2,setStatusText/2,setStatusText/3,setStatusWidths/2,
+ setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
+ thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
+ updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxMiniFrame/0]).
%% @hidden
@@ -240,6 +241,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxMirrorDC.erl b/lib/wx/src/gen/wxMirrorDC.erl
index 9a681bff2e..459205e18b 100644
--- a/lib/wx/src/gen/wxMirrorDC.erl
+++ b/lib/wx/src/gen/wxMirrorDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl b/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
index 6b0a4500b0..d9d4ab9ba4 100644
--- a/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
+++ b/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMouseCaptureLostEvent.erl b/lib/wx/src/gen/wxMouseCaptureLostEvent.erl
new file mode 100644
index 0000000000..a7e68a2d2f
--- /dev/null
+++ b/lib/wx/src/gen/wxMouseCaptureLostEvent.erl
@@ -0,0 +1,65 @@
+%%
+%% %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.
+%% 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%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmousecapturelostevent.html">wxMouseCaptureLostEvent</a>.
+%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt>
+%% <dd><em>mouse_capture_lost</em></dd></dl>
+%% See also the message variant {@link wxEvtHandler:wxMouseCaptureLost(). #wxMouseCaptureLost{}} event record type.
+%%
+%% <p>This class is derived (and can use functions) from:
+%% <br />{@link wxEvent}
+%% </p>
+%% @type wxMouseCaptureLostEvent(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxMouseCaptureLostEvent).
+-include("wxe.hrl").
+-export([]).
+
+%% inherited exports
+-export([getId/1,getSkipped/1,getTimestamp/1,isCommandEvent/1,parent_class/1,
+ resumePropagation/2,shouldPropagate/1,skip/1,skip/2,stopPropagation/1]).
+
+-export_type([wxMouseCaptureLostEvent/0]).
+%% @hidden
+parent_class(wxEvent) -> true;
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxMouseCaptureLostEvent() :: wx:wx_object().
+ %% From wxEvent
+%% @hidden
+stopPropagation(This) -> wxEvent:stopPropagation(This).
+%% @hidden
+skip(This, Options) -> wxEvent:skip(This, Options).
+%% @hidden
+skip(This) -> wxEvent:skip(This).
+%% @hidden
+shouldPropagate(This) -> wxEvent:shouldPropagate(This).
+%% @hidden
+resumePropagation(This,PropagationLevel) -> wxEvent:resumePropagation(This,PropagationLevel).
+%% @hidden
+isCommandEvent(This) -> wxEvent:isCommandEvent(This).
+%% @hidden
+getTimestamp(This) -> wxEvent:getTimestamp(This).
+%% @hidden
+getSkipped(This) -> wxEvent:getSkipped(This).
+%% @hidden
+getId(This) -> wxEvent:getId(This).
diff --git a/lib/wx/src/gen/wxMouseEvent.erl b/lib/wx/src/gen/wxMouseEvent.erl
index f267b437a0..8fcdc79620 100644
--- a/lib/wx/src/gen/wxMouseEvent.erl
+++ b/lib/wx/src/gen/wxMouseEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMoveEvent.erl b/lib/wx/src/gen/wxMoveEvent.erl
index 429f35411e..bbab536400 100644
--- a/lib/wx/src/gen/wxMoveEvent.erl
+++ b/lib/wx/src/gen/wxMoveEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMultiChoiceDialog.erl b/lib/wx/src/gen/wxMultiChoiceDialog.erl
index 4a83bb52d9..96e9c070a3 100644
--- a/lib/wx/src/gen/wxMultiChoiceDialog.erl
+++ b/lib/wx/src/gen/wxMultiChoiceDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,getSelections/1,new/0,new/4,new/5,setSelections/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -215,6 +217,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxNavigationKeyEvent.erl b/lib/wx/src/gen/wxNavigationKeyEvent.erl
index 314d2814ef..58b465fdd5 100644
--- a/lib/wx/src/gen/wxNavigationKeyEvent.erl
+++ b/lib/wx/src/gen/wxNavigationKeyEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNotebook.erl b/lib/wx/src/gen/wxNotebook.erl
index 036e13c3c7..5011375aad 100644
--- a/lib/wx/src/gen/wxNotebook.erl
+++ b/lib/wx/src/gen/wxNotebook.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -37,10 +38,10 @@
setPadding/2,setPageImage/3,setPageSize/2,setPageText/3,setSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -52,24 +53,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -407,6 +409,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxNotebookEvent.erl b/lib/wx/src/gen/wxNotebookEvent.erl
index d7fbf7b4a4..931313008d 100644
--- a/lib/wx/src/gen/wxNotebookEvent.erl
+++ b/lib/wx/src/gen/wxNotebookEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNotifyEvent.erl b/lib/wx/src/gen/wxNotifyEvent.erl
index b78f2ed348..f43d72db3c 100644
--- a/lib/wx/src/gen/wxNotifyEvent.erl
+++ b/lib/wx/src/gen/wxNotifyEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxOverlay.erl b/lib/wx/src/gen/wxOverlay.erl
new file mode 100644
index 0000000000..7da3ece657
--- /dev/null
+++ b/lib/wx/src/gen/wxOverlay.erl
@@ -0,0 +1,57 @@
+%%
+%% %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.
+%% 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%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxoverlay.html">wxOverlay</a>.
+%% @type wxOverlay(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxOverlay).
+-include("wxe.hrl").
+-export([destroy/1,new/0,reset/1]).
+
+%% inherited exports
+-export([parent_class/1]).
+
+-export_type([wxOverlay/0]).
+%% @hidden
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxOverlay() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxoverlay.html#wxoverlaywxoverlay">external documentation</a>.
+-spec new() -> wxOverlay().
+new() ->
+ wxe_util:construct(?wxOverlay_new,
+ <<>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxoverlay.html#wxoverlayreset">external documentation</a>.
+-spec reset(This) -> ok when
+ This::wxOverlay().
+reset(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxOverlay),
+ wxe_util:cast(?wxOverlay_Reset,
+ <<ThisRef:32/?UI>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxOverlay()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxOverlay),
+ wxe_util:destroy(?wxOverlay_destruct,Obj),
+ ok.
diff --git a/lib/wx/src/gen/wxPageSetupDialog.erl b/lib/wx/src/gen/wxPageSetupDialog.erl
index 6b190eac28..e6e6412d2c 100644
--- a/lib/wx/src/gen/wxPageSetupDialog.erl
+++ b/lib/wx/src/gen/wxPageSetupDialog.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPageSetupDialogData.erl b/lib/wx/src/gen/wxPageSetupDialogData.erl
index de8e36ccae..bcfd55d8bc 100644
--- a/lib/wx/src/gen/wxPageSetupDialogData.erl
+++ b/lib/wx/src/gen/wxPageSetupDialogData.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPaintDC.erl b/lib/wx/src/gen/wxPaintDC.erl
index 0ff27a8c7a..b2f2d6a977 100644
--- a/lib/wx/src/gen/wxPaintDC.erl
+++ b/lib/wx/src/gen/wxPaintDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPaintEvent.erl b/lib/wx/src/gen/wxPaintEvent.erl
index 951756f76e..20885bf69c 100644
--- a/lib/wx/src/gen/wxPaintEvent.erl
+++ b/lib/wx/src/gen/wxPaintEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPalette.erl b/lib/wx/src/gen/wxPalette.erl
index 753aa04dd9..9883283828 100644
--- a/lib/wx/src/gen/wxPalette.erl
+++ b/lib/wx/src/gen/wxPalette.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPaletteChangedEvent.erl b/lib/wx/src/gen/wxPaletteChangedEvent.erl
index 16013536aa..80e15af0ec 100644
--- a/lib/wx/src/gen/wxPaletteChangedEvent.erl
+++ b/lib/wx/src/gen/wxPaletteChangedEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPanel.erl b/lib/wx/src/gen/wxPanel.erl
index eeadbee2f8..ceb894fe31 100644
--- a/lib/wx/src/gen/wxPanel.erl
+++ b/lib/wx/src/gen/wxPanel.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -31,10 +32,10 @@
-export([destroy/1,initDialog/1,new/0,new/1,new/2,new/5,new/6,setFocusIgnoringChildren/1]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -46,24 +47,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,invalidateBestSize/1,isEnabled/1,isExposed/2,
- isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
- moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -153,6 +155,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPasswordEntryDialog.erl b/lib/wx/src/gen/wxPasswordEntryDialog.erl
index 67c9b10e8b..ac3f1c9d8c 100644
--- a/lib/wx/src/gen/wxPasswordEntryDialog.erl
+++ b/lib/wx/src/gen/wxPasswordEntryDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,11 +35,11 @@
-export([destroy/1,new/2,new/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -53,8 +54,8 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getValue/1,getVirtualSize/1,
getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isActive/1,isEnabled/1,isExposed/2,
- isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
@@ -65,19 +66,19 @@
scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setValue/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
- transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
- updateWindowUI/2,validate/1,warpPointer/3]).
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setValue/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
+ showModal/1,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxPasswordEntryDialog/0]).
%% @hidden
@@ -200,6 +201,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPen.erl b/lib/wx/src/gen/wxPen.erl
index f19106c630..cd6fa9884c 100644
--- a/lib/wx/src/gen/wxPen.erl
+++ b/lib/wx/src/gen/wxPen.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPickerBase.erl b/lib/wx/src/gen/wxPickerBase.erl
index bdd488d65a..bbdeaf6af8 100644
--- a/lib/wx/src/gen/wxPickerBase.erl
+++ b/lib/wx/src/gen/wxPickerBase.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
setTextCtrlGrowable/1,setTextCtrlGrowable/2,setTextCtrlProportion/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,24 +51,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -212,6 +214,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPopupTransientWindow.erl b/lib/wx/src/gen/wxPopupTransientWindow.erl
index 253d33e5ac..c07c6e239e 100644
--- a/lib/wx/src/gen/wxPopupTransientWindow.erl
+++ b/lib/wx/src/gen/wxPopupTransientWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -32,10 +33,10 @@
-export([destroy/1,dismiss/1,new/0,new/1,new/2,popup/1,popup/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -47,24 +48,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,position/3,raise/1,refresh/1,refresh/2,
- refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,position/3,raise/1,
+ refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -144,6 +146,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
position(This,PtOrigin,Size) -> wxPopupWindow:position(This,PtOrigin,Size).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPopupWindow.erl b/lib/wx/src/gen/wxPopupWindow.erl
index 415185d574..439f5fac54 100644
--- a/lib/wx/src/gen/wxPopupWindow.erl
+++ b/lib/wx/src/gen/wxPopupWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -31,10 +32,10 @@
-export([create/2,create/3,destroy/1,new/0,new/1,new/2,position/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -46,24 +47,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -141,6 +143,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPostScriptDC.erl b/lib/wx/src/gen/wxPostScriptDC.erl
index e7e498efa1..2af3b53cf0 100644
--- a/lib/wx/src/gen/wxPostScriptDC.erl
+++ b/lib/wx/src/gen/wxPostScriptDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPreviewCanvas.erl b/lib/wx/src/gen/wxPreviewCanvas.erl
index 33ec12c371..67357dbd65 100644
--- a/lib/wx/src/gen/wxPreviewCanvas.erl
+++ b/lib/wx/src/gen/wxPreviewCanvas.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,10 +35,10 @@
%% inherited exports
-export([cacheBestSize/2,calcScrolledPosition/2,calcScrolledPosition/3,calcUnscrolledPosition/2,
- calcUnscrolledPosition/3,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+ calcUnscrolledPosition/3,canSetTransparent/1,captureMouse/1,center/1,
+ center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
doPrepareDC/2,enable/1,enable/2,enableScrolling/3,findWindow/2,fit/1,
fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
@@ -50,25 +51,26 @@
getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
getToolTip/1,getUpdateRegion/1,getViewStart/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,raise/1,refresh/1,refresh/2,
- refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
- screenToClient/1,screenToClient/2,scroll/3,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,
- setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,
- setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scroll/3,
+ scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6,setScrollbars/5,
+ setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
+ setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
+ setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -119,6 +121,14 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPreviewControlBar.erl b/lib/wx/src/gen/wxPreviewControlBar.erl
index 22608197b5..0e1828e87b 100644
--- a/lib/wx/src/gen/wxPreviewControlBar.erl
+++ b/lib/wx/src/gen/wxPreviewControlBar.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
new/4,setZoomControl/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -150,6 +152,14 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPreviewFrame.erl b/lib/wx/src/gen/wxPreviewFrame.erl
index 70cc62635a..fe684478a5 100644
--- a/lib/wx/src/gen/wxPreviewFrame.erl
+++ b/lib/wx/src/gen/wxPreviewFrame.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,11 +35,11 @@
onCloseWindow/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -54,32 +55,32 @@
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
+ releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,
- setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,setMaxSize/2,
- setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setScrollPos/3,setScrollPos/4,
- setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,setStatusBarPane/2,
- setStatusText/2,setStatusText/3,setStatusWidths/2,setThemeEnabled/2,
- setTitle/2,setToolBar/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,showFullScreen/2,showFullScreen/3,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,
+ setStatusBarPane/2,setStatusText/2,setStatusText/3,setStatusWidths/2,
+ setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
+ thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
+ updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxPreviewFrame/0]).
%% @hidden
@@ -243,6 +244,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPrintData.erl b/lib/wx/src/gen/wxPrintData.erl
index dc3b0048c5..757685c36b 100644
--- a/lib/wx/src/gen/wxPrintData.erl
+++ b/lib/wx/src/gen/wxPrintData.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintDialog.erl b/lib/wx/src/gen/wxPrintDialog.erl
index bf1fd7d179..a337089d5a 100644
--- a/lib/wx/src/gen/wxPrintDialog.erl
+++ b/lib/wx/src/gen/wxPrintDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,getPrintDC/1,getPrintDialogData/1,new/1,new/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -212,6 +214,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxPrintDialogData.erl b/lib/wx/src/gen/wxPrintDialogData.erl
index 797ea3e5ec..3ed49808e6 100644
--- a/lib/wx/src/gen/wxPrintDialogData.erl
+++ b/lib/wx/src/gen/wxPrintDialogData.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintPreview.erl b/lib/wx/src/gen/wxPrintPreview.erl
index da0f76af0e..cb3ccccbbe 100644
--- a/lib/wx/src/gen/wxPrintPreview.erl
+++ b/lib/wx/src/gen/wxPrintPreview.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrinter.erl b/lib/wx/src/gen/wxPrinter.erl
index b21f6df2d7..ec27b3cab9 100644
--- a/lib/wx/src/gen/wxPrinter.erl
+++ b/lib/wx/src/gen/wxPrinter.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintout.erl b/lib/wx/src/gen/wxPrintout.erl
index c357c74bf3..45ca116251 100644
--- a/lib/wx/src/gen/wxPrintout.erl
+++ b/lib/wx/src/gen/wxPrintout.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxProgressDialog.erl b/lib/wx/src/gen/wxProgressDialog.erl
index b88e7ac75e..665b900729 100644
--- a/lib/wx/src/gen/wxProgressDialog.erl
+++ b/lib/wx/src/gen/wxProgressDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,new/2,new/3,resume/1,update/1,update/2,update/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -227,6 +229,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxQueryNewPaletteEvent.erl b/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
index 606566a6e7..11ca65923d 100644
--- a/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
+++ b/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxRadioBox.erl b/lib/wx/src/gen/wxRadioBox.erl
index 98769ff11b..5ef1deff66 100644
--- a/lib/wx/src/gen/wxRadioBox.erl
+++ b/lib/wx/src/gen/wxRadioBox.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
setItemHelpText/3,setItemToolTip/3,setSelection/2,show/1,show/2,show/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
@@ -50,24 +51,24 @@
getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
- lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
updateWindowUI/2,validate/1,warpPointer/3]).
@@ -347,6 +348,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxRadioButton.erl b/lib/wx/src/gen/wxRadioButton.erl
index ead0fe32e8..3b4689a27b 100644
--- a/lib/wx/src/gen/wxRadioButton.erl
+++ b/lib/wx/src/gen/wxRadioButton.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -32,10 +33,10 @@
-export([create/4,create/5,destroy/1,getValue/1,new/0,new/3,new/4,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -47,24 +48,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -170,6 +172,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxRegion.erl b/lib/wx/src/gen/wxRegion.erl
index addb752680..63662eb163 100644
--- a/lib/wx/src/gen/wxRegion.erl
+++ b/lib/wx/src/gen/wxRegion.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSashEvent.erl b/lib/wx/src/gen/wxSashEvent.erl
index 028b8ba067..e4d31043e0 100644
--- a/lib/wx/src/gen/wxSashEvent.erl
+++ b/lib/wx/src/gen/wxSashEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSashLayoutWindow.erl b/lib/wx/src/gen/wxSashLayoutWindow.erl
index c7c0c7d1ab..223c07419d 100644
--- a/lib/wx/src/gen/wxSashLayoutWindow.erl
+++ b/lib/wx/src/gen/wxSashLayoutWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
new/2,setAlignment/2,setDefaultSize/2,setOrientation/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,9 +51,9 @@
getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- invalidateBestSize/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
- isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
- makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
+ lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
@@ -60,17 +61,17 @@
scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMaximumSizeX/2,setMaximumSizeY/2,setMinSize/2,setMinimumSizeX/2,
setMinimumSizeY/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
setOwnForegroundColour/2,setPalette/2,setSashVisible/3,setScrollPos/3,
setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
- setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
- setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
- shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
validate/1,warpPointer/3]).
@@ -219,6 +220,14 @@ getMaximumSizeX(This) -> wxSashWindow:getMaximumSizeX(This).
getSashVisible(This,Edge) -> wxSashWindow:getSashVisible(This,Edge).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSashWindow.erl b/lib/wx/src/gen/wxSashWindow.erl
index 9404d73b6c..4a39726ffd 100644
--- a/lib/wx/src/gen/wxSashWindow.erl
+++ b/lib/wx/src/gen/wxSashWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
setMinimumSizeX/2,setMinimumSizeY/2,setSashVisible/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -206,6 +208,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxScreenDC.erl b/lib/wx/src/gen/wxScreenDC.erl
index 21ca4bacfc..2766d8d397 100644
--- a/lib/wx/src/gen/wxScreenDC.erl
+++ b/lib/wx/src/gen/wxScreenDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrollBar.erl b/lib/wx/src/gen/wxScrollBar.erl
index 8907b15ee9..ccddf84835 100644
--- a/lib/wx/src/gen/wxScrollBar.erl
+++ b/lib/wx/src/gen/wxScrollBar.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
getThumbSize/1,new/0,new/2,new/3,setScrollbar/5,setScrollbar/6,setThumbPosition/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,25 +49,26 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setSize/2,setSize/3,setSize/5,
setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
- setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
- setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
- shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
validate/1,warpPointer/3]).
@@ -214,6 +216,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxScrollEvent.erl b/lib/wx/src/gen/wxScrollEvent.erl
index a2a8a59caa..d8b29dfa2d 100644
--- a/lib/wx/src/gen/wxScrollEvent.erl
+++ b/lib/wx/src/gen/wxScrollEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrollWinEvent.erl b/lib/wx/src/gen/wxScrollWinEvent.erl
index eb8d191b5f..a5bfb101f0 100644
--- a/lib/wx/src/gen/wxScrollWinEvent.erl
+++ b/lib/wx/src/gen/wxScrollWinEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrolledWindow.erl b/lib/wx/src/gen/wxScrolledWindow.erl
index e154643d05..7c807980b4 100644
--- a/lib/wx/src/gen/wxScrolledWindow.erl
+++ b/lib/wx/src/gen/wxScrolledWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
scroll/3,setScrollRate/3,setScrollbars/5,setScrollbars/6,setTargetWindow/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,24 +51,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -257,6 +259,14 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSetCursorEvent.erl b/lib/wx/src/gen/wxSetCursorEvent.erl
index 389966af82..0e2fbc5cba 100644
--- a/lib/wx/src/gen/wxSetCursorEvent.erl
+++ b/lib/wx/src/gen/wxSetCursorEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxShowEvent.erl b/lib/wx/src/gen/wxShowEvent.erl
index f476f476f7..3723213ebd 100644
--- a/lib/wx/src/gen/wxShowEvent.erl
+++ b/lib/wx/src/gen/wxShowEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSingleChoiceDialog.erl b/lib/wx/src/gen/wxSingleChoiceDialog.erl
index 79969f92a6..641cb2836f 100644
--- a/lib/wx/src/gen/wxSingleChoiceDialog.erl
+++ b/lib/wx/src/gen/wxSingleChoiceDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,getSelection/1,getStringSelection/1,new/0,new/4,new/5,setSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -222,6 +224,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSizeEvent.erl b/lib/wx/src/gen/wxSizeEvent.erl
index 5ecd021f29..5bef3a845d 100644
--- a/lib/wx/src/gen/wxSizeEvent.erl
+++ b/lib/wx/src/gen/wxSizeEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizer.erl b/lib/wx/src/gen/wxSizer.erl
index bc89350f6e..06f6fa7463 100644
--- a/lib/wx/src/gen/wxSizer.erl
+++ b/lib/wx/src/gen/wxSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizerFlags.erl b/lib/wx/src/gen/wxSizerFlags.erl
index e6aaa18b8a..1cbe38426f 100644
--- a/lib/wx/src/gen/wxSizerFlags.erl
+++ b/lib/wx/src/gen/wxSizerFlags.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizerItem.erl b/lib/wx/src/gen/wxSizerItem.erl
index 4711caff11..807941df5a 100644
--- a/lib/wx/src/gen/wxSizerItem.erl
+++ b/lib/wx/src/gen/wxSizerItem.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSlider.erl b/lib/wx/src/gen/wxSlider.erl
index 752253eaca..02103aed01 100644
--- a/lib/wx/src/gen/wxSlider.erl
+++ b/lib/wx/src/gen/wxSlider.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,10 +35,10 @@
setRange/3,setThumbLength/2,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,24 +50,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -246,6 +248,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSpinButton.erl b/lib/wx/src/gen/wxSpinButton.erl
index a09d041798..82b48f87da 100644
--- a/lib/wx/src/gen/wxSpinButton.erl
+++ b/lib/wx/src/gen/wxSpinButton.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
new/2,setRange/3,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -194,6 +196,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSpinCtrl.erl b/lib/wx/src/gen/wxSpinCtrl.erl
index 2e34024a41..89fa971543 100644
--- a/lib/wx/src/gen/wxSpinCtrl.erl
+++ b/lib/wx/src/gen/wxSpinCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
new/2,setRange/3,setSelection/3,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -231,6 +233,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSpinEvent.erl b/lib/wx/src/gen/wxSpinEvent.erl
index ea1f7b8718..21ebdd500f 100644
--- a/lib/wx/src/gen/wxSpinEvent.erl
+++ b/lib/wx/src/gen/wxSpinEvent.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSplashScreen.erl b/lib/wx/src/gen/wxSplashScreen.erl
index 10c1d4a2e7..fad8cfcd8e 100644
--- a/lib/wx/src/gen/wxSplashScreen.erl
+++ b/lib/wx/src/gen/wxSplashScreen.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,getSplashStyle/1,getTimeout/1,new/0,new/5,new/6]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -53,32 +54,32 @@
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
+ releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,
- setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,setMaxSize/2,
- setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setScrollPos/3,setScrollPos/4,
- setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,setStatusBarPane/2,
- setStatusText/2,setStatusText/3,setStatusWidths/2,setThemeEnabled/2,
- setTitle/2,setToolBar/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,showFullScreen/2,showFullScreen/3,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,
+ setStatusBarPane/2,setStatusText/2,setStatusText/3,setStatusWidths/2,
+ setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
+ thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
+ updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxSplashScreen/0]).
%% @hidden
@@ -229,6 +230,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxSplitterEvent.erl b/lib/wx/src/gen/wxSplitterEvent.erl
index 0b67a6867f..e8001ec540 100644
--- a/lib/wx/src/gen/wxSplitterEvent.erl
+++ b/lib/wx/src/gen/wxSplitterEvent.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSplitterWindow.erl b/lib/wx/src/gen/wxSplitterWindow.erl
index 1b54bfdebc..7db8dc60c4 100644
--- a/lib/wx/src/gen/wxSplitterWindow.erl
+++ b/lib/wx/src/gen/wxSplitterWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -36,10 +37,10 @@
unsplit/1,unsplit/2,updateSize/1]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -51,24 +52,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -357,6 +359,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStaticBitmap.erl b/lib/wx/src/gen/wxStaticBitmap.erl
index 40114da423..4da50262b9 100644
--- a/lib/wx/src/gen/wxStaticBitmap.erl
+++ b/lib/wx/src/gen/wxStaticBitmap.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -32,10 +33,10 @@
-export([create/4,create/5,destroy/1,getBitmap/1,new/0,new/3,new/4,setBitmap/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -47,24 +48,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -166,6 +168,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStaticBox.erl b/lib/wx/src/gen/wxStaticBox.erl
index e82d64a5c3..04584f23b2 100644
--- a/lib/wx/src/gen/wxStaticBox.erl
+++ b/lib/wx/src/gen/wxStaticBox.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -32,10 +33,10 @@
-export([create/4,create/5,destroy/1,new/0,new/3,new/4]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -47,24 +48,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -149,6 +151,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStaticBoxSizer.erl b/lib/wx/src/gen/wxStaticBoxSizer.erl
index 22f8c83ad5..9edf495679 100644
--- a/lib/wx/src/gen/wxStaticBoxSizer.erl
+++ b/lib/wx/src/gen/wxStaticBoxSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStaticLine.erl b/lib/wx/src/gen/wxStaticLine.erl
index d6c598d51c..6d23c5ac3d 100644
--- a/lib/wx/src/gen/wxStaticLine.erl
+++ b/lib/wx/src/gen/wxStaticLine.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,10 +34,10 @@
new/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -48,24 +49,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -166,6 +168,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStaticText.erl b/lib/wx/src/gen/wxStaticText.erl
index eed93fec5d..635f29a1e8 100644
--- a/lib/wx/src/gen/wxStaticText.erl
+++ b/lib/wx/src/gen/wxStaticText.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -32,10 +33,10 @@
-export([create/4,create/5,destroy/1,getLabel/1,new/0,new/3,new/4,setLabel/2,wrap/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -47,24 +48,25 @@
getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -172,6 +174,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
%% From wxControl
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStatusBar.erl b/lib/wx/src/gen/wxStatusBar.erl
index ce98a92de9..2cd0d4a43e 100644
--- a/lib/wx/src/gen/wxStatusBar.erl
+++ b/lib/wx/src/gen/wxStatusBar.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -34,10 +35,10 @@
setStatusStyles/2,setStatusText/2,setStatusText/3,setStatusWidths/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -49,24 +50,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -294,6 +296,14 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStdDialogButtonSizer.erl b/lib/wx/src/gen/wxStdDialogButtonSizer.erl
index 2878345600..2843eaf98b 100644
--- a/lib/wx/src/gen/wxStdDialogButtonSizer.erl
+++ b/lib/wx/src/gen/wxStdDialogButtonSizer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStyledTextCtrl.erl b/lib/wx/src/gen/wxStyledTextCtrl.erl
index 34b4c2a4ec..8e629db9ff 100644
--- a/lib/wx/src/gen/wxStyledTextCtrl.erl
+++ b/lib/wx/src/gen/wxStyledTextCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -134,10 +135,10 @@
wordRightExtend/1,wordStartPosition/3,wrapCount/2,zoomIn/1,zoomOut/1]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -149,27 +150,27 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2,
- setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,
- setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,
- setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
- setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ parent_class/1,popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,
+ popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
+ releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,screenToClient/2,
+ scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxStyledTextCtrl/0]).
%% @hidden
@@ -4077,6 +4078,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxStyledTextEvent.erl b/lib/wx/src/gen/wxStyledTextEvent.erl
index 7173404df8..d794673f69 100644
--- a/lib/wx/src/gen/wxStyledTextEvent.erl
+++ b/lib/wx/src/gen/wxStyledTextEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSysColourChangedEvent.erl b/lib/wx/src/gen/wxSysColourChangedEvent.erl
index c9a5fd1e06..308b399198 100644
--- a/lib/wx/src/gen/wxSysColourChangedEvent.erl
+++ b/lib/wx/src/gen/wxSysColourChangedEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSystemOptions.erl b/lib/wx/src/gen/wxSystemOptions.erl
index 5dd4a50f6a..fe2e1c98cd 100644
--- a/lib/wx/src/gen/wxSystemOptions.erl
+++ b/lib/wx/src/gen/wxSystemOptions.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSystemSettings.erl b/lib/wx/src/gen/wxSystemSettings.erl
index e4e9096d19..57fcf455dc 100644
--- a/lib/wx/src/gen/wxSystemSettings.erl
+++ b/lib/wx/src/gen/wxSystemSettings.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTaskBarIcon.erl b/lib/wx/src/gen/wxTaskBarIcon.erl
index be3862fd24..aab41f4645 100644
--- a/lib/wx/src/gen/wxTaskBarIcon.erl
+++ b/lib/wx/src/gen/wxTaskBarIcon.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTaskBarIconEvent.erl b/lib/wx/src/gen/wxTaskBarIconEvent.erl
index 0c57bdf017..199e4930c3 100644
--- a/lib/wx/src/gen/wxTaskBarIconEvent.erl
+++ b/lib/wx/src/gen/wxTaskBarIconEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextAttr.erl b/lib/wx/src/gen/wxTextAttr.erl
index 7f74cd3dc4..9d4361f742 100644
--- a/lib/wx/src/gen/wxTextAttr.erl
+++ b/lib/wx/src/gen/wxTextAttr.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextCtrl.erl b/lib/wx/src/gen/wxTextCtrl.erl
index 7e6852b9c8..5840812579 100644
--- a/lib/wx/src/gen/wxTextCtrl.erl
+++ b/lib/wx/src/gen/wxTextCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -40,10 +41,10 @@
setStyle/4,setValue/2,showPosition/2,undo/1,writeText/2,xYToPosition/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -55,24 +56,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -596,6 +598,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxTextDataObject.erl b/lib/wx/src/gen/wxTextDataObject.erl
index 0f780509e6..89e51b24cb 100644
--- a/lib/wx/src/gen/wxTextDataObject.erl
+++ b/lib/wx/src/gen/wxTextDataObject.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextEntryDialog.erl b/lib/wx/src/gen/wxTextEntryDialog.erl
index 1cc4bce0b9..a93c3857a8 100644
--- a/lib/wx/src/gen/wxTextEntryDialog.erl
+++ b/lib/wx/src/gen/wxTextEntryDialog.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -33,11 +34,11 @@
-export([destroy/1,getValue/1,new/2,new/3,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centerOnScreen/1,centerOnScreen/2,centre/1,centre/2,
- centreOnParent/1,centreOnParent/2,centreOnScreen/1,centreOnScreen/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centerOnScreen/1,centerOnScreen/2,
+ centre/1,centre/2,centreOnParent/1,centreOnParent/2,centreOnScreen/1,
+ centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
@@ -52,25 +53,26 @@
getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,
- isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setTitle/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
+ setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
+ setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
+ setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
@@ -210,6 +212,14 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxToggleButton.erl b/lib/wx/src/gen/wxToggleButton.erl
index 2cd1739754..dffb4b159d 100644
--- a/lib/wx/src/gen/wxToggleButton.erl
+++ b/lib/wx/src/gen/wxToggleButton.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -32,10 +33,10 @@
-export([create/4,create/5,destroy/1,getValue/1,new/0,new/3,new/4,setValue/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -47,24 +48,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -170,6 +172,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxToolBar.erl b/lib/wx/src/gen/wxToolBar.erl
index f8e4b7704a..b3cce2b6e9 100644
--- a/lib/wx/src/gen/wxToolBar.erl
+++ b/lib/wx/src/gen/wxToolBar.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -30,20 +31,21 @@
-module(wxToolBar).
-include("wxe.hrl").
-export([addCheckTool/4,addCheckTool/5,addControl/2,addRadioTool/4,addRadioTool/5,
- addSeparator/1,addTool/2,addTool/3,addTool/4,addTool/5,addTool/6,addTool/7,
- deleteTool/2,deleteToolByPos/2,enableTool/3,findById/2,findControl/2,
- findToolForPosition/3,getMargins/1,getToolBitmapSize/1,getToolEnabled/2,
- getToolLongHelp/2,getToolPacking/1,getToolPos/2,getToolSeparation/1,
- getToolShortHelp/2,getToolSize/1,getToolState/2,insertControl/3,insertSeparator/2,
- insertTool/3,insertTool/4,insertTool/5,insertTool/6,realize/1,removeTool/2,
- setMargins/3,setToolBitmapSize/2,setToolLongHelp/3,setToolPacking/2,
- setToolSeparation/2,setToolShortHelp/3,toggleTool/3]).
+ addSeparator/1,addStretchableSpace/1,addTool/2,addTool/3,addTool/4,
+ addTool/5,addTool/6,addTool/7,deleteTool/2,deleteToolByPos/2,enableTool/3,
+ findById/2,findControl/2,findToolForPosition/3,getMargins/1,getToolBitmapSize/1,
+ getToolEnabled/2,getToolLongHelp/2,getToolPacking/1,getToolPos/2,
+ getToolSeparation/1,getToolShortHelp/2,getToolSize/1,getToolState/2,
+ insertControl/3,insertSeparator/2,insertStretchableSpace/2,insertTool/3,
+ insertTool/4,insertTool/5,insertTool/6,realize/1,removeTool/2,setMargins/3,
+ setToolBitmapSize/2,setToolLongHelp/3,setToolPacking/2,setToolSeparation/2,
+ setToolShortHelp/3,toggleTool/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -55,24 +57,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -327,6 +330,23 @@ addRadioTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Label,#wx_ref{type=BitmapT,r
wxe_util:call(?wxToolBar_AddRadioTool,
<<ThisRef:32/?UI,Toolid:32/?UI,(byte_size(Label_UC)):32/?UI,(Label_UC)/binary, 0:(((8- ((4+byte_size(Label_UC)) band 16#7)) band 16#7))/unit:8,BitmapRef:32/?UI, 0:32,BinOpt/binary>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbar.html#wxtoolbaraddstretchablespace">external documentation</a>.
+-spec addStretchableSpace(This) -> wx:wx_object() when
+ This::wxToolBar().
+addStretchableSpace(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxToolBar),
+ wxe_util:call(?wxToolBar_AddStretchableSpace,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbar.html#wxtoolbarinsertstretchablespace">external documentation</a>.
+-spec insertStretchableSpace(This, Pos) -> wx:wx_object() when
+ This::wxToolBar(), Pos::integer().
+insertStretchableSpace(#wx_ref{type=ThisT,ref=ThisRef},Pos)
+ when is_integer(Pos) ->
+ ?CLASS(ThisT,wxToolBar),
+ wxe_util:call(?wxToolBar_InsertStretchableSpace,
+ <<ThisRef:32/?UI,Pos:32/?UI>>).
+
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbar.html#wxtoolbardeletetool">external documentation</a>.
-spec deleteTool(This, Toolid) -> boolean() when
This::wxToolBar(), Toolid::integer().
@@ -654,6 +674,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxToolTip.erl b/lib/wx/src/gen/wxToolTip.erl
index 1df04adea8..b462dac72a 100644
--- a/lib/wx/src/gen/wxToolTip.erl
+++ b/lib/wx/src/gen/wxToolTip.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxToolbook.erl b/lib/wx/src/gen/wxToolbook.erl
index f820471ad7..cf77aefd8a 100644
--- a/lib/wx/src/gen/wxToolbook.erl
+++ b/lib/wx/src/gen/wxToolbook.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -37,10 +38,10 @@
setPageSize/2,setPageText/3,setSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -52,24 +53,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -382,6 +384,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxTopLevelWindow.erl b/lib/wx/src/gen/wxTopLevelWindow.erl
index 0a6f830d23..72813b0073 100644
--- a/lib/wx/src/gen/wxTopLevelWindow.erl
+++ b/lib/wx/src/gen/wxTopLevelWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -35,10 +36,10 @@
showFullScreen/2,showFullScreen/3]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -50,24 +51,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -300,6 +302,14 @@ showFullScreen(#wx_ref{type=ThisT,ref=ThisRef},Show, Options)
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl
index c25310b284..43dee9107d 100644
--- a/lib/wx/src/gen/wxTreeCtrl.erl
+++ b/lib/wx/src/gen/wxTreeCtrl.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -53,10 +54,10 @@
unselectItem/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -68,24 +69,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,show/1,
show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,
updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -944,6 +946,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxTreeEvent.erl b/lib/wx/src/gen/wxTreeEvent.erl
index fd28cd3fd7..54cdf9ef66 100644
--- a/lib/wx/src/gen/wxTreeEvent.erl
+++ b/lib/wx/src/gen/wxTreeEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTreebook.erl b/lib/wx/src/gen/wxTreebook.erl
index 14c04eb373..1900f47289 100644
--- a/lib/wx/src/gen/wxTreebook.erl
+++ b/lib/wx/src/gen/wxTreebook.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -38,10 +39,10 @@
setPageSize/2,setPageText/3,setSelection/2]).
%% inherited exports
--export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+-export([cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,center/2,
+ centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
@@ -53,24 +54,25 @@
getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -438,6 +440,14 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
+%% @hidden
+isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
+%% @hidden
+canSetTransparent(This) -> wxWindow:canSetTransparent(This).
+%% @hidden
+setTransparent(This,Alpha) -> wxWindow:setTransparent(This,Alpha).
+%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
validate(This) -> wxWindow:validate(This).
diff --git a/lib/wx/src/gen/wxUpdateUIEvent.erl b/lib/wx/src/gen/wxUpdateUIEvent.erl
index a51fff0a69..5d4fb6e2b0 100644
--- a/lib/wx/src/gen/wxUpdateUIEvent.erl
+++ b/lib/wx/src/gen/wxUpdateUIEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindow.erl b/lib/wx/src/gen/wxWindow.erl
index 97af96f31d..a8a61d547b 100644
--- a/lib/wx/src/gen/wxWindow.erl
+++ b/lib/wx/src/gen/wxWindow.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -27,13 +28,13 @@
-module(wxWindow).
-include("wxe.hrl").
--export(['Destroy'/1,cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
- centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
- clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
- convertDialogToPixels/2,convertPixelsToDialog/2,destroy/1,destroyChildren/1,
- disable/1,enable/1,enable/2,findFocus/0,findWindow/2,findWindowById/1,
- findWindowById/2,findWindowByLabel/1,findWindowByLabel/2,findWindowByName/1,
- findWindowByName/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+-export(['Destroy'/1,cacheBestSize/2,canSetTransparent/1,captureMouse/1,center/1,
+ center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
+ centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
+ close/1,close/2,convertDialogToPixels/2,convertPixelsToDialog/2,destroy/1,
+ destroyChildren/1,disable/1,enable/1,enable/2,findFocus/0,findWindow/2,
+ findWindowById/1,findWindowById/2,findWindowByLabel/1,findWindowByLabel/2,
+ findWindowByName/1,findWindowByName/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCapture/0,
getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
@@ -44,24 +45,24 @@
getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
- lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,new/0,new/2,new/3,pageDown/1,
- pageUp/1,popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,
- popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
- releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,screenToClient/2,
- scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,new/0,new/2,new/3,pageDown/1,pageUp/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
@@ -1909,6 +1910,40 @@ warpPointer(#wx_ref{type=ThisT,ref=ThisRef},X,Y)
wxe_util:cast(?wxWindow_WarpPointer,
<<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowsettransparent">external documentation</a>.
+-spec setTransparent(This, Alpha) -> boolean() when
+ This::wxWindow(), Alpha::integer().
+setTransparent(#wx_ref{type=ThisT,ref=ThisRef},Alpha)
+ when is_integer(Alpha) ->
+ ?CLASS(ThisT,wxWindow),
+ wxe_util:call(?wxWindow_SetTransparent,
+ <<ThisRef:32/?UI,Alpha:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowcansettransparent">external documentation</a>.
+-spec canSetTransparent(This) -> boolean() when
+ This::wxWindow().
+canSetTransparent(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxWindow),
+ wxe_util:call(?wxWindow_CanSetTransparent,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowisdoublebuffered">external documentation</a>.
+-spec isDoubleBuffered(This) -> boolean() when
+ This::wxWindow().
+isDoubleBuffered(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxWindow),
+ wxe_util:call(?wxWindow_IsDoubleBuffered,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowsetdoublebuffered">external documentation</a>.
+-spec setDoubleBuffered(This, On) -> ok when
+ This::wxWindow(), On::boolean().
+setDoubleBuffered(#wx_ref{type=ThisT,ref=ThisRef},On)
+ when is_boolean(On) ->
+ ?CLASS(ThisT,wxWindow),
+ wxe_util:cast(?wxWindow_SetDoubleBuffered,
+ <<ThisRef:32/?UI,(wxe_util:from_bool(On)):32/?UI>>).
+
%% @doc Destroys this object, do not use object again
-spec destroy(This::wxWindow()) -> ok.
destroy(Obj=#wx_ref{type=Type}) ->
diff --git a/lib/wx/src/gen/wxWindowCreateEvent.erl b/lib/wx/src/gen/wxWindowCreateEvent.erl
index 6688d54703..d5b1c0d256 100644
--- a/lib/wx/src/gen/wxWindowCreateEvent.erl
+++ b/lib/wx/src/gen/wxWindowCreateEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindowDC.erl b/lib/wx/src/gen/wxWindowDC.erl
index 6bb303cfe6..96f932d3d5 100644
--- a/lib/wx/src/gen/wxWindowDC.erl
+++ b/lib/wx/src/gen/wxWindowDC.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindowDestroyEvent.erl b/lib/wx/src/gen/wxWindowDestroyEvent.erl
index c21d4787b8..d8e15397f7 100644
--- a/lib/wx/src/gen/wxWindowDestroyEvent.erl
+++ b/lib/wx/src/gen/wxWindowDestroyEvent.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxXmlResource.erl b/lib/wx/src/gen/wxXmlResource.erl
index 30290b4f9a..fec9a5b4a9 100644
--- a/lib/wx/src/gen/wxXmlResource.erl
+++ b/lib/wx/src/gen/wxXmlResource.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wx_misc.erl b/lib/wx/src/gen/wx_misc.erl
index 397d48b727..44a9309f7e 100644
--- a/lib/wx/src/gen/wx_misc.erl
+++ b/lib/wx/src/gen/wx_misc.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index 7d4db9ba97..a2462a6fb2 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -191,3155 +192,3190 @@ wxdebug_table() ->
{281, {wxWindow, updateWindowUI, 1}},
{282, {wxWindow, validate, 0}},
{283, {wxWindow, warpPointer, 2}},
- {284, {wxTopLevelWindow, getIcon, 0}},
- {285, {wxTopLevelWindow, getIcons, 0}},
- {286, {wxTopLevelWindow, getTitle, 0}},
- {287, {wxTopLevelWindow, isActive, 0}},
- {288, {wxTopLevelWindow, iconize, 1}},
- {289, {wxTopLevelWindow, isFullScreen, 0}},
- {290, {wxTopLevelWindow, isIconized, 0}},
- {291, {wxTopLevelWindow, isMaximized, 0}},
- {292, {wxTopLevelWindow, maximize, 1}},
- {293, {wxTopLevelWindow, requestUserAttention, 1}},
- {294, {wxTopLevelWindow, setIcon, 1}},
- {295, {wxTopLevelWindow, setIcons, 1}},
- {296, {wxTopLevelWindow, centerOnScreen, 1}},
- {297, {wxTopLevelWindow, centreOnScreen, 1}},
- {299, {wxTopLevelWindow, setShape, 1}},
- {300, {wxTopLevelWindow, setTitle, 1}},
- {301, {wxTopLevelWindow, showFullScreen, 2}},
- {303, {wxFrame, new_4, 4}},
- {304, {wxFrame, new_0, 0}},
- {306, {wxFrame, destruct, 0}},
- {307, {wxFrame, create, 4}},
- {308, {wxFrame, createStatusBar, 1}},
- {309, {wxFrame, createToolBar, 1}},
- {310, {wxFrame, getClientAreaOrigin, 0}},
- {311, {wxFrame, getMenuBar, 0}},
- {312, {wxFrame, getStatusBar, 0}},
- {313, {wxFrame, getStatusBarPane, 0}},
- {314, {wxFrame, getToolBar, 0}},
- {315, {wxFrame, processCommand, 1}},
- {316, {wxFrame, sendSizeEvent, 0}},
- {317, {wxFrame, setMenuBar, 1}},
- {318, {wxFrame, setStatusBar, 1}},
- {319, {wxFrame, setStatusBarPane, 1}},
- {320, {wxFrame, setStatusText, 2}},
- {321, {wxFrame, setStatusWidths, 2}},
- {322, {wxFrame, setToolBar, 1}},
- {323, {wxMiniFrame, new_0, 0}},
- {324, {wxMiniFrame, new_4, 4}},
- {325, {wxMiniFrame, create, 4}},
- {326, {wxMiniFrame, 'Destroy', undefined}},
- {327, {wxSplashScreen, new_0, 0}},
- {328, {wxSplashScreen, new_6, 6}},
- {329, {wxSplashScreen, destruct, 0}},
- {330, {wxSplashScreen, getSplashStyle, 0}},
- {331, {wxSplashScreen, getTimeout, 0}},
- {332, {wxPanel, new_0, 0}},
- {333, {wxPanel, new_6, 6}},
- {334, {wxPanel, new_2, 2}},
- {335, {wxPanel, destruct, 0}},
- {336, {wxPanel, initDialog, 0}},
- {337, {wxPanel, setFocusIgnoringChildren, 0}},
- {338, {wxScrolledWindow, new_0, 0}},
- {339, {wxScrolledWindow, new_2, 2}},
- {340, {wxScrolledWindow, destruct, 0}},
- {341, {wxScrolledWindow, calcScrolledPosition_4, 4}},
- {342, {wxScrolledWindow, calcScrolledPosition_1, 1}},
- {343, {wxScrolledWindow, calcUnscrolledPosition_4, 4}},
- {344, {wxScrolledWindow, calcUnscrolledPosition_1, 1}},
- {345, {wxScrolledWindow, enableScrolling, 2}},
- {346, {wxScrolledWindow, getScrollPixelsPerUnit, 2}},
- {347, {wxScrolledWindow, getViewStart, 2}},
- {348, {wxScrolledWindow, doPrepareDC, 1}},
- {349, {wxScrolledWindow, prepareDC, 1}},
- {350, {wxScrolledWindow, scroll, 2}},
- {351, {wxScrolledWindow, setScrollbars, 5}},
- {352, {wxScrolledWindow, setScrollRate, 2}},
- {353, {wxScrolledWindow, setTargetWindow, 1}},
- {354, {wxSashWindow, new_0, 0}},
- {355, {wxSashWindow, new_2, 2}},
- {356, {wxSashWindow, destruct, 0}},
- {357, {wxSashWindow, getSashVisible, 1}},
- {358, {wxSashWindow, getMaximumSizeX, 0}},
- {359, {wxSashWindow, getMaximumSizeY, 0}},
- {360, {wxSashWindow, getMinimumSizeX, 0}},
- {361, {wxSashWindow, getMinimumSizeY, 0}},
- {362, {wxSashWindow, setMaximumSizeX, 1}},
- {363, {wxSashWindow, setMaximumSizeY, 1}},
- {364, {wxSashWindow, setMinimumSizeX, 1}},
- {365, {wxSashWindow, setMinimumSizeY, 1}},
- {366, {wxSashWindow, setSashVisible, 2}},
- {367, {wxSashLayoutWindow, new_0, 0}},
- {368, {wxSashLayoutWindow, new_2, 2}},
- {369, {wxSashLayoutWindow, create, 2}},
- {370, {wxSashLayoutWindow, getAlignment, 0}},
- {371, {wxSashLayoutWindow, getOrientation, 0}},
- {372, {wxSashLayoutWindow, setAlignment, 1}},
- {373, {wxSashLayoutWindow, setDefaultSize, 1}},
- {374, {wxSashLayoutWindow, setOrientation, 1}},
- {375, {wxSashLayoutWindow, 'Destroy', undefined}},
- {376, {wxGrid, new_0, 0}},
- {377, {wxGrid, new_3, 3}},
- {378, {wxGrid, new_4, 4}},
- {379, {wxGrid, destruct, 0}},
- {380, {wxGrid, appendCols, 1}},
- {381, {wxGrid, appendRows, 1}},
- {382, {wxGrid, autoSize, 0}},
- {383, {wxGrid, autoSizeColumn, 2}},
- {384, {wxGrid, autoSizeColumns, 1}},
- {385, {wxGrid, autoSizeRow, 2}},
- {386, {wxGrid, autoSizeRows, 1}},
- {387, {wxGrid, beginBatch, 0}},
- {388, {wxGrid, blockToDeviceRect, 2}},
- {389, {wxGrid, canDragColSize, 0}},
- {390, {wxGrid, canDragRowSize, 0}},
- {391, {wxGrid, canDragGridSize, 0}},
- {392, {wxGrid, canEnableCellControl, 0}},
- {393, {wxGrid, cellToRect_2, 2}},
- {394, {wxGrid, cellToRect_1, 1}},
- {395, {wxGrid, clearGrid, 0}},
- {396, {wxGrid, clearSelection, 0}},
- {397, {wxGrid, createGrid, 3}},
- {398, {wxGrid, deleteCols, 1}},
- {399, {wxGrid, deleteRows, 1}},
- {400, {wxGrid, disableCellEditControl, 0}},
- {401, {wxGrid, disableDragColSize, 0}},
- {402, {wxGrid, disableDragGridSize, 0}},
- {403, {wxGrid, disableDragRowSize, 0}},
- {404, {wxGrid, enableCellEditControl, 1}},
- {405, {wxGrid, enableDragColSize, 1}},
- {406, {wxGrid, enableDragGridSize, 1}},
- {407, {wxGrid, enableDragRowSize, 1}},
- {408, {wxGrid, enableEditing, 1}},
- {409, {wxGrid, enableGridLines, 1}},
- {410, {wxGrid, endBatch, 0}},
- {411, {wxGrid, fit, 0}},
- {412, {wxGrid, forceRefresh, 0}},
- {413, {wxGrid, getBatchCount, 0}},
- {414, {wxGrid, getCellAlignment, 4}},
- {415, {wxGrid, getCellBackgroundColour, 2}},
- {416, {wxGrid, getCellEditor, 2}},
- {417, {wxGrid, getCellFont, 2}},
- {418, {wxGrid, getCellRenderer, 2}},
- {419, {wxGrid, getCellTextColour, 2}},
- {420, {wxGrid, getCellValue_2, 2}},
- {421, {wxGrid, getCellValue_1, 1}},
- {422, {wxGrid, getColLabelAlignment, 2}},
- {423, {wxGrid, getColLabelSize, 0}},
- {424, {wxGrid, getColLabelValue, 1}},
- {425, {wxGrid, getColMinimalAcceptableWidth, 0}},
- {426, {wxGrid, getDefaultCellAlignment, 2}},
- {427, {wxGrid, getDefaultCellBackgroundColour, 0}},
- {428, {wxGrid, getDefaultCellFont, 0}},
- {429, {wxGrid, getDefaultCellTextColour, 0}},
- {430, {wxGrid, getDefaultColLabelSize, 0}},
- {431, {wxGrid, getDefaultColSize, 0}},
- {432, {wxGrid, getDefaultEditor, 0}},
- {433, {wxGrid, getDefaultEditorForCell_2, 2}},
- {434, {wxGrid, getDefaultEditorForCell_1, 1}},
- {435, {wxGrid, getDefaultEditorForType, 1}},
- {436, {wxGrid, getDefaultRenderer, 0}},
- {437, {wxGrid, getDefaultRendererForCell, 2}},
- {438, {wxGrid, getDefaultRendererForType, 1}},
- {439, {wxGrid, getDefaultRowLabelSize, 0}},
- {440, {wxGrid, getDefaultRowSize, 0}},
- {441, {wxGrid, getGridCursorCol, 0}},
- {442, {wxGrid, getGridCursorRow, 0}},
- {443, {wxGrid, getGridLineColour, 0}},
- {444, {wxGrid, gridLinesEnabled, 0}},
- {445, {wxGrid, getLabelBackgroundColour, 0}},
- {446, {wxGrid, getLabelFont, 0}},
- {447, {wxGrid, getLabelTextColour, 0}},
- {448, {wxGrid, getNumberCols, 0}},
- {449, {wxGrid, getNumberRows, 0}},
- {450, {wxGrid, getOrCreateCellAttr, 2}},
- {451, {wxGrid, getRowMinimalAcceptableHeight, 0}},
- {452, {wxGrid, getRowLabelAlignment, 2}},
- {453, {wxGrid, getRowLabelSize, 0}},
- {454, {wxGrid, getRowLabelValue, 1}},
- {455, {wxGrid, getRowSize, 1}},
- {456, {wxGrid, getScrollLineX, 0}},
- {457, {wxGrid, getScrollLineY, 0}},
- {458, {wxGrid, getSelectedCells, 0}},
- {459, {wxGrid, getSelectedCols, 0}},
- {460, {wxGrid, getSelectedRows, 0}},
- {461, {wxGrid, getSelectionBackground, 0}},
- {462, {wxGrid, getSelectionBlockTopLeft, 0}},
- {463, {wxGrid, getSelectionBlockBottomRight, 0}},
- {464, {wxGrid, getSelectionForeground, 0}},
- {465, {wxGrid, getViewWidth, 0}},
- {466, {wxGrid, getGridWindow, 0}},
- {467, {wxGrid, getGridRowLabelWindow, 0}},
- {468, {wxGrid, getGridColLabelWindow, 0}},
- {469, {wxGrid, getGridCornerLabelWindow, 0}},
- {470, {wxGrid, hideCellEditControl, 0}},
- {471, {wxGrid, insertCols, 1}},
- {472, {wxGrid, insertRows, 1}},
- {473, {wxGrid, isCellEditControlEnabled, 0}},
- {474, {wxGrid, isCurrentCellReadOnly, 0}},
- {475, {wxGrid, isEditable, 0}},
- {476, {wxGrid, isInSelection_2, 2}},
- {477, {wxGrid, isInSelection_1, 1}},
- {478, {wxGrid, isReadOnly, 2}},
- {479, {wxGrid, isSelection, 0}},
- {480, {wxGrid, isVisible_3, 3}},
- {481, {wxGrid, isVisible_2, 2}},
- {482, {wxGrid, makeCellVisible_2, 2}},
- {483, {wxGrid, makeCellVisible_1, 1}},
- {484, {wxGrid, moveCursorDown, 1}},
- {485, {wxGrid, moveCursorLeft, 1}},
- {486, {wxGrid, moveCursorRight, 1}},
- {487, {wxGrid, moveCursorUp, 1}},
- {488, {wxGrid, moveCursorDownBlock, 1}},
- {489, {wxGrid, moveCursorLeftBlock, 1}},
- {490, {wxGrid, moveCursorRightBlock, 1}},
- {491, {wxGrid, moveCursorUpBlock, 1}},
- {492, {wxGrid, movePageDown, 0}},
- {493, {wxGrid, movePageUp, 0}},
- {494, {wxGrid, registerDataType, 3}},
- {495, {wxGrid, saveEditControlValue, 0}},
- {496, {wxGrid, selectAll, 0}},
- {497, {wxGrid, selectBlock_5, 5}},
- {498, {wxGrid, selectBlock_3, 3}},
- {499, {wxGrid, selectCol, 2}},
- {500, {wxGrid, selectRow, 2}},
- {501, {wxGrid, setCellAlignment_4, 4}},
- {502, {wxGrid, setCellAlignment_3, 3}},
- {503, {wxGrid, setCellAlignment_1, 1}},
- {504, {wxGrid, setCellBackgroundColour_3_0, 3}},
- {505, {wxGrid, setCellBackgroundColour_1, 1}},
- {506, {wxGrid, setCellBackgroundColour_3_1, 3}},
- {507, {wxGrid, setCellEditor, 3}},
- {508, {wxGrid, setCellFont, 3}},
- {509, {wxGrid, setCellRenderer, 3}},
- {510, {wxGrid, setCellTextColour_3_0, 3}},
- {511, {wxGrid, setCellTextColour_3_1, 3}},
- {512, {wxGrid, setCellTextColour_1, 1}},
- {513, {wxGrid, setCellValue_3_0, 3}},
- {514, {wxGrid, setCellValue_2, 2}},
- {515, {wxGrid, setCellValue_3_1, 3}},
- {516, {wxGrid, setColAttr, 2}},
- {517, {wxGrid, setColFormatBool, 1}},
- {518, {wxGrid, setColFormatNumber, 1}},
- {519, {wxGrid, setColFormatFloat, 2}},
- {520, {wxGrid, setColFormatCustom, 2}},
- {521, {wxGrid, setColLabelAlignment, 2}},
- {522, {wxGrid, setColLabelSize, 1}},
- {523, {wxGrid, setColLabelValue, 2}},
- {524, {wxGrid, setColMinimalWidth, 2}},
- {525, {wxGrid, setColMinimalAcceptableWidth, 1}},
- {526, {wxGrid, setColSize, 2}},
- {527, {wxGrid, setDefaultCellAlignment, 2}},
- {528, {wxGrid, setDefaultCellBackgroundColour, 1}},
- {529, {wxGrid, setDefaultCellFont, 1}},
- {530, {wxGrid, setDefaultCellTextColour, 1}},
- {531, {wxGrid, setDefaultEditor, 1}},
- {532, {wxGrid, setDefaultRenderer, 1}},
- {533, {wxGrid, setDefaultColSize, 2}},
- {534, {wxGrid, setDefaultRowSize, 2}},
- {535, {wxGrid, setGridCursor, 2}},
- {536, {wxGrid, setGridLineColour, 1}},
- {537, {wxGrid, setLabelBackgroundColour, 1}},
- {538, {wxGrid, setLabelFont, 1}},
- {539, {wxGrid, setLabelTextColour, 1}},
- {540, {wxGrid, setMargins, 2}},
- {541, {wxGrid, setReadOnly, 3}},
- {542, {wxGrid, setRowAttr, 2}},
- {543, {wxGrid, setRowLabelAlignment, 2}},
- {544, {wxGrid, setRowLabelSize, 1}},
- {545, {wxGrid, setRowLabelValue, 2}},
- {546, {wxGrid, setRowMinimalHeight, 2}},
- {547, {wxGrid, setRowMinimalAcceptableHeight, 1}},
- {548, {wxGrid, setRowSize, 2}},
- {549, {wxGrid, setScrollLineX, 1}},
- {550, {wxGrid, setScrollLineY, 1}},
- {551, {wxGrid, setSelectionBackground, 1}},
- {552, {wxGrid, setSelectionForeground, 1}},
- {553, {wxGrid, setSelectionMode, 1}},
- {554, {wxGrid, showCellEditControl, 0}},
- {555, {wxGrid, xToCol, 2}},
- {556, {wxGrid, xToEdgeOfCol, 1}},
- {557, {wxGrid, yToEdgeOfRow, 1}},
- {558, {wxGrid, yToRow, 1}},
- {559, {wxGridCellRenderer, draw, 7}},
- {560, {wxGridCellRenderer, getBestSize, 5}},
- {561, {wxGridCellEditor, create, 3}},
- {562, {wxGridCellEditor, isCreated, 0}},
- {563, {wxGridCellEditor, setSize, 1}},
- {564, {wxGridCellEditor, show, 2}},
- {565, {wxGridCellEditor, paintBackground, 2}},
- {566, {wxGridCellEditor, beginEdit, 3}},
- {567, {wxGridCellEditor, endEdit, 3}},
- {568, {wxGridCellEditor, reset, 0}},
- {569, {wxGridCellEditor, startingKey, 1}},
- {570, {wxGridCellEditor, startingClick, 0}},
- {571, {wxGridCellEditor, handleReturn, 1}},
- {572, {wxGridCellBoolRenderer, new, 0}},
- {573, {wxGridCellBoolRenderer, 'Destroy', undefined}},
- {574, {wxGridCellBoolEditor, new, 0}},
- {575, {wxGridCellBoolEditor, isTrueValue, 1}},
- {576, {wxGridCellBoolEditor, useStringValues, 1}},
- {577, {wxGridCellBoolEditor, 'Destroy', undefined}},
- {578, {wxGridCellFloatRenderer, new, 1}},
- {579, {wxGridCellFloatRenderer, getPrecision, 0}},
- {580, {wxGridCellFloatRenderer, getWidth, 0}},
- {581, {wxGridCellFloatRenderer, setParameters, 1}},
- {582, {wxGridCellFloatRenderer, setPrecision, 1}},
- {583, {wxGridCellFloatRenderer, setWidth, 1}},
- {584, {wxGridCellFloatRenderer, 'Destroy', undefined}},
- {585, {wxGridCellFloatEditor, new, 1}},
- {586, {wxGridCellFloatEditor, setParameters, 1}},
- {587, {wxGridCellFloatEditor, 'Destroy', undefined}},
- {588, {wxGridCellStringRenderer, new, 0}},
- {589, {wxGridCellStringRenderer, 'Destroy', undefined}},
- {590, {wxGridCellTextEditor, new, 0}},
- {591, {wxGridCellTextEditor, setParameters, 1}},
- {592, {wxGridCellTextEditor, 'Destroy', undefined}},
- {594, {wxGridCellChoiceEditor, new, 2}},
- {595, {wxGridCellChoiceEditor, setParameters, 1}},
- {596, {wxGridCellChoiceEditor, 'Destroy', undefined}},
- {597, {wxGridCellNumberRenderer, new, 0}},
- {598, {wxGridCellNumberRenderer, 'Destroy', undefined}},
- {599, {wxGridCellNumberEditor, new, 1}},
- {600, {wxGridCellNumberEditor, getValue, 0}},
- {601, {wxGridCellNumberEditor, setParameters, 1}},
- {602, {wxGridCellNumberEditor, 'Destroy', undefined}},
- {603, {wxGridCellAttr, setTextColour, 1}},
- {604, {wxGridCellAttr, setBackgroundColour, 1}},
- {605, {wxGridCellAttr, setFont, 1}},
- {606, {wxGridCellAttr, setAlignment, 2}},
- {607, {wxGridCellAttr, setReadOnly, 1}},
- {608, {wxGridCellAttr, setRenderer, 1}},
- {609, {wxGridCellAttr, setEditor, 1}},
- {610, {wxGridCellAttr, hasTextColour, 0}},
- {611, {wxGridCellAttr, hasBackgroundColour, 0}},
- {612, {wxGridCellAttr, hasFont, 0}},
- {613, {wxGridCellAttr, hasAlignment, 0}},
- {614, {wxGridCellAttr, hasRenderer, 0}},
- {615, {wxGridCellAttr, hasEditor, 0}},
- {616, {wxGridCellAttr, getTextColour, 0}},
- {617, {wxGridCellAttr, getBackgroundColour, 0}},
- {618, {wxGridCellAttr, getFont, 0}},
- {619, {wxGridCellAttr, getAlignment, 2}},
- {620, {wxGridCellAttr, getRenderer, 3}},
- {621, {wxGridCellAttr, getEditor, 3}},
- {622, {wxGridCellAttr, isReadOnly, 0}},
- {623, {wxGridCellAttr, setDefAttr, 1}},
- {624, {wxDC, blit, 5}},
- {625, {wxDC, calcBoundingBox, 2}},
- {626, {wxDC, clear, 0}},
- {627, {wxDC, computeScaleAndOrigin, 0}},
- {628, {wxDC, crossHair, 1}},
- {629, {wxDC, destroyClippingRegion, 0}},
- {630, {wxDC, deviceToLogicalX, 1}},
- {631, {wxDC, deviceToLogicalXRel, 1}},
- {632, {wxDC, deviceToLogicalY, 1}},
- {633, {wxDC, deviceToLogicalYRel, 1}},
- {634, {wxDC, drawArc, 3}},
- {635, {wxDC, drawBitmap, 3}},
- {636, {wxDC, drawCheckMark, 1}},
- {637, {wxDC, drawCircle, 2}},
- {639, {wxDC, drawEllipse_2, 2}},
- {640, {wxDC, drawEllipse_1, 1}},
- {641, {wxDC, drawEllipticArc, 4}},
- {642, {wxDC, drawIcon, 2}},
- {643, {wxDC, drawLabel, 3}},
- {644, {wxDC, drawLine, 2}},
- {645, {wxDC, drawLines, 3}},
- {647, {wxDC, drawPolygon, 3}},
- {649, {wxDC, drawPoint, 1}},
- {651, {wxDC, drawRectangle_2, 2}},
- {652, {wxDC, drawRectangle_1, 1}},
- {653, {wxDC, drawRotatedText, 3}},
- {655, {wxDC, drawRoundedRectangle_3, 3}},
- {656, {wxDC, drawRoundedRectangle_2, 2}},
- {657, {wxDC, drawText, 2}},
- {658, {wxDC, endDoc, 0}},
- {659, {wxDC, endPage, 0}},
- {660, {wxDC, floodFill, 3}},
- {661, {wxDC, getBackground, 0}},
- {662, {wxDC, getBackgroundMode, 0}},
- {663, {wxDC, getBrush, 0}},
- {664, {wxDC, getCharHeight, 0}},
- {665, {wxDC, getCharWidth, 0}},
- {666, {wxDC, getClippingBox, 4}},
- {668, {wxDC, getFont, 0}},
- {669, {wxDC, getLayoutDirection, 0}},
- {670, {wxDC, getLogicalFunction, 0}},
- {671, {wxDC, getMapMode, 0}},
- {672, {wxDC, getMultiLineTextExtent_4, 4}},
- {673, {wxDC, getMultiLineTextExtent_1, 1}},
- {674, {wxDC, getPartialTextExtents, 2}},
- {675, {wxDC, getPen, 0}},
- {676, {wxDC, getPixel, 2}},
- {677, {wxDC, getPPI, 0}},
- {679, {wxDC, getSize, 0}},
- {681, {wxDC, getSizeMM, 0}},
- {682, {wxDC, getTextBackground, 0}},
- {683, {wxDC, getTextExtent_4, 4}},
- {684, {wxDC, getTextExtent_1, 1}},
- {686, {wxDC, getTextForeground, 0}},
- {687, {wxDC, getUserScale, 2}},
- {688, {wxDC, gradientFillConcentric_3, 3}},
- {689, {wxDC, gradientFillConcentric_4, 4}},
- {690, {wxDC, gradientFillLinear, 4}},
- {691, {wxDC, logicalToDeviceX, 1}},
- {692, {wxDC, logicalToDeviceXRel, 1}},
- {693, {wxDC, logicalToDeviceY, 1}},
- {694, {wxDC, logicalToDeviceYRel, 1}},
- {695, {wxDC, maxX, 0}},
- {696, {wxDC, maxY, 0}},
- {697, {wxDC, minX, 0}},
- {698, {wxDC, minY, 0}},
- {699, {wxDC, isOk, 0}},
- {700, {wxDC, resetBoundingBox, 0}},
- {701, {wxDC, setAxisOrientation, 2}},
- {702, {wxDC, setBackground, 1}},
- {703, {wxDC, setBackgroundMode, 1}},
- {704, {wxDC, setBrush, 1}},
- {706, {wxDC, setClippingRegion_2, 2}},
- {707, {wxDC, setClippingRegion_1_1, 1}},
- {708, {wxDC, setClippingRegion_1_0, 1}},
- {709, {wxDC, setDeviceOrigin, 2}},
- {710, {wxDC, setFont, 1}},
- {711, {wxDC, setLayoutDirection, 1}},
- {712, {wxDC, setLogicalFunction, 1}},
- {713, {wxDC, setMapMode, 1}},
- {714, {wxDC, setPalette, 1}},
- {715, {wxDC, setPen, 1}},
- {716, {wxDC, setTextBackground, 1}},
- {717, {wxDC, setTextForeground, 1}},
- {718, {wxDC, setUserScale, 2}},
- {719, {wxDC, startDoc, 1}},
- {720, {wxDC, startPage, 0}},
- {721, {wxMirrorDC, new, 2}},
- {722, {wxMirrorDC, 'Destroy', undefined}},
- {723, {wxScreenDC, new, 0}},
- {724, {wxScreenDC, destruct, 0}},
- {725, {wxPostScriptDC, new_0, 0}},
- {726, {wxPostScriptDC, new_1, 1}},
- {727, {wxPostScriptDC, destruct, 0}},
- {728, {wxPostScriptDC, setResolution, 1}},
- {729, {wxPostScriptDC, getResolution, 0}},
- {730, {wxWindowDC, new_0, 0}},
- {731, {wxWindowDC, new_1, 1}},
- {732, {wxWindowDC, destruct, 0}},
- {733, {wxClientDC, new_0, 0}},
- {734, {wxClientDC, new_1, 1}},
- {735, {wxClientDC, 'Destroy', undefined}},
- {736, {wxPaintDC, new_0, 0}},
- {737, {wxPaintDC, new_1, 1}},
- {738, {wxPaintDC, 'Destroy', undefined}},
- {740, {wxMemoryDC, new_1_0, 1}},
- {741, {wxMemoryDC, new_1_1, 1}},
- {742, {wxMemoryDC, new_0, 0}},
- {744, {wxMemoryDC, destruct, 0}},
- {745, {wxMemoryDC, selectObject, 1}},
- {746, {wxMemoryDC, selectObjectAsSource, 1}},
- {747, {wxBufferedDC, new_0, 0}},
- {748, {wxBufferedDC, new_2, 2}},
- {749, {wxBufferedDC, new_3, 3}},
- {750, {wxBufferedDC, destruct, 0}},
- {751, {wxBufferedDC, init_2, 2}},
- {752, {wxBufferedDC, init_3, 3}},
- {753, {wxBufferedPaintDC, new_3, 3}},
- {754, {wxBufferedPaintDC, new_2, 2}},
- {755, {wxBufferedPaintDC, destruct, 0}},
- {756, {wxGraphicsObject, destruct, 0}},
- {757, {wxGraphicsObject, getRenderer, 0}},
- {758, {wxGraphicsObject, isNull, 0}},
- {759, {wxGraphicsContext, destruct, 0}},
- {760, {wxGraphicsContext, create_1_1, 1}},
- {761, {wxGraphicsContext, create_1_0, 1}},
- {762, {wxGraphicsContext, create_0, 0}},
- {763, {wxGraphicsContext, createPen, 1}},
- {764, {wxGraphicsContext, createBrush, 1}},
- {765, {wxGraphicsContext, createRadialGradientBrush, 7}},
- {766, {wxGraphicsContext, createLinearGradientBrush, 6}},
- {767, {wxGraphicsContext, createFont, 2}},
- {768, {wxGraphicsContext, createMatrix, 1}},
- {769, {wxGraphicsContext, createPath, 0}},
- {770, {wxGraphicsContext, clip_1, 1}},
- {771, {wxGraphicsContext, clip_4, 4}},
- {772, {wxGraphicsContext, resetClip, 0}},
- {773, {wxGraphicsContext, drawBitmap, 5}},
- {774, {wxGraphicsContext, drawEllipse, 4}},
- {775, {wxGraphicsContext, drawIcon, 5}},
- {776, {wxGraphicsContext, drawLines, 3}},
- {777, {wxGraphicsContext, drawPath, 2}},
- {778, {wxGraphicsContext, drawRectangle, 4}},
- {779, {wxGraphicsContext, drawRoundedRectangle, 5}},
- {780, {wxGraphicsContext, drawText_3, 3}},
- {781, {wxGraphicsContext, drawText_4_0, 4}},
- {782, {wxGraphicsContext, drawText_4_1, 4}},
- {783, {wxGraphicsContext, drawText_5, 5}},
- {784, {wxGraphicsContext, fillPath, 2}},
- {785, {wxGraphicsContext, strokePath, 1}},
- {786, {wxGraphicsContext, getPartialTextExtents, 2}},
- {787, {wxGraphicsContext, getTextExtent, 5}},
- {788, {wxGraphicsContext, rotate, 1}},
- {789, {wxGraphicsContext, scale, 2}},
- {790, {wxGraphicsContext, translate, 2}},
- {791, {wxGraphicsContext, getTransform, 0}},
- {792, {wxGraphicsContext, setTransform, 1}},
- {793, {wxGraphicsContext, concatTransform, 1}},
- {794, {wxGraphicsContext, setBrush_1_1, 1}},
- {795, {wxGraphicsContext, setBrush_1_0, 1}},
- {796, {wxGraphicsContext, setFont_1, 1}},
- {797, {wxGraphicsContext, setFont_2, 2}},
- {798, {wxGraphicsContext, setPen_1_0, 1}},
- {799, {wxGraphicsContext, setPen_1_1, 1}},
- {800, {wxGraphicsContext, strokeLine, 4}},
- {801, {wxGraphicsContext, strokeLines, 2}},
- {803, {wxGraphicsMatrix, concat, 1}},
- {805, {wxGraphicsMatrix, get, 1}},
- {806, {wxGraphicsMatrix, invert, 0}},
- {807, {wxGraphicsMatrix, isEqual, 1}},
- {809, {wxGraphicsMatrix, isIdentity, 0}},
- {810, {wxGraphicsMatrix, rotate, 1}},
- {811, {wxGraphicsMatrix, scale, 2}},
- {812, {wxGraphicsMatrix, translate, 2}},
- {813, {wxGraphicsMatrix, set, 1}},
- {814, {wxGraphicsMatrix, transformPoint, 2}},
- {815, {wxGraphicsMatrix, transformDistance, 2}},
- {816, {wxGraphicsPath, moveToPoint_2, 2}},
- {817, {wxGraphicsPath, moveToPoint_1, 1}},
- {818, {wxGraphicsPath, addArc_6, 6}},
- {819, {wxGraphicsPath, addArc_5, 5}},
- {820, {wxGraphicsPath, addArcToPoint, 5}},
- {821, {wxGraphicsPath, addCircle, 3}},
- {822, {wxGraphicsPath, addCurveToPoint_6, 6}},
- {823, {wxGraphicsPath, addCurveToPoint_3, 3}},
- {824, {wxGraphicsPath, addEllipse, 4}},
- {825, {wxGraphicsPath, addLineToPoint_2, 2}},
- {826, {wxGraphicsPath, addLineToPoint_1, 1}},
- {827, {wxGraphicsPath, addPath, 1}},
- {828, {wxGraphicsPath, addQuadCurveToPoint, 4}},
- {829, {wxGraphicsPath, addRectangle, 4}},
- {830, {wxGraphicsPath, addRoundedRectangle, 5}},
- {831, {wxGraphicsPath, closeSubpath, 0}},
- {832, {wxGraphicsPath, contains_3, 3}},
- {833, {wxGraphicsPath, contains_2, 2}},
- {835, {wxGraphicsPath, getBox, 0}},
- {837, {wxGraphicsPath, getCurrentPoint, 0}},
- {838, {wxGraphicsPath, transform, 1}},
- {839, {wxGraphicsRenderer, getDefaultRenderer, 0}},
- {840, {wxGraphicsRenderer, createContext_1_1, 1}},
- {841, {wxGraphicsRenderer, createContext_1_0, 1}},
- {842, {wxGraphicsRenderer, createPen, 1}},
- {843, {wxGraphicsRenderer, createBrush, 1}},
- {844, {wxGraphicsRenderer, createLinearGradientBrush, 6}},
- {845, {wxGraphicsRenderer, createRadialGradientBrush, 7}},
- {846, {wxGraphicsRenderer, createFont, 2}},
- {847, {wxGraphicsRenderer, createMatrix, 1}},
- {848, {wxGraphicsRenderer, createPath, 0}},
- {850, {wxMenuBar, new_1, 1}},
- {852, {wxMenuBar, new_0, 0}},
- {854, {wxMenuBar, destruct, 0}},
- {855, {wxMenuBar, append, 2}},
- {856, {wxMenuBar, check, 2}},
- {857, {wxMenuBar, enable_2, 2}},
- {858, {wxMenuBar, enable_1, 1}},
- {859, {wxMenuBar, enableTop, 2}},
- {860, {wxMenuBar, findMenu, 1}},
- {861, {wxMenuBar, findMenuItem, 2}},
- {862, {wxMenuBar, findItem, 2}},
- {863, {wxMenuBar, getHelpString, 1}},
- {864, {wxMenuBar, getLabel_1, 1}},
- {865, {wxMenuBar, getLabel_0, 0}},
- {866, {wxMenuBar, getLabelTop, 1}},
- {867, {wxMenuBar, getMenu, 1}},
- {868, {wxMenuBar, getMenuCount, 0}},
- {869, {wxMenuBar, insert, 3}},
- {870, {wxMenuBar, isChecked, 1}},
- {871, {wxMenuBar, isEnabled_1, 1}},
- {872, {wxMenuBar, isEnabled_0, 0}},
- {873, {wxMenuBar, remove, 1}},
- {874, {wxMenuBar, replace, 3}},
- {875, {wxMenuBar, setHelpString, 2}},
- {876, {wxMenuBar, setLabel_2, 2}},
- {877, {wxMenuBar, setLabel_1, 1}},
- {878, {wxMenuBar, setLabelTop, 2}},
- {879, {wxControl, getLabel, 0}},
- {880, {wxControl, setLabel, 1}},
- {881, {wxControlWithItems, append_1, 1}},
- {882, {wxControlWithItems, append_2, 2}},
- {883, {wxControlWithItems, appendStrings_1, 1}},
- {884, {wxControlWithItems, clear, 0}},
- {885, {wxControlWithItems, delete, 1}},
- {886, {wxControlWithItems, findString, 2}},
- {887, {wxControlWithItems, getClientData, 1}},
- {888, {wxControlWithItems, setClientData, 2}},
- {889, {wxControlWithItems, getCount, 0}},
- {890, {wxControlWithItems, getSelection, 0}},
- {891, {wxControlWithItems, getString, 1}},
- {892, {wxControlWithItems, getStringSelection, 0}},
- {893, {wxControlWithItems, insert_2, 2}},
- {894, {wxControlWithItems, insert_3, 3}},
- {895, {wxControlWithItems, isEmpty, 0}},
- {896, {wxControlWithItems, select, 1}},
- {897, {wxControlWithItems, setSelection, 1}},
- {898, {wxControlWithItems, setString, 2}},
- {899, {wxControlWithItems, setStringSelection, 1}},
- {902, {wxMenu, new_2, 2}},
- {903, {wxMenu, new_1, 1}},
- {905, {wxMenu, destruct, 0}},
- {906, {wxMenu, append_3, 3}},
- {907, {wxMenu, append_1, 1}},
- {908, {wxMenu, append_4_0, 4}},
- {909, {wxMenu, append_4_1, 4}},
- {910, {wxMenu, appendCheckItem, 3}},
- {911, {wxMenu, appendRadioItem, 3}},
- {912, {wxMenu, appendSeparator, 0}},
- {913, {wxMenu, break, 0}},
- {914, {wxMenu, check, 2}},
- {915, {wxMenu, delete_1_0, 1}},
- {916, {wxMenu, delete_1_1, 1}},
- {917, {wxMenu, destroy_1_0, 1}},
- {918, {wxMenu, destroy_1_1, 1}},
- {919, {wxMenu, enable, 2}},
- {920, {wxMenu, findItem_1, 1}},
- {921, {wxMenu, findItem_2, 2}},
- {922, {wxMenu, findItemByPosition, 1}},
- {923, {wxMenu, getHelpString, 1}},
- {924, {wxMenu, getLabel, 1}},
- {925, {wxMenu, getMenuItemCount, 0}},
- {926, {wxMenu, getMenuItems, 0}},
- {928, {wxMenu, getTitle, 0}},
- {929, {wxMenu, insert_2, 2}},
- {930, {wxMenu, insert_3, 3}},
- {931, {wxMenu, insert_5_1, 5}},
- {932, {wxMenu, insert_5_0, 5}},
- {933, {wxMenu, insertCheckItem, 4}},
- {934, {wxMenu, insertRadioItem, 4}},
- {935, {wxMenu, insertSeparator, 1}},
- {936, {wxMenu, isChecked, 1}},
- {937, {wxMenu, isEnabled, 1}},
- {938, {wxMenu, prepend_1, 1}},
- {939, {wxMenu, prepend_2, 2}},
- {940, {wxMenu, prepend_4_1, 4}},
- {941, {wxMenu, prepend_4_0, 4}},
- {942, {wxMenu, prependCheckItem, 3}},
- {943, {wxMenu, prependRadioItem, 3}},
- {944, {wxMenu, prependSeparator, 0}},
- {945, {wxMenu, remove_1_0, 1}},
- {946, {wxMenu, remove_1_1, 1}},
- {947, {wxMenu, setHelpString, 2}},
- {948, {wxMenu, setLabel, 2}},
- {949, {wxMenu, setTitle, 1}},
- {950, {wxMenuItem, new, 1}},
- {952, {wxMenuItem, destruct, 0}},
- {953, {wxMenuItem, check, 1}},
- {954, {wxMenuItem, enable, 1}},
- {955, {wxMenuItem, getBitmap, 0}},
- {956, {wxMenuItem, getHelp, 0}},
- {957, {wxMenuItem, getId, 0}},
- {958, {wxMenuItem, getKind, 0}},
- {959, {wxMenuItem, getLabel, 0}},
- {960, {wxMenuItem, getLabelFromText, 1}},
- {961, {wxMenuItem, getMenu, 0}},
- {962, {wxMenuItem, getText, 0}},
- {963, {wxMenuItem, getSubMenu, 0}},
- {964, {wxMenuItem, isCheckable, 0}},
- {965, {wxMenuItem, isChecked, 0}},
- {966, {wxMenuItem, isEnabled, 0}},
- {967, {wxMenuItem, isSeparator, 0}},
- {968, {wxMenuItem, isSubMenu, 0}},
- {969, {wxMenuItem, setBitmap, 1}},
- {970, {wxMenuItem, setHelp, 1}},
- {971, {wxMenuItem, setMenu, 1}},
- {972, {wxMenuItem, setSubMenu, 1}},
- {973, {wxMenuItem, setText, 1}},
- {974, {wxToolBar, addControl, 1}},
- {975, {wxToolBar, addSeparator, 0}},
- {976, {wxToolBar, addTool_5, 5}},
- {977, {wxToolBar, addTool_4_0, 4}},
- {978, {wxToolBar, addTool_1, 1}},
- {979, {wxToolBar, addTool_4_1, 4}},
- {980, {wxToolBar, addTool_3, 3}},
- {981, {wxToolBar, addTool_6, 6}},
- {982, {wxToolBar, addCheckTool, 4}},
- {983, {wxToolBar, addRadioTool, 4}},
- {984, {wxToolBar, deleteTool, 1}},
- {985, {wxToolBar, deleteToolByPos, 1}},
- {986, {wxToolBar, enableTool, 2}},
- {987, {wxToolBar, findById, 1}},
- {988, {wxToolBar, findControl, 1}},
- {989, {wxToolBar, findToolForPosition, 2}},
- {990, {wxToolBar, getToolSize, 0}},
- {991, {wxToolBar, getToolBitmapSize, 0}},
- {992, {wxToolBar, getMargins, 0}},
- {993, {wxToolBar, getToolEnabled, 1}},
- {994, {wxToolBar, getToolLongHelp, 1}},
- {995, {wxToolBar, getToolPacking, 0}},
- {996, {wxToolBar, getToolPos, 1}},
- {997, {wxToolBar, getToolSeparation, 0}},
- {998, {wxToolBar, getToolShortHelp, 1}},
- {999, {wxToolBar, getToolState, 1}},
- {1000, {wxToolBar, insertControl, 2}},
- {1001, {wxToolBar, insertSeparator, 1}},
- {1002, {wxToolBar, insertTool_5, 5}},
- {1003, {wxToolBar, insertTool_2, 2}},
- {1004, {wxToolBar, insertTool_4, 4}},
- {1005, {wxToolBar, realize, 0}},
- {1006, {wxToolBar, removeTool, 1}},
- {1007, {wxToolBar, setMargins, 2}},
- {1008, {wxToolBar, setToolBitmapSize, 1}},
- {1009, {wxToolBar, setToolLongHelp, 2}},
- {1010, {wxToolBar, setToolPacking, 1}},
- {1011, {wxToolBar, setToolShortHelp, 2}},
- {1012, {wxToolBar, setToolSeparation, 1}},
- {1013, {wxToolBar, toggleTool, 2}},
- {1015, {wxStatusBar, new_0, 0}},
- {1016, {wxStatusBar, new_2, 2}},
- {1018, {wxStatusBar, destruct, 0}},
- {1019, {wxStatusBar, create, 2}},
- {1020, {wxStatusBar, getFieldRect, 2}},
- {1021, {wxStatusBar, getFieldsCount, 0}},
- {1022, {wxStatusBar, getStatusText, 1}},
- {1023, {wxStatusBar, popStatusText, 1}},
- {1024, {wxStatusBar, pushStatusText, 2}},
- {1025, {wxStatusBar, setFieldsCount, 2}},
- {1026, {wxStatusBar, setMinHeight, 1}},
- {1027, {wxStatusBar, setStatusText, 2}},
- {1028, {wxStatusBar, setStatusWidths, 2}},
- {1029, {wxStatusBar, setStatusStyles, 2}},
- {1030, {wxBitmap, new_0, 0}},
- {1031, {wxBitmap, new_3, 3}},
- {1032, {wxBitmap, new_4, 4}},
- {1033, {wxBitmap, new_2_0, 2}},
- {1034, {wxBitmap, new_2_1, 2}},
- {1035, {wxBitmap, destruct, 0}},
- {1036, {wxBitmap, convertToImage, 0}},
- {1037, {wxBitmap, copyFromIcon, 1}},
- {1038, {wxBitmap, create, 3}},
- {1039, {wxBitmap, getDepth, 0}},
- {1040, {wxBitmap, getHeight, 0}},
- {1041, {wxBitmap, getPalette, 0}},
- {1042, {wxBitmap, getMask, 0}},
- {1043, {wxBitmap, getWidth, 0}},
- {1044, {wxBitmap, getSubBitmap, 1}},
- {1045, {wxBitmap, loadFile, 2}},
- {1046, {wxBitmap, ok, 0}},
- {1047, {wxBitmap, saveFile, 3}},
- {1048, {wxBitmap, setDepth, 1}},
- {1049, {wxBitmap, setHeight, 1}},
- {1050, {wxBitmap, setMask, 1}},
- {1051, {wxBitmap, setPalette, 1}},
- {1052, {wxBitmap, setWidth, 1}},
- {1053, {wxIcon, new_0, 0}},
- {1054, {wxIcon, new_2, 2}},
- {1055, {wxIcon, new_1, 1}},
- {1056, {wxIcon, copyFromBitmap, 1}},
- {1057, {wxIcon, 'Destroy', undefined}},
- {1058, {wxIconBundle, new_0, 0}},
- {1059, {wxIconBundle, new_2, 2}},
- {1060, {wxIconBundle, new_1_0, 1}},
- {1061, {wxIconBundle, new_1_1, 1}},
- {1062, {wxIconBundle, destruct, 0}},
- {1063, {wxIconBundle, addIcon_2, 2}},
- {1064, {wxIconBundle, addIcon_1, 1}},
- {1065, {wxIconBundle, getIcon_1_1, 1}},
- {1066, {wxIconBundle, getIcon_1_0, 1}},
- {1067, {wxCursor, new_0, 0}},
- {1068, {wxCursor, new_1_0, 1}},
- {1069, {wxCursor, new_1_1, 1}},
- {1070, {wxCursor, new_4, 4}},
- {1071, {wxCursor, destruct, 0}},
- {1072, {wxCursor, ok, 0}},
- {1073, {wxMask, new_0, 0}},
- {1074, {wxMask, new_2_1, 2}},
- {1075, {wxMask, new_2_0, 2}},
- {1076, {wxMask, new_1, 1}},
- {1077, {wxMask, destruct, 0}},
- {1078, {wxMask, create_2_1, 2}},
- {1079, {wxMask, create_2_0, 2}},
- {1080, {wxMask, create_1, 1}},
- {1081, {wxImage, new_0, 0}},
- {1082, {wxImage, new_3_0, 3}},
- {1083, {wxImage, new_4, 4}},
- {1084, {wxImage, new_5, 5}},
- {1085, {wxImage, new_2, 2}},
- {1086, {wxImage, new_3_1, 3}},
- {1087, {wxImage, blur, 1}},
- {1088, {wxImage, blurHorizontal, 1}},
- {1089, {wxImage, blurVertical, 1}},
- {1090, {wxImage, convertAlphaToMask, 1}},
- {1091, {wxImage, convertToGreyscale, 1}},
- {1092, {wxImage, convertToMono, 3}},
- {1093, {wxImage, copy, 0}},
- {1094, {wxImage, create_3, 3}},
- {1095, {wxImage, create_4, 4}},
- {1096, {wxImage, create_5, 5}},
- {1097, {wxImage, 'Destroy', 0}},
- {1098, {wxImage, findFirstUnusedColour, 4}},
- {1099, {wxImage, getImageExtWildcard, 0}},
- {1100, {wxImage, getAlpha_2, 2}},
- {1101, {wxImage, getAlpha_0, 0}},
- {1102, {wxImage, getBlue, 2}},
- {1103, {wxImage, getData, 0}},
- {1104, {wxImage, getGreen, 2}},
- {1105, {wxImage, getImageCount, 2}},
- {1106, {wxImage, getHeight, 0}},
- {1107, {wxImage, getMaskBlue, 0}},
- {1108, {wxImage, getMaskGreen, 0}},
- {1109, {wxImage, getMaskRed, 0}},
- {1110, {wxImage, getOrFindMaskColour, 3}},
- {1111, {wxImage, getPalette, 0}},
- {1112, {wxImage, getRed, 2}},
- {1113, {wxImage, getSubImage, 1}},
- {1114, {wxImage, getWidth, 0}},
- {1115, {wxImage, hasAlpha, 0}},
- {1116, {wxImage, hasMask, 0}},
- {1117, {wxImage, getOption, 1}},
- {1118, {wxImage, getOptionInt, 1}},
- {1119, {wxImage, hasOption, 1}},
- {1120, {wxImage, initAlpha, 0}},
- {1121, {wxImage, initStandardHandlers, 0}},
- {1122, {wxImage, isTransparent, 3}},
- {1123, {wxImage, loadFile_2, 2}},
- {1124, {wxImage, loadFile_3, 3}},
- {1125, {wxImage, ok, 0}},
- {1126, {wxImage, removeHandler, 1}},
- {1127, {wxImage, mirror, 1}},
- {1128, {wxImage, replace, 6}},
- {1129, {wxImage, rescale, 3}},
- {1130, {wxImage, resize, 3}},
- {1131, {wxImage, rotate, 3}},
- {1132, {wxImage, rotateHue, 1}},
- {1133, {wxImage, rotate90, 1}},
- {1134, {wxImage, saveFile_1, 1}},
- {1135, {wxImage, saveFile_2_0, 2}},
- {1136, {wxImage, saveFile_2_1, 2}},
- {1137, {wxImage, scale, 3}},
- {1138, {wxImage, size, 3}},
- {1139, {wxImage, setAlpha_3, 3}},
- {1140, {wxImage, setAlpha_2, 2}},
- {1141, {wxImage, setData_2, 2}},
- {1142, {wxImage, setData_4, 4}},
- {1143, {wxImage, setMask, 1}},
- {1144, {wxImage, setMaskColour, 3}},
- {1145, {wxImage, setMaskFromImage, 4}},
- {1146, {wxImage, setOption_2_1, 2}},
- {1147, {wxImage, setOption_2_0, 2}},
- {1148, {wxImage, setPalette, 1}},
- {1149, {wxImage, setRGB_5, 5}},
- {1150, {wxImage, setRGB_4, 4}},
- {1151, {wxImage, 'Destroy', undefined}},
- {1152, {wxBrush, new_0, 0}},
- {1153, {wxBrush, new_2, 2}},
- {1154, {wxBrush, new_1, 1}},
- {1156, {wxBrush, destruct, 0}},
- {1157, {wxBrush, getColour, 0}},
- {1158, {wxBrush, getStipple, 0}},
- {1159, {wxBrush, getStyle, 0}},
- {1160, {wxBrush, isHatch, 0}},
- {1161, {wxBrush, isOk, 0}},
- {1162, {wxBrush, setColour_1, 1}},
- {1163, {wxBrush, setColour_3, 3}},
- {1164, {wxBrush, setStipple, 1}},
- {1165, {wxBrush, setStyle, 1}},
- {1166, {wxPen, new_0, 0}},
- {1167, {wxPen, new_2, 2}},
- {1168, {wxPen, destruct, 0}},
- {1169, {wxPen, getCap, 0}},
- {1170, {wxPen, getColour, 0}},
- {1171, {wxPen, getJoin, 0}},
- {1172, {wxPen, getStyle, 0}},
- {1173, {wxPen, getWidth, 0}},
- {1174, {wxPen, isOk, 0}},
- {1175, {wxPen, setCap, 1}},
- {1176, {wxPen, setColour_1, 1}},
- {1177, {wxPen, setColour_3, 3}},
- {1178, {wxPen, setJoin, 1}},
- {1179, {wxPen, setStyle, 1}},
- {1180, {wxPen, setWidth, 1}},
- {1181, {wxRegion, new_0, 0}},
- {1182, {wxRegion, new_4, 4}},
- {1183, {wxRegion, new_2, 2}},
- {1184, {wxRegion, new_1_1, 1}},
- {1186, {wxRegion, new_1_0, 1}},
- {1188, {wxRegion, destruct, 0}},
- {1189, {wxRegion, clear, 0}},
- {1190, {wxRegion, contains_2, 2}},
- {1191, {wxRegion, contains_1_0, 1}},
- {1192, {wxRegion, contains_4, 4}},
- {1193, {wxRegion, contains_1_1, 1}},
- {1194, {wxRegion, convertToBitmap, 0}},
- {1195, {wxRegion, getBox, 0}},
- {1196, {wxRegion, intersect_4, 4}},
- {1197, {wxRegion, intersect_1_1, 1}},
- {1198, {wxRegion, intersect_1_0, 1}},
- {1199, {wxRegion, isEmpty, 0}},
- {1200, {wxRegion, subtract_4, 4}},
- {1201, {wxRegion, subtract_1_1, 1}},
- {1202, {wxRegion, subtract_1_0, 1}},
- {1203, {wxRegion, offset_2, 2}},
- {1204, {wxRegion, offset_1, 1}},
- {1205, {wxRegion, union_4, 4}},
- {1206, {wxRegion, union_1_2, 1}},
- {1207, {wxRegion, union_1_1, 1}},
- {1208, {wxRegion, union_1_0, 1}},
- {1209, {wxRegion, union_3, 3}},
- {1210, {wxRegion, xor_4, 4}},
- {1211, {wxRegion, xor_1_1, 1}},
- {1212, {wxRegion, xor_1_0, 1}},
- {1213, {wxAcceleratorTable, new_0, 0}},
- {1214, {wxAcceleratorTable, new_2, 2}},
- {1215, {wxAcceleratorTable, destruct, 0}},
- {1216, {wxAcceleratorTable, ok, 0}},
- {1217, {wxAcceleratorEntry, new_1_0, 1}},
- {1218, {wxAcceleratorEntry, new_1_1, 1}},
- {1219, {wxAcceleratorEntry, getCommand, 0}},
- {1220, {wxAcceleratorEntry, getFlags, 0}},
- {1221, {wxAcceleratorEntry, getKeyCode, 0}},
- {1222, {wxAcceleratorEntry, set, 4}},
- {1223, {wxAcceleratorEntry, 'Destroy', undefined}},
- {1228, {wxCaret, new_3, 3}},
- {1229, {wxCaret, new_2, 2}},
- {1231, {wxCaret, destruct, 0}},
- {1232, {wxCaret, create_3, 3}},
- {1233, {wxCaret, create_2, 2}},
- {1234, {wxCaret, getBlinkTime, 0}},
- {1236, {wxCaret, getPosition, 0}},
- {1238, {wxCaret, getSize, 0}},
- {1239, {wxCaret, getWindow, 0}},
- {1240, {wxCaret, hide, 0}},
- {1241, {wxCaret, isOk, 0}},
- {1242, {wxCaret, isVisible, 0}},
- {1243, {wxCaret, move_2, 2}},
- {1244, {wxCaret, move_1, 1}},
- {1245, {wxCaret, setBlinkTime, 1}},
- {1246, {wxCaret, setSize_2, 2}},
- {1247, {wxCaret, setSize_1, 1}},
- {1248, {wxCaret, show, 1}},
- {1249, {wxSizer, add_2_1, 2}},
- {1250, {wxSizer, add_2_0, 2}},
- {1251, {wxSizer, add_3, 3}},
- {1252, {wxSizer, add_2_3, 2}},
- {1253, {wxSizer, add_2_2, 2}},
- {1254, {wxSizer, addSpacer, 1}},
- {1255, {wxSizer, addStretchSpacer, 1}},
- {1256, {wxSizer, calcMin, 0}},
- {1257, {wxSizer, clear, 1}},
- {1258, {wxSizer, detach_1_2, 1}},
- {1259, {wxSizer, detach_1_1, 1}},
- {1260, {wxSizer, detach_1_0, 1}},
- {1261, {wxSizer, fit, 1}},
- {1262, {wxSizer, fitInside, 1}},
- {1263, {wxSizer, getChildren, 0}},
- {1264, {wxSizer, getItem_2_1, 2}},
- {1265, {wxSizer, getItem_2_0, 2}},
- {1266, {wxSizer, getItem_1, 1}},
- {1267, {wxSizer, getSize, 0}},
- {1268, {wxSizer, getPosition, 0}},
- {1269, {wxSizer, getMinSize, 0}},
- {1270, {wxSizer, hide_2_0, 2}},
- {1271, {wxSizer, hide_2_1, 2}},
- {1272, {wxSizer, hide_1, 1}},
- {1273, {wxSizer, insert_3_1, 3}},
- {1274, {wxSizer, insert_3_0, 3}},
- {1275, {wxSizer, insert_4, 4}},
- {1276, {wxSizer, insert_3_3, 3}},
- {1277, {wxSizer, insert_3_2, 3}},
- {1278, {wxSizer, insert_2, 2}},
- {1279, {wxSizer, insertSpacer, 2}},
- {1280, {wxSizer, insertStretchSpacer, 2}},
- {1281, {wxSizer, isShown_1_2, 1}},
- {1282, {wxSizer, isShown_1_1, 1}},
- {1283, {wxSizer, isShown_1_0, 1}},
- {1284, {wxSizer, layout, 0}},
- {1285, {wxSizer, prepend_2_1, 2}},
- {1286, {wxSizer, prepend_2_0, 2}},
- {1287, {wxSizer, prepend_3, 3}},
- {1288, {wxSizer, prepend_2_3, 2}},
- {1289, {wxSizer, prepend_2_2, 2}},
- {1290, {wxSizer, prepend_1, 1}},
- {1291, {wxSizer, prependSpacer, 1}},
- {1292, {wxSizer, prependStretchSpacer, 1}},
- {1293, {wxSizer, recalcSizes, 0}},
- {1294, {wxSizer, remove_1_1, 1}},
- {1295, {wxSizer, remove_1_0, 1}},
- {1296, {wxSizer, replace_3_1, 3}},
- {1297, {wxSizer, replace_3_0, 3}},
- {1298, {wxSizer, replace_2, 2}},
- {1299, {wxSizer, setDimension, 4}},
- {1300, {wxSizer, setMinSize_2, 2}},
- {1301, {wxSizer, setMinSize_1, 1}},
- {1302, {wxSizer, setItemMinSize_3_2, 3}},
- {1303, {wxSizer, setItemMinSize_2_2, 2}},
- {1304, {wxSizer, setItemMinSize_3_1, 3}},
- {1305, {wxSizer, setItemMinSize_2_1, 2}},
- {1306, {wxSizer, setItemMinSize_3_0, 3}},
- {1307, {wxSizer, setItemMinSize_2_0, 2}},
- {1308, {wxSizer, setSizeHints, 1}},
- {1309, {wxSizer, setVirtualSizeHints, 1}},
- {1310, {wxSizer, show_2_2, 2}},
- {1311, {wxSizer, show_2_1, 2}},
- {1312, {wxSizer, show_2_0, 2}},
- {1313, {wxSizer, show_1, 1}},
- {1314, {wxSizerFlags, new, 1}},
- {1315, {wxSizerFlags, align, 1}},
- {1316, {wxSizerFlags, border_2, 2}},
- {1317, {wxSizerFlags, border_1, 1}},
- {1318, {wxSizerFlags, center, 0}},
- {1319, {wxSizerFlags, centre, 0}},
- {1320, {wxSizerFlags, expand, 0}},
- {1321, {wxSizerFlags, left, 0}},
- {1322, {wxSizerFlags, proportion, 1}},
- {1323, {wxSizerFlags, right, 0}},
- {1324, {wxSizerFlags, 'Destroy', undefined}},
- {1325, {wxSizerItem, new_5_1, 5}},
- {1326, {wxSizerItem, new_2_1, 2}},
- {1327, {wxSizerItem, new_5_0, 5}},
- {1328, {wxSizerItem, new_2_0, 2}},
- {1329, {wxSizerItem, new_6, 6}},
- {1330, {wxSizerItem, new_3, 3}},
- {1331, {wxSizerItem, new_0, 0}},
- {1332, {wxSizerItem, destruct, 0}},
- {1333, {wxSizerItem, calcMin, 0}},
- {1334, {wxSizerItem, deleteWindows, 0}},
- {1335, {wxSizerItem, detachSizer, 0}},
- {1336, {wxSizerItem, getBorder, 0}},
- {1337, {wxSizerItem, getFlag, 0}},
- {1338, {wxSizerItem, getMinSize, 0}},
- {1339, {wxSizerItem, getPosition, 0}},
- {1340, {wxSizerItem, getProportion, 0}},
- {1341, {wxSizerItem, getRatio, 0}},
- {1342, {wxSizerItem, getRect, 0}},
- {1343, {wxSizerItem, getSize, 0}},
- {1344, {wxSizerItem, getSizer, 0}},
- {1345, {wxSizerItem, getSpacer, 0}},
- {1346, {wxSizerItem, getUserData, 0}},
- {1347, {wxSizerItem, getWindow, 0}},
- {1348, {wxSizerItem, isSizer, 0}},
- {1349, {wxSizerItem, isShown, 0}},
- {1350, {wxSizerItem, isSpacer, 0}},
- {1351, {wxSizerItem, isWindow, 0}},
- {1352, {wxSizerItem, setBorder, 1}},
- {1353, {wxSizerItem, setDimension, 2}},
- {1354, {wxSizerItem, setFlag, 1}},
- {1355, {wxSizerItem, setInitSize, 2}},
- {1356, {wxSizerItem, setMinSize_1, 1}},
- {1357, {wxSizerItem, setMinSize_2, 2}},
- {1358, {wxSizerItem, setProportion, 1}},
- {1359, {wxSizerItem, setRatio_2, 2}},
- {1360, {wxSizerItem, setRatio_1_1, 1}},
- {1361, {wxSizerItem, setRatio_1_0, 1}},
- {1362, {wxSizerItem, setSizer, 1}},
- {1363, {wxSizerItem, setSpacer_1, 1}},
- {1364, {wxSizerItem, setSpacer_2, 2}},
- {1365, {wxSizerItem, setWindow, 1}},
- {1366, {wxSizerItem, show, 1}},
- {1367, {wxBoxSizer, new, 1}},
- {1368, {wxBoxSizer, getOrientation, 0}},
- {1369, {wxBoxSizer, 'Destroy', undefined}},
- {1370, {wxStaticBoxSizer, new_2, 2}},
- {1371, {wxStaticBoxSizer, new_3, 3}},
- {1372, {wxStaticBoxSizer, getStaticBox, 0}},
- {1373, {wxStaticBoxSizer, 'Destroy', undefined}},
- {1374, {wxGridSizer, new_4, 4}},
- {1375, {wxGridSizer, new_2, 2}},
- {1376, {wxGridSizer, getCols, 0}},
- {1377, {wxGridSizer, getHGap, 0}},
- {1378, {wxGridSizer, getRows, 0}},
- {1379, {wxGridSizer, getVGap, 0}},
- {1380, {wxGridSizer, setCols, 1}},
- {1381, {wxGridSizer, setHGap, 1}},
- {1382, {wxGridSizer, setRows, 1}},
- {1383, {wxGridSizer, setVGap, 1}},
- {1384, {wxGridSizer, 'Destroy', undefined}},
- {1385, {wxFlexGridSizer, new_4, 4}},
- {1386, {wxFlexGridSizer, new_2, 2}},
- {1387, {wxFlexGridSizer, addGrowableCol, 2}},
- {1388, {wxFlexGridSizer, addGrowableRow, 2}},
- {1389, {wxFlexGridSizer, getFlexibleDirection, 0}},
- {1390, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}},
- {1391, {wxFlexGridSizer, removeGrowableCol, 1}},
- {1392, {wxFlexGridSizer, removeGrowableRow, 1}},
- {1393, {wxFlexGridSizer, setFlexibleDirection, 1}},
- {1394, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}},
- {1395, {wxFlexGridSizer, 'Destroy', undefined}},
- {1396, {wxGridBagSizer, new, 1}},
- {1397, {wxGridBagSizer, add_3_2, 3}},
- {1398, {wxGridBagSizer, add_3_1, 3}},
- {1399, {wxGridBagSizer, add_4, 4}},
- {1400, {wxGridBagSizer, add_1_0, 1}},
- {1401, {wxGridBagSizer, add_2_1, 2}},
- {1402, {wxGridBagSizer, add_2_0, 2}},
- {1403, {wxGridBagSizer, add_3_0, 3}},
- {1404, {wxGridBagSizer, add_1_1, 1}},
- {1405, {wxGridBagSizer, calcMin, 0}},
- {1406, {wxGridBagSizer, checkForIntersection_2, 2}},
- {1407, {wxGridBagSizer, checkForIntersection_3, 3}},
- {1408, {wxGridBagSizer, findItem_1_1, 1}},
- {1409, {wxGridBagSizer, findItem_1_0, 1}},
- {1410, {wxGridBagSizer, findItemAtPoint, 1}},
- {1411, {wxGridBagSizer, findItemAtPosition, 1}},
- {1412, {wxGridBagSizer, findItemWithData, 1}},
- {1413, {wxGridBagSizer, getCellSize, 2}},
- {1414, {wxGridBagSizer, getEmptyCellSize, 0}},
- {1415, {wxGridBagSizer, getItemPosition_1_2, 1}},
- {1416, {wxGridBagSizer, getItemPosition_1_1, 1}},
- {1417, {wxGridBagSizer, getItemPosition_1_0, 1}},
- {1418, {wxGridBagSizer, getItemSpan_1_2, 1}},
- {1419, {wxGridBagSizer, getItemSpan_1_1, 1}},
- {1420, {wxGridBagSizer, getItemSpan_1_0, 1}},
- {1421, {wxGridBagSizer, setEmptyCellSize, 1}},
- {1422, {wxGridBagSizer, setItemPosition_2_2, 2}},
- {1423, {wxGridBagSizer, setItemPosition_2_1, 2}},
- {1424, {wxGridBagSizer, setItemPosition_2_0, 2}},
- {1425, {wxGridBagSizer, setItemSpan_2_2, 2}},
- {1426, {wxGridBagSizer, setItemSpan_2_1, 2}},
- {1427, {wxGridBagSizer, setItemSpan_2_0, 2}},
- {1428, {wxGridBagSizer, 'Destroy', undefined}},
- {1429, {wxStdDialogButtonSizer, new, 0}},
- {1430, {wxStdDialogButtonSizer, addButton, 1}},
- {1431, {wxStdDialogButtonSizer, realize, 0}},
- {1432, {wxStdDialogButtonSizer, setAffirmativeButton, 1}},
- {1433, {wxStdDialogButtonSizer, setCancelButton, 1}},
- {1434, {wxStdDialogButtonSizer, setNegativeButton, 1}},
- {1435, {wxStdDialogButtonSizer, 'Destroy', undefined}},
- {1436, {wxFont, new_0, 0}},
- {1437, {wxFont, new_1, 1}},
- {1438, {wxFont, new_5, 5}},
- {1440, {wxFont, destruct, 0}},
- {1441, {wxFont, isFixedWidth, 0}},
- {1442, {wxFont, getDefaultEncoding, 0}},
- {1443, {wxFont, getFaceName, 0}},
- {1444, {wxFont, getFamily, 0}},
- {1445, {wxFont, getNativeFontInfoDesc, 0}},
- {1446, {wxFont, getNativeFontInfoUserDesc, 0}},
- {1447, {wxFont, getPointSize, 0}},
- {1448, {wxFont, getStyle, 0}},
- {1449, {wxFont, getUnderlined, 0}},
- {1450, {wxFont, getWeight, 0}},
- {1451, {wxFont, ok, 0}},
- {1452, {wxFont, setDefaultEncoding, 1}},
- {1453, {wxFont, setFaceName, 1}},
- {1454, {wxFont, setFamily, 1}},
- {1455, {wxFont, setPointSize, 1}},
- {1456, {wxFont, setStyle, 1}},
- {1457, {wxFont, setUnderlined, 1}},
- {1458, {wxFont, setWeight, 1}},
- {1459, {wxToolTip, enable, 1}},
- {1460, {wxToolTip, setDelay, 1}},
- {1461, {wxToolTip, new, 1}},
- {1462, {wxToolTip, setTip, 1}},
- {1463, {wxToolTip, getTip, 0}},
- {1464, {wxToolTip, getWindow, 0}},
- {1465, {wxToolTip, 'Destroy', undefined}},
- {1467, {wxButton, new_3, 3}},
- {1468, {wxButton, new_0, 0}},
- {1469, {wxButton, destruct, 0}},
- {1470, {wxButton, create, 3}},
- {1471, {wxButton, getDefaultSize, 0}},
- {1472, {wxButton, setDefault, 0}},
- {1473, {wxButton, setLabel, 1}},
- {1475, {wxBitmapButton, new_4, 4}},
- {1476, {wxBitmapButton, new_0, 0}},
- {1477, {wxBitmapButton, create, 4}},
- {1478, {wxBitmapButton, getBitmapDisabled, 0}},
- {1480, {wxBitmapButton, getBitmapFocus, 0}},
- {1482, {wxBitmapButton, getBitmapLabel, 0}},
- {1484, {wxBitmapButton, getBitmapSelected, 0}},
- {1486, {wxBitmapButton, setBitmapDisabled, 1}},
- {1487, {wxBitmapButton, setBitmapFocus, 1}},
- {1488, {wxBitmapButton, setBitmapLabel, 1}},
- {1489, {wxBitmapButton, setBitmapSelected, 1}},
- {1490, {wxBitmapButton, 'Destroy', undefined}},
- {1491, {wxToggleButton, new_0, 0}},
- {1492, {wxToggleButton, new_4, 4}},
- {1493, {wxToggleButton, create, 4}},
- {1494, {wxToggleButton, getValue, 0}},
- {1495, {wxToggleButton, setValue, 1}},
- {1496, {wxToggleButton, 'Destroy', undefined}},
- {1497, {wxCalendarCtrl, new_0, 0}},
- {1498, {wxCalendarCtrl, new_3, 3}},
- {1499, {wxCalendarCtrl, create, 3}},
- {1500, {wxCalendarCtrl, destruct, 0}},
- {1501, {wxCalendarCtrl, setDate, 1}},
- {1502, {wxCalendarCtrl, getDate, 0}},
- {1503, {wxCalendarCtrl, enableYearChange, 1}},
- {1504, {wxCalendarCtrl, enableMonthChange, 1}},
- {1505, {wxCalendarCtrl, enableHolidayDisplay, 1}},
- {1506, {wxCalendarCtrl, setHeaderColours, 2}},
- {1507, {wxCalendarCtrl, getHeaderColourFg, 0}},
- {1508, {wxCalendarCtrl, getHeaderColourBg, 0}},
- {1509, {wxCalendarCtrl, setHighlightColours, 2}},
- {1510, {wxCalendarCtrl, getHighlightColourFg, 0}},
- {1511, {wxCalendarCtrl, getHighlightColourBg, 0}},
- {1512, {wxCalendarCtrl, setHolidayColours, 2}},
- {1513, {wxCalendarCtrl, getHolidayColourFg, 0}},
- {1514, {wxCalendarCtrl, getHolidayColourBg, 0}},
- {1515, {wxCalendarCtrl, getAttr, 1}},
- {1516, {wxCalendarCtrl, setAttr, 2}},
- {1517, {wxCalendarCtrl, setHoliday, 1}},
- {1518, {wxCalendarCtrl, resetAttr, 1}},
- {1519, {wxCalendarCtrl, hitTest, 2}},
- {1520, {wxCalendarDateAttr, new_0, 0}},
- {1521, {wxCalendarDateAttr, new_2_1, 2}},
- {1522, {wxCalendarDateAttr, new_2_0, 2}},
- {1523, {wxCalendarDateAttr, setTextColour, 1}},
- {1524, {wxCalendarDateAttr, setBackgroundColour, 1}},
- {1525, {wxCalendarDateAttr, setBorderColour, 1}},
- {1526, {wxCalendarDateAttr, setFont, 1}},
- {1527, {wxCalendarDateAttr, setBorder, 1}},
- {1528, {wxCalendarDateAttr, setHoliday, 1}},
- {1529, {wxCalendarDateAttr, hasTextColour, 0}},
- {1530, {wxCalendarDateAttr, hasBackgroundColour, 0}},
- {1531, {wxCalendarDateAttr, hasBorderColour, 0}},
- {1532, {wxCalendarDateAttr, hasFont, 0}},
- {1533, {wxCalendarDateAttr, hasBorder, 0}},
- {1534, {wxCalendarDateAttr, isHoliday, 0}},
- {1535, {wxCalendarDateAttr, getTextColour, 0}},
- {1536, {wxCalendarDateAttr, getBackgroundColour, 0}},
- {1537, {wxCalendarDateAttr, getBorderColour, 0}},
- {1538, {wxCalendarDateAttr, getFont, 0}},
- {1539, {wxCalendarDateAttr, getBorder, 0}},
- {1540, {wxCalendarDateAttr, 'Destroy', undefined}},
- {1542, {wxCheckBox, new_4, 4}},
- {1543, {wxCheckBox, new_0, 0}},
- {1544, {wxCheckBox, create, 4}},
- {1545, {wxCheckBox, getValue, 0}},
- {1546, {wxCheckBox, get3StateValue, 0}},
- {1547, {wxCheckBox, is3rdStateAllowedForUser, 0}},
- {1548, {wxCheckBox, is3State, 0}},
- {1549, {wxCheckBox, isChecked, 0}},
- {1550, {wxCheckBox, setValue, 1}},
- {1551, {wxCheckBox, set3StateValue, 1}},
- {1552, {wxCheckBox, 'Destroy', undefined}},
- {1553, {wxCheckListBox, new_0, 0}},
- {1555, {wxCheckListBox, new_3, 3}},
- {1556, {wxCheckListBox, check, 2}},
- {1557, {wxCheckListBox, isChecked, 1}},
- {1558, {wxCheckListBox, 'Destroy', undefined}},
- {1561, {wxChoice, new_3, 3}},
- {1562, {wxChoice, new_0, 0}},
- {1564, {wxChoice, destruct, 0}},
- {1566, {wxChoice, create, 6}},
- {1567, {wxChoice, delete, 1}},
- {1568, {wxChoice, getColumns, 0}},
- {1569, {wxChoice, setColumns, 1}},
- {1570, {wxComboBox, new_0, 0}},
- {1572, {wxComboBox, new_3, 3}},
- {1573, {wxComboBox, destruct, 0}},
- {1575, {wxComboBox, create, 7}},
- {1576, {wxComboBox, canCopy, 0}},
- {1577, {wxComboBox, canCut, 0}},
- {1578, {wxComboBox, canPaste, 0}},
- {1579, {wxComboBox, canRedo, 0}},
- {1580, {wxComboBox, canUndo, 0}},
- {1581, {wxComboBox, copy, 0}},
- {1582, {wxComboBox, cut, 0}},
- {1583, {wxComboBox, getInsertionPoint, 0}},
- {1584, {wxComboBox, getLastPosition, 0}},
- {1585, {wxComboBox, getValue, 0}},
- {1586, {wxComboBox, paste, 0}},
- {1587, {wxComboBox, redo, 0}},
- {1588, {wxComboBox, replace, 3}},
- {1589, {wxComboBox, remove, 2}},
- {1590, {wxComboBox, setInsertionPoint, 1}},
- {1591, {wxComboBox, setInsertionPointEnd, 0}},
- {1592, {wxComboBox, setSelection_1, 1}},
- {1593, {wxComboBox, setSelection_2, 2}},
- {1594, {wxComboBox, setValue, 1}},
- {1595, {wxComboBox, undo, 0}},
- {1596, {wxGauge, new_0, 0}},
- {1597, {wxGauge, new_4, 4}},
- {1598, {wxGauge, create, 4}},
- {1599, {wxGauge, getBezelFace, 0}},
- {1600, {wxGauge, getRange, 0}},
- {1601, {wxGauge, getShadowWidth, 0}},
- {1602, {wxGauge, getValue, 0}},
- {1603, {wxGauge, isVertical, 0}},
- {1604, {wxGauge, setBezelFace, 1}},
- {1605, {wxGauge, setRange, 1}},
- {1606, {wxGauge, setShadowWidth, 1}},
- {1607, {wxGauge, setValue, 1}},
- {1608, {wxGauge, pulse, 0}},
- {1609, {wxGauge, 'Destroy', undefined}},
- {1610, {wxGenericDirCtrl, new_0, 0}},
- {1611, {wxGenericDirCtrl, new_2, 2}},
- {1612, {wxGenericDirCtrl, destruct, 0}},
- {1613, {wxGenericDirCtrl, create, 2}},
- {1614, {wxGenericDirCtrl, init, 0}},
- {1615, {wxGenericDirCtrl, collapseTree, 0}},
- {1616, {wxGenericDirCtrl, expandPath, 1}},
- {1617, {wxGenericDirCtrl, getDefaultPath, 0}},
- {1618, {wxGenericDirCtrl, getPath, 0}},
- {1619, {wxGenericDirCtrl, getFilePath, 0}},
- {1620, {wxGenericDirCtrl, getFilter, 0}},
- {1621, {wxGenericDirCtrl, getFilterIndex, 0}},
- {1622, {wxGenericDirCtrl, getRootId, 0}},
- {1623, {wxGenericDirCtrl, getTreeCtrl, 0}},
- {1624, {wxGenericDirCtrl, reCreateTree, 0}},
- {1625, {wxGenericDirCtrl, setDefaultPath, 1}},
- {1626, {wxGenericDirCtrl, setFilter, 1}},
- {1627, {wxGenericDirCtrl, setFilterIndex, 1}},
- {1628, {wxGenericDirCtrl, setPath, 1}},
- {1630, {wxStaticBox, new_4, 4}},
- {1631, {wxStaticBox, new_0, 0}},
- {1632, {wxStaticBox, create, 4}},
- {1633, {wxStaticBox, 'Destroy', undefined}},
- {1635, {wxStaticLine, new_2, 2}},
- {1636, {wxStaticLine, new_0, 0}},
- {1637, {wxStaticLine, create, 2}},
- {1638, {wxStaticLine, isVertical, 0}},
- {1639, {wxStaticLine, getDefaultSize, 0}},
- {1640, {wxStaticLine, 'Destroy', undefined}},
- {1643, {wxListBox, new_3, 3}},
- {1644, {wxListBox, new_0, 0}},
- {1646, {wxListBox, destruct, 0}},
- {1648, {wxListBox, create, 6}},
- {1649, {wxListBox, deselect, 1}},
- {1650, {wxListBox, getSelections, 1}},
- {1651, {wxListBox, insertItems, 2}},
- {1652, {wxListBox, isSelected, 1}},
- {1653, {wxListBox, set, 1}},
- {1654, {wxListBox, hitTest, 1}},
- {1655, {wxListBox, setFirstItem_1_0, 1}},
- {1656, {wxListBox, setFirstItem_1_1, 1}},
- {1657, {wxListCtrl, new_0, 0}},
- {1658, {wxListCtrl, new_2, 2}},
- {1659, {wxListCtrl, arrange, 1}},
- {1660, {wxListCtrl, assignImageList, 2}},
- {1661, {wxListCtrl, clearAll, 0}},
- {1662, {wxListCtrl, create, 2}},
- {1663, {wxListCtrl, deleteAllItems, 0}},
- {1664, {wxListCtrl, deleteColumn, 1}},
- {1665, {wxListCtrl, deleteItem, 1}},
- {1666, {wxListCtrl, editLabel, 1}},
- {1667, {wxListCtrl, ensureVisible, 1}},
- {1668, {wxListCtrl, findItem_3_0, 3}},
- {1669, {wxListCtrl, findItem_3_1, 3}},
- {1670, {wxListCtrl, getColumn, 2}},
- {1671, {wxListCtrl, getColumnCount, 0}},
- {1672, {wxListCtrl, getColumnWidth, 1}},
- {1673, {wxListCtrl, getCountPerPage, 0}},
- {1674, {wxListCtrl, getEditControl, 0}},
- {1675, {wxListCtrl, getImageList, 1}},
- {1676, {wxListCtrl, getItem, 1}},
- {1677, {wxListCtrl, getItemBackgroundColour, 1}},
- {1678, {wxListCtrl, getItemCount, 0}},
- {1679, {wxListCtrl, getItemData, 1}},
- {1680, {wxListCtrl, getItemFont, 1}},
- {1681, {wxListCtrl, getItemPosition, 2}},
- {1682, {wxListCtrl, getItemRect, 3}},
- {1683, {wxListCtrl, getItemSpacing, 0}},
- {1684, {wxListCtrl, getItemState, 2}},
- {1685, {wxListCtrl, getItemText, 1}},
- {1686, {wxListCtrl, getItemTextColour, 1}},
- {1687, {wxListCtrl, getNextItem, 2}},
- {1688, {wxListCtrl, getSelectedItemCount, 0}},
- {1689, {wxListCtrl, getTextColour, 0}},
- {1690, {wxListCtrl, getTopItem, 0}},
- {1691, {wxListCtrl, getViewRect, 0}},
- {1692, {wxListCtrl, hitTest, 2}},
- {1693, {wxListCtrl, insertColumn_2, 2}},
- {1694, {wxListCtrl, insertColumn_3, 3}},
- {1695, {wxListCtrl, insertItem_1, 1}},
- {1696, {wxListCtrl, insertItem_2_1, 2}},
- {1697, {wxListCtrl, insertItem_2_0, 2}},
- {1698, {wxListCtrl, insertItem_3, 3}},
- {1699, {wxListCtrl, refreshItem, 1}},
- {1700, {wxListCtrl, refreshItems, 2}},
- {1701, {wxListCtrl, scrollList, 2}},
- {1702, {wxListCtrl, setBackgroundColour, 1}},
- {1703, {wxListCtrl, setColumn, 2}},
- {1704, {wxListCtrl, setColumnWidth, 2}},
- {1705, {wxListCtrl, setImageList, 2}},
- {1706, {wxListCtrl, setItem_1, 1}},
- {1707, {wxListCtrl, setItem_4, 4}},
- {1708, {wxListCtrl, setItemBackgroundColour, 2}},
- {1709, {wxListCtrl, setItemCount, 1}},
- {1710, {wxListCtrl, setItemData, 2}},
- {1711, {wxListCtrl, setItemFont, 2}},
- {1712, {wxListCtrl, setItemImage, 3}},
- {1713, {wxListCtrl, setItemColumnImage, 3}},
- {1714, {wxListCtrl, setItemPosition, 2}},
- {1715, {wxListCtrl, setItemState, 3}},
- {1716, {wxListCtrl, setItemText, 2}},
- {1717, {wxListCtrl, setItemTextColour, 2}},
- {1718, {wxListCtrl, setSingleStyle, 2}},
- {1719, {wxListCtrl, setTextColour, 1}},
- {1720, {wxListCtrl, setWindowStyleFlag, 1}},
- {1721, {wxListCtrl, sortItems, 2}},
- {1722, {wxListCtrl, 'Destroy', undefined}},
- {1723, {wxListView, clearColumnImage, 1}},
- {1724, {wxListView, focus, 1}},
- {1725, {wxListView, getFirstSelected, 0}},
- {1726, {wxListView, getFocusedItem, 0}},
- {1727, {wxListView, getNextSelected, 1}},
- {1728, {wxListView, isSelected, 1}},
- {1729, {wxListView, select, 2}},
- {1730, {wxListView, setColumnImage, 2}},
- {1731, {wxListItem, new_0, 0}},
- {1732, {wxListItem, new_1, 1}},
- {1733, {wxListItem, destruct, 0}},
- {1734, {wxListItem, clear, 0}},
- {1735, {wxListItem, getAlign, 0}},
- {1736, {wxListItem, getBackgroundColour, 0}},
- {1737, {wxListItem, getColumn, 0}},
- {1738, {wxListItem, getFont, 0}},
- {1739, {wxListItem, getId, 0}},
- {1740, {wxListItem, getImage, 0}},
- {1741, {wxListItem, getMask, 0}},
- {1742, {wxListItem, getState, 0}},
- {1743, {wxListItem, getText, 0}},
- {1744, {wxListItem, getTextColour, 0}},
- {1745, {wxListItem, getWidth, 0}},
- {1746, {wxListItem, setAlign, 1}},
- {1747, {wxListItem, setBackgroundColour, 1}},
- {1748, {wxListItem, setColumn, 1}},
- {1749, {wxListItem, setFont, 1}},
- {1750, {wxListItem, setId, 1}},
- {1751, {wxListItem, setImage, 1}},
- {1752, {wxListItem, setMask, 1}},
- {1753, {wxListItem, setState, 1}},
- {1754, {wxListItem, setStateMask, 1}},
- {1755, {wxListItem, setText, 1}},
- {1756, {wxListItem, setTextColour, 1}},
- {1757, {wxListItem, setWidth, 1}},
- {1758, {wxListItemAttr, new_0, 0}},
- {1759, {wxListItemAttr, new_3, 3}},
- {1760, {wxListItemAttr, getBackgroundColour, 0}},
- {1761, {wxListItemAttr, getFont, 0}},
- {1762, {wxListItemAttr, getTextColour, 0}},
- {1763, {wxListItemAttr, hasBackgroundColour, 0}},
- {1764, {wxListItemAttr, hasFont, 0}},
- {1765, {wxListItemAttr, hasTextColour, 0}},
- {1766, {wxListItemAttr, setBackgroundColour, 1}},
- {1767, {wxListItemAttr, setFont, 1}},
- {1768, {wxListItemAttr, setTextColour, 1}},
- {1769, {wxListItemAttr, 'Destroy', undefined}},
- {1770, {wxImageList, new_0, 0}},
- {1771, {wxImageList, new_3, 3}},
- {1772, {wxImageList, add_1, 1}},
- {1773, {wxImageList, add_2_0, 2}},
- {1774, {wxImageList, add_2_1, 2}},
- {1775, {wxImageList, create, 3}},
- {1777, {wxImageList, draw, 5}},
- {1778, {wxImageList, getBitmap, 1}},
- {1779, {wxImageList, getIcon, 1}},
- {1780, {wxImageList, getImageCount, 0}},
- {1781, {wxImageList, getSize, 3}},
- {1782, {wxImageList, remove, 1}},
- {1783, {wxImageList, removeAll, 0}},
- {1784, {wxImageList, replace_2, 2}},
- {1785, {wxImageList, replace_3, 3}},
- {1786, {wxImageList, 'Destroy', undefined}},
- {1787, {wxTextAttr, new_0, 0}},
- {1788, {wxTextAttr, new_2, 2}},
- {1789, {wxTextAttr, getAlignment, 0}},
- {1790, {wxTextAttr, getBackgroundColour, 0}},
- {1791, {wxTextAttr, getFont, 0}},
- {1792, {wxTextAttr, getLeftIndent, 0}},
- {1793, {wxTextAttr, getLeftSubIndent, 0}},
- {1794, {wxTextAttr, getRightIndent, 0}},
- {1795, {wxTextAttr, getTabs, 0}},
- {1796, {wxTextAttr, getTextColour, 0}},
- {1797, {wxTextAttr, hasBackgroundColour, 0}},
- {1798, {wxTextAttr, hasFont, 0}},
- {1799, {wxTextAttr, hasTextColour, 0}},
- {1800, {wxTextAttr, getFlags, 0}},
- {1801, {wxTextAttr, isDefault, 0}},
- {1802, {wxTextAttr, setAlignment, 1}},
- {1803, {wxTextAttr, setBackgroundColour, 1}},
- {1804, {wxTextAttr, setFlags, 1}},
- {1805, {wxTextAttr, setFont, 2}},
- {1806, {wxTextAttr, setLeftIndent, 2}},
- {1807, {wxTextAttr, setRightIndent, 1}},
- {1808, {wxTextAttr, setTabs, 1}},
- {1809, {wxTextAttr, setTextColour, 1}},
- {1810, {wxTextAttr, 'Destroy', undefined}},
- {1812, {wxTextCtrl, new_3, 3}},
- {1813, {wxTextCtrl, new_0, 0}},
- {1815, {wxTextCtrl, destruct, 0}},
- {1816, {wxTextCtrl, appendText, 1}},
- {1817, {wxTextCtrl, canCopy, 0}},
- {1818, {wxTextCtrl, canCut, 0}},
- {1819, {wxTextCtrl, canPaste, 0}},
- {1820, {wxTextCtrl, canRedo, 0}},
- {1821, {wxTextCtrl, canUndo, 0}},
- {1822, {wxTextCtrl, clear, 0}},
- {1823, {wxTextCtrl, copy, 0}},
- {1824, {wxTextCtrl, create, 3}},
- {1825, {wxTextCtrl, cut, 0}},
- {1826, {wxTextCtrl, discardEdits, 0}},
- {1827, {wxTextCtrl, changeValue, 1}},
- {1828, {wxTextCtrl, emulateKeyPress, 1}},
- {1829, {wxTextCtrl, getDefaultStyle, 0}},
- {1830, {wxTextCtrl, getInsertionPoint, 0}},
- {1831, {wxTextCtrl, getLastPosition, 0}},
- {1832, {wxTextCtrl, getLineLength, 1}},
- {1833, {wxTextCtrl, getLineText, 1}},
- {1834, {wxTextCtrl, getNumberOfLines, 0}},
- {1835, {wxTextCtrl, getRange, 2}},
- {1836, {wxTextCtrl, getSelection, 2}},
- {1837, {wxTextCtrl, getStringSelection, 0}},
- {1838, {wxTextCtrl, getStyle, 2}},
- {1839, {wxTextCtrl, getValue, 0}},
- {1840, {wxTextCtrl, isEditable, 0}},
- {1841, {wxTextCtrl, isModified, 0}},
- {1842, {wxTextCtrl, isMultiLine, 0}},
- {1843, {wxTextCtrl, isSingleLine, 0}},
- {1844, {wxTextCtrl, loadFile, 2}},
- {1845, {wxTextCtrl, markDirty, 0}},
- {1846, {wxTextCtrl, paste, 0}},
- {1847, {wxTextCtrl, positionToXY, 3}},
- {1848, {wxTextCtrl, redo, 0}},
- {1849, {wxTextCtrl, remove, 2}},
- {1850, {wxTextCtrl, replace, 3}},
- {1851, {wxTextCtrl, saveFile, 1}},
- {1852, {wxTextCtrl, setDefaultStyle, 1}},
- {1853, {wxTextCtrl, setEditable, 1}},
- {1854, {wxTextCtrl, setInsertionPoint, 1}},
- {1855, {wxTextCtrl, setInsertionPointEnd, 0}},
- {1857, {wxTextCtrl, setMaxLength, 1}},
- {1858, {wxTextCtrl, setSelection, 2}},
- {1859, {wxTextCtrl, setStyle, 3}},
- {1860, {wxTextCtrl, setValue, 1}},
- {1861, {wxTextCtrl, showPosition, 1}},
- {1862, {wxTextCtrl, undo, 0}},
- {1863, {wxTextCtrl, writeText, 1}},
- {1864, {wxTextCtrl, xYToPosition, 2}},
- {1867, {wxNotebook, new_0, 0}},
- {1868, {wxNotebook, new_3, 3}},
- {1869, {wxNotebook, destruct, 0}},
- {1870, {wxNotebook, addPage, 3}},
- {1871, {wxNotebook, advanceSelection, 1}},
- {1872, {wxNotebook, assignImageList, 1}},
- {1873, {wxNotebook, create, 3}},
- {1874, {wxNotebook, deleteAllPages, 0}},
- {1875, {wxNotebook, deletePage, 1}},
- {1876, {wxNotebook, removePage, 1}},
- {1877, {wxNotebook, getCurrentPage, 0}},
- {1878, {wxNotebook, getImageList, 0}},
- {1880, {wxNotebook, getPage, 1}},
- {1881, {wxNotebook, getPageCount, 0}},
- {1882, {wxNotebook, getPageImage, 1}},
- {1883, {wxNotebook, getPageText, 1}},
- {1884, {wxNotebook, getRowCount, 0}},
- {1885, {wxNotebook, getSelection, 0}},
- {1886, {wxNotebook, getThemeBackgroundColour, 0}},
- {1888, {wxNotebook, hitTest, 2}},
- {1890, {wxNotebook, insertPage, 4}},
- {1891, {wxNotebook, setImageList, 1}},
- {1892, {wxNotebook, setPadding, 1}},
- {1893, {wxNotebook, setPageSize, 1}},
- {1894, {wxNotebook, setPageImage, 2}},
- {1895, {wxNotebook, setPageText, 2}},
- {1896, {wxNotebook, setSelection, 1}},
- {1897, {wxNotebook, changeSelection, 1}},
- {1898, {wxChoicebook, new_0, 0}},
- {1899, {wxChoicebook, new_3, 3}},
- {1900, {wxChoicebook, addPage, 3}},
- {1901, {wxChoicebook, advanceSelection, 1}},
- {1902, {wxChoicebook, assignImageList, 1}},
- {1903, {wxChoicebook, create, 3}},
- {1904, {wxChoicebook, deleteAllPages, 0}},
- {1905, {wxChoicebook, deletePage, 1}},
- {1906, {wxChoicebook, removePage, 1}},
- {1907, {wxChoicebook, getCurrentPage, 0}},
- {1908, {wxChoicebook, getImageList, 0}},
- {1910, {wxChoicebook, getPage, 1}},
- {1911, {wxChoicebook, getPageCount, 0}},
- {1912, {wxChoicebook, getPageImage, 1}},
- {1913, {wxChoicebook, getPageText, 1}},
- {1914, {wxChoicebook, getSelection, 0}},
- {1915, {wxChoicebook, hitTest, 2}},
- {1916, {wxChoicebook, insertPage, 4}},
- {1917, {wxChoicebook, setImageList, 1}},
- {1918, {wxChoicebook, setPageSize, 1}},
- {1919, {wxChoicebook, setPageImage, 2}},
- {1920, {wxChoicebook, setPageText, 2}},
- {1921, {wxChoicebook, setSelection, 1}},
- {1922, {wxChoicebook, changeSelection, 1}},
- {1923, {wxChoicebook, 'Destroy', undefined}},
- {1924, {wxToolbook, new_0, 0}},
- {1925, {wxToolbook, new_3, 3}},
- {1926, {wxToolbook, addPage, 3}},
- {1927, {wxToolbook, advanceSelection, 1}},
- {1928, {wxToolbook, assignImageList, 1}},
- {1929, {wxToolbook, create, 3}},
- {1930, {wxToolbook, deleteAllPages, 0}},
- {1931, {wxToolbook, deletePage, 1}},
- {1932, {wxToolbook, removePage, 1}},
- {1933, {wxToolbook, getCurrentPage, 0}},
- {1934, {wxToolbook, getImageList, 0}},
- {1936, {wxToolbook, getPage, 1}},
- {1937, {wxToolbook, getPageCount, 0}},
- {1938, {wxToolbook, getPageImage, 1}},
- {1939, {wxToolbook, getPageText, 1}},
- {1940, {wxToolbook, getSelection, 0}},
- {1942, {wxToolbook, hitTest, 2}},
- {1943, {wxToolbook, insertPage, 4}},
- {1944, {wxToolbook, setImageList, 1}},
- {1945, {wxToolbook, setPageSize, 1}},
- {1946, {wxToolbook, setPageImage, 2}},
- {1947, {wxToolbook, setPageText, 2}},
- {1948, {wxToolbook, setSelection, 1}},
- {1949, {wxToolbook, changeSelection, 1}},
- {1950, {wxToolbook, 'Destroy', undefined}},
- {1951, {wxListbook, new_0, 0}},
- {1952, {wxListbook, new_3, 3}},
- {1953, {wxListbook, addPage, 3}},
- {1954, {wxListbook, advanceSelection, 1}},
- {1955, {wxListbook, assignImageList, 1}},
- {1956, {wxListbook, create, 3}},
- {1957, {wxListbook, deleteAllPages, 0}},
- {1958, {wxListbook, deletePage, 1}},
- {1959, {wxListbook, removePage, 1}},
- {1960, {wxListbook, getCurrentPage, 0}},
- {1961, {wxListbook, getImageList, 0}},
- {1963, {wxListbook, getPage, 1}},
- {1964, {wxListbook, getPageCount, 0}},
- {1965, {wxListbook, getPageImage, 1}},
- {1966, {wxListbook, getPageText, 1}},
- {1967, {wxListbook, getSelection, 0}},
- {1969, {wxListbook, hitTest, 2}},
- {1970, {wxListbook, insertPage, 4}},
- {1971, {wxListbook, setImageList, 1}},
- {1972, {wxListbook, setPageSize, 1}},
- {1973, {wxListbook, setPageImage, 2}},
- {1974, {wxListbook, setPageText, 2}},
- {1975, {wxListbook, setSelection, 1}},
- {1976, {wxListbook, changeSelection, 1}},
- {1977, {wxListbook, 'Destroy', undefined}},
- {1978, {wxTreebook, new_0, 0}},
- {1979, {wxTreebook, new_3, 3}},
- {1980, {wxTreebook, addPage, 3}},
- {1981, {wxTreebook, advanceSelection, 1}},
- {1982, {wxTreebook, assignImageList, 1}},
- {1983, {wxTreebook, create, 3}},
- {1984, {wxTreebook, deleteAllPages, 0}},
- {1985, {wxTreebook, deletePage, 1}},
- {1986, {wxTreebook, removePage, 1}},
- {1987, {wxTreebook, getCurrentPage, 0}},
- {1988, {wxTreebook, getImageList, 0}},
- {1990, {wxTreebook, getPage, 1}},
- {1991, {wxTreebook, getPageCount, 0}},
- {1992, {wxTreebook, getPageImage, 1}},
- {1993, {wxTreebook, getPageText, 1}},
- {1994, {wxTreebook, getSelection, 0}},
- {1995, {wxTreebook, expandNode, 2}},
- {1996, {wxTreebook, isNodeExpanded, 1}},
- {1998, {wxTreebook, hitTest, 2}},
- {1999, {wxTreebook, insertPage, 4}},
- {2000, {wxTreebook, insertSubPage, 4}},
- {2001, {wxTreebook, setImageList, 1}},
- {2002, {wxTreebook, setPageSize, 1}},
- {2003, {wxTreebook, setPageImage, 2}},
- {2004, {wxTreebook, setPageText, 2}},
- {2005, {wxTreebook, setSelection, 1}},
- {2006, {wxTreebook, changeSelection, 1}},
- {2007, {wxTreebook, 'Destroy', undefined}},
- {2010, {wxTreeCtrl, new_2, 2}},
- {2011, {wxTreeCtrl, new_0, 0}},
- {2013, {wxTreeCtrl, destruct, 0}},
- {2014, {wxTreeCtrl, addRoot, 2}},
- {2015, {wxTreeCtrl, appendItem, 3}},
- {2016, {wxTreeCtrl, assignImageList, 1}},
- {2017, {wxTreeCtrl, assignStateImageList, 1}},
- {2018, {wxTreeCtrl, collapse, 1}},
- {2019, {wxTreeCtrl, collapseAndReset, 1}},
- {2020, {wxTreeCtrl, create, 2}},
- {2021, {wxTreeCtrl, delete, 1}},
- {2022, {wxTreeCtrl, deleteAllItems, 0}},
- {2023, {wxTreeCtrl, deleteChildren, 1}},
- {2024, {wxTreeCtrl, editLabel, 1}},
- {2025, {wxTreeCtrl, ensureVisible, 1}},
- {2026, {wxTreeCtrl, expand, 1}},
- {2027, {wxTreeCtrl, getBoundingRect, 3}},
- {2029, {wxTreeCtrl, getChildrenCount, 2}},
- {2030, {wxTreeCtrl, getCount, 0}},
- {2031, {wxTreeCtrl, getEditControl, 0}},
- {2032, {wxTreeCtrl, getFirstChild, 2}},
- {2033, {wxTreeCtrl, getNextChild, 2}},
- {2034, {wxTreeCtrl, getFirstVisibleItem, 0}},
- {2035, {wxTreeCtrl, getImageList, 0}},
- {2036, {wxTreeCtrl, getIndent, 0}},
- {2037, {wxTreeCtrl, getItemBackgroundColour, 1}},
- {2038, {wxTreeCtrl, getItemData, 1}},
- {2039, {wxTreeCtrl, getItemFont, 1}},
- {2040, {wxTreeCtrl, getItemImage_1, 1}},
- {2041, {wxTreeCtrl, getItemImage_2, 2}},
- {2042, {wxTreeCtrl, getItemText, 1}},
- {2043, {wxTreeCtrl, getItemTextColour, 1}},
- {2044, {wxTreeCtrl, getLastChild, 1}},
- {2045, {wxTreeCtrl, getNextSibling, 1}},
- {2046, {wxTreeCtrl, getNextVisible, 1}},
- {2047, {wxTreeCtrl, getItemParent, 1}},
- {2048, {wxTreeCtrl, getPrevSibling, 1}},
- {2049, {wxTreeCtrl, getPrevVisible, 1}},
- {2050, {wxTreeCtrl, getRootItem, 0}},
- {2051, {wxTreeCtrl, getSelection, 0}},
- {2052, {wxTreeCtrl, getSelections, 1}},
- {2053, {wxTreeCtrl, getStateImageList, 0}},
- {2054, {wxTreeCtrl, hitTest, 2}},
- {2056, {wxTreeCtrl, insertItem, 4}},
- {2057, {wxTreeCtrl, isBold, 1}},
- {2058, {wxTreeCtrl, isExpanded, 1}},
- {2059, {wxTreeCtrl, isSelected, 1}},
- {2060, {wxTreeCtrl, isVisible, 1}},
- {2061, {wxTreeCtrl, itemHasChildren, 1}},
- {2062, {wxTreeCtrl, isTreeItemIdOk, 1}},
- {2063, {wxTreeCtrl, prependItem, 3}},
- {2064, {wxTreeCtrl, scrollTo, 1}},
- {2065, {wxTreeCtrl, selectItem_1, 1}},
- {2066, {wxTreeCtrl, selectItem_2, 2}},
- {2067, {wxTreeCtrl, setIndent, 1}},
- {2068, {wxTreeCtrl, setImageList, 1}},
- {2069, {wxTreeCtrl, setItemBackgroundColour, 2}},
- {2070, {wxTreeCtrl, setItemBold, 2}},
- {2071, {wxTreeCtrl, setItemData, 2}},
- {2072, {wxTreeCtrl, setItemDropHighlight, 2}},
- {2073, {wxTreeCtrl, setItemFont, 2}},
- {2074, {wxTreeCtrl, setItemHasChildren, 2}},
- {2075, {wxTreeCtrl, setItemImage_2, 2}},
- {2076, {wxTreeCtrl, setItemImage_3, 3}},
- {2077, {wxTreeCtrl, setItemText, 2}},
- {2078, {wxTreeCtrl, setItemTextColour, 2}},
- {2079, {wxTreeCtrl, setStateImageList, 1}},
- {2080, {wxTreeCtrl, setWindowStyle, 1}},
- {2081, {wxTreeCtrl, sortChildren, 1}},
- {2082, {wxTreeCtrl, toggle, 1}},
- {2083, {wxTreeCtrl, toggleItemSelection, 1}},
- {2084, {wxTreeCtrl, unselect, 0}},
- {2085, {wxTreeCtrl, unselectAll, 0}},
- {2086, {wxTreeCtrl, unselectItem, 1}},
- {2087, {wxScrollBar, new_0, 0}},
- {2088, {wxScrollBar, new_3, 3}},
- {2089, {wxScrollBar, destruct, 0}},
- {2090, {wxScrollBar, create, 3}},
- {2091, {wxScrollBar, getRange, 0}},
- {2092, {wxScrollBar, getPageSize, 0}},
- {2093, {wxScrollBar, getThumbPosition, 0}},
- {2094, {wxScrollBar, getThumbSize, 0}},
- {2095, {wxScrollBar, setThumbPosition, 1}},
- {2096, {wxScrollBar, setScrollbar, 5}},
- {2098, {wxSpinButton, new_2, 2}},
- {2099, {wxSpinButton, new_0, 0}},
- {2100, {wxSpinButton, create, 2}},
- {2101, {wxSpinButton, getMax, 0}},
- {2102, {wxSpinButton, getMin, 0}},
- {2103, {wxSpinButton, getValue, 0}},
- {2104, {wxSpinButton, setRange, 2}},
- {2105, {wxSpinButton, setValue, 1}},
- {2106, {wxSpinButton, 'Destroy', undefined}},
- {2107, {wxSpinCtrl, new_0, 0}},
- {2108, {wxSpinCtrl, new_2, 2}},
- {2110, {wxSpinCtrl, create, 2}},
- {2113, {wxSpinCtrl, setValue_1_1, 1}},
- {2114, {wxSpinCtrl, setValue_1_0, 1}},
- {2116, {wxSpinCtrl, getValue, 0}},
- {2118, {wxSpinCtrl, setRange, 2}},
- {2119, {wxSpinCtrl, setSelection, 2}},
- {2121, {wxSpinCtrl, getMin, 0}},
- {2123, {wxSpinCtrl, getMax, 0}},
- {2124, {wxSpinCtrl, 'Destroy', undefined}},
- {2125, {wxStaticText, new_0, 0}},
- {2126, {wxStaticText, new_4, 4}},
- {2127, {wxStaticText, create, 4}},
- {2128, {wxStaticText, getLabel, 0}},
- {2129, {wxStaticText, setLabel, 1}},
- {2130, {wxStaticText, wrap, 1}},
- {2131, {wxStaticText, 'Destroy', undefined}},
- {2132, {wxStaticBitmap, new_0, 0}},
- {2133, {wxStaticBitmap, new_4, 4}},
- {2134, {wxStaticBitmap, create, 4}},
- {2135, {wxStaticBitmap, getBitmap, 0}},
- {2136, {wxStaticBitmap, setBitmap, 1}},
- {2137, {wxStaticBitmap, 'Destroy', undefined}},
- {2138, {wxRadioBox, new, 7}},
- {2140, {wxRadioBox, destruct, 0}},
- {2141, {wxRadioBox, create, 7}},
- {2142, {wxRadioBox, enable_2, 2}},
- {2143, {wxRadioBox, enable_1, 1}},
- {2144, {wxRadioBox, getSelection, 0}},
- {2145, {wxRadioBox, getString, 1}},
- {2146, {wxRadioBox, setSelection, 1}},
- {2147, {wxRadioBox, show_2, 2}},
- {2148, {wxRadioBox, show_1, 1}},
- {2149, {wxRadioBox, getColumnCount, 0}},
- {2150, {wxRadioBox, getItemHelpText, 1}},
- {2151, {wxRadioBox, getItemToolTip, 1}},
- {2153, {wxRadioBox, getItemFromPoint, 1}},
- {2154, {wxRadioBox, getRowCount, 0}},
- {2155, {wxRadioBox, isItemEnabled, 1}},
- {2156, {wxRadioBox, isItemShown, 1}},
- {2157, {wxRadioBox, setItemHelpText, 2}},
- {2158, {wxRadioBox, setItemToolTip, 2}},
- {2159, {wxRadioButton, new_0, 0}},
- {2160, {wxRadioButton, new_4, 4}},
- {2161, {wxRadioButton, create, 4}},
- {2162, {wxRadioButton, getValue, 0}},
- {2163, {wxRadioButton, setValue, 1}},
- {2164, {wxRadioButton, 'Destroy', undefined}},
- {2166, {wxSlider, new_6, 6}},
- {2167, {wxSlider, new_0, 0}},
- {2168, {wxSlider, create, 6}},
- {2169, {wxSlider, getLineSize, 0}},
- {2170, {wxSlider, getMax, 0}},
- {2171, {wxSlider, getMin, 0}},
- {2172, {wxSlider, getPageSize, 0}},
- {2173, {wxSlider, getThumbLength, 0}},
- {2174, {wxSlider, getValue, 0}},
- {2175, {wxSlider, setLineSize, 1}},
- {2176, {wxSlider, setPageSize, 1}},
- {2177, {wxSlider, setRange, 2}},
- {2178, {wxSlider, setThumbLength, 1}},
- {2179, {wxSlider, setValue, 1}},
- {2180, {wxSlider, 'Destroy', undefined}},
- {2182, {wxDialog, new_4, 4}},
- {2183, {wxDialog, new_0, 0}},
- {2185, {wxDialog, destruct, 0}},
- {2186, {wxDialog, create, 4}},
- {2187, {wxDialog, createButtonSizer, 1}},
- {2188, {wxDialog, createStdDialogButtonSizer, 1}},
- {2189, {wxDialog, endModal, 1}},
- {2190, {wxDialog, getAffirmativeId, 0}},
- {2191, {wxDialog, getReturnCode, 0}},
- {2192, {wxDialog, isModal, 0}},
- {2193, {wxDialog, setAffirmativeId, 1}},
- {2194, {wxDialog, setReturnCode, 1}},
- {2195, {wxDialog, show, 1}},
- {2196, {wxDialog, showModal, 0}},
- {2197, {wxColourDialog, new_0, 0}},
- {2198, {wxColourDialog, new_2, 2}},
- {2199, {wxColourDialog, destruct, 0}},
- {2200, {wxColourDialog, create, 2}},
- {2201, {wxColourDialog, getColourData, 0}},
- {2202, {wxColourData, new_0, 0}},
- {2203, {wxColourData, new_1, 1}},
- {2204, {wxColourData, destruct, 0}},
- {2205, {wxColourData, getChooseFull, 0}},
- {2206, {wxColourData, getColour, 0}},
- {2208, {wxColourData, getCustomColour, 1}},
- {2209, {wxColourData, setChooseFull, 1}},
- {2210, {wxColourData, setColour, 1}},
- {2211, {wxColourData, setCustomColour, 2}},
- {2212, {wxPalette, new_0, 0}},
- {2213, {wxPalette, new_4, 4}},
- {2215, {wxPalette, destruct, 0}},
- {2216, {wxPalette, create, 4}},
- {2217, {wxPalette, getColoursCount, 0}},
- {2218, {wxPalette, getPixel, 3}},
- {2219, {wxPalette, getRGB, 4}},
- {2220, {wxPalette, isOk, 0}},
- {2224, {wxDirDialog, new, 2}},
- {2225, {wxDirDialog, destruct, 0}},
- {2226, {wxDirDialog, getPath, 0}},
- {2227, {wxDirDialog, getMessage, 0}},
- {2228, {wxDirDialog, setMessage, 1}},
- {2229, {wxDirDialog, setPath, 1}},
- {2233, {wxFileDialog, new, 2}},
- {2234, {wxFileDialog, destruct, 0}},
- {2235, {wxFileDialog, getDirectory, 0}},
- {2236, {wxFileDialog, getFilename, 0}},
- {2237, {wxFileDialog, getFilenames, 1}},
- {2238, {wxFileDialog, getFilterIndex, 0}},
- {2239, {wxFileDialog, getMessage, 0}},
- {2240, {wxFileDialog, getPath, 0}},
- {2241, {wxFileDialog, getPaths, 1}},
- {2242, {wxFileDialog, getWildcard, 0}},
- {2243, {wxFileDialog, setDirectory, 1}},
- {2244, {wxFileDialog, setFilename, 1}},
- {2245, {wxFileDialog, setFilterIndex, 1}},
- {2246, {wxFileDialog, setMessage, 1}},
- {2247, {wxFileDialog, setPath, 1}},
- {2248, {wxFileDialog, setWildcard, 1}},
- {2249, {wxPickerBase, setInternalMargin, 1}},
- {2250, {wxPickerBase, getInternalMargin, 0}},
- {2251, {wxPickerBase, setTextCtrlProportion, 1}},
- {2252, {wxPickerBase, setPickerCtrlProportion, 1}},
- {2253, {wxPickerBase, getTextCtrlProportion, 0}},
- {2254, {wxPickerBase, getPickerCtrlProportion, 0}},
- {2255, {wxPickerBase, hasTextCtrl, 0}},
- {2256, {wxPickerBase, getTextCtrl, 0}},
- {2257, {wxPickerBase, isTextCtrlGrowable, 0}},
- {2258, {wxPickerBase, setPickerCtrlGrowable, 1}},
- {2259, {wxPickerBase, setTextCtrlGrowable, 1}},
- {2260, {wxPickerBase, isPickerCtrlGrowable, 0}},
- {2261, {wxFilePickerCtrl, new_0, 0}},
- {2262, {wxFilePickerCtrl, new_3, 3}},
- {2263, {wxFilePickerCtrl, create, 3}},
- {2264, {wxFilePickerCtrl, getPath, 0}},
- {2265, {wxFilePickerCtrl, setPath, 1}},
- {2266, {wxFilePickerCtrl, 'Destroy', undefined}},
- {2267, {wxDirPickerCtrl, new_0, 0}},
- {2268, {wxDirPickerCtrl, new_3, 3}},
- {2269, {wxDirPickerCtrl, create, 3}},
- {2270, {wxDirPickerCtrl, getPath, 0}},
- {2271, {wxDirPickerCtrl, setPath, 1}},
- {2272, {wxDirPickerCtrl, 'Destroy', undefined}},
- {2273, {wxColourPickerCtrl, new_0, 0}},
- {2274, {wxColourPickerCtrl, new_3, 3}},
- {2275, {wxColourPickerCtrl, create, 3}},
- {2276, {wxColourPickerCtrl, getColour, 0}},
- {2277, {wxColourPickerCtrl, setColour_1_1, 1}},
- {2278, {wxColourPickerCtrl, setColour_1_0, 1}},
- {2279, {wxColourPickerCtrl, 'Destroy', undefined}},
- {2280, {wxDatePickerCtrl, new_0, 0}},
- {2281, {wxDatePickerCtrl, new_3, 3}},
- {2282, {wxDatePickerCtrl, getRange, 2}},
- {2283, {wxDatePickerCtrl, getValue, 0}},
- {2284, {wxDatePickerCtrl, setRange, 2}},
- {2285, {wxDatePickerCtrl, setValue, 1}},
- {2286, {wxDatePickerCtrl, 'Destroy', undefined}},
- {2287, {wxFontPickerCtrl, new_0, 0}},
- {2288, {wxFontPickerCtrl, new_3, 3}},
- {2289, {wxFontPickerCtrl, create, 3}},
- {2290, {wxFontPickerCtrl, getSelectedFont, 0}},
- {2291, {wxFontPickerCtrl, setSelectedFont, 1}},
- {2292, {wxFontPickerCtrl, getMaxPointSize, 0}},
- {2293, {wxFontPickerCtrl, setMaxPointSize, 1}},
- {2294, {wxFontPickerCtrl, 'Destroy', undefined}},
- {2297, {wxFindReplaceDialog, new_0, 0}},
- {2298, {wxFindReplaceDialog, new_4, 4}},
- {2299, {wxFindReplaceDialog, destruct, 0}},
- {2300, {wxFindReplaceDialog, create, 4}},
- {2301, {wxFindReplaceDialog, getData, 0}},
- {2302, {wxFindReplaceData, new_0, 0}},
- {2303, {wxFindReplaceData, new_1, 1}},
- {2304, {wxFindReplaceData, getFindString, 0}},
- {2305, {wxFindReplaceData, getReplaceString, 0}},
- {2306, {wxFindReplaceData, getFlags, 0}},
- {2307, {wxFindReplaceData, setFlags, 1}},
- {2308, {wxFindReplaceData, setFindString, 1}},
- {2309, {wxFindReplaceData, setReplaceString, 1}},
- {2310, {wxFindReplaceData, 'Destroy', undefined}},
- {2311, {wxMultiChoiceDialog, new_0, 0}},
- {2313, {wxMultiChoiceDialog, new_5, 5}},
- {2314, {wxMultiChoiceDialog, getSelections, 0}},
- {2315, {wxMultiChoiceDialog, setSelections, 1}},
- {2316, {wxMultiChoiceDialog, 'Destroy', undefined}},
- {2317, {wxSingleChoiceDialog, new_0, 0}},
- {2319, {wxSingleChoiceDialog, new_5, 5}},
- {2320, {wxSingleChoiceDialog, getSelection, 0}},
- {2321, {wxSingleChoiceDialog, getStringSelection, 0}},
- {2322, {wxSingleChoiceDialog, setSelection, 1}},
- {2323, {wxSingleChoiceDialog, 'Destroy', undefined}},
- {2324, {wxTextEntryDialog, new, 3}},
- {2325, {wxTextEntryDialog, getValue, 0}},
- {2326, {wxTextEntryDialog, setValue, 1}},
- {2327, {wxTextEntryDialog, 'Destroy', undefined}},
- {2328, {wxPasswordEntryDialog, new, 3}},
- {2329, {wxPasswordEntryDialog, 'Destroy', undefined}},
- {2330, {wxFontData, new_0, 0}},
- {2331, {wxFontData, new_1, 1}},
- {2332, {wxFontData, destruct, 0}},
- {2333, {wxFontData, enableEffects, 1}},
- {2334, {wxFontData, getAllowSymbols, 0}},
- {2335, {wxFontData, getColour, 0}},
- {2336, {wxFontData, getChosenFont, 0}},
- {2337, {wxFontData, getEnableEffects, 0}},
- {2338, {wxFontData, getInitialFont, 0}},
- {2339, {wxFontData, getShowHelp, 0}},
- {2340, {wxFontData, setAllowSymbols, 1}},
- {2341, {wxFontData, setChosenFont, 1}},
- {2342, {wxFontData, setColour, 1}},
- {2343, {wxFontData, setInitialFont, 1}},
- {2344, {wxFontData, setRange, 2}},
- {2345, {wxFontData, setShowHelp, 1}},
- {2349, {wxFontDialog, new_0, 0}},
- {2351, {wxFontDialog, new_2, 2}},
- {2353, {wxFontDialog, create, 2}},
- {2354, {wxFontDialog, getFontData, 0}},
- {2356, {wxFontDialog, 'Destroy', undefined}},
- {2357, {wxProgressDialog, new, 3}},
- {2358, {wxProgressDialog, destruct, 0}},
- {2359, {wxProgressDialog, resume, 0}},
- {2360, {wxProgressDialog, update_2, 2}},
- {2361, {wxProgressDialog, update_0, 0}},
- {2362, {wxMessageDialog, new, 3}},
- {2363, {wxMessageDialog, destruct, 0}},
- {2364, {wxPageSetupDialog, new, 2}},
- {2365, {wxPageSetupDialog, destruct, 0}},
- {2366, {wxPageSetupDialog, getPageSetupData, 0}},
- {2367, {wxPageSetupDialog, showModal, 0}},
- {2368, {wxPageSetupDialogData, new_0, 0}},
- {2369, {wxPageSetupDialogData, new_1_0, 1}},
- {2370, {wxPageSetupDialogData, new_1_1, 1}},
- {2371, {wxPageSetupDialogData, destruct, 0}},
- {2372, {wxPageSetupDialogData, enableHelp, 1}},
- {2373, {wxPageSetupDialogData, enableMargins, 1}},
- {2374, {wxPageSetupDialogData, enableOrientation, 1}},
- {2375, {wxPageSetupDialogData, enablePaper, 1}},
- {2376, {wxPageSetupDialogData, enablePrinter, 1}},
- {2377, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
- {2378, {wxPageSetupDialogData, getEnableMargins, 0}},
- {2379, {wxPageSetupDialogData, getEnableOrientation, 0}},
- {2380, {wxPageSetupDialogData, getEnablePaper, 0}},
- {2381, {wxPageSetupDialogData, getEnablePrinter, 0}},
- {2382, {wxPageSetupDialogData, getEnableHelp, 0}},
- {2383, {wxPageSetupDialogData, getDefaultInfo, 0}},
- {2384, {wxPageSetupDialogData, getMarginTopLeft, 0}},
- {2385, {wxPageSetupDialogData, getMarginBottomRight, 0}},
- {2386, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
- {2387, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
- {2388, {wxPageSetupDialogData, getPaperId, 0}},
- {2389, {wxPageSetupDialogData, getPaperSize, 0}},
- {2391, {wxPageSetupDialogData, getPrintData, 0}},
- {2392, {wxPageSetupDialogData, isOk, 0}},
- {2393, {wxPageSetupDialogData, setDefaultInfo, 1}},
- {2394, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
- {2395, {wxPageSetupDialogData, setMarginTopLeft, 1}},
- {2396, {wxPageSetupDialogData, setMarginBottomRight, 1}},
- {2397, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
- {2398, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
- {2399, {wxPageSetupDialogData, setPaperId, 1}},
- {2400, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
- {2401, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
- {2402, {wxPageSetupDialogData, setPrintData, 1}},
- {2403, {wxPrintDialog, new_2_0, 2}},
- {2404, {wxPrintDialog, new_2_1, 2}},
- {2405, {wxPrintDialog, destruct, 0}},
- {2406, {wxPrintDialog, getPrintDialogData, 0}},
- {2407, {wxPrintDialog, getPrintDC, 0}},
- {2408, {wxPrintDialogData, new_0, 0}},
- {2409, {wxPrintDialogData, new_1_1, 1}},
- {2410, {wxPrintDialogData, new_1_0, 1}},
- {2411, {wxPrintDialogData, destruct, 0}},
- {2412, {wxPrintDialogData, enableHelp, 1}},
- {2413, {wxPrintDialogData, enablePageNumbers, 1}},
- {2414, {wxPrintDialogData, enablePrintToFile, 1}},
- {2415, {wxPrintDialogData, enableSelection, 1}},
- {2416, {wxPrintDialogData, getAllPages, 0}},
- {2417, {wxPrintDialogData, getCollate, 0}},
- {2418, {wxPrintDialogData, getFromPage, 0}},
- {2419, {wxPrintDialogData, getMaxPage, 0}},
- {2420, {wxPrintDialogData, getMinPage, 0}},
- {2421, {wxPrintDialogData, getNoCopies, 0}},
- {2422, {wxPrintDialogData, getPrintData, 0}},
- {2423, {wxPrintDialogData, getPrintToFile, 0}},
- {2424, {wxPrintDialogData, getSelection, 0}},
- {2425, {wxPrintDialogData, getToPage, 0}},
- {2426, {wxPrintDialogData, isOk, 0}},
- {2427, {wxPrintDialogData, setCollate, 1}},
- {2428, {wxPrintDialogData, setFromPage, 1}},
- {2429, {wxPrintDialogData, setMaxPage, 1}},
- {2430, {wxPrintDialogData, setMinPage, 1}},
- {2431, {wxPrintDialogData, setNoCopies, 1}},
- {2432, {wxPrintDialogData, setPrintData, 1}},
- {2433, {wxPrintDialogData, setPrintToFile, 1}},
- {2434, {wxPrintDialogData, setSelection, 1}},
- {2435, {wxPrintDialogData, setToPage, 1}},
- {2436, {wxPrintData, new_0, 0}},
- {2437, {wxPrintData, new_1, 1}},
- {2438, {wxPrintData, destruct, 0}},
- {2439, {wxPrintData, getCollate, 0}},
- {2440, {wxPrintData, getBin, 0}},
- {2441, {wxPrintData, getColour, 0}},
- {2442, {wxPrintData, getDuplex, 0}},
- {2443, {wxPrintData, getNoCopies, 0}},
- {2444, {wxPrintData, getOrientation, 0}},
- {2445, {wxPrintData, getPaperId, 0}},
- {2446, {wxPrintData, getPrinterName, 0}},
- {2447, {wxPrintData, getQuality, 0}},
- {2448, {wxPrintData, isOk, 0}},
- {2449, {wxPrintData, setBin, 1}},
- {2450, {wxPrintData, setCollate, 1}},
- {2451, {wxPrintData, setColour, 1}},
- {2452, {wxPrintData, setDuplex, 1}},
- {2453, {wxPrintData, setNoCopies, 1}},
- {2454, {wxPrintData, setOrientation, 1}},
- {2455, {wxPrintData, setPaperId, 1}},
- {2456, {wxPrintData, setPrinterName, 1}},
- {2457, {wxPrintData, setQuality, 1}},
- {2460, {wxPrintPreview, new_2, 2}},
- {2461, {wxPrintPreview, new_3, 3}},
- {2463, {wxPrintPreview, destruct, 0}},
- {2464, {wxPrintPreview, getCanvas, 0}},
- {2465, {wxPrintPreview, getCurrentPage, 0}},
- {2466, {wxPrintPreview, getFrame, 0}},
- {2467, {wxPrintPreview, getMaxPage, 0}},
- {2468, {wxPrintPreview, getMinPage, 0}},
- {2469, {wxPrintPreview, getPrintout, 0}},
- {2470, {wxPrintPreview, getPrintoutForPrinting, 0}},
- {2471, {wxPrintPreview, isOk, 0}},
- {2472, {wxPrintPreview, paintPage, 2}},
- {2473, {wxPrintPreview, print, 1}},
- {2474, {wxPrintPreview, renderPage, 1}},
- {2475, {wxPrintPreview, setCanvas, 1}},
- {2476, {wxPrintPreview, setCurrentPage, 1}},
- {2477, {wxPrintPreview, setFrame, 1}},
- {2478, {wxPrintPreview, setPrintout, 1}},
- {2479, {wxPrintPreview, setZoom, 1}},
- {2480, {wxPreviewFrame, new, 3}},
- {2481, {wxPreviewFrame, destruct, 0}},
- {2482, {wxPreviewFrame, createControlBar, 0}},
- {2483, {wxPreviewFrame, createCanvas, 0}},
- {2484, {wxPreviewFrame, initialize, 0}},
- {2485, {wxPreviewFrame, onCloseWindow, 1}},
- {2486, {wxPreviewControlBar, new, 4}},
- {2487, {wxPreviewControlBar, destruct, 0}},
- {2488, {wxPreviewControlBar, createButtons, 0}},
- {2489, {wxPreviewControlBar, getPrintPreview, 0}},
- {2490, {wxPreviewControlBar, getZoomControl, 0}},
- {2491, {wxPreviewControlBar, setZoomControl, 1}},
- {2493, {wxPrinter, new, 1}},
- {2494, {wxPrinter, createAbortWindow, 2}},
- {2495, {wxPrinter, getAbort, 0}},
- {2496, {wxPrinter, getLastError, 0}},
- {2497, {wxPrinter, getPrintDialogData, 0}},
- {2498, {wxPrinter, print, 3}},
- {2499, {wxPrinter, printDialog, 1}},
- {2500, {wxPrinter, reportError, 3}},
- {2501, {wxPrinter, setup, 1}},
- {2502, {wxPrinter, 'Destroy', undefined}},
- {2503, {wxXmlResource, new_1, 1}},
- {2504, {wxXmlResource, new_2, 2}},
- {2505, {wxXmlResource, destruct, 0}},
- {2506, {wxXmlResource, attachUnknownControl, 3}},
- {2507, {wxXmlResource, clearHandlers, 0}},
- {2508, {wxXmlResource, compareVersion, 4}},
- {2509, {wxXmlResource, get, 0}},
- {2510, {wxXmlResource, getFlags, 0}},
- {2511, {wxXmlResource, getVersion, 0}},
- {2512, {wxXmlResource, getXRCID, 2}},
- {2513, {wxXmlResource, initAllHandlers, 0}},
- {2514, {wxXmlResource, load, 1}},
- {2515, {wxXmlResource, loadBitmap, 1}},
- {2516, {wxXmlResource, loadDialog_2, 2}},
- {2517, {wxXmlResource, loadDialog_3, 3}},
- {2518, {wxXmlResource, loadFrame_2, 2}},
- {2519, {wxXmlResource, loadFrame_3, 3}},
- {2520, {wxXmlResource, loadIcon, 1}},
- {2521, {wxXmlResource, loadMenu, 1}},
- {2522, {wxXmlResource, loadMenuBar_2, 2}},
- {2523, {wxXmlResource, loadMenuBar_1, 1}},
- {2524, {wxXmlResource, loadPanel_2, 2}},
- {2525, {wxXmlResource, loadPanel_3, 3}},
- {2526, {wxXmlResource, loadToolBar, 2}},
- {2527, {wxXmlResource, set, 1}},
- {2528, {wxXmlResource, setFlags, 1}},
- {2529, {wxXmlResource, unload, 1}},
- {2530, {wxXmlResource, xrcctrl, 3}},
- {2531, {wxHtmlEasyPrinting, new, 1}},
- {2532, {wxHtmlEasyPrinting, destruct, 0}},
- {2533, {wxHtmlEasyPrinting, getPrintData, 0}},
- {2534, {wxHtmlEasyPrinting, getPageSetupData, 0}},
- {2535, {wxHtmlEasyPrinting, previewFile, 1}},
- {2536, {wxHtmlEasyPrinting, previewText, 2}},
- {2537, {wxHtmlEasyPrinting, printFile, 1}},
- {2538, {wxHtmlEasyPrinting, printText, 2}},
- {2539, {wxHtmlEasyPrinting, pageSetup, 0}},
- {2540, {wxHtmlEasyPrinting, setFonts, 3}},
- {2541, {wxHtmlEasyPrinting, setHeader, 2}},
- {2542, {wxHtmlEasyPrinting, setFooter, 2}},
- {2544, {wxGLCanvas, new_2, 2}},
- {2545, {wxGLCanvas, new_3_1, 3}},
- {2546, {wxGLCanvas, new_3_0, 3}},
- {2547, {wxGLCanvas, getContext, 0}},
- {2549, {wxGLCanvas, setCurrent, 0}},
- {2550, {wxGLCanvas, swapBuffers, 0}},
- {2551, {wxGLCanvas, 'Destroy', undefined}},
- {2552, {wxAuiManager, new, 1}},
- {2553, {wxAuiManager, destruct, 0}},
- {2554, {wxAuiManager, addPane_2_1, 2}},
- {2555, {wxAuiManager, addPane_3, 3}},
- {2556, {wxAuiManager, addPane_2_0, 2}},
- {2557, {wxAuiManager, detachPane, 1}},
- {2558, {wxAuiManager, getAllPanes, 0}},
- {2559, {wxAuiManager, getArtProvider, 0}},
- {2560, {wxAuiManager, getDockSizeConstraint, 2}},
- {2561, {wxAuiManager, getFlags, 0}},
- {2562, {wxAuiManager, getManagedWindow, 0}},
- {2563, {wxAuiManager, getManager, 1}},
- {2564, {wxAuiManager, getPane_1_1, 1}},
- {2565, {wxAuiManager, getPane_1_0, 1}},
- {2566, {wxAuiManager, hideHint, 0}},
- {2567, {wxAuiManager, insertPane, 3}},
- {2568, {wxAuiManager, loadPaneInfo, 2}},
- {2569, {wxAuiManager, loadPerspective, 2}},
- {2570, {wxAuiManager, savePaneInfo, 1}},
- {2571, {wxAuiManager, savePerspective, 0}},
- {2572, {wxAuiManager, setArtProvider, 1}},
- {2573, {wxAuiManager, setDockSizeConstraint, 2}},
- {2574, {wxAuiManager, setFlags, 1}},
- {2575, {wxAuiManager, setManagedWindow, 1}},
- {2576, {wxAuiManager, showHint, 1}},
- {2577, {wxAuiManager, unInit, 0}},
- {2578, {wxAuiManager, update, 0}},
- {2579, {wxAuiPaneInfo, new_0, 0}},
- {2580, {wxAuiPaneInfo, new_1, 1}},
- {2581, {wxAuiPaneInfo, destruct, 0}},
- {2582, {wxAuiPaneInfo, bestSize_1, 1}},
- {2583, {wxAuiPaneInfo, bestSize_2, 2}},
- {2584, {wxAuiPaneInfo, bottom, 0}},
- {2585, {wxAuiPaneInfo, bottomDockable, 1}},
- {2586, {wxAuiPaneInfo, caption, 1}},
- {2587, {wxAuiPaneInfo, captionVisible, 1}},
- {2588, {wxAuiPaneInfo, centre, 0}},
- {2589, {wxAuiPaneInfo, centrePane, 0}},
- {2590, {wxAuiPaneInfo, closeButton, 1}},
- {2591, {wxAuiPaneInfo, defaultPane, 0}},
- {2592, {wxAuiPaneInfo, destroyOnClose, 1}},
- {2593, {wxAuiPaneInfo, direction, 1}},
- {2594, {wxAuiPaneInfo, dock, 0}},
- {2595, {wxAuiPaneInfo, dockable, 1}},
- {2596, {wxAuiPaneInfo, fixed, 0}},
- {2597, {wxAuiPaneInfo, float, 0}},
- {2598, {wxAuiPaneInfo, floatable, 1}},
- {2599, {wxAuiPaneInfo, floatingPosition_1, 1}},
- {2600, {wxAuiPaneInfo, floatingPosition_2, 2}},
- {2601, {wxAuiPaneInfo, floatingSize_1, 1}},
- {2602, {wxAuiPaneInfo, floatingSize_2, 2}},
- {2603, {wxAuiPaneInfo, gripper, 1}},
- {2604, {wxAuiPaneInfo, gripperTop, 1}},
- {2605, {wxAuiPaneInfo, hasBorder, 0}},
- {2606, {wxAuiPaneInfo, hasCaption, 0}},
- {2607, {wxAuiPaneInfo, hasCloseButton, 0}},
- {2608, {wxAuiPaneInfo, hasFlag, 1}},
- {2609, {wxAuiPaneInfo, hasGripper, 0}},
- {2610, {wxAuiPaneInfo, hasGripperTop, 0}},
- {2611, {wxAuiPaneInfo, hasMaximizeButton, 0}},
- {2612, {wxAuiPaneInfo, hasMinimizeButton, 0}},
- {2613, {wxAuiPaneInfo, hasPinButton, 0}},
- {2614, {wxAuiPaneInfo, hide, 0}},
- {2615, {wxAuiPaneInfo, isBottomDockable, 0}},
- {2616, {wxAuiPaneInfo, isDocked, 0}},
- {2617, {wxAuiPaneInfo, isFixed, 0}},
- {2618, {wxAuiPaneInfo, isFloatable, 0}},
- {2619, {wxAuiPaneInfo, isFloating, 0}},
- {2620, {wxAuiPaneInfo, isLeftDockable, 0}},
- {2621, {wxAuiPaneInfo, isMovable, 0}},
- {2622, {wxAuiPaneInfo, isOk, 0}},
- {2623, {wxAuiPaneInfo, isResizable, 0}},
- {2624, {wxAuiPaneInfo, isRightDockable, 0}},
- {2625, {wxAuiPaneInfo, isShown, 0}},
- {2626, {wxAuiPaneInfo, isToolbar, 0}},
- {2627, {wxAuiPaneInfo, isTopDockable, 0}},
- {2628, {wxAuiPaneInfo, layer, 1}},
- {2629, {wxAuiPaneInfo, left, 0}},
- {2630, {wxAuiPaneInfo, leftDockable, 1}},
- {2631, {wxAuiPaneInfo, maxSize_1, 1}},
- {2632, {wxAuiPaneInfo, maxSize_2, 2}},
- {2633, {wxAuiPaneInfo, maximizeButton, 1}},
- {2634, {wxAuiPaneInfo, minSize_1, 1}},
- {2635, {wxAuiPaneInfo, minSize_2, 2}},
- {2636, {wxAuiPaneInfo, minimizeButton, 1}},
- {2637, {wxAuiPaneInfo, movable, 1}},
- {2638, {wxAuiPaneInfo, name, 1}},
- {2639, {wxAuiPaneInfo, paneBorder, 1}},
- {2640, {wxAuiPaneInfo, pinButton, 1}},
- {2641, {wxAuiPaneInfo, position, 1}},
- {2642, {wxAuiPaneInfo, resizable, 1}},
- {2643, {wxAuiPaneInfo, right, 0}},
- {2644, {wxAuiPaneInfo, rightDockable, 1}},
- {2645, {wxAuiPaneInfo, row, 1}},
- {2646, {wxAuiPaneInfo, safeSet, 1}},
- {2647, {wxAuiPaneInfo, setFlag, 2}},
- {2648, {wxAuiPaneInfo, show, 1}},
- {2649, {wxAuiPaneInfo, toolbarPane, 0}},
- {2650, {wxAuiPaneInfo, top, 0}},
- {2651, {wxAuiPaneInfo, topDockable, 1}},
- {2652, {wxAuiPaneInfo, window, 1}},
- {2653, {wxAuiNotebook, new_0, 0}},
- {2654, {wxAuiNotebook, new_2, 2}},
- {2655, {wxAuiNotebook, addPage, 3}},
- {2656, {wxAuiNotebook, create, 2}},
- {2657, {wxAuiNotebook, deletePage, 1}},
- {2658, {wxAuiNotebook, getArtProvider, 0}},
- {2659, {wxAuiNotebook, getPage, 1}},
- {2660, {wxAuiNotebook, getPageBitmap, 1}},
- {2661, {wxAuiNotebook, getPageCount, 0}},
- {2662, {wxAuiNotebook, getPageIndex, 1}},
- {2663, {wxAuiNotebook, getPageText, 1}},
- {2664, {wxAuiNotebook, getSelection, 0}},
- {2665, {wxAuiNotebook, insertPage, 4}},
- {2666, {wxAuiNotebook, removePage, 1}},
- {2667, {wxAuiNotebook, setArtProvider, 1}},
- {2668, {wxAuiNotebook, setFont, 1}},
- {2669, {wxAuiNotebook, setPageBitmap, 2}},
- {2670, {wxAuiNotebook, setPageText, 2}},
- {2671, {wxAuiNotebook, setSelection, 1}},
- {2672, {wxAuiNotebook, setTabCtrlHeight, 1}},
- {2673, {wxAuiNotebook, setUniformBitmapSize, 1}},
- {2674, {wxAuiNotebook, 'Destroy', undefined}},
- {2675, {wxMDIParentFrame, new_0, 0}},
- {2676, {wxMDIParentFrame, new_4, 4}},
- {2677, {wxMDIParentFrame, destruct, 0}},
- {2678, {wxMDIParentFrame, activateNext, 0}},
- {2679, {wxMDIParentFrame, activatePrevious, 0}},
- {2680, {wxMDIParentFrame, arrangeIcons, 0}},
- {2681, {wxMDIParentFrame, cascade, 0}},
- {2682, {wxMDIParentFrame, create, 4}},
- {2683, {wxMDIParentFrame, getActiveChild, 0}},
- {2684, {wxMDIParentFrame, getClientWindow, 0}},
- {2685, {wxMDIParentFrame, tile, 1}},
- {2686, {wxMDIChildFrame, new_0, 0}},
- {2687, {wxMDIChildFrame, new_4, 4}},
- {2688, {wxMDIChildFrame, destruct, 0}},
- {2689, {wxMDIChildFrame, activate, 0}},
- {2690, {wxMDIChildFrame, create, 4}},
- {2691, {wxMDIChildFrame, maximize, 1}},
- {2692, {wxMDIChildFrame, restore, 0}},
- {2693, {wxMDIClientWindow, new_0, 0}},
- {2694, {wxMDIClientWindow, new_2, 2}},
- {2695, {wxMDIClientWindow, destruct, 0}},
- {2696, {wxMDIClientWindow, createClient, 2}},
- {2697, {wxLayoutAlgorithm, new, 0}},
- {2698, {wxLayoutAlgorithm, layoutFrame, 2}},
- {2699, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
- {2700, {wxLayoutAlgorithm, layoutWindow, 2}},
- {2701, {wxLayoutAlgorithm, 'Destroy', undefined}},
- {2702, {wxEvent, getId, 0}},
- {2703, {wxEvent, getSkipped, 0}},
- {2704, {wxEvent, getTimestamp, 0}},
- {2705, {wxEvent, isCommandEvent, 0}},
- {2706, {wxEvent, resumePropagation, 1}},
- {2707, {wxEvent, shouldPropagate, 0}},
- {2708, {wxEvent, skip, 1}},
- {2709, {wxEvent, stopPropagation, 0}},
- {2710, {wxCommandEvent, getClientData, 0}},
- {2711, {wxCommandEvent, getExtraLong, 0}},
- {2712, {wxCommandEvent, getInt, 0}},
- {2713, {wxCommandEvent, getSelection, 0}},
- {2714, {wxCommandEvent, getString, 0}},
- {2715, {wxCommandEvent, isChecked, 0}},
- {2716, {wxCommandEvent, isSelection, 0}},
- {2717, {wxCommandEvent, setInt, 1}},
- {2718, {wxCommandEvent, setString, 1}},
- {2719, {wxScrollEvent, getOrientation, 0}},
- {2720, {wxScrollEvent, getPosition, 0}},
- {2721, {wxScrollWinEvent, getOrientation, 0}},
- {2722, {wxScrollWinEvent, getPosition, 0}},
- {2723, {wxMouseEvent, altDown, 0}},
- {2724, {wxMouseEvent, button, 1}},
- {2725, {wxMouseEvent, buttonDClick, 1}},
- {2726, {wxMouseEvent, buttonDown, 1}},
- {2727, {wxMouseEvent, buttonUp, 1}},
- {2728, {wxMouseEvent, cmdDown, 0}},
- {2729, {wxMouseEvent, controlDown, 0}},
- {2730, {wxMouseEvent, dragging, 0}},
- {2731, {wxMouseEvent, entering, 0}},
- {2732, {wxMouseEvent, getButton, 0}},
- {2735, {wxMouseEvent, getPosition, 0}},
- {2736, {wxMouseEvent, getLogicalPosition, 1}},
- {2737, {wxMouseEvent, getLinesPerAction, 0}},
- {2738, {wxMouseEvent, getWheelRotation, 0}},
- {2739, {wxMouseEvent, getWheelDelta, 0}},
- {2740, {wxMouseEvent, getX, 0}},
- {2741, {wxMouseEvent, getY, 0}},
- {2742, {wxMouseEvent, isButton, 0}},
- {2743, {wxMouseEvent, isPageScroll, 0}},
- {2744, {wxMouseEvent, leaving, 0}},
- {2745, {wxMouseEvent, leftDClick, 0}},
- {2746, {wxMouseEvent, leftDown, 0}},
- {2747, {wxMouseEvent, leftIsDown, 0}},
- {2748, {wxMouseEvent, leftUp, 0}},
- {2749, {wxMouseEvent, metaDown, 0}},
- {2750, {wxMouseEvent, middleDClick, 0}},
- {2751, {wxMouseEvent, middleDown, 0}},
- {2752, {wxMouseEvent, middleIsDown, 0}},
- {2753, {wxMouseEvent, middleUp, 0}},
- {2754, {wxMouseEvent, moving, 0}},
- {2755, {wxMouseEvent, rightDClick, 0}},
- {2756, {wxMouseEvent, rightDown, 0}},
- {2757, {wxMouseEvent, rightIsDown, 0}},
- {2758, {wxMouseEvent, rightUp, 0}},
- {2759, {wxMouseEvent, shiftDown, 0}},
- {2760, {wxSetCursorEvent, getCursor, 0}},
- {2761, {wxSetCursorEvent, getX, 0}},
- {2762, {wxSetCursorEvent, getY, 0}},
- {2763, {wxSetCursorEvent, hasCursor, 0}},
- {2764, {wxSetCursorEvent, setCursor, 1}},
- {2765, {wxKeyEvent, altDown, 0}},
- {2766, {wxKeyEvent, cmdDown, 0}},
- {2767, {wxKeyEvent, controlDown, 0}},
- {2768, {wxKeyEvent, getKeyCode, 0}},
- {2769, {wxKeyEvent, getModifiers, 0}},
- {2772, {wxKeyEvent, getPosition, 0}},
- {2773, {wxKeyEvent, getRawKeyCode, 0}},
- {2774, {wxKeyEvent, getRawKeyFlags, 0}},
- {2775, {wxKeyEvent, getUnicodeKey, 0}},
- {2776, {wxKeyEvent, getX, 0}},
- {2777, {wxKeyEvent, getY, 0}},
- {2778, {wxKeyEvent, hasModifiers, 0}},
- {2779, {wxKeyEvent, metaDown, 0}},
- {2780, {wxKeyEvent, shiftDown, 0}},
- {2781, {wxSizeEvent, getSize, 0}},
- {2782, {wxMoveEvent, getPosition, 0}},
- {2783, {wxEraseEvent, getDC, 0}},
- {2784, {wxFocusEvent, getWindow, 0}},
- {2785, {wxChildFocusEvent, getWindow, 0}},
- {2786, {wxMenuEvent, getMenu, 0}},
- {2787, {wxMenuEvent, getMenuId, 0}},
- {2788, {wxMenuEvent, isPopup, 0}},
- {2789, {wxCloseEvent, canVeto, 0}},
- {2790, {wxCloseEvent, getLoggingOff, 0}},
- {2791, {wxCloseEvent, setCanVeto, 1}},
- {2792, {wxCloseEvent, setLoggingOff, 1}},
- {2793, {wxCloseEvent, veto, 1}},
- {2794, {wxShowEvent, setShow, 1}},
- {2795, {wxShowEvent, getShow, 0}},
- {2796, {wxIconizeEvent, iconized, 0}},
- {2797, {wxJoystickEvent, buttonDown, 1}},
- {2798, {wxJoystickEvent, buttonIsDown, 1}},
- {2799, {wxJoystickEvent, buttonUp, 1}},
- {2800, {wxJoystickEvent, getButtonChange, 0}},
- {2801, {wxJoystickEvent, getButtonState, 0}},
- {2802, {wxJoystickEvent, getJoystick, 0}},
- {2803, {wxJoystickEvent, getPosition, 0}},
- {2804, {wxJoystickEvent, getZPosition, 0}},
- {2805, {wxJoystickEvent, isButton, 0}},
- {2806, {wxJoystickEvent, isMove, 0}},
- {2807, {wxJoystickEvent, isZMove, 0}},
- {2808, {wxUpdateUIEvent, canUpdate, 1}},
- {2809, {wxUpdateUIEvent, check, 1}},
- {2810, {wxUpdateUIEvent, enable, 1}},
- {2811, {wxUpdateUIEvent, show, 1}},
- {2812, {wxUpdateUIEvent, getChecked, 0}},
- {2813, {wxUpdateUIEvent, getEnabled, 0}},
- {2814, {wxUpdateUIEvent, getShown, 0}},
- {2815, {wxUpdateUIEvent, getSetChecked, 0}},
- {2816, {wxUpdateUIEvent, getSetEnabled, 0}},
- {2817, {wxUpdateUIEvent, getSetShown, 0}},
- {2818, {wxUpdateUIEvent, getSetText, 0}},
- {2819, {wxUpdateUIEvent, getText, 0}},
- {2820, {wxUpdateUIEvent, getMode, 0}},
- {2821, {wxUpdateUIEvent, getUpdateInterval, 0}},
- {2822, {wxUpdateUIEvent, resetUpdateTime, 0}},
- {2823, {wxUpdateUIEvent, setMode, 1}},
- {2824, {wxUpdateUIEvent, setText, 1}},
- {2825, {wxUpdateUIEvent, setUpdateInterval, 1}},
- {2826, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
- {2827, {wxPaletteChangedEvent, setChangedWindow, 1}},
- {2828, {wxPaletteChangedEvent, getChangedWindow, 0}},
- {2829, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
- {2830, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
- {2831, {wxNavigationKeyEvent, getDirection, 0}},
- {2832, {wxNavigationKeyEvent, setDirection, 1}},
- {2833, {wxNavigationKeyEvent, isWindowChange, 0}},
- {2834, {wxNavigationKeyEvent, setWindowChange, 1}},
- {2835, {wxNavigationKeyEvent, isFromTab, 0}},
- {2836, {wxNavigationKeyEvent, setFromTab, 1}},
- {2837, {wxNavigationKeyEvent, getCurrentFocus, 0}},
- {2838, {wxNavigationKeyEvent, setCurrentFocus, 1}},
- {2839, {wxHelpEvent, getOrigin, 0}},
- {2840, {wxHelpEvent, getPosition, 0}},
- {2841, {wxHelpEvent, setOrigin, 1}},
- {2842, {wxHelpEvent, setPosition, 1}},
- {2843, {wxContextMenuEvent, getPosition, 0}},
- {2844, {wxContextMenuEvent, setPosition, 1}},
- {2845, {wxIdleEvent, canSend, 1}},
- {2846, {wxIdleEvent, getMode, 0}},
- {2847, {wxIdleEvent, requestMore, 1}},
- {2848, {wxIdleEvent, moreRequested, 0}},
- {2849, {wxIdleEvent, setMode, 1}},
- {2850, {wxGridEvent, altDown, 0}},
- {2851, {wxGridEvent, controlDown, 0}},
- {2852, {wxGridEvent, getCol, 0}},
- {2853, {wxGridEvent, getPosition, 0}},
- {2854, {wxGridEvent, getRow, 0}},
- {2855, {wxGridEvent, metaDown, 0}},
- {2856, {wxGridEvent, selecting, 0}},
- {2857, {wxGridEvent, shiftDown, 0}},
- {2858, {wxNotifyEvent, allow, 0}},
- {2859, {wxNotifyEvent, isAllowed, 0}},
- {2860, {wxNotifyEvent, veto, 0}},
- {2861, {wxSashEvent, getEdge, 0}},
- {2862, {wxSashEvent, getDragRect, 0}},
- {2863, {wxSashEvent, getDragStatus, 0}},
- {2864, {wxListEvent, getCacheFrom, 0}},
- {2865, {wxListEvent, getCacheTo, 0}},
- {2866, {wxListEvent, getKeyCode, 0}},
- {2867, {wxListEvent, getIndex, 0}},
- {2868, {wxListEvent, getColumn, 0}},
- {2869, {wxListEvent, getPoint, 0}},
- {2870, {wxListEvent, getLabel, 0}},
- {2871, {wxListEvent, getText, 0}},
- {2872, {wxListEvent, getImage, 0}},
- {2873, {wxListEvent, getData, 0}},
- {2874, {wxListEvent, getMask, 0}},
- {2875, {wxListEvent, getItem, 0}},
- {2876, {wxListEvent, isEditCancelled, 0}},
- {2877, {wxDateEvent, getDate, 0}},
- {2878, {wxCalendarEvent, getWeekDay, 0}},
- {2879, {wxFileDirPickerEvent, getPath, 0}},
- {2880, {wxColourPickerEvent, getColour, 0}},
- {2881, {wxFontPickerEvent, getFont, 0}},
- {2882, {wxStyledTextEvent, getPosition, 0}},
- {2883, {wxStyledTextEvent, getKey, 0}},
- {2884, {wxStyledTextEvent, getModifiers, 0}},
- {2885, {wxStyledTextEvent, getModificationType, 0}},
- {2886, {wxStyledTextEvent, getText, 0}},
- {2887, {wxStyledTextEvent, getLength, 0}},
- {2888, {wxStyledTextEvent, getLinesAdded, 0}},
- {2889, {wxStyledTextEvent, getLine, 0}},
- {2890, {wxStyledTextEvent, getFoldLevelNow, 0}},
- {2891, {wxStyledTextEvent, getFoldLevelPrev, 0}},
- {2892, {wxStyledTextEvent, getMargin, 0}},
- {2893, {wxStyledTextEvent, getMessage, 0}},
- {2894, {wxStyledTextEvent, getWParam, 0}},
- {2895, {wxStyledTextEvent, getLParam, 0}},
- {2896, {wxStyledTextEvent, getListType, 0}},
- {2897, {wxStyledTextEvent, getX, 0}},
- {2898, {wxStyledTextEvent, getY, 0}},
- {2899, {wxStyledTextEvent, getDragText, 0}},
- {2900, {wxStyledTextEvent, getDragAllowMove, 0}},
- {2901, {wxStyledTextEvent, getDragResult, 0}},
- {2902, {wxStyledTextEvent, getShift, 0}},
- {2903, {wxStyledTextEvent, getControl, 0}},
- {2904, {wxStyledTextEvent, getAlt, 0}},
- {2905, {utils, getKeyState, 1}},
- {2906, {utils, getMousePosition, 2}},
- {2907, {utils, getMouseState, 0}},
- {2908, {utils, setDetectableAutoRepeat, 1}},
- {2909, {utils, bell, 0}},
- {2910, {utils, findMenuItemId, 3}},
- {2911, {utils, genericFindWindowAtPoint, 1}},
- {2912, {utils, findWindowAtPoint, 1}},
- {2913, {utils, beginBusyCursor, 1}},
- {2914, {utils, endBusyCursor, 0}},
- {2915, {utils, isBusy, 0}},
- {2916, {utils, shutdown, 1}},
- {2917, {utils, shell, 1}},
- {2918, {utils, launchDefaultBrowser, 2}},
- {2919, {utils, getEmailAddress, 0}},
- {2920, {utils, getUserId, 0}},
- {2921, {utils, getHomeDir, 0}},
- {2922, {utils, newId, 0}},
- {2923, {utils, registerId, 1}},
- {2924, {utils, getCurrentId, 0}},
- {2925, {utils, getOsDescription, 0}},
- {2926, {utils, isPlatformLittleEndian, 0}},
- {2927, {utils, isPlatform64Bit, 0}},
- {2928, {gdicmn, displaySize, 2}},
- {2929, {gdicmn, setCursor, 1}},
- {2930, {wxPrintout, new, 1}},
- {2931, {wxPrintout, destruct, 0}},
- {2932, {wxPrintout, getDC, 0}},
- {2933, {wxPrintout, getPageSizeMM, 2}},
- {2934, {wxPrintout, getPageSizePixels, 2}},
- {2935, {wxPrintout, getPaperRectPixels, 0}},
- {2936, {wxPrintout, getPPIPrinter, 2}},
- {2937, {wxPrintout, getPPIScreen, 2}},
- {2938, {wxPrintout, getTitle, 0}},
- {2939, {wxPrintout, isPreview, 0}},
- {2940, {wxPrintout, fitThisSizeToPaper, 1}},
- {2941, {wxPrintout, fitThisSizeToPage, 1}},
- {2942, {wxPrintout, fitThisSizeToPageMargins, 2}},
- {2943, {wxPrintout, mapScreenSizeToPaper, 0}},
- {2944, {wxPrintout, mapScreenSizeToPage, 0}},
- {2945, {wxPrintout, mapScreenSizeToPageMargins, 1}},
- {2946, {wxPrintout, mapScreenSizeToDevice, 0}},
- {2947, {wxPrintout, getLogicalPaperRect, 0}},
- {2948, {wxPrintout, getLogicalPageRect, 0}},
- {2949, {wxPrintout, getLogicalPageMarginsRect, 1}},
- {2950, {wxPrintout, setLogicalOrigin, 2}},
- {2951, {wxPrintout, offsetLogicalOrigin, 2}},
- {2952, {wxStyledTextCtrl, new_2, 2}},
- {2953, {wxStyledTextCtrl, new_0, 0}},
- {2954, {wxStyledTextCtrl, destruct, 0}},
- {2955, {wxStyledTextCtrl, create, 2}},
- {2956, {wxStyledTextCtrl, addText, 1}},
- {2957, {wxStyledTextCtrl, addStyledText, 1}},
- {2958, {wxStyledTextCtrl, insertText, 2}},
- {2959, {wxStyledTextCtrl, clearAll, 0}},
- {2960, {wxStyledTextCtrl, clearDocumentStyle, 0}},
- {2961, {wxStyledTextCtrl, getLength, 0}},
- {2962, {wxStyledTextCtrl, getCharAt, 1}},
- {2963, {wxStyledTextCtrl, getCurrentPos, 0}},
- {2964, {wxStyledTextCtrl, getAnchor, 0}},
- {2965, {wxStyledTextCtrl, getStyleAt, 1}},
- {2966, {wxStyledTextCtrl, redo, 0}},
- {2967, {wxStyledTextCtrl, setUndoCollection, 1}},
- {2968, {wxStyledTextCtrl, selectAll, 0}},
- {2969, {wxStyledTextCtrl, setSavePoint, 0}},
- {2970, {wxStyledTextCtrl, getStyledText, 2}},
- {2971, {wxStyledTextCtrl, canRedo, 0}},
- {2972, {wxStyledTextCtrl, markerLineFromHandle, 1}},
- {2973, {wxStyledTextCtrl, markerDeleteHandle, 1}},
- {2974, {wxStyledTextCtrl, getUndoCollection, 0}},
- {2975, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
- {2976, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
- {2977, {wxStyledTextCtrl, positionFromPoint, 1}},
- {2978, {wxStyledTextCtrl, positionFromPointClose, 2}},
- {2979, {wxStyledTextCtrl, gotoLine, 1}},
- {2980, {wxStyledTextCtrl, gotoPos, 1}},
- {2981, {wxStyledTextCtrl, setAnchor, 1}},
- {2982, {wxStyledTextCtrl, getCurLine, 1}},
- {2983, {wxStyledTextCtrl, getEndStyled, 0}},
- {2984, {wxStyledTextCtrl, convertEOLs, 1}},
- {2985, {wxStyledTextCtrl, getEOLMode, 0}},
- {2986, {wxStyledTextCtrl, setEOLMode, 1}},
- {2987, {wxStyledTextCtrl, startStyling, 2}},
- {2988, {wxStyledTextCtrl, setStyling, 2}},
- {2989, {wxStyledTextCtrl, getBufferedDraw, 0}},
- {2990, {wxStyledTextCtrl, setBufferedDraw, 1}},
- {2991, {wxStyledTextCtrl, setTabWidth, 1}},
- {2992, {wxStyledTextCtrl, getTabWidth, 0}},
- {2993, {wxStyledTextCtrl, setCodePage, 1}},
- {2994, {wxStyledTextCtrl, markerDefine, 3}},
- {2995, {wxStyledTextCtrl, markerSetForeground, 2}},
- {2996, {wxStyledTextCtrl, markerSetBackground, 2}},
- {2997, {wxStyledTextCtrl, markerAdd, 2}},
- {2998, {wxStyledTextCtrl, markerDelete, 2}},
- {2999, {wxStyledTextCtrl, markerDeleteAll, 1}},
- {3000, {wxStyledTextCtrl, markerGet, 1}},
- {3001, {wxStyledTextCtrl, markerNext, 2}},
- {3002, {wxStyledTextCtrl, markerPrevious, 2}},
- {3003, {wxStyledTextCtrl, markerDefineBitmap, 2}},
- {3004, {wxStyledTextCtrl, markerAddSet, 2}},
- {3005, {wxStyledTextCtrl, markerSetAlpha, 2}},
- {3006, {wxStyledTextCtrl, setMarginType, 2}},
- {3007, {wxStyledTextCtrl, getMarginType, 1}},
- {3008, {wxStyledTextCtrl, setMarginWidth, 2}},
- {3009, {wxStyledTextCtrl, getMarginWidth, 1}},
- {3010, {wxStyledTextCtrl, setMarginMask, 2}},
- {3011, {wxStyledTextCtrl, getMarginMask, 1}},
- {3012, {wxStyledTextCtrl, setMarginSensitive, 2}},
- {3013, {wxStyledTextCtrl, getMarginSensitive, 1}},
- {3014, {wxStyledTextCtrl, styleClearAll, 0}},
- {3015, {wxStyledTextCtrl, styleSetForeground, 2}},
- {3016, {wxStyledTextCtrl, styleSetBackground, 2}},
- {3017, {wxStyledTextCtrl, styleSetBold, 2}},
- {3018, {wxStyledTextCtrl, styleSetItalic, 2}},
- {3019, {wxStyledTextCtrl, styleSetSize, 2}},
- {3020, {wxStyledTextCtrl, styleSetFaceName, 2}},
- {3021, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
- {3022, {wxStyledTextCtrl, styleResetDefault, 0}},
- {3023, {wxStyledTextCtrl, styleSetUnderline, 2}},
- {3024, {wxStyledTextCtrl, styleSetCase, 2}},
- {3025, {wxStyledTextCtrl, styleSetHotSpot, 2}},
- {3026, {wxStyledTextCtrl, setSelForeground, 2}},
- {3027, {wxStyledTextCtrl, setSelBackground, 2}},
- {3028, {wxStyledTextCtrl, getSelAlpha, 0}},
- {3029, {wxStyledTextCtrl, setSelAlpha, 1}},
- {3030, {wxStyledTextCtrl, setCaretForeground, 1}},
- {3031, {wxStyledTextCtrl, cmdKeyAssign, 3}},
- {3032, {wxStyledTextCtrl, cmdKeyClear, 2}},
- {3033, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
- {3034, {wxStyledTextCtrl, setStyleBytes, 2}},
- {3035, {wxStyledTextCtrl, styleSetVisible, 2}},
- {3036, {wxStyledTextCtrl, getCaretPeriod, 0}},
- {3037, {wxStyledTextCtrl, setCaretPeriod, 1}},
- {3038, {wxStyledTextCtrl, setWordChars, 1}},
- {3039, {wxStyledTextCtrl, beginUndoAction, 0}},
- {3040, {wxStyledTextCtrl, endUndoAction, 0}},
- {3041, {wxStyledTextCtrl, indicatorSetStyle, 2}},
- {3042, {wxStyledTextCtrl, indicatorGetStyle, 1}},
- {3043, {wxStyledTextCtrl, indicatorSetForeground, 2}},
- {3044, {wxStyledTextCtrl, indicatorGetForeground, 1}},
- {3045, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
- {3046, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
- {3047, {wxStyledTextCtrl, getStyleBits, 0}},
- {3048, {wxStyledTextCtrl, setLineState, 2}},
- {3049, {wxStyledTextCtrl, getLineState, 1}},
- {3050, {wxStyledTextCtrl, getMaxLineState, 0}},
- {3051, {wxStyledTextCtrl, getCaretLineVisible, 0}},
- {3052, {wxStyledTextCtrl, setCaretLineVisible, 1}},
- {3053, {wxStyledTextCtrl, getCaretLineBackground, 0}},
- {3054, {wxStyledTextCtrl, setCaretLineBackground, 1}},
- {3055, {wxStyledTextCtrl, autoCompShow, 2}},
- {3056, {wxStyledTextCtrl, autoCompCancel, 0}},
- {3057, {wxStyledTextCtrl, autoCompActive, 0}},
- {3058, {wxStyledTextCtrl, autoCompPosStart, 0}},
- {3059, {wxStyledTextCtrl, autoCompComplete, 0}},
- {3060, {wxStyledTextCtrl, autoCompStops, 1}},
- {3061, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
- {3062, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
- {3063, {wxStyledTextCtrl, autoCompSelect, 1}},
- {3064, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
- {3065, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
- {3066, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
- {3067, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
- {3068, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
- {3069, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
- {3070, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
- {3071, {wxStyledTextCtrl, userListShow, 2}},
- {3072, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
- {3073, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
- {3074, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
- {3075, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
- {3076, {wxStyledTextCtrl, registerImage, 2}},
- {3077, {wxStyledTextCtrl, clearRegisteredImages, 0}},
- {3078, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
- {3079, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
- {3080, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
- {3081, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
- {3082, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
- {3083, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
- {3084, {wxStyledTextCtrl, setIndent, 1}},
- {3085, {wxStyledTextCtrl, getIndent, 0}},
- {3086, {wxStyledTextCtrl, setUseTabs, 1}},
- {3087, {wxStyledTextCtrl, getUseTabs, 0}},
- {3088, {wxStyledTextCtrl, setLineIndentation, 2}},
- {3089, {wxStyledTextCtrl, getLineIndentation, 1}},
- {3090, {wxStyledTextCtrl, getLineIndentPosition, 1}},
- {3091, {wxStyledTextCtrl, getColumn, 1}},
- {3092, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
- {3093, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
- {3094, {wxStyledTextCtrl, setIndentationGuides, 1}},
- {3095, {wxStyledTextCtrl, getIndentationGuides, 0}},
- {3096, {wxStyledTextCtrl, setHighlightGuide, 1}},
- {3097, {wxStyledTextCtrl, getHighlightGuide, 0}},
- {3098, {wxStyledTextCtrl, getLineEndPosition, 1}},
- {3099, {wxStyledTextCtrl, getCodePage, 0}},
- {3100, {wxStyledTextCtrl, getCaretForeground, 0}},
- {3101, {wxStyledTextCtrl, getReadOnly, 0}},
- {3102, {wxStyledTextCtrl, setCurrentPos, 1}},
- {3103, {wxStyledTextCtrl, setSelectionStart, 1}},
- {3104, {wxStyledTextCtrl, getSelectionStart, 0}},
- {3105, {wxStyledTextCtrl, setSelectionEnd, 1}},
- {3106, {wxStyledTextCtrl, getSelectionEnd, 0}},
- {3107, {wxStyledTextCtrl, setPrintMagnification, 1}},
- {3108, {wxStyledTextCtrl, getPrintMagnification, 0}},
- {3109, {wxStyledTextCtrl, setPrintColourMode, 1}},
- {3110, {wxStyledTextCtrl, getPrintColourMode, 0}},
- {3111, {wxStyledTextCtrl, findText, 4}},
- {3112, {wxStyledTextCtrl, formatRange, 7}},
- {3113, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
- {3114, {wxStyledTextCtrl, getLine, 1}},
- {3115, {wxStyledTextCtrl, getLineCount, 0}},
- {3116, {wxStyledTextCtrl, setMarginLeft, 1}},
- {3117, {wxStyledTextCtrl, getMarginLeft, 0}},
- {3118, {wxStyledTextCtrl, setMarginRight, 1}},
- {3119, {wxStyledTextCtrl, getMarginRight, 0}},
- {3120, {wxStyledTextCtrl, getModify, 0}},
- {3121, {wxStyledTextCtrl, setSelection, 2}},
- {3122, {wxStyledTextCtrl, getSelectedText, 0}},
- {3123, {wxStyledTextCtrl, getTextRange, 2}},
- {3124, {wxStyledTextCtrl, hideSelection, 1}},
- {3125, {wxStyledTextCtrl, lineFromPosition, 1}},
- {3126, {wxStyledTextCtrl, positionFromLine, 1}},
- {3127, {wxStyledTextCtrl, lineScroll, 2}},
- {3128, {wxStyledTextCtrl, ensureCaretVisible, 0}},
- {3129, {wxStyledTextCtrl, replaceSelection, 1}},
- {3130, {wxStyledTextCtrl, setReadOnly, 1}},
- {3131, {wxStyledTextCtrl, canPaste, 0}},
- {3132, {wxStyledTextCtrl, canUndo, 0}},
- {3133, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
- {3134, {wxStyledTextCtrl, undo, 0}},
- {3135, {wxStyledTextCtrl, cut, 0}},
- {3136, {wxStyledTextCtrl, copy, 0}},
- {3137, {wxStyledTextCtrl, paste, 0}},
- {3138, {wxStyledTextCtrl, clear, 0}},
- {3139, {wxStyledTextCtrl, setText, 1}},
- {3140, {wxStyledTextCtrl, getText, 0}},
- {3141, {wxStyledTextCtrl, getTextLength, 0}},
- {3142, {wxStyledTextCtrl, getOvertype, 0}},
- {3143, {wxStyledTextCtrl, setCaretWidth, 1}},
- {3144, {wxStyledTextCtrl, getCaretWidth, 0}},
- {3145, {wxStyledTextCtrl, setTargetStart, 1}},
- {3146, {wxStyledTextCtrl, getTargetStart, 0}},
- {3147, {wxStyledTextCtrl, setTargetEnd, 1}},
- {3148, {wxStyledTextCtrl, getTargetEnd, 0}},
- {3149, {wxStyledTextCtrl, replaceTarget, 1}},
- {3150, {wxStyledTextCtrl, searchInTarget, 1}},
- {3151, {wxStyledTextCtrl, setSearchFlags, 1}},
- {3152, {wxStyledTextCtrl, getSearchFlags, 0}},
- {3153, {wxStyledTextCtrl, callTipShow, 2}},
- {3154, {wxStyledTextCtrl, callTipCancel, 0}},
- {3155, {wxStyledTextCtrl, callTipActive, 0}},
- {3156, {wxStyledTextCtrl, callTipPosAtStart, 0}},
- {3157, {wxStyledTextCtrl, callTipSetHighlight, 2}},
- {3158, {wxStyledTextCtrl, callTipSetBackground, 1}},
- {3159, {wxStyledTextCtrl, callTipSetForeground, 1}},
- {3160, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
- {3161, {wxStyledTextCtrl, callTipUseStyle, 1}},
- {3162, {wxStyledTextCtrl, visibleFromDocLine, 1}},
- {3163, {wxStyledTextCtrl, docLineFromVisible, 1}},
- {3164, {wxStyledTextCtrl, wrapCount, 1}},
- {3165, {wxStyledTextCtrl, setFoldLevel, 2}},
- {3166, {wxStyledTextCtrl, getFoldLevel, 1}},
- {3167, {wxStyledTextCtrl, getLastChild, 2}},
- {3168, {wxStyledTextCtrl, getFoldParent, 1}},
- {3169, {wxStyledTextCtrl, showLines, 2}},
- {3170, {wxStyledTextCtrl, hideLines, 2}},
- {3171, {wxStyledTextCtrl, getLineVisible, 1}},
- {3172, {wxStyledTextCtrl, setFoldExpanded, 2}},
- {3173, {wxStyledTextCtrl, getFoldExpanded, 1}},
- {3174, {wxStyledTextCtrl, toggleFold, 1}},
- {3175, {wxStyledTextCtrl, ensureVisible, 1}},
- {3176, {wxStyledTextCtrl, setFoldFlags, 1}},
- {3177, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
- {3178, {wxStyledTextCtrl, setTabIndents, 1}},
- {3179, {wxStyledTextCtrl, getTabIndents, 0}},
- {3180, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
- {3181, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
- {3182, {wxStyledTextCtrl, setMouseDwellTime, 1}},
- {3183, {wxStyledTextCtrl, getMouseDwellTime, 0}},
- {3184, {wxStyledTextCtrl, wordStartPosition, 2}},
- {3185, {wxStyledTextCtrl, wordEndPosition, 2}},
- {3186, {wxStyledTextCtrl, setWrapMode, 1}},
- {3187, {wxStyledTextCtrl, getWrapMode, 0}},
- {3188, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
- {3189, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
- {3190, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
- {3191, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
- {3192, {wxStyledTextCtrl, setWrapStartIndent, 1}},
- {3193, {wxStyledTextCtrl, getWrapStartIndent, 0}},
- {3194, {wxStyledTextCtrl, setLayoutCache, 1}},
- {3195, {wxStyledTextCtrl, getLayoutCache, 0}},
- {3196, {wxStyledTextCtrl, setScrollWidth, 1}},
- {3197, {wxStyledTextCtrl, getScrollWidth, 0}},
- {3198, {wxStyledTextCtrl, textWidth, 2}},
- {3199, {wxStyledTextCtrl, getEndAtLastLine, 0}},
- {3200, {wxStyledTextCtrl, textHeight, 1}},
- {3201, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
- {3202, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
- {3203, {wxStyledTextCtrl, appendText, 1}},
- {3204, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
- {3205, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
- {3206, {wxStyledTextCtrl, targetFromSelection, 0}},
- {3207, {wxStyledTextCtrl, linesJoin, 0}},
- {3208, {wxStyledTextCtrl, linesSplit, 1}},
- {3209, {wxStyledTextCtrl, setFoldMarginColour, 2}},
- {3210, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
- {3211, {wxStyledTextCtrl, lineDown, 0}},
- {3212, {wxStyledTextCtrl, lineDownExtend, 0}},
- {3213, {wxStyledTextCtrl, lineUp, 0}},
- {3214, {wxStyledTextCtrl, lineUpExtend, 0}},
- {3215, {wxStyledTextCtrl, charLeft, 0}},
- {3216, {wxStyledTextCtrl, charLeftExtend, 0}},
- {3217, {wxStyledTextCtrl, charRight, 0}},
- {3218, {wxStyledTextCtrl, charRightExtend, 0}},
- {3219, {wxStyledTextCtrl, wordLeft, 0}},
- {3220, {wxStyledTextCtrl, wordLeftExtend, 0}},
- {3221, {wxStyledTextCtrl, wordRight, 0}},
- {3222, {wxStyledTextCtrl, wordRightExtend, 0}},
- {3223, {wxStyledTextCtrl, home, 0}},
- {3224, {wxStyledTextCtrl, homeExtend, 0}},
- {3225, {wxStyledTextCtrl, lineEnd, 0}},
- {3226, {wxStyledTextCtrl, lineEndExtend, 0}},
- {3227, {wxStyledTextCtrl, documentStart, 0}},
- {3228, {wxStyledTextCtrl, documentStartExtend, 0}},
- {3229, {wxStyledTextCtrl, documentEnd, 0}},
- {3230, {wxStyledTextCtrl, documentEndExtend, 0}},
- {3231, {wxStyledTextCtrl, pageUp, 0}},
- {3232, {wxStyledTextCtrl, pageUpExtend, 0}},
- {3233, {wxStyledTextCtrl, pageDown, 0}},
- {3234, {wxStyledTextCtrl, pageDownExtend, 0}},
- {3235, {wxStyledTextCtrl, editToggleOvertype, 0}},
- {3236, {wxStyledTextCtrl, cancel, 0}},
- {3237, {wxStyledTextCtrl, deleteBack, 0}},
- {3238, {wxStyledTextCtrl, tab, 0}},
- {3239, {wxStyledTextCtrl, backTab, 0}},
- {3240, {wxStyledTextCtrl, newLine, 0}},
- {3241, {wxStyledTextCtrl, formFeed, 0}},
- {3242, {wxStyledTextCtrl, vCHome, 0}},
- {3243, {wxStyledTextCtrl, vCHomeExtend, 0}},
- {3244, {wxStyledTextCtrl, zoomIn, 0}},
- {3245, {wxStyledTextCtrl, zoomOut, 0}},
- {3246, {wxStyledTextCtrl, delWordLeft, 0}},
- {3247, {wxStyledTextCtrl, delWordRight, 0}},
- {3248, {wxStyledTextCtrl, lineCut, 0}},
- {3249, {wxStyledTextCtrl, lineDelete, 0}},
- {3250, {wxStyledTextCtrl, lineTranspose, 0}},
- {3251, {wxStyledTextCtrl, lineDuplicate, 0}},
- {3252, {wxStyledTextCtrl, lowerCase, 0}},
- {3253, {wxStyledTextCtrl, upperCase, 0}},
- {3254, {wxStyledTextCtrl, lineScrollDown, 0}},
- {3255, {wxStyledTextCtrl, lineScrollUp, 0}},
- {3256, {wxStyledTextCtrl, deleteBackNotLine, 0}},
- {3257, {wxStyledTextCtrl, homeDisplay, 0}},
- {3258, {wxStyledTextCtrl, homeDisplayExtend, 0}},
- {3259, {wxStyledTextCtrl, lineEndDisplay, 0}},
- {3260, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
- {3261, {wxStyledTextCtrl, homeWrapExtend, 0}},
- {3262, {wxStyledTextCtrl, lineEndWrap, 0}},
- {3263, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
- {3264, {wxStyledTextCtrl, vCHomeWrap, 0}},
- {3265, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
- {3266, {wxStyledTextCtrl, lineCopy, 0}},
- {3267, {wxStyledTextCtrl, moveCaretInsideView, 0}},
- {3268, {wxStyledTextCtrl, lineLength, 1}},
- {3269, {wxStyledTextCtrl, braceHighlight, 2}},
- {3270, {wxStyledTextCtrl, braceBadLight, 1}},
- {3271, {wxStyledTextCtrl, braceMatch, 1}},
- {3272, {wxStyledTextCtrl, getViewEOL, 0}},
- {3273, {wxStyledTextCtrl, setViewEOL, 1}},
- {3274, {wxStyledTextCtrl, setModEventMask, 1}},
- {3275, {wxStyledTextCtrl, getEdgeColumn, 0}},
- {3276, {wxStyledTextCtrl, setEdgeColumn, 1}},
- {3277, {wxStyledTextCtrl, setEdgeMode, 1}},
- {3278, {wxStyledTextCtrl, getEdgeMode, 0}},
- {3279, {wxStyledTextCtrl, getEdgeColour, 0}},
- {3280, {wxStyledTextCtrl, setEdgeColour, 1}},
- {3281, {wxStyledTextCtrl, searchAnchor, 0}},
- {3282, {wxStyledTextCtrl, searchNext, 2}},
- {3283, {wxStyledTextCtrl, searchPrev, 2}},
- {3284, {wxStyledTextCtrl, linesOnScreen, 0}},
- {3285, {wxStyledTextCtrl, usePopUp, 1}},
- {3286, {wxStyledTextCtrl, selectionIsRectangle, 0}},
- {3287, {wxStyledTextCtrl, setZoom, 1}},
- {3288, {wxStyledTextCtrl, getZoom, 0}},
- {3289, {wxStyledTextCtrl, getModEventMask, 0}},
- {3290, {wxStyledTextCtrl, setSTCFocus, 1}},
- {3291, {wxStyledTextCtrl, getSTCFocus, 0}},
- {3292, {wxStyledTextCtrl, setStatus, 1}},
- {3293, {wxStyledTextCtrl, getStatus, 0}},
- {3294, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
- {3295, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
- {3296, {wxStyledTextCtrl, setSTCCursor, 1}},
- {3297, {wxStyledTextCtrl, getSTCCursor, 0}},
- {3298, {wxStyledTextCtrl, setControlCharSymbol, 1}},
- {3299, {wxStyledTextCtrl, getControlCharSymbol, 0}},
- {3300, {wxStyledTextCtrl, wordPartLeft, 0}},
- {3301, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
- {3302, {wxStyledTextCtrl, wordPartRight, 0}},
- {3303, {wxStyledTextCtrl, wordPartRightExtend, 0}},
- {3304, {wxStyledTextCtrl, setVisiblePolicy, 2}},
- {3305, {wxStyledTextCtrl, delLineLeft, 0}},
- {3306, {wxStyledTextCtrl, delLineRight, 0}},
- {3307, {wxStyledTextCtrl, getXOffset, 0}},
- {3308, {wxStyledTextCtrl, chooseCaretX, 0}},
- {3309, {wxStyledTextCtrl, setXCaretPolicy, 2}},
- {3310, {wxStyledTextCtrl, setYCaretPolicy, 2}},
- {3311, {wxStyledTextCtrl, getPrintWrapMode, 0}},
- {3312, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
- {3313, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
- {3314, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
- {3315, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
- {3316, {wxStyledTextCtrl, paraDownExtend, 0}},
- {3317, {wxStyledTextCtrl, paraUp, 0}},
- {3318, {wxStyledTextCtrl, paraUpExtend, 0}},
- {3319, {wxStyledTextCtrl, positionBefore, 1}},
- {3320, {wxStyledTextCtrl, positionAfter, 1}},
- {3321, {wxStyledTextCtrl, copyRange, 2}},
- {3322, {wxStyledTextCtrl, copyText, 2}},
- {3323, {wxStyledTextCtrl, setSelectionMode, 1}},
- {3324, {wxStyledTextCtrl, getSelectionMode, 0}},
- {3325, {wxStyledTextCtrl, lineDownRectExtend, 0}},
- {3326, {wxStyledTextCtrl, lineUpRectExtend, 0}},
- {3327, {wxStyledTextCtrl, charLeftRectExtend, 0}},
- {3328, {wxStyledTextCtrl, charRightRectExtend, 0}},
- {3329, {wxStyledTextCtrl, homeRectExtend, 0}},
- {3330, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
- {3331, {wxStyledTextCtrl, lineEndRectExtend, 0}},
- {3332, {wxStyledTextCtrl, pageUpRectExtend, 0}},
- {3333, {wxStyledTextCtrl, pageDownRectExtend, 0}},
- {3334, {wxStyledTextCtrl, stutteredPageUp, 0}},
- {3335, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
- {3336, {wxStyledTextCtrl, stutteredPageDown, 0}},
- {3337, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
- {3338, {wxStyledTextCtrl, wordLeftEnd, 0}},
- {3339, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
- {3340, {wxStyledTextCtrl, wordRightEnd, 0}},
- {3341, {wxStyledTextCtrl, wordRightEndExtend, 0}},
- {3342, {wxStyledTextCtrl, setWhitespaceChars, 1}},
- {3343, {wxStyledTextCtrl, setCharsDefault, 0}},
- {3344, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
- {3345, {wxStyledTextCtrl, allocate, 1}},
- {3346, {wxStyledTextCtrl, findColumn, 2}},
- {3347, {wxStyledTextCtrl, getCaretSticky, 0}},
- {3348, {wxStyledTextCtrl, setCaretSticky, 1}},
- {3349, {wxStyledTextCtrl, toggleCaretSticky, 0}},
- {3350, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
- {3351, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
- {3352, {wxStyledTextCtrl, selectionDuplicate, 0}},
- {3353, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
- {3354, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
- {3355, {wxStyledTextCtrl, startRecord, 0}},
- {3356, {wxStyledTextCtrl, stopRecord, 0}},
- {3357, {wxStyledTextCtrl, setLexer, 1}},
- {3358, {wxStyledTextCtrl, getLexer, 0}},
- {3359, {wxStyledTextCtrl, colourise, 2}},
- {3360, {wxStyledTextCtrl, setProperty, 2}},
- {3361, {wxStyledTextCtrl, setKeyWords, 2}},
- {3362, {wxStyledTextCtrl, setLexerLanguage, 1}},
- {3363, {wxStyledTextCtrl, getProperty, 1}},
- {3364, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
- {3365, {wxStyledTextCtrl, getCurrentLine, 0}},
- {3366, {wxStyledTextCtrl, styleSetSpec, 2}},
- {3367, {wxStyledTextCtrl, styleSetFont, 2}},
- {3368, {wxStyledTextCtrl, styleSetFontAttr, 7}},
- {3369, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
- {3370, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
- {3371, {wxStyledTextCtrl, cmdKeyExecute, 1}},
- {3372, {wxStyledTextCtrl, setMargins, 2}},
- {3373, {wxStyledTextCtrl, getSelection, 2}},
- {3374, {wxStyledTextCtrl, pointFromPosition, 1}},
- {3375, {wxStyledTextCtrl, scrollToLine, 1}},
- {3376, {wxStyledTextCtrl, scrollToColumn, 1}},
- {3377, {wxStyledTextCtrl, setVScrollBar, 1}},
- {3378, {wxStyledTextCtrl, setHScrollBar, 1}},
- {3379, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
- {3380, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
- {3381, {wxStyledTextCtrl, saveFile, 1}},
- {3382, {wxStyledTextCtrl, loadFile, 1}},
- {3383, {wxStyledTextCtrl, doDragOver, 3}},
- {3384, {wxStyledTextCtrl, doDropText, 3}},
- {3385, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
- {3386, {wxStyledTextCtrl, addTextRaw, 1}},
- {3387, {wxStyledTextCtrl, insertTextRaw, 2}},
- {3388, {wxStyledTextCtrl, getCurLineRaw, 1}},
- {3389, {wxStyledTextCtrl, getLineRaw, 1}},
- {3390, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
- {3391, {wxStyledTextCtrl, getTextRangeRaw, 2}},
- {3392, {wxStyledTextCtrl, setTextRaw, 1}},
- {3393, {wxStyledTextCtrl, getTextRaw, 0}},
- {3394, {wxStyledTextCtrl, appendTextRaw, 1}},
- {3395, {wxArtProvider, getBitmap, 2}},
- {3396, {wxArtProvider, getIcon, 2}},
- {3397, {wxTreeEvent, getKeyCode, 0}},
- {3398, {wxTreeEvent, getItem, 0}},
- {3399, {wxTreeEvent, getKeyEvent, 0}},
- {3400, {wxTreeEvent, getLabel, 0}},
- {3401, {wxTreeEvent, getOldItem, 0}},
- {3402, {wxTreeEvent, getPoint, 0}},
- {3403, {wxTreeEvent, isEditCancelled, 0}},
- {3404, {wxTreeEvent, setToolTip, 1}},
- {3405, {wxNotebookEvent, getOldSelection, 0}},
- {3406, {wxNotebookEvent, getSelection, 0}},
- {3407, {wxNotebookEvent, setOldSelection, 1}},
- {3408, {wxNotebookEvent, setSelection, 1}},
- {3409, {wxFileDataObject, new, 0}},
- {3410, {wxFileDataObject, addFile, 1}},
- {3411, {wxFileDataObject, getFilenames, 0}},
- {3412, {wxFileDataObject, 'Destroy', undefined}},
- {3413, {wxTextDataObject, new, 1}},
- {3414, {wxTextDataObject, getTextLength, 0}},
- {3415, {wxTextDataObject, getText, 0}},
- {3416, {wxTextDataObject, setText, 1}},
- {3417, {wxTextDataObject, 'Destroy', undefined}},
- {3418, {wxBitmapDataObject, new_1_1, 1}},
- {3419, {wxBitmapDataObject, new_1_0, 1}},
- {3420, {wxBitmapDataObject, getBitmap, 0}},
- {3421, {wxBitmapDataObject, setBitmap, 1}},
- {3422, {wxBitmapDataObject, 'Destroy', undefined}},
- {3424, {wxClipboard, new, 0}},
- {3425, {wxClipboard, destruct, 0}},
- {3426, {wxClipboard, addData, 1}},
- {3427, {wxClipboard, clear, 0}},
- {3428, {wxClipboard, close, 0}},
- {3429, {wxClipboard, flush, 0}},
- {3430, {wxClipboard, getData, 1}},
- {3431, {wxClipboard, isOpened, 0}},
- {3432, {wxClipboard, open, 0}},
- {3433, {wxClipboard, setData, 1}},
- {3435, {wxClipboard, usePrimarySelection, 1}},
- {3436, {wxClipboard, isSupported, 1}},
- {3437, {wxClipboard, get, 0}},
- {3438, {wxSpinEvent, getPosition, 0}},
- {3439, {wxSpinEvent, setPosition, 1}},
- {3440, {wxSplitterWindow, new_0, 0}},
- {3441, {wxSplitterWindow, new_2, 2}},
- {3442, {wxSplitterWindow, destruct, 0}},
- {3443, {wxSplitterWindow, create, 2}},
- {3444, {wxSplitterWindow, getMinimumPaneSize, 0}},
- {3445, {wxSplitterWindow, getSashGravity, 0}},
- {3446, {wxSplitterWindow, getSashPosition, 0}},
- {3447, {wxSplitterWindow, getSplitMode, 0}},
- {3448, {wxSplitterWindow, getWindow1, 0}},
- {3449, {wxSplitterWindow, getWindow2, 0}},
- {3450, {wxSplitterWindow, initialize, 1}},
- {3451, {wxSplitterWindow, isSplit, 0}},
- {3452, {wxSplitterWindow, replaceWindow, 2}},
- {3453, {wxSplitterWindow, setSashGravity, 1}},
- {3454, {wxSplitterWindow, setSashPosition, 2}},
- {3455, {wxSplitterWindow, setSashSize, 1}},
- {3456, {wxSplitterWindow, setMinimumPaneSize, 1}},
- {3457, {wxSplitterWindow, setSplitMode, 1}},
- {3458, {wxSplitterWindow, splitHorizontally, 3}},
- {3459, {wxSplitterWindow, splitVertically, 3}},
- {3460, {wxSplitterWindow, unsplit, 1}},
- {3461, {wxSplitterWindow, updateSize, 0}},
- {3462, {wxSplitterEvent, getSashPosition, 0}},
- {3463, {wxSplitterEvent, getX, 0}},
- {3464, {wxSplitterEvent, getY, 0}},
- {3465, {wxSplitterEvent, getWindowBeingRemoved, 0}},
- {3466, {wxSplitterEvent, setSashPosition, 1}},
- {3467, {wxHtmlWindow, new_0, 0}},
- {3468, {wxHtmlWindow, new_2, 2}},
- {3469, {wxHtmlWindow, appendToPage, 1}},
- {3470, {wxHtmlWindow, getOpenedAnchor, 0}},
- {3471, {wxHtmlWindow, getOpenedPage, 0}},
- {3472, {wxHtmlWindow, getOpenedPageTitle, 0}},
- {3473, {wxHtmlWindow, getRelatedFrame, 0}},
- {3474, {wxHtmlWindow, historyBack, 0}},
- {3475, {wxHtmlWindow, historyCanBack, 0}},
- {3476, {wxHtmlWindow, historyCanForward, 0}},
- {3477, {wxHtmlWindow, historyClear, 0}},
- {3478, {wxHtmlWindow, historyForward, 0}},
- {3479, {wxHtmlWindow, loadFile, 1}},
- {3480, {wxHtmlWindow, loadPage, 1}},
- {3481, {wxHtmlWindow, selectAll, 0}},
- {3482, {wxHtmlWindow, selectionToText, 0}},
- {3483, {wxHtmlWindow, selectLine, 1}},
- {3484, {wxHtmlWindow, selectWord, 1}},
- {3485, {wxHtmlWindow, setBorders, 1}},
- {3486, {wxHtmlWindow, setFonts, 3}},
- {3487, {wxHtmlWindow, setPage, 1}},
- {3488, {wxHtmlWindow, setRelatedFrame, 2}},
- {3489, {wxHtmlWindow, setRelatedStatusBar, 1}},
- {3490, {wxHtmlWindow, toText, 0}},
- {3491, {wxHtmlWindow, 'Destroy', undefined}},
- {3492, {wxHtmlLinkEvent, getLinkInfo, 0}},
- {3493, {wxSystemSettings, getColour, 1}},
- {3494, {wxSystemSettings, getFont, 1}},
- {3495, {wxSystemSettings, getMetric, 2}},
- {3496, {wxSystemSettings, getScreenType, 0}},
- {3497, {wxSystemOptions, getOption, 1}},
- {3498, {wxSystemOptions, getOptionInt, 1}},
- {3499, {wxSystemOptions, hasOption, 1}},
- {3500, {wxSystemOptions, isFalse, 1}},
- {3501, {wxSystemOptions, setOption_2_1, 2}},
- {3502, {wxSystemOptions, setOption_2_0, 2}},
- {3503, {wxAuiNotebookEvent, setSelection, 1}},
- {3504, {wxAuiNotebookEvent, getSelection, 0}},
- {3505, {wxAuiNotebookEvent, setOldSelection, 1}},
- {3506, {wxAuiNotebookEvent, getOldSelection, 0}},
- {3507, {wxAuiNotebookEvent, setDragSource, 1}},
- {3508, {wxAuiNotebookEvent, getDragSource, 0}},
- {3509, {wxAuiManagerEvent, setManager, 1}},
- {3510, {wxAuiManagerEvent, getManager, 0}},
- {3511, {wxAuiManagerEvent, setPane, 1}},
- {3512, {wxAuiManagerEvent, getPane, 0}},
- {3513, {wxAuiManagerEvent, setButton, 1}},
- {3514, {wxAuiManagerEvent, getButton, 0}},
- {3515, {wxAuiManagerEvent, setDC, 1}},
- {3516, {wxAuiManagerEvent, getDC, 0}},
- {3517, {wxAuiManagerEvent, veto, 1}},
- {3518, {wxAuiManagerEvent, getVeto, 0}},
- {3519, {wxAuiManagerEvent, setCanVeto, 1}},
- {3520, {wxAuiManagerEvent, canVeto, 0}},
- {3521, {wxLogNull, new, 0}},
- {3522, {wxLogNull, 'Destroy', undefined}},
- {3523, {wxTaskBarIcon, new, 0}},
- {3524, {wxTaskBarIcon, destruct, 0}},
- {3525, {wxTaskBarIcon, popupMenu, 1}},
- {3526, {wxTaskBarIcon, removeIcon, 0}},
- {3527, {wxTaskBarIcon, setIcon, 2}},
- {3528, {wxLocale, new_0, 0}},
- {3530, {wxLocale, new_2, 2}},
- {3531, {wxLocale, destruct, 0}},
- {3533, {wxLocale, init, 1}},
- {3534, {wxLocale, addCatalog_1, 1}},
- {3535, {wxLocale, addCatalog_3, 3}},
- {3536, {wxLocale, addCatalogLookupPathPrefix, 1}},
- {3537, {wxLocale, getCanonicalName, 0}},
- {3538, {wxLocale, getLanguage, 0}},
- {3539, {wxLocale, getLanguageName, 1}},
- {3540, {wxLocale, getLocale, 0}},
- {3541, {wxLocale, getName, 0}},
- {3542, {wxLocale, getString_2, 2}},
- {3543, {wxLocale, getString_4, 4}},
- {3544, {wxLocale, getHeaderValue, 2}},
- {3545, {wxLocale, getSysName, 0}},
- {3546, {wxLocale, getSystemEncoding, 0}},
- {3547, {wxLocale, getSystemEncodingName, 0}},
- {3548, {wxLocale, getSystemLanguage, 0}},
- {3549, {wxLocale, isLoaded, 1}},
- {3550, {wxLocale, isOk, 0}},
- {3551, {wxActivateEvent, getActive, 0}},
- {3553, {wxPopupWindow, new_2, 2}},
- {3554, {wxPopupWindow, new_0, 0}},
- {3556, {wxPopupWindow, destruct, 0}},
- {3557, {wxPopupWindow, create, 2}},
- {3558, {wxPopupWindow, position, 2}},
- {3559, {wxPopupTransientWindow, new_0, 0}},
- {3560, {wxPopupTransientWindow, new_2, 2}},
- {3561, {wxPopupTransientWindow, destruct, 0}},
- {3562, {wxPopupTransientWindow, popup, 1}},
- {3563, {wxPopupTransientWindow, dismiss, 0}},
+ {284, {wxWindow, setTransparent, 1}},
+ {285, {wxWindow, canSetTransparent, 0}},
+ {286, {wxWindow, isDoubleBuffered, 0}},
+ {287, {wxWindow, setDoubleBuffered, 1}},
+ {288, {wxTopLevelWindow, getIcon, 0}},
+ {289, {wxTopLevelWindow, getIcons, 0}},
+ {290, {wxTopLevelWindow, getTitle, 0}},
+ {291, {wxTopLevelWindow, isActive, 0}},
+ {292, {wxTopLevelWindow, iconize, 1}},
+ {293, {wxTopLevelWindow, isFullScreen, 0}},
+ {294, {wxTopLevelWindow, isIconized, 0}},
+ {295, {wxTopLevelWindow, isMaximized, 0}},
+ {296, {wxTopLevelWindow, maximize, 1}},
+ {297, {wxTopLevelWindow, requestUserAttention, 1}},
+ {298, {wxTopLevelWindow, setIcon, 1}},
+ {299, {wxTopLevelWindow, setIcons, 1}},
+ {300, {wxTopLevelWindow, centerOnScreen, 1}},
+ {301, {wxTopLevelWindow, centreOnScreen, 1}},
+ {303, {wxTopLevelWindow, setShape, 1}},
+ {304, {wxTopLevelWindow, setTitle, 1}},
+ {305, {wxTopLevelWindow, showFullScreen, 2}},
+ {307, {wxFrame, new_4, 4}},
+ {308, {wxFrame, new_0, 0}},
+ {310, {wxFrame, destruct, 0}},
+ {311, {wxFrame, create, 4}},
+ {312, {wxFrame, createStatusBar, 1}},
+ {313, {wxFrame, createToolBar, 1}},
+ {314, {wxFrame, getClientAreaOrigin, 0}},
+ {315, {wxFrame, getMenuBar, 0}},
+ {316, {wxFrame, getStatusBar, 0}},
+ {317, {wxFrame, getStatusBarPane, 0}},
+ {318, {wxFrame, getToolBar, 0}},
+ {319, {wxFrame, processCommand, 1}},
+ {320, {wxFrame, sendSizeEvent, 0}},
+ {321, {wxFrame, setMenuBar, 1}},
+ {322, {wxFrame, setStatusBar, 1}},
+ {323, {wxFrame, setStatusBarPane, 1}},
+ {324, {wxFrame, setStatusText, 2}},
+ {325, {wxFrame, setStatusWidths, 2}},
+ {326, {wxFrame, setToolBar, 1}},
+ {327, {wxMiniFrame, new_0, 0}},
+ {328, {wxMiniFrame, new_4, 4}},
+ {329, {wxMiniFrame, create, 4}},
+ {330, {wxMiniFrame, 'Destroy', undefined}},
+ {331, {wxSplashScreen, new_0, 0}},
+ {332, {wxSplashScreen, new_6, 6}},
+ {333, {wxSplashScreen, destruct, 0}},
+ {334, {wxSplashScreen, getSplashStyle, 0}},
+ {335, {wxSplashScreen, getTimeout, 0}},
+ {336, {wxPanel, new_0, 0}},
+ {337, {wxPanel, new_6, 6}},
+ {338, {wxPanel, new_2, 2}},
+ {339, {wxPanel, destruct, 0}},
+ {340, {wxPanel, initDialog, 0}},
+ {341, {wxPanel, setFocusIgnoringChildren, 0}},
+ {342, {wxScrolledWindow, new_0, 0}},
+ {343, {wxScrolledWindow, new_2, 2}},
+ {344, {wxScrolledWindow, destruct, 0}},
+ {345, {wxScrolledWindow, calcScrolledPosition_4, 4}},
+ {346, {wxScrolledWindow, calcScrolledPosition_1, 1}},
+ {347, {wxScrolledWindow, calcUnscrolledPosition_4, 4}},
+ {348, {wxScrolledWindow, calcUnscrolledPosition_1, 1}},
+ {349, {wxScrolledWindow, enableScrolling, 2}},
+ {350, {wxScrolledWindow, getScrollPixelsPerUnit, 2}},
+ {351, {wxScrolledWindow, getViewStart, 2}},
+ {352, {wxScrolledWindow, doPrepareDC, 1}},
+ {353, {wxScrolledWindow, prepareDC, 1}},
+ {354, {wxScrolledWindow, scroll, 2}},
+ {355, {wxScrolledWindow, setScrollbars, 5}},
+ {356, {wxScrolledWindow, setScrollRate, 2}},
+ {357, {wxScrolledWindow, setTargetWindow, 1}},
+ {358, {wxSashWindow, new_0, 0}},
+ {359, {wxSashWindow, new_2, 2}},
+ {360, {wxSashWindow, destruct, 0}},
+ {361, {wxSashWindow, getSashVisible, 1}},
+ {362, {wxSashWindow, getMaximumSizeX, 0}},
+ {363, {wxSashWindow, getMaximumSizeY, 0}},
+ {364, {wxSashWindow, getMinimumSizeX, 0}},
+ {365, {wxSashWindow, getMinimumSizeY, 0}},
+ {366, {wxSashWindow, setMaximumSizeX, 1}},
+ {367, {wxSashWindow, setMaximumSizeY, 1}},
+ {368, {wxSashWindow, setMinimumSizeX, 1}},
+ {369, {wxSashWindow, setMinimumSizeY, 1}},
+ {370, {wxSashWindow, setSashVisible, 2}},
+ {371, {wxSashLayoutWindow, new_0, 0}},
+ {372, {wxSashLayoutWindow, new_2, 2}},
+ {373, {wxSashLayoutWindow, create, 2}},
+ {374, {wxSashLayoutWindow, getAlignment, 0}},
+ {375, {wxSashLayoutWindow, getOrientation, 0}},
+ {376, {wxSashLayoutWindow, setAlignment, 1}},
+ {377, {wxSashLayoutWindow, setDefaultSize, 1}},
+ {378, {wxSashLayoutWindow, setOrientation, 1}},
+ {379, {wxSashLayoutWindow, 'Destroy', undefined}},
+ {380, {wxGrid, new_0, 0}},
+ {381, {wxGrid, new_3, 3}},
+ {382, {wxGrid, new_4, 4}},
+ {383, {wxGrid, destruct, 0}},
+ {384, {wxGrid, appendCols, 1}},
+ {385, {wxGrid, appendRows, 1}},
+ {386, {wxGrid, autoSize, 0}},
+ {387, {wxGrid, autoSizeColumn, 2}},
+ {388, {wxGrid, autoSizeColumns, 1}},
+ {389, {wxGrid, autoSizeRow, 2}},
+ {390, {wxGrid, autoSizeRows, 1}},
+ {391, {wxGrid, beginBatch, 0}},
+ {392, {wxGrid, blockToDeviceRect, 2}},
+ {393, {wxGrid, canDragColSize, 0}},
+ {394, {wxGrid, canDragRowSize, 0}},
+ {395, {wxGrid, canDragGridSize, 0}},
+ {396, {wxGrid, canEnableCellControl, 0}},
+ {397, {wxGrid, cellToRect_2, 2}},
+ {398, {wxGrid, cellToRect_1, 1}},
+ {399, {wxGrid, clearGrid, 0}},
+ {400, {wxGrid, clearSelection, 0}},
+ {401, {wxGrid, createGrid, 3}},
+ {402, {wxGrid, deleteCols, 1}},
+ {403, {wxGrid, deleteRows, 1}},
+ {404, {wxGrid, disableCellEditControl, 0}},
+ {405, {wxGrid, disableDragColSize, 0}},
+ {406, {wxGrid, disableDragGridSize, 0}},
+ {407, {wxGrid, disableDragRowSize, 0}},
+ {408, {wxGrid, enableCellEditControl, 1}},
+ {409, {wxGrid, enableDragColSize, 1}},
+ {410, {wxGrid, enableDragGridSize, 1}},
+ {411, {wxGrid, enableDragRowSize, 1}},
+ {412, {wxGrid, enableEditing, 1}},
+ {413, {wxGrid, enableGridLines, 1}},
+ {414, {wxGrid, endBatch, 0}},
+ {415, {wxGrid, fit, 0}},
+ {416, {wxGrid, forceRefresh, 0}},
+ {417, {wxGrid, getBatchCount, 0}},
+ {418, {wxGrid, getCellAlignment, 4}},
+ {419, {wxGrid, getCellBackgroundColour, 2}},
+ {420, {wxGrid, getCellEditor, 2}},
+ {421, {wxGrid, getCellFont, 2}},
+ {422, {wxGrid, getCellRenderer, 2}},
+ {423, {wxGrid, getCellTextColour, 2}},
+ {424, {wxGrid, getCellValue_2, 2}},
+ {425, {wxGrid, getCellValue_1, 1}},
+ {426, {wxGrid, getColLabelAlignment, 2}},
+ {427, {wxGrid, getColLabelSize, 0}},
+ {428, {wxGrid, getColLabelValue, 1}},
+ {429, {wxGrid, getColMinimalAcceptableWidth, 0}},
+ {430, {wxGrid, getDefaultCellAlignment, 2}},
+ {431, {wxGrid, getDefaultCellBackgroundColour, 0}},
+ {432, {wxGrid, getDefaultCellFont, 0}},
+ {433, {wxGrid, getDefaultCellTextColour, 0}},
+ {434, {wxGrid, getDefaultColLabelSize, 0}},
+ {435, {wxGrid, getDefaultColSize, 0}},
+ {436, {wxGrid, getDefaultEditor, 0}},
+ {437, {wxGrid, getDefaultEditorForCell_2, 2}},
+ {438, {wxGrid, getDefaultEditorForCell_1, 1}},
+ {439, {wxGrid, getDefaultEditorForType, 1}},
+ {440, {wxGrid, getDefaultRenderer, 0}},
+ {441, {wxGrid, getDefaultRendererForCell, 2}},
+ {442, {wxGrid, getDefaultRendererForType, 1}},
+ {443, {wxGrid, getDefaultRowLabelSize, 0}},
+ {444, {wxGrid, getDefaultRowSize, 0}},
+ {445, {wxGrid, getGridCursorCol, 0}},
+ {446, {wxGrid, getGridCursorRow, 0}},
+ {447, {wxGrid, getGridLineColour, 0}},
+ {448, {wxGrid, gridLinesEnabled, 0}},
+ {449, {wxGrid, getLabelBackgroundColour, 0}},
+ {450, {wxGrid, getLabelFont, 0}},
+ {451, {wxGrid, getLabelTextColour, 0}},
+ {452, {wxGrid, getNumberCols, 0}},
+ {453, {wxGrid, getNumberRows, 0}},
+ {454, {wxGrid, getOrCreateCellAttr, 2}},
+ {455, {wxGrid, getRowMinimalAcceptableHeight, 0}},
+ {456, {wxGrid, getRowLabelAlignment, 2}},
+ {457, {wxGrid, getRowLabelSize, 0}},
+ {458, {wxGrid, getRowLabelValue, 1}},
+ {459, {wxGrid, getRowSize, 1}},
+ {460, {wxGrid, getScrollLineX, 0}},
+ {461, {wxGrid, getScrollLineY, 0}},
+ {462, {wxGrid, getSelectedCells, 0}},
+ {463, {wxGrid, getSelectedCols, 0}},
+ {464, {wxGrid, getSelectedRows, 0}},
+ {465, {wxGrid, getSelectionBackground, 0}},
+ {466, {wxGrid, getSelectionBlockTopLeft, 0}},
+ {467, {wxGrid, getSelectionBlockBottomRight, 0}},
+ {468, {wxGrid, getSelectionForeground, 0}},
+ {469, {wxGrid, getViewWidth, 0}},
+ {470, {wxGrid, getGridWindow, 0}},
+ {471, {wxGrid, getGridRowLabelWindow, 0}},
+ {472, {wxGrid, getGridColLabelWindow, 0}},
+ {473, {wxGrid, getGridCornerLabelWindow, 0}},
+ {474, {wxGrid, hideCellEditControl, 0}},
+ {475, {wxGrid, insertCols, 1}},
+ {476, {wxGrid, insertRows, 1}},
+ {477, {wxGrid, isCellEditControlEnabled, 0}},
+ {478, {wxGrid, isCurrentCellReadOnly, 0}},
+ {479, {wxGrid, isEditable, 0}},
+ {480, {wxGrid, isInSelection_2, 2}},
+ {481, {wxGrid, isInSelection_1, 1}},
+ {482, {wxGrid, isReadOnly, 2}},
+ {483, {wxGrid, isSelection, 0}},
+ {484, {wxGrid, isVisible_3, 3}},
+ {485, {wxGrid, isVisible_2, 2}},
+ {486, {wxGrid, makeCellVisible_2, 2}},
+ {487, {wxGrid, makeCellVisible_1, 1}},
+ {488, {wxGrid, moveCursorDown, 1}},
+ {489, {wxGrid, moveCursorLeft, 1}},
+ {490, {wxGrid, moveCursorRight, 1}},
+ {491, {wxGrid, moveCursorUp, 1}},
+ {492, {wxGrid, moveCursorDownBlock, 1}},
+ {493, {wxGrid, moveCursorLeftBlock, 1}},
+ {494, {wxGrid, moveCursorRightBlock, 1}},
+ {495, {wxGrid, moveCursorUpBlock, 1}},
+ {496, {wxGrid, movePageDown, 0}},
+ {497, {wxGrid, movePageUp, 0}},
+ {498, {wxGrid, registerDataType, 3}},
+ {499, {wxGrid, saveEditControlValue, 0}},
+ {500, {wxGrid, selectAll, 0}},
+ {501, {wxGrid, selectBlock_5, 5}},
+ {502, {wxGrid, selectBlock_3, 3}},
+ {503, {wxGrid, selectCol, 2}},
+ {504, {wxGrid, selectRow, 2}},
+ {505, {wxGrid, setCellAlignment_4, 4}},
+ {506, {wxGrid, setCellAlignment_3, 3}},
+ {507, {wxGrid, setCellAlignment_1, 1}},
+ {508, {wxGrid, setCellBackgroundColour_3_0, 3}},
+ {509, {wxGrid, setCellBackgroundColour_1, 1}},
+ {510, {wxGrid, setCellBackgroundColour_3_1, 3}},
+ {511, {wxGrid, setCellEditor, 3}},
+ {512, {wxGrid, setCellFont, 3}},
+ {513, {wxGrid, setCellRenderer, 3}},
+ {514, {wxGrid, setCellTextColour_3_0, 3}},
+ {515, {wxGrid, setCellTextColour_3_1, 3}},
+ {516, {wxGrid, setCellTextColour_1, 1}},
+ {517, {wxGrid, setCellValue_3_0, 3}},
+ {518, {wxGrid, setCellValue_2, 2}},
+ {519, {wxGrid, setCellValue_3_1, 3}},
+ {520, {wxGrid, setColAttr, 2}},
+ {521, {wxGrid, setColFormatBool, 1}},
+ {522, {wxGrid, setColFormatNumber, 1}},
+ {523, {wxGrid, setColFormatFloat, 2}},
+ {524, {wxGrid, setColFormatCustom, 2}},
+ {525, {wxGrid, setColLabelAlignment, 2}},
+ {526, {wxGrid, setColLabelSize, 1}},
+ {527, {wxGrid, setColLabelValue, 2}},
+ {528, {wxGrid, setColMinimalWidth, 2}},
+ {529, {wxGrid, setColMinimalAcceptableWidth, 1}},
+ {530, {wxGrid, setColSize, 2}},
+ {531, {wxGrid, setDefaultCellAlignment, 2}},
+ {532, {wxGrid, setDefaultCellBackgroundColour, 1}},
+ {533, {wxGrid, setDefaultCellFont, 1}},
+ {534, {wxGrid, setDefaultCellTextColour, 1}},
+ {535, {wxGrid, setDefaultEditor, 1}},
+ {536, {wxGrid, setDefaultRenderer, 1}},
+ {537, {wxGrid, setDefaultColSize, 2}},
+ {538, {wxGrid, setDefaultRowSize, 2}},
+ {539, {wxGrid, setGridCursor, 2}},
+ {540, {wxGrid, setGridLineColour, 1}},
+ {541, {wxGrid, setLabelBackgroundColour, 1}},
+ {542, {wxGrid, setLabelFont, 1}},
+ {543, {wxGrid, setLabelTextColour, 1}},
+ {544, {wxGrid, setMargins, 2}},
+ {545, {wxGrid, setReadOnly, 3}},
+ {546, {wxGrid, setRowAttr, 2}},
+ {547, {wxGrid, setRowLabelAlignment, 2}},
+ {548, {wxGrid, setRowLabelSize, 1}},
+ {549, {wxGrid, setRowLabelValue, 2}},
+ {550, {wxGrid, setRowMinimalHeight, 2}},
+ {551, {wxGrid, setRowMinimalAcceptableHeight, 1}},
+ {552, {wxGrid, setRowSize, 2}},
+ {553, {wxGrid, setScrollLineX, 1}},
+ {554, {wxGrid, setScrollLineY, 1}},
+ {555, {wxGrid, setSelectionBackground, 1}},
+ {556, {wxGrid, setSelectionForeground, 1}},
+ {557, {wxGrid, setSelectionMode, 1}},
+ {558, {wxGrid, showCellEditControl, 0}},
+ {559, {wxGrid, xToCol, 2}},
+ {560, {wxGrid, xToEdgeOfCol, 1}},
+ {561, {wxGrid, yToEdgeOfRow, 1}},
+ {562, {wxGrid, yToRow, 1}},
+ {563, {wxGridCellRenderer, draw, 7}},
+ {564, {wxGridCellRenderer, getBestSize, 5}},
+ {565, {wxGridCellEditor, create, 3}},
+ {566, {wxGridCellEditor, isCreated, 0}},
+ {567, {wxGridCellEditor, setSize, 1}},
+ {568, {wxGridCellEditor, show, 2}},
+ {569, {wxGridCellEditor, paintBackground, 2}},
+ {570, {wxGridCellEditor, beginEdit, 3}},
+ {571, {wxGridCellEditor, endEdit, 3}},
+ {572, {wxGridCellEditor, reset, 0}},
+ {573, {wxGridCellEditor, startingKey, 1}},
+ {574, {wxGridCellEditor, startingClick, 0}},
+ {575, {wxGridCellEditor, handleReturn, 1}},
+ {576, {wxGridCellBoolRenderer, new, 0}},
+ {577, {wxGridCellBoolRenderer, 'Destroy', undefined}},
+ {578, {wxGridCellBoolEditor, new, 0}},
+ {579, {wxGridCellBoolEditor, isTrueValue, 1}},
+ {580, {wxGridCellBoolEditor, useStringValues, 1}},
+ {581, {wxGridCellBoolEditor, 'Destroy', undefined}},
+ {582, {wxGridCellFloatRenderer, new, 1}},
+ {583, {wxGridCellFloatRenderer, getPrecision, 0}},
+ {584, {wxGridCellFloatRenderer, getWidth, 0}},
+ {585, {wxGridCellFloatRenderer, setParameters, 1}},
+ {586, {wxGridCellFloatRenderer, setPrecision, 1}},
+ {587, {wxGridCellFloatRenderer, setWidth, 1}},
+ {588, {wxGridCellFloatRenderer, 'Destroy', undefined}},
+ {589, {wxGridCellFloatEditor, new, 1}},
+ {590, {wxGridCellFloatEditor, setParameters, 1}},
+ {591, {wxGridCellFloatEditor, 'Destroy', undefined}},
+ {592, {wxGridCellStringRenderer, new, 0}},
+ {593, {wxGridCellStringRenderer, 'Destroy', undefined}},
+ {594, {wxGridCellTextEditor, new, 0}},
+ {595, {wxGridCellTextEditor, setParameters, 1}},
+ {596, {wxGridCellTextEditor, 'Destroy', undefined}},
+ {598, {wxGridCellChoiceEditor, new, 2}},
+ {599, {wxGridCellChoiceEditor, setParameters, 1}},
+ {600, {wxGridCellChoiceEditor, 'Destroy', undefined}},
+ {601, {wxGridCellNumberRenderer, new, 0}},
+ {602, {wxGridCellNumberRenderer, 'Destroy', undefined}},
+ {603, {wxGridCellNumberEditor, new, 1}},
+ {604, {wxGridCellNumberEditor, getValue, 0}},
+ {605, {wxGridCellNumberEditor, setParameters, 1}},
+ {606, {wxGridCellNumberEditor, 'Destroy', undefined}},
+ {607, {wxGridCellAttr, setTextColour, 1}},
+ {608, {wxGridCellAttr, setBackgroundColour, 1}},
+ {609, {wxGridCellAttr, setFont, 1}},
+ {610, {wxGridCellAttr, setAlignment, 2}},
+ {611, {wxGridCellAttr, setReadOnly, 1}},
+ {612, {wxGridCellAttr, setRenderer, 1}},
+ {613, {wxGridCellAttr, setEditor, 1}},
+ {614, {wxGridCellAttr, hasTextColour, 0}},
+ {615, {wxGridCellAttr, hasBackgroundColour, 0}},
+ {616, {wxGridCellAttr, hasFont, 0}},
+ {617, {wxGridCellAttr, hasAlignment, 0}},
+ {618, {wxGridCellAttr, hasRenderer, 0}},
+ {619, {wxGridCellAttr, hasEditor, 0}},
+ {620, {wxGridCellAttr, getTextColour, 0}},
+ {621, {wxGridCellAttr, getBackgroundColour, 0}},
+ {622, {wxGridCellAttr, getFont, 0}},
+ {623, {wxGridCellAttr, getAlignment, 2}},
+ {624, {wxGridCellAttr, getRenderer, 3}},
+ {625, {wxGridCellAttr, getEditor, 3}},
+ {626, {wxGridCellAttr, isReadOnly, 0}},
+ {627, {wxGridCellAttr, setDefAttr, 1}},
+ {628, {wxDC, blit, 5}},
+ {629, {wxDC, calcBoundingBox, 2}},
+ {630, {wxDC, clear, 0}},
+ {631, {wxDC, computeScaleAndOrigin, 0}},
+ {632, {wxDC, crossHair, 1}},
+ {633, {wxDC, destroyClippingRegion, 0}},
+ {634, {wxDC, deviceToLogicalX, 1}},
+ {635, {wxDC, deviceToLogicalXRel, 1}},
+ {636, {wxDC, deviceToLogicalY, 1}},
+ {637, {wxDC, deviceToLogicalYRel, 1}},
+ {638, {wxDC, drawArc, 3}},
+ {639, {wxDC, drawBitmap, 3}},
+ {640, {wxDC, drawCheckMark, 1}},
+ {641, {wxDC, drawCircle, 2}},
+ {643, {wxDC, drawEllipse_2, 2}},
+ {644, {wxDC, drawEllipse_1, 1}},
+ {645, {wxDC, drawEllipticArc, 4}},
+ {646, {wxDC, drawIcon, 2}},
+ {647, {wxDC, drawLabel, 3}},
+ {648, {wxDC, drawLine, 2}},
+ {649, {wxDC, drawLines, 3}},
+ {651, {wxDC, drawPolygon, 3}},
+ {653, {wxDC, drawPoint, 1}},
+ {655, {wxDC, drawRectangle_2, 2}},
+ {656, {wxDC, drawRectangle_1, 1}},
+ {657, {wxDC, drawRotatedText, 3}},
+ {659, {wxDC, drawRoundedRectangle_3, 3}},
+ {660, {wxDC, drawRoundedRectangle_2, 2}},
+ {661, {wxDC, drawText, 2}},
+ {662, {wxDC, endDoc, 0}},
+ {663, {wxDC, endPage, 0}},
+ {664, {wxDC, floodFill, 3}},
+ {665, {wxDC, getBackground, 0}},
+ {666, {wxDC, getBackgroundMode, 0}},
+ {667, {wxDC, getBrush, 0}},
+ {668, {wxDC, getCharHeight, 0}},
+ {669, {wxDC, getCharWidth, 0}},
+ {670, {wxDC, getClippingBox, 4}},
+ {672, {wxDC, getFont, 0}},
+ {673, {wxDC, getLayoutDirection, 0}},
+ {674, {wxDC, getLogicalFunction, 0}},
+ {675, {wxDC, getMapMode, 0}},
+ {676, {wxDC, getMultiLineTextExtent_4, 4}},
+ {677, {wxDC, getMultiLineTextExtent_1, 1}},
+ {678, {wxDC, getPartialTextExtents, 2}},
+ {679, {wxDC, getPen, 0}},
+ {680, {wxDC, getPixel, 2}},
+ {681, {wxDC, getPPI, 0}},
+ {683, {wxDC, getSize, 0}},
+ {685, {wxDC, getSizeMM, 0}},
+ {686, {wxDC, getTextBackground, 0}},
+ {687, {wxDC, getTextExtent_4, 4}},
+ {688, {wxDC, getTextExtent_1, 1}},
+ {690, {wxDC, getTextForeground, 0}},
+ {691, {wxDC, getUserScale, 2}},
+ {692, {wxDC, gradientFillConcentric_3, 3}},
+ {693, {wxDC, gradientFillConcentric_4, 4}},
+ {694, {wxDC, gradientFillLinear, 4}},
+ {695, {wxDC, logicalToDeviceX, 1}},
+ {696, {wxDC, logicalToDeviceXRel, 1}},
+ {697, {wxDC, logicalToDeviceY, 1}},
+ {698, {wxDC, logicalToDeviceYRel, 1}},
+ {699, {wxDC, maxX, 0}},
+ {700, {wxDC, maxY, 0}},
+ {701, {wxDC, minX, 0}},
+ {702, {wxDC, minY, 0}},
+ {703, {wxDC, isOk, 0}},
+ {704, {wxDC, resetBoundingBox, 0}},
+ {705, {wxDC, setAxisOrientation, 2}},
+ {706, {wxDC, setBackground, 1}},
+ {707, {wxDC, setBackgroundMode, 1}},
+ {708, {wxDC, setBrush, 1}},
+ {710, {wxDC, setClippingRegion_2, 2}},
+ {711, {wxDC, setClippingRegion_1_1, 1}},
+ {712, {wxDC, setClippingRegion_1_0, 1}},
+ {713, {wxDC, setDeviceOrigin, 2}},
+ {714, {wxDC, setFont, 1}},
+ {715, {wxDC, setLayoutDirection, 1}},
+ {716, {wxDC, setLogicalFunction, 1}},
+ {717, {wxDC, setMapMode, 1}},
+ {718, {wxDC, setPalette, 1}},
+ {719, {wxDC, setPen, 1}},
+ {720, {wxDC, setTextBackground, 1}},
+ {721, {wxDC, setTextForeground, 1}},
+ {722, {wxDC, setUserScale, 2}},
+ {723, {wxDC, startDoc, 1}},
+ {724, {wxDC, startPage, 0}},
+ {725, {wxMirrorDC, new, 2}},
+ {726, {wxMirrorDC, 'Destroy', undefined}},
+ {727, {wxScreenDC, new, 0}},
+ {728, {wxScreenDC, destruct, 0}},
+ {729, {wxPostScriptDC, new_0, 0}},
+ {730, {wxPostScriptDC, new_1, 1}},
+ {731, {wxPostScriptDC, destruct, 0}},
+ {732, {wxPostScriptDC, setResolution, 1}},
+ {733, {wxPostScriptDC, getResolution, 0}},
+ {734, {wxWindowDC, new_0, 0}},
+ {735, {wxWindowDC, new_1, 1}},
+ {736, {wxWindowDC, destruct, 0}},
+ {737, {wxClientDC, new_0, 0}},
+ {738, {wxClientDC, new_1, 1}},
+ {739, {wxClientDC, 'Destroy', undefined}},
+ {740, {wxPaintDC, new_0, 0}},
+ {741, {wxPaintDC, new_1, 1}},
+ {742, {wxPaintDC, 'Destroy', undefined}},
+ {744, {wxMemoryDC, new_1_0, 1}},
+ {745, {wxMemoryDC, new_1_1, 1}},
+ {746, {wxMemoryDC, new_0, 0}},
+ {748, {wxMemoryDC, destruct, 0}},
+ {749, {wxMemoryDC, selectObject, 1}},
+ {750, {wxMemoryDC, selectObjectAsSource, 1}},
+ {751, {wxBufferedDC, new_0, 0}},
+ {752, {wxBufferedDC, new_2, 2}},
+ {753, {wxBufferedDC, new_3, 3}},
+ {754, {wxBufferedDC, destruct, 0}},
+ {755, {wxBufferedDC, init_2, 2}},
+ {756, {wxBufferedDC, init_3, 3}},
+ {757, {wxBufferedPaintDC, new_3, 3}},
+ {758, {wxBufferedPaintDC, new_2, 2}},
+ {759, {wxBufferedPaintDC, destruct, 0}},
+ {760, {wxGraphicsObject, destruct, 0}},
+ {761, {wxGraphicsObject, getRenderer, 0}},
+ {762, {wxGraphicsObject, isNull, 0}},
+ {763, {wxGraphicsContext, destruct, 0}},
+ {764, {wxGraphicsContext, create_1_1, 1}},
+ {765, {wxGraphicsContext, create_1_0, 1}},
+ {766, {wxGraphicsContext, create_0, 0}},
+ {767, {wxGraphicsContext, createPen, 1}},
+ {768, {wxGraphicsContext, createBrush, 1}},
+ {769, {wxGraphicsContext, createRadialGradientBrush, 7}},
+ {770, {wxGraphicsContext, createLinearGradientBrush, 6}},
+ {771, {wxGraphicsContext, createFont, 2}},
+ {772, {wxGraphicsContext, createMatrix, 1}},
+ {773, {wxGraphicsContext, createPath, 0}},
+ {774, {wxGraphicsContext, clip_1, 1}},
+ {775, {wxGraphicsContext, clip_4, 4}},
+ {776, {wxGraphicsContext, resetClip, 0}},
+ {777, {wxGraphicsContext, drawBitmap, 5}},
+ {778, {wxGraphicsContext, drawEllipse, 4}},
+ {779, {wxGraphicsContext, drawIcon, 5}},
+ {780, {wxGraphicsContext, drawLines, 3}},
+ {781, {wxGraphicsContext, drawPath, 2}},
+ {782, {wxGraphicsContext, drawRectangle, 4}},
+ {783, {wxGraphicsContext, drawRoundedRectangle, 5}},
+ {784, {wxGraphicsContext, drawText_3, 3}},
+ {785, {wxGraphicsContext, drawText_4_0, 4}},
+ {786, {wxGraphicsContext, drawText_4_1, 4}},
+ {787, {wxGraphicsContext, drawText_5, 5}},
+ {788, {wxGraphicsContext, fillPath, 2}},
+ {789, {wxGraphicsContext, strokePath, 1}},
+ {790, {wxGraphicsContext, getPartialTextExtents, 2}},
+ {791, {wxGraphicsContext, getTextExtent, 5}},
+ {792, {wxGraphicsContext, rotate, 1}},
+ {793, {wxGraphicsContext, scale, 2}},
+ {794, {wxGraphicsContext, translate, 2}},
+ {795, {wxGraphicsContext, getTransform, 0}},
+ {796, {wxGraphicsContext, setTransform, 1}},
+ {797, {wxGraphicsContext, concatTransform, 1}},
+ {798, {wxGraphicsContext, setBrush_1_1, 1}},
+ {799, {wxGraphicsContext, setBrush_1_0, 1}},
+ {800, {wxGraphicsContext, setFont_1, 1}},
+ {801, {wxGraphicsContext, setFont_2, 2}},
+ {802, {wxGraphicsContext, setPen_1_0, 1}},
+ {803, {wxGraphicsContext, setPen_1_1, 1}},
+ {804, {wxGraphicsContext, strokeLine, 4}},
+ {805, {wxGraphicsContext, strokeLines, 2}},
+ {807, {wxGraphicsMatrix, concat, 1}},
+ {809, {wxGraphicsMatrix, get, 1}},
+ {810, {wxGraphicsMatrix, invert, 0}},
+ {811, {wxGraphicsMatrix, isEqual, 1}},
+ {813, {wxGraphicsMatrix, isIdentity, 0}},
+ {814, {wxGraphicsMatrix, rotate, 1}},
+ {815, {wxGraphicsMatrix, scale, 2}},
+ {816, {wxGraphicsMatrix, translate, 2}},
+ {817, {wxGraphicsMatrix, set, 1}},
+ {818, {wxGraphicsMatrix, transformPoint, 2}},
+ {819, {wxGraphicsMatrix, transformDistance, 2}},
+ {820, {wxGraphicsPath, moveToPoint_2, 2}},
+ {821, {wxGraphicsPath, moveToPoint_1, 1}},
+ {822, {wxGraphicsPath, addArc_6, 6}},
+ {823, {wxGraphicsPath, addArc_5, 5}},
+ {824, {wxGraphicsPath, addArcToPoint, 5}},
+ {825, {wxGraphicsPath, addCircle, 3}},
+ {826, {wxGraphicsPath, addCurveToPoint_6, 6}},
+ {827, {wxGraphicsPath, addCurveToPoint_3, 3}},
+ {828, {wxGraphicsPath, addEllipse, 4}},
+ {829, {wxGraphicsPath, addLineToPoint_2, 2}},
+ {830, {wxGraphicsPath, addLineToPoint_1, 1}},
+ {831, {wxGraphicsPath, addPath, 1}},
+ {832, {wxGraphicsPath, addQuadCurveToPoint, 4}},
+ {833, {wxGraphicsPath, addRectangle, 4}},
+ {834, {wxGraphicsPath, addRoundedRectangle, 5}},
+ {835, {wxGraphicsPath, closeSubpath, 0}},
+ {836, {wxGraphicsPath, contains_3, 3}},
+ {837, {wxGraphicsPath, contains_2, 2}},
+ {839, {wxGraphicsPath, getBox, 0}},
+ {841, {wxGraphicsPath, getCurrentPoint, 0}},
+ {842, {wxGraphicsPath, transform, 1}},
+ {843, {wxGraphicsRenderer, getDefaultRenderer, 0}},
+ {844, {wxGraphicsRenderer, createContext_1_1, 1}},
+ {845, {wxGraphicsRenderer, createContext_1_0, 1}},
+ {846, {wxGraphicsRenderer, createPen, 1}},
+ {847, {wxGraphicsRenderer, createBrush, 1}},
+ {848, {wxGraphicsRenderer, createLinearGradientBrush, 6}},
+ {849, {wxGraphicsRenderer, createRadialGradientBrush, 7}},
+ {850, {wxGraphicsRenderer, createFont, 2}},
+ {851, {wxGraphicsRenderer, createMatrix, 1}},
+ {852, {wxGraphicsRenderer, createPath, 0}},
+ {854, {wxMenuBar, new_1, 1}},
+ {856, {wxMenuBar, new_0, 0}},
+ {858, {wxMenuBar, destruct, 0}},
+ {859, {wxMenuBar, append, 2}},
+ {860, {wxMenuBar, check, 2}},
+ {861, {wxMenuBar, enable_2, 2}},
+ {862, {wxMenuBar, enable_1, 1}},
+ {863, {wxMenuBar, enableTop, 2}},
+ {864, {wxMenuBar, findMenu, 1}},
+ {865, {wxMenuBar, findMenuItem, 2}},
+ {866, {wxMenuBar, findItem, 2}},
+ {867, {wxMenuBar, getHelpString, 1}},
+ {868, {wxMenuBar, getLabel_1, 1}},
+ {869, {wxMenuBar, getLabel_0, 0}},
+ {870, {wxMenuBar, getLabelTop, 1}},
+ {871, {wxMenuBar, getMenu, 1}},
+ {872, {wxMenuBar, getMenuCount, 0}},
+ {873, {wxMenuBar, insert, 3}},
+ {874, {wxMenuBar, isChecked, 1}},
+ {875, {wxMenuBar, isEnabled_1, 1}},
+ {876, {wxMenuBar, isEnabled_0, 0}},
+ {877, {wxMenuBar, remove, 1}},
+ {878, {wxMenuBar, replace, 3}},
+ {879, {wxMenuBar, setHelpString, 2}},
+ {880, {wxMenuBar, setLabel_2, 2}},
+ {881, {wxMenuBar, setLabel_1, 1}},
+ {882, {wxMenuBar, setLabelTop, 2}},
+ {883, {wxControl, getLabel, 0}},
+ {884, {wxControl, setLabel, 1}},
+ {885, {wxControlWithItems, append_1, 1}},
+ {886, {wxControlWithItems, append_2, 2}},
+ {887, {wxControlWithItems, appendStrings_1, 1}},
+ {888, {wxControlWithItems, clear, 0}},
+ {889, {wxControlWithItems, delete, 1}},
+ {890, {wxControlWithItems, findString, 2}},
+ {891, {wxControlWithItems, getClientData, 1}},
+ {892, {wxControlWithItems, setClientData, 2}},
+ {893, {wxControlWithItems, getCount, 0}},
+ {894, {wxControlWithItems, getSelection, 0}},
+ {895, {wxControlWithItems, getString, 1}},
+ {896, {wxControlWithItems, getStringSelection, 0}},
+ {897, {wxControlWithItems, insert_2, 2}},
+ {898, {wxControlWithItems, insert_3, 3}},
+ {899, {wxControlWithItems, isEmpty, 0}},
+ {900, {wxControlWithItems, select, 1}},
+ {901, {wxControlWithItems, setSelection, 1}},
+ {902, {wxControlWithItems, setString, 2}},
+ {903, {wxControlWithItems, setStringSelection, 1}},
+ {906, {wxMenu, new_2, 2}},
+ {907, {wxMenu, new_1, 1}},
+ {909, {wxMenu, destruct, 0}},
+ {910, {wxMenu, append_3, 3}},
+ {911, {wxMenu, append_1, 1}},
+ {912, {wxMenu, append_4_0, 4}},
+ {913, {wxMenu, append_4_1, 4}},
+ {914, {wxMenu, appendCheckItem, 3}},
+ {915, {wxMenu, appendRadioItem, 3}},
+ {916, {wxMenu, appendSeparator, 0}},
+ {917, {wxMenu, break, 0}},
+ {918, {wxMenu, check, 2}},
+ {919, {wxMenu, delete_1_0, 1}},
+ {920, {wxMenu, delete_1_1, 1}},
+ {921, {wxMenu, destroy_1_0, 1}},
+ {922, {wxMenu, destroy_1_1, 1}},
+ {923, {wxMenu, enable, 2}},
+ {924, {wxMenu, findItem_1, 1}},
+ {925, {wxMenu, findItem_2, 2}},
+ {926, {wxMenu, findItemByPosition, 1}},
+ {927, {wxMenu, getHelpString, 1}},
+ {928, {wxMenu, getLabel, 1}},
+ {929, {wxMenu, getMenuItemCount, 0}},
+ {930, {wxMenu, getMenuItems, 0}},
+ {932, {wxMenu, getTitle, 0}},
+ {933, {wxMenu, insert_2, 2}},
+ {934, {wxMenu, insert_3, 3}},
+ {935, {wxMenu, insert_5_1, 5}},
+ {936, {wxMenu, insert_5_0, 5}},
+ {937, {wxMenu, insertCheckItem, 4}},
+ {938, {wxMenu, insertRadioItem, 4}},
+ {939, {wxMenu, insertSeparator, 1}},
+ {940, {wxMenu, isChecked, 1}},
+ {941, {wxMenu, isEnabled, 1}},
+ {942, {wxMenu, prepend_1, 1}},
+ {943, {wxMenu, prepend_2, 2}},
+ {944, {wxMenu, prepend_4_1, 4}},
+ {945, {wxMenu, prepend_4_0, 4}},
+ {946, {wxMenu, prependCheckItem, 3}},
+ {947, {wxMenu, prependRadioItem, 3}},
+ {948, {wxMenu, prependSeparator, 0}},
+ {949, {wxMenu, remove_1_0, 1}},
+ {950, {wxMenu, remove_1_1, 1}},
+ {951, {wxMenu, setHelpString, 2}},
+ {952, {wxMenu, setLabel, 2}},
+ {953, {wxMenu, setTitle, 1}},
+ {954, {wxMenuItem, new, 1}},
+ {956, {wxMenuItem, destruct, 0}},
+ {957, {wxMenuItem, check, 1}},
+ {958, {wxMenuItem, enable, 1}},
+ {959, {wxMenuItem, getBitmap, 0}},
+ {960, {wxMenuItem, getHelp, 0}},
+ {961, {wxMenuItem, getId, 0}},
+ {962, {wxMenuItem, getKind, 0}},
+ {963, {wxMenuItem, getLabel, 0}},
+ {964, {wxMenuItem, getLabelFromText, 1}},
+ {965, {wxMenuItem, getMenu, 0}},
+ {966, {wxMenuItem, getText, 0}},
+ {967, {wxMenuItem, getSubMenu, 0}},
+ {968, {wxMenuItem, isCheckable, 0}},
+ {969, {wxMenuItem, isChecked, 0}},
+ {970, {wxMenuItem, isEnabled, 0}},
+ {971, {wxMenuItem, isSeparator, 0}},
+ {972, {wxMenuItem, isSubMenu, 0}},
+ {973, {wxMenuItem, setBitmap, 1}},
+ {974, {wxMenuItem, setHelp, 1}},
+ {975, {wxMenuItem, setMenu, 1}},
+ {976, {wxMenuItem, setSubMenu, 1}},
+ {977, {wxMenuItem, setText, 1}},
+ {978, {wxToolBar, addControl, 1}},
+ {979, {wxToolBar, addSeparator, 0}},
+ {980, {wxToolBar, addTool_5, 5}},
+ {981, {wxToolBar, addTool_4_0, 4}},
+ {982, {wxToolBar, addTool_1, 1}},
+ {983, {wxToolBar, addTool_4_1, 4}},
+ {984, {wxToolBar, addTool_3, 3}},
+ {985, {wxToolBar, addTool_6, 6}},
+ {986, {wxToolBar, addCheckTool, 4}},
+ {987, {wxToolBar, addRadioTool, 4}},
+ {988, {wxToolBar, addStretchableSpace, 0}},
+ {989, {wxToolBar, insertStretchableSpace, 1}},
+ {990, {wxToolBar, deleteTool, 1}},
+ {991, {wxToolBar, deleteToolByPos, 1}},
+ {992, {wxToolBar, enableTool, 2}},
+ {993, {wxToolBar, findById, 1}},
+ {994, {wxToolBar, findControl, 1}},
+ {995, {wxToolBar, findToolForPosition, 2}},
+ {996, {wxToolBar, getToolSize, 0}},
+ {997, {wxToolBar, getToolBitmapSize, 0}},
+ {998, {wxToolBar, getMargins, 0}},
+ {999, {wxToolBar, getToolEnabled, 1}},
+ {1000, {wxToolBar, getToolLongHelp, 1}},
+ {1001, {wxToolBar, getToolPacking, 0}},
+ {1002, {wxToolBar, getToolPos, 1}},
+ {1003, {wxToolBar, getToolSeparation, 0}},
+ {1004, {wxToolBar, getToolShortHelp, 1}},
+ {1005, {wxToolBar, getToolState, 1}},
+ {1006, {wxToolBar, insertControl, 2}},
+ {1007, {wxToolBar, insertSeparator, 1}},
+ {1008, {wxToolBar, insertTool_5, 5}},
+ {1009, {wxToolBar, insertTool_2, 2}},
+ {1010, {wxToolBar, insertTool_4, 4}},
+ {1011, {wxToolBar, realize, 0}},
+ {1012, {wxToolBar, removeTool, 1}},
+ {1013, {wxToolBar, setMargins, 2}},
+ {1014, {wxToolBar, setToolBitmapSize, 1}},
+ {1015, {wxToolBar, setToolLongHelp, 2}},
+ {1016, {wxToolBar, setToolPacking, 1}},
+ {1017, {wxToolBar, setToolShortHelp, 2}},
+ {1018, {wxToolBar, setToolSeparation, 1}},
+ {1019, {wxToolBar, toggleTool, 2}},
+ {1021, {wxStatusBar, new_0, 0}},
+ {1022, {wxStatusBar, new_2, 2}},
+ {1024, {wxStatusBar, destruct, 0}},
+ {1025, {wxStatusBar, create, 2}},
+ {1026, {wxStatusBar, getFieldRect, 2}},
+ {1027, {wxStatusBar, getFieldsCount, 0}},
+ {1028, {wxStatusBar, getStatusText, 1}},
+ {1029, {wxStatusBar, popStatusText, 1}},
+ {1030, {wxStatusBar, pushStatusText, 2}},
+ {1031, {wxStatusBar, setFieldsCount, 2}},
+ {1032, {wxStatusBar, setMinHeight, 1}},
+ {1033, {wxStatusBar, setStatusText, 2}},
+ {1034, {wxStatusBar, setStatusWidths, 2}},
+ {1035, {wxStatusBar, setStatusStyles, 2}},
+ {1036, {wxBitmap, new_0, 0}},
+ {1037, {wxBitmap, new_3, 3}},
+ {1038, {wxBitmap, new_4, 4}},
+ {1039, {wxBitmap, new_2_0, 2}},
+ {1040, {wxBitmap, new_2_1, 2}},
+ {1041, {wxBitmap, destruct, 0}},
+ {1042, {wxBitmap, convertToImage, 0}},
+ {1043, {wxBitmap, copyFromIcon, 1}},
+ {1044, {wxBitmap, create, 3}},
+ {1045, {wxBitmap, getDepth, 0}},
+ {1046, {wxBitmap, getHeight, 0}},
+ {1047, {wxBitmap, getPalette, 0}},
+ {1048, {wxBitmap, getMask, 0}},
+ {1049, {wxBitmap, getWidth, 0}},
+ {1050, {wxBitmap, getSubBitmap, 1}},
+ {1051, {wxBitmap, loadFile, 2}},
+ {1052, {wxBitmap, ok, 0}},
+ {1053, {wxBitmap, saveFile, 3}},
+ {1054, {wxBitmap, setDepth, 1}},
+ {1055, {wxBitmap, setHeight, 1}},
+ {1056, {wxBitmap, setMask, 1}},
+ {1057, {wxBitmap, setPalette, 1}},
+ {1058, {wxBitmap, setWidth, 1}},
+ {1059, {wxIcon, new_0, 0}},
+ {1060, {wxIcon, new_2, 2}},
+ {1061, {wxIcon, new_1, 1}},
+ {1062, {wxIcon, copyFromBitmap, 1}},
+ {1063, {wxIcon, 'Destroy', undefined}},
+ {1064, {wxIconBundle, new_0, 0}},
+ {1065, {wxIconBundle, new_2, 2}},
+ {1066, {wxIconBundle, new_1_0, 1}},
+ {1067, {wxIconBundle, new_1_1, 1}},
+ {1068, {wxIconBundle, destruct, 0}},
+ {1069, {wxIconBundle, addIcon_2, 2}},
+ {1070, {wxIconBundle, addIcon_1, 1}},
+ {1071, {wxIconBundle, getIcon_1_1, 1}},
+ {1072, {wxIconBundle, getIcon_1_0, 1}},
+ {1073, {wxCursor, new_0, 0}},
+ {1074, {wxCursor, new_1_0, 1}},
+ {1075, {wxCursor, new_1_1, 1}},
+ {1076, {wxCursor, new_4, 4}},
+ {1077, {wxCursor, destruct, 0}},
+ {1078, {wxCursor, ok, 0}},
+ {1079, {wxMask, new_0, 0}},
+ {1080, {wxMask, new_2_1, 2}},
+ {1081, {wxMask, new_2_0, 2}},
+ {1082, {wxMask, new_1, 1}},
+ {1083, {wxMask, destruct, 0}},
+ {1084, {wxMask, create_2_1, 2}},
+ {1085, {wxMask, create_2_0, 2}},
+ {1086, {wxMask, create_1, 1}},
+ {1087, {wxImage, new_0, 0}},
+ {1088, {wxImage, new_3_0, 3}},
+ {1089, {wxImage, new_4, 4}},
+ {1090, {wxImage, new_5, 5}},
+ {1091, {wxImage, new_2, 2}},
+ {1092, {wxImage, new_3_1, 3}},
+ {1093, {wxImage, blur, 1}},
+ {1094, {wxImage, blurHorizontal, 1}},
+ {1095, {wxImage, blurVertical, 1}},
+ {1096, {wxImage, convertAlphaToMask, 1}},
+ {1097, {wxImage, convertToGreyscale, 1}},
+ {1098, {wxImage, convertToMono, 3}},
+ {1099, {wxImage, copy, 0}},
+ {1100, {wxImage, create_3, 3}},
+ {1101, {wxImage, create_4, 4}},
+ {1102, {wxImage, create_5, 5}},
+ {1103, {wxImage, 'Destroy', 0}},
+ {1104, {wxImage, findFirstUnusedColour, 4}},
+ {1105, {wxImage, getImageExtWildcard, 0}},
+ {1106, {wxImage, getAlpha_2, 2}},
+ {1107, {wxImage, getAlpha_0, 0}},
+ {1108, {wxImage, getBlue, 2}},
+ {1109, {wxImage, getData, 0}},
+ {1110, {wxImage, getGreen, 2}},
+ {1111, {wxImage, getImageCount, 2}},
+ {1112, {wxImage, getHeight, 0}},
+ {1113, {wxImage, getMaskBlue, 0}},
+ {1114, {wxImage, getMaskGreen, 0}},
+ {1115, {wxImage, getMaskRed, 0}},
+ {1116, {wxImage, getOrFindMaskColour, 3}},
+ {1117, {wxImage, getPalette, 0}},
+ {1118, {wxImage, getRed, 2}},
+ {1119, {wxImage, getSubImage, 1}},
+ {1120, {wxImage, getWidth, 0}},
+ {1121, {wxImage, hasAlpha, 0}},
+ {1122, {wxImage, hasMask, 0}},
+ {1123, {wxImage, getOption, 1}},
+ {1124, {wxImage, getOptionInt, 1}},
+ {1125, {wxImage, hasOption, 1}},
+ {1126, {wxImage, initAlpha, 0}},
+ {1127, {wxImage, initStandardHandlers, 0}},
+ {1128, {wxImage, isTransparent, 3}},
+ {1129, {wxImage, loadFile_2, 2}},
+ {1130, {wxImage, loadFile_3, 3}},
+ {1131, {wxImage, ok, 0}},
+ {1132, {wxImage, removeHandler, 1}},
+ {1133, {wxImage, mirror, 1}},
+ {1134, {wxImage, replace, 6}},
+ {1135, {wxImage, rescale, 3}},
+ {1136, {wxImage, resize, 3}},
+ {1137, {wxImage, rotate, 3}},
+ {1138, {wxImage, rotateHue, 1}},
+ {1139, {wxImage, rotate90, 1}},
+ {1140, {wxImage, saveFile_1, 1}},
+ {1141, {wxImage, saveFile_2_0, 2}},
+ {1142, {wxImage, saveFile_2_1, 2}},
+ {1143, {wxImage, scale, 3}},
+ {1144, {wxImage, size, 3}},
+ {1145, {wxImage, setAlpha_3, 3}},
+ {1146, {wxImage, setAlpha_2, 2}},
+ {1147, {wxImage, setData_2, 2}},
+ {1148, {wxImage, setData_4, 4}},
+ {1149, {wxImage, setMask, 1}},
+ {1150, {wxImage, setMaskColour, 3}},
+ {1151, {wxImage, setMaskFromImage, 4}},
+ {1152, {wxImage, setOption_2_1, 2}},
+ {1153, {wxImage, setOption_2_0, 2}},
+ {1154, {wxImage, setPalette, 1}},
+ {1155, {wxImage, setRGB_5, 5}},
+ {1156, {wxImage, setRGB_4, 4}},
+ {1157, {wxImage, 'Destroy', undefined}},
+ {1158, {wxBrush, new_0, 0}},
+ {1159, {wxBrush, new_2, 2}},
+ {1160, {wxBrush, new_1, 1}},
+ {1162, {wxBrush, destruct, 0}},
+ {1163, {wxBrush, getColour, 0}},
+ {1164, {wxBrush, getStipple, 0}},
+ {1165, {wxBrush, getStyle, 0}},
+ {1166, {wxBrush, isHatch, 0}},
+ {1167, {wxBrush, isOk, 0}},
+ {1168, {wxBrush, setColour_1, 1}},
+ {1169, {wxBrush, setColour_3, 3}},
+ {1170, {wxBrush, setStipple, 1}},
+ {1171, {wxBrush, setStyle, 1}},
+ {1172, {wxPen, new_0, 0}},
+ {1173, {wxPen, new_2, 2}},
+ {1174, {wxPen, destruct, 0}},
+ {1175, {wxPen, getCap, 0}},
+ {1176, {wxPen, getColour, 0}},
+ {1177, {wxPen, getJoin, 0}},
+ {1178, {wxPen, getStyle, 0}},
+ {1179, {wxPen, getWidth, 0}},
+ {1180, {wxPen, isOk, 0}},
+ {1181, {wxPen, setCap, 1}},
+ {1182, {wxPen, setColour_1, 1}},
+ {1183, {wxPen, setColour_3, 3}},
+ {1184, {wxPen, setJoin, 1}},
+ {1185, {wxPen, setStyle, 1}},
+ {1186, {wxPen, setWidth, 1}},
+ {1187, {wxRegion, new_0, 0}},
+ {1188, {wxRegion, new_4, 4}},
+ {1189, {wxRegion, new_2, 2}},
+ {1190, {wxRegion, new_1_1, 1}},
+ {1192, {wxRegion, new_1_0, 1}},
+ {1194, {wxRegion, destruct, 0}},
+ {1195, {wxRegion, clear, 0}},
+ {1196, {wxRegion, contains_2, 2}},
+ {1197, {wxRegion, contains_1_0, 1}},
+ {1198, {wxRegion, contains_4, 4}},
+ {1199, {wxRegion, contains_1_1, 1}},
+ {1200, {wxRegion, convertToBitmap, 0}},
+ {1201, {wxRegion, getBox, 0}},
+ {1202, {wxRegion, intersect_4, 4}},
+ {1203, {wxRegion, intersect_1_1, 1}},
+ {1204, {wxRegion, intersect_1_0, 1}},
+ {1205, {wxRegion, isEmpty, 0}},
+ {1206, {wxRegion, subtract_4, 4}},
+ {1207, {wxRegion, subtract_1_1, 1}},
+ {1208, {wxRegion, subtract_1_0, 1}},
+ {1209, {wxRegion, offset_2, 2}},
+ {1210, {wxRegion, offset_1, 1}},
+ {1211, {wxRegion, union_4, 4}},
+ {1212, {wxRegion, union_1_2, 1}},
+ {1213, {wxRegion, union_1_1, 1}},
+ {1214, {wxRegion, union_1_0, 1}},
+ {1215, {wxRegion, union_3, 3}},
+ {1216, {wxRegion, xor_4, 4}},
+ {1217, {wxRegion, xor_1_1, 1}},
+ {1218, {wxRegion, xor_1_0, 1}},
+ {1219, {wxAcceleratorTable, new_0, 0}},
+ {1220, {wxAcceleratorTable, new_2, 2}},
+ {1221, {wxAcceleratorTable, destruct, 0}},
+ {1222, {wxAcceleratorTable, ok, 0}},
+ {1223, {wxAcceleratorEntry, new_1_0, 1}},
+ {1224, {wxAcceleratorEntry, new_1_1, 1}},
+ {1225, {wxAcceleratorEntry, getCommand, 0}},
+ {1226, {wxAcceleratorEntry, getFlags, 0}},
+ {1227, {wxAcceleratorEntry, getKeyCode, 0}},
+ {1228, {wxAcceleratorEntry, set, 4}},
+ {1229, {wxAcceleratorEntry, 'Destroy', undefined}},
+ {1234, {wxCaret, new_3, 3}},
+ {1235, {wxCaret, new_2, 2}},
+ {1237, {wxCaret, destruct, 0}},
+ {1238, {wxCaret, create_3, 3}},
+ {1239, {wxCaret, create_2, 2}},
+ {1240, {wxCaret, getBlinkTime, 0}},
+ {1242, {wxCaret, getPosition, 0}},
+ {1244, {wxCaret, getSize, 0}},
+ {1245, {wxCaret, getWindow, 0}},
+ {1246, {wxCaret, hide, 0}},
+ {1247, {wxCaret, isOk, 0}},
+ {1248, {wxCaret, isVisible, 0}},
+ {1249, {wxCaret, move_2, 2}},
+ {1250, {wxCaret, move_1, 1}},
+ {1251, {wxCaret, setBlinkTime, 1}},
+ {1252, {wxCaret, setSize_2, 2}},
+ {1253, {wxCaret, setSize_1, 1}},
+ {1254, {wxCaret, show, 1}},
+ {1255, {wxSizer, add_2_1, 2}},
+ {1256, {wxSizer, add_2_0, 2}},
+ {1257, {wxSizer, add_3, 3}},
+ {1258, {wxSizer, add_2_3, 2}},
+ {1259, {wxSizer, add_2_2, 2}},
+ {1260, {wxSizer, addSpacer, 1}},
+ {1261, {wxSizer, addStretchSpacer, 1}},
+ {1262, {wxSizer, calcMin, 0}},
+ {1263, {wxSizer, clear, 1}},
+ {1264, {wxSizer, detach_1_2, 1}},
+ {1265, {wxSizer, detach_1_1, 1}},
+ {1266, {wxSizer, detach_1_0, 1}},
+ {1267, {wxSizer, fit, 1}},
+ {1268, {wxSizer, fitInside, 1}},
+ {1269, {wxSizer, getChildren, 0}},
+ {1270, {wxSizer, getItem_2_1, 2}},
+ {1271, {wxSizer, getItem_2_0, 2}},
+ {1272, {wxSizer, getItem_1, 1}},
+ {1273, {wxSizer, getSize, 0}},
+ {1274, {wxSizer, getPosition, 0}},
+ {1275, {wxSizer, getMinSize, 0}},
+ {1276, {wxSizer, hide_2_0, 2}},
+ {1277, {wxSizer, hide_2_1, 2}},
+ {1278, {wxSizer, hide_1, 1}},
+ {1279, {wxSizer, insert_3_1, 3}},
+ {1280, {wxSizer, insert_3_0, 3}},
+ {1281, {wxSizer, insert_4, 4}},
+ {1282, {wxSizer, insert_3_3, 3}},
+ {1283, {wxSizer, insert_3_2, 3}},
+ {1284, {wxSizer, insert_2, 2}},
+ {1285, {wxSizer, insertSpacer, 2}},
+ {1286, {wxSizer, insertStretchSpacer, 2}},
+ {1287, {wxSizer, isShown_1_2, 1}},
+ {1288, {wxSizer, isShown_1_1, 1}},
+ {1289, {wxSizer, isShown_1_0, 1}},
+ {1290, {wxSizer, layout, 0}},
+ {1291, {wxSizer, prepend_2_1, 2}},
+ {1292, {wxSizer, prepend_2_0, 2}},
+ {1293, {wxSizer, prepend_3, 3}},
+ {1294, {wxSizer, prepend_2_3, 2}},
+ {1295, {wxSizer, prepend_2_2, 2}},
+ {1296, {wxSizer, prepend_1, 1}},
+ {1297, {wxSizer, prependSpacer, 1}},
+ {1298, {wxSizer, prependStretchSpacer, 1}},
+ {1299, {wxSizer, recalcSizes, 0}},
+ {1300, {wxSizer, remove_1_1, 1}},
+ {1301, {wxSizer, remove_1_0, 1}},
+ {1302, {wxSizer, replace_3_1, 3}},
+ {1303, {wxSizer, replace_3_0, 3}},
+ {1304, {wxSizer, replace_2, 2}},
+ {1305, {wxSizer, setDimension, 4}},
+ {1306, {wxSizer, setMinSize_2, 2}},
+ {1307, {wxSizer, setMinSize_1, 1}},
+ {1308, {wxSizer, setItemMinSize_3_2, 3}},
+ {1309, {wxSizer, setItemMinSize_2_2, 2}},
+ {1310, {wxSizer, setItemMinSize_3_1, 3}},
+ {1311, {wxSizer, setItemMinSize_2_1, 2}},
+ {1312, {wxSizer, setItemMinSize_3_0, 3}},
+ {1313, {wxSizer, setItemMinSize_2_0, 2}},
+ {1314, {wxSizer, setSizeHints, 1}},
+ {1315, {wxSizer, setVirtualSizeHints, 1}},
+ {1316, {wxSizer, show_2_2, 2}},
+ {1317, {wxSizer, show_2_1, 2}},
+ {1318, {wxSizer, show_2_0, 2}},
+ {1319, {wxSizer, show_1, 1}},
+ {1320, {wxSizerFlags, new, 1}},
+ {1321, {wxSizerFlags, align, 1}},
+ {1322, {wxSizerFlags, border_2, 2}},
+ {1323, {wxSizerFlags, border_1, 1}},
+ {1324, {wxSizerFlags, center, 0}},
+ {1325, {wxSizerFlags, centre, 0}},
+ {1326, {wxSizerFlags, expand, 0}},
+ {1327, {wxSizerFlags, left, 0}},
+ {1328, {wxSizerFlags, proportion, 1}},
+ {1329, {wxSizerFlags, right, 0}},
+ {1330, {wxSizerFlags, 'Destroy', undefined}},
+ {1331, {wxSizerItem, new_5_1, 5}},
+ {1332, {wxSizerItem, new_2_1, 2}},
+ {1333, {wxSizerItem, new_5_0, 5}},
+ {1334, {wxSizerItem, new_2_0, 2}},
+ {1335, {wxSizerItem, new_6, 6}},
+ {1336, {wxSizerItem, new_3, 3}},
+ {1337, {wxSizerItem, new_0, 0}},
+ {1338, {wxSizerItem, destruct, 0}},
+ {1339, {wxSizerItem, calcMin, 0}},
+ {1340, {wxSizerItem, deleteWindows, 0}},
+ {1341, {wxSizerItem, detachSizer, 0}},
+ {1342, {wxSizerItem, getBorder, 0}},
+ {1343, {wxSizerItem, getFlag, 0}},
+ {1344, {wxSizerItem, getMinSize, 0}},
+ {1345, {wxSizerItem, getPosition, 0}},
+ {1346, {wxSizerItem, getProportion, 0}},
+ {1347, {wxSizerItem, getRatio, 0}},
+ {1348, {wxSizerItem, getRect, 0}},
+ {1349, {wxSizerItem, getSize, 0}},
+ {1350, {wxSizerItem, getSizer, 0}},
+ {1351, {wxSizerItem, getSpacer, 0}},
+ {1352, {wxSizerItem, getUserData, 0}},
+ {1353, {wxSizerItem, getWindow, 0}},
+ {1354, {wxSizerItem, isSizer, 0}},
+ {1355, {wxSizerItem, isShown, 0}},
+ {1356, {wxSizerItem, isSpacer, 0}},
+ {1357, {wxSizerItem, isWindow, 0}},
+ {1358, {wxSizerItem, setBorder, 1}},
+ {1359, {wxSizerItem, setDimension, 2}},
+ {1360, {wxSizerItem, setFlag, 1}},
+ {1361, {wxSizerItem, setInitSize, 2}},
+ {1362, {wxSizerItem, setMinSize_1, 1}},
+ {1363, {wxSizerItem, setMinSize_2, 2}},
+ {1364, {wxSizerItem, setProportion, 1}},
+ {1365, {wxSizerItem, setRatio_2, 2}},
+ {1366, {wxSizerItem, setRatio_1_1, 1}},
+ {1367, {wxSizerItem, setRatio_1_0, 1}},
+ {1368, {wxSizerItem, setSizer, 1}},
+ {1369, {wxSizerItem, setSpacer_1, 1}},
+ {1370, {wxSizerItem, setSpacer_2, 2}},
+ {1371, {wxSizerItem, setWindow, 1}},
+ {1372, {wxSizerItem, show, 1}},
+ {1373, {wxBoxSizer, new, 1}},
+ {1374, {wxBoxSizer, getOrientation, 0}},
+ {1375, {wxBoxSizer, 'Destroy', undefined}},
+ {1376, {wxStaticBoxSizer, new_2, 2}},
+ {1377, {wxStaticBoxSizer, new_3, 3}},
+ {1378, {wxStaticBoxSizer, getStaticBox, 0}},
+ {1379, {wxStaticBoxSizer, 'Destroy', undefined}},
+ {1380, {wxGridSizer, new_4, 4}},
+ {1381, {wxGridSizer, new_2, 2}},
+ {1382, {wxGridSizer, getCols, 0}},
+ {1383, {wxGridSizer, getHGap, 0}},
+ {1384, {wxGridSizer, getRows, 0}},
+ {1385, {wxGridSizer, getVGap, 0}},
+ {1386, {wxGridSizer, setCols, 1}},
+ {1387, {wxGridSizer, setHGap, 1}},
+ {1388, {wxGridSizer, setRows, 1}},
+ {1389, {wxGridSizer, setVGap, 1}},
+ {1390, {wxGridSizer, 'Destroy', undefined}},
+ {1391, {wxFlexGridSizer, new_4, 4}},
+ {1392, {wxFlexGridSizer, new_2, 2}},
+ {1393, {wxFlexGridSizer, addGrowableCol, 2}},
+ {1394, {wxFlexGridSizer, addGrowableRow, 2}},
+ {1395, {wxFlexGridSizer, getFlexibleDirection, 0}},
+ {1396, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}},
+ {1397, {wxFlexGridSizer, removeGrowableCol, 1}},
+ {1398, {wxFlexGridSizer, removeGrowableRow, 1}},
+ {1399, {wxFlexGridSizer, setFlexibleDirection, 1}},
+ {1400, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}},
+ {1401, {wxFlexGridSizer, 'Destroy', undefined}},
+ {1402, {wxGridBagSizer, new, 1}},
+ {1403, {wxGridBagSizer, add_3_2, 3}},
+ {1404, {wxGridBagSizer, add_3_1, 3}},
+ {1405, {wxGridBagSizer, add_4, 4}},
+ {1406, {wxGridBagSizer, add_1_0, 1}},
+ {1407, {wxGridBagSizer, add_2_1, 2}},
+ {1408, {wxGridBagSizer, add_2_0, 2}},
+ {1409, {wxGridBagSizer, add_3_0, 3}},
+ {1410, {wxGridBagSizer, add_1_1, 1}},
+ {1411, {wxGridBagSizer, calcMin, 0}},
+ {1412, {wxGridBagSizer, checkForIntersection_2, 2}},
+ {1413, {wxGridBagSizer, checkForIntersection_3, 3}},
+ {1414, {wxGridBagSizer, findItem_1_1, 1}},
+ {1415, {wxGridBagSizer, findItem_1_0, 1}},
+ {1416, {wxGridBagSizer, findItemAtPoint, 1}},
+ {1417, {wxGridBagSizer, findItemAtPosition, 1}},
+ {1418, {wxGridBagSizer, findItemWithData, 1}},
+ {1419, {wxGridBagSizer, getCellSize, 2}},
+ {1420, {wxGridBagSizer, getEmptyCellSize, 0}},
+ {1421, {wxGridBagSizer, getItemPosition_1_2, 1}},
+ {1422, {wxGridBagSizer, getItemPosition_1_1, 1}},
+ {1423, {wxGridBagSizer, getItemPosition_1_0, 1}},
+ {1424, {wxGridBagSizer, getItemSpan_1_2, 1}},
+ {1425, {wxGridBagSizer, getItemSpan_1_1, 1}},
+ {1426, {wxGridBagSizer, getItemSpan_1_0, 1}},
+ {1427, {wxGridBagSizer, setEmptyCellSize, 1}},
+ {1428, {wxGridBagSizer, setItemPosition_2_2, 2}},
+ {1429, {wxGridBagSizer, setItemPosition_2_1, 2}},
+ {1430, {wxGridBagSizer, setItemPosition_2_0, 2}},
+ {1431, {wxGridBagSizer, setItemSpan_2_2, 2}},
+ {1432, {wxGridBagSizer, setItemSpan_2_1, 2}},
+ {1433, {wxGridBagSizer, setItemSpan_2_0, 2}},
+ {1434, {wxGridBagSizer, 'Destroy', undefined}},
+ {1435, {wxStdDialogButtonSizer, new, 0}},
+ {1436, {wxStdDialogButtonSizer, addButton, 1}},
+ {1437, {wxStdDialogButtonSizer, realize, 0}},
+ {1438, {wxStdDialogButtonSizer, setAffirmativeButton, 1}},
+ {1439, {wxStdDialogButtonSizer, setCancelButton, 1}},
+ {1440, {wxStdDialogButtonSizer, setNegativeButton, 1}},
+ {1441, {wxStdDialogButtonSizer, 'Destroy', undefined}},
+ {1442, {wxFont, new_0, 0}},
+ {1443, {wxFont, new_1, 1}},
+ {1444, {wxFont, new_5, 5}},
+ {1446, {wxFont, destruct, 0}},
+ {1447, {wxFont, isFixedWidth, 0}},
+ {1448, {wxFont, getDefaultEncoding, 0}},
+ {1449, {wxFont, getFaceName, 0}},
+ {1450, {wxFont, getFamily, 0}},
+ {1451, {wxFont, getNativeFontInfoDesc, 0}},
+ {1452, {wxFont, getNativeFontInfoUserDesc, 0}},
+ {1453, {wxFont, getPointSize, 0}},
+ {1454, {wxFont, getStyle, 0}},
+ {1455, {wxFont, getUnderlined, 0}},
+ {1456, {wxFont, getWeight, 0}},
+ {1457, {wxFont, ok, 0}},
+ {1458, {wxFont, setDefaultEncoding, 1}},
+ {1459, {wxFont, setFaceName, 1}},
+ {1460, {wxFont, setFamily, 1}},
+ {1461, {wxFont, setPointSize, 1}},
+ {1462, {wxFont, setStyle, 1}},
+ {1463, {wxFont, setUnderlined, 1}},
+ {1464, {wxFont, setWeight, 1}},
+ {1465, {wxToolTip, enable, 1}},
+ {1466, {wxToolTip, setDelay, 1}},
+ {1467, {wxToolTip, new, 1}},
+ {1468, {wxToolTip, setTip, 1}},
+ {1469, {wxToolTip, getTip, 0}},
+ {1470, {wxToolTip, getWindow, 0}},
+ {1471, {wxToolTip, 'Destroy', undefined}},
+ {1473, {wxButton, new_3, 3}},
+ {1474, {wxButton, new_0, 0}},
+ {1475, {wxButton, destruct, 0}},
+ {1476, {wxButton, create, 3}},
+ {1477, {wxButton, getDefaultSize, 0}},
+ {1478, {wxButton, setDefault, 0}},
+ {1479, {wxButton, setLabel, 1}},
+ {1481, {wxBitmapButton, new_4, 4}},
+ {1482, {wxBitmapButton, new_0, 0}},
+ {1483, {wxBitmapButton, create, 4}},
+ {1484, {wxBitmapButton, getBitmapDisabled, 0}},
+ {1486, {wxBitmapButton, getBitmapFocus, 0}},
+ {1488, {wxBitmapButton, getBitmapLabel, 0}},
+ {1490, {wxBitmapButton, getBitmapSelected, 0}},
+ {1492, {wxBitmapButton, setBitmapDisabled, 1}},
+ {1493, {wxBitmapButton, setBitmapFocus, 1}},
+ {1494, {wxBitmapButton, setBitmapLabel, 1}},
+ {1495, {wxBitmapButton, setBitmapSelected, 1}},
+ {1496, {wxBitmapButton, 'Destroy', undefined}},
+ {1497, {wxToggleButton, new_0, 0}},
+ {1498, {wxToggleButton, new_4, 4}},
+ {1499, {wxToggleButton, create, 4}},
+ {1500, {wxToggleButton, getValue, 0}},
+ {1501, {wxToggleButton, setValue, 1}},
+ {1502, {wxToggleButton, 'Destroy', undefined}},
+ {1503, {wxCalendarCtrl, new_0, 0}},
+ {1504, {wxCalendarCtrl, new_3, 3}},
+ {1505, {wxCalendarCtrl, create, 3}},
+ {1506, {wxCalendarCtrl, destruct, 0}},
+ {1507, {wxCalendarCtrl, setDate, 1}},
+ {1508, {wxCalendarCtrl, getDate, 0}},
+ {1509, {wxCalendarCtrl, enableYearChange, 1}},
+ {1510, {wxCalendarCtrl, enableMonthChange, 1}},
+ {1511, {wxCalendarCtrl, enableHolidayDisplay, 1}},
+ {1512, {wxCalendarCtrl, setHeaderColours, 2}},
+ {1513, {wxCalendarCtrl, getHeaderColourFg, 0}},
+ {1514, {wxCalendarCtrl, getHeaderColourBg, 0}},
+ {1515, {wxCalendarCtrl, setHighlightColours, 2}},
+ {1516, {wxCalendarCtrl, getHighlightColourFg, 0}},
+ {1517, {wxCalendarCtrl, getHighlightColourBg, 0}},
+ {1518, {wxCalendarCtrl, setHolidayColours, 2}},
+ {1519, {wxCalendarCtrl, getHolidayColourFg, 0}},
+ {1520, {wxCalendarCtrl, getHolidayColourBg, 0}},
+ {1521, {wxCalendarCtrl, getAttr, 1}},
+ {1522, {wxCalendarCtrl, setAttr, 2}},
+ {1523, {wxCalendarCtrl, setHoliday, 1}},
+ {1524, {wxCalendarCtrl, resetAttr, 1}},
+ {1525, {wxCalendarCtrl, hitTest, 2}},
+ {1526, {wxCalendarDateAttr, new_0, 0}},
+ {1527, {wxCalendarDateAttr, new_2_1, 2}},
+ {1528, {wxCalendarDateAttr, new_2_0, 2}},
+ {1529, {wxCalendarDateAttr, setTextColour, 1}},
+ {1530, {wxCalendarDateAttr, setBackgroundColour, 1}},
+ {1531, {wxCalendarDateAttr, setBorderColour, 1}},
+ {1532, {wxCalendarDateAttr, setFont, 1}},
+ {1533, {wxCalendarDateAttr, setBorder, 1}},
+ {1534, {wxCalendarDateAttr, setHoliday, 1}},
+ {1535, {wxCalendarDateAttr, hasTextColour, 0}},
+ {1536, {wxCalendarDateAttr, hasBackgroundColour, 0}},
+ {1537, {wxCalendarDateAttr, hasBorderColour, 0}},
+ {1538, {wxCalendarDateAttr, hasFont, 0}},
+ {1539, {wxCalendarDateAttr, hasBorder, 0}},
+ {1540, {wxCalendarDateAttr, isHoliday, 0}},
+ {1541, {wxCalendarDateAttr, getTextColour, 0}},
+ {1542, {wxCalendarDateAttr, getBackgroundColour, 0}},
+ {1543, {wxCalendarDateAttr, getBorderColour, 0}},
+ {1544, {wxCalendarDateAttr, getFont, 0}},
+ {1545, {wxCalendarDateAttr, getBorder, 0}},
+ {1546, {wxCalendarDateAttr, 'Destroy', undefined}},
+ {1548, {wxCheckBox, new_4, 4}},
+ {1549, {wxCheckBox, new_0, 0}},
+ {1550, {wxCheckBox, create, 4}},
+ {1551, {wxCheckBox, getValue, 0}},
+ {1552, {wxCheckBox, get3StateValue, 0}},
+ {1553, {wxCheckBox, is3rdStateAllowedForUser, 0}},
+ {1554, {wxCheckBox, is3State, 0}},
+ {1555, {wxCheckBox, isChecked, 0}},
+ {1556, {wxCheckBox, setValue, 1}},
+ {1557, {wxCheckBox, set3StateValue, 1}},
+ {1558, {wxCheckBox, 'Destroy', undefined}},
+ {1559, {wxCheckListBox, new_0, 0}},
+ {1561, {wxCheckListBox, new_3, 3}},
+ {1562, {wxCheckListBox, check, 2}},
+ {1563, {wxCheckListBox, isChecked, 1}},
+ {1564, {wxCheckListBox, 'Destroy', undefined}},
+ {1567, {wxChoice, new_3, 3}},
+ {1568, {wxChoice, new_0, 0}},
+ {1570, {wxChoice, destruct, 0}},
+ {1572, {wxChoice, create, 6}},
+ {1573, {wxChoice, delete, 1}},
+ {1574, {wxChoice, getColumns, 0}},
+ {1575, {wxChoice, setColumns, 1}},
+ {1576, {wxComboBox, new_0, 0}},
+ {1578, {wxComboBox, new_3, 3}},
+ {1579, {wxComboBox, destruct, 0}},
+ {1581, {wxComboBox, create, 7}},
+ {1582, {wxComboBox, canCopy, 0}},
+ {1583, {wxComboBox, canCut, 0}},
+ {1584, {wxComboBox, canPaste, 0}},
+ {1585, {wxComboBox, canRedo, 0}},
+ {1586, {wxComboBox, canUndo, 0}},
+ {1587, {wxComboBox, copy, 0}},
+ {1588, {wxComboBox, cut, 0}},
+ {1589, {wxComboBox, getInsertionPoint, 0}},
+ {1590, {wxComboBox, getLastPosition, 0}},
+ {1591, {wxComboBox, getValue, 0}},
+ {1592, {wxComboBox, paste, 0}},
+ {1593, {wxComboBox, redo, 0}},
+ {1594, {wxComboBox, replace, 3}},
+ {1595, {wxComboBox, remove, 2}},
+ {1596, {wxComboBox, setInsertionPoint, 1}},
+ {1597, {wxComboBox, setInsertionPointEnd, 0}},
+ {1598, {wxComboBox, setSelection_1, 1}},
+ {1599, {wxComboBox, setSelection_2, 2}},
+ {1600, {wxComboBox, setValue, 1}},
+ {1601, {wxComboBox, undo, 0}},
+ {1602, {wxGauge, new_0, 0}},
+ {1603, {wxGauge, new_4, 4}},
+ {1604, {wxGauge, create, 4}},
+ {1605, {wxGauge, getBezelFace, 0}},
+ {1606, {wxGauge, getRange, 0}},
+ {1607, {wxGauge, getShadowWidth, 0}},
+ {1608, {wxGauge, getValue, 0}},
+ {1609, {wxGauge, isVertical, 0}},
+ {1610, {wxGauge, setBezelFace, 1}},
+ {1611, {wxGauge, setRange, 1}},
+ {1612, {wxGauge, setShadowWidth, 1}},
+ {1613, {wxGauge, setValue, 1}},
+ {1614, {wxGauge, pulse, 0}},
+ {1615, {wxGauge, 'Destroy', undefined}},
+ {1616, {wxGenericDirCtrl, new_0, 0}},
+ {1617, {wxGenericDirCtrl, new_2, 2}},
+ {1618, {wxGenericDirCtrl, destruct, 0}},
+ {1619, {wxGenericDirCtrl, create, 2}},
+ {1620, {wxGenericDirCtrl, init, 0}},
+ {1621, {wxGenericDirCtrl, collapseTree, 0}},
+ {1622, {wxGenericDirCtrl, expandPath, 1}},
+ {1623, {wxGenericDirCtrl, getDefaultPath, 0}},
+ {1624, {wxGenericDirCtrl, getPath, 0}},
+ {1625, {wxGenericDirCtrl, getFilePath, 0}},
+ {1626, {wxGenericDirCtrl, getFilter, 0}},
+ {1627, {wxGenericDirCtrl, getFilterIndex, 0}},
+ {1628, {wxGenericDirCtrl, getRootId, 0}},
+ {1629, {wxGenericDirCtrl, getTreeCtrl, 0}},
+ {1630, {wxGenericDirCtrl, reCreateTree, 0}},
+ {1631, {wxGenericDirCtrl, setDefaultPath, 1}},
+ {1632, {wxGenericDirCtrl, setFilter, 1}},
+ {1633, {wxGenericDirCtrl, setFilterIndex, 1}},
+ {1634, {wxGenericDirCtrl, setPath, 1}},
+ {1636, {wxStaticBox, new_4, 4}},
+ {1637, {wxStaticBox, new_0, 0}},
+ {1638, {wxStaticBox, create, 4}},
+ {1639, {wxStaticBox, 'Destroy', undefined}},
+ {1641, {wxStaticLine, new_2, 2}},
+ {1642, {wxStaticLine, new_0, 0}},
+ {1643, {wxStaticLine, create, 2}},
+ {1644, {wxStaticLine, isVertical, 0}},
+ {1645, {wxStaticLine, getDefaultSize, 0}},
+ {1646, {wxStaticLine, 'Destroy', undefined}},
+ {1649, {wxListBox, new_3, 3}},
+ {1650, {wxListBox, new_0, 0}},
+ {1652, {wxListBox, destruct, 0}},
+ {1654, {wxListBox, create, 6}},
+ {1655, {wxListBox, deselect, 1}},
+ {1656, {wxListBox, getSelections, 1}},
+ {1657, {wxListBox, insertItems, 2}},
+ {1658, {wxListBox, isSelected, 1}},
+ {1659, {wxListBox, set, 1}},
+ {1660, {wxListBox, hitTest, 1}},
+ {1661, {wxListBox, setFirstItem_1_0, 1}},
+ {1662, {wxListBox, setFirstItem_1_1, 1}},
+ {1663, {wxListCtrl, new_0, 0}},
+ {1664, {wxListCtrl, new_2, 2}},
+ {1665, {wxListCtrl, arrange, 1}},
+ {1666, {wxListCtrl, assignImageList, 2}},
+ {1667, {wxListCtrl, clearAll, 0}},
+ {1668, {wxListCtrl, create, 2}},
+ {1669, {wxListCtrl, deleteAllItems, 0}},
+ {1670, {wxListCtrl, deleteColumn, 1}},
+ {1671, {wxListCtrl, deleteItem, 1}},
+ {1672, {wxListCtrl, editLabel, 1}},
+ {1673, {wxListCtrl, ensureVisible, 1}},
+ {1674, {wxListCtrl, findItem_3_0, 3}},
+ {1675, {wxListCtrl, findItem_3_1, 3}},
+ {1676, {wxListCtrl, getColumn, 2}},
+ {1677, {wxListCtrl, getColumnCount, 0}},
+ {1678, {wxListCtrl, getColumnWidth, 1}},
+ {1679, {wxListCtrl, getCountPerPage, 0}},
+ {1680, {wxListCtrl, getEditControl, 0}},
+ {1681, {wxListCtrl, getImageList, 1}},
+ {1682, {wxListCtrl, getItem, 1}},
+ {1683, {wxListCtrl, getItemBackgroundColour, 1}},
+ {1684, {wxListCtrl, getItemCount, 0}},
+ {1685, {wxListCtrl, getItemData, 1}},
+ {1686, {wxListCtrl, getItemFont, 1}},
+ {1687, {wxListCtrl, getItemPosition, 2}},
+ {1688, {wxListCtrl, getItemRect, 3}},
+ {1689, {wxListCtrl, getItemSpacing, 0}},
+ {1690, {wxListCtrl, getItemState, 2}},
+ {1691, {wxListCtrl, getItemText, 1}},
+ {1692, {wxListCtrl, getItemTextColour, 1}},
+ {1693, {wxListCtrl, getNextItem, 2}},
+ {1694, {wxListCtrl, getSelectedItemCount, 0}},
+ {1695, {wxListCtrl, getTextColour, 0}},
+ {1696, {wxListCtrl, getTopItem, 0}},
+ {1697, {wxListCtrl, getViewRect, 0}},
+ {1698, {wxListCtrl, hitTest, 2}},
+ {1699, {wxListCtrl, insertColumn_2, 2}},
+ {1700, {wxListCtrl, insertColumn_3, 3}},
+ {1701, {wxListCtrl, insertItem_1, 1}},
+ {1702, {wxListCtrl, insertItem_2_1, 2}},
+ {1703, {wxListCtrl, insertItem_2_0, 2}},
+ {1704, {wxListCtrl, insertItem_3, 3}},
+ {1705, {wxListCtrl, refreshItem, 1}},
+ {1706, {wxListCtrl, refreshItems, 2}},
+ {1707, {wxListCtrl, scrollList, 2}},
+ {1708, {wxListCtrl, setBackgroundColour, 1}},
+ {1709, {wxListCtrl, setColumn, 2}},
+ {1710, {wxListCtrl, setColumnWidth, 2}},
+ {1711, {wxListCtrl, setImageList, 2}},
+ {1712, {wxListCtrl, setItem_1, 1}},
+ {1713, {wxListCtrl, setItem_4, 4}},
+ {1714, {wxListCtrl, setItemBackgroundColour, 2}},
+ {1715, {wxListCtrl, setItemCount, 1}},
+ {1716, {wxListCtrl, setItemData, 2}},
+ {1717, {wxListCtrl, setItemFont, 2}},
+ {1718, {wxListCtrl, setItemImage, 3}},
+ {1719, {wxListCtrl, setItemColumnImage, 3}},
+ {1720, {wxListCtrl, setItemPosition, 2}},
+ {1721, {wxListCtrl, setItemState, 3}},
+ {1722, {wxListCtrl, setItemText, 2}},
+ {1723, {wxListCtrl, setItemTextColour, 2}},
+ {1724, {wxListCtrl, setSingleStyle, 2}},
+ {1725, {wxListCtrl, setTextColour, 1}},
+ {1726, {wxListCtrl, setWindowStyleFlag, 1}},
+ {1727, {wxListCtrl, sortItems, 2}},
+ {1728, {wxListCtrl, 'Destroy', undefined}},
+ {1729, {wxListView, clearColumnImage, 1}},
+ {1730, {wxListView, focus, 1}},
+ {1731, {wxListView, getFirstSelected, 0}},
+ {1732, {wxListView, getFocusedItem, 0}},
+ {1733, {wxListView, getNextSelected, 1}},
+ {1734, {wxListView, isSelected, 1}},
+ {1735, {wxListView, select, 2}},
+ {1736, {wxListView, setColumnImage, 2}},
+ {1737, {wxListItem, new_0, 0}},
+ {1738, {wxListItem, new_1, 1}},
+ {1739, {wxListItem, destruct, 0}},
+ {1740, {wxListItem, clear, 0}},
+ {1741, {wxListItem, getAlign, 0}},
+ {1742, {wxListItem, getBackgroundColour, 0}},
+ {1743, {wxListItem, getColumn, 0}},
+ {1744, {wxListItem, getFont, 0}},
+ {1745, {wxListItem, getId, 0}},
+ {1746, {wxListItem, getImage, 0}},
+ {1747, {wxListItem, getMask, 0}},
+ {1748, {wxListItem, getState, 0}},
+ {1749, {wxListItem, getText, 0}},
+ {1750, {wxListItem, getTextColour, 0}},
+ {1751, {wxListItem, getWidth, 0}},
+ {1752, {wxListItem, setAlign, 1}},
+ {1753, {wxListItem, setBackgroundColour, 1}},
+ {1754, {wxListItem, setColumn, 1}},
+ {1755, {wxListItem, setFont, 1}},
+ {1756, {wxListItem, setId, 1}},
+ {1757, {wxListItem, setImage, 1}},
+ {1758, {wxListItem, setMask, 1}},
+ {1759, {wxListItem, setState, 1}},
+ {1760, {wxListItem, setStateMask, 1}},
+ {1761, {wxListItem, setText, 1}},
+ {1762, {wxListItem, setTextColour, 1}},
+ {1763, {wxListItem, setWidth, 1}},
+ {1764, {wxListItemAttr, new_0, 0}},
+ {1765, {wxListItemAttr, new_3, 3}},
+ {1766, {wxListItemAttr, getBackgroundColour, 0}},
+ {1767, {wxListItemAttr, getFont, 0}},
+ {1768, {wxListItemAttr, getTextColour, 0}},
+ {1769, {wxListItemAttr, hasBackgroundColour, 0}},
+ {1770, {wxListItemAttr, hasFont, 0}},
+ {1771, {wxListItemAttr, hasTextColour, 0}},
+ {1772, {wxListItemAttr, setBackgroundColour, 1}},
+ {1773, {wxListItemAttr, setFont, 1}},
+ {1774, {wxListItemAttr, setTextColour, 1}},
+ {1775, {wxListItemAttr, 'Destroy', undefined}},
+ {1776, {wxImageList, new_0, 0}},
+ {1777, {wxImageList, new_3, 3}},
+ {1778, {wxImageList, add_1, 1}},
+ {1779, {wxImageList, add_2_0, 2}},
+ {1780, {wxImageList, add_2_1, 2}},
+ {1781, {wxImageList, create, 3}},
+ {1783, {wxImageList, draw, 5}},
+ {1784, {wxImageList, getBitmap, 1}},
+ {1785, {wxImageList, getIcon, 1}},
+ {1786, {wxImageList, getImageCount, 0}},
+ {1787, {wxImageList, getSize, 3}},
+ {1788, {wxImageList, remove, 1}},
+ {1789, {wxImageList, removeAll, 0}},
+ {1790, {wxImageList, replace_2, 2}},
+ {1791, {wxImageList, replace_3, 3}},
+ {1792, {wxImageList, 'Destroy', undefined}},
+ {1793, {wxTextAttr, new_0, 0}},
+ {1794, {wxTextAttr, new_2, 2}},
+ {1795, {wxTextAttr, getAlignment, 0}},
+ {1796, {wxTextAttr, getBackgroundColour, 0}},
+ {1797, {wxTextAttr, getFont, 0}},
+ {1798, {wxTextAttr, getLeftIndent, 0}},
+ {1799, {wxTextAttr, getLeftSubIndent, 0}},
+ {1800, {wxTextAttr, getRightIndent, 0}},
+ {1801, {wxTextAttr, getTabs, 0}},
+ {1802, {wxTextAttr, getTextColour, 0}},
+ {1803, {wxTextAttr, hasBackgroundColour, 0}},
+ {1804, {wxTextAttr, hasFont, 0}},
+ {1805, {wxTextAttr, hasTextColour, 0}},
+ {1806, {wxTextAttr, getFlags, 0}},
+ {1807, {wxTextAttr, isDefault, 0}},
+ {1808, {wxTextAttr, setAlignment, 1}},
+ {1809, {wxTextAttr, setBackgroundColour, 1}},
+ {1810, {wxTextAttr, setFlags, 1}},
+ {1811, {wxTextAttr, setFont, 2}},
+ {1812, {wxTextAttr, setLeftIndent, 2}},
+ {1813, {wxTextAttr, setRightIndent, 1}},
+ {1814, {wxTextAttr, setTabs, 1}},
+ {1815, {wxTextAttr, setTextColour, 1}},
+ {1816, {wxTextAttr, 'Destroy', undefined}},
+ {1818, {wxTextCtrl, new_3, 3}},
+ {1819, {wxTextCtrl, new_0, 0}},
+ {1821, {wxTextCtrl, destruct, 0}},
+ {1822, {wxTextCtrl, appendText, 1}},
+ {1823, {wxTextCtrl, canCopy, 0}},
+ {1824, {wxTextCtrl, canCut, 0}},
+ {1825, {wxTextCtrl, canPaste, 0}},
+ {1826, {wxTextCtrl, canRedo, 0}},
+ {1827, {wxTextCtrl, canUndo, 0}},
+ {1828, {wxTextCtrl, clear, 0}},
+ {1829, {wxTextCtrl, copy, 0}},
+ {1830, {wxTextCtrl, create, 3}},
+ {1831, {wxTextCtrl, cut, 0}},
+ {1832, {wxTextCtrl, discardEdits, 0}},
+ {1833, {wxTextCtrl, changeValue, 1}},
+ {1834, {wxTextCtrl, emulateKeyPress, 1}},
+ {1835, {wxTextCtrl, getDefaultStyle, 0}},
+ {1836, {wxTextCtrl, getInsertionPoint, 0}},
+ {1837, {wxTextCtrl, getLastPosition, 0}},
+ {1838, {wxTextCtrl, getLineLength, 1}},
+ {1839, {wxTextCtrl, getLineText, 1}},
+ {1840, {wxTextCtrl, getNumberOfLines, 0}},
+ {1841, {wxTextCtrl, getRange, 2}},
+ {1842, {wxTextCtrl, getSelection, 2}},
+ {1843, {wxTextCtrl, getStringSelection, 0}},
+ {1844, {wxTextCtrl, getStyle, 2}},
+ {1845, {wxTextCtrl, getValue, 0}},
+ {1846, {wxTextCtrl, isEditable, 0}},
+ {1847, {wxTextCtrl, isModified, 0}},
+ {1848, {wxTextCtrl, isMultiLine, 0}},
+ {1849, {wxTextCtrl, isSingleLine, 0}},
+ {1850, {wxTextCtrl, loadFile, 2}},
+ {1851, {wxTextCtrl, markDirty, 0}},
+ {1852, {wxTextCtrl, paste, 0}},
+ {1853, {wxTextCtrl, positionToXY, 3}},
+ {1854, {wxTextCtrl, redo, 0}},
+ {1855, {wxTextCtrl, remove, 2}},
+ {1856, {wxTextCtrl, replace, 3}},
+ {1857, {wxTextCtrl, saveFile, 1}},
+ {1858, {wxTextCtrl, setDefaultStyle, 1}},
+ {1859, {wxTextCtrl, setEditable, 1}},
+ {1860, {wxTextCtrl, setInsertionPoint, 1}},
+ {1861, {wxTextCtrl, setInsertionPointEnd, 0}},
+ {1863, {wxTextCtrl, setMaxLength, 1}},
+ {1864, {wxTextCtrl, setSelection, 2}},
+ {1865, {wxTextCtrl, setStyle, 3}},
+ {1866, {wxTextCtrl, setValue, 1}},
+ {1867, {wxTextCtrl, showPosition, 1}},
+ {1868, {wxTextCtrl, undo, 0}},
+ {1869, {wxTextCtrl, writeText, 1}},
+ {1870, {wxTextCtrl, xYToPosition, 2}},
+ {1873, {wxNotebook, new_0, 0}},
+ {1874, {wxNotebook, new_3, 3}},
+ {1875, {wxNotebook, destruct, 0}},
+ {1876, {wxNotebook, addPage, 3}},
+ {1877, {wxNotebook, advanceSelection, 1}},
+ {1878, {wxNotebook, assignImageList, 1}},
+ {1879, {wxNotebook, create, 3}},
+ {1880, {wxNotebook, deleteAllPages, 0}},
+ {1881, {wxNotebook, deletePage, 1}},
+ {1882, {wxNotebook, removePage, 1}},
+ {1883, {wxNotebook, getCurrentPage, 0}},
+ {1884, {wxNotebook, getImageList, 0}},
+ {1886, {wxNotebook, getPage, 1}},
+ {1887, {wxNotebook, getPageCount, 0}},
+ {1888, {wxNotebook, getPageImage, 1}},
+ {1889, {wxNotebook, getPageText, 1}},
+ {1890, {wxNotebook, getRowCount, 0}},
+ {1891, {wxNotebook, getSelection, 0}},
+ {1892, {wxNotebook, getThemeBackgroundColour, 0}},
+ {1894, {wxNotebook, hitTest, 2}},
+ {1896, {wxNotebook, insertPage, 4}},
+ {1897, {wxNotebook, setImageList, 1}},
+ {1898, {wxNotebook, setPadding, 1}},
+ {1899, {wxNotebook, setPageSize, 1}},
+ {1900, {wxNotebook, setPageImage, 2}},
+ {1901, {wxNotebook, setPageText, 2}},
+ {1902, {wxNotebook, setSelection, 1}},
+ {1903, {wxNotebook, changeSelection, 1}},
+ {1904, {wxChoicebook, new_0, 0}},
+ {1905, {wxChoicebook, new_3, 3}},
+ {1906, {wxChoicebook, addPage, 3}},
+ {1907, {wxChoicebook, advanceSelection, 1}},
+ {1908, {wxChoicebook, assignImageList, 1}},
+ {1909, {wxChoicebook, create, 3}},
+ {1910, {wxChoicebook, deleteAllPages, 0}},
+ {1911, {wxChoicebook, deletePage, 1}},
+ {1912, {wxChoicebook, removePage, 1}},
+ {1913, {wxChoicebook, getCurrentPage, 0}},
+ {1914, {wxChoicebook, getImageList, 0}},
+ {1916, {wxChoicebook, getPage, 1}},
+ {1917, {wxChoicebook, getPageCount, 0}},
+ {1918, {wxChoicebook, getPageImage, 1}},
+ {1919, {wxChoicebook, getPageText, 1}},
+ {1920, {wxChoicebook, getSelection, 0}},
+ {1921, {wxChoicebook, hitTest, 2}},
+ {1922, {wxChoicebook, insertPage, 4}},
+ {1923, {wxChoicebook, setImageList, 1}},
+ {1924, {wxChoicebook, setPageSize, 1}},
+ {1925, {wxChoicebook, setPageImage, 2}},
+ {1926, {wxChoicebook, setPageText, 2}},
+ {1927, {wxChoicebook, setSelection, 1}},
+ {1928, {wxChoicebook, changeSelection, 1}},
+ {1929, {wxChoicebook, 'Destroy', undefined}},
+ {1930, {wxToolbook, new_0, 0}},
+ {1931, {wxToolbook, new_3, 3}},
+ {1932, {wxToolbook, addPage, 3}},
+ {1933, {wxToolbook, advanceSelection, 1}},
+ {1934, {wxToolbook, assignImageList, 1}},
+ {1935, {wxToolbook, create, 3}},
+ {1936, {wxToolbook, deleteAllPages, 0}},
+ {1937, {wxToolbook, deletePage, 1}},
+ {1938, {wxToolbook, removePage, 1}},
+ {1939, {wxToolbook, getCurrentPage, 0}},
+ {1940, {wxToolbook, getImageList, 0}},
+ {1942, {wxToolbook, getPage, 1}},
+ {1943, {wxToolbook, getPageCount, 0}},
+ {1944, {wxToolbook, getPageImage, 1}},
+ {1945, {wxToolbook, getPageText, 1}},
+ {1946, {wxToolbook, getSelection, 0}},
+ {1948, {wxToolbook, hitTest, 2}},
+ {1949, {wxToolbook, insertPage, 4}},
+ {1950, {wxToolbook, setImageList, 1}},
+ {1951, {wxToolbook, setPageSize, 1}},
+ {1952, {wxToolbook, setPageImage, 2}},
+ {1953, {wxToolbook, setPageText, 2}},
+ {1954, {wxToolbook, setSelection, 1}},
+ {1955, {wxToolbook, changeSelection, 1}},
+ {1956, {wxToolbook, 'Destroy', undefined}},
+ {1957, {wxListbook, new_0, 0}},
+ {1958, {wxListbook, new_3, 3}},
+ {1959, {wxListbook, addPage, 3}},
+ {1960, {wxListbook, advanceSelection, 1}},
+ {1961, {wxListbook, assignImageList, 1}},
+ {1962, {wxListbook, create, 3}},
+ {1963, {wxListbook, deleteAllPages, 0}},
+ {1964, {wxListbook, deletePage, 1}},
+ {1965, {wxListbook, removePage, 1}},
+ {1966, {wxListbook, getCurrentPage, 0}},
+ {1967, {wxListbook, getImageList, 0}},
+ {1969, {wxListbook, getPage, 1}},
+ {1970, {wxListbook, getPageCount, 0}},
+ {1971, {wxListbook, getPageImage, 1}},
+ {1972, {wxListbook, getPageText, 1}},
+ {1973, {wxListbook, getSelection, 0}},
+ {1975, {wxListbook, hitTest, 2}},
+ {1976, {wxListbook, insertPage, 4}},
+ {1977, {wxListbook, setImageList, 1}},
+ {1978, {wxListbook, setPageSize, 1}},
+ {1979, {wxListbook, setPageImage, 2}},
+ {1980, {wxListbook, setPageText, 2}},
+ {1981, {wxListbook, setSelection, 1}},
+ {1982, {wxListbook, changeSelection, 1}},
+ {1983, {wxListbook, 'Destroy', undefined}},
+ {1984, {wxTreebook, new_0, 0}},
+ {1985, {wxTreebook, new_3, 3}},
+ {1986, {wxTreebook, addPage, 3}},
+ {1987, {wxTreebook, advanceSelection, 1}},
+ {1988, {wxTreebook, assignImageList, 1}},
+ {1989, {wxTreebook, create, 3}},
+ {1990, {wxTreebook, deleteAllPages, 0}},
+ {1991, {wxTreebook, deletePage, 1}},
+ {1992, {wxTreebook, removePage, 1}},
+ {1993, {wxTreebook, getCurrentPage, 0}},
+ {1994, {wxTreebook, getImageList, 0}},
+ {1996, {wxTreebook, getPage, 1}},
+ {1997, {wxTreebook, getPageCount, 0}},
+ {1998, {wxTreebook, getPageImage, 1}},
+ {1999, {wxTreebook, getPageText, 1}},
+ {2000, {wxTreebook, getSelection, 0}},
+ {2001, {wxTreebook, expandNode, 2}},
+ {2002, {wxTreebook, isNodeExpanded, 1}},
+ {2004, {wxTreebook, hitTest, 2}},
+ {2005, {wxTreebook, insertPage, 4}},
+ {2006, {wxTreebook, insertSubPage, 4}},
+ {2007, {wxTreebook, setImageList, 1}},
+ {2008, {wxTreebook, setPageSize, 1}},
+ {2009, {wxTreebook, setPageImage, 2}},
+ {2010, {wxTreebook, setPageText, 2}},
+ {2011, {wxTreebook, setSelection, 1}},
+ {2012, {wxTreebook, changeSelection, 1}},
+ {2013, {wxTreebook, 'Destroy', undefined}},
+ {2016, {wxTreeCtrl, new_2, 2}},
+ {2017, {wxTreeCtrl, new_0, 0}},
+ {2019, {wxTreeCtrl, destruct, 0}},
+ {2020, {wxTreeCtrl, addRoot, 2}},
+ {2021, {wxTreeCtrl, appendItem, 3}},
+ {2022, {wxTreeCtrl, assignImageList, 1}},
+ {2023, {wxTreeCtrl, assignStateImageList, 1}},
+ {2024, {wxTreeCtrl, collapse, 1}},
+ {2025, {wxTreeCtrl, collapseAndReset, 1}},
+ {2026, {wxTreeCtrl, create, 2}},
+ {2027, {wxTreeCtrl, delete, 1}},
+ {2028, {wxTreeCtrl, deleteAllItems, 0}},
+ {2029, {wxTreeCtrl, deleteChildren, 1}},
+ {2030, {wxTreeCtrl, editLabel, 1}},
+ {2031, {wxTreeCtrl, ensureVisible, 1}},
+ {2032, {wxTreeCtrl, expand, 1}},
+ {2033, {wxTreeCtrl, getBoundingRect, 3}},
+ {2035, {wxTreeCtrl, getChildrenCount, 2}},
+ {2036, {wxTreeCtrl, getCount, 0}},
+ {2037, {wxTreeCtrl, getEditControl, 0}},
+ {2038, {wxTreeCtrl, getFirstChild, 2}},
+ {2039, {wxTreeCtrl, getNextChild, 2}},
+ {2040, {wxTreeCtrl, getFirstVisibleItem, 0}},
+ {2041, {wxTreeCtrl, getImageList, 0}},
+ {2042, {wxTreeCtrl, getIndent, 0}},
+ {2043, {wxTreeCtrl, getItemBackgroundColour, 1}},
+ {2044, {wxTreeCtrl, getItemData, 1}},
+ {2045, {wxTreeCtrl, getItemFont, 1}},
+ {2046, {wxTreeCtrl, getItemImage_1, 1}},
+ {2047, {wxTreeCtrl, getItemImage_2, 2}},
+ {2048, {wxTreeCtrl, getItemText, 1}},
+ {2049, {wxTreeCtrl, getItemTextColour, 1}},
+ {2050, {wxTreeCtrl, getLastChild, 1}},
+ {2051, {wxTreeCtrl, getNextSibling, 1}},
+ {2052, {wxTreeCtrl, getNextVisible, 1}},
+ {2053, {wxTreeCtrl, getItemParent, 1}},
+ {2054, {wxTreeCtrl, getPrevSibling, 1}},
+ {2055, {wxTreeCtrl, getPrevVisible, 1}},
+ {2056, {wxTreeCtrl, getRootItem, 0}},
+ {2057, {wxTreeCtrl, getSelection, 0}},
+ {2058, {wxTreeCtrl, getSelections, 1}},
+ {2059, {wxTreeCtrl, getStateImageList, 0}},
+ {2060, {wxTreeCtrl, hitTest, 2}},
+ {2062, {wxTreeCtrl, insertItem, 4}},
+ {2063, {wxTreeCtrl, isBold, 1}},
+ {2064, {wxTreeCtrl, isExpanded, 1}},
+ {2065, {wxTreeCtrl, isSelected, 1}},
+ {2066, {wxTreeCtrl, isVisible, 1}},
+ {2067, {wxTreeCtrl, itemHasChildren, 1}},
+ {2068, {wxTreeCtrl, isTreeItemIdOk, 1}},
+ {2069, {wxTreeCtrl, prependItem, 3}},
+ {2070, {wxTreeCtrl, scrollTo, 1}},
+ {2071, {wxTreeCtrl, selectItem_1, 1}},
+ {2072, {wxTreeCtrl, selectItem_2, 2}},
+ {2073, {wxTreeCtrl, setIndent, 1}},
+ {2074, {wxTreeCtrl, setImageList, 1}},
+ {2075, {wxTreeCtrl, setItemBackgroundColour, 2}},
+ {2076, {wxTreeCtrl, setItemBold, 2}},
+ {2077, {wxTreeCtrl, setItemData, 2}},
+ {2078, {wxTreeCtrl, setItemDropHighlight, 2}},
+ {2079, {wxTreeCtrl, setItemFont, 2}},
+ {2080, {wxTreeCtrl, setItemHasChildren, 2}},
+ {2081, {wxTreeCtrl, setItemImage_2, 2}},
+ {2082, {wxTreeCtrl, setItemImage_3, 3}},
+ {2083, {wxTreeCtrl, setItemText, 2}},
+ {2084, {wxTreeCtrl, setItemTextColour, 2}},
+ {2085, {wxTreeCtrl, setStateImageList, 1}},
+ {2086, {wxTreeCtrl, setWindowStyle, 1}},
+ {2087, {wxTreeCtrl, sortChildren, 1}},
+ {2088, {wxTreeCtrl, toggle, 1}},
+ {2089, {wxTreeCtrl, toggleItemSelection, 1}},
+ {2090, {wxTreeCtrl, unselect, 0}},
+ {2091, {wxTreeCtrl, unselectAll, 0}},
+ {2092, {wxTreeCtrl, unselectItem, 1}},
+ {2093, {wxScrollBar, new_0, 0}},
+ {2094, {wxScrollBar, new_3, 3}},
+ {2095, {wxScrollBar, destruct, 0}},
+ {2096, {wxScrollBar, create, 3}},
+ {2097, {wxScrollBar, getRange, 0}},
+ {2098, {wxScrollBar, getPageSize, 0}},
+ {2099, {wxScrollBar, getThumbPosition, 0}},
+ {2100, {wxScrollBar, getThumbSize, 0}},
+ {2101, {wxScrollBar, setThumbPosition, 1}},
+ {2102, {wxScrollBar, setScrollbar, 5}},
+ {2104, {wxSpinButton, new_2, 2}},
+ {2105, {wxSpinButton, new_0, 0}},
+ {2106, {wxSpinButton, create, 2}},
+ {2107, {wxSpinButton, getMax, 0}},
+ {2108, {wxSpinButton, getMin, 0}},
+ {2109, {wxSpinButton, getValue, 0}},
+ {2110, {wxSpinButton, setRange, 2}},
+ {2111, {wxSpinButton, setValue, 1}},
+ {2112, {wxSpinButton, 'Destroy', undefined}},
+ {2113, {wxSpinCtrl, new_0, 0}},
+ {2114, {wxSpinCtrl, new_2, 2}},
+ {2116, {wxSpinCtrl, create, 2}},
+ {2119, {wxSpinCtrl, setValue_1_1, 1}},
+ {2120, {wxSpinCtrl, setValue_1_0, 1}},
+ {2122, {wxSpinCtrl, getValue, 0}},
+ {2124, {wxSpinCtrl, setRange, 2}},
+ {2125, {wxSpinCtrl, setSelection, 2}},
+ {2127, {wxSpinCtrl, getMin, 0}},
+ {2129, {wxSpinCtrl, getMax, 0}},
+ {2130, {wxSpinCtrl, 'Destroy', undefined}},
+ {2131, {wxStaticText, new_0, 0}},
+ {2132, {wxStaticText, new_4, 4}},
+ {2133, {wxStaticText, create, 4}},
+ {2134, {wxStaticText, getLabel, 0}},
+ {2135, {wxStaticText, setLabel, 1}},
+ {2136, {wxStaticText, wrap, 1}},
+ {2137, {wxStaticText, 'Destroy', undefined}},
+ {2138, {wxStaticBitmap, new_0, 0}},
+ {2139, {wxStaticBitmap, new_4, 4}},
+ {2140, {wxStaticBitmap, create, 4}},
+ {2141, {wxStaticBitmap, getBitmap, 0}},
+ {2142, {wxStaticBitmap, setBitmap, 1}},
+ {2143, {wxStaticBitmap, 'Destroy', undefined}},
+ {2144, {wxRadioBox, new, 7}},
+ {2146, {wxRadioBox, destruct, 0}},
+ {2147, {wxRadioBox, create, 7}},
+ {2148, {wxRadioBox, enable_2, 2}},
+ {2149, {wxRadioBox, enable_1, 1}},
+ {2150, {wxRadioBox, getSelection, 0}},
+ {2151, {wxRadioBox, getString, 1}},
+ {2152, {wxRadioBox, setSelection, 1}},
+ {2153, {wxRadioBox, show_2, 2}},
+ {2154, {wxRadioBox, show_1, 1}},
+ {2155, {wxRadioBox, getColumnCount, 0}},
+ {2156, {wxRadioBox, getItemHelpText, 1}},
+ {2157, {wxRadioBox, getItemToolTip, 1}},
+ {2159, {wxRadioBox, getItemFromPoint, 1}},
+ {2160, {wxRadioBox, getRowCount, 0}},
+ {2161, {wxRadioBox, isItemEnabled, 1}},
+ {2162, {wxRadioBox, isItemShown, 1}},
+ {2163, {wxRadioBox, setItemHelpText, 2}},
+ {2164, {wxRadioBox, setItemToolTip, 2}},
+ {2165, {wxRadioButton, new_0, 0}},
+ {2166, {wxRadioButton, new_4, 4}},
+ {2167, {wxRadioButton, create, 4}},
+ {2168, {wxRadioButton, getValue, 0}},
+ {2169, {wxRadioButton, setValue, 1}},
+ {2170, {wxRadioButton, 'Destroy', undefined}},
+ {2172, {wxSlider, new_6, 6}},
+ {2173, {wxSlider, new_0, 0}},
+ {2174, {wxSlider, create, 6}},
+ {2175, {wxSlider, getLineSize, 0}},
+ {2176, {wxSlider, getMax, 0}},
+ {2177, {wxSlider, getMin, 0}},
+ {2178, {wxSlider, getPageSize, 0}},
+ {2179, {wxSlider, getThumbLength, 0}},
+ {2180, {wxSlider, getValue, 0}},
+ {2181, {wxSlider, setLineSize, 1}},
+ {2182, {wxSlider, setPageSize, 1}},
+ {2183, {wxSlider, setRange, 2}},
+ {2184, {wxSlider, setThumbLength, 1}},
+ {2185, {wxSlider, setValue, 1}},
+ {2186, {wxSlider, 'Destroy', undefined}},
+ {2188, {wxDialog, new_4, 4}},
+ {2189, {wxDialog, new_0, 0}},
+ {2191, {wxDialog, destruct, 0}},
+ {2192, {wxDialog, create, 4}},
+ {2193, {wxDialog, createButtonSizer, 1}},
+ {2194, {wxDialog, createStdDialogButtonSizer, 1}},
+ {2195, {wxDialog, endModal, 1}},
+ {2196, {wxDialog, getAffirmativeId, 0}},
+ {2197, {wxDialog, getReturnCode, 0}},
+ {2198, {wxDialog, isModal, 0}},
+ {2199, {wxDialog, setAffirmativeId, 1}},
+ {2200, {wxDialog, setReturnCode, 1}},
+ {2201, {wxDialog, show, 1}},
+ {2202, {wxDialog, showModal, 0}},
+ {2203, {wxColourDialog, new_0, 0}},
+ {2204, {wxColourDialog, new_2, 2}},
+ {2205, {wxColourDialog, destruct, 0}},
+ {2206, {wxColourDialog, create, 2}},
+ {2207, {wxColourDialog, getColourData, 0}},
+ {2208, {wxColourData, new_0, 0}},
+ {2209, {wxColourData, new_1, 1}},
+ {2210, {wxColourData, destruct, 0}},
+ {2211, {wxColourData, getChooseFull, 0}},
+ {2212, {wxColourData, getColour, 0}},
+ {2214, {wxColourData, getCustomColour, 1}},
+ {2215, {wxColourData, setChooseFull, 1}},
+ {2216, {wxColourData, setColour, 1}},
+ {2217, {wxColourData, setCustomColour, 2}},
+ {2218, {wxPalette, new_0, 0}},
+ {2219, {wxPalette, new_4, 4}},
+ {2221, {wxPalette, destruct, 0}},
+ {2222, {wxPalette, create, 4}},
+ {2223, {wxPalette, getColoursCount, 0}},
+ {2224, {wxPalette, getPixel, 3}},
+ {2225, {wxPalette, getRGB, 4}},
+ {2226, {wxPalette, isOk, 0}},
+ {2230, {wxDirDialog, new, 2}},
+ {2231, {wxDirDialog, destruct, 0}},
+ {2232, {wxDirDialog, getPath, 0}},
+ {2233, {wxDirDialog, getMessage, 0}},
+ {2234, {wxDirDialog, setMessage, 1}},
+ {2235, {wxDirDialog, setPath, 1}},
+ {2239, {wxFileDialog, new, 2}},
+ {2240, {wxFileDialog, destruct, 0}},
+ {2241, {wxFileDialog, getDirectory, 0}},
+ {2242, {wxFileDialog, getFilename, 0}},
+ {2243, {wxFileDialog, getFilenames, 1}},
+ {2244, {wxFileDialog, getFilterIndex, 0}},
+ {2245, {wxFileDialog, getMessage, 0}},
+ {2246, {wxFileDialog, getPath, 0}},
+ {2247, {wxFileDialog, getPaths, 1}},
+ {2248, {wxFileDialog, getWildcard, 0}},
+ {2249, {wxFileDialog, setDirectory, 1}},
+ {2250, {wxFileDialog, setFilename, 1}},
+ {2251, {wxFileDialog, setFilterIndex, 1}},
+ {2252, {wxFileDialog, setMessage, 1}},
+ {2253, {wxFileDialog, setPath, 1}},
+ {2254, {wxFileDialog, setWildcard, 1}},
+ {2255, {wxPickerBase, setInternalMargin, 1}},
+ {2256, {wxPickerBase, getInternalMargin, 0}},
+ {2257, {wxPickerBase, setTextCtrlProportion, 1}},
+ {2258, {wxPickerBase, setPickerCtrlProportion, 1}},
+ {2259, {wxPickerBase, getTextCtrlProportion, 0}},
+ {2260, {wxPickerBase, getPickerCtrlProportion, 0}},
+ {2261, {wxPickerBase, hasTextCtrl, 0}},
+ {2262, {wxPickerBase, getTextCtrl, 0}},
+ {2263, {wxPickerBase, isTextCtrlGrowable, 0}},
+ {2264, {wxPickerBase, setPickerCtrlGrowable, 1}},
+ {2265, {wxPickerBase, setTextCtrlGrowable, 1}},
+ {2266, {wxPickerBase, isPickerCtrlGrowable, 0}},
+ {2267, {wxFilePickerCtrl, new_0, 0}},
+ {2268, {wxFilePickerCtrl, new_3, 3}},
+ {2269, {wxFilePickerCtrl, create, 3}},
+ {2270, {wxFilePickerCtrl, getPath, 0}},
+ {2271, {wxFilePickerCtrl, setPath, 1}},
+ {2272, {wxFilePickerCtrl, 'Destroy', undefined}},
+ {2273, {wxDirPickerCtrl, new_0, 0}},
+ {2274, {wxDirPickerCtrl, new_3, 3}},
+ {2275, {wxDirPickerCtrl, create, 3}},
+ {2276, {wxDirPickerCtrl, getPath, 0}},
+ {2277, {wxDirPickerCtrl, setPath, 1}},
+ {2278, {wxDirPickerCtrl, 'Destroy', undefined}},
+ {2279, {wxColourPickerCtrl, new_0, 0}},
+ {2280, {wxColourPickerCtrl, new_3, 3}},
+ {2281, {wxColourPickerCtrl, create, 3}},
+ {2282, {wxColourPickerCtrl, getColour, 0}},
+ {2283, {wxColourPickerCtrl, setColour_1_1, 1}},
+ {2284, {wxColourPickerCtrl, setColour_1_0, 1}},
+ {2285, {wxColourPickerCtrl, 'Destroy', undefined}},
+ {2286, {wxDatePickerCtrl, new_0, 0}},
+ {2287, {wxDatePickerCtrl, new_3, 3}},
+ {2288, {wxDatePickerCtrl, getRange, 2}},
+ {2289, {wxDatePickerCtrl, getValue, 0}},
+ {2290, {wxDatePickerCtrl, setRange, 2}},
+ {2291, {wxDatePickerCtrl, setValue, 1}},
+ {2292, {wxDatePickerCtrl, 'Destroy', undefined}},
+ {2293, {wxFontPickerCtrl, new_0, 0}},
+ {2294, {wxFontPickerCtrl, new_3, 3}},
+ {2295, {wxFontPickerCtrl, create, 3}},
+ {2296, {wxFontPickerCtrl, getSelectedFont, 0}},
+ {2297, {wxFontPickerCtrl, setSelectedFont, 1}},
+ {2298, {wxFontPickerCtrl, getMaxPointSize, 0}},
+ {2299, {wxFontPickerCtrl, setMaxPointSize, 1}},
+ {2300, {wxFontPickerCtrl, 'Destroy', undefined}},
+ {2303, {wxFindReplaceDialog, new_0, 0}},
+ {2304, {wxFindReplaceDialog, new_4, 4}},
+ {2305, {wxFindReplaceDialog, destruct, 0}},
+ {2306, {wxFindReplaceDialog, create, 4}},
+ {2307, {wxFindReplaceDialog, getData, 0}},
+ {2308, {wxFindReplaceData, new_0, 0}},
+ {2309, {wxFindReplaceData, new_1, 1}},
+ {2310, {wxFindReplaceData, getFindString, 0}},
+ {2311, {wxFindReplaceData, getReplaceString, 0}},
+ {2312, {wxFindReplaceData, getFlags, 0}},
+ {2313, {wxFindReplaceData, setFlags, 1}},
+ {2314, {wxFindReplaceData, setFindString, 1}},
+ {2315, {wxFindReplaceData, setReplaceString, 1}},
+ {2316, {wxFindReplaceData, 'Destroy', undefined}},
+ {2317, {wxMultiChoiceDialog, new_0, 0}},
+ {2319, {wxMultiChoiceDialog, new_5, 5}},
+ {2320, {wxMultiChoiceDialog, getSelections, 0}},
+ {2321, {wxMultiChoiceDialog, setSelections, 1}},
+ {2322, {wxMultiChoiceDialog, 'Destroy', undefined}},
+ {2323, {wxSingleChoiceDialog, new_0, 0}},
+ {2325, {wxSingleChoiceDialog, new_5, 5}},
+ {2326, {wxSingleChoiceDialog, getSelection, 0}},
+ {2327, {wxSingleChoiceDialog, getStringSelection, 0}},
+ {2328, {wxSingleChoiceDialog, setSelection, 1}},
+ {2329, {wxSingleChoiceDialog, 'Destroy', undefined}},
+ {2330, {wxTextEntryDialog, new, 3}},
+ {2331, {wxTextEntryDialog, getValue, 0}},
+ {2332, {wxTextEntryDialog, setValue, 1}},
+ {2333, {wxTextEntryDialog, 'Destroy', undefined}},
+ {2334, {wxPasswordEntryDialog, new, 3}},
+ {2335, {wxPasswordEntryDialog, 'Destroy', undefined}},
+ {2336, {wxFontData, new_0, 0}},
+ {2337, {wxFontData, new_1, 1}},
+ {2338, {wxFontData, destruct, 0}},
+ {2339, {wxFontData, enableEffects, 1}},
+ {2340, {wxFontData, getAllowSymbols, 0}},
+ {2341, {wxFontData, getColour, 0}},
+ {2342, {wxFontData, getChosenFont, 0}},
+ {2343, {wxFontData, getEnableEffects, 0}},
+ {2344, {wxFontData, getInitialFont, 0}},
+ {2345, {wxFontData, getShowHelp, 0}},
+ {2346, {wxFontData, setAllowSymbols, 1}},
+ {2347, {wxFontData, setChosenFont, 1}},
+ {2348, {wxFontData, setColour, 1}},
+ {2349, {wxFontData, setInitialFont, 1}},
+ {2350, {wxFontData, setRange, 2}},
+ {2351, {wxFontData, setShowHelp, 1}},
+ {2355, {wxFontDialog, new_0, 0}},
+ {2357, {wxFontDialog, new_2, 2}},
+ {2359, {wxFontDialog, create, 2}},
+ {2360, {wxFontDialog, getFontData, 0}},
+ {2362, {wxFontDialog, 'Destroy', undefined}},
+ {2363, {wxProgressDialog, new, 3}},
+ {2364, {wxProgressDialog, destruct, 0}},
+ {2365, {wxProgressDialog, resume, 0}},
+ {2366, {wxProgressDialog, update_2, 2}},
+ {2367, {wxProgressDialog, update_0, 0}},
+ {2368, {wxMessageDialog, new, 3}},
+ {2369, {wxMessageDialog, destruct, 0}},
+ {2370, {wxPageSetupDialog, new, 2}},
+ {2371, {wxPageSetupDialog, destruct, 0}},
+ {2372, {wxPageSetupDialog, getPageSetupData, 0}},
+ {2373, {wxPageSetupDialog, showModal, 0}},
+ {2374, {wxPageSetupDialogData, new_0, 0}},
+ {2375, {wxPageSetupDialogData, new_1_0, 1}},
+ {2376, {wxPageSetupDialogData, new_1_1, 1}},
+ {2377, {wxPageSetupDialogData, destruct, 0}},
+ {2378, {wxPageSetupDialogData, enableHelp, 1}},
+ {2379, {wxPageSetupDialogData, enableMargins, 1}},
+ {2380, {wxPageSetupDialogData, enableOrientation, 1}},
+ {2381, {wxPageSetupDialogData, enablePaper, 1}},
+ {2382, {wxPageSetupDialogData, enablePrinter, 1}},
+ {2383, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
+ {2384, {wxPageSetupDialogData, getEnableMargins, 0}},
+ {2385, {wxPageSetupDialogData, getEnableOrientation, 0}},
+ {2386, {wxPageSetupDialogData, getEnablePaper, 0}},
+ {2387, {wxPageSetupDialogData, getEnablePrinter, 0}},
+ {2388, {wxPageSetupDialogData, getEnableHelp, 0}},
+ {2389, {wxPageSetupDialogData, getDefaultInfo, 0}},
+ {2390, {wxPageSetupDialogData, getMarginTopLeft, 0}},
+ {2391, {wxPageSetupDialogData, getMarginBottomRight, 0}},
+ {2392, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
+ {2393, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
+ {2394, {wxPageSetupDialogData, getPaperId, 0}},
+ {2395, {wxPageSetupDialogData, getPaperSize, 0}},
+ {2397, {wxPageSetupDialogData, getPrintData, 0}},
+ {2398, {wxPageSetupDialogData, isOk, 0}},
+ {2399, {wxPageSetupDialogData, setDefaultInfo, 1}},
+ {2400, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
+ {2401, {wxPageSetupDialogData, setMarginTopLeft, 1}},
+ {2402, {wxPageSetupDialogData, setMarginBottomRight, 1}},
+ {2403, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
+ {2404, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
+ {2405, {wxPageSetupDialogData, setPaperId, 1}},
+ {2406, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
+ {2407, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
+ {2408, {wxPageSetupDialogData, setPrintData, 1}},
+ {2409, {wxPrintDialog, new_2_0, 2}},
+ {2410, {wxPrintDialog, new_2_1, 2}},
+ {2411, {wxPrintDialog, destruct, 0}},
+ {2412, {wxPrintDialog, getPrintDialogData, 0}},
+ {2413, {wxPrintDialog, getPrintDC, 0}},
+ {2414, {wxPrintDialogData, new_0, 0}},
+ {2415, {wxPrintDialogData, new_1_1, 1}},
+ {2416, {wxPrintDialogData, new_1_0, 1}},
+ {2417, {wxPrintDialogData, destruct, 0}},
+ {2418, {wxPrintDialogData, enableHelp, 1}},
+ {2419, {wxPrintDialogData, enablePageNumbers, 1}},
+ {2420, {wxPrintDialogData, enablePrintToFile, 1}},
+ {2421, {wxPrintDialogData, enableSelection, 1}},
+ {2422, {wxPrintDialogData, getAllPages, 0}},
+ {2423, {wxPrintDialogData, getCollate, 0}},
+ {2424, {wxPrintDialogData, getFromPage, 0}},
+ {2425, {wxPrintDialogData, getMaxPage, 0}},
+ {2426, {wxPrintDialogData, getMinPage, 0}},
+ {2427, {wxPrintDialogData, getNoCopies, 0}},
+ {2428, {wxPrintDialogData, getPrintData, 0}},
+ {2429, {wxPrintDialogData, getPrintToFile, 0}},
+ {2430, {wxPrintDialogData, getSelection, 0}},
+ {2431, {wxPrintDialogData, getToPage, 0}},
+ {2432, {wxPrintDialogData, isOk, 0}},
+ {2433, {wxPrintDialogData, setCollate, 1}},
+ {2434, {wxPrintDialogData, setFromPage, 1}},
+ {2435, {wxPrintDialogData, setMaxPage, 1}},
+ {2436, {wxPrintDialogData, setMinPage, 1}},
+ {2437, {wxPrintDialogData, setNoCopies, 1}},
+ {2438, {wxPrintDialogData, setPrintData, 1}},
+ {2439, {wxPrintDialogData, setPrintToFile, 1}},
+ {2440, {wxPrintDialogData, setSelection, 1}},
+ {2441, {wxPrintDialogData, setToPage, 1}},
+ {2442, {wxPrintData, new_0, 0}},
+ {2443, {wxPrintData, new_1, 1}},
+ {2444, {wxPrintData, destruct, 0}},
+ {2445, {wxPrintData, getCollate, 0}},
+ {2446, {wxPrintData, getBin, 0}},
+ {2447, {wxPrintData, getColour, 0}},
+ {2448, {wxPrintData, getDuplex, 0}},
+ {2449, {wxPrintData, getNoCopies, 0}},
+ {2450, {wxPrintData, getOrientation, 0}},
+ {2451, {wxPrintData, getPaperId, 0}},
+ {2452, {wxPrintData, getPrinterName, 0}},
+ {2453, {wxPrintData, getQuality, 0}},
+ {2454, {wxPrintData, isOk, 0}},
+ {2455, {wxPrintData, setBin, 1}},
+ {2456, {wxPrintData, setCollate, 1}},
+ {2457, {wxPrintData, setColour, 1}},
+ {2458, {wxPrintData, setDuplex, 1}},
+ {2459, {wxPrintData, setNoCopies, 1}},
+ {2460, {wxPrintData, setOrientation, 1}},
+ {2461, {wxPrintData, setPaperId, 1}},
+ {2462, {wxPrintData, setPrinterName, 1}},
+ {2463, {wxPrintData, setQuality, 1}},
+ {2466, {wxPrintPreview, new_2, 2}},
+ {2467, {wxPrintPreview, new_3, 3}},
+ {2469, {wxPrintPreview, destruct, 0}},
+ {2470, {wxPrintPreview, getCanvas, 0}},
+ {2471, {wxPrintPreview, getCurrentPage, 0}},
+ {2472, {wxPrintPreview, getFrame, 0}},
+ {2473, {wxPrintPreview, getMaxPage, 0}},
+ {2474, {wxPrintPreview, getMinPage, 0}},
+ {2475, {wxPrintPreview, getPrintout, 0}},
+ {2476, {wxPrintPreview, getPrintoutForPrinting, 0}},
+ {2477, {wxPrintPreview, isOk, 0}},
+ {2478, {wxPrintPreview, paintPage, 2}},
+ {2479, {wxPrintPreview, print, 1}},
+ {2480, {wxPrintPreview, renderPage, 1}},
+ {2481, {wxPrintPreview, setCanvas, 1}},
+ {2482, {wxPrintPreview, setCurrentPage, 1}},
+ {2483, {wxPrintPreview, setFrame, 1}},
+ {2484, {wxPrintPreview, setPrintout, 1}},
+ {2485, {wxPrintPreview, setZoom, 1}},
+ {2486, {wxPreviewFrame, new, 3}},
+ {2487, {wxPreviewFrame, destruct, 0}},
+ {2488, {wxPreviewFrame, createControlBar, 0}},
+ {2489, {wxPreviewFrame, createCanvas, 0}},
+ {2490, {wxPreviewFrame, initialize, 0}},
+ {2491, {wxPreviewFrame, onCloseWindow, 1}},
+ {2492, {wxPreviewControlBar, new, 4}},
+ {2493, {wxPreviewControlBar, destruct, 0}},
+ {2494, {wxPreviewControlBar, createButtons, 0}},
+ {2495, {wxPreviewControlBar, getPrintPreview, 0}},
+ {2496, {wxPreviewControlBar, getZoomControl, 0}},
+ {2497, {wxPreviewControlBar, setZoomControl, 1}},
+ {2499, {wxPrinter, new, 1}},
+ {2500, {wxPrinter, createAbortWindow, 2}},
+ {2501, {wxPrinter, getAbort, 0}},
+ {2502, {wxPrinter, getLastError, 0}},
+ {2503, {wxPrinter, getPrintDialogData, 0}},
+ {2504, {wxPrinter, print, 3}},
+ {2505, {wxPrinter, printDialog, 1}},
+ {2506, {wxPrinter, reportError, 3}},
+ {2507, {wxPrinter, setup, 1}},
+ {2508, {wxPrinter, 'Destroy', undefined}},
+ {2509, {wxXmlResource, new_1, 1}},
+ {2510, {wxXmlResource, new_2, 2}},
+ {2511, {wxXmlResource, destruct, 0}},
+ {2512, {wxXmlResource, attachUnknownControl, 3}},
+ {2513, {wxXmlResource, clearHandlers, 0}},
+ {2514, {wxXmlResource, compareVersion, 4}},
+ {2515, {wxXmlResource, get, 0}},
+ {2516, {wxXmlResource, getFlags, 0}},
+ {2517, {wxXmlResource, getVersion, 0}},
+ {2518, {wxXmlResource, getXRCID, 2}},
+ {2519, {wxXmlResource, initAllHandlers, 0}},
+ {2520, {wxXmlResource, load, 1}},
+ {2521, {wxXmlResource, loadBitmap, 1}},
+ {2522, {wxXmlResource, loadDialog_2, 2}},
+ {2523, {wxXmlResource, loadDialog_3, 3}},
+ {2524, {wxXmlResource, loadFrame_2, 2}},
+ {2525, {wxXmlResource, loadFrame_3, 3}},
+ {2526, {wxXmlResource, loadIcon, 1}},
+ {2527, {wxXmlResource, loadMenu, 1}},
+ {2528, {wxXmlResource, loadMenuBar_2, 2}},
+ {2529, {wxXmlResource, loadMenuBar_1, 1}},
+ {2530, {wxXmlResource, loadPanel_2, 2}},
+ {2531, {wxXmlResource, loadPanel_3, 3}},
+ {2532, {wxXmlResource, loadToolBar, 2}},
+ {2533, {wxXmlResource, set, 1}},
+ {2534, {wxXmlResource, setFlags, 1}},
+ {2535, {wxXmlResource, unload, 1}},
+ {2536, {wxXmlResource, xrcctrl, 3}},
+ {2537, {wxHtmlEasyPrinting, new, 1}},
+ {2538, {wxHtmlEasyPrinting, destruct, 0}},
+ {2539, {wxHtmlEasyPrinting, getPrintData, 0}},
+ {2540, {wxHtmlEasyPrinting, getPageSetupData, 0}},
+ {2541, {wxHtmlEasyPrinting, previewFile, 1}},
+ {2542, {wxHtmlEasyPrinting, previewText, 2}},
+ {2543, {wxHtmlEasyPrinting, printFile, 1}},
+ {2544, {wxHtmlEasyPrinting, printText, 2}},
+ {2545, {wxHtmlEasyPrinting, pageSetup, 0}},
+ {2546, {wxHtmlEasyPrinting, setFonts, 3}},
+ {2547, {wxHtmlEasyPrinting, setHeader, 2}},
+ {2548, {wxHtmlEasyPrinting, setFooter, 2}},
+ {2550, {wxGLCanvas, new_2, 2}},
+ {2551, {wxGLCanvas, new_3_1, 3}},
+ {2552, {wxGLCanvas, new_3_0, 3}},
+ {2553, {wxGLCanvas, getContext, 0}},
+ {2555, {wxGLCanvas, setCurrent, 0}},
+ {2556, {wxGLCanvas, swapBuffers, 0}},
+ {2557, {wxGLCanvas, 'Destroy', undefined}},
+ {2558, {wxAuiManager, new, 1}},
+ {2559, {wxAuiManager, destruct, 0}},
+ {2560, {wxAuiManager, addPane_2_1, 2}},
+ {2561, {wxAuiManager, addPane_3, 3}},
+ {2562, {wxAuiManager, addPane_2_0, 2}},
+ {2563, {wxAuiManager, detachPane, 1}},
+ {2564, {wxAuiManager, getAllPanes, 0}},
+ {2565, {wxAuiManager, getArtProvider, 0}},
+ {2566, {wxAuiManager, getDockSizeConstraint, 2}},
+ {2567, {wxAuiManager, getFlags, 0}},
+ {2568, {wxAuiManager, getManagedWindow, 0}},
+ {2569, {wxAuiManager, getManager, 1}},
+ {2570, {wxAuiManager, getPane_1_1, 1}},
+ {2571, {wxAuiManager, getPane_1_0, 1}},
+ {2572, {wxAuiManager, hideHint, 0}},
+ {2573, {wxAuiManager, insertPane, 3}},
+ {2574, {wxAuiManager, loadPaneInfo, 2}},
+ {2575, {wxAuiManager, loadPerspective, 2}},
+ {2576, {wxAuiManager, savePaneInfo, 1}},
+ {2577, {wxAuiManager, savePerspective, 0}},
+ {2578, {wxAuiManager, setArtProvider, 1}},
+ {2579, {wxAuiManager, setDockSizeConstraint, 2}},
+ {2580, {wxAuiManager, setFlags, 1}},
+ {2581, {wxAuiManager, setManagedWindow, 1}},
+ {2582, {wxAuiManager, showHint, 1}},
+ {2583, {wxAuiManager, unInit, 0}},
+ {2584, {wxAuiManager, update, 0}},
+ {2585, {wxAuiPaneInfo, new_0, 0}},
+ {2586, {wxAuiPaneInfo, new_1, 1}},
+ {2587, {wxAuiPaneInfo, destruct, 0}},
+ {2588, {wxAuiPaneInfo, bestSize_1, 1}},
+ {2589, {wxAuiPaneInfo, bestSize_2, 2}},
+ {2590, {wxAuiPaneInfo, bottom, 0}},
+ {2591, {wxAuiPaneInfo, bottomDockable, 1}},
+ {2592, {wxAuiPaneInfo, caption, 1}},
+ {2593, {wxAuiPaneInfo, captionVisible, 1}},
+ {2594, {wxAuiPaneInfo, centre, 0}},
+ {2595, {wxAuiPaneInfo, centrePane, 0}},
+ {2596, {wxAuiPaneInfo, closeButton, 1}},
+ {2597, {wxAuiPaneInfo, defaultPane, 0}},
+ {2598, {wxAuiPaneInfo, destroyOnClose, 1}},
+ {2599, {wxAuiPaneInfo, direction, 1}},
+ {2600, {wxAuiPaneInfo, dock, 0}},
+ {2601, {wxAuiPaneInfo, dockable, 1}},
+ {2602, {wxAuiPaneInfo, fixed, 0}},
+ {2603, {wxAuiPaneInfo, float, 0}},
+ {2604, {wxAuiPaneInfo, floatable, 1}},
+ {2605, {wxAuiPaneInfo, floatingPosition_1, 1}},
+ {2606, {wxAuiPaneInfo, floatingPosition_2, 2}},
+ {2607, {wxAuiPaneInfo, floatingSize_1, 1}},
+ {2608, {wxAuiPaneInfo, floatingSize_2, 2}},
+ {2609, {wxAuiPaneInfo, gripper, 1}},
+ {2610, {wxAuiPaneInfo, gripperTop, 1}},
+ {2611, {wxAuiPaneInfo, hasBorder, 0}},
+ {2612, {wxAuiPaneInfo, hasCaption, 0}},
+ {2613, {wxAuiPaneInfo, hasCloseButton, 0}},
+ {2614, {wxAuiPaneInfo, hasFlag, 1}},
+ {2615, {wxAuiPaneInfo, hasGripper, 0}},
+ {2616, {wxAuiPaneInfo, hasGripperTop, 0}},
+ {2617, {wxAuiPaneInfo, hasMaximizeButton, 0}},
+ {2618, {wxAuiPaneInfo, hasMinimizeButton, 0}},
+ {2619, {wxAuiPaneInfo, hasPinButton, 0}},
+ {2620, {wxAuiPaneInfo, hide, 0}},
+ {2621, {wxAuiPaneInfo, isBottomDockable, 0}},
+ {2622, {wxAuiPaneInfo, isDocked, 0}},
+ {2623, {wxAuiPaneInfo, isFixed, 0}},
+ {2624, {wxAuiPaneInfo, isFloatable, 0}},
+ {2625, {wxAuiPaneInfo, isFloating, 0}},
+ {2626, {wxAuiPaneInfo, isLeftDockable, 0}},
+ {2627, {wxAuiPaneInfo, isMovable, 0}},
+ {2628, {wxAuiPaneInfo, isOk, 0}},
+ {2629, {wxAuiPaneInfo, isResizable, 0}},
+ {2630, {wxAuiPaneInfo, isRightDockable, 0}},
+ {2631, {wxAuiPaneInfo, isShown, 0}},
+ {2632, {wxAuiPaneInfo, isToolbar, 0}},
+ {2633, {wxAuiPaneInfo, isTopDockable, 0}},
+ {2634, {wxAuiPaneInfo, layer, 1}},
+ {2635, {wxAuiPaneInfo, left, 0}},
+ {2636, {wxAuiPaneInfo, leftDockable, 1}},
+ {2637, {wxAuiPaneInfo, maxSize_1, 1}},
+ {2638, {wxAuiPaneInfo, maxSize_2, 2}},
+ {2639, {wxAuiPaneInfo, maximizeButton, 1}},
+ {2640, {wxAuiPaneInfo, minSize_1, 1}},
+ {2641, {wxAuiPaneInfo, minSize_2, 2}},
+ {2642, {wxAuiPaneInfo, minimizeButton, 1}},
+ {2643, {wxAuiPaneInfo, movable, 1}},
+ {2644, {wxAuiPaneInfo, name, 1}},
+ {2645, {wxAuiPaneInfo, paneBorder, 1}},
+ {2646, {wxAuiPaneInfo, pinButton, 1}},
+ {2647, {wxAuiPaneInfo, position, 1}},
+ {2648, {wxAuiPaneInfo, resizable, 1}},
+ {2649, {wxAuiPaneInfo, right, 0}},
+ {2650, {wxAuiPaneInfo, rightDockable, 1}},
+ {2651, {wxAuiPaneInfo, row, 1}},
+ {2652, {wxAuiPaneInfo, safeSet, 1}},
+ {2653, {wxAuiPaneInfo, setFlag, 2}},
+ {2654, {wxAuiPaneInfo, show, 1}},
+ {2655, {wxAuiPaneInfo, toolbarPane, 0}},
+ {2656, {wxAuiPaneInfo, top, 0}},
+ {2657, {wxAuiPaneInfo, topDockable, 1}},
+ {2658, {wxAuiPaneInfo, window, 1}},
+ {2659, {wxAuiPaneInfo, getWindow, 0}},
+ {2660, {wxAuiPaneInfo, getFrame, 0}},
+ {2661, {wxAuiPaneInfo, getDirection, 0}},
+ {2662, {wxAuiPaneInfo, getLayer, 0}},
+ {2663, {wxAuiPaneInfo, getRow, 0}},
+ {2664, {wxAuiPaneInfo, getPosition, 0}},
+ {2665, {wxAuiPaneInfo, getFloatingPosition, 0}},
+ {2666, {wxAuiPaneInfo, getFloatingSize, 0}},
+ {2667, {wxAuiNotebook, new_0, 0}},
+ {2668, {wxAuiNotebook, new_2, 2}},
+ {2669, {wxAuiNotebook, addPage, 3}},
+ {2670, {wxAuiNotebook, create, 2}},
+ {2671, {wxAuiNotebook, deletePage, 1}},
+ {2672, {wxAuiNotebook, getArtProvider, 0}},
+ {2673, {wxAuiNotebook, getPage, 1}},
+ {2674, {wxAuiNotebook, getPageBitmap, 1}},
+ {2675, {wxAuiNotebook, getPageCount, 0}},
+ {2676, {wxAuiNotebook, getPageIndex, 1}},
+ {2677, {wxAuiNotebook, getPageText, 1}},
+ {2678, {wxAuiNotebook, getSelection, 0}},
+ {2679, {wxAuiNotebook, insertPage, 4}},
+ {2680, {wxAuiNotebook, removePage, 1}},
+ {2681, {wxAuiNotebook, setArtProvider, 1}},
+ {2682, {wxAuiNotebook, setFont, 1}},
+ {2683, {wxAuiNotebook, setPageBitmap, 2}},
+ {2684, {wxAuiNotebook, setPageText, 2}},
+ {2685, {wxAuiNotebook, setSelection, 1}},
+ {2686, {wxAuiNotebook, setTabCtrlHeight, 1}},
+ {2687, {wxAuiNotebook, setUniformBitmapSize, 1}},
+ {2688, {wxAuiNotebook, 'Destroy', undefined}},
+ {2689, {wxAuiTabArt, setFlags, 1}},
+ {2690, {wxAuiTabArt, setMeasuringFont, 1}},
+ {2691, {wxAuiTabArt, setNormalFont, 1}},
+ {2692, {wxAuiTabArt, setSelectedFont, 1}},
+ {2693, {wxAuiTabArt, setColour, 1}},
+ {2694, {wxAuiTabArt, setActiveColour, 1}},
+ {2695, {wxAuiDockArt, getColour, 1}},
+ {2696, {wxAuiDockArt, getFont, 1}},
+ {2697, {wxAuiDockArt, getMetric, 1}},
+ {2698, {wxAuiDockArt, setColour, 2}},
+ {2699, {wxAuiDockArt, setFont, 2}},
+ {2700, {wxAuiDockArt, setMetric, 2}},
+ {2701, {wxAuiSimpleTabArt, new, 0}},
+ {2702, {wxAuiSimpleTabArt, 'Destroy', undefined}},
+ {2703, {wxMDIParentFrame, new_0, 0}},
+ {2704, {wxMDIParentFrame, new_4, 4}},
+ {2705, {wxMDIParentFrame, destruct, 0}},
+ {2706, {wxMDIParentFrame, activateNext, 0}},
+ {2707, {wxMDIParentFrame, activatePrevious, 0}},
+ {2708, {wxMDIParentFrame, arrangeIcons, 0}},
+ {2709, {wxMDIParentFrame, cascade, 0}},
+ {2710, {wxMDIParentFrame, create, 4}},
+ {2711, {wxMDIParentFrame, getActiveChild, 0}},
+ {2712, {wxMDIParentFrame, getClientWindow, 0}},
+ {2713, {wxMDIParentFrame, tile, 1}},
+ {2714, {wxMDIChildFrame, new_0, 0}},
+ {2715, {wxMDIChildFrame, new_4, 4}},
+ {2716, {wxMDIChildFrame, destruct, 0}},
+ {2717, {wxMDIChildFrame, activate, 0}},
+ {2718, {wxMDIChildFrame, create, 4}},
+ {2719, {wxMDIChildFrame, maximize, 1}},
+ {2720, {wxMDIChildFrame, restore, 0}},
+ {2721, {wxMDIClientWindow, new_0, 0}},
+ {2722, {wxMDIClientWindow, new_2, 2}},
+ {2723, {wxMDIClientWindow, destruct, 0}},
+ {2724, {wxMDIClientWindow, createClient, 2}},
+ {2725, {wxLayoutAlgorithm, new, 0}},
+ {2726, {wxLayoutAlgorithm, layoutFrame, 2}},
+ {2727, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
+ {2728, {wxLayoutAlgorithm, layoutWindow, 2}},
+ {2729, {wxLayoutAlgorithm, 'Destroy', undefined}},
+ {2730, {wxEvent, getId, 0}},
+ {2731, {wxEvent, getSkipped, 0}},
+ {2732, {wxEvent, getTimestamp, 0}},
+ {2733, {wxEvent, isCommandEvent, 0}},
+ {2734, {wxEvent, resumePropagation, 1}},
+ {2735, {wxEvent, shouldPropagate, 0}},
+ {2736, {wxEvent, skip, 1}},
+ {2737, {wxEvent, stopPropagation, 0}},
+ {2738, {wxCommandEvent, getClientData, 0}},
+ {2739, {wxCommandEvent, getExtraLong, 0}},
+ {2740, {wxCommandEvent, getInt, 0}},
+ {2741, {wxCommandEvent, getSelection, 0}},
+ {2742, {wxCommandEvent, getString, 0}},
+ {2743, {wxCommandEvent, isChecked, 0}},
+ {2744, {wxCommandEvent, isSelection, 0}},
+ {2745, {wxCommandEvent, setInt, 1}},
+ {2746, {wxCommandEvent, setString, 1}},
+ {2747, {wxScrollEvent, getOrientation, 0}},
+ {2748, {wxScrollEvent, getPosition, 0}},
+ {2749, {wxScrollWinEvent, getOrientation, 0}},
+ {2750, {wxScrollWinEvent, getPosition, 0}},
+ {2751, {wxMouseEvent, altDown, 0}},
+ {2752, {wxMouseEvent, button, 1}},
+ {2753, {wxMouseEvent, buttonDClick, 1}},
+ {2754, {wxMouseEvent, buttonDown, 1}},
+ {2755, {wxMouseEvent, buttonUp, 1}},
+ {2756, {wxMouseEvent, cmdDown, 0}},
+ {2757, {wxMouseEvent, controlDown, 0}},
+ {2758, {wxMouseEvent, dragging, 0}},
+ {2759, {wxMouseEvent, entering, 0}},
+ {2760, {wxMouseEvent, getButton, 0}},
+ {2763, {wxMouseEvent, getPosition, 0}},
+ {2764, {wxMouseEvent, getLogicalPosition, 1}},
+ {2765, {wxMouseEvent, getLinesPerAction, 0}},
+ {2766, {wxMouseEvent, getWheelRotation, 0}},
+ {2767, {wxMouseEvent, getWheelDelta, 0}},
+ {2768, {wxMouseEvent, getX, 0}},
+ {2769, {wxMouseEvent, getY, 0}},
+ {2770, {wxMouseEvent, isButton, 0}},
+ {2771, {wxMouseEvent, isPageScroll, 0}},
+ {2772, {wxMouseEvent, leaving, 0}},
+ {2773, {wxMouseEvent, leftDClick, 0}},
+ {2774, {wxMouseEvent, leftDown, 0}},
+ {2775, {wxMouseEvent, leftIsDown, 0}},
+ {2776, {wxMouseEvent, leftUp, 0}},
+ {2777, {wxMouseEvent, metaDown, 0}},
+ {2778, {wxMouseEvent, middleDClick, 0}},
+ {2779, {wxMouseEvent, middleDown, 0}},
+ {2780, {wxMouseEvent, middleIsDown, 0}},
+ {2781, {wxMouseEvent, middleUp, 0}},
+ {2782, {wxMouseEvent, moving, 0}},
+ {2783, {wxMouseEvent, rightDClick, 0}},
+ {2784, {wxMouseEvent, rightDown, 0}},
+ {2785, {wxMouseEvent, rightIsDown, 0}},
+ {2786, {wxMouseEvent, rightUp, 0}},
+ {2787, {wxMouseEvent, shiftDown, 0}},
+ {2788, {wxSetCursorEvent, getCursor, 0}},
+ {2789, {wxSetCursorEvent, getX, 0}},
+ {2790, {wxSetCursorEvent, getY, 0}},
+ {2791, {wxSetCursorEvent, hasCursor, 0}},
+ {2792, {wxSetCursorEvent, setCursor, 1}},
+ {2793, {wxKeyEvent, altDown, 0}},
+ {2794, {wxKeyEvent, cmdDown, 0}},
+ {2795, {wxKeyEvent, controlDown, 0}},
+ {2796, {wxKeyEvent, getKeyCode, 0}},
+ {2797, {wxKeyEvent, getModifiers, 0}},
+ {2800, {wxKeyEvent, getPosition, 0}},
+ {2801, {wxKeyEvent, getRawKeyCode, 0}},
+ {2802, {wxKeyEvent, getRawKeyFlags, 0}},
+ {2803, {wxKeyEvent, getUnicodeKey, 0}},
+ {2804, {wxKeyEvent, getX, 0}},
+ {2805, {wxKeyEvent, getY, 0}},
+ {2806, {wxKeyEvent, hasModifiers, 0}},
+ {2807, {wxKeyEvent, metaDown, 0}},
+ {2808, {wxKeyEvent, shiftDown, 0}},
+ {2809, {wxSizeEvent, getSize, 0}},
+ {2810, {wxMoveEvent, getPosition, 0}},
+ {2811, {wxEraseEvent, getDC, 0}},
+ {2812, {wxFocusEvent, getWindow, 0}},
+ {2813, {wxChildFocusEvent, getWindow, 0}},
+ {2814, {wxMenuEvent, getMenu, 0}},
+ {2815, {wxMenuEvent, getMenuId, 0}},
+ {2816, {wxMenuEvent, isPopup, 0}},
+ {2817, {wxCloseEvent, canVeto, 0}},
+ {2818, {wxCloseEvent, getLoggingOff, 0}},
+ {2819, {wxCloseEvent, setCanVeto, 1}},
+ {2820, {wxCloseEvent, setLoggingOff, 1}},
+ {2821, {wxCloseEvent, veto, 1}},
+ {2822, {wxShowEvent, setShow, 1}},
+ {2823, {wxShowEvent, getShow, 0}},
+ {2824, {wxIconizeEvent, iconized, 0}},
+ {2825, {wxJoystickEvent, buttonDown, 1}},
+ {2826, {wxJoystickEvent, buttonIsDown, 1}},
+ {2827, {wxJoystickEvent, buttonUp, 1}},
+ {2828, {wxJoystickEvent, getButtonChange, 0}},
+ {2829, {wxJoystickEvent, getButtonState, 0}},
+ {2830, {wxJoystickEvent, getJoystick, 0}},
+ {2831, {wxJoystickEvent, getPosition, 0}},
+ {2832, {wxJoystickEvent, getZPosition, 0}},
+ {2833, {wxJoystickEvent, isButton, 0}},
+ {2834, {wxJoystickEvent, isMove, 0}},
+ {2835, {wxJoystickEvent, isZMove, 0}},
+ {2836, {wxUpdateUIEvent, canUpdate, 1}},
+ {2837, {wxUpdateUIEvent, check, 1}},
+ {2838, {wxUpdateUIEvent, enable, 1}},
+ {2839, {wxUpdateUIEvent, show, 1}},
+ {2840, {wxUpdateUIEvent, getChecked, 0}},
+ {2841, {wxUpdateUIEvent, getEnabled, 0}},
+ {2842, {wxUpdateUIEvent, getShown, 0}},
+ {2843, {wxUpdateUIEvent, getSetChecked, 0}},
+ {2844, {wxUpdateUIEvent, getSetEnabled, 0}},
+ {2845, {wxUpdateUIEvent, getSetShown, 0}},
+ {2846, {wxUpdateUIEvent, getSetText, 0}},
+ {2847, {wxUpdateUIEvent, getText, 0}},
+ {2848, {wxUpdateUIEvent, getMode, 0}},
+ {2849, {wxUpdateUIEvent, getUpdateInterval, 0}},
+ {2850, {wxUpdateUIEvent, resetUpdateTime, 0}},
+ {2851, {wxUpdateUIEvent, setMode, 1}},
+ {2852, {wxUpdateUIEvent, setText, 1}},
+ {2853, {wxUpdateUIEvent, setUpdateInterval, 1}},
+ {2854, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
+ {2855, {wxPaletteChangedEvent, setChangedWindow, 1}},
+ {2856, {wxPaletteChangedEvent, getChangedWindow, 0}},
+ {2857, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
+ {2858, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
+ {2859, {wxNavigationKeyEvent, getDirection, 0}},
+ {2860, {wxNavigationKeyEvent, setDirection, 1}},
+ {2861, {wxNavigationKeyEvent, isWindowChange, 0}},
+ {2862, {wxNavigationKeyEvent, setWindowChange, 1}},
+ {2863, {wxNavigationKeyEvent, isFromTab, 0}},
+ {2864, {wxNavigationKeyEvent, setFromTab, 1}},
+ {2865, {wxNavigationKeyEvent, getCurrentFocus, 0}},
+ {2866, {wxNavigationKeyEvent, setCurrentFocus, 1}},
+ {2867, {wxHelpEvent, getOrigin, 0}},
+ {2868, {wxHelpEvent, getPosition, 0}},
+ {2869, {wxHelpEvent, setOrigin, 1}},
+ {2870, {wxHelpEvent, setPosition, 1}},
+ {2871, {wxContextMenuEvent, getPosition, 0}},
+ {2872, {wxContextMenuEvent, setPosition, 1}},
+ {2873, {wxIdleEvent, canSend, 1}},
+ {2874, {wxIdleEvent, getMode, 0}},
+ {2875, {wxIdleEvent, requestMore, 1}},
+ {2876, {wxIdleEvent, moreRequested, 0}},
+ {2877, {wxIdleEvent, setMode, 1}},
+ {2878, {wxGridEvent, altDown, 0}},
+ {2879, {wxGridEvent, controlDown, 0}},
+ {2880, {wxGridEvent, getCol, 0}},
+ {2881, {wxGridEvent, getPosition, 0}},
+ {2882, {wxGridEvent, getRow, 0}},
+ {2883, {wxGridEvent, metaDown, 0}},
+ {2884, {wxGridEvent, selecting, 0}},
+ {2885, {wxGridEvent, shiftDown, 0}},
+ {2886, {wxNotifyEvent, allow, 0}},
+ {2887, {wxNotifyEvent, isAllowed, 0}},
+ {2888, {wxNotifyEvent, veto, 0}},
+ {2889, {wxSashEvent, getEdge, 0}},
+ {2890, {wxSashEvent, getDragRect, 0}},
+ {2891, {wxSashEvent, getDragStatus, 0}},
+ {2892, {wxListEvent, getCacheFrom, 0}},
+ {2893, {wxListEvent, getCacheTo, 0}},
+ {2894, {wxListEvent, getKeyCode, 0}},
+ {2895, {wxListEvent, getIndex, 0}},
+ {2896, {wxListEvent, getColumn, 0}},
+ {2897, {wxListEvent, getPoint, 0}},
+ {2898, {wxListEvent, getLabel, 0}},
+ {2899, {wxListEvent, getText, 0}},
+ {2900, {wxListEvent, getImage, 0}},
+ {2901, {wxListEvent, getData, 0}},
+ {2902, {wxListEvent, getMask, 0}},
+ {2903, {wxListEvent, getItem, 0}},
+ {2904, {wxListEvent, isEditCancelled, 0}},
+ {2905, {wxDateEvent, getDate, 0}},
+ {2906, {wxCalendarEvent, getWeekDay, 0}},
+ {2907, {wxFileDirPickerEvent, getPath, 0}},
+ {2908, {wxColourPickerEvent, getColour, 0}},
+ {2909, {wxFontPickerEvent, getFont, 0}},
+ {2910, {wxStyledTextEvent, getPosition, 0}},
+ {2911, {wxStyledTextEvent, getKey, 0}},
+ {2912, {wxStyledTextEvent, getModifiers, 0}},
+ {2913, {wxStyledTextEvent, getModificationType, 0}},
+ {2914, {wxStyledTextEvent, getText, 0}},
+ {2915, {wxStyledTextEvent, getLength, 0}},
+ {2916, {wxStyledTextEvent, getLinesAdded, 0}},
+ {2917, {wxStyledTextEvent, getLine, 0}},
+ {2918, {wxStyledTextEvent, getFoldLevelNow, 0}},
+ {2919, {wxStyledTextEvent, getFoldLevelPrev, 0}},
+ {2920, {wxStyledTextEvent, getMargin, 0}},
+ {2921, {wxStyledTextEvent, getMessage, 0}},
+ {2922, {wxStyledTextEvent, getWParam, 0}},
+ {2923, {wxStyledTextEvent, getLParam, 0}},
+ {2924, {wxStyledTextEvent, getListType, 0}},
+ {2925, {wxStyledTextEvent, getX, 0}},
+ {2926, {wxStyledTextEvent, getY, 0}},
+ {2927, {wxStyledTextEvent, getDragText, 0}},
+ {2928, {wxStyledTextEvent, getDragAllowMove, 0}},
+ {2929, {wxStyledTextEvent, getDragResult, 0}},
+ {2930, {wxStyledTextEvent, getShift, 0}},
+ {2931, {wxStyledTextEvent, getControl, 0}},
+ {2932, {wxStyledTextEvent, getAlt, 0}},
+ {2933, {utils, getKeyState, 1}},
+ {2934, {utils, getMousePosition, 2}},
+ {2935, {utils, getMouseState, 0}},
+ {2936, {utils, setDetectableAutoRepeat, 1}},
+ {2937, {utils, bell, 0}},
+ {2938, {utils, findMenuItemId, 3}},
+ {2939, {utils, genericFindWindowAtPoint, 1}},
+ {2940, {utils, findWindowAtPoint, 1}},
+ {2941, {utils, beginBusyCursor, 1}},
+ {2942, {utils, endBusyCursor, 0}},
+ {2943, {utils, isBusy, 0}},
+ {2944, {utils, shutdown, 1}},
+ {2945, {utils, shell, 1}},
+ {2946, {utils, launchDefaultBrowser, 2}},
+ {2947, {utils, getEmailAddress, 0}},
+ {2948, {utils, getUserId, 0}},
+ {2949, {utils, getHomeDir, 0}},
+ {2950, {utils, newId, 0}},
+ {2951, {utils, registerId, 1}},
+ {2952, {utils, getCurrentId, 0}},
+ {2953, {utils, getOsDescription, 0}},
+ {2954, {utils, isPlatformLittleEndian, 0}},
+ {2955, {utils, isPlatform64Bit, 0}},
+ {2956, {gdicmn, displaySize, 2}},
+ {2957, {gdicmn, setCursor, 1}},
+ {2958, {wxPrintout, new, 1}},
+ {2959, {wxPrintout, destruct, 0}},
+ {2960, {wxPrintout, getDC, 0}},
+ {2961, {wxPrintout, getPageSizeMM, 2}},
+ {2962, {wxPrintout, getPageSizePixels, 2}},
+ {2963, {wxPrintout, getPaperRectPixels, 0}},
+ {2964, {wxPrintout, getPPIPrinter, 2}},
+ {2965, {wxPrintout, getPPIScreen, 2}},
+ {2966, {wxPrintout, getTitle, 0}},
+ {2967, {wxPrintout, isPreview, 0}},
+ {2968, {wxPrintout, fitThisSizeToPaper, 1}},
+ {2969, {wxPrintout, fitThisSizeToPage, 1}},
+ {2970, {wxPrintout, fitThisSizeToPageMargins, 2}},
+ {2971, {wxPrintout, mapScreenSizeToPaper, 0}},
+ {2972, {wxPrintout, mapScreenSizeToPage, 0}},
+ {2973, {wxPrintout, mapScreenSizeToPageMargins, 1}},
+ {2974, {wxPrintout, mapScreenSizeToDevice, 0}},
+ {2975, {wxPrintout, getLogicalPaperRect, 0}},
+ {2976, {wxPrintout, getLogicalPageRect, 0}},
+ {2977, {wxPrintout, getLogicalPageMarginsRect, 1}},
+ {2978, {wxPrintout, setLogicalOrigin, 2}},
+ {2979, {wxPrintout, offsetLogicalOrigin, 2}},
+ {2980, {wxStyledTextCtrl, new_2, 2}},
+ {2981, {wxStyledTextCtrl, new_0, 0}},
+ {2982, {wxStyledTextCtrl, destruct, 0}},
+ {2983, {wxStyledTextCtrl, create, 2}},
+ {2984, {wxStyledTextCtrl, addText, 1}},
+ {2985, {wxStyledTextCtrl, addStyledText, 1}},
+ {2986, {wxStyledTextCtrl, insertText, 2}},
+ {2987, {wxStyledTextCtrl, clearAll, 0}},
+ {2988, {wxStyledTextCtrl, clearDocumentStyle, 0}},
+ {2989, {wxStyledTextCtrl, getLength, 0}},
+ {2990, {wxStyledTextCtrl, getCharAt, 1}},
+ {2991, {wxStyledTextCtrl, getCurrentPos, 0}},
+ {2992, {wxStyledTextCtrl, getAnchor, 0}},
+ {2993, {wxStyledTextCtrl, getStyleAt, 1}},
+ {2994, {wxStyledTextCtrl, redo, 0}},
+ {2995, {wxStyledTextCtrl, setUndoCollection, 1}},
+ {2996, {wxStyledTextCtrl, selectAll, 0}},
+ {2997, {wxStyledTextCtrl, setSavePoint, 0}},
+ {2998, {wxStyledTextCtrl, getStyledText, 2}},
+ {2999, {wxStyledTextCtrl, canRedo, 0}},
+ {3000, {wxStyledTextCtrl, markerLineFromHandle, 1}},
+ {3001, {wxStyledTextCtrl, markerDeleteHandle, 1}},
+ {3002, {wxStyledTextCtrl, getUndoCollection, 0}},
+ {3003, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
+ {3004, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
+ {3005, {wxStyledTextCtrl, positionFromPoint, 1}},
+ {3006, {wxStyledTextCtrl, positionFromPointClose, 2}},
+ {3007, {wxStyledTextCtrl, gotoLine, 1}},
+ {3008, {wxStyledTextCtrl, gotoPos, 1}},
+ {3009, {wxStyledTextCtrl, setAnchor, 1}},
+ {3010, {wxStyledTextCtrl, getCurLine, 1}},
+ {3011, {wxStyledTextCtrl, getEndStyled, 0}},
+ {3012, {wxStyledTextCtrl, convertEOLs, 1}},
+ {3013, {wxStyledTextCtrl, getEOLMode, 0}},
+ {3014, {wxStyledTextCtrl, setEOLMode, 1}},
+ {3015, {wxStyledTextCtrl, startStyling, 2}},
+ {3016, {wxStyledTextCtrl, setStyling, 2}},
+ {3017, {wxStyledTextCtrl, getBufferedDraw, 0}},
+ {3018, {wxStyledTextCtrl, setBufferedDraw, 1}},
+ {3019, {wxStyledTextCtrl, setTabWidth, 1}},
+ {3020, {wxStyledTextCtrl, getTabWidth, 0}},
+ {3021, {wxStyledTextCtrl, setCodePage, 1}},
+ {3022, {wxStyledTextCtrl, markerDefine, 3}},
+ {3023, {wxStyledTextCtrl, markerSetForeground, 2}},
+ {3024, {wxStyledTextCtrl, markerSetBackground, 2}},
+ {3025, {wxStyledTextCtrl, markerAdd, 2}},
+ {3026, {wxStyledTextCtrl, markerDelete, 2}},
+ {3027, {wxStyledTextCtrl, markerDeleteAll, 1}},
+ {3028, {wxStyledTextCtrl, markerGet, 1}},
+ {3029, {wxStyledTextCtrl, markerNext, 2}},
+ {3030, {wxStyledTextCtrl, markerPrevious, 2}},
+ {3031, {wxStyledTextCtrl, markerDefineBitmap, 2}},
+ {3032, {wxStyledTextCtrl, markerAddSet, 2}},
+ {3033, {wxStyledTextCtrl, markerSetAlpha, 2}},
+ {3034, {wxStyledTextCtrl, setMarginType, 2}},
+ {3035, {wxStyledTextCtrl, getMarginType, 1}},
+ {3036, {wxStyledTextCtrl, setMarginWidth, 2}},
+ {3037, {wxStyledTextCtrl, getMarginWidth, 1}},
+ {3038, {wxStyledTextCtrl, setMarginMask, 2}},
+ {3039, {wxStyledTextCtrl, getMarginMask, 1}},
+ {3040, {wxStyledTextCtrl, setMarginSensitive, 2}},
+ {3041, {wxStyledTextCtrl, getMarginSensitive, 1}},
+ {3042, {wxStyledTextCtrl, styleClearAll, 0}},
+ {3043, {wxStyledTextCtrl, styleSetForeground, 2}},
+ {3044, {wxStyledTextCtrl, styleSetBackground, 2}},
+ {3045, {wxStyledTextCtrl, styleSetBold, 2}},
+ {3046, {wxStyledTextCtrl, styleSetItalic, 2}},
+ {3047, {wxStyledTextCtrl, styleSetSize, 2}},
+ {3048, {wxStyledTextCtrl, styleSetFaceName, 2}},
+ {3049, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
+ {3050, {wxStyledTextCtrl, styleResetDefault, 0}},
+ {3051, {wxStyledTextCtrl, styleSetUnderline, 2}},
+ {3052, {wxStyledTextCtrl, styleSetCase, 2}},
+ {3053, {wxStyledTextCtrl, styleSetHotSpot, 2}},
+ {3054, {wxStyledTextCtrl, setSelForeground, 2}},
+ {3055, {wxStyledTextCtrl, setSelBackground, 2}},
+ {3056, {wxStyledTextCtrl, getSelAlpha, 0}},
+ {3057, {wxStyledTextCtrl, setSelAlpha, 1}},
+ {3058, {wxStyledTextCtrl, setCaretForeground, 1}},
+ {3059, {wxStyledTextCtrl, cmdKeyAssign, 3}},
+ {3060, {wxStyledTextCtrl, cmdKeyClear, 2}},
+ {3061, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
+ {3062, {wxStyledTextCtrl, setStyleBytes, 2}},
+ {3063, {wxStyledTextCtrl, styleSetVisible, 2}},
+ {3064, {wxStyledTextCtrl, getCaretPeriod, 0}},
+ {3065, {wxStyledTextCtrl, setCaretPeriod, 1}},
+ {3066, {wxStyledTextCtrl, setWordChars, 1}},
+ {3067, {wxStyledTextCtrl, beginUndoAction, 0}},
+ {3068, {wxStyledTextCtrl, endUndoAction, 0}},
+ {3069, {wxStyledTextCtrl, indicatorSetStyle, 2}},
+ {3070, {wxStyledTextCtrl, indicatorGetStyle, 1}},
+ {3071, {wxStyledTextCtrl, indicatorSetForeground, 2}},
+ {3072, {wxStyledTextCtrl, indicatorGetForeground, 1}},
+ {3073, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
+ {3074, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
+ {3075, {wxStyledTextCtrl, getStyleBits, 0}},
+ {3076, {wxStyledTextCtrl, setLineState, 2}},
+ {3077, {wxStyledTextCtrl, getLineState, 1}},
+ {3078, {wxStyledTextCtrl, getMaxLineState, 0}},
+ {3079, {wxStyledTextCtrl, getCaretLineVisible, 0}},
+ {3080, {wxStyledTextCtrl, setCaretLineVisible, 1}},
+ {3081, {wxStyledTextCtrl, getCaretLineBackground, 0}},
+ {3082, {wxStyledTextCtrl, setCaretLineBackground, 1}},
+ {3083, {wxStyledTextCtrl, autoCompShow, 2}},
+ {3084, {wxStyledTextCtrl, autoCompCancel, 0}},
+ {3085, {wxStyledTextCtrl, autoCompActive, 0}},
+ {3086, {wxStyledTextCtrl, autoCompPosStart, 0}},
+ {3087, {wxStyledTextCtrl, autoCompComplete, 0}},
+ {3088, {wxStyledTextCtrl, autoCompStops, 1}},
+ {3089, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
+ {3090, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
+ {3091, {wxStyledTextCtrl, autoCompSelect, 1}},
+ {3092, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
+ {3093, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
+ {3094, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
+ {3095, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
+ {3096, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
+ {3097, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
+ {3098, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
+ {3099, {wxStyledTextCtrl, userListShow, 2}},
+ {3100, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
+ {3101, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
+ {3102, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
+ {3103, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
+ {3104, {wxStyledTextCtrl, registerImage, 2}},
+ {3105, {wxStyledTextCtrl, clearRegisteredImages, 0}},
+ {3106, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
+ {3107, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
+ {3108, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
+ {3109, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
+ {3110, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
+ {3111, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
+ {3112, {wxStyledTextCtrl, setIndent, 1}},
+ {3113, {wxStyledTextCtrl, getIndent, 0}},
+ {3114, {wxStyledTextCtrl, setUseTabs, 1}},
+ {3115, {wxStyledTextCtrl, getUseTabs, 0}},
+ {3116, {wxStyledTextCtrl, setLineIndentation, 2}},
+ {3117, {wxStyledTextCtrl, getLineIndentation, 1}},
+ {3118, {wxStyledTextCtrl, getLineIndentPosition, 1}},
+ {3119, {wxStyledTextCtrl, getColumn, 1}},
+ {3120, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
+ {3121, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
+ {3122, {wxStyledTextCtrl, setIndentationGuides, 1}},
+ {3123, {wxStyledTextCtrl, getIndentationGuides, 0}},
+ {3124, {wxStyledTextCtrl, setHighlightGuide, 1}},
+ {3125, {wxStyledTextCtrl, getHighlightGuide, 0}},
+ {3126, {wxStyledTextCtrl, getLineEndPosition, 1}},
+ {3127, {wxStyledTextCtrl, getCodePage, 0}},
+ {3128, {wxStyledTextCtrl, getCaretForeground, 0}},
+ {3129, {wxStyledTextCtrl, getReadOnly, 0}},
+ {3130, {wxStyledTextCtrl, setCurrentPos, 1}},
+ {3131, {wxStyledTextCtrl, setSelectionStart, 1}},
+ {3132, {wxStyledTextCtrl, getSelectionStart, 0}},
+ {3133, {wxStyledTextCtrl, setSelectionEnd, 1}},
+ {3134, {wxStyledTextCtrl, getSelectionEnd, 0}},
+ {3135, {wxStyledTextCtrl, setPrintMagnification, 1}},
+ {3136, {wxStyledTextCtrl, getPrintMagnification, 0}},
+ {3137, {wxStyledTextCtrl, setPrintColourMode, 1}},
+ {3138, {wxStyledTextCtrl, getPrintColourMode, 0}},
+ {3139, {wxStyledTextCtrl, findText, 4}},
+ {3140, {wxStyledTextCtrl, formatRange, 7}},
+ {3141, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
+ {3142, {wxStyledTextCtrl, getLine, 1}},
+ {3143, {wxStyledTextCtrl, getLineCount, 0}},
+ {3144, {wxStyledTextCtrl, setMarginLeft, 1}},
+ {3145, {wxStyledTextCtrl, getMarginLeft, 0}},
+ {3146, {wxStyledTextCtrl, setMarginRight, 1}},
+ {3147, {wxStyledTextCtrl, getMarginRight, 0}},
+ {3148, {wxStyledTextCtrl, getModify, 0}},
+ {3149, {wxStyledTextCtrl, setSelection, 2}},
+ {3150, {wxStyledTextCtrl, getSelectedText, 0}},
+ {3151, {wxStyledTextCtrl, getTextRange, 2}},
+ {3152, {wxStyledTextCtrl, hideSelection, 1}},
+ {3153, {wxStyledTextCtrl, lineFromPosition, 1}},
+ {3154, {wxStyledTextCtrl, positionFromLine, 1}},
+ {3155, {wxStyledTextCtrl, lineScroll, 2}},
+ {3156, {wxStyledTextCtrl, ensureCaretVisible, 0}},
+ {3157, {wxStyledTextCtrl, replaceSelection, 1}},
+ {3158, {wxStyledTextCtrl, setReadOnly, 1}},
+ {3159, {wxStyledTextCtrl, canPaste, 0}},
+ {3160, {wxStyledTextCtrl, canUndo, 0}},
+ {3161, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
+ {3162, {wxStyledTextCtrl, undo, 0}},
+ {3163, {wxStyledTextCtrl, cut, 0}},
+ {3164, {wxStyledTextCtrl, copy, 0}},
+ {3165, {wxStyledTextCtrl, paste, 0}},
+ {3166, {wxStyledTextCtrl, clear, 0}},
+ {3167, {wxStyledTextCtrl, setText, 1}},
+ {3168, {wxStyledTextCtrl, getText, 0}},
+ {3169, {wxStyledTextCtrl, getTextLength, 0}},
+ {3170, {wxStyledTextCtrl, getOvertype, 0}},
+ {3171, {wxStyledTextCtrl, setCaretWidth, 1}},
+ {3172, {wxStyledTextCtrl, getCaretWidth, 0}},
+ {3173, {wxStyledTextCtrl, setTargetStart, 1}},
+ {3174, {wxStyledTextCtrl, getTargetStart, 0}},
+ {3175, {wxStyledTextCtrl, setTargetEnd, 1}},
+ {3176, {wxStyledTextCtrl, getTargetEnd, 0}},
+ {3177, {wxStyledTextCtrl, replaceTarget, 1}},
+ {3178, {wxStyledTextCtrl, searchInTarget, 1}},
+ {3179, {wxStyledTextCtrl, setSearchFlags, 1}},
+ {3180, {wxStyledTextCtrl, getSearchFlags, 0}},
+ {3181, {wxStyledTextCtrl, callTipShow, 2}},
+ {3182, {wxStyledTextCtrl, callTipCancel, 0}},
+ {3183, {wxStyledTextCtrl, callTipActive, 0}},
+ {3184, {wxStyledTextCtrl, callTipPosAtStart, 0}},
+ {3185, {wxStyledTextCtrl, callTipSetHighlight, 2}},
+ {3186, {wxStyledTextCtrl, callTipSetBackground, 1}},
+ {3187, {wxStyledTextCtrl, callTipSetForeground, 1}},
+ {3188, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
+ {3189, {wxStyledTextCtrl, callTipUseStyle, 1}},
+ {3190, {wxStyledTextCtrl, visibleFromDocLine, 1}},
+ {3191, {wxStyledTextCtrl, docLineFromVisible, 1}},
+ {3192, {wxStyledTextCtrl, wrapCount, 1}},
+ {3193, {wxStyledTextCtrl, setFoldLevel, 2}},
+ {3194, {wxStyledTextCtrl, getFoldLevel, 1}},
+ {3195, {wxStyledTextCtrl, getLastChild, 2}},
+ {3196, {wxStyledTextCtrl, getFoldParent, 1}},
+ {3197, {wxStyledTextCtrl, showLines, 2}},
+ {3198, {wxStyledTextCtrl, hideLines, 2}},
+ {3199, {wxStyledTextCtrl, getLineVisible, 1}},
+ {3200, {wxStyledTextCtrl, setFoldExpanded, 2}},
+ {3201, {wxStyledTextCtrl, getFoldExpanded, 1}},
+ {3202, {wxStyledTextCtrl, toggleFold, 1}},
+ {3203, {wxStyledTextCtrl, ensureVisible, 1}},
+ {3204, {wxStyledTextCtrl, setFoldFlags, 1}},
+ {3205, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
+ {3206, {wxStyledTextCtrl, setTabIndents, 1}},
+ {3207, {wxStyledTextCtrl, getTabIndents, 0}},
+ {3208, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
+ {3209, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
+ {3210, {wxStyledTextCtrl, setMouseDwellTime, 1}},
+ {3211, {wxStyledTextCtrl, getMouseDwellTime, 0}},
+ {3212, {wxStyledTextCtrl, wordStartPosition, 2}},
+ {3213, {wxStyledTextCtrl, wordEndPosition, 2}},
+ {3214, {wxStyledTextCtrl, setWrapMode, 1}},
+ {3215, {wxStyledTextCtrl, getWrapMode, 0}},
+ {3216, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
+ {3217, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
+ {3218, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
+ {3219, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
+ {3220, {wxStyledTextCtrl, setWrapStartIndent, 1}},
+ {3221, {wxStyledTextCtrl, getWrapStartIndent, 0}},
+ {3222, {wxStyledTextCtrl, setLayoutCache, 1}},
+ {3223, {wxStyledTextCtrl, getLayoutCache, 0}},
+ {3224, {wxStyledTextCtrl, setScrollWidth, 1}},
+ {3225, {wxStyledTextCtrl, getScrollWidth, 0}},
+ {3226, {wxStyledTextCtrl, textWidth, 2}},
+ {3227, {wxStyledTextCtrl, getEndAtLastLine, 0}},
+ {3228, {wxStyledTextCtrl, textHeight, 1}},
+ {3229, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
+ {3230, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
+ {3231, {wxStyledTextCtrl, appendText, 1}},
+ {3232, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
+ {3233, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
+ {3234, {wxStyledTextCtrl, targetFromSelection, 0}},
+ {3235, {wxStyledTextCtrl, linesJoin, 0}},
+ {3236, {wxStyledTextCtrl, linesSplit, 1}},
+ {3237, {wxStyledTextCtrl, setFoldMarginColour, 2}},
+ {3238, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
+ {3239, {wxStyledTextCtrl, lineDown, 0}},
+ {3240, {wxStyledTextCtrl, lineDownExtend, 0}},
+ {3241, {wxStyledTextCtrl, lineUp, 0}},
+ {3242, {wxStyledTextCtrl, lineUpExtend, 0}},
+ {3243, {wxStyledTextCtrl, charLeft, 0}},
+ {3244, {wxStyledTextCtrl, charLeftExtend, 0}},
+ {3245, {wxStyledTextCtrl, charRight, 0}},
+ {3246, {wxStyledTextCtrl, charRightExtend, 0}},
+ {3247, {wxStyledTextCtrl, wordLeft, 0}},
+ {3248, {wxStyledTextCtrl, wordLeftExtend, 0}},
+ {3249, {wxStyledTextCtrl, wordRight, 0}},
+ {3250, {wxStyledTextCtrl, wordRightExtend, 0}},
+ {3251, {wxStyledTextCtrl, home, 0}},
+ {3252, {wxStyledTextCtrl, homeExtend, 0}},
+ {3253, {wxStyledTextCtrl, lineEnd, 0}},
+ {3254, {wxStyledTextCtrl, lineEndExtend, 0}},
+ {3255, {wxStyledTextCtrl, documentStart, 0}},
+ {3256, {wxStyledTextCtrl, documentStartExtend, 0}},
+ {3257, {wxStyledTextCtrl, documentEnd, 0}},
+ {3258, {wxStyledTextCtrl, documentEndExtend, 0}},
+ {3259, {wxStyledTextCtrl, pageUp, 0}},
+ {3260, {wxStyledTextCtrl, pageUpExtend, 0}},
+ {3261, {wxStyledTextCtrl, pageDown, 0}},
+ {3262, {wxStyledTextCtrl, pageDownExtend, 0}},
+ {3263, {wxStyledTextCtrl, editToggleOvertype, 0}},
+ {3264, {wxStyledTextCtrl, cancel, 0}},
+ {3265, {wxStyledTextCtrl, deleteBack, 0}},
+ {3266, {wxStyledTextCtrl, tab, 0}},
+ {3267, {wxStyledTextCtrl, backTab, 0}},
+ {3268, {wxStyledTextCtrl, newLine, 0}},
+ {3269, {wxStyledTextCtrl, formFeed, 0}},
+ {3270, {wxStyledTextCtrl, vCHome, 0}},
+ {3271, {wxStyledTextCtrl, vCHomeExtend, 0}},
+ {3272, {wxStyledTextCtrl, zoomIn, 0}},
+ {3273, {wxStyledTextCtrl, zoomOut, 0}},
+ {3274, {wxStyledTextCtrl, delWordLeft, 0}},
+ {3275, {wxStyledTextCtrl, delWordRight, 0}},
+ {3276, {wxStyledTextCtrl, lineCut, 0}},
+ {3277, {wxStyledTextCtrl, lineDelete, 0}},
+ {3278, {wxStyledTextCtrl, lineTranspose, 0}},
+ {3279, {wxStyledTextCtrl, lineDuplicate, 0}},
+ {3280, {wxStyledTextCtrl, lowerCase, 0}},
+ {3281, {wxStyledTextCtrl, upperCase, 0}},
+ {3282, {wxStyledTextCtrl, lineScrollDown, 0}},
+ {3283, {wxStyledTextCtrl, lineScrollUp, 0}},
+ {3284, {wxStyledTextCtrl, deleteBackNotLine, 0}},
+ {3285, {wxStyledTextCtrl, homeDisplay, 0}},
+ {3286, {wxStyledTextCtrl, homeDisplayExtend, 0}},
+ {3287, {wxStyledTextCtrl, lineEndDisplay, 0}},
+ {3288, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
+ {3289, {wxStyledTextCtrl, homeWrapExtend, 0}},
+ {3290, {wxStyledTextCtrl, lineEndWrap, 0}},
+ {3291, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
+ {3292, {wxStyledTextCtrl, vCHomeWrap, 0}},
+ {3293, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
+ {3294, {wxStyledTextCtrl, lineCopy, 0}},
+ {3295, {wxStyledTextCtrl, moveCaretInsideView, 0}},
+ {3296, {wxStyledTextCtrl, lineLength, 1}},
+ {3297, {wxStyledTextCtrl, braceHighlight, 2}},
+ {3298, {wxStyledTextCtrl, braceBadLight, 1}},
+ {3299, {wxStyledTextCtrl, braceMatch, 1}},
+ {3300, {wxStyledTextCtrl, getViewEOL, 0}},
+ {3301, {wxStyledTextCtrl, setViewEOL, 1}},
+ {3302, {wxStyledTextCtrl, setModEventMask, 1}},
+ {3303, {wxStyledTextCtrl, getEdgeColumn, 0}},
+ {3304, {wxStyledTextCtrl, setEdgeColumn, 1}},
+ {3305, {wxStyledTextCtrl, setEdgeMode, 1}},
+ {3306, {wxStyledTextCtrl, getEdgeMode, 0}},
+ {3307, {wxStyledTextCtrl, getEdgeColour, 0}},
+ {3308, {wxStyledTextCtrl, setEdgeColour, 1}},
+ {3309, {wxStyledTextCtrl, searchAnchor, 0}},
+ {3310, {wxStyledTextCtrl, searchNext, 2}},
+ {3311, {wxStyledTextCtrl, searchPrev, 2}},
+ {3312, {wxStyledTextCtrl, linesOnScreen, 0}},
+ {3313, {wxStyledTextCtrl, usePopUp, 1}},
+ {3314, {wxStyledTextCtrl, selectionIsRectangle, 0}},
+ {3315, {wxStyledTextCtrl, setZoom, 1}},
+ {3316, {wxStyledTextCtrl, getZoom, 0}},
+ {3317, {wxStyledTextCtrl, getModEventMask, 0}},
+ {3318, {wxStyledTextCtrl, setSTCFocus, 1}},
+ {3319, {wxStyledTextCtrl, getSTCFocus, 0}},
+ {3320, {wxStyledTextCtrl, setStatus, 1}},
+ {3321, {wxStyledTextCtrl, getStatus, 0}},
+ {3322, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
+ {3323, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
+ {3324, {wxStyledTextCtrl, setSTCCursor, 1}},
+ {3325, {wxStyledTextCtrl, getSTCCursor, 0}},
+ {3326, {wxStyledTextCtrl, setControlCharSymbol, 1}},
+ {3327, {wxStyledTextCtrl, getControlCharSymbol, 0}},
+ {3328, {wxStyledTextCtrl, wordPartLeft, 0}},
+ {3329, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
+ {3330, {wxStyledTextCtrl, wordPartRight, 0}},
+ {3331, {wxStyledTextCtrl, wordPartRightExtend, 0}},
+ {3332, {wxStyledTextCtrl, setVisiblePolicy, 2}},
+ {3333, {wxStyledTextCtrl, delLineLeft, 0}},
+ {3334, {wxStyledTextCtrl, delLineRight, 0}},
+ {3335, {wxStyledTextCtrl, getXOffset, 0}},
+ {3336, {wxStyledTextCtrl, chooseCaretX, 0}},
+ {3337, {wxStyledTextCtrl, setXCaretPolicy, 2}},
+ {3338, {wxStyledTextCtrl, setYCaretPolicy, 2}},
+ {3339, {wxStyledTextCtrl, getPrintWrapMode, 0}},
+ {3340, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
+ {3341, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
+ {3342, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
+ {3343, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
+ {3344, {wxStyledTextCtrl, paraDownExtend, 0}},
+ {3345, {wxStyledTextCtrl, paraUp, 0}},
+ {3346, {wxStyledTextCtrl, paraUpExtend, 0}},
+ {3347, {wxStyledTextCtrl, positionBefore, 1}},
+ {3348, {wxStyledTextCtrl, positionAfter, 1}},
+ {3349, {wxStyledTextCtrl, copyRange, 2}},
+ {3350, {wxStyledTextCtrl, copyText, 2}},
+ {3351, {wxStyledTextCtrl, setSelectionMode, 1}},
+ {3352, {wxStyledTextCtrl, getSelectionMode, 0}},
+ {3353, {wxStyledTextCtrl, lineDownRectExtend, 0}},
+ {3354, {wxStyledTextCtrl, lineUpRectExtend, 0}},
+ {3355, {wxStyledTextCtrl, charLeftRectExtend, 0}},
+ {3356, {wxStyledTextCtrl, charRightRectExtend, 0}},
+ {3357, {wxStyledTextCtrl, homeRectExtend, 0}},
+ {3358, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
+ {3359, {wxStyledTextCtrl, lineEndRectExtend, 0}},
+ {3360, {wxStyledTextCtrl, pageUpRectExtend, 0}},
+ {3361, {wxStyledTextCtrl, pageDownRectExtend, 0}},
+ {3362, {wxStyledTextCtrl, stutteredPageUp, 0}},
+ {3363, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
+ {3364, {wxStyledTextCtrl, stutteredPageDown, 0}},
+ {3365, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
+ {3366, {wxStyledTextCtrl, wordLeftEnd, 0}},
+ {3367, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
+ {3368, {wxStyledTextCtrl, wordRightEnd, 0}},
+ {3369, {wxStyledTextCtrl, wordRightEndExtend, 0}},
+ {3370, {wxStyledTextCtrl, setWhitespaceChars, 1}},
+ {3371, {wxStyledTextCtrl, setCharsDefault, 0}},
+ {3372, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
+ {3373, {wxStyledTextCtrl, allocate, 1}},
+ {3374, {wxStyledTextCtrl, findColumn, 2}},
+ {3375, {wxStyledTextCtrl, getCaretSticky, 0}},
+ {3376, {wxStyledTextCtrl, setCaretSticky, 1}},
+ {3377, {wxStyledTextCtrl, toggleCaretSticky, 0}},
+ {3378, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
+ {3379, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
+ {3380, {wxStyledTextCtrl, selectionDuplicate, 0}},
+ {3381, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
+ {3382, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
+ {3383, {wxStyledTextCtrl, startRecord, 0}},
+ {3384, {wxStyledTextCtrl, stopRecord, 0}},
+ {3385, {wxStyledTextCtrl, setLexer, 1}},
+ {3386, {wxStyledTextCtrl, getLexer, 0}},
+ {3387, {wxStyledTextCtrl, colourise, 2}},
+ {3388, {wxStyledTextCtrl, setProperty, 2}},
+ {3389, {wxStyledTextCtrl, setKeyWords, 2}},
+ {3390, {wxStyledTextCtrl, setLexerLanguage, 1}},
+ {3391, {wxStyledTextCtrl, getProperty, 1}},
+ {3392, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
+ {3393, {wxStyledTextCtrl, getCurrentLine, 0}},
+ {3394, {wxStyledTextCtrl, styleSetSpec, 2}},
+ {3395, {wxStyledTextCtrl, styleSetFont, 2}},
+ {3396, {wxStyledTextCtrl, styleSetFontAttr, 7}},
+ {3397, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
+ {3398, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
+ {3399, {wxStyledTextCtrl, cmdKeyExecute, 1}},
+ {3400, {wxStyledTextCtrl, setMargins, 2}},
+ {3401, {wxStyledTextCtrl, getSelection, 2}},
+ {3402, {wxStyledTextCtrl, pointFromPosition, 1}},
+ {3403, {wxStyledTextCtrl, scrollToLine, 1}},
+ {3404, {wxStyledTextCtrl, scrollToColumn, 1}},
+ {3405, {wxStyledTextCtrl, setVScrollBar, 1}},
+ {3406, {wxStyledTextCtrl, setHScrollBar, 1}},
+ {3407, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
+ {3408, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
+ {3409, {wxStyledTextCtrl, saveFile, 1}},
+ {3410, {wxStyledTextCtrl, loadFile, 1}},
+ {3411, {wxStyledTextCtrl, doDragOver, 3}},
+ {3412, {wxStyledTextCtrl, doDropText, 3}},
+ {3413, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
+ {3414, {wxStyledTextCtrl, addTextRaw, 1}},
+ {3415, {wxStyledTextCtrl, insertTextRaw, 2}},
+ {3416, {wxStyledTextCtrl, getCurLineRaw, 1}},
+ {3417, {wxStyledTextCtrl, getLineRaw, 1}},
+ {3418, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
+ {3419, {wxStyledTextCtrl, getTextRangeRaw, 2}},
+ {3420, {wxStyledTextCtrl, setTextRaw, 1}},
+ {3421, {wxStyledTextCtrl, getTextRaw, 0}},
+ {3422, {wxStyledTextCtrl, appendTextRaw, 1}},
+ {3423, {wxArtProvider, getBitmap, 2}},
+ {3424, {wxArtProvider, getIcon, 2}},
+ {3425, {wxTreeEvent, getKeyCode, 0}},
+ {3426, {wxTreeEvent, getItem, 0}},
+ {3427, {wxTreeEvent, getKeyEvent, 0}},
+ {3428, {wxTreeEvent, getLabel, 0}},
+ {3429, {wxTreeEvent, getOldItem, 0}},
+ {3430, {wxTreeEvent, getPoint, 0}},
+ {3431, {wxTreeEvent, isEditCancelled, 0}},
+ {3432, {wxTreeEvent, setToolTip, 1}},
+ {3433, {wxNotebookEvent, getOldSelection, 0}},
+ {3434, {wxNotebookEvent, getSelection, 0}},
+ {3435, {wxNotebookEvent, setOldSelection, 1}},
+ {3436, {wxNotebookEvent, setSelection, 1}},
+ {3437, {wxFileDataObject, new, 0}},
+ {3438, {wxFileDataObject, addFile, 1}},
+ {3439, {wxFileDataObject, getFilenames, 0}},
+ {3440, {wxFileDataObject, 'Destroy', undefined}},
+ {3441, {wxTextDataObject, new, 1}},
+ {3442, {wxTextDataObject, getTextLength, 0}},
+ {3443, {wxTextDataObject, getText, 0}},
+ {3444, {wxTextDataObject, setText, 1}},
+ {3445, {wxTextDataObject, 'Destroy', undefined}},
+ {3446, {wxBitmapDataObject, new_1_1, 1}},
+ {3447, {wxBitmapDataObject, new_1_0, 1}},
+ {3448, {wxBitmapDataObject, getBitmap, 0}},
+ {3449, {wxBitmapDataObject, setBitmap, 1}},
+ {3450, {wxBitmapDataObject, 'Destroy', undefined}},
+ {3452, {wxClipboard, new, 0}},
+ {3453, {wxClipboard, destruct, 0}},
+ {3454, {wxClipboard, addData, 1}},
+ {3455, {wxClipboard, clear, 0}},
+ {3456, {wxClipboard, close, 0}},
+ {3457, {wxClipboard, flush, 0}},
+ {3458, {wxClipboard, getData, 1}},
+ {3459, {wxClipboard, isOpened, 0}},
+ {3460, {wxClipboard, open, 0}},
+ {3461, {wxClipboard, setData, 1}},
+ {3463, {wxClipboard, usePrimarySelection, 1}},
+ {3464, {wxClipboard, isSupported, 1}},
+ {3465, {wxClipboard, get, 0}},
+ {3466, {wxSpinEvent, getPosition, 0}},
+ {3467, {wxSpinEvent, setPosition, 1}},
+ {3468, {wxSplitterWindow, new_0, 0}},
+ {3469, {wxSplitterWindow, new_2, 2}},
+ {3470, {wxSplitterWindow, destruct, 0}},
+ {3471, {wxSplitterWindow, create, 2}},
+ {3472, {wxSplitterWindow, getMinimumPaneSize, 0}},
+ {3473, {wxSplitterWindow, getSashGravity, 0}},
+ {3474, {wxSplitterWindow, getSashPosition, 0}},
+ {3475, {wxSplitterWindow, getSplitMode, 0}},
+ {3476, {wxSplitterWindow, getWindow1, 0}},
+ {3477, {wxSplitterWindow, getWindow2, 0}},
+ {3478, {wxSplitterWindow, initialize, 1}},
+ {3479, {wxSplitterWindow, isSplit, 0}},
+ {3480, {wxSplitterWindow, replaceWindow, 2}},
+ {3481, {wxSplitterWindow, setSashGravity, 1}},
+ {3482, {wxSplitterWindow, setSashPosition, 2}},
+ {3483, {wxSplitterWindow, setSashSize, 1}},
+ {3484, {wxSplitterWindow, setMinimumPaneSize, 1}},
+ {3485, {wxSplitterWindow, setSplitMode, 1}},
+ {3486, {wxSplitterWindow, splitHorizontally, 3}},
+ {3487, {wxSplitterWindow, splitVertically, 3}},
+ {3488, {wxSplitterWindow, unsplit, 1}},
+ {3489, {wxSplitterWindow, updateSize, 0}},
+ {3490, {wxSplitterEvent, getSashPosition, 0}},
+ {3491, {wxSplitterEvent, getX, 0}},
+ {3492, {wxSplitterEvent, getY, 0}},
+ {3493, {wxSplitterEvent, getWindowBeingRemoved, 0}},
+ {3494, {wxSplitterEvent, setSashPosition, 1}},
+ {3495, {wxHtmlWindow, new_0, 0}},
+ {3496, {wxHtmlWindow, new_2, 2}},
+ {3497, {wxHtmlWindow, appendToPage, 1}},
+ {3498, {wxHtmlWindow, getOpenedAnchor, 0}},
+ {3499, {wxHtmlWindow, getOpenedPage, 0}},
+ {3500, {wxHtmlWindow, getOpenedPageTitle, 0}},
+ {3501, {wxHtmlWindow, getRelatedFrame, 0}},
+ {3502, {wxHtmlWindow, historyBack, 0}},
+ {3503, {wxHtmlWindow, historyCanBack, 0}},
+ {3504, {wxHtmlWindow, historyCanForward, 0}},
+ {3505, {wxHtmlWindow, historyClear, 0}},
+ {3506, {wxHtmlWindow, historyForward, 0}},
+ {3507, {wxHtmlWindow, loadFile, 1}},
+ {3508, {wxHtmlWindow, loadPage, 1}},
+ {3509, {wxHtmlWindow, selectAll, 0}},
+ {3510, {wxHtmlWindow, selectionToText, 0}},
+ {3511, {wxHtmlWindow, selectLine, 1}},
+ {3512, {wxHtmlWindow, selectWord, 1}},
+ {3513, {wxHtmlWindow, setBorders, 1}},
+ {3514, {wxHtmlWindow, setFonts, 3}},
+ {3515, {wxHtmlWindow, setPage, 1}},
+ {3516, {wxHtmlWindow, setRelatedFrame, 2}},
+ {3517, {wxHtmlWindow, setRelatedStatusBar, 1}},
+ {3518, {wxHtmlWindow, toText, 0}},
+ {3519, {wxHtmlWindow, 'Destroy', undefined}},
+ {3520, {wxHtmlLinkEvent, getLinkInfo, 0}},
+ {3521, {wxSystemSettings, getColour, 1}},
+ {3522, {wxSystemSettings, getFont, 1}},
+ {3523, {wxSystemSettings, getMetric, 2}},
+ {3524, {wxSystemSettings, getScreenType, 0}},
+ {3525, {wxSystemOptions, getOption, 1}},
+ {3526, {wxSystemOptions, getOptionInt, 1}},
+ {3527, {wxSystemOptions, hasOption, 1}},
+ {3528, {wxSystemOptions, isFalse, 1}},
+ {3529, {wxSystemOptions, setOption_2_1, 2}},
+ {3530, {wxSystemOptions, setOption_2_0, 2}},
+ {3531, {wxAuiNotebookEvent, setSelection, 1}},
+ {3532, {wxAuiNotebookEvent, getSelection, 0}},
+ {3533, {wxAuiNotebookEvent, setOldSelection, 1}},
+ {3534, {wxAuiNotebookEvent, getOldSelection, 0}},
+ {3535, {wxAuiNotebookEvent, setDragSource, 1}},
+ {3536, {wxAuiNotebookEvent, getDragSource, 0}},
+ {3537, {wxAuiManagerEvent, setManager, 1}},
+ {3538, {wxAuiManagerEvent, getManager, 0}},
+ {3539, {wxAuiManagerEvent, setPane, 1}},
+ {3540, {wxAuiManagerEvent, getPane, 0}},
+ {3541, {wxAuiManagerEvent, setButton, 1}},
+ {3542, {wxAuiManagerEvent, getButton, 0}},
+ {3543, {wxAuiManagerEvent, setDC, 1}},
+ {3544, {wxAuiManagerEvent, getDC, 0}},
+ {3545, {wxAuiManagerEvent, veto, 1}},
+ {3546, {wxAuiManagerEvent, getVeto, 0}},
+ {3547, {wxAuiManagerEvent, setCanVeto, 1}},
+ {3548, {wxAuiManagerEvent, canVeto, 0}},
+ {3549, {wxLogNull, new, 0}},
+ {3550, {wxLogNull, 'Destroy', undefined}},
+ {3551, {wxTaskBarIcon, new, 0}},
+ {3552, {wxTaskBarIcon, destruct, 0}},
+ {3553, {wxTaskBarIcon, popupMenu, 1}},
+ {3554, {wxTaskBarIcon, removeIcon, 0}},
+ {3555, {wxTaskBarIcon, setIcon, 2}},
+ {3556, {wxLocale, new_0, 0}},
+ {3558, {wxLocale, new_2, 2}},
+ {3559, {wxLocale, destruct, 0}},
+ {3561, {wxLocale, init, 1}},
+ {3562, {wxLocale, addCatalog_1, 1}},
+ {3563, {wxLocale, addCatalog_3, 3}},
+ {3564, {wxLocale, addCatalogLookupPathPrefix, 1}},
+ {3565, {wxLocale, getCanonicalName, 0}},
+ {3566, {wxLocale, getLanguage, 0}},
+ {3567, {wxLocale, getLanguageName, 1}},
+ {3568, {wxLocale, getLocale, 0}},
+ {3569, {wxLocale, getName, 0}},
+ {3570, {wxLocale, getString_2, 2}},
+ {3571, {wxLocale, getString_4, 4}},
+ {3572, {wxLocale, getHeaderValue, 2}},
+ {3573, {wxLocale, getSysName, 0}},
+ {3574, {wxLocale, getSystemEncoding, 0}},
+ {3575, {wxLocale, getSystemEncodingName, 0}},
+ {3576, {wxLocale, getSystemLanguage, 0}},
+ {3577, {wxLocale, isLoaded, 1}},
+ {3578, {wxLocale, isOk, 0}},
+ {3579, {wxActivateEvent, getActive, 0}},
+ {3581, {wxPopupWindow, new_2, 2}},
+ {3582, {wxPopupWindow, new_0, 0}},
+ {3584, {wxPopupWindow, destruct, 0}},
+ {3585, {wxPopupWindow, create, 2}},
+ {3586, {wxPopupWindow, position, 2}},
+ {3587, {wxPopupTransientWindow, new_0, 0}},
+ {3588, {wxPopupTransientWindow, new_2, 2}},
+ {3589, {wxPopupTransientWindow, destruct, 0}},
+ {3590, {wxPopupTransientWindow, popup, 1}},
+ {3591, {wxPopupTransientWindow, dismiss, 0}},
+ {3592, {wxOverlay, new, 0}},
+ {3593, {wxOverlay, destruct, 0}},
+ {3594, {wxOverlay, reset, 0}},
+ {3595, {wxDCOverlay, new_6, 6}},
+ {3596, {wxDCOverlay, new_2, 2}},
+ {3597, {wxDCOverlay, destruct, 0}},
+ {3598, {wxDCOverlay, clear, 0}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index 82d0d265d7..f5f839ac67 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%% This file is generated DO NOT EDIT
@@ -188,3152 +189,3187 @@
-define(wxWindow_UpdateWindowUI, 281).
-define(wxWindow_Validate, 282).
-define(wxWindow_WarpPointer, 283).
--define(wxTopLevelWindow_GetIcon, 284).
--define(wxTopLevelWindow_GetIcons, 285).
--define(wxTopLevelWindow_GetTitle, 286).
--define(wxTopLevelWindow_IsActive, 287).
--define(wxTopLevelWindow_Iconize, 288).
--define(wxTopLevelWindow_IsFullScreen, 289).
--define(wxTopLevelWindow_IsIconized, 290).
--define(wxTopLevelWindow_IsMaximized, 291).
--define(wxTopLevelWindow_Maximize, 292).
--define(wxTopLevelWindow_RequestUserAttention, 293).
--define(wxTopLevelWindow_SetIcon, 294).
--define(wxTopLevelWindow_SetIcons, 295).
--define(wxTopLevelWindow_CenterOnScreen, 296).
--define(wxTopLevelWindow_CentreOnScreen, 297).
--define(wxTopLevelWindow_SetShape, 299).
--define(wxTopLevelWindow_SetTitle, 300).
--define(wxTopLevelWindow_ShowFullScreen, 301).
--define(wxFrame_new_4, 303).
--define(wxFrame_new_0, 304).
--define(wxFrame_destruct, 306).
--define(wxFrame_Create, 307).
--define(wxFrame_CreateStatusBar, 308).
--define(wxFrame_CreateToolBar, 309).
--define(wxFrame_GetClientAreaOrigin, 310).
--define(wxFrame_GetMenuBar, 311).
--define(wxFrame_GetStatusBar, 312).
--define(wxFrame_GetStatusBarPane, 313).
--define(wxFrame_GetToolBar, 314).
--define(wxFrame_ProcessCommand, 315).
--define(wxFrame_SendSizeEvent, 316).
--define(wxFrame_SetMenuBar, 317).
--define(wxFrame_SetStatusBar, 318).
--define(wxFrame_SetStatusBarPane, 319).
--define(wxFrame_SetStatusText, 320).
--define(wxFrame_SetStatusWidths, 321).
--define(wxFrame_SetToolBar, 322).
--define(wxMiniFrame_new_0, 323).
--define(wxMiniFrame_new_4, 324).
--define(wxMiniFrame_Create, 325).
--define(wxMiniFrame_destroy, 326).
--define(wxSplashScreen_new_0, 327).
--define(wxSplashScreen_new_6, 328).
--define(wxSplashScreen_destruct, 329).
--define(wxSplashScreen_GetSplashStyle, 330).
--define(wxSplashScreen_GetTimeout, 331).
--define(wxPanel_new_0, 332).
--define(wxPanel_new_6, 333).
--define(wxPanel_new_2, 334).
--define(wxPanel_destruct, 335).
--define(wxPanel_InitDialog, 336).
--define(wxPanel_SetFocusIgnoringChildren, 337).
--define(wxScrolledWindow_new_0, 338).
--define(wxScrolledWindow_new_2, 339).
--define(wxScrolledWindow_destruct, 340).
--define(wxScrolledWindow_CalcScrolledPosition_4, 341).
--define(wxScrolledWindow_CalcScrolledPosition_1, 342).
--define(wxScrolledWindow_CalcUnscrolledPosition_4, 343).
--define(wxScrolledWindow_CalcUnscrolledPosition_1, 344).
--define(wxScrolledWindow_EnableScrolling, 345).
--define(wxScrolledWindow_GetScrollPixelsPerUnit, 346).
--define(wxScrolledWindow_GetViewStart, 347).
--define(wxScrolledWindow_DoPrepareDC, 348).
--define(wxScrolledWindow_PrepareDC, 349).
--define(wxScrolledWindow_Scroll, 350).
--define(wxScrolledWindow_SetScrollbars, 351).
--define(wxScrolledWindow_SetScrollRate, 352).
--define(wxScrolledWindow_SetTargetWindow, 353).
--define(wxSashWindow_new_0, 354).
--define(wxSashWindow_new_2, 355).
--define(wxSashWindow_destruct, 356).
--define(wxSashWindow_GetSashVisible, 357).
--define(wxSashWindow_GetMaximumSizeX, 358).
--define(wxSashWindow_GetMaximumSizeY, 359).
--define(wxSashWindow_GetMinimumSizeX, 360).
--define(wxSashWindow_GetMinimumSizeY, 361).
--define(wxSashWindow_SetMaximumSizeX, 362).
--define(wxSashWindow_SetMaximumSizeY, 363).
--define(wxSashWindow_SetMinimumSizeX, 364).
--define(wxSashWindow_SetMinimumSizeY, 365).
--define(wxSashWindow_SetSashVisible, 366).
--define(wxSashLayoutWindow_new_0, 367).
--define(wxSashLayoutWindow_new_2, 368).
--define(wxSashLayoutWindow_Create, 369).
--define(wxSashLayoutWindow_GetAlignment, 370).
--define(wxSashLayoutWindow_GetOrientation, 371).
--define(wxSashLayoutWindow_SetAlignment, 372).
--define(wxSashLayoutWindow_SetDefaultSize, 373).
--define(wxSashLayoutWindow_SetOrientation, 374).
--define(wxSashLayoutWindow_destroy, 375).
--define(wxGrid_new_0, 376).
--define(wxGrid_new_3, 377).
--define(wxGrid_new_4, 378).
--define(wxGrid_destruct, 379).
--define(wxGrid_AppendCols, 380).
--define(wxGrid_AppendRows, 381).
--define(wxGrid_AutoSize, 382).
--define(wxGrid_AutoSizeColumn, 383).
--define(wxGrid_AutoSizeColumns, 384).
--define(wxGrid_AutoSizeRow, 385).
--define(wxGrid_AutoSizeRows, 386).
--define(wxGrid_BeginBatch, 387).
--define(wxGrid_BlockToDeviceRect, 388).
--define(wxGrid_CanDragColSize, 389).
--define(wxGrid_CanDragRowSize, 390).
--define(wxGrid_CanDragGridSize, 391).
--define(wxGrid_CanEnableCellControl, 392).
--define(wxGrid_CellToRect_2, 393).
--define(wxGrid_CellToRect_1, 394).
--define(wxGrid_ClearGrid, 395).
--define(wxGrid_ClearSelection, 396).
--define(wxGrid_CreateGrid, 397).
--define(wxGrid_DeleteCols, 398).
--define(wxGrid_DeleteRows, 399).
--define(wxGrid_DisableCellEditControl, 400).
--define(wxGrid_DisableDragColSize, 401).
--define(wxGrid_DisableDragGridSize, 402).
--define(wxGrid_DisableDragRowSize, 403).
--define(wxGrid_EnableCellEditControl, 404).
--define(wxGrid_EnableDragColSize, 405).
--define(wxGrid_EnableDragGridSize, 406).
--define(wxGrid_EnableDragRowSize, 407).
--define(wxGrid_EnableEditing, 408).
--define(wxGrid_EnableGridLines, 409).
--define(wxGrid_EndBatch, 410).
--define(wxGrid_Fit, 411).
--define(wxGrid_ForceRefresh, 412).
--define(wxGrid_GetBatchCount, 413).
--define(wxGrid_GetCellAlignment, 414).
--define(wxGrid_GetCellBackgroundColour, 415).
--define(wxGrid_GetCellEditor, 416).
--define(wxGrid_GetCellFont, 417).
--define(wxGrid_GetCellRenderer, 418).
--define(wxGrid_GetCellTextColour, 419).
--define(wxGrid_GetCellValue_2, 420).
--define(wxGrid_GetCellValue_1, 421).
--define(wxGrid_GetColLabelAlignment, 422).
--define(wxGrid_GetColLabelSize, 423).
--define(wxGrid_GetColLabelValue, 424).
--define(wxGrid_GetColMinimalAcceptableWidth, 425).
--define(wxGrid_GetDefaultCellAlignment, 426).
--define(wxGrid_GetDefaultCellBackgroundColour, 427).
--define(wxGrid_GetDefaultCellFont, 428).
--define(wxGrid_GetDefaultCellTextColour, 429).
--define(wxGrid_GetDefaultColLabelSize, 430).
--define(wxGrid_GetDefaultColSize, 431).
--define(wxGrid_GetDefaultEditor, 432).
--define(wxGrid_GetDefaultEditorForCell_2, 433).
--define(wxGrid_GetDefaultEditorForCell_1, 434).
--define(wxGrid_GetDefaultEditorForType, 435).
--define(wxGrid_GetDefaultRenderer, 436).
--define(wxGrid_GetDefaultRendererForCell, 437).
--define(wxGrid_GetDefaultRendererForType, 438).
--define(wxGrid_GetDefaultRowLabelSize, 439).
--define(wxGrid_GetDefaultRowSize, 440).
--define(wxGrid_GetGridCursorCol, 441).
--define(wxGrid_GetGridCursorRow, 442).
--define(wxGrid_GetGridLineColour, 443).
--define(wxGrid_GridLinesEnabled, 444).
--define(wxGrid_GetLabelBackgroundColour, 445).
--define(wxGrid_GetLabelFont, 446).
--define(wxGrid_GetLabelTextColour, 447).
--define(wxGrid_GetNumberCols, 448).
--define(wxGrid_GetNumberRows, 449).
--define(wxGrid_GetOrCreateCellAttr, 450).
--define(wxGrid_GetRowMinimalAcceptableHeight, 451).
--define(wxGrid_GetRowLabelAlignment, 452).
--define(wxGrid_GetRowLabelSize, 453).
--define(wxGrid_GetRowLabelValue, 454).
--define(wxGrid_GetRowSize, 455).
--define(wxGrid_GetScrollLineX, 456).
--define(wxGrid_GetScrollLineY, 457).
--define(wxGrid_GetSelectedCells, 458).
--define(wxGrid_GetSelectedCols, 459).
--define(wxGrid_GetSelectedRows, 460).
--define(wxGrid_GetSelectionBackground, 461).
--define(wxGrid_GetSelectionBlockTopLeft, 462).
--define(wxGrid_GetSelectionBlockBottomRight, 463).
--define(wxGrid_GetSelectionForeground, 464).
--define(wxGrid_GetViewWidth, 465).
--define(wxGrid_GetGridWindow, 466).
--define(wxGrid_GetGridRowLabelWindow, 467).
--define(wxGrid_GetGridColLabelWindow, 468).
--define(wxGrid_GetGridCornerLabelWindow, 469).
--define(wxGrid_HideCellEditControl, 470).
--define(wxGrid_InsertCols, 471).
--define(wxGrid_InsertRows, 472).
--define(wxGrid_IsCellEditControlEnabled, 473).
--define(wxGrid_IsCurrentCellReadOnly, 474).
--define(wxGrid_IsEditable, 475).
--define(wxGrid_IsInSelection_2, 476).
--define(wxGrid_IsInSelection_1, 477).
--define(wxGrid_IsReadOnly, 478).
--define(wxGrid_IsSelection, 479).
--define(wxGrid_IsVisible_3, 480).
--define(wxGrid_IsVisible_2, 481).
--define(wxGrid_MakeCellVisible_2, 482).
--define(wxGrid_MakeCellVisible_1, 483).
--define(wxGrid_MoveCursorDown, 484).
--define(wxGrid_MoveCursorLeft, 485).
--define(wxGrid_MoveCursorRight, 486).
--define(wxGrid_MoveCursorUp, 487).
--define(wxGrid_MoveCursorDownBlock, 488).
--define(wxGrid_MoveCursorLeftBlock, 489).
--define(wxGrid_MoveCursorRightBlock, 490).
--define(wxGrid_MoveCursorUpBlock, 491).
--define(wxGrid_MovePageDown, 492).
--define(wxGrid_MovePageUp, 493).
--define(wxGrid_RegisterDataType, 494).
--define(wxGrid_SaveEditControlValue, 495).
--define(wxGrid_SelectAll, 496).
--define(wxGrid_SelectBlock_5, 497).
--define(wxGrid_SelectBlock_3, 498).
--define(wxGrid_SelectCol, 499).
--define(wxGrid_SelectRow, 500).
--define(wxGrid_SetCellAlignment_4, 501).
--define(wxGrid_SetCellAlignment_3, 502).
--define(wxGrid_SetCellAlignment_1, 503).
--define(wxGrid_SetCellBackgroundColour_3_0, 504).
--define(wxGrid_SetCellBackgroundColour_1, 505).
--define(wxGrid_SetCellBackgroundColour_3_1, 506).
--define(wxGrid_SetCellEditor, 507).
--define(wxGrid_SetCellFont, 508).
--define(wxGrid_SetCellRenderer, 509).
--define(wxGrid_SetCellTextColour_3_0, 510).
--define(wxGrid_SetCellTextColour_3_1, 511).
--define(wxGrid_SetCellTextColour_1, 512).
--define(wxGrid_SetCellValue_3_0, 513).
--define(wxGrid_SetCellValue_2, 514).
--define(wxGrid_SetCellValue_3_1, 515).
--define(wxGrid_SetColAttr, 516).
--define(wxGrid_SetColFormatBool, 517).
--define(wxGrid_SetColFormatNumber, 518).
--define(wxGrid_SetColFormatFloat, 519).
--define(wxGrid_SetColFormatCustom, 520).
--define(wxGrid_SetColLabelAlignment, 521).
--define(wxGrid_SetColLabelSize, 522).
--define(wxGrid_SetColLabelValue, 523).
--define(wxGrid_SetColMinimalWidth, 524).
--define(wxGrid_SetColMinimalAcceptableWidth, 525).
--define(wxGrid_SetColSize, 526).
--define(wxGrid_SetDefaultCellAlignment, 527).
--define(wxGrid_SetDefaultCellBackgroundColour, 528).
--define(wxGrid_SetDefaultCellFont, 529).
--define(wxGrid_SetDefaultCellTextColour, 530).
--define(wxGrid_SetDefaultEditor, 531).
--define(wxGrid_SetDefaultRenderer, 532).
--define(wxGrid_SetDefaultColSize, 533).
--define(wxGrid_SetDefaultRowSize, 534).
--define(wxGrid_SetGridCursor, 535).
--define(wxGrid_SetGridLineColour, 536).
--define(wxGrid_SetLabelBackgroundColour, 537).
--define(wxGrid_SetLabelFont, 538).
--define(wxGrid_SetLabelTextColour, 539).
--define(wxGrid_SetMargins, 540).
--define(wxGrid_SetReadOnly, 541).
--define(wxGrid_SetRowAttr, 542).
--define(wxGrid_SetRowLabelAlignment, 543).
--define(wxGrid_SetRowLabelSize, 544).
--define(wxGrid_SetRowLabelValue, 545).
--define(wxGrid_SetRowMinimalHeight, 546).
--define(wxGrid_SetRowMinimalAcceptableHeight, 547).
--define(wxGrid_SetRowSize, 548).
--define(wxGrid_SetScrollLineX, 549).
--define(wxGrid_SetScrollLineY, 550).
--define(wxGrid_SetSelectionBackground, 551).
--define(wxGrid_SetSelectionForeground, 552).
--define(wxGrid_SetSelectionMode, 553).
--define(wxGrid_ShowCellEditControl, 554).
--define(wxGrid_XToCol, 555).
--define(wxGrid_XToEdgeOfCol, 556).
--define(wxGrid_YToEdgeOfRow, 557).
--define(wxGrid_YToRow, 558).
--define(wxGridCellRenderer_Draw, 559).
--define(wxGridCellRenderer_GetBestSize, 560).
--define(wxGridCellEditor_Create, 561).
--define(wxGridCellEditor_IsCreated, 562).
--define(wxGridCellEditor_SetSize, 563).
--define(wxGridCellEditor_Show, 564).
--define(wxGridCellEditor_PaintBackground, 565).
--define(wxGridCellEditor_BeginEdit, 566).
--define(wxGridCellEditor_EndEdit, 567).
--define(wxGridCellEditor_Reset, 568).
--define(wxGridCellEditor_StartingKey, 569).
--define(wxGridCellEditor_StartingClick, 570).
--define(wxGridCellEditor_HandleReturn, 571).
--define(wxGridCellBoolRenderer_new, 572).
--define(wxGridCellBoolRenderer_destroy, 573).
--define(wxGridCellBoolEditor_new, 574).
--define(wxGridCellBoolEditor_IsTrueValue, 575).
--define(wxGridCellBoolEditor_UseStringValues, 576).
--define(wxGridCellBoolEditor_destroy, 577).
--define(wxGridCellFloatRenderer_new, 578).
--define(wxGridCellFloatRenderer_GetPrecision, 579).
--define(wxGridCellFloatRenderer_GetWidth, 580).
--define(wxGridCellFloatRenderer_SetParameters, 581).
--define(wxGridCellFloatRenderer_SetPrecision, 582).
--define(wxGridCellFloatRenderer_SetWidth, 583).
--define(wxGridCellFloatRenderer_destroy, 584).
--define(wxGridCellFloatEditor_new, 585).
--define(wxGridCellFloatEditor_SetParameters, 586).
--define(wxGridCellFloatEditor_destroy, 587).
--define(wxGridCellStringRenderer_new, 588).
--define(wxGridCellStringRenderer_destroy, 589).
--define(wxGridCellTextEditor_new, 590).
--define(wxGridCellTextEditor_SetParameters, 591).
--define(wxGridCellTextEditor_destroy, 592).
--define(wxGridCellChoiceEditor_new, 594).
--define(wxGridCellChoiceEditor_SetParameters, 595).
--define(wxGridCellChoiceEditor_destroy, 596).
--define(wxGridCellNumberRenderer_new, 597).
--define(wxGridCellNumberRenderer_destroy, 598).
--define(wxGridCellNumberEditor_new, 599).
--define(wxGridCellNumberEditor_GetValue, 600).
--define(wxGridCellNumberEditor_SetParameters, 601).
--define(wxGridCellNumberEditor_destroy, 602).
--define(wxGridCellAttr_SetTextColour, 603).
--define(wxGridCellAttr_SetBackgroundColour, 604).
--define(wxGridCellAttr_SetFont, 605).
--define(wxGridCellAttr_SetAlignment, 606).
--define(wxGridCellAttr_SetReadOnly, 607).
--define(wxGridCellAttr_SetRenderer, 608).
--define(wxGridCellAttr_SetEditor, 609).
--define(wxGridCellAttr_HasTextColour, 610).
--define(wxGridCellAttr_HasBackgroundColour, 611).
--define(wxGridCellAttr_HasFont, 612).
--define(wxGridCellAttr_HasAlignment, 613).
--define(wxGridCellAttr_HasRenderer, 614).
--define(wxGridCellAttr_HasEditor, 615).
--define(wxGridCellAttr_GetTextColour, 616).
--define(wxGridCellAttr_GetBackgroundColour, 617).
--define(wxGridCellAttr_GetFont, 618).
--define(wxGridCellAttr_GetAlignment, 619).
--define(wxGridCellAttr_GetRenderer, 620).
--define(wxGridCellAttr_GetEditor, 621).
--define(wxGridCellAttr_IsReadOnly, 622).
--define(wxGridCellAttr_SetDefAttr, 623).
--define(wxDC_Blit, 624).
--define(wxDC_CalcBoundingBox, 625).
--define(wxDC_Clear, 626).
--define(wxDC_ComputeScaleAndOrigin, 627).
--define(wxDC_CrossHair, 628).
--define(wxDC_DestroyClippingRegion, 629).
--define(wxDC_DeviceToLogicalX, 630).
--define(wxDC_DeviceToLogicalXRel, 631).
--define(wxDC_DeviceToLogicalY, 632).
--define(wxDC_DeviceToLogicalYRel, 633).
--define(wxDC_DrawArc, 634).
--define(wxDC_DrawBitmap, 635).
--define(wxDC_DrawCheckMark, 636).
--define(wxDC_DrawCircle, 637).
--define(wxDC_DrawEllipse_2, 639).
--define(wxDC_DrawEllipse_1, 640).
--define(wxDC_DrawEllipticArc, 641).
--define(wxDC_DrawIcon, 642).
--define(wxDC_DrawLabel, 643).
--define(wxDC_DrawLine, 644).
--define(wxDC_DrawLines, 645).
--define(wxDC_DrawPolygon, 647).
--define(wxDC_DrawPoint, 649).
--define(wxDC_DrawRectangle_2, 651).
--define(wxDC_DrawRectangle_1, 652).
--define(wxDC_DrawRotatedText, 653).
--define(wxDC_DrawRoundedRectangle_3, 655).
--define(wxDC_DrawRoundedRectangle_2, 656).
--define(wxDC_DrawText, 657).
--define(wxDC_EndDoc, 658).
--define(wxDC_EndPage, 659).
--define(wxDC_FloodFill, 660).
--define(wxDC_GetBackground, 661).
--define(wxDC_GetBackgroundMode, 662).
--define(wxDC_GetBrush, 663).
--define(wxDC_GetCharHeight, 664).
--define(wxDC_GetCharWidth, 665).
--define(wxDC_GetClippingBox, 666).
--define(wxDC_GetFont, 668).
--define(wxDC_GetLayoutDirection, 669).
--define(wxDC_GetLogicalFunction, 670).
--define(wxDC_GetMapMode, 671).
--define(wxDC_GetMultiLineTextExtent_4, 672).
--define(wxDC_GetMultiLineTextExtent_1, 673).
--define(wxDC_GetPartialTextExtents, 674).
--define(wxDC_GetPen, 675).
--define(wxDC_GetPixel, 676).
--define(wxDC_GetPPI, 677).
--define(wxDC_GetSize, 679).
--define(wxDC_GetSizeMM, 681).
--define(wxDC_GetTextBackground, 682).
--define(wxDC_GetTextExtent_4, 683).
--define(wxDC_GetTextExtent_1, 684).
--define(wxDC_GetTextForeground, 686).
--define(wxDC_GetUserScale, 687).
--define(wxDC_GradientFillConcentric_3, 688).
--define(wxDC_GradientFillConcentric_4, 689).
--define(wxDC_GradientFillLinear, 690).
--define(wxDC_LogicalToDeviceX, 691).
--define(wxDC_LogicalToDeviceXRel, 692).
--define(wxDC_LogicalToDeviceY, 693).
--define(wxDC_LogicalToDeviceYRel, 694).
--define(wxDC_MaxX, 695).
--define(wxDC_MaxY, 696).
--define(wxDC_MinX, 697).
--define(wxDC_MinY, 698).
--define(wxDC_IsOk, 699).
--define(wxDC_ResetBoundingBox, 700).
--define(wxDC_SetAxisOrientation, 701).
--define(wxDC_SetBackground, 702).
--define(wxDC_SetBackgroundMode, 703).
--define(wxDC_SetBrush, 704).
--define(wxDC_SetClippingRegion_2, 706).
--define(wxDC_SetClippingRegion_1_1, 707).
--define(wxDC_SetClippingRegion_1_0, 708).
--define(wxDC_SetDeviceOrigin, 709).
--define(wxDC_SetFont, 710).
--define(wxDC_SetLayoutDirection, 711).
--define(wxDC_SetLogicalFunction, 712).
--define(wxDC_SetMapMode, 713).
--define(wxDC_SetPalette, 714).
--define(wxDC_SetPen, 715).
--define(wxDC_SetTextBackground, 716).
--define(wxDC_SetTextForeground, 717).
--define(wxDC_SetUserScale, 718).
--define(wxDC_StartDoc, 719).
--define(wxDC_StartPage, 720).
--define(wxMirrorDC_new, 721).
--define(wxMirrorDC_destroy, 722).
--define(wxScreenDC_new, 723).
--define(wxScreenDC_destruct, 724).
--define(wxPostScriptDC_new_0, 725).
--define(wxPostScriptDC_new_1, 726).
--define(wxPostScriptDC_destruct, 727).
--define(wxPostScriptDC_SetResolution, 728).
--define(wxPostScriptDC_GetResolution, 729).
--define(wxWindowDC_new_0, 730).
--define(wxWindowDC_new_1, 731).
--define(wxWindowDC_destruct, 732).
--define(wxClientDC_new_0, 733).
--define(wxClientDC_new_1, 734).
--define(wxClientDC_destroy, 735).
--define(wxPaintDC_new_0, 736).
--define(wxPaintDC_new_1, 737).
--define(wxPaintDC_destroy, 738).
--define(wxMemoryDC_new_1_0, 740).
--define(wxMemoryDC_new_1_1, 741).
--define(wxMemoryDC_new_0, 742).
--define(wxMemoryDC_destruct, 744).
--define(wxMemoryDC_SelectObject, 745).
--define(wxMemoryDC_SelectObjectAsSource, 746).
--define(wxBufferedDC_new_0, 747).
--define(wxBufferedDC_new_2, 748).
--define(wxBufferedDC_new_3, 749).
--define(wxBufferedDC_destruct, 750).
--define(wxBufferedDC_Init_2, 751).
--define(wxBufferedDC_Init_3, 752).
--define(wxBufferedPaintDC_new_3, 753).
--define(wxBufferedPaintDC_new_2, 754).
--define(wxBufferedPaintDC_destruct, 755).
--define(wxGraphicsObject_destruct, 756).
--define(wxGraphicsObject_GetRenderer, 757).
--define(wxGraphicsObject_IsNull, 758).
--define(wxGraphicsContext_destruct, 759).
--define(wxGraphicsContext_Create_1_1, 760).
--define(wxGraphicsContext_Create_1_0, 761).
--define(wxGraphicsContext_Create_0, 762).
--define(wxGraphicsContext_CreatePen, 763).
--define(wxGraphicsContext_CreateBrush, 764).
--define(wxGraphicsContext_CreateRadialGradientBrush, 765).
--define(wxGraphicsContext_CreateLinearGradientBrush, 766).
--define(wxGraphicsContext_CreateFont, 767).
--define(wxGraphicsContext_CreateMatrix, 768).
--define(wxGraphicsContext_CreatePath, 769).
--define(wxGraphicsContext_Clip_1, 770).
--define(wxGraphicsContext_Clip_4, 771).
--define(wxGraphicsContext_ResetClip, 772).
--define(wxGraphicsContext_DrawBitmap, 773).
--define(wxGraphicsContext_DrawEllipse, 774).
--define(wxGraphicsContext_DrawIcon, 775).
--define(wxGraphicsContext_DrawLines, 776).
--define(wxGraphicsContext_DrawPath, 777).
--define(wxGraphicsContext_DrawRectangle, 778).
--define(wxGraphicsContext_DrawRoundedRectangle, 779).
--define(wxGraphicsContext_DrawText_3, 780).
--define(wxGraphicsContext_DrawText_4_0, 781).
--define(wxGraphicsContext_DrawText_4_1, 782).
--define(wxGraphicsContext_DrawText_5, 783).
--define(wxGraphicsContext_FillPath, 784).
--define(wxGraphicsContext_StrokePath, 785).
--define(wxGraphicsContext_GetPartialTextExtents, 786).
--define(wxGraphicsContext_GetTextExtent, 787).
--define(wxGraphicsContext_Rotate, 788).
--define(wxGraphicsContext_Scale, 789).
--define(wxGraphicsContext_Translate, 790).
--define(wxGraphicsContext_GetTransform, 791).
--define(wxGraphicsContext_SetTransform, 792).
--define(wxGraphicsContext_ConcatTransform, 793).
--define(wxGraphicsContext_SetBrush_1_1, 794).
--define(wxGraphicsContext_SetBrush_1_0, 795).
--define(wxGraphicsContext_SetFont_1, 796).
--define(wxGraphicsContext_SetFont_2, 797).
--define(wxGraphicsContext_SetPen_1_0, 798).
--define(wxGraphicsContext_SetPen_1_1, 799).
--define(wxGraphicsContext_StrokeLine, 800).
--define(wxGraphicsContext_StrokeLines, 801).
--define(wxGraphicsMatrix_Concat, 803).
--define(wxGraphicsMatrix_Get, 805).
--define(wxGraphicsMatrix_Invert, 806).
--define(wxGraphicsMatrix_IsEqual, 807).
--define(wxGraphicsMatrix_IsIdentity, 809).
--define(wxGraphicsMatrix_Rotate, 810).
--define(wxGraphicsMatrix_Scale, 811).
--define(wxGraphicsMatrix_Translate, 812).
--define(wxGraphicsMatrix_Set, 813).
--define(wxGraphicsMatrix_TransformPoint, 814).
--define(wxGraphicsMatrix_TransformDistance, 815).
--define(wxGraphicsPath_MoveToPoint_2, 816).
--define(wxGraphicsPath_MoveToPoint_1, 817).
--define(wxGraphicsPath_AddArc_6, 818).
--define(wxGraphicsPath_AddArc_5, 819).
--define(wxGraphicsPath_AddArcToPoint, 820).
--define(wxGraphicsPath_AddCircle, 821).
--define(wxGraphicsPath_AddCurveToPoint_6, 822).
--define(wxGraphicsPath_AddCurveToPoint_3, 823).
--define(wxGraphicsPath_AddEllipse, 824).
--define(wxGraphicsPath_AddLineToPoint_2, 825).
--define(wxGraphicsPath_AddLineToPoint_1, 826).
--define(wxGraphicsPath_AddPath, 827).
--define(wxGraphicsPath_AddQuadCurveToPoint, 828).
--define(wxGraphicsPath_AddRectangle, 829).
--define(wxGraphicsPath_AddRoundedRectangle, 830).
--define(wxGraphicsPath_CloseSubpath, 831).
--define(wxGraphicsPath_Contains_3, 832).
--define(wxGraphicsPath_Contains_2, 833).
--define(wxGraphicsPath_GetBox, 835).
--define(wxGraphicsPath_GetCurrentPoint, 837).
--define(wxGraphicsPath_Transform, 838).
--define(wxGraphicsRenderer_GetDefaultRenderer, 839).
--define(wxGraphicsRenderer_CreateContext_1_1, 840).
--define(wxGraphicsRenderer_CreateContext_1_0, 841).
--define(wxGraphicsRenderer_CreatePen, 842).
--define(wxGraphicsRenderer_CreateBrush, 843).
--define(wxGraphicsRenderer_CreateLinearGradientBrush, 844).
--define(wxGraphicsRenderer_CreateRadialGradientBrush, 845).
--define(wxGraphicsRenderer_CreateFont, 846).
--define(wxGraphicsRenderer_CreateMatrix, 847).
--define(wxGraphicsRenderer_CreatePath, 848).
--define(wxMenuBar_new_1, 850).
--define(wxMenuBar_new_0, 852).
--define(wxMenuBar_destruct, 854).
--define(wxMenuBar_Append, 855).
--define(wxMenuBar_Check, 856).
--define(wxMenuBar_Enable_2, 857).
--define(wxMenuBar_Enable_1, 858).
--define(wxMenuBar_EnableTop, 859).
--define(wxMenuBar_FindMenu, 860).
--define(wxMenuBar_FindMenuItem, 861).
--define(wxMenuBar_FindItem, 862).
--define(wxMenuBar_GetHelpString, 863).
--define(wxMenuBar_GetLabel_1, 864).
--define(wxMenuBar_GetLabel_0, 865).
--define(wxMenuBar_GetLabelTop, 866).
--define(wxMenuBar_GetMenu, 867).
--define(wxMenuBar_GetMenuCount, 868).
--define(wxMenuBar_Insert, 869).
--define(wxMenuBar_IsChecked, 870).
--define(wxMenuBar_IsEnabled_1, 871).
--define(wxMenuBar_IsEnabled_0, 872).
--define(wxMenuBar_Remove, 873).
--define(wxMenuBar_Replace, 874).
--define(wxMenuBar_SetHelpString, 875).
--define(wxMenuBar_SetLabel_2, 876).
--define(wxMenuBar_SetLabel_1, 877).
--define(wxMenuBar_SetLabelTop, 878).
--define(wxControl_GetLabel, 879).
--define(wxControl_SetLabel, 880).
--define(wxControlWithItems_Append_1, 881).
--define(wxControlWithItems_Append_2, 882).
--define(wxControlWithItems_appendStrings_1, 883).
--define(wxControlWithItems_Clear, 884).
--define(wxControlWithItems_Delete, 885).
--define(wxControlWithItems_FindString, 886).
--define(wxControlWithItems_getClientData, 887).
--define(wxControlWithItems_setClientData, 888).
--define(wxControlWithItems_GetCount, 889).
--define(wxControlWithItems_GetSelection, 890).
--define(wxControlWithItems_GetString, 891).
--define(wxControlWithItems_GetStringSelection, 892).
--define(wxControlWithItems_Insert_2, 893).
--define(wxControlWithItems_Insert_3, 894).
--define(wxControlWithItems_IsEmpty, 895).
--define(wxControlWithItems_Select, 896).
--define(wxControlWithItems_SetSelection, 897).
--define(wxControlWithItems_SetString, 898).
--define(wxControlWithItems_SetStringSelection, 899).
--define(wxMenu_new_2, 902).
--define(wxMenu_new_1, 903).
--define(wxMenu_destruct, 905).
--define(wxMenu_Append_3, 906).
--define(wxMenu_Append_1, 907).
--define(wxMenu_Append_4_0, 908).
--define(wxMenu_Append_4_1, 909).
--define(wxMenu_AppendCheckItem, 910).
--define(wxMenu_AppendRadioItem, 911).
--define(wxMenu_AppendSeparator, 912).
--define(wxMenu_Break, 913).
--define(wxMenu_Check, 914).
--define(wxMenu_Delete_1_0, 915).
--define(wxMenu_Delete_1_1, 916).
--define(wxMenu_Destroy_1_0, 917).
--define(wxMenu_Destroy_1_1, 918).
--define(wxMenu_Enable, 919).
--define(wxMenu_FindItem_1, 920).
--define(wxMenu_FindItem_2, 921).
--define(wxMenu_FindItemByPosition, 922).
--define(wxMenu_GetHelpString, 923).
--define(wxMenu_GetLabel, 924).
--define(wxMenu_GetMenuItemCount, 925).
--define(wxMenu_GetMenuItems, 926).
--define(wxMenu_GetTitle, 928).
--define(wxMenu_Insert_2, 929).
--define(wxMenu_Insert_3, 930).
--define(wxMenu_Insert_5_1, 931).
--define(wxMenu_Insert_5_0, 932).
--define(wxMenu_InsertCheckItem, 933).
--define(wxMenu_InsertRadioItem, 934).
--define(wxMenu_InsertSeparator, 935).
--define(wxMenu_IsChecked, 936).
--define(wxMenu_IsEnabled, 937).
--define(wxMenu_Prepend_1, 938).
--define(wxMenu_Prepend_2, 939).
--define(wxMenu_Prepend_4_1, 940).
--define(wxMenu_Prepend_4_0, 941).
--define(wxMenu_PrependCheckItem, 942).
--define(wxMenu_PrependRadioItem, 943).
--define(wxMenu_PrependSeparator, 944).
--define(wxMenu_Remove_1_0, 945).
--define(wxMenu_Remove_1_1, 946).
--define(wxMenu_SetHelpString, 947).
--define(wxMenu_SetLabel, 948).
--define(wxMenu_SetTitle, 949).
--define(wxMenuItem_new, 950).
--define(wxMenuItem_destruct, 952).
--define(wxMenuItem_Check, 953).
--define(wxMenuItem_Enable, 954).
--define(wxMenuItem_GetBitmap, 955).
--define(wxMenuItem_GetHelp, 956).
--define(wxMenuItem_GetId, 957).
--define(wxMenuItem_GetKind, 958).
--define(wxMenuItem_GetLabel, 959).
--define(wxMenuItem_GetLabelFromText, 960).
--define(wxMenuItem_GetMenu, 961).
--define(wxMenuItem_GetText, 962).
--define(wxMenuItem_GetSubMenu, 963).
--define(wxMenuItem_IsCheckable, 964).
--define(wxMenuItem_IsChecked, 965).
--define(wxMenuItem_IsEnabled, 966).
--define(wxMenuItem_IsSeparator, 967).
--define(wxMenuItem_IsSubMenu, 968).
--define(wxMenuItem_SetBitmap, 969).
--define(wxMenuItem_SetHelp, 970).
--define(wxMenuItem_SetMenu, 971).
--define(wxMenuItem_SetSubMenu, 972).
--define(wxMenuItem_SetText, 973).
--define(wxToolBar_AddControl, 974).
--define(wxToolBar_AddSeparator, 975).
--define(wxToolBar_AddTool_5, 976).
--define(wxToolBar_AddTool_4_0, 977).
--define(wxToolBar_AddTool_1, 978).
--define(wxToolBar_AddTool_4_1, 979).
--define(wxToolBar_AddTool_3, 980).
--define(wxToolBar_AddTool_6, 981).
--define(wxToolBar_AddCheckTool, 982).
--define(wxToolBar_AddRadioTool, 983).
--define(wxToolBar_DeleteTool, 984).
--define(wxToolBar_DeleteToolByPos, 985).
--define(wxToolBar_EnableTool, 986).
--define(wxToolBar_FindById, 987).
--define(wxToolBar_FindControl, 988).
--define(wxToolBar_FindToolForPosition, 989).
--define(wxToolBar_GetToolSize, 990).
--define(wxToolBar_GetToolBitmapSize, 991).
--define(wxToolBar_GetMargins, 992).
--define(wxToolBar_GetToolEnabled, 993).
--define(wxToolBar_GetToolLongHelp, 994).
--define(wxToolBar_GetToolPacking, 995).
--define(wxToolBar_GetToolPos, 996).
--define(wxToolBar_GetToolSeparation, 997).
--define(wxToolBar_GetToolShortHelp, 998).
--define(wxToolBar_GetToolState, 999).
--define(wxToolBar_InsertControl, 1000).
--define(wxToolBar_InsertSeparator, 1001).
--define(wxToolBar_InsertTool_5, 1002).
--define(wxToolBar_InsertTool_2, 1003).
--define(wxToolBar_InsertTool_4, 1004).
--define(wxToolBar_Realize, 1005).
--define(wxToolBar_RemoveTool, 1006).
--define(wxToolBar_SetMargins, 1007).
--define(wxToolBar_SetToolBitmapSize, 1008).
--define(wxToolBar_SetToolLongHelp, 1009).
--define(wxToolBar_SetToolPacking, 1010).
--define(wxToolBar_SetToolShortHelp, 1011).
--define(wxToolBar_SetToolSeparation, 1012).
--define(wxToolBar_ToggleTool, 1013).
--define(wxStatusBar_new_0, 1015).
--define(wxStatusBar_new_2, 1016).
--define(wxStatusBar_destruct, 1018).
--define(wxStatusBar_Create, 1019).
--define(wxStatusBar_GetFieldRect, 1020).
--define(wxStatusBar_GetFieldsCount, 1021).
--define(wxStatusBar_GetStatusText, 1022).
--define(wxStatusBar_PopStatusText, 1023).
--define(wxStatusBar_PushStatusText, 1024).
--define(wxStatusBar_SetFieldsCount, 1025).
--define(wxStatusBar_SetMinHeight, 1026).
--define(wxStatusBar_SetStatusText, 1027).
--define(wxStatusBar_SetStatusWidths, 1028).
--define(wxStatusBar_SetStatusStyles, 1029).
--define(wxBitmap_new_0, 1030).
--define(wxBitmap_new_3, 1031).
--define(wxBitmap_new_4, 1032).
--define(wxBitmap_new_2_0, 1033).
--define(wxBitmap_new_2_1, 1034).
--define(wxBitmap_destruct, 1035).
--define(wxBitmap_ConvertToImage, 1036).
--define(wxBitmap_CopyFromIcon, 1037).
--define(wxBitmap_Create, 1038).
--define(wxBitmap_GetDepth, 1039).
--define(wxBitmap_GetHeight, 1040).
--define(wxBitmap_GetPalette, 1041).
--define(wxBitmap_GetMask, 1042).
--define(wxBitmap_GetWidth, 1043).
--define(wxBitmap_GetSubBitmap, 1044).
--define(wxBitmap_LoadFile, 1045).
--define(wxBitmap_Ok, 1046).
--define(wxBitmap_SaveFile, 1047).
--define(wxBitmap_SetDepth, 1048).
--define(wxBitmap_SetHeight, 1049).
--define(wxBitmap_SetMask, 1050).
--define(wxBitmap_SetPalette, 1051).
--define(wxBitmap_SetWidth, 1052).
--define(wxIcon_new_0, 1053).
--define(wxIcon_new_2, 1054).
--define(wxIcon_new_1, 1055).
--define(wxIcon_CopyFromBitmap, 1056).
--define(wxIcon_destroy, 1057).
--define(wxIconBundle_new_0, 1058).
--define(wxIconBundle_new_2, 1059).
--define(wxIconBundle_new_1_0, 1060).
--define(wxIconBundle_new_1_1, 1061).
--define(wxIconBundle_destruct, 1062).
--define(wxIconBundle_AddIcon_2, 1063).
--define(wxIconBundle_AddIcon_1, 1064).
--define(wxIconBundle_GetIcon_1_1, 1065).
--define(wxIconBundle_GetIcon_1_0, 1066).
--define(wxCursor_new_0, 1067).
--define(wxCursor_new_1_0, 1068).
--define(wxCursor_new_1_1, 1069).
--define(wxCursor_new_4, 1070).
--define(wxCursor_destruct, 1071).
--define(wxCursor_Ok, 1072).
--define(wxMask_new_0, 1073).
--define(wxMask_new_2_1, 1074).
--define(wxMask_new_2_0, 1075).
--define(wxMask_new_1, 1076).
--define(wxMask_destruct, 1077).
--define(wxMask_Create_2_1, 1078).
--define(wxMask_Create_2_0, 1079).
--define(wxMask_Create_1, 1080).
--define(wxImage_new_0, 1081).
--define(wxImage_new_3_0, 1082).
--define(wxImage_new_4, 1083).
--define(wxImage_new_5, 1084).
--define(wxImage_new_2, 1085).
--define(wxImage_new_3_1, 1086).
--define(wxImage_Blur, 1087).
--define(wxImage_BlurHorizontal, 1088).
--define(wxImage_BlurVertical, 1089).
--define(wxImage_ConvertAlphaToMask, 1090).
--define(wxImage_ConvertToGreyscale, 1091).
--define(wxImage_ConvertToMono, 1092).
--define(wxImage_Copy, 1093).
--define(wxImage_Create_3, 1094).
--define(wxImage_Create_4, 1095).
--define(wxImage_Create_5, 1096).
--define(wxImage_Destroy, 1097).
--define(wxImage_FindFirstUnusedColour, 1098).
--define(wxImage_GetImageExtWildcard, 1099).
--define(wxImage_GetAlpha_2, 1100).
--define(wxImage_GetAlpha_0, 1101).
--define(wxImage_GetBlue, 1102).
--define(wxImage_GetData, 1103).
--define(wxImage_GetGreen, 1104).
--define(wxImage_GetImageCount, 1105).
--define(wxImage_GetHeight, 1106).
--define(wxImage_GetMaskBlue, 1107).
--define(wxImage_GetMaskGreen, 1108).
--define(wxImage_GetMaskRed, 1109).
--define(wxImage_GetOrFindMaskColour, 1110).
--define(wxImage_GetPalette, 1111).
--define(wxImage_GetRed, 1112).
--define(wxImage_GetSubImage, 1113).
--define(wxImage_GetWidth, 1114).
--define(wxImage_HasAlpha, 1115).
--define(wxImage_HasMask, 1116).
--define(wxImage_GetOption, 1117).
--define(wxImage_GetOptionInt, 1118).
--define(wxImage_HasOption, 1119).
--define(wxImage_InitAlpha, 1120).
--define(wxImage_InitStandardHandlers, 1121).
--define(wxImage_IsTransparent, 1122).
--define(wxImage_LoadFile_2, 1123).
--define(wxImage_LoadFile_3, 1124).
--define(wxImage_Ok, 1125).
--define(wxImage_RemoveHandler, 1126).
--define(wxImage_Mirror, 1127).
--define(wxImage_Replace, 1128).
--define(wxImage_Rescale, 1129).
--define(wxImage_Resize, 1130).
--define(wxImage_Rotate, 1131).
--define(wxImage_RotateHue, 1132).
--define(wxImage_Rotate90, 1133).
--define(wxImage_SaveFile_1, 1134).
--define(wxImage_SaveFile_2_0, 1135).
--define(wxImage_SaveFile_2_1, 1136).
--define(wxImage_Scale, 1137).
--define(wxImage_Size, 1138).
--define(wxImage_SetAlpha_3, 1139).
--define(wxImage_SetAlpha_2, 1140).
--define(wxImage_SetData_2, 1141).
--define(wxImage_SetData_4, 1142).
--define(wxImage_SetMask, 1143).
--define(wxImage_SetMaskColour, 1144).
--define(wxImage_SetMaskFromImage, 1145).
--define(wxImage_SetOption_2_1, 1146).
--define(wxImage_SetOption_2_0, 1147).
--define(wxImage_SetPalette, 1148).
--define(wxImage_SetRGB_5, 1149).
--define(wxImage_SetRGB_4, 1150).
--define(wxImage_destroy, 1151).
--define(wxBrush_new_0, 1152).
--define(wxBrush_new_2, 1153).
--define(wxBrush_new_1, 1154).
--define(wxBrush_destruct, 1156).
--define(wxBrush_GetColour, 1157).
--define(wxBrush_GetStipple, 1158).
--define(wxBrush_GetStyle, 1159).
--define(wxBrush_IsHatch, 1160).
--define(wxBrush_IsOk, 1161).
--define(wxBrush_SetColour_1, 1162).
--define(wxBrush_SetColour_3, 1163).
--define(wxBrush_SetStipple, 1164).
--define(wxBrush_SetStyle, 1165).
--define(wxPen_new_0, 1166).
--define(wxPen_new_2, 1167).
--define(wxPen_destruct, 1168).
--define(wxPen_GetCap, 1169).
--define(wxPen_GetColour, 1170).
--define(wxPen_GetJoin, 1171).
--define(wxPen_GetStyle, 1172).
--define(wxPen_GetWidth, 1173).
--define(wxPen_IsOk, 1174).
--define(wxPen_SetCap, 1175).
--define(wxPen_SetColour_1, 1176).
--define(wxPen_SetColour_3, 1177).
--define(wxPen_SetJoin, 1178).
--define(wxPen_SetStyle, 1179).
--define(wxPen_SetWidth, 1180).
--define(wxRegion_new_0, 1181).
--define(wxRegion_new_4, 1182).
--define(wxRegion_new_2, 1183).
--define(wxRegion_new_1_1, 1184).
--define(wxRegion_new_1_0, 1186).
--define(wxRegion_destruct, 1188).
--define(wxRegion_Clear, 1189).
--define(wxRegion_Contains_2, 1190).
--define(wxRegion_Contains_1_0, 1191).
--define(wxRegion_Contains_4, 1192).
--define(wxRegion_Contains_1_1, 1193).
--define(wxRegion_ConvertToBitmap, 1194).
--define(wxRegion_GetBox, 1195).
--define(wxRegion_Intersect_4, 1196).
--define(wxRegion_Intersect_1_1, 1197).
--define(wxRegion_Intersect_1_0, 1198).
--define(wxRegion_IsEmpty, 1199).
--define(wxRegion_Subtract_4, 1200).
--define(wxRegion_Subtract_1_1, 1201).
--define(wxRegion_Subtract_1_0, 1202).
--define(wxRegion_Offset_2, 1203).
--define(wxRegion_Offset_1, 1204).
--define(wxRegion_Union_4, 1205).
--define(wxRegion_Union_1_2, 1206).
--define(wxRegion_Union_1_1, 1207).
--define(wxRegion_Union_1_0, 1208).
--define(wxRegion_Union_3, 1209).
--define(wxRegion_Xor_4, 1210).
--define(wxRegion_Xor_1_1, 1211).
--define(wxRegion_Xor_1_0, 1212).
--define(wxAcceleratorTable_new_0, 1213).
--define(wxAcceleratorTable_new_2, 1214).
--define(wxAcceleratorTable_destruct, 1215).
--define(wxAcceleratorTable_Ok, 1216).
--define(wxAcceleratorEntry_new_1_0, 1217).
--define(wxAcceleratorEntry_new_1_1, 1218).
--define(wxAcceleratorEntry_GetCommand, 1219).
--define(wxAcceleratorEntry_GetFlags, 1220).
--define(wxAcceleratorEntry_GetKeyCode, 1221).
--define(wxAcceleratorEntry_Set, 1222).
--define(wxAcceleratorEntry_destroy, 1223).
--define(wxCaret_new_3, 1228).
--define(wxCaret_new_2, 1229).
--define(wxCaret_destruct, 1231).
--define(wxCaret_Create_3, 1232).
--define(wxCaret_Create_2, 1233).
--define(wxCaret_GetBlinkTime, 1234).
--define(wxCaret_GetPosition, 1236).
--define(wxCaret_GetSize, 1238).
--define(wxCaret_GetWindow, 1239).
--define(wxCaret_Hide, 1240).
--define(wxCaret_IsOk, 1241).
--define(wxCaret_IsVisible, 1242).
--define(wxCaret_Move_2, 1243).
--define(wxCaret_Move_1, 1244).
--define(wxCaret_SetBlinkTime, 1245).
--define(wxCaret_SetSize_2, 1246).
--define(wxCaret_SetSize_1, 1247).
--define(wxCaret_Show, 1248).
--define(wxSizer_Add_2_1, 1249).
--define(wxSizer_Add_2_0, 1250).
--define(wxSizer_Add_3, 1251).
--define(wxSizer_Add_2_3, 1252).
--define(wxSizer_Add_2_2, 1253).
--define(wxSizer_AddSpacer, 1254).
--define(wxSizer_AddStretchSpacer, 1255).
--define(wxSizer_CalcMin, 1256).
--define(wxSizer_Clear, 1257).
--define(wxSizer_Detach_1_2, 1258).
--define(wxSizer_Detach_1_1, 1259).
--define(wxSizer_Detach_1_0, 1260).
--define(wxSizer_Fit, 1261).
--define(wxSizer_FitInside, 1262).
--define(wxSizer_GetChildren, 1263).
--define(wxSizer_GetItem_2_1, 1264).
--define(wxSizer_GetItem_2_0, 1265).
--define(wxSizer_GetItem_1, 1266).
--define(wxSizer_GetSize, 1267).
--define(wxSizer_GetPosition, 1268).
--define(wxSizer_GetMinSize, 1269).
--define(wxSizer_Hide_2_0, 1270).
--define(wxSizer_Hide_2_1, 1271).
--define(wxSizer_Hide_1, 1272).
--define(wxSizer_Insert_3_1, 1273).
--define(wxSizer_Insert_3_0, 1274).
--define(wxSizer_Insert_4, 1275).
--define(wxSizer_Insert_3_3, 1276).
--define(wxSizer_Insert_3_2, 1277).
--define(wxSizer_Insert_2, 1278).
--define(wxSizer_InsertSpacer, 1279).
--define(wxSizer_InsertStretchSpacer, 1280).
--define(wxSizer_IsShown_1_2, 1281).
--define(wxSizer_IsShown_1_1, 1282).
--define(wxSizer_IsShown_1_0, 1283).
--define(wxSizer_Layout, 1284).
--define(wxSizer_Prepend_2_1, 1285).
--define(wxSizer_Prepend_2_0, 1286).
--define(wxSizer_Prepend_3, 1287).
--define(wxSizer_Prepend_2_3, 1288).
--define(wxSizer_Prepend_2_2, 1289).
--define(wxSizer_Prepend_1, 1290).
--define(wxSizer_PrependSpacer, 1291).
--define(wxSizer_PrependStretchSpacer, 1292).
--define(wxSizer_RecalcSizes, 1293).
--define(wxSizer_Remove_1_1, 1294).
--define(wxSizer_Remove_1_0, 1295).
--define(wxSizer_Replace_3_1, 1296).
--define(wxSizer_Replace_3_0, 1297).
--define(wxSizer_Replace_2, 1298).
--define(wxSizer_SetDimension, 1299).
--define(wxSizer_SetMinSize_2, 1300).
--define(wxSizer_SetMinSize_1, 1301).
--define(wxSizer_SetItemMinSize_3_2, 1302).
--define(wxSizer_SetItemMinSize_2_2, 1303).
--define(wxSizer_SetItemMinSize_3_1, 1304).
--define(wxSizer_SetItemMinSize_2_1, 1305).
--define(wxSizer_SetItemMinSize_3_0, 1306).
--define(wxSizer_SetItemMinSize_2_0, 1307).
--define(wxSizer_SetSizeHints, 1308).
--define(wxSizer_SetVirtualSizeHints, 1309).
--define(wxSizer_Show_2_2, 1310).
--define(wxSizer_Show_2_1, 1311).
--define(wxSizer_Show_2_0, 1312).
--define(wxSizer_Show_1, 1313).
--define(wxSizerFlags_new, 1314).
--define(wxSizerFlags_Align, 1315).
--define(wxSizerFlags_Border_2, 1316).
--define(wxSizerFlags_Border_1, 1317).
--define(wxSizerFlags_Center, 1318).
--define(wxSizerFlags_Centre, 1319).
--define(wxSizerFlags_Expand, 1320).
--define(wxSizerFlags_Left, 1321).
--define(wxSizerFlags_Proportion, 1322).
--define(wxSizerFlags_Right, 1323).
--define(wxSizerFlags_destroy, 1324).
--define(wxSizerItem_new_5_1, 1325).
--define(wxSizerItem_new_2_1, 1326).
--define(wxSizerItem_new_5_0, 1327).
--define(wxSizerItem_new_2_0, 1328).
--define(wxSizerItem_new_6, 1329).
--define(wxSizerItem_new_3, 1330).
--define(wxSizerItem_new_0, 1331).
--define(wxSizerItem_destruct, 1332).
--define(wxSizerItem_CalcMin, 1333).
--define(wxSizerItem_DeleteWindows, 1334).
--define(wxSizerItem_DetachSizer, 1335).
--define(wxSizerItem_GetBorder, 1336).
--define(wxSizerItem_GetFlag, 1337).
--define(wxSizerItem_GetMinSize, 1338).
--define(wxSizerItem_GetPosition, 1339).
--define(wxSizerItem_GetProportion, 1340).
--define(wxSizerItem_GetRatio, 1341).
--define(wxSizerItem_GetRect, 1342).
--define(wxSizerItem_GetSize, 1343).
--define(wxSizerItem_GetSizer, 1344).
--define(wxSizerItem_GetSpacer, 1345).
--define(wxSizerItem_GetUserData, 1346).
--define(wxSizerItem_GetWindow, 1347).
--define(wxSizerItem_IsSizer, 1348).
--define(wxSizerItem_IsShown, 1349).
--define(wxSizerItem_IsSpacer, 1350).
--define(wxSizerItem_IsWindow, 1351).
--define(wxSizerItem_SetBorder, 1352).
--define(wxSizerItem_SetDimension, 1353).
--define(wxSizerItem_SetFlag, 1354).
--define(wxSizerItem_SetInitSize, 1355).
--define(wxSizerItem_SetMinSize_1, 1356).
--define(wxSizerItem_SetMinSize_2, 1357).
--define(wxSizerItem_SetProportion, 1358).
--define(wxSizerItem_SetRatio_2, 1359).
--define(wxSizerItem_SetRatio_1_1, 1360).
--define(wxSizerItem_SetRatio_1_0, 1361).
--define(wxSizerItem_SetSizer, 1362).
--define(wxSizerItem_SetSpacer_1, 1363).
--define(wxSizerItem_SetSpacer_2, 1364).
--define(wxSizerItem_SetWindow, 1365).
--define(wxSizerItem_Show, 1366).
--define(wxBoxSizer_new, 1367).
--define(wxBoxSizer_GetOrientation, 1368).
--define(wxBoxSizer_destroy, 1369).
--define(wxStaticBoxSizer_new_2, 1370).
--define(wxStaticBoxSizer_new_3, 1371).
--define(wxStaticBoxSizer_GetStaticBox, 1372).
--define(wxStaticBoxSizer_destroy, 1373).
--define(wxGridSizer_new_4, 1374).
--define(wxGridSizer_new_2, 1375).
--define(wxGridSizer_GetCols, 1376).
--define(wxGridSizer_GetHGap, 1377).
--define(wxGridSizer_GetRows, 1378).
--define(wxGridSizer_GetVGap, 1379).
--define(wxGridSizer_SetCols, 1380).
--define(wxGridSizer_SetHGap, 1381).
--define(wxGridSizer_SetRows, 1382).
--define(wxGridSizer_SetVGap, 1383).
--define(wxGridSizer_destroy, 1384).
--define(wxFlexGridSizer_new_4, 1385).
--define(wxFlexGridSizer_new_2, 1386).
--define(wxFlexGridSizer_AddGrowableCol, 1387).
--define(wxFlexGridSizer_AddGrowableRow, 1388).
--define(wxFlexGridSizer_GetFlexibleDirection, 1389).
--define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1390).
--define(wxFlexGridSizer_RemoveGrowableCol, 1391).
--define(wxFlexGridSizer_RemoveGrowableRow, 1392).
--define(wxFlexGridSizer_SetFlexibleDirection, 1393).
--define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1394).
--define(wxFlexGridSizer_destroy, 1395).
--define(wxGridBagSizer_new, 1396).
--define(wxGridBagSizer_Add_3_2, 1397).
--define(wxGridBagSizer_Add_3_1, 1398).
--define(wxGridBagSizer_Add_4, 1399).
--define(wxGridBagSizer_Add_1_0, 1400).
--define(wxGridBagSizer_Add_2_1, 1401).
--define(wxGridBagSizer_Add_2_0, 1402).
--define(wxGridBagSizer_Add_3_0, 1403).
--define(wxGridBagSizer_Add_1_1, 1404).
--define(wxGridBagSizer_CalcMin, 1405).
--define(wxGridBagSizer_CheckForIntersection_2, 1406).
--define(wxGridBagSizer_CheckForIntersection_3, 1407).
--define(wxGridBagSizer_FindItem_1_1, 1408).
--define(wxGridBagSizer_FindItem_1_0, 1409).
--define(wxGridBagSizer_FindItemAtPoint, 1410).
--define(wxGridBagSizer_FindItemAtPosition, 1411).
--define(wxGridBagSizer_FindItemWithData, 1412).
--define(wxGridBagSizer_GetCellSize, 1413).
--define(wxGridBagSizer_GetEmptyCellSize, 1414).
--define(wxGridBagSizer_GetItemPosition_1_2, 1415).
--define(wxGridBagSizer_GetItemPosition_1_1, 1416).
--define(wxGridBagSizer_GetItemPosition_1_0, 1417).
--define(wxGridBagSizer_GetItemSpan_1_2, 1418).
--define(wxGridBagSizer_GetItemSpan_1_1, 1419).
--define(wxGridBagSizer_GetItemSpan_1_0, 1420).
--define(wxGridBagSizer_SetEmptyCellSize, 1421).
--define(wxGridBagSizer_SetItemPosition_2_2, 1422).
--define(wxGridBagSizer_SetItemPosition_2_1, 1423).
--define(wxGridBagSizer_SetItemPosition_2_0, 1424).
--define(wxGridBagSizer_SetItemSpan_2_2, 1425).
--define(wxGridBagSizer_SetItemSpan_2_1, 1426).
--define(wxGridBagSizer_SetItemSpan_2_0, 1427).
--define(wxGridBagSizer_destroy, 1428).
--define(wxStdDialogButtonSizer_new, 1429).
--define(wxStdDialogButtonSizer_AddButton, 1430).
--define(wxStdDialogButtonSizer_Realize, 1431).
--define(wxStdDialogButtonSizer_SetAffirmativeButton, 1432).
--define(wxStdDialogButtonSizer_SetCancelButton, 1433).
--define(wxStdDialogButtonSizer_SetNegativeButton, 1434).
--define(wxStdDialogButtonSizer_destroy, 1435).
--define(wxFont_new_0, 1436).
--define(wxFont_new_1, 1437).
--define(wxFont_new_5, 1438).
--define(wxFont_destruct, 1440).
--define(wxFont_IsFixedWidth, 1441).
--define(wxFont_GetDefaultEncoding, 1442).
--define(wxFont_GetFaceName, 1443).
--define(wxFont_GetFamily, 1444).
--define(wxFont_GetNativeFontInfoDesc, 1445).
--define(wxFont_GetNativeFontInfoUserDesc, 1446).
--define(wxFont_GetPointSize, 1447).
--define(wxFont_GetStyle, 1448).
--define(wxFont_GetUnderlined, 1449).
--define(wxFont_GetWeight, 1450).
--define(wxFont_Ok, 1451).
--define(wxFont_SetDefaultEncoding, 1452).
--define(wxFont_SetFaceName, 1453).
--define(wxFont_SetFamily, 1454).
--define(wxFont_SetPointSize, 1455).
--define(wxFont_SetStyle, 1456).
--define(wxFont_SetUnderlined, 1457).
--define(wxFont_SetWeight, 1458).
--define(wxToolTip_Enable, 1459).
--define(wxToolTip_SetDelay, 1460).
--define(wxToolTip_new, 1461).
--define(wxToolTip_SetTip, 1462).
--define(wxToolTip_GetTip, 1463).
--define(wxToolTip_GetWindow, 1464).
--define(wxToolTip_destroy, 1465).
--define(wxButton_new_3, 1467).
--define(wxButton_new_0, 1468).
--define(wxButton_destruct, 1469).
--define(wxButton_Create, 1470).
--define(wxButton_GetDefaultSize, 1471).
--define(wxButton_SetDefault, 1472).
--define(wxButton_SetLabel, 1473).
--define(wxBitmapButton_new_4, 1475).
--define(wxBitmapButton_new_0, 1476).
--define(wxBitmapButton_Create, 1477).
--define(wxBitmapButton_GetBitmapDisabled, 1478).
--define(wxBitmapButton_GetBitmapFocus, 1480).
--define(wxBitmapButton_GetBitmapLabel, 1482).
--define(wxBitmapButton_GetBitmapSelected, 1484).
--define(wxBitmapButton_SetBitmapDisabled, 1486).
--define(wxBitmapButton_SetBitmapFocus, 1487).
--define(wxBitmapButton_SetBitmapLabel, 1488).
--define(wxBitmapButton_SetBitmapSelected, 1489).
--define(wxBitmapButton_destroy, 1490).
--define(wxToggleButton_new_0, 1491).
--define(wxToggleButton_new_4, 1492).
--define(wxToggleButton_Create, 1493).
--define(wxToggleButton_GetValue, 1494).
--define(wxToggleButton_SetValue, 1495).
--define(wxToggleButton_destroy, 1496).
--define(wxCalendarCtrl_new_0, 1497).
--define(wxCalendarCtrl_new_3, 1498).
--define(wxCalendarCtrl_Create, 1499).
--define(wxCalendarCtrl_destruct, 1500).
--define(wxCalendarCtrl_SetDate, 1501).
--define(wxCalendarCtrl_GetDate, 1502).
--define(wxCalendarCtrl_EnableYearChange, 1503).
--define(wxCalendarCtrl_EnableMonthChange, 1504).
--define(wxCalendarCtrl_EnableHolidayDisplay, 1505).
--define(wxCalendarCtrl_SetHeaderColours, 1506).
--define(wxCalendarCtrl_GetHeaderColourFg, 1507).
--define(wxCalendarCtrl_GetHeaderColourBg, 1508).
--define(wxCalendarCtrl_SetHighlightColours, 1509).
--define(wxCalendarCtrl_GetHighlightColourFg, 1510).
--define(wxCalendarCtrl_GetHighlightColourBg, 1511).
--define(wxCalendarCtrl_SetHolidayColours, 1512).
--define(wxCalendarCtrl_GetHolidayColourFg, 1513).
--define(wxCalendarCtrl_GetHolidayColourBg, 1514).
--define(wxCalendarCtrl_GetAttr, 1515).
--define(wxCalendarCtrl_SetAttr, 1516).
--define(wxCalendarCtrl_SetHoliday, 1517).
--define(wxCalendarCtrl_ResetAttr, 1518).
--define(wxCalendarCtrl_HitTest, 1519).
--define(wxCalendarDateAttr_new_0, 1520).
--define(wxCalendarDateAttr_new_2_1, 1521).
--define(wxCalendarDateAttr_new_2_0, 1522).
--define(wxCalendarDateAttr_SetTextColour, 1523).
--define(wxCalendarDateAttr_SetBackgroundColour, 1524).
--define(wxCalendarDateAttr_SetBorderColour, 1525).
--define(wxCalendarDateAttr_SetFont, 1526).
--define(wxCalendarDateAttr_SetBorder, 1527).
--define(wxCalendarDateAttr_SetHoliday, 1528).
--define(wxCalendarDateAttr_HasTextColour, 1529).
--define(wxCalendarDateAttr_HasBackgroundColour, 1530).
--define(wxCalendarDateAttr_HasBorderColour, 1531).
--define(wxCalendarDateAttr_HasFont, 1532).
--define(wxCalendarDateAttr_HasBorder, 1533).
--define(wxCalendarDateAttr_IsHoliday, 1534).
--define(wxCalendarDateAttr_GetTextColour, 1535).
--define(wxCalendarDateAttr_GetBackgroundColour, 1536).
--define(wxCalendarDateAttr_GetBorderColour, 1537).
--define(wxCalendarDateAttr_GetFont, 1538).
--define(wxCalendarDateAttr_GetBorder, 1539).
--define(wxCalendarDateAttr_destroy, 1540).
--define(wxCheckBox_new_4, 1542).
--define(wxCheckBox_new_0, 1543).
--define(wxCheckBox_Create, 1544).
--define(wxCheckBox_GetValue, 1545).
--define(wxCheckBox_Get3StateValue, 1546).
--define(wxCheckBox_Is3rdStateAllowedForUser, 1547).
--define(wxCheckBox_Is3State, 1548).
--define(wxCheckBox_IsChecked, 1549).
--define(wxCheckBox_SetValue, 1550).
--define(wxCheckBox_Set3StateValue, 1551).
--define(wxCheckBox_destroy, 1552).
--define(wxCheckListBox_new_0, 1553).
--define(wxCheckListBox_new_3, 1555).
--define(wxCheckListBox_Check, 1556).
--define(wxCheckListBox_IsChecked, 1557).
--define(wxCheckListBox_destroy, 1558).
--define(wxChoice_new_3, 1561).
--define(wxChoice_new_0, 1562).
--define(wxChoice_destruct, 1564).
--define(wxChoice_Create, 1566).
--define(wxChoice_Delete, 1567).
--define(wxChoice_GetColumns, 1568).
--define(wxChoice_SetColumns, 1569).
--define(wxComboBox_new_0, 1570).
--define(wxComboBox_new_3, 1572).
--define(wxComboBox_destruct, 1573).
--define(wxComboBox_Create, 1575).
--define(wxComboBox_CanCopy, 1576).
--define(wxComboBox_CanCut, 1577).
--define(wxComboBox_CanPaste, 1578).
--define(wxComboBox_CanRedo, 1579).
--define(wxComboBox_CanUndo, 1580).
--define(wxComboBox_Copy, 1581).
--define(wxComboBox_Cut, 1582).
--define(wxComboBox_GetInsertionPoint, 1583).
--define(wxComboBox_GetLastPosition, 1584).
--define(wxComboBox_GetValue, 1585).
--define(wxComboBox_Paste, 1586).
--define(wxComboBox_Redo, 1587).
--define(wxComboBox_Replace, 1588).
--define(wxComboBox_Remove, 1589).
--define(wxComboBox_SetInsertionPoint, 1590).
--define(wxComboBox_SetInsertionPointEnd, 1591).
--define(wxComboBox_SetSelection_1, 1592).
--define(wxComboBox_SetSelection_2, 1593).
--define(wxComboBox_SetValue, 1594).
--define(wxComboBox_Undo, 1595).
--define(wxGauge_new_0, 1596).
--define(wxGauge_new_4, 1597).
--define(wxGauge_Create, 1598).
--define(wxGauge_GetBezelFace, 1599).
--define(wxGauge_GetRange, 1600).
--define(wxGauge_GetShadowWidth, 1601).
--define(wxGauge_GetValue, 1602).
--define(wxGauge_IsVertical, 1603).
--define(wxGauge_SetBezelFace, 1604).
--define(wxGauge_SetRange, 1605).
--define(wxGauge_SetShadowWidth, 1606).
--define(wxGauge_SetValue, 1607).
--define(wxGauge_Pulse, 1608).
--define(wxGauge_destroy, 1609).
--define(wxGenericDirCtrl_new_0, 1610).
--define(wxGenericDirCtrl_new_2, 1611).
--define(wxGenericDirCtrl_destruct, 1612).
--define(wxGenericDirCtrl_Create, 1613).
--define(wxGenericDirCtrl_Init, 1614).
--define(wxGenericDirCtrl_CollapseTree, 1615).
--define(wxGenericDirCtrl_ExpandPath, 1616).
--define(wxGenericDirCtrl_GetDefaultPath, 1617).
--define(wxGenericDirCtrl_GetPath, 1618).
--define(wxGenericDirCtrl_GetFilePath, 1619).
--define(wxGenericDirCtrl_GetFilter, 1620).
--define(wxGenericDirCtrl_GetFilterIndex, 1621).
--define(wxGenericDirCtrl_GetRootId, 1622).
--define(wxGenericDirCtrl_GetTreeCtrl, 1623).
--define(wxGenericDirCtrl_ReCreateTree, 1624).
--define(wxGenericDirCtrl_SetDefaultPath, 1625).
--define(wxGenericDirCtrl_SetFilter, 1626).
--define(wxGenericDirCtrl_SetFilterIndex, 1627).
--define(wxGenericDirCtrl_SetPath, 1628).
--define(wxStaticBox_new_4, 1630).
--define(wxStaticBox_new_0, 1631).
--define(wxStaticBox_Create, 1632).
--define(wxStaticBox_destroy, 1633).
--define(wxStaticLine_new_2, 1635).
--define(wxStaticLine_new_0, 1636).
--define(wxStaticLine_Create, 1637).
--define(wxStaticLine_IsVertical, 1638).
--define(wxStaticLine_GetDefaultSize, 1639).
--define(wxStaticLine_destroy, 1640).
--define(wxListBox_new_3, 1643).
--define(wxListBox_new_0, 1644).
--define(wxListBox_destruct, 1646).
--define(wxListBox_Create, 1648).
--define(wxListBox_Deselect, 1649).
--define(wxListBox_GetSelections, 1650).
--define(wxListBox_InsertItems, 1651).
--define(wxListBox_IsSelected, 1652).
--define(wxListBox_Set, 1653).
--define(wxListBox_HitTest, 1654).
--define(wxListBox_SetFirstItem_1_0, 1655).
--define(wxListBox_SetFirstItem_1_1, 1656).
--define(wxListCtrl_new_0, 1657).
--define(wxListCtrl_new_2, 1658).
--define(wxListCtrl_Arrange, 1659).
--define(wxListCtrl_AssignImageList, 1660).
--define(wxListCtrl_ClearAll, 1661).
--define(wxListCtrl_Create, 1662).
--define(wxListCtrl_DeleteAllItems, 1663).
--define(wxListCtrl_DeleteColumn, 1664).
--define(wxListCtrl_DeleteItem, 1665).
--define(wxListCtrl_EditLabel, 1666).
--define(wxListCtrl_EnsureVisible, 1667).
--define(wxListCtrl_FindItem_3_0, 1668).
--define(wxListCtrl_FindItem_3_1, 1669).
--define(wxListCtrl_GetColumn, 1670).
--define(wxListCtrl_GetColumnCount, 1671).
--define(wxListCtrl_GetColumnWidth, 1672).
--define(wxListCtrl_GetCountPerPage, 1673).
--define(wxListCtrl_GetEditControl, 1674).
--define(wxListCtrl_GetImageList, 1675).
--define(wxListCtrl_GetItem, 1676).
--define(wxListCtrl_GetItemBackgroundColour, 1677).
--define(wxListCtrl_GetItemCount, 1678).
--define(wxListCtrl_GetItemData, 1679).
--define(wxListCtrl_GetItemFont, 1680).
--define(wxListCtrl_GetItemPosition, 1681).
--define(wxListCtrl_GetItemRect, 1682).
--define(wxListCtrl_GetItemSpacing, 1683).
--define(wxListCtrl_GetItemState, 1684).
--define(wxListCtrl_GetItemText, 1685).
--define(wxListCtrl_GetItemTextColour, 1686).
--define(wxListCtrl_GetNextItem, 1687).
--define(wxListCtrl_GetSelectedItemCount, 1688).
--define(wxListCtrl_GetTextColour, 1689).
--define(wxListCtrl_GetTopItem, 1690).
--define(wxListCtrl_GetViewRect, 1691).
--define(wxListCtrl_HitTest, 1692).
--define(wxListCtrl_InsertColumn_2, 1693).
--define(wxListCtrl_InsertColumn_3, 1694).
--define(wxListCtrl_InsertItem_1, 1695).
--define(wxListCtrl_InsertItem_2_1, 1696).
--define(wxListCtrl_InsertItem_2_0, 1697).
--define(wxListCtrl_InsertItem_3, 1698).
--define(wxListCtrl_RefreshItem, 1699).
--define(wxListCtrl_RefreshItems, 1700).
--define(wxListCtrl_ScrollList, 1701).
--define(wxListCtrl_SetBackgroundColour, 1702).
--define(wxListCtrl_SetColumn, 1703).
--define(wxListCtrl_SetColumnWidth, 1704).
--define(wxListCtrl_SetImageList, 1705).
--define(wxListCtrl_SetItem_1, 1706).
--define(wxListCtrl_SetItem_4, 1707).
--define(wxListCtrl_SetItemBackgroundColour, 1708).
--define(wxListCtrl_SetItemCount, 1709).
--define(wxListCtrl_SetItemData, 1710).
--define(wxListCtrl_SetItemFont, 1711).
--define(wxListCtrl_SetItemImage, 1712).
--define(wxListCtrl_SetItemColumnImage, 1713).
--define(wxListCtrl_SetItemPosition, 1714).
--define(wxListCtrl_SetItemState, 1715).
--define(wxListCtrl_SetItemText, 1716).
--define(wxListCtrl_SetItemTextColour, 1717).
--define(wxListCtrl_SetSingleStyle, 1718).
--define(wxListCtrl_SetTextColour, 1719).
--define(wxListCtrl_SetWindowStyleFlag, 1720).
--define(wxListCtrl_SortItems, 1721).
--define(wxListCtrl_destroy, 1722).
--define(wxListView_ClearColumnImage, 1723).
--define(wxListView_Focus, 1724).
--define(wxListView_GetFirstSelected, 1725).
--define(wxListView_GetFocusedItem, 1726).
--define(wxListView_GetNextSelected, 1727).
--define(wxListView_IsSelected, 1728).
--define(wxListView_Select, 1729).
--define(wxListView_SetColumnImage, 1730).
--define(wxListItem_new_0, 1731).
--define(wxListItem_new_1, 1732).
--define(wxListItem_destruct, 1733).
--define(wxListItem_Clear, 1734).
--define(wxListItem_GetAlign, 1735).
--define(wxListItem_GetBackgroundColour, 1736).
--define(wxListItem_GetColumn, 1737).
--define(wxListItem_GetFont, 1738).
--define(wxListItem_GetId, 1739).
--define(wxListItem_GetImage, 1740).
--define(wxListItem_GetMask, 1741).
--define(wxListItem_GetState, 1742).
--define(wxListItem_GetText, 1743).
--define(wxListItem_GetTextColour, 1744).
--define(wxListItem_GetWidth, 1745).
--define(wxListItem_SetAlign, 1746).
--define(wxListItem_SetBackgroundColour, 1747).
--define(wxListItem_SetColumn, 1748).
--define(wxListItem_SetFont, 1749).
--define(wxListItem_SetId, 1750).
--define(wxListItem_SetImage, 1751).
--define(wxListItem_SetMask, 1752).
--define(wxListItem_SetState, 1753).
--define(wxListItem_SetStateMask, 1754).
--define(wxListItem_SetText, 1755).
--define(wxListItem_SetTextColour, 1756).
--define(wxListItem_SetWidth, 1757).
--define(wxListItemAttr_new_0, 1758).
--define(wxListItemAttr_new_3, 1759).
--define(wxListItemAttr_GetBackgroundColour, 1760).
--define(wxListItemAttr_GetFont, 1761).
--define(wxListItemAttr_GetTextColour, 1762).
--define(wxListItemAttr_HasBackgroundColour, 1763).
--define(wxListItemAttr_HasFont, 1764).
--define(wxListItemAttr_HasTextColour, 1765).
--define(wxListItemAttr_SetBackgroundColour, 1766).
--define(wxListItemAttr_SetFont, 1767).
--define(wxListItemAttr_SetTextColour, 1768).
--define(wxListItemAttr_destroy, 1769).
--define(wxImageList_new_0, 1770).
--define(wxImageList_new_3, 1771).
--define(wxImageList_Add_1, 1772).
--define(wxImageList_Add_2_0, 1773).
--define(wxImageList_Add_2_1, 1774).
--define(wxImageList_Create, 1775).
--define(wxImageList_Draw, 1777).
--define(wxImageList_GetBitmap, 1778).
--define(wxImageList_GetIcon, 1779).
--define(wxImageList_GetImageCount, 1780).
--define(wxImageList_GetSize, 1781).
--define(wxImageList_Remove, 1782).
--define(wxImageList_RemoveAll, 1783).
--define(wxImageList_Replace_2, 1784).
--define(wxImageList_Replace_3, 1785).
--define(wxImageList_destroy, 1786).
--define(wxTextAttr_new_0, 1787).
--define(wxTextAttr_new_2, 1788).
--define(wxTextAttr_GetAlignment, 1789).
--define(wxTextAttr_GetBackgroundColour, 1790).
--define(wxTextAttr_GetFont, 1791).
--define(wxTextAttr_GetLeftIndent, 1792).
--define(wxTextAttr_GetLeftSubIndent, 1793).
--define(wxTextAttr_GetRightIndent, 1794).
--define(wxTextAttr_GetTabs, 1795).
--define(wxTextAttr_GetTextColour, 1796).
--define(wxTextAttr_HasBackgroundColour, 1797).
--define(wxTextAttr_HasFont, 1798).
--define(wxTextAttr_HasTextColour, 1799).
--define(wxTextAttr_GetFlags, 1800).
--define(wxTextAttr_IsDefault, 1801).
--define(wxTextAttr_SetAlignment, 1802).
--define(wxTextAttr_SetBackgroundColour, 1803).
--define(wxTextAttr_SetFlags, 1804).
--define(wxTextAttr_SetFont, 1805).
--define(wxTextAttr_SetLeftIndent, 1806).
--define(wxTextAttr_SetRightIndent, 1807).
--define(wxTextAttr_SetTabs, 1808).
--define(wxTextAttr_SetTextColour, 1809).
--define(wxTextAttr_destroy, 1810).
--define(wxTextCtrl_new_3, 1812).
--define(wxTextCtrl_new_0, 1813).
--define(wxTextCtrl_destruct, 1815).
--define(wxTextCtrl_AppendText, 1816).
--define(wxTextCtrl_CanCopy, 1817).
--define(wxTextCtrl_CanCut, 1818).
--define(wxTextCtrl_CanPaste, 1819).
--define(wxTextCtrl_CanRedo, 1820).
--define(wxTextCtrl_CanUndo, 1821).
--define(wxTextCtrl_Clear, 1822).
--define(wxTextCtrl_Copy, 1823).
--define(wxTextCtrl_Create, 1824).
--define(wxTextCtrl_Cut, 1825).
--define(wxTextCtrl_DiscardEdits, 1826).
--define(wxTextCtrl_ChangeValue, 1827).
--define(wxTextCtrl_EmulateKeyPress, 1828).
--define(wxTextCtrl_GetDefaultStyle, 1829).
--define(wxTextCtrl_GetInsertionPoint, 1830).
--define(wxTextCtrl_GetLastPosition, 1831).
--define(wxTextCtrl_GetLineLength, 1832).
--define(wxTextCtrl_GetLineText, 1833).
--define(wxTextCtrl_GetNumberOfLines, 1834).
--define(wxTextCtrl_GetRange, 1835).
--define(wxTextCtrl_GetSelection, 1836).
--define(wxTextCtrl_GetStringSelection, 1837).
--define(wxTextCtrl_GetStyle, 1838).
--define(wxTextCtrl_GetValue, 1839).
--define(wxTextCtrl_IsEditable, 1840).
--define(wxTextCtrl_IsModified, 1841).
--define(wxTextCtrl_IsMultiLine, 1842).
--define(wxTextCtrl_IsSingleLine, 1843).
--define(wxTextCtrl_LoadFile, 1844).
--define(wxTextCtrl_MarkDirty, 1845).
--define(wxTextCtrl_Paste, 1846).
--define(wxTextCtrl_PositionToXY, 1847).
--define(wxTextCtrl_Redo, 1848).
--define(wxTextCtrl_Remove, 1849).
--define(wxTextCtrl_Replace, 1850).
--define(wxTextCtrl_SaveFile, 1851).
--define(wxTextCtrl_SetDefaultStyle, 1852).
--define(wxTextCtrl_SetEditable, 1853).
--define(wxTextCtrl_SetInsertionPoint, 1854).
--define(wxTextCtrl_SetInsertionPointEnd, 1855).
--define(wxTextCtrl_SetMaxLength, 1857).
--define(wxTextCtrl_SetSelection, 1858).
--define(wxTextCtrl_SetStyle, 1859).
--define(wxTextCtrl_SetValue, 1860).
--define(wxTextCtrl_ShowPosition, 1861).
--define(wxTextCtrl_Undo, 1862).
--define(wxTextCtrl_WriteText, 1863).
--define(wxTextCtrl_XYToPosition, 1864).
--define(wxNotebook_new_0, 1867).
--define(wxNotebook_new_3, 1868).
--define(wxNotebook_destruct, 1869).
--define(wxNotebook_AddPage, 1870).
--define(wxNotebook_AdvanceSelection, 1871).
--define(wxNotebook_AssignImageList, 1872).
--define(wxNotebook_Create, 1873).
--define(wxNotebook_DeleteAllPages, 1874).
--define(wxNotebook_DeletePage, 1875).
--define(wxNotebook_RemovePage, 1876).
--define(wxNotebook_GetCurrentPage, 1877).
--define(wxNotebook_GetImageList, 1878).
--define(wxNotebook_GetPage, 1880).
--define(wxNotebook_GetPageCount, 1881).
--define(wxNotebook_GetPageImage, 1882).
--define(wxNotebook_GetPageText, 1883).
--define(wxNotebook_GetRowCount, 1884).
--define(wxNotebook_GetSelection, 1885).
--define(wxNotebook_GetThemeBackgroundColour, 1886).
--define(wxNotebook_HitTest, 1888).
--define(wxNotebook_InsertPage, 1890).
--define(wxNotebook_SetImageList, 1891).
--define(wxNotebook_SetPadding, 1892).
--define(wxNotebook_SetPageSize, 1893).
--define(wxNotebook_SetPageImage, 1894).
--define(wxNotebook_SetPageText, 1895).
--define(wxNotebook_SetSelection, 1896).
--define(wxNotebook_ChangeSelection, 1897).
--define(wxChoicebook_new_0, 1898).
--define(wxChoicebook_new_3, 1899).
--define(wxChoicebook_AddPage, 1900).
--define(wxChoicebook_AdvanceSelection, 1901).
--define(wxChoicebook_AssignImageList, 1902).
--define(wxChoicebook_Create, 1903).
--define(wxChoicebook_DeleteAllPages, 1904).
--define(wxChoicebook_DeletePage, 1905).
--define(wxChoicebook_RemovePage, 1906).
--define(wxChoicebook_GetCurrentPage, 1907).
--define(wxChoicebook_GetImageList, 1908).
--define(wxChoicebook_GetPage, 1910).
--define(wxChoicebook_GetPageCount, 1911).
--define(wxChoicebook_GetPageImage, 1912).
--define(wxChoicebook_GetPageText, 1913).
--define(wxChoicebook_GetSelection, 1914).
--define(wxChoicebook_HitTest, 1915).
--define(wxChoicebook_InsertPage, 1916).
--define(wxChoicebook_SetImageList, 1917).
--define(wxChoicebook_SetPageSize, 1918).
--define(wxChoicebook_SetPageImage, 1919).
--define(wxChoicebook_SetPageText, 1920).
--define(wxChoicebook_SetSelection, 1921).
--define(wxChoicebook_ChangeSelection, 1922).
--define(wxChoicebook_destroy, 1923).
--define(wxToolbook_new_0, 1924).
--define(wxToolbook_new_3, 1925).
--define(wxToolbook_AddPage, 1926).
--define(wxToolbook_AdvanceSelection, 1927).
--define(wxToolbook_AssignImageList, 1928).
--define(wxToolbook_Create, 1929).
--define(wxToolbook_DeleteAllPages, 1930).
--define(wxToolbook_DeletePage, 1931).
--define(wxToolbook_RemovePage, 1932).
--define(wxToolbook_GetCurrentPage, 1933).
--define(wxToolbook_GetImageList, 1934).
--define(wxToolbook_GetPage, 1936).
--define(wxToolbook_GetPageCount, 1937).
--define(wxToolbook_GetPageImage, 1938).
--define(wxToolbook_GetPageText, 1939).
--define(wxToolbook_GetSelection, 1940).
--define(wxToolbook_HitTest, 1942).
--define(wxToolbook_InsertPage, 1943).
--define(wxToolbook_SetImageList, 1944).
--define(wxToolbook_SetPageSize, 1945).
--define(wxToolbook_SetPageImage, 1946).
--define(wxToolbook_SetPageText, 1947).
--define(wxToolbook_SetSelection, 1948).
--define(wxToolbook_ChangeSelection, 1949).
--define(wxToolbook_destroy, 1950).
--define(wxListbook_new_0, 1951).
--define(wxListbook_new_3, 1952).
--define(wxListbook_AddPage, 1953).
--define(wxListbook_AdvanceSelection, 1954).
--define(wxListbook_AssignImageList, 1955).
--define(wxListbook_Create, 1956).
--define(wxListbook_DeleteAllPages, 1957).
--define(wxListbook_DeletePage, 1958).
--define(wxListbook_RemovePage, 1959).
--define(wxListbook_GetCurrentPage, 1960).
--define(wxListbook_GetImageList, 1961).
--define(wxListbook_GetPage, 1963).
--define(wxListbook_GetPageCount, 1964).
--define(wxListbook_GetPageImage, 1965).
--define(wxListbook_GetPageText, 1966).
--define(wxListbook_GetSelection, 1967).
--define(wxListbook_HitTest, 1969).
--define(wxListbook_InsertPage, 1970).
--define(wxListbook_SetImageList, 1971).
--define(wxListbook_SetPageSize, 1972).
--define(wxListbook_SetPageImage, 1973).
--define(wxListbook_SetPageText, 1974).
--define(wxListbook_SetSelection, 1975).
--define(wxListbook_ChangeSelection, 1976).
--define(wxListbook_destroy, 1977).
--define(wxTreebook_new_0, 1978).
--define(wxTreebook_new_3, 1979).
--define(wxTreebook_AddPage, 1980).
--define(wxTreebook_AdvanceSelection, 1981).
--define(wxTreebook_AssignImageList, 1982).
--define(wxTreebook_Create, 1983).
--define(wxTreebook_DeleteAllPages, 1984).
--define(wxTreebook_DeletePage, 1985).
--define(wxTreebook_RemovePage, 1986).
--define(wxTreebook_GetCurrentPage, 1987).
--define(wxTreebook_GetImageList, 1988).
--define(wxTreebook_GetPage, 1990).
--define(wxTreebook_GetPageCount, 1991).
--define(wxTreebook_GetPageImage, 1992).
--define(wxTreebook_GetPageText, 1993).
--define(wxTreebook_GetSelection, 1994).
--define(wxTreebook_ExpandNode, 1995).
--define(wxTreebook_IsNodeExpanded, 1996).
--define(wxTreebook_HitTest, 1998).
--define(wxTreebook_InsertPage, 1999).
--define(wxTreebook_InsertSubPage, 2000).
--define(wxTreebook_SetImageList, 2001).
--define(wxTreebook_SetPageSize, 2002).
--define(wxTreebook_SetPageImage, 2003).
--define(wxTreebook_SetPageText, 2004).
--define(wxTreebook_SetSelection, 2005).
--define(wxTreebook_ChangeSelection, 2006).
--define(wxTreebook_destroy, 2007).
--define(wxTreeCtrl_new_2, 2010).
--define(wxTreeCtrl_new_0, 2011).
--define(wxTreeCtrl_destruct, 2013).
--define(wxTreeCtrl_AddRoot, 2014).
--define(wxTreeCtrl_AppendItem, 2015).
--define(wxTreeCtrl_AssignImageList, 2016).
--define(wxTreeCtrl_AssignStateImageList, 2017).
--define(wxTreeCtrl_Collapse, 2018).
--define(wxTreeCtrl_CollapseAndReset, 2019).
--define(wxTreeCtrl_Create, 2020).
--define(wxTreeCtrl_Delete, 2021).
--define(wxTreeCtrl_DeleteAllItems, 2022).
--define(wxTreeCtrl_DeleteChildren, 2023).
--define(wxTreeCtrl_EditLabel, 2024).
--define(wxTreeCtrl_EnsureVisible, 2025).
--define(wxTreeCtrl_Expand, 2026).
--define(wxTreeCtrl_GetBoundingRect, 2027).
--define(wxTreeCtrl_GetChildrenCount, 2029).
--define(wxTreeCtrl_GetCount, 2030).
--define(wxTreeCtrl_GetEditControl, 2031).
--define(wxTreeCtrl_GetFirstChild, 2032).
--define(wxTreeCtrl_GetNextChild, 2033).
--define(wxTreeCtrl_GetFirstVisibleItem, 2034).
--define(wxTreeCtrl_GetImageList, 2035).
--define(wxTreeCtrl_GetIndent, 2036).
--define(wxTreeCtrl_GetItemBackgroundColour, 2037).
--define(wxTreeCtrl_GetItemData, 2038).
--define(wxTreeCtrl_GetItemFont, 2039).
--define(wxTreeCtrl_GetItemImage_1, 2040).
--define(wxTreeCtrl_GetItemImage_2, 2041).
--define(wxTreeCtrl_GetItemText, 2042).
--define(wxTreeCtrl_GetItemTextColour, 2043).
--define(wxTreeCtrl_GetLastChild, 2044).
--define(wxTreeCtrl_GetNextSibling, 2045).
--define(wxTreeCtrl_GetNextVisible, 2046).
--define(wxTreeCtrl_GetItemParent, 2047).
--define(wxTreeCtrl_GetPrevSibling, 2048).
--define(wxTreeCtrl_GetPrevVisible, 2049).
--define(wxTreeCtrl_GetRootItem, 2050).
--define(wxTreeCtrl_GetSelection, 2051).
--define(wxTreeCtrl_GetSelections, 2052).
--define(wxTreeCtrl_GetStateImageList, 2053).
--define(wxTreeCtrl_HitTest, 2054).
--define(wxTreeCtrl_InsertItem, 2056).
--define(wxTreeCtrl_IsBold, 2057).
--define(wxTreeCtrl_IsExpanded, 2058).
--define(wxTreeCtrl_IsSelected, 2059).
--define(wxTreeCtrl_IsVisible, 2060).
--define(wxTreeCtrl_ItemHasChildren, 2061).
--define(wxTreeCtrl_IsTreeItemIdOk, 2062).
--define(wxTreeCtrl_PrependItem, 2063).
--define(wxTreeCtrl_ScrollTo, 2064).
--define(wxTreeCtrl_SelectItem_1, 2065).
--define(wxTreeCtrl_SelectItem_2, 2066).
--define(wxTreeCtrl_SetIndent, 2067).
--define(wxTreeCtrl_SetImageList, 2068).
--define(wxTreeCtrl_SetItemBackgroundColour, 2069).
--define(wxTreeCtrl_SetItemBold, 2070).
--define(wxTreeCtrl_SetItemData, 2071).
--define(wxTreeCtrl_SetItemDropHighlight, 2072).
--define(wxTreeCtrl_SetItemFont, 2073).
--define(wxTreeCtrl_SetItemHasChildren, 2074).
--define(wxTreeCtrl_SetItemImage_2, 2075).
--define(wxTreeCtrl_SetItemImage_3, 2076).
--define(wxTreeCtrl_SetItemText, 2077).
--define(wxTreeCtrl_SetItemTextColour, 2078).
--define(wxTreeCtrl_SetStateImageList, 2079).
--define(wxTreeCtrl_SetWindowStyle, 2080).
--define(wxTreeCtrl_SortChildren, 2081).
--define(wxTreeCtrl_Toggle, 2082).
--define(wxTreeCtrl_ToggleItemSelection, 2083).
--define(wxTreeCtrl_Unselect, 2084).
--define(wxTreeCtrl_UnselectAll, 2085).
--define(wxTreeCtrl_UnselectItem, 2086).
--define(wxScrollBar_new_0, 2087).
--define(wxScrollBar_new_3, 2088).
--define(wxScrollBar_destruct, 2089).
--define(wxScrollBar_Create, 2090).
--define(wxScrollBar_GetRange, 2091).
--define(wxScrollBar_GetPageSize, 2092).
--define(wxScrollBar_GetThumbPosition, 2093).
--define(wxScrollBar_GetThumbSize, 2094).
--define(wxScrollBar_SetThumbPosition, 2095).
--define(wxScrollBar_SetScrollbar, 2096).
--define(wxSpinButton_new_2, 2098).
--define(wxSpinButton_new_0, 2099).
--define(wxSpinButton_Create, 2100).
--define(wxSpinButton_GetMax, 2101).
--define(wxSpinButton_GetMin, 2102).
--define(wxSpinButton_GetValue, 2103).
--define(wxSpinButton_SetRange, 2104).
--define(wxSpinButton_SetValue, 2105).
--define(wxSpinButton_destroy, 2106).
--define(wxSpinCtrl_new_0, 2107).
--define(wxSpinCtrl_new_2, 2108).
--define(wxSpinCtrl_Create, 2110).
--define(wxSpinCtrl_SetValue_1_1, 2113).
--define(wxSpinCtrl_SetValue_1_0, 2114).
--define(wxSpinCtrl_GetValue, 2116).
--define(wxSpinCtrl_SetRange, 2118).
--define(wxSpinCtrl_SetSelection, 2119).
--define(wxSpinCtrl_GetMin, 2121).
--define(wxSpinCtrl_GetMax, 2123).
--define(wxSpinCtrl_destroy, 2124).
--define(wxStaticText_new_0, 2125).
--define(wxStaticText_new_4, 2126).
--define(wxStaticText_Create, 2127).
--define(wxStaticText_GetLabel, 2128).
--define(wxStaticText_SetLabel, 2129).
--define(wxStaticText_Wrap, 2130).
--define(wxStaticText_destroy, 2131).
--define(wxStaticBitmap_new_0, 2132).
--define(wxStaticBitmap_new_4, 2133).
--define(wxStaticBitmap_Create, 2134).
--define(wxStaticBitmap_GetBitmap, 2135).
--define(wxStaticBitmap_SetBitmap, 2136).
--define(wxStaticBitmap_destroy, 2137).
--define(wxRadioBox_new, 2138).
--define(wxRadioBox_destruct, 2140).
--define(wxRadioBox_Create, 2141).
--define(wxRadioBox_Enable_2, 2142).
--define(wxRadioBox_Enable_1, 2143).
--define(wxRadioBox_GetSelection, 2144).
--define(wxRadioBox_GetString, 2145).
--define(wxRadioBox_SetSelection, 2146).
--define(wxRadioBox_Show_2, 2147).
--define(wxRadioBox_Show_1, 2148).
--define(wxRadioBox_GetColumnCount, 2149).
--define(wxRadioBox_GetItemHelpText, 2150).
--define(wxRadioBox_GetItemToolTip, 2151).
--define(wxRadioBox_GetItemFromPoint, 2153).
--define(wxRadioBox_GetRowCount, 2154).
--define(wxRadioBox_IsItemEnabled, 2155).
--define(wxRadioBox_IsItemShown, 2156).
--define(wxRadioBox_SetItemHelpText, 2157).
--define(wxRadioBox_SetItemToolTip, 2158).
--define(wxRadioButton_new_0, 2159).
--define(wxRadioButton_new_4, 2160).
--define(wxRadioButton_Create, 2161).
--define(wxRadioButton_GetValue, 2162).
--define(wxRadioButton_SetValue, 2163).
--define(wxRadioButton_destroy, 2164).
--define(wxSlider_new_6, 2166).
--define(wxSlider_new_0, 2167).
--define(wxSlider_Create, 2168).
--define(wxSlider_GetLineSize, 2169).
--define(wxSlider_GetMax, 2170).
--define(wxSlider_GetMin, 2171).
--define(wxSlider_GetPageSize, 2172).
--define(wxSlider_GetThumbLength, 2173).
--define(wxSlider_GetValue, 2174).
--define(wxSlider_SetLineSize, 2175).
--define(wxSlider_SetPageSize, 2176).
--define(wxSlider_SetRange, 2177).
--define(wxSlider_SetThumbLength, 2178).
--define(wxSlider_SetValue, 2179).
--define(wxSlider_destroy, 2180).
--define(wxDialog_new_4, 2182).
--define(wxDialog_new_0, 2183).
--define(wxDialog_destruct, 2185).
--define(wxDialog_Create, 2186).
--define(wxDialog_CreateButtonSizer, 2187).
--define(wxDialog_CreateStdDialogButtonSizer, 2188).
--define(wxDialog_EndModal, 2189).
--define(wxDialog_GetAffirmativeId, 2190).
--define(wxDialog_GetReturnCode, 2191).
--define(wxDialog_IsModal, 2192).
--define(wxDialog_SetAffirmativeId, 2193).
--define(wxDialog_SetReturnCode, 2194).
--define(wxDialog_Show, 2195).
--define(wxDialog_ShowModal, 2196).
--define(wxColourDialog_new_0, 2197).
--define(wxColourDialog_new_2, 2198).
--define(wxColourDialog_destruct, 2199).
--define(wxColourDialog_Create, 2200).
--define(wxColourDialog_GetColourData, 2201).
--define(wxColourData_new_0, 2202).
--define(wxColourData_new_1, 2203).
--define(wxColourData_destruct, 2204).
--define(wxColourData_GetChooseFull, 2205).
--define(wxColourData_GetColour, 2206).
--define(wxColourData_GetCustomColour, 2208).
--define(wxColourData_SetChooseFull, 2209).
--define(wxColourData_SetColour, 2210).
--define(wxColourData_SetCustomColour, 2211).
--define(wxPalette_new_0, 2212).
--define(wxPalette_new_4, 2213).
--define(wxPalette_destruct, 2215).
--define(wxPalette_Create, 2216).
--define(wxPalette_GetColoursCount, 2217).
--define(wxPalette_GetPixel, 2218).
--define(wxPalette_GetRGB, 2219).
--define(wxPalette_IsOk, 2220).
--define(wxDirDialog_new, 2224).
--define(wxDirDialog_destruct, 2225).
--define(wxDirDialog_GetPath, 2226).
--define(wxDirDialog_GetMessage, 2227).
--define(wxDirDialog_SetMessage, 2228).
--define(wxDirDialog_SetPath, 2229).
--define(wxFileDialog_new, 2233).
--define(wxFileDialog_destruct, 2234).
--define(wxFileDialog_GetDirectory, 2235).
--define(wxFileDialog_GetFilename, 2236).
--define(wxFileDialog_GetFilenames, 2237).
--define(wxFileDialog_GetFilterIndex, 2238).
--define(wxFileDialog_GetMessage, 2239).
--define(wxFileDialog_GetPath, 2240).
--define(wxFileDialog_GetPaths, 2241).
--define(wxFileDialog_GetWildcard, 2242).
--define(wxFileDialog_SetDirectory, 2243).
--define(wxFileDialog_SetFilename, 2244).
--define(wxFileDialog_SetFilterIndex, 2245).
--define(wxFileDialog_SetMessage, 2246).
--define(wxFileDialog_SetPath, 2247).
--define(wxFileDialog_SetWildcard, 2248).
--define(wxPickerBase_SetInternalMargin, 2249).
--define(wxPickerBase_GetInternalMargin, 2250).
--define(wxPickerBase_SetTextCtrlProportion, 2251).
--define(wxPickerBase_SetPickerCtrlProportion, 2252).
--define(wxPickerBase_GetTextCtrlProportion, 2253).
--define(wxPickerBase_GetPickerCtrlProportion, 2254).
--define(wxPickerBase_HasTextCtrl, 2255).
--define(wxPickerBase_GetTextCtrl, 2256).
--define(wxPickerBase_IsTextCtrlGrowable, 2257).
--define(wxPickerBase_SetPickerCtrlGrowable, 2258).
--define(wxPickerBase_SetTextCtrlGrowable, 2259).
--define(wxPickerBase_IsPickerCtrlGrowable, 2260).
--define(wxFilePickerCtrl_new_0, 2261).
--define(wxFilePickerCtrl_new_3, 2262).
--define(wxFilePickerCtrl_Create, 2263).
--define(wxFilePickerCtrl_GetPath, 2264).
--define(wxFilePickerCtrl_SetPath, 2265).
--define(wxFilePickerCtrl_destroy, 2266).
--define(wxDirPickerCtrl_new_0, 2267).
--define(wxDirPickerCtrl_new_3, 2268).
--define(wxDirPickerCtrl_Create, 2269).
--define(wxDirPickerCtrl_GetPath, 2270).
--define(wxDirPickerCtrl_SetPath, 2271).
--define(wxDirPickerCtrl_destroy, 2272).
--define(wxColourPickerCtrl_new_0, 2273).
--define(wxColourPickerCtrl_new_3, 2274).
--define(wxColourPickerCtrl_Create, 2275).
--define(wxColourPickerCtrl_GetColour, 2276).
--define(wxColourPickerCtrl_SetColour_1_1, 2277).
--define(wxColourPickerCtrl_SetColour_1_0, 2278).
--define(wxColourPickerCtrl_destroy, 2279).
--define(wxDatePickerCtrl_new_0, 2280).
--define(wxDatePickerCtrl_new_3, 2281).
--define(wxDatePickerCtrl_GetRange, 2282).
--define(wxDatePickerCtrl_GetValue, 2283).
--define(wxDatePickerCtrl_SetRange, 2284).
--define(wxDatePickerCtrl_SetValue, 2285).
--define(wxDatePickerCtrl_destroy, 2286).
--define(wxFontPickerCtrl_new_0, 2287).
--define(wxFontPickerCtrl_new_3, 2288).
--define(wxFontPickerCtrl_Create, 2289).
--define(wxFontPickerCtrl_GetSelectedFont, 2290).
--define(wxFontPickerCtrl_SetSelectedFont, 2291).
--define(wxFontPickerCtrl_GetMaxPointSize, 2292).
--define(wxFontPickerCtrl_SetMaxPointSize, 2293).
--define(wxFontPickerCtrl_destroy, 2294).
--define(wxFindReplaceDialog_new_0, 2297).
--define(wxFindReplaceDialog_new_4, 2298).
--define(wxFindReplaceDialog_destruct, 2299).
--define(wxFindReplaceDialog_Create, 2300).
--define(wxFindReplaceDialog_GetData, 2301).
--define(wxFindReplaceData_new_0, 2302).
--define(wxFindReplaceData_new_1, 2303).
--define(wxFindReplaceData_GetFindString, 2304).
--define(wxFindReplaceData_GetReplaceString, 2305).
--define(wxFindReplaceData_GetFlags, 2306).
--define(wxFindReplaceData_SetFlags, 2307).
--define(wxFindReplaceData_SetFindString, 2308).
--define(wxFindReplaceData_SetReplaceString, 2309).
--define(wxFindReplaceData_destroy, 2310).
--define(wxMultiChoiceDialog_new_0, 2311).
--define(wxMultiChoiceDialog_new_5, 2313).
--define(wxMultiChoiceDialog_GetSelections, 2314).
--define(wxMultiChoiceDialog_SetSelections, 2315).
--define(wxMultiChoiceDialog_destroy, 2316).
--define(wxSingleChoiceDialog_new_0, 2317).
--define(wxSingleChoiceDialog_new_5, 2319).
--define(wxSingleChoiceDialog_GetSelection, 2320).
--define(wxSingleChoiceDialog_GetStringSelection, 2321).
--define(wxSingleChoiceDialog_SetSelection, 2322).
--define(wxSingleChoiceDialog_destroy, 2323).
--define(wxTextEntryDialog_new, 2324).
--define(wxTextEntryDialog_GetValue, 2325).
--define(wxTextEntryDialog_SetValue, 2326).
--define(wxTextEntryDialog_destroy, 2327).
--define(wxPasswordEntryDialog_new, 2328).
--define(wxPasswordEntryDialog_destroy, 2329).
--define(wxFontData_new_0, 2330).
--define(wxFontData_new_1, 2331).
--define(wxFontData_destruct, 2332).
--define(wxFontData_EnableEffects, 2333).
--define(wxFontData_GetAllowSymbols, 2334).
--define(wxFontData_GetColour, 2335).
--define(wxFontData_GetChosenFont, 2336).
--define(wxFontData_GetEnableEffects, 2337).
--define(wxFontData_GetInitialFont, 2338).
--define(wxFontData_GetShowHelp, 2339).
--define(wxFontData_SetAllowSymbols, 2340).
--define(wxFontData_SetChosenFont, 2341).
--define(wxFontData_SetColour, 2342).
--define(wxFontData_SetInitialFont, 2343).
--define(wxFontData_SetRange, 2344).
--define(wxFontData_SetShowHelp, 2345).
--define(wxFontDialog_new_0, 2349).
--define(wxFontDialog_new_2, 2351).
--define(wxFontDialog_Create, 2353).
--define(wxFontDialog_GetFontData, 2354).
--define(wxFontDialog_destroy, 2356).
--define(wxProgressDialog_new, 2357).
--define(wxProgressDialog_destruct, 2358).
--define(wxProgressDialog_Resume, 2359).
--define(wxProgressDialog_Update_2, 2360).
--define(wxProgressDialog_Update_0, 2361).
--define(wxMessageDialog_new, 2362).
--define(wxMessageDialog_destruct, 2363).
--define(wxPageSetupDialog_new, 2364).
--define(wxPageSetupDialog_destruct, 2365).
--define(wxPageSetupDialog_GetPageSetupData, 2366).
--define(wxPageSetupDialog_ShowModal, 2367).
--define(wxPageSetupDialogData_new_0, 2368).
--define(wxPageSetupDialogData_new_1_0, 2369).
--define(wxPageSetupDialogData_new_1_1, 2370).
--define(wxPageSetupDialogData_destruct, 2371).
--define(wxPageSetupDialogData_EnableHelp, 2372).
--define(wxPageSetupDialogData_EnableMargins, 2373).
--define(wxPageSetupDialogData_EnableOrientation, 2374).
--define(wxPageSetupDialogData_EnablePaper, 2375).
--define(wxPageSetupDialogData_EnablePrinter, 2376).
--define(wxPageSetupDialogData_GetDefaultMinMargins, 2377).
--define(wxPageSetupDialogData_GetEnableMargins, 2378).
--define(wxPageSetupDialogData_GetEnableOrientation, 2379).
--define(wxPageSetupDialogData_GetEnablePaper, 2380).
--define(wxPageSetupDialogData_GetEnablePrinter, 2381).
--define(wxPageSetupDialogData_GetEnableHelp, 2382).
--define(wxPageSetupDialogData_GetDefaultInfo, 2383).
--define(wxPageSetupDialogData_GetMarginTopLeft, 2384).
--define(wxPageSetupDialogData_GetMarginBottomRight, 2385).
--define(wxPageSetupDialogData_GetMinMarginTopLeft, 2386).
--define(wxPageSetupDialogData_GetMinMarginBottomRight, 2387).
--define(wxPageSetupDialogData_GetPaperId, 2388).
--define(wxPageSetupDialogData_GetPaperSize, 2389).
--define(wxPageSetupDialogData_GetPrintData, 2391).
--define(wxPageSetupDialogData_IsOk, 2392).
--define(wxPageSetupDialogData_SetDefaultInfo, 2393).
--define(wxPageSetupDialogData_SetDefaultMinMargins, 2394).
--define(wxPageSetupDialogData_SetMarginTopLeft, 2395).
--define(wxPageSetupDialogData_SetMarginBottomRight, 2396).
--define(wxPageSetupDialogData_SetMinMarginTopLeft, 2397).
--define(wxPageSetupDialogData_SetMinMarginBottomRight, 2398).
--define(wxPageSetupDialogData_SetPaperId, 2399).
--define(wxPageSetupDialogData_SetPaperSize_1_1, 2400).
--define(wxPageSetupDialogData_SetPaperSize_1_0, 2401).
--define(wxPageSetupDialogData_SetPrintData, 2402).
--define(wxPrintDialog_new_2_0, 2403).
--define(wxPrintDialog_new_2_1, 2404).
--define(wxPrintDialog_destruct, 2405).
--define(wxPrintDialog_GetPrintDialogData, 2406).
--define(wxPrintDialog_GetPrintDC, 2407).
--define(wxPrintDialogData_new_0, 2408).
--define(wxPrintDialogData_new_1_1, 2409).
--define(wxPrintDialogData_new_1_0, 2410).
--define(wxPrintDialogData_destruct, 2411).
--define(wxPrintDialogData_EnableHelp, 2412).
--define(wxPrintDialogData_EnablePageNumbers, 2413).
--define(wxPrintDialogData_EnablePrintToFile, 2414).
--define(wxPrintDialogData_EnableSelection, 2415).
--define(wxPrintDialogData_GetAllPages, 2416).
--define(wxPrintDialogData_GetCollate, 2417).
--define(wxPrintDialogData_GetFromPage, 2418).
--define(wxPrintDialogData_GetMaxPage, 2419).
--define(wxPrintDialogData_GetMinPage, 2420).
--define(wxPrintDialogData_GetNoCopies, 2421).
--define(wxPrintDialogData_GetPrintData, 2422).
--define(wxPrintDialogData_GetPrintToFile, 2423).
--define(wxPrintDialogData_GetSelection, 2424).
--define(wxPrintDialogData_GetToPage, 2425).
--define(wxPrintDialogData_IsOk, 2426).
--define(wxPrintDialogData_SetCollate, 2427).
--define(wxPrintDialogData_SetFromPage, 2428).
--define(wxPrintDialogData_SetMaxPage, 2429).
--define(wxPrintDialogData_SetMinPage, 2430).
--define(wxPrintDialogData_SetNoCopies, 2431).
--define(wxPrintDialogData_SetPrintData, 2432).
--define(wxPrintDialogData_SetPrintToFile, 2433).
--define(wxPrintDialogData_SetSelection, 2434).
--define(wxPrintDialogData_SetToPage, 2435).
--define(wxPrintData_new_0, 2436).
--define(wxPrintData_new_1, 2437).
--define(wxPrintData_destruct, 2438).
--define(wxPrintData_GetCollate, 2439).
--define(wxPrintData_GetBin, 2440).
--define(wxPrintData_GetColour, 2441).
--define(wxPrintData_GetDuplex, 2442).
--define(wxPrintData_GetNoCopies, 2443).
--define(wxPrintData_GetOrientation, 2444).
--define(wxPrintData_GetPaperId, 2445).
--define(wxPrintData_GetPrinterName, 2446).
--define(wxPrintData_GetQuality, 2447).
--define(wxPrintData_IsOk, 2448).
--define(wxPrintData_SetBin, 2449).
--define(wxPrintData_SetCollate, 2450).
--define(wxPrintData_SetColour, 2451).
--define(wxPrintData_SetDuplex, 2452).
--define(wxPrintData_SetNoCopies, 2453).
--define(wxPrintData_SetOrientation, 2454).
--define(wxPrintData_SetPaperId, 2455).
--define(wxPrintData_SetPrinterName, 2456).
--define(wxPrintData_SetQuality, 2457).
--define(wxPrintPreview_new_2, 2460).
--define(wxPrintPreview_new_3, 2461).
--define(wxPrintPreview_destruct, 2463).
--define(wxPrintPreview_GetCanvas, 2464).
--define(wxPrintPreview_GetCurrentPage, 2465).
--define(wxPrintPreview_GetFrame, 2466).
--define(wxPrintPreview_GetMaxPage, 2467).
--define(wxPrintPreview_GetMinPage, 2468).
--define(wxPrintPreview_GetPrintout, 2469).
--define(wxPrintPreview_GetPrintoutForPrinting, 2470).
--define(wxPrintPreview_IsOk, 2471).
--define(wxPrintPreview_PaintPage, 2472).
--define(wxPrintPreview_Print, 2473).
--define(wxPrintPreview_RenderPage, 2474).
--define(wxPrintPreview_SetCanvas, 2475).
--define(wxPrintPreview_SetCurrentPage, 2476).
--define(wxPrintPreview_SetFrame, 2477).
--define(wxPrintPreview_SetPrintout, 2478).
--define(wxPrintPreview_SetZoom, 2479).
--define(wxPreviewFrame_new, 2480).
--define(wxPreviewFrame_destruct, 2481).
--define(wxPreviewFrame_CreateControlBar, 2482).
--define(wxPreviewFrame_CreateCanvas, 2483).
--define(wxPreviewFrame_Initialize, 2484).
--define(wxPreviewFrame_OnCloseWindow, 2485).
--define(wxPreviewControlBar_new, 2486).
--define(wxPreviewControlBar_destruct, 2487).
--define(wxPreviewControlBar_CreateButtons, 2488).
--define(wxPreviewControlBar_GetPrintPreview, 2489).
--define(wxPreviewControlBar_GetZoomControl, 2490).
--define(wxPreviewControlBar_SetZoomControl, 2491).
--define(wxPrinter_new, 2493).
--define(wxPrinter_CreateAbortWindow, 2494).
--define(wxPrinter_GetAbort, 2495).
--define(wxPrinter_GetLastError, 2496).
--define(wxPrinter_GetPrintDialogData, 2497).
--define(wxPrinter_Print, 2498).
--define(wxPrinter_PrintDialog, 2499).
--define(wxPrinter_ReportError, 2500).
--define(wxPrinter_Setup, 2501).
--define(wxPrinter_destroy, 2502).
--define(wxXmlResource_new_1, 2503).
--define(wxXmlResource_new_2, 2504).
--define(wxXmlResource_destruct, 2505).
--define(wxXmlResource_AttachUnknownControl, 2506).
--define(wxXmlResource_ClearHandlers, 2507).
--define(wxXmlResource_CompareVersion, 2508).
--define(wxXmlResource_Get, 2509).
--define(wxXmlResource_GetFlags, 2510).
--define(wxXmlResource_GetVersion, 2511).
--define(wxXmlResource_GetXRCID, 2512).
--define(wxXmlResource_InitAllHandlers, 2513).
--define(wxXmlResource_Load, 2514).
--define(wxXmlResource_LoadBitmap, 2515).
--define(wxXmlResource_LoadDialog_2, 2516).
--define(wxXmlResource_LoadDialog_3, 2517).
--define(wxXmlResource_LoadFrame_2, 2518).
--define(wxXmlResource_LoadFrame_3, 2519).
--define(wxXmlResource_LoadIcon, 2520).
--define(wxXmlResource_LoadMenu, 2521).
--define(wxXmlResource_LoadMenuBar_2, 2522).
--define(wxXmlResource_LoadMenuBar_1, 2523).
--define(wxXmlResource_LoadPanel_2, 2524).
--define(wxXmlResource_LoadPanel_3, 2525).
--define(wxXmlResource_LoadToolBar, 2526).
--define(wxXmlResource_Set, 2527).
--define(wxXmlResource_SetFlags, 2528).
--define(wxXmlResource_Unload, 2529).
--define(wxXmlResource_xrcctrl, 2530).
--define(wxHtmlEasyPrinting_new, 2531).
--define(wxHtmlEasyPrinting_destruct, 2532).
--define(wxHtmlEasyPrinting_GetPrintData, 2533).
--define(wxHtmlEasyPrinting_GetPageSetupData, 2534).
--define(wxHtmlEasyPrinting_PreviewFile, 2535).
--define(wxHtmlEasyPrinting_PreviewText, 2536).
--define(wxHtmlEasyPrinting_PrintFile, 2537).
--define(wxHtmlEasyPrinting_PrintText, 2538).
--define(wxHtmlEasyPrinting_PageSetup, 2539).
--define(wxHtmlEasyPrinting_SetFonts, 2540).
--define(wxHtmlEasyPrinting_SetHeader, 2541).
--define(wxHtmlEasyPrinting_SetFooter, 2542).
--define(wxGLCanvas_new_2, 2544).
--define(wxGLCanvas_new_3_1, 2545).
--define(wxGLCanvas_new_3_0, 2546).
--define(wxGLCanvas_GetContext, 2547).
--define(wxGLCanvas_SetCurrent, 2549).
--define(wxGLCanvas_SwapBuffers, 2550).
--define(wxGLCanvas_destroy, 2551).
--define(wxAuiManager_new, 2552).
--define(wxAuiManager_destruct, 2553).
--define(wxAuiManager_AddPane_2_1, 2554).
--define(wxAuiManager_AddPane_3, 2555).
--define(wxAuiManager_AddPane_2_0, 2556).
--define(wxAuiManager_DetachPane, 2557).
--define(wxAuiManager_GetAllPanes, 2558).
--define(wxAuiManager_GetArtProvider, 2559).
--define(wxAuiManager_GetDockSizeConstraint, 2560).
--define(wxAuiManager_GetFlags, 2561).
--define(wxAuiManager_GetManagedWindow, 2562).
--define(wxAuiManager_GetManager, 2563).
--define(wxAuiManager_GetPane_1_1, 2564).
--define(wxAuiManager_GetPane_1_0, 2565).
--define(wxAuiManager_HideHint, 2566).
--define(wxAuiManager_InsertPane, 2567).
--define(wxAuiManager_LoadPaneInfo, 2568).
--define(wxAuiManager_LoadPerspective, 2569).
--define(wxAuiManager_SavePaneInfo, 2570).
--define(wxAuiManager_SavePerspective, 2571).
--define(wxAuiManager_SetArtProvider, 2572).
--define(wxAuiManager_SetDockSizeConstraint, 2573).
--define(wxAuiManager_SetFlags, 2574).
--define(wxAuiManager_SetManagedWindow, 2575).
--define(wxAuiManager_ShowHint, 2576).
--define(wxAuiManager_UnInit, 2577).
--define(wxAuiManager_Update, 2578).
--define(wxAuiPaneInfo_new_0, 2579).
--define(wxAuiPaneInfo_new_1, 2580).
--define(wxAuiPaneInfo_destruct, 2581).
--define(wxAuiPaneInfo_BestSize_1, 2582).
--define(wxAuiPaneInfo_BestSize_2, 2583).
--define(wxAuiPaneInfo_Bottom, 2584).
--define(wxAuiPaneInfo_BottomDockable, 2585).
--define(wxAuiPaneInfo_Caption, 2586).
--define(wxAuiPaneInfo_CaptionVisible, 2587).
--define(wxAuiPaneInfo_Centre, 2588).
--define(wxAuiPaneInfo_CentrePane, 2589).
--define(wxAuiPaneInfo_CloseButton, 2590).
--define(wxAuiPaneInfo_DefaultPane, 2591).
--define(wxAuiPaneInfo_DestroyOnClose, 2592).
--define(wxAuiPaneInfo_Direction, 2593).
--define(wxAuiPaneInfo_Dock, 2594).
--define(wxAuiPaneInfo_Dockable, 2595).
--define(wxAuiPaneInfo_Fixed, 2596).
--define(wxAuiPaneInfo_Float, 2597).
--define(wxAuiPaneInfo_Floatable, 2598).
--define(wxAuiPaneInfo_FloatingPosition_1, 2599).
--define(wxAuiPaneInfo_FloatingPosition_2, 2600).
--define(wxAuiPaneInfo_FloatingSize_1, 2601).
--define(wxAuiPaneInfo_FloatingSize_2, 2602).
--define(wxAuiPaneInfo_Gripper, 2603).
--define(wxAuiPaneInfo_GripperTop, 2604).
--define(wxAuiPaneInfo_HasBorder, 2605).
--define(wxAuiPaneInfo_HasCaption, 2606).
--define(wxAuiPaneInfo_HasCloseButton, 2607).
--define(wxAuiPaneInfo_HasFlag, 2608).
--define(wxAuiPaneInfo_HasGripper, 2609).
--define(wxAuiPaneInfo_HasGripperTop, 2610).
--define(wxAuiPaneInfo_HasMaximizeButton, 2611).
--define(wxAuiPaneInfo_HasMinimizeButton, 2612).
--define(wxAuiPaneInfo_HasPinButton, 2613).
--define(wxAuiPaneInfo_Hide, 2614).
--define(wxAuiPaneInfo_IsBottomDockable, 2615).
--define(wxAuiPaneInfo_IsDocked, 2616).
--define(wxAuiPaneInfo_IsFixed, 2617).
--define(wxAuiPaneInfo_IsFloatable, 2618).
--define(wxAuiPaneInfo_IsFloating, 2619).
--define(wxAuiPaneInfo_IsLeftDockable, 2620).
--define(wxAuiPaneInfo_IsMovable, 2621).
--define(wxAuiPaneInfo_IsOk, 2622).
--define(wxAuiPaneInfo_IsResizable, 2623).
--define(wxAuiPaneInfo_IsRightDockable, 2624).
--define(wxAuiPaneInfo_IsShown, 2625).
--define(wxAuiPaneInfo_IsToolbar, 2626).
--define(wxAuiPaneInfo_IsTopDockable, 2627).
--define(wxAuiPaneInfo_Layer, 2628).
--define(wxAuiPaneInfo_Left, 2629).
--define(wxAuiPaneInfo_LeftDockable, 2630).
--define(wxAuiPaneInfo_MaxSize_1, 2631).
--define(wxAuiPaneInfo_MaxSize_2, 2632).
--define(wxAuiPaneInfo_MaximizeButton, 2633).
--define(wxAuiPaneInfo_MinSize_1, 2634).
--define(wxAuiPaneInfo_MinSize_2, 2635).
--define(wxAuiPaneInfo_MinimizeButton, 2636).
--define(wxAuiPaneInfo_Movable, 2637).
--define(wxAuiPaneInfo_Name, 2638).
--define(wxAuiPaneInfo_PaneBorder, 2639).
--define(wxAuiPaneInfo_PinButton, 2640).
--define(wxAuiPaneInfo_Position, 2641).
--define(wxAuiPaneInfo_Resizable, 2642).
--define(wxAuiPaneInfo_Right, 2643).
--define(wxAuiPaneInfo_RightDockable, 2644).
--define(wxAuiPaneInfo_Row, 2645).
--define(wxAuiPaneInfo_SafeSet, 2646).
--define(wxAuiPaneInfo_SetFlag, 2647).
--define(wxAuiPaneInfo_Show, 2648).
--define(wxAuiPaneInfo_ToolbarPane, 2649).
--define(wxAuiPaneInfo_Top, 2650).
--define(wxAuiPaneInfo_TopDockable, 2651).
--define(wxAuiPaneInfo_Window, 2652).
--define(wxAuiNotebook_new_0, 2653).
--define(wxAuiNotebook_new_2, 2654).
--define(wxAuiNotebook_AddPage, 2655).
--define(wxAuiNotebook_Create, 2656).
--define(wxAuiNotebook_DeletePage, 2657).
--define(wxAuiNotebook_GetArtProvider, 2658).
--define(wxAuiNotebook_GetPage, 2659).
--define(wxAuiNotebook_GetPageBitmap, 2660).
--define(wxAuiNotebook_GetPageCount, 2661).
--define(wxAuiNotebook_GetPageIndex, 2662).
--define(wxAuiNotebook_GetPageText, 2663).
--define(wxAuiNotebook_GetSelection, 2664).
--define(wxAuiNotebook_InsertPage, 2665).
--define(wxAuiNotebook_RemovePage, 2666).
--define(wxAuiNotebook_SetArtProvider, 2667).
--define(wxAuiNotebook_SetFont, 2668).
--define(wxAuiNotebook_SetPageBitmap, 2669).
--define(wxAuiNotebook_SetPageText, 2670).
--define(wxAuiNotebook_SetSelection, 2671).
--define(wxAuiNotebook_SetTabCtrlHeight, 2672).
--define(wxAuiNotebook_SetUniformBitmapSize, 2673).
--define(wxAuiNotebook_destroy, 2674).
--define(wxMDIParentFrame_new_0, 2675).
--define(wxMDIParentFrame_new_4, 2676).
--define(wxMDIParentFrame_destruct, 2677).
--define(wxMDIParentFrame_ActivateNext, 2678).
--define(wxMDIParentFrame_ActivatePrevious, 2679).
--define(wxMDIParentFrame_ArrangeIcons, 2680).
--define(wxMDIParentFrame_Cascade, 2681).
--define(wxMDIParentFrame_Create, 2682).
--define(wxMDIParentFrame_GetActiveChild, 2683).
--define(wxMDIParentFrame_GetClientWindow, 2684).
--define(wxMDIParentFrame_Tile, 2685).
--define(wxMDIChildFrame_new_0, 2686).
--define(wxMDIChildFrame_new_4, 2687).
--define(wxMDIChildFrame_destruct, 2688).
--define(wxMDIChildFrame_Activate, 2689).
--define(wxMDIChildFrame_Create, 2690).
--define(wxMDIChildFrame_Maximize, 2691).
--define(wxMDIChildFrame_Restore, 2692).
--define(wxMDIClientWindow_new_0, 2693).
--define(wxMDIClientWindow_new_2, 2694).
--define(wxMDIClientWindow_destruct, 2695).
--define(wxMDIClientWindow_CreateClient, 2696).
--define(wxLayoutAlgorithm_new, 2697).
--define(wxLayoutAlgorithm_LayoutFrame, 2698).
--define(wxLayoutAlgorithm_LayoutMDIFrame, 2699).
--define(wxLayoutAlgorithm_LayoutWindow, 2700).
--define(wxLayoutAlgorithm_destroy, 2701).
--define(wxEvent_GetId, 2702).
--define(wxEvent_GetSkipped, 2703).
--define(wxEvent_GetTimestamp, 2704).
--define(wxEvent_IsCommandEvent, 2705).
--define(wxEvent_ResumePropagation, 2706).
--define(wxEvent_ShouldPropagate, 2707).
--define(wxEvent_Skip, 2708).
--define(wxEvent_StopPropagation, 2709).
--define(wxCommandEvent_getClientData, 2710).
--define(wxCommandEvent_GetExtraLong, 2711).
--define(wxCommandEvent_GetInt, 2712).
--define(wxCommandEvent_GetSelection, 2713).
--define(wxCommandEvent_GetString, 2714).
--define(wxCommandEvent_IsChecked, 2715).
--define(wxCommandEvent_IsSelection, 2716).
--define(wxCommandEvent_SetInt, 2717).
--define(wxCommandEvent_SetString, 2718).
--define(wxScrollEvent_GetOrientation, 2719).
--define(wxScrollEvent_GetPosition, 2720).
--define(wxScrollWinEvent_GetOrientation, 2721).
--define(wxScrollWinEvent_GetPosition, 2722).
--define(wxMouseEvent_AltDown, 2723).
--define(wxMouseEvent_Button, 2724).
--define(wxMouseEvent_ButtonDClick, 2725).
--define(wxMouseEvent_ButtonDown, 2726).
--define(wxMouseEvent_ButtonUp, 2727).
--define(wxMouseEvent_CmdDown, 2728).
--define(wxMouseEvent_ControlDown, 2729).
--define(wxMouseEvent_Dragging, 2730).
--define(wxMouseEvent_Entering, 2731).
--define(wxMouseEvent_GetButton, 2732).
--define(wxMouseEvent_GetPosition, 2735).
--define(wxMouseEvent_GetLogicalPosition, 2736).
--define(wxMouseEvent_GetLinesPerAction, 2737).
--define(wxMouseEvent_GetWheelRotation, 2738).
--define(wxMouseEvent_GetWheelDelta, 2739).
--define(wxMouseEvent_GetX, 2740).
--define(wxMouseEvent_GetY, 2741).
--define(wxMouseEvent_IsButton, 2742).
--define(wxMouseEvent_IsPageScroll, 2743).
--define(wxMouseEvent_Leaving, 2744).
--define(wxMouseEvent_LeftDClick, 2745).
--define(wxMouseEvent_LeftDown, 2746).
--define(wxMouseEvent_LeftIsDown, 2747).
--define(wxMouseEvent_LeftUp, 2748).
--define(wxMouseEvent_MetaDown, 2749).
--define(wxMouseEvent_MiddleDClick, 2750).
--define(wxMouseEvent_MiddleDown, 2751).
--define(wxMouseEvent_MiddleIsDown, 2752).
--define(wxMouseEvent_MiddleUp, 2753).
--define(wxMouseEvent_Moving, 2754).
--define(wxMouseEvent_RightDClick, 2755).
--define(wxMouseEvent_RightDown, 2756).
--define(wxMouseEvent_RightIsDown, 2757).
--define(wxMouseEvent_RightUp, 2758).
--define(wxMouseEvent_ShiftDown, 2759).
--define(wxSetCursorEvent_GetCursor, 2760).
--define(wxSetCursorEvent_GetX, 2761).
--define(wxSetCursorEvent_GetY, 2762).
--define(wxSetCursorEvent_HasCursor, 2763).
--define(wxSetCursorEvent_SetCursor, 2764).
--define(wxKeyEvent_AltDown, 2765).
--define(wxKeyEvent_CmdDown, 2766).
--define(wxKeyEvent_ControlDown, 2767).
--define(wxKeyEvent_GetKeyCode, 2768).
--define(wxKeyEvent_GetModifiers, 2769).
--define(wxKeyEvent_GetPosition, 2772).
--define(wxKeyEvent_GetRawKeyCode, 2773).
--define(wxKeyEvent_GetRawKeyFlags, 2774).
--define(wxKeyEvent_GetUnicodeKey, 2775).
--define(wxKeyEvent_GetX, 2776).
--define(wxKeyEvent_GetY, 2777).
--define(wxKeyEvent_HasModifiers, 2778).
--define(wxKeyEvent_MetaDown, 2779).
--define(wxKeyEvent_ShiftDown, 2780).
--define(wxSizeEvent_GetSize, 2781).
--define(wxMoveEvent_GetPosition, 2782).
--define(wxEraseEvent_GetDC, 2783).
--define(wxFocusEvent_GetWindow, 2784).
--define(wxChildFocusEvent_GetWindow, 2785).
--define(wxMenuEvent_GetMenu, 2786).
--define(wxMenuEvent_GetMenuId, 2787).
--define(wxMenuEvent_IsPopup, 2788).
--define(wxCloseEvent_CanVeto, 2789).
--define(wxCloseEvent_GetLoggingOff, 2790).
--define(wxCloseEvent_SetCanVeto, 2791).
--define(wxCloseEvent_SetLoggingOff, 2792).
--define(wxCloseEvent_Veto, 2793).
--define(wxShowEvent_SetShow, 2794).
--define(wxShowEvent_GetShow, 2795).
--define(wxIconizeEvent_Iconized, 2796).
--define(wxJoystickEvent_ButtonDown, 2797).
--define(wxJoystickEvent_ButtonIsDown, 2798).
--define(wxJoystickEvent_ButtonUp, 2799).
--define(wxJoystickEvent_GetButtonChange, 2800).
--define(wxJoystickEvent_GetButtonState, 2801).
--define(wxJoystickEvent_GetJoystick, 2802).
--define(wxJoystickEvent_GetPosition, 2803).
--define(wxJoystickEvent_GetZPosition, 2804).
--define(wxJoystickEvent_IsButton, 2805).
--define(wxJoystickEvent_IsMove, 2806).
--define(wxJoystickEvent_IsZMove, 2807).
--define(wxUpdateUIEvent_CanUpdate, 2808).
--define(wxUpdateUIEvent_Check, 2809).
--define(wxUpdateUIEvent_Enable, 2810).
--define(wxUpdateUIEvent_Show, 2811).
--define(wxUpdateUIEvent_GetChecked, 2812).
--define(wxUpdateUIEvent_GetEnabled, 2813).
--define(wxUpdateUIEvent_GetShown, 2814).
--define(wxUpdateUIEvent_GetSetChecked, 2815).
--define(wxUpdateUIEvent_GetSetEnabled, 2816).
--define(wxUpdateUIEvent_GetSetShown, 2817).
--define(wxUpdateUIEvent_GetSetText, 2818).
--define(wxUpdateUIEvent_GetText, 2819).
--define(wxUpdateUIEvent_GetMode, 2820).
--define(wxUpdateUIEvent_GetUpdateInterval, 2821).
--define(wxUpdateUIEvent_ResetUpdateTime, 2822).
--define(wxUpdateUIEvent_SetMode, 2823).
--define(wxUpdateUIEvent_SetText, 2824).
--define(wxUpdateUIEvent_SetUpdateInterval, 2825).
--define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2826).
--define(wxPaletteChangedEvent_SetChangedWindow, 2827).
--define(wxPaletteChangedEvent_GetChangedWindow, 2828).
--define(wxQueryNewPaletteEvent_SetPaletteRealized, 2829).
--define(wxQueryNewPaletteEvent_GetPaletteRealized, 2830).
--define(wxNavigationKeyEvent_GetDirection, 2831).
--define(wxNavigationKeyEvent_SetDirection, 2832).
--define(wxNavigationKeyEvent_IsWindowChange, 2833).
--define(wxNavigationKeyEvent_SetWindowChange, 2834).
--define(wxNavigationKeyEvent_IsFromTab, 2835).
--define(wxNavigationKeyEvent_SetFromTab, 2836).
--define(wxNavigationKeyEvent_GetCurrentFocus, 2837).
--define(wxNavigationKeyEvent_SetCurrentFocus, 2838).
--define(wxHelpEvent_GetOrigin, 2839).
--define(wxHelpEvent_GetPosition, 2840).
--define(wxHelpEvent_SetOrigin, 2841).
--define(wxHelpEvent_SetPosition, 2842).
--define(wxContextMenuEvent_GetPosition, 2843).
--define(wxContextMenuEvent_SetPosition, 2844).
--define(wxIdleEvent_CanSend, 2845).
--define(wxIdleEvent_GetMode, 2846).
--define(wxIdleEvent_RequestMore, 2847).
--define(wxIdleEvent_MoreRequested, 2848).
--define(wxIdleEvent_SetMode, 2849).
--define(wxGridEvent_AltDown, 2850).
--define(wxGridEvent_ControlDown, 2851).
--define(wxGridEvent_GetCol, 2852).
--define(wxGridEvent_GetPosition, 2853).
--define(wxGridEvent_GetRow, 2854).
--define(wxGridEvent_MetaDown, 2855).
--define(wxGridEvent_Selecting, 2856).
--define(wxGridEvent_ShiftDown, 2857).
--define(wxNotifyEvent_Allow, 2858).
--define(wxNotifyEvent_IsAllowed, 2859).
--define(wxNotifyEvent_Veto, 2860).
--define(wxSashEvent_GetEdge, 2861).
--define(wxSashEvent_GetDragRect, 2862).
--define(wxSashEvent_GetDragStatus, 2863).
--define(wxListEvent_GetCacheFrom, 2864).
--define(wxListEvent_GetCacheTo, 2865).
--define(wxListEvent_GetKeyCode, 2866).
--define(wxListEvent_GetIndex, 2867).
--define(wxListEvent_GetColumn, 2868).
--define(wxListEvent_GetPoint, 2869).
--define(wxListEvent_GetLabel, 2870).
--define(wxListEvent_GetText, 2871).
--define(wxListEvent_GetImage, 2872).
--define(wxListEvent_GetData, 2873).
--define(wxListEvent_GetMask, 2874).
--define(wxListEvent_GetItem, 2875).
--define(wxListEvent_IsEditCancelled, 2876).
--define(wxDateEvent_GetDate, 2877).
--define(wxCalendarEvent_GetWeekDay, 2878).
--define(wxFileDirPickerEvent_GetPath, 2879).
--define(wxColourPickerEvent_GetColour, 2880).
--define(wxFontPickerEvent_GetFont, 2881).
--define(wxStyledTextEvent_GetPosition, 2882).
--define(wxStyledTextEvent_GetKey, 2883).
--define(wxStyledTextEvent_GetModifiers, 2884).
--define(wxStyledTextEvent_GetModificationType, 2885).
--define(wxStyledTextEvent_GetText, 2886).
--define(wxStyledTextEvent_GetLength, 2887).
--define(wxStyledTextEvent_GetLinesAdded, 2888).
--define(wxStyledTextEvent_GetLine, 2889).
--define(wxStyledTextEvent_GetFoldLevelNow, 2890).
--define(wxStyledTextEvent_GetFoldLevelPrev, 2891).
--define(wxStyledTextEvent_GetMargin, 2892).
--define(wxStyledTextEvent_GetMessage, 2893).
--define(wxStyledTextEvent_GetWParam, 2894).
--define(wxStyledTextEvent_GetLParam, 2895).
--define(wxStyledTextEvent_GetListType, 2896).
--define(wxStyledTextEvent_GetX, 2897).
--define(wxStyledTextEvent_GetY, 2898).
--define(wxStyledTextEvent_GetDragText, 2899).
--define(wxStyledTextEvent_GetDragAllowMove, 2900).
--define(wxStyledTextEvent_GetDragResult, 2901).
--define(wxStyledTextEvent_GetShift, 2902).
--define(wxStyledTextEvent_GetControl, 2903).
--define(wxStyledTextEvent_GetAlt, 2904).
--define(utils_wxGetKeyState, 2905).
--define(utils_wxGetMousePosition, 2906).
--define(utils_wxGetMouseState, 2907).
--define(utils_wxSetDetectableAutoRepeat, 2908).
--define(utils_wxBell, 2909).
--define(utils_wxFindMenuItemId, 2910).
--define(utils_wxGenericFindWindowAtPoint, 2911).
--define(utils_wxFindWindowAtPoint, 2912).
--define(utils_wxBeginBusyCursor, 2913).
--define(utils_wxEndBusyCursor, 2914).
--define(utils_wxIsBusy, 2915).
--define(utils_wxShutdown, 2916).
--define(utils_wxShell, 2917).
--define(utils_wxLaunchDefaultBrowser, 2918).
--define(utils_wxGetEmailAddress, 2919).
--define(utils_wxGetUserId, 2920).
--define(utils_wxGetHomeDir, 2921).
--define(utils_wxNewId, 2922).
--define(utils_wxRegisterId, 2923).
--define(utils_wxGetCurrentId, 2924).
--define(utils_wxGetOsDescription, 2925).
--define(utils_wxIsPlatformLittleEndian, 2926).
--define(utils_wxIsPlatform64Bit, 2927).
--define(gdicmn_wxDisplaySize, 2928).
--define(gdicmn_wxSetCursor, 2929).
--define(wxPrintout_new, 2930).
--define(wxPrintout_destruct, 2931).
--define(wxPrintout_GetDC, 2932).
--define(wxPrintout_GetPageSizeMM, 2933).
--define(wxPrintout_GetPageSizePixels, 2934).
--define(wxPrintout_GetPaperRectPixels, 2935).
--define(wxPrintout_GetPPIPrinter, 2936).
--define(wxPrintout_GetPPIScreen, 2937).
--define(wxPrintout_GetTitle, 2938).
--define(wxPrintout_IsPreview, 2939).
--define(wxPrintout_FitThisSizeToPaper, 2940).
--define(wxPrintout_FitThisSizeToPage, 2941).
--define(wxPrintout_FitThisSizeToPageMargins, 2942).
--define(wxPrintout_MapScreenSizeToPaper, 2943).
--define(wxPrintout_MapScreenSizeToPage, 2944).
--define(wxPrintout_MapScreenSizeToPageMargins, 2945).
--define(wxPrintout_MapScreenSizeToDevice, 2946).
--define(wxPrintout_GetLogicalPaperRect, 2947).
--define(wxPrintout_GetLogicalPageRect, 2948).
--define(wxPrintout_GetLogicalPageMarginsRect, 2949).
--define(wxPrintout_SetLogicalOrigin, 2950).
--define(wxPrintout_OffsetLogicalOrigin, 2951).
--define(wxStyledTextCtrl_new_2, 2952).
--define(wxStyledTextCtrl_new_0, 2953).
--define(wxStyledTextCtrl_destruct, 2954).
--define(wxStyledTextCtrl_Create, 2955).
--define(wxStyledTextCtrl_AddText, 2956).
--define(wxStyledTextCtrl_AddStyledText, 2957).
--define(wxStyledTextCtrl_InsertText, 2958).
--define(wxStyledTextCtrl_ClearAll, 2959).
--define(wxStyledTextCtrl_ClearDocumentStyle, 2960).
--define(wxStyledTextCtrl_GetLength, 2961).
--define(wxStyledTextCtrl_GetCharAt, 2962).
--define(wxStyledTextCtrl_GetCurrentPos, 2963).
--define(wxStyledTextCtrl_GetAnchor, 2964).
--define(wxStyledTextCtrl_GetStyleAt, 2965).
--define(wxStyledTextCtrl_Redo, 2966).
--define(wxStyledTextCtrl_SetUndoCollection, 2967).
--define(wxStyledTextCtrl_SelectAll, 2968).
--define(wxStyledTextCtrl_SetSavePoint, 2969).
--define(wxStyledTextCtrl_GetStyledText, 2970).
--define(wxStyledTextCtrl_CanRedo, 2971).
--define(wxStyledTextCtrl_MarkerLineFromHandle, 2972).
--define(wxStyledTextCtrl_MarkerDeleteHandle, 2973).
--define(wxStyledTextCtrl_GetUndoCollection, 2974).
--define(wxStyledTextCtrl_GetViewWhiteSpace, 2975).
--define(wxStyledTextCtrl_SetViewWhiteSpace, 2976).
--define(wxStyledTextCtrl_PositionFromPoint, 2977).
--define(wxStyledTextCtrl_PositionFromPointClose, 2978).
--define(wxStyledTextCtrl_GotoLine, 2979).
--define(wxStyledTextCtrl_GotoPos, 2980).
--define(wxStyledTextCtrl_SetAnchor, 2981).
--define(wxStyledTextCtrl_GetCurLine, 2982).
--define(wxStyledTextCtrl_GetEndStyled, 2983).
--define(wxStyledTextCtrl_ConvertEOLs, 2984).
--define(wxStyledTextCtrl_GetEOLMode, 2985).
--define(wxStyledTextCtrl_SetEOLMode, 2986).
--define(wxStyledTextCtrl_StartStyling, 2987).
--define(wxStyledTextCtrl_SetStyling, 2988).
--define(wxStyledTextCtrl_GetBufferedDraw, 2989).
--define(wxStyledTextCtrl_SetBufferedDraw, 2990).
--define(wxStyledTextCtrl_SetTabWidth, 2991).
--define(wxStyledTextCtrl_GetTabWidth, 2992).
--define(wxStyledTextCtrl_SetCodePage, 2993).
--define(wxStyledTextCtrl_MarkerDefine, 2994).
--define(wxStyledTextCtrl_MarkerSetForeground, 2995).
--define(wxStyledTextCtrl_MarkerSetBackground, 2996).
--define(wxStyledTextCtrl_MarkerAdd, 2997).
--define(wxStyledTextCtrl_MarkerDelete, 2998).
--define(wxStyledTextCtrl_MarkerDeleteAll, 2999).
--define(wxStyledTextCtrl_MarkerGet, 3000).
--define(wxStyledTextCtrl_MarkerNext, 3001).
--define(wxStyledTextCtrl_MarkerPrevious, 3002).
--define(wxStyledTextCtrl_MarkerDefineBitmap, 3003).
--define(wxStyledTextCtrl_MarkerAddSet, 3004).
--define(wxStyledTextCtrl_MarkerSetAlpha, 3005).
--define(wxStyledTextCtrl_SetMarginType, 3006).
--define(wxStyledTextCtrl_GetMarginType, 3007).
--define(wxStyledTextCtrl_SetMarginWidth, 3008).
--define(wxStyledTextCtrl_GetMarginWidth, 3009).
--define(wxStyledTextCtrl_SetMarginMask, 3010).
--define(wxStyledTextCtrl_GetMarginMask, 3011).
--define(wxStyledTextCtrl_SetMarginSensitive, 3012).
--define(wxStyledTextCtrl_GetMarginSensitive, 3013).
--define(wxStyledTextCtrl_StyleClearAll, 3014).
--define(wxStyledTextCtrl_StyleSetForeground, 3015).
--define(wxStyledTextCtrl_StyleSetBackground, 3016).
--define(wxStyledTextCtrl_StyleSetBold, 3017).
--define(wxStyledTextCtrl_StyleSetItalic, 3018).
--define(wxStyledTextCtrl_StyleSetSize, 3019).
--define(wxStyledTextCtrl_StyleSetFaceName, 3020).
--define(wxStyledTextCtrl_StyleSetEOLFilled, 3021).
--define(wxStyledTextCtrl_StyleResetDefault, 3022).
--define(wxStyledTextCtrl_StyleSetUnderline, 3023).
--define(wxStyledTextCtrl_StyleSetCase, 3024).
--define(wxStyledTextCtrl_StyleSetHotSpot, 3025).
--define(wxStyledTextCtrl_SetSelForeground, 3026).
--define(wxStyledTextCtrl_SetSelBackground, 3027).
--define(wxStyledTextCtrl_GetSelAlpha, 3028).
--define(wxStyledTextCtrl_SetSelAlpha, 3029).
--define(wxStyledTextCtrl_SetCaretForeground, 3030).
--define(wxStyledTextCtrl_CmdKeyAssign, 3031).
--define(wxStyledTextCtrl_CmdKeyClear, 3032).
--define(wxStyledTextCtrl_CmdKeyClearAll, 3033).
--define(wxStyledTextCtrl_SetStyleBytes, 3034).
--define(wxStyledTextCtrl_StyleSetVisible, 3035).
--define(wxStyledTextCtrl_GetCaretPeriod, 3036).
--define(wxStyledTextCtrl_SetCaretPeriod, 3037).
--define(wxStyledTextCtrl_SetWordChars, 3038).
--define(wxStyledTextCtrl_BeginUndoAction, 3039).
--define(wxStyledTextCtrl_EndUndoAction, 3040).
--define(wxStyledTextCtrl_IndicatorSetStyle, 3041).
--define(wxStyledTextCtrl_IndicatorGetStyle, 3042).
--define(wxStyledTextCtrl_IndicatorSetForeground, 3043).
--define(wxStyledTextCtrl_IndicatorGetForeground, 3044).
--define(wxStyledTextCtrl_SetWhitespaceForeground, 3045).
--define(wxStyledTextCtrl_SetWhitespaceBackground, 3046).
--define(wxStyledTextCtrl_GetStyleBits, 3047).
--define(wxStyledTextCtrl_SetLineState, 3048).
--define(wxStyledTextCtrl_GetLineState, 3049).
--define(wxStyledTextCtrl_GetMaxLineState, 3050).
--define(wxStyledTextCtrl_GetCaretLineVisible, 3051).
--define(wxStyledTextCtrl_SetCaretLineVisible, 3052).
--define(wxStyledTextCtrl_GetCaretLineBackground, 3053).
--define(wxStyledTextCtrl_SetCaretLineBackground, 3054).
--define(wxStyledTextCtrl_AutoCompShow, 3055).
--define(wxStyledTextCtrl_AutoCompCancel, 3056).
--define(wxStyledTextCtrl_AutoCompActive, 3057).
--define(wxStyledTextCtrl_AutoCompPosStart, 3058).
--define(wxStyledTextCtrl_AutoCompComplete, 3059).
--define(wxStyledTextCtrl_AutoCompStops, 3060).
--define(wxStyledTextCtrl_AutoCompSetSeparator, 3061).
--define(wxStyledTextCtrl_AutoCompGetSeparator, 3062).
--define(wxStyledTextCtrl_AutoCompSelect, 3063).
--define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3064).
--define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3065).
--define(wxStyledTextCtrl_AutoCompSetFillUps, 3066).
--define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3067).
--define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3068).
--define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3069).
--define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3070).
--define(wxStyledTextCtrl_UserListShow, 3071).
--define(wxStyledTextCtrl_AutoCompSetAutoHide, 3072).
--define(wxStyledTextCtrl_AutoCompGetAutoHide, 3073).
--define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3074).
--define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3075).
--define(wxStyledTextCtrl_RegisterImage, 3076).
--define(wxStyledTextCtrl_ClearRegisteredImages, 3077).
--define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3078).
--define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3079).
--define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3080).
--define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3081).
--define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3082).
--define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3083).
--define(wxStyledTextCtrl_SetIndent, 3084).
--define(wxStyledTextCtrl_GetIndent, 3085).
--define(wxStyledTextCtrl_SetUseTabs, 3086).
--define(wxStyledTextCtrl_GetUseTabs, 3087).
--define(wxStyledTextCtrl_SetLineIndentation, 3088).
--define(wxStyledTextCtrl_GetLineIndentation, 3089).
--define(wxStyledTextCtrl_GetLineIndentPosition, 3090).
--define(wxStyledTextCtrl_GetColumn, 3091).
--define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3092).
--define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3093).
--define(wxStyledTextCtrl_SetIndentationGuides, 3094).
--define(wxStyledTextCtrl_GetIndentationGuides, 3095).
--define(wxStyledTextCtrl_SetHighlightGuide, 3096).
--define(wxStyledTextCtrl_GetHighlightGuide, 3097).
--define(wxStyledTextCtrl_GetLineEndPosition, 3098).
--define(wxStyledTextCtrl_GetCodePage, 3099).
--define(wxStyledTextCtrl_GetCaretForeground, 3100).
--define(wxStyledTextCtrl_GetReadOnly, 3101).
--define(wxStyledTextCtrl_SetCurrentPos, 3102).
--define(wxStyledTextCtrl_SetSelectionStart, 3103).
--define(wxStyledTextCtrl_GetSelectionStart, 3104).
--define(wxStyledTextCtrl_SetSelectionEnd, 3105).
--define(wxStyledTextCtrl_GetSelectionEnd, 3106).
--define(wxStyledTextCtrl_SetPrintMagnification, 3107).
--define(wxStyledTextCtrl_GetPrintMagnification, 3108).
--define(wxStyledTextCtrl_SetPrintColourMode, 3109).
--define(wxStyledTextCtrl_GetPrintColourMode, 3110).
--define(wxStyledTextCtrl_FindText, 3111).
--define(wxStyledTextCtrl_FormatRange, 3112).
--define(wxStyledTextCtrl_GetFirstVisibleLine, 3113).
--define(wxStyledTextCtrl_GetLine, 3114).
--define(wxStyledTextCtrl_GetLineCount, 3115).
--define(wxStyledTextCtrl_SetMarginLeft, 3116).
--define(wxStyledTextCtrl_GetMarginLeft, 3117).
--define(wxStyledTextCtrl_SetMarginRight, 3118).
--define(wxStyledTextCtrl_GetMarginRight, 3119).
--define(wxStyledTextCtrl_GetModify, 3120).
--define(wxStyledTextCtrl_SetSelection, 3121).
--define(wxStyledTextCtrl_GetSelectedText, 3122).
--define(wxStyledTextCtrl_GetTextRange, 3123).
--define(wxStyledTextCtrl_HideSelection, 3124).
--define(wxStyledTextCtrl_LineFromPosition, 3125).
--define(wxStyledTextCtrl_PositionFromLine, 3126).
--define(wxStyledTextCtrl_LineScroll, 3127).
--define(wxStyledTextCtrl_EnsureCaretVisible, 3128).
--define(wxStyledTextCtrl_ReplaceSelection, 3129).
--define(wxStyledTextCtrl_SetReadOnly, 3130).
--define(wxStyledTextCtrl_CanPaste, 3131).
--define(wxStyledTextCtrl_CanUndo, 3132).
--define(wxStyledTextCtrl_EmptyUndoBuffer, 3133).
--define(wxStyledTextCtrl_Undo, 3134).
--define(wxStyledTextCtrl_Cut, 3135).
--define(wxStyledTextCtrl_Copy, 3136).
--define(wxStyledTextCtrl_Paste, 3137).
--define(wxStyledTextCtrl_Clear, 3138).
--define(wxStyledTextCtrl_SetText, 3139).
--define(wxStyledTextCtrl_GetText, 3140).
--define(wxStyledTextCtrl_GetTextLength, 3141).
--define(wxStyledTextCtrl_GetOvertype, 3142).
--define(wxStyledTextCtrl_SetCaretWidth, 3143).
--define(wxStyledTextCtrl_GetCaretWidth, 3144).
--define(wxStyledTextCtrl_SetTargetStart, 3145).
--define(wxStyledTextCtrl_GetTargetStart, 3146).
--define(wxStyledTextCtrl_SetTargetEnd, 3147).
--define(wxStyledTextCtrl_GetTargetEnd, 3148).
--define(wxStyledTextCtrl_ReplaceTarget, 3149).
--define(wxStyledTextCtrl_SearchInTarget, 3150).
--define(wxStyledTextCtrl_SetSearchFlags, 3151).
--define(wxStyledTextCtrl_GetSearchFlags, 3152).
--define(wxStyledTextCtrl_CallTipShow, 3153).
--define(wxStyledTextCtrl_CallTipCancel, 3154).
--define(wxStyledTextCtrl_CallTipActive, 3155).
--define(wxStyledTextCtrl_CallTipPosAtStart, 3156).
--define(wxStyledTextCtrl_CallTipSetHighlight, 3157).
--define(wxStyledTextCtrl_CallTipSetBackground, 3158).
--define(wxStyledTextCtrl_CallTipSetForeground, 3159).
--define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3160).
--define(wxStyledTextCtrl_CallTipUseStyle, 3161).
--define(wxStyledTextCtrl_VisibleFromDocLine, 3162).
--define(wxStyledTextCtrl_DocLineFromVisible, 3163).
--define(wxStyledTextCtrl_WrapCount, 3164).
--define(wxStyledTextCtrl_SetFoldLevel, 3165).
--define(wxStyledTextCtrl_GetFoldLevel, 3166).
--define(wxStyledTextCtrl_GetLastChild, 3167).
--define(wxStyledTextCtrl_GetFoldParent, 3168).
--define(wxStyledTextCtrl_ShowLines, 3169).
--define(wxStyledTextCtrl_HideLines, 3170).
--define(wxStyledTextCtrl_GetLineVisible, 3171).
--define(wxStyledTextCtrl_SetFoldExpanded, 3172).
--define(wxStyledTextCtrl_GetFoldExpanded, 3173).
--define(wxStyledTextCtrl_ToggleFold, 3174).
--define(wxStyledTextCtrl_EnsureVisible, 3175).
--define(wxStyledTextCtrl_SetFoldFlags, 3176).
--define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3177).
--define(wxStyledTextCtrl_SetTabIndents, 3178).
--define(wxStyledTextCtrl_GetTabIndents, 3179).
--define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3180).
--define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3181).
--define(wxStyledTextCtrl_SetMouseDwellTime, 3182).
--define(wxStyledTextCtrl_GetMouseDwellTime, 3183).
--define(wxStyledTextCtrl_WordStartPosition, 3184).
--define(wxStyledTextCtrl_WordEndPosition, 3185).
--define(wxStyledTextCtrl_SetWrapMode, 3186).
--define(wxStyledTextCtrl_GetWrapMode, 3187).
--define(wxStyledTextCtrl_SetWrapVisualFlags, 3188).
--define(wxStyledTextCtrl_GetWrapVisualFlags, 3189).
--define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3190).
--define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3191).
--define(wxStyledTextCtrl_SetWrapStartIndent, 3192).
--define(wxStyledTextCtrl_GetWrapStartIndent, 3193).
--define(wxStyledTextCtrl_SetLayoutCache, 3194).
--define(wxStyledTextCtrl_GetLayoutCache, 3195).
--define(wxStyledTextCtrl_SetScrollWidth, 3196).
--define(wxStyledTextCtrl_GetScrollWidth, 3197).
--define(wxStyledTextCtrl_TextWidth, 3198).
--define(wxStyledTextCtrl_GetEndAtLastLine, 3199).
--define(wxStyledTextCtrl_TextHeight, 3200).
--define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3201).
--define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3202).
--define(wxStyledTextCtrl_AppendText, 3203).
--define(wxStyledTextCtrl_GetTwoPhaseDraw, 3204).
--define(wxStyledTextCtrl_SetTwoPhaseDraw, 3205).
--define(wxStyledTextCtrl_TargetFromSelection, 3206).
--define(wxStyledTextCtrl_LinesJoin, 3207).
--define(wxStyledTextCtrl_LinesSplit, 3208).
--define(wxStyledTextCtrl_SetFoldMarginColour, 3209).
--define(wxStyledTextCtrl_SetFoldMarginHiColour, 3210).
--define(wxStyledTextCtrl_LineDown, 3211).
--define(wxStyledTextCtrl_LineDownExtend, 3212).
--define(wxStyledTextCtrl_LineUp, 3213).
--define(wxStyledTextCtrl_LineUpExtend, 3214).
--define(wxStyledTextCtrl_CharLeft, 3215).
--define(wxStyledTextCtrl_CharLeftExtend, 3216).
--define(wxStyledTextCtrl_CharRight, 3217).
--define(wxStyledTextCtrl_CharRightExtend, 3218).
--define(wxStyledTextCtrl_WordLeft, 3219).
--define(wxStyledTextCtrl_WordLeftExtend, 3220).
--define(wxStyledTextCtrl_WordRight, 3221).
--define(wxStyledTextCtrl_WordRightExtend, 3222).
--define(wxStyledTextCtrl_Home, 3223).
--define(wxStyledTextCtrl_HomeExtend, 3224).
--define(wxStyledTextCtrl_LineEnd, 3225).
--define(wxStyledTextCtrl_LineEndExtend, 3226).
--define(wxStyledTextCtrl_DocumentStart, 3227).
--define(wxStyledTextCtrl_DocumentStartExtend, 3228).
--define(wxStyledTextCtrl_DocumentEnd, 3229).
--define(wxStyledTextCtrl_DocumentEndExtend, 3230).
--define(wxStyledTextCtrl_PageUp, 3231).
--define(wxStyledTextCtrl_PageUpExtend, 3232).
--define(wxStyledTextCtrl_PageDown, 3233).
--define(wxStyledTextCtrl_PageDownExtend, 3234).
--define(wxStyledTextCtrl_EditToggleOvertype, 3235).
--define(wxStyledTextCtrl_Cancel, 3236).
--define(wxStyledTextCtrl_DeleteBack, 3237).
--define(wxStyledTextCtrl_Tab, 3238).
--define(wxStyledTextCtrl_BackTab, 3239).
--define(wxStyledTextCtrl_NewLine, 3240).
--define(wxStyledTextCtrl_FormFeed, 3241).
--define(wxStyledTextCtrl_VCHome, 3242).
--define(wxStyledTextCtrl_VCHomeExtend, 3243).
--define(wxStyledTextCtrl_ZoomIn, 3244).
--define(wxStyledTextCtrl_ZoomOut, 3245).
--define(wxStyledTextCtrl_DelWordLeft, 3246).
--define(wxStyledTextCtrl_DelWordRight, 3247).
--define(wxStyledTextCtrl_LineCut, 3248).
--define(wxStyledTextCtrl_LineDelete, 3249).
--define(wxStyledTextCtrl_LineTranspose, 3250).
--define(wxStyledTextCtrl_LineDuplicate, 3251).
--define(wxStyledTextCtrl_LowerCase, 3252).
--define(wxStyledTextCtrl_UpperCase, 3253).
--define(wxStyledTextCtrl_LineScrollDown, 3254).
--define(wxStyledTextCtrl_LineScrollUp, 3255).
--define(wxStyledTextCtrl_DeleteBackNotLine, 3256).
--define(wxStyledTextCtrl_HomeDisplay, 3257).
--define(wxStyledTextCtrl_HomeDisplayExtend, 3258).
--define(wxStyledTextCtrl_LineEndDisplay, 3259).
--define(wxStyledTextCtrl_LineEndDisplayExtend, 3260).
--define(wxStyledTextCtrl_HomeWrapExtend, 3261).
--define(wxStyledTextCtrl_LineEndWrap, 3262).
--define(wxStyledTextCtrl_LineEndWrapExtend, 3263).
--define(wxStyledTextCtrl_VCHomeWrap, 3264).
--define(wxStyledTextCtrl_VCHomeWrapExtend, 3265).
--define(wxStyledTextCtrl_LineCopy, 3266).
--define(wxStyledTextCtrl_MoveCaretInsideView, 3267).
--define(wxStyledTextCtrl_LineLength, 3268).
--define(wxStyledTextCtrl_BraceHighlight, 3269).
--define(wxStyledTextCtrl_BraceBadLight, 3270).
--define(wxStyledTextCtrl_BraceMatch, 3271).
--define(wxStyledTextCtrl_GetViewEOL, 3272).
--define(wxStyledTextCtrl_SetViewEOL, 3273).
--define(wxStyledTextCtrl_SetModEventMask, 3274).
--define(wxStyledTextCtrl_GetEdgeColumn, 3275).
--define(wxStyledTextCtrl_SetEdgeColumn, 3276).
--define(wxStyledTextCtrl_SetEdgeMode, 3277).
--define(wxStyledTextCtrl_GetEdgeMode, 3278).
--define(wxStyledTextCtrl_GetEdgeColour, 3279).
--define(wxStyledTextCtrl_SetEdgeColour, 3280).
--define(wxStyledTextCtrl_SearchAnchor, 3281).
--define(wxStyledTextCtrl_SearchNext, 3282).
--define(wxStyledTextCtrl_SearchPrev, 3283).
--define(wxStyledTextCtrl_LinesOnScreen, 3284).
--define(wxStyledTextCtrl_UsePopUp, 3285).
--define(wxStyledTextCtrl_SelectionIsRectangle, 3286).
--define(wxStyledTextCtrl_SetZoom, 3287).
--define(wxStyledTextCtrl_GetZoom, 3288).
--define(wxStyledTextCtrl_GetModEventMask, 3289).
--define(wxStyledTextCtrl_SetSTCFocus, 3290).
--define(wxStyledTextCtrl_GetSTCFocus, 3291).
--define(wxStyledTextCtrl_SetStatus, 3292).
--define(wxStyledTextCtrl_GetStatus, 3293).
--define(wxStyledTextCtrl_SetMouseDownCaptures, 3294).
--define(wxStyledTextCtrl_GetMouseDownCaptures, 3295).
--define(wxStyledTextCtrl_SetSTCCursor, 3296).
--define(wxStyledTextCtrl_GetSTCCursor, 3297).
--define(wxStyledTextCtrl_SetControlCharSymbol, 3298).
--define(wxStyledTextCtrl_GetControlCharSymbol, 3299).
--define(wxStyledTextCtrl_WordPartLeft, 3300).
--define(wxStyledTextCtrl_WordPartLeftExtend, 3301).
--define(wxStyledTextCtrl_WordPartRight, 3302).
--define(wxStyledTextCtrl_WordPartRightExtend, 3303).
--define(wxStyledTextCtrl_SetVisiblePolicy, 3304).
--define(wxStyledTextCtrl_DelLineLeft, 3305).
--define(wxStyledTextCtrl_DelLineRight, 3306).
--define(wxStyledTextCtrl_GetXOffset, 3307).
--define(wxStyledTextCtrl_ChooseCaretX, 3308).
--define(wxStyledTextCtrl_SetXCaretPolicy, 3309).
--define(wxStyledTextCtrl_SetYCaretPolicy, 3310).
--define(wxStyledTextCtrl_GetPrintWrapMode, 3311).
--define(wxStyledTextCtrl_SetHotspotActiveForeground, 3312).
--define(wxStyledTextCtrl_SetHotspotActiveBackground, 3313).
--define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3314).
--define(wxStyledTextCtrl_SetHotspotSingleLine, 3315).
--define(wxStyledTextCtrl_ParaDownExtend, 3316).
--define(wxStyledTextCtrl_ParaUp, 3317).
--define(wxStyledTextCtrl_ParaUpExtend, 3318).
--define(wxStyledTextCtrl_PositionBefore, 3319).
--define(wxStyledTextCtrl_PositionAfter, 3320).
--define(wxStyledTextCtrl_CopyRange, 3321).
--define(wxStyledTextCtrl_CopyText, 3322).
--define(wxStyledTextCtrl_SetSelectionMode, 3323).
--define(wxStyledTextCtrl_GetSelectionMode, 3324).
--define(wxStyledTextCtrl_LineDownRectExtend, 3325).
--define(wxStyledTextCtrl_LineUpRectExtend, 3326).
--define(wxStyledTextCtrl_CharLeftRectExtend, 3327).
--define(wxStyledTextCtrl_CharRightRectExtend, 3328).
--define(wxStyledTextCtrl_HomeRectExtend, 3329).
--define(wxStyledTextCtrl_VCHomeRectExtend, 3330).
--define(wxStyledTextCtrl_LineEndRectExtend, 3331).
--define(wxStyledTextCtrl_PageUpRectExtend, 3332).
--define(wxStyledTextCtrl_PageDownRectExtend, 3333).
--define(wxStyledTextCtrl_StutteredPageUp, 3334).
--define(wxStyledTextCtrl_StutteredPageUpExtend, 3335).
--define(wxStyledTextCtrl_StutteredPageDown, 3336).
--define(wxStyledTextCtrl_StutteredPageDownExtend, 3337).
--define(wxStyledTextCtrl_WordLeftEnd, 3338).
--define(wxStyledTextCtrl_WordLeftEndExtend, 3339).
--define(wxStyledTextCtrl_WordRightEnd, 3340).
--define(wxStyledTextCtrl_WordRightEndExtend, 3341).
--define(wxStyledTextCtrl_SetWhitespaceChars, 3342).
--define(wxStyledTextCtrl_SetCharsDefault, 3343).
--define(wxStyledTextCtrl_AutoCompGetCurrent, 3344).
--define(wxStyledTextCtrl_Allocate, 3345).
--define(wxStyledTextCtrl_FindColumn, 3346).
--define(wxStyledTextCtrl_GetCaretSticky, 3347).
--define(wxStyledTextCtrl_SetCaretSticky, 3348).
--define(wxStyledTextCtrl_ToggleCaretSticky, 3349).
--define(wxStyledTextCtrl_SetPasteConvertEndings, 3350).
--define(wxStyledTextCtrl_GetPasteConvertEndings, 3351).
--define(wxStyledTextCtrl_SelectionDuplicate, 3352).
--define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3353).
--define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3354).
--define(wxStyledTextCtrl_StartRecord, 3355).
--define(wxStyledTextCtrl_StopRecord, 3356).
--define(wxStyledTextCtrl_SetLexer, 3357).
--define(wxStyledTextCtrl_GetLexer, 3358).
--define(wxStyledTextCtrl_Colourise, 3359).
--define(wxStyledTextCtrl_SetProperty, 3360).
--define(wxStyledTextCtrl_SetKeyWords, 3361).
--define(wxStyledTextCtrl_SetLexerLanguage, 3362).
--define(wxStyledTextCtrl_GetProperty, 3363).
--define(wxStyledTextCtrl_GetStyleBitsNeeded, 3364).
--define(wxStyledTextCtrl_GetCurrentLine, 3365).
--define(wxStyledTextCtrl_StyleSetSpec, 3366).
--define(wxStyledTextCtrl_StyleSetFont, 3367).
--define(wxStyledTextCtrl_StyleSetFontAttr, 3368).
--define(wxStyledTextCtrl_StyleSetCharacterSet, 3369).
--define(wxStyledTextCtrl_StyleSetFontEncoding, 3370).
--define(wxStyledTextCtrl_CmdKeyExecute, 3371).
--define(wxStyledTextCtrl_SetMargins, 3372).
--define(wxStyledTextCtrl_GetSelection, 3373).
--define(wxStyledTextCtrl_PointFromPosition, 3374).
--define(wxStyledTextCtrl_ScrollToLine, 3375).
--define(wxStyledTextCtrl_ScrollToColumn, 3376).
--define(wxStyledTextCtrl_SetVScrollBar, 3377).
--define(wxStyledTextCtrl_SetHScrollBar, 3378).
--define(wxStyledTextCtrl_GetLastKeydownProcessed, 3379).
--define(wxStyledTextCtrl_SetLastKeydownProcessed, 3380).
--define(wxStyledTextCtrl_SaveFile, 3381).
--define(wxStyledTextCtrl_LoadFile, 3382).
--define(wxStyledTextCtrl_DoDragOver, 3383).
--define(wxStyledTextCtrl_DoDropText, 3384).
--define(wxStyledTextCtrl_GetUseAntiAliasing, 3385).
--define(wxStyledTextCtrl_AddTextRaw, 3386).
--define(wxStyledTextCtrl_InsertTextRaw, 3387).
--define(wxStyledTextCtrl_GetCurLineRaw, 3388).
--define(wxStyledTextCtrl_GetLineRaw, 3389).
--define(wxStyledTextCtrl_GetSelectedTextRaw, 3390).
--define(wxStyledTextCtrl_GetTextRangeRaw, 3391).
--define(wxStyledTextCtrl_SetTextRaw, 3392).
--define(wxStyledTextCtrl_GetTextRaw, 3393).
--define(wxStyledTextCtrl_AppendTextRaw, 3394).
--define(wxArtProvider_GetBitmap, 3395).
--define(wxArtProvider_GetIcon, 3396).
--define(wxTreeEvent_GetKeyCode, 3397).
--define(wxTreeEvent_GetItem, 3398).
--define(wxTreeEvent_GetKeyEvent, 3399).
--define(wxTreeEvent_GetLabel, 3400).
--define(wxTreeEvent_GetOldItem, 3401).
--define(wxTreeEvent_GetPoint, 3402).
--define(wxTreeEvent_IsEditCancelled, 3403).
--define(wxTreeEvent_SetToolTip, 3404).
--define(wxNotebookEvent_GetOldSelection, 3405).
--define(wxNotebookEvent_GetSelection, 3406).
--define(wxNotebookEvent_SetOldSelection, 3407).
--define(wxNotebookEvent_SetSelection, 3408).
--define(wxFileDataObject_new, 3409).
--define(wxFileDataObject_AddFile, 3410).
--define(wxFileDataObject_GetFilenames, 3411).
--define(wxFileDataObject_destroy, 3412).
--define(wxTextDataObject_new, 3413).
--define(wxTextDataObject_GetTextLength, 3414).
--define(wxTextDataObject_GetText, 3415).
--define(wxTextDataObject_SetText, 3416).
--define(wxTextDataObject_destroy, 3417).
--define(wxBitmapDataObject_new_1_1, 3418).
--define(wxBitmapDataObject_new_1_0, 3419).
--define(wxBitmapDataObject_GetBitmap, 3420).
--define(wxBitmapDataObject_SetBitmap, 3421).
--define(wxBitmapDataObject_destroy, 3422).
--define(wxClipboard_new, 3424).
--define(wxClipboard_destruct, 3425).
--define(wxClipboard_AddData, 3426).
--define(wxClipboard_Clear, 3427).
--define(wxClipboard_Close, 3428).
--define(wxClipboard_Flush, 3429).
--define(wxClipboard_GetData, 3430).
--define(wxClipboard_IsOpened, 3431).
--define(wxClipboard_Open, 3432).
--define(wxClipboard_SetData, 3433).
--define(wxClipboard_UsePrimarySelection, 3435).
--define(wxClipboard_IsSupported, 3436).
--define(wxClipboard_Get, 3437).
--define(wxSpinEvent_GetPosition, 3438).
--define(wxSpinEvent_SetPosition, 3439).
--define(wxSplitterWindow_new_0, 3440).
--define(wxSplitterWindow_new_2, 3441).
--define(wxSplitterWindow_destruct, 3442).
--define(wxSplitterWindow_Create, 3443).
--define(wxSplitterWindow_GetMinimumPaneSize, 3444).
--define(wxSplitterWindow_GetSashGravity, 3445).
--define(wxSplitterWindow_GetSashPosition, 3446).
--define(wxSplitterWindow_GetSplitMode, 3447).
--define(wxSplitterWindow_GetWindow1, 3448).
--define(wxSplitterWindow_GetWindow2, 3449).
--define(wxSplitterWindow_Initialize, 3450).
--define(wxSplitterWindow_IsSplit, 3451).
--define(wxSplitterWindow_ReplaceWindow, 3452).
--define(wxSplitterWindow_SetSashGravity, 3453).
--define(wxSplitterWindow_SetSashPosition, 3454).
--define(wxSplitterWindow_SetSashSize, 3455).
--define(wxSplitterWindow_SetMinimumPaneSize, 3456).
--define(wxSplitterWindow_SetSplitMode, 3457).
--define(wxSplitterWindow_SplitHorizontally, 3458).
--define(wxSplitterWindow_SplitVertically, 3459).
--define(wxSplitterWindow_Unsplit, 3460).
--define(wxSplitterWindow_UpdateSize, 3461).
--define(wxSplitterEvent_GetSashPosition, 3462).
--define(wxSplitterEvent_GetX, 3463).
--define(wxSplitterEvent_GetY, 3464).
--define(wxSplitterEvent_GetWindowBeingRemoved, 3465).
--define(wxSplitterEvent_SetSashPosition, 3466).
--define(wxHtmlWindow_new_0, 3467).
--define(wxHtmlWindow_new_2, 3468).
--define(wxHtmlWindow_AppendToPage, 3469).
--define(wxHtmlWindow_GetOpenedAnchor, 3470).
--define(wxHtmlWindow_GetOpenedPage, 3471).
--define(wxHtmlWindow_GetOpenedPageTitle, 3472).
--define(wxHtmlWindow_GetRelatedFrame, 3473).
--define(wxHtmlWindow_HistoryBack, 3474).
--define(wxHtmlWindow_HistoryCanBack, 3475).
--define(wxHtmlWindow_HistoryCanForward, 3476).
--define(wxHtmlWindow_HistoryClear, 3477).
--define(wxHtmlWindow_HistoryForward, 3478).
--define(wxHtmlWindow_LoadFile, 3479).
--define(wxHtmlWindow_LoadPage, 3480).
--define(wxHtmlWindow_SelectAll, 3481).
--define(wxHtmlWindow_SelectionToText, 3482).
--define(wxHtmlWindow_SelectLine, 3483).
--define(wxHtmlWindow_SelectWord, 3484).
--define(wxHtmlWindow_SetBorders, 3485).
--define(wxHtmlWindow_SetFonts, 3486).
--define(wxHtmlWindow_SetPage, 3487).
--define(wxHtmlWindow_SetRelatedFrame, 3488).
--define(wxHtmlWindow_SetRelatedStatusBar, 3489).
--define(wxHtmlWindow_ToText, 3490).
--define(wxHtmlWindow_destroy, 3491).
--define(wxHtmlLinkEvent_GetLinkInfo, 3492).
--define(wxSystemSettings_GetColour, 3493).
--define(wxSystemSettings_GetFont, 3494).
--define(wxSystemSettings_GetMetric, 3495).
--define(wxSystemSettings_GetScreenType, 3496).
--define(wxSystemOptions_GetOption, 3497).
--define(wxSystemOptions_GetOptionInt, 3498).
--define(wxSystemOptions_HasOption, 3499).
--define(wxSystemOptions_IsFalse, 3500).
--define(wxSystemOptions_SetOption_2_1, 3501).
--define(wxSystemOptions_SetOption_2_0, 3502).
--define(wxAuiNotebookEvent_SetSelection, 3503).
--define(wxAuiNotebookEvent_GetSelection, 3504).
--define(wxAuiNotebookEvent_SetOldSelection, 3505).
--define(wxAuiNotebookEvent_GetOldSelection, 3506).
--define(wxAuiNotebookEvent_SetDragSource, 3507).
--define(wxAuiNotebookEvent_GetDragSource, 3508).
--define(wxAuiManagerEvent_SetManager, 3509).
--define(wxAuiManagerEvent_GetManager, 3510).
--define(wxAuiManagerEvent_SetPane, 3511).
--define(wxAuiManagerEvent_GetPane, 3512).
--define(wxAuiManagerEvent_SetButton, 3513).
--define(wxAuiManagerEvent_GetButton, 3514).
--define(wxAuiManagerEvent_SetDC, 3515).
--define(wxAuiManagerEvent_GetDC, 3516).
--define(wxAuiManagerEvent_Veto, 3517).
--define(wxAuiManagerEvent_GetVeto, 3518).
--define(wxAuiManagerEvent_SetCanVeto, 3519).
--define(wxAuiManagerEvent_CanVeto, 3520).
--define(wxLogNull_new, 3521).
--define(wxLogNull_destroy, 3522).
--define(wxTaskBarIcon_new, 3523).
--define(wxTaskBarIcon_destruct, 3524).
--define(wxTaskBarIcon_PopupMenu, 3525).
--define(wxTaskBarIcon_RemoveIcon, 3526).
--define(wxTaskBarIcon_SetIcon, 3527).
--define(wxLocale_new_0, 3528).
--define(wxLocale_new_2, 3530).
--define(wxLocale_destruct, 3531).
--define(wxLocale_Init, 3533).
--define(wxLocale_AddCatalog_1, 3534).
--define(wxLocale_AddCatalog_3, 3535).
--define(wxLocale_AddCatalogLookupPathPrefix, 3536).
--define(wxLocale_GetCanonicalName, 3537).
--define(wxLocale_GetLanguage, 3538).
--define(wxLocale_GetLanguageName, 3539).
--define(wxLocale_GetLocale, 3540).
--define(wxLocale_GetName, 3541).
--define(wxLocale_GetString_2, 3542).
--define(wxLocale_GetString_4, 3543).
--define(wxLocale_GetHeaderValue, 3544).
--define(wxLocale_GetSysName, 3545).
--define(wxLocale_GetSystemEncoding, 3546).
--define(wxLocale_GetSystemEncodingName, 3547).
--define(wxLocale_GetSystemLanguage, 3548).
--define(wxLocale_IsLoaded, 3549).
--define(wxLocale_IsOk, 3550).
--define(wxActivateEvent_GetActive, 3551).
--define(wxPopupWindow_new_2, 3553).
--define(wxPopupWindow_new_0, 3554).
--define(wxPopupWindow_destruct, 3556).
--define(wxPopupWindow_Create, 3557).
--define(wxPopupWindow_Position, 3558).
--define(wxPopupTransientWindow_new_0, 3559).
--define(wxPopupTransientWindow_new_2, 3560).
--define(wxPopupTransientWindow_destruct, 3561).
--define(wxPopupTransientWindow_Popup, 3562).
--define(wxPopupTransientWindow_Dismiss, 3563).
+-define(wxWindow_SetTransparent, 284).
+-define(wxWindow_CanSetTransparent, 285).
+-define(wxWindow_IsDoubleBuffered, 286).
+-define(wxWindow_SetDoubleBuffered, 287).
+-define(wxTopLevelWindow_GetIcon, 288).
+-define(wxTopLevelWindow_GetIcons, 289).
+-define(wxTopLevelWindow_GetTitle, 290).
+-define(wxTopLevelWindow_IsActive, 291).
+-define(wxTopLevelWindow_Iconize, 292).
+-define(wxTopLevelWindow_IsFullScreen, 293).
+-define(wxTopLevelWindow_IsIconized, 294).
+-define(wxTopLevelWindow_IsMaximized, 295).
+-define(wxTopLevelWindow_Maximize, 296).
+-define(wxTopLevelWindow_RequestUserAttention, 297).
+-define(wxTopLevelWindow_SetIcon, 298).
+-define(wxTopLevelWindow_SetIcons, 299).
+-define(wxTopLevelWindow_CenterOnScreen, 300).
+-define(wxTopLevelWindow_CentreOnScreen, 301).
+-define(wxTopLevelWindow_SetShape, 303).
+-define(wxTopLevelWindow_SetTitle, 304).
+-define(wxTopLevelWindow_ShowFullScreen, 305).
+-define(wxFrame_new_4, 307).
+-define(wxFrame_new_0, 308).
+-define(wxFrame_destruct, 310).
+-define(wxFrame_Create, 311).
+-define(wxFrame_CreateStatusBar, 312).
+-define(wxFrame_CreateToolBar, 313).
+-define(wxFrame_GetClientAreaOrigin, 314).
+-define(wxFrame_GetMenuBar, 315).
+-define(wxFrame_GetStatusBar, 316).
+-define(wxFrame_GetStatusBarPane, 317).
+-define(wxFrame_GetToolBar, 318).
+-define(wxFrame_ProcessCommand, 319).
+-define(wxFrame_SendSizeEvent, 320).
+-define(wxFrame_SetMenuBar, 321).
+-define(wxFrame_SetStatusBar, 322).
+-define(wxFrame_SetStatusBarPane, 323).
+-define(wxFrame_SetStatusText, 324).
+-define(wxFrame_SetStatusWidths, 325).
+-define(wxFrame_SetToolBar, 326).
+-define(wxMiniFrame_new_0, 327).
+-define(wxMiniFrame_new_4, 328).
+-define(wxMiniFrame_Create, 329).
+-define(wxMiniFrame_destroy, 330).
+-define(wxSplashScreen_new_0, 331).
+-define(wxSplashScreen_new_6, 332).
+-define(wxSplashScreen_destruct, 333).
+-define(wxSplashScreen_GetSplashStyle, 334).
+-define(wxSplashScreen_GetTimeout, 335).
+-define(wxPanel_new_0, 336).
+-define(wxPanel_new_6, 337).
+-define(wxPanel_new_2, 338).
+-define(wxPanel_destruct, 339).
+-define(wxPanel_InitDialog, 340).
+-define(wxPanel_SetFocusIgnoringChildren, 341).
+-define(wxScrolledWindow_new_0, 342).
+-define(wxScrolledWindow_new_2, 343).
+-define(wxScrolledWindow_destruct, 344).
+-define(wxScrolledWindow_CalcScrolledPosition_4, 345).
+-define(wxScrolledWindow_CalcScrolledPosition_1, 346).
+-define(wxScrolledWindow_CalcUnscrolledPosition_4, 347).
+-define(wxScrolledWindow_CalcUnscrolledPosition_1, 348).
+-define(wxScrolledWindow_EnableScrolling, 349).
+-define(wxScrolledWindow_GetScrollPixelsPerUnit, 350).
+-define(wxScrolledWindow_GetViewStart, 351).
+-define(wxScrolledWindow_DoPrepareDC, 352).
+-define(wxScrolledWindow_PrepareDC, 353).
+-define(wxScrolledWindow_Scroll, 354).
+-define(wxScrolledWindow_SetScrollbars, 355).
+-define(wxScrolledWindow_SetScrollRate, 356).
+-define(wxScrolledWindow_SetTargetWindow, 357).
+-define(wxSashWindow_new_0, 358).
+-define(wxSashWindow_new_2, 359).
+-define(wxSashWindow_destruct, 360).
+-define(wxSashWindow_GetSashVisible, 361).
+-define(wxSashWindow_GetMaximumSizeX, 362).
+-define(wxSashWindow_GetMaximumSizeY, 363).
+-define(wxSashWindow_GetMinimumSizeX, 364).
+-define(wxSashWindow_GetMinimumSizeY, 365).
+-define(wxSashWindow_SetMaximumSizeX, 366).
+-define(wxSashWindow_SetMaximumSizeY, 367).
+-define(wxSashWindow_SetMinimumSizeX, 368).
+-define(wxSashWindow_SetMinimumSizeY, 369).
+-define(wxSashWindow_SetSashVisible, 370).
+-define(wxSashLayoutWindow_new_0, 371).
+-define(wxSashLayoutWindow_new_2, 372).
+-define(wxSashLayoutWindow_Create, 373).
+-define(wxSashLayoutWindow_GetAlignment, 374).
+-define(wxSashLayoutWindow_GetOrientation, 375).
+-define(wxSashLayoutWindow_SetAlignment, 376).
+-define(wxSashLayoutWindow_SetDefaultSize, 377).
+-define(wxSashLayoutWindow_SetOrientation, 378).
+-define(wxSashLayoutWindow_destroy, 379).
+-define(wxGrid_new_0, 380).
+-define(wxGrid_new_3, 381).
+-define(wxGrid_new_4, 382).
+-define(wxGrid_destruct, 383).
+-define(wxGrid_AppendCols, 384).
+-define(wxGrid_AppendRows, 385).
+-define(wxGrid_AutoSize, 386).
+-define(wxGrid_AutoSizeColumn, 387).
+-define(wxGrid_AutoSizeColumns, 388).
+-define(wxGrid_AutoSizeRow, 389).
+-define(wxGrid_AutoSizeRows, 390).
+-define(wxGrid_BeginBatch, 391).
+-define(wxGrid_BlockToDeviceRect, 392).
+-define(wxGrid_CanDragColSize, 393).
+-define(wxGrid_CanDragRowSize, 394).
+-define(wxGrid_CanDragGridSize, 395).
+-define(wxGrid_CanEnableCellControl, 396).
+-define(wxGrid_CellToRect_2, 397).
+-define(wxGrid_CellToRect_1, 398).
+-define(wxGrid_ClearGrid, 399).
+-define(wxGrid_ClearSelection, 400).
+-define(wxGrid_CreateGrid, 401).
+-define(wxGrid_DeleteCols, 402).
+-define(wxGrid_DeleteRows, 403).
+-define(wxGrid_DisableCellEditControl, 404).
+-define(wxGrid_DisableDragColSize, 405).
+-define(wxGrid_DisableDragGridSize, 406).
+-define(wxGrid_DisableDragRowSize, 407).
+-define(wxGrid_EnableCellEditControl, 408).
+-define(wxGrid_EnableDragColSize, 409).
+-define(wxGrid_EnableDragGridSize, 410).
+-define(wxGrid_EnableDragRowSize, 411).
+-define(wxGrid_EnableEditing, 412).
+-define(wxGrid_EnableGridLines, 413).
+-define(wxGrid_EndBatch, 414).
+-define(wxGrid_Fit, 415).
+-define(wxGrid_ForceRefresh, 416).
+-define(wxGrid_GetBatchCount, 417).
+-define(wxGrid_GetCellAlignment, 418).
+-define(wxGrid_GetCellBackgroundColour, 419).
+-define(wxGrid_GetCellEditor, 420).
+-define(wxGrid_GetCellFont, 421).
+-define(wxGrid_GetCellRenderer, 422).
+-define(wxGrid_GetCellTextColour, 423).
+-define(wxGrid_GetCellValue_2, 424).
+-define(wxGrid_GetCellValue_1, 425).
+-define(wxGrid_GetColLabelAlignment, 426).
+-define(wxGrid_GetColLabelSize, 427).
+-define(wxGrid_GetColLabelValue, 428).
+-define(wxGrid_GetColMinimalAcceptableWidth, 429).
+-define(wxGrid_GetDefaultCellAlignment, 430).
+-define(wxGrid_GetDefaultCellBackgroundColour, 431).
+-define(wxGrid_GetDefaultCellFont, 432).
+-define(wxGrid_GetDefaultCellTextColour, 433).
+-define(wxGrid_GetDefaultColLabelSize, 434).
+-define(wxGrid_GetDefaultColSize, 435).
+-define(wxGrid_GetDefaultEditor, 436).
+-define(wxGrid_GetDefaultEditorForCell_2, 437).
+-define(wxGrid_GetDefaultEditorForCell_1, 438).
+-define(wxGrid_GetDefaultEditorForType, 439).
+-define(wxGrid_GetDefaultRenderer, 440).
+-define(wxGrid_GetDefaultRendererForCell, 441).
+-define(wxGrid_GetDefaultRendererForType, 442).
+-define(wxGrid_GetDefaultRowLabelSize, 443).
+-define(wxGrid_GetDefaultRowSize, 444).
+-define(wxGrid_GetGridCursorCol, 445).
+-define(wxGrid_GetGridCursorRow, 446).
+-define(wxGrid_GetGridLineColour, 447).
+-define(wxGrid_GridLinesEnabled, 448).
+-define(wxGrid_GetLabelBackgroundColour, 449).
+-define(wxGrid_GetLabelFont, 450).
+-define(wxGrid_GetLabelTextColour, 451).
+-define(wxGrid_GetNumberCols, 452).
+-define(wxGrid_GetNumberRows, 453).
+-define(wxGrid_GetOrCreateCellAttr, 454).
+-define(wxGrid_GetRowMinimalAcceptableHeight, 455).
+-define(wxGrid_GetRowLabelAlignment, 456).
+-define(wxGrid_GetRowLabelSize, 457).
+-define(wxGrid_GetRowLabelValue, 458).
+-define(wxGrid_GetRowSize, 459).
+-define(wxGrid_GetScrollLineX, 460).
+-define(wxGrid_GetScrollLineY, 461).
+-define(wxGrid_GetSelectedCells, 462).
+-define(wxGrid_GetSelectedCols, 463).
+-define(wxGrid_GetSelectedRows, 464).
+-define(wxGrid_GetSelectionBackground, 465).
+-define(wxGrid_GetSelectionBlockTopLeft, 466).
+-define(wxGrid_GetSelectionBlockBottomRight, 467).
+-define(wxGrid_GetSelectionForeground, 468).
+-define(wxGrid_GetViewWidth, 469).
+-define(wxGrid_GetGridWindow, 470).
+-define(wxGrid_GetGridRowLabelWindow, 471).
+-define(wxGrid_GetGridColLabelWindow, 472).
+-define(wxGrid_GetGridCornerLabelWindow, 473).
+-define(wxGrid_HideCellEditControl, 474).
+-define(wxGrid_InsertCols, 475).
+-define(wxGrid_InsertRows, 476).
+-define(wxGrid_IsCellEditControlEnabled, 477).
+-define(wxGrid_IsCurrentCellReadOnly, 478).
+-define(wxGrid_IsEditable, 479).
+-define(wxGrid_IsInSelection_2, 480).
+-define(wxGrid_IsInSelection_1, 481).
+-define(wxGrid_IsReadOnly, 482).
+-define(wxGrid_IsSelection, 483).
+-define(wxGrid_IsVisible_3, 484).
+-define(wxGrid_IsVisible_2, 485).
+-define(wxGrid_MakeCellVisible_2, 486).
+-define(wxGrid_MakeCellVisible_1, 487).
+-define(wxGrid_MoveCursorDown, 488).
+-define(wxGrid_MoveCursorLeft, 489).
+-define(wxGrid_MoveCursorRight, 490).
+-define(wxGrid_MoveCursorUp, 491).
+-define(wxGrid_MoveCursorDownBlock, 492).
+-define(wxGrid_MoveCursorLeftBlock, 493).
+-define(wxGrid_MoveCursorRightBlock, 494).
+-define(wxGrid_MoveCursorUpBlock, 495).
+-define(wxGrid_MovePageDown, 496).
+-define(wxGrid_MovePageUp, 497).
+-define(wxGrid_RegisterDataType, 498).
+-define(wxGrid_SaveEditControlValue, 499).
+-define(wxGrid_SelectAll, 500).
+-define(wxGrid_SelectBlock_5, 501).
+-define(wxGrid_SelectBlock_3, 502).
+-define(wxGrid_SelectCol, 503).
+-define(wxGrid_SelectRow, 504).
+-define(wxGrid_SetCellAlignment_4, 505).
+-define(wxGrid_SetCellAlignment_3, 506).
+-define(wxGrid_SetCellAlignment_1, 507).
+-define(wxGrid_SetCellBackgroundColour_3_0, 508).
+-define(wxGrid_SetCellBackgroundColour_1, 509).
+-define(wxGrid_SetCellBackgroundColour_3_1, 510).
+-define(wxGrid_SetCellEditor, 511).
+-define(wxGrid_SetCellFont, 512).
+-define(wxGrid_SetCellRenderer, 513).
+-define(wxGrid_SetCellTextColour_3_0, 514).
+-define(wxGrid_SetCellTextColour_3_1, 515).
+-define(wxGrid_SetCellTextColour_1, 516).
+-define(wxGrid_SetCellValue_3_0, 517).
+-define(wxGrid_SetCellValue_2, 518).
+-define(wxGrid_SetCellValue_3_1, 519).
+-define(wxGrid_SetColAttr, 520).
+-define(wxGrid_SetColFormatBool, 521).
+-define(wxGrid_SetColFormatNumber, 522).
+-define(wxGrid_SetColFormatFloat, 523).
+-define(wxGrid_SetColFormatCustom, 524).
+-define(wxGrid_SetColLabelAlignment, 525).
+-define(wxGrid_SetColLabelSize, 526).
+-define(wxGrid_SetColLabelValue, 527).
+-define(wxGrid_SetColMinimalWidth, 528).
+-define(wxGrid_SetColMinimalAcceptableWidth, 529).
+-define(wxGrid_SetColSize, 530).
+-define(wxGrid_SetDefaultCellAlignment, 531).
+-define(wxGrid_SetDefaultCellBackgroundColour, 532).
+-define(wxGrid_SetDefaultCellFont, 533).
+-define(wxGrid_SetDefaultCellTextColour, 534).
+-define(wxGrid_SetDefaultEditor, 535).
+-define(wxGrid_SetDefaultRenderer, 536).
+-define(wxGrid_SetDefaultColSize, 537).
+-define(wxGrid_SetDefaultRowSize, 538).
+-define(wxGrid_SetGridCursor, 539).
+-define(wxGrid_SetGridLineColour, 540).
+-define(wxGrid_SetLabelBackgroundColour, 541).
+-define(wxGrid_SetLabelFont, 542).
+-define(wxGrid_SetLabelTextColour, 543).
+-define(wxGrid_SetMargins, 544).
+-define(wxGrid_SetReadOnly, 545).
+-define(wxGrid_SetRowAttr, 546).
+-define(wxGrid_SetRowLabelAlignment, 547).
+-define(wxGrid_SetRowLabelSize, 548).
+-define(wxGrid_SetRowLabelValue, 549).
+-define(wxGrid_SetRowMinimalHeight, 550).
+-define(wxGrid_SetRowMinimalAcceptableHeight, 551).
+-define(wxGrid_SetRowSize, 552).
+-define(wxGrid_SetScrollLineX, 553).
+-define(wxGrid_SetScrollLineY, 554).
+-define(wxGrid_SetSelectionBackground, 555).
+-define(wxGrid_SetSelectionForeground, 556).
+-define(wxGrid_SetSelectionMode, 557).
+-define(wxGrid_ShowCellEditControl, 558).
+-define(wxGrid_XToCol, 559).
+-define(wxGrid_XToEdgeOfCol, 560).
+-define(wxGrid_YToEdgeOfRow, 561).
+-define(wxGrid_YToRow, 562).
+-define(wxGridCellRenderer_Draw, 563).
+-define(wxGridCellRenderer_GetBestSize, 564).
+-define(wxGridCellEditor_Create, 565).
+-define(wxGridCellEditor_IsCreated, 566).
+-define(wxGridCellEditor_SetSize, 567).
+-define(wxGridCellEditor_Show, 568).
+-define(wxGridCellEditor_PaintBackground, 569).
+-define(wxGridCellEditor_BeginEdit, 570).
+-define(wxGridCellEditor_EndEdit, 571).
+-define(wxGridCellEditor_Reset, 572).
+-define(wxGridCellEditor_StartingKey, 573).
+-define(wxGridCellEditor_StartingClick, 574).
+-define(wxGridCellEditor_HandleReturn, 575).
+-define(wxGridCellBoolRenderer_new, 576).
+-define(wxGridCellBoolRenderer_destroy, 577).
+-define(wxGridCellBoolEditor_new, 578).
+-define(wxGridCellBoolEditor_IsTrueValue, 579).
+-define(wxGridCellBoolEditor_UseStringValues, 580).
+-define(wxGridCellBoolEditor_destroy, 581).
+-define(wxGridCellFloatRenderer_new, 582).
+-define(wxGridCellFloatRenderer_GetPrecision, 583).
+-define(wxGridCellFloatRenderer_GetWidth, 584).
+-define(wxGridCellFloatRenderer_SetParameters, 585).
+-define(wxGridCellFloatRenderer_SetPrecision, 586).
+-define(wxGridCellFloatRenderer_SetWidth, 587).
+-define(wxGridCellFloatRenderer_destroy, 588).
+-define(wxGridCellFloatEditor_new, 589).
+-define(wxGridCellFloatEditor_SetParameters, 590).
+-define(wxGridCellFloatEditor_destroy, 591).
+-define(wxGridCellStringRenderer_new, 592).
+-define(wxGridCellStringRenderer_destroy, 593).
+-define(wxGridCellTextEditor_new, 594).
+-define(wxGridCellTextEditor_SetParameters, 595).
+-define(wxGridCellTextEditor_destroy, 596).
+-define(wxGridCellChoiceEditor_new, 598).
+-define(wxGridCellChoiceEditor_SetParameters, 599).
+-define(wxGridCellChoiceEditor_destroy, 600).
+-define(wxGridCellNumberRenderer_new, 601).
+-define(wxGridCellNumberRenderer_destroy, 602).
+-define(wxGridCellNumberEditor_new, 603).
+-define(wxGridCellNumberEditor_GetValue, 604).
+-define(wxGridCellNumberEditor_SetParameters, 605).
+-define(wxGridCellNumberEditor_destroy, 606).
+-define(wxGridCellAttr_SetTextColour, 607).
+-define(wxGridCellAttr_SetBackgroundColour, 608).
+-define(wxGridCellAttr_SetFont, 609).
+-define(wxGridCellAttr_SetAlignment, 610).
+-define(wxGridCellAttr_SetReadOnly, 611).
+-define(wxGridCellAttr_SetRenderer, 612).
+-define(wxGridCellAttr_SetEditor, 613).
+-define(wxGridCellAttr_HasTextColour, 614).
+-define(wxGridCellAttr_HasBackgroundColour, 615).
+-define(wxGridCellAttr_HasFont, 616).
+-define(wxGridCellAttr_HasAlignment, 617).
+-define(wxGridCellAttr_HasRenderer, 618).
+-define(wxGridCellAttr_HasEditor, 619).
+-define(wxGridCellAttr_GetTextColour, 620).
+-define(wxGridCellAttr_GetBackgroundColour, 621).
+-define(wxGridCellAttr_GetFont, 622).
+-define(wxGridCellAttr_GetAlignment, 623).
+-define(wxGridCellAttr_GetRenderer, 624).
+-define(wxGridCellAttr_GetEditor, 625).
+-define(wxGridCellAttr_IsReadOnly, 626).
+-define(wxGridCellAttr_SetDefAttr, 627).
+-define(wxDC_Blit, 628).
+-define(wxDC_CalcBoundingBox, 629).
+-define(wxDC_Clear, 630).
+-define(wxDC_ComputeScaleAndOrigin, 631).
+-define(wxDC_CrossHair, 632).
+-define(wxDC_DestroyClippingRegion, 633).
+-define(wxDC_DeviceToLogicalX, 634).
+-define(wxDC_DeviceToLogicalXRel, 635).
+-define(wxDC_DeviceToLogicalY, 636).
+-define(wxDC_DeviceToLogicalYRel, 637).
+-define(wxDC_DrawArc, 638).
+-define(wxDC_DrawBitmap, 639).
+-define(wxDC_DrawCheckMark, 640).
+-define(wxDC_DrawCircle, 641).
+-define(wxDC_DrawEllipse_2, 643).
+-define(wxDC_DrawEllipse_1, 644).
+-define(wxDC_DrawEllipticArc, 645).
+-define(wxDC_DrawIcon, 646).
+-define(wxDC_DrawLabel, 647).
+-define(wxDC_DrawLine, 648).
+-define(wxDC_DrawLines, 649).
+-define(wxDC_DrawPolygon, 651).
+-define(wxDC_DrawPoint, 653).
+-define(wxDC_DrawRectangle_2, 655).
+-define(wxDC_DrawRectangle_1, 656).
+-define(wxDC_DrawRotatedText, 657).
+-define(wxDC_DrawRoundedRectangle_3, 659).
+-define(wxDC_DrawRoundedRectangle_2, 660).
+-define(wxDC_DrawText, 661).
+-define(wxDC_EndDoc, 662).
+-define(wxDC_EndPage, 663).
+-define(wxDC_FloodFill, 664).
+-define(wxDC_GetBackground, 665).
+-define(wxDC_GetBackgroundMode, 666).
+-define(wxDC_GetBrush, 667).
+-define(wxDC_GetCharHeight, 668).
+-define(wxDC_GetCharWidth, 669).
+-define(wxDC_GetClippingBox, 670).
+-define(wxDC_GetFont, 672).
+-define(wxDC_GetLayoutDirection, 673).
+-define(wxDC_GetLogicalFunction, 674).
+-define(wxDC_GetMapMode, 675).
+-define(wxDC_GetMultiLineTextExtent_4, 676).
+-define(wxDC_GetMultiLineTextExtent_1, 677).
+-define(wxDC_GetPartialTextExtents, 678).
+-define(wxDC_GetPen, 679).
+-define(wxDC_GetPixel, 680).
+-define(wxDC_GetPPI, 681).
+-define(wxDC_GetSize, 683).
+-define(wxDC_GetSizeMM, 685).
+-define(wxDC_GetTextBackground, 686).
+-define(wxDC_GetTextExtent_4, 687).
+-define(wxDC_GetTextExtent_1, 688).
+-define(wxDC_GetTextForeground, 690).
+-define(wxDC_GetUserScale, 691).
+-define(wxDC_GradientFillConcentric_3, 692).
+-define(wxDC_GradientFillConcentric_4, 693).
+-define(wxDC_GradientFillLinear, 694).
+-define(wxDC_LogicalToDeviceX, 695).
+-define(wxDC_LogicalToDeviceXRel, 696).
+-define(wxDC_LogicalToDeviceY, 697).
+-define(wxDC_LogicalToDeviceYRel, 698).
+-define(wxDC_MaxX, 699).
+-define(wxDC_MaxY, 700).
+-define(wxDC_MinX, 701).
+-define(wxDC_MinY, 702).
+-define(wxDC_IsOk, 703).
+-define(wxDC_ResetBoundingBox, 704).
+-define(wxDC_SetAxisOrientation, 705).
+-define(wxDC_SetBackground, 706).
+-define(wxDC_SetBackgroundMode, 707).
+-define(wxDC_SetBrush, 708).
+-define(wxDC_SetClippingRegion_2, 710).
+-define(wxDC_SetClippingRegion_1_1, 711).
+-define(wxDC_SetClippingRegion_1_0, 712).
+-define(wxDC_SetDeviceOrigin, 713).
+-define(wxDC_SetFont, 714).
+-define(wxDC_SetLayoutDirection, 715).
+-define(wxDC_SetLogicalFunction, 716).
+-define(wxDC_SetMapMode, 717).
+-define(wxDC_SetPalette, 718).
+-define(wxDC_SetPen, 719).
+-define(wxDC_SetTextBackground, 720).
+-define(wxDC_SetTextForeground, 721).
+-define(wxDC_SetUserScale, 722).
+-define(wxDC_StartDoc, 723).
+-define(wxDC_StartPage, 724).
+-define(wxMirrorDC_new, 725).
+-define(wxMirrorDC_destroy, 726).
+-define(wxScreenDC_new, 727).
+-define(wxScreenDC_destruct, 728).
+-define(wxPostScriptDC_new_0, 729).
+-define(wxPostScriptDC_new_1, 730).
+-define(wxPostScriptDC_destruct, 731).
+-define(wxPostScriptDC_SetResolution, 732).
+-define(wxPostScriptDC_GetResolution, 733).
+-define(wxWindowDC_new_0, 734).
+-define(wxWindowDC_new_1, 735).
+-define(wxWindowDC_destruct, 736).
+-define(wxClientDC_new_0, 737).
+-define(wxClientDC_new_1, 738).
+-define(wxClientDC_destroy, 739).
+-define(wxPaintDC_new_0, 740).
+-define(wxPaintDC_new_1, 741).
+-define(wxPaintDC_destroy, 742).
+-define(wxMemoryDC_new_1_0, 744).
+-define(wxMemoryDC_new_1_1, 745).
+-define(wxMemoryDC_new_0, 746).
+-define(wxMemoryDC_destruct, 748).
+-define(wxMemoryDC_SelectObject, 749).
+-define(wxMemoryDC_SelectObjectAsSource, 750).
+-define(wxBufferedDC_new_0, 751).
+-define(wxBufferedDC_new_2, 752).
+-define(wxBufferedDC_new_3, 753).
+-define(wxBufferedDC_destruct, 754).
+-define(wxBufferedDC_Init_2, 755).
+-define(wxBufferedDC_Init_3, 756).
+-define(wxBufferedPaintDC_new_3, 757).
+-define(wxBufferedPaintDC_new_2, 758).
+-define(wxBufferedPaintDC_destruct, 759).
+-define(wxGraphicsObject_destruct, 760).
+-define(wxGraphicsObject_GetRenderer, 761).
+-define(wxGraphicsObject_IsNull, 762).
+-define(wxGraphicsContext_destruct, 763).
+-define(wxGraphicsContext_Create_1_1, 764).
+-define(wxGraphicsContext_Create_1_0, 765).
+-define(wxGraphicsContext_Create_0, 766).
+-define(wxGraphicsContext_CreatePen, 767).
+-define(wxGraphicsContext_CreateBrush, 768).
+-define(wxGraphicsContext_CreateRadialGradientBrush, 769).
+-define(wxGraphicsContext_CreateLinearGradientBrush, 770).
+-define(wxGraphicsContext_CreateFont, 771).
+-define(wxGraphicsContext_CreateMatrix, 772).
+-define(wxGraphicsContext_CreatePath, 773).
+-define(wxGraphicsContext_Clip_1, 774).
+-define(wxGraphicsContext_Clip_4, 775).
+-define(wxGraphicsContext_ResetClip, 776).
+-define(wxGraphicsContext_DrawBitmap, 777).
+-define(wxGraphicsContext_DrawEllipse, 778).
+-define(wxGraphicsContext_DrawIcon, 779).
+-define(wxGraphicsContext_DrawLines, 780).
+-define(wxGraphicsContext_DrawPath, 781).
+-define(wxGraphicsContext_DrawRectangle, 782).
+-define(wxGraphicsContext_DrawRoundedRectangle, 783).
+-define(wxGraphicsContext_DrawText_3, 784).
+-define(wxGraphicsContext_DrawText_4_0, 785).
+-define(wxGraphicsContext_DrawText_4_1, 786).
+-define(wxGraphicsContext_DrawText_5, 787).
+-define(wxGraphicsContext_FillPath, 788).
+-define(wxGraphicsContext_StrokePath, 789).
+-define(wxGraphicsContext_GetPartialTextExtents, 790).
+-define(wxGraphicsContext_GetTextExtent, 791).
+-define(wxGraphicsContext_Rotate, 792).
+-define(wxGraphicsContext_Scale, 793).
+-define(wxGraphicsContext_Translate, 794).
+-define(wxGraphicsContext_GetTransform, 795).
+-define(wxGraphicsContext_SetTransform, 796).
+-define(wxGraphicsContext_ConcatTransform, 797).
+-define(wxGraphicsContext_SetBrush_1_1, 798).
+-define(wxGraphicsContext_SetBrush_1_0, 799).
+-define(wxGraphicsContext_SetFont_1, 800).
+-define(wxGraphicsContext_SetFont_2, 801).
+-define(wxGraphicsContext_SetPen_1_0, 802).
+-define(wxGraphicsContext_SetPen_1_1, 803).
+-define(wxGraphicsContext_StrokeLine, 804).
+-define(wxGraphicsContext_StrokeLines, 805).
+-define(wxGraphicsMatrix_Concat, 807).
+-define(wxGraphicsMatrix_Get, 809).
+-define(wxGraphicsMatrix_Invert, 810).
+-define(wxGraphicsMatrix_IsEqual, 811).
+-define(wxGraphicsMatrix_IsIdentity, 813).
+-define(wxGraphicsMatrix_Rotate, 814).
+-define(wxGraphicsMatrix_Scale, 815).
+-define(wxGraphicsMatrix_Translate, 816).
+-define(wxGraphicsMatrix_Set, 817).
+-define(wxGraphicsMatrix_TransformPoint, 818).
+-define(wxGraphicsMatrix_TransformDistance, 819).
+-define(wxGraphicsPath_MoveToPoint_2, 820).
+-define(wxGraphicsPath_MoveToPoint_1, 821).
+-define(wxGraphicsPath_AddArc_6, 822).
+-define(wxGraphicsPath_AddArc_5, 823).
+-define(wxGraphicsPath_AddArcToPoint, 824).
+-define(wxGraphicsPath_AddCircle, 825).
+-define(wxGraphicsPath_AddCurveToPoint_6, 826).
+-define(wxGraphicsPath_AddCurveToPoint_3, 827).
+-define(wxGraphicsPath_AddEllipse, 828).
+-define(wxGraphicsPath_AddLineToPoint_2, 829).
+-define(wxGraphicsPath_AddLineToPoint_1, 830).
+-define(wxGraphicsPath_AddPath, 831).
+-define(wxGraphicsPath_AddQuadCurveToPoint, 832).
+-define(wxGraphicsPath_AddRectangle, 833).
+-define(wxGraphicsPath_AddRoundedRectangle, 834).
+-define(wxGraphicsPath_CloseSubpath, 835).
+-define(wxGraphicsPath_Contains_3, 836).
+-define(wxGraphicsPath_Contains_2, 837).
+-define(wxGraphicsPath_GetBox, 839).
+-define(wxGraphicsPath_GetCurrentPoint, 841).
+-define(wxGraphicsPath_Transform, 842).
+-define(wxGraphicsRenderer_GetDefaultRenderer, 843).
+-define(wxGraphicsRenderer_CreateContext_1_1, 844).
+-define(wxGraphicsRenderer_CreateContext_1_0, 845).
+-define(wxGraphicsRenderer_CreatePen, 846).
+-define(wxGraphicsRenderer_CreateBrush, 847).
+-define(wxGraphicsRenderer_CreateLinearGradientBrush, 848).
+-define(wxGraphicsRenderer_CreateRadialGradientBrush, 849).
+-define(wxGraphicsRenderer_CreateFont, 850).
+-define(wxGraphicsRenderer_CreateMatrix, 851).
+-define(wxGraphicsRenderer_CreatePath, 852).
+-define(wxMenuBar_new_1, 854).
+-define(wxMenuBar_new_0, 856).
+-define(wxMenuBar_destruct, 858).
+-define(wxMenuBar_Append, 859).
+-define(wxMenuBar_Check, 860).
+-define(wxMenuBar_Enable_2, 861).
+-define(wxMenuBar_Enable_1, 862).
+-define(wxMenuBar_EnableTop, 863).
+-define(wxMenuBar_FindMenu, 864).
+-define(wxMenuBar_FindMenuItem, 865).
+-define(wxMenuBar_FindItem, 866).
+-define(wxMenuBar_GetHelpString, 867).
+-define(wxMenuBar_GetLabel_1, 868).
+-define(wxMenuBar_GetLabel_0, 869).
+-define(wxMenuBar_GetLabelTop, 870).
+-define(wxMenuBar_GetMenu, 871).
+-define(wxMenuBar_GetMenuCount, 872).
+-define(wxMenuBar_Insert, 873).
+-define(wxMenuBar_IsChecked, 874).
+-define(wxMenuBar_IsEnabled_1, 875).
+-define(wxMenuBar_IsEnabled_0, 876).
+-define(wxMenuBar_Remove, 877).
+-define(wxMenuBar_Replace, 878).
+-define(wxMenuBar_SetHelpString, 879).
+-define(wxMenuBar_SetLabel_2, 880).
+-define(wxMenuBar_SetLabel_1, 881).
+-define(wxMenuBar_SetLabelTop, 882).
+-define(wxControl_GetLabel, 883).
+-define(wxControl_SetLabel, 884).
+-define(wxControlWithItems_Append_1, 885).
+-define(wxControlWithItems_Append_2, 886).
+-define(wxControlWithItems_appendStrings_1, 887).
+-define(wxControlWithItems_Clear, 888).
+-define(wxControlWithItems_Delete, 889).
+-define(wxControlWithItems_FindString, 890).
+-define(wxControlWithItems_getClientData, 891).
+-define(wxControlWithItems_setClientData, 892).
+-define(wxControlWithItems_GetCount, 893).
+-define(wxControlWithItems_GetSelection, 894).
+-define(wxControlWithItems_GetString, 895).
+-define(wxControlWithItems_GetStringSelection, 896).
+-define(wxControlWithItems_Insert_2, 897).
+-define(wxControlWithItems_Insert_3, 898).
+-define(wxControlWithItems_IsEmpty, 899).
+-define(wxControlWithItems_Select, 900).
+-define(wxControlWithItems_SetSelection, 901).
+-define(wxControlWithItems_SetString, 902).
+-define(wxControlWithItems_SetStringSelection, 903).
+-define(wxMenu_new_2, 906).
+-define(wxMenu_new_1, 907).
+-define(wxMenu_destruct, 909).
+-define(wxMenu_Append_3, 910).
+-define(wxMenu_Append_1, 911).
+-define(wxMenu_Append_4_0, 912).
+-define(wxMenu_Append_4_1, 913).
+-define(wxMenu_AppendCheckItem, 914).
+-define(wxMenu_AppendRadioItem, 915).
+-define(wxMenu_AppendSeparator, 916).
+-define(wxMenu_Break, 917).
+-define(wxMenu_Check, 918).
+-define(wxMenu_Delete_1_0, 919).
+-define(wxMenu_Delete_1_1, 920).
+-define(wxMenu_Destroy_1_0, 921).
+-define(wxMenu_Destroy_1_1, 922).
+-define(wxMenu_Enable, 923).
+-define(wxMenu_FindItem_1, 924).
+-define(wxMenu_FindItem_2, 925).
+-define(wxMenu_FindItemByPosition, 926).
+-define(wxMenu_GetHelpString, 927).
+-define(wxMenu_GetLabel, 928).
+-define(wxMenu_GetMenuItemCount, 929).
+-define(wxMenu_GetMenuItems, 930).
+-define(wxMenu_GetTitle, 932).
+-define(wxMenu_Insert_2, 933).
+-define(wxMenu_Insert_3, 934).
+-define(wxMenu_Insert_5_1, 935).
+-define(wxMenu_Insert_5_0, 936).
+-define(wxMenu_InsertCheckItem, 937).
+-define(wxMenu_InsertRadioItem, 938).
+-define(wxMenu_InsertSeparator, 939).
+-define(wxMenu_IsChecked, 940).
+-define(wxMenu_IsEnabled, 941).
+-define(wxMenu_Prepend_1, 942).
+-define(wxMenu_Prepend_2, 943).
+-define(wxMenu_Prepend_4_1, 944).
+-define(wxMenu_Prepend_4_0, 945).
+-define(wxMenu_PrependCheckItem, 946).
+-define(wxMenu_PrependRadioItem, 947).
+-define(wxMenu_PrependSeparator, 948).
+-define(wxMenu_Remove_1_0, 949).
+-define(wxMenu_Remove_1_1, 950).
+-define(wxMenu_SetHelpString, 951).
+-define(wxMenu_SetLabel, 952).
+-define(wxMenu_SetTitle, 953).
+-define(wxMenuItem_new, 954).
+-define(wxMenuItem_destruct, 956).
+-define(wxMenuItem_Check, 957).
+-define(wxMenuItem_Enable, 958).
+-define(wxMenuItem_GetBitmap, 959).
+-define(wxMenuItem_GetHelp, 960).
+-define(wxMenuItem_GetId, 961).
+-define(wxMenuItem_GetKind, 962).
+-define(wxMenuItem_GetLabel, 963).
+-define(wxMenuItem_GetLabelFromText, 964).
+-define(wxMenuItem_GetMenu, 965).
+-define(wxMenuItem_GetText, 966).
+-define(wxMenuItem_GetSubMenu, 967).
+-define(wxMenuItem_IsCheckable, 968).
+-define(wxMenuItem_IsChecked, 969).
+-define(wxMenuItem_IsEnabled, 970).
+-define(wxMenuItem_IsSeparator, 971).
+-define(wxMenuItem_IsSubMenu, 972).
+-define(wxMenuItem_SetBitmap, 973).
+-define(wxMenuItem_SetHelp, 974).
+-define(wxMenuItem_SetMenu, 975).
+-define(wxMenuItem_SetSubMenu, 976).
+-define(wxMenuItem_SetText, 977).
+-define(wxToolBar_AddControl, 978).
+-define(wxToolBar_AddSeparator, 979).
+-define(wxToolBar_AddTool_5, 980).
+-define(wxToolBar_AddTool_4_0, 981).
+-define(wxToolBar_AddTool_1, 982).
+-define(wxToolBar_AddTool_4_1, 983).
+-define(wxToolBar_AddTool_3, 984).
+-define(wxToolBar_AddTool_6, 985).
+-define(wxToolBar_AddCheckTool, 986).
+-define(wxToolBar_AddRadioTool, 987).
+-define(wxToolBar_AddStretchableSpace, 988).
+-define(wxToolBar_InsertStretchableSpace, 989).
+-define(wxToolBar_DeleteTool, 990).
+-define(wxToolBar_DeleteToolByPos, 991).
+-define(wxToolBar_EnableTool, 992).
+-define(wxToolBar_FindById, 993).
+-define(wxToolBar_FindControl, 994).
+-define(wxToolBar_FindToolForPosition, 995).
+-define(wxToolBar_GetToolSize, 996).
+-define(wxToolBar_GetToolBitmapSize, 997).
+-define(wxToolBar_GetMargins, 998).
+-define(wxToolBar_GetToolEnabled, 999).
+-define(wxToolBar_GetToolLongHelp, 1000).
+-define(wxToolBar_GetToolPacking, 1001).
+-define(wxToolBar_GetToolPos, 1002).
+-define(wxToolBar_GetToolSeparation, 1003).
+-define(wxToolBar_GetToolShortHelp, 1004).
+-define(wxToolBar_GetToolState, 1005).
+-define(wxToolBar_InsertControl, 1006).
+-define(wxToolBar_InsertSeparator, 1007).
+-define(wxToolBar_InsertTool_5, 1008).
+-define(wxToolBar_InsertTool_2, 1009).
+-define(wxToolBar_InsertTool_4, 1010).
+-define(wxToolBar_Realize, 1011).
+-define(wxToolBar_RemoveTool, 1012).
+-define(wxToolBar_SetMargins, 1013).
+-define(wxToolBar_SetToolBitmapSize, 1014).
+-define(wxToolBar_SetToolLongHelp, 1015).
+-define(wxToolBar_SetToolPacking, 1016).
+-define(wxToolBar_SetToolShortHelp, 1017).
+-define(wxToolBar_SetToolSeparation, 1018).
+-define(wxToolBar_ToggleTool, 1019).
+-define(wxStatusBar_new_0, 1021).
+-define(wxStatusBar_new_2, 1022).
+-define(wxStatusBar_destruct, 1024).
+-define(wxStatusBar_Create, 1025).
+-define(wxStatusBar_GetFieldRect, 1026).
+-define(wxStatusBar_GetFieldsCount, 1027).
+-define(wxStatusBar_GetStatusText, 1028).
+-define(wxStatusBar_PopStatusText, 1029).
+-define(wxStatusBar_PushStatusText, 1030).
+-define(wxStatusBar_SetFieldsCount, 1031).
+-define(wxStatusBar_SetMinHeight, 1032).
+-define(wxStatusBar_SetStatusText, 1033).
+-define(wxStatusBar_SetStatusWidths, 1034).
+-define(wxStatusBar_SetStatusStyles, 1035).
+-define(wxBitmap_new_0, 1036).
+-define(wxBitmap_new_3, 1037).
+-define(wxBitmap_new_4, 1038).
+-define(wxBitmap_new_2_0, 1039).
+-define(wxBitmap_new_2_1, 1040).
+-define(wxBitmap_destruct, 1041).
+-define(wxBitmap_ConvertToImage, 1042).
+-define(wxBitmap_CopyFromIcon, 1043).
+-define(wxBitmap_Create, 1044).
+-define(wxBitmap_GetDepth, 1045).
+-define(wxBitmap_GetHeight, 1046).
+-define(wxBitmap_GetPalette, 1047).
+-define(wxBitmap_GetMask, 1048).
+-define(wxBitmap_GetWidth, 1049).
+-define(wxBitmap_GetSubBitmap, 1050).
+-define(wxBitmap_LoadFile, 1051).
+-define(wxBitmap_Ok, 1052).
+-define(wxBitmap_SaveFile, 1053).
+-define(wxBitmap_SetDepth, 1054).
+-define(wxBitmap_SetHeight, 1055).
+-define(wxBitmap_SetMask, 1056).
+-define(wxBitmap_SetPalette, 1057).
+-define(wxBitmap_SetWidth, 1058).
+-define(wxIcon_new_0, 1059).
+-define(wxIcon_new_2, 1060).
+-define(wxIcon_new_1, 1061).
+-define(wxIcon_CopyFromBitmap, 1062).
+-define(wxIcon_destroy, 1063).
+-define(wxIconBundle_new_0, 1064).
+-define(wxIconBundle_new_2, 1065).
+-define(wxIconBundle_new_1_0, 1066).
+-define(wxIconBundle_new_1_1, 1067).
+-define(wxIconBundle_destruct, 1068).
+-define(wxIconBundle_AddIcon_2, 1069).
+-define(wxIconBundle_AddIcon_1, 1070).
+-define(wxIconBundle_GetIcon_1_1, 1071).
+-define(wxIconBundle_GetIcon_1_0, 1072).
+-define(wxCursor_new_0, 1073).
+-define(wxCursor_new_1_0, 1074).
+-define(wxCursor_new_1_1, 1075).
+-define(wxCursor_new_4, 1076).
+-define(wxCursor_destruct, 1077).
+-define(wxCursor_Ok, 1078).
+-define(wxMask_new_0, 1079).
+-define(wxMask_new_2_1, 1080).
+-define(wxMask_new_2_0, 1081).
+-define(wxMask_new_1, 1082).
+-define(wxMask_destruct, 1083).
+-define(wxMask_Create_2_1, 1084).
+-define(wxMask_Create_2_0, 1085).
+-define(wxMask_Create_1, 1086).
+-define(wxImage_new_0, 1087).
+-define(wxImage_new_3_0, 1088).
+-define(wxImage_new_4, 1089).
+-define(wxImage_new_5, 1090).
+-define(wxImage_new_2, 1091).
+-define(wxImage_new_3_1, 1092).
+-define(wxImage_Blur, 1093).
+-define(wxImage_BlurHorizontal, 1094).
+-define(wxImage_BlurVertical, 1095).
+-define(wxImage_ConvertAlphaToMask, 1096).
+-define(wxImage_ConvertToGreyscale, 1097).
+-define(wxImage_ConvertToMono, 1098).
+-define(wxImage_Copy, 1099).
+-define(wxImage_Create_3, 1100).
+-define(wxImage_Create_4, 1101).
+-define(wxImage_Create_5, 1102).
+-define(wxImage_Destroy, 1103).
+-define(wxImage_FindFirstUnusedColour, 1104).
+-define(wxImage_GetImageExtWildcard, 1105).
+-define(wxImage_GetAlpha_2, 1106).
+-define(wxImage_GetAlpha_0, 1107).
+-define(wxImage_GetBlue, 1108).
+-define(wxImage_GetData, 1109).
+-define(wxImage_GetGreen, 1110).
+-define(wxImage_GetImageCount, 1111).
+-define(wxImage_GetHeight, 1112).
+-define(wxImage_GetMaskBlue, 1113).
+-define(wxImage_GetMaskGreen, 1114).
+-define(wxImage_GetMaskRed, 1115).
+-define(wxImage_GetOrFindMaskColour, 1116).
+-define(wxImage_GetPalette, 1117).
+-define(wxImage_GetRed, 1118).
+-define(wxImage_GetSubImage, 1119).
+-define(wxImage_GetWidth, 1120).
+-define(wxImage_HasAlpha, 1121).
+-define(wxImage_HasMask, 1122).
+-define(wxImage_GetOption, 1123).
+-define(wxImage_GetOptionInt, 1124).
+-define(wxImage_HasOption, 1125).
+-define(wxImage_InitAlpha, 1126).
+-define(wxImage_InitStandardHandlers, 1127).
+-define(wxImage_IsTransparent, 1128).
+-define(wxImage_LoadFile_2, 1129).
+-define(wxImage_LoadFile_3, 1130).
+-define(wxImage_Ok, 1131).
+-define(wxImage_RemoveHandler, 1132).
+-define(wxImage_Mirror, 1133).
+-define(wxImage_Replace, 1134).
+-define(wxImage_Rescale, 1135).
+-define(wxImage_Resize, 1136).
+-define(wxImage_Rotate, 1137).
+-define(wxImage_RotateHue, 1138).
+-define(wxImage_Rotate90, 1139).
+-define(wxImage_SaveFile_1, 1140).
+-define(wxImage_SaveFile_2_0, 1141).
+-define(wxImage_SaveFile_2_1, 1142).
+-define(wxImage_Scale, 1143).
+-define(wxImage_Size, 1144).
+-define(wxImage_SetAlpha_3, 1145).
+-define(wxImage_SetAlpha_2, 1146).
+-define(wxImage_SetData_2, 1147).
+-define(wxImage_SetData_4, 1148).
+-define(wxImage_SetMask, 1149).
+-define(wxImage_SetMaskColour, 1150).
+-define(wxImage_SetMaskFromImage, 1151).
+-define(wxImage_SetOption_2_1, 1152).
+-define(wxImage_SetOption_2_0, 1153).
+-define(wxImage_SetPalette, 1154).
+-define(wxImage_SetRGB_5, 1155).
+-define(wxImage_SetRGB_4, 1156).
+-define(wxImage_destroy, 1157).
+-define(wxBrush_new_0, 1158).
+-define(wxBrush_new_2, 1159).
+-define(wxBrush_new_1, 1160).
+-define(wxBrush_destruct, 1162).
+-define(wxBrush_GetColour, 1163).
+-define(wxBrush_GetStipple, 1164).
+-define(wxBrush_GetStyle, 1165).
+-define(wxBrush_IsHatch, 1166).
+-define(wxBrush_IsOk, 1167).
+-define(wxBrush_SetColour_1, 1168).
+-define(wxBrush_SetColour_3, 1169).
+-define(wxBrush_SetStipple, 1170).
+-define(wxBrush_SetStyle, 1171).
+-define(wxPen_new_0, 1172).
+-define(wxPen_new_2, 1173).
+-define(wxPen_destruct, 1174).
+-define(wxPen_GetCap, 1175).
+-define(wxPen_GetColour, 1176).
+-define(wxPen_GetJoin, 1177).
+-define(wxPen_GetStyle, 1178).
+-define(wxPen_GetWidth, 1179).
+-define(wxPen_IsOk, 1180).
+-define(wxPen_SetCap, 1181).
+-define(wxPen_SetColour_1, 1182).
+-define(wxPen_SetColour_3, 1183).
+-define(wxPen_SetJoin, 1184).
+-define(wxPen_SetStyle, 1185).
+-define(wxPen_SetWidth, 1186).
+-define(wxRegion_new_0, 1187).
+-define(wxRegion_new_4, 1188).
+-define(wxRegion_new_2, 1189).
+-define(wxRegion_new_1_1, 1190).
+-define(wxRegion_new_1_0, 1192).
+-define(wxRegion_destruct, 1194).
+-define(wxRegion_Clear, 1195).
+-define(wxRegion_Contains_2, 1196).
+-define(wxRegion_Contains_1_0, 1197).
+-define(wxRegion_Contains_4, 1198).
+-define(wxRegion_Contains_1_1, 1199).
+-define(wxRegion_ConvertToBitmap, 1200).
+-define(wxRegion_GetBox, 1201).
+-define(wxRegion_Intersect_4, 1202).
+-define(wxRegion_Intersect_1_1, 1203).
+-define(wxRegion_Intersect_1_0, 1204).
+-define(wxRegion_IsEmpty, 1205).
+-define(wxRegion_Subtract_4, 1206).
+-define(wxRegion_Subtract_1_1, 1207).
+-define(wxRegion_Subtract_1_0, 1208).
+-define(wxRegion_Offset_2, 1209).
+-define(wxRegion_Offset_1, 1210).
+-define(wxRegion_Union_4, 1211).
+-define(wxRegion_Union_1_2, 1212).
+-define(wxRegion_Union_1_1, 1213).
+-define(wxRegion_Union_1_0, 1214).
+-define(wxRegion_Union_3, 1215).
+-define(wxRegion_Xor_4, 1216).
+-define(wxRegion_Xor_1_1, 1217).
+-define(wxRegion_Xor_1_0, 1218).
+-define(wxAcceleratorTable_new_0, 1219).
+-define(wxAcceleratorTable_new_2, 1220).
+-define(wxAcceleratorTable_destruct, 1221).
+-define(wxAcceleratorTable_Ok, 1222).
+-define(wxAcceleratorEntry_new_1_0, 1223).
+-define(wxAcceleratorEntry_new_1_1, 1224).
+-define(wxAcceleratorEntry_GetCommand, 1225).
+-define(wxAcceleratorEntry_GetFlags, 1226).
+-define(wxAcceleratorEntry_GetKeyCode, 1227).
+-define(wxAcceleratorEntry_Set, 1228).
+-define(wxAcceleratorEntry_destroy, 1229).
+-define(wxCaret_new_3, 1234).
+-define(wxCaret_new_2, 1235).
+-define(wxCaret_destruct, 1237).
+-define(wxCaret_Create_3, 1238).
+-define(wxCaret_Create_2, 1239).
+-define(wxCaret_GetBlinkTime, 1240).
+-define(wxCaret_GetPosition, 1242).
+-define(wxCaret_GetSize, 1244).
+-define(wxCaret_GetWindow, 1245).
+-define(wxCaret_Hide, 1246).
+-define(wxCaret_IsOk, 1247).
+-define(wxCaret_IsVisible, 1248).
+-define(wxCaret_Move_2, 1249).
+-define(wxCaret_Move_1, 1250).
+-define(wxCaret_SetBlinkTime, 1251).
+-define(wxCaret_SetSize_2, 1252).
+-define(wxCaret_SetSize_1, 1253).
+-define(wxCaret_Show, 1254).
+-define(wxSizer_Add_2_1, 1255).
+-define(wxSizer_Add_2_0, 1256).
+-define(wxSizer_Add_3, 1257).
+-define(wxSizer_Add_2_3, 1258).
+-define(wxSizer_Add_2_2, 1259).
+-define(wxSizer_AddSpacer, 1260).
+-define(wxSizer_AddStretchSpacer, 1261).
+-define(wxSizer_CalcMin, 1262).
+-define(wxSizer_Clear, 1263).
+-define(wxSizer_Detach_1_2, 1264).
+-define(wxSizer_Detach_1_1, 1265).
+-define(wxSizer_Detach_1_0, 1266).
+-define(wxSizer_Fit, 1267).
+-define(wxSizer_FitInside, 1268).
+-define(wxSizer_GetChildren, 1269).
+-define(wxSizer_GetItem_2_1, 1270).
+-define(wxSizer_GetItem_2_0, 1271).
+-define(wxSizer_GetItem_1, 1272).
+-define(wxSizer_GetSize, 1273).
+-define(wxSizer_GetPosition, 1274).
+-define(wxSizer_GetMinSize, 1275).
+-define(wxSizer_Hide_2_0, 1276).
+-define(wxSizer_Hide_2_1, 1277).
+-define(wxSizer_Hide_1, 1278).
+-define(wxSizer_Insert_3_1, 1279).
+-define(wxSizer_Insert_3_0, 1280).
+-define(wxSizer_Insert_4, 1281).
+-define(wxSizer_Insert_3_3, 1282).
+-define(wxSizer_Insert_3_2, 1283).
+-define(wxSizer_Insert_2, 1284).
+-define(wxSizer_InsertSpacer, 1285).
+-define(wxSizer_InsertStretchSpacer, 1286).
+-define(wxSizer_IsShown_1_2, 1287).
+-define(wxSizer_IsShown_1_1, 1288).
+-define(wxSizer_IsShown_1_0, 1289).
+-define(wxSizer_Layout, 1290).
+-define(wxSizer_Prepend_2_1, 1291).
+-define(wxSizer_Prepend_2_0, 1292).
+-define(wxSizer_Prepend_3, 1293).
+-define(wxSizer_Prepend_2_3, 1294).
+-define(wxSizer_Prepend_2_2, 1295).
+-define(wxSizer_Prepend_1, 1296).
+-define(wxSizer_PrependSpacer, 1297).
+-define(wxSizer_PrependStretchSpacer, 1298).
+-define(wxSizer_RecalcSizes, 1299).
+-define(wxSizer_Remove_1_1, 1300).
+-define(wxSizer_Remove_1_0, 1301).
+-define(wxSizer_Replace_3_1, 1302).
+-define(wxSizer_Replace_3_0, 1303).
+-define(wxSizer_Replace_2, 1304).
+-define(wxSizer_SetDimension, 1305).
+-define(wxSizer_SetMinSize_2, 1306).
+-define(wxSizer_SetMinSize_1, 1307).
+-define(wxSizer_SetItemMinSize_3_2, 1308).
+-define(wxSizer_SetItemMinSize_2_2, 1309).
+-define(wxSizer_SetItemMinSize_3_1, 1310).
+-define(wxSizer_SetItemMinSize_2_1, 1311).
+-define(wxSizer_SetItemMinSize_3_0, 1312).
+-define(wxSizer_SetItemMinSize_2_0, 1313).
+-define(wxSizer_SetSizeHints, 1314).
+-define(wxSizer_SetVirtualSizeHints, 1315).
+-define(wxSizer_Show_2_2, 1316).
+-define(wxSizer_Show_2_1, 1317).
+-define(wxSizer_Show_2_0, 1318).
+-define(wxSizer_Show_1, 1319).
+-define(wxSizerFlags_new, 1320).
+-define(wxSizerFlags_Align, 1321).
+-define(wxSizerFlags_Border_2, 1322).
+-define(wxSizerFlags_Border_1, 1323).
+-define(wxSizerFlags_Center, 1324).
+-define(wxSizerFlags_Centre, 1325).
+-define(wxSizerFlags_Expand, 1326).
+-define(wxSizerFlags_Left, 1327).
+-define(wxSizerFlags_Proportion, 1328).
+-define(wxSizerFlags_Right, 1329).
+-define(wxSizerFlags_destroy, 1330).
+-define(wxSizerItem_new_5_1, 1331).
+-define(wxSizerItem_new_2_1, 1332).
+-define(wxSizerItem_new_5_0, 1333).
+-define(wxSizerItem_new_2_0, 1334).
+-define(wxSizerItem_new_6, 1335).
+-define(wxSizerItem_new_3, 1336).
+-define(wxSizerItem_new_0, 1337).
+-define(wxSizerItem_destruct, 1338).
+-define(wxSizerItem_CalcMin, 1339).
+-define(wxSizerItem_DeleteWindows, 1340).
+-define(wxSizerItem_DetachSizer, 1341).
+-define(wxSizerItem_GetBorder, 1342).
+-define(wxSizerItem_GetFlag, 1343).
+-define(wxSizerItem_GetMinSize, 1344).
+-define(wxSizerItem_GetPosition, 1345).
+-define(wxSizerItem_GetProportion, 1346).
+-define(wxSizerItem_GetRatio, 1347).
+-define(wxSizerItem_GetRect, 1348).
+-define(wxSizerItem_GetSize, 1349).
+-define(wxSizerItem_GetSizer, 1350).
+-define(wxSizerItem_GetSpacer, 1351).
+-define(wxSizerItem_GetUserData, 1352).
+-define(wxSizerItem_GetWindow, 1353).
+-define(wxSizerItem_IsSizer, 1354).
+-define(wxSizerItem_IsShown, 1355).
+-define(wxSizerItem_IsSpacer, 1356).
+-define(wxSizerItem_IsWindow, 1357).
+-define(wxSizerItem_SetBorder, 1358).
+-define(wxSizerItem_SetDimension, 1359).
+-define(wxSizerItem_SetFlag, 1360).
+-define(wxSizerItem_SetInitSize, 1361).
+-define(wxSizerItem_SetMinSize_1, 1362).
+-define(wxSizerItem_SetMinSize_2, 1363).
+-define(wxSizerItem_SetProportion, 1364).
+-define(wxSizerItem_SetRatio_2, 1365).
+-define(wxSizerItem_SetRatio_1_1, 1366).
+-define(wxSizerItem_SetRatio_1_0, 1367).
+-define(wxSizerItem_SetSizer, 1368).
+-define(wxSizerItem_SetSpacer_1, 1369).
+-define(wxSizerItem_SetSpacer_2, 1370).
+-define(wxSizerItem_SetWindow, 1371).
+-define(wxSizerItem_Show, 1372).
+-define(wxBoxSizer_new, 1373).
+-define(wxBoxSizer_GetOrientation, 1374).
+-define(wxBoxSizer_destroy, 1375).
+-define(wxStaticBoxSizer_new_2, 1376).
+-define(wxStaticBoxSizer_new_3, 1377).
+-define(wxStaticBoxSizer_GetStaticBox, 1378).
+-define(wxStaticBoxSizer_destroy, 1379).
+-define(wxGridSizer_new_4, 1380).
+-define(wxGridSizer_new_2, 1381).
+-define(wxGridSizer_GetCols, 1382).
+-define(wxGridSizer_GetHGap, 1383).
+-define(wxGridSizer_GetRows, 1384).
+-define(wxGridSizer_GetVGap, 1385).
+-define(wxGridSizer_SetCols, 1386).
+-define(wxGridSizer_SetHGap, 1387).
+-define(wxGridSizer_SetRows, 1388).
+-define(wxGridSizer_SetVGap, 1389).
+-define(wxGridSizer_destroy, 1390).
+-define(wxFlexGridSizer_new_4, 1391).
+-define(wxFlexGridSizer_new_2, 1392).
+-define(wxFlexGridSizer_AddGrowableCol, 1393).
+-define(wxFlexGridSizer_AddGrowableRow, 1394).
+-define(wxFlexGridSizer_GetFlexibleDirection, 1395).
+-define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1396).
+-define(wxFlexGridSizer_RemoveGrowableCol, 1397).
+-define(wxFlexGridSizer_RemoveGrowableRow, 1398).
+-define(wxFlexGridSizer_SetFlexibleDirection, 1399).
+-define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1400).
+-define(wxFlexGridSizer_destroy, 1401).
+-define(wxGridBagSizer_new, 1402).
+-define(wxGridBagSizer_Add_3_2, 1403).
+-define(wxGridBagSizer_Add_3_1, 1404).
+-define(wxGridBagSizer_Add_4, 1405).
+-define(wxGridBagSizer_Add_1_0, 1406).
+-define(wxGridBagSizer_Add_2_1, 1407).
+-define(wxGridBagSizer_Add_2_0, 1408).
+-define(wxGridBagSizer_Add_3_0, 1409).
+-define(wxGridBagSizer_Add_1_1, 1410).
+-define(wxGridBagSizer_CalcMin, 1411).
+-define(wxGridBagSizer_CheckForIntersection_2, 1412).
+-define(wxGridBagSizer_CheckForIntersection_3, 1413).
+-define(wxGridBagSizer_FindItem_1_1, 1414).
+-define(wxGridBagSizer_FindItem_1_0, 1415).
+-define(wxGridBagSizer_FindItemAtPoint, 1416).
+-define(wxGridBagSizer_FindItemAtPosition, 1417).
+-define(wxGridBagSizer_FindItemWithData, 1418).
+-define(wxGridBagSizer_GetCellSize, 1419).
+-define(wxGridBagSizer_GetEmptyCellSize, 1420).
+-define(wxGridBagSizer_GetItemPosition_1_2, 1421).
+-define(wxGridBagSizer_GetItemPosition_1_1, 1422).
+-define(wxGridBagSizer_GetItemPosition_1_0, 1423).
+-define(wxGridBagSizer_GetItemSpan_1_2, 1424).
+-define(wxGridBagSizer_GetItemSpan_1_1, 1425).
+-define(wxGridBagSizer_GetItemSpan_1_0, 1426).
+-define(wxGridBagSizer_SetEmptyCellSize, 1427).
+-define(wxGridBagSizer_SetItemPosition_2_2, 1428).
+-define(wxGridBagSizer_SetItemPosition_2_1, 1429).
+-define(wxGridBagSizer_SetItemPosition_2_0, 1430).
+-define(wxGridBagSizer_SetItemSpan_2_2, 1431).
+-define(wxGridBagSizer_SetItemSpan_2_1, 1432).
+-define(wxGridBagSizer_SetItemSpan_2_0, 1433).
+-define(wxGridBagSizer_destroy, 1434).
+-define(wxStdDialogButtonSizer_new, 1435).
+-define(wxStdDialogButtonSizer_AddButton, 1436).
+-define(wxStdDialogButtonSizer_Realize, 1437).
+-define(wxStdDialogButtonSizer_SetAffirmativeButton, 1438).
+-define(wxStdDialogButtonSizer_SetCancelButton, 1439).
+-define(wxStdDialogButtonSizer_SetNegativeButton, 1440).
+-define(wxStdDialogButtonSizer_destroy, 1441).
+-define(wxFont_new_0, 1442).
+-define(wxFont_new_1, 1443).
+-define(wxFont_new_5, 1444).
+-define(wxFont_destruct, 1446).
+-define(wxFont_IsFixedWidth, 1447).
+-define(wxFont_GetDefaultEncoding, 1448).
+-define(wxFont_GetFaceName, 1449).
+-define(wxFont_GetFamily, 1450).
+-define(wxFont_GetNativeFontInfoDesc, 1451).
+-define(wxFont_GetNativeFontInfoUserDesc, 1452).
+-define(wxFont_GetPointSize, 1453).
+-define(wxFont_GetStyle, 1454).
+-define(wxFont_GetUnderlined, 1455).
+-define(wxFont_GetWeight, 1456).
+-define(wxFont_Ok, 1457).
+-define(wxFont_SetDefaultEncoding, 1458).
+-define(wxFont_SetFaceName, 1459).
+-define(wxFont_SetFamily, 1460).
+-define(wxFont_SetPointSize, 1461).
+-define(wxFont_SetStyle, 1462).
+-define(wxFont_SetUnderlined, 1463).
+-define(wxFont_SetWeight, 1464).
+-define(wxToolTip_Enable, 1465).
+-define(wxToolTip_SetDelay, 1466).
+-define(wxToolTip_new, 1467).
+-define(wxToolTip_SetTip, 1468).
+-define(wxToolTip_GetTip, 1469).
+-define(wxToolTip_GetWindow, 1470).
+-define(wxToolTip_destroy, 1471).
+-define(wxButton_new_3, 1473).
+-define(wxButton_new_0, 1474).
+-define(wxButton_destruct, 1475).
+-define(wxButton_Create, 1476).
+-define(wxButton_GetDefaultSize, 1477).
+-define(wxButton_SetDefault, 1478).
+-define(wxButton_SetLabel, 1479).
+-define(wxBitmapButton_new_4, 1481).
+-define(wxBitmapButton_new_0, 1482).
+-define(wxBitmapButton_Create, 1483).
+-define(wxBitmapButton_GetBitmapDisabled, 1484).
+-define(wxBitmapButton_GetBitmapFocus, 1486).
+-define(wxBitmapButton_GetBitmapLabel, 1488).
+-define(wxBitmapButton_GetBitmapSelected, 1490).
+-define(wxBitmapButton_SetBitmapDisabled, 1492).
+-define(wxBitmapButton_SetBitmapFocus, 1493).
+-define(wxBitmapButton_SetBitmapLabel, 1494).
+-define(wxBitmapButton_SetBitmapSelected, 1495).
+-define(wxBitmapButton_destroy, 1496).
+-define(wxToggleButton_new_0, 1497).
+-define(wxToggleButton_new_4, 1498).
+-define(wxToggleButton_Create, 1499).
+-define(wxToggleButton_GetValue, 1500).
+-define(wxToggleButton_SetValue, 1501).
+-define(wxToggleButton_destroy, 1502).
+-define(wxCalendarCtrl_new_0, 1503).
+-define(wxCalendarCtrl_new_3, 1504).
+-define(wxCalendarCtrl_Create, 1505).
+-define(wxCalendarCtrl_destruct, 1506).
+-define(wxCalendarCtrl_SetDate, 1507).
+-define(wxCalendarCtrl_GetDate, 1508).
+-define(wxCalendarCtrl_EnableYearChange, 1509).
+-define(wxCalendarCtrl_EnableMonthChange, 1510).
+-define(wxCalendarCtrl_EnableHolidayDisplay, 1511).
+-define(wxCalendarCtrl_SetHeaderColours, 1512).
+-define(wxCalendarCtrl_GetHeaderColourFg, 1513).
+-define(wxCalendarCtrl_GetHeaderColourBg, 1514).
+-define(wxCalendarCtrl_SetHighlightColours, 1515).
+-define(wxCalendarCtrl_GetHighlightColourFg, 1516).
+-define(wxCalendarCtrl_GetHighlightColourBg, 1517).
+-define(wxCalendarCtrl_SetHolidayColours, 1518).
+-define(wxCalendarCtrl_GetHolidayColourFg, 1519).
+-define(wxCalendarCtrl_GetHolidayColourBg, 1520).
+-define(wxCalendarCtrl_GetAttr, 1521).
+-define(wxCalendarCtrl_SetAttr, 1522).
+-define(wxCalendarCtrl_SetHoliday, 1523).
+-define(wxCalendarCtrl_ResetAttr, 1524).
+-define(wxCalendarCtrl_HitTest, 1525).
+-define(wxCalendarDateAttr_new_0, 1526).
+-define(wxCalendarDateAttr_new_2_1, 1527).
+-define(wxCalendarDateAttr_new_2_0, 1528).
+-define(wxCalendarDateAttr_SetTextColour, 1529).
+-define(wxCalendarDateAttr_SetBackgroundColour, 1530).
+-define(wxCalendarDateAttr_SetBorderColour, 1531).
+-define(wxCalendarDateAttr_SetFont, 1532).
+-define(wxCalendarDateAttr_SetBorder, 1533).
+-define(wxCalendarDateAttr_SetHoliday, 1534).
+-define(wxCalendarDateAttr_HasTextColour, 1535).
+-define(wxCalendarDateAttr_HasBackgroundColour, 1536).
+-define(wxCalendarDateAttr_HasBorderColour, 1537).
+-define(wxCalendarDateAttr_HasFont, 1538).
+-define(wxCalendarDateAttr_HasBorder, 1539).
+-define(wxCalendarDateAttr_IsHoliday, 1540).
+-define(wxCalendarDateAttr_GetTextColour, 1541).
+-define(wxCalendarDateAttr_GetBackgroundColour, 1542).
+-define(wxCalendarDateAttr_GetBorderColour, 1543).
+-define(wxCalendarDateAttr_GetFont, 1544).
+-define(wxCalendarDateAttr_GetBorder, 1545).
+-define(wxCalendarDateAttr_destroy, 1546).
+-define(wxCheckBox_new_4, 1548).
+-define(wxCheckBox_new_0, 1549).
+-define(wxCheckBox_Create, 1550).
+-define(wxCheckBox_GetValue, 1551).
+-define(wxCheckBox_Get3StateValue, 1552).
+-define(wxCheckBox_Is3rdStateAllowedForUser, 1553).
+-define(wxCheckBox_Is3State, 1554).
+-define(wxCheckBox_IsChecked, 1555).
+-define(wxCheckBox_SetValue, 1556).
+-define(wxCheckBox_Set3StateValue, 1557).
+-define(wxCheckBox_destroy, 1558).
+-define(wxCheckListBox_new_0, 1559).
+-define(wxCheckListBox_new_3, 1561).
+-define(wxCheckListBox_Check, 1562).
+-define(wxCheckListBox_IsChecked, 1563).
+-define(wxCheckListBox_destroy, 1564).
+-define(wxChoice_new_3, 1567).
+-define(wxChoice_new_0, 1568).
+-define(wxChoice_destruct, 1570).
+-define(wxChoice_Create, 1572).
+-define(wxChoice_Delete, 1573).
+-define(wxChoice_GetColumns, 1574).
+-define(wxChoice_SetColumns, 1575).
+-define(wxComboBox_new_0, 1576).
+-define(wxComboBox_new_3, 1578).
+-define(wxComboBox_destruct, 1579).
+-define(wxComboBox_Create, 1581).
+-define(wxComboBox_CanCopy, 1582).
+-define(wxComboBox_CanCut, 1583).
+-define(wxComboBox_CanPaste, 1584).
+-define(wxComboBox_CanRedo, 1585).
+-define(wxComboBox_CanUndo, 1586).
+-define(wxComboBox_Copy, 1587).
+-define(wxComboBox_Cut, 1588).
+-define(wxComboBox_GetInsertionPoint, 1589).
+-define(wxComboBox_GetLastPosition, 1590).
+-define(wxComboBox_GetValue, 1591).
+-define(wxComboBox_Paste, 1592).
+-define(wxComboBox_Redo, 1593).
+-define(wxComboBox_Replace, 1594).
+-define(wxComboBox_Remove, 1595).
+-define(wxComboBox_SetInsertionPoint, 1596).
+-define(wxComboBox_SetInsertionPointEnd, 1597).
+-define(wxComboBox_SetSelection_1, 1598).
+-define(wxComboBox_SetSelection_2, 1599).
+-define(wxComboBox_SetValue, 1600).
+-define(wxComboBox_Undo, 1601).
+-define(wxGauge_new_0, 1602).
+-define(wxGauge_new_4, 1603).
+-define(wxGauge_Create, 1604).
+-define(wxGauge_GetBezelFace, 1605).
+-define(wxGauge_GetRange, 1606).
+-define(wxGauge_GetShadowWidth, 1607).
+-define(wxGauge_GetValue, 1608).
+-define(wxGauge_IsVertical, 1609).
+-define(wxGauge_SetBezelFace, 1610).
+-define(wxGauge_SetRange, 1611).
+-define(wxGauge_SetShadowWidth, 1612).
+-define(wxGauge_SetValue, 1613).
+-define(wxGauge_Pulse, 1614).
+-define(wxGauge_destroy, 1615).
+-define(wxGenericDirCtrl_new_0, 1616).
+-define(wxGenericDirCtrl_new_2, 1617).
+-define(wxGenericDirCtrl_destruct, 1618).
+-define(wxGenericDirCtrl_Create, 1619).
+-define(wxGenericDirCtrl_Init, 1620).
+-define(wxGenericDirCtrl_CollapseTree, 1621).
+-define(wxGenericDirCtrl_ExpandPath, 1622).
+-define(wxGenericDirCtrl_GetDefaultPath, 1623).
+-define(wxGenericDirCtrl_GetPath, 1624).
+-define(wxGenericDirCtrl_GetFilePath, 1625).
+-define(wxGenericDirCtrl_GetFilter, 1626).
+-define(wxGenericDirCtrl_GetFilterIndex, 1627).
+-define(wxGenericDirCtrl_GetRootId, 1628).
+-define(wxGenericDirCtrl_GetTreeCtrl, 1629).
+-define(wxGenericDirCtrl_ReCreateTree, 1630).
+-define(wxGenericDirCtrl_SetDefaultPath, 1631).
+-define(wxGenericDirCtrl_SetFilter, 1632).
+-define(wxGenericDirCtrl_SetFilterIndex, 1633).
+-define(wxGenericDirCtrl_SetPath, 1634).
+-define(wxStaticBox_new_4, 1636).
+-define(wxStaticBox_new_0, 1637).
+-define(wxStaticBox_Create, 1638).
+-define(wxStaticBox_destroy, 1639).
+-define(wxStaticLine_new_2, 1641).
+-define(wxStaticLine_new_0, 1642).
+-define(wxStaticLine_Create, 1643).
+-define(wxStaticLine_IsVertical, 1644).
+-define(wxStaticLine_GetDefaultSize, 1645).
+-define(wxStaticLine_destroy, 1646).
+-define(wxListBox_new_3, 1649).
+-define(wxListBox_new_0, 1650).
+-define(wxListBox_destruct, 1652).
+-define(wxListBox_Create, 1654).
+-define(wxListBox_Deselect, 1655).
+-define(wxListBox_GetSelections, 1656).
+-define(wxListBox_InsertItems, 1657).
+-define(wxListBox_IsSelected, 1658).
+-define(wxListBox_Set, 1659).
+-define(wxListBox_HitTest, 1660).
+-define(wxListBox_SetFirstItem_1_0, 1661).
+-define(wxListBox_SetFirstItem_1_1, 1662).
+-define(wxListCtrl_new_0, 1663).
+-define(wxListCtrl_new_2, 1664).
+-define(wxListCtrl_Arrange, 1665).
+-define(wxListCtrl_AssignImageList, 1666).
+-define(wxListCtrl_ClearAll, 1667).
+-define(wxListCtrl_Create, 1668).
+-define(wxListCtrl_DeleteAllItems, 1669).
+-define(wxListCtrl_DeleteColumn, 1670).
+-define(wxListCtrl_DeleteItem, 1671).
+-define(wxListCtrl_EditLabel, 1672).
+-define(wxListCtrl_EnsureVisible, 1673).
+-define(wxListCtrl_FindItem_3_0, 1674).
+-define(wxListCtrl_FindItem_3_1, 1675).
+-define(wxListCtrl_GetColumn, 1676).
+-define(wxListCtrl_GetColumnCount, 1677).
+-define(wxListCtrl_GetColumnWidth, 1678).
+-define(wxListCtrl_GetCountPerPage, 1679).
+-define(wxListCtrl_GetEditControl, 1680).
+-define(wxListCtrl_GetImageList, 1681).
+-define(wxListCtrl_GetItem, 1682).
+-define(wxListCtrl_GetItemBackgroundColour, 1683).
+-define(wxListCtrl_GetItemCount, 1684).
+-define(wxListCtrl_GetItemData, 1685).
+-define(wxListCtrl_GetItemFont, 1686).
+-define(wxListCtrl_GetItemPosition, 1687).
+-define(wxListCtrl_GetItemRect, 1688).
+-define(wxListCtrl_GetItemSpacing, 1689).
+-define(wxListCtrl_GetItemState, 1690).
+-define(wxListCtrl_GetItemText, 1691).
+-define(wxListCtrl_GetItemTextColour, 1692).
+-define(wxListCtrl_GetNextItem, 1693).
+-define(wxListCtrl_GetSelectedItemCount, 1694).
+-define(wxListCtrl_GetTextColour, 1695).
+-define(wxListCtrl_GetTopItem, 1696).
+-define(wxListCtrl_GetViewRect, 1697).
+-define(wxListCtrl_HitTest, 1698).
+-define(wxListCtrl_InsertColumn_2, 1699).
+-define(wxListCtrl_InsertColumn_3, 1700).
+-define(wxListCtrl_InsertItem_1, 1701).
+-define(wxListCtrl_InsertItem_2_1, 1702).
+-define(wxListCtrl_InsertItem_2_0, 1703).
+-define(wxListCtrl_InsertItem_3, 1704).
+-define(wxListCtrl_RefreshItem, 1705).
+-define(wxListCtrl_RefreshItems, 1706).
+-define(wxListCtrl_ScrollList, 1707).
+-define(wxListCtrl_SetBackgroundColour, 1708).
+-define(wxListCtrl_SetColumn, 1709).
+-define(wxListCtrl_SetColumnWidth, 1710).
+-define(wxListCtrl_SetImageList, 1711).
+-define(wxListCtrl_SetItem_1, 1712).
+-define(wxListCtrl_SetItem_4, 1713).
+-define(wxListCtrl_SetItemBackgroundColour, 1714).
+-define(wxListCtrl_SetItemCount, 1715).
+-define(wxListCtrl_SetItemData, 1716).
+-define(wxListCtrl_SetItemFont, 1717).
+-define(wxListCtrl_SetItemImage, 1718).
+-define(wxListCtrl_SetItemColumnImage, 1719).
+-define(wxListCtrl_SetItemPosition, 1720).
+-define(wxListCtrl_SetItemState, 1721).
+-define(wxListCtrl_SetItemText, 1722).
+-define(wxListCtrl_SetItemTextColour, 1723).
+-define(wxListCtrl_SetSingleStyle, 1724).
+-define(wxListCtrl_SetTextColour, 1725).
+-define(wxListCtrl_SetWindowStyleFlag, 1726).
+-define(wxListCtrl_SortItems, 1727).
+-define(wxListCtrl_destroy, 1728).
+-define(wxListView_ClearColumnImage, 1729).
+-define(wxListView_Focus, 1730).
+-define(wxListView_GetFirstSelected, 1731).
+-define(wxListView_GetFocusedItem, 1732).
+-define(wxListView_GetNextSelected, 1733).
+-define(wxListView_IsSelected, 1734).
+-define(wxListView_Select, 1735).
+-define(wxListView_SetColumnImage, 1736).
+-define(wxListItem_new_0, 1737).
+-define(wxListItem_new_1, 1738).
+-define(wxListItem_destruct, 1739).
+-define(wxListItem_Clear, 1740).
+-define(wxListItem_GetAlign, 1741).
+-define(wxListItem_GetBackgroundColour, 1742).
+-define(wxListItem_GetColumn, 1743).
+-define(wxListItem_GetFont, 1744).
+-define(wxListItem_GetId, 1745).
+-define(wxListItem_GetImage, 1746).
+-define(wxListItem_GetMask, 1747).
+-define(wxListItem_GetState, 1748).
+-define(wxListItem_GetText, 1749).
+-define(wxListItem_GetTextColour, 1750).
+-define(wxListItem_GetWidth, 1751).
+-define(wxListItem_SetAlign, 1752).
+-define(wxListItem_SetBackgroundColour, 1753).
+-define(wxListItem_SetColumn, 1754).
+-define(wxListItem_SetFont, 1755).
+-define(wxListItem_SetId, 1756).
+-define(wxListItem_SetImage, 1757).
+-define(wxListItem_SetMask, 1758).
+-define(wxListItem_SetState, 1759).
+-define(wxListItem_SetStateMask, 1760).
+-define(wxListItem_SetText, 1761).
+-define(wxListItem_SetTextColour, 1762).
+-define(wxListItem_SetWidth, 1763).
+-define(wxListItemAttr_new_0, 1764).
+-define(wxListItemAttr_new_3, 1765).
+-define(wxListItemAttr_GetBackgroundColour, 1766).
+-define(wxListItemAttr_GetFont, 1767).
+-define(wxListItemAttr_GetTextColour, 1768).
+-define(wxListItemAttr_HasBackgroundColour, 1769).
+-define(wxListItemAttr_HasFont, 1770).
+-define(wxListItemAttr_HasTextColour, 1771).
+-define(wxListItemAttr_SetBackgroundColour, 1772).
+-define(wxListItemAttr_SetFont, 1773).
+-define(wxListItemAttr_SetTextColour, 1774).
+-define(wxListItemAttr_destroy, 1775).
+-define(wxImageList_new_0, 1776).
+-define(wxImageList_new_3, 1777).
+-define(wxImageList_Add_1, 1778).
+-define(wxImageList_Add_2_0, 1779).
+-define(wxImageList_Add_2_1, 1780).
+-define(wxImageList_Create, 1781).
+-define(wxImageList_Draw, 1783).
+-define(wxImageList_GetBitmap, 1784).
+-define(wxImageList_GetIcon, 1785).
+-define(wxImageList_GetImageCount, 1786).
+-define(wxImageList_GetSize, 1787).
+-define(wxImageList_Remove, 1788).
+-define(wxImageList_RemoveAll, 1789).
+-define(wxImageList_Replace_2, 1790).
+-define(wxImageList_Replace_3, 1791).
+-define(wxImageList_destroy, 1792).
+-define(wxTextAttr_new_0, 1793).
+-define(wxTextAttr_new_2, 1794).
+-define(wxTextAttr_GetAlignment, 1795).
+-define(wxTextAttr_GetBackgroundColour, 1796).
+-define(wxTextAttr_GetFont, 1797).
+-define(wxTextAttr_GetLeftIndent, 1798).
+-define(wxTextAttr_GetLeftSubIndent, 1799).
+-define(wxTextAttr_GetRightIndent, 1800).
+-define(wxTextAttr_GetTabs, 1801).
+-define(wxTextAttr_GetTextColour, 1802).
+-define(wxTextAttr_HasBackgroundColour, 1803).
+-define(wxTextAttr_HasFont, 1804).
+-define(wxTextAttr_HasTextColour, 1805).
+-define(wxTextAttr_GetFlags, 1806).
+-define(wxTextAttr_IsDefault, 1807).
+-define(wxTextAttr_SetAlignment, 1808).
+-define(wxTextAttr_SetBackgroundColour, 1809).
+-define(wxTextAttr_SetFlags, 1810).
+-define(wxTextAttr_SetFont, 1811).
+-define(wxTextAttr_SetLeftIndent, 1812).
+-define(wxTextAttr_SetRightIndent, 1813).
+-define(wxTextAttr_SetTabs, 1814).
+-define(wxTextAttr_SetTextColour, 1815).
+-define(wxTextAttr_destroy, 1816).
+-define(wxTextCtrl_new_3, 1818).
+-define(wxTextCtrl_new_0, 1819).
+-define(wxTextCtrl_destruct, 1821).
+-define(wxTextCtrl_AppendText, 1822).
+-define(wxTextCtrl_CanCopy, 1823).
+-define(wxTextCtrl_CanCut, 1824).
+-define(wxTextCtrl_CanPaste, 1825).
+-define(wxTextCtrl_CanRedo, 1826).
+-define(wxTextCtrl_CanUndo, 1827).
+-define(wxTextCtrl_Clear, 1828).
+-define(wxTextCtrl_Copy, 1829).
+-define(wxTextCtrl_Create, 1830).
+-define(wxTextCtrl_Cut, 1831).
+-define(wxTextCtrl_DiscardEdits, 1832).
+-define(wxTextCtrl_ChangeValue, 1833).
+-define(wxTextCtrl_EmulateKeyPress, 1834).
+-define(wxTextCtrl_GetDefaultStyle, 1835).
+-define(wxTextCtrl_GetInsertionPoint, 1836).
+-define(wxTextCtrl_GetLastPosition, 1837).
+-define(wxTextCtrl_GetLineLength, 1838).
+-define(wxTextCtrl_GetLineText, 1839).
+-define(wxTextCtrl_GetNumberOfLines, 1840).
+-define(wxTextCtrl_GetRange, 1841).
+-define(wxTextCtrl_GetSelection, 1842).
+-define(wxTextCtrl_GetStringSelection, 1843).
+-define(wxTextCtrl_GetStyle, 1844).
+-define(wxTextCtrl_GetValue, 1845).
+-define(wxTextCtrl_IsEditable, 1846).
+-define(wxTextCtrl_IsModified, 1847).
+-define(wxTextCtrl_IsMultiLine, 1848).
+-define(wxTextCtrl_IsSingleLine, 1849).
+-define(wxTextCtrl_LoadFile, 1850).
+-define(wxTextCtrl_MarkDirty, 1851).
+-define(wxTextCtrl_Paste, 1852).
+-define(wxTextCtrl_PositionToXY, 1853).
+-define(wxTextCtrl_Redo, 1854).
+-define(wxTextCtrl_Remove, 1855).
+-define(wxTextCtrl_Replace, 1856).
+-define(wxTextCtrl_SaveFile, 1857).
+-define(wxTextCtrl_SetDefaultStyle, 1858).
+-define(wxTextCtrl_SetEditable, 1859).
+-define(wxTextCtrl_SetInsertionPoint, 1860).
+-define(wxTextCtrl_SetInsertionPointEnd, 1861).
+-define(wxTextCtrl_SetMaxLength, 1863).
+-define(wxTextCtrl_SetSelection, 1864).
+-define(wxTextCtrl_SetStyle, 1865).
+-define(wxTextCtrl_SetValue, 1866).
+-define(wxTextCtrl_ShowPosition, 1867).
+-define(wxTextCtrl_Undo, 1868).
+-define(wxTextCtrl_WriteText, 1869).
+-define(wxTextCtrl_XYToPosition, 1870).
+-define(wxNotebook_new_0, 1873).
+-define(wxNotebook_new_3, 1874).
+-define(wxNotebook_destruct, 1875).
+-define(wxNotebook_AddPage, 1876).
+-define(wxNotebook_AdvanceSelection, 1877).
+-define(wxNotebook_AssignImageList, 1878).
+-define(wxNotebook_Create, 1879).
+-define(wxNotebook_DeleteAllPages, 1880).
+-define(wxNotebook_DeletePage, 1881).
+-define(wxNotebook_RemovePage, 1882).
+-define(wxNotebook_GetCurrentPage, 1883).
+-define(wxNotebook_GetImageList, 1884).
+-define(wxNotebook_GetPage, 1886).
+-define(wxNotebook_GetPageCount, 1887).
+-define(wxNotebook_GetPageImage, 1888).
+-define(wxNotebook_GetPageText, 1889).
+-define(wxNotebook_GetRowCount, 1890).
+-define(wxNotebook_GetSelection, 1891).
+-define(wxNotebook_GetThemeBackgroundColour, 1892).
+-define(wxNotebook_HitTest, 1894).
+-define(wxNotebook_InsertPage, 1896).
+-define(wxNotebook_SetImageList, 1897).
+-define(wxNotebook_SetPadding, 1898).
+-define(wxNotebook_SetPageSize, 1899).
+-define(wxNotebook_SetPageImage, 1900).
+-define(wxNotebook_SetPageText, 1901).
+-define(wxNotebook_SetSelection, 1902).
+-define(wxNotebook_ChangeSelection, 1903).
+-define(wxChoicebook_new_0, 1904).
+-define(wxChoicebook_new_3, 1905).
+-define(wxChoicebook_AddPage, 1906).
+-define(wxChoicebook_AdvanceSelection, 1907).
+-define(wxChoicebook_AssignImageList, 1908).
+-define(wxChoicebook_Create, 1909).
+-define(wxChoicebook_DeleteAllPages, 1910).
+-define(wxChoicebook_DeletePage, 1911).
+-define(wxChoicebook_RemovePage, 1912).
+-define(wxChoicebook_GetCurrentPage, 1913).
+-define(wxChoicebook_GetImageList, 1914).
+-define(wxChoicebook_GetPage, 1916).
+-define(wxChoicebook_GetPageCount, 1917).
+-define(wxChoicebook_GetPageImage, 1918).
+-define(wxChoicebook_GetPageText, 1919).
+-define(wxChoicebook_GetSelection, 1920).
+-define(wxChoicebook_HitTest, 1921).
+-define(wxChoicebook_InsertPage, 1922).
+-define(wxChoicebook_SetImageList, 1923).
+-define(wxChoicebook_SetPageSize, 1924).
+-define(wxChoicebook_SetPageImage, 1925).
+-define(wxChoicebook_SetPageText, 1926).
+-define(wxChoicebook_SetSelection, 1927).
+-define(wxChoicebook_ChangeSelection, 1928).
+-define(wxChoicebook_destroy, 1929).
+-define(wxToolbook_new_0, 1930).
+-define(wxToolbook_new_3, 1931).
+-define(wxToolbook_AddPage, 1932).
+-define(wxToolbook_AdvanceSelection, 1933).
+-define(wxToolbook_AssignImageList, 1934).
+-define(wxToolbook_Create, 1935).
+-define(wxToolbook_DeleteAllPages, 1936).
+-define(wxToolbook_DeletePage, 1937).
+-define(wxToolbook_RemovePage, 1938).
+-define(wxToolbook_GetCurrentPage, 1939).
+-define(wxToolbook_GetImageList, 1940).
+-define(wxToolbook_GetPage, 1942).
+-define(wxToolbook_GetPageCount, 1943).
+-define(wxToolbook_GetPageImage, 1944).
+-define(wxToolbook_GetPageText, 1945).
+-define(wxToolbook_GetSelection, 1946).
+-define(wxToolbook_HitTest, 1948).
+-define(wxToolbook_InsertPage, 1949).
+-define(wxToolbook_SetImageList, 1950).
+-define(wxToolbook_SetPageSize, 1951).
+-define(wxToolbook_SetPageImage, 1952).
+-define(wxToolbook_SetPageText, 1953).
+-define(wxToolbook_SetSelection, 1954).
+-define(wxToolbook_ChangeSelection, 1955).
+-define(wxToolbook_destroy, 1956).
+-define(wxListbook_new_0, 1957).
+-define(wxListbook_new_3, 1958).
+-define(wxListbook_AddPage, 1959).
+-define(wxListbook_AdvanceSelection, 1960).
+-define(wxListbook_AssignImageList, 1961).
+-define(wxListbook_Create, 1962).
+-define(wxListbook_DeleteAllPages, 1963).
+-define(wxListbook_DeletePage, 1964).
+-define(wxListbook_RemovePage, 1965).
+-define(wxListbook_GetCurrentPage, 1966).
+-define(wxListbook_GetImageList, 1967).
+-define(wxListbook_GetPage, 1969).
+-define(wxListbook_GetPageCount, 1970).
+-define(wxListbook_GetPageImage, 1971).
+-define(wxListbook_GetPageText, 1972).
+-define(wxListbook_GetSelection, 1973).
+-define(wxListbook_HitTest, 1975).
+-define(wxListbook_InsertPage, 1976).
+-define(wxListbook_SetImageList, 1977).
+-define(wxListbook_SetPageSize, 1978).
+-define(wxListbook_SetPageImage, 1979).
+-define(wxListbook_SetPageText, 1980).
+-define(wxListbook_SetSelection, 1981).
+-define(wxListbook_ChangeSelection, 1982).
+-define(wxListbook_destroy, 1983).
+-define(wxTreebook_new_0, 1984).
+-define(wxTreebook_new_3, 1985).
+-define(wxTreebook_AddPage, 1986).
+-define(wxTreebook_AdvanceSelection, 1987).
+-define(wxTreebook_AssignImageList, 1988).
+-define(wxTreebook_Create, 1989).
+-define(wxTreebook_DeleteAllPages, 1990).
+-define(wxTreebook_DeletePage, 1991).
+-define(wxTreebook_RemovePage, 1992).
+-define(wxTreebook_GetCurrentPage, 1993).
+-define(wxTreebook_GetImageList, 1994).
+-define(wxTreebook_GetPage, 1996).
+-define(wxTreebook_GetPageCount, 1997).
+-define(wxTreebook_GetPageImage, 1998).
+-define(wxTreebook_GetPageText, 1999).
+-define(wxTreebook_GetSelection, 2000).
+-define(wxTreebook_ExpandNode, 2001).
+-define(wxTreebook_IsNodeExpanded, 2002).
+-define(wxTreebook_HitTest, 2004).
+-define(wxTreebook_InsertPage, 2005).
+-define(wxTreebook_InsertSubPage, 2006).
+-define(wxTreebook_SetImageList, 2007).
+-define(wxTreebook_SetPageSize, 2008).
+-define(wxTreebook_SetPageImage, 2009).
+-define(wxTreebook_SetPageText, 2010).
+-define(wxTreebook_SetSelection, 2011).
+-define(wxTreebook_ChangeSelection, 2012).
+-define(wxTreebook_destroy, 2013).
+-define(wxTreeCtrl_new_2, 2016).
+-define(wxTreeCtrl_new_0, 2017).
+-define(wxTreeCtrl_destruct, 2019).
+-define(wxTreeCtrl_AddRoot, 2020).
+-define(wxTreeCtrl_AppendItem, 2021).
+-define(wxTreeCtrl_AssignImageList, 2022).
+-define(wxTreeCtrl_AssignStateImageList, 2023).
+-define(wxTreeCtrl_Collapse, 2024).
+-define(wxTreeCtrl_CollapseAndReset, 2025).
+-define(wxTreeCtrl_Create, 2026).
+-define(wxTreeCtrl_Delete, 2027).
+-define(wxTreeCtrl_DeleteAllItems, 2028).
+-define(wxTreeCtrl_DeleteChildren, 2029).
+-define(wxTreeCtrl_EditLabel, 2030).
+-define(wxTreeCtrl_EnsureVisible, 2031).
+-define(wxTreeCtrl_Expand, 2032).
+-define(wxTreeCtrl_GetBoundingRect, 2033).
+-define(wxTreeCtrl_GetChildrenCount, 2035).
+-define(wxTreeCtrl_GetCount, 2036).
+-define(wxTreeCtrl_GetEditControl, 2037).
+-define(wxTreeCtrl_GetFirstChild, 2038).
+-define(wxTreeCtrl_GetNextChild, 2039).
+-define(wxTreeCtrl_GetFirstVisibleItem, 2040).
+-define(wxTreeCtrl_GetImageList, 2041).
+-define(wxTreeCtrl_GetIndent, 2042).
+-define(wxTreeCtrl_GetItemBackgroundColour, 2043).
+-define(wxTreeCtrl_GetItemData, 2044).
+-define(wxTreeCtrl_GetItemFont, 2045).
+-define(wxTreeCtrl_GetItemImage_1, 2046).
+-define(wxTreeCtrl_GetItemImage_2, 2047).
+-define(wxTreeCtrl_GetItemText, 2048).
+-define(wxTreeCtrl_GetItemTextColour, 2049).
+-define(wxTreeCtrl_GetLastChild, 2050).
+-define(wxTreeCtrl_GetNextSibling, 2051).
+-define(wxTreeCtrl_GetNextVisible, 2052).
+-define(wxTreeCtrl_GetItemParent, 2053).
+-define(wxTreeCtrl_GetPrevSibling, 2054).
+-define(wxTreeCtrl_GetPrevVisible, 2055).
+-define(wxTreeCtrl_GetRootItem, 2056).
+-define(wxTreeCtrl_GetSelection, 2057).
+-define(wxTreeCtrl_GetSelections, 2058).
+-define(wxTreeCtrl_GetStateImageList, 2059).
+-define(wxTreeCtrl_HitTest, 2060).
+-define(wxTreeCtrl_InsertItem, 2062).
+-define(wxTreeCtrl_IsBold, 2063).
+-define(wxTreeCtrl_IsExpanded, 2064).
+-define(wxTreeCtrl_IsSelected, 2065).
+-define(wxTreeCtrl_IsVisible, 2066).
+-define(wxTreeCtrl_ItemHasChildren, 2067).
+-define(wxTreeCtrl_IsTreeItemIdOk, 2068).
+-define(wxTreeCtrl_PrependItem, 2069).
+-define(wxTreeCtrl_ScrollTo, 2070).
+-define(wxTreeCtrl_SelectItem_1, 2071).
+-define(wxTreeCtrl_SelectItem_2, 2072).
+-define(wxTreeCtrl_SetIndent, 2073).
+-define(wxTreeCtrl_SetImageList, 2074).
+-define(wxTreeCtrl_SetItemBackgroundColour, 2075).
+-define(wxTreeCtrl_SetItemBold, 2076).
+-define(wxTreeCtrl_SetItemData, 2077).
+-define(wxTreeCtrl_SetItemDropHighlight, 2078).
+-define(wxTreeCtrl_SetItemFont, 2079).
+-define(wxTreeCtrl_SetItemHasChildren, 2080).
+-define(wxTreeCtrl_SetItemImage_2, 2081).
+-define(wxTreeCtrl_SetItemImage_3, 2082).
+-define(wxTreeCtrl_SetItemText, 2083).
+-define(wxTreeCtrl_SetItemTextColour, 2084).
+-define(wxTreeCtrl_SetStateImageList, 2085).
+-define(wxTreeCtrl_SetWindowStyle, 2086).
+-define(wxTreeCtrl_SortChildren, 2087).
+-define(wxTreeCtrl_Toggle, 2088).
+-define(wxTreeCtrl_ToggleItemSelection, 2089).
+-define(wxTreeCtrl_Unselect, 2090).
+-define(wxTreeCtrl_UnselectAll, 2091).
+-define(wxTreeCtrl_UnselectItem, 2092).
+-define(wxScrollBar_new_0, 2093).
+-define(wxScrollBar_new_3, 2094).
+-define(wxScrollBar_destruct, 2095).
+-define(wxScrollBar_Create, 2096).
+-define(wxScrollBar_GetRange, 2097).
+-define(wxScrollBar_GetPageSize, 2098).
+-define(wxScrollBar_GetThumbPosition, 2099).
+-define(wxScrollBar_GetThumbSize, 2100).
+-define(wxScrollBar_SetThumbPosition, 2101).
+-define(wxScrollBar_SetScrollbar, 2102).
+-define(wxSpinButton_new_2, 2104).
+-define(wxSpinButton_new_0, 2105).
+-define(wxSpinButton_Create, 2106).
+-define(wxSpinButton_GetMax, 2107).
+-define(wxSpinButton_GetMin, 2108).
+-define(wxSpinButton_GetValue, 2109).
+-define(wxSpinButton_SetRange, 2110).
+-define(wxSpinButton_SetValue, 2111).
+-define(wxSpinButton_destroy, 2112).
+-define(wxSpinCtrl_new_0, 2113).
+-define(wxSpinCtrl_new_2, 2114).
+-define(wxSpinCtrl_Create, 2116).
+-define(wxSpinCtrl_SetValue_1_1, 2119).
+-define(wxSpinCtrl_SetValue_1_0, 2120).
+-define(wxSpinCtrl_GetValue, 2122).
+-define(wxSpinCtrl_SetRange, 2124).
+-define(wxSpinCtrl_SetSelection, 2125).
+-define(wxSpinCtrl_GetMin, 2127).
+-define(wxSpinCtrl_GetMax, 2129).
+-define(wxSpinCtrl_destroy, 2130).
+-define(wxStaticText_new_0, 2131).
+-define(wxStaticText_new_4, 2132).
+-define(wxStaticText_Create, 2133).
+-define(wxStaticText_GetLabel, 2134).
+-define(wxStaticText_SetLabel, 2135).
+-define(wxStaticText_Wrap, 2136).
+-define(wxStaticText_destroy, 2137).
+-define(wxStaticBitmap_new_0, 2138).
+-define(wxStaticBitmap_new_4, 2139).
+-define(wxStaticBitmap_Create, 2140).
+-define(wxStaticBitmap_GetBitmap, 2141).
+-define(wxStaticBitmap_SetBitmap, 2142).
+-define(wxStaticBitmap_destroy, 2143).
+-define(wxRadioBox_new, 2144).
+-define(wxRadioBox_destruct, 2146).
+-define(wxRadioBox_Create, 2147).
+-define(wxRadioBox_Enable_2, 2148).
+-define(wxRadioBox_Enable_1, 2149).
+-define(wxRadioBox_GetSelection, 2150).
+-define(wxRadioBox_GetString, 2151).
+-define(wxRadioBox_SetSelection, 2152).
+-define(wxRadioBox_Show_2, 2153).
+-define(wxRadioBox_Show_1, 2154).
+-define(wxRadioBox_GetColumnCount, 2155).
+-define(wxRadioBox_GetItemHelpText, 2156).
+-define(wxRadioBox_GetItemToolTip, 2157).
+-define(wxRadioBox_GetItemFromPoint, 2159).
+-define(wxRadioBox_GetRowCount, 2160).
+-define(wxRadioBox_IsItemEnabled, 2161).
+-define(wxRadioBox_IsItemShown, 2162).
+-define(wxRadioBox_SetItemHelpText, 2163).
+-define(wxRadioBox_SetItemToolTip, 2164).
+-define(wxRadioButton_new_0, 2165).
+-define(wxRadioButton_new_4, 2166).
+-define(wxRadioButton_Create, 2167).
+-define(wxRadioButton_GetValue, 2168).
+-define(wxRadioButton_SetValue, 2169).
+-define(wxRadioButton_destroy, 2170).
+-define(wxSlider_new_6, 2172).
+-define(wxSlider_new_0, 2173).
+-define(wxSlider_Create, 2174).
+-define(wxSlider_GetLineSize, 2175).
+-define(wxSlider_GetMax, 2176).
+-define(wxSlider_GetMin, 2177).
+-define(wxSlider_GetPageSize, 2178).
+-define(wxSlider_GetThumbLength, 2179).
+-define(wxSlider_GetValue, 2180).
+-define(wxSlider_SetLineSize, 2181).
+-define(wxSlider_SetPageSize, 2182).
+-define(wxSlider_SetRange, 2183).
+-define(wxSlider_SetThumbLength, 2184).
+-define(wxSlider_SetValue, 2185).
+-define(wxSlider_destroy, 2186).
+-define(wxDialog_new_4, 2188).
+-define(wxDialog_new_0, 2189).
+-define(wxDialog_destruct, 2191).
+-define(wxDialog_Create, 2192).
+-define(wxDialog_CreateButtonSizer, 2193).
+-define(wxDialog_CreateStdDialogButtonSizer, 2194).
+-define(wxDialog_EndModal, 2195).
+-define(wxDialog_GetAffirmativeId, 2196).
+-define(wxDialog_GetReturnCode, 2197).
+-define(wxDialog_IsModal, 2198).
+-define(wxDialog_SetAffirmativeId, 2199).
+-define(wxDialog_SetReturnCode, 2200).
+-define(wxDialog_Show, 2201).
+-define(wxDialog_ShowModal, 2202).
+-define(wxColourDialog_new_0, 2203).
+-define(wxColourDialog_new_2, 2204).
+-define(wxColourDialog_destruct, 2205).
+-define(wxColourDialog_Create, 2206).
+-define(wxColourDialog_GetColourData, 2207).
+-define(wxColourData_new_0, 2208).
+-define(wxColourData_new_1, 2209).
+-define(wxColourData_destruct, 2210).
+-define(wxColourData_GetChooseFull, 2211).
+-define(wxColourData_GetColour, 2212).
+-define(wxColourData_GetCustomColour, 2214).
+-define(wxColourData_SetChooseFull, 2215).
+-define(wxColourData_SetColour, 2216).
+-define(wxColourData_SetCustomColour, 2217).
+-define(wxPalette_new_0, 2218).
+-define(wxPalette_new_4, 2219).
+-define(wxPalette_destruct, 2221).
+-define(wxPalette_Create, 2222).
+-define(wxPalette_GetColoursCount, 2223).
+-define(wxPalette_GetPixel, 2224).
+-define(wxPalette_GetRGB, 2225).
+-define(wxPalette_IsOk, 2226).
+-define(wxDirDialog_new, 2230).
+-define(wxDirDialog_destruct, 2231).
+-define(wxDirDialog_GetPath, 2232).
+-define(wxDirDialog_GetMessage, 2233).
+-define(wxDirDialog_SetMessage, 2234).
+-define(wxDirDialog_SetPath, 2235).
+-define(wxFileDialog_new, 2239).
+-define(wxFileDialog_destruct, 2240).
+-define(wxFileDialog_GetDirectory, 2241).
+-define(wxFileDialog_GetFilename, 2242).
+-define(wxFileDialog_GetFilenames, 2243).
+-define(wxFileDialog_GetFilterIndex, 2244).
+-define(wxFileDialog_GetMessage, 2245).
+-define(wxFileDialog_GetPath, 2246).
+-define(wxFileDialog_GetPaths, 2247).
+-define(wxFileDialog_GetWildcard, 2248).
+-define(wxFileDialog_SetDirectory, 2249).
+-define(wxFileDialog_SetFilename, 2250).
+-define(wxFileDialog_SetFilterIndex, 2251).
+-define(wxFileDialog_SetMessage, 2252).
+-define(wxFileDialog_SetPath, 2253).
+-define(wxFileDialog_SetWildcard, 2254).
+-define(wxPickerBase_SetInternalMargin, 2255).
+-define(wxPickerBase_GetInternalMargin, 2256).
+-define(wxPickerBase_SetTextCtrlProportion, 2257).
+-define(wxPickerBase_SetPickerCtrlProportion, 2258).
+-define(wxPickerBase_GetTextCtrlProportion, 2259).
+-define(wxPickerBase_GetPickerCtrlProportion, 2260).
+-define(wxPickerBase_HasTextCtrl, 2261).
+-define(wxPickerBase_GetTextCtrl, 2262).
+-define(wxPickerBase_IsTextCtrlGrowable, 2263).
+-define(wxPickerBase_SetPickerCtrlGrowable, 2264).
+-define(wxPickerBase_SetTextCtrlGrowable, 2265).
+-define(wxPickerBase_IsPickerCtrlGrowable, 2266).
+-define(wxFilePickerCtrl_new_0, 2267).
+-define(wxFilePickerCtrl_new_3, 2268).
+-define(wxFilePickerCtrl_Create, 2269).
+-define(wxFilePickerCtrl_GetPath, 2270).
+-define(wxFilePickerCtrl_SetPath, 2271).
+-define(wxFilePickerCtrl_destroy, 2272).
+-define(wxDirPickerCtrl_new_0, 2273).
+-define(wxDirPickerCtrl_new_3, 2274).
+-define(wxDirPickerCtrl_Create, 2275).
+-define(wxDirPickerCtrl_GetPath, 2276).
+-define(wxDirPickerCtrl_SetPath, 2277).
+-define(wxDirPickerCtrl_destroy, 2278).
+-define(wxColourPickerCtrl_new_0, 2279).
+-define(wxColourPickerCtrl_new_3, 2280).
+-define(wxColourPickerCtrl_Create, 2281).
+-define(wxColourPickerCtrl_GetColour, 2282).
+-define(wxColourPickerCtrl_SetColour_1_1, 2283).
+-define(wxColourPickerCtrl_SetColour_1_0, 2284).
+-define(wxColourPickerCtrl_destroy, 2285).
+-define(wxDatePickerCtrl_new_0, 2286).
+-define(wxDatePickerCtrl_new_3, 2287).
+-define(wxDatePickerCtrl_GetRange, 2288).
+-define(wxDatePickerCtrl_GetValue, 2289).
+-define(wxDatePickerCtrl_SetRange, 2290).
+-define(wxDatePickerCtrl_SetValue, 2291).
+-define(wxDatePickerCtrl_destroy, 2292).
+-define(wxFontPickerCtrl_new_0, 2293).
+-define(wxFontPickerCtrl_new_3, 2294).
+-define(wxFontPickerCtrl_Create, 2295).
+-define(wxFontPickerCtrl_GetSelectedFont, 2296).
+-define(wxFontPickerCtrl_SetSelectedFont, 2297).
+-define(wxFontPickerCtrl_GetMaxPointSize, 2298).
+-define(wxFontPickerCtrl_SetMaxPointSize, 2299).
+-define(wxFontPickerCtrl_destroy, 2300).
+-define(wxFindReplaceDialog_new_0, 2303).
+-define(wxFindReplaceDialog_new_4, 2304).
+-define(wxFindReplaceDialog_destruct, 2305).
+-define(wxFindReplaceDialog_Create, 2306).
+-define(wxFindReplaceDialog_GetData, 2307).
+-define(wxFindReplaceData_new_0, 2308).
+-define(wxFindReplaceData_new_1, 2309).
+-define(wxFindReplaceData_GetFindString, 2310).
+-define(wxFindReplaceData_GetReplaceString, 2311).
+-define(wxFindReplaceData_GetFlags, 2312).
+-define(wxFindReplaceData_SetFlags, 2313).
+-define(wxFindReplaceData_SetFindString, 2314).
+-define(wxFindReplaceData_SetReplaceString, 2315).
+-define(wxFindReplaceData_destroy, 2316).
+-define(wxMultiChoiceDialog_new_0, 2317).
+-define(wxMultiChoiceDialog_new_5, 2319).
+-define(wxMultiChoiceDialog_GetSelections, 2320).
+-define(wxMultiChoiceDialog_SetSelections, 2321).
+-define(wxMultiChoiceDialog_destroy, 2322).
+-define(wxSingleChoiceDialog_new_0, 2323).
+-define(wxSingleChoiceDialog_new_5, 2325).
+-define(wxSingleChoiceDialog_GetSelection, 2326).
+-define(wxSingleChoiceDialog_GetStringSelection, 2327).
+-define(wxSingleChoiceDialog_SetSelection, 2328).
+-define(wxSingleChoiceDialog_destroy, 2329).
+-define(wxTextEntryDialog_new, 2330).
+-define(wxTextEntryDialog_GetValue, 2331).
+-define(wxTextEntryDialog_SetValue, 2332).
+-define(wxTextEntryDialog_destroy, 2333).
+-define(wxPasswordEntryDialog_new, 2334).
+-define(wxPasswordEntryDialog_destroy, 2335).
+-define(wxFontData_new_0, 2336).
+-define(wxFontData_new_1, 2337).
+-define(wxFontData_destruct, 2338).
+-define(wxFontData_EnableEffects, 2339).
+-define(wxFontData_GetAllowSymbols, 2340).
+-define(wxFontData_GetColour, 2341).
+-define(wxFontData_GetChosenFont, 2342).
+-define(wxFontData_GetEnableEffects, 2343).
+-define(wxFontData_GetInitialFont, 2344).
+-define(wxFontData_GetShowHelp, 2345).
+-define(wxFontData_SetAllowSymbols, 2346).
+-define(wxFontData_SetChosenFont, 2347).
+-define(wxFontData_SetColour, 2348).
+-define(wxFontData_SetInitialFont, 2349).
+-define(wxFontData_SetRange, 2350).
+-define(wxFontData_SetShowHelp, 2351).
+-define(wxFontDialog_new_0, 2355).
+-define(wxFontDialog_new_2, 2357).
+-define(wxFontDialog_Create, 2359).
+-define(wxFontDialog_GetFontData, 2360).
+-define(wxFontDialog_destroy, 2362).
+-define(wxProgressDialog_new, 2363).
+-define(wxProgressDialog_destruct, 2364).
+-define(wxProgressDialog_Resume, 2365).
+-define(wxProgressDialog_Update_2, 2366).
+-define(wxProgressDialog_Update_0, 2367).
+-define(wxMessageDialog_new, 2368).
+-define(wxMessageDialog_destruct, 2369).
+-define(wxPageSetupDialog_new, 2370).
+-define(wxPageSetupDialog_destruct, 2371).
+-define(wxPageSetupDialog_GetPageSetupData, 2372).
+-define(wxPageSetupDialog_ShowModal, 2373).
+-define(wxPageSetupDialogData_new_0, 2374).
+-define(wxPageSetupDialogData_new_1_0, 2375).
+-define(wxPageSetupDialogData_new_1_1, 2376).
+-define(wxPageSetupDialogData_destruct, 2377).
+-define(wxPageSetupDialogData_EnableHelp, 2378).
+-define(wxPageSetupDialogData_EnableMargins, 2379).
+-define(wxPageSetupDialogData_EnableOrientation, 2380).
+-define(wxPageSetupDialogData_EnablePaper, 2381).
+-define(wxPageSetupDialogData_EnablePrinter, 2382).
+-define(wxPageSetupDialogData_GetDefaultMinMargins, 2383).
+-define(wxPageSetupDialogData_GetEnableMargins, 2384).
+-define(wxPageSetupDialogData_GetEnableOrientation, 2385).
+-define(wxPageSetupDialogData_GetEnablePaper, 2386).
+-define(wxPageSetupDialogData_GetEnablePrinter, 2387).
+-define(wxPageSetupDialogData_GetEnableHelp, 2388).
+-define(wxPageSetupDialogData_GetDefaultInfo, 2389).
+-define(wxPageSetupDialogData_GetMarginTopLeft, 2390).
+-define(wxPageSetupDialogData_GetMarginBottomRight, 2391).
+-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2392).
+-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2393).
+-define(wxPageSetupDialogData_GetPaperId, 2394).
+-define(wxPageSetupDialogData_GetPaperSize, 2395).
+-define(wxPageSetupDialogData_GetPrintData, 2397).
+-define(wxPageSetupDialogData_IsOk, 2398).
+-define(wxPageSetupDialogData_SetDefaultInfo, 2399).
+-define(wxPageSetupDialogData_SetDefaultMinMargins, 2400).
+-define(wxPageSetupDialogData_SetMarginTopLeft, 2401).
+-define(wxPageSetupDialogData_SetMarginBottomRight, 2402).
+-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2403).
+-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2404).
+-define(wxPageSetupDialogData_SetPaperId, 2405).
+-define(wxPageSetupDialogData_SetPaperSize_1_1, 2406).
+-define(wxPageSetupDialogData_SetPaperSize_1_0, 2407).
+-define(wxPageSetupDialogData_SetPrintData, 2408).
+-define(wxPrintDialog_new_2_0, 2409).
+-define(wxPrintDialog_new_2_1, 2410).
+-define(wxPrintDialog_destruct, 2411).
+-define(wxPrintDialog_GetPrintDialogData, 2412).
+-define(wxPrintDialog_GetPrintDC, 2413).
+-define(wxPrintDialogData_new_0, 2414).
+-define(wxPrintDialogData_new_1_1, 2415).
+-define(wxPrintDialogData_new_1_0, 2416).
+-define(wxPrintDialogData_destruct, 2417).
+-define(wxPrintDialogData_EnableHelp, 2418).
+-define(wxPrintDialogData_EnablePageNumbers, 2419).
+-define(wxPrintDialogData_EnablePrintToFile, 2420).
+-define(wxPrintDialogData_EnableSelection, 2421).
+-define(wxPrintDialogData_GetAllPages, 2422).
+-define(wxPrintDialogData_GetCollate, 2423).
+-define(wxPrintDialogData_GetFromPage, 2424).
+-define(wxPrintDialogData_GetMaxPage, 2425).
+-define(wxPrintDialogData_GetMinPage, 2426).
+-define(wxPrintDialogData_GetNoCopies, 2427).
+-define(wxPrintDialogData_GetPrintData, 2428).
+-define(wxPrintDialogData_GetPrintToFile, 2429).
+-define(wxPrintDialogData_GetSelection, 2430).
+-define(wxPrintDialogData_GetToPage, 2431).
+-define(wxPrintDialogData_IsOk, 2432).
+-define(wxPrintDialogData_SetCollate, 2433).
+-define(wxPrintDialogData_SetFromPage, 2434).
+-define(wxPrintDialogData_SetMaxPage, 2435).
+-define(wxPrintDialogData_SetMinPage, 2436).
+-define(wxPrintDialogData_SetNoCopies, 2437).
+-define(wxPrintDialogData_SetPrintData, 2438).
+-define(wxPrintDialogData_SetPrintToFile, 2439).
+-define(wxPrintDialogData_SetSelection, 2440).
+-define(wxPrintDialogData_SetToPage, 2441).
+-define(wxPrintData_new_0, 2442).
+-define(wxPrintData_new_1, 2443).
+-define(wxPrintData_destruct, 2444).
+-define(wxPrintData_GetCollate, 2445).
+-define(wxPrintData_GetBin, 2446).
+-define(wxPrintData_GetColour, 2447).
+-define(wxPrintData_GetDuplex, 2448).
+-define(wxPrintData_GetNoCopies, 2449).
+-define(wxPrintData_GetOrientation, 2450).
+-define(wxPrintData_GetPaperId, 2451).
+-define(wxPrintData_GetPrinterName, 2452).
+-define(wxPrintData_GetQuality, 2453).
+-define(wxPrintData_IsOk, 2454).
+-define(wxPrintData_SetBin, 2455).
+-define(wxPrintData_SetCollate, 2456).
+-define(wxPrintData_SetColour, 2457).
+-define(wxPrintData_SetDuplex, 2458).
+-define(wxPrintData_SetNoCopies, 2459).
+-define(wxPrintData_SetOrientation, 2460).
+-define(wxPrintData_SetPaperId, 2461).
+-define(wxPrintData_SetPrinterName, 2462).
+-define(wxPrintData_SetQuality, 2463).
+-define(wxPrintPreview_new_2, 2466).
+-define(wxPrintPreview_new_3, 2467).
+-define(wxPrintPreview_destruct, 2469).
+-define(wxPrintPreview_GetCanvas, 2470).
+-define(wxPrintPreview_GetCurrentPage, 2471).
+-define(wxPrintPreview_GetFrame, 2472).
+-define(wxPrintPreview_GetMaxPage, 2473).
+-define(wxPrintPreview_GetMinPage, 2474).
+-define(wxPrintPreview_GetPrintout, 2475).
+-define(wxPrintPreview_GetPrintoutForPrinting, 2476).
+-define(wxPrintPreview_IsOk, 2477).
+-define(wxPrintPreview_PaintPage, 2478).
+-define(wxPrintPreview_Print, 2479).
+-define(wxPrintPreview_RenderPage, 2480).
+-define(wxPrintPreview_SetCanvas, 2481).
+-define(wxPrintPreview_SetCurrentPage, 2482).
+-define(wxPrintPreview_SetFrame, 2483).
+-define(wxPrintPreview_SetPrintout, 2484).
+-define(wxPrintPreview_SetZoom, 2485).
+-define(wxPreviewFrame_new, 2486).
+-define(wxPreviewFrame_destruct, 2487).
+-define(wxPreviewFrame_CreateControlBar, 2488).
+-define(wxPreviewFrame_CreateCanvas, 2489).
+-define(wxPreviewFrame_Initialize, 2490).
+-define(wxPreviewFrame_OnCloseWindow, 2491).
+-define(wxPreviewControlBar_new, 2492).
+-define(wxPreviewControlBar_destruct, 2493).
+-define(wxPreviewControlBar_CreateButtons, 2494).
+-define(wxPreviewControlBar_GetPrintPreview, 2495).
+-define(wxPreviewControlBar_GetZoomControl, 2496).
+-define(wxPreviewControlBar_SetZoomControl, 2497).
+-define(wxPrinter_new, 2499).
+-define(wxPrinter_CreateAbortWindow, 2500).
+-define(wxPrinter_GetAbort, 2501).
+-define(wxPrinter_GetLastError, 2502).
+-define(wxPrinter_GetPrintDialogData, 2503).
+-define(wxPrinter_Print, 2504).
+-define(wxPrinter_PrintDialog, 2505).
+-define(wxPrinter_ReportError, 2506).
+-define(wxPrinter_Setup, 2507).
+-define(wxPrinter_destroy, 2508).
+-define(wxXmlResource_new_1, 2509).
+-define(wxXmlResource_new_2, 2510).
+-define(wxXmlResource_destruct, 2511).
+-define(wxXmlResource_AttachUnknownControl, 2512).
+-define(wxXmlResource_ClearHandlers, 2513).
+-define(wxXmlResource_CompareVersion, 2514).
+-define(wxXmlResource_Get, 2515).
+-define(wxXmlResource_GetFlags, 2516).
+-define(wxXmlResource_GetVersion, 2517).
+-define(wxXmlResource_GetXRCID, 2518).
+-define(wxXmlResource_InitAllHandlers, 2519).
+-define(wxXmlResource_Load, 2520).
+-define(wxXmlResource_LoadBitmap, 2521).
+-define(wxXmlResource_LoadDialog_2, 2522).
+-define(wxXmlResource_LoadDialog_3, 2523).
+-define(wxXmlResource_LoadFrame_2, 2524).
+-define(wxXmlResource_LoadFrame_3, 2525).
+-define(wxXmlResource_LoadIcon, 2526).
+-define(wxXmlResource_LoadMenu, 2527).
+-define(wxXmlResource_LoadMenuBar_2, 2528).
+-define(wxXmlResource_LoadMenuBar_1, 2529).
+-define(wxXmlResource_LoadPanel_2, 2530).
+-define(wxXmlResource_LoadPanel_3, 2531).
+-define(wxXmlResource_LoadToolBar, 2532).
+-define(wxXmlResource_Set, 2533).
+-define(wxXmlResource_SetFlags, 2534).
+-define(wxXmlResource_Unload, 2535).
+-define(wxXmlResource_xrcctrl, 2536).
+-define(wxHtmlEasyPrinting_new, 2537).
+-define(wxHtmlEasyPrinting_destruct, 2538).
+-define(wxHtmlEasyPrinting_GetPrintData, 2539).
+-define(wxHtmlEasyPrinting_GetPageSetupData, 2540).
+-define(wxHtmlEasyPrinting_PreviewFile, 2541).
+-define(wxHtmlEasyPrinting_PreviewText, 2542).
+-define(wxHtmlEasyPrinting_PrintFile, 2543).
+-define(wxHtmlEasyPrinting_PrintText, 2544).
+-define(wxHtmlEasyPrinting_PageSetup, 2545).
+-define(wxHtmlEasyPrinting_SetFonts, 2546).
+-define(wxHtmlEasyPrinting_SetHeader, 2547).
+-define(wxHtmlEasyPrinting_SetFooter, 2548).
+-define(wxGLCanvas_new_2, 2550).
+-define(wxGLCanvas_new_3_1, 2551).
+-define(wxGLCanvas_new_3_0, 2552).
+-define(wxGLCanvas_GetContext, 2553).
+-define(wxGLCanvas_SetCurrent, 2555).
+-define(wxGLCanvas_SwapBuffers, 2556).
+-define(wxGLCanvas_destroy, 2557).
+-define(wxAuiManager_new, 2558).
+-define(wxAuiManager_destruct, 2559).
+-define(wxAuiManager_AddPane_2_1, 2560).
+-define(wxAuiManager_AddPane_3, 2561).
+-define(wxAuiManager_AddPane_2_0, 2562).
+-define(wxAuiManager_DetachPane, 2563).
+-define(wxAuiManager_GetAllPanes, 2564).
+-define(wxAuiManager_GetArtProvider, 2565).
+-define(wxAuiManager_GetDockSizeConstraint, 2566).
+-define(wxAuiManager_GetFlags, 2567).
+-define(wxAuiManager_GetManagedWindow, 2568).
+-define(wxAuiManager_GetManager, 2569).
+-define(wxAuiManager_GetPane_1_1, 2570).
+-define(wxAuiManager_GetPane_1_0, 2571).
+-define(wxAuiManager_HideHint, 2572).
+-define(wxAuiManager_InsertPane, 2573).
+-define(wxAuiManager_LoadPaneInfo, 2574).
+-define(wxAuiManager_LoadPerspective, 2575).
+-define(wxAuiManager_SavePaneInfo, 2576).
+-define(wxAuiManager_SavePerspective, 2577).
+-define(wxAuiManager_SetArtProvider, 2578).
+-define(wxAuiManager_SetDockSizeConstraint, 2579).
+-define(wxAuiManager_SetFlags, 2580).
+-define(wxAuiManager_SetManagedWindow, 2581).
+-define(wxAuiManager_ShowHint, 2582).
+-define(wxAuiManager_UnInit, 2583).
+-define(wxAuiManager_Update, 2584).
+-define(wxAuiPaneInfo_new_0, 2585).
+-define(wxAuiPaneInfo_new_1, 2586).
+-define(wxAuiPaneInfo_destruct, 2587).
+-define(wxAuiPaneInfo_BestSize_1, 2588).
+-define(wxAuiPaneInfo_BestSize_2, 2589).
+-define(wxAuiPaneInfo_Bottom, 2590).
+-define(wxAuiPaneInfo_BottomDockable, 2591).
+-define(wxAuiPaneInfo_Caption, 2592).
+-define(wxAuiPaneInfo_CaptionVisible, 2593).
+-define(wxAuiPaneInfo_Centre, 2594).
+-define(wxAuiPaneInfo_CentrePane, 2595).
+-define(wxAuiPaneInfo_CloseButton, 2596).
+-define(wxAuiPaneInfo_DefaultPane, 2597).
+-define(wxAuiPaneInfo_DestroyOnClose, 2598).
+-define(wxAuiPaneInfo_Direction, 2599).
+-define(wxAuiPaneInfo_Dock, 2600).
+-define(wxAuiPaneInfo_Dockable, 2601).
+-define(wxAuiPaneInfo_Fixed, 2602).
+-define(wxAuiPaneInfo_Float, 2603).
+-define(wxAuiPaneInfo_Floatable, 2604).
+-define(wxAuiPaneInfo_FloatingPosition_1, 2605).
+-define(wxAuiPaneInfo_FloatingPosition_2, 2606).
+-define(wxAuiPaneInfo_FloatingSize_1, 2607).
+-define(wxAuiPaneInfo_FloatingSize_2, 2608).
+-define(wxAuiPaneInfo_Gripper, 2609).
+-define(wxAuiPaneInfo_GripperTop, 2610).
+-define(wxAuiPaneInfo_HasBorder, 2611).
+-define(wxAuiPaneInfo_HasCaption, 2612).
+-define(wxAuiPaneInfo_HasCloseButton, 2613).
+-define(wxAuiPaneInfo_HasFlag, 2614).
+-define(wxAuiPaneInfo_HasGripper, 2615).
+-define(wxAuiPaneInfo_HasGripperTop, 2616).
+-define(wxAuiPaneInfo_HasMaximizeButton, 2617).
+-define(wxAuiPaneInfo_HasMinimizeButton, 2618).
+-define(wxAuiPaneInfo_HasPinButton, 2619).
+-define(wxAuiPaneInfo_Hide, 2620).
+-define(wxAuiPaneInfo_IsBottomDockable, 2621).
+-define(wxAuiPaneInfo_IsDocked, 2622).
+-define(wxAuiPaneInfo_IsFixed, 2623).
+-define(wxAuiPaneInfo_IsFloatable, 2624).
+-define(wxAuiPaneInfo_IsFloating, 2625).
+-define(wxAuiPaneInfo_IsLeftDockable, 2626).
+-define(wxAuiPaneInfo_IsMovable, 2627).
+-define(wxAuiPaneInfo_IsOk, 2628).
+-define(wxAuiPaneInfo_IsResizable, 2629).
+-define(wxAuiPaneInfo_IsRightDockable, 2630).
+-define(wxAuiPaneInfo_IsShown, 2631).
+-define(wxAuiPaneInfo_IsToolbar, 2632).
+-define(wxAuiPaneInfo_IsTopDockable, 2633).
+-define(wxAuiPaneInfo_Layer, 2634).
+-define(wxAuiPaneInfo_Left, 2635).
+-define(wxAuiPaneInfo_LeftDockable, 2636).
+-define(wxAuiPaneInfo_MaxSize_1, 2637).
+-define(wxAuiPaneInfo_MaxSize_2, 2638).
+-define(wxAuiPaneInfo_MaximizeButton, 2639).
+-define(wxAuiPaneInfo_MinSize_1, 2640).
+-define(wxAuiPaneInfo_MinSize_2, 2641).
+-define(wxAuiPaneInfo_MinimizeButton, 2642).
+-define(wxAuiPaneInfo_Movable, 2643).
+-define(wxAuiPaneInfo_Name, 2644).
+-define(wxAuiPaneInfo_PaneBorder, 2645).
+-define(wxAuiPaneInfo_PinButton, 2646).
+-define(wxAuiPaneInfo_Position, 2647).
+-define(wxAuiPaneInfo_Resizable, 2648).
+-define(wxAuiPaneInfo_Right, 2649).
+-define(wxAuiPaneInfo_RightDockable, 2650).
+-define(wxAuiPaneInfo_Row, 2651).
+-define(wxAuiPaneInfo_SafeSet, 2652).
+-define(wxAuiPaneInfo_SetFlag, 2653).
+-define(wxAuiPaneInfo_Show, 2654).
+-define(wxAuiPaneInfo_ToolbarPane, 2655).
+-define(wxAuiPaneInfo_Top, 2656).
+-define(wxAuiPaneInfo_TopDockable, 2657).
+-define(wxAuiPaneInfo_Window, 2658).
+-define(wxAuiPaneInfo_GetWindow, 2659).
+-define(wxAuiPaneInfo_GetFrame, 2660).
+-define(wxAuiPaneInfo_GetDirection, 2661).
+-define(wxAuiPaneInfo_GetLayer, 2662).
+-define(wxAuiPaneInfo_GetRow, 2663).
+-define(wxAuiPaneInfo_GetPosition, 2664).
+-define(wxAuiPaneInfo_GetFloatingPosition, 2665).
+-define(wxAuiPaneInfo_GetFloatingSize, 2666).
+-define(wxAuiNotebook_new_0, 2667).
+-define(wxAuiNotebook_new_2, 2668).
+-define(wxAuiNotebook_AddPage, 2669).
+-define(wxAuiNotebook_Create, 2670).
+-define(wxAuiNotebook_DeletePage, 2671).
+-define(wxAuiNotebook_GetArtProvider, 2672).
+-define(wxAuiNotebook_GetPage, 2673).
+-define(wxAuiNotebook_GetPageBitmap, 2674).
+-define(wxAuiNotebook_GetPageCount, 2675).
+-define(wxAuiNotebook_GetPageIndex, 2676).
+-define(wxAuiNotebook_GetPageText, 2677).
+-define(wxAuiNotebook_GetSelection, 2678).
+-define(wxAuiNotebook_InsertPage, 2679).
+-define(wxAuiNotebook_RemovePage, 2680).
+-define(wxAuiNotebook_SetArtProvider, 2681).
+-define(wxAuiNotebook_SetFont, 2682).
+-define(wxAuiNotebook_SetPageBitmap, 2683).
+-define(wxAuiNotebook_SetPageText, 2684).
+-define(wxAuiNotebook_SetSelection, 2685).
+-define(wxAuiNotebook_SetTabCtrlHeight, 2686).
+-define(wxAuiNotebook_SetUniformBitmapSize, 2687).
+-define(wxAuiNotebook_destroy, 2688).
+-define(wxAuiTabArt_SetFlags, 2689).
+-define(wxAuiTabArt_SetMeasuringFont, 2690).
+-define(wxAuiTabArt_SetNormalFont, 2691).
+-define(wxAuiTabArt_SetSelectedFont, 2692).
+-define(wxAuiTabArt_SetColour, 2693).
+-define(wxAuiTabArt_SetActiveColour, 2694).
+-define(wxAuiDockArt_GetColour, 2695).
+-define(wxAuiDockArt_GetFont, 2696).
+-define(wxAuiDockArt_GetMetric, 2697).
+-define(wxAuiDockArt_SetColour, 2698).
+-define(wxAuiDockArt_SetFont, 2699).
+-define(wxAuiDockArt_SetMetric, 2700).
+-define(wxAuiSimpleTabArt_new, 2701).
+-define(wxAuiSimpleTabArt_destroy, 2702).
+-define(wxMDIParentFrame_new_0, 2703).
+-define(wxMDIParentFrame_new_4, 2704).
+-define(wxMDIParentFrame_destruct, 2705).
+-define(wxMDIParentFrame_ActivateNext, 2706).
+-define(wxMDIParentFrame_ActivatePrevious, 2707).
+-define(wxMDIParentFrame_ArrangeIcons, 2708).
+-define(wxMDIParentFrame_Cascade, 2709).
+-define(wxMDIParentFrame_Create, 2710).
+-define(wxMDIParentFrame_GetActiveChild, 2711).
+-define(wxMDIParentFrame_GetClientWindow, 2712).
+-define(wxMDIParentFrame_Tile, 2713).
+-define(wxMDIChildFrame_new_0, 2714).
+-define(wxMDIChildFrame_new_4, 2715).
+-define(wxMDIChildFrame_destruct, 2716).
+-define(wxMDIChildFrame_Activate, 2717).
+-define(wxMDIChildFrame_Create, 2718).
+-define(wxMDIChildFrame_Maximize, 2719).
+-define(wxMDIChildFrame_Restore, 2720).
+-define(wxMDIClientWindow_new_0, 2721).
+-define(wxMDIClientWindow_new_2, 2722).
+-define(wxMDIClientWindow_destruct, 2723).
+-define(wxMDIClientWindow_CreateClient, 2724).
+-define(wxLayoutAlgorithm_new, 2725).
+-define(wxLayoutAlgorithm_LayoutFrame, 2726).
+-define(wxLayoutAlgorithm_LayoutMDIFrame, 2727).
+-define(wxLayoutAlgorithm_LayoutWindow, 2728).
+-define(wxLayoutAlgorithm_destroy, 2729).
+-define(wxEvent_GetId, 2730).
+-define(wxEvent_GetSkipped, 2731).
+-define(wxEvent_GetTimestamp, 2732).
+-define(wxEvent_IsCommandEvent, 2733).
+-define(wxEvent_ResumePropagation, 2734).
+-define(wxEvent_ShouldPropagate, 2735).
+-define(wxEvent_Skip, 2736).
+-define(wxEvent_StopPropagation, 2737).
+-define(wxCommandEvent_getClientData, 2738).
+-define(wxCommandEvent_GetExtraLong, 2739).
+-define(wxCommandEvent_GetInt, 2740).
+-define(wxCommandEvent_GetSelection, 2741).
+-define(wxCommandEvent_GetString, 2742).
+-define(wxCommandEvent_IsChecked, 2743).
+-define(wxCommandEvent_IsSelection, 2744).
+-define(wxCommandEvent_SetInt, 2745).
+-define(wxCommandEvent_SetString, 2746).
+-define(wxScrollEvent_GetOrientation, 2747).
+-define(wxScrollEvent_GetPosition, 2748).
+-define(wxScrollWinEvent_GetOrientation, 2749).
+-define(wxScrollWinEvent_GetPosition, 2750).
+-define(wxMouseEvent_AltDown, 2751).
+-define(wxMouseEvent_Button, 2752).
+-define(wxMouseEvent_ButtonDClick, 2753).
+-define(wxMouseEvent_ButtonDown, 2754).
+-define(wxMouseEvent_ButtonUp, 2755).
+-define(wxMouseEvent_CmdDown, 2756).
+-define(wxMouseEvent_ControlDown, 2757).
+-define(wxMouseEvent_Dragging, 2758).
+-define(wxMouseEvent_Entering, 2759).
+-define(wxMouseEvent_GetButton, 2760).
+-define(wxMouseEvent_GetPosition, 2763).
+-define(wxMouseEvent_GetLogicalPosition, 2764).
+-define(wxMouseEvent_GetLinesPerAction, 2765).
+-define(wxMouseEvent_GetWheelRotation, 2766).
+-define(wxMouseEvent_GetWheelDelta, 2767).
+-define(wxMouseEvent_GetX, 2768).
+-define(wxMouseEvent_GetY, 2769).
+-define(wxMouseEvent_IsButton, 2770).
+-define(wxMouseEvent_IsPageScroll, 2771).
+-define(wxMouseEvent_Leaving, 2772).
+-define(wxMouseEvent_LeftDClick, 2773).
+-define(wxMouseEvent_LeftDown, 2774).
+-define(wxMouseEvent_LeftIsDown, 2775).
+-define(wxMouseEvent_LeftUp, 2776).
+-define(wxMouseEvent_MetaDown, 2777).
+-define(wxMouseEvent_MiddleDClick, 2778).
+-define(wxMouseEvent_MiddleDown, 2779).
+-define(wxMouseEvent_MiddleIsDown, 2780).
+-define(wxMouseEvent_MiddleUp, 2781).
+-define(wxMouseEvent_Moving, 2782).
+-define(wxMouseEvent_RightDClick, 2783).
+-define(wxMouseEvent_RightDown, 2784).
+-define(wxMouseEvent_RightIsDown, 2785).
+-define(wxMouseEvent_RightUp, 2786).
+-define(wxMouseEvent_ShiftDown, 2787).
+-define(wxSetCursorEvent_GetCursor, 2788).
+-define(wxSetCursorEvent_GetX, 2789).
+-define(wxSetCursorEvent_GetY, 2790).
+-define(wxSetCursorEvent_HasCursor, 2791).
+-define(wxSetCursorEvent_SetCursor, 2792).
+-define(wxKeyEvent_AltDown, 2793).
+-define(wxKeyEvent_CmdDown, 2794).
+-define(wxKeyEvent_ControlDown, 2795).
+-define(wxKeyEvent_GetKeyCode, 2796).
+-define(wxKeyEvent_GetModifiers, 2797).
+-define(wxKeyEvent_GetPosition, 2800).
+-define(wxKeyEvent_GetRawKeyCode, 2801).
+-define(wxKeyEvent_GetRawKeyFlags, 2802).
+-define(wxKeyEvent_GetUnicodeKey, 2803).
+-define(wxKeyEvent_GetX, 2804).
+-define(wxKeyEvent_GetY, 2805).
+-define(wxKeyEvent_HasModifiers, 2806).
+-define(wxKeyEvent_MetaDown, 2807).
+-define(wxKeyEvent_ShiftDown, 2808).
+-define(wxSizeEvent_GetSize, 2809).
+-define(wxMoveEvent_GetPosition, 2810).
+-define(wxEraseEvent_GetDC, 2811).
+-define(wxFocusEvent_GetWindow, 2812).
+-define(wxChildFocusEvent_GetWindow, 2813).
+-define(wxMenuEvent_GetMenu, 2814).
+-define(wxMenuEvent_GetMenuId, 2815).
+-define(wxMenuEvent_IsPopup, 2816).
+-define(wxCloseEvent_CanVeto, 2817).
+-define(wxCloseEvent_GetLoggingOff, 2818).
+-define(wxCloseEvent_SetCanVeto, 2819).
+-define(wxCloseEvent_SetLoggingOff, 2820).
+-define(wxCloseEvent_Veto, 2821).
+-define(wxShowEvent_SetShow, 2822).
+-define(wxShowEvent_GetShow, 2823).
+-define(wxIconizeEvent_Iconized, 2824).
+-define(wxJoystickEvent_ButtonDown, 2825).
+-define(wxJoystickEvent_ButtonIsDown, 2826).
+-define(wxJoystickEvent_ButtonUp, 2827).
+-define(wxJoystickEvent_GetButtonChange, 2828).
+-define(wxJoystickEvent_GetButtonState, 2829).
+-define(wxJoystickEvent_GetJoystick, 2830).
+-define(wxJoystickEvent_GetPosition, 2831).
+-define(wxJoystickEvent_GetZPosition, 2832).
+-define(wxJoystickEvent_IsButton, 2833).
+-define(wxJoystickEvent_IsMove, 2834).
+-define(wxJoystickEvent_IsZMove, 2835).
+-define(wxUpdateUIEvent_CanUpdate, 2836).
+-define(wxUpdateUIEvent_Check, 2837).
+-define(wxUpdateUIEvent_Enable, 2838).
+-define(wxUpdateUIEvent_Show, 2839).
+-define(wxUpdateUIEvent_GetChecked, 2840).
+-define(wxUpdateUIEvent_GetEnabled, 2841).
+-define(wxUpdateUIEvent_GetShown, 2842).
+-define(wxUpdateUIEvent_GetSetChecked, 2843).
+-define(wxUpdateUIEvent_GetSetEnabled, 2844).
+-define(wxUpdateUIEvent_GetSetShown, 2845).
+-define(wxUpdateUIEvent_GetSetText, 2846).
+-define(wxUpdateUIEvent_GetText, 2847).
+-define(wxUpdateUIEvent_GetMode, 2848).
+-define(wxUpdateUIEvent_GetUpdateInterval, 2849).
+-define(wxUpdateUIEvent_ResetUpdateTime, 2850).
+-define(wxUpdateUIEvent_SetMode, 2851).
+-define(wxUpdateUIEvent_SetText, 2852).
+-define(wxUpdateUIEvent_SetUpdateInterval, 2853).
+-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2854).
+-define(wxPaletteChangedEvent_SetChangedWindow, 2855).
+-define(wxPaletteChangedEvent_GetChangedWindow, 2856).
+-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2857).
+-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2858).
+-define(wxNavigationKeyEvent_GetDirection, 2859).
+-define(wxNavigationKeyEvent_SetDirection, 2860).
+-define(wxNavigationKeyEvent_IsWindowChange, 2861).
+-define(wxNavigationKeyEvent_SetWindowChange, 2862).
+-define(wxNavigationKeyEvent_IsFromTab, 2863).
+-define(wxNavigationKeyEvent_SetFromTab, 2864).
+-define(wxNavigationKeyEvent_GetCurrentFocus, 2865).
+-define(wxNavigationKeyEvent_SetCurrentFocus, 2866).
+-define(wxHelpEvent_GetOrigin, 2867).
+-define(wxHelpEvent_GetPosition, 2868).
+-define(wxHelpEvent_SetOrigin, 2869).
+-define(wxHelpEvent_SetPosition, 2870).
+-define(wxContextMenuEvent_GetPosition, 2871).
+-define(wxContextMenuEvent_SetPosition, 2872).
+-define(wxIdleEvent_CanSend, 2873).
+-define(wxIdleEvent_GetMode, 2874).
+-define(wxIdleEvent_RequestMore, 2875).
+-define(wxIdleEvent_MoreRequested, 2876).
+-define(wxIdleEvent_SetMode, 2877).
+-define(wxGridEvent_AltDown, 2878).
+-define(wxGridEvent_ControlDown, 2879).
+-define(wxGridEvent_GetCol, 2880).
+-define(wxGridEvent_GetPosition, 2881).
+-define(wxGridEvent_GetRow, 2882).
+-define(wxGridEvent_MetaDown, 2883).
+-define(wxGridEvent_Selecting, 2884).
+-define(wxGridEvent_ShiftDown, 2885).
+-define(wxNotifyEvent_Allow, 2886).
+-define(wxNotifyEvent_IsAllowed, 2887).
+-define(wxNotifyEvent_Veto, 2888).
+-define(wxSashEvent_GetEdge, 2889).
+-define(wxSashEvent_GetDragRect, 2890).
+-define(wxSashEvent_GetDragStatus, 2891).
+-define(wxListEvent_GetCacheFrom, 2892).
+-define(wxListEvent_GetCacheTo, 2893).
+-define(wxListEvent_GetKeyCode, 2894).
+-define(wxListEvent_GetIndex, 2895).
+-define(wxListEvent_GetColumn, 2896).
+-define(wxListEvent_GetPoint, 2897).
+-define(wxListEvent_GetLabel, 2898).
+-define(wxListEvent_GetText, 2899).
+-define(wxListEvent_GetImage, 2900).
+-define(wxListEvent_GetData, 2901).
+-define(wxListEvent_GetMask, 2902).
+-define(wxListEvent_GetItem, 2903).
+-define(wxListEvent_IsEditCancelled, 2904).
+-define(wxDateEvent_GetDate, 2905).
+-define(wxCalendarEvent_GetWeekDay, 2906).
+-define(wxFileDirPickerEvent_GetPath, 2907).
+-define(wxColourPickerEvent_GetColour, 2908).
+-define(wxFontPickerEvent_GetFont, 2909).
+-define(wxStyledTextEvent_GetPosition, 2910).
+-define(wxStyledTextEvent_GetKey, 2911).
+-define(wxStyledTextEvent_GetModifiers, 2912).
+-define(wxStyledTextEvent_GetModificationType, 2913).
+-define(wxStyledTextEvent_GetText, 2914).
+-define(wxStyledTextEvent_GetLength, 2915).
+-define(wxStyledTextEvent_GetLinesAdded, 2916).
+-define(wxStyledTextEvent_GetLine, 2917).
+-define(wxStyledTextEvent_GetFoldLevelNow, 2918).
+-define(wxStyledTextEvent_GetFoldLevelPrev, 2919).
+-define(wxStyledTextEvent_GetMargin, 2920).
+-define(wxStyledTextEvent_GetMessage, 2921).
+-define(wxStyledTextEvent_GetWParam, 2922).
+-define(wxStyledTextEvent_GetLParam, 2923).
+-define(wxStyledTextEvent_GetListType, 2924).
+-define(wxStyledTextEvent_GetX, 2925).
+-define(wxStyledTextEvent_GetY, 2926).
+-define(wxStyledTextEvent_GetDragText, 2927).
+-define(wxStyledTextEvent_GetDragAllowMove, 2928).
+-define(wxStyledTextEvent_GetDragResult, 2929).
+-define(wxStyledTextEvent_GetShift, 2930).
+-define(wxStyledTextEvent_GetControl, 2931).
+-define(wxStyledTextEvent_GetAlt, 2932).
+-define(utils_wxGetKeyState, 2933).
+-define(utils_wxGetMousePosition, 2934).
+-define(utils_wxGetMouseState, 2935).
+-define(utils_wxSetDetectableAutoRepeat, 2936).
+-define(utils_wxBell, 2937).
+-define(utils_wxFindMenuItemId, 2938).
+-define(utils_wxGenericFindWindowAtPoint, 2939).
+-define(utils_wxFindWindowAtPoint, 2940).
+-define(utils_wxBeginBusyCursor, 2941).
+-define(utils_wxEndBusyCursor, 2942).
+-define(utils_wxIsBusy, 2943).
+-define(utils_wxShutdown, 2944).
+-define(utils_wxShell, 2945).
+-define(utils_wxLaunchDefaultBrowser, 2946).
+-define(utils_wxGetEmailAddress, 2947).
+-define(utils_wxGetUserId, 2948).
+-define(utils_wxGetHomeDir, 2949).
+-define(utils_wxNewId, 2950).
+-define(utils_wxRegisterId, 2951).
+-define(utils_wxGetCurrentId, 2952).
+-define(utils_wxGetOsDescription, 2953).
+-define(utils_wxIsPlatformLittleEndian, 2954).
+-define(utils_wxIsPlatform64Bit, 2955).
+-define(gdicmn_wxDisplaySize, 2956).
+-define(gdicmn_wxSetCursor, 2957).
+-define(wxPrintout_new, 2958).
+-define(wxPrintout_destruct, 2959).
+-define(wxPrintout_GetDC, 2960).
+-define(wxPrintout_GetPageSizeMM, 2961).
+-define(wxPrintout_GetPageSizePixels, 2962).
+-define(wxPrintout_GetPaperRectPixels, 2963).
+-define(wxPrintout_GetPPIPrinter, 2964).
+-define(wxPrintout_GetPPIScreen, 2965).
+-define(wxPrintout_GetTitle, 2966).
+-define(wxPrintout_IsPreview, 2967).
+-define(wxPrintout_FitThisSizeToPaper, 2968).
+-define(wxPrintout_FitThisSizeToPage, 2969).
+-define(wxPrintout_FitThisSizeToPageMargins, 2970).
+-define(wxPrintout_MapScreenSizeToPaper, 2971).
+-define(wxPrintout_MapScreenSizeToPage, 2972).
+-define(wxPrintout_MapScreenSizeToPageMargins, 2973).
+-define(wxPrintout_MapScreenSizeToDevice, 2974).
+-define(wxPrintout_GetLogicalPaperRect, 2975).
+-define(wxPrintout_GetLogicalPageRect, 2976).
+-define(wxPrintout_GetLogicalPageMarginsRect, 2977).
+-define(wxPrintout_SetLogicalOrigin, 2978).
+-define(wxPrintout_OffsetLogicalOrigin, 2979).
+-define(wxStyledTextCtrl_new_2, 2980).
+-define(wxStyledTextCtrl_new_0, 2981).
+-define(wxStyledTextCtrl_destruct, 2982).
+-define(wxStyledTextCtrl_Create, 2983).
+-define(wxStyledTextCtrl_AddText, 2984).
+-define(wxStyledTextCtrl_AddStyledText, 2985).
+-define(wxStyledTextCtrl_InsertText, 2986).
+-define(wxStyledTextCtrl_ClearAll, 2987).
+-define(wxStyledTextCtrl_ClearDocumentStyle, 2988).
+-define(wxStyledTextCtrl_GetLength, 2989).
+-define(wxStyledTextCtrl_GetCharAt, 2990).
+-define(wxStyledTextCtrl_GetCurrentPos, 2991).
+-define(wxStyledTextCtrl_GetAnchor, 2992).
+-define(wxStyledTextCtrl_GetStyleAt, 2993).
+-define(wxStyledTextCtrl_Redo, 2994).
+-define(wxStyledTextCtrl_SetUndoCollection, 2995).
+-define(wxStyledTextCtrl_SelectAll, 2996).
+-define(wxStyledTextCtrl_SetSavePoint, 2997).
+-define(wxStyledTextCtrl_GetStyledText, 2998).
+-define(wxStyledTextCtrl_CanRedo, 2999).
+-define(wxStyledTextCtrl_MarkerLineFromHandle, 3000).
+-define(wxStyledTextCtrl_MarkerDeleteHandle, 3001).
+-define(wxStyledTextCtrl_GetUndoCollection, 3002).
+-define(wxStyledTextCtrl_GetViewWhiteSpace, 3003).
+-define(wxStyledTextCtrl_SetViewWhiteSpace, 3004).
+-define(wxStyledTextCtrl_PositionFromPoint, 3005).
+-define(wxStyledTextCtrl_PositionFromPointClose, 3006).
+-define(wxStyledTextCtrl_GotoLine, 3007).
+-define(wxStyledTextCtrl_GotoPos, 3008).
+-define(wxStyledTextCtrl_SetAnchor, 3009).
+-define(wxStyledTextCtrl_GetCurLine, 3010).
+-define(wxStyledTextCtrl_GetEndStyled, 3011).
+-define(wxStyledTextCtrl_ConvertEOLs, 3012).
+-define(wxStyledTextCtrl_GetEOLMode, 3013).
+-define(wxStyledTextCtrl_SetEOLMode, 3014).
+-define(wxStyledTextCtrl_StartStyling, 3015).
+-define(wxStyledTextCtrl_SetStyling, 3016).
+-define(wxStyledTextCtrl_GetBufferedDraw, 3017).
+-define(wxStyledTextCtrl_SetBufferedDraw, 3018).
+-define(wxStyledTextCtrl_SetTabWidth, 3019).
+-define(wxStyledTextCtrl_GetTabWidth, 3020).
+-define(wxStyledTextCtrl_SetCodePage, 3021).
+-define(wxStyledTextCtrl_MarkerDefine, 3022).
+-define(wxStyledTextCtrl_MarkerSetForeground, 3023).
+-define(wxStyledTextCtrl_MarkerSetBackground, 3024).
+-define(wxStyledTextCtrl_MarkerAdd, 3025).
+-define(wxStyledTextCtrl_MarkerDelete, 3026).
+-define(wxStyledTextCtrl_MarkerDeleteAll, 3027).
+-define(wxStyledTextCtrl_MarkerGet, 3028).
+-define(wxStyledTextCtrl_MarkerNext, 3029).
+-define(wxStyledTextCtrl_MarkerPrevious, 3030).
+-define(wxStyledTextCtrl_MarkerDefineBitmap, 3031).
+-define(wxStyledTextCtrl_MarkerAddSet, 3032).
+-define(wxStyledTextCtrl_MarkerSetAlpha, 3033).
+-define(wxStyledTextCtrl_SetMarginType, 3034).
+-define(wxStyledTextCtrl_GetMarginType, 3035).
+-define(wxStyledTextCtrl_SetMarginWidth, 3036).
+-define(wxStyledTextCtrl_GetMarginWidth, 3037).
+-define(wxStyledTextCtrl_SetMarginMask, 3038).
+-define(wxStyledTextCtrl_GetMarginMask, 3039).
+-define(wxStyledTextCtrl_SetMarginSensitive, 3040).
+-define(wxStyledTextCtrl_GetMarginSensitive, 3041).
+-define(wxStyledTextCtrl_StyleClearAll, 3042).
+-define(wxStyledTextCtrl_StyleSetForeground, 3043).
+-define(wxStyledTextCtrl_StyleSetBackground, 3044).
+-define(wxStyledTextCtrl_StyleSetBold, 3045).
+-define(wxStyledTextCtrl_StyleSetItalic, 3046).
+-define(wxStyledTextCtrl_StyleSetSize, 3047).
+-define(wxStyledTextCtrl_StyleSetFaceName, 3048).
+-define(wxStyledTextCtrl_StyleSetEOLFilled, 3049).
+-define(wxStyledTextCtrl_StyleResetDefault, 3050).
+-define(wxStyledTextCtrl_StyleSetUnderline, 3051).
+-define(wxStyledTextCtrl_StyleSetCase, 3052).
+-define(wxStyledTextCtrl_StyleSetHotSpot, 3053).
+-define(wxStyledTextCtrl_SetSelForeground, 3054).
+-define(wxStyledTextCtrl_SetSelBackground, 3055).
+-define(wxStyledTextCtrl_GetSelAlpha, 3056).
+-define(wxStyledTextCtrl_SetSelAlpha, 3057).
+-define(wxStyledTextCtrl_SetCaretForeground, 3058).
+-define(wxStyledTextCtrl_CmdKeyAssign, 3059).
+-define(wxStyledTextCtrl_CmdKeyClear, 3060).
+-define(wxStyledTextCtrl_CmdKeyClearAll, 3061).
+-define(wxStyledTextCtrl_SetStyleBytes, 3062).
+-define(wxStyledTextCtrl_StyleSetVisible, 3063).
+-define(wxStyledTextCtrl_GetCaretPeriod, 3064).
+-define(wxStyledTextCtrl_SetCaretPeriod, 3065).
+-define(wxStyledTextCtrl_SetWordChars, 3066).
+-define(wxStyledTextCtrl_BeginUndoAction, 3067).
+-define(wxStyledTextCtrl_EndUndoAction, 3068).
+-define(wxStyledTextCtrl_IndicatorSetStyle, 3069).
+-define(wxStyledTextCtrl_IndicatorGetStyle, 3070).
+-define(wxStyledTextCtrl_IndicatorSetForeground, 3071).
+-define(wxStyledTextCtrl_IndicatorGetForeground, 3072).
+-define(wxStyledTextCtrl_SetWhitespaceForeground, 3073).
+-define(wxStyledTextCtrl_SetWhitespaceBackground, 3074).
+-define(wxStyledTextCtrl_GetStyleBits, 3075).
+-define(wxStyledTextCtrl_SetLineState, 3076).
+-define(wxStyledTextCtrl_GetLineState, 3077).
+-define(wxStyledTextCtrl_GetMaxLineState, 3078).
+-define(wxStyledTextCtrl_GetCaretLineVisible, 3079).
+-define(wxStyledTextCtrl_SetCaretLineVisible, 3080).
+-define(wxStyledTextCtrl_GetCaretLineBackground, 3081).
+-define(wxStyledTextCtrl_SetCaretLineBackground, 3082).
+-define(wxStyledTextCtrl_AutoCompShow, 3083).
+-define(wxStyledTextCtrl_AutoCompCancel, 3084).
+-define(wxStyledTextCtrl_AutoCompActive, 3085).
+-define(wxStyledTextCtrl_AutoCompPosStart, 3086).
+-define(wxStyledTextCtrl_AutoCompComplete, 3087).
+-define(wxStyledTextCtrl_AutoCompStops, 3088).
+-define(wxStyledTextCtrl_AutoCompSetSeparator, 3089).
+-define(wxStyledTextCtrl_AutoCompGetSeparator, 3090).
+-define(wxStyledTextCtrl_AutoCompSelect, 3091).
+-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3092).
+-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3093).
+-define(wxStyledTextCtrl_AutoCompSetFillUps, 3094).
+-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3095).
+-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3096).
+-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3097).
+-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3098).
+-define(wxStyledTextCtrl_UserListShow, 3099).
+-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3100).
+-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3101).
+-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3102).
+-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3103).
+-define(wxStyledTextCtrl_RegisterImage, 3104).
+-define(wxStyledTextCtrl_ClearRegisteredImages, 3105).
+-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3106).
+-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3107).
+-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3108).
+-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3109).
+-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3110).
+-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3111).
+-define(wxStyledTextCtrl_SetIndent, 3112).
+-define(wxStyledTextCtrl_GetIndent, 3113).
+-define(wxStyledTextCtrl_SetUseTabs, 3114).
+-define(wxStyledTextCtrl_GetUseTabs, 3115).
+-define(wxStyledTextCtrl_SetLineIndentation, 3116).
+-define(wxStyledTextCtrl_GetLineIndentation, 3117).
+-define(wxStyledTextCtrl_GetLineIndentPosition, 3118).
+-define(wxStyledTextCtrl_GetColumn, 3119).
+-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3120).
+-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3121).
+-define(wxStyledTextCtrl_SetIndentationGuides, 3122).
+-define(wxStyledTextCtrl_GetIndentationGuides, 3123).
+-define(wxStyledTextCtrl_SetHighlightGuide, 3124).
+-define(wxStyledTextCtrl_GetHighlightGuide, 3125).
+-define(wxStyledTextCtrl_GetLineEndPosition, 3126).
+-define(wxStyledTextCtrl_GetCodePage, 3127).
+-define(wxStyledTextCtrl_GetCaretForeground, 3128).
+-define(wxStyledTextCtrl_GetReadOnly, 3129).
+-define(wxStyledTextCtrl_SetCurrentPos, 3130).
+-define(wxStyledTextCtrl_SetSelectionStart, 3131).
+-define(wxStyledTextCtrl_GetSelectionStart, 3132).
+-define(wxStyledTextCtrl_SetSelectionEnd, 3133).
+-define(wxStyledTextCtrl_GetSelectionEnd, 3134).
+-define(wxStyledTextCtrl_SetPrintMagnification, 3135).
+-define(wxStyledTextCtrl_GetPrintMagnification, 3136).
+-define(wxStyledTextCtrl_SetPrintColourMode, 3137).
+-define(wxStyledTextCtrl_GetPrintColourMode, 3138).
+-define(wxStyledTextCtrl_FindText, 3139).
+-define(wxStyledTextCtrl_FormatRange, 3140).
+-define(wxStyledTextCtrl_GetFirstVisibleLine, 3141).
+-define(wxStyledTextCtrl_GetLine, 3142).
+-define(wxStyledTextCtrl_GetLineCount, 3143).
+-define(wxStyledTextCtrl_SetMarginLeft, 3144).
+-define(wxStyledTextCtrl_GetMarginLeft, 3145).
+-define(wxStyledTextCtrl_SetMarginRight, 3146).
+-define(wxStyledTextCtrl_GetMarginRight, 3147).
+-define(wxStyledTextCtrl_GetModify, 3148).
+-define(wxStyledTextCtrl_SetSelection, 3149).
+-define(wxStyledTextCtrl_GetSelectedText, 3150).
+-define(wxStyledTextCtrl_GetTextRange, 3151).
+-define(wxStyledTextCtrl_HideSelection, 3152).
+-define(wxStyledTextCtrl_LineFromPosition, 3153).
+-define(wxStyledTextCtrl_PositionFromLine, 3154).
+-define(wxStyledTextCtrl_LineScroll, 3155).
+-define(wxStyledTextCtrl_EnsureCaretVisible, 3156).
+-define(wxStyledTextCtrl_ReplaceSelection, 3157).
+-define(wxStyledTextCtrl_SetReadOnly, 3158).
+-define(wxStyledTextCtrl_CanPaste, 3159).
+-define(wxStyledTextCtrl_CanUndo, 3160).
+-define(wxStyledTextCtrl_EmptyUndoBuffer, 3161).
+-define(wxStyledTextCtrl_Undo, 3162).
+-define(wxStyledTextCtrl_Cut, 3163).
+-define(wxStyledTextCtrl_Copy, 3164).
+-define(wxStyledTextCtrl_Paste, 3165).
+-define(wxStyledTextCtrl_Clear, 3166).
+-define(wxStyledTextCtrl_SetText, 3167).
+-define(wxStyledTextCtrl_GetText, 3168).
+-define(wxStyledTextCtrl_GetTextLength, 3169).
+-define(wxStyledTextCtrl_GetOvertype, 3170).
+-define(wxStyledTextCtrl_SetCaretWidth, 3171).
+-define(wxStyledTextCtrl_GetCaretWidth, 3172).
+-define(wxStyledTextCtrl_SetTargetStart, 3173).
+-define(wxStyledTextCtrl_GetTargetStart, 3174).
+-define(wxStyledTextCtrl_SetTargetEnd, 3175).
+-define(wxStyledTextCtrl_GetTargetEnd, 3176).
+-define(wxStyledTextCtrl_ReplaceTarget, 3177).
+-define(wxStyledTextCtrl_SearchInTarget, 3178).
+-define(wxStyledTextCtrl_SetSearchFlags, 3179).
+-define(wxStyledTextCtrl_GetSearchFlags, 3180).
+-define(wxStyledTextCtrl_CallTipShow, 3181).
+-define(wxStyledTextCtrl_CallTipCancel, 3182).
+-define(wxStyledTextCtrl_CallTipActive, 3183).
+-define(wxStyledTextCtrl_CallTipPosAtStart, 3184).
+-define(wxStyledTextCtrl_CallTipSetHighlight, 3185).
+-define(wxStyledTextCtrl_CallTipSetBackground, 3186).
+-define(wxStyledTextCtrl_CallTipSetForeground, 3187).
+-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3188).
+-define(wxStyledTextCtrl_CallTipUseStyle, 3189).
+-define(wxStyledTextCtrl_VisibleFromDocLine, 3190).
+-define(wxStyledTextCtrl_DocLineFromVisible, 3191).
+-define(wxStyledTextCtrl_WrapCount, 3192).
+-define(wxStyledTextCtrl_SetFoldLevel, 3193).
+-define(wxStyledTextCtrl_GetFoldLevel, 3194).
+-define(wxStyledTextCtrl_GetLastChild, 3195).
+-define(wxStyledTextCtrl_GetFoldParent, 3196).
+-define(wxStyledTextCtrl_ShowLines, 3197).
+-define(wxStyledTextCtrl_HideLines, 3198).
+-define(wxStyledTextCtrl_GetLineVisible, 3199).
+-define(wxStyledTextCtrl_SetFoldExpanded, 3200).
+-define(wxStyledTextCtrl_GetFoldExpanded, 3201).
+-define(wxStyledTextCtrl_ToggleFold, 3202).
+-define(wxStyledTextCtrl_EnsureVisible, 3203).
+-define(wxStyledTextCtrl_SetFoldFlags, 3204).
+-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3205).
+-define(wxStyledTextCtrl_SetTabIndents, 3206).
+-define(wxStyledTextCtrl_GetTabIndents, 3207).
+-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3208).
+-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3209).
+-define(wxStyledTextCtrl_SetMouseDwellTime, 3210).
+-define(wxStyledTextCtrl_GetMouseDwellTime, 3211).
+-define(wxStyledTextCtrl_WordStartPosition, 3212).
+-define(wxStyledTextCtrl_WordEndPosition, 3213).
+-define(wxStyledTextCtrl_SetWrapMode, 3214).
+-define(wxStyledTextCtrl_GetWrapMode, 3215).
+-define(wxStyledTextCtrl_SetWrapVisualFlags, 3216).
+-define(wxStyledTextCtrl_GetWrapVisualFlags, 3217).
+-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3218).
+-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3219).
+-define(wxStyledTextCtrl_SetWrapStartIndent, 3220).
+-define(wxStyledTextCtrl_GetWrapStartIndent, 3221).
+-define(wxStyledTextCtrl_SetLayoutCache, 3222).
+-define(wxStyledTextCtrl_GetLayoutCache, 3223).
+-define(wxStyledTextCtrl_SetScrollWidth, 3224).
+-define(wxStyledTextCtrl_GetScrollWidth, 3225).
+-define(wxStyledTextCtrl_TextWidth, 3226).
+-define(wxStyledTextCtrl_GetEndAtLastLine, 3227).
+-define(wxStyledTextCtrl_TextHeight, 3228).
+-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3229).
+-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3230).
+-define(wxStyledTextCtrl_AppendText, 3231).
+-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3232).
+-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3233).
+-define(wxStyledTextCtrl_TargetFromSelection, 3234).
+-define(wxStyledTextCtrl_LinesJoin, 3235).
+-define(wxStyledTextCtrl_LinesSplit, 3236).
+-define(wxStyledTextCtrl_SetFoldMarginColour, 3237).
+-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3238).
+-define(wxStyledTextCtrl_LineDown, 3239).
+-define(wxStyledTextCtrl_LineDownExtend, 3240).
+-define(wxStyledTextCtrl_LineUp, 3241).
+-define(wxStyledTextCtrl_LineUpExtend, 3242).
+-define(wxStyledTextCtrl_CharLeft, 3243).
+-define(wxStyledTextCtrl_CharLeftExtend, 3244).
+-define(wxStyledTextCtrl_CharRight, 3245).
+-define(wxStyledTextCtrl_CharRightExtend, 3246).
+-define(wxStyledTextCtrl_WordLeft, 3247).
+-define(wxStyledTextCtrl_WordLeftExtend, 3248).
+-define(wxStyledTextCtrl_WordRight, 3249).
+-define(wxStyledTextCtrl_WordRightExtend, 3250).
+-define(wxStyledTextCtrl_Home, 3251).
+-define(wxStyledTextCtrl_HomeExtend, 3252).
+-define(wxStyledTextCtrl_LineEnd, 3253).
+-define(wxStyledTextCtrl_LineEndExtend, 3254).
+-define(wxStyledTextCtrl_DocumentStart, 3255).
+-define(wxStyledTextCtrl_DocumentStartExtend, 3256).
+-define(wxStyledTextCtrl_DocumentEnd, 3257).
+-define(wxStyledTextCtrl_DocumentEndExtend, 3258).
+-define(wxStyledTextCtrl_PageUp, 3259).
+-define(wxStyledTextCtrl_PageUpExtend, 3260).
+-define(wxStyledTextCtrl_PageDown, 3261).
+-define(wxStyledTextCtrl_PageDownExtend, 3262).
+-define(wxStyledTextCtrl_EditToggleOvertype, 3263).
+-define(wxStyledTextCtrl_Cancel, 3264).
+-define(wxStyledTextCtrl_DeleteBack, 3265).
+-define(wxStyledTextCtrl_Tab, 3266).
+-define(wxStyledTextCtrl_BackTab, 3267).
+-define(wxStyledTextCtrl_NewLine, 3268).
+-define(wxStyledTextCtrl_FormFeed, 3269).
+-define(wxStyledTextCtrl_VCHome, 3270).
+-define(wxStyledTextCtrl_VCHomeExtend, 3271).
+-define(wxStyledTextCtrl_ZoomIn, 3272).
+-define(wxStyledTextCtrl_ZoomOut, 3273).
+-define(wxStyledTextCtrl_DelWordLeft, 3274).
+-define(wxStyledTextCtrl_DelWordRight, 3275).
+-define(wxStyledTextCtrl_LineCut, 3276).
+-define(wxStyledTextCtrl_LineDelete, 3277).
+-define(wxStyledTextCtrl_LineTranspose, 3278).
+-define(wxStyledTextCtrl_LineDuplicate, 3279).
+-define(wxStyledTextCtrl_LowerCase, 3280).
+-define(wxStyledTextCtrl_UpperCase, 3281).
+-define(wxStyledTextCtrl_LineScrollDown, 3282).
+-define(wxStyledTextCtrl_LineScrollUp, 3283).
+-define(wxStyledTextCtrl_DeleteBackNotLine, 3284).
+-define(wxStyledTextCtrl_HomeDisplay, 3285).
+-define(wxStyledTextCtrl_HomeDisplayExtend, 3286).
+-define(wxStyledTextCtrl_LineEndDisplay, 3287).
+-define(wxStyledTextCtrl_LineEndDisplayExtend, 3288).
+-define(wxStyledTextCtrl_HomeWrapExtend, 3289).
+-define(wxStyledTextCtrl_LineEndWrap, 3290).
+-define(wxStyledTextCtrl_LineEndWrapExtend, 3291).
+-define(wxStyledTextCtrl_VCHomeWrap, 3292).
+-define(wxStyledTextCtrl_VCHomeWrapExtend, 3293).
+-define(wxStyledTextCtrl_LineCopy, 3294).
+-define(wxStyledTextCtrl_MoveCaretInsideView, 3295).
+-define(wxStyledTextCtrl_LineLength, 3296).
+-define(wxStyledTextCtrl_BraceHighlight, 3297).
+-define(wxStyledTextCtrl_BraceBadLight, 3298).
+-define(wxStyledTextCtrl_BraceMatch, 3299).
+-define(wxStyledTextCtrl_GetViewEOL, 3300).
+-define(wxStyledTextCtrl_SetViewEOL, 3301).
+-define(wxStyledTextCtrl_SetModEventMask, 3302).
+-define(wxStyledTextCtrl_GetEdgeColumn, 3303).
+-define(wxStyledTextCtrl_SetEdgeColumn, 3304).
+-define(wxStyledTextCtrl_SetEdgeMode, 3305).
+-define(wxStyledTextCtrl_GetEdgeMode, 3306).
+-define(wxStyledTextCtrl_GetEdgeColour, 3307).
+-define(wxStyledTextCtrl_SetEdgeColour, 3308).
+-define(wxStyledTextCtrl_SearchAnchor, 3309).
+-define(wxStyledTextCtrl_SearchNext, 3310).
+-define(wxStyledTextCtrl_SearchPrev, 3311).
+-define(wxStyledTextCtrl_LinesOnScreen, 3312).
+-define(wxStyledTextCtrl_UsePopUp, 3313).
+-define(wxStyledTextCtrl_SelectionIsRectangle, 3314).
+-define(wxStyledTextCtrl_SetZoom, 3315).
+-define(wxStyledTextCtrl_GetZoom, 3316).
+-define(wxStyledTextCtrl_GetModEventMask, 3317).
+-define(wxStyledTextCtrl_SetSTCFocus, 3318).
+-define(wxStyledTextCtrl_GetSTCFocus, 3319).
+-define(wxStyledTextCtrl_SetStatus, 3320).
+-define(wxStyledTextCtrl_GetStatus, 3321).
+-define(wxStyledTextCtrl_SetMouseDownCaptures, 3322).
+-define(wxStyledTextCtrl_GetMouseDownCaptures, 3323).
+-define(wxStyledTextCtrl_SetSTCCursor, 3324).
+-define(wxStyledTextCtrl_GetSTCCursor, 3325).
+-define(wxStyledTextCtrl_SetControlCharSymbol, 3326).
+-define(wxStyledTextCtrl_GetControlCharSymbol, 3327).
+-define(wxStyledTextCtrl_WordPartLeft, 3328).
+-define(wxStyledTextCtrl_WordPartLeftExtend, 3329).
+-define(wxStyledTextCtrl_WordPartRight, 3330).
+-define(wxStyledTextCtrl_WordPartRightExtend, 3331).
+-define(wxStyledTextCtrl_SetVisiblePolicy, 3332).
+-define(wxStyledTextCtrl_DelLineLeft, 3333).
+-define(wxStyledTextCtrl_DelLineRight, 3334).
+-define(wxStyledTextCtrl_GetXOffset, 3335).
+-define(wxStyledTextCtrl_ChooseCaretX, 3336).
+-define(wxStyledTextCtrl_SetXCaretPolicy, 3337).
+-define(wxStyledTextCtrl_SetYCaretPolicy, 3338).
+-define(wxStyledTextCtrl_GetPrintWrapMode, 3339).
+-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3340).
+-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3341).
+-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3342).
+-define(wxStyledTextCtrl_SetHotspotSingleLine, 3343).
+-define(wxStyledTextCtrl_ParaDownExtend, 3344).
+-define(wxStyledTextCtrl_ParaUp, 3345).
+-define(wxStyledTextCtrl_ParaUpExtend, 3346).
+-define(wxStyledTextCtrl_PositionBefore, 3347).
+-define(wxStyledTextCtrl_PositionAfter, 3348).
+-define(wxStyledTextCtrl_CopyRange, 3349).
+-define(wxStyledTextCtrl_CopyText, 3350).
+-define(wxStyledTextCtrl_SetSelectionMode, 3351).
+-define(wxStyledTextCtrl_GetSelectionMode, 3352).
+-define(wxStyledTextCtrl_LineDownRectExtend, 3353).
+-define(wxStyledTextCtrl_LineUpRectExtend, 3354).
+-define(wxStyledTextCtrl_CharLeftRectExtend, 3355).
+-define(wxStyledTextCtrl_CharRightRectExtend, 3356).
+-define(wxStyledTextCtrl_HomeRectExtend, 3357).
+-define(wxStyledTextCtrl_VCHomeRectExtend, 3358).
+-define(wxStyledTextCtrl_LineEndRectExtend, 3359).
+-define(wxStyledTextCtrl_PageUpRectExtend, 3360).
+-define(wxStyledTextCtrl_PageDownRectExtend, 3361).
+-define(wxStyledTextCtrl_StutteredPageUp, 3362).
+-define(wxStyledTextCtrl_StutteredPageUpExtend, 3363).
+-define(wxStyledTextCtrl_StutteredPageDown, 3364).
+-define(wxStyledTextCtrl_StutteredPageDownExtend, 3365).
+-define(wxStyledTextCtrl_WordLeftEnd, 3366).
+-define(wxStyledTextCtrl_WordLeftEndExtend, 3367).
+-define(wxStyledTextCtrl_WordRightEnd, 3368).
+-define(wxStyledTextCtrl_WordRightEndExtend, 3369).
+-define(wxStyledTextCtrl_SetWhitespaceChars, 3370).
+-define(wxStyledTextCtrl_SetCharsDefault, 3371).
+-define(wxStyledTextCtrl_AutoCompGetCurrent, 3372).
+-define(wxStyledTextCtrl_Allocate, 3373).
+-define(wxStyledTextCtrl_FindColumn, 3374).
+-define(wxStyledTextCtrl_GetCaretSticky, 3375).
+-define(wxStyledTextCtrl_SetCaretSticky, 3376).
+-define(wxStyledTextCtrl_ToggleCaretSticky, 3377).
+-define(wxStyledTextCtrl_SetPasteConvertEndings, 3378).
+-define(wxStyledTextCtrl_GetPasteConvertEndings, 3379).
+-define(wxStyledTextCtrl_SelectionDuplicate, 3380).
+-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3381).
+-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3382).
+-define(wxStyledTextCtrl_StartRecord, 3383).
+-define(wxStyledTextCtrl_StopRecord, 3384).
+-define(wxStyledTextCtrl_SetLexer, 3385).
+-define(wxStyledTextCtrl_GetLexer, 3386).
+-define(wxStyledTextCtrl_Colourise, 3387).
+-define(wxStyledTextCtrl_SetProperty, 3388).
+-define(wxStyledTextCtrl_SetKeyWords, 3389).
+-define(wxStyledTextCtrl_SetLexerLanguage, 3390).
+-define(wxStyledTextCtrl_GetProperty, 3391).
+-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3392).
+-define(wxStyledTextCtrl_GetCurrentLine, 3393).
+-define(wxStyledTextCtrl_StyleSetSpec, 3394).
+-define(wxStyledTextCtrl_StyleSetFont, 3395).
+-define(wxStyledTextCtrl_StyleSetFontAttr, 3396).
+-define(wxStyledTextCtrl_StyleSetCharacterSet, 3397).
+-define(wxStyledTextCtrl_StyleSetFontEncoding, 3398).
+-define(wxStyledTextCtrl_CmdKeyExecute, 3399).
+-define(wxStyledTextCtrl_SetMargins, 3400).
+-define(wxStyledTextCtrl_GetSelection, 3401).
+-define(wxStyledTextCtrl_PointFromPosition, 3402).
+-define(wxStyledTextCtrl_ScrollToLine, 3403).
+-define(wxStyledTextCtrl_ScrollToColumn, 3404).
+-define(wxStyledTextCtrl_SetVScrollBar, 3405).
+-define(wxStyledTextCtrl_SetHScrollBar, 3406).
+-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3407).
+-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3408).
+-define(wxStyledTextCtrl_SaveFile, 3409).
+-define(wxStyledTextCtrl_LoadFile, 3410).
+-define(wxStyledTextCtrl_DoDragOver, 3411).
+-define(wxStyledTextCtrl_DoDropText, 3412).
+-define(wxStyledTextCtrl_GetUseAntiAliasing, 3413).
+-define(wxStyledTextCtrl_AddTextRaw, 3414).
+-define(wxStyledTextCtrl_InsertTextRaw, 3415).
+-define(wxStyledTextCtrl_GetCurLineRaw, 3416).
+-define(wxStyledTextCtrl_GetLineRaw, 3417).
+-define(wxStyledTextCtrl_GetSelectedTextRaw, 3418).
+-define(wxStyledTextCtrl_GetTextRangeRaw, 3419).
+-define(wxStyledTextCtrl_SetTextRaw, 3420).
+-define(wxStyledTextCtrl_GetTextRaw, 3421).
+-define(wxStyledTextCtrl_AppendTextRaw, 3422).
+-define(wxArtProvider_GetBitmap, 3423).
+-define(wxArtProvider_GetIcon, 3424).
+-define(wxTreeEvent_GetKeyCode, 3425).
+-define(wxTreeEvent_GetItem, 3426).
+-define(wxTreeEvent_GetKeyEvent, 3427).
+-define(wxTreeEvent_GetLabel, 3428).
+-define(wxTreeEvent_GetOldItem, 3429).
+-define(wxTreeEvent_GetPoint, 3430).
+-define(wxTreeEvent_IsEditCancelled, 3431).
+-define(wxTreeEvent_SetToolTip, 3432).
+-define(wxNotebookEvent_GetOldSelection, 3433).
+-define(wxNotebookEvent_GetSelection, 3434).
+-define(wxNotebookEvent_SetOldSelection, 3435).
+-define(wxNotebookEvent_SetSelection, 3436).
+-define(wxFileDataObject_new, 3437).
+-define(wxFileDataObject_AddFile, 3438).
+-define(wxFileDataObject_GetFilenames, 3439).
+-define(wxFileDataObject_destroy, 3440).
+-define(wxTextDataObject_new, 3441).
+-define(wxTextDataObject_GetTextLength, 3442).
+-define(wxTextDataObject_GetText, 3443).
+-define(wxTextDataObject_SetText, 3444).
+-define(wxTextDataObject_destroy, 3445).
+-define(wxBitmapDataObject_new_1_1, 3446).
+-define(wxBitmapDataObject_new_1_0, 3447).
+-define(wxBitmapDataObject_GetBitmap, 3448).
+-define(wxBitmapDataObject_SetBitmap, 3449).
+-define(wxBitmapDataObject_destroy, 3450).
+-define(wxClipboard_new, 3452).
+-define(wxClipboard_destruct, 3453).
+-define(wxClipboard_AddData, 3454).
+-define(wxClipboard_Clear, 3455).
+-define(wxClipboard_Close, 3456).
+-define(wxClipboard_Flush, 3457).
+-define(wxClipboard_GetData, 3458).
+-define(wxClipboard_IsOpened, 3459).
+-define(wxClipboard_Open, 3460).
+-define(wxClipboard_SetData, 3461).
+-define(wxClipboard_UsePrimarySelection, 3463).
+-define(wxClipboard_IsSupported, 3464).
+-define(wxClipboard_Get, 3465).
+-define(wxSpinEvent_GetPosition, 3466).
+-define(wxSpinEvent_SetPosition, 3467).
+-define(wxSplitterWindow_new_0, 3468).
+-define(wxSplitterWindow_new_2, 3469).
+-define(wxSplitterWindow_destruct, 3470).
+-define(wxSplitterWindow_Create, 3471).
+-define(wxSplitterWindow_GetMinimumPaneSize, 3472).
+-define(wxSplitterWindow_GetSashGravity, 3473).
+-define(wxSplitterWindow_GetSashPosition, 3474).
+-define(wxSplitterWindow_GetSplitMode, 3475).
+-define(wxSplitterWindow_GetWindow1, 3476).
+-define(wxSplitterWindow_GetWindow2, 3477).
+-define(wxSplitterWindow_Initialize, 3478).
+-define(wxSplitterWindow_IsSplit, 3479).
+-define(wxSplitterWindow_ReplaceWindow, 3480).
+-define(wxSplitterWindow_SetSashGravity, 3481).
+-define(wxSplitterWindow_SetSashPosition, 3482).
+-define(wxSplitterWindow_SetSashSize, 3483).
+-define(wxSplitterWindow_SetMinimumPaneSize, 3484).
+-define(wxSplitterWindow_SetSplitMode, 3485).
+-define(wxSplitterWindow_SplitHorizontally, 3486).
+-define(wxSplitterWindow_SplitVertically, 3487).
+-define(wxSplitterWindow_Unsplit, 3488).
+-define(wxSplitterWindow_UpdateSize, 3489).
+-define(wxSplitterEvent_GetSashPosition, 3490).
+-define(wxSplitterEvent_GetX, 3491).
+-define(wxSplitterEvent_GetY, 3492).
+-define(wxSplitterEvent_GetWindowBeingRemoved, 3493).
+-define(wxSplitterEvent_SetSashPosition, 3494).
+-define(wxHtmlWindow_new_0, 3495).
+-define(wxHtmlWindow_new_2, 3496).
+-define(wxHtmlWindow_AppendToPage, 3497).
+-define(wxHtmlWindow_GetOpenedAnchor, 3498).
+-define(wxHtmlWindow_GetOpenedPage, 3499).
+-define(wxHtmlWindow_GetOpenedPageTitle, 3500).
+-define(wxHtmlWindow_GetRelatedFrame, 3501).
+-define(wxHtmlWindow_HistoryBack, 3502).
+-define(wxHtmlWindow_HistoryCanBack, 3503).
+-define(wxHtmlWindow_HistoryCanForward, 3504).
+-define(wxHtmlWindow_HistoryClear, 3505).
+-define(wxHtmlWindow_HistoryForward, 3506).
+-define(wxHtmlWindow_LoadFile, 3507).
+-define(wxHtmlWindow_LoadPage, 3508).
+-define(wxHtmlWindow_SelectAll, 3509).
+-define(wxHtmlWindow_SelectionToText, 3510).
+-define(wxHtmlWindow_SelectLine, 3511).
+-define(wxHtmlWindow_SelectWord, 3512).
+-define(wxHtmlWindow_SetBorders, 3513).
+-define(wxHtmlWindow_SetFonts, 3514).
+-define(wxHtmlWindow_SetPage, 3515).
+-define(wxHtmlWindow_SetRelatedFrame, 3516).
+-define(wxHtmlWindow_SetRelatedStatusBar, 3517).
+-define(wxHtmlWindow_ToText, 3518).
+-define(wxHtmlWindow_destroy, 3519).
+-define(wxHtmlLinkEvent_GetLinkInfo, 3520).
+-define(wxSystemSettings_GetColour, 3521).
+-define(wxSystemSettings_GetFont, 3522).
+-define(wxSystemSettings_GetMetric, 3523).
+-define(wxSystemSettings_GetScreenType, 3524).
+-define(wxSystemOptions_GetOption, 3525).
+-define(wxSystemOptions_GetOptionInt, 3526).
+-define(wxSystemOptions_HasOption, 3527).
+-define(wxSystemOptions_IsFalse, 3528).
+-define(wxSystemOptions_SetOption_2_1, 3529).
+-define(wxSystemOptions_SetOption_2_0, 3530).
+-define(wxAuiNotebookEvent_SetSelection, 3531).
+-define(wxAuiNotebookEvent_GetSelection, 3532).
+-define(wxAuiNotebookEvent_SetOldSelection, 3533).
+-define(wxAuiNotebookEvent_GetOldSelection, 3534).
+-define(wxAuiNotebookEvent_SetDragSource, 3535).
+-define(wxAuiNotebookEvent_GetDragSource, 3536).
+-define(wxAuiManagerEvent_SetManager, 3537).
+-define(wxAuiManagerEvent_GetManager, 3538).
+-define(wxAuiManagerEvent_SetPane, 3539).
+-define(wxAuiManagerEvent_GetPane, 3540).
+-define(wxAuiManagerEvent_SetButton, 3541).
+-define(wxAuiManagerEvent_GetButton, 3542).
+-define(wxAuiManagerEvent_SetDC, 3543).
+-define(wxAuiManagerEvent_GetDC, 3544).
+-define(wxAuiManagerEvent_Veto, 3545).
+-define(wxAuiManagerEvent_GetVeto, 3546).
+-define(wxAuiManagerEvent_SetCanVeto, 3547).
+-define(wxAuiManagerEvent_CanVeto, 3548).
+-define(wxLogNull_new, 3549).
+-define(wxLogNull_destroy, 3550).
+-define(wxTaskBarIcon_new, 3551).
+-define(wxTaskBarIcon_destruct, 3552).
+-define(wxTaskBarIcon_PopupMenu, 3553).
+-define(wxTaskBarIcon_RemoveIcon, 3554).
+-define(wxTaskBarIcon_SetIcon, 3555).
+-define(wxLocale_new_0, 3556).
+-define(wxLocale_new_2, 3558).
+-define(wxLocale_destruct, 3559).
+-define(wxLocale_Init, 3561).
+-define(wxLocale_AddCatalog_1, 3562).
+-define(wxLocale_AddCatalog_3, 3563).
+-define(wxLocale_AddCatalogLookupPathPrefix, 3564).
+-define(wxLocale_GetCanonicalName, 3565).
+-define(wxLocale_GetLanguage, 3566).
+-define(wxLocale_GetLanguageName, 3567).
+-define(wxLocale_GetLocale, 3568).
+-define(wxLocale_GetName, 3569).
+-define(wxLocale_GetString_2, 3570).
+-define(wxLocale_GetString_4, 3571).
+-define(wxLocale_GetHeaderValue, 3572).
+-define(wxLocale_GetSysName, 3573).
+-define(wxLocale_GetSystemEncoding, 3574).
+-define(wxLocale_GetSystemEncodingName, 3575).
+-define(wxLocale_GetSystemLanguage, 3576).
+-define(wxLocale_IsLoaded, 3577).
+-define(wxLocale_IsOk, 3578).
+-define(wxActivateEvent_GetActive, 3579).
+-define(wxPopupWindow_new_2, 3581).
+-define(wxPopupWindow_new_0, 3582).
+-define(wxPopupWindow_destruct, 3584).
+-define(wxPopupWindow_Create, 3585).
+-define(wxPopupWindow_Position, 3586).
+-define(wxPopupTransientWindow_new_0, 3587).
+-define(wxPopupTransientWindow_new_2, 3588).
+-define(wxPopupTransientWindow_destruct, 3589).
+-define(wxPopupTransientWindow_Popup, 3590).
+-define(wxPopupTransientWindow_Dismiss, 3591).
+-define(wxOverlay_new, 3592).
+-define(wxOverlay_destruct, 3593).
+-define(wxOverlay_Reset, 3594).
+-define(wxDCOverlay_new_6, 3595).
+-define(wxDCOverlay_new_2, 3596).
+-define(wxDCOverlay_destruct, 3597).
+-define(wxDCOverlay_Clear, 3598).
diff --git a/lib/wx/src/wx.app.src b/lib/wx/src/wx.app.src
index d5ac478f20..9b9358abf6 100644
--- a/lib/wx/src/wx.app.src
+++ b/lib/wx/src/wx.app.src
@@ -4,16 +4,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
diff --git a/lib/wx/src/wx.appup.src b/lib/wx/src/wx.appup.src
index 311c0c0f52..aea54f6814 100644
--- a/lib/wx/src/wx.appup.src
+++ b/lib/wx/src/wx.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/wx/src/wx.erl b/lib/wx/src/wx.erl
index 2a4b18d101..e9f612edf7 100644
--- a/lib/wx/src/wx.erl
+++ b/lib/wx/src/wx.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl
index 80f8937656..35069425ac 100644
--- a/lib/wx/src/wx_object.erl
+++ b/lib/wx/src/wx_object.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
@@ -102,6 +103,7 @@
%% API
-export([start/3, start/4,
start_link/3, start_link/4,
+ stop/1, stop/3,
call/2, call/3,
cast/2,
reply/2,
@@ -215,6 +217,42 @@ gen_response({ok, Pid}) ->
gen_response(Reply) ->
Reply.
+%% @spec (Ref::wxObject()|atom()|pid()) -> ok
+%% @doc Stops a generic wx_object server with reason 'normal'.
+%% Invokes terminate(Reason,State) in the server. The call waits until
+%% the process is terminated. If the process does not exist, an
+%% exception is raised.
+stop(Ref = #wx_ref{state=Pid}) when is_pid(Pid) ->
+ try
+ gen:stop(Pid)
+ catch _:ExitReason ->
+ erlang:error({ExitReason, {?MODULE, stop, [Ref]}})
+ end;
+stop(Name) when is_atom(Name) orelse is_pid(Name) ->
+ try
+ gen:stop(Name)
+ catch _:ExitReason ->
+ erlang:error({ExitReason, {?MODULE, stop, [Name]}})
+ end.
+
+%% @spec (Ref::wxObject()|atom()|pid(), Reason::term(), Timeout::timeout()) -> ok
+%% @doc Stops a generic wx_object server with the given Reason.
+%% Invokes terminate(Reason,State) in the server. The call waits until
+%% the process is terminated. If the call times out, or if the process
+%% does not exist, an exception is raised.
+stop(Ref = #wx_ref{state=Pid}, Reason, Timeout) when is_pid(Pid) ->
+ try
+ gen:stop(Pid, Reason, Timeout)
+ catch _:ExitReason ->
+ erlang:error({ExitReason, {?MODULE, stop, [Ref, Reason, Timeout]}})
+ end;
+stop(Name, Reason, Timeout) when is_atom(Name) orelse is_pid(Name) ->
+ try
+ gen:stop(Name, Reason, Timeout)
+ catch _:ExitReason ->
+ erlang:error({ExitReason, {?MODULE, stop, [Name, Reason, Timeout]}})
+ end.
+
%% @spec (Ref::wxObject()|atom()|pid(), Request::term()) -> term()
%% @doc Make a call to a wx_object server.
%% The call waits until it gets a result.
@@ -563,22 +601,10 @@ opt(_, []) ->
%% @hidden
debug_options(Name, Opts) ->
case opt(debug, Opts) of
- {ok, Options} -> dbg_options(Name, Options);
- _ -> dbg_options(Name, [])
+ {ok, Options} -> dbg_opts(Name, Options);
+ _ -> []
end.
%% @hidden
-dbg_options(Name, []) ->
- Opts =
- case init:get_argument(generic_debug) of
- error ->
- [];
- _ ->
- [log, statistics]
- end,
- dbg_opts(Name, Opts);
-dbg_options(Name, Opts) ->
- dbg_opts(Name, Opts).
-%% @hidden
dbg_opts(Name, Opts) ->
case catch sys:debug_options(Opts) of
{'EXIT',_} ->
diff --git a/lib/wx/src/wxe.hrl b/lib/wx/src/wxe.hrl
index 66ec9ac45e..75bd260d38 100644
--- a/lib/wx/src/wxe.hrl
+++ b/lib/wx/src/wxe.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl
index 4b8a8f5720..cdf66aa6d1 100644
--- a/lib/wx/src/wxe_master.erl
+++ b/lib/wx/src/wxe_master.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/src/wxe_server.erl b/lib/wx/src/wxe_server.erl
index 153e2475ba..693a008e3d 100644
--- a/lib/wx/src/wxe_server.erl
+++ b/lib/wx/src/wxe_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
@@ -239,6 +240,8 @@ handle_connect(Object, EvData=#evh{handler=Handler},
invoke_cb({{Ev=#wx{}, Ref=#wx_ref{}}, FunId,_}, _S) ->
%% Event callbacks
case get(FunId) of
+ {{nospawn, Fun}, _} when is_function(Fun) ->
+ invoke_callback_fun(fun() -> Fun(Ev, Ref), <<>> end);
{Fun,_} when is_function(Fun) ->
invoke_callback(fun() -> Fun(Ev, Ref), <<>> end);
{Pid,_} when is_pid(Pid) -> %% wx_object sync event
@@ -257,21 +260,10 @@ invoke_cb({FunId, Args, _}, _S) when is_list(Args), is_integer(FunId) ->
invoke_callback(Fun) ->
Env = get(?WXE_IDENTIFIER),
- CB = fun() ->
- wx:set_env(Env),
- wxe_util:cast(?WXE_CB_START, <<>>),
- Res = try
- Return = Fun(),
- true = is_binary(Return),
- Return
- catch _:Reason ->
- ?log("Callback fun crashed with {'EXIT, ~p, ~p}~n",
- [Reason, erlang:get_stacktrace()]),
- <<>>
- end,
- wxe_util:cast(?WXE_CB_RETURN, Res)
- end,
- spawn(CB),
+ spawn(fun() ->
+ wx:set_env(Env),
+ invoke_callback_fun(Fun)
+ end),
ok.
invoke_callback(Pid, Ev, Ref) ->
@@ -280,7 +272,7 @@ invoke_callback(Pid, Ev, Ref) ->
wx:set_env(Env),
wxe_util:cast(?WXE_CB_START, <<>>),
try
- case get_wx_object_state(Pid) of
+ case get_wx_object_state(Pid, 5) of
ignore ->
%% Ignore early events
wxEvent:skip(Ref);
@@ -301,16 +293,38 @@ invoke_callback(Pid, Ev, Ref) ->
spawn(CB),
ok.
-get_wx_object_state(Pid) ->
+invoke_callback_fun(Fun) ->
+ wxe_util:cast(?WXE_CB_START, <<>>),
+ Res = try
+ Return = Fun(),
+ true = is_binary(Return),
+ Return
+ catch _:Reason ->
+ ?log("Callback fun crashed with {'EXIT, ~p, ~p}~n",
+ [Reason, erlang:get_stacktrace()]),
+ <<>>
+ end,
+ wxe_util:cast(?WXE_CB_RETURN, Res).
+
+
+get_wx_object_state(Pid, N) when N > 0 ->
case process_info(Pid, dictionary) of
{dictionary, Dict} ->
case lists:keysearch('_wx_object_',1,Dict) of
- {value, {'_wx_object_', {_Mod, '_wx_init_'}}} -> ignore;
- {value, {'_wx_object_', Value}} -> Value;
- _ -> ignore
+ {value, {'_wx_object_', {_Mod, '_wx_init_'}}} ->
+ timer:sleep(50),
+ get_wx_object_state(Pid, N-1);
+ {value, {'_wx_object_', Value}} ->
+ Value;
+ _ ->
+ ignore
end;
- _ -> ignore
- end.
+ _ ->
+ ignore
+ end;
+get_wx_object_state(_, _) ->
+ ignore.
+
attach_fun(Fun, S = #state{cb=CB,cb_cnt=Next}) ->
case gb_trees:lookup(Fun,CB) of
@@ -346,25 +360,8 @@ handle_disconnect(Object, Evh = #evh{cb=Fun}, From,
State0 = #state{users=Users0, cb=Callbacks}) ->
#user{events=Evs0} = gb_trees:get(From, Users0),
FunId = gb_trees:lookup(Fun, Callbacks),
- case find_handler(Evs0, Object, Evh#evh{cb=FunId}) of
- [] ->
- {reply, false, State0};
- Handlers ->
- case disconnect(Object,Handlers) of
- #evh{} -> {reply, true, State0};
- Result -> {reply, Result, State0}
- end
- end.
-
-disconnect(Object,[Ev|Evs]) ->
- try wxEvtHandler:disconnect_impl(Object,Ev) of
- true -> Ev;
- false -> disconnect(Object, Evs);
- Error -> Error
- catch _:_ ->
- false
- end;
-disconnect(_, []) -> false.
+ Handlers = find_handler(Evs0, Object, Evh#evh{cb=FunId}),
+ {reply, {try_in_order, Handlers}, State0}.
find_handler([{Object,Evh}|Evs], Object, Match) ->
case match_handler(Match, Evh) of
diff --git a/lib/wx/src/wxe_util.erl b/lib/wx/src/wxe_util.erl
index 02ac4ddfa6..398ceddd4f 100644
--- a/lib/wx/src/wxe_util.erl
+++ b/lib/wx/src/wxe_util.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
@@ -126,8 +127,21 @@ connect_cb(Object,EvData0 = #evh{cb=Callback}) ->
disconnect_cb(Object,EvData) ->
Server = (wx:get_env())#wx_env.sv,
- gen_server:call(Server, {disconnect_cb,Object,EvData}, infinity).
-
+ {try_in_order, Handlers} =
+ gen_server:call(Server, {disconnect_cb,Object,EvData}, infinity),
+ disconnect(Object, Handlers).
+
+disconnect(Object,[Ev|Evs]) ->
+ try wxEvtHandler:disconnect_impl(Object,Ev) of
+ true -> true;
+ false -> disconnect(Object, Evs);
+ Error -> Error
+ catch _:_ ->
+ false
+ end;
+disconnect(_, []) -> false.
+
+
debug_cast(1, Op, _Args, _Port) ->
check_previous(),
case ets:lookup(wx_debug_info,Op) of
diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile
index 836885a308..136cbd5454 100644
--- a/lib/wx/test/Makefile
+++ b/lib/wx/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2008-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/wx/test/wx_app_SUITE.erl b/lib/wx/test/wx_app_SUITE.erl
index 6331180ece..2d128df433 100644
--- a/lib/wx/test/wx_app_SUITE.erl
+++ b/lib/wx/test/wx_app_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl
index e3bbb21a23..0b919f6254 100644
--- a/lib/wx/test/wx_basic_SUITE.erl
+++ b/lib/wx/test/wx_basic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
@@ -271,13 +272,19 @@ wx_misc(_Config) ->
wx:destroy().
-%% Check that all the data_types works in communication
+%% Check that all the data_types works in communication
%% between erlang and c++ thread.
data_types(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
data_types(_Config) ->
Wx = ?mr(wx_ref, wx:new()),
-
+
Frame = wxFrame:new(Wx, 1, "Data Types"),
+ wxFrame:connect(Frame, show),
+ wxFrame:show(Frame),
+ receive #wx{event=#wxShow{}} -> ok
+ after 1000 -> exit(show_timeout)
+ end,
+
CDC = wxClientDC:new(Frame),
%% From wx.erl
@@ -292,16 +299,31 @@ data_types(_Config) ->
?m(ok, wxDC:setUserScale(CDC, 123.45, 234.67)),
?m({123.45,234.67}, wxDC:getUserScale(CDC)),
+ %% Array of doubles
+ try wxGraphicsContext:create(CDC) of
+ GC ->
+ wxGraphicsContext:setFont(GC, ?wxITALIC_FONT, {0, 0, 50}),
+ Ws = wxGraphicsContext:getPartialTextExtents(GC, "a String With More Than 16 Characters"),
+ _ = lists:foldl(fun(Width, {Index, Acc}) ->
+ if Width >= Acc, Width < 500 -> {Index+1, Width};
+ true -> throw({bad_float, Width, Index, Acc})
+ end
+ end, {0,0.0}, Ws),
+ ok
+ catch _:_ -> %% GC not supported on this platform
+ ok
+ end,
+
%% Colors input is 3 or 4 tuple, returns are 4 tuples
?m(ok, wxDC:setTextForeground(CDC, {100,10,1})),
?m({100,10,1,255}, wxDC:getTextForeground(CDC)),
?m(ok, wxDC:setTextForeground(CDC, {100,10,1,43})),
?m({100,10,1,43}, wxDC:getTextForeground(CDC)),
- %% Bool
+ %% Bool
?m(ok, wxDC:setAxisOrientation(CDC, true, false)),
?m(true, is_boolean(wxDC:isOk(CDC))),
-
+
%% wxCoord
?m(true, is_integer(wxDC:maxX(CDC))),
@@ -309,13 +331,27 @@ data_types(_Config) ->
?m({_,_}, wxWindow:getSize(Frame)),
%% DateTime
- DateTime = {Date, _Time} = calendar:now_to_datetime(erlang:now()),
+ DateTime = {Date, _Time} = calendar:now_to_datetime(os:timestamp()),
io:format("DateTime ~p ~n",[DateTime]),
Cal = ?mt(wxCalendarCtrl, wxCalendarCtrl:new(Frame, ?wxID_ANY, [{date,DateTime}])),
?m({Date,_}, wxCalendarCtrl:getDate(Cal)),
?m(true, is_boolean(wxCalendarCtrl:setDate(Cal,DateTime))),
?m({Date,_}, wxCalendarCtrl:getDate(Cal)),
+ %% Images, test sending and reading binaries
+ Colors = << <<200:8, 199:8, 198:8 >> || _ <- lists:seq(1, 128*64) >>,
+ Alpha = << <<255:8>> || _ <- lists:seq(1, 128*64) >>,
+ ImgRGB = ?mt(wxImage, wxImage:new(128, 64, Colors)),
+ ?m(true, wxImage:ok(ImgRGB)),
+ ?m(false, wxImage:hasAlpha(ImgRGB)),
+ ?m(Colors, wxImage:getData(ImgRGB)),
+
+ ImgRGBA = ?mt(wxImage, wxImage:new(128, 64, Colors, Alpha)),
+ ?m(true, wxImage:ok(ImgRGBA)),
+ ?m(true, wxImage:hasAlpha(ImgRGBA)),
+ ?m(Colors, wxImage:getData(ImgRGBA)),
+ ?m(Alpha, wxImage:getAlpha(ImgRGBA)),
+
wxClientDC:destroy(CDC),
%%wx_test_lib:wx_destroy(Frame,Config).
wx:destroy().
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index b127e6b71d..876db9893f 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
@@ -71,7 +72,7 @@ calendarCtrl(Config) ->
Panel = wxPanel:new(Frame),
Sz = wxBoxSizer:new(?wxVERTICAL),
- {YMD={_,_,Day},_} = DateTime = calendar:now_to_datetime(erlang:now()),
+ {YMD={_,_,Day},_} = DateTime = calendar:now_to_datetime(os:timestamp()),
Cal = ?mt(wxCalendarCtrl, wxCalendarCtrl:new(Panel, ?wxID_ANY,
[{date,DateTime}
])),
@@ -231,8 +232,15 @@ staticBoxSizer(Config) ->
clipboard(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
-clipboard(_Config) ->
- wx:new(),
+clipboard(Config) ->
+ Wx = wx:new(),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Main Frame"),
+ Ctrl = wxTextCtrl:new(Frame, ?wxID_ANY, [{size, {600,400}}, {style, ?wxTE_MULTILINE}]),
+ wxTextCtrl:connect(Ctrl, command_text_copy, [{skip, true}]),
+ wxTextCtrl:connect(Ctrl, command_text_cut, [{skip, true}]),
+ wxTextCtrl:connect(Ctrl, command_text_paste, [{skip, true}]),
+ wxWindow:show(Frame),
+
CB = ?mt(wxClipboard, wxClipboard:get()),
wxClipboard:usePrimarySelection(CB),
?m(false, wx:is_null(CB)),
@@ -271,7 +279,8 @@ clipboard(_Config) ->
?log("Flushing ~n",[]),
wxClipboard:flush(CB),
?log("Stopping ~n",[]),
- ok.
+ wx_test_lib:wx_destroy(Frame,Config).
+
helpFrame(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
helpFrame(Config) ->
@@ -279,10 +288,13 @@ helpFrame(Config) ->
MFrame = wx:batch(fun() ->
MFrame = wxFrame:new(Wx, ?wxID_ANY, "Main Frame"),
wxPanel:new(MFrame, [{size, {600,400}}]),
+ wxFrame:connect(MFrame, show),
wxWindow:show(MFrame),
MFrame
end),
- timer:sleep(9),
+ receive #wx{event=#wxShow{}} -> ok
+ after 1000 -> exit(show_timeout)
+ end,
{X0, Y0} = wxWindow:getScreenPosition(MFrame),
{X, Y, W,H} = wxWindow:getScreenRect(MFrame),
@@ -374,13 +386,26 @@ listCtrlSort(Config) ->
io:format("Sorted ~p ~n",[Time]),
Item = wxListItem:new(),
+
+ %% Test that wx-asserts are sent to error logger
+ %% Force an assert on 3.0 (when debug compiled which it is by default)
+ wxListItem:setId(Item, 200),
+ case os:type() of
+ {win32, _} ->
+ wxListItem:setColumn(Item, 3),
+ io:format("Got ~p ~n", [wxListCtrl:insertItem(LC, Item)]),
+ wxListItem:setColumn(Item, 0);
+ _ -> %% Uses generic listctrl
+ %% we can't use the code above on linux with wx-2.8.8 because it segfaults.
+ io:format("Got ~p ~n", [wxListCtrl:getItem(LC, Item)])
+ end,
+
wxListItem:setMask(Item, ?wxLIST_MASK_TEXT),
_List = wx:map(fun(Int) ->
wxListItem:setId(Item, Int),
?m(true, wxListCtrl:getItem(LC, Item)),
io:format("~p: ~s~n",[Int, wxListItem:getText(Item)])
end, lists:seq(0,10)),
- wxListItem:destroy(Item),
wx_test_lib:wx_destroy(Frame,Config).
@@ -433,15 +458,16 @@ radioBox(Config) ->
Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
TrSortRadioBox = wxRadioBox:new(Frame, ?wxID_ANY, "Sort by:",
- {100, 100},{100, 100}, ["Timestamp"]),
+ {100, 100},{100, 100},
+ ["Timestamp", "Session", "FooBar"]),
io:format("TrSortRadioBox ~p ~n", [TrSortRadioBox]),
- %% If I uncomment any of these lines, it will crash
-
- io:format("~p~n", [catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)]),
- %?m(_, wxListBox:append(TrSortRadioBox, "Session Id", session_id)),
- %?m(_, wxListBox:insert(TrSortRadioBox, "Session Id", 0, session_id)),
-
+ wxRadioBox:setSelection(TrSortRadioBox, 2),
+ wxRadioBox:setItemToolTip(TrSortRadioBox, 2, "Test"),
+ TT0 = ?mt(wxToolTip,wxRadioBox:getItemToolTip(TrSortRadioBox, 0)),
+ TT1 = ?mt(wxToolTip,wxRadioBox:getItemToolTip(TrSortRadioBox, 2)),
+ ?m(true, wx:is_null(TT0)),
+ ?m("Test", wxToolTip:getTip(TT1)),
wxWindow:show(Frame),
wx_test_lib:wx_destroy(Frame,Config).
@@ -500,19 +526,23 @@ toolbar(Config) ->
Wx = wx:new(),
Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
TB = wxFrame:createToolBar(Frame),
- wxToolBar:addTool(TB, 747, "PressMe", wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}]),
+ BM1 = wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}, {client, "wxART_TOOLBAR"}]),
+ BM2 = wxArtProvider:getBitmap("wxART_TICK_MARK", [{size, {16,16}}, {client, "wxART_TOOLBAR"}]),
+ wxToolBar:addTool(TB, 747, "PressMe", BM1,
[{shortHelp, "Press Me"}]),
-
+ catch wxToolBar:addStretchableSpace(TB), %% wxWidgets 3.0 only
Add = fun(#wx{}, _) ->
- wxToolBar:addTool(TB, -1, "Added", wxArtProvider:getBitmap("wxART_TICK_MARK", [{size, {16,16}}]),
- [{shortHelp, "Test 2 popup text"}])
+ wxToolBar:addTool(TB, -1, "Added", BM2,
+ [{shortHelp, "Test 2 popup text"}]),
+ catch wxToolBar:addStretchableSpace(TB), %% wxWidgets 3.0 only
+ wxToolBar:realize(TB)
end,
+ wxToolBar:realize(TB),
wxFrame:connect(Frame, command_menu_selected, [{callback, Add}, {id, 747}]),
wxFrame:show(Frame),
wx_test_lib:wx_destroy(Frame,Config).
-
popup(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
popup(Config) ->
Wx = wx:new(),
@@ -522,7 +552,7 @@ popup(Config) ->
[{shortHelp, "Press Me"}]),
Log = fun(#wx{id=Id, event=Ev}, Obj) ->
- io:format("Got ~p from ~p~n", [Id, Ev]),
+ io:format("Got ~p from ~p~n", [Ev, Id]),
wxEvent:skip(Obj)
end,
CreatePopup = fun() ->
@@ -545,7 +575,11 @@ popup(Config) ->
Pop
end,
wxFrame:connect(Frame, command_menu_selected, [{id, 747}]),
+ wxFrame:connect(Frame, show),
wxFrame:show(Frame),
+ receive #wx{event=#wxShow{}} -> ok
+ after 1000 -> exit(show_timeout)
+ end,
Pop = CreatePopup(),
Scale = case wx_test_lib:user_available(Config) of
@@ -558,3 +592,32 @@ popup(Config) ->
wxPopupTransientWindow:dismiss(Pop)
end,
wx_test_lib:wx_destroy(Frame,Config).
+
+locale(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+locale(_Config) ->
+ wx:new(),
+ io:format("SystemEncoding: ~p~n",[wxLocale:getSystemEncoding()]),
+ io:format("SystemEncodingName: ~ts~n",[wxLocale:getSystemEncodingName()]),
+ io:format("SystemLanguage: ~p~n",[wxLocale:getSystemLanguage()]),
+ io:format("SystemLanguageName: ~p~n",[wxLocale:getLanguageName(wxLocale:getSystemLanguage())]),
+ lang_env(),
+ LC = wxLocale:new(),
+ %% wxLocale:addCatalog(LC, "wxstd"),
+ io:format("Swedish: ~p~n",[wxLocale:getLanguageName(?wxLANGUAGE_SWEDISH)]),
+ R0 = wxLocale:init(LC, [{language, ?wxLANGUAGE_SWEDISH}, {flags, 0}]),
+ io:format("initiated ~p~n",[R0]),
+ lang_env(),
+ ok.
+%% wx_test_lib:wx_destroy(Frame,Config).
+
+lang_env() ->
+ Env0 = os:getenv(),
+ Env = [[R,"\n"]||R <- Env0],
+ %%io:format("~p~n",[lists:sort(Env)]),
+ Opts = [global, multiline, {capture, all, list}],
+ format_env(re:run(Env, "LC_ALL.*", Opts)),
+ format_env(re:run(Env, "^LANG.*=.*$", Opts)),
+ ok.
+format_env({match, List}) ->
+ [io:format(" ~ts~n",[L]) || L <- List];
+format_env(nomatch) -> ok.
diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl
index f9f8788d8f..516133e3e2 100644
--- a/lib/wx/test/wx_event_SUITE.erl
+++ b/lib/wx/test/wx_event_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
@@ -45,8 +46,8 @@ end_per_testcase(Func,Config) ->
%% SUITE specification
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
- [connect, disconnect, connect_msg_20, connect_cb_20,
+all() ->
+ [connect, disconnect, disconnect_cb, connect_msg_20, connect_cb_20,
mouse_on_grid, spin_event, connect_in_callback, recursive,
dialog, char_events, callback_clean
].
@@ -77,7 +78,6 @@ connect(Config) ->
Tester ! {got_size, UserD}
end,
- ?m(ok, wxFrame:connect(Frame, size)),
?m(ok, wxEvtHandler:connect(Panel, size,[{skip, true},{userData, panel}])),
?m(ok, wxEvtHandler:connect(Panel, size,[{callback,CB},{userData, panel}])),
@@ -90,12 +90,16 @@ connect(Config) ->
?m(ok, wxWindow:connect(Window, size,[{callback,CB},{userData, window}])),
?m(ok, wxWindow:connect(Window, size,[{skip,true},{userData, window}])),
+ %% For trivial side effect free callbacks, can deadlock easily otherwise
+ CB1 = fun(_,_) -> Tester ! {got_size, nospawn_cb} end,
+ ?m(ok, wxWindow:connect(Frame, size, [{callback,{nospawn, CB1}}])),
+ ?m(ok, wxFrame:connect(Frame, size, [{skip, true}])),
?m(true, wxFrame:show(Frame)),
wxWindow:setSize(Panel, {200,100}),
wxWindow:setSize(Window, {200,100}),
- get_size_messages(Frame, [frame, panel_cb, window_cb, window]),
+ get_size_messages(Frame, [frame, panel_cb, window_cb, window, nospawn_cb]),
wx_test_lib:wx_destroy(Frame, Config).
@@ -114,7 +118,9 @@ get_size_messages(Frame, Msgs) ->
?m(false, lists:member(window, Msgs)),
get_size_messages(Frame, lists:delete(window_cb, Msgs));
{got_size,panel} ->
- get_size_messages(Frame, lists:delete(panel_cb, Msgs));
+ get_size_messages(Frame, lists:delete(panel_cb, Msgs));
+ {got_size,nospawn_cb} ->
+ get_size_messages(Frame, lists:delete(nospawn_cb, Msgs));
Other ->
?error("Got unexpected msg ~p ~p~n", [Other,Msgs])
after 1000 ->
@@ -156,9 +162,33 @@ disconnect(Config) ->
?m([], wx_test_lib:flush()),
wx_test_lib:wx_destroy(Frame, Config).
-
+
+disconnect_cb(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+disconnect_cb(Config) ->
+ ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(wx:null(), 1, "Event Testing")),
+ Panel = ?mt(wxPanel, wxPanel:new(Frame)),
+
+ Tester = self(),
+ CB = fun(#wx{event=#wxSize{},userData=UserD}, SizeEvent) ->
+ ?mt(wxSizeEvent, SizeEvent),
+ wxEvtHandler:disconnect(Frame, close_window),
+ Tester ! {got_size, UserD}
+ end,
+ ?m(ok, wxFrame:connect(Frame, close_window)),
+ ?m(ok, wxFrame:connect(Frame, size)),
+ ?m(ok, wxEvtHandler:connect(Panel, size, [{callback,CB},{userData, panel}])),
+
+ ?m(true, wxFrame:show(Frame)),
+
+ wxWindow:setSize(Panel, {200,100}),
+ get_size_messages(Frame, [frame, panel_cb]),
+ wx_test_lib:flush(),
+
+ wx_test_lib:wx_destroy(Frame, Config).
+
%% Test that the msg events are forwarded as supposed to
connect_msg_20(TestInfo)
when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
@@ -379,25 +409,29 @@ recursive(Config) ->
Frame = wxFrame:new(Wx, ?wxID_ANY, "Connect in callback"),
Panel = wxPanel:new(Frame, []),
Sz = wxBoxSizer:new(?wxVERTICAL),
- ListBox = wxListBox:new(Panel, ?wxID_ANY, [{choices, ["foo", "bar", "baz"]}]),
- wxSizer:add(Sz, ListBox, [{proportion, 1},{flag, ?wxEXPAND}]),
- wxWindow:setSizer(Panel, Sz),
- wxListBox:connect(ListBox, command_listbox_selected,
- [{callback,
- fun(#wx{event=#wxCommand{commandInt=Id}}, _) ->
- io:format("Selected ~p~n",[Id])
- end}]),
- wxListBox:setSelection(ListBox, 0),
- wxListBox:connect(ListBox, size,
- [{callback,
- fun(#wx{event=#wxSize{}}, _) ->
- io:format("Size init ~n",[]),
- case wxListBox:getCount(ListBox) > 0 of
- true -> wxListBox:delete(ListBox, 0);
- false -> ok
- end,
- io:format("Size done ~n",[])
- end}]),
+ Ctrl1 = wxTextCtrl:new(Panel, ?wxID_ANY, [{size, {300, -1}}]),
+ Ctrl2 = wxTextCtrl:new(Panel, ?wxID_ANY, [{size, {300, -1}}]),
+ wxSizer:add(Sz, Ctrl1, [{proportion, 1},{flag, ?wxEXPAND}]),
+ wxSizer:add(Sz, Ctrl2, [{proportion, 1},{flag, ?wxEXPAND}]),
+ wxWindow:setSizerAndFit(Panel, Sz),
+
+ CB1 = fun(#wx{event=#wxCommand{cmdString=String}}, _) ->
+ io:format(" CB1: ~s~n",[String]),
+ wxTextCtrl:setValue(Ctrl2, io_lib:format("from CB1 ~s", [String]))
+ end,
+ CB2 = fun(#wx{event=#wxCommand{cmdString=String}}, _) ->
+ io:format(" CB2: ~s~n",[String]),
+ ok
+ end,
+ wxTextCtrl:connect(Ctrl1, command_text_updated, [{callback,CB1}]),
+ wxTextCtrl:connect(Ctrl2, command_text_updated, [{callback,CB2}]),
+ wxFrame:connect(Frame, size,
+ [{callback,
+ fun(#wx{event=#wxSize{size=Size}}, _) ->
+ io:format("Size init: ~s ~n",[wxTextCtrl:getValue(Ctrl2)]),
+ wxTextCtrl:setValue(Ctrl1, io_lib:format("Size ~p", [Size])),
+ io:format("Size done: ~s ~n",[wxTextCtrl:getValue(Ctrl2)])
+ end}]),
wxFrame:show(Frame),
wx_test_lib:flush(),
@@ -544,13 +578,14 @@ handler_clean(_Config) ->
?mt(wxFrame, Frame1),
wxWindow:show(Frame1),
?m([_|_], lists:sort(wx_test_lib:flush())),
- ?m({stop,_}, wx_obj_test:stop(Frame1, fun(_) -> normal end)),
+ ?m(ok, wx_obj_test:stop(Frame1)),
?m([{terminate,normal}], lists:sort(wx_test_lib:flush())),
- Frame2 = wx_obj_test:start([{init, Init}]),
+ Terminate = fun({Frame,_}) -> wxWindow:destroy(Frame) end,
+ Frame2 = wx_obj_test:start([{init, Init}, {terminate, Terminate}]),
wxWindow:show(Frame2),
?m([_|_], lists:sort(wx_test_lib:flush())),
- ?m({stop,_}, wx_obj_test:stop(Frame2, fun(_) -> wxWindow:destroy(Frame2), normal end)),
+ ?m(ok, wx_obj_test:stop(Frame2)),
?m([{terminate,normal}], lists:sort(wx_test_lib:flush())),
timer:sleep(104),
?m({[],[],[]}, white_box_check_event_handlers()),
diff --git a/lib/wx/test/wx_obj_test.erl b/lib/wx/test/wx_obj_test.erl
index f47f2fbc46..068e59f243 100644
--- a/lib/wx/test/wx_obj_test.erl
+++ b/lib/wx/test/wx_obj_test.erl
@@ -1,24 +1,25 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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(wx_obj_test).
-include_lib("wx/include/wx.hrl").
--export([start/1, stop/2]).
+-export([start/1, stop/1]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -29,8 +30,8 @@
start(Opts) ->
wx_object:start_link(?MODULE, [{parent, self()}| Opts], []).
-stop(Object, Fun) ->
- wx_object:call(Object, {stop, Fun}).
+stop(Object) ->
+ wx_object:stop(Object).
init(Opts) ->
Parent = proplists:get_value(parent, Opts),
@@ -61,8 +62,6 @@ handle_event(Event, State = #state{parent=Parent}) ->
handle_call(What, From, State = #state{user_state=US}) when is_function(What) ->
Result = What(US),
{reply, {call, Result, From}, State};
-handle_call({stop, Fun}, From, State = #state{user_state=US}) ->
- {stop, Fun(US), {stop, From}, State};
handle_call(What, From, State) ->
{reply, {call, What, From}, State}.
@@ -79,7 +78,13 @@ handle_info(What, State = #state{parent=Pid}) ->
Pid ! {info, What},
{noreply, State}.
-terminate(What, #state{parent=Pid}) ->
+terminate(What, #state{parent=Pid, opts=Opts, user_state=US}) ->
+ case proplists:get_value(terminate, Opts) of
+ undefined ->
+ ok;
+ Terminate ->
+ Terminate(US)
+ end,
Pid ! {terminate, What},
ok.
diff --git a/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl
index f351bc93ed..5d6da4240d 100644
--- a/lib/wx/test/wx_opengl_SUITE.erl
+++ b/lib/wx/test/wx_opengl_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/test/wx_test_lib.erl b/lib/wx/test/wx_test_lib.erl
index 9b65a50864..423e371fbb 100644
--- a/lib/wx/test/wx_test_lib.erl
+++ b/lib/wx/test/wx_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/test/wx_test_lib.hrl b/lib/wx/test/wx_test_lib.hrl
index 820e8f0050..d7ca98629a 100644
--- a/lib/wx/test/wx_test_lib.hrl
+++ b/lib/wx/test/wx_test_lib.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/test/wx_xtra_SUITE.erl b/lib/wx/test/wx_xtra_SUITE.erl
index 8d5d7ddb6a..42f4fe53f6 100644
--- a/lib/wx/test/wx_xtra_SUITE.erl
+++ b/lib/wx/test/wx_xtra_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/test/wxt b/lib/wx/test/wxt
index f94350e47b..700c0a432b 100755
--- a/lib/wx/test/wxt
+++ b/lib/wx/test/wxt
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2008-2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
@@ -38,4 +39,4 @@ if [ "$ostype" = "SunOS" ] ; then
else
xterm -T Testing -e script -f -c "$erlcmd" "$log" &
fi
-tail -f "$log" | egrep 'Eval|<ERROR>|NYI' \ No newline at end of file
+tail -f "$log" | egrep 'Eval|<ERROR>|NYI'
diff --git a/lib/wx/test/wxt.erl b/lib/wx/test/wxt.erl
index c14d3f8647..57529d4876 100644
--- a/lib/wx/test/wxt.erl
+++ b/lib/wx/test/wxt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index 942d4c0d6f..de723b2a2d 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 1.3.3
+WX_VSN = 1.6.1
diff --git a/lib/xmerl/Makefile b/lib/xmerl/Makefile
index dca910444b..a584aacbac 100644
--- a/lib/xmerl/Makefile
+++ b/lib/xmerl/Makefile
@@ -3,16 +3,17 @@
# <holder>Ericsson AB, All Rights Reserved</holder>
#</copyright>
#<legalnotice>
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# The Initial Developer of the Original Code is Ericsson AB.
#</legalnotice>
diff --git a/lib/xmerl/doc/examples/test_html.erl b/lib/xmerl/doc/examples/test_html.erl
index 3ca15f30f8..cb8088833c 100644
--- a/lib/xmerl/doc/examples/test_html.erl
+++ b/lib/xmerl/doc/examples/test_html.erl
@@ -1,12 +1,14 @@
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.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.erlang.org/license/EPL1_0.txt
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% 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.
%%%
%%% The Original Code is xmerl-0.7
%%%
diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile
index 6f95e30a28..5c39355278 100644
--- a/lib/xmerl/doc/src/Makefile
+++ b/lib/xmerl/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/xmerl/doc/src/book.xml b/lib/xmerl/doc/src/book.xml
index 128a870628..012a62c505 100644
--- a/lib/xmerl/doc/src/book.xml
+++ b/lib/xmerl/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 3fa1f01a79..55367eb25e 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,6 +32,50 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.3.10</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Suppress Dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-12862</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Xmerl 1.3.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Removed the built-in definitions of xml.xsd from the
+ xmerl_xsd module.</p>
+ <p>
+ Own Id: OTP-13070</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Xmerl 1.3.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Remove compiler warnings in xmerl. </p>
+ <p>
+ Own Id: OTP-12689</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Xmerl 1.3.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/xmerl/doc/src/notes_history.xml b/lib/xmerl/doc/src/notes_history.xml
index 6afd07fa56..02d420c849 100644
--- a/lib/xmerl/doc/src/notes_history.xml
+++ b/lib/xmerl/doc/src/notes_history.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/xmerl/doc/src/part.xml b/lib/xmerl/doc/src/part.xml
index 3567fe4a21..e672bdc3f2 100644
--- a/lib/xmerl/doc/src/part.xml
+++ b/lib/xmerl/doc/src/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/xmerl/doc/src/part_notes.xml b/lib/xmerl/doc/src/part_notes.xml
index ace667deb9..a7c89ec560 100644
--- a/lib/xmerl/doc/src/part_notes.xml
+++ b/lib/xmerl/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/xmerl/doc/src/ref_man.xml b/lib/xmerl/doc/src/ref_man.xml
index db35552845..8805f04fbc 100644
--- a/lib/xmerl/doc/src/ref_man.xml
+++ b/lib/xmerl/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/xmerl/doc/src/xmerl_sax_parser.xml b/lib/xmerl/doc/src/xmerl_sax_parser.xml
index 4af55066eb..2251be00bb 100644
--- a/lib/xmerl/doc/src/xmerl_sax_parser.xml
+++ b/lib/xmerl/doc/src/xmerl_sax_parser.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/lib/xmerl/doc/src/xmerl_ug.xmlsrc b/lib/xmerl/doc/src/xmerl_ug.xmlsrc
index aa60c65417..5d1408b54c 100644
--- a/lib/xmerl/doc/src/xmerl_ug.xmlsrc
+++ b/lib/xmerl/doc/src/xmerl_ug.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/lib/xmerl/include/xmerl.hrl b/lib/xmerl/include/xmerl.hrl
index 331d1507a0..7d37241116 100644
--- a/lib/xmerl/include/xmerl.hrl
+++ b/lib/xmerl/include/xmerl.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/include/xmerl_xpath.hrl b/lib/xmerl/include/xmerl_xpath.hrl
index fc4eeb3c66..e5d697eea5 100644
--- a/lib/xmerl/include/xmerl_xpath.hrl
+++ b/lib/xmerl/include/xmerl_xpath.hrl
@@ -1,12 +1,14 @@
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.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.erlang.org/license/EPL1_0.txt
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% 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.
%%%
%%% The Original Code is xmerl-0.19
%%%
diff --git a/lib/xmerl/include/xmerl_xsd.hrl b/lib/xmerl/include/xmerl_xsd.hrl
index 644cc2e433..e3ee8efd40 100644
--- a/lib/xmerl/include/xmerl_xsd.hrl
+++ b/lib/xmerl/include/xmerl_xsd.hrl
@@ -1,12 +1,14 @@
-%%% The contents of this file are subject to the Erlang Public License,
-%%% Version 1.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.erlang.org/license/EPL1_0.txt
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
%%%
-%%% Software distributed under the License is distributed on an "AS IS"
-%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%%% the License for the specific language governing rights and limitations
-%%% under the License.
+%%% 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.
%%%
%%%
%%% The Initial Developer of the Original Code is Ericsson Telecom
diff --git a/lib/xmerl/src/Makefile b/lib/xmerl/src/Makefile
index d5ce3fe6ff..f8f0320f46 100644
--- a/lib/xmerl/src/Makefile
+++ b/lib/xmerl/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/lib/xmerl/src/xmerl.app.src b/lib/xmerl/src/xmerl.app.src
index 45cfe9d250..aed9cf176f 100644
--- a/lib/xmerl/src/xmerl.app.src
+++ b/lib/xmerl/src/xmerl.app.src
@@ -40,5 +40,5 @@
{registered, []},
{env, []},
{applications, [kernel, stdlib]},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}
+ {runtime_dependencies, ["stdlib-2.5","kernel-3.0","erts-6.0"]}
]}.
diff --git a/lib/xmerl/src/xmerl.appup.src b/lib/xmerl/src/xmerl.appup.src
index 0a84966576..388e4d8a86 100644
--- a/lib/xmerl/src/xmerl.appup.src
+++ b/lib/xmerl/src/xmerl.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
{"%VSN%",
diff --git a/lib/xmerl/src/xmerl.erl b/lib/xmerl/src/xmerl.erl
index 01af183eef..7c8c6c56f4 100644
--- a/lib/xmerl/src/xmerl.erl
+++ b/lib/xmerl/src/xmerl.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -40,6 +41,7 @@
callbacks/1]).
-include("xmerl.hrl").
+-include("xmerl_internal.hrl").
%% @spec export(Content, Callback) -> ExportedFormat
@@ -273,7 +275,7 @@ tagdef(Tag,Pos,Parents,Args,CBs) ->
callbacks(Module) ->
Result = check_inheritance(Module, []),
-%%% io:format("callbacks = ~p~n", [lists:reverse(Result)]),
+%%% ?dbg("callbacks = ~p~n", [lists:reverse(Result)]),
lists:reverse(Result).
callbacks([M|Mods], Visited) ->
@@ -288,7 +290,7 @@ callbacks([], Visited) ->
Visited.
check_inheritance(M, Visited) ->
-%%% io:format("calling ~p:'#xml-inheritance#'()~n", [M]),
+%%% ?dbg("calling ~p:'#xml-inheritance#'()~n", [M]),
case M:'#xml-inheritance#'() of
[] ->
[M|Visited];
@@ -313,7 +315,7 @@ apply_cb([M|Ms], F, Df, Args, A, Ms0) ->
true -> apply(M, F, Args);
false -> apply_cb(Ms, F, Df, Args, A, Ms0)
end;
-apply_cb([], Df, Df, Args, A, _Ms0) ->
+apply_cb([], Df, Df, Args, _A, _Ms0) ->
exit({unknown_tag, {Df, Args}});
apply_cb([], F, Df, Args, A, Ms0) ->
apply_cb(Ms0, Df, Df, [F|Args], A+1).
diff --git a/lib/xmerl/src/xmerl_b64Bin.yrl b/lib/xmerl/src/xmerl_b64Bin.yrl
index 2d94ea30e2..46cf23ef34 100644
--- a/lib/xmerl/src/xmerl_b64Bin.yrl
+++ b/lib/xmerl/src/xmerl_b64Bin.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_b64Bin_scan.erl b/lib/xmerl/src/xmerl_b64Bin_scan.erl
index 6f40680547..50ac5c05c2 100644
--- a/lib/xmerl/src/xmerl_b64Bin_scan.erl
+++ b/lib/xmerl/src/xmerl_b64Bin_scan.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_eventp.erl b/lib/xmerl/src/xmerl_eventp.erl
index ad5c3cbc47..243f47f159 100644
--- a/lib/xmerl/src/xmerl_eventp.erl
+++ b/lib/xmerl/src/xmerl_eventp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -80,17 +81,17 @@ stream_sax(Fname, CallBack, UserState,Options) ->
HookF=
fun(ParsedEntity, S) ->
{CBs,Arg}=xmerl_scan:user_state(S),
-% io:format("stream_sax Arg=~p~n",[Arg]),
+% ?dbg("stream_sax Arg=~p~n",[Arg]),
case ParsedEntity of
#xmlComment{} -> % Toss away comments...
{[],S};
_ -> % Use callback module for the rest
-% io:format("stream_sax ParsedEntity=~p~n",[ParsedEntity]),
+% ?dbg("stream_sax ParsedEntity=~p~n",[ParsedEntity]),
case xmerl:export_element(ParsedEntity,CBs,Arg) of
{error,Reason} ->
throw({error,Reason});
Resp ->
-% io:format("stream_sax Resp=~p~n",[Resp]),
+% ?dbg("stream_sax Resp=~p~n",[Resp]),
{Resp,xmerl_scan:user_state({CBs,Resp},S)}
end
end
diff --git a/lib/xmerl/src/xmerl_html.erl b/lib/xmerl/src/xmerl_html.erl
index 38fdeb2205..1c38ed111a 100644
--- a/lib/xmerl/src/xmerl_html.erl
+++ b/lib/xmerl/src/xmerl_html.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_internal.hrl b/lib/xmerl/src/xmerl_internal.hrl
index 85df757138..cbdfa4f673 100644
--- a/lib/xmerl/src/xmerl_internal.hrl
+++ b/lib/xmerl/src/xmerl_internal.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_lib.erl b/lib/xmerl/src/xmerl_lib.erl
index aeb821f411..a2d6a88c18 100644
--- a/lib/xmerl/src/xmerl_lib.erl
+++ b/lib/xmerl/src/xmerl_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_otpsgml.erl b/lib/xmerl/src/xmerl_otpsgml.erl
index 38688e788f..bd6ac33997 100644
--- a/lib/xmerl/src/xmerl_otpsgml.erl
+++ b/lib/xmerl/src/xmerl_otpsgml.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -34,6 +35,7 @@
export_text/1]).
-include("xmerl.hrl").
+-include("xmerl_internal.hrl").
'#xml-inheritance#'() -> [xmerl_sgml].
@@ -58,7 +60,7 @@
%% the scope of a markup is not extended by mistake.)
'#element#'(Tag, Data, Attrs, _Parents, _E) ->
-% io:format("parents:\n~p\n",[_Parents]),
+% ?dbg("parents:\n~p\n",[_Parents]),
case convert_tag(Tag,Attrs) of
{false,NewTag,NewAttrs} ->
markup(NewTag, NewAttrs, Data);
@@ -108,7 +110,7 @@ convert_aref([#xmlAttribute{name = href, value = V}|_Rest]) ->
seealso
end;
convert_aref([#xmlAttribute{name = K}|Rest]) ->
- io:format("Warning: ignoring attribute \'~p\' for tag \'a\'\n",[K]),
+ error_logger:warning_msg("ignoring attribute \'~p\' for tag \'a\'\n",[K]),
convert_aref(Rest).
convert_aref_attrs(url,Attrs) ->
Attrs;
@@ -130,7 +132,7 @@ html_content([_H|T]) ->
% convert_seealso_attrs([#xmlAttribute{name = href, value = V} = A|Rest]) ->
% [A#xmlAttribute{name=marker,value=normalize_web_ref(V)}|convert_seealso_attrs(Rest)];
% convert_seealso_attrs([#xmlAttribute{name = K}|Rest]) ->
-% io:format("Warning: ignoring attribute \'~p\' for tag \'a\'\n",[K]),
+% error_logger:warning_msg("ignoring attribute \'~p\' for tag \'a\'\n",[K]),
% convert_seealso_attrs(Rest);
% convert_seealso_attrs([]) ->
% [].
diff --git a/lib/xmerl/src/xmerl_regexp.erl b/lib/xmerl/src/xmerl_regexp.erl
index 9303bdb125..2b4696f8d2 100644
--- a/lib/xmerl/src/xmerl_regexp.erl
+++ b/lib/xmerl/src/xmerl_regexp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -41,6 +42,8 @@
-export([setup/1,compile_proc/2]).
+-include("xmerl_internal.hrl").
+
setup(RE0) ->
RE = setup(RE0, [$^]),
Pid = spawn(?MODULE,compile_proc,[self(),RE]),
@@ -844,7 +847,7 @@ parse_error(E) -> throw({error,E}).
re_apply(S, St, {RE,Sc}) ->
Subs = erlang:make_tuple(Sc, none), %Make a sub-regexp table.
Res = re_apply(RE, [], S, St, Subs),
- %% io:format("~p x ~p -> ~p\n", [RE,S,Res]),
+ %% ?dbg("~p x ~p -> ~p\n", [RE,S,Res]),
Res.
re_apply(epsilon, More, S, P, Subs) -> %This always matches
@@ -900,7 +903,7 @@ re_apply({comp_class,Cc}, More, [C|S], P, Subs) ->
re_apply(C, More, [C|S], P, Subs) when is_integer(C) ->
re_apply_more(More, S, P+1, Subs);
re_apply(_RE, _More, _S, _P, _Subs) ->
- %% io:format("~p : ~p\n", [_RE,_S]),
+ %% ?dbg("~p : ~p\n", [_RE,_S]),
nomatch.
%% re_apply_more([RegExp], String, Length, SubsExprs) ->
@@ -1121,7 +1124,7 @@ build_nfa(C, N, S, NFA) when is_integer(C) ->
nfa_char_class(Cc) ->
Crs = lists:foldl(fun({C1,C2}, Set) -> add_element({C1,C2}, Set);
(C, Set) -> add_element({C,C}, Set) end, [], Cc),
- %% io:fwrite("cc: ~p\n", [Crs]),
+ %% ?dbg("cc: ~p\n", [Crs]),
pack_crs(Crs).
pack_crs([{C1,C2}=Cr,{C3,C4}|Crs]) when C1 =< C3, C2 >= C4 ->
@@ -1141,7 +1144,7 @@ pack_crs([]) -> [].
nfa_comp_class(Cc) ->
Crs = nfa_char_class(Cc),
- %% io:fwrite("comp: ~p\n", [Crs]),
+ %% ?dbg("comp: ~p\n", [Crs]),
comp_crs(Crs, 0).
comp_crs([{C1,C2}|Crs], Last) ->
@@ -1192,7 +1195,7 @@ build_dfa(Set, Us, N, Ts, Ms, NFA) ->
Crs1 = lists:usort(Crs0), %Must remove duplicates!
%% Build list of disjoint test ranges.
Test = disjoint_crs(Crs1),
- %% io:fwrite("bd: ~p\n ~p\n ~p\n ~p\n", [Set,Crs0,Crs1,Test]),
+ %% ?dbg("bd: ~p\n ~p\n ~p\n ~p\n", [Set,Crs0,Crs1,Test]),
build_dfa(Test, Set, Us, N, Ts, Ms, NFA).
%% disjoint_crs([CharRange]) -> [CharRange].
@@ -1263,7 +1266,7 @@ move(Sts, Cr, NFA) ->
{Crs,St} <- (element(N, NFA))#nfa_state.edges,
is_list(Crs),
%% begin
-%% io:fwrite("move1: ~p\n", [{Sts,Cr,Crs,in_crs(Cr,Crs)}]),
+%% ?dbg("move1: ~p\n", [{Sts,Cr,Crs,in_crs(Cr,Crs)}]),
%% true
%% end,
in_crs(Cr, Crs) ].
@@ -1413,7 +1416,7 @@ build_trans(Ts0, NoAccept) ->
%% Have transitions, convert to tuple.
Ts2 = keysort(1, Ts1),
{Tmin,Smin,Ts3} = min_trans(Ts2, NoAccept),
- %% io:fwrite("exptr: ~p\n", [{Ts3,Tmin}]),
+ %% ?dbg("exptr: ~p\n", [{Ts3,Tmin}]),
{Trans,Tmax,Smax} = expand_trans(Ts3, Tmin, NoAccept),
{list_to_tuple(Trans),Tmin,Smin,Tmax,Smax,Sp1}
end.
diff --git a/lib/xmerl/src/xmerl_sax_old_dom.erl b/lib/xmerl/src/xmerl_sax_old_dom.erl
index c357816a1e..2a1e5f6df8 100644
--- a/lib/xmerl/src/xmerl_sax_old_dom.erl
+++ b/lib/xmerl/src/xmerl_sax_old_dom.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
@@ -28,6 +29,7 @@
%% Include files
%%----------------------------------------------------------------------
-include("xmerl_sax_old_dom.hrl").
+-include("xmerl_internal.hrl").
%%----------------------------------------------------------------------
%% External exports
@@ -126,7 +128,7 @@ build_dom(endDocument,
content=lists:reverse(C)
}]};
_ ->
- io:format("~p\n", [D]),
+ %%?dbg("~p\n", [D]),
?error("we're not at end the document when endDocument event is encountered.")
end;
diff --git a/lib/xmerl/src/xmerl_sax_old_dom.hrl b/lib/xmerl/src/xmerl_sax_old_dom.hrl
index 92000f8d7f..04c9253e83 100644
--- a/lib/xmerl/src/xmerl_sax_old_dom.hrl
+++ b/lib/xmerl/src/xmerl_sax_old_dom.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%% Contributor(s):
diff --git a/lib/xmerl/src/xmerl_sax_parser.erl b/lib/xmerl/src/xmerl_sax_parser.erl
index ad71072d95..6924db6c15 100644
--- a/lib/xmerl/src/xmerl_sax_parser.erl
+++ b/lib/xmerl/src/xmerl_sax_parser.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_parser.hrl b/lib/xmerl/src/xmerl_sax_parser.hrl
index b433dd6cf9..e7067e7629 100644
--- a/lib/xmerl/src/xmerl_sax_parser.hrl
+++ b/lib/xmerl/src/xmerl_sax_parser.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
index e198f2fef5..2c5caab07b 100644
--- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
@@ -151,6 +152,7 @@ parse_document(Rest, State) when is_record(State, xmerl_sax_parser_state) ->
%% [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
%% [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
%%----------------------------------------------------------------------
+-dialyzer({[no_fail_call, no_match], parse_xml_decl/2}).
parse_xml_decl(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_xml_decl/2);
parse_xml_decl(?BYTE_ORDER_MARK_1, State) ->
@@ -1204,6 +1206,7 @@ send_character_event(_, true, String, State) ->
%% Description: Parse whitespaces.
%% [3] S ::= (#x20 | #x9 | #xD | #xA)+
%%----------------------------------------------------------------------
+-dialyzer({no_fail_call, whitespace/3}).
whitespace(?STRING_EMPTY, State, Acc) ->
case cf(?STRING_EMPTY, State, Acc, fun whitespace/3) of
{?STRING_EMPTY, State} ->
@@ -1715,6 +1718,7 @@ handle_external_entity({Tag, _Url}, State) ->
%% Result : {Rest, State}
%% Description: Parse the external entity.
%%----------------------------------------------------------------------
+-dialyzer({[no_fail_call, no_match], parse_external_entity_1/2}).
parse_external_entity_1(?STRING_EMPTY, #xmerl_sax_parser_state{file_type=Type} = State) ->
case catch cf(?STRING_EMPTY, State, fun parse_external_entity_1/2) of
{Rest, State1} when is_record(State1, xmerl_sax_parser_state) ->
diff --git a/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc b/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc
index f27758069d..3361ae837c 100644
--- a/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_parser_list.erlsrc b/lib/xmerl/src/xmerl_sax_parser_list.erlsrc
index 26fec41cb9..ce0fdc4e7b 100644
--- a/lib/xmerl/src/xmerl_sax_parser_list.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_list.erlsrc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc b/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc
index 5c995a5a9c..8b1d36eae3 100644
--- a/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc b/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc
index 5c6ca0caba..63cfa11bf4 100644
--- a/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc b/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc
index 542aca5a3a..b827086a2e 100644
--- a/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/src/xmerl_sax_simple_dom.erl b/lib/xmerl/src/xmerl_sax_simple_dom.erl
index 58a11f70fe..2ce2f03827 100644
--- a/lib/xmerl/src/xmerl_sax_simple_dom.erl
+++ b/lib/xmerl/src/xmerl_sax_simple_dom.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
@@ -28,6 +29,7 @@
%% Include files
%%----------------------------------------------------------------------
-include("xmerl_sax_old_dom.hrl").
+-include("xmerl_internal.hrl").
%%----------------------------------------------------------------------
%% External exports
@@ -127,7 +129,7 @@ build_dom(endDocument,
State#xmerl_sax_simple_dom_state{dom=[Decl, {Tag, Attributes,
lists:reverse(Content)}]};
_ ->
- io:format("~p\n", [D]),
+ ?dbg("~p\n", [D]),
?error("we're not at end the document when endDocument event is encountered.")
end;
diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl
index 8dfbc2b89e..829716dcdb 100644
--- a/lib/xmerl/src/xmerl_scan.erl
+++ b/lib/xmerl/src/xmerl_scan.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -147,7 +148,8 @@
S#xmerl_scanner.quiet ->
ok;
true ->
- ok=io:format("~p- fatal: ~p~n", [?LINE, Reason])
+ error_logger:error_msg("~p- fatal: ~p~n", [?LINE, Reason]),
+ ok
end,
fatal(Reason, S)).
@@ -255,7 +257,7 @@ file(F, Options) ->
end.
int_file(F, Options,_ExtCharset) ->
- %%io:format("int_file F=~p~n",[F]),
+ %%?dbg("int_file F=~p~n",[F]),
case file:read_file(F) of
{ok, Bin} ->
int_string(binary_to_list(Bin), Options, filename:dirname(F),F);
@@ -264,7 +266,7 @@ int_file(F, Options,_ExtCharset) ->
end.
int_file_decl(F, Options,_ExtCharset) ->
-% io:format("int_file_decl F=~p~n",[F]),
+% ?dbg("int_file_decl F=~p~n",[F]),
case file:read_file(F) of
{ok, Bin} ->
int_string_decl(binary_to_list(Bin), Options, filename:dirname(F),F);
@@ -294,7 +296,7 @@ int_string(Str, Options,FileName) ->
int_string(Str, Options, XMLBase, FileName) ->
S0=initial_state0(Options,XMLBase),
S = S0#xmerl_scanner{filename=FileName},
- %%io:format("int_string1, calling xmerl_lib:detect_charset~n",[]),
+ %%?dbg("int_string1, calling xmerl_lib:detect_charset~n",[]),
%% In case of no encoding attribute in document utf-8 is default, but
%% another character set may be detected with help of Byte Order Marker or
@@ -559,20 +561,20 @@ scan_document(Str0, S=#xmerl_scanner{event_fun = Event,
Str0
end,
%% M1 = erlang:memory(),
-%% io:format("Memory status before prolog: ~p~n",[M1]),
+%% ?dbg("Memory status before prolog: ~p~n",[M1]),
{Prolog, Pos, T1, S2} = scan_prolog(Str, S1, _StartPos = 1),
%% M2 = erlang:memory(),
-%% io:format("Memory status after prolog: ~p~n",[M2]),
- %%io:format("scan_document 2, prolog parsed~n",[]),
+%% ?dbg("Memory status after prolog: ~p~n",[M2]),
+ %%?dbg("scan_document 2, prolog parsed~n",[]),
T2 = scan_mandatory("<", T1, 1, S2, expected_element_start_tag),
%% M3 = erlang:memory(),
-%% io:format("Memory status before element: ~p~n",[M3]),
+%% ?dbg("Memory status before element: ~p~n",[M3]),
{Res, T3, S3} = scan_element(T2,S2,Pos),
%% M4 = erlang:memory(),
-%% io:format("Memory status after element: ~p~n",[M4]),
+%% ?dbg("Memory status after element: ~p~n",[M4]),
{Misc, _Pos1, Tail, S4}=scan_misc(T3, S3, Pos + 1),
%% M5 = erlang:memory(),
-%% io:format("Memory status after misc: ~p~n",[M5]),
+%% ?dbg("Memory status after misc: ~p~n",[M5]),
S5 = #xmerl_scanner{} = Event(#xmerl_event{event = ended,
line = S4#xmerl_scanner.line,
@@ -604,7 +606,7 @@ scan_document(Str0, S=#xmerl_scanner{event_fun = Event,
case schemaLocations(Res, S5) of
{ok, Schemas} ->
cleanup(S5),
- %%io:format("Schemas: ~p~nRes: ~p~ninhertih_options(S): ~p~n",
+ %%?dbg("Schemas: ~p~nRes: ~p~ninhertih_options(S): ~p~n",
%% [Schemas,Res,inherit_options(S5)]),
XSDRes = xmerl_xsd:process_validate(Schemas, Res,
inherit_options(S5)),
@@ -1008,7 +1010,7 @@ scan_optional_version(T,S) ->
scan_enc_name([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_enc_name(MoreBytes, S1) end,
- fun(S1) -> ?fatal(expected_encoding_name, S1) end,
+ fatal_fun(expected_encoding_name),
S);
scan_enc_name([H|T], S0) when H >= $"; H =< $' ->
?bump_col(1),
@@ -1018,7 +1020,7 @@ scan_enc_name([H|T], S0) when H >= $"; H =< $' ->
scan_enc_name([], S=#xmerl_scanner{continuation_fun = F}, Delim, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_enc_name(MoreBytes, S1, Delim, Acc) end,
- fun(S1) -> ?fatal(expected_encoding_name, S1) end,
+ fatal_fun(expected_encoding_name),
S);
scan_enc_name([H|T], S0, Delim, Acc) when H >= $a, H =< $z ->
?bump_col(1),
@@ -1032,7 +1034,7 @@ scan_enc_name([H|_T],S,_Delim,_Acc) ->
scan_enc_name2([], S=#xmerl_scanner{continuation_fun = F}, Delim, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_enc_name2(MoreBytes, S1, Delim, Acc) end,
- fun(S1) -> ?fatal(expected_encoding_name, S1) end,
+ fatal_fun(expected_encoding_name),
S);
scan_enc_name2([H|T], S0, H, Acc) ->
?bump_col(1),
@@ -1056,7 +1058,7 @@ scan_enc_name2([H|T], S0, Delim, Acc) when H == $.; H == $_; H == $- ->
scan_xml_vsn([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_xml_vsn(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_xml_vsn([H|T], S) when H==$"; H==$'->
xml_vsn(T, S#xmerl_scanner{col = S#xmerl_scanner.col+1}, H, []).
@@ -1064,7 +1066,7 @@ scan_xml_vsn([H|T], S) when H==$"; H==$'->
xml_vsn([], S=#xmerl_scanner{continuation_fun = F}, Delim, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> xml_vsn(MoreBytes, S1, Delim, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
xml_vsn([H|T], S=#xmerl_scanner{col = C}, H, Acc) ->
{lists:reverse(Acc), T, S#xmerl_scanner{col = C+1}};
@@ -1087,7 +1089,7 @@ xml_vsn([H|T], S=#xmerl_scanner{col = C}, Delim, Acc) ->
scan_pi([], S=#xmerl_scanner{continuation_fun = F}, Pos, Ps) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_pi(MoreBytes, S1, Pos, Ps) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_pi(Str = [H1,H2,H3 | T],S0=#xmerl_scanner{line = L, col = C}, Pos, Ps)
when H1==$x;H1==$X ->
@@ -1123,7 +1125,7 @@ scan_pi([], S=#xmerl_scanner{continuation_fun = F}, Target,
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_pi(MoreBytes, S1, Target,
L, C, Pos, Ps, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_pi("?>" ++ T, S0 = #xmerl_scanner{hook_fun = Hook,
event_fun = Event},
@@ -1150,7 +1152,7 @@ scan_pi2([], S=#xmerl_scanner{continuation_fun = F}, Target,
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_pi2(MoreBytes, S1, Target,
L, C, Pos, Ps, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_pi2("?>" ++ T, S0 = #xmerl_scanner{hook_fun = Hook,
event_fun = Event},
@@ -1178,7 +1180,7 @@ scan_pi2(Str, S0, Target, L, C, Pos, Ps, Acc) ->
scan_doctype([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_doctype(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_doctype(T, S) ->
{_,T1,S1} = mandatory_strip(T,S),
@@ -1192,7 +1194,7 @@ scan_doctype(T, S) ->
scan_doctype1([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_doctype1(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_doctype1("PUBLIC" ++ T, S0) ->
?bump_col(6),
@@ -1215,7 +1217,7 @@ scan_doctype1(T, S) ->
scan_doctype2([], S=#xmerl_scanner{continuation_fun = F},DTD) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_doctype2(MoreBytes, S1, DTD) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_doctype2("[" ++ T, S0, DTD) ->
?bump_col(1),
@@ -1235,7 +1237,7 @@ scan_doctype2(_T,S,_DTD) ->
scan_doctype3([], S=#xmerl_scanner{continuation_fun = F},DTD) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_doctype3(MoreBytes, S1,DTD) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_doctype3("%" ++ T, S0, DTD) ->
?bump_col(1),
@@ -1373,7 +1375,7 @@ fetch_not_parse(ExtSpec,S=#xmerl_scanner{fetch_fun=Fetch}) ->
end.
get_file(F,S) ->
-% io:format("get_file F=~p~n",[F]),
+% ?dbg("get_file F=~p~n",[F]),
case file:read_file(F) of
{ok,Bin} ->
binary_to_list(Bin);
@@ -1547,7 +1549,7 @@ scan_decl_sep(T,S) ->
scan_conditional_sect([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_conditional_sect(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_conditional_sect("IGNORE" ++ T, S0) ->
?bump_col(6),
@@ -1580,7 +1582,7 @@ scan_ignore(Str,S) ->
scan_ignore([], S=#xmerl_scanner{continuation_fun = F},Level) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_ignore(MoreBytes, S1,Level) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_ignore("<![" ++ T, S0,Level) ->
%% nested conditional section. Topmost condition is ignore, though
@@ -1601,7 +1603,7 @@ scan_ignore([_H|T],S0,Level) ->
scan_include([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_include(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_include("]]>" ++ T, S0) ->
?bump_col(3),
@@ -1743,7 +1745,7 @@ update_attributes1([],Acc) ->
scan_attdef([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_attdef(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_attdef(T, S) ->
scan_attdef(T, S, _AttrAcc = []).
@@ -1752,7 +1754,7 @@ scan_attdef(T, S) ->
scan_attdef([], S=#xmerl_scanner{continuation_fun = F}, Attrs) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_attdef(MoreBytes, S1, Attrs) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_attdef(">" ++ T, S0, Attrs) ->
?bump_col(1),
@@ -1796,7 +1798,7 @@ scan_attdef2(T, S, Attrs) ->
scan_att_type([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_att_type(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_att_type("CDATA" ++ T, S0) ->
?bump_col(5),
@@ -1854,7 +1856,7 @@ scan_att_type("%" ++ T, S0) ->
scan_notation_type([], S=#xmerl_scanner{continuation_fun = F}, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_notation_type(MoreBytes, S1, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_notation_type(")" ++ T, S0, Acc) ->
?bump_col(1),
@@ -1887,7 +1889,7 @@ notation_exists(Name, #xmerl_scanner{rules_read_fun = Read,
scan_enumeration([], S=#xmerl_scanner{continuation_fun = F}, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_enumeration(MoreBytes, S1, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_enumeration(")" ++ T, S0, Acc) ->
?bump_col(1),
@@ -1905,7 +1907,7 @@ scan_enumeration("|" ++ T, S0, Acc) ->
scan_default_decl([], S=#xmerl_scanner{continuation_fun = F}, Type) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_default_decl(MoreBytes, S1, Type) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_default_decl("#REQUIRED" ++ T, S0, _Type) ->
?bump_col(9),
@@ -1934,7 +1936,7 @@ default_value(T, S, Type) ->
scan_entity([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_entity(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_entity("%" ++ T, #xmerl_scanner{rules_write_fun = Write} = S0) ->
%% parameter entity
@@ -1972,7 +1974,7 @@ scan_entity_completion(T,S) ->
scan_entity_def([], S=#xmerl_scanner{continuation_fun = F}, EName) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_entity_def(MoreBytes, S1, EName) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_entity_def("'" ++ T, S0, EName) ->
?bump_col(1),
@@ -2013,7 +2015,7 @@ scan_entity_def(Str, S, EName) ->
scan_ndata_decl([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_ndata_decl(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_ndata_decl(Str = ">"++_T, S) ->
{[], Str, S};
@@ -2060,7 +2062,7 @@ scan_element("/", S=#xmerl_scanner{continuation_fun = F},
F(fun(MoreBytes, S1) -> scan_element("/" ++ MoreBytes, S1,
Pos, Name, StartL, StartC, Attrs,
Lang,Parents,NSI,NS,SpaceDefault) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_element([], S=#xmerl_scanner{continuation_fun = F},
Pos, Name, StartL, StartC, Attrs, Lang, Parents,
@@ -2069,7 +2071,7 @@ scan_element([], S=#xmerl_scanner{continuation_fun = F},
F(fun(MoreBytes, S1) -> scan_element(MoreBytes, S1,
Pos, Name, StartL, StartC, Attrs,
Lang,Parents,NSI,NS,SpaceDefault) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_element("/>" ++ T, S0 = #xmerl_scanner{hook_fun = Hook,
event_fun = Event,
@@ -2097,7 +2099,7 @@ scan_element(">", S=#xmerl_scanner{continuation_fun = F},
F(fun(MoreBytes, S1) -> scan_element(">" ++ MoreBytes, S1,
Pos, Name, StartL, StartC, Attrs,
Lang,Parents,NSI,NS,SpaceDefault) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_element(">" ++ T, S0 = #xmerl_scanner{event_fun = Event,
hook_fun = Hook,
@@ -2342,7 +2344,7 @@ keyreplaceadd(_K, _Pos, [], Obj) ->
scan_att_value([], S=#xmerl_scanner{continuation_fun = F},AT) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_att_value(MoreBytes, S1, AT) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_att_value("%"++_T,S=#xmerl_scanner{environment=prolog},_AttType) ->
?fatal({error,{wfc_PEs_In_Internal_Subset}},S);
@@ -2383,7 +2385,7 @@ scan_att_chars([],S=#xmerl_scanner{continuation_fun=F},H,Acc,TmpAcc,AT,IsNorm)->
F(fun(MoreBytes, S1) ->
scan_att_chars(MoreBytes, S1, H, Acc,TmpAcc,AT,IsNorm)
end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_att_chars([H|T], S0, H, Acc, TmpAcc,AttType,IsNorm) -> % End quote
?bump_col(1),
@@ -2516,7 +2518,7 @@ scan_content("<", S= #xmerl_scanner{continuation_fun = F},
F(fun(MoreBytes, S1) -> scan_content("<" ++ MoreBytes, S1,
Pos, Name, Attrs,
Space, Lang, Parents, NS, Acc,[]) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_content([], S=#xmerl_scanner{environment={external,{entity,_}}},
_Pos, _Name, _Attrs, _Space, _Lang, _Parents, _NS, Acc,_) ->
@@ -2530,7 +2532,7 @@ scan_content([], S=#xmerl_scanner{continuation_fun = F},
F(fun(MoreBytes, S1) -> scan_content(MoreBytes, S1,
Pos, Name, Attrs,
Space, Lang, Parents, NS, Acc,[]) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_content("</" ++ T, S0, _Pos, Name, _Attrs, _Space, _Lang,
_Parents, _NS, Acc,[]) ->
@@ -2634,7 +2636,7 @@ scan_content_markup([], S=#xmerl_scanner{continuation_fun = F},
F(fun(MoreBytes, S1) -> scan_content_markup(
MoreBytes,S1,Pos,Name,
Attrs,Space,Lang,Parents,NS) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_content_markup("![CDATA[" ++ T, S0, Pos, _Name, _Attrs,
_Space, _Lang, Parents, _NS) ->
@@ -2662,7 +2664,7 @@ scan_char_data([], S=#xmerl_scanner{environment=internal_parsed_entity},
scan_char_data([], S=#xmerl_scanner{continuation_fun = F}, Space, _MUD,Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_char_data(MoreBytes,S1,Space,_MUD,Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_char_data([$&|T], S,Space,"&",Acc) ->
scan_char_data(T, S, Space,[], [$&|Acc]);
@@ -2714,7 +2716,7 @@ scan_cdata(Str, S, Pos, Parents) ->
scan_cdata([], S=#xmerl_scanner{continuation_fun = F}, Pos, Parents, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_cdata(MoreBytes, S1, Pos, Parents, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_cdata("]]>" ++ T, S0, Pos, Parents, Acc) ->
?bump_col(3),
@@ -2739,7 +2741,7 @@ scan_cdata(Str, S0, Pos, Parents, Acc) ->
scan_reference([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_reference(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_reference("#x" ++ T, S0) ->
%% [66] CharRef
@@ -2781,7 +2783,7 @@ scan_reference(T, S) ->
scan_entity_ref([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_entity_ref(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_entity_ref("amp;" ++ T, S0) ->
?bump_col(4),
@@ -2866,7 +2868,7 @@ expand_reference(Name, #xmerl_scanner{rules_read_fun = Read} = S) ->
scan_char_ref_dec([], S=#xmerl_scanner{continuation_fun = F}, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_char_ref_dec(MoreBytes, S1, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_char_ref_dec([H|T], S0, Acc) when H >= $0, H =< $9 ->
?bump_col(1),
@@ -2881,7 +2883,7 @@ scan_char_ref_dec(";" ++ T, S0, Acc) ->
scan_char_ref_hex([], S=#xmerl_scanner{continuation_fun = F}, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_char_ref_hex(MoreBytes, S1, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_char_ref_hex([H|T], S0, Acc) when H >= $0, H =< $9 ->
?bump_col(1),
@@ -2955,7 +2957,7 @@ scan_name_no_colons(Str, S) ->
scan_name([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_name(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_name(Str = [$:|T], S0 = #xmerl_scanner{namespace_conformant = NSC}) ->
if NSC == false ->
@@ -3005,7 +3007,7 @@ scan_nmtoken(Str, S, Acc, NSC) ->
scan_nmtoken([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_nmtoken(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_nmtoken("%"++T, S0=#xmerl_scanner{environment={external,_}}) ->
?bump_col(1),
@@ -3082,7 +3084,7 @@ isLatin1(_,_) ->
scan_system_literal([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_system_literal(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_system_literal("\"" ++ T, S) ->
scan_system_literal(T, S, $", []);
@@ -3094,7 +3096,7 @@ scan_system_literal([], S=#xmerl_scanner{continuation_fun = F},
Delimiter, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_system_literal(MoreBytes,S1,Delimiter,Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_system_literal([H|T], S, H, Acc) ->
{lists:reverse(Acc), T, S#xmerl_scanner{col = S#xmerl_scanner.col+1}};
@@ -3112,7 +3114,7 @@ scan_system_literal(Str, S, Delimiter, Acc) ->
scan_pubid_literal([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_pubid_literal(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_pubid_literal([H|T], S) when H == $"; H == $' ->
scan_pubid_literal(T, S#xmerl_scanner{col = S#xmerl_scanner.col+1}, H, []);
@@ -3124,7 +3126,7 @@ scan_pubid_literal([], S=#xmerl_scanner{continuation_fun = F},
Delimiter, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_pubid_literal(MoreBytes,S1,Delimiter,Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_pubid_literal([H|T], S, H, Acc) ->
{lists:reverse(Acc), T, S#xmerl_scanner{col = S#xmerl_scanner.col+1}};
@@ -3159,7 +3161,7 @@ is_pubid_char(X) ->
scan_contentspec([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_contentspec(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_contentspec("EMPTY" ++ T, S0) ->
?bump_col(5),
@@ -3193,7 +3195,7 @@ scan_elem_content([], S=#xmerl_scanner{continuation_fun = F},
Context, Mode, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes,S1) -> scan_elem_content(MoreBytes,S1,Context,Mode,Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_elem_content(")" ++ T, S0, Context, Mode0, Acc0) ->
?bump_col(1),
@@ -3280,7 +3282,7 @@ format_elem_content(Other) -> Other.
scan_occurrence([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_occurrence(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_occurrence([$?|T], S0) ->
?bump_col(1),
@@ -3431,7 +3433,7 @@ wfc_whitespace_betw_attrs([$> |_]=L,S) ->
wfc_whitespace_betw_attrs([],S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> wfc_whitespace_betw_attrs(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
wfc_whitespace_betw_attrs(_,S) ->
?fatal({whitespace_required_between_attributes},S).
@@ -3475,7 +3477,7 @@ vc_Element_valid(_,_) ->
scan_pe_def([], S=#xmerl_scanner{continuation_fun = F}, PEName) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_pe_def(MoreBytes, S1, PEName) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_pe_def("'" ++ T, S0, PEName) ->
?bump_col(1),
@@ -3508,7 +3510,7 @@ scan_notation_decl(T, #xmerl_scanner{rules_write_fun = Write,
scan_notation_decl1([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_notation_decl1(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_notation_decl1("SYSTEM" ++ T, S0) ->
?bump_col(6),
@@ -3534,7 +3536,7 @@ scan_notation_decl1("PUBLIC" ++ T, S0) ->
scan_external_id([], S=#xmerl_scanner{continuation_fun = F}) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_external_id(MoreBytes, S1) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_external_id("SYSTEM" ++ T, S0) ->
?bump_col(6),
@@ -3580,7 +3582,7 @@ scan_entity_value([], S=#xmerl_scanner{continuation_fun = F},
scan_entity_value(MoreBytes,S1,
Delim,Acc,PEName,Namespace,PENesting)
end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_entity_value([Delim|T], S=#xmerl_scanner{validation=dtd},
Delim,_Acc,PEName,_NS,PENesting) when length(PENesting) /= 0 ->
@@ -3848,7 +3850,7 @@ scan_comment1([], S=#xmerl_scanner{continuation_fun = F},
Pos, Comment, Acc) ->
?dbg("cont()...~n", []),
F(fun(MoreBytes, S1) -> scan_comment1(MoreBytes, S1, Pos, Comment, Acc) end,
- fun(S1) -> ?fatal(unexpected_end, S1) end,
+ fatal_fun(unexpected_end),
S);
scan_comment1("-->" ++ T, S0 = #xmerl_scanner{col = C,
event_fun = Event,
@@ -4088,7 +4090,7 @@ schemaLocations(#xmlElement{attributes=Atts,xmlbase=_Base}) ->
end.
inherit_options(S) ->
- %%io:format("xsdbase: ~p~n",[S#xmerl_scanner.xmlbase]),
+ %%?dbg("xsdbase: ~p~n",[S#xmerl_scanner.xmlbase]),
[{xsdbase,S#xmerl_scanner.xmlbase}].
handle_schema_result({XSDRes=#xmlElement{},_},S5) ->
@@ -4098,6 +4100,13 @@ handle_schema_result({error,Reason},S5) ->
%%% Helper functions
+-compile({inline, [fatal_fun/1]}).
+
+-spec fatal_fun(_) -> fun((_) -> no_return()).
+
+fatal_fun(Reason) ->
+ fun(S) -> ?fatal(Reason, S) end.
+
fatal(Reason, S) ->
exit({fatal, {Reason,
{file,S#xmerl_scanner.filename},
@@ -4227,7 +4236,7 @@ string_to_char_set(_,Str) ->
%% NewTot =
%% case {lists:keysearch(total,1,Mem),OldTot*1.1} of
%% {{_,{_,Tot}},Tot110} when Tot > Tot110 ->
-%% io:format("From ~p to ~p, total memory: ~p (~p)~n",[OldLine,Line,Tot,OldTot]),
+%% ?dbg("From ~p to ~p, total memory: ~p (~p)~n",[OldLine,Line,Tot,OldTot]),
%% Tot;
%% {{_,{_,Tot}},_} ->
%% Tot
diff --git a/lib/xmerl/src/xmerl_sgml.erl b/lib/xmerl/src/xmerl_sgml.erl
index 1fe6453e7f..6c0ee55448 100644
--- a/lib/xmerl/src/xmerl_sgml.erl
+++ b/lib/xmerl/src/xmerl_sgml.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_simple.erl b/lib/xmerl/src/xmerl_simple.erl
index 573dcd2a62..32479066cd 100644
--- a/lib/xmerl/src/xmerl_simple.erl
+++ b/lib/xmerl/src/xmerl_simple.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_text.erl b/lib/xmerl/src/xmerl_text.erl
index 70df8369ff..459c7d4562 100644
--- a/lib/xmerl/src/xmerl_text.erl
+++ b/lib/xmerl/src/xmerl_text.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_ucs.erl b/lib/xmerl/src/xmerl_ucs.erl
index 6550a9d954..f93d1d15c4 100644
--- a/lib/xmerl/src/xmerl_ucs.erl
+++ b/lib/xmerl/src/xmerl_ucs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -227,7 +228,7 @@ from_ucs4be(<<Ch:32/big-signed-integer, Rest/binary>>,Acc,Tail) ->
from_ucs4be(<<>>,Acc,Tail) ->
lists:reverse(Acc,Tail);
from_ucs4be(Bin,Acc,Tail) ->
- io:format("ucs Error: Bin=~p~n Acc=~p~n Tail=~p~n",[Bin,Acc,Tail]),
+ ucs_error(Bin,Acc,Tail),
{error,not_ucs4be}.
char_to_ucs4le(Ch) ->
@@ -247,7 +248,7 @@ from_ucs4le(<<Ch:32/little-signed-integer, Rest/binary>>,Acc,Tail) ->
from_ucs4le(<<>>,Acc,Tail) ->
lists:reverse(Acc,Tail);
from_ucs4le(Bin,Acc,Tail) ->
- io:format("ucs Error: Bin=~p~n Acc=~p~n Tail=~p~n",[Bin,Acc,Tail]),
+ ucs_error(Bin,Acc,Tail),
{error,not_ucs4le}.
@@ -269,7 +270,7 @@ from_ucs2be(<<Ch:16/big-signed-integer, Rest/binary>>,Acc,Tail) ->
from_ucs2be(<<>>,Acc,Tail) ->
lists:reverse(Acc,Tail);
from_ucs2be(Bin,Acc,Tail) ->
- io:format("ucs Error: Bin=~p~n Acc=~p~n Tail=~p~n",[Bin,Acc,Tail]),
+ ucs_error(Bin,Acc,Tail),
{error,not_ucs2be}.
char_to_ucs2le(Ch) ->
@@ -287,7 +288,7 @@ from_ucs2le(<<Ch:16/little-signed-integer, Rest/binary>>,Acc,Tail) ->
from_ucs2le(<<>>,Acc,Tail) ->
lists:reverse(Acc,Tail);
from_ucs2le(Bin,Acc,Tail) ->
- io:format("ucs Error: Bin=~p~n Acc=~p~n Tail=~p~n",[Bin,Acc,Tail]),
+ ucs_error(Bin,Acc,Tail),
{error,not_ucs2le}.
@@ -331,7 +332,7 @@ from_utf16be(<<Hi:16/big-unsigned-integer, Lo:16/big-unsigned-integer,
from_utf16be(<<>>,Acc,Tail) ->
lists:reverse(Acc,Tail);
from_utf16be(Bin,Acc,Tail) ->
- io:format("ucs Error: Bin=~p~n Acc=~p~n Tail=~p~n",[Bin,Acc,Tail]),
+ ucs_error(Bin,Acc,Tail),
{error,not_utf16be}.
char_to_utf16le(Ch) when is_integer(Ch), Ch >= 0 ->
@@ -363,7 +364,7 @@ from_utf16le(<<Hi:16/little-unsigned-integer, Lo:16/little-unsigned-integer,
from_utf16le(<<>>,Acc,Tail) ->
lists:reverse(Acc,Tail);
from_utf16le(Bin,Acc,Tail) ->
- io:format("ucs Error: Bin=~p~n Acc=~p~n Tail=~p~n",[Bin,Acc,Tail]),
+ ucs_error(Bin,Acc,Tail),
{error,not_utf16le}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -571,3 +572,6 @@ test_charset(Fun,Input) ->
false
end.
+ucs_error(Bin,Acc,Tail) ->
+ error_logger:error_msg("~w: Bin=~p~n Acc=~p~n Tail=~p~n",
+ [?MODULE,Bin,Acc,Tail]).
diff --git a/lib/xmerl/src/xmerl_uri.erl b/lib/xmerl/src/xmerl_uri.erl
index ed66dd78d4..78278fba63 100644
--- a/lib/xmerl/src/xmerl_uri.erl
+++ b/lib/xmerl/src/xmerl_uri.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_validate.erl b/lib/xmerl/src/xmerl_validate.erl
index 60f228474b..87b9a43ce9 100644
--- a/lib/xmerl/src/xmerl_validate.erl
+++ b/lib/xmerl/src/xmerl_validate.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -23,7 +24,7 @@
-include("xmerl.hrl"). % record def, macros
-
+-include("xmerl_internal.hrl").
%% +type validate(xmerl_scanner(),xmlElement())->
@@ -300,7 +301,7 @@ test_attribute_value('NMTOKEN',#xmlAttribute{name=Name,value=V}=Attr,
true->
ok;
false->
- %%io:format("Warning*** nmtoken,value_incorrect: ~p~n",[V]),
+ %%?dbg("nmtoken,value_incorrect: ~p~n",[V]),
exit({error,{invalid_value_nmtoken,Name,V}})
end
end,
@@ -381,7 +382,7 @@ test_attribute_value({Type,L},#xmlAttribute{value=Value}=Attr,Default,_S)
exit({error,{duplicate_tokens_not_allowed,{list,L}}})
end;
test_attribute_value(_Rule,Attr,_,_) ->
-% io:format("Attr Value*****~nRule~p~nValue~p~n",[Rule,Attr]),
+% ?dbg("Attr Value*****~nRule~p~nValue~p~n",[Rule,Attr]),
Attr.
@@ -423,11 +424,11 @@ parse({'+',SubRule}, XMLS, Rules, WSaction, S) ->
parse({choice,CHOICE}, XMLS, Rules, WSaction, S)->
% case XMLS of
% [] ->
-% io:format("~p~n",[{choice,CHOICE,[]}]);
+% ?dbg("~p~n",[{choice,CHOICE,[]}]);
% [#xmlElement{name=Name,pos=Pos}|_] ->
-% io:format("~p~n",[{choice,CHOICE,{Name,Pos}}]);
+% ?dbg("~p~n",[{choice,CHOICE,{Name,Pos}}]);
% [#xmlText{value=V}|_] ->
-% io:format("~p~n",[{choice,CHOICE,{text,V}}])
+% ?dbg("~p~n",[{choice,CHOICE,{text,V}}])
% end,
choice(CHOICE, XMLS, Rules, WSaction, S);
parse(empty, [], _Rules, _WSaction, _S) ->
@@ -550,10 +551,10 @@ star(Rule,XMLS,Rules,WSaction,Tree,S) ->
{WS,XMLS1} = whitespace_action(XMLS,WSaction),
case parse(Rule,XMLS1,Rules,WSaction,S) of
{error, _E, {{next,N},{act,A}}}->
- %%io:format("Error~p~n",[_E]),
+ %%?dbg("Error~p~n",[_E]),
{WS++Tree++A,N};
{error, _E}->
- %%io:format("Error~p~n",[_E]),
+ %%?dbg("Error~p~n",[_E]),
% {WS++[Tree],[]};
case whitespace_action(XMLS,ws_action(WSaction,remove)) of
{[],_} ->
diff --git a/lib/xmerl/src/xmerl_xlate.erl b/lib/xmerl/src/xmerl_xlate.erl
index 5c4d9d2540..6bfd9595f0 100644
--- a/lib/xmerl/src/xmerl_xlate.erl
+++ b/lib/xmerl/src/xmerl_xlate.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_xml.erl b/lib/xmerl/src/xmerl_xml.erl
index 702a654629..914bbad6be 100644
--- a/lib/xmerl/src/xmerl_xml.erl
+++ b/lib/xmerl/src/xmerl_xml.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -31,6 +32,7 @@
-import(xmerl_lib, [markup/3, empty_tag/2, export_text/1]).
-include("xmerl.hrl").
+-include("xmerl_internal.hrl").
'#xml-inheritance#'() -> [].
@@ -39,7 +41,7 @@
%% The '#text#' function is called for every text segment.
'#text#'(Text) ->
-%io:format("Text=~p~n",[Text]),
+%?dbg("Text=~p~n",[Text]),
export_text(Text).
@@ -55,8 +57,8 @@
%% The '#element#' function is the default handler for XML elements.
'#element#'(Tag, [], Attrs, _Parents, _E) ->
-%io:format("Empty Tag=~p~n",[Tag]),
+%?dbg("Empty Tag=~p~n",[Tag]),
empty_tag(Tag, Attrs);
'#element#'(Tag, Data, Attrs, _Parents, _E) ->
-%io:format("Tag=~p~n",[Tag]),
+%?dbg("Tag=~p~n",[Tag]),
markup(Tag, Attrs, Data).
diff --git a/lib/xmerl/src/xmerl_xpath.erl b/lib/xmerl/src/xmerl_xpath.erl
index be0e863ce4..97ae3a1971 100644
--- a/lib/xmerl/src/xmerl_xpath.erl
+++ b/lib/xmerl/src/xmerl_xpath.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -128,18 +129,18 @@ string(Str, Node, Parents, Doc, Options) ->
[{H, P}|_] when is_atom(H), is_integer(P) ->
full_parents(Parents, Doc)
end,
-%io:format("string FullParents=~p~n",[FullParents]),
+%?dbg("string FullParents=~p~n",[FullParents]),
ContextNode=#xmlNode{type = node_type(Node),
node = Node,
parents = FullParents},
-%io:format("string ContextNode=~p~n",[ContextNode]),
+%?dbg("string ContextNode=~p~n",[ContextNode]),
WholeDoc = whole_document(Doc),
-%io:format("string WholeDoc=~p~n",[WholeDoc]),
+%?dbg("string WholeDoc=~p~n",[WholeDoc]),
Context=(new_context(Options))#xmlContext{context_node = ContextNode,
whole_document = WholeDoc},
-%io:format("string Context=~p~n",[Context]),
+%?dbg("string Context=~p~n",[Context]),
#state{context = NewContext} = match(Str, #state{context = Context}),
-%io:format("string NewContext=~p~n",[NewContext]),
+%?dbg("string NewContext=~p~n",[NewContext]),
case NewContext#xmlContext.nodeset of
ScalObj = #xmlObj{type=Scalar}
when Scalar == boolean; Scalar == number; Scalar == string ->
@@ -274,7 +275,7 @@ eval_pred(Predicate, S = #state{context = C =
NewNodeSet =
lists:filter(
fun(Node) ->
- %io:format("current node: ~p~n", [write_node(Node)]),
+ %?dbg("current node: ~p~n", [write_node(Node)]),
ThisContext = C#xmlContext{context_node = Node},
xmerl_xpath_pred:eval(Predicate, ThisContext)
end, NodeSet),
@@ -461,7 +462,7 @@ match_descendant_or_self(Tok, N, Acc, Context) ->
match_child(Tok, N, Acc, Context) ->
- %io:format("match_child(~p)~n", [write_node(N)]),
+ %?dbg("match_child(~p)~n", [write_node(N)]),
#xmlNode{parents = Ps, node = Node, type = Type} = N,
case Type of
El when El == element; El == root_node ->
@@ -738,7 +739,7 @@ node_test({prefix_test, Prefix}, #xmlNode{node = N}, Context) ->
end;
node_test({name, {Tag, _Prefix, _Local}},
#xmlNode{node = #xmlElement{name = Tag}}=_N, _Context) ->
- %io:format("node_test({tag, ~p}, ~p) -> true.~n", [Tag, write_node(_N)]),
+ %?dbg("node_test({tag, ~p}, ~p) -> true.~n", [Tag, write_node(_N)]),
true;
node_test({name, {Tag, Prefix, Local}},
#xmlNode{node = #xmlElement{name = Name,
@@ -816,7 +817,7 @@ node_test({processing_instruction, Name1},
#xmlNode{node = #xmlPI{name = Name2}}, _Context) ->
Name1 == atom_to_list(Name2);
node_test(_Other, _N, _Context) ->
- %io:format("node_test(~p, ~p) -> false.~n", [_Other, write_node(_N)]),
+ %?dbg("node_test(~p, ~p) -> false.~n", [_Other, write_node(_N)]),
false.
diff --git a/lib/xmerl/src/xmerl_xpath_lib.erl b/lib/xmerl/src/xmerl_xpath_lib.erl
index b37bdc93f9..873fc41c4b 100644
--- a/lib/xmerl/src/xmerl_xpath_lib.erl
+++ b/lib/xmerl/src/xmerl_xpath_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_xpath_parse.yrl b/lib/xmerl/src/xmerl_xpath_parse.yrl
index 381ea20193..14a8c27352 100644
--- a/lib/xmerl/src/xmerl_xpath_parse.yrl
+++ b/lib/xmerl/src/xmerl_xpath_parse.yrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_xpath_pred.erl b/lib/xmerl/src/xmerl_xpath_pred.erl
index b94f3bb14d..582a4e4091 100644
--- a/lib/xmerl/src/xmerl_xpath_pred.erl
+++ b/lib/xmerl/src/xmerl_xpath_pred.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -58,6 +59,7 @@
-export([core_function/1]).
-include("xmerl.hrl").
+-include("xmerl_internal.hrl").
-include("xmerl_xpath.hrl").
%% -record(obj, {type,
@@ -88,7 +90,7 @@ eval(Expr, C = #xmlContext{context_node = #xmlNode{pos = Pos}}) ->
_ ->
mk_boolean(C, Obj)
end,
-% io:format("eval(~p, ~p) -> ~p~n", [Expr, Pos, Res]),
+% ?dbg("eval(~p, ~p) -> ~p~n", [Expr, Pos, Res]),
Res.
diff --git a/lib/xmerl/src/xmerl_xpath_scan.erl b/lib/xmerl/src/xmerl_xpath_scan.erl
index f0a5bd35a3..53d6032475 100644
--- a/lib/xmerl/src/xmerl_xpath_scan.erl
+++ b/lib/xmerl/src/xmerl_xpath_scan.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_xs.erl b/lib/xmerl/src/xmerl_xs.erl
index f42a470a43..2a8e221e16 100644
--- a/lib/xmerl/src/xmerl_xs.erl
+++ b/lib/xmerl/src/xmerl_xs.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl
index 16d02f571d..3038a54ee6 100644
--- a/lib/xmerl/src/xmerl_xsd.erl
+++ b/lib/xmerl/src/xmerl_xsd.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -381,7 +382,7 @@ initiate_state2(S,[{target_namespace,_NS}|T]) ->
%% initiate_state2(S#xsd_state{targetNamespace=if_list_to_atom(NS)},T);
initiate_state2(S,T); %% used in validation phase
initiate_state2(S,[H|T]) ->
- error_msg("Invalid option: ~p~n",[H]),
+ error_msg("~w: invalid option: ~p~n",[?MODULE, H]),
initiate_state2(S,T).
validation_options(S,[{target_namespace,NS}|T]) ->
@@ -4887,7 +4888,6 @@ mk_EII_Att_QName(AttName,XMLEl,S) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
create_tables(S=#xsd_state{table=undefined}) ->
Tid=ets:new(xmerl_schema_tab,[]),
- initial_tab_data(Tid),
S#xsd_state{table=Tid};
create_tables(S) ->
S.
@@ -5391,7 +5391,7 @@ search_attribute(_,{Name,_,_},SchemaAtts) ->
end.
error_msg(Format,Args) ->
- io:format(Format,Args).
+ error_logger:error_msg(Format,Args).
add_once(El,L) ->
@@ -5425,7 +5425,7 @@ add_key_once(Key,N,El,L) ->
%% "/"++filename:join(L).
%% mk_xml_path(Parents,Type,Pos) ->
-%% %% io:format("mk_xml_path: Parents = ~p~n",[Parents]),
+%% %% ?dbg("mk_xml_path: Parents = ~p~n",[Parents]),
%% {filename:join([[io_lib:format("/~w(~w)",[X,Y])||{X,Y}<-Parents],Type]),Pos}.
%% @spec format_error(Errors) -> Result
@@ -5616,131 +5616,5 @@ format_error(Err) ->
%% {shema_el_pathname(SchemaE,Env),
%% xml_el_pathname(E)}.
-initial_tab_data(Tab) ->
- ets:insert(Tab,
- binary_to_term(
- <<131,108,0,0,0,9,104,2,104,2,100,0,9,97,116,116,114,105,98,117,116,
- 101,104,3,100,0,5,115,112,97,99,101,106,100,0,36,104,116,116,112,58,
- 47,47,119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,
- 56,47,110,97,109,101,115,112,97,99,101,104,9,100,0,16,115,99,104,101,
- 109,97,95,97,116,116,114,105,98,117,116,101,104,3,100,0,5,115,112,97,
- 99,101,106,100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,
- 46,111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,
- 97,99,101,108,0,0,0,1,104,2,100,0,10,115,105,109,112,108,101,84,121,
- 112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,
- 109,101,95,108,0,0,0,1,100,0,5,115,112,97,99,101,106,106,106,100,0,5,
- 102,97,108,115,101,106,100,0,8,111,112,116,105,111,110,97,108,100,0,9,
- 117,110,100,101,102,105,110,101,100,100,0,9,117,110,100,101,102,105,
- 110,101,100,100,0,9,117,110,100,101,102,105,110,101,100,104,2,104,2,
- 100,0,6,115,99,104,101,109,97,107,0,7,120,109,108,46,120,115,100,104,
- 7,100,0,6,115,99,104,101,109,97,100,0,11,117,110,113,117,97,108,105,
- 102,105,101,100,100,0,11,117,110,113,117,97,108,105,102,105,101,100,
- 100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,
- 103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,99,101,
- 106,106,106,104,2,104,2,100,0,9,97,116,116,114,105,98,117,116,101,
- 104,3,100,0,4,98,97,115,101,106,100,0,36,104,116,116,112,58,47,47,
- 119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,56,47,
- 110,97,109,101,115,112,97,99,101,104,9,100,0,16,115,99,104,101,109,
- 97,95,97,116,116,114,105,98,117,116,101,104,3,100,0,4,98,97,115,101,
- 106,100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,
- 114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,99,
- 101,108,0,0,0,1,104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,
- 104,3,100,0,6,97,110,121,85,82,73,106,100,0,32,104,116,116,112,58,47,
- 47,119,119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,
- 99,104,101,109,97,106,100,0,5,102,97,108,115,101,106,100,0,8,111,112,
- 116,105,111,110,97,108,100,0,9,117,110,100,101,102,105,110,101,100,
- 100,0,9,117,110,100,101,102,105,110,101,100,100,0,9,117,110,100,101,
- 102,105,110,101,100,104,2,104,2,100,0,14,97,116,116,114,105,98,117,
- 116,101,71,114,111,117,112,104,3,100,0,12,115,112,101,99,105,97,108,
- 65,116,116,114,115,106,100,0,36,104,116,116,112,58,47,47,119,119,119,
- 46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,
- 115,112,97,99,101,104,5,100,0,22,115,99,104,101,109,97,95,97,116,116,
- 114,105,98,117,116,101,95,103,114,111,117,112,104,3,100,0,12,115,112,
- 101,99,105,97,108,65,116,116,114,115,106,100,0,36,104,116,116,112,58,
- 47,47,119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,
- 56,47,110,97,109,101,115,112,97,99,101,100,0,9,117,110,100,101,102,
- 105,110,101,100,100,0,9,117,110,100,101,102,105,110,101,100,108,0,0,
- 0,3,104,2,100,0,9,97,116,116,114,105,98,117,116,101,104,3,100,0,4,98,
- 97,115,101,106,106,104,2,100,0,9,97,116,116,114,105,98,117,116,101,
- 104,3,100,0,4,108,97,110,103,106,106,104,2,100,0,9,97,116,116,114,
- 105,98,117,116,101,104,3,100,0,5,115,112,97,99,101,106,106,106,104,
- 2,104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,3,100,0,
- 15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,0,0,0,
- 1,100,0,5,115,112,97,99,101,106,106,104,9,100,0,18,115,99,104,101,
- 109,97,95,115,105,109,112,108,101,95,116,121,112,101,104,3,100,0,15,
- 95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,0,0,0,1,
- 100,0,5,115,112,97,99,101,106,106,108,0,0,0,1,100,0,5,115,112,97,99,
- 101,106,104,3,100,0,6,78,67,78,97,109,101,106,100,0,32,104,116,116,
- 112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,
- 88,77,76,83,99,104,101,109,97,100,0,5,102,97,108,115,101,106,108,0,0,
- 0,1,104,2,100,0,11,101,110,117,109,101,114,97,116,105,111,110,108,0,0,
- 0,2,107,0,7,100,101,102,97,117,108,116,107,0,8,112,114,101,115,101,
- 114,118,101,106,106,100,0,6,97,116,111,109,105,99,108,0,0,0,1,104,2,
- 100,0,11,114,101,115,116,114,105,99,116,105,111,110,104,2,104,3,100,
- 0,6,78,67,78,97,109,101,106,100,0,32,104,116,116,112,58,47,47,119,
- 119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,99,
- 104,101,109,97,108,0,0,0,2,104,2,100,0,11,101,110,117,109,101,114,
- 97,116,105,111,110,107,0,7,100,101,102,97,117,108,116,104,2,100,0,
- 11,101,110,117,109,101,114,97,116,105,111,110,107,0,8,112,114,101,
- 115,101,114,118,101,106,106,104,2,104,2,100,0,10,115,105,109,112,
- 108,101,84,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,
- 111,95,110,97,109,101,95,108,0,0,0,1,100,0,4,108,97,110,103,106,106,
- 104,9,100,0,18,115,99,104,101,109,97,95,115,105,109,112,108,101,95,
- 116,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,111,95,
- 110,97,109,101,95,108,0,0,0,1,100,0,4,108,97,110,103,106,106,108,0,0,
- 0,1,100,0,4,108,97,110,103,106,100,0,9,117,110,100,101,102,105,110,
- 101,100,100,0,5,102,97,108,115,101,106,106,100,0,6,97,116,111,109,
- 105,99,108,0,0,0,1,104,2,100,0,5,117,110,105,111,110,108,0,0,0,2,104,
- 2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,3,100,0,8,108,
- 97,110,103,117,97,103,101,106,100,0,32,104,116,116,112,58,47,47,119,
- 119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,99,104,
- 101,109,97,104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,
- 3,100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,
- 0,0,0,2,100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,
- 95,100,0,4,108,97,110,103,106,106,106,106,104,2,104,2,100,0,9,97,116,
- 116,114,105,98,117,116,101,104,3,100,0,2,105,100,106,100,0,36,104,116,
- 116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,
- 49,57,57,56,47,110,97,109,101,115,112,97,99,101,104,9,100,0,16,115,99,
- 104,101,109,97,95,97,116,116,114,105,98,117,116,101,104,3,100,0,2,105,
- 100,106,100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,46,
- 111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,
- 99,101,108,0,0,0,1,104,2,100,0,10,115,105,109,112,108,101,84,121,112,
- 101,104,3,100,0,2,73,68,106,100,0,32,104,116,116,112,58,47,47,119,119,
- 119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,99,104,101,
- 109,97,106,100,0,5,102,97,108,115,101,106,100,0,8,111,112,116,105,111,
- 110,97,108,100,0,9,117,110,100,101,102,105,110,101,100,100,0,9,117,
- 110,100,101,102,105,110,101,100,100,0,9,117,110,100,101,102,105,110,
- 101,100,104,2,104,2,100,0,9,97,116,116,114,105,98,117,116,101,104,3,
- 100,0,4,108,97,110,103,106,100,0,36,104,116,116,112,58,47,47,119,119,
- 119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,
- 101,115,112,97,99,101,104,9,100,0,16,115,99,104,101,109,97,95,97,116,
- 116,114,105,98,117,116,101,104,3,100,0,4,108,97,110,103,106,100,0,36,
- 104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,88,
- 77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,99,101,108,0,0,0,1,
- 104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,3,100,0,15,
- 95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,0,0,0,1,
- 100,0,4,108,97,110,103,106,106,106,100,0,5,102,97,108,115,101,106,
- 100,0,8,111,112,116,105,111,110,97,108,100,0,9,117,110,100,101,102,
- 105,110,101,100,100,0,9,117,110,100,101,102,105,110,101,100,100,0,9,
- 117,110,100,101,102,105,110,101,100,104,2,104,2,100,0,10,115,105,109,
- 112,108,101,84,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,
- 110,111,95,110,97,109,101,95,108,0,0,0,2,100,0,15,95,120,109,101,114,
- 108,95,110,111,95,110,97,109,101,95,100,0,4,108,97,110,103,106,106,
- 104,9,100,0,18,115,99,104,101,109,97,95,115,105,109,112,108,101,95,
- 116,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,111,95,
- 110,97,109,101,95,108,0,0,0,2,100,0,15,95,120,109,101,114,108,95,110,
- 111,95,110,97,109,101,95,100,0,4,108,97,110,103,106,106,108,0,0,0,2,
- 100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,100,
- 0,4,108,97,110,103,106,104,3,100,0,6,115,116,114,105,110,103,106,100,
- 0,32,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,
- 50,48,48,49,47,88,77,76,83,99,104,101,109,97,100,0,5,102,97,108,115,
- 101,106,108,0,0,0,1,104,2,100,0,11,101,110,117,109,101,114,97,116,105,
- 111,110,108,0,0,0,1,106,106,106,100,0,6,97,116,111,109,105,99,108,0,0,
- 0,1,104,2,100,0,11,114,101,115,116,114,105,99,116,105,111,110,104,2,
- 104,3,100,0,6,115,116,114,105,110,103,106,100,0,32,104,116,116,112,58,
- 47,47,119,119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,
- 83,99,104,101,109,97,108,0,0,0,1,104,2,100,0,11,101,110,117,109,101,
- 114,97,116,105,111,110,106,106,106,106>>)).
-
default_namespace_by_convention() ->
[{xml,'http://www.w3.org/XML/1998/namespace'}].
diff --git a/lib/xmerl/src/xmerl_xsd_type.erl b/lib/xmerl/src/xmerl_xsd_type.erl
index 0f46b1f9aa..2cd7e85edd 100644
--- a/lib/xmerl/src/xmerl_xsd_type.erl
+++ b/lib/xmerl/src/xmerl_xsd_type.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
@@ -29,6 +30,7 @@
-export([compare_durations/2,compare_dateTime/2]).
-include("xmerl.hrl").
+-include("xmerl_internal.hrl").
-include("xmerl_xsd.hrl").
@@ -687,7 +689,8 @@ facet_fun(Type,{fractionDigits,V}) ->
fractionDigits_fun(Type,list_to_integer(V));
facet_fun(Type,F) ->
fun(_X_) ->
- io:format("Warning: not valid facet on ~p ~p~n",[Type,F])
+ error_logger:warning_msg("~w: not valid facet on ~p ~p~n",
+ [?MODULE,Type,F])
end.
@@ -1075,7 +1078,7 @@ compare_floats(F1,F2) when F1=="-INF";F2=="INF" ->
compare_floats(Str1,Str2) ->
F1={S1,_B1,_D1,_E1} = str_to_float(Str1),
F2={S2,_B2,_D2,_E2} = str_to_float(Str2),
-% io:format("F1: ~p~nF2: ~p~n",[F1,F2]),
+% ?dbg("F1: ~p~nF2: ~p~n",[F1,F2]),
if
S1=='-',S2=='+' -> lt;
S1=='+',S2=='-' -> gt;
diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile
index ac3370dbda..f9c03336c8 100644
--- a/lib/xmerl/test/Makefile
+++ b/lib/xmerl/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/lib/xmerl/test/xmerl_SUITE.erl b/lib/xmerl/test/xmerl_SUITE.erl
index 692cd64249..7ddf1066de 100644
--- a/lib/xmerl/test/xmerl_SUITE.erl
+++ b/lib/xmerl/test/xmerl_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/xmerl/test/xmerl_app_test.erl b/lib/xmerl/test/xmerl_app_test.erl
index 4cc4bf3791..7b30eb260c 100644
--- a/lib/xmerl/test/xmerl_app_test.erl
+++ b/lib/xmerl/test/xmerl_app_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/lib/xmerl/test/xmerl_appup_test.erl b/lib/xmerl/test/xmerl_appup_test.erl
index ff6b368bcc..506bbfcd51 100644
--- a/lib/xmerl/test/xmerl_appup_test.erl
+++ b/lib/xmerl/test/xmerl_appup_test.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/test/xmerl_sax_SUITE.erl b/lib/xmerl/test/xmerl_sax_SUITE.erl
index 10a96f470b..a15d9bd57c 100644
--- a/lib/xmerl/test/xmerl_sax_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% 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.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/test/xmerl_sax_std_SUITE.erl b/lib/xmerl/test/xmerl_sax_std_SUITE.erl
index 6440329112..70e768ff04 100644
--- a/lib/xmerl/test/xmerl_sax_std_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_std_SUITE.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%----------------------------------------------------------------------
diff --git a/lib/xmerl/test/xmerl_std_SUITE.erl b/lib/xmerl/test/xmerl_std_SUITE.erl
index c3cc9007d3..0ef44bb04e 100644
--- a/lib/xmerl/test/xmerl_std_SUITE.erl
+++ b/lib/xmerl/test/xmerl_std_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/test/xmerl_test_lib.erl b/lib/xmerl/test/xmerl_test_lib.erl
index e82ad283b2..62689353f2 100644
--- a/lib/xmerl/test/xmerl_test_lib.erl
+++ b/lib/xmerl/test/xmerl_test_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/test/xmerl_xsd_MS2002-01-16_SUITE.erl b/lib/xmerl/test/xmerl_xsd_MS2002-01-16_SUITE.erl
index 34a65ac6ff..ee648dc455 100644
--- a/lib/xmerl/test/xmerl_xsd_MS2002-01-16_SUITE.erl
+++ b/lib/xmerl/test/xmerl_xsd_MS2002-01-16_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-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.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/test/xmerl_xsd_NIST2002-01-16_SUITE.erl b/lib/xmerl/test/xmerl_xsd_NIST2002-01-16_SUITE.erl
index daebf1393d..634e47ba7b 100644
--- a/lib/xmerl/test/xmerl_xsd_NIST2002-01-16_SUITE.erl
+++ b/lib/xmerl/test/xmerl_xsd_NIST2002-01-16_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE.erl b/lib/xmerl/test/xmerl_xsd_SUITE.erl
index 421fa48054..92c8287782 100644
--- a/lib/xmerl/test/xmerl_xsd_SUITE.erl
+++ b/lib/xmerl/test/xmerl_xsd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -40,7 +41,8 @@ groups() ->
[{group, primitive_datatypes},
{group, derived_datatypes}]},
{validation_tests, [],
- [{group, xmlSchemaPrimerExamples},
+ [{group, xmlXsdAndExample},
+ {group, xmlSchemaPrimerExamples},
{group, miscXMLexamples}]},
{primitive_datatypes, [],
[string, boolean, decimal, float, double, duration,
@@ -54,6 +56,8 @@ groups() ->
negativeInteger, long, int, short, byte,
nonNegativeInteger, unsignedLong, unsignedInt,
unsignedShort, unsignedByte, positiveInteger]},
+ {xmlXsdAndExample, [],
+ [xml_xsd, xml_lang_attr]},
{xmlSchemaPrimerExamples, [],
[po, po1, po2, ipo, ipo_redefine, '4Q99']},
{miscXMLexamples, [],
@@ -862,6 +866,19 @@ compare_duration(_Config) ->
?line indefinite = xmerl_xsd_type:compare_durations("P5M","P153D"),
?line lt = xmerl_xsd_type:compare_durations("P5M","P154D").
+xml_xsd(suite) -> [];
+xml_xsd(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Options = [{fetch_path, [DataDir]}],
+ {ok, _} = xmerl_xsd:process_schema("xml.xsd", Options).
+
+xml_lang_attr(suite) -> [];
+xml_lang_attr(Config) ->
+ DataDir = ?config(data_dir, Config),
+ {Element, _} = xmerl_scan:file(filename:join([DataDir, "book.xml"])),
+ Options = [{fetch_path, [DataDir]}],
+ {ok, Schema} = xmerl_xsd:process_schema("book.xsd", Options),
+ {Element, _} = xmerl_xsd:validate(Element, Schema).
po(suite) -> [];
po(Config) ->
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml
new file mode 100644
index 0000000000..17d7ceffee
--- /dev/null
+++ b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<book title="Title" xml:lang="EN">
+ <author>Author1</author>
+ <author>Author2</author>
+</book>
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd
new file mode 100644
index 0000000000..830951ec1b
--- /dev/null
+++ b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
+ <xs:element name="book">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="author" type="xs:string" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="title" type="xs:string"/>
+ <xs:attribute ref="xml:lang"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd b/lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd
new file mode 100644
index 0000000000..aea7d0db0a
--- /dev/null
+++ b/lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd
@@ -0,0 +1,287 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns ="http://www.w3.org/1999/xhtml"
+ xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+ <h1>About the XML namespace</h1>
+
+ <div class="bodytext">
+ <p>
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+ </p>
+ <p>
+ See <a href="http://www.w3.org/XML/1998/namespace.html">
+ http://www.w3.org/XML/1998/namespace.html</a> and
+ <a href="http://www.w3.org/TR/REC-xml">
+ http://www.w3.org/TR/REC-xml</a> for information
+ about this namespace.
+ </p>
+ <p>
+ Note that local names in this namespace are intended to be
+ defined only by the World Wide Web Consortium or its subgroups.
+ The names currently defined in this namespace are listed below.
+ They should not be used with conflicting semantics by any Working
+ Group, specification, or document instance.
+ </p>
+ <p>
+ See further below in this document for more information about <a
+ href="#usage">how to refer to this schema document from your own
+ XSD schema documents</a> and about <a href="#nsversioning">the
+ namespace-versioning policy governing this schema document</a>.
+ </p>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>lang (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.</p>
+
+ </div>
+ <div>
+ <h4>Notes</h4>
+ <p>
+ Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility.
+ </p>
+ <p>
+ See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+ http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+ and the IANA language subtag registry at
+ <a href="http://www.iana.org/assignments/language-subtag-registry">
+ http://www.iana.org/assignments/language-subtag-registry</a>
+ for further information.
+ </p>
+ <p>
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>space (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.</p>
+
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>base (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.</p>
+
+ <p>
+ See <a
+ href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+ for information about this attribute.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>id (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.</p>
+
+ <p>
+ See <a
+ href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+ for information about this attribute.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>Father (in any context at all)</h3>
+
+ <div class="bodytext">
+ <p>
+ denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+ </p>
+ <blockquote>
+ <p>
+ In appreciation for his vision, leadership and
+ dedication the W3C XML Plenary on this 10th day of
+ February, 2000, reserves for Jon Bosak in perpetuity
+ the XML name "xml:Father".
+ </p>
+ </blockquote>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div xml:id="usage" id="usage">
+ <h2><a name="usage">About this schema document</a></h2>
+
+ <div class="bodytext">
+ <p>
+ This schema defines attributes and an attribute group suitable
+ for use by schemas wishing to allow <code>xml:base</code>,
+ <code>xml:lang</code>, <code>xml:space</code> or
+ <code>xml:id</code> attributes on elements they define.
+ </p>
+ <p>
+ To enable this, such a schema must import this schema for
+ the XML namespace, e.g. as follows:
+ </p>
+ <pre>
+ &lt;schema . . .>
+ . . .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+ </pre>
+ <p>
+ or
+ </p>
+ <pre>
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+ </pre>
+ <p>
+ Subsequently, qualified reference to any of the attributes or the
+ group defined below will have the desired effect, e.g.
+ </p>
+ <pre>
+ &lt;type . . .>
+ . . .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+ </pre>
+ <p>
+ will define a type which will schema-validate an instance element
+ with any of those attributes.
+ </p>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div id="nsversioning" xml:id="nsversioning">
+ <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+ <div class="bodytext">
+ <p>
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ <a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd</a>.
+ </p>
+ <p>
+ At the date of issue it can also be found at
+ <a href="http://www.w3.org/2001/xml.xsd">
+ http://www.w3.org/2001/xml.xsd</a>.
+ </p>
+ <p>
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML
+ Schema itself, or with the XML namespace itself. In other words,
+ if the XML Schema or XML namespaces change, the version of this
+ document at <a href="http://www.w3.org/2001/xml.xsd">
+ http://www.w3.org/2001/xml.xsd
+ </a>
+ will change accordingly; the version at
+ <a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd
+ </a>
+ will not change.
+ </p>
+ <p>
+ Previous dated (and unchanging) versions of this schema
+ document are at:
+ </p>
+ <ul>
+ <li><a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2007/08/xml.xsd">
+ http://www.w3.org/2007/08/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2004/10/xml.xsd">
+ http://www.w3.org/2004/10/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2001/03/xml.xsd">
+ http://www.w3.org/2001/03/xml.xsd</a></li>
+ </ul>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
+
diff --git a/lib/xmerl/test/xmerl_xsd_Sun2002-01-16_SUITE.erl b/lib/xmerl/test/xmerl_xsd_Sun2002-01-16_SUITE.erl
index e619390f65..5ad6bb94fb 100644
--- a/lib/xmerl/test/xmerl_xsd_Sun2002-01-16_SUITE.erl
+++ b/lib/xmerl/test/xmerl_xsd_Sun2002-01-16_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/test/xmerl_xsd_lib.erl b/lib/xmerl/test/xmerl_xsd_lib.erl
index e5c2d900ba..892706609f 100644
--- a/lib/xmerl/test/xmerl_xsd_lib.erl
+++ b/lib/xmerl/test/xmerl_xsd_lib.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% Licensed under the Apache License, Version 2.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%
%%
diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk
index aab2a37d6c..09d81e0533 100644
--- a/lib/xmerl/vsn.mk
+++ b/lib/xmerl/vsn.mk
@@ -1 +1 @@
-XMERL_VSN = 1.3.7
+XMERL_VSN = 1.3.10
diff --git a/make/cross_check_erl b/make/cross_check_erl
index cb9dadfb32..f8ba73023a 100755
--- a/make/cross_check_erl
+++ b/make/cross_check_erl
@@ -4,16 +4,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -61,16 +62,17 @@ cat > cross_check_erl.erl <<\EOF
%
% Copyright Ericsson AB 2010. All Rights Reserved.
%
-% The contents of this file are subject to the Erlang Public License,
-% Version 1.1, (the "License"); you may not use this file except in
-% compliance with the License. You should have received a copy of the
-% Erlang Public License along with this software. If not, it can be
-% retrieved online at http://www.erlang.org/.
-%
-% Software distributed under the License is distributed on an "AS IS"
-% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-% the License for the specific language governing rights and limitations
-% under the License.
+% Licensed under the Apache License, Version 2.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.
%
-module(cross_check_erl).
diff --git a/make/emd2exml.in b/make/emd2exml.in
index 48473349d0..d84b967e40 100644
--- a/make/emd2exml.in
+++ b/make/emd2exml.in
@@ -7,16 +7,17 @@
%%
%% Copyright Ericsson AB 2010-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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
@@ -799,16 +800,17 @@ parse_crd([], From, To, Holder, Legal) ->
end,
case Legal of
[] ->
- ["The contents of this file are subject to the Erlang Public License,", nl(),
- "Version 1.1, (the \"License\"); you may not use this file except in", nl(),
- "compliance with the License. You should have received a copy of the", nl(),
- "Erlang Public License along with this software. If not, it can be", nl(),
- "retrieved online at http://www.erlang.org/.", nl(),
- nl(),
- "Software distributed under the License is distributed on an \"AS IS\"", nl(),
- "basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See", nl(),
- "the License for the specific language governing rights and limitations", nl(),
- "under the License.", nl()];
+ ["Licensed under the Apache License, Version 2.0 (the \"License\");", nl(),
+ "you may not use this file except in compliance with the License.", nl(),
+ "You may obtain a copy of the License at", nl(),
+ nl(),
+ " http://www.apache.org/licenses/LICENSE-2.0", nl(),
+ nl(),
+ "Unless required by applicable law or agreed to in writing, software", nl(),
+ "distributed under the License is distributed on an \"AS IS\" BASIS,", nl(),
+ "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", nl(),
+ "See the License for the specific language governing permissions and", nl(),
+ "limitations under the License.", nl()];
_ -> Legal
end};
parse_crd([Line|Lines], OldFrom, OldTo, OldHolder, Legal) ->
diff --git a/make/fakefop b/make/fakefop
index b64428bbd1..7beeddf0a5 100755
--- a/make/fakefop
+++ b/make/fakefop
@@ -5,16 +5,17 @@
# Copyright Tuncer Ayaz 2010-2013. All Rights Reserved.
# Copyright Ericsson AB 2010-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/make/install_bin b/make/install_bin
index 0d3e82266e..6c9d83e1ca 100755
--- a/make/install_bin
+++ b/make/install_bin
@@ -4,16 +4,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/make/lazy_configure.mk b/make/lazy_configure.mk
index 320f485d90..c74f216de0 100644
--- a/make/lazy_configure.mk
+++ b/make/lazy_configure.mk
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/make/ose_lm.mk.in b/make/ose_lm.mk.in
index 5455ad94c6..de8d351af3 100644
--- a/make/ose_lm.mk.in
+++ b/make/ose_lm.mk.in
@@ -6,16 +6,17 @@
#
# Copyright Ericsson AB 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/make/otp.mk.in b/make/otp.mk.in
index ddc9cd9b79..ea36be333b 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -6,16 +6,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/make/otp_ded.mk.in b/make/otp_ded.mk.in
index c534209a25..0b5311d75e 100644
--- a/make/otp_ded.mk.in
+++ b/make/otp_ded.mk.in
@@ -4,16 +4,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/make/otp_default_release_path.mk b/make/otp_default_release_path.mk
index 932bbb2f6d..bdaaca53ea 100644
--- a/make/otp_default_release_path.mk
+++ b/make/otp_default_release_path.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk
index fcac2ff695..e104b68991 100644
--- a/make/otp_release_targets.mk
+++ b/make/otp_release_targets.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -44,6 +45,7 @@ $(HTMLDIR)/index.html: $(XML_FILES) $(SPECS_FILES)
--stringparam gendate "$$date" \
--stringparam appname "$(APPLICATION)" \
--stringparam appver "$(VSN)" \
+ --stringparam extra_front_page_info "$(DOC_EXTRA_FRONT_PAGE_INFO)" \
--stringparam stylesheet "$(CSS_FILE)" \
--stringparam winprefix "$(WINPREFIX)" \
--stringparam logo "$(HTMLLOGO_FILE)" \
@@ -64,6 +66,7 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES)
--stringparam gendate "$$date" \
--stringparam appname "$(APPLICATION)" \
--stringparam appver "$(VSN)" \
+ --stringparam extra_front_page_info "$(DOC_EXTRA_FRONT_PAGE_INFO)" \
--stringparam stylesheet "$(CSS_FILE)" \
--stringparam winprefix "$(WINPREFIX)" \
--stringparam logo "$(HTMLLOGO_FILE)" \
@@ -80,6 +83,7 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES)
--stringparam gendate "$$date" \
--stringparam appname "$(APPLICATION)" \
--stringparam appver "$(VSN)" \
+ --stringparam extra_front_page_info "$(DOC_EXTRA_FRONT_PAGE_INFO)" \
--stringparam logo "$(PDFLOGO_FILE)" \
--stringparam pdfcolor "$(PDFCOLOR)" \
--xinclude $(TOP_SPECS_PARAM) \
@@ -109,7 +113,16 @@ $(HTMLDIR)/$(APPLICATION).eix: $(XML_FILES) $(SPECS_FILES)
docs: $(HTMLDIR)/$(APPLICATION).eix
xmllint: $(XML_FILES)
- $(XMLLINT) --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities $(XML_FILES)
+ @echo "Running xmllint"
+ @BookFiles=`awk -F\" '/xi:include/ {print $$2}' book.xml`; \
+ for i in $$BookFiles; do \
+ if [ $$i = "notes.xml" ]; then \
+ echo Checking $$i; \
+ xmllint --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities $$i; \
+ else\
+ awk -F\" '/xi:include/ {print "echo Checking " $$2 ;print "xmllint --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities " $$2}' $$i |sh; \
+ fi \
+ done
# ----------------------------------------------------
# Local documentation target for testing
diff --git a/make/otp_released_app.mk b/make/otp_released_app.mk
index fb5205ab23..71d1771b47 100644
--- a/make/otp_released_app.mk
+++ b/make/otp_released_app.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
diff --git a/make/otp_subdir.mk b/make/otp_subdir.mk
index e6a75cce17..fa6470ddd7 100644
--- a/make/otp_subdir.mk
+++ b/make/otp_subdir.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/make/output.mk.in b/make/output.mk.in
index f2f738a2ce..171d2456aa 100644
--- a/make/output.mk.in
+++ b/make/output.mk.in
@@ -6,16 +6,17 @@
#
# Copyright Ericsson AB 1997-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/make/run_make.mk b/make/run_make.mk
index 01ab257006..2591a37cad 100644
--- a/make/run_make.mk
+++ b/make/run_make.mk
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
@@ -30,7 +31,7 @@ include $(ERL_TOP)/make/target.mk
.PHONY: valgrind
-opt debug purify quantify purecov valgrind gcov gprof lcnt frmptr:
+opt debug purify quantify purecov valgrind gcov gprof lcnt frmptr icount:
$(make_verbose)$(MAKE) -f $(TARGET)/Makefile TYPE=$@
plain smp frag smp_frag:
diff --git a/make/save_args b/make/save_args
index 331cde99e1..1109f8dd1b 100755
--- a/make/save_args
+++ b/make/save_args
@@ -1,15 +1,16 @@
#!/bin/sh
#
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/make/target.mk b/make/target.mk
index 4e13779461..8917e1ae44 100644
--- a/make/target.mk
+++ b/make/target.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1998-2011. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
diff --git a/make/unexpected_use b/make/unexpected_use
index d7543a7d83..58f6fc4793 100755
--- a/make/unexpected_use
+++ b/make/unexpected_use
@@ -4,16 +4,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/make/verify_runtime_dependencies b/make/verify_runtime_dependencies
index b8eea06b6e..cd08091a67 100755
--- a/make/verify_runtime_dependencies
+++ b/make/verify_runtime_dependencies
@@ -6,16 +6,17 @@
%%
%% Copyright Ericsson AB 2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/otp_build b/otp_build
index fca2b6ca13..ac99ced42a 100755
--- a/otp_build
+++ b/otp_build
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2002-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
@@ -1442,13 +1443,13 @@ case "$1" in
do_debuginfo_win32 "$2";;
env_win32)
if [ x"$2" = x"x64" -o x"$2" = x"amd64" ]; then
- if [ -x /usr/bin/msysinfo ]; then
+ if [ -x /usr/bin/msys-?.0.dll ]; then
echo_env_msys64
else
echo_env_win64
fi
else
- if [ -x /usr/bin/msysinfo ]; then
+ if [ -x /usr/bin/msys-?.0.dll ]; then
echo_env_msys32
else
echo_env_win32
diff --git a/otp_patch_apply b/otp_patch_apply
index 51b9431d89..3ff929ccbb 100755
--- a/otp_patch_apply
+++ b/otp_patch_apply
@@ -4,16 +4,17 @@
#
# Copyright Ericsson AB 2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/otp_versions.table b/otp_versions.table
index 50a77237ff..af476841ab 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,3 +1,32 @@
+OTP-18.3.4 : inets-6.2.4 ssl-7.3.3 # asn1-4.0.2 common_test-1.12.1 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3.1 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 mnesia-4.13.4 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 :
+OTP-18.3.3 : common_test-1.12.1 inets-6.2.3 ssl-7.3.2 # asn1-4.0.2 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3.1 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 mnesia-4.13.4 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 :
+OTP-18.3.2 : inets-6.2.2 ssl-7.3.1 # asn1-4.0.2 common_test-1.12 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3.1 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 mnesia-4.13.4 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 :
+OTP-18.3.1 : erts-7.3.1 inets-6.2.1 mnesia-4.13.4 # asn1-4.0.2 common_test-1.12 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 ssl-7.3 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 :
+OTP-18.3 : asn1-4.0.2 common_test-1.12 compiler-6.0.3 cosNotification-1.2.1 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3 eunit-2.2.13 hipe-3.15 inets-6.2 kernel-4.2 mnesia-4.13.3 observer-2.1.2 orber-3.8.1 public_key-1.1.1 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 ssl-7.3 stdlib-2.8 test_server-3.10 tools-2.8.3 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 # cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosProperty-1.2 et-1.5.1 gs-1.6 ic-4.4 jinterface-1.6.1 megaco-3.18 odbc-2.11.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 reltool-0.7 syntax_tools-1.7 typer-0.9.10 :
+OTP-18.2.4 : common_test-1.11.2 # asn1-4.0.1 compiler-6.0.2 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.2 debugger-4.1.1 dialyzer-2.8.2 diameter-1.11.1 edoc-0.7.17 eldap-1.2 erl_docgen-0.4.1 erl_interface-3.8.1 erts-7.2.1 et-1.5.1 eunit-2.2.12 gs-1.6 hipe-3.14 ic-4.4 inets-6.1.1 jinterface-1.6.1 kernel-4.1.1 megaco-3.18 mnesia-4.13.2 observer-2.1.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1 reltool-0.7 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssh-4.2.1 ssl-7.2 stdlib-2.7 syntax_tools-1.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 webtool-0.9 wx-1.6 xmerl-1.3.9 :
+OTP-18.2.3 : inets-6.1.1 # asn1-4.0.1 common_test-1.11.1 compiler-6.0.2 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.2 debugger-4.1.1 dialyzer-2.8.2 diameter-1.11.1 edoc-0.7.17 eldap-1.2 erl_docgen-0.4.1 erl_interface-3.8.1 erts-7.2.1 et-1.5.1 eunit-2.2.12 gs-1.6 hipe-3.14 ic-4.4 jinterface-1.6.1 kernel-4.1.1 megaco-3.18 mnesia-4.13.2 observer-2.1.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1 reltool-0.7 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssh-4.2.1 ssl-7.2 stdlib-2.7 syntax_tools-1.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 webtool-0.9 wx-1.6 xmerl-1.3.9 :
+OTP-18.2.2 : ssh-4.2.1 # asn1-4.0.1 common_test-1.11.1 compiler-6.0.2 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.2 debugger-4.1.1 dialyzer-2.8.2 diameter-1.11.1 edoc-0.7.17 eldap-1.2 erl_docgen-0.4.1 erl_interface-3.8.1 erts-7.2.1 et-1.5.1 eunit-2.2.12 gs-1.6 hipe-3.14 ic-4.4 inets-6.1 jinterface-1.6.1 kernel-4.1.1 megaco-3.18 mnesia-4.13.2 observer-2.1.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1 reltool-0.7 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssl-7.2 stdlib-2.7 syntax_tools-1.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 webtool-0.9 wx-1.6 xmerl-1.3.9 :
+OTP-18.2.1 : erts-7.2.1 # asn1-4.0.1 common_test-1.11.1 compiler-6.0.2 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.2 debugger-4.1.1 dialyzer-2.8.2 diameter-1.11.1 edoc-0.7.17 eldap-1.2 erl_docgen-0.4.1 erl_interface-3.8.1 et-1.5.1 eunit-2.2.12 gs-1.6 hipe-3.14 ic-4.4 inets-6.1 jinterface-1.6.1 kernel-4.1.1 megaco-3.18 mnesia-4.13.2 observer-2.1.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1 reltool-0.7 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssh-4.2 ssl-7.2 stdlib-2.7 syntax_tools-1.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 webtool-0.9 wx-1.6 xmerl-1.3.9 :
+OTP-18.2 : asn1-4.0.1 common_test-1.11.1 compiler-6.0.2 crypto-3.6.2 dialyzer-2.8.2 diameter-1.11.1 erl_docgen-0.4.1 erl_interface-3.8.1 erts-7.2 eunit-2.2.12 hipe-3.14 inets-6.1 jinterface-1.6.1 kernel-4.1.1 observer-2.1.1 parsetools-2.1.1 public_key-1.1 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssh-4.2 ssl-7.2 stdlib-2.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 wx-1.6 xmerl-1.3.9 # cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 debugger-4.1.1 edoc-0.7.17 eldap-1.2 et-1.5.1 gs-1.6 ic-4.4 megaco-3.18 mnesia-4.13.2 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 percept-0.8.11 reltool-0.7 syntax_tools-1.7 webtool-0.9 :
+OTP-18.1.5 : ssh-4.1.3 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 inets-6.0.3 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.4 : inets-6.0.3 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssh-4.1.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.3 : ssh-4.1.2 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 inets-6.0.2 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.2 : ssh-4.1.1 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 inets-6.0.2 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.1 : inets-6.0.2 mnesia-4.13.2 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 jinterface-1.6 kernel-4.1 megaco-3.18 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssh-4.1 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1 : compiler-6.0.1 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 erts-7.1 eunit-2.2.11 hipe-3.13 inets-6.0.1 kernel-4.1 mnesia-4.13.1 odbc-2.11.1 public_key-1.0.1 sasl-2.6 ssh-4.1 ssl-7.1 stdlib-2.6 tools-2.8.1 wx-1.5 # asn1-4.0 common_test-1.11 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 gs-1.6 ic-4.4 jinterface-1.6 megaco-3.18 observer-2.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 reltool-0.7 runtime_tools-1.9.1 snmp-5.2 syntax_tools-1.7 test_server-3.9 typer-0.9.9 webtool-0.9 xmerl-1.3.8 :
+OTP-18.0.3 : erts-7.0.3 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9.1 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
+OTP-18.0.2 : erts-7.0.2 runtime_tools-1.9.1 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
+OTP-18.0.1 : erts-7.0.1 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
+OTP-18.0 : asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.0 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 # :
+OTP-17.5.6.9 : diameter-1.9.2.4 erts-6.4.1.6 ssl-6.0.1.2 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.8 : diameter-1.9.2.3 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1.5 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.7 : diameter-1.9.2.2 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1.5 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.6 : erts-6.4.1.5 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 diameter-1.9.2.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.5 : erts-6.4.1.4 kernel-3.2.0.1 ssl-6.0.1.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 diameter-1.9.2.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.4 : debugger-4.0.3.1 erts-6.4.1.3 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 dialyzer-2.7.4 diameter-1.9.2.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.3 : diameter-1.9.2.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1.2 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.2 : erts-6.4.1.2 runtime_tools-1.8.16.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 diameter-1.9.2 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.1 : erts-6.4.1.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 diameter-1.9.2 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
OTP-17.5.6 : inets-5.10.9 ssh-3.2.4 ssl-6.0.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 diameter-1.9.2 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16 sasl-2.4.1 snmp-5.1.2 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
OTP-17.5.5 : diameter-1.9.2 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.8 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16 sasl-2.4.1 snmp-5.1.2 ssh-3.2.3 ssl-6.0 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
OTP-17.5.4 : inets-5.10.8 ssh-3.2.3 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 diameter-1.9.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16 sasl-2.4.1 snmp-5.1.2 ssl-6.0 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
diff --git a/system/COPYRIGHT b/system/COPYRIGHT
index 7014f080d5..0d0668974d 100644
--- a/system/COPYRIGHT
+++ b/system/COPYRIGHT
@@ -7,16 +7,17 @@ This software is subject to the following Copyrights and Licenses:
Copyright Ericsson AB 1997-2012. All Rights Reserved.
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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%
diff --git a/system/doc/Makefile b/system/doc/Makefile
index 3f32e35561..eb900b933f 100644
--- a/system/doc/Makefile
+++ b/system/doc/Makefile
@@ -1,13 +1,14 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# ``Licensed under the Apache License, Version 2.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.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/system/doc/design_principles/Makefile b/system/doc/design_principles/Makefile
index 14e0c8f3f6..1f35ed8773 100644
--- a/system/doc/design_principles/Makefile
+++ b/system/doc/design_principles/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/design_principles/applications.xml b/system/doc/design_principles/applications.xml
index 7b030115df..4d73e0fc66 100644
--- a/system/doc/design_principles/applications.xml
+++ b/system/doc/design_principles/applications.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,55 +30,63 @@
<file>applications.xml</file>
</header>
<marker id="appl"></marker>
- <p>This chapter should be read in conjunction with <c>app(4)</c> and
- <c>application(3)</c>.</p>
+ <p>This section is to be read with the <c>app(4)</c> and
+ <c>application(3)</c> manual pages in Kernel.</p>
<section>
<title>Application Concept</title>
- <p>When we have written code implementing some specific
- functionality, we might want to make the code into an
- <em>application</em>, that is a component that can be started and
- stopped as a unit, and which can be re-used in other systems as
- well.</p>
- <p>To do this, we create an
- <seealso marker="#callback_module">application callback module</seealso>, where we describe how the application should
- be started and stopped.</p>
+ <p>When you have written code implementing some specific functionality
+ you might want to make the code into an <em>application</em>,
+ that is, a component that can be started and stopped as a unit,
+ and which can also be reused in other systems.</p>
+ <p>To do this, create an
+ <seealso marker="#callback_module">application callback module</seealso>,
+ and describe how the application is to be started and stopped.</p>
<p>Then, an <em>application specification</em> is needed, which is
- put in an <seealso marker="#appl_res_file">application resource file</seealso>. Among other things, we specify which
- modules the application consists of and the name of the callback
- module.</p>
- <p>If we use <c>systools</c>, the Erlang/OTP tools for packaging code
+ put in an
+ <seealso marker="#appl_res_file">application resource file</seealso>.
+ Among other things, this file specifies which modules the application
+ consists of and the name of the callback module.</p>
+ <p>If you use <c>systools</c>, the Erlang/OTP tools for packaging code
(see <seealso marker="release_structure">Releases</seealso>),
- the code for each application is placed in a separate directory
- following a pre-defined <seealso marker="#app_dir">directory structure</seealso>.</p>
+ the code for each application is placed in a
+ separate directory following a pre-defined
+ <seealso marker="#app_dir">directory structure</seealso>.</p>
</section>
<section>
<marker id="callback_module"></marker>
<title>Application Callback Module</title>
- <p>How to start and stop the code for the application, i.e.
+ <p>How to start and stop the code for the application, that is,
the supervision tree, is described by two callback functions:</p>
<code type="none">
start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}
-stop(State)</code>
- <p><c>start</c> is called when starting the application and should
- create the supervision tree by starting the top supervisor.
- It is expected to return the pid of the top supervisor and an
- optional term <c>State</c>, which defaults to []. This term is
- passed as-is to <c>stop</c>.</p>
- <p><c>StartType</c> is usually the atom <c>normal</c>. It has other
+stop(State)
+ </code>
+ <list type="bulleted">
+ <item><c>start</c> is called when starting the application and is to
+ create the supervision tree by starting the top supervisor. It is
+ expected to return the pid of the top supervisor and an optional
+ term, <c>State</c>, which defaults to <c>[]</c>. This term is passed
+ as is to <c>stop</c>.</item>
+ <item><c>StartType</c> is usually the atom <c>normal</c>. It has other
values only in the case of a takeover or failover, see
- <seealso marker="distributed_applications">Distributed Applications</seealso>. <c>StartArgs</c> is defined by the key
- <c>mod</c> in the <seealso marker="#appl_res_file">application resource file</seealso> file.</p>
- <p><c>stop/1</c> is called <em>after</em> the application has been
- stopped and should do any necessary cleaning up. Note that
- the actual stopping of the application, that is the shutdown of
- the supervision tree, is handled automatically as described in
- <seealso marker="#stopping">Starting and Stopping Applications</seealso>.</p>
+ <seealso marker="distributed_applications">Distributed Applications</seealso>.
+ </item>
+ <item><c>StartArgs</c> is defined by the key <c>mod</c> in the
+ <seealso marker="#appl_res_file">application
+ resource file</seealso>.</item>
+ <item><c>stop/1</c> is called <em>after</em> the application has been
+ stopped and is to do any necessary cleaning up. The actual stopping of
+ the application, that is, the shutdown of the supervision tree, is
+ handled automatically as described in
+ <seealso marker="#stopping">Starting and Stopping Applications</seealso>.
+ </item>
+ </list>
<marker id="ch_app"></marker>
<p>Example of an application callback module for packaging
the supervision tree from
- the <seealso marker="sup_princ#ex">Supervisor</seealso> chapter:</p>
+ <seealso marker="sup_princ#ex">Supervisor Behaviour</seealso>:</p>
<code type="none">
-module(ch_app).
-behaviour(application).
@@ -89,44 +98,48 @@ start(_Type, _Args) ->
stop(_State) ->
ok.</code>
- <p>A library application, which can not be started or stopped,
- does not need any application callback module.</p>
+ <p>A library application that cannot be started or stopped, does not
+ need any application callback module.</p>
</section>
<section>
<marker id="appl_res_file"></marker>
<title>Application Resource File</title>
- <p>To define an application, we create an <em>application specification</em> which is put in an <em>application resource file</em>, or in short <c>.app</c> file:</p>
+ <p>To define an application, an <em>application specification</em> is
+ created, which is put in an <em>application resource file</em>, or in
+ short an <c>.app</c> file:</p>
<code type="none">
{application, Application, [Opt1,...,OptN]}.</code>
- <p><c>Application</c>, an atom, is the name of the application.
- The file must be named <c>Application.app</c>.</p>
- <p>Each <c>Opt</c> is a tuple <c>{Key, Value}</c> which define a
+<list>
+ <item><c>Application</c>, an atom, is the name of the application.
+ The file must be named <c>Application.app</c>.</item>
+ <item>Each <c>Opt</c> is a tuple <c>{Key,Value}</c>, which define a
certain property of the application. All keys are optional.
- Default values are used for any omitted keys.</p>
+ Default values are used for any omitted keys.</item>
+</list>
<p>The contents of a minimal <c>.app</c> file for a library
- application <c>libapp</c> looks like this:</p>
+ application <c>libapp</c> looks as follows:</p>
<code type="none">
{application, libapp, []}.</code>
<p>The contents of a minimal <c>.app</c> file <c>ch_app.app</c> for
- a supervision tree application like <c>ch_app</c> looks like this:</p>
+ a supervision tree application like <c>ch_app</c> looks as follows:</p>
<code type="none">
{application, ch_app,
[{mod, {ch_app,[]}}]}.</code>
- <p>The key <c>mod</c> defines the callback module and start
- argument of the application, in this case <c>ch_app</c> and
- [], respectively. This means that</p>
+ <p>The key <c>mod</c> defines the callback module and start argument of
+ the application, in this case <c>ch_app</c> and <c>[]</c>, respectively.
+ This means that the following is called when the application is to be
+ started:</p>
<code type="none">
ch_app:start(normal, [])</code>
- <p>will be called when the application should be started and</p>
+ <p>The following is called when the application is stopped.</p>
<code type="none">
ch_app:stop([])</code>
- <p>will be called when the application has been stopped.</p>
<p>When using <c>systools</c>, the Erlang/OTP tools for packaging
- code (see <seealso marker="release_structure">Releases</seealso>),
- the keys <c>description</c>, <c>vsn</c>, <c>modules</c>,
- <c>registered</c> and <c>applications</c> should also be
- specified:</p>
+ code (see Section
+ <seealso marker="release_structure">Releases</seealso>), the keys
+ <c>description</c>, <c>vsn</c>, <c>modules</c>, <c>registered</c>,
+ and <c>applications</c> are also to be specified:</p>
<code type="none">
{application, ch_app,
[{description, "Channel allocator"},
@@ -136,67 +149,54 @@ ch_app:stop([])</code>
{applications, [kernel, stdlib, sasl]},
{mod, {ch_app,[]}}
]}.</code>
- <taglist>
- <tag><c>description</c></tag>
- <item>A short description, a string. Defaults to "".</item>
- <tag><c>vsn</c></tag>
- <item>Version number, a string. Defaults to "".</item>
- <tag><c>modules</c></tag>
- <item>All modules <em>introduced</em> by this application.
- <c>systools</c> uses this list when generating boot scripts and
- tar files. A module must be defined in one and only one
- application. Defaults to [].</item>
- <tag><c>registered</c></tag>
- <item>All names of registered processes in the application.
- <c>systools</c> uses this list to detect name clashes
- between applications. Defaults to [].</item>
- <tag><c>applications</c></tag>
- <item>All applications which must be started before this
- application is started. <c>systools</c> uses this list to
- generate correct boot scripts. Defaults to [], but note that
- all applications have dependencies to at least <c>kernel</c>
- and <c>stdlib</c>.</item>
- </taglist>
- <note><p>The syntax and contents of of the application resource file
- are described in detail in the<seealso marker="kernel:app">
- Application resource file reference</seealso>.</p></note>
+ <list>
+ <item><c>description</c> - A short description, a string. Defaults to
+ "".</item>
+ <item><c>vsn</c> - Version number, a string. Defaults to "".</item>
+ <item><c>modules</c> - All modules <em>introduced</em> by this
+ application. <c>systools</c> uses this list when generating boot scripts
+ and tar files. A module must be defined in only one application.
+ Defaults to <c>[]</c>.</item>
+ <item><c>registered</c> - All names of registered processes in the
+ application. <c>systools</c> uses this list to detect name clashes
+ between applications. Defaults to <c>[]</c>.</item>
+ <item><c>applications</c> - All applications that must be
+ started before this application is started. <c>systools</c> uses this
+ list to generate correct boot scripts. Defaults to <c>[]</c>. Notice
+ that all applications have dependencies to at least Kernel
+ and STDLIB.</item>
+ </list>
+ <note><p>For details about the syntax and contents of the application
+ resource file, see the <seealso marker="kernel:app">app</seealso>
+ manual page in Kernel.</p></note>
</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
+ application is placed in a separate directory,
<c>lib/Application-Vsn</c>, where <c>Vsn</c> is the version number.</p>
- <p>This may be useful to know, even if <c>systools</c> is not used,
- since Erlang/OTP itself is packaged according to the OTP principles
+ <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 <c>code(3)</c>) will automatically use code from
- the directory with the highest version number, if there are
- more than one version of an application present.</p>
- <p>The application directory structure can of course be used in
- the development environment as well. The version number may then
+ (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 have the following sub-directories:</p>
+ <p>The application directory has the following sub-directories:</p>
<list type="bulleted">
- <item><c>src</c></item>
- <item><c>ebin</c></item>
- <item><c>priv</c></item>
- <item><c>include</c></item>
+ <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>
- <taglist>
- <tag><c>src</c></tag>
- <item>Contains the Erlang source code.</item>
- <tag><c>ebin</c></tag>
- <item>Contains the Erlang object code, the <c>beam</c> files.
- The <c>.app</c> file is also placed here.</item>
- <tag><c>priv</c></tag>
- <item>Used for application specific files. For example, C
- executables are placed here. The function <c>code:priv_dir/1</c>
- should be used to access this directory.</item>
- <tag><c>include</c></tag>
- <item>Used for include files.</item>
- </taglist>
</section>
<section>
@@ -207,17 +207,17 @@ ch_app:stop([])</code>
processes is the <em>application controller</em> process,
registered as <c>application_controller</c>.</p>
<p>All operations on applications are coordinated by the application
- controller. It is interfaced through the functions in
- the module <c>application</c>, see <c>application(3)</c>.
- In particular, applications can be loaded, unloaded, started and
- stopped.</p>
+ controller. It is interacted through the functions in
+ the module <c>application</c>, see the <c>application(3)</c>
+ manual page in Kernel. In particular, applications can be
+ loaded, unloaded, started, and stopped.</p>
</section>
<section>
<title>Loading and Unloading Applications</title>
<p>Before an application can be started, it must be <em>loaded</em>.
The application controller reads and stores the information from
- the <c>.app</c> file.</p>
+ the <c>.app</c> file:</p>
<pre>
1> <input>application:load(ch_app).</input>
ok
@@ -236,7 +236,7 @@ ok
{stdlib,"ERTS CXC 138 10","1.11.4.3"}]</pre>
<note>
<p>Loading/unloading an application does not load/unload the code
- used by the application. Code loading is done the usual way.</p>
+ used by the application. Code loading is done the usual way.</p>
</note>
</section>
@@ -252,13 +252,14 @@ ok
{stdlib,"ERTS CXC 138 10","1.11.4.3"},
{ch_app,"Channel allocator","1"}]</pre>
<p>If the application is not already loaded, the application
- controller will first load it using <c>application:load/1</c>. It
- will check the value of the <c>applications</c> key, to ensure
- that all applications that should be started before this
+ controller first loads it using <c>application:load/1</c>. It
+ checks the value of the <c>applications</c> key, to ensure
+ that all applications that are to be started before this
application are running.</p>
<marker id="application_master"></marker>
- <p>The application controller then creates an <em>application master</em> for the application. The application master is
- the group leader of all the processes in the application.
+ <p>The application controller then creates an
+ <em>application master</em> for the application. The application master
+ is the group leader of all the processes in the application.
The application master starts the application by calling
the application callback function <c>start/2</c> in the module,
and with the start argument, defined by the <c>mod</c> key in
@@ -268,8 +269,8 @@ ok
7> <input>application:stop(ch_app).</input>
ok</pre>
<p>The application master stops the application by telling the top
- supervisor to shutdown. The top supervisor tells all its child
- processes to shutdown etc. and the entire tree is terminated in
+ supervisor to shut down. The top supervisor tells all its child
+ processes to shut down, and so on; the entire tree is terminated in
reversed start order. The application master then calls
the application callback function <c>stop/1</c> in the module
defined by the <c>mod</c> key.</p>
@@ -277,8 +278,10 @@ ok</pre>
<section>
<title>Configuring an Application</title>
- <p>An application can be configured using <em>configuration parameters</em>. These are a list of <c>{Par, Val}</c> tuples
- specified by a key <c>env</c> in the <c>.app</c> file.</p>
+ <p>An application can be configured using
+ <em>configuration parameters</em>. These are a list of
+ <c>{Par,Val}</c> tuples
+ specified by a key <c>env</c> in the <c>.app</c> file:</p>
<code type="none">
{application, ch_app,
[{description, "Channel allocator"},
@@ -289,11 +292,12 @@ ok</pre>
{mod, {ch_app,[]}},
{env, [{file, "/usr/local/log"}]}
]}.</code>
- <p><c>Par</c> should be an atom, <c>Val</c> is any term.
+ <p><c>Par</c> is to be an atom. <c>Val</c> is any term.
The application can retrieve the value of a configuration
parameter by calling <c>application:get_env(App, Par)</c> or a
- number of similar functions, see <c>application(3)</c>.</p>
- <p>Example:</p>
+ number of similar functions, see the <c>application(3)</c>
+ manual page in Kernel.</p>
+ <p><em>Example:</em></p>
<pre>
% <input>erl</input>
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
@@ -304,20 +308,21 @@ ok
2> <input>application:get_env(ch_app, file).</input>
{ok,"/usr/local/log"}</pre>
<p>The values in the <c>.app</c> file can be overridden by values
- in a <em>system configuration file</em>. This is a file which
+ in a <em>system configuration file</em>. This is a file that
contains configuration parameters for relevant applications:</p>
<code type="none">
[{Application1, [{Par11,Val11},...]},
...,
{ApplicationN, [{ParN1,ValN1},...]}].</code>
- <p>The system configuration should be called <c>Name.config</c> and
- Erlang should be started with the command line argument
- <c>-config Name</c>. See <c>config(4)</c> for more information.</p>
- <p>Example: A file <c>test.config</c> is created with the following
- contents:</p>
+ <p>The system configuration is to be called <c>Name.config</c> and
+ Erlang is to be started with the command-line argument
+ <c>-config Name</c>. For details, see the <c>config(4)</c>
+ manual page in Kernel.</p>
+ <p><em>Example:</em></p>
+ <p>A file <c>test.config</c> is created with the following contents:</p>
<code type="none">
[{ch_app, [{file, "testlog"}]}].</code>
- <p>The value of <c>file</c> will override the value of <c>file</c>
+ <p>The value of <c>file</c> overrides the value of <c>file</c>
as defined in the <c>.app</c> file:</p>
<pre>
% <input>erl -config test</input>
@@ -330,14 +335,14 @@ ok
{ok,"testlog"}</pre>
<p>If
<seealso marker="release_handling#sys">release handling</seealso>
- is used, exactly one system configuration file should be used and
- that file should be called <c>sys.config</c></p>
- <p>The values in the <c>.app</c> file, as well as the values in a
- system configuration file, can be overridden directly from
+ is used, exactly one system configuration file is to be used and
+ that file is to be called <c>sys.config</c>.</p>
+ <p>The values in the <c>.app</c> file and the values in a
+ system configuration file can be overridden directly from
the command line:</p>
<pre>
% <input>erl -ApplName Par1 Val1 ... ParN ValN</input></pre>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
% <input>erl -ch_app file '"testlog"'</input>
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
@@ -368,10 +373,10 @@ application:start(Application, Type)</code>
<item>If a temporary application terminates, this is reported but
no other applications are terminated.</item>
</list>
- <p>It is always possible to stop an application explicitly by
+ <p>An application can always be stopped explicitly by
calling <c>application:stop/1</c>. Regardless of the mode, no
- other applications will be affected.</p>
- <p>Note that transient mode is of little practical use, since when
+ other applications are affected.</p>
+ <p>The transient mode is of little practical use, since when
a supervision tree terminates, the reason is set to
<c>shutdown</c>, not <c>normal</c>.</p>
</section>
diff --git a/system/doc/design_principles/appup_cookbook.xml b/system/doc/design_principles/appup_cookbook.xml
index 70c34a5a06..31335197d7 100644
--- a/system/doc/design_principles/appup_cookbook.xml
+++ b/system/doc/design_principles/appup_cookbook.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,15 +29,15 @@
<rev></rev>
<file>appup_cookbook.xml</file>
</header>
- <p>This chapter contains examples of <c>.appup</c> files for
- typical cases of upgrades/downgrades done in run-time.</p>
+ <marker id="appup cookbook"></marker>
+ <p>This section includes examples of <c>.appup</c> files for
+ typical cases of upgrades/downgrades done in runtime.</p>
<section>
<title>Changing a Functional Module</title>
- <p>When a change has been made to a functional module, for example
+ <p>When a functional module has been changed, for example,
if a new function has been added or a bug has been corrected,
- simple code replacement is sufficient.</p>
- <p>Example:</p>
+ simple code replacement is sufficient, for example:</p>
<code type="none">
{"2",
[{"1", [{load_module, m}]}],
@@ -46,29 +47,31 @@
<section>
<title>Changing a Residence Module</title>
- <p>In a system implemented according to the OTP Design Principles,
+ <p>In a system implemented according to the OTP design principles,
all processes, except system processes and special processes,
reside in one of the behaviours <c>supervisor</c>,
- <c>gen_server</c>, <c>gen_fsm</c> or <c>gen_event</c>. These
+ <c>gen_server</c>, <c>gen_fsm</c>, or <c>gen_event</c>. These
belong to the STDLIB application and upgrading/downgrading
normally requires an emulator restart.</p>
- <p>OTP thus provides no support for changing residence modules
- except in the case of <seealso marker="#spec">special processes</seealso>.</p>
+ <p>OTP thus provides no support for changing residence modules except
+ in the case of <seealso marker="#spec">special processes</seealso>.</p>
</section>
<section>
<title>Changing a Callback Module</title>
- <p>A callback module is a functional module, and for code
+ <p>A callback module is a functional module, and for code
extensions simple code replacement is sufficient.</p>
- <p>Example: When adding a function to <c>ch3</c> as described in
- the example in <seealso marker="release_handling#appup">Release Handling</seealso>, <c>ch_app.appup</c> looks as follows:</p>
+ <p><em>Example:</em> When adding a function to <c>ch3</c>,
+ as described in the example in
+ <seealso marker="release_handling#appup">Release Handling</seealso>,
+ <c>ch_app.appup</c> looks as follows:</p>
<code type="none">
{"2",
[{"1", [{load_module, ch3}]}],
[{"1", [{load_module, ch3}]}]
}.</code>
<p>OTP also supports changing the internal state of behaviour
- processes, see <seealso marker="#int_state">Changing Internal State</seealso> below.</p>
+ processes, see <seealso marker="#int_state">Changing Internal State</seealso>.</p>
</section>
<section>
@@ -77,26 +80,28 @@
<p>In this case, simple code replacement is not sufficient.
The process must explicitly transform its state using the callback
function <c>code_change</c> before switching to the new version
- of the callback module. Thus synchronized code replacement is
+ of the callback module. Thus, synchronized code replacement is
used.</p>
- <p>Example: Consider the gen_server <c>ch3</c> from the chapter
- about the <seealso marker="gen_server_concepts#ex">gen_server behaviour</seealso>. The internal state is a term <c>Chs</c>
- representing the available channels. Assume we want add a counter
- <c>N</c> which keeps track of the number of <c>alloc</c> requests
- so far. This means we need to change the format to
+ <p><em>Example:</em> Consider <c>gen_server</c> <c>ch3</c> from
+ <seealso marker="gen_server_concepts#ex">gen_server Behaviour</seealso>.
+ The internal state is a term <c>Chs</c>
+ representing the available channels. Assume you want to add a counter
+ <c>N</c>, which keeps track of the number of <c>alloc</c> requests
+ so far. This means that the format must be changed to
<c>{Chs,N}</c>.</p>
- <p>The <c>.appup</c> file could look as follows:</p>
+ <p>The <c>.appup</c> file can look as follows:</p>
<code type="none">
{"2",
[{"1", [{update, ch3, {advanced, []}}]}],
[{"1", [{update, ch3, {advanced, []}}]}]
}.</code>
<p>The third element of the <c>update</c> instruction is a tuple
- <c>{advanced,Extra}</c> which says that the affected processes
- should do a state transformation before loading the new version
+ <c>{advanced,Extra}</c>, which says that the affected processes
+ are to do a state transformation before loading the new version
of the module. This is done by the processes calling the callback
- function <c>code_change</c> (see <c>gen_server(3)</c>). The term
- <c>Extra</c>, in this case [], is passed as-is to the function:</p>
+ function <c>code_change</c> (see the <c>gen_server(3)</c> manual
+ page in STDLIB). The term <c>Extra</c>, in this case
+ <c>[]</c>, is passed as is to the function:</p>
<marker id="code_change"></marker>
<code type="none">
-module(ch3).
@@ -107,40 +112,41 @@ code_change({down, _Vsn}, {Chs, N}, _Extra) ->
{ok, Chs};
code_change(_Vsn, Chs, _Extra) ->
{ok, {Chs, 0}}.</code>
- <p>The first argument is <c>{down,Vsn}</c> in case of a downgrade,
- or <c>Vsn</c> in case of an upgrade. The term <c>Vsn</c> is
- fetched from the 'original' version of the module, i.e.
- the version we are upgrading from, or downgrading to.</p>
+ <p>The first argument is <c>{down,Vsn}</c> if there is a downgrade,
+ or <c>Vsn</c> if there is a upgrade. The term <c>Vsn</c> is
+ fetched from the 'original' version of the module, that is,
+ the version you are upgrading from, or downgrading to.</p>
<p>The version is defined by the module attribute <c>vsn</c>, if
any. There is no such attribute in <c>ch3</c>, so in this case
- the version is the checksum (a huge integer) of the BEAM file, an
- uninteresting value which is ignored.</p>
- <p>(The other callback functions of <c>ch3</c> need to be modified
- as well and perhaps a new interface function added, this is not
- shown here).</p>
+ the version is the checksum (a huge integer) of the beam file, an
+ uninteresting value, which is ignored.</p>
+ <p>The other callback functions of <c>ch3</c> must also be modified
+ and perhaps a new interface function must be added, but this is not
+ shown here.</p>
</section>
<section>
<title>Module Dependencies</title>
- <p>Assume we extend a module by adding a new interface function, as
- in the example in <seealso marker="release_handling#appup">Release Handling</seealso>, where a function <c>available/0</c> is
- added to <c>ch3</c>.</p>
- <p>If we also add a call to this function, say in the module
- <c>m1</c>, a run-time error could occur during release upgrade if
+ <p>Assume that a module is extended by adding an interface function,
+ as in the example in
+ <seealso marker="release_handling#appup">Release Handling</seealso>,
+ where a function <c>available/0</c> is added to <c>ch3</c>.</p>
+ <p>If a call is added to this function, say in module
+ <c>m1</c>, a runtime error could can occur during release upgrade if
the new version of <c>m1</c> is loaded first and calls
<c>ch3:available/0</c> before the new version of <c>ch3</c> is
loaded.</p>
- <p>Thus, <c>ch3</c> must be loaded before <c>m1</c> is, in
- the upgrade case, and vice versa in the downgrade case. We say
- that <c>m1</c><em>is dependent on</em><c>ch3</c>. In a release
- handling instruction, this is expressed by the element
- <c>DepMods</c>:</p>
+ <p>Thus, <c>ch3</c> must be loaded before <c>m1</c>, in
+ the upgrade case, and conversely in the downgrade case.
+ <c>m1</c> is said to be <em>dependent on</em> <c>ch3</c>. In a release
+ handling instruction, this is expressed by the
+ <c>DepMods</c> element:</p>
<code type="none">
{load_module, Module, DepMods}
{update, Module, {advanced, Extra}, DepMods}</code>
<p><c>DepMods</c> is a list of modules, on which <c>Module</c> is
dependent.</p>
- <p>Example: The module <c>m1</c> in the application <c>myapp</c> is
+ <p><em>Example:</em> The module <c>m1</c> in application <c>myapp</c> is
dependent on <c>ch3</c> when upgrading from "1" to "2", or
downgrading from "2" to "1":</p>
<code type="none">
@@ -157,8 +163,8 @@ ch_app.appup:
[{"1", [{load_module, ch3}]}],
[{"1", [{load_module, ch3}]}]
}.</code>
- <p>If <c>m1</c> and <c>ch3</c> had belonged to the same application,
- the <c>.appup</c> file could have looked like this:</p>
+ <p>If instead <c>m1</c> and <c>ch3</c> belong to the same application,
+ the <c>.appup</c> file can look as follows:</p>
<code type="none">
{"2",
[{"1",
@@ -168,48 +174,48 @@ ch_app.appup:
[{load_module, ch3},
{load_module, m1, [ch3]}]}]
}.</code>
- <p>Note that it is <c>m1</c> that is dependent on <c>ch3</c> also
+ <p><c>m1</c> is dependent on <c>ch3</c> also
when downgrading. <c>systools</c> knows the difference between
- up- and downgrading and will generate a correct <c>relup</c>,
- where <c>ch3</c> is loaded before <c>m1</c> when upgrading but
+ up- and downgrading and generates a correct <c>relup</c>,
+ where <c>ch3</c> is loaded before <c>m1</c> when upgrading, but
<c>m1</c> is loaded before <c>ch3</c> when downgrading.</p>
</section>
<section>
<marker id="spec"></marker>
- <title>Changing Code For a Special Process</title>
+ <title>Changing Code for a Special Process</title>
<p>In this case, simple code replacement is not sufficient.
When a new version of a residence module for a special process
is loaded, the process must make a fully qualified call to
- its loop function to switch to the new code. Thus synchronized
+ its loop function to switch to the new code. Thus, synchronized
code replacement must be used.</p>
<note>
<p>The name(s) of the user-defined residence module(s) must be
listed in the <c>Modules</c> part of the child specification
- for the special process, in order for the release handler to
+ for the special process. Otherwise the release handler cannot
find the process.</p>
</note>
- <p>Example. Consider the example <c>ch4</c> from the chapter about
+ <p><em>Example:</em> Consider the example <c>ch4</c> in
<seealso marker="spec_proc#ex">sys and proc_lib</seealso>.
- When started by a supervisor, the child specification could look
- like this:</p>
+ When started by a supervisor, the child specification can look
+ as follows:</p>
<code type="none">
{ch4, {ch4, start_link, []},
permanent, brutal_kill, worker, [ch4]}</code>
<p>If <c>ch4</c> is part of the application <c>sp_app</c> and a new
- version of the module should be loaded when upgrading from
- version "1" to "2" of this application, <c>sp_app.appup</c> could
- look like this:</p>
+ version of the module is to be loaded when upgrading from
+ version "1" to "2" of this application, <c>sp_app.appup</c> can
+ look as follows:</p>
<code type="none">
{"2",
[{"1", [{update, ch4, {advanced, []}}]}],
[{"1", [{update, ch4, {advanced, []}}]}]
}.</code>
<p>The <c>update</c> instruction must contain the tuple
- <c>{advanced,Extra}</c>. The instruction will make the special
+ <c>{advanced,Extra}</c>. The instruction makes the special
process call the callback function <c>system_code_change/4</c>, a
function the user must implement. The term <c>Extra</c>, in this
- case [], is passed as-is to <c>system_code_change/4</c>:</p>
+ case <c>[]</c>, is passed as is to <c>system_code_change/4</c>:</p>
<code type="none">
-module(ch4).
...
@@ -218,39 +224,43 @@ ch_app.appup:
system_code_change(Chs, _Module, _OldVsn, _Extra) ->
{ok, Chs}.</code>
- <p>The first argument is the internal state <c>State</c> passed from
- the function <c>sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</c>, called by the special process when
- a system message is received. In <c>ch4</c>, the internal state is
- the set of available channels <c>Chs</c>.</p>
- <p>The second argument is the name of the module (<c>ch4</c>).</p>
- <p>The third argument is <c>Vsn</c> or <c>{down,Vsn}</c> as
- described for
- <seealso marker="#code_change">gen_server:code_change/3</seealso>.</p>
+ <list type="bulleted">
+ <item>The first argument is the internal state <c>State</c>,
+ passed from function
+ <c>sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</c>,
+ and called by the special process when a system message is received.
+ In <c>ch4</c>, the internal state is the set of available channels
+ <c>Chs</c>.</item>
+ <item>The second argument is the name of the module
+ (<c>ch4</c>).</item>
+ <item>The third argument is <c>Vsn</c> or <c>{down,Vsn}</c>, as
+ described for <c>gen_server:code_change/3</c> in
+ <seealso marker="#code_change">Changing Internal State</seealso>.</item>
+ </list>
<p>In this case, all arguments but the first are ignored and
the function simply returns the internal state again. This is
- enough if the code only has been extended. If we had wanted to
- change the internal state (similar to the example in
+ enough if the code only has been extended. If instead the
+ internal state is changed (similar to the example in
<seealso marker="#int_state">Changing Internal State</seealso>),
- it would have been done in this function and
- <c>{ok,Chs2}</c> returned.</p>
+ this is done in this function and <c>{ok,Chs2}</c> returned.</p>
</section>
<section>
<marker id="sup"></marker>
<title>Changing a Supervisor</title>
<p>The supervisor behaviour supports changing the internal state,
- i.e. changing restart strategy and maximum restart frequency
- properties, as well as changing existing child specifications.</p>
- <p>Adding and deleting child processes are also possible, but not
+ that is, changing the restart strategy and maximum restart frequency
+ properties, as well as changing the existing child specifications.</p>
+ <p>Child processes can be added or deleted, but this is not
handled automatically. Instructions must be given by in
the <c>.appup</c> file.</p>
<section>
<title>Changing Properties</title>
- <p>Since the supervisor should change its internal state,
+ <p>Since the supervisor is to change its internal state,
synchronized code replacement is required. However,
a special <c>update</c> instruction must be used.</p>
- <p>The new version of the callback module must be loaded first
+ <p>First, the new version of the callback module must be loaded,
both in the case of upgrade and downgrade. Then the new return
value of <c>init/1</c> can be checked and the internal state be
changed accordingly.</p>
@@ -258,16 +268,17 @@ system_code_change(Chs, _Module, _OldVsn, _Extra) ->
supervisors:</p>
<code type="none">
{update, Module, supervisor}</code>
- <p>Example: Assume we want to change the restart strategy of
- <c>ch_sup</c> from the <seealso marker="sup_princ#ex">Supervisor Behaviour</seealso> chapter from one_for_one to one_for_all.
- We change the callback function <c>init/1</c> in
- <c>ch_sup.erl</c>:</p>
+ <p><em>Example:</em> To change the restart strategy of
+ <c>ch_sup</c> (from
+ <seealso marker="sup_princ#ex">Supervisor Behaviour</seealso>)
+ from <c>one_for_one</c> to <c>one_for_all</c>, change the callback
+ function <c>init/1</c> in <c>ch_sup.erl</c>:</p>
<code type="none">
-module(ch_sup).
...
init(_Args) ->
- {ok, {{one_for_all, 1, 60}, ...}}.</code>
+ {ok, {#{strategy => one_for_all, ...}, ...}}.</code>
<p>The file <c>ch_app.appup</c>:</p>
<code type="none">
{"2",
@@ -280,7 +291,7 @@ init(_Args) ->
<title>Changing Child Specifications</title>
<p>The instruction, and thus the <c>.appup</c> file, when
changing an existing child specification, is the same as when
- changing properties as described above:</p>
+ changing properties as described earlier:</p>
<code type="none">
{"2",
[{"1", [{update, ch_sup, supervisor}]}],
@@ -288,25 +299,25 @@ init(_Args) ->
}.</code>
<p>The changes do not affect existing child processes. For
example, changing the start function only specifies how
- the child process should be restarted, if needed later on.</p>
- <p>Note that the id of the child specification cannot be changed.</p>
- <p>Note also that changing the <c>Modules</c> field of the child
- specification may affect the release handling process itself,
+ the child process is to be restarted, if needed later on.</p>
+ <p>The id of the child specification cannot be changed.</p>
+ <p>Changing the <c>Modules</c> field of the child
+ specification can affect the release handling process itself,
as this field is used to identify which processes are affected
when doing a synchronized code replacement.</p>
</section>
<marker id="sup_add"></marker>
<section>
- <title>Adding And Deleting Child Processes</title>
- <p>As stated above, changing child specifications does not affect
+ <title>Adding and Deleting Child Processes</title>
+ <p>As stated earlier, changing child specifications does not affect
existing child processes. New child specifications are
- automatically added, but not deleted. Also, child processes are
- not automatically started or terminated. Instead, this must be
- done explicitly using <c>apply</c> instructions.</p>
- <p>Example: Assume we want to add a new child process <c>m1</c> to
- <c>ch_sup</c> when upgrading <c>ch_app</c> from "1" to "2".
- This means <c>m1</c> should be deleted when downgrading from
+ automatically added, but not deleted. Child processes are
+ not automatically started or terminated, this must be
+ done using <c>apply</c> instructions.</p>
+ <p><em>Example:</em> Assume a new child process <c>m1</c> is to be
+ added to <c>ch_sup</c> when upgrading <c>ch_app</c> from "1" to "2".
+ This means <c>m1</c> is to be deleted when downgrading from
"2" to "1":</p>
<code type="none">
{"2",
@@ -320,13 +331,13 @@ init(_Args) ->
{update, ch_sup, supervisor}
]}]
}.</code>
- <p>Note that the order of the instructions is important.</p>
- <p>Note also that the supervisor must be registered as
+ <p>The order of the instructions is important.</p>
+ <p>The supervisor must be registered as
<c>ch_sup</c> for the script to work. If the supervisor is not
registered, it cannot be accessed directly from the script.
Instead a help function that finds the pid of the supervisor
- and calls <c>supervisor:restart_child</c> etc. must be written,
- and it is this function that should be called from the script
+ and calls <c>supervisor:restart_child</c>, and so on, must be
+ written. This function is then to be called from the script
using the <c>apply</c> instruction.</p>
<p>If the module <c>m1</c> is introduced in version "2" of
<c>ch_app</c>, it must also be loaded when upgrading and
@@ -345,18 +356,18 @@ init(_Args) ->
{delete_module, m1}
]}]
}.</code>
- <p>Note again that the order of the instructions is important.
- When upgrading, <c>m1</c> must be loaded and the supervisor's
+ <p>As stated earlier, the order of the instructions is important.
+ When upgrading, <c>m1</c> must be loaded, and the supervisor
child specification changed, before the new child process can
be started. When downgrading, the child process must be
- terminated before child specification is changed and the module
+ terminated before the child specification is changed and the module
is deleted.</p>
</section>
</section>
<section>
<title>Adding or Deleting a Module</title>
- <p>Example: A new functional module <c>m</c> is added to
+ <p><em>Example:</em> A new functional module <c>m</c> is added to
<c>ch_app</c>:</p>
<code type="none">
{"2",
@@ -367,15 +378,16 @@ init(_Args) ->
<section>
<title>Starting or Terminating a Process</title>
<p>In a system structured according to the OTP design principles,
- any process would be a child process belonging to a supervisor,
- see <seealso marker="#sup_add">Adding and Deleting Child Processes</seealso> above.</p>
+ any process would be a child process belonging to a supervisor, see
+ <seealso marker="#sup_add">Adding and Deleting Child Processes</seealso>
+ in Changing a Supervisor.</p>
</section>
<section>
<title>Adding or Removing an Application</title>
<p>When adding or removing an application, no <c>.appup</c> file
is needed. When generating <c>relup</c>, the <c>.rel</c> files
- are compared and <c>add_application</c> and
+ are compared and the <c>add_application</c> and
<c>remove_application</c> instructions are added automatically.</p>
</section>
@@ -383,11 +395,11 @@ init(_Args) ->
<title>Restarting an Application</title>
<p>Restarting an application is useful when a change is too
complicated to be made without restarting the processes, for
- example if the supervisor hierarchy has been restructured.</p>
- <p>Example: When adding a new child <c>m1</c> to <c>ch_sup</c>, as
- in the <seealso marker="#sup_add">example above</seealso>, an
- alternative to updating the supervisor is to restart the entire
- application:</p>
+ example, if the supervisor hierarchy has been restructured.</p>
+ <p><em>Example:</em> When adding a child <c>m1</c> to <c>ch_sup</c>, as in
+ <seealso marker="#sup_add">Adding and Deleting Child Processes</seealso>
+ in Changing a Supervisor, an alternative to updating
+ the supervisor is to restart the entire application:</p>
<code type="none">
{"2",
[{"1", [{restart_application, ch_app}]}],
@@ -400,7 +412,7 @@ init(_Args) ->
<title>Changing an Application Specification</title>
<p>When installing a release, the application specifications are
automatically updated before evaluating the <c>relup</c> script.
- Hence, no instructions are needed in the <c>.appup</c> file:</p>
+ Thus, no instructions are needed in the <c>.appup</c> file:</p>
<pre>
{"2",
[{"1", []}],
@@ -412,28 +424,29 @@ init(_Args) ->
<title>Changing Application Configuration</title>
<p>Changing an application configuration by updating the <c>env</c>
key in the <c>.app</c> file is an instance of changing an
- application specification, <seealso marker="#app_spec">see above</seealso>.</p>
+ application specification, see the previous section.</p>
<p>Alternatively, application configuration parameters can be
added or updated in <c>sys.config</c>.</p>
</section>
<section>
<title>Changing Included Applications</title>
- <p>The release handling instructions for adding, removing and
+ <p>The release handling instructions for adding, removing, and
restarting applications apply to primary applications only.
There are no corresponding instructions for included
applications. However, since an included application is really a
supervision tree with a topmost supervisor, started as a child
process to a supervisor in the including application, a
<c>relup</c> file can be manually created.</p>
- <p>Example: Assume we have a release containing an application
- <c>prim_app</c> which have a supervisor <c>prim_sup</c> in its
+ <p><em>Example:</em> Assume there is a release containing an application
+ <c>prim_app</c>, which have a supervisor <c>prim_sup</c> in its
supervision tree.</p>
- <p>In a new version of the release, our example application
- <c>ch_app</c> should be included in <c>prim_app</c>. That is,
- its topmost supervisor <c>ch_sup</c> should be started as a child
+ <p>In a new version of the release, the application <c>ch_app</c>
+ is to be included in <c>prim_app</c>. That is,
+ its topmost supervisor <c>ch_sup</c> is to be started as a child
process to <c>prim_sup</c>.</p>
- <p>1) Edit the code for <c>prim_sup</c>:</p>
+ <p>The workflow is as follows:</p>
+ <p><em>Step 1)</em> Edit the code for <c>prim_sup</c>:</p>
<code type="none">
init(...) ->
{ok, {...supervisor flags...,
@@ -441,7 +454,7 @@ init(...) ->
{ch_sup, {ch_sup,start_link,[]},
permanent,infinity,supervisor,[ch_sup]},
...]}}.</code>
- <p>2) Edit the <c>.app</c> file for <c>prim_app</c>:</p>
+ <p><em>Step 2)</em> Edit the <c>.app</c> file for <c>prim_app</c>:</p>
<code type="none">
{application, prim_app,
[...,
@@ -450,27 +463,29 @@ init(...) ->
{included_applications, [ch_app]},
...
]}.</code>
- <p>3) Create a new <c>.rel</c> file, including <c>ch_app</c>:</p>
+ <p><em>Step 3)</em> Create a new <c>.rel</c> file, including
+ <c>ch_app</c>:</p>
<code type="none">
{release,
...,
[...,
{prim_app, "2"},
{ch_app, "1"}]}.</code>
+ <p>The included application can be started in two ways.
+ This is described in the next two sections.</p>
<section>
<title>Application Restart</title>
- <p>4a) One way to start the included application is to restart
- the entire <c>prim_app</c> application. Normally, we would then
- use the <c>restart_application</c> instruction in
- the <c>.appup</c> file for <c>prim_app</c>.</p>
- <p>However, if we did this and then generated a <c>relup</c> file,
- not only would it contain instructions for restarting (i.e.
+ <p><em>Step 4a)</em> One way to start the included application is to
+ restart the entire <c>prim_app</c> application. Normally, the
+ <c>restart_application</c> instruction in the <c>.appup</c> file
+ for <c>prim_app</c> would be used.</p>
+ <p>However, if this is done and a <c>relup</c> file is generated,
+ not only would it contain instructions for restarting (that is,
removing and adding) <c>prim_app</c>, it would also contain
instructions for starting <c>ch_app</c> (and stopping it, in
- the case of downgrade). This is due to the fact that
- <c>ch_app</c> is included in the new <c>.rel</c> file, but not
- in the old one.</p>
+ the case of downgrade). This is because <c>ch_app</c> is included
+ in the new <c>.rel</c> file, but not in the old one.</p>
<p>Instead, a correct <c>relup</c> file can be created manually,
either from scratch or by editing the generated version.
The instructions for starting/stopping <c>ch_app</c> are
@@ -512,7 +527,8 @@ init(...) ->
<section>
<title>Supervisor Change</title>
- <p>4b) Another way to start the included application (or stop it
+ <p><em>Step 4b)</em> Another way to start the included
+ application (or stop it
in the case of downgrade) is by combining instructions for
adding and removing child processes to/from <c>prim_sup</c> with
instructions for loading/unloading all <c>ch_app</c> code and
@@ -521,7 +537,7 @@ init(...) ->
scratch or by editing a generated version. Load all code for
<c>ch_app</c> first, and also load the application
specification, before <c>prim_sup</c> is updated. When
- downgrading, <c>prim_sup</c> should be updated first, before
+ downgrading, <c>prim_sup</c> is to updated first, before
the code for <c>ch_app</c> and its application specification
are unloaded.</p>
<code type="none">
@@ -560,10 +576,10 @@ init(...) ->
<section>
<title>Changing Non-Erlang Code</title>
<p>Changing code for a program written in another programming
- language than Erlang, for example a port program, is very
- application dependent and OTP provides no special support for it.</p>
- <p>Example, changing code for a port program: Assume that
- the Erlang process controlling the port is a gen_server
+ language than Erlang, for example, a port program, is
+ application-dependent and OTP provides no special support for it.</p>
+ <p><em>Example:</em> When changing code for a port program, assume that
+ the Erlang process controlling the port is a <c>gen_server</c>
<c>portc</c> and that the port is opened in the callback function
<c>init/1</c>:</p>
<code type="none">
@@ -573,10 +589,11 @@ init(...) ->
Port = open_port({spawn,PortPrg}, [...]),
...,
{ok, #state{port=Port, ...}}.</code>
- <p>If the port program should be updated, we can extend the code for
- the gen_server with a <c>code_change</c> function which closes
- the old port and opens a new port. (If necessary, the gen_server
- may first request data that needs to be saved from the port
+ <p>If the port program is to be updated, the code for the
+ <c>gen_server</c> can be extended with a <c>code_change</c> function,
+ which closes the old port and opens a new port.
+ (If necessary, the <c>gen_server</c> can
+ first request data that must be saved from the port
program and pass this data to the new port):</p>
<code type="none">
code_change(_OldVsn, State, port) ->
@@ -595,8 +612,8 @@ code_change(_OldVsn, State, port) ->
[{"1", [{update, portc, {advanced,port}}]}],
[{"1", [{update, portc, {advanced,port}}]}]
].</code>
- <p>Make sure the <c>priv</c> directory where the C program is
- located is included in the new release package:</p>
+ <p>Ensure that the <c>priv</c> directory, where the C program is
+ located, is included in the new release package:</p>
<pre>
1> <input>systools:make_tar("my_release", [{dirs,[priv]}]).</input>
...</pre>
@@ -604,28 +621,29 @@ code_change(_OldVsn, State, port) ->
<section>
<title>Emulator Restart and Upgrade</title>
- <p>There are two upgrade instructions that will restart the emulator:</p>
- <taglist>
- <tag><c>restart_new_emulator</c></tag>
- <item>Intended for when erts, kernel, stdlib or sasl is
- upgraded. It is automatically added when the relup file is
- generated by <c>systools:make_relup/3,4</c>. It is executed
- before all other upgrade instructions. See
- <seealso marker="release_handling#restart_new_emulator_instr">Release
- Handling</seealso> for more information about this
- instruction.</item>
- <tag><c>restart_emulator</c></tag>
- <item>Used when a restart of the emulator is required after all
- other upgrade instructions are executed. See
- <seealso marker="release_handling#restart_emulator_instr">Release
- Handling</seealso> for more information about this
- instruction.</item>
- </taglist>
-
+ <p>Two upgrade instructions restart the emulator:</p>
+ <list type="bulleted">
+ <item><p><c>restart_new_emulator</c></p>
+ <p>Intended when ERTS, Kernel, STDLIB, or
+ SASL is upgraded. It is automatically added when the
+ <c>relup</c> file is generated by <c>systools:make_relup/3,4</c>.
+ It is executed before all other upgrade instructions.
+ For more information about this instruction, see
+ restart_new_emulator (Low-Level) in
+ <seealso marker="release_handling#restart_new_emulator_instr">Release Handling Instructions</seealso>.
+ </p></item>
+ <item><p><c>restart_emulator</c></p>
+ <p>Used when a restart of the emulator is required after all
+ other upgrade instructions are executed.
+ For more information about this instruction, see
+ restart_emulator (Low-Level) in
+ <seealso marker="release_handling#restart_emulator_instr">Release Handling Instructions</seealso>.
+ </p></item>
+ </list>
<p>If an emulator restart is necessary and no upgrade instructions
- are needed, i.e. if the restart itself is enough for the
- upgraded applications to start running the new versions, a very
- simple <c>.relup</c> file can be created manually:</p>
+ are needed, that is, if the restart itself is enough for the
+ upgraded applications to start running the new versions, a
+ simple <c>relup</c> file can be created manually:</p>
<code type="none">
{"B",
[{"A",
@@ -637,26 +655,27 @@ code_change(_OldVsn, State, port) ->
}.</code>
<p>In this case, the release handler framework with automatic
packing and unpacking of release packages, automatic path
- updates etc. can be used without having to specify <c>.appup</c>
- files.</p>
+ updates, and so on, can be used without having to specify
+ <c>.appup</c> files.</p>
</section>
<section>
- <title>Emulator Upgrade from pre OTP R15</title>
+ <title>Emulator Upgrade From Pre OTP R15</title>
<p>From OTP R15, an emulator upgrade is performed by restarting
the emulator with new versions of the core applications
- (<c>kernel</c>, <c>stdlib</c> and <c>sasl</c>) before loading code
+ (Kernel, STDLIB, and SASL) before loading code
and running upgrade instruction for other applications. For this
- to work, the release to upgrade from must includes OTP R15 or
- later. For the case where the release to upgrade from includes an
- earlier emulator version, <c>systools:make_relup</c> will create a
+ to work, the release to upgrade from must include OTP R15 or
+ later.</p>
+ <p>For the case where the release to upgrade from includes an
+ earlier emulator version, <c>systools:make_relup</c> creates a
backwards compatible relup file. This means that all upgrade
- instructions will be executed before the emulator is
- restarted. The new application code will therefore be loaded into
+ instructions are executed before the emulator is
+ restarted. The new application code is therefore loaded into
the old emulator. If the new code is compiled with the new
- emulator, there might be cases where the beam format has changed
- and beam files can not be loaded. To overcome this problem, the
- new code should be compiled with the old emulator.</p>
+ emulator, there can be cases where the beam format has changed
+ and beam files cannot be loaded. To overcome this problem, compile
+ the new code with the old emulator.</p>
</section>
</chapter>
diff --git a/system/doc/design_principles/book.xml b/system/doc/design_principles/book.xml
index b583df0bf0..663551df2f 100644
--- a/system/doc/design_principles/book.xml
+++ b/system/doc/design_principles/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/design_principles/des_princ.xml b/system/doc/design_principles/des_princ.xml
index e8f289b905..0e087cf843 100644
--- a/system/doc/design_principles/des_princ.xml
+++ b/system/doc/design_principles/des_princ.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,50 +29,52 @@
<rev></rev>
<file>des_princ.xml</file>
</header>
- <p>The <em>OTP Design Principles</em> is a set of principles for how
- to structure Erlang code in terms of processes, modules and
- directories.</p>
+ <marker id="otp design principles"></marker>
+ <p>The <em>OTP design principles</em> define how to
+ structure Erlang code in terms of processes, modules,
+ and directories.</p>
<section>
<title>Supervision Trees</title>
<p>A basic concept in Erlang/OTP is the <em>supervision tree</em>.
This is a process structuring model based on the idea of
- <em>workers</em> and <em>supervisors</em>.</p>
+ <em>workers</em> and <em>supervisors</em>:</p>
<list type="bulleted">
- <item>Workers are processes which perform computations, that is,
+ <item>Workers are processes that perform computations, that is,
they do the actual work.</item>
- <item>Supervisors are processes which monitor the behaviour of
+ <item>Supervisors are processes that monitor the behaviour of
workers. A supervisor can restart a worker if something goes
wrong.</item>
<item>The supervision tree is a hierarchical arrangement of
- code into supervisors and workers, making it possible to
+ code into supervisors and workers, which makes it possible to
design and program fault-tolerant software.</item>
</list>
+ <p>In the following figure, square boxes represents supervisors and
+ circles represent workers:</p>
<marker id="sup6"></marker>
<image file="../design_principles/sup6.gif">
<icaption>Supervision Tree</icaption>
</image>
- <p>In the figure above, square boxes represents supervisors and
- circles represent workers.</p>
</section>
<section>
<title>Behaviours</title>
<p>In a supervision tree, many of the processes have similar
structures, they follow similar patterns. For example,
- the supervisors are very similar in structure. The only difference
- between them is which child processes they supervise. Also, many
- of the workers are servers in a server-client relation, finite
- state machines, or event handlers such as error loggers.</p>
+ the supervisors are similar in structure. The only difference
+ between them is which child processes they supervise. Many
+ of the workers are servers in a server-client relation,
+ finite-state machines, or event handlers such as error loggers.</p>
<p><em>Behaviours</em> are formalizations of these common patterns.
The idea is to divide the code for a process in a generic part
- (a behaviour module) and a specific part (a <em>callback module</em>).</p>
+ (a behaviour module) and a specific part (a
+ <em>callback module</em>).</p>
<p>The behaviour module is part of Erlang/OTP. To implement a
process such as a supervisor, the user only has to implement
- the callback module which should export a pre-defined set of
+ the callback module which is to export a pre-defined set of
functions, the <em>callback functions</em>.</p>
- <p>An example to illustrate how code can be divided into a generic
- and a specific part: Consider the following code (written in
+ <p>The following example illustrate how code can be divided into a
+ generic and a specific part. Consider the following code (written in
plain Erlang) for a simple server, which keeps track of a number
of "channels". Other processes can allocate and free the channels
by calling the functions <c>alloc/0</c> and <c>free/1</c>,
@@ -149,7 +152,7 @@ loop(Mod, State) ->
State2 = Mod:handle_cast(Req, State),
loop(Mod, State2)
end.</code>
- <p>and a callback module <c>ch2.erl</c>:</p>
+ <p>And a callback module <c>ch2.erl</c>:</p>
<code type="none">
-module(ch2).
-export([start/0]).
@@ -173,27 +176,27 @@ handle_call(alloc, Chs) ->
handle_cast({free, Ch}, Chs) ->
free(Ch, Chs). % => Chs2</code>
- <p>Note the following:</p>
+ <p>Notice the following:</p>
<list type="bulleted">
- <item>The code in <c>server</c> can be re-used to build many
+ <item>The code in <c>server</c> can be reused to build many
different servers.</item>
- <item>The name of the server, in this example the atom
- <c>ch2</c>, is hidden from the users of the client functions.
- This means the name can be changed without affecting them.</item>
- <item>The protcol (messages sent to and received from the server)
- is hidden as well. This is good programming practice and allows
- us to change the protocol without making changes to code using
+ <item>The server name, in this example the atom
+ <c>ch2</c>, is hidden from the users of the client functions. This
+ means that the name can be changed without affecting them.</item>
+ <item>The protocol (messages sent to and received from the server)
+ is also hidden. This is good programming practice and allows
+ one to change the protocol without changing the code using
the interface functions.</item>
- <item>We can extend the functionality of <c>server</c>, without
+ <item>The functionality of <c>server</c> can be extended without
having to change <c>ch2</c> or any other callback module.</item>
</list>
- <p>(In <c>ch1.erl</c> and <c>ch2.erl</c> above, the implementation
- of <c>channels/0</c>, <c>alloc/1</c> and <c>free/2</c> has been
+ <p>In <c>ch1.erl</c> and <c>ch2.erl</c> above, the implementation
+ of <c>channels/0</c>, <c>alloc/1</c>, and <c>free/2</c> has been
intentionally left out, as it is not relevant to the example.
For completeness, one way to write these functions are given
- below. Note that this is an example only, a realistic
+ below. This is an example only, a realistic
implementation must be able to handle situations like running out
- of channels to allocate etc.)</p>
+ of channels to allocate, and so on.</p>
<code type="none">
channels() ->
{_Allocated = [], _Free = lists:seq(1,100)}.
@@ -208,30 +211,30 @@ free(Ch, {Alloc, Free} = Channels) ->
false ->
Channels
end. </code>
- <p>Code written without making use of behaviours may be more
- efficient, but the increased efficiency will be at the expense of
+ <p>Code written without using behaviours can be more
+ efficient, but the increased efficiency is at the expense of
generality. The ability to manage all applications in the system
- in a consistent manner is very important.</p>
+ in a consistent manner is important.</p>
<p>Using behaviours also makes it easier to read and understand
- code written by other programmers. Ad hoc programming structures,
+ code written by other programmers. Improvised programming structures,
while possibly more efficient, are always more difficult to
understand.</p>
- <p>The module <c>server</c> corresponds, greatly simplified,
+ <p>The <c>server</c> module corresponds, greatly simplified,
to the Erlang/OTP behaviour <c>gen_server</c>.</p>
<p>The standard Erlang/OTP behaviours are:</p>
- <taglist>
- <tag><seealso marker="gen_server_concepts">gen_server</seealso></tag>
- <item>For implementing the server of a client-server relation.</item>
- <tag><seealso marker="fsm">gen_fsm</seealso></tag>
- <item>For implementing finite state machines.</item>
- <tag><seealso marker="events">gen_event</seealso></tag>
- <item>For implementing event handling functionality.</item>
- <tag><seealso marker="sup_princ">supervisor</seealso></tag>
- <item>For implementing a supervisor in a supervision tree.</item>
- </taglist>
+ <list type="bulleted">
+ <item><p><seealso marker="gen_server_concepts">gen_server</seealso></p>
+ <p>For implementing the server of a client-server relation</p></item>
+ <item><p><seealso marker="fsm">gen_fsm</seealso></p>
+ <p>For implementing finite-state machines</p></item>
+ <item><p><seealso marker="events">gen_event</seealso></p>
+ <p>For implementing event handling functionality</p></item>
+ <item><p><seealso marker="sup_princ">supervisor</seealso></p>
+ <p>For implementing a supervisor in a supervision tree</p></item>
+ </list>
<p>The compiler understands the module attribute
<c>-behaviour(Behaviour)</c> and issues warnings about
- missing callback functions. Example:</p>
+ missing callback functions, for example:</p>
<code type="none">
-module(chs3).
-behaviour(gen_server).
@@ -248,13 +251,17 @@ free(Ch, {Alloc, Free} = Channels) ->
some specific functionality. Components are with Erlang/OTP
terminology called <em>applications</em>. Examples of Erlang/OTP
applications are Mnesia, which has everything needed for
- programming database services, and Debugger which is used to
- debug Erlang programs. The minimal system based on Erlang/OTP
- consists of the applications Kernel and STDLIB.</p>
+ programming database services, and Debugger, which is used
+ to debug Erlang programs. The minimal system based on Erlang/OTP
+ consists of the following two applications:</p>
+ <list type="bulleted">
+ <item>Kernel - Functionality necessary to run Erlang</item>
+ <item>STDLIB - Erlang standard libraries</item>
+ </list>
<p>The application concept applies both to program structure
(processes) and directory structure (modules).</p>
- <p>The simplest kind of application does not have any processes,
- but consists of a collection of functional modules. Such an
+ <p>The simplest applications do not have any processes,
+ but consist of a collection of functional modules. Such an
application is called a <em>library application</em>. An example
of a library application is STDLIB.</p>
<p>An application with processes is easiest implemented as a
@@ -266,12 +273,11 @@ free(Ch, {Alloc, Free} = Channels) ->
<section>
<title>Releases</title>
<p>A <em>release</em> is a complete system made out from a subset of
- the Erlang/OTP applications and a set of user-specific
- applications.</p>
+ Erlang/OTP applications and a set of user-specific applications.</p>
<p>How to program releases is described in
<seealso marker="release_structure">Releases</seealso>.</p>
<p>How to install a release in a target environment is described
- in the chapter about Target Systems in System Principles.</p>
+ in the section about target systems in Section 2 System Principles.</p>
</section>
<section>
diff --git a/system/doc/design_principles/distributed_applications.xml b/system/doc/design_principles/distributed_applications.xml
index 2886f06b53..f1624a9ad7 100644
--- a/system/doc/design_principles/distributed_applications.xml
+++ b/system/doc/design_principles/distributed_applications.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,71 +29,73 @@
<rev></rev>
<file>distributed_applications.xml</file>
</header>
+ <marker id="distributed appl"></marker>
<section>
- <title>Definition</title>
- <p>In a distributed system with several Erlang nodes, there may be
- a need to control applications in a distributed manner. If
+ <title>Introduction</title>
+ <p>In a distributed system with several Erlang nodes, it can be
+ necessary to control applications in a distributed manner. If
the node, where a certain application is running, goes down,
- the application should be restarted at another node.</p>
+ the application is to be restarted at another node.</p>
<p>Such an application is called a <em>distributed application</em>.
- Note that it is the control of the application which is
- distributed, all applications can of course be distributed in
- the sense that they, for example, use services on other nodes.</p>
- <p>Because a distributed application may move between nodes, some
+ Notice that it is the control of the application that is distributed.
+ All applications can be distributed in the sense that they,
+ for example, use services on other nodes.</p>
+ <p>Since a distributed application can move between nodes, some
addressing mechanism is required to ensure that it can be
addressed by other applications, regardless on which node it
currently executes. This issue is not addressed here, but the
- Kernel module <c>global</c> or STDLIB module <c>pg</c> can be
- used for this purpose.</p>
+ <c>global</c> or <c>pg2</c> modules in Kernel
+ can be used for this purpose.</p>
</section>
<section>
<title>Specifying Distributed Applications</title>
<p>Distributed applications are controlled by both the application
- controller and a distributed application controller process,
- <c>dist_ac</c>. Both these processes are part of the <c>kernel</c>
- application. Therefore, distributed applications are specified by
- configuring the <c>kernel</c> application, using the following
- configuration parameter (see also <c>kernel(6)</c>):</p>
- <taglist>
- <tag><c>distributed = [{Application, [Timeout,] NodeDesc}]</c></tag>
- <item>
- <p>Specifies where the application <c>Application = atom()</c>
- may execute. <c>NodeDesc = [Node | {Node,...,Node}]</c> is
- a list of node names in priority order. The order between
- nodes in a tuple is undefined.</p>
- <p><c>Timeout = integer()</c> specifies how many milliseconds to
- wait before restarting the application at another node.
- Defaults to 0.</p>
- </item>
- </taglist>
+ controller and a distributed application controller process,
+ <c>dist_ac</c>. Both these processes are part of the Kernel
+ application. Distributed applications are thus specified by
+ configuring the Kernel application, using the following
+ configuration parameter (see also <c>kernel(6)</c>):</p>
+ <p><c>distributed = [{Application, [Timeout,] NodeDesc}]</c></p>
+ <list type="bulleted">
+ <item>Specifies where the application <c>Application = atom()</c>
+ can execute.</item>
+ <item>><c>NodeDesc = [Node | {Node,...,Node}]</c> is a list of
+ node names in priority order. The order between nodes in a tuple
+ is undefined.</item>
+ <item><c>Timeout = integer()</c> specifies how many milliseconds
+ to wait before restarting the application at another node. It
+ defaults to 0.</item>
+ </list>
<p>For distribution of application control to work properly,
- the nodes where a distributed application may run must contact
+ the nodes where a distributed application can run must contact
each other and negotiate where to start the application. This is
- done using the following <c>kernel</c> configuration parameters:</p>
- <taglist>
- <tag><c>sync_nodes_mandatory = [Node]</c></tag>
- <item>Specifies which other nodes must be started (within
- the timeout specified by <c>sync_nodes_timeout</c>.</item>
- <tag><c>sync_nodes_optional = [Node]</c></tag>
- <item>Specifies which other nodes can be started (within
- the timeout specified by <c>sync_nodes_timeout</c>.</item>
- <tag><c>sync_nodes_timeout = integer() | infinity</c></tag>
- <item>Specifies how many milliseconds to wait for the other nodes
- to start.</item>
- </taglist>
- <p>When started, the node will wait for all nodes specified by
+ done using the following configuration parameters in
+ Kernel:</p>
+ <list type="bulleted">
+ <item><c>sync_nodes_mandatory = [Node]</c> - Specifies which
+ other nodes must be started (within the time-out specified by
+ <c>sync_nodes_timeout</c>).</item>
+ <item><c>sync_nodes_optional = [Node]</c> - Specifies which
+ other nodes can be started (within the time-out specified by
+ <c>sync_nodes_timeout</c>).</item>
+ <item><c>sync_nodes_timeout = integer() | infinity</c> -
+ Specifies how many milliseconds to wait for the other nodes to
+ start.</item>
+ </list>
+ <p>When started, the node waits for all nodes specified by
<c>sync_nodes_mandatory</c> and <c>sync_nodes_optional</c> to
- come up. When all nodes have come up, or when all mandatory nodes
- have come up and the time specified by <c>sync_nodes_timeout</c>
- has elapsed, all applications will be started. If not all
- mandatory nodes have come up, the node will terminate.</p>
- <p>Example: An application <c>myapp</c> should run at the node
- <c>cp1@cave</c>. If this node goes down, <c>myapp</c> should
+ come up. When all nodes are up, or when all mandatory nodes
+ are up and the time specified by <c>sync_nodes_timeout</c>
+ has elapsed, all applications start. If not all
+ mandatory nodes are up, the node terminates.</p>
+ <p><em>Example:</em></p>
+ <p>An application <c>myapp</c> is to run at the node
+ <c>cp1@cave</c>. If this node goes down, <c>myapp</c> is to
be restarted at <c>cp2@cave</c> or <c>cp3@cave</c>. A system
- configuration file <c>cp1.config</c> for <c>cp1@cave</c> could
- look like:</p>
+ configuration file <c>cp1.config</c> for <c>cp1@cave</c> can
+ look as follows:</p>
<code type="none">
[{kernel,
[{distributed, [{myapp, 5000, [cp1@cave, {cp2@cave, cp3@cave}]}]},
@@ -103,13 +106,13 @@
].</code>
<p>The system configuration files for <c>cp2@cave</c> and
<c>cp3@cave</c> are identical, except for the list of mandatory
- nodes which should be <c>[cp1@cave, cp3@cave]</c> for
+ nodes, which is to be <c>[cp1@cave, cp3@cave]</c> for
<c>cp2@cave</c> and <c>[cp1@cave, cp2@cave]</c> for
<c>cp3@cave</c>.</p>
<note>
<p>All involved nodes must have the same value for
- <c>distributed</c> and <c>sync_nodes_timeout</c>, or
- the behaviour of the system is undefined.</p>
+ <c>distributed</c> and <c>sync_nodes_timeout</c>.
+ Otherwise the system behaviour is undefined.</p>
</note>
</section>
@@ -117,28 +120,29 @@
<title>Starting and Stopping Distributed Applications</title>
<p>When all involved (mandatory) nodes have been started,
the distributed application can be started by calling
- <c>application:start(Application)</c> at <em>all of these nodes.</em></p>
- <p>It is of course also possible to use a boot script (see
- <seealso marker="release_structure">Releases</seealso>) which
- automatically starts the application.</p>
- <p>The application will be started at the first node, specified
- by the <c>distributed</c> configuration parameter, which is up
- and running. The application is started as usual. That is, an
- application master is created and calls the application callback
- function:</p>
+ <c>application:start(Application)</c> at <em>all of these
+ nodes.</em></p>
+ <p>A boot script (see
+ <seealso marker="release_structure">Releases</seealso>)
+ can be used that automatically starts the application.</p>
+ <p>The application is started at the first operational node that
+ is listed in the list of nodes in the <c>distributed</c>
+ configuration parameter. The application is started as usual.
+ That is, an application master is created and calls the
+ application callback function:</p>
<code type="none">
Module:start(normal, StartArgs)</code>
- <p>Example: Continuing the example from the previous section,
- the three nodes are started, specifying the system configuration
- file:</p>
+ <p>Example:</p>
+ <p>Continuing the example from the previous section, the three nodes
+ are started, specifying the system configuration file:</p>
<pre>
> <input>erl -sname cp1 -config cp1</input>
> <input>erl -sname cp2 -config cp2</input>
> <input>erl -sname cp3 -config cp3</input></pre>
- <p>When all nodes are up and running, <c>myapp</c> can be started.
+ <p>When all nodes are operational, <c>myapp</c> can be started.
This is achieved by calling <c>application:start(myapp)</c> at
all three nodes. It is then started at <c>cp1</c>, as shown in
- the figure below.</p>
+ the following figure:</p>
<marker id="dist1"></marker>
<image file="../design_principles/dist1.gif">
<icaption>Application myapp - Situation 1</icaption>
@@ -150,31 +154,33 @@ Module:start(normal, StartArgs)</code>
<section>
<title>Failover</title>
<p>If the node where the application is running goes down,
- the application is restarted (after the specified timeout) at
- the first node, specified by the <c>distributed</c> configuration
- parameter, which is up and running. This is called a
+ the application is restarted (after the specified time-out) at
+ the first operational node that is listed in the list of nodes
+ in the <c>distributed</c> configuration parameter. This is called a
<em>failover</em>.</p>
<p>The application is started the normal way at the new node,
that is, by the application master calling:</p>
<code type="none">
Module:start(normal, StartArgs)</code>
- <p>Exception: If the application has the <c>start_phases</c> key
- defined (see <seealso marker="included_applications">Included Applications</seealso>), then the application is instead started
- by calling:</p>
+ <p>An exception is if the application has the <c>start_phases</c>
+ key defined
+ (see <seealso marker="included_applications">Included Applications</seealso>).
+ The application is then instead started by calling:</p>
<code type="none">
Module:start({failover, Node}, StartArgs)</code>
- <p>where <c>Node</c> is the terminated node.</p>
- <p>Example: If <c>cp1</c> goes down, the system checks which one of
+ <p>Here <c>Node</c> is the terminated node.</p>
+ <p><em>Example:</em></p>
+ <p> If <c>cp1</c> goes down, the system checks which one of
the other nodes, <c>cp2</c> or <c>cp3</c>, has the least number of
running applications, but waits for 5 seconds for <c>cp1</c> to
restart. If <c>cp1</c> does not restart and <c>cp2</c> runs fewer
- applications than <c>cp3,</c> then <c>myapp</c> is restarted on
+ applications than <c>cp3</c>, <c>myapp</c> is restarted on
<c>cp2</c>.</p>
<marker id="dist2"></marker>
<image file="../design_principles/dist2.gif">
<icaption>Application myapp - Situation 2</icaption>
</image>
- <p>Suppose now that <c>cp2</c> goes down as well and does not
+ <p>Suppose now that <c>cp2</c> goes also down and does not
restart within 5 seconds. <c>myapp</c> is now restarted on
<c>cp3</c>.</p>
<marker id="dist3"></marker>
@@ -186,28 +192,29 @@ Module:start({failover, Node}, StartArgs)</code>
<section>
<title>Takeover</title>
<p>If a node is started, which has higher priority according
- to <c>distributed</c>, than the node where a distributed
- application is currently running, the application will be
- restarted at the new node and stopped at the old node. This is
+ to <c>distributed</c> than the node where a distributed
+ application is running, the application is restarted at the
+ new node and stopped at the old node. This is
called a <em>takeover</em>.</p>
<p>The application is started by the application master calling:</p>
<code type="none">
Module:start({takeover, Node}, StartArgs)</code>
- <p>where <c>Node</c> is the old node.</p>
- <p>Example: If <c>myapp</c> is running at <c>cp3</c>, and if
- <c>cp2</c> now restarts, it will not restart <c>myapp</c>,
- because the order between nodes <c>cp2</c> and <c>cp3</c> is
+ <p>Here <c>Node</c> is the old node.</p>
+ <p><em>Example: </em></p>
+ <p>If <c>myapp</c> is running at <c>cp3</c>, and if
+ <c>cp2</c> now restarts, it does not restart <c>myapp</c>,
+ as the order between the <c>cp2</c> and <c>cp3</c> nodes is
undefined.</p>
<marker id="dist4"></marker>
<image file="../design_principles/dist4.gif">
<icaption>Application myapp - Situation 4</icaption>
</image>
- <p>However, if <c>cp1</c> restarts as well, the function
+ <p>However, if <c>cp1</c> also restarts, the function
<c>application:takeover/2</c> moves <c>myapp</c> to <c>cp1</c>,
- because <c>cp1</c> has a higher priority than <c>cp3</c> for this
- application. In this case,
- <c>Module:start({takeover, cp3@cave}, StartArgs)</c> is executed
- at <c>cp1</c> to start the application.</p>
+ as <c>cp1</c> has a higher priority than <c>cp3</c> for this
+ application. In this case,
+ <c>Module:start({takeover, cp3@cave}, StartArgs)</c> is
+ executed at <c>cp1</c> to start the application.</p>
<marker id="dist5"></marker>
<image file="../design_principles/dist5.gif">
<icaption>Application myapp - Situation 5</icaption>
diff --git a/system/doc/design_principles/events.xml b/system/doc/design_principles/events.xml
index 529e12c216..3c9d0996dc 100644
--- a/system/doc/design_principles/events.xml
+++ b/system/doc/design_principles/events.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Gen_Event Behaviour</title>
+ <title>gen_event Behaviour</title>
<prepared></prepared>
<docno></docno>
<date></date>
@@ -29,35 +30,36 @@
<file>events.xml</file>
</header>
<marker id="gen_event"></marker>
- <p>This chapter should be read in conjunction with
- <c>gen_event(3)</c>, where all interface functions and callback
- functions are described in detail.</p>
+ <p>This section is to be read with the <c>gen_event(3)</c> manual
+ page in STDLIB, where all interface functions and callback
+ functions are described in detail.</p>
<section>
<title>Event Handling Principles</title>
<p>In OTP, an <em>event manager</em> is a named object to which
- events can be sent. An <em>event</em> could be, for example,
- an error, an alarm or some information that should be logged.</p>
- <p>In the event manager, zero, one or several <em>event handlers</em> are installed. When the event manager is notified
- about an event, the event will be processed by all the installed
+ events can be sent. An <em>event</em> can be, for example,
+ an error, an alarm, or some information that is to be logged.</p>
+ <p>In the event manager, zero, one, or many <em>event handlers</em>
+ are installed. When the event manager is notified
+ about an event, the event is processed by all the installed
event handlers. For example, an event manager for handling errors
- can by default have a handler installed which writes error
+ can by default have a handler installed, which writes error
messages to the terminal. If the error messages during a certain
- period should be saved to a file as well, the user adds another
- event handler which does this. When logging to file is no longer
- necessary, this event handler is deleted.</p>
+ period is to be saved to a file as well, the user adds another
+ event handler that does this. When logging to the file is no
+ longer necessary, this event handler is deleted.</p>
<p>An event manager is implemented as a process and each event
handler is implemented as a callback module.</p>
<p>The event manager essentially maintains a list of
<c>{Module, State}</c> pairs, where each <c>Module</c> is an
- event handler, and <c>State</c> the internal state of that event
- handler.</p>
+ event handler, and <c>State</c> is the internal state of that
+ event handler.</p>
</section>
<section>
<title>Example</title>
<p>The callback module for the event handler writing error messages
- to the terminal could look like:</p>
+ to the terminal can look as follows:</p>
<code type="none">
-module(terminal_logger).
-behaviour(gen_event).
@@ -74,7 +76,7 @@ handle_event(ErrorMsg, State) ->
terminate(_Args, _State) ->
ok.</code>
<p>The callback module for the event handler writing error messages
- to a file could look like:</p>
+ to a file can look as follows:</p>
<code type="none">
-module(file_logger).
-behaviour(gen_event).
@@ -98,29 +100,28 @@ terminate(_Args, Fd) ->
<marker id="mgr"></marker>
<title>Starting an Event Manager</title>
<p>To start an event manager for handling errors, as described in
- the example above, call the following function:</p>
+ the previous example, call the following function:</p>
<code type="none">
gen_event:start_link({local, error_man})</code>
<p>This function spawns and links to a new process, an event
manager.</p>
- <p>The argument, <c>{local, error_man}</c> specifies the name. In
- this case, the event manager will be locally registered as
- <c>error_man</c>.</p>
+ <p>The argument, <c>{local, error_man}</c> specifies the name. The
+ event manager is then locally registered as <c>error_man</c>.</p>
<p>If the name is omitted, the event manager is not registered.
- Instead its pid must be used. The name could also be given
+ Instead its pid must be used. The name can also be given
as <c>{global, Name}</c>, in which case the event manager is
registered using <c>global:register_name/2</c>.</p>
<p><c>gen_event:start_link</c> must be used if the event manager is
- part of a supervision tree, i.e. is started by a supervisor.
- There is another function <c>gen_event:start</c> to start a
- stand-alone event manager, i.e. an event manager which is not
+ part of a supervision tree, that is, started by a supervisor.
+ There is another function, <c>gen_event:start</c>, to start a
+ standalone event manager, that is, an event manager that is not
part of a supervision tree.</p>
</section>
<section>
<title>Adding an Event Handler</title>
- <p>Here is an example using the shell on how to start an event
- manager and add an event handler to it:</p>
+ <p>The following example shows how to start an event manager and
+ add an event handler to it by using the shell:</p>
<pre>
1> <input>gen_event:start({local, error_man}).</input>
{ok,&lt;0.31.0>}
@@ -128,16 +129,16 @@ gen_event:start_link({local, error_man})</code>
ok</pre>
<p>This function sends a message to the event manager registered as
<c>error_man</c>, telling it to add the event handler
- <c>terminal_logger</c>. The event manager will call the callback
- function <c>terminal_logger:init([])</c>, where the argument []
- is the third argument to <c>add_handler</c>. <c>init</c> is
- expected to return <c>{ok, State}</c>, where <c>State</c> is
+ <c>terminal_logger</c>. The event manager calls the callback
+ function <c>terminal_logger:init([])</c>, where the argument
+ <c>[]</c> is the third argument to <c>add_handler</c>. <c>init</c>
+ is expected to return <c>{ok, State}</c>, where <c>State</c> is
the internal state of the event handler.</p>
<code type="none">
init(_Args) ->
{ok, []}.</code>
<p>Here, <c>init</c> does not need any input data and ignores its
- argument. Also, for <c>terminal_logger</c> the internal state is
+ argument. For <c>terminal_logger</c>, the internal state is
not used. For <c>file_logger</c>, the internal state is used
to save the open file descriptor.</p>
<code type="none">
@@ -147,7 +148,7 @@ init(File) ->
</section>
<section>
- <title>Notifying About Events</title>
+ <title>Notifying about Events</title>
<pre>
3> <input>gen_event:notify(error_man, no_reply).</input>
***Error*** no_reply
@@ -158,7 +159,7 @@ ok</pre>
When the event is received, the event manager calls
<c>handle_event(Event, State)</c> for each installed event
handler, in the same order as they were added. The function is
- expected to return a tuple <c>{ok, State1}</c>, where
+ expected to return a tuple <c>{ok,State1}</c>, where
<c>State1</c> is a new value for the state of the event handler.</p>
<p>In <c>terminal_logger</c>:</p>
<code type="none">
@@ -179,17 +180,17 @@ handle_event(ErrorMsg, Fd) ->
ok</pre>
<p>This function sends a message to the event manager registered as
<c>error_man</c>, telling it to delete the event handler
- <c>terminal_logger</c>. The event manager will call the callback
+ <c>terminal_logger</c>. The event manager calls the callback
function <c>terminal_logger:terminate([], State)</c>, where
- the argument [] is the third argument to <c>delete_handler</c>.
- <c>terminate</c> should be the opposite of <c>init</c> and do any
+ the argument <c>[]</c> is the third argument to <c>delete_handler</c>.
+ <c>terminate</c> is to be the opposite of <c>init</c> and do any
necessary cleaning up. Its return value is ignored.</p>
<p>For <c>terminal_logger</c>, no cleaning up is necessary:</p>
<code type="none">
terminate(_Args, _State) ->
ok.</code>
<p>For <c>file_logger</c>, the file descriptor opened in <c>init</c>
- needs to be closed:</p>
+ must be closed:</p>
<code type="none">
terminate(_Args, Fd) ->
file:close(Fd).</code>
@@ -197,20 +198,22 @@ terminate(_Args, Fd) ->
<section>
<title>Stopping</title>
- <p>When an event manager is stopped, it will give each of
+ <p>When an event manager is stopped, it gives each of
the installed event handlers the chance to clean up by calling
<c>terminate/2</c>, the same way as when deleting a handler.</p>
<section>
<title>In a Supervision Tree</title>
<p>If the event manager is part of a supervision tree, no stop
- function is needed. The event manager will automatically be
+ function is needed. The event manager is automatically
terminated by its supervisor. Exactly how this is done is
- defined by a <seealso marker="sup_princ#shutdown">shutdown strategy</seealso> set in the supervisor.</p>
+ defined by a
+ <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
+ set in the supervisor.</p>
</section>
<section>
- <title>Stand-Alone Event Managers</title>
+ <title>Standalone Event Managers</title>
<p>An event manager can also be stopped by calling:</p>
<pre>
> <input>gen_event:stop(error_man).</input>
@@ -219,16 +222,17 @@ ok</pre>
</section>
<section>
<title>Handling Other Messages</title>
- <p>If the gen_event should be able to receive other messages than
- events, the callback function <c>handle_info(Info, StateName, StateData)</c>
- must be implemented to handle them. Examples of
- other messages are exit messages, if the gen_event is linked to
+ <p>If the <c>gen_event</c> is to be able to receive other messages
+ than events, the callback function
+ <c>handle_info(Info, StateName, StateData)</c>
+ must be implemented to handle them. Examples of other
+ messages are exit messages, if the <c>gen_event</c> is linked to
other processes (than the supervisor) and trapping exit signals.</p>
<code type="none">
handle_info({'EXIT', Pid, Reason}, State) ->
..code to handle exits here..
{ok, NewState}.</code>
- <p>The code_change method also has to be implemented.</p>
+ <p>The <c>code_change</c> method must also be implemented.</p>
<code type="none">
code_change(OldVsn, State, Extra) ->
..code to convert state (and more) during code change
diff --git a/system/doc/design_principles/fsm.xml b/system/doc/design_principles/fsm.xml
index 9dce159dca..f58b50cbff 100644
--- a/system/doc/design_principles/fsm.xml
+++ b/system/doc/design_principles/fsm.xml
@@ -8,45 +8,47 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Gen_Fsm Behaviour</title>
+ <title>gen_fsm Behaviour</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
<file>fsm.xml</file>
</header>
- <p>This chapter should be read in conjunction with <c>gen_fsm(3)</c>,
- where all interface functions and callback functions are described
- in detail.</p>
+ <marker id="gen_fsm behaviour"></marker>
+ <p>This section is to be read with the <c>gen_fsm(3)</c> manual page
+ in STDLIB, where all interface functions and callback
+ functions are described in detail.</p>
<section>
- <title>Finite State Machines</title>
- <p>A finite state machine, FSM, can be described as a set of
+ <title>Finite-State Machines</title>
+ <p>A Finite-State Machine (FSM) can be described as a set of
relations of the form:</p>
<pre>
State(S) x Event(E) -> Actions(A), State(S')</pre>
<p>These relations are interpreted as meaning:</p>
<quote>
- <p>If we are in state <c>S</c> and the event <c>E</c> occurs, we
- should perform the actions <c>A</c> and make a transition to
- the state <c>S'</c>.</p>
+ <p>If we are in state <c>S</c> and event <c>E</c> occurs, we
+ are to perform actions <c>A</c> and make a transition to
+ state <c>S'</c>.</p>
</quote>
<p>For an FSM implemented using the <c>gen_fsm</c> behaviour,
the state transition rules are written as a number of Erlang
- functions which conform to the following convention:</p>
+ functions, which conform to the following convention:</p>
<pre>
StateName(Event, StateData) ->
.. code for actions here ...
@@ -55,16 +57,16 @@ StateName(Event, StateData) ->
<section>
<title>Example</title>
- <p>A door with a code lock could be viewed as an FSM. Initially,
+ <p>A door with a code lock can be viewed as an FSM. Initially,
the door is locked. Anytime someone presses a button, this
generates an event. Depending on what buttons have been pressed
- before, the sequence so far may be correct, incomplete or wrong.</p>
- <p>If it is correct, the door is unlocked for 30 seconds (30000 ms).
+ before, the sequence so far can be correct, incomplete, or wrong.</p>
+ <p>If it is correct, the door is unlocked for 30 seconds (30,000 ms).
If it is incomplete, we wait for another button to be pressed. If
it is is wrong, we start all over, waiting for a new button
sequence.</p>
<p>Implementing the code lock FSM using <c>gen_fsm</c> results in
- this callback module:</p>
+ the following callback module:</p>
<marker id="ex"></marker>
<code type="none"><![CDATA[
-module(code_lock).
@@ -101,85 +103,88 @@ open(timeout, State) ->
</section>
<section>
- <title>Starting a Gen_Fsm</title>
- <p>In the example in the previous section, the gen_fsm is started by
- calling <c>code_lock:start_link(Code)</c>:</p>
+ <title>Starting gen_fsm</title>
+ <p>In the example in the previous section, the <c>gen_fsm</c> is
+ started by calling <c>code_lock:start_link(Code)</c>:</p>
<code type="none">
start_link(Code) ->
gen_fsm:start_link({local, code_lock}, code_lock, lists:reverse(Code), []).
</code>
- <p><c>start_link</c> calls the function <c>gen_fsm:start_link/4</c>.
- This function spawns and links to a new process, a gen_fsm.</p>
+ <p><c>start_link</c> calls the function <c>gen_fsm:start_link/4</c>,
+ which spawns and links to a new process, a <c>gen_fsm</c>.</p>
<list type="bulleted">
<item>
- <p>The first argument <c>{local, code_lock}</c> specifies
- the name. In this case, the gen_fsm will be locally registered
- as <c>code_lock</c>.</p>
- <p>If the name is omitted, the gen_fsm is not registered.
- Instead its pid must be used. The name could also be given as
- <c>{global, Name}</c>, in which case the gen_fsm is registered
- using <c>global:register_name/2</c>.</p>
+ <p>The first argument, <c>{local, code_lock}</c>, specifies
+ the name. In this case, the <c>gen_fsm</c> is locally
+ registered as <c>code_lock</c>.</p>
+ <p>If the name is omitted, the <c>gen_fsm</c> is not registered.
+ Instead its pid must be used. The name can also be given
+ as <c>{global, Name}</c>, in which case the <c>gen_fsm</c> is
+ registered using <c>global:register_name/2</c>.</p>
</item>
<item>
<p>The second argument, <c>code_lock</c>, is the name of
- the callback module, that is the module where the callback
+ the callback module, that is, the module where the callback
functions are located.</p>
- <p>In this case, the interface functions (<c>start_link</c> and
- <c>button</c>) are located in the same module as the callback
- functions (<c>init</c>, <c>locked</c> and <c>open</c>). This
+ <p>The interface functions (<c>start_link</c> and <c>button</c>)
+ are then located in the same module as the callback
+ functions (<c>init</c>, <c>locked</c>, and <c>open</c>). This
is normally good programming practice, to have the code
corresponding to one process contained in one module.</p>
</item>
<item>
- <p>The third argument, <c>Code</c>, is a list of digits which is passed
- reversed to the callback function <c>init</c>. Here, <c>init</c>
+ <p>The third argument, <c>Code</c>, is a list of digits that
+ which is passed reversed to the callback function <c>init</c>.
+ Here, <c>init</c>
gets the correct code for the lock as indata.</p>
</item>
<item>
- <p>The fourth argument, [], is a list of options. See
- <c>gen_fsm(3)</c> for available options.</p>
+ <p>The fourth argument, <c>[]</c>, is a list of options. See
+ the <c>gen_fsm(3)</c> manual page for available options.</p>
</item>
</list>
- <p>If name registration succeeds, the new gen_fsm process calls
+ <p>If name registration succeeds, the new <c>gen_fsm</c> process calls
the callback function <c>code_lock:init(Code)</c>. This function
is expected to return <c>{ok, StateName, StateData}</c>, where
- <c>StateName</c> is the name of the initial state of the gen_fsm.
- In this case <c>locked</c>, assuming the door is locked to begin
- with. <c>StateData</c> is the internal state of the gen_fsm. (For
- gen_fsms, the internal state is often referred to 'state data' to
+ <c>StateName</c> is the name of the initial state of the
+ <c>gen_fsm</c>. In this case <c>locked</c>, assuming the door is
+ locked to begin with. <c>StateData</c> is the internal state of
+ the <c>gen_fsm</c>. (For <c>gen_fsm</c>, the internal state is
+ often referred to 'state data' to
distinguish it from the state as in states of a state machine.)
In this case, the state data is the button sequence so far (empty
to begin with) and the correct code of the lock.</p>
<code type="none">
init(Code) ->
{ok, locked, {[], Code}}.</code>
- <p>Note that <c>gen_fsm:start_link</c> is synchronous. It does not
- return until the gen_fsm has been initialized and is ready to
+ <p><c>gen_fsm:start_link</c> is synchronous. It does not return until
+ the <c>gen_fsm</c> has been initialized and is ready to
receive notifications.</p>
- <p><c>gen_fsm:start_link</c> must be used if the gen_fsm is part of
- a supervision tree, i.e. is started by a supervisor. There is
- another function <c>gen_fsm:start</c> to start a stand-alone
- gen_fsm, i.e. a gen_fsm which is not part of a supervision tree.</p>
+ <p><c>gen_fsm:start_link</c> must be used if the <c>gen_fsm</c> is
+ part of a supervision tree, that is, started by a supervisor. There
+ is another function, <c>gen_fsm:start</c>, to start a standalone
+ <c>gen_fsm</c>, that is, a <c>gen_fsm</c> that is not part of a
+ supervision tree.</p>
</section>
<section>
- <title>Notifying About Events</title>
+ <title>Notifying about Events</title>
<p>The function notifying the code lock about a button event is
implemented using <c>gen_fsm:send_event/2</c>:</p>
<code type="none">
button(Digit) ->
gen_fsm:send_event(code_lock, {button, Digit}).</code>
- <p><c>code_lock</c> is the name of the gen_fsm and must agree with
- the name used to start it. <c>{button, Digit}</c> is the actual
- event.</p>
- <p>The event is made into a message and sent to the gen_fsm. When
- the event is received, the gen_fsm calls
- <c>StateName(Event, StateData)</c> which is expected to return a
- tuple <c>{next_state, StateName1, StateData1}</c>.
+ <p><c>code_lock</c> is the name of the <c>gen_fsm</c> and must
+ agree with the name used to start it.
+ <c>{button, Digit}</c> is the actual event.</p>
+ <p>The event is made into a message and sent to the <c>gen_fsm</c>.
+ When the event is received, the <c>gen_fsm</c> calls
+ <c>StateName(Event, StateData)</c>, which is expected to return a
+ tuple <c>{next_state,StateName1,StateData1}</c>.
<c>StateName</c> is the name of the current state and
<c>StateName1</c> is the name of the next state to go to.
<c>StateData1</c> is a new value for the state data of
- the gen_fsm.</p>
+ the <c>gen_fsm</c>.</p>
<code type="none"><![CDATA[
locked({button, Digit}, {SoFar, Code}) ->
case [Digit|SoFar] of
@@ -198,20 +203,21 @@ open(timeout, State) ->
<p>If the door is locked and a button is pressed, the complete
button sequence so far is compared with the correct code for
the lock and, depending on the result, the door is either unlocked
- and the gen_fsm goes to state <c>open</c>, or the door remains in
- state <c>locked</c>.</p>
+ and the <c>gen_fsm</c> goes to state <c>open</c>, or the door
+ remains in state <c>locked</c>.</p>
</section>
<section>
- <title>Timeouts</title>
+ <title>Time-Outs</title>
<p>When a correct code has been given, the door is unlocked and
the following tuple is returned from <c>locked/2</c>:</p>
<code type="none">
{next_state, open, {[], Code}, 30000};</code>
- <p>30000 is a timeout value in milliseconds. After 30000 ms, i.e.
- 30 seconds, a timeout occurs. Then <c>StateName(timeout, StateData)</c> is called. In this case, the timeout occurs when
- the door has been in state <c>open</c> for 30 seconds. After that
- the door is locked again:</p>
+ <p>30,000 is a time-out value in milliseconds. After this time,
+ that is, 30 seconds, a time-out occurs. Then,
+ <c>StateName(timeout, StateData)</c> is called. The time-out
+ then occurs when the door has been in state <c>open</c> for 30
+ seconds. After that the door is locked again:</p>
<code type="none">
open(timeout, State) ->
do_lock(),
@@ -220,7 +226,7 @@ open(timeout, State) ->
<section>
<title>All State Events</title>
- <p>Sometimes an event can arrive at any state of the gen_fsm.
+ <p>Sometimes an event can arrive at any state of the <c>gen_fsm</c>.
Instead of sending the message with <c>gen_fsm:send_event/2</c>
and writing one clause handling the event for each state function,
the message can be sent with <c>gen_fsm:send_all_state_event/2</c>
@@ -245,15 +251,16 @@ handle_event(stop, _StateName, StateData) ->
<section>
<title>In a Supervision Tree</title>
- <p>If the gen_fsm is part of a supervision tree, no stop function
- is needed. The gen_fsm will automatically be terminated by its
- supervisor. Exactly how this is done is defined by a
- <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
+ <p>If the <c>gen_fsm</c> is part of a supervision tree, no stop
+ function is needed. The <c>gen_fsm</c> is automatically
+ terminated by its supervisor. Exactly how this is done is
+ defined by a
+ <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
set in the supervisor.</p>
<p>If it is necessary to clean up before termination, the shutdown
- strategy must be a timeout value and the gen_fsm must be set to
- trap exit signals in the <c>init</c> function. When ordered
- to shutdown, the gen_fsm will then call the callback function
+ strategy must be a time-out value and the <c>gen_fsm</c> must be
+ set to trap exit signals in the <c>init</c> function. When ordered
+ to shutdown, the <c>gen_fsm</c> then calls the callback function
<c>terminate(shutdown, StateName, StateData)</c>:</p>
<code type="none">
init(Args) ->
@@ -270,9 +277,9 @@ terminate(shutdown, StateName, StateData) ->
</section>
<section>
- <title>Stand-Alone Gen_Fsms</title>
- <p>If the gen_fsm is not part of a supervision tree, a stop
- function may be useful, for example:</p>
+ <title>Standalone gen_fsm</title>
+ <p>If the <c>gen_fsm</c> is not part of a supervision tree, a stop
+ function can be useful, for example:</p>
<code type="none">
...
-export([stop/0]).
@@ -290,26 +297,28 @@ handle_event(stop, _StateName, StateData) ->
terminate(normal, _StateName, _StateData) ->
ok.</code>
<p>The callback function handling the <c>stop</c> event returns a
- tuple <c>{stop,normal,StateData1}</c>, where <c>normal</c>
+ tuple, <c>{stop,normal,StateData1}</c>, where <c>normal</c>
specifies that it is a normal termination and <c>StateData1</c>
- is a new value for the state data of the gen_fsm. This will
- cause the gen_fsm to call
+ is a new value for the state data of the <c>gen_fsm</c>. This
+ causes the <c>gen_fsm</c> to call
<c>terminate(normal,StateName,StateData1)</c> and then
- terminate gracefully:</p>
+ it terminates gracefully:</p>
</section>
</section>
<section>
<title>Handling Other Messages</title>
- <p>If the gen_fsm should be able to receive other messages than
- events, the callback function <c>handle_info(Info, StateName, StateData)</c> must be implemented to handle them. Examples of
- other messages are exit messages, if the gen_fsm is linked to
+ <p>If the <c>gen_fsm</c> is to be able to receive other messages
+ than events, the callback function
+ <c>handle_info(Info, StateName, StateData)</c> must be implemented
+ to handle them. Examples of
+ other messages are exit messages, if the <c>gen_fsm</c> is linked to
other processes (than the supervisor) and trapping exit signals.</p>
<code type="none">
handle_info({'EXIT', Pid, Reason}, StateName, StateData) ->
..code to handle exits here..
{next_state, StateName1, StateData1}.</code>
- <p>The code_change method also has to be implemented.</p>
+ <p>The code_change method must also be implemented.</p>
<code type="none">
code_change(OldVsn, StateName, StateData, Extra) ->
..code to convert state (and more) during code change
diff --git a/system/doc/design_principles/gen_server_concepts.xml b/system/doc/design_principles/gen_server_concepts.xml
index d24d87aa03..f8f98918fa 100644
--- a/system/doc/design_principles/gen_server_concepts.xml
+++ b/system/doc/design_principles/gen_server_concepts.xml
@@ -8,20 +8,21 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Gen_Server Behaviour</title>
+ <title>gen_server Behaviour</title>
<prepared></prepared>
<docno></docno>
<date></date>
@@ -29,16 +30,16 @@
<file>gen_server_concepts.xml</file>
</header>
<marker id="gen_server"></marker>
- <p>This chapter should be read in conjunction with
- <seealso marker="stdlib:gen_server">gen_server(3)</seealso>,
- where all interface functions and callback
- functions are described in detail.</p>
+ <p>This section is to be read with the
+ <seealso marker="stdlib:gen_server">gen_server(3)</seealso>
+ manual page in <c>stdblib</c>, where all interface functions and
+ callback functions are described in detail.</p>
<section>
<title>Client-Server Principles</title>
<p>The client-server model is characterized by a central server
and an arbitrary number of clients. The client-server model is
- generally used for resource management operations, where several
+ used for resource management operations, where several
different clients want to share a common resource. The server is
responsible for managing this resource.</p>
<marker id="clientserver"></marker>
@@ -49,9 +50,10 @@
<section>
<title>Example</title>
- <p>An example of a simple server written in plain Erlang was
- given in <seealso marker="des_princ#ch1">Overview</seealso>.
- The server can be re-implemented using <c>gen_server</c>,
+ <p>An example of a simple server written in plain Erlang is
+ provided in
+ <seealso marker="des_princ#ch1">Overview</seealso>.
+ The server can be reimplemented using <c>gen_server</c>,
resulting in this callback module:</p>
<marker id="ex"></marker>
<code type="none">
@@ -86,61 +88,60 @@ handle_cast({free, Ch}, Chs) ->
<section>
<title>Starting a Gen_Server</title>
- <p>In the example in the previous section, the gen_server is started
- by calling <c>ch3:start_link()</c>:</p>
+ <p>In the example in the previous section, <c>gen_server</c> is
+ started by calling <c>ch3:start_link()</c>:</p>
<code type="none">
start_link() ->
gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}</code>
- <p><c>start_link</c> calls the function
- <c>gen_server:start_link/4</c>. This function spawns and links to
- a new process, a gen_server.</p>
+ <p><c>start_link</c> calls function <c>gen_server:start_link/4</c>.
+ This function spawns and links to a new process, a
+ <c>gen_server</c>.</p>
<list type="bulleted">
<item>
- <p>The first argument <c>{local, ch3}</c> specifies the name. In
- this case, the gen_server will be locally registered as
- <c>ch3</c>.</p>
- <p>If the name is omitted, the gen_server is not registered.
- Instead its pid must be used. The name could also be given
- as <c>{global, Name}</c>, in which case the gen_server is
+ <p>The first argument, <c>{local, ch3}</c>, specifies the name.
+ The gen_server is then locally registered as <c>ch3</c>.</p>
+ <p>If the name is omitted, the <c>gen_server</c> is not registered.
+ Instead its pid must be used. The name can also be given
+ as <c>{global, Name}</c>, in which case the <c>gen_server</c> is
registered using <c>global:register_name/2</c>.</p>
</item>
<item>
<p>The second argument, <c>ch3</c>, is the name of the callback
- module, that is the module where the callback functions are
+ module, that is, the module where the callback functions are
located.</p>
- <p>In this case, the interface functions (<c>start_link</c>,
- <c>alloc</c> and <c>free</c>) are located in the same module
- as the callback functions (<c>init</c>, <c>handle_call</c> and
+ <p>The interface functions (<c>start_link</c>, <c>alloc</c>,
+ and <c>free</c>) are then located in the same module
+ as the callback functions (<c>init</c>, <c>handle_call</c>, and
<c>handle_cast</c>). This is normally good programming
practice, to have the code corresponding to one process
contained in one module.</p>
</item>
<item>
- <p>The third argument, [], is a term which is passed as-is to
- the callback function <c>init</c>. Here, <c>init</c> does not
+ <p>The third argument, <c>[]</c>, is a term that is passed as is
+ to the callback function <c>init</c>. Here, <c>init</c> does not
need any indata and ignores the argument.</p>
</item>
<item>
- <p>The fourth argument, [], is a list of options. See
- <c>gen_server(3)</c> for available options.</p>
+ <p>The fourth argument, <c>[]</c>, is a list of options. See the
+ <c>gen_server(3)</c> manual page for available options.</p>
</item>
</list>
- <p>If name registration succeeds, the new gen_server process calls
- the callback function <c>ch3:init([])</c>. <c>init</c> is expected
- to return <c>{ok, State}</c>, where <c>State</c> is the internal
- state of the gen_server. In this case, the state is the available
- channels.</p>
+ <p>If name registration succeeds, the new <c>gen_server</c> process
+ calls the callback function <c>ch3:init([])</c>. <c>init</c> is
+ expected to return <c>{ok, State}</c>, where <c>State</c> is the
+ internal state of the <c>gen_server</c>. In this case, the state
+ is the available channels.</p>
<code type="none">
init(_Args) ->
{ok, channels()}.</code>
- <p>Note that <c>gen_server:start_link</c> is synchronous. It does
- not return until the gen_server has been initialized and is ready
+ <p><c>gen_server:start_link</c> is synchronous. It does not return
+ until the <c>gen_server</c> has been initialized and is ready
to receive requests.</p>
- <p><c>gen_server:start_link</c> must be used if the gen_server is
- part of a supervision tree, i.e. is started by a supervisor.
- There is another function <c>gen_server:start</c> to start a
- stand-alone gen_server, i.e. a gen_server which is not part of a
- supervision tree.</p>
+ <p><c>gen_server:start_link</c> must be used if the <c>gen_server</c>
+ is part of a supervision tree, that is, started by a supervisor.
+ There is another function, <c>gen_server:start</c>, to start a
+ standalone <c>gen_server</c>, that is, a <c>gen_server</c> that
+ is not part of a supervision tree.</p>
</section>
<section>
@@ -150,14 +151,17 @@ init(_Args) ->
<code type="none">
alloc() ->
gen_server:call(ch3, alloc).</code>
- <p><c>ch3</c> is the name of the gen_server and must agree with
- the name used to start it. <c>alloc</c> is the actual request.</p>
- <p>The request is made into a message and sent to the gen_server.
- When the request is received, the gen_server calls
- <c>handle_call(Request, From, State)</c> which is expected to
- return a tuple <c>{reply, Reply, State1}</c>. <c>Reply</c> is
- the reply which should be sent back to the client, and
- <c>State1</c> is a new value for the state of the gen_server.</p>
+ <p><c>ch3</c> is the name of the <c>gen_server</c> and must agree
+ with the name used to start it. <c>alloc</c> is the actual
+ request.</p>
+ <p>The request is made into a message and sent to the
+ <c>gen_server</c>. When the request is received, the
+ <c>gen_server</c> calls
+ <c>handle_call(Request, From, State)</c>, which is expected to
+ return a tuple <c>{reply,Reply,State1}</c>. <c>Reply</c> is
+ the reply that is to be sent back to the client, and
+ <c>State1</c> is a new value for the state of the
+ <c>gen_server</c>.</p>
<code type="none">
handle_call(alloc, _From, Chs) ->
{Ch, Chs2} = alloc(Chs),
@@ -166,8 +170,8 @@ handle_call(alloc, _From, Chs) ->
the new state is the set of remaining available channels
<c>Chs2</c>.</p>
<p>Thus, the call <c>ch3:alloc()</c> returns the allocated channel
- <c>Ch</c> and the gen_server then waits for new requests, now
- with an updated list of available channels.</p>
+ <c>Ch</c> and the <c>gen_server</c> then waits for new requests,
+ now with an updated list of available channels.</p>
</section>
<section>
@@ -177,20 +181,21 @@ handle_call(alloc, _From, Chs) ->
<code type="none">
free(Ch) ->
gen_server:cast(ch3, {free, Ch}).</code>
- <p><c>ch3</c> is the name of the gen_server. <c>{free, Ch}</c> is
- the actual request.</p>
- <p>The request is made into a message and sent to the gen_server.
+ <p><c>ch3</c> is the name of the <c>gen_server</c>.
+ <c>{free, Ch}</c> is the actual request.</p>
+ <p>The request is made into a message and sent to the
+ <c>gen_server</c>.
<c>cast</c>, and thus <c>free</c>, then returns <c>ok</c>.</p>
- <p>When the request is received, the gen_server calls
- <c>handle_cast(Request, State)</c> which is expected to
- return a tuple <c>{noreply, State1}</c>. <c>State1</c> is a new
- value for the state of the gen_server.</p>
+ <p>When the request is received, the <c>gen_server</c> calls
+ <c>handle_cast(Request, State)</c>, which is expected to
+ return a tuple <c>{noreply,State1}</c>. <c>State1</c> is a new
+ value for the state of the <c>gen_server</c>.</p>
<code type="none">
handle_cast({free, Ch}, Chs) ->
Chs2 = free(Ch, Chs),
{noreply, Chs2}.</code>
<p>In this case, the new state is the updated list of available
- channels <c>Chs2</c>. The gen_server is now ready for new
+ channels <c>Chs2</c>. The <c>gen_server</c> is now ready for new
requests.</p>
</section>
@@ -199,15 +204,17 @@ handle_cast({free, Ch}, Chs) ->
<section>
<title>In a Supervision Tree</title>
- <p>If the gen_server is part of a supervision tree, no stop
- function is needed. The gen_server will automatically be
+ <p>If the <c>gen_server</c> is part of a supervision tree, no stop
+ function is needed. The <c>gen_server</c> is automatically
terminated by its supervisor. Exactly how this is done is
- defined by a <seealso marker="sup_princ#shutdown">shutdown strategy</seealso> set in the supervisor.</p>
+ defined by a
+ <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
+ set in the supervisor.</p>
<p>If it is necessary to clean up before termination, the shutdown
- strategy must be a timeout value and the gen_server must be set
- to trap exit signals in the <c>init</c> function. When ordered
- to shutdown, the gen_server will then call the callback function
- <c>terminate(shutdown, State)</c>:</p>
+ strategy must be a time-out value and the <c>gen_server</c> must
+ be set to trap exit signals in function <c>init</c>. When ordered
+ to shutdown, the <c>gen_server</c> then calls the callback
+ function <c>terminate(shutdown, State)</c>:</p>
<code type="none">
init(Args) ->
...,
@@ -223,9 +230,9 @@ terminate(shutdown, State) ->
</section>
<section>
- <title>Stand-Alone Gen_Servers</title>
- <p>If the gen_server is not part of a supervision tree, a stop
- function may be useful, for example:</p>
+ <title>Standalone Gen_Servers</title>
+ <p>If the <c>gen_server</c> is not part of a supervision tree, a
+ stop function can be useful, for example:</p>
<code type="none">
...
export([stop/0]).
@@ -245,26 +252,26 @@ handle_cast({free, Ch}, State) ->
terminate(normal, State) ->
ok.</code>
<p>The callback function handling the <c>stop</c> request returns
- a tuple <c>{stop, normal, State1}</c>, where <c>normal</c>
+ a tuple <c>{stop,normal,State1}</c>, where <c>normal</c>
specifies that it is a normal termination and <c>State1</c> is
- a new value for the state of the gen_server. This will cause
- the gen_server to call <c>terminate(normal,State1)</c> and then
- terminate gracefully.</p>
+ a new value for the state of the <c>gen_server</c>. This causes
+ the <c>gen_server</c> to call <c>terminate(normal, State1)</c>
+ and then it terminates gracefully.</p>
</section>
</section>
<section>
<title>Handling Other Messages</title>
- <p>If the gen_server should be able to receive other messages than
- requests, the callback function <c>handle_info(Info, State)</c>
+ <p>If the <c>gen_server</c> is to be able to receive other messages
+ than requests, the callback function <c>handle_info(Info, State)</c>
must be implemented to handle them. Examples of other messages
- are exit messages, if the gen_server is linked to other processes
- (than the supervisor) and trapping exit signals.</p>
+ are exit messages, if the <c>gen_server</c> is linked to other
+ processes (than the supervisor) and trapping exit signals.</p>
<code type="none">
handle_info({'EXIT', Pid, Reason}, State) ->
..code to handle exits here..
{noreply, State1}.</code>
- <p>The code_change method also has to be implemented.</p>
+ <p>The <c>code_change</c> method must also be implemented.</p>
<code type="none">
code_change(OldVsn, State, Extra) ->
..code to convert state (and more) during code change
diff --git a/system/doc/design_principles/included_applications.xml b/system/doc/design_principles/included_applications.xml
index 3aa43fd595..3257795e5f 100644
--- a/system/doc/design_principles/included_applications.xml
+++ b/system/doc/design_principles/included_applications.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,35 +29,36 @@
<rev></rev>
<file>included_applications.xml</file>
</header>
+ <marker id="included appl"></marker>
<section>
- <title>Definition</title>
+ <title>Introduction</title>
<p>An application can <em>include</em> other applications.
An <em>included application</em> has its own application directory
and <c>.app</c> file, but it is started as part of the supervisor
tree of another application.</p>
<p>An application can only be included by one other application.</p>
<p>An included application can include other applications.</p>
- <p>An application which is not included by any other application is
+ <p>An application that is not included by any other application is
called a <em>primary application</em>.</p>
<marker id="inclappls"></marker>
<image file="../design_principles/inclappls.gif">
- <icaption>Primary Application and Included Applications.</icaption>
+ <icaption>Primary Application and Included Applications</icaption>
</image>
- <p>The application controller will automatically load any included
- applications when loading a primary application, but not start
+ <p>The application controller automatically loads any included
+ applications when loading a primary application, but does not start
them. Instead, the top supervisor of the included application
must be started by a supervisor in the including application.</p>
<p>This means that when running, an included application is in fact
- part of the primary application and a process in an included
- application will consider itself belonging to the primary
+ part of the primary application, and a process in an included
+ application considers itself belonging to the primary
application.</p>
</section>
<section>
<title>Specifying Included Applications</title>
<p>Which applications to include is defined by
- the <c>included_applications</c> key in the <c>.app</c> file.</p>
+ the <c>included_applications</c> key in the <c>.app</c> file:</p>
<pre>
{application, prim_app,
[{description, "Tree application"},
@@ -71,7 +73,7 @@
</section>
<section>
- <title>Synchronizing Processes During Startup</title>
+ <title>Synchronizing Processes during Startup</title>
<p>The supervisor tree of an included application is started as
part of the supervisor tree of the including application.
If there is a need for synchronization between processes in
@@ -79,12 +81,12 @@
by using <em>start phases</em>.</p>
<p>Start phases are defined by the <c>start_phases</c> key in
the <c>.app</c> file as a list of tuples <c>{Phase,PhaseArgs}</c>,
- where <c>Phase</c> is an atom and <c>PhaseArgs</c> is a term.
- Also, the value of the <c>mod</c> key of the including application
+ where <c>Phase</c> is an atom and <c>PhaseArgs</c> is a term.</p>
+ <p>The value of the <c>mod</c> key of the including application
must be set to <c>{application_starter,[Module,StartArgs]}</c>,
- where <c>Module</c> as usual is the application callback module
- and <c>StartArgs</c> a term provided as argument to the callback
- function <c>Module:start/2</c>.</p>
+ where <c>Module</c> as usual is the application callback module.
+ <c>StartArgs</c> is a term provided as argument to the callback
+ function <c>Module:start/2</c>:</p>
<code type="none">
{application, prim_app,
[{description, "Tree application"},
@@ -108,36 +110,38 @@
{mod, {incl_app_cb,[]}}
]}.</code>
<p>When starting a primary application with included applications,
- the primary application is started the normal way:
- The application controller creates an application master for
- the application, and the application master calls
+ the primary application is started the normal way, that is:</p>
+ <list type="bulleted">
+ <item>The application controller creates an application master for
+ the application</item>
+ <item>The application master calls
<c>Module:start(normal, StartArgs)</c> to start the top
- supervisor.</p>
+ supervisor.</item>
+ </list>
<p>Then, for the primary application and each included application
in top-down, left-to-right order, the application master calls
<c>Module:start_phase(Phase, Type, PhaseArgs)</c> for each phase
- defined for for the primary application, in that order.
- Note that if a phase is not defined for an included application,
+ defined for the primary application, in that order. If a phase
+ is not defined for an included application,
the function is not called for this phase and application.</p>
<p>The following requirements apply to the <c>.app</c> file for
an included application:</p>
<list type="bulleted">
- <item>The <c>{mod, {Module,StartArgs}}</c> option must be
- included. This option is used to find the callback module
- <c>Module</c> of the application. <c>StartArgs</c> is ignored,
- as <c>Module:start/2</c> is called only for the primary
- application.</item>
+ <item>The <c>{mod, {Module,StartArgs}}</c> option must be included.
+ This option is used to find the callback module <c>Module</c> of the
+ application. <c>StartArgs</c> is ignored, as <c>Module:start/2</c>
+ is called only for the primary application.</item>
<item>If the included application itself contains included
- applications, instead the option
- <c>{mod, {application_starter, [Module,StartArgs]}}</c> must be
- included.</item>
+ applications, instead the
+ <c>{mod, {application_starter, [Module,StartArgs]}}</c> option
+ must be included.</item>
<item>The <c>{start_phases, [{Phase,PhaseArgs}]}</c> option must
- be included, and the set of specified phases must be a subset
- of the set of phases specified for the primary application.</item>
+ be included, and the set of specified phases must be a subset
+ of the set of phases specified for the primary application.</item>
</list>
<p>When starting <c>prim_app</c> as defined above, the application
- controller will call the following callback functions, before
- <c>application:start(prim_app)</c> returns a value:</p>
+ controller calls the following callback functions before
+ <c>application:start(prim_app)</c> returns a value:</p>
<code type="none">
application:start(prim_app)
=> prim_app_cb:start(normal, [])
diff --git a/system/doc/design_principles/part.xml b/system/doc/design_principles/part.xml
index a560147648..42fd3beb6a 100644
--- a/system/doc/design_principles/part.xml
+++ b/system/doc/design_principles/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml
index 9d1e2c8669..20ddc3dbf5 100644
--- a/system/doc/design_principles/release_handling.xml
+++ b/system/doc/design_principles/release_handling.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,128 +29,126 @@
<rev></rev>
<file>release_handling.xml</file>
</header>
+ <marker id="release handling"></marker>
<section>
<title>Release Handling Principles</title>
<p>An important feature of the Erlang programming language is
- the ability to change module code in run-time, <em>code replacement</em>, as described in <em>Erlang Reference Manual</em>.</p>
+ the ability to change module code in runtime,
+ <em>code replacement</em>, as described in the Erlang
+ Reference Manual.</p>
<p>Based on this feature, the OTP application SASL provides a
framework for upgrading and downgrading between different
- versions of an entire release in run-time. This is what we call
+ versions of an entire release in runtime. This is called
<em>release handling</em>.</p>
- <p>The framework consists of off-line support (<c>systools</c>) for
- generating scripts and building release packages, and on-line
- support (<c>release_handler</c>) for unpacking and installing
- release packages.</p>
- <p>Note that the minimal system based on Erlang/OTP, enabling
- release handling, thus consists of Kernel, STDLIB and SASL.</p>
- <list type="ordered">
- <item>
- <p>A release is created as described in the previous chapter
- <seealso marker="release_structure">Releases</seealso>.
- The release is transferred to and installed at target
- environment. Refer to <em>System Principles</em> for
- information of how to install the first target system.</p>
- </item>
- <item>
- <p>Modifications, for example error corrections, are made to
- the code in the development environment.</p>
- </item>
- <item>
- <p>At some point it is time to make a new version of release.
- The relevant <c>.app</c> files are updated and a new
- <c>.rel</c> file is written.</p>
- </item>
- <item>
- <p>For each modified application, an
- <seealso marker="#appup">application upgrade file</seealso>,
- <c>.appup</c>, is created. In this file, it is described how
- to upgrade and/or downgrade between the old and new version of
- the application.</p>
- </item>
- <item>
- <p>Based on the <c>.appup</c> files, a
- <seealso marker="#relup">release upgrade file</seealso> called
- <c>relup</c>, is created. This file describes how to upgrade
- and/or downgrade between the old and new version of
- the entire release.</p>
- </item>
- <item>
- <p>A new release package is made and transferred to
- the target system.</p>
- </item>
- <item>
- <p>The new release package is unpacked using the release
- handler.</p>
- </item>
- <item>
- <p>The new version of the release is installed, also using
- the release handler. This is done by evaluating
- the instructions in <c>relup</c>. Modules may be added,
- deleted or re-loaded, applications may be started, stopped or
- re-started etc. In some cases, it is even necessary to restart
- the entire emulator.</p>
- <p>If the installation fails, the system may be rebooted.
- The old release version is then automatically used.</p>
- </item>
- <item>
- <p>If the installation succeeds, the new version is made
- the default version, which should now be used in case of a
- system reboot.</p>
- </item>
- </list>
- <p>The next chapter, <seealso marker="appup_cookbook">Appup Cookbook</seealso>, contains examples of <c>.appup</c> files
- for typical cases of upgrades/downgrades that are normally easy
- to handle in run-time. However, there are a many aspects that can
- make release handling complicated. To name a few examples:</p>
+ <p>The framework consists of:</p>
<list type="bulleted">
- <item>
- <p>Complicated or circular dependencies can make it difficult
- or even impossible to decide in which order things must be
- done without risking run-time errors during an upgrade or
- downgrade. Dependencies may be:</p>
- <list type="bulleted">
- <item>between nodes,</item>
- <item>between processes, and</item>
- <item>between modules.</item>
- </list>
- </item>
- <item>
- <p>During release handling, non-affected processes continue
- normal execution. This may lead to timeouts or other problems.
- For example, new processes created in the time window between
- suspending processes using a certain module and loading a new
- version of this module, may execute old code.</p>
- </item>
+ <item>Offline support - <c>systools</c> for generating scripts
+ and building release packages</item>
+ <item>Online support - <c>release_handler</c> for unpacking and
+ installing release packages</item>
</list>
- <p>It is therefore recommended that code is changed in as small
+ <p>The minimal system based on Erlang/OTP, enabling release handling,
+ thus consists of the Kernel, STDLIB, and SASL
+ applications.</p>
+
+ <section>
+ <title>Release Handling Workflow</title>
+ <p><em>Step 1</em>) A release is created as described in
+ <seealso marker="release_structure">Releases</seealso>.</p>
+ <p><em>Step 2</em>) The release is transferred to and installed at
+ target environment. For information of how to install the first
+ target system, see System Principles.</p>
+ <p><em>Step 3</em>) Modifications, for example, error corrections,
+ are made to the code in the development environment.</p>
+ <p><em>Step 4</em>) At some point, it is time to make a new version
+ of release. The relevant <c>.app</c> files are updated and a new
+ <c>.rel</c> file is written.</p>
+ <p><em>Step 5</em>) For each modified application, an
+ <seealso marker="#appup">application upgrade file</seealso>,
+ <c>.appup</c>, is created. In this file, it is described how to
+ upgrade and/or downgrade between the old and new version of the
+ application.</p>
+ <p><em>Step 6</em>) Based on the <c>.appup</c> files, a
+ <seealso marker="#relup">release upgrade file</seealso> called
+ <c>relup</c>, is created. This file describes how to upgrade and/or
+ downgrade between the old and new version of the entire release.</p>
+ <p><em>Step 7</em>) A new release package is made and transferred to
+ the target system.</p>
+ <p><em>Step 8</em>) The new release package is unpacked using the
+ release handler.</p>
+ <p><em>Step 9</em>) The new version of the release is installed,
+ also using the release handler. This is done by evaluating the
+ instructions in <c>relup</c>. Modules can be added, deleted, or
+ reloaded, applications can be started, stopped, or restarted, and so
+ on. In some cases, it is even necessary to restart the entire
+ emulator.</p>
+ <list type="bulleted">
+ <item>If the installation fails, the system can be rebooted.
+ The old release version is then automatically used.</item>
+ <item>If the installation succeeds, the new version is made
+ the default version, which is to now be used if there is a
+ system reboot.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Release Handling Aspects</title>
+ <p><seealso marker="appup_cookbook">Appup Cookbook</seealso>,
+ contains examples of <c>.appup</c> files
+ for typical cases of upgrades/downgrades that are normally easy to
+ handle in runtime. However, many aspects can make release handling
+ complicated, for example:</p>
+ <list type="bulleted">
+ <item>
+ <p>Complicated or circular dependencies can make it difficult
+ or even impossible to decide in which order things must be
+ done without risking runtime errors during an upgrade or
+ downgrade. Dependencies can be:</p>
+ <list type="bulleted">
+ <item>Between nodes</item>
+ <item>Between processes</item>
+ <item>Between modules</item>
+ </list>
+ </item>
+ <item>
+ <p>During release handling, non-affected processes continue
+ normal execution. This can lead to time-outs or other problems.
+ For example, new processes created in the time window between
+ suspending processes using a certain module, and loading a new
+ version of this module, can execute old code.</p>
+ </item>
+ </list>
+ <p>It is thus recommended that code is changed in as small
steps as possible, and always kept backwards compatible.</p>
+ </section>
</section>
<section>
<marker id="req"></marker>
<title>Requirements</title>
- <p>For release handling to work properly, the runtime system needs
- to have knowledge about which release it is currently running. It
- must also be able to change (in run-time) which boot script and
- system configuration file should be used if the system is
- rebooted, for example by <c>heart</c> after a failure.
- Therefore, Erlang must be started as an embedded system, see
- <em>Embedded System</em> for information on how to do this.</p>
+ <p>For release handling to work properly, the runtime system must
+ have knowledge about which release it is running. It
+ must also be able to change (in runtime) which boot script and
+ system configuration file to use if the system is
+ rebooted, for example, by <c>heart</c> after a failure.
+ Thus, Erlang must be started as an embedded system; for
+ information on how to do this, see Embedded System.</p>
<p>For system reboots to work properly, it is also required that
- the system is started with heart beat monitoring, see
- <c>erl(1)</c> and <c>heart(3)</c>.</p>
+ the system is started with heartbeat monitoring, see the
+ <c>erl(1)</c> manual page in ERTS and the <c>heart(3)</c>
+ manual page in Kernel</p>
<p>Other requirements:</p>
<list type="bulleted">
<item>
<p>The boot script included in a release package must be
generated from the same <c>.rel</c> file as the release
package itself.</p>
- <p>Information about applications are fetched from the script
+ <p>Information about applications is fetched from the script
when an upgrade or downgrade is performed.</p>
</item>
<item>
- <p>The system must be configured using one and only one system
+ <p>The system must be configured using only one system
configuration file, called <c>sys.config</c>.</p>
<p>If found, this file is automatically included when a release
package is created.</p>
@@ -165,13 +164,13 @@
<section>
<title>Distributed Systems</title>
- <p>If the system consists of several Erlang nodes, each node may use
+ <p>If the system consists of several Erlang nodes, each node can use
its own version of the release. The release handler is a locally
registered process and must be called at each node where an
- upgrade or downgrade is required. There is a release handling
- instruction that can be used to synchronize the release handler
- processes at a number of nodes: <c>sync_nodes</c>. See
- <c>appup(4)</c>.</p>
+ upgrade or downgrade is required. A release handling
+ instruction, <c>sync_nodes</c>, can be used to synchronize the
+ release handler processes at a number of nodes, see the
+ <c>appup(4)</c> manual page in SASL.</p>
</section>
<section>
@@ -183,31 +182,26 @@
instructions. To make it easier for the user, there are also a
number of <em>high-level</em> instructions, which are translated
to low-level instructions by <c>systools:make_relup</c>.</p>
- <p>Here, some of the most frequently used instructions are
- described. The complete list of instructions can be found in
- <c>appup(4)</c>.</p>
+ <p>Some of the most frequently used instructions are described in
+ this section. The complete list of instructions is included in the
+ <c>appup(4)</c> manual page in SASL.</p>
<p>First, some definitions:</p>
- <taglist>
- <tag><em>Residence module</em></tag>
- <item>
- <p>The module where a process has its tail-recursive loop
- function(s). If the tail-recursive loop functions are
- implemented in several modules, all those modules are residence
- modules for the process.</p>
- </item>
- <tag><em>Functional module</em></tag>
- <item>
- <p>A module which is not a residence module for any process.</p>
- </item>
- </taglist>
- <p>Note that for a process implemented using an OTP behaviour,
- the behaviour module is the residence module for that process.
- The callback module is a functional module.</p>
+ <list type="bulleted">
+ <item><em>Residence module</em> - The module where a process has
+ its tail-recursive loop function(s). If these functions are
+ implemented in several modules, all those modules are residence
+ modules for the process.</item>
+ <item><em>Functional module</em> - A module that is not a
+ residence module for any process.</item>
+ </list>
+ <p>For a process implemented using an OTP behaviour, the behaviour
+ module is the residence module for that process.
+ The callback module is a functional module.</p>
<section>
<title>load_module</title>
<p>If a simple extension has been made to a functional module, it
- is sufficient to simply load the new version of the module into
+ is sufficient to load the new version of the module into
the system, and remove the old version. This is called
<em>simple code replacement</em> and for this the following
instruction is used:</p>
@@ -217,44 +211,50 @@
<section>
<title>update</title>
- <p>If a more complex change has been made, for example a change
- to the format of the internal state of a gen_server, simple code
- replacement is not sufficient. Instead it is necessary to
- suspend the processes using the module (to avoid that they try
- to handle any requests before the code replacement is
- completed), ask them to transform the internal state format and
- switch to the new version of the module, remove the old version
- and last, resume the processes. This is called <em>synchronized code replacement</em> and for this the following instructions
- are used:</p>
+ <p>If a more complex change has been made, for example, a change
+ to the format of the internal state of a <c>gen_server</c>, simple
+ code replacement is not sufficient. Instead, it is necessary to:</p>
+ <list type="bulleted">
+ <item>Suspend the processes using the module (to avoid that
+ they try to handle any requests before the code replacement is
+ completed).</item>
+ <item>Ask them to transform the internal state format and
+ switch to the new version of the module.</item>
+ <item>Remove the old version.</item>
+ <item>Resume the processes.</item>
+ </list>
+ <p>This is called <em>synchronized code replacement</em> and for
+ this the following instructions are used:</p>
<code type="none">
{update, Module, {advanced, Extra}}
{update, Module, supervisor}</code>
<p><c>update</c> with argument <c>{advanced,Extra}</c> is used
when changing the internal state of a behaviour as described
- above. It will cause behaviour processes to call the callback
+ above. It causes behaviour processes to call the callback
function <c>code_change</c>, passing the term <c>Extra</c> and
- some other information as arguments. See the man pages for
+ some other information as arguments. See the manual pages for
the respective behaviours and
- <seealso marker="appup_cookbook#int_state">Appup Cookbook</seealso>.</p>
+ <seealso marker="appup_cookbook#int_state">Appup Cookbook</seealso>.</p>
<p><c>update</c> with argument <c>supervisor</c> is used when
changing the start specification of a supervisor. See
- <seealso marker="appup_cookbook#sup">Appup Cookbook</seealso>.</p>
+ <seealso marker="appup_cookbook#sup">Appup Cookbook</seealso>.</p>
<p>When a module is to be updated, the release handler finds
which processes that are <em>using</em> the module by
traversing the supervision tree of each running application
and checking all the child specifications:</p>
<code type="none">
{Id, StartFunc, Restart, Shutdown, Type, Modules}</code>
- <p>A process is using a module if the name is listed in
+ <p>A process uses a module if the name is listed in
<c>Modules</c> in the child specification for the process.</p>
<p>If <c>Modules=dynamic</c>, which is the case for event
managers, the event manager process informs the release handler
- about the list of currently installed event handlers (gen_fsm)
- and it is checked if the module name is in this list instead.</p>
+ about the list of currently installed event handlers
+ (<c>gen_fsm</c>), and it is checked if the module name is in
+ this list instead.</p>
<p>The release handler suspends, asks for code change, and
resumes processes by calling the functions
- <c>sys:suspend/1,2</c>, <c>sys:change_code/4,5</c> and
- <c>sys:resume/1,2</c> respectively.</p>
+ <c>sys:suspend/1,2</c>, <c>sys:change_code/4,5</c>, and
+ <c>sys:resume/1,2</c>, respectively.</p>
</section>
<section>
@@ -263,39 +263,39 @@
used:</p>
<code type="none">
{add_module, Module}</code>
- <p>The instruction loads the module and is absolutely necessary
+ <p>The instruction loads the module and is necessary
when running Erlang in embedded mode. It is not strictly
required when running Erlang in interactive (default) mode,
since the code server then automatically searches for and
loads unloaded modules.</p>
- <p>The opposite of <c>add_module</c> is <c>delete_module</c> which
+ <p>The opposite of <c>add_module</c> is <c>delete_module</c>, which
unloads a module:</p>
<code type="none">
{delete_module, Module}</code>
- <p>Note that any process, in any application, with <c>Module</c>
+ <p>Any process, in any application, with <c>Module</c>
as residence module, is killed when the instruction is
- evaluated. The user should therefore ensure that all such
+ evaluated. The user must therefore ensure that all such
processes are terminated before deleting the module, to avoid
- a possible situation with failing supervisor restarts.</p>
+ a situation with failing supervisor restarts.</p>
</section>
<section>
<title>Application Instructions</title>
- <p>Instruction for adding an application:</p>
+ <p>The following is the instruction for adding an application:</p>
<code type="none">
{add_application, Application}</code>
<p>Adding an application means that the modules defined by
the <c>modules</c> key in the <c>.app</c> file are loaded using
- a number of <c>add_module</c> instructions, then the application
+ a number of <c>add_module</c> instructions, and then the application
is started.</p>
- <p>Instruction for removing an application:</p>
+ <p>The following is the instruction for removing an application:</p>
<code type="none">
{remove_application, Application}</code>
<p>Removing an application means that the application is stopped,
the modules are unloaded using a number of <c>delete_module</c>
- instructions and then the application specification is unloaded
+ instructions, and then the application specification is unloaded
from the application controller.</p>
- <p>Instruction for restarting an application:</p>
+ <p>The following is the instruction for restarting an application:</p>
<code type="none">
{restart_application, Application}</code>
<p>Restarting an application means that the application is stopped
@@ -305,46 +305,48 @@
</section>
<section>
- <title>apply (low-level)</title>
+ <title>apply (Low-Level)</title>
<p>To call an arbitrary function from the release handler,
the following instruction is used:</p>
<code type="none">
{apply, {M, F, A}}</code>
- <p>The release handler will evaluate <c>apply(M, F, A)</c>.</p>
+ <p>The release handler evalutes <c>apply(M, F, A)</c>.</p>
</section>
<section>
<marker id="restart_new_emulator_instr"></marker>
- <title>restart_new_emulator (low-level)</title>
+ <title>restart_new_emulator (Low-Level)</title>
<p>This instruction is used when changing to a new emulator
- version, or when any of the core applications kernel, stdlib
- or sasl is upgraded. If a system reboot is needed for some
- other reason, the <c>restart_emulator</c> instruction should
- be used instead.</p>
- <p>Requires that the system is started with heart beat
- monitoring, see <c>erl(1)</c> and <c>heart(3)</c>.</p>
- <p>The <c>restart_new_emulator</c> instruction shall always be
- the very first instruction in a relup. If the relup is
- generated by <c>systools:make_relup/3,4</c> this is
+ version, or when any of the core applications Kernel,
+ STDLIB, or SASL is upgraded. If a system reboot
+ is needed for another reason, the <c>restart_emulator</c>
+ instruction is to be used instead.</p>
+ <p>This instruction requires that the system is started with
+ heartbeat monitoring, see the <c>erl(1)</c> manual page in
+ ERTS and the <c>heart(3)</c> manual page in Kernel.</p>
+ <p>The <c>restart_new_emulator</c> instruction must always be
+ the first instruction in a relup. If the relup is
+ generated by <c>systools:make_relup/3,4</c>, this is
automatically ensured.</p>
<p>When the release handler encounters the instruction, it first
generates a temporary boot file, which starts the new versions
of the emulator and the core applications, and the old version
of all other applications. Then it shuts down
- the current emulator by calling <c>init:reboot()</c>, see
- <c>init(3)</c>. All processes are terminated gracefully and
- the system is rebooted by the heart program, using the
+ the current emulator by calling <c>init:reboot()</c>, see the
+ <c>init(3)</c> manual page in Kernel.
+ All processes are terminated gracefully and
+ the system is rebooted by the <c>heart</c> program, using the
temporary boot file. After the reboot, the rest of the relup
instructions are executed. This is done as a part of the
temporary boot script.</p>
<warning>
- <p>Since this mechanism causes the new versions of the
- emulator and core applications to run with the old version of
- other applications during startup, extra care must be taken to
+ <p>This mechanism causes the new versions of the emulator and
+ core applications to run with the old version of other
+ applications during startup. Thus, take extra care to
avoid incompatibility. Incompatible changes in the core
- applications may in some situations be necessary. If possible,
+ applications can in some situations be necessary. If possible,
such changes are preceded by deprecation over two major
- releases before the actual change. To make sure your
+ releases before the actual change. To ensure the
application is not crashed by an incompatible change, always
remove any call to deprecated functions as soon as
possible.</p>
@@ -352,35 +354,36 @@
<p>An info report is written when the upgrade is completed. To
programmatically find out if the upgrade is complete,
call <c>release_handler:which_releases(current)</c> and check
- if it returns the expected (i.e. the new) release.</p>
+ if it returns the expected (that is, the new) release.</p>
<p>The new release version must be made permanent when the new
- emulator is up and running. Otherwise, the old version will be
- used in case of a new system reboot.</p>
- <p>On UNIX, the release handler tells the heart program which
- command to use to reboot the system. Note that the environment
- variable <c>HEART_COMMAND</c>, normally used by the heart
- program, in this case is ignored. The command instead defaults
- to <c>$ROOT/bin/start</c>. Another command can be set
- by using the SASL configuration parameter <c>start_prg</c>, see
- <c>sasl(6)</c>.</p>
+ emulator is operational. Otherwise, the old version will be
+ used if there is a new system reboot.</p>
+ <p>On UNIX, the release handler tells the <c>heart</c> program
+ which command to use to reboot the system. The environment
+ variable <c>HEART_COMMAND</c>, normally used by the <c>heart</c>
+ program, is ignored in this case. The command instead defaults
+ to <c>$ROOT/bin/start</c>. Another command can be set by using
+ the SASL configuration parameter <c>start_prg</c>, see
+ the <c>sasl(6)</c> manual page.</p>
</section>
<section>
<marker id="restart_emulator_instr"></marker>
- <title>restart_emulator (low-level)</title>
- <p>This instruction is not related to upgrades of erts or any of
- the core applications. It can be used by any application to
+ <title>restart_emulator (Low-Level)</title>
+ <p>This instruction is not related to upgrades of ERTS or any
+ of the core applications. It can be used by any application to
force a restart of the emulator after all upgrade instructions
are executed.</p>
- <p>There can only be one <c>restart_emulator</c> instruction in
- a relup script, and it shall always be placed at the end. If
- the relup is generated by <c>systools:make_relup/3,4</c> this
+ <p>A relup script can only have one <c>restart_emulator</c>
+ instruction and it must always be placed at the end. If
+ the relup is generated by <c>systools:make_relup/3,4</c>, this
is automatically ensured.</p>
<p>When the release handler encounters the instruction, it shuts
- down the emulator by calling <c>init:reboot()</c>, see
- <c>init(3)</c>. All processes are terminated gracefully and
- the system can then be rebooted by the heart program using the
- new release version. No more upgrade instruction will be
+ down the emulator by calling <c>init:reboot()</c>, see the
+ <c>init(3)</c> manual page in Kernel.
+ All processes are terminated gracefully and the system
+ can then be rebooted by the <c>heart</c> program using the
+ new release version. No more upgrade instruction is
executed after the restart.</p>
</section>
</section>
@@ -389,10 +392,11 @@
<marker id="appup"></marker>
<title>Application Upgrade File</title>
<p>To define how to upgrade/downgrade between the current version
- and previous versions of an application, we create an
- <em>application upgrade file</em>, or in short <c>.appup</c> file.
- The file should be called <c>Application.appup</c>, where
- <c>Application</c> is the name of the application:</p>
+ and previous versions of an application, an
+ <em>application upgrade file</em>, or in short an <c>.appup</c>
+ file is created.
+ The file is to be called <c>Application.appup</c>, where
+ <c>Application</c> is the application name:</p>
<code type="none">
{Vsn,
[{UpFromVsn1, InstructionsU1},
@@ -401,24 +405,27 @@
[{DownToVsn1, InstructionsD1},
...,
{DownToVsnK, InstructionsDK}]}.</code>
- <p><c>Vsn</c>, a string, is the current version of the application,
- as defined in the <c>.app</c> file. Each <c>UpFromVsn</c>
- is a previous version of the application to upgrade from, and each
- <c>DownToVsn</c> is a previous version of the application to
- downgrade to. Each <c>Instructions</c> is a list of release
- handling instructions.</p>
- <p>The syntax and contents of the <c>appup</c> file are described
- in detail in <c>appup(4)</c>.</p>
- <p>In the chapter <seealso marker="appup_cookbook">Appup Cookbook</seealso>, examples of <c>.appup</c> files for typical
- upgrade/downgrade cases are given.</p>
- <p>Example: Consider the release <c>ch_rel-1</c> from
- the <seealso marker="release_structure#ch_rel">Releases</seealso>
- chapter. Assume we want to add a function <c>available/0</c> to
- the server <c>ch3</c> which returns the number of available
- channels:</p>
- <p>(Hint: When trying out the example, make the changes in a copy of
- the original directory, so that the first versions are still
- available.)</p>
+ <list type="bulleted">
+ <item><c>Vsn</c>, a string, is the current version of the application,
+ as defined in the <c>.app</c> file.</item>
+ <item>Each <c>UpFromVsn</c> is a previous version of the application
+ to upgrade from.</item>
+ <item>Each <c>DownToVsn</c> is a previous version of the application
+ to downgrade to.</item>
+ <item>Each <c>Instructions</c> is a list of release handling
+ instructions.</item>
+ </list>
+ <p>For information about the syntax and contents of the <c>.appup</c>
+ file, see the <c>appup(4)</c> manual page in SASL.</p>
+ <p><seealso marker="appup_cookbook">Appup Cookbook</seealso>
+ includes examples of <c>.appup</c> files for typical upgrade/downgrade
+ cases.</p>
+ <p><em>Example:</em> Consider the release <c>ch_rel-1</c> from
+ <seealso marker="release_structure#ch_rel">Releases</seealso>.
+ Assume you want to add a function <c>available/0</c> to server
+ <c>ch3</c>, which returns the number of available channels (when
+ trying out the example, change in a copy of the original
+ directory, so that the first versions are still available):</p>
<code type="none">
-module(ch3).
-behaviour(gen_server).
@@ -465,9 +472,9 @@ handle_cast({free, Ch}, Chs) ->
{mod, {ch_app,[]}}
]}.</code>
<p>To upgrade <c>ch_app</c> from <c>"1"</c> to <c>"2"</c> (and
- to downgrade from <c>"2"</c> to <c>"1"</c>), we simply need to
+ to downgrade from <c>"2"</c> to <c>"1"</c>), you only need to
load the new (old) version of the <c>ch3</c> callback module.
- We create the application upgrade file <c>ch_app.appup</c> in
+ Create the application upgrade file <c>ch_app.appup</c> in
the <c>ebin</c> directory:</p>
<code type="none">
{"2",
@@ -480,25 +487,25 @@ handle_cast({free, Ch}, Chs) ->
<marker id="relup"></marker>
<title>Release Upgrade File</title>
<p>To define how to upgrade/downgrade between the new version and
- previous versions of a release, we create a <em>release upgrade file</em>, or in short <c>relup</c> file.</p>
+ previous versions of a release, a <em>release upgrade file</em>,
+ or in short <c>relup</c> file, is to be created.</p>
<p>This file does not need to be created manually, it can be
generated by <c>systools:make_relup/3,4</c>. The relevant versions
- of the <c>.rel</c> file, <c>.app</c> files and <c>.appup</c> files
- are used as input. It is deducted which applications should be
- added and deleted, and which applications that need to be upgraded
- and/or downgraded. The instructions for this is fetched from
+ of the <c>.rel</c> file, <c>.app</c> files, and <c>.appup</c> files
+ are used as input. It is deducted which applications are to be
+ added and deleted, and which applications that must be upgraded
+ and/or downgraded. The instructions for this are fetched from
the <c>.appup</c> files and transformed into a single list of
low-level instructions in the right order.</p>
<p>If the <c>relup</c> file is relatively simple, it can be created
- manually. Remember that it should only contain low-level
- instructions.</p>
- <p>The syntax and contents of the release upgrade file are
- described in detail in <c>relup(4)</c>.</p>
- <p>Example, continued from the previous section. We have a new
- version "2" of <c>ch_app</c> and an <c>.appup</c> file. We also
- need a new version of the <c>.rel</c> file. This time the file is
- called <c>ch_rel-2.rel</c> and the release version string is
- changed changed from "A" to "B":</p>
+ manually. It it only to contain low-level instructions.</p>
+ <p>For details about the syntax and contents of the release upgrade
+ file, see the <c>relup(4)</c> manual page in SASL.</p>
+ <p><em>Example, continued from the previous section:</em> You have a
+ new version "2" of <c>ch_app</c> and an <c>.appup</c> file. A new
+ version of the <c>.rel</c> file is also needed. This time the file
+ is called <c>ch_rel-2.rel</c> and the release version string is
+ changed from "A" to "B":</p>
<code type="none">
{release,
{"ch_rel", "B"},
@@ -512,13 +519,13 @@ handle_cast({free, Ch}, Chs) ->
<pre>
1> <input>systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"]).</input>
ok</pre>
- <p>This will generate a <c>relup</c> file with instructions for
+ <p>This generates a <c>relup</c> file with instructions for
how to upgrade from version "A" ("ch_rel-1") to version "B"
("ch_rel-2") and how to downgrade from version "B" to version "A".</p>
- <p>Note that both the old and new versions of the <c>.app</c> and
- <c>.rel</c> files must be in the code path, as well as
- the <c>.appup</c> and (new) <c>.beam</c> files. It is possible
- to extend the code path by using the option <c>path</c>:</p>
+ <p>Both the old and new versions of the <c>.app</c> and
+ <c>.rel</c> files must be in the code path, as well as the
+ <c>.appup</c> and (new) <c>.beam</c> files. The code path can be
+ extended by using the option <c>path</c>:</p>
<pre>
1> <input>systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"],</input>
<input>[{path,["../ch_rel-1",</input>
@@ -529,31 +536,34 @@ ok</pre>
<section>
<marker id="rel_handler"></marker>
<title>Installing a Release</title>
- <p>When we have made a new version of a release, a release package
+ <p>When you have made a new version of a release, a release package
can be created with this new version and transferred to the target
environment.</p>
- <p>To install the new version of the release in run-time,
+ <p>To install the new version of the release in runtime,
the <em>release handler</em> is used. This is a process belonging
- to the SASL application, that handles unpacking, installation,
- and removal of release packages. It is interfaced through
- the module <c>release_handler</c>, which is described in detail in
- <c>release_handler(3)</c>.</p>
- <p>Assuming there is a target system up and running with
+ to the SASL application, which handles unpacking, installation,
+ and removal of release packages. It is communicated through
+ the <c>release_handler</c> module. For details, see the
+ <c>release_handler(3)</c> manual page in SASL.</p>
+ <p>Assuming there is an operational target system with
installation root directory <c>$ROOT</c>, the release package with
- the new version of the release should be copied to
+ the new version of the release is to be copied to
<c>$ROOT/releases</c>.</p>
- <p>The first action is to <em>unpack</em> the release package,
- the files are then extracted from the package:</p>
+ <p>First, <em>unpack</em> the release package.
+ The files are then extracted from the package:</p>
<code type="none">
release_handler:unpack_release(ReleaseName) => {ok, Vsn}</code>
- <p><c>ReleaseName</c> is the name of the release package except
- the <c>.tar.gz</c> extension. <c>Vsn</c> is the version of
- the unpacked release, as defined in its <c>.rel</c> file.</p>
- <p>A directory <c>$ROOT/lib/releases/Vsn</c> will be created, where
+ <list type="bulleted">
+ <item><c>ReleaseName</c> is the name of the release package except
+ the <c>.tar.gz</c> extension.</item>
+ <item><c>Vsn</c> is the version of the unpacked release, as
+ defined in its <c>.rel</c> file.</item>
+ </list>
+ <p>A directory <c>$ROOT/lib/releases/Vsn</c> is created, where
the <c>.rel</c> file, the boot script <c>start.boot</c>,
- the system configuration file <c>sys.config</c> and <c>relup</c>
+ the system configuration file <c>sys.config</c>, and <c>relup</c>
are placed. For applications with new version numbers,
- the application directories will be placed under <c>$ROOT/lib</c>.
+ the application directories are placed under <c>$ROOT/lib</c>.
Unchanged applications are not affected.</p>
<p>An unpacked release can be <em>installed</em>. The release
handler then evaluates the instructions in <c>relup</c>, step by
@@ -563,11 +573,11 @@ release_handler:install_release(Vsn) => {ok, FromVsn, []}</code>
<p>If an error occurs during the installation, the system is
rebooted using the old version of the release. If installation
succeeds, the system is afterwards using the new version of
- the release, but should anything happen and the system is
- rebooted, it would start using the previous version again. To be
- made the default version, the newly installed release must be made
- <em>permanent</em>, which means the previous version becomes
- <em>old</em>:</p>
+ the release, but if anything happens and the system is
+ rebooted, it starts using the previous version again.</p>
+ <p>To be made the default version, the newly installed release
+ must be made <em>permanent</em>, which means the previous
+ version becomes <em>old</em>:</p>
<code type="none">
release_handler:make_permanent(Vsn) => ok</code>
<p>The system keeps information about which versions are old and
@@ -579,41 +589,44 @@ release_handler:make_permanent(Vsn) => ok</code>
release_handler:install_release(FromVsn) => {ok, Vsn, []}</code>
<p>An installed, but not permanent, release can be <em>removed</em>.
Information about the release is then deleted from
- <c>$ROOT/releases/RELEASES</c> and the release specific code,
- that is the new application directories and
+ <c>$ROOT/releases/RELEASES</c> and the release-specific code,
+ that is, the new application directories and
the <c>$ROOT/releases/Vsn</c> directory, are removed.</p>
<code type="none">
release_handler:remove_release(Vsn) => ok</code>
- <p>Example, continued from the previous sections:</p>
- <p>1) Create a target system as described in <em>System Principles</em> of the first version <c>"A"</c> of <c>ch_rel</c>
- from
- the <seealso marker="release_structure#ch_rel">Releases</seealso>
- chapter. This time <c>sys.config</c> must be included in
- the release package. If no configuration is needed, the file
- should contain the empty list:</p>
- <code type="none">
+
+ <section>
+ <title>Example (continued from the previous sections)</title>
+ <p><em>Step 1)</em> Create a target system as described in
+ System Principles of the first version <c>"A"</c>
+ of <c>ch_rel</c> from
+ <seealso marker="release_structure#ch_rel">Releases</seealso>.
+ This time <c>sys.config</c> must be included in the release package.
+ If no configuration is needed, the file is to contain the empty
+ list:</p>
+ <code type="none">
[].</code>
- <p>2) Start the system as a simple target system. Note that in
- reality, it should be started as an embedded system. However,
- using <c>erl</c> with the correct boot script and config file is
- enough for illustration purposes:</p>
- <pre>
+ <p><em>Step 2)</em> Start the system as a simple target system. In
+ reality, it is to be started as an embedded system. However, using
+ <c>erl</c> with the correct boot script and config file is enough for
+ illustration purposes:</p>
+ <pre>
% <input>cd $ROOT</input>
% <input>bin/erl -boot $ROOT/releases/A/start -config $ROOT/releases/A/sys</input>
...</pre>
<p><c>$ROOT</c> is the installation directory of the target system.</p>
- <p>3) In another Erlang shell, generate start scripts and create a
- release package for the new version <c>"B"</c>. Remember to
- include (a possible updated) <c>sys.config</c> and
- the <c>relup</c> file, see <seealso marker="#relup">Release Upgrade File</seealso> above.</p>
- <pre>
+ <p><em>Step 3)</em> In another Erlang shell, generate start scripts and
+ create a release package for the new version <c>"B"</c>. Remember to
+ include (a possible updated) <c>sys.config</c> and the <c>relup</c> file,
+ see <seealso marker="#relup">Release Upgrade File</seealso>.</p>
+ <pre>
1> <input>systools:make_script("ch_rel-2").</input>
ok
2> <input>systools:make_tar("ch_rel-2").</input>
ok</pre>
- <p>The new release package now contains version "2" of <c>ch_app</c>
- and the <c>relup</c> file as well:</p>
- <code type="none">
+ <p>The new release package now also contains version "2" of <c>ch_app</c>
+ and the <c>relup</c> file:</p>
+ <code type="none">
% tar tf ch_rel-2.tar
lib/kernel-2.9/ebin/kernel.app
lib/kernel-2.9/ebin/application.beam
@@ -633,28 +646,30 @@ releases/B/relup
releases/B/sys.config
releases/B/ch_rel-2.rel
releases/ch_rel-2.rel</code>
- <p>4) Copy the release package <c>ch_rel-2.tar.gz</c> to
- the <c>$ROOT/releases</c> directory.</p>
- <p>5) In the running target system, unpack the release package:</p>
- <pre>
+ <p><em>Step 4)</em> Copy the release package <c>ch_rel-2.tar.gz</c>
+ to the <c>$ROOT/releases</c> directory.</p>
+ <p><em>Step 5)</em> In the running target system, unpack the release
+ package:</p>
+ <pre>
1> <input>release_handler:unpack_release("ch_rel-2").</input>
{ok,"B"}</pre>
<p>The new application version <c>ch_app-2</c> is installed under
<c>$ROOT/lib</c> next to <c>ch_app-1</c>. The <c>kernel</c>,
- <c>stdlib</c> and <c>sasl</c> directories are not affected, as
+ <c>stdlib</c>, and <c>sasl</c> directories are not affected, as
they have not changed.</p>
<p>Under <c>$ROOT/releases</c>, a new directory <c>B</c> is created,
containing <c>ch_rel-2.rel</c>, <c>start.boot</c>,
- <c>sys.config</c> and <c>relup</c>.</p>
- <p>6) Check if the function <c>ch3:available/0</c> is available:</p>
- <pre>
+ <c>sys.config</c>, and <c>relup</c>.</p>
+ <p><em>Step 6)</em> Check if the function <c>ch3:available/0</c> is
+ available:</p>
+ <pre>
2> <input>ch3:available().</input>
** exception error: undefined function ch3:available/0</pre>
- <p>7) Install the new release. The instructions in
+ <p><em>Step 7)</em> Install the new release. The instructions in
<c>$ROOT/releases/B/relup</c> are executed one by one, resulting
in the new version of <c>ch3</c> being loaded. The function
<c>ch3:available/0</c> is now available:</p>
- <pre>
+ <pre>
3> <input>release_handler:install_release("B").</input>
{ok,"A",[]}
4> <input>ch3:available().</input>
@@ -663,15 +678,16 @@ releases/ch_rel-2.rel</code>
".../lib/ch_app-2/ebin/ch3.beam"
6> <input>code:which(ch_sup).</input>
".../lib/ch_app-1/ebin/ch_sup.beam"</pre>
- <p>Note that processes in <c>ch_app</c> for which code have not
- been updated, for example the supervisor, are still evaluating
+ <p>Processes in <c>ch_app</c> for which code have not
+ been updated, for example, the supervisor, are still evaluating
code from <c>ch_app-1</c>.</p>
- <p>8) If the target system is now rebooted, it will use version "A"
- again. The "B" version must be made permanent, in order to be
+ <p><em>Step 8)</em> If the target system is now rebooted, it uses
+ version "A" again. The "B" version must be made permanent, to be
used when the system is rebooted.</p>
- <pre>
+ <pre>
7> <input>release_handler:make_permanent("B").</input>
ok</pre>
+ </section>
</section>
<section>
@@ -681,37 +697,40 @@ ok</pre>
specifications are automatically updated for all loaded
applications.</p>
<note>
- <p>The information about the new application specifications are
+ <p>The information about the new application specifications is
fetched from the boot script included in the release package.
- It is therefore important that the boot script is generated from
+ Thus, it is important that the boot script is generated from
the same <c>.rel</c> file as is used to build the release
package itself.</p>
</note>
<p>Specifically, the application configuration parameters are
automatically updated according to (in increasing priority
order):</p>
- <list type="ordered">
+ <list type="bulleted">
<item>The data in the boot script, fetched from the new
application resource file <c>App.app</c></item>
<item>The new <c>sys.config</c></item>
- <item>Command line arguments <c>-App Par Val</c></item>
+ <item>Command-line arguments <c>-App Par Val</c></item>
</list>
<p>This means that parameter values set in the other system
- configuration files, as well as values set using
- <c>application:set_env/3</c>, are disregarded.</p>
+ configuration files and values set using
+ <c>application:set_env/3</c> are disregarded.</p>
<p>When an installed release is made permanent, the system process
<c>init</c> is set to point out the new <c>sys.config</c>.</p>
- <p>After the installation, the application controller will compare
+ <p>After the installation, the application controller compares
the old and new configuration parameters for all running
applications and call the callback function:</p>
<code type="none">
Module:config_change(Changed, New, Removed)</code>
- <p><c>Module</c> is the application callback module as defined by
- the <c>mod</c> key in the <c>.app</c> file. <c>Changed</c> and
- <c>New</c> are lists of <c>{Par,Val}</c> for all changed and
- added configuration parameters, respectively. <c>Removed</c> is
- a list of all parameters <c>Par</c> that have been removed.</p>
- <p>The function is optional and may be omitted when implementing an
+ <list type="bulleted">
+ <item><c>Module</c> is the application callback module as defined
+ by the <c>mod</c> key in the <c>.app</c> file.</item>
+ <item><c>Changed</c> and <c>New</c> are lists of <c>{Par,Val}</c> for
+ all changed and added configuration parameters, respectively.</item>
+ <item><c>Removed</c> is a list of all parameters <c>Par</c> that have
+ been removed.</item>
+ </list>
+ <p>The function is optional and can be omitted when implementing an
application callback module.</p>
</section>
</chapter>
diff --git a/system/doc/design_principles/release_structure.xml b/system/doc/design_principles/release_structure.xml
index cec33f42e3..6e7ab06094 100644
--- a/system/doc/design_principles/release_structure.xml
+++ b/system/doc/design_principles/release_structure.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,21 +29,23 @@
<rev></rev>
<file>release_structure.xml</file>
</header>
- <p>This chapter should be read in conjuction with <c>rel(4)</c>,
- <c>systools(3)</c> and <c>script(4)</c>.</p>
+ <marker id="releases section"></marker>
+ <p>This section is to be read with the <c>rel(4)</c>, <c>systools(3)</c>,
+ and <c>script(4)</c> manual pages in SASL.</p>
<section>
<title>Release Concept</title>
- <p>When we have written one or more applications, we might want to
- create a complete system consisting of these applications and a
+ <p>When you have written one or more applications, you might want
+ to create a complete system with these applications and a
subset of the Erlang/OTP applications. This is called a
<em>release</em>.</p>
- <p>To do this, we create a <seealso marker="#res_file">release resource file</seealso> which defines which applications
- are included in the release.</p>
+ <p>To do this, create a
+ <seealso marker="#res_file">release resource file</seealso> that
+ defines which applications are included in the release.</p>
<p>The release resource file is used to generate
<seealso marker="#boot">boot scripts</seealso> and
<seealso marker="#pack">release packages</seealso>. A system
- which is transfered to and installed at another site is called a
+ that is transferred to and installed at another site is called a
<em>target system</em>. How to use a release package to create a
target system is described in System Principles.</p>
</section>
@@ -50,29 +53,30 @@
<section>
<marker id="res_file"></marker>
<title>Release Resource File</title>
- <p>To define a release, we create a <em>release resource file</em>,
- or in short <c>.rel</c> file, where we specify the name and
- version of the release, which ERTS version it is based on, and
- which applications it consists of:</p>
+ <p>To define a release, create a <em>release resource file</em>,
+ or in short a <c>.rel</c> file. In the file, specify the name and
+ version of the release, which ERTS version it is based on,
+ and which applications it consists of:</p>
<code type="none">
{release, {Name,Vsn}, {erts, EVsn},
[{Application1, AppVsn1},
...
{ApplicationN, AppVsnN}]}.</code>
+ <p><c>Name</c>, <c>Vsn</c>, <c>EVsn</c>, and <c>AppVsn</c> are
+ strings.</p>
<p>The file must be named <c>Rel.rel</c>, where <c>Rel</c> is a
unique name.</p>
- <p><c>Name</c>, <c>Vsn</c> and <c>EVsn</c> are strings.</p>
- <p>Each <c>Application</c> (atom) and <c>AppVsn</c> (string) is
+ <p>Each <c>Application</c> (atom) and <c>AppVsn</c> is
the name and version of an application included in the release.
- Note that the minimal release based on Erlang/OTP consists of
- the <c>kernel</c> and <c>stdlib</c> applications, so these
+ The minimal release based on Erlang/OTP consists of
+ the Kernel and STDLIB applications, so these
applications must be included in the list.</p>
<p>If the release is to be upgraded, it must also include
- the <c>sasl</c> application.</p>
+ the SASL application.</p>
<marker id="ch_rel"></marker>
- <p>Example: We want to make a release of <c>ch_app</c> from
- the <seealso marker="applications#ch_app">Applications</seealso>
- chapter. It has the following <c>.app</c> file:</p>
+ <p><em>Example: </em> A release of <c>ch_app</c> from
+ <seealso marker="applications#ch_app">Applications</seealso>
+ has the following <c>.app</c> file:</p>
<code type="none">
{application, ch_app,
[{description, "Channel allocator"},
@@ -83,8 +87,8 @@
{mod, {ch_app,[]}}
]}.</code>
<p>The <c>.rel</c> file must also contain <c>kernel</c>,
- <c>stdlib</c> and <c>sasl</c>, since these applications are
- required by <c>ch_app</c>. We call the file <c>ch_rel-1.rel</c>:</p>
+ <c>stdlib</c>, and <c>sasl</c>, as these applications are required
+ by <c>ch_app</c>. The file is called <c>ch_rel-1.rel</c>:</p>
<code type="none">
{release,
{"ch_rel", "A"},
@@ -99,24 +103,28 @@
<section>
<marker id="boot"></marker>
<title>Generating Boot Scripts</title>
- <p>There are tools in the SASL module <c>systools</c> available to
- build and check releases. The functions read the <c>.rel</c> and
+ <p><c>systools</c> in the SASL application includes tools to
+ build and check releases. The functions read the <c>rel</c> and
<c>.app</c> files and performs syntax and dependency checks.
- The function <c>systools:make_script/1,2</c> is used to generate
- a boot script (see System Principles).</p>
+ The <c>systools:make_script/1,2</c> function is used to generate
+ a boot script (see System Principles):</p>
<pre>
1> <input>systools:make_script("ch_rel-1", [local]).</input>
ok</pre>
- <p>This creates a boot script, both the readable version
- <c>ch_rel-1.script</c> and the binary version used by the runtime
- system, <c>ch_rel-1.boot</c>. <c>"ch_rel-1"</c> is the name of
- the <c>.rel</c> file, minus the extension. <c>local</c> is an
- option that means that the directories where the applications are
- found are used in the boot script, instead of <c>$ROOT/lib</c>.
- (<c>$ROOT</c> is the root directory of the installed release.)
- This is a useful way to test a generated boot script locally.</p>
+ <p>This creates a boot script, both the readable version,
+ <c>ch_rel-1.script</c>, and the binary version, <c>ch_rel-1.boot</c>,
+ used by the runtime system.</p>
+ <list type="bulleted">
+ <item><c>"ch_rel-1"</c> is the name of the <c>.rel</c> file,
+ minus the extension.</item>
+ <item><c>local</c> is an option that means that the directories
+ where the applications are found are used in the boot script,
+ instead of <c>$ROOT/lib</c> (<c>$ROOT</c> is the root directory
+ of the installed release).</item>
+ </list>
+ <p> This is a useful way to test a generated boot script locally.</p>
<p>When starting Erlang/OTP using the boot script, all applications
- from the <c>.rel</c> file are automatically loaded and started:</p>
+ from the <c>.rel</c> file are automatically loaded and started:</p>
<pre>
% <input>erl -boot ch_rel-1</input>
Erlang (BEAM) emulator version 5.3
@@ -147,18 +155,24 @@ Eshell V5.3 (abort with ^G)
<section>
<marker id="pack"></marker>
<title>Creating a Release Package</title>
- <p>There is a function <c>systools:make_tar/1,2</c> which takes
- a <c>.rel</c> file as input and creates a zipped tar-file with
- the code for the specified applications, a <em>release package</em>.</p>
+ <p>The <c>systools:make_tar/1,2</c> function takes a <c>.rel</c> file
+ as input and creates a zipped tar file with the code for the specified
+ applications, a <em>release package</em>:</p>
<pre>
1> <input>systools:make_script("ch_rel-1").</input>
ok
2> <input>systools:make_tar("ch_rel-1").</input>
ok</pre>
- <p>The release package by default contains the <c>.app</c> files and
- object code for all applications, structured according to
- the <seealso marker="applications#app_dir">application directory structure</seealso>, the binary boot script renamed to
- <c>start.boot</c>, and the <c>.rel</c> file.</p>
+ <p>The release package by default contains:</p>
+ <list type="bulleted">
+ <item>The <c>.app</c> files</item>
+ <item>The <c>.rel</c> file</item>
+ <item>The object code for all applications, structured according
+ to the
+ <seealso marker="applications#app_dir">application directory
+ structure</seealso></item>
+ <item>The binary boot script renamed to <c>start.boot</c></item>
+ </list>
<pre>
% <input>tar tf ch_rel-1.tar</input>
lib/kernel-2.9/ebin/kernel.app
@@ -177,40 +191,39 @@ lib/ch_app-1/ebin/ch3.beam
releases/A/start.boot
releases/A/ch_rel-1.rel
releases/ch_rel-1.rel</pre>
- <p>Note that a new boot script was generated, without
+ <p>A new boot script was generated, without
the <c>local</c> option set, before the release package was made.
In the release package, all application directories are placed
- under <c>lib</c>. Also, we do not know where the release package
- will be installed, so we do not want any hardcoded absolute paths
- in the boot script here.</p>
+ under <c>lib</c>. You do not know where the release package
+ will be installed, so no hard-coded absolute paths are allowed.</p>
<p>The release resource file <c>mysystem.rel</c> is duplicated in
the tar file. Originally, this file was only stored in
- the <c>releases</c> directory in order to make it possible for
+ the <c>releases</c> directory to make it possible for
the <c>release_handler</c> to extract this file
separately. After unpacking the tar file, <c>release_handler</c>
would automatically copy the file
to <c>releases/FIRST</c>. However, sometimes the tar file is
- unpacked without involving the <c>release_handler</c> (e.g. when
- unpacking the first target system) and therefore the file is now
- instead duplicated in the tar file so no manual copying is
- necessary.</p>
+ unpacked without involving the <c>release_handler</c> (for
+ example, when unpacking the first target system) and the file
+ is therefore now instead duplicated in the tar file so no manual
+ copying is necessary.</p>
<p>If a <c>relup</c> file and/or a system configuration file called
- <c>sys.config</c> is found, these files are included in
- the release package as well. See
+ <c>sys.config</c> is found, these files are also included in
+ the release package. See
<seealso marker="release_handling#req">Release Handling</seealso>.</p>
<p>Options can be set to make the release package include source
code and the ERTS binary as well.</p>
- <p>Refer to System Principles for how to install the first target
- system, using a release package, and to
- <seealso marker="release_handling">Release Handling</seealso> for
- how to install a new release package in an existing system.</p>
+ <p>For information on how to install the first target system, using
+ a release package, see System Principles. For information
+ on how to install a new release package in an existing system, see
+ <seealso marker="release_handling">Release Handling</seealso>.</p>
</section>
<section>
<marker id="reldir"></marker>
<title>Directory Structure</title>
- <p>Directory structure for the code installed by the release handler
- from a release package:</p>
+ <p>The directory structure for the code installed by the release handler
+ from a release package is as follows:</p>
<code type="none">
$ROOT/lib/App1-AVsn1/ebin
/priv
@@ -222,24 +235,18 @@ $ROOT/lib/App1-AVsn1/ebin
/erts-EVsn/bin
/releases/Vsn
/bin</code>
- <taglist>
- <tag><c>lib</c></tag>
- <item>Application directories.</item>
- <tag><c>erts-EVsn/bin</c></tag>
- <item>Erlang runtime system executables.</item>
- <tag><c>releases/Vsn</c></tag>
- <item><c>.rel</c> file and boot script <c>start.boot</c>. <br></br>
-
- If present in the release package, <br></br>
-<c>relup</c> and/or <c>sys.config</c>.</item>
- <tag><c>bin</c></tag>
- <item>Top level Erlang runtime system executables.</item>
- </taglist>
- <p>Applications are not required to be located under the
- <c>$ROOT/lib</c> directory. Accordingly, several installation
- directories may exist which contain different parts of a
- system. For example, the previous example could be extended as
- follows:</p>
+ <list type="bulleted">
+ <item><c>lib</c> - Application directories</item>
+ <item><c>erts-EVsn/bin</c> - Erlang runtime system executables</item>
+ <item><c>releases/Vsn</c> - <c>.rel</c> file and boot script
+ <c>start.boot</c>; if present in the release package, <c>relup</c>
+ and/or <c>sys.config</c></item>
+ <item><c>bin</c> - Top-level Erlang runtime system executables</item>
+ </list>
+ <p>Applications are not required to be located under directory
+ <c>$ROOT/lib</c>. Several installation directories, which contain
+ different parts of a system, can thus exist.
+ For example, the previous example can be extended as follows:</p>
<pre>
$SECOND_ROOT/.../SApp1-SAVsn1/ebin
/priv
@@ -256,24 +263,24 @@ $THIRD_ROOT/TApp1-TAVsn1/ebin
...
/TAppN-TAVsnN/ebin
/priv</pre>
- <p>The <c>$SECOND_ROOT</c> and <c>$THIRD_ROOT</c> are introduced as
+ <p><c>$SECOND_ROOT</c> and <c>$THIRD_ROOT</c> are introduced as
<c>variables</c> in the call to the <c>systools:make_script/2</c>
function.</p>
<section>
<title>Disk-Less and/or Read-Only Clients</title>
- <p>If a complete system consists of some disk-less and/or
- read-only client nodes, a <c>clients</c> directory should be
- added to the <c>$ROOT</c> directory. By a read-only node we
- mean a node with a read-only file system.</p>
- <p>The <c>clients</c> directory should have one sub-directory
+ <p>If a complete system consists of disk-less and/or
+ read-only client nodes, a <c>clients</c> directory is to be
+ added to the <c>$ROOT</c> directory. A read-only node is
+ a node with a read-only file system.</p>
+ <p>The <c>clients</c> directory is to have one subdirectory
per supported client node. The name of each client directory
- should be the name of the corresponding client node. As a
- minimum, each client directory should contain the <c>bin</c> and
- <c>releases</c> sub-directories. These directories are used to
+ is to be the name of the corresponding client node. As a
+ minimum, each client directory is to contain the <c>bin</c> and
+ <c>releases</c> subdirectories. These directories are used to
store information about installed releases and to appoint the
- current release to the client. Accordingly, the <c>$ROOT</c>
- directory contains the following:</p>
+ current release to the client. The <c>$ROOT</c>
+ directory thus contains the following:</p>
<code type="none">
$ROOT/...
/clients/ClientName1/bin
@@ -283,14 +290,14 @@ $ROOT/...
...
/ClientNameN/bin
/releases/Vsn</code>
- <p>This structure should be used if all clients are running
+ <p>This structure is to be used if all clients are running
the same type of Erlang machine. If there are clients running
different types of Erlang machines, or on different operating
- systems, the <c>clients</c> directory could be divided into one
- sub-directory per type of Erlang machine. Alternatively, you
- can set up one <c>$ROOT</c> per type of machine. For each
+ systems, the <c>clients</c> directory can be divided into one
+ subdirectory per type of Erlang machine. Alternatively, one
+ <c>$ROOT</c> can be set up per type of machine. For each
type, some of the directories specified for the <c>$ROOT</c>
- directory should be included:</p>
+ directory are to be included:</p>
<code type="none">
$ROOT/...
/clients/Type1/lib
diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml
index e4fb5fdca7..3d7a88da3f 100644
--- a/system/doc/design_principles/spec_proc.xml
+++ b/system/doc/design_principles/spec_proc.xml
@@ -8,43 +8,45 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Sys and Proc_Lib</title>
+ <title>sys and proc_lib</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
<file>spec_proc.xml</file>
</header>
- <p>The module <c>sys</c> contains functions for simple debugging of
- processes implemented using behaviours.</p>
- <p>There are also functions that, together with functions in
- the module <c>proc_lib</c>, can be used to implement a
- <em>special process</em>, a process which comply to the OTP design
- principles without making use of a standard behaviour. They can
- also be used to implement user defined (non-standard) behaviours.</p>
- <p>Both <c>sys</c> and <c>proc_lib</c> belong to the STDLIB
- application.</p>
+ <marker id="sys and proc_lib"></marker>
+ <p>The <c>sys</c> module has functions for simple debugging of
+ processes implemented using behaviours. It also has functions that,
+ together with functions in the <c>proc_lib</c> module, can be used
+ to implement a <em>special process</em> that complies to the OTP
+ design principles without using a standard behaviour. These
+ functions can also be used to implement user-defined (non-standard)
+ behaviours.</p>
+ <p>Both <c>sys</c> and <c>proc_lib</c> belong to the STDLIB
+ application.</p>
<section>
<title>Simple Debugging</title>
- <p>The module <c>sys</c> contains some functions for simple debugging
- of processes implemented using behaviours. We use the
- <c>code_lock</c> example from
- the <seealso marker="fsm#ex">gen_fsm</seealso> chapter to
- illustrate this:</p>
+ <p>The <c>sys</c> module has functions for simple debugging of
+ processes implemented using behaviours. The <c>code_lock</c>
+ example from
+ <seealso marker="fsm#ex">gen_fsm Behaviour</seealso>
+ is used to illustrate this:</p>
<pre>
% <input>erl</input>
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
@@ -102,16 +104,18 @@ ok
<section>
<title>Special Processes</title>
- <p>This section describes how to write a process which comply to
- the OTP design principles, without making use of a standard
- behaviour. Such a process should:</p>
+ <p>This section describes how to write a process that complies to
+ the OTP design principles, without using a standard behaviour.
+ Such a process is to:</p>
<list type="bulleted">
- <item>be started in a way that makes the process fit into a
- supervision tree,</item>
- <item>support the <c>sys</c> <seealso marker="#debug">debug facilities</seealso>, and</item>
- <item>take care of <seealso marker="#msg">system messages</seealso>.</item>
+ <item>Be started in a way that makes the process fit into a
+ supervision tree</item>
+ <item>Support the <c>sys</c>
+ <seealso marker="#debug">debug facilities</seealso></item>
+ <item>Take care of
+ <seealso marker="#msg">system messages</seealso>.</item>
</list>
- <p>System messages are messages with special meaning, used in
+ <p>System messages are messages with a special meaning, used in
the supervision tree. Typical system messages are requests for
trace output, and requests to suspend or resume process execution
(used during release handling). Processes implemented using
@@ -120,9 +124,9 @@ ok
<section>
<title>Example</title>
<p>The simple server from
- the <seealso marker="des_princ#ch1">Overview</seealso> chapter,
- implemented using <c>sys</c> and <c>proc_lib</c> so it fits into
- a supervision tree:</p>
+ <seealso marker="des_princ#ch1">Overview</seealso>,
+ implemented using <c>sys</c> and <c>proc_lib</c> so it fits into a
+ supervision tree:</p>
<marker id="ex"></marker>
<pre>
-module(ch4).
@@ -190,8 +194,8 @@ system_replace_state(StateFun, Chs) ->
write_debug(Dev, Event, Name) ->
io:format(Dev, "~p event = ~p~n", [Name, Event]).</pre>
- <p>Example on how the simple debugging functions in <c>sys</c> can
- be used for <c>ch4</c> as well:</p>
+ <p>Example on how the simple debugging functions in the <c>sys</c>
+ module can also be used for <c>ch4</c>:</p>
<pre>
% <input>erl</input>
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
@@ -230,31 +234,32 @@ ok
<section>
<title>Starting the Process</title>
- <p>A function in the <c>proc_lib</c> module should be used to
- start the process. There are several possible functions, for
- example <c>spawn_link/3,4</c> for asynchronous start and
+ <p>A function in the <c>proc_lib</c> module is to be used to
+ start the process. Several functions are available, for
+ example, <c>spawn_link/3,4</c> for asynchronous start and
<c>start_link/3,4,5</c> for synchronous start.</p>
- <p>A process started using one of these functions will store
- information that is needed for a process in a supervision tree,
- for example about the ancestors and initial call.</p>
- <p>Also, if the process terminates with another reason than
- <c>normal</c> or <c>shutdown</c>, a crash report (see SASL
- User's Guide) is generated.</p>
- <p>In the example, synchronous start is used. The process is
- started by calling <c>ch4:start_link()</c>:</p>
+ <p>A process started using one of these functions stores
+ information (for example, about the ancestors and initial call)
+ that is needed for a process in a supervision tree.</p>
+ <p>If the process terminates with another reason than
+ <c>normal</c> or <c>shutdown</c>, a crash report is generated.
+ For more information about the crash report, see the SASL
+ User's Guide.</p>
+ <p>In the example, synchronous start is used. The process
+ starts by calling <c>ch4:start_link()</c>:</p>
<code type="none">
start_link() ->
proc_lib:start_link(ch4, init, [self()]).</code>
<p><c>ch4:start_link</c> calls the function
<c>proc_lib:start_link</c>. This function takes a module name,
- a function name and an argument list as arguments and spawns
+ a function name, and an argument list as arguments, spawns,
and links to a new process. The new process starts by executing
- the given function, in this case <c>ch4:init(Pid)</c>, where
- <c>Pid</c> is the pid (<c>self()</c>) of the first process, that
- is the parent process.</p>
- <p>In <c>init</c>, all initialization including name registration
- is done. The new process must also acknowledge that it has been
- started to the parent:</p>
+ the given function, here <c>ch4:init(Pid)</c>, where
+ <c>Pid</c> is the pid (<c>self()</c>) of the first process,
+ which is the parent process.</p>
+ <p>All initialization, including name registration, is done in
+ <c>init</c>. The new process must also acknowledge that it has
+ been started to the parent:</p>
<code type="none">
init(Parent) ->
...
@@ -267,8 +272,8 @@ init(Parent) ->
<section>
<marker id="debug"></marker>
<title>Debugging</title>
- <p>To support the debug facilites in <c>sys</c>, we need a
- <em>debug structure</em>, a term <c>Deb</c> which is
+ <p>To support the debug facilites in <c>sys</c>, a
+ <em>debug structure</em> is needed. The <c>Deb</c> term is
initialized using <c>sys:debug_options/1</c>:</p>
<code type="none">
init(Parent) ->
@@ -278,50 +283,41 @@ init(Parent) ->
loop(Chs, Parent, Deb).</code>
<p><c>sys:debug_options/1</c> takes a list of options as argument.
Here the list is empty, which means no debugging is enabled
- initially. See <c>sys(3)</c> for information about possible
- options.</p>
- <p>Then for each <em>system event</em> that we want to be logged
- or traced, the following function should be called.</p>
+ initially. For information about the possible options, see the
+ <c>sys(3)</c> manual page in STDLIB.</p>
+ <p>Then, for each <em>system event</em> to be logged
+ or traced, the following function is to be called.</p>
<code type="none">
sys:handle_debug(Deb, Func, Info, Event) => Deb1</code>
+<p>Here:</p>
<list type="bulleted">
- <item>
- <p><c>Deb</c> is the debug structure.</p>
- </item>
- <item>
- <p><c>Func</c> is a fun specifying
- a (user defined) function used to format
+ <item><c>Deb</c> is the debug structure.</item>
+ <item><c>Func</c> is a fun specifying
+ a (user-defined) function used to format
trace output. For each system event, the format function is
- called as <c>Func(Dev, Event, Info)</c>, where:</p>
+ called as <c>Func(Dev, Event, Info)</c>, where:
<list type="bulleted">
- <item>
- <p><c>Dev</c> is the IO device to which the output should
- be printed. See <c>io(3)</c>.</p>
- </item>
- <item>
- <p><c>Event</c> and <c>Info</c> are passed as-is from
- <c>handle_debug</c>.</p>
- </item>
+ <item><c>Dev</c> is the I/O device to which the output is to
+ be printed. See the <c>io(3)</c> manual page in
+ STDLIB.</item>
+ <item><c>Event</c> and <c>Info</c> are passed as is from
+ <c>handle_debug</c>.</item>
</list>
</item>
- <item>
- <p><c>Info</c> is used to pass additional information to
- <c>Func</c>, it can be any term and is passed as-is.</p>
- </item>
- <item>
- <p><c>Event</c> is the system event. It is up to the user to
- define what a system event is and how it should be
- represented, but typically at least incoming and outgoing
+ <item><c>Info</c> is used to pass more information to
+ <c>Func</c>. It can be any term and is passed as is.</item>
+ <item><c>Event</c> is the system event. It is up to the user to
+ define what a system event is and how it is to be
+ represented. Typically at least incoming and outgoing
messages are considered system events and represented by
the tuples <c>{in,Msg[,From]}</c> and <c>{out,Msg,To}</c>,
- respectively.</p>
- </item>
+ respectively.</item>
</list>
<p><c>handle_debug</c> returns an updated debug structure
<c>Deb1</c>.</p>
<p>In the example, <c>handle_debug</c> is called for each incoming
and outgoing message. The format function <c>Func</c> is
- the function <c>ch4:write_debug/3</c> which prints the message
+ the function <c>ch4:write_debug/3</c>, which prints the message
using <c>io:format/3</c>.</p>
<code type="none">
loop(Chs, Parent, Deb) ->
@@ -354,22 +350,22 @@ write_debug(Dev, Event, Name) ->
{system, From, Request}</code>
<p>The content and meaning of these messages do not need to be
interpreted by the process. Instead the following function
- should be called:</p>
+ is to be called:</p>
<code type="none">
sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</code>
- <p>This function does not return. It will handle the system
- message and then call:</p>
+ <p>This function does not return. It handles the system
+ message and then either calls the following if process execution is
+ to continue:</p>
<code type="none">
Module:system_continue(Parent, Deb, State)</code>
- <p>if process execution should continue, or:</p>
+ <p>Or calls the following if the process is to terminate:</p>
<code type="none">
Module:system_terminate(Reason, Parent, Deb, State)</code>
- <p>if the process should terminate. Note that a process in a
- supervision tree is expected to terminate with the same reason as
- its parent.</p>
+ <p>A process in a supervision tree is expected to terminate with
+ the same reason as its parent.</p>
<list type="bulleted">
- <item><c>Request</c> and <c>From</c> should be passed as-is from
- the system message to the call to <c>handle_system_msg</c>.</item>
+ <item><c>Request</c> and <c>From</c> are to be passed as is from
+ the system message to the call to <c>handle_system_msg</c>.</item>
<item><c>Parent</c> is the pid of the parent.</item>
<item><c>Module</c> is the name of the module.</item>
<item><c>Deb</c> is the debug structure.</item>
@@ -377,10 +373,12 @@ Module:system_terminate(Reason, Parent, Deb, State)</code>
is passed to <c>system_continue</c>/<c>system_terminate</c>/
<c>system_get_state</c>/<c>system_replace_state</c>.</item>
</list>
- <p>If the process should return its state <c>handle_system_msg</c> will call:</p>
+ <p>If the process is to return its state, <c>handle_system_msg</c>
+ calls:</p>
<code type="none">
Module:system_get_state(State)</code>
- <p>or if the process should replace its state using the fun <c>StateFun</c>:</p>
+ <p>If the process is to replace its state using the fun <c>StateFun</c>,
+ <c>handle_system_msg</c> calls:</p>
<code type="none">
Module:system_replace_state(StateFun, State)</code>
<p>In the example:</p>
@@ -407,9 +405,9 @@ system_replace_state(StateFun, Chs) ->
NChs = StateFun(Chs),
{ok, NChs, NChs}.
</code>
- <p>If the special process is set to trap exits, note that if
- the parent process terminates, the expected behavior is to
- terminate with the same reason:</p>
+ <p>If the special process is set to trap exits and if the parent
+ process terminates, the expected behavior is to terminate with
+ the same reason:</p>
<code type="none">
init(...) ->
...,
@@ -431,43 +429,74 @@ loop(...) ->
<section>
<title>User-Defined Behaviours</title>
- <p><marker id="behaviours"/>To implement a user-defined behaviour, write code similar to
- code for a special process but calling functions in a callback
+ <p><marker id="behaviours"/>To implement a user-defined behaviour,
+ write code similar to
+ code for a special process, but call functions in a callback
module for handling specific tasks.</p>
- <p>If it is desired that the compiler should warn for missing callback
- functions, as it does for the OTP behaviours, add <c>-callback</c> attributes in the
+ <p>If the compiler is to warn for missing callback functions, as it
+ does for the OTP behaviours, add <c>-callback</c> attributes in the
behaviour module to describe the expected callbacks:</p>
<code type="none">
-callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -> Res1.
-callback Name2(Arg2_1, Arg2_2, ..., Arg2_N2) -> Res2.
...
-callback NameM(ArgM_1, ArgM_2, ..., ArgM_NM) -> ResM.</code>
- <p>where <c>NameX</c> are the names of the expected callbacks and
- <c>ArgX_Y</c>, <c>ResX</c> are types as they are described in Specifications
- for functions in <seealso marker="../reference_manual/typespec">Types and
- Function Specifications</seealso>. The whole syntax of <c>-spec</c> attribute is
- supported by <c>-callback</c> attribute.</p>
- <p>Alternatively you may directly implement and export the function:</p>
+ <p><c>NameX</c> are the names of the expected callbacks.
+ <c>ArgX_Y</c> and <c>ResX</c> are types as they are described in
+ <seealso marker="../reference_manual/typespec">Types and
+ Function Specifications</seealso>. The whole syntax of the <c>-spec</c>
+ attribute is supported by the <c>-callback</c> attribute.</p>
+ <p>Callback functions that are optional for the user of the
+ behaviour to implement are specified by use of the
+ <c>-optional_callbacks</c> attribute:</p>
+
+<code type="none">
+-optional_callbacks([OptName1/OptArity1, ..., OptNameK/OptArityK]).</code>
+
+ <p>where each <c>OptName/OptArity</c> specifies the name and arity
+ of a callback function. Note that the <c>-optional_callbacks</c>
+ attribute is to be used together with the <c>-callback</c>
+ attribute; it cannot be combined with the
+ <c>behaviour_info()</c> function described below.</p>
+ <p>Tools that need to know about optional callback functions can
+ call <c>Behaviour:behaviour_info(optional_callbacks)</c> to get
+ a list of all optional callback functions.</p>
+
+ <note><p>We recommend using the <c>-callback</c> attribute rather
+ than the <c>behaviour_info()</c> function. The reason is that
+ the extra type information can be used by tools to produce
+ documentation or find discrepancies.</p></note>
+
+ <p>As an alternative to the <c>-callback</c> and
+ <c>-optional_callbacks</c> attributes you may directly implement
+ and export <c>behaviour_info()</c>:</p>
+
<code type="none">
behaviour_info(callbacks) ->
[{Name1, Arity1},...,{NameN, ArityN}].</code>
- <p>where each <c>{Name, Arity}</c> specifies the name and arity of a callback
- function. This function is otherwise automatically generated by the compiler
- using the <c>-callback</c> attributes.</p>
+
+ <p>where each <c>{Name, Arity}</c> specifies the name and arity of
+ a callback function. This function is otherwise automatically
+ generated by the compiler using the <c>-callback</c>
+ attributes.</p>
<p>When the compiler encounters the module attribute
- <c>-behaviour(Behaviour).</c> in a module <c>Mod</c>, it will call
- <c>Behaviour:behaviour_info(callbacks)</c> and compare the result with the
- set of functions actually exported from <c>Mod</c>, and issue a warning if
- any callback function is missing.</p>
+ <c>-behaviour(Behaviour).</c> in a module <c>Mod</c>, it
+ calls <c>Behaviour:behaviour_info(callbacks)</c> and compares the
+ result with the set of functions actually exported from
+ <c>Mod</c>, and issues a warning if any callback function is
+ missing.</p>
<p>Example:</p>
<code type="none">
%% User-defined behaviour module
-module(simple_server).
--export([start_link/2,...]).
+-export([start_link/2, init/3, ...]).
-callback init(State :: term()) -> 'ok'.
-callback handle_req(Req :: term(), State :: term()) -> {'ok', Reply :: term()}.
-callback terminate() -> 'ok'.
+-callback format_state(State :: term()) -> term().
+
+-optional_callbacks([format_state/1]).
%% Alternatively you may define:
%%
diff --git a/system/doc/design_principles/sup_princ.xml b/system/doc/design_principles/sup_princ.xml
index 11ef3813d6..5e2f6ba9cb 100644
--- a/system/doc/design_principles/sup_princ.xml
+++ b/system/doc/design_principles/sup_princ.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,15 +29,16 @@
<rev></rev>
<file>sup_princ.xml</file>
</header>
- <p>This section should be read in conjunction with
- <c>supervisor(3)</c>, where all details about the supervisor
+ <p>This section should be read with the
+ <seealso marker="stdlib:supervisor">supervisor(3)</seealso> manual page
+ in STDLIB, where all details about the supervisor
behaviour is given.</p>
<section>
<title>Supervision Principles</title>
- <p>A supervisor is responsible for starting, stopping and
+ <p>A supervisor is responsible for starting, stopping, and
monitoring its child processes. The basic idea of a supervisor is
- that it should keep its child processes alive by restarting them
+ that it is to keep its child processes alive by restarting them
when necessary.</p>
<p>Which child processes to start and monitor is specified by a
list of <seealso marker="#spec">child specifications</seealso>.
@@ -47,8 +49,8 @@
<section>
<title>Example</title>
<p>The callback module for a supervisor starting the server from
- the <seealso marker="gen_server_concepts#ex">gen_server chapter</seealso>
- could look like this:</p>
+ <seealso marker="gen_server_concepts#ex">gen_server Behaviour</seealso>
+ can look as follows:</p>
<marker id="ex"></marker>
<code type="none">
-module(ch_sup).
@@ -61,18 +63,60 @@ start_link() ->
supervisor:start_link(ch_sup, []).
init(_Args) ->
- {ok, {{one_for_one, 1, 60},
- [{ch3, {ch3, start_link, []},
- permanent, brutal_kill, worker, [ch3]}]}}.</code>
- <p><c>one_for_one</c> is the <seealso marker="#strategy">restart strategy</seealso>.</p>
- <p>1 and 60 defines the <seealso marker="#frequency">maximum restart frequency</seealso>.</p>
- <p>The tuple <c>{ch3, ...}</c> is a <seealso marker="#spec">child specification</seealso>.</p>
+ SupFlags = #{strategy => one_for_one, intensity => 1, period => 5},
+ ChildSpecs = [#{id => ch3,
+ start => {ch3, start_link, []},
+ restart => permanent,
+ shutdown => brutal_kill,
+ type => worker,
+ modules => [cg3]}],
+ {ok, {SupFlags, ChildSpecs}}.</code>
+ <p>The <c>SupFlags</c> variable in the return value
+ from <c>init/1</c> represents
+ the <seealso marker="#flags">supervisor flags</seealso>.</p>
+ <p>The <c>ChildSpecs</c> variable in the return value
+ from <c>init/1</c> is a list of <seealso marker="#spec">child
+ specifications</seealso>.</p>
+ </section>
+
+ <section>
+ <title>Supervisor Flags</title>
+ <marker id="flags"/>
+ <p>This is the type definition for the supervisor flags:</p>
+ <code type="none"><![CDATA[
+sup_flags() = #{strategy => strategy(), % optional
+ intensity => non_neg_integer(), % optional
+ period => pos_integer()} % optional
+ strategy() = one_for_all
+ | one_for_one
+ | rest_for_one
+ | simple_one_for_one]]></code>
+ <list type="bulleted">
+ <item>
+ <p><c>strategy</c> specifies
+ the <seealso marker="#strategy">restart
+ strategy</seealso>.</p>
+ </item>
+ <item>
+ <p><c>intensity</c> and <c>period</c> specify
+ the <seealso marker="#max_intensity">maximum restart
+ intensity</seealso>.</p>
+ </item>
+ </list>
</section>
<section>
<marker id="strategy"></marker>
<title>Restart Strategy</title>
+ <p> The restart strategy is specified by
+ the <c>strategy</c> key in the supervisor flags map returned by
+ the callback function <c>init</c>:</p>
+ <code type="none">
+SupFlags = #{strategy => Strategy, ...}</code>
+ <p>The <c>strategy</c> key is optional in this map. If it is not
+ given, it defaults to <c>one_for_one</c>.</p>
+
<section>
<title>one_for_one</title>
<p>If a child process terminates, only that process is restarted.</p>
@@ -85,7 +129,7 @@ init(_Args) ->
<section>
<title>one_for_all</title>
<p>If a child process terminates, all other child processes are
- terminated and then all child processes, including
+ terminated, and then all child processes, including
the terminated one, are restarted.</p>
<marker id="sup5"></marker>
<image file="../design_principles/sup5.gif">
@@ -95,165 +139,208 @@ init(_Args) ->
<section>
<title>rest_for_one</title>
- <p>If a child process terminates, the 'rest' of the child
- processes -- i.e. the child processes after the terminated
- process in start order -- are terminated. Then the terminated
+ <p>If a child process terminates, the rest of the child
+ processes (that is, the child processes after the terminated
+ process in start order) are terminated. Then the terminated
child process and the rest of the child processes are restarted.</p>
</section>
+
+ <section>
+ <title>simple_one_for_one</title>
+ <p>See <seealso marker="#simple">simple-one-for-one
+ supervisors</seealso>.</p>
+ </section>
</section>
<section>
- <marker id="frequency"></marker>
- <title>Maximum Restart Frequency</title>
+ <marker id="max_intensity"></marker>
+ <title>Maximum Restart Intensity</title>
<p>The supervisors have a built-in mechanism to limit the number of
restarts which can occur in a given time interval. This is
- determined by the values of the two parameters <c>MaxR</c> and
- <c>MaxT</c> in the start specification returned by the callback
- function <c>init</c>:</p>
+ specified by the two keys <c>intensity</c> and
+ <c>period</c> in the supervisor flags map returned by the
+ callback function <c>init</c>:</p>
<code type="none">
-init(...) ->
- {ok, {{RestartStrategy, MaxR, MaxT},
- [ChildSpec, ...]}}.</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, then the supervisor terminates all the child
+ <c>MaxT</c> seconds, the supervisor terminates all the child
processes and then itself.</p>
- <p>When the supervisor terminates, then the next higher level
+ <p>When the supervisor terminates, then the next higher-level
supervisor takes some action. It either restarts the terminated
- supervisor, or terminates itself.</p>
+ supervisor or terminates itself.</p>
<p>The intention of the restart mechanism is to prevent a situation
where a process repeatedly dies for the same reason, only to be
restarted again.</p>
+ <p>The keys <c>intensity</c> and <c>period</c> are optional in the
+ supervisor flags map. If they are not given, they default
+ to <c>1</c> and <c>5</c>, respectively.</p>
</section>
<section>
<marker id="spec"></marker>
<title>Child Specification</title>
- <p>This is the type definition for a child specification:</p>
+ <p>The type definition for a child specification is as follows:</p>
<code type="none"><![CDATA[
-{Id, StartFunc, Restart, Shutdown, Type, Modules}
- Id = term()
- StartFunc = {M, F, A}
- M = F = atom()
- A = [term()]
- Restart = permanent | transient | temporary
- Shutdown = brutal_kill | integer()>0 | infinity
- Type = worker | supervisor
- Modules = [Module] | dynamic
- Module = atom()]]></code>
+child_spec() = #{id => child_id(), % mandatory
+ start => mfargs(), % mandatory
+ restart => restart(), % optional
+ shutdown => shutdown(), % optional
+ type => worker(), % optional
+ modules => modules()} % optional
+ child_id() = term()
+ mfargs() = {M :: module(), F :: atom(), A :: [term()]}
+ modules() = [module()] | dynamic
+ restart() = permanent | transient | temporary
+ shutdown() = brutal_kill | timeout()
+ worker() = worker | supervisor]]></code>
<list type="bulleted">
<item>
- <p><c>Id</c> is a name that is used to identify the child
+ <p><c>id</c> is used to identify the child
specification internally by the supervisor.</p>
+ <p>The <c>id</c> key is mandatory.</p>
+ <p>Note that this identifier occasionally has been called
+ "name". As far as possible, the terms "identifier" or "id"
+ are now used but in order to keep backwards compatibility,
+ some occurences of "name" can still be found, for example
+ in error messages.</p>
</item>
<item>
- <p><c>StartFunc</c> defines the function call used to start
+ <p><c>start</c> defines the function call used to start
the child process. It is a module-function-arguments tuple
used as <c>apply(M, F, A)</c>.</p>
- <p>It should be (or result in) a call to
- <c>supervisor:start_link</c>, <c>gen_server:start_link</c>,
- <c>gen_fsm:start_link</c> or <c>gen_event:start_link</c>.
- (Or a function compliant with these functions, see
- <c>supervisor(3)</c> for details.</p>
+ <p>It is to be (or result in) a call to any of the following:</p>
+ <list type="bulleted">
+ <item><c>supervisor:start_link</c></item>
+ <item><c>gen_server:start_link</c></item>
+ <item><c>gen_fsm:start_link</c></item>
+ <item><c>gen_event:start_link</c></item>
+ <item>A function compliant with these functions. For details,
+ see the <c>supervisor(3)</c> manual page.</item>
+ </list>
+ <p>The <c>start</c> key is mandatory.</p>
</item>
<item>
- <p><c>Restart</c> defines when a terminated child process should
+ <p><c>restart</c> defines when a terminated child process is to
be restarted.</p>
<list type="bulleted">
<item>A <c>permanent</c> child process is always restarted.</item>
<item>A <c>temporary</c> child process is never restarted
- (not even when the supervisor's restart strategy
- is <c>rest_for_one</c> or <c>one_for_all</c> and a sibling's
+ (not even when the supervisor restart strategy
+ is <c>rest_for_one</c> or <c>one_for_all</c> and a sibling
death causes the temporary process to be terminated).</item>
<item>A <c>transient</c> child process is restarted only if it
- terminates abnormally, i.e. with another exit reason than
- <c>normal</c>, <c>shutdown</c> or <c>{shutdown,Term}</c>.</item>
+ terminates abnormally, that is, with another exit reason than
+ <c>normal</c>, <c>shutdown</c>, or <c>{shutdown,Term}</c>.</item>
</list>
+ <p>The <c>restart</c> key is optional. If it is not given, the
+ default value <c>permanent</c> will be used.</p>
</item>
<item>
<marker id="shutdown"></marker>
- <p><c>Shutdown</c> defines how a child process should be
+ <p><c>shutdown</c> defines how a child process is to be
terminated.</p>
<list type="bulleted">
- <item><c>brutal_kill</c> means the child process is
+ <item><c>brutal_kill</c> means that the child process is
unconditionally terminated using <c>exit(Child, kill)</c>.</item>
- <item>An integer timeout value means that the supervisor tells
+ <item>An integer time-out value means that the supervisor tells
the child process to terminate by calling
<c>exit(Child, shutdown)</c> and then waits for an exit
signal back. If no exit signal is received within
the specified time, the child process is unconditionally
terminated using <c>exit(Child, kill)</c>.</item>
- <item>If the child process is another supervisor, it should be
+ <item>If the child process is another supervisor, it is to be
set to <c>infinity</c> to give the subtree enough time to
- shutdown. It is also allowed to set it to <c>infinity</c>, if the
- child process is a worker.</item>
+ shut down. It is also allowed to set it to <c>infinity</c>,
+ if the child process is a worker. See the warning below:</item>
</list>
<warning>
- <p>Be careful by setting the <c>Shutdown</c> strategy to
+ <p>Be careful when setting the shutdown time to
<c>infinity</c> when the child process is a worker. Because, in this
situation, the termination of the supervision tree depends on the
- child process, it must be implemented in a safe way and its cleanup
+ child process; it must be implemented in a safe way and its cleanup
procedure must always return.</p>
</warning>
+ <p>The <c>shutdown</c> key is optional. If it is not given,
+ and the child is of type <c>worker</c>, the default value
+ <c>5000</c> will be used; if the child is of type
+ <c>supervisor</c>, the default value <c>infinity</c> will be
+ used.</p>
</item>
<item>
- <p><c>Type</c> specifies if the child process is a supervisor or
+ <p><c>type</c> specifies if the child process is a supervisor or
a worker.</p>
+ <p>The <c>type</c> key is optional. If it is not given, the
+ default value <c>worker</c> will be used.</p>
</item>
<item>
- <p><c>Modules</c> should be a list with one element
+ <p><c>modules</c> are to be a list with one element
<c>[Module]</c>, where <c>Module</c> is the name of
the callback module, if the child process is a supervisor,
gen_server or gen_fsm. If the child process is a gen_event,
- <c>Modules</c> should be <c>dynamic</c>.</p>
+ the value shall be <c>dynamic</c>.</p>
<p>This information is used by the release handler during
upgrades and downgrades, see
<seealso marker="release_handling">Release Handling</seealso>.</p>
+ <p>The <c>modules</c> key is optional. If it is not given, it
+ defaults to <c>[M]</c>, where <c>M</c> comes from the
+ child's start <c>{M,F,A}</c>.</p>
</item>
</list>
- <p>Example: The child specification to start the server <c>ch3</c>
- in the example above looks like:</p>
+ <p><em>Example:</em> The child specification to start the server
+ <c>ch3</c> in the previous example look as follows:</p>
+ <code type="none">
+#{id => ch3,
+ start => {ch3, start_link, []},
+ restart => permanent,
+ shutdown => brutal_kill,
+ type => worker,
+ modules => [ch3]}</code>
+ <p>or simplified, relying on the default values:</p>
<code type="none">
-{ch3,
- {ch3, start_link, []},
- permanent, brutal_kill, worker, [ch3]}</code>
+#{id => ch3,
+ start => {ch3, start_link, []}
+ shutdown => brutal_kill}</code>
<p>Example: A child specification to start the event manager from
the chapter about
<seealso marker="events#mgr">gen_event</seealso>:</p>
<code type="none">
-{error_man,
- {gen_event, start_link, [{local, error_man}]},
- permanent, 5000, worker, dynamic}</code>
- <p>Both the server and event manager are registered processes which
- can be expected to be accessible at all times, thus they are
+#{id => error_man,
+ start => {gen_event, start_link, [{local, error_man}]},
+ modules => dynamic}</code>
+ <p>Both server and event manager are registered processes which
+ can be expected to be always accessible. Thus they are
specified to be <c>permanent</c>.</p>
<p><c>ch3</c> does not need to do any cleaning up before
- termination, thus no shutdown time is needed but
- <c>brutal_kill</c> should be sufficient. <c>error_man</c> may
+ termination. Thus, no shutdown time is needed, but
+ <c>brutal_kill</c> is sufficient. <c>error_man</c> can
need some time for the event handlers to clean up, thus
- <c>Shutdown</c> is set to 5000 ms.</p>
+ the shutdown time is set to 5000 ms (which is the default
+ value).</p>
<p>Example: A child specification to start another supervisor:</p>
<code type="none">
-{sup,
- {sup, start_link, []},
- transient, infinity, supervisor, [sup]}</code>
+#{id => sup,
+ start => {sup, start_link, []},
+ restart => transient,
+ type => supervisor} % will cause default shutdown=>infinity</code>
</section>
<section>
<marker id="super_tree"></marker>
<title>Starting a Supervisor</title>
- <p>In the example above, the supervisor is started by calling
+ <p>In the previous example, the supervisor is started by calling
<c>ch_sup:start_link()</c>:</p>
<code type="none">
start_link() ->
supervisor:start_link(ch_sup, []).</code>
- <p><c>ch_sup:start_link</c> calls the function
- <c>supervisor:start_link/2</c>. This function spawns and links to
- a new process, a supervisor.</p>
+ <p><c>ch_sup:start_link</c> calls function
+ <c>supervisor:start_link/2</c>, which spawns and links to a new
+ process, a supervisor.</p>
<list type="bulleted">
<item>The first argument, <c>ch_sup</c>, is the name of
- the callback module, that is the module where the <c>init</c>
+ the callback module, that is, the module where the <c>init</c>
callback function is located.</item>
- <item>The second argument, [], is a term which is passed as-is to
+ <item>The second argument, <c>[]</c>, is a term that is passed
+ as is to
the callback function <c>init</c>. Here, <c>init</c> does not
need any indata and ignores the argument.</item>
</list>
@@ -262,34 +349,37 @@ start_link() ->
<c>supervisor:start_link({local, Name}, Module, Args)</c> or
<c>supervisor:start_link({global, Name}, Module, Args)</c>.</p>
<p>The new supervisor process calls the callback function
- <c>ch_sup:init([])</c>. <c>init</c> is expected to return
- <c>{ok, StartSpec}</c>:</p>
+ <c>ch_sup:init([])</c>. <c>init</c> shall return
+ <c>{ok, {SupFlags, ChildSpecs}}</c>:</p>
<code type="none">
init(_Args) ->
- {ok, {{one_for_one, 1, 60},
- [{ch3, {ch3, start_link, []},
- permanent, brutal_kill, worker, [ch3]}]}}.</code>
+ SupFlags = #{},
+ ChildSpecs = [#{id => ch3,
+ start => {ch3, start_link, []},
+ shutdown => brutal_kill}],
+ {ok, {SupFlags, ChildSpecs}}.</code>
<p>The supervisor then starts all its child processes according to
the child specifications in the start specification. In this case
there is one child process, <c>ch3</c>.</p>
- <p>Note that <c>supervisor:start_link</c> is synchronous. It does
+ <p><c>supervisor:start_link</c> is synchronous. It does
not return until all child processes have been started.</p>
</section>
<section>
<title>Adding a Child Process</title>
- <p>In addition to the static supervision tree, we can also add
- dynamic child processes to an existing supervisor with
- the following call:</p>
+ <p>In addition to the static supervision tree, dynamic child
+ processes can be added to an existing supervisor with the following
+ call:</p>
<code type="none">
supervisor:start_child(Sup, ChildSpec)</code>
<p><c>Sup</c> is the pid, or name, of the supervisor.
- <c>ChildSpec</c> is a <seealso marker="#spec">child specification</seealso>.</p>
+ <c>ChildSpec</c> is a
+ <seealso marker="#spec">child specification</seealso>.</p>
<p>Child processes added using <c>start_child/2</c> behave in
- the same manner as the other child processes, with the following
- important exception: If a supervisor dies and is re-created, then
- all child processes which were dynamically added to the supervisor
- will be lost.</p>
+ the same way as the other child processes, with the an important
+ exception: if a supervisor dies and is recreated, then
+ all child processes that were dynamically added to the supervisor
+ are lost.</p>
</section>
<section>
@@ -303,18 +393,21 @@ supervisor:terminate_child(Sup, Id)</code>
<code type="none">
supervisor:delete_child(Sup, Id)</code>
<p><c>Sup</c> is the pid, or name, of the supervisor.
- <c>Id</c> is the id specified in the <seealso marker="#spec">child specification</seealso>.</p>
+ <c>Id</c> is the value associated with the <c>id</c> key in
+ the <seealso marker="#spec">child specification</seealso>.</p>
<p>As with dynamically added child processes, the effects of
deleting a static child process is lost if the supervisor itself
restarts.</p>
</section>
+ <marker id="simple"/>
<section>
- <title>Simple-One-For-One Supervisors</title>
+ <title>Simplified one_for_one Supervisors</title>
<p>A supervisor with restart strategy <c>simple_one_for_one</c> is
- a simplified one_for_one supervisor, where all child processes are
- dynamically added instances of the same process.</p>
- <p>Example of a callback module for a simple_one_for_one supervisor:</p>
+ a simplified <c>one_for_one</c> supervisor, where all child
+ processes are dynamically added instances of the same process.</p>
+ <p>The following is an example of a callback module for a
+ <c>simple_one_for_one</c> supervisor:</p>
<code type="none">
-module(simple_sup).
-behaviour(supervisor).
@@ -326,45 +419,49 @@ start_link() ->
supervisor:start_link(simple_sup, []).
init(_Args) ->
- {ok, {{simple_one_for_one, 0, 1},
- [{call, {call, start_link, []},
- temporary, brutal_kill, worker, [call]}]}}.</code>
- <p>When started, the supervisor will not start any child processes.
+ SupFlags = #{strategy => simple_one_for_one,
+ intensity => 0,
+ period => 1},
+ ChildSpecs = [#{id => call,
+ start => {call, start_link, []},
+ shutdown => brutal_kill}],
+ {ok, {SupFlags, ChildSpecs}}.</code>
+ <p>When started, the supervisor does not start any child processes.
Instead, all child processes are added dynamically by calling:</p>
<code type="none">
supervisor:start_child(Sup, List)</code>
<p><c>Sup</c> is the pid, or name, of the supervisor.
- <c>List</c> is an arbitrary list of terms which will be added to
+ <c>List</c> is an arbitrary list of terms, which are added to
the list of arguments specified in the child specification. If
- the start function is specified as <c>{M, F, A}</c>, then
+ the start function is specified as <c>{M, F, A}</c>,
the child process is started by calling
<c>apply(M, F, A++List)</c>.</p>
<p>For example, adding a child to <c>simple_sup</c> above:</p>
<code type="none">
supervisor:start_child(Pid, [id1])</code>
- <p>results in the child process being started by calling
+ <p>The result is that the child process is started by calling
<c>apply(call, start_link, []++[id1])</c>, or actually:</p>
<code type="none">
call:start_link(id1)</code>
- <p>A child under a <c>simple_one_for_one</c> supervisor can be terminated
- with</p>
+ <p>A child under a <c>simple_one_for_one</c> supervisor can be
+ terminated with the following:</p>
<code type="none">
supervisor:terminate_child(Sup, Pid)</code>
- <p>where <c>Sup</c> is the pid, or name, of the supervisor and
+ <p><c>Sup</c> is the pid, or name, of the supervisor and
<c>Pid</c> is the pid of the child.</p>
- <p>Because a <c>simple_one_for_one</c> supervisor could have many children,
- it shuts them all down at same time. So, order in which they are stopped is
- not defined. For the same reason, it could have an overhead with regards to
- the <c>Shutdown</c> strategy.</p>
+ <p>Because a <c>simple_one_for_one</c> supervisor can have many
+ children, it shuts them all down asynchronously. This means that
+ the children will do their cleanup in parallel and therefore the
+ order in which they are stopped is not defined.</p>
</section>
<section>
<title>Stopping</title>
- <p>Since the supervisor is part of a supervision tree, it will
- automatically be terminated by its supervisor. When asked to
- shutdown, it will terminate all child processes in reversed start
+ <p>Since the supervisor is part of a supervision tree, it is
+ automatically terminated by its supervisor. When asked to
+ shut down, it terminates all child processes in reversed start
order according to the respective shutdown specifications, and
- then terminate itself.</p>
+ then terminates itself.</p>
</section>
</chapter>
diff --git a/system/doc/design_principles/xmlfiles.mk b/system/doc/design_principles/xmlfiles.mk
index f34d1c9a0f..3032ac3ab9 100644
--- a/system/doc/design_principles/xmlfiles.mk
+++ b/system/doc/design_principles/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/efficiency_guide/Makefile b/system/doc/efficiency_guide/Makefile
index a995d26361..87997b6e41 100644
--- a/system/doc/efficiency_guide/Makefile
+++ b/system/doc/efficiency_guide/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2001-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml
index 51f1b2612c..d4e47f4f10 100644
--- a/system/doc/efficiency_guide/advanced.xml
+++ b/system/doc/efficiency_guide/advanced.xml
@@ -8,17 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Advanced</title>
@@ -31,175 +31,245 @@
<section>
<title>Memory</title>
- <p>A good start when programming efficiently is to have knowledge about
+ <p>A good start when programming efficiently is to know
how much memory different data types and operations require. It is
implementation-dependent how much memory the Erlang data types and
- other items consume, but here are some figures for the
- erts-5.2 system (OTP release R9B). (There have been no significant
- changes in R13.)</p>
+ other items consume, but the following table shows some figures for
+ the <c>erts-5.2</c> system in R9B. There have been no significant
+ changes in R13.</p>
- <p>The unit of measurement is memory words. There exists both a 32-bit
- and a 64-bit implementation, and a word is therefore, 4 bytes or
+ <p>The unit of measurement is memory words. There exists both a
+ 32-bit and a 64-bit implementation. A word is therefore 4 bytes or
8 bytes, respectively.</p>
<table>
<row>
- <cell align="center" valign="middle">Data type</cell>
- <cell align="center" valign="middle">Memory size</cell>
+ <cell><em>Data Type</em></cell>
+ <cell><em>Memory Size</em></cell>
</row>
<row>
- <cell align="left" valign="middle">Small integer</cell>
- <cell align="left" valign="middle">1 word<br></br>
-On 32-bit architectures: -134217729 &lt; i &lt; 134217728 (28 bits)<br></br>
-On 64-bit architectures: -576460752303423489 &lt; i &lt; 576460752303423488 (60 bits)</cell>
+ <cell>Small integer</cell>
+ <cell>1 word.<br></br>
+ On 32-bit architectures: -134217729 &lt; i &lt; 134217728
+ (28 bits).<br></br>
+ On 64-bit architectures: -576460752303423489 &lt; i &lt;
+ 576460752303423488 (60 bits).</cell>
</row>
<row>
- <cell align="left" valign="middle">Big integer</cell>
- <cell align="left" valign="middle">3..N words</cell>
+ <cell>Large integer</cell>
+ <cell>3..N words.</cell>
</row>
<row>
- <cell align="left" valign="middle">Atom</cell>
- <cell align="left" valign="middle">1 word. Note: an atom refers into
- an atom table which also consumes memory.
+ <cell>Atom</cell>
+ <cell>1 word.<br></br>
+ An atom refers into an atom table, which also consumes memory.
The atom text is stored once for each unique atom in this table.
The atom table is <em>not</em> garbage-collected.</cell>
</row>
<row>
- <cell align="left" valign="middle">Float</cell>
- <cell align="left" valign="middle">On 32-bit architectures: 4 words <br></br>
-On 64-bit architectures: 3 words</cell>
+ <cell>Float</cell>
+ <cell>On 32-bit architectures: 4 words.<br></br>
+ On 64-bit architectures: 3 words.</cell>
</row>
<row>
- <cell align="left" valign="middle">Binary</cell>
- <cell align="left" valign="middle">3..6 + data (can be shared)</cell>
+ <cell>Binary</cell>
+ <cell>3..6 words + data (can be shared).</cell>
</row>
<row>
- <cell align="left" valign="middle">List</cell>
- <cell align="left" valign="middle">1 word + 1 word per element + the size of each element</cell>
+ <cell>List</cell>
+ <cell>1 word + 1 word per element + the size of each element.</cell>
</row>
<row>
- <cell align="left" valign="middle">String (is the same as a list of integers)</cell>
- <cell align="left" valign="middle">1 word + 2 words per character</cell>
+ <cell>String (is the same as a list of integers)</cell>
+ <cell>1 word + 2 words per character.</cell>
</row>
<row>
- <cell align="left" valign="middle">Tuple</cell>
- <cell align="left" valign="middle">2 words + the size of each element</cell>
+ <cell>Tuple</cell>
+ <cell>2 words + the size of each element.</cell>
</row>
<row>
- <cell align="left" valign="middle">Pid</cell>
- <cell align="left" valign="middle">1 word for a process identifier from the current local node, and 5 words for a process identifier from another node. Note: a process identifier refers into a process table and a node table which also consumes memory.</cell>
+ <cell>Pid</cell>
+ <cell>1 word for a process identifier from the current local node
+ + 5 words for a process identifier from another node.<br></br>
+ A process identifier refers into a process table and a node table,
+ which also consumes memory.</cell>
</row>
<row>
- <cell align="left" valign="middle">Port</cell>
- <cell align="left" valign="middle">1 word for a port identifier from the current local node, and 5 words for a port identifier from another node. Note: a port identifier refers into a port table and a node table which also consumes memory.</cell>
+ <cell>Port</cell>
+ <cell>1 word for a port identifier from the current local node
+ + 5 words for a port identifier from another node.<br></br>
+ A port identifier refers into a port table and a node table,
+ which also consumes memory.</cell>
</row>
<row>
- <cell align="left" valign="middle">Reference</cell>
- <cell align="left" valign="middle">On 32-bit architectures: 5 words for a reference from the current local node, and 7 words for a reference from another node. <br></br>
-On 64-bit architectures: 4 words for a reference from the current local node, and 6 words for a reference from another node. Note: a reference refers into a node table which also consumes memory.</cell>
+ <cell>Reference</cell>
+ <cell>On 32-bit architectures: 5 words for a reference from the
+ current local node + 7 words for a reference from another
+ node.<br></br>
+ On 64-bit architectures: 4 words for a reference from the current
+ local node + 6 words for a reference from another node.<br></br>
+ A reference refers into a node table, which also consumes
+ memory.</cell>
</row>
<row>
- <cell align="left" valign="middle">Fun</cell>
- <cell align="left" valign="middle">9..13 words + size of environment. Note: a fun refers into a fun table which also consumes memory.</cell>
+ <cell>Fun</cell>
+ <cell>9..13 words + the size of environment.<br></br>
+ A fun refers into a fun table, which also consumes memory.</cell>
</row>
<row>
- <cell align="left" valign="middle">Ets table</cell>
- <cell align="left" valign="middle">Initially 768 words + the size of each element (6 words + size of Erlang data). The table will grow when necessary.</cell>
+ <cell>Ets table</cell>
+ <cell>Initially 768 words + the size of each element (6 words +
+ the size of Erlang data). The table grows when necessary.</cell>
</row>
<row>
- <cell align="left" valign="middle">Erlang process</cell>
- <cell align="left" valign="middle">327 words when spawned including a heap of 233 words.</cell>
+ <cell>Erlang process</cell>
+ <cell>327 words when spawned, including a heap of 233 words.</cell>
</row>
- <tcaption>Memory size of different data types</tcaption>
+ <tcaption>Memory Size of Different Data Types</tcaption>
</table>
</section>
<section>
- <title>System limits</title>
- <p>The Erlang language specification puts no limits on number of processes,
- length of atoms etc., but for performance and memory saving reasons,
- there will always be limits in a practical implementation of the Erlang
- language and execution environment.</p>
- <taglist>
- <tag><em>Processes</em></tag>
- <item>
- <p>The maximum number of simultaneously alive Erlang processes is
- by default 32768. This limit can be configured at startup,
- for more information see the
- <seealso marker="erts:erl#max_processes"><c>+P</c></seealso>
- command line flag of
- <seealso marker="erts:erl"><c>erl(1)</c></seealso>.</p>
- </item>
- <tag><em>Distributed nodes</em></tag>
- <item>
- <taglist>
- <tag>Known nodes</tag>
- <item>
- <p>A remote node Y has to be known to node X if there exist
- any pids, ports, references, or funs (Erlang data types) from Y
- on X, or if X and Y are connected. The maximum number of remote
- nodes simultaneously/ever known to a node is limited by the
- <seealso marker="#atoms">maximum number of atoms</seealso>
- available for node names. All data concerning remote nodes,
- except for the node name atom, are garbage-collected.</p>
- </item>
- <tag>Connected nodes</tag>
- <item>The maximum number of simultaneously connected nodes is limited by
- either the maximum number of simultaneously known remote nodes,
- <seealso marker="#ports">the maximum number of (Erlang) ports</seealso>
- available, or
- <seealso marker="#files_sockets">the maximum number of sockets</seealso>
- available.</item>
- </taglist>
- </item>
- <tag><em>Characters in an atom</em></tag>
- <item>255</item>
- <tag><em>Atoms </em></tag>
- <item> <marker id="atoms"></marker>
- By default, the maximum number of atoms is 1048576.
- This limit can be raised or lowered using the <c>+t</c> option.</item>
- <tag><em>Ets-tables</em></tag>
- <item>The default is 1400, can be changed with the environment variable <c>ERL_MAX_ETS_TABLES</c>.</item>
- <tag><em>Elements in a tuple</em></tag>
- <item>The maximum number of elements in a tuple is 67108863 (26 bit unsigned integer). Other factors
- such as the available memory can of course make it hard to create a tuple of that size. </item>
- <tag><em>Size of binary</em></tag>
- <item>In the 32-bit implementation of Erlang, 536870911 bytes is the
- largest binary that can be constructed or matched using the bit syntax.
- (In the 64-bit implementation, the maximum size is 2305843009213693951 bytes.)
- If the limit is exceeded, bit syntax construction will fail with a
- <c>system_limit</c> exception, while any attempt to match a binary that is
- too large will fail.
- This limit is enforced starting with the R11B-4 release; in earlier releases,
- operations on too large binaries would in general either fail or give incorrect
- results.
- In future releases of Erlang/OTP, other operations that create binaries (such as
- <c>list_to_binary/1</c>) will probably also enforce the same limit.</item>
- <tag><em>Total amount of data allocated by an Erlang node</em></tag>
- <item>The Erlang runtime system can use the complete 32 (or 64) bit address space,
- but the operating system often limits a single process to use less than that.</item>
- <tag><em>Length of a node name</em></tag>
- <item>An Erlang node name has the form host@shortname or host@longname. The node name is
- used as an atom within the system so the maximum size of 255 holds for the node name too.</item>
- <tag><em>Open ports</em></tag>
- <item>
- <marker id="ports"></marker>
- <p>The maximum number of simultaneously open Erlang ports is
- often by default 16384. This limit can be configured at startup,
- for more information see the
- <seealso marker="erts:erl#max_ports"><c>+Q</c></seealso>
- command line flag of
- <seealso marker="erts:erl"><c>erl(1)</c></seealso>.</p>
- </item>
- <tag><em>Open files, and sockets</em></tag>
- <item> <marker id="files_sockets"></marker>
+ <title>System Limits</title>
+ <p>The Erlang language specification puts no limits on the number of
+ processes, length of atoms, and so on. However, for performance and
+ memory saving reasons, there will always be limits in a practical
+ implementation of the Erlang language and execution environment.</p>
- The maximum number of simultaneously open files and sockets
- depend on
- <seealso marker="#ports">the maximum number of Erlang ports</seealso>
- available, and operating system specific settings and limits.</item>
- <tag><em>Number of arguments to a function or fun</em></tag>
- <item>255</item>
- </taglist>
+ <table>
+ <row>
+ <cell>Processes</cell>
+ <cell>The maximum number of simultaneously alive Erlang processes
+ is by default 32,768. This limit can be configured at startup.
+ For more information, see the
+ <seealso marker="erts:erl#max_processes"><c>+P</c></seealso>
+ command-line flag in the
+ <seealso marker="erts:erl"><c>erl(1)</c></seealso>
+ manual page in <c>erts</c>.</cell>
+ </row>
+ <row>
+ <cell>Known nodes</cell>
+ <cell>A remote node Y must be known to node X if there exists
+ any pids, ports, references, or funs (Erlang data types) from Y
+ on X, or if X and Y are connected. The maximum number of remote
+ nodes simultaneously/ever known to a node is limited by the
+ <seealso marker="#atoms">maximum number of atoms</seealso>
+ available for node names. All data concerning remote nodes,
+ except for the node name atom, are garbage-collected.</cell>
+ </row>
+ <row>
+ <cell>Connected nodes</cell>
+ <cell>The maximum number of simultaneously connected nodes is
+ limited by either the maximum number of simultaneously known
+ remote nodes,
+ <seealso marker="#ports">the maximum number of (Erlang) ports</seealso>
+ available, or
+ <seealso marker="#files_sockets">the maximum number of sockets</seealso>
+ available.</cell>
+ </row>
+ <row>
+ <cell>Characters in an atom</cell>
+ <cell>255.</cell>
+ </row>
+ <row>
+ <cell><marker id="atoms"></marker>Atoms</cell>
+ <cell>By default, the maximum number of atoms is 1,048,576. This
+ limit can be raised or lowered using the <c>+t</c> option.</cell>
+ </row>
+ <row>
+ <cell>Ets tables</cell>
+ <cell>Default is 1400. It can be changed with the environment
+ variable <c>ERL_MAX_ETS_TABLES</c>.</cell>
+ </row>
+ <row>
+ <cell>Elements in a tuple</cell>
+ <cell>The maximum number of elements in a tuple is 67,108,863
+ (26-bit unsigned integer). Clearly, other factors such as the
+ available memory can make it difficult to create a tuple of
+ that size.</cell>
+ </row>
+ <row>
+ <cell>Size of binary</cell>
+ <cell>In the 32-bit implementation of Erlang, 536,870,911
+ bytes is the largest binary that can be constructed or matched
+ using the bit syntax. In the 64-bit implementation, the maximum
+ size is 2,305,843,009,213,693,951 bytes. If the limit is
+ exceeded, bit syntax construction fails with a
+ <c>system_limit</c> exception, while any attempt to match a
+ binary that is too large fails. This limit is enforced starting
+ in R11B-4.<br></br>
+ In earlier Erlang/OTP releases, operations on too large
+ binaries in general either fail or give incorrect results. In
+ future releases, other operations that create binaries (such as
+ <c>list_to_binary/1</c>) will probably also enforce the same
+ limit.</cell>
+ </row>
+ <row>
+ <cell>Total amount of data allocated by an Erlang node</cell>
+ <cell>The Erlang runtime system can use the complete 32-bit
+ (or 64-bit) address space, but the operating system often
+ limits a single process to use less than that.</cell>
+ </row>
+ <row>
+ <cell>Length of a node name</cell>
+ <cell>An Erlang node name has the form host@shortname or
+ host@longname. The node name is used as an atom within
+ the system, so the maximum size of 255 holds also for the
+ node name.</cell>
+ </row>
+ <row>
+ <cell><marker id="ports"></marker>Open ports</cell>
+ <cell>The maximum number of simultaneously open Erlang ports is
+ often by default 16,384. This limit can be configured at startup.
+ For more information, see the
+ <seealso marker="erts:erl#max_ports"><c>+Q</c></seealso>
+ command-line flag in the
+ <seealso marker="erts:erl"><c>erl(1)</c></seealso> manual page
+ in <c>erts</c>.</cell>
+ </row>
+ <row>
+ <cell><marker id="files_sockets"></marker>Open files and
+ sockets</cell>
+ <cell>The maximum number of simultaneously open files and
+ sockets depends on
+ <seealso marker="#ports">the maximum number of Erlang ports</seealso>
+ available, as well as on operating system-specific settings
+ and limits.</cell>
+ </row>
+ <row>
+ <cell>Number of arguments to a function or fun</cell>
+ <cell>255</cell>
+ </row>
+ <row>
+ <cell><marker id="unique_references"/>Unique References on a Runtime System Instance</cell>
+ <cell>Each scheduler thread has its own set of references, and all
+ other threads have a shared set of references. Each set of references
+ consist of <c>2⁶⁴ - 1</c> unique references. That is the total
+ amount of unique references that can be produced on a runtime
+ system instance is <c>(NoSchedulers + 1) * (2⁶⁴ - 1)</c>. If a
+ scheduler thread create a new reference each nano second,
+ references will at earliest be reused after more than 584 years.
+ That is, for the foreseeable future they are unique enough.</cell>
+ </row>
+ <row>
+ <cell><marker id="unique_integers"/>Unique Integers on a Runtime System Instance</cell>
+ <cell>There are two types of unique integers both created using the
+ <seealso marker="erts:erlang#unique_integer/1">erlang:unique_integer()</seealso>
+ BIF. Unique integers created:
+ <taglist>
+ <tag>with the <c>monotonic</c> modifier</tag>
+ <item>consist of a set of <c>2⁶⁴ - 1</c> unique integers.</item>
+ <tag>without the <c>monotonic</c> modifier</tag>
+ <item>consist of a set of <c>2⁶⁴ - 1</c> unique integers per scheduler
+ thread and a set of <c>2⁶⁴ - 1</c> unique integers shared by
+ other threads. That is the total amount of unique integers without
+ the <c>monotonic</c> modifier is <c>(NoSchedulers + 1) * (2⁶⁴ - 1)</c></item>
+ </taglist>
+ If a unique integer is created each nano second, unique integers
+ will at earliest be reused after more than 584 years. That is, for
+ the foreseeable future they are unique enough.</cell>
+ </row>
+ <tcaption>System Limits</tcaption>
+ </table>
</section>
</chapter>
diff --git a/system/doc/efficiency_guide/all.erl b/system/doc/efficiency_guide/all.erl
index a0f7809422..de0563a043 100644
--- a/system/doc/efficiency_guide/all.erl
+++ b/system/doc/efficiency_guide/all.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/system/doc/efficiency_guide/appendix.xml b/system/doc/efficiency_guide/appendix.xml
index 48d40d2493..1e2e906515 100644
--- a/system/doc/efficiency_guide/appendix.xml
+++ b/system/doc/efficiency_guide/appendix.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/system/doc/efficiency_guide/bench.erl b/system/doc/efficiency_guide/bench.erl
index 8f26b8d0af..1f60e858f6 100644
--- a/system/doc/efficiency_guide/bench.erl
+++ b/system/doc/efficiency_guide/bench.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/system/doc/efficiency_guide/bench.hrl b/system/doc/efficiency_guide/bench.hrl
index a98ca1c89e..7ad3257705 100644
--- a/system/doc/efficiency_guide/bench.hrl
+++ b/system/doc/efficiency_guide/bench.hrl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/system/doc/efficiency_guide/binaryhandling.xml b/system/doc/efficiency_guide/binaryhandling.xml
index 4ba1378059..0964b759d8 100644
--- a/system/doc/efficiency_guide/binaryhandling.xml
+++ b/system/doc/efficiency_guide/binaryhandling.xml
@@ -9,21 +9,22 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>Constructing and matching binaries</title>
+ <title>Constructing and Matching Binaries</title>
<prepared>Bjorn Gustavsson</prepared>
<docno></docno>
<date>2007-10-12</date>
@@ -31,10 +32,10 @@
<file>binaryhandling.xml</file>
</header>
- <p>In R12B, the most natural way to write binary construction and matching is now
+ <p>In R12B, the most natural way to construct and match binaries is
significantly faster than in earlier releases.</p>
- <p>To construct at binary, you can simply write</p>
+ <p>To construct a binary, you can simply write as follows:</p>
<p><em>DO</em> (in R12B) / <em>REALLY DO NOT</em> (in earlier releases)</p>
<code type="erl"><![CDATA[
@@ -46,13 +47,12 @@ my_list_to_binary([H|T], Acc) ->
my_list_to_binary([], Acc) ->
Acc.]]></code>
- <p>In releases before R12B, <c>Acc</c> would be copied in every iteration.
- In R12B, <c>Acc</c> will be copied only in the first iteration and extra
- space will be allocated at the end of the copied binary. In the next iteration,
- <c>H</c> will be written in to the extra space. When the extra space runs out,
- the binary will be reallocated with more extra space.</p>
-
- <p>The extra space allocated (or reallocated) will be twice the size of the
+ <p>In releases before R12B, <c>Acc</c> is copied in every iteration.
+ In R12B, <c>Acc</c> is copied only in the first iteration and extra
+ space is allocated at the end of the copied binary. In the next iteration,
+ <c>H</c> is written into the extra space. When the extra space runs out,
+ the binary is reallocated with more extra space. The extra space allocated
+ (or reallocated) is twice the size of the
existing binary data, or 256, whichever is larger.</p>
<p>The most natural way to match binaries is now the fastest:</p>
@@ -64,55 +64,79 @@ my_binary_to_list(<<H,T/binary>>) ->
my_binary_to_list(<<>>) -> [].]]></code>
<section>
- <title>How binaries are implemented</title>
+ <title>How Binaries are Implemented</title>
<p>Internally, binaries and bitstrings are implemented in the same way.
- In this section, we will call them <em>binaries</em> since that is what
+ In this section, they are called <em>binaries</em> because that is what
they are called in the emulator source code.</p>
- <p>There are four types of binary objects internally. Two of them are
- containers for binary data and two of them are merely references to
- a part of a binary.</p>
-
- <p>The binary containers are called <em>refc binaries</em>
- (short for <em>reference-counted binaries</em>) and <em>heap binaries</em>.</p>
+ <p>Four types of binary objects are available internally:</p>
+ <list type="bulleted">
+ <item><p>Two are containers for binary data and are called:</p>
+ <list type="bulleted">
+ <item><em>Refc binaries</em> (short for
+ <em>reference-counted binaries</em>)</item>
+ <item><em>Heap binaries</em></item>
+ </list></item>
+ <item><p>Two are merely references to a part of a binary and
+ are called:</p>
+ <list type="bulleted">
+ <item><em>sub binaries</em></item>
+ <item><em>match contexts</em></item>
+ </list></item>
+ </list>
- <p><marker id="refc_binary"></marker><em>Refc binaries</em>
- consist of two parts: an object stored on
- the process heap, called a <em>ProcBin</em>, and the binary object itself
- stored outside all process heaps.</p>
+ <section>
+ <marker id="refc_binary"></marker>
+ <title>Refc Binaries</title>
+ <p>Refc binaries consist of two parts:</p>
+ <list type="bulleted">
+ <item>An object stored on the process heap, called a
+ <em>ProcBin</em></item>
+ <item>The binary object itself, stored outside all process
+ heaps</item>
+ </list>
<p>The binary object can be referenced by any number of ProcBins from any
- number of processes; the object contains a reference counter to keep track
+ number of processes. The object contains a reference counter to keep track
of the number of references, so that it can be removed when the last
reference disappears.</p>
<p>All ProcBin objects in a process are part of a linked list, so that
the garbage collector can keep track of them and decrement the reference
counters in the binary when a ProcBin disappears.</p>
+ </section>
- <p><marker id="heap_binary"></marker><em>Heap binaries</em> are small binaries,
- up to 64 bytes, that are stored directly on the process heap.
- They will be copied when the process
- is garbage collected and when they are sent as a message. They don't
+ <section>
+ <marker id="heap_binary"></marker>
+ <title>Heap Binaries</title>
+ <p>Heap binaries are small binaries, up to 64 bytes, and are stored
+ directly on the process heap. They are copied when the process is
+ garbage-collected and when they are sent as a message. They do not
require any special handling by the garbage collector.</p>
+ </section>
- <p>There are two types of reference objects that can reference part of
- a refc binary or heap binary. They are called <em>sub binaries</em> and
- <em>match contexts</em>.</p>
+ <section>
+ <title>Sub Binaries</title>
+ <p>The reference objects <em>sub binaries</em> and
+ <em>match contexts</em> can reference part of
+ a refc binary or heap binary.</p>
<p><marker id="sub_binary"></marker>A <em>sub binary</em>
is created by <c>split_binary/2</c> and when
a binary is matched out in a binary pattern. A sub binary is a reference
- into a part of another binary (refc or heap binary, never into a another
+ into a part of another binary (refc or heap binary, but never into another
sub binary). Therefore, matching out a binary is relatively cheap because
the actual binary data is never copied.</p>
+ </section>
- <p><marker id="match_context"></marker>A <em>match context</em> is
- similar to a sub binary, but is optimized
- for binary matching; for instance, it contains a direct pointer to the binary
- data. For each field that is matched out of a binary, the position in the
- match context will be incremented.</p>
+ <section>
+ <title>Match Context</title>
+ <marker id="match_context"></marker>
+ <p>A <em>match context</em> is similar to a sub binary, but is
+ optimized for binary matching. For example, it contains a direct
+ pointer to the binary data. For each field that is matched out of
+ a binary, the position in the match context is incremented.</p>
<p>In R11B, a match context was only used during a binary matching
operation.</p>
@@ -122,27 +146,28 @@ my_binary_to_list(<<>>) -> [].]]></code>
context and discard the sub binary. Instead of creating a sub binary,
the match context is kept.</p>
- <p>The compiler can only do this optimization if it can know for sure
+ <p>The compiler can only do this optimization if it knows
that the match context will not be shared. If it would be shared, the
functional properties (also called referential transparency) of Erlang
would break.</p>
+ </section>
</section>
<section>
- <title>Constructing binaries</title>
-
- <p>In R12B, appending to a binary or bitstring</p>
+ <title>Constructing Binaries</title>
+ <p>In R12B, appending to a binary or bitstring
+ is specially optimized by the <em>runtime system</em>:</p>
<code type="erl"><![CDATA[
<<Binary/binary, ...>>
<<Binary/bitstring, ...>>]]></code>
- <p>is specially optimized by the <em>run-time system</em>.
- Because the run-time system handles the optimization (instead of
+ <p>As the runtime system handles the optimization (instead of
the compiler), there are very few circumstances in which the optimization
- will not work.</p>
+ does not work.</p>
- <p>To explain how it works, we will go through this code</p>
+ <p>To explain how it works, let us examine the following code line
+ by line:</p>
<code type="erl"><![CDATA[
Bin0 = <<0>>, %% 1
@@ -152,81 +177,81 @@ Bin3 = <<Bin2/binary,7,8,9>>, %% 4
Bin4 = <<Bin1/binary,17>>, %% 5 !!!
{Bin4,Bin3} %% 6]]></code>
- <p>line by line.</p>
-
- <p>The first line (marked with the <c>%% 1</c> comment), assigns
+ <list type="bulleted">
+ <item>Line 1 (marked with the <c>%% 1</c> comment), assigns
a <seealso marker="#heap_binary">heap binary</seealso> to
- the variable <c>Bin0</c>.</p>
+ the <c>Bin0</c> variable.</item>
- <p>The second line is an append operation. Since <c>Bin0</c>
+ <item>Line 2 is an append operation. As <c>Bin0</c>
has not been involved in an append operation,
a new <seealso marker="#refc_binary">refc binary</seealso>
- will be created and the contents of <c>Bin0</c> will be copied
- into it. The <em>ProcBin</em> part of the refc binary will have
+ is created and the contents of <c>Bin0</c> is copied
+ into it. The <em>ProcBin</em> part of the refc binary has
its size set to the size of the data stored in the binary, while
- the binary object will have extra space allocated.
- The size of the binary object will be either twice the
- size of <c>Bin0</c> or 256, whichever is larger. In this case
- it will be 256.</p>
+ the binary object has extra space allocated.
+ The size of the binary object is either twice the
+ size of <c>Bin1</c> or 256, whichever is larger. In this case
+ it is 256.</item>
- <p>It gets more interesting in the third line.
+ <item>Line 3 is more interesting.
<c>Bin1</c> <em>has</em> been used in an append operation,
- and it has 255 bytes of unused storage at the end, so the three new bytes
- will be stored there.</p>
+ and it has 252 bytes of unused storage at the end, so the 3 new
+ bytes are stored there.</item>
- <p>Same thing in the fourth line. There are 252 bytes left,
- so there is no problem storing another three bytes.</p>
+ <item>Line 4. The same applies here. There are 249 bytes left,
+ so there is no problem storing another 3 bytes.</item>
- <p>But in the fifth line something <em>interesting</em> happens.
- Note that we don't append to the previous result in <c>Bin3</c>,
- but to <c>Bin1</c>. We expect that <c>Bin4</c> will be assigned
- the value <c>&lt;&lt;0,1,2,3,17&gt;&gt;</c>. We also expect that
+ <item>Line 5. Here, something <em>interesting</em> happens. Notice
+ that the result is not appended to the previous result in <c>Bin3</c>,
+ but to <c>Bin1</c>. It is expected that <c>Bin4</c> will be assigned
+ the value <c>&lt;&lt;0,1,2,3,17&gt;&gt;</c>. It is also expected that
<c>Bin3</c> will retain its value
(<c>&lt;&lt;0,1,2,3,4,5,6,7,8,9&gt;&gt;</c>).
- Clearly, the run-time system cannot write the byte <c>17</c> into the binary,
+ Clearly, the runtime system cannot write byte <c>17</c> into the binary,
because that would change the value of <c>Bin3</c> to
- <c>&lt;&lt;0,1,2,3,4,17,6,7,8,9&gt;&gt;</c>.</p>
-
- <p>What will happen?</p>
+ <c>&lt;&lt;0,1,2,3,4,17,6,7,8,9&gt;&gt;</c>.</item>
+ </list>
- <p>The run-time system will see that <c>Bin1</c> is the result
+ <p>The runtime system sees that <c>Bin1</c> is the result
from a previous append operation (not from the latest append operation),
- so it will <em>copy</em> the contents of <c>Bin1</c> to a new binary
- and reserve extra storage and so on. (We will not explain here how the
- run-time system can know that it is not allowed to write into <c>Bin1</c>;
+ so it <em>copies</em> the contents of <c>Bin1</c> to a new binary,
+ reserve extra storage, and so on. (Here is not explained how the
+ runtime system can know that it is not allowed to write into <c>Bin1</c>;
it is left as an exercise to the curious reader to figure out how it is
done by reading the emulator sources, primarily <c>erl_bits.c</c>.)</p>
<section>
- <title>Circumstances that force copying</title>
+ <title>Circumstances That Force Copying</title>
<p>The optimization of the binary append operation requires that
there is a <em>single</em> ProcBin and a <em>single reference</em> to the
ProcBin for the binary. The reason is that the binary object can be
- moved (reallocated) during an append operation, and when that happens
+ moved (reallocated) during an append operation, and when that happens,
the pointer in the ProcBin must be updated. If there would be more than
one ProcBin pointing to the binary object, it would not be possible to
find and update all of them.</p>
- <p>Therefore, certain operations on a binary will mark it so that
+ <p>Therefore, certain operations on a binary mark it so that
any future append operation will be forced to copy the binary.
In most cases, the binary object will be shrunk at the same time
to reclaim the extra space allocated for growing.</p>
- <p>When appending to a binary</p>
+ <p>When appending to a binary as follows, only the binary returned
+ from the latest append operation will support further cheap append
+ operations:</p>
<code type="erl"><![CDATA[
Bin = <<Bin0,...>>]]></code>
- <p>only the binary returned from the latest append operation will
- support further cheap append operations. In the code fragment above,
+ <p>In the code fragment in the beginning of this section,
appending to <c>Bin</c> will be cheap, while appending to <c>Bin0</c>
will force the creation of a new binary and copying of the contents
of <c>Bin0</c>.</p>
<p>If a binary is sent as a message to a process or port, the binary
will be shrunk and any further append operation will copy the binary
- data into a new binary. For instance, in the following code fragment</p>
+ data into a new binary. For example, in the following code fragment
+ <c>Bin1</c> will be copied in the third line:</p>
<code type="erl"><![CDATA[
Bin1 = <<Bin0,...>>,
@@ -234,12 +259,12 @@ PortOrPid ! Bin1,
Bin = <<Bin1,...>> %% Bin1 will be COPIED
]]></code>
- <p><c>Bin1</c> will be copied in the third line.</p>
-
- <p>The same thing happens if you insert a binary into an <em>ets</em>
- table or send it to a port using <c>erlang:port_command/2</c> or pass it to
+ <p>The same happens if you insert a binary into an Ets
+ table, send it to a port using <c>erlang:port_command/2</c>, or
+ pass it to
<seealso marker="erts:erl_nif#enif_inspect_binary">enif_inspect_binary</seealso>
in a NIF.</p>
+
<p>Matching a binary will also cause it to shrink and the next append
operation will copy the binary data:</p>
@@ -249,22 +274,23 @@ Bin1 = <<Bin0,...>>,
Bin = <<Bin1,...>> %% Bin1 will be COPIED
]]></code>
- <p>The reason is that a <seealso marker="#match_context">match context</seealso>
+ <p>The reason is that a
+ <seealso marker="#match_context">match context</seealso>
contains a direct pointer to the binary data.</p>
- <p>If a process simply keeps binaries (either in "loop data" or in the process
- dictionary), the garbage collector may eventually shrink the binaries.
- If only one such binary is kept, it will not be shrunk. If the process later
- appends to a binary that has been shrunk, the binary object will be reallocated
- to make place for the data to be appended.</p>
+ <p>If a process simply keeps binaries (either in "loop data" or in the
+ process
+ dictionary), the garbage collector can eventually shrink the binaries.
+ If only one such binary is kept, it will not be shrunk. If the process
+ later appends to a binary that has been shrunk, the binary object will
+ be reallocated to make place for the data to be appended.</p>
</section>
-
</section>
<section>
- <title>Matching binaries</title>
+ <title>Matching Binaries</title>
- <p>We will revisit the example shown earlier</p>
+ <p>Let us revisit the example in the beginning of the previous section:</p>
<p><em>DO</em> (in R12B)</p>
<code type="erl"><![CDATA[
@@ -272,36 +298,35 @@ my_binary_to_list(<<H,T/binary>>) ->
[H|my_binary_to_list(T)];
my_binary_to_list(<<>>) -> [].]]></code>
- <p>too see what is happening under the hood.</p>
-
- <p>The very first time <c>my_binary_to_list/1</c> is called,
+ <p>The first time <c>my_binary_to_list/1</c> is called,
a <seealso marker="#match_context">match context</seealso>
- will be created. The match context will point to the first
- byte of the binary. One byte will be matched out and the match context
- will be updated to point to the second byte in the binary.</p>
+ is created. The match context points to the first
+ byte of the binary. 1 byte is matched out and the match context
+ is updated to point to the second byte in the binary.</p>
- <p>In R11B, at this point a <seealso marker="#sub_binary">sub binary</seealso>
+ <p>In R11B, at this point a
+ <seealso marker="#sub_binary">sub binary</seealso>
would be created. In R12B,
the compiler sees that there is no point in creating a sub binary,
because there will soon be a call to a function (in this case,
- to <c>my_binary_to_list/1</c> itself) that will immediately
+ to <c>my_binary_to_list/1</c> itself) that immediately will
create a new match context and discard the sub binary.</p>
- <p>Therefore, in R12B, <c>my_binary_to_list/1</c> will call itself
+ <p>Therefore, in R12B, <c>my_binary_to_list/1</c> calls itself
with the match context instead of with a sub binary. The instruction
- that initializes the matching operation will basically do nothing
+ that initializes the matching operation basically does nothing
when it sees that it was passed a match context instead of a binary.</p>
<p>When the end of the binary is reached and the second clause matches,
the match context will simply be discarded (removed in the next
- garbage collection, since there is no longer any reference to it).</p>
+ garbage collection, as there is no longer any reference to it).</p>
<p>To summarize, <c>my_binary_to_list/1</c> in R12B only needs to create
<em>one</em> match context and no sub binaries. In R11B, if the binary
contains <em>N</em> bytes, <em>N+1</em> match contexts and <em>N</em>
- sub binaries will be created.</p>
+ sub binaries are created.</p>
- <p>In R11B, the fastest way to match binaries is:</p>
+ <p>In R11B, the fastest way to match binaries is as follows:</p>
<p><em>DO NOT</em> (in R12B)</p>
<code type="erl"><![CDATA[
@@ -317,13 +342,14 @@ my_complicated_binary_to_list(Bin, Skip) ->
end.]]></code>
<p>This function cleverly avoids building sub binaries, but it cannot
- avoid building a match context in each recursion step. Therefore, in both R11B and R12B,
+ avoid building a match context in each recursion step.
+ Therefore, in both R11B and R12B,
<c>my_complicated_binary_to_list/1</c> builds <em>N+1</em> match
- contexts. (In a future release, the compiler might be able to generate code
- that reuses the match context, but don't hold your breath.)</p>
+ contexts. (In a future Erlang/OTP release, the compiler might be able
+ to generate code that reuses the match context.)</p>
- <p>Returning to <c>my_binary_to_list/1</c>, note that the match context was
- discarded when the entire binary had been traversed. What happens if
+ <p>Returning to <c>my_binary_to_list/1</c>, notice that the match context
+ was discarded when the entire binary had been traversed. What happens if
the iteration stops before it has reached the end of the binary? Will
the optimization still work?</p>
@@ -336,29 +362,23 @@ after_zero(<<>>) ->
<<>>.
]]></code>
- <p>Yes, it will. The compiler will remove the building of the sub binary in the
- second clause</p>
+ <p>Yes, it will. The compiler will remove the building of the sub binary in
+ the second clause:</p>
<code type="erl"><![CDATA[
-.
-.
-.
+...
after_zero(<<_,T/binary>>) ->
after_zero(T);
-.
-.
-.]]></code>
+...]]></code>
- <p>but will generate code that builds a sub binary in the first clause</p>
+ <p>But it will generate code that builds a sub binary in the first clause:</p>
<code type="erl"><![CDATA[
after_zero(<<0,T/binary>>) ->
T;
-.
-.
-.]]></code>
+...]]></code>
- <p>Therefore, <c>after_zero/1</c> will build one match context and one sub binary
+ <p>Therefore, <c>after_zero/1</c> builds one match context and one sub binary
(assuming it is passed a binary that contains a zero byte).</p>
<p>Code like the following will also be optimized:</p>
@@ -371,12 +391,14 @@ all_but_zeroes_to_list(<<0,T/binary>>, Acc, Remaining) ->
all_but_zeroes_to_list(<<Byte,T/binary>>, Acc, Remaining) ->
all_but_zeroes_to_list(T, [Byte|Acc], Remaining-1).]]></code>
- <p>The compiler will remove building of sub binaries in the second and third clauses,
- and it will add an instruction to the first clause that will convert <c>Buffer</c>
- from a match context to a sub binary (or do nothing if <c>Buffer</c> already is a binary).</p>
+ <p>The compiler removes building of sub binaries in the second and third
+ clauses, and it adds an instruction to the first clause that converts
+ <c>Buffer</c> from a match context to a sub binary (or do nothing if
+ <c>Buffer</c> is a binary already).</p>
- <p>Before you begin to think that the compiler can optimize any binary patterns,
- here is a function that the compiler (currently, at least) is not able to optimize:</p>
+ <p>Before you begin to think that the compiler can optimize any binary
+ patterns, the following function cannot be optimized by the compiler
+ (currently, at least):</p>
<code type="erl"><![CDATA[
non_opt_eq([H|T1], <<H,T2/binary>>) ->
@@ -386,43 +408,44 @@ non_opt_eq([_|_], <<_,_/binary>>) ->
non_opt_eq([], <<>>) ->
true.]]></code>
- <p>It was briefly mentioned earlier that the compiler can only delay creation of
- sub binaries if it can be sure that the binary will not be shared. In this case,
- the compiler cannot be sure.</p>
+ <p>It was mentioned earlier that the compiler can only delay creation of
+ sub binaries if it knows that the binary will not be shared. In this case,
+ the compiler cannot know.</p>
- <p>We will soon show how to rewrite <c>non_opt_eq/2</c> so that the delayed sub binary
- optimization can be applied, and more importantly, we will show how you can find out
- whether your code can be optimized.</p>
+ <p>Soon it is shown how to rewrite <c>non_opt_eq/2</c> so that the delayed
+ sub binary optimization can be applied, and more importantly, it is shown
+ how you can find out whether your code can be optimized.</p>
<section>
- <title>The bin_opt_info option</title>
+ <marker id="bin_opt_info"></marker>
+ <title>Option bin_opt_info</title>
<p>Use the <c>bin_opt_info</c> option to have the compiler print a lot of
- information about binary optimizations. It can be given either to the compiler or
- <c>erlc</c></p>
+ information about binary optimizations. It can be given either to the
+ compiler or <c>erlc</c>:</p>
<code type="erl"><![CDATA[
erlc +bin_opt_info Mod.erl]]></code>
- <p>or passed via an environment variable</p>
+ <p>or passed through an environment variable:</p>
<code type="erl"><![CDATA[
export ERL_COMPILER_OPTIONS=bin_opt_info]]></code>
- <p>Note that the <c>bin_opt_info</c> is not meant to be a permanent option added
- to your <c>Makefile</c>s, because it is not possible to eliminate all messages that
- it generates. Therefore, passing the option through the environment is in most cases
- the most practical approach.</p>
+ <p>Notice that the <c>bin_opt_info</c> is not meant to be a permanent
+ option added to your <c>Makefile</c>s, because all messages that it
+ generates cannot be eliminated. Therefore, passing the option through
+ the environment is in most cases the most practical approach.</p>
- <p>The warnings will look like this:</p>
+ <p>The warnings look as follows:</p>
<code type="erl"><![CDATA[
./efficiency_guide.erl:60: Warning: NOT OPTIMIZED: sub binary is used or returned
./efficiency_guide.erl:62: Warning: OPTIMIZED: creation of sub binary delayed]]></code>
- <p>To make it clearer exactly what code the warnings refer to,
- in the examples that follow, the warnings are inserted as comments
- after the clause they refer to:</p>
+ <p>To make it clearer exactly what code the warnings refer to, the
+ warnings in the following examples are inserted as comments
+ after the clause they refer to, for example:</p>
<code type="erl"><![CDATA[
after_zero(<<0,T/binary>>) ->
@@ -434,12 +457,12 @@ after_zero(<<_,T/binary>>) ->
after_zero(<<>>) ->
<<>>.]]></code>
- <p>The warning for the first clause tells us that it is not possible to
- delay the creation of a sub binary, because it will be returned.
- The warning for the second clause tells us that a sub binary will not be
+ <p>The warning for the first clause says that the creation of a sub
+ binary cannot be delayed, because it will be returned.
+ The warning for the second clause says that a sub binary will not be
created (yet).</p>
- <p>It is time to revisit the earlier example of the code that could not
+ <p>Let us revisit the earlier example of the code that could not
be optimized and find out why:</p>
<code type="erl"><![CDATA[
@@ -456,16 +479,16 @@ non_opt_eq([_|_], <<_,_/binary>>) ->
non_opt_eq([], <<>>) ->
true.]]></code>
- <p>The compiler emitted two warnings. The <c>INFO</c> warning refers to the function
- <c>non_opt_eq/2</c> as a callee, indicating that any functions that call <c>non_opt_eq/2</c>
- will not be able to make delayed sub binary optimization.
- There is also a suggestion to change argument order.
- The second warning (that happens to refer to the same line) refers to the construction of
- the sub binary itself.</p>
+ <p>The compiler emitted two warnings. The <c>INFO</c> warning refers
+ to the function <c>non_opt_eq/2</c> as a callee, indicating that any
+ function that call <c>non_opt_eq/2</c> cannot make delayed sub binary
+ optimization. There is also a suggestion to change argument order.
+ The second warning (that happens to refer to the same line) refers to
+ the construction of the sub binary itself.</p>
- <p>We will soon show another example that should make the distinction between <c>INFO</c>
- and <c>NOT OPTIMIZED</c> warnings somewhat clearer, but first we will heed the suggestion
- to change argument order:</p>
+ <p>Soon another example will show the difference between the
+ <c>INFO</c> and <c>NOT OPTIMIZED</c> warnings somewhat clearer, but
+ let us first follow the suggestion to change argument order:</p>
<code type="erl"><![CDATA[
opt_eq(<<H,T1/binary>>, [H|T2]) ->
@@ -485,15 +508,13 @@ match_body([0|_], <<H,_/binary>>) ->
%% sub binary optimization;
%% SUGGEST changing argument order
done;
-.
-.
-.]]></code>
+...]]></code>
<p>The warning means that <em>if</em> there is a call to <c>match_body/2</c>
(from another clause in <c>match_body/2</c> or another function), the
- delayed sub binary optimization will not be possible. There will be additional
- warnings for any place where a sub binary is matched out at the end of and
- passed as the second argument to <c>match_body/2</c>. For instance:</p>
+ delayed sub binary optimization will not be possible. More warnings will
+ occur for any place where a sub binary is matched out at the end of and
+ passed as the second argument to <c>match_body/2</c>, for example:</p>
<code type="erl"><![CDATA[
match_head(List, <<_:10,Data/binary>>) ->
@@ -504,10 +525,10 @@ match_head(List, <<_:10,Data/binary>>) ->
</section>
<section>
- <title>Unused variables</title>
+ <title>Unused Variables</title>
- <p>The compiler itself figures out if a variable is unused. The same
- code is generated for each of the following functions</p>
+ <p>The compiler figures out if a variable is unused. The same
+ code is generated for each of the following functions:</p>
<code type="erl"><![CDATA[
count1(<<_,T/binary>>, Count) -> count1(T, Count+1);
@@ -519,11 +540,9 @@ count2(<<>>, Count) -> Count.
count3(<<_H,T/binary>>, Count) -> count3(T, Count+1);
count3(<<>>, Count) -> Count.]]></code>
- <p>In each iteration, the first 8 bits in the binary will be skipped, not matched out.</p>
-
+ <p>In each iteration, the first 8 bits in the binary will be skipped,
+ not matched out.</p>
</section>
-
</section>
-
</chapter>
diff --git a/system/doc/efficiency_guide/book.xml b/system/doc/efficiency_guide/book.xml
index f8b4c59e3f..76f0ad24d3 100644
--- a/system/doc/efficiency_guide/book.xml
+++ b/system/doc/efficiency_guide/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/efficiency_guide/call_bm.erl b/system/doc/efficiency_guide/call_bm.erl
index 389814f11f..c5a072c2f4 100644
--- a/system/doc/efficiency_guide/call_bm.erl
+++ b/system/doc/efficiency_guide/call_bm.erl
@@ -1,13 +1,14 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% ``Licensed under the Apache License, Version 2.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.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/system/doc/efficiency_guide/commoncaveats.xml b/system/doc/efficiency_guide/commoncaveats.xml
index 551b0a03e6..c1d71e745a 100644
--- a/system/doc/efficiency_guide/commoncaveats.xml
+++ b/system/doc/efficiency_guide/commoncaveats.xml
@@ -8,17 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Common Caveats</title>
@@ -29,49 +29,50 @@
<file>commoncaveats.xml</file>
</header>
- <p>Here we list a few modules and BIFs to watch out for, and not only
+ <p>This section lists a few modules and BIFs to watch out for, not only
from a performance point of view.</p>
<section>
- <title>The timer module</title>
+ <title>Timer Module</title>
<p>Creating timers using <seealso
marker="erts:erlang#erlang:send_after/3">erlang:send_after/3</seealso>
- and <seealso marker="erts:erlang#erlang:start_timer/3">erlang:start_timer/3</seealso>
+ and
+ <seealso marker="erts:erlang#erlang:start_timer/3">erlang:start_timer/3</seealso>
+,
is much more efficient than using the timers provided by the
- <seealso marker="stdlib:timer">timer</seealso> module. The
- <c>timer</c> module uses a separate process to manage the timers,
- and that process can easily become overloaded if many processes
+ <seealso marker="stdlib:timer">timer</seealso> module in STDLIB.
+ The <c>timer</c> module uses a separate process to manage the timers.
+ That process can easily become overloaded if many processes
create and cancel timers frequently (especially when using the
SMP emulator).</p>
- <p>The functions in the <c>timer</c> module that do not manage timers (such as
- <c>timer:tc/3</c> or <c>timer:sleep/1</c>), do not call the timer-server process
- and are therefore harmless.</p>
+ <p>The functions in the <c>timer</c> module that do not manage timers
+ (such as <c>timer:tc/3</c> or <c>timer:sleep/1</c>), do not call the
+ timer-server process and are therefore harmless.</p>
</section>
<section>
<title>list_to_atom/1</title>
- <p>Atoms are not garbage-collected. Once an atom is created, it will never
- be removed. The emulator will terminate if the limit for the number
- of atoms (1048576 by default) is reached.</p>
+ <p>Atoms are not garbage-collected. Once an atom is created, it is never
+ removed. The emulator terminates if the limit for the number
+ of atoms (1,048,576 by default) is reached.</p>
- <p>Therefore, converting arbitrary input strings to atoms could be
- dangerous in a system that will run continuously.
- If only certain well-defined atoms are allowed as input, you can use
+ <p>Therefore, converting arbitrary input strings to atoms can be
+ dangerous in a system that runs continuously.
+ If only certain well-defined atoms are allowed as input,
<seealso marker="erts:erlang#list_to_existing_atom/1">list_to_existing_atom/1</seealso>
+ can be used to
to guard against a denial-of-service attack. (All atoms that are allowed
- must have been created earlier, for instance by simply using all of them
+ must have been created earlier, for example, by simply using all of them
in a module and loading that module.)</p>
<p>Using <c>list_to_atom/1</c> to construct an atom that is passed to
- <c>apply/3</c> like this</p>
-
+ <c>apply/3</c> as follows, is quite expensive and not recommended
+ in time-critical code:</p>
<code type="erl">
-apply(list_to_atom("some_prefix"++Var), foo, Args)</code>
-
- <p>is quite expensive and is not recommended in time-critical code.</p>
+apply(list_to_atom("some_prefix"++Var), foo, Args)</code>
</section>
<section>
@@ -81,25 +82,25 @@ apply(list_to_atom("some_prefix"++Var), foo, Args)</code>
length of the list, as opposed to <c>tuple_size/1</c>, <c>byte_size/1</c>,
and <c>bit_size/1</c>, which all execute in constant time.</p>
- <p>Normally you don't have to worry about the speed of <c>length/1</c>,
- because it is efficiently implemented in C. In time critical-code, though,
- you might want to avoid it if the input list could potentially be very long.</p>
+ <p>Normally, there is no need to worry about the speed of <c>length/1</c>,
+ because it is efficiently implemented in C. In time-critical code,
+ you might want to avoid it if the input list could potentially be very
+ long.</p>
<p>Some uses of <c>length/1</c> can be replaced by matching.
- For instance, this code</p>
-
+ For example, the following code:</p>
<code type="erl">
foo(L) when length(L) >= 3 ->
...</code>
- <p>can be rewritten to</p>
+ <p>can be rewritten to:</p>
<code type="erl">
foo([_,_,_|_]=L) ->
...</code>
- <p>(One slight difference is that <c>length(L)</c> will fail if the <c>L</c>
- is an improper list, while the pattern in the second code fragment will
- accept an improper list.)</p>
+ <p>One slight difference is that <c>length(L)</c> fails if <c>L</c>
+ is an improper list, while the pattern in the second code fragment
+ accepts an improper list.</p>
</section>
<section>
@@ -107,50 +108,49 @@ foo([_,_,_|_]=L) ->
<p><seealso marker="erts:erlang#setelement/3">setelement/3</seealso>
copies the tuple it modifies. Therefore, updating a tuple in a loop
- using <c>setelement/3</c> will create a new copy of the tuple every time.</p>
+ using <c>setelement/3</c> creates a new copy of the tuple every time.</p>
<p>There is one exception to the rule that the tuple is copied.
If the compiler clearly can see that destructively updating the tuple would
- give exactly the same result as if the tuple was copied, the call to
- <c>setelement/3</c> will be replaced with a special destructive setelement
- instruction. In the following code sequence</p>
-
+ give the same result as if the tuple was copied, the call to
+ <c>setelement/3</c> is replaced with a special destructive <c>setelement</c>
+ instruction. In the following code sequence, the first <c>setelement/3</c>
+ call copies the tuple and modifies the ninth element:</p>
<code type="erl">
multiple_setelement(T0) ->
T1 = setelement(9, T0, bar),
T2 = setelement(7, T1, foobar),
setelement(5, T2, new_value).</code>
- <p>the first <c>setelement/3</c> call will copy the tuple and modify the
- ninth element. The two following <c>setelement/3</c> calls will modify
+ <p>The two following <c>setelement/3</c> calls modify
the tuple in place.</p>
- <p>For the optimization to be applied, <em>all</em> of the followings conditions
+ <p>For the optimization to be applied, <em>all</em> the followings conditions
must be true:</p>
<list type="bulleted">
<item>The indices must be integer literals, not variables or expressions.</item>
<item>The indices must be given in descending order.</item>
- <item>There must be no calls to other function in between the calls to
+ <item>There must be no calls to another function in between the calls to
<c>setelement/3</c>.</item>
<item>The tuple returned from one <c>setelement/3</c> call must only be used
in the subsequent call to <c>setelement/3</c>.</item>
</list>
- <p>If it is not possible to structure the code as in the <c>multiple_setelement/1</c>
+ <p>If the code cannot be structured as in the <c>multiple_setelement/1</c>
example, the best way to modify multiple elements in a large tuple is to
- convert the tuple to a list, modify the list, and convert the list back to
+ convert the tuple to a list, modify the list, and convert it back to
a tuple.</p>
</section>
<section>
<title>size/1</title>
- <p><c>size/1</c> returns the size for both tuples and binary.</p>
+ <p><c>size/1</c> returns the size for both tuples and binaries.</p>
- <p>Using the new BIFs <c>tuple_size/1</c> and <c>byte_size/1</c> introduced
- in R12B gives the compiler and run-time system more opportunities for
- optimization. A further advantage is that the new BIFs could help Dialyzer
+ <p>Using the new BIFs <c>tuple_size/1</c> and <c>byte_size/1</c>, introduced
+ in R12B, gives the compiler and the runtime system more opportunities for
+ optimization. Another advantage is that the new BIFs can help Dialyzer to
find more bugs in your program.</p>
</section>
@@ -159,22 +159,21 @@ multiple_setelement(T0) ->
<p>It is usually more efficient to split a binary using matching
instead of calling the <c>split_binary/2</c> function.
Furthermore, mixing bit syntax matching and <c>split_binary/2</c>
- may prevent some optimizations of bit syntax matching.</p>
+ can prevent some optimizations of bit syntax matching.</p>
<p><em>DO</em></p>
<code type="none"><![CDATA[
<<Bin1:Num/binary,Bin2/binary>> = Bin,]]></code>
<p><em>DO NOT</em></p>
<code type="none">
- {Bin1,Bin2} = split_binary(Bin, Num)
- </code>
+ {Bin1,Bin2} = split_binary(Bin, Num)</code>
</section>
<section>
- <title>The '--' operator</title>
- <p>Note that the '<c>--</c>' operator has a complexity
- proportional to the product of the length of its operands,
- meaning that it will be very slow if both of its operands
+ <title>Operator "--"</title>
+ <p>The "<c>--</c>" operator has a complexity
+ proportional to the product of the length of its operands.
+ This means that the operator is very slow if both of its operands
are long lists:</p>
<p><em>DO NOT</em></p>
@@ -182,42 +181,39 @@ multiple_setelement(T0) ->
HugeList1 -- HugeList2]]></code>
<p>Instead use the <seealso marker="stdlib:ordsets">ordsets</seealso>
- module:</p>
+ module in STDLIB:</p>
<p><em>DO</em></p>
<code type="none">
HugeSet1 = ordsets:from_list(HugeList1),
HugeSet2 = ordsets:from_list(HugeList2),
- ordsets:subtract(HugeSet1, HugeSet2)
- </code>
+ ordsets:subtract(HugeSet1, HugeSet2)</code>
- <p>Obviously, that code will not work if the original order
+ <p>Obviously, that code does not work if the original order
of the list is important. If the order of the list must be
- preserved, do like this:</p>
+ preserved, do as follows:</p>
<p><em>DO</em></p>
<code type="none"><![CDATA[
Set = gb_sets:from_list(HugeList2),
[E || E <- HugeList1, not gb_sets:is_element(E, Set)]]]></code>
- <p>Subtle note 1: This code behaves differently from '<c>--</c>'
- if the lists contain duplicate elements. (One occurrence
- of an element in HugeList2 will remove <em>all</em>
+ <note><p>This code behaves differently from "<c>--</c>"
+ if the lists contain duplicate elements (one occurrence
+ of an element in HugeList2 removes <em>all</em>
occurrences in HugeList1.)</p>
+ <p>Also, this code compares lists elements using the
+ "<c>==</c>" operator, while "<c>--</c>" uses the "<c>=:=</c>" operator.
+ If that difference is important, <c>sets</c> can be used instead of
+ <c>gb_sets</c>, but <c>sets:from_list/1</c> is much
+ slower than <c>gb_sets:from_list/1</c> for long lists.</p></note>
- <p>Subtle note 2: This code compares lists elements using the
- '<c>==</c>' operator, while '<c>--</c>' uses the '<c>=:=</c>'. If
- that difference is important, <c>sets</c> can be used instead of
- <c>gb_sets</c>, but note that <c>sets:from_list/1</c> is much
- slower than <c>gb_sets:from_list/1</c> for long lists.</p>
-
- <p>Using the '<c>--</c>' operator to delete an element
+ <p>Using the "<c>--</c>" operator to delete an element
from a list is not a performance problem:</p>
<p><em>OK</em></p>
<code type="none">
- HugeList1 -- [Element]
- </code>
+ HugeList1 -- [Element]</code>
</section>
diff --git a/system/doc/efficiency_guide/drivers.xml b/system/doc/efficiency_guide/drivers.xml
index dfc49bdf21..202551ab8e 100644
--- a/system/doc/efficiency_guide/drivers.xml
+++ b/system/doc/efficiency_guide/drivers.xml
@@ -8,17 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Drivers</title>
@@ -29,26 +29,26 @@
<file>drivers.xml</file>
</header>
- <p>This chapter provides a (very) brief overview on how to write efficient
- drivers. It is assumed that you already have a good understanding of
+ <p>This section provides a brief overview on how to write efficient
drivers.</p>
+ <p>It is assumed that you have a good understanding of drivers.</p>
<section>
- <title>Drivers and concurrency</title>
+ <title>Drivers and Concurrency</title>
- <p>The run-time system will always take a lock before running
+ <p>The runtime system always takes a lock before running
any code in a driver.</p>
- <p>By default, that lock will be at the driver level, meaning that
+ <p>By default, that lock is at the driver level, that is,
if several ports have been opened to the same driver, only code for
one port at the same time can be running.</p>
- <p>A driver can be configured to instead have one lock for each port.</p>
+ <p>A driver can be configured to have one lock for each port instead.</p>
- <p>If a driver is used in a functional way (i.e. it holds no state,
+ <p>If a driver is used in a functional way (that is, holds no state,
but only does some heavy calculation and returns a result), several
- ports with registered names can be opened beforehand and the port to
- be used can be chosen based on the scheduler ID like this:</p>
+ ports with registered names can be opened beforehand, and the port to
+ be used can be chosen based on the scheduler ID as follows:</p>
<code type="none">
-define(PORT_NAMES(),
@@ -67,82 +67,82 @@ client_port() ->
</section>
<section>
- <title>Avoiding copying of binaries when calling a driver</title>
+ <title>Avoiding Copying Binaries When Calling a Driver</title>
<p>There are basically two ways to avoid copying a binary that is
- sent to a driver.</p>
-
- <p>If the <c>Data</c> argument for
- <seealso marker="erts:erlang#port_control/3">port_control/3</seealso>
- is a binary, the driver will be passed a pointer to the contents of
- the binary and the binary will not be copied.
- If the <c>Data</c> argument is an iolist (list of binaries and lists),
- all binaries in the iolist will be copied.</p>
-
- <p>Therefore, if you want to send both a pre-existing binary and some
- additional data to a driver without copying the binary, you must call
- <c>port_control/3</c> twice; once with the binary and once with the
- additional data. However, that will only work if there is only one
- process communicating with the port (because otherwise another process
- could call the driver in-between the calls).</p>
-
- <p>Another way to avoid copying binaries is to implement an <c>outputv</c>
- callback (instead of an <c>output</c> callback) in the driver.
- If a driver has an <c>outputv</c> callback, refc binaries passed
- in an iolist in the <c>Data</c> argument for
- <seealso marker="erts:erlang#port_command/2">port_command/2</seealso>
- will be passed as references to the driver.</p>
+ sent to a driver:</p>
+
+ <list type="bulleted">
+ <item><p>If the <c>Data</c> argument for
+ <seealso marker="erts:erlang#port_control/3">port_control/3</seealso>
+ is a binary, the driver will be passed a pointer to the contents of
+ the binary and the binary will not be copied. If the <c>Data</c>
+ argument is an iolist (list of binaries and lists), all binaries in
+ the iolist will be copied.</p>
+
+ <p>Therefore, if you want to send both a pre-existing binary and some
+ extra data to a driver without copying the binary, you must call
+ <c>port_control/3</c> twice; once with the binary and once with the
+ extra data. However, that will only work if there is only one
+ process communicating with the port (because otherwise another process
+ can call the driver in-between the calls).</p></item>
+
+ <item><p>Implement an <c>outputv</c> callback (instead of an
+ <c>output</c> callback) in the driver. If a driver has an
+ <c>outputv</c> callback, refc binaries passed in an iolist
+ in the <c>Data</c> argument for
+ <seealso marker="erts:erlang#port_command/2">port_command/2</seealso>
+ will be passed as references to the driver.</p></item>
+ </list>
</section>
<section>
- <title>Returning small binaries from a driver</title>
+ <title>Returning Small Binaries from a Driver</title>
- <p>The run-time system can represent binaries up to 64 bytes as
- heap binaries. They will always be copied when sent in a messages,
- but they will require less memory if they are not sent to another
+ <p>The runtime system can represent binaries up to 64 bytes as
+ heap binaries. They are always copied when sent in messages,
+ but they require less memory if they are not sent to another
process and garbage collection is cheaper.</p>
- <p>If you know that the binaries you return are always small,
- you should use driver API calls that do not require a pre-allocated
- binary, for instance
+ <p>If you know that the binaries you return are always small, you
+ are advised to use driver API calls that do not require a pre-allocated
+ binary, for example,
<seealso marker="erts:erl_driver#driver_output">driver_output()</seealso>
- or
- <seealso marker="erts:erl_driver#erl_drv_output_term">erl_drv_output_term()</seealso>
+ or
+ <seealso marker="erts:erl_driver#erl_drv_output_term">erl_drv_output_term()</seealso>,
using the <c>ERL_DRV_BUF2BINARY</c> format,
- to allow the run-time to construct a heap binary.</p>
+ to allow the runtime to construct a heap binary.</p>
</section>
<section>
- <title>Returning big binaries without copying from a driver</title>
+ <title>Returning Large Binaries without Copying from a Driver</title>
- <p>To avoid copying data when a big binary is sent or returned from
+ <p>To avoid copying data when a large binary is sent or returned from
the driver to an Erlang process, the driver must first allocate the
binary and then send it to an Erlang process in some way.</p>
- <p>Use <seealso marker="erts:erl_driver#driver_alloc_binary">driver_alloc_binary()</seealso> to allocate a binary.</p>
+ <p>Use
+ <seealso marker="erts:erl_driver#driver_alloc_binary">driver_alloc_binary()</seealso>
+ to allocate a binary.</p>
<p>There are several ways to send a binary created with
- <c>driver_alloc_binary()</c>.</p>
+ <c>driver_alloc_binary()</c>:</p>
<list type="bulleted">
- <item><p>From the <c>control</c> callback, a binary can be returned provided
- that
- <seealso marker="erts:erl_driver#set_port_control_flags">set_port_control_flags()</seealso>
- has been called with the flag value <c>PORT_CONTROL_FLAG_BINARY</c>.</p>
- </item>
+ <item>From the <c>control</c> callback, a binary can be returned if
+ <seealso marker="erts:erl_driver#set_port_control_flags">set_port_control_flags()</seealso>
+ has been called with the flag value <c>PORT_CONTROL_FLAG_BINARY</c>.</item>
- <item><p>A single binary can be sent with
- <seealso marker="erts:erl_driver#driver_output_binary">driver_output_binary()</seealso>.</p></item>
+ <item>A single binary can be sent with
+ <seealso marker="erts:erl_driver#driver_output_binary">driver_output_binary()</seealso>.</item>
- <item><p>Using
+ <item>Using
<seealso marker="erts:erl_driver#erl_drv_output_term">erl_drv_output_term()</seealso>
or
<seealso marker="erts:erl_driver#erl_drv_send_term">erl_drv_send_term()</seealso>,
- a binary can be included in an Erlang term.</p>
- </item>
+ a binary can be included in an Erlang term.</item>
</list>
</section>
-
</chapter>
diff --git a/system/doc/efficiency_guide/functions.xml b/system/doc/efficiency_guide/functions.xml
index ec1a45eaa9..9616df554e 100644
--- a/system/doc/efficiency_guide/functions.xml
+++ b/system/doc/efficiency_guide/functions.xml
@@ -8,17 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Functions</title>
@@ -30,17 +30,18 @@
</header>
<section>
- <title>Pattern matching</title>
- <p>Pattern matching in function head and in <c>case</c> and <c>receive</c>
- clauses are optimized by the compiler. With a few exceptions, there is nothing
- to gain by rearranging clauses.</p>
+ <title>Pattern Matching</title>
+ <p>Pattern matching in function head as well as in <c>case</c> and
+ <c>receive</c> clauses are optimized by the compiler. With a few
+ exceptions, there is nothing to gain by rearranging clauses.</p>
<p>One exception is pattern matching of binaries. The compiler
- will not rearrange clauses that match binaries. Placing the
- clause that matches against the empty binary <em>last</em> will usually
- be slightly faster than placing it <em>first</em>.</p>
+ does not rearrange clauses that match binaries. Placing the
+ clause that matches against the empty binary <em>last</em> is usually
+ slightly faster than placing it <em>first</em>.</p>
- <p>Here is a rather contrived example to show another exception:</p>
+ <p>The following is a rather unnatural example to show another
+ exception:</p>
<p><em>DO NOT</em></p>
<code type="erl">
@@ -53,27 +54,30 @@ atom_map1(five) -> 5;
atom_map1(six) -> 6.</code>
<p>The problem is the clause with the variable <c>Int</c>.
- Since a variable can match anything, including the atoms
- <c>four</c>, <c>five</c>, and <c>six</c> that the following clauses
- also will match, the compiler must generate sub-optimal code that will
- execute as follows:</p>
+ As a variable can match anything, including the atoms
+ <c>four</c>, <c>five</c>, and <c>six</c>, which the following clauses
+ also match, the compiler must generate suboptimal code that
+ executes as follows:</p>
- <p>First the input value is compared to <c>one</c>, <c>two</c>, and
+ <list type="bulleted">
+ <item>First, the input value is compared to <c>one</c>, <c>two</c>, and
<c>three</c> (using a single instruction that does a binary search;
thus, quite efficient even if there are many values) to select which
- one of the first three clauses to execute (if any).</p>
+ one of the first three clauses to execute (if any).</item>
+
+ <item>>If none of the first three clauses match, the fourth clause
+ match as a variable always matches.</item>
- <p>If none of the first three clauses matched, the fourth clause
- will match since a variable always matches. If the guard test
- <c>is_integer(Int)</c> succeeds, the fourth clause will be
- executed.</p>
+ <item>If the guard test <c>is_integer(Int)</c> succeeds, the fourth
+ clause is executed.</item>
- <p>If the guard test failed, the input value is compared to
+ <item>If the guard test fails, the input value is compared to
<c>four</c>, <c>five</c>, and <c>six</c>, and the appropriate clause
- is selected. (There will be a <c>function_clause</c> exception if
- none of the values matched.)</p>
+ is selected. (There is a <c>function_clause</c> exception if none of
+ the values matched.)</item>
+ </list>
- <p>Rewriting to either</p>
+ <p>Rewriting to either:</p>
<p><em>DO</em></p>
<code type="erl"><![CDATA[
@@ -85,7 +89,7 @@ atom_map2(five) -> 5;
atom_map2(six) -> 6;
atom_map2(Int) when is_integer(Int) -> Int.]]></code>
- <p>or</p>
+ <p>or:</p>
<p><em>DO</em></p>
<code type="erl"><![CDATA[
@@ -97,9 +101,9 @@ atom_map3(four) -> 4;
atom_map3(five) -> 5;
atom_map3(six) -> 6.]]></code>
- <p>will give slightly more efficient matching code.</p>
+ <p>gives slightly more efficient matching code.</p>
- <p>Here is a less contrived example:</p>
+ <p>Another example:</p>
<p><em>DO NOT</em></p>
<code type="erl"><![CDATA[
@@ -116,7 +120,8 @@ map_pairs1(Map, [X|Xs], [Y|Ys]) ->
match anything, the compiler is not allowed to rearrange the clauses,
but must generate code that matches them in the order written.</p>
- <p>If the function is rewritten like this</p>
+ <p>If the function is rewritten as follows, the compiler is free to
+ rearrange the clauses:</p>
<p><em>DO</em></p>
<code type="erl"><![CDATA[
@@ -127,8 +132,7 @@ map_pairs2(_Map, [_|_]=Xs, [] ) ->
map_pairs2(Map, [X|Xs], [Y|Ys]) ->
[Map(X, Y)|map_pairs2(Map, Xs, Ys)].]]></code>
- <p>the compiler is free to rearrange the clauses. It will generate code
- similar to this</p>
+ <p>The compiler will generate code similar to this:</p>
<p><em>DO NOT (already done by the compiler)</em></p>
<code type="erl"><![CDATA[
@@ -145,31 +149,35 @@ explicit_map_pairs(Map, Xs0, Ys0) ->
Ys0
end.]]></code>
- <p>which should be slightly faster for presumably the most common case
+ <p>This is slightly faster for probably the most common case
that the input lists are not empty or very short.
- (Another advantage is that Dialyzer is able to deduce a better type
- for the variable <c>Xs</c>.)</p>
+ (Another advantage is that Dialyzer can deduce a better type
+ for the <c>Xs</c> variable.)</p>
</section>
<section>
- <title>Function Calls </title>
+ <title>Function Calls</title>
- <p>Here is an intentionally rough guide to the relative costs of
- different kinds of calls. It is based on benchmark figures run on
+ <p>This is an intentionally rough guide to the relative costs of
+ different calls. It is based on benchmark figures run on
Solaris/Sparc:</p>
<list type="bulleted">
<item>Calls to local or external functions (<c>foo()</c>, <c>m:foo()</c>)
- are the fastest kind of calls.</item>
+ are the fastest calls.</item>
+
<item>Calling or applying a fun (<c>Fun()</c>, <c>apply(Fun, [])</c>)
- is about <em>three times</em> as expensive as calling a local function.</item>
+ is about <em>three times</em> as expensive as calling a local
+ function.</item>
+
<item>Applying an exported function (<c>Mod:Name()</c>,
- <c>apply(Mod, Name, [])</c>) is about twice as expensive as calling a fun,
- or about <em>six times</em> as expensive as calling a local function.</item>
+ <c>apply(Mod, Name, [])</c>) is about twice as expensive as calling
+ a fun or about <em>six times</em> as expensive as calling a local
+ function.</item>
</list>
<section>
- <title>Notes and implementation details</title>
+ <title>Notes and Implementation Details</title>
<p>Calling and applying a fun does not involve any hash-table lookup.
A fun contains an (indirect) pointer to the function that implements
@@ -178,42 +186,44 @@ explicit_map_pairs(Map, Xs0, Ys0) ->
<warning><p><em>Tuples are not fun(s)</em>.
A "tuple fun", <c>{Module,Function}</c>, is not a fun.
The cost for calling a "tuple fun" is similar to that
- of <c>apply/3</c> or worse. Using "tuple funs" is <em>strongly discouraged</em>,
- as they may not be supported in a future release,
- and because there exists a superior alternative since the R10B
- release, namely the <c>fun Module:Function/Arity</c> syntax.</p></warning>
+ of <c>apply/3</c> or worse.
+ Using "tuple funs" is <em>strongly discouraged</em>,
+ as they might not be supported in a future Erlang/OTP release,
+ and because there exists a superior alternative from R10B,
+ namely the <c>fun Module:Function/Arity</c> syntax.</p></warning>
<p><c>apply/3</c> must look up the code for the function to execute
- in a hash table. Therefore, it will always be slower than a
+ in a hash table. It is therefore always slower than a
direct call or a fun call.</p>
<p>It no longer matters (from a performance point of view)
- whether you write</p>
+ whether you write:</p>
<code type="erl">
Module:Function(Arg1, Arg2)</code>
- <p>or</p>
+ <p>or:</p>
<code type="erl">
apply(Module, Function, [Arg1,Arg2])</code>
- <p>(The compiler internally rewrites the latter code into the former.)</p>
+ <p>The compiler internally rewrites the latter code into the
+ former.</p>
- <p>The following code</p>
+ <p>The following code is slightly slower because the shape of the
+ list of arguments is unknown at compile time.</p>
<code type="erl">
apply(Module, Function, Arguments)</code>
- <p>is slightly slower because the shape of the list of arguments
- is not known at compile time.</p>
</section>
</section>
<section>
- <title>Memory usage in recursion</title>
- <p>When writing recursive functions it is preferable to make them
- tail-recursive so that they can execute in constant memory space.</p>
+ <title>Memory Usage in Recursion</title>
+ <p>When writing recursive functions, it is preferable to make them
+ tail-recursive so that they can execute in constant memory space:</p>
+
<p><em>DO</em></p>
<code type="none">
list_length(List) ->
@@ -224,13 +234,14 @@ list_length([], AccLen) ->
list_length([_|Tail], AccLen) ->
list_length(Tail, AccLen + 1). % Tail-recursive</code>
+
<p><em>DO NOT</em></p>
+
<code type="none">
list_length([]) ->
0. % Base case
list_length([_ | Tail]) ->
list_length(Tail) + 1. % Not tail-recursive</code>
</section>
-
</chapter>
diff --git a/system/doc/efficiency_guide/introduction.xml b/system/doc/efficiency_guide/introduction.xml
index 9726d3ad11..121ce3af21 100644
--- a/system/doc/efficiency_guide/introduction.xml
+++ b/system/doc/efficiency_guide/introduction.xml
@@ -8,17 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
<title>Introduction</title>
@@ -32,38 +32,39 @@
<section>
<title>Purpose</title>
- <quote><p>Premature optimization is the root of all evil. -- D.E. Knuth</p></quote>
+ <quote><p>"Premature optimization is the root of all evil"
+ (D.E. Knuth)</p></quote>
- <p>Efficient code can be well-structured and clean code, based on
+ <p>Efficient code can be well-structured and clean, based
on a sound overall architecture and sound algorithms.
Efficient code can be highly implementation-code that bypasses
documented interfaces and takes advantage of obscure quirks in
the current implementation.</p>
- <p>Ideally, your code should only contain the first kind of efficient
- code. If that turns out to be too slow, you should profile the application
+ <p>Ideally, your code only contains the first type of efficient
+ code. If that turns out to be too slow, profile the application
to find out where the performance bottlenecks are and optimize only the
- bottlenecks. Other code should stay as clean as possible.</p>
+ bottlenecks. Let other code stay as clean as possible.</p>
- <p>Fortunately, compiler and run-time optimizations introduced in
- R12B makes it easier to write code that is both clean and
- efficient. For instance, the ugly workarounds needed in R11B and earlier
+ <p>Fortunately, compiler and runtime optimizations introduced in
+ Erlang/OTP R12B makes it easier to write code that is both clean and
+ efficient. For example, the ugly workarounds needed in R11B and earlier
releases to get the most speed out of binary pattern matching are
no longer necessary. In fact, the ugly code is slower
than the clean code (because the clean code has become faster, not
because the uglier code has become slower).</p>
- <p>This Efficiency Guide cannot really learn you how to write efficient
+ <p>This Efficiency Guide cannot really teach you how to write efficient
code. It can give you a few pointers about what to avoid and what to use,
and some understanding of how certain language features are implemented.
- We have generally not included general tips about optimization that will
- work in any language, such as moving common calculations out of loops.</p>
+ This guide does not include general tips about optimization that
+ works in any language, such as moving common calculations out of loops.</p>
</section>
<section>
<title>Prerequisites</title>
- <p>It is assumed that the reader is familiar with the Erlang
- programming language and concepts of OTP.</p>
+ <p>It is assumed that you are familiar with the Erlang programming
+ language and the OTP concepts.</p>
</section>
</chapter>
diff --git a/system/doc/efficiency_guide/listhandling.xml b/system/doc/efficiency_guide/listhandling.xml
index 9112738b18..c7b5cf9a9a 100644
--- a/system/doc/efficiency_guide/listhandling.xml
+++ b/system/doc/efficiency_guide/listhandling.xml
@@ -8,20 +8,20 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>List handling</title>
+ <title>List Handling</title>
<prepared>Bjorn Gustavsson</prepared>
<docno></docno>
<date>2007-11-16</date>
@@ -30,19 +30,18 @@
</header>
<section>
- <title>Creating a list</title>
+ <title>Creating a List</title>
- <p>Lists can only be built starting from the end and attaching
- list elements at the beginning. If you use the <c>++</c> operator
- like this</p>
+ <p>Lists can only be built starting from the end and attaching list
+ elements at the beginning. If you use the "<c>++</c>" operator as
+ follows, a new list is created that is a copy of the elements in
+ <c>List1</c>, followed by <c>List2</c>:</p>
<code type="erl">
List1 ++ List2</code>
- <p>you will create a new list which is copy of the elements in <c>List1</c>,
- followed by <c>List2</c>. Looking at how <c>lists:append/1</c> or <c>++</c> would be
- implemented in plain Erlang, it can be seen clearly that the first list
- is copied:</p>
+ <p>Looking at how <c>lists:append/1</c> or <c>++</c> would be
+ implemented in plain Erlang, clearly the first list is copied:</p>
<code type="erl">
append([H|T], Tail) ->
@@ -50,12 +49,12 @@ append([H|T], Tail) ->
append([], Tail) ->
Tail.</code>
- <p>So the important thing when recursing and building a list is to
- make sure that you attach the new elements to the beginning of the list,
- so that you build <em>a</em> list, and not hundreds or thousands of
- copies of the growing result list.</p>
+ <p>When recursing and building a list, it is important to ensure
+ that you attach the new elements to the beginning of the list. In
+ this way, you will build <em>one</em> list, not hundreds or thousands
+ of copies of the growing result list.</p>
- <p>Let us first look at how it should not be done:</p>
+ <p>Let us first see how it is not to be done:</p>
<p><em>DO NOT</em></p>
<code type="erl"><![CDATA[
@@ -67,11 +66,11 @@ bad_fib(0, _Current, _Next, Fibs) ->
bad_fib(N, Current, Next, Fibs) ->
bad_fib(N - 1, Next, Current + Next, Fibs ++ [Current]).]]></code>
- <p>Here we are not a building a list; in each iteration step we
- create a new list that is one element longer than the new previous list.</p>
+ <p>Here more than one list is built. In each iteration step a new list
+ is created that is one element longer than the new previous list.</p>
- <p>To avoid copying the result in each iteration, we must build the list in
- reverse order and reverse the list when we are done:</p>
+ <p>To avoid copying the result in each iteration, build the list in
+ reverse order and reverse the list when you are done:</p>
<p><em>DO</em></p>
<code type="erl"><![CDATA[
@@ -86,49 +85,45 @@ tail_recursive_fib(N, Current, Next, Fibs) ->
</section>
<section>
- <title>List comprehensions</title>
+ <title>List Comprehensions</title>
<p>Lists comprehensions still have a reputation for being slow.
They used to be implemented using funs, which used to be slow.</p>
- <p>In recent Erlang/OTP releases (including R12B), a list comprehension</p>
+ <p>In recent Erlang/OTP releases (including R12B), a list comprehension:</p>
<code type="erl"><![CDATA[
[Expr(E) || E <- List]]]></code>
- <p>is basically translated to a local function</p>
+ <p>is basically translated to a local function:</p>
<code type="erl">
'lc^0'([E|Tail], Expr) ->
[Expr(E)|'lc^0'(Tail, Expr)];
'lc^0'([], _Expr) -> [].</code>
- <p>In R12B, if the result of the list comprehension will <em>obviously</em> not be used,
- a list will not be constructed. For instance, in this code</p>
+ <p>In R12B, if the result of the list comprehension will <em>obviously</em>
+ not be used, a list will not be constructed. For example, in this code:</p>
<code type="erl"><![CDATA[
[io:put_chars(E) || E <- List],
ok.]]></code>
- <p>or in this code</p>
+ <p>or in this code:</p>
<code type="erl"><![CDATA[
-.
-.
-.
+...
case Var of
... ->
[io:put_chars(E) || E <- List];
... ->
end,
some_function(...),
-.
-.
-.]]></code>
+...]]></code>
- <p>the value is neither assigned to a variable, nor passed to another function,
- nor returned, so there is no need to construct a list and the compiler will simplify
- the code for the list comprehension to</p>
+ <p>the value is not assigned to a variable, not passed to another function,
+ and not returned. This means that there is no need to construct a list and
+ the compiler will simplify the code for the list comprehension to:</p>
<code type="erl">
'lc^0'([E|Tail], Expr) ->
@@ -139,14 +134,15 @@ some_function(...),
</section>
<section>
- <title>Deep and flat lists</title>
+ <title>Deep and Flat Lists</title>
<p><seealso marker="stdlib:lists#flatten/1">lists:flatten/1</seealso>
- builds an entirely new list. Therefore, it is expensive, and even
- <em>more</em> expensive than the <c>++</c> (which copies its left argument,
- but not its right argument).</p>
+ builds an entirely new list. It is therefore expensive, and even
+ <em>more</em> expensive than the <c>++</c> operator (which copies its
+ left argument, but not its right argument).</p>
- <p>In the following situations, you can easily avoid calling <c>lists:flatten/1</c>:</p>
+ <p>In the following situations, you can easily avoid calling
+ <c>lists:flatten/1</c>:</p>
<list type="bulleted">
<item>When sending data to a port. Ports understand deep lists
@@ -155,16 +151,19 @@ some_function(...),
<item>When calling BIFs that accept deep lists, such as
<seealso marker="erts:erlang#list_to_binary/1">list_to_binary/1</seealso> or
<seealso marker="erts:erlang#iolist_to_binary/1">iolist_to_binary/1</seealso>.</item>
- <item>When you know that your list is only one level deep, you can can use
+ <item>When you know that your list is only one level deep, you can use
<seealso marker="stdlib:lists#append/1">lists:append/1</seealso>.</item>
</list>
- <p><em>Port example</em></p>
+ <section>
+ <title>Port Example</title>
+
<p><em>DO</em></p>
<pre>
...
port_command(Port, DeepList)
...</pre>
+
<p><em>DO NOT</em></p>
<pre>
...
@@ -180,7 +179,7 @@ some_function(...),
port_command(Port, TerminatedStr)
...</pre>
- <p>Instead do like this:</p>
+ <p>Instead:</p>
<p><em>DO</em></p>
<pre>
@@ -188,47 +187,53 @@ some_function(...),
TerminatedStr = [String, 0], % String="foo" => [[$f, $o, $o], 0]
port_command(Port, TerminatedStr)
...</pre>
+ </section>
+
+ <section>
+ <title>Append Example</title>
- <p><em>Append example</em></p>
<p><em>DO</em></p>
<pre>
> lists:append([[1], [2], [3]]).
[1,2,3]
></pre>
+
<p><em>DO NOT</em></p>
<pre>
> lists:flatten([[1], [2], [3]]).
[1,2,3]
></pre>
+ </section>
</section>
<section>
- <title>Why you should not worry about recursive lists functions</title>
+ <title>Recursive List Functions</title>
- <p>In the performance myth chapter, the following myth was exposed:
- <seealso marker="myths#tail_recursive">Tail-recursive functions
- are MUCH faster than recursive functions</seealso>.</p>
+ <p>In Section 7.2, the following myth was exposed:
+ <seealso marker="myths#tail_recursive">Tail-Recursive Functions
+ are Much Faster Than Recursive Functions</seealso>.</p>
<p>To summarize, in R12B there is usually not much difference between
a body-recursive list function and tail-recursive function that reverses
the list at the end. Therefore, concentrate on writing beautiful code
- and forget about the performance of your list functions. In the time-critical
- parts of your code (and only there), <em>measure</em> before rewriting
- your code.</p>
-
- <p><em>Important note</em>: This section talks about lists functions that
- <em>construct</em> lists. A tail-recursive function that does not construct
- a list runs in constant space, while the corresponding body-recursive
- function uses stack space proportional to the length of the list.
- For instance, a function that sums a list of integers, should <em>not</em> be
- written like this</p>
+ and forget about the performance of your list functions. In the
+ time-critical parts of your code (and only there), <em>measure</em>
+ before rewriting your code.</p>
+
+ <note><p>This section is about list functions that <em>construct</em>
+ lists. A tail-recursive function that does not construct a list runs
+ in constant space, while the corresponding body-recursive function
+ uses stack space proportional to the length of the list.</p></note>
+
+ <p>For example, a function that sums a list of integers, is
+ <em>not</em> to be written as follows:</p>
<p><em>DO NOT</em></p>
<code type="erl">
recursive_sum([H|T]) -> H+recursive_sum(T);
recursive_sum([]) -> 0.</code>
- <p>but like this</p>
+ <p>Instead:</p>
<p><em>DO</em></p>
<code type="erl">
diff --git a/system/doc/efficiency_guide/myths.xml b/system/doc/efficiency_guide/myths.xml
index b1108dbab2..651d909834 100644
--- a/system/doc/efficiency_guide/myths.xml
+++ b/system/doc/efficiency_guide/myths.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
@@ -31,47 +32,48 @@
<file>myths.xml</file>
</header>
+ <marker id="myths"></marker>
<p>Some truths seem to live on well beyond their best-before date,
- perhaps because "information" spreads more rapidly from person-to-person
- faster than a single release note that notes, for instance, that funs
+ perhaps because "information" spreads faster from person-to-person
+ than a single release note that says, for example, that funs
have become faster.</p>
- <p>Here we try to kill the old truths (or semi-truths) that have
+ <p>This section tries to kill the old truths (or semi-truths) that have
become myths.</p>
<section>
- <title>Myth: Funs are slow</title>
- <p>Yes, funs used to be slow. Very slow. Slower than <c>apply/3</c>.
+ <title>Myth: Funs are Slow</title>
+ <p>Funs used to be very slow, slower than <c>apply/3</c>.
Originally, funs were implemented using nothing more than
compiler trickery, ordinary tuples, <c>apply/3</c>, and a great
deal of ingenuity.</p>
- <p>But that is ancient history. Funs was given its own data type
- in the R6B release and was further optimized in the R7B release.
- Now the cost for a fun call falls roughly between the cost for a call to
- local function and <c>apply/3</c>.</p>
+ <p>But that is history. Funs was given its own data type
+ in R6B and was further optimized in R7B.
+ Now the cost for a fun call falls roughly between the cost for a call
+ to a local function and <c>apply/3</c>.</p>
</section>
<section>
- <title>Myth: List comprehensions are slow</title>
+ <title>Myth: List Comprehensions are Slow</title>
<p>List comprehensions used to be implemented using funs, and in the
- bad old days funs were really slow.</p>
+ old days funs were indeed slow.</p>
- <p>Nowadays the compiler rewrites list comprehensions into an ordinary
- recursive function. Of course, using a tail-recursive function with
+ <p>Nowadays, the compiler rewrites list comprehensions into an ordinary
+ recursive function. Using a tail-recursive function with
a reverse at the end would be still faster. Or would it?
That leads us to the next myth.</p>
</section>
<section>
- <title>Myth: Tail-recursive functions are MUCH faster
- than recursive functions</title>
+ <title>Myth: Tail-Recursive Functions are Much Faster
+ Than Recursive Functions</title>
<p><marker id="tail_recursive"></marker>According to the myth,
recursive functions leave references
- to dead terms on the stack and the garbage collector will have to
- copy all those dead terms, while tail-recursive functions immediately
+ to dead terms on the stack and the garbage collector has to copy
+ all those dead terms, while tail-recursive functions immediately
discard those terms.</p>
<p>That used to be true before R7B. In R7B, the compiler started
@@ -79,48 +81,47 @@
be used with an empty list, so that the garbage collector would not
keep dead values any longer than necessary.</p>
- <p>Even after that optimization, a tail-recursive function would
- still most of the time be faster than a body-recursive function. Why?</p>
+ <p>Even after that optimization, a tail-recursive function is
+ still most of the times faster than a body-recursive function. Why?</p>
<p>It has to do with how many words of stack that are used in each
- recursive call. In most cases, a recursive function would use more words
+ recursive call. In most cases, a recursive function uses more words
on the stack for each recursion than the number of words a tail-recursive
- would allocate on the heap. Since more memory is used, the garbage
- collector will be invoked more frequently, and it will have more work traversing
+ would allocate on the heap. As more memory is used, the garbage
+ collector is invoked more frequently, and it has more work traversing
the stack.</p>
- <p>In R12B and later releases, there is an optimization that will
+ <p>In R12B and later releases, there is an optimization that
in many cases reduces the number of words used on the stack in
- body-recursive calls, so that a body-recursive list function and
+ body-recursive calls. A body-recursive list function and a
tail-recursive function that calls <seealso
- marker="stdlib:lists#reverse/1">lists:reverse/1</seealso> at the
- end will use exactly the same amount of memory.
+ marker="stdlib:lists#reverse/1">lists:reverse/1</seealso> at
+ the end will use the same amount of memory.
<c>lists:map/2</c>, <c>lists:filter/2</c>, list comprehensions,
and many other recursive functions now use the same amount of space
as their tail-recursive equivalents.</p>
- <p>So which is faster?</p>
-
- <p>It depends. On Solaris/Sparc, the body-recursive function seems to
- be slightly faster, even for lists with very many elements. On the x86
- architecture, tail-recursion was up to about 30 percent faster.</p>
+ <p>So, which is faster?
+ It depends. On Solaris/Sparc, the body-recursive function seems to
+ be slightly faster, even for lists with a lot of elements. On the x86
+ architecture, tail-recursion was up to about 30% faster.</p>
- <p>So the choice is now mostly a matter of taste. If you really do need
+ <p>So, the choice is now mostly a matter of taste. If you really do need
the utmost speed, you must <em>measure</em>. You can no longer be
- absolutely sure that the tail-recursive list function will be the fastest
- in all circumstances.</p>
+ sure that the tail-recursive list function always is the fastest.</p>
- <p>Note: A tail-recursive function that does not need to reverse the
- list at the end is, of course, faster than a body-recursive function,
+ <note><p>A tail-recursive function that does not need to reverse the
+ list at the end is faster than a body-recursive function,
as are tail-recursive functions that do not construct any terms at all
- (for instance, a function that sums all integers in a list).</p>
+ (for example, a function that sums all integers in a list).</p></note>
</section>
<section>
- <title>Myth: '++' is always bad</title>
+ <title>Myth: Operator "++" is Always Bad</title>
- <p>The <c>++</c> operator has, somewhat undeservedly, got a very bad reputation.
- It probably has something to do with code like</p>
+ <p>The <c>++</c> operator has, somewhat undeservedly, got a bad reputation.
+ It probably has something to do with code like the following,
+ which is the most inefficient way there is to reverse a list:</p>
<p><em>DO NOT</em></p>
<code type="erl">
@@ -129,12 +130,10 @@ naive_reverse([H|T]) ->
naive_reverse([]) ->
[].</code>
- <p>which is the most inefficient way there is to reverse a list.
- Since the <c>++</c> operator copies its left operand, the result
- will be copied again and again and again... leading to quadratic
- complexity.</p>
+ <p>As the <c>++</c> operator copies its left operand, the result
+ is copied repeatedly, leading to quadratic complexity.</p>
- <p>On the other hand, using <c>++</c> like this</p>
+ <p>But using <c>++</c> as follows is not bad:</p>
<p><em>OK</em></p>
<code type="erl">
@@ -143,11 +142,11 @@ naive_but_ok_reverse([H|T], Acc) ->
naive_but_ok_reverse([], Acc) ->
Acc.</code>
- <p>is not bad. Each list element will only be copied once.
+ <p>Each list element is copied only once.
The growing result <c>Acc</c> is the right operand
- for the <c>++</c> operator, and it will <em>not</em> be copied.</p>
+ for the <c>++</c> operator, and it is <em>not</em> copied.</p>
- <p>Of course, experienced Erlang programmers would actually write</p>
+ <p>Experienced Erlang programmers would write as follows:</p>
<p><em>DO</em></p>
<code type="erl">
@@ -156,32 +155,34 @@ vanilla_reverse([H|T], Acc) ->
vanilla_reverse([], Acc) ->
Acc.</code>
- <p>which is slightly more efficient because you don't build a
- list element only to directly copy it. (Or it would be more efficient
- if the the compiler did not automatically rewrite <c>[H]++Acc</c>
+ <p>This is slightly more efficient because here you do not build a
+ list element only to copy it directly. (Or it would be more efficient
+ if the compiler did not automatically rewrite <c>[H]++Acc</c>
to <c>[H|Acc]</c>.)</p>
</section>
<section>
- <title>Myth: Strings are slow</title>
-
- <p>Actually, string handling could be slow if done improperly.
- In Erlang, you'll have to think a little more about how the strings
- are used and choose an appropriate representation and use
- the <seealso marker="stdlib:re">re</seealso> module instead of the obsolete
- <c>regexp</c> module if you are going to use regular expressions.</p>
+ <title>Myth: Strings are Slow</title>
+
+ <p>String handling can be slow if done improperly.
+ In Erlang, you need to think a little more about how the strings
+ are used and choose an appropriate representation. If you
+ use regular expressions, use the
+ <seealso marker="stdlib:re">re</seealso> module in STDLIB
+ instead of the obsolete <c>regexp</c> module.</p>
</section>
<section>
- <title>Myth: Repairing a Dets file is very slow</title>
+ <title>Myth: Repairing a Dets File is Very Slow</title>
<p>The repair time is still proportional to the number of records
- in the file, but Dets repairs used to be much, much slower in the past.
+ in the file, but Dets repairs used to be much slower in the past.
Dets has been massively rewritten and improved.</p>
</section>
<section>
- <title>Myth: BEAM is a stack-based byte-code virtual machine (and therefore slow)</title>
+ <title>Myth: BEAM is a Stack-Based Byte-Code Virtual Machine
+ (and Therefore Slow)</title>
<p>BEAM is a register-based virtual machine. It has 1024 virtual registers
that are used for holding temporary values and for passing arguments when
@@ -193,11 +194,11 @@ vanilla_reverse([], Acc) ->
</section>
<section>
- <title>Myth: Use '_' to speed up your program when a variable is not used</title>
+ <title>Myth: Use "_" to Speed Up Your Program When a Variable
+ is Not Used</title>
- <p>That was once true, but since R6B the BEAM compiler is quite capable of seeing itself
+ <p>That was once true, but from R6B the BEAM compiler can see
that a variable is not used.</p>
</section>
-
</chapter>
diff --git a/system/doc/efficiency_guide/part.xml b/system/doc/efficiency_guide/part.xml
index 3918560812..2862058bf2 100644
--- a/system/doc/efficiency_guide/part.xml
+++ b/system/doc/efficiency_guide/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/efficiency_guide/processes.xml b/system/doc/efficiency_guide/processes.xml
index 86951e2dcc..2d486ef7ff 100644
--- a/system/doc/efficiency_guide/processes.xml
+++ b/system/doc/efficiency_guide/processes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,15 +31,15 @@
</header>
<section>
- <title>Creation of an Erlang process</title>
+ <title>Creating an Erlang Process</title>
- <p>An Erlang process is lightweight compared to operating
- systems threads and processes.</p>
+ <p>An Erlang process is lightweight compared to threads and
+ processes in operating systems.</p>
<p>A newly spawned Erlang process uses 309 words of memory
in the non-SMP emulator without HiPE support. (SMP support
- and HiPE support will both add to this size.) The size can
- be found out like this:</p>
+ and HiPE support both add to this size.) The size can
+ be found as follows:</p>
<pre>
Erlang (BEAM) emulator version 5.6 [async-threads:0] [kernel-poll:false]
@@ -51,11 +52,11 @@ Eshell V5.6 (abort with ^G)
3> <input>Bytes div erlang:system_info(wordsize).</input>
309</pre>
- <p>The size includes 233 words for the heap area (which includes the stack).
- The garbage collector will increase the heap as needed.</p>
+ <p>The size includes 233 words for the heap area (which includes the
+ stack). The garbage collector increases the heap as needed.</p>
<p>The main (outer) loop for a process <em>must</em> be tail-recursive.
- If not, the stack will grow until the process terminates.</p>
+ Otherwise, the stack grows until the process terminates.</p>
<p><em>DO NOT</em></p>
<code type="erl">
@@ -74,7 +75,7 @@ loop() ->
<p>The call to <c>io:format/2</c> will never be executed, but a
return address will still be pushed to the stack each time
<c>loop/0</c> is called recursively. The correct tail-recursive
- version of the function looks like this:</p>
+ version of the function looks as follows:</p>
<p><em>DO</em></p>
<code type="erl">
@@ -90,92 +91,98 @@ loop() ->
end.</code>
<section>
- <title>Initial heap size</title>
+ <title>Initial Heap Size</title>
<p>The default initial heap size of 233 words is quite conservative
- in order to support Erlang systems with hundreds of thousands or
- even millions of processes. The garbage collector will grow and
- shrink the heap as needed.</p>
+ to support Erlang systems with hundreds of thousands or
+ even millions of processes. The garbage collector grows and
+ shrinks the heap as needed.</p>
<p>In a system that use comparatively few processes, performance
- <em>might</em> be improved by increasing the minimum heap size using either
- the <c>+h</c> option for
+ <em>might</em> be improved by increasing the minimum heap size
+ using either the <c>+h</c> option for
<seealso marker="erts:erl">erl</seealso> or on a process-per-process
basis using the <c>min_heap_size</c> option for
<seealso marker="erts:erlang#spawn_opt/4">spawn_opt/4</seealso>.</p>
- <p>The gain is twofold: Firstly, although the garbage collector will
- grow the heap, it will grow it step by step, which will be more
- costly than directly establishing a larger heap when the process
- is spawned. Secondly, the garbage collector may also shrink the
- heap if it is much larger than the amount of data stored on it;
- setting the minimum heap size will prevent that.</p>
-
- <warning><p>The emulator will probably use more memory, and because garbage
- collections occur less frequently, huge binaries could be
+ <p>The gain is twofold:</p>
+ <list type="bulleted">
+ <item>Although the garbage collector grows the heap, it grows it
+ step-by-step, which is more costly than directly establishing a
+ larger heap when the process is spawned.</item>
+ <item>The garbage collector can also shrink the heap if it is
+ much larger than the amount of data stored on it;
+ setting the minimum heap size prevents that.</item>
+ </list>
+
+ <warning><p>The emulator probably uses more memory, and because garbage
+ collections occur less frequently, huge binaries can be
kept much longer.</p></warning>
<p>In systems with many processes, computation tasks that run
- for a short time could be spawned off into a new process with
- a higher minimum heap size. When the process is done, it will
- send the result of the computation to another process and terminate.
- If the minimum heap size is calculated properly, the process may not
- have to do any garbage collections at all.
- <em>This optimization should not be attempted
+ for a short time can be spawned off into a new process with
+ a higher minimum heap size. When the process is done, it sends
+ the result of the computation to another process and terminates.
+ If the minimum heap size is calculated properly, the process might
+ not have to do any garbage collections at all.
+ <em>This optimization is not to be attempted
without proper measurements.</em></p>
</section>
-
</section>
<section>
- <title>Process messages</title>
+ <title>Process Messages</title>
- <p>All data in messages between Erlang processes is copied, with
- the exception of
+ <p>All data in messages between Erlang processes is copied,
+ except for
<seealso marker="binaryhandling#refc_binary">refc binaries</seealso>
on the same Erlang node.</p>
<p>When a message is sent to a process on another Erlang node,
- it will first be encoded to the Erlang External Format before
- being sent via an TCP/IP socket. The receiving Erlang node decodes
- the message and distributes it to the right process.</p>
+ it is first encoded to the Erlang External Format before
+ being sent through a TCP/IP socket. The receiving Erlang node decodes
+ the message and distributes it to the correct process.</p>
<section>
- <title>The constant pool</title>
+ <title>Constant Pool</title>
<p>Constant Erlang terms (also called <em>literals</em>) are now
kept in constant pools; each loaded module has its own pool.
- The following function</p>
+ The following function does no longer build the tuple every time
+ it is called (only to have it discarded the next time the garbage
+ collector was run), but the tuple is located in the module's
+ constant pool:</p>
<p><em>DO</em> (in R12B and later)</p>
<code type="erl">
days_in_month(M) ->
- element(M, {31,28,31,30,31,30,31,31,30,31,30,31}).</code>
-
- <p>will no longer build the tuple every time it is called (only
- to have it discarded the next time the garbage collector was run), but
- the tuple will be located in the module's constant pool.</p>
+ element(M, {31,28,31,30,31,30,31,31,30,31,30,31}).</code>
<p>But if a constant is sent to another process (or stored in
- an ETS table), it will be <em>copied</em>.
- The reason is that the run-time system must be able
- to keep track of all references to constants in order to properly
- unload code containing constants. (When the code is unloaded,
- the constants will be copied to the heap of the processes that refer
+ an Ets table), it is <em>copied</em>.
+ The reason is that the runtime system must be able
+ to keep track of all references to constants to unload code
+ containing constants properly. (When the code is unloaded,
+ the constants are copied to the heap of the processes that refer
to them.) The copying of constants might be eliminated in a future
- release.</p>
+ Erlang/OTP release.</p>
</section>
<section>
- <title>Loss of sharing</title>
+ <title>Loss of Sharing</title>
- <p>Shared sub-terms are <em>not</em> preserved when a term is sent
- to another process, passed as the initial process arguments in
- the <c>spawn</c> call, or stored in an ETS table.
- That is an optimization. Most applications do not send messages
- with shared sub-terms.</p>
+ <p>Shared subterms are <em>not</em> preserved in the following
+ cases:</p>
+ <list type="bulleted">
+ <item>When a term is sent to another process</item>
+ <item>When a term is passed as the initial process arguments in
+ the <c>spawn</c> call</item>
+ <item>When a term is stored in an Ets table</item>
+ </list>
+ <p>That is an optimization. Most applications do not send messages
+ with shared subterms.</p>
- <p>Here is an example of how a shared sub-term can be created:</p>
+ <p>The following example shows how a shared subterm can be created:</p>
<code type="erl">
kilo_byte() ->
@@ -186,32 +193,32 @@ kilo_byte(0, Acc) ->
kilo_byte(N, Acc) ->
kilo_byte(N-1, [Acc|Acc]).</code>
- <p><c>kilo_byte/0</c> creates a deep list. If we call
- <c>list_to_binary/1</c>, we can convert the deep list to a binary
- of 1024 bytes:</p>
+ <p><c>kilo_byte/1</c> creates a deep list.
+ If <c>list_to_binary/1</c> is called, the deep list can be
+ converted to a binary of 1024 bytes:</p>
<pre>
1> <input>byte_size(list_to_binary(efficiency_guide:kilo_byte())).</input>
1024</pre>
- <p>Using the <c>erts_debug:size/1</c> BIF we can see that the
+ <p>Using the <c>erts_debug:size/1</c> BIF, it can be seen that the
deep list only requires 22 words of heap space:</p>
<pre>
2> <input>erts_debug:size(efficiency_guide:kilo_byte()).</input>
22</pre>
- <p>Using the <c>erts_debug:flat_size/1</c> BIF, we can calculate
- the size of the deep list if sharing is ignored. It will be
+ <p>Using the <c>erts_debug:flat_size/1</c> BIF, the size of the
+ deep list can be calculated if sharing is ignored. It becomes
the size of the list when it has been sent to another process
- or stored in an ETS table:</p>
+ or stored in an Ets table:</p>
<pre>
3> <input>erts_debug:flat_size(efficiency_guide:kilo_byte()).</input>
4094</pre>
- <p>We can verify that sharing will be lost if we insert the
- data into an ETS table:</p>
+ <p>It can be verified that sharing will be lost if the data is
+ inserted into an Ets table:</p>
<pre>
4> <input>T = ets:new(tab, []).</input>
@@ -223,21 +230,21 @@ true
7> <input>erts_debug:flat_size(element(2, hd(ets:lookup(T, key)))).</input>
4094</pre>
- <p>When the data has passed through an ETS table,
+ <p>When the data has passed through an Ets table,
<c>erts_debug:size/1</c> and <c>erts_debug:flat_size/1</c>
return the same value. Sharing has been lost.</p>
- <p>In a future release of Erlang/OTP, we might implement a
- way to (optionally) preserve sharing. We have no plans to make
- preserving of sharing the default behaviour, since that would
+ <p>In a future Erlang/OTP release, it might be implemented a
+ way to (optionally) preserve sharing. There are no plans to make
+ preserving of sharing the default behaviour, as that would
penalize the vast majority of Erlang applications.</p>
</section>
</section>
<section>
- <title>The SMP emulator</title>
+ <title>SMP Emulator</title>
- <p>The SMP emulator (introduced in R11B) will take advantage of a
+ <p>The SMP emulator (introduced in R11B) takes advantage of a
multi-core or multi-CPU computer by running several Erlang scheduler
threads (typically, the same as the number of cores). Each scheduler
thread schedules Erlang processes in the same way as the Erlang scheduler
@@ -247,11 +254,11 @@ true
<em>must have more than one runnable Erlang process</em> most of the time.
Otherwise, the Erlang emulator can still only run one Erlang process
at the time, but you must still pay the overhead for locking. Although
- we try to reduce the locking overhead as much as possible, it will never
- become exactly zero.</p>
+ Erlang/OTP tries to reduce the locking overhead as much as possible,
+ it will never become exactly zero.</p>
- <p>Benchmarks that may seem to be concurrent are often sequential.
- The estone benchmark, for instance, is entirely sequential. So is also
+ <p>Benchmarks that appear to be concurrent are often sequential.
+ The estone benchmark, for example, is entirely sequential. So is
the most common implementation of the "ring benchmark"; usually one process
is active, while the others wait in a <c>receive</c> statement.</p>
@@ -259,6 +266,5 @@ true
can be used to profile your application to see how much potential (or lack
thereof) it has for concurrency.</p>
</section>
-
</chapter>
diff --git a/system/doc/efficiency_guide/profiling.xml b/system/doc/efficiency_guide/profiling.xml
index b93c884270..4fbec927f4 100644
--- a/system/doc/efficiency_guide/profiling.xml
+++ b/system/doc/efficiency_guide/profiling.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,190 +31,197 @@
</header>
<section>
- <title>Do not guess about performance - profile</title>
+ <title>Do Not Guess About Performance - Profile</title>
<p>Even experienced software developers often guess wrong about where
- the performance bottlenecks are in their programs.</p>
-
- <p>Therefore, profile your program to see where the performance
+ the performance bottlenecks are in their programs. Therefore, profile
+ your program to see where the performance
bottlenecks are and concentrate on optimizing them.</p>
- <p>Erlang/OTP contains several tools to help finding bottlenecks.</p>
+ <p>Erlang/OTP contains several tools to help finding bottlenecks:</p>
+
+ <list type="bulleted">
+ <item><c>fprof</c> provides the most detailed information about
+ where the program time is spent, but it significantly slows down the
+ program it profiles.</item>
- <p><c>fprof</c> provide the most detailed information
- about where the time is spent, but it significantly slows down the
- program it profiles.</p>
+ <item><p><c>eprof</c> provides time information of each function
+ used in the program. No call graph is produced, but <c>eprof</c> has
+ considerable less impact on the program it profiles.</p>
+ <p>If the program is too large to be profiled by <c>fprof</c> or
+ <c>eprof</c>, the <c>cover</c> and <c>cprof</c> tools can be used
+ to locate code parts that are to be more thoroughly profiled using
+ <c>fprof</c> or <c>eprof</c>.</p></item>
- <p><c>eprof</c> provides time information of each function used
- in the program. No callgraph is produced but <c>eprof</c> has
- considerable less impact on the program profiled.</p>
+ <item><c>cover</c> provides execution counts per line per
+ process, with less overhead than <c>fprof</c>. Execution counts
+ can, with some caution, be used to locate potential performance
+ bottlenecks.</item>
- <p>If the program is too big to be profiled by <c>fprof</c> or <c>eprof</c>,
- <c>cover</c> and <c>cprof</c> could be used to locate parts of the
- code that should be more thoroughly profiled using <c>fprof</c> or
- <c>eprof</c>.</p>
+ <item><c>cprof</c> is the most lightweight tool, but it only
+ provides execution counts on a function basis (for all processes,
+ not per process).</item>
+ </list>
- <p><c>cover</c> provides execution counts per line per process,
- with less overhead than <c>fprof</c>. Execution counts can
- with some caution be used to locate potential performance bottlenecks.
- The most lightweight tool is <c>cprof</c>, but it only provides execution
- counts on a function basis (for all processes, not per process).</p>
+ <p>The tools are further described in
+ <seealso marker="#profiling_tools">Tools</seealso>.</p>
</section>
<section>
- <title>Big systems</title>
- <p>If you have a big system it might be interesting to run profiling
+ <title>Large Systems</title>
+ <p>For a large system, it can be interesting to run profiling
on a simulated and limited scenario to start with. But bottlenecks
- have a tendency to only appear or cause problems when
- there are many things going on at the same time, and when there
- are many nodes involved. Therefore it is desirable to also run
+ have a tendency to appear or cause problems only when
+ many things are going on at the same time, and when
+ many nodes are involved. Therefore, it is also desirable to run
profiling in a system test plant on a real target system.</p>
- <p>When your system is big you do not want to run the profiling
- tools on the whole system. You want to concentrate on processes
- and modules that you know are central and stand for a big part of the
- execution.</p>
+
+ <p>For a large system, you do not want to run the profiling
+ tools on the whole system. Instead you want to concentrate on
+ central processes and modules, which contribute for a big part
+ of the execution.</p>
</section>
<section>
- <title>What to look for</title>
- <p>When analyzing the result file from the profiling activity
- you should look for functions that are called many
+ <title>What to Look For</title>
+ <p>When analyzing the result file from the profiling activity,
+ look for functions that are called many
times and have a long "own" execution time (time excluding calls
- to other functions). Functions that just are called very
- many times can also be interesting, as even small things can add
- up to quite a bit if they are repeated often. Then you need to
- ask yourself what can I do to reduce this time. Appropriate
- types of questions to ask yourself are: </p>
+ to other functions). Functions that are called a lot of
+ times can also be interesting, as even small things can add
+ up to quite a bit if repeated often. Also
+ ask yourself what you can do to reduce this time. The following
+ are appropriate types of questions to ask yourself:</p>
+
<list type="bulleted">
- <item>Can I reduce the number of times the function is called?</item>
- <item>Are there tests that can be run less often if I change
- the order of tests?</item>
- <item>Are there redundant tests that can be removed? </item>
- <item>Is there some expression calculated giving the same result
- each time? </item>
- <item>Are there other ways of doing this that are equivalent and
+ <item>Is it possible to reduce the number of times the function
+ is called?</item>
+ <item>Can any test be run less often if the order of tests is
+ changed?</item>
+ <item>Can any redundant tests be removed?</item>
+ <item>Does any calculated expression give the same result
+ each time?</item>
+ <item>Are there other ways to do this that are equivalent and
more efficient?</item>
- <item>Can I use another internal data representation to make
- things more efficient? </item>
+ <item>Can another internal data representation be used to make
+ things more efficient?</item>
</list>
- <p>These questions are not always trivial to answer. You might
- need to do some benchmarks to back up your theory, to avoid
- making things slower if your theory is wrong. See <seealso marker="#benchmark">benchmarking</seealso>.</p>
+
+ <p>These questions are not always trivial to answer. Some
+ benchmarks might be needed to back up your theory and to avoid
+ making things slower if your theory is wrong. For details, see
+ <seealso marker="#benchmark">Benchmarking</seealso>.</p>
</section>
<section>
<title>Tools</title>
-
+ <marker id="profiling_tools"></marker>
<section>
<title>fprof</title>
- <p>
- <c>fprof</c> measures the execution time for each function,
- both own time i.e how much time a function has used for its
- own execution, and accumulated time i.e. including called
- functions. The values are displayed per process. You also get
- to know how many times each function has been
- called. <c>fprof</c> is based on trace to file in order to
- minimize runtime performance impact. Using fprof is just a
- matter of calling a few library functions, see
- <seealso marker="tools:fprof">fprof</seealso>
- manual page under the application tools.<c> fprof</c> was introduced in
- version R8 of Erlang/OTP.
- </p>
+ <p><c>fprof</c> measures the execution time for each function,
+ both own time, that is, how much time a function has used for its
+ own execution, and accumulated time, that is, including called
+ functions. The values are displayed per process. You also get
+ to know how many times each function has been called.</p>
+
+ <p><c>fprof</c> is based on trace to file to minimize runtime
+ performance impact. Using <c>fprof</c> is just a matter of
+ calling a few library functions, see the
+ <seealso marker="tools:fprof">fprof</seealso> manual page in
+ <c>tools</c> .<c>fprof</c> was introduced in R8.</p>
</section>
- <section>
- <title>eprof</title>
- <p>
- <c>eprof</c> is based on the Erlang trace_info BIFs. Eprof shows how much time has been used by
- each process, and in which function calls this time has been
- spent. Time is shown as percentage of total time and absolute time.
- See <seealso marker="tools:eprof">eprof</seealso> for
- additional information.
- </p>
- </section>
+ <section>
+ <title>eprof</title>
+ <p><c>eprof</c> is based on the Erlang <c>trace_info</c> BIFs.
+ <c>eprof</c> shows how much time has been used by each process,
+ and in which function calls this time has been spent. Time is
+ shown as percentage of total time and absolute time. For more
+ information, see the <seealso marker="tools:eprof">eprof</seealso>
+ manual page in <c>tools</c>.</p>
+ </section>
<section>
<title>cover</title>
- <p>
- <c>cover</c>'s primary use is coverage analysis to verify
- test cases, making sure all relevant code is covered.
- <c>cover</c> counts how many times each executable line of
- code is executed when a program is run. This is done on a per
- module basis. Of course this information can be used to
- determine what code is run very frequently and could therefore
- be subject for optimization. Using cover is just a matter of
- calling a few library functions, see
- <seealso marker="tools:cover">cover</seealso>
- manual page under the application tools.</p>
+ <p>The primary use of <c>cover</c> is coverage analysis to verify
+ test cases, making sure that all relevant code is covered.
+ <c>cover</c> counts how many times each executable line of code
+ is executed when a program is run, on a per module basis.</p>
+ <p>Clearly, this information can be used to determine what
+ code is run very frequently and can therefore be subject for
+ optimization. Using <c>cover</c> is just a matter of calling a
+ few library functions, see the
+ <seealso marker="tools:cover">cover</seealso> manual page in
+ <c>tools</c>.</p>
</section>
<section>
<title>cprof</title>
<p><c>cprof</c> is something in between <c>fprof</c> and
- <c>cover</c> regarding features. It counts how many times each
- function is called when the program is run, on a per module
- basis. <c>cprof</c> has a low performance degradation effect (versus
- <c>fprof</c>) and does not need to recompile
- any modules to profile (versus <c>cover</c>).
- See <seealso marker="tools:cprof">cprof</seealso> manual page for additional
- information.
- </p>
+ <c>cover</c> regarding features. It counts how many times each
+ function is called when the program is run, on a per module
+ basis. <c>cprof</c> has a low performance degradation effect
+ (compared with <c>fprof</c>) and does not need to recompile
+ any modules to profile (compared with <c>cover</c>).
+ For more information, see the
+ <seealso marker="tools:cprof">cprof</seealso> manual page in
+ <c>tools</c>.</p>
</section>
<section>
- <title>Tool summarization</title>
+ <title>Tool Summary</title>
<table>
<row>
- <cell align="center" valign="middle">Tool</cell>
- <cell align="center" valign="middle">Results</cell>
- <cell align="center" valign="middle">Size of result</cell>
- <cell align="center" valign="middle">Effects on program execution time</cell>
- <cell align="center" valign="middle">Records number of calls</cell>
- <cell align="center" valign="middle">Records Execution time</cell>
- <cell align="center" valign="middle">Records called by</cell>
- <cell align="center" valign="middle">Records garbage collection</cell>
+ <cell><em>Tool</em></cell>
+ <cell><em>Results</em></cell>
+ <cell><em>Size of Result</em></cell>
+ <cell><em>Effects on Program Execution Time</em></cell>
+ <cell><em>Records Number of Calls</em></cell>
+ <cell><em>Records Execution Time</em></cell>
+ <cell><em>Records Called by</em></cell>
+ <cell><em>Records Garbage Collection</em></cell>
</row>
<row>
- <cell align="left" valign="middle"><c>fprof </c></cell>
- <cell align="left" valign="middle">per process to screen/file </cell>
- <cell align="left" valign="middle">large </cell>
- <cell align="left" valign="middle">significant slowdown </cell>
- <cell align="left" valign="middle">yes </cell>
- <cell align="left" valign="middle">total and own</cell>
- <cell align="left" valign="middle">yes </cell>
- <cell align="left" valign="middle">yes </cell>
+ <cell><c>fprof</c></cell>
+ <cell>Per process to screen/file</cell>
+ <cell>Large</cell>
+ <cell>Significant slowdown</cell>
+ <cell>Yes</cell>
+ <cell>Total and own</cell>
+ <cell>Yes</cell>
+ <cell>Yes</cell>
</row>
<row>
- <cell align="left" valign="middle"><c>eprof </c></cell>
- <cell align="left" valign="middle">per process/function to screen/file </cell>
- <cell align="left" valign="middle">medium </cell>
- <cell align="left" valign="middle">small slowdown </cell>
- <cell align="left" valign="middle">yes </cell>
- <cell align="left" valign="middle">only total </cell>
- <cell align="left" valign="middle">no </cell>
- <cell align="left" valign="middle">no </cell>
+ <cell><c>eprof</c></cell>
+ <cell>Per process/function to screen/file</cell>
+ <cell>Medium</cell>
+ <cell>Small slowdown</cell>
+ <cell>Yes</cell>
+ <cell>Only total</cell>
+ <cell>No</cell>
+ <cell>No</cell>
</row>
<row>
- <cell align="left" valign="middle"><c>cover </c></cell>
- <cell align="left" valign="middle">per module to screen/file</cell>
- <cell align="left" valign="middle">small </cell>
- <cell align="left" valign="middle">moderate slowdown</cell>
- <cell align="left" valign="middle">yes, per line </cell>
- <cell align="left" valign="middle">no </cell>
- <cell align="left" valign="middle">no </cell>
- <cell align="left" valign="middle">no </cell>
+ <cell><c>cover</c></cell>
+ <cell>Per module to screen/file</cell>
+ <cell>Small</cell>
+ <cell>Moderate slowdown</cell>
+ <cell>Yes, per line</cell>
+ <cell>No</cell>
+ <cell>No</cell>
+ <cell>No</cell>
</row>
<row>
- <cell align="left" valign="middle"><c>cprof </c></cell>
- <cell align="left" valign="middle">per module to caller</cell>
- <cell align="left" valign="middle">small </cell>
- <cell align="left" valign="middle">small slowdown </cell>
- <cell align="left" valign="middle">yes </cell>
- <cell align="left" valign="middle">no </cell>
- <cell align="left" valign="middle">no </cell>
- <cell align="left" valign="middle">no </cell>
+ <cell><c>cprof</c></cell>
+ <cell>Per module to caller</cell>
+ <cell>Small</cell>
+ <cell>Small slowdown</cell>
+ <cell>Yes</cell>
+ <cell>No</cell>
+ <cell>No</cell>
+ <cell>No</cell>
</row>
- <tcaption></tcaption>
+ <tcaption>Tool Summary</tcaption>
</table>
</section>
</section>
@@ -226,49 +234,51 @@
implementation of a given algorithm or function is the fastest.
Benchmarking is far from an exact science. Today's operating systems
generally run background tasks that are difficult to turn off.
- Caches and multiple CPU cores doesn't make it any easier.
- It would be best to run Unix-computers in single-user mode when
+ Caches and multiple CPU cores does not facilitate benchmarking.
+ It would be best to run UNIX computers in single-user mode when
benchmarking, but that is inconvenient to say the least for casual
testing.</p>
<p>Benchmarks can measure wall-clock time or CPU time.</p>
- <p><seealso marker="stdlib:timer#tc/3">timer:tc/3</seealso> measures
+ <list type="bulleted">
+ <item><seealso marker="stdlib:timer#tc/3">timer:tc/3</seealso> measures
wall-clock time. The advantage with wall-clock time is that I/O,
- swapping, and other activities in the operating-system kernel are
+ swapping, and other activities in the operating system kernel are
included in the measurements. The disadvantage is that the
- the measurements will vary wildly. Usually it is best to run the
- benchmark several times and note the shortest time - that time should
+ measurements vary a lot. Usually it is best to run the
+ benchmark several times and note the shortest time, which is to
be the minimum time that is possible to achieve under the best of
- circumstances.</p>
+ circumstances.</item>
- <p><seealso marker="erts:erlang#statistics/1">statistics/1</seealso>
- with the argument <c>runtime</c> measures CPU time spent in the Erlang
- virtual machine. The advantage is that the results are more
+ <item><seealso marker="erts:erlang#statistics/1">statistics/1</seealso>
+ with argument <c>runtime</c> measures CPU time spent in the Erlang
+ virtual machine. The advantage with CPU time is that the results are more
consistent from run to run. The disadvantage is that the time
spent in the operating system kernel (such as swapping and I/O)
- are not included. Therefore, measuring CPU time is misleading if
- any I/O (file or socket) is involved.</p>
+ is not included. Therefore, measuring CPU time is misleading if
+ any I/O (file or socket) is involved.</item>
+ </list>
<p>It is probably a good idea to do both wall-clock measurements and
CPU time measurements.</p>
- <p>Some additional advice:</p>
+ <p>Some final advice:</p>
<list type="bulleted">
- <item>The granularity of both types of measurement could be quite
- high so you should make sure that each individual measurement
+ <item>The granularity of both measurement types can be high.
+ Therefore, ensure that each individual measurement
lasts for at least several seconds.</item>
- <item>To make the test fair, each new test run should run in its own,
+ <item>To make the test fair, each new test run is to run in its own,
newly created Erlang process. Otherwise, if all tests run in the
- same process, the later tests would start out with larger heap sizes
- and therefore probably do less garbage collections. You could
- also consider restarting the Erlang emulator between each test.</item>
+ same process, the later tests start out with larger heap sizes
+ and therefore probably do fewer garbage collections.
+ Also consider restarting the Erlang emulator between each test.</item>
<item>Do not assume that the fastest implementation of a given algorithm
- on computer architecture X also is the fastest on computer architecture Y.</item>
-
+ on computer architecture X is also the fastest on computer architecture
+ Y.</item>
</list>
</section>
</chapter>
diff --git a/system/doc/efficiency_guide/tablesDatabases.xml b/system/doc/efficiency_guide/tablesDatabases.xml
index 94c921fa1c..865c46bc33 100644
--- a/system/doc/efficiency_guide/tablesDatabases.xml
+++ b/system/doc/efficiency_guide/tablesDatabases.xml
@@ -8,20 +8,20 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Tables and databases</title>
+ <title>Tables and Databases</title>
<prepared>Ingela Anderton</prepared>
<docno></docno>
<date>2001-08-07</date>
@@ -30,46 +30,45 @@
</header>
<section>
- <title>Ets, Dets and Mnesia</title>
+ <title>Ets, Dets, and Mnesia</title>
<p>Every example using Ets has a corresponding example in
- Mnesia. In general all Ets examples also apply to Dets tables.</p>
+ Mnesia. In general, all Ets examples also apply to Dets tables.</p>
<section>
- <title>Select/Match operations</title>
- <p>Select/Match operations on Ets and Mnesia tables can become
+ <title>Select/Match Operations</title>
+ <p>Select/match operations on Ets and Mnesia tables can become
very expensive operations. They usually need to scan the complete
- table. You should try to structure your
- data so that you minimize the need for select/match
- operations. However, if you really need a select/match operation,
- it will still be more efficient than using <c>tab2list</c>.
- Examples of this and also of ways to avoid select/match will be provided in
- some of the following sections. The functions
- <c>ets:select/2</c> and <c>mnesia:select/3</c> should be preferred over
- <c>ets:match/2</c>,<c>ets:match_object/2</c>, and <c>mnesia:match_object/3</c>.</p>
- <note>
- <p>There are exceptions when the complete table is not
- scanned, for instance if part of the key is bound when searching an
- <c>ordered_set</c> table, or if it is a Mnesia
- table and there is a secondary index on the field that is
- selected/matched. If the key is fully bound there will, of course, be
- no point in doing a select/match, unless you have a bag table and
- you are only interested in a sub-set of the elements with
- the specific key.</p>
- </note>
- <p>When creating a record to be used in a select/match operation you
- want most of the fields to have the value '_'. The easiest and fastest way
- to do that is as follows:</p>
+ table. Try to structure the data to minimize the need for select/match
+ operations. However, if you require a select/match operation,
+ it is still more efficient than using <c>tab2list</c>.
+ Examples of this and of how to avoid select/match are provided in
+ the following sections. The functions
+ <c>ets:select/2</c> and <c>mnesia:select/3</c> are to be preferred
+ over <c>ets:match/2</c>, <c>ets:match_object/2</c>, and
+ <c>mnesia:match_object/3</c>.</p>
+ <p>In some circumstances, the select/match operations do not need
+ to scan the complete table.
+ For example, if part of the key is bound when searching an
+ <c>ordered_set</c> table, or if it is a Mnesia
+ table and there is a secondary index on the field that is
+ selected/matched. If the key is fully bound, there is
+ no point in doing a select/match, unless you have a bag table
+ and are only interested in a subset of the elements with
+ the specific key.</p>
+ <p>When creating a record to be used in a select/match operation, you
+ want most of the fields to have the value "_". The easiest and
+ fastest way to do that is as follows:</p>
<pre>
#person{age = 42, _ = '_'}. </pre>
</section>
<section>
- <title>Deleting an element</title>
- <p>The delete operation is considered
+ <title>Deleting an Element</title>
+ <p>The <c>delete</c> operation is considered
successful if the element was not present in the table. Hence
all attempts to check that the element is present in the
Ets/Mnesia table before deletion are unnecessary. Here follows
- an example for Ets tables.</p>
+ an example for Ets tables:</p>
<p><em>DO</em></p>
<pre>
...
@@ -88,14 +87,16 @@ end,
</section>
<section>
- <title>Data fetching</title>
- <p>Do not fetch data that you already have! Consider that you
- have a module that handles the abstract data type Person. You
- export the interface function <c>print_person/1</c> that uses the internal functions
- <c>print_name/1</c>, <c>print_age/1</c>, <c>print_occupation/1</c>.</p>
+ <title>Fetching Data</title>
+ <p>Do not fetch data that you already have.</p>
+ <p>Consider that you have a module that handles the abstract data
+ type <c>Person</c>. You export the interface function
+ <c>print_person/1</c>, which uses the internal functions
+ <c>print_name/1</c>, <c>print_age/1</c>, and
+ <c>print_occupation/1</c>.</p>
<note>
- <p>If the functions <c>print_name/1</c> and so on, had been interface
- functions the matter comes in to a whole new light, as you
+ <p>If the function <c>print_name/1</c>, and so on, had been interface
+ functions, the situation would have been different, as you
do not want the user of the interface to know about the
internal data representation. </p>
</note>
@@ -136,7 +137,7 @@ print_person(PersonId) ->
io:format("No person with ID = ~p~n", [PersonID])
end.
-%%% Internal functions
+%%% Internal functionss
print_name(PersonID) ->
[Person] = ets:lookup(person, PersonId),
io:format("No person ~p~n", [Person#person.name]).
@@ -151,31 +152,31 @@ print_occupation(PersonID) ->
</section>
<section>
- <title>Non-persistent data storage </title>
+ <title>Non-Persistent Database Storage</title>
<p>For non-persistent database storage, prefer Ets tables over
- Mnesia local_content tables. Even the Mnesia <c>dirty_write</c>
+ Mnesia <c>local_content</c> tables. Even the Mnesia <c>dirty_write</c>
operations carry a fixed overhead compared to Ets writes.
Mnesia must check if the table is replicated or has indices,
this involves at least one Ets lookup for each
- <c>dirty_write</c>. Thus, Ets writes will always be faster than
+ <c>dirty_write</c>. Thus, Ets writes is always faster than
Mnesia writes.</p>
</section>
<section>
<title>tab2list</title>
- <p>Assume we have an Ets-table, which uses <c>idno</c> as key,
- and contains:</p>
+ <p>Assuming an Ets table that uses <c>idno</c> as key
+ and contains the following:</p>
<pre>
[#person{idno = 1, name = "Adam", age = 31, occupation = "mailman"},
#person{idno = 2, name = "Bryan", age = 31, occupation = "cashier"},
#person{idno = 3, name = "Bryan", age = 35, occupation = "banker"},
#person{idno = 4, name = "Carl", age = 25, occupation = "mailman"}]</pre>
- <p>If we <em>must</em> return all data stored in the Ets-table we
- can use <c>ets:tab2list/1</c>. However, usually we are only
+ <p>If you <em>must</em> return all data stored in the Ets table, you
+ can use <c>ets:tab2list/1</c>. However, usually you are only
interested in a subset of the information in which case
- <c>ets:tab2list/1</c> is expensive. If we only want to extract
- one field from each record, e.g., the age of every person, we
- should use:</p>
+ <c>ets:tab2list/1</c> is expensive. If you only want to extract
+ one field from each record, for example, the age of every person,
+ then:</p>
<p><em>DO</em></p>
<pre>
...
@@ -192,8 +193,8 @@ ets:select(Tab,[{ #person{idno='_',
TabList = ets:tab2list(Tab),
lists:map(fun(X) -> X#person.age end, TabList),
...</pre>
- <p>If we are only interested in the age of all persons named
- Bryan, we should:</p>
+ <p>If you are only interested in the age of all persons named
+ "Bryan", then:</p>
<p><em>DO</em></p>
<pre>
...
@@ -224,8 +225,8 @@ BryanList = lists:filter(fun(X) -> X#person.name == "Bryan" end,
TabList),
lists:map(fun(X) -> X#person.age end, BryanList),
...</pre>
- <p>If we need all information stored in the Ets table about
- persons named Bryan we should:</p>
+ <p>If you need all information stored in the Ets table about
+ persons named "Bryan", then:</p>
<p><em>DO</em></p>
<pre>
...
@@ -243,60 +244,60 @@ lists:filter(fun(X) -> X#person.name == "Bryan" end, TabList),
</section>
<section>
- <title>Ordered_set tables</title>
- <p>If the data in the table should be accessed so that the order
+ <title>Ordered_set Tables</title>
+ <p>If the data in the table is to be accessed so that the order
of the keys in the table is significant, the table type
- <c>ordered_set</c> could be used instead of the more usual
+ <c>ordered_set</c> can be used instead of the more usual
<c>set</c> table type. An <c>ordered_set</c> is always
- traversed in Erlang term order with regard to the key field
- so that return values from functions such as <c>select</c>,
+ traversed in Erlang term order regarding the key field
+ so that the return values from functions such as <c>select</c>,
<c>match_object</c>, and <c>foldl</c> are ordered by the key
values. Traversing an <c>ordered_set</c> with the <c>first</c> and
<c>next</c> operations also returns the keys ordered.</p>
<note>
<p>An <c>ordered_set</c> only guarantees that
- objects are processed in <em>key</em> order. Results from functions as
- <c>ets:select/2</c> appear in the <em>key</em> order even if
+ objects are processed in <em>key</em> order.
+ Results from functions such as
+ <c>ets:select/2</c> appear in <em>key</em> order even if
the key is not included in the result.</p>
</note>
</section>
</section>
<section>
- <title>Ets specific</title>
+ <title>Ets-Specific</title>
<section>
- <title>Utilizing the keys of the Ets table</title>
- <p>An Ets table is a single key table (either a hash table or a
- tree ordered by the key) and should be used as one. In other
+ <title>Using Keys of Ets Table</title>
+ <p>An Ets table is a single-key table (either a hash table or a
+ tree ordered by the key) and is to be used as one. In other
words, use the key to look up things whenever possible. A
- lookup by a known key in a set Ets table is constant and for a
- ordered_set Ets table it is O(logN). A key lookup is always
+ lookup by a known key in a <c>set</c> Ets table is constant and for
+ an <c>ordered_set</c> Ets table it is O(logN). A key lookup is always
preferable to a call where the whole table has to be
- scanned. In the examples above, the field <c>idno</c> is the
+ scanned. In the previous examples, the field <c>idno</c> is the
key of the table and all lookups where only the name is known
- will result in a complete scan of the (possibly large) table
+ result in a complete scan of the (possibly large) table
for a matching result.</p>
<p>A simple solution would be to use the <c>name</c> field as
the key instead of the <c>idno</c> field, but that would cause
- problems if the names were not unique. A more general solution
- would be to create a second table with <c>name</c> as key and
- <c>idno</c> as data, i.e. to index (invert) the table with regards
- to the <c>name</c> field. The second table would of course have to be
- kept consistent with the master table. Mnesia could do this
- for you, but a home brew index table could be very efficient
+ problems if the names were not unique. A more general solution would
+ be to create a second table with <c>name</c> as key and
+ <c>idno</c> as data, that is, to index (invert) the table regarding
+ the <c>name</c> field. Clearly, the second table would have to be
+ kept consistent with the master table. Mnesia can do this
+ for you, but a home brew index table can be very efficient
compared to the overhead involved in using Mnesia.</p>
<p>An index table for the table in the previous examples would
- have to be a bag (as keys would appear more than once) and could
+ have to be a bag (as keys would appear more than once) and can
have the following contents:</p>
<pre>
-
[#index_entry{name="Adam", idno=1},
#index_entry{name="Bryan", idno=2},
#index_entry{name="Bryan", idno=3},
#index_entry{name="Carl", idno=4}]</pre>
- <p>Given this index table a lookup of the <c>age</c> fields for
- all persons named "Bryan" could be done like this:</p>
+ <p>Given this index table, a lookup of the <c>age</c> fields for
+ all persons named "Bryan" can be done as follows:</p>
<pre>
...
MatchingIDs = ets:lookup(IndexTable,"Bryan"),
@@ -306,30 +307,31 @@ lists:map(fun(#index_entry{idno = ID}) ->
end,
MatchingIDs),
...</pre>
- <p>Note that the code above never uses <c>ets:match/2</c> but
- instead utilizes the <c>ets:lookup/2</c> call. The
+ <p>Notice that this code never uses <c>ets:match/2</c> but
+ instead uses the <c>ets:lookup/2</c> call. The
<c>lists:map/2</c> call is only used to traverse the <c>idno</c>s
- matching the name "Bryan" in the table; therefore the number of lookups
+ matching the name "Bryan" in the table; thus the number of lookups
in the master table is minimized.</p>
<p>Keeping an index table introduces some overhead when
- inserting records in the table, therefore the number of operations
- gained from the table has to be weighted against the number of
- operations inserting objects in the table. However, note that the gain when
- the key can be used to lookup elements is significant.</p>
+ inserting records in the table. The number of operations gained
+ from the table must therefore be compared against the number of
+ operations inserting objects in the table. However, notice that the
+ gain is significant when the key can be used to lookup elements.</p>
</section>
</section>
<section>
- <title>Mnesia specific</title>
+ <title>Mnesia-Specific</title>
<section>
- <title>Secondary index</title>
+ <title>Secondary Index</title>
<p>If you frequently do a lookup on a field that is not the
- key of the table, you will lose performance using
- "mnesia:select/match_object" as this function will traverse the
- whole table. You may create a secondary index instead and
+ key of the table, you lose performance using
+ "mnesia:select/match_object" as this function traverses the
+ whole table. You can create a secondary index instead and
use "mnesia:index_read" to get faster access, however this
- will require more memory. Example:</p>
+ requires more memory.</p>
+ <p><em>Example</em></p>
<pre>
-record(person, {idno, name, age, occupation}).
...
@@ -347,14 +349,15 @@ PersonsAge42 =
<section>
<title>Transactions </title>
- <p>Transactions is a way to guarantee that the distributed
+ <p>Using transactions is a way to guarantee that the distributed
Mnesia database remains consistent, even when many different
- processes update it in parallel. However if you have
- real time requirements it is recommended to use dirty
- operations instead of transactions. When using the dirty
- operations you lose the consistency guarantee, this is usually
+ processes update it in parallel. However, if you have
+ real-time requirements it is recommended to use <c>dirty</c>
+ operations instead of transactions. When using <c>dirty</c>
+ operations, you lose the consistency guarantee; this is usually
solved by only letting one process update the table. Other
- processes have to send update requests to that process.</p>
+ processes must send update requests to that process.</p>
+ <p><em>Example</em></p>
<pre>
...
% Using transaction
diff --git a/system/doc/efficiency_guide/xmlfiles.mk b/system/doc/efficiency_guide/xmlfiles.mk
index fa2fe44eec..e3373d545a 100644
--- a/system/doc/efficiency_guide/xmlfiles.mk
+++ b/system/doc/efficiency_guide/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/embedded/Makefile b/system/doc/embedded/Makefile
index 95d34957bf..c09816564c 100644
--- a/system/doc/embedded/Makefile
+++ b/system/doc/embedded/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/embedded/book.xml b/system/doc/embedded/book.xml
index 3fc00b58ae..5a414152d0 100644
--- a/system/doc/embedded/book.xml
+++ b/system/doc/embedded/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/embedded/embedded_nt.xml b/system/doc/embedded/embedded_nt.xml
index 530e3663e4..b35a5edf36 100644
--- a/system/doc/embedded/embedded_nt.xml
+++ b/system/doc/embedded/embedded_nt.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,54 +32,47 @@
<rev>PA2</rev>
<file>embedded_nt.xml</file>
</header>
- <p>This chapter describes the OS specific parts of OTP which relate
- to Windows NT.
- </p>
-
- <section>
- <title>Introduction</title>
- <p>A normal installation of NT 4.0, with service pack 4 or later,
- is required for an embedded Windows NT running OTP.</p>
- </section>
+ <marker id="windows nt"></marker>
+ <p>This section describes the operating system-specific parts of OTP
+ that relate to Windows NT.</p>
+ <p>A normal installation of Windows NT 4.0, with Service Pack 4 or
+ later, is required for an embedded Windows NT running OTP.</p>
<section>
- <title>Memory Usage</title>
- <p>RAM memory of 96 MBytes is recommended to run OTP on NT.
- A system with less than 64 Mbytes of RAM is not recommended.</p>
+ <title>Memory Use</title>
+ <p>RAM memory of 96 MB is recommended to run OTP on Windows NT.
+ A system with less than 64 MB of RAM is not recommended.</p>
</section>
<section>
- <title>Disk Space Usage</title>
- <p>A minimum NT installation with networking needs 250 MB, and
- an additional 130 MB for the swap file. </p>
+ <title>Disk Space Use</title>
+ <p>A minimum Windows NT installation with networking needs 250 MB,
+ and an extra 130 MB for the swap file.</p>
</section>
<section>
- <title>Installation</title>
- <p>Normal NT installation is performed. No additional application
- programs are needed, such as Internet explorer or web server. Networking
- with TCP/IP is required. <br></br>
-
- Service pack 4 or later must be installed.</p>
+ <title>Installing an Embedded System</title>
+ <p>Normal Windows NT installation is performed. No additional
+ application programs are needed, such as Internet Explorer or
+ web server. Networking with TCP/IP is required.</p>
+ <p>Service Pack 4 or later must be installed.</p>
<section>
<title>Hardware Watchdog</title>
- <p>For Windows NT running on standard PCs with ISA and/or PCI bus
- there is a possibility to install an extension card with a hardware
- watchdog.
- </p>
- <p>See also the <c>heart(3)</c> reference manual page in
- <em>Kernel</em>.
- </p>
+ <p>For Windows NT running on standard PCs with ISA and/or PCI bus,
+ an extension card with a hardware watchdog can be installed.</p>
+ <p>For more information, see the <c>heart(3)</c> manual page in
+ <c>kernel</c>.</p>
</section>
</section>
<section>
<title>Starting Erlang</title>
- <p>On an embedded system, the <c>erlsrv</c> module should be used,
- to install the erlang process as a Windows system service.
- This service can start
- after NT has booted. See documentation for <c>erlsrv</c>.</p>
+ <p>On an embedded system, the <c>erlsrv</c> module is to be used
+ to install the Erlang process as a Windows system service.
+ This service can start after Windows NT has booted.</p>
+ <p>For more information, see the <c>erlsrv</c> manual page
+ in <c>erts</c>.</p>
</section>
</chapter>
diff --git a/system/doc/embedded/embedded_solaris.xml b/system/doc/embedded/embedded_solaris.xml
index cab3437725..ade5ad344e 100644
--- a/system/doc/embedded/embedded_solaris.xml
+++ b/system/doc/embedded/embedded_solaris.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,125 +32,97 @@
<rev>B</rev>
<file>embedded_solaris.xml</file>
</header>
- <p>This chapter describes the OS specific parts of OTP which relate
- to Solaris.
- </p>
+ <marker id="embedded solaris"></marker>
+
+ <p>This section describes the operating system-specific parts
+ of OTP that relate to Solaris.</p>
<section>
- <title>Memory Usage</title>
- <p>Solaris takes about 17 Mbyte of RAM on a system with 64 Mbyte of
- total RAM. This leaves about 47 Mbyte for the applications. If
- the system utilizes swapping, these figures cannot be improved
+ <title>Memory Use</title>
+ <p>Solaris takes about 17 MB of RAM on a system with 64 MB of
+ total RAM. This leaves about 47 MB for the applications. If
+ the system uses swapping, these figures cannot be improved
because unnecessary daemon processes are swapped out. However,
if swapping is disabled, or if the swap space is of limited
resource in the system, it becomes necessary to kill off
- unnecessary daemon processes.
- </p>
+ unnecessary daemon processes.</p>
</section>
<section>
- <title>Disk Space Usage</title>
+ <title>Disk Space Use</title>
<p>The disk space required by Solaris can be minimized by using the
- Core User support installation. It requires about 80 Mbyte of
+ Core User support installation. It requires about 80 MB of
disk space. This installs only the minimum software required to
- boot and run Solaris. The disk space can be further reduced by
+ boot and run Solaris. The disk space can be further reduced by
deleting unnecessary individual files. However, unless disk
space is a critical resource the effort required and the risks
- involved may not be justified.</p>
+ involved cannot be justified.</p>
</section>
<section>
- <title>Installation</title>
+ <title>Installing an Embedded System</title>
<p>This section is about installing an embedded system.
- The following topics are considered,
- </p>
+ The following topics are considered:
+ </p>
<list type="bulleted">
- <item>
- <p>Creation of user and installation directory,</p>
- </item>
- <item>
- <p>Installation of embedded system,</p>
- </item>
- <item>
- <p>Configuration for automatic start at reboot,</p>
- </item>
- <item>
- <p>Making a hardware watchdog available,</p>
- </item>
- <item>
- <p>Changing permission for reboot,</p>
- </item>
- <item>
- <p>Patches,</p>
- </item>
- <item>
- <p>Configuration of the OS_Mon application.</p>
- </item>
+ <item>Creating user and installation directory</item>
+ <item>Installing an embedded system</item>
+ <item>Configuring automatic start at boot</item>
+ <item>Making a hardware watchdog available</item>
+ <item>Changing permission for reboot</item>
+ <item>Setting TERM environment variable</item>
+ <item>Adding patches</item>
+ <item>Installing module os_sup in application os_mon</item>
</list>
- <p>Several of the procedures described below require expert
- knowledge of the Solaris 2 operating system. For most of them
- super user privilege is needed.
- </p>
+ <p>Several of the procedures in this section require expert
+ knowledge of the Solaris operating system. For most of them
+ super user privilege is needed.</p>
<section>
- <title>Creation of User and Installation Directory</title>
- <p>It is recommended that the Embedded Environment is run by an
- ordinary user, i.e. a user who does not have super user
- privileges.
- </p>
- <p>Throughout this section we assume that the user name is
- <c>otpuser</c>, and that the home directory of that user is,
- </p>
+ <title>Creating User and Installation Directory</title>
+ <p>It is recommended that the embedded environment is run by an
+ ordinary user, that is, a user who does not have super user
+ privileges.</p>
+ <p>In this section, it is assumed that the username is
+ <c>otpuser</c> and that the home directory of that user is:</p>
<pre>
/export/home/otpuser</pre>
- <p>Furthermore, we assume that in the home directory of
+ <p>It is also assumed that in the home directory of
<c>otpuser</c>, there is a directory named <c>otp</c>, the
- full path of which is,
- </p>
+ full path of which is:</p>
<pre>
/export/home/otpuser/otp</pre>
<p>This directory is the <em>installation directory</em> of the
- Embedded Environment.
- </p>
+ embedded environment.</p>
</section>
<section>
- <title>Installation of an Embedded System</title>
- <p>The procedure for installation of an embedded system does
- not differ from that of an ordinary system (see the
- <em>Installation Guide</em>),
- except for the following:
- </p>
+ <title>Installing an Embedded System</title>
+ <p>The procedure for installing an embedded system
+ is the same as for an ordinary system (see
+ Installation Guide), except for the following:</p>
<list type="bulleted">
- <item>
- <p>the (compressed) tape archive file should be
- extracted in the installation directory as defined above,
- and,</p>
- </item>
- <item>
- <p>there is no need to link the start script to a
- standard directory like <c>/usr/local/bin</c>.</p>
- </item>
+ <item>The (compressed) tape archive file is to be extracted in
+ the installation directory defined above.</item>
+ <item>It is not needed to link the start script to a standard
+ directory like <c>/usr/local/bin</c>.</item>
</list>
</section>
<section>
- <title>Configuration for Automatic Start at Boot</title>
- <p>A true embedded system has to start when the system
- boots. This section accounts for the necessary configurations
- needed to achieve that.
- </p>
- <p>The embedded system and all the applications will start
- automatically if the script file shown below is added to the
- <c>/etc/rc3.d</c> directory. The file must be owned and
- readable by <c>root</c>, and its name cannot be arbitrarily
- assigned. The following name is recommended,
- </p>
+ <title>Configuring Automatic Start at Boot</title>
+ <p>A true embedded system must start when the system boots.
+ This section accounts for the necessary configurations
+ needed to achieve that.</p>
+ <p>The embedded system and all the applications start
+ automatically if the script file shown below is added to
+ directory <c>/etc/rc3.d</c>. The file must be owned and
+ readable by <c>root</c>. Its name cannot be arbitrarily
+ assigned; the following name is recommended:</p>
<pre>
S75otp.system</pre>
- <p>For further details on initialization (and termination)
- scripts, and naming thereof, see the Solaris documentation.
- </p>
+ <p>For more details on initialization (and termination)
+ scripts, and naming thereof, see the Solaris documentation.</p>
<pre>
#!/bin/sh
#
@@ -187,386 +160,333 @@ case "$1" in
echo "Usage: $0 { start | stop }"
;;
esac</pre>
- <p>The file <c>/export/home/otpuser/otp/bin/start</c> referred to
- in the above script, is precisely the script <c>start</c>
- described in the section <em>Starting Erlang</em> below. The
+ <p>File <c>/export/home/otpuser/otp/bin/start</c> referred to
+ in the above script is precisely the <c>start</c> script
+ described in <em>Starting Erlang</em>. The
script variable <c>OTP_ROOT</c> in that <c>start</c> script
- corresponds to the example path
- </p>
+ corresponds to the following example path used in this
+ section:</p>
<pre>
/export/home/otpuser/otp</pre>
- <p>used in this section. The <c>start</c> script should be edited
- accordingly.
- </p>
- <p>Use of the <c>killproc</c> procedure in the above script could
- be combined with a call to <c>erl_call</c>, e.g.
- </p>
+ <p>The <c>start</c> script is to be edited accordingly.</p>
+ <p>Use of the <c>killproc</c> procedure in the above script can
+ be combined with a call to <c>erl_call</c>, for example:</p>
<pre>
$SOME_PATH/erl_call -n Node init stop</pre>
- <p>In order to take Erlang down gracefully see the
- <c>erl_call(1)</c> reference manual page for further details
- on the use of <c>erl_call</c>. That however requires that
- Erlang runs as a distributed node which is not always the
- case.
- </p>
- <p>The <c>killproc</c> procedure should not be removed: the
+ <p>To take Erlang down gracefully, see the <c>erl_call(1)</c>
+ manual page in <c>erl_interface</c> for details on the use
+ of <c>erl_call</c>. However,
+ that requires that Erlang runs as a distributed node, which is
+ not always the case.</p>
+ <p>The <c>killproc</c> procedure is not to be removed. The
purpose is here to move from run level 3 (multi-user mode with
networking resources) to run level 2 (multi-user mode without
- such resources), in which Erlang should not run.
- </p>
+ such resources), in which Erlang is not to run.</p>
</section>
<section>
- <title>Hardware Watchdog</title>
+ <title>Making Hardware Watchdog Available</title>
<p>For Solaris running on VME boards from Force Computers,
- there is a possibility to activate the onboard hardware
- watchdog, provided a VME bus driver is added to the operating
- system (see also <em>Installation Problems</em> below).
- </p>
- <p>See also the <c>heart(3)</c> reference manual page in
- <em>Kernel</em>.
- </p>
+ the onboard hardware watchdog can be activated,
+ provided a VME bus driver is added to the operating system
+ (see also Installation Problems).</p>
+ <p>See also the <c>heart(3)</c> manual page in <c>kernel</c>.</p>
</section>
<section>
<title>Changing Permissions for Reboot</title>
<p>If the <c>HEART_COMMAND</c> environment variable is to be set
- in the <c>start</c> script in the section, <em>Starting Erlang</em>, and if the value shall be set to the
- path of the Solaris <c>reboot</c> command, i.e.
- </p>
+ in the <c>start</c> script in
+ <em>Starting Erlang</em>, and if the value is to be set to the
+ path of the Solaris <c>reboot</c> command, that is:</p>
<pre>
HEART_COMMAND=/usr/sbin/reboot</pre>
- <p>the ownership and file permissions for <c>/usr/sbin/reboot</c>
- must be changed as follows,
- </p>
+ <p>then the ownership and file permissions for
+ <c>/usr/sbin/reboot</c> must be changed as follows:</p>
<pre>
chown 0 /usr/sbin/reboot
chmod 4755 /usr/sbin/reboot</pre>
- <p>See also the <c>heart(3)</c> reference manual page in
- <em>Kernel</em>.
- </p>
+ <p>See also the <c>heart(3)</c> manual page in <c>kernel</c>.</p>
</section>
<section>
- <title>The TERM Environment Variable</title>
- <p>When the Erlang runtime system is automatically started from the
- <c>S75otp.system</c> script the <c>TERM</c> environment
- variable has to be set. The following is a minimal setting,
- </p>
+ <title>Setting TERM Environment Variable</title>
+ <p>When the Erlang runtime system is automatically started from
+ the <c>S75otp.system</c> script, the <c>TERM</c> environment
+ variable must be set. The following is a minimal setting:</p>
<pre>
TERM=sun</pre>
- <p>which should be added to the <c>start</c> script described in
- the section.
- </p>
+ <p>This is to be added to the <c>start</c> script.</p>
</section>
<section>
- <title>Patches</title>
+ <title>Adding Patches</title>
<p>For proper functioning of flushing file system data to disk on
- Solaris 2.5.1, the version specific patch with number
- 103640-02 must be added to the operating system. There may be
- other patches needed, see the release README file
- <c><![CDATA[<ERL_INSTALL_DIR>/README]]></c>.
- </p>
+ Solaris 2.5.1, the version-specific patch with number
+ 103640-02 must be added to the operating system. Other
+ patches might be needed, see the release README file
+ <c><![CDATA[<ERL_INSTALL_DIR>/README]]></c>.</p>
</section>
<section>
- <title>Installation of Module os_sup in Application OS_Mon</title>
+ <title>Installing Module os_sup in Application os_mon</title>
<p>The following four installation procedures require super user
- privilege.
- </p>
-
- <section>
- <title>Installation</title>
- <list type="ordered">
- <item>
- <p><em>Make a copy the Solaris standard configuration file for syslogd.</em></p>
- <list type="bulleted">
- <item>
- <p>Make a copy the Solaris standard configuration
- file for syslogd. This file is usually named
- <c>syslog.conf</c> and found in the <c>/etc</c>
- directory.</p>
- </item>
- <item>
- <p>The file name of the copy must be
- <c>syslog.conf.ORIG</c> but the directory location
- is optional. Usually it is <c>/etc</c>.
- </p>
- <p>A simple way to do this is to issue the command</p>
- <code type="none">
+ privilege:</p>
+
+ <section>
+ <title>Installation</title>
+ <list type="bulleted">
+ <item><em>Make a copy of the Solaris standard configuration
+ file for <c>syslogd</c>:</em>
+ <list type="bulleted">
+ <item>Make a copy of the Solaris standard configuration
+ file for <c>syslogd</c>. This file is usually named
+ <c>syslog.conf</c> and found in directory <c>/etc</c>.</item>
+ <item>The filename of the copy must be <c>syslog.conf.ORIG</c>.
+ The directory location is optional; usually it is <c>/etc</c>.
+ A simple way to do this is to issue the following command:
+ <code type="none">
cp /etc/syslog.conf /etc/syslog.conf.ORIG</code>
</item>
- </list>
- </item>
- <item>
- <p><em>Make an Erlang specific configuration file for syslogd.</em></p>
- <list type="bulleted">
- <item>
- <p>Make an edited copy of the back-up copy previously
- made.</p>
- </item>
- <item>
- <p>The file name must be <c>syslog.conf.OTP</c> and the
- path must be the same as the back-up copy.</p>
- </item>
- <item>
- <p>The format of the configuration file is found in the
- man page for <c>syslog.conf(5)</c>, by issuing the
- command <c>man syslog.conf</c>.</p>
- </item>
- <item>
- <p>Usually a line is added which should state:</p>
- <list type="bulleted">
- <item>
- <p>which types of information that will be
- supervised by Erlang,</p>
- </item>
- <item>
- <p>the name of the file (actually a named pipe)
- that should receive the information.</p>
- </item>
- </list>
- </item>
- <item>
- <p>If e.g. only information originating from the
- unix-kernel should be supervised, the line should
- begin with <c>kern.LEVEL</c> (for the possible
- values of <c>LEVEL</c> see <c>syslog.conf(5)</c>).</p>
- </item>
- <item>
- <p>After at least one tab-character, the line added
- should contain the full name of the named pipe where
- syslogd writes its information. The path must be the
- same as for the <c>syslog.conf.ORIG</c> and
- <c>syslog.conf.OTP</c> files. The file name must be
- <c>syslog.otp</c>.</p>
- </item>
- <item>
- <p>If the directory for the <c>syslog.conf.ORIG</c> and
- <c>syslog.conf.OTP</c> files is <c>/etc</c> the line
- in <c>syslog.conf.OTP</c> will look like:</p>
- <code type="none">
+ </list>
+ </item>
+ <item><em>Make an Erlang-specific configuration file for
+ <c>syslogd</c>:</em>
+ <list type="bulleted">
+ <item>Make an edited copy of the backup copy previously
+ made.</item>
+ <item>The filename must be <c>syslog.conf.OTP</c>. The
+ path must be the same as the backup copy.</item>
+ <item>The format of the configuration file is found in the
+ <c>syslog.conf(5)</c> manual page, by issuing the command
+ <c>man syslog.conf</c>.</item>
+ <item>Usually a line is added that is to state:
+ <list type="bulleted">
+ <item>Which types of information that is to be
+ supervised by Erlang</item>
+ <item>The name of the file (actually a named pipe) that
+ is to receive the information</item>
+ </list>
+ </item>
+ <item>If, for example, only information originating from
+ the UNIX kernel is to be supervised, the line is to
+ begin with <c>kern.LEVEL</c>. For the possible
+ values of <c>LEVEL</c>, see <c>syslog.conf(5)</c>.</item>
+ <item>After at least one tab-character, the line added is to
+ contain the full name of the named pipe where <c>syslogd</c>
+ writes its information. The path must be the same as for the
+ files <c>syslog.conf.ORIG</c> and <c>syslog.conf.OTP</c>.
+ The filename must be <c>syslog.otp</c>.</item>
+ <item>If the directory for the files <c>syslog.conf.ORIG</c>
+ and <c>syslog.conf.OTP</c> is <c>/etc</c>, the line in
+ <c>syslog.conf.OTP</c> is as follows:
+ <code type="none">
kern.LEVEL /etc/syslog.otp</code>
- </item>
- </list>
- </item>
- <item>
- <p><em>Check the file privileges of the configuration files.</em></p>
- <list type="bulleted">
- <item>
- <p>The configuration files should have <c>rw-r--r--</c>
- file privileges and be owned by root.</p>
- </item>
- <item>
- <p>A simple way to do this is to issue the commands</p>
- <code type="none">
+ </item>
+ </list>
+ </item>
+ <item><em>Check the file privileges of the configuration
+ files:</em>
+ <list type="bulleted">
+ <item>The configuration files is to have <c>rw-r--r--</c>
+ file privileges and be owned by root.</item>
+ <item>A simple way to do this is to issue these commands:
+ <code type="none">
chmod 644 /etc/syslog.conf
chmod 644 /etc/syslog.conf.ORIG
chmod 644 /etc/syslog.conf.OTP</code>
- </item>
- <item>
- <p><em>Note:</em> If the <c>syslog.conf.ORIG</c> and
- <c>syslog.conf.OTP</c> files are not in the
- <c>/etc</c> directory, the file path in the second
- and third command must be modified.</p>
- </item>
- </list>
- </item>
- <item>
- <p><em>Modify file privileges and ownership of the mod_syslog utility.</em></p>
- <list type="bulleted">
- <item>
- <p>The file privileges and ownership of the
- <c>mod_syslog</c> utility must be modified.</p>
- </item>
- <item>
- <p>The full name of the binary executable file is
- derived from the position of the <c>os_mon</c>
- application if the file system by adding
- <c>/priv/bin/mod_syslog</c>. The generic full name
- of the binary executable file is thus</p>
- <code type="none"><![CDATA[
+ </item>
+ <item>Notice that if the files <c>syslog.conf.ORIG</c> and
+ <c>syslog.conf.OTP</c> are not in directory <c>/etc</c>,
+ the file path in the second and third command must be
+ modified.</item>
+ </list>
+ </item>
+ <item><em>Modify file privileges and ownership of the
+ <c>mod_syslog</c> utility:</em>
+ <list type="bulleted">
+ <item>The file privileges and ownership of the
+ <c>mod_syslog</c> utility must be modified.</item>
+ <item><p>The full name of the binary executable file is
+ derived from the position of application <c>os_mon</c>
+ in the file system by adding
+ <c>/priv/bin/mod_syslog</c>. The generic full name
+ of the binary executable file is thus:</p>
+ <code type="none"><![CDATA[
<OTP_ROOT>/lib/os_mon-<REV>/priv/bin/mod_syslog]]></code>
- <p><em>Example:</em> If the path to the otp-root is
- <c>/usr/otp</c>, thus the path to the <c>os_mon</c>
- application is <c>/usr/otp/lib/os_mon-1.0</c>
- (assuming revision 1.0) and the full name of the
- binary executable file is
- <c>/usr/otp/lib/os_mon-1.0/priv/bin/mod_syslog</c>.</p>
- </item>
- <item>
- <p>The binary executable file must be owned by root,
- have <c>rwsr-xr-x</c> file privileges, in particular
- the setuid bit of user must be set.
- </p>
- </item>
- <item>
- <p>A simple way to do this is to issue the commands</p>
- <code type="none"><![CDATA[
+ <p><em>Example:</em> If the path to <c>otp-root</c> is
+ <c>/usr/otp</c>, then the path to the <c>os_mon</c>
+ application is <c>/usr/otp/lib/os_mon-1.0</c>
+ (assuming revision 1.0) and the full name of the
+ binary executable file is
+ <c>/usr/otp/lib/os_mon-1.0/priv/bin/mod_syslog</c>.</p>
+ </item>
+ <item>The binary executable file must be owned by root,
+ have <c>rwsr-xr-x</c> file privileges, in particular
+ the <c>setuid</c> bit of the user must be set.</item>
+ <item><p>A simple way to do this is to issue the following
+ commands:</p>
+ <code type="none"><![CDATA[
cd <OTP_ROOT>/lib/os_mon-<REV>/priv/bin/mod_syslog
chmod 4755 mod_syslog
chown root mod_syslog]]></code>
- </item>
- </list>
- </item>
- </list>
- </section>
-
- <section>
- <title>Testing the Application Configuration File</title>
- <p>The following procedure does not require root privilege.
- </p>
- <list type="bulleted">
- <item>
- <p>Ensure that the configuration parameters for the
- <c>os_sup</c> module in the <c>os_mon</c> application
- are correct.</p>
- </item>
- <item>
- <p>Browse the application configuration file (do
- <em>not</em> edit it). The full name of the application
- configuration file is derived from the position of the
- OS_Mon application if the file system by adding
- <c>/ebin/os_mon.app</c>.
- </p>
- <p>The generic full name of the file is thus</p>
- <code type="none"><![CDATA[
+ </item>
+ </list>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Testing the Application Configuration File</title>
+ <p>The following procedure does not require root privilege:</p>
+ <list type="bulleted">
+ <item>Ensure that the configuration parameters for the
+ <c>os_sup</c> module in the <c>os_mon</c> application
+ are correct.</item>
+ <item><p>Browse the application configuration file (do
+ <em>not</em> edit it). The full name of the application
+ configuration file is derived from the position of the
+ <c>os_mon</c> application in the file system by adding
+ <c>/ebin/os_mon.app</c>.</p>
+ <p>The generic full name of the file is thus:</p>
+ <code type="none"><![CDATA[
<OTP_ROOT>/lib/os_mon-<REV>/ebin/os_mon.app.]]></code>
- <p><em>Example:</em> If the path to the otp-root is
- <c>/usr/otp</c>, thus the path to the <c>os_mon</c>
- application is <c>/usr/otp/lib/os_mon-1.0 </c> (assuming
- revision 1.0) and the full name of the binary executable
- file is <c>/usr/otp/lib/os_mon-1.0/ebin/os_mon.app</c>.</p>
- </item>
- <item>
- <p>Ensure that the following configuration parameters are
- bound to the correct values.</p>
- </item>
+ <p><em>Example:</em> If the path to <c>otp-root</c> is
+ <c>/usr/otp</c>, then the path to the <c>os_mon</c> application
+ is <c>/usr/otp/lib/os_mon-1.0 </c> (assuming revision 1.0) and
+ the full name of the binary executable file is
+ <c>/usr/otp/lib/os_mon-1.0/ebin/os_mon.app</c>.</p>
+ </item>
+ <item>Ensure that the following configuration parameters have
+ correct values:</item>
</list>
- <table>
+
+ <table>
<row>
<cell align="left" valign="top"><em>Parameter</em></cell>
<cell align="left" valign="top"><em>Function</em></cell>
<cell align="left" valign="top"><em>Standard value</em></cell>
</row>
<row>
- <cell align="left" valign="middle">start_os_sup</cell>
- <cell align="left" valign="middle">Specifies if os_sup will be started or not.</cell>
- <cell align="left" valign="middle"><c>true</c>for the first instance on the hardware; <c>false</c>for the other instances.</cell>
+ <cell align="left" valign="middle"><c>start_os_sup</c></cell>
+ <cell align="left" valign="middle">Specifies if <c>os_sup</c>
+ is to be started or not.</cell>
+ <cell align="left" valign="middle"><c>true</c> for the
+ first instance on the hardware; <c>false</c> for the
+ other instances</cell>
</row>
<row>
- <cell align="left" valign="middle">os_sup_own</cell>
- <cell align="left" valign="middle">The directory for (1)the back-up copy, (2) the Erlang specific configuration file for syslogd.</cell>
+ <cell align="left" valign="middle"><c>os_sup_own</c></cell>
+ <cell align="left" valign="middle">The directory for
+ (1) back-up copy and (2) Erlang-specific configuration
+ file for <c>syslogd</c></cell>
<cell align="left" valign="middle"><c>"/etc"</c></cell>
</row>
<row>
- <cell align="left" valign="middle">os_sup_syslogconf</cell>
- <cell align="left" valign="middle">The full name for the Solaris standard configuration file for syslogd </cell>
+ <cell align="left" valign="middle"><c>os_sup_syslogconf</c></cell>
+ <cell align="left" valign="middle">The full name for the
+ Solaris standard configuration file for <c>syslogd</c></cell>
<cell align="left" valign="middle"><c>"/etc/syslog.conf"</c></cell>
</row>
<row>
- <cell align="left" valign="middle">error_tag</cell>
- <cell align="left" valign="middle">The tag for the messages that are sent to the error logger in the Erlang runtime system.</cell>
+ <cell align="left" valign="middle"><c>error_tag</c></cell>
+ <cell align="left" valign="middle">The tag for the
+ messages that are sent to the error logger in the Erlang
+ runtime system</cell>
<cell align="left" valign="middle"><c>std_error</c></cell>
</row>
<tcaption>Configuration Parameters</tcaption>
</table>
- <p>If the values listed in the <c>os_mon.app</c> do not suit
- your needs, you should <c>not</c> edit that file. Instead
- you should <em>override</em> values in a <em>system configuration file</em>, the full pathname of which is given
- on the command line to <c>erl</c>.
- </p>
- <p><em>Example:</em> The following is an example of the
- contents of an application configuration file.</p>
- <p></p>
- <pre>
+
+ <p>If the values listed in <c>os_mon.app</c> do not suit
+ your needs, do <em>not</em> edit that file. Instead
+ <em>override</em> the values in a <em>system configuration
+ file</em>, the full pathname of which is given
+ on the command line to <c>erl</c>.</p>
+ <p><em>Example:</em> Contents of an application configuration
+ file:</p>
+ <pre>
[{os_mon, [{start_os_sup, true}, {os_sup_own, "/etc"},
{os_sup_syslogconf, "/etc/syslog.conf"}, {os_sup_errortag, std_error}]}].</pre>
- </section>
-
- <section>
- <title>Related Documents</title>
- <p>See also the <c>os_mon(3)</c>, <c>application(3)</c> and
- <c>erl(1)</c> reference manual pages.</p>
- </section>
</section>
<section>
- <title>Installation Problems</title>
- <p>The hardware watchdog timer which is controlled by the
- <c>heart</c> port program requires the <c>FORCEvme</c>
- package, which contains the VME bus driver, to be
- installed. This driver, however, may clash with the Sun
- <c>mcp</c> driver and cause the system to completely refuse to
- boot. To cure this problem, the following lines should be
- added to <c>/etc/system</c>:
- </p>
+ <title>Related Documents</title>
+ <p>See the <c>os_mon(3)</c> application,
+ the <c>application(3)</c> manual page in <c>kernel</c>,
+ and the <c>erl(1)</c> manual page in <c>erts</c>.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Installation Problems</title>
+ <p>The hardware watchdog timer, which is controlled by the
+ <c>heart</c> port program, requires package <c>FORCEvme</c>,
+ which contains the VME bus driver, to be
+ installed. However, this driver can clash with the Sun
+ <c>mcp</c> driver and cause the system to refuse to
+ boot. To cure this problem, the following lines are
+ to be added to <c>/etc/system</c>:</p>
<list type="bulleted">
<item><c>exclude: drv/mcp</c></item>
<item><c>exclude: drv/mcpzsa</c></item>
<item><c>exclude: drv/mcpp</c></item>
</list>
<warning>
- <p>It is recommended that these lines be added to avoid the
- clash described, which may make it completely impossible to
- boot the system.</p>
+ <p>It is recommended to add these lines to avoid a clash.
+ The clash can make it impossible to boot the system.</p>
</warning>
</section>
</section>
<section>
<title>Starting Erlang</title>
- <p>This section describes how an embedded system is started. There
- are four programs involved, and they all normally reside in the
- directory <c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. The only exception is
- the program <c>start</c>, which may be located anywhere, and
- also is the only program that must be modified by the user.
- </p>
- <p>In an embedded system there usually is no interactive shell.
- However, it is possible for an operator to attach to the Erlang
- system by giving the command <c>to_erl</c>. He is then
- connected to the Erlang shell, and may give ordinary Erlang
- commands. All interaction with the system through this shell is
- logged in a special directory.
- </p>
- <p>Basically, the procedure is as follows. The program
- <c>start</c> is called when the machine is started. It calls
- <c>run_erl</c>, which sets things up so the operator can attach
- to the system. It calls <c>start_erl</c> which calls the
- correct version of <c>erlexec</c> (which is located in
- <c><![CDATA[<ERL_INSTALL_DIR>/erts-EVsn/bin]]></c>) with the correct
- <c>boot</c> and <c>config</c> files.
- </p>
+ <p>This section describes how an embedded system is started. Four
+ programs are involved and they normally reside in the directory
+ <c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. The only exception is
+ the <c>start</c> program, which can be located anywhere, and
+ is also the only program that must be modified by the user.</p>
+ <p>In an embedded system, there is usually no interactive shell.
+ However, an operator can attach to the Erlang
+ system by command <c>to_erl</c>. The operator is then
+ connected to the Erlang shell and can give ordinary Erlang
+ commands. All interaction with the system through this shell is
+ logged in a special directory.</p>
+ <p>Basically, the procedure is as follows:</p>
+ <list type="bulleted">
+ <item>The <c>start</c> program is called when the machine
+ is started.</item>
+ <item>It calls <c>run_erl</c>, which sets up things so the
+ operator can attach to the system.</item>
+ <item>It calls <c>start_erl</c>, which calls the correct
+ version of <c>erlexec</c> (which is located in
+ <c><![CDATA[<ERL_INSTALL_DIR>/erts-EVsn/bin]]></c>) with the
+ correct <c>boot</c> and <c>config</c> files.</item>
+ </list>
</section>
<section>
<title>Programs</title>
-
<section>
<title>start</title>
- <p>This program is called when the machine is started. It may
- be modified or re-written to suit a special system. By
+ <p>This program is called when the machine is started. It can
+ be modified or rewritten to suit a special system. By
default, it must be called <c>start</c> and reside in
- <c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. Another start program can be
- used, by using the configuration parameter <c>start_prg</c> in
- the application <c>sasl</c>.</p>
+ <c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. Another start
+ program can be used, by using configuration parameter
+ <c>start_prg</c> in application <c>sasl</c>.</p>
<p>The start program must call <c>run_erl</c> as shown below.
- It must also take an optional parameter which defaults to
- <c><![CDATA[<ERL_INSTALL_DIR>/releases/start_erl.data]]></c>.
- </p>
- <p>This program should set static parameters and environment
+ It must also take an optional parameter, which defaults to
+ <c><![CDATA[<ERL_INSTALL_DIR>/releases/start_erl.data]]></c>.</p>
+ <p>This program is to set static parameters and environment
variables such as <c>-sname Name</c> and <c>HEART_COMMAND</c>
- to reboot the machine.
- </p>
- <p>The <c><![CDATA[<RELDIR>]]></c> directory is where new release packets
- are installed, and where the release handler keeps information
- about releases. See <c>release_handler(3)</c> in the
- application <c>sasl</c> for further information.
- </p>
+ to reboot the machine.</p>
+ <p>The <c><![CDATA[<RELDIR>]]></c> directory is where new release
+ packets are installed, and where the release handler keeps
+ information about releases. For more information, see the
+ <c>release_handler(3)</c> manual page in <c>sasl</c>.</p>
<p>The following script illustrates the default behaviour of the
- program.
- </p>
+ program:</p>
<code type="none"><![CDATA[
#!/bin/sh
# Usage: start [DataFile]
@@ -583,10 +503,9 @@ START_ERL_DATA=${1:-$RELDIR/start_erl.data}
$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \
$ROOTDIR $RELDIR $START_ERL_DATA" > /dev/null 2>&1 &]]></code>
<p>The following script illustrates a modification where the node
- is given the name <c>cp1</c>, and the environment variables
+ is given the name <c>cp1</c>, and where the environment variables
<c>HEART_COMMAND</c> and <c>TERM</c> have been added to the
- above script.
- </p>
+ previous script:</p>
<code type="none"><![CDATA[
#!/bin/sh
# Usage: start [DataFile]
@@ -606,11 +525,10 @@ START_ERL_DATA=${1:-$RELDIR/start_erl.data}
$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \
$ROOTDIR $RELDIR $START_ERL_DATA -heart -sname cp1" > /dev/null 2>&1 &]]></code>
- <p>If a diskless and/or read-only client node is about to start the
- <c>start_erl.data</c> file is located in the client directory at
- the master node. Thus, the <c>START_ERL_DATA</c> line should look
- like:
- </p>
+ <p>If a diskless and/or read-only client node is about to start,
+ file <c>start_erl.data</c> is located in the client directory at
+ the master node. Thus, the <c>START_ERL_DATA</c> line is to look
+ like:</p>
<code type="none">
CLIENTDIR=$ROOTDIR/clients/clientname
START_ERL_DATA=${1:-$CLIENTDIR/bin/start_erl.data}</code>
@@ -620,22 +538,24 @@ START_ERL_DATA=${1:-$CLIENTDIR/bin/start_erl.data}</code>
<title>run_erl</title>
<p>This program is used to start the emulator, but you will not
be connected to the shell. <c>to_erl</c> is used to connect to
- the Erlang shell.
- </p>
+ the Erlang shell.</p>
<code type="none">
Usage: run_erl pipe_dir/ log_dir "exec command [parameters ...]"</code>
- <p>Where <c>pipe_dir/</c> should be <c>/tmp/</c> (<c>to_erl</c>
- uses this name by default) and <c>log_dir</c> is where the log
- files are written. <c>command [parameters]</c> is executed,
- and everything written to stdin and stdout is logged in the
- <c>log_dir</c>.
- </p>
- <p>In the <c>log_dir</c>, log files are written. Each logfile
- has a name of the form: <c>erlang.log.N</c> where N is a
- generation number, ranging from 1 to 5. Each logfile holds up
- to 100kB text. As time goes by the following logfiles will be
- found in the logfile directory</p>
- <code type="none">
+<p>Here:</p>
+ <list type="bulleted">
+ <item><c>pipe_dir/</c> is to be <c>/tmp/</c> (<c>to_erl</c>
+ uses this name by default).</item>
+ <item><c>log_dir</c> is where the log files are written.</item>
+ <item><c>command [parameters]</c> is executed.</item>
+ <item>Everything written to <c>stdin</c> and <c>stdout</c>
+ is logged in <c>log_dir</c>.</item>
+ </list>
+ <p>Log files are written in <c>log_dir</c>. Each log file
+ has a name of the form <c>erlang.log.N</c>, where N is a
+ generation number, ranging from 1 to 5. Each log file holds up
+ to 100 kB text. As time goes by, the following log files are
+ found in the log file directory:</p>
+ <code type="none">
erlang.log.1
erlang.log.1, erlang.log.2
erlang.log.1, erlang.log.2, erlang.log.3
@@ -643,48 +563,40 @@ erlang.log.1, erlang.log.2, erlang.log.3, erlang.log.4
erlang.log.2, erlang.log.3, erlang.log.4, erlang.log.5
erlang.log.3, erlang.log.4, erlang.log.5, erlang.log.1
...</code>
- <p>with the most recent logfile being the right most in each row
- of the above list. That is, the most recent file is the one
- with the highest number, or if there are already four files,
- the one before the skip.
- </p>
- <p>When a logfile is opened (for appending or created) a time
- stamp is written to the file. If nothing has been written to
+ <p>The most recent log file is the rightmost in each row. That
+ is, the most recent file is the one with the highest number, or
+ if there are already four files, the one before the skip.</p>
+ <p>When a log file is opened (for appending or created), a time
+ stamp is written to the file. If nothing has been written to
the log files for 15 minutes, a record is inserted that says
- that we're still alive.
- </p>
+ that we are still alive.</p>
</section>
<section>
<title>to_erl</title>
<p>This program is used to attach to a running Erlang runtime
- system, started with <c>run_erl</c>.
- </p>
+ system, started with <c>run_erl</c>.</p>
<code type="none">
Usage: to_erl [pipe_name | pipe_dir]</code>
- <p>Where <c>pipe_name</c> defaults to <c>/tmp/erlang.pipe.N</c>.
- </p>
+ <p>Here <c>pipe_name</c> defaults to <c>/tmp/erlang.pipe.N</c>.</p>
<p>To disconnect from the shell without exiting the Erlang
- system, type <c>Ctrl-D</c>.
- </p>
+ system, type <c>Ctrl-D</c>.</p>
</section>
<section>
<title>start_erl</title>
<p>This program starts the Erlang emulator with parameters
- <c>-boot</c> and <c>-config</c> set. It reads data about
- where these files are located from a file called
- <c>start_erl.data</c> which is located in the <c><![CDATA[<RELDIR>]]></c>.
- Each new release introduces a new data file. This file is
- automatically generated by the release handler in Erlang.
- </p>
- <p>The following script illustrates the behaviour of the
- program.
- </p>
+ <c>-boot</c> and <c>-config</c> set. It reads data about
+ where these files are located from a file named
+ <c>start_erl.data</c>, which is located in
+ <c><![CDATA[<RELDIR>]]></c>.
+ Each new release introduces a new data file. This file is
+ automatically generated by the release handler in Erlang.</p>
+ <p>The following script illustrates the behaviour of the program:</p>
<code type="none">
#!/bin/sh
#
-# This program is called by run_erl. It starts
+# This program is called by run_erl. It starts
# the Erlang emulator and sets -boot and -config parameters.
# It should only be used at an embedded target system.
#
@@ -710,22 +622,23 @@ export PROGNAME
export RELDIR
exec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $*</code>
+
<p>If a diskless and/or read-only client node with the
<c>sasl</c> configuration parameter <c>static_emulator</c> set
- to <c>true</c> is about to start the <c>-boot</c> and
- <c>-config</c> flags must be changed. As such a client cannot
- read a new <c>start_erl.data</c> file (the file is not
- possible to change dynamically) the boot and config files are
+ to <c>true</c> is about to start, the <c>-boot</c> and
+ <c>-config</c> flags must be changed.</p>
+ <p>As such a client cannot
+ read a new <c>start_erl.data</c> file (the file cannot
+ be changed dynamically). The boot and config files are
always fetched from the same place (but with new contents if
- a new release has been installed). The <c>release_handler</c>
- copies this files to the <c>bin</c> directory in the client
+ a new release has been installed).</p>
+ <p>The <c>release_handler</c>
+ copies these files to the <c>bin</c> directory in the client
directory at the master nodes whenever a new release is made
- permanent.
- </p>
- <p>Assuming the same <c>CLIENTDIR</c> as above the last line
- should look like:
- </p>
- <code type="none">
+ permanent.</p>
+ <p>Assuming the same <c>CLIENTDIR</c> as above, the last line
+ is to look like:</p>
+ <code type="none">
exec $BINDIR/erlexec -boot $CLIENTDIR/bin/start \
-config $CLIENTDIR/bin/sys $*</code>
</section>
diff --git a/system/doc/embedded/intro.xml b/system/doc/embedded/intro.xml
index 85ce74611c..7fea2eeb82 100644
--- a/system/doc/embedded/intro.xml
+++ b/system/doc/embedded/intro.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/system/doc/embedded/part.xml b/system/doc/embedded/part.xml
index e4366bd2c2..7bac643be7 100644
--- a/system/doc/embedded/part.xml
+++ b/system/doc/embedded/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,17 +32,17 @@
<rev>C</rev>
<file></file>
</header>
+
<description>
- <p>This manual describes the issues that are specific
+ <marker id="embedded systems user guide"></marker>
+ <p>This section describes the issues that are specific
for running Erlang on an embedded system.
It describes the differences in installing and starting
- Erlang compared to how it is done for a non-embedded system.
- </p>
- <p>Note that this is a supplementary document. You still need to
- read the Installation Guide.
- </p>
- <p>There is also target architecture specific information in
- the top level README file of the Erlang distribution.</p>
+ Erlang compared to how it is done for a non-embedded system.</p>
+ <note><p>This is a supplementary section. You also need to
+ read Section 1 Installation Guide.</p></note>
+ <p>There is also target architecture-specific information in
+ the top-level README file of the Erlang distribution.</p>
</description>
<xi:include href="embedded_solaris.xml"/>
<xi:include href="embedded_nt.xml"/>
diff --git a/system/doc/embedded/starting.xml b/system/doc/embedded/starting.xml
index 527496c420..f9454f1021 100644
--- a/system/doc/embedded/starting.xml
+++ b/system/doc/embedded/starting.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/embedded/target.xml b/system/doc/embedded/target.xml
index 123e26f918..20ef6b0fc6 100644
--- a/system/doc/embedded/target.xml
+++ b/system/doc/embedded/target.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/embedded/vme_problems.xml b/system/doc/embedded/vme_problems.xml
index e9d164f454..54618935cd 100644
--- a/system/doc/embedded/vme_problems.xml
+++ b/system/doc/embedded/vme_problems.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/system/doc/embedded/xmlfiles.mk b/system/doc/embedded/xmlfiles.mk
index d11f5a1004..4446aa1516 100644
--- a/system/doc/embedded/xmlfiles.mk
+++ b/system/doc/embedded/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# 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.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/embedded/xntp.xml b/system/doc/embedded/xntp.xml
index 2fab4e4455..2f4dc9a534 100644
--- a/system/doc/embedded/xntp.xml
+++ b/system/doc/embedded/xntp.xml
@@ -9,16 +9,17 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
diff --git a/system/doc/getting_started/Makefile b/system/doc/getting_started/Makefile
index c28da373cf..37b6db3207 100644
--- a/system/doc/getting_started/Makefile
+++ b/system/doc/getting_started/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/getting_started/book.xml b/system/doc/getting_started/book.xml
index fb5e5eec3b..8dfca19480 100644
--- a/system/doc/getting_started/book.xml
+++ b/system/doc/getting_started/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/getting_started/conc_prog.xml b/system/doc/getting_started/conc_prog.xml
index 2b64826a93..9f13ee4802 100644
--- a/system/doc/getting_started/conc_prog.xml
+++ b/system/doc/getting_started/conc_prog.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,25 +30,26 @@
<file>conc_prog.xml</file>
</header>
+ <marker id="Distributed Programming"></marker>
<section>
<title>Processes</title>
<p>One of the main reasons for using Erlang instead of other
functional languages is Erlang's ability to handle concurrency
- and distributed programming. By concurrency we mean programs
- which can handle several threads of execution at the same time.
- For example, modern operating systems would allow you to use a
- word processor, a spreadsheet, a mail client and a print job all
- running at the same time. Of course each processor (CPU) in
+ and distributed programming. By concurrency is meant programs
+ that can handle several threads of execution at the same time.
+ For example, modern operating systems allow you to use a
+ word processor, a spreadsheet, a mail client, and a print job all
+ running at the same time. Each processor (CPU) in
the system is probably only handling one thread (or job) at a
- time, but it swaps between the jobs a such a rate that it gives
+ time, but it swaps between the jobs at such a rate that it gives
the illusion of running them all at the same time. It is easy to
- create parallel threads of execution in an Erlang program and it
- is easy to allow these threads to communicate with each other. In
- Erlang we call each thread of execution a <em>process</em>.</p>
+ create parallel threads of execution in an Erlang program and
+ to allow these threads to communicate with each other. In
+ Erlang, each thread of execution is called a <em>process</em>.</p>
<p>(Aside: the term "process" is usually used when the threads of
execution share no data with each other and the term "thread"
when they share data in some way. Threads of execution in Erlang
- share no data, that's why we call them processes).</p>
+ share no data, that is why they are called processes).</p>
<p>The Erlang BIF <c>spawn</c> is used to create a new process:
<c>spawn(Module, Exported_Function, List of Arguments)</c>.
Consider the following module:</p>
@@ -73,14 +75,14 @@ hello
hello
hello
done</pre>
- <p>We can see that function <c>say_something</c> writes its first
- argument the number of times specified by second argument. Now
- look at the function <c>start</c>. It starts two Erlang processes,
- one which writes "hello" three times and one which writes
- "goodbye" three times. Both of these processes use the function
- <c>say_something</c>. Note that a function used in this way by
- <c>spawn</c> to start a process must be exported from the module
- (i.e. in the <c>-export</c> at the start of the module).</p>
+ <p>As shown, the function <c>say_something</c> writes its first
+ argument the number of times specified by second argument.
+ The function <c>start</c> starts two Erlang processes,
+ one that writes "hello" three times and one that writes
+ "goodbye" three times. Both processes use the function
+ <c>say_something</c>. Notice that a function used in this way by
+ <c>spawn</c>, to start a process, must be exported from the module
+ (that is, in the <c>-export</c> at the start of the module).</p>
<pre>
9> <input>tut14:start().</input>
hello
@@ -90,19 +92,19 @@ hello
goodbye
hello
goodbye</pre>
- <p>Notice that it didn't write "hello" three times and then
- "goodbye" three times, but the first process wrote a "hello",
+ <p>Notice that it did not write "hello" three times and then
+ "goodbye" three times. Instead, the first process wrote a "hello",
the second a "goodbye", the first another "hello" and so forth.
But where did the &lt;0.63.0&gt; come from? The return value of a
- function is of course the return value of the last "thing" in
- the function. The last thing in the function <c>start</c> is:</p>
+ function is the return value of the last "thing" in
+ the function. The last thing in the function <c>start</c> is</p>
<code type="none">
spawn(tut14, say_something, [goodbye, 3]).</code>
<p><c>spawn</c> returns a <em>process identifier</em>, or
<em>pid</em>, which uniquely identifies the process. So &lt;0.63.0&gt;
- is the pid of the <c>spawn</c> function call above. We will see
- how to use pids in the next example.</p>
- <p>Note as well that we have used ~p instead of ~w in
+ is the pid of the <c>spawn</c> function call above.
+ The next example shows how to use pids.</p>
+ <p>Notice also that ~p is used instead of ~w in
<c>io:format</c>. To quote the manual: "~p Writes the data with
standard syntax in the same way as ~w, but breaks terms whose
printed representation is longer than one line into many lines
@@ -112,8 +114,8 @@ spawn(tut14, say_something, [goodbye, 3]).</code>
<section>
<title>Message Passing</title>
- <p>In the following example we create two processes which send
- messages to each other a number of times.</p>
+ <p>In the following example two processes are created and
+ they send messages to each other a number of times.</p>
<code type="none">
-module(tut15).
@@ -157,13 +159,13 @@ Pong received ping
Ping received pong
ping finished
Pong finished</pre>
- <p>The function <c>start</c> first creates a process, let's call it
- "pong":</p>
+ <p>The function <c>start</c> first creates a process,
+ let us call it "pong":</p>
<code type="none">
Pong_PID = spawn(tut15, pong, [])</code>
<p>This process executes <c>tut15:pong()</c>. <c>Pong_PID</c> is
the process identity of the "pong" process. The function
- <c>start</c> now creates another process "ping".</p>
+ <c>start</c> now creates another process "ping":</p>
<code type="none">
spawn(tut15, ping, [3, Pong_PID]),</code>
<p>This process executes:</p>
@@ -181,7 +183,7 @@ receive
pong()
end.</code>
<p>The <c>receive</c> construct is used to allow processes to wait
- for messages from other processes. It has the format:</p>
+ for messages from other processes. It has the following format:</p>
<code type="none">
receive
pattern1 ->
@@ -192,35 +194,37 @@ receive
patternN
actionsN
end.</code>
- <p>Note: no ";" before the <c>end</c>.</p>
+ <p>Notice there is no ";" before the <c>end</c>.</p>
<p>Messages between Erlang processes are simply valid Erlang terms.
- I.e. they can be lists, tuples, integers, atoms, pids etc.</p>
+ That is, they can be lists, tuples, integers, atoms, pids,
+ and so on.</p>
<p>Each process has its own input queue for messages it receives.
New messages received are put at the end of the queue. When a
process executes a <c>receive</c>, the first message in the queue
- is matched against the first pattern in the <c>receive</c>, if
+ is matched against the first pattern in the <c>receive</c>. If
this matches, the message is removed from the queue and
- the actions corresponding to the the pattern are executed.</p>
+ the actions corresponding to the pattern are executed.</p>
<p>However, if the first pattern does not match, the second pattern
- is tested, if this matches the message is removed from the queue
+ is tested. If this matches, the message is removed from the queue
and the actions corresponding to the second pattern are executed.
- If the second pattern does not match the third is tried and so on
- until there are no more pattern to test. If there are no more
- patterns to test, the first message is kept in the queue and we
- try the second message instead. If this matches any pattern,
+ If the second pattern does not match, the third is tried and so on
+ until there are no more patterns to test. If there are no more
+ patterns to test, the first message is kept in the queue and
+ the second message is tried instead. If this matches any pattern,
the appropriate actions are executed and the second message is
removed from the queue (keeping the first message and any other
- messages in the queue). If the second message does not match we
- try the third message and so on until we reach the end of
- the queue. If we reach the end of the queue, the process blocks
+ messages in the queue). If the second message does not match,
+ the third message is tried, and so on, until the end of
+ the queue is reached. If the end of the queue is reached,
+ the process blocks
(stops execution) and waits until a new message is received and
this procedure is repeated.</p>
- <p>Of course the Erlang implementation is "clever" and minimizes
+ <p>The Erlang implementation is "clever" and minimizes
the number of times each message is tested against the patterns
in each <c>receive</c>.</p>
<p>Now back to the ping pong example.</p>
<p>"Pong" is waiting for messages. If the atom <c>finished</c> is
- received, "pong" writes "Pong finished" to the output and as it
+ received, "pong" writes "Pong finished" to the output and, as it
has nothing more to do, terminates. If it receives a message with
the format:</p>
<code type="none">
@@ -229,20 +233,20 @@ end.</code>
<c>pong</c> to the process "ping":</p>
<code type="none">
Ping_PID ! pong</code>
- <p>Note how the operator "!" is used to send messages. The syntax
+ <p>Notice how the operator "!" is used to send messages. The syntax
of "!" is:</p>
<code type="none">
Pid ! Message</code>
- <p>I.e. <c>Message</c> (any Erlang term) is sent to the process
+ <p>That is, <c>Message</c> (any Erlang term) is sent to the process
with identity <c>Pid</c>.</p>
<p>After sending the message <c>pong</c> to the process "ping",
"pong" calls the <c>pong</c> function again, which causes it to
- get back to the <c>receive</c> again and wait for another message.
- Now let's look at the process "ping". Recall that it was started
+ get back to the <c>receive</c> again and wait for another message.</p>
+ <p>Now let us look at the process "ping". Recall that it was started
by executing:</p>
<code type="none">
tut15:ping(3, Pong_PID)</code>
- <p>Looking at the function <c>ping/2</c> we see that the second
+ <p>Looking at the function <c>ping/2</c>, the second
clause of <c>ping/2</c> is executed since the value of the first
argument is 3 (not 0) (first clause head is
<c>ping(0,Pong_PID)</c>, second clause head is
@@ -250,9 +254,9 @@ tut15:ping(3, Pong_PID)</code>
<p>The second clause sends a message to "pong":</p>
<code type="none">
Pong_PID ! {ping, self()},</code>
- <p><c>self()</c> returns the pid of the process which executes
+ <p><c>self()</c> returns the pid of the process that executes
<c>self()</c>, in this case the pid of "ping". (Recall the code
- for "pong", this will land up in the variable <c>Ping_PID</c> in
+ for "pong", this lands up in the variable <c>Ping_PID</c> in
the <c>receive</c> previously explained.)</p>
<p>"Ping" now waits for a reply from "pong":</p>
<code type="none">
@@ -260,37 +264,37 @@ receive
pong ->
io:format("Ping received pong~n", [])
end,</code>
- <p>and writes "Ping received pong" when this reply arrives, after
+ <p>It writes "Ping received pong" when this reply arrives, after
which "ping" calls the <c>ping</c> function again.</p>
<code type="none">
ping(N - 1, Pong_PID)</code>
<p><c>N-1</c> causes the first argument to be decremented until it
becomes 0. When this occurs, the first clause of <c>ping/2</c>
- will be executed:</p>
+ is executed:</p>
<code type="none">
ping(0, Pong_PID) ->
Pong_PID ! finished,
io:format("ping finished~n", []);</code>
<p>The atom <c>finished</c> is sent to "pong" (causing it to
terminate as described above) and "ping finished" is written to
- the output. "Ping" then itself terminates as it has nothing left
+ the output. "Ping" then terminates as it has nothing left
to do.</p>
</section>
<section>
<title>Registered Process Names</title>
- <p>In the above example, we first created "pong" so as to be able
- to give the identity of "pong" when we started "ping". I.e. in
- some way "ping" must be able to know the identity of "pong" in
- order to be able to send a message to it. Sometimes processes
- which need to know each others identities are started completely
+ <p>In the above example, "pong" was first created to be able
+ to give the identity of "pong" when "ping" was started. That is, in
+ some way "ping" must be able to know the identity of "pong" to be
+ able to send a message to it. Sometimes processes
+ which need to know each other's identities are started
independently of each other. Erlang thus provides a mechanism for
processes to be given names so that these names can be used as
identities instead of pids. This is done by using
the <c>register</c> BIF:</p>
<code type="none">
register(some_atom, Pid)</code>
- <p>We will now re-write the ping pong example using this and giving
+ <p>Let us now rewrite the ping pong example using this and give
the name <c>pong</c> to the "pong" process:</p>
<code type="none">
-module(tut16).
@@ -335,52 +339,57 @@ Pong received ping
Ping received pong
ping finished
Pong finished</pre>
- <p>In the <c>start/0</c> function,</p>
+ <p>Here the <c>start/0</c> function,</p>
<code type="none">
register(pong, spawn(tut16, pong, [])),</code>
<p>both spawns the "pong" process and gives it the name <c>pong</c>.
- In the "ping" process we can now send messages to <c>pong</c> by:</p>
+ In the "ping" process, messages can be sent to <c>pong</c> by:</p>
<code type="none">
pong ! {ping, self()},</code>
- <p>so that <c>ping/2</c> now becomes <c>ping/1</c> as we don't have
- to use the argument <c>Pong_PID</c>.</p>
+ <p><c>ping/2</c> now becomes <c>ping/1</c> as
+ the argument <c>Pong_PID</c> is not needed.</p>
</section>
<section>
<title>Distributed Programming</title>
- <p>Now let's re-write the ping pong program with "ping" and "pong"
- on different computers. Before we do this, there are a few things
- we need to set up to get this to work. The distributed Erlang
+ <p>Let us rewrite the ping pong program with "ping" and "pong"
+ on different computers. First a few things
+ are needed to set up to get this to work. The distributed Erlang
implementation provides a basic security mechanism to prevent
unauthorized access to an Erlang system on another computer.
Erlang systems which talk to each other must have
the same <em>magic cookie</em>. The easiest way to achieve this
is by having a file called <c>.erlang.cookie</c> in your home
- directory on all machines which on which you are going to run
- Erlang systems communicating with each other (on Windows systems
- the home directory is the directory where pointed to by the $HOME
- environment variable - you may need to set this. On Linux or Unix
- you can safely ignore this and simply create a file called
- <c>.erlang.cookie</c> in the directory you get to after executing
- the command <c>cd</c> without any argument).
- The <c>.erlang.cookie</c> file should contain one line with
- the same atom. For example, on Linux or Unix in the OS shell:</p>
+ directory on all machines on which you are going to run
+ Erlang systems communicating with each other:
+ </p>
+ <list type="bulleted">
+ <item>On Windows systems the home directory is the directory
+ pointed out by the environment variable $HOME - you may need
+ to set this.</item>
+ <item> On Linux or UNIX
+ you can safely ignore this and simply create a file called
+ <c>.erlang.cookie</c> in the directory you get to after executing
+ the command <c>cd</c> without any argument.</item>
+ </list>
+ <p>The <c>.erlang.cookie</c> file is to contain a line with
+ the same atom. For example, on Linux or UNIX, in the OS shell:</p>
<pre>
$ <input>cd</input>
$ <input>cat > .erlang.cookie</input>
this_is_very_secret
$ <input>chmod 400 .erlang.cookie</input></pre>
- <p>The <c>chmod</c> above make the <c>.erlang.cookie</c> file
+ <p>The <c>chmod</c> above makes the <c>.erlang.cookie</c> file
accessible only by the owner of the file. This is a requirement.</p>
- <p>When you start an Erlang system which is going to talk to other
- Erlang systems, you must give it a name, e.g.: </p>
+ <p>When you start an Erlang system that is going to talk to other
+ Erlang systems, you must give it a name, for example:</p>
<pre>
$ <input>erl -sname my_name</input></pre>
<p>We will see more details of this later. If you want to
experiment with distributed Erlang, but you only have one
computer to work on, you can start two separate Erlang systems on
the same computer but give them different names. Each Erlang
- system running on a computer is called an Erlang node.</p>
+ system running on a computer is called an <em>Erlang node</em>.</p>
<p>(Note: <c>erl -sname</c> assumes that all nodes are in the same
IP domain and we can use only the first component of the IP
address, if we want to use nodes in different domains we use
@@ -420,10 +429,10 @@ start_pong() ->
start_ping(Pong_Node) ->
spawn(tut17, ping, [3, Pong_Node]).</code>
- <p>Let us assume we have two computers called gollum and kosken. We
- will start a node on kosken called ping and then a node on gollum
+ <p>Let us assume there are two computers called gollum and kosken.
+ First a node is started on kosken, called ping, and then a node on gollum,
called pong.</p>
- <p>On kosken (on a Linux/Unix system):</p>
+ <p>On kosken (on a Linux/UNIX system):</p>
<pre>
kosken> <input>erl -sname ping</input>
Erlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]
@@ -437,12 +446,12 @@ Erlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]
Eshell V5.2.3.7 (abort with ^G)
(pong@gollum)1></pre>
- <p>Now we start the "pong" process on gollum:</p>
+ <p>Now the "pong" process on gollum is started:</p>
<pre>
(pong@gollum)1> <input>tut17:start_pong().</input>
true</pre>
- <p>and start the "ping" process on kosken (from the code above you
- will see that a parameter of the <c>start_ping</c> function is
+ <p>And the "ping" process on kosken is started (from the code above you
+ can see that a parameter of the <c>start_ping</c> function is
the node name of the Erlang system where "pong" is running):</p>
<pre>
(ping@kosken)1> <input>tut17:start_ping(pong@gollum).</input>
@@ -451,8 +460,7 @@ Ping received pong
Ping received pong
Ping received pong
ping finished</pre>
- <p>Here we see that the ping pong program has run, on the "pong"
- side we see:</p>
+ <p>As shown, the ping pong program has run. On the "pong" side:</p>
<pre>
(pong@gollum)2>
Pong received ping
@@ -460,28 +468,28 @@ Pong received ping
Pong received ping
Pong finished
(pong@gollum)2></pre>
- <p>Looking at the <c>tut17</c> code we see that the <c>pong</c>
- function itself is unchanged, the lines:</p>
+ <p>Looking at the <c>tut17</c> code, you see that the <c>pong</c>
+ function itself is unchanged, the following lines work in the same way
+ irrespective of on which node the "ping" process is executes:</p>
<code type="none">
{ping, Ping_PID} ->
io:format("Pong received ping~n", []),
Ping_PID ! pong,</code>
- <p>work in the same way irrespective of on which node the "ping"
- process is executing. Thus Erlang pids contain information about
- where the process executes so if you know the pid of a process,
- the "!" operator can be used to send it a message if the process
- is on the same node or on a different node.</p>
- <p>A difference is how we send messages to a registered process on
+ <p>Thus, Erlang pids contain information about
+ where the process executes. So if you know the pid of a process,
+ the "!" operator can be used to send it a message disregarding
+ if the process is on the same node or on a different node.</p>
+ <p>A difference is how messages are sent to a registered process on
another node:</p>
<code type="none">
{pong, Pong_Node} ! {ping, self()},</code>
- <p>We use a tuple <c>{registered_name,node_name}</c> instead of
+ <p>A tuple <c>{registered_name,node_name}</c> is used instead of
just the <c>registered_name</c>.</p>
- <p>In the previous example, we started "ping" and "pong" from
+ <p>In the previous example, "ping" and "pong" were started from
the shells of two separate Erlang nodes. <c>spawn</c> can also be
- used to start processes in other nodes. The next example is
- the ping pong program, yet again, but this time we will start
- "ping" in another node:</p>
+ used to start processes in other nodes.</p>
+ <p>The next example is the ping pong program, yet again,
+ but this time "ping" is started in another node:</p>
<code type="none">
-module(tut18).
@@ -513,7 +521,7 @@ start(Ping_Node) ->
register(pong, spawn(tut18, pong, [])),
spawn(Ping_Node, tut18, ping, [3, node()]).</code>
<p>Assuming an Erlang system called ping (but not the "ping"
- process) has already been started on kosken, then on gollum we do:</p>
+ process) has already been started on kosken, then on gollum this is done:</p>
<pre>
(pong@gollum)1> <input>tut18:start(ping@kosken).</input>
&lt;3934.39.0>
@@ -525,39 +533,40 @@ Pong received ping
Ping received pong
Pong finished
ping finished</pre>
- <p>Notice we get all the output on gollum. This is because the io
+ <p>Notice that all the output is received on gollum. This is because
+ the I/O
system finds out where the process is spawned from and sends all
output there.</p>
</section>
<section>
<title>A Larger Example</title>
- <p>Now for a larger example. We will make an extremely simple
- "messenger". The messenger is a program which allows users to log
+ <p>Now for a larger example with a simple
+ "messenger". The messenger is a program that allows users to log
in on different nodes and send simple messages to each other.</p>
- <p>Before we start, let's note the following:</p>
+ <p>Before starting, notice the following:</p>
<list type="bulleted">
<item>
- <p>This example will just show the message passing logic - no
- attempt at all has been made to provide a nice graphical user
- interface. This can, of course, also be done in Erlang - but
- that's another tutorial.</p>
+ <p>This example only shows the message passing logic - no
+ attempt has been made to provide a nice graphical user
+ interface, although this can also be done in Erlang.</p>
</item>
<item>
- <p>This sort of problem can be solved more easily if you use
- the facilities in OTP, which will also provide methods for
- updating code on the fly etc. But again, that's another
- tutorial.</p>
+ <p>This sort of problem can be solved easier by use of
+ the facilities in OTP, which also provide methods for
+ updating code on the fly and so on (see
+ <seealso marker="doc/design_principles:des_princ#otp design principles">
+ OTP Design Principles</seealso>).</p>
</item>
<item>
- <p>The first program we write will contain some inadequacies
- regarding the handling of nodes which disappear. We will correct
- these in a later version of the program.</p>
+ <p>The first program contains some inadequacies
+ regarding handling of nodes which disappear.
+ These are corrected in a later version of the program.</p>
</item>
</list>
- <p>We will set up the messenger by allowing "clients" to connect to
- a central server and say who and where they are. I.e. a user
- won't need to know the name of the Erlang node where another user
+ <p>The messenger is set up by allowing "clients" to connect to
+ a central server and say who and where they are. That is, a user
+ does not need to know the name of the Erlang node where another user
is located to send a message.</p>
<p>File <c>messenger.erl</c>:</p>
<marker id="ex"></marker>
@@ -728,19 +737,19 @@ await_result() ->
{messenger, What} -> % Normal response
io:format("~p~n", [What])
end.</code>
- <p>To use this program you need to:</p>
+ <p>To use this program, you need to:</p>
<list type="bulleted">
- <item>configure the <c>server_node()</c> function</item>
- <item>copy the compiled code (<c>messenger.beam</c>) to
- the directory on each computer where you start Erlang.</item>
+ <item>Configure the <c>server_node()</c> function.</item>
+ <item>Copy the compiled code (<c>messenger.beam</c>) to
+ the directory on each computer where you start Erlang.</item>
</list>
- <p>In the following example of use of this program I have started
- nodes on four different computers, but if you don't have that
- many machines available on your network you could start up
+ <p>In the following example using this program,
+ nodes are started on four different computers. If you do not have that
+ many machines available on your network, you can start
several nodes on the same machine.</p>
- <p>We start up four Erlang nodes: messenger@super, c1@bilbo,
+ <p>Four Erlang nodes are started up: messenger@super, c1@bilbo,
c2@kosken, c3@gollum.</p>
- <p>First we start up a the server at messenger@super:</p>
+ <p>First the server at messenger@super is started up:</p>
<pre>
(messenger@super)1> <input>messenger:start_server().</input>
true</pre>
@@ -754,7 +763,7 @@ logged_on</pre>
(c2@kosken)1> <input>messenger:logon(james).</input>
true
logged_on</pre>
- <p>and Fred logs on at c3@gollum:</p>
+ <p>And Fred logs on at c3@gollum:</p>
<pre>
(c3@gollum)1> <input>messenger:logon(fred).</input>
true
@@ -764,7 +773,7 @@ logged_on</pre>
(c1@bilbo)2> <input>messenger:message(fred, "hello").</input>
ok
sent</pre>
- <p>And Fred receives the message and sends a message to Peter and
+ <p>Fred receives the message and sends a message to Peter and
logs off:</p>
<pre>
Message from peter: "hello"
@@ -779,27 +788,28 @@ logoff</pre>
ok
receiver_not_found</pre>
<p>But this fails as Fred has already logged off.</p>
- <p>First let's look at some of the new concepts we have introduced.</p>
+ <p>First let us look at some of the new concepts that have
+ been introduced.</p>
<p>There are two versions of the <c>server_transfer</c> function:
one with four arguments (<c>server_transfer/4</c>) and one with
five (<c>server_transfer/5</c>). These are regarded by Erlang as
two separate functions.</p>
- <p>Note how we write the <c>server</c> function so that it calls
- itself, via <c>server(User_List)</c>, and thus creates a loop.
+ <p>Notice how to write the <c>server</c> function so that it calls
+ itself, through <c>server(User_List)</c>, and thus creates a loop.
The Erlang compiler is "clever" and optimizes the code so that
this really is a sort of loop and not a proper function call. But
- this only works if there is no code after the call, otherwise
- the compiler will expect the call to return and make a proper
+ this only works if there is no code after the call. Otherwise,
+ the compiler expects the call to return and make a proper
function call. This would result in the process getting bigger
and bigger for every loop.</p>
- <p>We use functions from the <c>lists</c> module. This is a very
+ <p>Functions in the <c>lists</c> module are used. This is a very
useful module and a study of the manual page is recommended
(<c>erl -man lists</c>).
<c>lists:keymember(Key,Position,Lists)</c> looks through a list
of tuples and looks at <c>Position</c> in each tuple to see if it
is the same as <c>Key</c>. The first element is position 1. If it
finds a tuple where the element at <c>Position</c> is the same as
- Key, it returns <c>true</c>, otherwise <c>false</c>.</p>
+ <c>Key</c>, it returns <c>true</c>, otherwise <c>false</c>.</p>
<pre>
3> <input>lists:keymember(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).</input>
true
@@ -812,82 +822,83 @@ false</pre>
[{x,y,z},{b,b,b},{q,r,s}]</pre>
<p><c>lists:keysearch</c> is like <c>lists:keymember</c>, but it
returns <c>{value,Tuple_Found}</c> or the atom <c>false</c>.</p>
- <p>There are a lot more very useful functions in the <c>lists</c>
+ <p>There are many very useful functions in the <c>lists</c>
module.</p>
- <p>An Erlang process will (conceptually) run until it does a
+ <p>An Erlang process (conceptually) runs until it does a
<c>receive</c> and there is no message which it wants to receive
- in the message queue. I say "conceptually" because the Erlang
+ in the message queue. "conceptually" is used here because the Erlang
system shares the CPU time between the active processes in
the system.</p>
<p>A process terminates when there is nothing more for it to do,
- i.e. the last function it calls simply returns and doesn't call
+ that is, the last function it calls simply returns and does not call
another function. Another way for a process to terminate is for
it to call <c>exit/1</c>. The argument to <c>exit/1</c> has a
- special meaning which we will look at later. In this example we
- will do <c>exit(normal)</c> which has the same effect as a
+ special meaning, which is discussed later. In this example,
+ <c>exit(normal)</c> is done, which has the same effect as a
process running out of functions to call.</p>
<p>The BIF <c>whereis(RegisteredName)</c> checks if a registered
- process of name <c>RegisteredName</c> exists and return the pid
- of the process if it does exist or the atom <c>undefined</c> if
- it does not.</p>
- <p>You should by now be able to understand most of the code above
- so I'll just go through one case: a message is sent from one user
- to another.</p>
+ process of name <c>RegisteredName</c> exists. If it exists, the pid of
+ that process is returned. If it does not exist, the atom
+ <c>undefined</c> is returned.</p>
+ <p>You should by now be able to understand most of the code in the
+ messenger-module. Let us study one case in detail: a message is
+ sent from one user to another.</p>
<p>The first user "sends" the message in the example above by:</p>
<code type="none">
messenger:message(fred, "hello")</code>
<p>After testing that the client process exists:</p>
<code type="none">
whereis(mess_client) </code>
- <p>and a message is sent to <c>mess_client</c>:</p>
+ <p>And a message is sent to <c>mess_client</c>:</p>
<code type="none">
mess_client ! {message_to, fred, "hello"}</code>
<p>The client sends the message to the server by:</p>
<code type="none">
{messenger, messenger@super} ! {self(), message_to, fred, "hello"},</code>
- <p>and waits for a reply from the server.</p>
+ <p>And waits for a reply from the server.</p>
<p>The server receives this message and calls:</p>
<code type="none">
server_transfer(From, fred, "hello", User_List),</code>
- <p>which checks that the pid <c>From</c> is in the <c>User_List</c>:</p>
+ <p>This checks that the pid <c>From</c> is in the <c>User_List</c>:</p>
<code type="none">
lists:keysearch(From, 1, User_List) </code>
- <p>If <c>keysearch</c> returns the atom <c>false</c>, some sort of
+ <p>If <c>keysearch</c> returns the atom <c>false</c>, some
error has occurred and the server sends back the message:</p>
<code type="none">
From ! {messenger, stop, you_are_not_logged_on}</code>
- <p>which is received by the client which in turn does
+ <p>This is received by the client, which in turn does
<c>exit(normal)</c> and terminates. If <c>keysearch</c> returns
- <c>{value,{From,Name}}</c> we know that the user is logged on and
- is his name (peter) is in variable <c>Name</c>. We now call:</p>
+ <c>{value,{From,Name}}</c> it is certain that the user is logged on and
+ that his name (peter) is in variable <c>Name</c>.</p>
+ <p>Let us now call:</p>
<code type="none">
server_transfer(From, peter, fred, "hello", User_List)</code>
- <p>Note that as this is <c>server_transfer/5</c> it is not the same
- as the previous function <c>server_transfer/4</c>. We do another
- <c>keysearch</c> on <c>User_List</c> to find the pid of the client
- corresponding to fred:</p>
+ <p>Notice that as this is <c>server_transfer/5</c>, it is not the same
+ as the previous function <c>server_transfer/4</c>. Another
+ <c>keysearch</c> is done on <c>User_List</c> to find the pid of
+ the client corresponding to fred:</p>
<code type="none">
lists:keysearch(fred, 2, User_List)</code>
- <p>This time we use argument 2 which is the second element in
- the tuple. If this returns the atom <c>false</c> we know that
- fred is not logged on and we send the message:</p>
+ <p>This time argument 2 is used, which is the second element in
+ the tuple. If this returns the atom <c>false</c>,
+ fred is not logged on and the following message is sent:</p>
<code type="none">
From ! {messenger, receiver_not_found};</code>
- <p>which is received by the client, if <c>keysearch</c> returns:</p>
+ <p>This is received by the client.</p>
+ <p> If <c>keysearch</c> returns:</p>
<code type="none">
{value, {ToPid, fred}}</code>
- <p>we send the message:</p>
+ <p>The following message is sent to fred's client:</p>
<code type="none">
ToPid ! {message_from, peter, "hello"}, </code>
- <p>to fred's client and the message:</p>
+ <p>The following message is sent to peter's client:</p>
<code type="none">
From ! {messenger, sent} </code>
- <p>to peter's client.</p>
<p>Fred's client receives the message and prints it:</p>
<code type="none">
{message_from, peter, "hello"} ->
io:format("Message from ~p: ~p~n", [peter, "hello"])</code>
- <p>and peter's client receives the message in
+ <p>Peter's client receives the message in
the <c>await_result</c> function.</p>
</section>
</chapter>
diff --git a/system/doc/getting_started/intro.xml b/system/doc/getting_started/intro.xml
index e8d568bcaf..6ac4f912fe 100644
--- a/system/doc/getting_started/intro.xml
+++ b/system/doc/getting_started/intro.xml
@@ -8,17 +8,18 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
+
</legalnotice>
<title>Introduction</title>
@@ -28,38 +29,47 @@
<rev></rev>
<file>intro.xml</file>
</header>
+ <marker id="getting started"></marker>
+
+ <p>This section is a quick start tutorial to get you started with Erlang.
+ Everything in this section is true, but only part of the truth. For example,
+ only the simplest form of the syntax is shown, not all esoteric forms.
+ Also, parts that are greatly simplified are indicated with *manual*.
+ This means that a lot more information on the subject is to be found in
+ the Erlang book or in
+ <seealso marker="doc/reference_manual:introduction#erlang ref manual">
+ Erlang Reference Manual</seealso>.</p>
<section>
- <title>Introduction</title>
- <p>This is a "kick start" tutorial to get you started with Erlang.
- Everything here is true, but only part of the truth. For example,
- I'll only tell you the simplest form of the syntax, not all
- esoteric forms. Where I've greatly oversimplified things I'll
- write *manual* which means there is lots more information to be
- found in the Erlang book or in the <em>Erlang Reference Manual</em>.</p>
- <p>I also assume that this isn't the first time you have touched a
- computer and you have a basic idea about how they are programmed.
- Don't worry, I won't assume you're a wizard programmer.</p>
+ <title>Prerequisites</title>
+
+ <p>The reader of this section is assumed to be familiar with the following:</p>
+ <list type="bulleted">
+ <item>Computers in general</item>
+ <item>Basics on how computers are programmed</item>
+ </list>
+
</section>
<section>
- <title>Things Left Out</title>
- <p>In particular the following has been omitted:</p>
+ <title>Omitted Topics</title>
+
+ <p>The following topics are not treated in this section:</p>
<list type="bulleted">
- <item>References</item>
- <item>Local error handling (catch/throw)</item>
- <item>Single direction links (monitor)</item>
- <item>Handling of binary data (binaries / bit syntax)</item>
- <item>List comprehensions</item>
- <item>How to communicate with the outside world and/or software
- written in other languages (ports). There is however a separate
- tutorial for this, <em>Interoperability Tutorial</em></item>
- <item>Very few of the Erlang libraries have been touched on (for
- example file handling)</item>
- <item>OTP has been totally skipped and in consequence the Mnesia
- database has been skipped.</item>
- <item>Hash tables for Erlang terms (ETS)</item>
- <item>Changing code in running systems</item>
+ <item>References.</item>
+ <item>Local error handling (catch/throw).</item>
+ <item>Single direction links (monitor).</item>
+ <item>Handling of binary data (binaries / bit syntax).</item>
+ <item>List comprehensions.</item>
+ <item>How to communicate with the outside world and software
+ written in other languages (ports);
+ this is described in
+ <seealso marker="doc/tutorial:introduction#interoperability tutorial">
+ Interoperability Tutorial</seealso>.</item>
+ <item>Erlang libraries (for example, file handling).</item>
+ <item>OTP and (in consequence) the Mnesia database.</item>
+ <item>Hash tables for Erlang terms (ETS).</item>
+ <item>Changing code in running systems.</item>
</list>
</section>
</chapter>
diff --git a/system/doc/getting_started/part.xml b/system/doc/getting_started/part.xml
index c53743baed..4b902f4c63 100644
--- a/system/doc/getting_started/part.xml
+++ b/system/doc/getting_started/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/getting_started/records_macros.xml b/system/doc/getting_started/records_macros.xml
index 73c8ce5c8d..dd2441b64e 100644
--- a/system/doc/getting_started/records_macros.xml
+++ b/system/doc/getting_started/records_macros.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,27 +30,32 @@
<file>record_macros.xml</file>
</header>
<p>Larger programs are usually written as a collection of files with
- a well defined interface between the various parts.</p>
+ a well-defined interface between the various parts.</p>
<section>
<title>The Larger Example Divided into Several Files</title>
- <p>To illustrate this, we will divide the messenger example from
- the previous chapter into five files.</p>
- <taglist>
- <tag><c>mess_config.hrl</c></tag>
- <item>header file for configuration data</item>
- <tag><c>mess_interface.hrl</c></tag>
- <item>interface definitions between the client and the messenger</item>
- <tag><c>user_interface.erl</c></tag>
- <item>functions for the user interface</item>
- <tag><c>mess_client.erl</c></tag>
- <item>functions for the client side of the messenger</item>
- <tag><c>mess_server.erl</c></tag>
- <item>functions for the server side of the messenger</item>
- </taglist>
- <p>While doing this we will also clean up the message passing
- interface between the shell, the client and the server and define
- it using <em>records</em>, we will also introduce <em>macros</em>.</p>
+ <p>To illustrate this, the messenger example from
+ the previous section is divided into the following five files:</p>
+ <list type="bulleted">
+ <item>
+ <p><c>mess_config.hrl</c></p>
+ <p>Header file for configuration data</p></item>
+ <item>
+ <p><c>mess_interface.hrl</c></p>
+ <p>Interface definitions between the client and the messenger</p></item>
+ <item>
+ <p><c>user_interface.erl</c></p>
+ <p>Functions for the user interface</p></item>
+ <item>
+ <p><c>mess_client.erl</c></p>
+ <p>Functions for the client side of the messenger</p></item>
+ <item>
+ <p><c>mess_server.erl</c></p>
+ <p>Functions for the server side of the messenger</p></item>
+ </list>
+ <p>While doing this, the message passing interface between the shell,
+ the client, and the server is cleaned up and is defined
+ using <em>records</em>. Also, <em>macros</em> are introduced:</p>
<code type="none">
%%%----FILE mess_config.hrl----
@@ -244,14 +250,14 @@ server_transfer(From, Name, To, Message, User_List) ->
<section>
<title>Header Files</title>
- <p>You will see some files above with extension <c>.hrl</c>. These
- are header files which are included in the <c>.erl</c> files by:</p>
+ <p>As shown above, some files have extension <c>.hrl</c>. These
+ are header files that are included in the <c>.erl</c> files by:</p>
<code type="none">
-include("File_Name").</code>
<p>for example:</p>
<code type="none">
-include("mess_interface.hrl").</code>
- <p>In our case above the file is fetched from the same directory as
+ <p>In the case above the file is fetched from the same directory as
all the other files in the messenger example. (*manual*).</p>
<p>.hrl files can contain any valid Erlang code but are most often
used for record and macro definitions.</p>
@@ -265,64 +271,63 @@ server_transfer(From, Name, To, Message, User_List) ->
<p>For example:</p>
<code type="none">
-record(message_to,{to_name, message}).</code>
- <p>This is exactly equivalent to:</p>
+ <p>This is equivalent to:</p>
<code type="none">
{message_to, To_Name, Message}</code>
- <p>Creating record, is best illustrated by an example:</p>
+ <p>Creating a record is best illustrated by an example:</p>
<code type="none">
#message_to{message="hello", to_name=fred)</code>
- <p>This will create:</p>
+ <p>This creates:</p>
<code type="none">
{message_to, fred, "hello"}</code>
- <p>Note that you don't have to worry about the order you assign
+ <p>Notice that you do not have to worry about the order you assign
values to the various parts of the records when you create it.
The advantage of using records is that by placing their
definitions in header files you can conveniently define
- interfaces which are easy to change. For example, if you want to
- add a new field to the record, you will only have to change
+ interfaces that are easy to change. For example, if you want to
+ add a new field to the record, you only have to change
the code where the new field is used and not at every place
the record is referred to. If you leave out a field when creating
- a record, it will get the value of the atom undefined. (*manual*)</p>
+ a record, it gets the value of the atom <c>undefined</c>. (*manual*)</p>
<p>Pattern matching with records is very similar to creating
records. For example, inside a <c>case</c> or <c>receive</c>:</p>
<code type="none">
#message_to{to_name=ToName, message=Message} -></code>
- <p>is the same as:</p>
+ <p>This is the same as:</p>
<code type="none">
{message_to, ToName, Message}</code>
</section>
<section>
<title>Macros</title>
- <p>The other thing we have added to the messenger is a macro.
+ <p>Another thing that has been added to the messenger is a macro.
The file <c>mess_config.hrl</c> contains the definition:</p>
<code type="none">
%%% Configure the location of the server node,
-define(server_node, messenger@super).</code>
- <p>We include this file in mess_server.erl:</p>
+ <p>This file is included in <c>mess_server.erl</c>:</p>
<code type="none">
-include("mess_config.hrl").</code>
<p>Every occurrence of <c>?server_node</c> in <c>mess_server.erl</c>
- will now be replaced by <c>messenger@super</c>.</p>
- <p>The other place a macro is used is when we spawn the server
- process:</p>
+ is now replaced by <c>messenger@super</c>.</p>
+ <p>A macro is also used when spawning the server process:</p>
<code type="none">
spawn(?MODULE, server, [])</code>
- <p>This is a standard macro (i.e. defined by the system, not
- the user). <c>?MODULE</c> is always replaced by the name of
- current module (i.e. the <c>-module</c> definition near the start
+ <p>This is a standard macro (that is, defined by the system, not by
+ the user). <c>?MODULE</c> is always replaced by the name of the
+ current module (that is, the <c>-module</c> definition near the start
of the file). There are more advanced ways of using macros with,
- for example parameters (*manual*).</p>
+ for example, parameters (*manual*).</p>
<p>The three Erlang (<c>.erl</c>) files in the messenger example are
individually compiled into object code file (<c>.beam</c>).
The Erlang system loads and links these files into the system
- when they are referred to during execution of the code. In our
- case we simply have put them in the same directory which is our
- current working directory (i.e. the place we have done "cd" to).
+ when they are referred to during execution of the code. In this
+ case, they are simply put in our current working directory
+ (that is, the place you have done "cd" to).
There are ways of putting the <c>.beam</c> files in other
directories.</p>
<p>In the messenger example, no assumptions have been made about
- what the message being sent is. It could be any valid Erlang term.</p>
+ what the message being sent is. It can be any valid Erlang term.</p>
</section>
</chapter>
diff --git a/system/doc/getting_started/robustness.xml b/system/doc/getting_started/robustness.xml
index e8fb81d5e8..abd5892b80 100644
--- a/system/doc/getting_started/robustness.xml
+++ b/system/doc/getting_started/robustness.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,27 +29,27 @@
<rev></rev>
<file>robustness.xml</file>
</header>
- <p>There are several things which are wrong with
- the <seealso marker="conc_prog#ex">messenger example</seealso> from
- the previous chapter. For example, if a node where a user is logged
- on goes down without doing a log off, the user will remain in
- the server's <c>User_List</c> but the client will disappear thus
- making it impossible for the user to log on again as the server
- thinks the user already logged on.</p>
+ <p>Several things are wrong with the messenger example in
+ <seealso marker="conc_prog#ex">A Larger Example</seealso>.
+ For example, if a node where a user is logged
+ on goes down without doing a logoff, the user remains in
+ the server's <c>User_List</c>, but the client disappears. This
+ makes it impossible for the user to log on again as the server
+ thinks the user already is logged on.</p>
<p>Or what happens if the server goes down in the middle of sending a
- message leaving the sending client hanging for ever in
+ message, leaving the sending client hanging forever in
the <c>await_result</c> function?</p>
<section>
- <title>Timeouts</title>
- <p>Before improving the messenger program we will look into some
+ <title>Time-outs</title>
+ <p>Before improving the messenger program, let us look at some
general principles, using the ping pong program as an example.
Recall that when "ping" finishes, it tells "pong" that it has
done so by sending the atom <c>finished</c> as a message to "pong"
- so that "pong" could also finish. Another way to let "pong"
- finish, is to make "pong" exit if it does not receive a message
- from ping within a certain time, this can be done by adding a
- <em>timeout</em> to <c>pong</c> as shown in the following example:</p>
+ so that "pong" can also finish. Another way to let "pong"
+ finish is to make "pong" exit if it does not receive a message
+ from ping within a certain time. This can be done by adding a
+ <em>time-out</em> to <c>pong</c> as shown in the following example:</p>
<code type="none">
-module(tut19).
@@ -80,9 +81,9 @@ start_pong() ->
start_ping(Pong_Node) ->
spawn(tut19, ping, [3, Pong_Node]).</code>
- <p>After we have compiled this and copied the <c>tut19.beam</c>
- file to the necessary directories:</p>
- <p>On (pong@kosken):</p>
+ <p>After this is compiled and the file <c>tut19.beam</c>
+ is copied to the necessary directories, the following is seen
+ on (pong@kosken): </p>
<pre>
(pong@kosken)1> <input>tut19:start_pong().</input>
true
@@ -90,7 +91,7 @@ Pong received ping
Pong received ping
Pong received ping
Pong timed out</pre>
- <p>On (ping@gollum):</p>
+ <p>And the following is seen on (ping@gollum):</p>
<pre>
(ping@gollum)1> <input>tut19:start_ping(pong@kosken).</input>
&lt;0.36.0>
@@ -98,7 +99,7 @@ Ping received pong
Ping received pong
Ping received pong
ping finished </pre>
- <p>(The timeout is set in:</p>
+ <p>The time-out is set in:</p>
<code type="none">
pong() ->
receive
@@ -109,35 +110,36 @@ pong() ->
after 5000 ->
io:format("Pong timed out~n", [])
end.</code>
- <p>We start the timeout (<c>after 5000</c>) when we enter
- <c>receive</c>. The timeout is canceled if <c>{ping,Ping_PID}</c>
+ <p>The time-out (<c>after 5000</c>) is started when
+ <c>receive</c> is entered.
+ The time-out is canceled if <c>{ping,Ping_PID}</c>
is received. If <c>{ping,Ping_PID}</c> is not received,
- the actions following the timeout will be done after 5000
+ the actions following the time-out are done after 5000
milliseconds. <c>after</c> must be last in the <c>receive</c>,
- i.e. preceded by all other message reception specifications in
- the <c>receive</c>. Of course we could also call a function which
- returned an integer for the timeout:</p>
+ that is, preceded by all other message reception specifications in
+ the <c>receive</c>. It is also possible to call a function that
+ returned an integer for the time-out:</p>
<code type="none">
after pong_timeout() -></code>
- <p>In general, there are better ways than using timeouts to
- supervise parts of a distributed Erlang system. Timeouts are
- usually appropriate to supervise external events, for example if
+ <p>In general, there are better ways than using time-outs to
+ supervise parts of a distributed Erlang system. Time-outs are
+ usually appropriate to supervise external events, for example, if
you have expected a message from some external system within a
- specified time. For example, we could use a timeout to log a user
- out of the messenger system if they have not accessed it, for
- example, in ten minutes.</p>
+ specified time. For example, a time-out can be used to log a user
+ out of the messenger system if they have not accessed it for,
+ say, ten minutes.</p>
</section>
<section>
<title>Error Handling</title>
- <p>Before we go into details of the supervision and error handling
- in an Erlang system, we need see how Erlang processes terminate,
+ <p>Before going into details of the supervision and error handling
+ in an Erlang system, let us see how Erlang processes terminate,
or in Erlang terminology, <em>exit</em>.</p>
<p>A process which executes <c>exit(normal)</c> or simply runs out
of things to do has a <em>normal</em> exit.</p>
- <p>A process which encounters a runtime error (e.g. divide by zero,
- bad match, trying to call a function which doesn't exist etc)
- exits with an error, i.e. has an <em>abnormal</em> exit. A
+ <p>A process which encounters a runtime error (for example, divide by zero,
+ bad match, trying to call a function that does not exist and so on)
+ exits with an error, that is, has an <em>abnormal</em> exit. A
process which executes
<seealso marker="erts:erlang#exit/1">exit(Reason)</seealso>
where <c>Reason</c> is any Erlang term except the atom
@@ -151,18 +153,23 @@ after pong_timeout() -></code>
links to.</p>
<p>The signal carries information about the pid it was sent from and
the exit reason.</p>
- <p>The default behaviour of a process which receives a normal exit
+ <p>The default behaviour of a process that receives a normal exit
is to ignore the signal.</p>
- <p>The default behaviour in the two other cases (i.e. abnormal exit)
- above is to bypass all messages to the receiving process and to
- kill it and to propagate the same error signal to the killed
- process' links. In this way you can connect all processes in a
- transaction together using links and if one of the processes
- exits abnormally, all the processes in the transaction will be
- killed. As we often want to create a process and link to it at
+ <p>The default behaviour in the two other cases (that is, abnormal exit)
+ above is to:</p>
+ <list type="bulleted">
+ <item>Bypass all messages to the receiving process.</item>
+ <item>Kill the receiving process.</item>
+ <item>Propagate the same error signal to the links of the
+ killed process.</item>
+ </list>
+ <p>In this way you can connect all processes in a
+ transaction together using links. If one of the processes
+ exits abnormally, all the processes in the transaction are
+ killed. As it is often wanted to create a process and link to it at
the same time, there is a special BIF,
<seealso marker="erts:erlang#spawn_link/1">spawn_link</seealso>
- which does the same as <c>spawn</c>, but also creates a link to
+ that does the same as <c>spawn</c>, but also creates a link to
the spawned process.</p>
<p>Now an example of the ping pong example using links to terminate
"pong":</p>
@@ -208,13 +215,13 @@ Pong received ping
Ping received pong</pre>
<p>This is a slight modification of the ping pong program where both
processes are spawned from the same <c>start/1</c> function,
- where the "ping" process can be spawned on a separate node. Note
+ and the "ping" process can be spawned on a separate node. Notice
the use of the <c>link</c> BIF. "Ping" calls
- <c>exit(ping)</c> when it finishes and this will cause an exit
- signal to be sent to "pong" which will also terminate.</p>
+ <c>exit(ping)</c> when it finishes and this causes an exit
+ signal to be sent to "pong", which also terminates.</p>
<p>It is possible to modify the default behaviour of a process so
that it does not get killed when it receives abnormal exit
- signals, but all signals will be turned into normal messages with
+ signals. Instead, all signals are turned into normal messages on
the format <c>{'EXIT',FromPID,Reason}</c> and added to the end of
the receiving process' message queue. This behaviour is set by:</p>
<code type="none">
@@ -223,8 +230,8 @@ process_flag(trap_exit, true)</code>
<seealso marker="erts:erlang#process_flag/2">erlang(3)</seealso>.
Changing the default behaviour of a process in this way is
usually not done in standard user programs, but is left to
- the supervisory programs in OTP (but that's another tutorial).
- However we will modify the ping pong program to illustrate exit
+ the supervisory programs in OTP.
+ However, the ping pong program is modified to illustrate exit
trapping.</p>
<code type="none">
-module(tut21).
@@ -277,7 +284,7 @@ pong exiting, got {'EXIT',&lt;3820.39.0>,ping}</pre>
<section>
<title>The Larger Example with Robustness Added</title>
- <p>Now we return to the messenger program and add changes which
+ <p>Let us return to the messenger program and add changes to
make it more robust:</p>
<code type="none">
%%% Message passing utility.
@@ -449,35 +456,34 @@ await_result() ->
io:format("No response from server~n", []),
exit(timeout)
end.</code>
- <p>We have added the following changes:</p>
+ <p>The following changes are added:</p>
<p>The messenger server traps exits. If it receives an exit signal,
- <c>{'EXIT',From,Reason}</c> this means that a client process has
- terminated or is unreachable because:</p>
+ <c>{'EXIT',From,Reason}</c>, this means that a client process has
+ terminated or is unreachable for one of the following reasons:</p>
<list type="bulleted">
- <item>the user has logged off (we have removed the "logoff"
- message),</item>
- <item>the network connection to the client is broken,</item>
- <item>the node on which the client process resides has gone down,
- or</item>
- <item>the client processes has done some illegal operation.</item>
+ <item>The user has logged off (the "logoff"
+ message is removed).</item>
+ <item>The network connection to the client is broken.</item>
+ <item>The node on which the client process resides has gone down.</item>
+ <item>The client processes has done some illegal operation.</item>
</list>
- <p>If we receive an exit signal as above, we delete the tuple,
- <c>{From,Name}</c> from the servers <c>User_List</c> using
+ <p>If an exit signal is received as above, the tuple
+ <c>{From,Name}</c> is deleted from the servers <c>User_List</c> using
the <c>server_logoff</c> function. If the node on which the server
runs goes down, an exit signal (automatically generated by
- the system), will be sent to all of the client processes:
+ the system) is sent to all of the client processes:
<c>{'EXIT',MessengerPID,noconnection}</c> causing all the client
processes to terminate.</p>
- <p>We have also introduced a timeout of five seconds in
- the <c>await_result</c> function. I.e. if the server does not
+ <p>Also, a time-out of five seconds has been introduced in
+ the <c>await_result</c> function. That is, if the server does not
reply within five seconds (5000 ms), the client terminates. This
- is really only needed in the logon sequence before the client and
+ is only needed in the logon sequence before the client and the
server are linked.</p>
- <p>An interesting case is if the client was to terminate before
+ <p>An interesting case is if the client terminates before
the server links to it. This is taken care of because linking to a
non-existent process causes an exit signal,
- <c>{'EXIT',From,noproc}</c>, to be automatically generated as if
- the process terminated immediately after the link operation.</p>
+ <c>{'EXIT',From,noproc}</c>, to be automatically generated. This is
+ as if the process terminated immediately after the link operation.</p>
</section>
</chapter>
diff --git a/system/doc/getting_started/seq_prog.xml b/system/doc/getting_started/seq_prog.xml
index 699b9487ed..5698405ed2 100644
--- a/system/doc/getting_started/seq_prog.xml
+++ b/system/doc/getting_started/seq_prog.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,11 +32,15 @@
<section>
<title>The Erlang Shell</title>
- <p>Most operating systems have a command interpreter or shell- Unix
- and Linux have many, while Windows has the Command Prompt. Erlang has
- its own shell where you can directly write bits of Erlang code
- and evaluate (run) them to see what happens (see
- <seealso marker="stdlib:shell">shell(3)</seealso>). Start
+ <p>
+ Most operating systems have a command interpreter or shell, UNIX
+ and Linux have many, Windows has the command prompt. Erlang has
+ its own shell where bits of Erlang code can be written directly,
+ and be evaluated to see what happens
+ (see the <seealso marker="stdlib:shell">shell(3)</seealso>
+ manual page in STDLIB).
+ </p>
+ <p>Start
the Erlang shell (in Linux or UNIX) by starting a shell or
command interpreter in your operating system and typing
<c>erl</c>. You will see something like this.</p>
@@ -45,41 +50,39 @@ Erlang R15B (erts-5.9.1) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe] [ker
Eshell V5.9.1 (abort with ^G)
1></pre>
- <p>Now type in "2 + 5." as shown below.</p>
+ <p>Type "2 + 5." in the shell and then press Enter (carriage return).
+ Notice that you tell the shell you are done entering code by finishing
+ with a full stop "." and a carriage return.</p>
<pre>
1> <input>2 + 5.</input>
7
2></pre>
- <p>In Windows, the shell is started by double-clicking on the Erlang
- shell icon.</p>
- <p>You'll notice that the Erlang shell has numbered the lines that
- can be entered, (as 1&gt; 2&gt;) and that it has correctly told you
- that 2 + 5 is 7! Also notice that you have to tell it you are
- done entering code by finishing with a full stop "." and a
- carriage return. If you make mistakes writing things in the shell,
- you can delete things by using the backspace key as in most
- shells. There are many more editing commands in the shell
- (See the chapter <seealso marker="erts:tty">"tty - A command line interface"</seealso> in ERTS User's Guide).</p>
- <p>(Note: you will find a lot of line numbers given by the shell
- out of sequence in this tutorial as it was written and the code
- tested in several sessions.)</p>
- <p>Now let's try a more complex calculation.</p>
+ <p>As shown, the Erlang shell numbers the lines that
+ can be entered, (as 1&gt; 2&gt;) and that it correctly says
+ that 2 + 5 is 7. If you make writing mistakes in the shell,
+ you can delete with the backspace key, as in most shells.
+ There are many more editing commands in the shell
+ (see <seealso marker="erts:tty">tty - A command line interface</seealso> in ERTS User's Guide).</p>
+ <p>(Notice that many line numbers given by the shell in the
+ following examples are out of sequence. This is because this
+ tutorial was written and code-tested in separate sessions).</p>
+ <p>Here is a bit more complex calculation:</p>
<pre>
2> <input>(42 + 77) * 66 / 3.</input>
2618.0</pre>
- <p>Here you can see the use of brackets and the multiplication
- operator "*" and division operator "/", just as in normal
- arithmetic (see the chapter
- <seealso marker="doc/reference_manual:expressions">"Arithmetic Expressions"</seealso> in the Erlang Reference Manual).</p>
- <p>To shutdown the Erlang system and the Erlang shell type
- Control-C. You will see the following output:</p>
+ <p>Notice the use of brackets, the multiplication operator "*",
+ and the division operator "/", as in normal arithmetic (see
+ <seealso marker="doc/reference_manual:expressions">Expressions</seealso>).</p>
+ <p>Press Control-C to shut down the Erlang system and the Erlang
+ shell.</p>
+ <p>The following output is shown:</p>
<pre>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
<input>a</input>
%</pre>
<p>Type "a" to leave the Erlang system.</p>
- <p>Another way to shutdown the Erlang system is by entering
+ <p>Another way to shut down the Erlang system is by entering
<c>halt()</c>:</p>
<pre>
3> <input>halt().</input>
@@ -88,67 +91,70 @@ BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
<section>
<title>Modules and Functions</title>
- <p>A programming language isn't much use if you can just run code
+ <p>A programming language is not much use if you only can run code
from the shell. So here is a small Erlang program. Enter it into
- a file called <c>tut.erl</c> (the file name <c>tut.erl</c> is
- important, also make sure that it is in the same directory as
- the one where you started <c>erl</c>) using a suitable
- text editor. If you are lucky your editor will have an Erlang
- mode which will make it easier for you to enter and format your
- code nicely (see the chapter
- <seealso marker="tools:erlang_mode_chapter">"The Erlang mode for Emacs"</seealso> in Tools User's Guide), but you can manage
- perfectly well without. Here's the code to enter:</p>
+ a file named <c>tut.erl</c> using a suitable
+ text editor. The file name <c>tut.erl</c> is important, and also
+ that it is in the same directory as the one where you started
+ <c>erl</c>). If you are lucky your editor has an Erlang mode
+ that makes it easier for you to enter and format your code
+ nicely (see <seealso
+ marker="tools:erlang_mode_chapter">The Erlang mode for
+ Emacs</seealso> in Tools User's Guide), but you can manage
+ perfectly well without. Here is the code to enter:</p>
<code type="none">
-module(tut).
-export([double/1]).
double(X) ->
2 * X.</code>
- <p>It's not hard to guess that this "program" doubles the value of
- numbers. I'll get back to the first two lines later. Let's compile
- the program. This can be done in your Erlang shell as shown below:</p>
+ <p>It is not hard to guess that this program doubles the value of
+ numbers. The first two lines of the code are described later.
+ Let us compile the program. This can be done in an Erlang shell
+ as follows, where <c>c</c> means compile:</p>
<pre>
3> <input>c(tut).</input>
{ok,tut}</pre>
- <p>The <c>{ok,tut}</c> tells you that the compilation was OK. If it
- said "error" instead, you have made some mistake in the text you
- entered and there will also be error messages to give you some
- idea as to what has gone wrong so you can change what you have
- written and try again.</p>
- <p>Now let's run the program.</p>
+ <p>The <c>{ok,tut}</c> means that the compilation is OK. If it
+ says "error" it means that there is some mistake in the text
+ that you entered. Additional error messages gives an idea to
+ what is wrong so you can modify the text and then try to compile
+ the program again.</p>
+ <p>Now run the program:</p>
<pre>
4> <input>tut:double(10).</input>
20</pre>
- <p>As expected double of 10 is 20.</p>
- <p>Now let's get back to the first two lines. Erlang programs are
- written in files. Each file contains what we call an Erlang
- <em>module</em>. The first line of code in the module tells us
- the name of the module (see the chapter
- <seealso marker="doc/reference_manual:modules">"Modules"</seealso>
- in the Erlang Reference Manual).</p>
+ <p>As expected, double of 10 is 20.</p>
+ <p>Now let us get back to the first two lines of the code. Erlang
+ programs are
+ written in files. Each file contains an Erlang
+ <em>module</em>. The first line of code in the module is
+ the module name (see
+ <seealso marker="doc/reference_manual:modules">Modules</seealso>):</p>
<code type="none">
-module(tut).</code>
- <p>This tells us that the module is called <em>tut</em>. Note
- the "." at the end of the line. The files which are used to store
+ <p>Thus, the module is called <em>tut</em>. Notice
+ the full stop "." at the end of the line. The files which are
+ used to store
the module must have the same name as the module but with
- the extension ".erl". In our case the file name is <c>tut.erl</c>.
- When we use a function in another module, we use the syntax,
- <c>module_name:function_name(arguments)</c>. So</p>
+ the extension ".erl". In this case the file name is <c>tut.erl</c>.
+ When using a function in another module, the syntax
+ <c>module_name:function_name(arguments)</c> is used. So the
+ following means call function <c>double</c> in module <c>tut</c>
+ with argument "10".</p>
<pre>
4> <input>tut:double(10).</input></pre>
- <p>means call function <c>double</c> in module <c>tut</c> with
- argument "10".</p>
- <p>The second line:</p>
+ <p>The second line says that the module <c>tut</c> contains a
+ function called <c>double</c>, which takes one argument
+ (<c>X</c> in our example):</p>
<code type="none">
-export([double/1]).</code>
- <p>says that the module <c>tut</c> contains a function called
- <c>double</c> which takes one argument (<c>X</c> in our example)
- and that this function can be called from outside the module
- <c>tut</c>. More about this later. Again note the "." at the end
- of the line.</p>
- <p>Now for a more complicated example, the factorial of a number
- (e.g. factorial of 4 is 4 * 3 * 2 * 1). Enter the following code
- in a file called <c>tut1.erl</c>.</p>
+ <p>The second line also says that this function can be called from
+ outside the module <c>tut</c>. More about this later. Again,
+ notice the "." at the end of the line.</p>
+ <p>Now for a more complicated example, the factorial of a number.
+ For example, the factorial of 4 is 4 * 3 * 2 * 1, which equals 24.</p>
+ <p>Enter the following code in a file named <c>tut1.erl</c>:</p>
<code type="none">
-module(tut1).
-export([fac/1]).
@@ -157,30 +163,34 @@ fac(1) ->
1;
fac(N) ->
N * fac(N - 1).</code>
- <p>Compile the file</p>
- <pre>
-5> <input>c(tut1).</input>
-{ok,tut1}</pre>
- <p>And now calculate the factorial of 4.</p>
- <pre>
-6> <input>tut1:fac(4).</input>
-24</pre>
- <p>The first part:</p>
+ <p>So this is a module, called <c>tut1</c> that contains a
+ function called <c>fac></c>, which takes one argument,
+ <c>N</c>.</p>
+ <p>The first part says that the factorial of 1 is 1.:</p>
<code type="none">
fac(1) ->
1;</code>
- <p>says that the factorial of 1 is 1. Note that we end this part
- with a ";" which indicates that there is more of this function to
- come. The second part:</p>
+ <p>Notice that this part ends with a semicolon ";" that indicates
+ that there is more of the function <c>fac></c> to come.</p>
+ <p>The second part says that the factorial of N is N multiplied
+ by the factorial of N - 1:</p>
<code type="none">
fac(N) ->
N * fac(N - 1).</code>
- <p>says that the factorial of N is N multiplied by the factorial of
- N - 1. Note that this part ends with a "." saying that there are
+ <p>Notice that this part ends with a "." saying that there are
no more parts of this function.</p>
- <p>A function can have many arguments. Let's expand the module
- <c>tut1</c> with the rather stupid function to multiply two
- numbers:</p>
+ <p>Compile the file:</p>
+ <pre>
+5> <input>c(tut1).</input>
+{ok,tut1}</pre>
+ <p>And now calculate the factorial of 4.</p>
+ <pre>
+6> <input>tut1:fac(4).</input>
+24</pre>
+ <p>Here the function <c>fac></c> in module <c>tut1</c> is called
+ with argument <c>4</c>.</p>
+ <p>A function can have many arguments. Let us expand the module
+ <c>tut1</c> with the function to multiply two numbers:</p>
<code type="none">
-module(tut1).
-export([fac/1, mult/2]).
@@ -192,36 +202,36 @@ fac(N) ->
mult(X, Y) ->
X * Y.</code>
- <p>Note that we have also had to expand the <c>-export</c> line
+ <p>Notice that it is also required to expand the <c>-export</c> line
with the information that there is another function <c>mult</c>
with two arguments.</p>
<p>Compile:</p>
<pre>
7> <input>c(tut1).</input>
{ok,tut1}</pre>
- <p>and try it out:</p>
+ <p>Try out the new function <c>mult</c>:</p>
<pre>
8> <input>tut1:mult(3,4).</input>
12</pre>
- <p>In the example above the numbers are integers and the arguments
- in the functions in the code, <c>N</c>, <c>X</c>, <c>Y</c> are
+ <p>In this example the numbers are integers and the arguments
+ in the functions in the code <c>N</c>, <c>X</c>, and <c>Y</c> are
called variables. Variables must start with a capital letter
- (see the chapter
- <seealso marker="doc/reference_manual:expressions">"Variables"</seealso>
- in the Erlang Reference Manual). Examples of variables could be
- <c>Number</c>, <c>ShoeSize</c>, <c>Age</c> etc.</p>
+ (see
+ <seealso marker="doc/reference_manual:expressions">Variables</seealso>).
+ Examples of variables are
+ <c>Number</c>, <c>ShoeSize</c>, and <c>Age</c>.</p>
</section>
<section>
<title>Atoms</title>
- <p>Atoms are another data type in Erlang. Atoms start with a small
- letter ((see the chapter
- <seealso marker="doc/reference_manual:data_types">"Atom"</seealso>
- in the Erlang Reference Manual)), for example: <c>charles</c>,
- <c>centimeter</c>, <c>inch</c>. Atoms are simply names, nothing
- else. They are not like variables which can have a value.</p>
- <p>Enter the next program (file: <c>tut2.erl</c>) which could be
- useful for converting from inches to centimeters and vice versa:</p>
+ <p>Atom is another data type in Erlang. Atoms start with a small
+ letter (see
+ <seealso marker="doc/reference_manual:data_types">Atom</seealso>),
+ for example, <c>charles</c>,
+ <c>centimeter</c>, and <c>inch</c>. Atoms are simply names, nothing
+ else. They are not like variables, which can have a value.</p>
+ <p>Enter the next program in a file named <c>tut2.erl</c>). It can be
+ useful for converting from inches to centimeters and conversely:</p>
<code type="none">
-module(tut2).
-export([convert/2]).
@@ -231,27 +241,30 @@ convert(M, inch) ->
convert(N, centimeter) ->
N * 2.54.</code>
- <p>Compile and test:</p>
+ <p>Compile:</p>
<pre>
9> <input>c(tut2).</input>
{ok,tut2}
+</pre>
+ <p>Test:</p>
+ <pre>
10> <input>tut2:convert(3, inch).</input>
1.1811023622047243
11> <input>tut2:convert(7, centimeter).</input>
17.78</pre>
- <p>Notice that I have introduced decimals (floating point numbers)
- without any explanation, but I guess you can cope with that.</p>
- <p>See what happens if I enter something other than centimeter or
- inch in the convert function:</p>
+ <p>Notice the introduction of decimals (floating point numbers)
+ without any explanation. Hopefully you can cope with that.</p>
+ <p>Let us see what happens if something other than <c>centimeter</c> or
+ <c>inch</c> is entered in the <c>convert</c> function:</p>
<pre>
12> <input>tut2:convert(3, miles).</input>
** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)</pre>
<p>The two parts of the <c>convert</c> function are called its
- clauses. Here we see that "miles" is not part of either of
- the clauses. The Erlang system can't <em>match</em> either of
- the clauses so we get an error message <c>function_clause</c>.
- The shell formats the error message nicely, but the error tuple
- is saved in the shell's history list and can be output by the shell
+ clauses. As shown, <c>miles</c> is not part of either of
+ the clauses. The Erlang system cannot <em>match</em> either of
+ the clauses so an error message <c>function_clause</c> is returned.
+ The shell formats the error message nicely, but the error tuple
+ is saved in the shell's history list and can be output by the shell
command <c>v/1</c>:</p>
<pre>
13> <input>v(12).</input>
@@ -271,14 +284,15 @@ convert(N, centimeter) ->
Consider:</p>
<code type="none">
tut2:convert(3, inch).</code>
- <p>Does this mean that 3 is in inches? Or that 3 is in centimeters
- and we want to convert it to inches? So Erlang has a way to group
- things together to make things more understandable. We call these
- <em>tuples</em>. Tuples are surrounded by "{" and "}".</p>
- <p>So we can write <c>{inch,3}</c> to denote 3 inches and
- <c>{centimeter,5}</c> to denote 5 centimeters. Now let's write a
- new program which converts centimeters to inches and vice versa.
- (file <c>tut3.erl</c>).</p>
+ <p>Does this mean that 3 is in inches? Or does it mean that 3 is
+ in centimeters
+ and is to be converted to inches? Erlang has a way to group
+ things together to make things more understandable. These are called
+ <em>tuples</em> and are surrounded by curly brackets, "{" and "}".</p>
+ <p>So, <c>{inch,3}</c> denotes 3 inches and
+ <c>{centimeter,5}</c> denotes 5 centimeters. Now let us write a
+ new program that converts centimeters to inches and conversely.
+ Enter the following code in a file called <c>tut3.erl</c>):</p>
<code type="none">
-module(tut3).
-export([convert_length/1]).
@@ -295,47 +309,48 @@ convert_length({inch, Y}) ->
{centimeter,12.7}
16> <input>tut3:convert_length(tut3:convert_length({inch, 5})).</input>
{inch,5.0}</pre>
- <p>Note on line 16 we convert 5 inches to centimeters and back
- again and reassuringly get back to the original value. I.e
+ <p>Notice on line 16 that 5 inches is converted to centimeters and back
+ again and reassuringly get back to the original value. That is,
the argument to a function can be the result of another function.
- Pause for a moment and consider how line 16 (above) works.
- The argument we have given the function <c>{inch,5}</c> is first
- matched against the first head clause of <c>convert_length</c>
- i.e. <c>convert_length({centimeter,X})</c> where it can be seen
+ Consider how line 16 (above) works.
+ The argument given to the function <c>{inch,5}</c> is first
+ matched against the first head clause of <c>convert_length</c>,
+ that is, <c>convert_length({centimeter,X})</c>. It can be seen
that <c>{centimeter,X}</c> does not match <c>{inch,5}</c>
- (the head is the bit before the "-&gt;"). This having failed, we try
- the head of the next clause i.e. <c>convert_length({inch,Y})</c>,
- this matches and <c>Y</c> get the value 5.</p>
- <p>We have shown tuples with two parts above, but tuples can have
- as many parts as we want and contain any valid Erlang
+ (the head is the bit before the "-&gt;"). This having failed,
+ let us try
+ the head of the next clause that is, <c>convert_length({inch,Y})</c>.
+ This matches, and <c>Y</c> gets the value 5.</p>
+ <p>Tuples can have more than two parts, in fact
+ as many parts as you want, and contain any valid Erlang
<em>term</em>. For example, to represent the temperature of
- various cities of the world we could write:</p>
+ various cities of the world:</p>
<code type="none">
{moscow, {c, -10}}
{cape_town, {f, 70}}
{paris, {f, 28}}</code>
- <p>Tuples have a fixed number of things in them. We call each thing
- in a tuple an element. So in the tuple <c>{moscow,{c,-10}}</c>,
- element 1 is <c>moscow</c> and element 2 is <c>{c,-10}</c>. I
- have chosen <c>c</c> meaning Centigrade (or Celsius) and <c>f</c>
- meaning Fahrenheit.</p>
+ <p>Tuples have a fixed number of items in them. Each item in a
+ tuple is called an <em>element</em>. In the tuple
+ <c>{moscow,{c,-10}}</c>, element 1 is <c>moscow</c> and element
+ 2 is <c>{c,-10}</c>. Here <c>c</c> represents Celsius and
+ <c>f</c> Fahrenheit.</p>
</section>
<section>
<title>Lists</title>
- <p>Whereas tuples group things together, we also want to be able to
- represent lists of things. Lists in Erlang are surrounded by "["
- and "]". For example, a list of the temperatures of various cities
- in the world could be:</p>
+ <p>Whereas tuples group things together, it is also needed to
+ represent lists of things. Lists in Erlang are surrounded by
+ square brackets, "[" and "]". For example, a list of the
+ temperatures of various cities in the world can be:</p>
<code type="none">
[{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},
{paris, {f, 28}}, {london, {f, 36}}]</code>
- <p>Note that this list was so long that it didn't fit on one line.
- This doesn't matter, Erlang allows line breaks at all "sensible
- places" but not, for example, in the middle of atoms, integers
- etc.</p>
- <p>A very useful way of looking at parts of lists, is by using "|".
- This is best explained by an example using the shell.</p>
+ <p>Notice that this list was so long that it did not fit on one line.
+ This does not matter, Erlang allows line breaks at all "sensible
+ places" but not, for example, in the middle of atoms, integers,
+ and others.</p>
+ <p>A useful way of looking at parts of lists, is by using "|".
+ This is best explained by an example using the shell:</p>
<pre>
17> <input>[First |TheRest] = [1,2,3,4,5].</input>
[1,2,3,4,5]
@@ -343,9 +358,9 @@ convert_length({inch, Y}) ->
1
19> <input>TheRest.</input>
[2,3,4,5]</pre>
- <p>We use | to separate the first elements of the list from
- the rest of the list. (<c>First</c> has got value 1 and
- <c>TheRest</c> value [2,3,4,5].)</p>
+ <p>To separate the first elements of the list from the rest of the
+ list, <c>|</c> is used. <c>First</c> has got value 1 and
+ <c>TheRest</c> has got the value [2,3,4,5].</p>
<p>Another example:</p>
<pre>
20> <input>[E1, E2 | R] = [1,2,3,4,5,6,7].</input>
@@ -356,10 +371,10 @@ convert_length({inch, Y}) ->
2
23> <input>R.</input>
[3,4,5,6,7]</pre>
- <p>Here we see the use of | to get the first two elements from
- the list. Of course if we try to get more elements from the list
- than there are elements in the list we will get an error. Note
- also the special case of the list with no elements [].</p>
+ <p>Here you see the use of <c>|</c> to get the first two elements from
+ the list. If you try to get more elements from the list
+ than there are elements in the list, an error is returned. Notice
+ also the special case of the list with no elements, []:</p>
<pre>
24> <input>[A, B | C] = [1, 2].</input>
[1,2]
@@ -369,13 +384,13 @@ convert_length({inch, Y}) ->
2
27> <input>C.</input>
[]</pre>
- <p>In all the examples above, I have been using new variable names,
- not reusing the old ones: <c>First</c>, <c>TheRest</c>, <c>E1</c>,
- <c>E2</c>, <c>R</c>, <c>A</c>, <c>B</c>, <c>C</c>. The reason
+ <p>In the previous examples, new variable names are used, instead of
+ reusing the old ones: <c>First</c>, <c>TheRest</c>, <c>E1</c>,
+ <c>E2</c>, <c>R</c>, <c>A</c>, <c>B</c>, and <c>C</c>. The reason
for this is that a variable can only be given a value once in its
- context (scope). I'll get back to this later, it isn't so
- peculiar as it sounds!</p>
- <p>The following example shows how we find the length of a list:</p>
+ context (scope). More about this later.</p>
+ <p>The following example shows how to find the length of a list.
+ Enter the following code in a file named <c>tut4.erl</c>):</p>
<code type="none">
-module(tut4).
@@ -385,7 +400,7 @@ list_length([]) ->
0;
list_length([First | Rest]) ->
1 + list_length(Rest).</code>
- <p>Compile (file <c>tut4.erl</c>) and test:</p>
+ <p>Compile and test:</p>
<pre>
28> <input>c(tut4).</input>
{ok,tut4}
@@ -404,14 +419,14 @@ list_length([First | Rest]) ->
<c>Rest</c>.</p>
<p>(Advanced readers only: This is not tail recursive, there is a
better way to write this function.)</p>
- <p>In general we can say we use tuples where we would use "records"
- or "structs" in other languages and we use lists when we want to
- represent things which have varying sizes, (i.e. where we would
- use linked lists in other languages).</p>
- <p>Erlang does not have a string data type, instead strings can be
- represented by lists of ASCII characters. So the list
- <c>[97,98,99]</c> is equivalent to "abc". The Erlang shell is
- "clever" and guesses the what sort of list we mean and outputs it
+ <p>In general, tuples are used where "records"
+ or "structs" are used in other languages. Also, lists are used when
+ representing things with varying sizes, that is, where
+ linked lists are used in other languages.</p>
+ <p>Erlang does not have a string data type. Instead, strings can be
+ represented by lists of Unicode characters. This implies for example that
+ the list <c>[97,98,99]</c> is equivalent to "abc". The Erlang shell is
+ "clever" and guesses what list you mean and outputs it
in what it thinks is the most appropriate form, for example:</p>
<pre>
30> <input>[97,98,99].</input>
@@ -420,16 +435,17 @@ list_length([First | Rest]) ->
<section>
<title>Maps</title>
- <p>Maps are a set of key to value associations. These associations
- are encapsulated with "#{" and "}". To create an association from
- "key" to value 42, we write:</p>
+ <p>Maps are a set of key to value associations. These associations
+ are encapsulated with "#{" and "}". To create an association
+ from "key" to value 42:</p>
<code type="none">
> #{ "key" => 42 }.
#{"key" => 42}</code>
- <p>We will jump straight into the deep end with an example using some
- interesting features.</p>
- <p>The following example shows how we calculate alpha blending using
- maps to reference color and alpha channels:</p>
+ <p>Let us jump straight into the deep end with an example using some
+ interesting features.</p>
+ <p>The following example shows how to calculate alpha blending
+ using maps to reference color and alpha channels. Enter the code
+ in a file named <c>color.erl</c>):</p>
<code type="none">
-module(color).
@@ -468,7 +484,7 @@ green(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) ->
SV*SA + DV*DA*(1.0 - SA).
blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) ->
SV*SA + DV*DA*(1.0 - SA).</code>
- <p>Compile (file <c>color.erl</c>) and test:</p>
+ <p>Compile and test:</p>
<pre>
> <input>c(color).</input>
{ok,color}
@@ -484,50 +500,48 @@ blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) ->
<p>This example warrants some explanation:</p>
<code type="none">
-define(is_channel(V), (is_float(V) andalso V &gt;= 0.0 andalso V =&lt; 1.0)).</code>
- <p>
- First we define a macro <c>is_channel</c> to help with our guard tests.
- This is only here for convenience and to reduce syntax cluttering.
-
- You can read more about <seealso marker="doc/reference_manual:macros">Macros</seealso>
- in the Erlang Reference Manual.
- </p>
+ <p>First a macro <c>is_channel</c> is defined to help with the
+ guard tests. This is only here for convenience and to reduce
+ syntax cluttering. For more information about macros, see
+ <seealso marker="doc/reference_manual:macros">
+ The Preprocessor</seealso>.
+ </p>
<code type="none">
new(R,G,B,A) when ?is_channel(R), ?is_channel(G),
?is_channel(B), ?is_channel(A) ->
#{red =&gt; R, green =&gt; G, blue =&gt; B, alpha =&gt; A}.</code>
- <p>
- The function <c>new/4</c> creates a new map term with and lets the keys
- <c>red</c>, <c>green</c>, <c>blue</c> and <c>alpha</c> be associated
- with an initial value. In this case we only allow for float
- values between and including 0.0 and 1.0 as ensured by the <c>?is_channel/1</c> macro
- for each argument. Only the <c>=></c> operator is allowed when creating a new map.
+ <p>The function <c>new/4</c> creates a new map term and lets the keys
+ <c>red</c>, <c>green</c>, <c>blue</c>, and <c>alpha</c> be
+ associated with an initial value. In this case, only float
+ values between and including 0.0 and 1.0 are allowed, as ensured
+ by the <c>?is_channel/1</c> macro for each argument. Only the
+ <c>=></c> operator is allowed when creating a new map.
+ </p>
+ <p>By calling <c>blend/2</c> on any color term created by
+ <c>new/4</c>, the resulting color can be calculated as
+ determined by the two map terms.
+ </p>
+ <p>The first thing <c>blend/2</c> does is to calculate the
+ resulting alpha channel:
</p>
- <p>
- By calling <c>blend/2</c> on any color term created by <c>new/4</c> we can calculate
- the resulting color as determined by the two maps terms.
- </p>
- <p>
- The first thing <c>blend/2</c> does is to calculate the resulting alpha channel.
- </p>
<code type="none">
alpha(#{alpha := SA}, #{alpha := DA}) ->
SA + DA*(1.0 - SA).</code>
- <p>
- We fetch the value associated with key <c>alpha</c> for both arguments using
- the <c>:=</c> operator. Any other keys
- in the map are ignored, only the key <c>alpha</c> is required and checked for.
- </p>
- <p>This is also the case for functions <c>red/2</c>, <c>blue/2</c> and <c>green/2</c>.</p>
+ <p>The value associated with key <c>alpha</c> is fetched for both
+ arguments using the <c>:=</c> operator. The other keys in the
+ map are ignored, only the key <c>alpha</c> is required and
+ checked for.
+ </p>
+ <p>This is also the case for functions <c>red/2</c>,
+ <c>blue/2</c>, and <c>green/2</c>.</p>
<code type="none">
red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->
SV*SA + DV*DA*(1.0 - SA).</code>
- <p>
- The difference here is that we check for two keys in each map argument. The other keys
- are ignored.
- </p>
- <p>
- Finally we return the resulting color in <c>blend/3</c>.
- </p>
+ <p>The difference here is that a check is made for two keys in
+ each map argument. The other keys are ignored.
+ </p>
+ <p>Finally, let us return the resulting color in <c>blend/3</c>:
+ </p>
<code type="none">
blend(Src,Dst,Alpha) when Alpha > 0.0 ->
Dst#{
@@ -536,20 +550,20 @@ blend(Src,Dst,Alpha) when Alpha > 0.0 ->
blue := blue(Src,Dst) / Alpha,
alpha := Alpha
};</code>
- <p>
- We update the <c>Dst</c> map with new channel values. The syntax for updating an existing key with a new value is done with <c>:=</c> operator.
- </p>
+ <p>The <c>Dst</c> map is updated with new channel values. The
+ syntax for updating an existing key with a new value is with the
+ <c>:=</c> operator.
+ </p>
</section>
<section>
<title>Standard Modules and Manual Pages</title>
- <p>Erlang has a lot of standard modules to help you do things. For
- example, the module <c>io</c> contains a lot of functions to help
- you do formatted input/output. To look up information about
- standard modules, the command <c>erl -man</c> can be used at
- the operating shell or command prompt (i.e. at the same place as
- that where you started <c>erl</c>). Try the operating system
- shell command:</p>
+ <p>Erlang has many standard modules to help you do things. For
+ example, the module <c>io</c> contains many functions that help
+ in doing formatted input/output. To look up information about
+ standard modules, the command <c>erl -man</c> can be used at the
+ operating shell or command prompt (the same place as you started
+ <c>erl</c>). Try the operating system shell command:</p>
<pre>
% <input>erl -man io</input>
ERLANG MODULE DEFINITION io(3)
@@ -561,21 +575,21 @@ DESCRIPTION
This module provides an interface to standard Erlang IO
servers. The output functions all return ok if they are suc-
...</pre>
- <p>If this doesn't work on your system, the documentation is
- included as HTML in the Erlang/OTP release, or you can read
+ <p>If this does not work on your system, the documentation is
+ included as HTML in the Erlang/OTP release. You can also read
the documentation as HTML or download it as PDF from either of
the sites www.erlang.se (commercial Erlang) or www.erlang.org
- (open source), for example for release R9B:</p>
+ (open source). For example, for Erlang/OTP release R9B:</p>
<code type="none">
http://www.erlang.org/doc/r9b/doc/index.html</code>
</section>
<section>
<title>Writing Output to a Terminal</title>
- <p>It's nice to be able to do formatted output in these example, so
+ <p>It is nice to be able to do formatted output in examples, so
the next example shows a simple way to use the <c>io:format</c>
- function. Of course, just like all other exported functions, you
- can test the <c>io:format</c> function in the shell:</p>
+ function. Like all other exported functions, you can test the
+ <c>io:format</c> function in the shell:</p>
<pre>
31> <input>io:format("hello world~n", []).</input>
hello world
@@ -589,28 +603,28 @@ ok
34> <input>io:format("this outputs two Erlang terms: ~w ~w~n", [hello, world]).</input>
this outputs two Erlang terms: hello world
ok</pre>
- <p>The function <c>format/2</c> (i.e. <c>format</c> with two
+ <p>The function <c>format/2</c> (that is, <c>format</c> with two
arguments) takes two lists. The first one is nearly always a list
- written between " ". This list is printed out as it stands,
+ written between " ". This list is printed out as it is,
except that each ~w is replaced by a term taken in order from
the second list. Each ~n is replaced by a new line.
The <c>io:format/2</c> function itself returns the atom <c>ok</c>
if everything goes as planned. Like other functions in Erlang, it
crashes if an error occurs. This is not a fault in Erlang, it is
a deliberate policy. Erlang has sophisticated mechanisms to
- handle errors which we will show later. As an exercise, try to
- make <c>io:format</c> crash, it shouldn't be difficult. But
+ handle errors which are shown later. As an exercise, try to
+ make <c>io:format</c> crash, it should not be difficult. But
notice that although <c>io:format</c> crashes, the Erlang shell
itself does not crash.</p>
</section>
<section>
<title>A Larger Example</title>
- <p>Now for a larger example to consolidate what we have learnt so
- far. Assume we have a list of temperature readings from a number
- of cities in the world. Some of them are in Celsius (Centigrade)
- and some in Fahrenheit (as in the previous list). First let's
- convert them all to Celsius, then let's print out the data neatly.</p>
+ <p>Now for a larger example to consolidate what you have learnt so
+ far. Assume that you have a list of temperature readings from a number
+ of cities in the world. Some of them are in Celsius
+ and some in Fahrenheit (as in the previous list). First let us
+ convert them all to Celsius, then let us print the data neatly.</p>
<code type="none">
%% This module is in file tut5.erl
@@ -642,50 +656,50 @@ stockholm -4 c
paris -2.2222222222222223 c
london 2.2222222222222223 c
ok</pre>
- <p>Before we look at how this program works, notice that we have
- added a few comments to the code. A comment starts with a %
- character and goes on to the end of the line. Note as well that
+ <p>Before looking at how this program works, notice that
+ a few comments are added to the code. A comment starts with a
+ %-character and goes on to the end of the line. Notice also that
the <c>-export([format_temps/1]).</c> line only includes
- the function <c>format_temps/1</c>, the other functions are
- <em>local</em> functions, i.e. they are not visible from outside
+ the function <c>format_temps/1</c>. The other functions are
+ <em>local</em> functions, that is, they are not visible from outside
the module <c>tut5</c>.</p>
- <p>Note as well that when testing the program from the shell, I had
- to spread the input over two lines as the line was too long.</p>
- <p>When we call <c>format_temps</c> the first time, <c>City</c>
+ <p>Notice also that when testing the program from the shell,
+ the input is spread over two lines as the line was too long.</p>
+ <p>When <c>format_temps</c> is called the first time, <c>City</c>
gets the value <c>{moscow,{c,-10}}</c> and <c>Rest</c> is
- the rest of the list. So we call the function
- <c>print_temp(convert_to_celsius({moscow,{c,-10}}))</c>.</p>
- <p>Here we see a function call as
+ the rest of the list. So the function
+ <c>print_temp(convert_to_celsius({moscow,{c,-10}}))</c> is called.</p>
+ <p>Here is a function call as
<c>convert_to_celsius({moscow,{c,-10}})</c> as the argument to
- the function <c>print_temp</c>. When we <em>nest</em> function
- calls like this we execute (evaluate) them from the inside out.
- I.e. we first evaluate <c>convert_to_celsius({moscow,{c,-10}})</c>
+ the function <c>print_temp</c>. When function calls are <em>nested</em>
+ like this, they execute (evaluate) from the inside out.
+ That is, first <c>convert_to_celsius({moscow,{c,-10}})</c> is evaluated,
which gives the value <c>{moscow,{c,-10}}</c> as the temperature
- is already in Celsius and then we evaluate
- <c>print_temp({moscow,{c,-10}})</c>. The function
- <c>convert_to_celsius</c> works in a similar way to
+ is already in Celsius. Then <c>print_temp({moscow,{c,-10}})</c>
+ is evaluated.
+ The function <c>convert_to_celsius</c> works in a similar way to
the <c>convert_length</c> function in the previous example.</p>
<p><c>print_temp</c> simply calls <c>io:format</c> in a similar way
- to what has been described above. Note that ~-15w says to print
+ to what has been described above. Notice that ~-15w says to print
the "term" with a field length (width) of 15 and left justify it.
- (<seealso marker="stdlib:io#fwrite/1">io(3)</seealso>).</p>
- <p>Now we call <c>format_temps(Rest)</c> with the rest of the list
+ (see the <seealso marker="stdlib:io#fwrite/1">io(3)</seealso>) manual page in STDLIB.</p>
+ <p>Now <c>format_temps(Rest)</c> is called with the rest of the list
as an argument. This way of doing things is similar to the loop
- constructs in other languages. (Yes, this is recursion, but don't
+ constructs in other languages. (Yes, this is recursion, but do not
let that worry you.) So the same <c>format_temps</c> function is
called again, this time <c>City</c> gets the value
- <c>{cape_town,{f,70}}</c> and we repeat the same procedure as
- before. We go on doing this until the list becomes empty, i.e. [],
+ <c>{cape_town,{f,70}}</c> and the same procedure is repeated as
+ before. This is done until the list becomes empty, that is [],
which causes the first clause <c>format_temps([])</c> to match.
This simply returns (results in) the atom <c>ok</c>, so
the program ends.</p>
</section>
<section>
- <title>Matching, Guards and Scope of Variables</title>
- <p>It could be useful to find the maximum and minimum temperature
+ <title>Matching, Guards, and Scope of Variables</title>
+ <p>It can be useful to find the maximum and minimum temperature
in lists like this. Before extending the program to do this,
- let's look at functions for finding the maximum value of
+ let us look at functions for finding the maximum value of
the elements in a list:</p>
<code type="none">
-module(tut6).
@@ -705,53 +719,57 @@ list_max([Head|Rest], Result_so_far) ->
{ok,tut6}
38> <input>tut6:list_max([1,2,3,4,5,7,4,3,2,1]).</input>
7</pre>
- <p>First note that we have two functions here with the same name
- <c>list_max</c>. However each of these takes a different number
+ <p>First notice that two functions have the same name,
+ <c>list_max</c>. However, each of these takes a different number
of arguments (parameters). In Erlang these are regarded as
- completely different functions. Where we need to distinguish
- between these functions we write <c>name/arity</c>, where
- <c>name</c> is the name of the function and <c>arity</c> is
+ completely different functions. Where you need to distinguish
+ between these functions, you write Name/Arity, where
+ Name is the function name and Arity is
the number of arguments, in this case <c>list_max/1</c> and
<c>list_max/2</c>.</p>
- <p>This is an example where we walk through a list "carrying" a
- value with us, in this case <c>Result_so_far</c>.
+ <p>In this example you walk through a list "carrying" a
+ value, in this case <c>Result_so_far</c>.
<c>list_max/1</c> simply assumes that the max value of the list
is the head of the list and calls <c>list_max/2</c> with the rest
- of the list and the value of the head of the list, in the above
- this would be <c>list_max([2,3,4,5,7,4,3,2,1],1)</c>. If we tried
+ of the list and the value of the head of the list. In the above
+ this would be <c>list_max([2,3,4,5,7,4,3,2,1],1)</c>. If you tried
to use <c>list_max/1</c> with an empty list or tried to use it
- with something which isn't a list at all, we would cause an error.
- Note that the Erlang philosophy is not to handle errors of this
+ with something that is not a list at all, you would cause an error.
+ Notice that the Erlang philosophy is not to handle errors of this
type in the function they occur, but to do so elsewhere. More
about this later.</p>
- <p>In <c>list_max/2</c> we walk down the list and use <c>Head</c>
+ <p>In <c>list_max/2</c>, you walk down the list and use <c>Head</c>
instead of <c>Result_so_far</c> when <c>Head</c> &gt;
- <c>Result_so_far</c>. <c>when</c> is a special word we use before
- the -&gt; in the function to say that we should only use this part
- of the function if the test which follows is true. We call tests
- of this type a <em>guard</em>. If the guard isn't true (we say
- the guard fails), we try the next part of the function. In this
- case if <c>Head</c> isn't greater than <c>Result_so_far</c> then
- it must be smaller or equal to is, so we don't need a guard on
- the next part of the function.</p>
- <p>Some useful operators in guards are, &lt; less than, &gt;
- greater than, == equal, &gt;= greater or equal, =&lt; less or
- equal, /= not equal. (See the chapter
- <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual.)</p>
- <p>To change the above program to one which works out the minimum
- value of the element in a list, all we would need to do is to
+ <c>Result_so_far</c>. <c>when</c> is a special word used before
+ the -&gt; in the function to say that you only use this part
+ of the function if the test that follows is true. A test
+ of this type is called <em>guard</em>. If the guard is false (that is,
+ the guard fails), the next part of the function is tried. In this
+ case, if <c>Head</c> is not greater than <c>Result_so_far</c>, then
+ it must be smaller or equal to it. This means that a guard on
+ the next part of the function is not needed.</p>
+ <p>Some useful operators in guards are:
+ </p><list type="bulleted"><item>&lt; less than</item>
+ <item>&gt; greater than</item>
+ <item>== equal</item>
+ <item>&gt;= greater or equal</item>
+ <item>=&lt; less or equal</item>
+ <item>/= not equal</item></list>
+ <p>(see <seealso marker="doc/reference_manual:expressions">Guard Sequences</seealso>).</p>
+ <p>To change the above program to one that works out the minimum
+ value of the element in a list, you only need to
write &lt; instead of &gt;. (But it would be wise to change
- the name of the function to <c>list_min</c> :-).)</p>
- <p>Remember that I mentioned earlier that a variable could only be
- given a value once in its scope? In the above we see, for example,
- that <c>Result_so_far</c> has been given several values. This is
- OK since every time we call <c>list_max/2</c> we create a new
- scope and one can regard the <c>Result_so_far</c> as a completely
+ the name of the function to <c>list_min</c>.)</p>
+ <p>Earlier it was mentioned that a variable can only be
+ given a value once in its scope. In the above you see
+ that <c>Result_so_far</c> is given several values. This is
+ OK since every time you call <c>list_max/2</c> you create a new
+ scope and one can regard <c>Result_so_far</c> as a
different variable in each scope.</p>
<p>Another way of creating and giving a variable a value is by using
- the match operator = . So if I write <c>M = 5</c>, a variable
- called <c>M</c> will be created and given the value 5. If, in
- the same scope I then write <c>M = 6</c>, I'll get an error. Try
+ the match operator = . So if you write <c>M = 5</c>, a variable
+ called <c>M</c> is created with the value 5. If, in
+ the same scope, you then write <c>M = 6</c>, an error is returned. Try
this out in the shell:</p>
<pre>
39> <input>M = 5.</input>
@@ -771,21 +789,21 @@ list_max([Head|Rest], Result_so_far) ->
paris
45> <input>Y.</input>
{f,28}</pre>
- <p>Here we see that <c>X</c> gets the value <c>paris</c> and
+ <p>Here <c>X</c> gets the value <c>paris</c> and
<c>Y</c><c>{f,28}</c>.</p>
- <p>Of course if we try to do the same again with another city, we
- get an error:</p>
+ <p>If you try to do the same again with another city,
+ an error is returned:</p>
<pre>
46> <input>{X, Y} = {london, {f, 36}}.</input>
** exception error: no match of right hand side value {london,{f,36}}</pre>
<p>Variables can also be used to improve the readability of
- programs, for example, in the <c>list_max/2</c> function above,
- we could write:</p>
+ programs. For example, in function <c>list_max/2</c> above,
+ you can write:</p>
<code type="none">
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
New_result_far = Head,
list_max(Rest, New_result_far);</code>
- <p>which is possibly a little clearer.</p>
+ <p>This is possibly a little clearer.</p>
</section>
<section>
@@ -824,9 +842,9 @@ reverse([], Reversed_List) ->
{ok,tut8}
53> <input>tut8:reverse([1,2,3]).</input>
[3,2,1]</pre>
- <p>Consider how <c>Reversed_List</c> is built. It starts as [], we
- then successively take off the heads of the list to be reversed
- and add them to the the <c>Reversed_List</c>, as shown in
+ <p>Consider how <c>Reversed_List</c> is built. It starts as [],
+ then successively the heads are taken off of the list to be reversed
+ and added to the the <c>Reversed_List</c>, as shown in
the following:</p>
<code type="none">
reverse([1|2,3], []) =>
@@ -840,14 +858,15 @@ reverse([3|[]], [2,1]) =>
reverse([], [3,2,1]) =>
[3,2,1]</code>
- <p>The module <c>lists</c> contains a lot of functions for
- manipulating lists, for example for reversing them, so before you
- write a list manipulating function it is a good idea to check
- that one isn't already written for you. (see
- <seealso marker="stdlib:lists">lists(3)</seealso>).</p>
- <p>Now let's get back to the cities and temperatures, but take a more
- structured approach this time. First let's convert the whole list
- to Celsius as follows and test the function:</p>
+ <p>The module <c>lists</c> contains many functions for
+ manipulating lists, for example, for reversing them. So before
+ writing a list-manipulating function it is a good idea to check
+ if one not already is written for you
+ (see the <seealso marker="stdlib:lists">lists(3)</seealso>
+ manual page in STDLIB).</p>
+ <p>Now let us get back to the cities and temperatures, but take a more
+ structured approach this time. First let us convert the whole list
+ to Celsius as follows:</p>
<code type="none">
-module(tut7).
-export([format_temps/1]).
@@ -864,6 +883,7 @@ convert_list_to_c([City | Rest]) ->
convert_list_to_c([]) ->
[].</code>
+ <p>Test the function:</p>
<pre>
54> <input>c(tut7).</input>
{ok, tut7}.
@@ -874,26 +894,26 @@ convert_list_to_c([]) ->
{stockholm,{c,-4}},
{paris,{c,-2.2222222222222223}},
{london,{c,2.2222222222222223}}]</pre>
- <p>Looking at this bit by bit:</p>
+ <p>Explanation:</p>
<code type="none">
format_temps(List_of_cities) ->
convert_list_to_c(List_of_cities).</code>
- <p>Here we see that <c>format_temps/1</c> calls
+ <p>Here <c>format_temps/1</c> calls
<c>convert_list_to_c/1</c>. <c>convert_list_to_c/1</c> takes off
the head of the <c>List_of_cities</c>, converts it to Celsius if
needed. The | operator is used to add the (maybe) converted
to the converted rest of the list:</p>
<code type="none">
[Converted_City | convert_list_to_c(Rest)];</code>
- <p>or</p>
+ <p>or:</p>
<code type="none">
[City | convert_list_to_c(Rest)];</code>
- <p>We go on doing this until we get to the end of the list (i.e.
- the list is empty):</p>
+ <p>This is done until the end of the list is reached, that is,
+ the list is empty:</p>
<code type="none">
convert_list_to_c([]) ->
[].</code>
- <p>Now we have converted the list, we add a function to print it:</p>
+ <p>Now when the list is converted, a function to print it is added:</p>
<code type="none">
-module(tut7).
-export([format_temps/1]).
@@ -928,12 +948,12 @@ stockholm -4 c
paris -2.2222222222222223 c
london 2.2222222222222223 c
ok</pre>
- <p>We now have to add a function to find the cities with
- the maximum and minimum temperatures. The program below isn't
- the most efficient way of doing this as we walk through the list
+ <p>Now a function has to be added to find the cities with
+ the maximum and minimum temperatures. The following program is not
+ the most efficient way of doing this as you walk through the list
of cities four times. But it is better to first strive for
clarity and correctness and to make programs efficient only if
- really needed.</p>
+ needed.</p>
<code type="none"><![CDATA[
-module(tut7).
-export([format_temps/1]).
@@ -1003,8 +1023,8 @@ ok</pre>
<section>
<title>If and Case</title>
<p>The function <c>find_max_and_min</c> works out the maximum and
- minimum temperature. We have introduced a new construct here
- <c>if</c>. If works as follows:</p>
+ minimum temperature. A new construct, <c>if</c>, is introduced here.
+ If works as follows:</p>
<code type="none">
if
Condition 1 ->
@@ -1016,14 +1036,15 @@ if
Condition 4 ->
Action 4
end</code>
- <p>Note there is no ";" before <c>end</c>! Conditions are the same
- as guards, tests which succeed or fail. Erlang starts at the top
- until it finds a condition which succeeds and then it evaluates
+ <p>Notice that there is no ";" before <c>end</c>. Conditions do
+ the same as guards, that is, tests that succeed or fail. Erlang
+ starts at the top
+ and tests until it finds a condition that succeeds. Then it evaluates
(performs) the action following the condition and ignores all
- other conditions and action before the <c>end</c>. If no
- condition matches, there will be a run-time failure. A condition
- which always is succeeds is the atom, <c>true</c> and this is
- often used last in an <c>if</c> meaning do the action following
+ other conditions and actions before the <c>end</c>. If no
+ condition matches, a run-time failure occurs. A condition
+ that always succeeds is the atom <c>true</c>. This is
+ often used last in an <c>if</c>, meaning, do the action following
the <c>true</c> if all other conditions have failed.</p>
<p>The following is a short program to show the workings of
<c>if</c>.</p>
@@ -1039,10 +1060,10 @@ test_if(A, B) ->
B == 6 ->
io:format("B == 6~n", []),
b_equals_6;
- A == 2, B == 3 -> %i.e. A equals 2 and B equals 3
+ A == 2, B == 3 -> %That is A equals 2 and B equals 3
io:format("A == 2, B == 3~n", []),
a_equals_2_b_equals_3;
- A == 1 ; B == 7 -> %i.e. A equals 1 or B equals 7
+ A == 1 ; B == 7 -> %That is A equals 1 or B equals 7
io:format("A == 1 ; B == 7~n", []),
a_equals_1_or_b_equals_7
end.</code>
@@ -1068,19 +1089,19 @@ a_equals_1_or_b_equals_7
66> <input>tut9:test_if(33, 33).</input>
** exception error: no true branch found when evaluating an if expression
in function tut9:test_if/2 (tut9.erl, line 5)</pre>
- <p>Notice that <c>tut9:test_if(33,33)</c> did not cause any
- condition to succeed so we got the run time error
- <c>if_clause</c>, here nicely formatted by the shell. See the chapter
- <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual for details
- of the many guard tests available. <c>case</c> is another
- construct in Erlang. Recall that we wrote the
- <c>convert_length</c> function as:</p>
+ <p>Notice that <c>tut9:test_if(33,33)</c> does not cause any
+ condition to succeed. This leads to the run time error
+ <c>if_clause</c>, here nicely formatted by the shell. See
+ <seealso marker="doc/reference_manual:expressions">Guard Sequences</seealso>
+ for details of the many guard tests available.</p>
+ <p><c>case</c> is another construct in Erlang. Recall that the
+ <c>convert_length</c> function was written as:</p>
<code type="none">
convert_length({centimeter, X}) ->
{inch, X / 2.54};
convert_length({inch, Y}) ->
{centimeter, Y * 2.54}.</code>
- <p>We could also write the same program as:</p>
+ <p>The same program can also be written as:</p>
<code type="none">
-module(tut10).
-export([convert_length/1]).
@@ -1099,12 +1120,13 @@ convert_length(Length) ->
{centimeter,15.24}
69> <input>tut10:convert_length({centimeter, 2.5}).</input>
{inch,0.984251968503937}</pre>
- <p>Notice that both <c>case</c> and <c>if</c> have <em>return values</em>, i.e. in the above example <c>case</c> returned
+ <p>Both <c>case</c> and <c>if</c> have <em>return values</em>, that is,
+ in the above example <c>case</c> returned
either <c>{inch,X/2.54}</c> or <c>{centimeter,Y*2.54}</c>.
The behaviour of <c>case</c> can also be modified by using guards.
- An example should hopefully clarify this. The following example
- tells us the length of a month, given the year. We need to know
- the year of course, since February has 29 days in a leap year.</p>
+ The following example clarifies this. It
+ tells us the length of a month, given the year.
+ The year must be known, since February has 29 days in a leap year.</p>
<code type="none">
-module(tut11).
-export([month_length/2]).
@@ -1150,57 +1172,58 @@ month_length(Year, Month) ->
</section>
<section>
- <title>Built In Functions (BIFs)</title>
- <p>Built in functions (BIFs) are functions which for some reason are
- built in to the Erlang virtual machine. BIFs often implement
- functionality that is impossible to implement in Erlang or is too
- inefficient to implement in Erlang. Some BIFs can be called
- by use of the function name only, but they by default belong
- to the erlang module. So for example, the call to the BIF <c>trunc</c>
+ <title>Built-In Functions (BIFs)</title>
+ <p>BIFs are functions that for some reason are
+ built-in to the Erlang virtual machine. BIFs often implement
+ functionality that is impossible or is too
+ inefficient to implement in Erlang. Some BIFs can be called
+ using the function name only but they are by default belonging
+ to the <c>erlang</c> module. For example, the call to the
+ BIF <c>trunc</c>
below is equivalent to a call to <c>erlang:trunc</c>.</p>
- <p>As you can see, we first find out if a year is leap or not. If a
- year is divisible by 400, it is a leap year. To find this out we
- first divide the year by 400 and use the built in function
- <c>trunc</c> (more later) to cut off any decimals. We then
- multiply by 400 again and see if we get back the same value. For
- example, year 2004:</p>
+ <p>As shown, first it is checked if a year is leap. If a
+ year is divisible by 400, it is a leap year. To determine this,
+ first divide the year by 400 and use the BIF
+ <c>trunc</c> (more about this later) to cut off any decimals. Then
+ multiply by 400 again and see if the same value is returned again.
+ For example, year 2004:</p>
<code type="none">
2004 / 400 = 5.01
trunc(5.01) = 5
5 * 400 = 2000</code>
- <p>and we can see that we got back 2000 which is not the same as
- 2004, so 2004 isn't divisible by 400. Year 2000:</p>
+ <p>2000 is not the same as 2004, so 2004 is not divisible by 400.
+ Year 2000:</p>
<code type="none">
2000 / 400 = 5.0
trunc(5.0) = 5
5 * 400 = 2000</code>
- <p>so we have a leap year. The next two tests, which check if the year is
- divisible by 100 or 4, are done in the same way. The first
- <c>if</c> returns <c>leap</c> or <c>not_leap</c> which ends up
- in the variable <c>Leap</c>. We use this variable in the guard
- for <c>feb</c> in the following <c>case</c> which tells us how
+ <p>That is, a leap year. The next two <c>trunc</c>-tests evaluate
+ if the year is divisible by 100 or 4 in the same way. The first
+ <c>if</c> returns <c>leap</c> or <c>not_leap</c>, which lands up
+ in the variable <c>Leap</c>. This variable is used in the guard
+ for <c>feb</c> in the following <c>case</c> that tells us how
long the month is.</p>
- <p>This example showed the use of <c>trunc</c>. An easier way would
- be to use the Erlang operator <c>rem</c>, which gives the remainder
- after division. For example:</p>
+ <p>This example showed the use of <c>trunc</c>. It is easier
+ to use the Erlang operator <c>rem</c> that gives the remainder
+ after division, for example:</p>
<pre>
74> <input>2004 rem 400.</input>
4</pre>
- <p>so instead of writing:</p>
+ <p>So instead of writing:</p>
<code type="none">
trunc(Year / 400) * 400 == Year ->
leap;</code>
- <p>we could write:</p>
+ <p>it can be written:</p>
<code type="none">
Year rem 400 == 0 ->
leap;</code>
- <p>There are many other built in functions (BIF) such as
- <c>trunc</c>. Only a few built in functions can be used in guards,
+ <p>There are many other BIFs such as
+ <c>trunc</c>. Only a few BIFs can be used in guards,
and you cannot use functions you have defined yourself in guards.
- (see the chapter
- <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual) (Aside for
- advanced readers: This is to ensure that guards don't have side
- effects.) Let's play with a few of these functions in the shell:</p>
+ (see
+ <seealso marker="doc/reference_manual:expressions">Guard Sequences</seealso>)
+ (For advanced readers: This is to ensure that guards do not have side
+ effects.) Let us play with a few of these functions in the shell:</p>
<pre>
75> <input>trunc(5.6).</input>
5
@@ -1218,7 +1241,7 @@ false
true
82> <input>is_tuple([paris, {c, 30}]).</input>
false</pre>
- <p>All the above can be used in guards. Now for some which can't be
+ <p>All of these can be used in guards. Now for some BIFs that cannot be
used in guards:</p>
<pre>
83> <input>atom_to_list(hello).</input>
@@ -1227,22 +1250,22 @@ false</pre>
goodbye
85> <input>integer_to_list(22).</input>
"22"</pre>
- <p>The 3 BIFs above do conversions which would be difficult (or
+ <p>These three BIFs do conversions that would be difficult (or
impossible) to do in Erlang.</p>
</section>
<section>
- <title>Higher Order Functions (Funs)</title>
+ <title>Higher-Order Functions (Funs)</title>
<p>Erlang, like most modern functional programming languages, has
- higher order functions. We start with an example using the shell:</p>
+ higher-order functions. Here is an example using the shell:</p>
<pre>
86> <input>Xf = fun(X) -> X * 2 end.</input>
#Fun&lt;erl_eval.5.123085357&gt;
87> <input>Xf(5).</input>
10</pre>
- <p>What we have done here is to define a function which doubles
- the value of number and assign this function to a variable. Thus
- <c>Xf(5)</c> returned the value 10. Two useful functions when
+ <p>Here is defined a function that doubles
+ the value of a number and assigned this function to a variable. Thus
+ <c>Xf(5)</c> returns value 10. Two useful functions when
working with lists are <c>foreach</c> and <c>map</c>, which are
defined as follows:</p>
<code type="none">
@@ -1258,17 +1281,16 @@ map(Fun, []) ->
[].</code>
<p>These two functions are provided in the standard module
<c>lists</c>. <c>foreach</c> takes a list and applies a fun to
- every element in the list, <c>map</c> creates a new list by
+ every element in the list. <c>map</c> creates a new list by
applying a fun to every element in a list. Going back to
- the shell, we start by using <c>map</c> and a fun to add 3 to
+ the shell, <c>map</c> is used and a fun to add 3 to
every element of a list:</p>
<pre>
88> <input>Add_3 = fun(X) -> X + 3 end.</input>
#Fun&lt;erl_eval.5.123085357&gt;
89> <input>lists:map(Add_3, [1,2,3]).</input>
[4,5,6]</pre>
- <p>Now let's print out the temperatures in a list of cities (yet
- again):</p>
+ <p>Let us (again) print the temperatures in a list of cities:</p>
<pre>
90> <input>Print_City = fun({City, {X, Temp}}) -> io:format("~-15w ~w ~w~n",</input>
<input>[City, X, Temp]) end.</input>
@@ -1281,7 +1303,7 @@ stockholm c -4
paris f 28
london f 36
ok</pre>
- <p>We will now define a fun which can be used to go through a list
+ <p>Let us now define a fun that can be used to go through a list
of cities and temperatures and transform them all to Celsius.</p>
<code type="none">
-module(tut13).
@@ -1303,21 +1325,21 @@ convert_list_to_c(List) ->
{stockholm,{c,-4}},
{paris,{c,-2}},
{london,{c,2}}]</pre>
- <p>The <c>convert_to_c</c> function is the same as before, but we
- use it as a fun:</p>
+ <p>The <c>convert_to_c</c> function is the same as before, but here
+ it is used as a fun:</p>
<code type="none">
lists:map(fun convert_to_c/1, List)</code>
- <p>When we use a function defined elsewhere as a fun we can refer
- to it as <c>Function/Arity</c> (remember that <c>Arity</c> =
- number of arguments). So in the <c>map</c> call we write
- <c>lists:map(fun convert_to_c/1, List)</c>. As you can see
+ <p>When a function defined elsewhere is used as a fun, it can be referred
+ to as <c>Function/Arity</c> (remember that <c>Arity</c> =
+ number of arguments). So in the <c>map</c>-call
+ <c>lists:map(fun convert_to_c/1, List)</c> is written. As shown,
<c>convert_list_to_c</c> becomes much shorter and easier to
understand.</p>
<p>The standard module <c>lists</c> also contains a function
<c>sort(Fun, List)</c> where <c>Fun</c> is a fun with two
- arguments. This fun should return <c>true</c> if the the first
+ arguments. This fun returns <c>true</c> if the first
argument is less than the second argument, or else <c>false</c>.
- We add sorting to the <c>convert_list_to_c</c>:</p>
+ Sorting is added to the <c>convert_list_to_c</c>:</p>
<code type="none"><![CDATA[
-module(tut13).
@@ -1342,13 +1364,13 @@ convert_list_to_c(List) ->
{paris,{c,-2}},
{london,{c,2}},
{cape_town,{c,21}}]</pre>
- <p>In <c>sort</c> we use the fun:</p>
+ <p>In <c>sort</c> the fun is used:</p>
<code type="none"><![CDATA[
fun({_, {c, Temp1}}, {_, {c, Temp2}}) -> Temp1 < Temp2 end,]]></code>
- <p>Here we introduce the concept of an <em>anonymous variable</em>
- "_". This is simply shorthand for a variable which is going to
- get a value, but we will ignore the value. This can be used
- anywhere suitable, not just in fun's. <c><![CDATA[Temp1 < Temp2]]></c>
+ <p>Here the concept of an <em>anonymous variable</em>
+ "_" is introduced. This is simply shorthand for a variable that
+ gets a value, but the value is ignored. This can be used
+ anywhere suitable, not just in funs. <c><![CDATA[Temp1 < Temp2]]></c>
returns <c>true</c> if <c>Temp1</c> is less than <c>Temp2</c>.</p>
</section>
</chapter>
diff --git a/system/doc/getting_started/xmlfiles.mk b/system/doc/getting_started/xmlfiles.mk
index c784d79dc3..892db0e8de 100644
--- a/system/doc/getting_started/xmlfiles.mk
+++ b/system/doc/getting_started/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile
index 2b5d47d4ef..5d2997b188 100644
--- a/system/doc/installation_guide/Makefile
+++ b/system/doc/installation_guide/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/system/doc/installation_guide/book.xml b/system/doc/installation_guide/book.xml
index 9788263a98..92a64345c0 100644
--- a/system/doc/installation_guide/book.xml
+++ b/system/doc/installation_guide/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/installation_guide/install-binary.xml b/system/doc/installation_guide/install-binary.xml
index af7dab6e44..43f5a57077 100644
--- a/system/doc/installation_guide/install-binary.xml
+++ b/system/doc/installation_guide/install-binary.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -33,25 +34,23 @@
</header>
<section>
<title>Windows</title>
+ <p>The system is delivered as a Windows Installer executable.
+ Get it from http://www.erlang.org/download.html</p>
<section>
- <title>Introduction</title>
- <p>The system is delivered as a Windows Installer executable.
- Get it from our <url href="http://www.erlang.org/download.html">download page</url>.</p>
- </section>
-
- <section>
- <title>Installation</title>
- <p>The installation procedure is is automated. Double-click the
+ <title>Installing</title>
+ <p>The installation procedure is automated. Double-click the
<c>.exe</c> file icon and follow the instructions.</p>
</section>
+
<section>
- <title>Verification</title>
+ <title>Verifying</title>
<list type="bulleted">
<item>
<p>Start Erlang/OTP by double-clicking on the Erlang shortcut icon on the
desktop.</p>
- <p>Expect a command line window to pop up with an output looking something like this:</p>
+ <p>Expect a command-line window to pop up with an output looking
+ something like this:</p>
<pre>
Erlang/OTP 17 [erts-6.0] [64-bit] [smp:2:2]
@@ -59,12 +58,12 @@
1></pre>
</item>
<item>
- <p>Exit by entering the command <c>halt()</c>,</p>
+ <p>Exit by entering the command <c>halt()</c>.</p>
<pre>
2> <input>halt().</input></pre>
- <p>which will close the Erlang/OTP shell. </p>
+ <p>This closes the Erlang/OTP shell.</p>
</item>
</list>
- </section>
+ </section>
</section>
</chapter>
diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml
index ff17cecd59..0aacd0f49b 100644
--- a/system/doc/installation_guide/part.xml
+++ b/system/doc/installation_guide/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -29,7 +30,8 @@
<file>part.xml</file>
</header>
<description>
- <p>How to install Erlang/OTP on UNIX or Windows.</p>
+ <marker id="installation guide"></marker>
+ <p>This section describes how to install Erlang/OTP on UNIX and Windows.</p>
</description>
<xi:include href="install-binary.xml"/>
<xi:include href="INSTALL.xml"/>
diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk
index a18c82bc25..05effe1534 100644
--- a/system/doc/installation_guide/xmlfiles.mk
+++ b/system/doc/installation_guide/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/system/doc/oam/Makefile b/system/doc/oam/Makefile
index c18570b25c..32453428ef 100644
--- a/system/doc/oam/Makefile
+++ b/system/doc/oam/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/oam/book.xml b/system/doc/oam/book.xml
index 5f429fbee2..93f5fe344a 100644
--- a/system/doc/oam/book.xml
+++ b/system/doc/oam/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/oam/oam_intro.xml b/system/doc/oam/oam_intro.xml
index f4f990393e..22a2080fd9 100644
--- a/system/doc/oam/oam_intro.xml
+++ b/system/doc/oam/oam_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,241 +29,224 @@
<rev>A</rev>
<file>oam_intro.xml</file>
</header>
- <p>The operation and maintenance support in OTP consists of a
- generic model for management subsystems in OTP, and some
- components to be used in these subsystems. This document
- describes the model.
- </p>
- <p>The main idea in the model is that it is management protocol
- independent. Thus, it is not tied to any specific management
- protocol. An API is defined which can be used to write
- adaptations for specific management protocols.
- </p>
- <p>Each OAM component in OTP is implemented as one sub application,
- which can be included in a management application for the system.
- Note that such a complete management application is not in the
- scope of this generic functionality. Examples illustrating how such an
- application can be built are included however.
- </p>
+ <marker id="oam principles"></marker>
+ <p>The Operation and Maintenance (OAM) support in OTP consists of a
+ generic model for management subsystems in OTP, and some components
+ to be used in these subsystems. This section describes the model.</p>
+
+ <p>The main idea in the model is that it is not tied to any specific
+ management protocol. An Application Programming Interface (API) is
+ defined, which can be used to write adaptations for specific
+ management protocols.</p>
+
+ <p>Each OAM component in OTP is implemented as one sub-application, which
+ can be included in a management application for the system. Notice that
+ such a complete management application is not in the scope of this
+ generic functionality. However, this section includes examples
+ illustrating how such an application can be built.</p>
<section>
<title>Terminology</title>
- <p>The protocol independent architectural model on the network
- level is the well-known <term id="Manager-Agent model"><termdef>Client-Server model for management operations</termdef></term>. This model is based on the client-server
- principle, where the manager (client) sends <term id="requests"><termdef>A request is sent from a manager to an agent when it accesses management information.</termdef></term>to the
- agent (server), the agent sends <term id="replies"><termdef>A reply is sent from the agent as a response to a request from a manager.</termdef></term>back to the manager. There are two main
- differences to the normal client-server model. First, there are
- usually a few managers that communicate with many agents; and
- second, the agent may spontaneously send <term id="notifications"><termdef>A notification is sent spontaneously from an agent to a manager, e.g. an alarm.</termdef></term>to the
- manager. The picture below illustrates the idea.</p>
+ <p>The protocol-independent architectural model on the network level
+ is the well-known client-server model for management operations. This
+ model is based on the client-server principle, where the manager
+ (client) sends a request from a manager to an agent (server) when it
+ accesses management information. The agent sends a reply back to the
+ manager. There are two main differences to the normal
+ client-server model:</p>
+ <list type="bulleted">
+ <item><p>Usually a few managers communicate with many agents.</p></item>
+ <item><p>The agent can spontaneously send a notification, for example,
+ an alarm, to the manager.</p></item>
+ </list>
+ <p>The following picture illustrates the idea:</p>
+
<image file="../oam/terminology.gif">
<icaption>Terminology</icaption>
</image>
- <p>The manager is often referred to as the <term id="NMS"></term>, to
- emphasize that it usually is realized as a program that presents
- data to an operator.
- </p>
- <p>The agent is an entity that executes within a <term id="NE"></term>.
- In OTP, the network element may be a distributed system, meaning
- that the distributed system is managed as one entity. Of
- course, the agent may be configured to be able to run on one of
- several nodes, making it a distributed OTP application.
- </p>
- <p>The management information is defined in an <term id="MIB"></term>.
- It is a formal definition of which information the agent makes
- available to the manager. The manager accesses the MIB through
- a management protocol, such as SNMP, CMIP, HTTP or CORBA. Each
- of these protocols have their own MIB definition language. In
- SNMP, it is a subset of ASN.1, in CMIP it is GDMO, in HTTP it is
- implicit, and using CORBA, it is IDL. Usually, the entities
- defined in the MIB are called <term id="MO"></term>, although these
- objects do not have to be objects in the OO way,for example, a simple
- scalar variable defined in an MIB is called a Managed Object.
- The Managed Objects are logical objects, not necessarily with a
- one-to-one mapping to the resources.
- </p>
+
+ <p>The manager is often referred to as the <em>Network Management
+ System (NMS)</em>, to emphasize that it usually is realized as a
+ program that presents data to an operator.</p>
+
+ <p>The agent is an entity that executes within a <em>Network
+ Element (NE)</em>. In OTP, the NE can be a distributed system,
+ meaning that the distributed system is managed as one entity.
+ Of course, the agent can be configured to be able to run on one
+ of several nodes, making it a distributed OTP application.</p>
+
+ <p>The management information is defined in a <em>Management
+ Information Base (MIB)</em>. It is a formal definition of which
+ information the agent makes available to the manager. The
+ manager accesses the MIB through a management protocol, such
+ as SNMP, CMIP, HTTP, or CORBA. Each protocol has its own MIB
+ definition language. In SNMP, it is a subset of ASN.1, in CMIP
+ it is GDMO, in HTTP it is implicit, and using CORBA, it is IDL.</p>
+
+ <p>Usually, the entities defined in the MIB are
+ called <em>Managed Objects (MOs)</em>, although they do not
+ have to be objects in the object-oriented way. For example,
+ a simple scalar variable defined in a MIB is called an MO. The
+ MOs are logical objects, not necessarily with a one-to-one
+ mapping to the resources.</p>
</section>
<section>
<title>Model</title>
- <p>In this section, the generic protocol independent model for use
- within an OTP based network element is presented. This model is
- used by all operation and maintenance components, and may be
- used by the applications. The advantage of the model is that it
- clearly separates the resources from the management protocol.
- The resources do not need to be aware of which management
- protocol is used to manage the system. This makes it possible
- to manage the same resources with different protocols.
- </p>
- <p>The different entities involved in this model are the <term id="agent"></term>which terminates the management protocol, and the
- <term id="resources"></term>which is to be managed, i.e. the actual
- application entities. The resources should in general have no
- knowledge of the management protocol used, and the agent should
- have no knowledge of the managed resources. This implies that
- some sort of translation mechanism must be used, to translate
- the management operations to operations on the resources. This
- translation mechanism is usually called
- <em>instrumentation</em>, and the function that implements it is
- called <term id="instrumentation function"></term>. The
- instrumentation functions are written for each combination of
- management protocol and resource to be managed. For example, if
- an application is to be managed by SNMP and HTTP, two sets of
- instrumentation functions are defined; one that maps SNMP
- requests to the resources, and one that e.g. generates an HTML
- page for some resources.
- </p>
- <p>When a manager makes a request to the agent, we have the
- following picture:</p>
+ <p>This section presents the generic protocol-independent model
+ for use within an OTP-based NE. This model is used by
+ all OAM components and can be used by the applications. The
+ advantage of the model is that it clearly separates the
+ resources from the management protocol. The resources do not
+ need to be aware of which management protocol is used to manage
+ the system. The same resources can therefore be managed with
+ different protocols.</p>
+
+ <p>The entities involved in this model are the agent, which
+ terminates the management protocol, and the resources, which
+ is to be managed, that is, the actual application entities.
+ The resources should in general have no knowledge of the
+ management protocol used, and the agent should have no
+ knowledge of the managed resources. This implies that a
+ translation mechanism is needed, to translate the management
+ operations to operations on the resources. This translation
+ mechanism is usually called <em>instrumentation</em> and the
+ function that implements it is called <em>instrumentation
+ function</em>. The instrumentation functions are written for
+ each combination of management protocol and resource to be
+ managed. For example, if an application is to be managed by
+ SNMP and HTTP, two sets of instrumentation functions are
+ defined; one that maps SNMP requests to the resources, and
+ one that, for example, generates an HTML page for some
+ resources.</p>
+
+ <p>When a manager makes a request to the agent, the following
+ illustrates the situation:</p>
+
<image file="../oam/snmp_model_1.gif">
- <icaption>Request to an agent by a manager</icaption>
+ <icaption>Request to An Agent by a Manager</icaption>
</image>
- <p>Note that the mapping between instrumentation function and
- resource is not necessarily 1-1. It is also possible to write
- one instrumentation function for each resource, and use that
- function from different protocols.
- </p>
- <p>The agent receives a request and maps this request to calls to
- one or several instrumentation functions. The instrumentation
- functions perform operations on the resources to implement the
- semantics associated with the managed object.
- </p>
- <p>For example, a system that is managed with SNMP and HTTP may be
- structured in the following way:</p>
+
+ <p>The mapping between an instrumentation function and a
+ resource is not necessarily 1-1. It is also possible to write
+ one instrumentation function for each resource, and use that
+ function from different protocols.</p>
+
+ <p>The agent receives a request and maps it to calls to one or
+ more instrumentation functions. These functions perform
+ operations on the resources to implement the semantics
+ associated with the MO.</p>
+
+ <p>For example, a system that is managed with SNMP and HTTP
+ can be structured as follows:</p>
+
<image file="../oam/snmp_model_2.gif">
- <icaption>Structure of a system managed with SNMP and HTTP</icaption>
+ <icaption>Structure of a System Managed with SNMP and HTTP</icaption>
</image>
- <p>The resources may send notifications to the manager as well.
- Examples of notifications are events and alarms. There is a
- need for the resource to generate protocol independent
- notifications. The following picture illustrates how this is
- achieved:</p>
+
+ <p>The resources can send notifications to the manager as well.
+ Examples of notifications are events and alarms. The resource
+ needs to generate protocol-independent notifications.
+ The following picture illustrates how this is achieved:</p>
+
<image file="../oam/snmp_model_3.gif">
- <icaption>Notification handling</icaption>
+ <icaption>Notification Handling</icaption>
</image>
- <p>The main idea is that the resource sends the notfications as
- Erlang terms to a dedicated <c>gen_event</c> process. Into this
- process, handlers for the different management protocols are
- installed. When an event is received by this process, it is
- forwarded to each installed handler. The handlers are
- responsible for translating the event into a notification to be
- sent over the management protocol. For example, a handler for
- SNMP would translate each event into an SNMP trap.
- </p>
+
+ <p>The main idea is that the resource sends the notifications as
+ Erlang terms to a dedicated <c>gen_event</c> process. Into this
+ process, handlers for the different management protocols are
+ installed. When an event is received by this process, it is
+ forwarded to each installed handler. The handlers are
+ responsible for translating the event into a notification to be
+ sent over the management protocol. For example, a handler for
+ SNMP translates each event into an SNMP trap.</p>
</section>
<section>
- <title>SNMP based OAM</title>
- <p>For all OAM components, SNMP adaptations are provided. Other
- adaptations may be defined in the future.
- </p>
+ <title>SNMP-Based OAM</title>
+ <p>For all OAM components, SNMP adaptations are provided. Other
+ adaptations might be defined in the future.</p>
+
<p>The OAM components, and some other OTP applications, define
- SNMP MIBs. All these MIBs are written in SNMPv2 SMI syntax, as
- defined in RFC1902. For convenience we also deliver the SNMPv1
- SMI equivalent. All MIBs are designed to be v1/v2 compatible,
- i.e. the v2 MIBs do not use any construct not available in v1.
- </p>
+ SNMP MIBs. These MIBs are written in SNMPv2 SMI syntax, as
+ defined in RFC 1902. For convenience we also deliver the SNMPv1
+ SMI equivalent. All MIBs are designed to be v1/v2 compatible,
+ that is, the v2 MIBs do not use any construct not available in
+ v1.</p>
<section>
- <title>MIB structure</title>
- <p>The top-level OTP MIB is called <c>OTP-REG</c>, and it is
- included in the <c>sasl</c> application. All other OTP mibs
- import some objects from this MIB.
- </p>
- <p>Each MIB is contained in one application. The MIB text files
- are stored under <c><![CDATA[mibs/<MIB>.mib]]></c> in the application
- directory. The generated <c>.hrl</c> files with constant
- declarations are stored under <c><![CDATA[include/<MIB>.hrl]]></c>, and
- the compiled MIBs are stored under
- <c><![CDATA[priv/mibs/<MIB>.bin]]></c>. For example, the <c>OTP-MIB</c>
- is included in the <c>sasl</c> application:
- </p>
+ <title>MIB Structure</title>
+ <p>The top-level OTP MIB is called <c>OTP-REG</c> and it is
+ included in the <c>sasl</c> application. All other OTP MIBs
+ import some objects from this MIB.</p>
+
+ <p>Each MIB is contained in one application. The MIB text
+ files are stored under <c><![CDATA[mibs/<MIB>.mib]]></c> in
+ the application directory. The generated <c>.hrl</c> files
+ with constant declarations are stored under
+ <c><![CDATA[include/<MIB>.hrl]]></c>, and the compiled MIBs
+ are stored under <c><![CDATA[priv/mibs/<MIB>.bin]]></c>.
+ For example, the <c>OTP-MIB</c> is included in the
+ <c>sasl</c> application:</p>
+
<code type="none">
sasl-1.3/mibs/OTP-MIB.mib
- include/OTP-MIB.hrl
- priv/mibs/OTP-MIB.bin</code>
- <p>An application that needs to IMPORT this mib into another
- MIB, should use the <c>il</c> option to the snmp mib compiler:
- </p>
+include/OTP-MIB.hrl
+priv/mibs/OTP-MIB.bin</code>
+
+ <p>An application that needs to import this MIB into another
+ MIB is to use the <c>il</c> option to the SNMP MIB compiler:</p>
+
<code type="none">
snmp:c("MY-MIB", [{il, ["sasl/priv/mibs"]}]).</code>
+
<p>If the application needs to include the generated
- <c>.hrl</c> file, it should use the <c>-include_lib</c>
- directive to the Erlang compiler.
- </p>
+ <c>.hrl</c> file, it is to use the <c>-include_lib</c>
+ directive to the Erlang compiler:</p>
+
<code type="none">
-module(my_mib).
-
-include_lib("sasl/include/OTP-MIB.hrl").</code>
- <p>The following MIBs are defined in the OTP system:
- </p>
- <taglist>
- <tag>OTP-REG (sasl)</tag>
- <item>
- <p>This MIB contains the top-level OTP registration
- objects, used by all other MIBs.
- </p>
- </item>
- <tag>OTP-TC (sasl)</tag>
- <item>
- <p>This MIB contains the general Textual Conventions,
- which can be used by any other MIB.
- </p>
- </item>
- <tag>OTP-MIB (sasl)</tag>
- <item>
- <p>This MIB contains objects for instrumentation of the
- Erlang nodes, the Erlang machines and the applications in
- the system.
- </p>
- </item>
- <tag>OTP-OS-MON-MIB (os_mon)</tag>
- <item>
- <p>This MIB contains objects for instrumentation of disk,
- memory and cpu usage of the nodes in the system.
- </p>
- </item>
- <tag>OTP-SNMPEA-MIB (snmp)</tag>
- <item>
- <p>This MIB contains objects for instrumentation and
- control of the extensible snmp agent itself. Note that
- the agent also implements the standard SNMPv2-MIB (or v1
- part of MIB-II, if SNMPv1 is used).
- </p>
- </item>
- <tag>OTP-EVA-MIB (eva)</tag>
- <item>
- <p>This MIB contains objects for instrumentation and
- control of the events and alarms in the system.
- </p>
- </item>
- <tag>OTP-LOG-MIB (eva)</tag>
- <item>
- <p>This MIB contains objects for instrumentation and
- control of the logs and FTP transfer of logs.
- </p>
- </item>
- <tag>OTP-EVA-LOG-MIB (eva)</tag>
- <item>
- <p>This MIB contains objects for instrumentation and
- control of the events and alarm logs in the system.
- </p>
- </item>
- <tag>OTP-SNMPEA-LOG-MIB (eva)</tag>
- <item>
- <p>This MIB contains objects for instrumentation and
- control of the snmp audit trail log in the system.
- </p>
- </item>
- </taglist>
+
+ <p>The following MIBs are defined in the OTP system:</p>
+ <list type="bulleted">
+ <item><p><c>OTP-REG)</c> (in <c>sasl</c>) contains the top-level
+ OTP registration objects, used by all other MIBs.</p></item>
+ <item><p><c>OTP-TC</c> (in <c>sasl</c>) contains the general
+ Textual Conventions, which can be used by any other MIB.</p></item>
+ <item><p><c>OTP-MIB</c> (in <c>sasl</c>) contains objects for
+ instrumentation of the Erlang nodes, the Erlang machines,
+ and the applications in the system.</p></item>
+ <item><p><c>OTP-OS-MON-MIB</c> (in <c>oc_mon</c>) contains
+ objects for instrumentation of disk, memory, and CPU use
+ of the nodes in the system.</p></item>
+ <item><p><c>OTP-SNMPEA-MIB</c> (in <c>snmp</c>)
+ contains objects for instrumentation and control of the extensible
+ SNMP agent itself. The agent also implements the standard SNMPv2-MIB
+ (or v1 part of MIB-II, if SNMPv1 is used).</p></item>
+ <item><p><c>OTP-EVA-MIB</c> (in <c>eva</c>) contains objects
+ for instrumentation and control of the events and alarms in
+ the system.</p></item>
+ <item><p><c>OTP-LOG-MIB</c> (in <c>eva</c>) contains objects
+ for instrumentation and control of the logs and FTP transfer of
+ logs.</p></item>
+ <item><p><c>OTP-EVA-LOG-MIB</c> (in <c>eva</c>) contains objects
+ for instrumentation and control of the events and alarm logs
+ in the system.</p></item>
+ <item><p><c>OTP-SNMPEA-LOG-MIB</c> (in <c>eva</c>) contains
+ objects for instrumentation and control of the SNMP audit
+ trail log in the system.</p></item>
+ </list>
+
<p>The different applications use different strategies for
- loading the MIBs into the agent. Some MIB implementations are
- code-only, while others need a server. One way, used by the
- code-only mib implementations, is for the user to call a
- function such as <c>otp_mib:init(Agent)</c> to load the MIB,
- and <c>otp_mib:stop(Agent)</c> to unload the MIB. See the
- application manual page for each application for a description
- of how to load each MIB.
- </p>
+ loading the MIBs into the agent. Some MIB implementations are
+ code-only, while others need a server. One way, used by the
+ code-only MIB implementations, is for the user to call a
+ function such as <c>otp_mib:init(Agent)</c> to load the MIB,
+ and <c>otp_mib:stop(Agent)</c> to unload the MIB. See the
+ manual page for each application for a description of how
+ to load each MIB.</p>
</section>
</section>
</chapter>
diff --git a/system/doc/oam/part.xml b/system/doc/oam/part.xml
index 9d44d6e0ad..efbaa05b94 100644
--- a/system/doc/oam/part.xml
+++ b/system/doc/oam/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/oam/xmlfiles.mk b/system/doc/oam/xmlfiles.mk
index 0610bdb989..5876243466 100644
--- a/system/doc/oam/xmlfiles.mk
+++ b/system/doc/oam/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/programming_examples/Makefile b/system/doc/programming_examples/Makefile
index ef9afa46bc..fe59dce7e4 100644
--- a/system/doc/programming_examples/Makefile
+++ b/system/doc/programming_examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/programming_examples/bit_syntax.xml b/system/doc/programming_examples/bit_syntax.xml
index fb321c1ba9..0af295b7b7 100644
--- a/system/doc/programming_examples/bit_syntax.xml
+++ b/system/doc/programming_examples/bit_syntax.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,62 +32,64 @@
<section>
<title>Introduction</title>
- <p>In Erlang a Bin is used for constructing binaries and matching
+ <p>In Erlang, a Bin is used for constructing binaries and matching
binary patterns. A Bin is written with the following syntax:</p>
<code type="none"><![CDATA[
<<E1, E2, ... En>>]]></code>
- <p>A Bin is a low-level sequence of bits or bytes. The purpose of a Bin is
- to be able to, from a high level, construct a binary,</p>
+ <p>A Bin is a low-level sequence of bits or bytes.
+ The purpose of a Bin is to enable construction of binaries:</p>
<code type="none"><![CDATA[
Bin = <<E1, E2, ... En>>]]></code>
- <p>in which case all elements must be bound, or to match a binary,</p>
+ <p>All elements must be bound. Or match a binary:</p>
<code type="none"><![CDATA[
<<E1, E2, ... En>> = Bin ]]></code>
- <p>where <c>Bin</c> is bound, and where the elements are bound or
+ <p>Here, <c>Bin</c> is bound and the elements are bound or
unbound, as in any match.</p>
- <p>In R12B, a Bin need not consist of a whole number of bytes.</p>
+ <p>Since Erlang R12B, a Bin does not need to consist of a whole number of bytes.</p>
<p>A <em>bitstring</em> is a sequence of zero or more bits, where
- the number of bits doesn't need to be divisible by 8. If the number
+ the number of bits does not need to be divisible by 8. If the number
of bits is divisible by 8, the bitstring is also a binary.</p>
<p>Each element specifies a certain <em>segment</em> of the bitstring.
A segment is a set of contiguous bits of the binary (not
necessarily on a byte boundary). The first element specifies
the initial segment, the second element specifies the following
- segment etc.</p>
- <p>The following examples illustrate how binaries are constructed
+ segment, and so on.</p>
+ <p>The following examples illustrate how binaries are constructed,
or matched, and how elements and tails are specified.</p>
<section>
<title>Examples</title>
- <p><em>Example 1: </em>A binary can be constructed from a set of
+ <p><em>Example 1:</em> A binary can be constructed from a set of
constants or a string literal:</p>
<code type="none"><![CDATA[
Bin11 = <<1, 17, 42>>,
Bin12 = <<"abc">>]]></code>
- <p>yields binaries of size 3; <c>binary_to_list(Bin11)</c>
- evaluates to <c>[1, 17, 42]</c>, and
- <c>binary_to_list(Bin12)</c> evaluates to <c>[97, 98, 99]</c>.</p>
- <p><em>Example 2: </em>Similarly, a binary can be constructed
+ <p>This gives two binaries of size 3, with the following evaluations:</p>
+ <list type="bulleted">
+ <item><c>binary_to_list(Bin11)</c> evaluates to <c>[1, 17, 42]</c>.</item>
+ <item><c>binary_to_list(Bin12)</c> evaluates to <c>[97, 98, 99]</c>.</item>
+ </list>
+ <p><em>Example 2:</em>Similarly, a binary can be constructed
from a set of bound variables:</p>
<code type="none"><![CDATA[
A = 1, B = 17, C = 42,
Bin2 = <<A, B, C:16>>]]></code>
- <p>yields a binary of size 4, and <c>binary_to_list(Bin2)</c>
- evaluates to <c>[1, 17, 00, 42]</c> too. Here we used a
- <em>size expression</em> for the variable <c>C</c> in order to
+ <p>This gives a binary of size 4.
+ Here, a <em>size expression</em> is used for the variable <c>C</c> to
specify a 16-bits segment of <c>Bin2</c>.</p>
- <p><em>Example 3: </em>A Bin can also be used for matching: if
+ <p><c>binary_to_list(Bin2)</c> evaluates to <c>[1, 17, 00, 42]</c>.</p>
+ <p><em>Example 3:</em> A Bin can also be used for matching.
<c>D</c>, <c>E</c>, and <c>F</c> are unbound variables, and
- <c>Bin2</c> is bound as in the former example,</p>
+ <c>Bin2</c> is bound, as in Example 2:</p>
<code type="none"><![CDATA[
<<D:16, E, F/binary>> = Bin2]]></code>
- <p>yields <c>D = 273</c>, <c>E = 00</c>, and F binds to a binary
+ <p>This gives <c>D = 273</c>, <c>E = 00</c>, and F binds to a binary
of size 1: <c>binary_to_list(F) = [42]</c>.</p>
<p><em>Example 4:</em> The following is a more elaborate example
- of matching, where <c>Dgram</c> is bound to the consecutive
- bytes of an IP datagram of IP protocol version 4, and where we
- want to extract the header and the data of the datagram:</p>
+ of matching. Here, <c>Dgram</c> is bound to the consecutive
+ bytes of an IP datagram of IP protocol version 4. The ambition is
+ to extract the header and the data of the datagram:</p>
<code type="none"><![CDATA[
-define(IP_VERSION, 4).
-define(IP_MIN_HDR_LEN, 5).
@@ -102,53 +105,59 @@ case Dgram of
<<Opts:OptsLen/binary,Data/binary>> = RestDgram,
...
end.]]></code>
- <p>Here the segment corresponding to the <c>Opts</c> variable
- has a <em>type modifier</em> specifying that <c>Opts</c> should
+ <p>Here, the segment corresponding to the <c>Opts</c> variable
+ has a <em>type modifier</em>, specifying that <c>Opts</c> is to
bind to a binary. All other variables have the default type
equal to unsigned integer.</p>
- <p>An IP datagram header is of variable length, and its length -
- measured in the number of 32-bit words - is given in
- the segment corresponding to <c>HLen</c>, the minimum value of
- which is 5. It is the segment corresponding to <c>Opts</c>
- that is variable: if <c>HLen</c> is equal to 5, <c>Opts</c>
- will be an empty binary.</p>
+ <p>An IP datagram header is of variable length. This length is
+ measured in the number of 32-bit words and is given in
+ the segment corresponding to <c>HLen</c>. The minimum value of
+ <c>HLen</c> is 5. It is the segment corresponding to <c>Opts</c>
+ that is variable, so if <c>HLen</c> is equal to 5, <c>Opts</c>
+ becomes an empty binary.</p>
<p>The tail variables <c>RestDgram</c> and <c>Data</c> bind to
- binaries, as all tail variables do. Both may bind to empty
+ binaries, as all tail variables do. Both can bind to empty
binaries.</p>
- <p>If the first 4-bits segment of <c>Dgram</c> is not equal to
- 4, or if <c>HLen</c> is less than 5, or if the size of
- <c>Dgram</c> is less than <c>4*HLen</c>, the match of
- <c>Dgram</c> fails.</p>
+ <p>The match of <c>Dgram</c> fails if one of the following occurs:</p>
+ <list type="bulleted">
+ <item>The first 4-bits segment of <c>Dgram</c> is not equal to 4.</item>
+ <item><c>HLen</c> is less than 5.</item>
+ <item>The size of <c>Dgram</c> is less than <c>4*HLen</c>.</item>
+ </list>
</section>
</section>
<section>
- <title>A Lexical Note</title>
- <p>Note that "<c><![CDATA[B=<<1>>]]></c>" will be interpreted as
+ <title>Lexical Note</title>
+ <p>Notice that "<c><![CDATA[B=<<1>>]]></c>" will be interpreted as
"<c><![CDATA[B =< <1>>]]></c>", which is a syntax error.
- The correct way to write the expression is
- "<c><![CDATA[B = <<1>>]]></c>".</p>
+ The correct way to write the expression is:
+ <c><![CDATA[B = <<1>>]]></c>.</p>
</section>
<section>
<title>Segments</title>
<p>Each segment has the following general syntax:</p>
<p><c>Value:Size/TypeSpecifierList</c></p>
- <p>Both the <c>Size</c> and the <c>TypeSpecifier</c> or both may be
- omitted; thus the following variations are allowed:</p>
- <p><c>Value</c></p>
- <p><c>Value:Size</c></p>
- <p><c>Value/TypeSpecifierList</c></p>
- <p>Default values will be used for missing specifications.
- The default values are described in the section
+ <p>The <c>Size</c> or the <c>TypeSpecifier</c>, or both, can be
+ omitted. Thus, the following variants are allowed:</p>
+ <list type="bulleted">
+ <item><c>Value</c></item>
+ <item><c>Value:Size</c></item>
+ <item><c>Value/TypeSpecifierList</c></item>
+ </list>
+ <p>Default values are used when specifications are missing.
+ The default values are described in
<seealso marker="#Defaults">Defaults</seealso>.</p>
- <p>Used in binary construction, the <c>Value</c> part is any
- expression. Used in binary matching, the <c>Value</c> part must
- be a literal or variable. You can read more about
- the <c>Value</c> part in the section about constructing
- binaries and matching binaries.</p>
+ <p>The <c>Value</c> part is any expression, when used in binary construction.
+ Used in binary matching, the <c>Value</c> part must
+ be a literal or a variable. For more information about
+ the <c>Value</c> part, see
+ <seealso marker="#Constructing Binaries and Bitstrings">Constructing Binaries and Bitstrings</seealso>
+ and
+ <seealso marker="#Matching Binaries">Matching Binaries</seealso>.</p>
<p>The <c>Size</c> part of the segment multiplied by the unit in
- the <c>TypeSpecifierList</c> (described below) gives the number
+ <c>TypeSpecifierList</c> (described later) gives the number
of bits for the segment. In construction, <c>Size</c> is any
expression that evaluates to an integer. In matching,
<c>Size</c> must be a constant expression or a variable.</p>
@@ -160,22 +169,22 @@ end.]]></code>
<c>binary</c>.</item>
<tag>Signedness</tag>
<item>The signedness specification can be either <c>signed</c>
- or <c>unsigned</c>. Note that signedness only matters for
+ or <c>unsigned</c>. Notice that signedness only matters for
matching.</item>
<tag>Endianness</tag>
<item>The endianness specification can be either <c>big</c>,
<c>little</c>, or <c>native</c>. Native-endian means that
- the endian will be resolved at load time to be either
+ the endian is resolved at load time, to be either
big-endian or little-endian, depending on what is "native"
for the CPU that the Erlang machine is run on.</item>
<tag>Unit</tag>
<item>The unit size is given as <c>unit:IntegerLiteral</c>.
- The allowed range is 1-256. It will be multiplied by
+ The allowed range is 1-256. It is multiplied by
the <c>Size</c> specifier to give the effective size of
- the segment. In R12B, the unit size specifies the alignment
- for binary segments without size (examples will follow).</item>
+ the segment. Since Erlang R12B, the unit size specifies the alignment
+ for binary segments without size.</item>
</taglist>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<code type="none">
X:4/little-signed-integer-unit:8</code>
<p>This element has a total size of 4*8 = 32 bits, and it contains
@@ -184,13 +193,14 @@ X:4/little-signed-integer-unit:8</code>
<section>
<title>Defaults</title>
- <p><marker id="Defaults"></marker>The default type for a segment is integer. The default
+ <p><marker id="Defaults"></marker>The default type for
+ a segment is integer. The default
type does not depend on the value, even if the value is a
- literal. For instance, the default type in '<c><![CDATA[<<3.14>>]]></c>' is
+ literal. For example, the default type in <c><![CDATA[<<3.14>>]]></c> is
integer, not float.</p>
<p>The default <c>Size</c> depends on the type. For integer it is
8. For float it is 64. For binary it is all of the binary. In
- matching, this default value is only valid for the very last
+ matching, this default value is only valid for the last
element. All other binary elements in matching must have a size
specification.</p>
<p>The default unit depends on the the type. For <c>integer</c>,
@@ -201,61 +211,60 @@ X:4/little-signed-integer-unit:8</code>
<section>
<title>Constructing Binaries and Bitstrings</title>
+ <marker id="Constructing Binaries and Bitstrings"></marker>
<p>This section describes the rules for constructing binaries using
the bit syntax. Unlike when constructing lists or tuples,
the construction of a binary can fail with a <c>badarg</c>
exception.</p>
<p>There can be zero or more segments in a binary to be
- constructed. The expression '<c><![CDATA[<<>>]]></c>' constructs a zero
+ constructed. The expression <c><![CDATA[<<>>]]></c> constructs a zero
length binary.</p>
<p>Each segment in a binary can consist of zero or more bits.
There are no alignment rules for individual segments of type
<c>integer</c> and <c>float</c>. For binaries and bitstrings
without size, the unit specifies the alignment. Since the default
alignment for the <c>binary</c> type is 8, the size of a binary
- segment must be a multiple of 8 bits (i.e. only whole bytes).
- Example:</p>
+ segment must be a multiple of 8 bits, that is, only whole bytes.</p>
+ <p><em>Example:</em></p>
<code type="none"><![CDATA[
<<Bin/binary,Bitstring/bitstring>>]]></code>
<p>The variable <c>Bin</c> must contain a whole number of bytes,
because the <c>binary</c> type defaults to <c>unit:8</c>.
- A <c>badarg</c> exception will be generated if <c>Bin</c> would
- consist of (for instance) 17 bits.</p>
+ A <c>badarg</c> exception is generated if <c>Bin</c>
+ consist of, for example, 17 bits.</p>
- <p>On the other hand, the variable <c>Bitstring</c> may consist of
- any number of bits, for instance 0, 1, 8, 11, 17, 42, and so on,
- because the default <c>unit</c> for bitstrings is 1.</p>
+ <p>The <c>Bitstring</c> variable can consist of
+ any number of bits, for example, 0, 1, 8, 11, 17, 42, and so on.
+ This is because the default <c>unit</c> for bitstrings is 1.</p>
- <warning><p>For clarity, it is recommended not to change the unit
- size for binaries, but to use <c>binary</c> when you need byte
- alignment, and <c>bitstring</c> when you need bit alignment.</p></warning>
+ <p>For clarity, it is recommended not to change the unit
+ size for binaries. Instead, use <c>binary</c> when you need byte alignment
+ and <c>bitstring</c> when you need bit alignment.</p>
- <p>The following example</p>
+ <p>The following example successfully constructs a bitstring of 7 bits,
+ provided that all of X and Y are integers:</p>
<code type="none"><![CDATA[
<<X:1,Y:6>>]]></code>
- <p>will successfully construct a bitstring of 7 bits.
- (Provided that all of X and Y are integers.)</p>
- <p>As noted earlier, segments have the following general syntax:</p>
+ <p>As mentioned earlier, segments have the following general syntax:</p>
<p><c>Value:Size/TypeSpecifierList</c></p>
<p>When constructing binaries, <c>Value</c> and <c>Size</c> can be
any Erlang expression. However, for syntactical reasons, both
<c>Value</c> and <c>Size</c> must be enclosed in parenthesis if
the expression consists of anything more than a single literal
- or variable. The following gives a compiler syntax error:</p>
+ or a variable. The following gives a compiler syntax error:</p>
<code type="none"><![CDATA[
<<X+1:8>>]]></code>
- <p>This expression must be rewritten to</p>
+ <p>This expression must be rewritten into the following,
+ to be accepted by the compiler:</p>
<code type="none"><![CDATA[
<<(X+1):8>>]]></code>
- <p>in order to be accepted by the compiler.</p>
<section>
<title>Including Literal Strings</title>
- <p>As syntactic sugar, an literal string may be written instead
- of a element.</p>
+ <p>A literal string can be written instead of an element:</p>
<code type="none"><![CDATA[
<<"hello">>]]></code>
- <p>which is syntactic sugar for</p>
+ <p>This is syntactic sugar for the following:</p>
<code type="none"><![CDATA[
<<$h,$e,$l,$l,$o>>]]></code>
</section>
@@ -263,29 +272,30 @@ X:4/little-signed-integer-unit:8</code>
<section>
<title>Matching Binaries</title>
- <p>This section describes the rules for matching binaries using
+ <marker id="Matching Binaries"></marker>
+ <p>This section describes the rules for matching binaries, using
the bit syntax.</p>
<p>There can be zero or more segments in a binary pattern.
- A binary pattern can occur in every place patterns are allowed,
- also inside other patterns. Binary patterns cannot be nested.</p>
- <p>The pattern '<c><![CDATA[<<>>]]></c>' matches a zero length binary.</p>
- <p>Each segment in a binary can consist of zero or more bits.</p>
- <p>A segment of type <c>binary</c> must have a size evenly
- divisible by 8 (or divisible by the unit size, if the unit size has been changed).</p>
- <p>A segment of type <c>bitstring</c> has no restrictions on the size.</p>
- <p>As noted earlier, segments have the following general syntax:</p>
+ A binary pattern can occur wherever patterns are allowed,
+ including inside other patterns. Binary patterns cannot be nested.
+ The pattern <c><![CDATA[<<>>]]></c> matches a zero length binary.</p>
+ <p>Each segment in a binary can consist of zero or more bits.
+ A segment of type <c>binary</c> must have a size evenly divisible by 8
+ (or divisible by the unit size, if the unit size has been changed).
+ A segment of type <c>bitstring</c> has no restrictions on the size.</p>
+ <p>As mentioned earlier, segments have the following general syntax:</p>
<p><c>Value:Size/TypeSpecifierList</c></p>
- <p>When matching <c>Value</c> value must be either a variable or
- an integer or floating point literal. Expressions are not
+ <p>When matching <c>Value</c>, value must be either a variable or
+ an integer, or a floating point literal. Expressions are not
allowed.</p>
<p><c>Size</c> must be an integer literal, or a previously bound
- variable. Note that the following is not allowed:</p>
+ variable. The following is not allowed:</p>
<code type="none"><![CDATA[
foo(N, <<X:N,T/binary>>) ->
{X,T}.]]></code>
<p>The two occurrences of <c>N</c> are not related. The compiler
will complain that the <c>N</c> in the size field is unbound.</p>
- <p>The correct way to write this example is like this:</p>
+ <p>The correct way to write this example is as follows:</p>
<code type="none"><![CDATA[
foo(N, Bin) ->
<<X:N,T/binary>> = Bin,
@@ -303,14 +313,14 @@ foo(<<A:8,Rest/binary>>) ->]]></code>
without size:</p>
<code type="none"><![CDATA[
foo(<<A:8,Rest/bitstring>>) ->]]></code>
- <p>There is no restriction on the number of bits in the tail.</p>
+ <p>There are no restrictions on the number of bits in the tail.</p>
</section>
</section>
<section>
<title>Appending to a Binary</title>
- <p>In R12B, the following function for creating a binary out of
- a list of triples of integers is now efficient:</p>
+ <p>Since Erlang R12B, the following function for creating a binary out of
+ a list of triples of integers is efficient:</p>
<code type="none"><![CDATA[
triples_to_bin(T) ->
triples_to_bin(T, <<>>).
@@ -321,7 +331,9 @@ triples_to_bin([], Acc) ->
Acc.]]></code>
<p>In previous releases, this function was highly inefficient, because
the binary constructed so far (<c>Acc</c>) was copied in each recursion step.
- That is no longer the case. See the Efficiency Guide for more information.</p>
+ That is no longer the case. For more information, see
+ <seealso marker="doc/efficiency_guide:introduction">
+ Efficiency Guide</seealso>.</p>
</section>
</chapter>
diff --git a/system/doc/programming_examples/book.xml b/system/doc/programming_examples/book.xml
index fd430a02c0..c6eb4fec97 100644
--- a/system/doc/programming_examples/book.xml
+++ b/system/doc/programming_examples/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index 7bfac9db8c..8469f0871c 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,146 +31,140 @@
</header>
<section>
- <title>Example 1 - map</title>
- <p>If we want to double every element in a list, we could write a
- function named <c>double</c>:</p>
+ <title>map</title>
+ <p>The following function, <c>double</c>, doubles every element in a list:</p>
<code type="none">
double([H|T]) -> [2*H|double(T)];
double([]) -> [].</code>
- <p>This function obviously doubles the argument entered as input
- as follows:</p>
+ <p>Hence, the argument entered as input is doubled as follows:</p>
<pre>
> <input>double([1,2,3,4]).</input>
[2,4,6,8]</pre>
- <p>We now add the function <c>add_one</c>, which adds one to every
+ <p>The following function, <c>add_one</c>, adds one to every
element in a list:</p>
<code type="none">
add_one([H|T]) -> [H+1|add_one(T)];
add_one([]) -> [].</code>
- <p>These functions, <c>double</c> and <c>add_one</c>, have a very
- similar structure. We can exploit this fact and write a function
- <c>map</c> which expresses this similarity:</p>
+ <p>The functions <c>double</c> and <c>add_one</c> have a
+ similar structure. This can be used by writing a function
+ <c>map</c> that expresses this similarity:</p>
<codeinclude file="funs1.erl" tag="%1" type="erl"></codeinclude>
- <p>We can now express the functions <c>double</c> and
- <c>add_one</c> in terms of <c>map</c> as follows:</p>
+ <p>The functions <c>double</c> and <c>add_one</c> can now be expressed
+ in terms of <c>map</c> as follows:</p>
<code type="none">
double(L) -> map(fun(X) -> 2*X end, L).
add_one(L) -> map(fun(X) -> 1 + X end, L).</code>
- <p><c>map(F, List)</c> is a function which takes a function
- <c>F</c> and a list <c>L</c> as arguments and returns the new
- list which is obtained by applying <c>F</c> to each of
+ <p><c>map(F, List)</c> is a function that takes a function
+ <c>F</c> and a list <c>L</c> as arguments and returns a new
+ list, obtained by applying <c>F</c> to each of
the elements in <c>L</c>.</p>
<p>The process of abstracting out the common features of a number
- of different programs is called procedural abstraction.
- Procedural abstraction can be used in order to write several
- different functions which have a similar structure, but differ
- only in some minor detail. This is done as follows:</p>
+ of different programs is called <em>procedural abstraction</em>.
+ Procedural abstraction can be used to write several
+ different functions that have a similar structure, but differ
+ in some minor detail. This is done as follows:</p>
<list type="ordered">
- <item>write one function which represents the common features of
- these functions</item>
- <item>parameterize the difference in terms of functions which
+ <item><em>Step 1.</em> Write one function that represents the common features of
+ these functions.</item>
+ <item><em>Step 2.</em> Parameterize the difference in terms of functions that
are passed as arguments to the common function.</item>
</list>
</section>
<section>
- <title>Example 2 - foreach</title>
- <p>This example illustrates procedural abstraction. Initially, we
- show the following two examples written as conventional
- functions:</p>
- <list type="ordered">
- <item>all elements of a list are printed onto a stream</item>
- <item>a message is broadcast to a list of processes.</item>
- </list>
+ <title>foreach</title>
+ <p>This section illustrates procedural abstraction. Initially,
+ the following two examples are written as conventional
+ functions.</p>
+ <p>This function prints all elements of a list onto a stream:</p>
<code type="none">
print_list(Stream, [H|T]) ->
io:format(Stream, "~p~n", [H]),
print_list(Stream, T);
print_list(Stream, []) ->
true.</code>
+ <p>This function broadcasts a message to a list of processes:</p>
<code type="none">
broadcast(Msg, [Pid|Pids]) ->
Pid ! Msg,
broadcast(Msg, Pids);
broadcast(_, []) ->
true.</code>
- <p>Both these functions have a very similar structure. They both
- iterate over a list doing something to each element in the list.
- The "something" has to be carried round as an extra argument to
- the function which does this.</p>
+ <p>These two functions have a similar structure. They both
+ iterate over a list and do something to each element in the list.
+ The "something" is passed on as an extra argument to
+ the function that does this.</p>
<p>The function <c>foreach</c> expresses this similarity:</p>
<codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
- <p>Using <c>foreach</c>, <c>print_list</c> becomes:</p>
+ <p>Using the function <c>foreach</c>, the function <c>print_list</c> becomes:</p>
<code type="none">
foreach(fun(H) -> io:format(S, "~p~n",[H]) end, L)</code>
- <p><c>broadcast</c> becomes:</p>
+ <p>Using the function <c>foreach</c>, the function <c>broadcast</c> becomes:</p>
<code type="none">
foreach(fun(Pid) -> Pid ! M end, L)</code>
<p><c>foreach</c> is evaluated for its side-effect and not its
value. <c>foreach(Fun ,L)</c> calls <c>Fun(X)</c> for each
element <c>X</c> in <c>L</c> and the processing occurs in
- the order in which the elements were defined in <c>L</c>.
+ the order that the elements were defined in <c>L</c>.
<c>map</c> does not define the order in which its elements are
processed.</p>
</section>
<section>
- <title>The Syntax of Funs</title>
- <p>Funs are written with the syntax:</p>
+ <title>Syntax of Funs</title>
+ <p>Funs are written with the following syntax (see <seealso
+ marker="doc/reference_manual:expressions#funs">Fun Expressions
+ </seealso> for full description):</p>
<code type="none">
F = fun (Arg1, Arg2, ... ArgN) ->
...
end</code>
<p>This creates an anonymous function of <c>N</c> arguments and
binds it to the variable <c>F</c>.</p>
- <p>If we have already written a function in the same module and
- wish to pass this function as an argument, we can use
- the following syntax:</p>
+ <p>Another function, <c>FunctionName</c>, written in the same module,
+ can be passed as an argument, using the following syntax:</p>
<code type="none">
F = fun FunctionName/Arity</code>
- <p>With this form of function reference, the function which is
+ <p>With this form of function reference, the function that is
referred to does not need to be exported from the module.</p>
- <p>We can also refer to a function defined in a different module
+ <p>It is also possible to refer to a function defined in a different module,
with the following syntax:</p>
<code type="none">
-F = {Module, FunctionName}</code>
+F = fun Module:FunctionName/Arity</code>
<p>In this case, the function must be exported from the module in
question.</p>
- <p>The follow program illustrates the different ways of creating
+ <p>The following program illustrates the different ways of creating
funs:</p>
<codeinclude file="fun_test.erl" tag="%1" type="erl"></codeinclude>
- <p>We can evaluate the fun <c>F</c> with the syntax:</p>
+ <p>The fun <c>F</c> can be evaluated with the following syntax:</p>
<code type="none">
F(Arg1, Arg2, ..., Argn)</code>
<p>To check whether a term is a fun, use the test
- <c>is_function/1</c> in a guard. Example:</p>
+ <c>is_function/1</c> in a guard.</p>
+ <p><em>Example:</em></p>
<code type="none">
f(F, Args) when is_function(F) ->
apply(F, Args);
f(N, _) when is_integer(N) ->
N.</code>
- <p>Funs are a distinct type. The BIFs erlang:fun_info/1,2 can
+ <p>Funs are a distinct type. The BIFs <c>erlang:fun_info/1,2</c> can
be used to retrieve information about a fun, and the BIF
- erlang:fun_to_list/1 returns a textual representation of a fun.
- The check_process_code/2 BIF returns true if the process
+ <c>erlang:fun_to_list/1</c> returns a textual representation of a fun.
+ The <c>check_process_code/2</c> BIF returns <c>true</c> if the process
contains funs that depend on the old version of a module.</p>
- <note>
- <p>In OTP R5 and earlier releases, funs were represented using
- tuples.</p>
- </note>
</section>
<section>
<title>Variable Bindings Within a Fun</title>
- <p>The scope rules for variables which occur in funs are as
+ <p>The scope rules for variables that occur in funs are as
follows:</p>
<list type="bulleted">
- <item>All variables which occur in the head of a fun are assumed
+ <item>All variables that occur in the head of a fun are assumed
to be "fresh" variables.</item>
- <item>Variables which are defined before the fun, and which
+ <item>Variables that are defined before the fun, and that
occur in function calls or guard tests within the fun, have
the values they had outside the fun.</item>
- <item>No variables may be exported from a fun.</item>
+ <item>Variables cannot be exported from a fun.</item>
</list>
<p>The following examples illustrate these rules:</p>
<code type="none">
@@ -177,12 +172,13 @@ print_list(File, List) ->
{ok, Stream} = file:open(File, write),
foreach(fun(X) -> io:format(Stream,"~p~n",[X]) end, List),
file:close(Stream).</code>
- <p>In the above example, the variable <c>X</c> which is defined in
- the head of the fun is a new variable. The value of the variable
- <c>Stream</c> which is used within within the fun gets its value
+ <p>Here, the variable <c>X</c>, defined in
+ the head of the fun, is a new variable. The variable
+ <c>Stream</c>, which is used within the fun, gets its value
from the <c>file:open</c> line.</p>
- <p>Since any variable which occurs in the head of a fun is
- considered a new variable it would be equally valid to write:</p>
+ <p>As any variable that occurs in the head of a fun is
+ considered a new variable, it is equally valid to write
+ as follows:</p>
<code type="none">
print_list(File, List) ->
{ok, Stream} = file:open(File, write),
@@ -190,21 +186,21 @@ print_list(File, List) ->
io:format(Stream,"~p~n",[File])
end, List),
file:close(Stream).</code>
- <p>In this example, <c>File</c> is used as the new variable
- instead of <c>X</c>. This is rather silly since code in the body
- of the fun cannot refer to the variable <c>File</c> which is
- defined outside the fun. Compiling this example will yield
- the diagnostic:</p>
+ <p>Here, <c>File</c> is used as the new variable
+ instead of <c>X</c>. This is not so wise because code in the fun
+ body cannot refer to the variable <c>File</c>, which is
+ defined outside of the fun. Compiling this example gives
+ the following diagnostic:</p>
<code type="none">
./FileName.erl:Line: Warning: variable 'File'
- shadowed in 'lambda head'</code>
- <p>This reminds us that the variable <c>File</c> which is defined
- inside the fun collides with the variable <c>File</c> which is
+ shadowed in 'fun'</code>
+ <p>This indicates that the variable <c>File</c>, which is defined
+ inside the fun, collides with the variable <c>File</c>, which is
defined outside the fun.</p>
<p>The rules for importing variables into a fun has the consequence
- that certain pattern matching operations have to be moved into
+ that certain pattern matching operations must be moved into
guard expressions and cannot be written in the head of the fun.
- For example, we might write the following code if we intend
+ For example, you might write the following code if you intend
the first clause of <c>F</c> to be evaluated when the value of
its argument is <c>Y</c>:</p>
<code type="none">
@@ -216,7 +212,7 @@ f(...) ->
...
end, ...)
...</code>
- <p>instead of</p>
+ <p>instead of writng the following code:</p>
<code type="none">
f(...) ->
Y = ...
@@ -229,35 +225,37 @@ f(...) ->
</section>
<section>
- <title>Funs and the Module Lists</title>
+ <title>Funs and Module Lists</title>
<p>The following examples show a dialogue with the Erlang shell.
All the higher order functions discussed are exported from
the module <c>lists</c>.</p>
<section>
<title>map</title>
+ <p><c>map</c> takes a function of one argument and a list of terms:</p>
<codeinclude file="funs1.erl" tag="%1" type="erl"></codeinclude>
- <p><c>map</c> takes a function of one argument and a list of
- terms. It returns the list obtained by applying the function
+ <p>It returns the list obtained by applying the function
to every argument in the list.</p>
+ <p>When a new fun is defined in the shell, the value of the fun
+ is printed as <c><![CDATA[Fun#<erl_eval>]]></c>:</p>
<pre>
> <input>Double = fun(X) -> 2 * X end.</input>
#Fun&lt;erl_eval.6.72228031&gt;
> <input>lists:map(Double, [1,2,3,4,5]).</input>
[2,4,6,8,10]</pre>
- <p>When a new fun is defined in the shell, the value of the Fun
- is printed as <c><![CDATA[Fun#<erl_eval>]]></c>.</p>
+
</section>
<section>
<title>any</title>
- <codeinclude file="funs1.erl" tag="%4" type="erl"></codeinclude>
<p><c>any</c> takes a predicate <c>P</c> of one argument and a
- list of terms. A predicate is a function which returns
- <c>true</c> or <c>false</c>. <c>any</c> is true if there is a
- term <c>X</c> in the list such that <c>P(X)</c> is <c>true</c>.</p>
- <p>We define a predicate <c>Big(X)</c> which is <c>true</c> if
- its argument is greater that 10.</p>
+ list of terms:</p>
+ <codeinclude file="funs1.erl" tag="%4" type="erl"></codeinclude>
+ <p>A predicate is a function that returns <c>true</c> or <c>false</c>.
+ <c>any</c> is <c>true</c> if there is a term <c>X</c> in the list such that
+ <c>P(X)</c> is <c>true</c>.</p>
+ <p>A predicate <c>Big(X)</c> is defined, which is <c>true</c> if
+ its argument is greater that 10:</p>
<pre>
> <input>Big = fun(X) -> if X > 10 -> true; true -> false end end.</input>
#Fun&lt;erl_eval.6.72228031&gt;
@@ -269,9 +267,10 @@ true</pre>
<section>
<title>all</title>
+ <p><c>all</c> has the same arguments as <c>any</c>:</p>
<codeinclude file="funs1.erl" tag="%3" type="erl"></codeinclude>
- <p><c>all</c> has the same arguments as <c>any</c>. It is true
- if the predicate applied to all elements in the list is true.</p>
+ <p>It is <c>true</c>
+ if the predicate applied to all elements in the list is <c>true</c>.</p>
<pre>
> <input>lists:all(Big, [1,2,3,4,12,6]).</input>
false
@@ -281,11 +280,12 @@ true</pre>
<section>
<title>foreach</title>
- <codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
<p><c>foreach</c> takes a function of one argument and a list of
- terms. The function is applied to each argument in the list.
- <c>foreach</c> returns <c>ok</c>. It is used for its
- side-effect only.</p>
+ terms:</p>
+ <codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
+ <p>The function is applied to each argument in the list.
+ <c>foreach</c> returns <c>ok</c>. It is only used for its
+ side-effect:</p>
<pre>
> <input>lists:foreach(fun(X) -> io:format("~w~n",[X]) end, [1,2,3,4]).</input>
1
@@ -297,15 +297,16 @@ ok</pre>
<section>
<title>foldl</title>
- <codeinclude file="funs1.erl" tag="%8" type="erl"></codeinclude>
<p><c>foldl</c> takes a function of two arguments, an
- accumulator and a list. The function is called with two
+ accumulator and a list:</p>
+ <codeinclude file="funs1.erl" tag="%8" type="erl"></codeinclude>
+ <p>The function is called with two
arguments. The first argument is the successive elements in
- the list, the second argument is the accumulator. The function
- must return a new accumulator which is used the next time
+ the list. The second argument is the accumulator. The function
+ must return a new accumulator, which is used the next time
the function is called.</p>
- <p>If we have a list of lists <c>L = ["I","like","Erlang"]</c>,
- then we can sum the lengths of all the strings in <c>L</c> as
+ <p>If you have a list of lists <c>L = ["I","like","Erlang"]</c>,
+ then you can sum the lengths of all the strings in <c>L</c> as
follows:</p>
<pre>
> <input>L = ["I","like","Erlang"].</input>
@@ -325,11 +326,11 @@ end</code>
<section>
<title>mapfoldl</title>
+ <p><c>mapfoldl</c> simultaneously maps and folds over a list:</p>
<codeinclude file="funs1.erl" tag="%10" type="erl"></codeinclude>
- <p><c>mapfoldl</c> simultaneously maps and folds over a list.
- The following example shows how to change all letters in
- <c>L</c> to upper case and count them.</p>
- <p>First upcase:</p>
+ <p>The following example shows how to change all letters in
+ <c>L</c> to upper case and then count them.</p>
+ <p>First the change to upper case:</p>
<pre>
> <input>Upcase = fun(X) when $a =&lt; X, X =&lt; $z -> X + $A - $a;</input>
<input>(X) -> X</input>
@@ -344,7 +345,7 @@ end</code>
"ERLANG"
> <input>lists:map(Upcase_word, L).</input>
["I","LIKE","ERLANG"]</pre>
- <p>Now we can do the fold and the map at the same time:</p>
+ <p>Now, the fold and the map can be done at the same time:</p>
<pre>
> <input>lists:mapfoldl(fun(Word, Sum) -></input>
<input>{Upcase_word(Word), Sum + length(Word)}</input>
@@ -354,23 +355,24 @@ end</code>
<section>
<title>filter</title>
- <codeinclude file="funs1.erl" tag="%9" type="erl"></codeinclude>
<p><c>filter</c> takes a predicate of one argument and a list
- and returns all element in the list which satisfy
- the predicate.</p>
+ and returns all elements in the list that satisfy
+ the predicate:</p>
+ <codeinclude file="funs1.erl" tag="%9" type="erl"></codeinclude>
<pre>
> <input>lists:filter(Big, [500,12,2,45,6,7]).</input>
[500,12,45]</pre>
- <p>When we combine maps and filters we can write very succinct
- code. For example, suppose we want to define a set difference
- function. We want to define <c>diff(L1, L2)</c> to be
- the difference between the lists <c>L1</c> and <c>L2</c>.
- This is the list of all elements in L1 which are not contained
- in L2. This code can be written as follows:</p>
+ <p>Combining maps and filters enables writing of very succinct
+ code. For example, to define a set difference
+ function <c>diff(L1, L2)</c> to be
+ the difference between the lists <c>L1</c> and <c>L2</c>,
+ the code can be written as follows:</p>
<code type="none">
diff(L1, L2) ->
filter(fun(X) -> not member(X, L2) end, L1).</code>
- <p>The AND intersection of the list <c>L1</c> and <c>L2</c> is
+ <p>This gives the list of all elements in L1 that are not contained
+ in L2.</p>
+ <p> The AND intersection of the list <c>L1</c> and <c>L2</c> is
also easily defined:</p>
<code type="none">
intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).</code>
@@ -378,9 +380,9 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).</code>
<section>
<title>takewhile</title>
- <codeinclude file="funs1.erl" tag="%5" type="erl"></codeinclude>
<p><c>takewhile(P, L)</c> takes elements <c>X</c> from a list
- <c>L</c> as long as the predicate <c>P(X)</c> is true.</p>
+ <c>L</c> as long as the predicate <c>P(X)</c> is true:</p>
+ <codeinclude file="funs1.erl" tag="%5" type="erl"></codeinclude>
<pre>
> <input>lists:takewhile(Big, [200,500,45,5,3,45,6]).</input>
[200,500,45]</pre>
@@ -388,8 +390,8 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).</code>
<section>
<title>dropwhile</title>
+ <p><c>dropwhile</c> is the complement of <c>takewhile</c>:</p>
<codeinclude file="funs1.erl" tag="%6" type="erl"></codeinclude>
- <p><c>dropwhile</c> is the complement of <c>takewhile</c>.</p>
<pre>
> <input>lists:dropwhile(Big, [200,500,45,5,3,45,6]).</input>
[5,3,45,6]</pre>
@@ -397,10 +399,10 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).</code>
<section>
<title>splitwith</title>
- <codeinclude file="funs1.erl" tag="%7" type="erl"></codeinclude>
<p><c>splitwith(P, L)</c> splits the list <c>L</c> into the two
- sub-lists <c>{L1, L2}</c>, where <c>L = takewhile(P, L)</c>
- and <c>L2 = dropwhile(P, L)</c>.</p>
+ sublists <c>{L1, L2}</c>, where <c>L = takewhile(P, L)</c>
+ and <c>L2 = dropwhile(P, L)</c>:</p>
+ <codeinclude file="funs1.erl" tag="%7" type="erl"></codeinclude>
<pre>
> <input>lists:splitwith(Big, [200,500,45,5,3,45,6]).</input>
{[200,500,45],[5,3,45,6]}</pre>
@@ -408,17 +410,17 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).</code>
</section>
<section>
- <title>Funs Which Return Funs</title>
- <p>So far, this section has only described functions which take
- funs as arguments. It is also possible to write more powerful
- functions which themselves return funs. The following examples
- illustrate these type of functions.</p>
+ <title>Funs Returning Funs</title>
+ <p>So far, only functions that take
+ funs as arguments have been described. More powerful
+ functions, that themselves return funs, can also be written. The following
+ examples illustrate these type of functions.</p>
<section>
<title>Simple Higher Order Functions</title>
- <p><c>Adder(X)</c> is a function which, given <c>X</c>, returns
+ <p><c>Adder(X)</c> is a function that given <c>X</c>, returns
a new function <c>G</c> such that <c>G(K)</c> returns
- <c>K + X</c>.</p>
+ <c>K + X</c>:</p>
<pre>
> <input>Adder = fun(X) -> fun(Y) -> X + Y end end.</input>
#Fun&lt;erl_eval.6.72228031&gt;
@@ -438,7 +440,7 @@ ints_from(N) ->
fun() ->
[N|ints_from(N+1)]
end.</code>
- <p>Then we can proceed as follows:</p>
+ <p>Then proceed as follows:</p>
<pre>
> <input>XX = lazy:ints_from(1).</input>
#Fun&lt;lazy.0.29874839&gt;
@@ -450,7 +452,7 @@ ints_from(N) ->
#Fun&lt;lazy.0.29874839&gt;
> <input>hd(Y()).</input>
2</pre>
- <p>etc. - this is an example of "lazy embedding".</p>
+ <p>And so on. This is an example of "lazy embedding".</p>
</section>
<section>
@@ -459,17 +461,21 @@ ints_from(N) ->
<pre>
Parser(Toks) -> {ok, Tree, Toks1} | fail</pre>
<p><c>Toks</c> is the list of tokens to be parsed. A successful
- parse returns <c>{ok, Tree, Toks1}</c>, where <c>Tree</c> is a
- parse tree and <c>Toks1</c> is a tail of <c>Tree</c> which
- contains symbols encountered after the structure which was
- correctly parsed. Otherwise <c>fail</c> is returned.</p>
- <p>The example which follows illustrates a simple, functional
- parser which parses the grammar:</p>
+ parse returns <c>{ok, Tree, Toks1}</c>.</p>
+ <list type="bulleted">
+ <item><c>Tree</c> is a parse tree.</item>
+ <item><c>Toks1</c> is a tail of <c>Tree</c> that
+ contains symbols encountered after the structure that was
+ correctly parsed.</item>
+ </list>
+ <p>An unsuccessful parse returns <c>fail</c>.</p>
+ <p>The following example illustrates a simple, functional
+ parser that parses the grammar:</p>
<pre>
(a | b) &amp; (c | d)</pre>
<p>The following code defines a function <c>pconst(X)</c> in
- the module <c>funparse</c>, which returns a fun which parses a
- list of tokens.</p>
+ the module <c>funparse</c>, which returns a fun that parses a
+ list of tokens:</p>
<codeinclude file="funparse.erl" tag="%14" type="erl"></codeinclude>
<p>This function can be used as follows:</p>
<pre>
@@ -479,17 +485,18 @@ Parser(Toks) -> {ok, Tree, Toks1} | fail</pre>
{ok,{const,a},[b,c]}
> <input>P1([x,y,z]).</input>
fail</pre>
- <p>Next, we define the two higher order functions <c>pand</c>
- and <c>por</c> which combine primitive parsers to produce more
- complex parsers. Firstly <c>pand</c>:</p>
+ <p>Next, the two higher order functions <c>pand</c>
+ and <c>por</c> are defined. They combine primitive parsers to produce more
+ complex parsers.</p>
+ <p>First <c>pand</c>:</p>
<codeinclude file="funparse.erl" tag="%16" type="erl"></codeinclude>
<p>Given a parser <c>P1</c> for grammar <c>G1</c>, and a parser
<c>P2</c> for grammar <c>G2</c>, <c>pand(P1, P2)</c> returns a
- parser for the grammar which consists of sequences of tokens
- which satisfy <c>G1</c> followed by sequences of tokens which
+ parser for the grammar, which consists of sequences of tokens
+ that satisfy <c>G1</c>, followed by sequences of tokens that
satisfy <c>G2</c>.</p>
<p><c>por(P1, P2)</c> returns a parser for the language
- described by the grammar <c>G1</c> or <c>G2</c>.</p>
+ described by the grammar <c>G1</c> or <c>G2</c>:</p>
<codeinclude file="funparse.erl" tag="%15" type="erl"></codeinclude>
<p>The original problem was to parse the grammar
<c><![CDATA[(a | b) & (c | d)]]></c>. The following code addresses this
@@ -497,7 +504,7 @@ fail</pre>
<codeinclude file="funparse.erl" tag="%13" type="erl"></codeinclude>
<p>The following code adds a parser interface to the grammar:</p>
<codeinclude file="funparse.erl" tag="%12" type="erl"></codeinclude>
- <p>We can test this parser as follows:</p>
+ <p>The parser can be tested as follows:</p>
<pre>
> <input>funparse:parse([a,c]).</input>
{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
diff --git a/system/doc/programming_examples/list_comprehensions.xml b/system/doc/programming_examples/list_comprehensions.xml
index d6c8a66e13..5667571ec5 100644
--- a/system/doc/programming_examples/list_comprehensions.xml
+++ b/system/doc/programming_examples/list_comprehensions.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,18 +32,15 @@
<section>
<title>Simple Examples</title>
- <p>We start with a simple example:</p>
+ <p>This section starts with a simple example, showing a generator and a filter:</p>
<pre>
> <input>[X || X &lt;- [1,2,a,3,4,b,5,6], X > 3].</input>
[a,4,b,5,6]</pre>
- <p>This should be read as follows:</p>
- <quote>
- <p>The list of X such that X is taken from the list
+ <p>This is read as follows: The list of X such that X is taken from the list
<c>[1,2,a,...]</c> and X is greater than 3.</p>
- </quote>
<p>The notation <c><![CDATA[X <- [1,2,a,...]]]></c> is a generator and
the expression <c>X > 3</c> is a filter.</p>
- <p>An additional filter can be added in order to restrict
+ <p>An additional filter, <c>integer(X)</c>, can be added to restrict
the result to integers:</p>
<pre>
> <input>[X || X &lt;- [1,2,a,3,4,b,5,6], integer(X), X > 3].</input>
@@ -56,7 +54,7 @@
<section>
<title>Quick Sort</title>
- <p>The well known quick sort routine can be written as follows:</p>
+ <p>The well-known quick sort routine can be written as follows:</p>
<code type="none"><![CDATA[
sort([Pivot|T]) ->
sort([ X || X <- T, X < Pivot]) ++
@@ -64,15 +62,20 @@ sort([Pivot|T]) ->
sort([ X || X <- T, X >= Pivot]);
sort([]) -> [].]]></code>
<p>The expression <c><![CDATA[[X || X <- T, X < Pivot]]]></c> is the list of
- all elements in <c>T</c>, which are less than <c>Pivot</c>.</p>
+ all elements in <c>T</c> that are less than <c>Pivot</c>.</p>
<p><c><![CDATA[[X || X <- T, X >= Pivot]]]></c> is the list of all elements in
- <c>T</c>, which are greater or equal to <c>Pivot</c>.</p>
- <p>To sort a list, we isolate the first element in the list and
- split the list into two sub-lists. The first sub-list contains
- all elements which are smaller than the first element in
- the list, the second contains all elements which are greater
- than or equal to the first element in the list. We then sort
- the sub-lists and combine the results.</p>
+ <c>T</c> that are greater than or equal to <c>Pivot</c>.</p>
+ <p>A list sorted as follows:</p>
+ <list type="bulleted">
+ <item>The first element in the list is isolated
+ and the list is split into two sublists.</item>
+ <item>The first sublist contains
+ all elements that are smaller than the first element in
+ the list.</item>
+ <item>The second sublist contains all elements that are greater
+ than, or equal to, the first element in the list.</item>
+ <item>Then the sublists are sorted and the results are combined.</item>
+ </list>
</section>
<section>
@@ -82,10 +85,10 @@ sort([]) -> [].]]></code>
<code type="none"><![CDATA[
perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].]]></code>
- <p>We take take <c>H</c> from <c>L</c> in all possible ways.
+ <p>This takes <c>H</c> from <c>L</c> in all possible ways.
The result is the set of all lists <c>[H|T]</c>, where <c>T</c>
- is the set of all possible permutations of <c>L</c> with
- <c>H</c> removed.</p>
+ is the set of all possible permutations of <c>L</c>, with
+ <c>H</c> removed:</p>
<pre>
> <input>perms([b,u,g]).</input>
[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]</pre>
@@ -97,7 +100,7 @@ perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].]]></code>
that <c>A**2 + B**2 = C**2</c>.</p>
<p>The function <c>pyth(N)</c> generates a list of all integers
<c>{A,B,C}</c> such that <c>A**2 + B**2 = C**2</c> and where
- the sum of the sides is equal to or less than <c>N</c>.</p>
+ the sum of the sides is equal to, or less than, <c>N</c>:</p>
<code type="none"><![CDATA[
pyth(N) ->
[ {A,B,C} ||
@@ -140,7 +143,7 @@ pyth1(N) ->
</section>
<section>
- <title>Simplifications with List Comprehensions</title>
+ <title>Simplifications With List Comprehensions</title>
<p>As an example, list comprehensions can be used to simplify some
of the functions in <c>lists.erl</c>:</p>
<code type="none"><![CDATA[
@@ -151,45 +154,47 @@ filter(Pred, L) -> [X || X <- L, Pred(X)].]]></code>
<section>
<title>Variable Bindings in List Comprehensions</title>
- <p>The scope rules for variables which occur in list
+ <p>The scope rules for variables that occur in list
comprehensions are as follows:</p>
<list type="bulleted">
- <item>all variables which occur in a generator pattern are
- assumed to be "fresh" variables</item>
- <item>any variables which are defined before the list
- comprehension and which are used in filters have the values
- they had before the list comprehension</item>
- <item>no variables may be exported from a list comprehension.</item>
+ <item>All variables that occur in a generator pattern are
+ assumed to be "fresh" variables.</item>
+ <item>Any variables that are defined before the list
+ comprehension, and that are used in filters, have the values
+ they had before the list comprehension.</item>
+ <item>Variables cannot be exported from a list comprehension.</item>
</list>
- <p>As an example of these rules, suppose we want to write
+ <p>As an example of these rules, suppose you want to write
the function <c>select</c>, which selects certain elements from
- a list of tuples. We might write
+ a list of tuples. Suppose you write
<c><![CDATA[select(X, L) -> [Y || {X, Y} <- L].]]></c> with the intention
- of extracting all tuples from <c>L</c> where the first item is
+ of extracting all tuples from <c>L</c>, where the first item is
<c>X</c>.</p>
- <p>Compiling this yields the following diagnostic:</p>
+ <p>Compiling this gives the following diagnostic:</p>
<code type="none">
./FileName.erl:Line: Warning: variable 'X' shadowed in generate</code>
- <p>This diagnostic warns us that the variable <c>X</c> in
- the pattern is not the same variable as the variable <c>X</c>
- which occurs in the function head.</p>
- <p>Evaluating <c>select</c> yields the following result:</p>
+ <p>This diagnostic warns that the variable <c>X</c> in
+ the pattern is not the same as the variable <c>X</c>
+ that occurs in the function head.</p>
+ <p>Evaluating <c>select</c> gives the following result:</p>
<pre>
> <input>select(b,[{a,1},{b,2},{c,3},{b,7}]).</input>
[1,2,3,7]</pre>
- <p>This result is not what we wanted. To achieve the desired
- effect we must write <c>select</c> as follows:</p>
+ <p>This is not the wanted result. To achieve the desired
+ effect, <c>select</c> must be written as follows:</p>
<code type="none"><![CDATA[
select(X, L) -> [Y || {X1, Y} <- L, X == X1].]]></code>
<p>The generator now contains unbound variables and the test has
- been moved into the filter. This now works as expected:</p>
+ been moved into the filter.</p>
+ <p>This now works as expected:</p>
<pre>
> <input>select(b,[{a,1},{b,2},{c,3},{b,7}]).</input>
[2,7]</pre>
- <p>One consequence of the rules for importing variables into a
+ <p>A consequence of the rules for importing variables into a
list comprehensions is that certain pattern matching operations
- have to be moved into the filters and cannot be written directly
- in the generators. To illustrate this, do not write as follows:</p>
+ must be moved into the filters and cannot be written directly
+ in the generators.</p>
+ <p>To illustrate this, do <em>not</em> write as follows:</p>
<code type="none"><![CDATA[
f(...) ->
Y = ...
diff --git a/system/doc/programming_examples/part.xml b/system/doc/programming_examples/part.xml
index 0bec9b4cf5..e1f8cc5d57 100644
--- a/system/doc/programming_examples/part.xml
+++ b/system/doc/programming_examples/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,8 +29,9 @@
<rev></rev>
</header>
<description>
- <p>This chapter contains examples on using records, funs, list
- comprehensions and the bit syntax.</p>
+ <marker id="programming examples"></marker>
+ <p>This section contains examples on using records, funs, list
+ comprehensions, and the bit syntax.</p>
</description>
<xi:include href="records.xml"/>
<xi:include href="funs.xml"/>
diff --git a/system/doc/programming_examples/records.xml b/system/doc/programming_examples/records.xml
index 58cf136a0b..6bda6dc0fd 100644
--- a/system/doc/programming_examples/records.xml
+++ b/system/doc/programming_examples/records.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -30,37 +31,39 @@
</header>
<section>
- <title>Records vs Tuples</title>
- <p>The main advantage of using records instead of tuples is that
+ <title>Records and Tuples</title>
+ <p>The main advantage of using records rather than tuples is that
fields in a record are accessed by name, whereas fields in a
tuple are accessed by position. To illustrate these differences,
- suppose that we want to represent a person with the tuple
+ suppose that you want to represent a person with the tuple
<c>{Name, Address, Phone}</c>.</p>
- <p>We must remember that the <c>Name</c> field is the first
- element of the tuple, the <c>Address</c> field is the second
- element, and so on, in order to write functions which manipulate
- this data. For example, to extract data from a variable <c>P</c>
- which contains such a tuple we might write the following code
- and then use pattern matching to extract the relevant fields.</p>
+ <p>To write functions that manipulate this data, remember the following:</p>
+ <list type="bulleted">
+ <item>The <c>Name</c> field is the first element of the tuple.</item>
+ <item>The <c>Address</c> field is the second element.</item>
+ <item>The <c>Phone</c> field is the third element.</item>
+ </list>
+ <p>For example, to extract data from a variable <c>P</c>
+ that contains such a tuple, you can write the following code
+ and then use pattern matching to extract the relevant fields:</p>
<code type="none">
Name = element(1, P),
Address = element(2, P),
...</code>
- <p>Code like this is difficult to read and understand and errors
- occur if we get the numbering of the elements in the tuple wrong.
- If we change the data representation by re-ordering the fields,
- or by adding or removing a field, then all references to
- the person tuple, wherever they occur, must be checked and
- possibly modified.</p>
- <p>Records allow us to refer to the fields by name and not
- position. We use a record instead of a tuple to store the data.
- If we write a record definition of the type shown below, we can
- then refer to the fields of the record by name.</p>
+ <p>Such code is difficult to read and understand, and errors
+ occur if the numbering of the elements in the tuple is wrong.
+ If the data representation of the fields is changed, by re-ordering,
+ adding, or removing fields, all references to
+ the person tuple must be checked and possibly modified.</p>
+ <p>Records allow references to the fields by name, instead of by
+ position. In the following example, a record instead of a tuple
+ is used to store the data:</p>
<code type="none">
-record(person, {name, phone, address}).</code>
- <p>For example, if <c>P</c> is now a variable whose value is a
- <c>person</c> record, we can code as follows in order to access
- the name and address fields of the records.</p>
+ <p>This enables references to the fields of the record by name.
+ For example, if <c>P</c> is a variable whose value is a
+ <c>person</c> record, the following code access
+ the name and address fields of the records:</p>
<code type="none">
Name = P#person.name,
Address = P#person.address,
@@ -72,24 +75,25 @@ Address = P#person.address,
<section>
<title>Defining a Record</title>
- <p>This definition of a person will be used in many of
- the examples which follow. It contains three fields, <c>name</c>,
- <c>phone</c> and <c>address</c>. The default values for
+ <p>This following definition of a <c>person</c> is used in several
+ examples in this section. Three fields are included, <c>name</c>,
+ <c>phone</c>, and <c>address</c>. The default values for
<c>name</c> and <c>phone</c> is "" and [], respectively.
The default value for <c>address</c> is the atom
<c>undefined</c>, since no default value is supplied for this
field:</p>
<pre>
-record(person, {name = "", phone = [], address}).</pre>
- <p>We have to define the record in the shell in order to be able
- use the record syntax in the examples:</p>
+ <p>The record must be defined in the shell to enable
+ use of the record syntax in the examples:</p>
<pre>
> <input>rd(person, {name = "", phone = [], address}).</input>
person</pre>
- <p>This is due to the fact that record definitions are available
- at compile time only, not at runtime. See <c>shell(3)</c> for
- details on records in the shell.
- </p>
+ <p>This is because record definitions are only available
+ at compile time, not at runtime. For details on records
+ in the shell, see the
+ <seealso marker="stdlib:shell">shell(3)</seealso>
+ manual page in <c>stdlib</c>.</p>
</section>
<section>
@@ -98,12 +102,12 @@ person</pre>
<pre>
> <input>#person{phone=[0,8,2,3,4,3,1,2], name="Robert"}.</input>
#person{name = "Robert",phone = [0,8,2,3,4,3,1,2],address = undefined}</pre>
- <p>Since the <c>address</c> field was omitted, its default value
+ <p>As the <c>address</c> field was omitted, its default value
is used.</p>
- <p>There is a new feature introduced in Erlang 5.1/OTP R8B,
- with which you can set a value to all fields in a record,
- overriding the defaults in the record specification. The special
- field <c>_</c>, means "all fields not explicitly specified".</p>
+ <p>From Erlang 5.1/OTP R8B, a value to all
+ fields in a record can be set with the special field <c>_</c>.
+ <c>_</c> means "all fields not explicitly specified".</p>
+ <p><em>Example:</em></p>
<pre>
> <input>#person{name = "Jakob", _ = '_'}.</input>
#person{name = "Jakob",phone = '_',address = '_'}</pre>
@@ -114,6 +118,7 @@ person</pre>
<section>
<title>Accessing a Record Field</title>
+ <p>The following example shows how to access a record field:</p>
<pre>
> <input>P = #person{name = "Joe", phone = [0,8,2,3,4,3,1,2]}.</input>
#person{name = "Joe",phone = [0,8,2,3,4,3,1,2],address = undefined}
@@ -123,6 +128,7 @@ person</pre>
<section>
<title>Updating a Record</title>
+ <p>The following example shows how to update a record:</p>
<pre>
> <input>P1 = #person{name="Joe", phone=[1,2,3], address="A street"}.</input>
#person{name = "Joe",phone = [1,2,3],address = "A street"}
@@ -133,7 +139,7 @@ person</pre>
<section>
<title>Type Testing</title>
<p>The following example shows that the guard succeeds if
- <c>P</c> is record of type <c>person</c>.</p>
+ <c>P</c> is record of type <c>person</c>:</p>
<pre>
foo(P) when is_record(P, person) -> a_person;
foo(_) -> not_a_person.</pre>
@@ -141,7 +147,7 @@ foo(_) -> not_a_person.</pre>
<section>
<title>Pattern Matching</title>
- <p>Matching can be used in combination with records as shown in
+ <p>Matching can be used in combination with records, as shown in
the following example:</p>
<pre>
> <input>P3 = #person{name="Joe", phone=[0,0,7], address="A street"}.</input>
@@ -163,7 +169,7 @@ find_phone([], Name) ->
<section>
<title>Nested Records</title>
- <p>The value of a field in a record might be an instance of a
+ <p>The value of a field in a record can be an instance of a
record. Retrieval of nested data can be done stepwise, or in a
single step, as shown in the following example:</p>
<pre>
@@ -173,11 +179,12 @@ find_phone([], Name) ->
demo() ->
P = #person{name= #name{first="Robert",last="Virding"}, phone=123},
First = (P#person.name)#name.first.</pre>
- <p>In this example, <c>demo()</c> evaluates to <c>"Robert"</c>.</p>
+ <p>Here, <c>demo()</c> evaluates to <c>"Robert"</c>.</p>
</section>
<section>
- <title>Example</title>
+ <title>A Longer Example</title>
+ <p>Comments are embedded in the following example:</p>
<pre>
%% File: person.hrl
diff --git a/system/doc/programming_examples/xmlfiles.mk b/system/doc/programming_examples/xmlfiles.mk
index 5eb42a2881..cc77f48253 100644
--- a/system/doc/programming_examples/xmlfiles.mk
+++ b/system/doc/programming_examples/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/reference_manual/Makefile b/system/doc/reference_manual/Makefile
index 5ae46178a7..bf0567932c 100644
--- a/system/doc/reference_manual/Makefile
+++ b/system/doc/reference_manual/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/reference_manual/book.xml b/system/doc/reference_manual/book.xml
index 546fb36a57..6b7306fb77 100644
--- a/system/doc/reference_manual/book.xml
+++ b/system/doc/reference_manual/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/reference_manual/character_set.xml b/system/doc/reference_manual/character_set.xml
index b09b484582..d25f2c001d 100644
--- a/system/doc/reference_manual/character_set.xml
+++ b/system/doc/reference_manual/character_set.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2014</year><year>2014</year>
+ <year>2014</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,7 +32,7 @@
<section>
<title>Character Set</title>
- <p>In Erlang 4.8/OTP R5A the syntax of Erlang tokens was extended to
+ <p>Since Erlang 4.8/OTP R5A, the syntax of Erlang tokens is extended to
allow the use of the full ISO-8859-1 (Latin-1) character set. This
is noticeable in the following ways:</p>
<list type="bulleted">
@@ -98,7 +99,7 @@
<cell align="center" valign="middle">&oslash; - &yuml;</cell>
<cell align="left" valign="middle">Lowercase letters</cell>
</row>
- <tcaption>Character Classes.</tcaption>
+ <tcaption>Character Classes</tcaption>
</table>
<p>In Erlang/OTP R16B the syntax of Erlang tokens was extended to
handle Unicode. The support is limited to
@@ -111,13 +112,13 @@
</section>
<section>
<title>Source File Encoding</title>
- <p>The Erlang source file <marker
- id="encoding">encoding</marker> is selected by a
+ <marker id="encoding"></marker>
+ <p>The Erlang source file <c>encoding</c> is selected by a
comment in one of the first two lines of the source file. The
first string that matches the regular expression
<c>coding\s*[:=]\s*([-a-zA-Z0-9])+</c> selects the encoding. If
- the matching string is not a valid encoding it is ignored. The
- valid encodings are <c>Latin-1</c> and <c>UTF-8</c> where the
+ the matching string is an invalid encoding, it is ignored. The
+ valid encodings are <c>Latin-1</c> and <c>UTF-8</c>, where the
case of the characters can be chosen freely.</p>
<p>The following example selects UTF-8 as default encoding:</p>
<pre>
@@ -127,7 +128,7 @@
%% For this file we have chosen encoding = Latin-1</pre>
<pre>
%% -*- coding: latin-1 -*-</pre>
- <p>The default encoding for Erlang source files was changed from
- Latin-1 to UTF-8 in Erlang OTP 17.0.</p>
+ <p>The default encoding for Erlang source files is changed from
+ Latin-1 to UTF-8 since Erlang/OTP 17.0.</p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/code_loading.xml b/system/doc/reference_manual/code_loading.xml
index b5b5704df5..e9da40e02f 100644
--- a/system/doc/reference_manual/code_loading.xml
+++ b/system/doc/reference_manual/code_loading.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -29,35 +30,39 @@
<file>code_loading.xml</file>
</header>
<p>How code is compiled and loaded is not a language issue, but
- is system dependent. This chapter describes compilation and
- code loading in Erlang/OTP with pointers to relevant parts of
+ is system-dependent. This section describes compilation and
+ code loading in Erlang/OTP with references to relevant parts of
the documentation.</p>
<section>
<title>Compilation</title>
<p>Erlang programs must be <em>compiled</em> to object code.
- The compiler can generate a new file which contains the object
- code. The current abstract machine which runs the object code is
+ The compiler can generate a new file that contains the object
+ code. The current abstract machine, which runs the object code, is
called BEAM, therefore the object files get the suffix
<c>.beam</c>. The compiler can also generate a binary which can
be loaded directly.</p>
- <p>The compiler is located in the Kernel module <c>compile</c>, see
- <c>compile(3)</c>.</p>
+ <p>The compiler is located in the module <c>compile</c> (see the
+ <seealso marker="compiler:compile">compile(3)</seealso> manual page in
+ Compiler).</p>
<pre>
compile:file(Module)
compile:file(Module, Options)</pre>
<p>The Erlang shell understands the command <c>c(Module)</c> which
both compiles and loads <c>Module</c>.</p>
- <p>There is also a module <c>make</c> which provides a set of
- functions similar to the UNIX type Make functions, see
- <c>make(3)</c>.</p>
- <p>The compiler can also be accessed from the OS prompt, see
- <c>erl(1)</c>.</p>
+ <p>There is also a module <c>make</c>, which provides a set of
+ functions similar to the UNIX type Make functions, see the
+ <seealso marker="tools:make">make(3)</seealso>
+ manual page in Tools.</p>
+ <p>The compiler can also be accessed from the OS prompt, see the
+ <seealso marker="erts:erl">erl(1)</seealso> manual page in ERTS.</p>
<pre>
% erl -compile <input>Module1</input>...<input>ModuleN</input>
% erl -make</pre>
<p>The <c>erlc</c> program provides an even better way to compile
- modules from the shell, see <c>erlc(1)</c>. It understands a
+ modules from the shell, see the
+ <seealso marker="erts:erlc">erlc(1)</seealso> manual page in ERTS.
+ It understands a
number of flags that can be used to define macros, add search
paths for include files, and more.</p>
<pre>
@@ -68,13 +73,17 @@ compile:file(Module, Options)</pre>
<marker id="loading"></marker>
<title>Code Loading</title>
<p>The object code must be <em>loaded</em> into the Erlang runtime
- system. This is handled by the <em>code server</em>, see
- <c>code(3)</c>.</p>
- <p>The code server loads code according to a code loading strategy
+ system. This is handled by the <em>code server</em>, see the
+ <seealso marker="kernel:code">code(3)</seealso>
+ manual page in Kernel.</p>
+ <p>The code server loads code according to a code loading strategy,
which is either <em>interactive</em> (default) or
- <em>embedded</em>. In interactive mode, code are searched for in
+ <em>embedded</em>. In interactive mode, code is searched for in
a <em>code path</em> and loaded when first referenced. In
- embedded mode, code is loaded at start-up according to a <em>boot script</em>. This is described in <em>System Principles</em>.</p>
+ embedded mode, code is loaded at start-up according to a
+ <em>boot script</em>. This is described in
+ <seealso marker="doc/system_principles:system_principles#code_loading">
+ System Principles </seealso>.</p>
</section>
<section>
@@ -86,16 +95,17 @@ compile:file(Module, Options)</pre>
the system for the first time, the code becomes 'current'. If then
a new instance of the module is loaded, the code of the previous
instance becomes 'old' and the new instance becomes 'current'.</p>
- <p>Both old and current code is valid, and may be evaluated
+ <p>Both old and current code is valid, and can be evaluated
concurrently. Fully qualified function calls always refer to
- current code. Old code may still be evaluated because of processes
+ current code. Old code can still be evaluated because of processes
lingering in the old code.</p>
- <p>If a third instance of the module is loaded, the code server will
- remove (purge) the old code and any processes lingering in it will
- be terminated. Then the third instance becomes 'current' and
+ <p>If a third instance of the module is loaded, the code server
+ removes (purges) the old code and any processes lingering in it is
+ terminated. Then the third instance becomes 'current' and
the previously current code becomes 'old'.</p>
<p>To change from old code to current code, a process must make a
- fully qualified function call. Example:</p>
+ fully qualified function call.</p>
+ <p><em>Example:</em></p>
<pre>
-module(m).
-export([loop/0]).
@@ -109,60 +119,62 @@ loop() ->
loop()
end.</pre>
<p>To make the process change code, send the message
- <c>code_switch</c> to it. The process then will make a fully
- qualified call to <c>m:loop()</c> and change to current code.
- Note that <c>m:loop/0</c> must be exported.</p>
- <p>For code replacement of funs to work, the syntax
- <c>fun Module:FunctionName/Arity</c> should be used.</p>
+ <c>code_switch</c> to it. The process then makes a fully
+ qualified call to <c>m:loop()</c> and changes to current code.
+ Notice that <c>m:loop/0</c> must be exported.</p>
+ <p>For code replacement of funs to work, use the syntax
+ <c>fun Module:FunctionName/Arity</c>.</p>
</section>
<section>
<marker id="on_load"></marker>
- <title>Running a function when a module is loaded</title>
+ <title>Running a Function When a Module is Loaded</title>
<warning>
- <p>The <c>on_load</c> feature should be considered experimental
- as there are a number of known weak points in current semantics
- which therefore might also change in future releases:</p>
+ <p>The <c>on_load</c> feature is to be considered experimental
+ as there are a number of known weak points in current semantics,
+ which therefore might change in future Erlang/OTP releases:</p>
<list>
- <item><p>Doing external call in on_load to the module itself
+ <item><p>Doing external call in <c>on_load</c> to the module itself
leads to deadlock.</p></item>
<item><p>At module upgrade, other processes calling the module
- get suspended waiting for on_load to finish. This can be very bad
+ get suspended waiting for <c>on_load</c> to finish. This can be very bad
for applications with demands on realtime characteristics.</p></item>
- <item><p>At module upgrade, no rollback is done if the on_load function fails.
- The system will be left in a bad limbo state without any working
+ <item><p>At module upgrade, no rollback is done if the
+ <c>on_load</c> function fails.
+ The system is left in a bad limbo state without any working
and reachable instance of the module.</p></item>
</list>
- <p>The problems with module upgrade described above could be fixed in future
- releases by changing the behaviour to not make the module reachable until
- after the on_load function has successfully returned.</p>
+ <p>The problems with module upgrade described above can be fixed in future
+ Erlang/OTP releases by changing the behaviour to not make the module reachable until
+ after the <c>on_load</c> function has successfully returned.</p>
</warning>
- <p>The <c>-on_load()</c> directive names a function that should
- be run automatically when a module a loaded. Its syntax is:</p>
+ <p>The <c>-on_load()</c> directive names a function that is to
+ be run automatically when a module is loaded.</p>
+ <p>Its syntax is as follows:</p>
<pre>
-on_load(Name/0).</pre>
- <p>It is not necessary to export the function. It will be called in a
- freshly spawned process (which will be terminated as soon as the function
+ <p>It is not necessary to export the function. It is called in a
+ freshly spawned process (which terminates as soon as the function
returns). The function must return <c>ok</c> if the module is to
- be remained loaded and become callable, or any other value if the module
- is to be unloaded. Generating an exception will also cause the
+ remain loaded and become callable, or any other value if the module
+ is to be unloaded. Generating an exception also causes the
module to be unloaded. If the return value is not an atom,
- a warning error report will be sent to the error logger.</p>
+ a warning error report is sent to the error logger.</p>
<p>A process that calls any function in a module whose <c>on_load</c>
- function has not yet returned will be suspended until the <c>on_load</c>
+ function has not yet returned, is suspended until the <c>on_load</c>
function has returned.</p>
- <p>In embedded mode, all modules will be loaded first and then
- will all on_load functions be called. The system will be
- terminated unless all of the on_load functions return
+ <p>In embedded mode, first all modules are loaded.
+ Then all <c>on_load</c> functions are called. The system is
+ terminated unless all of the <c>on_load</c> functions return
<c>ok</c></p>.
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
-module(m).
@@ -174,7 +186,7 @@ load_my_nifs() ->
erlang:load_nif(NifPath, Info).</pre>
<p>If the call to <c>erlang:load_nif/2</c> fails, the module
- will be unloaded and there will be warning report sent to
+ is unloaded and a warning report is sent to
the error loader.</p>
</section>
diff --git a/system/doc/reference_manual/data_types.xml b/system/doc/reference_manual/data_types.xml
index ad92143179..e63825b97d 100644
--- a/system/doc/reference_manual/data_types.xml
+++ b/system/doc/reference_manual/data_types.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,12 +29,12 @@
<rev></rev>
<file>data_types.xml</file>
</header>
+ <p>Erlang provides a number of data types, which are listed in
+ this section.</p>
<section>
<title>Terms</title>
- <p>Erlang provides a number of data types which are listed in this
- chapter. A piece of data of any data type is called a
- <em>term</em>.</p>
+ <p>A piece of data of any data type is called a <em>term</em>.</p>
</section>
<section>
@@ -48,13 +49,13 @@
<em><c>char</c></em>.</item>
<item><em><c>base</c></em><c>#</c><em><c>value</c></em> <br></br>
- Integer with the base <em><c>base</c></em>, which must be an
+ Integer with the base <em><c>base</c></em>, that must be an
integer in the range 2..36. <br></br>
In Erlang 5.2/OTP R9B and earlier versions, the allowed range
is 2..16.</item>
</list>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>42.</input>
42
@@ -76,11 +77,11 @@
<section>
<title>Atom</title>
- <p>An atom is a literal, a constant with name. An atom should be
+ <p>An atom is a literal, a constant with name. An atom is to be
enclosed in single quotes (') if it does not begin with a
lower-case letter or if it contains other characters than
alphanumeric characters, underscore (_), or @.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
hello
phone_number
@@ -91,11 +92,11 @@ phone_number
<section>
<title>Bit Strings and Binaries</title>
<p>A bit string is used to store an area of untyped memory.</p>
- <p>Bit Strings are expressed using the
+ <p>Bit strings are expressed using the
<seealso marker="expressions#bit_syntax">bit syntax</seealso>.</p>
- <p>Bit Strings which consists of a number of bits which is evenly
- divisible by eight are called Binaries</p>
- <p>Examples:</p>
+ <p>Bit strings that consist of a number of bits that are evenly
+ divisible by eight, are called <em>binaries</em></p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>&lt;&lt;10,20&gt;&gt;.</input>
&lt;&lt;10,20>>
@@ -103,12 +104,14 @@ phone_number
&lt;&lt;"ABC">>
1> <input>&lt;&lt;1:1,0:1&gt;&gt;.</input>
&lt;&lt;2:2>></pre>
- <p>More examples can be found in Programming Examples.</p>
+ <p>For more examples,
+ see <seealso marker="doc/programming_examples:bit_syntax">
+ Programming Examples</seealso>.</p>
</section>
<section>
<title>Reference</title>
- <p>A reference is a term which is unique in an Erlang runtime
+ <p>A reference is a term that is unique in an Erlang runtime
system, created by calling <c>make_ref/0</c>.</p>
</section>
@@ -117,34 +120,42 @@ phone_number
<p>A fun is a functional object. Funs make it possible to create
an anonymous function and pass the function itself -- not its
name -- as argument to other functions.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
1> <input>Fun1 = fun (X) -> X+1 end.</input>
#Fun&lt;erl_eval.6.39074546&gt;
2> <input>Fun1(2).</input>
3</pre>
- <p>Read more about funs in <seealso marker="expressions#funs">Fun Expressions</seealso>. More examples can be found in Programming
- Examples.</p>
+ <p>Read more about funs in <seealso marker="expressions#funs">
+ Fun Expressions</seealso>. For more examples, see
+ <seealso marker="doc/programming_examples:funs">
+ Programming Examples</seealso>.</p>
</section>
<section>
<title>Port Identifier</title>
- <p>A port identifier identifies an Erlang port. <c>open_port/2</c>,
- which is used to create ports, will return a value of this type.</p>
+ <p>A port identifier identifies an Erlang port.</p>
+ <p><c>open_port/2</c>, which is used to create ports, returns
+ a value of this data type.</p>
<p>Read more about ports in <seealso marker="ports">Ports and Port Drivers</seealso>.</p>
</section>
<section>
<title>Pid</title>
- <p>A process identifier, pid, identifies a process.
- <c>spawn/1,2,3,4</c>, <c>spawn_link/1,2,3,4</c> and
- <c>spawn_opt/4</c>, which are used to create processes, return
- values of this type. Example:</p>
+ <p>A process identifier, pid, identifies a process.</p>
+ <p>The following BIFs, which are used to create processes, return
+ values of this data type:</p>
+ <list type="bulleted">
+ <item><c>spawn/1,2,3,4</c></item>
+ <item><c>spawn_link/1,2,3,4</c></item>
+ <item><c>spawn_opt/4</c></item>
+ </list>
+ <p><em>Example:</em></p>
<pre>
1> <input>spawn(m, f, []).</input>
&lt;0.51.0></pre>
- <p>The BIF <c>self()</c> returns the pid of the calling process.
- Example:</p>
+ <p>In the following example, the BIF <c>self()</c> returns
+ the pid of the calling process:</p>
<pre>
-module(m).
-export([loop/0]).
@@ -167,14 +178,14 @@ who_are_you</pre>
<section>
<title>Tuple</title>
- <p>Compound data type with a fixed number of terms:</p>
+ <p>A tuple is a compound data type with a fixed number of terms:</p>
<pre>
{Term1,...,TermN}</pre>
<p>Each term <c>Term</c> in the tuple is called an
<em>element</em>. The number of elements is said to be
the <em>size</em> of the tuple.</p>
<p>There exists a number of BIFs to manipulate tuples.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>P = {adam,24,{july,29}}.</input>
{adam,24,{july,29}}
@@ -192,7 +203,8 @@ adam
<section>
<title>Map</title>
- <p>Compound data type with a variable number of key-value associations:</p>
+ <p>A map is a compound data type with a variable number of
+ key-value associations:</p>
<pre>
#{Key1=>Value1,...,KeyN=>ValueN}</pre>
<p>Each key-value association in the map is called an
@@ -200,7 +212,7 @@ adam
called <em>elements</em>. The number of association pairs is said to be
the <em>size</em> of the map.</p>
<p>There exists a number of BIFs to manipulate maps.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>M1 = #{name=>adam,age=>24,date=>{july,29}}.</input>
#{age => 24,date => {july,29},name => adam}
@@ -215,16 +227,18 @@ adam
6> <input>map_size(#{}).</input>
0</pre>
<p>A collection of maps processing functions can be found in
- the STDLIB module <seealso marker="stdlib:maps"><c>maps</c></seealso>.</p>
- <p>Read more about <seealso marker="expressions#map_expressions">Maps</seealso>.</p>
+ <seealso marker="stdlib:maps"><c>maps</c></seealso> manual page
+ in STDLIB.</p>
+ <p>Read more about maps in <seealso marker="expressions#map_expressions">
+ Map Expressions</seealso>.</p>
<note>
- <p>Maps are considered experimental during OTP 17.</p>
+ <p>Maps are considered to be experimental during Erlang/OTP R17.</p>
</note>
</section>
<section>
<title>List</title>
- <p>Compound data type with a variable number of terms.</p>
+ <p>A list is a compound data type with a variable number of terms.</p>
<pre>
[Term1,...,TermN]</pre>
<p>Each term <c>Term</c> in the list is called an
@@ -232,20 +246,21 @@ adam
the <em>length</em> of the list.</p>
<p>Formally, a list is either the empty list <c>[]</c> or
consists of a <em>head</em> (first element) and a <em>tail</em>
- (remainder of the list) which is also a list. The latter can
+ (remainder of the list).
+ The <em>tail</em> is also a list. The latter can
be expressed as <c>[H|T]</c>. The notation
- <c>[Term1,...,TermN]</c> above is actually shorthand for
+ <c>[Term1,...,TermN]</c> above is equivalent with
the list <c>[Term1|[...|[TermN|[]]]]</c>.</p>
- <p>Example: <br></br>
-<c>[]</c> is a list, thus <br></br>
+ <p><em>Example:</em></p>
+<p><c>[]</c> is a list, thus <br></br>
<c>[c|[]]</c> is a list, thus <br></br>
<c>[b|[c|[]]]</c> is a list, thus <br></br>
-<c>[a|[b|[c|[]]]]</c> is a list, or in short <c>[a,b,c]</c>.</p>
- <p></p>
+<c>[a|[b|[c|[]]]]</c> is a list, or in short <c>[a,b,c]</c></p>
+
<p>A list where the tail is a list is sometimes called a <em>proper list</em>. It is allowed to have a list where the tail is not a
- list, for example <c>[a|b]</c>. However, this type of list is of
+ list, for example, <c>[a|b]</c>. However, this type of list is of
little practical use.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>L1 = [a,2,{c,4}].</input>
[a,2,{c,4}]
@@ -262,18 +277,19 @@ a
7> <input>length([]).</input>
0</pre>
<p>A collection of list processing functions can be found in
- the STDLIB module <c>lists</c>.</p>
+ the <seealso marker="stdlib:lists">lists</seealso> manual
+ page in STDLIB.</p>
</section>
<section>
<title>String</title>
<p>Strings are enclosed in double quotes ("), but is not a
- data type in Erlang. Instead a string <c>"hello"</c> is
- shorthand for the list <c>[$h,$e,$l,$l,$o]</c>, that is
+ data type in Erlang. Instead, a string <c>"hello"</c> is
+ shorthand for the list <c>[$h,$e,$l,$l,$o]</c>, that is,
<c>[104,101,108,108,111]</c>.</p>
<p>Two adjacent string literals are concatenated into one. This is
- done at compile-time and does not incur any runtime overhead.
- Example:</p>
+ done in the compilation, thus, does not incur any runtime overhead.</p>
+ <p><em>Example:</em></p>
<pre>
"string" "42"</pre>
<p>is equivalent to</p>
@@ -285,12 +301,13 @@ a
<title>Record</title>
<p>A record is a data structure for storing a fixed number of
elements. It has named fields and is similar to a struct in C.
- However, record is not a true data type. Instead record
+ However, a record is not a true data type. Instead, record
expressions are translated to tuple expressions during
compilation. Therefore, record expressions are not understood by
- the shell unless special actions are taken. See <c>shell(3)</c>
- for details.</p>
- <p>Examples:</p>
+ the shell unless special actions are taken. For details, see the
+ <seealso marker="stdlib:shell">shell(3)</seealso> manual
+ page in STDLIB).</p>
+ <p><em>Examples:</em></p>
<pre>
-module(person).
-export([new/2]).
@@ -304,14 +321,15 @@ new(Name, Age) ->
{person,ernie,44}</pre>
<p>Read more about records in
<seealso marker="records">Records</seealso>. More examples can be
- found in Programming Examples.</p>
+ found in <seealso marker="doc/programming_examples:records">
+ Programming Examples</seealso>.</p>
</section>
<section>
<title>Boolean</title>
<p>There is no Boolean data type in Erlang. Instead the atoms
<c>true</c> and <c>false</c> are used to denote Boolean values.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>2 =&lt; 3</input>.
true
@@ -330,76 +348,80 @@ true</pre>
</row>
<row>
<cell align="left" valign="middle">\b</cell>
- <cell align="left" valign="middle">backspace</cell>
+ <cell align="left" valign="middle">Backspace</cell>
</row>
<row>
<cell align="left" valign="middle">\d</cell>
- <cell align="left" valign="middle">delete</cell>
+ <cell align="left" valign="middle">Delete</cell>
</row>
<row>
<cell align="left" valign="middle">\e</cell>
- <cell align="left" valign="middle">escape</cell>
+ <cell align="left" valign="middle">Escape</cell>
</row>
<row>
<cell align="left" valign="middle">\f</cell>
- <cell align="left" valign="middle">form feed</cell>
+ <cell align="left" valign="middle">Form feed</cell>
</row>
<row>
<cell align="left" valign="middle">\n</cell>
- <cell align="left" valign="middle">newline</cell>
+ <cell align="left" valign="middle">Newline</cell>
</row>
<row>
<cell align="left" valign="middle">\r</cell>
- <cell align="left" valign="middle">carriage return</cell>
+ <cell align="left" valign="middle">Carriage return</cell>
</row>
<row>
<cell align="left" valign="middle">\s</cell>
- <cell align="left" valign="middle">space</cell>
+ <cell align="left" valign="middle">Space</cell>
</row>
<row>
<cell align="left" valign="middle">\t</cell>
- <cell align="left" valign="middle">tab</cell>
+ <cell align="left" valign="middle">Tab</cell>
</row>
<row>
<cell align="left" valign="middle">\v</cell>
- <cell align="left" valign="middle">vertical tab</cell>
+ <cell align="left" valign="middle">Vertical tab</cell>
</row>
<row>
<cell align="left" valign="middle">\XYZ, \YZ, \Z</cell>
- <cell align="left" valign="middle">character with octal representation XYZ, YZ or Z</cell>
+ <cell align="left" valign="middle">Character with octal
+ representation XYZ, YZ or Z</cell>
</row>
<row>
<cell align="left" valign="middle">\xXY</cell>
- <cell align="left" valign="middle">character with hexadecimal representation XY</cell>
+ <cell align="left" valign="middle">Character with hexadecimal
+ representation XY</cell>
</row>
<row>
<cell align="left" valign="middle">\x{X...}</cell>
- <cell align="left" valign="middle">character with hexadecimal representation; X... is one or more hexadecimal characters</cell>
+ <cell align="left" valign="middle">Character with hexadecimal
+ representation; X... is one or more hexadecimal characters</cell>
</row>
<row>
<cell align="left" valign="middle">\^a...\^z <br></br>
\^A...\^Z</cell>
- <cell align="left" valign="middle">control A to control Z</cell>
+ <cell align="left" valign="middle">Control A to control Z</cell>
</row>
<row>
<cell align="left" valign="middle">\'</cell>
- <cell align="left" valign="middle">single quote</cell>
+ <cell align="left" valign="middle">Single quote</cell>
</row>
<row>
<cell align="left" valign="middle">\"</cell>
- <cell align="left" valign="middle">double quote</cell>
+ <cell align="left" valign="middle">Double quote</cell>
</row>
<row>
<cell align="left" valign="middle">\\</cell>
- <cell align="left" valign="middle">backslash</cell>
+ <cell align="left" valign="middle">Backslash</cell>
</row>
- <tcaption>Recognized Escape Sequences.</tcaption>
+ <tcaption>Recognized Escape Sequences</tcaption>
</table>
</section>
<section>
<title>Type Conversions</title>
- <p>There are a number of BIFs for type conversions. Examples:</p>
+ <p>There are a number of BIFs for type conversions.</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>atom_to_list(hello).</input>
"hello"
diff --git a/system/doc/reference_manual/distributed.xml b/system/doc/reference_manual/distributed.xml
index 88f98bc106..0a4a323fe9 100644
--- a/system/doc/reference_manual/distributed.xml
+++ b/system/doc/reference_manual/distributed.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -36,22 +37,24 @@
runtime system is called a <em>node</em>. Message passing between
processes at different nodes, as well as links and monitors, are
transparent when pids are used. Registered names, however, are
- local to each node. This means the node must be specified as well
- when sending messages etc. using registered names.</p>
+ local to each node. This means that the node must be specified as well
+ when sending messages, and so on, using registered names.</p>
<p>The distribution mechanism is implemented using TCP/IP sockets.
- How to implement an alternative carrier is described in <em>ERTS User's Guide</em>.</p>
+ How to implement an alternative carrier is described in the
+ <seealso marker="erts:alt_dist">ERTS User's Guide</seealso>.</p>
</section>
<section>
<title>Nodes</title>
- <p>A <em>node</em> is an executing Erlang runtime system which has
- been given a name, using the command line flag <c>-name</c>
+ <p>A <em>node</em> is an executing Erlang runtime system that has
+ been given a name, using the command-line flag <c>-name</c>
(long names) or <c>-sname</c> (short names).</p>
- <p>The format of the node name is an atom <c>name@host</c> where
- <c>name</c> is the name given by the user and <c>host</c> is
+ <p>The format of the node name is an atom <c>name@host</c>.
+ <c>name</c> is the name given by the user. <c>host</c> is
the full host name if long names are used, or the first part of
the host name if short names are used. <c>node()</c> returns
- the name of the node. Example:</p>
+ the name of the node.</p>
+ <p><em>Example:</em></p>
<pre>
% <input>erl -name dilbert</input>
([email protected])1> <input>node().</input>
@@ -69,16 +72,16 @@ dilbert@uab</pre>
<section>
<title>Node Connections</title>
<p>The nodes in a distributed Erlang system are loosely connected.
- The first time the name of another node is used, for example if
+ The first time the name of another node is used, for example, if
<c>spawn(Node,M,F,A)</c> or <c>net_adm:ping(Node)</c> is called,
- a connection attempt to that node will be made.</p>
+ a connection attempt to that node is made.</p>
<p>Connections are by default transitive. If a node A connects to
- node B, and node B has a connection to node C, then node A will
- also try to connect to node C. This feature can be turned off by
- using the command line flag <c>-connect_all false</c>, see
- <c>erl(1)</c>.</p>
+ node B, and node B has a connection to node C, then node A
+ also tries to connect to node C. This feature can be turned off by
+ using the command-line flag <c>-connect_all false</c>, see the
+ <seealso marker="erts:erl">erl(1)</seealso> manual page in ERTS.</p>
<p>If a node goes down, all connections to that node are removed.
- Calling <c>erlang:disconnect_node(Node)</c> will force disconnection
+ Calling <c>erlang:disconnect_node(Node)</c> forces disconnection
of a node.</p>
<p>The list of (visible) nodes currently connected to is returned by
<c>nodes()</c>.</p>
@@ -89,23 +92,24 @@ dilbert@uab</pre>
<p>The Erlang Port Mapper Daemon <em>epmd</em> is automatically
started at every host where an Erlang node is started. It is
responsible for mapping the symbolic node names to machine
- addresses. See <c>epmd(1)</c>.</p>
+ addresses. See the
+ <seealso marker="erts:epmd">epmd(1)</seealso> manual page in ERTS.</p>
</section>
<section>
<title>Hidden Nodes</title>
<p>In a distributed Erlang system, it is sometimes useful to
connect to a node without also connecting to all other nodes.
- An example could be some kind of O&amp;M functionality used to
- inspect the status of a system without disturbing it. For this
- purpose, a <em>hidden node</em> may be used.</p>
- <p>A hidden node is a node started with the command line flag
+ An example is some kind of O&amp;M functionality used to
+ inspect the status of a system, without disturbing it. For this
+ purpose, a <em>hidden node</em> can be used.</p>
+ <p>A hidden node is a node started with the command-line flag
<c>-hidden</c>. Connections between hidden nodes and other nodes
are not transitive, they must be set up explicitly. Also, hidden
nodes does not show up in the list of nodes returned by
<c>nodes()</c>. Instead, <c>nodes(hidden)</c> or
<c>nodes(connected)</c> must be used. This means, for example,
- that the hidden node will not be added to the set of nodes that
+ that the hidden node is not added to the set of nodes that
<c>global</c> is keeping track of.</p>
<p>This feature was added in Erlang 5.0/OTP R7.</p>
</section>
@@ -114,9 +118,11 @@ dilbert@uab</pre>
<title>C Nodes</title>
<p>A <em>C node</em> is a C program written to act as a hidden node
in a distributed Erlang system. The library <em>Erl_Interface</em>
- contains functions for this purpose. Refer to the documentation
- for Erl_Interface and <em>Interoperability Tutorial</em> for more
- information about C nodes.</p>
+ contains functions for this purpose. For more information about
+ C nodes, see the <seealso marker="erl_interface:ei_users_guide">
+ Erl_Interface</seealso> application and
+ <seealso marker="doc/tutorial:introduction#interoperability tutorial">
+ Interoperability Tutorial.</seealso>.</p>
</section>
<section>
@@ -125,7 +131,7 @@ dilbert@uab</pre>
with each other. In a network of different Erlang nodes, it is
built into the system at the lowest possible level. Each node has
its own <em>magic cookie</em>, which is an Erlang atom.</p>
- <p>When a nodes tries to connect to another node, the magic cookies
+ <p>When a node tries to connect to another node, the magic cookies
are compared. If they do not match, the connected node rejects
the connection.</p>
<p>At start-up, a node has a random atom assigned as its magic
@@ -141,8 +147,8 @@ dilbert@uab</pre>
the local node assume that all other nodes have the same cookie
<c>Cookie</c>.</p>
<p>Thus, groups of users with identical cookie files get Erlang
- nodes which can communicate freely and without interference from
- the magic cookie system. Users who want run nodes on separate
+ nodes that can communicate freely and without interference from
+ the magic cookie system. Users who want to run nodes on separate
file systems must make certain that their cookie files are
identical on the different file systems.</p>
<p>For a node <c>Node1</c> with magic cookie <c>Cookie</c> to be
@@ -154,19 +160,25 @@ dilbert@uab</pre>
<p>The default when a connection is established between two nodes,
is to immediately connect all other visible nodes as well. This
way, there is always a fully connected network. If there are
- nodes with different cookies, this method might be inappropriate
- and the command line flag <c>-connect_all false</c> must be set,
- see <seealso marker="erts:erl">erl(1)</seealso>.</p>
+ nodes with different cookies, this method can be inappropriate
+ and the command-line flag <c>-connect_all false</c> must be set,
+ see the <seealso marker="erts:erl">erl(1)</seealso>
+ manual page in ERTS.</p>
<p>The magic cookie of the local node is retrieved by calling
<c>erlang:get_cookie()</c>.</p>
</section>
<section>
<title>Distribution BIFs</title>
- <p>Some useful BIFs for distributed programming, see
- <c>erlang(3)</c> for more information:</p>
+ <p>Some useful BIFs for distributed programming
+ (for more information, see the <seealso marker="erts:erlang">
+ erlang(3)</seealso> manual page in ERTS:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>BIF</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>erlang:disconnect_node(Node)</c></cell>
<cell align="left" valign="middle">Forces the disconnection of a node.</cell>
</row>
@@ -180,7 +192,9 @@ dilbert@uab</pre>
</row>
<row>
<cell align="left" valign="middle"><c>monitor_node(Node, true|false)</c></cell>
- <cell align="left" valign="middle">Monitor the status of <c>Node</c>. A message<c>{nodedown, Node}</c> is received if the connection to it is lost.</cell>
+ <cell align="left" valign="middle">Monitors the status of
+ <c>Node</c>. A message<c>{nodedown, Node}</c> is received
+ if the connection to it is lost.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>node()</c></cell>
@@ -196,11 +210,16 @@ dilbert@uab</pre>
</row>
<row>
<cell align="left" valign="middle"><c>nodes(Arg)</c></cell>
- <cell align="left" valign="middle">Depending on <c>Arg</c>, this function can return a list not only of visible nodes, but also hidden nodes and previously known nodes, etc.</cell>
+ <cell align="left" valign="middle">Depending on <c>Arg</c>,
+ this function can return a list not only of visible nodes,
+ but also hidden nodes and previously known nodes, and so on.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>erlang:set_cookie(Node, Cookie)</c></cell>
- <cell align="left" valign="middle">Sets the magic cookie used when connecting to <c>Node</c>. If <c>Node</c> is the current node, <c>Cookie</c> will be used when connecting to all new nodes.</cell>
+ <cell align="left" valign="middle">Sets the magic cookie used
+ when connecting to <c>Node</c>. If <c>Node</c> is the
+ current node, <c>Cookie</c> is used when connecting to
+ all new nodes.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>spawn[_link|_opt](Node, Fun)</c></cell>
@@ -210,18 +229,24 @@ dilbert@uab</pre>
<cell align="left" valign="middle"><c>spawn[_link|opt](Node, Module, FunctionName, Args)</c></cell>
<cell align="left" valign="middle">Creates a process at a remote node.</cell>
</row>
- <tcaption>Distribution BIFs.</tcaption>
+ <tcaption>Distribution BIFs</tcaption>
</table>
</section>
<section>
- <title>Distribution Command Line Flags</title>
- <p>Examples of command line flags used for distributed programming,
- see <c>erl(1)</c> for more information:</p>
+ <title>Distribution Command-Line Flags</title>
+ <p>Examples of command-line flags used for distributed programming
+ (for more information, see the <seealso marker="erts:erl">erl(1)
+ </seealso> manual page in ERTS:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>Command-Line Flag</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>-connect_all false</c></cell>
- <cell align="left" valign="middle">Only explicit connection set-ups will be used.</cell>
+ <cell align="left" valign="middle">Only explicit connection
+ set-ups are used.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>-hidden</c></cell>
@@ -239,16 +264,20 @@ dilbert@uab</pre>
<cell align="left" valign="middle"><c>-sname Name</c></cell>
<cell align="left" valign="middle">Makes a runtime system into a node, using short node names.</cell>
</row>
- <tcaption>Distribution Command Line Flags.</tcaption>
+ <tcaption>Distribution Command-Line Flags</tcaption>
</table>
</section>
<section>
<title>Distribution Modules</title>
<p>Examples of modules useful for distributed programming:</p>
- <p>In Kernel:</p>
+ <p>In the Kernel application:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>Module</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>global</c></cell>
<cell align="left" valign="middle">A global name registration facility.</cell>
</row>
@@ -266,9 +295,13 @@ dilbert@uab</pre>
</row>
<tcaption>Kernel Modules Useful For Distribution.</tcaption>
</table>
- <p>In STDLIB:</p>
+ <p>In the STDLIB application:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>Module</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>slave</c></cell>
<cell align="left" valign="middle">Start and control of slave nodes.</cell>
</row>
diff --git a/system/doc/reference_manual/errors.xml b/system/doc/reference_manual/errors.xml
index dde6e68f4a..e764cf431f 100644
--- a/system/doc/reference_manual/errors.xml
+++ b/system/doc/reference_manual/errors.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -38,12 +39,12 @@
<item>Run-time errors</item>
<item>Generated errors</item>
</list>
- <p>A compile-time error, for example a syntax error, should not
+ <p>A compile-time error, for example a syntax error, does not
cause much trouble as it is caught by the compiler.</p>
<p>A logical error is when a program does not behave as intended,
- but does not crash. An example could be that nothing happens when
+ but does not crash. An example is that nothing happens when
a button in a graphical user interface is clicked.</p>
- <p>A run-time error is when a crash occurs. An example could be
+ <p>A run-time error is when a crash occurs. An example is
when an operator is applied to arguments of the wrong type.
The Erlang programming language has built-in features for
handling of run-time errors.</p>
@@ -54,23 +55,23 @@
of class <c>error</c>.
</p>
<p>A generated error is when the code itself calls
- <c>exit/1</c> or <c>throw/1</c>. Note that emulated run-time
+ <c>exit/1</c> or <c>throw/1</c>. Notice that emulated run-time
errors are not denoted as generated errors here.
</p>
<p>Generated errors are exceptions of classes <c>exit</c> and
<c>throw</c>.
</p>
<p>When a run-time error or generated error occurs in Erlang,
- execution for the process which evaluated
+ execution for the process that evaluated
the erroneous expression is stopped.
This is referred to as a <em>failure</em>, that execution or
evaluation <em>fails</em>, or that the process <em>fails</em>,
- <em>terminates</em> or <em>exits</em>. Note that a process may
+ <em>terminates</em>, or <em>exits</em>. Notice that a process can
terminate/exit for other reasons than a failure.</p>
- <p>A process that terminates will emit an <em>exit signal</em> with
+ <p>A process that terminates emits an <em>exit signal</em> with
an <em>exit reason</em> that says something about which error
- has occurred. Normally, some information about the error will
- be printed to the terminal.</p>
+ has occurred. Normally, some information about the error is
+ printed to the terminal.</p>
</section>
<section>
@@ -78,10 +79,12 @@
<p>Exceptions are run-time errors or generated errors and
are of three different classes, with different origins. The
<seealso marker="expressions#try">try</seealso> expression
- (appeared in Erlang 5.4/OTP-R10B)
+ (new in Erlang 5.4/OTP R10B)
can distinguish between the different classes, whereas the
<seealso marker="expressions#catch">catch</seealso>
- expression can not. They are described in the Expressions chapter.</p>
+ expression cannot. They are described in
+ <seealso marker="expressions">Expressions
+ </seealso>.</p>
<table>
<row>
<cell align="left" valign="middle"><em>Class</em></cell>
@@ -89,7 +92,9 @@
</row>
<row>
<cell align="left" valign="middle"><c>error</c></cell>
- <cell align="left" valign="middle">Run-time error for example <c>1+a</c>, or the process called <c>erlang:error/1,2</c> (appeared in Erlang 5.4/OTP-R10B)</cell>
+ <cell align="left" valign="middle">Run-time error,
+ for example, <c>1+a</c>, or the process called
+ <c>erlang:error/1,2</c> (new in Erlang 5.4/OTP R10B)</cell>
</row>
<row>
<cell align="left" valign="middle"><c>exit</c></cell>
@@ -102,11 +107,11 @@
<tcaption>Exception Classes.</tcaption>
</table>
<p>An exception consists of its class, an exit reason
- (the <seealso marker="#exit_reasons">Exit Reason</seealso>),
- and a stack trace (that aids in finding the code location of
+ (see <seealso marker="#exit_reasons">Exit Reason</seealso>),
+ and a stack trace (which aids in finding the code location of
the exception).</p>
<p>The stack trace can be retrieved using
- <c>erlang:get_stacktrace/0</c> (new in Erlang 5.4/OTP-R10B)
+ <c>erlang:get_stacktrace/0</c> (new in Erlang 5.4/OTP R10B)
from within a <c>try</c> expression, and is returned for
exceptions of class <c>error</c> from a <c>catch</c> expression.</p>
<p>An exception of class <c>error</c> is also known as a run-time
@@ -114,38 +119,38 @@
</section>
<section>
- <title>Handling of Run-Time Errors in Erlang</title>
+ <title>Handling of Run-time Errors in Erlang</title>
<section>
<title>Error Handling Within Processes</title>
<p>It is possible to prevent run-time errors and other
exceptions from causing
the process to terminate by using <c>catch</c> or
- <c>try</c>, see the Expressions chapter about
- <seealso marker="expressions#catch">Catch</seealso>
- and <seealso marker="expressions#try">Try</seealso>.</p>
+ <c>try</c>, see <seealso marker="expressions">
+ Expressions</seealso> about
+ <seealso marker="expressions#catch">catch</seealso>
+ and <seealso marker="expressions#try">try</seealso>.</p>
</section>
<section>
<title>Error Handling Between Processes</title>
<p>Processes can monitor other processes and detect process
terminations, see
- the <seealso marker="processes#errors">Processes</seealso>
- chapter.</p>
+ <seealso marker="processes#errors">Processes</seealso>.</p>
</section>
</section>
<section>
<marker id="exit_reasons"></marker>
<title>Exit Reasons</title>
- <p>When a run-time error occurs,
- that is an exception of class <c>error</c>,
- the exit reason is a tuple <c>{Reason,Stack}</c>.
+ <p>When a run-time error occurs,
+ that is an exception of class <c>error</c>.
+ The exit reason is a tuple <c>{Reason,Stack}</c>, where
<c>Reason</c> is a term indicating the type of error:</p>
<table>
<row>
<cell align="left" valign="middle"><em>Reason</em></cell>
- <cell align="left" valign="middle"><em>Type of error</em></cell>
+ <cell align="left" valign="middle"><em>Type of Error</em></cell>
</row>
<row>
<cell align="left" valign="middle"><c>badarg</c></cell>
@@ -181,7 +186,7 @@
</row>
<row>
<cell align="left" valign="middle"><c>{badfun,F}</c></cell>
- <cell align="left" valign="middle">There is something wrong with a fun <c>F</c>.</cell>
+ <cell align="left" valign="middle">Something is wrong with a fun <c>F</c>.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>{badarity,F}</c></cell>
@@ -201,14 +206,17 @@
</row>
<row>
<cell align="left" valign="middle"><c>system_limit</c></cell>
- <cell align="left" valign="middle">A system limit has been reached. See Efficiency Guide for information about system limits.</cell>
+ <cell align="left" valign="middle">A system limit has been reached.
+ See <seealso marker="doc/efficiency_guide:advanced">
+ Efficiency Guide</seealso> for information about system limits.
+ </cell>
</row>
- <tcaption>Exit Reasons.</tcaption>
+ <tcaption>Exit Reasons</tcaption>
</table>
<p><c>Stack</c> is the stack of function calls being evaluated
when the error occurred, given as a list of tuples
<c>{Module,Name,Arity}</c> with the most recent function call
- first. The most recent function call tuple may in some
+ first. The most recent function call tuple can in some
cases be <c>{Module,Name,[Arg]}</c>.</p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml
index 62a344ad58..893398b71b 100644
--- a/system/doc/reference_manual/expressions.xml
+++ b/system/doc/reference_manual/expressions.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,13 +29,17 @@
<rev></rev>
<file>expressions.xml</file>
</header>
- <p>In this chapter, all valid Erlang expressions are listed.
+ <p>In this section, all valid Erlang expressions are listed.
When writing Erlang programs, it is also allowed to use macro-
and record expressions. However, these expressions are expanded
during compilation and are in that sense not true Erlang
expressions. Macro- and record expressions are covered in
- separate chapters: <seealso marker="macros">Macros</seealso> and
- <seealso marker="records">Records</seealso>.</p>
+ separate sections:
+ </p>
+ <list type="bulleted">
+ <item><p><seealso marker="macros">Preprocessor</seealso></p></item>
+ <item><p><seealso marker="records">Records</seealso></p></item>
+ </list>
<section>
<title>Expression Evaluation</title>
@@ -48,15 +53,15 @@ Expr1 + Expr2</code>
performed.</p>
<p>Many of the operators can only be applied to arguments of a
certain type. For example, arithmetic operators can only be
- applied to numbers. An argument of the wrong type will cause
- a <c>badarg</c> run-time error.</p>
+ applied to numbers. An argument of the wrong type causes
+ a <c>badarg</c> runtime error.</p>
</section>
<section>
<marker id="term"></marker>
<title>Terms</title>
<p>The simplest form of expression is a term, that is an integer,
- float, atom, string, list, map or tuple.
+ float, atom, string, list, map, or tuple.
The return value is the term itself.</p>
</section>
@@ -65,9 +70,10 @@ Expr1 + Expr2</code>
<p>A variable is an expression. If a variable is bound to a value,
the return value is this value. Unbound variables are only
allowed in patterns.</p>
- <p>Variables start with an uppercase letter or underscore (_)
- and may contain alphanumeric characters, underscore and @.
- Examples:</p>
+ <p>Variables start with an uppercase letter or underscore (_).
+ Variables can contain alphanumeric characters, underscore and <c>@</c>.
+ </p>
+ <p><em>Examples:</em></p>
<pre>
X
Name1
@@ -77,18 +83,20 @@ _
_Height</pre>
<p>Variables are bound to values using
<seealso marker="patterns">pattern matching</seealso>. Erlang
- uses <em>single assignment</em>, a variable can only be bound
+ uses <em>single assignment</em>, that is, a variable can only be bound
once.</p>
<p>The <em>anonymous variable</em> is denoted by underscore (_) and
can be used when a variable is required but its value can be
- ignored. Example:</p>
+ ignored.</p>
+ <p><em>Example:</em></p>
<pre>
[H|_] = [1,2,3]</pre>
- <p>Variables starting with underscore (_), for example
+ <p>Variables starting with underscore (_), for example,
<c>_Height</c>, are normal variables, not anonymous. They are
- however ignored by the compiler in the sense that they will not
- generate any warnings for unused variables. Example: The following
- code</p>
+ however ignored by the compiler in the sense that they do not
+ generate any warnings for unused variables.</p>
+ <p><em>Example:</em></p>
+ <p>The following code:</p>
<pre>
member(_, []) ->
[].</pre>
@@ -96,36 +104,37 @@ member(_, []) ->
<pre>
member(Elem, []) ->
[].</pre>
- <p>This will however cause a warning for an unused variable
+ <p>This causes a warning for an unused variable,
<c>Elem</c>, if the code is compiled with the flag
<c>warn_unused_vars</c> set. Instead, the code can be rewritten
to:</p>
<pre>
member(_Elem, []) ->
[].</pre>
- <p>Note that since variables starting with an underscore are
- not anonymous, this will match:</p>
+ <p>Notice that since variables starting with an underscore are
+ not anonymous, this matches:</p>
<pre>
{_,_} = {1,2}</pre>
- <p>But this will fail:</p>
+ <p>But this fails:</p>
<pre>
{_N,_N} = {1,2}</pre>
<p>The scope for a variable is its function clause.
Variables bound in a branch of an <c>if</c>, <c>case</c>,
or <c>receive</c> expression must be bound in all branches
- to have a value outside the expression, otherwise they
- will be regarded as 'unsafe' outside the expression.</p>
+ to have a value outside the expression. Otherwise they
+ are regarded as 'unsafe' outside the expression.</p>
<p>For the <c>try</c> expression introduced in
- Erlang 5.4/OTP-R10B, variable scoping is limited so that
+ Erlang 5.4/OTP R10B, variable scoping is limited so that
variables bound in the expression are always 'unsafe' outside
- the expression. This will be improved.</p>
+ the expression. This is to be improved.</p>
</section>
<section>
<marker id="pattern"></marker>
<title>Patterns</title>
- <p>A pattern has the same structure as a term but may contain
- unbound variables. Example:</p>
+ <p>A pattern has the same structure as a term but can contain
+ unbound variables.</p>
+ <p><em>Example:</em></p>
<pre>
Name1
[H|T]
@@ -136,13 +145,13 @@ Name1
<section>
<title>Match Operator = in Patterns</title>
<p>If <c>Pattern1</c> and <c>Pattern2</c> are valid patterns,
- then the following is also a valid pattern:</p>
+ the following is also a valid pattern:</p>
<pre>
Pattern1 = Pattern2</pre>
<p>When matched against a term, both <c>Pattern1</c> and
- <c>Pattern2</c> will be matched against the term. The idea
- behind this feature is to avoid reconstruction of terms.
- Example:</p>
+ <c>Pattern2</c> are matched against the term. The idea
+ behind this feature is to avoid reconstruction of terms.</p>
+ <p><em>Example:</em></p>
<pre>
f({connect,From,To,Number,Options}, To) ->
Signal = {connect,From,To,Number,Options},
@@ -163,16 +172,20 @@ f(Signal, To) ->
<pre>
f("prefix" ++ Str) -> ...</pre>
<p>This is syntactic sugar for the equivalent, but harder to
- read</p>
+ read:</p>
<pre>
f([$p,$r,$e,$f,$i,$x | Str]) -> ...</pre>
</section>
<section>
<title>Expressions in Patterns</title>
- <p>An arithmetic expression can be used within a pattern, if
- it uses only numeric or bitwise operators, and if its value
- can be evaluated to a constant at compile-time. Example:</p>
+ <p>An arithmetic expression can be used within a pattern if
+ it meets both of the following two conditions:</p>
+ <list type="bulleted">
+ <item>It uses only numeric or bitwise operators.</item>
+ <item>Its value can be evaluated to a constant when complied.</item>
+ </list>
+ <p><em>Example:</em></p>
<pre>
case {Value, Result} of
{?THRESHOLD+1, ok} -> ...</pre>
@@ -182,21 +195,21 @@ case {Value, Result} of
<section>
<title>Match</title>
+ <p>The following matches <c>Expr1</c>, a pattern, against
+ <c>Expr2</c>:</p>
<pre>
Expr1 = Expr2</pre>
- <p>Matches <c>Expr1</c>, a pattern, against <c>Expr2</c>.
- If the matching succeeds, any unbound variable in the pattern
+ <p>If the matching succeeds, any unbound variable in the pattern
becomes bound and the value of <c>Expr2</c> is returned.</p>
- <p>If the matching fails, a <c>badmatch</c> run-time error will
- occur.</p>
- <p>Examples:</p>
+ <p>If the matching fails, a <c>badmatch</c> run-time error occurs.</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>{A, B} = {answer, 42}.</input>
{answer,42}
2> <input>A.</input>
answer
3> <input>{C, D} = [1, 2].</input>
-** exception error: no match of right hand side value [1,2]</pre>
+** exception error: no match of right-hand side value [1,2]</pre>
</section>
<section>
@@ -210,27 +223,28 @@ ExprM:ExprF(Expr1,...,ExprN)</pre>
<c>ExprF</c> must be an atom or an expression that evaluates to
an atom. The function is said to be called by using the
<em>fully qualified function name</em>. This is often referred
- to as a <em>remote</em> or <em>external function call</em>.
- Example:</p>
+ to as a <em>remote</em> or <em>external function call</em>.</p>
+ <p><em>Example:</em></p>
<code type="none">
lists:keysearch(Name, 1, List)</code>
<p>In the second form of function calls,
<c>ExprF(Expr1,...,ExprN)</c>, <c>ExprF</c> must be an atom or
evaluate to a fun.</p>
- <p>If <c>ExprF</c> is an atom the function is said to be called by
+ <p>If <c>ExprF</c> is an atom, the function is said to be called by
using the <em>implicitly qualified function name</em>. If the
function <c>ExprF</c> is locally defined, it is called.
- Alternatively if <c>ExprF</c> is explicitly imported from module
- <c>M</c>, <c>M:ExprF(Expr1,...,ExprN)</c> is called. If
+ Alternatively, if <c>ExprF</c> is explicitly imported from the
+ <c>M</c> module, <c>M:ExprF(Expr1,...,ExprN)</c> is called. If
<c>ExprF</c> is neither declared locally nor explicitly
imported, <c>ExprF</c> must be the name of an automatically
- imported BIF. Examples:</p>
+ imported BIF. </p>
+ <p><em>Examples:</em></p>
<code type="none">
handle(Msg, State)
spawn(m, init, [])</code>
- <p>Examples where ExprF is a fun:</p>
+ <p><em>Examples</em> where <c>ExprF</c> is a fun:</p>
<code type="none">
Fun1 = fun(X) -> X+1 end
Fun1(3)
@@ -239,16 +253,15 @@ Fun1(3)
fun lists:append/2([1,2], [3,4])
=> [1,2,3,4]</code>
- <p>Note that when calling a local function, there is a difference
- between using the implicitly or fully qualified function name, as
- the latter always refers to the latest version of the module. See
- <seealso marker="code_loading">Compilation and Code Loading</seealso>.</p>
-
- <p>See also the chapter about
- <seealso marker="functions#eval">Function Evaluation</seealso>.</p>
+ <p>Notice that when calling a local function, there is a difference
+ between using the implicitly or fully qualified function name.
+ The latter always refers to the latest version of the module.
+ See <seealso marker="code_loading">Compilation and Code Loading
+ </seealso> and <seealso marker="functions#eval">
+ Function Evaluation</seealso>.</p>
<section>
- <title>Local Function Names Clashing With Auto-imported BIFs</title>
+ <title>Local Function Names Clashing With Auto-Imported BIFs</title>
<p>If a local function has the same name as an auto-imported BIF,
the semantics is that implicitly qualified function calls are
directed to the locally defined function, not to the BIF. To avoid
@@ -260,9 +273,9 @@ fun lists:append/2([1,2], [3,4])
<warning><p>Before OTP R14A (ERTS version 5.8), an implicitly
qualified function call to a function having the same name as an
auto-imported BIF always resulted in the BIF being called. In
- newer versions of the compiler the local function is instead
- called. The change is there to avoid that future additions to the
- set of auto-imported BIFs does not silently change the behavior
+ newer versions of the compiler, the local function is called instead.
+ This is to avoid that future additions to the
+ set of auto-imported BIFs do not silently change the behavior
of old code.</p>
<p>However, to avoid that old (pre R14) code changed its
@@ -272,8 +285,8 @@ fun lists:append/2([1,2], [3,4])
5.8) and have an implicitly qualified call to that function in
your code, you either need to explicitly remove the auto-import
using a compiler directive, or replace the call with a fully
- qualified function call, otherwise you will get a compilation
- error. See example below:</p> </warning>
+ qualified function call. Otherwise you get a compilation
+ error. See the following example:</p> </warning>
<code type="none">
-export([length/1,f/1]).
@@ -290,9 +303,10 @@ f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
long.</code>
<p>The same logic applies to explicitly imported functions from
- other modules as to locally defined functions. To both import a
+ other modules, as to locally defined functions.
+ It is not allowed to both import a
function from another module and have the function declared in the
- module at the same time is not allowed.</p>
+ module at the same time:</p>
<code type="none">
-export([f/1]).
@@ -310,10 +324,10 @@ f(X) ->
length(X). %% mod:length/1 is called</code>
- <p>For auto-imported BIFs added to Erlang in release R14A and thereafter,
+ <p>For auto-imported BIFs added in Erlang/OTP R14A and thereafter,
overriding the name with a local function or explicit import is always
allowed. However, if the <c>-compile({no_auto_import,[F/A])</c>
- directive is not used, the compiler will issue a warning whenever
+ directive is not used, the compiler issues a warning whenever
the function is called in the module using the implicitly qualified
function name.</p>
</section>
@@ -330,15 +344,16 @@ if
BodyN
end</pre>
<p>The branches of an <c>if</c>-expression are scanned sequentially
- until a guard sequence <c>GuardSeq</c> which evaluates to true is
+ until a guard sequence <c>GuardSeq</c> that evaluates to true is
found. Then the corresponding <c>Body</c> (sequence of expressions
separated by ',') is evaluated.</p>
<p>The return value of <c>Body</c> is the return value of
the <c>if</c> expression.</p>
- <p>If no guard sequence is true, an <c>if_clause</c> run-time error
- will occur. If necessary, the guard expression <c>true</c> can be
+ <p>If no guard sequence is evaluated as true,
+ an <c>if_clause</c> run-time error
+ occurs. If necessary, the guard expression <c>true</c> can be
used in the last branch, as that guard sequence is always true.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
is_greater_than(X, Y) ->
if
@@ -367,8 +382,8 @@ end</pre>
<p>The return value of <c>Body</c> is the return value of
the <c>case</c> expression.</p>
<p>If there is no matching pattern with a true guard sequence,
- a <c>case_clause</c> run-time error will occur.</p>
- <p>Example:</p>
+ a <c>case_clause</c> run-time error occurs.</p>
+ <p><em>Example:</em></p>
<pre>
is_valid_signal(Signal) ->
case Signal of
@@ -389,15 +404,15 @@ Expr1 ! Expr2</pre>
<p>Sends the value of <c>Expr2</c> as a message to the process
specified by <c>Expr1</c>. The value of <c>Expr2</c> is also
the return value of the expression.</p>
- <p><c>Expr1</c> must evaluate to a pid, a registered name (atom) or
- a tuple <c>{Name,Node}</c>, where <c>Name</c> is an atom and
- <c>Node</c> a node name, also an atom.</p>
+ <p><c>Expr1</c> must evaluate to a pid, a registered name (atom), or
+ a tuple <c>{Name,Node}</c>. <c>Name</c> is an atom and
+ <c>Node</c> is a node name, also an atom.</p>
<list type="bulleted">
<item>If <c>Expr1</c> evaluates to a name, but this name is not
- registered, a <c>badarg</c> run-time error will occur.</item>
+ registered, a <c>badarg</c> run-time error occurs.</item>
<item>Sending a message to a pid never fails, even if the pid
identifies a non-existing process.</item>
- <item>Distributed message sending, that is if <c>Expr1</c>
+ <item>Distributed message sending, that is, if <c>Expr1</c>
evaluates to a tuple <c>{Name,Node}</c> (or a pid located at
another node), also never fails.</item>
</list>
@@ -420,14 +435,14 @@ end</pre>
the second, and so on. If a match succeeds and the optional
guard sequence <c>GuardSeq</c> is true, the corresponding
<c>Body</c> is evaluated. The matching message is consumed, that
- is removed from the mailbox, while any other messages in
+ is, removed from the mailbox, while any other messages in
the mailbox remain unchanged.</p>
<p>The return value of <c>Body</c> is the return value of
the <c>receive</c> expression.</p>
- <p><c>receive</c> never fails. Execution is suspended, possibly
- indefinitely, until a message arrives that does match one of
+ <p><c>receive</c> never fails. The execution is suspended, possibly
+ indefinitely, until a message arrives that matches one of
the patterns and with a true guard sequence. </p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
wait_for_onhook() ->
receive
@@ -438,7 +453,7 @@ wait_for_onhook() ->
B ! {busy, self()},
wait_for_onhook()
end.</pre>
- <p>It is possible to augment the <c>receive</c> expression with a
+ <p>The <c>receive</c> expression can be augmented with a
timeout:</p>
<pre>
receive
@@ -451,14 +466,14 @@ after
ExprT ->
BodyT
end</pre>
- <p><c>ExprT</c> should evaluate to an integer. The highest allowed
- value is 16#ffffffff, that is, the value must fit in 32 bits.
+ <p><c>ExprT</c> is to evaluate to an integer. The highest allowed
+ value is 16#FFFFFFFF, that is, the value must fit in 32 bits.
<c>receive..after</c> works exactly as <c>receive</c>, except
that if no matching message has arrived within <c>ExprT</c>
- milliseconds, then <c>BodyT</c> is evaluated instead and its
- return value becomes the return value of the <c>receive..after</c>
- expression.</p>
- <p>Example:</p>
+ milliseconds, then <c>BodyT</c> is evaluated instead. The
+ return value of <c>BodyT</c> then becomes the return value
+ of the <c>receive..after</c> expression.</p>
+ <p><em>Example:</em></p>
<pre>
wait_for_onhook() ->
receive
@@ -481,10 +496,10 @@ after
ExprT ->
BodyT
end</pre>
- <p>This construction will not consume any messages, only suspend
- execution in the process for <c>ExprT</c> milliseconds and can be
+ <p>This construction does not consume any messages, only suspends
+ execution in the process for <c>ExprT</c> milliseconds. This can be
used to implement simple timers.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
timer() ->
spawn(m, timer, [self()]).
@@ -498,12 +513,12 @@ timer(Pid) ->
<p>There are two special cases for the timeout value <c>ExprT</c>:</p>
<taglist>
<tag><c>infinity</c></tag>
- <item>The process should wait indefinitely for a matching message
- -- this is the same as not using a timeout. Can be
- useful for timeout values that are calculated at run-time.</item>
+ <item>The process is to wait indefinitely for a matching message;
+ this is the same as not using a timeout. This can be
+ useful for timeout values that are calculated at runtime.</item>
<tag>0</tag>
<item>If there is no matching message in the mailbox, the timeout
- will occur immediately.</item>
+ occurs immediately.</item>
</taglist>
</section>
@@ -518,64 +533,73 @@ Expr1 <input>op</input> Expr2</pre>
</row>
<row>
<cell align="left" valign="middle">==</cell>
- <cell align="left" valign="middle">equal to</cell>
+ <cell align="left" valign="middle">Equal to</cell>
</row>
<row>
<cell align="left" valign="middle">/=</cell>
- <cell align="left" valign="middle">not equal to</cell>
+ <cell align="left" valign="middle">Not equal to</cell>
</row>
<row>
<cell align="left" valign="middle">=&lt;</cell>
- <cell align="left" valign="middle">less than or equal to</cell>
+ <cell align="left" valign="middle">Less than or equal to</cell>
</row>
<row>
<cell align="left" valign="middle">&lt;</cell>
- <cell align="left" valign="middle">less than</cell>
+ <cell align="left" valign="middle">Less than</cell>
</row>
<row>
<cell align="left" valign="middle">&gt;=</cell>
- <cell align="left" valign="middle">greater than or equal to</cell>
+ <cell align="left" valign="middle">Greater than or equal to</cell>
</row>
<row>
<cell align="left" valign="middle">&gt;</cell>
- <cell align="left" valign="middle">greater than</cell>
+ <cell align="left" valign="middle">Greater than</cell>
</row>
<row>
<cell align="left" valign="middle">=:=</cell>
- <cell align="left" valign="middle">exactly equal to</cell>
+ <cell align="left" valign="middle">Exactly equal to</cell>
</row>
<row>
<cell align="left" valign="middle">=/=</cell>
- <cell align="left" valign="middle">exactly not equal to</cell>
+ <cell align="left" valign="middle">Exactly not equal to</cell>
</row>
<tcaption>Term Comparison Operators.</tcaption>
</table>
- <p>The arguments may be of different data types. The following
+ <p>The arguments can be of different data types. The following
order is defined:</p>
<pre>
-number &lt; atom &lt; reference &lt; fun &lt; port &lt; pid &lt; tuple &lt; list &lt; bit string</pre>
+number &lt; atom &lt; reference &lt; fun &lt; port &lt; pid &lt; tuple &lt; map &lt; nil &lt; list &lt; bit string</pre>
<p>Lists are compared element by element. Tuples are ordered by
size, two tuples with the same size are compared element by
element.</p>
+ <p>Maps are ordered by size, two maps with the same size are compared by keys in
+ ascending term order and then by values in key order.
+ In maps key order integers types are considered less than floats types.
+ </p>
<p>When comparing an integer to a float, the term with the lesser
- precision will be converted into the other term's type, unless the
- operator is one of =:= or =/=. A float is more precise than
+ precision is converted into the type of the other term, unless the
+ operator is one of <c>=:=</c> or <c>=/=</c>. A float is more precise than
an integer until all significant figures of the float are to the left of
the decimal point. This happens when the float is larger/smaller than
+/-9007199254740992.0. The conversion strategy is changed
depending on the size of the float because otherwise comparison of large
floats and integers would lose their transitivity.</p>
- <p>Returns the Boolean value of the expression, <c>true</c> or
- <c>false</c>.</p>
- <p>Examples:</p>
+ <p>Term comparison operators return the Boolean value of the
+ expression, <c>true</c> or <c>false</c>.</p>
+
+ <p><em>Examples:</em></p>
<pre>
1> <input>1==1.0.</input>
true
2> <input>1=:=1.0.</input>
false
3> <input>1 > a.</input>
-false</pre>
+false
+4> <input>#{c => 3} > #{a => 1, b => 2}.</input>
+false
+4> <input>#{a => 1, b => 2} == #{a => 1.0, b => 2.0}.</input>
+true</pre>
</section>
<section>
@@ -585,19 +609,19 @@ false</pre>
Expr1 <input>op</input> Expr2</pre>
<table>
<row>
- <cell align="left" valign="middle"><em>op</em></cell>
+ <cell align="left" valign="middle"><em>Operator</em></cell>
<cell align="left" valign="middle"><em>Description</em></cell>
- <cell align="left" valign="middle"><em>Argument type</em></cell>
+ <cell align="left" valign="middle"><em>Argument Type</em></cell>
</row>
<row>
<cell align="left" valign="middle">+</cell>
- <cell align="left" valign="middle">unary +</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Unary +</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">-</cell>
- <cell align="left" valign="middle">unary -</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Unary -</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">+</cell>
@@ -607,62 +631,62 @@ Expr1 <input>op</input> Expr2</pre>
<row>
<cell align="left" valign="middle">-</cell>
<cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">*</cell>
<cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">/</cell>
- <cell align="left" valign="middle">floating point division</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Floating point division</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">bnot</cell>
- <cell align="left" valign="middle">unary bitwise not</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Unary bitwise NOT</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">div</cell>
- <cell align="left" valign="middle">integer division</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Integer division</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">rem</cell>
- <cell align="left" valign="middle">integer remainder of X/Y</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Integer remainder of X/Y</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">band</cell>
- <cell align="left" valign="middle">bitwise and</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Bitwise AND</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bor</cell>
- <cell align="left" valign="middle">bitwise or</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Bitwise OR</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bxor</cell>
- <cell align="left" valign="middle">arithmetic bitwise xor</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Arithmetic bitwise XOR</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bsl</cell>
- <cell align="left" valign="middle">arithmetic bitshift left</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Arithmetic bitshift left</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bsr</cell>
- <cell align="left" valign="middle">bitshift right</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Bitshift right</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<tcaption>Arithmetic Operators.</tcaption>
</table>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>+1.</input>
1
@@ -697,28 +721,28 @@ Expr1 <input>op</input> Expr2</pre>
Expr1 <input>op</input> Expr2</pre>
<table>
<row>
- <cell align="left" valign="middle"><em>op</em></cell>
+ <cell align="left" valign="middle"><em>Operator</em></cell>
<cell align="left" valign="middle"><em>Description</em></cell>
</row>
<row>
<cell align="left" valign="middle">not</cell>
- <cell align="left" valign="middle">unary logical not</cell>
+ <cell align="left" valign="middle">Unary logical NOT</cell>
</row>
<row>
<cell align="left" valign="middle">and</cell>
- <cell align="left" valign="middle">logical and</cell>
+ <cell align="left" valign="middle">Logical AND</cell>
</row>
<row>
<cell align="left" valign="middle">or</cell>
- <cell align="left" valign="middle">logical or</cell>
+ <cell align="left" valign="middle">Logical OR</cell>
</row>
<row>
<cell align="left" valign="middle">xor</cell>
- <cell align="left" valign="middle">logical xor</cell>
+ <cell align="left" valign="middle">Logical XOR</cell>
</row>
<tcaption>Logical Operators.</tcaption>
</table>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>not true.</input>
false
@@ -737,28 +761,37 @@ true
<pre>
Expr1 orelse Expr2
Expr1 andalso Expr2</pre>
- <p>Expressions where <c>Expr2</c> is evaluated only if
- necessary. That is, <c>Expr2</c> is evaluated only if <c>Expr1</c>
- evaluates to <c>false</c> in an <c>orelse</c> expression, or only
- if <c>Expr1</c> evaluates to <c>true</c> in an <c>andalso</c>
- expression. Returns either the value of <c>Expr1</c> (that is,
+ <p><c>Expr2</c> is evaluated only if
+ necessary. That is, <c>Expr2</c> is evaluated only if:</p>
+ <list type="bulleted">
+ <item><p><c>Expr1</c> evaluates to <c>false</c> in an
+ <c>orelse</c> expression.</p>
+ </item>
+ </list>
+ <p>or</p>
+ <list type="bulleted">
+ <item><p><c>Expr1</c> evaluates to <c>true</c> in an
+ <c>andalso</c> expression.</p>
+ </item>
+ </list>
+ <p>Returns either the value of <c>Expr1</c> (that is,
<c>true</c> or <c>false</c>) or the value of <c>Expr2</c>
- (if <c>Expr2</c> was evaluated).</p>
+ (if <c>Expr2</c> is evaluated).</p>
- <p>Example 1:</p>
+ <p><em>Example 1:</em></p>
<pre>
case A >= -1.0 andalso math:sqrt(A+1) > B of</pre>
- <p>This will work even if <c>A</c> is less than <c>-1.0</c>,
+ <p>This works even if <c>A</c> is less than <c>-1.0</c>,
since in that case, <c>math:sqrt/1</c> is never evaluated.</p>
- <p>Example 2:</p>
+ <p><em>Example 2:</em></p>
<pre>
OnlyOne = is_atom(L) orelse
(is_list(L) andalso length(L) == 1),</pre>
- <p>From R13A, <c>Expr2</c> is no longer required to evaluate to a
- boolean value. As a consequence, <c>andalso</c> and <c>orelse</c>
+ <p>From Erlang/OTP R13A, <c>Expr2</c> is no longer required to evaluate to a
+ Boolean value. As a consequence, <c>andalso</c> and <c>orelse</c>
are now tail-recursive. For instance, the following function is
- tail-recursive in R13A and later:</p>
+ tail-recursive in Erlang/OTP R13A and later:</p>
<pre>
all(Pred, [Hd|Tail]) ->
@@ -774,11 +807,11 @@ Expr1 ++ Expr2
Expr1 -- Expr2</pre>
<p>The list concatenation operator <c>++</c> appends its second
argument to its first and returns the resulting list.</p>
- <p>The list subtraction operator <c>--</c> produces a list which
- is a copy of the first argument, subjected to the following
- procedure: for each element in the second argument, the first
+ <p>The list subtraction operator <c>--</c> produces a list that
+ is a copy of the first argument. The procedure is a follows:
+ for each element in the second argument, the first
occurrence of this element (if any) is removed.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
1> <input>[1,2,3]++[4,5].</input>
[1,2,3,4,5]
@@ -786,8 +819,8 @@ Expr1 -- Expr2</pre>
[3,1,2]</pre>
<warning><p>The complexity of <c>A -- B</c> is
- proportional to <c>length(A)*length(B)</c>, meaning that it
- will be very slow if both <c>A</c> and <c>B</c> are
+ proportional to <c>length(A)*length(B)</c>. That is, it
+ becomes very slow if both <c>A</c> and <c>B</c> are
long lists.</p></warning>
</section>
@@ -802,7 +835,7 @@ Expr1 -- Expr2</pre>
</p>
<code>#{ K => V }</code>
<p>
- New maps may include multiple associations at construction by listing every
+ New maps can include multiple associations at construction by listing every
association:
</p>
<code>#{ K1 => V1, .., Kn => Vn }</code>
@@ -816,11 +849,11 @@ Expr1 -- Expr2</pre>
</p>
<p>
Keys and values are separated by the <c>=></c> arrow and associations are
- separated by <c>,</c>.
+ separated by a comma <c>,</c>.
</p>
<p>
- Examples:
+ <em>Examples:</em>
</p>
<code>
M0 = #{}, % empty map
@@ -829,14 +862,14 @@ M2 = #{1 => 2, b => b}, % multiple associations with literals
M3 = #{k => {A,B}}, % single association with variables
M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression</code>
<p>
- where, <c>A</c> and <c>B</c> are any expressions and <c>M0</c> through <c>M4</c>
+ Here, <c>A</c> and <c>B</c> are any expressions and <c>M0</c> through <c>M4</c>
are the resulting map terms.
</p>
<p>
- If two matching keys are declared, the latter key will take precedence.
+ If two matching keys are declared, the latter key takes precedence.
</p>
<p>
- Example:
+ <em>Example:</em>
</p>
<pre>
@@ -846,54 +879,57 @@ M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression
#{1 => b, 1.0 => a}
</pre>
<p>
- The order in which the expressions constructing the keys and their
- associated values are evaluated is not defined. The syntactic order of
+ The order in which the expressions constructing the keys (and their
+ associated values) are evaluated is not defined. The syntactic order of
the key-value pairs in the construction is of no relevance, except in
- the above mentioned case of two matching keys.
+ the recently mentioned case of two matching keys.
</p>
</section>
<section>
<title>Updating Maps</title>
<p>
- Updating a map has similar syntax as constructing it.
+ Updating a map has a similar syntax as constructing it.
</p>
<p>
- An expression defining the map to be updated is put in front of the expression
- defining the keys to be updated and their respective values.
+ An expression defining the map to be updated, is put in front of the expression
+ defining the keys to be updated and their respective values:
</p>
<code>M#{ K => V }</code>
<p>
- where <c>M</c> is a term of type map and <c>K</c> and <c>V</c> are any expression.
+ Here <c>M</c> is a term of type map and <c>K</c> and <c>V</c> are any expression.
</p>
<p>
If key <c>K</c> does not match any existing key in the map, a new association
- will be created from key <c>K</c> to value <c>V</c>. If key <c>K</c> matches
- an existing key in map <c>M</c> its associated value will be replaced by the
- new value <c>V</c>. In both cases the evaluated map expression will return a new map.
+ is created from key <c>K</c> to value <c>V</c>.
+ </p>
+ <p> If key <c>K</c> matches an existing key in map <c>M</c>,
+ its associated value
+ is replaced by the new value <c>V</c>. In both cases, the evaluated map expression
+ returns a new map.
</p>
<p>
- If <c>M</c> is not of type map an exception of type <c>badmap</c> is thrown.
+ If <c>M</c> is not of type map, an exception of type <c>badmap</c> is thrown.
</p>
<p>
- To only update an existing value, the following syntax is used,
+ To only update an existing value, the following syntax is used:
</p>
<code>M#{ K := V } </code>
<p>
- where <c>M</c> is an term of type map, <c>V</c> is an expression and <c>K</c>
- is an expression which evaluates to an existing key in <c>M</c>.
+ Here <c>M</c> is a term of type map, <c>V</c> is an expression and <c>K</c>
+ is an expression that evaluates to an existing key in <c>M</c>.
</p>
<p>
- If key <c>K</c> does not match any existing keys in map <c>M</c> an exception
- of type <c>badarg</c> will be triggered at runtime. If a matching key <c>K</c>
- is present in map <c>M</c> its associated value will be replaced by the new
- value <c>V</c> and the evaluated map expression returns a new map.
+ If key <c>K</c> does not match any existing keys in map <c>M</c>, an exception
+ of type <c>badarg</c> is triggered at runtime. If a matching key <c>K</c>
+ is present in map <c>M</c>, its associated value is replaced by the new
+ value <c>V</c>, and the evaluated map expression returns a new map.
</p>
<p>
- If <c>M</c> is not of type map an exception of type <c>badmap</c> is thrown.
+ If <c>M</c> is not of type map, an exception of type <c>badmap</c> is thrown.
</p>
<p>
- Examples:
+ <em>Examples:</em>
</p>
<code>
M0 = #{},
@@ -902,10 +938,10 @@ M2 = M1#{a => 1, b => 2},
M3 = M2#{"function" => fun() -> f() end},
M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.</code>
<p>
- where <c>M0</c> is any map. It follows that <c>M1 .. M4</c> are maps as well.
+ Here <c>M0</c> is any map. It follows that <c>M1 .. M4</c> are maps as well.
</p>
<p>
- More Examples:
+ More <em>Examples:</em>
</p>
<pre>
1> <input>M = #{1 => a}.</input>
@@ -921,83 +957,84 @@ M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.</code>
As in construction, the order in which the key and value expressions
are evaluated is not defined. The
syntactic order of the key-value pairs in the update is of no
- relevance, except in the case where two keys match, in which
- case the latter value is used.
+ relevance, except in the case where two keys match.
+ In that case, the latter value is used.
</p>
</section>
<section>
<title>Maps in Patterns</title>
<p>
- Matching of key-value associations from maps is done in the following way:
+ Matching of key-value associations from maps is done as follows:
</p>
<code>#{ K := V } = M</code>
<p>
- where <c>M</c> is any map. The key <c>K</c> has to be an expression with bound
- variables or a literals, and <c>V</c> can be any pattern with either bound or
+ Here <c>M</c> is any map. The key <c>K</c> must be an expression with bound
+ variables or literals. <c>V</c> can be any pattern with either bound or
unbound variables.
</p>
<p>
- If the variable <c>V</c> is unbound, it will be bound to the value associated
- with the key <c>K</c>, which has to exist in the map <c>M</c>. If the variable
- <c>V</c> is bound, it has to match the value associated with <c>K</c> in <c>M</c>.
+ If the variable <c>V</c> is unbound, it becomes bound to the value associated
+ with the key <c>K</c>, which must exist in the map <c>M</c>. If the variable
+ <c>V</c> is bound, it must match the value associated with <c>K</c> in <c>M</c>.
</p>
- <p> Example: </p>
-<code>
+ <p><em>Example:</em></p>
+<pre>
1> <input>M = #{"tuple" => {1,2}}.</input>
#{"tuple" => {1,2}}
2> <input>#{"tuple" := {1,B}} = M.</input>
#{"tuple" => {1,2}}
3> <input>B.</input>
-2.</code>
+2.</pre>
<p>
- This will bind variable <c>B</c> to integer <c>2</c>.
+ This binds variable <c>B</c> to integer <c>2</c>.
</p>
<p>
- Similarly, multiple values from the map may be matched:
+ Similarly, multiple values from the map can be matched:
</p>
<code>#{ K1 := V1, .., Kn := Vn } = M</code>
<p>
- where keys <c>K1 .. Kn</c> are any expressions with literals or bound variables. If all
- keys exist in map <c>M</c> all variables in <c>V1 .. Vn</c> will be matched to the
+ Here keys <c>K1 .. Kn</c> are any expressions with literals or bound variables. If all
+ keys exist in map <c>M</c>, all variables in <c>V1 .. Vn</c> is matched to the
associated values of their respective keys.
</p>
<p>
- If the matching conditions are not met, the match will fail, either with
+ If the matching conditions are not met, the match fails, either with:
</p>
<list>
- <item>
- a <c>badmatch</c> exception, if used in the context of the matching operator
- as in the example,
+ <item><p>A <c>badmatch</c> exception.</p>
+ <p>This is if it is used in the context of the matching operator
+ as in the example.</p>
</item>
- <item>
- or resulting in the next clause being tested in function heads and
- case expressions.
+ <item><p>Or resulting in the next clause being tested in function heads and
+ case expressions.</p>
</item>
</list>
<p>
Matching in maps only allows for <c>:=</c> as delimiters of associations.
+ </p>
+ <p>
The order in which keys are declared in matching has no relevance.
</p>
<p>
- Duplicate keys are allowed in matching and will match each pattern associated
- to the keys.
+ Duplicate keys are allowed in matching and match each pattern associated
+ to the keys:
</p>
<code>#{ K := V1, K := V2 } = M</code>
<p>
- Matching an expression against an empty map literal will match its type but
- no variables will be bound:
+ Matching an expression against an empty map literal, matches its type but
+ no variables are bound:
</p>
<code>#{} = Expr</code>
<p>
- This expression will match if the expression <c>Expr</c> is of type map, otherwise
- it will fail with an exception <c>badmatch</c>.
+ This expression matches if the expression <c>Expr</c> is of type map, otherwise
+ it fails with an exception <c>badmatch</c>.
</p>
<section>
- <title>Matching syntax: Example with literals in function heads</title>
+ <title>Matching Syntax</title>
<p>
- Matching of literals as keys are allowed in function heads.
+ Matching of literals as keys are allowed in function heads:
</p>
<code>
%% only start if not_started
@@ -1014,17 +1051,19 @@ handle_call(change, From, #{ state := start } = S) ->
<section>
<title>Maps in Guards</title>
<p>
- Maps are allowed in guards as long as all sub-expressions are valid guard expressions.
+ Maps are allowed in guards as long as all subexpressions are valid guard expressions.
</p>
<p>
- Two guard BIFs handles maps:
+ Two guard BIFs handle maps:
</p>
<list>
<item>
<seealso marker="erts:erlang#is_map/1">is_map/1</seealso>
+ in the <c>erlang</c> module
</item>
<item>
<seealso marker="erts:erlang#map_size/1">map_size/1</seealso>
+ in the <c>erlang</c> module
</item>
</list>
</section>
@@ -1044,29 +1083,34 @@ Ei = Value |
Value/TypeSpecifierList |
Value:Size/TypeSpecifierList</pre>
<p>Used in a bit string construction, <c>Value</c> is an expression
- which should evaluate to an integer, float or bit string. If the
- expression is something else than a single literal or variable, it
- should be enclosed in parenthesis.</p>
+ that is to evaluate to an integer, float, or bit string. If the
+ expression is not a single literal or variable, it
+ is to be enclosed in parenthesis.</p>
<p>Used in a bit string matching, <c>Value</c> must be a variable,
- or an integer, float or string.</p>
+ or an integer, float, or string.</p>
- <p>Note that, for example, using a string literal as in
+ <p>Notice that, for example, using a string literal as in
<c><![CDATA[<<"abc">>]]></c> is syntactic sugar for
<c><![CDATA[<<$a,$b,$c>>]]></c>.</p>
<p>Used in a bit string construction, <c>Size</c> is an expression
- which should evaluate to an integer.</p>
+ that is to evaluate to an integer.</p>
- <p>Used in a bit string matching, <c>Size</c> must be an integer or a
+ <p>Used in a bit string matching, <c>Size</c> must be an integer, or a
variable bound to an integer.</p>
<p>The value of <c>Size</c> specifies the size of the segment in
units (see below). The default value depends on the type (see
- below). For <c>integer</c> it is 8, for
- <c>float</c> it is 64, for <c>binary</c> and <c>bitstring</c> it is
- the whole binary or bit string. In matching, this default value is only
- valid for the very last element. All other bit string or binary
+ below):</p>
+ <list type="bulleted">
+ <item>For <c>integer</c> it is 8.</item>
+ <item>For <c>float</c> it is 64.</item>
+ <item>For <c>binary</c> and <c>bitstring</c> it is
+ the whole binary or bit string.</item>
+ </list>
+ <p>In matching, this default value is only
+ valid for the last element. All other bit string or binary
elements in the matching must have a size specification.</p>
<p>For the <c>utf8</c>, <c>utf16</c>, and <c>utf32</c> types,
@@ -1090,7 +1134,7 @@ Ei = Value |
The default is <c>unsigned</c>.</item>
<tag><c>Endianness</c>= <c>big</c> | <c>little</c> | <c>native</c></tag>
- <item>Native-endian means that the endianness will be resolved at load
+ <item>Native-endian means that the endianness is resolved at load
time to be either big-endian or little-endian, depending on
what is native for the CPU that the Erlang machine is run on.
Endianness only matters when the Type is either <c>integer</c>,
@@ -1099,7 +1143,7 @@ Ei = Value |
<tag><c>Unit</c>= <c>unit:IntegerLiteral</c></tag>
<item>The allowed range is 1..256. Defaults to 1 for <c>integer</c>,
- <c>float</c> and <c>bitstring</c>, and to 8 for <c>binary</c>.
+ <c>float</c>, and <c>bitstring</c>, and to 8 for <c>binary</c>.
No unit specifier must be given for the types
<c>utf8</c>, <c>utf16</c>, and <c>utf32</c>.
</item>
@@ -1110,8 +1154,8 @@ Ei = Value |
<note><p>When constructing binaries, if the size <c>N</c> of an integer
segment is too small to contain the given integer, the most significant
- bits of the integer will be silently discarded and only the <c>N</c> least
- significant bits will be put into the binary.</p></note>
+ bits of the integer are silently discarded and only the <c>N</c> least
+ significant bits are put into the binary.</p></note>
<p>The types <c>utf8</c>, <c>utf16</c>, and <c>utf32</c> specifies
encoding/decoding of the <em>Unicode Transformation Format</em>s UTF-8, UTF-16,
@@ -1120,39 +1164,39 @@ Ei = Value |
<p>When constructing a segment of a <c>utf</c> type, <c>Value</c>
must be an integer in the range 0..16#D7FF or
16#E000....16#10FFFF. Construction
- will fail with a <c>badarg</c> exception if <c>Value</c> is
+ fails with a <c>badarg</c> exception if <c>Value</c> is
outside the allowed ranges. The size of the resulting binary
- segment depends on the type and/or <c>Value</c>. For <c>utf8</c>,
- <c>Value</c> will be encoded in 1 through 4 bytes. For
- <c>utf16</c>, <c>Value</c> will be encoded in 2 or 4
- bytes. Finally, for <c>utf32</c>, <c>Value</c> will always be
- encoded in 4 bytes.</p>
+ segment depends on the type or <c>Value</c>, or both:</p>
+ <list type="bulleted">
+ <item>For <c>utf8</c>, <c>Value</c> is encoded in 1-4 bytes.</item>
+ <item>For <c>utf16</c>, <c>Value</c> is encoded in 2 or 4 bytes.</item>
+ <item>For <c>utf32</c>, <c>Value</c> is always be encoded in 4 bytes.</item>
+ </list>
- <p>When constructing, a literal string may be given followed
+ <p>When constructing, a literal string can be given followed
by one of the UTF types, for example: <c><![CDATA[<<"abc"/utf8>>]]></c>
- which is syntatic sugar for
+ which is syntactic sugar for
<c><![CDATA[<<$a/utf8,$b/utf8,$c/utf8>>]]></c>.</p>
- <p>A successful match of a segment of a <c>utf</c> type results
+ <p>A successful match of a segment of a <c>utf</c> type, results
in an integer in the range 0..16#D7FF or 16#E000..16#10FFFF.
- The match will fail if returned value
- would fall outside those ranges.</p>
+ The match fails if the returned value falls outside those ranges.</p>
- <p>A segment of type <c>utf8</c> will match 1 to 4 bytes in the binary,
+ <p>A segment of type <c>utf8</c> matches 1-4 bytes in the binary,
if the binary at the match position contains a valid UTF-8 sequence.
(See RFC-3629 or the Unicode standard.)</p>
- <p>A segment of type <c>utf16</c> may match 2 or 4 bytes in the binary.
- The match will fail if the binary at the match position does not contain
+ <p>A segment of type <c>utf16</c> can match 2 or 4 bytes in the binary.
+ The match fails if the binary at the match position does not contain
a legal UTF-16 encoding of a Unicode code point. (See RFC-2781 or
the Unicode standard.)</p>
- <p>A segment of type <c>utf32</c> may match 4 bytes in the binary in the
- same way as an <c>integer</c> segment matching 32 bits.
- The match will fail if the resulting integer is outside the legal ranges
+ <p>A segment of type <c>utf32</c> can match 4 bytes in the binary in the
+ same way as an <c>integer</c> segment matches 32 bits.
+ The match fails if the resulting integer is outside the legal ranges
mentioned above.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>Bin1 = &lt;&lt;1,17,42&gt;&gt;.</input>
&lt;&lt;1,17,42&gt;&gt;
@@ -1181,11 +1225,13 @@ Ei = Value |
13> <input>&lt;&lt;1024/utf8&gt;&gt;.</input>
&lt;&lt;208,128&gt;&gt;
</pre>
- <p>Note that bit string patterns cannot be nested.</p>
- <p>Note also that "<c><![CDATA[B=<<1>>]]></c>" is interpreted as
+ <p>Notice that bit string patterns cannot be nested.</p>
+ <p>Notice also that "<c><![CDATA[B=<<1>>]]></c>" is interpreted as
"<c><![CDATA[B =<<1>>]]></c>" which is a syntax error. The correct way is
to write a space after '=': "<c><![CDATA[B= <<1>>]]></c>.</p>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:bit_syntax">
+ Programming Examples</seealso>.</p>
</section>
<section>
@@ -1200,16 +1246,16 @@ fun
BodyK
end</pre>
<p>A fun expression begins with the keyword <c>fun</c> and ends
- with the keyword <c>end</c>. Between them should be a function
+ with the keyword <c>end</c>. Between them is to be a function
declaration, similar to a
<seealso marker="functions#syntax">regular function declaration</seealso>,
- except that the function name is optional and should be a variable if
+ except that the function name is optional and is to be a variable, if
any.</p>
<p>Variables in a fun head shadow the function name and both shadow
- variables in the function clause surrounding the fun expression, and
- variables bound in a fun body are local to the fun body.</p>
+ variables in the function clause surrounding the fun expression.
+ Variables bound in a fun body are local to the fun body.</p>
<p>The return value of the expression is the resulting fun.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>Fun1 = fun (X) -> X+1 end.</input>
#Fun&lt;erl_eval.6.39074546&gt;
@@ -1232,15 +1278,17 @@ fun Module:Name/Arity</pre>
syntactic sugar for:</p>
<pre>
fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end</pre>
- <p>In <c>Module:Name/Arity</c>, <c>Module</c> and <c>Name</c> are atoms
- and <c>Arity</c> is an integer. Starting from the R15 release,
- <c>Module</c>, <c>Name</c>, and <c>Arity</c> may also be variables.
- A fun defined in this way will refer to the function <c>Name</c>
+ <p>In <c>Module:Name/Arity</c>, <c>Module</c>, and <c>Name</c> are atoms
+ and <c>Arity</c> is an integer. Starting from Erlang/OTP R15,
+ <c>Module</c>, <c>Name</c>, and <c>Arity</c> can also be variables.
+ A fun defined in this way refers to the function <c>Name</c>
with arity <c>Arity</c> in the <em>latest</em> version of module
- <c>Module</c>. A fun defined in this way will not be dependent on
- the code for module in which it is defined.
+ <c>Module</c>. A fun defined in this way is not dependent on
+ the code for the module in which it is defined.
</p>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:funs">
+ Programming Examples</seealso>.</p>
</section>
<section>
@@ -1250,23 +1298,26 @@ fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end</pre>
catch Expr</code>
<p>Returns the value of <c>Expr</c> unless an exception
occurs during the evaluation. In that case, the exception is
- caught. For exceptions of class <c>error</c>,
- that is run-time errors: <c>{'EXIT',{Reason,Stack}}</c>
- is returned. For exceptions of class <c>exit</c>, that is
- the code called <c>exit(Term)</c>: <c>{'EXIT',Term}</c> is returned.
- For exceptions of class <c>throw</c>, that is
- the code called <c>throw(Term)</c>: <c>Term</c> is returned.</p>
+ caught.</p>
+ <p>For exceptions of class <c>error</c>, that is,
+ run-time errors,
+ <c>{'EXIT',{Reason,Stack}}</c> is returned.</p>
+ <p>For exceptions of class <c>exit</c>, that is,
+ the code called <c>exit(Term)</c>,
+ <c>{'EXIT',Term}</c> is returned.</p>
+ <p>For exceptions of class <c>throw</c>, that is
+ the code called <c>throw(Term)</c>,
+ <c>Term</c> is returned.</p>
<p><c>Reason</c> depends on the type of error that occurred, and
<c>Stack</c> is the stack of recent function calls, see
- <seealso marker="errors#exit_reasons">Errors and Error Handling</seealso>.</p>
- <p>Examples:</p>
- <p></p>
+ <seealso marker="errors#exit_reasons">Exit Reasons</seealso>.</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>catch 1+2.</input>
3
2> <input>catch 1+a.</input>
{'EXIT',{badarith,[...]}}</pre>
- <p>Note that <c>catch</c> has low precedence and catch
+ <p>Notice that <c>catch</c> has low precedence and catch
subexpressions often needs to be enclosed in a block
expression or in parenthesis:</p>
<pre>
@@ -1275,13 +1326,14 @@ catch Expr</code>
4> <input>A = (catch 1+2).</input>
3</pre>
<p>The BIF <c>throw(Any)</c> can be used for non-local return from
- a function. It must be evaluated within a <c>catch</c>, which will
- return the value <c>Any</c>. Example:</p>
+ a function. It must be evaluated within a <c>catch</c>, which
+ returns the value <c>Any</c>.</p>
+ <p><em>Example:</em></p>
<pre>
5> <input>catch throw(hello).</input>
hello</pre>
<p>If <c>throw/1</c> is not evaluated within a catch, a
- <c>nocatch</c> run-time error will occur.</p>
+ <c>nocatch</c> run-time error occurs.</p>
</section>
<section>
@@ -1297,14 +1349,17 @@ catch
end</code>
<p>This is an enhancement of
<seealso marker="#catch">catch</seealso> that appeared in
- Erlang 5.4/OTP-R10B. It gives the possibility do distinguish
- between different exception classes, and to choose to handle only
- the desired ones, passing the others on to an enclosing
- <c>try</c> or <c>catch</c> or to default error handling.</p>
- <p>Note that although the keyword <c>catch</c> is used in
+ Erlang 5.4/OTP R10B. It gives the possibility to:</p>
+ <list type="bulleted">
+ <item>Distinguish between different exception classes.</item>
+ <item>Choose to handle only the desired ones.</item>
+ <item>Passing the others on to an enclosing
+ <c>try</c> or <c>catch</c>, or to default error handling.</item>
+ </list>
+ <p>Notice that although the keyword <c>catch</c> is used in
the <c>try</c> expression, there is not a <c>catch</c> expression
within the <c>try</c> expression.</p>
- <p>Returns the value of <c>Exprs</c> (a sequence of expressions
+ <p>It returns the value of <c>Exprs</c> (a sequence of expressions
<c>Expr1, ..., ExprN</c>) unless an exception occurs during
the evaluation. In that case the exception is caught and
the patterns <c>ExceptionPattern</c> with the right exception
@@ -1318,7 +1373,7 @@ end</code>
<c>Class</c> with a true guard sequence, the exception is passed
on as if <c>Exprs</c> had not been enclosed in a <c>try</c>
expression.</p>
- <p>If an exception occurs during evaluation of <c>ExceptionBody</c>
+ <p>If an exception occurs during evaluation of <c>ExceptionBody</c>,
it is not caught.</p>
<p>The <c>try</c> expression can have an <c>of</c>
section:
@@ -1341,7 +1396,7 @@ end</code>
the patterns <c>Pattern</c> are sequentially matched against
the result in the same way as for a
<seealso marker="#case">case</seealso> expression, except that if
- the matching fails, a <c>try_clause</c> run-time error will occur.</p>
+ the matching fails, a <c>try_clause</c> run-time error occurs.</p>
<p>An exception occurring during the evaluation of <c>Body</c> is
not caught.</p>
<p>The <c>try</c> expression can also be augmented with an
@@ -1364,7 +1419,7 @@ after
AfterBody
end</code>
<p><c>AfterBody</c> is evaluated after either <c>Body</c> or
- <c>ExceptionBody</c> no matter which one. The evaluated value of
+ <c>ExceptionBody</c>, no matter which one. The evaluated value of
<c>AfterBody</c> is lost; the return value of the <c>try</c>
expression is the same with an <c>after</c> section as without.</p>
<p>Even if an exception occurs during evaluation of <c>Body</c> or
@@ -1373,13 +1428,13 @@ end</code>
evaluated, so the exception from the <c>try</c> expression is
the same with an <c>after</c> section as without.</p>
<p>If an exception occurs during evaluation of <c>AfterBody</c>
- itself it is not caught, so if <c>AfterBody</c> is evaluated after
- an exception in <c>Exprs</c>, <c>Body</c> or <c>ExceptionBody</c>,
+ itself, it is not caught. So if <c>AfterBody</c> is evaluated after
+ an exception in <c>Exprs</c>, <c>Body</c>, or <c>ExceptionBody</c>,
that exception is lost and masked by the exception in
<c>AfterBody</c>.</p>
- <p>The <c>of</c>, <c>catch</c> and <c>after</c> sections are all
+ <p>The <c>of</c>, <c>catch</c>, and <c>after</c> sections are all
optional, as long as there is at least a <c>catch</c> or an
- <c>after</c> section, so the following are valid <c>try</c>
+ <c>after</c> section. So the following are valid <c>try</c>
expressions:</p>
<code type="none">
try Exprs of
@@ -1398,9 +1453,9 @@ after
end
try Exprs after AfterBody end</code>
- <p>Example of using <c>after</c>, this code will close the file
+ <p>Next is an example of using <c>after</c>. This closes the file,
even in the event of exceptions in <c>file:read/2</c> or in
- <c>binary_to_term/1</c>, and exceptions will be the same as
+ <c>binary_to_term/1</c>. The exceptions are the same as
without the <c>try</c>...<c>after</c>...<c>end</c> expression:</p>
<code type="none">
termize_file(Name) ->
@@ -1411,7 +1466,7 @@ termize_file(Name) ->
after
file:close(F)
end.</code>
- <p>Example: Using <c>try</c> to emulate <c>catch Expr</c>.</p>
+ <p>Next is an example of using <c>try</c> to emulate <c>catch Expr</c>:</p>
<code type="none">
try Expr
catch
@@ -1427,7 +1482,7 @@ end</code>
(Expr)</pre>
<p>Parenthesized expressions are useful to override
<seealso marker="#prec">operator precedences</seealso>,
- for example in arithmetic expressions:</p>
+ for example, in arithmetic expressions:</p>
<pre>
1> <input>1 + 2 * 3.</input>
7
@@ -1451,7 +1506,7 @@ end</pre>
<section>
<marker id="lcs"></marker>
<title>List Comprehensions</title>
- <p>List comprehensions are a feature of many modern functional
+ <p>List comprehensions is a feature of many modern functional
programming languages. Subject to certain rules, they provide a
succinct notation for generating elements in a list.</p>
<p>List comprehensions are analogous to set comprehensions in
@@ -1461,32 +1516,34 @@ end</pre>
<p>List comprehensions are written with the following syntax:</p>
<pre>
[Expr || Qualifier1,...,QualifierN]</pre>
- <p><c>Expr</c> is an arbitrary expression, and each
+ <p>Here, <c>Expr</c> is an arbitrary expression, and each
<c>Qualifier</c> is either a generator or a filter.</p>
<list type="bulleted">
<item>A <em>generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[Pattern <- ListExpr]]></c>. <br></br>
-<c>ListExpr</c> must be an expression which evaluates to a
+<c>ListExpr</c> must be an expression, which evaluates to a
list of terms.</item>
<item>A <em>bit string generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[BitstringPattern <= BitStringExpr]]></c>. <br></br>
-<c>BitStringExpr</c> must be an expression which evaluates to a
+<c>BitStringExpr</c> must be an expression, which evaluates to a
bitstring.</item>
- <item>A <em>filter</em> is an expression which evaluates to
+ <item>A <em>filter</em> is an expression, which evaluates to
<c>true</c> or <c>false</c>.</item>
</list>
- <p>The variables in the generator patterns shadow variables in the function
- clause surrounding the list comprehensions.</p> <p>A list comprehension
+ <p>The variables in the generator patterns, shadow variables in the function
+ clause, surrounding the list comprehensions.</p> <p>A list comprehension
returns a list, where the elements are the result of evaluating <c>Expr</c>
for each combination of generator list elements and bit string generator
- elements for which all filters are true.</p> <p></p> <p>Example:</p>
+ elements, for which all filters are true.</p>
+ <p><em>Example:</em></p>
<pre>
1> <input>[X*2 || X &lt;- [1,2,3]].</input>
[2,4,6]</pre>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
-
+ <p>More examples are provoded in
+ <seealso marker="doc/programming_examples:list_comprehensions">
+ Programming Examples.</seealso></p>
</section>
@@ -1500,34 +1557,35 @@ end</pre>
the following syntax:</p>
<pre>
&lt;&lt; BitString || Qualifier1,...,QualifierN &gt;&gt;</pre>
- <p><c>BitString</c> is a bit string expression, and each
+ <p>Here, <c>BitString</c> is a bit string expression and each
<c>Qualifier</c> is either a generator, a bit string generator or a filter.</p>
<list type="bulleted">
<item>A <em>generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[Pattern <- ListExpr]]></c>. <br></br>
- <c>ListExpr</c> must be an expression which evaluates to a
+ <c>ListExpr</c> must be an expression that evaluates to a
list of terms.</item>
<item>A <em>bit string generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[BitstringPattern <= BitStringExpr]]></c>. <br></br>
-<c>BitStringExpr</c> must be an expression which evaluates to a
+<c>BitStringExpr</c> must be an expression that evaluates to a
bitstring.</item>
- <item>A <em>filter</em> is an expression which evaluates to
+ <item>A <em>filter</em> is an expression that evaluates to
<c>true</c> or <c>false</c>.</item>
</list>
- <p>The variables in the generator patterns shadow variables in
- the function clause surrounding the bit string comprehensions.</p>
+ <p>The variables in the generator patterns, shadow variables in
+ the function clause, surrounding the bit string comprehensions.</p>
<p>A bit string comprehension returns a bit string, which is
created by concatenating the results of evaluating <c>BitString</c>
- for each combination of bit string generator elements for which all
+ for each combination of bit string generator elements, for which all
filters are true.</p>
- <p></p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
-1> <input>&lt;&lt; &lt;&lt; (X*2) &gt;&gt; ||
+1> <input>&lt;&lt; &lt;&lt; (X*2) &gt;&gt; ||
&lt;&lt;X&gt;&gt; &lt;= &lt;&lt; 1,2,3 &gt;&gt; &gt;&gt;.</input>
&lt;&lt;2,4,6&gt;&gt;</pre>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:bit_syntax">
+ Programming Examples.</seealso></p>
</section>
<section>
@@ -1536,27 +1594,27 @@ end</pre>
<p>A <em>guard sequence</em> is a sequence of guards, separated
by semicolon (;). The guard sequence is true if at least one of
- the guards is true. (The remaining guards, if any, will not be
- evaluated.)<br></br>
-<c>Guard1;...;GuardK</c></p>
+ the guards is true. (The remaining guards, if any, are not
+ evaluated.)</p>
+ <p><c>Guard1;...;GuardK</c></p>
<p>A <em>guard</em> is a sequence of guard expressions, separated
by comma (,). The guard is true if all guard expressions
- evaluate to <c>true</c>.<br></br>
-<c>GuardExpr1,...,GuardExprN</c></p>
+ evaluate to <c>true</c>.</p>
+ <p><c>GuardExpr1,...,GuardExprN</c></p>
<p>The set of valid <em>guard expressions</em> (sometimes called
guard tests) is a subset of the set of valid Erlang expressions.
The reason for restricting the set of valid expressions is that
evaluation of a guard expression must be guaranteed to be free
- of side effects. Valid guard expressions are:</p>
+ of side effects. Valid guard expressions are the following:</p>
<list type="bulleted">
- <item>the atom <c>true</c>,</item>
- <item>other constants (terms and bound variables), all regarded
- as false,</item>
- <item>calls to the BIFs specified below,</item>
- <item>term comparisons,</item>
- <item>arithmetic expressions,</item>
- <item>boolean expressions, and</item>
- <item>short-circuit expressions (<c>andalso</c>/<c>orelse</c>).</item>
+ <item>The atom <c>true</c></item>
+ <item>Other constants (terms and bound variables), all regarded
+ as false</item>
+ <item>Calls to the BIFs specified in table <c>Type Test BIFs</c></item>
+ <item>Term comparisons</item>
+ <item>Arithmetic expressions</item>
+ <item>Boolean expressions</item>
+ <item>Short-circuit expressions (<c>andalso</c>/<c>orelse</c>)</item>
</list>
<table>
<row>
@@ -1610,13 +1668,13 @@ end</pre>
<row>
<cell align="left" valign="middle"><c>is_tuple/1</c></cell>
</row>
- <tcaption>Type Test BIFs.</tcaption>
+ <tcaption>Type Test BIFs</tcaption>
</table>
- <p>Note that most type test BIFs have older equivalents, without
+ <p>Notice that most type test BIFs have older equivalents, without
the <c>is_</c> prefix. These old BIFs are retained for backwards
- compatibility only and should not be used in new code. They are
+ compatibility only and are not to be used in new code. They are
also only allowed at top level. For example, they are not allowed
- in boolean expressions in guards.</p>
+ in Boolean expressions in guards.</p>
<table>
<row>
<cell align="left" valign="middle"><c>abs(Number)</c></cell>
@@ -1666,14 +1724,14 @@ end</pre>
<row>
<cell align="left" valign="middle"><c>tuple_size(Tuple)</c></cell>
</row>
- <tcaption>Other BIFs Allowed in Guard Expressions.</tcaption>
+ <tcaption>Other BIFs Allowed in Guard Expressions</tcaption>
</table>
- <p>If an arithmetic expression, a boolean expression, a
+ <p>If an arithmetic expression, a Boolean expression, a
short-circuit expression, or a call to a guard BIF fails (because
of invalid arguments), the entire guard fails. If the guard was
part of a guard sequence, the next guard in the sequence (that is,
- the guard following the next semicolon) will be evaluated.</p>
+ the guard following the next semicolon) is evaluated.</p>
</section>
@@ -1726,12 +1784,13 @@ end</pre>
<cell align="left" valign="middle">catch</cell>
<cell align="left" valign="middle">&nbsp;</cell>
</row>
- <tcaption>Operator Precedence.</tcaption>
+ <tcaption>Operator Precedence</tcaption>
</table>
<p>When evaluating an expression, the operator with the highest
priority is evaluated first. Operators with the same priority
- are evaluated according to their associativity. Example:
- The left associative arithmetic operators are evaluated left to
+ are evaluated according to their associativity.</p>
+ <p><em>Example:</em></p>
+ <p>The left associative arithmetic operators are evaluated left to
right:</p>
<pre>
<input>6 + 5 * 4 - 3 / 2</input> evaluates to
diff --git a/system/doc/reference_manual/functions.xml b/system/doc/reference_manual/functions.xml
index 9498ef1402..863514ee78 100644
--- a/system/doc/reference_manual/functions.xml
+++ b/system/doc/reference_manual/functions.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -38,7 +39,7 @@
clause body, separated by <c>-></c>.</p>
<p>A clause <em>head</em> consists of the function name, an
argument list, and an optional guard sequence
- beginning with the keyword <c>when</c>.</p>
+ beginning with the keyword <c>when</c>:</p>
<pre>
Name(Pattern11,...,Pattern1N) [when GuardSeq1] ->
Body1;
@@ -48,9 +49,9 @@ Name(PatternK1,...,PatternKN) [when GuardSeqK] ->
<p>The function name is an atom. Each argument is a pattern.</p>
<p>The number of arguments <c>N</c> is the <em>arity</em> of
the function. A function is uniquely defined by the module name,
- function name and arity. That is, two functions with the same
+ function name, and arity. That is, two functions with the same
name and in the same module, but with different arities are two
- completely different functions.</p>
+ different functions.</p>
<p>A function named <c>f</c> in the module <c>m</c> and with arity
<c>N</c> is often denoted as <c>m:f/N</c>.</p>
<p>A clause <em>body</em> consists of a sequence of expressions
@@ -60,8 +61,8 @@ Expr1,
...,
ExprN</pre>
<p>Valid Erlang expressions and guard sequences are described in
- <seealso marker="expressions">Erlang Expressions</seealso>.</p>
- <p>Example:</p>
+ <seealso marker="expressions">Expressions</seealso>.</p>
+ <p><em>Example:</em></p>
<pre>
fact(N) when N>0 -> % first clause head
N * fact(N-1); % first clause body
@@ -75,23 +76,23 @@ fact(0) -> % second clause head
<title>Function Evaluation</title>
<p>When a function <c>m:f/N</c> is called, first the code for
the function is located. If the function cannot be found, an
- <c>undef</c> run-time error will occur. Note that the function
+ <c>undef</c> runtime error occurs. Notice that the function
must be exported to be visible outside the module it is defined
in.</p>
<p>If the function is found, the function clauses are scanned
- sequentially until a clause is found that fulfills the following
- two conditions:</p>
+ sequentially until a clause is found that fulfills both of
+ the following two conditions:</p>
<list type="ordered">
- <item>the patterns in the clause head can be successfully
- matched against the given arguments, and</item>
- <item>the guard sequence, if any, is true.</item>
+ <item>The patterns in the clause head can be successfully
+ matched against the given arguments.</item>
+ <item>The guard sequence, if any, is true.</item>
</list>
<p>If such a clause cannot be found, a <c>function_clause</c>
- run-time error will occur.</p>
+ runtime error occurs.</p>
<p>If such a clause is found, the corresponding clause body is
evaluated. That is, the expressions in the body are evaluated
sequentially and the value of the last expression is returned.</p>
- <p>Example: Consider the function <c>fact</c>:</p>
+ <p>Consider the function <c>fact</c>:</p>
<pre>
-module(m).
-export([fact/1]).
@@ -100,17 +101,17 @@ fact(N) when N>0 ->
N * fact(N-1);
fact(0) ->
1.</pre>
- <p>Assume we want to calculate factorial for 1:</p>
+ <p>Assume that you want to calculate the factorial for 1:</p>
<pre>
1> <input>m:fact(1).</input></pre>
<p>Evaluation starts at the first clause. The pattern <c>N</c> is
- matched against the argument 1. The matching succeeds and
- the guard (<c>N>0</c>) is true, thus <c>N</c> is bound to 1 and
+ matched against argument 1. The matching succeeds and
+ the guard (<c>N>0</c>) is true, thus <c>N</c> is bound to 1, and
the corresponding body is evaluated:</p>
<pre>
<input>N * fact(N-1)</input> => (N is bound to 1)
<input>1 * fact(0)</input></pre>
- <p>Now <c>fact(0)</c> is called and the function clauses are
+ <p>Now, <c>fact(0)</c> is called, and the function clauses are
scanned sequentially again. First, the pattern <c>N</c> is
matched against 0. The matching succeeds, but the guard
(<c>N>0</c>) is false. Second, the pattern 0 is matched against
@@ -121,48 +122,51 @@ fact(0) ->
<input>1</input></pre>
<p>Evaluation has succeed and <c>m:fact(1)</c> returns 1.</p>
<p>If <c>m:fact/1</c> is called with a negative number as
- argument, no clause head will match. A <c>function_clause</c>
- run-time error will occur.</p>
+ argument, no clause head matches. A <c>function_clause</c>
+ runtime error occurs.</p>
</section>
<section>
<title>Tail recursion</title>
<p>If the last expression of a function body is a function call,
- a <em>tail recursive</em> call is done so that no system
- resources for example call stack are consumed. This means
- that an infinite loop can be done if it uses tail recursive
+ a <em>tail recursive</em> call is done.
+ This is to ensure that no system
+ resources, for example, call stack, are consumed. This means
+ that an infinite loop can be done if it uses tail-recursive
calls.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
loop(N) ->
io:format("~w~n", [N]),
loop(N+1).</pre>
- <p>As a counter-example see the factorial example above
- that is not tail recursive since a multiplication is done
+ <p>The earlier factorial example can act as a counter-example.
+ It is not tail-recursive, since a multiplication is done
on the result of the recursive call to <c>fact(N-1)</c>.</p>
</section>
<section>
- <title>Built-In Functions, BIFs</title>
- <p><em>Built-in functions</em>, BIFs, are implemented in C code in
- the runtime system and do things that are difficult or impossible
- to implement in Erlang. Most of the built-in functions belong
- to the module <c>erlang</c> but there are also built-in functions
+ <title>Built-In Functions (BIFs)</title>
+ <p>BIFs are implemented in C code in
+ the runtime system. BIFs do things that are difficult or impossible
+ to implement in Erlang. Most of the BIFs belong
+ to the module <c>erlang</c> but there are also BIFs
belonging to a few other modules, for example <c>lists</c> and
<c>ets</c>.</p>
- <p>The most commonly used BIFs belonging to <c>erlang</c> are
- <em>auto-imported</em>, they do not need to be prefixed with
- the module name. Which BIFs are auto-imported is specified in
- <c>erlang(3)</c>. For example, standard type conversion BIFs like
+ <p>The most commonly used BIFs belonging to <c>erlang(3)</c> are
+ <em>auto-imported</em>. They do not need to be prefixed with
+ the module name. Which BIFs that are auto-imported is specified in the
+ <seealso marker="erts:erlang">erlang(3)</seealso> module in ERTS.
+ For example, standard-type conversion BIFs like
<c>atom_to_list</c> and BIFs allowed in guards can be called
- without specifying the module name. Examples:</p>
+ without specifying the module name.</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>tuple_size({a,b,c}).</input>
3
2> <input>atom_to_list('Erlang').</input>
"Erlang"</pre>
- <p>Note that normally it is the set of auto-imported built-in
- functions that is referred to when talking about 'BIFs'.</p>
+ <p>Notice that it is normally the set of auto-imported BIFs
+ that are referred to when talking about 'BIFs'.</p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/introduction.xml b/system/doc/reference_manual/introduction.xml
index 36bec17825..abb4ed407d 100644
--- a/system/doc/reference_manual/introduction.xml
+++ b/system/doc/reference_manual/introduction.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,20 +29,38 @@
<rev></rev>
<file>introduction.xml</file>
</header>
+ <marker id="erlang ref manual"></marker>
+
+ <p>This section is the Erlang reference manual. It describes the
+ Erlang programming language. </p>
<section>
<title>Purpose</title>
- <p>This reference manual describes the Erlang programming
- language. The focus is on the language itself, not
- the implementation. The language constructs are described in
- text and with examples rather than formally specified, with
- the intention to make the manual more readable.
- The manual is not intended as a tutorial.</p>
- <p>Information about this implementation of Erlang can be found, for
- example, in <em>System Principles</em> (starting and stopping,
- boot scripts, code loading, error logging, creating target
- systems), <em>Efficiency Guide</em> (memory consumption, system
- limits) and <em>ERTS User's Guide</em> (crash dumps, drivers).</p>
+ <p>The focus of the Erlang reference manual is on the language itself,
+ not the implementation of it. The language constructs are described in
+ text and with examples rather than formally specified. This is
+ to make the manual more readable.
+ The Erlang reference manual is not intended as a tutorial.</p>
+ <p>Information about implementation of Erlang can, for example, be found,
+ in the following:</p>
+ <list type="bulleted">
+ <item><p><seealso marker="doc/system_principles:system_principles">
+ System Principles</seealso></p>
+ <p>Starting and stopping, boot scripts, code loading,
+ <seealso marker="doc/system_principles:error_logging">
+ error logging</seealso>,
+ <seealso marker="doc/system_principles:create_target">
+ creating target systems</seealso></p>
+ </item>
+ <item><p><seealso marker="doc/efficiency_guide:advanced">
+ Efficiency Guide</seealso></p>
+ <p>Memory consumption, system limits</p>
+ </item>
+ <item><p>ERTS User's Guide</p>
+ <p><seealso marker="erts:crash_dump">Crash dumps</seealso>,
+ <seealso marker="erts:driver">drivers</seealso></p>
+ </item>
+ </list>
</section>
<section>
@@ -53,13 +72,13 @@
<section>
<title>Document Conventions</title>
- <p>In the document, the following terminology is used:</p>
+ <p>In this section, the following terminology is used:</p>
<list type="bulleted">
<item>A <em>sequence</em> is one or more items. For example, a
clause body consists of a sequence of expressions. This
means that there must be at least one expression.</item>
<item>A <em>list</em> is any number of items. For example,
- an argument list can consist of zero, one or more arguments.</item>
+ an argument list can consist of zero, one, or more arguments.</item>
</list>
<p>If a feature has been added recently, in Erlang 5.0/OTP R7 or
later, this is mentioned in the text.</p>
@@ -68,15 +87,16 @@
<section>
<title>Complete List of BIFs</title>
<p>For a complete list of BIFs, their arguments and return values,
- refer to <c>erlang(3)</c>.</p>
+ see <seealso marker="erts:erlang#process_flag/2">erlang(3)</seealso>
+ manual page in ERTS.</p>
</section>
<section>
<title>Reserved Words</title>
<p>The following are reserved words in Erlang:</p>
- <p>after and andalso band begin bnot bor bsl bsr bxor case catch
+ <p><c>after and andalso band begin bnot bor bsl bsr bxor case catch
cond div end fun if let not of or orelse receive rem try
- when xor</p>
+ when xor</c></p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/macros.xml b/system/doc/reference_manual/macros.xml
index 9fd0b0f287..3b1f72e5d6 100644
--- a/system/doc/reference_manual/macros.xml
+++ b/system/doc/reference_manual/macros.xml
@@ -4,24 +4,25 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>The Preprocessor</title>
+ <title>Preprocessor</title>
<prepared></prepared>
<docno></docno>
<date></date>
@@ -31,17 +32,17 @@
<section>
<title>File Inclusion</title>
- <p>A file can be included in the following way:</p>
+ <p>A file can be included as follows:</p>
<pre>
-include(File).
-include_lib(File).</pre>
- <p><c>File</c>, a string, should point out a file. The contents of
- this file are included as-is, at the position of the directive.</p>
+ <p><c>File</c>, a string, is to point out a file. The contents of
+ this file are included as is, at the position of the directive.</p>
<p>Include files are typically used for record and macro
definitions that are shared by several modules. It is
- recommended that the file name extension <c>.hrl</c> be used
- for include files.</p>
- <p><c>File</c> may start with a path component <c>$VAR</c>, for
+ recommended to use the file name extension <c>.hrl</c> for
+ include files.</p>
+ <p><c>File</c> can start with a path component <c>$VAR</c>, for
some string <c>VAR</c>. If that is the case, the value of
the environment variable <c>VAR</c> as returned by
<c>os:getenv(VAR)</c> is substituted for <c>$VAR</c>. If
@@ -49,21 +50,29 @@
as is.</p>
<p>If the filename <c>File</c> is absolute (possibly after
variable substitution), the include file with that name is
- included. Otherwise, the specified file is searched for in
- the current working directory, in the same directory as
- the module being compiled, and in the directories given by
- the <c>include</c> option, in that order.
- See <c>erlc(1)</c> and <c>compile(3)</c> for details.</p>
- <p>Examples:</p>
+ included. Otherwise, the specified file is searched for
+ in the following directories, and in this order:</p>
+ <list type="ordered">
+ <item>The current working directory</item>
+ <item>The directory where the module is being compiled</item>
+ <item>The directories given by the <c>include</c> option</item>
+ </list>
+ <p>For details, see the
+ <seealso marker="erts:erlc">erlc(1)</seealso> manual page
+ in ERTS and
+ <seealso marker="compiler:compile">compile(3)</seealso>
+ manual page in Compiler.</p>
+ <p><em>Examples:</em></p>
<pre>
-include("my_records.hrl").
-include("incdir/my_records.hrl").
-include("/home/user/proj/my_records.hrl").
-include("$PROJ_ROOT/my_records.hrl").</pre>
- <p><c>include_lib</c> is similar to <c>include</c>, but should not
+ <p><c>include_lib</c> is similar to <c>include</c>, but is not to
point out an absolute file. Instead, the first path component
(possibly after variable substitution) is assumed to be
- the name of an application. Example:</p>
+ the name of an application.</p>
+ <p><em>Example:</em></p>
<pre>
-include_lib("kernel/include/file.hrl").</pre>
<p>The code server uses <c>code:lib_dir(kernel)</c> to find
@@ -74,7 +83,7 @@
<section>
<title>Defining and Using Macros</title>
- <p>A macro is defined the following way:</p>
+ <p>A macro is defined as follows:</p>
<code type="none">
-define(Const, Replacement).
-define(Func(Var1,...,VarN), Replacement).</code>
@@ -83,33 +92,34 @@
come before any usage of the macro.</p>
<p>If a macro is used in several modules, it is recommended that
the macro definition is placed in an include file.</p>
- <p>A macro is used the following way:</p>
+ <p>A macro is used as follows:</p>
<code type="none">
?Const
?Func(Arg1,...,ArgN)</code>
<p>Macros are expanded during compilation. A simple macro
- <c>?Const</c> will be replaced with <c>Replacement</c>.
- Example:</p>
+ <c>?Const</c> is replaced with <c>Replacement</c>.</p>
+ <p><em>Example:</em></p>
<code type="none">
-define(TIMEOUT, 200).
...
call(Request) ->
server:call(refserver, Request, ?TIMEOUT).</code>
- <p>This will be expanded to:</p>
+ <p>This is expanded to:</p>
<code type="none">
call(Request) ->
server:call(refserver, Request, 200).</code>
- <p>A macro <c>?Func(Arg1,...,ArgN)</c> will be replaced with
+ <p>A macro <c>?Func(Arg1,...,ArgN)</c> is replaced with
<c>Replacement</c>, where all occurrences of a variable <c>Var</c>
from the macro definition are replaced with the corresponding
- argument <c>Arg</c>. Example:</p>
+ argument <c>Arg</c>.</p>
+ <p><em>Example:</em></p>
<code type="none">
-define(MACRO1(X, Y), {a, X, b, Y}).
...
bar(X) ->
?MACRO1(a, b),
?MACRO1(X, 123)</code>
- <p>This will be expanded to:</p>
+ <p>This is expanded to:</p>
<code type="none">
bar(X) ->
{a,a,b,b},
@@ -154,7 +164,7 @@ bar(X) ->
-define(F0(), c).
-define(F1(A), A).
-define(C, m:f).</code>
- <p>the following will not work:</p>
+ <p>the following does not work:</p>
<code type="none">
f0() ->
?F0. % No, an empty list of arguments expected.
@@ -165,7 +175,7 @@ f1(A) ->
<code>
f() ->
?C().</code>
- <p>will expand to</p>
+ <p>is expanded to</p>
<code>
f() ->
m:f().</code>
@@ -185,7 +195,7 @@ f() ->
defined.</item>
<tag><c>-else.</c></tag>
<item>Only allowed after an <c>ifdef</c> or <c>ifndef</c>
- directive. If that condition was false, the lines following
+ directive. If that condition is false, the lines following
<c>else</c> are evaluated instead.</item>
<tag><c>-endif.</c></tag>
<item>Specifies the end of an <c>ifdef</c> or <c>ifndef</c>
@@ -194,7 +204,7 @@ f() ->
<note>
<p>The macro directives cannot be used inside functions.</p>
</note>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<code type="none">
-module(m).
...
@@ -206,7 +216,7 @@ f() ->
-endif.
...</code>
- <p>When trace output is desired, <c>debug</c> should be defined
+ <p>When trace output is desired, <c>debug</c> is to be defined
when the module <c>m</c> is compiled:</p>
<pre>
% <input>erlc -Ddebug m.erl</input>
@@ -215,18 +225,18 @@ or
1> <input>c(m, {d, debug}).</input>
{ok,m}</pre>
- <p><c>?LOG(Arg)</c> will then expand to a call to <c>io:format/2</c>
+ <p><c>?LOG(Arg)</c> is then expanded to a call to <c>io:format/2</c>
and provide the user with some simple trace output.</p>
</section>
<section>
<title>Stringifying Macro Arguments</title>
<p>The construction <c>??Arg</c>, where <c>Arg</c> is a macro
- argument, will be expanded to a string containing the tokens of
+ argument, is expanded to a string containing the tokens of
the argument. This is similar to the <c>#arg</c> stringifying
construction in C.</p>
<p>The feature was added in Erlang 5.0/OTP R7.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<code type="none">
-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
@@ -236,7 +246,7 @@ or
<code type="none">
io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",myfunction(1,2)]),
io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).</code>
- <p>That is, a trace output with both the function called and
+ <p>That is, a trace output, with both the function called and
the resulting value.</p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml
index f0ec7ef165..5f2ac2a67d 100644
--- a/system/doc/reference_manual/modules.xml
+++ b/system/doc/reference_manual/modules.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -33,7 +34,8 @@
<title>Module Syntax</title>
<p>Erlang code is divided into <em>modules</em>. A module consists
of a sequence of attributes and function declarations, each
- terminated by period (.). Example:</p>
+ terminated by period (.).</p>
+ <p><em>Example:</em></p>
<pre>
-module(m). % module attribute
-export([fact/1]). % module attribute
@@ -42,50 +44,52 @@ fact(N) when N>0 -> % beginning of function declaration
N * fact(N-1); % |
fact(0) -> % |
1. % end of function declaration</pre>
- <p>See the <seealso marker="functions">Functions</seealso> chapter
- for a description of function declarations.</p>
+ <p>For a description of function declarations, see
+ <seealso marker="functions">Function Declaration Syntax</seealso>.</p>
</section>
<section>
<title>Module Attributes</title>
<p>A <em>module attribute</em> defines a certain property of a
- module. A module attribute consists of a tag and a value.</p>
+ module.</p>
+ <p>A module attribute consists of a tag and a value:</p>
<pre>
-Tag(Value).</pre>
<p><c>Tag</c> must be an atom, while <c>Value</c> must be a literal
term. As a convenience in user-defined attributes, if the literal term
<c>Value</c> has the syntax <c>Name/Arity</c>
(where <c>Name</c> is an atom and <c>Arity</c> a positive integer),
- the term <c>Name/Arity</c> will be translated to <c>{Name,Arity}</c>.</p>
+ the term <c>Name/Arity</c> is translated to <c>{Name,Arity}</c>.</p>
<p>Any module attribute can be specified. The attributes are stored
in the compiled code and can be retrieved by calling
- <c>Module:module_info(attributes)</c> or by using
- <seealso marker="stdlib:beam_lib#chunks/2">beam_lib(3)</seealso>.</p>
+ <c>Module:module_info(attributes)</c>, or by using the module
+ <seealso marker="stdlib:beam_lib#chunks/2">beam_lib(3)</seealso>
+ in STDLIB.</p>
- <p>There are several module attributes with predefined meanings,
- some of which have arity two, but user-defined module
+ <p>Several module attributes have predefined meanings.
+ Some of them have arity two, but user-defined module
attributes must have arity one.</p>
<section>
<title>Pre-Defined Module Attributes</title>
- <p>Pre-defined module attributes should be placed before any
+ <p>Pre-defined module attributes is to be placed before any
function declaration.</p>
<taglist>
<tag><c>-module(Module).</c></tag>
<item>
<p>Module declaration, defining the name of the module.
- The name <c>Module</c>, an atom, should be the same as
- the file name minus the extension <c>erl</c>. Otherwise
- <seealso marker="code_loading#loading">code loading</seealso> will
+ The name <c>Module</c>, an atom, is to be same as
+ the file name minus the extension <c>.erl</c>. Otherwise
+ <seealso marker="code_loading#loading">code loading</seealso> does
not work as intended.</p>
- <p>This attribute should be specified first and is the only
- attribute which is mandatory.</p>
+ <p>This attribute is to be specified first and is the only
+ mandatory attribute.</p>
</item>
<tag><c>-export(Functions).</c></tag>
<item>
- <p>Exported functions. Specifies which of the functions
- defined within the module that are visible outside
+ <p>Exported functions. Specifies which of the functions,
+ defined within the module, that are visible from outside
the module.</p>
<p><c>Functions</c> is a list
<c>[Name1/Arity1, ..., NameN/ArityN]</c>, where each
@@ -93,32 +97,37 @@ fact(0) -> % |
</item>
<tag><c>-import(Module,Functions).</c></tag>
<item>
- <p>Imported functions. Imported functions can be called
- the same way as local functions, that is without any module
+ <p>Imported functions. Can be called
+ the same way as local functions, that is, without any module
prefix.</p>
<p><c>Module</c>, an atom, specifies which module to import
functions from. <c>Functions</c> is a list similar as for
- <c>export</c> above.</p>
+ <c>export</c>.</p>
</item>
<tag><c>-compile(Options).</c></tag>
<item>
- <p>Compiler options. <c>Options</c>, which is a single option
- or a list of options, will be added to the option list when
- compiling the module. See <c>compile(3)</c>.</p>
+ <p>Compiler options. <c>Options</c> is a single option
+ or a list of options.
+ This attribute is added to the option list when
+ compiling the module. See the <seealso marker="compiler:compile">
+ compile(3)</seealso> manual page in Compiler.</p>
</item>
<tag><c>-vsn(Vsn).</c></tag>
<item>
<p>Module version. <c>Vsn</c> is any literal term and can be
- retrieved using <c>beam_lib:version/1</c>, see
- <seealso marker="stdlib:beam_lib#version/1">beam_lib(3)</seealso>.</p>
+ retrieved using <c>beam_lib:version/1</c>, see the
+ <seealso marker="stdlib:beam_lib#version/1">beam_lib(3)</seealso>
+ manual page in STDLIB.</p>
<p>If this attribute is not specified, the version defaults
to the MD5 checksum of the module.</p>
</item>
<tag><c>-on_load(Function).</c></tag>
<item>
- <p>Names a function that should be run automatically when a
- module a loaded. See <seealso marker="code_loading#on_load">
- code loading</seealso> for more information.</p>
+ <p>This attribute names a function that is to be run
+ automatically when a
+ module is loaded. For more information, see
+ <seealso marker="code_loading#on_load">
+ Running a Function When a Module is Loaded</seealso>.</p>
</item>
</taglist>
</section>
@@ -130,9 +139,14 @@ fact(0) -> % |
<pre>
-behaviour(Behaviour).</pre>
<p>The atom <c>Behaviour</c> gives the name of the behaviour,
- which can be a user defined behaviour or one of the OTP
- standard behaviours <c>gen_server</c>, <c>gen_fsm</c>,
- <c>gen_event</c> or <c>supervisor</c>.</p>
+ which can be a user-defined behaviour or one of the following OTP
+ standard behaviours:</p>
+ <list type="bulleted">
+ <item><c>gen_server</c></item>
+ <item><c>gen_fsm</c></item>
+ <item><c>gen_event</c></item>
+ <item><c>supervisor</c></item>
+ </list>
<p>The spelling <c>behavior</c> is also accepted.</p>
<p>The callback functions of the module can be specified either
directly by the exported function <c>behaviour_info/1</c>:</p>
@@ -142,7 +156,7 @@ behaviour_info(callbacks) -> Callbacks.</pre>
function:</p>
<pre>
-callback Name(Arguments) -> Result.</pre>
- <p>where <c>Arguments</c> is a list of zero or more arguments.
+ <p>Here, <c>Arguments</c> is a list of zero or more arguments.
The <c>-callback</c> attribute is to be preferred since the
extra type information can be used by tools to produce
documentation or find discrepancies.</p>
@@ -153,7 +167,7 @@ behaviour_info(callbacks) -> Callbacks.</pre>
<section>
<title>Record Definitions</title>
- <p>The same syntax as for module attributes is used by
+ <p>The same syntax as for module attributes is used
for record definitions:</p>
<pre>
-record(Record,Fields).</pre>
@@ -163,7 +177,7 @@ behaviour_info(callbacks) -> Callbacks.</pre>
</section>
<section>
- <title>The Preprocessor</title>
+ <title>Preprocessor</title>
<p>The same syntax as for module attributes is used by
the preprocessor, which supports file inclusion, macros,
and conditional compilation:</p>
@@ -171,7 +185,7 @@ behaviour_info(callbacks) -> Callbacks.</pre>
-include("SomeFile.hrl").
-define(Macro,Replacement).</pre>
- <p>Read more in <seealso marker="macros">The Preprocessor</seealso>.</p>
+ <p>Read more in <seealso marker="macros">Preprocessor</seealso>.</p>
</section>
<section>
@@ -180,110 +194,125 @@ behaviour_info(callbacks) -> Callbacks.</pre>
changing the pre-defined macros <c>?FILE</c> and <c>?LINE</c>:</p>
<pre>
-file(File, Line).</pre>
- <p>This attribute is used by tools such as Yecc to inform the
- compiler that the source program was generated by another tool
- and indicates the correspondence of source files to lines of
- the original user-written file from which the source program
- was produced.</p>
+ <p>This attribute is used by tools, such as Yecc, to inform the
+ compiler that the source program is generated by another tool.
+ It also indicates the correspondence of source files to lines of
+ the original user-written file, from which the source program
+ is produced.</p>
</section>
<section>
<title>Types and function specifications</title>
<p>A similar syntax as for module attributes is used for
- specifying types and function specifications.
+ specifying types and function specifications:
</p>
<pre>
-type my_type() :: atom() | integer().
--spec my_function(integer()) -> integer().
- </pre>
+-spec my_function(integer()) -> integer().</pre>
<p>Read more in <seealso marker="typespec">Types and Function specifications</seealso>.
</p>
<p>
The description is based on
<url href="http://www.erlang.org/eeps/eep-0008.html">EEP8 -
- Types and function specifications</url>
- which will not be further updated.
+ Types and function specifications</url>,
+ which is not to be further updated.
</p>
</section>
</section>
<section>
<title>Comments</title>
- <p>Comments may be placed anywhere in a module except within strings
- and quoted atoms. The comment begins with the character "%",
+ <p>Comments can be placed anywhere in a module except within strings
+ and quoted atoms. A comment begins with the character "%",
continues up to, but does not include the next end-of-line, and
- has no effect. Note that the terminating end-of-line has
+ has no effect. Notice that the terminating end-of-line has
the effect of white space.</p>
</section>
<section>
- <title>The module_info/0 and module_info/1 functions</title>
+ <title>module_info/0 and module_info/1 functions</title>
<p>The compiler automatically inserts the two special, exported
- functions into each module: <c>Module:module_info/0</c> and
- <c>Module:module_info/1</c>. These functions can be called to
- retrieve information about the module.</p>
+ functions into each module:</p>
+ <list type="bulleted">
+ <item><c>Module:module_info/0</c></item>
+ <item><c>Module:module_info/1</c></item>
+ </list>
+ <p>These functions can be called to retrieve information
+ about the module.</p>
<section>
<title>module_info/0</title>
- <p>The <c>module_info/0</c> function in each module returns
+ <p>The <c>module_info/0</c> function in each module, returns
a list of <c>{Key,Value}</c> tuples with information about
the module. Currently, the list contain tuples with the following
- <c>Key</c>s: <c>attributes</c>, <c>compile</c>,
- <c>exports</c>, and <c>imports</c>. The order and number of tuples
+ <c>Key</c>s: <c>module</c>, <c>attributes</c>, <c>compile</c>,
+ <c>exports</c>, <c>md5</c> and <c>native</c>.
+ The order and number of tuples
may change without prior notice.</p>
-
- <warning><p>The <c>{imports,Value}</c> tuple may be removed in a future
- release because <c>Value</c> is always an empty list.
- Do not write code that depends on it being present.</p></warning>
</section>
<section>
<title>module_info/1</title>
- <p>The call <c>module_info(Key)</c>, where key is an atom,
+ <p>The call <c>module_info(Key)</c>, where <c>Key</c> is an atom,
returns a single piece of information about the module.</p>
<p>The following values are allowed for <c>Key</c>:</p>
<taglist>
+ <tag><c>module</c></tag>
+ <item>
+ <p>Returns an atom representing the module name.</p>
+ </item>
+
<tag><c>attributes</c></tag>
<item>
- <p>Return a list of <c>{AttributeName,ValueList}</c> tuples,
+ <p>Returns a list of <c>{AttributeName,ValueList}</c> tuples,
where <c>AttributeName</c> is the name of an attribute,
- and <c>ValueList</c> is a list of values. Note: a given
- attribute may occur more than once in the list with different
+ and <c>ValueList</c> is a list of values. Notice that a given
+ attribute can occur more than once in the list with different
values if the attribute occurs more than once in the module.</p>
- <p>The list of attributes will be empty if
- the module has been stripped with
- <seealso marker="stdlib:beam_lib#strip/1">beam_lib(3)</seealso>.</p>
+ <p>The list of attributes becomes empty if
+ the module is stripped with the
+ <seealso marker="stdlib:beam_lib#strip/1">beam_lib(3)</seealso>
+ module (in STDLIB).</p>
</item>
<tag><c>compile</c></tag>
<item>
- <p>Return a list of tuples containing information about
- how the module was compiled. This list will be empty if
- the module has been stripped with
- <seealso marker="stdlib:beam_lib#strip/1">beam_lib(3)</seealso>.</p>
+ <p>Returns a list of tuples with information about
+ how the module was compiled. This list is empty if
+ the module has been stripped with the
+ <seealso marker="stdlib:beam_lib#strip/1">beam_lib(3)</seealso>
+ module (in STDLIB).</p>
</item>
- <tag><c>imports</c></tag>
+ <tag><c>md5</c></tag>
<item>
- <p>Always return an empty list. The <c>imports</c> key may not
- be supported in future release.</p>
+ <p>Returns a binary representing the MD5 checksum of the module.
+ If the module has native code loaded, this will be the MD5 of the
+ native code, not the BEAM bytecode.</p>
</item>
<tag><c>exports</c></tag>
<item>
- <p>Return a list of <c>{Name,Arity}</c> tuples with
+ <p>Returns a list of <c>{Name,Arity}</c> tuples with
all exported functions in the module.</p>
</item>
<tag><c>functions</c></tag>
<item>
- <p>Return a list of <c>{Name,Arity}</c> tuples with
+ <p>Returns a list of <c>{Name,Arity}</c> tuples with
all functions in the module.</p>
</item>
+
+ <tag><c>native</c></tag>
+ <item>
+ <p>Return <c>true</c> if the module has native compiled code.
+ Return <c>false</c> otherwise. In a system compiled without HiPE
+ support, the result is always <c>false</c></p>
+ </item>
</taglist>
</section>
</section>
diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml
index ee8f3dd7eb..58483b099a 100644
--- a/system/doc/reference_manual/part.xml
+++ b/system/doc/reference_manual/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/system/doc/reference_manual/patterns.xml b/system/doc/reference_manual/patterns.xml
index 1611002fa1..043d282de7 100644
--- a/system/doc/reference_manual/patterns.xml
+++ b/system/doc/reference_manual/patterns.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -40,7 +41,7 @@
<seealso marker="expressions#term">term</seealso>. If
the matching succeeds, any unbound variables in the pattern
become bound. If the matching fails, a run-time error occurs.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>X.</input>
** 1: variable 'X' is unbound **
diff --git a/system/doc/reference_manual/ports.xml b/system/doc/reference_manual/ports.xml
index 621af10624..e96eb428e2 100644
--- a/system/doc/reference_manual/ports.xml
+++ b/system/doc/reference_manual/ports.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,9 +29,12 @@
<rev></rev>
<file>ports.xml</file>
</header>
- <p>Examples of how to use ports and port drivers can be found in
- <em>Interoperability Tutorial</em>. The BIFs mentioned are as usual
- documented in <c>erlang(3)</c>.</p>
+ <p>Examples of how to use ports and port drivers are provided in
+ <seealso marker="doc/tutorial:introduction#interoperability tutorial">
+ Interoperability Tutorial</seealso>.
+ For information about the BIFs mentioned, see the
+ <seealso marker="erts:erlang">erlang(3)</seealso> manual
+ page in ERTS.</p>
<section>
<title>Ports</title>
@@ -39,29 +43,34 @@
provide a byte-oriented interface to an external program. When a
port has been created, Erlang can communicate with it by sending
and receiving lists of bytes, including binaries.</p>
- <p>The Erlang process which creates a port is said to be
+ <p>The Erlang process creating a port is said to be
the <em>port owner</em>, or the <em>connected process</em> of
- the port. All communication to and from the port should go via
- the port owner. If the port owner terminates, so will the port
+ the port. All communication to and from the port must go through
+ the port owner. If the port owner terminates, so does the port
(and the external program, if it is written correctly).</p>
<p>The external program resides in another OS process. By default,
- it should read from standard input (file descriptor 0) and write
+ it reads from standard input (file descriptor 0) and writes
to standard output (file descriptor 1). The external program
- should terminate when the port is closed.</p>
+ is to terminate when the port is closed.</p>
</section>
<section>
<title>Port Drivers</title>
- <p>It is also possible to write a driver in C according to certain
+ <p>It is possible to write a driver in C according to certain
principles and dynamically link it to the Erlang runtime system.
The linked-in driver looks like a port from the Erlang
programmer's point of view and is called a <em>port driver</em>.</p>
<warning>
- <p>An erroneous port driver will cause the entire Erlang runtime
+ <p>An erroneous port driver causes the entire Erlang runtime
system to leak memory, hang or crash.</p>
</warning>
- <p>Port drivers are documented in <c>erl_driver(4)</c>,
- <c>driver_entry(1)</c> and <c>erl_ddll(3)</c>.</p>
+ <p>For information about port drivers, see the
+ <seealso marker="erts:erl_driver">erl_driver(4)</seealso>
+ manual page in ERTS,
+ <seealso marker="erts:driver_entry">driver_entry(1)</seealso>
+ manual page in ERTS, and
+ <seealso marker="kernel:erl_ddll">erl_ddll(3)</seealso>
+ manual page in Kernel.</p>
</section>
<section>
@@ -70,53 +79,74 @@
<table>
<row>
<cell align="left" valign="middle"><c>open_port(PortName, PortSettings</c></cell>
- <cell align="left" valign="middle">Returns a port identifier <c>Port</c>as the result of opening a new Erlang port. Messages can be sent to and received from a port identifier, just like a pid. Port identifiers can also be linked to or registered under a name using <c>link/1</c>and <c>register/2</c>.</cell>
+ <cell align="left" valign="middle">Returns a port identifier
+ <c>Port</c> as the result of opening a new Erlang port.
+ Messages can be sent to, and received from, a port identifier,
+ just like a pid. Port identifiers can also be linked to
+ using <c>link/1</c>, or registered under a name using
+ <c>register/2</c>.</cell>
</row>
- <tcaption>Port Creation BIF.</tcaption>
+ <tcaption>Port Creation BIF</tcaption>
</table>
<p><c>PortName</c> is usually a tuple <c>{spawn,Command}</c>, where
the string <c>Command</c> is the name of the external program.
- The external program runs outside the Erlang workspace unless a
- port driver with the name <c>Command</c> is found. If found, that
- driver is started.</p>
+ The external program runs outside the Erlang workspace, unless a
+ port driver with the name <c>Command</c> is found. If <c>Command</c>
+ is found, that driver is started.</p>
<p><c>PortSettings</c> is a list of settings (options) for the port.
- The list typically contains at least a tuple <c>{packet,N}</c>
+ The list typically contains at least a tuple <c>{packet,N}</c>,
which specifies that data sent between the port and the external
program are preceded by an N-byte length indicator. Valid values
- for N are 1, 2 or 4. If binaries should be used instead of lists
+ for N are 1, 2, or 4. If binaries are to be used instead of lists
of bytes, the option <c>binary</c> must be included.</p>
<p>The port owner <c>Pid</c> can communicate with the port
<c>Port</c> by sending and receiving messages. (In fact, any
process can send the messages to the port, but the port owner must
be identified in the message).</p>
- <p>As of OTP-R16 messages sent to ports are delivered truly
+ <p>As of Erlang/OTP R16, messages sent to ports are delivered truly
asynchronously. The underlying implementation previously
delivered messages to ports synchronously. Message passing has
- however always been documented as an asynchronous operation, so
- this should not be an issue for an Erlang program communicating
- with ports, unless false assumptions about ports has been made.</p>
- <p>Below, <c>Data</c> must be an I/O list. An I/O list is a binary
- or a (possibly deep) list of binaries or integers in the range
- 0..255.</p>
+ however always been documented as an asynchronous operation. Hence,
+ this is not to be an issue for an Erlang program communicating
+ with ports, unless false assumptions about ports have been made.</p>
+ <p>In the following tables of examples, <c>Data</c> must be an I/O list.
+ An I/O list is a binary or a (possibly deep) list of binaries
+ or integers in the range 0..255:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>Message</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>{Pid,{command,Data}}</c></cell>
- <cell align="left" valign="middle">Sends <c>Data</c>to the port.</cell>
+ <cell align="left" valign="middle">Sends <c>Data</c> to the port.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>{Pid,close}</c></cell>
- <cell align="left" valign="middle">Closes the port. Unless the port is already closed, the port replies with <c>{Port,closed}</c>when all buffers have been flushed and the port really closes.</cell>
+ <cell align="left" valign="middle">Closes the port. Unless the
+ port is already closed, the port replies with
+ <c>{Port,closed}</c> when all buffers have been flushed
+ and the port really closes.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>{Pid,{connect,NewPid}}</c></cell>
- <cell align="left" valign="middle">Sets the port owner of <c>Port</c>to <c>NewPid</c>. Unless the port is already closed, the port replies with<c>{Port,connected}</c>to the old port owner. Note that the old port owner is still linked to the port, but the new port owner is not.</cell>
+ <cell align="left" valign="middle">Sets the port owner of
+ <c>Port</c>to <c>NewPid</c>. Unless the port is already closed,
+ the port replies with<c>{Port,connected}</c> to the old
+ port owner. Note that the old port owner is still linked
+ to the port, but the new port owner is not.</cell>
</row>
- <tcaption>Messages Sent To a Port.</tcaption>
+ <tcaption>Messages Sent To a Port</tcaption>
</table>
+ <p></p>
<table>
<row>
+ <cell align="left" valign="middle"><em>Message</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>{Port,{data,Data}}</c></cell>
- <cell align="left" valign="middle"><c>Data</c>is received from the external program.</cell>
+ <cell align="left" valign="middle"><c>Data</c> is received from the external program.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>{Port,closed}</c></cell>
@@ -124,20 +154,24 @@
</row>
<row>
<cell align="left" valign="middle"><c>{Port,connected}</c></cell>
- <cell align="left" valign="middle">Reply to <c>Port ! {Pid,{connect,NewPid}}</c></cell>
+ <cell align="left" valign="middle">Reply to <c>Port ! {Pid,{connect,NewPid}}</c>.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>{'EXIT',Port,Reason}</c></cell>
<cell align="left" valign="middle">If the port has terminated for some reason.</cell>
</row>
- <tcaption>Messages Received From a Port.</tcaption>
+ <tcaption>Messages Received From a Port</tcaption>
</table>
<p>Instead of sending and receiving messages, there are also a
- number of BIFs that can be used.</p>
+ number of BIFs that can be used:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>Port BIF</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>port_command(Port,Data)</c></cell>
- <cell align="left" valign="middle">Sends <c>Data</c>to the port.</cell>
+ <cell align="left" valign="middle">Sends <c>Data</c> to the port.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>port_close(Port)</c></cell>
@@ -145,7 +179,10 @@
</row>
<row>
<cell align="left" valign="middle"><c>port_connect(Port,NewPid)</c></cell>
- <cell align="left" valign="middle">Sets the port owner of <c>Port</c>to <c>NewPid</c>. The old port owner <c>Pid</c>stays linked to the port and have to call <c>unlink(Port)</c>if this is not desired.</cell>
+ <cell align="left" valign="middle">Sets the port owner of
+ <c>Port</c>to <c>NewPid</c>. The old port owner <c>Pid</c>
+ stays linked to the port and must call <c>unlink(Port)</c>
+ if this is not desired.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>erlang:port_info(Port,Item)</c></cell>
@@ -155,9 +192,9 @@
<cell align="left" valign="middle"><c>erlang:ports()</c></cell>
<cell align="left" valign="middle">Returns a list of all ports on the current node.</cell>
</row>
- <tcaption>Port BIFs.</tcaption>
+ <tcaption>Port BIFs</tcaption>
</table>
- <p>There are some additional BIFs that only apply to port drivers:
+ <p>Some additional BIFs that apply to port drivers:
<c>port_control/3</c> and <c>erlang:port_call/3</c>.</p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/processes.xml b/system/doc/reference_manual/processes.xml
index 95ae0672ec..f656d0318e 100644
--- a/system/doc/reference_manual/processes.xml
+++ b/system/doc/reference_manual/processes.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,8 +33,8 @@
<section>
<title>Processes</title>
<p>Erlang is designed for massive concurrency. Erlang processes are
- light-weight (grow and shrink dynamically) with small memory
- footprint, fast to create and terminate and the scheduling
+ lightweight (grow and shrink dynamically) with small memory
+ footprint, fast to create and terminate, and the scheduling
overhead is low.</p>
</section>
@@ -46,10 +47,10 @@ spawn(Module, Name, Args) -> pid()
Args = [Arg1,...,ArgN]
ArgI = term()</pre>
<p><c>spawn</c> creates a new process and returns the pid.</p>
- <p>The new process will start executing in
- <c>Module:Name(Arg1,...,ArgN)</c> where the arguments is
+ <p>The new process starts executing in
+ <c>Module:Name(Arg1,...,ArgN)</c> where the arguments are
the elements of the (possible empty) <c>Args</c> argument list.</p>
- <p>There exist a number of other <c>spawn</c> BIFs, for example
+ <p>There exist a number of other <c>spawn</c> BIFs, for example,
<c>spawn/4</c> for spawning a process at another node.</p>
</section>
@@ -60,18 +61,25 @@ spawn(Module, Name, Args) -> pid()
atom and is automatically unregistered if the process terminates:</p>
<table>
<row>
+ <cell align="left" valign="middle"><em>BIF</em></cell>
+ <cell align="left" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>register(Name, Pid)</c></cell>
<cell align="left" valign="middle">Associates the name <c>Name</c>, an atom, with the process <c>Pid</c>.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>registered()</c></cell>
- <cell align="left" valign="middle">Returns a list of names which have been registered using<c>register/2</c>.</cell>
+ <cell align="left" valign="middle">Returns a list of names that
+ have been registered using <c>register/2</c>.</cell>
</row>
<row>
<cell align="left" valign="middle"><c>whereis(Name)</c></cell>
- <cell align="left" valign="middle">Returns the pid registered under <c>Name</c>, or<c>undefined</c>if the name is not registered.</cell>
+ <cell align="left" valign="middle">Returns the pid registered
+ under <c>Name</c>, or <c>undefined </c>if the name is not
+ registered.</cell>
</row>
- <tcaption>Name Registration BIFs.</tcaption>
+ <tcaption>Name Registration BIFs</tcaption>
</table>
</section>
@@ -79,22 +87,25 @@ spawn(Module, Name, Args) -> pid()
<marker id="term"></marker>
<title>Process Termination</title>
<p>When a process terminates, it always terminates with an
- <em>exit reason</em>. The reason may be any term.</p>
+ <em>exit reason</em>. The reason can be any term.</p>
<p>A process is said to terminate <em>normally</em>, if the exit
reason is the atom <c>normal</c>. A process with no more code to
execute terminates normally.</p>
- <p>A process terminates with exit reason <c>{Reason,Stack}</c>
+ <p>A process terminates with an exit reason <c>{Reason,Stack}</c>
when a run-time error occurs. See
- <seealso marker="errors#exit_reasons">Error and Error Handling</seealso>.</p>
- <p>A process can terminate itself by calling one of the BIFs
- <c>exit(Reason)</c>,
- <c>erlang:error(Reason)</c>, <c>erlang:error(Reason, Args)</c>,
- <c>erlang:fault(Reason)</c> or <c>erlang:fault(Reason, Args)</c>.
- The process then terminates with reason <c>Reason</c> for
- <c>exit/1</c> or <c>{Reason,Stack} for the others</c>.</p>
- <p>A process may also be terminated if it receives an exit signal
+ <seealso marker="errors#exit_reasons">Exit Reasons</seealso>.</p>
+ <p>A process can terminate itself by calling one of the
+ following BIFs:</p>
+ <list type="bulleted">
+ <item><c>exit(Reason)</c></item>
+ <item><c>erlang:error(Reason)</c></item>
+ <item><c>erlang:error(Reason, Args)</c></item>
+ </list>
+ <p>The process then terminates with reason <c>Reason</c> for
+ <c>exit/1</c> or <c>{Reason,Stack}</c> for the others.</p>
+ <p>A process can also be terminated if it receives an exit signal
with another exit reason than <c>normal</c>, see
- <seealso marker="#errors">Error Handling</seealso> below.</p>
+ <seealso marker="#errors">Error Handling</seealso>.</p>
</section>
<section>
@@ -113,35 +124,39 @@ spawn(Module, Name, Args) -> pid()
<title>Links</title>
<p>Two processes can be <em>linked</em> to each other. A link
between two processes <c>Pid1</c> and <c>Pid2</c> is created
- by <c>Pid1</c> calling the BIF <c>link(Pid2)</c> (or vice versa).
+ by <c>Pid1</c> calling the BIF <c>link(Pid2)</c> (or conversely).
There also exist a number of <c>spawn_link</c> BIFs, which spawn
and link to a process in one operation.</p>
<p>Links are bidirectional and there can only be one link between
two processes. Repeated calls to <c>link(Pid)</c> have no effect.</p>
<p>A link can be removed by calling the BIF <c>unlink(Pid)</c>.</p>
<p>Links are used to monitor the behaviour of other processes, see
- <seealso marker="#errors">Error Handling</seealso> below.</p>
+ <seealso marker="#errors">Error Handling</seealso>.</p>
</section>
<section>
<marker id="errors"></marker>
<title>Error Handling</title>
<p>Erlang has a built-in feature for error handling between
- processes. Terminating processes will emit exit signals to all
- linked processes, which may terminate as well or handle the exit
+ processes. Terminating processes emit exit signals to all
+ linked processes, which can terminate as well or handle the exit
in some way. This feature can be used to build hierarchical
program structures where some processes are supervising other
- processes, for example restarting them if they terminate
+ processes, for example, restarting them if they terminate
abnormally.</p>
- <p>Refer to OTP Design Principles for more information about
- OTP supervision trees, which uses this feature.</p>
+ <p>See <seealso marker=
+ "doc/design_principles:des_princ#otp design principles">
+ OTP Design Principles</seealso> for more information about
+ OTP supervision trees, which use this feature.</p>
<section>
<title>Emitting Exit Signals</title>
- <p>When a process terminates, it will terminate with an <em>exit reason</em> as explained in <seealso marker="#term">Process Termination</seealso> above. This exit reason is emitted in
+ <p>When a process terminates, it terminates with an
+ <em>exit reason</em> as explained in <seealso marker="#term">
+ Process Termination</seealso>. This exit reason is emitted in
an <em>exit signal</em> to all linked processes.</p>
<p>A process can also call the function <c>exit(Pid,Reason)</c>.
- This will result in an exit signal with exit reason
+ This results in an exit signal with exit reason
<c>Reason</c> being emitted to <c>Pid</c>, but does not affect
the calling process.</p>
</section>
@@ -156,14 +171,14 @@ spawn(Module, Name, Args) -> pid()
<p>A process can be set to trap exit signals by calling:</p>
<pre>
process_flag(trap_exit, true)</pre>
- <p>When a process is trapping exits, it will not terminate when
+ <p>When a process is trapping exits, it does not terminate when
an exit signal is received. Instead, the signal is transformed
- into a message <c>{'EXIT',FromPid,Reason}</c> which is put into
- the mailbox of the process just like a regular message.</p>
+ into a message <c>{'EXIT',FromPid,Reason}</c>, which is put into
+ the mailbox of the process, just like a regular message.</p>
<p>An exception to the above is if the exit reason is <c>kill</c>,
- that is if <c>exit(Pid,kill)</c> has been called. This will
- unconditionally terminate the process, regardless of if it is
- trapping exit signals or not.</p>
+ that is if <c>exit(Pid,kill)</c> has been called. This
+ unconditionally terminates the process, regardless of if it is
+ trapping exit signals.</p>
</section>
</section>
@@ -180,12 +195,12 @@ process_flag(trap_exit, true)</pre>
<p>If <c>Pid2</c> does not exist, the 'DOWN' message is sent
immediately with <c>Reason</c> set to <c>noproc</c>.</p>
<p>Monitors are unidirectional. Repeated calls to
- <c>erlang:monitor(process, Pid)</c> will create several,
- independent monitors and each one will send a 'DOWN' message when
+ <c>erlang:monitor(process, Pid)</c> creates several
+ independent monitors, and each one sends a 'DOWN' message when
<c>Pid</c> terminates.</p>
<p>A monitor can be removed by calling
<c>erlang:demonitor(Ref)</c>.</p>
- <p>It is possible to create monitors for processes with registered
+ <p>Monitors can be created for processes with registered
names, also at other nodes.</p>
</section>
diff --git a/system/doc/reference_manual/records.xml b/system/doc/reference_manual/records.xml
index 04766531df..12a3e697cd 100644
--- a/system/doc/reference_manual/records.xml
+++ b/system/doc/reference_manual/records.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -32,16 +33,19 @@
elements. It has named fields and is similar to a struct in C.
Record expressions are translated to tuple expressions during
compilation. Therefore, record expressions are not understood by
- the shell unless special actions are taken. See <c>shell(3)</c>
- for details.</p>
- <p>More record examples can be found in <em>Programming Examples</em>.</p>
+ the shell unless special actions are taken. For details, see the
+ <seealso marker="stdlib:shell">shell(3)</seealso>
+ manual page in STDLIB.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:records">
+ Programming Examples</seealso>.</p>
<section>
<title>Defining Records</title>
<p>A record definition consists of the name of the record,
followed by the field names of the record. Record and field names
must be atoms. Each field can be given an optional default value.
- If no default value is supplied, <c>undefined</c> will be used.</p>
+ If no default value is supplied, <c>undefined</c> is used.</p>
<pre>
-record(Name, {Field1 [= Value1],
...
@@ -60,17 +64,18 @@
the corresponding expression <c>ExprI</c>:</p>
<pre>
#Name{Field1=Expr1,...,FieldK=ExprK}</pre>
- <p>The fields may be in any order, not necessarily the same order as
+ <p>The fields can be in any order, not necessarily the same order as
in the record definition, and fields can be omitted. Omitted
- fields will get their respective default value instead.</p>
- <p>If several fields should be assigned the same value,
+ fields get their respective default value instead.</p>
+ <p>If several fields are to be assigned the same value,
the following construction can be used:</p>
<pre>
#Name{Field1=Expr1,...,FieldK=ExprK, _=ExprL}</pre>
- <p>Omitted fields will then get the value of evaluating <c>ExprL</c>
+ <p>Omitted fields then get the value of evaluating <c>ExprL</c>
instead of their default values. This feature was added in
Erlang 5.1/OTP R8 and is primarily intended to be used to create
- patterns for ETS and Mnesia match functions. Example:</p>
+ patterns for ETS and Mnesia match functions.</p>
+ <p><em>Example:</em></p>
<pre>
-record(person, {name, phone, address}).
@@ -84,13 +89,13 @@ lookup(Name, Tab) ->
<title>Accessing Record Fields</title>
<pre>
Expr#Name.Field</pre>
- <p>Returns the value of the specified field. <c>Expr</c> should
+ <p>Returns the value of the specified field. <c>Expr</c> is to
evaluate to a <c>Name</c> record.</p>
<p>The following expression returns the position of the specified
field in the tuple representation of the record:</p>
<pre>
#Name.Field</pre>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
-record(person, {name, phone, address}).
@@ -104,8 +109,8 @@ lookup(Name, List) ->
<title>Updating Records</title>
<pre>
Expr#Name{Field1=Expr1,...,FieldK=ExprK}</pre>
- <p><c>Expr</c> should evaluate to a <c>Name</c> record. Returns a
- copy of this record, with the value of each specified field
+ <p><c>Expr</c> is to evaluate to a <c>Name</c> record. A
+ copy of this record is returned, with the value of each specified field
<c>FieldI</c> changed to the value of evaluating the corresponding
expression <c>ExprI</c>. All other fields retain their old
values.</p>
@@ -116,17 +121,17 @@ Expr#Name{Field1=Expr1,...,FieldK=ExprK}</pre>
<title>Records in Guards</title>
<p>Since record expressions are expanded to tuple expressions,
creating records and accessing record fields are allowed in
- guards. However all subexpressions, for example for field
- initiations, must of course be valid guard expressions as well.
- Examples:</p>
+ guards. However all subexpressions, for example, for field
+ initiations, must be valid guard expressions as well.</p>
+ <p><em>Examples:</em></p>
<code type="none">
handle(Msg, State) when Msg==#msg{to=void, no=3} ->
...
handle(Msg, State) when State#state.running==true ->
...</code>
- <p>There is also a type test BIF <c>is_record(Term, RecordTag)</c>.
- Example:</p>
+ <p>There is also a type test BIF <c>is_record(Term, RecordTag)</c>.</p>
+ <p><em>Example:</em></p>
<pre>
is_person(P) when is_record(P, person) ->
true;
@@ -136,18 +141,18 @@ is_person(_P) ->
<section>
<title>Records in Patterns</title>
- <p>A pattern that will match a certain record is created the same
+ <p>A pattern that matches a certain record is created in the same
way as a record is created:</p>
<pre>
#Name{Field1=Expr1,...,FieldK=ExprK}</pre>
- <p>In this case, one or more of <c>Expr1</c>...<c>ExprK</c> may be
+ <p>In this case, one or more of <c>Expr1</c>...<c>ExprK</c> can be
unbound variables.</p>
</section>
<section>
- <title>Nested records</title>
- <p>Beginning with R14 parentheses when accessing or updating nested
- records can be omitted. Assuming we have the following record
+ <title>Nested Records</title>
+ <p>Beginning with Erlang/OTP R14, parentheses when accessing or updating nested
+ records can be omitted. Assume the following record
definitions:</p>
<pre>
-record(nrec0, {name = "nested0"}).
@@ -156,12 +161,12 @@ is_person(_P) ->
N2 = #nrec2{},
</pre>
- <p>Before R14 you would have needed to use parentheses as following:</p>
+ <p>Before R14, parentheses were needed as follows:</p>
<pre>
"nested0" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name,
N0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = "nested0a"},
</pre>
- <p>Since R14 you can also write:</p>
+ <p>Since R14, the following can also be written:</p>
<pre>
"nested0" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name,
N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},</pre>
@@ -170,23 +175,23 @@ N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},</pre>
<section>
<title>Internal Representation of Records</title>
<p>Record expressions are translated to tuple expressions during
- compilation. A record defined as</p>
+ compilation. A record defined as:</p>
<pre>
-record(Name, {Field1,...,FieldN}).</pre>
- <p>is internally represented by the tuple</p>
+ <p>is internally represented by the tuple:</p>
<pre>
{Name,Value1,...,ValueN}</pre>
- <p>where each <c>ValueI</c> is the default value for <c>FieldI</c>.</p>
+ <p>Here each <c>ValueI</c> is the default value for <c>FieldI</c>.</p>
<p>To each module using records, a pseudo function is added
during compilation to obtain information about records:</p>
<pre>
record_info(fields, Record) -> [Field]
record_info(size, Record) -> Size</pre>
- <p><c>Size</c> is the size of the tuple representation, that is
+ <p><c>Size</c> is the size of the tuple representation, that is,
one more than the number of fields.</p>
<p>In addition, <c>#Record.Name</c> returns the index in the tuple
- representation of <c>Name</c> of the record <c>Record</c>.
- <c>Name</c> must be an atom.</p>
+ representation of <c>Name</c> of the record <c>Record</c>.</p>
+ <p><c>Name</c> must be an atom.</p>
</section>
</chapter>
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
index e4aa2ceda6..22627058c1 100644
--- a/system/doc/reference_manual/typespec.xml
+++ b/system/doc/reference_manual/typespec.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -34,43 +35,46 @@
<p>
Erlang is a dynamically typed language. Still, it comes with a
notation for declaring sets of Erlang terms to form a particular
- type, effectively forming a specific sub-type of the set of all
+ type. This effectively forms specific subtypes of the set of all
Erlang terms.
</p>
<p>
Subsequently, these types can be used to specify types of record fields
- and the argument and return types of functions.
- </p>
- <p>
- Type information can be used to document function interfaces,
- provide more information for bug detection tools such as <c>Dialyzer</c>,
- and can be exploited by documentation tools such as <c>Edoc</c> for
- generating program documentation of various forms.
- It is expected that the type language described in this document will
- supersede and replace the purely comment-based <c>@type</c> and
- <c>@spec</c> declarations used by <c>Edoc</c>.
- </p>
+ and also the argument and return types of functions.
+ </p>
+ <p>
+ Type information can be used for the following:</p>
+ <list type="bulleted">
+ <item>To document function interfaces</item>
+ <item>To provide more information for bug detection tools,
+ such as <c>Dialyzer</c></item>
+ <item>To be exploited by documentation tools, such as EDoc, for
+ generating program documentation of various forms</item>
+ </list>
+ <p>It is expected that the type language described in this section
+ supersedes and replaces the purely comment-based <c>@type</c> and
+ <c>@spec</c> declarations used by EDoc.</p>
</section>
<section>
<marker id="syntax"></marker>
<title>Types and their Syntax</title>
<p>
Types describe sets of Erlang terms.
- Types consist and are built from a set of predefined types
- (e.g. <c>integer()</c>, <c>atom()</c>, <c>pid()</c>, ...)
- described below.
- Predefined types represent a typically infinite set of Erlang terms which
+ Types consist of, and are built from, a set of predefined types,
+ for example, <c>integer()</c>, <c>atom()</c>, and <c>pid()</c>.
+ Predefined types represent a typically infinite set of Erlang terms that
belong to this type. For example, the type <c>atom()</c> stands for the
set of all Erlang atoms.
</p>
<p>
- For integers and atoms, we allow for singleton types (e.g. the integers
- <c>-1</c> and <c>42</c> or the atoms <c>'foo'</c> and <c>'bar'</c>).
+ For integers and atoms, it is allowed for singleton types; for example,
+ the integers
+ <c>-1</c> and <c>42</c>, or the atoms <c>'foo'</c> and <c>'bar'</c>).
All other types are built using unions of either predefined
types or singleton types. In a type union between a type and one
- of its sub-types the sub-type is absorbed by the super-type and
- the union is subsequently treated as if the sub-type was not a
+ of its subtypes, the subtype is absorbed by the supertype. Thus,
+ the union is then treated as if the subtype was not a
constituent of the union. For example, the type union:
</p>
<pre> atom() | 'bar' | integer() | 42</pre>
@@ -79,13 +83,13 @@
</p>
<pre> atom() | integer()</pre>
<p>
- Because of sub-type relations that exist between types, types
- form a lattice where the topmost element, <c>any()</c>, denotes
+ Because of subtype relations that exist between types, types
+ form a lattice where the top-most element, <c>any()</c>, denotes
the set of all Erlang terms and the bottom-most element, <c>none()</c>,
denotes the empty set of terms.
</p>
<p>
- The set of predefined types and the syntax for types is given below:
+ The set of predefined types and the syntax for types follows:
</p>
<pre><![CDATA[
Type :: any() %% The top type, the set of all Erlang terms
@@ -103,7 +107,7 @@
| Map
| Tuple
| Union
- | UserDefined %% described in Section 7.3
+ | UserDefined %% described in Type Declarations of User-Defined Types
Atom :: atom()
| Erlang_Atom %% 'foo', 'bar', ...
@@ -146,22 +150,22 @@
<p>
The general form of bitstrings is <c>&lt;&lt;_:M, _:_*N&gt;&gt;</c>,
where <c>M</c> and <c>N</c> are positive integers. It denotes a
- bitstring that is <c>M + (k*N)</c> bits long (i.e., a bitstring that
+ bitstring that is <c>M + (k*N)</c> bits long (that is, a bitstring that
starts with <c>M</c> bits and continues with <c>k</c> segments of
<c>N</c> bits each, where <c>k</c> is also a positive integer).
The notations <c>&lt;&lt;_:_*N&gt;&gt;</c>, <c>&lt;&lt;_:M&gt;&gt;</c>,
and <c>&lt;&lt;&gt;&gt;</c> are convenient shorthands for the cases
- that <c>M</c>, <c>N</c>, or both, respectively, are zero.
+ that <c>M</c> or <c>N</c>, or both, are zero.
</p>
<p>
Because lists are commonly used, they have shorthand type notations.
The types <c>list(T)</c> and <c>nonempty_list(T)</c> have the shorthands
<c>[T]</c> and <c>[T,...]</c>, respectively.
- The only difference between the two shorthands is that <c>[T]</c> may be an
- empty list but <c>[T,...]</c> may not.
+ The only difference between the two shorthands is that <c>[T]</c> can be an
+ empty list but <c>[T,...]</c> cannot.
</p>
<p>
- Notice that the shorthand for <c>list()</c>, i.e. the list of
+ Notice that the shorthand for <c>list()</c>, that is, the list of
elements of unknown type, is <c>[_]</c> (or <c>[any()]</c>), not <c>[]</c>.
The notation <c>[]</c> specifies the singleton type for the empty list.
</p>
@@ -172,7 +176,7 @@
</p>
<table>
<row>
- <cell><b>Built-in type</b></cell><cell><b>Defined as</b></cell>
+ <cell><em>Built-in type</em></cell><cell><em>Defined as</em></cell>
</row>
<row>
<cell><c>term()</c></cell><cell><c>any()</c></cell>
@@ -193,6 +197,9 @@
<cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell>
</row>
<row>
+ <cell><c>nil()</c></cell><cell><c>[]</c></cell>
+ </row>
+ <row>
<cell><c>number()</c></cell><cell><c>integer() | float()</c></cell>
</row>
<row>
@@ -223,12 +230,15 @@
<cell><c>module()</c></cell><cell><c>atom()</c></cell>
</row>
<row>
- <cell><c>mfa()</c></cell><cell><c>{atom(),atom(),arity()}</c></cell>
+ <cell><c>mfa()</c></cell><cell><c>{module(),atom(),arity()}</c></cell>
</row>
<row>
<cell><c>arity()</c></cell><cell><c>0..255</c></cell>
</row>
<row>
+ <cell><c>identifier()</c></cell><cell><c>pid() | port() | reference()</c></cell>
+ </row>
+ <row>
<cell><c>node()</c></cell><cell><c>atom()</c></cell>
</row>
<row>
@@ -237,6 +247,7 @@
<row>
<cell><c>no_return()</c></cell><cell><c>none()</c></cell>
</row>
+ <tcaption>Built-in types, predefined aliases</tcaption>
</table>
<p>
In addition, the following three built-in types exist and can be
@@ -245,7 +256,8 @@
</p>
<table>
<row>
- <cell><b>Built-in type</b></cell><cell><b>Could be thought defined by the syntax</b></cell>
+ <cell><em>Built-in type</em></cell><cell><em>
+ Can be thought defined by the syntax</em></cell>
</row>
<row>
<cell><c>non_neg_integer()</c></cell><cell><c>0..</c></cell>
@@ -256,6 +268,7 @@
<row>
<cell><c>neg_integer()</c></cell><cell><c>..-1</c></cell>
</row>
+ <tcaption>Additional built-in types</tcaption>
</table>
<p>
@@ -264,8 +277,10 @@
its violation results in a compilation error.
</p>
<note>
- The following built-in list types also exist,
- but they are expected to be rarely used. Hence, they have long names:
+ <p>
+ The following built-in list types also exist,
+ but they are expected to be rarely used. Hence, they have long names:
+ </p>
</note>
<pre>
nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any())
@@ -276,109 +291,118 @@
define the set of Erlang terms one would expect.
</p>
<p>
- Also for convenience, we allow for record notation to be used.
- Records are just shorthands for the corresponding tuples.
+ Also for convenience, record notation is allowed to be used.
+ Records are shorthands for the corresponding tuples:
</p>
<pre>
Record :: #Erlang_Atom{}
| #Erlang_Atom{Fields}</pre>
<p>
- Records have been extended to possibly contain type information.
- This is described in the sub-section <seealso marker="#typeinrecords">"Type information in record declarations"</seealso> below.
+ Records are extended to possibly contain type information.
+ This is described in <seealso marker="#typeinrecords">
+ Type Information in Record Declarations</seealso>.
</p>
<note>
- <p>Map types, both <c>map()</c> and <c>#{ ... }</c>, are considered experimental during OTP 17.</p>
- <p>No type information of maps pairs, only the containing map types, are used by Dialyzer in OTP 17.</p>
+ <p>Map types, both <c>map()</c> and <c>#{...}</c>,
+ are considered experimental during OTP 17.</p>
+ <p>No type information of maps pairs, only the containing map types,
+ are used by Dialyzer in OTP 17.</p>
</note>
</section>
-
+
<section>
- <title>Type declarations of user-defined types</title>
+ <title>Type Declarations of User-Defined Types</title>
<p>
As seen, the basic syntax of a type is an atom followed by closed
- parentheses. New types are declared using '-type' and '-opaque'
- compiler attributes as in the following:
+ parentheses. New types are declared using <c>-type</c> and <c>-opaque</c>
+ attributes as in the following:
</p>
<pre>
-type my_struct_type() :: Type.
-opaque my_opaq_type() :: Type.</pre>
<p>
- where the type name is an atom (<c>'my_struct_type'</c> in the above)
- followed by parentheses. Type is a type as defined in the
+ The type name is the atom <c>my_struct_type</c>,
+ followed by parentheses. <c>Type</c> is a type as defined in the
previous section.
- A current restriction is that Type can contain only predefined types,
- or user-defined types which are either module-local (i.e., with a
- definition that is present in the code of the module) or are remote
- types (i.e., types defined in and exported by other modules; see below).
- For module-local types, the restriction that their definition
+ A current restriction is that <c>Type</c> can contain
+ only predefined types,
+ or user-defined types which are either of the following:
+ </p>
+ <list type="bulleted">
+ <item>Module-local type, that is, with a
+ definition that is present in the code of the module</item>
+ <item>Remote type, that is, type defined in, and exported by,
+ other modules; more about this soon.</item>
+ </list>
+ <p>For module-local types, the restriction that their definition
exists in the module is enforced by the compiler and results in a
- compilation error. (A similar restriction currently exists for records.)
- </p>
+ compilation error. (A similar restriction currently exists for records.) </p>
<p>
Type declarations can also be parameterized by including type variables
between the parentheses. The syntax of type variables is the same as
- Erlang variables (starts with an upper case letter).
- Naturally, these variables can - and should - appear on the RHS of the
- definition. A concrete example appears below:
+ Erlang variables, that is, starts with an upper-case letter.
+ Naturally, these variables can - and is to - appear on the RHS of the
+ definition. A concrete example follows:
</p>
<pre>
-type orddict(Key, Val) :: [{Key, Val}].</pre>
<p>
- A module can export some types in order to declare that other modules
+ A module can export some types to declare that other modules
are allowed to refer to them as <em>remote types</em>.
- This declaration has the following form:
+ This declaration has the following form:</p>
<pre>
-export_type([T1/A1, ..., Tk/Ak]).</pre>
- where the Ti's are atoms (the name of the type) and the Ai's are their
- arguments. An example is given below:
+ <p>Here the Ti's are atoms (the name of the type) and the Ai's are their
+ arguments</p>
+ <p><em>Example:</em></p>
<pre>
-export_type([my_struct_type/0, orddict/2]).</pre>
- Assuming that these types are exported from module <c>'mod'</c> then
- one can refer to them from other modules using remote type expressions
- like those below:
+ <p>Assuming that these types are exported from module <c>'mod'</c>,
+ you can refer to them from other modules using remote type expressions
+ like the following:</p>
<pre>
mod:my_struct_type()
mod:orddict(atom(), term())</pre>
- One is not allowed to refer to types which are not declared as exported.
+ <p>It is not allowed to refer to types that are not declared as exported.
</p>
<p>
Types declared as <c>opaque</c> represent sets of terms whose
- structure is not supposed to be visible in any way outside of
- their defining module (i.e., only the module defining them is
- allowed to depend on their term structure). Consequently, such
+ structure is not supposed to be visible from outside of
+ their defining module. That is, only the module defining them
+ is allowed to depend on their term structure. Consequently, such
types do not make much sense as module local - module local
- types are not accessible by other modules anyway - and should
- always be exported.
+ types are not accessible by other modules anyway - and is
+ always to be exported.
</p>
</section>
-
- <marker id="typeinrecords"/>
+
<section>
- <title>Type information in record declarations</title>
+ <marker id="typeinrecords"/>
+ <title>Type Information in Record Declarations</title>
<p>
- The types of record fields can be specified in the declaration of the
- record. The syntax for this is:
+ The types of record fields can be specified in the declaration of the
+ record. The syntax for this is as follows:
</p>
<pre>
-record(rec, {field1 :: Type1, field2, field3 :: Type3}).</pre>
<p>
For fields without type annotations, their type defaults to any().
- I.e., the above is a shorthand for:
+ That is, the previous example is a shorthand for the following:
</p>
<pre>
-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).</pre>
<p>
In the presence of initial values for fields,
- the type must be declared after the initialization as in the following:
+ the type must be declared after the initialization, as follows:
</p>
<pre>
-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).</pre>
<p>
- Naturally, the initial values for fields should be compatible
- with (i.e. a member of) the corresponding types.
- This is checked by the compiler and results in a compilation error
- if a violation is detected. For fields without initial values,
- the singleton type <c>'undefined'</c> is added to all declared types.
+ The initial values for fields are to be compatible
+ with (that is, a member of) the corresponding types.
+ This is checked by the compiler and results in a compilation error
+ if a violation is detected. For fields without initial values,
+ the singleton type <c>'undefined'</c> is added to all declared types.
In other words, the following two record declarations have identical
effects:
</p>
@@ -396,13 +420,13 @@
</p>
<p>
Any record, containing type information or not, once defined,
- can be used as a type using the syntax:
+ can be used as a type using the following syntax:
</p>
<pre> #rec{}</pre>
<p>
In addition, the record fields can be further specified when using
- a record type by adding type information about the field in
- the following manner:
+ a record type by adding type information about the field
+ as follows:
</p>
<pre> #rec{some_field :: Type}</pre>
<p>
@@ -412,16 +436,16 @@
</section>
<section>
- <title>Specifications for functions</title>
+ <title>Specifications for Functions</title>
<p>
- A specification (or contract) for a function is given using the new
- compiler attribute <c>'-spec'</c>. The general format is as follows:
+ A specification (or contract) for a function is given using the
+ <c>-spec</c> attribute. The general format is as follows:
</p>
<pre>
-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.</pre>
<p>
- The arity of the function has to match the number of arguments,
- or else a compilation error occurs.
+ The arity of the function must match the number of arguments,
+ else a compilation error occurs.
</p>
<p>
This form can also be used in header files (.hrl) to declare type
@@ -430,7 +454,7 @@
explicitly) import these functions.
</p>
<p>
- For most uses within a given module, the following shorthand suffices:
+ Within a given module, the following shorthand suffices in most cases:
</p>
<pre>
-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.</pre>
@@ -448,8 +472,8 @@
; (T4, T5) -> T6.</pre>
<p>
A current restriction, which currently results in a warning
- (OBS: not an error) by the compiler, is that the domains of
- the argument types cannot be overlapping.
+ (not an error) by the compiler, is that the domains of
+ the argument types cannot overlap.
For example, the following specification results in a warning:
</p>
<pre>
@@ -464,62 +488,67 @@
<pre>
-spec id(X) -> X.</pre>
<p>
- However, note that the above specification does not restrict the input
- and output type in any way.
- We can constrain these types by guard-like subtype constraints
+ Notice that the above specification does not restrict the input
+ and output type in any way.
+ These types can be constrained by guard-like subtype constraints
and provide bounded quantification:
</p>
<pre> -spec id(X) -> X when X :: tuple().</pre>
<p>
Currently, the <c>::</c> constraint (read as <c>is_subtype</c>) is
- the only guard constraint which can be used in the <c>'when'</c>
+ the only guard constraint that can be used in the <c>'when'</c>
part of a <c>'-spec'</c> attribute.
</p>
<note>
<p>
- The above function specification, using multiple occurrences of
- the same type variable, provides more type information than the
- function specification below where the type variables are missing:
+ The above function specification uses multiple occurrences of
+ the same type variable. That provides more type information than the
+ following function specification, where the type variables are missing:
</p>
<pre> -spec id(tuple()) -> tuple().</pre>
<p>
The latter specification says that the function takes some tuple
- and returns some tuple, while the one with the <c>X</c> type
+ and returns some tuple. The specification with the <c>X</c> type
variable specifies that the function takes a tuple and returns
<em>the same</em> tuple.
</p>
<p>
- However, it's up to the tools that process the specs to choose
- whether to take this extra information into account or ignore it.
+ However, it is up to the tools that process the specificationss
+ to choose whether to take this extra information into account
+ or not.
</p>
</note>
<p>
- The scope of an <c>::</c> constraint is the
- <c>(...) -> RetType</c>
- specification after which it appears. To avoid confusion,
- we suggest that different variables are used in different
- constituents of an overloaded contract as in the example below:
+ The scope of a <c>::</c> constraint is the
+ <c>(...) -> RetType</c>
+ specification after which it appears. To avoid confusion,
+ it is suggested that different variables are used in different
+ constituents of an overloaded contract, as shown in the
+ following example:
</p>
<pre>
-spec foo({X, integer()}) -> X when X :: atom()
; ([Y]) -> Y when Y :: number().</pre>
<note>
+ <p>
For backwards compatibility the following form is also allowed:
+ </p>
<pre> -spec id(X) -> X when is_subtype(X, tuple()).</pre>
<p>
- but its use is discouraged. It will be taken out in a future
+ but its use is discouraged. It will be removed in a future
Erlang/OTP release.
</p>
</note>
<p>
Some functions in Erlang are not meant to return;
either because they define servers or because they are used to
- throw exceptions as the function below:
+ throw exceptions, as in the following function:
</p>
<pre> my_error(Err) -> erlang:throw({error, Err}).</pre>
<p>
- For such functions we recommend the use of the special <c>no_return()</c>
- type for their "return", via a contract of the form:
+ For such functions, it is recommended to use the special
+ <c>no_return()</c> type for their "return", through a contract
+ of the following form:
</p>
<pre> -spec my_error(term()) -> no_return().</pre>
</section>
diff --git a/system/doc/reference_manual/xmlfiles.mk b/system/doc/reference_manual/xmlfiles.mk
index 6886c8c7cf..323b94c0de 100644
--- a/system/doc/reference_manual/xmlfiles.mk
+++ b/system/doc/reference_manual/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/system_architecture_intro/Makefile b/system/doc/system_architecture_intro/Makefile
index f11b078963..5e41ab7b85 100644
--- a/system/doc/system_architecture_intro/Makefile
+++ b/system/doc/system_architecture_intro/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/system_architecture_intro/book.xml b/system/doc/system_architecture_intro/book.xml
index f010ec53fc..318f940a18 100644
--- a/system/doc/system_architecture_intro/book.xml
+++ b/system/doc/system_architecture_intro/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/system_architecture_intro/part.xml b/system/doc/system_architecture_intro/part.xml
index e5eec36cbb..eb0f9e0ba6 100644
--- a/system/doc/system_architecture_intro/part.xml
+++ b/system/doc/system_architecture_intro/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/system_architecture_intro/sys_arch_intro.xml b/system/doc/system_architecture_intro/sys_arch_intro.xml
index 3e88548861..b9535f66f8 100644
--- a/system/doc/system_architecture_intro/sys_arch_intro.xml
+++ b/system/doc/system_architecture_intro/sys_arch_intro.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/system_architecture_intro/xmlfiles.mk b/system/doc/system_architecture_intro/xmlfiles.mk
index 0b91c3bc0f..6e7e712703 100644
--- a/system/doc/system_architecture_intro/xmlfiles.mk
+++ b/system/doc/system_architecture_intro/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/system_principles/Makefile b/system/doc/system_principles/Makefile
index d558f92d46..93f0147aa4 100644
--- a/system/doc/system_principles/Makefile
+++ b/system/doc/system_principles/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1996-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/system_principles/book.xml b/system/doc/system_principles/book.xml
index 3692752bbe..11eacba578 100644
--- a/system/doc/system_principles/book.xml
+++ b/system/doc/system_principles/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc
index a8ee2d1245..ccc26081c3 100644
--- a/system/doc/system_principles/create_target.xmlsrc
+++ b/system/doc/system_principles/create_target.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,55 +32,54 @@
<rev>A</rev>
<file>create_target.xml</file>
</header>
+ <marker id="creating upgrading target system"></marker>
- <section>
- <title>Introduction</title>
- <p>When creating a system using Erlang/OTP, the most simple way is
- to install Erlang/OTP somewhere, install the application specific
+ <p>When creating a system using Erlang/OTP, the simplest way is
+ to install Erlang/OTP somewhere, install the application-specific
code somewhere else, and then start the Erlang runtime system,
- making sure the code path includes the application specific code.</p>
- <p>Often it is not desirable to use an Erlang/OTP system as is. A
- developer may create new Erlang/OTP compliant applications for a
+ making sure the code path includes the application-specific code.</p>
+ <p>It is often not desirable to use an Erlang/OTP system as is. A
+ developer can create new Erlang/OTP-compliant applications for a
particular purpose, and several original Erlang/OTP applications
- may be irrelevant for the purpose in question. Thus, there is a
+ can be irrelevant for the purpose in question. Thus, there is a
need to be able to create a new system based on a given
- Erlang/OTP system, where dispensable applications are removed,
- and a set of new applications are included. Documentation and
+ Erlang/OTP system, where dispensable applications are removed
+ and new applications are included. Documentation and
source code is irrelevant and is therefore not included in the
new system.</p>
- <p>This chapter is about creating such a system, which we call a
+ <p>This chapter is about creating such a system, which is called a
<em>target system</em>.</p>
- <p>In the following sections we consider creating target systems with
- different requirements of functionality:</p>
+ <p>The following sections deal with target systems
+ with different requirements of functionality:</p>
<list type="bulleted">
- <item>a <em>basic target system</em> that can be started by
- calling the ordinary <c>erl</c> script, </item>
- <item>a <em>simple target system</em> where also code
- replacement in run-time can be performed, and</item>
- <item>an <em>embedded target system</em> where there is also
+ <item>A <em>basic target system</em> that can be started by
+ calling the ordinary <c>erl</c> script.</item>
+ <item>A <em>simple target system</em> where also code
+ replacement in runtime can be performed.</item>
+ <item>An <em>embedded target system</em> where there is also
support for logging output from the system to file for later
inspection, and where the system can be started automatically
- at boot time. </item>
+ at boot time.</item>
</list>
- <p>We only consider the case when Erlang/OTP is running on a UNIX
- system.</p>
- <p>In the <c>sasl</c> application there is an example Erlang
- module <c>target_system.erl</c> that contains functions for
- creating and installing a target system. This module is used in
- the examples below, and the source code of the module is listed
- at the end of this chapter.</p>
- </section>
+ <p>Here is only considered the case when Erlang/OTP is running on a
+ UNIX system.</p>
+ <p>The <c>sasl</c> application includes the example Erlang
+ module <c>target_system.erl</c>, which contains functions for
+ creating and installing a target system. This module is used in
+ the following examples. The source code of the module is listed
+ in <seealso marker="#listing of target system">
+ Listing of target_system.erl</seealso></p>
<section>
<marker id="create"/>
<title>Creating a Target System</title>
<p>It is assumed that you have a working Erlang/OTP system structured
- according to the OTP Design Principles.</p>
- <p><em>Step 1.</em> First create a <c>.rel</c> file (see <seealso
- marker="sasl:rel">rel(4)</seealso>) that specifies the <c>erts</c>
- version and lists all applications that should be included in the
- new basic target system. An example is the following
- <c>mysystem.rel</c> file:</p>
+ according to the OTP design principles.</p>
+ <p><em>Step 1.</em> Create a <c>.rel</c> file (see the
+ <seealso marker="sasl:rel">rel(4)</seealso> manual page in
+ SASL), which specifies the ERTS version and lists
+ all applications that are to be included in the new basic target
+ system. An example is the following <c>mysystem.rel</c> file:</p>
<code type="none">
%% mysystem.rel
{release,
@@ -91,23 +91,23 @@
{pea, "1.0"}]}.</code>
<p>The listed applications are not only original Erlang/OTP
applications but possibly also new applications that you have
- written yourself (here exemplified by the application
- <c>pea</c>). </p>
- <p><em>Step 2.</em> From the directory where the <c>mysystem.rel</c>
- file reside, start the Erlang/OTP system:</p>
+ written (here exemplified by the application Pea (<c>pea</c>)).</p>
+ <p><em>Step 2.</em> Start Erlang/OTP from the directory where
+ the <c>mysystem.rel</c> file resides:</p>
<pre>
os> <input>erl -pa /home/user/target_system/myapps/pea-1.0/ebin</input></pre>
- <p>where also the path to the <c>pea-1.0</c> ebin directory is
- provided. </p>
- <p><em>Step 3.</em> Now create the target system: </p>
+ <p>Here also the path to the <c>pea-1.0</c> ebin directory is
+ provided.</p>
+ <p><em>Step 3.</em> Create the target system:</p>
<pre>
1> <input>target_system:create("mysystem").</input></pre>
- <p>The <c>target_system:create/1</c> function does the following:</p>
+ <p>The function <c>target_system:create/1</c> performs the
+ following:</p>
<list type="ordered">
- <item>Reads the <c>mysystem.rel</c> file, and creates a new file
- <c>plain.rel</c> which is identical to former, except that it
- only lists the <c>kernel</c> and <c>stdlib</c> applications. </item>
- <item>From the <c>mysystem.rel</c> and <c>plain.rel</c> files
+ <item>Reads the file <c>mysystem.rel</c> and creates a new file
+ <c>plain.rel</c> that is identical to the former, except that it
+ only lists the Kernel and STDLIB applications.</item>
+ <item>From the files <c>mysystem.rel</c> and <c>plain.rel</c>
creates the files <c>mysystem.script</c>,
<c>mysystem.boot</c>, <c>plain.script</c>, and
<c>plain.boot</c> through a call to
@@ -124,26 +124,26 @@ releases/mysystem.rel
lib/kernel-2.16.4/
lib/stdlib-1.19.4/
lib/sasl-2.3.4/
-lib/pea-1.0/ </code>
+lib/pea-1.0/</code>
<p>The file <c>releases/FIRST/start.boot</c> is a copy of our
<c>mysystem.boot</c></p>
<p>The release resource file <c>mysystem.rel</c> is duplicated
in the tar file. Originally, this file was only stored in
- the <c>releases</c> directory in order to make it possible
+ the <c>releases</c> directory to make it possible
for the <c>release_handler</c> to extract this file
separately. After unpacking the tar
file, <c>release_handler</c> would automatically copy the
file to <c>releases/FIRST</c>. However, sometimes the tar
file is unpacked without involving
- the <c>release_handler</c> (e.g. when unpacking the first
- target system) and therefore the file is now instead
+ the <c>release_handler</c> (for example, when unpacking the
+ first target system). The file is therefore now instead
duplicated in the tar file so no manual copying is
- necessary.</p>
+ needed.</p>
</item>
- <item>Creates the temporary directory <c>tmp</c> and extracts the tar file
- <c>mysystem.tar.gz</c> into that directory. </item>
- <item>Deletes the <c>erl</c> and <c>start</c> files from
- <c>tmp/erts-5.10.4/bin</c>. These files will be created again from
+ <item>Creates the temporary directory <c>tmp</c> and extracts
+ the tar file <c>mysystem.tar.gz</c> into that directory.</item>
+ <item>Deletes the files <c>erl</c> and <c>start</c> from
+ <c>tmp/erts-5.10.4/bin</c>. These files are created again from
source when installing the release.</item>
<item>Creates the directory <c>tmp/bin</c>.</item>
<item>Copies the previously created file <c>plain.boot</c> to
@@ -151,31 +151,31 @@ lib/pea-1.0/ </code>
<item>Copies the files <c>epmd</c>, <c>run_erl</c>, and
<c>to_erl</c> from the directory <c>tmp/erts-5.10.4/bin</c> to
the directory <c>tmp/bin</c>.</item>
- <item>Creates the directory <c>tmp/log</c>, which will be used
+ <item>Creates the directory <c>tmp/log</c>, which is used
if the system is started as embedded with the <c>bin/start</c>
script.</item>
<item>Creates the file <c>tmp/releases/start_erl.data</c> with
the contents "5.10.4 FIRST". This file is to be passed as data
- file to the <c>start_erl</c> script.
- </item>
+ file to the <c>start_erl</c> script.</item>
<item>Recreates the file <c>mysystem.tar.gz</c> from the directories
- in the directory <c>tmp</c>, and removes <c>tmp</c>.</item>
+ in the directory <c>tmp</c> and removes <c>tmp</c>.</item>
</list>
</section>
<section>
<title>Installing a Target System</title>
<p><em>Step 4.</em> Install the created target system in a
- suitable directory. </p>
+ suitable directory.</p>
<pre>
2> <input>target_system:install("mysystem", "/usr/local/erl-target").</input></pre>
- <p>The function <c>target_system:install/2</c> does the following:
+ <p>The function <c>target_system:install/2</c> performs the following:
</p>
<list type="ordered">
<item>Extracts the tar file <c>mysystem.tar.gz</c> into the target
directory <c>/usr/local/erl-target</c>.</item>
- <item>In the target directory reads the file <c>releases/start_erl.data</c>
- in order to find the Erlang runtime system version ("5.10.4").</item>
+ <item>In the target directory reads the file
+ <c>releases/start_erl.data</c> to find the Erlang runtime system
+ version ("5.10.4").</item>
<item>Substitutes <c>%FINAL_ROOTDIR%</c> and <c>%EMU%</c> for
<c>/usr/local/erl-target</c> and <c>beam</c>, respectively, in
the files <c>erl.src</c>, <c>start.src</c>, and
@@ -184,97 +184,102 @@ lib/pea-1.0/ </code>
<c>start</c>, and <c>run_erl</c> in the target <c>bin</c>
directory.</item>
<item>Finally the target <c>releases/RELEASES</c> file is created
- from data in the <c>releases/mysystem.rel</c> file.</item>
+ from data in the file <c>releases/mysystem.rel</c>.</item>
</list>
</section>
<section>
<marker id="start"/>
<title>Starting a Target System</title>
- <p>Now we have a target system that can be started in various ways.</p>
- <p>We start it as a <em>basic target system</em> by invoking</p>
+ <p>Now we have a target system that can be started in various ways.
+ We start it as a <em>basic target system</em> by invoking:</p>
<pre>
os> <input>/usr/local/erl-target/bin/erl</input></pre>
- <p>where only the <c>kernel</c> and <c>stdlib</c> applications are
- started, i.e. the system is started as an ordinary development
- system. There are only two files needed for all this to work:
- <c>bin/erl</c> file (obtained from <c>erts-5.10.4/bin/erl.src</c>)
- and the <c>bin/start.boot</c> file (a copy of <c>plain.boot</c>).</p>
+ <p>Here only the Kernel and STDLIB applications are
+ started, that is, the system is started as an ordinary development
+ system. Only two files are needed for all this to work:</p>
+ <list type="ordered">
+ <item><c>bin/erl</c> (obtained from
+ <c>erts-5.10.4/bin/erl.src</c>)</item>
+ <item><c>bin/start.boot</c> (a copy of
+ <c>plain.boot</c>)</item>
+ </list>
<p>We can also start a distributed system (requires <c>bin/epmd</c>).</p>
<p>To start all applications specified in the original
- <c>mysystem.rel</c> file, use the <c>-boot</c> flag as follows:</p>
+ <c>mysystem.rel</c> file, use flag <c>-boot</c> as follows:</p>
<pre>
os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start</input></pre>
- <p>We start a <em>simple target system</em> as above. The only difference
- is that also the file <c>releases/RELEASES</c> is present for
- code replacement in run-time to work.</p>
- <p>To start an <em>embedded target system</em> the shell script
- <c>bin/start</c> is used. That shell script calls
+ <p>We start a <em>simple target system</em> as above. The only
+ difference is that also the file <c>releases/RELEASES</c> is
+ present for code replacement in runtime to work.</p>
+ <p>To start an <em>embedded target system</em>, the shell script
+ <c>bin/start</c> is used. The script calls
<c>bin/run_erl</c>, which in turn calls <c>bin/start_erl</c>
(roughly, <c>start_erl</c> is an embedded variant of
- <c>erl</c>). </p>
+ <c>erl</c>).</p>
<p>The shell script <c>start</c>, which is generated from
erts-5.10.4/bin/start.src during installation, is only an
- example. You should edit it to suite your needs. Typically it is
+ example. Edit it to suite your needs. Typically it is
executed when the UNIX system boots.</p>
<p><c>run_erl</c> is a wrapper that provides logging of output from
- the run-time system to file. It also provides a simple mechanism
+ the runtime system to file. It also provides a simple mechanism
for attaching to the Erlang shell (<c>to_erl</c>).</p>
- <p><c>start_erl</c> requires the root directory
- (<c>"/usr/local/erl-target"</c>), the releases directory
- (<c>"/usr/local/erl-target/releases"</c>), and the location of
- the <c>start_erl.data</c> file. It reads the run-time system
- version (<c>"5.10.4"</c>) and release version (<c>"FIRST"</c>) from
- the <c>start_erl.data</c> file, starts the run-time system of the
- version found, and provides <c>-boot</c> flag specifying the boot
- file of the release version found
- (<c>"releases/FIRST/start.boot"</c>).</p>
- <p><c>start_erl</c> also assumes that there is <c>sys.config</c> in
- release version directory (<c>"releases/FIRST/sys.config"</c>). That
- is the topic of the next section (see below).</p>
- <p>The <c>start_erl</c> shell script should normally not be
+ <p><c>start_erl</c> requires:</p>
+ <list type="ordered">
+ <item>The root directory (<c>"/usr/local/erl-target"</c>)</item>
+ <item>The releases directory
+ (<c>"/usr/local/erl-target/releases"</c></item>
+ <item>The location of the file <c>start_erl.data</c></item>
+ </list>
+ <p>It performs the following:</p>
+ <list type="ordered">
+ <item>Reads the runtime system version (<c>"5.10.4"</c>) and
+ release version (<c>"FIRST"</c>) from the file
+ <c>start_erl.data</c>.</item>
+ <item>Starts the runtime system of the version found.</item>
+ <item>Provides the flag <c>-boot</c> specifying the boot
+ file of the release version found
+ (<c>"releases/FIRST/start.boot"</c>).</item>
+ </list>
+ <p><c>start_erl</c> also assumes that there is <c>sys.config</c>
+ in the release version directory (<c>"releases/FIRST/sys.config"</c>).
+ That is the topic of the next section.</p>
+ <p>The <c>start_erl</c> shell script is normally not to be
altered by the user.</p>
</section>
<section>
<title>System Configuration Parameters</title>
- <p>As was pointed out above <c>start_erl</c> requires a
- <c>sys.config</c> in the release version directory
- (<c>"releases/FIRST/sys.config"</c>). If there is no such a
- file, the system start will fail. Hence such a file has to
- be added as well.</p>
- <p></p>
- <p>If you have system configuration data that are neither file
- location dependent nor site dependent, it may be convenient to
- create the <c>sys.config</c> early, so that it becomes a part of
+ <p>As was mentioned in the previous section, <c>start_erl</c>
+ requires a <c>sys.config</c> in the release version directory
+ (<c>"releases/FIRST/sys.config"</c>). If there is no such
+ file, the system start fails. Such a file must therefore
+ also be added.</p>
+ <p>If you have system configuration data that is neither
+ file-location-dependent nor site-dependent, it can be convenient
+ to create <c>sys.config</c> early, so it becomes part of
the target system tar file created by
- <c>target_system:create/1</c>. In fact, if you create, in the
- current directory, not only the <c>mysystem.rel</c> file, but
- also a <c>sys.config</c> file, that latter file will be tacitly
+ <c>target_system:create/1</c>. In fact, if you in the
+ current directory create not only the file <c>mysystem.rel</c>,
+ but also file <c>sys.config</c>, the latter file is tacitly
put in the appropriate directory.</p>
</section>
<section>
- <title>Differences from the Install Script</title>
- <p>The above <c>install/2</c> procedure differs somewhat from that
+ <title>Differences From the Install Script</title>
+ <p>The previous <c>install/2</c> procedure differs somewhat from that
of the ordinary <c>Install</c> shell script. In fact, <c>create/1</c>
makes the release package as complete as possible, and leave to the
- <c>install/2</c> procedure to finish by only considering location
- dependent files.</p>
+ <c>install/2</c> procedure to finish by only considering
+ location-dependent files.</p>
</section>
<section>
<title>Creating the Next Version</title>
-
- <p>
- In this example the <c>pea</c> application has been changed, and
- so are <c>erts</c>, <c>kernel</c>, <c>stdlib</c> and
- <c>sasl</c>.
- </p>
-
- <p>
- <em>Step 1.</em> Create the <c>.rel</c> file:
- </p>
+ <p>In this example the Pea application has been changed, and
+ so are the applications ERTS, Kernel, STDLIB
+ and SASL.</p>
+ <p><em>Step 1.</em> Create the file <c>.rel</c>:</p>
<code type="none">
%% mysystem2.rel
{release,
@@ -284,65 +289,49 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI
{stdlib, "2.0"},
{sasl, "2.4"},
{pea, "2.0"}]}.</code>
- <p>
- <em>Step 2.</em> Create the application upgrade file (see
- <seealso marker="sasl:appup">appup(4)</seealso>) for <c>pea</c>,
- for example:
- </p>
+ <p><em>Step 2.</em> Create the application upgrade file (see the
+ <seealso marker="sasl:appup">appup(4)</seealso> manual page in
+ SASL) for Pea, for example:</p>
<code type="none">
%% pea.appup
{"2.0",
[{"1.0",[{load_module,pea_lib}]}],
[{"1.0",[{load_module,pea_lib}]}]}.</code>
- <p>
- <em>Step 3.</em> From the directory where the
- <c>mysystem2.rel</c> file reside, start the Erlang/OTP system:
- </p>
+ <p><em>Step 3.</em> From the directory where the file
+ <c>mysystem2.rel</c> resides, start the Erlang/OTP system,
+ giving the path to the new version of Pea:</p>
<pre>
os> <input>erl -pa /home/user/target_system/myapps/pea-2.0/ebin</input></pre>
- <p>giving the path to the new version of <c>pea</c>. </p>
-
- <p>
- <em>Step 4.</em> Create the release upgrade file (see <seealso
- marker="sasl:relup">relup(4)</seealso>):
- </p>
+ <p><em>Step 4.</em> Create the release upgrade file (see the
+ <seealso marker="sasl:relup">relup(4)</seealso> manual page in
+ SASL):</p>
<pre>
-1> <input>systools:make_relup("mysystem2",["mysystem"],["mysystem"],[{path,["/home/user/target_system/myapps/pea-1.0/ebin","/my/old/erlang/lib/*/ebin"]}]).</input></pre>
- <p>
- where <c>"mysystem"</c> is the base release and
- <c>"mysystem2"</c> is the release to upgrade to.
- </p>
- <p>
- Note that the <c>path</c> option is used for pointing out the
+1> <input>systools:make_relup("mysystem2",["mysystem"],["mysystem"],
+ [{path,["/home/user/target_system/myapps/pea-1.0/ebin",
+ "/my/old/erlang/lib/*/ebin"]}]).</input></pre>
+ <p>Here <c>"mysystem"</c> is the base release and
+ <c>"mysystem2"</c> is the release to upgrade to.</p>
+ <p>The <c>path</c> option is used for pointing out the
old version of all applications. (The new versions are already
- in the code path - assuming of course that the erlang node on
+ in the code path - assuming of course that the Erlang node on
which this is executed is running the correct version of
- Erlang/OTP.)
- </p>
- <p>
- <em>Step 5.</em> Create the new release:
- </p>
+ Erlang/OTP.)</p>
+ <p><em>Step 5.</em> Create the new release:</p>
<pre>
2> <input>target_system:create("mysystem2").</input></pre>
- <p>
- Given that the <c>relup</c> file generated in step 4 above is
- now located in the current directory, it will automatically be
- included in the release package.
- </p>
+ <p>Given that the file <c>relup</c> generated in Step 4 is
+ now located in the current directory, it is automatically
+ included in the release package.</p>
</section>
<section>
<title>Upgrading the Target System</title>
- <p>
- This part is done on the target node, and for this example we
+ <p>This part is done on the target node, and for this example we
want the node to be running as an embedded system with the
- <c>-heart</c> option, allowing automatic restart of the
- node. See <seealso marker="#start">Starting a Target
- System</seealso> above for more information.
- </p>
- <p>
- We add <c>-heart</c> to <c>bin/start</c>:
- </p>
+ <c>-heart</c> option, allowing automatic restart of the node.
+ For more information, see <seealso marker="#start">
+ Starting a Target System</seealso>.</p>
+ <p>We add <c>-heart</c> to <c>bin/start</c>:</p>
<code type="none">
#!/bin/sh
ROOTDIR=/usr/local/erl-target/
@@ -354,36 +343,27 @@ fi
START_ERL_DATA=${1:-$RELDIR/start_erl.data}
-$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart</code>
- <p>
- And we use the simplest possible <c>sys.config</c>, which we
- store in <c>releases/FIRST</c>:
- </p>
+$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR\
+$RELDIR $START_ERL_DATA -heart</code>
+ <p>We use the simplest possible <c>sys.config</c>, which we
+ store in <c>releases/FIRST</c>:</p>
<code type="none">
%% sys.config
[].</code>
- <p>
- Finally, in order to prepare the upgrade, we need to put the new
+ <p>Finally, to prepare the upgrade, we must put the new
release package in the <c>releases</c> directory of the first
- target system:
- </p>
+ target system:</p>
<pre>
os> <input>cp mysystem2.tar.gz /usr/local/erl-target/releases</input></pre>
- <p>
- And assuming that the node has been started like this:
- </p>
+ <p>Assuming that the node has been started as follows:</p>
<pre>
os> <input>/usr/local/erl-target/bin/start</input></pre>
- <p>
- it can be accessed like this:
- </p>
+ <p>It can be accessed as follows:</p>
<pre>
os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1</input></pre>
- <p>
- Also note that logs can be found in
+ <p>Logs can be found in
<c>/usr/local/erl-target/log</c>. This directory is specified as
- an argument to <c>run_erl</c>in the start script listed above.
- </p>
+ an argument to <c>run_erl</c>in the start script listed above.</p>
<p>
<em>Step 1.</em> Unpack the release:
</p>
@@ -402,18 +382,19 @@ heart: Tue Apr 1 12:15:11 2014: Executed "/usr/local/erl-target/bin/start /usr/
The above return value and output after the call to
<c>release_handler:install_release/1</c> means that the
<c>release_handler</c> has restarted the node by using
- <c>heart</c>. This will always be done when the upgrade involves
- a change of <c>erts</c>, <c>kernel</c>, <c>stdlib</c> or
- <c>sasl</c>. See <seealso marker="upgrade">Upgrade when
- Erlang/OTP has Changed</seealso> for more infomation about this.
+ <c>heart</c>. This is always done when the upgrade involves
+ a change of the applications ERTS, Kernel,
+ STDLIB, or SASL. For more information, see
+ <seealso marker="upgrade">
+ Upgrade when Erlang/OTP has Changed</seealso>.
</p>
<p>
- The node will be accessible via a new pipe:
+ The node is accessible through a new pipe:
</p>
<pre>
os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre>
<p>
- Let's see which releases we have in our system:
+ Check which releases there are in the system:
</p>
<pre>
1> <input>release_handler:which_releases().</input>
@@ -426,7 +407,7 @@ os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre>
<p>
Our new release, "SECOND", is now the current release, but we
can also see that our "FIRST" release is still permanent. This
- means that if the node would be restarted at this point, it
+ means that if the node would be restarted now, it
would come up running the "FIRST" release again.
</p>
<p>
@@ -434,11 +415,9 @@ os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre>
</p>
<pre>
2> <input>release_handler:make_permanent("SECOND").</input></pre>
-
<p>
- Now look at the releases again:
+ Check the releases again:
</p>
-
<pre>
3> <input>release_handler:which_releases().</input>
<output>[{"MYSYSTEM","SECOND",
@@ -447,19 +426,16 @@ os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre>
{"MYSYSTEM","FIRST",
["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
old}]</output></pre>
-
<p>
- Here we see that the new release version is <c>permanent</c>, so
- it would be safe to restart the node.
- </p>
-
+ We see that the new release version is <c>permanent</c>, so
+ it would be safe to restart the node.</p>
</section>
<section>
+ <marker id="listing of target system"/>
<title>Listing of target_system.erl</title>
<p>This module can also be found in the <c>examples</c> directory
- of the <c>sasl</c> application.</p>
+ of the SASL application.</p>
<codeinclude file="../../../lib/sasl/examples/src/target_system.erl" tag="%module" type="erl"></codeinclude>
-
</section>
</chapter>
diff --git a/system/doc/system_principles/error_logging.xml b/system/doc/system_principles/error_logging.xml
index 80d5211323..024137a430 100644
--- a/system/doc/system_principles/error_logging.xml
+++ b/system/doc/system_principles/error_logging.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,41 +29,43 @@
<rev></rev>
<file>error_logging.xml</file>
</header>
+ <marker id="error logging"></marker>
<section>
<title>Error Information From the Runtime System</title>
<p>Error information from the runtime system, that is, information
- about a process terminating due to an uncaught error exception,
+ about a process terminating because of an uncaught error exception,
is by default written to terminal (tty):</p>
<code type="none"><![CDATA[
=ERROR REPORT==== 9-Dec-2003::13:25:02 ===
Error in process <0.27.0> with exit value: {{badmatch,[1,2,3]},[{m,f,1},{shell,eval_loop,2}]}]]></code>
<p>The error information is handled by the <em>error logger</em>, a
system process registered as <c>error_logger</c>. This process
- receives all error messages from the Erlang runtime system and
- also from the standard behaviours and different Erlang/OTP
+ receives all error messages from the Erlang runtime system as
+ well as from the standard behaviours and different Erlang/OTP
applications.</p>
- <p>The exit reasons (such as <c>badarg</c> above) used by
+ <p>The exit reasons (such as <c>badarg</c>) used by
the runtime system are described in
- <seealso marker="doc/reference_manual:errors#exit_reasons">Errors and Error Handling</seealso>
- in the Erlang Reference Manual.</p>
- <p>The process <c>error_logger</c> and its user interface (with
- the same name) are described in
- <seealso marker="kernel:error_logger">error_logger(3)</seealso>.
- It is possible to configure the system so that error information
- is written to file instead/as well as tty. Also, it is possible
- for user defined applications to send and format error
- information using <c>error_logger</c>.</p>
+ <seealso marker="doc/reference_manual:errors#exit_reasons">
+ Errors and Error Handling</seealso>.</p>
+ <p>For information about the process <c>error_logger</c> and its user
+ interface (with the same name), see the
+ <seealso marker="kernel:error_logger">error_logger(3)</seealso>
+ manual page in Kernel. The system can be configured so that
+ error information
+ is written to file or to tty, or both. In addition, user-defined
+ applications can send and format error information using
+ <c>error_logger</c>.</p>
</section>
<section>
<title>SASL Error Logging</title>
- <p>The standard behaviors (<c>supervisor</c>, <c>gen_server</c>,
- etc.) sends progress and error information to <c>error_logger</c>.
- If the SASL application is started, this information is written
- to tty as well. See
+ <p>The standard behaviours (<c>supervisor</c>, <c>gen_server</c>,
+ and so on) send progress and error information to <c>error_logger</c>.
+ If the SASL application is started, this information is
+ written to tty as well. For more information, see
<seealso marker="sasl:error_logging">SASL Error Logging</seealso>
- in the SASL User's Guide for further information.</p>
+ in the SASL User's Guide.</p>
<pre>
% <input>erl -boot start_sasl</input>
Erlang (BEAM) emulator version 5.4.13 [hipe] [threads:0] [kernel-poll]
diff --git a/system/doc/system_principles/part.xml b/system/doc/system_principles/part.xml
index d05c89fde8..1557b5ff62 100644
--- a/system/doc/system_principles/part.xml
+++ b/system/doc/system_principles/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/system_principles/system_principles.xml b/system/doc/system_principles/system_principles.xml
index 79ed86cd9f..3605df3ade 100644
--- a/system/doc/system_principles/system_principles.xml
+++ b/system/doc/system_principles/system_principles.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2014</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,35 +29,41 @@
<rev></rev>
<file>system_principles.xml</file>
</header>
+ <marker id="system principles"></marker>
<section>
<title>Starting the System</title>
- <p>An Erlang runtime system is started with the command <c>erl</c>:</p>
+ <p>An Erlang runtime system is started with command <c>erl</c>:</p>
<pre>
% <input>erl</input>
Erlang/OTP 17 [erts-6.0] [hipe] [smp:8:8]
Eshell V6.0 (abort with ^G)
1> </pre>
- <p><c>erl</c> understands a number of command line arguments, see
- <c>erl(1)</c>. A number of them are also described in this chapter.</p>
- <p>Application programs can access the values of the command line
- arguments by calling one of the functions
- <c>init:get_argument(Key)</c>, or <c>init:get_arguments()</c>.
- See <c>init(3)</c>.</p>
+ <p><c>erl</c> understands a number of command-line arguments, see
+ the <seealso marker="erts:erl">erl(1)</seealso> manual page in
+ ERTS. Some of them are also described in this chapter.</p>
+ <p>Application programs can access the values of the command-line
+ arguments by calling the function <c>init:get_argument(Key)</c>
+ or <c>init:get_arguments()</c>. See the
+ <seealso marker="erts:init">init(3)</seealso> manual page in
+ ERTS.</p>
</section>
<section>
<title>Restarting and Stopping the System</title>
- <p>The runtime system can be halted by calling <c>halt/0,1</c>.
- See <c>erlang(3)</c>.</p>
- <p>The module <c>init</c> contains function for restarting,
- rebooting and stopping the runtime system. See <c>init(3)</c>.</p>
+ <p>The runtime system is halted by calling <c>halt/0,1</c>. For
+ details, see the <seealso marker="erts:erlang">erlang(3)</seealso>
+ manual page in ERTS.</p>
+ <p>The module <c>init</c> contains functions for restarting,
+ rebooting, and stopping the runtime system:</p>
<pre>
init:restart()
init:reboot()
init:stop()</pre>
- <p>Also, the runtime system will terminate if the Erlang shell is
+ <p>For details, see the <seealso marker="erts:init">init(3)</seealso>
+ manual page in ERTS.</p>
+ <p>The runtime system terminates if the Erlang shell is
terminated.</p>
</section>
@@ -69,14 +76,15 @@ init:stop()</pre>
<p>A boot script file has the extension <c>.script</c>.
The runtime system uses a binary version of the script. This
<em>binary boot script</em> file has the extension <c>.boot</c>.</p>
- <p>Which boot script to use is specified by the command line flag
- <c>-boot</c>. The extension <c>.boot</c> should be omitted.
- Example, using the boot script <c>start_all.boot</c>:</p>
+ <p>Which boot script to use is specified by the command-line flag
+ <c>-boot</c>. The extension <c>.boot</c> is to be omitted.
+ For example, using the boot script <c>start_all.boot</c>:</p>
<pre>
% <input>erl -boot start_all</input></pre>
<p>If no boot script is specified, it defaults to
- <c>ROOT/bin/start</c>, see Default Boot Scripts below.</p>
- <p>The command line flag <c>-init_debug</c> makes the <c>init</c>
+ <c>ROOT/bin/start</c>, see <seealso marker="#default_boot_scripts">
+ Default Boot Scripts</seealso>.</p>
+ <p>The command-line flag <c>-init_debug</c> makes the <c>init</c>
process write some debug information while interpreting the boot
script:</p>
<pre>
@@ -87,59 +95,55 @@ init:stop()</pre>
{start,heart}
{start,error_logger}
...</pre>
- <p>See <c>script(4)</c> for a detailed description of the syntax
- and contents of the boot script.</p>
+ <p>For a detailed description of the syntax and contents of the
+ boot script, see the <c>script(4)</c> manual page in SASL.</p>
<section>
+ <marker id="default_boot_scripts"></marker>
<title>Default Boot Scripts</title>
- <p>Erlang/OTP comes with two boot scripts:</p>
- <taglist>
- <tag><c>start_clean.boot</c></tag>
- <item>
- <p>Loads the code for and starts the applications Kernel and
- STDLIB.</p>
- </item>
- <tag><c>start_sasl.boot</c></tag>
- <item>
- <p>Loads the code for and starts the applications Kernel,
- STDLIB and SASL.</p>
- </item>
- <tag><c>no_dot_erlang.boot</c></tag>
- <item>
- <p>Loads the code for and starts the applications Kernel and
- STDLIB, skips loading the <c>.erlang</c> file.
- Useful for scripts and other tools that should be behave the
- same regardless of user preferences.
- </p>
- </item>
- </taglist>
+ <p>Erlang/OTP comes with these boot scripts:</p>
+ <list type="bulleted">
+ <item><c>start_clean.boot</c> - Loads the code for and starts
+ the applications Kernel and STDLIB.</item>
+ <item><c>start_sasl.boot</c> - Loads the code for and starts
+ the applications Kernel, STDLIB, and
+ SASL).</item>
+ <item><c>no_dot_erlang.boot</c> - Loads the code for and
+ starts the applications Kernel and STDLIB.
+ Skips loading the file <c>.erlang</c>. Useful for scripts and
+ other tools that are to behave the same irrespective of user
+ preferences.</item>
+ </list>
<p>Which of <c>start_clean</c> and <c>start_sasl</c> to use as
default is decided by the user when installing Erlang/OTP using
<c>Install</c>. The user is asked "Do you want to use a minimal
system startup instead of the SASL startup". If the answer is
yes, then <c>start_clean</c> is used, otherwise
- <c>start_sasl</c> is used. A copy of the selected boot script
- is made, named <c>start.boot</c> and placed in
- the <c>ROOT/bin</c> directory.</p>
+ <c>start_sasl</c> is used. A copy of the selected boot script is
+ made, named <c>start.boot</c> and placed in directory
+ <c>ROOT/bin</c>.</p>
</section>
<section>
<title>User-Defined Boot Scripts</title>
<p>It is sometimes useful or necessary to create a user-defined
boot script. This is true especially when running Erlang in
- embedded mode, see <seealso marker="#code_loading">Code Loading Strategy</seealso>.</p>
- <p>It is possible to write a boot script manually.
- The recommended way to create a boot script, however, is to
- generate the boot script from a release resource file
- <c>Name.rel</c>, using the function
+ embedded mode, see <seealso marker="#code_loading">
+ Code Loading Strategy</seealso>.</p>
+ <p>A boot script can be written manually. However, it is
+ recommended to create a boot script by generating it from a
+ release resource file <c>Name.rel</c>, using the function
<c>systools:make_script/1,2</c>. This requires that the source
code is structured as applications according to the OTP design
principles. (The program does not have to be started in terms of
- OTP applications but can be plain Erlang).</p>
- <p>Read more about <c>.rel</c> files in OTP Design Principles and
- <c>rel(4)</c>.</p>
+ OTP applications, but can be plain Erlang).</p>
+ <p>For more information about <c>.rel</c> files, see
+ <seealso marker="doc/design_principles:release_handling">
+ OTP Design Principles</seealso> and the
+ <seealso marker="sasl:rel">rel(4)</seealso> manual page in
+ SASL.</p>
<p>The binary boot script file <c>Name.boot</c> is generated from
- the boot script file <c>Name.script</c> using the function
+ the boot script file <c>Name.script</c>, using the function
<c>systools:script2boot(File)</c>.</p>
</section>
</section>
@@ -148,16 +152,17 @@ init:stop()</pre>
<marker id="code_loading"></marker>
<title>Code Loading Strategy</title>
<p>The runtime system can be started in either <em>embedded</em> or
- <em>interactive</em> mode. Which one is decided by the command
- line flag <c>-mode</c>.</p>
+ <em>interactive</em> mode. Which one is decided by the
+ command-line flag <c>-mode</c>.</p>
<pre>
% <input>erl -mode embedded</input></pre>
<p>Default mode is <c>interactive</c>.</p>
+ <p>The mode properties are as follows:</p>
<list type="bulleted">
- <item>In embedded mode, all code is loaded during system start-up
+ <item>In embedded mode, all code is loaded during system startup
according to the boot script. (Code can also be loaded later
- by explicitly ordering the code server to do so).</item>
- <item>In interactive mode, code is dynamically loaded when first
+ by explicitly ordering the code server to do so.)</item>
+ <item>In interactive mode, the code is dynamically loaded when first
referenced. When a call to a function in a module is made, and
the module is not loaded, the code server searches the code path
and loads the module into the system.</item>
@@ -165,21 +170,21 @@ init:stop()</pre>
<p>Initially, the code path consists of the current
working directory and all object code directories under
<c>ROOT/lib</c>, where <c>ROOT</c> is the installation directory
- of Erlang/OTP. Directories can be named <c>Name[-Vsn]</c> and
- the code server, by default, chooses the directory with
+ of Erlang/OTP. Directories can be named <c>Name[-Vsn]</c>. The
+ code server, by default, chooses the directory with
the highest version number among those which have the same
<c>Name</c>. The <c>-Vsn</c> suffix is optional. If an
<c>ebin</c> directory exists under the <c>Name[-Vsn]</c>
- directory, it is this directory which is added to the code path.</p>
- <p>The code path can be extended by using the command line flags
- <c>-pa Directories</c> and <c>-pz Directories</c>. These will add
- <c>Directories</c> to the head or end of the code path,
- respectively. Example</p>
+ directory, this directory is added to the code path.</p>
+ <p>The code path can be extended by using the command-line flags
+ <c>-pa Directories</c> and <c>-pz Directories</c>. These add
+ <c>Directories</c> to the head or the end of the code path,
+ respectively. Example:</p>
<pre>
% <input>erl -pa /home/arne/mycode</input></pre>
<p>The code server module <c>code</c> contains a number of
- functions for modifying and checking the search path, see
- <c>code(3)</c>.</p>
+ functions for modifying and checking the search path, see the
+ <c>code(3)</c> manual page in Kernel.</p>
</section>
<section>
@@ -192,49 +197,65 @@ init:stop()</pre>
<cell align="left" valign="middle"><em>Documented in</em></cell>
</row>
<row>
- <cell align="left" valign="middle">module</cell>
+ <cell align="left" valign="middle">Module</cell>
<cell align="left" valign="middle"><c>.erl</c></cell>
- <cell align="left" valign="middle">Erlang Reference Manual</cell>
+ <cell align="left" valign="middle">
+ <seealso marker="doc/reference_manual:modules">
+ Erlang Reference Manual</seealso></cell>
</row>
<row>
- <cell align="left" valign="middle">include file</cell>
+ <cell align="left" valign="middle">Include file</cell>
<cell align="left" valign="middle"><c>.hrl</c></cell>
- <cell align="left" valign="middle">Erlang Reference Manual</cell>
+ <cell align="left" valign="middle">
+ <seealso marker="doc/reference_manual:modules">
+ Erlang Reference Manual</seealso></cell>
</row>
<row>
- <cell align="left" valign="middle">release resource file</cell>
+ <cell align="left" valign="middle">Release resource file</cell>
<cell align="left" valign="middle"><c>.rel</c></cell>
- <cell align="left" valign="middle"><c>rel(4)</c></cell>
+ <cell align="left" valign="middle">
+ <seealso marker="sasl:rel">rel(4)</seealso>
+ manual page in SASL</cell>
</row>
<row>
- <cell align="left" valign="middle">application resource file</cell>
+ <cell align="left" valign="middle">Application resource file</cell>
<cell align="left" valign="middle"><c>.app</c></cell>
- <cell align="left" valign="middle"><c>app(4)</c></cell>
+ <cell align="left" valign="middle">
+ <seealso marker="kernel:app">app(4)</seealso>
+ manual page in Kernel</cell>
</row>
<row>
- <cell align="left" valign="middle">boot script</cell>
+ <cell align="left" valign="middle">Boot script</cell>
<cell align="left" valign="middle"><c>.script</c></cell>
- <cell align="left" valign="middle"><c>script(4)</c></cell>
+ <cell align="left" valign="middle">
+ <seealso marker="sasl:script">script(4)</seealso>
+ manual page in SASL</cell>
</row>
<row>
- <cell align="left" valign="middle">binary boot script</cell>
+ <cell align="left" valign="middle">Binary boot script</cell>
<cell align="left" valign="middle"><c>.boot</c></cell>
<cell align="left" valign="middle">-</cell>
</row>
<row>
- <cell align="left" valign="middle">configuration file</cell>
+ <cell align="left" valign="middle">Configuration file</cell>
<cell align="left" valign="middle"><c>.config</c></cell>
- <cell align="left" valign="middle"><c>config(4)</c></cell>
+ <cell align="left" valign="middle">
+ <seealso marker="kernel:config">config(4)</seealso>
+ manual page in Kernel</cell>
</row>
<row>
- <cell align="left" valign="middle">application upgrade file</cell>
+ <cell align="left" valign="middle">Application upgrade file</cell>
<cell align="left" valign="middle"><c>.appup</c></cell>
- <cell align="left" valign="middle"><c>appup(4)</c></cell>
+ <cell align="left" valign="middle">
+ <seealso marker="sasl:appup">appup(4)</seealso>
+ manual page in SASL</cell>
</row>
<row>
- <cell align="left" valign="middle">release upgrade file</cell>
+ <cell align="left" valign="middle">Release upgrade file</cell>
<cell align="left" valign="middle"><c>relup</c></cell>
- <cell align="left" valign="middle"><c>relup(4)</c></cell>
+ <cell align="left" valign="middle">
+ <seealso marker="sasl:relup">relup(4)</seealso>
+ manual page in SASL</cell>
</row>
<tcaption>File Types</tcaption>
</table>
diff --git a/system/doc/system_principles/upgrade.xml b/system/doc/system_principles/upgrade.xml
index 68e48da0b8..173e46185c 100644
--- a/system/doc/system_principles/upgrade.xml
+++ b/system/doc/system_principles/upgrade.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -31,88 +32,72 @@
<rev></rev>
<file>upgrade.xml</file>
</header>
+ <marker id="upgrade section"></marker>
<section>
<title>Introduction</title>
- <p>
- As of Erlang/OTP 17, most applications deliver a valid
- application upgrade (<c>appup</c>) file. In earlier releases, a
+ <marker id="upgrade"></marker>
+ <p>As of Erlang/OTP 17, most applications deliver a valid
+ application upgrade file (<c>appup</c>). In earlier releases, a
majority of the applications in Erlang/OTP did not support
- upgrade at all. Many of the applications use the
+ upgrade. Many of the applications use the
<c>restart_application</c> instruction. These are applications
for which it is not crucial to support real soft upgrade, for
- instance tools and library applications. The
+ example, tools and library applications. The
<c>restart_application</c> instruction
ensures that all modules in the application are reloaded and
- thereby running the new code.
- </p>
+ thereby running the new code.</p>
</section>
<section>
- <title>Upgrade of core applications</title>
- <p>
- The core applications ERTS, Kernel, STDLIB
+ <title>Upgrade of Core Applications</title>
+ <p>The core applications ERTS, Kernel, STDLIB,
and SASL never allow real soft upgrade, but require the
Erlang emulator to be restarted. This is indicated to the
<c>release_handler</c> by the upgrade instruction
- <c>restart_new_emulator</c>. This instruction will always be the
- very first instruction executed, and it will restart the
+ <c>restart_new_emulator</c>. This instruction is always the
+ very first instruction executed, and it restarts the
emulator with the new versions of the above mentioned core
- applications and the old versions of all other
- applications. When the node is back up all other upgrade instructions are
+ applications and the old versions of all other applications.
+ When the node is back up, all other upgrade instructions are
executed, making sure each application is finally running its
- new version.
- </p>
-
- <p>
- It might seem strange to do a two-step upgrade instead of
+ new version.</p>
+ <p>It might seem strange to do a two-step upgrade instead of
just restarting the emulator with the new version of all
applications. The reason for this design decision is to allow
- <c>code_change</c> functions to have side effects, for example changing
- data on disk. It also makes sure that the upgrade mechanism for
- non-core applications does not differ depending on whether or not
- core applications are changed at the same time.
- </p>
-
- <p>
- If, however, the more brutal variant is preferred, it is
- possible to handwrite the release upgrade file using only the
+ <c>code_change</c> functions to have side effects, for example,
+ changing data on disk. It also guarantees that the upgrade
+ mechanism for non-core applications does not differ depending
+ on whether or not core applications are changed at the same time.</p>
+ <p>If, however, the more brutal variant is preferred, the
+ the release upgrade file can be handwritten using only the
single upgrade instruction <c>restart_emulator</c>. This
- instruction, in contrast to <c>restart_new_emulator</c>, will
- cause the emulator to restart with the new versions of
- <em>all</em> applications.
- </p>
-
- <p>
- <em>Note</em> that if other instructions are included before
+ instruction, in contrast to <c>restart_new_emulator</c>,
+ causes the emulator to restart with the new versions of
+ <em>all</em> applications.</p>
+ <p><em>Note:</em> If other instructions are included before
<c>restart_emulator</c> in the handwritten <c>relup</c> file,
- they will be executed in the old emulator. This is a big risk
+ they are executed in the old emulator. This is a big risk
since there is no guarantee that new beam code can be loaded
into the old emulator. Adding instructions after
<c>restart_emulator</c> has no effect as the
- <c>release_handler</c> will not do any attempt at executing
- them.
- </p>
-
- <p>
- See <seealso marker="sasl:relup">relup(4)</seealso> for
- information about the release upgrade file, and <seealso
- marker="sasl:appup">appup(4)</seealso> for further information
- about upgrade instructions.
- </p>
+ <c>release_handler</c> will not execute them.</p>
+ <p>For information about the release upgrade file, see the
+ <seealso marker="sasl:relup">relup(4)</seealso> manual page
+ in SASL.
+ For more information about upgrade instructions, see the
+ <seealso marker="sasl:appup">appup(4)</seealso> manual page
+ in SASL.</p>
</section>
<section>
- <title>Applications that still do not allow code upgrade</title>
- <p>
- A few applications, for instance HiPE do not support
- upgrade at all. This is indicated by an application upgrade file
- containing only <c>{Vsn,[],[]}</c>. Any attempt at creating a release
- upgrade file with such input will fail.
- The only way to force an upgrade involving applications like this is to
- handwrite the <c>relup</c> file, preferably as described above
- with only the <c>restart_emulator</c> instruction.
- </p>
-
+ <title>Applications that Still do Not Allow Code Upgrade</title>
+ <p>A few applications, such as HiPE, do not support upgrade.
+ This is indicated by an application upgrade file containing only
+ <c>{Vsn,[],[]}</c>. Any attempt at creating a release upgrade file
+ with such input fails. The only way to force an upgrade involving
+ applications like this is to
+ handwrite the file <c>relup</c>, preferably as described above
+ with only the <c>restart_emulator</c> instruction.</p>
</section>
</chapter>
diff --git a/system/doc/system_principles/versions.xml b/system/doc/system_principles/versions.xml
index ed6fd1f7fe..ee104a8302 100644
--- a/system/doc/system_principles/versions.xml
+++ b/system/doc/system_principles/versions.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,94 +32,100 @@
<rev></rev>
<file>versions.xml</file>
</header>
- <section><title>OTP Version</title>
+ <marker id="versions section"></marker>
+
+ <section>
+ <title>OTP Version</title>
<p>As of OTP release 17, the OTP release number corresponds to
the major part of the OTP version. The OTP version as a concept was
- introduced in OTP 17. The <seealso marker="#version_scheme">version
- scheme</seealso> used is described in more detail below.</p>
-
+ introduced in OTP 17. The version scheme used is described in detail in
+ <seealso marker="#version_scheme">Version Scheme</seealso>.</p>
<p>OTP of a specific version is a set of applications of specific
versions. The application versions identified by an OTP version
corresponds to application versions that have been tested together
- by the Erlang/OTP team at Ericsson AB. An OTP system can however be
+ by the Erlang/OTP team at Ericsson AB. An OTP system can, however, be
put together with applications from different OTP versions. Such a
combination of application versions has not been tested by the
Erlang/OTP team. It is therefore <em>always preferred to use OTP
applications from one single OTP version</em>.</p>
-
<p>Release candidates have an <c>-rc&lt;N&gt;</c>
- suffix. The suffix <c>-rc0</c> will be used during development up to
+ suffix. The suffix <c>-rc0</c> is used during development up to
the first release candidate.</p>
- <section><title>Retrieving Current OTP Version</title>
- <p>In an OTP source code tree, the OTP version can be read from
- the text file <c>&lt;OTP source root&gt;/OTP_VERSION</c>. The
- absolute path to the file can be constructed by calling
- <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "OTP_VERSION"])</c>.</p>
- <p>In an installed OTP development system, the OTP version can be read
- from the text file <c>&lt;OTP installation root&gt;/releases/&lt;OTP release number&gt;/OTP_VERSION</c>.
- The absolute path to the file can by constructed by calling
- <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "releases", <seealso marker="erts:erlang#system_info_otp_release">erlang:system_info(otp_release)</seealso>, "OTP_VERSION"]).</c></p>
- <p>If the version read from the <c>OTP_VERSION</c> file in a
- development system has a <c>**</c> suffix, the system has been
- patched using the
- <seealso marker="../installation_guide/OTP-PATCH-APPLY"><c>otp_patch_apply</c></seealso>
- tool. In this case, the system consists of application
- versions from multiple OTP versions. The version preceding the <c>**</c>
- suffix corresponds to the OTP version of the base system that
- has been patched. Note that if a development system is updated by
- other means than <c>otp_patch_apply</c>, the <c>OTP_VERSION</c> file
- may identify an incorrect OTP version.</p>
-
- <p>No <c>OTP_VERSION</c> file will be placed in a
- <seealso marker="create_target">target system</seealso> created
- by OTP tools. This since one easily can create a target system
- where it is hard to even determine the base OTP version. You may,
- however, place such a file there yourself if you know the OTP
- version.</p>
+ <section>
+ <title>Retrieving Current OTP Version</title>
+ <p>In an OTP source code tree, the OTP version can be read from
+ the text file <c>&lt;OTP source root&gt;/OTP_VERSION</c>. The
+ absolute path to the file can be constructed by calling
+ <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "OTP_VERSION"])</c>.</p>
+ <p>In an installed OTP development system, the OTP version can be read
+ from the text file <c>&lt;OTP installation root&gt;/releases/&lt;OTP release number&gt;/OTP_VERSION</c>.
+ The absolute path to the file can by constructed by calling
+ <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "releases", <seealso marker="erts:erlang#system_info_otp_release"> erlang:system_info(otp_release)</seealso>, "OTP_VERSION"]).</c></p>
+ <p>If the version read from the <c>OTP_VERSION</c> file in a
+ development system has a <c>**</c> suffix, the system has been
+ patched using the
+ <seealso marker="../installation_guide/OTP-PATCH-APPLY"><c>otp_patch_apply</c></seealso>
+ tool. In this case, the system consists of application
+ versions from multiple OTP versions. The version preceding the <c>**</c>
+ suffix corresponds to the OTP version of the base system that
+ has been patched. Notice that if a development system is updated by
+ other means than <c>otp_patch_apply</c>, the file <c>OTP_VERSION</c>
+ can identify an incorrect OTP version.</p>
+ <p>No <c>OTP_VERSION</c> file is placed in a
+ <seealso marker="create_target">target system</seealso> created
+ by OTP tools. This since one easily can create a target system
+ where it is hard to even determine the base OTP version. You can,
+ however, place such a file there if you know the OTP version.</p>
</section>
- <section><title>OTP Versions Table</title>
- <p>The text file <c>&lt;OTP source root&gt;/otp_versions.table</c> that
- is part of the source code contains information about all OTP versions
- from OTP 17.0 up to current OTP version. Each line contains information
- about application versions that are part of a specific OTP version, and
- is on the format:</p>
-<pre>
-&lt;OtpVersion&gt; : &lt;ChangedAppVersions&gt; # &lt;UnchangedAppVersions&gt; :
-</pre>
- <p><c>&lt;OtpVersion&gt;</c> is on the format <c>OTP-&lt;VSN&gt;</c>, i.e.,
- the same as the git tag used to identify the source.
- <c>&lt;ChangedAppVersions&gt;</c> and <c>&lt;UnchangedAppVersions&gt;</c>
- are space separated lists of application versions on the
- format <c>&lt;application&gt;-&lt;vsn&gt;</c>.
- <c>&lt;ChangedAppVersions&gt;</c> corresponds to changed applications
- with new version numbers in this OTP version, and
- <c>&lt;UnchangedAppVersions&gt;</c> corresponds to unchanged application
- versions in this OTP version. Both of them might be empty, although
- not at the same time. If &lt;ChangedAppVersions&gt; is empty, no changes
- has been made that change the build result of any application. This could
- for example be a pure bug fix of the build system. The order of lines
- is undefined. All white space characters in this file are either space
- (character 32) or line-break (character 10).</p>
- <p>Using ordinary UNIX tools like <c>sed</c> and <c>grep</c> one
- can easily find answers to various questions like:</p>
- <taglist>
- <tag>Which OTP versions are <c>kernel-3.0</c> part of?</tag>
- <item><p><c> $ grep ' kernel-3\.0 ' otp_versions.table</c></p></item>
- <tag>In which OTP version was <c>kernel-3.0</c> introduced?</tag>
- <item><p><c> $ sed 's/#.*//;/ kernel-3\.0 /!d' otp_versions.table</c></p></item>
- </taglist>
- <p>The above commands give a bit more information than the exact answers,
- but adequate information when manually searching for answers to these
- questions.</p>
- <warning><p>The format of the <c>otp_versions.table</c> might be subject
- to changes during the OTP 17 release.</p></warning>
- </section>
+ <section>
+ <title>OTP Versions Table</title>
+ <p>The text file <c>&lt;OTP source root&gt;/otp_versions.table</c>,
+ which is part of the source code, contains information about all
+ OTP versions from OTP 17.0 up to the current OTP version. Each line
+ contains information about application versions that are part of a
+ specific OTP version, and has the following format:</p>
+ <pre>
+&lt;OtpVersion&gt; : &lt;ChangedAppVersions&gt; # &lt;UnchangedAppVersions&gt; :</pre>
+ <p><c>&lt;OtpVersion&gt;</c> has the format <c>OTP-&lt;VSN&gt;</c>,
+ that is, the same as the git tag used to identify the source.</p>
+ <p><c>&lt;ChangedAppVersions&gt;</c> and
+ <c>&lt;UnchangedAppVersions&gt;</c> are space-separated lists of
+ application versions and has the format
+ <c>&lt;application&gt;-&lt;vsn&gt;</c>.</p>
+ <list type="bulleted">
+ <item><c>&lt;ChangedAppVersions&gt;</c> corresponds to changed
+ applications with new version numbers in this OTP version.</item>
+ <item><c>&lt;UnchangedAppVersions&gt;</c> corresponds to unchanged
+ application versions in this OTP version.</item>
+ </list>
+ <p>Both of them can be empty, but not at the same time.
+ If <c>&lt;ChangedAppVersions&gt;</c> is empty, no changes have
+ been made that change the build result of any application. This could,
+ for example, be a pure bug fix of the build system. The order of lines
+ is undefined. All white-space characters in this file are either space
+ (character 32) or line-break (character 10).</p>
+ <p>By using ordinary UNIX tools like <c>sed</c> and <c>grep</c> one
+ can easily find answers to various questions like:</p>
+ <list type="bulleted">
+ <item><p>Which OTP versions are <c>kernel-3.0</c> part of?</p>
+ <p><c>$ grep ' kernel-3\.0 ' otp_versions.table</c> </p></item>
+ <item><p>In which OTP version was <c>kernel-3.0</c> introduced?</p>
+ <p><c>$ sed 's/#.*//;/ kernel-3\.0 /!d' otp_versions.table</c>
+ </p></item>
+ </list>
+ <p>The above commands give a bit more information than the exact
+ answers, but adequate information when manually searching for answers
+ to these questions.</p>
+ <warning><p>The format of the <c>otp_versions.table</c> might be
+ subject to changes during the OTP 17 release.</p></warning>
</section>
+ </section>
- <section><title>Application Version</title>
- <p>As of OTP 17.0 application versions will use the same
+ <section>
+ <title>Application Version</title>
+ <p>As of OTP 17.0 application versions use the same
<seealso marker="#version_scheme">version scheme</seealso> as the
OTP version. Application versions part of a release candidate will
however not have an <c>-rc&lt;N&gt;</c> suffix as the OTP version.
@@ -126,88 +133,88 @@
necessarily imply a major increment of the OTP version. This depends
on whether the major change in the application is considered as a
major change for OTP as a whole or not.</p>
- </section>
+ </section>
+ <section>
+ <title>Version Scheme</title>
<marker id="version_scheme"/>
- <section><title>Version Scheme</title>
- <note>Note that the version scheme was changed as of OTP 17.0. This implies
+ <note><p>The version scheme was changed as of OTP 17.0. This implies
that application versions used prior to OTP 17.0 do not adhere to this
version scheme. <seealso marker="#otp_17_0_app_versions">A list of
- application versions used in OTP 17.0</seealso> can be found
- at the end of this document.</note>
-
- <p>In the normal case, a version will be constructed as
- <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> where <c>&lt;Major&gt;</c>
- is the most significant part. However, more dot separated parts than
- this may exist. The dot separated parts consists of non-negative integers.
- If all parts less significant than <c>&lt;Minor&gt;</c> equals <c>0</c>,
- they are omitted. The three normal parts
- <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> will be changed as
+ application versions used in OTP 17.0</seealso> is included at the
+ end of this section</p></note>
+ <p>In the normal case, a version is constructed as
+ <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c>,
+ where <c>&lt;Major&gt;</c> is the most significant part.</p>
+ <p>However, more dot-separated parts than this can exist.
+ The dot-separated parts consist of non-negative integers. If
+ all parts less significant than <c>&lt;Minor&gt;</c> equals
+ <c>0</c>, they are omitted. The three normal parts
+ <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> are changed as
follows:</p>
- <taglist>
- <tag><c>&lt;Major&gt;</c></tag><item>Increased when major changes,
- including incompatibilities, have been made.</item>
- <tag><c>&lt;Minor&gt;</c></tag><item>Increased when new functionality
- has been added.</item>
- <tag><c>&lt;Patch&gt;</c></tag><item>Increased when pure bug fixes
- have been made.</item>
- </taglist>
- <p>When a part in the version number is increased, all less significant
+ <list type="bulleted">
+ <item><c>&lt;Major&gt;</c> - Increases when major changes,
+ including incompatibilities, are made.</item>
+ <item><c>&lt;Minor&gt;</c> - Increases when new
+ functionality is added.</item>
+ <item><c>&lt;Patch&gt;</c> - Increases when pure bug fixes
+ are made.</item>
+ </list>
+ <p>When a part in the version number increases, all less significant
parts are set to <c>0</c>.</p>
-
<p>An application version or an OTP version identifies source code
- versions. That is, it does not imply anything about how the application
+ versions. That is, it implies nothing about how the application
or OTP has been built.</p>
- <section><title>Order of Versions</title>
- <p>Version numbers in general are only partially ordered. However,
- normal version numbers (with three parts) as of OTP 17.0 have a total
- or linear order. This applies both to normal OTP versions and
- normal application versions.</p>
-
- <p>When comparing two version numbers that have an order, one
- compare each part as ordinary integers from the most
- significant part towards less significant parts. The order is
- defined by the first parts of the same significance that
- differ. An OTP version with a larger version include all
- changes that that are part of a smaller OTP version. The same
- goes for application versions.</p>
-
- <p>In the general case, versions may have more than three parts. In
- this case the versions are only partially ordered. Note that such
- versions are only used in exceptional cases. When an extra
- part (out of the normal three parts) is added to a version number,
- a new branch of versions is made. The new branch has a linear
- order against the base version. However, versions on different
- branches have no order. Since they have no order, we
- only know that they all include what is included in their
- closest common ancestor. When branching multiple times from the
- same base version, <c>0</c> parts are added between the base
- version and the least significant <c>1</c> part until a unique
- version is found. Versions that have an order can be compared
- as described in the paragraph above.</p>
-
- <p>An example of branched versions: The version <c>6.0.2.1</c>
- is a branched version from the base version <c>6.0.2</c>.
- Versions on the form <c>6.0.2.&lt;X&gt;</c> can be compared
- with normal versions smaller than or equal to <c>6.0.2</c>,
- and other versions on the form <c>6.0.2.&lt;X&gt;</c>. The
- version <c>6.0.2.1</c> will include all changes in
- <c>6.0.2</c>. However, <c>6.0.3</c> will most likely
- <em>not</em> include all changes in <c>6.0.2.1</c> (note that
- these versions have no order). A second branched version from the base
- version <c>6.0.2</c> will be version <c>6.0.2.0.1</c>, and a
- third branched version will be <c>6.0.2.0.0.1</c>.</p>
- </section>
+ <section>
+ <title>Order of Versions</title>
+ <p>Version numbers in general are only partially ordered. However,
+ normal version numbers (with three parts) as of OTP 17.0 have a total
+ or linear order. This applies both to normal OTP versions and
+ normal application versions.</p>
+ <p>When comparing two version numbers that have an order, one
+ compare each part as ordinary integers from the most
+ significant part to less significant parts. The order is
+ defined by the first parts of the same significance that
+ differ. An OTP version with a larger version includes all
+ changes that are part of a smaller OTP version. The same
+ goes for application versions.</p>
+ <p>In general, versions can have more than three parts.
+ The versions are then only partially ordered. Such
+ versions are only used in exceptional cases. When an extra
+ part (out of the normal three parts) is added to a version number,
+ a new branch of versions is made. The new branch has a linear
+ order against the base version. However, versions on different
+ branches have no order, and therefore one can only conclude
+ that they all include what is included in their
+ closest common ancestor. When branching multiple times from the
+ same base version, <c>0</c> parts are added between the base
+ version and the least significant <c>1</c> part until a unique
+ version is found. Versions that have an order can be compared
+ as described in the previous paragraph.</p>
+ <p>An example of branched versions: The version <c>6.0.2.1</c>
+ is a branched version from the base version <c>6.0.2</c>.
+ Versions on the form <c>6.0.2.&lt;X&gt;</c> can be compared
+ with normal versions smaller than or equal to <c>6.0.2</c>,
+ and other versions on the form <c>6.0.2.&lt;X&gt;</c>. The
+ version <c>6.0.2.1</c> will include all changes in
+ <c>6.0.2</c>. However, <c>6.0.3</c> will most likely
+ <em>not</em> include all changes in <c>6.0.2.1</c> (note that
+ these versions have no order). A second branched version from the base
+ version <c>6.0.2</c> will be version <c>6.0.2.0.1</c>, and a
+ third branched version will be <c>6.0.2.0.0.1</c>.</p>
</section>
+ </section>
+ <section>
+ <title>OTP 17.0 Application Versions</title>
<marker id="otp_17_0_app_versions"/>
- <section><title>OTP 17.0 Application Versions</title>
- <p>The following application versions were part of OTP 17.0. If
- the normal part of an applications version number compares
- as smaller than the corresponding application version in this list,
+ <p>The following list details the application versions that
+ were part of OTP 17.0. If
+ the normal part of an application version number compares
+ as smaller than the corresponding application version in the list,
the version number does not adhere to the version scheme introduced
- in OTP 17.0 and should be considered as not having an order against
+ in OTP 17.0 and is to be considered as not having an order against
versions used as of OTP 17.0.</p>
<list>
<item><c>asn1-3.0</c></item>
@@ -263,6 +270,6 @@
<item><c>wx-1.2</c></item>
<item><c>xmerl-1.3.7</c></item>
</list>
- </section>
+ </section>
</chapter>
diff --git a/system/doc/system_principles/xmlfiles.mk b/system/doc/system_principles/xmlfiles.mk
index c60ffbad28..fcc1fc886f 100644
--- a/system/doc/system_principles/xmlfiles.mk
+++ b/system/doc/system_principles/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009-2014. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile
index 823ec18940..9e676a57fe 100644
--- a/system/doc/top/Makefile
+++ b/system/doc/top/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1999-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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/system/doc/top/book.xml b/system/doc/top/book.xml
index 600f87e0ae..7bbeb38472 100644
--- a/system/doc/top/book.xml
+++ b/system/doc/top/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl
index 73d131ec0b..dddf025020 100644
--- a/system/doc/top/src/erl_html_tools.erl
+++ b/system/doc/top/src/erl_html_tools.erl
@@ -4,16 +4,17 @@
%%
%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/system/doc/top/src/erlresolvelinks.erl b/system/doc/top/src/erlresolvelinks.erl
index 27dbcf9b7b..82b79d9f9f 100644
--- a/system/doc/top/src/erlresolvelinks.erl
+++ b/system/doc/top/src/erlresolvelinks.erl
@@ -4,16 +4,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/system/doc/top/src/otp_man_index.erl b/system/doc/top/src/otp_man_index.erl
index 4ad975c53d..753e952ecb 100644
--- a/system/doc/top/src/otp_man_index.erl
+++ b/system/doc/top/src/otp_man_index.erl
@@ -4,16 +4,17 @@
%%
%% 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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%
%%
diff --git a/system/doc/top/templates/applications.html.src b/system/doc/top/templates/applications.html.src
index 285bbced71..4be969f9d1 100644
--- a/system/doc/top/templates/applications.html.src
+++ b/system/doc/top/templates/applications.html.src
@@ -4,16 +4,17 @@
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.
+Licensed under the Apache License, Version 2.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%
-->
diff --git a/system/doc/top/templates/index.html.src b/system/doc/top/templates/index.html.src
index 7acdadbf8a..bdac3895b0 100644
--- a/system/doc/top/templates/index.html.src
+++ b/system/doc/top/templates/index.html.src
@@ -4,16 +4,17 @@
Copyright Ericsson AB 2009-2014. All Rights Reserved.
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+Licensed under the Apache License, Version 2.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%
-->
diff --git a/system/doc/tutorial/Makefile b/system/doc/tutorial/Makefile
index 403c81e685..7393dc9e9d 100644
--- a/system/doc/tutorial/Makefile
+++ b/system/doc/tutorial/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2000-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/system/doc/tutorial/appendix.xmlsrc b/system/doc/tutorial/appendix.xmlsrc
index 418df30bc8..52c24c1b67 100644
--- a/system/doc/tutorial/appendix.xmlsrc
+++ b/system/doc/tutorial/appendix.xmlsrc
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/tutorial/book.xml b/system/doc/tutorial/book.xml
index 57c2ac4373..81530f25eb 100644
--- a/system/doc/tutorial/book.xml
+++ b/system/doc/tutorial/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
diff --git a/system/doc/tutorial/c_port.xmlsrc b/system/doc/tutorial/c_port.xmlsrc
index 8579da8520..695f16515d 100644
--- a/system/doc/tutorial/c_port.xmlsrc
+++ b/system/doc/tutorial/c_port.xmlsrc
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,16 +29,34 @@
<rev></rev>
<file>c_port.xml</file>
</header>
- <p>This is an example of how to solve the <seealso marker="example">example problem</seealso> by using a port.</p>
+ <p>This section outlines an example of how to solve the example
+ problem in the <seealso marker="example">previous section</seealso>
+ by using a port.</p>
+ <p>The scenario is illustrated in the following figure:</p>
<image file="../tutorial/port.gif">
- <icaption>Port Communication.</icaption>
+ <icaption>Port Communication</icaption>
</image>
<section>
<title>Erlang Program</title>
- <p>First of all communication between Erlang and C must be established by creating the port. The Erlang process which creates a port is said to be <em>the connected process</em> of the port. All communication to and from the port should go via the connected process. If the connected process terminates, so will the port (and the external program, if it is written correctly).</p>
- <p>The port is created using the BIF <c>open_port/2</c> with <c>{spawn,ExtPrg}</c> as the first argument. The string <c>ExtPrg</c> is the name of the external program, including any command line arguments. The second argument is a list of options, in this case only <c>{packet,2}</c>. This option says that a two byte length indicator will be used to simplify the communication between C and Erlang. Adding the length indicator will be done automatically by the Erlang port, but must be done explicitly in the external C program.</p>
- <p>The process is also set to trap exits which makes it possible to detect if the external program fails.</p>
+ <p>All communication between Erlang and C must be established by
+ creating the port. The Erlang process that creates a port is
+ said to be <em>the connected process</em> of the port. All
+ communication to and from the port must go through the connected
+ process. If the connected process terminates, the port also
+ terminates (and the external program, if it is written
+ properly).</p>
+ <p>The port is created using the BIF <c>open_port/2</c> with
+ <c>{spawn,ExtPrg}</c> as the first argument. The string
+ <c>ExtPrg</c> is the name of the external program, including any
+ command line arguments. The second argument is a list of
+ options, in this case only <c>{packet,2}</c>. This option says
+ that a 2 byte length indicator is to be used to simplify the
+ communication between C and Erlang. The Erlang port
+ automatically adds the length indicator, but this must be done
+ explicitly in the external C program.</p>
+ <p>The process is also set to trap exits, which enables detection
+ of failure of the external program:</p>
<pre>
-module(complex1).
-export([start/1, init/1]).
@@ -50,7 +69,9 @@ init(ExtPrg) ->
process_flag(trap_exit, true),
Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
loop(Port).</pre>
- <p>Now it is possible to implement <c>complex1:foo/1</c> and <c>complex1:bar/1</c>. They both send a message to the <c>complex</c> process and receive the reply.</p>
+ <p>Now <c>complex1:foo/1</c> and <c>complex1:bar/1</c> can be
+ implemented. Both send a message to the <c>complex</c> process
+ and receive the following replies:</p>
<pre>
foo(X) ->
call_port({foo, X}).
@@ -63,7 +84,14 @@ call_port(Msg) ->
{complex, Result} ->
Result
end.</pre>
- <p>The <c>complex</c> process encodes the message into a sequence of bytes, sends it to the port, waits for a reply, decodes the reply and sends it back to the caller.</p>
+ <p>The <c>complex</c> process does the following:</p>
+ <list type="bulleted">
+ <item>Encodes the message into a sequence of bytes.</item>
+ <item>Sends it to the port.</item>
+ <item>Waits for a reply.</item>
+ <item>Decodes the reply.</item>
+ <item>Sends it back to the caller:</item>
+ </list>
<pre>
loop(Port) ->
receive
@@ -75,37 +103,52 @@ loop(Port) ->
end,
loop(Port)
end.</pre>
- <p>Assuming that both the arguments and the results from the C functions will be less than 256, a very simple encoding/decoding scheme is employed where <c>foo</c> is represented by the byte 1, <c>bar</c> is represented by 2, and the argument/result is represented by a single byte as well.</p>
+ <p>Assuming that both the arguments and the results from the C
+ functions are less than 256, a simple encoding/decoding scheme
+ is employed. In this scheme, <c>foo</c> is represented by byte
+ 1, <c>bar</c> is represented by 2, and the argument/result is
+ represented by a single byte as well:</p>
<pre>
encode({foo, X}) -> [1, X];
encode({bar, Y}) -> [2, Y].
-
+
decode([Int]) -> Int.</pre>
- <p>The resulting Erlang program, including functionality for stopping the port and detecting port failures is shown below.
+ <p>The resulting Erlang program, including functionality for
+ stopping the port and detecting port failures, is as follows:
</p>
<codeinclude file="complex1.erl" type="erl"/>
</section>
<section>
<title>C Program</title>
- <p>On the C side, it is necessary to write functions for receiving and sending
- data with two byte length indicators from/to Erlang. By default, the C program
- should read from standard input (file descriptor 0) and write to standard output
- (file descriptor 1). Examples of such functions, <c>read_cmd/1</c> and
- <c>write_cmd/2</c>, are shown below.</p>
+ <p>On the C side, it is necessary to write functions for receiving
+ and sending data with 2 byte length indicators from/to Erlang.
+ By default, the C program is to read from standard input (file
+ descriptor 0) and write to standard output (file descriptor 1).
+ Examples of such functions, <c>read_cmd/1</c> and
+ <c>write_cmd/2</c>, follows:</p>
<codeinclude file="erl_comm.c" type="erl"/>
- <p>Note that <c>stdin</c> and <c>stdout</c> are for buffered input/output and should not be used for the communication with Erlang!</p>
- <p>In the <c>main</c> function, the C program should listen for a message from Erlang and, according to the selected encoding/decoding scheme, use the first byte to determine which function to call and the second byte as argument to the function. The result of calling the function should then be sent back to Erlang.</p>
+ <p>Notice that <c>stdin</c> and <c>stdout</c> are for buffered
+ input/output and must <em>not</em> be used for the communication
+ with Erlang.</p>
+ <p>In the <c>main</c> function, the C program is to listen for a
+ message from Erlang and, according to the selected
+ encoding/decoding scheme, use the first byte to determine which
+ function to call and the second byte as argument to the
+ function. The result of calling the function is then to be sent
+ back to Erlang:</p>
<codeinclude file="port.c" tag="" type="none"></codeinclude>
- <p>Note that the C program is in a <c>while</c>-loop checking for the return value of <c>read_cmd/1</c>. The reason for this is that the C program must detect when the port gets closed and terminate.</p>
+ <p>Notice that the C program is in a <c>while</c>-loop, checking
+ for the return value of <c>read_cmd/1</c>. This is because the C
+ program must detect when the port closes and terminates.</p>
</section>
<section>
<title>Running the Example</title>
- <p>1. Compile the C code.</p>
+ <p><em>Step 1.</em> Compile the C code:</p>
<pre>
unix> <input>gcc -o extprg complex.c erl_comm.c port.c</input></pre>
- <p>2. Start Erlang and compile the Erlang code.</p>
+ <p><em>Step 2.</em> Start Erlang and compile the Erlang code:</p>
<pre>
unix> <input>erl</input>
Erlang (BEAM) emulator version 4.9.1.2
@@ -113,7 +156,7 @@ Erlang (BEAM) emulator version 4.9.1.2
Eshell V4.9.1.2 (abort with ^G)
1> <input>c(complex1).</input>
{ok,complex1}</pre>
- <p>3. Run the example.</p>
+ <p><em>Step 3.</em> Run the example:</p>
<pre>
2> <input>complex1:start("extprg").</input>
&lt;0.34.0>
diff --git a/system/doc/tutorial/c_portdriver.xmlsrc b/system/doc/tutorial/c_portdriver.xmlsrc
index 2fd6fb0aac..933e2395a3 100644
--- a/system/doc/tutorial/c_portdriver.xmlsrc
+++ b/system/doc/tutorial/c_portdriver.xmlsrc
@@ -4,63 +4,63 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
- <title>Port drivers</title>
+ <title>Port Drivers</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
<file>c_portdriver.xml</file>
</header>
- <p>This is an example of how to solve the <seealso marker="example">example problem</seealso> by using a linked in port driver.</p>
+ <p>This section outlines an example of how to solve the example problem
+ in <seealso marker="example">Problem Example</seealso>
+ by using a linked-in port driver.</p>
+ <p>A port driver is a linked-in driver that is accessible as a port
+ from an Erlang program. It is a shared library (SO in UNIX, DLL in
+ Windows), with special entry points. The Erlang runtime system
+ calls these entry points when the driver is started and when data
+ is sent to the port. The port driver can also send data to
+ Erlang.</p>
+ <p>As a port driver is dynamically linked into the emulator process,
+ this is the fastest way of calling C-code from Erlang. Calling
+ functions in the port driver requires no context switches. But it
+ is also the least safe way, because a crash in the port driver
+ brings the emulator down too.</p>
+ <p>The scenario is illustrated in the following figure:</p>
<image file="../tutorial/port_driver.gif">
- <icaption>Port Driver Communication.</icaption>
+ <icaption>Port Driver Communication</icaption>
</image>
<section>
- <title>Port Drivers</title>
- <p>A port driver is a linked in driver that is accessible as a
- port from an Erlang program. It is a shared library (SO in Unix,
- DLL in Windows), with special entry points. The Erlang runtime
- calls these entry points, when the driver is started and when
- data is sent to the port. The port driver can also send data to
- Erlang.</p>
- <p>Since a port driver is dynamically linked into the emulator
- process, this is the fastest way of calling C-code from Erlang.
- Calling functions in the port driver requires no context
- switches. But it is also the least safe, because a crash in the
- port driver brings the emulator down too.</p>
- </section>
-
- <section>
<title>Erlang Program</title>
- <p>Just as with a port program, the port communicates with a Erlang
+ <p>Like a port program, the port communicates with an Erlang
process. All communication goes through one Erlang process that
is the <em>connected process</em> of the port
driver. Terminating this process closes the port driver.</p>
<p>Before the port is created, the driver must be loaded. This is
done with the function <c>erl_dll:load_driver/1</c>, with the
name of the shared library as argument.</p>
- <p>The port is then created using the BIF <c>open_port/2</c> with
+ <p>The port is then created using the BIF <c>open_port/2</c>, with
the tuple <c>{spawn, DriverName}</c> as the first argument. The
string <c>SharedLib</c> is the name of the port driver. The second
- argument is a list of options, none in this case.</p>
+ argument is a list of options, none in this case:</p>
<pre>
-module(complex5).
-export([start/1, init/1]).
@@ -77,9 +77,9 @@ init(SharedLib) ->
register(complex, self()),
Port = open_port({spawn, SharedLib}, []),
loop(Port).</pre>
- <p>Now it is possible to implement <c>complex5:foo/1</c> and
- <c>complex5:bar/1</c>. They both send a message to the
- <c>complex</c> process and receive the reply.</p>
+ <p>Now <c>complex5:foo/1</c> and <c>complex5:bar/1</c>
+ can be implemented. Both send a message to the
+ <c>complex</c> process and receive the following reply:</p>
<pre>
foo(X) ->
call_port({foo, X}).
@@ -92,10 +92,14 @@ call_port(Msg) ->
{complex, Result} ->
Result
end.</pre>
- <p>The <c>complex</c> process encodes the message into a sequence
- of bytes, sends it to the port, waits for a reply, decodes the
- reply and sends it back to the caller.
- </p>
+ <p>The <c>complex</c> process performs the following:</p>
+ <list type="bulleted">
+ <item>Encodes the message into a sequence of bytes.</item>
+ <item>Sends it to the port.</item>
+ <item>Waits for a reply.</item>
+ <item>Decodes the reply.</item>
+ <item>Sends it back to the caller:</item>
+ </list>
<pre>
loop(Port) ->
receive
@@ -108,59 +112,58 @@ loop(Port) ->
loop(Port)
end.</pre>
<p>Assuming that both the arguments and the results from the C
- functions will be less than 256, a very simple encoding/decoding
- scheme is employed where <c>foo</c> is represented by the byte
+ functions are less than 256, a simple encoding/decoding scheme
+ is employed. In this scheme, <c>foo</c> is represented by byte
1, <c>bar</c> is represented by 2, and the argument/result is
- represented by a single byte as well.
- </p>
+ represented by a single byte as well:</p>
<pre>
encode({foo, X}) -> [1, X];
encode({bar, Y}) -> [2, Y].
-
+
decode([Int]) -> Int.</pre>
- <p>The resulting Erlang program, including functionality for
- stopping the port and detecting port failures is shown below.</p>
+ <p>The resulting Erlang program, including functions for stopping
+ the port and detecting port failures, is as follows:</p>
<codeinclude file="complex5.erl" type="erl"/>
</section>
<section>
<title>C Driver</title>
<p>The C driver is a module that is compiled and linked into a
- shared library. It uses a driver structure, and includes the
+ shared library. It uses a driver structure and includes the
header file <c>erl_driver.h</c>.</p>
<p>The driver structure is filled with the driver name and function
pointers. It is returned from the special entry point, declared
with the macro <c><![CDATA[DRIVER_INIT(<driver_name>)]]></c>.</p>
- <p>The functions for receiving and sending data, are combined into
+ <p>The functions for receiving and sending data are combined into
a function, pointed out by the driver structure. The data sent
- into the port is given as arguments, and the data the port
- sends back is sent with the C-function <c>driver_output</c>.</p>
- <p>Since the driver is a shared module, not a program, no main
- function should be present. All function pointers are not used
- in our example, and the corresponding fields in the
+ into the port is given as arguments, and the replied data is sent
+ with the C-function <c>driver_output</c>.</p>
+ <p>As the driver is a shared module, not a program, no main
+ function is present. All function pointers are not used
+ in this example, and the corresponding fields in the
<c>driver_entry</c> structure are set to NULL.</p>
- <p>All functions in the driver, takes a handle (returned from
- <c>start</c>), that is just passed along by the erlang
+ <p>All functions in the driver takes a handle (returned from
+ <c>start</c>) that is just passed along by the Erlang
process. This must in some way refer to the port driver
instance.</p>
- <p>The example_drv_start, is the only function that is called with
- a handle to the port instance, so we must save this. It is
- customary to use a allocated driver-defined structure for this
- one, and pass a pointer back as a reference.</p>
- <p>It is not a good idea to use a global variable; since the port
- driver can be spawned by multiple Erlang processes, this
- driver-structure should be instantiated multiple times.
+ <p>The <c>example_drv_start</c>, is the only function that is called with
+ a handle to the port instance, so this must be saved. It is
+ customary to use an allocated driver-defined structure for this
+ one, and to pass a pointer back as a reference.</p>
+ <p>It is not a good idea to use a global variable as the port
+ driver can be spawned by multiple Erlang processes. This
+ driver-structure is to be instantiated multiple times:
</p>
<codeinclude file="port_driver.c" tag="" type="none"></codeinclude>
</section>
<section>
<title>Running the Example</title>
- <p>1. Compile the C code.</p>
+ <p><em>Step 1.</em> Compile the C code:</p>
<pre>
unix> <input>gcc -o exampledrv -fpic -shared complex.c port_driver.c</input>
windows> <input>cl -LD -MD -Fe exampledrv.dll complex.c port_driver.c</input></pre>
- <p>2. Start Erlang and compile the Erlang code.</p>
+ <p><em>Step 2.</em> Start Erlang and compile the Erlang code:</p>
<pre>
> <input>erl</input>
Erlang (BEAM) emulator version 5.1
@@ -168,7 +171,7 @@ Erlang (BEAM) emulator version 5.1
Eshell V5.1 (abort with ^G)
1> <input>c(complex5).</input>
{ok,complex5}</pre>
- <p>3. Run the example.</p>
+ <p><em>Step 3.</em> Run the example:</p>
<pre>
2> <input>complex5:start("example_drv").</input>
&lt;0.34.0>
diff --git a/system/doc/tutorial/cnode.xmlsrc b/system/doc/tutorial/cnode.xmlsrc
index 293406160f..f1f0e976ad 100644
--- a/system/doc/tutorial/cnode.xmlsrc
+++ b/system/doc/tutorial/cnode.xmlsrc
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,19 +29,39 @@
<rev></rev>
<file>cnode.xml</file>
</header>
- <p>This is an example of how to solve the <seealso marker="example">example problem</seealso> by using a C node. Note that a C node would not typically be used for solving a simple problem like this, a port would suffice.</p>
+ <p>This section outlines an example of how to solve the example
+ problem in <seealso marker="example">Problem Example</seealso>
+ by using a C node. Notice that a C node is not typically
+ used for solving simple problems like this, a port is
+ sufficient.</p>
<section>
<title>Erlang Program</title>
- <p>From Erlang's point of view, the C node is treated like a normal Erlang node. Therefore, calling the functions <c>foo</c> and <c>bar</c> only involves sending a message to the C node asking for the function to be called, and receiving the result. Sending a message requires a recipient; a process which can be defined using either a pid or a tuple consisting of a registered name and a node name. In this case a tuple is the only alternative as no pid is known.</p>
+ <p>From Erlang's point of view, the C node is treated like a
+ normal Erlang node. Thus, calling the functions <c>foo</c> and
+ <c>bar</c> only involves sending a message to the C node asking
+ for the function to be called, and receiving the result. Sending
+ a message requires a recipient, that is, a process that can be
+ defined using either a pid or a tuple, consisting of a
+ registered name and a node name. In this case, a tuple is the
+ only alternative as no pid is known:</p>
<pre>
{RegName, Node} ! Msg</pre>
- <p>The node name <c>Node</c> should be the name of the C node. If short node names are used, the plain name of the node will be <c>cN</c> where <c>N</c> is an integer. If long node names are used, there is no such restriction. An example of a C node name using short node names is thus <c>c1@idril</c>, an example using long node names is <c>[email protected]</c>.</p>
- <p>The registered name <c>RegName</c> could be any atom. The name can be ignored by the C code, or it could be used for example to distinguish between different types of messages. Below is an example of what the Erlang code could look like when using short node names.
+ <p>The node name <c>Node</c> is to be the name of the C node. If
+ short node names are used, the plain name of the node is
+ <c>cN</c>, where <c>N</c> is an integer. If long node names are
+ used, there is no such restriction. An example of a C node name
+ using short node names is thus <c>c1@idril</c>, an example using
+ long node names is <c>[email protected]</c>.</p>
+ <p>The registered name, <c>RegName</c>, can be any atom. The name
+ can be ignored by the C code, or, for example, be used to
+ distinguish between different types of messages. An example of
+ Erlang code using short node names follows:
</p>
<codeinclude file="complex3.erl" tag="" type="erl"></codeinclude>
<p>
- When using long node names the code is slightly different as shown in the following example:
+ When using long node names, the code is slightly different as
+ shown in the following example:
</p>
<codeinclude file="complex4.erl" tag="" type="erl"></codeinclude>
@@ -50,39 +71,77 @@
<title>C Program</title>
<section>
- <title>Setting Up the Communication</title>
- <p>Before calling any other Erl_Interface function, the memory handling must be initiated.</p>
+ <title>Setting Up Communication</title>
+ <p>Before calling any other function in Erl_Interface, the
+ memory handling must be initiated:</p>
<pre>
erl_init(NULL, 0);</pre>
- <p>Now the C node can be initiated. If short node names are used, this is done by calling <c>erl_connect_init()</c>.</p>
+ <p>Now the C node can be initiated. If short node names are
+ used, this is done by calling <c>erl_connect_init()</c>:</p>
<pre>
erl_connect_init(1, "secretcookie", 0);</pre>
- <p>The first argument is the integer which is used to construct the node name. In the example the plain node name will be <c>c1</c>. <br></br>
-
- The second argument is a string defining the magic cookie. <br></br>
-
- The third argument is an integer which is used to identify a particular instance of a C node.</p>
- <p>If long node node names are used, initiation is done by calling <c>erl_connect_xinit()</c>.</p>
+ <p>Here:</p>
+ <list type="bulleted">
+ <item>The first argument is the integer used to construct the node name.
+ <p>In the example, the plain node name is <c>c1</c>.</p></item>
+ <item>The second argument is a string defining the magic cookie.</item>
+ <item>The third argument is an integer that is used to identify
+ a particular instance of a C node.</item>
+ </list>
+ <p>If long node node names are used, initiation is done by
+ calling <c>erl_connect_xinit()</c>:</p>
<pre>
erl_connect_xinit("idril", "cnode", "[email protected]",
&amp;addr, "secretcookie", 0);</pre>
- <p>The first three arguments are the host name, the plain node name, and the full node name. The fourth argument is a pointer to an <c>in_addr</c> struct with the IP address of the host, and the fifth and sixth arguments are the magic cookie and instance number.</p>
- <p>The C node can act as a server or a client when setting up the communication Erlang-C. If it acts as a client, it connects to an Erlang node by calling <c>erl_connect()</c>, which will return an open file descriptor at success.</p>
+ <p>Here:</p>
+ <list type="bulleted">
+ <item>The first argument is the host name.</item>
+ <item>The second argument is the plain node name.</item>
+ <item>The third argument is the full node name.</item>
+ <item>The fourth argument is a pointer to an <c>in_addr</c>
+ struct with the IP address of the host.</item>
+ <item>The fifth argument is the magic cookie.</item>
+ <item>The sixth argument is the instance number.</item>
+ </list>
+ <p>The C node can act as a server or a client when setting up
+ the Erlang-C communication. If it acts as a client, it
+ connects to an Erlang node by calling <c>erl_connect()</c>,
+ which returns an open file descriptor at success:</p>
<pre>
fd = erl_connect("e1@idril");</pre>
- <p>If the C node acts as a server, it must first create a socket (call <c>bind()</c> and <c>listen()</c>) listening to a certain port number <c>port</c>. It then publishes its name and port number with <c>epmd</c> (the Erlang port mapper daemon, see the man page for <c>epmd</c>).</p>
+ <p>If the C node acts as a server, it must first create a socket
+ (call <c>bind()</c> and <c>listen()</c>) listening to a
+ certain port number <c>port</c>. It then publishes its name
+ and port number with <c>epmd</c>, the Erlang port mapper
+ daemon. For details, see the <seealso
+ marker="erts:epmd">epmd</seealso> manual page in ERTS:</p>
<pre>
erl_publish(port);</pre>
- <p>Now the C node server can accept connections from Erlang nodes.</p>
+ <p>Now the C node server can accept connections from Erlang nodes:</p>
<pre>
fd = erl_accept(listen, &amp;conn);</pre>
- <p>The second argument to <c>erl_accept</c> is a struct <c>ErlConnect</c> that will contain useful information when a connection has been established; for example, the name of the Erlang node.</p>
+ <p>The second argument to <c>erl_accept</c> is a struct
+ <c>ErlConnect</c> which contains useful information when a
+ connection has been established, for example, the name of the
+ Erlang node.</p>
</section>
<section>
<title>Sending and Receiving Messages</title>
- <p>The C node can receive a message from Erlang by calling <c>erl_receive msg()</c>. This function reads data from the open file descriptor <c>fd</c> into a buffer and puts the result in an <c>ErlMessage</c> struct <c>emsg</c>. <c>ErlMessage</c> has a field <c>type</c> defining which kind of data was received. In this case the type of interest is <c>ERL_REG_SEND</c> which indicates that Erlang sent a message to a registered process at the C node. The actual message, an <c>ETERM</c>, will be in the <c>msg</c> field.</p>
- <p>It is also necessary to take care of the types <c>ERL_ERROR</c> (an error occurred) and <c>ERL_TICK</c> (alive check from other node, should be ignored). Other possible types indicate process events such as link/unlink and exit.</p>
+ <p>The C node can receive a message from Erlang by calling
+ <c>erl_receive msg()</c>. This function reads data from the
+ open file descriptor <c>fd</c> into a buffer and puts the
+ result in an <c>ErlMessage</c> struct <c>emsg</c>.
+ <c>ErlMessage</c> has a field <c>type</c> defining what kind
+ of data is received. In this case, the type of interest is
+ <c>ERL_REG_SEND</c> which indicates that Erlang sent a message
+ to a registered process at the C node. The actual message, an
+ <c>ETERM</c>, is in the <c>msg</c> field.</p>
+ <p>It is also necessary to take care of the types
+ <c>ERL_ERROR</c> (an error occurred) and <c>ERL_TICK</c>
+ (alive check from other node, is to be ignored). Other
+ possible types indicate process events such as link, unlink,
+ and exit:</p>
<pre>
while (loop) {
@@ -93,7 +152,16 @@ fd = erl_accept(listen, &amp;conn);</pre>
loop = 0; /* exit while loop */
} else {
if (emsg.type == ERL_REG_SEND) {</pre>
- <p>Since the message is an <c>ETERM</c> struct, Erl_Interface functions can be used to manipulate it. In this case, the message will be a 3-tuple (because that was how the Erlang code was written, see above). The second element will be the pid of the caller and the third element will be the tuple <c>{Function,Arg}</c> determining which function to call with which argument. The result of calling the function is made into an <c>ETERM</c> struct as well and sent back to Erlang using <c>erl_send()</c>, which takes the open file descriptor, a pid and a term as arguments.</p>
+ <p>As the message is an <c>ETERM</c> struct, Erl_Interface
+ functions can be used to manipulate it. In this case, the
+ message becomes a 3-tuple, because that is how the Erlang code
+ is written. The second element will be the pid of the caller
+ and the third element will be the tuple <c>{Function,Arg}</c>
+ determining which function to call, and with which argument.
+ The result of calling the function is made into an
+ <c>ETERM</c> struct as well and sent back to Erlang using
+ <c>erl_send()</c>, which takes the open file descriptor, a
+ pid, and a term as arguments:</p>
<pre>
fromp = erl_element(2, emsg.msg);
tuplep = erl_element(3, emsg.msg);
@@ -108,29 +176,30 @@ fd = erl_accept(listen, &amp;conn);</pre>
resp = erl_format("{cnode, ~i}", res);
erl_send(fd, fromp, resp);</pre>
- <p>Finally, the memory allocated by the <c>ETERM</c> creating functions (including <c>erl_receive_msg()</c> must be freed.</p>
+ <p>Finally, the memory allocated by the <c>ETERM</c> creating
+ functions (including <c>erl_receive_msg()</c> must be
+ freed:</p>
<pre>
erl_free_term(emsg.from); erl_free_term(emsg.msg);
erl_free_term(fromp); erl_free_term(tuplep);
erl_free_term(fnp); erl_free_term(argp);
erl_free_term(resp);</pre>
- <p>The resulting C programs can be found in looks like the following examples. First a C node server using short node names.</p>
+ <p>The following examples show the resulting C programs.
+ First a C node server using short node names:</p>
<codeinclude file="cnode_s.c" type="c"/>
- <p>Below follows a C node server using long node names.</p>
+ <p>A C node server using long node names:</p>
<codeinclude file="cnode_s2.c" type="c"/>
- <p>And finally we have the code for the C node client.</p>
+ <p>Finally, the code for the C node client:</p>
<codeinclude file="cnode_c.c" type="c"/>
</section>
</section>
<section>
<title>Running the Example</title>
- <p>1. Compile the C code, providing the paths to the Erl_Interface include files and libraries, and to the <c>socket</c> and <c>nsl</c> libraries.</p>
- <p>In R5B and later versions of OTP, the <c>include</c> and <c>lib</c> directories are situated under <c>OTPROOT/lib/erl_interface-VSN</c>, where <c>OTPROOT</c> is the root directory of the OTP installation (<c>/usr/local/otp</c> in the example above) and <c>VSN</c> is the version of the <c>erl_interface</c> application (3.2.1 in the example above). <br></br>
-
- In R4B and earlier versions of OTP, <c>include</c> and <c>lib</c> are situated under <c>OTPROOT/usr</c>.</p>
+ <p><em>Step 1.</em> Compile the C code. This provides the paths to
+ the Erl_Interface include files and libraries, and to the
+ <c>socket</c> and <c>nsl</c> libraries:</p>
<pre>
-
> <input>gcc -o cserver \\ </input>
<input>-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </input>
<input>-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </input>
@@ -148,11 +217,29 @@ unix> <input>gcc -o cclient \\ </input>
<input>-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </input>
<input>complex.c cnode_c.c \\ </input>
<input>-lerl_interface -lei -lsocket -lnsl</input></pre>
- <p>2. Compile the Erlang code.</p>
+ <p>In Erlang/OTP R5B and later versions of OTP, the
+ <c>include</c> and <c>lib</c> directories are situated under
+ <c>OTPROOT/lib/erl_interface-VSN</c>, where <c>OTPROOT</c> is
+ the root directory of the OTP installation
+ (<c>/usr/local/otp</c> in the recent example) and <c>VSN</c> is
+ the version of the Erl_Interface application (3.2.1 in the
+ recent example).</p>
+ <p>In R4B and earlier versions of OTP, <c>include</c> and
+ <c>lib</c> are situated under <c>OTPROOT/usr</c>.</p>
+ <p><em>Step 2.</em> Compile the Erlang code:</p>
<pre>
unix> <input>erl -compile complex3 complex4</input></pre>
- <p>3. Run the C node server example with short node names.</p>
- <p>Start the C program <c>cserver</c> and Erlang in different windows. <c>cserver</c> takes a port number as argument and must be started before trying to call the Erlang functions. The Erlang node should be given the short name <c>e1</c> and must be set to use the same magic cookie as the C node, <c>secretcookie</c>.</p>
+ <p><em>Step 3.</em> Run the C node server example with short node names.</p>
+ <p>Do as follows:</p>
+ <list type="bulleted">
+ <item>Start the C program <c>cserver</c> and Erlang in
+ different windows.</item>
+ <item><c>cserver</c> takes a port number as argument and must
+ be started before trying to call the Erlang functions.</item>
+ <item>The Erlang node is to be given the short name <c>e1</c>
+ and must be set to use the same magic cookie as the C node,
+ <c>secretcookie</c>:</item>
+ </list>
<pre>
unix> <input>cserver 3456</input>
@@ -164,7 +251,9 @@ Eshell V4.9.1.2 (abort with ^G)
4
(e1@idril)2> <input>complex3:bar(5).</input>
10</pre>
- <p>4. Run the C node client example. Terminate <c>cserver</c> but not Erlang and start <c>cclient</c>. The Erlang node must be started before the C node client is.</p>
+ <p><em>Step 4.</em> Run the C node client example. Terminate
+ <c>cserver</c>, but not Erlang, and start <c>cclient</c>. The
+ Erlang node must be started before the C node client:</p>
<pre>
unix> <input>cclient</input>
@@ -172,7 +261,7 @@ unix> <input>cclient</input>
4
(e1@idril)4> <input>complex3:bar(5).</input>
10</pre>
- <p>5. Run the C node server, long node names, example.</p>
+ <p><em>Step 5.</em> Run the C node server example with long node names:</p>
<pre>
unix> <input>cserver2 3456</input>
diff --git a/system/doc/tutorial/distribution.xml b/system/doc/tutorial/distribution.xml
index 6a0ea759c4..40d60acb3a 100644
--- a/system/doc/tutorial/distribution.xml
+++ b/system/doc/tutorial/distribution.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -58,7 +59,6 @@
<item>global_group - Grouping nodes to global name registration groups.</item>
<item>net_adm - Various net administration routines.</item>
<item>net_kernel - Networking kernel.</item>
- <item>pg - Distributed named process groups, experimental implementation.</item>
<item>pg2 - Distributed named process groups.</item>
<item>pool - Load distribution facility.</item>
<item>slave - Functions for starting and controlling slave nodes.</item>
diff --git a/system/doc/tutorial/ei.c b/system/doc/tutorial/ei.c
index b234a00768..c33e3fb78e 100644
--- a/system/doc/tutorial/ei.c
+++ b/system/doc/tutorial/ei.c
@@ -21,7 +21,7 @@ int main() {
if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
res = foo(ERL_INT_VALUE(argp));
- } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 17) == 0) {
+ } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
res = bar(ERL_INT_VALUE(argp));
}
diff --git a/system/doc/tutorial/erl_interface.xmlsrc b/system/doc/tutorial/erl_interface.xmlsrc
index 0c4c5a99c2..de50af42cf 100644
--- a/system/doc/tutorial/erl_interface.xmlsrc
+++ b/system/doc/tutorial/erl_interface.xmlsrc
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,14 +29,29 @@
<rev></rev>
<file>erl_interface.xml</file>
</header>
- <p>This is an example of how to solve the <seealso marker="example">example problem</seealso> by using a port and <c>erl_interface</c>. It is necessary to read the <seealso marker="c_port">port example</seealso> before reading this chapter.</p>
+
+ <p>This section outlines an example of how to solve the example
+ problem in <seealso marker="example">Problem Example</seealso> by
+ using a port and Erl_Interface. It is necessary to read the port
+ example in <seealso marker="c_port">Ports</seealso> before reading
+ this section.</p>
<section>
<title>Erlang Program</title>
- <p>The example below shows an Erlang program communicating with a C program over a plain port with home made encoding.</p>
- <codeinclude file="complex1.erl" type="erl"/>
- <p>Compared to the Erlang module
- above used for the plain port, there are two differences when using Erl_Interface on the C side: Since Erl_Interface operates on the Erlang external term format the port must be set to use binaries and, instead of inventing an encoding/decoding scheme, the BIFs <c>term_to_binary/1</c> and <c>binary_to_term/1</c> should be used. That is:</p>
+ <p>The following example shows an Erlang program communicating
+ with a C program over a plain port with home made encoding:</p>
+ <codeinclude file="complex1.erl" type="erl"/>
+ <p>There are two differences when using Erl_Interface on the C
+ side compared to the example in <seealso marker="c_port">
+ Ports</seealso>, using only the plain port:</p>
+ <list type="bulleted">
+ <item>As Erl_Interface operates on the Erlang external term format,
+ the port must be set to use binaries.</item>
+ <item>Instead of inventing an encoding/decoding scheme, the
+ <c>term_to_binary/1</c> and <c>binary_to_term/1</c> BIFs are to
+ be used.</item>
+ </list>
+ <p>That is:</p>
<pre>
open_port({spawn, ExtPrg}, [{packet, 2}])</pre>
<p>is replaced with:</p>
@@ -55,69 +71,110 @@ receive
{Port, {data, Data}} ->
Caller ! {complex, binary_to_term(Data)}
end</pre>
- <p>The resulting Erlang program is shown below.</p>
+ <p>The resulting Erlang program is as follows:</p>
<codeinclude file="complex2.erl" type="erl"/>
- <p>Note that calling <c>complex2:foo/1</c> and <c>complex2:bar/1</c> will result in the tuple <c>{foo,X}</c> or <c>{bar,Y}</c> being sent to the <c>complex</c> process, which will code them as binaries and send them to the port. This means that the C program must be able to handle these two tuples.</p>
+ <p>Notice that calling <c>complex2:foo/1</c> and
+ <c>complex2:bar/1</c> results in the tuple <c>{foo,X}</c> or
+ <c>{bar,Y}</c> being sent to the <c>complex</c> process, which
+ codes them as binaries and sends them to the port. This means
+ that the C program must be able to handle these two tuples.</p>
</section>
<section>
<title>C Program</title>
- <p>The example below shows a C program communicating with an Erlang program over a plain port with home made encoding.</p>
+ <p>The following example shows a C program communicating with an
+ Erlang program over a plain port with home made encoding:</p>
<codeinclude file="port.c" type="c"/>
- <p>Compared to the C program above
- used for the plain port the <c>while</c>-loop must be rewritten. Messages coming from the port will be on the Erlang external term format. They should be converted into an <c>ETERM</c> struct, a C struct similar to an Erlang term. The result of calling <c>foo()</c> or <c>bar()</c> must be converted to the Erlang external term format before being sent back to the port. But before calling any other <c>erl_interface</c> function, the memory handling must be initiated.</p>
+ <p>Compared to the C program in <seealso marker="c_port">
+ Ports</seealso>, using only the plain port, the
+ <c>while</c>-loop must be rewritten. Messages coming from the
+ port is on the Erlang external term format. They must be
+ converted into an <c>ETERM</c> struct, which is a C struct
+ similar to an Erlang term. The result of calling <c>foo()</c> or
+ <c>bar()</c> must be converted to the Erlang external term
+ format before being sent back to the port. But before calling
+ any other Erl_Interface function, the memory handling must be
+ initiated:</p>
<pre>
erl_init(NULL, 0);</pre>
- <p>For reading from and writing to the port the functions <c>read_cmd()</c> and <c>write_cmd()</c> from the erl_comm.c example below
- can still be used.
+ <p>The following functions, <c>read_cmd()</c> and
+ <c>write_cmd()</c>, from the <c>erl_comm.c</c> example in
+ <seealso marker="c_port">Ports</seealso> can still be
+ used for reading from and writing to the port:
</p>
<codeinclude file="erl_comm.c" type="c"/>
- <p>The function <c>erl_decode()</c> from <c>erl_marshal</c> will convert the binary into an <c>ETERM</c> struct.</p>
+ <p>The function <c>erl_decode()</c> from <c>erl_marshal</c>
+ converts the binary into an <c>ETERM</c> struct:</p>
<pre>
int main() {
ETERM *tuplep;
while (read_cmd(buf) > 0) {
tuplep = erl_decode(buf);</pre>
- <p>In this case <c>tuplep</c> now points to an <c>ETERM</c> struct representing a tuple with two elements; the function name (atom) and the argument (integer). By using the function <c>erl_element()</c> from <c>erl_eterm</c> it is possible to extract these elements, which also must be declared as pointers to an <c>ETERM</c> struct.</p>
+ <p>Here, <c>tuplep</c> points to an <c>ETERM</c> struct
+ representing a tuple with two elements; the function name (atom)
+ and the argument (integer). Using the function
+ <c>erl_element()</c> from <c>erl_eterm</c>, these elements can
+ be extracted, but they must also be declared as pointers to an
+ <c>ETERM</c> struct:</p>
<pre>
fnp = erl_element(1, tuplep);
argp = erl_element(2, tuplep);</pre>
- <p>The macros <c>ERL_ATOM_PTR</c> and <c>ERL_INT_VALUE</c> from <c>erl_eterm</c> can be used to obtain the actual values of the atom and the integer. The atom value is represented as a string. By comparing this value with the strings "foo" and "bar" it can be decided which function to call.</p>
+ <p>The macros <c>ERL_ATOM_PTR</c> and <c>ERL_INT_VALUE</c> from
+ <c>erl_eterm</c> can be used to obtain the actual values of the
+ atom and the integer. The atom value is represented as a string.
+ By comparing this value with the strings "foo" and "bar", it can
+ be decided which function to call:</p>
<pre>
if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
res = foo(ERL_INT_VALUE(argp));
} else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
res = bar(ERL_INT_VALUE(argp));
}</pre>
- <p>Now an <c>ETERM</c> struct representing the integer result can be constructed using the function <c>erl_mk_int()</c> from <c>erl_eterm</c>. It is also possible to use the function <c>erl_format()</c> from the module <c>erl_format</c>.</p>
+ <p>Now an <c>ETERM</c> struct that represents the integer result
+ can be constructed using the function <c>erl_mk_int()</c> from
+ <c>erl_eterm</c>. The function
+ <c>erl_format()</c> from the module <c>erl_format</c> can also
+ be used:</p>
<pre>
intp = erl_mk_int(res);</pre>
- <p>The resulting <c>ETERM</c> struct is converted into the Erlang external term format using the function <c>erl_encode()</c> from <c>erl_marshal</c> and sent to Erlang using <c>write_cmd()</c>.</p>
+ <p>The resulting <c>ETERM</c> struct is converted into the Erlang
+ external term format using the function <c>erl_encode()</c> from
+ <c>erl_marshal</c> and sent to Erlang using
+ <c>write_cmd()</c>:</p>
<pre>
erl_encode(intp, buf);
write_cmd(buf, erl_eterm_len(intp));</pre>
- <p>Last, the memory allocated by the <c>ETERM</c> creating functions must be freed.</p>
+ <p>Finally, the memory allocated by the <c>ETERM</c> creating
+ functions must be freed:</p>
<pre>
erl_free_compound(tuplep);
erl_free_term(fnp);
erl_free_term(argp);
erl_free_term(intp);</pre>
- <p>The resulting C program is shown below:</p>
+ <p>The resulting C program is as follows:</p>
<codeinclude file="ei.c" type="c"/>
</section>
<section>
<title>Running the Example</title>
- <p>1. Compile the C code, providing the paths to the include files <c>erl_interface.h</c> and <c>ei.h</c>, and to the libraries <c>erl_interface</c> and <c>ei</c>.</p>
+ <p><em>Step 1.</em> Compile the C code. This provides the paths to
+ the include files <c>erl_interface.h</c> and <c>ei.h</c>, and
+ also to the libraries <c>erl_interface</c> and <c>ei</c>:</p>
<pre>
unix> <input>gcc -o extprg -I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </input>
<input> -L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </input>
<input> complex.c erl_comm.c ei.c -lerl_interface -lei</input></pre>
- <p>In R5B and later versions of OTP, the <c>include</c> and <c>lib</c> directories are situated under <c>OTPROOT/lib/erl_interface-VSN</c>, where <c>OTPROOT</c> is the root directory of the OTP installation (<c>/usr/local/otp</c> in the example above) and <c>VSN</c> is the version of the <c>erl_interface</c> application (3.2.1 in the example above). <br></br>
-
- In R4B and earlier versions of OTP, <c>include</c> and <c>lib</c> are situated under <c>OTPROOT/usr</c>.</p>
- <p>2. Start Erlang and compile the Erlang code.</p>
+ <p>In Erlang/OTP R5B and later versions of OTP, the <c>include</c>
+ and <c>lib</c> directories are situated under
+ <c>OTPROOT/lib/erl_interface-VSN</c>, where <c>OTPROOT</c> is
+ the root directory of the OTP installation
+ (<c>/usr/local/otp</c> in the recent example) and <c>VSN</c> is
+ the version of the Erl_interface application (3.2.1 in the
+ recent example).</p>
+ <p>In R4B and earlier versions of OTP, <c>include</c> and <c>lib</c>
+ are situated under <c>OTPROOT/usr</c>.</p>
+ <p><em>Step 2.</em> Start Erlang and compile the Erlang code:</p>
<pre>
unix> <input>erl</input>
Erlang (BEAM) emulator version 4.9.1.2
@@ -125,7 +182,7 @@ Erlang (BEAM) emulator version 4.9.1.2
Eshell V4.9.1.2 (abort with ^G)
1> <input>c(complex2).</input>
{ok,complex2}</pre>
- <p>3. Run the example.</p>
+ <p><em>Step 3.</em> Run the example:</p>
<pre>
2> <input>complex2:start("extprg").</input>
&lt;0.34.0>
diff --git a/system/doc/tutorial/example.xmlsrc b/system/doc/tutorial/example.xmlsrc
index f87eb217e9..91f09ec522 100644
--- a/system/doc/tutorial/example.xmlsrc
+++ b/system/doc/tutorial/example.xmlsrc
@@ -4,21 +4,22 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
+ Licensed under the Apache License, Version 2.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.
+
</legalnotice>
<title>Problem Example</title>
@@ -31,16 +32,25 @@
<section>
<title>Description</title>
- <p>A common interoperability situation is when there exists a piece of code solving some complex problem, and we would like to incorporate this piece of code in our Erlang program. Suppose for example we have the following C functions that we would like to be able to call from Erlang.</p>
- <codeinclude file="complex.c" tag="" type="none"></codeinclude>
- <p>(For the sake of keeping the example as simple as possible, the functions are not very complicated in this case).</p>
- <p>Preferably we would like to able to call <c>foo</c> and <c>bar</c> without having to bother about them actually being C functions.</p>
+ <p>A common interoperability situation is when you want to incorporate
+ a piece of code, solving a complex problem, in your Erlang
+ program. Suppose for example, that you have the following C
+ functions that you would like to call from Erlang:</p>
+ <codeinclude file="complex.c" tag="" type="none"></codeinclude>
+ <p>The functions are deliberately kept as simple as possible, for
+ readability reasons.</p>
+ <p>From an Erlang perspective, it is preferable to be able to call
+ <c>foo</c> and <c>bar</c> without having to bother about that
+ they are C functions:</p>
<pre>
% Erlang code
...
Res = complex:foo(X),
...</pre>
- <p>The communication with C is hidden in the implementation of <c>complex.erl</c>. In the following chapters it is shown how this module can be implemented using the different interoperability mechanisms.</p>
+ <p>Here, the communication with C is hidden in the implementation
+ of <c>complex.erl</c>.
+ In the following sections, it is shown how this module can be
+ implemented using the different interoperability mechanisms.</p>
</section>
</chapter>
diff --git a/system/doc/tutorial/introduction.xml b/system/doc/tutorial/introduction.xml
index ed86a00f76..36a2e61357 100644
--- a/system/doc/tutorial/introduction.xml
+++ b/system/doc/tutorial/introduction.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,18 +29,34 @@
<rev></rev>
<file>introduction.xml</file>
</header>
+ <marker id="interoperability tutorial"></marker>
+ <p>This section informs on interoperability, that is, information
+ exchange, between Erlang and other programming languages. The
+ included examples mainly treat interoperability between Erlang and
+ C.</p>
<section>
<title>Purpose</title>
- <p>The purpose of this tutorial is to give the reader an orientation of the different interoperability mechanisms that can be used when integrating a program written in Erlang with a program written in another programming language, from the Erlang programmer's point of view.</p>
+ <p>The purpose of this tutorial is to describe different
+ interoperability mechanisms that can be used when integrating a
+ program written in Erlang with a program written in another
+ programming language, from the Erlang programmer's
+ perspective.</p>
</section>
<section>
<title>Prerequisites</title>
- <p>It is assumed that the reader is a skilled Erlang programmer, familiar with concepts such as Erlang data types, processes, messages and error handling.</p>
- <p>To illustrate the interoperability principles C programs running in a UNIX environment have been used. It is assumed that the reader has enough knowledge to be able to apply these principles to the relevant programming languages and platforms.</p>
+ <p>It is assumed that you are a skilled Erlang programmer,
+ familiar with concepts such as Erlang data types, processes,
+ messages, and error handling.</p>
+ <p>To illustrate the interoperability principles, C programs
+ running in a UNIX environment have been used. It is assumed that
+ you have enough knowledge to apply these principles to the
+ relevant programming languages and platforms.</p>
<note>
- <p>For the sake of readability, the example code has been kept as simple as possible. It does not include functionality such as error handling, which might be vital in a real-life system.</p>
+ <p>For readability, the example code is kept as simple as
+ possible. For example, it does not include error handling,
+ which might be vital in a real-life system.</p>
</note>
</section>
</chapter>
diff --git a/system/doc/tutorial/nif.xmlsrc b/system/doc/tutorial/nif.xmlsrc
index 8ddad60f74..ccd49b228d 100644
--- a/system/doc/tutorial/nif.xmlsrc
+++ b/system/doc/tutorial/nif.xmlsrc
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -28,92 +29,105 @@
<rev></rev>
<file>nif.xml</file>
</header>
- <p>This is an example of how to solve the <seealso marker="example">example problem</seealso>
- by using NIFs. NIFs were introduced in R13B03 as an experimental
- feature. It is a simpler and more efficient way of calling C-code
- than using port drivers. NIFs are most suitable for synchronous functions like
- <c>foo</c> and <c>bar</c> in the example, that does some
- relatively short calculations without side effects and return the result.</p>
- <section>
- <title>NIFs</title>
- <p>A NIF (Native Implemented Function) is a function that is
- implemented in C instead of Erlang. NIFs appear as any other functions to
- the callers. They belong to a module and are called like any other Erlang
- functions. The NIFs of a module are compiled and linked into a dynamic
- loadable shared library (SO in Unix, DLL in Windows). The NIF library must
- be loaded in runtime by the Erlang code of the module.</p>
- <p>Since a NIF library is dynamically linked into the emulator
- process, this is the fastest way of calling C-code from Erlang (alongside
- port drivers). Calling NIFs requires no context switches. But it is also
- the least safe, because a crash in a NIF will bring the emulator down
- too.</p>
- </section>
+ <p>This section outlines an example of how to solve the example
+ problem in <seealso marker="example">Problem Example</seealso>
+ by using Native Implemented Functions (NIFs).</p>
+ <p>NIFs were introduced in Erlang/OTP R13B03 as an experimental
+ feature. It is a simpler and more efficient way of calling C-code
+ than using port drivers. NIFs are most suitable for synchronous
+ functions, such as <c>foo</c> and <c>bar</c> in the example, that
+ do some relatively short calculations without side effects and
+ return the result.</p>
+ <p>A NIF is a function that is implemented in C instead of Erlang.
+ NIFs appear as any other functions to the callers. They belong to
+ a module and are called like any other Erlang functions. The NIFs
+ of a module are compiled and linked into a dynamic loadable,
+ shared library (SO in UNIX, DLL in Windows). The NIF library must
+ be loaded in runtime by the Erlang code of the module.</p>
+ <p>As a NIF library is dynamically linked into the emulator process,
+ this is the fastest way of calling C-code from Erlang (alongside
+ port drivers). Calling NIFs requires no context switches. But it
+ is also the least safe, because a crash in a NIF brings the
+ emulator down too.</p>
<section>
<title>Erlang Program</title>
- <p>Even if all functions of a module will be NIFs, you still need an Erlang
- module for two reasons. First, the NIF library must be explicitly loaded
- by Erlang code in the same module. Second, all NIFs of a module must have
- an Erlang implementation as well. Normally these are minimal stub
- implementations that throw an exception. But it can also be used as
- fallback implementations for functions that do not have native
- implemenations on some architectures.</p>
- <p>NIF libraries are loaded by calling <c>erlang:load_nif/2</c>, with the
- name of the shared library as argument. The second argument can be any
- term that will be passed on to the library and used for
- initialization.</p>
+ <p>Even if all functions of a module are NIFs, an Erlang
+ module is still needed for two reasons:</p>
+ <list type="bulleted">
+ <item>The NIF library must be explicitly loaded by
+ Erlang code in the same module.</item>
+ <item>All NIFs of a module must have an Erlang implementation
+ as well.</item>
+ </list>
+ <p>Normally these are minimal stub implementations that throw an
+ exception. But they can also be used as fallback implementations
+ for functions that do not have native implemenations on some
+ architectures.</p>
+ <p>NIF libraries are loaded by calling <c>erlang:load_nif/2</c>,
+ with the name of the shared library as argument. The second
+ argument can be any term that will be passed on to the library
+ and used for initialization:</p>
<codeinclude file="complex6.erl" tag="" type="none"></codeinclude>
- <p>We use the directive <c>on_load</c> to get function <c>init</c> to be
- automatically called when the module is loaded. If <c>init</c>
- returns anything other than <c>ok</c>, such when the loading of
- the NIF library fails in this example, the module will be
- unloaded and calls to functions within it will fail.</p>
- <p>Loading the NIF library will override the stub implementations
+ <p>Here, the directive <c>on_load</c> is used to get function
+ <c>init</c> to be automatically called when the module is
+ loaded. If <c>init</c> returns anything other than <c>ok</c>,
+ such when the loading of the NIF library fails in this example,
+ the module is unloaded and calls to functions within it,
+ fail.</p>
+ <p>Loading the NIF library overrides the stub implementations
and cause calls to <c>foo</c> and <c>bar</c> to be dispatched to
the NIF implementations instead.</p>
</section>
<section>
- <title>NIF library code</title>
+ <title>NIF Library Code</title>
<p>The NIFs of the module are compiled and linked into a
shared library. Each NIF is implemented as a normal C function. The macro
<c>ERL_NIF_INIT</c> together with an array of structures defines the names,
- arity and function pointers of all the NIFs in the module. The header
- file <c>erl_nif.h</c> must be included. Since the library is a shared
- module, not a program, no main function should be present.</p>
+ arity, and function pointers of all the NIFs in the module. The header
+ file <c>erl_nif.h</c> must be included. As the library is a shared
+ module, not a program, no main function is to be present.</p>
<p>The function arguments passed to a NIF appears in an array <c>argv</c>,
- with <c>argc</c> as the length of the array and thus the arity of the
+ with <c>argc</c> as the length of the array, and thus the arity of the
function. The Nth argument of the function can be accessed as
<c>argv[N-1]</c>. NIFs also take an environment argument that
serves as an opaque handle that is needed to be passed on to
most API functions. The environment contains information about
- the calling Erlang process.</p>
+ the calling Erlang process:</p>
<codeinclude file="complex6_nif.c" tag="" type="none"></codeinclude>
- <p>The first argument to <c>ERL_NIF_INIT</c> must be the name of the
+ <p>Here,<c>ERL_NIF_INIT</c> has the following arguments:</p>
+ <list type="bulleted">
+ <item><p>The first argument must be the name of the
Erlang module as a C-identifier. It will be stringified by the
- macro. The second argument is the array of <c>ErlNifFunc</c>
- structures containing name, arity and function pointer of
- each NIF. The other arguments are pointers to callback functions
- that can be used to initialize the library. We do not use them
- in this simple example so we set them all to <c>NULL</c>.</p>
+ macro.</p>
+ </item>
+ <item>The second argument is the array of <c>ErlNifFunc</c>
+ structures containing name, arity, and function pointer of
+ each NIF.</item>
+ <item>The remaining arguments are pointers to callback functions
+ that can be used to initialize the library. They are not used
+ in this simple example, hence they are all set to <c>NULL</c>.</item>
+ </list>
<p>Function arguments and return values are represented as values
- of type <c>ERL_NIF_TERM</c>. We use functions like <c>enif_get_int</c>
- and <c>enif_make_int</c> to convert between Erlang term and C-type.
- If the function argument <c>argv[0]</c> is not an integer then
- <c>enif_get_int</c> will return false, in which case we return
+ of type <c>ERL_NIF_TERM</c>. Here, functions like <c>enif_get_int</c>
+ and <c>enif_make_int</c> are used to convert between Erlang term
+ and C-type.
+ If the function argument <c>argv[0]</c> is not an integer,
+ <c>enif_get_int</c> returns false, in which case it returns
by throwing a <c>badarg</c>-exception with <c>enif_make_badarg</c>.</p>
</section>
<section>
<title>Running the Example</title>
- <p>1. Compile the C code.</p>
+ <p><em>Step 1.</em> Compile the C code:</p>
<pre>
unix> <input>gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c</input>
windows> <input>cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c</input></pre>
- <p>2. Start Erlang and compile the Erlang code.</p>
+ <p><em>Step 2:</em> Start Erlang and compile the Erlang code:</p>
<pre>
> <input>erl</input>
Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
@@ -121,7 +135,7 @@ Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-p
Eshell V5.7.5 (abort with ^G)
1> <input>c(complex6).</input>
{ok,complex6}</pre>
- <p>3. Run the example.</p>
+ <p><em>Step 3:</em> Run the example:</p>
<pre>
3> <input>complex6:foo(3).</input>
4
diff --git a/system/doc/tutorial/overview.xml b/system/doc/tutorial/overview.xml
index 1fe1aad22b..255c22f2c1 100644
--- a/system/doc/tutorial/overview.xml
+++ b/system/doc/tutorial/overview.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ Licensed under the Apache License, Version 2.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.
</legalnotice>
@@ -31,35 +32,90 @@
<section>
<title>Built-In Mechanisms</title>
- <p>There are two interoperability mechanisms built into the Erlang runtime system. One is <em>distributed Erlang</em> and the other one is <em>ports</em>. A variation of ports is <em>linked-in drivers</em>.</p>
+ <p>Two interoperability mechanisms are built into the Erlang
+ runtime system, <em>distributed Erlang</em> and <em>ports</em>.
+ A variation of ports is <em>linked-in drivers</em>.</p>
<marker id="dist"></marker>
<section>
<title>Distributed Erlang</title>
- <p>An Erlang runtime system is made into a distributed Erlang node by giving it a name. A distributed Erlang node can connect to and monitor other nodes, it is also possible to spawn processes at other nodes. Message passing and error handling between processes at different nodes are transparent. There exists a number of useful <c>stdlib</c> modules intended for use in a distributed Erlang system; for example, <c>global</c> which provides global name registration. The distribution mechanism is implemented using TCP/IP sockets.</p>
- <p><em>When to use:</em> Distributed Erlang is primarily used for communication Erlang-Erlang. It can also be used for communication between Erlang and C, if the C program is implemented as a <seealso marker="#cnode">C node</seealso>, see below.</p>
- <p><em>Where to read more:</em> Distributed Erlang and some distributed programming techniques are described in the Erlang book. <br></br>
-
- In the Erlang/OTP documentation there is a chapter about distributed Erlang in "Getting Started" (User's Guide). <br></br>
-
- Relevant man pages are <c>erlang</c> (describes the BIFs) and <c>global</c>, <c>net_adm</c>, <c>pg2</c>, <c>rpc</c>, <c>pool</c> and <c>slave</c>.</p>
+ <p>An Erlang runtime system is made a distributed Erlang node by
+ giving it a name. A distributed Erlang node can connect to,
+ and monitor, other nodes. It can also spawn processes at other
+ nodes. Message passing and error handling between processes at
+ different nodes are transparent. A number of useful STDLIB
+ modules are available in a distributed Erlang system. For
+ example, <c>global</c>, which provides global name
+ registration. The distribution mechanism is implemented using
+ TCP/IP sockets.</p>
+ <p><em>When to use:</em> Distributed Erlang is primarily used
+ for Erlang-Erlang communication. It can also be used for
+ communication between Erlang and C, if the C program is
+ implemented as a C node, see
+ <seealso marker="#cnode">C and Java Libraries</seealso>.</p>
+ <p><em>Where to read more:</em> Distributed Erlang and some distributed
+ programming techniques are described in the Erlang book.</p>
+ <p>For more information, see <seealso
+ marker="doc/getting_started:conc_prog#Distributed Programming">
+ Distributed Programming.</seealso></p>
+ <p>Relevant manual pages are the following:</p>
+ <list type="bulleted">
+ <item><seealso marker="erts:erlang">erlang</seealso> manual page in ERTS
+ (describes the BIFs)</item>
+ <item><seealso marker="kernel:global">global</seealso> manual page in Kernel</item>
+ <item><seealso marker="kernel:net_adm">net_adm</seealso> manual page in Kernel</item>
+ <item><seealso marker="kernel:pg2">pg2</seealso> manual page in Kernel</item>
+ <item><seealso marker="kernel:rpc">rpc</seealso> manual page in Kernel</item>
+ <item><seealso marker="stdlib:pool">pool</seealso> manual page in STDLIB</item>
+ <item><seealso marker="stdlib:slave">slave</seealso> manual page in STDLIB</item>
+ </list>
</section>
<section>
<title>Ports and Linked-In Drivers</title>
- <p>Ports provide the basic mechanism for communication with the external world, from Erlang's point of view. They provide a byte-oriented interface to an external program. When a port has been created, Erlang can communicate with it by sending and receiving lists of bytes (not Erlang terms). This means that the programmer may have to invent a suitable encoding and decoding scheme.</p>
- <p>The actual implementation of the port mechanism depends on the platform. In the Unix case, pipes are used and the external program should as default read from standard input and write to standard output. Theoretically, the external program could be written in any programming language as long as it can handle the interprocess communication mechanism with which the port is implemented.</p>
- <p>The external program resides in another OS process than the Erlang runtime system. In some cases this is not acceptable, consider for example drivers with very hard time requirements. It is therefore possible to write a program in C according to certain principles and dynamically link it to the Erlang runtime system, this is called a linked-in driver.</p>
- <p><em>When to use:</em> Being the basic mechanism, ports can be used for all kinds of interoperability situations where the Erlang program and the other program runs on the same machine. Programming is fairly straight-forward. <br></br>
-
- Linked-in drivers involves writing certain call-back functions in C. Very good skills are required as the code is linked to the Erlang runtime system.</p>
+ <p>Ports provide the basic mechanism for communication with the
+ external world, from Erlang's point of view. The ports provide
+ a byte-oriented interface to an external program. When a port
+ is created, Erlang can communicate with it by sending and
+ receiving lists of bytes (not Erlang terms). This means that
+ the programmer might have to invent a suitable encoding and
+ decoding scheme.</p>
+ <p>The implementation of the port mechanism depends on the
+ platform. For UNIX, pipes are used and the external program is
+ assumed to read from standard input and write to standard
+ output. The external program can be written in any programming
+ language as long as it can handle the interprocess
+ communication mechanism with which the port is
+ implemented.</p>
+ <p>The external program resides in another OS process than the
+ Erlang runtime system. In some cases this is not acceptable.
+ Consider, for example, drivers with very hard time
+ requirements. It is therefore possible to write a program in C
+ according to certain principles, and dynamically link it to
+ the Erlang runtime system. This is called a <em>linked-in
+ driver</em>.</p>
+ <p><em>When to use:</em> Ports can be used for all kinds of
+ interoperability situations where the Erlang program and the
+ other program runs on the same machine. Programming is fairly
+ straight-forward.</p>
+ <p>Linked-in drivers involves writing certain call-back
+ functions in C. This requires very good skills as the code is
+ linked to the Erlang runtime system.</p>
<warning>
- <p>An erroneous linked-in driver will cause the entire Erlang runtime system to leak memory, hang or crash.</p>
+ <p>A faulty linked-in driver causes the entire Erlang runtime
+ system to leak memory, hang, or crash.</p>
</warning>
- <p><em>Where to read more:</em> Ports are described in the "Miscellaneous Items" chapter of the Erlang book. Linked-in drivers are described in Appendix E. <br></br>
-
- The BIF <c>open_port/2</c> is documented in the man page for <c>erlang</c>. For linked-in drivers, the programmer needs to read the information in the man page for <c>erl_ddll</c>.</p>
- <p><em>Examples:</em><seealso marker="c_port">Port example</seealso>.</p>
+ <p><em>Where to read more:</em> Ports are described in section
+ "Miscellaneous Items" of the Erlang book. Linked-in drivers
+ are described in Appendix E.</p>
+ <p>The BIF <c>open_port/2</c> is documented in the
+ <seealso marker="erts:erlang">erlang</seealso> manual page in
+ ERTS.</p>
+ <p>For linked-in drivers, the programmer needs to read the
+ <seealso marker="kernel:erl_ddll">erl_ddll</seealso> manual
+ page in Kernel.</p>
+ <p><em>Examples:</em> Port example in <seealso marker="c_port">
+ Ports</seealso>.</p>
</section>
</section>
@@ -68,64 +124,152 @@
<section>
<title>Erl_Interface</title>
- <p>Very often the program at the other side of a port is a C program. To help the C programmer a library called Erl_Interface has been developed. It consists of five parts:</p>
+ <p>The program at the other side of a port is often a C program.
+ To help the C programmer, the Erl_Interface library
+ has been developed, including the following five parts:</p>
<list type="bulleted">
- <item><c>erl_marshal</c>, <c>erl_eterm</c>, <c>erl_format</c>, <c>erl_malloc</c> Handling of the Erlang external term format.</item>
- <item><c>erl_connect</c> Communication with distributed Erlang, see <seealso marker="#cnode">C nodes</seealso> below.</item>
- <item><c>erl_error</c> Error print routines.</item>
- <item><c>erl_global</c> Access globally registered names.</item>
- <item><c>Registry</c> Store and backup of key-value pairs.</item>
+ <item>
+ <c>erl_marshal</c>, <c>erl_eterm</c>, <c>erl_format</c>, and
+ <c>erl_malloc</c>: Handling of the Erlang external term format</item>
+ <item>
+ <c>erl_connect</c>:
+ Communication with distributed Erlang, see <seealso
+ marker="#cnode">C nodes</seealso> below</item>
+ <item>
+ <c>erl_error</c>:
+ Error print routines</item>
+ <item>
+ <c>erl_global</c>:
+ Access globally registered names</item>
+ <item>
+ <c>Registry</c>:
+ Store and backup of key-value pairs</item>
</list>
- <p>The Erlang external term format is a representation of an Erlang term as a sequence of bytes, a binary. Conversion between the two representations is done using BIFs.</p>
+ <p>The Erlang external term format is a representation of an
+ Erlang term as a sequence of bytes, that is, a binary.
+ Conversion between the two representations is done using the
+ following BIFs:</p>
<pre>
Binary = term_to_binary(Term)
Term = binary_to_term(Binary)</pre>
- <p>A port can be set to use binaries instead of lists of bytes. It is then not necessary to invent any encoding/decoding scheme. Erl_Interface functions are used for unpacking the binary and convert it into a struct similar to an Erlang term. Such a struct can be manipulated in different ways and be converted to the Erlang external format and sent to Erlang.</p>
+ <p>A port can be set to use binaries instead of lists of bytes.
+ It is then not necessary to invent any encoding/decoding
+ scheme. Erl_Interface functions are used for unpacking the
+ binary and convert it into a struct similar to an Erlang term.
+ Such a struct can be manipulated in different ways, be
+ converted to the Erlang external format, and sent to
+ Erlang.</p>
<p><em>When to use:</em> In C code, in conjunction with Erlang binaries.</p>
- <p><em>Where to read more:</em> Read about the Erl_Interface User's Guide; Command Reference and Library Reference. In R5B and earlier versions the information can be found under the Kernel application.</p>
- </section>
- <p><em>Examples:</em><seealso marker="erl_interface">erl_interface example</seealso>.</p>
+ <p><em>Where to read more:</em> See the Erlang Interface User's
+ Guide, Command Reference, and Library Reference. In Erlang/OTP
+ R5B, and earlier versions, the information is part of the
+ Kernel application.</p> </section>
+ <p><em>Examples:</em> Erl_Interface example in
+ <seealso marker="erl_interface">Erl_Interface</seealso>.</p>
<marker id="cnode"></marker>
<section>
<title>C Nodes</title>
- <p>A C program which uses the Erl_Interface functions for setting up a connection to and communicating with a distributed Erlang node is called a <em>C node</em>, or a <em>hidden node</em>. The main advantage with a C node is that the communication from the Erlang programmer's point of view is extremely easy, since the C program behaves as a distributed Erlang node.</p>
- <p><em>When to use:</em> C nodes can typically be used on device processors (as opposed to control processors) where C is a better choice than Erlang due to memory limitations and/or application characteristics.</p>
- <p><em>Where to read more:</em> In the <c>erl_connect</c> part of the Erl_Interface documentation, see above. The programmer also needs to be familiar with TCP/IP sockets, see <seealso marker="#sockets">below</seealso>, and distributed Erlang, see <seealso marker="#dist">above</seealso>.</p>
- <p><em>Examples:</em><seealso marker="cnode">C node example</seealso>.</p>
+ <p>A C program that uses the Erl_Interface functions for setting
+ up a connection to, and communicating with, a distributed
+ Erlang node is called a <em>C node</em>, or a <em>hidden
+ node</em>. The main advantage with a C node is that the
+ communication from the Erlang programmer's perspective is
+ extremely easy, as the C program behaves as a distributed
+ Erlang node.</p>
+ <p><em>When to use:</em> C nodes can typically be used on device
+ processors (as opposed to control processors) where C is a
+ better choice than Erlang due to memory limitations or
+ application characteristics, or both.</p>
+ <p><em>Where to read more:</em> See the <c>erl_connect</c> part
+ of the Erl_Interface documentation. The programmer also needs
+ to be familiar with TCP/IP sockets, see Sockets in <seealso
+ marker="#sockets">Standard
+ Protocols</seealso> and Distributed Erlang in <seealso
+ marker="#dist">Built-In Mechanisms</seealso>.</p>
+ <p><em>Example:</em> C node example in <seealso marker="cnode">
+ C Nodes</seealso>.</p>
</section>
<section>
<title>Jinterface</title>
- <p>In Erlang/OTP R6B, a library similar to Erl_Interface for Java was added called <em>jinterface</em>.</p>
+ <p>In Erlang/OTP R6B, a library similar to Erl_Interface for
+ Java was added called <em>jinterface</em>. It provides a tool
+ for Java programs to communicate with Erlang nodes.</p>
</section>
</section>
<section>
<title>Standard Protocols</title>
- <p>Sometimes communication between an Erlang program and another program using a standard protocol is desirable. Erlang/OTP currently supports TCP/IP and UDP <em>sockets</em>, SNMP, HTTP and IIOP (CORBA). Using one of the latter three requires good knowledge about the protocol and is not covered by this tutorial. Please refer to the documentation for the SNMP, Inets and Orber applications, respectively.</p>
+ <p>Sometimes communication between an Erlang program and another
+ program using a standard protocol is desirable. Erlang/OTP
+ currently supports TCP/IP and UDP <em>sockets</em>: as
+ follows:</p>
+ <list type="bulleted">
+ <item>SNMP</item>
+ <item>HTTP</item>
+ <item>IIOP (CORBA)</item>
+ </list>
+ <p>Using one of the latter three requires good knowledge about the
+ protocol and is not covered by this tutorial. See the SNMP,
+ Inets, and Orber applications, respectively.</p>
<marker id="sockets"></marker>
<section>
<title>Sockets</title>
- <p>Simply put, connection-oriented socket communication (TCP/IP) consists of an initiator socket ("server") started at a certain host with a certain port number. A connector socket ("client") aware of the initiator's host name and port number can connect to it and data can be sent between them. Connection-less socket communication (UDP) consists of an initiator socket at a certain host with a certain port number and a connector socket sending data to it. For a detailed description of the socket concept, please refer to a suitable book about network programming. A suggestion is <em>UNIX Network Programming, Volume 1: Networking APIs - Sockets and XTI</em> by W. Richard Stevens, ISBN: 013490012X.</p>
- <p>In Erlang/OTP, access to TCP/IP and UDP sockets is provided by the
- Kernel modules <c>gen_tcp</c> and <c>gen_udp</c>. Both are easy to
- use and do not require any deeper knowledge about the socket concept.</p>
- <p><em>When to use:</em> For programs running on the same or on another machine than the Erlang program.</p>
- <p><em>Where to read more:</em> The man pages for <c>gen_tcp</c> and <c>gen_udp</c>.</p>
+ <p>Simply put, connection-oriented socket communication (TCP/IP)
+ consists of an initiator socket ("server") started at a
+ certain host with a certain port number. A connector socket
+ ("client"), which is aware of the initiator host name and port
+ number, can connect to it and data can be sent between
+ them.</p>
+ <p>Connection-less socket communication (UDP) consists of an
+ initiator socket at a certain host with a certain port number
+ and a connector socket sending data to it.</p>
+ <p>For a detailed description of the socket concept, refer to a
+ suitable book about network programming. A suggestion is
+ <em>UNIX Network Programming, Volume 1: Networking APIs -
+ Sockets and XTI</em> by W. Richard Stevens, ISBN:
+ 013490012X.</p>
+ <p>In Erlang/OTP, access to TCP/IP and UDP sockets is provided
+ by the modules <c>gen_tcp</c> and <c>gen_udp</c> in
+ Kernel. Both are easy to use and do not require
+ detailed knowledge about the socket concept.</p>
+ <p><em>When to use:</em> For programs running on the same or on
+ another machine than the Erlang program.</p>
+ <p><em>Where to read more:</em> See the <seealso
+ marker="kernel:gen_tcp">gen_tcp</seealso> and the <seealso
+ marker="kernel:gen_udp">gen_udp</seealso> manual pages in
+ Kernel.</p>
</section>
</section>
<section>
<title>IC</title>
- <p>IC (IDL Compiler) is an interface generator which given an IDL interface specification automatically generates stub code in Erlang, C or Java. Please refer to the IC User's Guide and IC Reference Manual.</p>
+ <p>IC (Erlang IDL Compiler) is an interface generator that, given
+ an IDL interface specification, automatically generates stub
+ code in Erlang, C, or Java. See the IC User's Guide and IC
+ Reference Manual.</p>
+ <p>For details, see the <seealso marker="ic:ic">ic</seealso>
+ manual page in IC.</p>
</section>
<section>
<title>Old Applications</title>
- <p>There are two old applications of interest when talking about interoperability: <em>IG</em> which was removed in Erlang/OTP R6B and <em>Jive</em> which was removed in Erlang/OTP R7B. Both applications have been replaced by IC and are mentioned here for reference only.</p>
- <p>IG (Interface Generator) automatically generated code for port or socket communication between an Erlang program and a C program, given a C header file with certain keywords. Jive provided a simple interface between an Erlang program and a Java program.</p>
+ <p>Two old applications are of interest regarding
+ interoperability. Both have been replaced by IC and are
+ mentioned here for reference only:</p>
+ <list type="bulleted">
+ <item><p>IG - Removed from Erlang/OTP R6B.</p>
+ <p>IG (Interface Generator) automatically generated code for
+ port or socket communication between an Erlang program and a
+ C program, given a C header file with certain keywords.</p>
+ </item>
+ <item><p>Jive - Removed from Erlang/OTP R7B.</p>
+ <p>Jive provided a simple interface between an Erlang program
+ and a Java program.</p>
+ </item>
+ </list>
</section>
</chapter>
diff --git a/system/doc/tutorial/part.xml b/system/doc/tutorial/part.xml
index f33bd97e29..5216d1653d 100644
--- a/system/doc/tutorial/part.xml
+++ b/system/doc/tutorial/part.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ Licensed under the Apache License, Version 2.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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/system/doc/tutorial/xmlfiles.mk b/system/doc/tutorial/xmlfiles.mk
index 95562bec60..28b66f232d 100644
--- a/system/doc/tutorial/xmlfiles.mk
+++ b/system/doc/tutorial/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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%
#
diff --git a/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf b/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
index fe0886ac8a..ac6cd0ca1e 100644
--- a/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
+++ b/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-arm-android.conf b/xcomp/erl-xcomp-arm-android.conf
index 4fd1f270d1..44ff7537d3 100644
--- a/xcomp/erl-xcomp-arm-android.conf
+++ b/xcomp/erl-xcomp-arm-android.conf
@@ -4,16 +4,17 @@
##
## 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/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-arm-linux.conf b/xcomp/erl-xcomp-arm-linux.conf
index 6656c1a1aa..e09e1b1d90 100644
--- a/xcomp/erl-xcomp-arm-linux.conf
+++ b/xcomp/erl-xcomp-arm-linux.conf
@@ -4,16 +4,17 @@
##
## 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/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf b/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf
index e86043f5c8..03c28091ed 100644
--- a/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf
+++ b/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2010-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-mips-linux.conf b/xcomp/erl-xcomp-mips-linux.conf
index e031bdcd26..9e05e4c1b2 100644
--- a/xcomp/erl-xcomp-mips-linux.conf
+++ b/xcomp/erl-xcomp-mips-linux.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2010-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf b/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf
index cc6c5a9678..8f1dd03440 100644
--- a/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf
+++ b/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-powerpc-ose5.conf b/xcomp/erl-xcomp-powerpc-ose5.conf
index bf49b32827..88b2135593 100644
--- a/xcomp/erl-xcomp-powerpc-ose5.conf
+++ b/xcomp/erl-xcomp-powerpc-ose5.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-powerpc64-bgq-linux.conf b/xcomp/erl-xcomp-powerpc64-bgq-linux.conf
index 1c45aaf86b..26a97ec301 100644
--- a/xcomp/erl-xcomp-powerpc64-bgq-linux.conf
+++ b/xcomp/erl-xcomp-powerpc64-bgq-linux.conf
@@ -4,16 +4,17 @@
##
## 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/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-sfk-linux-ose5.conf b/xcomp/erl-xcomp-sfk-linux-ose5.conf
index a9c06f3cb4..a4d64e5636 100644
--- a/xcomp/erl-xcomp-sfk-linux-ose5.conf
+++ b/xcomp/erl-xcomp-sfk-linux-ose5.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-vars.sh b/xcomp/erl-xcomp-vars.sh
index 5e55c3af1b..0443867341 100644
--- a/xcomp/erl-xcomp-vars.sh
+++ b/xcomp/erl-xcomp-vars.sh
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2010-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.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%
#
diff --git a/xcomp/erl-xcomp-vxworks_ppc32.conf b/xcomp/erl-xcomp-vxworks_ppc32.conf
index 7424cee496..f1655caa4e 100644
--- a/xcomp/erl-xcomp-vxworks_ppc32.conf
+++ b/xcomp/erl-xcomp-vxworks_ppc32.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf b/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf
index d5b9d8c469..2a09869910 100644
--- a/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf
+++ b/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2010-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##
diff --git a/xcomp/erl-xcomp.conf.template b/xcomp/erl-xcomp.conf.template
index ad72b7d66b..e9bbebb960 100644
--- a/xcomp/erl-xcomp.conf.template
+++ b/xcomp/erl-xcomp.conf.template
@@ -4,16 +4,17 @@
##
## Copyright Ericsson AB 2009-2012. All Rights Reserved.
##
-## The contents of this file are subject to the Erlang Public License,
-## Version 1.1, (the "License"); you may not use this file except in
-## compliance with the License. You should have received a copy of the
-## Erlang Public License along with this software. If not, it can be
-## retrieved online at http://www.erlang.org/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## Software distributed under the License is distributed on an "AS IS"
-## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-## the License for the specific language governing rights and limitations
-## under the License.
+## 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%
##